diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a42cff4356..b0c7da7039 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,7 +25,15 @@ jobs: cache: true - run: make tools - run: make lint - - run: make website-lint + - run: make docs-lint + + - name: Check for uncommitted docs changes + run: | + tfplugindocs generate + if ! [[ -z $(git status --porcelain) ]]; then + echo "::error::Uncommitted changes after tfplugindocs generate" + exit 1 + fi - run: make build - run: make test diff --git a/.markdownlint.json b/.markdownlint.json new file mode 100644 index 0000000000..25d26cadd9 --- /dev/null +++ b/.markdownlint.json @@ -0,0 +1,17 @@ +{ + "MD004": { + "style": "dash" + }, + "MD007": { + "indent": 4 + }, + "MD013": false, + "MD014": false, + "MD022": false, + "MD029": { + "style": "ordered" + }, + "MD033": { + "allowed_elements": ["a"] + } +} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a14f7ef024..0b5b307ef1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,11 +10,14 @@ Before submitting an issue or a pull request, please search the repository for e ## Submitting a pull request -0. Fork and clone the repository. -0. Create a new branch: `git switch -c my-branch-name`. -0. Make your change, add tests, and make sure the tests still pass. -0. Push to your fork and submit a pull request. -0. Pat yourself on the back and wait for your pull request to be reviewed and merged. +1. Fork and clone the repository. +2. Create a new branch: `git switch -c my-branch-name`. +3. Make your change, add tests, and make sure the tests still pass. +4. Run `make docs-lint` to check if the documentation is up to date. +5. Update the documentation templates if needed. +6. Run `make docs-generate` to generate changes to the documentation. +7. Push to your fork and submit a pull request. +8. Pat yourself on the back and wait for your pull request to be reviewed and merged. Here are a few things you can do that will increase the likelihood of your pull request being accepted: @@ -33,26 +36,31 @@ This section describes a typical sequence performed when developing locally. Ful Once you have the repository cloned, there's a couple of additional steps you'll need to take. Since most of the testing is acceptance or integration testing, we need to manipulate real GitHub resources in order to run it. Useful setup steps are listed below: - If you haven't already, [create a GitHub organization you can use for testing](#github-organization). - - Optional: you may find it beneficial to create a test user as well in order to avoid potential rate-limiting issues on your main account. - - Your organization _must_ have a repository called `terraform-template-module`. The [terraformtesting/terraform-template-module](https://github.com/terraformtesting/terraform-template-module) repo is a good, re-usable example. - - You _must_ make sure that the "Template Repository" item in Settings is checked for this repo. + - Optional: you may find it beneficial to create a test user as well in order to avoid potential rate-limiting issues on your main account. + - Your organization _must_ have a repository called `terraform-template-module`. The [terraformtesting/terraform-template-module](https://github.com/terraformtesting/terraform-template-module) repo is a good, re-usable example. + - You _must_ make sure that the "Template Repository" item in Settings is checked for this repo. - If you haven't already, generate a Personal Access Token (PAT) for authenticating your test runs. - Export the necessary configuration for authenticating your provider with GitHub + ```sh export GITHUB_TOKEN= export GITHUB_ORGANIZATION= ``` + - Build the project with `make build` - Try an example test run from the default (`main`) branch, like `TF_LOG=DEBUG TF_ACC=1 go test -v ./... -run ^TestAccGithubRepositories`. All those tests should pass. ### Local Development Iteration 1. Write a test describing what you will fix. See [`github_label`](./github/resource_github_issue_label_test.go) for an example format. -1. Run your test and observe it fail. Enabling debug output allows for observing the underlying requests and responses made as well as viewing state (search `STATE:`) generated during the acceptance test run. +2. Run your test and observe it fail. Enabling debug output allows for observing the underlying requests and responses made as well as viewing state (search `STATE:`) generated during the acceptance test run. + ```sh TF_LOG=DEBUG TF_ACC=1 go test -v ./... -run ^TestAccGithubIssueLabel ``` + 1. Align the resource's implementation to your test case and observe it pass: + ```sh TF_ACC=1 go test -v ./... -run ^TestAccGithubIssueLabel ``` @@ -67,27 +75,29 @@ Println debugging can easily be used to obtain information about how code change If a full debugger is desired, VSCode may be used. In order to do so, -0. Create a launch.json file with this configuration: +1. Create a launch.json file with this configuration: + ```json { - "name": "Attach to Process", - "type": "go", - "request": "attach", - "mode": "local", - "processId": 0, + "name": "Attach to Process", + "type": "go", + "request": "attach", + "mode": "local", + "processId": 0, } ``` + Setting a `processId` of 0 allows a dropdown to select the process of the provider. -0. Add a sleep call (e.g. `time.Sleep(10 * time.Second)`) in the [`func providerConfigure(p *schema.Provider) schema.ConfigureFunc`](https://github.com/integrations/terraform-provider-github/blob/cec7e175c50bb091feecdc96ba117067c35ee351/github/provider.go#L274C1-L274C64) before the immediate `return` call. This will allow time to connect the debugger while the provider is initializing, before any critical logic happens. +1. Add a sleep call (e.g. `time.Sleep(10 * time.Second)`) in the [`func providerConfigure(p *schema.Provider) schema.ConfigureFunc`](https://github.com/integrations/terraform-provider-github/blob/cec7e175c50bb091feecdc96ba117067c35ee351/github/provider.go#L274C1-L274C64) before the immediate `return` call. This will allow time to connect the debugger while the provider is initializing, before any critical logic happens. -0. Build the terraform provider with debug flags enabled and copy it to the appropriate bin folder with a command like `go build -gcflags="all=-N -l" -o ~/go/bin/`. +2. Build the terraform provider with debug flags enabled and copy it to the appropriate bin folder with a command like `go build -gcflags="all=-N -l" -o ~/go/bin/`. -0. Create or edit a `dev.tfrc` that points toward the newly-built binary, and export the `TF_CLI_CONFIG_FILE` variable to point to it. Further instructions on this process may be found in the [Building the provider](#using-a-local-version-of-the-provider) section. +3. Create or edit a `dev.tfrc` that points toward the newly-built binary, and export the `TF_CLI_CONFIG_FILE` variable to point to it. Further instructions on this process may be found in the [Building the provider](#using-a-local-version-of-the-provider) section. -0. Run a terraform command (e.g. `terraform apply`). While the provider pauses on initialization, go to VSCode and click "Attach to Process". In the search box that appears, type `terraform-provi` and select the terraform provider process. +4. Run a terraform command (e.g. `terraform apply`). While the provider pauses on initialization, go to VSCode and click "Attach to Process". In the search box that appears, type `terraform-provi` and select the terraform provider process. -0. The debugger is now connected! During a typical terraform command, the plugin will be invoked multiple times. If the debugger disconnects and the plugin is invoked again later in the run, the developer will have to re-attach each time as the process ID changes. +5. The debugger is now connected! During a typical terraform command, the plugin will be invoked multiple times. If the debugger disconnects and the plugin is invoked again later in the run, the developer will have to re-attach each time as the process ID changes. ## Manual Testing @@ -121,7 +131,7 @@ provider_installation { } ``` -See https://www.terraform.io/docs/cli/config/config-file.html for more details. +See [Terraform CLI Config File](https://www.terraform.io/docs/cli/config/config-file.html) for more details. When running examples, you should spot the following warning to confirm you are using a local build: @@ -179,45 +189,45 @@ This may come in handy when debugging both acceptance and manual testing. ```json { - // for information on how to debug the provider, see the CONTRIBUTING.md file - "version": "0.2.0", - "configurations": [ - { - "name": "Launch test function", - "type": "go", - "request": "launch", - "mode": "test", - // note that the program file must be in the same package as the test to run, - // though it does not necessarily have to be the file that contains the test. - "program": "/home/kfcampbell/github/dev/terraform-provider-github/github/resource_github_team_members_test.go", - "args": [ - "-test.v", - "-test.run", - "^TestAccGithubRepositoryTopics$" // ^ExactMatch$ - ], - "env": { - "GITHUB_TEST_COLLABORATOR": "kfcampbell-terraform-test-user", - "GITHUB_TEST_COLLABORATOR_TOKEN": "ghp_xxx", - "GITHUB_TEST_USER": "kfcampbell", - "GITHUB_TOKEN": "ghp_xxx", - "GITHUB_TEMPLATE_REPOSITORY": "terraform-template-module", - "GITHUB_TEMPLATE_REPOSITORY_RELEASE_ID": "12345678", - // "GITHUB_OWNER": "kfcampbell-terraform-provider", - // "GITHUB_OWNER": "kfcampbell", - "GITHUB_ORGANIZATION": "kfcampbell-terraform-provider", // GITHUB_ORGANIZATION is required for organization integration tests - "TF_CLI_CONFIG_FILE": "/home/kfcampbell/github/dev/terraform-provider-github/examples/dev.tfrc", - "TF_ACC": "1", - "TF_LOG": "DEBUG", - "APP_INSTALLATION_ID": "12345678" - } - }, - { - "name": "Attach to Process", - "type": "go", - "request": "attach", - "mode": "local", - "processId": 0 - } - ] + // for information on how to debug the provider, see the CONTRIBUTING.md file + "version": "0.2.0", + "configurations": [ + { + "name": "Launch test function", + "type": "go", + "request": "launch", + "mode": "test", + // note that the program file must be in the same package as the test to run, + // though it does not necessarily have to be the file that contains the test. + "program": "/home/kfcampbell/github/dev/terraform-provider-github/github/resource_github_team_members_test.go", + "args": [ + "-test.v", + "-test.run", + "^TestAccGithubRepositoryTopics$" // ^ExactMatch$ + ], + "env": { + "GITHUB_TEST_COLLABORATOR": "kfcampbell-terraform-test-user", + "GITHUB_TEST_COLLABORATOR_TOKEN": "ghp_xxx", + "GITHUB_TEST_USER": "kfcampbell", + "GITHUB_TOKEN": "ghp_xxx", + "GITHUB_TEMPLATE_REPOSITORY": "terraform-template-module", + "GITHUB_TEMPLATE_REPOSITORY_RELEASE_ID": "12345678", + // "GITHUB_OWNER": "kfcampbell-terraform-provider", + // "GITHUB_OWNER": "kfcampbell", + "GITHUB_ORGANIZATION": "kfcampbell-terraform-provider", // GITHUB_ORGANIZATION is required for organization integration tests + "TF_CLI_CONFIG_FILE": "/home/kfcampbell/github/dev/terraform-provider-github/examples/dev.tfrc", + "TF_ACC": "1", + "TF_LOG": "DEBUG", + "APP_INSTALLATION_ID": "12345678" + } + }, + { + "name": "Attach to Process", + "type": "go", + "request": "attach", + "mode": "local", + "processId": 0 + } + ] } ``` diff --git a/GNUmakefile b/GNUmakefile index 22901d666e..3469f74900 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -1,12 +1,12 @@ TEST?=$$(go list ./... |grep -v 'vendor') -WEBSITE_REPO=github.com/hashicorp/terraform-website PKG_NAME=github default: build tools: - go install github.com/client9/misspell/cmd/misspell@v0.3.4 - go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.6.0 + go install github.com/golangci/misspell/cmd/misspell@latest + go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.6 + go install github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs@v0.24 build: fmtcheck CGO_ENABLED=0 go build -ldflags="-s -w" ./... @@ -37,22 +37,14 @@ test-compile: fi CGO_ENABLED=0 go test -c $(TEST) $(TESTARGS) -website: -ifeq (,$(wildcard $(GOPATH)/src/$(WEBSITE_REPO))) - echo "$(WEBSITE_REPO) not found in your GOPATH (necessary for layouts and assets), get-ting..." - git clone https://$(WEBSITE_REPO) $(GOPATH)/src/$(WEBSITE_REPO) -endif - @$(MAKE) -C $(GOPATH)/src/$(WEBSITE_REPO) website-provider PROVIDER_PATH=$(shell pwd) PROVIDER_NAME=$(PKG_NAME) - -website-lint: - @echo "==> Checking website against linters..." - @misspell -error -source=text website/ - -website-test: -ifeq (,$(wildcard $(GOPATH)/src/$(WEBSITE_REPO))) - echo "$(WEBSITE_REPO) not found in your GOPATH (necessary for layouts and assets), get-ting..." - git clone https://$(WEBSITE_REPO) $(GOPATH)/src/$(WEBSITE_REPO) -endif - @$(MAKE) -C $(GOPATH)/src/$(WEBSITE_REPO) website-provider-test PROVIDER_PATH=$(shell pwd) PROVIDER_NAME=$(PKG_NAME) - -.PHONY: build test testacc fmt fmtcheck lint tools test-compile website website-lint website-test +docs-generate: + @echo "==> Generating docs..." + tfplugindocs generate + +docs-lint: + @echo "==> Checking docs against linters..." + @misspell -error -source=text docs/ + @tfplugindocs validate + + +.PHONY: build test testacc fmt fmtcheck lint tools test-compile docs-generate docs-lint diff --git a/docs/data-sources/actions_environment_public_key.md b/docs/data-sources/actions_environment_public_key.md new file mode 100644 index 0000000000..f10d6b90b4 --- /dev/null +++ b/docs/data-sources/actions_environment_public_key.md @@ -0,0 +1,32 @@ +--- +page_title: "github_actions_environment_public_key Data Source - terraform-provider-github" +description: |- + Get information on a GitHub Actions Environment Public Key. +--- + +# github_actions_environment_public_key (Data Source) + +Use this data source to retrieve information about a GitHub Actions public key of a specific environment. This data source is required to be used with other GitHub secrets interactions. Note that the provider `token` must have admin rights to a repository to retrieve the action public keys of it's environments. + +## Example Usage + +```terraform +data "github_actions_environment_public_key" "example" { + repository = "example_repo" + environment = "example_environment" +} +``` + + +## Schema + +### Required + +- `environment` (String) Name of the environment to get public key from. +- `repository` (String) Name of the repository to get public key from. + +### Read-Only + +- `id` (String) The ID of this resource. +- `key` (String) Actual key retrieved. +- `key_id` (String) ID of the key that has been retrieved. diff --git a/docs/data-sources/actions_environment_secrets.md b/docs/data-sources/actions_environment_secrets.md new file mode 100644 index 0000000000..cf512865de --- /dev/null +++ b/docs/data-sources/actions_environment_secrets.md @@ -0,0 +1,27 @@ +--- +page_title: "github_actions_environment_secrets Data Source - terraform-provider-github +description: |- + Get Actions secrets of the repository environment +--- + +# github_actions_environment_secrets (Data Source) + +Use this data source to retrieve the list of secrets of the repository environment. + +## Example Usage + +```terraform +data "github_actions_environment_secrets" "example" { + name = "exampleRepo" + environment = "exampleEnvironment" +} +``` + +## Argument Reference + +## Attributes Reference + +- `secrets` - list of secrets for the environment + - `name` - Name of the secret + - `created_at` - Timestamp of the secret creation + - `updated_at` - Timestamp of the secret last update diff --git a/docs/data-sources/actions_environment_variables.md b/docs/data-sources/actions_environment_variables.md new file mode 100644 index 0000000000..ccd6efa247 --- /dev/null +++ b/docs/data-sources/actions_environment_variables.md @@ -0,0 +1,28 @@ +--- +page_title: "github_actions_environment_variables Data Source - terraform-provider-github +description: |- + Get Actions variables of the repository environment +--- + +# github_actions_environment_variables (Data Source) + +Use this data source to retrieve the list of variables of the repository environment. + +## Example Usage + +```terraform +data "github_actions_environment_variables" "example" { + name = "exampleRepo" + environment = "exampleEnvironment" +} +``` + +## Argument Reference + +## Attributes Reference + +- `variables` - list of variables for the environment + - `name` - Name of the variable + - `value` - Value of the variable + - `created_at` - Timestamp of the variable creation + - `updated_at` - Timestamp of the variable last update diff --git a/docs/data-sources/actions_organization_oidc_subject_claim_customization_template.md b/docs/data-sources/actions_organization_oidc_subject_claim_customization_template.md new file mode 100644 index 0000000000..ec82b0fbeb --- /dev/null +++ b/docs/data-sources/actions_organization_oidc_subject_claim_customization_template.md @@ -0,0 +1,24 @@ +--- +page_title: "github_actions_organization_oidc_subject_claim_customization_template Data Source - terraform-provider-github +description: |- + Get a GitHub Actions organization OpenID Connect customization template +--- + +# github_actions_organization_oidc_subject_claim_customization_template (Data Source) + +Use this data source to retrieve the OpenID Connect subject claim customization template for an organization + +## Example Usage + +```terraform +data "github_actions_organization_oidc_subject_claim_customization_template" "example" { +} +``` + + +## Schema + +### Read-Only + +- `id` (String) The ID of this resource. +- `include_claim_keys` (List of String) The list of OpenID Connect claim keys diff --git a/docs/data-sources/actions_organization_public_key.md b/docs/data-sources/actions_organization_public_key.md new file mode 100644 index 0000000000..ba647a71cd --- /dev/null +++ b/docs/data-sources/actions_organization_public_key.md @@ -0,0 +1,20 @@ +--- +page_title: "github_actions_organization_public_key Data Source - terraform-provider-github +description: |- + Get information on a GitHub Actions Organization Public Key. +--- + +# github_actions_organization_public_key (Data Source) + +Use this data source to retrieve information about a GitHub Actions Organization public key. This data source is required to be used with other GitHub secrets interactions. Note that the provider `token` must have admin rights to an organization to retrieve it's action public key. + +## Example Usage + +```terraform +data "github_actions_organization_public_key" "example" {} +``` + +## Attributes Reference + +- `key_id` - ID of the key that has been retrieved. +- `key` - Actual key retrieved. diff --git a/docs/data-sources/actions_organization_registration_token.md b/docs/data-sources/actions_organization_registration_token.md new file mode 100644 index 0000000000..d06942a774 --- /dev/null +++ b/docs/data-sources/actions_organization_registration_token.md @@ -0,0 +1,23 @@ +--- +page_title: "github_actions_organization_registration_token Data Source - terraform-provider-github +description: |- + Get a GitHub Actions organization registration token. +--- + +# github_actions_organization_registration_token (Data Source) + +Use this data source to retrieve a GitHub Actions organization registration token. This token can then be used to register a self-hosted runner. + +## Example Usage + +```terraform +data "github_actions_organization_registration_token" "example" { +} +``` + +## Argument Reference + +## Attributes Reference + +- `token` - The token that has been retrieved. +- `expires_at` - The token expiration date. diff --git a/docs/data-sources/actions_organization_secrets.md b/docs/data-sources/actions_organization_secrets.md new file mode 100644 index 0000000000..5afc4e8540 --- /dev/null +++ b/docs/data-sources/actions_organization_secrets.md @@ -0,0 +1,26 @@ +--- +page_title: "github_actions_organization_secrets Data Source - terraform-provider-github +description: |- + Get actions secrets of the organization +--- + +# github_actions_organization_secrets (Data Source) + +Use this data source to retrieve the list of secrets of the organization. + +## Example Usage + +```terraform +data "github_actions_organization_secrets" "example" { +} +``` + +## Argument Reference + +## Attributes Reference + +- `secrets` - list of secrets for the repository + - `name` - Secret name + - `visibility` - Secret visibility + - `created_at` - Timestamp of the secret creation + - `updated_at` - Timestamp of the secret last update diff --git a/docs/data-sources/actions_organization_variables.md b/docs/data-sources/actions_organization_variables.md new file mode 100644 index 0000000000..c2743dda79 --- /dev/null +++ b/docs/data-sources/actions_organization_variables.md @@ -0,0 +1,27 @@ +--- +page_title: "github_actions_organization_variables Data Source - terraform-provider-github +description: |- + Get Actions variables of the organization +--- + +# github_actions_organization_variables (Data Source) + +Use this data source to retrieve the list of variables of the organization. + +## Example Usage + +```terraform +data "github_actions_organization_variables" "example" { +} +``` + +## Argument Reference + +## Attributes Reference + +- `variables` - list of variables for the repository + - `name` - Name of the variable + - `value` - Value of the variable + - `visibility` - Visibility of the variable + - `created_at` - Timestamp of the variable creation + - `updated_at` - Timestamp of the variable last update diff --git a/docs/data-sources/actions_public_key.md b/docs/data-sources/actions_public_key.md new file mode 100644 index 0000000000..236d2ee65f --- /dev/null +++ b/docs/data-sources/actions_public_key.md @@ -0,0 +1,26 @@ +--- +page_title: "github_actions_public_key Data Source - terraform-provider-github +description: |- + Get information on a GitHub Actions Public Key. +--- + +# github_actions_public_key (Data Source) + +Use this data source to retrieve information about a GitHub Actions public key. This data source is required to be used with other GitHub secrets interactions. Note that the provider `token` must have admin rights to a repository to retrieve it's action public key. + +## Example Usage + +```terraform +data "github_actions_public_key" "example" { + repository = "example_repo" +} +``` + +## Argument Reference + +- `repository` - (Required) Name of the repository to get public key from. + +## Attributes Reference + +- `key_id` - ID of the key that has been retrieved. +- `key` - Actual key retrieved. diff --git a/docs/data-sources/actions_registration_token.md b/docs/data-sources/actions_registration_token.md new file mode 100644 index 0000000000..b5025f8a99 --- /dev/null +++ b/docs/data-sources/actions_registration_token.md @@ -0,0 +1,26 @@ +--- +page_title: "github_actions_registration_token Data Source - terraform-provider-github +description: |- + Get a GitHub Actions repository registration token. +--- + +# github_actions_registration_token (Data Source) + +Use this data source to retrieve a GitHub Actions repository registration token. This token can then be used to register a self-hosted runner. + +## Example Usage + +```terraform +data "github_actions_registration_token" "example" { + repository = "example_repo" +} +``` + +## Argument Reference + +- `repository` - (Required) Name of the repository to get a GitHub Actions registration token for. + +## Attributes Reference + +- `token` - The token that has been retrieved. +- `expires_at` - The token expiration date. diff --git a/docs/data-sources/actions_repository_oidc_subject_claim_customization_template.md b/docs/data-sources/actions_repository_oidc_subject_claim_customization_template.md new file mode 100644 index 0000000000..f9119c8a8b --- /dev/null +++ b/docs/data-sources/actions_repository_oidc_subject_claim_customization_template.md @@ -0,0 +1,26 @@ +--- +page_title: "github_actions_repository_oidc_subject_claim_customization_template Data Source - terraform-provider-github +description: |- + Get a GitHub Actions repository's OpenID Connect customization template +--- + +# github_actions_repository_oidc_subject_claim_customization_template (Data Source) + +Use this data source to retrieve the OpenID Connect subject claim customization template for a repository + +## Example Usage + +```terraform +data "github_actions_repository_oidc_subject_claim_customization_template" "example" { + name = "example_repository" +} +``` + +## Argument Reference + +- `name` - (Required) Name of the repository to get the OpenID Connect subject claim customization template for. + +## Attributes Reference + +- `use_default` - Whether the repository uses the default template. +- `include_claim_keys` - The list of OpenID Connect claim keys. diff --git a/docs/data-sources/actions_secrets.md b/docs/data-sources/actions_secrets.md new file mode 100644 index 0000000000..de60596d69 --- /dev/null +++ b/docs/data-sources/actions_secrets.md @@ -0,0 +1,29 @@ +--- +page_title: "github_actions_secrets Data Source - terraform-provider-github +description: |- + Get actions secrets for a repository +--- + +# github_actions_secrets (Data Source) + +Use this data source to retrieve the list of secrets for a GitHub repository. + +## Example Usage + +```terraform +data "github_actions_secrets" "example" { + name = "example" +} +``` + +## Argument Reference + +- `name` - (Optional) The name of the repository. +- `full_name` - (Optional) Full name of the repository (in `org/name` format). + +## Attributes Reference + +- `secrets` - list of secrets for the repository + - `name` - Secret name + - `created_at` - Timestamp of the secret creation + - `updated_at` - Timestamp of the secret last update diff --git a/docs/data-sources/actions_variables.md b/docs/data-sources/actions_variables.md new file mode 100644 index 0000000000..c2795503e9 --- /dev/null +++ b/docs/data-sources/actions_variables.md @@ -0,0 +1,30 @@ +--- +page_title: "github_actions_variables Data Source - terraform-provider-github +description: |- + Get Actions variables for a repository +--- + +# github_actions_variables (Data Source) + +Use this data source to retrieve the list of variables for a GitHub repository. + +## Example Usage + +```terraform +data "github_actions_variables" "example" { + name = "example" +} +``` + +## Argument Reference + +- `name` - (Optional) The name of the repository. +- `full_name` - (Optional) Full name of the repository (in `org/name` format). + +## Attributes Reference + +- `variables` - list of variables for the repository + - `name` - Name of the variable + - `value` - Value of the variable + - `created_at` - Timestamp of the variable creation + - `updated_at` - Timestamp of the variable last update diff --git a/docs/data-sources/app.md b/docs/data-sources/app.md new file mode 100644 index 0000000000..c07dbe4ff4 --- /dev/null +++ b/docs/data-sources/app.md @@ -0,0 +1,31 @@ +--- +page_title: "github_app Data Source - terraform-provider-github" +description: |- + Use this data source to retrieve information about a GitHub App. +--- + +# github_app (Data Source) + +Use this data source to retrieve information about a GitHub App. + +## Example Usage + +```terraform +data "github_app" "foobar" { + slug = "foobar" +} +``` + + +## Schema + +### Required + +- `slug` (String) The URL-friendly name of your GitHub App. + +### Read-Only + +- `description` (String) The app's description. +- `id` (String) The ID of this resource. +- `name` (String) The app's full name. +- `node_id` (String) The Node ID of the app. diff --git a/docs/data-sources/app_token.md b/docs/data-sources/app_token.md new file mode 100644 index 0000000000..2f16a1f4d6 --- /dev/null +++ b/docs/data-sources/app_token.md @@ -0,0 +1,35 @@ +--- +page_title: "github_app_token Data Source - terraform-provider-github +description: |- + Generate a GitHub APP JWT. +--- + +# github_app_token (Data Source) + +Use this data source to generate a [GitHub App JWT](https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/generating-a-json-web-token-jwt-for-a-github-app). + +## Example Usage + +```terraform +data "github_app_token" "this" { + app_id = "123456" + installation_id = "78910" + pem_file = file("foo/bar.pem") +} +``` + +## Argument Reference + +The following arguments are supported: + +- `app_id` - (Required) This is the ID of the GitHub App. + +- `installation_id` - (Required) This is the ID of the GitHub App installation. + +- `pem_file` - (Required) This is the contents of the GitHub App private key PEM file. + +## Attribute Reference + +The following additional attributes are exported: + +- `token` - The generated GitHub APP JWT. diff --git a/docs/data-sources/branch.md b/docs/data-sources/branch.md new file mode 100644 index 0000000000..46f6ed3b9e --- /dev/null +++ b/docs/data-sources/branch.md @@ -0,0 +1,36 @@ +--- +page_title: "github_branch Data Source - terraform-provider-github +description: |- + Get information about a repository branch. +--- + +# github_branch (Data Source) + +Use this data source to retrieve information about a repository branch. + +## Example Usage + +```terraform +data "github_branch" "development" { + repository = "example" + branch = "development" +} +``` + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The GitHub repository name. + +- `branch` - (Required) The repository branch to retrieve. + +## Attribute Reference + +The following additional attributes are exported: + +- `etag` - An etag representing the Branch object. + +- `ref` - A string representing a branch reference, in the form of `refs/heads/`. + +- `sha` - A string storing the reference's `HEAD` commit's SHA1. diff --git a/docs/data-sources/branch_protection_rules.md b/docs/data-sources/branch_protection_rules.md new file mode 100644 index 0000000000..db18684133 --- /dev/null +++ b/docs/data-sources/branch_protection_rules.md @@ -0,0 +1,29 @@ +--- +page_title: "github_branch_protection_rules Data Source - terraform-provider-github +description: |- + Get information about a repository branch protection rules. +--- + +# github_branch_protection_rules (Data Source) + +Use this data source to retrieve a list of repository branch protection rules. + +## Example Usage + +```terraform +data "github_branch_protection_rules" "example" { + repository = "example" +} +``` + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The GitHub repository name. + +## Attribute Reference + +- `rules` - Collection of Branch Protection Rules. Each of the results conforms to the following scheme: + + - `pattern` - Identifies the protection rule pattern. diff --git a/docs/data-sources/codespaces_organization_public_key.md b/docs/data-sources/codespaces_organization_public_key.md new file mode 100644 index 0000000000..13fcc6d8b9 --- /dev/null +++ b/docs/data-sources/codespaces_organization_public_key.md @@ -0,0 +1,20 @@ +--- +page_title: "github_codespaces_organization_public_key Data Source - terraform-provider-github +description: |- + Get information on a GitHub Codespaces Organization Public Key. +--- + +# github_codespaces_organization_public_key (Data Source) + +Use this data source to retrieve information about a GitHub Codespaces Organization public key. This data source is required to be used with other GitHub secrets interactions. Note that the provider `token` must have admin rights to an organization to retrieve it's Codespaces public key. + +## Example Usage + +```terraform +data "github_codespaces_organization_public_key" "example" {} +``` + +## Attributes Reference + +- `key_id` - ID of the key that has been retrieved. +- `key` - Actual key retrieved. diff --git a/docs/data-sources/codespaces_organization_secrets.md b/docs/data-sources/codespaces_organization_secrets.md new file mode 100644 index 0000000000..98c5ab8f87 --- /dev/null +++ b/docs/data-sources/codespaces_organization_secrets.md @@ -0,0 +1,26 @@ +--- +page_title: "github_codespaces_organization_secrets Data Source - terraform-provider-github +description: |- + Get codespaces secrets of the organization +--- + +# github_codespaces_organization_secrets (Data Source) + +Use this data source to retrieve the list of codespaces secrets of the organization. + +## Example Usage + +```terraform +data "github_codespaces_organization_secrets" "example" { +} +``` + +## Argument Reference + +## Attributes Reference + +- `secrets` - list of secrets for the repository + - `name` - Secret name + - `visibility` - Secret visibility + - `created_at` - Timestamp of the secret creation + - `updated_at` - Timestamp of the secret last update diff --git a/docs/data-sources/codespaces_public_key.md b/docs/data-sources/codespaces_public_key.md new file mode 100644 index 0000000000..f6d83e9b4d --- /dev/null +++ b/docs/data-sources/codespaces_public_key.md @@ -0,0 +1,26 @@ +--- +page_title: "github_codespaces_public_key Data Source - terraform-provider-github +description: |- + Get information on a GitHub Codespaces Public Key. +--- + +# github_codespaces_public_key (Data Source) + +Use this data source to retrieve information about a GitHub Codespaces public key. This data source is required to be used with other GitHub secrets interactions. Note that the provider `token` must have admin rights to a repository to retrieve it's Codespaces public key. + +## Example Usage + +```terraform +data "github_codespaces_public_key" "example" { + repository = "example_repo" +} +``` + +## Argument Reference + +- `repository` - (Required) Name of the repository to get public key from. + +## Attributes Reference + +- `key_id` - ID of the key that has been retrieved. +- `key` - Actual key retrieved. diff --git a/docs/data-sources/codespaces_secrets.md b/docs/data-sources/codespaces_secrets.md new file mode 100644 index 0000000000..2ad735705e --- /dev/null +++ b/docs/data-sources/codespaces_secrets.md @@ -0,0 +1,33 @@ +--- +page_title: "github_codespaces_secrets Data Source - terraform-provider-github +description: |- + Get codespaces secrets for a repository +--- + +# github_codespaces_secrets (Data Source) + +Use this data source to retrieve the list of codespaces secrets for a GitHub repository. + +## Example Usage + +```terraform +data "github_codespaces_secrets" "example" { + name = "example_repository" +} + +data "github_codespaces_secrets" "example_2" { + full_name = "org/example_repository" +} +``` + +## Argument Reference + +- `name` - (Optional) The name of the repository. +- `full_name` - (Optional) Full name of the repository (in `org/name` format). + +## Attributes Reference + +- `secrets` - list of codespaces secrets for the repository + - `name` - Secret name + - `created_at` - Timestamp of the secret creation + - `updated_at` - Timestamp of the secret last update diff --git a/docs/data-sources/codespaces_user_public_key.md b/docs/data-sources/codespaces_user_public_key.md new file mode 100644 index 0000000000..e4fd750ec8 --- /dev/null +++ b/docs/data-sources/codespaces_user_public_key.md @@ -0,0 +1,20 @@ +--- +page_title: "github_codespaces_user_public_key Data Source - terraform-provider-github +description: |- + Get information on a GitHub Codespaces User Public Key. +--- + +# github_codespaces_user_public_key (Data Source) + +Use this data source to retrieve information about a GitHub Codespaces User public key. This data source is required to be used with other GitHub secrets interactions. Note that the provider `token` must have admin rights to an user to retrieve it's Codespaces public key. + +## Example Usage + +```terraform +data "github_codespaces_user_public_key" "example" {} +``` + +## Attributes Reference + +- `key_id` - ID of the key that has been retrieved. +- `key` - Actual key retrieved. diff --git a/docs/data-sources/codespaces_user_secrets.md b/docs/data-sources/codespaces_user_secrets.md new file mode 100644 index 0000000000..b8a8c1a975 --- /dev/null +++ b/docs/data-sources/codespaces_user_secrets.md @@ -0,0 +1,26 @@ +--- +page_title: "github_codespaces_user_secrets Data Source - terraform-provider-github +description: |- + Get codespaces secrets of the user +--- + +# github_codespaces_user_secrets (Data Source) + +Use this data source to retrieve the list of codespaces secrets of the user. + +## Example Usage + +```terraform +data "github_codespaces_user_secrets" "example" { +} +``` + +## Argument Reference + +## Attributes Reference + +- `secrets` - list of secrets for the repository + - `name` - Secret name + - `visibility` - Secret visibility + - `created_at` - Timestamp of the secret creation + - `updated_at` - Timestamp of the secret last update diff --git a/docs/data-sources/collaborators.md b/docs/data-sources/collaborators.md new file mode 100644 index 0000000000..f26f7d84be --- /dev/null +++ b/docs/data-sources/collaborators.md @@ -0,0 +1,68 @@ +--- +page_title: "github_collaborators Data Source - terraform-provider-github +description: |- + Get the collaborators for a given repository. +--- + +# github_collaborators (Data Source) + +Use this data source to retrieve the collaborators for a given repository. + +## Example Usage + +```terraform +data "github_collaborators" "test" { + owner = "example_owner" + repository = "example_repository" +} +``` + +## Arguments Reference + +- `owner` - (Required) The organization that owns the repository. + +- `repository` - (Required) The name of the repository. + +- `affiliation` - (Optional) Filter collaborators returned by their affiliation. Can be one of: `outside`, `direct`, `all`. Defaults to `all`. + +- `permission` - (Optional) Filter collaborators returned by their permission. Can be one of: `pull`, `triage`, `push`, `maintain`, `admin`. Defaults to not doing any filtering on permission. + +## Attributes Reference + +- `collaborator` - An Array of GitHub collaborators. Each `collaborator` block consists of the fields documented below. + +--- + +The `collaborator` block consists of: + +- `login` - The collaborator's login. + +- `id` - The ID of the collaborator. + +- `url` - The GitHub API URL for the collaborator. + +- `html_url` - The GitHub HTML URL for the collaborator. + +- `followers_url` - The GitHub API URL for the collaborator's followers. + +- `following_url` - The GitHub API URL for those following the collaborator. + +- `gists_url` - The GitHub API URL for the collaborator's gists. + +- `starred_url` - The GitHub API URL for the collaborator's starred repositories. + +- `subscriptions_url` - The GitHub API URL for the collaborator's subscribed repositories. + +- `organizations_url` - The GitHub API URL for the collaborator's organizations. + +- `repos_url` - The GitHub API URL for the collaborator's repositories. + +- `events_url` - The GitHub API URL for the collaborator's events. + +- `received_events_url` - The GitHub API URL for the collaborator's received events. + +- `type` - The type of the collaborator (ex. `user`). + +- `site_admin` - Whether the user is a GitHub admin. + +- `permission` - The permission of the collaborator. diff --git a/docs/data-sources/dependabot_organization_public_key.md b/docs/data-sources/dependabot_organization_public_key.md new file mode 100644 index 0000000000..417a053aaa --- /dev/null +++ b/docs/data-sources/dependabot_organization_public_key.md @@ -0,0 +1,20 @@ +--- +page_title: "github_dependabot_organization_public_key Data Source - terraform-provider-github +description: |- + Get information on a GitHub Dependabot Organization Public Key. +--- + +# github_dependabot_organization_public_key (Data Source) + +Use this data source to retrieve information about a GitHub Dependabot Organization public key. This data source is required to be used with other GitHub secrets interactions. Note that the provider `token` must have admin rights to an organization to retrieve it's Dependabot public key. + +## Example Usage + +```terraform +data "github_dependabot_organization_public_key" "example" {} +``` + +## Attributes Reference + +- `key_id` - ID of the key that has been retrieved. +- `key` - Actual key retrieved. diff --git a/docs/data-sources/dependabot_organization_secrets.md b/docs/data-sources/dependabot_organization_secrets.md new file mode 100644 index 0000000000..b21f3716da --- /dev/null +++ b/docs/data-sources/dependabot_organization_secrets.md @@ -0,0 +1,26 @@ +--- +page_title: "github_dependabot_organization_secrets Data Source - terraform-provider-github +description: |- + Get dependabot secrets of the organization +--- + +# github_dependabot_organization_secrets (Data Source) + +Use this data source to retrieve the list of dependabot secrets of the organization. + +## Example Usage + +```terraform +data "github_dependabot_organization_secrets" "example" { +} +``` + +## Argument Reference + +## Attributes Reference + +- `secrets` - list of secrets for the repository + - `name` - Secret name + - `visibility` - Secret visibility + - `created_at` - Timestamp of the secret creation + - `updated_at` - Timestamp of the secret last update diff --git a/docs/data-sources/dependabot_public_key.md b/docs/data-sources/dependabot_public_key.md new file mode 100644 index 0000000000..e4e5f172c7 --- /dev/null +++ b/docs/data-sources/dependabot_public_key.md @@ -0,0 +1,26 @@ +--- +page_title: "github_dependabot_public_key Data Source - terraform-provider-github +description: |- + Get information on a GitHub Dependabot Public Key. +--- + +# github_dependabot_public_key (Data Source) + +Use this data source to retrieve information about a GitHub Dependabot public key. This data source is required to be used with other GitHub secrets interactions. Note that the provider `token` must have admin rights to a repository to retrieve it's Dependabot public key. + +## Example Usage + +```terraform +data "github_dependabot_public_key" "example" { + repository = "example_repo" +} +``` + +## Argument Reference + +- `repository` - (Required) Name of the repository to get public key from. + +## Attributes Reference + +- `key_id` - ID of the key that has been retrieved. +- `key` - Actual key retrieved. diff --git a/docs/data-sources/dependabot_secrets.md b/docs/data-sources/dependabot_secrets.md new file mode 100644 index 0000000000..c066c44a8c --- /dev/null +++ b/docs/data-sources/dependabot_secrets.md @@ -0,0 +1,29 @@ +--- +page_title: "github_dependabot_secrets Data Source - terraform-provider-github +description: |- + Get dependabot secrets for a repository +--- + +# github_dependabot_secrets (Data Source) + +Use this data source to retrieve the list of dependabot secrets for a GitHub repository. + +## Example Usage + +```terraform +data "github_dependabot_secrets" "example" { + name = "example" +} +``` + +## Argument Reference + +- `name` - (Optional) The name of the repository. +- `full_name` - (Optional) Full name of the repository (in `org/name` format). + +## Attributes Reference + +- `secrets` - list of dependabot secrets for the repository + - `name` - Secret name + - `created_at` - Timestamp of the secret creation + - `updated_at` - Timestamp of the secret last update diff --git a/docs/data-sources/enterprise.md b/docs/data-sources/enterprise.md new file mode 100644 index 0000000000..6baf753cc6 --- /dev/null +++ b/docs/data-sources/enterprise.md @@ -0,0 +1,27 @@ +--- +page_title: "github_enterprise Data Source - terraform-provider-github +description: |- + Get an enterprise. +--- + +# github_enterprise (Data Source) + +Use this data source to retrieve basic information about a GitHub enterprise. + +## Example Usage + +``` +data "github_enterprise" "example" { + slug = "example-co" +} +``` + +## Attributes Reference + +- `id` - The ID of the enterprise. +- `database_id` - The database ID of the enterprise. +- `slug` - The URL slug identifying the enterprise. +- `name` - The name of the enterprise. +- `description` - The description of the enterprise. +- `created_at` - The time the enterprise was created. +- `url` - The url for the enterprise. diff --git a/docs/data-sources/external_groups.md b/docs/data-sources/external_groups.md new file mode 100644 index 0000000000..e973b19acf --- /dev/null +++ b/docs/data-sources/external_groups.md @@ -0,0 +1,37 @@ +--- +page_title: "github_external_groups Data Source - terraform-provider-github +description: |- + Retrieve external groups belonging to an organization. +--- + +# github_external_groups (Data Source) + +Use this data source to retrieve external groups belonging to an organization. + +## Example Usage + +```terraform +data "github_external_groups" "example_external_groups" {} + +locals { + local_groups = "${data.github_external_groups.example_external_groups}" +} + +output "groups" { + value = local.local_groups +} +``` + +## Argument Reference + +N/A. This resource will retrieve all the external groups belonging to an organization. + +## Attributes Reference + +- `external_groups` - an array of external groups belonging to the organization. Each group consists of the fields documented below. + +--- + +- `group_id` - the ID of the group. +- `group_name` - the name of the group. +- `updated_at` - the date the group was last updated. diff --git a/docs/data-sources/ip_ranges.md b/docs/data-sources/ip_ranges.md new file mode 100644 index 0000000000..2a4516f94b --- /dev/null +++ b/docs/data-sources/ip_ranges.md @@ -0,0 +1,45 @@ +--- +page_title: "github_ip_ranges Data Source - terraform-provider-github +description: |- + Get information on GitHub's IP addresses. +--- + +# github_ip_ranges (Data Source) + +Use this data source to retrieve information about GitHub's IP addresses. + +## Example Usage + +```terraform +data "github_ip_ranges" "test" {} +``` + +## Attributes Reference + +- `actions` - An array of IP addresses in CIDR format specifying the addresses that incoming requests from GitHub actions will originate from. +- `actions_ipv4` - A subset of the `actions` array that contains IP addresses in IPv4 CIDR format. +- `actions_ipv6` - A subset of the `actions` array that contains IP addresses in IPv6 CIDR format. +- `dependabot` - An array of IP addresses in CIDR format specifying the A records for dependabot. +- `dependabot_ipv4` - A subset of the `dependabot` array that contains IP addresses in IPv4 CIDR format. +- `dependabot_ipv6` - A subset of the `dependabot` array that contains IP addresses in IPv6 CIDR format. +- `hooks` - An Array of IP addresses in CIDR format specifying the addresses that incoming service hooks will originate from. +- `hooks_ipv4` - A subset of the `hooks` array that contains IP addresses in IPv4 CIDR format. +- `hooks_ipv6` - A subset of the `hooks` array that contains IP addresses in IPv6 CIDR format. +- `git` - An Array of IP addresses in CIDR format specifying the Git servers. +- `git_ipv4` - A subset of the `git` array that contains IP addresses in IPv4 CIDR format. +- `git_ipv6` - A subset of the `git` array that contains IP addresses in IPv6 CIDR format. +- `web` - An Array of IP addresses in CIDR format for GitHub Web. +- `web_ipv4` - A subset of the `web` array that contains IP addresses in IPv4 CIDR format. +- `web_ipv6` - A subset of the `web` array that contains IP addresses in IPv6 CIDR format. +- `api` - An Array of IP addresses in CIDR format for the GitHub API. +- `api_ipv4` - A subset of the `api` array that contains IP addresses in IPv4 CIDR format. +- `api_ipv6` - A subset of the `api` array that contains IP addresses in IPv6 CIDR format. +- `packages` - An Array of IP addresses in CIDR format specifying the A records for GitHub Packages. +- `packages_ipv4` - A subset of the `packages` array that contains IP addresses in IPv4 CIDR format. +- `packages_ipv6` - A subset of the `packages` array that contains IP addresses in IPv6 CIDR format. +- `pages` - An Array of IP addresses in CIDR format specifying the A records for GitHub Pages. +- `pages_ipv4` - A subset of the `pages` array that contains IP addresses in IPv4 CIDR format. +- `pages_ipv6` - A subset of the `pages` array that contains IP addresses in IPv6 CIDR format. +- `importer` - An Array of IP addresses in CIDR format specifying the A records for GitHub Importer. +- `importer_ipv4` - A subset of the `importer` array that contains IP addresses in IPv4 CIDR format. +- `importer_ipv6` - A subset of the `importer` array that contains IP addresses in IPv6 CIDR format. diff --git a/docs/data-sources/issue_labels.md b/docs/data-sources/issue_labels.md new file mode 100644 index 0000000000..c83e19493e --- /dev/null +++ b/docs/data-sources/issue_labels.md @@ -0,0 +1,29 @@ +--- +page_title: "github_issue_labels Data Source - terraform-provider-github +description: |- + Get the labels for a given repository. +--- + +# github_issue_labels (Data Source) + +Use this data source to retrieve the labels for a given repository. + +## Example Usage + +```terraform +data "github_issue_labels" "test" { + repository = "example_repository" +} +``` + +## Arguments Reference + +- `repository` - (Required) The name of the repository. + +## Attributes Reference + +- `labels` - The list of this repository's labels. Each element of `labels` has the following attributes: + - `name` - The name of the label. + - `color` - The hexadecimal color code for the label, without the leading #. + - `description` - A short description of the label. + - `url` - The URL of the label. diff --git a/docs/data-sources/membership.md b/docs/data-sources/membership.md new file mode 100644 index 0000000000..4fa32cb06d --- /dev/null +++ b/docs/data-sources/membership.md @@ -0,0 +1,30 @@ +--- +page_title: "github_membership Data Source - terraform-provider-github +description: |- + Get information on user membership in an organization. +--- + +# github_membership (Data Source) + +Use this data source to find out if a user is a member of your organization, as well as what role they have within it. If the user's membership in the organization is pending their acceptance of an invite, the role they would have once they accept will be returned. + +## Example Usage + +```terraform +data "github_membership" "membership_for_some_user" { + username = "SomeUser" +} +``` + +## Argument Reference + +- `username` - (Required) The username to lookup in the organization. + +- `organization` - (Optional) The organization to check for the above username. + +## Attributes Reference + +- `username` - The username. +- `role` - `admin` or `member` -- the role the user has within the organization. +- `etag` - An etag representing the membership object. +- `state` - `active` or `pending` -- the state of membership within the organization. `active` if the member has accepted the invite, or `pending` if the invite is still pending. diff --git a/docs/data-sources/organization.md b/docs/data-sources/organization.md new file mode 100644 index 0000000000..27a398079e --- /dev/null +++ b/docs/data-sources/organization.md @@ -0,0 +1,58 @@ +--- +page_title: "github_organization Data Source - terraform-provider-github +description: |- + Get an organization. +--- + +# github_organization (Data Source) + +Use this data source to retrieve basic information about a GitHub Organization. + +## Example Usage + +```terraform +data "github_organization" "example" { + name = "github" +} +``` + +## Argument Reference + +- `name` - (Required) The name of the organization. +- `ignore_archived_repos` - (Optional) Whether or not to include archived repos in the `repositories` list. Defaults to `false`. +- `summary_only` - (Optional) Exclude the repos, members and other attributes from the returned result. Defaults to `false`. + +## Attributes Reference + +- `id` - The ID of the organization +- `node_id` - GraphQL global node ID for use with the v4 API +- `name` - The organization's public profile name +- `orgname` - The organization's name as used in URLs and the API +- `login` - The organization account login +- `description` - The organization account description +- `plan` - The organization account plan name +- `repositories` - (`list`) A list of the full names of the repositories in the organization formatted as `owner/name` strings +- `members` - **Deprecated**: use `users` instead by replacing `github_organization.example.members` to `github_organization.example.users[*].login` which will give you the same value, expect this field to be removed in next major version +- `users` - (`list`) A list with the members of the organization with following fields: + - `id` - The ID of the member + - `login` - The members login + - `email` - Publicly available email + - `role` - Member role `ADMIN`, `MEMBER` +- `two_factor_requirement_enabled` - Whether two-factor authentication is required for all members of the organization. +- `default_repository_permission` - Default permission level members have for organization repositories. +- `members_allowed_repository_creation_type` - The type of repository allowed to be created by members of the organization. Can be one of `ALL`, `PUBLIC`, `PRIVATE`, `NONE`. +- `members_can_create_repositories` - Whether non-admin organization members can create repositories. +- `members_can_create_internal_repositories` - Whether organization members can create internal repositories. +- `members_can_create_private_repositories` - Whether organization members can create private repositories. +- `members_can_create_public_repositories` - Whether organization members can create public repositories. +- `members_can_create_pages` - Whether organization members can create pages sites. +- `members_can_create_public_pages` - Whether organization members can create public pages sites. +- `members_can_create_private_pages` - Whether organization members can create private pages sites. +- `members_can_fork_private_repositories` - Whether organization members can create private repository forks. +- `web_commit_signoff_required` - Whether organization members must sign all commits. +- `advanced_security_enabled_for_new_repositories` - Whether advanced security is enabled for new repositories. +- `dependabot_alerts_enabled_for_new_repositories` - Whether Dependabot alerts is automatically enabled for new repositories. +- `dependabot_security_updates_enabled_for_new_repositories` - Whether Dependabot security updates is automatically enabled for new repositories. +- `dependency_graph_enabled_for_new_repositories` - Whether dependency graph is automatically enabled for new repositories. +- `secret_scanning_enabled_for_new_repositories` - Whether secret scanning is automatically enabled for new repositories. +- `secret_scanning_push_protection_enabled_for_new_repositories` - Whether secret scanning push protection is automatically enabled for new repositories. diff --git a/docs/data-sources/organization_custom_properties.md b/docs/data-sources/organization_custom_properties.md new file mode 100644 index 0000000000..0a24874dbd --- /dev/null +++ b/docs/data-sources/organization_custom_properties.md @@ -0,0 +1,39 @@ +--- +page_title: "github_organization_custom_properties Data Source - terraform-provider-github +description: |- + Get information about a GitHub organization custom property +--- + +# github_organization_custom_properties (Data Source) + +Use this data source to retrieve information about a GitHub organization custom property. + +## Example Usage + +```terraform +data "github_organization_custom_properties" "environment" { + property_name = "environment" +} +``` + +## Argument Reference + +The following arguments are supported: + +- `property_name` - (Required) The name of the custom property to retrieve. + +## Attributes Reference + +- `property_name` - The name of the custom property. + +- `value_type` - The type of the custom property. Can be one of `string`, `single_select`, `multi_select`, or `true_false`. + +- `required` - Whether the custom property is required. + +- `description` - The description of the custom property. + +- `default_value` - The default value of the custom property. + +- `allowed_values` - List of allowed values for the custom property. Only populated when `value_type` is `single_select` or `multi_select`. + +- `values_editable_by` - Who can edit the values of the custom property. Can be one of `org_actors` or `org_and_repo_actors`. diff --git a/docs/data-sources/organization_custom_role.md b/docs/data-sources/organization_custom_role.md new file mode 100644 index 0000000000..eb4b79bab7 --- /dev/null +++ b/docs/data-sources/organization_custom_role.md @@ -0,0 +1,36 @@ +--- +page_title: "github_organization_custom_role Data Source - terraform-provider-github +description: |- + Get a custom role from a GitHub Organization for use in repositories. +--- + +# github_organization_custom_role (Data Source) + +~> **Note:** This data source is deprecated, please use the `github_organization_repository_role` data source instead. + +Use this data source to retrieve information about a custom role in a GitHub Organization. + +~> Note: Custom roles are currently only available in GitHub Enterprise Cloud. + +## Example Usage + +```terraform +data "github_organization_custom_role" "example" { + name = "example" +} +``` + +## Argument Reference + +The following arguments are supported: + +- `name` - (Required) The name of the custom role. + +## Attributes Reference + +The following additional attributes are exported: + +- `id` - The ID of the custom role. +- `description` - The description for the custom role. +- `base_role` - The system role from which the role inherits permissions. +- `permissions` - A list of additional permissions included in this role. diff --git a/docs/data-sources/organization_external_identities.md b/docs/data-sources/organization_external_identities.md new file mode 100644 index 0000000000..f9840dfa56 --- /dev/null +++ b/docs/data-sources/organization_external_identities.md @@ -0,0 +1,45 @@ +--- +page_title: "github_organization_external_identities Data Source - terraform-provider-github +description: |- + Get a list of organization members and their SAML linked external identity NameID +--- + +# github_organization_external_identities (Data Source) + +Use this data source to retrieve each organization member's SAML or SCIM user attributes. + +## Example Usage + +```terraform +data "github_organization_external_identities" "all" {} +``` + +## Attributes Reference + +- `identities` - An Array of identities returned from GitHub + +--- + +Each element in the `identities` block consists of: + +- `login` - The username of the GitHub user +- `saml_identity` - An Object containing the user's SAML data. This object will be empty if the user is not managed by SAML. +- `scim_identity` - An Object contining the user's SCIM data. This object will be empty if the user is not managed by SCIM. + +--- + +If a user is managed by SAML, the `saml_identity` object will contain: + +- `name_id` - The member's SAML NameID +- `username` - The member's SAML Username +- `family_name` - The member's SAML Family Name +- `given_name` - The member's SAML Given Name + +--- + +If a user is managed by SCIM, the `scim_identity` object will contain: + +- `username` - The member's SCIM Username. (will be empty string if user is not managed by SCIM) +- `groups` - The member's SCIM Groups +- `family_name` - The member's SCIM Family Name +- `given_name` - The member's SCIM Given Name diff --git a/docs/data-sources/organization_ip_allow_list.md b/docs/data-sources/organization_ip_allow_list.md new file mode 100644 index 0000000000..8ece41bf05 --- /dev/null +++ b/docs/data-sources/organization_ip_allow_list.md @@ -0,0 +1,30 @@ +--- +page_title: "github_organization_ip_allow_list Data Source - terraform-provider-github +description: |- + Get the IP allow list of an organization. +--- + +# github_organization_ip_allow_list (Data Source) + +Use this data source to retrieve information about the IP allow list of an organization. The allow list for IP addresses will block access to private resources via the web, API, and Git from any IP addresses that are not on the allow list. + +## Example Usage + +```terraform +data "github_organization_ip_allow_list" "all" {} +``` + +## Attributes Reference + +- `ip_allow_list` - An Array of allowed IP addresses. + +--- + +Each element in the `ip_allow_list` block consists of: + +- `id` - The ID of the IP allow list entry. +- `name` - The name of the IP allow list entry. +- `allow_list_value` - A single IP address or range of IP addresses in CIDR notation. +- `is_active` - Whether the entry is currently active. +- `created_at` - Identifies the date and time when the object was created. +- `updated_at` - Identifies the date and time when the object was last updated. diff --git a/docs/data-sources/organization_repository_role.md b/docs/data-sources/organization_repository_role.md new file mode 100644 index 0000000000..c31d67402f --- /dev/null +++ b/docs/data-sources/organization_repository_role.md @@ -0,0 +1,32 @@ +--- +page_title: "github_organization_repository_role Data Source - terraform-provider-github +description: |- + Lookup a custom organization repository role. +--- + +# github_organization_repository_role (Data Source) + +Lookup a custom organization repository role. + +~> **Note**: Custom organization repository roles are currently only available in GitHub Enterprise Cloud. + +## Example Usage + +```terraform +data "github_organization_repository_role" "example" { + role_id = 1234 +} +``` + +## Schema + +### Required + +- `role_id` (Number) The ID of the organization repository role. + +### Read-Only + +- `name` (String) The name of the organization repository role. +- `description` (String) The description of the organization repository role. +- `base_role` (String) The system role from which this role inherits permissions. +- `permissions` (Set of String) The permissions included in this role. diff --git a/docs/data-sources/organization_repository_roles.md b/docs/data-sources/organization_repository_roles.md new file mode 100644 index 0000000000..91fa53df52 --- /dev/null +++ b/docs/data-sources/organization_repository_roles.md @@ -0,0 +1,34 @@ +--- +page_title: "github_organization_repository_roles Data Source - terraform-provider-github +description: |- + Lookup all custom repository roles in an organization. +--- + +# github_organization_repository_roles (Data Source) + +Lookup all custom repository roles in an organization. + +~> **Note**: Custom organization repository roles are currently only available in GitHub Enterprise Cloud. + +## Example Usage + +```terraform +data "github_organization_repository_roles" "example" { +} +``` + +## Schema + +### Read-Only + +- `roles` (Set of Object, see [schema](#nested-schema-for-roles)) Available organization repository roles. + +## Nested Schema for `roles` + +### Read-Only + +- `role_id` (Number) The ID of the organization repository role. +- `name` (String) The name of the organization repository role. +- `description` (String) The description of the organization repository role. +- `base_role` (String) The system role from which this role inherits permissions. +- `permissions` (Set of String) The permissions included in this role. diff --git a/docs/data-sources/organization_role.md b/docs/data-sources/organization_role.md new file mode 100644 index 0000000000..4f5a266441 --- /dev/null +++ b/docs/data-sources/organization_role.md @@ -0,0 +1,31 @@ +--- +page_title: "github_organization_role Data Source - terraform-provider-github +description: |- + Lookup a custom organization role. +--- + +# github_organization_role (Data Source) + +Lookup a custom organization role. + +## Example Usage + +```terraform +data "github_organization_role" "example" { + role_id = 1234 +} +``` + +## Schema + +### Required + +- `role_id` (Number) The ID of the organization role. + +### Read-Only + +- `name` (String) The name of the organization role. +- `description` (String) The description of the organization role. +- `source` (String) The source of this role; one of `Predefined`, `Organization`, or `Enterprise`. +- `base_role` (String) The system role from which this role inherits permissions. +- `permissions` (Set of String) The permissions included in this role. diff --git a/docs/data-sources/organization_role_teams.md b/docs/data-sources/organization_role_teams.md new file mode 100644 index 0000000000..159175c470 --- /dev/null +++ b/docs/data-sources/organization_role_teams.md @@ -0,0 +1,36 @@ +--- +page_title: "github_organization_role_teams Data Source - terraform-provider-github +description: |- + Lookup all teams assigned to a custom organization role. +--- + +# github_organization_role_teams (Data Source) + +Lookup all teams assigned to a custom organization role. + +## Example Usage + +```terraform +data "github_organization_role_teams" "example" { + role_id = 1234 +} +``` + +## Schema + +### Required + +- `role_id` (Number) The ID of the organization role. + +### Read-Only + +- `teams` (Set of Object, see [schema](#nested-schema-for-teams)) Teams assigned to the organization role. + +## Nested Schema for `teams` + +### Read-Only + +- `team_id` (Number) The ID of the team. +- `slug` (String) The Slug of the team name. +- `name` (String) The name of the team. +- `permission` (String) The permission that the team will have for its repositories. diff --git a/docs/data-sources/organization_role_users.md b/docs/data-sources/organization_role_users.md new file mode 100644 index 0000000000..6b47666062 --- /dev/null +++ b/docs/data-sources/organization_role_users.md @@ -0,0 +1,34 @@ +--- +page_title: "github_organization_role_users Data Source - terraform-provider-github +description: |- + Lookup all users assigned to a custom organization role. +--- + +# github_organization_role_users (Data Source) + +Lookup all users assigned to a custom organization role. + +## Example Usage + +```terraform +data "github_organization_role_users" "example" { + role_id = 1234 +} +``` + +## Schema + +### Required + +- `role_id` (Number) The ID of the organization role. + +### Read-Only + +- `users` (Set of Object, see [schema](#nested-schema-for-users)) Users assigned to the organization role. + +## Nested Schema for `users` + +### Read-Only + +- `user_id` (Number) The ID of the user. +- `login` (String) The login for the GitHub user account. diff --git a/docs/data-sources/organization_roles.md b/docs/data-sources/organization_roles.md new file mode 100644 index 0000000000..078a4c996e --- /dev/null +++ b/docs/data-sources/organization_roles.md @@ -0,0 +1,33 @@ +--- +page_title: "github_organization_roles Data Source - terraform-provider-github +description: |- + Lookup all custom roles in an organization. +--- + +# github_organization_roles (Data Source) + +Lookup all custom roles in an organization. + +## Example Usage + +```terraform +data "github_organization_roles" "example" { +} +``` + +## Schema + +### Read-Only + +- `roles` (Set of Object, see [schema](#nested-schema-for-roles)) Available organization roles. + +## Nested Schema for `roles` + +### Read-Only + +- `role_id` (Number) The ID of the organization role. +- `name` (String) The name of the organization role. +- `description` (String) The description of the organization role. +- `source` (String) The source of this role; one of `Predefined`, `Organization`, or `Enterprise`. +- `base_role` (String) The system role from which this role inherits permissions. +- `permissions` (Set of String) The permissions included in this role. diff --git a/docs/data-sources/organization_security_managers.md b/docs/data-sources/organization_security_managers.md new file mode 100644 index 0000000000..f58e8dbaf5 --- /dev/null +++ b/docs/data-sources/organization_security_managers.md @@ -0,0 +1,30 @@ +--- +page_title: "github_organization_security_managers Data Source - terraform-provider-github +description: |- + Get the security managers for an organization. +--- + +# github_organization_security_managers (Data Source) + +~> **Note:** This data source is deprecated, please use the `github_organization_role_team` resource instead. + +Use this data source to retrieve the security managers for an organization. + +## Example Usage + +```terraform +data "github_organization_security_managers" "test" {} +``` + +## Attributes Reference + +- `teams` - An list of GitHub teams. Each `team` block consists of the fields documented below. + +---___ + +The `team` block consists of: + +- `id` - Unique identifier of the team. +- `slug` - Name based identifier of the team. +- `name` - Name of the team. +- `permission` - Permission that the team will have for its repositories. diff --git a/docs/data-sources/organization_team_sync_groups.md b/docs/data-sources/organization_team_sync_groups.md new file mode 100644 index 0000000000..fce7938d82 --- /dev/null +++ b/docs/data-sources/organization_team_sync_groups.md @@ -0,0 +1,29 @@ +--- +page_title: "github_organization_team_sync_groups Data Source - terraform-provider-github +description: |- + Get the external identity provider (IdP) groups for an organization. +--- + +# github_organization_team_sync_groups (Data Source) + +Use this data source to retrieve the identity provider (IdP) groups for an organization. + +## Example Usage + +```terraform +data "github_organization_team_sync_groups" "test" {} +``` + +## Attributes Reference + +- `groups` - An Array of GitHub Identity Provider Groups. Each `group` block consists of the fields documented below. + +--- + +The `group` block consists of: + +- `group_id` - The ID of the IdP group. + +- `group_name` - The name of the IdP group. + +- `group_description` - The description of the IdP group. diff --git a/docs/data-sources/organization_teams.md b/docs/data-sources/organization_teams.md new file mode 100644 index 0000000000..9db6258998 --- /dev/null +++ b/docs/data-sources/organization_teams.md @@ -0,0 +1,48 @@ +--- +page_title: "github_organization_teams Data Source - terraform-provider-github +description: |- + Get information on all GitHub teams of an organization. +--- + +# github_organization_teams (Data Source) + +Use this data source to retrieve information about all GitHub teams in an organization. + +## Example Usage + +To retrieve *all* teams of the organization: + +```terraform +data "github_organization_teams" "all" {} +``` + +To retrieve only the team's at the root of the organization: + +```terraform +data "github_organization_teams" "root_teams" { + root_teams_only = true +} +``` + +## Attributes Reference + +- `teams` - (Required) An Array of GitHub Teams. Each `team` block consists of the fields documented below. +- `root_teams_only` - (Optional) Only return teams that are at the organization's root, i.e. no nested teams. Defaults to `false`. +- `summary_only` - (Optional) Exclude the members and repositories of the team from the returned result. Defaults to `false`. +- `results_per_page` - (Optional) Set the number of results per graphql query. Reducing this number can alleviate timeout errors. Accepts a value between 0 - 100. Defaults to `100`. + +--- + +The `team` block consists of: + +- `id` - The ID of the team. +- `node_id` - The Node ID of the team. +- `slug` - The slug of the team. +- `name` - The team's full name. +- `description` - The team's description. +- `privacy` - The team's privacy type. +- `members` - List of team members. Not returned if `summary_only = true` +- `repositories` - List of team repositories. Not returned if `summary_only = true` +- `parent_team_id` - The ID of the parent team, if there is one. +- `parent_team_slug` - The slug of the parent team, if there is one. +- `parent` - (**DEPRECATED**) The parent team, use `parent_team_id` or `parent_team_slug` instead. diff --git a/docs/data-sources/organization_webhooks.md b/docs/data-sources/organization_webhooks.md new file mode 100644 index 0000000000..c56765ce64 --- /dev/null +++ b/docs/data-sources/organization_webhooks.md @@ -0,0 +1,31 @@ +--- +page_title: "github_organization_webhooks Data Source - terraform-provider-github +description: |- + Get information on all GitHub webhooks of the organization. +--- + +# github_organization_webhooks (Data Source) + +Use this data source to retrieve all webhooks of the organization. + +## Example Usage + +To retrieve *all* webhooks of the organization: + +```terraform +data "github_organization_webhooks" "all" {} +``` + +## Attributes Reference + +- `webhooks` - An Array of GitHub Webhooks. Each `webhook` block consists of the fields documented below. + +--- + +The `webhook` block consists of: + +- `id` - the ID of the webhook. +- `type` - the type of the webhook. +- `name` - the name of the webhook. +- `url` - the url of the webhook. +- `active` - `true` if the webhook is active. diff --git a/docs/data-sources/ref.md b/docs/data-sources/ref.md new file mode 100644 index 0000000000..08c43e1012 --- /dev/null +++ b/docs/data-sources/ref.md @@ -0,0 +1,39 @@ +--- +page_title: "github_ref Data Source - terraform-provider-github +description: |- + Get information about a repository ref. +--- + +# github_ref (Data Source) + +Use this data source to retrieve information about a repository ref. + +## Example Usage + +```terraform +data "github_ref" "development" { + owner = "example" + repository = "example" + ref = "heads/development" +} +``` + +## Argument Reference + +The following arguments are supported: + +- `owner` - (Required) Owner of the repository. + +- `repository` - (Required) The GitHub repository name. + +- `ref` - (Required) The repository ref to look up. Must be formatted `heads/` for branches, and `tags/` for tags. + +## Attribute Reference + +The following additional attributes are exported: + +- `etag` - An etag representing the ref. + +- `id` - A string storing a reference to the repository name and ref. + +- `sha` - A string storing the reference's `HEAD` commit's SHA1. diff --git a/docs/data-sources/release.md b/docs/data-sources/release.md new file mode 100644 index 0000000000..89f10e024b --- /dev/null +++ b/docs/data-sources/release.md @@ -0,0 +1,85 @@ +--- +page_title: "github_release Data Source - terraform-provider-github +description: |- + Get information on a GitHub release. +--- + +# github_release (Data Source) + +Use this data source to retrieve information about a GitHub release in a specific repository. + +## Example Usage + +To retrieve the latest release that is present in a repository: + +```terraform +data "github_release" "example" { + repository = "example-repository" + owner = "example-owner" + retrieve_by = "latest" +} +``` + +To retrieve a specific release from a repository based on it's ID: + +```terraform +data "github_release" "example" { + repository = "example-repository" + owner = "example-owner" + retrieve_by = "id" + id = 12345 +} +``` + +Finally, to retrieve a release based on it's tag: + +```terraform +data "github_release" "example" { + repository = "example-repository" + owner = "example-owner" + retrieve_by = "tag" + release_tag = "v1.0.0" +} +``` + +## Argument Reference + +- `repository` - (Required) Name of the repository to retrieve the release from. + +- `owner` - (Required) Owner of the repository. + +- `retrieve_by` - (Required) Describes how to fetch the release. Valid values are `id`, `tag`, `latest`. + +- `release_id` - (Optional) ID of the release to retrieve. Must be specified when `retrieve_by` = `id`. + +- `release_tag` - (Optional) Tag of the release to retrieve. Must be specified when `retrieve_by` = `tag`. + +## Attributes Reference + +- `release_tag` - Tag of release +- `release_id` - ID of release +- `target_commitish` - Commitish value that determines where the Git release is created from +- `name` - Name of release +- `body` - Contents of the description (body) of a release +- `draft` - (`Boolean`) indicates whether the release is a draft +- `prerelease` - (`Boolean`) indicates whether the release is a prerelease +- `created_at` - Date of release creation +- `published_at` - Date of release publishing +- `url` - Base URL of the release +- `html_url` - URL directing to detailed information on the release +- `assets_url` - URL of any associated assets with the release +- `asserts_url` - **Deprecated**: Use `assets_url` resource instead +- `upload_url` - URL that can be used to upload Assets to the release +- `zipball_url` - Download URL of a specific release in `zip` format +- `tarball_url` - Download URL of a specific release in `tar.gz` format +- `assets` - Collection of assets for the release. Each asset conforms to the following schema: + - `id` - ID of the asset + - `url` - URL of the asset + - `node_id` - Node ID of the asset + - `name` - The file name of the asset + - `label` - Label for the asset + - `content_type` - MIME type of the asset + - `size` - Size in byte + - `created_at` - Date the asset was created + - `updated_at` - Date the asset was last updated + - `browser_download_url` - Browser download URL diff --git a/docs/data-sources/repositories.md b/docs/data-sources/repositories.md new file mode 100644 index 0000000000..a14dd01419 --- /dev/null +++ b/docs/data-sources/repositories.md @@ -0,0 +1,35 @@ +--- +page_title: "github_repositories Data Source - terraform-provider-github +description: |- + Search for GitHub repositories +--- + +# github_repositories (Data Source) + +-> **Note:** The data source will return a maximum of `1000` repositories [as documented in official API docs](https://developer.github.com/v3/search/#about-the-search-api). + +Use this data source to retrieve a list of GitHub repositories using a search query. + +## Example Usage + +```terraform +data "github_repositories" "example" { + query = "org:hashicorp language:Go" + include_repo_id = true +} +``` + +## Argument Reference + +The following arguments are supported: + +- `query` - (Required) Search query. See [documentation for the search syntax](https://help.github.com/articles/understanding-the-search-syntax/). +- `sort` - (Optional) Sorts the repositories returned by the specified attribute. Valid values include `stars`, `fork`, and `updated`. Defaults to `updated`. +- `include_repo_id` - (Optional) Returns a list of found repository IDs +- `results_per_page` - (Optional) Set the number of repositories requested per API call. Can be useful to decrease if requests are timing out or to increase to reduce the number of API calls. Defaults to 100. + +## Attributes Reference + +- `full_names` - A list of full names of found repositories (e.g. `hashicorp/terraform`) +- `names` - A list of found repository names (e.g. `terraform`) +- `repo_ids` - (Optional) A list of found repository IDs (e.g. `449898861`) diff --git a/docs/data-sources/repository.md b/docs/data-sources/repository.md new file mode 100644 index 0000000000..14a2524193 --- /dev/null +++ b/docs/data-sources/repository.md @@ -0,0 +1,127 @@ +--- +page_title: "github_repository Data Source - terraform-provider-github +description: |- + Get details about GitHub repository +--- + +# github_repository (Data Source) + +Use this data source to retrieve information about a GitHub repository. + +## Example Usage + +```terraform +data "github_repository" "example" { + full_name = "hashicorp/terraform" +} +``` + +## Argument Reference + +The following arguments are supported: + +- `name` - (Optional) The name of the repository. + +- `full_name` - (Optional) Full name of the repository (in `org/name` format). + +## Attributes Reference + +- `node_id` - the Node ID of the repository. + +- `description` - A description of the repository. + +- `homepage_url` - URL of a page describing the project. + +- `private` - Whether the repository is private. + +- `visibility` - Whether the repository is public, private or internal. + +- `has_issues` - Whether the repository has GitHub Issues enabled. + +- `has_discussions` - Whether the repository has GitHub Discussions enabled. + +- `has_projects` - Whether the repository has the GitHub Projects enabled. + +- `has_wiki` - Whether the repository has the GitHub Wiki enabled. + +- `is_template` - Whether the repository is a template repository. + +- `fork` - Whether the repository is a fork. + +- `allow_merge_commit` - Whether the repository allows merge commits. + +- `allow_squash_merge` - Whether the repository allows squash merges. + +- `allow_rebase_merge` - Whether the repository allows rebase merges. + +- `allow_auto_merge` - Whether the repository allows auto-merging pull requests. + +- `squash_merge_commit_title` - The default value for a squash merge commit title. + +- `squash_merge_commit_message` - The default value for a squash merge commit message. + +- `merge_commit_title` - The default value for a merge commit title. + +- `merge_commit_message` - The default value for a merge commit message. + +- `has_downloads` - Whether the repository has Downloads feature enabled. + +- `default_branch` - The name of the default branch of the repository. + +- `primary_language` - The primary language used in the repository. + +- `archived` - Whether the repository is archived. + +- `pages` - The repository's GitHub Pages configuration. + +- `topics` - The list of topics of the repository. + +- `template` - The repository source template configuration. + +- `html_url` - URL to the repository on the web. + +- `ssh_clone_url` - URL that can be provided to `git clone` to clone the repository via SSH. + +- `http_clone_url` - URL that can be provided to `git clone` to clone the repository via HTTPS. + +- `git_clone_url` - URL that can be provided to `git clone` to clone the repository anonymously via the git protocol. + +- `svn_url` - URL that can be provided to `svn checkout` to check out the repository via GitHub's Subversion protocol emulation. + +- `node_id` - GraphQL global node id for use with v4 API + +- `repo_id` - GitHub ID for the repository + +- `repository_license` - An Array of GitHub repository licenses. Each `repository_license` block consists of the fields documented below. + +--- + +The `repository_license` block consists of: + +- `content` - Content of the license file, encoded by encoding scheme mentioned below. +- `download_url` - The URL to download the raw content of the license file. +- `encoding` - The encoding used for the content (e.g., "base64"). +- `git_url` - The URL to access information about the license file as a Git blob. +- `html_url` - The URL to view the license file on GitHub. +- `license` - `license` block consists of the fields documented below. +- `name` - The name of the license file (e.g., "LICENSE"). +- `path` - The path to the license file within the repository. +- `sha` - The SHA hash of the license file. +- `size` - The size of the license file in bytes. +- `type` - The type of the content, (e.g., "file"). +- `url` - The URL to access information about the license file on GitHub. + +The `license` block consists of: + +- `body` - The text of the license. +- `conditions` - Conditions associated with the license. +- `description` - A description of the license. +- `featured` - Indicates if the license is featured. +- `html_url` - The URL to view the license details on GitHub. +- `implementation` - Details about the implementation of the license. +- `key` - A key representing the license type (e.g., "apache-2.0"). +- `limitations` - Limitations associated with the license. +- `name` - The name of the license (e.g., "Apache License 2.0"). +- `permissions` - Permissions associated with the license. +- `spdx_id` - The SPDX identifier for the license (e.g., "Apache-2.0"). +- `url` - The URL to access information about the license on GitHub. diff --git a/docs/data-sources/repository_autolink_references.md b/docs/data-sources/repository_autolink_references.md new file mode 100644 index 0000000000..bbef59512b --- /dev/null +++ b/docs/data-sources/repository_autolink_references.md @@ -0,0 +1,28 @@ +--- +page_title: "github_repository_autolink_references Data Source - terraform-provider-github +description: |- + Get autolink references for a Github repository. +--- + +# github_repository_autolink_references (Data Source) + +Use this data source to retrieve autolink references for a repository. + +## Example Usage + +```terraform +data "github_repository_autolink_references" "example" { + repository = "example-repository" +} +``` + +## Argument Reference + +- `repository` - (Required) Name of the repository to retrieve the autolink references from. + +## Attributes Reference + +- `autolink_references` - The list of this repository's autolink references. Each element of `autolink_references` has the following attributes: + - `key_prefix` - Key prefix. + - `target_url_template` - Target url template. + - `is_alphanumeric` - True if alphanumeric. diff --git a/docs/data-sources/repository_branches.md b/docs/data-sources/repository_branches.md new file mode 100644 index 0000000000..ed3fbe6e23 --- /dev/null +++ b/docs/data-sources/repository_branches.md @@ -0,0 +1,31 @@ +--- +page_title: "github_repository_branches Data Source - terraform-provider-github +description: |- + Get information on a GitHub repository's branches. +--- + +# github_repository_branches (Data Source) + +Use this data source to retrieve information about branches in a repository. + +## Example Usage + +```terraform +data "github_repository_branches" "example" { + repository = "example-repository" +} +``` + +## Argument Reference + +- `repository` - (Required) Name of the repository to retrieve the branches from. + +- `only_protected_branches` - (Optional). If true, the `branches` attributes will be populated only with protected branches. Default: `false`. + +- `only_non_protected_branches` - (Optional). If true, the `branches` attributes will be populated only with non protected branches. Default: `false`. + +## Attributes Reference + +- `branches` - The list of this repository's branches. Each element of `branches` has the following attributes: + - `name` - Name of the branch. + - `protected` - Whether the branch is protected. diff --git a/docs/data-sources/repository_custom_properties.md b/docs/data-sources/repository_custom_properties.md new file mode 100644 index 0000000000..8bc20d5785 --- /dev/null +++ b/docs/data-sources/repository_custom_properties.md @@ -0,0 +1,27 @@ +--- +page_title: "github_repository_custom_properties Data Source - terraform-provider-github +description: |- + Get all custom properties of a repository +--- + +# github_repository_custom_properties (Data Source) + +Use this data source to retrieve all custom properties of a repository. + +## Example Usage + +```terraform +data "github_repository_custom_properties" "example" { + repository = "example-repository" +} +``` + +## Argument Reference + +- `repository` - (Required) Name of the repository to retrieve the custom properties from. + +## Attributes Reference + +- `property` - The list of this repository's custom properties. Each element of `property` has the following attributes: + - `property_name` - Name of the property + - `property_value` - Value of the property diff --git a/docs/data-sources/repository_deploy_keys.md b/docs/data-sources/repository_deploy_keys.md new file mode 100644 index 0000000000..f84adf863e --- /dev/null +++ b/docs/data-sources/repository_deploy_keys.md @@ -0,0 +1,29 @@ +--- +page_title: "github_repository_deploy_keys Data Source - terraform-provider-github +description: |- + Get all deploy keys of a repository +--- + +# github_repository_deploy_keys (Data Source) + +Use this data source to retrieve all deploy keys of a repository. + +## Example Usage + +```terraform +data "github_repository_deploy_keys" "example" { + repository = "example-repository" +} +``` + +## Argument Reference + +- `repository` - (Required) Name of the repository to retrieve the branches from. + +## Attributes Reference + +- `keys` - The list of this repository's deploy keys. Each element of `keys` has the following attributes: + - `id` - Key id + - `title` - Key title + - `key` - Key itself + - `verified` - `true` if the key was verified. diff --git a/docs/data-sources/repository_deployment_branch_policies.md b/docs/data-sources/repository_deployment_branch_policies.md new file mode 100644 index 0000000000..317714e40c --- /dev/null +++ b/docs/data-sources/repository_deployment_branch_policies.md @@ -0,0 +1,32 @@ +--- +page_title: "github_repository_deployment_branch_policies Data Source - terraform-provider-github +description: |- + Get the list of deployment branch policies for a given repo / env. +--- + +# github_repository_deployment_branch_policies (Data Source) + +~> **Note:** This data source is deprecated, please use the `github_repository_environment_deployment_policies` data source instead. + +Use this data source to retrieve deployment branch policies for a repository / environment. + +## Example Usage + +```terraform +data "github_repository_deployment_branch_policies" "example" { + repository = "example-repository" + environment_name = "env_name" +} +``` + +## Argument Reference + +- `repository` - (Required) Name of the repository to retrieve the deployment branch policies from. + +- `environment_name` - (Required) Name of the environment to retrieve the deployment branch policies from. + +## Attributes Reference + +- `deployment_branch_policies` - The list of this repository / environment deployment policies. Each element of `deployment_branch_policies` has the following attributes: + - `id` - Id of the policy. + - `name` - The name pattern that branches must match in order to deploy to the environment. diff --git a/docs/data-sources/repository_environment_deployment_policies.md b/docs/data-sources/repository_environment_deployment_policies.md new file mode 100644 index 0000000000..45f2a28dcb --- /dev/null +++ b/docs/data-sources/repository_environment_deployment_policies.md @@ -0,0 +1,30 @@ +--- +page_title: "github_repository_environment_deployment_policies Data Source - terraform-provider-github +description: |- + Get the list of environment deployment policies for a given repository environment. +--- + +# github_repository_environment_deployment_policies (Data Source) + +Use this data source to retrieve deployment branch policies for a repository environment. + +## Example Usage + +```terraform +data "github_repository_environment_deployment_policies" "example" { + repository = "example-repository" + environment = "env-name" +} +``` + +## Argument Reference + +- `repository` - (Required) Name of the repository to retrieve the deployment branch policies from. + +- `environment` - (Required) Name of the environment to retrieve the deployment branch policies from. + +## Attributes Reference + +- `policies` - The list of deployment policies for the repository environment. Each element of `policies` has the following attributes: + - `type` - Type of the policy; this could be `branch` or `tag`. + - `pattern` - The pattern that branch or tag names must match in order to deploy to the environment. diff --git a/docs/data-sources/repository_environments.md b/docs/data-sources/repository_environments.md new file mode 100644 index 0000000000..7d70ace066 --- /dev/null +++ b/docs/data-sources/repository_environments.md @@ -0,0 +1,27 @@ +--- +page_title: "github_repository_environments Data Source - terraform-provider-github +description: |- + Get information on a GitHub repository's environments. +--- + +# github_repository_environments (Data Source) + +Use this data source to retrieve information about environments for a repository. + +## Example Usage + +```terraform +data "github_repository_environments" "example" { + repository = "example-repository" +} +``` + +## Argument Reference + +- `repository` - (Required) Name of the repository to retrieve the environments from. + +## Attributes Reference + +- `environments` - The list of this repository's environments. Each element of `environments` has the following attributes: + - `name` - Environment name. + - `node_id` - Environment node id. diff --git a/docs/data-sources/repository_file.md b/docs/data-sources/repository_file.md new file mode 100644 index 0000000000..f203bcdcfd --- /dev/null +++ b/docs/data-sources/repository_file.md @@ -0,0 +1,47 @@ +--- +page_title: "github_repository_file Data Source - terraform-provider-github +description: |- + Reads files within a GitHub repository +--- + +# github_repository_file (Data Source) + +This data source allows you to read files within a GitHub repository. + +## Example Usage + +```terraform +data "github_repository_file" "foo" { + repository = github_repository.foo.name + branch = "main" + file = ".gitignore" +} +``` + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The repository to read the file from. If an unqualified repo name (without an owner) is passed, the owner will be inferred from the owner of the token used to execute the plan. If a name of the type "owner/repo" (with a slash in the middle) is passed, the owner will be as specified and not the owner of the token. + +- `file` - (Required) The path of the file to read. + +- `branch` - (Optional) Git branch. Defaults to the repository's default branch. + +## Attributes Reference + +The following additional attributes are exported: + +- `content` - The file content. + +- `commit_sha` - The SHA of the commit that modified the file. + +- `sha` - The SHA blob of the file. + +- `commit_author` - Committer author name. + +- `commit_email` - Committer email address. + +- `commit_message` - Commit message when file was last updated. + +- `ref` - The name of the commit/branch/tag. diff --git a/docs/data-sources/repository_milestone.md b/docs/data-sources/repository_milestone.md new file mode 100644 index 0000000000..21e67fbd2d --- /dev/null +++ b/docs/data-sources/repository_milestone.md @@ -0,0 +1,34 @@ +--- +page_title: "github_repository_milestone Data Source - terraform-provider-github +description: |- + Get information on a GitHub Repository Milestone. +--- + +# github_repository_milestone (Data Source) + +Use this data source to retrieve information about a specific GitHub milestone in a repository. + +## Example Usage + +```terraform +data "github_repository_milestone" "example" { + owner = "example-owner" + repository = "example-repository" + number = 1 +} +``` + +## Argument Reference + +- `owner` - (Required) Owner of the repository. + +- `repository` - (Required) Name of the repository to retrieve the milestone from. + +- `number` - (Required) The number of the milestone. + +## Attributes Reference + +- `description` - Description of the milestone. +- `due_date` - The milestone due date (in ISO-8601 `yyyy-mm-dd` format). +- `state` - State of the milestone. +- `title` - Title of the milestone. diff --git a/docs/data-sources/repository_pull_request.md b/docs/data-sources/repository_pull_request.md new file mode 100644 index 0000000000..4b7d78f1d1 --- /dev/null +++ b/docs/data-sources/repository_pull_request.md @@ -0,0 +1,56 @@ +--- +page_title: "github_repository_pull_request Data Source - terraform-provider-github +description: |- + Get information on a single GitHub Pull Request. +--- + +# github_repository_pull_request (Data Source) + +Use this data source to retrieve information about a specific GitHub Pull Request in a repository. + +## Example Usage + +```terraform +data "github_repository_pull_request" "example" { + base_repository = "example_repository" + number = 1 +} +``` + +## Argument Reference + +- `base_repository` - (Required) Name of the base repository to retrieve the Pull Request from. + +- `number` - (Required) The number of the Pull Request within the repository. + +- `owner` - (Optional) Owner of the repository. If not provided, the provider's default owner is used. + +## Attributes Reference + +- `base_ref` - Name of the ref (branch) of the Pull Request base. + +- `base_sha` - Head commit SHA of the Pull Request base. + +- `body` - Body of the Pull Request. + +- `draft` - Indicates Whether this Pull Request is a draft. + +- `head_owner` - Owner of the Pull Request head repository. + +- `head_repository` - Name of the Pull Request head repository. + +- `head_sha` - Head commit SHA of the Pull Request head. + +- `labels` - List of label names set on the Pull Request. + +- `maintainer_can_modify` - Indicates whether the base repository maintainers can modify the Pull Request. + +- `opened_at` - Unix timestamp indicating the Pull Request creation time. + +- `opened_by` - GitHub login of the user who opened the Pull Request. + +- `state` - the current Pull Request state - can be "open", "closed" or "merged". + +- `title` - The title of the Pull Request. + +- `updated_at` - The timestamp of the last Pull Request update. diff --git a/docs/data-sources/repository_pull_requests.md b/docs/data-sources/repository_pull_requests.md new file mode 100644 index 0000000000..99962638f5 --- /dev/null +++ b/docs/data-sources/repository_pull_requests.md @@ -0,0 +1,73 @@ +--- +page_title: "github_repository_pull_requests Data Source - terraform-provider-github +description: |- + Get information on multiple GitHub Pull Requests. +--- + +# github_repository_pull_requests (Data Source) + +Use this data source to retrieve information about multiple GitHub Pull Requests in a repository. + +## Example Usage + +```terraform +data "github_repository_pull_requests" "example" { + base_repository = "example-repository" + base_ref = "main" + sort_by = "updated" + sort_direction = "desc" + state = "open" +} +``` + +## Argument Reference + +- `base_repository` - (Required) Name of the base repository to retrieve the Pull Requests from. + +- `owner` - (Optional) Owner of the repository. If not provided, the provider's default owner is used. + +- `base_ref` - (Optional) If set, filters Pull Requests by base branch name. + +- `head_ref` - (Optional) If set, filters Pull Requests by head user or head organization and branch name in the format of "user:ref-name" or "organization:ref-name". For example: "github:new-script-format" or "octocat:test-branch". + +- `sort_by` - (Optional) If set, indicates what to sort results by. Can be either "created", "updated", "popularity" (comment count) or "long-running" (age, filtering by pulls updated in the last month). Default: "created". + +- `sort_direction` - (Optional) If set, controls the direction of the sort. Can be either "asc" or "desc". Default: "asc". + +- `state` - (Optional) If set, filters Pull Requests by state. Can be "open", "closed", or "all". Default: "open". + +## Attributes Reference + +- `results` - Collection of Pull Requests matching the filters. Each of the results conforms to the following scheme: + + - `base_ref` - Name of the ref (branch) of the Pull Request base. + + - `base_sha` - Head commit SHA of the Pull Request base. + + - `body` - Body of the Pull Request. + + - `draft` - Indicates Whether this Pull Request is a draft. + + - `head_owner` - Owner of the Pull Request head repository. + + - `head_ref` - Value of the Pull Request `HEAD` reference. + + - `head_repository` - Name of the Pull Request head repository. + + - `head_sha` - Head commit SHA of the Pull Request head. + + - `labels` - List of label names set on the Pull Request. + + - `maintainer_can_modify` - Indicates whether the base repository maintainers can modify the Pull Request. + + - `number` - The number of the Pull Request within the repository. + + - `opened_at` - Unix timestamp indicating the Pull Request creation time. + + - `opened_by` - GitHub login of the user who opened the Pull Request. + + - `state` - the current Pull Request state - can be "open", "closed" or "merged". + + - `title` - The title of the Pull Request. + + - `updated_at` - The timestamp of the last Pull Request update. diff --git a/docs/data-sources/repository_teams.md b/docs/data-sources/repository_teams.md new file mode 100644 index 0000000000..39ff8be633 --- /dev/null +++ b/docs/data-sources/repository_teams.md @@ -0,0 +1,29 @@ +--- +page_title: "github_repository_teams Data Source - terraform-provider-github +description: |- + Get teams which have permission on the given repo. +--- + +# github_repository_teams (Data Source) + +Use this data source to retrieve the list of teams which have access to a GitHub repository. + +## Example Usage + +```terraform +data "github_repository_teams" "example" { + name = "example" +} +``` + +## Argument Reference + +- `name` - (Optional) The name of the repository. +- `full_name` - (Optional) Full name of the repository (in `org/name` format). + +## Attributes Reference + +- `teams` - List of teams which have access to the repository + - `name` - Team name + - `slug` - Team slug + - `permission` - Team permission diff --git a/docs/data-sources/repository_webhooks.md b/docs/data-sources/repository_webhooks.md new file mode 100644 index 0000000000..e95379f792 --- /dev/null +++ b/docs/data-sources/repository_webhooks.md @@ -0,0 +1,33 @@ +--- +page_title: "github_repository_webhooks Data Source - terraform-provider-github +description: |- + Get information on all GitHub webhooks of the organization. +--- + +# github_repository_webhooks (Data Source) + +Use this data source to retrieve webhooks for a given repository. + +## Example Usage + +To retrieve webhooks of a repository: + +```terraform +data "github_repository_webhooks" "repo" { + repository = "foo" +} +``` + +## Attributes Reference + +- `webhooks` - An Array of GitHub Webhooks. Each `webhook` block consists of the fields documented below. + +--- + +The `webhook` block consists of: + +- `id` - the ID of the webhook. +- `type` - the type of the webhook. +- `name` - the name of the webhook. +- `url` - the url of the webhook. +- `active` - `true` if the webhook is active. diff --git a/docs/data-sources/rest_api.md b/docs/data-sources/rest_api.md new file mode 100644 index 0000000000..258a66362a --- /dev/null +++ b/docs/data-sources/rest_api.md @@ -0,0 +1,29 @@ +--- +page_title: "github_rest_api Data Source - terraform-provider-github +description: |- + Get information on a GitHub resource with a custom GET request to GitHub REST API. +--- + +# github_rest_api (Data Source) + +Use this data source to retrieve information about a GitHub resource through REST API. + +## Example Usage + +```terraform +data "github_rest_api" "example" { + endpoint = "repos/example_repo/git/refs/heads/main" +} +``` + +## Argument Reference + +- `endpoint` - (Required) REST API endpoint to send the GET request to. + +## Attributes Reference + +- `id` - The GitHub API Request ID +- `code` - A response status code. +- `status` - A response status string. +- `headers` - A JSON string containing response headers. +- `body` - A JSON string containing response body. diff --git a/docs/data-sources/ssh_keys.md b/docs/data-sources/ssh_keys.md new file mode 100644 index 0000000000..806867e8f5 --- /dev/null +++ b/docs/data-sources/ssh_keys.md @@ -0,0 +1,19 @@ +--- +page_title: "github_ssh_keys Data Source - terraform-provider-github +description: |- + Get information on GitHub's SSH keys. +--- + +# github_ssh_keys (Data Source) + +Use this data source to retrieve information about GitHub's SSH keys. + +## Example Usage + +```terraform +data "github_ssh_keys" "test" {} +``` + +## Attributes Reference + +- `keys` - An array of GitHub's SSH public keys. diff --git a/docs/data-sources/team.md b/docs/data-sources/team.md new file mode 100644 index 0000000000..5da27e95c4 --- /dev/null +++ b/docs/data-sources/team.md @@ -0,0 +1,36 @@ +--- +page_title: "github_team Data Source - terraform-provider-github +description: |- + Get information on a GitHub team. +--- + +# github_team (Data Source) + +Use this data source to retrieve information about a GitHub team. + +## Example Usage + +```terraform +data "github_team" "example" { + slug = "example" +} +``` + +## Argument Reference + +- `slug` - (Required) The team slug. +- `membership_type` - (Optional) Type of membership to be requested to fill the list of members. Can be either "all" or "immediate". Default: "all" +- `summary_only` - (Optional) Exclude the members and repositories of the team from the returned result. Defaults to `false`. +- `results_per_page` - (Optional) Set the number of results per graphql query. Reducing this number can alleviate timeout errors. Accepts a value between 0 - 100. Defaults to `100`. + +## Attributes Reference + +- `id` - the ID of the team. +- `node_id` - the Node ID of the team. +- `name` - the team's full name. +- `description` - the team's description. +- `privacy` - the team's privacy type. +- `permission` - the team's permission level. +- `members` - List of team members (list of GitHub usernames). Not returned if `summary_only = true` +- `repositories` - (**DEPRECATED**) List of team repositories (list of repo names). Not returned if `summary_only = true` +- `repositories_detailed` - List of team repositories (each item comprises of `repo_id`, `repo_name` & [`role_name`](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/team_repository#permission)). Not returned if `summary_only = true` diff --git a/docs/data-sources/tree.md b/docs/data-sources/tree.md new file mode 100644 index 0000000000..497821eb97 --- /dev/null +++ b/docs/data-sources/tree.md @@ -0,0 +1,42 @@ +--- +page_title: "github_tree Data Source - terraform-provider-github +description: |- + Returns a single tree using the SHA1 value for that tree. +--- + +# github_tree (Data Source) + +Use this data source to retrieve information about a single tree. + +## Example Usage + +```terraform +data "github_repository" "this" { + name = "example" +} + +data "github_branch" "this" { + branch = data.github_repository.this.default_branch + repository = data.github_repository.this.name +} + +data "github_tree" "this" { + recursive = false + repository = data.github_repository.this.name + tree_sha = data.github_branch.this.sha +} + +output "entries" { + value = data.github_tree.this.entries +} +``` + +## Argument Reference + +- `recursive` - (Optional) Setting this parameter to `true` returns the objects or subtrees referenced by the tree specified in `tree_sha`. +- `repository` - (Required) The name of the repository. +- `tree_sha` - (Required) The SHA1 value for the tree. + +## Attributes Reference + +- `entries` - Objects (of `path`, `mode`, `type`, `size`, and `sha`) specifying a tree structure. diff --git a/docs/data-sources/user.md b/docs/data-sources/user.md new file mode 100644 index 0000000000..492f20b5d9 --- /dev/null +++ b/docs/data-sources/user.md @@ -0,0 +1,55 @@ +--- +page_title: "github_user Data Source - terraform-provider-github +description: |- + Get information on a GitHub user. +--- + +# github_user (Data Source) + +Use this data source to retrieve information about a GitHub user. + +## Example Usage + +```terraform +# Retrieve information about a GitHub user. +data "github_user" "example" { + username = "example" +} + +# Retrieve information about the currently authenticated user. +data "github_user" "current" { + username = "" +} + +output "current_github_login" { + value = "${data.github_user.current.login}" +} +``` + +## Argument Reference + +- `username` - (Required) The username. Use an empty string `""` to retrieve information about the currently authenticated user. + +## Attributes Reference + +- `id` - the ID of the user. +- `node_id` - the Node ID of the user. +- `login` - the user's login. +- `avatar_url` - the user's avatar URL. +- `gravatar_id` - the user's gravatar ID. +- `site_admin` - whether the user is a GitHub admin. +- `name` - the user's full name. +- `company` - the user's company name. +- `blog` - the user's blog location. +- `location` - the user's location. +- `email` - the user's email. +- `gpg_keys` - list of user's GPG keys. +- `ssh_keys` - list of user's SSH keys. +- `bio` - the user's bio. +- `public_repos` - the number of public repositories. +- `public_gists` - the number of public gists. +- `followers` - the number of followers. +- `following` - the number of following users. +- `created_at` - the creation date. +- `updated_at` - the update date. +- `suspended_at` - the suspended date if the user is suspended. diff --git a/docs/data-sources/user_external_identity.md b/docs/data-sources/user_external_identity.md new file mode 100644 index 0000000000..13f919d8a5 --- /dev/null +++ b/docs/data-sources/user_external_identity.md @@ -0,0 +1,46 @@ +--- +page_title: "github_user_external_identity Data Source - terraform-provider-github +description: |- + Get a specific organization member's SAML/SCIM linked external identity +--- + +# github_user_external_identity (Data Source) + +Use this data source to retrieve a specific organization member's SAML or SCIM user attributes. + +## Example Usage + +```terraform +data "github_user_external_identity" "example_user" { + username = "example-user" +} +``` + +## Argument Reference + +The following arguments are supported: + +- `username` - (Required) The username of the member to fetch external identity for. + +## Attributes Reference + +- `login` - The username of the GitHub user +- `saml_identity` - An Object containing the user's SAML data. This object will be empty if the user is not managed by SAML. +- `scim_identity` - An Object contining the user's SCIM data. This object will be empty if the user is not managed by SCIM. + +--- + +If a user is managed by SAML, the `saml_identity` object will contain: + +- `name_id` - The member's SAML NameID +- `username` - The member's SAML Username +- `family_name` - The member's SAML Family Name +- `given_name` - The member's SAML Given Name + +--- + +If a user is managed by SCIM, the `scim_identity` object will contain: + +- `scim_username` - The member's SCIM Username. (will be empty string if user is not managed by SCIM) +- `scim_family_name` - The member's SCIM Family Name +- `scim_given_name` - The member's SCIM Given Name diff --git a/docs/data-sources/users.md b/docs/data-sources/users.md new file mode 100644 index 0000000000..d2a5fb6fe4 --- /dev/null +++ b/docs/data-sources/users.md @@ -0,0 +1,37 @@ +--- +page_title: "github_users Data Source - terraform-provider-github +description: |- + Get information about multiple GitHub users. +--- + +# github_users (Data Source) + +Use this data source to retrieve information about multiple GitHub users at once. + +## Example Usage + +```terraform +# Retrieve information about multiple GitHub users. +data "github_users" "example" { + usernames = ["example1", "example2", "example3"] +} + +output "valid_users" { + value = "${data.github_users.example.logins}" +} + +output "invalid_users" { + value = "${data.github_users.example.unknown_logins}" +} +``` + +## Argument Reference + +- `usernames` - (Required) List of usernames. + +## Attributes Reference + +- `node_ids` - list of Node IDs of users that could be found. +- `logins` - list of logins of users that could be found. +- `emails` - list of the user's publicly visible profile email (will be empty string in case if user decided not to show it). +- `unknown_logins` - list of logins without matching user. diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000000..e8d1b00deb --- /dev/null +++ b/docs/index.md @@ -0,0 +1,136 @@ +--- +page_title: "Provider: GitHub" +description: |- + The GitHub provider is used to interact with GitHub resources. +--- + +# GitHub Provider + +The GitHub provider is used to interact with GitHub resources. + +The provider allows you to manage your GitHub organization's members and teams easily. It needs to be configured with the proper credentials before it can be used. + +Use the navigation to the left to read about the available resources. + +## Example Usage + +Terraform 0.13 and later: + +```terraform +terraform { + required_providers { + github = { + source = "integrations/github" + version = "~> 6.0" + } + } +} + +# Configure the GitHub Provider +provider "github" {} + +# Add a user to the organization +resource "github_membership" "membership_for_user_x" { + # ... +} +``` + +- You **must** add a `required_providers` block to every module that will create resources with this provider. If you do not explicitly require `integrations/github` in a submodule, your terraform run may [break in hard-to-troubleshoot ways](https://github.com/integrations/terraform-provider-github/issues/876#issuecomment-1303790559). + +Terraform 0.12 and earlier: + +```terraform +# Configure the GitHub Provider +provider "github" { + version = "~> 5.0" +} + +# Add a user to the organization +resource "github_membership" "membership_for_user_x" { + # ... +} +``` + +~> **Note:** When upgrading from `hashicorp/github` to `integrations/github`, use `terraform state replace-provider`. Otherwise, Terraform will still require the old provider to interact with the state file. + +## Authentication + +The GitHub provider offers multiple ways to authenticate with GitHub API. + +### GitHub CLI + +The GitHub provider taps into [GitHub CLI](https://cli.github.com/) authentication, where it picks up the token issued by [`gh auth login`](https://cli.github.com/manual/gh_auth_login) command. It is possible to specify the path to the `gh` executable in the `GH_PATH` environment variable, which is useful for when the GitHub Terraform provider can not properly determine its the path to GitHub CLI such as in the cygwin terminal. + +### OAuth / Personal Access Token + +To authenticate using OAuth tokens, ensure that the `token` argument or the `GITHUB_TOKEN` environment variable is set. + +```terraform +provider "github" { + token = var.token # or `GITHUB_TOKEN` +} +``` + +### GitHub App Installation + +To authenticate using a GitHub App installation, ensure that arguments in the `app_auth` block or the `GITHUB_APP_XXX` environment variables are set. The `owner` parameter required in this situation. Leaving out will throw a `403 "Resource not accessible by integration"` error. + +Some API operations may not be available when using a GitHub App installation configuration. For more information, refer to the list of [supported endpoints](https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps). + +```terraform +provider "github" { + owner = var.github_organization + app_auth { + id = var.app_id # or `GITHUB_APP_ID` + installation_id = var.app_installation_id # or `GITHUB_APP_INSTALLATION_ID` + pem_file = var.app_pem_file # or `GITHUB_APP_PEM_FILE` + } +} +``` + +~> **Note:** When using environment variables, an empty `app_auth` block is required to allow provider configurations from environment variables to be specified. See: [Terraform SDK Issue](https://github.com/hashicorp/terraform-plugin-sdk/issues/142) + +```terraform +provider "github" { + owner = var.github_organization + app_auth {} # When using `GITHUB_APP_XXX` environment variables +} +``` + +## Argument Reference + +The following arguments are supported in the `provider` block: + +- `token` - (Optional) A GitHub OAuth / Personal Access Token. When not provided or made available via the `GITHUB_TOKEN` environment variable, the provider can only access resources available anonymously. + +- `base_url` - (Optional) This is the target GitHub base API endpoint. Providing a value is a requirement when working with GitHub Enterprise. It is optional to provide this value and it can also be sourced from the `GITHUB_BASE_URL` environment variable. The value must end with a slash, for example: `https://terraformtesting-ghe.westus.cloudapp.azure.com/` + +- `owner` - (Optional) This is the target GitHub organization or individual user account to manage. For example, `torvalds` and `github` are valid owners. It is optional to provide this value and it can also be sourced from the `GITHUB_OWNER` environment variable. When not provided and a `token` is available, the individual user account owning the `token` will be used. When not provided and no `token` is available, the provider may not function correctly. It is required in case of GitHub App Installation. + +- `organization` - (Deprecated) This behaves the same as `owner`, which should be used instead. This value can also be sourced from the `GITHUB_ORGANIZATION` environment variable. + +- `app_auth` - (Optional) Configuration block to use GitHub App installation token. When not provided, the provider can only access resources available anonymously. + - `id` - (Required) This is the ID of the GitHub App. It can sourced from the `GITHUB_APP_ID` environment variable. + - `installation_id` - (Required) This is the ID of the GitHub App installation. It can sourced from the `GITHUB_APP_INSTALLATION_ID` environment variable. + - `pem_file` - (Required) This is the contents of the GitHub App private key PEM file. It can also be sourced from the `GITHUB_APP_PEM_FILE` environment variable and may use `\n` instead of actual new lines. + +- `write_delay_ms` - (Optional) The number of milliseconds to sleep in between write operations in order to satisfy the GitHub API rate limits. Note that requests to the GraphQL API are implemented as `POST` requests under the hood, so this setting affects those calls as well. Defaults to 1000ms or 1 second if not provided. + +- `retry_delay_ms` - (Optional) Amount of time in milliseconds to sleep in between requests to GitHub API after an error response. Defaults to 1000ms or 1 second if not provided, the max_retries must be set to greater than zero. + +- `read_delay_ms` - (Optional) The number of milliseconds to sleep in between non-write operations in order to satisfy the GitHub API rate limits. Defaults to 0ms. + +- `retryable_errors` - (Optional) "Allow the provider to retry after receiving an error status code, the max_retries should be set for this to work. Defaults to [500, 502, 503, 504] + +- `max_retries` - (Optional) Number of times to retry a request after receiving an error status code. Defaults to 3 + +Note: If you have a PEM file on disk, you can pass it in via `pem_file = file("path/to/file.pem")`. + +For backwards compatibility, if more than one of `owner`, `organization`, `GITHUB_OWNER` and `GITHUB_ORGANIZATION` are set, the first in this list takes priority. + +1. Setting `organization` in the GitHub provider configuration. +2. Setting the `GITHUB_ORGANIZATION` environment variable. +3. Setting the `GITHUB_OWNER` environment variable. +4. Setting `owner` in the GitHub provider configuration. + +~> It is a bug that `GITHUB_OWNER` takes precedence over `owner`, which may be fixed in a future major release. For compatibility with future releases, please set only one of `GITHUB_OWNER` and `owner`. diff --git a/docs/resources/actions_environment_secret.md b/docs/resources/actions_environment_secret.md new file mode 100644 index 0000000000..cf0f183570 --- /dev/null +++ b/docs/resources/actions_environment_secret.md @@ -0,0 +1,92 @@ +--- +page_title: "github_actions_environment_secret Resource - terraform-provider-github +description: |- + Creates and manages an Action Secret within a GitHub repository environment +--- + +# github_actions_environment_secret (Resource) + +This resource allows you to create and manage GitHub Actions secrets within your GitHub repository environments. You must have write access to a repository to use this resource. + +Secret values are encrypted using the [Go '/crypto/box' module](https://godoc.org/golang.org/x/crypto/nacl/box) which is interoperable with [libsodium](https://libsodium.gitbook.io/doc/). Libsodium is used by GitHub to decrypt secret values. + +For the purposes of security, the contents of the `plaintext_value` field have been marked as `sensitive` to Terraform, but it is important to note that **this does not hide it from state files**. You should treat state as sensitive always. It is also advised that you do not store plaintext values in your code but rather populate the `encrypted_value` using fields from a resource, data source or variable as, while encrypted in state, these will be easily accessible in your code. See below for an example of this abstraction. + +## Example Usage + +```terraform +resource "github_actions_environment_secret" "example_secret" { + environment = "example_environment" + secret_name = "example_secret_name" + plaintext_value = var.some_secret_string +} + +resource "github_actions_environment_secret" "example_secret" { + environment = "example_environment" + secret_name = "example_secret_name" + encrypted_value = var.some_encrypted_secret_string +} +``` + +```terraform +data "github_repository" "repo" { + full_name = "my-org/repo" +} + +resource "github_repository_environment" "repo_environment" { + repository = data.github_repository.repo.name + environment = "example_environment" +} + +resource "github_actions_environment_secret" "test_secret" { + repository = data.github_repository.repo.name + environment = github_repository_environment.repo_environment.environment + secret_name = "test_secret_name" + plaintext_value = "%s" +} +``` + +## Example Lifecycle Ignore Changes + +This resource supports the `lifecycle` `ignore_changes` block. This is for use cases where a secret value is created using a placeholder value and then modified after creation outside the scope of Terraform. This approach ensures only the initial placeholder value is referenced in your code and in the resulting state file. + +```terraform +resource "github_actions_environment_secret" "example_secret" { + environment = "example_environment" + secret_name = "example_secret_name" + plaintext_value = "placeholder" + + lifecycle { + ignore_changes = [plaintext_value] + } +} + +resource "github_actions_environment_secret" "example_secret" { + environment = "example_environment" + secret_name = "example_secret_name" + encrypted_value = base64sha256("placeholder") + + lifecycle { + ignore_changes = [encrypted_value] + } +} +``` + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) Name of the repository. +- `environment` - (Required) Name of the environment. +- `secret_name` - (Required) Name of the secret. +- `encrypted_value` - (Optional) Encrypted value of the secret using the GitHub public key in Base64 format. +- `plaintext_value` - (Optional) Plaintext value of the secret to be encrypted. + +## Attributes Reference + +- `created_at` - Date of actions_environment_secret creation. +- `updated_at` - Date of actions_environment_secret update. + +## Import + +This resource does not support importing. If you'd like to help contribute it, please visit our [GitHub page](https://github.com/integrations/terraform-provider-github)! diff --git a/docs/resources/actions_environment_variable.md b/docs/resources/actions_environment_variable.md new file mode 100644 index 0000000000..06bf9ef6a3 --- /dev/null +++ b/docs/resources/actions_environment_variable.md @@ -0,0 +1,60 @@ +--- +page_title: "github_actions_environment_variable Resource - terraform-provider-github +description: |- + Creates and manages an Action variable within a GitHub repository environment +--- + +# github_actions_environment_variable (Resource) + +This resource allows you to create and manage GitHub Actions variables within your GitHub repository environments. You must have write access to a repository to use this resource. + +## Example Usage + +```terraform +resource "github_actions_environment_variable" "example_variable" { + environment = "example_environment" + repository = "example_repository" + value = "example_variable_value" + variable_name = "example_variable_name" +} +``` + +```terraform +data "github_repository" "repo" { + full_name = "my-org/repo" +} + +resource "github_repository_environment" "repo_environment" { + repository = data.github_repository.repo.name + environment = "example_environment" +} + +resource "github_actions_environment_variable" "example_variable" { + repository = data.github_repository.repo.name + environment = github_repository_environment.repo_environment.environment + variable_name = "example_variable_name" + value = "example_variable_value" +} +``` + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) Name of the repository. +- `environment` - (Required) Name of the environment. +- `variable_name` - (Required) Name of the variable. +- `value` - (Required) Value of the variable + +## Attributes Reference + +- `created_at` - Date of actions_environment_secret creation. +- `updated_at` - Date of actions_environment_secret update. + +## Import + +This resource can be imported using an ID made up of the repository name, environment name, and variable name: + +```sh +$ terraform import github_actions_environment_variable.test_variable myrepo:myenv:myvariable +``` diff --git a/docs/resources/actions_hosted_runner.md b/docs/resources/actions_hosted_runner.md new file mode 100644 index 0000000000..90fd59b802 --- /dev/null +++ b/docs/resources/actions_hosted_runner.md @@ -0,0 +1,153 @@ +--- +page_title: "github_actions_hosted_runner Resource - terraform-provider-github +description: |- + Creates and manages GitHub-hosted runners within a GitHub organization +--- + +# github_actions_hosted_runner (Resource) + +This resource allows you to create and manage GitHub-hosted runners within your GitHub organization. You must have admin access to an organization to use this resource. + +GitHub-hosted runners are fully managed virtual machines that run your GitHub Actions workflows. Unlike self-hosted runners, GitHub handles the infrastructure, maintenance, and scaling. + +## Example Usage + +### Basic Usage + +```terraform +resource "github_actions_runner_group" "example" { + name = "example-runner-group" + visibility = "all" +} + +resource "github_actions_hosted_runner" "example" { + name = "example-hosted-runner" + + image { + id = "2306" + source = "github" + } + + size = "4-core" + runner_group_id = github_actions_runner_group.example.id +} +``` + +### Advanced Usage with Optional Parameters + +```terraform +resource "github_actions_runner_group" "advanced" { + name = "advanced-runner-group" + visibility = "selected" +} + +resource "github_actions_hosted_runner" "advanced" { + name = "advanced-hosted-runner" + + image { + id = "2306" + source = "github" + } + + size = "8-core" + runner_group_id = github_actions_runner_group.advanced.id + maximum_runners = 10 + public_ip_enabled = true +} +``` + +## Argument Reference + +The following arguments are supported: + +- `name` - (Required) Name of the hosted runner. Must be between 1 and 64 characters and may only contain alphanumeric characters, '.', '-', and '_'. +- `image` - (Required) Image configuration for the hosted runner. Cannot be changed after creation. Block supports: + - `id` - (Required) The image ID. For GitHub-owned images, use numeric IDs like "2306" for Ubuntu Latest 24.04. To get available images, use the GitHub API: `GET /orgs/{org}/actions/hosted-runners/images/github-owned`. + - `source` - (Optional) The image source. Valid values are "github", "partner", or "custom". Defaults to "github". +- `size` - (Required) Machine size for the hosted runner (e.g., "4-core", "8-core"). Can be updated to scale the runner. To list available sizes, use the GitHub API: `GET /orgs/{org}/actions/hosted-runners/machine-sizes`. +- `runner_group_id` - (Required) The ID of the runner group to assign this runner to. +- `maximum_runners` - (Optional) Maximum number of runners to scale up to. Runners will not auto-scale above this number. Use this setting to limit costs. +- `public_ip_enabled` - (Optional) Whether to enable static public IP for the runner. Note there are account limits. To list limits, use the GitHub API: `GET /orgs/{org}/actions/hosted-runners/limits`. Defaults to false. +- `image_version` - (Optional) The version of the runner image to deploy. This is only relevant for runners using custom images. + +## Timeouts + +The `timeouts` block allows you to specify timeouts for certain actions: + +- `delete` - (Defaults to 10 minutes) Used for waiting for the hosted runner deletion to complete. + +Example: + +```terraform +resource "github_actions_hosted_runner" "example" { + name = "example-hosted-runner" + + image { + id = "2306" + source = "github" + } + + size = "4-core" + runner_group_id = github_actions_runner_group.example.id + + timeouts { + delete = "15m" + } +} +``` + +## Attributes Reference + +In addition to the arguments above, the following attributes are exported: + +- `id` - The ID of the hosted runner. +- `status` - Current status of the runner (e.g., "Ready", "Provisioning"). +- `platform` - Platform of the runner (e.g., "linux-x64", "win-x64"). +- `image` - In addition to the arguments above, the image block exports: + - `size_gb` - The size of the image in gigabytes. +- `machine_size_details` - Detailed specifications of the machine size: + - `id` - Machine size identifier. + - `cpu_cores` - Number of CPU cores. + - `memory_gb` - Amount of memory in gigabytes. + - `storage_gb` - Amount of storage in gigabytes. +- `public_ips` - List of public IP ranges assigned to this runner (only if `public_ip_enabled` is true): + - `enabled` - Whether this IP range is enabled. + - `prefix` - IP address prefix. + - `length` - Subnet length. +- `last_active_on` - Timestamp (RFC3339) when the runner was last active. + +## Import + +Hosted runners can be imported using the runner ID: + +```sh +$ terraform import github_actions_hosted_runner.example 123456 +``` + +## Notes + +- This resource is **organization-only** and cannot be used with individual accounts. +- The `image` field cannot be changed after the runner is created. Changing it will force recreation of the runner. +- The `size` field can be updated to scale the runner up or down as needed. +- Image IDs for GitHub-owned images are numeric strings (e.g., "2306" for Ubuntu Latest 24.04), not names like "ubuntu-latest". +- Deletion of hosted runners is asynchronous. The provider will poll for up to 10 minutes (configurable via timeouts) to confirm deletion. +- Runner creation and updates may take several minutes as GitHub provisions the infrastructure. +- Static public IPs are subject to account limits. Check your organization's limits before enabling. + +## Getting Available Images and Sizes + +To get a list of available images: + +```bash +curl -H "Authorization: Bearer YOUR_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + https://api.github.com/orgs/YOUR_ORG/actions/hosted-runners/images/github-owned +``` + +To get available machine sizes: + +```bash +curl -H "Authorization: Bearer YOUR_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + https://api.github.com/orgs/YOUR_ORG/actions/hosted-runners/machine-sizes +``` diff --git a/docs/resources/actions_organization_oidc_subject_claim_customization_template.md b/docs/resources/actions_organization_oidc_subject_claim_customization_template.md new file mode 100644 index 0000000000..80546d1576 --- /dev/null +++ b/docs/resources/actions_organization_oidc_subject_claim_customization_template.md @@ -0,0 +1,33 @@ +--- +page_title: "github_actions_organization_oidc_subject_claim_customization_template Resource - terraform-provider-github +description: |- + Creates and manages an OpenID Connect subject claim customization template for an organization +--- + +# github_actions_organization_oidc_subject_claim_customization_template (Resource) + +This resource allows you to create and manage an OpenID Connect subject claim customization template within a GitHub organization. + +More information on integrating GitHub with cloud providers using OpenID Connect and a list of available claims is available in the [Actions documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect). + +## Example Usage + +```terraform +resource "github_actions_organization_oidc_subject_claim_customization_template" "example_template" { + include_claim_keys = ["actor", "context", "repository_owner"] +} +``` + +## Argument Reference + +The following arguments are supported: + +- `include_claim_keys` - (Required) A list of OpenID Connect claims. + +## Import + +This resource can be imported using the organization's name. + +```sh +$ terraform import github_actions_organization_oidc_subject_claim_customization_template.test example_organization +``` diff --git a/docs/resources/actions_organization_permissions.md b/docs/resources/actions_organization_permissions.md new file mode 100644 index 0000000000..45c69f10bf --- /dev/null +++ b/docs/resources/actions_organization_permissions.md @@ -0,0 +1,61 @@ +--- +page_title: "github_actions_organization_permissions Resource - terraform-provider-github +description: |- + Creates and manages Actions permissions within a GitHub organization +--- + +# github_actions_organization_permissions (Resource) + +This resource allows you to create and manage GitHub Actions permissions within your GitHub enterprise organizations. You must have admin access to an organization to use this resource. + +## Example Usage + +```terraform +resource "github_repository" "example" { + name = "my-repository" +} + +resource "github_actions_organization_permissions" "test" { + allowed_actions = "selected" + enabled_repositories = "selected" + allowed_actions_config { + github_owned_allowed = true + patterns_allowed = ["actions/cache@*", "actions/checkout@*"] + verified_allowed = true + } + enabled_repositories_config { + repository_ids = [github_repository.example.repo_id] + } +} +``` + +## Argument Reference + +The following arguments are supported: + +- `allowed_actions` - (Optional) The permissions policy that controls the actions that are allowed to run. Can be one of: `all`, `local_only`, or `selected`. +- `enabled_repositories` - (Required) The policy that controls the repositories in the organization that are allowed to run GitHub Actions. Can be one of: `all`, `none`, or `selected`. +- `allowed_actions_config` - (Optional) Sets the actions that are allowed in an organization. Only available when `allowed_actions` = `selected`. See [Allowed Actions Config](#allowed-actions-config) below for details. +- `enabled_repositories_config` - (Optional) Sets the list of selected repositories that are enabled for GitHub Actions in an organization. Only available when `enabled_repositories` = `selected`. See [Enabled Repositories Config](#enabled-repositories-config) below for details. + +### Allowed Actions Config + +The `allowed_actions_config` block supports the following: + +- `github_owned_allowed` - (Required) Whether GitHub-owned actions are allowed in the organization. +- `patterns_allowed` - (Optional) Specifies a list of string-matching patterns to allow specific action(s). Wildcards, tags, and SHAs are allowed. For example, `monalisa/octocat@*`, `monalisa/octocat@v2`, `monalisa/*`. +- `verified_allowed` - (Optional) Whether actions in GitHub Marketplace from verified creators are allowed. Set to `true` to allow all GitHub Marketplace actions by verified creators. + +### Enabled Repositories Config + +The `enabled_repositories_config` block supports the following: + +- `repository_ids` - (Required) List of repository IDs to enable for GitHub Actions. + +## Import + +This resource can be imported using the name of the GitHub organization: + +```sh +$ terraform import github_actions_organization_permissions.test github_organization_name +``` diff --git a/docs/resources/actions_organization_secret.md b/docs/resources/actions_organization_secret.md new file mode 100644 index 0000000000..306f5f2c99 --- /dev/null +++ b/docs/resources/actions_organization_secret.md @@ -0,0 +1,75 @@ +--- +page_title: "github_actions_organization_secret Resource - terraform-provider-github +description: |- + Creates and manages an Action Secret within a GitHub organization +--- + +# github_actions_organization_secret (Resource) + +This resource allows you to create and manage GitHub Actions secrets within your GitHub organization. You must have write access to a repository to use this resource. + +Secret values are encrypted using the [Go '/crypto/box' module](https://godoc.org/golang.org/x/crypto/nacl/box) which is interoperable with [libsodium](https://libsodium.gitbook.io/doc/). Libsodium is used by GitHub to decrypt secret values. + +For the purposes of security, the contents of the `plaintext_value` field have been marked as `sensitive` to Terraform, but it is important to note that **this does not hide it from state files**. You should treat state as sensitive always. It is also advised that you do not store plaintext values in your code but rather populate the `encrypted_value` using fields from a resource, data source or variable as, while encrypted in state, these will be easily accessible in your code. See below for an example of this abstraction. + +## Example Usage + +```terraform +resource "github_actions_organization_secret" "example_secret" { + secret_name = "example_secret_name" + visibility = "private" + plaintext_value = var.some_secret_string +} + +resource "github_actions_organization_secret" "example_secret" { + secret_name = "example_secret_name" + visibility = "private" + encrypted_value = var.some_encrypted_secret_string +} +``` + +```terraform +data "github_repository" "repo" { + full_name = "my-org/repo" +} + +resource "github_actions_organization_secret" "example_secret" { + secret_name = "example_secret_name" + visibility = "selected" + plaintext_value = var.some_secret_string + selected_repository_ids = [data.github_repository.repo.repo_id] +} + +resource "github_actions_organization_secret" "example_secret" { + secret_name = "example_secret_name" + visibility = "selected" + encrypted_value = var.some_encrypted_secret_string + selected_repository_ids = [data.github_repository.repo.repo_id] +} +``` + +## Argument Reference + +The following arguments are supported: + +- `secret_name` - (Required) Name of the secret +- `encrypted_value` - (Optional) Encrypted value of the secret using the GitHub public key in Base64 format. +- `plaintext_value` - (Optional) Plaintext value of the secret to be encrypted +- `visibility` - (Required) Configures the access that repositories have to the organization secret. Must be one of `all`, `private`, `selected`. `selected_repository_ids` is required if set to `selected`. +- `selected_repository_ids` - (Optional) An array of repository ids that can access the organization secret. +- `destroy_on_drift` - (Optional) Boolean indicating whether to recreate the secret if it's modified outside of Terraform. When `true` (default), Terraform will delete and recreate the secret if it detects external changes. When `false`, Terraform will acknowledge external changes but not recreate the secret. Defaults to `true`. + +## Attributes Reference + +- `created_at` - Date of actions_secret creation. +- `updated_at` - Date of actions_secret update. + +## Import + +This resource can be imported using an ID made up of the secret name: + +```sh +$ terraform import github_actions_organization_secret.test_secret test_secret_name +``` + +!> **Note:** The implementation is limited in that it won't fetch the value of the `plaintext_value` or `encrypted_value` fields when importing. You may need to ignore changes for these as a workaround. diff --git a/docs/resources/actions_organization_secret_repositories.md b/docs/resources/actions_organization_secret_repositories.md new file mode 100644 index 0000000000..e8b306c6f4 --- /dev/null +++ b/docs/resources/actions_organization_secret_repositories.md @@ -0,0 +1,39 @@ +--- +page_title: "github_actions_organization_secret_repositories Resource - terraform-provider-github +description: |- + Manages repository allow list for an Action Secret within a GitHub organization +--- + +# github_actions_organization_secret_repositories (Resource) + +This resource allows you to manage repository allow list for existing GitHub Actions secrets within your GitHub organization. You must have write access to an organization secret to use this resource. + +This resource is only applicable when `visibility` of the existing organization secret has been set to `selected`. + +## Example Usage + +```terraform +data "github_repository" "repo" { + full_name = "my-org/repo" +} + +resource "github_actions_organization_secret_repositories" "org_secret_repos" { + secret_name = "existing_secret_name" + selected_repository_ids = [data.github_repository.repo.repo_id] +} +``` + +## Argument Reference + +The following arguments are supported: + +- `secret_name` - (Required) Name of the existing secret +- `selected_repository_ids` - (Required) An array of repository ids that can access the organization secret. + +## Import + +This resource can be imported using an ID made up of the secret name: + +```sh +$ terraform import github_actions_organization_secret_repositories.test_secret_repos test_secret_name +``` diff --git a/docs/resources/actions_organization_secret_repository.md b/docs/resources/actions_organization_secret_repository.md new file mode 100644 index 0000000000..b5815805a8 --- /dev/null +++ b/docs/resources/actions_organization_secret_repository.md @@ -0,0 +1,39 @@ +--- +page_title: "github_actions_organization_secret_repository Resource - terraform-provider-github +description: |- + Adds/remove a repository to an organization secret when the visibility for repository access is set to selected. +--- + +# github_actions_organization_secret_repository (Resource) + +This resource help you to allow/unallow a repository to use an existing GitHub Actions secrets within your GitHub organization. You must have write access to an organization secret to use this resource. + +This resource is only applicable when `visibility` of the existing organization secret has been set to `selected`. + +## Example Usage + +```terraform +data "github_repository" "repo" { + full_name = "my-org/repo" +} + +resource "github_actions_organization_secret_repository" "org_secret_repos" { + secret_name = "EXAMPLE_SECRET_NAME" + repository_id = github_repository.repo.repo_id +} +``` + +## Argument Reference + +The following arguments are supported: + +- `secret_name` - (Required) Name of the existing secret +- `repository_id` - (Required) Repository id that can access the organization secret. + +## Import + +This resource can be imported using an ID made up of the secret name: + +```sh +$ terraform import github_actions_organization_secret_repository.test_secret_repos test_secret_name:repo_id +``` diff --git a/docs/resources/actions_organization_variable.md b/docs/resources/actions_organization_variable.md new file mode 100644 index 0000000000..655872aeb7 --- /dev/null +++ b/docs/resources/actions_organization_variable.md @@ -0,0 +1,54 @@ +--- +page_title: "github_actions_organization_variable Resource - terraform-provider-github +description: |- + Creates and manages an Action variable within a GitHub organization +--- + +# github_actions_organization_variable (Resource) + +This resource allows you to create and manage GitHub Actions variables within your GitHub organization. You must have write access to a repository to use this resource. + +## Example Usage + +```terraform +resource "github_actions_organization_variable" "example_variable" { + variable_name = "example_variable_name" + visibility = "private" + value = "example_variable_value" +} +``` + +```terraform +data "github_repository" "repo" { + full_name = "my-org/repo" +} + +resource "github_actions_organization_variable" "example_variable" { + variable_name = "example_variable_name" + visibility = "selected" + value = "example_variable_value" + selected_repository_ids = [data.github_repository.repo.repo_id] +} +``` + +## Argument Reference + +The following arguments are supported: + +- `variable_name` - (Required) Name of the variable +- `value` - (Required) Value of the variable +- `visibility` - (Required) Configures the access that repositories have to the organization variable. Must be one of `all`, `private`, `selected`. `selected_repository_ids` is required if set to `selected`. +- `selected_repository_ids` - (Optional) An array of repository ids that can access the organization variable. + +## Attributes Reference + +- `created_at` - Date of actions_variable creation. +- `updated_at` - Date of actions_variable update. + +## Import + +This resource can be imported using an ID made up of the variable name: + +```sh +$ terraform import github_actions_organization_variable.test_variable test_variable_name +``` diff --git a/docs/resources/actions_repository_access_level.md b/docs/resources/actions_repository_access_level.md new file mode 100644 index 0000000000..324d9ab0cc --- /dev/null +++ b/docs/resources/actions_repository_access_level.md @@ -0,0 +1,38 @@ +--- +page_title: "github_actions_repository_access_level Resource - terraform-provider-github +description: |- + Manages Actions and Reusable Workflow access for a GitHub repository +--- + +# github_actions_repository_access_level (Resource) + +This resource allows you to set the access level of a non-public repositories actions and reusable workflows for use in other repositories. You must have admin access to a repository to use this resource. + +## Example Usage + +```terraform +resource "github_repository" "example" { + name = "my-repository" + visibility = "private" +} + +resource "github_actions_repository_access_level" "test" { + access_level = "user" + repository = github_repository.example.name +} +``` + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The GitHub repository +- `access_level` - (Required) Where the actions or reusable workflows of the repository may be used. Possible values are `none`, `user`, `organization`, or `enterprise`. + +## Import + +This resource can be imported using the name of the GitHub repository: + +```sh +$ terraform import github_actions_repository_access_level.test my-repository +``` diff --git a/docs/resources/actions_repository_oidc_subject_claim_customization_template.md b/docs/resources/actions_repository_oidc_subject_claim_customization_template.md new file mode 100644 index 0000000000..01a09f4e06 --- /dev/null +++ b/docs/resources/actions_repository_oidc_subject_claim_customization_template.md @@ -0,0 +1,48 @@ +--- +page_title: "github_actions_repository_oidc_subject_claim_customization_template Resource - terraform-provider-github +description: |- + Creates and manages an OpenID Connect subject claim customization template for a repository +--- + +# github_actions_repository_oidc_subject_claim_customization_template (Resource) + +This resource allows you to create and manage an OpenID Connect subject claim customization template for a GitHub repository. + +More information on integrating GitHub with cloud providers using OpenID Connect and a list of available claims is available in the [Actions documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect). + +The following table lists the behaviour of `use_default`: + +| `use_default` | `include_claim_keys` | Template used | +|---------------|----------------------|-----------------------------------------------------------| +| `true` | Unset | GitHub's default | +| `false` | Set | `include_claim_keys` | +| `false` | Unset | Organization's default if set, otherwise GitHub's default | + +## Example Usage + +```terraform +resource "github_repository" "example" { + name = "example-repository" +} + +resource "github_actions_repository_oidc_subject_claim_customization_template" "example_template" { + repository = github_repository.example.name + use_default = false + include_claim_keys = ["actor", "context", "repository_owner"] +} +``` + +## Argument Reference + +The following arguments are supported: + +- `use_default` - (Required) Whether to use the default template or not. If `true`, `include_claim_keys` must not be set. +- `include_claim_keys` - (Optional) A list of OpenID Connect claims. + +## Import + +This resource can be imported using the repository's name. + +```sh +$ terraform import github_actions_repository_oidc_subject_claim_customization_template.test example_repository +``` diff --git a/docs/resources/actions_repository_permissions.md b/docs/resources/actions_repository_permissions.md new file mode 100644 index 0000000000..9a098135e2 --- /dev/null +++ b/docs/resources/actions_repository_permissions.md @@ -0,0 +1,52 @@ +--- +page_title: "github_actions_repository_permissions Resource - terraform-provider-github +description: |- + Enables and manages Actions permissions for a GitHub repository +--- + +# github_actions_repository_permissions (Resource) + +This resource allows you to enable and manage GitHub Actions permissions for a given repository. You must have admin access to an repository to use this resource. + +## Example Usage + +```terraform +resource "github_repository" "example" { + name = "my-repository" +} + +resource "github_actions_repository_permissions" "test" { + allowed_actions = "selected" + allowed_actions_config { + github_owned_allowed = true + patterns_allowed = ["actions/cache@*", "actions/checkout@*"] + verified_allowed = true + } + repository = github_repository.example.name +} +``` + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The GitHub repository +- `allowed_actions` - (Optional) The permissions policy that controls the actions that are allowed to run. Can be one of: `all`, `local_only`, or `selected`. +- `enabled` - (Optional) Should GitHub actions be enabled on this repository? +- `allowed_actions_config` - (Optional) Sets the actions that are allowed in an repository. Only available when `allowed_actions` = `selected`. See [Allowed Actions Config](#allowed-actions-config) below for details. + +### Allowed Actions Config + +The `allowed_actions_config` block supports the following: + +- `github_owned_allowed` - (Required) Whether GitHub-owned actions are allowed in the repository. +- `patterns_allowed` - (Optional) Specifies a list of string-matching patterns to allow specific action(s). Wildcards, tags, and SHAs are allowed. For example, `monalisa/octocat@*`, `monalisa/octocat@v2`, `monalisa/*`. +- `verified_allowed` - (Optional) Whether actions in GitHub Marketplace from verified creators are allowed. Set to `true` to allow all GitHub Marketplace actions by verified creators. + +## Import + +This resource can be imported using the name of the GitHub repository: + +```sh +$ terraform import github_actions_repository_permissions.test my-repository +``` diff --git a/docs/resources/actions_runner_group.md b/docs/resources/actions_runner_group.md new file mode 100644 index 0000000000..71d4029c78 --- /dev/null +++ b/docs/resources/actions_runner_group.md @@ -0,0 +1,55 @@ +--- +page_title: "github_actions_runner_group Resource - terraform-provider-github +description: |- + Creates and manages an Actions Runner Group within a GitHub organization +--- + +# github_actions_runner_group (Resource) + +This resource allows you to create and manage GitHub Actions runner groups within your GitHub enterprise organizations. You must have admin access to an organization to use this resource. + +## Example Usage + +```terraform +resource "github_repository" "example" { + name = "my-repository" +} + +resource "github_actions_runner_group" "example" { + name = github_repository.example.name + visibility = "selected" + selected_repository_ids = [github_repository.example.repo_id] +} +``` + +## Argument Reference + +The following arguments are supported: + +- `name` - (Required) Name of the runner group +- `restricted_to_workflows` - (Optional) If true, the runner group will be restricted to running only the workflows specified in the selected_workflows array. Defaults to false. +- `selected_repository_ids` - (Optional) IDs of the repositories which should be added to the runner group +- `selected_workflows` - (Optional) List of workflows the runner group should be allowed to run. This setting will be ignored unless restricted_to_workflows is set to true. +- `visibility` - (Optional) Visibility of a runner group. Whether the runner group can include `all`, `selected`, or `private` repositories. A value of `private` is not currently supported due to limitations in the GitHub API. +- `allows_public_repositories` - (Optional) Whether public repositories can be added to the runner group. Defaults to false. + +## Attributes Reference + +- `allows_public_repositories` - Whether public repositories can be added to the runner group +- `default` - Whether this is the default runner group +- `etag` - An etag representing the runner group object +- `inherited` - Whether the runner group is inherited from the enterprise level +- `runners_url` - The GitHub API URL for the runner group's runners +- `selected_repository_ids` - List of repository IDs that can access the runner group +- `selected_repositories_url` - GitHub API URL for the runner group's repositories +- `visibility` - The visibility of the runner group +- `restricted_to_workflows` - If true, the runner group will be restricted to running only the workflows specified in the selected_workflows array. Defaults to false. +- `selected_workflows` - List of workflows the runner group should be allowed to run. This setting will be ignored unless restricted_to_workflows is set to true. + +## Import + +This resource can be imported using the ID of the runner group: + +```sh +$ terraform import github_actions_runner_group.test 7 +``` diff --git a/docs/resources/actions_secret.md b/docs/resources/actions_secret.md new file mode 100644 index 0000000000..c81f798e65 --- /dev/null +++ b/docs/resources/actions_secret.md @@ -0,0 +1,58 @@ +--- +page_title: "github_actions_secret Resource - terraform-provider-github +description: |- + Creates and manages an Action Secret within a GitHub repository +--- + +# github_actions_secret (Resource) + +This resource allows you to create and manage GitHub Actions secrets within your GitHub repositories. You must have write access to a repository to use this resource. + +Secret values are encrypted using the [Go '/crypto/box' module](https://godoc.org/golang.org/x/crypto/nacl/box) which is interoperable with [libsodium](https://libsodium.gitbook.io/doc/). Libsodium is used by GitHub to decrypt secret values. + +For the purposes of security, the contents of the `plaintext_value` field have been marked as `sensitive` to Terraform, but it is important to note that **this does not hide it from state files**. You should treat state as sensitive always. It is also advised that you do not store plaintext values in your code but rather populate the `encrypted_value` using fields from a resource, data source or variable as, while encrypted in state, these will be easily accessible in your code. See below for an example of this abstraction. + +## Example Usage + +```terraform +data "github_actions_public_key" "example_public_key" { + repository = "example_repository" +} + +resource "github_actions_secret" "example_secret" { + repository = "example_repository" + secret_name = "example_secret_name" + plaintext_value = var.some_secret_string +} + +resource "github_actions_secret" "example_secret" { + repository = "example_repository" + secret_name = "example_secret_name" + encrypted_value = var.some_encrypted_secret_string +} +``` + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) Name of the repository +- `secret_name` - (Required) Name of the secret +- `encrypted_value` - (Optional) Encrypted value of the secret using the GitHub public key in Base64 format. +- `plaintext_value` - (Optional) Plaintext value of the secret to be encrypted +- `destroy_on_drift` - (Optional) Boolean indicating whether to recreate the secret if it's modified outside of Terraform. When `true` (default), Terraform will delete and recreate the secret if it detects external changes. When `false`, Terraform will acknowledge external changes but not recreate the secret. Defaults to `true`. + +## Attributes Reference + +- `created_at` - Date of actions_secret creation. +- `updated_at` - Date of actions_secret update. + +## Import + +This resource can be imported using an ID made up of the `repository` and `secret_name`: + +```sh +$ terraform import github_actions_secret.example_secret repository/secret_name +``` + +!> **Note:** The implementation is limited in that it won't fetch the value of the `plaintext_value` or `encrypted_value` fields when importing. You may need to ignore changes for these as a workaround. diff --git a/docs/resources/actions_variable.md b/docs/resources/actions_variable.md new file mode 100644 index 0000000000..1c6be38b11 --- /dev/null +++ b/docs/resources/actions_variable.md @@ -0,0 +1,40 @@ +--- +page_title: "github_actions_variable Resource - terraform-provider-github +description: |- + Creates and manages an Action variable within a GitHub repository +--- + +# github_actions_variable (Resource) + +This resource allows you to create and manage GitHub Actions variables within your GitHub repositories. You must have write access to a repository to use this resource. + +## Example Usage + +```terraform +resource "github_actions_variable" "example_variable" { + repository = "example_repository" + variable_name = "example_variable_name" + value = "example_variable_value" +} +``` + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) Name of the repository +- `variable_name` - (Required) Name of the variable +- `value` - (Required) Value of the variable + +## Attributes Reference + +- `created_at` - Date of actions_variable creation. +- `updated_at` - Date of actions_variable update. + +## Import + +GitHub Actions variables can be imported using an ID made up of `repository:variable_name`, e.g. + +```sh +$ terraform import github_actions_variable.myvariable myrepo:myvariable +``` diff --git a/docs/resources/app_installation_repositories.md b/docs/resources/app_installation_repositories.md new file mode 100644 index 0000000000..dc30a62fac --- /dev/null +++ b/docs/resources/app_installation_repositories.md @@ -0,0 +1,51 @@ +--- +page_title: "github_app_installation_repositories Resource - terraform-provider-github +description: |- + Manages the associations between app installations and repositories. +--- + +# github_app_installation_repositories (Resource) + +~> **Note**: This resource is not compatible with the GitHub App Installation authentication method. + +This resource manages relationships between app installations and repositories in your GitHub organization. + +Creating this resource installs a particular app on multiple repositories. + +The app installation and the repositories must all belong to the same organization on GitHub. Note: you can review your organization's installations by the following the instructions at this [link](https://docs.github.com/en/github/setting-up-and-managing-organizations-and-teams/reviewing-your-organizations-installed-integrations). + +## Example Usage + +```terraform +# Create some repositories. +resource "github_repository" "some_repo" { + name = "some-repo" +} + +resource "github_repository" "another_repo" { + name = "another-repo" +} + +resource "github_app_installation_repositories" "some_app_repos" { + # The installation id of the app (in the organization). + installation_id = "1234567" + selected_repositories = [github_repository.some_repo.name, github_repository.another_repo.name]" +} +``` + +## Argument Reference + +The following arguments are supported: + +- `installation_id` - (Required) The GitHub app installation id. +- `selected_repositories` - (Required) A list of repository names to install the app on. + +~> **Note**: Due to how GitHub implements app installations, apps cannot be installed with no repositories selected. Therefore deleting this resource will leave one repository with the app installed. Manually uninstall the app or set the installation to all repositories via the GUI as after deleting this resource. + +## Import + +GitHub App Installation Repositories can be imported using an ID made up of `installation_id`, e.g. + +```sh +$ terraform import github_app_installation_repositories.some_app_repos 1234567 +``` diff --git a/docs/resources/app_installation_repository.md b/docs/resources/app_installation_repository.md new file mode 100644 index 0000000000..ed12bada58 --- /dev/null +++ b/docs/resources/app_installation_repository.md @@ -0,0 +1,45 @@ +--- +page_title: "github_app_installation_repository Resource - terraform-provider-github +description: |- + Manages the associations between app installations and repositories. +--- + +# github_app_installation_repository (Resource) + +~> **Note**: This resource is not compatible with the GitHub App Installation authentication method. + +This resource manages relationships between app installations and repositories in your GitHub organization. + +Creating this resource installs a particular app on a particular repository. + +The app installation and the repository must both belong to the same organization on GitHub. Note: you can review your organization's installations by the following the instructions at this [link](https://docs.github.com/en/github/setting-up-and-managing-organizations-and-teams/reviewing-your-organizations-installed-integrations). + +## Example Usage + +```terraform +# Create a repository. +resource "github_repository" "some_repo" { + name = "some-repo" +} + +resource "github_app_installation_repository" "some_app_repo" { + # The installation id of the app (in the organization). + installation_id = "1234567" + repository = "${github_repository.some_repo.name}" +} +``` + +## Argument Reference + +The following arguments are supported: + +- `installation_id` - (Required) The GitHub app installation id. +- `repository` - (Required) The repository to install the app on. + +## Import + +GitHub App Installation Repository can be imported using an ID made up of `installation_id:repository`, e.g. + +```sh +$ terraform import github_app_installation_repository.terraform_repo 1234567:terraform +``` diff --git a/docs/resources/branch.md b/docs/resources/branch.md new file mode 100644 index 0000000000..a467cbd9c3 --- /dev/null +++ b/docs/resources/branch.md @@ -0,0 +1,64 @@ +--- +page_title: "github_branch Resource - terraform-provider-github +description: |- + Creates and manages branches within GitHub repositories. +--- + +# github_branch (Resource) + +This resource allows you to create and manage branches within your repository. + +Additional constraints can be applied to ensure your branch is created from another branch or commit. + +## Example Usage + +```terraform +resource "github_branch" "development" { + repository = "example" + branch = "development" +} +``` + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The GitHub repository name. + +- `branch` - (Required) The repository branch to create. + +- `source_branch` - (Optional) The branch name to start from. Defaults to `main`. + +- `source_sha` - (Optional) The commit hash to start from. Defaults to the tip of `source_branch`. If provided, `source_branch` is ignored. + +## Attribute Reference + +The following additional attributes are exported: + +- `source_sha` - A string storing the commit this branch was started from. Not populated when imported. + +- `etag` - An etag representing the Branch object. + +- `ref` - A string representing a branch reference, in the form of `refs/heads/`. + +- `sha` - A string storing the reference's `HEAD` commit's SHA1. + +## Import + +GitHub Branch can be imported using an ID made up of `repository:branch`, e.g. + +```sh +$ terraform import github_branch.terraform terraform:main +``` + +Importing github branch into an instance object (when using a for each block to manage multiple branches) + +```sh +$ terraform import github_branch.terraform["terraform"] terraform:main +``` + +Optionally, a source branch may be specified using an ID of `repository:branch:source_branch`. This is useful for importing branches that do not branch directly off main. + +```sh +$ terraform import github_branch.terraform terraform:feature-branch:dev +``` diff --git a/docs/resources/branch_default.md b/docs/resources/branch_default.md new file mode 100644 index 0000000000..01b5e04a44 --- /dev/null +++ b/docs/resources/branch_default.md @@ -0,0 +1,67 @@ +--- +page_title: "github_branch_default Resource - terraform-provider-github +description: |- + Provides a GitHub branch default for a given repository. +--- + +# github_branch_default (Resource) + +Provides a GitHub branch default resource. + +This resource allows you to set the default branch for a given repository. + +Note that use of this resource is incompatible with the `default_branch` option of the `github_repository` resource. Using both will result in plans always showing a diff. + +## Example Usage + +Basic usage: + +```terraform +resource "github_repository" "example" { + name = "example" + description = "My awesome codebase" + auto_init = true +} + +resource "github_branch" "development" { + repository = github_repository.example.name + branch = "development" +} + +resource "github_branch_default" "default"{ + repository = github_repository.example.name + branch = github_branch.development.branch +} +``` + +Renaming to a branch that doesn't exist: + +```terraform +resource "github_repository" "example" { + name = "example" + description = "My awesome codebase" + auto_init = true +} + +resource "github_branch_default" "default"{ + repository = github_repository.example.name + branch = "development" + rename = true +} +``` + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The GitHub repository +- `branch` - (Required) The branch (e.g. `main`) +- `rename` - (Optional) Indicate if it should rename the branch rather than use an existing branch. Defaults to `false`. + +## Import + +GitHub Branch Defaults can be imported using an ID made up of `repository`, e.g. + +```sh +$ terraform import github_branch_default.branch_default my-repo +``` diff --git a/docs/resources/branch_protection.md b/docs/resources/branch_protection.md new file mode 100644 index 0000000000..1debbb1abe --- /dev/null +++ b/docs/resources/branch_protection.md @@ -0,0 +1,141 @@ +--- +page_title: "github_branch_protection Resource - terraform-provider-github +description: |- + Protects a GitHub branch. +--- + +# github_branch_protection (Resource) + +Protects a GitHub branch. + +This resource allows you to configure branch protection for repositories in your organization. When applied, the branch will be protected from forced pushes and deletion. Additional constraints, such as required status checks or restrictions on users, teams, and apps, can also be configured. + +Note: for the `push_allowances` a given user or team must have specific write access to the repository. If specific write access not provided, github will reject the given actor, which will be the cause of terraform drift. + +## Example Usage + +```terraform +# Protect the main branch of the foo repository. Additionally, require that +# the "ci/travis" context to be passing and only allow the engineers team merge +# to the branch. + +resource "github_branch_protection" "example" { + repository_id = github_repository.example.node_id + # also accepts repository name + # repository_id = github_repository.example.name + + pattern = "main" + enforce_admins = true + allows_deletions = true + + required_status_checks { + strict = false + contexts = ["ci/travis"] + } + + required_pull_request_reviews { + dismiss_stale_reviews = true + restrict_dismissals = true + dismissal_restrictions = [ + data.github_user.example.node_id, + github_team.example.node_id, + "/exampleuser", + "exampleorganization/exampleteam", + ] + } + + restrict_pushes { + push_allowances = [ + data.github_user.example.node_id, + "/exampleuser", + "exampleorganization/exampleteam", + # you can have more than one type of restriction (teams + users). If you use + # more than one type, you must use node_ids of each user and each team. + # github_team.example.node_id + # github_user.example-2.node_id + ] + } + + force_push_bypassers = [ + data.github_user.example.node_id, + "/exampleuser", + "exampleorganization/exampleteam", + # you can have more than one type of restriction (teams + users) + # github_team.example.node_id + # github_team.example-2.node_id + ] + +} + +resource "github_repository" "example" { + name = "test" +} + +data "github_user" "example" { + username = "example" +} + +resource "github_team" "example" { + name = "Example Name" +} + +resource "github_team_repository" "example" { + team_id = github_team.example.id + repository = github_repository.example.name + permission = "pull" +} +``` + +## Argument Reference + +The following arguments are supported: + +- `repository_id` - (Required) The name or node ID of the repository associated with this branch protection rule. +- `pattern` - (Required) Identifies the protection rule pattern. +- `enforce_admins` - (Optional) Boolean, setting this to `true` enforces status checks for repository administrators. +- `require_signed_commits` - (Optional) Boolean, setting this to `true` requires all commits to be signed with GPG. +- `required_linear_history` - (Optional) Boolean, setting this to `true` enforces a linear commit Git history, which prevents anyone from pushing merge commits to a branch +- `require_conversation_resolution` - (Optional) Boolean, setting this to `true` requires all conversations on code must be resolved before a pull request can be merged. +- `required_status_checks` - (Optional) Enforce restrictions for required status checks. See [Required Status Checks](#required-status-checks) below for details. +- `required_pull_request_reviews` - (Optional) Enforce restrictions for pull request reviews. See [Required Pull Request Reviews](#required-pull-request-reviews) below for details. +- `restrict_pushes` - (Optional) Restrict pushes to matching branches. See [Restrict Pushes](#restrict-pushes) below for details. +- `force_push_bypassers` - (Optional) The list of actor Names/IDs that are allowed to bypass force push restrictions. Actor names must either begin with a "/" for users or the organization name followed by a "/" for teams. If the list is not empty, `allows_force_pushes` should be set to `false`. +- `allows_deletions` - (Optional) Boolean, setting this to `true` to allow the branch to be deleted. +- `allows_force_pushes` - (Optional) Boolean, setting this to `true` to allow force pushes on the branch to everyone. Set it to `false` if you specify `force_push_bypassers`. +- `lock_branch` - (Optional) Boolean, Setting this to `true` will make the branch read-only and preventing any pushes to it. Defaults to `false` + +### Required Status Checks + +`required_status_checks` supports the following arguments: + +- `strict`: (Optional) Require branches to be up to date before merging. Defaults to `false`. +- `contexts`: (Optional) The list of status checks to require in order to merge into this branch. No status checks are required by default. + +~> Note: This attribute can contain multiple string patterns. If specified, usual value is the [job name](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idname). Otherwise, the [job id](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idname) is defaulted to. For workflows that use matrixes, append the matrix name to the value using the following pattern `([, ])`. Matrixes should be specified based on the order of matrix properties in the workflow file. See [GitHub Documentation](https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs#using-a-matrix-strategy) for more information. For workflows that use reusable workflows, the pattern is ` / `. This can extend multiple levels. + +### Required Pull Request Reviews + +`required_pull_request_reviews` supports the following arguments: + +- `dismiss_stale_reviews`: (Optional) Dismiss approved reviews automatically when a new commit is pushed. Defaults to `false`. +- `restrict_dismissals`: (Optional) Restrict pull request review dismissals. +- `dismissal_restrictions`: (Optional) The list of actor Names/IDs with dismissal access. If not empty, `restrict_dismissals` is ignored. Actor names must either begin with a "/" for users or the organization name followed by a "/" for teams. +- `pull_request_bypassers`: (Optional) The list of actor Names/IDs that are allowed to bypass pull request requirements. Actor names must either begin with a "/" for users or the organization name followed by a "/" for teams. +- `require_code_owner_reviews`: (Optional) Require an approved review in pull requests including files with a designated code owner. Defaults to `false`. +- `required_approving_review_count`: (Optional) Require x number of approvals to satisfy branch protection requirements. If this is specified it must be a number between 0-6. This requirement matches GitHub's API, see the upstream [documentation](https://docs.github.com/en/rest/branches/branch-protection?apiVersion=2022-11-28#update-branch-protection--parameters) for more information. +- `require_last_push_approval`: (Optional) Require that The most recent push must be approved by someone other than the last pusher. Defaults to `false` + +### Restrict Pushes + +`restrict_pushes` supports the following arguments: + +- `blocks_creations` - (Optional) Boolean, setting this to `false` allows people, teams, or apps to create new branches matching this rule. Defaults to `true`. +- `push_allowances` - (Optional) A list of actor Names/IDs that may push to the branch. Actor names must either begin with a "/" for users or the organization name followed by a "/" for teams. Organization administrators, repository administrators, and users with the Maintain role on the repository can always push when all other requirements have passed. + +## Import + +GitHub Branch Protection can be imported using an ID made up of `repository:pattern`, e.g. + +```sh +$ terraform import github_branch_protection.terraform terraform:main +``` diff --git a/docs/resources/branch_protection_v3.md b/docs/resources/branch_protection_v3.md new file mode 100644 index 0000000000..e5a9ee0ab4 --- /dev/null +++ b/docs/resources/branch_protection_v3.md @@ -0,0 +1,142 @@ +--- +page_title: "github_branch_protection_v3 Resource - terraform-provider-github +description: |- + Protects a GitHub branch using the v3 / REST implementation. The `github_branch_protection` resource has moved to the GraphQL API, while this resource will continue to leverage the REST API +--- + +# github_branch_protection_v3 (Resource) + +Protects a GitHub branch. + +The `github_branch_protection` resource has moved to the GraphQL API, while this resource will continue to leverage the REST API. + +This resource allows you to configure branch protection for repositories in your organization. When applied, the branch will be protected from forced pushes and deletion. Additional constraints, such as required status checks or restrictions on users, teams, and apps, can also be configured. + +## Example Usage + +```terraform +# Protect the main branch of the foo repository. Only allow a specific user to merge to the branch. +resource "github_branch_protection_v3" "example" { + repository = github_repository.example.name + branch = "main" + + restrictions { + users = ["foo-user"] + } +} +``` + +```terraform +# Protect the main branch of the foo repository. Additionally, require that +# the "ci/check" check ran by the Github Actions app is passing and only allow +# the engineers team merge to the branch. + +resource "github_branch_protection_v3" "example" { + repository = github_repository.example.name + branch = "main" + enforce_admins = true + + required_status_checks { + strict = false + checks = [ + "ci/check:824642007264" + ] + } + + required_pull_request_reviews { + dismiss_stale_reviews = true + dismissal_users = ["foo-user"] + dismissal_teams = [github_team.example.slug] + dismissal_app = ["foo-app"] + + bypass_pull_request_allowances { + users = ["foo-user"] + teams = [github_team.example.slug] + apps = ["foo-app"] + } + } + + restrictions { + users = ["foo-user"] + teams = [github_team.example.slug] + apps = ["foo-app"] + } +} + +resource "github_repository" "example" { + name = "example" +} + +resource "github_team" "example" { + name = "Example Name" +} + +resource "github_team_repository" "example" { + team_id = github_team.example.id + repository = github_repository.example.name + permission = "pull" +} +``` + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The GitHub repository name. +- `branch` - (Required) The Git branch to protect. +- `enforce_admins` - (Optional) Boolean, setting this to `true` enforces status checks for repository administrators. +- `require_signed_commits` - (Optional) Boolean, setting this to `true` requires all commits to be signed with GPG. +- `require_conversation_resolution` - (Optional) Boolean, setting this to `true` requires all conversations on code must be resolved before a pull request can be merged. +- `required_status_checks` - (Optional) Enforce restrictions for required status checks. See [Required Status Checks](#required-status-checks) below for details. +- `required_pull_request_reviews` - (Optional) Enforce restrictions for pull request reviews. See [Required Pull Request Reviews](#required-pull-request-reviews) below for details. +- `restrictions` - (Optional) Enforce restrictions for the users and teams that may push to the branch. See [Restrictions](#restrictions) below for details. + +### Required Status Checks + +`required_status_checks` supports the following arguments: + +- `strict`: (Optional) Require branches to be up to date before merging. Defaults to `false`. +- `contexts`: [**DEPRECATED**] (Optional) The list of status checks to require in order to merge into this branch. No status checks are required by default. + +~> Note: This attribute can contain multiple string patterns. If specified, usual value is the [job name](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idname). Otherwise, the [job id](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idname) is defaulted to. For workflows that use matrixes, append the matrix name to the value using the following pattern `([, ])`. Matrixes should be specified based on the order of matrix properties in the workflow file. See [GitHub Documentation](https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs#using-a-matrix-strategy) for more information. For workflows that use reusable workflows, the pattern is ` / `. This can extend multiple levels. + +- `checks`: (Optional) The list of status checks to require in order to merge into this branch. No status checks are required by default. Checks should be strings containing the context and app_id like so "context:app_id". + +### Required Pull Request Reviews + +`required_pull_request_reviews` supports the following arguments: + +- `dismiss_stale_reviews`: (Optional) Dismiss approved reviews automatically when a new commit is pushed. Defaults to `false`. +- `dismissal_users`: (Optional) The list of user logins with dismissal access +- `dismissal_teams`: (Optional) The list of team slugs with dismissal access. Always use `slug` of the team, **not** its name. Each team already **has** to have access to the repository. +- `dismissal_apps`: (Optional) The list of app slugs with dismissal access. +- `require_code_owner_reviews`: (Optional) Require an approved review in pull requests including files with a designated code owner. Defaults to `false`. +- `required_approving_review_count`: (Optional) Require x number of approvals to satisfy branch protection requirements. If this is specified it must be a number between 0-6. This requirement matches GitHub's API, see the upstream [documentation](https://docs.github.com/en/rest/branches/branch-protection?apiVersion=2022-11-28#update-branch-protection--parameters) for more information. +- `bypass_pull_request_allowances`: (Optional) Allow specific users, teams, or apps to bypass pull request requirements. See [Bypass Pull Request Allowances](#bypass-pull-request-allowances) below for details. +- `require_last_push_approval`: (Optional) Require that the most recent push must be approved by someone other than the last pusher. Defaults to `false` + +### Restrictions + +`restrictions` supports the following arguments: + +- `users`: (Optional) The list of user logins with push access. +- `teams`: (Optional) The list of team slugs with push access. Always use `slug` of the team, **not** its name. Each team already **has** to have access to the repository. +- `apps`: (Optional) The list of app slugs with push access. + +`restrictions` is only available for organization-owned repositories. + +### Bypass Pull Request Allowances + +`bypass_pull_request_allowances` supports the following arguments: + +- `users`: (Optional) The list of user logins allowed to bypass pull request requirements. +- `teams`: (Optional) The list of team slugs allowed to bypass pull request requirements. +- `apps`: (Optional) The list of app slugs allowed to bypass pull request requirements. + +## Import + +GitHub Branch Protection can be imported using an ID made up of `repository:branch`, e.g. + +```sh +$ terraform import github_branch_protection_v3.terraform terraform:main +``` diff --git a/docs/resources/codespaces_organization_secret.md b/docs/resources/codespaces_organization_secret.md new file mode 100644 index 0000000000..d80c5d920a --- /dev/null +++ b/docs/resources/codespaces_organization_secret.md @@ -0,0 +1,74 @@ +--- +page_title: "github_codespaces_organization_secret Resource - terraform-provider-github +description: |- + Creates and manages an Codespaces Secret within a GitHub organization +--- + +# github_codespaces_organization_secret (Resource) + +This resource allows you to create and manage GitHub Codespaces secrets within your GitHub organization. You must have write access to a repository to use this resource. + +Secret values are encrypted using the [Go '/crypto/box' module](https://godoc.org/golang.org/x/crypto/nacl/box) which is interoperable with [libsodium](https://libsodium.gitbook.io/doc/). Libsodium is used by GitHub to decrypt secret values. + +For the purposes of security, the contents of the `plaintext_value` field have been marked as `sensitive` to Terraform, but it is important to note that **this does not hide it from state files**. You should treat state as sensitive always. It is also advised that you do not store plaintext values in your code but rather populate the `encrypted_value` using fields from a resource, data source or variable as, while encrypted in state, these will be easily accessible in your code. See below for an example of this abstraction. + +## Example Usage + +```terraform +resource "github_codespaces_organization_secret" "example_secret" { + secret_name = "example_secret_name" + visibility = "private" + plaintext_value = var.some_secret_string +} + +resource "github_codespaces_organization_secret" "example_secret" { + secret_name = "example_secret_name" + visibility = "private" + encrypted_value = var.some_encrypted_secret_string +} +``` + +```terraform +data "github_repository" "repo" { + full_name = "my-org/repo" +} + +resource "github_codespaces_organization_secret" "example_secret" { + secret_name = "example_secret_name" + visibility = "selected" + plaintext_value = var.some_secret_string + selected_repository_ids = [data.github_repository.repo.repo_id] +} + +resource "github_codespaces_organization_secret" "example_secret" { + secret_name = "example_secret_name" + visibility = "selected" + encrypted_value = var.some_encrypted_secret_string + selected_repository_ids = [data.github_repository.repo.repo_id] +} +``` + +## Argument Reference + +The following arguments are supported: + +- `secret_name` - (Required) Name of the secret +- `encrypted_value` - (Optional) Encrypted value of the secret using the GitHub public key in Base64 format. +- `plaintext_value` - (Optional) Plaintext value of the secret to be encrypted +- `visibility` - (Required) Configures the access that repositories have to the organization secret. Must be one of `all`, `private`, `selected`. `selected_repository_ids` is required if set to `selected`. +- `selected_repository_ids` - (Optional) An array of repository ids that can access the organization secret. + +## Attributes Reference + +- `created_at` - Date of codespaces_secret creation. +- `updated_at` - Date of codespaces_secret update. + +## Import + +This resource can be imported using an ID made up of the secret name: + +```sh +terraform import github_codespaces_organization_secret.test_secret test_secret_name +``` + +!> **Note:** The implementation is limited in that it won't fetch the value of the `plaintext_value` or `encrypted_value` fields when importing. You may need to ignore changes for these as a workaround. diff --git a/docs/resources/codespaces_organization_secret_repositories.md b/docs/resources/codespaces_organization_secret_repositories.md new file mode 100644 index 0000000000..28bc40509d --- /dev/null +++ b/docs/resources/codespaces_organization_secret_repositories.md @@ -0,0 +1,41 @@ +--- +page_title: "github_codespaces_organization_secret_repositories Resource - terraform-provider-github +description: |- + Manages repository allow list for a Codespaces Secret within a GitHub organization +--- + +# github_codespaces_organization_secret_repositories (Resource) + +This resource allows you to manage repository allow list for existing GitHub Codespaces secrets within your GitHub organization. + +You must have write access to an organization secret to use this resource. + +This resource is only applicable when `visibility` of the existing organization secret has been set to `selected`. + +## Example Usage + +```terraform +data "github_repository" "repo" { + full_name = "my-org/repo" +} + +resource "github_codespaces_organization_secret_repositories" "org_secret_repos" { + secret_name = "existing_secret_name" + selected_repository_ids = [data.github_repository.repo.repo_id] +} +``` + +## Argument Reference + +The following arguments are supported: + +- `secret_name` - (Required) Name of the existing secret +- `selected_repository_ids` - (Required) An array of repository ids that can access the organization secret. + +## Import + +This resource can be imported using an ID made up of the secret name: + +```sh +$ terraform import github_codespaces_organization_secret_repositories.org_secret_repos existing_secret_name +``` diff --git a/docs/resources/codespaces_secret.md b/docs/resources/codespaces_secret.md new file mode 100644 index 0000000000..be1974db17 --- /dev/null +++ b/docs/resources/codespaces_secret.md @@ -0,0 +1,57 @@ +--- +page_title: "github_codespaces_secret Resource - terraform-provider-github +description: |- + Creates and manages an Codespaces Secret within a GitHub repository +--- + +# github_codespaces_secret (Resource) + +This resource allows you to create and manage GitHub Codespaces secrets within your GitHub repositories. You must have write access to a repository to use this resource. + +Secret values are encrypted using the [Go '/crypto/box' module](https://godoc.org/golang.org/x/crypto/nacl/box) which is interoperable with [libsodium](https://libsodium.gitbook.io/doc/). Libsodium is used by GitHub to decrypt secret values. + +For the purposes of security, the contents of the `plaintext_value` field have been marked as `sensitive` to Terraform, but it is important to note that **this does not hide it from state files**. You should treat state as sensitive always. It is also advised that you do not store plaintext values in your code but rather populate the `encrypted_value` using fields from a resource, data source or variable as, while encrypted in state, these will be easily accessible in your code. See below for an example of this abstraction. + +## Example Usage + +```terraform +data "github_codespaces_public_key" "example_public_key" { + repository = "example_repository" +} + +resource "github_codespaces_secret" "example_secret" { + repository = "example_repository" + secret_name = "example_secret_name" + plaintext_value = var.some_secret_string +} + +resource "github_codespaces_secret" "example_secret" { + repository = "example_repository" + secret_name = "example_secret_name" + encrypted_value = var.some_encrypted_secret_string +} +``` + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) Name of the repository +- `secret_name` - (Required) Name of the secret +- `encrypted_value` - (Optional) Encrypted value of the secret using the GitHub public key in Base64 format. +- `plaintext_value` - (Optional) Plaintext value of the secret to be encrypted + +## Attributes Reference + +- `created_at` - Date of codespaces_secret creation. +- `updated_at` - Date of codespaces_secret update. + +## Import + +This resource can be imported using an ID made up of the `repository` and `secret_name`: + +```sh +$ terraform import github_codespaces_secret.example_secret example_repository/example_secret_name +``` + +!> **Note:** The implementation is limited in that it won't fetch the value of the `plaintext_value` or `encrypted_value` fields when importing. You may need to ignore changes for these as a workaround. diff --git a/docs/resources/codespaces_user_secret.md b/docs/resources/codespaces_user_secret.md new file mode 100644 index 0000000000..307bec1be3 --- /dev/null +++ b/docs/resources/codespaces_user_secret.md @@ -0,0 +1,57 @@ +--- +page_title: "github_codespaces_user_secret Resource - terraform-provider-github +description: |- + Creates and manages an Codespaces Secret within a GitHub user +--- + +# github_codespaces_user_secret (Resource) + +This resource allows you to create and manage GitHub Codespaces secrets within your GitHub user. You must have write access to a repository to use this resource. + +Secret values are encrypted using the [Go '/crypto/box' module](https://godoc.org/golang.org/x/crypto/nacl/box) which is interoperable with [libsodium](https://libsodium.gitbook.io/doc/). Libsodium is used by GitHub to decrypt secret values. + +For the purposes of security, the contents of the `plaintext_value` field have been marked as `sensitive` to Terraform, but it is important to note that **this does not hide it from state files**. You should treat state as sensitive always. It is also advised that you do not store plaintext values in your code but rather populate the `encrypted_value` using fields from a resource, data source or variable as, while encrypted in state, these will be easily accessible in your code. See below for an example of this abstraction. + +## Example Usage + +```terraform +data "github_repository" "repo" { + full_name = "my-org/repo" +} + +resource "github_codespaces_user_secret" "example_secret" { + secret_name = "example_secret_name" + plaintext_value = var.some_secret_string + selected_repository_ids = [data.github_repository.repo.repo_id] +} + +resource "github_codespaces_user_secret" "example_secret" { + secret_name = "example_secret_name" + encrypted_value = var.some_encrypted_secret_string + selected_repository_ids = [data.github_repository.repo.repo_id] +} +``` + +## Argument Reference + +The following arguments are supported: + +- `secret_name` - (Required) Name of the secret +- `encrypted_value` - (Optional) Encrypted value of the secret using the GitHub public key in Base64 format. +- `plaintext_value` - (Optional) Plaintext value of the secret to be encrypted +- `selected_repository_ids` - (Optional) An array of repository ids that can access the user secret. + +## Attributes Reference + +- `created_at` - Date of codespaces_secret creation. +- `updated_at` - Date of codespaces_secret update. + +## Import + +This resource can be imported using an ID made up of the secret name: + +```sh +terraform import github_codespaces_user_secret.test_secret test_secret_name +``` + +!> **Note:** The implementation is limited in that it won't fetch the value of the `plaintext_value` or `encrypted_value` fields when importing. You may need to ignore changes for these as a workaround. diff --git a/docs/resources/dependabot_organization_secret.md b/docs/resources/dependabot_organization_secret.md new file mode 100644 index 0000000000..41a6b5891b --- /dev/null +++ b/docs/resources/dependabot_organization_secret.md @@ -0,0 +1,74 @@ +--- +page_title: "github_dependabot_organization_secret Resource - terraform-provider-github +description: |- + Creates and manages an Dependabot Secret within a GitHub organization +--- + +# github_dependabot_organization_secret (Resource) + +This resource allows you to create and manage GitHub Dependabot secrets within your GitHub organization. You must have write access to a repository to use this resource. + +Secret values are encrypted using the [Go '/crypto/box' module](https://godoc.org/golang.org/x/crypto/nacl/box) which is interoperable with [libsodium](https://libsodium.gitbook.io/doc/). Libsodium is used by GitHub to decrypt secret values. + +For the purposes of security, the contents of the `plaintext_value` field have been marked as `sensitive` to Terraform, but it is important to note that **this does not hide it from state files**. You should treat state as sensitive always. It is also advised that you do not store plaintext values in your code but rather populate the `encrypted_value` using fields from a resource, data source or variable as, while encrypted in state, these will be easily accessible in your code. See below for an example of this abstraction. + +## Example Usage + +```terraform +resource "github_dependabot_organization_secret" "example_secret" { + secret_name = "example_secret_name" + visibility = "private" + plaintext_value = var.some_secret_string +} + +resource "github_dependabot_organization_secret" "example_secret" { + secret_name = "example_secret_name" + visibility = "private" + encrypted_value = var.some_encrypted_secret_string +} +``` + +```terraform +data "github_repository" "repo" { + full_name = "my-org/repo" +} + +resource "github_dependabot_organization_secret" "example_secret" { + secret_name = "example_secret_name" + visibility = "selected" + plaintext_value = var.some_secret_string + selected_repository_ids = [data.github_repository.repo.repo_id] +} + +resource "github_dependabot_organization_secret" "example_secret" { + secret_name = "example_secret_name" + visibility = "selected" + encrypted_value = var.some_encrypted_secret_string + selected_repository_ids = [data.github_repository.repo.repo_id] +} +``` + +## Argument Reference + +The following arguments are supported: + +- `secret_name` - (Required) Name of the secret +- `encrypted_value` - (Optional) Encrypted value of the secret using the GitHub public key in Base64 format. +- `plaintext_value` - (Optional) Plaintext value of the secret to be encrypted +- `visibility` - (Required) Configures the access that repositories have to the organization secret. Must be one of `all`, `private`, `selected`. `selected_repository_ids` is required if set to `selected`. +- `selected_repository_ids` - (Optional) An array of repository ids that can access the organization secret. + +## Attributes Reference + +- `created_at` - Date of dependabot_secret creation. +- `updated_at` - Date of dependabot_secret update. + +## Import + +This resource can be imported using an ID made up of the secret name: + +```sh +terraform import github_dependabot_organization_secret.test_secret test_secret_name +``` + +!> **Note:** The implementation is limited in that it won't fetch the value of the `plaintext_value` or `encrypted_value` fields when importing. You may need to ignore changes for these as a workaround. diff --git a/docs/resources/dependabot_organization_secret_repositories.md b/docs/resources/dependabot_organization_secret_repositories.md new file mode 100644 index 0000000000..b0d25c7712 --- /dev/null +++ b/docs/resources/dependabot_organization_secret_repositories.md @@ -0,0 +1,45 @@ +--- +page_title: "github_dependabot_organization_secret_repositories Resource - terraform-provider-github +description: |- + Manages repository allow list for an Dependabot Secret within a GitHub organization +--- + +# github_dependabot_organization_secret_repositories (Resource) + +This resource allows you to manage the repository allow list for existing GitHub Dependabot secrets within your GitHub organization. You must have write access to an organization secret to use this resource. + +This resource is only applicable when `visibility` of the existing organization secret has been set to `selected`. + +## Example Usage + +```terraform +data "github_repository" "repo" { + full_name = "my-org/repo" +} + +resource "github_dependabot_organization_secret" "example_secret" { + secret_name = "example_secret_name" + visibility = "private" + plaintext_value = var.some_secret_string +} + +resource "github_dependabot_organization_secret_repositories" "org_secret_repos" { + secret_name = github_dependabot_organization_secret.example_secret.secret_name + selected_repository_ids = [data.github_repository.repo.repo_id] +} +``` + +## Argument Reference + +The following arguments are supported: + +- `secret_name` - (Required) Name of the existing secret +- `selected_repository_ids` - (Required) An array of repository ids that can access the organization secret. + +## Import + +This resource can be imported using an ID made up of the secret name: + +```sh +terraform import github_dependabot_organization_secret_repositories.test_secret_repos test_secret_name +``` diff --git a/docs/resources/dependabot_secret.md b/docs/resources/dependabot_secret.md new file mode 100644 index 0000000000..4ea8a8cb51 --- /dev/null +++ b/docs/resources/dependabot_secret.md @@ -0,0 +1,57 @@ +--- +page_title: "github_dependabot_secret Resource - terraform-provider-github +description: |- + Creates and manages an Dependabot Secret within a GitHub repository +--- + +# github_dependabot_secret (Resource) + +This resource allows you to create and manage GitHub Dependabot secrets within your GitHub repositories. You must have write access to a repository to use this resource. + +Secret values are encrypted using the [Go '/crypto/box' module](https://godoc.org/golang.org/x/crypto/nacl/box) which is interoperable with [libsodium](https://libsodium.gitbook.io/doc/). Libsodium is used by GitHub to decrypt secret values. + +For the purposes of security, the contents of the `plaintext_value` field have been marked as `sensitive` to Terraform, but it is important to note that **this does not hide it from state files**. You should treat state as sensitive always. It is also advised that you do not store plaintext values in your code but rather populate the `encrypted_value` using fields from a resource, data source or variable as, while encrypted in state, these will be easily accessible in your code. See below for an example of this abstraction. + +## Example Usage + +```terraform +data "github_dependabot_public_key" "example_public_key" { + repository = "example_repository" +} + +resource "github_dependabot_secret" "example_secret" { + repository = "example_repository" + secret_name = "example_secret_name" + plaintext_value = var.some_secret_string +} + +resource "github_dependabot_secret" "example_secret" { + repository = "example_repository" + secret_name = "example_secret_name" + encrypted_value = var.some_encrypted_secret_string +} +``` + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) Name of the repository +- `secret_name` - (Required) Name of the secret +- `encrypted_value` - (Optional) Encrypted value of the secret using the GitHub public key in Base64 format. +- `plaintext_value` - (Optional) Plaintext value of the secret to be encrypted + +## Attributes Reference + +- `created_at` - Date of dependabot_secret creation. +- `updated_at` - Date of dependabot_secret update. + +## Import + +This resource can be imported using an ID made up of the `repository` and `secret_name`: + +```sh +$ terraform import github_dependabot_secret.example_secret example_repository/example_secret +``` + +!> **Note:** The implementation is limited in that it won't fetch the value of the `plaintext_value` or `encrypted_value` fields when importing. You may need to ignore changes for these as a workaround. diff --git a/docs/resources/emu_group_mapping.md b/docs/resources/emu_group_mapping.md new file mode 100644 index 0000000000..e3110a3190 --- /dev/null +++ b/docs/resources/emu_group_mapping.md @@ -0,0 +1,35 @@ +--- +page_title: "github_emu_group_mapping Resource - terraform-provider-github +description: |- + Manages mappings between external groups for enterprise managed users. +--- + +# github_emu_group_mapping (Resource) + +This resource manages mappings between external groups for enterprise managed users and GitHub teams. It wraps the API detailed [here](https://docs.github.com/en/rest/reference/teams#external-groups). Note that this is a distinct resource from `github_team_sync_group_mapping`. `github_emu_group_mapping` is special to the Enterprise Managed User (EMU) external group feature, whereas `github_team_sync_group_mapping` is specific to Identity Provider Groups. + +## Example Usage + +```terraform +resource "github_emu_group_mapping" "example_emu_group_mapping" { + team_slug = "emu-test-team" # The GitHub team name to modify + group_id = 28836 # The group ID of the external group to link +} + +# Note that here GITHUB_OWNER and GITHUB_TOKEN have been set in the environment. +``` + +## Argument Reference + +The following arguments are supported: + +- `team_slug` - (Required) Slug of the GitHub team +- `group_id` - (Required) Integer corresponding to the external group ID to be linked + +## Import + +GitHub EMU External Group Mappings can be imported using the external `group_id`, e.g. + +```sh +$ terraform import github_emu_group_mapping.example_emu_group_mapping 28836 +``` diff --git a/docs/resources/enterprise_actions_permissions.md b/docs/resources/enterprise_actions_permissions.md new file mode 100644 index 0000000000..ee8f8e5a75 --- /dev/null +++ b/docs/resources/enterprise_actions_permissions.md @@ -0,0 +1,63 @@ +--- +page_title: "github_enterprise_actions_permissions Resource - terraform-provider-github +description: |- + Creates and manages Actions permissions within a GitHub enterprise +--- + +# github_enterprise_actions_permissions (Resource) + +This resource allows you to create and manage GitHub Actions permissions within your GitHub enterprise. You must have admin access to an enterprise to use this resource. + +## Example Usage + +```terraform +data "github_organization" "example-org" { + name = "my-org" +} + +resource "github_enterprise_actions_permissions" "test" { + enterprise_slug = "my-enterprise" + allowed_actions = "selected" + enabled_organizations = "selected" + allowed_actions_config { + github_owned_allowed = true + patterns_allowed = ["actions/cache@*", "actions/checkout@*"] + verified_allowed = true + } + enabled_organizations_config { + organization_ids = [data.github_organization.example-org.id] + } +} +``` + +## Argument Reference + +The following arguments are supported: + +- `enterprise_slug` - (Required) The slug of the enterprise. +- `allowed_actions` - (Optional) The permissions policy that controls the actions that are allowed to run. Can be one of: `all`, `local_only`, or `selected`. +- `enabled_organizations` - (Required) The policy that controls the organizations in the enterprise that are allowed to run GitHub Actions. Can be one of: `all`, `none`, or `selected`. +- `allowed_actions_config` - (Optional) Sets the actions that are allowed in an enterprise. Only available when `allowed_actions` = `selected`. See [Allowed Actions Config](#allowed-actions-config) below for details. +- `enabled_organizations_config` - (Optional) Sets the list of selected organizations that are enabled for GitHub Actions in an enterprise. Only available when `enabled_organizations` = `selected`. See [Enabled Organizations Config](#enabled-organizations-config) below for details. + +### Allowed Actions Config + +The `allowed_actions_config` block supports the following: + +- `github_owned_allowed` - (Required) Whether GitHub-owned actions are allowed in the organization. +- `patterns_allowed` - (Optional) Specifies a list of string-matching patterns to allow specific action(s). Wildcards, tags, and SHAs are allowed. For example, `monalisa/octocat@*`, `monalisa/octocat@v2`, `monalisa/*`. +- `verified_allowed` - (Optional) Whether actions in GitHub Marketplace from verified creators are allowed. Set to `true` to allow all GitHub Marketplace actions by verified creators. + +### Enabled Organizations Config + +The `enabled_organizations_config` block supports the following: + +- `organization_ids` - (Required) List of organization IDs to enable for GitHub Actions. + +## Import + +This resource can be imported using the name of the GitHub enterprise: + +```sh +$ terraform import github_enterprise_actions_permissions.test github_enterprise_name +``` diff --git a/docs/resources/enterprise_actions_runner_group.md b/docs/resources/enterprise_actions_runner_group.md new file mode 100644 index 0000000000..98c706ab8e --- /dev/null +++ b/docs/resources/enterprise_actions_runner_group.md @@ -0,0 +1,64 @@ +--- +page_title: "github_enterprise_actions_runner_group Resource - terraform-provider-github +description: |- + Creates and manages an Actions Runner Group within a GitHub enterprise. +--- + +# github_enterprise_actions_runner_group (Resource) + +This resource allows you to create and manage GitHub Actions runner groups within your GitHub enterprise. You must have admin access to an enterprise to use this resource. + +## Example Usage + +```terraform +data "github_enterprise" "enterprise" { + slug = "my-enterprise" +} + +resource "github_enterprise_organization" "enterprise_organization" { + enterprise_id = data.github_enterprise.enterprise.id + name = "my-organization" + billing_email = "octocat@octo.cat" + admin_logins = ["octocat"] +} + +resource "github_enterprise_actions_runner_group" "example" { + name = "my-awesome-runner-group" + enterprise_slug = data.github_enterprise.enterprise.slug + allows_public_repositories = true + visibility = "selected" + selected_organization_ids = [github_enterprise_organization.enterprise_organization.database_id] + restricted_to_workflows = true + selected_workflows = ["my-organization/my-repo/.github/workflows/cool-workflow.yaml@refs/tags/v1"] +} +``` + +## Argument Reference + +The following arguments are supported: + +- `enterprise_slug` - (Required) The slug of the enterprise. +- `name` - (Required) Name of the runner group +- `visibility` - (Required) Visibility of a runner group to enterprise organizations. Whether the runner group can include `all` or `selected` +- `selected_organization_ids` - (Optional) IDs of the organizations which should be added to the runner group +- `allows_public_repositories` - (Optional) Whether public repositories can be added to the runner group. Defaults to false. +- `restricted_to_workflows` - (Optional) If true, the runner group will be restricted to running only the workflows specified in the selected_workflows array. Defaults to false. +- `selected_workflows` - (Optional) List of workflows the runner group should be allowed to run. This setting will be ignored unless restricted_to_workflows is set to true. + +## Attributes Reference + +The following additional attributes are exported: + +- `id` - The ID of the runner group +- `default` - Whether this is the default runner group +- `etag` - An etag representing the runner group object +- `runners_url` - The GitHub API URL for the runner group's runners +- `selected_organizations_url` - The GitHub API URL for the runner group's selected organizations + +## Import + +This resource can be imported using the enterprise slug and the ID of the runner group: + +```sh +$ terraform import github_enterprise_actions_runner_group.test enterprise-slug/42 +``` diff --git a/docs/resources/enterprise_actions_workflow_permissions.md b/docs/resources/enterprise_actions_workflow_permissions.md new file mode 100644 index 0000000000..88cac51e9e --- /dev/null +++ b/docs/resources/enterprise_actions_workflow_permissions.md @@ -0,0 +1,64 @@ +--- +page_title: "github_enterprise_actions_workflow_permissions Resource - terraform-provider-github +description: |- + Manages GitHub Actions workflow permissions for a GitHub Enterprise. +--- + +# github_enterprise_actions_workflow_permissions (Resource) + +This resource allows you to manage GitHub Actions workflow permissions for a GitHub Enterprise account. This controls the default permissions granted to the GITHUB_TOKEN when running workflows and whether GitHub Actions can approve pull request reviews. + +You must have enterprise admin access to use this resource. + +## Example Usage + +```terraform +# Basic workflow permissions configuration +resource "github_enterprise_actions_workflow_permissions" "example" { + enterprise_slug = "my-enterprise" + + default_workflow_permissions = "read" + can_approve_pull_request_reviews = false +} + +# Allow write permissions and PR approvals +resource "github_enterprise_actions_workflow_permissions" "permissive" { + enterprise_slug = "my-enterprise" + + default_workflow_permissions = "write" + can_approve_pull_request_reviews = true +} +``` + +## Argument Reference + +The following arguments are supported: + +- `enterprise_slug` - (Required) The slug of the enterprise. + +- `default_workflow_permissions` - (Optional) The default workflow permissions granted to the GITHUB_TOKEN when running workflows. Can be `read` or `write`. Defaults to `read`. + +- `can_approve_pull_request_reviews` - (Optional) Whether GitHub Actions can approve pull request reviews. Defaults to `false`. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +- `id` - The enterprise slug. + +## Import + +Enterprise Actions workflow permissions can be imported using the enterprise slug: + +```sh +terraform import github_enterprise_actions_workflow_permissions.example my-enterprise +``` + +## Notes + +~> **Note:** This resource requires a GitHub Enterprise account and enterprise admin permissions. + +When this resource is destroyed, the workflow permissions will be reset to safe defaults: + +- `default_workflow_permissions` = `read` +- `can_approve_pull_request_reviews` = `false` diff --git a/docs/resources/enterprise_organization.md b/docs/resources/enterprise_organization.md new file mode 100644 index 0000000000..b85c0e4977 --- /dev/null +++ b/docs/resources/enterprise_organization.md @@ -0,0 +1,48 @@ +--- +page_title: "github_enterprise_organization Resource - terraform-provider-github +description: |- + Create and manages a GitHub enterprise organization. +--- + +# github_enterprise_organization (Resource) + +This resource allows you to create and manage a GitHub enterprise organization. + +## Example Usage + +``` +resource "github_enterprise_organization" "org" { + enterprise_id = data.github_enterprise.enterprise.id + name = "some-awesome-org" + display_name = "Some Awesome Org" + description = "Organization created with terraform" + billing_email = "jon@winteriscoming.com" + admin_logins = [ + "jon-snow" + ] +} +``` + +## Argument Reference + +- `enterprise_id` - (Required) The ID of the enterprise. +- `name` - (Required) The name of the organization. +- `description` - (Optional) The description of the organization. +- `display_name` - (Optional) The display name of the organization. +- `billing_email` - (Required) The billing email address. +- `admin_logins` - (Required) List of organization owner usernames. + +## Attributes Reference + +The following additional attributes are exported: + +- `id` - The node ID of the organization for use with the v4 API. +- `database_id` - The ID of the organization. + +## Import + +GitHub Enterprise Organization can be imported using the `slug` of the enterprise, combined with the `orgname` of the organization, separated by a `/` character. + +```sh +$ terraform import github_enterprise_organization.org enterp/some-awesome-org +``` diff --git a/docs/resources/enterprise_security_analysis_settings.md b/docs/resources/enterprise_security_analysis_settings.md new file mode 100644 index 0000000000..60d1775d20 --- /dev/null +++ b/docs/resources/enterprise_security_analysis_settings.md @@ -0,0 +1,82 @@ +--- +page_title: "github_enterprise_security_analysis_settings Resource - terraform-provider-github +description: |- + Manages GitHub Enterprise security analysis settings. +--- + +# github_enterprise_security_analysis_settings (Resource) + +This resource allows you to manage code security and analysis settings for a GitHub Enterprise account. This controls Advanced Security, Secret Scanning, and related security features that are automatically enabled for new repositories in the enterprise. + +You must have enterprise admin access to use this resource. + +## Example Usage + +```terraform +# Basic security settings - enable secret scanning only +resource "github_enterprise_security_analysis_settings" "basic" { + enterprise_slug = "my-enterprise" + + secret_scanning_enabled_for_new_repositories = true +} + +# Full security configuration with all features enabled +resource "github_enterprise_security_analysis_settings" "comprehensive" { + enterprise_slug = "my-enterprise" + + advanced_security_enabled_for_new_repositories = true + secret_scanning_enabled_for_new_repositories = true + secret_scanning_push_protection_enabled_for_new_repositories = true + secret_scanning_validity_checks_enabled = true + secret_scanning_push_protection_custom_link = "https://octokit.com/security-guidelines" +} +``` + +## Argument Reference + +The following arguments are supported: + +- `enterprise_slug` - (Required) The slug of the enterprise. + +- `advanced_security_enabled_for_new_repositories` - (Optional) Whether GitHub Advanced Security is automatically enabled for new repositories. Defaults to `false`. Requires Advanced Security license. + +- `secret_scanning_enabled_for_new_repositories` - (Optional) Whether secret scanning is automatically enabled for new repositories. Defaults to `false`. + +- `secret_scanning_push_protection_enabled_for_new_repositories` - (Optional) Whether secret scanning push protection is automatically enabled for new repositories. Defaults to `false`. + +- `secret_scanning_push_protection_custom_link` - (Optional) Custom URL for secret scanning push protection bypass instructions. + +- `secret_scanning_validity_checks_enabled` - (Optional) Whether secret scanning validity checks are enabled. Defaults to `false`. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +- `id` - The enterprise slug. + +## Import + +Enterprise security analysis settings can be imported using the enterprise slug: + +```sh +terraform import github_enterprise_security_analysis_settings.example my-enterprise +``` + +## Notes + +~> **Note:** This resource requires a GitHub Enterprise account and enterprise admin permissions. + +~> **Note:** Advanced Security features require a GitHub Advanced Security license. + +When this resource is destroyed, all security analysis settings will be reset to disabled defaults for security reasons. + +## Dependencies + +This resource manages the following security features: + +- **Advanced Security**: Code scanning, secret scanning, and dependency review +- **Secret Scanning**: Automatic detection of secrets in code +- **Push Protection**: Prevents secrets from being committed to repositories +- **Validity Checks**: Verifies that detected secrets are actually valid + +These settings only apply to **new repositories** created after the settings are enabled. Existing repositories are not affected and must be configured individually. diff --git a/docs/resources/issue.md b/docs/resources/issue.md new file mode 100644 index 0000000000..8c9bbd8607 --- /dev/null +++ b/docs/resources/issue.md @@ -0,0 +1,87 @@ +--- +page_title: "github_issue Resource - terraform-provider-github +description: |- + Provides a GitHub issue resource. +--- + +# github_issue (Resource) + +Provides a GitHub issue resource. + +This resource allows you to create and manage issue within your GitHub repository. + +## Example Usage + +```terraform +# Create a simple issue +resource "github_repository" "test" { + name = "tf-acc-test-%s" + auto_init = true + has_issues = true +} + +resource "github_issue" "test" { + repository = github_repository.test.name + title = "My issue title" + body = "The body of my issue" +} +``` + +## Example Usage with milestone and project assignment + +```terraform +# Create an issue with milestone and project assignment +resource "github_repository" "test" { + name = "tf-acc-test-%s" + auto_init = true + has_issues = true +} + +resource "github_repository_milestone" "test" { + owner = split("/", "${github_repository.test.full_name}")[0] + repository = github_repository.test.name + title = "v1.0.0" + description = "General Availability" + due_date = "2022-11-22" + state = "open" +} + +resource "github_issue" "test" { + repository = github_repository.test.name + title = "My issue" + body = "My issue body" + labels = ["bug", "documentation"] + assignees = ["bob-github"] + milestone_number = github_repository_milestone.test.number +} +``` + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The GitHub repository name + +- `title` - (Required) Title of the issue + +- `body` - (Optional) Body of the issue + +- `labels` - (Optional) List of labels to attach to the issue + +- `assignees` - (Optional) List of Logins to assign the to the issue + +- `milestone_number` - (Optional) Milestone number to assign to the issue + +## Attributes Reference + +- `number` - (Computed) - The issue number + +- `issue_id` - (Computed) - The issue id + +## Import + +GitHub Issues can be imported using an ID made up of `repository:number`, e.g. + +```sh +$ terraform import github_issue.issue_15 myrepo:15 +``` diff --git a/docs/resources/issue_label.md b/docs/resources/issue_label.md new file mode 100644 index 0000000000..2b98ca1566 --- /dev/null +++ b/docs/resources/issue_label.md @@ -0,0 +1,50 @@ +--- +page_title: "github_issue_label Resource - terraform-provider-github +description: |- + Provides a GitHub issue label resource. +--- + +# github_issue_label (Resource) + +Provides a GitHub issue label resource. + +This resource allows you to create and manage issue labels within your GitHub organization. + +Issue labels are keyed off of their "name", so pre-existing issue labels result in a 422 HTTP error if they exist outside of Terraform. Normally this would not be an issue, except new repositories are created with a "default" set of labels, and those labels easily conflict with custom ones. + +This resource will first check if the label exists, and then issue an update, otherwise it will create. + +~> **Note:** When a repository is archived, Terraform will skip deletion of issue labels to avoid API errors, as archived repositories are read-only. The labels will be removed from Terraform state without attempting to delete them from GitHub. + +## Example Usage + +```terraform +# Create a new, red colored label +resource "github_issue_label" "test_repo" { + repository = "test-repo" + name = "Urgent" + color = "FF0000" +} +``` + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The GitHub repository + +- `name` - (Required) The name of the label. + +- `color` - (Required) A 6 character hex code, **without the leading #**, identifying the color of the label. + +- `description` - (Optional) A short description of the label. + +- `url` - (Computed) The URL to the issue label + +## Import + +GitHub Issue Labels can be imported using an ID made up of `repository:name`, e.g. + +```sh +$ terraform import github_issue_label.panic_label terraform:panic +``` diff --git a/docs/resources/issue_labels.md b/docs/resources/issue_labels.md new file mode 100644 index 0000000000..946d67fd11 --- /dev/null +++ b/docs/resources/issue_labels.md @@ -0,0 +1,60 @@ +--- +page_title: "github_issue_labels Resource - terraform-provider-github +description: |- + Provides GitHub issue labels resource. +--- + +# github_issue_labels (Resource) + +Provides GitHub issue labels resource. + +This resource allows you to create and manage issue labels within your GitHub organization. + +~> Note: github_issue_labels cannot be used in conjunction with github_issue_label or they will fight over what your policy should be. + +This resource is authoritative. For adding a label to a repo in a non-authoritative manner, use github_issue_label instead. + +If you change the case of a label's name, its' color, or description, this resource will edit the existing label to match the new values. However, if you change the name of a label, this resource will create a new label with the new name and delete the old label. Beware that this will remove the label from any issues it was previously attached to. + +~> **Note:** When a repository is archived, Terraform will skip deletion of issue labels to avoid API errors, as archived repositories are read-only. The labels will be removed from Terraform state without attempting to delete them from GitHub. + +## Example Usage + +```terraform +# Create a new, red colored label +resource "github_issue_labels" "test_repo" { + repository = "test-repo" + + label { + name = "Urgent" + color = "FF0000" + } + + label { + name = "Critical" + color = "FF0000" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The GitHub repository + +- `name` - (Required) The name of the label. + +- `color` - (Required) A 6 character hex code, **without the leading #**, identifying the color of the label. + +- `description` - (Optional) A short description of the label. + +- `url` - (Computed) The URL to the issue label + +## Import + +GitHub Issue Labels can be imported using the repository `name`, e.g. + +```sh +$ terraform import github_issue_labels.test_repo test_repo +``` diff --git a/docs/resources/membership.md b/docs/resources/membership.md new file mode 100644 index 0000000000..0b0dee9ae7 --- /dev/null +++ b/docs/resources/membership.md @@ -0,0 +1,37 @@ +--- +page_title: "github_membership Resource - terraform-provider-github +description: |- + Provides a GitHub membership resource. +--- + +# github_membership (Resource) + +Provides a GitHub membership resource. + +This resource allows you to add/remove users from your organization. When applied, an invitation will be sent to the user to become part of the organization. When destroyed, either the invitation will be cancelled or the user will be removed. + +## Example Usage + +```terraform +# Add a user to the organization +resource "github_membership" "membership_for_some_user" { + username = "SomeUser" + role = "member" +} +``` + +## Argument Reference + +The following arguments are supported: + +- `username` - (Required) The user to add to the organization. +- `role` - (Optional) The role of the user within the organization. Must be one of `member` or `admin`. Defaults to `member`. `admin` role represents the `owner` role available via GitHub UI. +- `downgrade_on_destroy` - (Optional) Defaults to `false`. If set to true, when this resource is destroyed, the member will not be removed from the organization. Instead, the member's role will be downgraded to 'member'. + +## Import + +GitHub Membership can be imported using an ID made up of `organization:username`, e.g. + +```sh +$ terraform import github_membership.member hashicorp:someuser +``` diff --git a/docs/resources/organization_block.md b/docs/resources/organization_block.md new file mode 100644 index 0000000000..89c0fab0b6 --- /dev/null +++ b/docs/resources/organization_block.md @@ -0,0 +1,31 @@ +--- +page_title: "github_organization_block Resource - terraform-provider-github +description: |- + Creates and manages blocks for GitHub organizations +--- + +# github_organization_block (Resource) + +This resource allows you to create and manage blocks for GitHub organizations. + +## Example Usage + +```terraform +resource "github_organization_block" "example" { + username = "paultyng" +} +``` + +## Argument Reference + +The following arguments are supported: + +- `username` - (Required) The name of the user to block. + +## Import + +GitHub organization block can be imported using a username, e.g. + +```sh +$ terraform import github_github_organization_block.example someuser +``` diff --git a/docs/resources/organization_custom_properties.md b/docs/resources/organization_custom_properties.md new file mode 100644 index 0000000000..e4be52361e --- /dev/null +++ b/docs/resources/organization_custom_properties.md @@ -0,0 +1,97 @@ +--- +page_title: "github_organization_custom_properties Resource - terraform-provider-github +description: |- + Creates and manages custom properties for a GitHub organization +--- + +# github_organization_custom_properties (Resource) + +This resource allows you to create and manage custom properties for a GitHub organization. + +Custom properties enable you to add metadata to repositories within your organization. You can use custom properties to add context about repositories, such as who owns them, when they expire, or compliance requirements. + +## Example Usage + +```terraform +resource "github_organization_custom_properties" "environment" { + property_name = "environment" + value_type = "single_select" + required = true + description = "The deployment environment for this repository" + default_value = "development" + allowed_values = [ + "development", + "staging", + "production" + ] +} +``` + +## Example Usage - Allow Repository Actors to Edit + +This example shows how to allow repository administrators to edit the property values: + +```terraform +resource "github_organization_custom_properties" "team_contact" { + property_name = "team_contact" + value_type = "string" + required = false + description = "Contact information for the team managing this repository" + values_editable_by = "org_and_repo_actors" +} +``` + +## Example Usage - Text Property + +```terraform +resource "github_organization_custom_properties" "owner" { + property_name = "owner" + value_type = "string" + required = true + description = "The team or individual responsible for this repository" +} +``` + +## Example Usage - Boolean Property + +```terraform +resource "github_organization_custom_properties" "archived" { + property_name = "archived" + value_type = "true_false" + required = false + description = "Whether this repository is archived" + default_value = "false" +} +``` + +## Argument Reference + +The following arguments are supported: + +- `property_name` - (Required) The name of the custom property. + +- `value_type` - (Optional) The type of the custom property. Can be one of `string`, `single_select`, `multi_select`, or `true_false`. Defaults to `string`. + +- `required` - (Optional) Whether the custom property is required. Defaults to `false`. + +- `description` - (Optional) The description of the custom property. + +- `default_value` - (Optional) The default value of the custom property. + +- `allowed_values` - (Optional) List of allowed values for the custom property. Only applicable when `value_type` is `single_select` or `multi_select`. + +- `values_editable_by` - (Optional) Who can edit the values of the custom property. Can be one of `org_actors` or `org_and_repo_actors`. When set to `org_actors` (the default), only organization owners can edit the property values on repositories. When set to `org_and_repo_actors`, both organization owners and repository administrators with the custom properties permission can edit the values. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +- `property_name` - The name of the custom property. + +## Import + +Organization custom properties can be imported using the property name: + +```sh +terraform import github_organization_custom_properties.environment environment +``` diff --git a/docs/resources/organization_custom_role.md b/docs/resources/organization_custom_role.md new file mode 100644 index 0000000000..35a58b7dec --- /dev/null +++ b/docs/resources/organization_custom_role.md @@ -0,0 +1,67 @@ +--- +page_title: "github_organization_custom_role Resource - terraform-provider-github +description: |- + Creates and manages a custom role in a GitHub Organization for use in repositories. +--- + +# github_organization_custom_role (Resource) + +~> **Note:** This resource is deprecated, please use the `github_organization_repository_role` resource instead. + +This resource allows you to create and manage custom roles in a GitHub Organization for use in repositories. + +~> Note: Custom roles are currently only available in GitHub Enterprise Cloud. + +## Example Usage + +```terraform +resource "github_organization_custom_role" "example" { + name = "example" + description = "Example custom role that uses the read role as its base" + base_role = "read" + permissions = [ + "add_assignee", + "add_label", + "bypass_branch_protection", + "close_issue", + "close_pull_request", + "mark_as_duplicate", + "create_tag", + "delete_issue", + "delete_tag", + "manage_deploy_keys", + "push_protected_branch", + "read_code_scanning", + "reopen_issue", + "reopen_pull_request", + "request_pr_review", + "resolve_dependabot_alerts", + "resolve_secret_scanning_alerts", + "view_secret_scanning_alerts", + "write_code_scanning" + ] +} +``` + +## Argument Reference + +The following arguments are supported: + +- `name` - (Required) The name of the custom role. +- `description` - (Optional) The description for the custom role. +- `base_role` - (Required) The system role from which the role inherits permissions. Can be one of: `read`, `triage`, `write`, or `maintain`. +- `permissions` - (Required) A list of additional permissions included in this role. Must have a minimum of 1 additional permission. The list of available permissions can be found using the [list repository fine-grained permissions for an organization](https://docs.github.com/en/enterprise-cloud@latest/rest/orgs/custom-roles?apiVersion=2022-11-28#list-repository-fine-grained-permissions-for-an-organization) API. + +## Attributes Reference + +The following additional attributes are exported: + +- `id` - The ID of the custom role. + +## Import + +Custom roles can be imported using the `id` of the role. The `id` of the custom role can be found using the [list custom roles in an organization](https://docs.github.com/en/enterprise-cloud@latest/rest/orgs/custom-roles#list-custom-repository-roles-in-an-organization) API. + +```sh +$ terraform import github_organization_custom_role.example 1234 +``` diff --git a/docs/resources/organization_repository_role.md b/docs/resources/organization_repository_role.md new file mode 100644 index 0000000000..3d97658338 --- /dev/null +++ b/docs/resources/organization_repository_role.md @@ -0,0 +1,49 @@ +--- +page_title: "github_organization_repository_role Resource - terraform-provider-github +description: |- + Manage a custom organization repository role. +--- + +# github_organization_repository_role (Resource) + +Manage a custom organization repository role. + +~> **Note**: Custom organization repository roles are currently only available in GitHub Enterprise Cloud. + +## Example Usage + +```terraform +resource "github_organization_repository_role" "example" { + name = "example" + base_role = "read" + + permissions = [ + "add_assignee", + "add_label" + ] +} +``` + +## Schema + +### Required + +- `name` (String) The name of the organization repository role. +- `base_role` (String) The system role from which this role inherits permissions. +- `permissions` (Set of String, Min: 1) The permissions included in this role. + +### Optional + +- `description` (String) The description of the organization repository role. + +### Read-Only + +- `role_id` (Number) The ID of the organization repository role. + +## Import + +A custom organization repository role can be imported using its ID. + +```shell +terraform import github_organization_repository_role.example 1234 +``` diff --git a/docs/resources/organization_role.md b/docs/resources/organization_role.md new file mode 100644 index 0000000000..7fa73a674e --- /dev/null +++ b/docs/resources/organization_role.md @@ -0,0 +1,49 @@ +--- +page_title: "github_organization_role Resource - terraform-provider-github +description: |- + Manage a custom organization role. +--- + +# github_organization_role (Resource) + +Manage a custom organization role. + +~> **Note**: Custom organization roles are currently only available in GitHub Enterprise Cloud. + +## Example Usage + +```terraform +resource "github_organization_role" "example" { + name = "example" + base_role = "read" + + permissions = [ + "read_organization_custom_org_role", + "read_organization_custom_repo_role" + ] +} +``` + +## Schema + +### Required + +- `name` (String) The name of the organization role. +- `permissions` (Set of String, Min: 1) The permissions included in this role. + +### Optional + +- `description` (String) The description of the organization role. +- `base_role` (String) The system role from which this role inherits permissions. + +### Read-Only + +- `role_id` (Number) The ID of the organization role. + +## Import + +A custom organization role can be imported using its ID. + +```shell +terraform import github_organization_role.example 1234 +``` diff --git a/docs/resources/organization_role_team.md b/docs/resources/organization_role_team.md new file mode 100644 index 0000000000..088e81b898 --- /dev/null +++ b/docs/resources/organization_role_team.md @@ -0,0 +1,33 @@ +--- +page_title: "github_organization_role_team Resource - terraform-provider-github +description: |- + Manage an association between an organization role and a team. +--- + +# github_organization_role_team (Resource) + +Manage an association between an organization role and a team. + +## Example Usage + +```terraform +resource "github_organization_role_team" "example" { + role_id = 1234 + team_slug = "example-team" +} +``` + +## Schema + +### Required + +- `role_id` (Number) The ID of the organization role. +- `team_slug` (String) The slug of the team name. + +## Import + +An organization role team association can be imported using the role ID and the team slug separated by a `:`. + +```shell +terraform import github_organization_role_team.example "1234:example-team" +``` diff --git a/docs/resources/organization_role_team_assignment.md b/docs/resources/organization_role_team_assignment.md new file mode 100644 index 0000000000..6a4c5f8094 --- /dev/null +++ b/docs/resources/organization_role_team_assignment.md @@ -0,0 +1,43 @@ +--- +page_title: "github_organization_role_team_assignment Resource - terraform-provider-github +description: |- + Manages the associations between teams and organization roles. +--- + +# github_organization_role_team_assignment (Resource) + +~> **Note:** This resource is deprecated, please use the `github_organization_role_team` resource instead. + +This resource manages relationships between teams and organization roles in your GitHub organization. This works on predefined roles, and custom roles, where the latter is an Enterprise feature. + +Creating this resource assigns the role to a team. + +The organization role and team must both belong to the same organization on GitHub. + +## Example Usage + +```terraform +resource "github_team" "test-team" { + name = "test-team" +} + +resource "github_organization_role_team_assignment" "test-team-role-assignment" { + team_slug = github_team.test-team.slug + role_id = "8132" # all_repo_read (predefined) +} +``` + +## Argument Reference + +The following arguments are supported: + +- `team_slug` - (Required) The GitHub team slug +- `role_id` - (Required) The GitHub organization role id + +## Import + +GitHub Team Organization Role Assignment can be imported using an ID made up of `team_slug:role_id` + +```sh +$ terraform import github_organization_role_team_assignment.role_assignment test-team:8132 +``` diff --git a/docs/resources/organization_role_user.md b/docs/resources/organization_role_user.md new file mode 100644 index 0000000000..0ce013e1ab --- /dev/null +++ b/docs/resources/organization_role_user.md @@ -0,0 +1,33 @@ +--- +page_title: "github_organization_role_user Resource - terraform-provider-github +description: |- + Manage an association between an organization role and a user. +--- + +# github_organization_role_user (Resource) + +Manage an association between an organization role and a user. + +## Example Usage + +```terraform +resource "github_organization_role_user" "example" { + role_id = 1234 + login = "example-user" +} +``` + +## Schema + +### Required + +- `role_id` (Number) The ID of the organization role. +- `login` (String) The login for the GitHub user account. + +## Import + +An organization role user association can be imported using the role ID and the user login separated by a `:`. + +```shell +terraform import github_organization_role_team.example "1234:example-user" +``` diff --git a/docs/resources/organization_ruleset.md b/docs/resources/organization_ruleset.md new file mode 100644 index 0000000000..081ee278c3 --- /dev/null +++ b/docs/resources/organization_ruleset.md @@ -0,0 +1,385 @@ +--- +page_title: "github_organization_ruleset Resource - terraform-provider-github" +description: |- + Creates a GitHub organization ruleset. + This resource allows you to create and manage rulesets on the organization level. When applied, a new ruleset will be created. When destroyed, that ruleset will be removed. +--- + +# github_organization_ruleset (Resource) + +Creates a GitHub organization ruleset. + +This resource allows you to create and manage rulesets on the organization level. When applied, a new ruleset will be created. When destroyed, that ruleset will be removed. + +## Example Usage + +```terraform +resource "github_organization_ruleset" "example" { + name = "example" + target = "branch" + enforcement = "active" + + conditions { + ref_name { + include = ["~ALL"] + exclude = [] + } + } + + bypass_actors { + actor_id = 13473 + actor_type = "Integration" + bypass_mode = "always" + } + + rules { + creation = true + update = true + deletion = true + required_linear_history = true + required_signatures = true + + branch_name_pattern { + name = "example" + negate = false + operator = "starts_with" + pattern = "ex" + } + + required_workflows { + do_not_enforce_on_create = true + required_workflow { + repository_id = 1234 + path = ".github/workflows/ci.yml" + ref = "main" + } + } + + required_code_scanning { + required_code_scanning_tool { + alerts_threshold = "errors" + security_alerts_threshold = "high_or_higher" + tool = "CodeQL" + } + } + } +} + +# Example with push ruleset +resource "github_organization_ruleset" "example_push" { + name = "example_push" + target = "push" + enforcement = "active" + + conditions { + ref_name { + include = ["~ALL"] + exclude = [] + } + repository_name { + include = ["~ALL"] + exclude = [] + } + } + + rules { + file_path_restriction { + restricted_file_paths = [".github/workflows/*", "*.env"] + } + + max_file_size { + max_file_size = 100 # 100 MB + } + + max_file_path_length { + max_file_path_length = 255 + } + + file_extension_restriction { + restricted_file_extensions = ["*.exe", "*.dll", "*.so"] + } + } +} +``` + + +## Schema + +### Required + +- `enforcement` (String) Possible values for Enforcement are `disabled`, `active`, `evaluate`. Note: `evaluate` is currently only supported for owners of type `organization`. +- `name` (String) The name of the ruleset. +- `rules` (Block List, Min: 1, Max: 1) Rules within the ruleset. (see [below for nested schema](#nestedblock--rules)) +- `target` (String) Possible values are `branch`, `tag` and `push`. Note: The `push` target is in beta and is subject to change. + +### Optional + +- `bypass_actors` (Block List) The actors that can bypass the rules in this ruleset. (see [below for nested schema](#nestedblock--bypass_actors)) +- `conditions` (Block List, Max: 1) Parameters for an organization ruleset condition. `ref_name` is required alongside one of `repository_name` or `repository_id`. (see [below for nested schema](#nestedblock--conditions)) + +### Read-Only + +- `etag` (String) The ETag of the ruleset. +- `id` (String) The ID of this resource. +- `node_id` (String) GraphQL global node id for use with v4 API. +- `ruleset_id` (Number) GitHub ID for the ruleset. + + +### Nested Schema for `rules` + +Optional: + +- `branch_name_pattern` (Block List, Max: 1) Parameters to be used for the branch_name_pattern rule. This rule only applies to repositories within an enterprise, it cannot be applied to repositories owned by individuals or regular organizations. Conflicts with `tag_name_pattern` as it only applies to rulesets with target `branch`. (see [below for nested schema](#nestedblock--rules--branch_name_pattern)) +- `commit_author_email_pattern` (Block List, Max: 1) Parameters to be used for the commit_author_email_pattern rule. (see [below for nested schema](#nestedblock--rules--commit_author_email_pattern)) +- `commit_message_pattern` (Block List, Max: 1) Parameters to be used for the commit_message_pattern rule. (see [below for nested schema](#nestedblock--rules--commit_message_pattern)) +- `committer_email_pattern` (Block List, Max: 1) Parameters to be used for the committer_email_pattern rule. (see [below for nested schema](#nestedblock--rules--committer_email_pattern)) +- `creation` (Boolean) Only allow users with bypass permission to create matching refs. +- `deletion` (Boolean) Only allow users with bypass permissions to delete matching refs. +- `file_extension_restriction` (Block List, Max: 1) Prevent pushes based on file extensions. (see [below for nested schema](#nestedblock--rules--file_extension_restriction)) +- `file_path_restriction` (Block List, Max: 1) Prevent commits that include changes in specified file paths from being pushed to the commit graph. (see [below for nested schema](#nestedblock--rules--file_path_restriction)) +- `max_file_path_length` (Block List, Max: 1) Prevent pushes based on file path length. (see [below for nested schema](#nestedblock--rules--max_file_path_length)) +- `max_file_size` (Block List, Max: 1) Prevent pushes based on file size. (see [below for nested schema](#nestedblock--rules--max_file_size)) +- `non_fast_forward` (Boolean) Prevent users with push access from force pushing to branches. +- `pull_request` (Block List, Max: 1) Require all commits be made to a non-target branch and submitted via a pull request before they can be merged. (see [below for nested schema](#nestedblock--rules--pull_request)) +- `required_code_scanning` (Block List, Max: 1) Choose which tools must provide code scanning results before the reference is updated. When configured, code scanning must be enabled and have results for both the commit and the reference being updated. (see [below for nested schema](#nestedblock--rules--required_code_scanning)) +- `required_linear_history` (Boolean) Prevent merge commits from being pushed to matching branches. +- `required_signatures` (Boolean) Commits pushed to matching branches must have verified signatures. +- `required_status_checks` (Block List, Max: 1) Choose which status checks must pass before branches can be merged into a branch that matches this rule. When enabled, commits must first be pushed to another branch, then merged or pushed directly to a branch that matches this rule after status checks have passed. (see [below for nested schema](#nestedblock--rules--required_status_checks)) +- `required_workflows` (Block List, Max: 1) Choose which Actions workflows must pass before branches can be merged into a branch that matches this rule. (see [below for nested schema](#nestedblock--rules--required_workflows)) +- `tag_name_pattern` (Block List, Max: 1) Parameters to be used for the tag_name_pattern rule. This rule only applies to repositories within an enterprise, it cannot be applied to repositories owned by individuals or regular organizations. Conflicts with `branch_name_pattern` as it only applies to rulesets with target `tag`. (see [below for nested schema](#nestedblock--rules--tag_name_pattern)) +- `update` (Boolean) Only allow users with bypass permission to update matching refs. + + +### Nested Schema for `rules.branch_name_pattern` + +Required: + +- `operator` (String) The operator to use for matching. Can be one of: `starts_with`, `ends_with`, `contains`, `regex`. +- `pattern` (String) The pattern to match with. + +Optional: + +- `name` (String) How this rule will appear to users. +- `negate` (Boolean) If true, the rule will fail if the pattern matches. + + + +### Nested Schema for `rules.commit_author_email_pattern` + +Required: + +- `operator` (String) The operator to use for matching. Can be one of: `starts_with`, `ends_with`, `contains`, `regex`. +- `pattern` (String) The pattern to match with. + +Optional: + +- `name` (String) How this rule will appear to users. +- `negate` (Boolean) If true, the rule will fail if the pattern matches. + + + +### Nested Schema for `rules.commit_message_pattern` + +Required: + +- `operator` (String) The operator to use for matching. Can be one of: `starts_with`, `ends_with`, `contains`, `regex`. +- `pattern` (String) The pattern to match with. + +Optional: + +- `name` (String) How this rule will appear to users. +- `negate` (Boolean) If true, the rule will fail if the pattern matches. + + + +### Nested Schema for `rules.committer_email_pattern` + +Required: + +- `operator` (String) The operator to use for matching. Can be one of: `starts_with`, `ends_with`, `contains`, `regex`. +- `pattern` (String) The pattern to match with. + +Optional: + +- `name` (String) How this rule will appear to users. +- `negate` (Boolean) If true, the rule will fail if the pattern matches. + + + +### Nested Schema for `rules.file_extension_restriction` + +Required: + +- `restricted_file_extensions` (Set of String) The file extensions that are restricted from being pushed to the commit graph. + + + +### Nested Schema for `rules.file_path_restriction` + +Required: + +- `restricted_file_paths` (List of String) The file paths that are restricted from being pushed to the commit graph. + + + +### Nested Schema for `rules.max_file_path_length` + +Required: + +- `max_file_path_length` (Number) The maximum allowed length of a file path. + + + +### Nested Schema for `rules.max_file_size` + +Required: + +- `max_file_size` (Number) The maximum allowed size of a file in megabytes (MB). Valid range is 1-100 MB. + + + +### Nested Schema for `rules.pull_request` + +Optional: + +- `dismiss_stale_reviews_on_push` (Boolean) New, reviewable commits pushed will dismiss previous pull request review approvals. Defaults to `false`. +- `require_code_owner_review` (Boolean) Require an approving review in pull requests that modify files that have a designated code owner. Defaults to `false`. +- `require_last_push_approval` (Boolean) Whether the most recent reviewable push must be approved by someone other than the person who pushed it. Defaults to `false`. +- `required_approving_review_count` (Number) The number of approving reviews that are required before a pull request can be merged. Defaults to `0`. +- `required_review_thread_resolution` (Boolean) All conversations on code must be resolved before a pull request can be merged. Defaults to `false`. + + + +### Nested Schema for `rules.required_code_scanning` + +Required: + +- `required_code_scanning_tool` (Block Set, Min: 1) Tools that must provide code scanning results for this rule to pass. (see [below for nested schema](#nestedblock--rules--required_code_scanning--required_code_scanning_tool)) + + +### Nested Schema for `rules.required_code_scanning.required_code_scanning_tool` + +Required: + +- `alerts_threshold` (String) The severity level at which code scanning results that raise alerts block a reference update. Can be one of: `none`, `errors`, `errors_and_warnings`, `all`. +- `security_alerts_threshold` (String) The severity level at which code scanning results that raise security alerts block a reference update. Can be one of: `none`, `critical`, `high_or_higher`, `medium_or_higher`, `all`. +- `tool` (String) The name of a code scanning tool. + + + + +### Nested Schema for `rules.required_status_checks` + +Required: + +- `required_check` (Block Set, Min: 1) Status checks that are required. Several can be defined. (see [below for nested schema](#nestedblock--rules--required_status_checks--required_check)) + +Optional: + +- `do_not_enforce_on_create` (Boolean) Allow repositories and branches to be created if a check would otherwise prohibit it. +- `strict_required_status_checks_policy` (Boolean) Whether pull requests targeting a matching branch must be tested with the latest code. This setting will not take effect unless at least one status check is enabled. Defaults to `false`. + + +### Nested Schema for `rules.required_status_checks.required_check` + +Required: + +- `context` (String) The status check context name that must be present on the commit. + +Optional: + +- `integration_id` (Number) The optional integration ID that this status check must originate from. + + + + +### Nested Schema for `rules.required_workflows` + +Required: + +- `required_workflow` (Block Set, Min: 1) Actions workflows that are required. Several can be defined. (see [below for nested schema](#nestedblock--rules--required_workflows--required_workflow)) + +Optional: + +- `do_not_enforce_on_create` (Boolean) Allow repositories and branches to be created if a check would otherwise prohibit it. + + +### Nested Schema for `rules.required_workflows.required_workflow` + +Required: + +- `path` (String) The path to the workflow YAML definition file. +- `repository_id` (Number) The repository in which the workflow is defined. + +Optional: + +- `ref` (String) The ref (branch or tag) of the workflow file to use. + + + + +### Nested Schema for `rules.tag_name_pattern` + +Required: + +- `operator` (String) The operator to use for matching. Can be one of: `starts_with`, `ends_with`, `contains`, `regex`. +- `pattern` (String) The pattern to match with. + +Optional: + +- `name` (String) How this rule will appear to users. +- `negate` (Boolean) If true, the rule will fail if the pattern matches. + + + + +### Nested Schema for `bypass_actors` + +Required: + +- `actor_type` (String) The type of actor that can bypass a ruleset. See [GitHub Documentation](https://docs.github.com/en/rest/orgs/rules) for more information +- `bypass_mode` (String) When the specified actor can bypass the ruleset. pull_request means that an actor can only bypass rules on pull requests. Can be one of: `always`, `pull_request`, `exempt`. + +Optional: + +- `actor_id` (Number) The ID of the actor that can bypass a ruleset. When `actor_type` is `OrganizationAdmin`, this should be set to `1`. Some resources such as DeployKey do not have an ID and this should be omitted. + + + +### Nested Schema for `conditions` + +Required: + +- `ref_name` (Block List, Min: 1, Max: 1) (see [below for nested schema](#nestedblock--conditions--ref_name)) + +Optional: + +- `repository_id` (List of Number) The repository IDs that the ruleset applies to. One of these IDs must match for the condition to pass. +- `repository_name` (Block List, Max: 1) (see [below for nested schema](#nestedblock--conditions--repository_name)) + + +### Nested Schema for `conditions.ref_name` + +Required: + +- `exclude` (List of String) Array of ref names or patterns to exclude. The condition will not pass if any of these patterns match. +- `include` (List of String) Array of ref names or patterns to include. One of these patterns must match for the condition to pass. Also accepts `~DEFAULT_BRANCH` to include the default branch or `~ALL` to include all branches. + + + +### Nested Schema for `conditions.repository_name` + +Required: + +- `exclude` (List of String) Array of repository names or patterns to exclude. The condition will not pass if any of these patterns match. +- `include` (List of String) Array of repository names or patterns to include. One of these patterns must match for the condition to pass. Also accepts `~ALL` to include all repositories. + +Optional: + +- `protected` (Boolean) Whether renaming of target repositories is prevented. + +## Import + +GitHub Organization Rulesets can be imported using the GitHub ruleset ID e.g. + +`$ terraform import github_organization_ruleset.example 12345` diff --git a/docs/resources/organization_security_manager.md b/docs/resources/organization_security_manager.md new file mode 100644 index 0000000000..4c7d0f2ed9 --- /dev/null +++ b/docs/resources/organization_security_manager.md @@ -0,0 +1,36 @@ +--- +page_title: "github_organization_security_manager Resource - terraform-provider-github +description: |- + Manages the Security manager teams for a GitHub Organization. +--- + +# github_organization_security_manager (Resource) + +~> **Note:** This resource is deprecated, please use the `github_organization_role_team` resource instead. + +## Example Usage + +```terraform +resource "github_team" "some_team" { + name = "SomeTeam" + description = "Some cool team" +} + +resource "github_organization_security_manager" "some_team" { + team_slug = github_team.some_team.slug +} +``` + +## Argument Reference + +The following arguments are supported: + +- `team_slug` - (Required) The slug of the team to manage. + +## Import + +GitHub Security Manager Teams can be imported using the GitHub team ID e.g. + +```sh +$ terraform import github_organization_security_manager.core 1234567 +``` diff --git a/docs/resources/organization_settings.md b/docs/resources/organization_settings.md new file mode 100644 index 0000000000..aefffc4a03 --- /dev/null +++ b/docs/resources/organization_settings.md @@ -0,0 +1,87 @@ +--- +page_title: "github_organization_settings Resource - terraform-provider-github +description: |- + Creates and manages settings for a GitHub Organization. +--- + +# github_organization_settings (Resource) + +This resource allows you to create and manage settings for a GitHub Organization. + +## Example Usage + +```terraform +resource "github_organization_settings" "test" { + billing_email = "test@example.com" + company = "Test Company" + blog = "https://example.com" + email = "test@example.com" + twitter_username = "Test" + location = "Test Location" + name = "Test Name" + description = "Test Description" + has_organization_projects = true + has_repository_projects = true + default_repository_permission = "read" + members_can_create_repositories = true + members_can_create_public_repositories = true + members_can_create_private_repositories = true + members_can_create_internal_repositories = true + members_can_create_pages = true + members_can_create_public_pages = true + members_can_create_private_pages = true + members_can_fork_private_repositories = true + web_commit_signoff_required = true + advanced_security_enabled_for_new_repositories = false + dependabot_alerts_enabled_for_new_repositories= false + dependabot_security_updates_enabled_for_new_repositories = false + dependency_graph_enabled_for_new_repositories = false + secret_scanning_enabled_for_new_repositories = false + secret_scanning_push_protection_enabled_for_new_repositories = false +} +``` + +## Argument Reference + +The following arguments are supported: + +- `billing_email` - (Required) The billing email address for the organization. +- `company` - (Optional) The company name for the organization. +- `blog` - (Optional) The blog URL for the organization. +- `email` - (Optional) The email address for the organization. +- `twitter_username` - (Optional) The Twitter username for the organization. +- `location` - (Optional) The location for the organization. +- `name` - (Optional) The name for the organization. +- `description` - (Optional) The description for the organization. +- `has_organization_projects` - (Optional) Whether or not organization projects are enabled for the organization. +- `has_repository_projects` - (Optional) Whether or not repository projects are enabled for the organization. +- `default_repository_permission` - (Optional) The default permission for organization members to create new repositories. Can be one of `read`, `write`, `admin`, or `none`. Defaults to `read`. +- `members_can_create_repositories` - (Optional) Whether or not organization members can create new repositories. Defaults to `true`. +- `members_can_create_public_repositories` - (Optional) Whether or not organization members can create new public repositories. Defaults to `true`. +- `members_can_create_private_repositories` - (Optional) Whether or not organization members can create new private repositories. Defaults to `true`. +- `members_can_create_internal_repositories` - (Optional) Whether or not organization members can create new internal repositories. For Enterprise Organizations only. +- `members_can_create_pages` - (Optional) Whether or not organization members can create new pages. Defaults to `true`. +- `members_can_create_public_pages` - (Optional) Whether or not organization members can create new public pages. Defaults to `true`. +- `members_can_create_private_pages` - (Optional) Whether or not organization members can create new private pages. Defaults to `true`. +- `members_can_fork_private_repositories` - (Optional) Whether or not organization members can fork private repositories. Defaults to `false`. +- `web_commit_signoff_required` - (Optional) Whether or not commit signatures are required for commits to the organization. Defaults to `false`. +- `advanced_security_enabled_for_new_repositories` - (Optional) Whether or not advanced security is enabled for new repositories. Defaults to `false`. +- `dependabot_alerts_enabled_for_new_repositories` - (Optional) Whether or not dependabot alerts are enabled for new repositories. Defaults to `false`. +- `dependabot_security_updates_enabled_for_new_repositories` - (Optional) Whether or not dependabot security updates are enabled for new repositories. Defaults to `false`. +- `dependency_graph_enabled_for_new_repositories` - (Optional) Whether or not dependency graph is enabled for new repositories. Defaults to `false`. +- `secret_scanning_enabled_for_new_repositories` - (Optional) Whether or not secret scanning is enabled for new repositories. Defaults to `false`. +- `secret_scanning_push_protection_enabled_for_new_repositories` - (Optional) Whether or not secret scanning push protection is enabled for new repositories. Defaults to `false`. + +## Attributes Reference + +The following additional attributes are exported: + +- `id` - The ID of the organization settings. + +## Import + +Organization settings can be imported using the `id` of the organization. The `id` of the organization can be found using the [get an organization](https://docs.github.com/en/rest/orgs/orgs#get-an-organization) API. + +```sh +$ terraform import github_organization_settings.test 123456789 +``` diff --git a/docs/resources/organization_webhook.md b/docs/resources/organization_webhook.md new file mode 100644 index 0000000000..59e3ae58df --- /dev/null +++ b/docs/resources/organization_webhook.md @@ -0,0 +1,55 @@ +--- +page_title: "github_organization_webhook Resource - terraform-provider-github +description: |- + Creates and manages webhooks for GitHub organizations +--- + +# github_organization_webhook (Resource) + +This resource allows you to create and manage webhooks for GitHub organization. + +## Example Usage + +```terraform +resource "github_organization_webhook" "foo" { + name = "web" + + configuration { + url = "https://google.de/" + content_type = "form" + insecure_ssl = false + } + + active = false + + events = ["issues"] +} +``` + +## Argument Reference + +The following arguments are supported: + +- `events` - (Required) A list of events which should trigger the webhook. See a list of [available events](https://developer.github.com/v3/activity/events/types/) + +- `configuration` - (Required) key/value pair of configuration for this webhook. Available keys are `url`, `content_type`, `secret` and `insecure_ssl`. + +- `active` - (Optional) Indicate of the webhook should receive events. Defaults to `true`. + +- `name` - (Optional) The type of the webhook. `web` is the default and the only option. + +## Attributes Reference + +The following additional attributes are exported: + +- `url` - URL of the webhook + +## Import + +Organization webhooks can be imported using the `id` of the webhook. The `id` of the webhook can be found in the URL of the webhook. For example, `"https://github.com/organizations/foo-org/settings/hooks/123456789"`. + +```sh +$ terraform import github_organization_webhook.terraform 123456789 +``` + +If secret is populated in the webhook's configuration, the value will be imported as "********". diff --git a/docs/resources/release.md b/docs/resources/release.md new file mode 100644 index 0000000000..2f4ac96997 --- /dev/null +++ b/docs/resources/release.md @@ -0,0 +1,102 @@ +--- +page_title: "github_release Resource - terraform-provider-github +description: |- + Creates and manages releases within a single GitHub repository +--- + +# github_release (Resource) + +This resource allows you to create and manage a release in a specific GitHub repository. + +## Example Usage + +```terraform +resource "github_repository" "repo" { + name = "repo" + description = "GitHub repo managed by Terraform" + + private = false +} + +resource "github_release" "example" { + repository = github_repository.repo.name + tag_name = "v1.0.0" +} +``` + +## Example Usage on Non-Default Branch + +```terraform +resource "github_repository" "example" { + name = "repo" + auto_init = true +} + +resource "github_branch" "example" { + repository = github_repository.example.name + branch = "branch_name" + source_branch = github_repository.example.default_branch +} + +resource "github_release" "example" { + repository = github_repository.example.name + tag_name = "v1.0.0" + target_commitish = github_branch.example.branch + draft = false + prerelease = false +} +``` + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The name of the repository. + +- `tag_name` - (Required) The name of the tag. + +- `target_commitish` - (Optional) The branch name or commit SHA the tag is created from. Defaults to the default branch of the repository. + +- `name` - (Optional) The name of the release. + +- `body` - (Optional) Text describing the contents of the tag. + +- `draft` - (Optional) Set to `false` to create a published release. + +- `prerelease` - (Optional) Set to `false` to identify the release as a full release. + +- `generate_release_notes` - (Optional) Set to `true` to automatically generate the name and body for this release. If `name` is specified, the specified `name` will be used; otherwise, a name will be automatically generated. If `body` is specified, the `body` will be pre-pended to the automatically generated notes. + +- `discussion_category_name` - (Optional) If specified, a discussion of the specified category is created and linked to the release. The value must be a category that already exists in the repository. For more information, see [Managing categories for discussions in your repository](https://docs.github.com/discussions/managing-discussions-for-your-community/managing-categories-for-discussions-in-your-repository). + +## Attributes Reference + +The following additional attributes are exported: + +- `release_id` - The ID of the release. + +- `created_at` - This is the date of the commit used for the release, and not the date when the release was drafted or published. + +- `published_at` - This is the date when the release was published. This will be empty if the release is a draft. + +- `html_url` - URL of the release in GitHub. + +- `url` - URL that can be provided to API calls that reference this release. + +- `assets_url` - URL that can be provided to API calls displaying the attached assets to this release. + +- `upload_url` - URL that can be provided to API calls to upload assets. + +- `zipball_url` - URL that can be provided to API calls to fetch the release ZIP archive. + +- `tarball_url` - URL that can be provided to API calls to fetch the release TAR archive. + +- `node_id` - GraphQL global node id for use with v4 API + +## Import + +This resource can be imported using the `name` of the repository, combined with the `id` of the release, and a `:` character for separating components, e.g. + +```sh +$ terraform import github_release.example repo:12345678 +``` diff --git a/docs/resources/repository.md b/docs/resources/repository.md new file mode 100644 index 0000000000..522896e2dc --- /dev/null +++ b/docs/resources/repository.md @@ -0,0 +1,241 @@ +--- +page_title: "github_repository Resource - terraform-provider-github" +description: |- + Creates and manages repositories within GitHub organizations or personal accounts +--- + +# github_repository (Resource) + +Creates and manages repositories within GitHub organizations or personal accounts + +~> **Note** When used with GitHub App authentication, even GET requests must have the `contents:write` permission. Without it, the following arguments will be ignored, leading to unexpected behavior and confusing diffs: `allow_merge_commit`, `allow_squash_merge`, `allow_rebase_merge`, `merge_commit_title`, `merge_commit_message`, `squash_merge_commit_title` and `squash_merge_commit_message`. + +## Example Usage + +```terraform +resource "github_repository" "example" { + name = "example" + description = "My awesome codebase" + + visibility = "public" + + template { + owner = "github" + repository = "terraform-template-module" + include_all_branches = true + } +} +``` + +## Example Usage with GitHub Pages Enabled + +```terraform +resource "github_repository" "example" { + name = "example" + description = "My awesome web page" + + private = false + + pages { + source { + branch = "master" + path = "/docs" + } + } +} +``` + +## Example Usage with Repository Forking + +```terraform +resource "github_repository" "forked_repo" { + name = "forked-repository" + description = "This is a fork of another repository" + fork = true + source_owner = "some-org" + source_repo = "original-repository" +} +``` + +## Argument Reference + +The following arguments are supported: + +- `name` - (Required) The name of the repository. + +- `description` - (Optional) A description of the repository. + +- `homepage_url` - (Optional) URL of a page describing the project. + +- `fork` - (Optional) Set to `true` to create a fork of an existing repository. When set to `true`, both `source_owner` and `source_repo` must also be specified. + +- `source_owner` - (Optional) The GitHub username or organization that owns the repository being forked. Required when `fork` is `true`. + +- `source_repo` - (Optional) The name of the repository to fork. Required when `fork` is `true`. + +- `private` - (Optional) Set to `true` to create a private repository. Repositories are created as public (e.g. open source) by default. + +- `visibility` - (Optional) Can be `public` or `private`. If your organization is associated with an enterprise account using GitHub Enterprise Cloud or GitHub Enterprise Server 2.20+, visibility can also be `internal`. The `visibility` parameter overrides the `private` parameter. + +- `has_issues` - (Optional) Set to `true` to enable the GitHub Issues features on the repository. + +- `has_discussions` - (Optional) Set to `true` to enable GitHub Discussions on the repository. Defaults to `false`. + +- `has_projects` - (Optional) Set to `true` to enable the GitHub Projects features on the repository. Per the GitHub [documentation](https://developer.github.com/v3/repos/#create) when in an organization that has disabled repository projects it will default to `false` and will otherwise default to `true`. If you specify `true` when it has been disabled it will return an error. + +- `has_wiki` - (Optional) Set to `true` to enable the GitHub Wiki features on the repository. + +- `is_template` - (Optional) Set to `true` to tell GitHub that this is a template repository. + +- `allow_merge_commit` - (Optional) Set to `false` to disable merge commits on the repository. + +- `allow_squash_merge` - (Optional) Set to `false` to disable squash merges on the repository. + +- `allow_rebase_merge` - (Optional) Set to `false` to disable rebase merges on the repository. + +- `allow_auto_merge` - (Optional) Set to `true` to allow auto-merging pull requests on the repository. + +- `squash_merge_commit_title` - (Optional) Can be `PR_TITLE` or `COMMIT_OR_PR_TITLE` for a default squash merge commit title. Applicable only if `allow_squash_merge` is `true`. + +- `squash_merge_commit_message` - (Optional) Can be `PR_BODY`, `COMMIT_MESSAGES`, or `BLANK` for a default squash merge commit message. Applicable only if `allow_squash_merge` is `true`. + +- `merge_commit_title` - Can be `PR_TITLE` or `MERGE_MESSAGE` for a default merge commit title. Applicable only if `allow_merge_commit` is `true`. + +- `merge_commit_message` - Can be `PR_BODY`, `PR_TITLE`, or `BLANK` for a default merge commit message. Applicable only if `allow_merge_commit` is `true`. + +- `delete_branch_on_merge` - (Optional) Automatically delete head branch after a pull request is merged. Defaults to `false`. + +- `web_commit_signoff_required` - (Optional) Require contributors to sign off on web-based commits. See more in [GitHub Documentation](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/managing-repository-settings/managing-the-commit-signoff-policy-for-your-repository). Defaults to `false`. + +- `has_downloads` - (Optional) Set to `true` to enable the (deprecated) downloads features on the repository. + +- `auto_init` - (Optional) Set to `true` to produce an initial commit in the repository. + +- `gitignore_template` - (Optional) Use the [name of the template](https://github.com/github/gitignore) without the extension. For example, "Haskell". + +- `license_template` - (Optional) Use the [name of the template](https://github.com/github/choosealicense.com/tree/gh-pages/_licenses) without the extension. For example, "mit" or "mpl-2.0". + +- `default_branch` - (Optional) (Deprecated: Use [`github_branch_default`](../branch_default) resource instead) The name of the default branch of the repository. **NOTE:** This can only be set after a repository has already been created, and after a correct reference has been created for the target branch inside the repository. This means a user will have to omit this parameter from the initial repository creation and create the target branch inside of the repository prior to setting this attribute. + +- `archived` - (Optional) Specifies if the repository should be archived. Defaults to `false`. **NOTE** Currently, the API does not support unarchiving. + +- `archive_on_destroy` - (Optional) Set to `true` to archive the repository instead of deleting on destroy. + +- `pages` - (Optional) The repository's GitHub Pages configuration. See [GitHub Pages Configuration](#github-pages-configuration) below for details. + +- `security_and_analysis` - (Optional) The repository's [security and analysis](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-security-and-analysis-settings-for-your-repository) configuration. See [Security and Analysis Configuration](#security-and-analysis-configuration) below for details. + +- `topics` - (Optional) The list of topics of the repository. + +~> Note: This attribute is not compatible with the `github_repository_topics` resource. Use one of them. `github_repository_topics` is only meant to be used if the repository itself is not handled via terraform, for example if it's only read as a datasource (see [issue #1845](https://github.com/integrations/terraform-provider-github/issues/1845)). + +- `template` - (Optional) Use a template repository to create this resource. See [Template Repositories](#template-repositories) below for details. + +- `vulnerability_alerts` (Optional) - Set to `true` to enable security alerts for vulnerable dependencies. Enabling requires alerts to be enabled on the owner level. (Note for importing: GitHub enables the alerts on public repos but disables them on private repos by default.) See [GitHub Documentation](https://help.github.com/en/github/managing-security-vulnerabilities/about-security-alerts-for-vulnerable-dependencies) for details. Note that vulnerability alerts have not been successfully tested on any GitHub Enterprise instance and may be unavailable in those settings. + +- `ignore_vulnerability_alerts_during_read` (Optional) - Set to `true` to not call the vulnerability alerts endpoint so the resource can also be used without admin permissions during read. + +- `allow_update_branch` (Optional) - Set to `true` to always suggest updating pull request branches. + +### GitHub Pages Configuration + +The `pages` block supports the following: + +- `source` - (Optional) The source branch and directory for the rendered Pages site. See [GitHub Pages Source](#github-pages-source) below for details. + +- `build_type` - (Optional) The type of GitHub Pages site to build. Can be `legacy` or `workflow`. If you use `legacy` as build type you need to set the option `source`. + +- `cname` - (Optional) The custom domain for the repository. This can only be set after the repository has been created. + +#### GitHub Pages Source + +The `source` block supports the following: + +- `branch` - (Required) The repository branch used to publish the site's source files. (i.e. `main` or `gh-pages`. + +- `path` - (Optional) The repository directory from which the site publishes (Default: `/`). + +### Security and Analysis Configuration + +The `security_and_analysis` block supports the following: + +- `advanced_security` - (Optional) The advanced security configuration for the repository. See [Advanced Security Configuration](#advanced-security-configuration) below for details. If a repository's visibility is `public`, advanced security is always enabled and cannot be changed, so this setting cannot be supplied. + +- `code_security` - (Optional) The code security configuration for the repository. See [Code Security](#code-security-configuration) below for details. + +- `secret_scanning` - (Optional) The secret scanning configuration for the repository. See [Secret Scanning Configuration](#secret-scanning-configuration) below for details. + +- `secret_scanning_push_protection` - (Optional) The secret scanning push protection configuration for the repository. See [Secret Scanning Push Protection Configuration](#secret-scanning-push-protection-configuration) below for details. + +- `secret_scanning_ai_detection` - (Optional) The secret scanning ai detection configuration for the repository. See [Secret Scanning AI Detection](#secret-scanning-ai-detection) below for details. + +- `secret_scanning_non_provider_patterns` - (Optional) The secret scanning non-provider patterns configuration for this repository. See [Secret Scanning Non-Provider Patterns](#secret-scanning-non-provider-patterns) below for more details. + +#### Advanced Security Configuration + +The `advanced_security` block supports the following: + +- `status` - (Required) Set to `enabled` to enable advanced security features on the repository. Can be `enabled` or `disabled`. + +#### Code Security Configuration + +- `status` - (Required) Set to `enabled` to enable GitHub Code Security on the repository. Can be `enabled` or `disabled`. If set to `enabled`, the repository's visibility must be `public`, `security_and_analysis[0].advanced_security[0].status` must also be set to `enabled`, or your Organization must have split licensing for Advanced security. + +#### Secret Scanning Configuration + +- `status` - (Required) Set to `enabled` to enable secret scanning on the repository. Can be `enabled` or `disabled`. If set to `enabled`, the repository's visibility must be `public`, `security_and_analysis[0].advanced_security[0].status` must also be set to `enabled`, or your Organization must have split licensing for Advanced security. + +#### Secret Scanning Push Protection Configuration + +- `status` - (Required) Set to `enabled` to enable secret scanning push protection on the repository. Can be `enabled` or `disabled`. If set to `enabled`, the repository's visibility must be `public`, `security_and_analysis[0].advanced_security[0].status` must also be set to `enabled`, or your Organization must have split licensing for Advanced security. + +#### Secret Scanning AI Detection + +- `status` - (Required) Set to `enabled` to enable secret scanning AI detection on the repository. Can be `enabled` or `disabled`. If set to `enabled`, the repository's visibility must be `public`, `security_and_analysis[0].advanced_security[0].status` must also be set to `enabled`, or your Organization must have split licensing for Advanced security. + +#### Secret Scanning Non-Provider Patterns + +- `status` - (Required) Set to `enabled` to enable secret scanning non-provider patterns on the repository. Can be `enabled` or `disabled`. If set to `enabled`, the repository's visibility must be `public`, `security_and_analysis[0].advanced_security[0].status` must also be set to `enabled`, or your Organization must have split licensing for Advanced security. + +### Template Repositories + +`template` supports the following arguments: + +- `owner`: The GitHub organization or user the template repository is owned by. +- `repository`: The name of the template repository. +- `include_all_branches`: Whether the new repository should include all the branches from the template repository (defaults to false, which includes only the default branch from the template). + +## Attributes Reference + +The following additional attributes are exported: + +- `full_name` - A string of the form "orgname/reponame". + +- `html_url` - URL to the repository on the web. + +- `ssh_clone_url` - URL that can be provided to `git clone` to clone the repository via SSH. + +- `http_clone_url` - URL that can be provided to `git clone` to clone the repository via HTTPS. + +- `git_clone_url` - URL that can be provided to `git clone` to clone the repository anonymously via the git protocol. + +- `svn_url` - URL that can be provided to `svn checkout` to check out the repository via GitHub's Subversion protocol emulation. + +- `node_id` - GraphQL global node id for use with v4 API + +- `repo_id` - GitHub ID for the repository + +- `primary_language` - The primary language used in the repository. + +- `pages` - The block consisting of the repository's GitHub Pages configuration with the following additional attributes: +- `custom_404` - Whether the rendered GitHub Pages site has a custom 404 page. +- `html_url` - The absolute URL (including scheme) of the rendered GitHub Pages site e.g. `https://username.github.io`. +- `status` - The GitHub Pages site's build status e.g. `building` or `built`. + +## Import + +Repositories can be imported using the `name`, e.g. + +```sh +$ terraform import github_repository.terraform terraform +``` diff --git a/docs/resources/repository_autolink_reference.md b/docs/resources/repository_autolink_reference.md new file mode 100644 index 0000000000..5a018209b3 --- /dev/null +++ b/docs/resources/repository_autolink_reference.md @@ -0,0 +1,64 @@ +--- +page_title: "github_repository_autolink_reference Resource - terraform-provider-github +description: |- + Creates and manages autolink references for a single repository +--- + +# github_repository_autolink_reference (Resource) + +This resource allows you to create and manage an autolink reference for a single repository. + +## Example Usage + +```terraform +resource "github_repository" "repo" { + name = "my-repo" + description = "GitHub repo managed by Terraform" + + private = false +} + +resource "github_repository_autolink_reference" "autolink" { + repository = github_repository.repo.name + + key_prefix = "TICKET-" + + target_url_template = "https://example.com/TICKET?query=" +} +``` + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The repository of the autolink reference. + +- `key_prefix` - (Required) This prefix appended by a number will generate a link any time it is found in an issue, pull request, or commit. + +- `target_url_template` - (Required) The template of the target URL used for the links; must be a valid URL and contain `` for the reference number + +- `is_alphanumeric` - (Optional) Whether this autolink reference matches alphanumeric characters. If false, this autolink reference only matches numeric characters. Default is true. + +## Attributes Reference + +The following additional attributes are exported: + +- `etag` - An etag representing the autolink reference object. + +## Import + +Autolink references can be imported using the `name` of the repository, combined with the `id` or `key prefix` of the autolink reference and a `/` character for separating components, e.g. + +### Import by ID + +```sh +terraform import github_repository_autolink_reference.auto my-repo/123 +``` + +See the GitHub documentation for how to [list all autolinks of a repository](https://docs.github.com/en/rest/repos/autolinks#list-all-autolinks-of-a-repository) to learn the autolink ids to use with the import command. + +### Import by key prefix + +```sh +terraform import github_repository_autolink_reference.auto oof/OOF- +``` diff --git a/docs/resources/repository_collaborator.md b/docs/resources/repository_collaborator.md new file mode 100644 index 0000000000..aadf8db814 --- /dev/null +++ b/docs/resources/repository_collaborator.md @@ -0,0 +1,62 @@ +--- +page_title: "github_repository_collaborator Resource - terraform-provider-github +description: |- + Provides a GitHub repository collaborator resource. +--- + +# github_repository_collaborator (Resource) + +Provides a GitHub repository collaborator resource. + +~> Note: github_repository_collaborator cannot be used in conjunction with github_repository_collaborators or they will fight over what your policy should be. + +This resource allows you to add/remove collaborators from repositories in your organization or personal account. For organization repositories, collaborators can have explicit (and differing levels of) read, write, or administrator access to specific repositories, without giving the user full organization membership. For personal repositories, collaborators can only be granted write (implicitly includes read) permission. + +When applied, an invitation will be sent to the user to become a collaborator on a repository. When destroyed, either the invitation will be cancelled or the collaborator will be removed from the repository. + +~> **Note on Archived Repositories**: When a repository is archived, GitHub makes it read-only, preventing collaborator modifications. If you attempt to destroy resources associated with archived repositories, the provider will gracefully handle the operation by logging an informational message and removing the resource from Terraform state without attempting to modify the archived repository. + +This resource is non-authoritative, for managing ALL collaborators of a repo, use github_repository_collaborators instead. + +Further documentation on GitHub collaborators: + +- [Adding outside collaborators to your personal repositories](https://help.github.com/en/github/setting-up-and-managing-your-github-user-account/managing-access-to-your-personal-repositories) +- [Adding outside collaborators to repositories in your organization](https://help.github.com/articles/adding-outside-collaborators-to-repositories-in-your-organization/) +- [Converting an organization member to an outside collaborator](https://help.github.com/articles/converting-an-organization-member-to-an-outside-collaborator/) + +## Example Usage + +```terraform +# Add a collaborator to a repository +resource "github_repository_collaborator" "a_repo_collaborator" { + repository = "our-cool-repo" + username = "SomeUser" + permission = "admin" +} +``` + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The GitHub repository + +~> Note: The owner of the repository can be passed as part of the repository name e.g. `owner-org-name/repo-name`. If owner is not supplied as part of the repository name, it may also be supplied by setting the environment variable `GITHUB_OWNER`. + +- `username` - (Required) The user to add to the repository as a collaborator. +- `permission` - (Optional) The permission of the outside collaborator for the repository. Must be one of `pull`, `push`, `maintain`, `triage` or `admin` or the name of an existing [custom repository role](https://docs.github.com/en/enterprise-cloud@latest/organizations/managing-peoples-access-to-your-organization-with-roles/managing-custom-repository-roles-for-an-organization) within the organization for organization-owned repositories. Must be `push` for personal repositories. Defaults to `push`. +- `permission_diff_suppression` - (Optional) Suppress plan diffs for `triage` and `maintain`. Defaults to `false`. + +## Attribute Reference + +In addition to the above arguments, the following attributes are exported: + +- `invitation_id` - ID of the invitation to be used in [`github_user_invitation_accepter`](./user_invitation_accepter.html) + +## Import + +GitHub Repository Collaborators can be imported using an ID made up of `repository:username`, e.g. + +```sh +$ terraform import github_repository_collaborator.collaborator terraform:someuser +``` diff --git a/docs/resources/repository_collaborators.md b/docs/resources/repository_collaborators.md new file mode 100644 index 0000000000..32d84c05ed --- /dev/null +++ b/docs/resources/repository_collaborators.md @@ -0,0 +1,90 @@ +--- +page_title: "github_repository_collaborators Resource - terraform-provider-github +description: |- + Provides a GitHub repository collaborators resource. +--- + +# github_repository_collaborators (Resource) + +Provides a GitHub repository collaborators resource. + +~> Note: github_repository_collaborators cannot be used in conjunction with github_repository_collaborator and github_team_repository or they will fight over what your policy should be. + +This resource allows you to manage all collaborators for repositories in your organization or personal account. For organization repositories, collaborators can have explicit (and differing levels of) read, write, or administrator access to specific repositories, without giving the user full organization membership. For personal repositories, collaborators can only be granted write (implicitly includes read) permission. + +When applied, an invitation will be sent to the user to become a collaborators on a repository. When destroyed, either the invitation will be cancelled or the collaborators will be removed from the repository. + +~> **Note on Archived Repositories**: When a repository is archived, GitHub makes it read-only, preventing collaborator modifications. If you attempt to destroy resources associated with archived repositories, the provider will gracefully handle the operation by logging an informational message and removing the resource from Terraform state without attempting to modify the archived repository. + +This resource is authoritative. For adding a collaborator to a repo in a non-authoritative manner, use github_repository_collaborator instead. + +Further documentation on GitHub collaborators: + +- [Adding outside collaborators to your personal repositories](https://help.github.com/en/github/setting-up-and-managing-your-github-user-account/managing-access-to-your-personal-repositories) +- [Adding outside collaborators to repositories in your organization](https://help.github.com/articles/adding-outside-collaborators-to-repositories-in-your-organization/) +- [Converting an organization member to an outside collaborators](https://help.github.com/articles/converting-an-organization-member-to-an-outside-collaborator/) + +## Example Usage + +```terraform +# Add collaborators to a repository +resource "github_team" "some_team" { + name = "SomeTeam" + description = "Some cool team" +} + +resource "github_repository" "some_repo" { + name = "some-repo" +} + +resource "github_repository_collaborators" "some_repo_collaborators" { + repository = github_repository.some_repo.name + + user { + permission = "admin" + username = "SomeUser" + } + + team { + permission = "pull" + team_id = github_team.some_team.slug + } +} +``` + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The GitHub repository. +- `user` - (Optional) List of users to grant access to the repository. +- `team` - (Optional) List of teams to grant access to the repository. +- `ignore_team` - (Optional) List of teams to ignore when checking for repository access. This supports ignoring teams granted access at an organizational level. + +The `user` block supports: + +- `username` - (Required) The user to add to the repository as a collaborator. +- `permission` - (Optional) The permission of the outside collaborators for the repository. Must be one of `pull`, `push`, `maintain`, `triage` or `admin` or the name of an existing [custom repository role](https://docs.github.com/en/enterprise-cloud@latest/organizations/managing-peoples-access-to-your-organization-with-roles/managing-custom-repository-roles-for-an-organization) within the organization for organization-owned repositories. Must be `push` for personal repositories. Defaults to `push`. + +The `team` block supports: + +- `team_id` - (Required) The GitHub team id or the GitHub team slug. +- `permission` - (Optional) The permission of the outside collaborators for the repository. Must be one of `pull`, `triage`, `push`, `maintain`, `admin` or the name of an existing [custom repository role](https://docs.github.com/en/enterprise-cloud@latest/organizations/managing-peoples-access-to-your-organization-with-roles/managing-custom-repository-roles-for-an-organization) within the organisation. Defaults to `pull`. Must be `push` for personal repositories. Defaults to `push`. + +The `team_ignore` block supports: + +- `team_id` - (Required) The GitHub team id or the GitHub team slug. + +## Attribute Reference + +In addition to the above arguments, the following attributes are exported: + +- `invitation_ids` - Map of usernames to invitation ID for any users added as part of creation of this resource to be used in [`github_user_invitation_accepter`](./user_invitation_accepter.html). + +## Import + +GitHub Repository Collaborators can be imported using the name `name`, e.g. + +```sh +$ terraform import github_repository_collaborators.collaborators terraform +``` diff --git a/docs/resources/repository_custom_property.md b/docs/resources/repository_custom_property.md new file mode 100644 index 0000000000..ba784e922e --- /dev/null +++ b/docs/resources/repository_custom_property.md @@ -0,0 +1,46 @@ +--- +page_title: "github_repository_custom_property Resource - terraform-provider-github +description: |- + Creates and a specific custom property for a GitHub repository +--- + +# github_repository_custom_property (Resource) + +This resource allows you to create and manage a specific custom property for a GitHub repository. + +## Example Usage + +> Note that this assumes there already is a custom property defined on the org level called `my-cool-property` of type `string` + +```terraform +resource "github_repository" "example" { + name = "example" + description = "My awesome codebase" +} +resource "github_repository_custom_property" "string" { + repository = github_repository.example.name + property_name = "my-cool-property" + property_type = "string" + property_value = ["test"] +} +``` + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The repository of the environment. + +- `property_type` - (Required) Type of the custom property. Can be one of `single_select`, `multi_select`, `string`, or `true_false` + +- `property_name` - (Required) Name of the custom property. Note that a pre-requisiste for this resource is that a custom property of this name has already been defined on the organization level + +- `property_value` - (Required) Value of the custom property in the form of an array. Properties of type `single_select`, `string`, and `true_false` are represented as a string array of length 1 + +## Import + +GitHub Repository Custom Property can be imported using an ID made up of a comibnation of the names of the organization, repository, custom property separated by a `:` character, e.g. + +```sh +$ terraform import github_repository_custom_property.example organization-name:repo-name:custom-property-name +``` diff --git a/docs/resources/repository_dependabot_security_updates.md b/docs/resources/repository_dependabot_security_updates.md new file mode 100644 index 0000000000..9af45405d7 --- /dev/null +++ b/docs/resources/repository_dependabot_security_updates.md @@ -0,0 +1,46 @@ +--- +page_title: "github_repository_dependabot_security_updates Resource - terraform-provider-github +description: |- + Manages automated security fixes for a single repository +--- + +# github_repository_dependabot_security_updates (Resource) + +This resource allows you to manage dependabot automated security fixes for a single repository. See the [documentation](https://docs.github.com/en/code-security/dependabot/dependabot-security-updates/about-dependabot-security-updates) for details of usage and how this will impact your repository + +## Example Usage + +```terraform +resource "github_repository" "repo" { + name = "my-repo" + description = "GitHub repo managed by Terraform" + + private = false + + vulnerability_alerts = true +} + + +resource "github_repository_dependabot_security_updates" "example" { + repository = github_repository.test.name + enabled = true +} +``` + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The name of the GitHub repository. + +- `enabled` - (Required) The state of the automated security fixes. + +## Import + +Automated security references can be imported using the `name` of the repository + +### Import by name + +```sh +terraform import github_repository_dependabot_security_updates.example my-repo +``` diff --git a/docs/resources/repository_deploy_key.md b/docs/resources/repository_deploy_key.md new file mode 100644 index 0000000000..138e4cfa2a --- /dev/null +++ b/docs/resources/repository_deploy_key.md @@ -0,0 +1,55 @@ +--- +page_title: "github_repository_deploy_key Resource - terraform-provider-github +description: |- + Provides a GitHub repository deploy key resource. +--- + +# github_repository_deploy_key (Resource) + +Provides a GitHub repository deploy key resource. + +A deploy key is an SSH key that is stored on your server and grants access to a single GitHub repository. This key is attached directly to the repository instead of to a personal user account. + +This resource allows you to add/remove repository deploy keys. + +~> **Note on Archived Repositories**: When a repository is archived, GitHub makes it read-only, preventing deploy key modifications. If you attempt to destroy resources associated with archived repositories, the provider will gracefully handle the operation by logging an informational message and removing the resource from Terraform state without attempting to modify the archived repository. + +Further documentation on GitHub repository deploy keys: + +- [About deploy keys](https://developer.github.com/guides/managing-deploy-keys/#deploy-keys) + +## Example Usage + +```terraform +# Generate an ssh key using provider "hashicorp/tls" +resource "tls_private_key" "example_repository_deploy_key" { + algorithm = "ED25519" +} + +# Add the ssh key as a deploy key +resource "github_repository_deploy_key" "example_repository_deploy_key" { + title = "Repository test key" + repository = "test-repo" + key = tls_private_key.example_repository_deploy_key.public_key_openssh + read_only = true +} +``` + +## Argument Reference + +The following arguments are supported: + +- `key` - (Required) A SSH key. +- `read_only` - (Required) A boolean qualifying the key to be either read only or read/write. +- `repository` - (Required) Name of the GitHub repository. +- `title` - (Required) A title. + +Changing any of the fields forces re-creating the resource. + +## Import + +Repository deploy keys can be imported using a colon-separated pair of repository name and GitHub's key id. The latter can be obtained by GitHub's SDKs and API. + +```sh +$ terraform import github_repository_deploy_key.foo test-repo:23824728 +``` diff --git a/docs/resources/repository_deployment_branch_policy.md b/docs/resources/repository_deployment_branch_policy.md new file mode 100644 index 0000000000..697b99c6e1 --- /dev/null +++ b/docs/resources/repository_deployment_branch_policy.md @@ -0,0 +1,54 @@ +--- +page_title: "github_repository_deployment_branch_policy Resource - terraform-provider-github +description: |- + Creates and manages deployment branch policies +--- + +# github_repository_deployment_branch_policy (Resource) + +~> **Note:** This resource is deprecated, please use the `github_repository_environment_deployment_policy` resource instead. + +This resource allows you to create and manage deployment branch policies. + +## Example Usage + +```terraform +resource "github_repository_environment" "env" { + repository = "my_repo" + environment = "my_env" + deployment_branch_policy { + protected_branches = false + custom_branch_policies = true + } +} + +resource "github_repository_deployment_branch_policy" "foo" { + depends_on = [github_repository_environment.env] + + repository = "my_repo" + environment_name = "my_env" + name = "foo" +} +``` + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The repository to create the policy in. + +- `environment_name` - (Required) The name of the environment. This environment must have `deployment_branch_policy.custom_branch_policies` set to true or a 404 error will be thrown. + +- `name` - (Required) The name pattern that branches must match in order to deploy to the environment. + +## Attributes Reference + +The following additional attributes are exported: + +- `id` - The ID of the deployment branch policy. + +## Import + +```sh +$ terraform import github_repository_deployment_branch_policy.foo repo:env:id +``` diff --git a/docs/resources/repository_environment.md b/docs/resources/repository_environment.md new file mode 100644 index 0000000000..d89b7068cf --- /dev/null +++ b/docs/resources/repository_environment.md @@ -0,0 +1,73 @@ +--- +page_title: "github_repository_environment Resource - terraform-provider-github +description: |- + Creates and manages environments for GitHub repositories +--- + +# github_repository_environment (Resource) + +This resource allows you to create and manage environments for a GitHub repository. + +## Example Usage + +```terraform +data "github_user" "current" { + username = "" +} + +resource "github_repository" "example" { + name = "A Repository Project" + description = "My awesome codebase" +} + +resource "github_repository_environment" "example" { + environment = "example" + repository = github_repository.example.name + prevent_self_review = true + reviewers { + users = [data.github_user.current.id] + } + deployment_branch_policy { + protected_branches = true + custom_branch_policies = false + } +} +``` + +## Argument Reference + +The following arguments are supported: + +- `environment` - (Required) The name of the environment. + +- `repository` - (Required) The repository of the environment. + +- `wait_timer` - (Optional) Amount of time to delay a job after the job is initially triggered. + +- `can_admins_bypass` - (Optional) Can repository admins bypass the environment protections. Defaults to `true`. + +- `prevent_self_review` - (Optional) Whether or not a user who created the job is prevented from approving their own job. Defaults to `false`. + +### Reviewers + +The `reviewers` block supports the following: + +- `teams` - (Optional) Up to 6 IDs for teams who may review jobs that reference the environment. Reviewers must have at least read access to the repository. Only one of the required reviewers needs to approve the job for it to proceed. + +- `users` - (Optional) Up to 6 IDs for users who may review jobs that reference the environment. Reviewers must have at least read access to the repository. Only one of the required reviewers needs to approve the job for it to proceed. + +#### Deployment Branch Policy + +The `deployment_branch_policy` block supports the following: + +- `protected_branches` - (Required) Whether only branches with branch protection rules can deploy to this environment. + +- `custom_branch_policies` - (Required) Whether only branches that match the specified name patterns can deploy to this environment. + +## Import + +GitHub Repository Environment can be imported using an ID made up of `name` of the repository combined with the `environment` name of the environment, separated by a `:` character, e.g. + +```sh +$ terraform import github_repository_environment.daily terraform:daily +``` diff --git a/docs/resources/repository_environment_deployment_policy.md b/docs/resources/repository_environment_deployment_policy.md new file mode 100644 index 0000000000..cc51f2f6f1 --- /dev/null +++ b/docs/resources/repository_environment_deployment_policy.md @@ -0,0 +1,93 @@ +--- +page_title: "github_repository_environment_deployment_policy Resource - terraform-provider-github +description: |- + Creates and manages environment deployment branch policies for GitHub repositories +--- + +# github_repository_environment_deployment_policy (Resource) + +This resource allows you to create and manage environment deployment branch policies for a GitHub repository. + +## Example Usage + +Create a branch-based deployment policy: + +```terraform +data "github_user" "current" { + username = "" +} + +resource "github_repository" "test" { + name = "tf-acc-test-%s" +} + +resource "github_repository_environment" "test" { + repository = github_repository.test.name + environment = "environment/test" + wait_timer = 10000 + reviewers { + users = [data.github_user.current.id] + } + deployment_branch_policy { + protected_branches = false + custom_branch_policies = true + } +} + +resource "github_repository_environment_deployment_policy" "test" { + repository = github_repository.test.name + environment = github_repository_environment.test.environment + branch_pattern = "releases/*" +} +``` + +Create a tag-based deployment policy: + +```terraform +data "github_user" "current" { + username = "" +} + +resource "github_repository" "test" { + name = "tf-acc-test-%s" +} + +resource "github_repository_environment" "test" { + repository = github_repository.test.name + environment = "environment/test" + wait_timer = 10000 + reviewers { + users = [data.github_user.current.id] + } + deployment_branch_policy { + protected_branches = false + custom_branch_policies = true + } +} + +resource "github_repository_environment_deployment_policy" "test" { + repository = github_repository.test.name + environment = github_repository_environment.test.environment + tag_pattern = "v*" +} +``` + +## Argument Reference + +The following arguments are supported: + +- `environment` - (Required) The name of the environment. + +- `repository` - (Required) The repository of the environment. + +- `branch_pattern` - (Optional) The name pattern that branches must match in order to deploy to the environment. If not specified, `tag_pattern` must be specified. + +- `tag_pattern` - (Optional) The name pattern that tags must match in order to deploy to the environment. If not specified, `branch_pattern` must be specified. + +## Import + +GitHub Repository Environment Deployment Policy can be imported using an ID made up of `name` of the repository combined with the `environment` name of the environment with the `Id` of the deployment policy, separated by a `:` character, e.g. + +```sh +$ terraform import github_repository_environment.daily terraform:daily:123456 +``` diff --git a/docs/resources/repository_file.md b/docs/resources/repository_file.md new file mode 100644 index 0000000000..59691d9954 --- /dev/null +++ b/docs/resources/repository_file.md @@ -0,0 +1,104 @@ +--- +page_title: "github_repository_file Resource - terraform-provider-github +description: |- + Creates and manages files within a GitHub repository +--- + +# github_repository_file (Resource) + +This resource allows you to create and manage files within a GitHub repository. + +~> **Note:** When a repository is archived, Terraform will skip deletion of repository files to avoid API errors, as archived repositories are read-only. The files will be removed from Terraform state without attempting to delete them from GitHub. + +## Example Usage + +### Existing Branch + +```terraform +resource "github_repository" "foo" { + name = "tf-acc-test-%s" + auto_init = true +} + +resource "github_repository_file" "foo" { + repository = github_repository.foo.name + branch = "main" + file = ".gitignore" + content = "**/*.tfstate" + commit_message = "Managed by Terraform" + commit_author = "Terraform User" + commit_email = "terraform@example.com" + overwrite_on_create = true +} +``` + +### Auto Created Branch + +```terraform +resource "github_repository" "foo" { + name = "tf-acc-test-%s" + auto_init = true +} + +resource "github_repository_file" "foo" { + repository = github_repository.foo.name + branch = "does/not/exist" + file = ".gitignore" + content = "**/*.tfstate" + commit_message = "Managed by Terraform" + commit_author = "Terraform User" + commit_email = "terraform@example.com" + overwrite_on_create = true + autocreate_branch = true +} +``` + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The repository to create the file in. + +- `file` - (Required) The path of the file to manage. + +- `content` - (Required) The file content. + +- `branch` - (Optional) Git branch (defaults to the repository's default branch). The branch must already exist, it will only be created automatically if 'autocreate_branch' is set true. + +- `commit_author` - (Optional) Committer author name to use. **NOTE:** GitHub app users may omit author and email information so GitHub can verify commits as the GitHub App. This maybe useful when a branch protection rule requires signed commits. + +- `commit_email` - (Optional) Committer email address to use. **NOTE:** GitHub app users may omit author and email information so GitHub can verify commits as the GitHub App. This may be useful when a branch protection rule requires signed commits. + +- `commit_message` - (Optional) The commit message when creating, updating or deleting the managed file. + +- `overwrite_on_create` - (Optional) Enable overwriting existing files. If set to `true` it will overwrite an existing file with the same name. If set to `false` it will fail if there is an existing file with the same name. + +- `autocreate_branch` - (Optional) Automatically create the branch if it could not be found. Defaults to false. Subsequent reads if the branch is deleted will occur from 'autocreate_branch_source_branch'. + +- `autocreate_branch_source_branch` - (Optional) The branch name to start from, if 'autocreate_branch' is set. Defaults to 'main'. + +- `autocreate_branch_source_sha` - (Optional) The commit hash to start from, if 'autocreate_branch' is set. Defaults to the tip of 'autocreate_branch_source_branch'. If provided, 'autocreate_branch_source_branch' is ignored. + +## Attributes Reference + +The following additional attributes are exported: + +- `commit_sha` - The SHA of the commit that modified the file. + +- `sha` - The SHA blob of the file. + +- `ref` - The name of the commit/branch/tag. + +## Import + +Repository files can be imported using a combination of the `repo` and `file`, e.g. + +```sh +$ terraform import github_repository_file.gitignore example/.gitignore +``` + +To import a file from a branch other than the default branch, append `:` and the branch name, e.g. + +```sh +$ terraform import github_repository_file.gitignore example/.gitignore:dev +``` diff --git a/docs/resources/repository_milestone.md b/docs/resources/repository_milestone.md new file mode 100644 index 0000000000..06957b28f0 --- /dev/null +++ b/docs/resources/repository_milestone.md @@ -0,0 +1,52 @@ +--- +page_title: "github_repository_milestone Resource - terraform-provider-github +description: |- + Provides a GitHub repository milestone resource. +--- + +# github_repository_milestone (Resource) + +Provides a GitHub repository milestone resource. + +This resource allows you to create and manage milestones for a GitHub Repository within an organization or user account. + +## Example Usage + +```terraform +# Create a milestone for a repository +resource "github_repository_milestone" "example" { + owner = "example-owner" + repository = "example-repository" + title = "v1.1.0" +} +``` + +## Argument Reference + +The following arguments are supported: + +- `owner` - (Required) The owner of the GitHub Repository. + +- `repository` - (Required) The name of the GitHub Repository. + +- `title` - (Required) The title of the milestone. + +- `description` - (Optional) A description of the milestone. + +- `due_date` - (Optional) The milestone due date. In `yyyy-mm-dd` format. + +- `state` - (Optional) The state of the milestone. Either `open` or `closed`. Default: `open` + +## Attributes Reference + +The following additional attributes are exported: + +- `number` - The number of the milestone. + +## Import + +A GitHub Repository Milestone can be imported using an ID made up of `owner/repository/number`, e.g. + +```sh +$ terraform import github_repository_milestone.example example-owner/example-repository/1 +``` diff --git a/docs/resources/repository_pull_request.md b/docs/resources/repository_pull_request.md new file mode 100644 index 0000000000..df1007ae95 --- /dev/null +++ b/docs/resources/repository_pull_request.md @@ -0,0 +1,57 @@ +--- +page_title: "github_repository_pull_request Resource - terraform-provider-github +description: |- + Get information on a single GitHub Pull Request. +--- + +# github_repository_pull_request (Resource) + +This resource allows you to create and manage PullRequests for repositories within your GitHub organization or personal account. + +## Example Usage + +```terraform +resource "github_repository_pull_request" "example" { + base_repository = "example-repository" + base_ref = "main" + head_ref = "feature-branch" + title = "My newest feature" + body = "This will change everything" +} +``` + +## Argument Reference + +- `base_repository` - (Required) Name of the base repository to retrieve the Pull Requests from. + +- `base_ref` - (Required) Name of the branch serving as the base of the Pull Request. + +- `head_ref` - (Required) Name of the branch serving as the head of the Pull Request. + +- `owner` - (Optional) Owner of the repository. If not provided, the provider's default owner is used. + +- `title` - (Optional) The title of the Pull Request. + +- `body` - (Optional) Body of the Pull Request. + +- `maintainer_can_modify` - Controls whether the base repository maintainers can modify the Pull Request. Default: false. + +## Attributes Reference + +- `base_sha` - Head commit SHA of the Pull Request base. + +- `draft` - Indicates Whether this Pull Request is a draft. + +- `head_sha` - Head commit SHA of the Pull Request head. + +- `labels` - List of label names set on the Pull Request. + +- `number` - The number of the Pull Request within the repository. + +- `opened_at` - Unix timestamp indicating the Pull Request creation time. + +- `opened_by` - GitHub login of the user who opened the Pull Request. + +- `state` - the current Pull Request state - can be "open", "closed" or "merged". + +- `updated_at` - The timestamp of the last Pull Request update. diff --git a/docs/resources/repository_ruleset.md b/docs/resources/repository_ruleset.md new file mode 100644 index 0000000000..4af0e31faf --- /dev/null +++ b/docs/resources/repository_ruleset.md @@ -0,0 +1,315 @@ +--- +page_title: "github_repository_ruleset Resource - terraform-provider-github +description: |- + Creates a GitHub repository ruleset. +--- + +# github_repository_ruleset (Resource) + +Creates a GitHub repository ruleset. + +This resource allows you to create and manage rulesets on the repository level. When applied, a new ruleset will be created. When destroyed, that ruleset will be removed. + +## Example Usage + +```terraform +resource "github_repository" "example" { + name = "example" + description = "Example repository" +} + +resource "github_repository_ruleset" "example" { + name = "example" + repository = github_repository.example.name + target = "branch" + enforcement = "active" + + conditions { + ref_name { + include = ["~ALL"] + exclude = [] + } + } + + bypass_actors { + actor_id = 13473 + actor_type = "Integration" + bypass_mode = "always" + } + + rules { + creation = true + update = true + deletion = true + required_linear_history = true + required_signatures = true + + required_deployments { + required_deployment_environments = ["test"] + } + + required_code_scanning { + required_code_scanning_tool { + alerts_threshold = "errors" + security_alerts_threshold = "high_or_higher" + tool = "CodeQL" + } + } + } +} + +# Example with push ruleset +resource "github_repository_ruleset" "example_push" { + name = "example_push" + repository = github_repository.example.name + target = "push" + enforcement = "active" + + rules { + file_path_restriction { + restricted_file_paths = [".github/workflows/*", "*.env"] + } + + max_file_size { + max_file_size = 100 # 100 MB + } + + max_file_path_length { + max_file_path_length = 255 + } + + file_extension_restriction { + restricted_file_extensions = ["*.exe", "*.dll", "*.so"] + } + } +} +``` + +## Argument Reference + +- `enforcement` - (Required) (String) Possible values for Enforcement are `disabled`, `active`, `evaluate`. Note: `evaluate` is currently only supported for owners of type `organization`. + +- `name` - (Required) (String) The name of the ruleset. + +- `rules` - (Required) (Block List, Min: 1, Max: 1) Rules within the ruleset. (see [below for nested schema](#rules)) + +- `target` - (Required) (String) Possible values are `branch`, `tag` and `push`. + +- `bypass_actors` - (Optional) (Block List) The actors that can bypass the rules in this ruleset. (see [below for nested schema](#bypass_actors)) + +- `conditions` - (Optional) (Block List, Max: 1) Parameters for a repository ruleset ref name condition. (see [below for nested schema](#conditions)) + +- `repository` - (Required) (String) Name of the repository to apply ruleset to. + +### Rules + +The `rules` block supports the following: + +- `branch_name_pattern` - (Optional) (Block List, Max: 1) Parameters to be used for the branch_name_pattern rule. This rule only applies to repositories within an enterprise, it cannot be applied to repositories owned by individuals or regular organizations. Conflicts with `tag_name_pattern` as it only applied to rulesets with target `branch`. (see [below for nested schema](#rulesbranch_name_pattern)) + +- `commit_author_email_pattern` - (Optional) (Block List, Max: 1) Parameters to be used for the commit_author_email_pattern rule. This rule only applies to repositories within an enterprise, it cannot be applied to repositories owned by individuals or regular organizations. (see [below for nested schema](#rulescommit_author_email_pattern)) + +- `commit_message_pattern` - (Optional) (Block List, Max: 1) Parameters to be used for the commit_message_pattern rule. This rule only applies to repositories within an enterprise, it cannot be applied to repositories owned by individuals or regular organizations. (see [below for nested schema](#rulescommit_message_pattern)) + +- `committer_email_pattern` - (Optional) (Block List, Max: 1) Parameters to be used for the committer_email_pattern rule. This rule only applies to repositories within an enterprise, it cannot be applied to repositories owned by individuals or regular organizations. (see [below for nested schema](#rulescommitter_email_pattern)) + +- `creation` - (Optional) (Boolean) Only allow users with bypass permission to create matching refs. + +- `deletion` - (Optional) (Boolean) Only allow users with bypass permissions to delete matching refs. + +- `non_fast_forward` - (Optional) (Boolean) Prevent users with push access from force pushing to branches. + +- `merge_queue` - (Optional) (Block List, Max: 1) Merges must be performed via a merge queue. + +- `pull_request` - (Optional) (Block List, Max: 1) Require all commits be made to a non-target branch and submitted via a pull request before they can be merged. (see [below for nested schema](#rulespull_request)) + +- `required_deployments` - (Optional) (Block List, Max: 1) Choose which environments must be successfully deployed to before branches can be merged into a branch that matches this rule. (see [below for nested schema](#rulesrequired_deployments)) + +- `required_linear_history` - (Optional) (Boolean) Prevent merge commits from being pushed to matching branches. + +- `required_signatures` - (Optional) (Boolean) Commits pushed to matching branches must have verified signatures. + +- `required_status_checks` - (Optional) (Block List, Max: 1) Choose which status checks must pass before branches can be merged into a branch that matches this rule. When enabled, commits must first be pushed to another branch, then merged or pushed directly to a branch that matches this rule after status checks have passed. (see [below for nested schema](#rulesrequired_status_checks)) + +- `tag_name_pattern` - (Optional) (Block List, Max: 1) Parameters to be used for the tag_name_pattern rule. This rule only applies to repositories within an enterprise, it cannot be applied to repositories owned by individuals or regular organizations. Conflicts with `branch_name_pattern` as it only applied to rulesets with target `tag`. (see [below for nested schema](#rulestag_name_pattern)) + +- `required_code_scanning` - (Optional) (Block List, Max: 1) Define which tools must provide code scanning results before the reference is updated. When configured, code scanning must be enabled and have results for both the commit and the reference being updated. Multiple code scanning tools can be specified. (see [below for nested schema](#rulesrequired_code_scanning)) + +- `file_path_restriction` - (Optional) (Block List, Max 1) Parameters to be used for the file_path_restriction rule. When enabled restricts access to files within the repository. (See [below for nested schema](#rules.file_path_restriction)) + +- `max_file_size` - (Optional) (Block List, Max 1) Parameters to be used for the max_file_size rule. When enabled restricts the maximum size of a file that can be pushed to the repository. (See [below for nested schema](#rules.max_file_size)) + +- `max_file_path_length` - (Optional) (Block List, Max: 1) Prevent commits that include file paths that exceed a specified character limit from being pushed to the commit graph. This rule only applies to rulesets with target `push`. (see [below for nested schema](#rules.max_file_path_length)) + +- `file_extension_restriction` - (Optional) (Block List, Max: 1) Prevent commits that include files with specified file extensions from being pushed to the commit graph. This rule only applies to rulesets with target `push`. (see [below for nested schema](#rules.file_extension_restriction)) +- `update` - (Optional) (Boolean) Only allow users with bypass permission to update matching refs. + +- `update_allows_fetch_and_merge` - (Optional) (Boolean) Branch can pull changes from its upstream repository. This is only applicable to forked repositories. Requires `update` to be set to `true`. Note: behaviour is affected by a known bug on the GitHub side which may cause issues when using this parameter. + +#### rules.branch_name_pattern + +- `operator` - (Required) (String) The operator to use for matching. Can be one of: `starts_with`, `ends_with`, `contains`, `regex`. + +- `pattern` - (Required) (String) The pattern to match with. + +- `name` - (Optional) (String) How this rule will appear to users. + +- `negate` - (Optional) (Boolean) If true, the rule will fail if the pattern matches. + +#### rules.commit_author_email_pattern + +- `operator` - (Required) (String) The operator to use for matching. Can be one of: `starts_with`, `ends_with`, `contains`, `regex`. + +- `pattern` - (Required) (String) The pattern to match with. + +- `name` - (Optional) (String) How this rule will appear to users. + +- `negate` - (Optional) (Boolean) If true, the rule will fail if the pattern matches. + +#### rules.commit_message_pattern + +- `operator` - (Required) (String) The operator to use for matching. Can be one of: `starts_with`, `ends_with`, `contains`, `regex`. + +- `pattern` - (Required) (String) The pattern to match with. + +- `name` - (Optional) (String) How this rule will appear to users. + +- `negate` - (Optional) (Boolean) If true, the rule will fail if the pattern matches. + +#### rules.committer_email_pattern + +- `operator` - (Required) (String) The operator to use for matching. Can be one of: `starts_with`, `ends_with`, `contains`, `regex`. + +- `pattern` - (Required) (String) The pattern to match with. + +- `name` - (Optional) (String) How this rule will appear to users. + +- `negate` - (Optional) (Boolean) If true, the rule will fail if the pattern matches. + +#### rules.merge_queue + +- `check_response_timeout_minutes` - (Required) (Number)Maximum time for a required status check to report a conclusion. After this much time has elapsed, checks that have not reported a conclusion will be assumed to have failed. Defaults to `60`. + +- `grouping_strategy` - (Required) (String)When set to ALLGREEN, the merge commit created by merge queue for each PR in the group must pass all required checks to merge. When set to HEADGREEN, only the commit at the head of the merge group, i.e. the commit containing changes from all of the PRs in the group, must pass its required checks to merge. Can be one of: ALLGREEN, HEADGREEN. Defaults to `ALLGREEN`. + +- `max_entries_to_build` - (Required) (Number) Limit the number of queued pull requests requesting checks and workflow runs at the same time. Defaults to `5`. + +- `max_entries_to_merge` - (Required) (Number) Limit the number of queued pull requests requesting checks and workflow runs at the same time. Defaults to `5`. + +- `merge_method` - (Required) (String) Method to use when merging changes from queued pull requests. Can be one of: MERGE, SQUASH, REBASE. Defaults to `MERGE`. + +- `min_entries_to_merge` - (Required) (Number) The minimum number of PRs that will be merged together in a group. Defaults to `1`. + +- `min_entries_to_merge_wait_minutes` - (Required) (Number) The time merge queue should wait after the first PR is added to the queue for the minimum group size to be met. After this time has elapsed, the minimum group size will be ignored and a smaller group will be merged. Defaults to `5`. + +#### rules.pull_request + +- `dismiss_stale_reviews_on_push` - (Optional) (Boolean) New, reviewable commits pushed will dismiss previous pull request review approvals. Defaults to `false`. + +- `require_code_owner_review` - (Optional) (Boolean) Require an approving review in pull requests that modify files that have a designated code owner. Defaults to `false`. + +- `require_last_push_approval` - (Optional) (Boolean) Whether the most recent reviewable push must be approved by someone other than the person who pushed it. Defaults to `false`. + +- `required_approving_review_count` - (Optional) (Number) The number of approving reviews that are required before a pull request can be merged. Defaults to `0`. + +- `required_review_thread_resolution` - (Optional) (Boolean) All conversations on code must be resolved before a pull request can be merged. Defaults to `false`. + +#### rules.required_deployments + +- `required_deployment_environments` - (Required) (List of String) The environments that must be successfully deployed to before branches can be merged. + +#### rules.required_status_checks + +- `required_check` - (Required) (Block Set, Min: 1) Status checks that are required. Several can be defined. (see [below for nested schema](#rulesrequired_status_checksrequired_check)) + +- `strict_required_status_checks_policy` - (Optional) (Boolean) Whether pull requests targeting a matching branch must be tested with the latest code. This setting will not take effect unless at least one status check is enabled. Defaults to `false`. + +- `do_not_enforce_on_create` - (Optional) (Boolean) Allow repositories and branches to be created if a check would otherwise prohibit it. Defaults to `false`. + +#### rules.required_status_checks.required_check + +- `context` - (Required) (String) The status check context name that must be present on the commit. + +- `integration_id` - (Optional) (Number) The optional integration ID that this status check must originate from. It's a GitHub App ID, which can be obtained by following instructions from the [Get an App API docs](https://docs.github.com/en/rest/apps/apps?apiVersion=2022-11-28#get-an-app). + +#### rules.tag_name_pattern + +- `operator` - (Required) (String) The operator to use for matching. Can be one of: `starts_with`, `ends_with`, `contains`, `regex`. + +- `pattern` - (Required) (String) The pattern to match with. + +- `name` - (Optional) (String) How this rule will appear to users. + +- `negate` - (Optional) (Boolean) If true, the rule will fail if the pattern matches. + +#### rules.required_code_scanning + +- `required_code_scanning_tool` - (Required) (Block Set, Min: 1) Actions code scanning tools that are required. Multiple can be defined. (see [below for nested schema](#rulesrequired_code_scanningrequired_code_scanning_tool)) + +#### rules.required_code_scanning.required_code_scanning_tool + +- `alerts_threshold` - (Required) (String) The severity level at which code scanning results that raise alerts block a reference update. Can be one of: `none`, `errors`, `errors_and_warnings`, `all`. + +- `security_alerts_threshold` - (Required) (String) The severity level at which code scanning results that raise security alerts block a reference update. Can be one of: `none`, `critical`, `high_or_higher`, `medium_or_higher`, `all`. + +- `tool` - (Required) (String) The name of a code scanning tool. + +#### rules.file_path_restriction + +- `restricted_file_paths` - (Required) (Block Set, Min: 1) The file paths that are restricted from being pushed to the commit graph. + +#### rules.max_file_size + +- `max_file_size` - (Required) (Integer) The maximum allowed size, in megabytes (MB), of a file. Valid range is 1-100 MB. + +#### rules.max_file_path_length + +- `max_file_path_length` - (Required) (Integer) The maximum number of characters allowed in file paths. + +#### rules.file_extension_restriction + +- `restricted_file_extensions` - (Required) (Block Set, Min: 1) The file extensions that are restricted from being pushed to the commit graph. + +#### bypass_actors + +- `actor_id` - (Number) The ID of the actor that can bypass a ruleset. If `actor_type` is `Integration`, `actor_id` is a GitHub App ID. App ID can be obtained by following instructions from the [Get an App API docs](https://docs.github.com/en/rest/apps/apps?apiVersion=2022-11-28#get-an-app) + +- `actor_type` (String) The type of actor that can bypass a ruleset. Can be one of: `RepositoryRole`, `Team`, `Integration`, `OrganizationAdmin`, `DeployKey`. + +- `bypass_mode` - (Optional) (String) When the specified actor can bypass the ruleset. pull_request means that an actor can only bypass rules on pull requests. Can be one of: `always`, `pull_request`, `exempt`. + +~> Note: at the time of writing this, the following actor types correspond to the following actor IDs: + +- `OrganizationAdmin` -> `1` +- `RepositoryRole` (This is the actor type, the following are the base repository roles and their associated IDs.) + - `maintain` -> `2` + - `write` -> `4` + - `admin` -> `5` + +#### conditions + +- `ref_name` - (Required) (Block List, Min: 1, Max: 1) (see [below for nested schema](#conditions.ref_name)) + +#### conditions.ref_name + +- `exclude` - (Required) (List of String) Array of ref names or patterns to exclude. The condition will not pass if any of these patterns match. + +- `include` - (Required) (List of String) Array of ref names or patterns to include. One of these patterns must match for the condition to pass. Also accepts `~DEFAULT_BRANCH` to include the default branch or `~ALL` to include all branches. + +## Attributes Reference + +The following additional attributes are exported: + +- `etag` (String) + +- `node_id` (String) GraphQL global node id for use with v4 API. + +- `ruleset_id` (Number) GitHub ID for the ruleset. + +## Import + +GitHub Repository Rulesets can be imported using the GitHub repository name and ruleset ID e.g. + +```sh +$ terraform import github_repository_ruleset.example example:12345 +``` diff --git a/docs/resources/repository_topics.md b/docs/resources/repository_topics.md new file mode 100644 index 0000000000..f64b36fc23 --- /dev/null +++ b/docs/resources/repository_topics.md @@ -0,0 +1,40 @@ +--- +page_title: "github_repository_topics Resource - terraform-provider-github +description: |- + Creates and manages the topics on a repository +--- + +# github_repository_topics (Resource) + +This resource allows you to create and manage topics for repositories within your GitHub organization or personal account. + +~> Note: This resource is not compatible with the `topic` attribute of the `github_repository` Use either `github_repository_topics` or `topic` in `github_repository`. `github_repository_topics` is only meant to be used if the repository itself is not handled via terraform, for example if it's only read as a datasource (see [issue #1845](https://github.com/integrations/terraform-provider-github/issues/1845)). + +## Example Usage + +```terraform +data "github_repository" "test" { + name = "test" +} + +resource "github_repository_topics" "test" { + repository = github_repository.test.name + topics = ["topic-1", "topic-2"] +} +``` + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The repository name. + +- `topics` - (Required) A list of topics to add to the repository. + +## Import + +Repository topics can be imported using the `name` of the repository. + +```sh +$ terraform import github_repository_topics.terraform terraform +``` diff --git a/docs/resources/repository_webhook.md b/docs/resources/repository_webhook.md new file mode 100644 index 0000000000..d283cd9852 --- /dev/null +++ b/docs/resources/repository_webhook.md @@ -0,0 +1,77 @@ +--- +page_title: "github_repository_webhook Resource - terraform-provider-github +description: |- + Creates and manages repository webhooks within GitHub organizations or personal accounts +--- + +# github_repository_webhook (Resource) + +This resource allows you to create and manage webhooks for repositories within your GitHub organization or personal account. + +~> **Note on Archived Repositories**: When a repository is archived, GitHub makes it read-only, preventing webhook modifications. If you attempt to destroy resources associated with archived repositories, the provider will gracefully handle the operation by logging an informational message and removing the resource from Terraform state without attempting to modify the archived repository. + +## Example Usage + +```terraform +resource "github_repository" "repo" { + name = "foo" + description = "Terraform acceptance tests" + homepage_url = "http://example.com/" + + visibility = "public" +} + +resource "github_repository_webhook" "foo" { + repository = github_repository.repo.name + + configuration { + url = "https://google.de/" + content_type = "form" + insecure_ssl = false + } + + active = false + + events = ["issues"] +} +``` + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The repository of the webhook. + +- `events` - (Required) A list of events which should trigger the webhook. See a list of [available events](https://developer.github.com/v3/activity/events/types/). + +- `configuration` - (Required) Configuration block for the webhook. [Detailed below.](#configuration) + +- `active` - (Optional) Indicate if the webhook should receive events. Defaults to `true`. + +### configuration + +- `url` - (Required) The URL of the webhook. + +- `content_type` - (Required) The content type for the payload. Valid values are either `form` or `json`. + +- `secret` - (Optional) The shared secret for the webhook. [See API documentation](https://developer.github.com/v3/repos/hooks/#create-a-hook). + +- `insecure_ssl` - (Optional) Insecure SSL boolean toggle. Defaults to `false`. + +## Attributes Reference + +The following additional attributes are exported: + +- `url` - URL of the webhook. This is a sensitive attribute because it may include basic auth credentials. + +## Import + +Repository webhooks can be imported using the `name` of the repository, combined with the `id` of the webhook, separated by a `/` character. The `id` of the webhook can be found in the URL of the webhook. For example: `"https://github.com/foo-org/foo-repo/settings/hooks/14711452"`. + +Importing uses the name of the repository, as well as the ID of the webhook, e.g. + +```sh +$ terraform import github_repository_webhook.terraform terraform/11235813 +``` + +If secret is populated in the webhook's configuration, the value will be imported as "********". diff --git a/docs/resources/team.md b/docs/resources/team.md new file mode 100644 index 0000000000..f90b5bb05f --- /dev/null +++ b/docs/resources/team.md @@ -0,0 +1,50 @@ +--- +page_title: "github_team Resource - terraform-provider-github +description: |- + Provides a GitHub team resource. +--- + +# github_team (Resource) + +Provides a GitHub team resource. + +This resource allows you to add/remove teams from your organization. When applied, a new team will be created. When destroyed, that team will be removed. + +## Example Usage + +```terraform +# Add a team to the organization +resource "github_team" "some_team" { + name = "some-team" + description = "Some cool team" + privacy = "closed" +} +``` + +## Argument Reference + +The following arguments are supported: + +- `name` - (Required) The name of the team. +- `description` - (Optional) A description of the team. +- `privacy` - (Optional) The level of privacy for the team. Must be one of `secret` or `closed`. Defaults to `secret`. +- `parent_team_id` - (Optional) The ID or slug of the parent team, if this is a nested team. +- `ldap_dn` - (Optional) The LDAP Distinguished Name of the group where membership will be synchronized. Only available in GitHub Enterprise Server. +- `create_default_maintainer` - (Optional) Adds a default maintainer to the team. Defaults to `false` and adds the creating user to the team when `true`. + +## Attributes Reference + +The following attributes are exported: + +- `id` - The ID of the created team. +- `node_id` - The Node ID of the created team. +- `slug` - The slug of the created team, which may or may not differ from `name`, depending on whether `name` contains "URL-unsafe" characters. Useful when referencing the team in [`github_branch_protection`](../branch_protection). + +## Import + +GitHub Teams can be imported using the GitHub team ID or slug e.g. + +```sh +$ terraform import github_team.core 1234567 +$ terraform import github_team.core administrators +``` diff --git a/docs/resources/team_members.md b/docs/resources/team_members.md new file mode 100644 index 0000000000..ebba6a0a15 --- /dev/null +++ b/docs/resources/team_members.md @@ -0,0 +1,83 @@ +--- +page_title: "github_team_members Resource - terraform-provider-github +description: |- + Provides an authoritative GitHub team members resource. +--- + +# github_team_members (Resource) + +Provides a GitHub team members resource. + +This resource allows you to manage members of teams in your organization. It sets the requested team members for the team and removes all users not managed by Terraform. + +When applied, if the user hasn't accepted their invitation to the organization, they won't be part of the team until they do. + +When destroyed, all users will be removed from the team. + +~> **Note** This resource is not compatible with `github_team_membership`. Use either `github_team_members` or `github_team_membership`. + +~> **Note** You can accidentally lock yourself out of your team using this resource. Deleting a `github_team_members` resource removes access from anyone without organization-level access to the team. Proceed with caution. It should generally only be used with teams fully managed by Terraform. + +~> **Note** Attempting to set a user who is an organization owner to "member" will result in the user being granted "maintainer" instead; this can result in a perpetual `terraform plan` diff that changes their status back to "member". + +## Example Usage + +```terraform +# Add a user to the organization +resource "github_membership" "membership_for_some_user" { + username = "SomeUser" + role = "member" +} + +resource "github_membership" "membership_for_another_user" { + username = "AnotherUser" + role = "member" +} + +resource "github_team" "some_team" { + name = "SomeTeam" + description = "Some cool team" +} + +resource "github_team_members" "some_team_members" { + team_id = github_team.some_team.id + + members { + username = "SomeUser" + role = "maintainer" + } + + members { + username = "AnotherUser" + role = "member" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +- `team_id` - (Required) The team id or the team slug + +~> **Note** Although the team id or team slug can be used it is recommended to use the team id. Using the team slug will cause the team members associations to the team to be destroyed and recreated if the team name is updated. + +- `members` - (Required) List of team members. See [Members](#members) below for details. + +### Members + +`members` supports the following arguments: + +- `username` - (Required) The user to add to the team. +- `role` - (Optional) The role of the user within the team. Must be one of `member` or `maintainer`. Defaults to `member`. + +## Import + +~> **Note** Although the team id or team slug can be used it is recommended to use the team id. Using the team slug will result in terraform doing conversions between the team slug and team id. This will cause team members associations to the team to be destroyed and recreated on import. + +GitHub Team Membership can be imported using the team ID team id or team slug, e.g. + +```sh +$ terraform import github_team_members.some_team 1234567 +$ terraform import github_team_members.some_team Administrators +``` diff --git a/docs/resources/team_membership.md b/docs/resources/team_membership.md new file mode 100644 index 0000000000..249ed41347 --- /dev/null +++ b/docs/resources/team_membership.md @@ -0,0 +1,53 @@ +--- +page_title: "github_team_membership Resource - terraform-provider-github +description: |- + Provides a GitHub team membership resource. +--- + +# github_team_membership (Resource) + +Provides a GitHub team membership resource. + +This resource allows you to add/remove users from teams in your organization. When applied, the user will be added to the team. If the user hasn't accepted their invitation to the organization, they won't be part of the team until they do. When destroyed, the user will be removed from the team. + +~> **Note** This resource is not compatible with `github_team_members`. Use either `github_team_members` or `github_team_membership`. + +~> **Note** Organization owners may not be set as "members" of a team; they may only be set as "maintainers". Attempting to set an organization owner as a "member" of a team may result in a `terraform plan` diff that changes their status back to "maintainer". + +## Example Usage + +```terraform +# Add a user to the organization +resource "github_membership" "membership_for_some_user" { + username = "SomeUser" + role = "member" +} + +resource "github_team" "some_team" { + name = "SomeTeam" + description = "Some cool team" +} + +resource "github_team_membership" "some_team_membership" { + team_id = github_team.some_team.id + username = "SomeUser" + role = "member" +} +``` + +## Argument Reference + +The following arguments are supported: + +- `team_id` - (Required) The GitHub team id or the GitHub team slug +- `username` - (Required) The user to add to the team. +- `role` - (Optional) The role of the user within the team. Must be one of `member` or `maintainer`. Defaults to `member`. + +## Import + +GitHub Team Membership can be imported using an ID made up of `teamid:username` or `teamname:username`, e.g. + +```sh +$ terraform import github_team_membership.member 1234567:someuser +$ terraform import github_team_membership.member Administrators:someuser +``` diff --git a/docs/resources/team_repository.md b/docs/resources/team_repository.md new file mode 100644 index 0000000000..d6dbb58a90 --- /dev/null +++ b/docs/resources/team_repository.md @@ -0,0 +1,56 @@ +--- +page_title: "github_team_repository Resource - terraform-provider-github +description: |- + Manages the associations between teams and repositories. +--- + +# github_team_repository (Resource) + +~> Note: github_team_repository cannot be used in conjunction with github_repository_collaborators or they will fight over what your policy should be. + +This resource manages relationships between teams and repositories in your GitHub organization. + +Creating this resource grants a particular team permissions on a particular repository. + +The repository and the team must both belong to the same organization on GitHub. This resource does not actually *create* any repositories; to do that, see [`github_repository`](repository.html). + +~> **Note on Archived Repositories**: When a repository is archived, GitHub makes it read-only, preventing team permission modifications. If you attempt to destroy resources associated with archived repositories, the provider will gracefully handle the operation by logging an informational message and removing the resource from Terraform state without attempting to modify the archived repository. + +This resource is non-authoritative, for managing ALL collaborators of a repo, use github_repository_collaborators instead. + +## Example Usage + +```terraform +# Add a repository to the team +resource "github_team" "some_team" { + name = "SomeTeam" + description = "Some cool team" +} + +resource "github_repository" "some_repo" { + name = "some-repo" +} + +resource "github_team_repository" "some_team_repo" { + team_id = github_team.some_team.id + repository = github_repository.some_repo.name + permission = "pull" +} +``` + +## Argument Reference + +The following arguments are supported: + +- `team_id` - (Required) The GitHub team id or the GitHub team slug +- `repository` - (Required) The repository to add to the team. +- `permission` - (Optional) The permissions of team members regarding the repository. Must be one of `pull`, `triage`, `push`, `maintain`, `admin` or the name of an existing [custom repository role](https://docs.github.com/en/enterprise-cloud@latest/organizations/managing-peoples-access-to-your-organization-with-roles/managing-custom-repository-roles-for-an-organization) within the organisation. Defaults to `pull`. + +## Import + +GitHub Team Repository can be imported using an ID made up of `team_id:repository` or `team_name:repository`, e.g. + +```sh +$ terraform import github_team_repository.terraform_repo 1234567:terraform +$ terraform import github_team_repository.terraform_repo Administrators:terraform +``` diff --git a/docs/resources/team_settings.md b/docs/resources/team_settings.md new file mode 100644 index 0000000000..1ad4fae2a1 --- /dev/null +++ b/docs/resources/team_settings.md @@ -0,0 +1,63 @@ +--- +page_title: "github_team_settings Resource - terraform-provider-github +description: |- + Manages the team settings (in particular the request review delegation settings) +--- + +# github_team_settings (Resource) + +This resource manages the team settings (in particular the request review delegation settings) within the organization + +Creating this resource will alter the team Code Review settings. + +The team must both belong to the same organization configured in the provider on GitHub. + +~> **Note**: This resource relies on the v4 GraphQl GitHub API. If this API is not available, or the Stone Crop schema preview is not available, then this resource will not work as intended. + +## Example Usage + +```terraform +# Add a repository to the team +resource "github_team" "some_team" { + name = "SomeTeam" + description = "Some cool team" +} + +resource "github_team_settings" "code_review_settings" { + team_id = github_team.some_team.id + review_request_delegation { + algorithm = "ROUND_ROBIN" + member_count = 1 + notify = true + } +} +``` + +## Argument Reference + +The following arguments are supported: + +- `team_id` - (Required) The GitHub team id or the GitHub team slug +- `review_request_delegation` - (Optional) The settings for delegating code reviews to individuals on behalf of the team. If this block is present, even without any fields, then review request delegation will be enabled for the team. See [GitHub Review Request Delegation](#github-review-request-delegation-configuration) below for details. See [GitHub's documentation](https://docs.github.com/en/organizations/organizing-members-into-teams/managing-code-review-settings-for-your-team#configuring-team-notifications) for more configuration details. + +### GitHub Review Request Delegation Configuration + +The following arguments are supported: + +- `algorithm` - (Optional) The algorithm to use when assigning pull requests to team members. Supported values are `ROUND_ROBIN` and `LOAD_BALANCE`. Default value is `ROUND_ROBIN` +- `member_count` - (Optional) The number of team members to assign to a pull request +- `notify` - (Optional) whether to notify the entire team when at least one member is also assigned to the pull request + +## Import + +GitHub Teams can be imported using the GitHub team ID, or the team slug e.g. + +```sh +$ terraform import github_team.code_review_settings 1234567 +``` + +or, + +```sh +$ terraform import github_team_settings.code_review_settings SomeTeam +``` diff --git a/docs/resources/team_sync_group_mapping.md b/docs/resources/team_sync_group_mapping.md new file mode 100644 index 0000000000..d51732017f --- /dev/null +++ b/docs/resources/team_sync_group_mapping.md @@ -0,0 +1,55 @@ +--- +page_title: "github_team_sync_group_mapping Resource - terraform-provider-github +description: |- + Creates and manages the connections between a team and its IdP group(s). +--- + +# github_team_sync_group_mapping (Resource) + +This resource allows you to create and manage Identity Provider (IdP) group connections within your GitHub teams. You must have team synchronization enabled for organizations owned by enterprise accounts. + +To learn more about team synchronization between IdPs and GitHub, please refer to: [Managing team synchronization for your organization](https://help.github.com/en/github/setting-up-and-managing-organizations-and-teams/synchronizing-teams-between-your-identity-provider-and-github) + +## Example Usage + +```terraform +data "github_organization_team_sync_groups" "example_groups" {} + +resource "github_team_sync_group_mapping" "example_group_mapping" { + team_slug = "example" + + dynamic "group" { + for_each = [for g in data.github_organization_team_sync_groups.example_groups.groups : g if g.group_name == "some_team_group"] + content { + group_id = group.value.group_id + group_name = group.value.group_name + group_description = group.value.group_description + } + } +} +``` + +## Argument Reference + +The following arguments are supported: + +- `team_slug` - (Required) Slug of the team +- `group` - (Required) An Array of GitHub Identity Provider Groups (or empty []). Each `group` block consists of the fields documented below. + +--- + +The `group` block consists of: + +- `group_id` - The ID of the IdP group. + +- `group_name` - The name of the IdP group. + +- `group_description` - The description of the IdP group. + +## Import + +GitHub Team Sync Group Mappings can be imported using the GitHub team `slug` e.g. + +```sh +$ terraform import github_team_sync_group_mapping.example some_team +``` diff --git a/docs/resources/user_gpg_key.md b/docs/resources/user_gpg_key.md new file mode 100644 index 0000000000..fce7648153 --- /dev/null +++ b/docs/resources/user_gpg_key.md @@ -0,0 +1,36 @@ +--- +page_title: "github_user_gpg_key Resource - terraform-provider-github +description: |- + Provides a GitHub user's GPG key resource. +--- + +# github_user_gpg_key (Resource) + +Provides a GitHub user's GPG key resource. + +This resource allows you to add/remove GPG keys from your user account. + +## Example Usage + +```terraform +resource "github_user_gpg_key" "example" { + armored_public_key = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n...\n-----END PGP PUBLIC KEY BLOCK-----" +} +``` + +## Argument Reference + +The following arguments are supported: + +- `armored_public_key` - (Required) Your public GPG key, generated in ASCII-armored format. See [Generating a new GPG key](https://help.github.com/articles/generating-a-new-gpg-key/) for help on creating a GPG key. + +## Attributes Reference + +The following attributes are exported: + +- `id` - The GitHub ID of the GPG key, e.g. `401586` +- `key_id` - The key ID of the GPG key, e.g. `3262EFF25BA0D270` + +## Import + +GPG keys are not importable due to the fact that [API](https://developer.github.com/v3/users/gpg_keys/#gpg-keys) does not return previously uploaded GPG key. diff --git a/docs/resources/user_invitation_accepter.md b/docs/resources/user_invitation_accepter.md new file mode 100644 index 0000000000..ae2c3e0ba5 --- /dev/null +++ b/docs/resources/user_invitation_accepter.md @@ -0,0 +1,50 @@ +--- +page_title: "github_user_invitation_accepter Resource - terraform-provider-github +description: |- + Provides a resource to manage GitHub repository collaborator invitations. +--- + +# github_user_invitation_accepter (Resource) + +Provides a resource to manage GitHub repository collaborator invitations. + +## Example Usage + +```terraform +resource "github_repository" "example" { + name = "example-repo" +} + +resource "github_repository_collaborator" "example" { + repository = github_repository.example.name + username = "example-username" + permission = "push" +} + +provider "github" { + alias = "invitee" + token = var.invitee_token +} + +resource "github_user_invitation_accepter" "example" { + provider = "github.invitee" + invitation_id = github_repository_collaborator.example.invitation_id +} +``` + +## Allowing empty invitation IDs + +Set `allow_empty_id` when using `for_each` over a list of `github_repository_collaborator.invitation_id`'s. + +This allows applying a module again when a new `github_repository_collaborator` resource is added to the `for_each` loop. This is needed as the `github_repository_collaborator.invitation_id` will be empty after a state refresh when the invitation has been accepted. + +Note that when an invitation is accepted manually or by another tool between a state refresh and a `terraform apply` using that refreshed state, the plan will contain the invitation ID, but the apply will receive an HTTP 404 from the API since the invitation has already been accepted. + +This is tracked in [#1157](https://github.com/integrations/terraform-provider-github/issues/1157). + +## Argument Reference + +The following arguments are supported: + +- `invitation_id` - (Optional) ID of the invitation to accept. Must be set when `allow_empty_id` is `false`. +- `allow_empty_id` - (Optional) Allow the ID to be unset. This will result in the resource being skipped when the ID is not set instead of returning an error. diff --git a/docs/resources/user_ssh_key.md b/docs/resources/user_ssh_key.md new file mode 100644 index 0000000000..201668af8c --- /dev/null +++ b/docs/resources/user_ssh_key.md @@ -0,0 +1,42 @@ +--- +page_title: "github_user_ssh_key Resource - terraform-provider-github +description: |- + Provides a GitHub user's SSH key resource. +--- + +# github_user_ssh_key (Resource) + +Provides a GitHub user's SSH key resource. + +This resource allows you to add/remove SSH keys from your user account. + +## Example Usage + +```terraform +resource "github_user_ssh_key" "example" { + title = "example title" + key = file("~/.ssh/id_rsa.pub") +} +``` + +## Argument Reference + +The following arguments are supported: + +- `title` - (Required) A descriptive name for the new key. e.g. `Personal MacBook Air` +- `key` - (Required) The public SSH key to add to your GitHub account. + +## Attributes Reference + +The following attributes are exported: + +- `id` - The ID of the SSH key +- `url` - The URL of the SSH key + +## Import + +SSH keys can be imported using their ID e.g. + +```sh +$ terraform import github_user_ssh_key.example 1234567 +``` diff --git a/docs/resources/workflow_repository_permissions.md b/docs/resources/workflow_repository_permissions.md new file mode 100644 index 0000000000..7ba2d0692d --- /dev/null +++ b/docs/resources/workflow_repository_permissions.md @@ -0,0 +1,39 @@ +--- +page_title: "github_workflow_repository_permissions Resource - terraform-provider-github +description: |- + Enables and manages Workflow permissions for a GitHub repository +--- + +# github_workflow_repository_permissions (Resource) + +This resource allows you to manage GitHub Workflow permissions for a given repository. You must have admin access to a repository to use this resource. + +## Example Usage + +```terraform +resource "github_repository" "example" { + name = "my-repository" +} + +resource "github_workflow_repository_permissions" "test" { + default_workflow_permissions = "read" + can_approve_pull_request_reviews = true + repository = github_repository.example.name +} +``` + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The GitHub repository +- `default_workflow_permissions` - (Optional) The default workflow permissions granted to the GITHUB_TOKEN when running workflows. Can be one of: `read` or `write`. +- `can_approve_pull_request_reviews` - (Optional) Whether GitHub Actions can approve pull requests. Enabling this can be a security risk. + +## Import + +This resource can be imported using the name of the GitHub repository: + +```sh +$ terraform import github_workflow_repository_permissions.test my-repository +``` diff --git a/examples/data-sources/actions_environment_public_key/example_1.tf b/examples/data-sources/actions_environment_public_key/example_1.tf new file mode 100644 index 0000000000..250aa5fbcb --- /dev/null +++ b/examples/data-sources/actions_environment_public_key/example_1.tf @@ -0,0 +1,4 @@ +data "github_actions_environment_public_key" "example" { + repository = "example_repo" + environment = "example_environment" +} diff --git a/examples/data-sources/actions_environment_secrets/example_1.tf b/examples/data-sources/actions_environment_secrets/example_1.tf new file mode 100644 index 0000000000..4a619005c1 --- /dev/null +++ b/examples/data-sources/actions_environment_secrets/example_1.tf @@ -0,0 +1,4 @@ +data "github_actions_environment_secrets" "example" { + name = "exampleRepo" + environment = "exampleEnvironment" +} diff --git a/examples/data-sources/actions_environment_variables/example_1.tf b/examples/data-sources/actions_environment_variables/example_1.tf new file mode 100644 index 0000000000..81a85eaccb --- /dev/null +++ b/examples/data-sources/actions_environment_variables/example_1.tf @@ -0,0 +1,4 @@ +data "github_actions_environment_variables" "example" { + name = "exampleRepo" + environment = "exampleEnvironment" +} diff --git a/examples/data-sources/actions_organization_oidc_subject_claim_customization_template/example_1.tf b/examples/data-sources/actions_organization_oidc_subject_claim_customization_template/example_1.tf new file mode 100644 index 0000000000..be5ecb9002 --- /dev/null +++ b/examples/data-sources/actions_organization_oidc_subject_claim_customization_template/example_1.tf @@ -0,0 +1,2 @@ +data "github_actions_organization_oidc_subject_claim_customization_template" "example" { +} diff --git a/examples/data-sources/actions_organization_public_key/example_1.tf b/examples/data-sources/actions_organization_public_key/example_1.tf new file mode 100644 index 0000000000..cb13e7930a --- /dev/null +++ b/examples/data-sources/actions_organization_public_key/example_1.tf @@ -0,0 +1 @@ +data "github_actions_organization_public_key" "example" {} diff --git a/examples/data-sources/actions_organization_registration_token/example_1.tf b/examples/data-sources/actions_organization_registration_token/example_1.tf new file mode 100644 index 0000000000..bb6c6edd2e --- /dev/null +++ b/examples/data-sources/actions_organization_registration_token/example_1.tf @@ -0,0 +1,2 @@ +data "github_actions_organization_registration_token" "example" { +} diff --git a/examples/data-sources/actions_organization_secrets/example_1.tf b/examples/data-sources/actions_organization_secrets/example_1.tf new file mode 100644 index 0000000000..e9bf52a4f8 --- /dev/null +++ b/examples/data-sources/actions_organization_secrets/example_1.tf @@ -0,0 +1,2 @@ +data "github_actions_organization_secrets" "example" { +} diff --git a/examples/data-sources/actions_organization_variables/example_1.tf b/examples/data-sources/actions_organization_variables/example_1.tf new file mode 100644 index 0000000000..81c954e460 --- /dev/null +++ b/examples/data-sources/actions_organization_variables/example_1.tf @@ -0,0 +1,2 @@ +data "github_actions_organization_variables" "example" { +} diff --git a/examples/data-sources/actions_public_key/example_1.tf b/examples/data-sources/actions_public_key/example_1.tf new file mode 100644 index 0000000000..6ebd23a389 --- /dev/null +++ b/examples/data-sources/actions_public_key/example_1.tf @@ -0,0 +1,3 @@ +data "github_actions_public_key" "example" { + repository = "example_repo" +} diff --git a/examples/data-sources/actions_registration_token/example_1.tf b/examples/data-sources/actions_registration_token/example_1.tf new file mode 100644 index 0000000000..0ad6656fe1 --- /dev/null +++ b/examples/data-sources/actions_registration_token/example_1.tf @@ -0,0 +1,3 @@ +data "github_actions_registration_token" "example" { + repository = "example_repo" +} diff --git a/examples/data-sources/actions_repository_oidc_subject_claim_customization_template/example_1.tf b/examples/data-sources/actions_repository_oidc_subject_claim_customization_template/example_1.tf new file mode 100644 index 0000000000..bc94f6bba2 --- /dev/null +++ b/examples/data-sources/actions_repository_oidc_subject_claim_customization_template/example_1.tf @@ -0,0 +1,3 @@ +data "github_actions_repository_oidc_subject_claim_customization_template" "example" { + name = "example_repository" +} diff --git a/examples/data-sources/actions_secrets/example_1.tf b/examples/data-sources/actions_secrets/example_1.tf new file mode 100644 index 0000000000..89c4036f2a --- /dev/null +++ b/examples/data-sources/actions_secrets/example_1.tf @@ -0,0 +1,3 @@ +data "github_actions_secrets" "example" { + name = "example" +} diff --git a/examples/data-sources/actions_variables/example_1.tf b/examples/data-sources/actions_variables/example_1.tf new file mode 100644 index 0000000000..e6a62d67c3 --- /dev/null +++ b/examples/data-sources/actions_variables/example_1.tf @@ -0,0 +1,3 @@ +data "github_actions_variables" "example" { + name = "example" +} diff --git a/examples/data-sources/app_token/example_1.tf b/examples/data-sources/app_token/example_1.tf new file mode 100644 index 0000000000..2d578f3876 --- /dev/null +++ b/examples/data-sources/app_token/example_1.tf @@ -0,0 +1,5 @@ +data "github_app_token" "this" { + app_id = "123456" + installation_id = "78910" + pem_file = file("foo/bar.pem") +} diff --git a/examples/data-sources/branch/example_1.tf b/examples/data-sources/branch/example_1.tf new file mode 100644 index 0000000000..e78991a304 --- /dev/null +++ b/examples/data-sources/branch/example_1.tf @@ -0,0 +1,4 @@ +data "github_branch" "development" { + repository = "example" + branch = "development" +} diff --git a/examples/data-sources/branch_protection_rules/example_1.tf b/examples/data-sources/branch_protection_rules/example_1.tf new file mode 100644 index 0000000000..f829069632 --- /dev/null +++ b/examples/data-sources/branch_protection_rules/example_1.tf @@ -0,0 +1,3 @@ +data "github_branch_protection_rules" "example" { + repository = "example" +} diff --git a/examples/data-sources/codespaces_organization_public_key/example_1.tf b/examples/data-sources/codespaces_organization_public_key/example_1.tf new file mode 100644 index 0000000000..3fc45d0858 --- /dev/null +++ b/examples/data-sources/codespaces_organization_public_key/example_1.tf @@ -0,0 +1 @@ +data "github_codespaces_organization_public_key" "example" {} diff --git a/examples/data-sources/codespaces_organization_secrets/example_1.tf b/examples/data-sources/codespaces_organization_secrets/example_1.tf new file mode 100644 index 0000000000..a1cdf2742e --- /dev/null +++ b/examples/data-sources/codespaces_organization_secrets/example_1.tf @@ -0,0 +1,2 @@ +data "github_codespaces_organization_secrets" "example" { +} diff --git a/examples/data-sources/codespaces_public_key/example_1.tf b/examples/data-sources/codespaces_public_key/example_1.tf new file mode 100644 index 0000000000..4e40e874e6 --- /dev/null +++ b/examples/data-sources/codespaces_public_key/example_1.tf @@ -0,0 +1,3 @@ +data "github_codespaces_public_key" "example" { + repository = "example_repo" +} diff --git a/examples/data-sources/codespaces_secrets/example_1.tf b/examples/data-sources/codespaces_secrets/example_1.tf new file mode 100644 index 0000000000..c00b20454d --- /dev/null +++ b/examples/data-sources/codespaces_secrets/example_1.tf @@ -0,0 +1,7 @@ +data "github_codespaces_secrets" "example" { + name = "example_repository" +} + +data "github_codespaces_secrets" "example_2" { + full_name = "org/example_repository" +} diff --git a/examples/data-sources/codespaces_user_public_key/example_1.tf b/examples/data-sources/codespaces_user_public_key/example_1.tf new file mode 100644 index 0000000000..f2c40f1862 --- /dev/null +++ b/examples/data-sources/codespaces_user_public_key/example_1.tf @@ -0,0 +1 @@ +data "github_codespaces_user_public_key" "example" {} diff --git a/examples/data-sources/codespaces_user_secrets/example_1.tf b/examples/data-sources/codespaces_user_secrets/example_1.tf new file mode 100644 index 0000000000..9daa1908c1 --- /dev/null +++ b/examples/data-sources/codespaces_user_secrets/example_1.tf @@ -0,0 +1,2 @@ +data "github_codespaces_user_secrets" "example" { +} diff --git a/examples/data-sources/collaborators/example_1.tf b/examples/data-sources/collaborators/example_1.tf new file mode 100644 index 0000000000..cb25f12da8 --- /dev/null +++ b/examples/data-sources/collaborators/example_1.tf @@ -0,0 +1,4 @@ +data "github_collaborators" "test" { + owner = "example_owner" + repository = "example_repository" +} diff --git a/examples/data-sources/dependabot_organization_public_key/example_1.tf b/examples/data-sources/dependabot_organization_public_key/example_1.tf new file mode 100644 index 0000000000..52373c44d8 --- /dev/null +++ b/examples/data-sources/dependabot_organization_public_key/example_1.tf @@ -0,0 +1 @@ +data "github_dependabot_organization_public_key" "example" {} diff --git a/examples/data-sources/dependabot_organization_secrets/example_1.tf b/examples/data-sources/dependabot_organization_secrets/example_1.tf new file mode 100644 index 0000000000..4f92aec63d --- /dev/null +++ b/examples/data-sources/dependabot_organization_secrets/example_1.tf @@ -0,0 +1,2 @@ +data "github_dependabot_organization_secrets" "example" { +} diff --git a/examples/data-sources/dependabot_public_key/example_1.tf b/examples/data-sources/dependabot_public_key/example_1.tf new file mode 100644 index 0000000000..b650d702ab --- /dev/null +++ b/examples/data-sources/dependabot_public_key/example_1.tf @@ -0,0 +1,3 @@ +data "github_dependabot_public_key" "example" { + repository = "example_repo" +} diff --git a/examples/data-sources/dependabot_secrets/example_1.tf b/examples/data-sources/dependabot_secrets/example_1.tf new file mode 100644 index 0000000000..eef8dbc22d --- /dev/null +++ b/examples/data-sources/dependabot_secrets/example_1.tf @@ -0,0 +1,3 @@ +data "github_dependabot_secrets" "example" { + name = "example" +} diff --git a/examples/data-sources/external_groups/example_1.tf b/examples/data-sources/external_groups/example_1.tf new file mode 100644 index 0000000000..edf3625010 --- /dev/null +++ b/examples/data-sources/external_groups/example_1.tf @@ -0,0 +1,9 @@ +data "github_external_groups" "example_external_groups" {} + +locals { + local_groups = "${data.github_external_groups.example_external_groups}" +} + +output "groups" { + value = local.local_groups +} diff --git a/examples/data-sources/github_app/example_1.tf b/examples/data-sources/github_app/example_1.tf new file mode 100644 index 0000000000..e6dd3e0a51 --- /dev/null +++ b/examples/data-sources/github_app/example_1.tf @@ -0,0 +1,3 @@ +data "github_app" "foobar" { + slug = "foobar" +} diff --git a/examples/data-sources/ip_ranges/example_1.tf b/examples/data-sources/ip_ranges/example_1.tf new file mode 100644 index 0000000000..c1b4dd4083 --- /dev/null +++ b/examples/data-sources/ip_ranges/example_1.tf @@ -0,0 +1 @@ +data "github_ip_ranges" "test" {} diff --git a/examples/data-sources/issue_labels/example_1.tf b/examples/data-sources/issue_labels/example_1.tf new file mode 100644 index 0000000000..5e1deb5580 --- /dev/null +++ b/examples/data-sources/issue_labels/example_1.tf @@ -0,0 +1,3 @@ +data "github_issue_labels" "test" { + repository = "example_repository" +} diff --git a/examples/data-sources/membership/example_1.tf b/examples/data-sources/membership/example_1.tf new file mode 100644 index 0000000000..e3824a3b0f --- /dev/null +++ b/examples/data-sources/membership/example_1.tf @@ -0,0 +1,3 @@ +data "github_membership" "membership_for_some_user" { + username = "SomeUser" +} diff --git a/examples/data-sources/organization/example_1.tf b/examples/data-sources/organization/example_1.tf new file mode 100644 index 0000000000..8c59e7f212 --- /dev/null +++ b/examples/data-sources/organization/example_1.tf @@ -0,0 +1,3 @@ +data "github_organization" "example" { + name = "github" +} diff --git a/examples/data-sources/organization_custom_properties/example_1.tf b/examples/data-sources/organization_custom_properties/example_1.tf new file mode 100644 index 0000000000..5bda02686d --- /dev/null +++ b/examples/data-sources/organization_custom_properties/example_1.tf @@ -0,0 +1,3 @@ +data "github_organization_custom_properties" "environment" { + property_name = "environment" +} diff --git a/examples/data-sources/organization_custom_role/example_1.tf b/examples/data-sources/organization_custom_role/example_1.tf new file mode 100644 index 0000000000..469a9d2f16 --- /dev/null +++ b/examples/data-sources/organization_custom_role/example_1.tf @@ -0,0 +1,3 @@ +data "github_organization_custom_role" "example" { + name = "example" +} diff --git a/examples/data-sources/organization_external_identities/example_1.tf b/examples/data-sources/organization_external_identities/example_1.tf new file mode 100644 index 0000000000..3111709a63 --- /dev/null +++ b/examples/data-sources/organization_external_identities/example_1.tf @@ -0,0 +1 @@ +data "github_organization_external_identities" "all" {} diff --git a/examples/data-sources/organization_ip_allow_list/example_1.tf b/examples/data-sources/organization_ip_allow_list/example_1.tf new file mode 100644 index 0000000000..b86d8115a0 --- /dev/null +++ b/examples/data-sources/organization_ip_allow_list/example_1.tf @@ -0,0 +1 @@ +data "github_organization_ip_allow_list" "all" {} diff --git a/examples/data-sources/organization_repository_role/example_1.tf b/examples/data-sources/organization_repository_role/example_1.tf new file mode 100644 index 0000000000..52b359b824 --- /dev/null +++ b/examples/data-sources/organization_repository_role/example_1.tf @@ -0,0 +1,3 @@ +data "github_organization_repository_role" "example" { + role_id = 1234 +} diff --git a/examples/data-sources/organization_repository_roles/example_1.tf b/examples/data-sources/organization_repository_roles/example_1.tf new file mode 100644 index 0000000000..83ac79284c --- /dev/null +++ b/examples/data-sources/organization_repository_roles/example_1.tf @@ -0,0 +1,2 @@ +data "github_organization_repository_roles" "example" { +} diff --git a/examples/data-sources/organization_role/example_1.tf b/examples/data-sources/organization_role/example_1.tf new file mode 100644 index 0000000000..b747f2df0d --- /dev/null +++ b/examples/data-sources/organization_role/example_1.tf @@ -0,0 +1,3 @@ +data "github_organization_role" "example" { + role_id = 1234 +} diff --git a/examples/data-sources/organization_role_teams/example_1.tf b/examples/data-sources/organization_role_teams/example_1.tf new file mode 100644 index 0000000000..23721f4648 --- /dev/null +++ b/examples/data-sources/organization_role_teams/example_1.tf @@ -0,0 +1,3 @@ +data "github_organization_role_teams" "example" { + role_id = 1234 +} diff --git a/examples/data-sources/organization_role_users/example_1.tf b/examples/data-sources/organization_role_users/example_1.tf new file mode 100644 index 0000000000..62e2554343 --- /dev/null +++ b/examples/data-sources/organization_role_users/example_1.tf @@ -0,0 +1,3 @@ +data "github_organization_role_users" "example" { + role_id = 1234 +} diff --git a/examples/data-sources/organization_roles/example_1.tf b/examples/data-sources/organization_roles/example_1.tf new file mode 100644 index 0000000000..ad06a5fd68 --- /dev/null +++ b/examples/data-sources/organization_roles/example_1.tf @@ -0,0 +1,2 @@ +data "github_organization_roles" "example" { +} diff --git a/examples/data-sources/organization_security_managers/example_1.tf b/examples/data-sources/organization_security_managers/example_1.tf new file mode 100644 index 0000000000..a8cb38d5a8 --- /dev/null +++ b/examples/data-sources/organization_security_managers/example_1.tf @@ -0,0 +1 @@ +data "github_organization_security_managers" "test" {} diff --git a/examples/data-sources/organization_team_sync_groups/example_1.tf b/examples/data-sources/organization_team_sync_groups/example_1.tf new file mode 100644 index 0000000000..19c77b153c --- /dev/null +++ b/examples/data-sources/organization_team_sync_groups/example_1.tf @@ -0,0 +1 @@ +data "github_organization_team_sync_groups" "test" {} diff --git a/examples/data-sources/organization_teams/example_1.tf b/examples/data-sources/organization_teams/example_1.tf new file mode 100644 index 0000000000..29688f01f4 --- /dev/null +++ b/examples/data-sources/organization_teams/example_1.tf @@ -0,0 +1 @@ +data "github_organization_teams" "all" {} diff --git a/examples/data-sources/organization_teams/example_2.tf b/examples/data-sources/organization_teams/example_2.tf new file mode 100644 index 0000000000..10ad7ef2c5 --- /dev/null +++ b/examples/data-sources/organization_teams/example_2.tf @@ -0,0 +1,3 @@ +data "github_organization_teams" "root_teams" { + root_teams_only = true +} diff --git a/examples/data-sources/organization_webhooks/example_1.tf b/examples/data-sources/organization_webhooks/example_1.tf new file mode 100644 index 0000000000..89b1a08651 --- /dev/null +++ b/examples/data-sources/organization_webhooks/example_1.tf @@ -0,0 +1 @@ +data "github_organization_webhooks" "all" {} diff --git a/examples/data-sources/ref/example_1.tf b/examples/data-sources/ref/example_1.tf new file mode 100644 index 0000000000..cc0d570d41 --- /dev/null +++ b/examples/data-sources/ref/example_1.tf @@ -0,0 +1,5 @@ +data "github_ref" "development" { + owner = "example" + repository = "example" + ref = "heads/development" +} diff --git a/examples/data-sources/release/example_1.tf b/examples/data-sources/release/example_1.tf new file mode 100644 index 0000000000..45b5edb97b --- /dev/null +++ b/examples/data-sources/release/example_1.tf @@ -0,0 +1,5 @@ +data "github_release" "example" { + repository = "example-repository" + owner = "example-owner" + retrieve_by = "latest" +} diff --git a/examples/data-sources/release/example_2.tf b/examples/data-sources/release/example_2.tf new file mode 100644 index 0000000000..83049e0c2c --- /dev/null +++ b/examples/data-sources/release/example_2.tf @@ -0,0 +1,6 @@ +data "github_release" "example" { + repository = "example-repository" + owner = "example-owner" + retrieve_by = "id" + id = 12345 +} diff --git a/examples/data-sources/release/example_3.tf b/examples/data-sources/release/example_3.tf new file mode 100644 index 0000000000..d64cc031a1 --- /dev/null +++ b/examples/data-sources/release/example_3.tf @@ -0,0 +1,6 @@ +data "github_release" "example" { + repository = "example-repository" + owner = "example-owner" + retrieve_by = "tag" + release_tag = "v1.0.0" +} diff --git a/examples/data-sources/repositories/example_1.tf b/examples/data-sources/repositories/example_1.tf new file mode 100644 index 0000000000..d1ab5892a7 --- /dev/null +++ b/examples/data-sources/repositories/example_1.tf @@ -0,0 +1,4 @@ +data "github_repositories" "example" { + query = "org:hashicorp language:Go" + include_repo_id = true +} diff --git a/examples/data-sources/repository/example_1.tf b/examples/data-sources/repository/example_1.tf new file mode 100644 index 0000000000..f1a2db8b84 --- /dev/null +++ b/examples/data-sources/repository/example_1.tf @@ -0,0 +1,3 @@ +data "github_repository" "example" { + full_name = "hashicorp/terraform" +} diff --git a/examples/data-sources/repository_autolink_references/example_1.tf b/examples/data-sources/repository_autolink_references/example_1.tf new file mode 100644 index 0000000000..404eedbda7 --- /dev/null +++ b/examples/data-sources/repository_autolink_references/example_1.tf @@ -0,0 +1,3 @@ +data "github_repository_autolink_references" "example" { + repository = "example-repository" +} diff --git a/examples/data-sources/repository_branches/example_1.tf b/examples/data-sources/repository_branches/example_1.tf new file mode 100644 index 0000000000..d6a2104b83 --- /dev/null +++ b/examples/data-sources/repository_branches/example_1.tf @@ -0,0 +1,3 @@ +data "github_repository_branches" "example" { + repository = "example-repository" +} diff --git a/examples/data-sources/repository_custom_properties/example_1.tf b/examples/data-sources/repository_custom_properties/example_1.tf new file mode 100644 index 0000000000..afdabd2545 --- /dev/null +++ b/examples/data-sources/repository_custom_properties/example_1.tf @@ -0,0 +1,3 @@ +data "github_repository_custom_properties" "example" { + repository = "example-repository" +} diff --git a/examples/data-sources/repository_deploy_keys/example_1.tf b/examples/data-sources/repository_deploy_keys/example_1.tf new file mode 100644 index 0000000000..fe8507aedf --- /dev/null +++ b/examples/data-sources/repository_deploy_keys/example_1.tf @@ -0,0 +1,3 @@ +data "github_repository_deploy_keys" "example" { + repository = "example-repository" +} diff --git a/examples/data-sources/repository_deployment_branch_policies/example_1.tf b/examples/data-sources/repository_deployment_branch_policies/example_1.tf new file mode 100644 index 0000000000..6c4e7fbc1d --- /dev/null +++ b/examples/data-sources/repository_deployment_branch_policies/example_1.tf @@ -0,0 +1,4 @@ +data "github_repository_deployment_branch_policies" "example" { + repository = "example-repository" + environment_name = "env_name" +} diff --git a/examples/data-sources/repository_environment_deployment_policies/example_1.tf b/examples/data-sources/repository_environment_deployment_policies/example_1.tf new file mode 100644 index 0000000000..1df14bce56 --- /dev/null +++ b/examples/data-sources/repository_environment_deployment_policies/example_1.tf @@ -0,0 +1,4 @@ +data "github_repository_environment_deployment_policies" "example" { + repository = "example-repository" + environment = "env-name" +} diff --git a/examples/data-sources/repository_environments/example_1.tf b/examples/data-sources/repository_environments/example_1.tf new file mode 100644 index 0000000000..6b5b7ed1de --- /dev/null +++ b/examples/data-sources/repository_environments/example_1.tf @@ -0,0 +1,3 @@ +data "github_repository_environments" "example" { + repository = "example-repository" +} diff --git a/examples/data-sources/repository_file/example_1.tf b/examples/data-sources/repository_file/example_1.tf new file mode 100644 index 0000000000..ea7be268b9 --- /dev/null +++ b/examples/data-sources/repository_file/example_1.tf @@ -0,0 +1,6 @@ +data "github_repository_file" "foo" { + repository = github_repository.foo.name + branch = "main" + file = ".gitignore" +} + diff --git a/examples/data-sources/repository_milestone/example_1.tf b/examples/data-sources/repository_milestone/example_1.tf new file mode 100644 index 0000000000..a30d0b9655 --- /dev/null +++ b/examples/data-sources/repository_milestone/example_1.tf @@ -0,0 +1,5 @@ +data "github_repository_milestone" "example" { + owner = "example-owner" + repository = "example-repository" + number = 1 +} diff --git a/examples/data-sources/repository_pull_request/example_1.tf b/examples/data-sources/repository_pull_request/example_1.tf new file mode 100644 index 0000000000..365eab9685 --- /dev/null +++ b/examples/data-sources/repository_pull_request/example_1.tf @@ -0,0 +1,4 @@ +data "github_repository_pull_request" "example" { + base_repository = "example_repository" + number = 1 +} diff --git a/examples/data-sources/repository_pull_requests/example_1.tf b/examples/data-sources/repository_pull_requests/example_1.tf new file mode 100644 index 0000000000..39bda8efbe --- /dev/null +++ b/examples/data-sources/repository_pull_requests/example_1.tf @@ -0,0 +1,7 @@ +data "github_repository_pull_requests" "example" { + base_repository = "example-repository" + base_ref = "main" + sort_by = "updated" + sort_direction = "desc" + state = "open" +} diff --git a/examples/data-sources/repository_teams/example_1.tf b/examples/data-sources/repository_teams/example_1.tf new file mode 100644 index 0000000000..f507ba7a3f --- /dev/null +++ b/examples/data-sources/repository_teams/example_1.tf @@ -0,0 +1,3 @@ +data "github_repository_teams" "example" { + name = "example" +} diff --git a/examples/data-sources/repository_webhooks/example_1.tf b/examples/data-sources/repository_webhooks/example_1.tf new file mode 100644 index 0000000000..d740a8a02f --- /dev/null +++ b/examples/data-sources/repository_webhooks/example_1.tf @@ -0,0 +1,3 @@ +data "github_repository_webhooks" "repo" { + repository = "foo" +} diff --git a/examples/data-sources/rest_api/example_1.tf b/examples/data-sources/rest_api/example_1.tf new file mode 100644 index 0000000000..c0a2ca49cc --- /dev/null +++ b/examples/data-sources/rest_api/example_1.tf @@ -0,0 +1,3 @@ +data "github_rest_api" "example" { + endpoint = "repos/example_repo/git/refs/heads/main" +} diff --git a/examples/data-sources/ssh_keys/example_1.tf b/examples/data-sources/ssh_keys/example_1.tf new file mode 100644 index 0000000000..72159b2f54 --- /dev/null +++ b/examples/data-sources/ssh_keys/example_1.tf @@ -0,0 +1 @@ +data "github_ssh_keys" "test" {} diff --git a/examples/data-sources/team/example_1.tf b/examples/data-sources/team/example_1.tf new file mode 100644 index 0000000000..9769d1b1e4 --- /dev/null +++ b/examples/data-sources/team/example_1.tf @@ -0,0 +1,3 @@ +data "github_team" "example" { + slug = "example" +} diff --git a/examples/data-sources/tree/example_1.tf b/examples/data-sources/tree/example_1.tf new file mode 100644 index 0000000000..f071612178 --- /dev/null +++ b/examples/data-sources/tree/example_1.tf @@ -0,0 +1,19 @@ +data "github_repository" "this" { + name = "example" +} + +data "github_branch" "this" { + branch = data.github_repository.this.default_branch + repository = data.github_repository.this.name +} + +data "github_tree" "this" { + recursive = false + repository = data.github_repository.this.name + tree_sha = data.github_branch.this.sha +} + +output "entries" { + value = data.github_tree.this.entries +} + diff --git a/examples/data-sources/user/example_1.tf b/examples/data-sources/user/example_1.tf new file mode 100644 index 0000000000..f710c1b62b --- /dev/null +++ b/examples/data-sources/user/example_1.tf @@ -0,0 +1,14 @@ +# Retrieve information about a GitHub user. +data "github_user" "example" { + username = "example" +} + +# Retrieve information about the currently authenticated user. +data "github_user" "current" { + username = "" +} + +output "current_github_login" { + value = "${data.github_user.current.login}" +} + diff --git a/examples/data-sources/user_external_identity/example_1.tf b/examples/data-sources/user_external_identity/example_1.tf new file mode 100644 index 0000000000..c4df822cd5 --- /dev/null +++ b/examples/data-sources/user_external_identity/example_1.tf @@ -0,0 +1,3 @@ +data "github_user_external_identity" "example_user" { + username = "example-user" +} diff --git a/examples/data-sources/users/example_1.tf b/examples/data-sources/users/example_1.tf new file mode 100644 index 0000000000..aa6c03589e --- /dev/null +++ b/examples/data-sources/users/example_1.tf @@ -0,0 +1,12 @@ +# Retrieve information about multiple GitHub users. +data "github_users" "example" { + usernames = ["example1", "example2", "example3"] +} + +output "valid_users" { + value = "${data.github_users.example.logins}" +} + +output "invalid_users" { + value = "${data.github_users.example.unknown_logins}" +} diff --git a/examples/example_1.tf b/examples/example_1.tf new file mode 100644 index 0000000000..285894e915 --- /dev/null +++ b/examples/example_1.tf @@ -0,0 +1,16 @@ +terraform { + required_providers { + github = { + source = "integrations/github" + version = "~> 6.0" + } + } +} + +# Configure the GitHub Provider +provider "github" {} + +# Add a user to the organization +resource "github_membership" "membership_for_user_x" { + # ... +} diff --git a/examples/example_2.tf b/examples/example_2.tf new file mode 100644 index 0000000000..247641b8a0 --- /dev/null +++ b/examples/example_2.tf @@ -0,0 +1,9 @@ +# Configure the GitHub Provider +provider "github" { + version = "~> 5.0" +} + +# Add a user to the organization +resource "github_membership" "membership_for_user_x" { + # ... +} diff --git a/examples/example_3.tf b/examples/example_3.tf new file mode 100644 index 0000000000..0e0f42fb61 --- /dev/null +++ b/examples/example_3.tf @@ -0,0 +1,3 @@ +provider "github" { + token = var.token # or `GITHUB_TOKEN` +} diff --git a/examples/example_4.tf b/examples/example_4.tf new file mode 100644 index 0000000000..abf529aae9 --- /dev/null +++ b/examples/example_4.tf @@ -0,0 +1,8 @@ +provider "github" { + owner = var.github_organization + app_auth { + id = var.app_id # or `GITHUB_APP_ID` + installation_id = var.app_installation_id # or `GITHUB_APP_INSTALLATION_ID` + pem_file = var.app_pem_file # or `GITHUB_APP_PEM_FILE` + } +} diff --git a/examples/example_5.tf b/examples/example_5.tf new file mode 100644 index 0000000000..0c3fb2cfd9 --- /dev/null +++ b/examples/example_5.tf @@ -0,0 +1,4 @@ +provider "github" { + owner = var.github_organization + app_auth {} # When using `GITHUB_APP_XXX` environment variables +} diff --git a/examples/resources/actions_environment_secret/example_1.tf b/examples/resources/actions_environment_secret/example_1.tf new file mode 100644 index 0000000000..1907a5fa5d --- /dev/null +++ b/examples/resources/actions_environment_secret/example_1.tf @@ -0,0 +1,11 @@ +resource "github_actions_environment_secret" "example_secret" { + environment = "example_environment" + secret_name = "example_secret_name" + plaintext_value = var.some_secret_string +} + +resource "github_actions_environment_secret" "example_secret" { + environment = "example_environment" + secret_name = "example_secret_name" + encrypted_value = var.some_encrypted_secret_string +} diff --git a/examples/resources/actions_environment_secret/example_2.tf b/examples/resources/actions_environment_secret/example_2.tf new file mode 100644 index 0000000000..32b7a6b3f5 --- /dev/null +++ b/examples/resources/actions_environment_secret/example_2.tf @@ -0,0 +1,15 @@ +data "github_repository" "repo" { + full_name = "my-org/repo" +} + +resource "github_repository_environment" "repo_environment" { + repository = data.github_repository.repo.name + environment = "example_environment" +} + +resource "github_actions_environment_secret" "test_secret" { + repository = data.github_repository.repo.name + environment = github_repository_environment.repo_environment.environment + secret_name = "test_secret_name" + plaintext_value = "%s" +} diff --git a/examples/resources/actions_environment_secret/example_3.tf b/examples/resources/actions_environment_secret/example_3.tf new file mode 100644 index 0000000000..d22f4705bd --- /dev/null +++ b/examples/resources/actions_environment_secret/example_3.tf @@ -0,0 +1,19 @@ +resource "github_actions_environment_secret" "example_secret" { + environment = "example_environment" + secret_name = "example_secret_name" + plaintext_value = "placeholder" + + lifecycle { + ignore_changes = [plaintext_value] + } +} + +resource "github_actions_environment_secret" "example_secret" { + environment = "example_environment" + secret_name = "example_secret_name" + encrypted_value = base64sha256("placeholder") + + lifecycle { + ignore_changes = [encrypted_value] + } +} diff --git a/examples/resources/actions_environment_variable/example_1.tf b/examples/resources/actions_environment_variable/example_1.tf new file mode 100644 index 0000000000..19de4b541d --- /dev/null +++ b/examples/resources/actions_environment_variable/example_1.tf @@ -0,0 +1,6 @@ +resource "github_actions_environment_variable" "example_variable" { + environment = "example_environment" + repository = "example_repository" + value = "example_variable_value" + variable_name = "example_variable_name" +} diff --git a/examples/resources/actions_environment_variable/example_2.tf b/examples/resources/actions_environment_variable/example_2.tf new file mode 100644 index 0000000000..7d4968e913 --- /dev/null +++ b/examples/resources/actions_environment_variable/example_2.tf @@ -0,0 +1,15 @@ +data "github_repository" "repo" { + full_name = "my-org/repo" +} + +resource "github_repository_environment" "repo_environment" { + repository = data.github_repository.repo.name + environment = "example_environment" +} + +resource "github_actions_environment_variable" "example_variable" { + repository = data.github_repository.repo.name + environment = github_repository_environment.repo_environment.environment + variable_name = "example_variable_name" + value = "example_variable_value" +} diff --git a/examples/resources/actions_hosted_runner/example_1.tf b/examples/resources/actions_hosted_runner/example_1.tf new file mode 100644 index 0000000000..f6bb0ceffb --- /dev/null +++ b/examples/resources/actions_hosted_runner/example_1.tf @@ -0,0 +1,16 @@ +resource "github_actions_runner_group" "example" { + name = "example-runner-group" + visibility = "all" +} + +resource "github_actions_hosted_runner" "example" { + name = "example-hosted-runner" + + image { + id = "2306" + source = "github" + } + + size = "4-core" + runner_group_id = github_actions_runner_group.example.id +} diff --git a/examples/resources/actions_hosted_runner/example_2.tf b/examples/resources/actions_hosted_runner/example_2.tf new file mode 100644 index 0000000000..208eca1d3b --- /dev/null +++ b/examples/resources/actions_hosted_runner/example_2.tf @@ -0,0 +1,18 @@ +resource "github_actions_runner_group" "advanced" { + name = "advanced-runner-group" + visibility = "selected" +} + +resource "github_actions_hosted_runner" "advanced" { + name = "advanced-hosted-runner" + + image { + id = "2306" + source = "github" + } + + size = "8-core" + runner_group_id = github_actions_runner_group.advanced.id + maximum_runners = 10 + public_ip_enabled = true +} diff --git a/examples/resources/actions_hosted_runner/example_3.tf b/examples/resources/actions_hosted_runner/example_3.tf new file mode 100644 index 0000000000..76b6fd7ce4 --- /dev/null +++ b/examples/resources/actions_hosted_runner/example_3.tf @@ -0,0 +1,15 @@ +resource "github_actions_hosted_runner" "example" { + name = "example-hosted-runner" + + image { + id = "2306" + source = "github" + } + + size = "4-core" + runner_group_id = github_actions_runner_group.example.id + + timeouts { + delete = "15m" + } +} diff --git a/examples/resources/actions_organization_oidc_subject_claim_customization_template/example_1.tf b/examples/resources/actions_organization_oidc_subject_claim_customization_template/example_1.tf new file mode 100644 index 0000000000..ac86ab0f65 --- /dev/null +++ b/examples/resources/actions_organization_oidc_subject_claim_customization_template/example_1.tf @@ -0,0 +1,3 @@ +resource "github_actions_organization_oidc_subject_claim_customization_template" "example_template" { + include_claim_keys = ["actor", "context", "repository_owner"] +} diff --git a/examples/resources/actions_organization_permissions/example_1.tf b/examples/resources/actions_organization_permissions/example_1.tf new file mode 100644 index 0000000000..88669ca6f8 --- /dev/null +++ b/examples/resources/actions_organization_permissions/example_1.tf @@ -0,0 +1,16 @@ +resource "github_repository" "example" { + name = "my-repository" +} + +resource "github_actions_organization_permissions" "test" { + allowed_actions = "selected" + enabled_repositories = "selected" + allowed_actions_config { + github_owned_allowed = true + patterns_allowed = ["actions/cache@*", "actions/checkout@*"] + verified_allowed = true + } + enabled_repositories_config { + repository_ids = [github_repository.example.repo_id] + } +} diff --git a/examples/resources/actions_organization_secret/example_1.tf b/examples/resources/actions_organization_secret/example_1.tf new file mode 100644 index 0000000000..f4998bdc09 --- /dev/null +++ b/examples/resources/actions_organization_secret/example_1.tf @@ -0,0 +1,11 @@ +resource "github_actions_organization_secret" "example_secret" { + secret_name = "example_secret_name" + visibility = "private" + plaintext_value = var.some_secret_string +} + +resource "github_actions_organization_secret" "example_secret" { + secret_name = "example_secret_name" + visibility = "private" + encrypted_value = var.some_encrypted_secret_string +} diff --git a/examples/resources/actions_organization_secret/example_2.tf b/examples/resources/actions_organization_secret/example_2.tf new file mode 100644 index 0000000000..1bab21493b --- /dev/null +++ b/examples/resources/actions_organization_secret/example_2.tf @@ -0,0 +1,17 @@ +data "github_repository" "repo" { + full_name = "my-org/repo" +} + +resource "github_actions_organization_secret" "example_secret" { + secret_name = "example_secret_name" + visibility = "selected" + plaintext_value = var.some_secret_string + selected_repository_ids = [data.github_repository.repo.repo_id] +} + +resource "github_actions_organization_secret" "example_secret" { + secret_name = "example_secret_name" + visibility = "selected" + encrypted_value = var.some_encrypted_secret_string + selected_repository_ids = [data.github_repository.repo.repo_id] +} diff --git a/examples/resources/actions_organization_secret_repositories/example_1.tf b/examples/resources/actions_organization_secret_repositories/example_1.tf new file mode 100644 index 0000000000..e3ae1ffa1b --- /dev/null +++ b/examples/resources/actions_organization_secret_repositories/example_1.tf @@ -0,0 +1,8 @@ +data "github_repository" "repo" { + full_name = "my-org/repo" +} + +resource "github_actions_organization_secret_repositories" "org_secret_repos" { + secret_name = "existing_secret_name" + selected_repository_ids = [data.github_repository.repo.repo_id] +} diff --git a/examples/resources/actions_organization_secret_repository/example_1.tf b/examples/resources/actions_organization_secret_repository/example_1.tf new file mode 100644 index 0000000000..d00e0016b8 --- /dev/null +++ b/examples/resources/actions_organization_secret_repository/example_1.tf @@ -0,0 +1,8 @@ +data "github_repository" "repo" { + full_name = "my-org/repo" +} + +resource "github_actions_organization_secret_repository" "org_secret_repos" { + secret_name = "EXAMPLE_SECRET_NAME" + repository_id = github_repository.repo.repo_id +} diff --git a/examples/resources/actions_organization_variable/example_1.tf b/examples/resources/actions_organization_variable/example_1.tf new file mode 100644 index 0000000000..5c6bc79ea6 --- /dev/null +++ b/examples/resources/actions_organization_variable/example_1.tf @@ -0,0 +1,5 @@ +resource "github_actions_organization_variable" "example_variable" { + variable_name = "example_variable_name" + visibility = "private" + value = "example_variable_value" +} diff --git a/examples/resources/actions_organization_variable/example_2.tf b/examples/resources/actions_organization_variable/example_2.tf new file mode 100644 index 0000000000..cb19a329da --- /dev/null +++ b/examples/resources/actions_organization_variable/example_2.tf @@ -0,0 +1,10 @@ +data "github_repository" "repo" { + full_name = "my-org/repo" +} + +resource "github_actions_organization_variable" "example_variable" { + variable_name = "example_variable_name" + visibility = "selected" + value = "example_variable_value" + selected_repository_ids = [data.github_repository.repo.repo_id] +} diff --git a/examples/resources/actions_repository_access_level/example_1.tf b/examples/resources/actions_repository_access_level/example_1.tf new file mode 100644 index 0000000000..6ea586b92d --- /dev/null +++ b/examples/resources/actions_repository_access_level/example_1.tf @@ -0,0 +1,9 @@ +resource "github_repository" "example" { + name = "my-repository" + visibility = "private" +} + +resource "github_actions_repository_access_level" "test" { + access_level = "user" + repository = github_repository.example.name +} diff --git a/examples/resources/actions_repository_oidc_subject_claim_customization_template/example_1.tf b/examples/resources/actions_repository_oidc_subject_claim_customization_template/example_1.tf new file mode 100644 index 0000000000..6bbb26b4d6 --- /dev/null +++ b/examples/resources/actions_repository_oidc_subject_claim_customization_template/example_1.tf @@ -0,0 +1,9 @@ +resource "github_repository" "example" { + name = "example-repository" +} + +resource "github_actions_repository_oidc_subject_claim_customization_template" "example_template" { + repository = github_repository.example.name + use_default = false + include_claim_keys = ["actor", "context", "repository_owner"] +} diff --git a/examples/resources/actions_repository_permissions/example_1.tf b/examples/resources/actions_repository_permissions/example_1.tf new file mode 100644 index 0000000000..f5ca96575f --- /dev/null +++ b/examples/resources/actions_repository_permissions/example_1.tf @@ -0,0 +1,13 @@ +resource "github_repository" "example" { + name = "my-repository" +} + +resource "github_actions_repository_permissions" "test" { + allowed_actions = "selected" + allowed_actions_config { + github_owned_allowed = true + patterns_allowed = ["actions/cache@*", "actions/checkout@*"] + verified_allowed = true + } + repository = github_repository.example.name +} diff --git a/examples/resources/actions_runner_group/example_1.tf b/examples/resources/actions_runner_group/example_1.tf new file mode 100644 index 0000000000..88a1344df2 --- /dev/null +++ b/examples/resources/actions_runner_group/example_1.tf @@ -0,0 +1,9 @@ +resource "github_repository" "example" { + name = "my-repository" +} + +resource "github_actions_runner_group" "example" { + name = github_repository.example.name + visibility = "selected" + selected_repository_ids = [github_repository.example.repo_id] +} diff --git a/examples/resources/actions_secret/example_1.tf b/examples/resources/actions_secret/example_1.tf new file mode 100644 index 0000000000..cc7fc63cd2 --- /dev/null +++ b/examples/resources/actions_secret/example_1.tf @@ -0,0 +1,15 @@ +data "github_actions_public_key" "example_public_key" { + repository = "example_repository" +} + +resource "github_actions_secret" "example_secret" { + repository = "example_repository" + secret_name = "example_secret_name" + plaintext_value = var.some_secret_string +} + +resource "github_actions_secret" "example_secret" { + repository = "example_repository" + secret_name = "example_secret_name" + encrypted_value = var.some_encrypted_secret_string +} diff --git a/examples/resources/actions_variable/example_1.tf b/examples/resources/actions_variable/example_1.tf new file mode 100644 index 0000000000..5e6c49f4b2 --- /dev/null +++ b/examples/resources/actions_variable/example_1.tf @@ -0,0 +1,5 @@ +resource "github_actions_variable" "example_variable" { + repository = "example_repository" + variable_name = "example_variable_name" + value = "example_variable_value" +} diff --git a/examples/resources/app_installation_repositories/example_1.tf b/examples/resources/app_installation_repositories/example_1.tf new file mode 100644 index 0000000000..c4546acb20 --- /dev/null +++ b/examples/resources/app_installation_repositories/example_1.tf @@ -0,0 +1,14 @@ +# Create some repositories. +resource "github_repository" "some_repo" { + name = "some-repo" +} + +resource "github_repository" "another_repo" { + name = "another-repo" +} + +resource "github_app_installation_repositories" "some_app_repos" { + # The installation id of the app (in the organization). + installation_id = "1234567" + selected_repositories = [github_repository.some_repo.name, github_repository.another_repo.name]" +} diff --git a/examples/resources/app_installation_repository/example_1.tf b/examples/resources/app_installation_repository/example_1.tf new file mode 100644 index 0000000000..507b11aa3c --- /dev/null +++ b/examples/resources/app_installation_repository/example_1.tf @@ -0,0 +1,10 @@ +# Create a repository. +resource "github_repository" "some_repo" { + name = "some-repo" +} + +resource "github_app_installation_repository" "some_app_repo" { + # The installation id of the app (in the organization). + installation_id = "1234567" + repository = "${github_repository.some_repo.name}" +} diff --git a/examples/resources/branch/example_1.tf b/examples/resources/branch/example_1.tf new file mode 100644 index 0000000000..d6b2903047 --- /dev/null +++ b/examples/resources/branch/example_1.tf @@ -0,0 +1,4 @@ +resource "github_branch" "development" { + repository = "example" + branch = "development" +} diff --git a/examples/resources/branch_default/example_1.tf b/examples/resources/branch_default/example_1.tf new file mode 100644 index 0000000000..df374ac288 --- /dev/null +++ b/examples/resources/branch_default/example_1.tf @@ -0,0 +1,15 @@ +resource "github_repository" "example" { + name = "example" + description = "My awesome codebase" + auto_init = true +} + +resource "github_branch" "development" { + repository = github_repository.example.name + branch = "development" +} + +resource "github_branch_default" "default"{ + repository = github_repository.example.name + branch = github_branch.development.branch +} diff --git a/examples/resources/branch_default/example_2.tf b/examples/resources/branch_default/example_2.tf new file mode 100644 index 0000000000..8a16ba1310 --- /dev/null +++ b/examples/resources/branch_default/example_2.tf @@ -0,0 +1,11 @@ +resource "github_repository" "example" { + name = "example" + description = "My awesome codebase" + auto_init = true +} + +resource "github_branch_default" "default"{ + repository = github_repository.example.name + branch = "development" + rename = true +} diff --git a/examples/resources/branch_protection/example_1.tf b/examples/resources/branch_protection/example_1.tf new file mode 100644 index 0000000000..5ce40014a9 --- /dev/null +++ b/examples/resources/branch_protection/example_1.tf @@ -0,0 +1,69 @@ +# Protect the main branch of the foo repository. Additionally, require that +# the "ci/travis" context to be passing and only allow the engineers team merge +# to the branch. + +resource "github_branch_protection" "example" { + repository_id = github_repository.example.node_id + # also accepts repository name + # repository_id = github_repository.example.name + + pattern = "main" + enforce_admins = true + allows_deletions = true + + required_status_checks { + strict = false + contexts = ["ci/travis"] + } + + required_pull_request_reviews { + dismiss_stale_reviews = true + restrict_dismissals = true + dismissal_restrictions = [ + data.github_user.example.node_id, + github_team.example.node_id, + "/exampleuser", + "exampleorganization/exampleteam", + ] + } + + restrict_pushes { + push_allowances = [ + data.github_user.example.node_id, + "/exampleuser", + "exampleorganization/exampleteam", + # you can have more than one type of restriction (teams + users). If you use + # more than one type, you must use node_ids of each user and each team. + # github_team.example.node_id + # github_user.example-2.node_id + ] + } + + force_push_bypassers = [ + data.github_user.example.node_id, + "/exampleuser", + "exampleorganization/exampleteam", + # you can have more than one type of restriction (teams + users) + # github_team.example.node_id + # github_team.example-2.node_id + ] + +} + +resource "github_repository" "example" { + name = "test" +} + +data "github_user" "example" { + username = "example" +} + +resource "github_team" "example" { + name = "Example Name" +} + +resource "github_team_repository" "example" { + team_id = github_team.example.id + repository = github_repository.example.name + permission = "pull" +} diff --git a/examples/resources/branch_protection_v3/example_1.tf b/examples/resources/branch_protection_v3/example_1.tf new file mode 100644 index 0000000000..7f435b6c62 --- /dev/null +++ b/examples/resources/branch_protection_v3/example_1.tf @@ -0,0 +1,9 @@ +# Protect the main branch of the foo repository. Only allow a specific user to merge to the branch. +resource "github_branch_protection_v3" "example" { + repository = github_repository.example.name + branch = "main" + + restrictions { + users = ["foo-user"] + } +} diff --git a/examples/resources/branch_protection_v3/example_2.tf b/examples/resources/branch_protection_v3/example_2.tf new file mode 100644 index 0000000000..22ef55ce15 --- /dev/null +++ b/examples/resources/branch_protection_v3/example_2.tf @@ -0,0 +1,49 @@ +# Protect the main branch of the foo repository. Additionally, require that +# the "ci/check" check ran by the Github Actions app is passing and only allow +# the engineers team merge to the branch. + +resource "github_branch_protection_v3" "example" { + repository = github_repository.example.name + branch = "main" + enforce_admins = true + + required_status_checks { + strict = false + checks = [ + "ci/check:824642007264" + ] + } + + required_pull_request_reviews { + dismiss_stale_reviews = true + dismissal_users = ["foo-user"] + dismissal_teams = [github_team.example.slug] + dismissal_app = ["foo-app"] + + bypass_pull_request_allowances { + users = ["foo-user"] + teams = [github_team.example.slug] + apps = ["foo-app"] + } + } + + restrictions { + users = ["foo-user"] + teams = [github_team.example.slug] + apps = ["foo-app"] + } +} + +resource "github_repository" "example" { + name = "example" +} + +resource "github_team" "example" { + name = "Example Name" +} + +resource "github_team_repository" "example" { + team_id = github_team.example.id + repository = github_repository.example.name + permission = "pull" +} diff --git a/examples/resources/codespaces_organization_secret/example_1.tf b/examples/resources/codespaces_organization_secret/example_1.tf new file mode 100644 index 0000000000..6b76567b33 --- /dev/null +++ b/examples/resources/codespaces_organization_secret/example_1.tf @@ -0,0 +1,11 @@ +resource "github_codespaces_organization_secret" "example_secret" { + secret_name = "example_secret_name" + visibility = "private" + plaintext_value = var.some_secret_string +} + +resource "github_codespaces_organization_secret" "example_secret" { + secret_name = "example_secret_name" + visibility = "private" + encrypted_value = var.some_encrypted_secret_string +} diff --git a/examples/resources/codespaces_organization_secret/example_2.tf b/examples/resources/codespaces_organization_secret/example_2.tf new file mode 100644 index 0000000000..684cb8cb9e --- /dev/null +++ b/examples/resources/codespaces_organization_secret/example_2.tf @@ -0,0 +1,17 @@ +data "github_repository" "repo" { + full_name = "my-org/repo" +} + +resource "github_codespaces_organization_secret" "example_secret" { + secret_name = "example_secret_name" + visibility = "selected" + plaintext_value = var.some_secret_string + selected_repository_ids = [data.github_repository.repo.repo_id] +} + +resource "github_codespaces_organization_secret" "example_secret" { + secret_name = "example_secret_name" + visibility = "selected" + encrypted_value = var.some_encrypted_secret_string + selected_repository_ids = [data.github_repository.repo.repo_id] +} diff --git a/examples/resources/codespaces_organization_secret_repositories/example_1.tf b/examples/resources/codespaces_organization_secret_repositories/example_1.tf new file mode 100644 index 0000000000..a9e66fe613 --- /dev/null +++ b/examples/resources/codespaces_organization_secret_repositories/example_1.tf @@ -0,0 +1,8 @@ +data "github_repository" "repo" { + full_name = "my-org/repo" +} + +resource "github_codespaces_organization_secret_repositories" "org_secret_repos" { + secret_name = "existing_secret_name" + selected_repository_ids = [data.github_repository.repo.repo_id] +} diff --git a/examples/resources/codespaces_secret/example_1.tf b/examples/resources/codespaces_secret/example_1.tf new file mode 100644 index 0000000000..1eb4a8fea4 --- /dev/null +++ b/examples/resources/codespaces_secret/example_1.tf @@ -0,0 +1,15 @@ +data "github_codespaces_public_key" "example_public_key" { + repository = "example_repository" +} + +resource "github_codespaces_secret" "example_secret" { + repository = "example_repository" + secret_name = "example_secret_name" + plaintext_value = var.some_secret_string +} + +resource "github_codespaces_secret" "example_secret" { + repository = "example_repository" + secret_name = "example_secret_name" + encrypted_value = var.some_encrypted_secret_string +} diff --git a/examples/resources/codespaces_user_secret/example_1.tf b/examples/resources/codespaces_user_secret/example_1.tf new file mode 100644 index 0000000000..6cefaeec3f --- /dev/null +++ b/examples/resources/codespaces_user_secret/example_1.tf @@ -0,0 +1,15 @@ +data "github_repository" "repo" { + full_name = "my-org/repo" +} + +resource "github_codespaces_user_secret" "example_secret" { + secret_name = "example_secret_name" + plaintext_value = var.some_secret_string + selected_repository_ids = [data.github_repository.repo.repo_id] +} + +resource "github_codespaces_user_secret" "example_secret" { + secret_name = "example_secret_name" + encrypted_value = var.some_encrypted_secret_string + selected_repository_ids = [data.github_repository.repo.repo_id] +} diff --git a/examples/resources/dependabot_organization_secret/example_1.tf b/examples/resources/dependabot_organization_secret/example_1.tf new file mode 100644 index 0000000000..00677c0376 --- /dev/null +++ b/examples/resources/dependabot_organization_secret/example_1.tf @@ -0,0 +1,11 @@ +resource "github_dependabot_organization_secret" "example_secret" { + secret_name = "example_secret_name" + visibility = "private" + plaintext_value = var.some_secret_string +} + +resource "github_dependabot_organization_secret" "example_secret" { + secret_name = "example_secret_name" + visibility = "private" + encrypted_value = var.some_encrypted_secret_string +} diff --git a/examples/resources/dependabot_organization_secret/example_2.tf b/examples/resources/dependabot_organization_secret/example_2.tf new file mode 100644 index 0000000000..e2f2f1cd02 --- /dev/null +++ b/examples/resources/dependabot_organization_secret/example_2.tf @@ -0,0 +1,17 @@ +data "github_repository" "repo" { + full_name = "my-org/repo" +} + +resource "github_dependabot_organization_secret" "example_secret" { + secret_name = "example_secret_name" + visibility = "selected" + plaintext_value = var.some_secret_string + selected_repository_ids = [data.github_repository.repo.repo_id] +} + +resource "github_dependabot_organization_secret" "example_secret" { + secret_name = "example_secret_name" + visibility = "selected" + encrypted_value = var.some_encrypted_secret_string + selected_repository_ids = [data.github_repository.repo.repo_id] +} diff --git a/examples/resources/dependabot_organization_secret_repositories/example_1.tf b/examples/resources/dependabot_organization_secret_repositories/example_1.tf new file mode 100644 index 0000000000..eeb6011ac4 --- /dev/null +++ b/examples/resources/dependabot_organization_secret_repositories/example_1.tf @@ -0,0 +1,14 @@ +data "github_repository" "repo" { + full_name = "my-org/repo" +} + +resource "github_dependabot_organization_secret" "example_secret" { + secret_name = "example_secret_name" + visibility = "private" + plaintext_value = var.some_secret_string +} + +resource "github_dependabot_organization_secret_repositories" "org_secret_repos" { + secret_name = github_dependabot_organization_secret.example_secret.secret_name + selected_repository_ids = [data.github_repository.repo.repo_id] +} diff --git a/examples/resources/dependabot_secret/example_1.tf b/examples/resources/dependabot_secret/example_1.tf new file mode 100644 index 0000000000..4c4fa11fec --- /dev/null +++ b/examples/resources/dependabot_secret/example_1.tf @@ -0,0 +1,15 @@ +data "github_dependabot_public_key" "example_public_key" { + repository = "example_repository" +} + +resource "github_dependabot_secret" "example_secret" { + repository = "example_repository" + secret_name = "example_secret_name" + plaintext_value = var.some_secret_string +} + +resource "github_dependabot_secret" "example_secret" { + repository = "example_repository" + secret_name = "example_secret_name" + encrypted_value = var.some_encrypted_secret_string +} diff --git a/examples/resources/emu_group_mapping/example_1.tf b/examples/resources/emu_group_mapping/example_1.tf new file mode 100644 index 0000000000..9723b23c3c --- /dev/null +++ b/examples/resources/emu_group_mapping/example_1.tf @@ -0,0 +1,6 @@ +resource "github_emu_group_mapping" "example_emu_group_mapping" { + team_slug = "emu-test-team" # The GitHub team name to modify + group_id = 28836 # The group ID of the external group to link +} + +# Note that here GITHUB_OWNER and GITHUB_TOKEN have been set in the environment. diff --git a/examples/resources/enterprise_actions_permissions/example_1.tf b/examples/resources/enterprise_actions_permissions/example_1.tf new file mode 100644 index 0000000000..ac72f85e22 --- /dev/null +++ b/examples/resources/enterprise_actions_permissions/example_1.tf @@ -0,0 +1,17 @@ +data "github_organization" "example-org" { + name = "my-org" +} + +resource "github_enterprise_actions_permissions" "test" { + enterprise_slug = "my-enterprise" + allowed_actions = "selected" + enabled_organizations = "selected" + allowed_actions_config { + github_owned_allowed = true + patterns_allowed = ["actions/cache@*", "actions/checkout@*"] + verified_allowed = true + } + enabled_organizations_config { + organization_ids = [data.github_organization.example-org.id] + } +} diff --git a/examples/resources/enterprise_actions_runner_group/example_1.tf b/examples/resources/enterprise_actions_runner_group/example_1.tf new file mode 100644 index 0000000000..165dd482d5 --- /dev/null +++ b/examples/resources/enterprise_actions_runner_group/example_1.tf @@ -0,0 +1,20 @@ +data "github_enterprise" "enterprise" { + slug = "my-enterprise" +} + +resource "github_enterprise_organization" "enterprise_organization" { + enterprise_id = data.github_enterprise.enterprise.id + name = "my-organization" + billing_email = "octocat@octo.cat" + admin_logins = ["octocat"] +} + +resource "github_enterprise_actions_runner_group" "example" { + name = "my-awesome-runner-group" + enterprise_slug = data.github_enterprise.enterprise.slug + allows_public_repositories = true + visibility = "selected" + selected_organization_ids = [github_enterprise_organization.enterprise_organization.database_id] + restricted_to_workflows = true + selected_workflows = ["my-organization/my-repo/.github/workflows/cool-workflow.yaml@refs/tags/v1"] +} diff --git a/examples/resources/enterprise_actions_workflow_permissions/example_1.tf b/examples/resources/enterprise_actions_workflow_permissions/example_1.tf new file mode 100644 index 0000000000..1074b3b0cd --- /dev/null +++ b/examples/resources/enterprise_actions_workflow_permissions/example_1.tf @@ -0,0 +1,15 @@ +# Basic workflow permissions configuration +resource "github_enterprise_actions_workflow_permissions" "example" { + enterprise_slug = "my-enterprise" + + default_workflow_permissions = "read" + can_approve_pull_request_reviews = false +} + +# Allow write permissions and PR approvals +resource "github_enterprise_actions_workflow_permissions" "permissive" { + enterprise_slug = "my-enterprise" + + default_workflow_permissions = "write" + can_approve_pull_request_reviews = true +} diff --git a/examples/resources/enterprise_security_analysis_settings/example_1.tf b/examples/resources/enterprise_security_analysis_settings/example_1.tf new file mode 100644 index 0000000000..e53f82159a --- /dev/null +++ b/examples/resources/enterprise_security_analysis_settings/example_1.tf @@ -0,0 +1,17 @@ +# Basic security settings - enable secret scanning only +resource "github_enterprise_security_analysis_settings" "basic" { + enterprise_slug = "my-enterprise" + + secret_scanning_enabled_for_new_repositories = true +} + +# Full security configuration with all features enabled +resource "github_enterprise_security_analysis_settings" "comprehensive" { + enterprise_slug = "my-enterprise" + + advanced_security_enabled_for_new_repositories = true + secret_scanning_enabled_for_new_repositories = true + secret_scanning_push_protection_enabled_for_new_repositories = true + secret_scanning_validity_checks_enabled = true + secret_scanning_push_protection_custom_link = "https://octokit.com/security-guidelines" +} diff --git a/examples/resources/issue/example_1.tf b/examples/resources/issue/example_1.tf new file mode 100644 index 0000000000..ed7194abc1 --- /dev/null +++ b/examples/resources/issue/example_1.tf @@ -0,0 +1,12 @@ +# Create a simple issue +resource "github_repository" "test" { + name = "tf-acc-test-%s" + auto_init = true + has_issues = true +} + +resource "github_issue" "test" { + repository = github_repository.test.name + title = "My issue title" + body = "The body of my issue" +} diff --git a/examples/resources/issue/example_2.tf b/examples/resources/issue/example_2.tf new file mode 100644 index 0000000000..1e52077d5b --- /dev/null +++ b/examples/resources/issue/example_2.tf @@ -0,0 +1,24 @@ +# Create an issue with milestone and project assignment +resource "github_repository" "test" { + name = "tf-acc-test-%s" + auto_init = true + has_issues = true +} + +resource "github_repository_milestone" "test" { + owner = split("/", "${github_repository.test.full_name}")[0] + repository = github_repository.test.name + title = "v1.0.0" + description = "General Availability" + due_date = "2022-11-22" + state = "open" +} + +resource "github_issue" "test" { + repository = github_repository.test.name + title = "My issue" + body = "My issue body" + labels = ["bug", "documentation"] + assignees = ["bob-github"] + milestone_number = github_repository_milestone.test.number +} diff --git a/examples/resources/issue_label/example_1.tf b/examples/resources/issue_label/example_1.tf new file mode 100644 index 0000000000..4610cf8fc5 --- /dev/null +++ b/examples/resources/issue_label/example_1.tf @@ -0,0 +1,6 @@ +# Create a new, red colored label +resource "github_issue_label" "test_repo" { + repository = "test-repo" + name = "Urgent" + color = "FF0000" +} diff --git a/examples/resources/issue_labels/example_1.tf b/examples/resources/issue_labels/example_1.tf new file mode 100644 index 0000000000..dd9ea9236c --- /dev/null +++ b/examples/resources/issue_labels/example_1.tf @@ -0,0 +1,14 @@ +# Create a new, red colored label +resource "github_issue_labels" "test_repo" { + repository = "test-repo" + + label { + name = "Urgent" + color = "FF0000" + } + + label { + name = "Critical" + color = "FF0000" + } +} diff --git a/examples/resources/membership/example_1.tf b/examples/resources/membership/example_1.tf new file mode 100644 index 0000000000..ffc6e358ee --- /dev/null +++ b/examples/resources/membership/example_1.tf @@ -0,0 +1,5 @@ +# Add a user to the organization +resource "github_membership" "membership_for_some_user" { + username = "SomeUser" + role = "member" +} diff --git a/examples/resources/organization_block/example_1.tf b/examples/resources/organization_block/example_1.tf new file mode 100644 index 0000000000..0b8af6fafe --- /dev/null +++ b/examples/resources/organization_block/example_1.tf @@ -0,0 +1,3 @@ +resource "github_organization_block" "example" { + username = "paultyng" +} diff --git a/examples/resources/organization_custom_properties/example_1.tf b/examples/resources/organization_custom_properties/example_1.tf new file mode 100644 index 0000000000..b27e48758a --- /dev/null +++ b/examples/resources/organization_custom_properties/example_1.tf @@ -0,0 +1,12 @@ +resource "github_organization_custom_properties" "environment" { + property_name = "environment" + value_type = "single_select" + required = true + description = "The deployment environment for this repository" + default_value = "development" + allowed_values = [ + "development", + "staging", + "production" + ] +} diff --git a/examples/resources/organization_custom_properties/example_2.tf b/examples/resources/organization_custom_properties/example_2.tf new file mode 100644 index 0000000000..21685e3a45 --- /dev/null +++ b/examples/resources/organization_custom_properties/example_2.tf @@ -0,0 +1,7 @@ +resource "github_organization_custom_properties" "team_contact" { + property_name = "team_contact" + value_type = "string" + required = false + description = "Contact information for the team managing this repository" + values_editable_by = "org_and_repo_actors" +} diff --git a/examples/resources/organization_custom_properties/example_3.tf b/examples/resources/organization_custom_properties/example_3.tf new file mode 100644 index 0000000000..569bc0a24f --- /dev/null +++ b/examples/resources/organization_custom_properties/example_3.tf @@ -0,0 +1,6 @@ +resource "github_organization_custom_properties" "owner" { + property_name = "owner" + value_type = "string" + required = true + description = "The team or individual responsible for this repository" +} diff --git a/examples/resources/organization_custom_properties/example_4.tf b/examples/resources/organization_custom_properties/example_4.tf new file mode 100644 index 0000000000..cf449c4d54 --- /dev/null +++ b/examples/resources/organization_custom_properties/example_4.tf @@ -0,0 +1,7 @@ +resource "github_organization_custom_properties" "archived" { + property_name = "archived" + value_type = "true_false" + required = false + description = "Whether this repository is archived" + default_value = "false" +} diff --git a/examples/resources/organization_custom_role/example_1.tf b/examples/resources/organization_custom_role/example_1.tf new file mode 100644 index 0000000000..bb5b0ebc21 --- /dev/null +++ b/examples/resources/organization_custom_role/example_1.tf @@ -0,0 +1,26 @@ +resource "github_organization_custom_role" "example" { + name = "example" + description = "Example custom role that uses the read role as its base" + base_role = "read" + permissions = [ + "add_assignee", + "add_label", + "bypass_branch_protection", + "close_issue", + "close_pull_request", + "mark_as_duplicate", + "create_tag", + "delete_issue", + "delete_tag", + "manage_deploy_keys", + "push_protected_branch", + "read_code_scanning", + "reopen_issue", + "reopen_pull_request", + "request_pr_review", + "resolve_dependabot_alerts", + "resolve_secret_scanning_alerts", + "view_secret_scanning_alerts", + "write_code_scanning" + ] +} diff --git a/examples/resources/organization_repository_role/example_1.tf b/examples/resources/organization_repository_role/example_1.tf new file mode 100644 index 0000000000..62905b7e26 --- /dev/null +++ b/examples/resources/organization_repository_role/example_1.tf @@ -0,0 +1,9 @@ +resource "github_organization_repository_role" "example" { + name = "example" + base_role = "read" + + permissions = [ + "add_assignee", + "add_label" + ] +} diff --git a/examples/resources/organization_role/example_1.tf b/examples/resources/organization_role/example_1.tf new file mode 100644 index 0000000000..a9d7605c62 --- /dev/null +++ b/examples/resources/organization_role/example_1.tf @@ -0,0 +1,9 @@ +resource "github_organization_role" "example" { + name = "example" + base_role = "read" + + permissions = [ + "read_organization_custom_org_role", + "read_organization_custom_repo_role" + ] +} diff --git a/examples/resources/organization_role_team/example_1.tf b/examples/resources/organization_role_team/example_1.tf new file mode 100644 index 0000000000..1b8f396be3 --- /dev/null +++ b/examples/resources/organization_role_team/example_1.tf @@ -0,0 +1,4 @@ +resource "github_organization_role_team" "example" { + role_id = 1234 + team_slug = "example-team" +} diff --git a/examples/resources/organization_role_team_assignment/example_1.tf b/examples/resources/organization_role_team_assignment/example_1.tf new file mode 100644 index 0000000000..4765152749 --- /dev/null +++ b/examples/resources/organization_role_team_assignment/example_1.tf @@ -0,0 +1,8 @@ +resource "github_team" "test-team" { + name = "test-team" +} + +resource "github_organization_role_team_assignment" "test-team-role-assignment" { + team_slug = github_team.test-team.slug + role_id = "8132" # all_repo_read (predefined) +} diff --git a/examples/resources/organization_role_user/example_1.tf b/examples/resources/organization_role_user/example_1.tf new file mode 100644 index 0000000000..743929075a --- /dev/null +++ b/examples/resources/organization_role_user/example_1.tf @@ -0,0 +1,4 @@ +resource "github_organization_role_user" "example" { + role_id = 1234 + login = "example-user" +} diff --git a/examples/resources/organization_ruleset/example_1.tf b/examples/resources/organization_ruleset/example_1.tf new file mode 100644 index 0000000000..6a838781ed --- /dev/null +++ b/examples/resources/organization_ruleset/example_1.tf @@ -0,0 +1,86 @@ +resource "github_organization_ruleset" "example" { + name = "example" + target = "branch" + enforcement = "active" + + conditions { + ref_name { + include = ["~ALL"] + exclude = [] + } + } + + bypass_actors { + actor_id = 13473 + actor_type = "Integration" + bypass_mode = "always" + } + + rules { + creation = true + update = true + deletion = true + required_linear_history = true + required_signatures = true + + branch_name_pattern { + name = "example" + negate = false + operator = "starts_with" + pattern = "ex" + } + + required_workflows { + do_not_enforce_on_create = true + required_workflow { + repository_id = 1234 + path = ".github/workflows/ci.yml" + ref = "main" + } + } + + required_code_scanning { + required_code_scanning_tool { + alerts_threshold = "errors" + security_alerts_threshold = "high_or_higher" + tool = "CodeQL" + } + } + } +} + +# Example with push ruleset +resource "github_organization_ruleset" "example_push" { + name = "example_push" + target = "push" + enforcement = "active" + + conditions { + ref_name { + include = ["~ALL"] + exclude = [] + } + repository_name { + include = ["~ALL"] + exclude = [] + } + } + + rules { + file_path_restriction { + restricted_file_paths = [".github/workflows/*", "*.env"] + } + + max_file_size { + max_file_size = 100 # 100 MB + } + + max_file_path_length { + max_file_path_length = 255 + } + + file_extension_restriction { + restricted_file_extensions = ["*.exe", "*.dll", "*.so"] + } + } +} diff --git a/examples/resources/organization_security_manager/example_1.tf b/examples/resources/organization_security_manager/example_1.tf new file mode 100644 index 0000000000..17b2487944 --- /dev/null +++ b/examples/resources/organization_security_manager/example_1.tf @@ -0,0 +1,8 @@ +resource "github_team" "some_team" { + name = "SomeTeam" + description = "Some cool team" +} + +resource "github_organization_security_manager" "some_team" { + team_slug = github_team.some_team.slug +} diff --git a/examples/resources/organization_settings/example_1.tf b/examples/resources/organization_settings/example_1.tf new file mode 100644 index 0000000000..23e588e31b --- /dev/null +++ b/examples/resources/organization_settings/example_1.tf @@ -0,0 +1,28 @@ +resource "github_organization_settings" "test" { + billing_email = "test@example.com" + company = "Test Company" + blog = "https://example.com" + email = "test@example.com" + twitter_username = "Test" + location = "Test Location" + name = "Test Name" + description = "Test Description" + has_organization_projects = true + has_repository_projects = true + default_repository_permission = "read" + members_can_create_repositories = true + members_can_create_public_repositories = true + members_can_create_private_repositories = true + members_can_create_internal_repositories = true + members_can_create_pages = true + members_can_create_public_pages = true + members_can_create_private_pages = true + members_can_fork_private_repositories = true + web_commit_signoff_required = true + advanced_security_enabled_for_new_repositories = false + dependabot_alerts_enabled_for_new_repositories= false + dependabot_security_updates_enabled_for_new_repositories = false + dependency_graph_enabled_for_new_repositories = false + secret_scanning_enabled_for_new_repositories = false + secret_scanning_push_protection_enabled_for_new_repositories = false +} diff --git a/examples/resources/organization_webhook/example_1.tf b/examples/resources/organization_webhook/example_1.tf new file mode 100644 index 0000000000..71142bc08d --- /dev/null +++ b/examples/resources/organization_webhook/example_1.tf @@ -0,0 +1,13 @@ +resource "github_organization_webhook" "foo" { + name = "web" + + configuration { + url = "https://google.de/" + content_type = "form" + insecure_ssl = false + } + + active = false + + events = ["issues"] +} diff --git a/examples/resources/release/example_1.tf b/examples/resources/release/example_1.tf new file mode 100644 index 0000000000..3ae5a91060 --- /dev/null +++ b/examples/resources/release/example_1.tf @@ -0,0 +1,11 @@ +resource "github_repository" "repo" { + name = "repo" + description = "GitHub repo managed by Terraform" + + private = false +} + +resource "github_release" "example" { + repository = github_repository.repo.name + tag_name = "v1.0.0" +} diff --git a/examples/resources/release/example_2.tf b/examples/resources/release/example_2.tf new file mode 100644 index 0000000000..2aefac5141 --- /dev/null +++ b/examples/resources/release/example_2.tf @@ -0,0 +1,18 @@ +resource "github_repository" "example" { + name = "repo" + auto_init = true +} + +resource "github_branch" "example" { + repository = github_repository.example.name + branch = "branch_name" + source_branch = github_repository.example.default_branch +} + +resource "github_release" "example" { + repository = github_repository.example.name + tag_name = "v1.0.0" + target_commitish = github_branch.example.branch + draft = false + prerelease = false +} diff --git a/examples/resources/repository/example_1.tf b/examples/resources/repository/example_1.tf new file mode 100644 index 0000000000..c897e2cf79 --- /dev/null +++ b/examples/resources/repository/example_1.tf @@ -0,0 +1,12 @@ +resource "github_repository" "example" { + name = "example" + description = "My awesome codebase" + + visibility = "public" + + template { + owner = "github" + repository = "terraform-template-module" + include_all_branches = true + } +} diff --git a/examples/resources/repository/example_2.tf b/examples/resources/repository/example_2.tf new file mode 100644 index 0000000000..df682a6fbf --- /dev/null +++ b/examples/resources/repository/example_2.tf @@ -0,0 +1,13 @@ +resource "github_repository" "example" { + name = "example" + description = "My awesome web page" + + private = false + + pages { + source { + branch = "master" + path = "/docs" + } + } +} diff --git a/examples/resources/repository/example_3.tf b/examples/resources/repository/example_3.tf new file mode 100644 index 0000000000..bb63657b8f --- /dev/null +++ b/examples/resources/repository/example_3.tf @@ -0,0 +1,7 @@ +resource "github_repository" "forked_repo" { + name = "forked-repository" + description = "This is a fork of another repository" + fork = true + source_owner = "some-org" + source_repo = "original-repository" +} diff --git a/examples/resources/repository_autolink_reference/example_1.tf b/examples/resources/repository_autolink_reference/example_1.tf new file mode 100644 index 0000000000..577f699b82 --- /dev/null +++ b/examples/resources/repository_autolink_reference/example_1.tf @@ -0,0 +1,14 @@ +resource "github_repository" "repo" { + name = "my-repo" + description = "GitHub repo managed by Terraform" + + private = false +} + +resource "github_repository_autolink_reference" "autolink" { + repository = github_repository.repo.name + + key_prefix = "TICKET-" + + target_url_template = "https://example.com/TICKET?query=" +} diff --git a/examples/resources/repository_collaborator/example_1.tf b/examples/resources/repository_collaborator/example_1.tf new file mode 100644 index 0000000000..8aa3a72428 --- /dev/null +++ b/examples/resources/repository_collaborator/example_1.tf @@ -0,0 +1,6 @@ +# Add a collaborator to a repository +resource "github_repository_collaborator" "a_repo_collaborator" { + repository = "our-cool-repo" + username = "SomeUser" + permission = "admin" +} diff --git a/examples/resources/repository_collaborators/example_1.tf b/examples/resources/repository_collaborators/example_1.tf new file mode 100644 index 0000000000..630e0d1b17 --- /dev/null +++ b/examples/resources/repository_collaborators/example_1.tf @@ -0,0 +1,23 @@ +# Add collaborators to a repository +resource "github_team" "some_team" { + name = "SomeTeam" + description = "Some cool team" +} + +resource "github_repository" "some_repo" { + name = "some-repo" +} + +resource "github_repository_collaborators" "some_repo_collaborators" { + repository = github_repository.some_repo.name + + user { + permission = "admin" + username = "SomeUser" + } + + team { + permission = "pull" + team_id = github_team.some_team.slug + } +} diff --git a/examples/resources/repository_custom_property/example_1.tf b/examples/resources/repository_custom_property/example_1.tf new file mode 100644 index 0000000000..be5eb8fb8c --- /dev/null +++ b/examples/resources/repository_custom_property/example_1.tf @@ -0,0 +1,10 @@ +resource "github_repository" "example" { + name = "example" + description = "My awesome codebase" +} +resource "github_repository_custom_property" "string" { + repository = github_repository.example.name + property_name = "my-cool-property" + property_type = "string" + property_value = ["test"] +} diff --git a/examples/resources/repository_dependabot_security_updates/example_1.tf b/examples/resources/repository_dependabot_security_updates/example_1.tf new file mode 100644 index 0000000000..47c1e95457 --- /dev/null +++ b/examples/resources/repository_dependabot_security_updates/example_1.tf @@ -0,0 +1,14 @@ +resource "github_repository" "repo" { + name = "my-repo" + description = "GitHub repo managed by Terraform" + + private = false + + vulnerability_alerts = true +} + + +resource "github_repository_dependabot_security_updates" "example" { + repository = github_repository.test.name + enabled = true +} diff --git a/examples/resources/repository_deploy_key/example_1.tf b/examples/resources/repository_deploy_key/example_1.tf new file mode 100644 index 0000000000..2bf08c4167 --- /dev/null +++ b/examples/resources/repository_deploy_key/example_1.tf @@ -0,0 +1,12 @@ +# Generate an ssh key using provider "hashicorp/tls" +resource "tls_private_key" "example_repository_deploy_key" { + algorithm = "ED25519" +} + +# Add the ssh key as a deploy key +resource "github_repository_deploy_key" "example_repository_deploy_key" { + title = "Repository test key" + repository = "test-repo" + key = tls_private_key.example_repository_deploy_key.public_key_openssh + read_only = true +} diff --git a/examples/resources/repository_deployment_branch_policy/example_1.tf b/examples/resources/repository_deployment_branch_policy/example_1.tf new file mode 100644 index 0000000000..ae13bf3be7 --- /dev/null +++ b/examples/resources/repository_deployment_branch_policy/example_1.tf @@ -0,0 +1,16 @@ +resource "github_repository_environment" "env" { + repository = "my_repo" + environment = "my_env" + deployment_branch_policy { + protected_branches = false + custom_branch_policies = true + } +} + +resource "github_repository_deployment_branch_policy" "foo" { + depends_on = [github_repository_environment.env] + + repository = "my_repo" + environment_name = "my_env" + name = "foo" +} diff --git a/examples/resources/repository_environment/example_1.tf b/examples/resources/repository_environment/example_1.tf new file mode 100644 index 0000000000..fa22218d71 --- /dev/null +++ b/examples/resources/repository_environment/example_1.tf @@ -0,0 +1,21 @@ +data "github_user" "current" { + username = "" +} + +resource "github_repository" "example" { + name = "A Repository Project" + description = "My awesome codebase" +} + +resource "github_repository_environment" "example" { + environment = "example" + repository = github_repository.example.name + prevent_self_review = true + reviewers { + users = [data.github_user.current.id] + } + deployment_branch_policy { + protected_branches = true + custom_branch_policies = false + } +} diff --git a/examples/resources/repository_environment_deployment_policy/example_1.tf b/examples/resources/repository_environment_deployment_policy/example_1.tf new file mode 100644 index 0000000000..27bea257b6 --- /dev/null +++ b/examples/resources/repository_environment_deployment_policy/example_1.tf @@ -0,0 +1,26 @@ +data "github_user" "current" { + username = "" +} + +resource "github_repository" "test" { + name = "tf-acc-test-%s" +} + +resource "github_repository_environment" "test" { + repository = github_repository.test.name + environment = "environment/test" + wait_timer = 10000 + reviewers { + users = [data.github_user.current.id] + } + deployment_branch_policy { + protected_branches = false + custom_branch_policies = true + } +} + +resource "github_repository_environment_deployment_policy" "test" { + repository = github_repository.test.name + environment = github_repository_environment.test.environment + branch_pattern = "releases/*" +} diff --git a/examples/resources/repository_environment_deployment_policy/example_2.tf b/examples/resources/repository_environment_deployment_policy/example_2.tf new file mode 100644 index 0000000000..9d7df80516 --- /dev/null +++ b/examples/resources/repository_environment_deployment_policy/example_2.tf @@ -0,0 +1,27 @@ + +data "github_user" "current" { + username = "" +} + +resource "github_repository" "test" { + name = "tf-acc-test-%s" +} + +resource "github_repository_environment" "test" { + repository = github_repository.test.name + environment = "environment/test" + wait_timer = 10000 + reviewers { + users = [data.github_user.current.id] + } + deployment_branch_policy { + protected_branches = false + custom_branch_policies = true + } +} + +resource "github_repository_environment_deployment_policy" "test" { + repository = github_repository.test.name + environment = github_repository_environment.test.environment + tag_pattern = "v*" +} diff --git a/examples/resources/repository_file/example_1.tf b/examples/resources/repository_file/example_1.tf new file mode 100644 index 0000000000..1d03f39729 --- /dev/null +++ b/examples/resources/repository_file/example_1.tf @@ -0,0 +1,17 @@ + +resource "github_repository" "foo" { + name = "tf-acc-test-%s" + auto_init = true +} + +resource "github_repository_file" "foo" { + repository = github_repository.foo.name + branch = "main" + file = ".gitignore" + content = "**/*.tfstate" + commit_message = "Managed by Terraform" + commit_author = "Terraform User" + commit_email = "terraform@example.com" + overwrite_on_create = true +} + diff --git a/examples/resources/repository_file/example_2.tf b/examples/resources/repository_file/example_2.tf new file mode 100644 index 0000000000..d4833c71eb --- /dev/null +++ b/examples/resources/repository_file/example_2.tf @@ -0,0 +1,18 @@ + +resource "github_repository" "foo" { + name = "tf-acc-test-%s" + auto_init = true +} + +resource "github_repository_file" "foo" { + repository = github_repository.foo.name + branch = "does/not/exist" + file = ".gitignore" + content = "**/*.tfstate" + commit_message = "Managed by Terraform" + commit_author = "Terraform User" + commit_email = "terraform@example.com" + overwrite_on_create = true + autocreate_branch = true +} + diff --git a/examples/resources/repository_milestone/example_1.tf b/examples/resources/repository_milestone/example_1.tf new file mode 100644 index 0000000000..7d15cf570a --- /dev/null +++ b/examples/resources/repository_milestone/example_1.tf @@ -0,0 +1,6 @@ +# Create a milestone for a repository +resource "github_repository_milestone" "example" { + owner = "example-owner" + repository = "example-repository" + title = "v1.1.0" +} diff --git a/examples/resources/repository_pull_request/example_1.tf b/examples/resources/repository_pull_request/example_1.tf new file mode 100644 index 0000000000..0fae030c4f --- /dev/null +++ b/examples/resources/repository_pull_request/example_1.tf @@ -0,0 +1,7 @@ +resource "github_repository_pull_request" "example" { + base_repository = "example-repository" + base_ref = "main" + head_ref = "feature-branch" + title = "My newest feature" + body = "This will change everything" +} diff --git a/examples/resources/repository_ruleset/example_1.tf b/examples/resources/repository_ruleset/example_1.tf new file mode 100644 index 0000000000..ef7dccbc80 --- /dev/null +++ b/examples/resources/repository_ruleset/example_1.tf @@ -0,0 +1,70 @@ +resource "github_repository" "example" { + name = "example" + description = "Example repository" +} + +resource "github_repository_ruleset" "example" { + name = "example" + repository = github_repository.example.name + target = "branch" + enforcement = "active" + + conditions { + ref_name { + include = ["~ALL"] + exclude = [] + } + } + + bypass_actors { + actor_id = 13473 + actor_type = "Integration" + bypass_mode = "always" + } + + rules { + creation = true + update = true + deletion = true + required_linear_history = true + required_signatures = true + + required_deployments { + required_deployment_environments = ["test"] + } + + required_code_scanning { + required_code_scanning_tool { + alerts_threshold = "errors" + security_alerts_threshold = "high_or_higher" + tool = "CodeQL" + } + } + } +} + +# Example with push ruleset +resource "github_repository_ruleset" "example_push" { + name = "example_push" + repository = github_repository.example.name + target = "push" + enforcement = "active" + + rules { + file_path_restriction { + restricted_file_paths = [".github/workflows/*", "*.env"] + } + + max_file_size { + max_file_size = 100 # 100 MB + } + + max_file_path_length { + max_file_path_length = 255 + } + + file_extension_restriction { + restricted_file_extensions = ["*.exe", "*.dll", "*.so"] + } + } +} diff --git a/examples/resources/repository_topics/example_1.tf b/examples/resources/repository_topics/example_1.tf new file mode 100644 index 0000000000..6408079514 --- /dev/null +++ b/examples/resources/repository_topics/example_1.tf @@ -0,0 +1,8 @@ +data "github_repository" "test" { + name = "test" +} + +resource "github_repository_topics" "test" { + repository = github_repository.test.name + topics = ["topic-1", "topic-2"] +} diff --git a/examples/resources/repository_webhook/example_1.tf b/examples/resources/repository_webhook/example_1.tf new file mode 100644 index 0000000000..e568d39794 --- /dev/null +++ b/examples/resources/repository_webhook/example_1.tf @@ -0,0 +1,21 @@ +resource "github_repository" "repo" { + name = "foo" + description = "Terraform acceptance tests" + homepage_url = "http://example.com/" + + visibility = "public" +} + +resource "github_repository_webhook" "foo" { + repository = github_repository.repo.name + + configuration { + url = "https://google.de/" + content_type = "form" + insecure_ssl = false + } + + active = false + + events = ["issues"] +} diff --git a/examples/resources/team/example_1.tf b/examples/resources/team/example_1.tf new file mode 100644 index 0000000000..6c0ed30c98 --- /dev/null +++ b/examples/resources/team/example_1.tf @@ -0,0 +1,6 @@ +# Add a team to the organization +resource "github_team" "some_team" { + name = "some-team" + description = "Some cool team" + privacy = "closed" +} diff --git a/examples/resources/team_members/example_1.tf b/examples/resources/team_members/example_1.tf new file mode 100644 index 0000000000..1f97c62b01 --- /dev/null +++ b/examples/resources/team_members/example_1.tf @@ -0,0 +1,29 @@ +# Add a user to the organization +resource "github_membership" "membership_for_some_user" { + username = "SomeUser" + role = "member" +} + +resource "github_membership" "membership_for_another_user" { + username = "AnotherUser" + role = "member" +} + +resource "github_team" "some_team" { + name = "SomeTeam" + description = "Some cool team" +} + +resource "github_team_members" "some_team_members" { + team_id = github_team.some_team.id + + members { + username = "SomeUser" + role = "maintainer" + } + + members { + username = "AnotherUser" + role = "member" + } +} diff --git a/examples/resources/team_membership/example_1.tf b/examples/resources/team_membership/example_1.tf new file mode 100644 index 0000000000..c96a4d2c38 --- /dev/null +++ b/examples/resources/team_membership/example_1.tf @@ -0,0 +1,16 @@ +# Add a user to the organization +resource "github_membership" "membership_for_some_user" { + username = "SomeUser" + role = "member" +} + +resource "github_team" "some_team" { + name = "SomeTeam" + description = "Some cool team" +} + +resource "github_team_membership" "some_team_membership" { + team_id = github_team.some_team.id + username = "SomeUser" + role = "member" +} diff --git a/examples/resources/team_repository/example_1.tf b/examples/resources/team_repository/example_1.tf new file mode 100644 index 0000000000..c2276ec830 --- /dev/null +++ b/examples/resources/team_repository/example_1.tf @@ -0,0 +1,15 @@ +# Add a repository to the team +resource "github_team" "some_team" { + name = "SomeTeam" + description = "Some cool team" +} + +resource "github_repository" "some_repo" { + name = "some-repo" +} + +resource "github_team_repository" "some_team_repo" { + team_id = github_team.some_team.id + repository = github_repository.some_repo.name + permission = "pull" +} diff --git a/examples/resources/team_settings/example_1.tf b/examples/resources/team_settings/example_1.tf new file mode 100644 index 0000000000..6df1f7f3e2 --- /dev/null +++ b/examples/resources/team_settings/example_1.tf @@ -0,0 +1,14 @@ +# Add a repository to the team +resource "github_team" "some_team" { + name = "SomeTeam" + description = "Some cool team" +} + +resource "github_team_settings" "code_review_settings" { + team_id = github_team.some_team.id + review_request_delegation { + algorithm = "ROUND_ROBIN" + member_count = 1 + notify = true + } +} diff --git a/examples/resources/team_sync_group_mapping/example_1.tf b/examples/resources/team_sync_group_mapping/example_1.tf new file mode 100644 index 0000000000..025c53983a --- /dev/null +++ b/examples/resources/team_sync_group_mapping/example_1.tf @@ -0,0 +1,15 @@ + +data "github_organization_team_sync_groups" "example_groups" {} + +resource "github_team_sync_group_mapping" "example_group_mapping" { + team_slug = "example" + + dynamic "group" { + for_each = [for g in data.github_organization_team_sync_groups.example_groups.groups : g if g.group_name == "some_team_group"] + content { + group_id = group.value.group_id + group_name = group.value.group_name + group_description = group.value.group_description + } + } +} diff --git a/examples/resources/user_gpg_key/example_1.tf b/examples/resources/user_gpg_key/example_1.tf new file mode 100644 index 0000000000..3b3165f269 --- /dev/null +++ b/examples/resources/user_gpg_key/example_1.tf @@ -0,0 +1,3 @@ +resource "github_user_gpg_key" "example" { + armored_public_key = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n...\n-----END PGP PUBLIC KEY BLOCK-----" +} diff --git a/examples/resources/user_invitation_accepter/example_1.tf b/examples/resources/user_invitation_accepter/example_1.tf new file mode 100644 index 0000000000..eaf70ea04e --- /dev/null +++ b/examples/resources/user_invitation_accepter/example_1.tf @@ -0,0 +1,19 @@ +resource "github_repository" "example" { + name = "example-repo" +} + +resource "github_repository_collaborator" "example" { + repository = github_repository.example.name + username = "example-username" + permission = "push" +} + +provider "github" { + alias = "invitee" + token = var.invitee_token +} + +resource "github_user_invitation_accepter" "example" { + provider = "github.invitee" + invitation_id = github_repository_collaborator.example.invitation_id +} diff --git a/examples/resources/user_ssh_key/example_1.tf b/examples/resources/user_ssh_key/example_1.tf new file mode 100644 index 0000000000..d6d3f5d702 --- /dev/null +++ b/examples/resources/user_ssh_key/example_1.tf @@ -0,0 +1,4 @@ +resource "github_user_ssh_key" "example" { + title = "example title" + key = file("~/.ssh/id_rsa.pub") +} diff --git a/examples/resources/workflow_repository_permissions/example_1.tf b/examples/resources/workflow_repository_permissions/example_1.tf new file mode 100644 index 0000000000..f2ea2480d9 --- /dev/null +++ b/examples/resources/workflow_repository_permissions/example_1.tf @@ -0,0 +1,9 @@ +resource "github_repository" "example" { + name = "my-repository" +} + +resource "github_workflow_repository_permissions" "test" { + default_workflow_permissions = "read" + can_approve_pull_request_reviews = true + repository = github_repository.example.name +} diff --git a/github/data_source_github_actions_environment_public_key.go b/github/data_source_github_actions_environment_public_key.go index 48a4fc1200..e504de9518 100644 --- a/github/data_source_github_actions_environment_public_key.go +++ b/github/data_source_github_actions_environment_public_key.go @@ -9,24 +9,29 @@ import ( func dataSourceGithubActionsEnvironmentPublicKey() *schema.Resource { return &schema.Resource{ - Read: dataSourceGithubActionsEnvironmentPublicKeyRead, + Read: dataSourceGithubActionsEnvironmentPublicKeyRead, + Description: "Use this data source to retrieve information about a GitHub Actions public key of a specific environment. This data source is required to be used with other GitHub secrets interactions. Note that the provider `token` must have admin rights to a repository to retrieve the action public keys of it's environments.", Schema: map[string]*schema.Schema{ "repository": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Description: "Name of the repository to get public key from.", + Required: true, }, "environment": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Description: "Name of the environment to get public key from.", + Required: true, }, "key_id": { - Type: schema.TypeString, - Computed: true, + Type: schema.TypeString, + Description: "ID of the key that has been retrieved.", + Computed: true, }, "key": { - Type: schema.TypeString, - Computed: true, + Type: schema.TypeString, + Description: "Actual key retrieved.", + Computed: true, }, }, } diff --git a/github/data_source_github_actions_organization_oidc_subject_claim_customization_template.go b/github/data_source_github_actions_organization_oidc_subject_claim_customization_template.go index 81e18c00b6..ddabda72d4 100644 --- a/github/data_source_github_actions_organization_oidc_subject_claim_customization_template.go +++ b/github/data_source_github_actions_organization_oidc_subject_claim_customization_template.go @@ -8,10 +8,13 @@ func dataSourceGithubActionsOrganizationOIDCSubjectClaimCustomizationTemplate() return &schema.Resource{ Read: dataSourceGithubActionsOrganizationOIDCSubjectClaimCustomizationTemplateRead, + Description: "Use this data source to retrieve the OpenID Connect subject claim customization template for an organization", + Schema: map[string]*schema.Schema{ "include_claim_keys": { - Type: schema.TypeList, - Computed: true, + Type: schema.TypeList, + Computed: true, + Description: "The list of OpenID Connect claim keys", Elem: &schema.Schema{ Type: schema.TypeString, }, diff --git a/github/data_source_github_app.go b/github/data_source_github_app.go index c2dcf3d366..6a9dc3492a 100644 --- a/github/data_source_github_app.go +++ b/github/data_source_github_app.go @@ -9,24 +9,29 @@ import ( func dataSourceGithubApp() *schema.Resource { return &schema.Resource{ - Read: dataSourceGithubAppRead, + Read: dataSourceGithubAppRead, + Description: "Use this data source to retrieve information about a GitHub App.", Schema: map[string]*schema.Schema{ "slug": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: true, + Description: "The URL-friendly name of your GitHub App.", }, "description": { - Type: schema.TypeString, - Computed: true, + Type: schema.TypeString, + Computed: true, + Description: "The app's description.", }, "name": { - Type: schema.TypeString, - Computed: true, + Type: schema.TypeString, + Computed: true, + Description: "The app's full name.", }, "node_id": { - Type: schema.TypeString, - Computed: true, + Type: schema.TypeString, + Computed: true, + Description: "The Node ID of the app.", }, }, } diff --git a/github/resource_github_organization_ruleset.go b/github/resource_github_organization_ruleset.go index c0a027dc67..d7a10a547d 100644 --- a/github/resource_github_organization_ruleset.go +++ b/github/resource_github_organization_ruleset.go @@ -25,6 +25,10 @@ func resourceGithubOrganizationRuleset() *schema.Resource { SchemaVersion: 1, + Description: `Creates a GitHub organization ruleset. + +This resource allows you to create and manage rulesets on the organization level. When applied, a new ruleset will be created. When destroyed, that ruleset will be removed.`, + Schema: map[string]*schema.Schema{ "name": { Type: schema.TypeString, @@ -61,7 +65,7 @@ func resourceGithubOrganizationRuleset() *schema.Resource { Type: schema.TypeString, Required: true, ValidateFunc: validation.StringInSlice([]string{"Integration", "OrganizationAdmin", "RepositoryRole", "Team", "DeployKey"}, false), - Description: "The type of actor that can bypass a ruleset. See https://docs.github.com/en/rest/orgs/rules for more information", + Description: "The type of actor that can bypass a ruleset. See [GitHub Documentation](https://docs.github.com/en/rest/orgs/rules) for more information", }, "bypass_mode": { Type: schema.TypeString, @@ -578,8 +582,9 @@ func resourceGithubOrganizationRuleset() *schema.Resource { }, }, "etag": { - Type: schema.TypeString, - Computed: true, + Type: schema.TypeString, + Description: "The ETag of the ruleset.", + Computed: true, }, }, } diff --git a/github/resource_github_repository.go b/github/resource_github_repository.go index 8673877aea..3d87413ee9 100644 --- a/github/resource_github_repository.go +++ b/github/resource_github_repository.go @@ -32,6 +32,8 @@ func resourceGithubRepository() *schema.Resource { SchemaVersion: 1, MigrateState: resourceGithubRepositoryMigrateState, + Description: "Creates and manages repositories within GitHub organizations or personal accounts", + Schema: map[string]*schema.Schema{ "name": { Type: schema.TypeString, diff --git a/go.mod b/go.mod index eacd1663f7..700b7c7934 100644 --- a/go.mod +++ b/go.mod @@ -3,9 +3,7 @@ module github.com/integrations/terraform-provider-github/v6 go 1.24.0 require ( - github.com/client9/misspell v0.3.4 github.com/go-jose/go-jose/v3 v3.0.4 - github.com/golangci/golangci-lint/v2 v2.6.2 github.com/google/go-github/v77 v77.0.0 github.com/google/uuid v1.6.0 github.com/hashicorp/go-cty v1.5.0 @@ -17,231 +15,49 @@ require ( ) require ( - 4d63.com/gocheckcompilerdirectives v1.3.0 // indirect - 4d63.com/gochecknoglobals v0.2.2 // indirect - codeberg.org/chavacava/garif v0.2.0 // indirect - dev.gaijin.team/go/exhaustruct/v4 v4.0.0 // indirect - dev.gaijin.team/go/golib v0.6.0 // indirect - github.com/4meepo/tagalign v1.4.3 // indirect - github.com/Abirdcfly/dupword v0.1.7 // indirect - github.com/AdminBenni/iota-mixing v1.0.0 // indirect - github.com/AlwxSin/noinlineerr v1.0.5 // indirect - github.com/Antonboom/errname v1.1.1 // indirect - github.com/Antonboom/nilnil v1.1.1 // indirect - github.com/Antonboom/testifylint v1.6.4 // indirect - github.com/BurntSushi/toml v1.5.0 // indirect - github.com/Djarvur/go-err113 v0.1.1 // indirect - github.com/Masterminds/semver/v3 v3.4.0 // indirect - github.com/MirrexOne/unqueryvet v1.2.1 // indirect - github.com/OpenPeeDeeP/depguard/v2 v2.2.1 // indirect github.com/ProtonMail/go-crypto v1.1.6 // indirect github.com/agext/levenshtein v1.2.2 // indirect - github.com/alecthomas/chroma/v2 v2.20.0 // indirect - github.com/alecthomas/go-check-sumtype v0.3.1 // indirect - github.com/alexkohler/nakedret/v2 v2.0.6 // indirect - github.com/alexkohler/prealloc v1.0.0 // indirect - github.com/alfatraining/structtag v1.0.0 // indirect - github.com/alingse/asasalint v0.0.11 // indirect - github.com/alingse/nilnesserr v0.2.0 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect - github.com/ashanbrown/forbidigo/v2 v2.3.0 // indirect - github.com/ashanbrown/makezero/v2 v2.1.0 // indirect - github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect - github.com/beorn7/perks v1.0.1 // indirect - github.com/bkielbasa/cyclop v1.2.3 // indirect - github.com/blizzy78/varnamelen v0.8.0 // indirect - github.com/bombsimon/wsl/v4 v4.7.0 // indirect - github.com/bombsimon/wsl/v5 v5.3.0 // indirect - github.com/breml/bidichk v0.3.3 // indirect - github.com/breml/errchkjson v0.4.1 // indirect - github.com/butuzov/ireturn v0.4.0 // indirect - github.com/butuzov/mirror v1.3.0 // indirect - github.com/catenacyber/perfsprint v0.10.0 // indirect - github.com/ccojocar/zxcvbn-go v1.0.4 // indirect - github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/charithe/durationcheck v0.0.11 // indirect - github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect - github.com/charmbracelet/lipgloss v1.1.0 // indirect - github.com/charmbracelet/x/ansi v0.8.0 // indirect - github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect - github.com/charmbracelet/x/term v0.2.1 // indirect - github.com/ckaznocha/intrange v0.3.1 // indirect github.com/cloudflare/circl v1.6.1 // indirect - github.com/curioswitch/go-reassign v0.3.0 // indirect - github.com/daixiang0/gci v0.13.7 // indirect - github.com/dave/dst v0.27.3 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/denis-tingaikin/go-header v0.5.0 // indirect - github.com/dlclark/regexp2 v1.11.5 // indirect - github.com/ettle/strcase v0.2.0 // indirect github.com/fatih/color v1.18.0 // indirect - github.com/fatih/structtag v1.2.0 // indirect - github.com/firefart/nonamedreturns v1.0.6 // indirect - github.com/fsnotify/fsnotify v1.5.4 // indirect - github.com/fzipp/gocyclo v0.6.0 // indirect - github.com/ghostiam/protogetter v0.3.17 // indirect - github.com/go-critic/go-critic v0.14.2 // indirect - github.com/go-toolsmith/astcast v1.1.0 // indirect - github.com/go-toolsmith/astcopy v1.1.0 // indirect - github.com/go-toolsmith/astequal v1.2.0 // indirect - github.com/go-toolsmith/astfmt v1.1.0 // indirect - github.com/go-toolsmith/astp v1.1.0 // indirect - github.com/go-toolsmith/strparse v1.1.0 // indirect - github.com/go-toolsmith/typep v1.1.0 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect - github.com/go-xmlfmt/xmlfmt v1.1.3 // indirect - github.com/gobwas/glob v0.2.3 // indirect - github.com/godoc-lint/godoc-lint v0.10.1 // indirect - github.com/gofrs/flock v0.13.0 // indirect github.com/golang/protobuf v1.5.4 // indirect - github.com/golangci/asciicheck v0.5.0 // indirect - github.com/golangci/dupl v0.0.0-20250308024227-f665c8d69b32 // indirect - github.com/golangci/go-printf-func-name v0.1.1 // indirect - github.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d // indirect - github.com/golangci/golines v0.0.0-20250217134842-442fd0091d95 // indirect - github.com/golangci/misspell v0.7.0 // indirect - github.com/golangci/plugin-module-register v0.1.2 // indirect - github.com/golangci/revgrep v0.8.0 // indirect - github.com/golangci/swaggoswag v0.0.0-20250504205917-77f2aca3143e // indirect - github.com/golangci/unconvert v0.0.0-20250410112200-a129a6e6413e // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/go-querystring v1.1.0 // indirect - github.com/gordonklaus/ineffassign v0.2.0 // indirect - github.com/gostaticanalysis/analysisutil v0.7.1 // indirect - github.com/gostaticanalysis/comment v1.5.0 // indirect - github.com/gostaticanalysis/forcetypeassert v0.2.0 // indirect - github.com/gostaticanalysis/nilerr v0.1.2 // indirect - github.com/hashicorp/errwrap v1.0.0 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-checkpoint v0.5.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-hclog v1.6.3 // indirect - github.com/hashicorp/go-immutable-radix/v2 v2.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-plugin v1.7.0 // indirect github.com/hashicorp/go-retryablehttp v0.7.7 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/go-version v1.7.0 // indirect - github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/hashicorp/hc-install v0.9.2 // indirect - github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/hcl/v2 v2.24.0 // indirect github.com/hashicorp/logutils v1.0.0 // indirect - github.com/hashicorp/terraform-exec v0.23.1 // indirect - github.com/hashicorp/terraform-json v0.27.1 // indirect + github.com/hashicorp/terraform-exec v0.24.0 // indirect + github.com/hashicorp/terraform-json v0.27.2 // indirect github.com/hashicorp/terraform-plugin-go v0.29.0 // indirect github.com/hashicorp/terraform-plugin-log v0.9.0 // indirect github.com/hashicorp/terraform-registry-address v0.4.0 // indirect github.com/hashicorp/terraform-svchost v0.1.1 // indirect github.com/hashicorp/yamux v0.1.2 // indirect - github.com/hexops/gotextdiff v1.0.3 // indirect - github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/jgautheron/goconst v1.8.2 // indirect - github.com/jingyugao/rowserrcheck v1.1.1 // indirect - github.com/jjti/go-spancheck v0.6.5 // indirect - github.com/julz/importas v0.2.0 // indirect - github.com/karamaru-alpha/copyloopvar v1.2.2 // indirect - github.com/kisielk/errcheck v1.9.0 // indirect - github.com/kkHAIKE/contextcheck v1.1.6 // indirect - github.com/kulti/thelper v0.7.1 // indirect - github.com/kunwardeep/paralleltest v1.0.15 // indirect - github.com/lasiar/canonicalheader v1.1.2 // indirect - github.com/ldez/exptostd v0.4.5 // indirect - github.com/ldez/gomoddirectives v0.7.1 // indirect - github.com/ldez/grignotin v0.10.1 // indirect - github.com/ldez/tagliatelle v0.7.2 // indirect - github.com/ldez/usetesting v0.5.0 // indirect - github.com/leonklingele/grouper v1.1.2 // indirect - github.com/lucasb-eyer/go-colorful v1.2.0 // indirect - github.com/macabu/inamedparam v0.2.0 // indirect - github.com/magiconair/properties v1.8.6 // indirect - github.com/manuelarte/embeddedstructfieldcheck v0.4.0 // indirect - github.com/manuelarte/funcorder v0.5.0 // indirect - github.com/maratori/testableexamples v1.0.1 // indirect - github.com/maratori/testpackage v1.1.2 // indirect - github.com/matoous/godox v1.1.0 // indirect + github.com/kr/text v0.2.0 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-runewidth v0.0.16 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect - github.com/mgechev/revive v1.12.0 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect - github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect - github.com/moricho/tparallel v0.3.2 // indirect - github.com/muesli/termenv v0.16.0 // indirect - github.com/nakabonne/nestif v0.3.1 // indirect - github.com/nishanths/exhaustive v0.12.0 // indirect - github.com/nishanths/predeclared v0.2.2 // indirect - github.com/nunnatsa/ginkgolinter v0.21.2 // indirect github.com/oklog/run v1.1.0 // indirect - github.com/pelletier/go-toml v1.9.5 // indirect - github.com/pelletier/go-toml/v2 v2.2.4 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/polyfloyd/go-errorlint v1.8.0 // indirect - github.com/prometheus/client_golang v1.12.1 // indirect - github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.32.1 // indirect - github.com/prometheus/procfs v0.7.3 // indirect - github.com/quasilyte/go-ruleguard v0.4.5 // indirect - github.com/quasilyte/go-ruleguard/dsl v0.3.23 // indirect - github.com/quasilyte/gogrep v0.5.0 // indirect - github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect - github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect - github.com/raeperd/recvcheck v0.2.0 // indirect - github.com/rivo/uniseg v0.4.7 // indirect - github.com/rogpeppe/go-internal v1.14.1 // indirect - github.com/ryancurrah/gomodguard v1.4.1 // indirect - github.com/ryanrolds/sqlclosecheck v0.5.1 // indirect - github.com/sanposhiho/wastedassign/v2 v2.1.0 // indirect - github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect - github.com/sashamelentyev/interfacebloat v1.1.0 // indirect - github.com/sashamelentyev/usestdlibvars v1.29.0 // indirect - github.com/securego/gosec/v2 v2.22.10 // indirect github.com/shurcooL/graphql v0.0.0-20220606043923-3cf50f8a0a29 // indirect - github.com/sirupsen/logrus v1.9.3 // indirect - github.com/sivchari/containedctx v1.0.3 // indirect - github.com/sonatard/noctx v0.4.0 // indirect - github.com/sourcegraph/go-diff v0.7.0 // indirect - github.com/spf13/afero v1.14.0 // indirect - github.com/spf13/cast v1.5.0 // indirect - github.com/spf13/cobra v1.10.1 // indirect - github.com/spf13/jwalterweatherman v1.1.0 // indirect - github.com/spf13/pflag v1.0.10 // indirect - github.com/spf13/viper v1.12.0 // indirect - github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect - github.com/stbenjam/no-sprintf-host-port v0.2.0 // indirect - github.com/stretchr/objx v0.5.2 // indirect - github.com/subosito/gotenv v1.4.1 // indirect - github.com/tetafro/godot v1.5.4 // indirect - github.com/timakin/bodyclose v0.0.0-20241222091800-1db5c5ca4d67 // indirect - github.com/timonwong/loggercheck v0.11.0 // indirect - github.com/tomarrell/wrapcheck/v2 v2.11.0 // indirect - github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect - github.com/ultraware/funlen v0.2.0 // indirect - github.com/ultraware/whitespace v0.2.0 // indirect - github.com/uudashr/gocognit v1.2.0 // indirect - github.com/uudashr/iface v1.4.1 // indirect github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect - github.com/xen0n/gosmopolitan v1.3.0 // indirect - github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect - github.com/yagipy/maintidx v1.0.0 // indirect - github.com/yeya24/promlinter v0.3.0 // indirect - github.com/ykadowak/zerologlint v0.1.5 // indirect github.com/zclconf/go-cty v1.17.0 // indirect - gitlab.com/bosi/decorder v0.4.2 // indirect - go-simpler.org/musttag v0.14.0 // indirect - go-simpler.org/sloglint v0.11.1 // indirect - go.augendre.info/arangolint v0.3.1 // indirect - go.augendre.info/fatcontext v0.9.0 // indirect - go.uber.org/automaxprocs v1.6.0 // indirect - go.uber.org/multierr v1.10.0 // indirect - go.uber.org/zap v1.27.0 // indirect - golang.org/x/exp/typeparams v0.0.0-20251023183803-a4bb9ffd2546 // indirect golang.org/x/mod v0.29.0 // indirect golang.org/x/net v0.47.0 // indirect golang.org/x/sync v0.18.0 // indirect @@ -252,10 +68,5 @@ require ( google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c // indirect google.golang.org/grpc v1.75.1 // indirect google.golang.org/protobuf v1.36.9 // indirect - gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - honnef.co/go/tools v0.6.1 // indirect - mvdan.cc/gofumpt v0.9.2 // indirect - mvdan.cc/unparam v0.0.0-20251027182757-5beb8c8f8f15 // indirect ) diff --git a/go.sum b/go.sum index a883320f4a..eba003754c 100644 --- a/go.sum +++ b/go.sum @@ -1,334 +1,54 @@ -4d63.com/gocheckcompilerdirectives v1.3.0 h1:Ew5y5CtcAAQeTVKUVFrE7EwHMrTO6BggtEj8BZSjZ3A= -4d63.com/gocheckcompilerdirectives v1.3.0/go.mod h1:ofsJ4zx2QAuIP/NO/NAh1ig6R1Fb18/GI7RVMwz7kAY= -4d63.com/gochecknoglobals v0.2.2 h1:H1vdnwnMaZdQW/N+NrkT1SZMTBmcwHe9Vq8lJcYYTtU= -4d63.com/gochecknoglobals v0.2.2/go.mod h1:lLxwTQjL5eIesRbvnzIP3jZtG140FnTdz+AlMa+ogt0= -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -codeberg.org/chavacava/garif v0.2.0 h1:F0tVjhYbuOCnvNcU3YSpO6b3Waw6Bimy4K0mM8y6MfY= -codeberg.org/chavacava/garif v0.2.0/go.mod h1:P2BPbVbT4QcvLZrORc2T29szK3xEOlnl0GiPTJmEqBQ= dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= -dev.gaijin.team/go/exhaustruct/v4 v4.0.0 h1:873r7aNneqoBB3IaFIzhvt2RFYTuHgmMjoKfwODoI1Y= -dev.gaijin.team/go/exhaustruct/v4 v4.0.0/go.mod h1:aZ/k2o4Y05aMJtiux15x8iXaumE88YdiB0Ai4fXOzPI= -dev.gaijin.team/go/golib v0.6.0 h1:v6nnznFTs4bppib/NyU1PQxobwDHwCXXl15P7DV5Zgo= -dev.gaijin.team/go/golib v0.6.0/go.mod h1:uY1mShx8Z/aNHWDyAkZTkX+uCi5PdX7KsG1eDQa2AVE= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/4meepo/tagalign v1.4.3 h1:Bnu7jGWwbfpAie2vyl63Zup5KuRv21olsPIha53BJr8= -github.com/4meepo/tagalign v1.4.3/go.mod h1:00WwRjiuSbrRJnSVeGWPLp2epS5Q/l4UEy0apLLS37c= -github.com/Abirdcfly/dupword v0.1.7 h1:2j8sInznrje4I0CMisSL6ipEBkeJUJAmK1/lfoNGWrQ= -github.com/Abirdcfly/dupword v0.1.7/go.mod h1:K0DkBeOebJ4VyOICFdppB23Q0YMOgVafM0zYW0n9lF4= -github.com/AdminBenni/iota-mixing v1.0.0 h1:Os6lpjG2dp/AE5fYBPAA1zfa2qMdCAWwPMCgpwKq7wo= -github.com/AdminBenni/iota-mixing v1.0.0/go.mod h1:i4+tpAaB+qMVIV9OK3m4/DAynOd5bQFaOu+2AhtBCNY= -github.com/AlwxSin/noinlineerr v1.0.5 h1:RUjt63wk1AYWTXtVXbSqemlbVTb23JOSRiNsshj7TbY= -github.com/AlwxSin/noinlineerr v1.0.5/go.mod h1:+QgkkoYrMH7RHvcdxdlI7vYYEdgeoFOVjU9sUhw/rQc= -github.com/Antonboom/errname v1.1.1 h1:bllB7mlIbTVzO9jmSWVWLjxTEbGBVQ1Ff/ClQgtPw9Q= -github.com/Antonboom/errname v1.1.1/go.mod h1:gjhe24xoxXp0ScLtHzjiXp0Exi1RFLKJb0bVBtWKCWQ= -github.com/Antonboom/nilnil v1.1.1 h1:9Mdr6BYd8WHCDngQnNVV0b554xyisFioEKi30sksufQ= -github.com/Antonboom/nilnil v1.1.1/go.mod h1:yCyAmSw3doopbOWhJlVci+HuyNRuHJKIv6V2oYQa8II= -github.com/Antonboom/testifylint v1.6.4 h1:gs9fUEy+egzxkEbq9P4cpcMB6/G0DYdMeiFS87UiqmQ= -github.com/Antonboom/testifylint v1.6.4/go.mod h1:YO33FROXX2OoUfwjz8g+gUxQXio5i9qpVy7nXGbxDD4= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg= -github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/Djarvur/go-err113 v0.1.1 h1:eHfopDqXRwAi+YmCUas75ZE0+hoBHJ2GQNLYRSxao4g= -github.com/Djarvur/go-err113 v0.1.1/go.mod h1:IaWJdYFLg76t2ihfflPZnM1LIQszWOsFDh2hhhAVF6k= -github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= -github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/MirrexOne/unqueryvet v1.2.1 h1:M+zdXMq84g+E1YOLa7g7ExN3dWfZQrdDSTCM7gC+m/A= -github.com/MirrexOne/unqueryvet v1.2.1/go.mod h1:IWwCwMQlSWjAIteW0t+28Q5vouyktfujzYznSIWiuOg= -github.com/OpenPeeDeeP/depguard/v2 v2.2.1 h1:vckeWVESWp6Qog7UZSARNqfu/cZqvki8zsuj3piCMx4= -github.com/OpenPeeDeeP/depguard/v2 v2.2.1/go.mod h1:q4DKzC4UcVaAvcfd41CZh0PWpGgzrVxUYBlgKNGquUo= github.com/ProtonMail/go-crypto v1.1.6 h1:ZcV+Ropw6Qn0AX9brlQLAUXfqLBc7Bl+f/DmNxpLfdw= github.com/ProtonMail/go-crypto v1.1.6/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= github.com/agext/levenshtein v1.2.2 h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXvaqE= github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= -github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0= -github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= -github.com/alecthomas/chroma/v2 v2.20.0 h1:sfIHpxPyR07/Oylvmcai3X/exDlE8+FA820NTz+9sGw= -github.com/alecthomas/chroma/v2 v2.20.0/go.mod h1:e7tViK0xh/Nf4BYHl00ycY6rV7b8iXBksI9E359yNmA= -github.com/alecthomas/go-check-sumtype v0.3.1 h1:u9aUvbGINJxLVXiFvHUlPEaD7VDULsrxJb4Aq31NLkU= -github.com/alecthomas/go-check-sumtype v0.3.1/go.mod h1:A8TSiN3UPRw3laIgWEUOHHLPa6/r9MtoigdlP5h3K/E= -github.com/alecthomas/repr v0.5.1 h1:E3G4t2QbHTSNpPKBgMTln5KLkZHLOcU7r37J4pXBuIg= -github.com/alecthomas/repr v0.5.1/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/alexkohler/nakedret/v2 v2.0.6 h1:ME3Qef1/KIKr3kWX3nti3hhgNxw6aqN5pZmQiFSsuzQ= -github.com/alexkohler/nakedret/v2 v2.0.6/go.mod h1:l3RKju/IzOMQHmsEvXwkqMDzHHvurNQfAgE1eVmT40Q= -github.com/alexkohler/prealloc v1.0.0 h1:Hbq0/3fJPQhNkN0dR95AVrr6R7tou91y0uHG5pOcUuw= -github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE= -github.com/alfatraining/structtag v1.0.0 h1:2qmcUqNcCoyVJ0up879K614L9PazjBSFruTB0GOFjCc= -github.com/alfatraining/structtag v1.0.0/go.mod h1:p3Xi5SwzTi+Ryj64DqjLWz7XurHxbGsq6y3ubePJPus= -github.com/alingse/asasalint v0.0.11 h1:SFwnQXJ49Kx/1GghOFz1XGqHYKp21Kq1nHad/0WQRnw= -github.com/alingse/asasalint v0.0.11/go.mod h1:nCaoMhw7a9kSJObvQyVzNTPBDbNpdocqrSP7t/cW5+I= -github.com/alingse/nilnesserr v0.2.0 h1:raLem5KG7EFVb4UIDAXgrv3N2JIaffeKNtcEXkEWd/w= -github.com/alingse/nilnesserr v0.2.0/go.mod h1:1xJPrXonEtX7wyTq8Dytns5P2hNzoWymVUIaKm4HNFg= github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec= github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= -github.com/ashanbrown/forbidigo/v2 v2.3.0 h1:OZZDOchCgsX5gvToVtEBoV2UWbFfI6RKQTir2UZzSxo= -github.com/ashanbrown/forbidigo/v2 v2.3.0/go.mod h1:5p6VmsG5/1xx3E785W9fouMxIOkvY2rRV9nMdWadd6c= -github.com/ashanbrown/makezero/v2 v2.1.0 h1:snuKYMbqosNokUKm+R6/+vOPs8yVAi46La7Ck6QYSaE= -github.com/ashanbrown/makezero/v2 v2.1.0/go.mod h1:aEGT/9q3S8DHeE57C88z2a6xydvgx8J5hgXIGWgo0MY= -github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= -github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bkielbasa/cyclop v1.2.3 h1:faIVMIGDIANuGPWH031CZJTi2ymOQBULs9H21HSMa5w= -github.com/bkielbasa/cyclop v1.2.3/go.mod h1:kHTwA9Q0uZqOADdupvcFJQtp/ksSnytRMe8ztxG8Fuo= -github.com/blizzy78/varnamelen v0.8.0 h1:oqSblyuQvFsW1hbBHh1zfwrKe3kcSj0rnXkKzsQ089M= -github.com/blizzy78/varnamelen v0.8.0/go.mod h1:V9TzQZ4fLJ1DSrjVDfl89H7aMnTvKkApdHeyESmyR7k= -github.com/bombsimon/wsl/v4 v4.7.0 h1:1Ilm9JBPRczjyUs6hvOPKvd7VL1Q++PL8M0SXBDf+jQ= -github.com/bombsimon/wsl/v4 v4.7.0/go.mod h1:uV/+6BkffuzSAVYD+yGyld1AChO7/EuLrCF/8xTiapg= -github.com/bombsimon/wsl/v5 v5.3.0 h1:nZWREJFL6U3vgW/B1lfDOigl+tEF6qgs6dGGbFeR0UM= -github.com/bombsimon/wsl/v5 v5.3.0/go.mod h1:Gp8lD04z27wm3FANIUPZycXp+8huVsn0oxc+n4qfV9I= -github.com/breml/bidichk v0.3.3 h1:WSM67ztRusf1sMoqH6/c4OBCUlRVTKq+CbSeo0R17sE= -github.com/breml/bidichk v0.3.3/go.mod h1:ISbsut8OnjB367j5NseXEGGgO/th206dVa427kR8YTE= -github.com/breml/errchkjson v0.4.1 h1:keFSS8D7A2T0haP9kzZTi7o26r7kE3vymjZNeNDRDwg= -github.com/breml/errchkjson v0.4.1/go.mod h1:a23OvR6Qvcl7DG/Z4o0el6BRAjKnaReoPQFciAl9U3s= github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw= github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c= -github.com/butuzov/ireturn v0.4.0 h1:+s76bF/PfeKEdbG8b54aCocxXmi0wvYdOVsWxVO7n8E= -github.com/butuzov/ireturn v0.4.0/go.mod h1:ghI0FrCmap8pDWZwfPisFD1vEc56VKH4NpQUxDHta70= -github.com/butuzov/mirror v1.3.0 h1:HdWCXzmwlQHdVhwvsfBb2Au0r3HyINry3bDWLYXiKoc= -github.com/butuzov/mirror v1.3.0/go.mod h1:AEij0Z8YMALaq4yQj9CPPVYOyJQyiexpQEQgihajRfI= -github.com/catenacyber/perfsprint v0.10.0 h1:AZj1mYyxbxLRqmnYOeguZXEQwWOgQGm2wzLI5d7Hl/0= -github.com/catenacyber/perfsprint v0.10.0/go.mod h1:DJTGsi/Zufpuus6XPGJyKOTMELe347o6akPvWG9Zcsc= -github.com/ccojocar/zxcvbn-go v1.0.4 h1:FWnCIRMXPj43ukfX000kvBZvV6raSxakYr1nzyNrUcc= -github.com/ccojocar/zxcvbn-go v1.0.4/go.mod h1:3GxGX+rHmueTUMvm5ium7irpyjmm7ikxYFOSJB21Das= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= -github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/charithe/durationcheck v0.0.11 h1:g1/EX1eIiKS57NTWsYtHDZ/APfeXKhye1DidBcABctk= -github.com/charithe/durationcheck v0.0.11/go.mod h1:x5iZaixRNl8ctbM+3B2RrPG5t856TxRyVQEnbIEM2X4= -github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs= -github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk= -github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY= -github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30= -github.com/charmbracelet/x/ansi v0.8.0 h1:9GTq3xq9caJW8ZrBTe0LIe2fvfLR/bYXKTx2llXn7xE= -github.com/charmbracelet/x/ansi v0.8.0/go.mod h1:wdYl/ONOLHLIVmQaxbIYEC/cRKOQyjTkowiI4blgS9Q= -github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd h1:vy0GVL4jeHEwG5YOXDmi86oYw2yuYUGqz6a8sLwg0X8= -github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs= -github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ= -github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/ckaznocha/intrange v0.3.1 h1:j1onQyXvHUsPWujDH6WIjhyH26gkRt/txNlV7LspvJs= -github.com/ckaznocha/intrange v0.3.1/go.mod h1:QVepyz1AkUoFQkpEqksSYpNpUo3c5W7nWh/s6SHIJJk= -github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0= github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= -github.com/curioswitch/go-reassign v0.3.0 h1:dh3kpQHuADL3cobV/sSGETA8DOv457dwl+fbBAhrQPs= -github.com/curioswitch/go-reassign v0.3.0/go.mod h1:nApPCCTtqLJN/s8HfItCcKV0jIPwluBOvZP+dsJGA88= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s= github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= -github.com/daixiang0/gci v0.13.7 h1:+0bG5eK9vlI08J+J/NWGbWPTNiXPG4WhNLJOkSxWITQ= -github.com/daixiang0/gci v0.13.7/go.mod h1:812WVN6JLFY9S6Tv76twqmNqevN0pa3SX3nih0brVzQ= -github.com/dave/dst v0.27.3 h1:P1HPoMza3cMEquVf9kKy8yXsFirry4zEnWOdYPOoIzY= -github.com/dave/dst v0.27.3/go.mod h1:jHh6EOibnHgcUW3WjKHisiooEkYwqpHLBSX1iOBhEyc= -github.com/dave/jennifer v1.7.1 h1:B4jJJDHelWcDhlRQxWeo0Npa/pYKBLrirAQoTN45txo= -github.com/dave/jennifer v1.7.1/go.mod h1:nXbxhEmQfOZhWml3D1cDK5M1FLnMSozpbFN/m3RmGZc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/denis-tingaikin/go-header v0.5.0 h1:SRdnP5ZKvcO9KKRP1KJrhFR3RrlGuD+42t4429eC9k8= -github.com/denis-tingaikin/go-header v0.5.0/go.mod h1:mMenU5bWrok6Wl2UsZjy+1okegmwQ3UgWl4V1D8gjlY= -github.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ= -github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/ettle/strcase v0.2.0 h1:fGNiVF21fHXpX1niBgk0aROov1LagYsOwV/xqKDKR/Q= -github.com/ettle/strcase v0.2.0/go.mod h1:DajmHElDSaX76ITe3/VHVyMin4LWSJN5Z909Wp+ED1A= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= -github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= -github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= -github.com/firefart/nonamedreturns v1.0.6 h1:vmiBcKV/3EqKY3ZiPxCINmpS431OcE1S47AQUwhrg8E= -github.com/firefart/nonamedreturns v1.0.6/go.mod h1:R8NisJnSIpvPWheCq0mNRXJok6D8h7fagJTF8EMEwCo= -github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= -github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= -github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= -github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= -github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo= -github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA= -github.com/ghostiam/protogetter v0.3.17 h1:sjGPErP9o7i2Ym+z3LsQzBdLCNaqbYy2iJQPxGXg04Q= -github.com/ghostiam/protogetter v0.3.17/go.mod h1:AivIX1eKA/TcUmzZdzbl+Tb8tjIe8FcyG6JFyemQAH4= -github.com/go-critic/go-critic v0.14.2 h1:PMvP5f+LdR8p6B29npvChUXbD1vrNlKDf60NJtgMBOo= -github.com/go-critic/go-critic v0.14.2/go.mod h1:xwntfW6SYAd7h1OqDzmN6hBX/JxsEKl5up/Y2bsxgVQ= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UNbRM= github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU= github.com/go-git/go-git/v5 v5.14.0 h1:/MD3lCrGjCen5WfEAzKg00MJJffKhC8gzS80ycmCi60= github.com/go-git/go-git/v5 v5.14.0/go.mod h1:Z5Xhoia5PcWA3NF8vRLURn9E5FRhSl7dGj9ItW3Wk5k= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-jose/go-jose/v3 v3.0.4 h1:Wp5HA7bLQcKnf6YYao/4kpRpVMp/yf6+pJKV8WFSaNY= github.com/go-jose/go-jose/v3 v3.0.4/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI= -github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= -github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= -github.com/go-toolsmith/astcast v1.1.0 h1:+JN9xZV1A+Re+95pgnMgDboWNVnIMMQXwfBwLRPgSC8= -github.com/go-toolsmith/astcast v1.1.0/go.mod h1:qdcuFWeGGS2xX5bLM/c3U9lewg7+Zu4mr+xPwZIB4ZU= -github.com/go-toolsmith/astcopy v1.1.0 h1:YGwBN0WM+ekI/6SS6+52zLDEf8Yvp3n2seZITCUBt5s= -github.com/go-toolsmith/astcopy v1.1.0/go.mod h1:hXM6gan18VA1T/daUEHCFcYiW8Ai1tIwIzHY6srfEAw= -github.com/go-toolsmith/astequal v1.0.3/go.mod h1:9Ai4UglvtR+4up+bAD4+hCj7iTo4m/OXVTSLnCyTAx4= -github.com/go-toolsmith/astequal v1.1.0/go.mod h1:sedf7VIdCL22LD8qIvv7Nn9MuWJruQA/ysswh64lffQ= -github.com/go-toolsmith/astequal v1.2.0 h1:3Fs3CYZ1k9Vo4FzFhwwewC3CHISHDnVUPC4x0bI2+Cw= -github.com/go-toolsmith/astequal v1.2.0/go.mod h1:c8NZ3+kSFtFY/8lPso4v8LuJjdJiUFVnSuU3s0qrrDY= -github.com/go-toolsmith/astfmt v1.1.0 h1:iJVPDPp6/7AaeLJEruMsBUlOYCmvg0MoCfJprsOmcco= -github.com/go-toolsmith/astfmt v1.1.0/go.mod h1:OrcLlRwu0CuiIBp/8b5PYF9ktGVZUjlNMV634mhwuQ4= -github.com/go-toolsmith/astp v1.1.0 h1:dXPuCl6u2llURjdPLLDxJeZInAeZ0/eZwFJmqZMnpQA= -github.com/go-toolsmith/astp v1.1.0/go.mod h1:0T1xFGz9hicKs8Z5MfAqSUitoUYS30pDMsRVIDHs8CA= -github.com/go-toolsmith/pkgload v1.2.2 h1:0CtmHq/02QhxcF7E9N5LIFcYFsMR5rdovfqTtRKkgIk= -github.com/go-toolsmith/pkgload v1.2.2/go.mod h1:R2hxLNRKuAsiXCo2i5J6ZQPhnPMOVtU+f0arbFPWCus= -github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= -github.com/go-toolsmith/strparse v1.1.0 h1:GAioeZUK9TGxnLS+qfdqNbA4z0SSm5zVNtCQiyP2Bvw= -github.com/go-toolsmith/strparse v1.1.0/go.mod h1:7ksGy58fsaQkGQlY8WVoBFNyEPMGuJin1rfoPS4lBSQ= -github.com/go-toolsmith/typep v1.1.0 h1:fIRYDyF+JywLfqzyhdiHzRop/GQDxxNhLGQ6gFUNHus= -github.com/go-toolsmith/typep v1.1.0/go.mod h1:fVIw+7zjdsMxDA3ITWnH1yOiw1rnTQKCsF/sk2H/qig= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= -github.com/go-xmlfmt/xmlfmt v1.1.3 h1:t8Ey3Uy7jDSEisW2K3somuMKIpzktkWptA0iFCnRUWY= -github.com/go-xmlfmt/xmlfmt v1.1.3/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= -github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= -github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/godoc-lint/godoc-lint v0.10.1 h1:ZPUVzlDtJfA+P688JfPJPkI/SuzcBr/753yGIk5bOPA= -github.com/godoc-lint/godoc-lint v0.10.1/go.mod h1:KleLcHu/CGSvkjUH2RvZyoK1MBC7pDQg4NxMYLcBBsw= -github.com/gofrs/flock v0.13.0 h1:95JolYOvGMqeH31+FC7D2+uULf6mG61mEZ/A8dRYMzw= -github.com/gofrs/flock v0.13.0/go.mod h1:jxeyy9R1auM5S6JYDBhDt+E2TCo7DkratH4Pgi8P+Z0= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/golangci/asciicheck v0.5.0 h1:jczN/BorERZwK8oiFBOGvlGPknhvq0bjnysTj4nUfo0= -github.com/golangci/asciicheck v0.5.0/go.mod h1:5RMNAInbNFw2krqN6ibBxN/zfRFa9S6tA1nPdM0l8qQ= -github.com/golangci/dupl v0.0.0-20250308024227-f665c8d69b32 h1:WUvBfQL6EW/40l6OmeSBYQJNSif4O11+bmWEz+C7FYw= -github.com/golangci/dupl v0.0.0-20250308024227-f665c8d69b32/go.mod h1:NUw9Zr2Sy7+HxzdjIULge71wI6yEg1lWQr7Evcu8K0E= -github.com/golangci/go-printf-func-name v0.1.1 h1:hIYTFJqAGp1iwoIfsNTpoq1xZAarogrvjO9AfiW3B4U= -github.com/golangci/go-printf-func-name v0.1.1/go.mod h1:Es64MpWEZbh0UBtTAICOZiB+miW53w/K9Or/4QogJss= -github.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d h1:viFft9sS/dxoYY0aiOTsLKO2aZQAPT4nlQCsimGcSGE= -github.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d/go.mod h1:ivJ9QDg0XucIkmwhzCDsqcnxxlDStoTl89jDMIoNxKY= -github.com/golangci/golangci-lint/v2 v2.6.2 h1:jkMSVv36JmyTENcEertckvimvjPcD5qxNM7W7qhECvI= -github.com/golangci/golangci-lint/v2 v2.6.2/go.mod h1:fSIMDiBt9kzdpnvvV7GO6iWzyv5uaeZ+iPor+2uRczE= -github.com/golangci/golines v0.0.0-20250217134842-442fd0091d95 h1:AkK+w9FZBXlU/xUmBtSJN1+tAI4FIvy5WtnUnY8e4p8= -github.com/golangci/golines v0.0.0-20250217134842-442fd0091d95/go.mod h1:k9mmcyWKSTMcPPvQUCfRWWQ9VHJ1U9Dc0R7kaXAgtnQ= -github.com/golangci/misspell v0.7.0 h1:4GOHr/T1lTW0hhR4tgaaV1WS/lJ+ncvYCoFKmqJsj0c= -github.com/golangci/misspell v0.7.0/go.mod h1:WZyyI2P3hxPY2UVHs3cS8YcllAeyfquQcKfdeE9AFVg= -github.com/golangci/plugin-module-register v0.1.2 h1:e5WM6PO6NIAEcij3B053CohVp3HIYbzSuP53UAYgOpg= -github.com/golangci/plugin-module-register v0.1.2/go.mod h1:1+QGTsKBvAIvPvoY/os+G5eoqxWn70HYDm2uvUyGuVw= -github.com/golangci/revgrep v0.8.0 h1:EZBctwbVd0aMeRnNUsFogoyayvKHyxlV3CdUA46FX2s= -github.com/golangci/revgrep v0.8.0/go.mod h1:U4R/s9dlXZsg8uJmaR1GrloUr14D7qDl8gi2iPXJH8k= -github.com/golangci/swaggoswag v0.0.0-20250504205917-77f2aca3143e h1:ai0EfmVYE2bRA5htgAG9r7s3tHsfjIhN98WshBTJ9jM= -github.com/golangci/swaggoswag v0.0.0-20250504205917-77f2aca3143e/go.mod h1:Vrn4B5oR9qRwM+f54koyeH3yzphlecwERs0el27Fr/s= -github.com/golangci/unconvert v0.0.0-20250410112200-a129a6e6413e h1:gD6P7NEo7Eqtt0ssnqSJNNndxe69DOQ24A5h7+i3KpM= -github.com/golangci/unconvert v0.0.0-20250410112200-a129a6e6413e/go.mod h1:h+wZwLjUTJnm/P2rwlbJdRPZXOzaT36/FwnPnY2inzc= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= @@ -336,39 +56,11 @@ github.com/google/go-github/v77 v77.0.0 h1:9DsKKbZqil5y/4Z9mNpZDQnpli6PJbqipSuuN github.com/google/go-github/v77 v77.0.0/go.mod h1:c8VmGXRUmaZUqbctUcGEDWYnMrtzZfJhDSylEf1wfmA= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6 h1:EEHtgt9IwisQ2AZ4pIsMjahcegHh6rmhqxzIRQIyepY= -github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6/go.mod h1:I6V7YzU0XDpsHqbsyrghnFZLO1gwK6NPTNvmetQIk9U= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/gordonklaus/ineffassign v0.2.0 h1:Uths4KnmwxNJNzq87fwQQDDnbNb7De00VOk9Nu0TySs= -github.com/gordonklaus/ineffassign v0.2.0/go.mod h1:TIpymnagPSexySzs7F9FnO1XFTy8IT3a59vmZp5Y9Lw= -github.com/gostaticanalysis/analysisutil v0.7.1 h1:ZMCjoue3DtDWQ5WyU16YbjbQEQ3VuzwxALrpYd+HeKk= -github.com/gostaticanalysis/analysisutil v0.7.1/go.mod h1:v21E3hY37WKMGSnbsw2S/ojApNWb6C1//mXO48CXbVc= -github.com/gostaticanalysis/comment v1.4.2/go.mod h1:KLUTGDv6HOCotCH8h2erHKmpci2ZoR8VPu34YA2uzdM= -github.com/gostaticanalysis/comment v1.5.0 h1:X82FLl+TswsUMpMh17srGRuKaaXprTaytmEpgnKIDu8= -github.com/gostaticanalysis/comment v1.5.0/go.mod h1:V6eb3gpCv9GNVqb6amXzEUX3jXLVK/AdA+IrAMSqvEc= -github.com/gostaticanalysis/forcetypeassert v0.2.0 h1:uSnWrrUEYDr86OCxWa4/Tp2jeYDlogZiZHzGkWFefTk= -github.com/gostaticanalysis/forcetypeassert v0.2.0/go.mod h1:M5iPavzE9pPqWyeiVXSFghQjljW1+l/Uke3PXHS6ILY= -github.com/gostaticanalysis/nilerr v0.1.2 h1:S6nk8a9N8g062nsx63kUkF6AzbHGw7zzyHMcpu52xQU= -github.com/gostaticanalysis/nilerr v0.1.2/go.mod h1:A19UHhoY3y8ahoL7YKz6sdjDtduwTSI4CsymaC2htPA= -github.com/gostaticanalysis/testutil v0.3.1-0.20210208050101-bfb5c8eec0e4/go.mod h1:D+FIZ+7OahH3ePw/izIEeH5I06eKs1IKI4Xr64/Am3M= -github.com/gostaticanalysis/testutil v0.5.0 h1:Dq4wT1DdTwTGCQQv3rl3IvD5Ld0E6HiY+3Zh0sUGqw8= -github.com/gostaticanalysis/testutil v0.5.0/go.mod h1:OLQSbuM6zw2EvCcXTz1lVq5unyoNft372msDY0nY5Hs= -github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-checkpoint v0.5.0 h1:MFYpPZCnQqQTE18jFwSII6eUQrD/oxMFp3mlgcqk5mU= github.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuDrwkBuEQsVcpCOgg= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= @@ -378,8 +70,6 @@ github.com/hashicorp/go-cty v1.5.0 h1:EkQ/v+dDNUqnuVpmS5fPqyY71NXVgT5gf32+57xY8g github.com/hashicorp/go-cty v1.5.0/go.mod h1:lFUCG5kd8exDobgSfyj4ONE/dc822kiYMguVKdHGMLM= github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= -github.com/hashicorp/go-immutable-radix/v2 v2.1.0 h1:CUW5RYIcysz+D3B+l1mDeXrQ7fUvGGCwJfdASSzbrfo= -github.com/hashicorp/go-immutable-radix/v2 v2.1.0/go.mod h1:hgdqLXA4f6NIjRVisM1TJ9aOJVNRqKZj+xDGF6m7PBw= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-plugin v1.7.0 h1:YghfQH/0QmPNc/AZMTFE3ac8fipZyZECHdDPshfk+mA= @@ -389,25 +79,18 @@ github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFO github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= -github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hc-install v0.9.2 h1:v80EtNX4fCVHqzL9Lg/2xkp62bbvQMnvPQ0G+OmtO24= github.com/hashicorp/hc-install v0.9.2/go.mod h1:XUqBQNnuT4RsxoxiM9ZaUk0NX8hi2h+Lb6/c0OZnC/I= -github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl/v2 v2.24.0 h1:2QJdZ454DSsYGoaE6QheQZjtKZSUs9Nh2izTWiwQxvE= github.com/hashicorp/hcl/v2 v2.24.0/go.mod h1:oGoO1FIQYfn/AgyOhlg9qLC6/nOJPX3qGbkZpYAcqfM= github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/terraform-exec v0.23.1 h1:diK5NSSDXDKqHEOIQefBMu9ny+FhzwlwV0xgUTB7VTo= -github.com/hashicorp/terraform-exec v0.23.1/go.mod h1:e4ZEg9BJDRaSalGm2z8vvrPONt0XWG0/tXpmzYTf+dM= -github.com/hashicorp/terraform-json v0.27.1 h1:zWhEracxJW6lcjt/JvximOYyc12pS/gaKSy/wzzE7nY= -github.com/hashicorp/terraform-json v0.27.1/go.mod h1:GzPLJ1PLdUG5xL6xn1OXWIjteQRT2CNT9o/6A9mi9hE= +github.com/hashicorp/terraform-exec v0.24.0 h1:mL0xlk9H5g2bn0pPF6JQZk5YlByqSqrO5VoaNtAf8OE= +github.com/hashicorp/terraform-exec v0.24.0/go.mod h1:lluc/rDYfAhYdslLJQg3J0oDqo88oGQAdHR+wDqFvo4= +github.com/hashicorp/terraform-json v0.27.2 h1:BwGuzM6iUPqf9JYM/Z4AF1OJ5VVJEEzoKST/tRDBJKU= +github.com/hashicorp/terraform-json v0.27.2/go.mod h1:GzPLJ1PLdUG5xL6xn1OXWIjteQRT2CNT9o/6A9mi9hE= github.com/hashicorp/terraform-plugin-go v0.29.0 h1:1nXKl/nSpaYIUBU1IG/EsDOX0vv+9JxAltQyDMpq5mU= github.com/hashicorp/terraform-plugin-go v0.29.0/go.mod h1:vYZbIyvxyy0FWSmDHChCqKvI40cFTDGSb3D8D70i9GM= github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0= @@ -420,44 +103,12 @@ github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S github.com/hashicorp/terraform-svchost v0.1.1/go.mod h1:mNsjQfZyf/Jhz35v6/0LWcv26+X7JPS+buii2c9/ctc= github.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8= github.com/hashicorp/yamux v0.1.2/go.mod h1:C+zze2n6e/7wshOZep2A70/aQU6QBRWJO/G6FT1wIns= -github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= -github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= -github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= -github.com/jgautheron/goconst v1.8.2 h1:y0XF7X8CikZ93fSNT6WBTb/NElBu9IjaY7CCYQrCMX4= -github.com/jgautheron/goconst v1.8.2/go.mod h1:A0oxgBCHy55NQn6sYpO7UdnA9p+h7cPtoOZUmvNIako= github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94= github.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8= -github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjzq7gFzUs= -github.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c= -github.com/jjti/go-spancheck v0.6.5 h1:lmi7pKxa37oKYIMScialXUK6hP3iY5F1gu+mLBPgYB8= -github.com/jjti/go-spancheck v0.6.5/go.mod h1:aEogkeatBrbYsyW6y5TgDfihCulDYciL1B7rG2vSsrU= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/julz/importas v0.2.0 h1:y+MJN/UdL63QbFJHws9BVC5RpA2iq0kpjrFajTGivjQ= -github.com/julz/importas v0.2.0/go.mod h1:pThlt589EnCYtMnmhmRYY/qn9lCf/frPOK+WMx3xiJY= -github.com/karamaru-alpha/copyloopvar v1.2.2 h1:yfNQvP9YaGQR7VaWLYcfZUlRP2eo2vhExWKxD/fP6q0= -github.com/karamaru-alpha/copyloopvar v1.2.2/go.mod h1:oY4rGZqZ879JkJMtX3RRkcXRkmUvH0x35ykgaKgsgJY= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= -github.com/kisielk/errcheck v1.9.0 h1:9xt1zI9EBfcYBvdU1nVrzMzzUPUtPKs9bVSIM3TAb3M= -github.com/kisielk/errcheck v1.9.0/go.mod h1:kQxWMMVZgIkDq7U8xtG/n2juOjbLgZtedi0D+/VL/i8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kkHAIKE/contextcheck v1.1.6 h1:7HIyRcnyzxL9Lz06NGhiKvenXq7Zw6Q0UQu/ttjfJCE= -github.com/kkHAIKE/contextcheck v1.1.6/go.mod h1:3dDbMRNBFaq8HFXWC1JyvDSPm43CmE6IuHam8Wr0rkg= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -465,42 +116,6 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kulti/thelper v0.7.1 h1:fI8QITAoFVLx+y+vSyuLBP+rcVIB8jKooNSCT2EiI98= -github.com/kulti/thelper v0.7.1/go.mod h1:NsMjfQEy6sd+9Kfw8kCP61W1I0nerGSYSFnGaxQkcbs= -github.com/kunwardeep/paralleltest v1.0.15 h1:ZMk4Qt306tHIgKISHWFJAO1IDQJLc6uDyJMLyncOb6w= -github.com/kunwardeep/paralleltest v1.0.15/go.mod h1:di4moFqtfz3ToSKxhNjhOZL+696QtJGCFe132CbBLGk= -github.com/lasiar/canonicalheader v1.1.2 h1:vZ5uqwvDbyJCnMhmFYimgMZnJMjwljN5VGY0VKbMXb4= -github.com/lasiar/canonicalheader v1.1.2/go.mod h1:qJCeLFS0G/QlLQ506T+Fk/fWMa2VmBUiEI2cuMK4djI= -github.com/ldez/exptostd v0.4.5 h1:kv2ZGUVI6VwRfp/+bcQ6Nbx0ghFWcGIKInkG/oFn1aQ= -github.com/ldez/exptostd v0.4.5/go.mod h1:QRjHRMXJrCTIm9WxVNH6VW7oN7KrGSht69bIRwvdFsM= -github.com/ldez/gomoddirectives v0.7.1 h1:FaULkvUIG36hj6chpwa+FdCNGZBsD7/fO+p7CCsM6pE= -github.com/ldez/gomoddirectives v0.7.1/go.mod h1:auDNtakWJR1rC+YX7ar+HmveqXATBAyEK1KYpsIRW/8= -github.com/ldez/grignotin v0.10.1 h1:keYi9rYsgbvqAZGI1liek5c+jv9UUjbvdj3Tbn5fn4o= -github.com/ldez/grignotin v0.10.1/go.mod h1:UlDbXFCARrXbWGNGP3S5vsysNXAPhnSuBufpTEbwOas= -github.com/ldez/tagliatelle v0.7.2 h1:KuOlL70/fu9paxuxbeqlicJnCspCRjH0x8FW+NfgYUk= -github.com/ldez/tagliatelle v0.7.2/go.mod h1:PtGgm163ZplJfZMZ2sf5nhUT170rSuPgBimoyYtdaSI= -github.com/ldez/usetesting v0.5.0 h1:3/QtzZObBKLy1F4F8jLuKJiKBjjVFi1IavpoWbmqLwc= -github.com/ldez/usetesting v0.5.0/go.mod h1:Spnb4Qppf8JTuRgblLrEWb7IE6rDmUpGvxY3iRrzvDQ= -github.com/leonklingele/grouper v1.1.2 h1:o1ARBDLOmmasUaNDesWqWCIFH3u7hoFlM84YrjT3mIY= -github.com/leonklingele/grouper v1.1.2/go.mod h1:6D0M/HVkhs2yRKRFZUoGjeDy7EZTfFBE9gl4kjmIGkA= -github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= -github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= -github.com/macabu/inamedparam v0.2.0 h1:VyPYpOc10nkhI2qeNUdh3Zket4fcZjEWe35poddBCpE= -github.com/macabu/inamedparam v0.2.0/go.mod h1:+Pee9/YfGe5LJ62pYXqB89lJ+0k5bsR8Wgz/C0Zlq3U= -github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= -github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= -github.com/manuelarte/embeddedstructfieldcheck v0.4.0 h1:3mAIyaGRtjK6EO9E73JlXLtiy7ha80b2ZVGyacxgfww= -github.com/manuelarte/embeddedstructfieldcheck v0.4.0/go.mod h1:z8dFSyXqp+fC6NLDSljRJeNQJJDWnY7RoWFzV3PC6UM= -github.com/manuelarte/funcorder v0.5.0 h1:llMuHXXbg7tD0i/LNw8vGnkDTHFpTnWqKPI85Rknc+8= -github.com/manuelarte/funcorder v0.5.0/go.mod h1:Yt3CiUQthSBMBxjShjdXMexmzpP8YGvGLjrxJNkO2hA= -github.com/maratori/testableexamples v1.0.1 h1:HfOQXs+XgfeRBJ+Wz0XfH+FHnoY9TVqL6Fcevpzy4q8= -github.com/maratori/testableexamples v1.0.1/go.mod h1:XE2F/nQs7B9N08JgyRmdGjYVGqxWwClLPCGSQhXQSrQ= -github.com/maratori/testpackage v1.1.2 h1:ffDSh+AgqluCLMXhM19f/cpvQAKygKAJXFl9aUjmbqs= -github.com/maratori/testpackage v1.1.2/go.mod h1:8F24GdVDFW5Ew43Et02jamrVMNXLUNaOynhDssITGfc= -github.com/matoous/godox v1.1.0 h1:W5mqwbyWrwZv6OQ5Z1a/DHGMOvXYCBP3+Ht7KMoJhq4= -github.com/matoous/godox v1.1.0/go.mod h1:jgE/3fUXiTurkdHOLT5WEkThTSuE7yxHv5iWPa80afs= -github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= -github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= @@ -509,16 +124,8 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= -github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/mgechev/revive v1.12.0 h1:Q+/kkbbwerrVYPv9d9efaPGmAO/NsxwW/nE6ahpQaCU= -github.com/mgechev/revive v1.12.0/go.mod h1:VXsY2LsTigk8XU9BpZauVLjVrhICMOV3k1lpB3CXrp8= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= @@ -527,184 +134,28 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/moricho/tparallel v0.3.2 h1:odr8aZVFA3NZrNybggMkYO3rgPRcqjeQUlBBFVxKHTI= -github.com/moricho/tparallel v0.3.2/go.mod h1:OQ+K3b4Ln3l2TZveGCywybl68glfLEwFGqvnjok8b+U= -github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc= -github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nakabonne/nestif v0.3.1 h1:wm28nZjhQY5HyYPx+weN3Q65k6ilSBxDb8v5S81B81U= -github.com/nakabonne/nestif v0.3.1/go.mod h1:9EtoZochLn5iUprVDmDjqGKPofoUEBL8U4Ngq6aY7OE= -github.com/nishanths/exhaustive v0.12.0 h1:vIY9sALmw6T/yxiASewa4TQcFsVYZQQRUQJhKRf3Swg= -github.com/nishanths/exhaustive v0.12.0/go.mod h1:mEZ95wPIZW+x8kC4TgC+9YCUgiST7ecevsVDTgc2obs= -github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk= -github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c= -github.com/nunnatsa/ginkgolinter v0.21.2 h1:khzWfm2/Br8ZemX8QM1pl72LwM+rMeW6VUbQ4rzh0Po= -github.com/nunnatsa/ginkgolinter v0.21.2/go.mod h1:GItSI5fw7mCGLPmkvGYrr1kEetZe7B593jcyOpyabsY= github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= -github.com/onsi/ginkgo/v2 v2.26.0 h1:1J4Wut1IlYZNEAWIV3ALrT9NfiaGW2cDCJQSFQMs/gE= -github.com/onsi/ginkgo/v2 v2.26.0/go.mod h1:qhEywmzWTBUY88kfO0BRvX4py7scov9yR+Az2oavUzw= -github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= -github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= -github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw= -github.com/otiai10/copy v1.14.0 h1:dCI/t1iTdYGtkvCuBG2BgR6KZa83PTclw4U5n2wAllU= -github.com/otiai10/copy v1.14.0/go.mod h1:ECfuL02W+/FkTWZWgQqXPWZgW9oeKCSQ5qVfSc4qc4w= -github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= -github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= -github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= -github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= -github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= -github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= -github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4= github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/polyfloyd/go-errorlint v1.8.0 h1:DL4RestQqRLr8U4LygLw8g2DX6RN1eBJOpa2mzsrl1Q= -github.com/polyfloyd/go-errorlint v1.8.0/go.mod h1:G2W0Q5roxbLCt0ZQbdoxQxXktTjwNyDbEaj3n7jvl4s= -github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= -github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk= -github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= -github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= -github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= -github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/quasilyte/go-ruleguard v0.4.5 h1:AGY0tiOT5hJX9BTdx/xBdoCubQUAE2grkqY2lSwvZcA= -github.com/quasilyte/go-ruleguard v0.4.5/go.mod h1:Vl05zJ538vcEEwu16V/Hdu7IYZWyKSwIy4c88Ro1kRE= -github.com/quasilyte/go-ruleguard/dsl v0.3.23 h1:lxjt5B6ZCiBeeNO8/oQsegE6fLeCzuMRoVWSkXC4uvY= -github.com/quasilyte/go-ruleguard/dsl v0.3.23/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= -github.com/quasilyte/gogrep v0.5.0 h1:eTKODPXbI8ffJMN+W2aE0+oL0z/nh8/5eNdiO34SOAo= -github.com/quasilyte/gogrep v0.5.0/go.mod h1:Cm9lpz9NZjEoL1tgZ2OgeUKPIxL1meE7eo60Z6Sk+Ng= -github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 h1:TCg2WBOl980XxGFEZSS6KlBGIV0diGdySzxATTWoqaU= -github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= -github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4lu7Gd+PU1fV2/qnDNfzT635KRSObncs= -github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ= -github.com/raeperd/recvcheck v0.2.0 h1:GnU+NsbiCqdC2XX5+vMZzP+jAJC5fht7rcVTAhX74UI= -github.com/raeperd/recvcheck v0.2.0/go.mod h1:n04eYkwIR0JbgD73wT8wL4JjPC3wm0nFtzBnWNocnYU= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= -github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryancurrah/gomodguard v1.4.1 h1:eWC8eUMNZ/wM/PWuZBv7JxxqT5fiIKSIyTvjb7Elr+g= -github.com/ryancurrah/gomodguard v1.4.1/go.mod h1:qnMJwV1hX9m+YJseXEBhd2s90+1Xn6x9dLz11ualI1I= -github.com/ryanrolds/sqlclosecheck v0.5.1 h1:dibWW826u0P8jNLsLN+En7+RqWWTYrjCB9fJfSfdyCU= -github.com/ryanrolds/sqlclosecheck v0.5.1/go.mod h1:2g3dUjoS6AL4huFdv6wn55WpLIDjY7ZgUR4J8HOO/XQ= -github.com/sanposhiho/wastedassign/v2 v2.1.0 h1:crurBF7fJKIORrV85u9UUpePDYGWnwvv3+A96WvwXT0= -github.com/sanposhiho/wastedassign/v2 v2.1.0/go.mod h1:+oSmSC+9bQ+VUAxA66nBb0Z7N8CK7mscKTDYC6aIek4= -github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 h1:KRzFb2m7YtdldCEkzs6KqmJw4nqEVZGK7IN2kJkjTuQ= -github.com/santhosh-tekuri/jsonschema/v6 v6.0.2/go.mod h1:JXeL+ps8p7/KNMjDQk3TCwPpBy0wYklyWTfbkIzdIFU= -github.com/sashamelentyev/interfacebloat v1.1.0 h1:xdRdJp0irL086OyW1H/RTZTr1h/tMEOsumirXcOJqAw= -github.com/sashamelentyev/interfacebloat v1.1.0/go.mod h1:+Y9yU5YdTkrNvoX0xHc84dxiN1iBi9+G8zZIhPVoNjQ= -github.com/sashamelentyev/usestdlibvars v1.29.0 h1:8J0MoRrw4/NAXtjQqTHrbW9NN+3iMf7Knkq057v4XOQ= -github.com/sashamelentyev/usestdlibvars v1.29.0/go.mod h1:8PpnjHMk5VdeWlVb4wCdrB8PNbLqZ3wBZTZWkrpZZL8= -github.com/securego/gosec/v2 v2.22.10 h1:ntbBqdWXnu46DUOXn+R2SvPo3PiJCDugTCgTW2g4tQg= -github.com/securego/gosec/v2 v2.22.10/go.mod h1:9UNjK3tLpv/w2b0+7r82byV43wCJDNtEDQMeS+H/g2w= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/shurcooL/githubv4 v0.0.0-20221126192849-0b5c4c7994eb h1:foJysa74+t41fG7adnt+TkfcNxQUWid8R/HlXe+Mmbw= github.com/shurcooL/githubv4 v0.0.0-20221126192849-0b5c4c7994eb/go.mod h1:hAF0iLZy4td2EX+/8Tw+4nodhlMrwN3HupfaXj3zkGo= -github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= -github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= github.com/shurcooL/graphql v0.0.0-20220606043923-3cf50f8a0a29 h1:B1PEwpArrNp4dkQrfxh/abbBAOZBVp0ds+fBEOUOqOc= github.com/shurcooL/graphql v0.0.0-20220606043923-3cf50f8a0a29/go.mod h1:AuYgA5Kyo4c7HfUmvRGs/6rGlMMV/6B1bVnB9JxJEEg= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/sivchari/containedctx v1.0.3 h1:x+etemjbsh2fB5ewm5FeLNi5bUjK0V8n0RB+Wwfd0XE= -github.com/sivchari/containedctx v1.0.3/go.mod h1:c1RDvCbnJLtH4lLcYD/GqwiBSSf4F5Qk0xld2rBqzJ4= github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8= github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY= -github.com/sonatard/noctx v0.4.0 h1:7MC/5Gg4SQ4lhLYR6mvOP6mQVSxCrdyiExo7atBs27o= -github.com/sonatard/noctx v0.4.0/go.mod h1:64XdbzFb18XL4LporKXp8poqZtPKbCrqQ402CV+kJas= -github.com/sourcegraph/go-diff v0.7.0 h1:9uLlrd5T46OXs5qpp8L/MTltk0zikUGi0sNNyCpA8G0= -github.com/sourcegraph/go-diff v0.7.0/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= -github.com/spf13/afero v1.14.0 h1:9tH6MapGnn/j0eb0yIXiLjERO8RB6xIVZRDCX7PtqWA= -github.com/spf13/afero v1.14.0/go.mod h1:acJQ8t0ohCGuMN3O+Pv0V0hgMxNYDlvdk+VTfyZmbYo= -github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= -github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= -github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= -github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= -github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= -github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= -github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ= -github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= -github.com/ssgreg/nlreturn/v2 v2.2.1 h1:X4XDI7jstt3ySqGU86YGAURbxw3oTDPK9sPEi6YEwQ0= -github.com/ssgreg/nlreturn/v2 v2.2.1/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I= -github.com/stbenjam/no-sprintf-host-port v0.2.0 h1:i8pxvGrt1+4G0czLr/WnmyH7zbZ8Bg8etvARQ1rpyl4= -github.com/stbenjam/no-sprintf-host-port v0.2.0/go.mod h1:eL0bQ9PasS0hsyTyfTjjG+E80QIyPnBVQbYZyv20Jfk= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs= -github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= -github.com/tenntenn/modver v1.0.1 h1:2klLppGhDgzJrScMpkj9Ujy3rXPUspSjAcev9tSEBgA= -github.com/tenntenn/modver v1.0.1/go.mod h1:bePIyQPb7UeioSRkw3Q0XeMhYZSMx9B8ePqg6SAMGH0= -github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3 h1:f+jULpRQGxTSkNYKJ51yaw6ChIqO+Je8UqsTKN/cDag= -github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY= -github.com/tetafro/godot v1.5.4 h1:u1ww+gqpRLiIA16yF2PV1CV1n/X3zhyezbNXC3E14Sg= -github.com/tetafro/godot v1.5.4/go.mod h1:eOkMrVQurDui411nBY2FA05EYH01r14LuWY/NrVDVcU= -github.com/timakin/bodyclose v0.0.0-20241222091800-1db5c5ca4d67 h1:9LPGD+jzxMlnk5r6+hJnar67cgpDIz/iyD+rfl5r2Vk= -github.com/timakin/bodyclose v0.0.0-20241222091800-1db5c5ca4d67/go.mod h1:mkjARE7Yr8qU23YcGMSALbIxTQ9r9QBVahQOBRfU460= -github.com/timonwong/loggercheck v0.11.0 h1:jdaMpYBl+Uq9mWPXv1r8jc5fC3gyXx4/WGwTnnNKn4M= -github.com/timonwong/loggercheck v0.11.0/go.mod h1:HEAWU8djynujaAVX7QI65Myb8qgfcZ1uKbdpg3ZzKl8= -github.com/tomarrell/wrapcheck/v2 v2.11.0 h1:BJSt36snX9+4WTIXeJ7nvHBQBcm1h2SjQMSlmQ6aFSU= -github.com/tomarrell/wrapcheck/v2 v2.11.0/go.mod h1:wFL9pDWDAbXhhPZZt+nG8Fu+h29TtnZ2MW6Lx4BRXIU= -github.com/tommy-muehle/go-mnd/v2 v2.5.1 h1:NowYhSdyE/1zwK9QCLeRb6USWdoif80Ie+v+yU8u1Zw= -github.com/tommy-muehle/go-mnd/v2 v2.5.1/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw= -github.com/ultraware/funlen v0.2.0 h1:gCHmCn+d2/1SemTdYMiKLAHFYxTYz7z9VIDRaTGyLkI= -github.com/ultraware/funlen v0.2.0/go.mod h1:ZE0q4TsJ8T1SQcjmkhN/w+MceuatI6pBFSxxyteHIJA= -github.com/ultraware/whitespace v0.2.0 h1:TYowo2m9Nfj1baEQBjuHzvMRbp19i+RCcRYrSWoFa+g= -github.com/ultraware/whitespace v0.2.0/go.mod h1:XcP1RLD81eV4BW8UhQlpaR+SDc2givTvyI8a586WjW8= -github.com/uudashr/gocognit v1.2.0 h1:3BU9aMr1xbhPlvJLSydKwdLN3tEUUrzPSSM8S4hDYRA= -github.com/uudashr/gocognit v1.2.0/go.mod h1:k/DdKPI6XBZO1q7HgoV2juESI2/Ofj9AcHPZhBBdrTU= -github.com/uudashr/iface v1.4.1 h1:J16Xl1wyNX9ofhpHmQ9h9gk5rnv2A6lX/2+APLTo0zU= -github.com/uudashr/iface v1.4.1/go.mod h1:pbeBPlbuU2qkNDn0mmfrxP2X+wjPMIQAy+r1MBXSXtg= github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= @@ -714,44 +165,11 @@ github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAh github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= -github.com/xen0n/gosmopolitan v1.3.0 h1:zAZI1zefvo7gcpbCOrPSHJZJYA9ZgLfJqtKzZ5pHqQM= -github.com/xen0n/gosmopolitan v1.3.0/go.mod h1:rckfr5T6o4lBtM1ga7mLGKZmLxswUoH1zxHgNXOsEt4= -github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= -github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= -github.com/yagipy/maintidx v1.0.0 h1:h5NvIsCz+nRDapQ0exNv4aJ0yXSI0420omVANTv3GJM= -github.com/yagipy/maintidx v1.0.0/go.mod h1:0qNf/I/CCZXSMhsRsrEPDZ+DkekpKLXAJfsTACwgXLk= -github.com/yeya24/promlinter v0.3.0 h1:JVDbMp08lVCP7Y6NP3qHroGAO6z2yGKQtS5JsjqtoFs= -github.com/yeya24/promlinter v0.3.0/go.mod h1:cDfJQQYv9uYciW60QT0eeHlFodotkYZlL+YcPQN+mW4= -github.com/ykadowak/zerologlint v0.1.5 h1:Gy/fMz1dFQN9JZTPjv1hxEk+sRWm05row04Yoolgdiw= -github.com/ykadowak/zerologlint v0.1.5/go.mod h1:KaUskqF3e/v59oPmdq1U1DnKcuHokl2/K1U4pmIELKg= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zclconf/go-cty v1.17.0 h1:seZvECve6XX4tmnvRzWtJNHdscMtYEx5R7bnnVyd/d0= github.com/zclconf/go-cty v1.17.0/go.mod h1:wqFzcImaLTI6A5HfsRwB0nj5n0MRZFwmey8YoFPPs3U= github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940 h1:4r45xpDWB6ZMSMNJFMOjqrGHynW3DIBuR2H9j0ug+Mo= github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM= -gitlab.com/bosi/decorder v0.4.2 h1:qbQaV3zgwnBZ4zPMhGLW4KZe7A7NwxEhJx39R3shffo= -gitlab.com/bosi/decorder v0.4.2/go.mod h1:muuhHoaJkA9QLcYHq4Mj8FJUwDZ+EirSHRiaTcTf6T8= -go-simpler.org/assert v0.9.0 h1:PfpmcSvL7yAnWyChSjOz6Sp6m9j5lyK8Ok9pEL31YkQ= -go-simpler.org/assert v0.9.0/go.mod h1:74Eqh5eI6vCK6Y5l3PI8ZYFXG4Sa+tkr70OIPJAUr28= -go-simpler.org/musttag v0.14.0 h1:XGySZATqQYSEV3/YTy+iX+aofbZZllJaqwFWs+RTtSo= -go-simpler.org/musttag v0.14.0/go.mod h1:uP8EymctQjJ4Z1kUnjX0u2l60WfUdQxCwSNKzE1JEOE= -go-simpler.org/sloglint v0.11.1 h1:xRbPepLT/MHPTCA6TS/wNfZrDzkGvCCqUv4Bdwc3H7s= -go-simpler.org/sloglint v0.11.1/go.mod h1:2PowwiCOK8mjiF+0KGifVOT8ZsCNiFzvfyJeJOIt8MQ= -go.augendre.info/arangolint v0.3.1 h1:n2E6p8f+zfXSFLa2e2WqFPp4bfvcuRdd50y6cT65pSo= -go.augendre.info/arangolint v0.3.1/go.mod h1:6ZKzEzIZuBQwoSvlKT+qpUfIbBfFCE5gbAoTg0/117g= -go.augendre.info/fatcontext v0.9.0 h1:Gt5jGD4Zcj8CDMVzjOJITlSb9cEch54hjRRlN3qDojE= -go.augendre.info/fatcontext v0.9.0/go.mod h1:L94brOAT1OOUNue6ph/2HnwxoNlds9aXDF2FcUntbNw= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= @@ -764,193 +182,44 @@ go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFh go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= -go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= -go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8= -go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= -go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= -go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= -go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= -golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= -golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= -golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= -golang.org/x/exp/typeparams v0.0.0-20251023183803-a4bb9ffd2546 h1:HDjDiATsGqvuqvkDvgJjD1IgPrVekcSXVVE21JwvzGE= -golang.org/x/exp/typeparams v0.0.0-20251023183803-a4bb9ffd2546/go.mod h1:4Mzdyp/6jzw9auFDJ3OMF5qksa7UvPnzKqTVGcb04ms= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA= golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= -golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= -golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211105183446-c75c47738b0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= @@ -958,207 +227,45 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200329025819-fd4102a86c65/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.1.1-0.20210205202024-ef80cdb6ec6d/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU= -golang.org/x/tools v0.1.1-0.20210302220138-2ac05c832e1a/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= -golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ= golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs= -golang.org/x/tools/go/expect v0.1.1-deprecated h1:jpBZDwmgPhXsKZC6WhL20P4b/wmnpsEAGHaNy0n/rJM= -golang.org/x/tools/go/expect v0.1.1-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY= -golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated h1:1h2MnaIAIXISqTFKdENegdpAgUXz6NrPEsbIeWaBRvM= -golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated/go.mod h1:RVAQXBGNv1ib0J382/DPCRS/BPnsGebyM1Gj5VSDpG8= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c h1:qXWI/sQtv5UKboZ/zUk7h+mrf/lXORyI+n9DKDAusdg= google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c/go.mod h1:gw1tLEfykwDz2ET4a12jcXt4couGAm7IwsVaTy0Sflo= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI= google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw= google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= -gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.6.1 h1:R094WgE8K4JirYjBaOpz/AvTyUu/3wbmAoskKN/pxTI= -honnef.co/go/tools v0.6.1/go.mod h1:3puzxxljPCe8RGJX7BIy1plGbxEOZni5mR2aXe3/uk4= -mvdan.cc/gofumpt v0.9.2 h1:zsEMWL8SVKGHNztrx6uZrXdp7AX8r421Vvp23sz7ik4= -mvdan.cc/gofumpt v0.9.2/go.mod h1:iB7Hn+ai8lPvofHd9ZFGVg2GOr8sBUw1QUWjNbmIL/s= -mvdan.cc/unparam v0.0.0-20251027182757-5beb8c8f8f15 h1:ssMzja7PDPJV8FStj7hq9IKiuiKhgz9ErWw+m68e7DI= -mvdan.cc/unparam v0.0.0-20251027182757-5beb8c8f8f15/go.mod h1:4M5MMXl2kW6fivUT6yRGpLLPNfuGtU2Z0cPvFquGDYU= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/templates/data-sources/actions_environment_public_key.md.tmpl b/templates/data-sources/actions_environment_public_key.md.tmpl new file mode 100644 index 0000000000..c14c28bbcd --- /dev/null +++ b/templates/data-sources/actions_environment_public_key.md.tmpl @@ -0,0 +1,19 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}}" +description: |- + Get information on a GitHub Actions Environment Public Key. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +{{ .Description | trimspace }} + +## Example Usage + +{{tffile "examples/data-sources/actions_environment_public_key/example_1.tf"}} + +{{ .SchemaMarkdown | trimspace }} diff --git a/templates/data-sources/actions_environment_secrets.md.tmpl b/templates/data-sources/actions_environment_secrets.md.tmpl new file mode 100644 index 0000000000..0e88cc751e --- /dev/null +++ b/templates/data-sources/actions_environment_secrets.md.tmpl @@ -0,0 +1,26 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get Actions secrets of the repository environment +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve the list of secrets of the repository environment. + +## Example Usage + +{{tffile "examples/data-sources/actions_environment_secrets/example_1.tf"}} + +## Argument Reference + +## Attributes Reference + +- `secrets` - list of secrets for the environment + - `name` - Name of the secret + - `created_at` - Timestamp of the secret creation + - `updated_at` - Timestamp of the secret last update diff --git a/templates/data-sources/actions_environment_variables.md.tmpl b/templates/data-sources/actions_environment_variables.md.tmpl new file mode 100644 index 0000000000..8a10787613 --- /dev/null +++ b/templates/data-sources/actions_environment_variables.md.tmpl @@ -0,0 +1,27 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get Actions variables of the repository environment +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve the list of variables of the repository environment. + +## Example Usage + +{{tffile "examples/data-sources/actions_environment_variables/example_1.tf"}} + +## Argument Reference + +## Attributes Reference + +- `variables` - list of variables for the environment + - `name` - Name of the variable + - `value` - Value of the variable + - `created_at` - Timestamp of the variable creation + - `updated_at` - Timestamp of the variable last update diff --git a/templates/data-sources/actions_organization_oidc_subject_claim_customization_template.md.tmpl b/templates/data-sources/actions_organization_oidc_subject_claim_customization_template.md.tmpl new file mode 100644 index 0000000000..346212de7a --- /dev/null +++ b/templates/data-sources/actions_organization_oidc_subject_claim_customization_template.md.tmpl @@ -0,0 +1,15 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get a GitHub Actions organization OpenID Connect customization template +--- + +# {{.Name}} ({{.Type}}) + +{{ .Description | trimspace }} + +## Example Usage + +{{tffile "examples/data-sources/actions_organization_oidc_subject_claim_customization_template/example_1.tf"}} + +{{ .SchemaMarkdown | trimspace }} diff --git a/templates/data-sources/actions_organization_public_key.md.tmpl b/templates/data-sources/actions_organization_public_key.md.tmpl new file mode 100644 index 0000000000..04bc37f588 --- /dev/null +++ b/templates/data-sources/actions_organization_public_key.md.tmpl @@ -0,0 +1,22 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get information on a GitHub Actions Organization Public Key. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve information about a GitHub Actions Organization public key. This data source is required to be used with other GitHub secrets interactions. Note that the provider `token` must have admin rights to an organization to retrieve it's action public key. + +## Example Usage + +{{tffile "examples/data-sources/actions_organization_public_key/example_1.tf"}} + +## Attributes Reference + +- `key_id` - ID of the key that has been retrieved. +- `key` - Actual key retrieved. diff --git a/templates/data-sources/actions_organization_registration_token.md.tmpl b/templates/data-sources/actions_organization_registration_token.md.tmpl new file mode 100644 index 0000000000..7225356e66 --- /dev/null +++ b/templates/data-sources/actions_organization_registration_token.md.tmpl @@ -0,0 +1,24 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get a GitHub Actions organization registration token. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve a GitHub Actions organization registration token. This token can then be used to register a self-hosted runner. + +## Example Usage + +{{tffile "examples/data-sources/actions_organization_registration_token/example_1.tf"}} + +## Argument Reference + +## Attributes Reference + +- `token` - The token that has been retrieved. +- `expires_at` - The token expiration date. diff --git a/templates/data-sources/actions_organization_secrets.md.tmpl b/templates/data-sources/actions_organization_secrets.md.tmpl new file mode 100644 index 0000000000..1ff68c44d4 --- /dev/null +++ b/templates/data-sources/actions_organization_secrets.md.tmpl @@ -0,0 +1,27 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get actions secrets of the organization +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve the list of secrets of the organization. + +## Example Usage + +{{tffile "examples/data-sources/actions_organization_secrets/example_1.tf"}} + +## Argument Reference + +## Attributes Reference + +- `secrets` - list of secrets for the repository + - `name` - Secret name + - `visibility` - Secret visibility + - `created_at` - Timestamp of the secret creation + - `updated_at` - Timestamp of the secret last update diff --git a/templates/data-sources/actions_organization_variables.md.tmpl b/templates/data-sources/actions_organization_variables.md.tmpl new file mode 100644 index 0000000000..3a9c253bd5 --- /dev/null +++ b/templates/data-sources/actions_organization_variables.md.tmpl @@ -0,0 +1,28 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get Actions variables of the organization +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve the list of variables of the organization. + +## Example Usage + +{{tffile "examples/data-sources/actions_organization_variables/example_1.tf"}} + +## Argument Reference + +## Attributes Reference + +- `variables` - list of variables for the repository + - `name` - Name of the variable + - `value` - Value of the variable + - `visibility` - Visibility of the variable + - `created_at` - Timestamp of the variable creation + - `updated_at` - Timestamp of the variable last update diff --git a/templates/data-sources/actions_public_key.md.tmpl b/templates/data-sources/actions_public_key.md.tmpl new file mode 100644 index 0000000000..b4cae61324 --- /dev/null +++ b/templates/data-sources/actions_public_key.md.tmpl @@ -0,0 +1,26 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get information on a GitHub Actions Public Key. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve information about a GitHub Actions public key. This data source is required to be used with other GitHub secrets interactions. Note that the provider `token` must have admin rights to a repository to retrieve it's action public key. + +## Example Usage + +{{tffile "examples/data-sources/actions_public_key/example_1.tf"}} + +## Argument Reference + +- `repository` - (Required) Name of the repository to get public key from. + +## Attributes Reference + +- `key_id` - ID of the key that has been retrieved. +- `key` - Actual key retrieved. diff --git a/templates/data-sources/actions_registration_token.md.tmpl b/templates/data-sources/actions_registration_token.md.tmpl new file mode 100644 index 0000000000..b770b3a5c4 --- /dev/null +++ b/templates/data-sources/actions_registration_token.md.tmpl @@ -0,0 +1,26 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get a GitHub Actions repository registration token. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve a GitHub Actions repository registration token. This token can then be used to register a self-hosted runner. + +## Example Usage + +{{tffile "examples/data-sources/actions_registration_token/example_1.tf"}} + +## Argument Reference + +- `repository` - (Required) Name of the repository to get a GitHub Actions registration token for. + +## Attributes Reference + +- `token` - The token that has been retrieved. +- `expires_at` - The token expiration date. diff --git a/templates/data-sources/actions_repository_oidc_subject_claim_customization_template.md.tmpl b/templates/data-sources/actions_repository_oidc_subject_claim_customization_template.md.tmpl new file mode 100644 index 0000000000..58507de95c --- /dev/null +++ b/templates/data-sources/actions_repository_oidc_subject_claim_customization_template.md.tmpl @@ -0,0 +1,26 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get a GitHub Actions repository's OpenID Connect customization template +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve the OpenID Connect subject claim customization template for a repository + +## Example Usage + +{{tffile "examples/data-sources/actions_repository_oidc_subject_claim_customization_template/example_1.tf"}} + +## Argument Reference + +- `name` - (Required) Name of the repository to get the OpenID Connect subject claim customization template for. + +## Attributes Reference + +- `use_default` - Whether the repository uses the default template. +- `include_claim_keys` - The list of OpenID Connect claim keys. diff --git a/templates/data-sources/actions_secrets.md.tmpl b/templates/data-sources/actions_secrets.md.tmpl new file mode 100644 index 0000000000..c40b7b218c --- /dev/null +++ b/templates/data-sources/actions_secrets.md.tmpl @@ -0,0 +1,29 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get actions secrets for a repository +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve the list of secrets for a GitHub repository. + +## Example Usage + +{{tffile "examples/data-sources/actions_secrets/example_1.tf"}} + +## Argument Reference + +- `name` - (Optional) The name of the repository. +- `full_name` - (Optional) Full name of the repository (in `org/name` format). + +## Attributes Reference + +- `secrets` - list of secrets for the repository + - `name` - Secret name + - `created_at` - Timestamp of the secret creation + - `updated_at` - Timestamp of the secret last update diff --git a/templates/data-sources/actions_variables.md.tmpl b/templates/data-sources/actions_variables.md.tmpl new file mode 100644 index 0000000000..cf0c626bc5 --- /dev/null +++ b/templates/data-sources/actions_variables.md.tmpl @@ -0,0 +1,30 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get Actions variables for a repository +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve the list of variables for a GitHub repository. + +## Example Usage + +{{tffile "examples/data-sources/actions_variables/example_1.tf"}} + +## Argument Reference + +- `name` - (Optional) The name of the repository. +- `full_name` - (Optional) Full name of the repository (in `org/name` format). + +## Attributes Reference + +- `variables` - list of variables for the repository + - `name` - Name of the variable + - `value` - Value of the variable + - `created_at` - Timestamp of the variable creation + - `updated_at` - Timestamp of the variable last update diff --git a/templates/data-sources/app.md.tmpl b/templates/data-sources/app.md.tmpl new file mode 100644 index 0000000000..9ea270918d --- /dev/null +++ b/templates/data-sources/app.md.tmpl @@ -0,0 +1,19 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}}" +description: |- +{{ .Description | plainmarkdown | trimspace | prefixlines " " }} +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +{{ .Description | trimspace }} + +## Example Usage + +{{ tffile (printf "examples/data-sources/%s/example_1.tf" .Name)}} + +{{ .SchemaMarkdown | trimspace }} diff --git a/templates/data-sources/app_token.md.tmpl b/templates/data-sources/app_token.md.tmpl new file mode 100644 index 0000000000..5ee7eb6a7f --- /dev/null +++ b/templates/data-sources/app_token.md.tmpl @@ -0,0 +1,33 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Generate a GitHub APP JWT. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to generate a [GitHub App JWT](https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/generating-a-json-web-token-jwt-for-a-github-app). + +## Example Usage + +{{tffile "examples/data-sources/app_token/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `app_id` - (Required) This is the ID of the GitHub App. + +- `installation_id` - (Required) This is the ID of the GitHub App installation. + +- `pem_file` - (Required) This is the contents of the GitHub App private key PEM file. + +## Attribute Reference + +The following additional attributes are exported: + +- `token` - The generated GitHub APP JWT. diff --git a/templates/data-sources/branch.md.tmpl b/templates/data-sources/branch.md.tmpl new file mode 100644 index 0000000000..9b27792ee2 --- /dev/null +++ b/templates/data-sources/branch.md.tmpl @@ -0,0 +1,35 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get information about a repository branch. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve information about a repository branch. + +## Example Usage + +{{tffile "examples/data-sources/branch/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The GitHub repository name. + +- `branch` - (Required) The repository branch to retrieve. + +## Attribute Reference + +The following additional attributes are exported: + +- `etag` - An etag representing the Branch object. + +- `ref` - A string representing a branch reference, in the form of `refs/heads/`. + +- `sha` - A string storing the reference's `HEAD` commit's SHA1. diff --git a/templates/data-sources/branch_protection_rules.md.tmpl b/templates/data-sources/branch_protection_rules.md.tmpl new file mode 100644 index 0000000000..3ea75fc439 --- /dev/null +++ b/templates/data-sources/branch_protection_rules.md.tmpl @@ -0,0 +1,29 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get information about a repository branch protection rules. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve a list of repository branch protection rules. + +## Example Usage + +{{tffile "examples/data-sources/branch_protection_rules/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The GitHub repository name. + +## Attribute Reference + +- `rules` - Collection of Branch Protection Rules. Each of the results conforms to the following scheme: + + - `pattern` - Identifies the protection rule pattern. diff --git a/templates/data-sources/codespaces_organization_public_key.md.tmpl b/templates/data-sources/codespaces_organization_public_key.md.tmpl new file mode 100644 index 0000000000..e1dea42a59 --- /dev/null +++ b/templates/data-sources/codespaces_organization_public_key.md.tmpl @@ -0,0 +1,22 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get information on a GitHub Codespaces Organization Public Key. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve information about a GitHub Codespaces Organization public key. This data source is required to be used with other GitHub secrets interactions. Note that the provider `token` must have admin rights to an organization to retrieve it's Codespaces public key. + +## Example Usage + +{{tffile "examples/data-sources/codespaces_organization_public_key/example_1.tf"}} + +## Attributes Reference + +- `key_id` - ID of the key that has been retrieved. +- `key` - Actual key retrieved. diff --git a/templates/data-sources/codespaces_organization_secrets.md.tmpl b/templates/data-sources/codespaces_organization_secrets.md.tmpl new file mode 100644 index 0000000000..343c547a5b --- /dev/null +++ b/templates/data-sources/codespaces_organization_secrets.md.tmpl @@ -0,0 +1,27 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get codespaces secrets of the organization +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve the list of codespaces secrets of the organization. + +## Example Usage + +{{tffile "examples/data-sources/codespaces_organization_secrets/example_1.tf"}} + +## Argument Reference + +## Attributes Reference + +- `secrets` - list of secrets for the repository + - `name` - Secret name + - `visibility` - Secret visibility + - `created_at` - Timestamp of the secret creation + - `updated_at` - Timestamp of the secret last update diff --git a/templates/data-sources/codespaces_public_key.md.tmpl b/templates/data-sources/codespaces_public_key.md.tmpl new file mode 100644 index 0000000000..e0a8c2c019 --- /dev/null +++ b/templates/data-sources/codespaces_public_key.md.tmpl @@ -0,0 +1,26 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get information on a GitHub Codespaces Public Key. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve information about a GitHub Codespaces public key. This data source is required to be used with other GitHub secrets interactions. Note that the provider `token` must have admin rights to a repository to retrieve it's Codespaces public key. + +## Example Usage + +{{tffile "examples/data-sources/codespaces_public_key/example_1.tf"}} + +## Argument Reference + +- `repository` - (Required) Name of the repository to get public key from. + +## Attributes Reference + +- `key_id` - ID of the key that has been retrieved. +- `key` - Actual key retrieved. diff --git a/templates/data-sources/codespaces_secrets.md.tmpl b/templates/data-sources/codespaces_secrets.md.tmpl new file mode 100644 index 0000000000..88ba8e90e6 --- /dev/null +++ b/templates/data-sources/codespaces_secrets.md.tmpl @@ -0,0 +1,29 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get codespaces secrets for a repository +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve the list of codespaces secrets for a GitHub repository. + +## Example Usage + +{{tffile "examples/data-sources/codespaces_secrets/example_1.tf"}} + +## Argument Reference + +- `name` - (Optional) The name of the repository. +- `full_name` - (Optional) Full name of the repository (in `org/name` format). + +## Attributes Reference + +- `secrets` - list of codespaces secrets for the repository + - `name` - Secret name + - `created_at` - Timestamp of the secret creation + - `updated_at` - Timestamp of the secret last update diff --git a/templates/data-sources/codespaces_user_public_key.md.tmpl b/templates/data-sources/codespaces_user_public_key.md.tmpl new file mode 100644 index 0000000000..8e8b2cd0ce --- /dev/null +++ b/templates/data-sources/codespaces_user_public_key.md.tmpl @@ -0,0 +1,22 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get information on a GitHub Codespaces User Public Key. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve information about a GitHub Codespaces User public key. This data source is required to be used with other GitHub secrets interactions. Note that the provider `token` must have admin rights to an user to retrieve it's Codespaces public key. + +## Example Usage + +{{tffile "examples/data-sources/codespaces_user_public_key/example_1.tf"}} + +## Attributes Reference + +- `key_id` - ID of the key that has been retrieved. +- `key` - Actual key retrieved. diff --git a/templates/data-sources/codespaces_user_secrets.md.tmpl b/templates/data-sources/codespaces_user_secrets.md.tmpl new file mode 100644 index 0000000000..5455135bcd --- /dev/null +++ b/templates/data-sources/codespaces_user_secrets.md.tmpl @@ -0,0 +1,27 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get codespaces secrets of the user +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve the list of codespaces secrets of the user. + +## Example Usage + +{{tffile "examples/data-sources/codespaces_user_secrets/example_1.tf"}} + +## Argument Reference + +## Attributes Reference + +- `secrets` - list of secrets for the repository + - `name` - Secret name + - `visibility` - Secret visibility + - `created_at` - Timestamp of the secret creation + - `updated_at` - Timestamp of the secret last update diff --git a/templates/data-sources/collaborators.md.tmpl b/templates/data-sources/collaborators.md.tmpl new file mode 100644 index 0000000000..6c04e641e1 --- /dev/null +++ b/templates/data-sources/collaborators.md.tmpl @@ -0,0 +1,67 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get the collaborators for a given repository. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve the collaborators for a given repository. + +## Example Usage + +{{tffile "examples/data-sources/collaborators/example_1.tf"}} + +## Arguments Reference + +- `owner` - (Required) The organization that owns the repository. + +- `repository` - (Required) The name of the repository. + +- `affiliation` - (Optional) Filter collaborators returned by their affiliation. Can be one of: `outside`, `direct`, `all`. Defaults to `all`. + +- `permission` - (Optional) Filter collaborators returned by their permission. Can be one of: `pull`, `triage`, `push`, `maintain`, `admin`. Defaults to not doing any filtering on permission. + +## Attributes Reference + +- `collaborator` - An Array of GitHub collaborators. Each `collaborator` block consists of the fields documented below. + +--- + +The `collaborator` block consists of: + +- `login` - The collaborator's login. + +- `id` - The ID of the collaborator. + +- `url` - The GitHub API URL for the collaborator. + +- `html_url` - The GitHub HTML URL for the collaborator. + +- `followers_url` - The GitHub API URL for the collaborator's followers. + +- `following_url` - The GitHub API URL for those following the collaborator. + +- `gists_url` - The GitHub API URL for the collaborator's gists. + +- `starred_url` - The GitHub API URL for the collaborator's starred repositories. + +- `subscriptions_url` - The GitHub API URL for the collaborator's subscribed repositories. + +- `organizations_url` - The GitHub API URL for the collaborator's organizations. + +- `repos_url` - The GitHub API URL for the collaborator's repositories. + +- `events_url` - The GitHub API URL for the collaborator's events. + +- `received_events_url` - The GitHub API URL for the collaborator's received events. + +- `type` - The type of the collaborator (ex. `user`). + +- `site_admin` - Whether the user is a GitHub admin. + +- `permission` - The permission of the collaborator. diff --git a/templates/data-sources/dependabot_organization_public_key.md.tmpl b/templates/data-sources/dependabot_organization_public_key.md.tmpl new file mode 100644 index 0000000000..44257d667b --- /dev/null +++ b/templates/data-sources/dependabot_organization_public_key.md.tmpl @@ -0,0 +1,22 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get information on a GitHub Dependabot Organization Public Key. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve information about a GitHub Dependabot Organization public key. This data source is required to be used with other GitHub secrets interactions. Note that the provider `token` must have admin rights to an organization to retrieve it's Dependabot public key. + +## Example Usage + +{{tffile "examples/data-sources/dependabot_organization_public_key/example_1.tf"}} + +## Attributes Reference + +- `key_id` - ID of the key that has been retrieved. +- `key` - Actual key retrieved. diff --git a/templates/data-sources/dependabot_organization_secrets.md.tmpl b/templates/data-sources/dependabot_organization_secrets.md.tmpl new file mode 100644 index 0000000000..f6b86f0f4c --- /dev/null +++ b/templates/data-sources/dependabot_organization_secrets.md.tmpl @@ -0,0 +1,27 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get dependabot secrets of the organization +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve the list of dependabot secrets of the organization. + +## Example Usage + +{{tffile "examples/data-sources/dependabot_organization_secrets/example_1.tf"}} + +## Argument Reference + +## Attributes Reference + +- `secrets` - list of secrets for the repository + - `name` - Secret name + - `visibility` - Secret visibility + - `created_at` - Timestamp of the secret creation + - `updated_at` - Timestamp of the secret last update diff --git a/templates/data-sources/dependabot_public_key.md.tmpl b/templates/data-sources/dependabot_public_key.md.tmpl new file mode 100644 index 0000000000..64d258a3a0 --- /dev/null +++ b/templates/data-sources/dependabot_public_key.md.tmpl @@ -0,0 +1,26 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get information on a GitHub Dependabot Public Key. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve information about a GitHub Dependabot public key. This data source is required to be used with other GitHub secrets interactions. Note that the provider `token` must have admin rights to a repository to retrieve it's Dependabot public key. + +## Example Usage + +{{tffile "examples/data-sources/dependabot_public_key/example_1.tf"}} + +## Argument Reference + +- `repository` - (Required) Name of the repository to get public key from. + +## Attributes Reference + +- `key_id` - ID of the key that has been retrieved. +- `key` - Actual key retrieved. diff --git a/templates/data-sources/dependabot_secrets.md.tmpl b/templates/data-sources/dependabot_secrets.md.tmpl new file mode 100644 index 0000000000..54eb15230f --- /dev/null +++ b/templates/data-sources/dependabot_secrets.md.tmpl @@ -0,0 +1,29 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get dependabot secrets for a repository +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve the list of dependabot secrets for a GitHub repository. + +## Example Usage + +{{tffile "examples/data-sources/dependabot_secrets/example_1.tf"}} + +## Argument Reference + +- `name` - (Optional) The name of the repository. +- `full_name` - (Optional) Full name of the repository (in `org/name` format). + +## Attributes Reference + +- `secrets` - list of dependabot secrets for the repository + - `name` - Secret name + - `created_at` - Timestamp of the secret creation + - `updated_at` - Timestamp of the secret last update diff --git a/templates/data-sources/enterprise.md.tmpl b/templates/data-sources/enterprise.md.tmpl new file mode 100644 index 0000000000..f72009fca1 --- /dev/null +++ b/templates/data-sources/enterprise.md.tmpl @@ -0,0 +1,31 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get an enterprise. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve basic information about a GitHub enterprise. + +## Example Usage + +``` +data "github_enterprise" "example" { + slug = "example-co" +} +``` + +## Attributes Reference + +- `id` - The ID of the enterprise. +- `database_id` - The database ID of the enterprise. +- `slug` - The URL slug identifying the enterprise. +- `name` - The name of the enterprise. +- `description` - The description of the enterprise. +- `created_at` - The time the enterprise was created. +- `url` - The url for the enterprise. diff --git a/templates/data-sources/external_groups.md.tmpl b/templates/data-sources/external_groups.md.tmpl new file mode 100644 index 0000000000..07fe0bb1c8 --- /dev/null +++ b/templates/data-sources/external_groups.md.tmpl @@ -0,0 +1,31 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Retrieve external groups belonging to an organization. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve external groups belonging to an organization. + +## Example Usage + +{{tffile "examples/data-sources/external_groups/example_1.tf"}} + +## Argument Reference + +N/A. This resource will retrieve all the external groups belonging to an organization. + +## Attributes Reference + +- `external_groups` - an array of external groups belonging to the organization. Each group consists of the fields documented below. + +--- + +- `group_id` - the ID of the group. +- `group_name` - the name of the group. +- `updated_at` - the date the group was last updated. diff --git a/templates/data-sources/ip_ranges.md.tmpl b/templates/data-sources/ip_ranges.md.tmpl new file mode 100644 index 0000000000..bf464d9918 --- /dev/null +++ b/templates/data-sources/ip_ranges.md.tmpl @@ -0,0 +1,47 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get information on GitHub's IP addresses. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve information about GitHub's IP addresses. + +## Example Usage + +{{tffile "examples/data-sources/ip_ranges/example_1.tf"}} + +## Attributes Reference + +- `actions` - An array of IP addresses in CIDR format specifying the addresses that incoming requests from GitHub actions will originate from. +- `actions_ipv4` - A subset of the `actions` array that contains IP addresses in IPv4 CIDR format. +- `actions_ipv6` - A subset of the `actions` array that contains IP addresses in IPv6 CIDR format. +- `dependabot` - An array of IP addresses in CIDR format specifying the A records for dependabot. +- `dependabot_ipv4` - A subset of the `dependabot` array that contains IP addresses in IPv4 CIDR format. +- `dependabot_ipv6` - A subset of the `dependabot` array that contains IP addresses in IPv6 CIDR format. +- `hooks` - An Array of IP addresses in CIDR format specifying the addresses that incoming service hooks will originate from. +- `hooks_ipv4` - A subset of the `hooks` array that contains IP addresses in IPv4 CIDR format. +- `hooks_ipv6` - A subset of the `hooks` array that contains IP addresses in IPv6 CIDR format. +- `git` - An Array of IP addresses in CIDR format specifying the Git servers. +- `git_ipv4` - A subset of the `git` array that contains IP addresses in IPv4 CIDR format. +- `git_ipv6` - A subset of the `git` array that contains IP addresses in IPv6 CIDR format. +- `web` - An Array of IP addresses in CIDR format for GitHub Web. +- `web_ipv4` - A subset of the `web` array that contains IP addresses in IPv4 CIDR format. +- `web_ipv6` - A subset of the `web` array that contains IP addresses in IPv6 CIDR format. +- `api` - An Array of IP addresses in CIDR format for the GitHub API. +- `api_ipv4` - A subset of the `api` array that contains IP addresses in IPv4 CIDR format. +- `api_ipv6` - A subset of the `api` array that contains IP addresses in IPv6 CIDR format. +- `packages` - An Array of IP addresses in CIDR format specifying the A records for GitHub Packages. +- `packages_ipv4` - A subset of the `packages` array that contains IP addresses in IPv4 CIDR format. +- `packages_ipv6` - A subset of the `packages` array that contains IP addresses in IPv6 CIDR format. +- `pages` - An Array of IP addresses in CIDR format specifying the A records for GitHub Pages. +- `pages_ipv4` - A subset of the `pages` array that contains IP addresses in IPv4 CIDR format. +- `pages_ipv6` - A subset of the `pages` array that contains IP addresses in IPv6 CIDR format. +- `importer` - An Array of IP addresses in CIDR format specifying the A records for GitHub Importer. +- `importer_ipv4` - A subset of the `importer` array that contains IP addresses in IPv4 CIDR format. +- `importer_ipv6` - A subset of the `importer` array that contains IP addresses in IPv6 CIDR format. diff --git a/templates/data-sources/issue_labels.md.tmpl b/templates/data-sources/issue_labels.md.tmpl new file mode 100644 index 0000000000..af8a9b307f --- /dev/null +++ b/templates/data-sources/issue_labels.md.tmpl @@ -0,0 +1,29 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get the labels for a given repository. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve the labels for a given repository. + +## Example Usage + +{{tffile "examples/data-sources/issue_labels/example_1.tf"}} + +## Arguments Reference + +- `repository` - (Required) The name of the repository. + +## Attributes Reference + +- `labels` - The list of this repository's labels. Each element of `labels` has the following attributes: + - `name` - The name of the label. + - `color` - The hexadecimal color code for the label, without the leading #. + - `description` - A short description of the label. + - `url` - The URL of the label. diff --git a/templates/data-sources/membership.md.tmpl b/templates/data-sources/membership.md.tmpl new file mode 100644 index 0000000000..e053e481c0 --- /dev/null +++ b/templates/data-sources/membership.md.tmpl @@ -0,0 +1,30 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get information on user membership in an organization. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to find out if a user is a member of your organization, as well as what role they have within it. If the user's membership in the organization is pending their acceptance of an invite, the role they would have once they accept will be returned. + +## Example Usage + +{{tffile "examples/data-sources/membership/example_1.tf"}} + +## Argument Reference + +- `username` - (Required) The username to lookup in the organization. + +- `organization` - (Optional) The organization to check for the above username. + +## Attributes Reference + +- `username` - The username. +- `role` - `admin` or `member` -- the role the user has within the organization. +- `etag` - An etag representing the membership object. +- `state` - `active` or `pending` -- the state of membership within the organization. `active` if the member has accepted the invite, or `pending` if the invite is still pending. diff --git a/templates/data-sources/organization.md.tmpl b/templates/data-sources/organization.md.tmpl new file mode 100644 index 0000000000..cf93de9a14 --- /dev/null +++ b/templates/data-sources/organization.md.tmpl @@ -0,0 +1,58 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get an organization. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve basic information about a GitHub Organization. + +## Example Usage + +{{tffile "examples/data-sources/organization/example_1.tf"}} + +## Argument Reference + +- `name` - (Required) The name of the organization. +- `ignore_archived_repos` - (Optional) Whether or not to include archived repos in the `repositories` list. Defaults to `false`. +- `summary_only` - (Optional) Exclude the repos, members and other attributes from the returned result. Defaults to `false`. + +## Attributes Reference + +- `id` - The ID of the organization +- `node_id` - GraphQL global node ID for use with the v4 API +- `name` - The organization's public profile name +- `orgname` - The organization's name as used in URLs and the API +- `login` - The organization account login +- `description` - The organization account description +- `plan` - The organization account plan name +- `repositories` - (`list`) A list of the full names of the repositories in the organization formatted as `owner/name` strings +- `members` - **Deprecated**: use `users` instead by replacing `github_organization.example.members` to `github_organization.example.users[*].login` which will give you the same value, expect this field to be removed in next major version +- `users` - (`list`) A list with the members of the organization with following fields: + - `id` - The ID of the member + - `login` - The members login + - `email` - Publicly available email + - `role` - Member role `ADMIN`, `MEMBER` +- `two_factor_requirement_enabled` - Whether two-factor authentication is required for all members of the organization. +- `default_repository_permission` - Default permission level members have for organization repositories. +- `members_allowed_repository_creation_type` - The type of repository allowed to be created by members of the organization. Can be one of `ALL`, `PUBLIC`, `PRIVATE`, `NONE`. +- `members_can_create_repositories` - Whether non-admin organization members can create repositories. +- `members_can_create_internal_repositories` - Whether organization members can create internal repositories. +- `members_can_create_private_repositories` - Whether organization members can create private repositories. +- `members_can_create_public_repositories` - Whether organization members can create public repositories. +- `members_can_create_pages` - Whether organization members can create pages sites. +- `members_can_create_public_pages` - Whether organization members can create public pages sites. +- `members_can_create_private_pages` - Whether organization members can create private pages sites. +- `members_can_fork_private_repositories` - Whether organization members can create private repository forks. +- `web_commit_signoff_required` - Whether organization members must sign all commits. +- `advanced_security_enabled_for_new_repositories` - Whether advanced security is enabled for new repositories. +- `dependabot_alerts_enabled_for_new_repositories` - Whether Dependabot alerts is automatically enabled for new repositories. +- `dependabot_security_updates_enabled_for_new_repositories` - Whether Dependabot security updates is automatically enabled for new repositories. +- `dependency_graph_enabled_for_new_repositories` - Whether dependency graph is automatically enabled for new repositories. +- `secret_scanning_enabled_for_new_repositories` - Whether secret scanning is automatically enabled for new repositories. +- `secret_scanning_push_protection_enabled_for_new_repositories` - Whether secret scanning push protection is automatically enabled for new repositories. diff --git a/templates/data-sources/organization_custom_properties.md.tmpl b/templates/data-sources/organization_custom_properties.md.tmpl new file mode 100644 index 0000000000..d450f34872 --- /dev/null +++ b/templates/data-sources/organization_custom_properties.md.tmpl @@ -0,0 +1,39 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get information about a GitHub organization custom property +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve information about a GitHub organization custom property. + +## Example Usage + +{{tffile "examples/data-sources/organization_custom_properties/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `property_name` - (Required) The name of the custom property to retrieve. + +## Attributes Reference + +- `property_name` - The name of the custom property. + +- `value_type` - The type of the custom property. Can be one of `string`, `single_select`, `multi_select`, or `true_false`. + +- `required` - Whether the custom property is required. + +- `description` - The description of the custom property. + +- `default_value` - The default value of the custom property. + +- `allowed_values` - List of allowed values for the custom property. Only populated when `value_type` is `single_select` or `multi_select`. + +- `values_editable_by` - Who can edit the values of the custom property. Can be one of `org_actors` or `org_and_repo_actors`. diff --git a/templates/data-sources/organization_custom_role.md.tmpl b/templates/data-sources/organization_custom_role.md.tmpl new file mode 100644 index 0000000000..819009f799 --- /dev/null +++ b/templates/data-sources/organization_custom_role.md.tmpl @@ -0,0 +1,36 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get a custom role from a GitHub Organization for use in repositories. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +~> **Note:** This data source is deprecated, please use the `github_organization_repository_role` data source instead. + +Use this data source to retrieve information about a custom role in a GitHub Organization. + +~> Note: Custom roles are currently only available in GitHub Enterprise Cloud. + +## Example Usage + +{{tffile "examples/data-sources/organization_custom_role/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `name` - (Required) The name of the custom role. + +## Attributes Reference + +The following additional attributes are exported: + +- `id` - The ID of the custom role. +- `description` - The description for the custom role. +- `base_role` - The system role from which the role inherits permissions. +- `permissions` - A list of additional permissions included in this role. diff --git a/templates/data-sources/organization_external_identities.md.tmpl b/templates/data-sources/organization_external_identities.md.tmpl new file mode 100644 index 0000000000..97c44a860d --- /dev/null +++ b/templates/data-sources/organization_external_identities.md.tmpl @@ -0,0 +1,47 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get a list of organization members and their SAML linked external identity NameID +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve each organization member's SAML or SCIM user attributes. + +## Example Usage + +{{tffile "examples/data-sources/organization_external_identities/example_1.tf"}} + +## Attributes Reference + +- `identities` - An Array of identities returned from GitHub + +--- + +Each element in the `identities` block consists of: + +- `login` - The username of the GitHub user +- `saml_identity` - An Object containing the user's SAML data. This object will be empty if the user is not managed by SAML. +- `scim_identity` - An Object contining the user's SCIM data. This object will be empty if the user is not managed by SCIM. + +--- + +If a user is managed by SAML, the `saml_identity` object will contain: + +- `name_id` - The member's SAML NameID +- `username` - The member's SAML Username +- `family_name` - The member's SAML Family Name +- `given_name` - The member's SAML Given Name + +--- + +If a user is managed by SCIM, the `scim_identity` object will contain: + +- `username` - The member's SCIM Username. (will be empty string if user is not managed by SCIM) +- `groups` - The member's SCIM Groups +- `family_name` - The member's SCIM Family Name +- `given_name` - The member's SCIM Given Name diff --git a/templates/data-sources/organization_ip_allow_list.md.tmpl b/templates/data-sources/organization_ip_allow_list.md.tmpl new file mode 100644 index 0000000000..6740b8e47a --- /dev/null +++ b/templates/data-sources/organization_ip_allow_list.md.tmpl @@ -0,0 +1,32 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get the IP allow list of an organization. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve information about the IP allow list of an organization. The allow list for IP addresses will block access to private resources via the web, API, and Git from any IP addresses that are not on the allow list. + +## Example Usage + +{{tffile "examples/data-sources/organization_ip_allow_list/example_1.tf"}} + +## Attributes Reference + +- `ip_allow_list` - An Array of allowed IP addresses. + +--- + +Each element in the `ip_allow_list` block consists of: + +- `id` - The ID of the IP allow list entry. +- `name` - The name of the IP allow list entry. +- `allow_list_value` - A single IP address or range of IP addresses in CIDR notation. +- `is_active` - Whether the entry is currently active. +- `created_at` - Identifies the date and time when the object was created. +- `updated_at` - Identifies the date and time when the object was last updated. diff --git a/templates/data-sources/organization_repository_role.md.tmpl b/templates/data-sources/organization_repository_role.md.tmpl new file mode 100644 index 0000000000..d9712b429d --- /dev/null +++ b/templates/data-sources/organization_repository_role.md.tmpl @@ -0,0 +1,32 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Lookup a custom organization repository role. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Lookup a custom organization repository role. + +~> **Note**: Custom organization repository roles are currently only available in GitHub Enterprise Cloud. + +## Example Usage + +{{tffile "examples/data-sources/organization_repository_role/example_1.tf"}} + +## Schema + +### Required + +- `role_id` (Number) The ID of the organization repository role. + +### Read-Only + +- `name` (String) The name of the organization repository role. +- `description` (String) The description of the organization repository role. +- `base_role` (String) The system role from which this role inherits permissions. +- `permissions` (Set of String) The permissions included in this role. diff --git a/templates/data-sources/organization_repository_roles.md.tmpl b/templates/data-sources/organization_repository_roles.md.tmpl new file mode 100644 index 0000000000..580c011afd --- /dev/null +++ b/templates/data-sources/organization_repository_roles.md.tmpl @@ -0,0 +1,35 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Lookup all custom repository roles in an organization. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Lookup all custom repository roles in an organization. + +~> **Note**: Custom organization repository roles are currently only available in GitHub Enterprise Cloud. + +## Example Usage + +{{tffile "examples/data-sources/organization_repository_roles/example_1.tf"}} + +## Schema + +### Read-Only + +- `roles` (Set of Object, see [schema](#nested-schema-for-roles)) Available organization repository roles. + +## Nested Schema for `roles` + +### Read-Only + +- `role_id` (Number) The ID of the organization repository role. +- `name` (String) The name of the organization repository role. +- `description` (String) The description of the organization repository role. +- `base_role` (String) The system role from which this role inherits permissions. +- `permissions` (Set of String) The permissions included in this role. diff --git a/templates/data-sources/organization_role.md.tmpl b/templates/data-sources/organization_role.md.tmpl new file mode 100644 index 0000000000..58cdb5172c --- /dev/null +++ b/templates/data-sources/organization_role.md.tmpl @@ -0,0 +1,31 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Lookup a custom organization role. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Lookup a custom organization role. + +## Example Usage + +{{tffile "examples/data-sources/organization_role/example_1.tf"}} + +## Schema + +### Required + +- `role_id` (Number) The ID of the organization role. + +### Read-Only + +- `name` (String) The name of the organization role. +- `description` (String) The description of the organization role. +- `source` (String) The source of this role; one of `Predefined`, `Organization`, or `Enterprise`. +- `base_role` (String) The system role from which this role inherits permissions. +- `permissions` (Set of String) The permissions included in this role. diff --git a/templates/data-sources/organization_role_teams.md.tmpl b/templates/data-sources/organization_role_teams.md.tmpl new file mode 100644 index 0000000000..53e34b6d96 --- /dev/null +++ b/templates/data-sources/organization_role_teams.md.tmpl @@ -0,0 +1,36 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Lookup all teams assigned to a custom organization role. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Lookup all teams assigned to a custom organization role. + +## Example Usage + +{{tffile "examples/data-sources/organization_role_teams/example_1.tf"}} + +## Schema + +### Required + +- `role_id` (Number) The ID of the organization role. + +### Read-Only + +- `teams` (Set of Object, see [schema](#nested-schema-for-teams)) Teams assigned to the organization role. + +## Nested Schema for `teams` + +### Read-Only + +- `team_id` (Number) The ID of the team. +- `slug` (String) The Slug of the team name. +- `name` (String) The name of the team. +- `permission` (String) The permission that the team will have for its repositories. diff --git a/templates/data-sources/organization_role_users.md.tmpl b/templates/data-sources/organization_role_users.md.tmpl new file mode 100644 index 0000000000..4ecbc6a402 --- /dev/null +++ b/templates/data-sources/organization_role_users.md.tmpl @@ -0,0 +1,34 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Lookup all users assigned to a custom organization role. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Lookup all users assigned to a custom organization role. + +## Example Usage + +{{tffile "examples/data-sources/organization_role_users/example_1.tf"}} + +## Schema + +### Required + +- `role_id` (Number) The ID of the organization role. + +### Read-Only + +- `users` (Set of Object, see [schema](#nested-schema-for-users)) Users assigned to the organization role. + +## Nested Schema for `users` + +### Read-Only + +- `user_id` (Number) The ID of the user. +- `login` (String) The login for the GitHub user account. diff --git a/templates/data-sources/organization_roles.md.tmpl b/templates/data-sources/organization_roles.md.tmpl new file mode 100644 index 0000000000..466771b060 --- /dev/null +++ b/templates/data-sources/organization_roles.md.tmpl @@ -0,0 +1,34 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Lookup all custom roles in an organization. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Lookup all custom roles in an organization. + +## Example Usage + +{{tffile "examples/data-sources/organization_roles/example_1.tf"}} + +## Schema + +### Read-Only + +- `roles` (Set of Object, see [schema](#nested-schema-for-roles)) Available organization roles. + +## Nested Schema for `roles` + +### Read-Only + +- `role_id` (Number) The ID of the organization role. +- `name` (String) The name of the organization role. +- `description` (String) The description of the organization role. +- `source` (String) The source of this role; one of `Predefined`, `Organization`, or `Enterprise`. +- `base_role` (String) The system role from which this role inherits permissions. +- `permissions` (Set of String) The permissions included in this role. diff --git a/templates/data-sources/organization_security_managers.md.tmpl b/templates/data-sources/organization_security_managers.md.tmpl new file mode 100644 index 0000000000..b9fe404908 --- /dev/null +++ b/templates/data-sources/organization_security_managers.md.tmpl @@ -0,0 +1,32 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get the security managers for an organization. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +~> **Note:** This data source is deprecated, please use the `github_organization_role_team` resource instead. + +Use this data source to retrieve the security managers for an organization. + +## Example Usage + +{{tffile "examples/data-sources/organization_security_managers/example_1.tf"}} + +## Attributes Reference + +- `teams` - An list of GitHub teams. Each `team` block consists of the fields documented below. + +---___ + +The `team` block consists of: + +- `id` - Unique identifier of the team. +- `slug` - Name based identifier of the team. +- `name` - Name of the team. +- `permission` - Permission that the team will have for its repositories. diff --git a/templates/data-sources/organization_team_sync_groups.md.tmpl b/templates/data-sources/organization_team_sync_groups.md.tmpl new file mode 100644 index 0000000000..f02fc7920b --- /dev/null +++ b/templates/data-sources/organization_team_sync_groups.md.tmpl @@ -0,0 +1,31 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get the external identity provider (IdP) groups for an organization. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve the identity provider (IdP) groups for an organization. + +## Example Usage + +{{tffile "examples/data-sources/organization_team_sync_groups/example_1.tf"}} + +## Attributes Reference + +- `groups` - An Array of GitHub Identity Provider Groups. Each `group` block consists of the fields documented below. + +--- + +The `group` block consists of: + +- `group_id` - The ID of the IdP group. + +- `group_name` - The name of the IdP group. + +- `group_description` - The description of the IdP group. diff --git a/templates/data-sources/organization_teams.md.tmpl b/templates/data-sources/organization_teams.md.tmpl new file mode 100644 index 0000000000..53011ed41e --- /dev/null +++ b/templates/data-sources/organization_teams.md.tmpl @@ -0,0 +1,46 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get information on all GitHub teams of an organization. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve information about all GitHub teams in an organization. + +## Example Usage + +To retrieve *all* teams of the organization: + +{{tffile "examples/data-sources/organization_teams/example_1.tf"}} + +To retrieve only the team's at the root of the organization: + +{{tffile "examples/data-sources/organization_teams/example_2.tf"}} + +## Attributes Reference + +- `teams` - (Required) An Array of GitHub Teams. Each `team` block consists of the fields documented below. +- `root_teams_only` - (Optional) Only return teams that are at the organization's root, i.e. no nested teams. Defaults to `false`. +- `summary_only` - (Optional) Exclude the members and repositories of the team from the returned result. Defaults to `false`. +- `results_per_page` - (Optional) Set the number of results per graphql query. Reducing this number can alleviate timeout errors. Accepts a value between 0 - 100. Defaults to `100`. + +--- + +The `team` block consists of: + +- `id` - The ID of the team. +- `node_id` - The Node ID of the team. +- `slug` - The slug of the team. +- `name` - The team's full name. +- `description` - The team's description. +- `privacy` - The team's privacy type. +- `members` - List of team members. Not returned if `summary_only = true` +- `repositories` - List of team repositories. Not returned if `summary_only = true` +- `parent_team_id` - The ID of the parent team, if there is one. +- `parent_team_slug` - The slug of the parent team, if there is one. +- `parent` - (**DEPRECATED**) The parent team, use `parent_team_id` or `parent_team_slug` instead. diff --git a/templates/data-sources/organization_webhooks.md.tmpl b/templates/data-sources/organization_webhooks.md.tmpl new file mode 100644 index 0000000000..26b547c4f8 --- /dev/null +++ b/templates/data-sources/organization_webhooks.md.tmpl @@ -0,0 +1,33 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get information on all GitHub webhooks of the organization. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve all webhooks of the organization. + +## Example Usage + +To retrieve *all* webhooks of the organization: + +{{tffile "examples/data-sources/organization_webhooks/example_1.tf"}} + +## Attributes Reference + +- `webhooks` - An Array of GitHub Webhooks. Each `webhook` block consists of the fields documented below. + +--- + +The `webhook` block consists of: + +- `id` - the ID of the webhook. +- `type` - the type of the webhook. +- `name` - the name of the webhook. +- `url` - the url of the webhook. +- `active` - `true` if the webhook is active. diff --git a/templates/data-sources/ref.md.tmpl b/templates/data-sources/ref.md.tmpl new file mode 100644 index 0000000000..4bea7461d6 --- /dev/null +++ b/templates/data-sources/ref.md.tmpl @@ -0,0 +1,37 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get information about a repository ref. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve information about a repository ref. + +## Example Usage + +{{tffile "examples/data-sources/ref/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `owner` - (Required) Owner of the repository. + +- `repository` - (Required) The GitHub repository name. + +- `ref` - (Required) The repository ref to look up. Must be formatted `heads/` for branches, and `tags/` for tags. + +## Attribute Reference + +The following additional attributes are exported: + +- `etag` - An etag representing the ref. + +- `id` - A string storing a reference to the repository name and ref. + +- `sha` - A string storing the reference's `HEAD` commit's SHA1. diff --git a/templates/data-sources/release.md.tmpl b/templates/data-sources/release.md.tmpl new file mode 100644 index 0000000000..5ef43b3fbb --- /dev/null +++ b/templates/data-sources/release.md.tmpl @@ -0,0 +1,69 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get information on a GitHub release. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve information about a GitHub release in a specific repository. + +## Example Usage + +To retrieve the latest release that is present in a repository: + +{{tffile "examples/data-sources/release/example_1.tf"}} + +To retrieve a specific release from a repository based on it's ID: + +{{tffile "examples/data-sources/release/example_2.tf"}} + +Finally, to retrieve a release based on it's tag: + +{{tffile "examples/data-sources/release/example_3.tf"}} + +## Argument Reference + +- `repository` - (Required) Name of the repository to retrieve the release from. + +- `owner` - (Required) Owner of the repository. + +- `retrieve_by` - (Required) Describes how to fetch the release. Valid values are `id`, `tag`, `latest`. + +- `release_id` - (Optional) ID of the release to retrieve. Must be specified when `retrieve_by` = `id`. + +- `release_tag` - (Optional) Tag of the release to retrieve. Must be specified when `retrieve_by` = `tag`. + +## Attributes Reference + +- `release_tag` - Tag of release +- `release_id` - ID of release +- `target_commitish` - Commitish value that determines where the Git release is created from +- `name` - Name of release +- `body` - Contents of the description (body) of a release +- `draft` - (`Boolean`) indicates whether the release is a draft +- `prerelease` - (`Boolean`) indicates whether the release is a prerelease +- `created_at` - Date of release creation +- `published_at` - Date of release publishing +- `url` - Base URL of the release +- `html_url` - URL directing to detailed information on the release +- `assets_url` - URL of any associated assets with the release +- `asserts_url` - **Deprecated**: Use `assets_url` resource instead +- `upload_url` - URL that can be used to upload Assets to the release +- `zipball_url` - Download URL of a specific release in `zip` format +- `tarball_url` - Download URL of a specific release in `tar.gz` format +- `assets` - Collection of assets for the release. Each asset conforms to the following schema: + - `id` - ID of the asset + - `url` - URL of the asset + - `node_id` - Node ID of the asset + - `name` - The file name of the asset + - `label` - Label for the asset + - `content_type` - MIME type of the asset + - `size` - Size in byte + - `created_at` - Date the asset was created + - `updated_at` - Date the asset was last updated + - `browser_download_url` - Browser download URL diff --git a/templates/data-sources/repositories.md.tmpl b/templates/data-sources/repositories.md.tmpl new file mode 100644 index 0000000000..930cbdf10f --- /dev/null +++ b/templates/data-sources/repositories.md.tmpl @@ -0,0 +1,34 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Search for GitHub repositories +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +-> **Note:** The data source will return a maximum of `1000` repositories [as documented in official API docs](https://developer.github.com/v3/search/#about-the-search-api). + +Use this data source to retrieve a list of GitHub repositories using a search query. + +## Example Usage + +{{tffile "examples/data-sources/repositories/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `query` - (Required) Search query. See [documentation for the search syntax](https://help.github.com/articles/understanding-the-search-syntax/). +- `sort` - (Optional) Sorts the repositories returned by the specified attribute. Valid values include `stars`, `fork`, and `updated`. Defaults to `updated`. +- `include_repo_id` - (Optional) Returns a list of found repository IDs +- `results_per_page` - (Optional) Set the number of repositories requested per API call. Can be useful to decrease if requests are timing out or to increase to reduce the number of API calls. Defaults to 100. + +## Attributes Reference + +- `full_names` - A list of full names of found repositories (e.g. `hashicorp/terraform`) +- `names` - A list of found repository names (e.g. `terraform`) +- `repo_ids` - (Optional) A list of found repository IDs (e.g. `449898861`) diff --git a/templates/data-sources/repository.md.tmpl b/templates/data-sources/repository.md.tmpl new file mode 100644 index 0000000000..09df28fe9d --- /dev/null +++ b/templates/data-sources/repository.md.tmpl @@ -0,0 +1,127 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get details about GitHub repository +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve information about a GitHub repository. + +## Example Usage + +{{tffile "examples/data-sources/repository/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `name` - (Optional) The name of the repository. + +- `full_name` - (Optional) Full name of the repository (in `org/name` format). + +## Attributes Reference + +- `node_id` - the Node ID of the repository. + +- `description` - A description of the repository. + +- `homepage_url` - URL of a page describing the project. + +- `private` - Whether the repository is private. + +- `visibility` - Whether the repository is public, private or internal. + +- `has_issues` - Whether the repository has GitHub Issues enabled. + +- `has_discussions` - Whether the repository has GitHub Discussions enabled. + +- `has_projects` - Whether the repository has the GitHub Projects enabled. + +- `has_wiki` - Whether the repository has the GitHub Wiki enabled. + +- `is_template` - Whether the repository is a template repository. + +- `fork` - Whether the repository is a fork. + +- `allow_merge_commit` - Whether the repository allows merge commits. + +- `allow_squash_merge` - Whether the repository allows squash merges. + +- `allow_rebase_merge` - Whether the repository allows rebase merges. + +- `allow_auto_merge` - Whether the repository allows auto-merging pull requests. + +- `squash_merge_commit_title` - The default value for a squash merge commit title. + +- `squash_merge_commit_message` - The default value for a squash merge commit message. + +- `merge_commit_title` - The default value for a merge commit title. + +- `merge_commit_message` - The default value for a merge commit message. + +- `has_downloads` - Whether the repository has Downloads feature enabled. + +- `default_branch` - The name of the default branch of the repository. + +- `primary_language` - The primary language used in the repository. + +- `archived` - Whether the repository is archived. + +- `pages` - The repository's GitHub Pages configuration. + +- `topics` - The list of topics of the repository. + +- `template` - The repository source template configuration. + +- `html_url` - URL to the repository on the web. + +- `ssh_clone_url` - URL that can be provided to `git clone` to clone the repository via SSH. + +- `http_clone_url` - URL that can be provided to `git clone` to clone the repository via HTTPS. + +- `git_clone_url` - URL that can be provided to `git clone` to clone the repository anonymously via the git protocol. + +- `svn_url` - URL that can be provided to `svn checkout` to check out the repository via GitHub's Subversion protocol emulation. + +- `node_id` - GraphQL global node id for use with v4 API + +- `repo_id` - GitHub ID for the repository + +- `repository_license` - An Array of GitHub repository licenses. Each `repository_license` block consists of the fields documented below. + +--- + +The `repository_license` block consists of: + +- `content` - Content of the license file, encoded by encoding scheme mentioned below. +- `download_url` - The URL to download the raw content of the license file. +- `encoding` - The encoding used for the content (e.g., "base64"). +- `git_url` - The URL to access information about the license file as a Git blob. +- `html_url` - The URL to view the license file on GitHub. +- `license` - `license` block consists of the fields documented below. +- `name` - The name of the license file (e.g., "LICENSE"). +- `path` - The path to the license file within the repository. +- `sha` - The SHA hash of the license file. +- `size` - The size of the license file in bytes. +- `type` - The type of the content, (e.g., "file"). +- `url` - The URL to access information about the license file on GitHub. + +The `license` block consists of: + +- `body` - The text of the license. +- `conditions` - Conditions associated with the license. +- `description` - A description of the license. +- `featured` - Indicates if the license is featured. +- `html_url` - The URL to view the license details on GitHub. +- `implementation` - Details about the implementation of the license. +- `key` - A key representing the license type (e.g., "apache-2.0"). +- `limitations` - Limitations associated with the license. +- `name` - The name of the license (e.g., "Apache License 2.0"). +- `permissions` - Permissions associated with the license. +- `spdx_id` - The SPDX identifier for the license (e.g., "Apache-2.0"). +- `url` - The URL to access information about the license on GitHub. diff --git a/templates/data-sources/repository_autolink_references.md.tmpl b/templates/data-sources/repository_autolink_references.md.tmpl new file mode 100644 index 0000000000..cbda477767 --- /dev/null +++ b/templates/data-sources/repository_autolink_references.md.tmpl @@ -0,0 +1,28 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get autolink references for a Github repository. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve autolink references for a repository. + +## Example Usage + +{{tffile "examples/data-sources/repository_autolink_references/example_1.tf"}} + +## Argument Reference + +- `repository` - (Required) Name of the repository to retrieve the autolink references from. + +## Attributes Reference + +- `autolink_references` - The list of this repository's autolink references. Each element of `autolink_references` has the following attributes: + - `key_prefix` - Key prefix. + - `target_url_template` - Target url template. + - `is_alphanumeric` - True if alphanumeric. diff --git a/templates/data-sources/repository_branches.md.tmpl b/templates/data-sources/repository_branches.md.tmpl new file mode 100644 index 0000000000..161d846fa5 --- /dev/null +++ b/templates/data-sources/repository_branches.md.tmpl @@ -0,0 +1,31 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get information on a GitHub repository's branches. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve information about branches in a repository. + +## Example Usage + +{{tffile "examples/data-sources/repository_branches/example_1.tf"}} + +## Argument Reference + +- `repository` - (Required) Name of the repository to retrieve the branches from. + +- `only_protected_branches` - (Optional). If true, the `branches` attributes will be populated only with protected branches. Default: `false`. + +- `only_non_protected_branches` - (Optional). If true, the `branches` attributes will be populated only with non protected branches. Default: `false`. + +## Attributes Reference + +- `branches` - The list of this repository's branches. Each element of `branches` has the following attributes: + - `name` - Name of the branch. + - `protected` - Whether the branch is protected. diff --git a/templates/data-sources/repository_custom_properties.md.tmpl b/templates/data-sources/repository_custom_properties.md.tmpl new file mode 100644 index 0000000000..d1b5254c27 --- /dev/null +++ b/templates/data-sources/repository_custom_properties.md.tmpl @@ -0,0 +1,27 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get all custom properties of a repository +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve all custom properties of a repository. + +## Example Usage + +{{tffile "examples/data-sources/repository_custom_properties/example_1.tf"}} + +## Argument Reference + +- `repository` - (Required) Name of the repository to retrieve the custom properties from. + +## Attributes Reference + +- `property` - The list of this repository's custom properties. Each element of `property` has the following attributes: + - `property_name` - Name of the property + - `property_value` - Value of the property diff --git a/templates/data-sources/repository_deploy_keys.md.tmpl b/templates/data-sources/repository_deploy_keys.md.tmpl new file mode 100644 index 0000000000..d3b69e0fb6 --- /dev/null +++ b/templates/data-sources/repository_deploy_keys.md.tmpl @@ -0,0 +1,29 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get all deploy keys of a repository +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve all deploy keys of a repository. + +## Example Usage + +{{tffile "examples/data-sources/repository_deploy_keys/example_1.tf"}} + +## Argument Reference + +- `repository` - (Required) Name of the repository to retrieve the branches from. + +## Attributes Reference + +- `keys` - The list of this repository's deploy keys. Each element of `keys` has the following attributes: + - `id` - Key id + - `title` - Key title + - `key` - Key itself + - `verified` - `true` if the key was verified. diff --git a/templates/data-sources/repository_deployment_branch_policies.md.tmpl b/templates/data-sources/repository_deployment_branch_policies.md.tmpl new file mode 100644 index 0000000000..4f894704d9 --- /dev/null +++ b/templates/data-sources/repository_deployment_branch_policies.md.tmpl @@ -0,0 +1,31 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get the list of deployment branch policies for a given repo / env. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +~> **Note:** This data source is deprecated, please use the `github_repository_environment_deployment_policies` data source instead. + +Use this data source to retrieve deployment branch policies for a repository / environment. + +## Example Usage + +{{tffile "examples/data-sources/repository_deployment_branch_policies/example_1.tf"}} + +## Argument Reference + +- `repository` - (Required) Name of the repository to retrieve the deployment branch policies from. + +- `environment_name` - (Required) Name of the environment to retrieve the deployment branch policies from. + +## Attributes Reference + +- `deployment_branch_policies` - The list of this repository / environment deployment policies. Each element of `deployment_branch_policies` has the following attributes: + - `id` - Id of the policy. + - `name` - The name pattern that branches must match in order to deploy to the environment. diff --git a/templates/data-sources/repository_environment_deployment_policies.md.tmpl b/templates/data-sources/repository_environment_deployment_policies.md.tmpl new file mode 100644 index 0000000000..2686adfa1b --- /dev/null +++ b/templates/data-sources/repository_environment_deployment_policies.md.tmpl @@ -0,0 +1,29 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get the list of environment deployment policies for a given repository environment. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve deployment branch policies for a repository environment. + +## Example Usage + +{{tffile "examples/data-sources/repository_environment_deployment_policies/example_1.tf"}} + +## Argument Reference + +- `repository` - (Required) Name of the repository to retrieve the deployment branch policies from. + +- `environment` - (Required) Name of the environment to retrieve the deployment branch policies from. + +## Attributes Reference + +- `policies` - The list of deployment policies for the repository environment. Each element of `policies` has the following attributes: + - `type` - Type of the policy; this could be `branch` or `tag`. + - `pattern` - The pattern that branch or tag names must match in order to deploy to the environment. diff --git a/templates/data-sources/repository_environments.md.tmpl b/templates/data-sources/repository_environments.md.tmpl new file mode 100644 index 0000000000..6d79fdfd0c --- /dev/null +++ b/templates/data-sources/repository_environments.md.tmpl @@ -0,0 +1,27 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get information on a GitHub repository's environments. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve information about environments for a repository. + +## Example Usage + +{{tffile "examples/data-sources/repository_environments/example_1.tf"}} + +## Argument Reference + +- `repository` - (Required) Name of the repository to retrieve the environments from. + +## Attributes Reference + +- `environments` - The list of this repository's environments. Each element of `environments` has the following attributes: + - `name` - Environment name. + - `node_id` - Environment node id. diff --git a/templates/data-sources/repository_file.md.tmpl b/templates/data-sources/repository_file.md.tmpl new file mode 100644 index 0000000000..727ce82dec --- /dev/null +++ b/templates/data-sources/repository_file.md.tmpl @@ -0,0 +1,45 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Reads files within a GitHub repository +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This data source allows you to read files within a GitHub repository. + +## Example Usage + +{{tffile "examples/data-sources/repository_file/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The repository to read the file from. If an unqualified repo name (without an owner) is passed, the owner will be inferred from the owner of the token used to execute the plan. If a name of the type "owner/repo" (with a slash in the middle) is passed, the owner will be as specified and not the owner of the token. + +- `file` - (Required) The path of the file to read. + +- `branch` - (Optional) Git branch. Defaults to the repository's default branch. + +## Attributes Reference + +The following additional attributes are exported: + +- `content` - The file content. + +- `commit_sha` - The SHA of the commit that modified the file. + +- `sha` - The SHA blob of the file. + +- `commit_author` - Committer author name. + +- `commit_email` - Committer email address. + +- `commit_message` - Commit message when file was last updated. + +- `ref` - The name of the commit/branch/tag. diff --git a/templates/data-sources/repository_milestone.md.tmpl b/templates/data-sources/repository_milestone.md.tmpl new file mode 100644 index 0000000000..b5939ea787 --- /dev/null +++ b/templates/data-sources/repository_milestone.md.tmpl @@ -0,0 +1,32 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get information on a GitHub Repository Milestone. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve information about a specific GitHub milestone in a repository. + +## Example Usage + +{{tffile "examples/data-sources/repository_milestone/example_1.tf"}} + +## Argument Reference + +- `owner` - (Required) Owner of the repository. + +- `repository` - (Required) Name of the repository to retrieve the milestone from. + +- `number` - (Required) The number of the milestone. + +## Attributes Reference + +- `description` - Description of the milestone. +- `due_date` - The milestone due date (in ISO-8601 `yyyy-mm-dd` format). +- `state` - State of the milestone. +- `title` - Title of the milestone. diff --git a/templates/data-sources/repository_pull_request.md.tmpl b/templates/data-sources/repository_pull_request.md.tmpl new file mode 100644 index 0000000000..7fbda65bb1 --- /dev/null +++ b/templates/data-sources/repository_pull_request.md.tmpl @@ -0,0 +1,55 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get information on a single GitHub Pull Request. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve information about a specific GitHub Pull Request in a repository. + +## Example Usage + +{{tffile "examples/data-sources/repository_pull_request/example_1.tf"}} + +## Argument Reference + +- `base_repository` - (Required) Name of the base repository to retrieve the Pull Request from. + +- `number` - (Required) The number of the Pull Request within the repository. + +- `owner` - (Optional) Owner of the repository. If not provided, the provider's default owner is used. + +## Attributes Reference + +- `base_ref` - Name of the ref (branch) of the Pull Request base. + +- `base_sha` - Head commit SHA of the Pull Request base. + +- `body` - Body of the Pull Request. + +- `draft` - Indicates Whether this Pull Request is a draft. + +- `head_owner` - Owner of the Pull Request head repository. + +- `head_repository` - Name of the Pull Request head repository. + +- `head_sha` - Head commit SHA of the Pull Request head. + +- `labels` - List of label names set on the Pull Request. + +- `maintainer_can_modify` - Indicates whether the base repository maintainers can modify the Pull Request. + +- `opened_at` - Unix timestamp indicating the Pull Request creation time. + +- `opened_by` - GitHub login of the user who opened the Pull Request. + +- `state` - the current Pull Request state - can be "open", "closed" or "merged". + +- `title` - The title of the Pull Request. + +- `updated_at` - The timestamp of the last Pull Request update. diff --git a/templates/data-sources/repository_pull_requests.md.tmpl b/templates/data-sources/repository_pull_requests.md.tmpl new file mode 100644 index 0000000000..1dee2b2885 --- /dev/null +++ b/templates/data-sources/repository_pull_requests.md.tmpl @@ -0,0 +1,69 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get information on multiple GitHub Pull Requests. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve information about multiple GitHub Pull Requests in a repository. + +## Example Usage + +{{tffile "examples/data-sources/repository_pull_requests/example_1.tf"}} + +## Argument Reference + +- `base_repository` - (Required) Name of the base repository to retrieve the Pull Requests from. + +- `owner` - (Optional) Owner of the repository. If not provided, the provider's default owner is used. + +- `base_ref` - (Optional) If set, filters Pull Requests by base branch name. + +- `head_ref` - (Optional) If set, filters Pull Requests by head user or head organization and branch name in the format of "user:ref-name" or "organization:ref-name". For example: "github:new-script-format" or "octocat:test-branch". + +- `sort_by` - (Optional) If set, indicates what to sort results by. Can be either "created", "updated", "popularity" (comment count) or "long-running" (age, filtering by pulls updated in the last month). Default: "created". + +- `sort_direction` - (Optional) If set, controls the direction of the sort. Can be either "asc" or "desc". Default: "asc". + +- `state` - (Optional) If set, filters Pull Requests by state. Can be "open", "closed", or "all". Default: "open". + +## Attributes Reference + +- `results` - Collection of Pull Requests matching the filters. Each of the results conforms to the following scheme: + + - `base_ref` - Name of the ref (branch) of the Pull Request base. + + - `base_sha` - Head commit SHA of the Pull Request base. + + - `body` - Body of the Pull Request. + + - `draft` - Indicates Whether this Pull Request is a draft. + + - `head_owner` - Owner of the Pull Request head repository. + + - `head_ref` - Value of the Pull Request `HEAD` reference. + + - `head_repository` - Name of the Pull Request head repository. + + - `head_sha` - Head commit SHA of the Pull Request head. + + - `labels` - List of label names set on the Pull Request. + + - `maintainer_can_modify` - Indicates whether the base repository maintainers can modify the Pull Request. + + - `number` - The number of the Pull Request within the repository. + + - `opened_at` - Unix timestamp indicating the Pull Request creation time. + + - `opened_by` - GitHub login of the user who opened the Pull Request. + + - `state` - the current Pull Request state - can be "open", "closed" or "merged". + + - `title` - The title of the Pull Request. + + - `updated_at` - The timestamp of the last Pull Request update. diff --git a/templates/data-sources/repository_teams.md.tmpl b/templates/data-sources/repository_teams.md.tmpl new file mode 100644 index 0000000000..c26588fc2b --- /dev/null +++ b/templates/data-sources/repository_teams.md.tmpl @@ -0,0 +1,29 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get teams which have permission on the given repo. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve the list of teams which have access to a GitHub repository. + +## Example Usage + +{{tffile "examples/data-sources/repository_teams/example_1.tf"}} + +## Argument Reference + +- `name` - (Optional) The name of the repository. +- `full_name` - (Optional) Full name of the repository (in `org/name` format). + +## Attributes Reference + +- `teams` - List of teams which have access to the repository + - `name` - Team name + - `slug` - Team slug + - `permission` - Team permission diff --git a/templates/data-sources/repository_webhooks.md.tmpl b/templates/data-sources/repository_webhooks.md.tmpl new file mode 100644 index 0000000000..c5e173f70e --- /dev/null +++ b/templates/data-sources/repository_webhooks.md.tmpl @@ -0,0 +1,33 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get information on all GitHub webhooks of the organization. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve webhooks for a given repository. + +## Example Usage + +To retrieve webhooks of a repository: + +{{tffile "examples/data-sources/repository_webhooks/example_1.tf"}} + +## Attributes Reference + +- `webhooks` - An Array of GitHub Webhooks. Each `webhook` block consists of the fields documented below. + +--- + +The `webhook` block consists of: + +- `id` - the ID of the webhook. +- `type` - the type of the webhook. +- `name` - the name of the webhook. +- `url` - the url of the webhook. +- `active` - `true` if the webhook is active. diff --git a/templates/data-sources/rest_api.md.tmpl b/templates/data-sources/rest_api.md.tmpl new file mode 100644 index 0000000000..ccf24a4eec --- /dev/null +++ b/templates/data-sources/rest_api.md.tmpl @@ -0,0 +1,29 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get information on a GitHub resource with a custom GET request to GitHub REST API. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve information about a GitHub resource through REST API. + +## Example Usage + +{{tffile "examples/data-sources/rest_api/example_1.tf"}} + +## Argument Reference + +- `endpoint` - (Required) REST API endpoint to send the GET request to. + +## Attributes Reference + +- `id` - The GitHub API Request ID +- `code` - A response status code. +- `status` - A response status string. +- `headers` - A JSON string containing response headers. +- `body` - A JSON string containing response body. diff --git a/templates/data-sources/ssh_keys.md.tmpl b/templates/data-sources/ssh_keys.md.tmpl new file mode 100644 index 0000000000..1449e9136d --- /dev/null +++ b/templates/data-sources/ssh_keys.md.tmpl @@ -0,0 +1,21 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get information on GitHub's SSH keys. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve information about GitHub's SSH keys. + +## Example Usage + +{{tffile "examples/data-sources/ssh_keys/example_1.tf"}} + +## Attributes Reference + +- `keys` - An array of GitHub's SSH public keys. diff --git a/templates/data-sources/team.md.tmpl b/templates/data-sources/team.md.tmpl new file mode 100644 index 0000000000..46734073c7 --- /dev/null +++ b/templates/data-sources/team.md.tmpl @@ -0,0 +1,36 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get information on a GitHub team. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve information about a GitHub team. + +## Example Usage + +{{tffile "examples/data-sources/team/example_1.tf"}} + +## Argument Reference + +- `slug` - (Required) The team slug. +- `membership_type` - (Optional) Type of membership to be requested to fill the list of members. Can be either "all" or "immediate". Default: "all" +- `summary_only` - (Optional) Exclude the members and repositories of the team from the returned result. Defaults to `false`. +- `results_per_page` - (Optional) Set the number of results per graphql query. Reducing this number can alleviate timeout errors. Accepts a value between 0 - 100. Defaults to `100`. + +## Attributes Reference + +- `id` - the ID of the team. +- `node_id` - the Node ID of the team. +- `name` - the team's full name. +- `description` - the team's description. +- `privacy` - the team's privacy type. +- `permission` - the team's permission level. +- `members` - List of team members (list of GitHub usernames). Not returned if `summary_only = true` +- `repositories` - (**DEPRECATED**) List of team repositories (list of repo names). Not returned if `summary_only = true` +- `repositories_detailed` - List of team repositories (each item comprises of `repo_id`, `repo_name` & [`role_name`](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/team_repository#permission)). Not returned if `summary_only = true` diff --git a/templates/data-sources/tree.md.tmpl b/templates/data-sources/tree.md.tmpl new file mode 100644 index 0000000000..6c2572732b --- /dev/null +++ b/templates/data-sources/tree.md.tmpl @@ -0,0 +1,27 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Returns a single tree using the SHA1 value for that tree. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve information about a single tree. + +## Example Usage + +{{tffile "examples/data-sources/tree/example_1.tf"}} + +## Argument Reference + +- `recursive` - (Optional) Setting this parameter to `true` returns the objects or subtrees referenced by the tree specified in `tree_sha`. +- `repository` - (Required) The name of the repository. +- `tree_sha` - (Required) The SHA1 value for the tree. + +## Attributes Reference + +- `entries` - Objects (of `path`, `mode`, `type`, `size`, and `sha`) specifying a tree structure. diff --git a/templates/data-sources/user.md.tmpl b/templates/data-sources/user.md.tmpl new file mode 100644 index 0000000000..4d7122c9b9 --- /dev/null +++ b/templates/data-sources/user.md.tmpl @@ -0,0 +1,45 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get information on a GitHub user. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve information about a GitHub user. + +## Example Usage + +{{tffile "examples/data-sources/user/example_1.tf"}} + +## Argument Reference + +- `username` - (Required) The username. Use an empty string `""` to retrieve information about the currently authenticated user. + +## Attributes Reference + +- `id` - the ID of the user. +- `node_id` - the Node ID of the user. +- `login` - the user's login. +- `avatar_url` - the user's avatar URL. +- `gravatar_id` - the user's gravatar ID. +- `site_admin` - whether the user is a GitHub admin. +- `name` - the user's full name. +- `company` - the user's company name. +- `blog` - the user's blog location. +- `location` - the user's location. +- `email` - the user's email. +- `gpg_keys` - list of user's GPG keys. +- `ssh_keys` - list of user's SSH keys. +- `bio` - the user's bio. +- `public_repos` - the number of public repositories. +- `public_gists` - the number of public gists. +- `followers` - the number of followers. +- `following` - the number of following users. +- `created_at` - the creation date. +- `updated_at` - the update date. +- `suspended_at` - the suspended date if the user is suspended. diff --git a/templates/data-sources/user_external_identity.md.tmpl b/templates/data-sources/user_external_identity.md.tmpl new file mode 100644 index 0000000000..46f726f141 --- /dev/null +++ b/templates/data-sources/user_external_identity.md.tmpl @@ -0,0 +1,46 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get a specific organization member's SAML/SCIM linked external identity +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve a specific organization member's SAML or SCIM user attributes. + +## Example Usage + +{{tffile "examples/data-sources/user_external_identity/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `username` - (Required) The username of the member to fetch external identity for. + +## Attributes Reference + +- `login` - The username of the GitHub user +- `saml_identity` - An Object containing the user's SAML data. This object will be empty if the user is not managed by SAML. +- `scim_identity` - An Object contining the user's SCIM data. This object will be empty if the user is not managed by SCIM. + +--- + +If a user is managed by SAML, the `saml_identity` object will contain: + +- `name_id` - The member's SAML NameID +- `username` - The member's SAML Username +- `family_name` - The member's SAML Family Name +- `given_name` - The member's SAML Given Name + +--- + +If a user is managed by SCIM, the `scim_identity` object will contain: + +- `scim_username` - The member's SCIM Username. (will be empty string if user is not managed by SCIM) +- `scim_family_name` - The member's SCIM Family Name +- `scim_given_name` - The member's SCIM Given Name diff --git a/templates/data-sources/users.md.tmpl b/templates/data-sources/users.md.tmpl new file mode 100644 index 0000000000..2ec12385fc --- /dev/null +++ b/templates/data-sources/users.md.tmpl @@ -0,0 +1,28 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get information about multiple GitHub users. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Use this data source to retrieve information about multiple GitHub users at once. + +## Example Usage + +{{tffile "examples/data-sources/users/example_1.tf"}} + +## Argument Reference + +- `usernames` - (Required) List of usernames. + +## Attributes Reference + +- `node_ids` - list of Node IDs of users that could be found. +- `logins` - list of logins of users that could be found. +- `emails` - list of the user's publicly visible profile email (will be empty string in case if user decided not to show it). +- `unknown_logins` - list of logins without matching user. diff --git a/templates/index.md.tmpl b/templates/index.md.tmpl new file mode 100644 index 0000000000..349fc8aa03 --- /dev/null +++ b/templates/index.md.tmpl @@ -0,0 +1,95 @@ +--- +page_title: "Provider: GitHub" +description: |- + The GitHub provider is used to interact with GitHub resources. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# GitHub Provider + +The GitHub provider is used to interact with GitHub resources. + +The provider allows you to manage your GitHub organization's members and teams easily. It needs to be configured with the proper credentials before it can be used. + +Use the navigation to the left to read about the available resources. + +## Example Usage + +Terraform 0.13 and later: + +{{tffile "examples/example_1.tf"}} + +- You **must** add a `required_providers` block to every module that will create resources with this provider. If you do not explicitly require `integrations/github` in a submodule, your terraform run may [break in hard-to-troubleshoot ways](https://github.com/integrations/terraform-provider-github/issues/876#issuecomment-1303790559). + +Terraform 0.12 and earlier: + +{{tffile "examples/example_2.tf"}} + +~> **Note:** When upgrading from `hashicorp/github` to `integrations/github`, use `terraform state replace-provider`. Otherwise, Terraform will still require the old provider to interact with the state file. + +## Authentication + +The GitHub provider offers multiple ways to authenticate with GitHub API. + +### GitHub CLI + +The GitHub provider taps into [GitHub CLI](https://cli.github.com/) authentication, where it picks up the token issued by [`gh auth login`](https://cli.github.com/manual/gh_auth_login) command. It is possible to specify the path to the `gh` executable in the `GH_PATH` environment variable, which is useful for when the GitHub Terraform provider can not properly determine its the path to GitHub CLI such as in the cygwin terminal. + +### OAuth / Personal Access Token + +To authenticate using OAuth tokens, ensure that the `token` argument or the `GITHUB_TOKEN` environment variable is set. + +{{tffile "examples/example_3.tf"}} + +### GitHub App Installation + +To authenticate using a GitHub App installation, ensure that arguments in the `app_auth` block or the `GITHUB_APP_XXX` environment variables are set. The `owner` parameter required in this situation. Leaving out will throw a `403 "Resource not accessible by integration"` error. + +Some API operations may not be available when using a GitHub App installation configuration. For more information, refer to the list of [supported endpoints](https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps). + +{{tffile "examples/example_4.tf"}} + +~> **Note:** When using environment variables, an empty `app_auth` block is required to allow provider configurations from environment variables to be specified. See: [Terraform SDK Issue](https://github.com/hashicorp/terraform-plugin-sdk/issues/142) + +{{tffile "examples/example_5.tf"}} + +## Argument Reference + +The following arguments are supported in the `provider` block: + +- `token` - (Optional) A GitHub OAuth / Personal Access Token. When not provided or made available via the `GITHUB_TOKEN` environment variable, the provider can only access resources available anonymously. + +- `base_url` - (Optional) This is the target GitHub base API endpoint. Providing a value is a requirement when working with GitHub Enterprise. It is optional to provide this value and it can also be sourced from the `GITHUB_BASE_URL` environment variable. The value must end with a slash, for example: `https://terraformtesting-ghe.westus.cloudapp.azure.com/` + +- `owner` - (Optional) This is the target GitHub organization or individual user account to manage. For example, `torvalds` and `github` are valid owners. It is optional to provide this value and it can also be sourced from the `GITHUB_OWNER` environment variable. When not provided and a `token` is available, the individual user account owning the `token` will be used. When not provided and no `token` is available, the provider may not function correctly. It is required in case of GitHub App Installation. + +- `organization` - (Deprecated) This behaves the same as `owner`, which should be used instead. This value can also be sourced from the `GITHUB_ORGANIZATION` environment variable. + +- `app_auth` - (Optional) Configuration block to use GitHub App installation token. When not provided, the provider can only access resources available anonymously. + - `id` - (Required) This is the ID of the GitHub App. It can sourced from the `GITHUB_APP_ID` environment variable. + - `installation_id` - (Required) This is the ID of the GitHub App installation. It can sourced from the `GITHUB_APP_INSTALLATION_ID` environment variable. + - `pem_file` - (Required) This is the contents of the GitHub App private key PEM file. It can also be sourced from the `GITHUB_APP_PEM_FILE` environment variable and may use `\n` instead of actual new lines. + +- `write_delay_ms` - (Optional) The number of milliseconds to sleep in between write operations in order to satisfy the GitHub API rate limits. Note that requests to the GraphQL API are implemented as `POST` requests under the hood, so this setting affects those calls as well. Defaults to 1000ms or 1 second if not provided. + +- `retry_delay_ms` - (Optional) Amount of time in milliseconds to sleep in between requests to GitHub API after an error response. Defaults to 1000ms or 1 second if not provided, the max_retries must be set to greater than zero. + +- `read_delay_ms` - (Optional) The number of milliseconds to sleep in between non-write operations in order to satisfy the GitHub API rate limits. Defaults to 0ms. + +- `retryable_errors` - (Optional) "Allow the provider to retry after receiving an error status code, the max_retries should be set for this to work. Defaults to [500, 502, 503, 504] + +- `max_retries` - (Optional) Number of times to retry a request after receiving an error status code. Defaults to 3 + +Note: If you have a PEM file on disk, you can pass it in via `pem_file = file("path/to/file.pem")`. + +For backwards compatibility, if more than one of `owner`, `organization`, `GITHUB_OWNER` and `GITHUB_ORGANIZATION` are set, the first in this list takes priority. + +1. Setting `organization` in the GitHub provider configuration. +2. Setting the `GITHUB_ORGANIZATION` environment variable. +3. Setting the `GITHUB_OWNER` environment variable. +4. Setting `owner` in the GitHub provider configuration. + +~> It is a bug that `GITHUB_OWNER` takes precedence over `owner`, which may be fixed in a future major release. For compatibility with future releases, please set only one of `GITHUB_OWNER` and `owner`. diff --git a/templates/resources/actions_environment_secret.md.tmpl b/templates/resources/actions_environment_secret.md.tmpl new file mode 100644 index 0000000000..00180a1b7c --- /dev/null +++ b/templates/resources/actions_environment_secret.md.tmpl @@ -0,0 +1,48 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Creates and manages an Action Secret within a GitHub repository environment +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to create and manage GitHub Actions secrets within your GitHub repository environments. You must have write access to a repository to use this resource. + +Secret values are encrypted using the [Go '/crypto/box' module](https://godoc.org/golang.org/x/crypto/nacl/box) which is interoperable with [libsodium](https://libsodium.gitbook.io/doc/). Libsodium is used by GitHub to decrypt secret values. + +For the purposes of security, the contents of the `plaintext_value` field have been marked as `sensitive` to Terraform, but it is important to note that **this does not hide it from state files**. You should treat state as sensitive always. It is also advised that you do not store plaintext values in your code but rather populate the `encrypted_value` using fields from a resource, data source or variable as, while encrypted in state, these will be easily accessible in your code. See below for an example of this abstraction. + +## Example Usage + +{{tffile "examples/resources/actions_environment_secret/example_1.tf"}} + +{{tffile "examples/resources/actions_environment_secret/example_2.tf"}} + +## Example Lifecycle Ignore Changes + +This resource supports the `lifecycle` `ignore_changes` block. This is for use cases where a secret value is created using a placeholder value and then modified after creation outside the scope of Terraform. This approach ensures only the initial placeholder value is referenced in your code and in the resulting state file. + +{{tffile "examples/resources/actions_environment_secret/example_3.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) Name of the repository. +- `environment` - (Required) Name of the environment. +- `secret_name` - (Required) Name of the secret. +- `encrypted_value` - (Optional) Encrypted value of the secret using the GitHub public key in Base64 format. +- `plaintext_value` - (Optional) Plaintext value of the secret to be encrypted. + +## Attributes Reference + +- `created_at` - Date of actions_environment_secret creation. +- `updated_at` - Date of actions_environment_secret update. + +## Import + +This resource does not support importing. If you'd like to help contribute it, please visit our [GitHub page](https://github.com/integrations/terraform-provider-github)! diff --git a/templates/resources/actions_environment_variable.md.tmpl b/templates/resources/actions_environment_variable.md.tmpl new file mode 100644 index 0000000000..a2e8f8163e --- /dev/null +++ b/templates/resources/actions_environment_variable.md.tmpl @@ -0,0 +1,41 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Creates and manages an Action variable within a GitHub repository environment +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to create and manage GitHub Actions variables within your GitHub repository environments. You must have write access to a repository to use this resource. + +## Example Usage + +{{tffile "examples/resources/actions_environment_variable/example_1.tf"}} + +{{tffile "examples/resources/actions_environment_variable/example_2.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) Name of the repository. +- `environment` - (Required) Name of the environment. +- `variable_name` - (Required) Name of the variable. +- `value` - (Required) Value of the variable + +## Attributes Reference + +- `created_at` - Date of actions_environment_secret creation. +- `updated_at` - Date of actions_environment_secret update. + +## Import + +This resource can be imported using an ID made up of the repository name, environment name, and variable name: + +```sh +$ terraform import github_actions_environment_variable.test_variable myrepo:myenv:myvariable +``` diff --git a/templates/resources/actions_hosted_runner.md.tmpl b/templates/resources/actions_hosted_runner.md.tmpl new file mode 100644 index 0000000000..ab4e4b2c6a --- /dev/null +++ b/templates/resources/actions_hosted_runner.md.tmpl @@ -0,0 +1,105 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Creates and manages GitHub-hosted runners within a GitHub organization +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to create and manage GitHub-hosted runners within your GitHub organization. You must have admin access to an organization to use this resource. + +GitHub-hosted runners are fully managed virtual machines that run your GitHub Actions workflows. Unlike self-hosted runners, GitHub handles the infrastructure, maintenance, and scaling. + +## Example Usage + +### Basic Usage + +{{tffile "examples/resources/actions_hosted_runner/example_1.tf"}} + +### Advanced Usage with Optional Parameters + +{{tffile "examples/resources/actions_hosted_runner/example_2.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `name` - (Required) Name of the hosted runner. Must be between 1 and 64 characters and may only contain alphanumeric characters, '.', '-', and '_'. +- `image` - (Required) Image configuration for the hosted runner. Cannot be changed after creation. Block supports: + - `id` - (Required) The image ID. For GitHub-owned images, use numeric IDs like "2306" for Ubuntu Latest 24.04. To get available images, use the GitHub API: `GET /orgs/{org}/actions/hosted-runners/images/github-owned`. + - `source` - (Optional) The image source. Valid values are "github", "partner", or "custom". Defaults to "github". +- `size` - (Required) Machine size for the hosted runner (e.g., "4-core", "8-core"). Can be updated to scale the runner. To list available sizes, use the GitHub API: `GET /orgs/{org}/actions/hosted-runners/machine-sizes`. +- `runner_group_id` - (Required) The ID of the runner group to assign this runner to. +- `maximum_runners` - (Optional) Maximum number of runners to scale up to. Runners will not auto-scale above this number. Use this setting to limit costs. +- `public_ip_enabled` - (Optional) Whether to enable static public IP for the runner. Note there are account limits. To list limits, use the GitHub API: `GET /orgs/{org}/actions/hosted-runners/limits`. Defaults to false. +- `image_version` - (Optional) The version of the runner image to deploy. This is only relevant for runners using custom images. + +## Timeouts + +The `timeouts` block allows you to specify timeouts for certain actions: + +- `delete` - (Defaults to 10 minutes) Used for waiting for the hosted runner deletion to complete. + +Example: + +{{tffile "examples/resources/actions_hosted_runner/example_3.tf"}} + +## Attributes Reference + +In addition to the arguments above, the following attributes are exported: + +- `id` - The ID of the hosted runner. +- `status` - Current status of the runner (e.g., "Ready", "Provisioning"). +- `platform` - Platform of the runner (e.g., "linux-x64", "win-x64"). +- `image` - In addition to the arguments above, the image block exports: + - `size_gb` - The size of the image in gigabytes. +- `machine_size_details` - Detailed specifications of the machine size: + - `id` - Machine size identifier. + - `cpu_cores` - Number of CPU cores. + - `memory_gb` - Amount of memory in gigabytes. + - `storage_gb` - Amount of storage in gigabytes. +- `public_ips` - List of public IP ranges assigned to this runner (only if `public_ip_enabled` is true): + - `enabled` - Whether this IP range is enabled. + - `prefix` - IP address prefix. + - `length` - Subnet length. +- `last_active_on` - Timestamp (RFC3339) when the runner was last active. + +## Import + +Hosted runners can be imported using the runner ID: + +```sh +$ terraform import github_actions_hosted_runner.example 123456 +``` + +## Notes + +- This resource is **organization-only** and cannot be used with individual accounts. +- The `image` field cannot be changed after the runner is created. Changing it will force recreation of the runner. +- The `size` field can be updated to scale the runner up or down as needed. +- Image IDs for GitHub-owned images are numeric strings (e.g., "2306" for Ubuntu Latest 24.04), not names like "ubuntu-latest". +- Deletion of hosted runners is asynchronous. The provider will poll for up to 10 minutes (configurable via timeouts) to confirm deletion. +- Runner creation and updates may take several minutes as GitHub provisions the infrastructure. +- Static public IPs are subject to account limits. Check your organization's limits before enabling. + +## Getting Available Images and Sizes + +To get a list of available images: + +```bash +curl -H "Authorization: Bearer YOUR_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + https://api.github.com/orgs/YOUR_ORG/actions/hosted-runners/images/github-owned +``` + +To get available machine sizes: + +```bash +curl -H "Authorization: Bearer YOUR_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + https://api.github.com/orgs/YOUR_ORG/actions/hosted-runners/machine-sizes +``` diff --git a/templates/resources/actions_organization_oidc_subject_claim_customization_template.md.tmpl b/templates/resources/actions_organization_oidc_subject_claim_customization_template.md.tmpl new file mode 100644 index 0000000000..2d85c0b2fe --- /dev/null +++ b/templates/resources/actions_organization_oidc_subject_claim_customization_template.md.tmpl @@ -0,0 +1,33 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Creates and manages an OpenID Connect subject claim customization template for an organization +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to create and manage an OpenID Connect subject claim customization template within a GitHub organization. + +More information on integrating GitHub with cloud providers using OpenID Connect and a list of available claims is available in the [Actions documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect). + +## Example Usage + +{{tffile "examples/resources/actions_organization_oidc_subject_claim_customization_template/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `include_claim_keys` - (Required) A list of OpenID Connect claims. + +## Import + +This resource can be imported using the organization's name. + +```sh +$ terraform import github_actions_organization_oidc_subject_claim_customization_template.test example_organization +``` diff --git a/templates/resources/actions_organization_permissions.md.tmpl b/templates/resources/actions_organization_permissions.md.tmpl new file mode 100644 index 0000000000..2a96b676bf --- /dev/null +++ b/templates/resources/actions_organization_permissions.md.tmpl @@ -0,0 +1,48 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Creates and manages Actions permissions within a GitHub organization +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to create and manage GitHub Actions permissions within your GitHub enterprise organizations. You must have admin access to an organization to use this resource. + +## Example Usage + +{{tffile "examples/resources/actions_organization_permissions/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `allowed_actions` - (Optional) The permissions policy that controls the actions that are allowed to run. Can be one of: `all`, `local_only`, or `selected`. +- `enabled_repositories` - (Required) The policy that controls the repositories in the organization that are allowed to run GitHub Actions. Can be one of: `all`, `none`, or `selected`. +- `allowed_actions_config` - (Optional) Sets the actions that are allowed in an organization. Only available when `allowed_actions` = `selected`. See [Allowed Actions Config](#allowed-actions-config) below for details. +- `enabled_repositories_config` - (Optional) Sets the list of selected repositories that are enabled for GitHub Actions in an organization. Only available when `enabled_repositories` = `selected`. See [Enabled Repositories Config](#enabled-repositories-config) below for details. + +### Allowed Actions Config + +The `allowed_actions_config` block supports the following: + +- `github_owned_allowed` - (Required) Whether GitHub-owned actions are allowed in the organization. +- `patterns_allowed` - (Optional) Specifies a list of string-matching patterns to allow specific action(s). Wildcards, tags, and SHAs are allowed. For example, `monalisa/octocat@*`, `monalisa/octocat@v2`, `monalisa/*`. +- `verified_allowed` - (Optional) Whether actions in GitHub Marketplace from verified creators are allowed. Set to `true` to allow all GitHub Marketplace actions by verified creators. + +### Enabled Repositories Config + +The `enabled_repositories_config` block supports the following: + +- `repository_ids` - (Required) List of repository IDs to enable for GitHub Actions. + +## Import + +This resource can be imported using the name of the GitHub organization: + +```sh +$ terraform import github_actions_organization_permissions.test github_organization_name +``` diff --git a/templates/resources/actions_organization_secret.md.tmpl b/templates/resources/actions_organization_secret.md.tmpl new file mode 100644 index 0000000000..379e56ecd9 --- /dev/null +++ b/templates/resources/actions_organization_secret.md.tmpl @@ -0,0 +1,49 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Creates and manages an Action Secret within a GitHub organization +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to create and manage GitHub Actions secrets within your GitHub organization. You must have write access to a repository to use this resource. + +Secret values are encrypted using the [Go '/crypto/box' module](https://godoc.org/golang.org/x/crypto/nacl/box) which is interoperable with [libsodium](https://libsodium.gitbook.io/doc/). Libsodium is used by GitHub to decrypt secret values. + +For the purposes of security, the contents of the `plaintext_value` field have been marked as `sensitive` to Terraform, but it is important to note that **this does not hide it from state files**. You should treat state as sensitive always. It is also advised that you do not store plaintext values in your code but rather populate the `encrypted_value` using fields from a resource, data source or variable as, while encrypted in state, these will be easily accessible in your code. See below for an example of this abstraction. + +## Example Usage + +{{tffile "examples/resources/actions_organization_secret/example_1.tf"}} + +{{tffile "examples/resources/actions_organization_secret/example_2.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `secret_name` - (Required) Name of the secret +- `encrypted_value` - (Optional) Encrypted value of the secret using the GitHub public key in Base64 format. +- `plaintext_value` - (Optional) Plaintext value of the secret to be encrypted +- `visibility` - (Required) Configures the access that repositories have to the organization secret. Must be one of `all`, `private`, `selected`. `selected_repository_ids` is required if set to `selected`. +- `selected_repository_ids` - (Optional) An array of repository ids that can access the organization secret. +- `destroy_on_drift` - (Optional) Boolean indicating whether to recreate the secret if it's modified outside of Terraform. When `true` (default), Terraform will delete and recreate the secret if it detects external changes. When `false`, Terraform will acknowledge external changes but not recreate the secret. Defaults to `true`. + +## Attributes Reference + +- `created_at` - Date of actions_secret creation. +- `updated_at` - Date of actions_secret update. + +## Import + +This resource can be imported using an ID made up of the secret name: + +```sh +$ terraform import github_actions_organization_secret.test_secret test_secret_name +``` + +!> **Note:** The implementation is limited in that it won't fetch the value of the `plaintext_value` or `encrypted_value` fields when importing. You may need to ignore changes for these as a workaround. diff --git a/templates/resources/actions_organization_secret_repositories.md.tmpl b/templates/resources/actions_organization_secret_repositories.md.tmpl new file mode 100644 index 0000000000..d8a9f54e4b --- /dev/null +++ b/templates/resources/actions_organization_secret_repositories.md.tmpl @@ -0,0 +1,34 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Manages repository allow list for an Action Secret within a GitHub organization +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to manage repository allow list for existing GitHub Actions secrets within your GitHub organization. You must have write access to an organization secret to use this resource. + +This resource is only applicable when `visibility` of the existing organization secret has been set to `selected`. + +## Example Usage + +{{tffile "examples/resources/actions_organization_secret_repositories/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `secret_name` - (Required) Name of the existing secret +- `selected_repository_ids` - (Required) An array of repository ids that can access the organization secret. + +## Import + +This resource can be imported using an ID made up of the secret name: + +```sh +$ terraform import github_actions_organization_secret_repositories.test_secret_repos test_secret_name +``` diff --git a/templates/resources/actions_organization_secret_repository.md.tmpl b/templates/resources/actions_organization_secret_repository.md.tmpl new file mode 100644 index 0000000000..d0c0880a2e --- /dev/null +++ b/templates/resources/actions_organization_secret_repository.md.tmpl @@ -0,0 +1,34 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Adds/remove a repository to an organization secret when the visibility for repository access is set to selected. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource help you to allow/unallow a repository to use an existing GitHub Actions secrets within your GitHub organization. You must have write access to an organization secret to use this resource. + +This resource is only applicable when `visibility` of the existing organization secret has been set to `selected`. + +## Example Usage + +{{tffile "examples/resources/actions_organization_secret_repository/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `secret_name` - (Required) Name of the existing secret +- `repository_id` - (Required) Repository id that can access the organization secret. + +## Import + +This resource can be imported using an ID made up of the secret name: + +```sh +$ terraform import github_actions_organization_secret_repository.test_secret_repos test_secret_name:repo_id +``` diff --git a/templates/resources/actions_organization_variable.md.tmpl b/templates/resources/actions_organization_variable.md.tmpl new file mode 100644 index 0000000000..1678277794 --- /dev/null +++ b/templates/resources/actions_organization_variable.md.tmpl @@ -0,0 +1,41 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Creates and manages an Action variable within a GitHub organization +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to create and manage GitHub Actions variables within your GitHub organization. You must have write access to a repository to use this resource. + +## Example Usage + +{{tffile "examples/resources/actions_organization_variable/example_1.tf"}} + +{{tffile "examples/resources/actions_organization_variable/example_2.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `variable_name` - (Required) Name of the variable +- `value` - (Required) Value of the variable +- `visibility` - (Required) Configures the access that repositories have to the organization variable. Must be one of `all`, `private`, `selected`. `selected_repository_ids` is required if set to `selected`. +- `selected_repository_ids` - (Optional) An array of repository ids that can access the organization variable. + +## Attributes Reference + +- `created_at` - Date of actions_variable creation. +- `updated_at` - Date of actions_variable update. + +## Import + +This resource can be imported using an ID made up of the variable name: + +```sh +$ terraform import github_actions_organization_variable.test_variable test_variable_name +``` diff --git a/templates/resources/actions_repository_access_level.md.tmpl b/templates/resources/actions_repository_access_level.md.tmpl new file mode 100644 index 0000000000..c8e1e63551 --- /dev/null +++ b/templates/resources/actions_repository_access_level.md.tmpl @@ -0,0 +1,32 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Manages Actions and Reusable Workflow access for a GitHub repository +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to set the access level of a non-public repositories actions and reusable workflows for use in other repositories. You must have admin access to a repository to use this resource. + +## Example Usage + +{{tffile "examples/resources/actions_repository_access_level/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The GitHub repository +- `access_level` - (Required) Where the actions or reusable workflows of the repository may be used. Possible values are `none`, `user`, `organization`, or `enterprise`. + +## Import + +This resource can be imported using the name of the GitHub repository: + +```sh +$ terraform import github_actions_repository_access_level.test my-repository +``` diff --git a/templates/resources/actions_repository_oidc_subject_claim_customization_template.md.tmpl b/templates/resources/actions_repository_oidc_subject_claim_customization_template.md.tmpl new file mode 100644 index 0000000000..0f78b05b6d --- /dev/null +++ b/templates/resources/actions_repository_oidc_subject_claim_customization_template.md.tmpl @@ -0,0 +1,42 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Creates and manages an OpenID Connect subject claim customization template for a repository +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to create and manage an OpenID Connect subject claim customization template for a GitHub repository. + +More information on integrating GitHub with cloud providers using OpenID Connect and a list of available claims is available in the [Actions documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect). + +The following table lists the behaviour of `use_default`: + +| `use_default` | `include_claim_keys` | Template used | +|---------------|----------------------|-----------------------------------------------------------| +| `true` | Unset | GitHub's default | +| `false` | Set | `include_claim_keys` | +| `false` | Unset | Organization's default if set, otherwise GitHub's default | + +## Example Usage + +{{tffile "examples/resources/actions_repository_oidc_subject_claim_customization_template/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `use_default` - (Required) Whether to use the default template or not. If `true`, `include_claim_keys` must not be set. +- `include_claim_keys` - (Optional) A list of OpenID Connect claims. + +## Import + +This resource can be imported using the repository's name. + +```sh +$ terraform import github_actions_repository_oidc_subject_claim_customization_template.test example_repository +``` diff --git a/templates/resources/actions_repository_permissions.md.tmpl b/templates/resources/actions_repository_permissions.md.tmpl new file mode 100644 index 0000000000..2e06af75d4 --- /dev/null +++ b/templates/resources/actions_repository_permissions.md.tmpl @@ -0,0 +1,42 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Enables and manages Actions permissions for a GitHub repository +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to enable and manage GitHub Actions permissions for a given repository. You must have admin access to an repository to use this resource. + +## Example Usage + +{{tffile "examples/resources/actions_repository_permissions/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The GitHub repository +- `allowed_actions` - (Optional) The permissions policy that controls the actions that are allowed to run. Can be one of: `all`, `local_only`, or `selected`. +- `enabled` - (Optional) Should GitHub actions be enabled on this repository? +- `allowed_actions_config` - (Optional) Sets the actions that are allowed in an repository. Only available when `allowed_actions` = `selected`. See [Allowed Actions Config](#allowed-actions-config) below for details. + +### Allowed Actions Config + +The `allowed_actions_config` block supports the following: + +- `github_owned_allowed` - (Required) Whether GitHub-owned actions are allowed in the repository. +- `patterns_allowed` - (Optional) Specifies a list of string-matching patterns to allow specific action(s). Wildcards, tags, and SHAs are allowed. For example, `monalisa/octocat@*`, `monalisa/octocat@v2`, `monalisa/*`. +- `verified_allowed` - (Optional) Whether actions in GitHub Marketplace from verified creators are allowed. Set to `true` to allow all GitHub Marketplace actions by verified creators. + +## Import + +This resource can be imported using the name of the GitHub repository: + +```sh +$ terraform import github_actions_repository_permissions.test my-repository +``` diff --git a/templates/resources/actions_runner_group.md.tmpl b/templates/resources/actions_runner_group.md.tmpl new file mode 100644 index 0000000000..1c7aea09ee --- /dev/null +++ b/templates/resources/actions_runner_group.md.tmpl @@ -0,0 +1,49 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Creates and manages an Actions Runner Group within a GitHub organization +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to create and manage GitHub Actions runner groups within your GitHub enterprise organizations. You must have admin access to an organization to use this resource. + +## Example Usage + +{{tffile "examples/resources/actions_runner_group/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `name` - (Required) Name of the runner group +- `restricted_to_workflows` - (Optional) If true, the runner group will be restricted to running only the workflows specified in the selected_workflows array. Defaults to false. +- `selected_repository_ids` - (Optional) IDs of the repositories which should be added to the runner group +- `selected_workflows` - (Optional) List of workflows the runner group should be allowed to run. This setting will be ignored unless restricted_to_workflows is set to true. +- `visibility` - (Optional) Visibility of a runner group. Whether the runner group can include `all`, `selected`, or `private` repositories. A value of `private` is not currently supported due to limitations in the GitHub API. +- `allows_public_repositories` - (Optional) Whether public repositories can be added to the runner group. Defaults to false. + +## Attributes Reference + +- `allows_public_repositories` - Whether public repositories can be added to the runner group +- `default` - Whether this is the default runner group +- `etag` - An etag representing the runner group object +- `inherited` - Whether the runner group is inherited from the enterprise level +- `runners_url` - The GitHub API URL for the runner group's runners +- `selected_repository_ids` - List of repository IDs that can access the runner group +- `selected_repositories_url` - GitHub API URL for the runner group's repositories +- `visibility` - The visibility of the runner group +- `restricted_to_workflows` - If true, the runner group will be restricted to running only the workflows specified in the selected_workflows array. Defaults to false. +- `selected_workflows` - List of workflows the runner group should be allowed to run. This setting will be ignored unless restricted_to_workflows is set to true. + +## Import + +This resource can be imported using the ID of the runner group: + +```sh +$ terraform import github_actions_runner_group.test 7 +``` diff --git a/templates/resources/actions_secret.md.tmpl b/templates/resources/actions_secret.md.tmpl new file mode 100644 index 0000000000..3dd51bcff8 --- /dev/null +++ b/templates/resources/actions_secret.md.tmpl @@ -0,0 +1,46 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Creates and manages an Action Secret within a GitHub repository +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to create and manage GitHub Actions secrets within your GitHub repositories. You must have write access to a repository to use this resource. + +Secret values are encrypted using the [Go '/crypto/box' module](https://godoc.org/golang.org/x/crypto/nacl/box) which is interoperable with [libsodium](https://libsodium.gitbook.io/doc/). Libsodium is used by GitHub to decrypt secret values. + +For the purposes of security, the contents of the `plaintext_value` field have been marked as `sensitive` to Terraform, but it is important to note that **this does not hide it from state files**. You should treat state as sensitive always. It is also advised that you do not store plaintext values in your code but rather populate the `encrypted_value` using fields from a resource, data source or variable as, while encrypted in state, these will be easily accessible in your code. See below for an example of this abstraction. + +## Example Usage + +{{tffile "examples/resources/actions_secret/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) Name of the repository +- `secret_name` - (Required) Name of the secret +- `encrypted_value` - (Optional) Encrypted value of the secret using the GitHub public key in Base64 format. +- `plaintext_value` - (Optional) Plaintext value of the secret to be encrypted +- `destroy_on_drift` - (Optional) Boolean indicating whether to recreate the secret if it's modified outside of Terraform. When `true` (default), Terraform will delete and recreate the secret if it detects external changes. When `false`, Terraform will acknowledge external changes but not recreate the secret. Defaults to `true`. + +## Attributes Reference + +- `created_at` - Date of actions_secret creation. +- `updated_at` - Date of actions_secret update. + +## Import + +This resource can be imported using an ID made up of the `repository` and `secret_name`: + +```sh +$ terraform import github_actions_secret.example_secret repository/secret_name +``` + +!> **Note:** The implementation is limited in that it won't fetch the value of the `plaintext_value` or `encrypted_value` fields when importing. You may need to ignore changes for these as a workaround. diff --git a/templates/resources/actions_variable.md.tmpl b/templates/resources/actions_variable.md.tmpl new file mode 100644 index 0000000000..82e3909671 --- /dev/null +++ b/templates/resources/actions_variable.md.tmpl @@ -0,0 +1,38 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Creates and manages an Action variable within a GitHub repository +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to create and manage GitHub Actions variables within your GitHub repositories. You must have write access to a repository to use this resource. + +## Example Usage + +{{tffile "examples/resources/actions_variable/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) Name of the repository +- `variable_name` - (Required) Name of the variable +- `value` - (Required) Value of the variable + +## Attributes Reference + +- `created_at` - Date of actions_variable creation. +- `updated_at` - Date of actions_variable update. + +## Import + +GitHub Actions variables can be imported using an ID made up of `repository:variable_name`, e.g. + +```sh +$ terraform import github_actions_variable.myvariable myrepo:myvariable +``` diff --git a/templates/resources/app_installation_repositories.md.tmpl b/templates/resources/app_installation_repositories.md.tmpl new file mode 100644 index 0000000000..22e1a4743e --- /dev/null +++ b/templates/resources/app_installation_repositories.md.tmpl @@ -0,0 +1,40 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Manages the associations between app installations and repositories. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +~> **Note**: This resource is not compatible with the GitHub App Installation authentication method. + +This resource manages relationships between app installations and repositories in your GitHub organization. + +Creating this resource installs a particular app on multiple repositories. + +The app installation and the repositories must all belong to the same organization on GitHub. Note: you can review your organization's installations by the following the instructions at this [link](https://docs.github.com/en/github/setting-up-and-managing-organizations-and-teams/reviewing-your-organizations-installed-integrations). + +## Example Usage + +{{tffile "examples/resources/app_installation_repositories/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `installation_id` - (Required) The GitHub app installation id. +- `selected_repositories` - (Required) A list of repository names to install the app on. + +~> **Note**: Due to how GitHub implements app installations, apps cannot be installed with no repositories selected. Therefore deleting this resource will leave one repository with the app installed. Manually uninstall the app or set the installation to all repositories via the GUI as after deleting this resource. + +## Import + +GitHub App Installation Repositories can be imported using an ID made up of `installation_id`, e.g. + +```sh +$ terraform import github_app_installation_repositories.some_app_repos 1234567 +``` diff --git a/templates/resources/app_installation_repository.md.tmpl b/templates/resources/app_installation_repository.md.tmpl new file mode 100644 index 0000000000..5d460c34eb --- /dev/null +++ b/templates/resources/app_installation_repository.md.tmpl @@ -0,0 +1,38 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Manages the associations between app installations and repositories. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +~> **Note**: This resource is not compatible with the GitHub App Installation authentication method. + +This resource manages relationships between app installations and repositories in your GitHub organization. + +Creating this resource installs a particular app on a particular repository. + +The app installation and the repository must both belong to the same organization on GitHub. Note: you can review your organization's installations by the following the instructions at this [link](https://docs.github.com/en/github/setting-up-and-managing-organizations-and-teams/reviewing-your-organizations-installed-integrations). + +## Example Usage + +{{tffile "examples/resources/app_installation_repository/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `installation_id` - (Required) The GitHub app installation id. +- `repository` - (Required) The repository to install the app on. + +## Import + +GitHub App Installation Repository can be imported using an ID made up of `installation_id:repository`, e.g. + +```sh +$ terraform import github_app_installation_repository.terraform_repo 1234567:terraform +``` diff --git a/templates/resources/branch.md.tmpl b/templates/resources/branch.md.tmpl new file mode 100644 index 0000000000..6da6c169f5 --- /dev/null +++ b/templates/resources/branch.md.tmpl @@ -0,0 +1,63 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Creates and manages branches within GitHub repositories. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to create and manage branches within your repository. + +Additional constraints can be applied to ensure your branch is created from another branch or commit. + +## Example Usage + +{{tffile "examples/resources/branch/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The GitHub repository name. + +- `branch` - (Required) The repository branch to create. + +- `source_branch` - (Optional) The branch name to start from. Defaults to `main`. + +- `source_sha` - (Optional) The commit hash to start from. Defaults to the tip of `source_branch`. If provided, `source_branch` is ignored. + +## Attribute Reference + +The following additional attributes are exported: + +- `source_sha` - A string storing the commit this branch was started from. Not populated when imported. + +- `etag` - An etag representing the Branch object. + +- `ref` - A string representing a branch reference, in the form of `refs/heads/`. + +- `sha` - A string storing the reference's `HEAD` commit's SHA1. + +## Import + +GitHub Branch can be imported using an ID made up of `repository:branch`, e.g. + +```sh +$ terraform import github_branch.terraform terraform:main +``` + +Importing github branch into an instance object (when using a for each block to manage multiple branches) + +```sh +$ terraform import github_branch.terraform["terraform"] terraform:main +``` + +Optionally, a source branch may be specified using an ID of `repository:branch:source_branch`. This is useful for importing branches that do not branch directly off main. + +```sh +$ terraform import github_branch.terraform terraform:feature-branch:dev +``` diff --git a/templates/resources/branch_default.md.tmpl b/templates/resources/branch_default.md.tmpl new file mode 100644 index 0000000000..8eda62bdb8 --- /dev/null +++ b/templates/resources/branch_default.md.tmpl @@ -0,0 +1,43 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Provides a GitHub branch default for a given repository. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Provides a GitHub branch default resource. + +This resource allows you to set the default branch for a given repository. + +Note that use of this resource is incompatible with the `default_branch` option of the `github_repository` resource. Using both will result in plans always showing a diff. + +## Example Usage + +Basic usage: + +{{tffile "examples/resources/branch_default/example_1.tf"}} + +Renaming to a branch that doesn't exist: + +{{tffile "examples/resources/branch_default/example_2.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The GitHub repository +- `branch` - (Required) The branch (e.g. `main`) +- `rename` - (Optional) Indicate if it should rename the branch rather than use an existing branch. Defaults to `false`. + +## Import + +GitHub Branch Defaults can be imported using an ID made up of `repository`, e.g. + +```sh +$ terraform import github_branch_default.branch_default my-repo +``` diff --git a/templates/resources/branch_protection.md.tmpl b/templates/resources/branch_protection.md.tmpl new file mode 100644 index 0000000000..faf35158e3 --- /dev/null +++ b/templates/resources/branch_protection.md.tmpl @@ -0,0 +1,75 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Protects a GitHub branch. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Protects a GitHub branch. + +This resource allows you to configure branch protection for repositories in your organization. When applied, the branch will be protected from forced pushes and deletion. Additional constraints, such as required status checks or restrictions on users, teams, and apps, can also be configured. + +Note: for the `push_allowances` a given user or team must have specific write access to the repository. If specific write access not provided, github will reject the given actor, which will be the cause of terraform drift. + +## Example Usage + +{{tffile "examples/resources/branch_protection/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `repository_id` - (Required) The name or node ID of the repository associated with this branch protection rule. +- `pattern` - (Required) Identifies the protection rule pattern. +- `enforce_admins` - (Optional) Boolean, setting this to `true` enforces status checks for repository administrators. +- `require_signed_commits` - (Optional) Boolean, setting this to `true` requires all commits to be signed with GPG. +- `required_linear_history` - (Optional) Boolean, setting this to `true` enforces a linear commit Git history, which prevents anyone from pushing merge commits to a branch +- `require_conversation_resolution` - (Optional) Boolean, setting this to `true` requires all conversations on code must be resolved before a pull request can be merged. +- `required_status_checks` - (Optional) Enforce restrictions for required status checks. See [Required Status Checks](#required-status-checks) below for details. +- `required_pull_request_reviews` - (Optional) Enforce restrictions for pull request reviews. See [Required Pull Request Reviews](#required-pull-request-reviews) below for details. +- `restrict_pushes` - (Optional) Restrict pushes to matching branches. See [Restrict Pushes](#restrict-pushes) below for details. +- `force_push_bypassers` - (Optional) The list of actor Names/IDs that are allowed to bypass force push restrictions. Actor names must either begin with a "/" for users or the organization name followed by a "/" for teams. If the list is not empty, `allows_force_pushes` should be set to `false`. +- `allows_deletions` - (Optional) Boolean, setting this to `true` to allow the branch to be deleted. +- `allows_force_pushes` - (Optional) Boolean, setting this to `true` to allow force pushes on the branch to everyone. Set it to `false` if you specify `force_push_bypassers`. +- `lock_branch` - (Optional) Boolean, Setting this to `true` will make the branch read-only and preventing any pushes to it. Defaults to `false` + +### Required Status Checks + +`required_status_checks` supports the following arguments: + +- `strict`: (Optional) Require branches to be up to date before merging. Defaults to `false`. +- `contexts`: (Optional) The list of status checks to require in order to merge into this branch. No status checks are required by default. + +~> Note: This attribute can contain multiple string patterns. If specified, usual value is the [job name](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idname). Otherwise, the [job id](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idname) is defaulted to. For workflows that use matrixes, append the matrix name to the value using the following pattern `([, ])`. Matrixes should be specified based on the order of matrix properties in the workflow file. See [GitHub Documentation](https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs#using-a-matrix-strategy) for more information. For workflows that use reusable workflows, the pattern is ` / `. This can extend multiple levels. + +### Required Pull Request Reviews + +`required_pull_request_reviews` supports the following arguments: + +- `dismiss_stale_reviews`: (Optional) Dismiss approved reviews automatically when a new commit is pushed. Defaults to `false`. +- `restrict_dismissals`: (Optional) Restrict pull request review dismissals. +- `dismissal_restrictions`: (Optional) The list of actor Names/IDs with dismissal access. If not empty, `restrict_dismissals` is ignored. Actor names must either begin with a "/" for users or the organization name followed by a "/" for teams. +- `pull_request_bypassers`: (Optional) The list of actor Names/IDs that are allowed to bypass pull request requirements. Actor names must either begin with a "/" for users or the organization name followed by a "/" for teams. +- `require_code_owner_reviews`: (Optional) Require an approved review in pull requests including files with a designated code owner. Defaults to `false`. +- `required_approving_review_count`: (Optional) Require x number of approvals to satisfy branch protection requirements. If this is specified it must be a number between 0-6. This requirement matches GitHub's API, see the upstream [documentation](https://docs.github.com/en/rest/branches/branch-protection?apiVersion=2022-11-28#update-branch-protection--parameters) for more information. +- `require_last_push_approval`: (Optional) Require that The most recent push must be approved by someone other than the last pusher. Defaults to `false` + +### Restrict Pushes + +`restrict_pushes` supports the following arguments: + +- `blocks_creations` - (Optional) Boolean, setting this to `false` allows people, teams, or apps to create new branches matching this rule. Defaults to `true`. +- `push_allowances` - (Optional) A list of actor Names/IDs that may push to the branch. Actor names must either begin with a "/" for users or the organization name followed by a "/" for teams. Organization administrators, repository administrators, and users with the Maintain role on the repository can always push when all other requirements have passed. + +## Import + +GitHub Branch Protection can be imported using an ID made up of `repository:pattern`, e.g. + +```sh +$ terraform import github_branch_protection.terraform terraform:main +``` diff --git a/templates/resources/branch_protection_v3.md.tmpl b/templates/resources/branch_protection_v3.md.tmpl new file mode 100644 index 0000000000..3aa83b4703 --- /dev/null +++ b/templates/resources/branch_protection_v3.md.tmpl @@ -0,0 +1,86 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Protects a GitHub branch using the v3 / REST implementation. The `github_branch_protection` resource has moved to the GraphQL API, while this resource will continue to leverage the REST API +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Protects a GitHub branch. + +The `github_branch_protection` resource has moved to the GraphQL API, while this resource will continue to leverage the REST API. + +This resource allows you to configure branch protection for repositories in your organization. When applied, the branch will be protected from forced pushes and deletion. Additional constraints, such as required status checks or restrictions on users, teams, and apps, can also be configured. + +## Example Usage + +{{tffile "examples/resources/branch_protection_v3/example_1.tf"}} + +{{tffile "examples/resources/branch_protection_v3/example_2.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The GitHub repository name. +- `branch` - (Required) The Git branch to protect. +- `enforce_admins` - (Optional) Boolean, setting this to `true` enforces status checks for repository administrators. +- `require_signed_commits` - (Optional) Boolean, setting this to `true` requires all commits to be signed with GPG. +- `require_conversation_resolution` - (Optional) Boolean, setting this to `true` requires all conversations on code must be resolved before a pull request can be merged. +- `required_status_checks` - (Optional) Enforce restrictions for required status checks. See [Required Status Checks](#required-status-checks) below for details. +- `required_pull_request_reviews` - (Optional) Enforce restrictions for pull request reviews. See [Required Pull Request Reviews](#required-pull-request-reviews) below for details. +- `restrictions` - (Optional) Enforce restrictions for the users and teams that may push to the branch. See [Restrictions](#restrictions) below for details. + +### Required Status Checks + +`required_status_checks` supports the following arguments: + +- `strict`: (Optional) Require branches to be up to date before merging. Defaults to `false`. +- `contexts`: [**DEPRECATED**] (Optional) The list of status checks to require in order to merge into this branch. No status checks are required by default. + +~> Note: This attribute can contain multiple string patterns. If specified, usual value is the [job name](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idname). Otherwise, the [job id](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idname) is defaulted to. For workflows that use matrixes, append the matrix name to the value using the following pattern `([, ])`. Matrixes should be specified based on the order of matrix properties in the workflow file. See [GitHub Documentation](https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs#using-a-matrix-strategy) for more information. For workflows that use reusable workflows, the pattern is ` / `. This can extend multiple levels. + +- `checks`: (Optional) The list of status checks to require in order to merge into this branch. No status checks are required by default. Checks should be strings containing the context and app_id like so "context:app_id". + +### Required Pull Request Reviews + +`required_pull_request_reviews` supports the following arguments: + +- `dismiss_stale_reviews`: (Optional) Dismiss approved reviews automatically when a new commit is pushed. Defaults to `false`. +- `dismissal_users`: (Optional) The list of user logins with dismissal access +- `dismissal_teams`: (Optional) The list of team slugs with dismissal access. Always use `slug` of the team, **not** its name. Each team already **has** to have access to the repository. +- `dismissal_apps`: (Optional) The list of app slugs with dismissal access. +- `require_code_owner_reviews`: (Optional) Require an approved review in pull requests including files with a designated code owner. Defaults to `false`. +- `required_approving_review_count`: (Optional) Require x number of approvals to satisfy branch protection requirements. If this is specified it must be a number between 0-6. This requirement matches GitHub's API, see the upstream [documentation](https://docs.github.com/en/rest/branches/branch-protection?apiVersion=2022-11-28#update-branch-protection--parameters) for more information. +- `bypass_pull_request_allowances`: (Optional) Allow specific users, teams, or apps to bypass pull request requirements. See [Bypass Pull Request Allowances](#bypass-pull-request-allowances) below for details. +- `require_last_push_approval`: (Optional) Require that the most recent push must be approved by someone other than the last pusher. Defaults to `false` + +### Restrictions + +`restrictions` supports the following arguments: + +- `users`: (Optional) The list of user logins with push access. +- `teams`: (Optional) The list of team slugs with push access. Always use `slug` of the team, **not** its name. Each team already **has** to have access to the repository. +- `apps`: (Optional) The list of app slugs with push access. + +`restrictions` is only available for organization-owned repositories. + +### Bypass Pull Request Allowances + +`bypass_pull_request_allowances` supports the following arguments: + +- `users`: (Optional) The list of user logins allowed to bypass pull request requirements. +- `teams`: (Optional) The list of team slugs allowed to bypass pull request requirements. +- `apps`: (Optional) The list of app slugs allowed to bypass pull request requirements. + +## Import + +GitHub Branch Protection can be imported using an ID made up of `repository:branch`, e.g. + +```sh +$ terraform import github_branch_protection_v3.terraform terraform:main +``` diff --git a/templates/resources/codespaces_organization_secret.md.tmpl b/templates/resources/codespaces_organization_secret.md.tmpl new file mode 100644 index 0000000000..daadaa9060 --- /dev/null +++ b/templates/resources/codespaces_organization_secret.md.tmpl @@ -0,0 +1,48 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Creates and manages an Codespaces Secret within a GitHub organization +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to create and manage GitHub Codespaces secrets within your GitHub organization. You must have write access to a repository to use this resource. + +Secret values are encrypted using the [Go '/crypto/box' module](https://godoc.org/golang.org/x/crypto/nacl/box) which is interoperable with [libsodium](https://libsodium.gitbook.io/doc/). Libsodium is used by GitHub to decrypt secret values. + +For the purposes of security, the contents of the `plaintext_value` field have been marked as `sensitive` to Terraform, but it is important to note that **this does not hide it from state files**. You should treat state as sensitive always. It is also advised that you do not store plaintext values in your code but rather populate the `encrypted_value` using fields from a resource, data source or variable as, while encrypted in state, these will be easily accessible in your code. See below for an example of this abstraction. + +## Example Usage + +{{tffile "examples/resources/codespaces_organization_secret/example_1.tf"}} + +{{tffile "examples/resources/codespaces_organization_secret/example_2.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `secret_name` - (Required) Name of the secret +- `encrypted_value` - (Optional) Encrypted value of the secret using the GitHub public key in Base64 format. +- `plaintext_value` - (Optional) Plaintext value of the secret to be encrypted +- `visibility` - (Required) Configures the access that repositories have to the organization secret. Must be one of `all`, `private`, `selected`. `selected_repository_ids` is required if set to `selected`. +- `selected_repository_ids` - (Optional) An array of repository ids that can access the organization secret. + +## Attributes Reference + +- `created_at` - Date of codespaces_secret creation. +- `updated_at` - Date of codespaces_secret update. + +## Import + +This resource can be imported using an ID made up of the secret name: + +```sh +terraform import github_codespaces_organization_secret.test_secret test_secret_name +``` + +!> **Note:** The implementation is limited in that it won't fetch the value of the `plaintext_value` or `encrypted_value` fields when importing. You may need to ignore changes for these as a workaround. diff --git a/templates/resources/codespaces_organization_secret_repositories.md.tmpl b/templates/resources/codespaces_organization_secret_repositories.md.tmpl new file mode 100644 index 0000000000..2bce4f5973 --- /dev/null +++ b/templates/resources/codespaces_organization_secret_repositories.md.tmpl @@ -0,0 +1,36 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Manages repository allow list for a Codespaces Secret within a GitHub organization +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to manage repository allow list for existing GitHub Codespaces secrets within your GitHub organization. + +You must have write access to an organization secret to use this resource. + +This resource is only applicable when `visibility` of the existing organization secret has been set to `selected`. + +## Example Usage + +{{tffile "examples/resources/codespaces_organization_secret_repositories/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `secret_name` - (Required) Name of the existing secret +- `selected_repository_ids` - (Required) An array of repository ids that can access the organization secret. + +## Import + +This resource can be imported using an ID made up of the secret name: + +```sh +$ terraform import github_codespaces_organization_secret_repositories.org_secret_repos existing_secret_name +``` diff --git a/templates/resources/codespaces_secret.md.tmpl b/templates/resources/codespaces_secret.md.tmpl new file mode 100644 index 0000000000..871a4b7262 --- /dev/null +++ b/templates/resources/codespaces_secret.md.tmpl @@ -0,0 +1,45 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Creates and manages an Codespaces Secret within a GitHub repository +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to create and manage GitHub Codespaces secrets within your GitHub repositories. You must have write access to a repository to use this resource. + +Secret values are encrypted using the [Go '/crypto/box' module](https://godoc.org/golang.org/x/crypto/nacl/box) which is interoperable with [libsodium](https://libsodium.gitbook.io/doc/). Libsodium is used by GitHub to decrypt secret values. + +For the purposes of security, the contents of the `plaintext_value` field have been marked as `sensitive` to Terraform, but it is important to note that **this does not hide it from state files**. You should treat state as sensitive always. It is also advised that you do not store plaintext values in your code but rather populate the `encrypted_value` using fields from a resource, data source or variable as, while encrypted in state, these will be easily accessible in your code. See below for an example of this abstraction. + +## Example Usage + +{{tffile "examples/resources/codespaces_secret/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) Name of the repository +- `secret_name` - (Required) Name of the secret +- `encrypted_value` - (Optional) Encrypted value of the secret using the GitHub public key in Base64 format. +- `plaintext_value` - (Optional) Plaintext value of the secret to be encrypted + +## Attributes Reference + +- `created_at` - Date of codespaces_secret creation. +- `updated_at` - Date of codespaces_secret update. + +## Import + +This resource can be imported using an ID made up of the `repository` and `secret_name`: + +```sh +$ terraform import github_codespaces_secret.example_secret example_repository/example_secret_name +``` + +!> **Note:** The implementation is limited in that it won't fetch the value of the `plaintext_value` or `encrypted_value` fields when importing. You may need to ignore changes for these as a workaround. diff --git a/templates/resources/codespaces_user_secret.md.tmpl b/templates/resources/codespaces_user_secret.md.tmpl new file mode 100644 index 0000000000..400dee73e0 --- /dev/null +++ b/templates/resources/codespaces_user_secret.md.tmpl @@ -0,0 +1,45 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Creates and manages an Codespaces Secret within a GitHub user +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to create and manage GitHub Codespaces secrets within your GitHub user. You must have write access to a repository to use this resource. + +Secret values are encrypted using the [Go '/crypto/box' module](https://godoc.org/golang.org/x/crypto/nacl/box) which is interoperable with [libsodium](https://libsodium.gitbook.io/doc/). Libsodium is used by GitHub to decrypt secret values. + +For the purposes of security, the contents of the `plaintext_value` field have been marked as `sensitive` to Terraform, but it is important to note that **this does not hide it from state files**. You should treat state as sensitive always. It is also advised that you do not store plaintext values in your code but rather populate the `encrypted_value` using fields from a resource, data source or variable as, while encrypted in state, these will be easily accessible in your code. See below for an example of this abstraction. + +## Example Usage + +{{tffile "examples/resources/codespaces_user_secret/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `secret_name` - (Required) Name of the secret +- `encrypted_value` - (Optional) Encrypted value of the secret using the GitHub public key in Base64 format. +- `plaintext_value` - (Optional) Plaintext value of the secret to be encrypted +- `selected_repository_ids` - (Optional) An array of repository ids that can access the user secret. + +## Attributes Reference + +- `created_at` - Date of codespaces_secret creation. +- `updated_at` - Date of codespaces_secret update. + +## Import + +This resource can be imported using an ID made up of the secret name: + +```sh +terraform import github_codespaces_user_secret.test_secret test_secret_name +``` + +!> **Note:** The implementation is limited in that it won't fetch the value of the `plaintext_value` or `encrypted_value` fields when importing. You may need to ignore changes for these as a workaround. diff --git a/templates/resources/dependabot_organization_secret.md.tmpl b/templates/resources/dependabot_organization_secret.md.tmpl new file mode 100644 index 0000000000..ca942a8693 --- /dev/null +++ b/templates/resources/dependabot_organization_secret.md.tmpl @@ -0,0 +1,48 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Creates and manages an Dependabot Secret within a GitHub organization +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to create and manage GitHub Dependabot secrets within your GitHub organization. You must have write access to a repository to use this resource. + +Secret values are encrypted using the [Go '/crypto/box' module](https://godoc.org/golang.org/x/crypto/nacl/box) which is interoperable with [libsodium](https://libsodium.gitbook.io/doc/). Libsodium is used by GitHub to decrypt secret values. + +For the purposes of security, the contents of the `plaintext_value` field have been marked as `sensitive` to Terraform, but it is important to note that **this does not hide it from state files**. You should treat state as sensitive always. It is also advised that you do not store plaintext values in your code but rather populate the `encrypted_value` using fields from a resource, data source or variable as, while encrypted in state, these will be easily accessible in your code. See below for an example of this abstraction. + +## Example Usage + +{{tffile "examples/resources/dependabot_organization_secret/example_1.tf"}} + +{{tffile "examples/resources/dependabot_organization_secret/example_2.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `secret_name` - (Required) Name of the secret +- `encrypted_value` - (Optional) Encrypted value of the secret using the GitHub public key in Base64 format. +- `plaintext_value` - (Optional) Plaintext value of the secret to be encrypted +- `visibility` - (Required) Configures the access that repositories have to the organization secret. Must be one of `all`, `private`, `selected`. `selected_repository_ids` is required if set to `selected`. +- `selected_repository_ids` - (Optional) An array of repository ids that can access the organization secret. + +## Attributes Reference + +- `created_at` - Date of dependabot_secret creation. +- `updated_at` - Date of dependabot_secret update. + +## Import + +This resource can be imported using an ID made up of the secret name: + +```sh +terraform import github_dependabot_organization_secret.test_secret test_secret_name +``` + +!> **Note:** The implementation is limited in that it won't fetch the value of the `plaintext_value` or `encrypted_value` fields when importing. You may need to ignore changes for these as a workaround. diff --git a/templates/resources/dependabot_organization_secret_repositories.md.tmpl b/templates/resources/dependabot_organization_secret_repositories.md.tmpl new file mode 100644 index 0000000000..0d9f369fde --- /dev/null +++ b/templates/resources/dependabot_organization_secret_repositories.md.tmpl @@ -0,0 +1,34 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Manages repository allow list for an Dependabot Secret within a GitHub organization +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to manage the repository allow list for existing GitHub Dependabot secrets within your GitHub organization. You must have write access to an organization secret to use this resource. + +This resource is only applicable when `visibility` of the existing organization secret has been set to `selected`. + +## Example Usage + +{{tffile "examples/resources/dependabot_organization_secret_repositories/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `secret_name` - (Required) Name of the existing secret +- `selected_repository_ids` - (Required) An array of repository ids that can access the organization secret. + +## Import + +This resource can be imported using an ID made up of the secret name: + +```sh +terraform import github_dependabot_organization_secret_repositories.test_secret_repos test_secret_name +``` diff --git a/templates/resources/dependabot_secret.md.tmpl b/templates/resources/dependabot_secret.md.tmpl new file mode 100644 index 0000000000..072b054985 --- /dev/null +++ b/templates/resources/dependabot_secret.md.tmpl @@ -0,0 +1,45 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Creates and manages an Dependabot Secret within a GitHub repository +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to create and manage GitHub Dependabot secrets within your GitHub repositories. You must have write access to a repository to use this resource. + +Secret values are encrypted using the [Go '/crypto/box' module](https://godoc.org/golang.org/x/crypto/nacl/box) which is interoperable with [libsodium](https://libsodium.gitbook.io/doc/). Libsodium is used by GitHub to decrypt secret values. + +For the purposes of security, the contents of the `plaintext_value` field have been marked as `sensitive` to Terraform, but it is important to note that **this does not hide it from state files**. You should treat state as sensitive always. It is also advised that you do not store plaintext values in your code but rather populate the `encrypted_value` using fields from a resource, data source or variable as, while encrypted in state, these will be easily accessible in your code. See below for an example of this abstraction. + +## Example Usage + +{{tffile "examples/resources/dependabot_secret/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) Name of the repository +- `secret_name` - (Required) Name of the secret +- `encrypted_value` - (Optional) Encrypted value of the secret using the GitHub public key in Base64 format. +- `plaintext_value` - (Optional) Plaintext value of the secret to be encrypted + +## Attributes Reference + +- `created_at` - Date of dependabot_secret creation. +- `updated_at` - Date of dependabot_secret update. + +## Import + +This resource can be imported using an ID made up of the `repository` and `secret_name`: + +```sh +$ terraform import github_dependabot_secret.example_secret example_repository/example_secret +``` + +!> **Note:** The implementation is limited in that it won't fetch the value of the `plaintext_value` or `encrypted_value` fields when importing. You may need to ignore changes for these as a workaround. diff --git a/templates/resources/emu_group_mapping.md.tmpl b/templates/resources/emu_group_mapping.md.tmpl new file mode 100644 index 0000000000..e3b1634219 --- /dev/null +++ b/templates/resources/emu_group_mapping.md.tmpl @@ -0,0 +1,32 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Manages mappings between external groups for enterprise managed users. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource manages mappings between external groups for enterprise managed users and GitHub teams. It wraps the API detailed [here](https://docs.github.com/en/rest/reference/teams#external-groups). Note that this is a distinct resource from `github_team_sync_group_mapping`. `github_emu_group_mapping` is special to the Enterprise Managed User (EMU) external group feature, whereas `github_team_sync_group_mapping` is specific to Identity Provider Groups. + +## Example Usage + +{{tffile "examples/resources/emu_group_mapping/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `team_slug` - (Required) Slug of the GitHub team +- `group_id` - (Required) Integer corresponding to the external group ID to be linked + +## Import + +GitHub EMU External Group Mappings can be imported using the external `group_id`, e.g. + +```sh +$ terraform import github_emu_group_mapping.example_emu_group_mapping 28836 +``` diff --git a/templates/resources/enterprise_actions_permissions.md.tmpl b/templates/resources/enterprise_actions_permissions.md.tmpl new file mode 100644 index 0000000000..da3a2cbe74 --- /dev/null +++ b/templates/resources/enterprise_actions_permissions.md.tmpl @@ -0,0 +1,49 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Creates and manages Actions permissions within a GitHub enterprise +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to create and manage GitHub Actions permissions within your GitHub enterprise. You must have admin access to an enterprise to use this resource. + +## Example Usage + +{{tffile "examples/resources/enterprise_actions_permissions/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `enterprise_slug` - (Required) The slug of the enterprise. +- `allowed_actions` - (Optional) The permissions policy that controls the actions that are allowed to run. Can be one of: `all`, `local_only`, or `selected`. +- `enabled_organizations` - (Required) The policy that controls the organizations in the enterprise that are allowed to run GitHub Actions. Can be one of: `all`, `none`, or `selected`. +- `allowed_actions_config` - (Optional) Sets the actions that are allowed in an enterprise. Only available when `allowed_actions` = `selected`. See [Allowed Actions Config](#allowed-actions-config) below for details. +- `enabled_organizations_config` - (Optional) Sets the list of selected organizations that are enabled for GitHub Actions in an enterprise. Only available when `enabled_organizations` = `selected`. See [Enabled Organizations Config](#enabled-organizations-config) below for details. + +### Allowed Actions Config + +The `allowed_actions_config` block supports the following: + +- `github_owned_allowed` - (Required) Whether GitHub-owned actions are allowed in the organization. +- `patterns_allowed` - (Optional) Specifies a list of string-matching patterns to allow specific action(s). Wildcards, tags, and SHAs are allowed. For example, `monalisa/octocat@*`, `monalisa/octocat@v2`, `monalisa/*`. +- `verified_allowed` - (Optional) Whether actions in GitHub Marketplace from verified creators are allowed. Set to `true` to allow all GitHub Marketplace actions by verified creators. + +### Enabled Organizations Config + +The `enabled_organizations_config` block supports the following: + +- `organization_ids` - (Required) List of organization IDs to enable for GitHub Actions. + +## Import + +This resource can be imported using the name of the GitHub enterprise: + +```sh +$ terraform import github_enterprise_actions_permissions.test github_enterprise_name +``` diff --git a/templates/resources/enterprise_actions_runner_group.md.tmpl b/templates/resources/enterprise_actions_runner_group.md.tmpl new file mode 100644 index 0000000000..2d89137ceb --- /dev/null +++ b/templates/resources/enterprise_actions_runner_group.md.tmpl @@ -0,0 +1,47 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Creates and manages an Actions Runner Group within a GitHub enterprise. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to create and manage GitHub Actions runner groups within your GitHub enterprise. You must have admin access to an enterprise to use this resource. + +## Example Usage + +{{tffile "examples/resources/enterprise_actions_runner_group/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `enterprise_slug` - (Required) The slug of the enterprise. +- `name` - (Required) Name of the runner group +- `visibility` - (Required) Visibility of a runner group to enterprise organizations. Whether the runner group can include `all` or `selected` +- `selected_organization_ids` - (Optional) IDs of the organizations which should be added to the runner group +- `allows_public_repositories` - (Optional) Whether public repositories can be added to the runner group. Defaults to false. +- `restricted_to_workflows` - (Optional) If true, the runner group will be restricted to running only the workflows specified in the selected_workflows array. Defaults to false. +- `selected_workflows` - (Optional) List of workflows the runner group should be allowed to run. This setting will be ignored unless restricted_to_workflows is set to true. + +## Attributes Reference + +The following additional attributes are exported: + +- `id` - The ID of the runner group +- `default` - Whether this is the default runner group +- `etag` - An etag representing the runner group object +- `runners_url` - The GitHub API URL for the runner group's runners +- `selected_organizations_url` - The GitHub API URL for the runner group's selected organizations + +## Import + +This resource can be imported using the enterprise slug and the ID of the runner group: + +```sh +$ terraform import github_enterprise_actions_runner_group.test enterprise-slug/42 +``` diff --git a/templates/resources/enterprise_actions_workflow_permissions.md.tmpl b/templates/resources/enterprise_actions_workflow_permissions.md.tmpl new file mode 100644 index 0000000000..4c5cda6054 --- /dev/null +++ b/templates/resources/enterprise_actions_workflow_permissions.md.tmpl @@ -0,0 +1,52 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Manages GitHub Actions workflow permissions for a GitHub Enterprise. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to manage GitHub Actions workflow permissions for a GitHub Enterprise account. This controls the default permissions granted to the GITHUB_TOKEN when running workflows and whether GitHub Actions can approve pull request reviews. + +You must have enterprise admin access to use this resource. + +## Example Usage + +{{tffile "examples/resources/enterprise_actions_workflow_permissions/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `enterprise_slug` - (Required) The slug of the enterprise. + +- `default_workflow_permissions` - (Optional) The default workflow permissions granted to the GITHUB_TOKEN when running workflows. Can be `read` or `write`. Defaults to `read`. + +- `can_approve_pull_request_reviews` - (Optional) Whether GitHub Actions can approve pull request reviews. Defaults to `false`. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +- `id` - The enterprise slug. + +## Import + +Enterprise Actions workflow permissions can be imported using the enterprise slug: + +```sh +terraform import github_enterprise_actions_workflow_permissions.example my-enterprise +``` + +## Notes + +~> **Note:** This resource requires a GitHub Enterprise account and enterprise admin permissions. + +When this resource is destroyed, the workflow permissions will be reset to safe defaults: + +- `default_workflow_permissions` = `read` +- `can_approve_pull_request_reviews` = `false` diff --git a/templates/resources/enterprise_organization.md.tmpl b/templates/resources/enterprise_organization.md.tmpl new file mode 100644 index 0000000000..8e265d5ef9 --- /dev/null +++ b/templates/resources/enterprise_organization.md.tmpl @@ -0,0 +1,52 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Create and manages a GitHub enterprise organization. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to create and manage a GitHub enterprise organization. + +## Example Usage + +``` +resource "github_enterprise_organization" "org" { + enterprise_id = data.github_enterprise.enterprise.id + name = "some-awesome-org" + display_name = "Some Awesome Org" + description = "Organization created with terraform" + billing_email = "jon@winteriscoming.com" + admin_logins = [ + "jon-snow" + ] +} +``` + +## Argument Reference + +- `enterprise_id` - (Required) The ID of the enterprise. +- `name` - (Required) The name of the organization. +- `description` - (Optional) The description of the organization. +- `display_name` - (Optional) The display name of the organization. +- `billing_email` - (Required) The billing email address. +- `admin_logins` - (Required) List of organization owner usernames. + +## Attributes Reference + +The following additional attributes are exported: + +- `id` - The node ID of the organization for use with the v4 API. +- `database_id` - The ID of the organization. + +## Import + +GitHub Enterprise Organization can be imported using the `slug` of the enterprise, combined with the `orgname` of the organization, separated by a `/` character. + +```sh +$ terraform import github_enterprise_organization.org enterp/some-awesome-org +``` diff --git a/templates/resources/enterprise_security_analysis_settings.md.tmpl b/templates/resources/enterprise_security_analysis_settings.md.tmpl new file mode 100644 index 0000000000..028577519b --- /dev/null +++ b/templates/resources/enterprise_security_analysis_settings.md.tmpl @@ -0,0 +1,68 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Manages GitHub Enterprise security analysis settings. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to manage code security and analysis settings for a GitHub Enterprise account. This controls Advanced Security, Secret Scanning, and related security features that are automatically enabled for new repositories in the enterprise. + +You must have enterprise admin access to use this resource. + +## Example Usage + +{{tffile "examples/resources/enterprise_security_analysis_settings/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `enterprise_slug` - (Required) The slug of the enterprise. + +- `advanced_security_enabled_for_new_repositories` - (Optional) Whether GitHub Advanced Security is automatically enabled for new repositories. Defaults to `false`. Requires Advanced Security license. + +- `secret_scanning_enabled_for_new_repositories` - (Optional) Whether secret scanning is automatically enabled for new repositories. Defaults to `false`. + +- `secret_scanning_push_protection_enabled_for_new_repositories` - (Optional) Whether secret scanning push protection is automatically enabled for new repositories. Defaults to `false`. + +- `secret_scanning_push_protection_custom_link` - (Optional) Custom URL for secret scanning push protection bypass instructions. + +- `secret_scanning_validity_checks_enabled` - (Optional) Whether secret scanning validity checks are enabled. Defaults to `false`. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +- `id` - The enterprise slug. + +## Import + +Enterprise security analysis settings can be imported using the enterprise slug: + +```sh +terraform import github_enterprise_security_analysis_settings.example my-enterprise +``` + +## Notes + +~> **Note:** This resource requires a GitHub Enterprise account and enterprise admin permissions. + +~> **Note:** Advanced Security features require a GitHub Advanced Security license. + +When this resource is destroyed, all security analysis settings will be reset to disabled defaults for security reasons. + +## Dependencies + +This resource manages the following security features: + +- **Advanced Security**: Code scanning, secret scanning, and dependency review +- **Secret Scanning**: Automatic detection of secrets in code +- **Push Protection**: Prevents secrets from being committed to repositories +- **Validity Checks**: Verifies that detected secrets are actually valid + +These settings only apply to **new repositories** created after the settings are enabled. Existing repositories are not affected and must be configured individually. diff --git a/templates/resources/issue.md.tmpl b/templates/resources/issue.md.tmpl new file mode 100644 index 0000000000..2fe73e5eea --- /dev/null +++ b/templates/resources/issue.md.tmpl @@ -0,0 +1,53 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Provides a GitHub issue resource. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Provides a GitHub issue resource. + +This resource allows you to create and manage issue within your GitHub repository. + +## Example Usage + +{{tffile "examples/resources/issue/example_1.tf"}} + +## Example Usage with milestone and project assignment + +{{tffile "examples/resources/issue/example_2.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The GitHub repository name + +- `title` - (Required) Title of the issue + +- `body` - (Optional) Body of the issue + +- `labels` - (Optional) List of labels to attach to the issue + +- `assignees` - (Optional) List of Logins to assign the to the issue + +- `milestone_number` - (Optional) Milestone number to assign to the issue + +## Attributes Reference + +- `number` - (Computed) - The issue number + +- `issue_id` - (Computed) - The issue id + +## Import + +GitHub Issues can be imported using an ID made up of `repository:number`, e.g. + +```sh +$ terraform import github_issue.issue_15 myrepo:15 +``` diff --git a/templates/resources/issue_label.md.tmpl b/templates/resources/issue_label.md.tmpl new file mode 100644 index 0000000000..375a95d29b --- /dev/null +++ b/templates/resources/issue_label.md.tmpl @@ -0,0 +1,47 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Provides a GitHub issue label resource. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Provides a GitHub issue label resource. + +This resource allows you to create and manage issue labels within your GitHub organization. + +Issue labels are keyed off of their "name", so pre-existing issue labels result in a 422 HTTP error if they exist outside of Terraform. Normally this would not be an issue, except new repositories are created with a "default" set of labels, and those labels easily conflict with custom ones. + +This resource will first check if the label exists, and then issue an update, otherwise it will create. + +~> **Note:** When a repository is archived, Terraform will skip deletion of issue labels to avoid API errors, as archived repositories are read-only. The labels will be removed from Terraform state without attempting to delete them from GitHub. + +## Example Usage + +{{tffile "examples/resources/issue_label/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The GitHub repository + +- `name` - (Required) The name of the label. + +- `color` - (Required) A 6 character hex code, **without the leading #**, identifying the color of the label. + +- `description` - (Optional) A short description of the label. + +- `url` - (Computed) The URL to the issue label + +## Import + +GitHub Issue Labels can be imported using an ID made up of `repository:name`, e.g. + +```sh +$ terraform import github_issue_label.panic_label terraform:panic +``` diff --git a/templates/resources/issue_labels.md.tmpl b/templates/resources/issue_labels.md.tmpl new file mode 100644 index 0000000000..0e011f271f --- /dev/null +++ b/templates/resources/issue_labels.md.tmpl @@ -0,0 +1,49 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Provides GitHub issue labels resource. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Provides GitHub issue labels resource. + +This resource allows you to create and manage issue labels within your GitHub organization. + +~> Note: github_issue_labels cannot be used in conjunction with github_issue_label or they will fight over what your policy should be. + +This resource is authoritative. For adding a label to a repo in a non-authoritative manner, use github_issue_label instead. + +If you change the case of a label's name, its' color, or description, this resource will edit the existing label to match the new values. However, if you change the name of a label, this resource will create a new label with the new name and delete the old label. Beware that this will remove the label from any issues it was previously attached to. + +~> **Note:** When a repository is archived, Terraform will skip deletion of issue labels to avoid API errors, as archived repositories are read-only. The labels will be removed from Terraform state without attempting to delete them from GitHub. + +## Example Usage + +{{tffile "examples/resources/issue_labels/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The GitHub repository + +- `name` - (Required) The name of the label. + +- `color` - (Required) A 6 character hex code, **without the leading #**, identifying the color of the label. + +- `description` - (Optional) A short description of the label. + +- `url` - (Computed) The URL to the issue label + +## Import + +GitHub Issue Labels can be imported using the repository `name`, e.g. + +```sh +$ terraform import github_issue_labels.test_repo test_repo +``` diff --git a/templates/resources/membership.md.tmpl b/templates/resources/membership.md.tmpl new file mode 100644 index 0000000000..373c19717e --- /dev/null +++ b/templates/resources/membership.md.tmpl @@ -0,0 +1,35 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Provides a GitHub membership resource. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Provides a GitHub membership resource. + +This resource allows you to add/remove users from your organization. When applied, an invitation will be sent to the user to become part of the organization. When destroyed, either the invitation will be cancelled or the user will be removed. + +## Example Usage + +{{tffile "examples/resources/membership/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `username` - (Required) The user to add to the organization. +- `role` - (Optional) The role of the user within the organization. Must be one of `member` or `admin`. Defaults to `member`. `admin` role represents the `owner` role available via GitHub UI. +- `downgrade_on_destroy` - (Optional) Defaults to `false`. If set to true, when this resource is destroyed, the member will not be removed from the organization. Instead, the member's role will be downgraded to 'member'. + +## Import + +GitHub Membership can be imported using an ID made up of `organization:username`, e.g. + +```sh +$ terraform import github_membership.member hashicorp:someuser +``` diff --git a/templates/resources/organization_block.md.tmpl b/templates/resources/organization_block.md.tmpl new file mode 100644 index 0000000000..50c3b23975 --- /dev/null +++ b/templates/resources/organization_block.md.tmpl @@ -0,0 +1,31 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Creates and manages blocks for GitHub organizations +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to create and manage blocks for GitHub organizations. + +## Example Usage + +{{tffile "examples/resources/organization_block/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `username` - (Required) The name of the user to block. + +## Import + +GitHub organization block can be imported using a username, e.g. + +```sh +$ terraform import github_github_organization_block.example someuser +``` diff --git a/templates/resources/organization_custom_properties.md.tmpl b/templates/resources/organization_custom_properties.md.tmpl new file mode 100644 index 0000000000..3cb4f67aa8 --- /dev/null +++ b/templates/resources/organization_custom_properties.md.tmpl @@ -0,0 +1,65 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Creates and manages custom properties for a GitHub organization +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to create and manage custom properties for a GitHub organization. + +Custom properties enable you to add metadata to repositories within your organization. You can use custom properties to add context about repositories, such as who owns them, when they expire, or compliance requirements. + +## Example Usage + +{{tffile "examples/resources/organization_custom_properties/example_1.tf"}} + +## Example Usage - Allow Repository Actors to Edit + +This example shows how to allow repository administrators to edit the property values: + +{{tffile "examples/resources/organization_custom_properties/example_2.tf"}} + +## Example Usage - Text Property + +{{tffile "examples/resources/organization_custom_properties/example_3.tf"}} + +## Example Usage - Boolean Property + +{{tffile "examples/resources/organization_custom_properties/example_4.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `property_name` - (Required) The name of the custom property. + +- `value_type` - (Optional) The type of the custom property. Can be one of `string`, `single_select`, `multi_select`, or `true_false`. Defaults to `string`. + +- `required` - (Optional) Whether the custom property is required. Defaults to `false`. + +- `description` - (Optional) The description of the custom property. + +- `default_value` - (Optional) The default value of the custom property. + +- `allowed_values` - (Optional) List of allowed values for the custom property. Only applicable when `value_type` is `single_select` or `multi_select`. + +- `values_editable_by` - (Optional) Who can edit the values of the custom property. Can be one of `org_actors` or `org_and_repo_actors`. When set to `org_actors` (the default), only organization owners can edit the property values on repositories. When set to `org_and_repo_actors`, both organization owners and repository administrators with the custom properties permission can edit the values. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +- `property_name` - The name of the custom property. + +## Import + +Organization custom properties can be imported using the property name: + +```sh +terraform import github_organization_custom_properties.environment environment +``` diff --git a/templates/resources/organization_custom_role.md.tmpl b/templates/resources/organization_custom_role.md.tmpl new file mode 100644 index 0000000000..bdf753537d --- /dev/null +++ b/templates/resources/organization_custom_role.md.tmpl @@ -0,0 +1,44 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Creates and manages a custom role in a GitHub Organization for use in repositories. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +~> **Note:** This resource is deprecated, please use the `github_organization_repository_role` resource instead. + +This resource allows you to create and manage custom roles in a GitHub Organization for use in repositories. + +~> Note: Custom roles are currently only available in GitHub Enterprise Cloud. + +## Example Usage + +{{tffile "examples/resources/organization_custom_role/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `name` - (Required) The name of the custom role. +- `description` - (Optional) The description for the custom role. +- `base_role` - (Required) The system role from which the role inherits permissions. Can be one of: `read`, `triage`, `write`, or `maintain`. +- `permissions` - (Required) A list of additional permissions included in this role. Must have a minimum of 1 additional permission. The list of available permissions can be found using the [list repository fine-grained permissions for an organization](https://docs.github.com/en/enterprise-cloud@latest/rest/orgs/custom-roles?apiVersion=2022-11-28#list-repository-fine-grained-permissions-for-an-organization) API. + +## Attributes Reference + +The following additional attributes are exported: + +- `id` - The ID of the custom role. + +## Import + +Custom roles can be imported using the `id` of the role. The `id` of the custom role can be found using the [list custom roles in an organization](https://docs.github.com/en/enterprise-cloud@latest/rest/orgs/custom-roles#list-custom-repository-roles-in-an-organization) API. + +```sh +$ terraform import github_organization_custom_role.example 1234 +``` diff --git a/templates/resources/organization_repository_role.md.tmpl b/templates/resources/organization_repository_role.md.tmpl new file mode 100644 index 0000000000..f835905d15 --- /dev/null +++ b/templates/resources/organization_repository_role.md.tmpl @@ -0,0 +1,43 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Manage a custom organization repository role. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Manage a custom organization repository role. + +~> **Note**: Custom organization repository roles are currently only available in GitHub Enterprise Cloud. + +## Example Usage + +{{tffile "examples/resources/organization_repository_role/example_1.tf"}} + +## Schema + +### Required + +- `name` (String) The name of the organization repository role. +- `base_role` (String) The system role from which this role inherits permissions. +- `permissions` (Set of String, Min: 1) The permissions included in this role. + +### Optional + +- `description` (String) The description of the organization repository role. + +### Read-Only + +- `role_id` (Number) The ID of the organization repository role. + +## Import + +A custom organization repository role can be imported using its ID. + +```shell +terraform import github_organization_repository_role.example 1234 +``` diff --git a/templates/resources/organization_role.md.tmpl b/templates/resources/organization_role.md.tmpl new file mode 100644 index 0000000000..469d9431f1 --- /dev/null +++ b/templates/resources/organization_role.md.tmpl @@ -0,0 +1,43 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Manage a custom organization role. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Manage a custom organization role. + +~> **Note**: Custom organization roles are currently only available in GitHub Enterprise Cloud. + +## Example Usage + +{{tffile "examples/resources/organization_role/example_1.tf"}} + +## Schema + +### Required + +- `name` (String) The name of the organization role. +- `permissions` (Set of String, Min: 1) The permissions included in this role. + +### Optional + +- `description` (String) The description of the organization role. +- `base_role` (String) The system role from which this role inherits permissions. + +### Read-Only + +- `role_id` (Number) The ID of the organization role. + +## Import + +A custom organization role can be imported using its ID. + +```shell +terraform import github_organization_role.example 1234 +``` diff --git a/templates/resources/organization_role_team.md.tmpl b/templates/resources/organization_role_team.md.tmpl new file mode 100644 index 0000000000..b8ebd892a4 --- /dev/null +++ b/templates/resources/organization_role_team.md.tmpl @@ -0,0 +1,32 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Manage an association between an organization role and a team. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Manage an association between an organization role and a team. + +## Example Usage + +{{tffile "examples/resources/organization_role_team/example_1.tf"}} + +## Schema + +### Required + +- `role_id` (Number) The ID of the organization role. +- `team_slug` (String) The slug of the team name. + +## Import + +An organization role team association can be imported using the role ID and the team slug separated by a `:`. + +```shell +terraform import github_organization_role_team.example "1234:example-team" +``` diff --git a/templates/resources/organization_role_team_assignment.md.tmpl b/templates/resources/organization_role_team_assignment.md.tmpl new file mode 100644 index 0000000000..f128a13e29 --- /dev/null +++ b/templates/resources/organization_role_team_assignment.md.tmpl @@ -0,0 +1,38 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Manages the associations between teams and organization roles. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +~> **Note:** This resource is deprecated, please use the `github_organization_role_team` resource instead. + +This resource manages relationships between teams and organization roles in your GitHub organization. This works on predefined roles, and custom roles, where the latter is an Enterprise feature. + +Creating this resource assigns the role to a team. + +The organization role and team must both belong to the same organization on GitHub. + +## Example Usage + +{{tffile "examples/resources/organization_role_team_assignment/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `team_slug` - (Required) The GitHub team slug +- `role_id` - (Required) The GitHub organization role id + +## Import + +GitHub Team Organization Role Assignment can be imported using an ID made up of `team_slug:role_id` + +```sh +$ terraform import github_organization_role_team_assignment.role_assignment test-team:8132 +``` diff --git a/templates/resources/organization_role_user.md.tmpl b/templates/resources/organization_role_user.md.tmpl new file mode 100644 index 0000000000..bb476a1d04 --- /dev/null +++ b/templates/resources/organization_role_user.md.tmpl @@ -0,0 +1,32 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Manage an association between an organization role and a user. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Manage an association between an organization role and a user. + +## Example Usage + +{{tffile "examples/resources/organization_role_user/example_1.tf"}} + +## Schema + +### Required + +- `role_id` (Number) The ID of the organization role. +- `login` (String) The login for the GitHub user account. + +## Import + +An organization role user association can be imported using the role ID and the user login separated by a `:`. + +```shell +terraform import github_organization_role_team.example "1234:example-user" +``` diff --git a/templates/resources/organization_ruleset.md.tmpl b/templates/resources/organization_ruleset.md.tmpl new file mode 100644 index 0000000000..4e159d536e --- /dev/null +++ b/templates/resources/organization_ruleset.md.tmpl @@ -0,0 +1,25 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}}" +description: |- +{{ .Description | plainmarkdown | trimspace | prefixlines " " }} +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +{{ .Description | trimspace }} + +## Example Usage + +{{tffile "examples/resources/organization_ruleset/example_1.tf"}} + +{{ .SchemaMarkdown | trimspace }} + +## Import + +GitHub Organization Rulesets can be imported using the GitHub ruleset ID e.g. + +`$ terraform import github_organization_ruleset.example 12345` diff --git a/templates/resources/organization_security_manager.md.tmpl b/templates/resources/organization_security_manager.md.tmpl new file mode 100644 index 0000000000..d2f2397cde --- /dev/null +++ b/templates/resources/organization_security_manager.md.tmpl @@ -0,0 +1,31 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Manages the Security manager teams for a GitHub Organization. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +~> **Note:** This resource is deprecated, please use the `github_organization_role_team` resource instead. + +## Example Usage + +{{tffile "examples/resources/organization_security_manager/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `team_slug` - (Required) The slug of the team to manage. + +## Import + +GitHub Security Manager Teams can be imported using the GitHub team ID e.g. + +```sh +$ terraform import github_organization_security_manager.core 1234567 +``` diff --git a/templates/resources/organization_settings.md.tmpl b/templates/resources/organization_settings.md.tmpl new file mode 100644 index 0000000000..c9a4d03191 --- /dev/null +++ b/templates/resources/organization_settings.md.tmpl @@ -0,0 +1,62 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Creates and manages settings for a GitHub Organization. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to create and manage settings for a GitHub Organization. + +## Example Usage + +{{tffile "examples/resources/organization_settings/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `billing_email` - (Required) The billing email address for the organization. +- `company` - (Optional) The company name for the organization. +- `blog` - (Optional) The blog URL for the organization. +- `email` - (Optional) The email address for the organization. +- `twitter_username` - (Optional) The Twitter username for the organization. +- `location` - (Optional) The location for the organization. +- `name` - (Optional) The name for the organization. +- `description` - (Optional) The description for the organization. +- `has_organization_projects` - (Optional) Whether or not organization projects are enabled for the organization. +- `has_repository_projects` - (Optional) Whether or not repository projects are enabled for the organization. +- `default_repository_permission` - (Optional) The default permission for organization members to create new repositories. Can be one of `read`, `write`, `admin`, or `none`. Defaults to `read`. +- `members_can_create_repositories` - (Optional) Whether or not organization members can create new repositories. Defaults to `true`. +- `members_can_create_public_repositories` - (Optional) Whether or not organization members can create new public repositories. Defaults to `true`. +- `members_can_create_private_repositories` - (Optional) Whether or not organization members can create new private repositories. Defaults to `true`. +- `members_can_create_internal_repositories` - (Optional) Whether or not organization members can create new internal repositories. For Enterprise Organizations only. +- `members_can_create_pages` - (Optional) Whether or not organization members can create new pages. Defaults to `true`. +- `members_can_create_public_pages` - (Optional) Whether or not organization members can create new public pages. Defaults to `true`. +- `members_can_create_private_pages` - (Optional) Whether or not organization members can create new private pages. Defaults to `true`. +- `members_can_fork_private_repositories` - (Optional) Whether or not organization members can fork private repositories. Defaults to `false`. +- `web_commit_signoff_required` - (Optional) Whether or not commit signatures are required for commits to the organization. Defaults to `false`. +- `advanced_security_enabled_for_new_repositories` - (Optional) Whether or not advanced security is enabled for new repositories. Defaults to `false`. +- `dependabot_alerts_enabled_for_new_repositories` - (Optional) Whether or not dependabot alerts are enabled for new repositories. Defaults to `false`. +- `dependabot_security_updates_enabled_for_new_repositories` - (Optional) Whether or not dependabot security updates are enabled for new repositories. Defaults to `false`. +- `dependency_graph_enabled_for_new_repositories` - (Optional) Whether or not dependency graph is enabled for new repositories. Defaults to `false`. +- `secret_scanning_enabled_for_new_repositories` - (Optional) Whether or not secret scanning is enabled for new repositories. Defaults to `false`. +- `secret_scanning_push_protection_enabled_for_new_repositories` - (Optional) Whether or not secret scanning push protection is enabled for new repositories. Defaults to `false`. + +## Attributes Reference + +The following additional attributes are exported: + +- `id` - The ID of the organization settings. + +## Import + +Organization settings can be imported using the `id` of the organization. The `id` of the organization can be found using the [get an organization](https://docs.github.com/en/rest/orgs/orgs#get-an-organization) API. + +```sh +$ terraform import github_organization_settings.test 123456789 +``` diff --git a/templates/resources/organization_webhook.md.tmpl b/templates/resources/organization_webhook.md.tmpl new file mode 100644 index 0000000000..c8b8a900dd --- /dev/null +++ b/templates/resources/organization_webhook.md.tmpl @@ -0,0 +1,45 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Creates and manages webhooks for GitHub organizations +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to create and manage webhooks for GitHub organization. + +## Example Usage + +{{tffile "examples/resources/organization_webhook/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `events` - (Required) A list of events which should trigger the webhook. See a list of [available events](https://developer.github.com/v3/activity/events/types/) + +- `configuration` - (Required) key/value pair of configuration for this webhook. Available keys are `url`, `content_type`, `secret` and `insecure_ssl`. + +- `active` - (Optional) Indicate of the webhook should receive events. Defaults to `true`. + +- `name` - (Optional) The type of the webhook. `web` is the default and the only option. + +## Attributes Reference + +The following additional attributes are exported: + +- `url` - URL of the webhook + +## Import + +Organization webhooks can be imported using the `id` of the webhook. The `id` of the webhook can be found in the URL of the webhook. For example, `"https://github.com/organizations/foo-org/settings/hooks/123456789"`. + +```sh +$ terraform import github_organization_webhook.terraform 123456789 +``` + +If secret is populated in the webhook's configuration, the value will be imported as "********". diff --git a/templates/resources/release.md.tmpl b/templates/resources/release.md.tmpl new file mode 100644 index 0000000000..89d5fcf954 --- /dev/null +++ b/templates/resources/release.md.tmpl @@ -0,0 +1,75 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Creates and manages releases within a single GitHub repository +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to create and manage a release in a specific GitHub repository. + +## Example Usage + +{{tffile "examples/resources/release/example_1.tf"}} + +## Example Usage on Non-Default Branch + +{{tffile "examples/resources/release/example_2.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The name of the repository. + +- `tag_name` - (Required) The name of the tag. + +- `target_commitish` - (Optional) The branch name or commit SHA the tag is created from. Defaults to the default branch of the repository. + +- `name` - (Optional) The name of the release. + +- `body` - (Optional) Text describing the contents of the tag. + +- `draft` - (Optional) Set to `false` to create a published release. + +- `prerelease` - (Optional) Set to `false` to identify the release as a full release. + +- `generate_release_notes` - (Optional) Set to `true` to automatically generate the name and body for this release. If `name` is specified, the specified `name` will be used; otherwise, a name will be automatically generated. If `body` is specified, the `body` will be pre-pended to the automatically generated notes. + +- `discussion_category_name` - (Optional) If specified, a discussion of the specified category is created and linked to the release. The value must be a category that already exists in the repository. For more information, see [Managing categories for discussions in your repository](https://docs.github.com/discussions/managing-discussions-for-your-community/managing-categories-for-discussions-in-your-repository). + +## Attributes Reference + +The following additional attributes are exported: + +- `release_id` - The ID of the release. + +- `created_at` - This is the date of the commit used for the release, and not the date when the release was drafted or published. + +- `published_at` - This is the date when the release was published. This will be empty if the release is a draft. + +- `html_url` - URL of the release in GitHub. + +- `url` - URL that can be provided to API calls that reference this release. + +- `assets_url` - URL that can be provided to API calls displaying the attached assets to this release. + +- `upload_url` - URL that can be provided to API calls to upload assets. + +- `zipball_url` - URL that can be provided to API calls to fetch the release ZIP archive. + +- `tarball_url` - URL that can be provided to API calls to fetch the release TAR archive. + +- `node_id` - GraphQL global node id for use with v4 API + +## Import + +This resource can be imported using the `name` of the repository, combined with the `id` of the release, and a `:` character for separating components, e.g. + +```sh +$ terraform import github_release.example repo:12345678 +``` diff --git a/templates/resources/repository.md.tmpl b/templates/resources/repository.md.tmpl new file mode 100644 index 0000000000..9fd7d7933c --- /dev/null +++ b/templates/resources/repository.md.tmpl @@ -0,0 +1,210 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}}" +description: |- +{{ .Description | plainmarkdown | trimspace | prefixlines " " }} +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +{{ .Description | trimspace }} + +~> **Note** When used with GitHub App authentication, even GET requests must have the `contents:write` permission. Without it, the following arguments will be ignored, leading to unexpected behavior and confusing diffs: `allow_merge_commit`, `allow_squash_merge`, `allow_rebase_merge`, `merge_commit_title`, `merge_commit_message`, `squash_merge_commit_title` and `squash_merge_commit_message`. + +## Example Usage + +{{tffile "examples/resources/repository/example_1.tf"}} + +## Example Usage with GitHub Pages Enabled + +{{tffile "examples/resources/repository/example_2.tf"}} + +## Example Usage with Repository Forking + +{{tffile "examples/resources/repository/example_3.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `name` - (Required) The name of the repository. + +- `description` - (Optional) A description of the repository. + +- `homepage_url` - (Optional) URL of a page describing the project. + +- `fork` - (Optional) Set to `true` to create a fork of an existing repository. When set to `true`, both `source_owner` and `source_repo` must also be specified. + +- `source_owner` - (Optional) The GitHub username or organization that owns the repository being forked. Required when `fork` is `true`. + +- `source_repo` - (Optional) The name of the repository to fork. Required when `fork` is `true`. + +- `private` - (Optional) Set to `true` to create a private repository. Repositories are created as public (e.g. open source) by default. + +- `visibility` - (Optional) Can be `public` or `private`. If your organization is associated with an enterprise account using GitHub Enterprise Cloud or GitHub Enterprise Server 2.20+, visibility can also be `internal`. The `visibility` parameter overrides the `private` parameter. + +- `has_issues` - (Optional) Set to `true` to enable the GitHub Issues features on the repository. + +- `has_discussions` - (Optional) Set to `true` to enable GitHub Discussions on the repository. Defaults to `false`. + +- `has_projects` - (Optional) Set to `true` to enable the GitHub Projects features on the repository. Per the GitHub [documentation](https://developer.github.com/v3/repos/#create) when in an organization that has disabled repository projects it will default to `false` and will otherwise default to `true`. If you specify `true` when it has been disabled it will return an error. + +- `has_wiki` - (Optional) Set to `true` to enable the GitHub Wiki features on the repository. + +- `is_template` - (Optional) Set to `true` to tell GitHub that this is a template repository. + +- `allow_merge_commit` - (Optional) Set to `false` to disable merge commits on the repository. + +- `allow_squash_merge` - (Optional) Set to `false` to disable squash merges on the repository. + +- `allow_rebase_merge` - (Optional) Set to `false` to disable rebase merges on the repository. + +- `allow_auto_merge` - (Optional) Set to `true` to allow auto-merging pull requests on the repository. + +- `squash_merge_commit_title` - (Optional) Can be `PR_TITLE` or `COMMIT_OR_PR_TITLE` for a default squash merge commit title. Applicable only if `allow_squash_merge` is `true`. + +- `squash_merge_commit_message` - (Optional) Can be `PR_BODY`, `COMMIT_MESSAGES`, or `BLANK` for a default squash merge commit message. Applicable only if `allow_squash_merge` is `true`. + +- `merge_commit_title` - Can be `PR_TITLE` or `MERGE_MESSAGE` for a default merge commit title. Applicable only if `allow_merge_commit` is `true`. + +- `merge_commit_message` - Can be `PR_BODY`, `PR_TITLE`, or `BLANK` for a default merge commit message. Applicable only if `allow_merge_commit` is `true`. + +- `delete_branch_on_merge` - (Optional) Automatically delete head branch after a pull request is merged. Defaults to `false`. + +- `web_commit_signoff_required` - (Optional) Require contributors to sign off on web-based commits. See more in [GitHub Documentation](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/managing-repository-settings/managing-the-commit-signoff-policy-for-your-repository). Defaults to `false`. + +- `has_downloads` - (Optional) Set to `true` to enable the (deprecated) downloads features on the repository. + +- `auto_init` - (Optional) Set to `true` to produce an initial commit in the repository. + +- `gitignore_template` - (Optional) Use the [name of the template](https://github.com/github/gitignore) without the extension. For example, "Haskell". + +- `license_template` - (Optional) Use the [name of the template](https://github.com/github/choosealicense.com/tree/gh-pages/_licenses) without the extension. For example, "mit" or "mpl-2.0". + +- `default_branch` - (Optional) (Deprecated: Use [`github_branch_default`](../branch_default) resource instead) The name of the default branch of the repository. **NOTE:** This can only be set after a repository has already been created, and after a correct reference has been created for the target branch inside the repository. This means a user will have to omit this parameter from the initial repository creation and create the target branch inside of the repository prior to setting this attribute. + +- `archived` - (Optional) Specifies if the repository should be archived. Defaults to `false`. **NOTE** Currently, the API does not support unarchiving. + +- `archive_on_destroy` - (Optional) Set to `true` to archive the repository instead of deleting on destroy. + +- `pages` - (Optional) The repository's GitHub Pages configuration. See [GitHub Pages Configuration](#github-pages-configuration) below for details. + +- `security_and_analysis` - (Optional) The repository's [security and analysis](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-security-and-analysis-settings-for-your-repository) configuration. See [Security and Analysis Configuration](#security-and-analysis-configuration) below for details. + +- `topics` - (Optional) The list of topics of the repository. + +~> Note: This attribute is not compatible with the `github_repository_topics` resource. Use one of them. `github_repository_topics` is only meant to be used if the repository itself is not handled via terraform, for example if it's only read as a datasource (see [issue #1845](https://github.com/integrations/terraform-provider-github/issues/1845)). + +- `template` - (Optional) Use a template repository to create this resource. See [Template Repositories](#template-repositories) below for details. + +- `vulnerability_alerts` (Optional) - Set to `true` to enable security alerts for vulnerable dependencies. Enabling requires alerts to be enabled on the owner level. (Note for importing: GitHub enables the alerts on public repos but disables them on private repos by default.) See [GitHub Documentation](https://help.github.com/en/github/managing-security-vulnerabilities/about-security-alerts-for-vulnerable-dependencies) for details. Note that vulnerability alerts have not been successfully tested on any GitHub Enterprise instance and may be unavailable in those settings. + +- `ignore_vulnerability_alerts_during_read` (Optional) - Set to `true` to not call the vulnerability alerts endpoint so the resource can also be used without admin permissions during read. + +- `allow_update_branch` (Optional) - Set to `true` to always suggest updating pull request branches. + +### GitHub Pages Configuration + +The `pages` block supports the following: + +- `source` - (Optional) The source branch and directory for the rendered Pages site. See [GitHub Pages Source](#github-pages-source) below for details. + +- `build_type` - (Optional) The type of GitHub Pages site to build. Can be `legacy` or `workflow`. If you use `legacy` as build type you need to set the option `source`. + +- `cname` - (Optional) The custom domain for the repository. This can only be set after the repository has been created. + +#### GitHub Pages Source + +The `source` block supports the following: + +- `branch` - (Required) The repository branch used to publish the site's source files. (i.e. `main` or `gh-pages`. + +- `path` - (Optional) The repository directory from which the site publishes (Default: `/`). + +### Security and Analysis Configuration + +The `security_and_analysis` block supports the following: + +- `advanced_security` - (Optional) The advanced security configuration for the repository. See [Advanced Security Configuration](#advanced-security-configuration) below for details. If a repository's visibility is `public`, advanced security is always enabled and cannot be changed, so this setting cannot be supplied. + +- `code_security` - (Optional) The code security configuration for the repository. See [Code Security](#code-security-configuration) below for details. + +- `secret_scanning` - (Optional) The secret scanning configuration for the repository. See [Secret Scanning Configuration](#secret-scanning-configuration) below for details. + +- `secret_scanning_push_protection` - (Optional) The secret scanning push protection configuration for the repository. See [Secret Scanning Push Protection Configuration](#secret-scanning-push-protection-configuration) below for details. + +- `secret_scanning_ai_detection` - (Optional) The secret scanning ai detection configuration for the repository. See [Secret Scanning AI Detection](#secret-scanning-ai-detection) below for details. + +- `secret_scanning_non_provider_patterns` - (Optional) The secret scanning non-provider patterns configuration for this repository. See [Secret Scanning Non-Provider Patterns](#secret-scanning-non-provider-patterns) below for more details. + +#### Advanced Security Configuration + +The `advanced_security` block supports the following: + +- `status` - (Required) Set to `enabled` to enable advanced security features on the repository. Can be `enabled` or `disabled`. + +#### Code Security Configuration + +- `status` - (Required) Set to `enabled` to enable GitHub Code Security on the repository. Can be `enabled` or `disabled`. If set to `enabled`, the repository's visibility must be `public`, `security_and_analysis[0].advanced_security[0].status` must also be set to `enabled`, or your Organization must have split licensing for Advanced security. + +#### Secret Scanning Configuration + +- `status` - (Required) Set to `enabled` to enable secret scanning on the repository. Can be `enabled` or `disabled`. If set to `enabled`, the repository's visibility must be `public`, `security_and_analysis[0].advanced_security[0].status` must also be set to `enabled`, or your Organization must have split licensing for Advanced security. + +#### Secret Scanning Push Protection Configuration + +- `status` - (Required) Set to `enabled` to enable secret scanning push protection on the repository. Can be `enabled` or `disabled`. If set to `enabled`, the repository's visibility must be `public`, `security_and_analysis[0].advanced_security[0].status` must also be set to `enabled`, or your Organization must have split licensing for Advanced security. + +#### Secret Scanning AI Detection + +- `status` - (Required) Set to `enabled` to enable secret scanning AI detection on the repository. Can be `enabled` or `disabled`. If set to `enabled`, the repository's visibility must be `public`, `security_and_analysis[0].advanced_security[0].status` must also be set to `enabled`, or your Organization must have split licensing for Advanced security. + +#### Secret Scanning Non-Provider Patterns + +- `status` - (Required) Set to `enabled` to enable secret scanning non-provider patterns on the repository. Can be `enabled` or `disabled`. If set to `enabled`, the repository's visibility must be `public`, `security_and_analysis[0].advanced_security[0].status` must also be set to `enabled`, or your Organization must have split licensing for Advanced security. + +### Template Repositories + +`template` supports the following arguments: + +- `owner`: The GitHub organization or user the template repository is owned by. +- `repository`: The name of the template repository. +- `include_all_branches`: Whether the new repository should include all the branches from the template repository (defaults to false, which includes only the default branch from the template). + +## Attributes Reference + +The following additional attributes are exported: + +- `full_name` - A string of the form "orgname/reponame". + +- `html_url` - URL to the repository on the web. + +- `ssh_clone_url` - URL that can be provided to `git clone` to clone the repository via SSH. + +- `http_clone_url` - URL that can be provided to `git clone` to clone the repository via HTTPS. + +- `git_clone_url` - URL that can be provided to `git clone` to clone the repository anonymously via the git protocol. + +- `svn_url` - URL that can be provided to `svn checkout` to check out the repository via GitHub's Subversion protocol emulation. + +- `node_id` - GraphQL global node id for use with v4 API + +- `repo_id` - GitHub ID for the repository + +- `primary_language` - The primary language used in the repository. + +- `pages` - The block consisting of the repository's GitHub Pages configuration with the following additional attributes: +- `custom_404` - Whether the rendered GitHub Pages site has a custom 404 page. +- `html_url` - The absolute URL (including scheme) of the rendered GitHub Pages site e.g. `https://username.github.io`. +- `status` - The GitHub Pages site's build status e.g. `building` or `built`. + +## Import + +Repositories can be imported using the `name`, e.g. + +```sh +$ terraform import github_repository.terraform terraform +``` diff --git a/templates/resources/repository_autolink_reference.md.tmpl b/templates/resources/repository_autolink_reference.md.tmpl new file mode 100644 index 0000000000..f93041ee37 --- /dev/null +++ b/templates/resources/repository_autolink_reference.md.tmpl @@ -0,0 +1,53 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Creates and manages autolink references for a single repository +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to create and manage an autolink reference for a single repository. + +## Example Usage + +{{tffile "examples/resources/repository_autolink_reference/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The repository of the autolink reference. + +- `key_prefix` - (Required) This prefix appended by a number will generate a link any time it is found in an issue, pull request, or commit. + +- `target_url_template` - (Required) The template of the target URL used for the links; must be a valid URL and contain `` for the reference number + +- `is_alphanumeric` - (Optional) Whether this autolink reference matches alphanumeric characters. If false, this autolink reference only matches numeric characters. Default is true. + +## Attributes Reference + +The following additional attributes are exported: + +- `etag` - An etag representing the autolink reference object. + +## Import + +Autolink references can be imported using the `name` of the repository, combined with the `id` or `key prefix` of the autolink reference and a `/` character for separating components, e.g. + +### Import by ID + +```sh +terraform import github_repository_autolink_reference.auto my-repo/123 +``` + +See the GitHub documentation for how to [list all autolinks of a repository](https://docs.github.com/en/rest/repos/autolinks#list-all-autolinks-of-a-repository) to learn the autolink ids to use with the import command. + +### Import by key prefix + +```sh +terraform import github_repository_autolink_reference.auto oof/OOF- +``` diff --git a/templates/resources/repository_collaborator.md.tmpl b/templates/resources/repository_collaborator.md.tmpl new file mode 100644 index 0000000000..77d24d1a26 --- /dev/null +++ b/templates/resources/repository_collaborator.md.tmpl @@ -0,0 +1,59 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Provides a GitHub repository collaborator resource. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Provides a GitHub repository collaborator resource. + +~> Note: github_repository_collaborator cannot be used in conjunction with github_repository_collaborators or they will fight over what your policy should be. + +This resource allows you to add/remove collaborators from repositories in your organization or personal account. For organization repositories, collaborators can have explicit (and differing levels of) read, write, or administrator access to specific repositories, without giving the user full organization membership. For personal repositories, collaborators can only be granted write (implicitly includes read) permission. + +When applied, an invitation will be sent to the user to become a collaborator on a repository. When destroyed, either the invitation will be cancelled or the collaborator will be removed from the repository. + +~> **Note on Archived Repositories**: When a repository is archived, GitHub makes it read-only, preventing collaborator modifications. If you attempt to destroy resources associated with archived repositories, the provider will gracefully handle the operation by logging an informational message and removing the resource from Terraform state without attempting to modify the archived repository. + +This resource is non-authoritative, for managing ALL collaborators of a repo, use github_repository_collaborators instead. + +Further documentation on GitHub collaborators: + +- [Adding outside collaborators to your personal repositories](https://help.github.com/en/github/setting-up-and-managing-your-github-user-account/managing-access-to-your-personal-repositories) +- [Adding outside collaborators to repositories in your organization](https://help.github.com/articles/adding-outside-collaborators-to-repositories-in-your-organization/) +- [Converting an organization member to an outside collaborator](https://help.github.com/articles/converting-an-organization-member-to-an-outside-collaborator/) + +## Example Usage + +{{tffile "examples/resources/repository_collaborator/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The GitHub repository + +~> Note: The owner of the repository can be passed as part of the repository name e.g. `owner-org-name/repo-name`. If owner is not supplied as part of the repository name, it may also be supplied by setting the environment variable `GITHUB_OWNER`. + +- `username` - (Required) The user to add to the repository as a collaborator. +- `permission` - (Optional) The permission of the outside collaborator for the repository. Must be one of `pull`, `push`, `maintain`, `triage` or `admin` or the name of an existing [custom repository role](https://docs.github.com/en/enterprise-cloud@latest/organizations/managing-peoples-access-to-your-organization-with-roles/managing-custom-repository-roles-for-an-organization) within the organization for organization-owned repositories. Must be `push` for personal repositories. Defaults to `push`. +- `permission_diff_suppression` - (Optional) Suppress plan diffs for `triage` and `maintain`. Defaults to `false`. + +## Attribute Reference + +In addition to the above arguments, the following attributes are exported: + +- `invitation_id` - ID of the invitation to be used in [`github_user_invitation_accepter`](./user_invitation_accepter.html) + +## Import + +GitHub Repository Collaborators can be imported using an ID made up of `repository:username`, e.g. + +```sh +$ terraform import github_repository_collaborator.collaborator terraform:someuser +``` diff --git a/templates/resources/repository_collaborators.md.tmpl b/templates/resources/repository_collaborators.md.tmpl new file mode 100644 index 0000000000..79c38d3879 --- /dev/null +++ b/templates/resources/repository_collaborators.md.tmpl @@ -0,0 +1,70 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Provides a GitHub repository collaborators resource. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Provides a GitHub repository collaborators resource. + +~> Note: github_repository_collaborators cannot be used in conjunction with github_repository_collaborator and github_team_repository or they will fight over what your policy should be. + +This resource allows you to manage all collaborators for repositories in your organization or personal account. For organization repositories, collaborators can have explicit (and differing levels of) read, write, or administrator access to specific repositories, without giving the user full organization membership. For personal repositories, collaborators can only be granted write (implicitly includes read) permission. + +When applied, an invitation will be sent to the user to become a collaborators on a repository. When destroyed, either the invitation will be cancelled or the collaborators will be removed from the repository. + +~> **Note on Archived Repositories**: When a repository is archived, GitHub makes it read-only, preventing collaborator modifications. If you attempt to destroy resources associated with archived repositories, the provider will gracefully handle the operation by logging an informational message and removing the resource from Terraform state without attempting to modify the archived repository. + +This resource is authoritative. For adding a collaborator to a repo in a non-authoritative manner, use github_repository_collaborator instead. + +Further documentation on GitHub collaborators: + +- [Adding outside collaborators to your personal repositories](https://help.github.com/en/github/setting-up-and-managing-your-github-user-account/managing-access-to-your-personal-repositories) +- [Adding outside collaborators to repositories in your organization](https://help.github.com/articles/adding-outside-collaborators-to-repositories-in-your-organization/) +- [Converting an organization member to an outside collaborators](https://help.github.com/articles/converting-an-organization-member-to-an-outside-collaborator/) + +## Example Usage + +{{tffile "examples/resources/repository_collaborators/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The GitHub repository. +- `user` - (Optional) List of users to grant access to the repository. +- `team` - (Optional) List of teams to grant access to the repository. +- `ignore_team` - (Optional) List of teams to ignore when checking for repository access. This supports ignoring teams granted access at an organizational level. + +The `user` block supports: + +- `username` - (Required) The user to add to the repository as a collaborator. +- `permission` - (Optional) The permission of the outside collaborators for the repository. Must be one of `pull`, `push`, `maintain`, `triage` or `admin` or the name of an existing [custom repository role](https://docs.github.com/en/enterprise-cloud@latest/organizations/managing-peoples-access-to-your-organization-with-roles/managing-custom-repository-roles-for-an-organization) within the organization for organization-owned repositories. Must be `push` for personal repositories. Defaults to `push`. + +The `team` block supports: + +- `team_id` - (Required) The GitHub team id or the GitHub team slug. +- `permission` - (Optional) The permission of the outside collaborators for the repository. Must be one of `pull`, `triage`, `push`, `maintain`, `admin` or the name of an existing [custom repository role](https://docs.github.com/en/enterprise-cloud@latest/organizations/managing-peoples-access-to-your-organization-with-roles/managing-custom-repository-roles-for-an-organization) within the organisation. Defaults to `pull`. Must be `push` for personal repositories. Defaults to `push`. + +The `team_ignore` block supports: + +- `team_id` - (Required) The GitHub team id or the GitHub team slug. + +## Attribute Reference + +In addition to the above arguments, the following attributes are exported: + +- `invitation_ids` - Map of usernames to invitation ID for any users added as part of creation of this resource to be used in [`github_user_invitation_accepter`](./user_invitation_accepter.html). + +## Import + +GitHub Repository Collaborators can be imported using the name `name`, e.g. + +```sh +$ terraform import github_repository_collaborators.collaborators terraform +``` diff --git a/templates/resources/repository_custom_property.md.tmpl b/templates/resources/repository_custom_property.md.tmpl new file mode 100644 index 0000000000..ebbdaeeb26 --- /dev/null +++ b/templates/resources/repository_custom_property.md.tmpl @@ -0,0 +1,39 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Creates and a specific custom property for a GitHub repository +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to create and manage a specific custom property for a GitHub repository. + +## Example Usage + +> Note that this assumes there already is a custom property defined on the org level called `my-cool-property` of type `string` + +{{tffile "examples/resources/repository_custom_property/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The repository of the environment. + +- `property_type` - (Required) Type of the custom property. Can be one of `single_select`, `multi_select`, `string`, or `true_false` + +- `property_name` - (Required) Name of the custom property. Note that a pre-requisiste for this resource is that a custom property of this name has already been defined on the organization level + +- `property_value` - (Required) Value of the custom property in the form of an array. Properties of type `single_select`, `string`, and `true_false` are represented as a string array of length 1 + +## Import + +GitHub Repository Custom Property can be imported using an ID made up of a comibnation of the names of the organization, repository, custom property separated by a `:` character, e.g. + +```sh +$ terraform import github_repository_custom_property.example organization-name:repo-name:custom-property-name +``` diff --git a/templates/resources/repository_dependabot_security_updates.md.tmpl b/templates/resources/repository_dependabot_security_updates.md.tmpl new file mode 100644 index 0000000000..84ed2abf9e --- /dev/null +++ b/templates/resources/repository_dependabot_security_updates.md.tmpl @@ -0,0 +1,35 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Manages automated security fixes for a single repository +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to manage dependabot automated security fixes for a single repository. See the [documentation](https://docs.github.com/en/code-security/dependabot/dependabot-security-updates/about-dependabot-security-updates) for details of usage and how this will impact your repository + +## Example Usage + +{{tffile "examples/resources/repository_dependabot_security_updates/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The name of the GitHub repository. + +- `enabled` - (Required) The state of the automated security fixes. + +## Import + +Automated security references can be imported using the `name` of the repository + +### Import by name + +```sh +terraform import github_repository_dependabot_security_updates.example my-repo +``` diff --git a/templates/resources/repository_deploy_key.md.tmpl b/templates/resources/repository_deploy_key.md.tmpl new file mode 100644 index 0000000000..446490bb31 --- /dev/null +++ b/templates/resources/repository_deploy_key.md.tmpl @@ -0,0 +1,46 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Provides a GitHub repository deploy key resource. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Provides a GitHub repository deploy key resource. + +A deploy key is an SSH key that is stored on your server and grants access to a single GitHub repository. This key is attached directly to the repository instead of to a personal user account. + +This resource allows you to add/remove repository deploy keys. + +~> **Note on Archived Repositories**: When a repository is archived, GitHub makes it read-only, preventing deploy key modifications. If you attempt to destroy resources associated with archived repositories, the provider will gracefully handle the operation by logging an informational message and removing the resource from Terraform state without attempting to modify the archived repository. + +Further documentation on GitHub repository deploy keys: + +- [About deploy keys](https://developer.github.com/guides/managing-deploy-keys/#deploy-keys) + +## Example Usage + +{{tffile "examples/resources/repository_deploy_key/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `key` - (Required) A SSH key. +- `read_only` - (Required) A boolean qualifying the key to be either read only or read/write. +- `repository` - (Required) Name of the GitHub repository. +- `title` - (Required) A title. + +Changing any of the fields forces re-creating the resource. + +## Import + +Repository deploy keys can be imported using a colon-separated pair of repository name and GitHub's key id. The latter can be obtained by GitHub's SDKs and API. + +```sh +$ terraform import github_repository_deploy_key.foo test-repo:23824728 +``` diff --git a/templates/resources/repository_deployment_branch_policy.md.tmpl b/templates/resources/repository_deployment_branch_policy.md.tmpl new file mode 100644 index 0000000000..a16477b5cc --- /dev/null +++ b/templates/resources/repository_deployment_branch_policy.md.tmpl @@ -0,0 +1,41 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Creates and manages deployment branch policies +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +~> **Note:** This resource is deprecated, please use the `github_repository_environment_deployment_policy` resource instead. + +This resource allows you to create and manage deployment branch policies. + +## Example Usage + +{{tffile "examples/resources/repository_deployment_branch_policy/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The repository to create the policy in. + +- `environment_name` - (Required) The name of the environment. This environment must have `deployment_branch_policy.custom_branch_policies` set to true or a 404 error will be thrown. + +- `name` - (Required) The name pattern that branches must match in order to deploy to the environment. + +## Attributes Reference + +The following additional attributes are exported: + +- `id` - The ID of the deployment branch policy. + +## Import + +```sh +$ terraform import github_repository_deployment_branch_policy.foo repo:env:id +``` diff --git a/templates/resources/repository_environment.md.tmpl b/templates/resources/repository_environment.md.tmpl new file mode 100644 index 0000000000..1f7541ab64 --- /dev/null +++ b/templates/resources/repository_environment.md.tmpl @@ -0,0 +1,55 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Creates and manages environments for GitHub repositories +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to create and manage environments for a GitHub repository. + +## Example Usage + +{{tffile "examples/resources/repository_environment/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `environment` - (Required) The name of the environment. + +- `repository` - (Required) The repository of the environment. + +- `wait_timer` - (Optional) Amount of time to delay a job after the job is initially triggered. + +- `can_admins_bypass` - (Optional) Can repository admins bypass the environment protections. Defaults to `true`. + +- `prevent_self_review` - (Optional) Whether or not a user who created the job is prevented from approving their own job. Defaults to `false`. + +### Reviewers + +The `reviewers` block supports the following: + +- `teams` - (Optional) Up to 6 IDs for teams who may review jobs that reference the environment. Reviewers must have at least read access to the repository. Only one of the required reviewers needs to approve the job for it to proceed. + +- `users` - (Optional) Up to 6 IDs for users who may review jobs that reference the environment. Reviewers must have at least read access to the repository. Only one of the required reviewers needs to approve the job for it to proceed. + +#### Deployment Branch Policy + +The `deployment_branch_policy` block supports the following: + +- `protected_branches` - (Required) Whether only branches with branch protection rules can deploy to this environment. + +- `custom_branch_policies` - (Required) Whether only branches that match the specified name patterns can deploy to this environment. + +## Import + +GitHub Repository Environment can be imported using an ID made up of `name` of the repository combined with the `environment` name of the environment, separated by a `:` character, e.g. + +```sh +$ terraform import github_repository_environment.daily terraform:daily +``` diff --git a/templates/resources/repository_environment_deployment_policy.md.tmpl b/templates/resources/repository_environment_deployment_policy.md.tmpl new file mode 100644 index 0000000000..e71c3fe7b1 --- /dev/null +++ b/templates/resources/repository_environment_deployment_policy.md.tmpl @@ -0,0 +1,43 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Creates and manages environment deployment branch policies for GitHub repositories +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to create and manage environment deployment branch policies for a GitHub repository. + +## Example Usage + +Create a branch-based deployment policy: + +{{tffile "examples/resources/repository_environment_deployment_policy/example_1.tf"}} + +Create a tag-based deployment policy: + +{{tffile "examples/resources/repository_environment_deployment_policy/example_2.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `environment` - (Required) The name of the environment. + +- `repository` - (Required) The repository of the environment. + +- `branch_pattern` - (Optional) The name pattern that branches must match in order to deploy to the environment. If not specified, `tag_pattern` must be specified. + +- `tag_pattern` - (Optional) The name pattern that tags must match in order to deploy to the environment. If not specified, `branch_pattern` must be specified. + +## Import + +GitHub Repository Environment Deployment Policy can be imported using an ID made up of `name` of the repository combined with the `environment` name of the environment with the `Id` of the deployment policy, separated by a `:` character, e.g. + +```sh +$ terraform import github_repository_environment.daily terraform:daily:123456 +``` diff --git a/templates/resources/repository_file.md.tmpl b/templates/resources/repository_file.md.tmpl new file mode 100644 index 0000000000..3106e2bf1a --- /dev/null +++ b/templates/resources/repository_file.md.tmpl @@ -0,0 +1,75 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Creates and manages files within a GitHub repository +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to create and manage files within a GitHub repository. + +~> **Note:** When a repository is archived, Terraform will skip deletion of repository files to avoid API errors, as archived repositories are read-only. The files will be removed from Terraform state without attempting to delete them from GitHub. + +## Example Usage + +### Existing Branch + +{{tffile "examples/resources/repository_file/example_1.tf"}} + +### Auto Created Branch + +{{tffile "examples/resources/repository_file/example_2.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The repository to create the file in. + +- `file` - (Required) The path of the file to manage. + +- `content` - (Required) The file content. + +- `branch` - (Optional) Git branch (defaults to the repository's default branch). The branch must already exist, it will only be created automatically if 'autocreate_branch' is set true. + +- `commit_author` - (Optional) Committer author name to use. **NOTE:** GitHub app users may omit author and email information so GitHub can verify commits as the GitHub App. This maybe useful when a branch protection rule requires signed commits. + +- `commit_email` - (Optional) Committer email address to use. **NOTE:** GitHub app users may omit author and email information so GitHub can verify commits as the GitHub App. This may be useful when a branch protection rule requires signed commits. + +- `commit_message` - (Optional) The commit message when creating, updating or deleting the managed file. + +- `overwrite_on_create` - (Optional) Enable overwriting existing files. If set to `true` it will overwrite an existing file with the same name. If set to `false` it will fail if there is an existing file with the same name. + +- `autocreate_branch` - (Optional) Automatically create the branch if it could not be found. Defaults to false. Subsequent reads if the branch is deleted will occur from 'autocreate_branch_source_branch'. + +- `autocreate_branch_source_branch` - (Optional) The branch name to start from, if 'autocreate_branch' is set. Defaults to 'main'. + +- `autocreate_branch_source_sha` - (Optional) The commit hash to start from, if 'autocreate_branch' is set. Defaults to the tip of 'autocreate_branch_source_branch'. If provided, 'autocreate_branch_source_branch' is ignored. + +## Attributes Reference + +The following additional attributes are exported: + +- `commit_sha` - The SHA of the commit that modified the file. + +- `sha` - The SHA blob of the file. + +- `ref` - The name of the commit/branch/tag. + +## Import + +Repository files can be imported using a combination of the `repo` and `file`, e.g. + +```sh +$ terraform import github_repository_file.gitignore example/.gitignore +``` + +To import a file from a branch other than the default branch, append `:` and the branch name, e.g. + +```sh +$ terraform import github_repository_file.gitignore example/.gitignore:dev +``` diff --git a/templates/resources/repository_milestone.md.tmpl b/templates/resources/repository_milestone.md.tmpl new file mode 100644 index 0000000000..1f38c09e01 --- /dev/null +++ b/templates/resources/repository_milestone.md.tmpl @@ -0,0 +1,49 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Provides a GitHub repository milestone resource. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Provides a GitHub repository milestone resource. + +This resource allows you to create and manage milestones for a GitHub Repository within an organization or user account. + +## Example Usage + +{{tffile "examples/resources/repository_milestone/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `owner` - (Required) The owner of the GitHub Repository. + +- `repository` - (Required) The name of the GitHub Repository. + +- `title` - (Required) The title of the milestone. + +- `description` - (Optional) A description of the milestone. + +- `due_date` - (Optional) The milestone due date. In `yyyy-mm-dd` format. + +- `state` - (Optional) The state of the milestone. Either `open` or `closed`. Default: `open` + +## Attributes Reference + +The following additional attributes are exported: + +- `number` - The number of the milestone. + +## Import + +A GitHub Repository Milestone can be imported using an ID made up of `owner/repository/number`, e.g. + +```sh +$ terraform import github_repository_milestone.example example-owner/example-repository/1 +``` diff --git a/templates/resources/repository_pull_request.md.tmpl b/templates/resources/repository_pull_request.md.tmpl new file mode 100644 index 0000000000..7303704ccb --- /dev/null +++ b/templates/resources/repository_pull_request.md.tmpl @@ -0,0 +1,53 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Get information on a single GitHub Pull Request. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to create and manage PullRequests for repositories within your GitHub organization or personal account. + +## Example Usage + +{{tffile "examples/resources/repository_pull_request/example_1.tf"}} + +## Argument Reference + +- `base_repository` - (Required) Name of the base repository to retrieve the Pull Requests from. + +- `base_ref` - (Required) Name of the branch serving as the base of the Pull Request. + +- `head_ref` - (Required) Name of the branch serving as the head of the Pull Request. + +- `owner` - (Optional) Owner of the repository. If not provided, the provider's default owner is used. + +- `title` - (Optional) The title of the Pull Request. + +- `body` - (Optional) Body of the Pull Request. + +- `maintainer_can_modify` - Controls whether the base repository maintainers can modify the Pull Request. Default: false. + +## Attributes Reference + +- `base_sha` - Head commit SHA of the Pull Request base. + +- `draft` - Indicates Whether this Pull Request is a draft. + +- `head_sha` - Head commit SHA of the Pull Request head. + +- `labels` - List of label names set on the Pull Request. + +- `number` - The number of the Pull Request within the repository. + +- `opened_at` - Unix timestamp indicating the Pull Request creation time. + +- `opened_by` - GitHub login of the user who opened the Pull Request. + +- `state` - the current Pull Request state - can be "open", "closed" or "merged". + +- `updated_at` - The timestamp of the last Pull Request update. diff --git a/templates/resources/repository_ruleset.md.tmpl b/templates/resources/repository_ruleset.md.tmpl new file mode 100644 index 0000000000..65b7697977 --- /dev/null +++ b/templates/resources/repository_ruleset.md.tmpl @@ -0,0 +1,248 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Creates a GitHub repository ruleset. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Creates a GitHub repository ruleset. + +This resource allows you to create and manage rulesets on the repository level. When applied, a new ruleset will be created. When destroyed, that ruleset will be removed. + +## Example Usage + +{{tffile "examples/resources/repository_ruleset/example_1.tf"}} + +## Argument Reference + +- `enforcement` - (Required) (String) Possible values for Enforcement are `disabled`, `active`, `evaluate`. Note: `evaluate` is currently only supported for owners of type `organization`. + +- `name` - (Required) (String) The name of the ruleset. + +- `rules` - (Required) (Block List, Min: 1, Max: 1) Rules within the ruleset. (see [below for nested schema](#rules)) + +- `target` - (Required) (String) Possible values are `branch`, `tag` and `push`. + +- `bypass_actors` - (Optional) (Block List) The actors that can bypass the rules in this ruleset. (see [below for nested schema](#bypass_actors)) + +- `conditions` - (Optional) (Block List, Max: 1) Parameters for a repository ruleset ref name condition. (see [below for nested schema](#conditions)) + +- `repository` - (Required) (String) Name of the repository to apply ruleset to. + +### Rules + +The `rules` block supports the following: + +- `branch_name_pattern` - (Optional) (Block List, Max: 1) Parameters to be used for the branch_name_pattern rule. This rule only applies to repositories within an enterprise, it cannot be applied to repositories owned by individuals or regular organizations. Conflicts with `tag_name_pattern` as it only applied to rulesets with target `branch`. (see [below for nested schema](#rulesbranch_name_pattern)) + +- `commit_author_email_pattern` - (Optional) (Block List, Max: 1) Parameters to be used for the commit_author_email_pattern rule. This rule only applies to repositories within an enterprise, it cannot be applied to repositories owned by individuals or regular organizations. (see [below for nested schema](#rulescommit_author_email_pattern)) + +- `commit_message_pattern` - (Optional) (Block List, Max: 1) Parameters to be used for the commit_message_pattern rule. This rule only applies to repositories within an enterprise, it cannot be applied to repositories owned by individuals or regular organizations. (see [below for nested schema](#rulescommit_message_pattern)) + +- `committer_email_pattern` - (Optional) (Block List, Max: 1) Parameters to be used for the committer_email_pattern rule. This rule only applies to repositories within an enterprise, it cannot be applied to repositories owned by individuals or regular organizations. (see [below for nested schema](#rulescommitter_email_pattern)) + +- `creation` - (Optional) (Boolean) Only allow users with bypass permission to create matching refs. + +- `deletion` - (Optional) (Boolean) Only allow users with bypass permissions to delete matching refs. + +- `non_fast_forward` - (Optional) (Boolean) Prevent users with push access from force pushing to branches. + +- `merge_queue` - (Optional) (Block List, Max: 1) Merges must be performed via a merge queue. + +- `pull_request` - (Optional) (Block List, Max: 1) Require all commits be made to a non-target branch and submitted via a pull request before they can be merged. (see [below for nested schema](#rulespull_request)) + +- `required_deployments` - (Optional) (Block List, Max: 1) Choose which environments must be successfully deployed to before branches can be merged into a branch that matches this rule. (see [below for nested schema](#rulesrequired_deployments)) + +- `required_linear_history` - (Optional) (Boolean) Prevent merge commits from being pushed to matching branches. + +- `required_signatures` - (Optional) (Boolean) Commits pushed to matching branches must have verified signatures. + +- `required_status_checks` - (Optional) (Block List, Max: 1) Choose which status checks must pass before branches can be merged into a branch that matches this rule. When enabled, commits must first be pushed to another branch, then merged or pushed directly to a branch that matches this rule after status checks have passed. (see [below for nested schema](#rulesrequired_status_checks)) + +- `tag_name_pattern` - (Optional) (Block List, Max: 1) Parameters to be used for the tag_name_pattern rule. This rule only applies to repositories within an enterprise, it cannot be applied to repositories owned by individuals or regular organizations. Conflicts with `branch_name_pattern` as it only applied to rulesets with target `tag`. (see [below for nested schema](#rulestag_name_pattern)) + +- `required_code_scanning` - (Optional) (Block List, Max: 1) Define which tools must provide code scanning results before the reference is updated. When configured, code scanning must be enabled and have results for both the commit and the reference being updated. Multiple code scanning tools can be specified. (see [below for nested schema](#rulesrequired_code_scanning)) + +- `file_path_restriction` - (Optional) (Block List, Max 1) Parameters to be used for the file_path_restriction rule. When enabled restricts access to files within the repository. (See [below for nested schema](#rules.file_path_restriction)) + +- `max_file_size` - (Optional) (Block List, Max 1) Parameters to be used for the max_file_size rule. When enabled restricts the maximum size of a file that can be pushed to the repository. (See [below for nested schema](#rules.max_file_size)) + +- `max_file_path_length` - (Optional) (Block List, Max: 1) Prevent commits that include file paths that exceed a specified character limit from being pushed to the commit graph. This rule only applies to rulesets with target `push`. (see [below for nested schema](#rules.max_file_path_length)) + +- `file_extension_restriction` - (Optional) (Block List, Max: 1) Prevent commits that include files with specified file extensions from being pushed to the commit graph. This rule only applies to rulesets with target `push`. (see [below for nested schema](#rules.file_extension_restriction)) +- `update` - (Optional) (Boolean) Only allow users with bypass permission to update matching refs. + +- `update_allows_fetch_and_merge` - (Optional) (Boolean) Branch can pull changes from its upstream repository. This is only applicable to forked repositories. Requires `update` to be set to `true`. Note: behaviour is affected by a known bug on the GitHub side which may cause issues when using this parameter. + +#### rules.branch_name_pattern + +- `operator` - (Required) (String) The operator to use for matching. Can be one of: `starts_with`, `ends_with`, `contains`, `regex`. + +- `pattern` - (Required) (String) The pattern to match with. + +- `name` - (Optional) (String) How this rule will appear to users. + +- `negate` - (Optional) (Boolean) If true, the rule will fail if the pattern matches. + +#### rules.commit_author_email_pattern + +- `operator` - (Required) (String) The operator to use for matching. Can be one of: `starts_with`, `ends_with`, `contains`, `regex`. + +- `pattern` - (Required) (String) The pattern to match with. + +- `name` - (Optional) (String) How this rule will appear to users. + +- `negate` - (Optional) (Boolean) If true, the rule will fail if the pattern matches. + +#### rules.commit_message_pattern + +- `operator` - (Required) (String) The operator to use for matching. Can be one of: `starts_with`, `ends_with`, `contains`, `regex`. + +- `pattern` - (Required) (String) The pattern to match with. + +- `name` - (Optional) (String) How this rule will appear to users. + +- `negate` - (Optional) (Boolean) If true, the rule will fail if the pattern matches. + +#### rules.committer_email_pattern + +- `operator` - (Required) (String) The operator to use for matching. Can be one of: `starts_with`, `ends_with`, `contains`, `regex`. + +- `pattern` - (Required) (String) The pattern to match with. + +- `name` - (Optional) (String) How this rule will appear to users. + +- `negate` - (Optional) (Boolean) If true, the rule will fail if the pattern matches. + +#### rules.merge_queue + +- `check_response_timeout_minutes` - (Required) (Number)Maximum time for a required status check to report a conclusion. After this much time has elapsed, checks that have not reported a conclusion will be assumed to have failed. Defaults to `60`. + +- `grouping_strategy` - (Required) (String)When set to ALLGREEN, the merge commit created by merge queue for each PR in the group must pass all required checks to merge. When set to HEADGREEN, only the commit at the head of the merge group, i.e. the commit containing changes from all of the PRs in the group, must pass its required checks to merge. Can be one of: ALLGREEN, HEADGREEN. Defaults to `ALLGREEN`. + +- `max_entries_to_build` - (Required) (Number) Limit the number of queued pull requests requesting checks and workflow runs at the same time. Defaults to `5`. + +- `max_entries_to_merge` - (Required) (Number) Limit the number of queued pull requests requesting checks and workflow runs at the same time. Defaults to `5`. + +- `merge_method` - (Required) (String) Method to use when merging changes from queued pull requests. Can be one of: MERGE, SQUASH, REBASE. Defaults to `MERGE`. + +- `min_entries_to_merge` - (Required) (Number) The minimum number of PRs that will be merged together in a group. Defaults to `1`. + +- `min_entries_to_merge_wait_minutes` - (Required) (Number) The time merge queue should wait after the first PR is added to the queue for the minimum group size to be met. After this time has elapsed, the minimum group size will be ignored and a smaller group will be merged. Defaults to `5`. + +#### rules.pull_request + +- `dismiss_stale_reviews_on_push` - (Optional) (Boolean) New, reviewable commits pushed will dismiss previous pull request review approvals. Defaults to `false`. + +- `require_code_owner_review` - (Optional) (Boolean) Require an approving review in pull requests that modify files that have a designated code owner. Defaults to `false`. + +- `require_last_push_approval` - (Optional) (Boolean) Whether the most recent reviewable push must be approved by someone other than the person who pushed it. Defaults to `false`. + +- `required_approving_review_count` - (Optional) (Number) The number of approving reviews that are required before a pull request can be merged. Defaults to `0`. + +- `required_review_thread_resolution` - (Optional) (Boolean) All conversations on code must be resolved before a pull request can be merged. Defaults to `false`. + +#### rules.required_deployments + +- `required_deployment_environments` - (Required) (List of String) The environments that must be successfully deployed to before branches can be merged. + +#### rules.required_status_checks + +- `required_check` - (Required) (Block Set, Min: 1) Status checks that are required. Several can be defined. (see [below for nested schema](#rulesrequired_status_checksrequired_check)) + +- `strict_required_status_checks_policy` - (Optional) (Boolean) Whether pull requests targeting a matching branch must be tested with the latest code. This setting will not take effect unless at least one status check is enabled. Defaults to `false`. + +- `do_not_enforce_on_create` - (Optional) (Boolean) Allow repositories and branches to be created if a check would otherwise prohibit it. Defaults to `false`. + +#### rules.required_status_checks.required_check + +- `context` - (Required) (String) The status check context name that must be present on the commit. + +- `integration_id` - (Optional) (Number) The optional integration ID that this status check must originate from. It's a GitHub App ID, which can be obtained by following instructions from the [Get an App API docs](https://docs.github.com/en/rest/apps/apps?apiVersion=2022-11-28#get-an-app). + +#### rules.tag_name_pattern + +- `operator` - (Required) (String) The operator to use for matching. Can be one of: `starts_with`, `ends_with`, `contains`, `regex`. + +- `pattern` - (Required) (String) The pattern to match with. + +- `name` - (Optional) (String) How this rule will appear to users. + +- `negate` - (Optional) (Boolean) If true, the rule will fail if the pattern matches. + +#### rules.required_code_scanning + +- `required_code_scanning_tool` - (Required) (Block Set, Min: 1) Actions code scanning tools that are required. Multiple can be defined. (see [below for nested schema](#rulesrequired_code_scanningrequired_code_scanning_tool)) + +#### rules.required_code_scanning.required_code_scanning_tool + +- `alerts_threshold` - (Required) (String) The severity level at which code scanning results that raise alerts block a reference update. Can be one of: `none`, `errors`, `errors_and_warnings`, `all`. + +- `security_alerts_threshold` - (Required) (String) The severity level at which code scanning results that raise security alerts block a reference update. Can be one of: `none`, `critical`, `high_or_higher`, `medium_or_higher`, `all`. + +- `tool` - (Required) (String) The name of a code scanning tool. + +#### rules.file_path_restriction + +- `restricted_file_paths` - (Required) (Block Set, Min: 1) The file paths that are restricted from being pushed to the commit graph. + +#### rules.max_file_size + +- `max_file_size` - (Required) (Integer) The maximum allowed size, in megabytes (MB), of a file. Valid range is 1-100 MB. + +#### rules.max_file_path_length + +- `max_file_path_length` - (Required) (Integer) The maximum number of characters allowed in file paths. + +#### rules.file_extension_restriction + +- `restricted_file_extensions` - (Required) (Block Set, Min: 1) The file extensions that are restricted from being pushed to the commit graph. + +#### bypass_actors + +- `actor_id` - (Number) The ID of the actor that can bypass a ruleset. If `actor_type` is `Integration`, `actor_id` is a GitHub App ID. App ID can be obtained by following instructions from the [Get an App API docs](https://docs.github.com/en/rest/apps/apps?apiVersion=2022-11-28#get-an-app) + +- `actor_type` (String) The type of actor that can bypass a ruleset. Can be one of: `RepositoryRole`, `Team`, `Integration`, `OrganizationAdmin`, `DeployKey`. + +- `bypass_mode` - (Optional) (String) When the specified actor can bypass the ruleset. pull_request means that an actor can only bypass rules on pull requests. Can be one of: `always`, `pull_request`, `exempt`. + +~> Note: at the time of writing this, the following actor types correspond to the following actor IDs: + +- `OrganizationAdmin` -> `1` +- `RepositoryRole` (This is the actor type, the following are the base repository roles and their associated IDs.) + - `maintain` -> `2` + - `write` -> `4` + - `admin` -> `5` + +#### conditions + +- `ref_name` - (Required) (Block List, Min: 1, Max: 1) (see [below for nested schema](#conditions.ref_name)) + +#### conditions.ref_name + +- `exclude` - (Required) (List of String) Array of ref names or patterns to exclude. The condition will not pass if any of these patterns match. + +- `include` - (Required) (List of String) Array of ref names or patterns to include. One of these patterns must match for the condition to pass. Also accepts `~DEFAULT_BRANCH` to include the default branch or `~ALL` to include all branches. + +## Attributes Reference + +The following additional attributes are exported: + +- `etag` (String) + +- `node_id` (String) GraphQL global node id for use with v4 API. + +- `ruleset_id` (Number) GitHub ID for the ruleset. + +## Import + +GitHub Repository Rulesets can be imported using the GitHub repository name and ruleset ID e.g. + +```sh +$ terraform import github_repository_ruleset.example example:12345 +``` diff --git a/templates/resources/repository_topics.md.tmpl b/templates/resources/repository_topics.md.tmpl new file mode 100644 index 0000000000..91173a6f34 --- /dev/null +++ b/templates/resources/repository_topics.md.tmpl @@ -0,0 +1,35 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Creates and manages the topics on a repository +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to create and manage topics for repositories within your GitHub organization or personal account. + +~> Note: This resource is not compatible with the `topic` attribute of the `github_repository` Use either `github_repository_topics` or `topic` in `github_repository`. `github_repository_topics` is only meant to be used if the repository itself is not handled via terraform, for example if it's only read as a datasource (see [issue #1845](https://github.com/integrations/terraform-provider-github/issues/1845)). + +## Example Usage + +{{tffile "examples/resources/repository_topics/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The repository name. + +- `topics` - (Required) A list of topics to add to the repository. + +## Import + +Repository topics can be imported using the `name` of the repository. + +```sh +$ terraform import github_repository_topics.terraform terraform +``` diff --git a/templates/resources/repository_webhook.md.tmpl b/templates/resources/repository_webhook.md.tmpl new file mode 100644 index 0000000000..6c5822b8db --- /dev/null +++ b/templates/resources/repository_webhook.md.tmpl @@ -0,0 +1,59 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Creates and manages repository webhooks within GitHub organizations or personal accounts +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to create and manage webhooks for repositories within your GitHub organization or personal account. + +~> **Note on Archived Repositories**: When a repository is archived, GitHub makes it read-only, preventing webhook modifications. If you attempt to destroy resources associated with archived repositories, the provider will gracefully handle the operation by logging an informational message and removing the resource from Terraform state without attempting to modify the archived repository. + +## Example Usage + +{{tffile "examples/resources/repository_webhook/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The repository of the webhook. + +- `events` - (Required) A list of events which should trigger the webhook. See a list of [available events](https://developer.github.com/v3/activity/events/types/). + +- `configuration` - (Required) Configuration block for the webhook. [Detailed below.](#configuration) + +- `active` - (Optional) Indicate if the webhook should receive events. Defaults to `true`. + +### configuration + +- `url` - (Required) The URL of the webhook. + +- `content_type` - (Required) The content type for the payload. Valid values are either `form` or `json`. + +- `secret` - (Optional) The shared secret for the webhook. [See API documentation](https://developer.github.com/v3/repos/hooks/#create-a-hook). + +- `insecure_ssl` - (Optional) Insecure SSL boolean toggle. Defaults to `false`. + +## Attributes Reference + +The following additional attributes are exported: + +- `url` - URL of the webhook. This is a sensitive attribute because it may include basic auth credentials. + +## Import + +Repository webhooks can be imported using the `name` of the repository, combined with the `id` of the webhook, separated by a `/` character. The `id` of the webhook can be found in the URL of the webhook. For example: `"https://github.com/foo-org/foo-repo/settings/hooks/14711452"`. + +Importing uses the name of the repository, as well as the ID of the webhook, e.g. + +```sh +$ terraform import github_repository_webhook.terraform terraform/11235813 +``` + +If secret is populated in the webhook's configuration, the value will be imported as "********". diff --git a/templates/resources/team.md.tmpl b/templates/resources/team.md.tmpl new file mode 100644 index 0000000000..0d218c380a --- /dev/null +++ b/templates/resources/team.md.tmpl @@ -0,0 +1,47 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Provides a GitHub team resource. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Provides a GitHub team resource. + +This resource allows you to add/remove teams from your organization. When applied, a new team will be created. When destroyed, that team will be removed. + +## Example Usage + +{{tffile "examples/resources/team/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `name` - (Required) The name of the team. +- `description` - (Optional) A description of the team. +- `privacy` - (Optional) The level of privacy for the team. Must be one of `secret` or `closed`. Defaults to `secret`. +- `parent_team_id` - (Optional) The ID or slug of the parent team, if this is a nested team. +- `ldap_dn` - (Optional) The LDAP Distinguished Name of the group where membership will be synchronized. Only available in GitHub Enterprise Server. +- `create_default_maintainer` - (Optional) Adds a default maintainer to the team. Defaults to `false` and adds the creating user to the team when `true`. + +## Attributes Reference + +The following attributes are exported: + +- `id` - The ID of the created team. +- `node_id` - The Node ID of the created team. +- `slug` - The slug of the created team, which may or may not differ from `name`, depending on whether `name` contains "URL-unsafe" characters. Useful when referencing the team in [`github_branch_protection`](../branch_protection). + +## Import + +GitHub Teams can be imported using the GitHub team ID or slug e.g. + +```sh +$ terraform import github_team.core 1234567 +$ terraform import github_team.core administrators +``` diff --git a/templates/resources/team_members.md.tmpl b/templates/resources/team_members.md.tmpl new file mode 100644 index 0000000000..f6b82ea125 --- /dev/null +++ b/templates/resources/team_members.md.tmpl @@ -0,0 +1,57 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Provides an authoritative GitHub team members resource. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Provides a GitHub team members resource. + +This resource allows you to manage members of teams in your organization. It sets the requested team members for the team and removes all users not managed by Terraform. + +When applied, if the user hasn't accepted their invitation to the organization, they won't be part of the team until they do. + +When destroyed, all users will be removed from the team. + +~> **Note** This resource is not compatible with `github_team_membership`. Use either `github_team_members` or `github_team_membership`. + +~> **Note** You can accidentally lock yourself out of your team using this resource. Deleting a `github_team_members` resource removes access from anyone without organization-level access to the team. Proceed with caution. It should generally only be used with teams fully managed by Terraform. + +~> **Note** Attempting to set a user who is an organization owner to "member" will result in the user being granted "maintainer" instead; this can result in a perpetual `terraform plan` diff that changes their status back to "member". + +## Example Usage + +{{tffile "examples/resources/team_members/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `team_id` - (Required) The team id or the team slug + +~> **Note** Although the team id or team slug can be used it is recommended to use the team id. Using the team slug will cause the team members associations to the team to be destroyed and recreated if the team name is updated. + +- `members` - (Required) List of team members. See [Members](#members) below for details. + +### Members + +`members` supports the following arguments: + +- `username` - (Required) The user to add to the team. +- `role` - (Optional) The role of the user within the team. Must be one of `member` or `maintainer`. Defaults to `member`. + +## Import + +~> **Note** Although the team id or team slug can be used it is recommended to use the team id. Using the team slug will result in terraform doing conversions between the team slug and team id. This will cause team members associations to the team to be destroyed and recreated on import. + +GitHub Team Membership can be imported using the team ID team id or team slug, e.g. + +```sh +$ terraform import github_team_members.some_team 1234567 +$ terraform import github_team_members.some_team Administrators +``` diff --git a/templates/resources/team_membership.md.tmpl b/templates/resources/team_membership.md.tmpl new file mode 100644 index 0000000000..69a1f5734c --- /dev/null +++ b/templates/resources/team_membership.md.tmpl @@ -0,0 +1,40 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Provides a GitHub team membership resource. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Provides a GitHub team membership resource. + +This resource allows you to add/remove users from teams in your organization. When applied, the user will be added to the team. If the user hasn't accepted their invitation to the organization, they won't be part of the team until they do. When destroyed, the user will be removed from the team. + +~> **Note** This resource is not compatible with `github_team_members`. Use either `github_team_members` or `github_team_membership`. + +~> **Note** Organization owners may not be set as "members" of a team; they may only be set as "maintainers". Attempting to set an organization owner as a "member" of a team may result in a `terraform plan` diff that changes their status back to "maintainer". + +## Example Usage + +{{tffile "examples/resources/team_membership/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `team_id` - (Required) The GitHub team id or the GitHub team slug +- `username` - (Required) The user to add to the team. +- `role` - (Optional) The role of the user within the team. Must be one of `member` or `maintainer`. Defaults to `member`. + +## Import + +GitHub Team Membership can be imported using an ID made up of `teamid:username` or `teamname:username`, e.g. + +```sh +$ terraform import github_team_membership.member 1234567:someuser +$ terraform import github_team_membership.member Administrators:someuser +``` diff --git a/templates/resources/team_repository.md.tmpl b/templates/resources/team_repository.md.tmpl new file mode 100644 index 0000000000..cf1010de87 --- /dev/null +++ b/templates/resources/team_repository.md.tmpl @@ -0,0 +1,44 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Manages the associations between teams and repositories. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +~> Note: github_team_repository cannot be used in conjunction with github_repository_collaborators or they will fight over what your policy should be. + +This resource manages relationships between teams and repositories in your GitHub organization. + +Creating this resource grants a particular team permissions on a particular repository. + +The repository and the team must both belong to the same organization on GitHub. This resource does not actually *create* any repositories; to do that, see [`github_repository`](repository.html). + +~> **Note on Archived Repositories**: When a repository is archived, GitHub makes it read-only, preventing team permission modifications. If you attempt to destroy resources associated with archived repositories, the provider will gracefully handle the operation by logging an informational message and removing the resource from Terraform state without attempting to modify the archived repository. + +This resource is non-authoritative, for managing ALL collaborators of a repo, use github_repository_collaborators instead. + +## Example Usage + +{{tffile "examples/resources/team_repository/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `team_id` - (Required) The GitHub team id or the GitHub team slug +- `repository` - (Required) The repository to add to the team. +- `permission` - (Optional) The permissions of team members regarding the repository. Must be one of `pull`, `triage`, `push`, `maintain`, `admin` or the name of an existing [custom repository role](https://docs.github.com/en/enterprise-cloud@latest/organizations/managing-peoples-access-to-your-organization-with-roles/managing-custom-repository-roles-for-an-organization) within the organisation. Defaults to `pull`. + +## Import + +GitHub Team Repository can be imported using an ID made up of `team_id:repository` or `team_name:repository`, e.g. + +```sh +$ terraform import github_team_repository.terraform_repo 1234567:terraform +$ terraform import github_team_repository.terraform_repo Administrators:terraform +``` diff --git a/templates/resources/team_settings.md.tmpl b/templates/resources/team_settings.md.tmpl new file mode 100644 index 0000000000..36b3059e6a --- /dev/null +++ b/templates/resources/team_settings.md.tmpl @@ -0,0 +1,52 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Manages the team settings (in particular the request review delegation settings) +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource manages the team settings (in particular the request review delegation settings) within the organization + +Creating this resource will alter the team Code Review settings. + +The team must both belong to the same organization configured in the provider on GitHub. + +~> **Note**: This resource relies on the v4 GraphQl GitHub API. If this API is not available, or the Stone Crop schema preview is not available, then this resource will not work as intended. + +## Example Usage + +{{tffile "examples/resources/team_settings/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `team_id` - (Required) The GitHub team id or the GitHub team slug +- `review_request_delegation` - (Optional) The settings for delegating code reviews to individuals on behalf of the team. If this block is present, even without any fields, then review request delegation will be enabled for the team. See [GitHub Review Request Delegation](#github-review-request-delegation-configuration) below for details. See [GitHub's documentation](https://docs.github.com/en/organizations/organizing-members-into-teams/managing-code-review-settings-for-your-team#configuring-team-notifications) for more configuration details. + +### GitHub Review Request Delegation Configuration + +The following arguments are supported: + +- `algorithm` - (Optional) The algorithm to use when assigning pull requests to team members. Supported values are `ROUND_ROBIN` and `LOAD_BALANCE`. Default value is `ROUND_ROBIN` +- `member_count` - (Optional) The number of team members to assign to a pull request +- `notify` - (Optional) whether to notify the entire team when at least one member is also assigned to the pull request + +## Import + +GitHub Teams can be imported using the GitHub team ID, or the team slug e.g. + +```sh +$ terraform import github_team.code_review_settings 1234567 +``` + +or, + +```sh +$ terraform import github_team_settings.code_review_settings SomeTeam +``` diff --git a/templates/resources/team_sync_group_mapping.md.tmpl b/templates/resources/team_sync_group_mapping.md.tmpl new file mode 100644 index 0000000000..7c975ff8ff --- /dev/null +++ b/templates/resources/team_sync_group_mapping.md.tmpl @@ -0,0 +1,44 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Creates and manages the connections between a team and its IdP group(s). +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to create and manage Identity Provider (IdP) group connections within your GitHub teams. You must have team synchronization enabled for organizations owned by enterprise accounts. + +To learn more about team synchronization between IdPs and GitHub, please refer to: [Managing team synchronization for your organization](https://help.github.com/en/github/setting-up-and-managing-organizations-and-teams/synchronizing-teams-between-your-identity-provider-and-github) + +## Example Usage + +{{tffile "examples/resources/team_sync_group_mapping/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `team_slug` - (Required) Slug of the team +- `group` - (Required) An Array of GitHub Identity Provider Groups (or empty []). Each `group` block consists of the fields documented below. + +--- + +The `group` block consists of: + +- `group_id` - The ID of the IdP group. + +- `group_name` - The name of the IdP group. + +- `group_description` - The description of the IdP group. + +## Import + +GitHub Team Sync Group Mappings can be imported using the GitHub team `slug` e.g. + +```sh +$ terraform import github_team_sync_group_mapping.example some_team +``` diff --git a/templates/resources/user_gpg_key.md.tmpl b/templates/resources/user_gpg_key.md.tmpl new file mode 100644 index 0000000000..fd7242022a --- /dev/null +++ b/templates/resources/user_gpg_key.md.tmpl @@ -0,0 +1,36 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Provides a GitHub user's GPG key resource. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Provides a GitHub user's GPG key resource. + +This resource allows you to add/remove GPG keys from your user account. + +## Example Usage + +{{tffile "examples/resources/user_gpg_key/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `armored_public_key` - (Required) Your public GPG key, generated in ASCII-armored format. See [Generating a new GPG key](https://help.github.com/articles/generating-a-new-gpg-key/) for help on creating a GPG key. + +## Attributes Reference + +The following attributes are exported: + +- `id` - The GitHub ID of the GPG key, e.g. `401586` +- `key_id` - The key ID of the GPG key, e.g. `3262EFF25BA0D270` + +## Import + +GPG keys are not importable due to the fact that [API](https://developer.github.com/v3/users/gpg_keys/#gpg-keys) does not return previously uploaded GPG key. diff --git a/templates/resources/user_invitation_accepter.md.tmpl b/templates/resources/user_invitation_accepter.md.tmpl new file mode 100644 index 0000000000..3c1e53e7c6 --- /dev/null +++ b/templates/resources/user_invitation_accepter.md.tmpl @@ -0,0 +1,34 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Provides a resource to manage GitHub repository collaborator invitations. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Provides a resource to manage GitHub repository collaborator invitations. + +## Example Usage + +{{tffile "examples/resources/user_invitation_accepter/example_1.tf"}} + +## Allowing empty invitation IDs + +Set `allow_empty_id` when using `for_each` over a list of `github_repository_collaborator.invitation_id`'s. + +This allows applying a module again when a new `github_repository_collaborator` resource is added to the `for_each` loop. This is needed as the `github_repository_collaborator.invitation_id` will be empty after a state refresh when the invitation has been accepted. + +Note that when an invitation is accepted manually or by another tool between a state refresh and a `terraform apply` using that refreshed state, the plan will contain the invitation ID, but the apply will receive an HTTP 404 from the API since the invitation has already been accepted. + +This is tracked in [#1157](https://github.com/integrations/terraform-provider-github/issues/1157). + +## Argument Reference + +The following arguments are supported: + +- `invitation_id` - (Optional) ID of the invitation to accept. Must be set when `allow_empty_id` is `false`. +- `allow_empty_id` - (Optional) Allow the ID to be unset. This will result in the resource being skipped when the ID is not set instead of returning an error. diff --git a/templates/resources/user_ssh_key.md.tmpl b/templates/resources/user_ssh_key.md.tmpl new file mode 100644 index 0000000000..4cf32c3bbe --- /dev/null +++ b/templates/resources/user_ssh_key.md.tmpl @@ -0,0 +1,41 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Provides a GitHub user's SSH key resource. +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +Provides a GitHub user's SSH key resource. + +This resource allows you to add/remove SSH keys from your user account. + +## Example Usage + +{{tffile "examples/resources/user_ssh_key/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `title` - (Required) A descriptive name for the new key. e.g. `Personal MacBook Air` +- `key` - (Required) The public SSH key to add to your GitHub account. + +## Attributes Reference + +The following attributes are exported: + +- `id` - The ID of the SSH key +- `url` - The URL of the SSH key + +## Import + +SSH keys can be imported using their ID e.g. + +```sh +$ terraform import github_user_ssh_key.example 1234567 +``` diff --git a/templates/resources/workflow_repository_permissions.md.tmpl b/templates/resources/workflow_repository_permissions.md.tmpl new file mode 100644 index 0000000000..8e7d7295bd --- /dev/null +++ b/templates/resources/workflow_repository_permissions.md.tmpl @@ -0,0 +1,33 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}} +description: |- + Enables and manages Workflow permissions for a GitHub repository +--- + +{{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. + +For example, the {{ .SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} + +# {{.Name}} ({{.Type}}) + +This resource allows you to manage GitHub Workflow permissions for a given repository. You must have admin access to a repository to use this resource. + +## Example Usage + +{{tffile "examples/resources/workflow_repository_permissions/example_1.tf"}} + +## Argument Reference + +The following arguments are supported: + +- `repository` - (Required) The GitHub repository +- `default_workflow_permissions` - (Optional) The default workflow permissions granted to the GITHUB_TOKEN when running workflows. Can be one of: `read` or `write`. +- `can_approve_pull_request_reviews` - (Optional) Whether GitHub Actions can approve pull requests. Enabling this can be a security risk. + +## Import + +This resource can be imported using the name of the GitHub repository: + +```sh +$ terraform import github_workflow_repository_permissions.test my-repository +``` diff --git a/tools.go b/tools.go deleted file mode 100644 index 70ecb83d8e..0000000000 --- a/tools.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build tools - -package main - -import ( - _ "github.com/client9/misspell/cmd/misspell" - _ "github.com/golangci/golangci-lint/v2/cmd/golangci-lint" -) diff --git a/vendor/4d63.com/gocheckcompilerdirectives/LICENSE b/vendor/4d63.com/gocheckcompilerdirectives/LICENSE deleted file mode 100644 index 3f12625b06..0000000000 --- a/vendor/4d63.com/gocheckcompilerdirectives/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 Leigh McCulloch - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/4d63.com/gocheckcompilerdirectives/checkcompilerdirectives/checkcompilerdirectives.go b/vendor/4d63.com/gocheckcompilerdirectives/checkcompilerdirectives/checkcompilerdirectives.go deleted file mode 100644 index e719155d96..0000000000 --- a/vendor/4d63.com/gocheckcompilerdirectives/checkcompilerdirectives/checkcompilerdirectives.go +++ /dev/null @@ -1,106 +0,0 @@ -package checkcompilerdirectives - -import ( - "strings" - - "golang.org/x/tools/go/analysis" -) - -func Analyzer() *analysis.Analyzer { - return &analysis.Analyzer{ - Name: "gocheckcompilerdirectives", - Doc: "Checks that go compiler directive comments (//go:) are valid.", - Run: run, - } -} - -func run(pass *analysis.Pass) (interface{}, error) { - for _, file := range pass.Files { - for _, group := range file.Comments { - for _, comment := range group.List { - text := comment.Text - if !strings.HasPrefix(text, "//") { - continue - } - start := 2 - spaces := 0 - for _, c := range text[start:] { - if c == ' ' { - spaces++ - continue - } - break - } - start += spaces - if !strings.HasPrefix(text[start:], "go:") { - continue - } - start += 3 - end := strings.Index(text[start:], " ") - if end == -1 { - continue - } - directive := text[start : start+end] - if len(directive) == 0 { - continue - } - prefix := text[:start+end] - // Leading whitespace will cause the go directive to be ignored - // by the compiler with no error, causing it not to work. This - // is an easy mistake. - if spaces > 0 { - pass.ReportRangef(comment, "compiler directive contains space: %s", prefix) - } - // If the directive is unknown it will be ignored by the - // compiler with no error. This is an easy mistake to make, - // especially if you typo a directive. - if !isKnown(directive) { - pass.ReportRangef(comment, "compiler directive unrecognized: %s", prefix) - } - } - } - } - return nil, nil -} - -func isKnown(directive string) bool { - for _, k := range known { - if directive == k { - return true - } - } - return false -} - -// Found by running the following command on the source of go. -// git grep -o -E -h '//go:[a-z_-]+' -- ':!**/*_test.go' ':!test/' ':!**/testdata/**' | sort -u -// See https://pkg.go.dev/cmd/compile@go1.24#hdr-Compiler_Directives -var known = []string{ - "build", - "cgo_dynamic_linker", - "cgo_export_dynamic", - "cgo_export_static", - "cgo_import_dynamic", - "cgo_import_static", - "cgo_ldflag", - "cgo_unsafe_args", - "debug", - "embed", - "generate", - "linkname", - "nocheckptr", - "noescape", - "noinline", - "nointerface", - "norace", - "nosplit", - "notinheap", - "nowritebarrier", - "nowritebarrierrec", - "systemstack", - "uintptrescapes", - "uintptrkeepalive", - "wasmimport", - "wasmexport", - "yeswritebarrierrec", -} diff --git a/vendor/4d63.com/gochecknoglobals/LICENSE b/vendor/4d63.com/gochecknoglobals/LICENSE deleted file mode 100644 index c401e6608d..0000000000 --- a/vendor/4d63.com/gochecknoglobals/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2018 Leigh McCulloch - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/4d63.com/gochecknoglobals/checknoglobals/check_no_globals.go b/vendor/4d63.com/gochecknoglobals/checknoglobals/check_no_globals.go deleted file mode 100644 index c17c6acca6..0000000000 --- a/vendor/4d63.com/gochecknoglobals/checknoglobals/check_no_globals.go +++ /dev/null @@ -1,186 +0,0 @@ -package checknoglobals - -import ( - "fmt" - "go/ast" - "go/token" - "go/types" - "strings" - - "golang.org/x/tools/go/analysis" -) - -// allowedExpression is a struct representing packages and methods that will -// be an allowed combination to use as a global variable, f.ex. Name `regexp` -// and SelName `MustCompile`. -type allowedExpression struct { - Name string - SelName string -} - -const Doc = `check that no global variables exist - -This analyzer checks for global variables and errors on any found. - -A global variable is a variable declared in package scope and that can be read -and written to by any function within the package. Global variables can cause -side effects which are difficult to keep track of. A code in one function may -change the variables state while another unrelated chunk of code may be -effected by it.` - -// Analyzer provides an Analyzer that checks that there are no global -// variables, except for errors and variables containing regular -// expressions. -func Analyzer() *analysis.Analyzer { - return &analysis.Analyzer{ - Name: "gochecknoglobals", - Doc: Doc, - Run: checkNoGlobals, - RunDespiteErrors: true, - } -} - -func isAllowed(cm ast.CommentMap, v ast.Node, ti *types.Info) bool { - switch i := v.(type) { - case *ast.GenDecl: - return hasEmbedComment(cm, i) - case *ast.Ident: - return i.Name == "_" || i.Name == "version" || isError(i, ti) || identHasEmbedComment(cm, i) - case *ast.CallExpr: - if expr, ok := i.Fun.(*ast.SelectorExpr); ok { - return isAllowedSelectorExpression(expr) - } - case *ast.CompositeLit: - if expr, ok := i.Type.(*ast.SelectorExpr); ok { - return isAllowedSelectorExpression(expr) - } - } - - return false -} - -func isAllowedSelectorExpression(v *ast.SelectorExpr) bool { - x, ok := v.X.(*ast.Ident) - if !ok { - return false - } - - allowList := []allowedExpression{ - {Name: "regexp", SelName: "MustCompile"}, - } - - for _, i := range allowList { - if x.Name == i.Name && v.Sel.Name == i.SelName { - return true - } - } - - return false -} - -// isError reports whether the AST identifier looks like -// an error and implements the error interface. -func isError(i *ast.Ident, ti *types.Info) bool { - return looksLikeError(i) && implementsError(i, ti) -} - -// looksLikeError returns true if the AST identifier starts -// with 'err' or 'Err', or false otherwise. -func looksLikeError(i *ast.Ident) bool { - prefix := "err" - if i.IsExported() { - prefix = "Err" - } - return strings.HasPrefix(i.Name, prefix) -} - -// implementsError reports whether the AST identifier -// implements the error interface. -func implementsError(i *ast.Ident, ti *types.Info) bool { - t := ti.TypeOf(i) - et := types.Universe.Lookup("error").Type().Underlying().(*types.Interface) - return types.Implements(t, et) -} - -func identHasEmbedComment(cm ast.CommentMap, i *ast.Ident) bool { - if i.Obj == nil { - return false - } - - spec, ok := i.Obj.Decl.(*ast.ValueSpec) - if !ok { - return false - } - - return hasEmbedComment(cm, spec) -} - -// hasEmbedComment returns true if the AST node has -// a '//go:embed ' comment, or false otherwise. -func hasEmbedComment(cm ast.CommentMap, n ast.Node) bool { - for _, g := range cm[n] { - for _, c := range g.List { - if strings.HasPrefix(c.Text, "//go:embed ") { - return true - } - } - } - return false -} - -func checkNoGlobals(pass *analysis.Pass) (interface{}, error) { - for _, file := range pass.Files { - filename := pass.Fset.Position(file.Pos()).Filename - if !strings.HasSuffix(filename, ".go") { - continue - } - - fileCommentMap := ast.NewCommentMap(pass.Fset, file, file.Comments) - - for _, decl := range file.Decls { - genDecl, ok := decl.(*ast.GenDecl) - if !ok { - continue - } - if genDecl.Tok != token.VAR { - continue - } - if isAllowed(fileCommentMap, genDecl, pass.TypesInfo) { - continue - } - for _, spec := range genDecl.Specs { - valueSpec := spec.(*ast.ValueSpec) - onlyAllowedValues := false - - for _, vn := range valueSpec.Values { - if isAllowed(fileCommentMap, vn, pass.TypesInfo) { - onlyAllowedValues = true - continue - } - - onlyAllowedValues = false - break - } - - if onlyAllowedValues { - continue - } - - for _, vn := range valueSpec.Names { - if isAllowed(fileCommentMap, vn, pass.TypesInfo) { - continue - } - - message := fmt.Sprintf("%s is a global variable", vn.Name) - pass.Report(analysis.Diagnostic{ - Pos: vn.Pos(), - Category: "global", - Message: message, - }) - } - } - } - } - - return nil, nil -} diff --git a/vendor/codeberg.org/chavacava/garif/.gitignore b/vendor/codeberg.org/chavacava/garif/.gitignore deleted file mode 100644 index 5dee1052c2..0000000000 --- a/vendor/codeberg.org/chavacava/garif/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -*.test -*.out -.devcontainer/ \ No newline at end of file diff --git a/vendor/codeberg.org/chavacava/garif/LICENSE b/vendor/codeberg.org/chavacava/garif/LICENSE deleted file mode 100644 index 2bba73fb78..0000000000 --- a/vendor/codeberg.org/chavacava/garif/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2021 Salvador Cavadini - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/codeberg.org/chavacava/garif/README.md b/vendor/codeberg.org/chavacava/garif/README.md deleted file mode 100644 index c1cc80d3bf..0000000000 --- a/vendor/codeberg.org/chavacava/garif/README.md +++ /dev/null @@ -1,52 +0,0 @@ -# garif - -A Go package to create and manipulate SARIF logs. - -SARIF, from _Static Analysis Results Interchange Format_, is a standard JSON-based format for the output of static analysis tools defined and promoted by [OASIS](https://www.oasis-open.org/). - -Current supported version of the standard is [SARIF-v2.1.0](https://docs.oasis-open.org/sarif/sarif/v2.1.0/csprd01/sarif-v2.1.0-csprd01.html -). - -## Usage - -The package provides access to every element of the SARIF model, therefore you are free to manipulate it at every detail. - -The package also provides constructors functions (`New...`) and decorators methods (`With...`) that simplify the creation of SARIF files for common use cases. - -Using these constructors and decorators we can easily create the example SARIF file of the [Microsoft SARIF pages](https://github.com/microsoft/sarif-tutorials/blob/master/docs/1-Introduction.md) - - -```go -import to `github.com/chavacava/garif` - -// ... - -rule := garif.NewRule("no-unused-vars"). - WithHelpUri("https://eslint.org/docs/rules/no-unused-vars"). - WithShortDescription("disallow unused variables"). - WithProperties("category", "Variables") - -driver := garif.NewDriver("ESLint"). - WithInformationUri("https://eslint.org"). - WithRules(rule) - -run := garif.NewRun(NewTool(driver)). - WithArtifactsURIs("file:///C:/dev/sarif/sarif-tutorials/samples/Introduction/simple-example.js") - -run.WithResult(rule.Id, "'x' is assigned a value but never used.", "file:///C:/dev/sarif/sarif-tutorials/samples/Introduction/simple-example.js", 1, 5) - -logFile := garif.NewLogFile([]*Run{run}, Version210) - -logFile.Write(os.Stdout) -``` - -## Why this package? -This package was initiated during my works on adding to [`revive`](https://github.com/mgechev/revive) a SARIF output formatter. -I've tried to use [go-sarif](https://github.com/owenrumney/go-sarif) by [Owen Rumney](https://github.com/owenrumney) but it is too focused in the use case of the static analyzer [tfsec](https://tfsec.dev) so I've decided to create a package flexible enough to generate SARIF files in broader cases. - -## More information about SARIF -For more information about SARIF, you can visit the [Oasis Open](https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=sarif) site. - - -## Contributing -Of course, contributions are welcome! \ No newline at end of file diff --git a/vendor/codeberg.org/chavacava/garif/constructors.go b/vendor/codeberg.org/chavacava/garif/constructors.go deleted file mode 100644 index 8910e396e9..0000000000 --- a/vendor/codeberg.org/chavacava/garif/constructors.go +++ /dev/null @@ -1,338 +0,0 @@ -package garif - -// NewAddress creates a valid Address -func NewAddress() *Address { - return &Address{} -} - -// NewArtifact creates a valid Artifact -func NewArtifact() *Artifact { - return &Artifact{} -} - -// NewArtifactChange creates a valid ArtifactChange -func NewArtifactChange(location *ArtifactLocation, replacements ...*Replacement) *ArtifactChange { - return &ArtifactChange{ - ArtifactLocation: location, - Replacements: replacements, - } -} - -// NewArtifactContent creates a valid ArtifactContent -func NewArtifactContent() *ArtifactContent { - return &ArtifactContent{} -} - -// NewArtifactLocation creates a valid ArtifactLocation -func NewArtifactLocation() *ArtifactLocation { - return &ArtifactLocation{} -} - -// NewAttachment creates a valid Attachment -func NewAttachment(location *ArtifactLocation) *Attachment { - return &Attachment{ArtifactLocation: location} -} - -// NewCodeFlow creates a valid CodeFlow -func NewCodeFlow(threadFlows ...*ThreadFlow) *CodeFlow { - return &CodeFlow{ThreadFlows: threadFlows} -} - -// NewConfigurationOverride creates a valid ConfigurationOverride -func NewConfigurationOverride(configuration *ReportingConfiguration, descriptor *ReportingDescriptorReference) *ConfigurationOverride { - return &ConfigurationOverride{ - Configuration: configuration, - Descriptor: descriptor, - } -} - -// NewConversion creates a valid Conversion -func NewConversion(tool *Tool) *Conversion { - return &Conversion{Tool: tool} -} - -// NewEdge creates a valid Edge -func NewEdge(id, sourceNodeId, targetNodeId string) *Edge { - return &Edge{ - Id: id, - SourceNodeId: sourceNodeId, - TargetNodeId: targetNodeId, - } -} - -// NewEdgeTraversal creates a valid EdgeTraversal -func NewEdgeTraversal(edgeId string) *EdgeTraversal { - return &EdgeTraversal{ - EdgeId: edgeId, - } -} - -// NewException creates a valid Exception -func NewException() *Exception { - return &Exception{} -} - -// NewExternalProperties creates a valid ExternalProperties -func NewExternalProperties() *ExternalProperties { - return &ExternalProperties{} -} - -// NewExternalPropertyFileReference creates a valid ExternalPropertyFileReference -func NewExternalPropertyFileReference() *ExternalPropertyFileReference { - return &ExternalPropertyFileReference{} -} - -// NewExternalPropertyFileReferences creates a valid ExternalPropertyFileReferences -func NewExternalPropertyFileReferences() *ExternalPropertyFileReferences { - return &ExternalPropertyFileReferences{} -} - -// NewFix creates a valid Fix -func NewFix(artifactChanges ...*ArtifactChange) *Fix { - return &Fix{ - ArtifactChanges: artifactChanges, - } -} - -// NewGraph creates a valid Graph -func NewGraph() *Graph { - return &Graph{} -} - -// NewGraphTraversal creates a valid GraphTraversal -func NewGraphTraversal() *GraphTraversal { - return &GraphTraversal{} -} - -// NewInvocation creates a valid Invocation -func NewInvocation(executionSuccessful bool) *Invocation { - return &Invocation{ - ExecutionSuccessful: executionSuccessful, - } -} - -// NewLocation creates a valid Location -func NewLocation() *Location { - return &Location{} -} - -// NewLocationRelationship creates a valid LocationRelationship -func NewLocationRelationship(target int) *LocationRelationship { - return &LocationRelationship{ - Target: target, - } -} - -type LogFileVersion string - -const Version210 LogFileVersion = "2.1.0" - -// NewLogFile creates a valid LogFile -func NewLogFile(runs []*Run, version LogFileVersion) *LogFile { - return &LogFile{ - Runs: runs, - Version: version, - } -} - -// NewLogicalLocation creates a valid LogicalLocation -func NewLogicalLocation() *LogicalLocation { - return &LogicalLocation{} -} - -// NewMessage creates a valid Message -func NewMessage() *Message { - return &Message{} -} - -// NewMessageFromText creates a valid Message with the given text -func NewMessageFromText(text string) *Message { - return &Message{ - Text: text, - } -} - -// NewMultiformatMessageString creates a valid MultiformatMessageString -func NewMultiformatMessageString(text string) *MultiformatMessageString { - return &MultiformatMessageString{ - Text: text, - } -} - -// NewNode creates a valid Node -func NewNode(id string) *Node { - return &Node{ - Id: id, - } -} - -// NewNotification creates a valid Notification -func NewNotification(message *Message) *Notification { - return &Notification{ - Message: message, - } -} - -// NewPhysicalLocation creates a valid PhysicalLocation -func NewPhysicalLocation() *PhysicalLocation { - return &PhysicalLocation{} -} - -// NewPropertyBag creates a valid PropertyBag -func NewPropertyBag() *PropertyBag { - return &PropertyBag{} -} - -// NewRectangle creates a valid Rectangle -func NewRectangle() *Rectangle { - return &Rectangle{} -} - -// NewRegion creates a valid Region -func NewRegion() *Region { - return &Region{} -} - -// NewReplacement creates a valid Replacement -func NewReplacement(deletedRegion *Region) *Replacement { - return &Replacement{ - DeletedRegion: deletedRegion, - } -} - -// NewReportingConfiguration creates a valid ReportingConfiguration -func NewReportingConfiguration() *ReportingConfiguration { - return &ReportingConfiguration{} -} - -// NewReportingDescriptor creates a valid ReportingDescriptor -func NewReportingDescriptor(id string) *ReportingDescriptor { - return &ReportingDescriptor{ - Id: id, - } -} - -// NewRule is an alias for NewReportingDescriptor -func NewRule(id string) *ReportingDescriptor { - return NewReportingDescriptor(id) -} - -// NewReportingDescriptorReference creates a valid ReportingDescriptorReference -func NewReportingDescriptorReference() *ReportingDescriptorReference { - return &ReportingDescriptorReference{} -} - -// NewReportingDescriptorRelationship creates a valid ReportingDescriptorRelationship -func NewReportingDescriptorRelationship(target *ReportingDescriptorReference) *ReportingDescriptorRelationship { - return &ReportingDescriptorRelationship{ - Target: target, - } -} - -// NewResult creates a valid Result -func NewResult(message *Message) *Result { - return &Result{ - Message: message, - } -} - -// NewResultProvenance creates a valid ResultProvenance -func NewResultProvenance() *ResultProvenance { - return &ResultProvenance{} -} - -// NewRun creates a valid Run -func NewRun(tool *Tool) *Run { - return &Run{ - Tool: tool, - } -} - -// NewRunAutomationDetails creates a valid RunAutomationDetails -func NewRunAutomationDetails() *RunAutomationDetails { - return &RunAutomationDetails{} -} - -// New creates a valid -func NewSpecialLocations() *SpecialLocations { - return &SpecialLocations{} -} - -// NewStack creates a valid Stack -func NewStack(frames ...*StackFrame) *Stack { - return &Stack{ - Frames: frames, - } -} - -// NewStackFrame creates a valid StackFrame -func NewStackFrame() *StackFrame { - return &StackFrame{} -} - -// NewSuppression creates a valid Suppression -func NewSuppression(kind string) *Suppression { - return &Suppression{ - Kind: kind, - } -} - -// NewThreadFlow creates a valid ThreadFlow -func NewThreadFlow(locations []*ThreadFlowLocation) *ThreadFlow { - return &ThreadFlow{ - Locations: locations, - } -} - -// NewThreadFlowLocation creates a valid ThreadFlowLocation -func NewThreadFlowLocation() *ThreadFlowLocation { - return &ThreadFlowLocation{} -} - -// NewTool creates a valid Tool -func NewTool(driver *ToolComponent) *Tool { - return &Tool{ - Driver: driver, - } -} - -// NewToolComponent creates a valid ToolComponent -func NewToolComponent(name string) *ToolComponent { - return &ToolComponent{ - Name: name, - } -} - -// NewDriver is an alias for NewToolComponent -func NewDriver(name string) *ToolComponent { - return NewToolComponent(name) -} - -// NewToolComponentReference creates a valid ToolComponentReference -func NewToolComponentReference() *ToolComponentReference { - return &ToolComponentReference{} -} - -// NewTranslationMetadata creates a valid TranslationMetadata -func NewTranslationMetadata(name string) *TranslationMetadata { - return &TranslationMetadata{ - Name: name, - } -} - -// NewVersionControlDetails creates a valid VersionControlDetails -func NewVersionControlDetails(repositoryUri string) *VersionControlDetails { - return &VersionControlDetails{ - RepositoryUri: repositoryUri, - } -} - -// NewWebRequest creates a valid WebRequest -func NewWebRequest() *WebRequest { - return &WebRequest{} -} - -// NewWebResponse creates a valid WebResponse -func NewWebResponse() *WebResponse { - return &WebResponse{} -} diff --git a/vendor/codeberg.org/chavacava/garif/decorators.go b/vendor/codeberg.org/chavacava/garif/decorators.go deleted file mode 100644 index 00b599fb82..0000000000 --- a/vendor/codeberg.org/chavacava/garif/decorators.go +++ /dev/null @@ -1,94 +0,0 @@ -package garif - -// WithLineColumn sets a physical location with the given line and column -func (l *Location) WithLineColumn(line, column int) *Location { - if l.PhysicalLocation == nil { - l.PhysicalLocation = NewPhysicalLocation() - } - - l.PhysicalLocation.Region = NewRegion() - l.PhysicalLocation.Region.StartLine = line - l.PhysicalLocation.Region.StartColumn = column - - return l -} - -// WithURI sets a physical location with the given URI -func (l *Location) WithURI(uri string) *Location { - if l.PhysicalLocation == nil { - l.PhysicalLocation = NewPhysicalLocation() - } - - l.PhysicalLocation.ArtifactLocation = NewArtifactLocation() - l.PhysicalLocation.ArtifactLocation.Uri = uri - - return l -} - -// WithKeyValue sets (overwrites) the value of the given key -func (b PropertyBag) WithKeyValue(key string, value interface{}) PropertyBag { - b[key] = value - return b -} - -// WithHelpUri sets the help URI for this ReportingDescriptor -func (r *ReportingDescriptor) WithHelpUri(uri string) *ReportingDescriptor { - r.HelpUri = uri - return r -} - -// WithProperties adds the key & value to the properties of this ReportingDescriptor -func (r *ReportingDescriptor) WithProperties(key string, value interface{}) *ReportingDescriptor { - if r.Properties == nil { - r.Properties = NewPropertyBag() - } - - r.Properties.WithKeyValue(key, value) - - return r -} - -// WithArtifactsURIs adds the given URI as artifacts of this Run -func (r *Run) WithArtifactsURIs(uris ...string) *Run { - if r.Artifacts == nil { - r.Artifacts = []*Artifact{} - } - - for _, uri := range uris { - a := NewArtifact() - a.Location = NewArtifactLocation() - a.Location.Uri = uri - r.Artifacts = append(r.Artifacts, a) - } - - return r -} - -// WithResult adds a result to this Run -func (r *Run) WithResult(ruleId string, message string, uri string, line int, column int) *Run { - if r.Results == nil { - r.Results = []*Result{} - } - - msg := NewMessage() - msg.Text = message - result := NewResult(msg) - location := NewLocation().WithURI(uri).WithLineColumn(line, column) - - result.Locations = append(result.Locations, location) - result.RuleId = ruleId - r.Results = append(r.Results, result) - return r -} - -// WithInformationUri sets the information URI -func (t *ToolComponent) WithInformationUri(uri string) *ToolComponent { - t.InformationUri = uri - return t -} - -// WithRules sets (overwrites) the rules -func (t *ToolComponent) WithRules(rules ...*ReportingDescriptor) *ToolComponent { - t.Rules = rules - return t -} diff --git a/vendor/codeberg.org/chavacava/garif/doc.go b/vendor/codeberg.org/chavacava/garif/doc.go deleted file mode 100644 index 5ac5a156ab..0000000000 --- a/vendor/codeberg.org/chavacava/garif/doc.go +++ /dev/null @@ -1,11 +0,0 @@ -// Package garif defines all the Go structures required to model a SARIF log file. -// These structures were created using the JSON-schema sarif-schema-2.1.0.json of SARIF logfiles -// available at https://github.com/oasis-tcs/sarif-spec/tree/master/Schemata. -// -// The package provides constructors for all structures (see constructors.go) These constructors -// ensure that the returned structure instantiation is valid with respect to the JSON schema and -// should be used in place of plain structure instantiation. -// The root structure is LogFile. -// -// The package provides utility decorators for the most commonly used structures (see decorators.go) -package garif diff --git a/vendor/codeberg.org/chavacava/garif/enums.go b/vendor/codeberg.org/chavacava/garif/enums.go deleted file mode 100644 index dea2daf131..0000000000 --- a/vendor/codeberg.org/chavacava/garif/enums.go +++ /dev/null @@ -1,41 +0,0 @@ -package garif - -type ResultKind string - -// declare JSON values -const ( - _pass ResultKind = "pass" - _open ResultKind = "open" - _informational ResultKind = "informational" - _notApplicable ResultKind = "notApplicable" - _review ResultKind = "review" - _fail ResultKind = "fail" -) - -// create public visible constants with a namespace as enums -const ( - ResultKind_Pass ResultKind = _pass - ResultKind_Open ResultKind = _open - ResultKind_Informational ResultKind = _informational - ResultKind_NotApplicable ResultKind = _notApplicable - ResultKind_Review ResultKind = _review - ResultKind_Fail ResultKind = _fail -) - -type ResultLevel string - -// declare JSON values -const ( - _warning ResultLevel = "warning" - _error ResultLevel = "error" - _note ResultLevel = "note" - _none ResultLevel = "none" -) - -// create public visible constants with a namespace as enums -const ( - ResultLevel_Warning ResultLevel = _warning - ResultLevel_Error ResultLevel = _error - ResultLevel_Note ResultLevel = _note - ResultLevel_None ResultLevel = _none -) diff --git a/vendor/codeberg.org/chavacava/garif/io.go b/vendor/codeberg.org/chavacava/garif/io.go deleted file mode 100644 index ce5719c96d..0000000000 --- a/vendor/codeberg.org/chavacava/garif/io.go +++ /dev/null @@ -1,26 +0,0 @@ -package garif - -import ( - "encoding/json" - "io" -) - -// Write writes the JSON -func (l *LogFile) Write(w io.Writer) error { - marshal, err := json.Marshal(l) - if err != nil { - return err - } - _, err = w.Write(marshal) - return err -} - -// PrettyWrite writes indented JSON -func (l *LogFile) PrettyWrite(w io.Writer) error { - marshal, err := json.MarshalIndent(l, "", " ") - if err != nil { - return err - } - _, err = w.Write(marshal) - return err -} diff --git a/vendor/codeberg.org/chavacava/garif/models.go b/vendor/codeberg.org/chavacava/garif/models.go deleted file mode 100644 index ed18b04a59..0000000000 --- a/vendor/codeberg.org/chavacava/garif/models.go +++ /dev/null @@ -1,1486 +0,0 @@ -package garif - -// Address A physical or virtual address, or a range of addresses, in an 'addressable region' (memory or a binary file). -type Address struct { - - // The address expressed as a byte offset from the start of the addressable region. - AbsoluteAddress int `json:"absoluteAddress,omitempty"` - - // A human-readable fully qualified name that is associated with the address. - FullyQualifiedName string `json:"fullyQualifiedName,omitempty"` - - // The index within run.addresses of the cached object for this address. - Index int `json:"index,omitempty"` - - // An open-ended string that identifies the address kind. - // 'data', 'function', 'header','instruction', 'module', 'page', 'section', - // 'segment', 'stack', 'stackFrame', 'table' are well-known values. - Kind string `json:"kind,omitempty"` - - // The number of bytes in this range of addresses. - Length int `json:"length,omitempty"` - - // A name that is associated with the address, e.g., '.text'. - Name string `json:"name,omitempty"` - - // The byte offset of this address from the absolute or relative address of the parent object. - OffsetFromParent int `json:"offsetFromParent,omitempty"` - - // The index within run.addresses of the parent object. - ParentIndex int `json:"parentIndex,omitempty"` - - // Key/value pairs that provide additional information about the address. - Properties *PropertyBag `json:"properties,omitempty"` - - // The address expressed as a byte offset from the absolute address of the top-most parent object. - RelativeAddress int `json:"relativeAddress,omitempty"` -} - -// Artifact A single artifact. In some cases, this artifact might be nested within another artifact. -type Artifact struct { - - // The contents of the artifact. - Contents *ArtifactContent `json:"contents,omitempty"` - - // A short description of the artifact. - Description *Message `json:"description,omitempty"` - - // Specifies the encoding for an artifact object that refers to a text file. - Encoding string `json:"encoding,omitempty"` - - // A dictionary, each of whose keys is the name of a hash function and each of whose values is - // the hashed value of the artifact produced by the specified hash function. - Hashes map[string]string `json:"hashes,omitempty"` - - // The Coordinated Universal Time (UTC) date and time at which the artifact was most recently modified. - // See "Date/time properties" in the SARIF spec for the required format. - LastModifiedTimeUtc string `json:"lastModifiedTimeUtc,omitempty"` - - // The length of the artifact in bytes. - Length int `json:"length,omitempty"` - - // The location of the artifact. - Location *ArtifactLocation `json:"location,omitempty"` - - // The MIME type (RFC 2045) of the artifact. - MimeType string `json:"mimeType,omitempty"` - - // The offset in bytes of the artifact within its containing artifact. - Offset int `json:"offset,omitempty"` - - // Identifies the index of the immediate parent of the artifact, if this artifact is nested. - ParentIndex int `json:"parentIndex,omitempty"` - - // Key/value pairs that provide additional information about the artifact. - Properties *PropertyBag `json:"properties,omitempty"` - - // The role or roles played by the artifact in the analysis. - Roles []interface{} `json:"roles,omitempty"` - - // Specifies the source language for any artifact object that refers to a text file that contains source code. - SourceLanguage string `json:"sourceLanguage,omitempty"` -} - -// ArtifactChange A change to a single artifact. -type ArtifactChange struct { - - // The location of the artifact to change. - ArtifactLocation *ArtifactLocation `json:"artifactLocation"` - - // Key/value pairs that provide additional information about the change. - Properties *PropertyBag `json:"properties,omitempty"` - - // An array of replacement objects, each of which represents the replacement of a single region in a - // single artifact specified by 'artifactLocation'. - Replacements []*Replacement `json:"replacements"` -} - -// ArtifactContent Represents the contents of an artifact. -type ArtifactContent struct { - - // MIME Base64-encoded content from a binary artifact, or from a text artifact in its original encoding. - Binary string `json:"binary,omitempty"` - - // Key/value pairs that provide additional information about the artifact content. - Properties *PropertyBag `json:"properties,omitempty"` - - // An alternate rendered representation of the artifact (e.g., a decompiled representation of a binary region). - Rendered *MultiformatMessageString `json:"rendered,omitempty"` - - // UTF-8-encoded content from a text artifact. - Text string `json:"text,omitempty"` -} - -// ArtifactLocation Specifies the location of an artifact. -type ArtifactLocation struct { - - // A short description of the artifact location. - Description *Message `json:"description,omitempty"` - - // The index within the run artifacts array of the artifact object associated with the artifact location. - Index int `json:"index,omitempty"` - - // Key/value pairs that provide additional information about the artifact location. - Properties *PropertyBag `json:"properties,omitempty"` - - // A string containing a valid relative or absolute URI. - Uri string `json:"uri,omitempty"` - - // A string which indirectly specifies the absolute URI with respect to which a relative URI in the "uri" property is interpreted. - UriBaseId string `json:"uriBaseId,omitempty"` -} - -// Attachment An artifact relevant to a result. -type Attachment struct { - - // The location of the attachment. - ArtifactLocation *ArtifactLocation `json:"artifactLocation"` - - // A message describing the role played by the attachment. - Description *Message `json:"description,omitempty"` - - // Key/value pairs that provide additional information about the attachment. - Properties *PropertyBag `json:"properties,omitempty"` - - // An array of rectangles specifying areas of interest within the image. - Rectangles []*Rectangle `json:"rectangles,omitempty"` - - // An array of regions of interest within the attachment. - Regions []*Region `json:"regions,omitempty"` -} - -// CodeFlow A set of threadFlows which together describe a pattern of code execution relevant to detecting a result. -type CodeFlow struct { - - // A message relevant to the code flow. - Message *Message `json:"message,omitempty"` - - // Key/value pairs that provide additional information about the code flow. - Properties *PropertyBag `json:"properties,omitempty"` - - // An array of one or more unique threadFlow objects, each of which describes the progress of a program - // through a thread of execution. - ThreadFlows []*ThreadFlow `json:"threadFlows"` -} - -// ConfigurationOverride Information about how a specific rule or notification was reconfigured at runtime. -type ConfigurationOverride struct { - - // Specifies how the rule or notification was configured during the scan. - Configuration *ReportingConfiguration `json:"configuration"` - - // A reference used to locate the descriptor whose configuration was overridden. - Descriptor *ReportingDescriptorReference `json:"descriptor"` - - // Key/value pairs that provide additional information about the configuration override. - Properties *PropertyBag `json:"properties,omitempty"` -} - -// Conversion Describes how a converter transformed the output of a static analysis tool from the analysis tool's native output format into the SARIF format. -type Conversion struct { - - // The locations of the analysis tool's per-run log files. - AnalysisToolLogFiles []*ArtifactLocation `json:"analysisToolLogFiles,omitempty"` - - // An invocation object that describes the invocation of the converter. - Invocation *Invocation `json:"invocation,omitempty"` - - // Key/value pairs that provide additional information about the conversion. - Properties *PropertyBag `json:"properties,omitempty"` - - // A tool object that describes the converter. - Tool *Tool `json:"tool"` -} - -// Edge Represents a directed edge in a graph. -type Edge struct { - - // A string that uniquely identifies the edge within its graph. - Id string `json:"id"` - - // A short description of the edge. - Label *Message `json:"label,omitempty"` - - // Key/value pairs that provide additional information about the edge. - Properties *PropertyBag `json:"properties,omitempty"` - - // Identifies the source node (the node at which the edge starts). - SourceNodeId string `json:"sourceNodeId"` - - // Identifies the target node (the node at which the edge ends). - TargetNodeId string `json:"targetNodeId"` -} - -// EdgeTraversal Represents the traversal of a single edge during a graph traversal. -type EdgeTraversal struct { - - // Identifies the edge being traversed. - EdgeId string `json:"edgeId"` - - // The values of relevant expressions after the edge has been traversed. - FinalState map[string]*MultiformatMessageString `json:"finalState,omitempty"` - - // A message to display to the user as the edge is traversed. - Message *Message `json:"message,omitempty"` - - // Key/value pairs that provide additional information about the edge traversal. - Properties *PropertyBag `json:"properties,omitempty"` - - // The number of edge traversals necessary to return from a nested graph. - StepOverEdgeCount int `json:"stepOverEdgeCount,omitempty"` -} - -// Exception Describes a runtime exception encountered during the execution of an analysis tool. -type Exception struct { - - // An array of exception objects each of which is considered a cause of this exception. - InnerExceptions []*Exception `json:"innerExceptions,omitempty"` - - // A string that identifies the kind of exception, for example, the fully qualified type name of an object that was thrown, or the symbolic name of a signal. - Kind string `json:"kind,omitempty"` - - // A message that describes the exception. - Message string `json:"message,omitempty"` - - // Key/value pairs that provide additional information about the exception. - Properties *PropertyBag `json:"properties,omitempty"` - - // The sequence of function calls leading to the exception. - Stack *Stack `json:"stack,omitempty"` -} - -// ExternalProperties The top-level element of an external property file. -type ExternalProperties struct { - - // Addresses that will be merged with a separate run. - Addresses []*Address `json:"addresses,omitempty"` - - // An array of artifact objects that will be merged with a separate run. - Artifacts []*Artifact `json:"artifacts,omitempty"` - - // A conversion object that will be merged with a separate run. - Conversion *Conversion `json:"conversion,omitempty"` - - // The analysis tool object that will be merged with a separate run. - Driver *ToolComponent `json:"driver,omitempty"` - - // Tool extensions that will be merged with a separate run. - Extensions []*ToolComponent `json:"extensions,omitempty"` - - // Key/value pairs that provide additional information that will be merged with a separate run. - ExternalizedProperties *PropertyBag `json:"externalizedProperties,omitempty"` - - // An array of graph objects that will be merged with a separate run. - Graphs []*Graph `json:"graphs,omitempty"` - - // A stable, unique identifier for this external properties object, in the form of a GUID. - Guid string `json:"guid,omitempty"` - - // Describes the invocation of the analysis tool that will be merged with a separate run. - Invocations []*Invocation `json:"invocations,omitempty"` - - // An array of logical locations such as namespaces, types or functions that will be merged with a separate run. - LogicalLocations []*LogicalLocation `json:"logicalLocations,omitempty"` - - // Tool policies that will be merged with a separate run. - Policies []*ToolComponent `json:"policies,omitempty"` - - // Key/value pairs that provide additional information about the external properties. - Properties *PropertyBag `json:"properties,omitempty"` - - // An array of result objects that will be merged with a separate run. - Results []*Result `json:"results,omitempty"` - - // A stable, unique identifier for the run associated with this external properties object, in the form of a GUID. - RunGuid string `json:"runGuid,omitempty"` - - // The URI of the JSON schema corresponding to the version of the external property file format. - Schema string `json:"schema,omitempty"` - - // Tool taxonomies that will be merged with a separate run. - Taxonomies []*ToolComponent `json:"taxonomies,omitempty"` - - // An array of threadFlowLocation objects that will be merged with a separate run. - ThreadFlowLocations []*ThreadFlowLocation `json:"threadFlowLocations,omitempty"` - - // Tool translations that will be merged with a separate run. - Translations []*ToolComponent `json:"translations,omitempty"` - - // The SARIF format version of this external properties object. - Version interface{} `json:"version,omitempty"` - - // Requests that will be merged with a separate run. - WebRequests []*WebRequest `json:"webRequests,omitempty"` - - // Responses that will be merged with a separate run. - WebResponses []*WebResponse `json:"webResponses,omitempty"` -} - -// ExternalPropertyFileReference Contains information that enables a SARIF consumer to locate the external property file that contains the value of an externalized property associated with the run. -type ExternalPropertyFileReference struct { - - // A stable, unique identifier for the external property file in the form of a GUID. - Guid string `json:"guid,omitempty"` - - // A non-negative integer specifying the number of items contained in the external property file. - ItemCount int `json:"itemCount,omitempty"` - - // The location of the external property file. - Location *ArtifactLocation `json:"location,omitempty"` - - // Key/value pairs that provide additional information about the external property file. - Properties *PropertyBag `json:"properties,omitempty"` -} - -// ExternalPropertyFileReferences References to external property files that should be inlined with the content of a root log file. -type ExternalPropertyFileReferences struct { - - // An array of external property files containing run.addresses arrays to be merged with the root log file. - Addresses []*ExternalPropertyFileReference `json:"addresses,omitempty"` - - // An array of external property files containing run.artifacts arrays to be merged with the root log file. - Artifacts []*ExternalPropertyFileReference `json:"artifacts,omitempty"` - - // An external property file containing a run.conversion object to be merged with the root log file. - Conversion *ExternalPropertyFileReference `json:"conversion,omitempty"` - - // An external property file containing a run.driver object to be merged with the root log file. - Driver *ExternalPropertyFileReference `json:"driver,omitempty"` - - // An array of external property files containing run.extensions arrays to be merged with the root log file. - Extensions []*ExternalPropertyFileReference `json:"extensions,omitempty"` - - // An external property file containing a run.properties object to be merged with the root log file. - ExternalizedProperties *ExternalPropertyFileReference `json:"externalizedProperties,omitempty"` - - // An array of external property files containing a run.graphs object to be merged with the root log file. - Graphs []*ExternalPropertyFileReference `json:"graphs,omitempty"` - - // An array of external property files containing run.invocations arrays to be merged with the root log file. - Invocations []*ExternalPropertyFileReference `json:"invocations,omitempty"` - - // An array of external property files containing run.logicalLocations arrays to be merged with the root log file. - LogicalLocations []*ExternalPropertyFileReference `json:"logicalLocations,omitempty"` - - // An array of external property files containing run.policies arrays to be merged with the root log file. - Policies []*ExternalPropertyFileReference `json:"policies,omitempty"` - - // Key/value pairs that provide additional information about the external property files. - Properties *PropertyBag `json:"properties,omitempty"` - - // An array of external property files containing run.results arrays to be merged with the root log file. - Results []*ExternalPropertyFileReference `json:"results,omitempty"` - - // An array of external property files containing run.taxonomies arrays to be merged with the root log file. - Taxonomies []*ExternalPropertyFileReference `json:"taxonomies,omitempty"` - - // An array of external property files containing run.threadFlowLocations arrays to be merged with the root log file. - ThreadFlowLocations []*ExternalPropertyFileReference `json:"threadFlowLocations,omitempty"` - - // An array of external property files containing run.translations arrays to be merged with the root log file. - Translations []*ExternalPropertyFileReference `json:"translations,omitempty"` - - // An array of external property files containing run.requests arrays to be merged with the root log file. - WebRequests []*ExternalPropertyFileReference `json:"webRequests,omitempty"` - - // An array of external property files containing run.responses arrays to be merged with the root log file. - WebResponses []*ExternalPropertyFileReference `json:"webResponses,omitempty"` -} - -// Fix A proposed fix for the problem represented by a result object. -// A fix specifies a set of artifacts to modify. For each artifact, -// it specifies a set of bytes to remove, and provides a set of new bytes to replace them. -type Fix struct { - - // One or more artifact changes that comprise a fix for a result. - ArtifactChanges []*ArtifactChange `json:"artifactChanges"` - - // A message that describes the proposed fix, enabling viewers to present the proposed change to an end user. - Description *Message `json:"description,omitempty"` - - // Key/value pairs that provide additional information about the fix. - Properties *PropertyBag `json:"properties,omitempty"` -} - -// Graph A network of nodes and directed edges that describes some aspect of the -// structure of the code (for example, a call graph). -type Graph struct { - - // A description of the graph. - Description *Message `json:"description,omitempty"` - - // An array of edge objects representing the edges of the graph. - Edges []*Edge `json:"edges,omitempty"` - - // An array of node objects representing the nodes of the graph. - Nodes []*Node `json:"nodes,omitempty"` - - // Key/value pairs that provide additional information about the graph. - Properties *PropertyBag `json:"properties,omitempty"` -} - -// GraphTraversal Represents a path through a graph. -type GraphTraversal struct { - - // A description of this graph traversal. - Description *Message `json:"description,omitempty"` - - // The sequences of edges traversed by this graph traversal. - EdgeTraversals []*EdgeTraversal `json:"edgeTraversals,omitempty"` - - // Values of relevant expressions at the start of the graph traversal that remain constant for the graph traversal. - ImmutableState map[string]*MultiformatMessageString `json:"immutableState,omitempty"` - - // Values of relevant expressions at the start of the graph traversal that may change during graph traversal. - InitialState map[string]*MultiformatMessageString `json:"initialState,omitempty"` - - // Key/value pairs that provide additional information about the graph traversal. - Properties *PropertyBag `json:"properties,omitempty"` - - // The index within the result.graphs to be associated with the result. - ResultGraphIndex int `json:"resultGraphIndex,omitempty"` - - // The index within the run.graphs to be associated with the result. - RunGraphIndex int `json:"runGraphIndex,omitempty"` -} - -// Invocation The runtime environment of the analysis tool run. -type Invocation struct { - - // The account under which the invocation occurred. - Account string `json:"account,omitempty"` - - // An array of strings, containing in order the command line arguments passed to the tool from the operating system. - Arguments []string `json:"arguments,omitempty"` - - // The command line used to invoke the tool. - CommandLine string `json:"commandLine,omitempty"` - - // The Coordinated Universal Time (UTC) date and time at which the invocation ended. See "Date/time properties" in the SARIF spec for the required format. - EndTimeUtc string `json:"endTimeUtc,omitempty"` - - // The environment variables associated with the analysis tool process, expressed as key/value pairs. - EnvironmentVariables map[string]string `json:"environmentVariables,omitempty"` - - // An absolute URI specifying the location of the executable that was invoked. - ExecutableLocation *ArtifactLocation `json:"executableLocation,omitempty"` - - // Specifies whether the tool's execution completed successfully. - ExecutionSuccessful bool `json:"executionSuccessful"` - - // The process exit code. - ExitCode int `json:"exitCode,omitempty"` - - // The reason for the process exit. - ExitCodeDescription string `json:"exitCodeDescription,omitempty"` - - // The name of the signal that caused the process to exit. - ExitSignalName string `json:"exitSignalName,omitempty"` - - // The numeric value of the signal that caused the process to exit. - ExitSignalNumber int `json:"exitSignalNumber,omitempty"` - - // The machine on which the invocation occurred. - Machine string `json:"machine,omitempty"` - - // An array of configurationOverride objects that describe notifications related runtime overrides. - NotificationConfigurationOverrides []*ConfigurationOverride `json:"notificationConfigurationOverrides,omitempty"` - - // The id of the process in which the invocation occurred. - ProcessId int `json:"processId,omitempty"` - - // The reason given by the operating system that the process failed to start. - ProcessStartFailureMessage string `json:"processStartFailureMessage,omitempty"` - - // Key/value pairs that provide additional information about the invocation. - Properties *PropertyBag `json:"properties,omitempty"` - - // The locations of any response files specified on the tool's command line. - ResponseFiles []*ArtifactLocation `json:"responseFiles,omitempty"` - - // An array of configurationOverride objects that describe rules related runtime overrides. - RuleConfigurationOverrides []*ConfigurationOverride `json:"ruleConfigurationOverrides,omitempty"` - - // The Coordinated Universal Time (UTC) date and time at which the invocation started. See "Date/time properties" in the SARIF spec for the required format. - StartTimeUtc string `json:"startTimeUtc,omitempty"` - - // A file containing the standard error stream from the process that was invoked. - Stderr *ArtifactLocation `json:"stderr,omitempty"` - - // A file containing the standard input stream to the process that was invoked. - Stdin *ArtifactLocation `json:"stdin,omitempty"` - - // A file containing the standard output stream from the process that was invoked. - Stdout *ArtifactLocation `json:"stdout,omitempty"` - - // A file containing the interleaved standard output and standard error stream from the process that was invoked. - StdoutStderr *ArtifactLocation `json:"stdoutStderr,omitempty"` - - // A list of conditions detected by the tool that are relevant to the tool's configuration. - ToolConfigurationNotifications []*Notification `json:"toolConfigurationNotifications,omitempty"` - - // A list of runtime conditions detected by the tool during the analysis. - ToolExecutionNotifications []*Notification `json:"toolExecutionNotifications,omitempty"` - - // The working directory for the invocation. - WorkingDirectory *ArtifactLocation `json:"workingDirectory,omitempty"` -} - -// Location A location within a programming artifact. -type Location struct { - - // A set of regions relevant to the location. - Annotations []*Region `json:"annotations,omitempty"` - - // Value that distinguishes this location from all other locations within a single result object. - Id int `json:"id,omitempty"` - - // The logical locations associated with the result. - LogicalLocations []*LogicalLocation `json:"logicalLocations,omitempty"` - - // A message relevant to the location. - Message *Message `json:"message,omitempty"` - - // Identifies the artifact and region. - PhysicalLocation *PhysicalLocation `json:"physicalLocation,omitempty"` - - // Key/value pairs that provide additional information about the location. - Properties *PropertyBag `json:"properties,omitempty"` - - // An array of objects that describe relationships between this location and others. - Relationships []*LocationRelationship `json:"relationships,omitempty"` -} - -// LocationRelationship Information about the relation of one location to another. -type LocationRelationship struct { - - // A description of the location relationship. - Description *Message `json:"description,omitempty"` - - // A set of distinct strings that categorize the relationship. Well-known kinds include 'includes', 'isIncludedBy' and 'relevant'. - Kinds []string `json:"kinds,omitempty"` - - // Key/value pairs that provide additional information about the location relationship. - Properties *PropertyBag `json:"properties,omitempty"` - - // A reference to the related location. - Target int `json:"target"` -} - -// LogFile Static Analysis Results Format (SARIF) Version 2.1.0 JSON Schema. -type LogFile struct { - - // References to external property files that share data between runs. - InlineExternalProperties []*ExternalProperties `json:"inlineExternalProperties,omitempty"` - - // Key/value pairs that provide additional information about the log file. - Properties *PropertyBag `json:"properties,omitempty"` - - // The set of runs contained in this log file. - Runs []*Run `json:"runs"` - - // The URI of the JSON schema corresponding to the version. - Schema string `json:"$schema,omitempty"` - - // The SARIF format version of this log file. - Version interface{} `json:"version"` -} - -// LogicalLocation A logical location of a construct that produced a result. -type LogicalLocation struct { - - // The machine-readable name for the logical location, such as a mangled function name provided by a C++ compiler that encodes calling convention, return type and other details along with the function name. - DecoratedName string `json:"decoratedName,omitempty"` - - // The human-readable fully qualified name of the logical location. - FullyQualifiedName string `json:"fullyQualifiedName,omitempty"` - - // The index within the logical locations array. - Index int `json:"index,omitempty"` - - // The type of construct this logical location component refers to. Should be one of 'function', 'member', 'module', 'namespace', 'parameter', 'resource', 'returnType', 'type', 'variable', 'object', 'array', 'property', 'value', 'element', 'text', 'attribute', 'comment', 'declaration', 'dtd' or 'processingInstruction', if any of those accurately describe the construct. - Kind string `json:"kind,omitempty"` - - // Identifies the construct in which the result occurred. For example, this property might contain the name of a class or a method. - Name string `json:"name,omitempty"` - - // Identifies the index of the immediate parent of the construct in which the result was detected. For example, this property might point to a logical location that represents the namespace that holds a type. - ParentIndex int `json:"parentIndex,omitempty"` - - // Key/value pairs that provide additional information about the logical location. - Properties *PropertyBag `json:"properties,omitempty"` -} - -// Message Encapsulates a message intended to be read by the end user. -type Message struct { - - // An array of strings to substitute into the message string. - Arguments []string `json:"arguments,omitempty"` - - // The identifier for this message. - Id string `json:"id,omitempty"` - - // A Markdown message string. - Markdown string `json:"markdown,omitempty"` - - // Key/value pairs that provide additional information about the message. - Properties *PropertyBag `json:"properties,omitempty"` - - // A plain text message string. - Text string `json:"text,omitempty"` -} - -// MultiformatMessageString A message string or message format string rendered in multiple formats. -type MultiformatMessageString struct { - - // A Markdown message string or format string. - Markdown string `json:"markdown,omitempty"` - - // Key/value pairs that provide additional information about the message. - Properties *PropertyBag `json:"properties,omitempty"` - - // A plain text message string or format string. - Text string `json:"text"` -} - -// Node Represents a node in a graph. -type Node struct { - - // Array of child nodes. - Children []*Node `json:"children,omitempty"` - - // A string that uniquely identifies the node within its graph. - Id string `json:"id"` - - // A short description of the node. - Label *Message `json:"label,omitempty"` - - // A code location associated with the node. - Location *Location `json:"location,omitempty"` - - // Key/value pairs that provide additional information about the node. - Properties *PropertyBag `json:"properties,omitempty"` -} - -// Notification Describes a condition relevant to the tool itself, as opposed to being relevant to a target being analyzed by the tool. -type Notification struct { - - // A reference used to locate the rule descriptor associated with this notification. - AssociatedRule *ReportingDescriptorReference `json:"associatedRule,omitempty"` - - // A reference used to locate the descriptor relevant to this notification. - Descriptor *ReportingDescriptorReference `json:"descriptor,omitempty"` - - // The runtime exception, if any, relevant to this notification. - Exception *Exception `json:"exception,omitempty"` - - // A value specifying the severity level of the notification. - Level interface{} `json:"level,omitempty"` - - // The locations relevant to this notification. - Locations []*Location `json:"locations,omitempty"` - - // A message that describes the condition that was encountered. - Message *Message `json:"message"` - - // Key/value pairs that provide additional information about the notification. - Properties *PropertyBag `json:"properties,omitempty"` - - // The thread identifier of the code that generated the notification. - ThreadId int `json:"threadId,omitempty"` - - // The Coordinated Universal Time (UTC) date and time at which the analysis tool generated the notification. - TimeUtc string `json:"timeUtc,omitempty"` -} - -// PhysicalLocation A physical location relevant to a result. Specifies a reference to a programming artifact together with a range of bytes or characters within that artifact. -type PhysicalLocation struct { - - // The address of the location. - Address *Address `json:"address,omitempty"` - - // The location of the artifact. - ArtifactLocation *ArtifactLocation `json:"artifactLocation,omitempty"` - - // Specifies a portion of the artifact that encloses the region. Allows a viewer to display additional context around the region. - ContextRegion *Region `json:"contextRegion,omitempty"` - - // Key/value pairs that provide additional information about the physical location. - Properties *PropertyBag `json:"properties,omitempty"` - - // Specifies a portion of the artifact. - Region *Region `json:"region,omitempty"` -} - -type PropertyBag map[string]interface{} - -/* -// PropertyBag Key/value pairs that provide additional information about the object. -type PropertyBag struct { - AdditionalProperties map[string]interface{} `json:"-,omitempty"` - - // A set of distinct strings that provide additional information. - Tags []string `json:"tags,omitempty"` -} -*/ -// Rectangle An area within an image. -type Rectangle struct { - - // The Y coordinate of the bottom edge of the rectangle, measured in the image's natural units. - Bottom float64 `json:"bottom,omitempty"` - - // The X coordinate of the left edge of the rectangle, measured in the image's natural units. - Left float64 `json:"left,omitempty"` - - // A message relevant to the rectangle. - Message *Message `json:"message,omitempty"` - - // Key/value pairs that provide additional information about the rectangle. - Properties *PropertyBag `json:"properties,omitempty"` - - // The X coordinate of the right edge of the rectangle, measured in the image's natural units. - Right float64 `json:"right,omitempty"` - - // The Y coordinate of the top edge of the rectangle, measured in the image's natural units. - Top float64 `json:"top,omitempty"` -} - -// Region A region within an artifact where a result was detected. -type Region struct { - - // The length of the region in bytes. - ByteLength int `json:"byteLength,omitempty"` - - // The zero-based offset from the beginning of the artifact of the first byte in the region. - ByteOffset int `json:"byteOffset,omitempty"` - - // The length of the region in characters. - CharLength int `json:"charLength,omitempty"` - - // The zero-based offset from the beginning of the artifact of the first character in the region. - CharOffset int `json:"charOffset,omitempty"` - - // The column number of the character following the end of the region. - EndColumn int `json:"endColumn,omitempty"` - - // The line number of the last character in the region. - EndLine int `json:"endLine,omitempty"` - - // A message relevant to the region. - Message *Message `json:"message,omitempty"` - - // Key/value pairs that provide additional information about the region. - Properties *PropertyBag `json:"properties,omitempty"` - - // The portion of the artifact contents within the specified region. - Snippet *ArtifactContent `json:"snippet,omitempty"` - - // Specifies the source language, if any, of the portion of the artifact specified by the region object. - SourceLanguage string `json:"sourceLanguage,omitempty"` - - // The column number of the first character in the region. - StartColumn int `json:"startColumn,omitempty"` - - // The line number of the first character in the region. - StartLine int `json:"startLine,omitempty"` -} - -// Replacement The replacement of a single region of an artifact. -type Replacement struct { - - // The region of the artifact to delete. - DeletedRegion *Region `json:"deletedRegion"` - - // The content to insert at the location specified by the 'deletedRegion' property. - InsertedContent *ArtifactContent `json:"insertedContent,omitempty"` - - // Key/value pairs that provide additional information about the replacement. - Properties *PropertyBag `json:"properties,omitempty"` -} - -// ReportingConfiguration Information about a rule or notification that can be configured at runtime. -type ReportingConfiguration struct { - - // Specifies whether the report may be produced during the scan. - Enabled bool `json:"enabled,omitempty"` - - // Specifies the failure level for the report. - Level interface{} `json:"level,omitempty"` - - // Contains configuration information specific to a report. - Parameters *PropertyBag `json:"parameters,omitempty"` - - // Key/value pairs that provide additional information about the reporting configuration. - Properties *PropertyBag `json:"properties,omitempty"` - - // Specifies the relative priority of the report. Used for analysis output only. - Rank float64 `json:"rank,omitempty"` -} - -// ReportingDescriptor Metadata that describes a specific report produced by the tool, as part of the analysis it provides or its runtime reporting. -type ReportingDescriptor struct { - - // Default reporting configuration information. - DefaultConfiguration *ReportingConfiguration `json:"defaultConfiguration,omitempty"` - - // An array of unique identifies in the form of a GUID by which this report was known in some previous version of the analysis tool. - DeprecatedGuids []string `json:"deprecatedGuids,omitempty"` - - // An array of stable, opaque identifiers by which this report was known in some previous version of the analysis tool. - DeprecatedIds []string `json:"deprecatedIds,omitempty"` - - // An array of readable identifiers by which this report was known in some previous version of the analysis tool. - DeprecatedNames []string `json:"deprecatedNames,omitempty"` - - // A description of the report. Should, as far as possible, provide details sufficient to enable resolution of any problem indicated by the result. - FullDescription *MultiformatMessageString `json:"fullDescription,omitempty"` - - // A unique identifier for the reporting descriptor in the form of a GUID. - Guid string `json:"guid,omitempty"` - - // Provides the primary documentation for the report, useful when there is no online documentation. - Help *MultiformatMessageString `json:"help,omitempty"` - - // A URI where the primary documentation for the report can be found. - HelpUri string `json:"helpUri,omitempty"` - - // A stable, opaque identifier for the report. - Id string `json:"id"` - - // A set of name/value pairs with arbitrary names. Each value is a multiformatMessageString object, which holds message strings in plain text and (optionally) Markdown format. The strings can include placeholders, which can be used to construct a message in combination with an arbitrary number of additional string arguments. - MessageStrings map[string]*MultiformatMessageString `json:"messageStrings,omitempty"` - - // A report identifier that is understandable to an end user. - Name string `json:"name,omitempty"` - - // Key/value pairs that provide additional information about the report. - Properties *PropertyBag `json:"properties,omitempty"` - - // An array of objects that describe relationships between this reporting descriptor and others. - Relationships []*ReportingDescriptorRelationship `json:"relationships,omitempty"` - - // A concise description of the report. Should be a single sentence that is understandable when visible space is limited to a single line of text. - ShortDescription *MultiformatMessageString `json:"shortDescription,omitempty"` -} - -// ReportingDescriptorReference Information about how to locate a relevant reporting descriptor. -type ReportingDescriptorReference struct { - - // A guid that uniquely identifies the descriptor. - Guid string `json:"guid,omitempty"` - - // The id of the descriptor. - Id string `json:"id,omitempty"` - - // The index into an array of descriptors in toolComponent.ruleDescriptors, toolComponent.notificationDescriptors, or toolComponent.taxonomyDescriptors, depending on context. - Index int `json:"index,omitempty"` - - // Key/value pairs that provide additional information about the reporting descriptor reference. - Properties *PropertyBag `json:"properties,omitempty"` - - // A reference used to locate the toolComponent associated with the descriptor. - ToolComponent *ToolComponentReference `json:"toolComponent,omitempty"` -} - -// ReportingDescriptorRelationship Information about the relation of one reporting descriptor to another. -type ReportingDescriptorRelationship struct { - - // A description of the reporting descriptor relationship. - Description *Message `json:"description,omitempty"` - - // A set of distinct strings that categorize the relationship. Well-known kinds include 'canPrecede', 'canFollow', 'willPrecede', 'willFollow', 'superset', 'subset', 'equal', 'disjoint', 'relevant', and 'incomparable'. - Kinds []string `json:"kinds,omitempty"` - - // Key/value pairs that provide additional information about the reporting descriptor reference. - Properties *PropertyBag `json:"properties,omitempty"` - - // A reference to the related reporting descriptor. - Target *ReportingDescriptorReference `json:"target"` -} - -// Result A result produced by an analysis tool. -type Result struct { - - // Identifies the artifact that the analysis tool was instructed to scan. This need not be the same as the artifact where the result actually occurred. - AnalysisTarget *ArtifactLocation `json:"analysisTarget,omitempty"` - - // A set of artifacts relevant to the result. - Attachments []*Attachment `json:"attachments,omitempty"` - - // The state of a result relative to a baseline of a previous run. - BaselineState interface{} `json:"baselineState,omitempty"` - - // An array of 'codeFlow' objects relevant to the result. - CodeFlows []*CodeFlow `json:"codeFlows,omitempty"` - - // A stable, unique identifier for the equivalence class of logically identical results to which this result belongs, in the form of a GUID. - CorrelationGuid string `json:"correlationGuid,omitempty"` - - // A set of strings each of which individually defines a stable, unique identity for the result. - Fingerprints map[string]string `json:"fingerprints,omitempty"` - - // An array of 'fix' objects, each of which represents a proposed fix to the problem indicated by the result. - Fixes []*Fix `json:"fixes,omitempty"` - - // An array of one or more unique 'graphTraversal' objects. - GraphTraversals []*GraphTraversal `json:"graphTraversals,omitempty"` - - // An array of zero or more unique graph objects associated with the result. - Graphs []*Graph `json:"graphs,omitempty"` - - // A stable, unique identifier for the result in the form of a GUID. - Guid string `json:"guid,omitempty"` - - // An absolute URI at which the result can be viewed. - HostedViewerUri string `json:"hostedViewerUri,omitempty"` - - // A value that categorizes results by evaluation state. - Kind ResultKind `json:"kind,omitempty"` - - // A value specifying the severity level of the result. - Level ResultLevel `json:"level,omitempty"` - - // The set of locations where the result was detected. Specify only one location unless the problem indicated by the result can only be corrected by making a change at every specified location. - Locations []*Location `json:"locations,omitempty"` - - // A message that describes the result. The first sentence of the message only will be displayed when visible space is limited. - Message *Message `json:"message"` - - // A positive integer specifying the number of times this logically unique result was observed in this run. - OccurrenceCount int `json:"occurrenceCount,omitempty"` - - // A set of strings that contribute to the stable, unique identity of the result. - PartialFingerprints map[string]string `json:"partialFingerprints,omitempty"` - - // Key/value pairs that provide additional information about the result. - Properties *PropertyBag `json:"properties,omitempty"` - - // Information about how and when the result was detected. - Provenance *ResultProvenance `json:"provenance,omitempty"` - - // A number representing the priority or importance of the result. - Rank float64 `json:"rank,omitempty"` - - // A set of locations relevant to this result. - RelatedLocations []*Location `json:"relatedLocations,omitempty"` - - // A reference used to locate the rule descriptor relevant to this result. - Rule *ReportingDescriptorReference `json:"rule,omitempty"` - - // The stable, unique identifier of the rule, if any, to which this result is relevant. - RuleId string `json:"ruleId,omitempty"` - - // The index within the tool component rules array of the rule object associated with this result. - RuleIndex int `json:"ruleIndex,omitempty"` - - // An array of 'stack' objects relevant to the result. - Stacks []*Stack `json:"stacks,omitempty"` - - // A set of suppressions relevant to this result. - Suppressions []*Suppression `json:"suppressions,omitempty"` - - // An array of references to taxonomy reporting descriptors that are applicable to the result. - Taxa []*ReportingDescriptorReference `json:"taxa,omitempty"` - - // A web request associated with this result. - WebRequest *WebRequest `json:"webRequest,omitempty"` - - // A web response associated with this result. - WebResponse *WebResponse `json:"webResponse,omitempty"` - - // The URIs of the work items associated with this result. - WorkItemUris []string `json:"workItemUris,omitempty"` -} - -// ResultProvenance Contains information about how and when a result was detected. -type ResultProvenance struct { - - // An array of physicalLocation objects which specify the portions of an analysis tool's output that a converter transformed into the result. - ConversionSources []*PhysicalLocation `json:"conversionSources,omitempty"` - - // A GUID-valued string equal to the automationDetails.guid property of the run in which the result was first detected. - FirstDetectionRunGuid string `json:"firstDetectionRunGuid,omitempty"` - - // The Coordinated Universal Time (UTC) date and time at which the result was first detected. See "Date/time properties" in the SARIF spec for the required format. - FirstDetectionTimeUtc string `json:"firstDetectionTimeUtc,omitempty"` - - // The index within the run.invocations array of the invocation object which describes the tool invocation that detected the result. - InvocationIndex int `json:"invocationIndex,omitempty"` - - // A GUID-valued string equal to the automationDetails.guid property of the run in which the result was most recently detected. - LastDetectionRunGuid string `json:"lastDetectionRunGuid,omitempty"` - - // The Coordinated Universal Time (UTC) date and time at which the result was most recently detected. See "Date/time properties" in the SARIF spec for the required format. - LastDetectionTimeUtc string `json:"lastDetectionTimeUtc,omitempty"` - - // Key/value pairs that provide additional information about the result. - Properties *PropertyBag `json:"properties,omitempty"` -} - -// Run Describes a single run of an analysis tool, and contains the reported output of that run. -type Run struct { - - // Addresses associated with this run instance, if any. - Addresses []*Address `json:"addresses,omitempty"` - - // An array of artifact objects relevant to the run. - Artifacts []*Artifact `json:"artifacts,omitempty"` - - // Automation details that describe this run. - AutomationDetails *RunAutomationDetails `json:"automationDetails,omitempty"` - - // The 'guid' property of a previous SARIF 'run' that comprises the baseline that was used to compute result 'baselineState' properties for the run. - BaselineGuid string `json:"baselineGuid,omitempty"` - - // Specifies the unit in which the tool measures columns. - ColumnKind interface{} `json:"columnKind,omitempty"` - - // A conversion object that describes how a converter transformed an analysis tool's native reporting format into the SARIF format. - Conversion *Conversion `json:"conversion,omitempty"` - - // Specifies the default encoding for any artifact object that refers to a text file. - DefaultEncoding string `json:"defaultEncoding,omitempty"` - - // Specifies the default source language for any artifact object that refers to a text file that contains source code. - DefaultSourceLanguage string `json:"defaultSourceLanguage,omitempty"` - - // References to external property files that should be inlined with the content of a root log file. - ExternalPropertyFileReferences *ExternalPropertyFileReferences `json:"externalPropertyFileReferences,omitempty"` - - // An array of zero or more unique graph objects associated with the run. - Graphs []*Graph `json:"graphs,omitempty"` - - // Describes the invocation of the analysis tool. - Invocations []*Invocation `json:"invocations,omitempty"` - - // The language of the messages emitted into the log file during this run (expressed as an ISO 639-1 two-letter lowercase culture code) and an optional region (expressed as an ISO 3166-1 two-letter uppercase subculture code associated with a country or region). The casing is recommended but not required (in order for this data to conform to RFC5646). - Language string `json:"language,omitempty"` - - // An array of logical locations such as namespaces, types or functions. - LogicalLocations []*LogicalLocation `json:"logicalLocations,omitempty"` - - // An ordered list of character sequences that were treated as line breaks when computing region information for the run. - NewlineSequences []string `json:"newlineSequences,omitempty"` - - // The artifact location specified by each uriBaseId symbol on the machine where the tool originally ran. - OriginalUriBaseIds map[string]*ArtifactLocation `json:"originalUriBaseIds,omitempty"` - - // Contains configurations that may potentially override both reportingDescriptor.defaultConfiguration (the tool's default severities) and invocation.configurationOverrides (severities established at run-time from the command line). - Policies []*ToolComponent `json:"policies,omitempty"` - - // Key/value pairs that provide additional information about the run. - Properties *PropertyBag `json:"properties,omitempty"` - - // An array of strings used to replace sensitive information in a redaction-aware property. - RedactionTokens []string `json:"redactionTokens,omitempty"` - - // The set of results contained in an SARIF log. The results array can be omitted when a run is solely exporting rules metadata. It must be present (but may be empty) if a log file represents an actual scan. - Results []*Result `json:"results,omitempty"` - - // Automation details that describe the aggregate of runs to which this run belongs. - RunAggregates []*RunAutomationDetails `json:"runAggregates,omitempty"` - - // A specialLocations object that defines locations of special significance to SARIF consumers. - SpecialLocations *SpecialLocations `json:"specialLocations,omitempty"` - - // An array of toolComponent objects relevant to a taxonomy in which results are categorized. - Taxonomies []*ToolComponent `json:"taxonomies,omitempty"` - - // An array of threadFlowLocation objects cached at run level. - ThreadFlowLocations []*ThreadFlowLocation `json:"threadFlowLocations,omitempty"` - - // Information about the tool or tool pipeline that generated the results in this run. A run can only contain results produced by a single tool or tool pipeline. A run can aggregate results from multiple log files, as long as context around the tool run (tool command-line arguments and the like) is identical for all aggregated files. - Tool *Tool `json:"tool"` - - // The set of available translations of the localized data provided by the tool. - Translations []*ToolComponent `json:"translations,omitempty"` - - // Specifies the revision in version control of the artifacts that were scanned. - VersionControlProvenance []*VersionControlDetails `json:"versionControlProvenance,omitempty"` - - // An array of request objects cached at run level. - WebRequests []*WebRequest `json:"webRequests,omitempty"` - - // An array of response objects cached at run level. - WebResponses []*WebResponse `json:"webResponses,omitempty"` -} - -// RunAutomationDetails Information that describes a run's identity and role within an engineering system process. -type RunAutomationDetails struct { - - // A stable, unique identifier for the equivalence class of runs to which this object's containing run object belongs in the form of a GUID. - CorrelationGuid string `json:"correlationGuid,omitempty"` - - // A description of the identity and role played within the engineering system by this object's containing run object. - Description *Message `json:"description,omitempty"` - - // A stable, unique identifier for this object's containing run object in the form of a GUID. - Guid string `json:"guid,omitempty"` - - // A hierarchical string that uniquely identifies this object's containing run object. - Id string `json:"id,omitempty"` - - // Key/value pairs that provide additional information about the run automation details. - Properties *PropertyBag `json:"properties,omitempty"` -} - -// SpecialLocations Defines locations of special significance to SARIF consumers. -type SpecialLocations struct { - - // Provides a suggestion to SARIF consumers to display file paths relative to the specified location. - DisplayBase *ArtifactLocation `json:"displayBase,omitempty"` - - // Key/value pairs that provide additional information about the special locations. - Properties *PropertyBag `json:"properties,omitempty"` -} - -// Stack A call stack that is relevant to a result. -type Stack struct { - - // An array of stack frames that represents a sequence of calls, rendered in reverse chronological order, that comprise the call stack. - Frames []*StackFrame `json:"frames"` - - // A message relevant to this call stack. - Message *Message `json:"message,omitempty"` - - // Key/value pairs that provide additional information about the stack. - Properties *PropertyBag `json:"properties,omitempty"` -} - -// StackFrame A function call within a stack trace. -type StackFrame struct { - - // The location to which this stack frame refers. - Location *Location `json:"location,omitempty"` - - // The name of the module that contains the code of this stack frame. - Module string `json:"module,omitempty"` - - // The parameters of the call that is executing. - Parameters []string `json:"parameters,omitempty"` - - // Key/value pairs that provide additional information about the stack frame. - Properties *PropertyBag `json:"properties,omitempty"` - - // The thread identifier of the stack frame. - ThreadId int `json:"threadId,omitempty"` -} - -// Suppression A suppression that is relevant to a result. -type Suppression struct { - - // A stable, unique identifier for the suppression in the form of a GUID. - Guid string `json:"guid,omitempty"` - - // A string representing the justification for the suppression. - Justification string `json:"justification,omitempty"` - - // A string that indicates where the suppression is persisted. - Kind string `json:"kind"` - - // Identifies the location associated with the suppression. - Location *Location `json:"location,omitempty"` - - // Key/value pairs that provide additional information about the suppression. - Properties *PropertyBag `json:"properties,omitempty"` - - // A string that indicates the review status of the suppression. - Status interface{} `json:"status,omitempty"` -} - -// ThreadFlow Describes a sequence of code locations that specify a path through a single thread of execution such as an operating system or fiber. -type ThreadFlow struct { - - // An string that uniquely identifies the threadFlow within the codeFlow in which it occurs. - Id string `json:"id,omitempty"` - - // Values of relevant expressions at the start of the thread flow that remain constant. - ImmutableState map[string]*MultiformatMessageString `json:"immutableState,omitempty"` - - // Values of relevant expressions at the start of the thread flow that may change during thread flow execution. - InitialState map[string]*MultiformatMessageString `json:"initialState,omitempty"` - - // A temporally ordered array of 'threadFlowLocation' objects, each of which describes a location visited by the tool while producing the result. - Locations []*ThreadFlowLocation `json:"locations"` - - // A message relevant to the thread flow. - Message *Message `json:"message,omitempty"` - - // Key/value pairs that provide additional information about the thread flow. - Properties *PropertyBag `json:"properties,omitempty"` -} - -// ThreadFlowLocation A location visited by an analysis tool while simulating or monitoring the execution of a program. -type ThreadFlowLocation struct { - - // An integer representing the temporal order in which execution reached this location. - ExecutionOrder int `json:"executionOrder,omitempty"` - - // The Coordinated Universal Time (UTC) date and time at which this location was executed. - ExecutionTimeUtc string `json:"executionTimeUtc,omitempty"` - - // Specifies the importance of this location in understanding the code flow in which it occurs. The order from most to least important is "essential", "important", "unimportant". Default: "important". - Importance interface{} `json:"importance,omitempty"` - - // The index within the run threadFlowLocations array. - Index int `json:"index,omitempty"` - - // A set of distinct strings that categorize the thread flow location. Well-known kinds include 'acquire', 'release', 'enter', 'exit', 'call', 'return', 'branch', 'implicit', 'false', 'true', 'caution', 'danger', 'unknown', 'unreachable', 'taint', 'function', 'handler', 'lock', 'memory', 'resource', 'scope' and 'value'. - Kinds []string `json:"kinds,omitempty"` - - // The code location. - Location *Location `json:"location,omitempty"` - - // The name of the module that contains the code that is executing. - Module string `json:"module,omitempty"` - - // An integer representing a containment hierarchy within the thread flow. - NestingLevel int `json:"nestingLevel,omitempty"` - - // Key/value pairs that provide additional information about the threadflow location. - Properties *PropertyBag `json:"properties,omitempty"` - - // The call stack leading to this location. - Stack *Stack `json:"stack,omitempty"` - - // A dictionary, each of whose keys specifies a variable or expression, the associated value of which represents the variable or expression value. For an annotation of kind 'continuation', for example, this dictionary might hold the current assumed values of a set of global variables. - State map[string]*MultiformatMessageString `json:"state,omitempty"` - - // An array of references to rule or taxonomy reporting descriptors that are applicable to the thread flow location. - Taxa []*ReportingDescriptorReference `json:"taxa,omitempty"` - - // A web request associated with this thread flow location. - WebRequest *WebRequest `json:"webRequest,omitempty"` - - // A web response associated with this thread flow location. - WebResponse *WebResponse `json:"webResponse,omitempty"` -} - -// Tool The analysis tool that was run. -type Tool struct { - - // The analysis tool that was run. - Driver *ToolComponent `json:"driver"` - - // Tool extensions that contributed to or reconfigured the analysis tool that was run. - Extensions []*ToolComponent `json:"extensions,omitempty"` - - // Key/value pairs that provide additional information about the tool. - Properties *PropertyBag `json:"properties,omitempty"` -} - -// ToolComponent A component, such as a plug-in or the driver, of the analysis tool that was run. -type ToolComponent struct { - - // The component which is strongly associated with this component. For a translation, this refers to the component which has been translated. For an extension, this is the driver that provides the extension's plugin model. - AssociatedComponent *ToolComponentReference `json:"associatedComponent,omitempty"` - - // The kinds of data contained in this object. - Contents []interface{} `json:"contents,omitempty"` - - // The binary version of the tool component's primary executable file expressed as four non-negative integers separated by a period (for operating systems that express file versions in this way). - DottedQuadFileVersion string `json:"dottedQuadFileVersion,omitempty"` - - // The absolute URI from which the tool component can be downloaded. - DownloadUri string `json:"downloadUri,omitempty"` - - // A comprehensive description of the tool component. - FullDescription *MultiformatMessageString `json:"fullDescription,omitempty"` - - // The name of the tool component along with its version and any other useful identifying information, such as its locale. - FullName string `json:"fullName,omitempty"` - - // A dictionary, each of whose keys is a resource identifier and each of whose values is a multiformatMessageString object, which holds message strings in plain text and (optionally) Markdown format. The strings can include placeholders, which can be used to construct a message in combination with an arbitrary number of additional string arguments. - GlobalMessageStrings map[string]*MultiformatMessageString `json:"globalMessageStrings,omitempty"` - - // A unique identifier for the tool component in the form of a GUID. - Guid string `json:"guid,omitempty"` - - // The absolute URI at which information about this version of the tool component can be found. - InformationUri string `json:"informationUri,omitempty"` - - // Specifies whether this object contains a complete definition of the localizable and/or non-localizable data for this component, as opposed to including only data that is relevant to the results persisted to this log file. - IsComprehensive bool `json:"isComprehensive,omitempty"` - - // The language of the messages emitted into the log file during this run (expressed as an ISO 639-1 two-letter lowercase language code) and an optional region (expressed as an ISO 3166-1 two-letter uppercase subculture code associated with a country or region). The casing is recommended but not required (in order for this data to conform to RFC5646). - Language string `json:"language,omitempty"` - - // The semantic version of the localized strings defined in this component; maintained by components that provide translations. - LocalizedDataSemanticVersion string `json:"localizedDataSemanticVersion,omitempty"` - - // An array of the artifactLocation objects associated with the tool component. - Locations []*ArtifactLocation `json:"locations,omitempty"` - - // The minimum value of localizedDataSemanticVersion required in translations consumed by this component; used by components that consume translations. - MinimumRequiredLocalizedDataSemanticVersion string `json:"minimumRequiredLocalizedDataSemanticVersion,omitempty"` - - // The name of the tool component. - Name string `json:"name"` - - // An array of reportingDescriptor objects relevant to the notifications related to the configuration and runtime execution of the tool component. - Notifications []*ReportingDescriptor `json:"notifications,omitempty"` - - // The organization or company that produced the tool component. - Organization string `json:"organization,omitempty"` - - // A product suite to which the tool component belongs. - Product string `json:"product,omitempty"` - - // A localizable string containing the name of the suite of products to which the tool component belongs. - ProductSuite string `json:"productSuite,omitempty"` - - // Key/value pairs that provide additional information about the tool component. - Properties *PropertyBag `json:"properties,omitempty"` - - // A string specifying the UTC date (and optionally, the time) of the component's release. - ReleaseDateUtc string `json:"releaseDateUtc,omitempty"` - - // An array of reportingDescriptor objects relevant to the analysis performed by the tool component. - Rules []*ReportingDescriptor `json:"rules,omitempty"` - - // The tool component version in the format specified by Semantic Versioning 2.0. - SemanticVersion string `json:"semanticVersion,omitempty"` - - // A brief description of the tool component. - ShortDescription *MultiformatMessageString `json:"shortDescription,omitempty"` - - // An array of toolComponentReference objects to declare the taxonomies supported by the tool component. - SupportedTaxonomies []*ToolComponentReference `json:"supportedTaxonomies,omitempty"` - - // An array of reportingDescriptor objects relevant to the definitions of both standalone and tool-defined taxonomies. - Taxa []*ReportingDescriptor `json:"taxa,omitempty"` - - // Translation metadata, required for a translation, not populated by other component types. - TranslationMetadata *TranslationMetadata `json:"translationMetadata,omitempty"` - - // The tool component version, in whatever format the component natively provides. - Version string `json:"version,omitempty"` -} - -// ToolComponentReference Identifies a particular toolComponent object, either the driver or an extension. -type ToolComponentReference struct { - - // The 'guid' property of the referenced toolComponent. - Guid string `json:"guid,omitempty"` - - // An index into the referenced toolComponent in tool.extensions. - Index int `json:"index,omitempty"` - - // The 'name' property of the referenced toolComponent. - Name string `json:"name,omitempty"` - - // Key/value pairs that provide additional information about the toolComponentReference. - Properties *PropertyBag `json:"properties,omitempty"` -} - -// TranslationMetadata Provides additional metadata related to translation. -type TranslationMetadata struct { - - // The absolute URI from which the translation metadata can be downloaded. - DownloadUri string `json:"downloadUri,omitempty"` - - // A comprehensive description of the translation metadata. - FullDescription *MultiformatMessageString `json:"fullDescription,omitempty"` - - // The full name associated with the translation metadata. - FullName string `json:"fullName,omitempty"` - - // The absolute URI from which information related to the translation metadata can be downloaded. - InformationUri string `json:"informationUri,omitempty"` - - // The name associated with the translation metadata. - Name string `json:"name"` - - // Key/value pairs that provide additional information about the translation metadata. - Properties *PropertyBag `json:"properties,omitempty"` - - // A brief description of the translation metadata. - ShortDescription *MultiformatMessageString `json:"shortDescription,omitempty"` -} - -// VersionControlDetails Specifies the information necessary to retrieve a desired revision from a version control system. -type VersionControlDetails struct { - - // A Coordinated Universal Time (UTC) date and time that can be used to synchronize an enlistment to the state of the repository at that time. - AsOfTimeUtc string `json:"asOfTimeUtc,omitempty"` - - // The name of a branch containing the revision. - Branch string `json:"branch,omitempty"` - - // The location in the local file system to which the root of the repository was mapped at the time of the analysis. - MappedTo *ArtifactLocation `json:"mappedTo,omitempty"` - - // Key/value pairs that provide additional information about the version control details. - Properties *PropertyBag `json:"properties,omitempty"` - - // The absolute URI of the repository. - RepositoryUri string `json:"repositoryUri"` - - // A string that uniquely and permanently identifies the revision within the repository. - RevisionId string `json:"revisionId,omitempty"` - - // A tag that has been applied to the revision. - RevisionTag string `json:"revisionTag,omitempty"` -} - -// WebRequest Describes an HTTP request. -type WebRequest struct { - - // The body of the request. - Body *ArtifactContent `json:"body,omitempty"` - - // The request headers. - Headers map[string]string `json:"headers,omitempty"` - - // The index within the run.webRequests array of the request object associated with this result. - Index int `json:"index,omitempty"` - - // The HTTP method. Well-known values are 'GET', 'PUT', 'POST', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS', 'TRACE', 'CONNECT'. - Method string `json:"method,omitempty"` - - // The request parameters. - Parameters map[string]string `json:"parameters,omitempty"` - - // Key/value pairs that provide additional information about the request. - Properties *PropertyBag `json:"properties,omitempty"` - - // The request protocol. Example: 'http'. - Protocol string `json:"protocol,omitempty"` - - // The target of the request. - Target string `json:"target,omitempty"` - - // The request version. Example: '1.1'. - Version string `json:"version,omitempty"` -} - -// WebResponse Describes the response to an HTTP request. -type WebResponse struct { - - // The body of the response. - Body *ArtifactContent `json:"body,omitempty"` - - // The response headers. - Headers map[string]string `json:"headers,omitempty"` - - // The index within the run.webResponses array of the response object associated with this result. - Index int `json:"index,omitempty"` - - // Specifies whether a response was received from the server. - NoResponseReceived bool `json:"noResponseReceived,omitempty"` - - // Key/value pairs that provide additional information about the response. - Properties *PropertyBag `json:"properties,omitempty"` - - // The response protocol. Example: 'http'. - Protocol string `json:"protocol,omitempty"` - - // The response reason. Example: 'Not found'. - ReasonPhrase string `json:"reasonPhrase,omitempty"` - - // The response status code. Example: 451. - StatusCode int `json:"statusCode,omitempty"` - - // The response version. Example: '1.1'. - Version string `json:"version,omitempty"` -} diff --git a/vendor/dev.gaijin.team/go/exhaustruct/v4/LICENSE b/vendor/dev.gaijin.team/go/exhaustruct/v4/LICENSE deleted file mode 100644 index 6698196c5a..0000000000 --- a/vendor/dev.gaijin.team/go/exhaustruct/v4/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2022 Gaijin Entertainment - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/dev.gaijin.team/go/exhaustruct/v4/analyzer/analyzer.go b/vendor/dev.gaijin.team/go/exhaustruct/v4/analyzer/analyzer.go deleted file mode 100644 index a235de3856..0000000000 --- a/vendor/dev.gaijin.team/go/exhaustruct/v4/analyzer/analyzer.go +++ /dev/null @@ -1,389 +0,0 @@ -package analyzer - -import ( - "flag" - "fmt" - "go/ast" - "go/token" - "go/types" - "sync" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/inspector" - - "dev.gaijin.team/go/exhaustruct/v4/internal/comment" - "dev.gaijin.team/go/exhaustruct/v4/internal/structure" -) - -type analyzer struct { - config Config - - structFields structure.FieldsCache `exhaustruct:"optional"` - comments comment.Cache `exhaustruct:"optional"` - - typeProcessingNeed map[string]bool - typeProcessingNeedMu sync.RWMutex `exhaustruct:"optional"` -} - -func NewAnalyzer(config Config) (*analysis.Analyzer, error) { - err := config.Prepare() - if err != nil { - return nil, err - } - - a := analyzer{ - config: config, - typeProcessingNeed: make(map[string]bool), - comments: comment.Cache{}, - } - - return &analysis.Analyzer{ //nolint:exhaustruct - Name: "exhaustruct", - Doc: "Checks if all structure fields are initialized", - Run: a.run, - Requires: []*analysis.Analyzer{inspect.Analyzer}, - Flags: *a.config.BindToFlagSet(flag.NewFlagSet("", flag.PanicOnError)), - }, nil -} - -func (a *analyzer) run(pass *analysis.Pass) (any, error) { - insp := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) //nolint:forcetypeassert - - insp.WithStack([]ast.Node{(*ast.CompositeLit)(nil)}, a.newVisitor(pass)) - - return nil, nil //nolint:nilnil -} - -// newVisitor returns visitor that only expects [ast.CompositeLit] nodes. -func (a *analyzer) newVisitor(pass *analysis.Pass) func(n ast.Node, push bool, stack []ast.Node) bool { - return func(n ast.Node, push bool, stack []ast.Node) bool { - if !push { - return true - } - - lit, ok := n.(*ast.CompositeLit) - if !ok { - // this should never happen, but better be prepared - return true - } - - structTyp, typeInfo, ok := getStructType(pass, lit) - if !ok { - return true - } - - if len(lit.Elts) == 0 && a.checkEmptyStructAllowed(pass, stack, typeInfo) { - return true - } - - file := a.comments.Get(pass.Fset, stack[0].(*ast.File)) //nolint:forcetypeassert - rc := getCompositeLitRelatedComments(stack, file) - pos, msg := a.processStruct(pass, lit, structTyp, typeInfo, rc) - - if pos != nil { - pass.Reportf(*pos, "%s", msg) - } - - return true - } -} - -func (a *analyzer) checkEmptyStructAllowed(pass *analysis.Pass, stack []ast.Node, typeInfo *TypeInfo) bool { - // empty structs are globally allowed - if a.config.AllowEmpty { - return true - } - - // some structs are allowed to be empty, basing on pattern - if a.config.allowEmptyPatterns.MatchFullString(typeInfo.String()) { - return true - } - - if ret, ok := getParentReturnStmt(stack); ok { - // empty structures are allowed in all return statements - if a.config.AllowEmptyReturns { - return true - } - - // empty structures are allowed in error returns - if isErrorReturnStatement(pass, ret, stack[len(stack)-1]) { - return true - } - } - - // empty structures are allowed in variable declarations - if isChildOfVariableDeclaration(stack) && a.config.AllowEmptyDeclarations { - return true - } - - return false -} - -// isPartOfVariableDeclaration checks if the node is direct part of variable -// declaration, meaning that it is a first-level RHS child of `:=` or `var` -// declaration. -func isChildOfVariableDeclaration(stack []ast.Node) bool { - if len(stack) < 2 { //nolint:mnd // stack for sure contains at leas current node and its parent (file) - return false - } - - // Start from composite literal and go up the stack - for i := len(stack) - 1; i > 0; i-- { - parent := stack[i-1] - - switch p := parent.(type) { - case *ast.AssignStmt: - if p.Tok == token.DEFINE { - return true - } - - case *ast.ValueSpec: - return true - - case *ast.UnaryExpr: - // Only allow pointer taking (&) - if p.Op == token.AND { - continue - } - - return false - - default: - return false - } - } - - return false -} - -// getParentReturnStmt checks if the direct parent of the current node is a -// return statement and returns it if so. -func getParentReturnStmt(stack []ast.Node) (*ast.ReturnStmt, bool) { - if len(stack) < 2 { //nolint:mnd // stack for sure contains at leas current node and its parent (file) - return nil, false - } - - // Start from composite literal and go up the stack - for i := len(stack) - 1; i > 0; i-- { - parent := stack[i-1] - - switch p := parent.(type) { - case *ast.ReturnStmt: - return p, true - - case *ast.UnaryExpr: - // Only allow pointer taking (&) - if p.Op == token.AND { - continue - } - - return nil, false - - default: - return nil, false - } - } - - return nil, false -} - -// errorIface is an interface type of the [error] interface. -// -//nolint:forcetypeassert,gochecknoglobals -var errorIface = types.Universe.Lookup("error").Type().Underlying().(*types.Interface) - -// isErrorReturnStatement checks if the return statement is an error return -// statement, meaning that it contains a non-nil value that implements [error]. -func isErrorReturnStatement(pass *analysis.Pass, n *ast.ReturnStmt, currentNode ast.Node) bool { - if len(n.Results) == 0 { - return false - } - - // iterate backwards, since idiomatic position of error is at the end - for i := len(n.Results) - 1; i >= 0; i-- { - ri := n.Results[i] - - // Skip the current node, since it is already being checked - if ri == currentNode { - continue - } - - switch ri := ri.(type) { - case *ast.Ident: - // Skip nil values - if ri.Name == "nil" { - continue - } - - case *ast.UnaryExpr: - // Current node might be under the unary expression - if ri.X == currentNode { - continue - } - } - - // Check if the type implements error interface - resultType := pass.TypesInfo.TypeOf(ri) - if resultType != nil && types.Implements(resultType, errorIface) { - return true - } - } - - return false -} - -// getCompositeLitRelatedComments returns all comments that are related to checked node. We -// have to traverse the stack manually as ast do not associate comments with -// [ast.CompositeLit]. -func getCompositeLitRelatedComments(stack []ast.Node, cm ast.CommentMap) []*ast.CommentGroup { - comments := make([]*ast.CommentGroup, 0) - - for i := len(stack) - 1; i >= 0; i-- { - node := stack[i] - - switch tn := node.(type) { - case *ast.CompositeLit: - // comments on the lines prior to literal - comments = append(comments, cm[node]...) - // comments on the same line as literal type definition - // worth noting that event "typeless" literals have a type - comments = append(comments, cm[tn.Type]...) - - case *ast.ReturnStmt, // return ... - *ast.IndexExpr, // map[enum]...{...}[key] - *ast.CallExpr, // myfunc(map...) - *ast.UnaryExpr, // &map... - *ast.AssignStmt, // variable assignment (without var keyword) - *ast.DeclStmt, // var declaration, parent of *ast.GenDecl - *ast.GenDecl, // var declaration, parent of *ast.ValueSpec - *ast.ValueSpec, // var declaration - *ast.KeyValueExpr: // field declaration - comments = append(comments, cm[node]...) - - default: - return comments - } - } - - return comments -} - -func getStructType(pass *analysis.Pass, lit *ast.CompositeLit) (*types.Struct, *TypeInfo, bool) { - switch typ := types.Unalias(pass.TypesInfo.TypeOf(lit)).(type) { - case *types.Named: // named type - if structTyp, ok := typ.Underlying().(*types.Struct); ok { - pkg := typ.Obj().Pkg() - ti := TypeInfo{ - Name: typ.Obj().Name(), - PackageName: pkg.Name(), - PackagePath: pkg.Path(), - } - - return structTyp, &ti, true - } - - return nil, nil, false - - case *types.Struct: // anonymous struct - ti := TypeInfo{ - Name: "", - PackageName: pass.Pkg.Name(), - PackagePath: pass.Pkg.Path(), - } - - return typ, &ti, true - - default: - return nil, nil, false - } -} - -func (a *analyzer) processStruct( - pass *analysis.Pass, - lit *ast.CompositeLit, - structTyp *types.Struct, - info *TypeInfo, - comments []*ast.CommentGroup, -) (*token.Pos, string) { - shouldProcess := a.shouldProcessType(info) - - if shouldProcess && comment.HasDirective(comments, comment.DirectiveIgnore) { - return nil, "" - } - - if !shouldProcess && !comment.HasDirective(comments, comment.DirectiveEnforce) { - return nil, "" - } - - // unnamed structures are only defined in same package, along with types that has - // prefix identical to current package name. - isSamePackage := info.PackagePath == pass.Pkg.Path() - - if f := a.litSkippedFields(lit, structTyp, !isSamePackage); len(f) > 0 { - pos := lit.Pos() - - if len(f) == 1 { - return &pos, fmt.Sprintf("%s is missing field %s", info.ShortString(), f.String()) - } - - return &pos, fmt.Sprintf("%s is missing fields %s", info.ShortString(), f.String()) - } - - return nil, "" -} - -// shouldProcessType returns true if type should be processed basing off include -// and exclude patterns, defined though constructor and\or flags. -func (a *analyzer) shouldProcessType(info *TypeInfo) bool { - if len(a.config.includePatterns) == 0 && len(a.config.excludePatterns) == 0 { - return true - } - - name := info.String() - - a.typeProcessingNeedMu.RLock() - res, ok := a.typeProcessingNeed[name] - a.typeProcessingNeedMu.RUnlock() - - if !ok { - a.typeProcessingNeedMu.Lock() - - res = true - - if a.config.includePatterns != nil && !a.config.includePatterns.MatchFullString(name) { - res = false - } - - if res && a.config.excludePatterns != nil && a.config.excludePatterns.MatchFullString(name) { - res = false - } - - a.typeProcessingNeed[name] = res - a.typeProcessingNeedMu.Unlock() - } - - return res -} - -func (a *analyzer) litSkippedFields( - lit *ast.CompositeLit, - typ *types.Struct, - onlyExported bool, -) structure.Fields { - return a.structFields.Get(typ).Skipped(lit, onlyExported) -} - -type TypeInfo struct { - Name string - PackageName string - PackagePath string -} - -func (t TypeInfo) String() string { - return t.PackagePath + "." + t.Name -} - -func (t TypeInfo) ShortString() string { - return t.PackageName + "." + t.Name -} diff --git a/vendor/dev.gaijin.team/go/exhaustruct/v4/analyzer/config.go b/vendor/dev.gaijin.team/go/exhaustruct/v4/analyzer/config.go deleted file mode 100644 index 0c39cbed8c..0000000000 --- a/vendor/dev.gaijin.team/go/exhaustruct/v4/analyzer/config.go +++ /dev/null @@ -1,127 +0,0 @@ -package analyzer - -import ( - "flag" - "strings" - - "dev.gaijin.team/go/golib/e" - - "dev.gaijin.team/go/exhaustruct/v4/internal/pattern" -) - -type Config struct { - // IncludeRx is a list of regular expressions to match type names that should be - // processed. Anonymous structs can be matched by '' alias. - // - // Each regular expression must match the full type name, including package path. - // For example, to match type `net/http.Cookie` regular expression should be - // `.*/http\.Cookie`, but not `http\.Cookie`. - IncludeRx []string `exhaustruct:"optional"` - includePatterns pattern.List `exhaustruct:"optional"` - - // ExcludeRx is a list of regular expressions to match type names that should be - // excluded from processing. Anonymous structs can be matched by '' - // alias. - // - // Has precedence over IncludeRx. - // - // Each regular expression must match the full type name, including package path. - // For example, to match type `net/http.Cookie` regular expression should be - // `.*/http\.Cookie`, but not `http\.Cookie`. - ExcludeRx []string `exhaustruct:"optional"` - excludePatterns pattern.List `exhaustruct:"optional"` - - // AllowEmpty allows empty structures, effectively excluding them from the check. - AllowEmpty bool `exhaustruct:"optional"` - - // AllowEmptyRx is a list of regular expressions to match type names that should - // be allowed to be empty. Anonymous structs can be matched by '' - // alias. - // - // Each regular expression must match the full type name, including package path. - // For example, to match type `net/http.Cookie` regular expression should be - // `.*/http\.Cookie`, but not `http\.Cookie`. - AllowEmptyRx []string `exhaustruct:"optional"` - allowEmptyPatterns pattern.List `exhaustruct:"optional"` - - // AllowEmptyReturns allows empty structures in return statements. - AllowEmptyReturns bool `exhaustruct:"optional"` - - // AllowEmptyDeclarations allows empty structures in variable declarations. - AllowEmptyDeclarations bool `exhaustruct:"optional"` -} - -// Prepare compiles all regular expression patterns into pattern lists for -// efficient matching. -func (c *Config) Prepare() error { - var err error - - c.includePatterns, err = pattern.NewList(c.IncludeRx...) - if err != nil { - return e.NewFrom("compile include patterns", err) - } - - c.excludePatterns, err = pattern.NewList(c.ExcludeRx...) - if err != nil { - return e.NewFrom("compile exclude patterns", err) - } - - c.allowEmptyPatterns, err = pattern.NewList(c.AllowEmptyRx...) - if err != nil { - return e.NewFrom("compile allow empty patterns", err) - } - - return nil -} - -// stringSliceFlag implements flag.Value interface for []string fields. -type stringSliceFlag struct { - slice *[]string -} - -func (s stringSliceFlag) String() string { - if s.slice == nil { - return "" - } - - return strings.Join(*s.slice, ",") -} - -func (s stringSliceFlag) Set(value string) error { - *s.slice = append(*s.slice, value) - return nil -} - -// BindToFlagSet binds the config fields to the provided flag set. -func (c *Config) BindToFlagSet(fs *flag.FlagSet) *flag.FlagSet { - fs.Var(stringSliceFlag{&c.IncludeRx}, "include-rx", - "Regular expression to match type names that should be processed. "+ - "Anonymous structs can be matched by '' alias. "+ - "Each regex must match the full type name including package path. "+ - "Example: `.*/http\\.Cookie`. Can be used multiple times.") - fs.Var(stringSliceFlag{&c.IncludeRx}, "i", "Short form of -include-rx") - - fs.Var(stringSliceFlag{&c.ExcludeRx}, "exclude-rx", - "Regular expression to exclude type names from processing, has precedence over -include. "+ - "Anonymous structs can be matched by '' alias. "+ - "Each regex must match the full type name including package path. "+ - "Example: `.*/http\\.Cookie`. Can be used multiple times.") - fs.Var(stringSliceFlag{&c.ExcludeRx}, "e", "Short form of -exclude-rx") - - fs.BoolVar(&c.AllowEmpty, "allow-empty", c.AllowEmpty, - "Allow empty structures, effectively excluding them from the check") - - fs.Var(stringSliceFlag{&c.AllowEmptyRx}, "allow-empty-rx", - "Regular expression to match type names that should be allowed to be empty. "+ - "Anonymous structs can be matched by '' alias. "+ - "Each regex must match the full type name including package path. "+ - "Example: `.*/http\\.Cookie`. Can be used multiple times.") - - fs.BoolVar(&c.AllowEmptyReturns, "allow-empty-returns", c.AllowEmptyReturns, - "Allow empty structures in return statements") - - fs.BoolVar(&c.AllowEmptyDeclarations, "allow-empty-declarations", c.AllowEmptyDeclarations, - "Allow empty structures in variable declarations") - - return fs -} diff --git a/vendor/dev.gaijin.team/go/exhaustruct/v4/internal/comment/cache.go b/vendor/dev.gaijin.team/go/exhaustruct/v4/internal/comment/cache.go deleted file mode 100644 index 88edef638a..0000000000 --- a/vendor/dev.gaijin.team/go/exhaustruct/v4/internal/comment/cache.go +++ /dev/null @@ -1,35 +0,0 @@ -package comment - -import ( - "go/ast" - "go/token" - "sync" -) - -type Cache struct { - comments map[*ast.File]ast.CommentMap - mu sync.RWMutex -} - -// Get returns a comment map for a given file. In case if a comment map is not -// found, it creates a new one. -func (c *Cache) Get(fset *token.FileSet, f *ast.File) ast.CommentMap { - c.mu.RLock() - if cm, ok := c.comments[f]; ok { - c.mu.RUnlock() - return cm - } - c.mu.RUnlock() - - c.mu.Lock() - defer c.mu.Unlock() - - if c.comments == nil { - c.comments = make(map[*ast.File]ast.CommentMap) - } - - cm := ast.NewCommentMap(fset, f, f.Comments) - c.comments[f] = cm - - return cm -} diff --git a/vendor/dev.gaijin.team/go/exhaustruct/v4/internal/comment/directive.go b/vendor/dev.gaijin.team/go/exhaustruct/v4/internal/comment/directive.go deleted file mode 100644 index a39a8076fa..0000000000 --- a/vendor/dev.gaijin.team/go/exhaustruct/v4/internal/comment/directive.go +++ /dev/null @@ -1,28 +0,0 @@ -package comment - -import ( - "go/ast" - "strings" -) - -type Directive string - -const ( - prefix = `//exhaustruct:` - DirectiveIgnore Directive = prefix + `ignore` - DirectiveEnforce Directive = prefix + `enforce` -) - -// HasDirective parses a directive from a given list of comments. -// If no directive is found, the second return value is `false`. -func HasDirective(comments []*ast.CommentGroup, expected Directive) bool { - for _, cg := range comments { - for _, commentLine := range cg.List { - if strings.HasPrefix(commentLine.Text, string(expected)) { - return true - } - } - } - - return false -} diff --git a/vendor/dev.gaijin.team/go/exhaustruct/v4/internal/pattern/list.go b/vendor/dev.gaijin.team/go/exhaustruct/v4/internal/pattern/list.go deleted file mode 100644 index 26b8ac20da..0000000000 --- a/vendor/dev.gaijin.team/go/exhaustruct/v4/internal/pattern/list.go +++ /dev/null @@ -1,91 +0,0 @@ -package pattern - -import ( - "regexp" - "strings" - - "dev.gaijin.team/go/golib/e" - "dev.gaijin.team/go/golib/fields" -) - -// List represents a collection of compiled regular expressions that can be used -// for pattern matching against strings. It implements the flag.Value interface -// to support command-line flag binding. -type List []*regexp.Regexp //nolint:recvcheck - -// NewList creates a new List from the provided regular expression patterns. -// Each pattern string is compiled into a regular expression. If any pattern -// is empty or fails to compile, an error is returned. -func NewList(patterns ...string) (List, error) { - if len(patterns) == 0 { - return nil, nil - } - - list := make(List, 0, len(patterns)) - - for _, pattern := range patterns { - re, err := parseRx(pattern) - if err != nil { - return nil, err - } - - list = append(list, re) - } - - return list, nil -} - -// MatchFullString checks if any of the regular expressions in the list matches -// the entire input string. A match is considered successful only if the regex -// matches the complete string from start to end, not just a substring. -// -// For example, if a List contains the pattern "test", it will match "test" -// but not "testing" or "contest". -func (l List) MatchFullString(str string) bool { - for i := 0; i < len(l); i++ { - if m := l[i].FindStringSubmatch(str); len(m) > 0 && m[0] == str { - return true - } - } - - return false -} - -// String returns a string representation of the List by joining all regex patterns -// with commas. This method implements the flag.Value interface and is used when -// the List is displayed or serialized. -func (l List) String() string { - patterns := make([]string, len(l)) - for i, re := range l { - patterns[i] = re.String() - } - - return strings.Join(patterns, ",") -} - -// Set adds a new regex pattern to the List by compiling the provided string. -// This method implements the flag.Value interface and is called when the flag -// is set from command-line arguments or programmatically. -func (l *List) Set(value string) error { - re, err := parseRx(value) - if err != nil { - return err - } - - *l = append(*l, re) - - return nil -} - -func parseRx(str string) (*regexp.Regexp, error) { - if str == "" { - return nil, e.New("empty regular expression is not allowed") - } - - re, err := regexp.Compile(str) - if err != nil { - return nil, e.NewFrom("failed to compile regular expression", err, fields.F("pattern", str)) - } - - return re, nil -} diff --git a/vendor/dev.gaijin.team/go/exhaustruct/v4/internal/structure/fields-cache.go b/vendor/dev.gaijin.team/go/exhaustruct/v4/internal/structure/fields-cache.go deleted file mode 100644 index 12a3796926..0000000000 --- a/vendor/dev.gaijin.team/go/exhaustruct/v4/internal/structure/fields-cache.go +++ /dev/null @@ -1,35 +0,0 @@ -package structure - -import ( - "go/types" - "sync" -) - -type FieldsCache struct { - fields map[*types.Struct]Fields - mu sync.RWMutex -} - -// Get returns a struct fields for a given type. In case if a struct fields is -// not found, it creates a new one from type definition. -func (c *FieldsCache) Get(typ *types.Struct) Fields { - c.mu.RLock() - fields, ok := c.fields[typ] - c.mu.RUnlock() - - if ok { - return fields - } - - c.mu.Lock() - defer c.mu.Unlock() - - if c.fields == nil { - c.fields = make(map[*types.Struct]Fields) - } - - fields = NewFields(typ) - c.fields[typ] = fields - - return fields -} diff --git a/vendor/dev.gaijin.team/go/exhaustruct/v4/internal/structure/fields.go b/vendor/dev.gaijin.team/go/exhaustruct/v4/internal/structure/fields.go deleted file mode 100644 index b6b1a48c87..0000000000 --- a/vendor/dev.gaijin.team/go/exhaustruct/v4/internal/structure/fields.go +++ /dev/null @@ -1,127 +0,0 @@ -package structure - -import ( - "go/ast" - "go/types" - "reflect" - "strings" -) - -const ( - tagName = "exhaustruct" - optionalTagValue = "optional" -) - -type Field struct { - Name string - Exported bool - Optional bool -} - -type Fields []*Field - -// NewFields creates a new [Fields] from a given struct type. -// Fields items are listed in order they appear in the struct. -func NewFields(strct *types.Struct) Fields { - sf := make(Fields, 0, strct.NumFields()) - - for i := 0; i < strct.NumFields(); i++ { - f := strct.Field(i) - - sf = append(sf, &Field{ - Name: f.Name(), - Exported: f.Exported(), - Optional: HasOptionalTag(strct.Tag(i)), - }) - } - - return sf -} - -func HasOptionalTag(tags string) bool { - return reflect.StructTag(tags).Get(tagName) == optionalTagValue -} - -// String returns a comma-separated list of field names. -func (sf Fields) String() string { - b := strings.Builder{} - - for i := 0; i < len(sf); i++ { - if b.Len() != 0 { - b.WriteString(", ") - } - - b.WriteString(sf[i].Name) - } - - return b.String() -} - -// Skipped returns a list of fields that are not present in the given -// literal, but expected to. -// -//revive:disable-next-line:cyclomatic -func (sf Fields) Skipped(lit *ast.CompositeLit, onlyExported bool) Fields { - if len(lit.Elts) != 0 && !isNamedLiteral(lit) { - if len(lit.Elts) == len(sf) { - return nil - } - - return sf[len(lit.Elts):] - } - - em := sf.existenceMap() - res := make(Fields, 0, len(sf)) - - for i := 0; i < len(lit.Elts); i++ { - kv, ok := lit.Elts[i].(*ast.KeyValueExpr) - if !ok { - continue - } - - k, ok := kv.Key.(*ast.Ident) - if !ok { - continue - } - - em[k.Name] = true - } - - for i := 0; i < len(sf); i++ { - if em[sf[i].Name] || (!sf[i].Exported && onlyExported) || sf[i].Optional { - continue - } - - res = append(res, sf[i]) - } - - if len(res) == 0 { - return nil - } - - return res -} - -func (sf Fields) existenceMap() map[string]bool { - m := make(map[string]bool, len(sf)) - - for i := 0; i < len(sf); i++ { - m[sf[i].Name] = false - } - - return m -} - -// isNamedLiteral returns true if the given literal is unnamed. -// -// The logic is basing on the principle that literal is named or unnamed, -// therefore is literal's first element is a [ast.KeyValueExpr], it is named. -// -// Method will panic if the given literal is empty. -func isNamedLiteral(lit *ast.CompositeLit) bool { - if _, ok := lit.Elts[0].(*ast.KeyValueExpr); !ok { - return false - } - - return true -} diff --git a/vendor/dev.gaijin.team/go/golib/LICENSE b/vendor/dev.gaijin.team/go/golib/LICENSE deleted file mode 100644 index 05a82fec2e..0000000000 --- a/vendor/dev.gaijin.team/go/golib/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2024 Gaijin Entertainment - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/dev.gaijin.team/go/golib/e/doc.go b/vendor/dev.gaijin.team/go/golib/e/doc.go deleted file mode 100644 index a1582f5c1e..0000000000 --- a/vendor/dev.gaijin.team/go/golib/e/doc.go +++ /dev/null @@ -1,46 +0,0 @@ -// Package e provides a custom error type with support for error chaining and -// structured metadata fields. -// -// The main type, Err, enables convenient error wrapping and the attachment of -// key-value metadata fields (fields.Field). Errors can be wrapped to add context -// and enriched with fields for structured logging or diagnostics. -// -// Example: Wrapping errors with context -// -// var ErrJSONParseFailed = e.New("JSON parse failed") -// var val any -// if err := json.Unmarshal([]byte(`["invalid", "json]`), &val); err != nil { -// return ErrJSONParseFailed.Wrap(err) -// // Output: "JSON parse failed: unexpected end of JSON input" -// } -// -// Example: Enriching errors with fields -// -// err := e.New("operation failed").WithField("user_id", 42) -// // Output: "operation failed (user_id=42)" -// -// err = err.Wrap(e.New("db error").WithFields(fields.F("query", "SELECT *"))) -// // Output: "operation failed (user_id=42): db error (query=SELECT *)" -// -// Any error can be converted to an Err using the From function. This does not -// wrap the error; unwrapping will not return the original error. -// -// e.From(errors.New("error")) // "error" -// errors.Unwrap(e.From(errors.New("error"))) // nil -// -// The Err string format is: -// -// (fields...): -// -// Fields are always enclosed in parentheses, and wrapped errors are separated by -// a colon and space. -// -// All methods that return errors create new instances; errors are immutable. -// -// Deprecated methods Unwrap, Is, and As are present for compatibility with the -// errors package, but should not be used directly. Use the errors package -// functions instead. -// -// The Log function logs errors using our logger abstraction - logger.Logger, -// extracting reason, wrapped error, and fields, logging them appropriately. -package e diff --git a/vendor/dev.gaijin.team/go/golib/e/err.go b/vendor/dev.gaijin.team/go/golib/e/err.go deleted file mode 100644 index 334dc563ca..0000000000 --- a/vendor/dev.gaijin.team/go/golib/e/err.go +++ /dev/null @@ -1,140 +0,0 @@ -package e - -import ( - "errors" - "slices" - "strings" - - "dev.gaijin.team/go/golib/fields" -) - -// Err represents a custom error type that supports error chaining and structured metadata fields. -type Err struct { - errs []error - fields fields.List -} - -// New returns a new Err with the given reason and optional fields. -// The returned error can be further wrapped or annotated with additional fields. -func New(reason string, f ...fields.Field) *Err { - return From(errors.New(reason), f...) //nolint:err113 -} - -// NewFrom returns a new Err with the given reason, wrapping the provided error, and optional fields. -// If wrapped is nil, it behaves like New. -func NewFrom(reason string, wrapped error, f ...fields.Field) *Err { - if wrapped == nil { - return New(reason, f...) - } - - return &Err{ - errs: []error{errors.New(reason), wrapped}, //nolint:err113 - fields: f, - } -} - -// From converts any error to an Err, optionally adding fields. This is not true wrapping; -// unwrapping will not return the original error. Passing nil results in an Err with reason "error(nil)". -func From(origin error, f ...fields.Field) *Err { - if origin == nil { - origin = errors.New("error(nil)") //nolint:err113 - } - - return &Err{ - errs: []error{origin}, - fields: f, - } -} - -// Wrap returns a new Err that wraps the provided error with the current Err as context. -// Additional fields can be attached. If err is nil, it is replaced with an Err for "error(nil)". -func (e *Err) Wrap(err error, f ...fields.Field) *Err { - if err == nil { - err = errors.New("error(nil)") //nolint:err113 - } - - return &Err{ - errs: []error{e, err}, - fields: f, - } -} - -// Error returns the string representation of the Err, including reason, fields, and wrapped errors. -func (e *Err) Error() string { - b := &strings.Builder{} - writeTo(b, e) - - return b.String() -} - -func writeTo(b *strings.Builder, err error) { - if b.Len() > 0 { - b.WriteString(": ") - } - - ee, ok := err.(*Err) //nolint:errorlint - if !ok { - b.WriteString(err.Error()) - - return - } - - b.WriteString(ee.Reason()) - - if ee == nil { - return - } - - if len(ee.fields) > 0 { - b.WriteRune(' ') - ee.fields.WriteTo(b) - } - - if len(ee.errs) > 1 { - writeTo(b, ee.errs[1]) - } -} - -// Clone returns a new Err with the same error, wrapped error, and a cloned fields container. -func (e *Err) Clone() *Err { - return &Err{ - errs: slices.Clone(e.errs), - fields: slices.Clone(e.fields), - } -} - -// WithFields returns a new Err with the same error and the provided fields. -func (e *Err) WithFields(f ...fields.Field) *Err { - return From(e, f...) -} - -// WithField returns a new Err with the same error and a single additional field. -func (e *Err) WithField(key string, val any) *Err { - return e.WithFields(fields.F(key, val)) -} - -// Fields returns the metadata fields attached to the Err. -func (e *Err) Fields() fields.List { - return e.fields -} - -// Reason returns the reason string of the Err, without fields or wrapped errors. -// If the Err is nil, returns "(*e.Err)(nil)". If empty, returns "(*e.Err)(empty)". -func (e *Err) Reason() string { - if e == nil { - return "(*e.Err)(nil)" - } - - if len(e.errs) == 0 { - return "(*e.Err)(empty)" - } - - return e.errs[0].Error() -} - -// Unwrap returns the underlying errors for compatibility with errors.Is and errors.As. -// -// Deprecated: This method is for internal use only. Prefer using the errors package directly. -func (e *Err) Unwrap() []error { - return e.errs -} diff --git a/vendor/dev.gaijin.team/go/golib/e/log.go b/vendor/dev.gaijin.team/go/golib/e/log.go deleted file mode 100644 index 0caafaab03..0000000000 --- a/vendor/dev.gaijin.team/go/golib/e/log.go +++ /dev/null @@ -1,33 +0,0 @@ -package e - -import ( - "dev.gaijin.team/go/golib/fields" -) - -// ErrorLogger defines a function that logs an error message, an error, and optional fields. -type ErrorLogger func(msg string, err error, fs ...fields.Field) - -// Log logs the provided error using the given ErrorLogger function. -// -// If err is nil, Log does nothing. If err is of type Err, its reason is used as the log message, -// the wrapped error is passed as the error, and its fields are passed as log fields. -// For other error types, err.Error() is used as the message and nil is passed as the error. -func Log(err error, f ErrorLogger) { - if err == nil { - return - } - - // We're not interested in wrapped error, therefore we're only typecasting it. - if e, ok := err.(*Err); ok { //nolint:errorlint - var wrapped error - if len(e.errs) > 1 { - wrapped = e.errs[1] - } - - f(e.Reason(), wrapped, e.fields...) - - return - } - - f(err.Error(), nil) -} diff --git a/vendor/dev.gaijin.team/go/golib/fields/dict.go b/vendor/dev.gaijin.team/go/golib/fields/dict.go deleted file mode 100644 index cd025089f3..0000000000 --- a/vendor/dev.gaijin.team/go/golib/fields/dict.go +++ /dev/null @@ -1,69 +0,0 @@ -package fields - -import ( - "iter" - "strings" -) - -const CollectionSep = ", " - -// Dict is a map-based collection of unique fields, keyed by string. -// It provides efficient lookup and overwrites duplicate keys. -type Dict map[string]any - -// Add inserts or updates fields in the Dict, overwriting existing keys if present. -// -// Example: -// -// d := fields.Dict{"foo": "bar"} -// d.Add(fields.F("baz", 42), fields.F("foo", "qux")) // d["foo"] == "qux" -func (d Dict) Add(fields ...Field) { - for _, f := range fields { - d[f.K] = f.V - } -} - -// ToList converts the Dict to a List, with order unspecified. -// Each key-value pair becomes a Field in the resulting List. -func (d Dict) ToList() List { - s := make(List, 0, len(d)) - - for k, v := range d { - s = append(s, Field{k, v}) - } - - return s -} - -// All returns an iterator over all key-value pairs in the Dict as iter.Seq2[string, any]. -// -// Example: -// -// for k, v := range d.All() { -// fmt.Println(k, v) -// } -func (d Dict) All() iter.Seq2[string, any] { - return func(yield func(string, any) bool) { - for k, v := range d { - if !yield(k, v) { - return - } - } - } -} - -// WriteTo writes the Dict as a string in the format "(key1=val1, key2=val2)" to the provided builder. -// If the Dict is empty, nothing is written. The order of fields is unspecified. -func (d Dict) WriteTo(b *strings.Builder) { - WriteTo(b, d.All()) -} - -// String returns the Dict as a string in the format "(key1=val1, key2=val2)". -// Returns an empty string if the Dict is empty. The order of fields is unspecified. -func (d Dict) String() string { - b := strings.Builder{} - - d.WriteTo(&b) - - return b.String() -} diff --git a/vendor/dev.gaijin.team/go/golib/fields/doc.go b/vendor/dev.gaijin.team/go/golib/fields/doc.go deleted file mode 100644 index 1ef4ee56d9..0000000000 --- a/vendor/dev.gaijin.team/go/golib/fields/doc.go +++ /dev/null @@ -1,32 +0,0 @@ -// Package fields provides types and functions to work with key-value pairs. -// -// The package offers three primary abstractions: -// -// - Field: A key-value pair where the key is a string and the value can be any type. -// - Dict: A map-based collection of unique fields, providing efficient key-based lookup. -// - List: An ordered collection of fields that preserves insertion order. -// -// Fields can be created using the F constructor, and both Dict and List provide -// conversion methods between the two collection types. All types implement String() -// for consistent string representation. -// -// Example usage: -// -// // Create fields -// f1 := fields.F("status", "success") -// f2 := fields.F("code", 200) -// -// // Working with a List (ordered collection) -// var list fields.List -// list.Add(f1, f2) -// fmt.Println(list) // "(status=success, code=200)" -// -// // Working with a Dict (unique key collection) -// dict := fields.Dict{} -// dict.Add(f1, f2, fields.F("status", "updated")) // overwrites "status" -// fmt.Println(dict) // "(status=updated, code=200)" (order may vary) -// -// // Converting between types -// list2 := dict.ToList() // order unspecified -// dict2 := list.ToDict() // last occurrence of each key wins -package fields diff --git a/vendor/dev.gaijin.team/go/golib/fields/field.go b/vendor/dev.gaijin.team/go/golib/fields/field.go deleted file mode 100644 index 324b2970f9..0000000000 --- a/vendor/dev.gaijin.team/go/golib/fields/field.go +++ /dev/null @@ -1,82 +0,0 @@ -// Package fields provides types and functions for working with key-value fields. -package fields - -import ( - "fmt" - "iter" - "strings" -) - -// Field represents a key-value pair, where the key is a string and the value can be any type. -type Field struct { - // Key of the field - K string - // Value of the field - V any -} - -// F creates a new Field with the given key and value. -// -// Example: -// -// f := fields.F("user", "alice") -func F(key string, value any) Field { - return Field{K: key, V: value} -} - -// writeKVTo writes a key-value pair to the given builder in the format "key=value". -func writeKVTo(b *strings.Builder, key string, value any) { - b.WriteString(key) - b.WriteRune('=') - - switch val := value.(type) { - case string: - b.WriteString(val) - - case fmt.Stringer: - b.WriteString(val.String()) - - case error: - b.WriteString(val.Error()) - - default: - _, _ = fmt.Fprintf(b, "%v", value) - } -} - -// WriteTo writes the Field as a string in the format "key=value" to the provided builder. -func (f Field) WriteTo(b *strings.Builder) { - writeKVTo(b, f.K, f.V) -} - -// String returns the Field as a string in the format "key=value". -func (f Field) String() string { - b := &strings.Builder{} - f.WriteTo(b) - - return b.String() -} - -// WriteTo writes key-value pairs from an iter.Seq2[string, any] to the builder in the format "(key1=val1, key2=val2)". -// If no fields are present, nothing is written. -func WriteTo(b *strings.Builder, seq iter.Seq2[string, any]) { - first := true - - for k, v := range seq { - if first { - first = false - - b.WriteString("(") - } else { - b.WriteString(", ") - } - - writeKVTo(b, k, v) - } - - // means that we've written at least one field, and, therefore, - // can close the parenthesis - if !first { - b.WriteString(")") - } -} diff --git a/vendor/dev.gaijin.team/go/golib/fields/list.go b/vendor/dev.gaijin.team/go/golib/fields/list.go deleted file mode 100644 index 5a881f77e0..0000000000 --- a/vendor/dev.gaijin.team/go/golib/fields/list.go +++ /dev/null @@ -1,69 +0,0 @@ -package fields - -import ( - "iter" - "strings" -) - -// List is an ordered collection of Field values, preserving insertion order. -// Such collection do not check for duplicate keys. -type List []Field //nolint:recvcheck //we need Add to be a pointer receiver to modify original value. - -// Add one or more fields to the List, modifying it. -// -// Example: -// -// var l fields.List -// l.Add(fields.F("foo", "bar"), fields.F("baz", 42)) -func (l *List) Add(fields ...Field) { - *l = append(*l, fields...) -} - -// ToDict converts the List to a Dict, overwriting duplicate keys with the last occurrence. -// -// Example: -// -// l := fields.List{fields.F("foo", 1), fields.F("foo", 2)} -// d := l.ToDict() // d["foo"] == 2 -func (l List) ToDict() Dict { - d := make(Dict, len(l)) - - for i := range l { - d[l[i].K] = l[i].V - } - - return d -} - -// All returns an iterator over all key-value pairs in the List as iter.Seq2[string, any]. -// -// Example: -// -// for k, v := range l.All() { -// fmt.Println(k, v) -// } -func (l List) All() iter.Seq2[string, any] { - return func(yield func(string, any) bool) { - for i := 0; i < len(l); i++ { - if !yield(l[i].K, l[i].V) { - return - } - } - } -} - -// WriteTo writes the List as a string in the format "(key1=val1, key2=val2)" to the provided builder. -// If the List is empty, nothing is written. -func (l List) WriteTo(b *strings.Builder) { - WriteTo(b, l.All()) -} - -// String returns the List as a string in the format "(key1=val1, key2=val2)". -// Returns an empty string if the List is empty. -func (l List) String() string { - b := strings.Builder{} - - l.WriteTo(&b) - - return b.String() -} diff --git a/vendor/github.com/4meepo/tagalign/.gitignore b/vendor/github.com/4meepo/tagalign/.gitignore deleted file mode 100644 index 1c6218ee29..0000000000 --- a/vendor/github.com/4meepo/tagalign/.gitignore +++ /dev/null @@ -1,76 +0,0 @@ -# File created using '.gitignore Generator' for Visual Studio Code: https://bit.ly/vscode-gig -# Created by https://www.toptal.com/developers/gitignore/api/visualstudiocode,macos,go -# Edit at https://www.toptal.com/developers/gitignore?templates=visualstudiocode,macos,go - -### Go ### -# If you prefer the allow list template instead of the deny list, see community template: -# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore -# -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib - -# Test binary, built with `go test -c` -*.test - -.vscode -.idea/ - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -# Dependency directories (remove the comment below to include it) -# vendor/ - -# Go workspace file -go.work - -### macOS ### -# 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 - -### macOS Patch ### -# iCloud generated files -*.icloud - -.history/ - -# Built Visual Studio Code Extensions -*.vsix - -### VisualStudioCode Patch ### -# Ignore all local history of files -.history -.ionide - -# End of https://www.toptal.com/developers/gitignore/api/visualstudiocode,macos,go - -# Custom rules (everything added below won't be overriden by 'Generate .gitignore File' if you use 'Update' option) diff --git a/vendor/github.com/4meepo/tagalign/.golangci.yml b/vendor/github.com/4meepo/tagalign/.golangci.yml deleted file mode 100644 index e65f604fe1..0000000000 --- a/vendor/github.com/4meepo/tagalign/.golangci.yml +++ /dev/null @@ -1,106 +0,0 @@ -# See https://golangci-lint.run/usage/configuration/ - -linters-settings: - revive: - # see https://github.com/mgechev/revive#available-rules for details. - ignore-generated-header: true - severity: warning - rules: - - name: atomic - - name: blank-imports - - name: bool-literal-in-expr - - name: call-to-gc - - name: confusing-naming - - name: confusing-results - - name: constant-logical-expr - - name: context-as-argument - - name: context-keys-type - - name: deep-exit - - name: defer - - name: dot-imports - - name: duplicated-imports - - name: early-return - - name: empty-block - - name: empty-lines - - name: error-naming - - name: error-return - - name: error-strings - - name: errorf - - name: exported - - name: get-return - - name: identical-branches - - name: if-return - - name: import-shadowing - - name: increment-decrement - - name: indent-error-flow - - name: modifies-parameter - - name: modifies-value-receiver - - name: package-comments - - name: range - - name: range-val-address - - name: range-val-in-closure - - name: receiver-naming - - name: redefines-builtin-id - - name: string-of-int - - name: superfluous-else - - name: time-naming - - name: unconditional-recursion - - name: unexported-naming - - name: unexported-return - - name: unnecessary-stmt - - name: unreachable-code - - name: unused-parameter - - name: var-declaration - - name: var-naming - - name: waitgroup-by-value - -linters: - disable-all: true - enable: - - asciicheck - - bodyclose - - dogsled - - dupl - - durationcheck - - errcheck - - errorlint - - exhaustive - - exportloopref - - forcetypeassert - - gochecknoinits - - gocognit - - goconst - - gocritic - - gocyclo - - godot - - godox - - goimports - - gomoddirectives - - gomodguard - - goprintffuncname - - gosec - - gosimple - # - govet - - importas - - ineffassign - - makezero - - misspell - - nakedret - - nestif - - nilerr - - noctx - - nolintlint - - prealloc - - predeclared - - revive - - rowserrcheck - - sqlclosecheck - - staticcheck - - stylecheck - - thelper - - tparallel - - typecheck - - unconvert - - unparam - - unused - - whitespace diff --git a/vendor/github.com/4meepo/tagalign/.goreleaser.yml b/vendor/github.com/4meepo/tagalign/.goreleaser.yml deleted file mode 100644 index 37dfec7c88..0000000000 --- a/vendor/github.com/4meepo/tagalign/.goreleaser.yml +++ /dev/null @@ -1,32 +0,0 @@ -version: 2 -project_name: tagalign - -release: - github: - owner: 4meepo - name: tagalign - -builds: - - binary: tagalign - goos: - - darwin - - windows - - linux - - freebsd - goarch: - - amd64 - - arm64 - - arm - goarm: - - 6 - - 7 - gomips: - - hardfloat - env: - - CGO_ENABLED=0 - ignore: - - goos: darwin - goarch: 386 - - goos: freebsd - goarch: arm64 - main: ./cmd/tagalign/ diff --git a/vendor/github.com/4meepo/tagalign/LICENSE b/vendor/github.com/4meepo/tagalign/LICENSE deleted file mode 100644 index da3ae82706..0000000000 --- a/vendor/github.com/4meepo/tagalign/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 Yifei Liu - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/4meepo/tagalign/Makefile b/vendor/github.com/4meepo/tagalign/Makefile deleted file mode 100644 index 614e7773c3..0000000000 --- a/vendor/github.com/4meepo/tagalign/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -.PHONY: lint -lint: - golangci-lint run ./... - -.PHONY: build -build: - go build -o tagalign cmd/tagalign/tagalign.go \ No newline at end of file diff --git a/vendor/github.com/4meepo/tagalign/README.md b/vendor/github.com/4meepo/tagalign/README.md deleted file mode 100644 index 9d04dccbf2..0000000000 --- a/vendor/github.com/4meepo/tagalign/README.md +++ /dev/null @@ -1,130 +0,0 @@ -# Go Tag Align - -![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/4meepo/tagalign?style=flat-square) -[![codecov](https://codecov.io/github/4meepo/tagalign/branch/main/graph/badge.svg?token=1R1T61UNBQ)](https://codecov.io/github/4meepo/tagalign) -[![GoDoc](https://godoc.org/github.com/4meepo/tagalign?status.svg)](https://pkg.go.dev/github.com/4meepo/tagalign) -[![Go Report Card](https://goreportcard.com/badge/github.com/4meepo/tagalign)](https://goreportcard.com/report/github.com/4meepo/tagalign) - -TagAlign is used to align and sort tags in Go struct. It can make the struct more readable and easier to maintain. - -For example, this struct - -```go -type FooBar struct { - Foo int `json:"foo" validate:"required"` - Bar string `json:"bar" validate:"required"` - FooFoo int8 `json:"foo_foo" validate:"required"` - BarBar int `json:"bar_bar" validate:"required"` - FooBar struct { - Foo int `json:"foo" yaml:"foo" validate:"required"` - Bar222 string `json:"bar222" validate:"required" yaml:"bar"` - } `json:"foo_bar" validate:"required"` - BarFoo string `json:"bar_foo" validate:"required"` - BarFooBar string `json:"bar_foo_bar" validate:"required"` -} -``` - -can be aligned to: - -```go -type FooBar struct { - Foo int `json:"foo" validate:"required"` - Bar string `json:"bar" validate:"required"` - FooFoo int8 `json:"foo_foo" validate:"required"` - BarBar int `json:"bar_bar" validate:"required"` - FooBar struct { - Foo int `json:"foo" yaml:"foo" validate:"required"` - Bar222 string `json:"bar222" validate:"required" yaml:"bar"` - } `json:"foo_bar" validate:"required"` - BarFoo string `json:"bar_foo" validate:"required"` - BarFooBar string `json:"bar_foo_bar" validate:"required"` -} -``` - -## Usage - -By default tagalign will only align tags, but not sort them. But alignment and [sort feature](https://github.com/4meepo/tagalign#sort-tag) can work together or separately. - -* As a Golangci Linter (Recommended) - - Tagalign is a built-in linter in [Golangci Lint](https://golangci-lint.run/usage/linters/#tagalign) since `v1.53`. - > Note: In order to have the best experience, add the `--fix` flag to `golangci-lint` to enable the autofix feature. - -* Standalone Mode - - Install it using `GO` or download it [here](https://github.com/4meepo/tagalign/releases). - - ```bash - go install github.com/4meepo/tagalign/cmd/tagalign@latest - ``` - - Run it in your terminal. - - ```bash - # Only align tags. - tagalign -fix {package path} - # Only sort tags with fixed order. - tagalign -fix -noalign -sort -order "json,xml" {package path} - # Align and sort together. - tagalign -fix -sort -order "json,xml" {package path} - # Align and sort together in strict style. - tagalign -fix -sort -order "json,xml" -strict {package path} - ``` - -## Advanced Features - -### Sort Tag - -In addition to alignment, it can also sort tags with fixed order. If we enable sort with fixed order `json,xml`, the following code - -```go -type SortExample struct { - Foo int `json:"foo,omitempty" yaml:"bar" xml:"baz" binding:"required" gorm:"column:foo" zip:"foo" validate:"required"` - Bar int `validate:"required" yaml:"foo" xml:"bar" binding:"required" json:"bar,omitempty" gorm:"column:bar" zip:"bar" ` - FooBar int `gorm:"column:bar" validate:"required" xml:"bar" binding:"required" json:"bar,omitempty" zip:"bar" yaml:"foo"` -} -``` - -will be sorted and aligned to: - -```go -type SortExample struct { - Foo int `json:"foo,omitempty" xml:"baz" binding:"required" gorm:"column:foo" validate:"required" yaml:"bar" zip:"foo"` - Bar int `json:"bar,omitempty" xml:"bar" binding:"required" gorm:"column:bar" validate:"required" yaml:"foo" zip:"bar"` - FooBar int `json:"bar,omitempty" xml:"bar" binding:"required" gorm:"column:bar" validate:"required" yaml:"foo" zip:"bar"` -} -``` - -The fixed order is `json,xml`, so the tags `json` and `xml` will be sorted and aligned first, and the rest tags will be sorted and aligned in the dictionary order. - -### Strict Style - -Sometimes, you may want to align your tags in strict style. In this style, the tags will be sorted and aligned in the dictionary order, and the tags with the same name will be aligned together. For example, the following code - -```go -type StrictStyleExample struct { - Foo int ` xml:"baz" yaml:"bar" zip:"foo" binding:"required" gorm:"column:foo" validate:"required"` - Bar int `validate:"required" gorm:"column:bar" yaml:"foo" xml:"bar" binding:"required" json:"bar,omitempty" ` -} -``` - -will be aligned to - -```go -type StrictStyleExample struct { - Foo int `binding:"required" gorm:"column:foo" validate:"required" xml:"baz" yaml:"bar" zip:"foo"` - Bar int `binding:"required" gorm:"column:bar" json:"bar,omitempty" validate:"required" xml:"bar" yaml:"foo"` -} -``` - -> ⚠️Note: The strict style can't run without the align or sort feature enabled. - -## References - -[Golang AST Visualizer](http://goast.yuroyoro.net/) - -[Create New Golang CI Linter](https://golangci-lint.run/contributing/new-linters/) - -[Autofix Example](https://github.com/golangci/golangci-lint/pull/2450/files) - -[Integrating](https://disaev.me/p/writing-useful-go-analysis-linter/#integrating) diff --git a/vendor/github.com/4meepo/tagalign/options.go b/vendor/github.com/4meepo/tagalign/options.go deleted file mode 100644 index 2a78592465..0000000000 --- a/vendor/github.com/4meepo/tagalign/options.go +++ /dev/null @@ -1,30 +0,0 @@ -package tagalign - -type Option func(*Helper) - -// WithSort enable tags sort. -// fixedOrder specify the order of tags, the other tags will be sorted by name. -// Sory is disabled by default. -func WithSort(fixedOrder ...string) Option { - return func(h *Helper) { - h.sort = true - h.fixedTagOrder = fixedOrder - } -} - -// WithAlign configure whether enable tags align. -// Align is enabled by default. -func WithAlign(enabled bool) Option { - return func(h *Helper) { - h.align = enabled - } -} - -// WithStrictStyle configure whether enable strict style. -// StrictStyle is disabled by default. -// Note: StrictStyle must be used with WithAlign(true) and WithSort(...) together, or it will be ignored. -func WithStrictStyle() Option { - return func(h *Helper) { - h.style = StrictStyle - } -} diff --git a/vendor/github.com/4meepo/tagalign/tagalign.go b/vendor/github.com/4meepo/tagalign/tagalign.go deleted file mode 100644 index 612aefb0b1..0000000000 --- a/vendor/github.com/4meepo/tagalign/tagalign.go +++ /dev/null @@ -1,394 +0,0 @@ -package tagalign - -import ( - "cmp" - "fmt" - "go/ast" - "go/token" - "reflect" - "slices" - "strconv" - "strings" - - "github.com/alfatraining/structtag" - "golang.org/x/tools/go/analysis" -) - -type Style int - -const ( - DefaultStyle Style = iota - StrictStyle -) - -const ( - errTagValueSyntax = "bad syntax for struct tag value" -) - -func NewAnalyzer(options ...Option) *analysis.Analyzer { - return &analysis.Analyzer{ - Name: "tagalign", - Doc: "check that struct tags are well aligned", - Run: func(p *analysis.Pass) (any, error) { - Run(p, options...) - return nil, nil - }, - } -} - -func Run(pass *analysis.Pass, options ...Option) { - for _, f := range pass.Files { - filename := getFilename(pass.Fset, f) - if !strings.HasSuffix(filename, ".go") { - continue - } - - h := &Helper{ - style: DefaultStyle, - align: true, - } - for _, opt := range options { - opt(h) - } - - // StrictStyle must be used with WithAlign(true) and WithSort(...) together, or it will be ignored. - if h.style == StrictStyle && (!h.align || !h.sort) { - h.style = DefaultStyle - } - - if !h.align && !h.sort { - // do nothing - return - } - - ast.Inspect(f, func(n ast.Node) bool { - h.find(pass, n) - return true - }) - - h.Process(pass) - } -} - -type Helper struct { - style Style - - align bool // whether enable tags align. - sort bool // whether enable tags sort. - fixedTagOrder []string // the order of tags, the other tags will be sorted by name. - - singleFields []*ast.Field - consecutiveFieldsGroups [][]*ast.Field // fields in this group, must be consecutive in struct. -} - -func (w *Helper) find(pass *analysis.Pass, n ast.Node) { - v, ok := n.(*ast.StructType) - if !ok { - return - } - - fields := v.Fields.List - if len(fields) == 0 { - return - } - - fs := make([]*ast.Field, 0) - split := func() { - n := len(fs) - if n > 1 { - w.consecutiveFieldsGroups = append(w.consecutiveFieldsGroups, fs) - } else if n == 1 { - w.singleFields = append(w.singleFields, fs[0]) - } - - fs = nil - } - - for i, field := range fields { - if field.Tag == nil { - // field without tags - split() - continue - } - - if i > 0 { - if fields[i-1].Tag == nil { - // if previous filed do not have a tag - fs = append(fs, field) - continue - } - preLineNum := pass.Fset.Position(fields[i-1].Tag.Pos()).Line - lineNum := pass.Fset.Position(field.Tag.Pos()).Line - if lineNum-preLineNum > 1 { - // fields with tags are not consecutive, including two case: - // 1. splited by lines - // 2. splited by a struct - split() - - // check if the field is a struct - if _, ok := field.Type.(*ast.StructType); ok { - continue - } - } - } - - fs = append(fs, field) - } - - split() -} - -func (w *Helper) report(pass *analysis.Pass, field *ast.Field, msg, replaceStr string) { - pass.Report(analysis.Diagnostic{ - Pos: field.Tag.Pos(), - End: field.Tag.End(), - Message: msg, - SuggestedFixes: []analysis.SuggestedFix{ - { - Message: msg, - TextEdits: []analysis.TextEdit{ - { - Pos: field.Tag.Pos(), - End: field.Tag.End(), - NewText: []byte(replaceStr), - }, - }, - }, - }, - }) -} - -//nolint:gocognit,gocyclo,nestif -func (w *Helper) Process(pass *analysis.Pass) { - // process grouped fields - for _, fields := range w.consecutiveFieldsGroups { - offsets := make([]int, len(fields)) - - var maxTagNum int - var tagsGroup, notSortedTagsGroup [][]*structtag.Tag - - var uniqueKeys []string - addKey := func(k string) { - for _, key := range uniqueKeys { - if key == k { - return - } - } - uniqueKeys = append(uniqueKeys, k) - } - - for i := 0; i < len(fields); { - field := fields[i] - column := pass.Fset.Position(field.Tag.Pos()).Column - 1 - offsets[i] = column - - tag, err := strconv.Unquote(field.Tag.Value) - if err != nil { - // if tag value is not a valid string, report it directly - w.report(pass, field, errTagValueSyntax, field.Tag.Value) - fields = removeField(fields, i) - continue - } - - tags, err := structtag.Parse(tag) - if err != nil { - // if tag value is not a valid struct tag, report it directly - w.report(pass, field, err.Error(), field.Tag.Value) - fields = removeField(fields, i) - continue - } - - maxTagNum = max(maxTagNum, tags.Len()) - - if w.sort { - cp := make([]*structtag.Tag, tags.Len()) - for i, tag := range tags.Tags() { - cp[i] = tag - } - notSortedTagsGroup = append(notSortedTagsGroup, cp) - sortTags(w.fixedTagOrder, tags) - } - for _, t := range tags.Tags() { - addKey(t.Key) - } - tagsGroup = append(tagsGroup, tags.Tags()) - - i++ - } - - if w.sort && StrictStyle == w.style { - sortKeys(w.fixedTagOrder, uniqueKeys) - maxTagNum = len(uniqueKeys) - } - - // record the max length of each column tag - type tagLen struct { - Key string // present only when sort enabled - Len int - } - tagMaxLens := make([]tagLen, maxTagNum) - for j := 0; j < maxTagNum; j++ { - var maxLength int - var key string - for i := 0; i < len(tagsGroup); i++ { - if w.style == StrictStyle { - key = uniqueKeys[j] - // search by key - for _, tag := range tagsGroup[i] { - if tag.Key == key { - maxLength = max(maxLength, len(tag.String())) - break - } - } - } else { - if len(tagsGroup[i]) <= j { - // in case of index out of range - continue - } - maxLength = max(maxLength, len(tagsGroup[i][j].String())) - } - } - tagMaxLens[j] = tagLen{key, maxLength} - } - - for i, field := range fields { - tags := tagsGroup[i] - - var newTagStr string - if w.align { - // if align enabled, align tags. - newTagBuilder := strings.Builder{} - for i, n := 0, 0; i < len(tags) && n < len(tagMaxLens); { - tag := tags[i] - var format string - if w.style == StrictStyle { - if tagMaxLens[n].Key == tag.Key { - // match - format = alignFormat(tagMaxLens[n].Len + 1) // with an extra space - newTagBuilder.WriteString(fmt.Sprintf(format, tag.String())) - i++ - n++ - } else { - // tag missing - format = alignFormat(tagMaxLens[n].Len + 1) - newTagBuilder.WriteString(fmt.Sprintf(format, "")) - n++ - } - } else { - format = alignFormat(tagMaxLens[n].Len + 1) // with an extra space - newTagBuilder.WriteString(fmt.Sprintf(format, tag.String())) - i++ - n++ - } - } - newTagStr = newTagBuilder.String() - } else { - // otherwise check if tags order changed - if w.sort && reflect.DeepEqual(notSortedTagsGroup[i], tags) { - // if tags order not changed, do nothing - continue - } - tagsStr := make([]string, len(tags)) - for i, tag := range tags { - tagsStr[i] = tag.String() - } - newTagStr = strings.Join(tagsStr, " ") - } - - unquoteTag := strings.TrimRight(newTagStr, " ") - // unquoteTag := newTagStr - newTagValue := fmt.Sprintf("`%s`", unquoteTag) - if field.Tag.Value == newTagValue { - // nothing changed - continue - } - - msg := "tag is not aligned, should be: " + unquoteTag - - w.report(pass, field, msg, newTagValue) - } - } - - // process single fields - for _, field := range w.singleFields { - tag, err := strconv.Unquote(field.Tag.Value) - if err != nil { - w.report(pass, field, errTagValueSyntax, field.Tag.Value) - continue - } - - tags, err := structtag.Parse(tag) - if err != nil { - w.report(pass, field, err.Error(), field.Tag.Value) - continue - } - originalTags := append([]*structtag.Tag(nil), tags.Tags()...) - if w.sort { - sortTags(w.fixedTagOrder, tags) - } - - newTagValue := fmt.Sprintf("`%s`", tags.String()) - if reflect.DeepEqual(originalTags, tags.Tags()) && field.Tag.Value == newTagValue { - // if tags order not changed, do nothing - continue - } - - msg := "tag is not aligned , should be: " + tags.String() - - w.report(pass, field, msg, newTagValue) - } -} - -// sortTags sorts tags by fixed order. -// If a tag is not in the fixed order, it will be sorted by name. -func sortTags(fixedOrder []string, tags *structtag.Tags) { - slices.SortFunc(tags.Tags(), func(a, b *structtag.Tag) int { - return compareByFixedOrder(fixedOrder)(a.Key, b.Key) - }) -} - -func sortKeys(fixedOrder []string, keys []string) { - slices.SortFunc(keys, compareByFixedOrder(fixedOrder)) -} - -func compareByFixedOrder(fixedOrder []string) func(a, b string) int { - return func(a, b string) int { - oi := slices.Index(fixedOrder, a) - oj := slices.Index(fixedOrder, b) - - if oi == -1 && oj == -1 { - return strings.Compare(a, b) - } - - if oi == -1 { - return 1 - } - - if oj == -1 { - return -1 - } - - return cmp.Compare(oi, oj) - } -} - -func alignFormat(length int) string { - return "%" + fmt.Sprintf("-%ds", length) -} - -func removeField(fields []*ast.Field, index int) []*ast.Field { - if index < 0 || index >= len(fields) { - return fields - } - - return append(fields[:index], fields[index+1:]...) -} - -func getFilename(fset *token.FileSet, file *ast.File) string { - filename := fset.PositionFor(file.Pos(), true).Filename - if !strings.HasSuffix(filename, ".go") { - return fset.PositionFor(file.Pos(), false).Filename - } - - return filename -} diff --git a/vendor/github.com/Abirdcfly/dupword/.gitignore b/vendor/github.com/Abirdcfly/dupword/.gitignore deleted file mode 100644 index b5109d2bbf..0000000000 --- a/vendor/github.com/Abirdcfly/dupword/.gitignore +++ /dev/null @@ -1,183 +0,0 @@ - -# Godot-specific ignores -.import/ -export.cfg -export_presets.cfg - -# Mono-specific ignores -.mono/ -data_*/ - -### JetBrains template -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider -# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 - -# User-specific stuff -.idea/**/workspace.xml -.idea/**/tasks.xml -.idea/**/usage.statistics.xml -.idea/**/dictionaries -.idea/**/shelf - -# Generated files -.idea/**/contentModel.xml - -# Sensitive or high-churn files -.idea/**/dataSources/ -.idea/**/dataSources.ids -.idea/**/dataSources.local.xml -.idea/**/sqlDataSources.xml -.idea/**/dynamic.xml -.idea/**/uiDesigner.xml -.idea/**/dbnavigator.xml - -# Gradle -.idea/**/gradle.xml -.idea/**/libraries - -# Gradle and Maven with auto-import -# When using Gradle or Maven with auto-import, you should exclude module files, -# since they will be recreated, and may cause churn. Uncomment if using -# auto-import. -.idea/artifacts -.idea/compiler.xml -.idea/jarRepositories.xml -.idea/modules.xml -.idea/*.iml -.idea/modules -*.iml -*.ipr - -# CMake -cmake-build-*/ - -# Mongo Explorer plugin -.idea/**/mongoSettings.xml - -# File-based project format -*.iws - -# IntelliJ -out/ - -# mpeltonen/sbt-idea plugin -.idea_modules/ - -# JIRA plugin -atlassian-ide-plugin.xml - -# Cursive Clojure plugin -.idea/replstate.xml - -# Crashlytics plugin (for Android Studio and IntelliJ) -com_crashlytics_export_strings.xml -crashlytics.properties -crashlytics-build.properties -fabric.properties - -# Editor-based Rest Client -.idea/httpRequests - -# Android studio 3.1+ serialized cache file -.idea/caches/build_file_checksums.ser - -### Emacs template -# -*- mode: gitignore; -*- -*~ -\#*\# -/.emacs.desktop -/.emacs.desktop.lock -*.elc -auto-save-list -tramp -.\#* - -# Org-mode -.org-id-locations -*_archive - -# flymake-mode -*_flymake.* - -# eshell files -/eshell/history -/eshell/lastdir - -# elpa packages -/elpa/ - -# reftex files -*.rel - -# AUCTeX auto folder -/auto/ - -# cask packages -.cask/ -dist/ - -# Flycheck -flycheck_*.el - -# server auth directory -/server/ - -# projectiles files -.projectile - -# directory configuration -.dir-locals.el - -# network security -/network-security.data - - -### Vim template -# Swap -[._]*.s[a-v][a-z] -!*.svg # comment out if you don't need vector files -[._]*.sw[a-p] -[._]s[a-rt-v][a-z] -[._]ss[a-gi-z] -[._]sw[a-p] - -# Session -Session.vim -Sessionx.vim - -# Temporary -.netrwhist -*~ -# Auto-generated tag files -tags -# Persistent undo -[._]*.un~ - -### macOS template -# 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 - diff --git a/vendor/github.com/Abirdcfly/dupword/.goreleaser.yml b/vendor/github.com/Abirdcfly/dupword/.goreleaser.yml deleted file mode 100644 index c3401787a0..0000000000 --- a/vendor/github.com/Abirdcfly/dupword/.goreleaser.yml +++ /dev/null @@ -1,72 +0,0 @@ ---- -project_name: dupword - -release: - github: - owner: Abirdcfly - name: dupword - -builds: - - binary: dupword - goos: - - darwin - - windows - - linux - - freebsd - goarch: - - amd64 - - arm64 - - arm - - 386 - - ppc64le - - s390x - - mips64 - - mips64le - - riscv64 - goarm: - - 6 - - 7 - gomips: - - hardfloat - env: - - CGO_ENABLED=0 - ignore: - - goos: darwin - goarch: 386 - - goos: freebsd - goarch: arm64 - main: ./cmd/dupword/ - flags: - - -trimpath - ldflags: -s -w -X main.version={{.Version}} -X main.commit={{.ShortCommit}} -X main.date={{.Date}} - -archives: - - format: tar.gz - wrap_in_directory: true - format_overrides: - - goos: windows - format: zip - name_template: '{{ .ProjectName }}-{{ .Version }}-{{ .Os }}-{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}' - files: - - LICENSE - - README.md - -snapshot: - name_template: SNAPSHOT-{{ .Commit }} - -checksum: - name_template: '{{ .ProjectName }}-{{ .Version }}-checksums.txt' - -changelog: - sort: asc - filters: - exclude: - - '(?i)^docs?:' - - '(?i)^docs\([^:]+\):' - - '(?i)^docs\[[^:]+\]:' - - '^tests?:' - - '(?i)^dev:' - - '^build\(deps\): bump .* in /docs \(#\d+\)' - - '^build\(deps\): bump .* in /\.github/peril \(#\d+\)' - - Merge pull request - - Merge branch diff --git a/vendor/github.com/Abirdcfly/dupword/LICENSE b/vendor/github.com/Abirdcfly/dupword/LICENSE deleted file mode 100644 index afa64c6e1e..0000000000 --- a/vendor/github.com/Abirdcfly/dupword/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2022 Abirdcfly - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/Abirdcfly/dupword/README.md b/vendor/github.com/Abirdcfly/dupword/README.md deleted file mode 100644 index a3db4c5037..0000000000 --- a/vendor/github.com/Abirdcfly/dupword/README.md +++ /dev/null @@ -1,157 +0,0 @@ -# dupword - -![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/Abirdcfly/dupword?style=flat-square) -[![GoDoc](https://godoc.org/github.com/Abirdcfly/dupword?status.svg)](https://pkg.go.dev/github.com/Abirdcfly/dupword) -[![Actions Status](https://github.com/Abirdcfly/dupword/actions/workflows/lint.yml/badge.svg)](https://github.com/Abirdcfly/dupword/actions) -[![Go Report Card](https://goreportcard.com/badge/github.com/Abirdcfly/dupword)](https://goreportcard.com/report/github.com/Abirdcfly/dupword) - -A linter that checks for duplicate words in the source code (usually miswritten) - -Examples in real code and related issues can be viewed in [dupword#3](https://github.com/Abirdcfly/dupword/issues/3) - -## example - -1. Repeated words appear on two adjacent lines [commit](https://github.com/golang/go/commit/d8f90ce0f8119bf593efb6fb91825de5b61fcda7) - -```diff ---- a/src/cmd/compile/internal/ssa/schedule.go -+++ b/src/cmd/compile/internal/ssa/schedule.go -@@ -179,7 +179,7 @@ func schedule(f *Func) { - // scored CarryChainTail (and prove w is not a tail). - score[w.ID] = ScoreFlags - } -- // Verify v has not been scored. If v has not been visited, v may be the -+ // Verify v has not been scored. If v has not been visited, v may be - // the final (tail) operation in a carry chain. If v is not, v will be - // rescored above when v's carry-using op is scored. When scoring is done, - // only tail operations will retain the CarryChainTail score. -``` - -2. Repeated words appearing on the same line [commit](https://github.com/golang/go/commit/48da729e8468b630ee003ac51cbaac595d53bec8) - -```diff ---- a/src/net/http/cookiejar/jar.go -+++ b/src/net/http/cookiejar/jar.go -@@ -465,7 +465,7 @@ func (j *Jar) domainAndType(host, domain string) (string, bool, error) { - // dot in the domain-attribute before processing the cookie. - // - // Most browsers don't do that for IP addresses, only curl -- // version 7.54) and and IE (version 11) do not reject a -+ // version 7.54) and IE (version 11) do not reject a - // Set-Cookie: a=1; domain=.127.0.0.1 - // This leading dot is optional and serves only as hint for - // humans to indicate that a cookie with "domain=.bbc.co.uk" -``` - -## Install - -```bash -go install github.com/Abirdcfly/dupword/cmd/dupword@latest -``` - -**Or** install the main branch (including the last commit) with: - -```bash -go install github.com/Abirdcfly/dupword/cmd/dupword@main -``` - -## Usage - -### 1. default - -Run with default settings(include test file): - -**But note that not all repeated words are wrong** see [dupword#4](https://github.com/Abirdcfly/dupword/issues/4) for real code example. - -```bash -$ dupword ./... -/Users/xxx/go/src/dupword/dupword_test.go:88:10: Duplicate words (the) found -exit status 3 -``` - -### 2. skip test file - -Skip detection test file(`*_test.go`): - -```bash -$ dupword -test=false ./... -``` - -### 3. auto-fix - -```bash -$ dupword -fix ./... -``` - -### 4. all options - -All options: - -```bash -$ dupword --help -dupword: checks for duplicate words in the source code (usually miswritten) - -Usage: dupword [-flag] [package] - -This analyzer checks miswritten duplicate words in comments or package doc or string declaration - -Flags: - -V print version and exit - -all - no effect (deprecated) - -c int - display offending line with this many lines of context (default -1) - -comments-only - check only comments, skip strings - -cpuprofile string - write CPU profile to this file - -debug string - debug flags, any subset of "fpstv" - -diff - with -fix, don't update the files, but print a unified diff - -fix - apply all suggested fixes - -flags - print analyzer flags in JSON - -ignore value - ignore words - -json - emit JSON output - -keyword value - keywords for detecting duplicate words - -memprofile string - write memory profile to this file - -source - no effect (deprecated) - -tags string - no effect (deprecated) - -test - indicates whether test files should be analyzed, too (default true) - -trace string - write trace log to this file - -v no effect (deprecated) -``` - -### 5. my advice - -use `--keyword=the,and,a` and `-fix` together. I think that specifying only commonly repeated prepositions can effectively avoid false positives. - -see [dupword#4](https://github.com/Abirdcfly/dupword/issues/4) for real code example. - -```bash -$ dupword --keyword=the,and,a -fix ./... -``` - -## TODO - -- [x] add this linter to golangci-lint -- [ ] rewrite the detection logic to make it more efficient - -## Limitation - -1. Only for `*.go` file.But some miswritten occurs in `*.md` or `*.json` file.(example: kubernetes), In this case, my advice is to use [rg](https://github.com/BurntSushi/ripgrep) to do the lookup and replace manually. -2. When use `-fix`, also running `go fmt` in the dark.([This logic is determined upstream](https://github.com/golang/tools/blob/248c34b88a4148128f89e41923498bd86f805b7d/go/analysis/internal/checker/checker.go#L424-L433), the project does not have this part of the code.) - -## License - -MIT diff --git a/vendor/github.com/Abirdcfly/dupword/dupword.go b/vendor/github.com/Abirdcfly/dupword/dupword.go deleted file mode 100644 index a3eaced8a2..0000000000 --- a/vendor/github.com/Abirdcfly/dupword/dupword.go +++ /dev/null @@ -1,353 +0,0 @@ -// MIT License -// -// Copyright (c) 2022 Abirdcfly -// -// 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. - -// Package dupword defines an Analyzer that checks those duplicate words in the source code. -package dupword - -import ( - "flag" - "fmt" - "go/ast" - "go/token" - "sort" - "strconv" - "strings" - "unicode" - "unicode/utf8" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/inspector" -) - -const ( - Name = "dupword" - Doc = `checks for duplicate words in the source code (usually miswritten) - -This analyzer checks miswritten duplicate words in comments or package doc or string declaration` - Message = "Duplicate words (%s) found" - CommentPrefix = `//` -) - -type keywords []string - -func (a keywords) String() string { - return strings.Join(a, ",") -} - -func (a *keywords) Set(w string) error { - if len(w) != 0 { - *a = append(*a, strings.Split(w, ",")...) - } - - return nil -} - -type ignore map[string]bool - -func (a ignore) String() string { - var t []string - - for k := range a { - t = append(t, k) - } - - return strings.Join(t, ",") -} - -func (a ignore) Set(w string) error { - for _, k := range strings.Split(w, ",") { - a[k] = true - } - - return nil -} - -func NewAnalyzer() *analysis.Analyzer { - analyzer := &analyzer{ - ignoreWords: map[string]bool{}, - } - - a := &analysis.Analyzer{ - Name: Name, - Doc: Doc, - Requires: []*analysis.Analyzer{inspect.Analyzer}, - Run: analyzer.run, - RunDespiteErrors: true, - } - - a.Flags.Init(Name, flag.ExitOnError) - a.Flags.Var(&analyzer.keywords, "keyword", "keywords for detecting duplicate words") - a.Flags.Var(&analyzer.ignoreWords, "ignore", "ignore words") - a.Flags.BoolVar(&analyzer.commentsOnly, "comments-only", false, "check only comments, skip strings") - a.Flags.Var(version{}, "V", "print version and exit") - - return a -} - -type analyzer struct { - keywords keywords - ignoreWords ignore - commentsOnly bool -} - -func (a *analyzer) run(pass *analysis.Pass) (interface{}, error) { - for _, file := range pass.Files { - a.fixDuplicateWordInComment(pass, file) - } - if a.commentsOnly { - return nil, nil - } - inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - nodeFilter := []ast.Node{ - (*ast.BasicLit)(nil), - } - inspect.Preorder(nodeFilter, func(n ast.Node) { - if lit, ok := n.(*ast.BasicLit); ok { - a.fixDuplicateWordInString(pass, lit) - } - }) - return nil, nil -} - -func (a *analyzer) fixDuplicateWordInComment(pass *analysis.Pass, f *ast.File) { - isTestFile := strings.HasSuffix(pass.Fset.File(f.FileStart).Name(), "_test.go") - for _, cg := range f.Comments { - // avoid checking example outputs for duplicate words - if isTestFile && isExampleOutputStart(cg.List[0].Text) { - continue - } - var preLine *ast.Comment - for _, c := range cg.List { - update, keyword, find := a.Check(c.Text) - if find { - pass.Report(analysis.Diagnostic{Pos: c.Slash, End: c.End(), Message: fmt.Sprintf(Message, keyword), SuggestedFixes: []analysis.SuggestedFix{{ - Message: "Update", - TextEdits: []analysis.TextEdit{{ - Pos: c.Slash, - End: c.End(), - NewText: []byte(update), - }}, - }}}) - } - if preLine != nil { - fields := strings.Fields(preLine.Text) - if len(fields) < 1 { - continue - } - preLineContent := fields[len(fields)-1] + "\n" - thisLineContent := c.Text - if find { - thisLineContent = update - } - before, after, _ := strings.Cut(thisLineContent, CommentPrefix) - update, keyword, find := a.Check(preLineContent + after) - if find { - var suggestedFixes []analysis.SuggestedFix - if strings.Contains(update, preLineContent) { - update = before + CommentPrefix + strings.TrimPrefix(update, preLineContent) - suggestedFixes = []analysis.SuggestedFix{{ - Message: "Update", - TextEdits: []analysis.TextEdit{{ - Pos: c.Slash, - End: c.End(), - NewText: []byte(update), - }}, - }} - } - pass.Report(analysis.Diagnostic{Pos: c.Slash, End: c.End(), Message: fmt.Sprintf(Message, keyword), SuggestedFixes: suggestedFixes}) - } - } - preLine = c - } - } -} - -func (a *analyzer) fixDuplicateWordInString(pass *analysis.Pass, lit *ast.BasicLit) { - if lit.Kind != token.STRING { - return - } - value, err := strconv.Unquote(lit.Value) - if err != nil { - fmt.Printf("lit.Value:%v, err: %v\n", lit.Value, err) - // fall back to default - value = lit.Value - } - quote := value != lit.Value - update, keyword, find := a.Check(value) - if quote { - update = strconv.Quote(update) - } - if find { - pass.Report(analysis.Diagnostic{Pos: lit.Pos(), End: lit.End(), Message: fmt.Sprintf(Message, keyword), SuggestedFixes: []analysis.SuggestedFix{{ - Message: "Update", - TextEdits: []analysis.TextEdit{{ - Pos: lit.Pos(), - End: lit.End(), - NewText: []byte(update), - }}, - }}}) - } -} - -// CheckOneKey use to check there is a defined duplicate word in a string. -// `raw` is the checked line. key is the keyword to check. empty means just check duplicate word. -func (a *analyzer) checkOneKey(raw, key string) (new string, findWord string, find bool) { - if key == "" { - has := false - fields := strings.Fields(raw) - for i := range fields { - if i == len(fields)-1 { - break - } - if fields[i] == fields[i+1] { - has = true - } - } - if !has { - return - } - } else { - if x := strings.Split(raw, key); len(x) < 2 { - return - } - } - - findWordMap := make(map[string]bool, 4) - newLine := strings.Builder{} - wordStart, spaceStart := 0, 0 - curWord, preWord := "", "" - lastSpace := "" - var lastRune int32 - for i, r := range raw { - if !unicode.IsSpace(r) && unicode.IsSpace(lastRune) { - // word start position - /* - i - | - hello[ spaceA ]the[ spaceB ]the[ spaceC ]word - ^ ^ - | curWord: the - preWord: the - */ - symbol := raw[spaceStart:i] - if ((key != "" && curWord == key) || key == "") && curWord == preWord && curWord != "" { - if !a.excludeWords(cutTrailingCommas(curWord)) { - find = true - findWordMap[curWord] = true - newLine.WriteString(lastSpace) - symbol = "" - } - } else { - newLine.WriteString(lastSpace) - newLine.WriteString(curWord) - } - lastSpace = symbol - preWord = curWord - wordStart = i - } else if unicode.IsSpace(r) && !unicode.IsSpace(lastRune) { - // space start position - spaceStart = i - curWord = raw[wordStart:i] - } else if i == len(raw)-1 { - // last position - word := raw[wordStart:] - if ((key != "" && word == key) || key == "") && word == preWord { - if !a.excludeWords(cutTrailingCommas(word)) { - find = true - findWordMap[word] = true - } - } else { - newLine.WriteString(lastSpace) - newLine.WriteString(word) - } - } - lastRune = r - } - if find { - new = newLine.String() - findWordSlice := make([]string, len(findWordMap)) - i := 0 - for k := range findWordMap { - findWordSlice[i] = k - i++ - } - sort.Strings(findWordSlice) - findWord = strings.Join(findWordSlice, ",") - } - return -} - -func (a *analyzer) Check(raw string) (update string, keyword string, find bool) { - for _, key := range a.keywords { - updateOne, _, findOne := a.checkOneKey(raw, key) - if findOne { - raw = updateOne - find = findOne - update = updateOne - if keyword == "" { - keyword = key - } else { - keyword = keyword + "," + key - } - } - } - if len(a.keywords) == 0 { - return a.checkOneKey(raw, "") - } - return -} - -// ExcludeWords determines whether duplicate words should be reported, -// -// e.g. %s, should not be reported. -func (a *analyzer) excludeWords(word string) (exclude bool) { - firstRune, _ := utf8.DecodeRuneInString(word) - if unicode.IsDigit(firstRune) { - return true - } - if unicode.IsPunct(firstRune) { - return true - } - if unicode.IsSymbol(firstRune) { - return true - } - if _, exist := a.ignoreWords[word]; exist { - return true - } - return false -} - -func isExampleOutputStart(comment string) bool { - return strings.HasPrefix(comment, "// Output:") || - strings.HasPrefix(comment, "// output:") || - strings.HasPrefix(comment, "// Unordered output:") || - strings.HasPrefix(comment, "// unordered output:") -} - -// cutTrailingCommas is used to remove trailing commas of words. -// The excludeWords are provided as comma-separated list, so it is -// impossible to ignore "[word], [word]," matches otherwise -func cutTrailingCommas(s string) string { - result, _ := strings.CutSuffix(s, ",") - return result -} diff --git a/vendor/github.com/Abirdcfly/dupword/version.go b/vendor/github.com/Abirdcfly/dupword/version.go deleted file mode 100644 index 9d892d0c98..0000000000 --- a/vendor/github.com/Abirdcfly/dupword/version.go +++ /dev/null @@ -1,41 +0,0 @@ -// MIT License -// -// # Copyright (c) 2022 Abirdcfly -// -// 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. - -package dupword - -import ( - "fmt" - "os" -) - -var Version = "dev" - -type version struct{} - -func (version) IsBoolFlag() bool { return true } -func (version) Get() interface{} { return nil } -func (version) String() string { return "" } -func (version) Set(_ string) error { - fmt.Println(Version) - os.Exit(0) - return nil -} diff --git a/vendor/github.com/AdminBenni/iota-mixing/LICENSE b/vendor/github.com/AdminBenni/iota-mixing/LICENSE deleted file mode 100644 index 06e009ffaf..0000000000 --- a/vendor/github.com/AdminBenni/iota-mixing/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2025 Benedikt Aron Þjóðbjargarson - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/AdminBenni/iota-mixing/pkg/analyzer/analyzer.go b/vendor/github.com/AdminBenni/iota-mixing/pkg/analyzer/analyzer.go deleted file mode 100644 index 4c56ebddeb..0000000000 --- a/vendor/github.com/AdminBenni/iota-mixing/pkg/analyzer/analyzer.go +++ /dev/null @@ -1,118 +0,0 @@ -package analyzer - -import ( - "go/ast" - "go/token" - "log" - "strings" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/inspector" - - "github.com/AdminBenni/iota-mixing/pkg/analyzer/flags" -) - -func GetIotaMixingAnalyzer() *analysis.Analyzer { - return &analysis.Analyzer{ - Name: "iotamixing", - Doc: "checks if iotas are being used in const blocks with other non-iota declarations.", - Run: run, - Requires: []*analysis.Analyzer{inspect.Analyzer}, - } -} - -func run(pass *analysis.Pass) (interface{}, error) { - ASTInspector := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) //nolint:forcetypeassert // will always be correct type - - // we only need to check Generic Declarations - nodeFilter := []ast.Node{ - (*ast.GenDecl)(nil), - } - - ASTInspector.Preorder(nodeFilter, func(node ast.Node) { checkGenericDeclaration(node, pass) }) - - return interface{}(nil), nil -} - -func checkGenericDeclaration(node ast.Node, pass *analysis.Pass) { - decl := node.(*ast.GenDecl) //nolint:forcetypeassert // filtered for this node, will always be this type - - if decl.Tok != token.CONST { - return - } - - checkConstDeclaration(decl, pass) -} - -func checkConstDeclaration(decl *ast.GenDecl, pass *analysis.Pass) { - iotaFound := false - valued := make([]*ast.ValueSpec, 0, len(decl.Specs)) - - // traverse specs inside const block - for _, spec := range decl.Specs { - if specVal, ok := spec.(*ast.ValueSpec); ok { - iotaFound, valued = checkValueSpec(specVal, iotaFound, valued) - } - } - - if !iotaFound { - return - } - - // there was an iota, now depending on the report-individual flag we must either - // report the const block or all regular valued specs that are mixing with the iota - switch flags.ReportIndividualFlag() { - case flags.TrueString: - for _, value := range valued { - pass.Reportf( - value.Pos(), - "%s is a const with r-val in same const block as iota. keep iotas in separate const blocks", - getName(value), - ) - } - default: //nolint:gocritic // default logs error and falls through to "false" case, simplest in this order - log.Printf( - "warning: unsupported value '%s' for flag %s, assuming value 'false'.", - flags.ReportIndividualFlag(), flags.ReportIndividualFlagName, - ) - - fallthrough - case flags.FalseString: - if len(valued) == 0 { - return - } - - pass.Reportf(decl.Pos(), "iota mixing. keep iotas in separate blocks to consts with r-val") - } -} - -func checkValueSpec(spec *ast.ValueSpec, iotaFound bool, valued []*ast.ValueSpec) (bool, []*ast.ValueSpec) { - // traverse through values (r-val) of spec and look for iota - for _, expr := range spec.Values { - if idn, ok := expr.(*ast.Ident); ok && idn.Name == "iota" { - return true, valued - } - } - - // iota wasn't found, add to valued spec list if there is an r-val - if len(spec.Values) > 0 { - return iotaFound, append(valued, spec) - } - - return iotaFound, valued -} - -func getName(spec *ast.ValueSpec) string { - sb := strings.Builder{} - - for i, ident := range spec.Names { - sb.WriteString(ident.Name) - - if i < len(spec.Names)-1 { - sb.WriteString(", ") - } - } - - return sb.String() -} diff --git a/vendor/github.com/AdminBenni/iota-mixing/pkg/analyzer/flags/flags.go b/vendor/github.com/AdminBenni/iota-mixing/pkg/analyzer/flags/flags.go deleted file mode 100644 index 8f9b73b64d..0000000000 --- a/vendor/github.com/AdminBenni/iota-mixing/pkg/analyzer/flags/flags.go +++ /dev/null @@ -1,23 +0,0 @@ -package flags - -import "flag" - -const ( - TrueString = "true" - FalseString = "false" - - ReportIndividualFlagName = "report-individual" - reportIndividualFlagUsage = "whether or not to report individual consts rather than just the const block." -) - -var ( - reportIndividualFlag *string //nolint:gochecknoglobals // only used in this file, not too plussed -) - -func SetupFlags(flags *flag.FlagSet) { - reportIndividualFlag = flags.String(ReportIndividualFlagName, FalseString, reportIndividualFlagUsage) -} - -func ReportIndividualFlag() string { - return *reportIndividualFlag -} diff --git a/vendor/github.com/AlwxSin/noinlineerr/.gitignore b/vendor/github.com/AlwxSin/noinlineerr/.gitignore deleted file mode 100644 index 15573eff6f..0000000000 --- a/vendor/github.com/AlwxSin/noinlineerr/.gitignore +++ /dev/null @@ -1,33 +0,0 @@ -# If you prefer the allow list template instead of the deny list, see community template: -# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore -# -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib - -# Test binary, built with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -# Dependency directories (remove the comment below to include it) -# vendor/ - -# Go workspace file -go.work -go.work.sum - -# env file -.env -.envrc - -# ide -.idea -.vscode - -# OS specific -.DS_Store diff --git a/vendor/github.com/AlwxSin/noinlineerr/.golangci.yml b/vendor/github.com/AlwxSin/noinlineerr/.golangci.yml deleted file mode 100644 index 36b3155896..0000000000 --- a/vendor/github.com/AlwxSin/noinlineerr/.golangci.yml +++ /dev/null @@ -1,168 +0,0 @@ -version: "2" - -linters: - default: all - disable: - - decorder - - depguard - - err113 - - exhaustruct - - nlreturn - - nonamedreturns - - paralleltest - - recvcheck - - testpackage - - varnamelen - - wrapcheck - - settings: - cyclop: - max-complexity: 30 - dogsled: - max-blank-identifiers: 2 - dupl: - threshold: 150 - errcheck: - check-type-assertions: false - check-blank: true - exclude-functions: - - fmt.Print - - fmt.Printf - - fmt.Println - - fmt.Fprint(*bytes.Buffer) - - fmt.Fprintf(*bytes.Buffer) - - fmt.Fprintln(*bytes.Buffer) - - fmt.Fprint(*strings.Builder) - - fmt.Fprintf(*strings.Builder) - - fmt.Fprintln(*strings.Builder) - - fmt.Fprint(os.Stderr) - - fmt.Fprintf(os.Stderr) - - fmt.Fprintln(os.Stderr) - - io/ioutil.ReadFile - - io/ioutil.ReadDir - gocognit: - min-complexity: 30 - goconst: - min-len: 3 - min-occurrences: 3 - gocritic: - disabled-checks: - - regexpMust - - rangeValCopy - - importShadow - - docStub - enabled-tags: - - performance - - style - - diagnostic - - experimental - - opinionated - settings: - captLocal: - paramsOnly: true - hugeParam: - sizeThreshold: 1024 - gocyclo: - min-complexity: 30 - godox: - keywords: - - FIXME - govet: - enable: - - atomicalign - disable: - - shadow - enable-all: false - disable-all: false - ireturn: - allow: - - anon - - error - - empty - - stdlib - - generic - lll: - line-length: 160 - misspell: - locale: US - mnd: - ignored-functions: - - ^strings\.SplitN - nakedret: - max-func-lines: 30 - perfsprint: - strconcat: false - prealloc: - simple: true - range-loops: true - for-loops: false - staticcheck: - checks: - - '*' - - -ST1003 - - -QF1008 - unparam: - check-exported: false - unused: - field-writes-are-uses: true - post-statements-are-reads: false - exported-fields-are-used: true - parameters-are-used: true - local-variables-are-used: true - generated-is-used: true - usetesting: - context-background: true - context-todo: true - os-chdir: true - os-mkdir-temp: true - os-setenv: true - os-temp-dir: false - os-create-temp: true - varnamelen: - min-name-length: 2 - whitespace: - multi-if: false - multi-func: false - - exclusions: - presets: - - comments - - common-false-positives - - std-error-handling - rules: - - path: _test\.go - linters: - - bodyclose - - containedctx - - contextcheck - - dogsled - - errcheck - - errchkjson - - errorlint - - forcetypeassert - - funlen - - gosec - - lll - - mnd - - musttag - - nilnil - - unparam - - gosmopolitan - - -formatters: - enable: - - gci - - gofumpt - - goimports - settings: - gci: - sections: - - standard - - default - - localmodule - - blank - - dot - gofumpt: - extra-rules: true - diff --git a/vendor/github.com/AlwxSin/noinlineerr/.goreleaser.yml b/vendor/github.com/AlwxSin/noinlineerr/.goreleaser.yml deleted file mode 100644 index a36e47cdc5..0000000000 --- a/vendor/github.com/AlwxSin/noinlineerr/.goreleaser.yml +++ /dev/null @@ -1,25 +0,0 @@ -project_name: noinlineerr -builds: - - main: ./cmd/noinlineerr/main.go - binary: noinlineerr - goos: - - linux - - darwin - - windows - goarch: - - amd64 - - arm64 - -archives: - - formats: [ 'tar.gz' ] - files: - - LICENSE - - README.md - -checksum: - name_template: 'checksums.txt' - -release: - github: - owner: AlwxSin - name: noinlineerr diff --git a/vendor/github.com/AlwxSin/noinlineerr/LICENSE b/vendor/github.com/AlwxSin/noinlineerr/LICENSE deleted file mode 100644 index 03a52166d5..0000000000 --- a/vendor/github.com/AlwxSin/noinlineerr/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2025 Alwx - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/AlwxSin/noinlineerr/README.md b/vendor/github.com/AlwxSin/noinlineerr/README.md deleted file mode 100644 index c0a9cb3867..0000000000 --- a/vendor/github.com/AlwxSin/noinlineerr/README.md +++ /dev/null @@ -1,54 +0,0 @@ -# noinlineerr - -A Go linter that forbids inline error handling using `if err := ...; err != nil`. - ---- - -## Why? -Inline error handling in Go can hurt readability by hiding the actual function call behind error plumbing. -We believe errors and functions deserve their own spotlight. - -Instead of: -```go -if err := doSomething(); err != nil { - return err -} -``` -Prefer the more explicit and readable: -```go -err := doSomething() -if err != nil { - return err -} -``` - ---- - -## Install -```bash -go install github.com/AlwxSin/noinlineerr/cmd/noinlineerr@latest -``` - ---- - -## Usage -### As a standalone tool -```bash -noinlineerr ./... -``` - -⚠️ Note: The linter detects inline error assignments only when the error variable is explicitly typed or deducible. It doesn't handle dynamically typed interfaces (e.g., `foo().Err()` where `Err()` returns an error via an interface). - ---- - -## Development -Run tests: -```bash -go test ./... -``` -Test data lives under `testdata/src/...` - ---- - -## Contributing -PRs are welcome. Let's make Go code cleaner, one `err` at a time. diff --git a/vendor/github.com/AlwxSin/noinlineerr/noinlineerr.go b/vendor/github.com/AlwxSin/noinlineerr/noinlineerr.go deleted file mode 100644 index 9bf562320b..0000000000 --- a/vendor/github.com/AlwxSin/noinlineerr/noinlineerr.go +++ /dev/null @@ -1,154 +0,0 @@ -package noinlineerr - -import ( - "bytes" - "go/ast" - "go/printer" - "go/types" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/inspector" -) - -const errMessage = "avoid inline error handling using `if err := ...; err != nil`; use plain assignment `err := ...`" - -func NewAnalyzer() *analysis.Analyzer { - return &analysis.Analyzer{ - Name: "noinlineerr", - Doc: "Disallows inline error handling (`if err := ...; err != nil {`)", - Run: run, - Requires: []*analysis.Analyzer{inspect.Analyzer}, - } -} - -func run(pass *analysis.Pass) (any, error) { - insp, ok := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - if !ok { - return nil, nil //nolint:nilnil // nothing to return - } - - nodeFilter := []ast.Node{ - (*ast.IfStmt)(nil), - } - - insp.Preorder(nodeFilter, inlineErrorInspector(pass)) - - return nil, nil //nolint:nilnil // nothing to return -} - -func inlineErrorInspector(pass *analysis.Pass) func(n ast.Node) { - return func(n ast.Node) { - ifStmt, ok := n.(*ast.IfStmt) - if !ok || ifStmt.Init == nil { - return - } - - // check if the init clause is an assignment - assignStmt, ok := ifStmt.Init.(*ast.AssignStmt) - if !ok { - return - } - - // iterate over left-hand side variables of the assignment - for _, lhs := range assignStmt.Lhs { - ident, ok := lhs.(*ast.Ident) - if !ok { - continue - } - - // confirm type is error and it is used in condition - obj := pass.TypesInfo.ObjectOf(ident) - if !isError(obj) || ident.Name == "_" || !errorUsedInCondition(ifStmt.Cond, ident.Name) { - continue - } - - // if there are more than 1 assignment - // or there are any variables with same name - // then we can make a shadow conflict with other variables - // so don't do anything beside simple error message - if len(assignStmt.Lhs) != 1 || shadowVarsExists(ident.Name, pass.TypesInfo.Scopes[ifStmt]) { - pass.Reportf(ident.Pos(), errMessage) - return - } - - // else we know there is a simple err assignment like - // if err := func(); err != nil {} - // and we can autofix that - - var buf bytes.Buffer - - _ = printer.Fprint(&buf, pass.Fset, assignStmt) - assignText := buf.String() - - // report usage of inline error assignment - pass.Report(analysis.Diagnostic{ - Pos: ident.Pos(), - End: ident.End(), - Message: errMessage, - SuggestedFixes: []analysis.SuggestedFix{ - { - Message: "move err assignment outside if", - TextEdits: []analysis.TextEdit{ - { - // insert err := ... before if - Pos: ifStmt.Pos(), - End: ifStmt.Pos(), - NewText: []byte(assignText + "\n"), - }, - { - // delete Init part - Pos: assignStmt.Pos(), - End: assignStmt.End() + 1, // +1 for ; - NewText: nil, - }, - }, - }, - }, - }) - } - } -} - -func isError(obj types.Object) bool { - if obj == nil { - return false - } - - errorType := types.Universe.Lookup("error").Type() - - return types.AssignableTo(obj.Type(), errorType) -} - -func shadowVarsExists(name string, scope *types.Scope) bool { - if scope == nil { - return false - } - - parentScope := scope.Parent() - if parentScope == nil { - return false - } - - return parentScope.Lookup(name) != nil -} - -func errorUsedInCondition(cond ast.Expr, errIdentName string) bool { - used := false - - ast.Inspect(cond, func(n ast.Node) bool { - ident, ok := n.(*ast.Ident) - if !ok { - return true - } - - if ident.Name == errIdentName { - used = true - return false - } - - return true - }) - - return used -} diff --git a/vendor/github.com/Antonboom/errname/LICENSE b/vendor/github.com/Antonboom/errname/LICENSE deleted file mode 100644 index e2002e4d43..0000000000 --- a/vendor/github.com/Antonboom/errname/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2021 Anton Telyshev - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/Antonboom/errname/pkg/analyzer/analyzer.go b/vendor/github.com/Antonboom/errname/pkg/analyzer/analyzer.go deleted file mode 100644 index 669edcc209..0000000000 --- a/vendor/github.com/Antonboom/errname/pkg/analyzer/analyzer.go +++ /dev/null @@ -1,112 +0,0 @@ -package analyzer - -import ( - "go/ast" - "go/token" - "go/types" - "unicode" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/inspector" -) - -// New returns new errname analyzer. -func New() *analysis.Analyzer { - return &analysis.Analyzer{ - Name: "errname", - Doc: "Checks that sentinel errors are prefixed with the `Err` and error types are suffixed with the `Error`.", - Run: run, - Requires: []*analysis.Analyzer{inspect.Analyzer}, - } -} - -func run(pass *analysis.Pass) (any, error) { - insp := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - - insp.Nodes([]ast.Node{ - (*ast.TypeSpec)(nil), - (*ast.ValueSpec)(nil), - (*ast.FuncDecl)(nil), - }, func(node ast.Node, push bool) bool { - if !push { - return false - } - - switch v := node.(type) { - case *ast.FuncDecl: - return false - - case *ast.ValueSpec: - if len(v.Names) != 1 { - return false - } - ident := v.Names[0] - - if exprImplementsError(pass, ident) && !isValidErrorVarName(ident.Name) { - reportAboutSentinelError(pass, v.Pos(), ident.Name) - } - return false - - case *ast.TypeSpec: - tt := pass.TypesInfo.TypeOf(v.Name) - if tt == nil { - return false - } - // NOTE(a.telyshev): Pointer is the hack against Error() method with pointer receiver. - if !typeImplementsError(types.NewPointer(tt)) { - return false - } - - name := v.Name.Name - if _, ok := v.Type.(*ast.ArrayType); ok { - if !isValidErrorArrayTypeName(name) { - reportAboutArrayErrorType(pass, v.Pos(), name) - } - } else if !isValidErrorTypeName(name) { - reportAboutErrorType(pass, v.Pos(), name) - } - return false - } - - return true - }) - - return nil, nil //nolint:nilnil // Integration interface of analysis.Analyzer. -} - -func reportAboutErrorType(pass *analysis.Pass, typePos token.Pos, typeName string) { - var form string - if startsWithLower(typeName) { - form = "xxxError" - } else { - form = "XxxError" - } - - pass.Reportf(typePos, "the error type name `%s` should conform to the `%s` format", typeName, form) -} - -func reportAboutArrayErrorType(pass *analysis.Pass, typePos token.Pos, typeName string) { - var forms string - if startsWithLower(typeName) { - forms = "`xxxErrors` or `xxxError`" - } else { - forms = "`XxxErrors` or `XxxError`" - } - - pass.Reportf(typePos, "the error type name `%s` should conform to the %s format", typeName, forms) -} - -func reportAboutSentinelError(pass *analysis.Pass, pos token.Pos, varName string) { - var form string - if startsWithLower(varName) { - form = "errXxx" - } else { - form = "ErrXxx" - } - pass.Reportf(pos, "the sentinel error name `%s` should conform to the `%s` format", varName, form) -} - -func startsWithLower(n string) bool { - return unicode.IsLower([]rune(n)[0]) //nolint:gocritic // Source code is Unicode text encoded in UTF-8. -} diff --git a/vendor/github.com/Antonboom/errname/pkg/analyzer/facts.go b/vendor/github.com/Antonboom/errname/pkg/analyzer/facts.go deleted file mode 100644 index 04e14fb68d..0000000000 --- a/vendor/github.com/Antonboom/errname/pkg/analyzer/facts.go +++ /dev/null @@ -1,95 +0,0 @@ -package analyzer - -import ( - "go/ast" - "go/types" - "strings" - "unicode" - - "golang.org/x/tools/go/analysis" -) - -var errorIface = types.Universe.Lookup("error").Type().Underlying().(*types.Interface) - -func exprImplementsError(pass *analysis.Pass, e ast.Expr) bool { - return typeImplementsError(pass.TypesInfo.TypeOf(e)) -} - -func typeImplementsError(t types.Type) bool { - return t != nil && types.Implements(t, errorIface) -} - -func isValidErrorTypeName(s string) bool { - if isInitialism(s) { - return true - } - - words := split(s) - wordsCnt := wordsCount(words) - - if wordsCnt["error"] != 1 { - return false - } - return words[len(words)-1] == "error" -} - -func isValidErrorArrayTypeName(s string) bool { - if isInitialism(s) { - return true - } - - words := split(s) - wordsCnt := wordsCount(words) - - if wordsCnt["errors"] != 1 && wordsCnt["error"] != 1 { - return false - } - - lastWord := words[len(words)-1] - return lastWord == "errors" || lastWord == "error" -} - -func isValidErrorVarName(s string) bool { - if isInitialism(s) { - return true - } - - words := split(s) - wordsCnt := wordsCount(words) - - if wordsCnt["err"] != 1 { - return false - } - return words[0] == "err" -} - -func isInitialism(s string) bool { - return strings.ToLower(s) == s || strings.ToUpper(s) == s -} - -func split(s string) []string { - var words []string - ss := []rune(s) - - var b strings.Builder - b.WriteRune(ss[0]) - - for _, r := range ss[1:] { - if unicode.IsUpper(r) { - words = append(words, strings.ToLower(b.String())) - b.Reset() - } - b.WriteRune(r) - } - - words = append(words, strings.ToLower(b.String())) - return words -} - -func wordsCount(w []string) map[string]int { - result := make(map[string]int, len(w)) - for _, ww := range w { - result[ww]++ - } - return result -} diff --git a/vendor/github.com/Antonboom/nilnil/LICENSE b/vendor/github.com/Antonboom/nilnil/LICENSE deleted file mode 100644 index e2002e4d43..0000000000 --- a/vendor/github.com/Antonboom/nilnil/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2021 Anton Telyshev - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/Antonboom/nilnil/pkg/analyzer/analyzer.go b/vendor/github.com/Antonboom/nilnil/pkg/analyzer/analyzer.go deleted file mode 100644 index 443d537148..0000000000 --- a/vendor/github.com/Antonboom/nilnil/pkg/analyzer/analyzer.go +++ /dev/null @@ -1,203 +0,0 @@ -package analyzer - -import ( - "go/ast" - "go/token" - "go/types" - "strconv" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/inspector" -) - -const ( - name = "nilnil" - doc = "Checks that there is no simultaneous return of `nil` error and an invalid value." - - nilNilReportMsg = "return both a `nil` error and an invalid value: use a sentinel error instead" - notNilNotNilReportMsg = "return both a non-nil error and a valid value: use separate returns instead" -) - -// New returns new nilnil analyzer. -func New() *analysis.Analyzer { - n := newNilNil() - - a := &analysis.Analyzer{ - Name: name, - Doc: doc, - Run: n.run, - Requires: []*analysis.Analyzer{inspect.Analyzer}, - } - a.Flags.Var(&n.checkedTypes, "checked-types", "comma separated list of return types to check") - a.Flags.BoolVar(&n.detectOpposite, "detect-opposite", false, - "in addition, to detect opposite situation (simultaneous return of non-nil error and valid value)") - a.Flags.BoolVar(&n.onlyTwo, "only-two", true, - "to check functions with only two return values") - - return a -} - -type nilNil struct { - checkedTypes checkedTypes - detectOpposite bool - onlyTwo bool -} - -func newNilNil() *nilNil { - return &nilNil{ - checkedTypes: newDefaultCheckedTypes(), - detectOpposite: false, - onlyTwo: true, - } -} - -var funcAndReturns = []ast.Node{ - (*ast.FuncDecl)(nil), - (*ast.FuncLit)(nil), - (*ast.ReturnStmt)(nil), -} - -func (n *nilNil) run(pass *analysis.Pass) (any, error) { - insp := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - - var fs funcTypeStack - insp.Nodes(funcAndReturns, func(node ast.Node, push bool) (proceed bool) { - switch v := node.(type) { - case *ast.FuncLit: - if push { - fs.Push(v.Type) - } else { - fs.Pop() - } - - case *ast.FuncDecl: - if push { - fs.Push(v.Type) - } else { - fs.Pop() - } - - case *ast.ReturnStmt: - ft := fs.Top() // Current function. - - if !push { - return false - } - if len(v.Results) < 2 { - return false - } - if (ft == nil) || (ft.Results == nil) || (len(ft.Results.List) != len(v.Results)) { - // Unreachable. - return false - } - - lastIdx := len(ft.Results.List) - 1 - if n.onlyTwo { - lastIdx = 1 - } - - lastFtRes := ft.Results.List[lastIdx] - if !implementsError(pass.TypesInfo.TypeOf(lastFtRes.Type)) { - return false - } - - retErr := v.Results[lastIdx] - for i := range lastIdx { - retVal := v.Results[i] - - zv, ok := n.isDangerNilType(pass.TypesInfo.TypeOf(ft.Results.List[i].Type)) - if !ok { - continue - } - - if ((zv == zeroValueNil) && isNil(pass, retVal) && isNil(pass, retErr)) || - ((zv == zeroValueZero) && isZero(retVal) && isNil(pass, retErr)) { - pass.Reportf(v.Pos(), nilNilReportMsg) - return false - } - - if n.detectOpposite && (((zv == zeroValueNil) && !isNil(pass, retVal) && !isNil(pass, retErr)) || - ((zv == zeroValueZero) && !isZero(retVal) && !isNil(pass, retErr))) { - pass.Reportf(v.Pos(), notNilNotNilReportMsg) - return false - } - } - } - - return true - }) - - return nil, nil //nolint:nilnil // Integration interface of analysis.Analyzer. -} - -type zeroValue int - -const ( - zeroValueNil = iota + 1 - zeroValueZero -) - -func (n *nilNil) isDangerNilType(t types.Type) (zeroValue, bool) { - switch v := types.Unalias(t).(type) { - case *types.Pointer: - return zeroValueNil, n.checkedTypes.Contains(ptrType) - - case *types.Signature: - return zeroValueNil, n.checkedTypes.Contains(funcType) - - case *types.Interface: - return zeroValueNil, n.checkedTypes.Contains(ifaceType) - - case *types.Map: - return zeroValueNil, n.checkedTypes.Contains(mapType) - - case *types.Chan: - return zeroValueNil, n.checkedTypes.Contains(chanType) - - case *types.Basic: - if v.Kind() == types.Uintptr { - return zeroValueZero, n.checkedTypes.Contains(uintptrType) - } - if v.Kind() == types.UnsafePointer { - return zeroValueNil, n.checkedTypes.Contains(unsafeptrType) - } - - case *types.Named: - return n.isDangerNilType(v.Underlying()) - } - return 0, false -} - -var errorIface = types.Universe.Lookup("error").Type().Underlying().(*types.Interface) - -func implementsError(t types.Type) bool { - _, ok := t.Underlying().(*types.Interface) - return ok && types.Implements(t, errorIface) -} - -func isNil(pass *analysis.Pass, e ast.Expr) bool { - i, ok := e.(*ast.Ident) - if !ok { - return false - } - - _, ok = pass.TypesInfo.ObjectOf(i).(*types.Nil) - return ok -} - -func isZero(e ast.Expr) bool { - bl, ok := e.(*ast.BasicLit) - if !ok { - return false - } - if bl.Kind != token.INT { - return false - } - - v, err := strconv.ParseInt(bl.Value, 0, 64) - if err != nil { - return false - } - return v == 0 -} diff --git a/vendor/github.com/Antonboom/nilnil/pkg/analyzer/config.go b/vendor/github.com/Antonboom/nilnil/pkg/analyzer/config.go deleted file mode 100644 index 90ae548f30..0000000000 --- a/vendor/github.com/Antonboom/nilnil/pkg/analyzer/config.go +++ /dev/null @@ -1,79 +0,0 @@ -package analyzer - -import ( - "fmt" - "sort" - "strings" -) - -func newDefaultCheckedTypes() checkedTypes { - return checkedTypes{ - chanType: {}, - funcType: {}, - ifaceType: {}, - mapType: {}, - ptrType: {}, - uintptrType: {}, - unsafeptrType: {}, - } -} - -const separator = ',' - -type typeName string - -func (t typeName) S() string { - return string(t) -} - -const ( - ptrType typeName = "ptr" - funcType typeName = "func" - ifaceType typeName = "iface" - mapType typeName = "map" - chanType typeName = "chan" - uintptrType typeName = "uintptr" - unsafeptrType typeName = "unsafeptr" -) - -type checkedTypes map[typeName]struct{} - -func (c checkedTypes) Contains(t typeName) bool { - _, ok := c[t] - return ok -} - -func (c checkedTypes) String() string { - result := make([]string, 0, len(c)) - for t := range c { - result = append(result, t.S()) - } - - sort.Strings(result) - return strings.Join(result, string(separator)) -} - -func (c checkedTypes) Set(s string) error { - types := strings.FieldsFunc(s, func(c rune) bool { return c == separator }) - if len(types) == 0 { - return nil - } - - c.disableAll() - for _, t := range types { - switch tt := typeName(t); tt { - case ptrType, funcType, ifaceType, mapType, chanType, uintptrType, unsafeptrType: - c[tt] = struct{}{} - default: - return fmt.Errorf("unknown checked type name %q (see help)", t) - } - } - - return nil -} - -func (c checkedTypes) disableAll() { - for k := range c { - delete(c, k) - } -} diff --git a/vendor/github.com/Antonboom/nilnil/pkg/analyzer/func_type_stack.go b/vendor/github.com/Antonboom/nilnil/pkg/analyzer/func_type_stack.go deleted file mode 100644 index 0817615470..0000000000 --- a/vendor/github.com/Antonboom/nilnil/pkg/analyzer/func_type_stack.go +++ /dev/null @@ -1,29 +0,0 @@ -package analyzer - -import ( - "go/ast" -) - -type funcTypeStack []*ast.FuncType - -func (s *funcTypeStack) Push(f *ast.FuncType) { - *s = append(*s, f) -} - -func (s *funcTypeStack) Pop() *ast.FuncType { - if len(*s) == 0 { - return nil - } - - last := len(*s) - 1 - f := (*s)[last] - *s = (*s)[:last] - return f -} - -func (s *funcTypeStack) Top() *ast.FuncType { - if len(*s) == 0 { - return nil - } - return (*s)[len(*s)-1] -} diff --git a/vendor/github.com/Antonboom/testifylint/LICENSE b/vendor/github.com/Antonboom/testifylint/LICENSE deleted file mode 100644 index 9b1cf3a393..0000000000 --- a/vendor/github.com/Antonboom/testifylint/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2022 Anton Telyshev - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/Antonboom/testifylint/analyzer/analyzer.go b/vendor/github.com/Antonboom/testifylint/analyzer/analyzer.go deleted file mode 100644 index 7111797141..0000000000 --- a/vendor/github.com/Antonboom/testifylint/analyzer/analyzer.go +++ /dev/null @@ -1,92 +0,0 @@ -package analyzer - -import ( - "fmt" - "go/ast" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/inspector" - - "github.com/Antonboom/testifylint/internal/checkers" - "github.com/Antonboom/testifylint/internal/config" - "github.com/Antonboom/testifylint/internal/testify" -) - -const ( - name = "testifylint" - doc = "Checks usage of " + testify.ModulePath + "." - url = "https://github.com/antonboom/" + name -) - -// New returns a new instance of testifylint analyzer. -func New() *analysis.Analyzer { - cfg := config.NewDefault() - - analyzer := &analysis.Analyzer{ - Name: name, - Doc: doc, - URL: url, - Requires: []*analysis.Analyzer{inspect.Analyzer}, - Run: func(pass *analysis.Pass) (any, error) { - regularCheckers, advancedCheckers, err := newCheckers(cfg) - if err != nil { - return nil, fmt.Errorf("build checkers: %v", err) - } - - tl := &testifyLint{ - regularCheckers: regularCheckers, - advancedCheckers: advancedCheckers, - } - return tl.run(pass) - }, - } - config.BindToFlags(&cfg, &analyzer.Flags) - - return analyzer -} - -type testifyLint struct { - regularCheckers []checkers.RegularChecker - advancedCheckers []checkers.AdvancedChecker -} - -func (tl *testifyLint) run(pass *analysis.Pass) (any, error) { - // NOTE(a.telyshev): There are no premature optimizations like "scan only _test.go" or - // "scan only files with testify imports", since it could lead to skip files - // with assertions (etc. test helpers in regular Go files or suite methods). - insp, ok := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - if !ok { - return nil, nil - } - - // Regular checkers. - insp.Preorder([]ast.Node{(*ast.CallExpr)(nil)}, func(node ast.Node) { - tl.regularCheck(pass, node.(*ast.CallExpr)) - }) - - // Advanced checkers. - for _, ch := range tl.advancedCheckers { - for _, d := range ch.Check(pass, insp) { - pass.Report(d) - } - } - - return nil, nil -} - -func (tl *testifyLint) regularCheck(pass *analysis.Pass, ce *ast.CallExpr) { - call := checkers.NewCallMeta(pass, ce) - if nil == call { - return - } - - for _, ch := range tl.regularCheckers { - if d := ch.Check(pass, call); d != nil { - pass.Report(*d) - // NOTE(a.telyshev): I'm not interested in multiple diagnostics per assertion. - // This simplifies the code and also makes the linter more efficient. - return - } - } -} diff --git a/vendor/github.com/Antonboom/testifylint/analyzer/checkers_factory.go b/vendor/github.com/Antonboom/testifylint/analyzer/checkers_factory.go deleted file mode 100644 index 274ce85cea..0000000000 --- a/vendor/github.com/Antonboom/testifylint/analyzer/checkers_factory.go +++ /dev/null @@ -1,82 +0,0 @@ -package analyzer - -import ( - "fmt" - - "github.com/Antonboom/testifylint/internal/checkers" - "github.com/Antonboom/testifylint/internal/config" -) - -// newCheckers accepts linter config and returns slices of enabled checkers sorted by priority. -func newCheckers(cfg config.Config) ([]checkers.RegularChecker, []checkers.AdvancedChecker, error) { - if err := cfg.Validate(); err != nil { - return nil, nil, err - } - - enabledCheckersSet := make(map[string]struct{}) - - if cfg.EnableAll { - for _, checker := range checkers.All() { - enabledCheckersSet[checker] = struct{}{} - } - } else if !cfg.DisableAll { - for _, checker := range checkers.EnabledByDefault() { - enabledCheckersSet[checker] = struct{}{} - } - } - - for _, checker := range cfg.EnabledCheckers { - enabledCheckersSet[checker] = struct{}{} - } - - for _, checker := range cfg.DisabledCheckers { - delete(enabledCheckersSet, checker) - } - - enabledCheckers := make([]string, 0, len(enabledCheckersSet)) - for v := range enabledCheckersSet { - enabledCheckers = append(enabledCheckers, v) - } - checkers.SortByPriority(enabledCheckers) - - regularCheckers := make([]checkers.RegularChecker, 0, len(enabledCheckers)) - advancedCheckers := make([]checkers.AdvancedChecker, 0, len(enabledCheckers)/2) - - for _, name := range enabledCheckers { - ch, ok := checkers.Get(name) - if !ok { - return nil, nil, fmt.Errorf("unknown checker %q", name) - } - - switch c := ch.(type) { - case *checkers.BoolCompare: - c.SetIgnoreCustomTypes(cfg.BoolCompare.IgnoreCustomTypes) - - case *checkers.ExpectedActual: - c.SetExpVarPattern(cfg.ExpectedActual.ExpVarPattern.Regexp) - - case *checkers.Formatter: - c.SetCheckFormatString(cfg.Formatter.CheckFormatString) - c.SetRequireFFuncs(cfg.Formatter.RequireFFuncs) - c.SetRequireStringMsg(cfg.Formatter.RequireStringMsg) - - case *checkers.GoRequire: - c.SetIgnoreHTTPHandlers(cfg.GoRequire.IgnoreHTTPHandlers) - - case *checkers.RequireError: - c.SetFnPattern(cfg.RequireError.FnPattern.Regexp) - - case *checkers.SuiteExtraAssertCall: - c.SetMode(cfg.SuiteExtraAssertCall.Mode) - } - - switch casted := ch.(type) { - case checkers.RegularChecker: - regularCheckers = append(regularCheckers, casted) - case checkers.AdvancedChecker: - advancedCheckers = append(advancedCheckers, casted) - } - } - - return regularCheckers, advancedCheckers, nil -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/analysisutil/doc.go b/vendor/github.com/Antonboom/testifylint/internal/analysisutil/doc.go deleted file mode 100644 index b57cbd9384..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/analysisutil/doc.go +++ /dev/null @@ -1,9 +0,0 @@ -// Package analysisutil contains functions common for `analyzer` and `internal/checkers` packages. -// In addition, it is intended to "lighten" these packages. -// -// If the function is common to several packages, or it makes sense to test it separately without -// "polluting" the target package with tests of private functionality, then you can put function in this package. -// -// It's important to avoid dependency on `golang.org/x/tools/go/analysis` in the helpers API. -// This makes the API "narrower" and also allows you to test functions without some "abstraction leaks". -package analysisutil diff --git a/vendor/github.com/Antonboom/testifylint/internal/analysisutil/encoded.go b/vendor/github.com/Antonboom/testifylint/internal/analysisutil/encoded.go deleted file mode 100644 index cafc283e6f..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/analysisutil/encoded.go +++ /dev/null @@ -1,46 +0,0 @@ -package analysisutil - -import "strings" - -var whitespaceRemover = strings.NewReplacer("\n", "", "\\n", "", "\t", "", "\\t", "", " ", "") - -// IsJSONLike returns true if the string has JSON format features. -// A positive result can be returned for invalid JSON as well. -func IsJSONLike(s string) bool { - s = whitespaceRemover.Replace(unescape(s)) - - var startMatch bool - for _, prefix := range []string{ - `{{`, `{[`, `{"`, - `[{{`, `[{[`, `[{"`, - } { - if strings.HasPrefix(s, prefix) { - startMatch = true - break - } - } - if !startMatch { - return false - } - - for _, keyValue := range []string{`":{`, `":[`, `":"`} { - if strings.Contains(s, keyValue) { - return true - } - } - return false - - // NOTE(a.telyshev): We do not check the end of the string, because this is usually a field for typos. - // And one of the reasons for using JSON-specific assertions is to catch typos like this. -} - -func unescape(s string) string { - s = strings.ReplaceAll(s, `\"`, `"`) - s = unquote(s, `"`) - s = unquote(s, "`") - return s -} - -func unquote(s string, q string) string { - return strings.TrimLeft(strings.TrimRight(s, q), q) -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/analysisutil/file.go b/vendor/github.com/Antonboom/testifylint/internal/analysisutil/file.go deleted file mode 100644 index d552609182..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/analysisutil/file.go +++ /dev/null @@ -1,26 +0,0 @@ -package analysisutil - -import ( - "go/ast" - "slices" - "strconv" -) - -// Imports tells if the file imports at least one of the packages. -// If no packages provided then function returns false. -func Imports(file *ast.File, pkgs ...string) bool { - for _, i := range file.Imports { - if i.Path == nil { - continue - } - - path, err := strconv.Unquote(i.Path.Value) - if err != nil { - continue - } - if slices.Contains(pkgs, path) { // Small O(n). - return true - } - } - return false -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/analysisutil/format.go b/vendor/github.com/Antonboom/testifylint/internal/analysisutil/format.go deleted file mode 100644 index fcb4b847f6..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/analysisutil/format.go +++ /dev/null @@ -1,34 +0,0 @@ -package analysisutil - -import ( - "bytes" - "go/ast" - "go/format" - "go/token" -) - -// NodeString is a more powerful analogue of types.ExprString. -// Return empty string if node AST is invalid. -func NodeString(fset *token.FileSet, node ast.Node) string { - if v := formatNode(fset, node); v != nil { - return v.String() - } - return "" -} - -// NodeBytes works as NodeString but returns a byte slice. -// Return nil if node AST is invalid. -func NodeBytes(fset *token.FileSet, node ast.Node) []byte { - if v := formatNode(fset, node); v != nil { - return v.Bytes() - } - return nil -} - -func formatNode(fset *token.FileSet, node ast.Node) *bytes.Buffer { - buf := new(bytes.Buffer) - if err := format.Node(buf, fset, node); err != nil { - return nil - } - return buf -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/analysisutil/object.go b/vendor/github.com/Antonboom/testifylint/internal/analysisutil/object.go deleted file mode 100644 index 4e0346d2ba..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/analysisutil/object.go +++ /dev/null @@ -1,34 +0,0 @@ -package analysisutil - -import ( - "go/ast" - "go/types" -) - -// ObjectOf works in context of Golang package and returns types.Object for the given object's package and name. -// The search is based on the provided package and its dependencies (imports). -// Returns nil if the object is not found. -func ObjectOf(pkg *types.Package, objPkg, objName string) types.Object { - if pkg.Path() == objPkg { - return pkg.Scope().Lookup(objName) - } - - for _, i := range pkg.Imports() { - if trimVendor(i.Path()) == objPkg { - return i.Scope().Lookup(objName) - } - } - return nil -} - -// IsObj returns true if expression is identifier which notes to given types.Object. -// Useful in combination with types.Universe objects. -func IsObj(typesInfo *types.Info, expr ast.Expr, expected types.Object) bool { - id, ok := expr.(*ast.Ident) - if !ok { - return false - } - - obj := typesInfo.ObjectOf(id) - return obj == expected -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/analysisutil/pkg.go b/vendor/github.com/Antonboom/testifylint/internal/analysisutil/pkg.go deleted file mode 100644 index d34be5d341..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/analysisutil/pkg.go +++ /dev/null @@ -1,19 +0,0 @@ -package analysisutil - -import ( - "go/types" - "strings" -) - -// IsPkg checks that package has corresponding objName and path. -// Supports vendored packages. -func IsPkg(pkg *types.Package, name, path string) bool { - return pkg.Name() == name && trimVendor(pkg.Path()) == path -} - -func trimVendor(path string) string { - if strings.HasPrefix(path, "vendor/") { - return path[len("vendor/"):] - } - return path -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/blank_import.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/blank_import.go deleted file mode 100644 index 56cd64e078..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/blank_import.go +++ /dev/null @@ -1,69 +0,0 @@ -package checkers - -import ( - "fmt" - "strconv" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/ast/inspector" - - "github.com/Antonboom/testifylint/internal/testify" -) - -// BlankImport detects useless blank imports of testify's packages. -// These imports are useless since testify doesn't do any magic with init() function. -// -// The checker detects situations like -// -// import ( -// "testing" -// -// _ "github.com/stretchr/testify" -// _ "github.com/stretchr/testify/assert" -// _ "github.com/stretchr/testify/http" -// _ "github.com/stretchr/testify/mock" -// _ "github.com/stretchr/testify/require" -// _ "github.com/stretchr/testify/suite" -// ) -// -// and requires -// -// import ( -// "testing" -// ) -type BlankImport struct{} - -// NewBlankImport constructs BlankImport checker. -func NewBlankImport() BlankImport { return BlankImport{} } -func (BlankImport) Name() string { return "blank-import" } - -func (checker BlankImport) Check(pass *analysis.Pass, _ *inspector.Inspector) (diagnostics []analysis.Diagnostic) { - for _, file := range pass.Files { - for _, imp := range file.Imports { - if imp.Name == nil || imp.Name.Name != "_" { - continue - } - - pkg, err := strconv.Unquote(imp.Path.Value) - if err != nil { - continue - } - if _, ok := packagesNotIntendedForBlankImport[pkg]; !ok { - continue - } - - msg := fmt.Sprintf("avoid blank import of %s as it does nothing", pkg) - diagnostics = append(diagnostics, *newDiagnostic(checker.Name(), imp, msg)) - } - } - return diagnostics -} - -var packagesNotIntendedForBlankImport = map[string]struct{}{ - testify.ModulePath: {}, - testify.AssertPkgPath: {}, - testify.HTTPPkgPath: {}, - testify.MockPkgPath: {}, - testify.RequirePkgPath: {}, - testify.SuitePkgPath: {}, -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/bool_compare.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/bool_compare.go deleted file mode 100644 index 4bcd5304f2..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/bool_compare.go +++ /dev/null @@ -1,210 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/token" - - "golang.org/x/tools/go/analysis" - - "github.com/Antonboom/testifylint/internal/analysisutil" -) - -// BoolCompare detects situations like -// -// assert.Equal(t, false, result) -// assert.EqualValues(t, false, result) -// assert.Exactly(t, false, result) -// assert.NotEqual(t, true, result) -// assert.NotEqualValues(t, true, result) -// assert.False(t, !result) -// assert.True(t, result == true) -// ... -// -// and requires -// -// assert.False(t, result) -// assert.True(t, result) -type BoolCompare struct { - ignoreCustomTypes bool -} - -// NewBoolCompare constructs BoolCompare checker. -func NewBoolCompare() *BoolCompare { return new(BoolCompare) } -func (BoolCompare) Name() string { return "bool-compare" } - -func (checker *BoolCompare) SetIgnoreCustomTypes(v bool) *BoolCompare { - checker.ignoreCustomTypes = v - return checker -} - -func (checker BoolCompare) Check(pass *analysis.Pass, call *CallMeta) *analysis.Diagnostic { - newBoolCast := func(e ast.Expr) ast.Expr { - return &ast.CallExpr{Fun: &ast.Ident{Name: "bool"}, Args: []ast.Expr{e}} - } - - newUseFnDiagnostic := func(proposed string, survivingArg ast.Expr, replaceStart, replaceEnd token.Pos) *analysis.Diagnostic { - if !hasBoolType(pass, survivingArg) { - if checker.ignoreCustomTypes { - return nil - } - survivingArg = newBoolCast(survivingArg) - } - return newUseFunctionDiagnostic(checker.Name(), call, proposed, analysis.TextEdit{ - Pos: replaceStart, - End: replaceEnd, - NewText: analysisutil.NodeBytes(pass.Fset, survivingArg), - }) - } - - newUseTrueDiagnostic := func(survivingArg ast.Expr, replaceStart, replaceEnd token.Pos) *analysis.Diagnostic { - return newUseFnDiagnostic("True", survivingArg, replaceStart, replaceEnd) - } - - newUseFalseDiagnostic := func(survivingArg ast.Expr, replaceStart, replaceEnd token.Pos) *analysis.Diagnostic { - return newUseFnDiagnostic("False", survivingArg, replaceStart, replaceEnd) - } - - newNeedSimplifyDiagnostic := func(survivingArg ast.Expr, replaceStart, replaceEnd token.Pos) *analysis.Diagnostic { - if !hasBoolType(pass, survivingArg) { - if checker.ignoreCustomTypes { - return nil - } - survivingArg = newBoolCast(survivingArg) - } - return newDiagnostic(checker.Name(), call, "need to simplify the assertion", - analysis.SuggestedFix{ - Message: "Simplify the assertion", - TextEdits: []analysis.TextEdit{{ - Pos: replaceStart, - End: replaceEnd, - NewText: analysisutil.NodeBytes(pass.Fset, survivingArg), - }}, - }, - ) - } - - switch call.Fn.NameFTrimmed { - case "Equal", "EqualValues", "Exactly": - if len(call.Args) < 2 { - return nil - } - - arg1, arg2 := call.Args[0], call.Args[1] - if anyCondSatisfaction(pass, isEmptyInterface, arg1, arg2) { - return nil - } - if anyCondSatisfaction(pass, isBoolOverride, arg1, arg2) { - return nil - } - - t1, t2 := isUntypedTrue(pass, arg1), isUntypedTrue(pass, arg2) - f1, f2 := isUntypedFalse(pass, arg1), isUntypedFalse(pass, arg2) - - switch { - case xor(t1, t2): - survivingArg, _ := anyVal([]bool{t1, t2}, arg2, arg1) - if call.Fn.NameFTrimmed == "Exactly" && !hasBoolType(pass, survivingArg) { - // NOTE(a.telyshev): `Exactly` assumes no type conversion. - return nil - } - return newUseTrueDiagnostic(survivingArg, arg1.Pos(), arg2.End()) - - case xor(f1, f2): - survivingArg, _ := anyVal([]bool{f1, f2}, arg2, arg1) - if call.Fn.NameFTrimmed == "Exactly" && !hasBoolType(pass, survivingArg) { - // NOTE(a.telyshev): `Exactly` assumes no type conversion. - return nil - } - return newUseFalseDiagnostic(survivingArg, arg1.Pos(), arg2.End()) - } - - case "NotEqual", "NotEqualValues": - if len(call.Args) < 2 { - return nil - } - - arg1, arg2 := call.Args[0], call.Args[1] - if anyCondSatisfaction(pass, isEmptyInterface, arg1, arg2) { - return nil - } - if anyCondSatisfaction(pass, isBoolOverride, arg1, arg2) { - return nil - } - - t1, t2 := isUntypedTrue(pass, arg1), isUntypedTrue(pass, arg2) - f1, f2 := isUntypedFalse(pass, arg1), isUntypedFalse(pass, arg2) - - switch { - case xor(t1, t2): - survivingArg, _ := anyVal([]bool{t1, t2}, arg2, arg1) - return newUseFalseDiagnostic(survivingArg, arg1.Pos(), arg2.End()) - - case xor(f1, f2): - survivingArg, _ := anyVal([]bool{f1, f2}, arg2, arg1) - return newUseTrueDiagnostic(survivingArg, arg1.Pos(), arg2.End()) - } - - case "True": - if len(call.Args) < 1 { - return nil - } - expr := call.Args[0] - - { - arg1, ok1 := isComparisonWithTrue(pass, expr, token.EQL) - arg2, ok2 := isComparisonWithFalse(pass, expr, token.NEQ) - - survivingArg, ok := anyVal([]bool{ok1, ok2}, arg1, arg2) - if ok && !isEmptyInterface(pass, survivingArg) { - return newNeedSimplifyDiagnostic(survivingArg, expr.Pos(), expr.End()) - } - } - - { - arg1, ok1 := isComparisonWithTrue(pass, expr, token.NEQ) - arg2, ok2 := isComparisonWithFalse(pass, expr, token.EQL) - arg3, ok3 := isNegation(expr) - - survivingArg, ok := anyVal([]bool{ok1, ok2, ok3}, arg1, arg2, arg3) - if ok && !isEmptyInterface(pass, survivingArg) { - return newUseFalseDiagnostic(survivingArg, expr.Pos(), expr.End()) - } - } - - case "False": - if len(call.Args) < 1 { - return nil - } - expr := call.Args[0] - - { - arg1, ok1 := isComparisonWithTrue(pass, expr, token.EQL) - arg2, ok2 := isComparisonWithFalse(pass, expr, token.NEQ) - - survivingArg, ok := anyVal([]bool{ok1, ok2}, arg1, arg2) - if ok && !isEmptyInterface(pass, survivingArg) { - return newNeedSimplifyDiagnostic(survivingArg, expr.Pos(), expr.End()) - } - } - - { - arg1, ok1 := isComparisonWithTrue(pass, expr, token.NEQ) - arg2, ok2 := isComparisonWithFalse(pass, expr, token.EQL) - arg3, ok3 := isNegation(expr) - - survivingArg, ok := anyVal([]bool{ok1, ok2, ok3}, arg1, arg2, arg3) - if ok && !isEmptyInterface(pass, survivingArg) { - return newUseTrueDiagnostic(survivingArg, expr.Pos(), expr.End()) - } - } - } - return nil -} - -func isNegation(e ast.Expr) (ast.Expr, bool) { - ue, ok := e.(*ast.UnaryExpr) - if !ok { - return nil, false - } - return ue.X, ue.Op == token.NOT -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/call_meta.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/call_meta.go deleted file mode 100644 index 3d9c3428ac..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/call_meta.go +++ /dev/null @@ -1,133 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/types" - "strings" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/types/typeutil" - - "github.com/Antonboom/testifylint/internal/analysisutil" - "github.com/Antonboom/testifylint/internal/testify" -) - -// CallMeta stores meta info about assertion function/method call, for example -// -// assert.Equal(t, 42, result, "helpful comment") -type CallMeta struct { - // Call stores the original AST call expression. - Call *ast.CallExpr - // Range contains start and end position of assertion call. - analysis.Range - // IsPkg true if this is package (not object) call. - IsPkg bool - // IsAssert true if this is "testify/assert" package (or object) call. - IsAssert bool - // Selector is the AST expression of "assert.Equal". - Selector *ast.SelectorExpr - // SelectorXStr is a string representation of Selector's left part – value before point, e.g. "assert". - SelectorXStr string - // Fn stores meta info about assertion function itself. - Fn FnMeta - // Args stores assertion call arguments but without `t *testing.T` argument. - // E.g [42, result, "helpful comment"]. - Args []ast.Expr - // ArgsRaw stores assertion call initial arguments. - // E.g [t, 42, result, "helpful comment"]. - ArgsRaw []ast.Expr -} - -func (c CallMeta) String() string { - return c.SelectorXStr + "." + c.Fn.Name -} - -// FnMeta stores meta info about assertion function itself, for example "Equal". -type FnMeta struct { - // Range contains start and end position of function Name. - analysis.Range - // Name is a function name. - Name string - // NameFTrimmed is a function name without "f" suffix. - NameFTrimmed string - // IsFmt is true if function is formatted, e.g. "Equalf". - IsFmt bool - // Signature represents assertion signature. - Signature *types.Signature -} - -// NewCallMeta returns meta information about testify assertion call. -// Returns nil if ast.CallExpr is not testify call. -func NewCallMeta(pass *analysis.Pass, ce *ast.CallExpr) *CallMeta { - se, ok := ce.Fun.(*ast.SelectorExpr) - if !ok || se.Sel == nil { - return nil - } - fnName := se.Sel.Name - - initiatorPkg, isPkgCall := func() (*types.Package, bool) { - // Examples: - // s.Assert -> method of *suite.Suite -> package suite ("vendor/github.com/stretchr/testify/suite") - // s.Assert().Equal -> method of *assert.Assertions -> package assert ("vendor/github.com/stretchr/testify/assert") - // s.Equal -> method of *assert.Assertions -> package assert ("vendor/github.com/stretchr/testify/assert") - // reqObj.Falsef -> method of *require.Assertions -> package require ("vendor/github.com/stretchr/testify/require") - if sel, isSel := pass.TypesInfo.Selections[se]; isSel { - return sel.Obj().Pkg(), false - } - - // Examples: - // assert.False -> assert -> package assert ("vendor/github.com/stretchr/testify/assert") - // require.NotEqualf -> require -> package require ("vendor/github.com/stretchr/testify/require") - if id, isIdent := se.X.(*ast.Ident); isIdent { - if selObj := pass.TypesInfo.ObjectOf(id); selObj != nil { - if pkg, isPkgName := selObj.(*types.PkgName); isPkgName { - return pkg.Imported(), true - } - } - } - return nil, false - }() - if initiatorPkg == nil { - return nil - } - - isAssert := analysisutil.IsPkg(initiatorPkg, testify.AssertPkgName, testify.AssertPkgPath) - isRequire := analysisutil.IsPkg(initiatorPkg, testify.RequirePkgName, testify.RequirePkgPath) - if !isAssert && !isRequire { - return nil - } - - funcObj, ok := typeutil.Callee(pass.TypesInfo, ce).(*types.Func) - if !ok { - return nil - } - - return &CallMeta{ - Call: ce, - Range: ce, - IsPkg: isPkgCall, - IsAssert: isAssert, - Selector: se, - SelectorXStr: analysisutil.NodeString(pass.Fset, se.X), - Fn: FnMeta{ - Range: se.Sel, - Name: fnName, - NameFTrimmed: strings.TrimSuffix(fnName, "f"), - IsFmt: strings.HasSuffix(fnName, "f"), - Signature: funcObj.Type().(*types.Signature), // NOTE(a.telyshev): Func's Type() is always a *Signature. - }, - Args: trimTArg(pass, ce.Args), - ArgsRaw: ce.Args, - } -} - -func trimTArg(pass *analysis.Pass, args []ast.Expr) []ast.Expr { - if len(args) == 0 { - return args - } - - if implementsTestingT(pass, args[0]) { - return args[1:] - } - return args -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/checker.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/checker.go deleted file mode 100644 index 0d8e9d2f4f..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/checker.go +++ /dev/null @@ -1,23 +0,0 @@ -package checkers - -import ( - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/ast/inspector" -) - -// Checker describes named checker. -type Checker interface { - Name() string -} - -// RegularChecker check assertion call presented in CallMeta form. -type RegularChecker interface { - Checker - Check(pass *analysis.Pass, call *CallMeta) *analysis.Diagnostic -} - -// AdvancedChecker implements complex Check logic different from trivial CallMeta check. -type AdvancedChecker interface { - Checker - Check(pass *analysis.Pass, insp *inspector.Inspector) []analysis.Diagnostic -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/checkers_registry.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/checkers_registry.go deleted file mode 100644 index 264e18b6db..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/checkers_registry.go +++ /dev/null @@ -1,114 +0,0 @@ -package checkers - -import ( - "sort" -) - -// registry stores checkers meta information in checkers' priority order. -var registry = checkersRegistry{ - // Regular checkers. - {factory: asCheckerFactory(NewFloatCompare), enabledByDefault: true}, - {factory: asCheckerFactory(NewBoolCompare), enabledByDefault: true}, - {factory: asCheckerFactory(NewEmpty), enabledByDefault: true}, - {factory: asCheckerFactory(NewNegativePositive), enabledByDefault: true}, - {factory: asCheckerFactory(NewCompares), enabledByDefault: true}, - {factory: asCheckerFactory(NewContains), enabledByDefault: true}, - {factory: asCheckerFactory(NewErrorNil), enabledByDefault: true}, - {factory: asCheckerFactory(NewNilCompare), enabledByDefault: true}, - {factory: asCheckerFactory(NewErrorIsAs), enabledByDefault: true}, - {factory: asCheckerFactory(NewEncodedCompare), enabledByDefault: true}, - {factory: asCheckerFactory(NewExpectedActual), enabledByDefault: true}, - {factory: asCheckerFactory(NewLen), enabledByDefault: true}, - {factory: asCheckerFactory(NewEqualValues), enabledByDefault: true}, - {factory: asCheckerFactory(NewRegexp), enabledByDefault: true}, - {factory: asCheckerFactory(NewSuiteExtraAssertCall), enabledByDefault: true}, - {factory: asCheckerFactory(NewSuiteDontUsePkg), enabledByDefault: true}, - {factory: asCheckerFactory(NewUselessAssert), enabledByDefault: true}, - {factory: asCheckerFactory(NewFormatter), enabledByDefault: true}, - // Advanced checkers. - {factory: asCheckerFactory(NewBlankImport), enabledByDefault: true}, - {factory: asCheckerFactory(NewGoRequire), enabledByDefault: true}, - {factory: asCheckerFactory(NewRequireError), enabledByDefault: true}, - {factory: asCheckerFactory(NewSuiteBrokenParallel), enabledByDefault: true}, - {factory: asCheckerFactory(NewSuiteMethodSignature), enabledByDefault: true}, - {factory: asCheckerFactory(NewSuiteSubtestRun), enabledByDefault: true}, - {factory: asCheckerFactory(NewSuiteTHelper), enabledByDefault: false}, -} - -type checkersRegistry []checkerMeta - -type checkerMeta struct { - factory checkerFactory - enabledByDefault bool -} - -type checkerFactory func() Checker - -func asCheckerFactory[T Checker](fn func() T) checkerFactory { - return func() Checker { - return fn() - } -} - -func (r checkersRegistry) get(name string) (m checkerMeta, priority int, found bool) { - for i, meta := range r { - if meta.factory().Name() == name { - return meta, i, true - } - } - return checkerMeta{}, 0, false -} - -// All returns all checkers names sorted by checker's priority. -func All() []string { - result := make([]string, 0, len(registry)) - for _, meta := range registry { - result = append(result, meta.factory().Name()) - } - return result -} - -// EnabledByDefault returns checkers enabled by default sorted by checker's priority. -func EnabledByDefault() []string { - result := make([]string, 0, len(registry)) - for _, meta := range registry { - if meta.enabledByDefault { - result = append(result, meta.factory().Name()) - } - } - return result -} - -// Get returns new checker instance by checker's name. -func Get(name string) (Checker, bool) { - meta, _, ok := registry.get(name) - if ok { - return meta.factory(), true - } - return nil, false -} - -// IsKnown checks if there is a checker with that name. -func IsKnown(name string) bool { - _, _, ok := registry.get(name) - return ok -} - -// IsEnabledByDefault returns true if a checker is enabled by default. -// Returns false if there is no such checker in the registry. -// For pre-validation use Get or IsKnown. -func IsEnabledByDefault(name string) bool { - meta, _, ok := registry.get(name) - return ok && meta.enabledByDefault -} - -// SortByPriority mutates the input checkers names by sorting them in checker priority order. -// Ignores unknown checkers. For pre-validation use Get or IsKnown. -func SortByPriority(checkers []string) { - sort.Slice(checkers, func(i, j int) bool { - lhs, rhs := checkers[i], checkers[j] - _, lhsPriority, _ := registry.get(lhs) - _, rhsPriority, _ := registry.get(rhs) - return lhsPriority < rhsPriority - }) -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/compares.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/compares.go deleted file mode 100644 index f0c4013f16..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/compares.go +++ /dev/null @@ -1,100 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/token" - - "golang.org/x/tools/go/analysis" -) - -// Compares detects situations like -// -// assert.True(t, a == b) -// assert.True(t, a != b) -// assert.True(t, a > b) -// assert.True(t, a >= b) -// assert.True(t, a < b) -// assert.True(t, a <= b) -// assert.False(t, a == b) -// ... -// -// and requires -// -// assert.Equal(t, a, b) -// assert.NotEqual(t, a, b) -// assert.Greater(t, a, b) -// assert.GreaterOrEqual(t, a, b) -// assert.Less(t, a, b) -// assert.LessOrEqual(t, a, b) -// -// If `a` and `b` are pointers then `assert.Same`/`NotSame` is required instead, -// due to the inappropriate recursive nature of `assert.Equal` (based on `reflect.DeepEqual`). -type Compares struct{} - -// NewCompares constructs Compares checker. -func NewCompares() Compares { return Compares{} } -func (Compares) Name() string { return "compares" } - -func (checker Compares) Check(pass *analysis.Pass, call *CallMeta) *analysis.Diagnostic { - if len(call.Args) < 1 { - return nil - } - - be, ok := call.Args[0].(*ast.BinaryExpr) - if !ok { - return nil - } - - var tokenToProposedFn map[token.Token]string - - switch call.Fn.NameFTrimmed { - case "True": - tokenToProposedFn = tokenToProposedFnInsteadOfTrue - case "False": - tokenToProposedFn = tokenToProposedFnInsteadOfFalse - default: - return nil - } - - proposedFn, ok := tokenToProposedFn[be.Op] - if !ok { - return nil - } - - _, xp := isPointer(pass, be.X) - _, yp := isPointer(pass, be.Y) - if xp && yp { - switch proposedFn { - case "Equal": - proposedFn = "Same" - case "NotEqual": - proposedFn = "NotSame" - } - } - - a, b := be.X, be.Y - return newUseFunctionDiagnostic(checker.Name(), call, proposedFn, - analysis.TextEdit{ - Pos: be.X.Pos(), - End: be.Y.End(), - NewText: formatAsCallArgs(pass, a, b), - }) -} - -var tokenToProposedFnInsteadOfTrue = map[token.Token]string{ - token.EQL: "Equal", - token.NEQ: "NotEqual", - token.GTR: "Greater", - token.GEQ: "GreaterOrEqual", - token.LSS: "Less", - token.LEQ: "LessOrEqual", -} - -var tokenToProposedFnInsteadOfFalse = map[token.Token]string{ - token.EQL: "NotEqual", - token.NEQ: "Equal", - token.GTR: "LessOrEqual", - token.GEQ: "Less", - token.LSS: "GreaterOrEqual", - token.LEQ: "Greater", -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/contains.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/contains.go deleted file mode 100644 index 07f76c6e4f..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/contains.go +++ /dev/null @@ -1,71 +0,0 @@ -package checkers - -import ( - "go/ast" - - "golang.org/x/tools/go/analysis" -) - -// Contains detects situations like -// -// assert.True(t, strings.Contains(a, "abc123")) -// assert.False(t, !strings.Contains(a, "abc123")) -// -// assert.False(t, strings.Contains(a, "abc123")) -// assert.True(t, !strings.Contains(a, "abc123")) -// -// and requires -// -// assert.Contains(t, a, "abc123") -// assert.NotContains(t, a, "abc123") -type Contains struct{} - -// NewContains constructs Contains checker. -func NewContains() Contains { return Contains{} } -func (Contains) Name() string { return "contains" } - -func (checker Contains) Check(pass *analysis.Pass, call *CallMeta) *analysis.Diagnostic { - if len(call.Args) < 1 { - return nil - } - - expr := call.Args[0] - unpacked, isNeg := isNegation(expr) - if isNeg { - expr = unpacked - } - - ce, ok := expr.(*ast.CallExpr) - if !ok || len(ce.Args) != 2 { - return nil - } - - if !isStringsContainsCall(pass, ce) { - return nil - } - - var proposed string - switch call.Fn.NameFTrimmed { - default: - return nil - - case "True": - proposed = "Contains" - if isNeg { - proposed = "NotContains" - } - - case "False": - proposed = "NotContains" - if isNeg { - proposed = "Contains" - } - } - - return newUseFunctionDiagnostic(checker.Name(), call, proposed, - analysis.TextEdit{ - Pos: call.Args[0].Pos(), - End: call.Args[0].End(), - NewText: formatAsCallArgs(pass, ce.Args[0], ce.Args[1]), - }) -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/empty.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/empty.go deleted file mode 100644 index 854421e6a9..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/empty.go +++ /dev/null @@ -1,204 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/token" - - "golang.org/x/tools/go/analysis" - - "github.com/Antonboom/testifylint/internal/analysisutil" -) - -// Empty detects situations like -// -// assert.Len(t, arr, 0) -// assert.Zero(t, str) -// assert.Zero(t, len(arr)) -// assert.Equal(t, 0, len(arr)) -// assert.EqualValues(t, 0, len(arr)) -// assert.Exactly(t, 0, len(arr)) -// assert.LessOrEqual(t, len(arr), 0) -// assert.GreaterOrEqual(t, 0, len(arr)) -// assert.Less(t, len(arr), 1) -// assert.Greater(t, 1, len(arr)) -// assert.Equal(t, "", str) -// assert.EqualValues(t, "", str) -// assert.Exactly(t, "", str) -// assert.Equal(t, “, str) -// assert.EqualValues(t, “, str) -// assert.Exactly(t, “, str) -// -// assert.Positive(t, len(arr)) -// assert.NotZero(t, str) -// assert.NotZero(t, len(arr)) -// assert.NotEqual(t, 0, len(arr)) -// assert.NotEqualValues(t, 0, len(arr)) -// assert.Greater(t, len(arr), 0) -// assert.Less(t, 0, len(arr)) -// assert.NotEqual(t, "", str) -// assert.NotEqualValues(t, "", str) -// assert.NotEqual(t, “, str) -// assert.NotEqualValues(t, “, str) -// -// and requires -// -// assert.Empty(t, arr) -// assert.NotEmpty(t, arr) -// -// Also Empty removes extra `len` call. -type Empty struct{} - -// NewEmpty constructs Empty checker. -func NewEmpty() Empty { return Empty{} } -func (Empty) Name() string { return "empty" } - -func (checker Empty) Check(pass *analysis.Pass, call *CallMeta) *analysis.Diagnostic { - if d := checker.checkEmpty(pass, call); d != nil { - return d - } - return checker.checkNotEmpty(pass, call) -} - -func (checker Empty) checkEmpty(pass *analysis.Pass, call *CallMeta) *analysis.Diagnostic { //nolint:gocognit // It is ok. - newUseEmptyDiagnostic := func(replaceStart, replaceEnd token.Pos, replaceWith ast.Expr) *analysis.Diagnostic { - const proposed = "Empty" - return newUseFunctionDiagnostic(checker.Name(), call, proposed, - analysis.TextEdit{ - Pos: replaceStart, - End: replaceEnd, - NewText: analysisutil.NodeBytes(pass.Fset, replaceWith), - }) - } - - if len(call.Args) == 0 { - return nil - } - a := call.Args[0] - - switch call.Fn.NameFTrimmed { - case "Zero": - if hasStringType(pass, a) { - return newUseEmptyDiagnostic(a.Pos(), a.End(), a) - } - if lenArg, ok := isBuiltinLenCall(pass, a); ok { - return newUseEmptyDiagnostic(a.Pos(), a.End(), lenArg) - } - - case "Empty": - if lenArg, ok := isBuiltinLenCall(pass, a); ok { - return newRemoveLenDiagnostic(pass, checker.Name(), call, a, lenArg) - } - } - - if len(call.Args) < 2 { - return nil - } - b := call.Args[1] - - switch call.Fn.NameFTrimmed { - case "Len": - if isZero(b) { - return newUseEmptyDiagnostic(a.Pos(), b.End(), a) - } - - case "Equal", "EqualValues", "Exactly": - if isEmptyStringLit(a) { - return newUseEmptyDiagnostic(a.Pos(), b.End(), b) - } - - arg1, ok1 := isLenCallAndZero(pass, a, b) - arg2, ok2 := isLenCallAndZero(pass, b, a) - - if lenArg, ok := anyVal([]bool{ok1, ok2}, arg1, arg2); ok { - return newUseEmptyDiagnostic(a.Pos(), b.End(), lenArg) - } - - case "LessOrEqual": - if lenArg, ok := isBuiltinLenCall(pass, a); ok && isZero(b) { - return newUseEmptyDiagnostic(a.Pos(), b.End(), lenArg) - } - - case "GreaterOrEqual": - if lenArg, ok := isBuiltinLenCall(pass, b); ok && isZero(a) { - return newUseEmptyDiagnostic(a.Pos(), b.End(), lenArg) - } - - case "Less": - if lenArg, ok := isBuiltinLenCall(pass, a); ok && (isOne(b) || isZero(b)) { - return newUseEmptyDiagnostic(a.Pos(), b.End(), lenArg) - } - - case "Greater": - if lenArg, ok := isBuiltinLenCall(pass, b); ok && (isOne(a) || isZero(a)) { - return newUseEmptyDiagnostic(a.Pos(), b.End(), lenArg) - } - } - return nil -} - -func (checker Empty) checkNotEmpty(pass *analysis.Pass, call *CallMeta) *analysis.Diagnostic { //nolint:gocognit // It is ok. - newUseNotEmptyDiagnostic := func(replaceStart, replaceEnd token.Pos, replaceWith ast.Expr) *analysis.Diagnostic { - const proposed = "NotEmpty" - return newUseFunctionDiagnostic(checker.Name(), call, proposed, - analysis.TextEdit{ - Pos: replaceStart, - End: replaceEnd, - NewText: analysisutil.NodeBytes(pass.Fset, replaceWith), - }) - } - - if len(call.Args) == 0 { - return nil - } - a := call.Args[0] - - switch call.Fn.NameFTrimmed { - case "Positive": - if lenArg, ok := isBuiltinLenCall(pass, a); ok { - return newUseNotEmptyDiagnostic(a.Pos(), a.End(), lenArg) - } - - case "NotZero": - if hasStringType(pass, a) { - return newUseNotEmptyDiagnostic(a.Pos(), a.End(), a) - } - if lenArg, ok := isBuiltinLenCall(pass, a); ok { - return newUseNotEmptyDiagnostic(a.Pos(), a.End(), lenArg) - } - - case "NotEmpty": - if lenArg, ok := isBuiltinLenCall(pass, a); ok { - return newRemoveLenDiagnostic(pass, checker.Name(), call, a, lenArg) - } - } - - if len(call.Args) < 2 { - return nil - } - b := call.Args[1] - - switch call.Fn.NameFTrimmed { - case "NotEqual", "NotEqualValues": - if isEmptyStringLit(a) { - return newUseNotEmptyDiagnostic(a.Pos(), b.End(), b) - } - - arg1, ok1 := isLenCallAndZero(pass, a, b) - arg2, ok2 := isLenCallAndZero(pass, b, a) - - if lenArg, ok := anyVal([]bool{ok1, ok2}, arg1, arg2); ok { - return newUseNotEmptyDiagnostic(a.Pos(), b.End(), lenArg) - } - - case "Less": - if lenArg, ok := isBuiltinLenCall(pass, b); ok && isZero(a) { - return newUseNotEmptyDiagnostic(a.Pos(), b.End(), lenArg) - } - - case "Greater": - if lenArg, ok := isBuiltinLenCall(pass, a); ok && isZero(b) { - return newUseNotEmptyDiagnostic(a.Pos(), b.End(), lenArg) - } - } - return nil -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/encoded_compare.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/encoded_compare.go deleted file mode 100644 index 1464fd640b..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/encoded_compare.go +++ /dev/null @@ -1,101 +0,0 @@ -package checkers - -import ( - "go/ast" - - "golang.org/x/tools/go/analysis" -) - -// EncodedCompare detects situations like -// -// assert.Equal(t, `{"foo": "bar"}`, body) -// assert.EqualValues(t, `{"foo": "bar"}`, body) -// assert.Exactly(t, `{"foo": "bar"}`, body) -// assert.Equal(t, expectedJSON, resultJSON) -// assert.Equal(t, expBodyConst, w.Body.String()) -// assert.Equal(t, fmt.Sprintf(`{"value":"%s"}`, hexString), result) -// assert.Equal(t, "{}", json.RawMessage(resp)) -// assert.Equal(t, expJSON, strings.Trim(string(resultJSONBytes), "\n")) // + Replace, ReplaceAll, TrimSpace -// -// assert.Equal(t, expectedYML, conf) -// -// and requires -// -// assert.JSONEq(t, `{"foo": "bar"}`, body) -// assert.YAMLEq(t, expectedYML, conf) -type EncodedCompare struct{} - -// NewEncodedCompare constructs EncodedCompare checker. -func NewEncodedCompare() EncodedCompare { return EncodedCompare{} } -func (EncodedCompare) Name() string { return "encoded-compare" } - -func (checker EncodedCompare) Check(pass *analysis.Pass, call *CallMeta) *analysis.Diagnostic { - switch call.Fn.NameFTrimmed { - case "Equal", "EqualValues", "Exactly": - default: - return nil - } - - if len(call.Args) < 2 { - return nil - } - lhs, rhs := call.Args[0], call.Args[1] - - a, aIsExplicitJSON := checker.unwrap(pass, call.Args[0]) - b, bIsExplicitJSON := checker.unwrap(pass, call.Args[1]) - - var proposed string - switch { - case aIsExplicitJSON, bIsExplicitJSON, isJSONStyleExpr(pass, a), isJSONStyleExpr(pass, b): - proposed = "JSONEq" - case isYAMLStyleExpr(pass, a), isYAMLStyleExpr(pass, b): - proposed = "YAMLEq" - } - - if proposed != "" { - return newUseFunctionDiagnostic(checker.Name(), call, proposed, - analysis.TextEdit{ - Pos: lhs.Pos(), - End: lhs.End(), - NewText: formatWithStringCastForBytes(pass, a), - }, - analysis.TextEdit{ - Pos: rhs.Pos(), - End: rhs.End(), - NewText: formatWithStringCastForBytes(pass, b), - }, - ) - } - return nil -} - -// unwrap unwraps expression from string, []byte, strings.Replace(All), strings.Trim(Space) and json.RawMessage conversions. -// Returns true in the second argument, if json.RawMessage was in the chain. -func (checker EncodedCompare) unwrap(pass *analysis.Pass, e ast.Expr) (ast.Expr, bool) { - ce, ok := e.(*ast.CallExpr) - if !ok { - return e, false - } - if len(ce.Args) == 0 { - return e, false - } - - if isJSONRawMessageCast(pass, ce) { - if isNil(ce.Args[0]) { // NOTE(a.telyshev): Ignore json.RawMessage(nil) case. - return checker.unwrap(pass, ce.Args[0]) - } - - v, _ := checker.unwrap(pass, ce.Args[0]) - return v, true - } - - if isIdentWithName("string", ce.Fun) || - isByteArray(ce.Fun) || - isStringsReplaceCall(pass, ce) || - isStringsReplaceAllCall(pass, ce) || - isStringsTrimCall(pass, ce) || - isStringsTrimSpaceCall(pass, ce) { - return checker.unwrap(pass, ce.Args[0]) - } - return e, false -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/equal_values.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/equal_values.go deleted file mode 100644 index c8f305c3e2..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/equal_values.go +++ /dev/null @@ -1,59 +0,0 @@ -package checkers - -import ( - "go/types" - "strings" - - "golang.org/x/tools/go/analysis" -) - -// EqualValues detects situations like -// -// assert.EqualValues(t, 42, result.IntField) -// assert.NotEqualValues(t, 42, result.IntField) -// ... -// -// and requires -// -// assert.Equal(t, 42, result.IntField) -// assert.NotEqual(t, 42, result.IntField) -type EqualValues struct{} - -// NewEqualValues constructs EqualValues checker. -func NewEqualValues() EqualValues { return EqualValues{} } -func (EqualValues) Name() string { return "equal-values" } - -func (checker EqualValues) Check(pass *analysis.Pass, call *CallMeta) *analysis.Diagnostic { - assrn := call.Fn.NameFTrimmed - switch assrn { - default: - return nil - case "EqualValues", "NotEqualValues": - } - - if len(call.Args) < 2 { - return nil - } - first, second := call.Args[0], call.Args[1] - - if isFunc(pass, first) || isFunc(pass, second) { - // NOTE(a.telyshev): EqualValues for funcs is ok, but not Equal: - // https://github.com/stretchr/testify/issues/1524 - return nil - } - - ft, st := pass.TypesInfo.TypeOf(first), pass.TypesInfo.TypeOf(second) - if !types.Identical(ft, st) { - return nil - } - - // Type of one of arguments is equivalent to any. - if isEmptyInterfaceType(ft) || isEmptyInterfaceType(st) { - // EqualValues is ok here. - // Equal would check their types and would fail. - return nil - } - - proposed := strings.TrimSuffix(assrn, "Values") - return newUseFunctionDiagnostic(checker.Name(), call, proposed) -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/error_is_as.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/error_is_as.go deleted file mode 100644 index ac9d968b8e..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/error_is_as.go +++ /dev/null @@ -1,182 +0,0 @@ -package checkers - -import ( - "fmt" - "go/ast" - "go/types" - - "golang.org/x/tools/go/analysis" - - "github.com/Antonboom/testifylint/internal/analysisutil" - "github.com/Antonboom/testifylint/internal/testify" -) - -// ErrorIsAs detects situations like -// -// assert.Error(t, err, errSentinel) -// assert.NoError(t, err, errSentinel) -// assert.IsType(t, err, errSentinel) -// assert.IsType(t, (*http.MaxBytesError)(nil), err) -// assert.IsNotType(t, err, errSentinel) -// assert.IsNotType(t, store.NotFoundError{}, err) -// assert.True(t, errors.Is(err, errSentinel)) -// assert.False(t, errors.Is(err, errSentinel)) -// assert.True(t, errors.As(err, &target)) -// assert.False(t, errors.As(err, &target)) -// -// and requires -// -// assert.ErrorIs(t, err, errSentinel) -// assert.NotErrorIs(t, err, errSentinel) -// assert.ErrorAs(t, err, &target) -// assert.NotErrorAs(t, err, &target) -// -// Also ErrorIsAs repeats go vet's "errorsas" check logic. -type ErrorIsAs struct{} - -// NewErrorIsAs constructs ErrorIsAs checker. -func NewErrorIsAs() ErrorIsAs { return ErrorIsAs{} } -func (ErrorIsAs) Name() string { return "error-is-as" } - -func (checker ErrorIsAs) Check(pass *analysis.Pass, call *CallMeta) *analysis.Diagnostic { - switch call.Fn.NameFTrimmed { - case "Error": - if len(call.Args) >= 2 && isError(pass, call.Args[1]) && !isAssertCollectT(pass, call.Selector.X) { - const proposed = "ErrorIs" - msg := fmt.Sprintf("invalid usage of %[1]s.Error, use %[1]s.%[2]s instead", call.SelectorXStr, proposed) - return newDiagnostic(checker.Name(), call, msg, newSuggestedFuncReplacement(call, proposed)) - } - - case "NoError": - if len(call.Args) >= 2 && isError(pass, call.Args[1]) { - const proposed = "NotErrorIs" - msg := fmt.Sprintf("invalid usage of %[1]s.NoError, use %[1]s.%[2]s instead", call.SelectorXStr, proposed) - return newDiagnostic(checker.Name(), call, msg, newSuggestedFuncReplacement(call, proposed)) - } - - case "IsType": - if len(call.Args) >= 2 && isError(pass, call.Args[0]) || isError(pass, call.Args[1]) { - msg := fmt.Sprintf("use %[1]s.ErrorIs or %[1]s.ErrorAs depending on the case", call.SelectorXStr) - return newDiagnostic(checker.Name(), call, msg) - } - - case "IsNotType": - if len(call.Args) >= 2 && isError(pass, call.Args[0]) || isError(pass, call.Args[1]) { - msg := fmt.Sprintf("use %[1]s.NotErrorIs or %[1]s.NotErrorAs depending on the case", call.SelectorXStr) - return newDiagnostic(checker.Name(), call, msg) - } - - case "True": - if len(call.Args) < 1 { - return nil - } - - ce, ok := call.Args[0].(*ast.CallExpr) - if !ok { - return nil - } - if len(ce.Args) != 2 { - return nil - } - - var proposed string - switch { - case isErrorsIsCall(pass, ce): - proposed = "ErrorIs" - case isErrorsAsCall(pass, ce): - proposed = "ErrorAs" - } - if proposed != "" { - return newUseFunctionDiagnostic(checker.Name(), call, proposed, - analysis.TextEdit{ - Pos: ce.Pos(), - End: ce.End(), - NewText: formatAsCallArgs(pass, ce.Args[0], ce.Args[1]), - }) - } - - case "False": - if len(call.Args) < 1 { - return nil - } - - ce, ok := call.Args[0].(*ast.CallExpr) - if !ok { - return nil - } - if len(ce.Args) != 2 { - return nil - } - - var proposed string - switch { - case isErrorsIsCall(pass, ce): - proposed = "NotErrorIs" - case isErrorsAsCall(pass, ce): - proposed = "NotErrorAs" - } - if proposed != "" { - return newUseFunctionDiagnostic(checker.Name(), call, proposed, - analysis.TextEdit{ - Pos: ce.Pos(), - End: ce.End(), - NewText: formatAsCallArgs(pass, ce.Args[0], ce.Args[1]), - }) - } - - case "ErrorAs", "NotErrorAs": - if len(call.Args) < 2 { - return nil - } - - // NOTE(a.telyshev): Logic below must be consistent with - // https://cs.opensource.google/go/x/tools/+/master:go/analysis/passes/errorsas/errorsas.go - - var ( - defaultReport = fmt.Sprintf("second argument to %s must be a non-nil pointer to either a type that implements error, or to any interface type", call) //nolint:lll - errorPtrReport = fmt.Sprintf("second argument to %s should not be *error", call) - ) - - target := call.Args[1] - - if isEmptyInterface(pass, target) { - // `any` interface case. It is always allowed, since it often indicates - // a value forwarded from another source. - return nil - } - - tv, ok := pass.TypesInfo.Types[target] - if !ok { - return nil - } - - pt, ok := tv.Type.Underlying().(*types.Pointer) - if !ok { - return newDiagnostic(checker.Name(), call, defaultReport) - } - if pt.Elem() == errorType { - return newDiagnostic(checker.Name(), call, errorPtrReport) - } - - _, isInterface := pt.Elem().Underlying().(*types.Interface) - if !isInterface && !types.Implements(pt.Elem(), errorIface) { - return newDiagnostic(checker.Name(), call, defaultReport) - } - } - return nil -} - -func isAssertCollectT(pass *analysis.Pass, e ast.Expr) bool { - ptr, ok := pass.TypesInfo.TypeOf(e).(*types.Pointer) - if !ok { - return false - } - - named, ok := ptr.Elem().(*types.Named) - if !ok { - return false - } - - collectT := analysisutil.ObjectOf(pass.Pkg, testify.AssertPkgPath, "CollectT") - return named.Obj() == collectT -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/error_nil.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/error_nil.go deleted file mode 100644 index b7ced9a8d0..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/error_nil.go +++ /dev/null @@ -1,97 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/token" - - "golang.org/x/tools/go/analysis" - - "github.com/Antonboom/testifylint/internal/analysisutil" -) - -// ErrorNil detects situations like -// -// assert.Nil(t, err) -// assert.Empty(t, err) -// assert.Zero(t, err) -// assert.Equal(t, nil, err) -// assert.EqualValues(t, nil, err) -// assert.Exactly(t, nil, err) -// assert.ErrorIs(t, err, nil) -// assert.IsType(t, err, nil) -// -// assert.NotNil(t, err) -// assert.NotEmpty(t, err) -// assert.NotZero(t, err) -// assert.NotEqual(t, nil, err) -// assert.NotEqualValues(t, nil, err) -// assert.NotErrorIs(t, err, nil) -// assert.IsNotType(t, err, nil) -// -// and requires -// -// assert.NoError(t, err) -// assert.Error(t, err) -type ErrorNil struct{} - -// NewErrorNil constructs ErrorNil checker. -func NewErrorNil() ErrorNil { return ErrorNil{} } -func (ErrorNil) Name() string { return "error-nil" } - -func (checker ErrorNil) Check(pass *analysis.Pass, call *CallMeta) *analysis.Diagnostic { - const ( - errorFn = "Error" - noErrorFn = "NoError" - ) - - proposedFn, survivingArg, replacementEndPos := func() (string, ast.Expr, token.Pos) { - switch call.Fn.NameFTrimmed { - case "Nil", "Empty", "Zero": - if len(call.Args) >= 1 && isError(pass, call.Args[0]) { - return noErrorFn, call.Args[0], call.Args[0].End() - } - - case "NotNil", "NotEmpty", "NotZero": - if len(call.Args) >= 1 && isError(pass, call.Args[0]) { - return errorFn, call.Args[0], call.Args[0].End() - } - - case "Equal", "EqualValues", "Exactly", "ErrorIs", "IsType": - if len(call.Args) < 2 { - return "", nil, token.NoPos - } - a, b := call.Args[0], call.Args[1] - - switch { - case isError(pass, a) && isNil(b): - return noErrorFn, a, b.End() - case isNil(a) && isError(pass, b): - return noErrorFn, b, b.End() - } - - case "NotEqual", "NotEqualValues", "NotErrorIs", "IsNotType": - if len(call.Args) < 2 { - return "", nil, token.NoPos - } - a, b := call.Args[0], call.Args[1] - - switch { - case isError(pass, a) && isNil(b): - return errorFn, a, b.End() - case isNil(a) && isError(pass, b): - return errorFn, b, b.End() - } - } - return "", nil, token.NoPos - }() - - if proposedFn != "" { - return newUseFunctionDiagnostic(checker.Name(), call, proposedFn, - analysis.TextEdit{ - Pos: call.Args[0].Pos(), - End: replacementEndPos, - NewText: analysisutil.NodeBytes(pass.Fset, survivingArg), - }) - } - return nil -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/expected_actual.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/expected_actual.go deleted file mode 100644 index e0467ac70b..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/expected_actual.go +++ /dev/null @@ -1,189 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/token" - "regexp" - - "golang.org/x/tools/go/analysis" - - "github.com/Antonboom/testifylint/internal/analysisutil" -) - -// DefaultExpectedVarPattern matches variables with "expected" or "wanted" prefix or suffix in the name. -var DefaultExpectedVarPattern = regexp.MustCompile( - `(^(exp(ected)?|want(ed)?)([A-Z]\w*)?$)|(^(\w*[a-z])?(Exp(ected)?|Want(ed)?)$)`) - -// ExpectedActual detects situations like -// -// assert.Equal(t, result, expected) -// assert.Equal(t, result, len(expected)) -// assert.Equal(t, len(resultFields), len(expectedFields)) -// assert.EqualExportedValues(t, resultObj, User{Name: "Anton"}) -// assert.EqualValues(t, result, 42) -// assert.Exactly(t, result, int64(42)) -// assert.JSONEq(t, result, `{"version": 3}`) -// assert.InDelta(t, result, 42.42, 1.0) -// assert.InDeltaMapValues(t, result, map[string]float64{"score": 0.99}, 1.0) -// assert.InDeltaSlice(t, result, []float64{0.98, 0.99}, 1.0) -// assert.InEpsilon(t, result, 42.42, 0.0001) -// assert.InEpsilonSlice(t, result, []float64{0.9801, 0.9902}, 0.0001) -// assert.IsType(t, result, (*User)(nil)) -// assert.NotEqual(t, result, "expected") -// assert.NotEqualValues(t, result, "expected") -// assert.NotSame(t, resultPtr, &value) -// assert.Same(t, resultPtr, &value) -// assert.WithinDuration(t, resultTime, time.Date(2023, 01, 12, 11, 46, 33, 0, nil), time.Second) -// assert.YAMLEq(t, result, "version: '3'") -// -// and requires -// -// assert.Equal(t, expected, result) -// assert.Equal(t, len(expected), result) -// assert.Equal(t, len(expectedFields), len(resultFields)) -// assert.EqualExportedValues(t, User{Name: "Anton"}, resultObj) -// assert.EqualValues(t, 42, result) -// ... -type ExpectedActual struct { - expVarPattern *regexp.Regexp -} - -// NewExpectedActual constructs ExpectedActual checker using DefaultExpectedVarPattern. -func NewExpectedActual() *ExpectedActual { - return &ExpectedActual{expVarPattern: DefaultExpectedVarPattern} -} - -func (ExpectedActual) Name() string { return "expected-actual" } - -func (checker *ExpectedActual) SetExpVarPattern(p *regexp.Regexp) *ExpectedActual { - if p != nil { - checker.expVarPattern = p - } - return checker -} - -func (checker ExpectedActual) Check(pass *analysis.Pass, call *CallMeta) *analysis.Diagnostic { - switch call.Fn.NameFTrimmed { - case "Equal", - "EqualExportedValues", - "EqualValues", - "Exactly", - "InDelta", - "InDeltaMapValues", - "InDeltaSlice", - "InEpsilon", - "InEpsilonSlice", - "IsNotType", - "IsType", - "JSONEq", - "NotEqual", - "NotEqualValues", - "NotSame", - "Same", - "WithinDuration", - "YAMLEq": - default: - return nil - } - - if len(call.Args) < 2 { - return nil - } - first, second := call.Args[0], call.Args[1] - - if checker.isWrongExpectedActualOrder(pass, first, second) { - return newDiagnostic(checker.Name(), call, "need to reverse actual and expected values", analysis.SuggestedFix{ - Message: "Reverse actual and expected values", - TextEdits: []analysis.TextEdit{ - { - Pos: first.Pos(), - End: second.End(), - NewText: formatAsCallArgs(pass, second, first), - }, - }, - }) - } - return nil -} - -func (checker ExpectedActual) isWrongExpectedActualOrder(pass *analysis.Pass, first, second ast.Expr) bool { - leftIsCandidate := checker.isExpectedValueCandidate(pass, first) - rightIsCandidate := checker.isExpectedValueCandidate(pass, second) - return rightIsCandidate && !leftIsCandidate -} - -func (checker ExpectedActual) isExpectedValueCandidate(pass *analysis.Pass, expr ast.Expr) bool { - switch v := expr.(type) { - case *ast.ParenExpr: - return checker.isExpectedValueCandidate(pass, v.X) - - case *ast.StarExpr: // *value - return checker.isExpectedValueCandidate(pass, v.X) - - case *ast.UnaryExpr: - if v.Op == token.AND || v.Op == token.SUB { // &value, -value - return checker.isExpectedValueCandidate(pass, v.X) - } - - case *ast.CompositeLit: - return true - - case *ast.CallExpr: - if lv, ok := isBuiltinLenCall(pass, expr); ok { - return isIdentNamedAfterPattern(checker.expVarPattern, lv) - } - return isParenExpr(v) || - isCastedBasicLitOrExpectedValue(v, checker.expVarPattern) || - isExpectedValueFactory(pass, v, checker.expVarPattern) - } - - return isBasicLit(expr) || - isUntypedConst(pass, expr) || - isTypedConst(pass, expr) || - isIdentNamedAfterPattern(checker.expVarPattern, expr) || - isStructVarNamedAfterPattern(checker.expVarPattern, expr) || - isStructFieldNamedAfterPattern(checker.expVarPattern, expr) -} - -func isParenExpr(ce *ast.CallExpr) bool { - _, ok := ce.Fun.(*ast.ParenExpr) - return ok -} - -func isCastedBasicLitOrExpectedValue(ce *ast.CallExpr, pattern *regexp.Regexp) bool { - if len(ce.Args) != 1 { - return false - } - - fn, ok := ce.Fun.(*ast.Ident) - if !ok { - return false - } - - switch fn.Name { - case "complex64", "complex128": - return true - - case "uint", "uint8", "uint16", "uint32", "uint64", - "int", "int8", "int16", "int32", "int64", - "float32", "float64", - "rune", "string": - return isBasicLit(ce.Args[0]) || isIdentNamedAfterPattern(pattern, ce.Args[0]) - } - return false -} - -func isExpectedValueFactory(pass *analysis.Pass, ce *ast.CallExpr, pattern *regexp.Regexp) bool { - switch fn := ce.Fun.(type) { - case *ast.Ident: - return pattern.MatchString(fn.Name) - - case *ast.SelectorExpr: - timeDateFn := analysisutil.ObjectOf(pass.Pkg, "time", "Date") - if timeDateFn != nil && analysisutil.IsObj(pass.TypesInfo, fn.Sel, timeDateFn) { - return true - } - return pattern.MatchString(fn.Sel.Name) - } - return false -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/float_compare.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/float_compare.go deleted file mode 100644 index 6bc22cd021..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/float_compare.go +++ /dev/null @@ -1,50 +0,0 @@ -package checkers - -import ( - "fmt" - "go/token" - - "golang.org/x/tools/go/analysis" -) - -// FloatCompare detects situations like -// -// assert.Equal(t, 42.42, result) -// assert.EqualValues(t, 42.42, result) -// assert.Exactly(t, 42.42, result) -// assert.True(t, result == 42.42) -// assert.False(t, result != 42.42) -// -// and requires -// -// assert.InEpsilon(t, 42.42, result, 0.0001) // Or assert.InDelta -type FloatCompare struct{} - -// NewFloatCompare constructs FloatCompare checker. -func NewFloatCompare() FloatCompare { return FloatCompare{} } -func (FloatCompare) Name() string { return "float-compare" } - -func (checker FloatCompare) Check(pass *analysis.Pass, call *CallMeta) *analysis.Diagnostic { - invalid := func() bool { - switch call.Fn.NameFTrimmed { - case "Equal", "EqualValues", "Exactly": - return len(call.Args) > 1 && (isFloat(pass, call.Args[0]) || isFloat(pass, call.Args[1])) - - case "True": - return len(call.Args) > 0 && isComparisonWithFloat(pass, call.Args[0], token.EQL) - - case "False": - return len(call.Args) > 0 && isComparisonWithFloat(pass, call.Args[0], token.NEQ) - } - return false - }() - - if invalid { - format := "use %s.InEpsilon (or InDelta)" - if call.Fn.IsFmt { - format = "use %s.InEpsilonf (or InDeltaf)" - } - return newDiagnostic(checker.Name(), call, fmt.Sprintf(format, call.SelectorXStr)) - } - return nil -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/formatter.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/formatter.go deleted file mode 100644 index 572e88f965..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/formatter.go +++ /dev/null @@ -1,268 +0,0 @@ -package checkers - -import ( - "fmt" - "go/types" - "strconv" - "strings" - - "golang.org/x/tools/go/analysis" - - "github.com/Antonboom/testifylint/internal/analysisutil" - "github.com/Antonboom/testifylint/internal/checkers/printf" - "github.com/Antonboom/testifylint/internal/testify" -) - -// Formatter detects situations like -// -// assert.ElementsMatch(t, certConfig.Org, csr.Subject.Org, "organizations not equal") -// assert.Error(t, err, fmt.Sprintf("Profile %s should not be valid", test.profile)) -// assert.Errorf(t, err, fmt.Sprintf("test %s", test.testName)) -// assert.Truef(t, targetTs.Equal(ts), "the timestamp should be as expected (%s) but was %s", targetTs) -// ... -// -// and requires -// -// assert.ElementsMatchf(t, certConfig.Org, csr.Subject.Org, "organizations not equal") -// assert.Errorf(t, err, "Profile %s should not be valid", test.profile) -// assert.Errorf(t, err, "test %s", test.testName) -// assert.Truef(t, targetTs.Equal(ts), "the timestamp should be as expected (%s) but was %s", targetTs, ts) -// -// It also checks that there are no arguments in `msgAndArgs` if the message is not a string, -// and additionally checks that the first argument of `msgAndArgs` is a not empty string. -// -// Finally, it checks that failure message in Fail and FailNow is not used as a format string (which won't work). -type Formatter struct { - checkFormatString bool - requireFFuncs bool - requireStringMsg bool -} - -// NewFormatter constructs Formatter checker. -func NewFormatter() *Formatter { - return &Formatter{ - checkFormatString: true, - requireFFuncs: false, - requireStringMsg: true, - } -} - -func (Formatter) Name() string { return "formatter" } - -func (checker *Formatter) SetCheckFormatString(v bool) *Formatter { - checker.checkFormatString = v - return checker -} - -func (checker *Formatter) SetRequireFFuncs(v bool) *Formatter { - checker.requireFFuncs = v - return checker -} - -func (checker *Formatter) SetRequireStringMsg(v bool) *Formatter { - checker.requireStringMsg = v - return checker -} - -func (checker Formatter) Check(pass *analysis.Pass, call *CallMeta) (result *analysis.Diagnostic) { - if call.Fn.IsFmt { - return checker.checkFmtAssertion(pass, call) - } - return checker.checkNotFmtAssertion(pass, call) -} - -func (checker Formatter) checkNotFmtAssertion(pass *analysis.Pass, call *CallMeta) *analysis.Diagnostic { - msgAndArgsPos, ok := isPrintfLikeCall(pass, call) - if !ok { - return nil - } - - lastArgPos := len(call.ArgsRaw) - 1 - isSingleMsgAndArgElem := msgAndArgsPos == lastArgPos - msgAndArgs := call.ArgsRaw[msgAndArgsPos] - - if name := call.Fn.NameFTrimmed; name == "Fail" || name == "FailNow" { - failureMsg, err := strconv.Unquote(analysisutil.NodeString(pass.Fset, call.Args[0])) - if err != nil { - return nil - } - if strings.Contains(failureMsg, "%") { - return newDiagnostic(checker.Name(), call, - "failure message is not a format string, use msgAndArgs instead") - } - } - - if args, ok := isFmtSprintfCall(pass, msgAndArgs); ok && isSingleMsgAndArgElem { - if checker.requireFFuncs { - return newRemoveFnAndUseDiagnostic(pass, checker.Name(), call, call.Fn.Name+"f", - "fmt.Sprintf", msgAndArgs, args...) - } - return newRemoveSprintfDiagnostic(pass, checker.Name(), call, msgAndArgs, args) - } - - if hasStringType(pass, msgAndArgs) { //nolint:nestif // This is the best option of code organization :( - format, err := strconv.Unquote(analysisutil.NodeString(pass.Fset, msgAndArgs)) - if nil == err && format == "" { // Unquote failed for not string literals. - var fixes []analysis.SuggestedFix - if isSingleMsgAndArgElem { - fixes = append(fixes, analysis.SuggestedFix{ - Message: "Remove empty message", - TextEdits: []analysis.TextEdit{newRemoveLastArgTextEdit(pass, call.Args)}, - }) - } - return newDiagnostic(checker.Name(), call, "empty message", fixes...) - } - if checker.requireFFuncs { - return newUseFunctionDiagnostic(checker.Name(), call, call.Fn.Name+"f") - } - } else { - if isSingleMsgAndArgElem { //nolint:revive // Better without early-return. - if checker.requireStringMsg { - return newDiagnostic(checker.Name(), call, - "do not use non-string value as first element (msg) of msgAndArgs", - analysis.SuggestedFix{ - Message: `Introduce "%+v" as the message`, - TextEdits: []analysis.TextEdit{ - { - Pos: msgAndArgs.Pos(), - End: msgAndArgs.End(), - NewText: []byte(`"%+v", ` + analysisutil.NodeString(pass.Fset, msgAndArgs)), - }, - }, - }) - } - } else { - return newDiagnostic(checker.Name(), call, - "using msgAndArgs with non-string first element (msg) causes panic") - } - } - return nil -} - -func (checker Formatter) checkFmtAssertion(pass *analysis.Pass, call *CallMeta) (result *analysis.Diagnostic) { - formatPos := getMsgPosition(call.Fn.Signature) - if formatPos < 0 { - return nil - } - - lastArgPos := len(call.ArgsRaw) - 1 - msg := call.ArgsRaw[formatPos] - noFormatArgs := formatPos == lastArgPos - - if formatPos == lastArgPos { - if args, ok := isFmtSprintfCall(pass, msg); ok { - return newRemoveSprintfDiagnostic(pass, checker.Name(), call, msg, args) - } - } - - format, err := strconv.Unquote(analysisutil.NodeString(pass.Fset, msg)) - if err != nil { - // Unreachable, because msg is a string literal in formatted assertion. - return nil - } - if format == "" { - var fixes []analysis.SuggestedFix - if noFormatArgs { - fixes = append(fixes, analysis.SuggestedFix{ - Message: fmt.Sprintf("Remove empty message and use `%s`", call.Fn.NameFTrimmed), - TextEdits: []analysis.TextEdit{ - newReplaceFnTextEdit(call.Fn, call.Fn.NameFTrimmed), - newRemoveLastArgTextEdit(pass, call.Args), - }, - }) - } - return newDiagnostic(checker.Name(), call, "empty message", fixes...) - } - - if checker.checkFormatString { - report := pass.Report - defer func() { pass.Report = report }() - - pass.Report = func(d analysis.Diagnostic) { - result = newDiagnostic(checker.Name(), call, d.Message) - } - printf.CheckPrintf(pass, call.Call, call.String(), format, formatPos) - } - return result -} - -func isPrintfLikeCall(pass *analysis.Pass, call *CallMeta) (int, bool) { - if call.Call.Ellipsis.IsValid() { - return -1, false - } - - msgAndArgsPos := getMsgAndArgsPosition(call.Fn.Signature) - if msgAndArgsPos <= 0 { - return -1, false - } - - if msgAndArgsPos >= len(call.ArgsRaw) { - return -1, false - } - - if !assertHasFormattedAnalogue(pass, call) { - return -1, false - } - - return msgAndArgsPos, true -} - -func assertHasFormattedAnalogue(pass *analysis.Pass, call *CallMeta) bool { - if fn := analysisutil.ObjectOf(pass.Pkg, testify.AssertPkgPath, call.Fn.Name+"f"); fn != nil { - return true - } - - if fn := analysisutil.ObjectOf(pass.Pkg, testify.RequirePkgPath, call.Fn.Name+"f"); fn != nil { - return true - } - - recv := call.Fn.Signature.Recv() - if recv == nil { - return false - } - - recvT := recv.Type() - if ptr, ok := recv.Type().(*types.Pointer); ok { - recvT = ptr.Elem() - } - - suite, ok := recvT.(*types.Named) - if !ok { - return false - } - for i := range suite.NumMethods() { - if suite.Method(i).Name() == call.Fn.Name+"f" { - return true - } - } - - return false -} - -func getMsgAndArgsPosition(sig *types.Signature) int { - params := sig.Params() - if params.Len() < 1 { - return -1 - } - - lastIdx := params.Len() - 1 - lastParam := params.At(lastIdx) - - _, isSlice := lastParam.Type().(*types.Slice) - if lastParam.Name() == "msgAndArgs" && isSlice { - return lastIdx - } - return -1 -} - -func getMsgPosition(sig *types.Signature) int { - for i := range sig.Params().Len() { - param := sig.Params().At(i) - - if b, ok := param.Type().(*types.Basic); ok && b.Kind() == types.String && (param.Name() == "msg" || - param.Name() == "format") { // NOTE(a.telyshev): assert.CollectT case. - return i - } - } - return -1 -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/go_require.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/go_require.go deleted file mode 100644 index 4a0eb294e4..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/go_require.go +++ /dev/null @@ -1,345 +0,0 @@ -package checkers - -import ( - "fmt" - "go/ast" - "go/types" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/ast/inspector" - - "github.com/Antonboom/testifylint/internal/analysisutil" -) - -const ( - goRequireFnReportFormat = "%s contains assertions that must only be used in the goroutine running the test function" - goRequireCallReportFormat = "%s must only be used in the goroutine running the test function" - goRequireHTTPHandlerReportFormat = "do not use %s in http handlers" -) - -// GoRequire takes idea from go vet's "testinggoroutine" check -// and detects usage of require package's functions or assert.FailNow in the non-test goroutines -// -// go func() { -// conn, err = lis.Accept() -// require.NoError(t, err) -// -// if assert.Error(err) { -// assert.FailNow(t, msg) -// } -// }() -type GoRequire struct { - ignoreHTTPHandlers bool -} - -// NewGoRequire constructs GoRequire checker. -func NewGoRequire() *GoRequire { return new(GoRequire) } -func (GoRequire) Name() string { return "go-require" } - -func (checker *GoRequire) SetIgnoreHTTPHandlers(v bool) *GoRequire { - checker.ignoreHTTPHandlers = v - return checker -} - -// Check should be consistent with -// https://cs.opensource.google/go/x/tools/+/master:go/analysis/passes/testinggoroutine/testinggoroutine.go -// -// But due to the fact that the Check covers cases missed by go vet, -// the implementation turned out to be terribly complicated. -// -// In simple words, the algorithm is as follows: -// - we walk along the call tree and store the status, whether we are in the test goroutine or not; -// - if we are in a test goroutine, then require is allowed, otherwise not; -// - when we encounter the launch of a subtest or `go` statement, the status changes; -// - in order to correctly handle the return to the correct status when exiting the current function, -// we have to store a stack of statuses (inGoroutineRunningTestFunc). -// -// Other test functions called in the test function are also analyzed to make a verdict about the current function. -// This leads to recursion, which the cache of processed functions (processedFuncs) helps reduce the impact of. -// Also, because of this, we have to pre-collect a list of test function declarations (testsDecls). -func (checker GoRequire) Check(pass *analysis.Pass, insp *inspector.Inspector) (diagnostics []analysis.Diagnostic) { - testsDecls := make(funcDeclarations) - insp.Preorder([]ast.Node{(*ast.FuncDecl)(nil)}, func(node ast.Node) { - fd := node.(*ast.FuncDecl) - - if isTestingFuncOrMethod(pass, fd) { - if tf, ok := pass.TypesInfo.ObjectOf(fd.Name).(*types.Func); ok { - testsDecls[tf] = fd - } - } - }) - - var inGoroutineRunningTestFunc boolStack - processedFuncs := make(map[*ast.FuncDecl]goRequireVerdict) - - nodesFilter := []ast.Node{ - (*ast.FuncDecl)(nil), - (*ast.FuncType)(nil), - (*ast.GoStmt)(nil), - (*ast.CallExpr)(nil), - } - insp.Nodes(nodesFilter, func(node ast.Node, push bool) bool { - if fd, ok := node.(*ast.FuncDecl); ok { - if !isTestingFuncOrMethod(pass, fd) { - return false - } - - if push { - inGoroutineRunningTestFunc.Push(true) - } else { - inGoroutineRunningTestFunc.Pop() - } - return true - } - - if ft, ok := node.(*ast.FuncType); ok { - if !isTestingAnonymousFunc(pass, ft) { - return false - } - - if push { - inGoroutineRunningTestFunc.Push(true) - } else { - inGoroutineRunningTestFunc.Pop() - } - return true - } - - if _, ok := node.(*ast.GoStmt); ok { - if push { - inGoroutineRunningTestFunc.Push(false) - } else { - inGoroutineRunningTestFunc.Pop() - } - return true - } - - ce := node.(*ast.CallExpr) - if isSubTestRun(pass, ce) { - if push { - // t.Run spawns the new testing goroutine and declines - // possible warnings from previous "simple" goroutine. - inGoroutineRunningTestFunc.Push(true) - } else { - inGoroutineRunningTestFunc.Pop() - } - return true - } - - if !push { - return false - } - if inGoroutineRunningTestFunc.Len() == 0 { - // Insufficient info. - return true - } - if inGoroutineRunningTestFunc.Last() { - // We are in testing goroutine and can skip any assertion checks. - return true - } - - testifyCall := NewCallMeta(pass, ce) - if testifyCall != nil { - switch checker.checkCall(testifyCall) { - case goRequireVerdictRequire: - d := newDiagnostic(checker.Name(), testifyCall, fmt.Sprintf(goRequireCallReportFormat, "require")) - diagnostics = append(diagnostics, *d) - - case goRequireVerdictAssertFailNow: - d := newDiagnostic(checker.Name(), testifyCall, fmt.Sprintf(goRequireCallReportFormat, testifyCall)) - diagnostics = append(diagnostics, *d) - - case goRequireVerdictNoExit: - } - return false - } - - // Case of nested function call. - { - calledFd := testsDecls.Get(pass, ce) - if calledFd == nil { - return true - } - - if v := checker.checkFunc(pass, calledFd, testsDecls, processedFuncs); v != goRequireVerdictNoExit { - caller := analysisutil.NodeString(pass.Fset, ce.Fun) - d := newDiagnostic(checker.Name(), ce, fmt.Sprintf(goRequireFnReportFormat, caller)) - diagnostics = append(diagnostics, *d) - } - } - return true - }) - - if !checker.ignoreHTTPHandlers { - diagnostics = append(diagnostics, checker.checkHTTPHandlers(pass, insp)...) - } - - return diagnostics -} - -func (checker GoRequire) checkHTTPHandlers(pass *analysis.Pass, insp *inspector.Inspector) (diagnostics []analysis.Diagnostic) { - insp.WithStack([]ast.Node{(*ast.CallExpr)(nil)}, func(node ast.Node, push bool, stack []ast.Node) bool { - if !push { - return false - } - if len(stack) < 3 { - return true - } - - fID := findSurroundingFunc(pass, stack) - if fID == nil || !fID.meta.isHTTPHandler { - return true - } - - testifyCall := NewCallMeta(pass, node.(*ast.CallExpr)) - if testifyCall == nil { - return true - } - - switch checker.checkCall(testifyCall) { - case goRequireVerdictRequire: - d := newDiagnostic(checker.Name(), testifyCall, fmt.Sprintf(goRequireHTTPHandlerReportFormat, "require")) - diagnostics = append(diagnostics, *d) - - case goRequireVerdictAssertFailNow: - d := newDiagnostic(checker.Name(), testifyCall, fmt.Sprintf(goRequireHTTPHandlerReportFormat, testifyCall)) - diagnostics = append(diagnostics, *d) - - case goRequireVerdictNoExit: - } - return false - }) - return diagnostics -} - -func (checker GoRequire) checkFunc( - pass *analysis.Pass, - fd *ast.FuncDecl, - testsDecls funcDeclarations, - processedFuncs map[*ast.FuncDecl]goRequireVerdict, -) (result goRequireVerdict) { - if v, ok := processedFuncs[fd]; ok { - return v - } - - ast.Inspect(fd, func(node ast.Node) bool { - if result != goRequireVerdictNoExit { - return false - } - - if _, ok := node.(*ast.GoStmt); ok { - return false - } - - ce, ok := node.(*ast.CallExpr) - if !ok { - return true - } - - testifyCall := NewCallMeta(pass, ce) - if testifyCall != nil { - if v := checker.checkCall(testifyCall); v != goRequireVerdictNoExit { - result, processedFuncs[fd] = v, v - } - return false - } - - // Case of nested function call. - { - calledFd := testsDecls.Get(pass, ce) - if calledFd == nil { - return true - } - if calledFd == fd { - // Recursion. - return true - } - - if v := checker.checkFunc(pass, calledFd, testsDecls, processedFuncs); v != goRequireVerdictNoExit { - result = v - return false - } - return true - } - }) - - return result -} - -type goRequireVerdict int - -const ( - goRequireVerdictNoExit goRequireVerdict = iota - goRequireVerdictRequire - goRequireVerdictAssertFailNow -) - -func (checker GoRequire) checkCall(call *CallMeta) goRequireVerdict { - if !call.IsAssert { - return goRequireVerdictRequire - } - if call.Fn.NameFTrimmed == "FailNow" { - return goRequireVerdictAssertFailNow - } - return goRequireVerdictNoExit -} - -type funcDeclarations map[*types.Func]*ast.FuncDecl - -// Get returns the declaration of a called function or method. -// Currently, only static calls within the same package are supported, otherwise returns nil. -func (fd funcDeclarations) Get(pass *analysis.Pass, ce *ast.CallExpr) *ast.FuncDecl { - var obj types.Object - - switch fun := ce.Fun.(type) { - case *ast.SelectorExpr: - obj = pass.TypesInfo.ObjectOf(fun.Sel) - - case *ast.Ident: - obj = pass.TypesInfo.ObjectOf(fun) - - case *ast.IndexExpr: - if id, ok := fun.X.(*ast.Ident); ok { - obj = pass.TypesInfo.ObjectOf(id) - } - - case *ast.IndexListExpr: - if id, ok := fun.X.(*ast.Ident); ok { - obj = pass.TypesInfo.ObjectOf(id) - } - } - - if tf, ok := obj.(*types.Func); ok { - return fd[tf] - } - return nil -} - -type boolStack []bool - -func (s boolStack) Len() int { - return len(s) -} - -func (s *boolStack) Push(v bool) { - *s = append(*s, v) -} - -func (s *boolStack) Pop() bool { - n := len(*s) - if n == 0 { - return false - } - - last := (*s)[n-1] - *s = (*s)[:n-1] - return last -} - -func (s boolStack) Last() bool { - n := len(s) - if n == 0 { - return false - } - return s[n-1] -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers.go deleted file mode 100644 index 4e4735269c..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers.go +++ /dev/null @@ -1,43 +0,0 @@ -package checkers - -import ( - "go/ast" - - "golang.org/x/tools/go/analysis" -) - -func xor(a, b bool) bool { - return a != b -} - -// anyVal returns the first value[i] for which bools[i] is true. -func anyVal[T any](bools []bool, vals ...T) (T, bool) { - if len(bools) != len(vals) { - panic("inconsistent usage of valOr") //nolint:forbidigo // Does not depend on the code being analyzed. - } - - for i, b := range bools { - if b { - return vals[i], true - } - } - - var _default T - return _default, false -} - -func anyCondSatisfaction(pass *analysis.Pass, p predicate, vals ...ast.Expr) bool { - for _, v := range vals { - if p(pass, v) { - return true - } - } - return false -} - -// p transforms simple is-function in a predicate. -func p(fn func(e ast.Expr) bool) predicate { - return func(_ *analysis.Pass, e ast.Expr) bool { - return fn(e) - } -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_basic_type.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_basic_type.go deleted file mode 100644 index a716cb0e2f..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_basic_type.go +++ /dev/null @@ -1,174 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/token" - "go/types" - "strconv" - - "golang.org/x/tools/go/analysis" -) - -func isZero(e ast.Expr) bool { return isIntNumber(e, 0) } - -func isOne(e ast.Expr) bool { return isIntNumber(e, 1) } - -func isAnyZero(e ast.Expr) bool { - return isIntNumber(e, 0) || isTypedSignedIntNumber(e, 0) || isTypedUnsignedIntNumber(e, 0) -} - -func isNotAnyZero(e ast.Expr) bool { - return !isAnyZero(e) -} - -func isZeroOrSignedZero(e ast.Expr) bool { - return isIntNumber(e, 0) || isTypedSignedIntNumber(e, 0) -} - -func isSignedNotZero(pass *analysis.Pass, e ast.Expr) bool { - return !isUnsigned(pass, e) && !isZeroOrSignedZero(e) -} - -func isTypedSignedIntNumber(e ast.Expr, v int) bool { - return isTypedIntNumber(e, v, "int", "int8", "int16", "int32", "int64") -} - -func isTypedUnsignedIntNumber(e ast.Expr, v int) bool { - return isTypedIntNumber(e, v, "uint", "uint8", "uint16", "uint32", "uint64") -} - -func isTypedIntNumber(e ast.Expr, v int, goTypes ...string) bool { - ce, ok := e.(*ast.CallExpr) - if !ok || len(ce.Args) != 1 { - return false - } - - fn, ok := ce.Fun.(*ast.Ident) - if !ok { - return false - } - - for _, t := range goTypes { - if fn.Name == t { - return isIntNumber(ce.Args[0], v) - } - } - return false -} - -func isIntNumber(e ast.Expr, rhs int) bool { - lhs, ok := isIntBasicLit(e) - return ok && (lhs == rhs) -} - -func isStringLit(e ast.Expr) bool { - bl, ok := e.(*ast.BasicLit) - return ok && bl.Kind == token.STRING -} - -func isEmptyStringLit(e ast.Expr) bool { - bl, ok := e.(*ast.BasicLit) - return ok && bl.Kind == token.STRING && (bl.Value == `""` || bl.Value == "``") -} - -func isBasicLit(e ast.Expr) bool { - if un, ok := e.(*ast.UnaryExpr); ok { - if un.Op == token.SUB { - return isBasicLit(un.X) - } - } - - _, ok := e.(*ast.BasicLit) - return ok -} - -func isIntBasicLit(e ast.Expr) (int, bool) { - if un, ok := e.(*ast.UnaryExpr); ok { - if un.Op == token.SUB { - v, ok := isIntBasicLit(un.X) - return -1 * v, ok - } - } - - bl, ok := e.(*ast.BasicLit) - if !ok { - return 0, false - } - if bl.Kind != token.INT { - return 0, false - } - - v, err := strconv.Atoi(bl.Value) - if err != nil { - return 0, false - } - return v, true -} - -func isUntypedConst(pass *analysis.Pass, e ast.Expr) bool { - return isUnderlying(pass, e, types.IsUntyped) -} - -func isTypedConst(pass *analysis.Pass, e ast.Expr) bool { - tt, ok := pass.TypesInfo.Types[e] - return ok && tt.IsValue() && tt.Value != nil -} - -func isFloat(pass *analysis.Pass, e ast.Expr) bool { - return isUnderlying(pass, e, types.IsFloat) -} - -func isUnsigned(pass *analysis.Pass, e ast.Expr) bool { - return isUnderlying(pass, e, types.IsUnsigned) -} - -func isUnderlying(pass *analysis.Pass, e ast.Expr, flag types.BasicInfo) bool { - t := pass.TypesInfo.TypeOf(e) - if t == nil { - return false - } - - bt, ok := t.Underlying().(*types.Basic) - return ok && (bt.Info()&flag > 0) -} - -func isPointer(pass *analysis.Pass, e ast.Expr) (types.Type, bool) { - ptr, ok := pass.TypesInfo.TypeOf(e).(*types.Pointer) - if !ok { - return nil, false - } - return ptr.Elem(), true -} - -func isFunc(pass *analysis.Pass, e ast.Expr) bool { - _, ok := pass.TypesInfo.TypeOf(e).(*types.Signature) - return ok -} - -// isByteArray returns true if expression is `[]byte` itself. -func isByteArray(e ast.Expr) bool { - at, ok := e.(*ast.ArrayType) - return ok && isIdentWithName("byte", at.Elt) -} - -// hasBytesType returns true if the expression is of `[]byte` type. -func hasBytesType(pass *analysis.Pass, e ast.Expr) bool { - t := pass.TypesInfo.TypeOf(e) - if t == nil { - return false - } - - sl, ok := t.(*types.Slice) - if !ok { - return false - } - - el, ok := sl.Elem().(*types.Basic) - return ok && el.Kind() == types.Uint8 -} - -// hasStringType returns true if the expression is of `string` type. -func hasStringType(pass *analysis.Pass, e ast.Expr) bool { - basicType, ok := pass.TypesInfo.TypeOf(e).(*types.Basic) - return ok && basicType.Kind() == types.String -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_bool.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_bool.go deleted file mode 100644 index 613f2fd30d..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_bool.go +++ /dev/null @@ -1,37 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/types" - - "golang.org/x/tools/go/analysis" - - "github.com/Antonboom/testifylint/internal/analysisutil" -) - -var ( - falseObj = types.Universe.Lookup("false") - trueObj = types.Universe.Lookup("true") -) - -func isUntypedBool(pass *analysis.Pass, e ast.Expr) bool { - return isUntypedTrue(pass, e) || isUntypedFalse(pass, e) -} - -func isUntypedTrue(pass *analysis.Pass, e ast.Expr) bool { - return analysisutil.IsObj(pass.TypesInfo, e, trueObj) -} - -func isUntypedFalse(pass *analysis.Pass, e ast.Expr) bool { - return analysisutil.IsObj(pass.TypesInfo, e, falseObj) -} - -func hasBoolType(pass *analysis.Pass, e ast.Expr) bool { - basicType, ok := pass.TypesInfo.TypeOf(e).(*types.Basic) - return ok && basicType.Kind() == types.Bool -} - -func isBoolOverride(pass *analysis.Pass, e ast.Expr) bool { - namedType, ok := pass.TypesInfo.TypeOf(e).(*types.Named) - return ok && namedType.Obj().Name() == "bool" -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_comparison.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_comparison.go deleted file mode 100644 index e628443074..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_comparison.go +++ /dev/null @@ -1,68 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/token" - - "golang.org/x/tools/go/analysis" -) - -func isComparisonWithFloat(p *analysis.Pass, e ast.Expr, op token.Token) bool { - be, ok := e.(*ast.BinaryExpr) - if !ok { - return false - } - return be.Op == op && (isFloat(p, be.X) || isFloat(p, be.Y)) -} - -func isComparisonWithTrue(pass *analysis.Pass, e ast.Expr, op token.Token) (ast.Expr, bool) { - return isComparisonWith(pass, e, isUntypedTrue, op) -} - -func isComparisonWithFalse(pass *analysis.Pass, e ast.Expr, op token.Token) (ast.Expr, bool) { - return isComparisonWith(pass, e, isUntypedFalse, op) -} - -type predicate func(pass *analysis.Pass, e ast.Expr) bool - -func isComparisonWith( - pass *analysis.Pass, - e ast.Expr, - predicate predicate, - op token.Token, -) (ast.Expr, bool) { - be, ok := e.(*ast.BinaryExpr) - if !ok { - return nil, false - } - if be.Op != op { - return nil, false - } - - t1, t2 := predicate(pass, be.X), predicate(pass, be.Y) - if xor(t1, t2) { - if t1 { - return be.Y, true - } - return be.X, true - } - return nil, false -} - -func isStrictComparisonWith( - pass *analysis.Pass, - e ast.Expr, - lhs predicate, - op token.Token, - rhs predicate, -) (leftOperand ast.Expr, rightOperand ast.Expr, fact bool) { - be, ok := e.(*ast.BinaryExpr) - if !ok { - return nil, nil, false - } - - if be.Op == op && lhs(pass, be.X) && rhs(pass, be.Y) { - return be.X, be.Y, true - } - return nil, nil, false -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_context.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_context.go deleted file mode 100644 index 2ad0ae4a36..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_context.go +++ /dev/null @@ -1,126 +0,0 @@ -package checkers - -import ( - "fmt" - "go/ast" - "go/token" - - "golang.org/x/tools/go/analysis" -) - -type funcID struct { - pos token.Pos - posStr string - name string - meta funcMeta -} - -type funcMeta struct { - isTestCleanup bool - isGoroutine bool - isHTTPHandler bool -} - -func (id funcID) String() string { - return fmt.Sprintf("%s at %s", id.name, id.posStr) -} - -func findSurroundingFunc(pass *analysis.Pass, stack []ast.Node) *funcID { - for i := len(stack) - 2; i >= 0; i-- { - var fType *ast.FuncType - var fName string - var isTestCleanup bool - var isGoroutine bool - var isHTTPHandler bool - - switch fd := stack[i].(type) { - case *ast.FuncDecl: - fType, fName = fd.Type, fd.Name.Name - - if isSuiteMethod(pass, fd) { - if ident := fd.Name; ident != nil && isSuiteAfterTestMethod(ident.Name) { - isTestCleanup = true - } - } - - if mimicHTTPHandler(pass, fd.Type) { - isHTTPHandler = true - } - - case *ast.FuncLit: - fType, fName = fd.Type, "anonymous" - - if mimicHTTPHandler(pass, fType) { - isHTTPHandler = true - } - - if i >= 2 { //nolint:nestif // Already clear code. - if ce, ok := stack[i-1].(*ast.CallExpr); ok { - if se, ok := ce.Fun.(*ast.SelectorExpr); ok { - isTestCleanup = implementsTestingT(pass, se.X) && se.Sel != nil && (se.Sel.Name == "Cleanup") - } - - if _, ok := stack[i-2].(*ast.GoStmt); ok { - isGoroutine = true - } - } - } - - default: - continue - } - - return &funcID{ - pos: fType.Pos(), - posStr: pass.Fset.Position(fType.Pos()).String(), - name: fName, - meta: funcMeta{ - isTestCleanup: isTestCleanup, - isGoroutine: isGoroutine, - isHTTPHandler: isHTTPHandler, - }, - } - } - return nil -} - -func findNearestNode[T ast.Node](stack []ast.Node) (v T) { - v, _ = findNearestNodeWithIdx[T](stack) - return -} - -func findNearestNodeWithIdx[T ast.Node](stack []ast.Node) (v T, index int) { - for i := len(stack) - 2; i >= 0; i-- { - if n, ok := stack[i].(T); ok { - return n, i - } - } - return -} - -func fnContainsAssertions(pass *analysis.Pass, fn *ast.FuncDecl) bool { - if fn.Body == nil { - return false - } - - for _, s := range fn.Body.List { - if isAssertionStmt(pass, s) { - return true - } - } - return false -} - -func isAssertionStmt(pass *analysis.Pass, stmt ast.Stmt) bool { - expr, ok := stmt.(*ast.ExprStmt) - if !ok { - return false - } - - ce, ok := expr.X.(*ast.CallExpr) - if !ok { - return false - } - - return NewCallMeta(pass, ce) != nil -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_diagnostic.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_diagnostic.go deleted file mode 100644 index c1364f2741..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_diagnostic.go +++ /dev/null @@ -1,153 +0,0 @@ -package checkers - -import ( - "fmt" - "go/ast" - - "golang.org/x/tools/go/analysis" -) - -func newRemoveFnAndUseDiagnostic( - pass *analysis.Pass, - checker string, - call *CallMeta, - proposedFn string, - removedFn string, - removedFnPos analysis.Range, - removedFnArgs ...ast.Expr, -) *analysis.Diagnostic { - f := proposedFn - if call.Fn.IsFmt { - f += "f" - } - msg := fmt.Sprintf("remove unnecessary %s and use %s.%s", removedFn, call.SelectorXStr, f) - - return newDiagnostic(checker, call, msg, - newSuggestedFuncRemoving(pass, removedFn, removedFnPos, removedFnArgs...), - newSuggestedFuncReplacement(call, proposedFn), - ) -} - -func newUseFunctionDiagnostic( - checker string, - call *CallMeta, - proposedFn string, - additionalEdits ...analysis.TextEdit, -) *analysis.Diagnostic { - f := proposedFn - if call.Fn.IsFmt { - f += "f" - } - msg := fmt.Sprintf("use %s.%s", call.SelectorXStr, f) - - return newDiagnostic(checker, call, msg, - newSuggestedFuncReplacement(call, proposedFn, additionalEdits...)) -} - -func newRemoveLenDiagnostic( - pass *analysis.Pass, - checker string, - call *CallMeta, - fnPos analysis.Range, - fnArg ast.Expr, -) *analysis.Diagnostic { - return newRemoveFnDiagnostic(pass, checker, call, "len", fnPos, fnArg) -} - -func newRemoveMustCompileDiagnostic( - pass *analysis.Pass, - checker string, - call *CallMeta, - fnPos analysis.Range, - fnArg ast.Expr, -) *analysis.Diagnostic { - return newRemoveFnDiagnostic(pass, checker, call, "regexp.MustCompile", fnPos, fnArg) -} - -func newRemoveSprintfDiagnostic( - pass *analysis.Pass, - checker string, - call *CallMeta, - fnPos analysis.Range, - fnArgs []ast.Expr, -) *analysis.Diagnostic { - return newRemoveFnDiagnostic(pass, checker, call, "fmt.Sprintf", fnPos, fnArgs...) -} - -func newRemoveFnDiagnostic( - pass *analysis.Pass, - checker string, - call *CallMeta, - fnName string, - fnPos analysis.Range, - fnArgs ...ast.Expr, -) *analysis.Diagnostic { - return newDiagnostic(checker, call, "remove unnecessary "+fnName, - newSuggestedFuncRemoving(pass, fnName, fnPos, fnArgs...)) -} - -func newDiagnostic( - checker string, - rng analysis.Range, - msg string, - fixes ...analysis.SuggestedFix, -) *analysis.Diagnostic { - d := analysis.Diagnostic{ - Pos: rng.Pos(), - End: rng.End(), - Category: checker, - Message: checker + ": " + msg, - } - if len(fixes) != 0 { - d.SuggestedFixes = fixes - } - return &d -} - -func newSuggestedFuncRemoving( - pass *analysis.Pass, - fnName string, - fnPos analysis.Range, - fnArgs ...ast.Expr, -) analysis.SuggestedFix { - return analysis.SuggestedFix{ - Message: fmt.Sprintf("Remove `%s`", fnName), - TextEdits: []analysis.TextEdit{ - { - Pos: fnPos.Pos(), - End: fnPos.End(), - NewText: formatAsCallArgs(pass, fnArgs...), - }, - }, - } -} - -func newSuggestedFuncReplacement( - call *CallMeta, - proposedFn string, - additionalEdits ...analysis.TextEdit, -) analysis.SuggestedFix { - if call.Fn.IsFmt { - proposedFn += "f" - } - return analysis.SuggestedFix{ - Message: fmt.Sprintf("Replace `%s` with `%s`", call.Fn.Name, proposedFn), - TextEdits: append([]analysis.TextEdit{newReplaceFnTextEdit(call.Fn, proposedFn)}, additionalEdits...), - } -} - -func newReplaceFnTextEdit(callFn analysis.Range, proposedFn string) analysis.TextEdit { - return analysis.TextEdit{ - Pos: callFn.Pos(), - End: callFn.End(), - NewText: []byte(proposedFn), - } -} - -func newRemoveLastArgTextEdit(pass *analysis.Pass, callArgs []ast.Expr) analysis.TextEdit { - return analysis.TextEdit{ - Pos: callArgs[0].Pos(), - End: callArgs[len(callArgs)-1].End(), - NewText: formatAsCallArgs(pass, callArgs[0:len(callArgs)-1]...), - } -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_encoded.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_encoded.go deleted file mode 100644 index c366f85635..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_encoded.go +++ /dev/null @@ -1,56 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/token" - "regexp" - - "golang.org/x/tools/go/analysis" - - "github.com/Antonboom/testifylint/internal/analysisutil" -) - -var ( - wordsRe = regexp.MustCompile(`[A-Z]+(?:[a-z]*|$)|[a-z]+`) // NOTE(a.telyshev): ChatGPT. - - jsonIdentRe = regexp.MustCompile(`json|JSON|Json`) - yamlWordRe = regexp.MustCompile(`yaml|YAML|Yaml|^(yml|YML|Yml)$`) -) - -func isJSONStyleExpr(pass *analysis.Pass, e ast.Expr) bool { - if isIdentNamedAfterPattern(jsonIdentRe, e) { - return hasBytesType(pass, e) || hasStringType(pass, e) - } - - if t, ok := pass.TypesInfo.Types[e]; ok && t.Value != nil { - return analysisutil.IsJSONLike(t.Value.String()) - } - - if bl, ok := e.(*ast.BasicLit); ok { - return bl.Kind == token.STRING && analysisutil.IsJSONLike(bl.Value) - } - - if args, ok := isFmtSprintfCall(pass, e); ok { - return isJSONStyleExpr(pass, args[0]) - } - - return false -} - -func isYAMLStyleExpr(pass *analysis.Pass, e ast.Expr) bool { - id, ok := e.(*ast.Ident) - return ok && (hasBytesType(pass, e) || hasStringType(pass, e)) && hasWordAfterPattern(id.Name, yamlWordRe) -} - -func hasWordAfterPattern(s string, re *regexp.Regexp) bool { - for _, w := range splitIntoWords(s) { - if re.MatchString(w) { - return true - } - } - return false -} - -func splitIntoWords(s string) []string { - return wordsRe.FindAllString(s, -1) -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_error.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_error.go deleted file mode 100644 index 859a39ee87..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_error.go +++ /dev/null @@ -1,26 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/types" - - "golang.org/x/tools/go/analysis" -) - -var ( - errorObj = types.Universe.Lookup("error") - errorType = errorObj.Type() - errorIface = errorType.Underlying().(*types.Interface) -) - -func isError(pass *analysis.Pass, expr ast.Expr) bool { - return pass.TypesInfo.TypeOf(expr) == errorType -} - -func isErrorsIsCall(pass *analysis.Pass, ce *ast.CallExpr) bool { - return isPkgFnCall(pass, ce, "errors", "Is") -} - -func isErrorsAsCall(pass *analysis.Pass, ce *ast.CallExpr) bool { - return isPkgFnCall(pass, ce, "errors", "As") -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_format.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_format.go deleted file mode 100644 index d69c42860f..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_format.go +++ /dev/null @@ -1,61 +0,0 @@ -package checkers - -import ( - "bytes" - "go/ast" - "strings" - - "golang.org/x/tools/go/analysis" - - "github.com/Antonboom/testifylint/internal/analysisutil" -) - -// formatAsCallArgs joins a, b and c and returns bytes like `a, b, c`. -func formatAsCallArgs(pass *analysis.Pass, args ...ast.Expr) []byte { - if len(args) == 0 { - return []byte("") - } - - var buf bytes.Buffer - for i, arg := range args { - buf.Write(analysisutil.NodeBytes(pass.Fset, arg)) - if i != len(args)-1 { - buf.WriteString(", ") - } - } - return buf.Bytes() -} - -func formatWithStringCastForBytes(pass *analysis.Pass, e ast.Expr) []byte { - if !hasBytesType(pass, e) { - return analysisutil.NodeBytes(pass.Fset, e) - } - - if se, ok := isBufferBytesCall(pass, e); ok { - return []byte(analysisutil.NodeString(pass.Fset, se) + ".String()") - } - return []byte("string(" + analysisutil.NodeString(pass.Fset, e) + ")") -} - -func isBufferBytesCall(pass *analysis.Pass, e ast.Expr) (ast.Node, bool) { - ce, ok := e.(*ast.CallExpr) - if !ok { - return nil, false - } - - se, ok := ce.Fun.(*ast.SelectorExpr) - if !ok { - return nil, false - } - - if !isIdentWithName("Bytes", se.Sel) { - return nil, false - } - if t := pass.TypesInfo.TypeOf(se.X); t != nil { - // NOTE(a.telyshev): This is hack, because `bytes` package can be not imported, - // and we cannot do "true" comparison with `Buffer` object. - return se.X, strings.TrimPrefix(t.String(), "*") == "bytes.Buffer" - } - - return nil, false -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_http.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_http.go deleted file mode 100644 index 4aa19c1bb7..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_http.go +++ /dev/null @@ -1,35 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/types" - - "golang.org/x/tools/go/analysis" - - "github.com/Antonboom/testifylint/internal/analysisutil" -) - -func mimicHTTPHandler(pass *analysis.Pass, fType *ast.FuncType) bool { - httpHandlerFuncObj := analysisutil.ObjectOf(pass.Pkg, "net/http", "HandlerFunc") - if httpHandlerFuncObj == nil { - return false - } - - sig, ok := httpHandlerFuncObj.Type().Underlying().(*types.Signature) - if !ok { - return false - } - - if len(fType.Params.List) != sig.Params().Len() { - return false - } - - for i := range sig.Params().Len() { - lhs := sig.Params().At(i).Type() - rhs := pass.TypesInfo.TypeOf(fType.Params.List[i].Type) - if !types.Identical(lhs, rhs) { - return false - } - } - return true -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_interface.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_interface.go deleted file mode 100644 index ad39c72d74..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_interface.go +++ /dev/null @@ -1,51 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/types" - - "golang.org/x/tools/go/analysis" - - "github.com/Antonboom/testifylint/internal/analysisutil" - "github.com/Antonboom/testifylint/internal/testify" -) - -func isEmptyInterface(pass *analysis.Pass, expr ast.Expr) bool { - t, ok := pass.TypesInfo.Types[expr] - if !ok { - return false - } - return isEmptyInterfaceType(t.Type) -} - -func isEmptyInterfaceType(t types.Type) bool { - iface, ok := t.Underlying().(*types.Interface) - return ok && iface.NumMethods() == 0 -} - -func implementsTestifySuite(pass *analysis.Pass, e ast.Expr) bool { - suiteIfaceObj := analysisutil.ObjectOf(pass.Pkg, testify.SuitePkgPath, "TestingSuite") - return (suiteIfaceObj != nil) && implements(pass, e, suiteIfaceObj) -} - -func implementsTestingT(pass *analysis.Pass, e ast.Expr) bool { - return implementsAssertTestingT(pass, e) || implementsRequireTestingT(pass, e) -} - -func implementsAssertTestingT(pass *analysis.Pass, e ast.Expr) bool { - assertTestingTObj := analysisutil.ObjectOf(pass.Pkg, testify.AssertPkgPath, "TestingT") - return (assertTestingTObj != nil) && implements(pass, e, assertTestingTObj) -} - -func implementsRequireTestingT(pass *analysis.Pass, e ast.Expr) bool { - requireTestingTObj := analysisutil.ObjectOf(pass.Pkg, testify.RequirePkgPath, "TestingT") - return (requireTestingTObj != nil) && implements(pass, e, requireTestingTObj) -} - -func implements(pass *analysis.Pass, e ast.Expr, ifaceObj types.Object) bool { - t := pass.TypesInfo.TypeOf(e) - if t == nil { - return false - } - return types.Implements(t, ifaceObj.Type().Underlying().(*types.Interface)) -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_len.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_len.go deleted file mode 100644 index 6afa5849aa..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_len.go +++ /dev/null @@ -1,29 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/types" - - "golang.org/x/tools/go/analysis" - - "github.com/Antonboom/testifylint/internal/analysisutil" -) - -var lenObj = types.Universe.Lookup("len") - -func isLenCallAndZero(pass *analysis.Pass, a, b ast.Expr) (ast.Expr, bool) { - lenArg, ok := isBuiltinLenCall(pass, a) - return lenArg, ok && isZero(b) -} - -func isBuiltinLenCall(pass *analysis.Pass, e ast.Expr) (ast.Expr, bool) { - ce, ok := e.(*ast.CallExpr) - if !ok { - return nil, false - } - - if analysisutil.IsObj(pass.TypesInfo, ce.Fun, lenObj) && len(ce.Args) == 1 { - return ce.Args[0], true - } - return nil, false -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_naming.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_naming.go deleted file mode 100644 index 1d92e3e810..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_naming.go +++ /dev/null @@ -1,26 +0,0 @@ -package checkers - -import ( - "go/ast" - "regexp" -) - -func isStructVarNamedAfterPattern(pattern *regexp.Regexp, e ast.Expr) bool { - s, ok := e.(*ast.SelectorExpr) - return ok && isIdentNamedAfterPattern(pattern, s.X) -} - -func isStructFieldNamedAfterPattern(pattern *regexp.Regexp, e ast.Expr) bool { - s, ok := e.(*ast.SelectorExpr) - return ok && isIdentNamedAfterPattern(pattern, s.Sel) -} - -func isIdentNamedAfterPattern(pattern *regexp.Regexp, e ast.Expr) bool { - id, ok := e.(*ast.Ident) - return ok && pattern.MatchString(id.Name) -} - -func isIdentWithName(name string, e ast.Expr) bool { - id, ok := e.(*ast.Ident) - return ok && id.Name == name -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_nil.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_nil.go deleted file mode 100644 index 112fca38e7..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_nil.go +++ /dev/null @@ -1,18 +0,0 @@ -package checkers - -import "go/ast" - -func xorNil(first, second ast.Expr) (ast.Expr, bool) { - a, b := isNil(first), isNil(second) - if xor(a, b) { - if a { - return second, true - } - return first, true - } - return nil, false -} - -func isNil(expr ast.Expr) bool { - return isIdentWithName("nil", expr) -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_pkg_func.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_pkg_func.go deleted file mode 100644 index daf309339c..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_pkg_func.go +++ /dev/null @@ -1,59 +0,0 @@ -package checkers - -import ( - "go/ast" - - "golang.org/x/tools/go/analysis" - - "github.com/Antonboom/testifylint/internal/analysisutil" -) - -func isFmtSprintfCall(pass *analysis.Pass, e ast.Expr) ([]ast.Expr, bool) { - ce, ok := e.(*ast.CallExpr) - if !ok { - return nil, false - } - return ce.Args, isPkgFnCall(pass, ce, "fmt", "Sprintf") -} - -func isJSONRawMessageCast(pass *analysis.Pass, ce *ast.CallExpr) bool { - return isPkgFnCall(pass, ce, "encoding/json", "RawMessage") -} - -func isRegexpMustCompileCall(pass *analysis.Pass, ce *ast.CallExpr) bool { - return isPkgFnCall(pass, ce, "regexp", "MustCompile") -} - -func isStringsContainsCall(pass *analysis.Pass, ce *ast.CallExpr) bool { - return isPkgFnCall(pass, ce, "strings", "Contains") -} - -func isStringsReplaceCall(pass *analysis.Pass, ce *ast.CallExpr) bool { - return isPkgFnCall(pass, ce, "strings", "Replace") -} - -func isStringsReplaceAllCall(pass *analysis.Pass, ce *ast.CallExpr) bool { - return isPkgFnCall(pass, ce, "strings", "ReplaceAll") -} - -func isStringsTrimCall(pass *analysis.Pass, ce *ast.CallExpr) bool { - return isPkgFnCall(pass, ce, "strings", "Trim") -} - -func isStringsTrimSpaceCall(pass *analysis.Pass, ce *ast.CallExpr) bool { - return isPkgFnCall(pass, ce, "strings", "TrimSpace") -} - -func isPkgFnCall(pass *analysis.Pass, ce *ast.CallExpr, pkg, fn string) bool { - se, ok := ce.Fun.(*ast.SelectorExpr) - if !ok { - return false - } - - fnObj := analysisutil.ObjectOf(pass.Pkg, pkg, fn) - if fnObj == nil { - return false - } - - return analysisutil.IsObj(pass.TypesInfo, se.Sel, fnObj) -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_suite.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_suite.go deleted file mode 100644 index 9f39d4653d..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_suite.go +++ /dev/null @@ -1,40 +0,0 @@ -package checkers - -import ( - "go/ast" - "strings" - - "golang.org/x/tools/go/analysis" -) - -func isSuiteMethod(pass *analysis.Pass, fDecl *ast.FuncDecl) bool { - if fDecl.Recv == nil || len(fDecl.Recv.List) != 1 { - return false - } - - rcv := fDecl.Recv.List[0] - return implementsTestifySuite(pass, rcv.Type) -} - -func isSuiteTestMethod(name string) bool { - return strings.HasPrefix(name, "Test") -} - -func isSuiteServiceMethod(name string) bool { - // https://github.com/stretchr/testify/blob/master/suite/interfaces.go - switch name { - case "T", "SetT", "SetS", "SetupSuite", "SetupTest", "TearDownSuite", "TearDownTest", - "BeforeTest", "AfterTest", "HandleStats", "SetupSubTest", "TearDownSubTest": - return true - } - return false -} - -func isSuiteAfterTestMethod(name string) bool { - // https://github.com/stretchr/testify/blob/master/suite/interfaces.go - switch name { - case "TearDownSuite", "TearDownTest", "AfterTest", "HandleStats", "TearDownSubTest": - return true - } - return false -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_testing.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_testing.go deleted file mode 100644 index 5c28ec883f..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/helpers_testing.go +++ /dev/null @@ -1,36 +0,0 @@ -package checkers - -import ( - "go/ast" - - "golang.org/x/tools/go/analysis" -) - -func isSubTestRun(pass *analysis.Pass, ce *ast.CallExpr) bool { - se, ok := ce.Fun.(*ast.SelectorExpr) - if !ok || se.Sel == nil { - return false - } - return (implementsTestingT(pass, se.X) || implementsTestifySuite(pass, se.X)) && se.Sel.Name == "Run" -} - -func isTestingFuncOrMethod(pass *analysis.Pass, fd *ast.FuncDecl) bool { - return hasTestingTParam(pass, fd.Type) || isSuiteMethod(pass, fd) -} - -func isTestingAnonymousFunc(pass *analysis.Pass, ft *ast.FuncType) bool { - return hasTestingTParam(pass, ft) -} - -func hasTestingTParam(pass *analysis.Pass, ft *ast.FuncType) bool { - if ft == nil || ft.Params == nil { - return false - } - - for _, param := range ft.Params.List { - if implementsTestingT(pass, param.Type) { - return true - } - } - return false -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/len.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/len.go deleted file mode 100644 index 51a883b142..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/len.go +++ /dev/null @@ -1,105 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/token" - - "golang.org/x/tools/go/analysis" -) - -// Len detects situations like -// -// assert.Equal(t, 42, len(arr)) -// assert.Equal(t, len(arr), 42) -// assert.EqualValues(t, 42, len(arr)) -// assert.EqualValues(t, len(arr), 42) -// assert.Exactly(t, 42, len(arr)) -// assert.Exactly(t, len(arr), 42) -// assert.True(t, 42 == len(arr)) -// assert.True(t, len(arr) == 42) -// -// assert.Equal(t, value, len(arr)) -// assert.EqualValues(t, value, len(arr)) -// assert.Exactly(t, value, len(arr)) -// assert.True(t, len(arr) == value) -// -// assert.Equal(t, len(expArr), len(arr)) -// assert.EqualValues(t, len(expArr), len(arr)) -// assert.Exactly(t, len(expArr), len(arr)) -// assert.True(t, len(arr) == len(expArr)) -// -// and requires -// -// assert.Len(t, arr, 42) -// assert.Len(t, arr, value) -// assert.Len(t, arr, len(expArr)) -// -// The checker ignores assertions in which length checking is not a priority, e.g -// -// assert.Equal(t, len(arr), value) -type Len struct{} - -// NewLen constructs Len checker. -func NewLen() Len { return Len{} } -func (Len) Name() string { return "len" } - -func (checker Len) Check(pass *analysis.Pass, call *CallMeta) *analysis.Diagnostic { - switch call.Fn.NameFTrimmed { - case "Equal", "EqualValues", "Exactly": - if len(call.Args) < 2 { - return nil - } - - a, b := call.Args[0], call.Args[1] - return checker.checkArgs(call, pass, a, b, false) - - case "True": - if len(call.Args) < 1 { - return nil - } - - be, ok := call.Args[0].(*ast.BinaryExpr) - if !ok { - return nil - } - if be.Op != token.EQL { - return nil - } - return checker.checkArgs(call, pass, be.Y, be.X, true) // In True, the actual value is usually first. - } - return nil -} - -func (checker Len) checkArgs(call *CallMeta, pass *analysis.Pass, a, b ast.Expr, inverted bool) *analysis.Diagnostic { - newUseLenDiagnostic := func(lenArg, expectedLen ast.Expr) *analysis.Diagnostic { - const proposedFn = "Len" - start, end := a.Pos(), b.End() - if inverted { - start, end = b.Pos(), a.End() - } - return newUseFunctionDiagnostic(checker.Name(), call, proposedFn, - analysis.TextEdit{ - Pos: start, - End: end, - NewText: formatAsCallArgs(pass, lenArg, expectedLen), - }) - } - - arg1, firstIsLen := isBuiltinLenCall(pass, a) - arg2, secondIsLen := isBuiltinLenCall(pass, b) - - switch { - case firstIsLen && secondIsLen: - return newUseLenDiagnostic(arg2, a) - - case firstIsLen: - if _, secondIsNum := isIntBasicLit(b); secondIsNum { - return newUseLenDiagnostic(arg1, b) - } - - case secondIsLen: - return newUseLenDiagnostic(arg2, a) - } - - return nil -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/negative_positive.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/negative_positive.go deleted file mode 100644 index f15dc49818..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/negative_positive.go +++ /dev/null @@ -1,178 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/token" - - "golang.org/x/tools/go/analysis" - - "github.com/Antonboom/testifylint/internal/analysisutil" -) - -// NegativePositive detects situations like -// -// assert.Less(t, a, 0) -// assert.Greater(t, 0, a) -// assert.True(t, a < 0) -// assert.True(t, 0 > a) -// assert.False(t, a >= 0) -// assert.False(t, 0 <= a) -// -// assert.Greater(t, a, 0) -// assert.Less(t, 0, a) -// assert.True(t, a > 0) -// assert.True(t, 0 < a) -// assert.False(t, a <= 0) -// assert.False(t, 0 >= a) -// -// and requires -// -// assert.Negative(t, value) -// assert.Positive(t, value) -// -// Typed zeros (like `int8(0)`, ..., `uint64(0)`) are also supported. -type NegativePositive struct{} - -// NewNegativePositive constructs NegativePositive checker. -func NewNegativePositive() NegativePositive { return NegativePositive{} } -func (NegativePositive) Name() string { return "negative-positive" } - -func (checker NegativePositive) Check(pass *analysis.Pass, call *CallMeta) *analysis.Diagnostic { - if d := checker.checkNegative(pass, call); d != nil { - return d - } - return checker.checkPositive(pass, call) -} - -func (checker NegativePositive) checkNegative(pass *analysis.Pass, call *CallMeta) *analysis.Diagnostic { - newUseNegativeDiagnostic := func(replaceStart, replaceEnd token.Pos, replaceWith ast.Expr) *analysis.Diagnostic { - const proposed = "Negative" - return newUseFunctionDiagnostic(checker.Name(), call, proposed, - analysis.TextEdit{ - Pos: replaceStart, - End: replaceEnd, - NewText: analysisutil.NodeBytes(pass.Fset, replaceWith), - }) - } - - // NOTE(a.telyshev): We ignore uint and len asserts as being no sense for assert.Negative. - - switch call.Fn.NameFTrimmed { - case "Less": - if len(call.Args) < 2 { - return nil - } - a, b := call.Args[0], call.Args[1] - - if canBeNegative(pass, a) && isZeroOrSignedZero(b) { - return newUseNegativeDiagnostic(a.Pos(), b.End(), a) - } - - case "Greater": - if len(call.Args) < 2 { - return nil - } - a, b := call.Args[0], call.Args[1] - - if isZeroOrSignedZero(a) && canBeNegative(pass, b) { - return newUseNegativeDiagnostic(a.Pos(), b.End(), b) - } - - case "True": - if len(call.Args) < 1 { - return nil - } - expr := call.Args[0] - - a, _, ok1 := isStrictComparisonWith(pass, expr, canBeNegative, token.LSS, p(isZeroOrSignedZero)) // a < 0 - _, b, ok2 := isStrictComparisonWith(pass, expr, p(isZeroOrSignedZero), token.GTR, canBeNegative) // 0 > a - - survivingArg, ok := anyVal([]bool{ok1, ok2}, a, b) - if ok { - return newUseNegativeDiagnostic(expr.Pos(), expr.End(), survivingArg) - } - - case "False": - if len(call.Args) < 1 { - return nil - } - expr := call.Args[0] - - a, _, ok1 := isStrictComparisonWith(pass, expr, canBeNegative, token.GEQ, p(isZeroOrSignedZero)) // a >= 0 - _, b, ok2 := isStrictComparisonWith(pass, expr, p(isZeroOrSignedZero), token.LEQ, canBeNegative) // 0 <= a - - survivingArg, ok := anyVal([]bool{ok1, ok2}, a, b) - if ok { - return newUseNegativeDiagnostic(expr.Pos(), expr.End(), survivingArg) - } - } - return nil -} - -func (checker NegativePositive) checkPositive(pass *analysis.Pass, call *CallMeta) *analysis.Diagnostic { - newUsePositiveDiagnostic := func(replaceStart, replaceEnd token.Pos, replaceWith ast.Expr) *analysis.Diagnostic { - const proposed = "Positive" - return newUseFunctionDiagnostic(checker.Name(), call, proposed, - analysis.TextEdit{ - Pos: replaceStart, - End: replaceEnd, - NewText: analysisutil.NodeBytes(pass.Fset, replaceWith), - }) - } - - switch call.Fn.NameFTrimmed { - case "Greater": - if len(call.Args) < 2 { - return nil - } - a, b := call.Args[0], call.Args[1] - - if isNotAnyZero(a) && isAnyZero(b) { - return newUsePositiveDiagnostic(a.Pos(), b.End(), a) - } - - case "Less": - if len(call.Args) < 2 { - return nil - } - a, b := call.Args[0], call.Args[1] - - if isAnyZero(a) && isNotAnyZero(b) { - return newUsePositiveDiagnostic(a.Pos(), b.End(), b) - } - - case "True": - if len(call.Args) < 1 { - return nil - } - expr := call.Args[0] - - a, _, ok1 := isStrictComparisonWith(pass, expr, p(isNotAnyZero), token.GTR, p(isAnyZero)) // a > 0 - _, b, ok2 := isStrictComparisonWith(pass, expr, p(isAnyZero), token.LSS, p(isNotAnyZero)) // 0 < a - - survivingArg, ok := anyVal([]bool{ok1, ok2}, a, b) - if ok { - return newUsePositiveDiagnostic(expr.Pos(), expr.End(), survivingArg) - } - - case "False": - if len(call.Args) < 1 { - return nil - } - expr := call.Args[0] - - a, _, ok1 := isStrictComparisonWith(pass, expr, p(isNotAnyZero), token.LEQ, p(isAnyZero)) // a <= 0 - _, b, ok2 := isStrictComparisonWith(pass, expr, p(isAnyZero), token.GEQ, p(isNotAnyZero)) // 0 >= a - - survivingArg, ok := anyVal([]bool{ok1, ok2}, a, b) - if ok { - return newUsePositiveDiagnostic(expr.Pos(), expr.End(), survivingArg) - } - } - return nil -} - -func canBeNegative(pass *analysis.Pass, e ast.Expr) bool { - _, isLen := isBuiltinLenCall(pass, e) - return isSignedNotZero(pass, e) && !isLen -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/nil_compare.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/nil_compare.go deleted file mode 100644 index fc1adb7ead..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/nil_compare.go +++ /dev/null @@ -1,55 +0,0 @@ -package checkers - -import ( - "golang.org/x/tools/go/analysis" - - "github.com/Antonboom/testifylint/internal/analysisutil" -) - -// NilCompare detects situations like -// -// assert.Equal(t, nil, value) -// assert.EqualValues(t, nil, value) -// assert.Exactly(t, nil, value) -// -// assert.NotEqual(t, nil, value) -// assert.NotEqualValues(t, nil, value) -// -// and requires -// -// assert.Nil(t, value) -// assert.NotNil(t, value) -type NilCompare struct{} - -// NewNilCompare constructs NilCompare checker. -func NewNilCompare() NilCompare { return NilCompare{} } -func (NilCompare) Name() string { return "nil-compare" } - -func (checker NilCompare) Check(pass *analysis.Pass, call *CallMeta) *analysis.Diagnostic { - if len(call.Args) < 2 { - return nil - } - - survivingArg, ok := xorNil(call.Args[0], call.Args[1]) - if !ok { - return nil - } - - var proposedFn string - - switch call.Fn.NameFTrimmed { - case "Equal", "EqualValues", "Exactly": - proposedFn = "Nil" - case "NotEqual", "NotEqualValues": - proposedFn = "NotNil" - default: - return nil - } - - return newUseFunctionDiagnostic(checker.Name(), call, proposedFn, - analysis.TextEdit{ - Pos: call.Args[0].Pos(), - End: call.Args[1].End(), - NewText: analysisutil.NodeBytes(pass.Fset, survivingArg), - }) -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/printf/LICENSE b/vendor/github.com/Antonboom/testifylint/internal/checkers/printf/LICENSE deleted file mode 100644 index 6a66aea5ea..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/printf/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/printf/doc.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/printf/doc.go deleted file mode 100644 index 09cd239937..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/printf/doc.go +++ /dev/null @@ -1,6 +0,0 @@ -// Package printf is a patched fork of -// https://github.com/golang/tools/blob/b6235391adb3b7f8bcfc4df81055e8f023de2688/go/analysis/passes/printf/printf.go#L538 -// -// Initial discussion: -// https://go-review.googlesource.com/c/tools/+/580555/comments/dfe3ef96_b1b815d5 -package printf diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/printf/printf.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/printf/printf.go deleted file mode 100644 index 4f6e3f9c44..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/printf/printf.go +++ /dev/null @@ -1,559 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package printf - -import ( - "bytes" - "fmt" - "go/ast" - "go/token" - "go/types" - "strconv" - "strings" - "unicode/utf8" - - "golang.org/x/tools/go/analysis" - - "github.com/Antonboom/testifylint/internal/analysisutil" -) - -// CheckPrintf checks a call to a formatted print routine such as Printf. -func CheckPrintf( - pass *analysis.Pass, - call *ast.CallExpr, - fnName string, - format string, - formatIdx int, -) { - firstArg := formatIdx + 1 // Arguments are immediately after format string. - if !strings.Contains(format, "%") { - if len(call.Args) > firstArg { - pass.Reportf(call.Lparen, "%s call has arguments but no formatting directives", fnName) - } - return - } - // Hard part: check formats against args. - argNum := firstArg - maxArgNum := firstArg - anyIndex := false - for i, w := 0, 0; i < len(format); i += w { - w = 1 - if format[i] != '%' { - continue - } - state := parsePrintfVerb(pass, call, fnName, format[i:], firstArg, argNum) - if state == nil { - return - } - w = len(state.format) - if !okPrintfArg(pass, call, state) { // One error per format is enough. - return - } - if state.hasIndex { - anyIndex = true - } - if state.verb == 'w' { - pass.Reportf(call.Pos(), "%s does not support error-wrapping directive %%w", state.name) - return - } - if len(state.argNums) > 0 { - // Continue with the next sequential argument. - argNum = state.argNums[len(state.argNums)-1] + 1 - } - for _, n := range state.argNums { - if n >= maxArgNum { - maxArgNum = n + 1 - } - } - } - // Dotdotdot is hard. - if call.Ellipsis.IsValid() && maxArgNum >= len(call.Args)-1 { - return - } - // If any formats are indexed, extra arguments are ignored. - if anyIndex { - return - } - // There should be no leftover arguments. - if maxArgNum != len(call.Args) { - expect := maxArgNum - firstArg - numArgs := len(call.Args) - firstArg - pass.ReportRangef(call, "%s call needs %v but has %v", fnName, count(expect, "arg"), count(numArgs, "arg")) - } -} - -// formatState holds the parsed representation of a printf directive such as "%3.*[4]d". -// It is constructed by parsePrintfVerb. -type formatState struct { - verb rune // the format verb: 'd' for "%d" - format string // the full format directive from % through verb, "%.3d". - name string // Printf, Sprintf etc. - flags []byte // the list of # + etc. - argNums []int // the successive argument numbers that are consumed, adjusted to refer to actual arg in call - firstArg int // Index of first argument after the format in the Printf call. - // Used only during parse. - pass *analysis.Pass - call *ast.CallExpr - argNum int // Which argument we're expecting to format now. - hasIndex bool // Whether the argument is indexed. - indexPending bool // Whether we have an indexed argument that has not resolved. - nbytes int // number of bytes of the format string consumed. -} - -// parseFlags accepts any printf flags. -func (s *formatState) parseFlags() { - for s.nbytes < len(s.format) { - switch c := s.format[s.nbytes]; c { - case '#', '0', '+', '-', ' ': - s.flags = append(s.flags, c) - s.nbytes++ - default: - return - } - } -} - -// scanNum advances through a decimal number if present. -func (s *formatState) scanNum() { - for ; s.nbytes < len(s.format); s.nbytes++ { - c := s.format[s.nbytes] - if c < '0' || '9' < c { - return - } - } -} - -// parseIndex scans an index expression. It returns false if there is a syntax error. -func (s *formatState) parseIndex() bool { - if s.nbytes == len(s.format) || s.format[s.nbytes] != '[' { - return true - } - // Argument index present. - s.nbytes++ // skip '[' - start := s.nbytes - s.scanNum() - ok := true - if s.nbytes == len(s.format) || s.nbytes == start || s.format[s.nbytes] != ']' { - ok = false // syntax error is either missing "]" or invalid index. - s.nbytes = strings.Index(s.format[start:], "]") - if s.nbytes < 0 { - s.pass.ReportRangef(s.call, "%s format %s is missing closing ]", s.name, s.format) - return false - } - s.nbytes += start - } - arg32, err := strconv.ParseInt(s.format[start:s.nbytes], 10, 32) - if err != nil || !ok || arg32 <= 0 || arg32 > int64(len(s.call.Args)-s.firstArg) { - s.pass.ReportRangef(s.call, "%s format has invalid argument index [%s]", s.name, s.format[start:s.nbytes]) - return false - } - s.nbytes++ // skip ']' - arg := int(arg32) - arg += s.firstArg - 1 // We want to zero-index the actual arguments. - s.argNum = arg - s.hasIndex = true - s.indexPending = true - return true -} - -// parseNum scans a width or precision (or *). It returns false if there's a bad index expression. -func (s *formatState) parseNum() bool { - if s.nbytes < len(s.format) && s.format[s.nbytes] == '*' { - if s.indexPending { // Absorb it. - s.indexPending = false - } - s.nbytes++ - s.argNums = append(s.argNums, s.argNum) - s.argNum++ - } else { - s.scanNum() - } - return true -} - -// parsePrecision scans for a precision. It returns false if there's a bad index expression. -func (s *formatState) parsePrecision() bool { - // If there's a period, there may be a precision. - if s.nbytes < len(s.format) && s.format[s.nbytes] == '.' { - s.flags = append(s.flags, '.') // Treat precision as a flag. - s.nbytes++ - if !s.parseIndex() { - return false - } - if !s.parseNum() { - return false - } - } - return true -} - -// isFormatter reports whether t could satisfy fmt.Formatter. -// The only interface method to look for is "Format(State, rune)". -func isFormatter(typ types.Type) bool { - // If the type is an interface, the value it holds might satisfy fmt.Formatter. - if _, ok := typ.Underlying().(*types.Interface); ok { - // Don't assume type parameters could be formatters. With the greater - // expressiveness of constraint interface syntax we expect more type safety - // when using type parameters. - if !isTypeParam(typ) { - return true - } - } - obj, _, _ := types.LookupFieldOrMethod(typ, false, nil, "Format") - fn, ok := obj.(*types.Func) - if !ok { - return false - } - sig := fn.Type().(*types.Signature) - return sig.Params().Len() == 2 && - sig.Results().Len() == 0 && - isNamedType(sig.Params().At(0).Type(), "fmt", "State") && - types.Identical(sig.Params().At(1).Type(), types.Typ[types.Rune]) -} - -// isTypeParam reports whether t is a type parameter (or an alias of one). -func isTypeParam(t types.Type) bool { - _, ok := types.Unalias(t).(*types.TypeParam) - return ok -} - -// isNamedType reports whether t is the named type with the given package path -// and one of the given names. -// This function avoids allocating the concatenation of "pkg.Name", -// which is important for the performance of syntax matching. -func isNamedType(t types.Type, pkgPath string, names ...string) bool { - n, ok := types.Unalias(t).(*types.Named) - if !ok { - return false - } - obj := n.Obj() - if obj == nil || obj.Pkg() == nil || obj.Pkg().Path() != pkgPath { - return false - } - name := obj.Name() - for _, n := range names { - if name == n { - return true - } - } - return false -} - -// parsePrintfVerb looks the formatting directive that begins the format string -// and returns a formatState that encodes what the directive wants, without looking -// at the actual arguments present in the call. The result is nil if there is an error. -func parsePrintfVerb(pass *analysis.Pass, call *ast.CallExpr, name, format string, firstArg, argNum int) *formatState { - state := &formatState{ - format: format, - name: name, - flags: make([]byte, 0, 5), - argNum: argNum, - argNums: make([]int, 0, 1), - nbytes: 1, // There's guaranteed to be a percent sign. - firstArg: firstArg, - pass: pass, - call: call, - } - // There may be flags. - state.parseFlags() - // There may be an index. - if !state.parseIndex() { - return nil - } - // There may be a width. - if !state.parseNum() { - return nil - } - // There may be a precision. - if !state.parsePrecision() { - return nil - } - // Now a verb, possibly prefixed by an index (which we may already have). - if !state.indexPending && !state.parseIndex() { - return nil - } - if state.nbytes == len(state.format) { - pass.ReportRangef(call.Fun, "%s format %s is missing verb at end of string", name, state.format) - return nil - } - verb, w := utf8.DecodeRuneInString(state.format[state.nbytes:]) - state.verb = verb - state.nbytes += w - if verb != '%' { - state.argNums = append(state.argNums, state.argNum) - } - state.format = state.format[:state.nbytes] - return state -} - -// printfArgType encodes the types of expressions a printf verb accepts. It is a bitmask. -type printfArgType int - -const ( - argBool printfArgType = 1 << iota - argInt - argRune - argString - argFloat - argComplex - argPointer - argError - anyType printfArgType = ^0 -) - -type printVerb struct { - verb rune // User may provide verb through Formatter; could be a rune. - flags string // known flags are all ASCII - typ printfArgType -} - -// Common flag sets for printf verbs. -const ( - noFlag = "" - numFlag = " -+.0" - sharpNumFlag = " -+.0#" - allFlags = " -+.0#" -) - -// printVerbs identifies which flags are known to printf for each verb. -var printVerbs = []printVerb{ - // '-' is a width modifier, always valid. - // '.' is a precision for float, max width for strings. - // '+' is required sign for numbers, Go format for %v. - // '#' is alternate format for several verbs. - // ' ' is spacer for numbers - {'%', noFlag, 0}, - {'b', sharpNumFlag, argInt | argFloat | argComplex | argPointer}, - {'c', "-", argRune | argInt}, - {'d', numFlag, argInt | argPointer}, - {'e', sharpNumFlag, argFloat | argComplex}, - {'E', sharpNumFlag, argFloat | argComplex}, - {'f', sharpNumFlag, argFloat | argComplex}, - {'F', sharpNumFlag, argFloat | argComplex}, - {'g', sharpNumFlag, argFloat | argComplex}, - {'G', sharpNumFlag, argFloat | argComplex}, - {'o', sharpNumFlag, argInt | argPointer}, - {'O', sharpNumFlag, argInt | argPointer}, - {'p', "-#", argPointer}, - {'q', " -+.0#", argRune | argInt | argString}, - {'s', " -+.0", argString}, - {'t', "-", argBool}, - {'T', "-", anyType}, - {'U', "-#", argRune | argInt}, - {'v', allFlags, anyType}, - {'w', allFlags, argError}, - {'x', sharpNumFlag, argRune | argInt | argString | argPointer | argFloat | argComplex}, - {'X', sharpNumFlag, argRune | argInt | argString | argPointer | argFloat | argComplex}, -} - -// okPrintfArg compares the formatState to the arguments actually present, -// reporting any discrepancies it can discern. If the final argument is ellipsissed, -// there's little it can do for that. -func okPrintfArg(pass *analysis.Pass, call *ast.CallExpr, state *formatState) (ok bool) { - var v printVerb - found := false - // Linear scan is fast enough for a small list. - for _, v = range printVerbs { - if v.verb == state.verb { - found = true - break - } - } - - // Could current arg implement fmt.Formatter? - // Skip check for the %w verb, which requires an error. - formatter := false - if v.typ != argError && state.argNum < len(call.Args) { - if tv, ok := pass.TypesInfo.Types[call.Args[state.argNum]]; ok { - formatter = isFormatter(tv.Type) - } - } - - if !formatter { - if !found { - pass.ReportRangef(call, "%s format %s has unknown verb %c", state.name, state.format, state.verb) - return false - } - for _, flag := range state.flags { - // TODO: Disable complaint about '0' for Go 1.10. To be fixed properly in 1.11. - // See issues 23598 and 23605. - if flag == '0' { - continue - } - if !strings.ContainsRune(v.flags, rune(flag)) { - pass.ReportRangef(call, "%s format %s has unrecognized flag %c", state.name, state.format, flag) - return false - } - } - } - // Verb is good. If len(state.argNums)>trueArgs, we have something like %.*s and all - // but the final arg must be an integer. - trueArgs := 1 - if state.verb == '%' { - trueArgs = 0 - } - nargs := len(state.argNums) - for i := 0; i < nargs-trueArgs; i++ { - if !argCanBeChecked(pass, call, i, state) { - return - } - // NOTE(a.telyshev): `matchArgType` leads to a lot of "golang.org/x/tools/internal" code. - /* - argNum := state.argNums[i] - arg := call.Args[argNum] - - if reason, ok := matchArgType(pass, argInt, arg); !ok { - details := "" - if reason != "" { - details = " (" + reason + ")" - } - pass.ReportRangef(call, "%s format %s uses non-int %s%s as argument of *", state.name, state.format, analysisutil.Format(pass.Fset, arg), details) - return false - } - */ - } - - if state.verb == '%' || formatter { - return true - } - argNum := state.argNums[len(state.argNums)-1] - if !argCanBeChecked(pass, call, len(state.argNums)-1, state) { - return false - } - arg := call.Args[argNum] - if isFunctionValue(pass, arg) && state.verb != 'p' && state.verb != 'T' { - pass.ReportRangef(call, "%s format %s arg %s is a func value, not called", state.name, state.format, analysisutil.NodeString(pass.Fset, arg)) - return false - } - // NOTE(a.telyshev): `matchArgType` leads to a lot of "golang.org/x/tools/internal" code. - /* - if reason, ok := matchArgType(pass, v.typ, arg); !ok { - typeString := "" - if typ := pass.TypesInfo.Types[arg].Type; typ != nil { - typeString = typ.String() - } - details := "" - if reason != "" { - details = " (" + reason + ")" - } - pass.ReportRangef(call, "%s format %s has arg %s of wrong type %s%s", state.name, state.format, analysisutil.Format(pass.Fset, arg), typeString, details) - return false - } - */ - if v.typ&argString != 0 && v.verb != 'T' && !bytes.Contains(state.flags, []byte{'#'}) { - if methodName, ok := recursiveStringer(pass, arg); ok { - pass.ReportRangef(call, "%s format %s with arg %s causes recursive %s method call", state.name, state.format, analysisutil.NodeString(pass.Fset, arg), methodName) - return false - } - } - return true -} - -// recursiveStringer reports whether the argument e is a potential -// recursive call to stringer or is an error, such as t and &t in these examples: -// -// func (t *T) String() string { printf("%s", t) } -// func (t T) Error() string { printf("%s", t) } -// func (t T) String() string { printf("%s", &t) } -func recursiveStringer(pass *analysis.Pass, e ast.Expr) (string, bool) { - typ := pass.TypesInfo.Types[e].Type - - // It's unlikely to be a recursive stringer if it has a Format method. - if isFormatter(typ) { - return "", false - } - - // Does e allow e.String() or e.Error()? - strObj, _, _ := types.LookupFieldOrMethod(typ, false, pass.Pkg, "String") - strMethod, strOk := strObj.(*types.Func) - errObj, _, _ := types.LookupFieldOrMethod(typ, false, pass.Pkg, "Error") - errMethod, errOk := errObj.(*types.Func) - if !strOk && !errOk { - return "", false - } - - // inScope returns true if e is in the scope of f. - inScope := func(e ast.Expr, f *types.Func) bool { - return f.Scope() != nil && f.Scope().Contains(e.Pos()) - } - - // Is the expression e within the body of that String or Error method? - var method *types.Func - if strOk && strMethod.Pkg() == pass.Pkg && inScope(e, strMethod) { - method = strMethod - } else if errOk && errMethod.Pkg() == pass.Pkg && inScope(e, errMethod) { - method = errMethod - } else { - return "", false - } - - sig := method.Type().(*types.Signature) - if !isStringer(sig) { - return "", false - } - - // Is it the receiver r, or &r? - if u, ok := e.(*ast.UnaryExpr); ok && u.Op == token.AND { - e = u.X // strip off & from &r - } - if id, ok := e.(*ast.Ident); ok { - if pass.TypesInfo.Uses[id] == sig.Recv() { - return method.FullName(), true - } - } - return "", false -} - -// isStringer reports whether the method signature matches the String() definition in fmt.Stringer. -func isStringer(sig *types.Signature) bool { - return sig.Params().Len() == 0 && - sig.Results().Len() == 1 && - sig.Results().At(0).Type() == types.Typ[types.String] -} - -// isFunctionValue reports whether the expression is a function as opposed to a function call. -// It is almost always a mistake to print a function value. -func isFunctionValue(pass *analysis.Pass, e ast.Expr) bool { - if typ := pass.TypesInfo.Types[e].Type; typ != nil { - // Don't call Underlying: a named func type with a String method is ok. - // TODO(adonovan): it would be more precise to check isStringer. - _, ok := typ.(*types.Signature) - return ok - } - return false -} - -// argCanBeChecked reports whether the specified argument is statically present; -// it may be beyond the list of arguments or in a terminal slice... argument, which -// means we can't see it. -func argCanBeChecked(pass *analysis.Pass, call *ast.CallExpr, formatArg int, state *formatState) bool { - argNum := state.argNums[formatArg] - if argNum <= 0 { - return false - } - if argNum < len(call.Args)-1 { - return true // Always OK. - } - if call.Ellipsis.IsValid() { - return false // We just can't tell; there could be many more arguments. - } - if argNum < len(call.Args) { - return true - } - // There are bad indexes in the format or there are fewer arguments than the format needs. - // This is the argument number relative to the format: Printf("%s", "hi") will give 1 for the "hi". - arg := argNum - state.firstArg + 1 // People think of arguments as 1-indexed. - pass.ReportRangef(call, "%s format %s reads arg #%d, but call has %v", state.name, state.format, arg, count(len(call.Args)-state.firstArg, "arg")) - return false -} - -// count(n, what) returns "1 what" or "N whats" -// (assuming the plural of what is whats). -func count(n int, what string) string { - if n == 1 { - return "1 " + what - } - return fmt.Sprintf("%d %ss", n, what) -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/regexp.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/regexp.go deleted file mode 100644 index d634b74bd8..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/regexp.go +++ /dev/null @@ -1,44 +0,0 @@ -package checkers - -import ( - "go/ast" - - "golang.org/x/tools/go/analysis" -) - -// Regexp detects situations like -// -// assert.Regexp(t, regexp.MustCompile(`\[.*\] DEBUG \(.*TestNew.*\): message`), out) -// assert.NotRegexp(t, regexp.MustCompile(`\[.*\] TRACE message`), out) -// -// and requires -// -// assert.Regexp(t, `\[.*\] DEBUG \(.*TestNew.*\): message`, out) -// assert.NotRegexp(t, `\[.*\] TRACE message`, out) -type Regexp struct{} - -// NewRegexp constructs Regexp checker. -func NewRegexp() Regexp { return Regexp{} } -func (Regexp) Name() string { return "regexp" } - -func (checker Regexp) Check(pass *analysis.Pass, call *CallMeta) *analysis.Diagnostic { - switch call.Fn.NameFTrimmed { - default: - return nil - case "Regexp", "NotRegexp": - } - - if len(call.Args) < 1 { - return nil - } - - ce, ok := call.Args[0].(*ast.CallExpr) - if !ok || len(ce.Args) != 1 { - return nil - } - - if isRegexpMustCompileCall(pass, ce) { - return newRemoveMustCompileDiagnostic(pass, checker.Name(), call, ce, ce.Args[0]) - } - return nil -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/require_error.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/require_error.go deleted file mode 100644 index e965163102..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/require_error.go +++ /dev/null @@ -1,249 +0,0 @@ -package checkers - -import ( - "go/ast" - "regexp" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/ast/inspector" -) - -const requireErrorReport = "for error assertions use require" - -// RequireError detects error assertions like -// -// assert.Error(t, err) // s.Error(err), s.Assert().Error(err) -// assert.ErrorIs(t, err, io.EOF) -// assert.ErrorAs(t, err, &target) -// assert.EqualError(t, err, "end of file") -// assert.ErrorContains(t, err, "end of file") -// assert.NoError(t, err) -// assert.NotErrorIs(t, err, io.EOF) -// -// and requires -// -// require.Error(t, err) // s.Require().Error(err), s.Require().Error(err) -// require.ErrorIs(t, err, io.EOF) -// require.ErrorAs(t, err, &target) -// ... -// -// RequireError ignores: -// - assertions in the `if` condition; -// - assertions in the bool expression; -// - the entire `if-else[-if]` block, if there is an assertion in any `if` condition; -// - the last assertion in the block, if there are no methods/functions calls after it; -// - assertions in an explicit goroutine (including `http.Handler`); -// - assertions in an explicit testing cleanup function or suite teardown methods; -// - sequence of NoError assertions. -type RequireError struct { - fnPattern *regexp.Regexp -} - -// NewRequireError constructs RequireError checker. -func NewRequireError() *RequireError { return new(RequireError) } -func (RequireError) Name() string { return "require-error" } - -func (checker *RequireError) SetFnPattern(p *regexp.Regexp) *RequireError { - if p != nil { - checker.fnPattern = p - } - return checker -} - -func (checker RequireError) Check(pass *analysis.Pass, insp *inspector.Inspector) []analysis.Diagnostic { - callsByFunc := make(map[funcID][]*callMeta) - - // Stage 1. Collect meta information about any calls inside functions. - - insp.WithStack([]ast.Node{(*ast.CallExpr)(nil)}, func(node ast.Node, push bool, stack []ast.Node) bool { - if !push { - return false - } - if len(stack) < 3 { - return true - } - - fID := findSurroundingFunc(pass, stack) - if fID == nil { - return true - } - - _, prevIsIfStmt := stack[len(stack)-2].(*ast.IfStmt) - _, prevIsAssignStmt := stack[len(stack)-2].(*ast.AssignStmt) - _, prevPrevIsIfStmt := stack[len(stack)-3].(*ast.IfStmt) - inIfCond := prevIsIfStmt || (prevPrevIsIfStmt && prevIsAssignStmt) - - _, inBoolExpr := stack[len(stack)-2].(*ast.BinaryExpr) - - callExpr := node.(*ast.CallExpr) - testifyCall := NewCallMeta(pass, callExpr) - - call := &callMeta{ - call: callExpr, - testifyCall: testifyCall, - rootIf: findRootIf(stack), - parentIf: findNearestNode[*ast.IfStmt](stack), - parentBlock: findNearestNode[*ast.BlockStmt](stack), - inIfCond: inIfCond, - inBoolExpr: inBoolExpr, - inNoErrorSeq: false, // Will be filled in below. - } - - callsByFunc[*fID] = append(callsByFunc[*fID], call) - return testifyCall == nil // Do not support asserts in asserts. - }) - - // Stage 2. Analyze calls and block context. - - var diagnostics []analysis.Diagnostic - - callsByBlock := map[*ast.BlockStmt][]*callMeta{} - for _, calls := range callsByFunc { - for _, c := range calls { - if b := c.parentBlock; b != nil { - callsByBlock[b] = append(callsByBlock[b], c) - } - } - } - - markCallsInNoErrorSequence(callsByBlock) - - for funcInfo, calls := range callsByFunc { - for i, c := range calls { - if m := funcInfo.meta; m.isTestCleanup || m.isGoroutine || m.isHTTPHandler { - continue - } - - if c.testifyCall == nil { - continue - } - if !c.testifyCall.IsAssert { - continue - } - switch c.testifyCall.Fn.NameFTrimmed { - default: - continue - case "Error", "ErrorIs", "ErrorAs", "EqualError", "ErrorContains", "NoError", "NotErrorIs": - } - - if needToSkipBasedOnContext(c, i, calls, callsByBlock) { - continue - } - if p := checker.fnPattern; p != nil && !p.MatchString(c.testifyCall.Fn.Name) { - continue - } - - diagnostics = append(diagnostics, - *newDiagnostic(checker.Name(), c.testifyCall, requireErrorReport)) - } - } - - return diagnostics -} - -func needToSkipBasedOnContext( - currCall *callMeta, - currCallIndex int, - otherCalls []*callMeta, - callsByBlock map[*ast.BlockStmt][]*callMeta, -) bool { - if currCall.inIfCond || currCall.inBoolExpr || currCall.inNoErrorSeq { - return true - } - - if currCall.rootIf != nil { - for _, rootCall := range otherCalls { - if (rootCall.rootIf == currCall.rootIf) && rootCall.inIfCond { - // Skip assertions in the entire if-else[-if] block, if some of "if condition" contains assertion. - return true - } - } - } - - block := currCall.parentBlock - blockCalls := callsByBlock[block] - isLastCallInBlock := blockCalls[len(blockCalls)-1] == currCall - - noCallsAfter := true - - _, blockEndWithReturn := block.List[len(block.List)-1].(*ast.ReturnStmt) - if !blockEndWithReturn { - for i := currCallIndex + 1; i < len(otherCalls); i++ { - nextCall := otherCalls[i] - nextCallInElseBlock := false - - if pIf := currCall.parentIf; pIf != nil && pIf.Else != nil { - ast.Inspect(pIf.Else, func(n ast.Node) bool { - if n == nextCall.call { - nextCallInElseBlock = true - return false - } - return true - }) - } - - if !nextCallInElseBlock { - noCallsAfter = false - break - } - } - } - - // Skip assertion if this is the last operation in the test. - return isLastCallInBlock && noCallsAfter -} - -func findRootIf(stack []ast.Node) *ast.IfStmt { - nearestIf, i := findNearestNodeWithIdx[*ast.IfStmt](stack) - for ; i > 0; i-- { - parent, ok := stack[i-1].(*ast.IfStmt) - if !ok { - break - } - nearestIf = parent - } - return nearestIf -} - -func markCallsInNoErrorSequence(callsByBlock map[*ast.BlockStmt][]*callMeta) { - for _, calls := range callsByBlock { - for i, c := range calls { - if c.testifyCall == nil { - continue - } - - var prevIsNoError bool - if i > 0 { - if prev := calls[i-1].testifyCall; prev != nil { - prevIsNoError = isNoErrorAssertion(prev.Fn.Name) - } - } - - var nextIsNoError bool - if i < len(calls)-1 { - if next := calls[i+1].testifyCall; next != nil { - nextIsNoError = isNoErrorAssertion(next.Fn.Name) - } - } - - if isNoErrorAssertion(c.testifyCall.Fn.Name) && (prevIsNoError || nextIsNoError) { - calls[i].inNoErrorSeq = true - } - } - } -} - -type callMeta struct { - call *ast.CallExpr - testifyCall *CallMeta - rootIf *ast.IfStmt // The root `if` in if-else[-if] chain. - parentIf *ast.IfStmt // The nearest `if`, can be equal with rootIf. - parentBlock *ast.BlockStmt - inIfCond bool // True for code like `if assert.ErrorAs(t, err, &target) {`. - inBoolExpr bool // True for code like `assert.Error(t, err) && assert.ErrorContains(t, err, "value")` - inNoErrorSeq bool // True for sequence of `assert.NoError` assertions. -} - -func isNoErrorAssertion(fnName string) bool { - return (fnName == "NoError") || (fnName == "NoErrorf") -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/suite_broken_parallel.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/suite_broken_parallel.go deleted file mode 100644 index 4374c9359b..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/suite_broken_parallel.go +++ /dev/null @@ -1,89 +0,0 @@ -package checkers - -import ( - "fmt" - "go/ast" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/ast/inspector" - - "github.com/Antonboom/testifylint/internal/analysisutil" -) - -// SuiteBrokenParallel detects unsupported t.Parallel() call in suite tests -// -// func (s *MySuite) SetupTest() { -// s.T().Parallel() -// } -// -// // And other hooks... -// -// func (s *MySuite) TestSomething() { -// s.T().Parallel() -// -// for _, tt := range cases { -// s.Run(tt.name, func() { -// s.T().Parallel() -// }) -// -// s.T().Run(tt.name, func(t *testing.T) { -// t.Parallel() -// }) -// } -// } -type SuiteBrokenParallel struct{} - -// NewSuiteBrokenParallel constructs SuiteBrokenParallel checker. -func NewSuiteBrokenParallel() SuiteBrokenParallel { return SuiteBrokenParallel{} } -func (SuiteBrokenParallel) Name() string { return "suite-broken-parallel" } - -func (checker SuiteBrokenParallel) Check(pass *analysis.Pass, insp *inspector.Inspector) (diagnostics []analysis.Diagnostic) { - const report = "testify v1 does not support suite's parallel tests and subtests" - - insp.WithStack([]ast.Node{(*ast.CallExpr)(nil)}, func(node ast.Node, push bool, stack []ast.Node) bool { - if !push { - return false - } - ce := node.(*ast.CallExpr) - - se, ok := ce.Fun.(*ast.SelectorExpr) - if !ok { - return true - } - if !isIdentWithName("Parallel", se.Sel) { - return true - } - if !implementsTestingT(pass, se.X) { - return true - } - - for i := len(stack) - 2; i >= 0; i-- { - fd, ok := stack[i].(*ast.FuncDecl) - if !ok { - continue - } - - if !isSuiteMethod(pass, fd) { - continue - } - - nextLine := pass.Fset.Position(ce.Pos()).Line + 1 - d := newDiagnostic(checker.Name(), ce, report, analysis.SuggestedFix{ - Message: fmt.Sprintf("Remove `%s` call", analysisutil.NodeString(pass.Fset, ce)), - TextEdits: []analysis.TextEdit{ - { - Pos: ce.Pos(), - End: pass.Fset.File(ce.Pos()).LineStart(nextLine), - NewText: []byte(""), - }, - }, - }) - - diagnostics = append(diagnostics, *d) - return false - } - - return true - }) - return diagnostics -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/suite_dont_use_pkg.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/suite_dont_use_pkg.go deleted file mode 100644 index 4fbfbe7e09..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/suite_dont_use_pkg.go +++ /dev/null @@ -1,80 +0,0 @@ -package checkers - -import ( - "fmt" - "go/ast" - - "golang.org/x/tools/go/analysis" -) - -// SuiteDontUsePkg detects situations like -// -// func (s *MySuite) TestSomething() { -// assert.Equal(s.T(), 42, value) -// } -// -// and requires -// -// func (s *MySuite) TestSomething() { -// s.Equal(42, value) -// } -type SuiteDontUsePkg struct{} - -// NewSuiteDontUsePkg constructs SuiteDontUsePkg checker. -func NewSuiteDontUsePkg() SuiteDontUsePkg { return SuiteDontUsePkg{} } -func (SuiteDontUsePkg) Name() string { return "suite-dont-use-pkg" } - -func (checker SuiteDontUsePkg) Check(pass *analysis.Pass, call *CallMeta) *analysis.Diagnostic { - if !call.IsPkg { - return nil - } - - args := call.ArgsRaw - if len(args) < 2 { - return nil - } - t := args[0] - - ce, ok := t.(*ast.CallExpr) - if !ok { - return nil - } - se, ok := ce.Fun.(*ast.SelectorExpr) - if !ok { - return nil - } - if se.X == nil || !implementsTestifySuite(pass, se.X) { - return nil - } - if se.Sel == nil || se.Sel.Name != "T" { - return nil - } - rcv, ok := se.X.(*ast.Ident) // At this point we ensure that `s.T()` is used as the first argument of assertion. - if !ok { - return nil - } - - newSelector := rcv.Name - if !call.IsAssert { - newSelector += "." + "Require()" - } - - msg := fmt.Sprintf("use %s.%s", newSelector, call.Fn.Name) - return newDiagnostic(checker.Name(), call, msg, analysis.SuggestedFix{ - Message: fmt.Sprintf("Replace `%s` with `%s`", call.SelectorXStr, newSelector), - TextEdits: []analysis.TextEdit{ - // Replace package function with suite method. - { - Pos: call.Selector.X.Pos(), - End: call.Selector.X.End(), - NewText: []byte(newSelector), - }, - // Remove `s.T()`. - { - Pos: t.Pos(), - End: args[1].Pos(), - NewText: []byte(""), - }, - }, - }) -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/suite_extra_assert_call.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/suite_extra_assert_call.go deleted file mode 100644 index fdea324fd1..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/suite_extra_assert_call.go +++ /dev/null @@ -1,99 +0,0 @@ -package checkers - -import ( - "fmt" - "go/ast" - - "golang.org/x/tools/go/analysis" - - "github.com/Antonboom/testifylint/internal/analysisutil" -) - -// SuiteExtraAssertCallMode reflects different modes of work of SuiteExtraAssertCall checker. -type SuiteExtraAssertCallMode int - -const ( - SuiteExtraAssertCallModeRemove SuiteExtraAssertCallMode = iota - SuiteExtraAssertCallModeRequire -) - -const DefaultSuiteExtraAssertCallMode = SuiteExtraAssertCallModeRemove - -// SuiteExtraAssertCall detects situations like -// -// func (s *MySuite) TestSomething() { -// s.Assert().Equal(42, value) -// } -// -// and requires -// -// func (s *MySuite) TestSomething() { -// s.Equal(42, value) -// } -// -// or vice versa (depending on the configurable mode). -type SuiteExtraAssertCall struct { - mode SuiteExtraAssertCallMode -} - -// NewSuiteExtraAssertCall constructs SuiteExtraAssertCall checker. -func NewSuiteExtraAssertCall() *SuiteExtraAssertCall { - return &SuiteExtraAssertCall{mode: DefaultSuiteExtraAssertCallMode} -} - -func (SuiteExtraAssertCall) Name() string { return "suite-extra-assert-call" } - -func (checker *SuiteExtraAssertCall) SetMode(m SuiteExtraAssertCallMode) *SuiteExtraAssertCall { - checker.mode = m - return checker -} - -func (checker SuiteExtraAssertCall) Check(pass *analysis.Pass, call *CallMeta) *analysis.Diagnostic { - if call.IsPkg { - return nil - } - - switch checker.mode { - case SuiteExtraAssertCallModeRequire: - x, ok := call.Selector.X.(*ast.Ident) // s.True - if !ok || x == nil || !implementsTestifySuite(pass, x) { - return nil - } - - msg := fmt.Sprintf("use an explicit %s.Assert().%s", analysisutil.NodeString(pass.Fset, x), call.Fn.Name) - return newDiagnostic(checker.Name(), call, msg, analysis.SuggestedFix{ - Message: "Add `Assert()` call", - TextEdits: []analysis.TextEdit{{ - Pos: x.End(), - End: x.End(), // Pure insertion. - NewText: []byte(".Assert()"), - }}, - }) - - case SuiteExtraAssertCallModeRemove: - x, ok := call.Selector.X.(*ast.CallExpr) // s.Assert().True - if !ok { - return nil - } - - se, ok := x.Fun.(*ast.SelectorExpr) - if !ok || se == nil || !implementsTestifySuite(pass, se.X) { - return nil - } - if se.Sel == nil || se.Sel.Name != "Assert" { - return nil - } - - msg := fmt.Sprintf("need to simplify the assertion to %s.%s", analysisutil.NodeString(pass.Fset, se.X), call.Fn.Name) - return newDiagnostic(checker.Name(), call, msg, analysis.SuggestedFix{ - Message: "Remove `Assert()` call", - TextEdits: []analysis.TextEdit{{ - Pos: se.Sel.Pos(), - End: x.End() + 1, // +1 for dot. - NewText: []byte(""), - }}, - }) - } - - return nil -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/suite_method_signature.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/suite_method_signature.go deleted file mode 100644 index 9ceba5db7c..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/suite_method_signature.go +++ /dev/null @@ -1,71 +0,0 @@ -package checkers - -import ( - "fmt" - "go/ast" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/ast/inspector" - - "github.com/Antonboom/testifylint/internal/analysisutil" - "github.com/Antonboom/testifylint/internal/testify" -) - -// SuiteMethodSignature warns, when -// - suite's test methods have arguments or returning values; -// - suite's custom (user) methods conflicts with (shadows/overrides) suite functionality methods. -type SuiteMethodSignature struct{} - -// NewSuiteMethodSignature constructs SuiteMethodSignature checker. -func NewSuiteMethodSignature() SuiteMethodSignature { return SuiteMethodSignature{} } -func (SuiteMethodSignature) Name() string { return "suite-method-signature" } - -func (checker SuiteMethodSignature) Check(pass *analysis.Pass, insp *inspector.Inspector) (diags []analysis.Diagnostic) { - insp.Preorder([]ast.Node{(*ast.FuncDecl)(nil)}, func(node ast.Node) { - fd := node.(*ast.FuncDecl) - if !isSuiteMethod(pass, fd) { - return - } - - methodName := fd.Name.Name - rcv := fd.Recv.List[0] - - if isSuiteTestMethod(methodName) { - if fd.Type.Params.NumFields() > 0 || fd.Type.Results.NumFields() > 0 { - const msg = "test method should not have any arguments or returning values" - diags = append(diags, *newDiagnostic(checker.Name(), fd, msg)) - return - } - } - - iface, ok := suiteMethodToInterface[methodName] - if !ok { - return - } - ifaceObj := analysisutil.ObjectOf(pass.Pkg, testify.SuitePkgPath, iface) - if ifaceObj == nil { - return - } - if !implements(pass, rcv.Type, ifaceObj) { - msg := fmt.Sprintf("method conflicts with %s.%s interface", testify.SuitePkgName, iface) - diags = append(diags, *newDiagnostic(checker.Name(), fd, msg)) - } - }) - return diags -} - -// https://github.com/stretchr/testify/blob/master/suite/interfaces.go -var suiteMethodToInterface = map[string]string{ - // NOTE(a.telyshev): We ignore suite.TestingSuite interface, because - // - suite.Run will not work for suite-types that do not implement it; - // - this interface has several methods, which may cause a false positive for one of the methods in the suite-type. - "SetupSuite": "SetupAllSuite", - "SetupTest": "SetupTestSuite", - "TearDownSuite": "TearDownAllSuite", - "TearDownTest": "TearDownTestSuite", - "BeforeTest": "BeforeTest", - "AfterTest": "AfterTest", - "HandleStats": "WithStats", - "SetupSubTest": "SetupSubTest", - "TearDownSubTest": "TearDownSubTest", -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/suite_subtest_run.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/suite_subtest_run.go deleted file mode 100644 index 525d5ffd86..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/suite_subtest_run.go +++ /dev/null @@ -1,60 +0,0 @@ -package checkers - -import ( - "fmt" - "go/ast" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/ast/inspector" - - "github.com/Antonboom/testifylint/internal/analysisutil" -) - -// SuiteSubtestRun detects situations like -// -// s.T().Run("subtest", func(t *testing.T) { -// assert.Equal(t, 42, result) -// }) -// -// and requires -// -// s.Run("subtest", func() { -// s.Equal(42, result) -// }) -type SuiteSubtestRun struct{} - -// NewSuiteSubtestRun constructs SuiteSubtestRun checker. -func NewSuiteSubtestRun() SuiteSubtestRun { return SuiteSubtestRun{} } -func (SuiteSubtestRun) Name() string { return "suite-subtest-run" } - -func (checker SuiteSubtestRun) Check(pass *analysis.Pass, insp *inspector.Inspector) (diagnostics []analysis.Diagnostic) { - insp.Preorder([]ast.Node{(*ast.CallExpr)(nil)}, func(node ast.Node) { - ce := node.(*ast.CallExpr) // s.T().Run - - se, ok := ce.Fun.(*ast.SelectorExpr) // s.T() + .Run - if !ok { - return - } - if !isIdentWithName("Run", se.Sel) { - return - } - - tCall, ok := se.X.(*ast.CallExpr) // s.T() - if !ok { - return - } - tCallSel, ok := tCall.Fun.(*ast.SelectorExpr) // s + .T() - if !ok { - return - } - if !isIdentWithName("T", tCallSel.Sel) { - return - } - - if implementsTestifySuite(pass, tCallSel.X) && implementsTestingT(pass, tCall) { - msg := fmt.Sprintf("use %s.Run to run subtest", analysisutil.NodeString(pass.Fset, tCallSel.X)) - diagnostics = append(diagnostics, *newDiagnostic(checker.Name(), ce, msg)) - } - }) - return diagnostics -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/suite_thelper.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/suite_thelper.go deleted file mode 100644 index 074de4f764..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/suite_thelper.go +++ /dev/null @@ -1,67 +0,0 @@ -package checkers - -import ( - "fmt" - "go/ast" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/ast/inspector" - - "github.com/Antonboom/testifylint/internal/analysisutil" -) - -// SuiteTHelper requires t.Helper() call in suite helpers: -// -// func (s *RoomSuite) assertRoomRound(roundID RoundID) { -// s.T().Helper() -// s.Equal(roundID, s.getRoom().CurrentRound.ID) -// } -type SuiteTHelper struct{} - -// NewSuiteTHelper constructs SuiteTHelper checker. -func NewSuiteTHelper() SuiteTHelper { return SuiteTHelper{} } -func (SuiteTHelper) Name() string { return "suite-thelper" } - -func (checker SuiteTHelper) Check(pass *analysis.Pass, insp *inspector.Inspector) (diagnostics []analysis.Diagnostic) { - insp.Preorder([]ast.Node{(*ast.FuncDecl)(nil)}, func(node ast.Node) { - fd := node.(*ast.FuncDecl) - if !isSuiteMethod(pass, fd) { - return - } - - if ident := fd.Name; ident == nil || isSuiteTestMethod(ident.Name) || isSuiteServiceMethod(ident.Name) { - return - } - - if !fnContainsAssertions(pass, fd) { - return - } - - rcv := fd.Recv.List[0] - if len(rcv.Names) != 1 || rcv.Names[0] == nil { - return - } - rcvName := rcv.Names[0].Name - - helperCallStr := rcvName + ".T().Helper()" - - firstStmt := fd.Body.List[0] - if analysisutil.NodeString(pass.Fset, firstStmt) == helperCallStr { - return - } - - msg := "suite helper method must start with " + helperCallStr - d := newDiagnostic(checker.Name(), fd, msg, analysis.SuggestedFix{ - Message: fmt.Sprintf("Insert `%s`", helperCallStr), - TextEdits: []analysis.TextEdit{ - { - Pos: firstStmt.Pos(), - End: firstStmt.Pos(), // Pure insertion. - NewText: []byte(helperCallStr + "\n\n"), - }, - }, - }) - diagnostics = append(diagnostics, *d) - }) - return diagnostics -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/checkers/useless_assert.go b/vendor/github.com/Antonboom/testifylint/internal/checkers/useless_assert.go deleted file mode 100644 index 15de9c6c59..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/checkers/useless_assert.go +++ /dev/null @@ -1,196 +0,0 @@ -package checkers - -import ( - "go/ast" - - "golang.org/x/tools/go/analysis" - - "github.com/Antonboom/testifylint/internal/analysisutil" -) - -// UselessAssert detects useless asserts like -// -// assert.Contains(t, tt.value, tt.value) -// assert.ElementsMatch(t, tt.value, tt.value) -// assert.Equal(t, tt.value, tt.value) -// assert.EqualExportedValues(t, tt.value, tt.value) -// ... -// -// assert.True(t, num > num) -// assert.True(t, num < num) -// assert.True(t, num >= num) -// assert.True(t, num <= num) -// assert.True(t, num == num) -// assert.True(t, num != num) -// -// assert.False(t, num > num) -// assert.False(t, num < num) -// assert.False(t, num >= num) -// assert.False(t, num <= num) -// assert.False(t, num == num) -// assert.False(t, num != num) -// -// assert.Empty(t, "value") // Any string literal. -// assert.Error(t, nil) -// assert.False(t, false) // Any bool literal. -// assert.Implements(t, (*any)(nil), new(Conn)) -// assert.Negative(t, 42) // Any int literal. -// assert.Nil(t, nil) -// assert.NoError(t, nil) -// assert.NotEmpty(t, "value") // Any string literal. -// assert.NotImplements(t, (*any)(nil), new(Conn)) -// assert.NotNil(t, nil) -// assert.NotZero(t, 42) // Any int literal. -// assert.NotZero(t, "value") // Any string literal. -// assert.NotZero(t, nil) -// assert.NotZero(t, false) // Any bool literal. -// assert.Positive(t, 42) // Any int literal. -// assert.True(t, true) // Any bool literal. -// assert.Zero(t, 42) // Any int literal. -// assert.Zero(t, "value") // Any string literal. -// assert.Zero(t, nil) -// assert.Zero(t, false) // Any bool literal. -// -// assert.Negative(len(x)) -// assert.Less(len(x), 0) -// assert.Greater(0, len(x)) -// assert.GreaterOrEqual(len(x), 0) -// assert.LessOrEqual(0, len(x)) -// -// assert.Negative(uintVal) -// assert.Less(uintVal, 0) -// assert.Greater(0, uintVal) -// assert.GreaterOrEqual(uintVal, 0) -// assert.LessOrEqual(0, uintVal) -type UselessAssert struct{} - -// NewUselessAssert constructs UselessAssert checker. -func NewUselessAssert() UselessAssert { return UselessAssert{} } -func (UselessAssert) Name() string { return "useless-assert" } - -func (checker UselessAssert) Check(pass *analysis.Pass, call *CallMeta) *analysis.Diagnostic { - if d := checker.checkSameVars(pass, call); d != nil { - return d - } - - var isMeaningless bool - switch call.Fn.NameFTrimmed { - case "False", "True": - isMeaningless = (len(call.Args) >= 1) && isUntypedBool(pass, call.Args[0]) - - case "GreaterOrEqual", "Less": - isMeaningless = (len(call.Args) >= 2) && isAnyZero(call.Args[1]) && canNotBeNegative(pass, call.Args[0]) - - case "Implements", "NotImplements": - if len(call.Args) < 2 { - return nil - } - - elem, ok := isPointer(pass, call.Args[0]) - isMeaningless = ok && isEmptyInterfaceType(elem) - - case "LessOrEqual", "Greater": - isMeaningless = (len(call.Args) >= 2) && isAnyZero(call.Args[0]) && canNotBeNegative(pass, call.Args[1]) - - case "Positive": - if len(call.Args) < 1 { - return nil - } - _, isMeaningless = isIntBasicLit(call.Args[0]) - - case "Negative": - if len(call.Args) < 1 { - return nil - } - _, isInt := isIntBasicLit(call.Args[0]) - isMeaningless = isInt || canNotBeNegative(pass, call.Args[0]) - - case "Error", "Nil", "NoError", "NotNil": - isMeaningless = (len(call.Args) >= 1) && isNil(call.Args[0]) - - case "Empty", "NotEmpty": - isMeaningless = (len(call.Args) >= 1) && isStringLit(call.Args[0]) - - case "NotZero", "Zero": - if len(call.Args) < 1 { - return nil - } - _, isInt := isIntBasicLit(call.Args[0]) - isMeaningless = isInt || isStringLit(call.Args[0]) || isNil(call.Args[0]) || isUntypedBool(pass, call.Args[0]) - } - - if isMeaningless { - return newDiagnostic(checker.Name(), call, "meaningless assertion") - } - return nil -} - -func (checker UselessAssert) checkSameVars(pass *analysis.Pass, call *CallMeta) *analysis.Diagnostic { - var first, second ast.Node - - switch call.Fn.NameFTrimmed { - case - "Contains", - "ElementsMatch", - "Equal", - "EqualExportedValues", - "EqualValues", - "ErrorAs", - "ErrorIs", - "Exactly", - "Greater", - "GreaterOrEqual", - "Implements", - "InDelta", - "InDeltaMapValues", - "InDeltaSlice", - "InEpsilon", - "InEpsilonSlice", - "IsNotType", - "IsType", - "JSONEq", - "Less", - "LessOrEqual", - "NotElementsMatch", - "NotEqual", - "NotEqualValues", - "NotErrorAs", - "NotErrorIs", - "NotRegexp", - "NotSame", - "NotSubset", - "Regexp", - "Same", - "Subset", - "WithinDuration", - "YAMLEq": - if len(call.Args) < 2 { - return nil - } - first, second = call.Args[0], call.Args[1] - - case "True", "False": - if len(call.Args) < 1 { - return nil - } - - be, ok := call.Args[0].(*ast.BinaryExpr) - if !ok { - return nil - } - first, second = be.X, be.Y - - default: - return nil - } - - if analysisutil.NodeString(pass.Fset, first) == analysisutil.NodeString(pass.Fset, second) { - return newDiagnostic(checker.Name(), call, "asserting of the same variable") - } - return nil -} - -func canNotBeNegative(pass *analysis.Pass, e ast.Expr) bool { - _, isLen := isBuiltinLenCall(pass, e) - return isLen || isUnsigned(pass, e) -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/config/config.go b/vendor/github.com/Antonboom/testifylint/internal/config/config.go deleted file mode 100644 index 7b25878764..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/config/config.go +++ /dev/null @@ -1,159 +0,0 @@ -package config - -import ( - "errors" - "flag" - "fmt" - - "github.com/Antonboom/testifylint/internal/checkers" -) - -// NewDefault builds default testifylint config. -func NewDefault() Config { - return Config{ - EnableAll: false, - DisabledCheckers: nil, - DisableAll: false, - EnabledCheckers: nil, - BoolCompare: BoolCompareConfig{ - IgnoreCustomTypes: false, - }, - ExpectedActual: ExpectedActualConfig{ - ExpVarPattern: RegexpValue{checkers.DefaultExpectedVarPattern}, - }, - Formatter: FormatterConfig{ - CheckFormatString: true, - RequireFFuncs: false, - RequireStringMsg: true, - }, - GoRequire: GoRequireConfig{ - IgnoreHTTPHandlers: false, - }, - RequireError: RequireErrorConfig{ - FnPattern: RegexpValue{nil}, - }, - SuiteExtraAssertCall: SuiteExtraAssertCallConfig{ - Mode: checkers.DefaultSuiteExtraAssertCallMode, - }, - } -} - -// Config implements testifylint configuration. -type Config struct { - EnableAll bool - DisabledCheckers KnownCheckersValue - DisableAll bool - EnabledCheckers KnownCheckersValue - - BoolCompare BoolCompareConfig - ExpectedActual ExpectedActualConfig - Formatter FormatterConfig - GoRequire GoRequireConfig - RequireError RequireErrorConfig - SuiteExtraAssertCall SuiteExtraAssertCallConfig -} - -// BoolCompareConfig implements configuration of checkers.BoolCompare. -type BoolCompareConfig struct { - IgnoreCustomTypes bool -} - -// ExpectedActualConfig implements configuration of checkers.ExpectedActual. -type ExpectedActualConfig struct { - ExpVarPattern RegexpValue -} - -// FormatterConfig implements configuration of checkers.Formatter. -type FormatterConfig struct { - CheckFormatString bool - RequireFFuncs bool - RequireStringMsg bool -} - -// GoRequireConfig implements configuration of checkers.GoRequire. -type GoRequireConfig struct { - IgnoreHTTPHandlers bool -} - -// RequireErrorConfig implements configuration of checkers.RequireError. -type RequireErrorConfig struct { - FnPattern RegexpValue -} - -// SuiteExtraAssertCallConfig implements configuration of checkers.SuiteExtraAssertCall. -type SuiteExtraAssertCallConfig struct { - Mode checkers.SuiteExtraAssertCallMode -} - -func (cfg Config) Validate() error { - if cfg.EnableAll { - if cfg.DisableAll { - return errors.New("enable-all and disable-all options must not be combined") - } - - if len(cfg.EnabledCheckers) != 0 { - return errors.New("enable-all and enable options must not be combined") - } - } - - if cfg.DisableAll { - if len(cfg.DisabledCheckers) != 0 { - return errors.New("disable-all and disable options must not be combined") - } - - if len(cfg.EnabledCheckers) == 0 { - return errors.New("all checkers were disabled, but no one checker was enabled: at least one must be enabled") - } - } - - for _, checker := range cfg.DisabledCheckers { - if cfg.EnabledCheckers.Contains(checker) { - return fmt.Errorf("checker %q disabled and enabled at one moment", checker) - } - } - - return nil -} - -// BindToFlags binds Config fields to according flags. -func BindToFlags(cfg *Config, fs *flag.FlagSet) { - fs.BoolVar(&cfg.EnableAll, "enable-all", false, "enable all checkers") - fs.Var(&cfg.DisabledCheckers, "disable", "comma separated list of disabled checkers (to exclude from enabled by default)") - fs.BoolVar(&cfg.DisableAll, "disable-all", false, "disable all checkers") - fs.Var(&cfg.EnabledCheckers, "enable", "comma separated list of enabled checkers (in addition to enabled by default)") - - fs.BoolVar(&cfg.BoolCompare.IgnoreCustomTypes, - "bool-compare.ignore-custom-types", false, - "to ignore user defined types (over builtin bool)") - - fs.Var(&cfg.ExpectedActual.ExpVarPattern, - "expected-actual.pattern", - "regexp for expected variable name") - - fs.BoolVar(&cfg.Formatter.CheckFormatString, - "formatter.check-format-string", true, - "to enable go vet's printf checks") - fs.BoolVar(&cfg.Formatter.RequireFFuncs, - "formatter.require-f-funcs", false, - "to require f-assertions (e.g. assert.Equalf) if format string is used, even if there are no variable-length variables") - fs.BoolVar(&cfg.Formatter.RequireStringMsg, - "formatter.require-string-msg", true, - "to require that the first element of msgAndArgs (msg) has a string type") - - fs.BoolVar(&cfg.GoRequire.IgnoreHTTPHandlers, - "go-require.ignore-http-handlers", false, - "to ignore HTTP handlers (like http.HandlerFunc)") - - fs.Var(&cfg.RequireError.FnPattern, - "require-error.fn-pattern", - "regexp for error assertions that should only be analyzed") - - fs.Var(NewEnumValue(suiteExtraAssertCallModeAsString, &cfg.SuiteExtraAssertCall.Mode), - "suite-extra-assert-call.mode", - "to require or remove extra Assert() call") -} - -var suiteExtraAssertCallModeAsString = map[string]checkers.SuiteExtraAssertCallMode{ - "remove": checkers.SuiteExtraAssertCallModeRemove, - "require": checkers.SuiteExtraAssertCallModeRequire, -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/config/flag_value_types.go b/vendor/github.com/Antonboom/testifylint/internal/config/flag_value_types.go deleted file mode 100644 index 5b08ec47b1..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/config/flag_value_types.go +++ /dev/null @@ -1,114 +0,0 @@ -package config - -import ( - "flag" - "fmt" - "regexp" - "sort" - "strings" - - "github.com/Antonboom/testifylint/internal/checkers" -) - -var ( - _ flag.Value = (*KnownCheckersValue)(nil) - _ flag.Value = (*RegexpValue)(nil) - _ flag.Value = (*EnumValue[checkers.SuiteExtraAssertCallMode])(nil) -) - -// KnownCheckersValue implements comma separated list of testify checkers. -type KnownCheckersValue []string - -func (kcv KnownCheckersValue) String() string { - return strings.Join(kcv, ",") -} - -func (kcv *KnownCheckersValue) Set(v string) error { - chckrs := strings.Split(v, ",") - for _, checkerName := range chckrs { - if ok := checkers.IsKnown(checkerName); !ok { - return fmt.Errorf("unknown checker %q", checkerName) - } - } - - *kcv = chckrs - return nil -} - -func (kcv KnownCheckersValue) Contains(v string) bool { - for _, checker := range kcv { - if checker == v { - return true - } - } - return false -} - -// RegexpValue is a special wrapper for support of flag.FlagSet over regexp.Regexp. -// Original regexp is available through RegexpValue.Regexp. -type RegexpValue struct { - *regexp.Regexp -} - -func (rv RegexpValue) String() string { - if rv.Regexp == nil { - return "" - } - return rv.Regexp.String() -} - -func (rv *RegexpValue) Set(v string) error { - compiled, err := regexp.Compile(v) - if err != nil { - return err - } - - rv.Regexp = compiled - return nil -} - -// EnumValue is a special type for support of flag.FlagSet over user-defined constants. -type EnumValue[EnumT comparable] struct { - mapping map[string]EnumT - keys []string - dst *EnumT -} - -// NewEnumValue takes the "enum-value-name to enum-value" mapping and a destination for the value passed through the CLI. -// Returns an EnumValue instance suitable for flag.FlagSet.Var. -func NewEnumValue[EnumT comparable](mapping map[string]EnumT, dst *EnumT) *EnumValue[EnumT] { - keys := make([]string, 0, len(mapping)) - for k := range mapping { - keys = append(keys, k) - } - sort.Strings(keys) - - return &EnumValue[EnumT]{ - mapping: mapping, - keys: keys, - dst: dst, - } -} - -func (e EnumValue[EnumT]) String() string { - if e.dst == nil { - return "" - } - - for k, v := range e.mapping { - if v == *e.dst { - return k - } - } - return "" -} - -func (e *EnumValue[EnumT]) Set(s string) error { - v, ok := e.mapping[s] - if !ok { - return fmt.Errorf("use one of (%v)", strings.Join(e.keys, " | ")) - } - - *e.dst = v - return nil -} diff --git a/vendor/github.com/Antonboom/testifylint/internal/testify/const.go b/vendor/github.com/Antonboom/testifylint/internal/testify/const.go deleted file mode 100644 index 3476e40402..0000000000 --- a/vendor/github.com/Antonboom/testifylint/internal/testify/const.go +++ /dev/null @@ -1,17 +0,0 @@ -package testify - -const ( - ModulePath = "github.com/stretchr/testify" - - AssertPkgName = "assert" - HTTPPkgName = "http" - MockPkgName = "mock" - RequirePkgName = "require" - SuitePkgName = "suite" - - AssertPkgPath = ModulePath + "/" + AssertPkgName - HTTPPkgPath = ModulePath + "/" + HTTPPkgName - MockPkgPath = ModulePath + "/" + MockPkgName - RequirePkgPath = ModulePath + "/" + RequirePkgName - SuitePkgPath = ModulePath + "/" + SuitePkgName -) diff --git a/vendor/github.com/BurntSushi/toml/.gitignore b/vendor/github.com/BurntSushi/toml/.gitignore deleted file mode 100644 index fe79e3adda..0000000000 --- a/vendor/github.com/BurntSushi/toml/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/toml.test -/toml-test diff --git a/vendor/github.com/BurntSushi/toml/COPYING b/vendor/github.com/BurntSushi/toml/COPYING deleted file mode 100644 index 01b5743200..0000000000 --- a/vendor/github.com/BurntSushi/toml/COPYING +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2013 TOML authors - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/vendor/github.com/BurntSushi/toml/README.md b/vendor/github.com/BurntSushi/toml/README.md deleted file mode 100644 index 235496eeb2..0000000000 --- a/vendor/github.com/BurntSushi/toml/README.md +++ /dev/null @@ -1,120 +0,0 @@ -TOML stands for Tom's Obvious, Minimal Language. This Go package provides a -reflection interface similar to Go's standard library `json` and `xml` packages. - -Compatible with TOML version [v1.0.0](https://toml.io/en/v1.0.0). - -Documentation: https://pkg.go.dev/github.com/BurntSushi/toml - -See the [releases page](https://github.com/BurntSushi/toml/releases) for a -changelog; this information is also in the git tag annotations (e.g. `git show -v0.4.0`). - -This library requires Go 1.18 or newer; add it to your go.mod with: - - % go get github.com/BurntSushi/toml@latest - -It also comes with a TOML validator CLI tool: - - % go install github.com/BurntSushi/toml/cmd/tomlv@latest - % tomlv some-toml-file.toml - -### Examples -For the simplest example, consider some TOML file as just a list of keys and -values: - -```toml -Age = 25 -Cats = [ "Cauchy", "Plato" ] -Pi = 3.14 -Perfection = [ 6, 28, 496, 8128 ] -DOB = 1987-07-05T05:45:00Z -``` - -Which can be decoded with: - -```go -type Config struct { - Age int - Cats []string - Pi float64 - Perfection []int - DOB time.Time -} - -var conf Config -_, err := toml.Decode(tomlData, &conf) -``` - -You can also use struct tags if your struct field name doesn't map to a TOML key -value directly: - -```toml -some_key_NAME = "wat" -``` - -```go -type TOML struct { - ObscureKey string `toml:"some_key_NAME"` -} -``` - -Beware that like other decoders **only exported fields** are considered when -encoding and decoding; private fields are silently ignored. - -### Using the `Marshaler` and `encoding.TextUnmarshaler` interfaces -Here's an example that automatically parses values in a `mail.Address`: - -```toml -contacts = [ - "Donald Duck ", - "Scrooge McDuck ", -] -``` - -Can be decoded with: - -```go -// Create address type which satisfies the encoding.TextUnmarshaler interface. -type address struct { - *mail.Address -} - -func (a *address) UnmarshalText(text []byte) error { - var err error - a.Address, err = mail.ParseAddress(string(text)) - return err -} - -// Decode it. -func decode() { - blob := ` - contacts = [ - "Donald Duck ", - "Scrooge McDuck ", - ] - ` - - var contacts struct { - Contacts []address - } - - _, err := toml.Decode(blob, &contacts) - if err != nil { - log.Fatal(err) - } - - for _, c := range contacts.Contacts { - fmt.Printf("%#v\n", c.Address) - } - - // Output: - // &mail.Address{Name:"Donald Duck", Address:"donald@duckburg.com"} - // &mail.Address{Name:"Scrooge McDuck", Address:"scrooge@duckburg.com"} -} -``` - -To target TOML specifically you can implement `UnmarshalTOML` TOML interface in -a similar way. - -### More complex usage -See the [`_example/`](/_example) directory for a more complex example. diff --git a/vendor/github.com/BurntSushi/toml/decode.go b/vendor/github.com/BurntSushi/toml/decode.go deleted file mode 100644 index 3fa516caa2..0000000000 --- a/vendor/github.com/BurntSushi/toml/decode.go +++ /dev/null @@ -1,638 +0,0 @@ -package toml - -import ( - "bytes" - "encoding" - "encoding/json" - "fmt" - "io" - "io/fs" - "math" - "os" - "reflect" - "strconv" - "strings" - "time" -) - -// Unmarshaler is the interface implemented by objects that can unmarshal a -// TOML description of themselves. -type Unmarshaler interface { - UnmarshalTOML(any) error -} - -// Unmarshal decodes the contents of data in TOML format into a pointer v. -// -// See [Decoder] for a description of the decoding process. -func Unmarshal(data []byte, v any) error { - _, err := NewDecoder(bytes.NewReader(data)).Decode(v) - return err -} - -// Decode the TOML data in to the pointer v. -// -// See [Decoder] for a description of the decoding process. -func Decode(data string, v any) (MetaData, error) { - return NewDecoder(strings.NewReader(data)).Decode(v) -} - -// DecodeFile reads the contents of a file and decodes it with [Decode]. -func DecodeFile(path string, v any) (MetaData, error) { - fp, err := os.Open(path) - if err != nil { - return MetaData{}, err - } - defer fp.Close() - return NewDecoder(fp).Decode(v) -} - -// DecodeFS reads the contents of a file from [fs.FS] and decodes it with -// [Decode]. -func DecodeFS(fsys fs.FS, path string, v any) (MetaData, error) { - fp, err := fsys.Open(path) - if err != nil { - return MetaData{}, err - } - defer fp.Close() - return NewDecoder(fp).Decode(v) -} - -// Primitive is a TOML value that hasn't been decoded into a Go value. -// -// This type can be used for any value, which will cause decoding to be delayed. -// You can use [PrimitiveDecode] to "manually" decode these values. -// -// NOTE: The underlying representation of a `Primitive` value is subject to -// change. Do not rely on it. -// -// NOTE: Primitive values are still parsed, so using them will only avoid the -// overhead of reflection. They can be useful when you don't know the exact type -// of TOML data until runtime. -type Primitive struct { - undecoded any - context Key -} - -// The significand precision for float32 and float64 is 24 and 53 bits; this is -// the range a natural number can be stored in a float without loss of data. -const ( - maxSafeFloat32Int = 16777215 // 2^24-1 - maxSafeFloat64Int = int64(9007199254740991) // 2^53-1 -) - -// Decoder decodes TOML data. -// -// TOML tables correspond to Go structs or maps; they can be used -// interchangeably, but structs offer better type safety. -// -// TOML table arrays correspond to either a slice of structs or a slice of maps. -// -// TOML datetimes correspond to [time.Time]. Local datetimes are parsed in the -// local timezone. -// -// [time.Duration] types are treated as nanoseconds if the TOML value is an -// integer, or they're parsed with time.ParseDuration() if they're strings. -// -// All other TOML types (float, string, int, bool and array) correspond to the -// obvious Go types. -// -// An exception to the above rules is if a type implements the TextUnmarshaler -// interface, in which case any primitive TOML value (floats, strings, integers, -// booleans, datetimes) will be converted to a []byte and given to the value's -// UnmarshalText method. See the Unmarshaler example for a demonstration with -// email addresses. -// -// # Key mapping -// -// TOML keys can map to either keys in a Go map or field names in a Go struct. -// The special `toml` struct tag can be used to map TOML keys to struct fields -// that don't match the key name exactly (see the example). A case insensitive -// match to struct names will be tried if an exact match can't be found. -// -// The mapping between TOML values and Go values is loose. That is, there may -// exist TOML values that cannot be placed into your representation, and there -// may be parts of your representation that do not correspond to TOML values. -// This loose mapping can be made stricter by using the IsDefined and/or -// Undecoded methods on the MetaData returned. -// -// This decoder does not handle cyclic types. Decode will not terminate if a -// cyclic type is passed. -type Decoder struct { - r io.Reader -} - -// NewDecoder creates a new Decoder. -func NewDecoder(r io.Reader) *Decoder { - return &Decoder{r: r} -} - -var ( - unmarshalToml = reflect.TypeOf((*Unmarshaler)(nil)).Elem() - unmarshalText = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem() - primitiveType = reflect.TypeOf((*Primitive)(nil)).Elem() -) - -// Decode TOML data in to the pointer `v`. -func (dec *Decoder) Decode(v any) (MetaData, error) { - rv := reflect.ValueOf(v) - if rv.Kind() != reflect.Ptr { - s := "%q" - if reflect.TypeOf(v) == nil { - s = "%v" - } - - return MetaData{}, fmt.Errorf("toml: cannot decode to non-pointer "+s, reflect.TypeOf(v)) - } - if rv.IsNil() { - return MetaData{}, fmt.Errorf("toml: cannot decode to nil value of %q", reflect.TypeOf(v)) - } - - // Check if this is a supported type: struct, map, any, or something that - // implements UnmarshalTOML or UnmarshalText. - rv = indirect(rv) - rt := rv.Type() - if rv.Kind() != reflect.Struct && rv.Kind() != reflect.Map && - !(rv.Kind() == reflect.Interface && rv.NumMethod() == 0) && - !rt.Implements(unmarshalToml) && !rt.Implements(unmarshalText) { - return MetaData{}, fmt.Errorf("toml: cannot decode to type %s", rt) - } - - // TODO: parser should read from io.Reader? Or at the very least, make it - // read from []byte rather than string - data, err := io.ReadAll(dec.r) - if err != nil { - return MetaData{}, err - } - - p, err := parse(string(data)) - if err != nil { - return MetaData{}, err - } - - md := MetaData{ - mapping: p.mapping, - keyInfo: p.keyInfo, - keys: p.ordered, - decoded: make(map[string]struct{}, len(p.ordered)), - context: nil, - data: data, - } - return md, md.unify(p.mapping, rv) -} - -// PrimitiveDecode is just like the other Decode* functions, except it decodes a -// TOML value that has already been parsed. Valid primitive values can *only* be -// obtained from values filled by the decoder functions, including this method. -// (i.e., v may contain more [Primitive] values.) -// -// Meta data for primitive values is included in the meta data returned by the -// Decode* functions with one exception: keys returned by the Undecoded method -// will only reflect keys that were decoded. Namely, any keys hidden behind a -// Primitive will be considered undecoded. Executing this method will update the -// undecoded keys in the meta data. (See the example.) -func (md *MetaData) PrimitiveDecode(primValue Primitive, v any) error { - md.context = primValue.context - defer func() { md.context = nil }() - return md.unify(primValue.undecoded, rvalue(v)) -} - -// markDecodedRecursive is a helper to mark any key under the given tmap as -// decoded, recursing as needed -func markDecodedRecursive(md *MetaData, tmap map[string]any) { - for key := range tmap { - md.decoded[md.context.add(key).String()] = struct{}{} - if tmap, ok := tmap[key].(map[string]any); ok { - md.context = append(md.context, key) - markDecodedRecursive(md, tmap) - md.context = md.context[0 : len(md.context)-1] - } - } -} - -// unify performs a sort of type unification based on the structure of `rv`, -// which is the client representation. -// -// Any type mismatch produces an error. Finding a type that we don't know -// how to handle produces an unsupported type error. -func (md *MetaData) unify(data any, rv reflect.Value) error { - // Special case. Look for a `Primitive` value. - // TODO: #76 would make this superfluous after implemented. - if rv.Type() == primitiveType { - // Save the undecoded data and the key context into the primitive - // value. - context := make(Key, len(md.context)) - copy(context, md.context) - rv.Set(reflect.ValueOf(Primitive{ - undecoded: data, - context: context, - })) - return nil - } - - rvi := rv.Interface() - if v, ok := rvi.(Unmarshaler); ok { - err := v.UnmarshalTOML(data) - if err != nil { - return md.parseErr(err) - } - // Assume the Unmarshaler decoded everything, so mark all keys under - // this table as decoded. - if tmap, ok := data.(map[string]any); ok { - markDecodedRecursive(md, tmap) - } - if aot, ok := data.([]map[string]any); ok { - for _, tmap := range aot { - markDecodedRecursive(md, tmap) - } - } - return nil - } - if v, ok := rvi.(encoding.TextUnmarshaler); ok { - return md.unifyText(data, v) - } - - // TODO: - // The behavior here is incorrect whenever a Go type satisfies the - // encoding.TextUnmarshaler interface but also corresponds to a TOML hash or - // array. In particular, the unmarshaler should only be applied to primitive - // TOML values. But at this point, it will be applied to all kinds of values - // and produce an incorrect error whenever those values are hashes or arrays - // (including arrays of tables). - - k := rv.Kind() - - if k >= reflect.Int && k <= reflect.Uint64 { - return md.unifyInt(data, rv) - } - switch k { - case reflect.Struct: - return md.unifyStruct(data, rv) - case reflect.Map: - return md.unifyMap(data, rv) - case reflect.Array: - return md.unifyArray(data, rv) - case reflect.Slice: - return md.unifySlice(data, rv) - case reflect.String: - return md.unifyString(data, rv) - case reflect.Bool: - return md.unifyBool(data, rv) - case reflect.Interface: - if rv.NumMethod() > 0 { /// Only empty interfaces are supported. - return md.e("unsupported type %s", rv.Type()) - } - return md.unifyAnything(data, rv) - case reflect.Float32, reflect.Float64: - return md.unifyFloat64(data, rv) - } - return md.e("unsupported type %s", rv.Kind()) -} - -func (md *MetaData) unifyStruct(mapping any, rv reflect.Value) error { - tmap, ok := mapping.(map[string]any) - if !ok { - if mapping == nil { - return nil - } - return md.e("type mismatch for %s: expected table but found %s", rv.Type().String(), fmtType(mapping)) - } - - for key, datum := range tmap { - var f *field - fields := cachedTypeFields(rv.Type()) - for i := range fields { - ff := &fields[i] - if ff.name == key { - f = ff - break - } - if f == nil && strings.EqualFold(ff.name, key) { - f = ff - } - } - if f != nil { - subv := rv - for _, i := range f.index { - subv = indirect(subv.Field(i)) - } - - if isUnifiable(subv) { - md.decoded[md.context.add(key).String()] = struct{}{} - md.context = append(md.context, key) - - err := md.unify(datum, subv) - if err != nil { - return err - } - md.context = md.context[0 : len(md.context)-1] - } else if f.name != "" { - return md.e("cannot write unexported field %s.%s", rv.Type().String(), f.name) - } - } - } - return nil -} - -func (md *MetaData) unifyMap(mapping any, rv reflect.Value) error { - keyType := rv.Type().Key().Kind() - if keyType != reflect.String && keyType != reflect.Interface { - return fmt.Errorf("toml: cannot decode to a map with non-string key type (%s in %q)", - keyType, rv.Type()) - } - - tmap, ok := mapping.(map[string]any) - if !ok { - if tmap == nil { - return nil - } - return md.badtype("map", mapping) - } - if rv.IsNil() { - rv.Set(reflect.MakeMap(rv.Type())) - } - for k, v := range tmap { - md.decoded[md.context.add(k).String()] = struct{}{} - md.context = append(md.context, k) - - rvval := reflect.Indirect(reflect.New(rv.Type().Elem())) - - err := md.unify(v, indirect(rvval)) - if err != nil { - return err - } - md.context = md.context[0 : len(md.context)-1] - - rvkey := indirect(reflect.New(rv.Type().Key())) - - switch keyType { - case reflect.Interface: - rvkey.Set(reflect.ValueOf(k)) - case reflect.String: - rvkey.SetString(k) - } - - rv.SetMapIndex(rvkey, rvval) - } - return nil -} - -func (md *MetaData) unifyArray(data any, rv reflect.Value) error { - datav := reflect.ValueOf(data) - if datav.Kind() != reflect.Slice { - if !datav.IsValid() { - return nil - } - return md.badtype("slice", data) - } - if l := datav.Len(); l != rv.Len() { - return md.e("expected array length %d; got TOML array of length %d", rv.Len(), l) - } - return md.unifySliceArray(datav, rv) -} - -func (md *MetaData) unifySlice(data any, rv reflect.Value) error { - datav := reflect.ValueOf(data) - if datav.Kind() != reflect.Slice { - if !datav.IsValid() { - return nil - } - return md.badtype("slice", data) - } - n := datav.Len() - if rv.IsNil() || rv.Cap() < n { - rv.Set(reflect.MakeSlice(rv.Type(), n, n)) - } - rv.SetLen(n) - return md.unifySliceArray(datav, rv) -} - -func (md *MetaData) unifySliceArray(data, rv reflect.Value) error { - l := data.Len() - for i := 0; i < l; i++ { - err := md.unify(data.Index(i).Interface(), indirect(rv.Index(i))) - if err != nil { - return err - } - } - return nil -} - -func (md *MetaData) unifyString(data any, rv reflect.Value) error { - _, ok := rv.Interface().(json.Number) - if ok { - if i, ok := data.(int64); ok { - rv.SetString(strconv.FormatInt(i, 10)) - } else if f, ok := data.(float64); ok { - rv.SetString(strconv.FormatFloat(f, 'f', -1, 64)) - } else { - return md.badtype("string", data) - } - return nil - } - - if s, ok := data.(string); ok { - rv.SetString(s) - return nil - } - return md.badtype("string", data) -} - -func (md *MetaData) unifyFloat64(data any, rv reflect.Value) error { - rvk := rv.Kind() - - if num, ok := data.(float64); ok { - switch rvk { - case reflect.Float32: - if num < -math.MaxFloat32 || num > math.MaxFloat32 { - return md.parseErr(errParseRange{i: num, size: rvk.String()}) - } - fallthrough - case reflect.Float64: - rv.SetFloat(num) - default: - panic("bug") - } - return nil - } - - if num, ok := data.(int64); ok { - if (rvk == reflect.Float32 && (num < -maxSafeFloat32Int || num > maxSafeFloat32Int)) || - (rvk == reflect.Float64 && (num < -maxSafeFloat64Int || num > maxSafeFloat64Int)) { - return md.parseErr(errUnsafeFloat{i: num, size: rvk.String()}) - } - rv.SetFloat(float64(num)) - return nil - } - - return md.badtype("float", data) -} - -func (md *MetaData) unifyInt(data any, rv reflect.Value) error { - _, ok := rv.Interface().(time.Duration) - if ok { - // Parse as string duration, and fall back to regular integer parsing - // (as nanosecond) if this is not a string. - if s, ok := data.(string); ok { - dur, err := time.ParseDuration(s) - if err != nil { - return md.parseErr(errParseDuration{s}) - } - rv.SetInt(int64(dur)) - return nil - } - } - - num, ok := data.(int64) - if !ok { - return md.badtype("integer", data) - } - - rvk := rv.Kind() - switch { - case rvk >= reflect.Int && rvk <= reflect.Int64: - if (rvk == reflect.Int8 && (num < math.MinInt8 || num > math.MaxInt8)) || - (rvk == reflect.Int16 && (num < math.MinInt16 || num > math.MaxInt16)) || - (rvk == reflect.Int32 && (num < math.MinInt32 || num > math.MaxInt32)) { - return md.parseErr(errParseRange{i: num, size: rvk.String()}) - } - rv.SetInt(num) - case rvk >= reflect.Uint && rvk <= reflect.Uint64: - unum := uint64(num) - if rvk == reflect.Uint8 && (num < 0 || unum > math.MaxUint8) || - rvk == reflect.Uint16 && (num < 0 || unum > math.MaxUint16) || - rvk == reflect.Uint32 && (num < 0 || unum > math.MaxUint32) { - return md.parseErr(errParseRange{i: num, size: rvk.String()}) - } - rv.SetUint(unum) - default: - panic("unreachable") - } - return nil -} - -func (md *MetaData) unifyBool(data any, rv reflect.Value) error { - if b, ok := data.(bool); ok { - rv.SetBool(b) - return nil - } - return md.badtype("boolean", data) -} - -func (md *MetaData) unifyAnything(data any, rv reflect.Value) error { - rv.Set(reflect.ValueOf(data)) - return nil -} - -func (md *MetaData) unifyText(data any, v encoding.TextUnmarshaler) error { - var s string - switch sdata := data.(type) { - case Marshaler: - text, err := sdata.MarshalTOML() - if err != nil { - return err - } - s = string(text) - case encoding.TextMarshaler: - text, err := sdata.MarshalText() - if err != nil { - return err - } - s = string(text) - case fmt.Stringer: - s = sdata.String() - case string: - s = sdata - case bool: - s = fmt.Sprintf("%v", sdata) - case int64: - s = fmt.Sprintf("%d", sdata) - case float64: - s = fmt.Sprintf("%f", sdata) - default: - return md.badtype("primitive (string-like)", data) - } - if err := v.UnmarshalText([]byte(s)); err != nil { - return md.parseErr(err) - } - return nil -} - -func (md *MetaData) badtype(dst string, data any) error { - return md.e("incompatible types: TOML value has type %s; destination has type %s", fmtType(data), dst) -} - -func (md *MetaData) parseErr(err error) error { - k := md.context.String() - d := string(md.data) - return ParseError{ - Message: err.Error(), - err: err, - LastKey: k, - Position: md.keyInfo[k].pos.withCol(d), - Line: md.keyInfo[k].pos.Line, - input: d, - } -} - -func (md *MetaData) e(format string, args ...any) error { - f := "toml: " - if len(md.context) > 0 { - f = fmt.Sprintf("toml: (last key %q): ", md.context) - p := md.keyInfo[md.context.String()].pos - if p.Line > 0 { - f = fmt.Sprintf("toml: line %d (last key %q): ", p.Line, md.context) - } - } - return fmt.Errorf(f+format, args...) -} - -// rvalue returns a reflect.Value of `v`. All pointers are resolved. -func rvalue(v any) reflect.Value { - return indirect(reflect.ValueOf(v)) -} - -// indirect returns the value pointed to by a pointer. -// -// Pointers are followed until the value is not a pointer. New values are -// allocated for each nil pointer. -// -// An exception to this rule is if the value satisfies an interface of interest -// to us (like encoding.TextUnmarshaler). -func indirect(v reflect.Value) reflect.Value { - if v.Kind() != reflect.Ptr { - if v.CanSet() { - pv := v.Addr() - pvi := pv.Interface() - if _, ok := pvi.(encoding.TextUnmarshaler); ok { - return pv - } - if _, ok := pvi.(Unmarshaler); ok { - return pv - } - } - return v - } - if v.IsNil() { - v.Set(reflect.New(v.Type().Elem())) - } - return indirect(reflect.Indirect(v)) -} - -func isUnifiable(rv reflect.Value) bool { - if rv.CanSet() { - return true - } - rvi := rv.Interface() - if _, ok := rvi.(encoding.TextUnmarshaler); ok { - return true - } - if _, ok := rvi.(Unmarshaler); ok { - return true - } - return false -} - -// fmt %T with "interface {}" replaced with "any", which is far more readable. -func fmtType(t any) string { - return strings.ReplaceAll(fmt.Sprintf("%T", t), "interface {}", "any") -} diff --git a/vendor/github.com/BurntSushi/toml/deprecated.go b/vendor/github.com/BurntSushi/toml/deprecated.go deleted file mode 100644 index 155709a80b..0000000000 --- a/vendor/github.com/BurntSushi/toml/deprecated.go +++ /dev/null @@ -1,29 +0,0 @@ -package toml - -import ( - "encoding" - "io" -) - -// TextMarshaler is an alias for encoding.TextMarshaler. -// -// Deprecated: use encoding.TextMarshaler -type TextMarshaler encoding.TextMarshaler - -// TextUnmarshaler is an alias for encoding.TextUnmarshaler. -// -// Deprecated: use encoding.TextUnmarshaler -type TextUnmarshaler encoding.TextUnmarshaler - -// DecodeReader is an alias for NewDecoder(r).Decode(v). -// -// Deprecated: use NewDecoder(reader).Decode(&value). -func DecodeReader(r io.Reader, v any) (MetaData, error) { return NewDecoder(r).Decode(v) } - -// PrimitiveDecode is an alias for MetaData.PrimitiveDecode(). -// -// Deprecated: use MetaData.PrimitiveDecode. -func PrimitiveDecode(primValue Primitive, v any) error { - md := MetaData{decoded: make(map[string]struct{})} - return md.unify(primValue.undecoded, rvalue(v)) -} diff --git a/vendor/github.com/BurntSushi/toml/doc.go b/vendor/github.com/BurntSushi/toml/doc.go deleted file mode 100644 index 82c90a9057..0000000000 --- a/vendor/github.com/BurntSushi/toml/doc.go +++ /dev/null @@ -1,8 +0,0 @@ -// Package toml implements decoding and encoding of TOML files. -// -// This package supports TOML v1.0.0, as specified at https://toml.io -// -// The github.com/BurntSushi/toml/cmd/tomlv package implements a TOML validator, -// and can be used to verify if TOML document is valid. It can also be used to -// print the type of each key. -package toml diff --git a/vendor/github.com/BurntSushi/toml/encode.go b/vendor/github.com/BurntSushi/toml/encode.go deleted file mode 100644 index ac196e7df8..0000000000 --- a/vendor/github.com/BurntSushi/toml/encode.go +++ /dev/null @@ -1,776 +0,0 @@ -package toml - -import ( - "bufio" - "bytes" - "encoding" - "encoding/json" - "errors" - "fmt" - "io" - "math" - "reflect" - "sort" - "strconv" - "strings" - "time" - - "github.com/BurntSushi/toml/internal" -) - -type tomlEncodeError struct{ error } - -var ( - errArrayNilElement = errors.New("toml: cannot encode array with nil element") - errNonString = errors.New("toml: cannot encode a map with non-string key type") - errNoKey = errors.New("toml: top-level values must be Go maps or structs") - errAnything = errors.New("") // used in testing -) - -var dblQuotedReplacer = strings.NewReplacer( - "\"", "\\\"", - "\\", "\\\\", - "\x00", `\u0000`, - "\x01", `\u0001`, - "\x02", `\u0002`, - "\x03", `\u0003`, - "\x04", `\u0004`, - "\x05", `\u0005`, - "\x06", `\u0006`, - "\x07", `\u0007`, - "\b", `\b`, - "\t", `\t`, - "\n", `\n`, - "\x0b", `\u000b`, - "\f", `\f`, - "\r", `\r`, - "\x0e", `\u000e`, - "\x0f", `\u000f`, - "\x10", `\u0010`, - "\x11", `\u0011`, - "\x12", `\u0012`, - "\x13", `\u0013`, - "\x14", `\u0014`, - "\x15", `\u0015`, - "\x16", `\u0016`, - "\x17", `\u0017`, - "\x18", `\u0018`, - "\x19", `\u0019`, - "\x1a", `\u001a`, - "\x1b", `\u001b`, - "\x1c", `\u001c`, - "\x1d", `\u001d`, - "\x1e", `\u001e`, - "\x1f", `\u001f`, - "\x7f", `\u007f`, -) - -var ( - marshalToml = reflect.TypeOf((*Marshaler)(nil)).Elem() - marshalText = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem() - timeType = reflect.TypeOf((*time.Time)(nil)).Elem() -) - -// Marshaler is the interface implemented by types that can marshal themselves -// into valid TOML. -type Marshaler interface { - MarshalTOML() ([]byte, error) -} - -// Marshal returns a TOML representation of the Go value. -// -// See [Encoder] for a description of the encoding process. -func Marshal(v any) ([]byte, error) { - buff := new(bytes.Buffer) - if err := NewEncoder(buff).Encode(v); err != nil { - return nil, err - } - return buff.Bytes(), nil -} - -// Encoder encodes a Go to a TOML document. -// -// The mapping between Go values and TOML values should be precisely the same as -// for [Decode]. -// -// time.Time is encoded as a RFC 3339 string, and time.Duration as its string -// representation. -// -// The [Marshaler] and [encoding.TextMarshaler] interfaces are supported to -// encoding the value as custom TOML. -// -// If you want to write arbitrary binary data then you will need to use -// something like base64 since TOML does not have any binary types. -// -// When encoding TOML hashes (Go maps or structs), keys without any sub-hashes -// are encoded first. -// -// Go maps will be sorted alphabetically by key for deterministic output. -// -// The toml struct tag can be used to provide the key name; if omitted the -// struct field name will be used. If the "omitempty" option is present the -// following value will be skipped: -// -// - arrays, slices, maps, and string with len of 0 -// - struct with all zero values -// - bool false -// -// If omitzero is given all int and float types with a value of 0 will be -// skipped. -// -// Encoding Go values without a corresponding TOML representation will return an -// error. Examples of this includes maps with non-string keys, slices with nil -// elements, embedded non-struct types, and nested slices containing maps or -// structs. (e.g. [][]map[string]string is not allowed but []map[string]string -// is okay, as is []map[string][]string). -// -// NOTE: only exported keys are encoded due to the use of reflection. Unexported -// keys are silently discarded. -type Encoder struct { - Indent string // string for a single indentation level; default is two spaces. - hasWritten bool // written any output to w yet? - w *bufio.Writer -} - -// NewEncoder create a new Encoder. -func NewEncoder(w io.Writer) *Encoder { - return &Encoder{w: bufio.NewWriter(w), Indent: " "} -} - -// Encode writes a TOML representation of the Go value to the [Encoder]'s writer. -// -// An error is returned if the value given cannot be encoded to a valid TOML -// document. -func (enc *Encoder) Encode(v any) error { - rv := eindirect(reflect.ValueOf(v)) - err := enc.safeEncode(Key([]string{}), rv) - if err != nil { - return err - } - return enc.w.Flush() -} - -func (enc *Encoder) safeEncode(key Key, rv reflect.Value) (err error) { - defer func() { - if r := recover(); r != nil { - if terr, ok := r.(tomlEncodeError); ok { - err = terr.error - return - } - panic(r) - } - }() - enc.encode(key, rv) - return nil -} - -func (enc *Encoder) encode(key Key, rv reflect.Value) { - // If we can marshal the type to text, then we use that. This prevents the - // encoder for handling these types as generic structs (or whatever the - // underlying type of a TextMarshaler is). - switch { - case isMarshaler(rv): - enc.writeKeyValue(key, rv, false) - return - case rv.Type() == primitiveType: // TODO: #76 would make this superfluous after implemented. - enc.encode(key, reflect.ValueOf(rv.Interface().(Primitive).undecoded)) - return - } - - k := rv.Kind() - switch k { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, - reflect.Int64, - reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, - reflect.Uint64, - reflect.Float32, reflect.Float64, reflect.String, reflect.Bool: - enc.writeKeyValue(key, rv, false) - case reflect.Array, reflect.Slice: - if typeEqual(tomlArrayHash, tomlTypeOfGo(rv)) { - enc.eArrayOfTables(key, rv) - } else { - enc.writeKeyValue(key, rv, false) - } - case reflect.Interface: - if rv.IsNil() { - return - } - enc.encode(key, rv.Elem()) - case reflect.Map: - if rv.IsNil() { - return - } - enc.eTable(key, rv) - case reflect.Ptr: - if rv.IsNil() { - return - } - enc.encode(key, rv.Elem()) - case reflect.Struct: - enc.eTable(key, rv) - default: - encPanic(fmt.Errorf("unsupported type for key '%s': %s", key, k)) - } -} - -// eElement encodes any value that can be an array element. -func (enc *Encoder) eElement(rv reflect.Value) { - switch v := rv.Interface().(type) { - case time.Time: // Using TextMarshaler adds extra quotes, which we don't want. - format := time.RFC3339Nano - switch v.Location() { - case internal.LocalDatetime: - format = "2006-01-02T15:04:05.999999999" - case internal.LocalDate: - format = "2006-01-02" - case internal.LocalTime: - format = "15:04:05.999999999" - } - switch v.Location() { - default: - enc.wf(v.Format(format)) - case internal.LocalDatetime, internal.LocalDate, internal.LocalTime: - enc.wf(v.In(time.UTC).Format(format)) - } - return - case Marshaler: - s, err := v.MarshalTOML() - if err != nil { - encPanic(err) - } - if s == nil { - encPanic(errors.New("MarshalTOML returned nil and no error")) - } - enc.w.Write(s) - return - case encoding.TextMarshaler: - s, err := v.MarshalText() - if err != nil { - encPanic(err) - } - if s == nil { - encPanic(errors.New("MarshalText returned nil and no error")) - } - enc.writeQuoted(string(s)) - return - case time.Duration: - enc.writeQuoted(v.String()) - return - case json.Number: - n, _ := rv.Interface().(json.Number) - - if n == "" { /// Useful zero value. - enc.w.WriteByte('0') - return - } else if v, err := n.Int64(); err == nil { - enc.eElement(reflect.ValueOf(v)) - return - } else if v, err := n.Float64(); err == nil { - enc.eElement(reflect.ValueOf(v)) - return - } - encPanic(fmt.Errorf("unable to convert %q to int64 or float64", n)) - } - - switch rv.Kind() { - case reflect.Ptr: - enc.eElement(rv.Elem()) - return - case reflect.String: - enc.writeQuoted(rv.String()) - case reflect.Bool: - enc.wf(strconv.FormatBool(rv.Bool())) - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - enc.wf(strconv.FormatInt(rv.Int(), 10)) - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - enc.wf(strconv.FormatUint(rv.Uint(), 10)) - case reflect.Float32: - f := rv.Float() - if math.IsNaN(f) { - if math.Signbit(f) { - enc.wf("-") - } - enc.wf("nan") - } else if math.IsInf(f, 0) { - if math.Signbit(f) { - enc.wf("-") - } - enc.wf("inf") - } else { - enc.wf(floatAddDecimal(strconv.FormatFloat(f, 'f', -1, 32))) - } - case reflect.Float64: - f := rv.Float() - if math.IsNaN(f) { - if math.Signbit(f) { - enc.wf("-") - } - enc.wf("nan") - } else if math.IsInf(f, 0) { - if math.Signbit(f) { - enc.wf("-") - } - enc.wf("inf") - } else { - enc.wf(floatAddDecimal(strconv.FormatFloat(f, 'f', -1, 64))) - } - case reflect.Array, reflect.Slice: - enc.eArrayOrSliceElement(rv) - case reflect.Struct: - enc.eStruct(nil, rv, true) - case reflect.Map: - enc.eMap(nil, rv, true) - case reflect.Interface: - enc.eElement(rv.Elem()) - default: - encPanic(fmt.Errorf("unexpected type: %s", fmtType(rv.Interface()))) - } -} - -// By the TOML spec, all floats must have a decimal with at least one number on -// either side. -func floatAddDecimal(fstr string) string { - if !strings.Contains(fstr, ".") { - return fstr + ".0" - } - return fstr -} - -func (enc *Encoder) writeQuoted(s string) { - enc.wf("\"%s\"", dblQuotedReplacer.Replace(s)) -} - -func (enc *Encoder) eArrayOrSliceElement(rv reflect.Value) { - length := rv.Len() - enc.wf("[") - for i := 0; i < length; i++ { - elem := eindirect(rv.Index(i)) - enc.eElement(elem) - if i != length-1 { - enc.wf(", ") - } - } - enc.wf("]") -} - -func (enc *Encoder) eArrayOfTables(key Key, rv reflect.Value) { - if len(key) == 0 { - encPanic(errNoKey) - } - for i := 0; i < rv.Len(); i++ { - trv := eindirect(rv.Index(i)) - if isNil(trv) { - continue - } - enc.newline() - enc.wf("%s[[%s]]", enc.indentStr(key), key) - enc.newline() - enc.eMapOrStruct(key, trv, false) - } -} - -func (enc *Encoder) eTable(key Key, rv reflect.Value) { - if len(key) == 1 { - // Output an extra newline between top-level tables. - // (The newline isn't written if nothing else has been written though.) - enc.newline() - } - if len(key) > 0 { - enc.wf("%s[%s]", enc.indentStr(key), key) - enc.newline() - } - enc.eMapOrStruct(key, rv, false) -} - -func (enc *Encoder) eMapOrStruct(key Key, rv reflect.Value, inline bool) { - switch rv.Kind() { - case reflect.Map: - enc.eMap(key, rv, inline) - case reflect.Struct: - enc.eStruct(key, rv, inline) - default: - // Should never happen? - panic("eTable: unhandled reflect.Value Kind: " + rv.Kind().String()) - } -} - -func (enc *Encoder) eMap(key Key, rv reflect.Value, inline bool) { - rt := rv.Type() - if rt.Key().Kind() != reflect.String { - encPanic(errNonString) - } - - // Sort keys so that we have deterministic output. And write keys directly - // underneath this key first, before writing sub-structs or sub-maps. - var mapKeysDirect, mapKeysSub []reflect.Value - for _, mapKey := range rv.MapKeys() { - if typeIsTable(tomlTypeOfGo(eindirect(rv.MapIndex(mapKey)))) { - mapKeysSub = append(mapKeysSub, mapKey) - } else { - mapKeysDirect = append(mapKeysDirect, mapKey) - } - } - - writeMapKeys := func(mapKeys []reflect.Value, trailC bool) { - sort.Slice(mapKeys, func(i, j int) bool { return mapKeys[i].String() < mapKeys[j].String() }) - for i, mapKey := range mapKeys { - val := eindirect(rv.MapIndex(mapKey)) - if isNil(val) { - continue - } - - if inline { - enc.writeKeyValue(Key{mapKey.String()}, val, true) - if trailC || i != len(mapKeys)-1 { - enc.wf(", ") - } - } else { - enc.encode(key.add(mapKey.String()), val) - } - } - } - - if inline { - enc.wf("{") - } - writeMapKeys(mapKeysDirect, len(mapKeysSub) > 0) - writeMapKeys(mapKeysSub, false) - if inline { - enc.wf("}") - } -} - -func pointerTo(t reflect.Type) reflect.Type { - if t.Kind() == reflect.Ptr { - return pointerTo(t.Elem()) - } - return t -} - -func (enc *Encoder) eStruct(key Key, rv reflect.Value, inline bool) { - // Write keys for fields directly under this key first, because if we write - // a field that creates a new table then all keys under it will be in that - // table (not the one we're writing here). - // - // Fields is a [][]int: for fieldsDirect this always has one entry (the - // struct index). For fieldsSub it contains two entries: the parent field - // index from tv, and the field indexes for the fields of the sub. - var ( - rt = rv.Type() - fieldsDirect, fieldsSub [][]int - addFields func(rt reflect.Type, rv reflect.Value, start []int) - ) - addFields = func(rt reflect.Type, rv reflect.Value, start []int) { - for i := 0; i < rt.NumField(); i++ { - f := rt.Field(i) - isEmbed := f.Anonymous && pointerTo(f.Type).Kind() == reflect.Struct - if f.PkgPath != "" && !isEmbed { /// Skip unexported fields. - continue - } - opts := getOptions(f.Tag) - if opts.skip { - continue - } - - frv := eindirect(rv.Field(i)) - - // Need to make a copy because ... ehm, I don't know why... I guess - // allocating a new array can cause it to fail(?) - // - // Done for: https://github.com/BurntSushi/toml/issues/430 - // Previously only on 32bit for: https://github.com/BurntSushi/toml/issues/314 - copyStart := make([]int, len(start)) - copy(copyStart, start) - start = copyStart - - // Treat anonymous struct fields with tag names as though they are - // not anonymous, like encoding/json does. - // - // Non-struct anonymous fields use the normal encoding logic. - if isEmbed { - if getOptions(f.Tag).name == "" && frv.Kind() == reflect.Struct { - addFields(frv.Type(), frv, append(start, f.Index...)) - continue - } - } - - if typeIsTable(tomlTypeOfGo(frv)) { - fieldsSub = append(fieldsSub, append(start, f.Index...)) - } else { - fieldsDirect = append(fieldsDirect, append(start, f.Index...)) - } - } - } - addFields(rt, rv, nil) - - writeFields := func(fields [][]int, totalFields int) { - for _, fieldIndex := range fields { - fieldType := rt.FieldByIndex(fieldIndex) - fieldVal := rv.FieldByIndex(fieldIndex) - - opts := getOptions(fieldType.Tag) - if opts.skip { - continue - } - if opts.omitempty && isEmpty(fieldVal) { - continue - } - - fieldVal = eindirect(fieldVal) - - if isNil(fieldVal) { /// Don't write anything for nil fields. - continue - } - - keyName := fieldType.Name - if opts.name != "" { - keyName = opts.name - } - - if opts.omitzero && isZero(fieldVal) { - continue - } - - if inline { - enc.writeKeyValue(Key{keyName}, fieldVal, true) - if fieldIndex[0] != totalFields-1 { - enc.wf(", ") - } - } else { - enc.encode(key.add(keyName), fieldVal) - } - } - } - - if inline { - enc.wf("{") - } - - l := len(fieldsDirect) + len(fieldsSub) - writeFields(fieldsDirect, l) - writeFields(fieldsSub, l) - if inline { - enc.wf("}") - } -} - -// tomlTypeOfGo returns the TOML type name of the Go value's type. -// -// It is used to determine whether the types of array elements are mixed (which -// is forbidden). If the Go value is nil, then it is illegal for it to be an -// array element, and valueIsNil is returned as true. -// -// The type may be `nil`, which means no concrete TOML type could be found. -func tomlTypeOfGo(rv reflect.Value) tomlType { - if isNil(rv) || !rv.IsValid() { - return nil - } - - if rv.Kind() == reflect.Struct { - if rv.Type() == timeType { - return tomlDatetime - } - if isMarshaler(rv) { - return tomlString - } - return tomlHash - } - - if isMarshaler(rv) { - return tomlString - } - - switch rv.Kind() { - case reflect.Bool: - return tomlBool - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, - reflect.Int64, - reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, - reflect.Uint64: - return tomlInteger - case reflect.Float32, reflect.Float64: - return tomlFloat - case reflect.Array, reflect.Slice: - if isTableArray(rv) { - return tomlArrayHash - } - return tomlArray - case reflect.Ptr, reflect.Interface: - return tomlTypeOfGo(rv.Elem()) - case reflect.String: - return tomlString - case reflect.Map: - return tomlHash - default: - encPanic(errors.New("unsupported type: " + rv.Kind().String())) - panic("unreachable") - } -} - -func isMarshaler(rv reflect.Value) bool { - return rv.Type().Implements(marshalText) || rv.Type().Implements(marshalToml) -} - -// isTableArray reports if all entries in the array or slice are a table. -func isTableArray(arr reflect.Value) bool { - if isNil(arr) || !arr.IsValid() || arr.Len() == 0 { - return false - } - - ret := true - for i := 0; i < arr.Len(); i++ { - tt := tomlTypeOfGo(eindirect(arr.Index(i))) - // Don't allow nil. - if tt == nil { - encPanic(errArrayNilElement) - } - - if ret && !typeEqual(tomlHash, tt) { - ret = false - } - } - return ret -} - -type tagOptions struct { - skip bool // "-" - name string - omitempty bool - omitzero bool -} - -func getOptions(tag reflect.StructTag) tagOptions { - t := tag.Get("toml") - if t == "-" { - return tagOptions{skip: true} - } - var opts tagOptions - parts := strings.Split(t, ",") - opts.name = parts[0] - for _, s := range parts[1:] { - switch s { - case "omitempty": - opts.omitempty = true - case "omitzero": - opts.omitzero = true - } - } - return opts -} - -func isZero(rv reflect.Value) bool { - switch rv.Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return rv.Int() == 0 - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - return rv.Uint() == 0 - case reflect.Float32, reflect.Float64: - return rv.Float() == 0.0 - } - return false -} - -func isEmpty(rv reflect.Value) bool { - switch rv.Kind() { - case reflect.Array, reflect.Slice, reflect.Map, reflect.String: - return rv.Len() == 0 - case reflect.Struct: - if rv.Type().Comparable() { - return reflect.Zero(rv.Type()).Interface() == rv.Interface() - } - // Need to also check if all the fields are empty, otherwise something - // like this with uncomparable types will always return true: - // - // type a struct{ field b } - // type b struct{ s []string } - // s := a{field: b{s: []string{"AAA"}}} - for i := 0; i < rv.NumField(); i++ { - if !isEmpty(rv.Field(i)) { - return false - } - } - return true - case reflect.Bool: - return !rv.Bool() - case reflect.Ptr: - return rv.IsNil() - } - return false -} - -func (enc *Encoder) newline() { - if enc.hasWritten { - enc.wf("\n") - } -} - -// Write a key/value pair: -// -// key = -// -// This is also used for "k = v" in inline tables; so something like this will -// be written in three calls: -// -// ┌───────────────────┐ -// │ ┌───┐ ┌────┐│ -// v v v v vv -// key = {k = 1, k2 = 2} -func (enc *Encoder) writeKeyValue(key Key, val reflect.Value, inline bool) { - /// Marshaler used on top-level document; call eElement() to just call - /// Marshal{TOML,Text}. - if len(key) == 0 { - enc.eElement(val) - return - } - enc.wf("%s%s = ", enc.indentStr(key), key.maybeQuoted(len(key)-1)) - enc.eElement(val) - if !inline { - enc.newline() - } -} - -func (enc *Encoder) wf(format string, v ...any) { - _, err := fmt.Fprintf(enc.w, format, v...) - if err != nil { - encPanic(err) - } - enc.hasWritten = true -} - -func (enc *Encoder) indentStr(key Key) string { - return strings.Repeat(enc.Indent, len(key)-1) -} - -func encPanic(err error) { - panic(tomlEncodeError{err}) -} - -// Resolve any level of pointers to the actual value (e.g. **string → string). -func eindirect(v reflect.Value) reflect.Value { - if v.Kind() != reflect.Ptr && v.Kind() != reflect.Interface { - if isMarshaler(v) { - return v - } - if v.CanAddr() { /// Special case for marshalers; see #358. - if pv := v.Addr(); isMarshaler(pv) { - return pv - } - } - return v - } - - if v.IsNil() { - return v - } - - return eindirect(v.Elem()) -} - -func isNil(rv reflect.Value) bool { - switch rv.Kind() { - case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: - return rv.IsNil() - default: - return false - } -} diff --git a/vendor/github.com/BurntSushi/toml/error.go b/vendor/github.com/BurntSushi/toml/error.go deleted file mode 100644 index b7077d3ae3..0000000000 --- a/vendor/github.com/BurntSushi/toml/error.go +++ /dev/null @@ -1,347 +0,0 @@ -package toml - -import ( - "fmt" - "strings" -) - -// ParseError is returned when there is an error parsing the TOML syntax such as -// invalid syntax, duplicate keys, etc. -// -// In addition to the error message itself, you can also print detailed location -// information with context by using [ErrorWithPosition]: -// -// toml: error: Key 'fruit' was already created and cannot be used as an array. -// -// At line 4, column 2-7: -// -// 2 | fruit = [] -// 3 | -// 4 | [[fruit]] # Not allowed -// ^^^^^ -// -// [ErrorWithUsage] can be used to print the above with some more detailed usage -// guidance: -// -// toml: error: newlines not allowed within inline tables -// -// At line 1, column 18: -// -// 1 | x = [{ key = 42 # -// ^ -// -// Error help: -// -// Inline tables must always be on a single line: -// -// table = {key = 42, second = 43} -// -// It is invalid to split them over multiple lines like so: -// -// # INVALID -// table = { -// key = 42, -// second = 43 -// } -// -// Use regular for this: -// -// [table] -// key = 42 -// second = 43 -type ParseError struct { - Message string // Short technical message. - Usage string // Longer message with usage guidance; may be blank. - Position Position // Position of the error - LastKey string // Last parsed key, may be blank. - - // Line the error occurred. - // - // Deprecated: use [Position]. - Line int - - err error - input string -} - -// Position of an error. -type Position struct { - Line int // Line number, starting at 1. - Col int // Error column, starting at 1. - Start int // Start of error, as byte offset starting at 0. - Len int // Length of the error in bytes. -} - -func (p Position) withCol(tomlFile string) Position { - var ( - pos int - lines = strings.Split(tomlFile, "\n") - ) - for i := range lines { - ll := len(lines[i]) + 1 // +1 for the removed newline - if pos+ll >= p.Start { - p.Col = p.Start - pos + 1 - if p.Col < 1 { // Should never happen, but just in case. - p.Col = 1 - } - break - } - pos += ll - } - return p -} - -func (pe ParseError) Error() string { - if pe.LastKey == "" { - return fmt.Sprintf("toml: line %d: %s", pe.Position.Line, pe.Message) - } - return fmt.Sprintf("toml: line %d (last key %q): %s", - pe.Position.Line, pe.LastKey, pe.Message) -} - -// ErrorWithPosition returns the error with detailed location context. -// -// See the documentation on [ParseError]. -func (pe ParseError) ErrorWithPosition() string { - if pe.input == "" { // Should never happen, but just in case. - return pe.Error() - } - - // TODO: don't show control characters as literals? This may not show up - // well everywhere. - - var ( - lines = strings.Split(pe.input, "\n") - b = new(strings.Builder) - ) - if pe.Position.Len == 1 { - fmt.Fprintf(b, "toml: error: %s\n\nAt line %d, column %d:\n\n", - pe.Message, pe.Position.Line, pe.Position.Col) - } else { - fmt.Fprintf(b, "toml: error: %s\n\nAt line %d, column %d-%d:\n\n", - pe.Message, pe.Position.Line, pe.Position.Col, pe.Position.Col+pe.Position.Len-1) - } - if pe.Position.Line > 2 { - fmt.Fprintf(b, "% 7d | %s\n", pe.Position.Line-2, expandTab(lines[pe.Position.Line-3])) - } - if pe.Position.Line > 1 { - fmt.Fprintf(b, "% 7d | %s\n", pe.Position.Line-1, expandTab(lines[pe.Position.Line-2])) - } - - /// Expand tabs, so that the ^^^s are at the correct position, but leave - /// "column 10-13" intact. Adjusting this to the visual column would be - /// better, but we don't know the tabsize of the user in their editor, which - /// can be 8, 4, 2, or something else. We can't know. So leaving it as the - /// character index is probably the "most correct". - expanded := expandTab(lines[pe.Position.Line-1]) - diff := len(expanded) - len(lines[pe.Position.Line-1]) - - fmt.Fprintf(b, "% 7d | %s\n", pe.Position.Line, expanded) - fmt.Fprintf(b, "% 10s%s%s\n", "", strings.Repeat(" ", pe.Position.Col-1+diff), strings.Repeat("^", pe.Position.Len)) - return b.String() -} - -// ErrorWithUsage returns the error with detailed location context and usage -// guidance. -// -// See the documentation on [ParseError]. -func (pe ParseError) ErrorWithUsage() string { - m := pe.ErrorWithPosition() - if u, ok := pe.err.(interface{ Usage() string }); ok && u.Usage() != "" { - lines := strings.Split(strings.TrimSpace(u.Usage()), "\n") - for i := range lines { - if lines[i] != "" { - lines[i] = " " + lines[i] - } - } - return m + "Error help:\n\n" + strings.Join(lines, "\n") + "\n" - } - return m -} - -func expandTab(s string) string { - var ( - b strings.Builder - l int - fill = func(n int) string { - b := make([]byte, n) - for i := range b { - b[i] = ' ' - } - return string(b) - } - ) - b.Grow(len(s)) - for _, r := range s { - switch r { - case '\t': - tw := 8 - l%8 - b.WriteString(fill(tw)) - l += tw - default: - b.WriteRune(r) - l += 1 - } - } - return b.String() -} - -type ( - errLexControl struct{ r rune } - errLexEscape struct{ r rune } - errLexUTF8 struct{ b byte } - errParseDate struct{ v string } - errLexInlineTableNL struct{} - errLexStringNL struct{} - errParseRange struct { - i any // int or float - size string // "int64", "uint16", etc. - } - errUnsafeFloat struct { - i interface{} // float32 or float64 - size string // "float32" or "float64" - } - errParseDuration struct{ d string } -) - -func (e errLexControl) Error() string { - return fmt.Sprintf("TOML files cannot contain control characters: '0x%02x'", e.r) -} -func (e errLexControl) Usage() string { return "" } - -func (e errLexEscape) Error() string { return fmt.Sprintf(`invalid escape in string '\%c'`, e.r) } -func (e errLexEscape) Usage() string { return usageEscape } -func (e errLexUTF8) Error() string { return fmt.Sprintf("invalid UTF-8 byte: 0x%02x", e.b) } -func (e errLexUTF8) Usage() string { return "" } -func (e errParseDate) Error() string { return fmt.Sprintf("invalid datetime: %q", e.v) } -func (e errParseDate) Usage() string { return usageDate } -func (e errLexInlineTableNL) Error() string { return "newlines not allowed within inline tables" } -func (e errLexInlineTableNL) Usage() string { return usageInlineNewline } -func (e errLexStringNL) Error() string { return "strings cannot contain newlines" } -func (e errLexStringNL) Usage() string { return usageStringNewline } -func (e errParseRange) Error() string { return fmt.Sprintf("%v is out of range for %s", e.i, e.size) } -func (e errParseRange) Usage() string { return usageIntOverflow } -func (e errUnsafeFloat) Error() string { - return fmt.Sprintf("%v is out of the safe %s range", e.i, e.size) -} -func (e errUnsafeFloat) Usage() string { return usageUnsafeFloat } -func (e errParseDuration) Error() string { return fmt.Sprintf("invalid duration: %q", e.d) } -func (e errParseDuration) Usage() string { return usageDuration } - -const usageEscape = ` -A '\' inside a "-delimited string is interpreted as an escape character. - -The following escape sequences are supported: -\b, \t, \n, \f, \r, \", \\, \uXXXX, and \UXXXXXXXX - -To prevent a '\' from being recognized as an escape character, use either: - -- a ' or '''-delimited string; escape characters aren't processed in them; or -- write two backslashes to get a single backslash: '\\'. - -If you're trying to add a Windows path (e.g. "C:\Users\martin") then using '/' -instead of '\' will usually also work: "C:/Users/martin". -` - -const usageInlineNewline = ` -Inline tables must always be on a single line: - - table = {key = 42, second = 43} - -It is invalid to split them over multiple lines like so: - - # INVALID - table = { - key = 42, - second = 43 - } - -Use regular for this: - - [table] - key = 42 - second = 43 -` - -const usageStringNewline = ` -Strings must always be on a single line, and cannot span more than one line: - - # INVALID - string = "Hello, - world!" - -Instead use """ or ''' to split strings over multiple lines: - - string = """Hello, - world!""" -` - -const usageIntOverflow = ` -This number is too large; this may be an error in the TOML, but it can also be a -bug in the program that uses too small of an integer. - -The maximum and minimum values are: - - size │ lowest │ highest - ───────┼────────────────┼────────────── - int8 │ -128 │ 127 - int16 │ -32,768 │ 32,767 - int32 │ -2,147,483,648 │ 2,147,483,647 - int64 │ -9.2 × 10¹⁷ │ 9.2 × 10¹⁷ - uint8 │ 0 │ 255 - uint16 │ 0 │ 65,535 - uint32 │ 0 │ 4,294,967,295 - uint64 │ 0 │ 1.8 × 10¹⁸ - -int refers to int32 on 32-bit systems and int64 on 64-bit systems. -` - -const usageUnsafeFloat = ` -This number is outside of the "safe" range for floating point numbers; whole -(non-fractional) numbers outside the below range can not always be represented -accurately in a float, leading to some loss of accuracy. - -Explicitly mark a number as a fractional unit by adding ".0", which will incur -some loss of accuracy; for example: - - f = 2_000_000_000.0 - -Accuracy ranges: - - float32 = 16,777,215 - float64 = 9,007,199,254,740,991 -` - -const usageDuration = ` -A duration must be as "number", without any spaces. Valid units are: - - ns nanoseconds (billionth of a second) - us, µs microseconds (millionth of a second) - ms milliseconds (thousands of a second) - s seconds - m minutes - h hours - -You can combine multiple units; for example "5m10s" for 5 minutes and 10 -seconds. -` - -const usageDate = ` -A TOML datetime must be in one of the following formats: - - 2006-01-02T15:04:05Z07:00 Date and time, with timezone. - 2006-01-02T15:04:05 Date and time, but without timezone. - 2006-01-02 Date without a time or timezone. - 15:04:05 Just a time, without any timezone. - -Seconds may optionally have a fraction, up to nanosecond precision: - - 15:04:05.123 - 15:04:05.856018510 -` - -// TOML 1.1: -// The seconds part in times is optional, and may be omitted: -// 2006-01-02T15:04Z07:00 -// 2006-01-02T15:04 -// 15:04 diff --git a/vendor/github.com/BurntSushi/toml/internal/tz.go b/vendor/github.com/BurntSushi/toml/internal/tz.go deleted file mode 100644 index 022f15bc2b..0000000000 --- a/vendor/github.com/BurntSushi/toml/internal/tz.go +++ /dev/null @@ -1,36 +0,0 @@ -package internal - -import "time" - -// Timezones used for local datetime, date, and time TOML types. -// -// The exact way times and dates without a timezone should be interpreted is not -// well-defined in the TOML specification and left to the implementation. These -// defaults to current local timezone offset of the computer, but this can be -// changed by changing these variables before decoding. -// -// TODO: -// Ideally we'd like to offer people the ability to configure the used timezone -// by setting Decoder.Timezone and Encoder.Timezone; however, this is a bit -// tricky: the reason we use three different variables for this is to support -// round-tripping – without these specific TZ names we wouldn't know which -// format to use. -// -// There isn't a good way to encode this right now though, and passing this sort -// of information also ties in to various related issues such as string format -// encoding, encoding of comments, etc. -// -// So, for the time being, just put this in internal until we can write a good -// comprehensive API for doing all of this. -// -// The reason they're exported is because they're referred from in e.g. -// internal/tag. -// -// Note that this behaviour is valid according to the TOML spec as the exact -// behaviour is left up to implementations. -var ( - localOffset = func() int { _, o := time.Now().Zone(); return o }() - LocalDatetime = time.FixedZone("datetime-local", localOffset) - LocalDate = time.FixedZone("date-local", localOffset) - LocalTime = time.FixedZone("time-local", localOffset) -) diff --git a/vendor/github.com/BurntSushi/toml/lex.go b/vendor/github.com/BurntSushi/toml/lex.go deleted file mode 100644 index 1c3b477029..0000000000 --- a/vendor/github.com/BurntSushi/toml/lex.go +++ /dev/null @@ -1,1272 +0,0 @@ -package toml - -import ( - "fmt" - "reflect" - "runtime" - "strings" - "unicode" - "unicode/utf8" -) - -type itemType int - -const ( - itemError itemType = iota - itemNIL // used in the parser to indicate no type - itemEOF - itemText - itemString - itemStringEsc - itemRawString - itemMultilineString - itemRawMultilineString - itemBool - itemInteger - itemFloat - itemDatetime - itemArray // the start of an array - itemArrayEnd - itemTableStart - itemTableEnd - itemArrayTableStart - itemArrayTableEnd - itemKeyStart - itemKeyEnd - itemCommentStart - itemInlineTableStart - itemInlineTableEnd -) - -const eof = 0 - -type stateFn func(lx *lexer) stateFn - -func (p Position) String() string { - return fmt.Sprintf("at line %d; start %d; length %d", p.Line, p.Start, p.Len) -} - -type lexer struct { - input string - start int - pos int - line int - state stateFn - items chan item - tomlNext bool - esc bool - - // Allow for backing up up to 4 runes. This is necessary because TOML - // contains 3-rune tokens (""" and '''). - prevWidths [4]int - nprev int // how many of prevWidths are in use - atEOF bool // If we emit an eof, we can still back up, but it is not OK to call next again. - - // A stack of state functions used to maintain context. - // - // The idea is to reuse parts of the state machine in various places. For - // example, values can appear at the top level or within arbitrarily nested - // arrays. The last state on the stack is used after a value has been lexed. - // Similarly for comments. - stack []stateFn -} - -type item struct { - typ itemType - val string - err error - pos Position -} - -func (lx *lexer) nextItem() item { - for { - select { - case item := <-lx.items: - return item - default: - lx.state = lx.state(lx) - //fmt.Printf(" STATE %-24s current: %-10s stack: %s\n", lx.state, lx.current(), lx.stack) - } - } -} - -func lex(input string, tomlNext bool) *lexer { - lx := &lexer{ - input: input, - state: lexTop, - items: make(chan item, 10), - stack: make([]stateFn, 0, 10), - line: 1, - tomlNext: tomlNext, - } - return lx -} - -func (lx *lexer) push(state stateFn) { - lx.stack = append(lx.stack, state) -} - -func (lx *lexer) pop() stateFn { - if len(lx.stack) == 0 { - return lx.errorf("BUG in lexer: no states to pop") - } - last := lx.stack[len(lx.stack)-1] - lx.stack = lx.stack[0 : len(lx.stack)-1] - return last -} - -func (lx *lexer) current() string { - return lx.input[lx.start:lx.pos] -} - -func (lx lexer) getPos() Position { - p := Position{ - Line: lx.line, - Start: lx.start, - Len: lx.pos - lx.start, - } - if p.Len <= 0 { - p.Len = 1 - } - return p -} - -func (lx *lexer) emit(typ itemType) { - // Needed for multiline strings ending with an incomplete UTF-8 sequence. - if lx.start > lx.pos { - lx.error(errLexUTF8{lx.input[lx.pos]}) - return - } - lx.items <- item{typ: typ, pos: lx.getPos(), val: lx.current()} - lx.start = lx.pos -} - -func (lx *lexer) emitTrim(typ itemType) { - lx.items <- item{typ: typ, pos: lx.getPos(), val: strings.TrimSpace(lx.current())} - lx.start = lx.pos -} - -func (lx *lexer) next() (r rune) { - if lx.atEOF { - panic("BUG in lexer: next called after EOF") - } - if lx.pos >= len(lx.input) { - lx.atEOF = true - return eof - } - - if lx.input[lx.pos] == '\n' { - lx.line++ - } - lx.prevWidths[3] = lx.prevWidths[2] - lx.prevWidths[2] = lx.prevWidths[1] - lx.prevWidths[1] = lx.prevWidths[0] - if lx.nprev < 4 { - lx.nprev++ - } - - r, w := utf8.DecodeRuneInString(lx.input[lx.pos:]) - if r == utf8.RuneError && w == 1 { - lx.error(errLexUTF8{lx.input[lx.pos]}) - return utf8.RuneError - } - - // Note: don't use peek() here, as this calls next(). - if isControl(r) || (r == '\r' && (len(lx.input)-1 == lx.pos || lx.input[lx.pos+1] != '\n')) { - lx.errorControlChar(r) - return utf8.RuneError - } - - lx.prevWidths[0] = w - lx.pos += w - return r -} - -// ignore skips over the pending input before this point. -func (lx *lexer) ignore() { - lx.start = lx.pos -} - -// backup steps back one rune. Can be called 4 times between calls to next. -func (lx *lexer) backup() { - if lx.atEOF { - lx.atEOF = false - return - } - if lx.nprev < 1 { - panic("BUG in lexer: backed up too far") - } - w := lx.prevWidths[0] - lx.prevWidths[0] = lx.prevWidths[1] - lx.prevWidths[1] = lx.prevWidths[2] - lx.prevWidths[2] = lx.prevWidths[3] - lx.nprev-- - - lx.pos -= w - if lx.pos < len(lx.input) && lx.input[lx.pos] == '\n' { - lx.line-- - } -} - -// accept consumes the next rune if it's equal to `valid`. -func (lx *lexer) accept(valid rune) bool { - if lx.next() == valid { - return true - } - lx.backup() - return false -} - -// peek returns but does not consume the next rune in the input. -func (lx *lexer) peek() rune { - r := lx.next() - lx.backup() - return r -} - -// skip ignores all input that matches the given predicate. -func (lx *lexer) skip(pred func(rune) bool) { - for { - r := lx.next() - if pred(r) { - continue - } - lx.backup() - lx.ignore() - return - } -} - -// error stops all lexing by emitting an error and returning `nil`. -// -// Note that any value that is a character is escaped if it's a special -// character (newlines, tabs, etc.). -func (lx *lexer) error(err error) stateFn { - if lx.atEOF { - return lx.errorPrevLine(err) - } - lx.items <- item{typ: itemError, pos: lx.getPos(), err: err} - return nil -} - -// errorfPrevline is like error(), but sets the position to the last column of -// the previous line. -// -// This is so that unexpected EOF or NL errors don't show on a new blank line. -func (lx *lexer) errorPrevLine(err error) stateFn { - pos := lx.getPos() - pos.Line-- - pos.Len = 1 - pos.Start = lx.pos - 1 - lx.items <- item{typ: itemError, pos: pos, err: err} - return nil -} - -// errorPos is like error(), but allows explicitly setting the position. -func (lx *lexer) errorPos(start, length int, err error) stateFn { - pos := lx.getPos() - pos.Start = start - pos.Len = length - lx.items <- item{typ: itemError, pos: pos, err: err} - return nil -} - -// errorf is like error, and creates a new error. -func (lx *lexer) errorf(format string, values ...any) stateFn { - if lx.atEOF { - pos := lx.getPos() - if lx.pos >= 1 && lx.input[lx.pos-1] == '\n' { - pos.Line-- - } - pos.Len = 1 - pos.Start = lx.pos - 1 - lx.items <- item{typ: itemError, pos: pos, err: fmt.Errorf(format, values...)} - return nil - } - lx.items <- item{typ: itemError, pos: lx.getPos(), err: fmt.Errorf(format, values...)} - return nil -} - -func (lx *lexer) errorControlChar(cc rune) stateFn { - return lx.errorPos(lx.pos-1, 1, errLexControl{cc}) -} - -// lexTop consumes elements at the top level of TOML data. -func lexTop(lx *lexer) stateFn { - r := lx.next() - if isWhitespace(r) || isNL(r) { - return lexSkip(lx, lexTop) - } - switch r { - case '#': - lx.push(lexTop) - return lexCommentStart - case '[': - return lexTableStart - case eof: - if lx.pos > lx.start { - return lx.errorf("unexpected EOF") - } - lx.emit(itemEOF) - return nil - } - - // At this point, the only valid item can be a key, so we back up - // and let the key lexer do the rest. - lx.backup() - lx.push(lexTopEnd) - return lexKeyStart -} - -// lexTopEnd is entered whenever a top-level item has been consumed. (A value -// or a table.) It must see only whitespace, and will turn back to lexTop -// upon a newline. If it sees EOF, it will quit the lexer successfully. -func lexTopEnd(lx *lexer) stateFn { - r := lx.next() - switch { - case r == '#': - // a comment will read to a newline for us. - lx.push(lexTop) - return lexCommentStart - case isWhitespace(r): - return lexTopEnd - case isNL(r): - lx.ignore() - return lexTop - case r == eof: - lx.emit(itemEOF) - return nil - } - return lx.errorf("expected a top-level item to end with a newline, comment, or EOF, but got %q instead", r) -} - -// lexTable lexes the beginning of a table. Namely, it makes sure that -// it starts with a character other than '.' and ']'. -// It assumes that '[' has already been consumed. -// It also handles the case that this is an item in an array of tables. -// e.g., '[[name]]'. -func lexTableStart(lx *lexer) stateFn { - if lx.peek() == '[' { - lx.next() - lx.emit(itemArrayTableStart) - lx.push(lexArrayTableEnd) - } else { - lx.emit(itemTableStart) - lx.push(lexTableEnd) - } - return lexTableNameStart -} - -func lexTableEnd(lx *lexer) stateFn { - lx.emit(itemTableEnd) - return lexTopEnd -} - -func lexArrayTableEnd(lx *lexer) stateFn { - if r := lx.next(); r != ']' { - return lx.errorf("expected end of table array name delimiter ']', but got %q instead", r) - } - lx.emit(itemArrayTableEnd) - return lexTopEnd -} - -func lexTableNameStart(lx *lexer) stateFn { - lx.skip(isWhitespace) - switch r := lx.peek(); { - case r == ']' || r == eof: - return lx.errorf("unexpected end of table name (table names cannot be empty)") - case r == '.': - return lx.errorf("unexpected table separator (table names cannot be empty)") - case r == '"' || r == '\'': - lx.ignore() - lx.push(lexTableNameEnd) - return lexQuotedName - default: - lx.push(lexTableNameEnd) - return lexBareName - } -} - -// lexTableNameEnd reads the end of a piece of a table name, optionally -// consuming whitespace. -func lexTableNameEnd(lx *lexer) stateFn { - lx.skip(isWhitespace) - switch r := lx.next(); { - case isWhitespace(r): - return lexTableNameEnd - case r == '.': - lx.ignore() - return lexTableNameStart - case r == ']': - return lx.pop() - default: - return lx.errorf("expected '.' or ']' to end table name, but got %q instead", r) - } -} - -// lexBareName lexes one part of a key or table. -// -// It assumes that at least one valid character for the table has already been -// read. -// -// Lexes only one part, e.g. only 'a' inside 'a.b'. -func lexBareName(lx *lexer) stateFn { - r := lx.next() - if isBareKeyChar(r, lx.tomlNext) { - return lexBareName - } - lx.backup() - lx.emit(itemText) - return lx.pop() -} - -// lexBareName lexes one part of a key or table. -// -// It assumes that at least one valid character for the table has already been -// read. -// -// Lexes only one part, e.g. only '"a"' inside '"a".b'. -func lexQuotedName(lx *lexer) stateFn { - r := lx.next() - switch { - case isWhitespace(r): - return lexSkip(lx, lexValue) - case r == '"': - lx.ignore() // ignore the '"' - return lexString - case r == '\'': - lx.ignore() // ignore the "'" - return lexRawString - case r == eof: - return lx.errorf("unexpected EOF; expected value") - default: - return lx.errorf("expected value but found %q instead", r) - } -} - -// lexKeyStart consumes all key parts until a '='. -func lexKeyStart(lx *lexer) stateFn { - lx.skip(isWhitespace) - switch r := lx.peek(); { - case r == '=' || r == eof: - return lx.errorf("unexpected '=': key name appears blank") - case r == '.': - return lx.errorf("unexpected '.': keys cannot start with a '.'") - case r == '"' || r == '\'': - lx.ignore() - fallthrough - default: // Bare key - lx.emit(itemKeyStart) - return lexKeyNameStart - } -} - -func lexKeyNameStart(lx *lexer) stateFn { - lx.skip(isWhitespace) - switch r := lx.peek(); { - case r == '=' || r == eof: - return lx.errorf("unexpected '='") - case r == '.': - return lx.errorf("unexpected '.'") - case r == '"' || r == '\'': - lx.ignore() - lx.push(lexKeyEnd) - return lexQuotedName - default: - lx.push(lexKeyEnd) - return lexBareName - } -} - -// lexKeyEnd consumes the end of a key and trims whitespace (up to the key -// separator). -func lexKeyEnd(lx *lexer) stateFn { - lx.skip(isWhitespace) - switch r := lx.next(); { - case isWhitespace(r): - return lexSkip(lx, lexKeyEnd) - case r == eof: - return lx.errorf("unexpected EOF; expected key separator '='") - case r == '.': - lx.ignore() - return lexKeyNameStart - case r == '=': - lx.emit(itemKeyEnd) - return lexSkip(lx, lexValue) - default: - if r == '\n' { - return lx.errorPrevLine(fmt.Errorf("expected '.' or '=', but got %q instead", r)) - } - return lx.errorf("expected '.' or '=', but got %q instead", r) - } -} - -// lexValue starts the consumption of a value anywhere a value is expected. -// lexValue will ignore whitespace. -// After a value is lexed, the last state on the next is popped and returned. -func lexValue(lx *lexer) stateFn { - // We allow whitespace to precede a value, but NOT newlines. - // In array syntax, the array states are responsible for ignoring newlines. - r := lx.next() - switch { - case isWhitespace(r): - return lexSkip(lx, lexValue) - case isDigit(r): - lx.backup() // avoid an extra state and use the same as above - return lexNumberOrDateStart - } - switch r { - case '[': - lx.ignore() - lx.emit(itemArray) - return lexArrayValue - case '{': - lx.ignore() - lx.emit(itemInlineTableStart) - return lexInlineTableValue - case '"': - if lx.accept('"') { - if lx.accept('"') { - lx.ignore() // Ignore """ - return lexMultilineString - } - lx.backup() - } - lx.ignore() // ignore the '"' - return lexString - case '\'': - if lx.accept('\'') { - if lx.accept('\'') { - lx.ignore() // Ignore """ - return lexMultilineRawString - } - lx.backup() - } - lx.ignore() // ignore the "'" - return lexRawString - case '.': // special error case, be kind to users - return lx.errorf("floats must start with a digit, not '.'") - case 'i', 'n': - if (lx.accept('n') && lx.accept('f')) || (lx.accept('a') && lx.accept('n')) { - lx.emit(itemFloat) - return lx.pop() - } - case '-', '+': - return lexDecimalNumberStart - } - if unicode.IsLetter(r) { - // Be permissive here; lexBool will give a nice error if the - // user wrote something like - // x = foo - // (i.e. not 'true' or 'false' but is something else word-like.) - lx.backup() - return lexBool - } - if r == eof { - return lx.errorf("unexpected EOF; expected value") - } - if r == '\n' { - return lx.errorPrevLine(fmt.Errorf("expected value but found %q instead", r)) - } - return lx.errorf("expected value but found %q instead", r) -} - -// lexArrayValue consumes one value in an array. It assumes that '[' or ',' -// have already been consumed. All whitespace and newlines are ignored. -func lexArrayValue(lx *lexer) stateFn { - r := lx.next() - switch { - case isWhitespace(r) || isNL(r): - return lexSkip(lx, lexArrayValue) - case r == '#': - lx.push(lexArrayValue) - return lexCommentStart - case r == ',': - return lx.errorf("unexpected comma") - case r == ']': - return lexArrayEnd - } - - lx.backup() - lx.push(lexArrayValueEnd) - return lexValue -} - -// lexArrayValueEnd consumes everything between the end of an array value and -// the next value (or the end of the array): it ignores whitespace and newlines -// and expects either a ',' or a ']'. -func lexArrayValueEnd(lx *lexer) stateFn { - switch r := lx.next(); { - case isWhitespace(r) || isNL(r): - return lexSkip(lx, lexArrayValueEnd) - case r == '#': - lx.push(lexArrayValueEnd) - return lexCommentStart - case r == ',': - lx.ignore() - return lexArrayValue // move on to the next value - case r == ']': - return lexArrayEnd - default: - return lx.errorf("expected a comma (',') or array terminator (']'), but got %s", runeOrEOF(r)) - } -} - -// lexArrayEnd finishes the lexing of an array. -// It assumes that a ']' has just been consumed. -func lexArrayEnd(lx *lexer) stateFn { - lx.ignore() - lx.emit(itemArrayEnd) - return lx.pop() -} - -// lexInlineTableValue consumes one key/value pair in an inline table. -// It assumes that '{' or ',' have already been consumed. Whitespace is ignored. -func lexInlineTableValue(lx *lexer) stateFn { - r := lx.next() - switch { - case isWhitespace(r): - return lexSkip(lx, lexInlineTableValue) - case isNL(r): - if lx.tomlNext { - return lexSkip(lx, lexInlineTableValue) - } - return lx.errorPrevLine(errLexInlineTableNL{}) - case r == '#': - lx.push(lexInlineTableValue) - return lexCommentStart - case r == ',': - return lx.errorf("unexpected comma") - case r == '}': - return lexInlineTableEnd - } - lx.backup() - lx.push(lexInlineTableValueEnd) - return lexKeyStart -} - -// lexInlineTableValueEnd consumes everything between the end of an inline table -// key/value pair and the next pair (or the end of the table): -// it ignores whitespace and expects either a ',' or a '}'. -func lexInlineTableValueEnd(lx *lexer) stateFn { - switch r := lx.next(); { - case isWhitespace(r): - return lexSkip(lx, lexInlineTableValueEnd) - case isNL(r): - if lx.tomlNext { - return lexSkip(lx, lexInlineTableValueEnd) - } - return lx.errorPrevLine(errLexInlineTableNL{}) - case r == '#': - lx.push(lexInlineTableValueEnd) - return lexCommentStart - case r == ',': - lx.ignore() - lx.skip(isWhitespace) - if lx.peek() == '}' { - if lx.tomlNext { - return lexInlineTableValueEnd - } - return lx.errorf("trailing comma not allowed in inline tables") - } - return lexInlineTableValue - case r == '}': - return lexInlineTableEnd - default: - return lx.errorf("expected a comma or an inline table terminator '}', but got %s instead", runeOrEOF(r)) - } -} - -func runeOrEOF(r rune) string { - if r == eof { - return "end of file" - } - return "'" + string(r) + "'" -} - -// lexInlineTableEnd finishes the lexing of an inline table. -// It assumes that a '}' has just been consumed. -func lexInlineTableEnd(lx *lexer) stateFn { - lx.ignore() - lx.emit(itemInlineTableEnd) - return lx.pop() -} - -// lexString consumes the inner contents of a string. It assumes that the -// beginning '"' has already been consumed and ignored. -func lexString(lx *lexer) stateFn { - r := lx.next() - switch { - case r == eof: - return lx.errorf(`unexpected EOF; expected '"'`) - case isNL(r): - return lx.errorPrevLine(errLexStringNL{}) - case r == '\\': - lx.push(lexString) - return lexStringEscape - case r == '"': - lx.backup() - if lx.esc { - lx.esc = false - lx.emit(itemStringEsc) - } else { - lx.emit(itemString) - } - lx.next() - lx.ignore() - return lx.pop() - } - return lexString -} - -// lexMultilineString consumes the inner contents of a string. It assumes that -// the beginning '"""' has already been consumed and ignored. -func lexMultilineString(lx *lexer) stateFn { - r := lx.next() - switch r { - default: - return lexMultilineString - case eof: - return lx.errorf(`unexpected EOF; expected '"""'`) - case '\\': - return lexMultilineStringEscape - case '"': - /// Found " → try to read two more "". - if lx.accept('"') { - if lx.accept('"') { - /// Peek ahead: the string can contain " and "", including at the - /// end: """str""""" - /// 6 or more at the end, however, is an error. - if lx.peek() == '"' { - /// Check if we already lexed 5 's; if so we have 6 now, and - /// that's just too many man! - /// - /// Second check is for the edge case: - /// - /// two quotes allowed. - /// vv - /// """lol \"""""" - /// ^^ ^^^---- closing three - /// escaped - /// - /// But ugly, but it works - if strings.HasSuffix(lx.current(), `"""""`) && !strings.HasSuffix(lx.current(), `\"""""`) { - return lx.errorf(`unexpected '""""""'`) - } - lx.backup() - lx.backup() - return lexMultilineString - } - - lx.backup() /// backup: don't include the """ in the item. - lx.backup() - lx.backup() - lx.esc = false - lx.emit(itemMultilineString) - lx.next() /// Read over ''' again and discard it. - lx.next() - lx.next() - lx.ignore() - return lx.pop() - } - lx.backup() - } - return lexMultilineString - } -} - -// lexRawString consumes a raw string. Nothing can be escaped in such a string. -// It assumes that the beginning "'" has already been consumed and ignored. -func lexRawString(lx *lexer) stateFn { - r := lx.next() - switch { - default: - return lexRawString - case r == eof: - return lx.errorf(`unexpected EOF; expected "'"`) - case isNL(r): - return lx.errorPrevLine(errLexStringNL{}) - case r == '\'': - lx.backup() - lx.emit(itemRawString) - lx.next() - lx.ignore() - return lx.pop() - } -} - -// lexMultilineRawString consumes a raw string. Nothing can be escaped in such a -// string. It assumes that the beginning triple-' has already been consumed and -// ignored. -func lexMultilineRawString(lx *lexer) stateFn { - r := lx.next() - switch r { - default: - return lexMultilineRawString - case eof: - return lx.errorf(`unexpected EOF; expected "'''"`) - case '\'': - /// Found ' → try to read two more ''. - if lx.accept('\'') { - if lx.accept('\'') { - /// Peek ahead: the string can contain ' and '', including at the - /// end: '''str''''' - /// 6 or more at the end, however, is an error. - if lx.peek() == '\'' { - /// Check if we already lexed 5 's; if so we have 6 now, and - /// that's just too many man! - if strings.HasSuffix(lx.current(), "'''''") { - return lx.errorf(`unexpected "''''''"`) - } - lx.backup() - lx.backup() - return lexMultilineRawString - } - - lx.backup() /// backup: don't include the ''' in the item. - lx.backup() - lx.backup() - lx.emit(itemRawMultilineString) - lx.next() /// Read over ''' again and discard it. - lx.next() - lx.next() - lx.ignore() - return lx.pop() - } - lx.backup() - } - return lexMultilineRawString - } -} - -// lexMultilineStringEscape consumes an escaped character. It assumes that the -// preceding '\\' has already been consumed. -func lexMultilineStringEscape(lx *lexer) stateFn { - if isNL(lx.next()) { /// \ escaping newline. - return lexMultilineString - } - lx.backup() - lx.push(lexMultilineString) - return lexStringEscape(lx) -} - -func lexStringEscape(lx *lexer) stateFn { - lx.esc = true - r := lx.next() - switch r { - case 'e': - if !lx.tomlNext { - return lx.error(errLexEscape{r}) - } - fallthrough - case 'b': - fallthrough - case 't': - fallthrough - case 'n': - fallthrough - case 'f': - fallthrough - case 'r': - fallthrough - case '"': - fallthrough - case ' ', '\t': - // Inside """ .. """ strings you can use \ to escape newlines, and any - // amount of whitespace can be between the \ and \n. - fallthrough - case '\\': - return lx.pop() - case 'x': - if !lx.tomlNext { - return lx.error(errLexEscape{r}) - } - return lexHexEscape - case 'u': - return lexShortUnicodeEscape - case 'U': - return lexLongUnicodeEscape - } - return lx.error(errLexEscape{r}) -} - -func lexHexEscape(lx *lexer) stateFn { - var r rune - for i := 0; i < 2; i++ { - r = lx.next() - if !isHex(r) { - return lx.errorf(`expected two hexadecimal digits after '\x', but got %q instead`, lx.current()) - } - } - return lx.pop() -} - -func lexShortUnicodeEscape(lx *lexer) stateFn { - var r rune - for i := 0; i < 4; i++ { - r = lx.next() - if !isHex(r) { - return lx.errorf(`expected four hexadecimal digits after '\u', but got %q instead`, lx.current()) - } - } - return lx.pop() -} - -func lexLongUnicodeEscape(lx *lexer) stateFn { - var r rune - for i := 0; i < 8; i++ { - r = lx.next() - if !isHex(r) { - return lx.errorf(`expected eight hexadecimal digits after '\U', but got %q instead`, lx.current()) - } - } - return lx.pop() -} - -// lexNumberOrDateStart processes the first character of a value which begins -// with a digit. It exists to catch values starting with '0', so that -// lexBaseNumberOrDate can differentiate base prefixed integers from other -// types. -func lexNumberOrDateStart(lx *lexer) stateFn { - r := lx.next() - switch r { - case '0': - return lexBaseNumberOrDate - } - - if !isDigit(r) { - // The only way to reach this state is if the value starts - // with a digit, so specifically treat anything else as an - // error. - return lx.errorf("expected a digit but got %q", r) - } - - return lexNumberOrDate -} - -// lexNumberOrDate consumes either an integer, float or datetime. -func lexNumberOrDate(lx *lexer) stateFn { - r := lx.next() - if isDigit(r) { - return lexNumberOrDate - } - switch r { - case '-', ':': - return lexDatetime - case '_': - return lexDecimalNumber - case '.', 'e', 'E': - return lexFloat - } - - lx.backup() - lx.emit(itemInteger) - return lx.pop() -} - -// lexDatetime consumes a Datetime, to a first approximation. -// The parser validates that it matches one of the accepted formats. -func lexDatetime(lx *lexer) stateFn { - r := lx.next() - if isDigit(r) { - return lexDatetime - } - switch r { - case '-', ':', 'T', 't', ' ', '.', 'Z', 'z', '+': - return lexDatetime - } - - lx.backup() - lx.emitTrim(itemDatetime) - return lx.pop() -} - -// lexHexInteger consumes a hexadecimal integer after seeing the '0x' prefix. -func lexHexInteger(lx *lexer) stateFn { - r := lx.next() - if isHex(r) { - return lexHexInteger - } - switch r { - case '_': - return lexHexInteger - } - - lx.backup() - lx.emit(itemInteger) - return lx.pop() -} - -// lexOctalInteger consumes an octal integer after seeing the '0o' prefix. -func lexOctalInteger(lx *lexer) stateFn { - r := lx.next() - if isOctal(r) { - return lexOctalInteger - } - switch r { - case '_': - return lexOctalInteger - } - - lx.backup() - lx.emit(itemInteger) - return lx.pop() -} - -// lexBinaryInteger consumes a binary integer after seeing the '0b' prefix. -func lexBinaryInteger(lx *lexer) stateFn { - r := lx.next() - if isBinary(r) { - return lexBinaryInteger - } - switch r { - case '_': - return lexBinaryInteger - } - - lx.backup() - lx.emit(itemInteger) - return lx.pop() -} - -// lexDecimalNumber consumes a decimal float or integer. -func lexDecimalNumber(lx *lexer) stateFn { - r := lx.next() - if isDigit(r) { - return lexDecimalNumber - } - switch r { - case '.', 'e', 'E': - return lexFloat - case '_': - return lexDecimalNumber - } - - lx.backup() - lx.emit(itemInteger) - return lx.pop() -} - -// lexDecimalNumber consumes the first digit of a number beginning with a sign. -// It assumes the sign has already been consumed. Values which start with a sign -// are only allowed to be decimal integers or floats. -// -// The special "nan" and "inf" values are also recognized. -func lexDecimalNumberStart(lx *lexer) stateFn { - r := lx.next() - - // Special error cases to give users better error messages - switch r { - case 'i': - if !lx.accept('n') || !lx.accept('f') { - return lx.errorf("invalid float: '%s'", lx.current()) - } - lx.emit(itemFloat) - return lx.pop() - case 'n': - if !lx.accept('a') || !lx.accept('n') { - return lx.errorf("invalid float: '%s'", lx.current()) - } - lx.emit(itemFloat) - return lx.pop() - case '0': - p := lx.peek() - switch p { - case 'b', 'o', 'x': - return lx.errorf("cannot use sign with non-decimal numbers: '%s%c'", lx.current(), p) - } - case '.': - return lx.errorf("floats must start with a digit, not '.'") - } - - if isDigit(r) { - return lexDecimalNumber - } - - return lx.errorf("expected a digit but got %q", r) -} - -// lexBaseNumberOrDate differentiates between the possible values which -// start with '0'. It assumes that before reaching this state, the initial '0' -// has been consumed. -func lexBaseNumberOrDate(lx *lexer) stateFn { - r := lx.next() - // Note: All datetimes start with at least two digits, so we don't - // handle date characters (':', '-', etc.) here. - if isDigit(r) { - return lexNumberOrDate - } - switch r { - case '_': - // Can only be decimal, because there can't be an underscore - // between the '0' and the base designator, and dates can't - // contain underscores. - return lexDecimalNumber - case '.', 'e', 'E': - return lexFloat - case 'b': - r = lx.peek() - if !isBinary(r) { - lx.errorf("not a binary number: '%s%c'", lx.current(), r) - } - return lexBinaryInteger - case 'o': - r = lx.peek() - if !isOctal(r) { - lx.errorf("not an octal number: '%s%c'", lx.current(), r) - } - return lexOctalInteger - case 'x': - r = lx.peek() - if !isHex(r) { - lx.errorf("not a hexadecimal number: '%s%c'", lx.current(), r) - } - return lexHexInteger - } - - lx.backup() - lx.emit(itemInteger) - return lx.pop() -} - -// lexFloat consumes the elements of a float. It allows any sequence of -// float-like characters, so floats emitted by the lexer are only a first -// approximation and must be validated by the parser. -func lexFloat(lx *lexer) stateFn { - r := lx.next() - if isDigit(r) { - return lexFloat - } - switch r { - case '_', '.', '-', '+', 'e', 'E': - return lexFloat - } - - lx.backup() - lx.emit(itemFloat) - return lx.pop() -} - -// lexBool consumes a bool string: 'true' or 'false. -func lexBool(lx *lexer) stateFn { - var rs []rune - for { - r := lx.next() - if !unicode.IsLetter(r) { - lx.backup() - break - } - rs = append(rs, r) - } - s := string(rs) - switch s { - case "true", "false": - lx.emit(itemBool) - return lx.pop() - } - return lx.errorf("expected value but found %q instead", s) -} - -// lexCommentStart begins the lexing of a comment. It will emit -// itemCommentStart and consume no characters, passing control to lexComment. -func lexCommentStart(lx *lexer) stateFn { - lx.ignore() - lx.emit(itemCommentStart) - return lexComment -} - -// lexComment lexes an entire comment. It assumes that '#' has been consumed. -// It will consume *up to* the first newline character, and pass control -// back to the last state on the stack. -func lexComment(lx *lexer) stateFn { - switch r := lx.next(); { - case isNL(r) || r == eof: - lx.backup() - lx.emit(itemText) - return lx.pop() - default: - return lexComment - } -} - -// lexSkip ignores all slurped input and moves on to the next state. -func lexSkip(lx *lexer, nextState stateFn) stateFn { - lx.ignore() - return nextState -} - -func (s stateFn) String() string { - name := runtime.FuncForPC(reflect.ValueOf(s).Pointer()).Name() - if i := strings.LastIndexByte(name, '.'); i > -1 { - name = name[i+1:] - } - if s == nil { - name = "" - } - return name + "()" -} - -func (itype itemType) String() string { - switch itype { - case itemError: - return "Error" - case itemNIL: - return "NIL" - case itemEOF: - return "EOF" - case itemText: - return "Text" - case itemString, itemStringEsc, itemRawString, itemMultilineString, itemRawMultilineString: - return "String" - case itemBool: - return "Bool" - case itemInteger: - return "Integer" - case itemFloat: - return "Float" - case itemDatetime: - return "DateTime" - case itemTableStart: - return "TableStart" - case itemTableEnd: - return "TableEnd" - case itemKeyStart: - return "KeyStart" - case itemKeyEnd: - return "KeyEnd" - case itemArray: - return "Array" - case itemArrayEnd: - return "ArrayEnd" - case itemCommentStart: - return "CommentStart" - case itemInlineTableStart: - return "InlineTableStart" - case itemInlineTableEnd: - return "InlineTableEnd" - } - panic(fmt.Sprintf("BUG: Unknown type '%d'.", int(itype))) -} - -func (item item) String() string { - return fmt.Sprintf("(%s, %s)", item.typ, item.val) -} - -func isWhitespace(r rune) bool { return r == '\t' || r == ' ' } -func isNL(r rune) bool { return r == '\n' || r == '\r' } -func isControl(r rune) bool { // Control characters except \t, \r, \n - switch r { - case '\t', '\r', '\n': - return false - default: - return (r >= 0x00 && r <= 0x1f) || r == 0x7f - } -} -func isDigit(r rune) bool { return r >= '0' && r <= '9' } -func isBinary(r rune) bool { return r == '0' || r == '1' } -func isOctal(r rune) bool { return r >= '0' && r <= '7' } -func isHex(r rune) bool { return (r >= '0' && r <= '9') || (r|0x20 >= 'a' && r|0x20 <= 'f') } -func isBareKeyChar(r rune, tomlNext bool) bool { - return (r >= 'A' && r <= 'Z') || (r >= 'a' && r <= 'z') || - (r >= '0' && r <= '9') || r == '_' || r == '-' -} diff --git a/vendor/github.com/BurntSushi/toml/meta.go b/vendor/github.com/BurntSushi/toml/meta.go deleted file mode 100644 index 0d337026c1..0000000000 --- a/vendor/github.com/BurntSushi/toml/meta.go +++ /dev/null @@ -1,145 +0,0 @@ -package toml - -import ( - "strings" -) - -// MetaData allows access to meta information about TOML data that's not -// accessible otherwise. -// -// It allows checking if a key is defined in the TOML data, whether any keys -// were undecoded, and the TOML type of a key. -type MetaData struct { - context Key // Used only during decoding. - - keyInfo map[string]keyInfo - mapping map[string]any - keys []Key - decoded map[string]struct{} - data []byte // Input file; for errors. -} - -// IsDefined reports if the key exists in the TOML data. -// -// The key should be specified hierarchically, for example to access the TOML -// key "a.b.c" you would use IsDefined("a", "b", "c"). Keys are case sensitive. -// -// Returns false for an empty key. -func (md *MetaData) IsDefined(key ...string) bool { - if len(key) == 0 { - return false - } - - var ( - hash map[string]any - ok bool - hashOrVal any = md.mapping - ) - for _, k := range key { - if hash, ok = hashOrVal.(map[string]any); !ok { - return false - } - if hashOrVal, ok = hash[k]; !ok { - return false - } - } - return true -} - -// Type returns a string representation of the type of the key specified. -// -// Type will return the empty string if given an empty key or a key that does -// not exist. Keys are case sensitive. -func (md *MetaData) Type(key ...string) string { - if ki, ok := md.keyInfo[Key(key).String()]; ok { - return ki.tomlType.typeString() - } - return "" -} - -// Keys returns a slice of every key in the TOML data, including key groups. -// -// Each key is itself a slice, where the first element is the top of the -// hierarchy and the last is the most specific. The list will have the same -// order as the keys appeared in the TOML data. -// -// All keys returned are non-empty. -func (md *MetaData) Keys() []Key { - return md.keys -} - -// Undecoded returns all keys that have not been decoded in the order in which -// they appear in the original TOML document. -// -// This includes keys that haven't been decoded because of a [Primitive] value. -// Once the Primitive value is decoded, the keys will be considered decoded. -// -// Also note that decoding into an empty interface will result in no decoding, -// and so no keys will be considered decoded. -// -// In this sense, the Undecoded keys correspond to keys in the TOML document -// that do not have a concrete type in your representation. -func (md *MetaData) Undecoded() []Key { - undecoded := make([]Key, 0, len(md.keys)) - for _, key := range md.keys { - if _, ok := md.decoded[key.String()]; !ok { - undecoded = append(undecoded, key) - } - } - return undecoded -} - -// Key represents any TOML key, including key groups. Use [MetaData.Keys] to get -// values of this type. -type Key []string - -func (k Key) String() string { - // This is called quite often, so it's a bit funky to make it faster. - var b strings.Builder - b.Grow(len(k) * 25) -outer: - for i, kk := range k { - if i > 0 { - b.WriteByte('.') - } - if kk == "" { - b.WriteString(`""`) - } else { - for _, r := range kk { - // "Inline" isBareKeyChar - if !((r >= 'A' && r <= 'Z') || (r >= 'a' && r <= 'z') || (r >= '0' && r <= '9') || r == '_' || r == '-') { - b.WriteByte('"') - b.WriteString(dblQuotedReplacer.Replace(kk)) - b.WriteByte('"') - continue outer - } - } - b.WriteString(kk) - } - } - return b.String() -} - -func (k Key) maybeQuoted(i int) string { - if k[i] == "" { - return `""` - } - for _, r := range k[i] { - if (r >= 'A' && r <= 'Z') || (r >= 'a' && r <= 'z') || (r >= '0' && r <= '9') || r == '_' || r == '-' { - continue - } - return `"` + dblQuotedReplacer.Replace(k[i]) + `"` - } - return k[i] -} - -// Like append(), but only increase the cap by 1. -func (k Key) add(piece string) Key { - newKey := make(Key, len(k)+1) - copy(newKey, k) - newKey[len(k)] = piece - return newKey -} - -func (k Key) parent() Key { return k[:len(k)-1] } // all except the last piece. -func (k Key) last() string { return k[len(k)-1] } // last piece of this key. diff --git a/vendor/github.com/BurntSushi/toml/parse.go b/vendor/github.com/BurntSushi/toml/parse.go deleted file mode 100644 index e3ea8a9a2d..0000000000 --- a/vendor/github.com/BurntSushi/toml/parse.go +++ /dev/null @@ -1,845 +0,0 @@ -package toml - -import ( - "fmt" - "math" - "os" - "strconv" - "strings" - "time" - "unicode/utf8" - - "github.com/BurntSushi/toml/internal" -) - -type parser struct { - lx *lexer - context Key // Full key for the current hash in scope. - currentKey string // Base key name for everything except hashes. - pos Position // Current position in the TOML file. - tomlNext bool - - ordered []Key // List of keys in the order that they appear in the TOML data. - - keyInfo map[string]keyInfo // Map keyname → info about the TOML key. - mapping map[string]any // Map keyname → key value. - implicits map[string]struct{} // Record implicit keys (e.g. "key.group.names"). -} - -type keyInfo struct { - pos Position - tomlType tomlType -} - -func parse(data string) (p *parser, err error) { - _, tomlNext := os.LookupEnv("BURNTSUSHI_TOML_110") - - defer func() { - if r := recover(); r != nil { - if pErr, ok := r.(ParseError); ok { - pErr.input = data - err = pErr - return - } - panic(r) - } - }() - - // Read over BOM; do this here as the lexer calls utf8.DecodeRuneInString() - // which mangles stuff. UTF-16 BOM isn't strictly valid, but some tools add - // it anyway. - if strings.HasPrefix(data, "\xff\xfe") || strings.HasPrefix(data, "\xfe\xff") { // UTF-16 - data = data[2:] - } else if strings.HasPrefix(data, "\xef\xbb\xbf") { // UTF-8 - data = data[3:] - } - - // Examine first few bytes for NULL bytes; this probably means it's a UTF-16 - // file (second byte in surrogate pair being NULL). Again, do this here to - // avoid having to deal with UTF-8/16 stuff in the lexer. - ex := 6 - if len(data) < 6 { - ex = len(data) - } - if i := strings.IndexRune(data[:ex], 0); i > -1 { - return nil, ParseError{ - Message: "files cannot contain NULL bytes; probably using UTF-16; TOML files must be UTF-8", - Position: Position{Line: 1, Col: 1, Start: i, Len: 1}, - Line: 1, - input: data, - } - } - - p = &parser{ - keyInfo: make(map[string]keyInfo), - mapping: make(map[string]any), - lx: lex(data, tomlNext), - ordered: make([]Key, 0), - implicits: make(map[string]struct{}), - tomlNext: tomlNext, - } - for { - item := p.next() - if item.typ == itemEOF { - break - } - p.topLevel(item) - } - - return p, nil -} - -func (p *parser) panicErr(it item, err error) { - panic(ParseError{ - Message: err.Error(), - err: err, - Position: it.pos.withCol(p.lx.input), - Line: it.pos.Len, - LastKey: p.current(), - }) -} - -func (p *parser) panicItemf(it item, format string, v ...any) { - panic(ParseError{ - Message: fmt.Sprintf(format, v...), - Position: it.pos.withCol(p.lx.input), - Line: it.pos.Len, - LastKey: p.current(), - }) -} - -func (p *parser) panicf(format string, v ...any) { - panic(ParseError{ - Message: fmt.Sprintf(format, v...), - Position: p.pos.withCol(p.lx.input), - Line: p.pos.Line, - LastKey: p.current(), - }) -} - -func (p *parser) next() item { - it := p.lx.nextItem() - //fmt.Printf("ITEM %-18s line %-3d │ %q\n", it.typ, it.pos.Line, it.val) - if it.typ == itemError { - if it.err != nil { - panic(ParseError{ - Message: it.err.Error(), - err: it.err, - Position: it.pos.withCol(p.lx.input), - Line: it.pos.Line, - LastKey: p.current(), - }) - } - - p.panicItemf(it, "%s", it.val) - } - return it -} - -func (p *parser) nextPos() item { - it := p.next() - p.pos = it.pos - return it -} - -func (p *parser) bug(format string, v ...any) { - panic(fmt.Sprintf("BUG: "+format+"\n\n", v...)) -} - -func (p *parser) expect(typ itemType) item { - it := p.next() - p.assertEqual(typ, it.typ) - return it -} - -func (p *parser) assertEqual(expected, got itemType) { - if expected != got { - p.bug("Expected '%s' but got '%s'.", expected, got) - } -} - -func (p *parser) topLevel(item item) { - switch item.typ { - case itemCommentStart: // # .. - p.expect(itemText) - case itemTableStart: // [ .. ] - name := p.nextPos() - - var key Key - for ; name.typ != itemTableEnd && name.typ != itemEOF; name = p.next() { - key = append(key, p.keyString(name)) - } - p.assertEqual(itemTableEnd, name.typ) - - p.addContext(key, false) - p.setType("", tomlHash, item.pos) - p.ordered = append(p.ordered, key) - case itemArrayTableStart: // [[ .. ]] - name := p.nextPos() - - var key Key - for ; name.typ != itemArrayTableEnd && name.typ != itemEOF; name = p.next() { - key = append(key, p.keyString(name)) - } - p.assertEqual(itemArrayTableEnd, name.typ) - - p.addContext(key, true) - p.setType("", tomlArrayHash, item.pos) - p.ordered = append(p.ordered, key) - case itemKeyStart: // key = .. - outerContext := p.context - /// Read all the key parts (e.g. 'a' and 'b' in 'a.b') - k := p.nextPos() - var key Key - for ; k.typ != itemKeyEnd && k.typ != itemEOF; k = p.next() { - key = append(key, p.keyString(k)) - } - p.assertEqual(itemKeyEnd, k.typ) - - /// The current key is the last part. - p.currentKey = key.last() - - /// All the other parts (if any) are the context; need to set each part - /// as implicit. - context := key.parent() - for i := range context { - p.addImplicitContext(append(p.context, context[i:i+1]...)) - } - p.ordered = append(p.ordered, p.context.add(p.currentKey)) - - /// Set value. - vItem := p.next() - val, typ := p.value(vItem, false) - p.setValue(p.currentKey, val) - p.setType(p.currentKey, typ, vItem.pos) - - /// Remove the context we added (preserving any context from [tbl] lines). - p.context = outerContext - p.currentKey = "" - default: - p.bug("Unexpected type at top level: %s", item.typ) - } -} - -// Gets a string for a key (or part of a key in a table name). -func (p *parser) keyString(it item) string { - switch it.typ { - case itemText: - return it.val - case itemString, itemStringEsc, itemMultilineString, - itemRawString, itemRawMultilineString: - s, _ := p.value(it, false) - return s.(string) - default: - p.bug("Unexpected key type: %s", it.typ) - } - panic("unreachable") -} - -var datetimeRepl = strings.NewReplacer( - "z", "Z", - "t", "T", - " ", "T") - -// value translates an expected value from the lexer into a Go value wrapped -// as an empty interface. -func (p *parser) value(it item, parentIsArray bool) (any, tomlType) { - switch it.typ { - case itemString: - return it.val, p.typeOfPrimitive(it) - case itemStringEsc: - return p.replaceEscapes(it, it.val), p.typeOfPrimitive(it) - case itemMultilineString: - return p.replaceEscapes(it, p.stripEscapedNewlines(stripFirstNewline(it.val))), p.typeOfPrimitive(it) - case itemRawString: - return it.val, p.typeOfPrimitive(it) - case itemRawMultilineString: - return stripFirstNewline(it.val), p.typeOfPrimitive(it) - case itemInteger: - return p.valueInteger(it) - case itemFloat: - return p.valueFloat(it) - case itemBool: - switch it.val { - case "true": - return true, p.typeOfPrimitive(it) - case "false": - return false, p.typeOfPrimitive(it) - default: - p.bug("Expected boolean value, but got '%s'.", it.val) - } - case itemDatetime: - return p.valueDatetime(it) - case itemArray: - return p.valueArray(it) - case itemInlineTableStart: - return p.valueInlineTable(it, parentIsArray) - default: - p.bug("Unexpected value type: %s", it.typ) - } - panic("unreachable") -} - -func (p *parser) valueInteger(it item) (any, tomlType) { - if !numUnderscoresOK(it.val) { - p.panicItemf(it, "Invalid integer %q: underscores must be surrounded by digits", it.val) - } - if numHasLeadingZero(it.val) { - p.panicItemf(it, "Invalid integer %q: cannot have leading zeroes", it.val) - } - - num, err := strconv.ParseInt(it.val, 0, 64) - if err != nil { - // Distinguish integer values. Normally, it'd be a bug if the lexer - // provides an invalid integer, but it's possible that the number is - // out of range of valid values (which the lexer cannot determine). - // So mark the former as a bug but the latter as a legitimate user - // error. - if e, ok := err.(*strconv.NumError); ok && e.Err == strconv.ErrRange { - p.panicErr(it, errParseRange{i: it.val, size: "int64"}) - } else { - p.bug("Expected integer value, but got '%s'.", it.val) - } - } - return num, p.typeOfPrimitive(it) -} - -func (p *parser) valueFloat(it item) (any, tomlType) { - parts := strings.FieldsFunc(it.val, func(r rune) bool { - switch r { - case '.', 'e', 'E': - return true - } - return false - }) - for _, part := range parts { - if !numUnderscoresOK(part) { - p.panicItemf(it, "Invalid float %q: underscores must be surrounded by digits", it.val) - } - } - if len(parts) > 0 && numHasLeadingZero(parts[0]) { - p.panicItemf(it, "Invalid float %q: cannot have leading zeroes", it.val) - } - if !numPeriodsOK(it.val) { - // As a special case, numbers like '123.' or '1.e2', - // which are valid as far as Go/strconv are concerned, - // must be rejected because TOML says that a fractional - // part consists of '.' followed by 1+ digits. - p.panicItemf(it, "Invalid float %q: '.' must be followed by one or more digits", it.val) - } - val := strings.Replace(it.val, "_", "", -1) - signbit := false - if val == "+nan" || val == "-nan" { - signbit = val == "-nan" - val = "nan" - } - num, err := strconv.ParseFloat(val, 64) - if err != nil { - if e, ok := err.(*strconv.NumError); ok && e.Err == strconv.ErrRange { - p.panicErr(it, errParseRange{i: it.val, size: "float64"}) - } else { - p.panicItemf(it, "Invalid float value: %q", it.val) - } - } - if signbit { - num = math.Copysign(num, -1) - } - return num, p.typeOfPrimitive(it) -} - -var dtTypes = []struct { - fmt string - zone *time.Location - next bool -}{ - {time.RFC3339Nano, time.Local, false}, - {"2006-01-02T15:04:05.999999999", internal.LocalDatetime, false}, - {"2006-01-02", internal.LocalDate, false}, - {"15:04:05.999999999", internal.LocalTime, false}, - - // tomlNext - {"2006-01-02T15:04Z07:00", time.Local, true}, - {"2006-01-02T15:04", internal.LocalDatetime, true}, - {"15:04", internal.LocalTime, true}, -} - -func (p *parser) valueDatetime(it item) (any, tomlType) { - it.val = datetimeRepl.Replace(it.val) - var ( - t time.Time - ok bool - err error - ) - for _, dt := range dtTypes { - if dt.next && !p.tomlNext { - continue - } - t, err = time.ParseInLocation(dt.fmt, it.val, dt.zone) - if err == nil { - if missingLeadingZero(it.val, dt.fmt) { - p.panicErr(it, errParseDate{it.val}) - } - ok = true - break - } - } - if !ok { - p.panicErr(it, errParseDate{it.val}) - } - return t, p.typeOfPrimitive(it) -} - -// Go's time.Parse() will accept numbers without a leading zero; there isn't any -// way to require it. https://github.com/golang/go/issues/29911 -// -// Depend on the fact that the separators (- and :) should always be at the same -// location. -func missingLeadingZero(d, l string) bool { - for i, c := range []byte(l) { - if c == '.' || c == 'Z' { - return false - } - if (c < '0' || c > '9') && d[i] != c { - return true - } - } - return false -} - -func (p *parser) valueArray(it item) (any, tomlType) { - p.setType(p.currentKey, tomlArray, it.pos) - - var ( - // Initialize to a non-nil slice to make it consistent with how S = [] - // decodes into a non-nil slice inside something like struct { S - // []string }. See #338 - array = make([]any, 0, 2) - ) - for it = p.next(); it.typ != itemArrayEnd; it = p.next() { - if it.typ == itemCommentStart { - p.expect(itemText) - continue - } - - val, typ := p.value(it, true) - array = append(array, val) - - // XXX: type isn't used here, we need it to record the accurate type - // information. - // - // Not entirely sure how to best store this; could use "key[0]", - // "key[1]" notation, or maybe store it on the Array type? - _ = typ - } - return array, tomlArray -} - -func (p *parser) valueInlineTable(it item, parentIsArray bool) (any, tomlType) { - var ( - topHash = make(map[string]any) - outerContext = p.context - outerKey = p.currentKey - ) - - p.context = append(p.context, p.currentKey) - prevContext := p.context - p.currentKey = "" - - p.addImplicit(p.context) - p.addContext(p.context, parentIsArray) - - /// Loop over all table key/value pairs. - for it := p.next(); it.typ != itemInlineTableEnd; it = p.next() { - if it.typ == itemCommentStart { - p.expect(itemText) - continue - } - - /// Read all key parts. - k := p.nextPos() - var key Key - for ; k.typ != itemKeyEnd && k.typ != itemEOF; k = p.next() { - key = append(key, p.keyString(k)) - } - p.assertEqual(itemKeyEnd, k.typ) - - /// The current key is the last part. - p.currentKey = key.last() - - /// All the other parts (if any) are the context; need to set each part - /// as implicit. - context := key.parent() - for i := range context { - p.addImplicitContext(append(p.context, context[i:i+1]...)) - } - p.ordered = append(p.ordered, p.context.add(p.currentKey)) - - /// Set the value. - val, typ := p.value(p.next(), false) - p.setValue(p.currentKey, val) - p.setType(p.currentKey, typ, it.pos) - - hash := topHash - for _, c := range context { - h, ok := hash[c] - if !ok { - h = make(map[string]any) - hash[c] = h - } - hash, ok = h.(map[string]any) - if !ok { - p.panicf("%q is not a table", p.context) - } - } - hash[p.currentKey] = val - - /// Restore context. - p.context = prevContext - } - p.context = outerContext - p.currentKey = outerKey - return topHash, tomlHash -} - -// numHasLeadingZero checks if this number has leading zeroes, allowing for '0', -// +/- signs, and base prefixes. -func numHasLeadingZero(s string) bool { - if len(s) > 1 && s[0] == '0' && !(s[1] == 'b' || s[1] == 'o' || s[1] == 'x') { // Allow 0b, 0o, 0x - return true - } - if len(s) > 2 && (s[0] == '-' || s[0] == '+') && s[1] == '0' { - return true - } - return false -} - -// numUnderscoresOK checks whether each underscore in s is surrounded by -// characters that are not underscores. -func numUnderscoresOK(s string) bool { - switch s { - case "nan", "+nan", "-nan", "inf", "-inf", "+inf": - return true - } - accept := false - for _, r := range s { - if r == '_' { - if !accept { - return false - } - } - - // isHex is a superset of all the permissible characters surrounding an - // underscore. - accept = isHex(r) - } - return accept -} - -// numPeriodsOK checks whether every period in s is followed by a digit. -func numPeriodsOK(s string) bool { - period := false - for _, r := range s { - if period && !isDigit(r) { - return false - } - period = r == '.' - } - return !period -} - -// Set the current context of the parser, where the context is either a hash or -// an array of hashes, depending on the value of the `array` parameter. -// -// Establishing the context also makes sure that the key isn't a duplicate, and -// will create implicit hashes automatically. -func (p *parser) addContext(key Key, array bool) { - /// Always start at the top level and drill down for our context. - hashContext := p.mapping - keyContext := make(Key, 0, len(key)-1) - - /// We only need implicit hashes for the parents. - for _, k := range key.parent() { - _, ok := hashContext[k] - keyContext = append(keyContext, k) - - // No key? Make an implicit hash and move on. - if !ok { - p.addImplicit(keyContext) - hashContext[k] = make(map[string]any) - } - - // If the hash context is actually an array of tables, then set - // the hash context to the last element in that array. - // - // Otherwise, it better be a table, since this MUST be a key group (by - // virtue of it not being the last element in a key). - switch t := hashContext[k].(type) { - case []map[string]any: - hashContext = t[len(t)-1] - case map[string]any: - hashContext = t - default: - p.panicf("Key '%s' was already created as a hash.", keyContext) - } - } - - p.context = keyContext - if array { - // If this is the first element for this array, then allocate a new - // list of tables for it. - k := key.last() - if _, ok := hashContext[k]; !ok { - hashContext[k] = make([]map[string]any, 0, 4) - } - - // Add a new table. But make sure the key hasn't already been used - // for something else. - if hash, ok := hashContext[k].([]map[string]any); ok { - hashContext[k] = append(hash, make(map[string]any)) - } else { - p.panicf("Key '%s' was already created and cannot be used as an array.", key) - } - } else { - p.setValue(key.last(), make(map[string]any)) - } - p.context = append(p.context, key.last()) -} - -// setValue sets the given key to the given value in the current context. -// It will make sure that the key hasn't already been defined, account for -// implicit key groups. -func (p *parser) setValue(key string, value any) { - var ( - tmpHash any - ok bool - hash = p.mapping - keyContext = make(Key, 0, len(p.context)+1) - ) - for _, k := range p.context { - keyContext = append(keyContext, k) - if tmpHash, ok = hash[k]; !ok { - p.bug("Context for key '%s' has not been established.", keyContext) - } - switch t := tmpHash.(type) { - case []map[string]any: - // The context is a table of hashes. Pick the most recent table - // defined as the current hash. - hash = t[len(t)-1] - case map[string]any: - hash = t - default: - p.panicf("Key '%s' has already been defined.", keyContext) - } - } - keyContext = append(keyContext, key) - - if _, ok := hash[key]; ok { - // Normally redefining keys isn't allowed, but the key could have been - // defined implicitly and it's allowed to be redefined concretely. (See - // the `valid/implicit-and-explicit-after.toml` in toml-test) - // - // But we have to make sure to stop marking it as an implicit. (So that - // another redefinition provokes an error.) - // - // Note that since it has already been defined (as a hash), we don't - // want to overwrite it. So our business is done. - if p.isArray(keyContext) { - p.removeImplicit(keyContext) - hash[key] = value - return - } - if p.isImplicit(keyContext) { - p.removeImplicit(keyContext) - return - } - // Otherwise, we have a concrete key trying to override a previous key, - // which is *always* wrong. - p.panicf("Key '%s' has already been defined.", keyContext) - } - - hash[key] = value -} - -// setType sets the type of a particular value at a given key. It should be -// called immediately AFTER setValue. -// -// Note that if `key` is empty, then the type given will be applied to the -// current context (which is either a table or an array of tables). -func (p *parser) setType(key string, typ tomlType, pos Position) { - keyContext := make(Key, 0, len(p.context)+1) - keyContext = append(keyContext, p.context...) - if len(key) > 0 { // allow type setting for hashes - keyContext = append(keyContext, key) - } - // Special case to make empty keys ("" = 1) work. - // Without it it will set "" rather than `""`. - // TODO: why is this needed? And why is this only needed here? - if len(keyContext) == 0 { - keyContext = Key{""} - } - p.keyInfo[keyContext.String()] = keyInfo{tomlType: typ, pos: pos} -} - -// Implicit keys need to be created when tables are implied in "a.b.c.d = 1" and -// "[a.b.c]" (the "a", "b", and "c" hashes are never created explicitly). -func (p *parser) addImplicit(key Key) { p.implicits[key.String()] = struct{}{} } -func (p *parser) removeImplicit(key Key) { delete(p.implicits, key.String()) } -func (p *parser) isImplicit(key Key) bool { _, ok := p.implicits[key.String()]; return ok } -func (p *parser) isArray(key Key) bool { return p.keyInfo[key.String()].tomlType == tomlArray } -func (p *parser) addImplicitContext(key Key) { p.addImplicit(key); p.addContext(key, false) } - -// current returns the full key name of the current context. -func (p *parser) current() string { - if len(p.currentKey) == 0 { - return p.context.String() - } - if len(p.context) == 0 { - return p.currentKey - } - return fmt.Sprintf("%s.%s", p.context, p.currentKey) -} - -func stripFirstNewline(s string) string { - if len(s) > 0 && s[0] == '\n' { - return s[1:] - } - if len(s) > 1 && s[0] == '\r' && s[1] == '\n' { - return s[2:] - } - return s -} - -// stripEscapedNewlines removes whitespace after line-ending backslashes in -// multiline strings. -// -// A line-ending backslash is an unescaped \ followed only by whitespace until -// the next newline. After a line-ending backslash, all whitespace is removed -// until the next non-whitespace character. -func (p *parser) stripEscapedNewlines(s string) string { - var ( - b strings.Builder - i int - ) - b.Grow(len(s)) - for { - ix := strings.Index(s[i:], `\`) - if ix < 0 { - b.WriteString(s) - return b.String() - } - i += ix - - if len(s) > i+1 && s[i+1] == '\\' { - // Escaped backslash. - i += 2 - continue - } - // Scan until the next non-whitespace. - j := i + 1 - whitespaceLoop: - for ; j < len(s); j++ { - switch s[j] { - case ' ', '\t', '\r', '\n': - default: - break whitespaceLoop - } - } - if j == i+1 { - // Not a whitespace escape. - i++ - continue - } - if !strings.Contains(s[i:j], "\n") { - // This is not a line-ending backslash. (It's a bad escape sequence, - // but we can let replaceEscapes catch it.) - i++ - continue - } - b.WriteString(s[:i]) - s = s[j:] - i = 0 - } -} - -func (p *parser) replaceEscapes(it item, str string) string { - var ( - b strings.Builder - skip = 0 - ) - b.Grow(len(str)) - for i, c := range str { - if skip > 0 { - skip-- - continue - } - if c != '\\' { - b.WriteRune(c) - continue - } - - if i >= len(str) { - p.bug("Escape sequence at end of string.") - return "" - } - switch str[i+1] { - default: - p.bug("Expected valid escape code after \\, but got %q.", str[i+1]) - case ' ', '\t': - p.panicItemf(it, "invalid escape: '\\%c'", str[i+1]) - case 'b': - b.WriteByte(0x08) - skip = 1 - case 't': - b.WriteByte(0x09) - skip = 1 - case 'n': - b.WriteByte(0x0a) - skip = 1 - case 'f': - b.WriteByte(0x0c) - skip = 1 - case 'r': - b.WriteByte(0x0d) - skip = 1 - case 'e': - if p.tomlNext { - b.WriteByte(0x1b) - skip = 1 - } - case '"': - b.WriteByte(0x22) - skip = 1 - case '\\': - b.WriteByte(0x5c) - skip = 1 - // The lexer guarantees the correct number of characters are present; - // don't need to check here. - case 'x': - if p.tomlNext { - escaped := p.asciiEscapeToUnicode(it, str[i+2:i+4]) - b.WriteRune(escaped) - skip = 3 - } - case 'u': - escaped := p.asciiEscapeToUnicode(it, str[i+2:i+6]) - b.WriteRune(escaped) - skip = 5 - case 'U': - escaped := p.asciiEscapeToUnicode(it, str[i+2:i+10]) - b.WriteRune(escaped) - skip = 9 - } - } - return b.String() -} - -func (p *parser) asciiEscapeToUnicode(it item, s string) rune { - hex, err := strconv.ParseUint(strings.ToLower(s), 16, 32) - if err != nil { - p.bug("Could not parse '%s' as a hexadecimal number, but the lexer claims it's OK: %s", s, err) - } - if !utf8.ValidRune(rune(hex)) { - p.panicItemf(it, "Escaped character '\\u%s' is not valid UTF-8.", s) - } - return rune(hex) -} diff --git a/vendor/github.com/BurntSushi/toml/type_fields.go b/vendor/github.com/BurntSushi/toml/type_fields.go deleted file mode 100644 index 10c51f7eeb..0000000000 --- a/vendor/github.com/BurntSushi/toml/type_fields.go +++ /dev/null @@ -1,238 +0,0 @@ -package toml - -// Struct field handling is adapted from code in encoding/json: -// -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the Go distribution. - -import ( - "reflect" - "sort" - "sync" -) - -// A field represents a single field found in a struct. -type field struct { - name string // the name of the field (`toml` tag included) - tag bool // whether field has a `toml` tag - index []int // represents the depth of an anonymous field - typ reflect.Type // the type of the field -} - -// byName sorts field by name, breaking ties with depth, -// then breaking ties with "name came from toml tag", then -// breaking ties with index sequence. -type byName []field - -func (x byName) Len() int { return len(x) } -func (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] } -func (x byName) Less(i, j int) bool { - if x[i].name != x[j].name { - return x[i].name < x[j].name - } - if len(x[i].index) != len(x[j].index) { - return len(x[i].index) < len(x[j].index) - } - if x[i].tag != x[j].tag { - return x[i].tag - } - return byIndex(x).Less(i, j) -} - -// byIndex sorts field by index sequence. -type byIndex []field - -func (x byIndex) Len() int { return len(x) } -func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] } -func (x byIndex) Less(i, j int) bool { - for k, xik := range x[i].index { - if k >= len(x[j].index) { - return false - } - if xik != x[j].index[k] { - return xik < x[j].index[k] - } - } - return len(x[i].index) < len(x[j].index) -} - -// typeFields returns a list of fields that TOML should recognize for the given -// type. The algorithm is breadth-first search over the set of structs to -// include - the top struct and then any reachable anonymous structs. -func typeFields(t reflect.Type) []field { - // Anonymous fields to explore at the current level and the next. - current := []field{} - next := []field{{typ: t}} - - // Count of queued names for current level and the next. - var count map[reflect.Type]int - var nextCount map[reflect.Type]int - - // Types already visited at an earlier level. - visited := map[reflect.Type]bool{} - - // Fields found. - var fields []field - - for len(next) > 0 { - current, next = next, current[:0] - count, nextCount = nextCount, map[reflect.Type]int{} - - for _, f := range current { - if visited[f.typ] { - continue - } - visited[f.typ] = true - - // Scan f.typ for fields to include. - for i := 0; i < f.typ.NumField(); i++ { - sf := f.typ.Field(i) - if sf.PkgPath != "" && !sf.Anonymous { // unexported - continue - } - opts := getOptions(sf.Tag) - if opts.skip { - continue - } - index := make([]int, len(f.index)+1) - copy(index, f.index) - index[len(f.index)] = i - - ft := sf.Type - if ft.Name() == "" && ft.Kind() == reflect.Ptr { - // Follow pointer. - ft = ft.Elem() - } - - // Record found field and index sequence. - if opts.name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct { - tagged := opts.name != "" - name := opts.name - if name == "" { - name = sf.Name - } - fields = append(fields, field{name, tagged, index, ft}) - if count[f.typ] > 1 { - // If there were multiple instances, add a second, - // so that the annihilation code will see a duplicate. - // It only cares about the distinction between 1 or 2, - // so don't bother generating any more copies. - fields = append(fields, fields[len(fields)-1]) - } - continue - } - - // Record new anonymous struct to explore in next round. - nextCount[ft]++ - if nextCount[ft] == 1 { - f := field{name: ft.Name(), index: index, typ: ft} - next = append(next, f) - } - } - } - } - - sort.Sort(byName(fields)) - - // Delete all fields that are hidden by the Go rules for embedded fields, - // except that fields with TOML tags are promoted. - - // The fields are sorted in primary order of name, secondary order - // of field index length. Loop over names; for each name, delete - // hidden fields by choosing the one dominant field that survives. - out := fields[:0] - for advance, i := 0, 0; i < len(fields); i += advance { - // One iteration per name. - // Find the sequence of fields with the name of this first field. - fi := fields[i] - name := fi.name - for advance = 1; i+advance < len(fields); advance++ { - fj := fields[i+advance] - if fj.name != name { - break - } - } - if advance == 1 { // Only one field with this name - out = append(out, fi) - continue - } - dominant, ok := dominantField(fields[i : i+advance]) - if ok { - out = append(out, dominant) - } - } - - fields = out - sort.Sort(byIndex(fields)) - - return fields -} - -// dominantField looks through the fields, all of which are known to -// have the same name, to find the single field that dominates the -// others using Go's embedding rules, modified by the presence of -// TOML tags. If there are multiple top-level fields, the boolean -// will be false: This condition is an error in Go and we skip all -// the fields. -func dominantField(fields []field) (field, bool) { - // The fields are sorted in increasing index-length order. The winner - // must therefore be one with the shortest index length. Drop all - // longer entries, which is easy: just truncate the slice. - length := len(fields[0].index) - tagged := -1 // Index of first tagged field. - for i, f := range fields { - if len(f.index) > length { - fields = fields[:i] - break - } - if f.tag { - if tagged >= 0 { - // Multiple tagged fields at the same level: conflict. - // Return no field. - return field{}, false - } - tagged = i - } - } - if tagged >= 0 { - return fields[tagged], true - } - // All remaining fields have the same length. If there's more than one, - // we have a conflict (two fields named "X" at the same level) and we - // return no field. - if len(fields) > 1 { - return field{}, false - } - return fields[0], true -} - -var fieldCache struct { - sync.RWMutex - m map[reflect.Type][]field -} - -// cachedTypeFields is like typeFields but uses a cache to avoid repeated work. -func cachedTypeFields(t reflect.Type) []field { - fieldCache.RLock() - f := fieldCache.m[t] - fieldCache.RUnlock() - if f != nil { - return f - } - - // Compute fields without lock. - // Might duplicate effort but won't hold other computations back. - f = typeFields(t) - if f == nil { - f = []field{} - } - - fieldCache.Lock() - if fieldCache.m == nil { - fieldCache.m = map[reflect.Type][]field{} - } - fieldCache.m[t] = f - fieldCache.Unlock() - return f -} diff --git a/vendor/github.com/BurntSushi/toml/type_toml.go b/vendor/github.com/BurntSushi/toml/type_toml.go deleted file mode 100644 index 1c090d331e..0000000000 --- a/vendor/github.com/BurntSushi/toml/type_toml.go +++ /dev/null @@ -1,65 +0,0 @@ -package toml - -// tomlType represents any Go type that corresponds to a TOML type. -// While the first draft of the TOML spec has a simplistic type system that -// probably doesn't need this level of sophistication, we seem to be militating -// toward adding real composite types. -type tomlType interface { - typeString() string -} - -// typeEqual accepts any two types and returns true if they are equal. -func typeEqual(t1, t2 tomlType) bool { - if t1 == nil || t2 == nil { - return false - } - return t1.typeString() == t2.typeString() -} - -func typeIsTable(t tomlType) bool { - return typeEqual(t, tomlHash) || typeEqual(t, tomlArrayHash) -} - -type tomlBaseType string - -func (btype tomlBaseType) typeString() string { return string(btype) } -func (btype tomlBaseType) String() string { return btype.typeString() } - -var ( - tomlInteger tomlBaseType = "Integer" - tomlFloat tomlBaseType = "Float" - tomlDatetime tomlBaseType = "Datetime" - tomlString tomlBaseType = "String" - tomlBool tomlBaseType = "Bool" - tomlArray tomlBaseType = "Array" - tomlHash tomlBaseType = "Hash" - tomlArrayHash tomlBaseType = "ArrayHash" -) - -// typeOfPrimitive returns a tomlType of any primitive value in TOML. -// Primitive values are: Integer, Float, Datetime, String and Bool. -// -// Passing a lexer item other than the following will cause a BUG message -// to occur: itemString, itemBool, itemInteger, itemFloat, itemDatetime. -func (p *parser) typeOfPrimitive(lexItem item) tomlType { - switch lexItem.typ { - case itemInteger: - return tomlInteger - case itemFloat: - return tomlFloat - case itemDatetime: - return tomlDatetime - case itemString, itemStringEsc: - return tomlString - case itemMultilineString: - return tomlString - case itemRawString: - return tomlString - case itemRawMultilineString: - return tomlString - case itemBool: - return tomlBool - } - p.bug("Cannot infer primitive type of lex item '%s'.", lexItem) - panic("unreachable") -} diff --git a/vendor/github.com/Djarvur/go-err113/.gitignore b/vendor/github.com/Djarvur/go-err113/.gitignore deleted file mode 100644 index 66fd13c903..0000000000 --- a/vendor/github.com/Djarvur/go-err113/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib - -# Test binary, built with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -# Dependency directories (remove the comment below to include it) -# vendor/ diff --git a/vendor/github.com/Djarvur/go-err113/.golangci.yml b/vendor/github.com/Djarvur/go-err113/.golangci.yml deleted file mode 100644 index 2abdfc6392..0000000000 --- a/vendor/github.com/Djarvur/go-err113/.golangci.yml +++ /dev/null @@ -1,150 +0,0 @@ -# This file contains all available configuration options -# with their default values. - -# options for analysis running -run: - # default concurrency is a available CPU number - concurrency: 4 - - # timeout for analysis, e.g. 30s, 5m, default is 1m - deadline: 15m - - # exit code when at least one issue was found, default is 1 - issues-exit-code: 1 - - # include test files or not, default is true - tests: false - - # list of build tags, all linters use it. Default is empty list. - #build-tags: - # - mytag - - # which dirs to skip: they won't be analyzed; - # can use regexp here: generated.*, regexp is applied on full path; - # default value is empty list, but next dirs are always skipped independently - # from this option's value: - # vendor$, third_party$, testdata$, examples$, Godeps$, builtin$ - skip-dirs: - - /gen$ - - # which files to skip: they will be analyzed, but issues from them - # won't be reported. Default value is empty list, but there is - # no need to include all autogenerated files, we confidently recognize - # autogenerated files. If it's not please let us know. - skip-files: - - ".*\\.my\\.go$" - - lib/bad.go - - ".*\\.template\\.go$" - -# output configuration options -output: - # colored-line-number|line-number|json|tab|checkstyle, default is "colored-line-number" - format: colored-line-number - - # print lines of code with issue, default is true - print-issued-lines: true - - # print linter name in the end of issue text, default is true - print-linter-name: true - -# all available settings of specific linters -linters-settings: - errcheck: - # report about not checking of errors in type assetions: `a := b.(MyStruct)`; - # default is false: such cases aren't reported by default. - check-type-assertions: false - - # report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`; - # default is false: such cases aren't reported by default. - check-blank: false - govet: - # report about shadowed variables - check-shadowing: true - - # Obtain type information from installed (to $GOPATH/pkg) package files: - # golangci-lint will execute `go install -i` and `go test -i` for analyzed packages - # before analyzing them. - # By default this option is disabled and govet gets type information by loader from source code. - # Loading from source code is slow, but it's done only once for all linters. - # Go-installing of packages first time is much slower than loading them from source code, - # therefore this option is disabled by default. - # But repeated installation is fast in go >= 1.10 because of build caching. - # Enable this option only if all conditions are met: - # 1. you use only "fast" linters (--fast e.g.): no program loading occurs - # 2. you use go >= 1.10 - # 3. you do repeated runs (false for CI) or cache $GOPATH/pkg or `go env GOCACHE` dir in CI. - use-installed-packages: false - golint: - # minimal confidence for issues, default is 0.8 - min-confidence: 0.8 - gofmt: - # simplify code: gofmt with `-s` option, true by default - simplify: true - gocyclo: - # minimal code complexity to report, 30 by default (but we recommend 10-20) - min-complexity: 10 - maligned: - # print struct with more effective memory layout or not, false by default - suggest-new: true - dupl: - # tokens count to trigger issue, 150 by default - threshold: 100 - goconst: - # minimal length of string constant, 3 by default - min-len: 3 - # minimal occurrences count to trigger, 3 by default - min-occurrences: 3 - depguard: - list-type: blacklist - include-go-root: false - packages: - - github.com/davecgh/go-spew/spew - -linters: - #enable: - # - staticcheck - # - unused - # - gosimple - enable-all: true - disable: - - lll - disable-all: false - #presets: - # - bugs - # - unused - fast: false - -issues: - # List of regexps of issue texts to exclude, empty list by default. - # But independently from this option we use default exclude patterns, - # it can be disabled by `exclude-use-default: false`. To list all - # excluded by default patterns execute `golangci-lint run --help` - exclude: - - "`parseTained` is unused" - - "`parseState` is unused" - - # Independently from option `exclude` we use default exclude patterns, - # it can be disabled by this option. To list all - # excluded by default patterns execute `golangci-lint run --help`. - # Default value for this option is false. - exclude-use-default: false - - # Maximum issues count per one linter. Set to 0 to disable. Default is 50. - max-per-linter: 0 - - # Maximum count of issues with the same text. Set to 0 to disable. Default is 3. - max-same: 0 - - # Show only new issues: if there are unstaged changes or untracked files, - # only those changes are analyzed, else only changes in HEAD~ are analyzed. - # It's a super-useful option for integration of golangci-lint into existing - # large codebase. It's not practical to fix all existing issues at the moment - # of integration: much better don't allow issues in new code. - # Default is false. - new: false - - # Show only new issues created after git revision `REV` - #new-from-rev: REV - - # Show only new issues created in git patch with set file path. - #new-from-patch: path/to/patch/file \ No newline at end of file diff --git a/vendor/github.com/Djarvur/go-err113/.travis.yml b/vendor/github.com/Djarvur/go-err113/.travis.yml deleted file mode 100644 index 142be3e8b0..0000000000 --- a/vendor/github.com/Djarvur/go-err113/.travis.yml +++ /dev/null @@ -1,20 +0,0 @@ -language: go - -go: - - "1.23" - - "1.24" - - "1.25" - - tip - -before_install: - - go install github.com/mattn/goveralls@v0.0.12 - - go install golang.org/x/tools/cmd/goimports@v0.36.0 - - wget -O - -q https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh| sh - -script: - - test -z "$(goimports -d ./ 2>&1)" - - ./bin/golangci-lint run - - go test -v -race ./... - -after_success: - - test "$TRAVIS_GO_VERSION" = "1.25" && goveralls -service=travis-ci diff --git a/vendor/github.com/Djarvur/go-err113/LICENSE b/vendor/github.com/Djarvur/go-err113/LICENSE deleted file mode 100644 index a78ad8c776..0000000000 --- a/vendor/github.com/Djarvur/go-err113/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2020 Djarvur - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/Djarvur/go-err113/README.adoc b/vendor/github.com/Djarvur/go-err113/README.adoc deleted file mode 100644 index b26af40386..0000000000 --- a/vendor/github.com/Djarvur/go-err113/README.adoc +++ /dev/null @@ -1,75 +0,0 @@ -= err113 image:https://godoc.org/github.com/Djarvur/go-err113?status.svg["GoDoc",link="http://godoc.org/github.com/Djarvur/go-err113"] image:https://travis-ci.org/Djarvur/go-err113.svg["Build Status",link="https://travis-ci.org/Djarvur/go-err113"] image:https://coveralls.io/repos/Djarvur/go-err113/badge.svg?branch=master&service=github["Coverage Status",link="https://coveralls.io/github/Djarvur/go-err113?branch=master"] -Daniel Podolsky -:toc: - -Golang linter to check the errors handling expressions - -== Details - -Starting from Go 1.13 the standard `error` type behaviour was changed: one `error` could be derived from another with `fmt.Errorf()` method using `%w` format specifier. - -So the errors hierarchy could be built for flexible and responsible errors processing. - -And to make this possible at least two simple rules should be followed: - -1. `error` values should not be compared directly but with `errors.Is()` method. -1. `error` should not be created dynamically from scratch but by the wrapping the static (package-level) error. - -This linter is checking the code for these 2 rules compliance. - -=== Reports - -So, `err113` reports every `==` and `!=` comparison for exact `error` type variables except comparison to `nil` and `io.EOF`. - -Also, any call of `errors.New()` and `fmt.Errorf()` methods are reported except the calls used to initialise package-level variables and the `fmt.Errorf()` calls wrapping the other errors. - -Note: non-standard packages, like `github.com/pkg/errors` are ignored completely. - -== Install - -``` -go get -u github.com/Djarvur/go-err113/cmd/err113 -``` - -== Usage - -Defined by link:https://pkg.go.dev/golang.org/x/tools/go/analysis/singlechecker[singlechecker] package. - -``` -err113: checks the error handling rules according to the Go 1.13 new error type - -Usage: err113 [-flag] [package] - - -Flags: - -V print version and exit - -all - no effect (deprecated) - -c int - display offending line with this many lines of context (default -1) - -cpuprofile string - write CPU profile to this file - -debug string - debug flags, any subset of "fpstv" - -fix - apply all suggested fixes - -flags - print analyzer flags in JSON - -json - emit JSON output - -memprofile string - write memory profile to this file - -source - no effect (deprecated) - -tags string - no effect (deprecated) - -trace string - write trace log to this file - -v no effect (deprecated) -``` - -== Thanks - -To link:https://github.com/quasilyte[Iskander (Alex) Sharipov] for the really useful advices. - -To link:https://github.com/jackwhelpton[Jack Whelpton] for the bugfix provided. \ No newline at end of file diff --git a/vendor/github.com/Djarvur/go-err113/comparison.go b/vendor/github.com/Djarvur/go-err113/comparison.go deleted file mode 100644 index a267ebdce8..0000000000 --- a/vendor/github.com/Djarvur/go-err113/comparison.go +++ /dev/null @@ -1,153 +0,0 @@ -package err113 - -import ( - "fmt" - "go/ast" - "go/token" - "go/types" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/ast/inspector" -) - -func inspectComparision(file *ast.File, pass *analysis.Pass, n ast.Node) bool { // nolint: unparam - // check whether the call expression matches time.Now().Sub() - be, ok := n.(*ast.BinaryExpr) - if !ok { - return true - } - - // check if it is a comparison operation - if be.Op != token.EQL && be.Op != token.NEQ { - return true - } - - if !areBothErrors(be.X, be.Y, pass.TypesInfo) { - return true - } - - root := inspector.New([]*ast.File{file}).Root() - c, ok := root.FindNode(n) - if !ok { - panic(fmt.Errorf("could not find node %T in inspector for file %q", n, file.Name.Name)) - } - - for cur := c.Parent(); cur != root; cur = cur.Parent() { - if isMethodNamed(cur, pass, "Is") { - return true - } - } - - oldExpr := render(pass.Fset, be) - - negate := "" - if be.Op == token.NEQ { - negate = "!" - } - - newExpr := fmt.Sprintf("%s%s.Is(%s, %s)", negate, "errors", rawString(be.X), rawString(be.Y)) - - pass.Report( - analysis.Diagnostic{ - Pos: be.Pos(), - Message: fmt.Sprintf("do not compare errors directly %q, use %q instead", oldExpr, newExpr), - SuggestedFixes: []analysis.SuggestedFix{ - { - Message: fmt.Sprintf("should replace %q with %q", oldExpr, newExpr), - TextEdits: []analysis.TextEdit{ - { - Pos: be.Pos(), - End: be.End(), - NewText: []byte(newExpr), - }, - }, - }, - }, - }, - ) - - return true -} - -var errorType = types.Universe.Lookup("error").Type().Underlying().(*types.Interface) - -func isMethodNamed(cur inspector.Cursor, pass *analysis.Pass, name string) bool { - funcNode, ok := cur.Node().(*ast.FuncDecl) - - if !ok || funcNode.Name == nil || funcNode.Name.Name != name { - return false - } - - if funcNode.Recv == nil && len(funcNode.Recv.List) != 1 { - return false - } - - typ := pass.TypesInfo.Types[funcNode.Recv.List[0].Type] - return typ.Type != nil && types.Implements(typ.Type, errorType) -} - -func isError(v ast.Expr, info *types.Info) bool { - if intf, ok := info.TypeOf(v).Underlying().(*types.Interface); ok { - return intf.NumMethods() == 1 && intf.Method(0).FullName() == "(error).Error" - } - - return false -} - -func isEOF(ex ast.Expr, info *types.Info) bool { - se, ok := ex.(*ast.SelectorExpr) - if !ok || se.Sel.Name != "EOF" { - return false - } - - if ep, ok := asImportedName(se.X, info); !ok || ep != "io" { - return false - } - - return true -} - -func asImportedName(ex ast.Expr, info *types.Info) (string, bool) { - ei, ok := ex.(*ast.Ident) - if !ok { - return "", false - } - - ep, ok := info.ObjectOf(ei).(*types.PkgName) - if !ok { - return "", false - } - - return ep.Imported().Path(), true -} - -func areBothErrors(x, y ast.Expr, typesInfo *types.Info) bool { - // check that both left and right hand side are not nil - if typesInfo.Types[x].IsNil() || typesInfo.Types[y].IsNil() { - return false - } - - // check that both left and right hand side are not io.EOF - if isEOF(x, typesInfo) || isEOF(y, typesInfo) { - return false - } - - // check that both left and right hand side are errors - if !isError(x, typesInfo) && !isError(y, typesInfo) { - return false - } - - return true -} - -func rawString(x ast.Expr) string { - switch t := x.(type) { - case *ast.Ident: - return t.Name - case *ast.SelectorExpr: - return fmt.Sprintf("%s.%s", rawString(t.X), t.Sel.Name) - case *ast.CallExpr: - return fmt.Sprintf("%s()", rawString(t.Fun)) - } - return fmt.Sprintf("%s", x) -} diff --git a/vendor/github.com/Djarvur/go-err113/definition.go b/vendor/github.com/Djarvur/go-err113/definition.go deleted file mode 100644 index 689236bac3..0000000000 --- a/vendor/github.com/Djarvur/go-err113/definition.go +++ /dev/null @@ -1,74 +0,0 @@ -package err113 - -import ( - "go/ast" - "go/types" - "strings" - - "golang.org/x/tools/go/analysis" -) - -var methods2check = map[string]map[string]func(*ast.CallExpr, *types.Info) bool{ // nolint: gochecknoglobals - "errors": {"New": justTrue}, - "fmt": {"Errorf": checkWrap}, -} - -func justTrue(*ast.CallExpr, *types.Info) bool { - return true -} - -func checkWrap(ce *ast.CallExpr, info *types.Info) bool { - return !(len(ce.Args) > 0 && strings.Contains(toString(ce.Args[0], info), `%w`)) -} - -func inspectDefinition(pass *analysis.Pass, tlds map[*ast.CallExpr]struct{}, n ast.Node) bool { //nolint: unparam - // check whether the call expression matches time.Now().Sub() - ce, ok := n.(*ast.CallExpr) - if !ok { - return true - } - - if _, ok = tlds[ce]; ok { - return true - } - - fn, ok := ce.Fun.(*ast.SelectorExpr) - if !ok { - return true - } - - fxName, ok := asImportedName(fn.X, pass.TypesInfo) - if !ok { - return true - } - - methods, ok := methods2check[fxName] - if !ok { - return true - } - - checkFunc, ok := methods[fn.Sel.Name] - if !ok { - return true - } - - if !checkFunc(ce, pass.TypesInfo) { - return true - } - - pass.Reportf( - ce.Pos(), - "do not define dynamic errors, use wrapped static errors instead: %q", - render(pass.Fset, ce), - ) - - return true -} - -func toString(ex ast.Expr, info *types.Info) string { - if tv, ok := info.Types[ex]; ok && tv.Value != nil { - return tv.Value.ExactString() - } - - return "" -} diff --git a/vendor/github.com/Djarvur/go-err113/err113.go b/vendor/github.com/Djarvur/go-err113/err113.go deleted file mode 100644 index 190a7ded96..0000000000 --- a/vendor/github.com/Djarvur/go-err113/err113.go +++ /dev/null @@ -1,90 +0,0 @@ -// Package err113 is a Golang linter to check the errors handling expressions -package err113 - -import ( - "go/ast" - "go/printer" - "go/token" - "strings" - - "golang.org/x/tools/go/analysis" -) - -// NewAnalyzer creates a new analysis.Analyzer instance tuned to run err113 checks. -func NewAnalyzer() *analysis.Analyzer { - return &analysis.Analyzer{ - Name: "err113", - Doc: "checks the error handling rules according to the Go 1.13 new error type", - Run: run, - } -} - -func run(pass *analysis.Pass) (any, error) { - for _, file := range pass.Files { - tlds := enumerateFileDecls(file) - - ast.Inspect( - file, - func(n ast.Node) bool { - return inspectComparision(file, pass, n) && - inspectDefinition(pass, tlds, n) - }, - ) - } - - return nil, nil -} - -// render returns the pretty-print of the given node. -func render(fset *token.FileSet, x any) string { - var buf strings.Builder - if err := printer.Fprint(&buf, fset, x); err != nil { - panic(err) - } - - return buf.String() -} - -func enumerateFileDecls(f *ast.File) map[*ast.CallExpr]struct{} { - res := make(map[*ast.CallExpr]struct{}) - - var ces []*ast.CallExpr // nolint: prealloc - - for _, d := range f.Decls { - ces = append(ces, enumerateDeclVars(d)...) - } - - for _, ce := range ces { - res[ce] = struct{}{} - } - - return res -} - -func enumerateDeclVars(d ast.Decl) (res []*ast.CallExpr) { - td, ok := d.(*ast.GenDecl) - if !ok || td.Tok != token.VAR { - return nil - } - - for _, s := range td.Specs { - res = append(res, enumerateSpecValues(s)...) - } - - return res -} - -func enumerateSpecValues(s ast.Spec) (res []*ast.CallExpr) { - vs, ok := s.(*ast.ValueSpec) - if !ok { - return nil - } - - for _, v := range vs.Values { - if ce, ok := v.(*ast.CallExpr); ok { - res = append(res, ce) - } - } - - return res -} diff --git a/vendor/github.com/Masterminds/semver/v3/.gitignore b/vendor/github.com/Masterminds/semver/v3/.gitignore deleted file mode 100644 index 6b061e6174..0000000000 --- a/vendor/github.com/Masterminds/semver/v3/.gitignore +++ /dev/null @@ -1 +0,0 @@ -_fuzz/ \ No newline at end of file diff --git a/vendor/github.com/Masterminds/semver/v3/.golangci.yml b/vendor/github.com/Masterminds/semver/v3/.golangci.yml deleted file mode 100644 index fbc6332592..0000000000 --- a/vendor/github.com/Masterminds/semver/v3/.golangci.yml +++ /dev/null @@ -1,27 +0,0 @@ -run: - deadline: 2m - -linters: - disable-all: true - enable: - - misspell - - govet - - staticcheck - - errcheck - - unparam - - ineffassign - - nakedret - - gocyclo - - dupl - - goimports - - revive - - gosec - - gosimple - - typecheck - - unused - -linters-settings: - gofmt: - simplify: true - dupl: - threshold: 600 diff --git a/vendor/github.com/Masterminds/semver/v3/CHANGELOG.md b/vendor/github.com/Masterminds/semver/v3/CHANGELOG.md deleted file mode 100644 index fabe5e43dc..0000000000 --- a/vendor/github.com/Masterminds/semver/v3/CHANGELOG.md +++ /dev/null @@ -1,268 +0,0 @@ -# Changelog - -## 3.4.0 (2025-06-27) - -### Added - -- #268: Added property to Constraints to include prereleases for Check and Validate - -### Changed - -- #263: Updated Go testing for 1.24, 1.23, and 1.22 -- #269: Updated the error message handling for message case and wrapping errors -- #266: Restore the ability to have leading 0's when parsing with NewVersion. - Opt-out of this by setting CoerceNewVersion to false. - -### Fixed - -- #257: Fixed the CodeQL link (thanks @dmitris) -- #262: Restored detailed errors when failed to parse with NewVersion. Opt-out - of this by setting DetailedNewVersionErrors to false for faster performance. -- #267: Handle pre-releases for an "and" group if one constraint includes them - -## 3.3.1 (2024-11-19) - -### Fixed - -- #253: Fix for allowing some version that were invalid - -## 3.3.0 (2024-08-27) - -### Added - -- #238: Add LessThanEqual and GreaterThanEqual functions (thanks @grosser) -- #213: nil version equality checking (thanks @KnutZuidema) - -### Changed - -- #241: Simplify StrictNewVersion parsing (thanks @grosser) -- Testing support up through Go 1.23 -- Minimum version set to 1.21 as this is what's tested now -- Fuzz testing now supports caching - -## 3.2.1 (2023-04-10) - -### Changed - -- #198: Improved testing around pre-release names -- #200: Improved code scanning with addition of CodeQL -- #201: Testing now includes Go 1.20. Go 1.17 has been dropped -- #202: Migrated Fuzz testing to Go built-in Fuzzing. CI runs daily -- #203: Docs updated for security details - -### Fixed - -- #199: Fixed issue with range transformations - -## 3.2.0 (2022-11-28) - -### Added - -- #190: Added text marshaling and unmarshaling -- #167: Added JSON marshalling for constraints (thanks @SimonTheLeg) -- #173: Implement encoding.TextMarshaler and encoding.TextUnmarshaler on Version (thanks @MarkRosemaker) -- #179: Added New() version constructor (thanks @kazhuravlev) - -### Changed - -- #182/#183: Updated CI testing setup - -### Fixed - -- #186: Fixing issue where validation of constraint section gave false positives -- #176: Fix constraints check with *-0 (thanks @mtt0) -- #181: Fixed Caret operator (^) gives unexpected results when the minor version in constraint is 0 (thanks @arshchimni) -- #161: Fixed godoc (thanks @afirth) - -## 3.1.1 (2020-11-23) - -### Fixed - -- #158: Fixed issue with generated regex operation order that could cause problem - -## 3.1.0 (2020-04-15) - -### Added - -- #131: Add support for serializing/deserializing SQL (thanks @ryancurrah) - -### Changed - -- #148: More accurate validation messages on constraints - -## 3.0.3 (2019-12-13) - -### Fixed - -- #141: Fixed issue with <= comparison - -## 3.0.2 (2019-11-14) - -### Fixed - -- #134: Fixed broken constraint checking with ^0.0 (thanks @krmichelos) - -## 3.0.1 (2019-09-13) - -### Fixed - -- #125: Fixes issue with module path for v3 - -## 3.0.0 (2019-09-12) - -This is a major release of the semver package which includes API changes. The Go -API is compatible with ^1. The Go API was not changed because many people are using -`go get` without Go modules for their applications and API breaking changes cause -errors which we have or would need to support. - -The changes in this release are the handling based on the data passed into the -functions. These are described in the added and changed sections below. - -### Added - -- StrictNewVersion function. This is similar to NewVersion but will return an - error if the version passed in is not a strict semantic version. For example, - 1.2.3 would pass but v1.2.3 or 1.2 would fail because they are not strictly - speaking semantic versions. This function is faster, performs fewer operations, - and uses fewer allocations than NewVersion. -- Fuzzing has been performed on NewVersion, StrictNewVersion, and NewConstraint. - The Makefile contains the operations used. For more information on you can start - on Wikipedia at https://en.wikipedia.org/wiki/Fuzzing -- Now using Go modules - -### Changed - -- NewVersion has proper prerelease and metadata validation with error messages - to signal an issue with either of them -- ^ now operates using a similar set of rules to npm/js and Rust/Cargo. If the - version is >=1 the ^ ranges works the same as v1. For major versions of 0 the - rules have changed. The minor version is treated as the stable version unless - a patch is specified and then it is equivalent to =. One difference from npm/js - is that prereleases there are only to a specific version (e.g. 1.2.3). - Prereleases here look over multiple versions and follow semantic version - ordering rules. This pattern now follows along with the expected and requested - handling of this packaged by numerous users. - -## 1.5.0 (2019-09-11) - -### Added - -- #103: Add basic fuzzing for `NewVersion()` (thanks @jesse-c) - -### Changed - -- #82: Clarify wildcard meaning in range constraints and update tests for it (thanks @greysteil) -- #83: Clarify caret operator range for pre-1.0.0 dependencies (thanks @greysteil) -- #72: Adding docs comment pointing to vert for a cli -- #71: Update the docs on pre-release comparator handling -- #89: Test with new go versions (thanks @thedevsaddam) -- #87: Added $ to ValidPrerelease for better validation (thanks @jeremycarroll) - -### Fixed - -- #78: Fix unchecked error in example code (thanks @ravron) -- #70: Fix the handling of pre-releases and the 0.0.0 release edge case -- #97: Fixed copyright file for proper display on GitHub -- #107: Fix handling prerelease when sorting alphanum and num -- #109: Fixed where Validate sometimes returns wrong message on error - -## 1.4.2 (2018-04-10) - -### Changed - -- #72: Updated the docs to point to vert for a console appliaction -- #71: Update the docs on pre-release comparator handling - -### Fixed - -- #70: Fix the handling of pre-releases and the 0.0.0 release edge case - -## 1.4.1 (2018-04-02) - -### Fixed - -- Fixed #64: Fix pre-release precedence issue (thanks @uudashr) - -## 1.4.0 (2017-10-04) - -### Changed - -- #61: Update NewVersion to parse ints with a 64bit int size (thanks @zknill) - -## 1.3.1 (2017-07-10) - -### Fixed - -- Fixed #57: number comparisons in prerelease sometimes inaccurate - -## 1.3.0 (2017-05-02) - -### Added - -- #45: Added json (un)marshaling support (thanks @mh-cbon) -- Stability marker. See https://masterminds.github.io/stability/ - -### Fixed - -- #51: Fix handling of single digit tilde constraint (thanks @dgodd) - -### Changed - -- #55: The godoc icon moved from png to svg - -## 1.2.3 (2017-04-03) - -### Fixed - -- #46: Fixed 0.x.x and 0.0.x in constraints being treated as * - -## Release 1.2.2 (2016-12-13) - -### Fixed - -- #34: Fixed issue where hyphen range was not working with pre-release parsing. - -## Release 1.2.1 (2016-11-28) - -### Fixed - -- #24: Fixed edge case issue where constraint "> 0" does not handle "0.0.1-alpha" - properly. - -## Release 1.2.0 (2016-11-04) - -### Added - -- #20: Added MustParse function for versions (thanks @adamreese) -- #15: Added increment methods on versions (thanks @mh-cbon) - -### Fixed - -- Issue #21: Per the SemVer spec (section 9) a pre-release is unstable and - might not satisfy the intended compatibility. The change here ignores pre-releases - on constraint checks (e.g., ~ or ^) when a pre-release is not part of the - constraint. For example, `^1.2.3` will ignore pre-releases while - `^1.2.3-alpha` will include them. - -## Release 1.1.1 (2016-06-30) - -### Changed - -- Issue #9: Speed up version comparison performance (thanks @sdboyer) -- Issue #8: Added benchmarks (thanks @sdboyer) -- Updated Go Report Card URL to new location -- Updated Readme to add code snippet formatting (thanks @mh-cbon) -- Updating tagging to v[SemVer] structure for compatibility with other tools. - -## Release 1.1.0 (2016-03-11) - -- Issue #2: Implemented validation to provide reasons a versions failed a - constraint. - -## Release 1.0.1 (2015-12-31) - -- Fixed #1: * constraint failing on valid versions. - -## Release 1.0.0 (2015-10-20) - -- Initial release diff --git a/vendor/github.com/Masterminds/semver/v3/LICENSE.txt b/vendor/github.com/Masterminds/semver/v3/LICENSE.txt deleted file mode 100644 index 9ff7da9c48..0000000000 --- a/vendor/github.com/Masterminds/semver/v3/LICENSE.txt +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (C) 2014-2019, Matt Butcher and Matt Farina - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/vendor/github.com/Masterminds/semver/v3/Makefile b/vendor/github.com/Masterminds/semver/v3/Makefile deleted file mode 100644 index 9ca87a2c79..0000000000 --- a/vendor/github.com/Masterminds/semver/v3/Makefile +++ /dev/null @@ -1,31 +0,0 @@ -GOPATH=$(shell go env GOPATH) -GOLANGCI_LINT=$(GOPATH)/bin/golangci-lint - -.PHONY: lint -lint: $(GOLANGCI_LINT) - @echo "==> Linting codebase" - @$(GOLANGCI_LINT) run - -.PHONY: test -test: - @echo "==> Running tests" - GO111MODULE=on go test -v - -.PHONY: test-cover -test-cover: - @echo "==> Running Tests with coverage" - GO111MODULE=on go test -cover . - -.PHONY: fuzz -fuzz: - @echo "==> Running Fuzz Tests" - go env GOCACHE - go test -fuzz=FuzzNewVersion -fuzztime=15s . - go test -fuzz=FuzzStrictNewVersion -fuzztime=15s . - go test -fuzz=FuzzNewConstraint -fuzztime=15s . - -$(GOLANGCI_LINT): - # Install golangci-lint. The configuration for it is in the .golangci.yml - # file in the root of the repository - echo ${GOPATH} - curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(GOPATH)/bin v1.56.2 diff --git a/vendor/github.com/Masterminds/semver/v3/README.md b/vendor/github.com/Masterminds/semver/v3/README.md deleted file mode 100644 index 2f56c676a5..0000000000 --- a/vendor/github.com/Masterminds/semver/v3/README.md +++ /dev/null @@ -1,274 +0,0 @@ -# SemVer - -The `semver` package provides the ability to work with [Semantic Versions](http://semver.org) in Go. Specifically it provides the ability to: - -* Parse semantic versions -* Sort semantic versions -* Check if a semantic version fits within a set of constraints -* Optionally work with a `v` prefix - -[![Stability: -Active](https://masterminds.github.io/stability/active.svg)](https://masterminds.github.io/stability/active.html) -[![](https://github.com/Masterminds/semver/workflows/Tests/badge.svg)](https://github.com/Masterminds/semver/actions) -[![GoDoc](https://img.shields.io/static/v1?label=godoc&message=reference&color=blue)](https://pkg.go.dev/github.com/Masterminds/semver/v3) -[![Go Report Card](https://goreportcard.com/badge/github.com/Masterminds/semver)](https://goreportcard.com/report/github.com/Masterminds/semver) - -## Package Versions - -Note, import `github.com/Masterminds/semver/v3` to use the latest version. - -There are three major versions fo the `semver` package. - -* 3.x.x is the stable and active version. This version is focused on constraint - compatibility for range handling in other tools from other languages. It has - a similar API to the v1 releases. The development of this version is on the master - branch. The documentation for this version is below. -* 2.x was developed primarily for [dep](https://github.com/golang/dep). There are - no tagged releases and the development was performed by [@sdboyer](https://github.com/sdboyer). - There are API breaking changes from v1. This version lives on the [2.x branch](https://github.com/Masterminds/semver/tree/2.x). -* 1.x.x is the original release. It is no longer maintained. You should use the - v3 release instead. You can read the documentation for the 1.x.x release - [here](https://github.com/Masterminds/semver/blob/release-1/README.md). - -## Parsing Semantic Versions - -There are two functions that can parse semantic versions. The `StrictNewVersion` -function only parses valid version 2 semantic versions as outlined in the -specification. The `NewVersion` function attempts to coerce a version into a -semantic version and parse it. For example, if there is a leading v or a version -listed without all 3 parts (e.g. `v1.2`) it will attempt to coerce it into a valid -semantic version (e.g., 1.2.0). In both cases a `Version` object is returned -that can be sorted, compared, and used in constraints. - -When parsing a version an error is returned if there is an issue parsing the -version. For example, - - v, err := semver.NewVersion("1.2.3-beta.1+build345") - -The version object has methods to get the parts of the version, compare it to -other versions, convert the version back into a string, and get the original -string. Getting the original string is useful if the semantic version was coerced -into a valid form. - -There are package level variables that affect how `NewVersion` handles parsing. - -- `CoerceNewVersion` is `true` by default. When set to `true` it coerces non-compliant - versions into SemVer. For example, allowing a leading 0 in a major, minor, or patch - part. This enables the use of CalVer in versions even when not compliant with SemVer. - When set to `false` less coercion work is done. -- `DetailedNewVersionErrors` provides more detailed errors. It only has an affect when - `CoerceNewVersion` is set to `false`. When `DetailedNewVersionErrors` is set to `true` - it can provide some more insight into why a version is invalid. Setting - `DetailedNewVersionErrors` to `false` is faster on performance but provides less - detailed error messages if a version fails to parse. - -## Sorting Semantic Versions - -A set of versions can be sorted using the `sort` package from the standard library. -For example, - -```go -raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",} -vs := make([]*semver.Version, len(raw)) -for i, r := range raw { - v, err := semver.NewVersion(r) - if err != nil { - t.Errorf("Error parsing version: %s", err) - } - - vs[i] = v -} - -sort.Sort(semver.Collection(vs)) -``` - -## Checking Version Constraints - -There are two methods for comparing versions. One uses comparison methods on -`Version` instances and the other uses `Constraints`. There are some important -differences to notes between these two methods of comparison. - -1. When two versions are compared using functions such as `Compare`, `LessThan`, - and others it will follow the specification and always include pre-releases - within the comparison. It will provide an answer that is valid with the - comparison section of the spec at https://semver.org/#spec-item-11 -2. When constraint checking is used for checks or validation it will follow a - different set of rules that are common for ranges with tools like npm/js - and Rust/Cargo. This includes considering pre-releases to be invalid if the - ranges does not include one. If you want to have it include pre-releases a - simple solution is to include `-0` in your range. -3. Constraint ranges can have some complex rules including the shorthand use of - ~ and ^. For more details on those see the options below. - -There are differences between the two methods or checking versions because the -comparison methods on `Version` follow the specification while comparison ranges -are not part of the specification. Different packages and tools have taken it -upon themselves to come up with range rules. This has resulted in differences. -For example, npm/js and Cargo/Rust follow similar patterns while PHP has a -different pattern for ^. The comparison features in this package follow the -npm/js and Cargo/Rust lead because applications using it have followed similar -patters with their versions. - -Checking a version against version constraints is one of the most featureful -parts of the package. - -```go -c, err := semver.NewConstraint(">= 1.2.3") -if err != nil { - // Handle constraint not being parsable. -} - -v, err := semver.NewVersion("1.3") -if err != nil { - // Handle version not being parsable. -} -// Check if the version meets the constraints. The variable a will be true. -a := c.Check(v) -``` - -### Basic Comparisons - -There are two elements to the comparisons. First, a comparison string is a list -of space or comma separated AND comparisons. These are then separated by || (OR) -comparisons. For example, `">= 1.2 < 3.0.0 || >= 4.2.3"` is looking for a -comparison that's greater than or equal to 1.2 and less than 3.0.0 or is -greater than or equal to 4.2.3. - -The basic comparisons are: - -* `=`: equal (aliased to no operator) -* `!=`: not equal -* `>`: greater than -* `<`: less than -* `>=`: greater than or equal to -* `<=`: less than or equal to - -### Working With Prerelease Versions - -Pre-releases, for those not familiar with them, are used for software releases -prior to stable or generally available releases. Examples of pre-releases include -development, alpha, beta, and release candidate releases. A pre-release may be -a version such as `1.2.3-beta.1` while the stable release would be `1.2.3`. In the -order of precedence, pre-releases come before their associated releases. In this -example `1.2.3-beta.1 < 1.2.3`. - -According to the Semantic Version specification, pre-releases may not be -API compliant with their release counterpart. It says, - -> A pre-release version indicates that the version is unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version. - -SemVer's comparisons using constraints without a pre-release comparator will skip -pre-release versions. For example, `>=1.2.3` will skip pre-releases when looking -at a list of releases while `>=1.2.3-0` will evaluate and find pre-releases. - -The reason for the `0` as a pre-release version in the example comparison is -because pre-releases can only contain ASCII alphanumerics and hyphens (along with -`.` separators), per the spec. Sorting happens in ASCII sort order, again per the -spec. The lowest character is a `0` in ASCII sort order -(see an [ASCII Table](http://www.asciitable.com/)) - -Understanding ASCII sort ordering is important because A-Z comes before a-z. That -means `>=1.2.3-BETA` will return `1.2.3-alpha`. What you might expect from case -sensitivity doesn't apply here. This is due to ASCII sort ordering which is what -the spec specifies. - -The `Constraints` instance returned from `semver.NewConstraint()` has a property -`IncludePrerelease` that, when set to true, will return prerelease versions when calls -to `Check()` and `Validate()` are made. - -### Hyphen Range Comparisons - -There are multiple methods to handle ranges and the first is hyphens ranges. -These look like: - -* `1.2 - 1.4.5` which is equivalent to `>= 1.2 <= 1.4.5` -* `2.3.4 - 4.5` which is equivalent to `>= 2.3.4 <= 4.5` - -Note that `1.2-1.4.5` without whitespace is parsed completely differently; it's -parsed as a single constraint `1.2.0` with _prerelease_ `1.4.5`. - -### Wildcards In Comparisons - -The `x`, `X`, and `*` characters can be used as a wildcard character. This works -for all comparison operators. When used on the `=` operator it falls -back to the patch level comparison (see tilde below). For example, - -* `1.2.x` is equivalent to `>= 1.2.0, < 1.3.0` -* `>= 1.2.x` is equivalent to `>= 1.2.0` -* `<= 2.x` is equivalent to `< 3` -* `*` is equivalent to `>= 0.0.0` - -### Tilde Range Comparisons (Patch) - -The tilde (`~`) comparison operator is for patch level ranges when a minor -version is specified and major level changes when the minor number is missing. -For example, - -* `~1.2.3` is equivalent to `>= 1.2.3, < 1.3.0` -* `~1` is equivalent to `>= 1, < 2` -* `~2.3` is equivalent to `>= 2.3, < 2.4` -* `~1.2.x` is equivalent to `>= 1.2.0, < 1.3.0` -* `~1.x` is equivalent to `>= 1, < 2` - -### Caret Range Comparisons (Major) - -The caret (`^`) comparison operator is for major level changes once a stable -(1.0.0) release has occurred. Prior to a 1.0.0 release the minor versions acts -as the API stability level. This is useful when comparisons of API versions as a -major change is API breaking. For example, - -* `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0` -* `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0` -* `^2.3` is equivalent to `>= 2.3, < 3` -* `^2.x` is equivalent to `>= 2.0.0, < 3` -* `^0.2.3` is equivalent to `>=0.2.3 <0.3.0` -* `^0.2` is equivalent to `>=0.2.0 <0.3.0` -* `^0.0.3` is equivalent to `>=0.0.3 <0.0.4` -* `^0.0` is equivalent to `>=0.0.0 <0.1.0` -* `^0` is equivalent to `>=0.0.0 <1.0.0` - -## Validation - -In addition to testing a version against a constraint, a version can be validated -against a constraint. When validation fails a slice of errors containing why a -version didn't meet the constraint is returned. For example, - -```go -c, err := semver.NewConstraint("<= 1.2.3, >= 1.4") -if err != nil { - // Handle constraint not being parseable. -} - -v, err := semver.NewVersion("1.3") -if err != nil { - // Handle version not being parseable. -} - -// Validate a version against a constraint. -a, msgs := c.Validate(v) -// a is false -for _, m := range msgs { - fmt.Println(m) - - // Loops over the errors which would read - // "1.3 is greater than 1.2.3" - // "1.3 is less than 1.4" -} -``` - -## Contribute - -If you find an issue or want to contribute please file an [issue](https://github.com/Masterminds/semver/issues) -or [create a pull request](https://github.com/Masterminds/semver/pulls). - -## Security - -Security is an important consideration for this project. The project currently -uses the following tools to help discover security issues: - -* [CodeQL](https://codeql.github.com) -* [gosec](https://github.com/securego/gosec) -* Daily Fuzz testing - -If you believe you have found a security vulnerability you can privately disclose -it through the [GitHub security page](https://github.com/Masterminds/semver/security). diff --git a/vendor/github.com/Masterminds/semver/v3/SECURITY.md b/vendor/github.com/Masterminds/semver/v3/SECURITY.md deleted file mode 100644 index a30a66b1f7..0000000000 --- a/vendor/github.com/Masterminds/semver/v3/SECURITY.md +++ /dev/null @@ -1,19 +0,0 @@ -# Security Policy - -## Supported Versions - -The following versions of semver are currently supported: - -| Version | Supported | -| ------- | ------------------ | -| 3.x | :white_check_mark: | -| 2.x | :x: | -| 1.x | :x: | - -Fixes are only released for the latest minor version in the form of a patch release. - -## Reporting a Vulnerability - -You can privately disclose a vulnerability through GitHubs -[private vulnerability reporting](https://github.com/Masterminds/semver/security/advisories) -mechanism. diff --git a/vendor/github.com/Masterminds/semver/v3/collection.go b/vendor/github.com/Masterminds/semver/v3/collection.go deleted file mode 100644 index a78235895f..0000000000 --- a/vendor/github.com/Masterminds/semver/v3/collection.go +++ /dev/null @@ -1,24 +0,0 @@ -package semver - -// Collection is a collection of Version instances and implements the sort -// interface. See the sort package for more details. -// https://golang.org/pkg/sort/ -type Collection []*Version - -// Len returns the length of a collection. The number of Version instances -// on the slice. -func (c Collection) Len() int { - return len(c) -} - -// Less is needed for the sort interface to compare two Version objects on the -// slice. If checks if one is less than the other. -func (c Collection) Less(i, j int) bool { - return c[i].LessThan(c[j]) -} - -// Swap is needed for the sort interface to replace the Version objects -// at two different positions in the slice. -func (c Collection) Swap(i, j int) { - c[i], c[j] = c[j], c[i] -} diff --git a/vendor/github.com/Masterminds/semver/v3/constraints.go b/vendor/github.com/Masterminds/semver/v3/constraints.go deleted file mode 100644 index 8b7a10f836..0000000000 --- a/vendor/github.com/Masterminds/semver/v3/constraints.go +++ /dev/null @@ -1,601 +0,0 @@ -package semver - -import ( - "bytes" - "errors" - "fmt" - "regexp" - "strings" -) - -// Constraints is one or more constraint that a semantic version can be -// checked against. -type Constraints struct { - constraints [][]*constraint - containsPre []bool - - // IncludePrerelease specifies if pre-releases should be included in - // the results. Note, if a constraint range has a prerelease than - // prereleases will be included for that AND group even if this is - // set to false. - IncludePrerelease bool -} - -// NewConstraint returns a Constraints instance that a Version instance can -// be checked against. If there is a parse error it will be returned. -func NewConstraint(c string) (*Constraints, error) { - - // Rewrite - ranges into a comparison operation. - c = rewriteRange(c) - - ors := strings.Split(c, "||") - lenors := len(ors) - or := make([][]*constraint, lenors) - hasPre := make([]bool, lenors) - for k, v := range ors { - // Validate the segment - if !validConstraintRegex.MatchString(v) { - return nil, fmt.Errorf("improper constraint: %s", v) - } - - cs := findConstraintRegex.FindAllString(v, -1) - if cs == nil { - cs = append(cs, v) - } - result := make([]*constraint, len(cs)) - for i, s := range cs { - pc, err := parseConstraint(s) - if err != nil { - return nil, err - } - - // If one of the constraints has a prerelease record this. - // This information is used when checking all in an "and" - // group to ensure they all check for prereleases. - if pc.con.pre != "" { - hasPre[k] = true - } - - result[i] = pc - } - or[k] = result - } - - o := &Constraints{ - constraints: or, - containsPre: hasPre, - } - return o, nil -} - -// Check tests if a version satisfies the constraints. -func (cs Constraints) Check(v *Version) bool { - // TODO(mattfarina): For v4 of this library consolidate the Check and Validate - // functions as the underlying functions make that possible now. - // loop over the ORs and check the inner ANDs - for i, o := range cs.constraints { - joy := true - for _, c := range o { - if check, _ := c.check(v, (cs.IncludePrerelease || cs.containsPre[i])); !check { - joy = false - break - } - } - - if joy { - return true - } - } - - return false -} - -// Validate checks if a version satisfies a constraint. If not a slice of -// reasons for the failure are returned in addition to a bool. -func (cs Constraints) Validate(v *Version) (bool, []error) { - // loop over the ORs and check the inner ANDs - var e []error - - // Capture the prerelease message only once. When it happens the first time - // this var is marked - var prerelesase bool - for i, o := range cs.constraints { - joy := true - for _, c := range o { - // Before running the check handle the case there the version is - // a prerelease and the check is not searching for prereleases. - if !(cs.IncludePrerelease || cs.containsPre[i]) && v.pre != "" { - if !prerelesase { - em := fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) - e = append(e, em) - prerelesase = true - } - joy = false - - } else { - - if _, err := c.check(v, (cs.IncludePrerelease || cs.containsPre[i])); err != nil { - e = append(e, err) - joy = false - } - } - } - - if joy { - return true, []error{} - } - } - - return false, e -} - -func (cs Constraints) String() string { - buf := make([]string, len(cs.constraints)) - var tmp bytes.Buffer - - for k, v := range cs.constraints { - tmp.Reset() - vlen := len(v) - for kk, c := range v { - tmp.WriteString(c.string()) - - // Space separate the AND conditions - if vlen > 1 && kk < vlen-1 { - tmp.WriteString(" ") - } - } - buf[k] = tmp.String() - } - - return strings.Join(buf, " || ") -} - -// UnmarshalText implements the encoding.TextUnmarshaler interface. -func (cs *Constraints) UnmarshalText(text []byte) error { - temp, err := NewConstraint(string(text)) - if err != nil { - return err - } - - *cs = *temp - - return nil -} - -// MarshalText implements the encoding.TextMarshaler interface. -func (cs Constraints) MarshalText() ([]byte, error) { - return []byte(cs.String()), nil -} - -var constraintOps map[string]cfunc -var constraintRegex *regexp.Regexp -var constraintRangeRegex *regexp.Regexp - -// Used to find individual constraints within a multi-constraint string -var findConstraintRegex *regexp.Regexp - -// Used to validate an segment of ANDs is valid -var validConstraintRegex *regexp.Regexp - -const cvRegex string = `v?([0-9|x|X|\*]+)(\.[0-9|x|X|\*]+)?(\.[0-9|x|X|\*]+)?` + - `(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` + - `(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` - -func init() { - constraintOps = map[string]cfunc{ - "": constraintTildeOrEqual, - "=": constraintTildeOrEqual, - "!=": constraintNotEqual, - ">": constraintGreaterThan, - "<": constraintLessThan, - ">=": constraintGreaterThanEqual, - "=>": constraintGreaterThanEqual, - "<=": constraintLessThanEqual, - "=<": constraintLessThanEqual, - "~": constraintTilde, - "~>": constraintTilde, - "^": constraintCaret, - } - - ops := `=||!=|>|<|>=|=>|<=|=<|~|~>|\^` - - constraintRegex = regexp.MustCompile(fmt.Sprintf( - `^\s*(%s)\s*(%s)\s*$`, - ops, - cvRegex)) - - constraintRangeRegex = regexp.MustCompile(fmt.Sprintf( - `\s*(%s)\s+-\s+(%s)\s*`, - cvRegex, cvRegex)) - - findConstraintRegex = regexp.MustCompile(fmt.Sprintf( - `(%s)\s*(%s)`, - ops, - cvRegex)) - - // The first time a constraint shows up will look slightly different from - // future times it shows up due to a leading space or comma in a given - // string. - validConstraintRegex = regexp.MustCompile(fmt.Sprintf( - `^(\s*(%s)\s*(%s)\s*)((?:\s+|,\s*)(%s)\s*(%s)\s*)*$`, - ops, - cvRegex, - ops, - cvRegex)) -} - -// An individual constraint -type constraint struct { - // The version used in the constraint check. For example, if a constraint - // is '<= 2.0.0' the con a version instance representing 2.0.0. - con *Version - - // The original parsed version (e.g., 4.x from != 4.x) - orig string - - // The original operator for the constraint - origfunc string - - // When an x is used as part of the version (e.g., 1.x) - minorDirty bool - dirty bool - patchDirty bool -} - -// Check if a version meets the constraint -func (c *constraint) check(v *Version, includePre bool) (bool, error) { - return constraintOps[c.origfunc](v, c, includePre) -} - -// String prints an individual constraint into a string -func (c *constraint) string() string { - return c.origfunc + c.orig -} - -type cfunc func(v *Version, c *constraint, includePre bool) (bool, error) - -func parseConstraint(c string) (*constraint, error) { - if len(c) > 0 { - m := constraintRegex.FindStringSubmatch(c) - if m == nil { - return nil, fmt.Errorf("improper constraint: %s", c) - } - - cs := &constraint{ - orig: m[2], - origfunc: m[1], - } - - ver := m[2] - minorDirty := false - patchDirty := false - dirty := false - if isX(m[3]) || m[3] == "" { - ver = fmt.Sprintf("0.0.0%s", m[6]) - dirty = true - } else if isX(strings.TrimPrefix(m[4], ".")) || m[4] == "" { - minorDirty = true - dirty = true - ver = fmt.Sprintf("%s.0.0%s", m[3], m[6]) - } else if isX(strings.TrimPrefix(m[5], ".")) || m[5] == "" { - dirty = true - patchDirty = true - ver = fmt.Sprintf("%s%s.0%s", m[3], m[4], m[6]) - } - - con, err := NewVersion(ver) - if err != nil { - - // The constraintRegex should catch any regex parsing errors. So, - // we should never get here. - return nil, errors.New("constraint parser error") - } - - cs.con = con - cs.minorDirty = minorDirty - cs.patchDirty = patchDirty - cs.dirty = dirty - - return cs, nil - } - - // The rest is the special case where an empty string was passed in which - // is equivalent to * or >=0.0.0 - con, err := StrictNewVersion("0.0.0") - if err != nil { - - // The constraintRegex should catch any regex parsing errors. So, - // we should never get here. - return nil, errors.New("constraint parser error") - } - - cs := &constraint{ - con: con, - orig: c, - origfunc: "", - minorDirty: false, - patchDirty: false, - dirty: true, - } - return cs, nil -} - -// Constraint functions -func constraintNotEqual(v *Version, c *constraint, includePre bool) (bool, error) { - // The existence of prereleases is checked at the group level and passed in. - // Exit early if the version has a prerelease but those are to be ignored. - if v.Prerelease() != "" && !includePre { - return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) - } - - if c.dirty { - if c.con.Major() != v.Major() { - return true, nil - } - if c.con.Minor() != v.Minor() && !c.minorDirty { - return true, nil - } else if c.minorDirty { - return false, fmt.Errorf("%s is equal to %s", v, c.orig) - } else if c.con.Patch() != v.Patch() && !c.patchDirty { - return true, nil - } else if c.patchDirty { - // Need to handle prereleases if present - if v.Prerelease() != "" || c.con.Prerelease() != "" { - eq := comparePrerelease(v.Prerelease(), c.con.Prerelease()) != 0 - if eq { - return true, nil - } - return false, fmt.Errorf("%s is equal to %s", v, c.orig) - } - return false, fmt.Errorf("%s is equal to %s", v, c.orig) - } - } - - eq := v.Equal(c.con) - if eq { - return false, fmt.Errorf("%s is equal to %s", v, c.orig) - } - - return true, nil -} - -func constraintGreaterThan(v *Version, c *constraint, includePre bool) (bool, error) { - - // The existence of prereleases is checked at the group level and passed in. - // Exit early if the version has a prerelease but those are to be ignored. - if v.Prerelease() != "" && !includePre { - return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) - } - - var eq bool - - if !c.dirty { - eq = v.Compare(c.con) == 1 - if eq { - return true, nil - } - return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig) - } - - if v.Major() > c.con.Major() { - return true, nil - } else if v.Major() < c.con.Major() { - return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig) - } else if c.minorDirty { - // This is a range case such as >11. When the version is something like - // 11.1.0 is it not > 11. For that we would need 12 or higher - return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig) - } else if c.patchDirty { - // This is for ranges such as >11.1. A version of 11.1.1 is not greater - // which one of 11.2.1 is greater - eq = v.Minor() > c.con.Minor() - if eq { - return true, nil - } - return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig) - } - - // If we have gotten here we are not comparing pre-preleases and can use the - // Compare function to accomplish that. - eq = v.Compare(c.con) == 1 - if eq { - return true, nil - } - return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig) -} - -func constraintLessThan(v *Version, c *constraint, includePre bool) (bool, error) { - // The existence of prereleases is checked at the group level and passed in. - // Exit early if the version has a prerelease but those are to be ignored. - if v.Prerelease() != "" && !includePre { - return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) - } - - eq := v.Compare(c.con) < 0 - if eq { - return true, nil - } - return false, fmt.Errorf("%s is greater than or equal to %s", v, c.orig) -} - -func constraintGreaterThanEqual(v *Version, c *constraint, includePre bool) (bool, error) { - - // The existence of prereleases is checked at the group level and passed in. - // Exit early if the version has a prerelease but those are to be ignored. - if v.Prerelease() != "" && !includePre { - return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) - } - - eq := v.Compare(c.con) >= 0 - if eq { - return true, nil - } - return false, fmt.Errorf("%s is less than %s", v, c.orig) -} - -func constraintLessThanEqual(v *Version, c *constraint, includePre bool) (bool, error) { - // The existence of prereleases is checked at the group level and passed in. - // Exit early if the version has a prerelease but those are to be ignored. - if v.Prerelease() != "" && !includePre { - return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) - } - - var eq bool - - if !c.dirty { - eq = v.Compare(c.con) <= 0 - if eq { - return true, nil - } - return false, fmt.Errorf("%s is greater than %s", v, c.orig) - } - - if v.Major() > c.con.Major() { - return false, fmt.Errorf("%s is greater than %s", v, c.orig) - } else if v.Major() == c.con.Major() && v.Minor() > c.con.Minor() && !c.minorDirty { - return false, fmt.Errorf("%s is greater than %s", v, c.orig) - } - - return true, nil -} - -// ~*, ~>* --> >= 0.0.0 (any) -// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0, <3.0.0 -// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0, <2.1.0 -// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0, <1.3.0 -// ~1.2.3, ~>1.2.3 --> >=1.2.3, <1.3.0 -// ~1.2.0, ~>1.2.0 --> >=1.2.0, <1.3.0 -func constraintTilde(v *Version, c *constraint, includePre bool) (bool, error) { - // The existence of prereleases is checked at the group level and passed in. - // Exit early if the version has a prerelease but those are to be ignored. - if v.Prerelease() != "" && !includePre { - return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) - } - - if v.LessThan(c.con) { - return false, fmt.Errorf("%s is less than %s", v, c.orig) - } - - // ~0.0.0 is a special case where all constraints are accepted. It's - // equivalent to >= 0.0.0. - if c.con.Major() == 0 && c.con.Minor() == 0 && c.con.Patch() == 0 && - !c.minorDirty && !c.patchDirty { - return true, nil - } - - if v.Major() != c.con.Major() { - return false, fmt.Errorf("%s does not have same major version as %s", v, c.orig) - } - - if v.Minor() != c.con.Minor() && !c.minorDirty { - return false, fmt.Errorf("%s does not have same major and minor version as %s", v, c.orig) - } - - return true, nil -} - -// When there is a .x (dirty) status it automatically opts in to ~. Otherwise -// it's a straight = -func constraintTildeOrEqual(v *Version, c *constraint, includePre bool) (bool, error) { - // The existence of prereleases is checked at the group level and passed in. - // Exit early if the version has a prerelease but those are to be ignored. - if v.Prerelease() != "" && !includePre { - return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) - } - - if c.dirty { - return constraintTilde(v, c, includePre) - } - - eq := v.Equal(c.con) - if eq { - return true, nil - } - - return false, fmt.Errorf("%s is not equal to %s", v, c.orig) -} - -// ^* --> (any) -// ^1.2.3 --> >=1.2.3 <2.0.0 -// ^1.2 --> >=1.2.0 <2.0.0 -// ^1 --> >=1.0.0 <2.0.0 -// ^0.2.3 --> >=0.2.3 <0.3.0 -// ^0.2 --> >=0.2.0 <0.3.0 -// ^0.0.3 --> >=0.0.3 <0.0.4 -// ^0.0 --> >=0.0.0 <0.1.0 -// ^0 --> >=0.0.0 <1.0.0 -func constraintCaret(v *Version, c *constraint, includePre bool) (bool, error) { - // The existence of prereleases is checked at the group level and passed in. - // Exit early if the version has a prerelease but those are to be ignored. - if v.Prerelease() != "" && !includePre { - return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) - } - - // This less than handles prereleases - if v.LessThan(c.con) { - return false, fmt.Errorf("%s is less than %s", v, c.orig) - } - - var eq bool - - // ^ when the major > 0 is >=x.y.z < x+1 - if c.con.Major() > 0 || c.minorDirty { - - // ^ has to be within a major range for > 0. Everything less than was - // filtered out with the LessThan call above. This filters out those - // that greater but not within the same major range. - eq = v.Major() == c.con.Major() - if eq { - return true, nil - } - return false, fmt.Errorf("%s does not have same major version as %s", v, c.orig) - } - - // ^ when the major is 0 and minor > 0 is >=0.y.z < 0.y+1 - if c.con.Major() == 0 && v.Major() > 0 { - return false, fmt.Errorf("%s does not have same major version as %s", v, c.orig) - } - // If the con Minor is > 0 it is not dirty - if c.con.Minor() > 0 || c.patchDirty { - eq = v.Minor() == c.con.Minor() - if eq { - return true, nil - } - return false, fmt.Errorf("%s does not have same minor version as %s. Expected minor versions to match when constraint major version is 0", v, c.orig) - } - // ^ when the minor is 0 and minor > 0 is =0.0.z - if c.con.Minor() == 0 && v.Minor() > 0 { - return false, fmt.Errorf("%s does not have same minor version as %s", v, c.orig) - } - - // At this point the major is 0 and the minor is 0 and not dirty. The patch - // is not dirty so we need to check if they are equal. If they are not equal - eq = c.con.Patch() == v.Patch() - if eq { - return true, nil - } - return false, fmt.Errorf("%s does not equal %s. Expect version and constraint to equal when major and minor versions are 0", v, c.orig) -} - -func isX(x string) bool { - switch x { - case "x", "*", "X": - return true - default: - return false - } -} - -func rewriteRange(i string) string { - m := constraintRangeRegex.FindAllStringSubmatch(i, -1) - if m == nil { - return i - } - o := i - for _, v := range m { - t := fmt.Sprintf(">= %s, <= %s ", v[1], v[11]) - o = strings.Replace(o, v[0], t, 1) - } - - return o -} diff --git a/vendor/github.com/Masterminds/semver/v3/doc.go b/vendor/github.com/Masterminds/semver/v3/doc.go deleted file mode 100644 index 74f97caa57..0000000000 --- a/vendor/github.com/Masterminds/semver/v3/doc.go +++ /dev/null @@ -1,184 +0,0 @@ -/* -Package semver provides the ability to work with Semantic Versions (http://semver.org) in Go. - -Specifically it provides the ability to: - - - Parse semantic versions - - Sort semantic versions - - Check if a semantic version fits within a set of constraints - - Optionally work with a `v` prefix - -# Parsing Semantic Versions - -There are two functions that can parse semantic versions. The `StrictNewVersion` -function only parses valid version 2 semantic versions as outlined in the -specification. The `NewVersion` function attempts to coerce a version into a -semantic version and parse it. For example, if there is a leading v or a version -listed without all 3 parts (e.g. 1.2) it will attempt to coerce it into a valid -semantic version (e.g., 1.2.0). In both cases a `Version` object is returned -that can be sorted, compared, and used in constraints. - -When parsing a version an optional error can be returned if there is an issue -parsing the version. For example, - - v, err := semver.NewVersion("1.2.3-beta.1+b345") - -The version object has methods to get the parts of the version, compare it to -other versions, convert the version back into a string, and get the original -string. For more details please see the documentation -at https://godoc.org/github.com/Masterminds/semver. - -# Sorting Semantic Versions - -A set of versions can be sorted using the `sort` package from the standard library. -For example, - - raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",} - vs := make([]*semver.Version, len(raw)) - for i, r := range raw { - v, err := semver.NewVersion(r) - if err != nil { - t.Errorf("Error parsing version: %s", err) - } - - vs[i] = v - } - - sort.Sort(semver.Collection(vs)) - -# Checking Version Constraints and Comparing Versions - -There are two methods for comparing versions. One uses comparison methods on -`Version` instances and the other is using Constraints. There are some important -differences to notes between these two methods of comparison. - - 1. When two versions are compared using functions such as `Compare`, `LessThan`, - and others it will follow the specification and always include prereleases - within the comparison. It will provide an answer valid with the comparison - spec section at https://semver.org/#spec-item-11 - 2. When constraint checking is used for checks or validation it will follow a - different set of rules that are common for ranges with tools like npm/js - and Rust/Cargo. This includes considering prereleases to be invalid if the - ranges does not include on. If you want to have it include pre-releases a - simple solution is to include `-0` in your range. - 3. Constraint ranges can have some complex rules including the shorthard use of - ~ and ^. For more details on those see the options below. - -There are differences between the two methods or checking versions because the -comparison methods on `Version` follow the specification while comparison ranges -are not part of the specification. Different packages and tools have taken it -upon themselves to come up with range rules. This has resulted in differences. -For example, npm/js and Cargo/Rust follow similar patterns which PHP has a -different pattern for ^. The comparison features in this package follow the -npm/js and Cargo/Rust lead because applications using it have followed similar -patters with their versions. - -Checking a version against version constraints is one of the most featureful -parts of the package. - - c, err := semver.NewConstraint(">= 1.2.3") - if err != nil { - // Handle constraint not being parsable. - } - - v, err := semver.NewVersion("1.3") - if err != nil { - // Handle version not being parsable. - } - // Check if the version meets the constraints. The a variable will be true. - a := c.Check(v) - -# Basic Comparisons - -There are two elements to the comparisons. First, a comparison string is a list -of comma or space separated AND comparisons. These are then separated by || (OR) -comparisons. For example, `">= 1.2 < 3.0.0 || >= 4.2.3"` is looking for a -comparison that's greater than or equal to 1.2 and less than 3.0.0 or is -greater than or equal to 4.2.3. This can also be written as -`">= 1.2, < 3.0.0 || >= 4.2.3"` - -The basic comparisons are: - - - `=`: equal (aliased to no operator) - - `!=`: not equal - - `>`: greater than - - `<`: less than - - `>=`: greater than or equal to - - `<=`: less than or equal to - -# Hyphen Range Comparisons - -There are multiple methods to handle ranges and the first is hyphens ranges. -These look like: - - - `1.2 - 1.4.5` which is equivalent to `>= 1.2, <= 1.4.5` - - `2.3.4 - 4.5` which is equivalent to `>= 2.3.4 <= 4.5` - -# Wildcards In Comparisons - -The `x`, `X`, and `*` characters can be used as a wildcard character. This works -for all comparison operators. When used on the `=` operator it falls -back to the tilde operation. For example, - - - `1.2.x` is equivalent to `>= 1.2.0 < 1.3.0` - - `>= 1.2.x` is equivalent to `>= 1.2.0` - - `<= 2.x` is equivalent to `<= 3` - - `*` is equivalent to `>= 0.0.0` - -Tilde Range Comparisons (Patch) - -The tilde (`~`) comparison operator is for patch level ranges when a minor -version is specified and major level changes when the minor number is missing. -For example, - - - `~1.2.3` is equivalent to `>= 1.2.3 < 1.3.0` - - `~1` is equivalent to `>= 1, < 2` - - `~2.3` is equivalent to `>= 2.3 < 2.4` - - `~1.2.x` is equivalent to `>= 1.2.0 < 1.3.0` - - `~1.x` is equivalent to `>= 1 < 2` - -Caret Range Comparisons (Major) - -The caret (`^`) comparison operator is for major level changes once a stable -(1.0.0) release has occurred. Prior to a 1.0.0 release the minor versions acts -as the API stability level. This is useful when comparisons of API versions as a -major change is API breaking. For example, - - - `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0` - - `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0` - - `^2.3` is equivalent to `>= 2.3, < 3` - - `^2.x` is equivalent to `>= 2.0.0, < 3` - - `^0.2.3` is equivalent to `>=0.2.3 <0.3.0` - - `^0.2` is equivalent to `>=0.2.0 <0.3.0` - - `^0.0.3` is equivalent to `>=0.0.3 <0.0.4` - - `^0.0` is equivalent to `>=0.0.0 <0.1.0` - - `^0` is equivalent to `>=0.0.0 <1.0.0` - -# Validation - -In addition to testing a version against a constraint, a version can be validated -against a constraint. When validation fails a slice of errors containing why a -version didn't meet the constraint is returned. For example, - - c, err := semver.NewConstraint("<= 1.2.3, >= 1.4") - if err != nil { - // Handle constraint not being parseable. - } - - v, _ := semver.NewVersion("1.3") - if err != nil { - // Handle version not being parseable. - } - - // Validate a version against a constraint. - a, msgs := c.Validate(v) - // a is false - for _, m := range msgs { - fmt.Println(m) - - // Loops over the errors which would read - // "1.3 is greater than 1.2.3" - // "1.3 is less than 1.4" - } -*/ -package semver diff --git a/vendor/github.com/Masterminds/semver/v3/version.go b/vendor/github.com/Masterminds/semver/v3/version.go deleted file mode 100644 index 7a3ba73887..0000000000 --- a/vendor/github.com/Masterminds/semver/v3/version.go +++ /dev/null @@ -1,788 +0,0 @@ -package semver - -import ( - "bytes" - "database/sql/driver" - "encoding/json" - "errors" - "fmt" - "regexp" - "strconv" - "strings" -) - -// The compiled version of the regex created at init() is cached here so it -// only needs to be created once. -var versionRegex *regexp.Regexp -var looseVersionRegex *regexp.Regexp - -// CoerceNewVersion sets if leading 0's are allowd in the version part. Leading 0's are -// not allowed in a valid semantic version. When set to true, NewVersion will coerce -// leading 0's into a valid version. -var CoerceNewVersion = true - -// DetailedNewVersionErrors specifies if detailed errors are returned from the NewVersion -// function. This is used when CoerceNewVersion is set to false. If set to false -// ErrInvalidSemVer is returned for an invalid version. This does not apply to -// StrictNewVersion. Setting this function to false returns errors more quickly. -var DetailedNewVersionErrors = true - -var ( - // ErrInvalidSemVer is returned a version is found to be invalid when - // being parsed. - ErrInvalidSemVer = errors.New("invalid semantic version") - - // ErrEmptyString is returned when an empty string is passed in for parsing. - ErrEmptyString = errors.New("version string empty") - - // ErrInvalidCharacters is returned when invalid characters are found as - // part of a version - ErrInvalidCharacters = errors.New("invalid characters in version") - - // ErrSegmentStartsZero is returned when a version segment starts with 0. - // This is invalid in SemVer. - ErrSegmentStartsZero = errors.New("version segment starts with 0") - - // ErrInvalidMetadata is returned when the metadata is an invalid format - ErrInvalidMetadata = errors.New("invalid metadata string") - - // ErrInvalidPrerelease is returned when the pre-release is an invalid format - ErrInvalidPrerelease = errors.New("invalid prerelease string") -) - -// semVerRegex is the regular expression used to parse a semantic version. -// This is not the official regex from the semver spec. It has been modified to allow for loose handling -// where versions like 2.1 are detected. -const semVerRegex string = `v?(0|[1-9]\d*)(?:\.(0|[1-9]\d*))?(?:\.(0|[1-9]\d*))?` + - `(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?` + - `(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?` - -// looseSemVerRegex is a regular expression that lets invalid semver expressions through -// with enough detail that certain errors can be checked for. -const looseSemVerRegex string = `v?([0-9]+)(\.[0-9]+)?(\.[0-9]+)?` + - `(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` + - `(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` - -// Version represents a single semantic version. -type Version struct { - major, minor, patch uint64 - pre string - metadata string - original string -} - -func init() { - versionRegex = regexp.MustCompile("^" + semVerRegex + "$") - looseVersionRegex = regexp.MustCompile("^" + looseSemVerRegex + "$") -} - -const ( - num string = "0123456789" - allowed string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-" + num -) - -// StrictNewVersion parses a given version and returns an instance of Version or -// an error if unable to parse the version. Only parses valid semantic versions. -// Performs checking that can find errors within the version. -// If you want to coerce a version such as 1 or 1.2 and parse it as the 1.x -// releases of semver did, use the NewVersion() function. -func StrictNewVersion(v string) (*Version, error) { - // Parsing here does not use RegEx in order to increase performance and reduce - // allocations. - - if len(v) == 0 { - return nil, ErrEmptyString - } - - // Split the parts into [0]major, [1]minor, and [2]patch,prerelease,build - parts := strings.SplitN(v, ".", 3) - if len(parts) != 3 { - return nil, ErrInvalidSemVer - } - - sv := &Version{ - original: v, - } - - // Extract build metadata - if strings.Contains(parts[2], "+") { - extra := strings.SplitN(parts[2], "+", 2) - sv.metadata = extra[1] - parts[2] = extra[0] - if err := validateMetadata(sv.metadata); err != nil { - return nil, err - } - } - - // Extract build prerelease - if strings.Contains(parts[2], "-") { - extra := strings.SplitN(parts[2], "-", 2) - sv.pre = extra[1] - parts[2] = extra[0] - if err := validatePrerelease(sv.pre); err != nil { - return nil, err - } - } - - // Validate the number segments are valid. This includes only having positive - // numbers and no leading 0's. - for _, p := range parts { - if !containsOnly(p, num) { - return nil, ErrInvalidCharacters - } - - if len(p) > 1 && p[0] == '0' { - return nil, ErrSegmentStartsZero - } - } - - // Extract major, minor, and patch - var err error - sv.major, err = strconv.ParseUint(parts[0], 10, 64) - if err != nil { - return nil, err - } - - sv.minor, err = strconv.ParseUint(parts[1], 10, 64) - if err != nil { - return nil, err - } - - sv.patch, err = strconv.ParseUint(parts[2], 10, 64) - if err != nil { - return nil, err - } - - return sv, nil -} - -// NewVersion parses a given version and returns an instance of Version or -// an error if unable to parse the version. If the version is SemVer-ish it -// attempts to convert it to SemVer. If you want to validate it was a strict -// semantic version at parse time see StrictNewVersion(). -func NewVersion(v string) (*Version, error) { - if CoerceNewVersion { - return coerceNewVersion(v) - } - m := versionRegex.FindStringSubmatch(v) - if m == nil { - - // Disabling detailed errors is first so that it is in the fast path. - if !DetailedNewVersionErrors { - return nil, ErrInvalidSemVer - } - - // Check for specific errors with the semver string and return a more detailed - // error. - m = looseVersionRegex.FindStringSubmatch(v) - if m == nil { - return nil, ErrInvalidSemVer - } - err := validateVersion(m) - if err != nil { - return nil, err - } - return nil, ErrInvalidSemVer - } - - sv := &Version{ - metadata: m[5], - pre: m[4], - original: v, - } - - var err error - sv.major, err = strconv.ParseUint(m[1], 10, 64) - if err != nil { - return nil, fmt.Errorf("error parsing version segment: %w", err) - } - - if m[2] != "" { - sv.minor, err = strconv.ParseUint(m[2], 10, 64) - if err != nil { - return nil, fmt.Errorf("error parsing version segment: %w", err) - } - } else { - sv.minor = 0 - } - - if m[3] != "" { - sv.patch, err = strconv.ParseUint(m[3], 10, 64) - if err != nil { - return nil, fmt.Errorf("error parsing version segment: %w", err) - } - } else { - sv.patch = 0 - } - - // Perform some basic due diligence on the extra parts to ensure they are - // valid. - - if sv.pre != "" { - if err = validatePrerelease(sv.pre); err != nil { - return nil, err - } - } - - if sv.metadata != "" { - if err = validateMetadata(sv.metadata); err != nil { - return nil, err - } - } - - return sv, nil -} - -func coerceNewVersion(v string) (*Version, error) { - m := looseVersionRegex.FindStringSubmatch(v) - if m == nil { - return nil, ErrInvalidSemVer - } - - sv := &Version{ - metadata: m[8], - pre: m[5], - original: v, - } - - var err error - sv.major, err = strconv.ParseUint(m[1], 10, 64) - if err != nil { - return nil, fmt.Errorf("error parsing version segment: %w", err) - } - - if m[2] != "" { - sv.minor, err = strconv.ParseUint(strings.TrimPrefix(m[2], "."), 10, 64) - if err != nil { - return nil, fmt.Errorf("error parsing version segment: %w", err) - } - } else { - sv.minor = 0 - } - - if m[3] != "" { - sv.patch, err = strconv.ParseUint(strings.TrimPrefix(m[3], "."), 10, 64) - if err != nil { - return nil, fmt.Errorf("error parsing version segment: %w", err) - } - } else { - sv.patch = 0 - } - - // Perform some basic due diligence on the extra parts to ensure they are - // valid. - - if sv.pre != "" { - if err = validatePrerelease(sv.pre); err != nil { - return nil, err - } - } - - if sv.metadata != "" { - if err = validateMetadata(sv.metadata); err != nil { - return nil, err - } - } - - return sv, nil -} - -// New creates a new instance of Version with each of the parts passed in as -// arguments instead of parsing a version string. -func New(major, minor, patch uint64, pre, metadata string) *Version { - v := Version{ - major: major, - minor: minor, - patch: patch, - pre: pre, - metadata: metadata, - original: "", - } - - v.original = v.String() - - return &v -} - -// MustParse parses a given version and panics on error. -func MustParse(v string) *Version { - sv, err := NewVersion(v) - if err != nil { - panic(err) - } - return sv -} - -// String converts a Version object to a string. -// Note, if the original version contained a leading v this version will not. -// See the Original() method to retrieve the original value. Semantic Versions -// don't contain a leading v per the spec. Instead it's optional on -// implementation. -func (v Version) String() string { - var buf bytes.Buffer - - fmt.Fprintf(&buf, "%d.%d.%d", v.major, v.minor, v.patch) - if v.pre != "" { - fmt.Fprintf(&buf, "-%s", v.pre) - } - if v.metadata != "" { - fmt.Fprintf(&buf, "+%s", v.metadata) - } - - return buf.String() -} - -// Original returns the original value passed in to be parsed. -func (v *Version) Original() string { - return v.original -} - -// Major returns the major version. -func (v Version) Major() uint64 { - return v.major -} - -// Minor returns the minor version. -func (v Version) Minor() uint64 { - return v.minor -} - -// Patch returns the patch version. -func (v Version) Patch() uint64 { - return v.patch -} - -// Prerelease returns the pre-release version. -func (v Version) Prerelease() string { - return v.pre -} - -// Metadata returns the metadata on the version. -func (v Version) Metadata() string { - return v.metadata -} - -// originalVPrefix returns the original 'v' prefix if any. -func (v Version) originalVPrefix() string { - // Note, only lowercase v is supported as a prefix by the parser. - if v.original != "" && v.original[:1] == "v" { - return v.original[:1] - } - return "" -} - -// IncPatch produces the next patch version. -// If the current version does not have prerelease/metadata information, -// it unsets metadata and prerelease values, increments patch number. -// If the current version has any of prerelease or metadata information, -// it unsets both values and keeps current patch value -func (v Version) IncPatch() Version { - vNext := v - // according to http://semver.org/#spec-item-9 - // Pre-release versions have a lower precedence than the associated normal version. - // according to http://semver.org/#spec-item-10 - // Build metadata SHOULD be ignored when determining version precedence. - if v.pre != "" { - vNext.metadata = "" - vNext.pre = "" - } else { - vNext.metadata = "" - vNext.pre = "" - vNext.patch = v.patch + 1 - } - vNext.original = v.originalVPrefix() + "" + vNext.String() - return vNext -} - -// IncMinor produces the next minor version. -// Sets patch to 0. -// Increments minor number. -// Unsets metadata. -// Unsets prerelease status. -func (v Version) IncMinor() Version { - vNext := v - vNext.metadata = "" - vNext.pre = "" - vNext.patch = 0 - vNext.minor = v.minor + 1 - vNext.original = v.originalVPrefix() + "" + vNext.String() - return vNext -} - -// IncMajor produces the next major version. -// Sets patch to 0. -// Sets minor to 0. -// Increments major number. -// Unsets metadata. -// Unsets prerelease status. -func (v Version) IncMajor() Version { - vNext := v - vNext.metadata = "" - vNext.pre = "" - vNext.patch = 0 - vNext.minor = 0 - vNext.major = v.major + 1 - vNext.original = v.originalVPrefix() + "" + vNext.String() - return vNext -} - -// SetPrerelease defines the prerelease value. -// Value must not include the required 'hyphen' prefix. -func (v Version) SetPrerelease(prerelease string) (Version, error) { - vNext := v - if len(prerelease) > 0 { - if err := validatePrerelease(prerelease); err != nil { - return vNext, err - } - } - vNext.pre = prerelease - vNext.original = v.originalVPrefix() + "" + vNext.String() - return vNext, nil -} - -// SetMetadata defines metadata value. -// Value must not include the required 'plus' prefix. -func (v Version) SetMetadata(metadata string) (Version, error) { - vNext := v - if len(metadata) > 0 { - if err := validateMetadata(metadata); err != nil { - return vNext, err - } - } - vNext.metadata = metadata - vNext.original = v.originalVPrefix() + "" + vNext.String() - return vNext, nil -} - -// LessThan tests if one version is less than another one. -func (v *Version) LessThan(o *Version) bool { - return v.Compare(o) < 0 -} - -// LessThanEqual tests if one version is less or equal than another one. -func (v *Version) LessThanEqual(o *Version) bool { - return v.Compare(o) <= 0 -} - -// GreaterThan tests if one version is greater than another one. -func (v *Version) GreaterThan(o *Version) bool { - return v.Compare(o) > 0 -} - -// GreaterThanEqual tests if one version is greater or equal than another one. -func (v *Version) GreaterThanEqual(o *Version) bool { - return v.Compare(o) >= 0 -} - -// Equal tests if two versions are equal to each other. -// Note, versions can be equal with different metadata since metadata -// is not considered part of the comparable version. -func (v *Version) Equal(o *Version) bool { - if v == o { - return true - } - if v == nil || o == nil { - return false - } - return v.Compare(o) == 0 -} - -// Compare compares this version to another one. It returns -1, 0, or 1 if -// the version smaller, equal, or larger than the other version. -// -// Versions are compared by X.Y.Z. Build metadata is ignored. Prerelease is -// lower than the version without a prerelease. Compare always takes into account -// prereleases. If you want to work with ranges using typical range syntaxes that -// skip prereleases if the range is not looking for them use constraints. -func (v *Version) Compare(o *Version) int { - // Compare the major, minor, and patch version for differences. If a - // difference is found return the comparison. - if d := compareSegment(v.Major(), o.Major()); d != 0 { - return d - } - if d := compareSegment(v.Minor(), o.Minor()); d != 0 { - return d - } - if d := compareSegment(v.Patch(), o.Patch()); d != 0 { - return d - } - - // At this point the major, minor, and patch versions are the same. - ps := v.pre - po := o.Prerelease() - - if ps == "" && po == "" { - return 0 - } - if ps == "" { - return 1 - } - if po == "" { - return -1 - } - - return comparePrerelease(ps, po) -} - -// UnmarshalJSON implements JSON.Unmarshaler interface. -func (v *Version) UnmarshalJSON(b []byte) error { - var s string - if err := json.Unmarshal(b, &s); err != nil { - return err - } - temp, err := NewVersion(s) - if err != nil { - return err - } - v.major = temp.major - v.minor = temp.minor - v.patch = temp.patch - v.pre = temp.pre - v.metadata = temp.metadata - v.original = temp.original - return nil -} - -// MarshalJSON implements JSON.Marshaler interface. -func (v Version) MarshalJSON() ([]byte, error) { - return json.Marshal(v.String()) -} - -// UnmarshalText implements the encoding.TextUnmarshaler interface. -func (v *Version) UnmarshalText(text []byte) error { - temp, err := NewVersion(string(text)) - if err != nil { - return err - } - - *v = *temp - - return nil -} - -// MarshalText implements the encoding.TextMarshaler interface. -func (v Version) MarshalText() ([]byte, error) { - return []byte(v.String()), nil -} - -// Scan implements the SQL.Scanner interface. -func (v *Version) Scan(value interface{}) error { - var s string - s, _ = value.(string) - temp, err := NewVersion(s) - if err != nil { - return err - } - v.major = temp.major - v.minor = temp.minor - v.patch = temp.patch - v.pre = temp.pre - v.metadata = temp.metadata - v.original = temp.original - return nil -} - -// Value implements the Driver.Valuer interface. -func (v Version) Value() (driver.Value, error) { - return v.String(), nil -} - -func compareSegment(v, o uint64) int { - if v < o { - return -1 - } - if v > o { - return 1 - } - - return 0 -} - -func comparePrerelease(v, o string) int { - // split the prelease versions by their part. The separator, per the spec, - // is a . - sparts := strings.Split(v, ".") - oparts := strings.Split(o, ".") - - // Find the longer length of the parts to know how many loop iterations to - // go through. - slen := len(sparts) - olen := len(oparts) - - l := slen - if olen > slen { - l = olen - } - - // Iterate over each part of the prereleases to compare the differences. - for i := 0; i < l; i++ { - // Since the lentgh of the parts can be different we need to create - // a placeholder. This is to avoid out of bounds issues. - stemp := "" - if i < slen { - stemp = sparts[i] - } - - otemp := "" - if i < olen { - otemp = oparts[i] - } - - d := comparePrePart(stemp, otemp) - if d != 0 { - return d - } - } - - // Reaching here means two versions are of equal value but have different - // metadata (the part following a +). They are not identical in string form - // but the version comparison finds them to be equal. - return 0 -} - -func comparePrePart(s, o string) int { - // Fastpath if they are equal - if s == o { - return 0 - } - - // When s or o are empty we can use the other in an attempt to determine - // the response. - if s == "" { - if o != "" { - return -1 - } - return 1 - } - - if o == "" { - if s != "" { - return 1 - } - return -1 - } - - // When comparing strings "99" is greater than "103". To handle - // cases like this we need to detect numbers and compare them. According - // to the semver spec, numbers are always positive. If there is a - at the - // start like -99 this is to be evaluated as an alphanum. numbers always - // have precedence over alphanum. Parsing as Uints because negative numbers - // are ignored. - - oi, n1 := strconv.ParseUint(o, 10, 64) - si, n2 := strconv.ParseUint(s, 10, 64) - - // The case where both are strings compare the strings - if n1 != nil && n2 != nil { - if s > o { - return 1 - } - return -1 - } else if n1 != nil { - // o is a string and s is a number - return -1 - } else if n2 != nil { - // s is a string and o is a number - return 1 - } - // Both are numbers - if si > oi { - return 1 - } - return -1 -} - -// Like strings.ContainsAny but does an only instead of any. -func containsOnly(s string, comp string) bool { - return strings.IndexFunc(s, func(r rune) bool { - return !strings.ContainsRune(comp, r) - }) == -1 -} - -// From the spec, "Identifiers MUST comprise only -// ASCII alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty. -// Numeric identifiers MUST NOT include leading zeroes.". These segments can -// be dot separated. -func validatePrerelease(p string) error { - eparts := strings.Split(p, ".") - for _, p := range eparts { - if p == "" { - return ErrInvalidPrerelease - } else if containsOnly(p, num) { - if len(p) > 1 && p[0] == '0' { - return ErrSegmentStartsZero - } - } else if !containsOnly(p, allowed) { - return ErrInvalidPrerelease - } - } - - return nil -} - -// From the spec, "Build metadata MAY be denoted by -// appending a plus sign and a series of dot separated identifiers immediately -// following the patch or pre-release version. Identifiers MUST comprise only -// ASCII alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty." -func validateMetadata(m string) error { - eparts := strings.Split(m, ".") - for _, p := range eparts { - if p == "" { - return ErrInvalidMetadata - } else if !containsOnly(p, allowed) { - return ErrInvalidMetadata - } - } - return nil -} - -// validateVersion checks for common validation issues but may not catch all errors -func validateVersion(m []string) error { - var err error - var v string - if m[1] != "" { - if len(m[1]) > 1 && m[1][0] == '0' { - return ErrSegmentStartsZero - } - _, err = strconv.ParseUint(m[1], 10, 64) - if err != nil { - return fmt.Errorf("error parsing version segment: %w", err) - } - } - - if m[2] != "" { - v = strings.TrimPrefix(m[2], ".") - if len(v) > 1 && v[0] == '0' { - return ErrSegmentStartsZero - } - _, err = strconv.ParseUint(v, 10, 64) - if err != nil { - return fmt.Errorf("error parsing version segment: %w", err) - } - } - - if m[3] != "" { - v = strings.TrimPrefix(m[3], ".") - if len(v) > 1 && v[0] == '0' { - return ErrSegmentStartsZero - } - _, err = strconv.ParseUint(v, 10, 64) - if err != nil { - return fmt.Errorf("error parsing version segment: %w", err) - } - } - - if m[5] != "" { - if err = validatePrerelease(m[5]); err != nil { - return err - } - } - - if m[8] != "" { - if err = validateMetadata(m[8]); err != nil { - return err - } - } - - return nil -} diff --git a/vendor/github.com/MirrexOne/unqueryvet/.gitignore b/vendor/github.com/MirrexOne/unqueryvet/.gitignore deleted file mode 100644 index bd2a78774c..0000000000 --- a/vendor/github.com/MirrexOne/unqueryvet/.gitignore +++ /dev/null @@ -1,43 +0,0 @@ -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib -/unqueryvet - -# Test binary, built with `go test -c` -*.test - -# Output of the go coverage tool -*.out -coverage.html - -# Dependency directories -vendor/ - -# Go workspace file -go.work -go.work.sum - -# IDE files -.idea/ -.vscode/ -*.swp -*.swo -*~ - -# OS files -.DS_Store -.DS_Store? -._* -.Spotlight-V100 -.Trashes -ehthumbs.db -Thumbs.db - -# Temporary files -*.tmp -*.log -go.work -.golangci.local.yml diff --git a/vendor/github.com/MirrexOne/unqueryvet/LICENSE b/vendor/github.com/MirrexOne/unqueryvet/LICENSE deleted file mode 100644 index 278a61152a..0000000000 --- a/vendor/github.com/MirrexOne/unqueryvet/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2024 MirrexOne - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/vendor/github.com/MirrexOne/unqueryvet/Makefile b/vendor/github.com/MirrexOne/unqueryvet/Makefile deleted file mode 100644 index d92d306811..0000000000 --- a/vendor/github.com/MirrexOne/unqueryvet/Makefile +++ /dev/null @@ -1,93 +0,0 @@ -.PHONY: all test build fmt fmt-check lint clean install help - -# Default target -all: fmt test build - -# Run tests -test: - @echo "Running tests..." - @go test -v -race -coverprofile=coverage.out ./... - -# Build the binary -build: - @echo "Building unqueryvet..." - @go build -v ./cmd/unqueryvet - -# Format code with gofmt -s -fmt: - @echo "Formatting code..." - @find . -name "*.go" -not -path "./vendor/*" -exec gofmt -s -w {} + - @go fmt ./... - -# Check if code is formatted -fmt-check: - @echo "Checking code formatting..." - @if [ -n "$$(find . -name '*.go' -not -path './vendor/*' -exec gofmt -s -l {} +)" ]; then \ - echo "The following files need formatting:"; \ - find . -name '*.go' -not -path './vendor/*' -exec gofmt -s -l {} +; \ - exit 1; \ - else \ - echo "All files are properly formatted"; \ - fi - -# Run linter -lint: - @echo "Running linter..." - @if command -v golangci-lint > /dev/null 2>&1; then \ - ./lint-local.sh ./...; \ - else \ - echo "golangci-lint not installed. Install it from https://golangci-lint.run/usage/install/"; \ - exit 1; \ - fi - -# Clean build artifacts -clean: - @echo "Cleaning..." - @rm -f unqueryvet - @rm -f coverage.out - @rm -f .golangci.local.yml - @go clean - -# Install the binary -install: - @echo "Installing unqueryvet..." - @go install ./cmd/unqueryvet - -# Run unqueryvet on the project itself -check: - @echo "Running unqueryvet on project..." - @go run ./cmd/unqueryvet ./... - -# Generate coverage report -coverage: test - @echo "Generating coverage report..." - @go tool cover -html=coverage.out -o coverage.html - @echo "Coverage report generated: coverage.html" - -# Run benchmarks -bench: - @echo "Running benchmarks..." - @go test -bench=. -benchmem ./internal/analyzer - -# Update dependencies -deps: - @echo "Updating dependencies..." - @go mod tidy - @go mod verify - -# Help target -help: - @echo "Available targets:" - @echo " make - Format, test, and build" - @echo " make test - Run tests with race detection" - @echo " make build - Build the unqueryvet binary" - @echo " make fmt - Format all Go files with gofmt -s" - @echo " make fmt-check - Check if files are formatted" - @echo " make lint - Run golangci-lint" - @echo " make clean - Remove build artifacts" - @echo " make install - Install unqueryvet binary" - @echo " make check - Run unqueryvet on the project" - @echo " make coverage - Generate coverage report" - @echo " make bench - Run benchmarks" - @echo " make deps - Update and verify dependencies" - @echo " make help - Show this help message" diff --git a/vendor/github.com/MirrexOne/unqueryvet/README.md b/vendor/github.com/MirrexOne/unqueryvet/README.md deleted file mode 100644 index 6c00223f74..0000000000 --- a/vendor/github.com/MirrexOne/unqueryvet/README.md +++ /dev/null @@ -1,269 +0,0 @@ -# unqueryvet - -[![Go Report Card](https://goreportcard.com/badge/github.com/MirrexOne/unqueryvet)](https://goreportcard.com/report/github.com/MirrexOne/unqueryvet) -[![GoDoc](https://godoc.org/github.com/MirrexOne/unqueryvet?status.svg)](https://godoc.org/github.com/MirrexOne/unqueryvet) -[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) - -unqueryvet is a Go static analysis tool (linter) that detects `SELECT *` usage in SQL queries and SQL builders, encouraging explicit column selection for better performance, maintainability, and API stability. - -## Features - -- **Detects `SELECT *` in string literals** - Finds problematic queries in your Go code -- **SQL Builder support** - Works with popular SQL builders like Squirrel, GORM, etc. -- **Highly configurable** - Extensive configuration options for different use cases -- **Supports `//nolint:unqueryvet`** - Standard Go linting suppression -- **golangci-lint integration** - Works seamlessly with golangci-lint -- **Zero false positives** - Smart pattern recognition for acceptable `SELECT *` usage -- **Fast and lightweight** - Built on golang.org/x/tools/go/analysis - -## Why avoid `SELECT *`? - -- **Performance**: Selecting unnecessary columns wastes network bandwidth and memory -- **Maintainability**: Schema changes can break your application unexpectedly -- **Security**: May expose sensitive data that shouldn't be returned -- **API Stability**: Adding new columns can break clients that depend on column order - -## Informative Error Messages - -Unqueryvet provides context-specific messages that explain WHY you should avoid `SELECT *`: - -```go -// Basic queries -query := "SELECT * FROM users" -// avoid SELECT * - explicitly specify needed columns for better performance, maintainability and stability - -// SQL Builders -query := squirrel.Select("*").From("users") -// avoid SELECT * in SQL builder - explicitly specify columns to prevent unnecessary data transfer and schema change issues - -// Empty Select() -query := squirrel.Select() -// SQL builder Select() without columns defaults to SELECT * - add specific columns with .Columns() method -``` - -## Quick Start - -### As a standalone tool - -```bash -go install github.com/MirrexOne/unqueryvet/cmd/unqueryvet@latest -unqueryvet ./... -``` - -### With golangci-lint (Recommended) - -Add to your `.golangci.yml`: - -```yaml -linters: - enable: - - unqueryvet - -linters-settings: - unqueryvet: - check-sql-builders: true - # By default, no functions are ignored - minimal configuration - # ignored-functions: - # - "fmt.Printf" - # - "log.Printf" - # allowed-patterns: - # - "SELECT \\* FROM information_schema\\..*" - # - "SELECT \\* FROM pg_catalog\\..*" -``` - -## Examples - -### Problematic code (will trigger warnings) - -```go -// String literals with SELECT * -query := "SELECT * FROM users" -rows, err := db.Query("SELECT * FROM orders WHERE status = ?", "active") - -// SQL builders with SELECT * -query := squirrel.Select("*").From("products") -query := builder.Select().Columns("*").From("inventory") -``` - -### Good code (recommended) - -```go -// Explicit column selection -query := "SELECT id, name, email FROM users" -rows, err := db.Query("SELECT id, total FROM orders WHERE status = ?", "active") - -// SQL builders with explicit columns -query := squirrel.Select("id", "name", "price").From("products") -query := builder.Select().Columns("id", "quantity", "location").From("inventory") -``` - -### Acceptable SELECT * usage (won't trigger warnings) - -```go -// System/meta queries -"SELECT * FROM information_schema.tables" -"SELECT * FROM pg_catalog.pg_tables" - -// Aggregate functions -"SELECT COUNT(*) FROM users" -"SELECT MAX(*) FROM scores" - -// With nolint suppression -query := "SELECT * FROM debug_table" //nolint:unqueryvet -``` - -## Configuration - -Unqueryvet is highly configurable to fit your project's needs: - -```yaml -linters-settings: - unqueryvet: - # Enable/disable SQL builder checking (default: true) - check-sql-builders: true - - # Optional: Functions to ignore during analysis (empty by default - minimal config) - # ignored-functions: - # - "fmt.Printf" - # - "log.Printf" - # - "debug.Query" - - # Optional: Packages to ignore completely (empty by default) - # ignored-packages: - # - "testing" - # - "debug" - - # Default allowed patterns (automatically included): - # - COUNT(*), MAX(*), MIN(*) functions - # - information_schema, pg_catalog, sys schema queries - # You can add more patterns if needed: - # allowed-patterns: - # - "SELECT \\* FROM temp_.*" - - # Default ignored file patterns (automatically included): - # *_test.go, *.pb.go, *_gen.go, *.gen.go, *_generated.go - # You can add more patterns if needed: - # ignored-file-patterns: - # - "my_special_pattern.go" - - # Default ignored directories (automatically included): - # vendor, testdata, migrations, generated, .git, node_modules - # You can add more directories if needed: - # ignored-directories: - # - "my_special_dir" -``` - -## Supported SQL Builders - -Unqueryvet supports popular SQL builders out of the box: - -- **Squirrel** - `squirrel.Select("*")`, `Select().Columns("*")` -- **GORM** - Custom query methods -- **SQLBoiler** - Generated query methods -- **Custom builders** - Any builder using `Select()` patterns - -## Integration Examples - -### GitHub Actions - -```yaml -name: Lint -on: [push, pull_request] -jobs: - lint: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 - with: - go-version: 1.23 - - name: golangci-lint - uses: golangci/golangci-lint-action@v6 - with: - version: latest - args: --enable unqueryvet -``` - -## Command Line Options - -When used as a standalone tool: - -```bash -# Check all packages -unqueryvet ./... - -# Check specific packages -unqueryvet ./cmd/... ./internal/... - -# With custom config file -unqueryvet -config=.unqueryvet.yml ./... - -# Verbose output -unqueryvet -v ./... -``` - -## Performance - -Unqueryvet is designed to be fast and lightweight: - -- **Parallel processing** - Analyzes multiple files concurrently -- **Incremental analysis** - Only analyzes changed files when possible -- **Minimal memory footprint** - Efficient AST traversal -- **Smart caching** - Reuses analysis results when appropriate - -## Advanced Usage - -### Custom Patterns - -You can define custom regex patterns for acceptable `SELECT *` usage: - -```yaml -allowed-patterns: - # Allow SELECT * from temporary tables - - "SELECT \\* FROM temp_\\w+" - # Allow SELECT * in migration scripts - - "SELECT \\* FROM.*-- migration" - # Allow SELECT * for specific schemas - - "SELECT \\* FROM audit\\..+" -``` - -### Integration with Custom SQL Builders - -For custom SQL builders, Unqueryvet looks for these patterns: - -```go -// Method chaining -builder.Select("*") // Direct SELECT * -builder.Select().Columns("*") // Chained SELECT * - -// Variable tracking -query := builder.Select() // Empty select -// If no .Columns() call follows, triggers warning -``` - -### Running Tests - -```bash -go test ./... -go test -race ./... -go test -bench=. ./... -``` - -### Development Setup - -```bash -git clone https://github.com/MirrexOne/unqueryvet.git -cd unqueryvet -go mod tidy -go test ./... -``` - -## License - -MIT License - see [LICENSE](LICENSE) file for details. - -## Support - -- **Bug Reports**: [GitHub Issues](https://github.com/MirrexOne/unqueryvet/issues) - ---- diff --git a/vendor/github.com/MirrexOne/unqueryvet/analyzer.go b/vendor/github.com/MirrexOne/unqueryvet/analyzer.go deleted file mode 100644 index 28c3ba6e84..0000000000 --- a/vendor/github.com/MirrexOne/unqueryvet/analyzer.go +++ /dev/null @@ -1,27 +0,0 @@ -// Package unqueryvet provides a Go static analysis tool that detects SELECT * usage -package unqueryvet - -import ( - "golang.org/x/tools/go/analysis" - - "github.com/MirrexOne/unqueryvet/internal/analyzer" - "github.com/MirrexOne/unqueryvet/pkg/config" -) - -// Analyzer is the main unqueryvet analyzer instance -// This is the primary export that golangci-lint will use -var Analyzer = analyzer.NewAnalyzer() - -// New creates a new instance of the unqueryvet analyzer -func New() *analysis.Analyzer { - return Analyzer -} - -// NewWithConfig creates a new analyzer instance with custom configuration -// This is the recommended way to use unqueryvet with custom settings -func NewWithConfig(cfg *config.UnqueryvetSettings) *analysis.Analyzer { - if cfg == nil { - return Analyzer - } - return analyzer.NewAnalyzerWithSettings(*cfg) -} diff --git a/vendor/github.com/MirrexOne/unqueryvet/config.go b/vendor/github.com/MirrexOne/unqueryvet/config.go deleted file mode 100644 index 03626ad38e..0000000000 --- a/vendor/github.com/MirrexOne/unqueryvet/config.go +++ /dev/null @@ -1,11 +0,0 @@ -package unqueryvet - -import "github.com/MirrexOne/unqueryvet/pkg/config" - -// Settings is a type alias for UnqueryvetSettings from the config package. -type Settings = config.UnqueryvetSettings - -// DefaultSettings returns the default configuration for Unqueryvet. -func DefaultSettings() Settings { - return config.DefaultSettings() -} diff --git a/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/analyzer.go b/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/analyzer.go deleted file mode 100644 index 1627ee144a..0000000000 --- a/vendor/github.com/MirrexOne/unqueryvet/internal/analyzer/analyzer.go +++ /dev/null @@ -1,429 +0,0 @@ -// Package analyzer provides the SQL static analysis implementation for detecting SELECT * usage. -package analyzer - -import ( - "go/ast" - "go/token" - "regexp" - "strconv" - "strings" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/inspector" - - "github.com/MirrexOne/unqueryvet/pkg/config" -) - -const ( - // selectKeyword is the SQL SELECT method name in builders - selectKeyword = "Select" - // columnKeyword is the SQL Column method name in builders - columnKeyword = "Column" - // columnsKeyword is the SQL Columns method name in builders - columnsKeyword = "Columns" - // defaultWarningMessage is the standard warning for SELECT * usage - defaultWarningMessage = "avoid SELECT * - explicitly specify needed columns for better performance, maintainability and stability" -) - -// NewAnalyzer creates the Unqueryvet analyzer with enhanced logic for production use -func NewAnalyzer() *analysis.Analyzer { - return &analysis.Analyzer{ - Name: "unqueryvet", - Doc: "detects SELECT * in SQL queries and SQL builders, preventing performance issues and encouraging explicit column selection", - Run: run, - Requires: []*analysis.Analyzer{inspect.Analyzer}, - } -} - -// NewAnalyzerWithSettings creates analyzer with provided settings for golangci-lint integration -func NewAnalyzerWithSettings(s config.UnqueryvetSettings) *analysis.Analyzer { - return &analysis.Analyzer{ - Name: "unqueryvet", - Doc: "detects SELECT * in SQL queries and SQL builders, preventing performance issues and encouraging explicit column selection", - Run: func(pass *analysis.Pass) (any, error) { - return RunWithConfig(pass, &s) - }, - Requires: []*analysis.Analyzer{inspect.Analyzer}, - } -} - -// RunWithConfig performs analysis with provided configuration -// This is the main entry point for configured analysis -func RunWithConfig(pass *analysis.Pass, cfg *config.UnqueryvetSettings) (any, error) { - insp := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - - // Use provided configuration or default if nil - if cfg == nil { - defaultSettings := config.DefaultSettings() - cfg = &defaultSettings - } - - // Define AST node types we're interested in - nodeFilter := []ast.Node{ - (*ast.CallExpr)(nil), // Function/method calls - (*ast.File)(nil), // Files (for SQL builder analysis) - (*ast.AssignStmt)(nil), // Assignment statements for standalone literals - } - - // Walk through all AST nodes and analyze them - insp.Preorder(nodeFilter, func(n ast.Node) { - - switch node := n.(type) { - case *ast.File: - // Analyze SQL builders only if enabled in configuration - if cfg.CheckSQLBuilders { - analyzeSQLBuilders(pass, node) - } - case *ast.AssignStmt: - // Check assignment statements for standalone SQL literals - checkAssignStmt(pass, node, cfg) - case *ast.CallExpr: - // Analyze function calls for SQL with SELECT * usage - checkCallExpr(pass, node, cfg) - } - }) - - return nil, nil -} - -// run performs the main analysis of Go code files for SELECT * usage -func run(pass *analysis.Pass) (any, error) { - insp := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - - // Define AST node types we're interested in - nodeFilter := []ast.Node{ - (*ast.CallExpr)(nil), // Function/method calls - (*ast.File)(nil), // Files (for SQL builder analysis) - (*ast.AssignStmt)(nil), // Assignment statements for standalone literals - } - - // Always use default settings since passing settings through ResultOf doesn't work reliably - defaultSettings := config.DefaultSettings() - cfg := &defaultSettings - - // Walk through all AST nodes and analyze them - insp.Preorder(nodeFilter, func(n ast.Node) { - - switch node := n.(type) { - case *ast.File: - // Analyze SQL builders only if enabled in configuration - if cfg.CheckSQLBuilders { - analyzeSQLBuilders(pass, node) - } - case *ast.AssignStmt: - // Check assignment statements for standalone SQL literals - checkAssignStmt(pass, node, cfg) - case *ast.CallExpr: - // Analyze function calls for SQL with SELECT * usage - checkCallExpr(pass, node, cfg) - } - }) - - return nil, nil -} - -// checkAssignStmt checks assignment statements for standalone SQL literals -func checkAssignStmt(pass *analysis.Pass, stmt *ast.AssignStmt, cfg *config.UnqueryvetSettings) { - // Check right-hand side expressions for string literals with SELECT * - for _, expr := range stmt.Rhs { - // Only check direct string literals, not function calls - if lit, ok := expr.(*ast.BasicLit); ok && lit.Kind == token.STRING { - content := normalizeSQLQuery(lit.Value) - if isSelectStarQuery(content, cfg) { - pass.Report(analysis.Diagnostic{ - Pos: lit.Pos(), - Message: getWarningMessage(), - }) - } - } - } -} - -// checkCallExpr analyzes function calls for SQL with SELECT * usage -// Includes checking arguments and SQL builders -func checkCallExpr(pass *analysis.Pass, call *ast.CallExpr, cfg *config.UnqueryvetSettings) { - - // Check SQL builders for SELECT * in arguments - if cfg.CheckSQLBuilders && isSQLBuilderSelectStar(call) { - pass.Report(analysis.Diagnostic{ - Pos: call.Pos(), - Message: getDetailedWarningMessage("sql_builder"), - }) - return - } - - // Check function call arguments for strings with SELECT * - for _, arg := range call.Args { - if lit, ok := arg.(*ast.BasicLit); ok && lit.Kind == token.STRING { - content := normalizeSQLQuery(lit.Value) - if isSelectStarQuery(content, cfg) { - pass.Report(analysis.Diagnostic{ - Pos: lit.Pos(), - Message: getWarningMessage(), - }) - } - } - } -} - -// NormalizeSQLQuery normalizes SQL query for analysis with advanced escape sequence handling. -// Exported for testing purposes. -func NormalizeSQLQuery(query string) string { - return normalizeSQLQuery(query) -} - -func normalizeSQLQuery(query string) string { - if len(query) < 2 { - return query - } - - first, last := query[0], query[len(query)-1] - - // 1. Handle different quote types with escape sequence processing - if first == '"' && last == '"' { - // For regular strings check for escape sequences - if !strings.Contains(query, "\\") { - query = trimQuotes(query) - } else if unquoted, err := strconv.Unquote(query); err == nil { - // Use standard Go unquoting for proper escape sequence handling - query = unquoted - } else { - // Fallback: simple quote removal - query = trimQuotes(query) - } - } else if first == '`' && last == '`' { - // Raw strings - simply remove backticks - query = trimQuotes(query) - } - - // 2. Process comments line by line before normalization - lines := strings.Split(query, "\n") - var processedParts []string - - for _, line := range lines { - // Remove comments from current line - if idx := strings.Index(line, "--"); idx != -1 { - line = line[:idx] - } - - // Add non-empty lines - if trimmed := strings.TrimSpace(line); trimmed != "" { - processedParts = append(processedParts, trimmed) - } - } - - // 3. Reassemble query and normalize - query = strings.Join(processedParts, " ") - query = strings.ToUpper(query) - query = strings.ReplaceAll(query, "\t", " ") - query = regexp.MustCompile(`\s+`).ReplaceAllString(query, " ") - - return strings.TrimSpace(query) -} - -// trimQuotes removes first and last character (quotes) -func trimQuotes(query string) string { - return query[1 : len(query)-1] -} - -// IsSelectStarQuery determines if query contains SELECT * with enhanced allowed patterns support. -// Exported for testing purposes. -func IsSelectStarQuery(query string, cfg *config.UnqueryvetSettings) bool { - return isSelectStarQuery(query, cfg) -} - -func isSelectStarQuery(query string, cfg *config.UnqueryvetSettings) bool { - // Check allowed patterns first - if query matches an allowed pattern, ignore it - for _, pattern := range cfg.AllowedPatterns { - if matched, _ := regexp.MatchString(pattern, query); matched { - return false - } - } - - // Check for SELECT * in query (case-insensitive) - upperQuery := strings.ToUpper(query) - if strings.Contains(upperQuery, "SELECT *") { //nolint:unqueryvet - // Ensure this is actually an SQL query by checking for SQL keywords - sqlKeywords := []string{"FROM", "WHERE", "JOIN", "GROUP", "ORDER", "HAVING", "UNION", "LIMIT"} - for _, keyword := range sqlKeywords { - if strings.Contains(upperQuery, keyword) { - return true - } - } - - // Also check if it's just "SELECT *" without other keywords (still problematic) - trimmed := strings.TrimSpace(upperQuery) - if trimmed == "SELECT *" { - return true - } - } - return false -} - -// getWarningMessage returns informative warning message -func getWarningMessage() string { - return defaultWarningMessage -} - -// getDetailedWarningMessage returns context-specific warning message -func getDetailedWarningMessage(context string) string { - switch context { - case "sql_builder": - return "avoid SELECT * in SQL builder - explicitly specify columns to prevent unnecessary data transfer and schema change issues" - case "nested": - return "avoid SELECT * in subquery - can cause performance issues and unexpected results when schema changes" - case "empty_select": - return "SQL builder Select() without columns defaults to SELECT * - add specific columns with .Columns() method" - default: - return defaultWarningMessage - } -} - -// isSQLBuilderSelectStar checks SQL builder method calls for SELECT * usage -func isSQLBuilderSelectStar(call *ast.CallExpr) bool { - fun, ok := call.Fun.(*ast.SelectorExpr) - if !ok { - return false - } - - // Check that this is a Select method call - if fun.Sel == nil || fun.Sel.Name != selectKeyword { - return false - } - - if len(call.Args) == 0 { - return false - } - - // Check Select method arguments for "*" or empty strings - for _, arg := range call.Args { - if lit, ok := arg.(*ast.BasicLit); ok && lit.Kind == token.STRING { - value := strings.Trim(lit.Value, "`\"") - // Consider both "*" and empty strings in Select() as problematic - if value == "*" || value == "" { - return true - } - } - } - - return false -} - -// analyzeSQLBuilders performs advanced SQL builder analysis -// Key logic for handling edge-cases like Select().Columns("*") -func analyzeSQLBuilders(pass *analysis.Pass, file *ast.File) { - // Track SQL builder variables and their state - builderVars := make(map[string]*ast.CallExpr) // Variables with empty Select() calls - hasColumns := make(map[string]bool) // Flag: were columns added for variable - - // First pass: find variables created with empty Select() calls - ast.Inspect(file, func(n ast.Node) bool { - switch node := n.(type) { - case *ast.AssignStmt: - // Analyze assignments like: query := builder.Select() - for i, expr := range node.Rhs { - if call, ok := expr.(*ast.CallExpr); ok { - if isEmptySelectCall(call) { - // Found empty Select() call, remember the variable - if i < len(node.Lhs) { - if ident, ok := node.Lhs[i].(*ast.Ident); ok { - builderVars[ident.Name] = call - hasColumns[ident.Name] = false - } - } - } - } - } - } - return true - }) - - // Second pass: check usage of Columns/Column methods - ast.Inspect(file, func(n ast.Node) bool { - switch node := n.(type) { - case *ast.CallExpr: - if sel, ok := node.Fun.(*ast.SelectorExpr); ok { - // Check calls to Columns() or Column() methods - if sel.Sel != nil && (sel.Sel.Name == columnsKeyword || sel.Sel.Name == columnKeyword) { - // Check for "*" in arguments - if hasStarInColumns(node) { - pass.Report(analysis.Diagnostic{ - Pos: node.Pos(), - Message: getDetailedWarningMessage("sql_builder"), - }) - } - - // Update variable state - columns were added - if ident, ok := sel.X.(*ast.Ident); ok { - if _, exists := builderVars[ident.Name]; exists { - if !hasStarInColumns(node) { - hasColumns[ident.Name] = true - } - } - } - } - } - - // Check call chains like builder.Select().Columns("*") - if isSelectWithColumns(node) { - if hasStarInColumns(node) { - if sel, ok := node.Fun.(*ast.SelectorExpr); ok && sel.Sel != nil { - pass.Report(analysis.Diagnostic{ - Pos: node.Pos(), - Message: getDetailedWarningMessage("sql_builder"), - }) - } - } - return true - } - } - return true - }) - - // Final check: warn about builders with empty Select() without subsequent columns - for varName, call := range builderVars { - if !hasColumns[varName] { - pass.Report(analysis.Diagnostic{ - Pos: call.Pos(), - Message: getDetailedWarningMessage("empty_select"), - }) - } - } -} - -// isEmptySelectCall checks if call is an empty Select() -func isEmptySelectCall(call *ast.CallExpr) bool { - if sel, ok := call.Fun.(*ast.SelectorExpr); ok { - if sel.Sel != nil && sel.Sel.Name == selectKeyword && len(call.Args) == 0 { - return true - } - } - return false -} - -// isSelectWithColumns checks call chains like Select().Columns() -func isSelectWithColumns(call *ast.CallExpr) bool { - if sel, ok := call.Fun.(*ast.SelectorExpr); ok { - if sel.Sel != nil && (sel.Sel.Name == columnsKeyword || sel.Sel.Name == columnKeyword) { - // Check that previous call in chain is Select() - if innerCall, ok := sel.X.(*ast.CallExpr); ok { - return isEmptySelectCall(innerCall) - } - } - } - return false -} - -// hasStarInColumns checks if call arguments contain "*" symbol -func hasStarInColumns(call *ast.CallExpr) bool { - for _, arg := range call.Args { - if lit, ok := arg.(*ast.BasicLit); ok && lit.Kind == token.STRING { - value := strings.Trim(lit.Value, "`\"") - if value == "*" { - return true - } - } - } - return false -} diff --git a/vendor/github.com/MirrexOne/unqueryvet/pkg/config/config.go b/vendor/github.com/MirrexOne/unqueryvet/pkg/config/config.go deleted file mode 100644 index 034c324d1d..0000000000 --- a/vendor/github.com/MirrexOne/unqueryvet/pkg/config/config.go +++ /dev/null @@ -1,27 +0,0 @@ -// Package config provides configuration structures for Unqueryvet analyzer. -package config - -// UnqueryvetSettings holds the configuration for the Unqueryvet analyzer. -type UnqueryvetSettings struct { - // CheckSQLBuilders enables checking SQL builders like Squirrel for SELECT * usage - CheckSQLBuilders bool `mapstructure:"check-sql-builders" json:"check-sql-builders" yaml:"check-sql-builders"` - - // AllowedPatterns is a list of regex patterns that are allowed to use SELECT * - // Example: ["SELECT \\* FROM temp_.*", "SELECT \\* FROM .*_backup"] - AllowedPatterns []string `mapstructure:"allowed-patterns" json:"allowed-patterns" yaml:"allowed-patterns"` -} - -// DefaultSettings returns the default configuration for unqueryvet -func DefaultSettings() UnqueryvetSettings { - return UnqueryvetSettings{ - CheckSQLBuilders: true, - AllowedPatterns: []string{ - `(?i)COUNT\(\s*\*\s*\)`, - `(?i)MAX\(\s*\*\s*\)`, - `(?i)MIN\(\s*\*\s*\)`, - `(?i)SELECT \* FROM information_schema\..*`, - `(?i)SELECT \* FROM pg_catalog\..*`, - `(?i)SELECT \* FROM sys\..*`, - }, - } -} diff --git a/vendor/github.com/OpenPeeDeeP/depguard/v2/.gitignore b/vendor/github.com/OpenPeeDeeP/depguard/v2/.gitignore deleted file mode 100644 index e189bdb220..0000000000 --- a/vendor/github.com/OpenPeeDeeP/depguard/v2/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib - -# Test binary, build with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -.idea -.null-ls*.go diff --git a/vendor/github.com/OpenPeeDeeP/depguard/v2/LICENSE b/vendor/github.com/OpenPeeDeeP/depguard/v2/LICENSE deleted file mode 100644 index 94a9ed024d..0000000000 --- a/vendor/github.com/OpenPeeDeeP/depguard/v2/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/vendor/github.com/OpenPeeDeeP/depguard/v2/README.md b/vendor/github.com/OpenPeeDeeP/depguard/v2/README.md deleted file mode 100644 index 0bf603b2bc..0000000000 --- a/vendor/github.com/OpenPeeDeeP/depguard/v2/README.md +++ /dev/null @@ -1,181 +0,0 @@ -# Depguard - -A Go linter that checks package imports are in a list of acceptable packages. -This allows you to allow imports from a whole organization or only -allow specific packages within a repository. - -## Install - -```bash -go install github.com/OpenPeeDeeP/depguard/cmd/depguard@latest -``` - -## Config - -The Depguard binary looks for a file named `^\.?depguard\.(yaml|yml|json|toml)$` in the current working directory. Examples include (`.depguard.yml` or `depguard.toml`). - -The following is an example configuration file. - -```json -{ - "main": { - "files": [ - "$all", - "!$test" - ], - "listMode": "Strict", - "allow": [ - "$gostd", - "github.com/OpenPeeDeeP" - ], - "deny": { - "reflect": "Who needs reflection", - } - }, - "tests": { - "files": [ - "$test" - ], - "listMode": "Lax", - "deny": { - "github.com/stretchr/testify": "Please use standard library for tests" - } - } -} -``` - -- The top level is a map of lists. The key of the map is a name that shows up in -the linter's output. -- `files` - list of file globs that will match this list of settings to compare against -- `allow` - list of allowed packages -- `deny` - map of packages that are not allowed where the value is a suggestion -- `listMode` - the mode to use for package matching - -Files are matched using [Globs](https://github.com/gobwas/glob). If the files -list is empty, then all files will match that list. Prefixing a file -with an exclamation mark `!` will put that glob in a "don't match" list. A file -will match a list if it is allowed and not denied. - -> Should always prefix a file glob with `**/` as files are matched against absolute paths. - -Allow is a prefix of packages to allow. A dollar sign `$` can be used at the end -of a package to specify it must be exact match only. - -Deny is a map where the key is a prefix of the package to deny, and the value -is a suggestion on what to use instead. A dollar sign `$` can be used at the end -of a package to specify it must be exact match only. - -A Prefix List just means that a package will match a value, if the value is a -prefix of the package. Example `github.com/OpenPeeDeeP/depguard` package will match -a value of `github.com/OpenPeeDeeP` but won't match `github.com/OpenPeeDeeP/depguard/v2`. - -ListMode is used to determine the package matching priority. There are three -different modes; Original, Strict, and Lax. - -Original is the original way that the package was written to use. It is not recommended -to stay with this and is only here for backwards compatibility. - -Strict, at its roots, is everything is denied unless in allowed. - -Lax, at its roots, is everything is allowed unless it is denied. - -There are cases where a package can be matched in both the allow and denied lists. -You may allow a subpackage but deny the root or vice versa. The `settings_tests.go` file -has many scenarios listed out under `TestListImportAllowed`. These tests will stay -up to date as features are added. - -### Variables - -There are variable replacements for each type of list (file or package). This is -to reduce repetition and tedious behaviors. - -#### File Variables - -> you can still use an exclamation mark `!` in front of a variable to say not to -use it. Example `!$test` will match any file that is not a go test file. - -- `$all` - matches all go files -- `$test` - matches all go test files - -#### Package Variables - -- `$gostd` - matches all of go's standard library (Pulled from GOROOT) - -### Example Configs - -Below: - -- non-test go files will match `Main` and test go files will match `Test`. -- both allow all of go standard library except for the `reflect` package which will -tell the user "Please don't use reflect package". -- go test files are also allowed to use https://github.com/stretchr/testify package -and any sub-package of it. - -```yaml -Main: - files: - - $all - - "!$test" - allow: - - $gostd - deny: - reflect: Please don't use reflect package -Test: - files: - - $test - allow: - - $gostd - - github.com/stretchr/testify - deny: - reflect: Please don't use reflect package -``` - -Below: - -- All go files will match `Main` -- Go files in internal will match both `Main` and `Internal` - -```yaml -Main: - files: - - $all -Internal: - files: - - "**/internal/**/*.go" -``` - -Below: - -- All packages are allowed except for `github.com/OpenPeeDeeP/depguard`. Though -`github.com/OpenPeeDeeP/depguard/v2` and `github.com/OpenPeeDeeP/depguard/somepackage` -would be allowed. - -```yaml -Main: - deny: - github.com/OpenPeeDeeP/depguard$: Please use v2 -``` - -## golangci-lint - -This linter was built with -[golangci-lint](https://github.com/golangci/golangci-lint) in mind, read the [linters docs](https://golangci-lint.run/usage/linters/#depguard) to see how to configure all their linters, including this one. - -The config is similar to the YAML depguard config documented above, however due to [golangci-lint limitation](https://github.com/golangci/golangci-lint/pull/4227) the `deny` value must be provided as a list, with `pkg` and `desc` keys (otherwise a [panic](https://github.com/OpenPeeDeeP/depguard/issues/74) may occur): - -```yaml -# golangci-lint config -linters-settings: - depguard: - rules: - prevent_unmaintained_packages: - list-mode: lax # allow unless explicitely denied - files: - - $all - - "!$test" - allow: - - $gostd - deny: - - pkg: io/ioutil - desc: "replaced by io and os packages since Go 1.16: https://tip.golang.org/doc/go1.16#ioutil" -``` diff --git a/vendor/github.com/OpenPeeDeeP/depguard/v2/depguard.go b/vendor/github.com/OpenPeeDeeP/depguard/v2/depguard.go deleted file mode 100644 index af07b9bb6f..0000000000 --- a/vendor/github.com/OpenPeeDeeP/depguard/v2/depguard.go +++ /dev/null @@ -1,95 +0,0 @@ -package depguard - -import ( - "fmt" - "go/ast" - "path/filepath" - "strings" - - "golang.org/x/tools/go/analysis" -) - -// NewAnalyzer creates a new analyzer from the settings passed in. -// This can fail if the passed in LinterSettings does not compile. -// Use NewUncompiledAnalyzer if you need control when the compile happens. -func NewAnalyzer(settings *LinterSettings) (*analysis.Analyzer, error) { - s, err := settings.compile() - if err != nil { - return nil, err - } - analyzer := newAnalyzer(s.run) - return analyzer, nil -} - -type UncompiledAnalyzer struct { - Analyzer *analysis.Analyzer - settings *LinterSettings -} - -// NewUncompiledAnalyzer creates a new analyzer from the settings passed in. -// This can never error unlike NewAnalyzer. -// It is advised to call the Compile method on the returned Analyzer before running. -func NewUncompiledAnalyzer(settings *LinterSettings) *UncompiledAnalyzer { - return &UncompiledAnalyzer{ - Analyzer: newAnalyzer(settings.run), - settings: settings, - } -} - -// Compile the settings ahead of time so each subsuquent run of the analyzer doesn't -// need to do this work. -func (ua *UncompiledAnalyzer) Compile() error { - s, err := ua.settings.compile() - if err != nil { - return err - } - ua.Analyzer.Run = s.run - return nil -} - -func (s LinterSettings) run(pass *analysis.Pass) (interface{}, error) { - settings, err := s.compile() - if err != nil { - return nil, err - } - return settings.run(pass) -} - -func newAnalyzer(run func(*analysis.Pass) (interface{}, error)) *analysis.Analyzer { - return &analysis.Analyzer{ - Name: "depguard", - Doc: "Go linter that checks if package imports are in a list of acceptable packages", - URL: "https://github.com/OpenPeeDeeP/depguard", - Run: run, - RunDespiteErrors: false, - } -} - -func (s linterSettings) run(pass *analysis.Pass) (interface{}, error) { - for _, file := range pass.Files { - // For Windows need to replace separator with '/' - fileName := filepath.ToSlash(pass.Fset.Position(file.Pos()).Filename) - lists := s.whichLists(fileName) - for _, imp := range file.Imports { - for _, l := range lists { - if allowed, sugg := l.importAllowed(rawBasicLit(imp.Path)); !allowed { - diag := analysis.Diagnostic{ - Pos: imp.Pos(), - End: imp.End(), - Message: fmt.Sprintf("import '%s' is not allowed from list '%s'", rawBasicLit(imp.Path), l.name), - } - if sugg != "" { - diag.Message = fmt.Sprintf("%s: %s", diag.Message, sugg) - diag.SuggestedFixes = append(diag.SuggestedFixes, analysis.SuggestedFix{Message: sugg}) - } - pass.Report(diag) - } - } - } - } - return nil, nil -} - -func rawBasicLit(lit *ast.BasicLit) string { - return strings.Trim(lit.Value, "\"") -} diff --git a/vendor/github.com/OpenPeeDeeP/depguard/v2/internal/utils/errors.go b/vendor/github.com/OpenPeeDeeP/depguard/v2/internal/utils/errors.go deleted file mode 100644 index 65325f6128..0000000000 --- a/vendor/github.com/OpenPeeDeeP/depguard/v2/internal/utils/errors.go +++ /dev/null @@ -1,18 +0,0 @@ -package utils - -import ( - "strings" -) - -type MultiError []error - -func (me MultiError) Error() string { - b := strings.Builder{} - for i, e := range me { - b.WriteString(e.Error()) - if i < len(me)-1 { - b.WriteByte('\n') - } - } - return b.String() -} diff --git a/vendor/github.com/OpenPeeDeeP/depguard/v2/internal/utils/variables.go b/vendor/github.com/OpenPeeDeeP/depguard/v2/internal/utils/variables.go deleted file mode 100644 index 3363bd8400..0000000000 --- a/vendor/github.com/OpenPeeDeeP/depguard/v2/internal/utils/variables.go +++ /dev/null @@ -1,131 +0,0 @@ -package utils - -import ( - "fmt" - "os" - "os/exec" - "path" - "path/filepath" - "runtime" - "strings" -) - -type Expander interface { - Expand() ([]string, error) -} - -type ExpanderMap map[string]Expander - -var ( - PathExpandable = ExpanderMap{ - "$all": &allExpander{}, - "$test": &testExpander{}, - } - PackageExpandable = ExpanderMap{ - "$gostd": &gostdExpander{}, - } -) - -type allExpander struct{} - -func (*allExpander) Expand() ([]string, error) { - return []string{"**/*.go"}, nil -} - -type testExpander struct{} - -func (*testExpander) Expand() ([]string, error) { - return []string{"**/*_test.go"}, nil -} - -type gostdExpander struct { - cache []string -} - -// We can do this as all imports that are not root are either prefixed with a domain -// or prefixed with `./` or `/` to dictate it is a local file reference -func (e *gostdExpander) Expand() ([]string, error) { - if len(e.cache) != 0 { - return e.cache, nil - } - root := path.Join(findGOROOT(), "src") - fs, err := os.ReadDir(root) - if err != nil { - return nil, fmt.Errorf("could not read GOROOT directory: %w", err) - } - var pkgPrefix []string - for _, f := range fs { - if !f.IsDir() { - continue - } - pkgPrefix = append(pkgPrefix, f.Name()) - } - e.cache = pkgPrefix - return pkgPrefix, nil -} - -func findGOROOT() string { - // code borrowed from https://github.com/golang/tools/blob/86c93e8732cce300d0270bce23117456ce92bb17/cmd/godoc/goroot.go#L15-L30 - if env := os.Getenv("GOROOT"); env != "" { - return filepath.Clean(env) - } - def := filepath.Clean(runtime.GOROOT()) - if runtime.Compiler == "gccgo" { - // gccgo has no real GOROOT, and it certainly doesn't - // depend on the executable's location. - return def - } - out, err := exec.Command("go", "env", "GOROOT").Output() - if err != nil { - return def - } - return strings.TrimSpace(string(out)) -} - -func ExpandSlice(sl []string, exp ExpanderMap) ([]string, error) { - for i, s := range sl { - f, found := exp[s] - if !found { - continue - } - e, err := f.Expand() - if err != nil { - return nil, fmt.Errorf("couldn't expand %s: %w", s, err) - } - sl = insertSlice(sl, i, e...) - } - return sl, nil -} - -func ExpandMap(m map[string]string, exp ExpanderMap) error { - for k, v := range m { - f, found := exp[k] - if !found { - continue - } - e, err := f.Expand() - if err != nil { - return fmt.Errorf("couldn't expand %s: %w", k, err) - } - for _, ex := range e { - m[ex] = v - } - delete(m, k) - } - return nil -} - -func insertSlice(a []string, k int, b ...string) []string { - n := len(a) + len(b) - 1 - if n <= cap(a) { - a2 := a[:n] - copy(a2[k+len(b):], a[k+1:]) - copy(a2[k:], b) - return a2 - } - a2 := make([]string, n) - copy(a2, a[:k]) - copy(a2[k:], b) - copy(a2[k+len(b):], a[k+1:]) - return a2 -} diff --git a/vendor/github.com/OpenPeeDeeP/depguard/v2/settings.go b/vendor/github.com/OpenPeeDeeP/depguard/v2/settings.go deleted file mode 100644 index 5bc74f8d07..0000000000 --- a/vendor/github.com/OpenPeeDeeP/depguard/v2/settings.go +++ /dev/null @@ -1,248 +0,0 @@ -package depguard - -import ( - "errors" - "fmt" - "sort" - "strings" - - "github.com/OpenPeeDeeP/depguard/v2/internal/utils" - "github.com/gobwas/glob" -) - -type List struct { - ListMode string `json:"listMode" yaml:"listMode" toml:"listMode" mapstructure:"listMode"` - Files []string `json:"files" yaml:"files" toml:"files" mapstructure:"files"` - Allow []string `json:"allow" yaml:"allow" toml:"allow" mapstructure:"allow"` - Deny map[string]string `json:"deny" yaml:"deny" toml:"deny" mapstructure:"deny"` -} - -type listMode int - -const ( - listModeOriginal listMode = iota - listModeStrict - listModeLax -) - -type list struct { - listMode listMode - name string - files []glob.Glob - negFiles []glob.Glob - allow []string - deny []string - suggestions []string -} - -func (l *List) compile() (*list, error) { - if l == nil { - return nil, nil - } - li := &list{} - var errs utils.MultiError - var err error - - // Determine List Mode - switch strings.ToLower(l.ListMode) { - case "": - li.listMode = listModeOriginal - case "original": - li.listMode = listModeOriginal - case "strict": - li.listMode = listModeStrict - case "lax": - li.listMode = listModeLax - default: - errs = append(errs, fmt.Errorf("%s is not a known list mode", l.ListMode)) - } - - // Compile Files - for _, f := range l.Files { - var negate bool - if len(f) > 0 && f[0] == '!' { - negate = true - f = f[1:] - } - // Expand File if needed - fs, err := utils.ExpandSlice([]string{f}, utils.PathExpandable) - if err != nil { - errs = append(errs, err) - } - for _, exp := range fs { - g, err := glob.Compile(exp, '/') - if err != nil { - errs = append(errs, fmt.Errorf("%s could not be compiled: %w", exp, err)) - continue - } - if negate { - li.negFiles = append(li.negFiles, g) - continue - } - li.files = append(li.files, g) - } - } - - if len(l.Allow) > 0 { - // Expand Allow - l.Allow, err = utils.ExpandSlice(l.Allow, utils.PackageExpandable) - if err != nil { - errs = append(errs, err) - } - - // Sort Allow - li.allow = make([]string, len(l.Allow)) - copy(li.allow, l.Allow) - sort.Strings(li.allow) - } - - if l.Deny != nil { - // Expand Deny Map (to keep suggestions) - err = utils.ExpandMap(l.Deny, utils.PackageExpandable) - if err != nil { - errs = append(errs, err) - } - - // Split Deny Into Package Slice - li.deny = make([]string, 0, len(l.Deny)) - for pkg := range l.Deny { - li.deny = append(li.deny, pkg) - } - - // Sort Deny - sort.Strings(li.deny) - - // Populate Suggestions to match the Deny order - li.suggestions = make([]string, 0, len(li.deny)) - for _, dp := range li.deny { - li.suggestions = append(li.suggestions, strings.TrimSpace(l.Deny[dp])) - } - } - - // Populate the type of this list - if len(li.allow) == 0 && len(li.deny) == 0 { - errs = append(errs, errors.New("must have an Allow and/or Deny package list")) - } - - if len(errs) > 0 { - return nil, errs - } - return li, nil -} - -func (l *list) fileMatch(fileName string) bool { - inAllowed := len(l.files) == 0 || strInGlobList(fileName, l.files) - inDenied := strInGlobList(fileName, l.negFiles) - return inAllowed && !inDenied -} - -func (l *list) importAllowed(imp string) (bool, string) { - inAllowed, aIdx := strInPrefixList(imp, l.allow) - inDenied, dIdx := strInPrefixList(imp, l.deny) - var allowed bool - switch l.listMode { - case listModeOriginal: - inAllowed = len(l.allow) == 0 || inAllowed - allowed = inAllowed && !inDenied - case listModeStrict: - allowed = inAllowed && (!inDenied || len(l.allow[aIdx]) > len(l.deny[dIdx])) - case listModeLax: - allowed = !inDenied || (inAllowed && len(l.allow[aIdx]) > len(l.deny[dIdx])) - default: - allowed = false - } - sugg := "" - if !allowed && inDenied && dIdx != -1 { - sugg = l.suggestions[dIdx] - } - return allowed, sugg -} - -type LinterSettings map[string]*List - -type linterSettings []*list - -func (l LinterSettings) compile() (linterSettings, error) { - if len(l) == 0 { - // Only allow $gostd in all files - set := &List{ - Files: []string{"$all"}, - Allow: []string{"$gostd"}, - } - li, err := set.compile() - if err != nil { - return nil, err - } - li.name = "Main" - return linterSettings{li}, nil - } - names := make([]string, 0, len(l)) - for name := range l { - names = append(names, name) - } - sort.Strings(names) - li := make(linterSettings, 0, len(l)) - var errs utils.MultiError - for _, name := range names { - c, err := l[name].compile() - if err != nil { - errs = append(errs, err) - continue - } - if c == nil { - continue - } - c.name = name - li = append(li, c) - } - if len(errs) > 0 { - return nil, errs - } - - return li, nil -} - -func (s linterSettings) whichLists(fileName string) []*list { - var matches []*list - for _, l := range s { - if l.fileMatch(fileName) { - matches = append(matches, l) - } - } - return matches -} - -func strInGlobList(str string, globList []glob.Glob) bool { - for _, g := range globList { - if g.Match(str) { - return true - } - } - return false -} - -func strInPrefixList(str string, prefixList []string) (bool, int) { - // Idx represents where in the prefix slice the passed in string would go - // when sorted. -1 Just means that it would be at the very front of the slice. - idx := sort.Search(len(prefixList), func(i int) bool { - return strings.TrimRight(prefixList[i], "$") > str - }) - 1 - // This means that the string passed in has no way to be prefixed by anything - // in the prefix list as it is already smaller then everything - if idx == -1 { - return false, idx - } - ioc := prefixList[idx] - if ioc[len(ioc)-1] == '$' { - return str == ioc[:len(ioc)-1], idx - } - - // There is no sep chars in ioc so it is a GOROOT import that is being matched to the import (str) (see $gostd expander) - // AND the import contains a period which GOROOT cannot have. This eliminates the go.evil.me/pkg scenario - // BUT should still allow /os/exec and ./os/exec imports which are very uncommon - if !strings.ContainsAny(ioc, "./") && strings.ContainsRune(str, '.') { - return false, idx - } - - return strings.HasPrefix(str, ioc), idx -} diff --git a/vendor/github.com/alecthomas/chroma/v2/.editorconfig b/vendor/github.com/alecthomas/chroma/v2/.editorconfig deleted file mode 100644 index cfb2c669e7..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/.editorconfig +++ /dev/null @@ -1,17 +0,0 @@ -root = true - -[*] -indent_style = tab -end_of_line = lf -charset = utf-8 -trim_trailing_whitespace = true -insert_final_newline = true - -[*.xml] -indent_style = space -indent_size = 2 -insert_final_newline = false - -[*.yml] -indent_style = space -indent_size = 2 diff --git a/vendor/github.com/alecthomas/chroma/v2/.gitignore b/vendor/github.com/alecthomas/chroma/v2/.gitignore deleted file mode 100644 index aedf83d998..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/.gitignore +++ /dev/null @@ -1,28 +0,0 @@ -# Binaries for programs and plugins -.git -.idea -.vscode -.hermit -*.exe -*.dll -*.so -*.dylib -/cmd/chroma/chroma - -# Test binary, build with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 -.glide/ - -_models/ - -_examples/ -*.min.* -build/ - -cmd/chromad/static/chroma.wasm -cmd/chromad/static/wasm_exec.js diff --git a/vendor/github.com/alecthomas/chroma/v2/.golangci.yml b/vendor/github.com/alecthomas/chroma/v2/.golangci.yml deleted file mode 100644 index 91f313b1a3..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/.golangci.yml +++ /dev/null @@ -1,89 +0,0 @@ -run: - tests: true - -output: - print-issued-lines: false - -linters: - enable-all: true - disable: - - lll - - gocyclo - - dupl - - gochecknoglobals - - funlen - - godox - - wsl - - gocognit - - nolintlint - - testpackage - - godot - - nestif - - paralleltest - - nlreturn - - cyclop - - gci - - gofumpt - - errorlint - - exhaustive - - wrapcheck - - stylecheck - - thelper - - nonamedreturns - - revive - - dupword - - exhaustruct - - varnamelen - - forcetypeassert - - ireturn - - maintidx - - govet - - testableexamples - - musttag - - depguard - - goconst - - perfsprint - - mnd - - predeclared - - recvcheck - - tenv - - err113 - -linters-settings: - gocyclo: - min-complexity: 10 - dupl: - threshold: 100 - goconst: - min-len: 8 - min-occurrences: 3 - forbidigo: - #forbid: - # - (Must)?NewLexer$ - exclude_godoc_examples: false - - -issues: - exclude-dirs: - - _examples - max-per-linter: 0 - max-same: 0 - exclude-use-default: false - exclude: - # Captured by errcheck. - - '^(G104|G204):' - # Very commonly not checked. - - 'Error return value of .(.*\.Help|.*\.MarkFlagRequired|(os\.)?std(out|err)\..*|.*Close|.*Flush|os\.Remove(All)?|.*printf?|os\.(Un)?Setenv). is not checked' - - 'exported method (.*\.MarshalJSON|.*\.UnmarshalJSON|.*\.EntityURN|.*\.GoString|.*\.Pos) should have comment or be unexported' - - 'composite literal uses unkeyed fields' - - 'declaration of "err" shadows declaration' - - 'should not use dot imports' - - 'Potential file inclusion via variable' - - 'should have comment or be unexported' - - 'comment on exported var .* should be of the form' - - 'at least one file in a package should have a package comment' - - 'string literal contains the Unicode' - - 'methods on the same type should have the same receiver name' - - '_TokenType_name should be _TokenTypeName' - - '`_TokenType_map` should be `_TokenTypeMap`' - - 'rewrite if-else to switch statement' diff --git a/vendor/github.com/alecthomas/chroma/v2/.goreleaser.yml b/vendor/github.com/alecthomas/chroma/v2/.goreleaser.yml deleted file mode 100644 index f7c4f7d2df..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/.goreleaser.yml +++ /dev/null @@ -1,34 +0,0 @@ -project_name: chroma -release: - github: - owner: alecthomas - name: chroma -brews: - - install: bin.install "chroma" -env: - - CGO_ENABLED=0 -builds: - - goos: - - linux - - darwin - - windows - goarch: - - arm64 - - amd64 - - "386" - goarm: - - "6" - dir: ./cmd/chroma - main: . - ldflags: -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}} - binary: chroma -archives: - - format: tar.gz - name_template: "{{ .Binary }}-{{ .Version }}-{{ .Os }}-{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}" - files: - - COPYING - - README* -snapshot: - name_template: SNAPSHOT-{{ .Commit }} -checksum: - name_template: "{{ .ProjectName }}-{{ .Version }}-checksums.txt" diff --git a/vendor/github.com/alecthomas/chroma/v2/Bitfile b/vendor/github.com/alecthomas/chroma/v2/Bitfile deleted file mode 100644 index bf158633a1..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/Bitfile +++ /dev/null @@ -1,24 +0,0 @@ -VERSION = %(git describe --tags --dirty --always)% -export CGOENABLED = 0 - -tokentype_enumer.go: types.go - build: go generate - -# Regenerate the list of lexers in the README -README.md: lexers/*.go lexers/*/*.xml table.py - build: ./table.py - -clean - -implicit %{1}%{2}.min.%{3}: **/*.{css,js} - build: esbuild --bundle %{IN} --minify --outfile=%{OUT} - -implicit build/%{1}: cmd/* - cd cmd/%{1} - inputs: cmd/%{1}/**/* **/*.go - build: go build -ldflags="-X 'main.version=%{VERSION}'" -o ../../build/%{1} . - -#upload: chromad -# build: -# scp chromad root@swapoff.org: -# ssh root@swapoff.org 'install -m755 ./chromad /srv/http/swapoff.org/bin && service chromad restart' -# touch upload diff --git a/vendor/github.com/alecthomas/chroma/v2/COPYING b/vendor/github.com/alecthomas/chroma/v2/COPYING deleted file mode 100644 index 92dc39f709..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/COPYING +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (C) 2017 Alec Thomas - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/alecthomas/chroma/v2/Dockerfile b/vendor/github.com/alecthomas/chroma/v2/Dockerfile deleted file mode 100644 index e2a1531331..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/Dockerfile +++ /dev/null @@ -1,65 +0,0 @@ -# Multi-stage Dockerfile for chromad Go application using Hermit-managed tools - -# Build stage -FROM ubuntu:24.04 AS builder - -# Install system dependencies -RUN apt-get update && apt-get install -y \ - curl \ - git \ - make \ - ca-certificates \ - && rm -rf /var/lib/apt/lists/* - -# Set working directory -WORKDIR /app - -# Copy the entire project (including bin directory with Hermit tools) -COPY . . - -# Make Hermit tools executable and add to PATH -ENV PATH="/app/bin:${PATH}" - -# Set Go environment variables for static compilation -ENV CGO_ENABLED=0 -ENV GOOS=linux -ENV GOARCH=amd64 - -# Build the application using make -RUN make build/chromad - -# Runtime stage -FROM alpine:3.22 AS runtime - -# Install ca-certificates for HTTPS requests -RUN apk --no-cache add ca-certificates curl - -# Create a non-root user -RUN addgroup -g 1001 chromad && \ - adduser -D -s /bin/sh -u 1001 -G chromad chromad - -# Set working directory -WORKDIR /app - -# Copy the binary from build stage -COPY --from=builder /app/build/chromad /app/chromad - -# Change ownership to non-root user -RUN chown chromad:chromad /app/chromad - -# Switch to non-root user -USER chromad - -# Expose port (default is 8080, but can be overridden via PORT env var) -EXPOSE 8080 - -# Set default environment variables -ENV PORT=8080 -ENV CHROMA_CSRF_KEY="testtest" - -# Health check -HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ - CMD curl -fsSL http://127.0.0.1:8080/ > /dev/null - -# Run the application -CMD ["sh", "-c", "./chromad --csrf-key=$CHROMA_CSRF_KEY --bind=0.0.0.0:$PORT"] diff --git a/vendor/github.com/alecthomas/chroma/v2/Makefile b/vendor/github.com/alecthomas/chroma/v2/Makefile deleted file mode 100644 index ca89f7cb06..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/Makefile +++ /dev/null @@ -1,42 +0,0 @@ -.PHONY: chromad upload all - -VERSION ?= $(shell git describe --tags --dirty --always) -export GOOS ?= linux -export GOARCH ?= amd64 - -all: README.md tokentype_string.go - -README.md: lexers/*.go lexers/embedded/*.xml - GOOS= GOARCH= ./table.py - -tokentype_string.go: types.go - go generate - -.PHONY: format-js -format-js: - biome format --write cmd/chromad/static/{index.js,chroma.js} - -.PHONY: chromad -chromad: build/chromad - -build/chromad: $(shell find cmd/chromad -name '*.go' -o -name '*.html' -o -name '*.css' -o -name '*.js') \ - cmd/chromad/static/wasm_exec.js \ - cmd/chromad/static/chroma.wasm - rm -rf build - esbuild --platform=node --bundle cmd/chromad/static/index.js --minify --outfile=cmd/chromad/static/index.min.js - esbuild --bundle cmd/chromad/static/index.css --minify --outfile=cmd/chromad/static/index.min.css - (export CGOENABLED=0 ; go build -C cmd/chromad -ldflags="-X 'main.version=$(VERSION)'" -o ../../build/chromad .) - -cmd/chromad/static/wasm_exec.js: $(shell tinygo env TINYGOROOT)/targets/wasm_exec.js - install -m644 $< $@ - -cmd/chromad/static/chroma.wasm: $(shell git ls-files | grep '\.go|\.xml') - if type tinygo > /dev/null; then \ - tinygo build -no-debug -target wasm -o $@ cmd/libchromawasm/main.go; \ - else \ - GOOS=js GOARCH=wasm go build -o $@ cmd/libchromawasm/main.go; \ - fi - -upload: build/chromad - scp build/chromad root@swapoff.org: && \ - ssh root@swapoff.org 'install -m755 ./chromad /srv/http/swapoff.org/bin && service chromad restart' diff --git a/vendor/github.com/alecthomas/chroma/v2/README.md b/vendor/github.com/alecthomas/chroma/v2/README.md deleted file mode 100644 index b65c325235..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/README.md +++ /dev/null @@ -1,307 +0,0 @@ -![Chroma](chroma.jpg) - -# A general purpose syntax highlighter in pure Go - -[![Go Reference](https://pkg.go.dev/badge/github.com/alecthomas/chroma/v2.svg)](https://pkg.go.dev/github.com/alecthomas/chroma/v2) [![CI](https://github.com/alecthomas/chroma/actions/workflows/ci.yml/badge.svg)](https://github.com/alecthomas/chroma/actions/workflows/ci.yml) [![Slack chat](https://img.shields.io/static/v1?logo=slack&style=flat&label=slack&color=green&message=gophers)](https://invite.slack.golangbridge.org/) - - -Chroma takes source code and other structured text and converts it into syntax -highlighted HTML, ANSI-coloured text, etc. - -Chroma is based heavily on [Pygments](http://pygments.org/), and includes -translators for Pygments lexers and styles. - -## Table of Contents - - - -1. [Supported languages](#supported-languages) -2. [Try it](#try-it) -3. [Using the library](#using-the-library) - 1. [Quick start](#quick-start) - 2. [Identifying the language](#identifying-the-language) - 3. [Formatting the output](#formatting-the-output) - 4. [The HTML formatter](#the-html-formatter) -4. [More detail](#more-detail) - 1. [Lexers](#lexers) - 2. [Formatters](#formatters) - 3. [Styles](#styles) -5. [Command-line interface](#command-line-interface) -6. [Testing lexers](#testing-lexers) -7. [What's missing compared to Pygments?](#whats-missing-compared-to-pygments) - - - -## Supported languages - -| Prefix | Language -| :----: | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| A | ABAP, ABNF, ActionScript, ActionScript 3, Ada, Agda, AL, Alloy, Angular2, ANTLR, ApacheConf, APL, AppleScript, ArangoDB AQL, Arduino, ArmAsm, ATL, AutoHotkey, AutoIt, Awk -| B | Ballerina, Bash, Bash Session, Batchfile, Beef, BibTeX, Bicep, BlitzBasic, BNF, BQN, Brainfuck -| C | C, C#, C++, Caddyfile, Caddyfile Directives, Cap'n Proto, Cassandra CQL, Ceylon, CFEngine3, cfstatement, ChaiScript, Chapel, Cheetah, Clojure, CMake, COBOL, CoffeeScript, Common Lisp, Coq, Core, Crystal, CSS, CSV, CUE, Cython -| D | D, Dart, Dax, Desktop file, Diff, Django/Jinja, dns, Docker, DTD, Dylan -| E | EBNF, Elixir, Elm, EmacsLisp, Erlang -| F | Factor, Fennel, Fish, Forth, Fortran, FortranFixed, FSharp -| G | GAS, GDScript, GDScript3, Gemtext, Genshi, Genshi HTML, Genshi Text, Gherkin, Gleam, GLSL, Gnuplot, Go, Go HTML Template, Go Template, Go Text Template, GraphQL, Groff, Groovy -| H | Handlebars, Hare, Haskell, Haxe, HCL, Hexdump, HLB, HLSL, HolyC, HTML, HTTP, Hy -| I | Idris, Igor, INI, Io, ISCdhcpd -| J | J, Janet, Java, JavaScript, JSON, JSONata, Jsonnet, Julia, Jungle -| K | Kotlin -| L | Lean4, Lighttpd configuration file, LLVM, lox, Lua -| M | Makefile, Mako, markdown, Mason, Materialize SQL dialect, Mathematica, Matlab, MCFunction, Meson, Metal, MiniZinc, MLIR, Modula-2, Mojo, MonkeyC, MoonScript, MorrowindScript, Myghty, MySQL -| N | NASM, Natural, NDISASM, Newspeak, Nginx configuration file, Nim, Nix, NSIS, Nu -| O | Objective-C, ObjectPascal, OCaml, Octave, Odin, OnesEnterprise, OpenEdge ABL, OpenSCAD, Org Mode -| P | PacmanConf, Perl, PHP, PHTML, Pig, PkgConfig, PL/pgSQL, plaintext, Plutus Core, Pony, PostgreSQL SQL dialect, PostScript, POVRay, PowerQuery, PowerShell, Prolog, Promela, PromQL, properties, Protocol Buffer, PRQL, PSL, Puppet, Python, Python 2 -| Q | QBasic, QML -| R | R, Racket, Ragel, Raku, react, ReasonML, reg, Rego, reStructuredText, Rexx, RPGLE, RPMSpec, Ruby, Rust -| S | SAS, Sass, Scala, Scheme, Scilab, SCSS, Sed, Sieve, Smali, Smalltalk, Smarty, SNBT, Snobol, Solidity, SourcePawn, SPARQL, SQL, SquidConf, Standard ML, stas, Stylus, Svelte, Swift, SYSTEMD, systemverilog -| T | TableGen, Tal, TASM, Tcl, Tcsh, Termcap, Terminfo, Terraform, TeX, Thrift, TOML, TradingView, Transact-SQL, Turing, Turtle, Twig, TypeScript, TypoScript, TypoScriptCssData, TypoScriptHtmlData, Typst -| U | ucode -| V | V, V shell, Vala, VB.net, verilog, VHDL, VHS, VimL, vue -| W | WDTE, WebGPU Shading Language, WebVTT, Whiley -| X | XML, Xorg -| Y | YAML, YANG -| Z | Z80 Assembly, Zed, Zig - -_I will attempt to keep this section up to date, but an authoritative list can be -displayed with `chroma --list`._ - -## Try it - -Try out various languages and styles on the [Chroma Playground](https://swapoff.org/chroma/playground/). - -## Using the library - -This is version 2 of Chroma, use the import path: - -```go -import "github.com/alecthomas/chroma/v2" -``` - -Chroma, like Pygments, has the concepts of -[lexers](https://github.com/alecthomas/chroma/tree/master/lexers), -[formatters](https://github.com/alecthomas/chroma/tree/master/formatters) and -[styles](https://github.com/alecthomas/chroma/tree/master/styles). - -Lexers convert source text into a stream of tokens, styles specify how token -types are mapped to colours, and formatters convert tokens and styles into -formatted output. - -A package exists for each of these, containing a global `Registry` variable -with all of the registered implementations. There are also helper functions -for using the registry in each package, such as looking up lexers by name or -matching filenames, etc. - -In all cases, if a lexer, formatter or style can not be determined, `nil` will -be returned. In this situation you may want to default to the `Fallback` -value in each respective package, which provides sane defaults. - -### Quick start - -A convenience function exists that can be used to simply format some source -text, without any effort: - -```go -err := quick.Highlight(os.Stdout, someSourceCode, "go", "html", "monokai") -``` - -### Identifying the language - -To highlight code, you'll first have to identify what language the code is -written in. There are three primary ways to do that: - -1. Detect the language from its filename. - - ```go - lexer := lexers.Match("foo.go") - ``` - -2. Explicitly specify the language by its Chroma syntax ID (a full list is available from `lexers.Names()`). - - ```go - lexer := lexers.Get("go") - ``` - -3. Detect the language from its content. - - ```go - lexer := lexers.Analyse("package main\n\nfunc main()\n{\n}\n") - ``` - -In all cases, `nil` will be returned if the language can not be identified. - -```go -if lexer == nil { - lexer = lexers.Fallback -} -``` - -At this point, it should be noted that some lexers can be extremely chatty. To -mitigate this, you can use the coalescing lexer to coalesce runs of identical -token types into a single token: - -```go -lexer = chroma.Coalesce(lexer) -``` - -### Formatting the output - -Once a language is identified you will need to pick a formatter and a style (theme). - -```go -style := styles.Get("swapoff") -if style == nil { - style = styles.Fallback -} -formatter := formatters.Get("html") -if formatter == nil { - formatter = formatters.Fallback -} -``` - -Then obtain an iterator over the tokens: - -```go -contents, err := ioutil.ReadAll(r) -iterator, err := lexer.Tokenise(nil, string(contents)) -``` - -And finally, format the tokens from the iterator: - -```go -err := formatter.Format(w, style, iterator) -``` - -### The HTML formatter - -By default the `html` registered formatter generates standalone HTML with -embedded CSS. More flexibility is available through the `formatters/html` package. - -Firstly, the output generated by the formatter can be customised with the -following constructor options: - -- `Standalone()` - generate standalone HTML with embedded CSS. -- `WithClasses()` - use classes rather than inlined style attributes. -- `ClassPrefix(prefix)` - prefix each generated CSS class. -- `TabWidth(width)` - Set the rendered tab width, in characters. -- `WithLineNumbers()` - Render line numbers (style with `LineNumbers`). -- `WithLinkableLineNumbers()` - Make the line numbers linkable and be a link to themselves. -- `HighlightLines(ranges)` - Highlight lines in these ranges (style with `LineHighlight`). -- `LineNumbersInTable()` - Use a table for formatting line numbers and code, rather than spans. - -If `WithClasses()` is used, the corresponding CSS can be obtained from the formatter with: - -```go -formatter := html.New(html.WithClasses(true)) -err := formatter.WriteCSS(w, style) -``` - -## More detail - -### Lexers - -See the [Pygments documentation](http://pygments.org/docs/lexerdevelopment/) -for details on implementing lexers. Most concepts apply directly to Chroma, -but see existing lexer implementations for real examples. - -In many cases lexers can be automatically converted directly from Pygments by -using the included Python 3 script `pygments2chroma_xml.py`. I use something like -the following: - -```sh -python3 _tools/pygments2chroma_xml.py \ - pygments.lexers.jvm.KotlinLexer \ - > lexers/embedded/kotlin.xml -``` - -A list of all lexers available in Pygments can be found in [pygments-lexers.txt](https://github.com/alecthomas/chroma/blob/master/pygments-lexers.txt). - -### Formatters - -Chroma supports HTML output, as well as terminal output in 8 colour, 256 colour, and true-colour. - -A `noop` formatter is included that outputs the token text only, and a `tokens` -formatter outputs raw tokens. The latter is useful for debugging lexers. - -### Styles - -Chroma styles are defined in XML. The style entries use the -[same syntax](http://pygments.org/docs/styles/) as Pygments. - -All Pygments styles have been converted to Chroma using the `_tools/style.py` -script. - -When you work with one of [Chroma's styles](https://github.com/alecthomas/chroma/tree/master/styles), -know that the `Background` token type provides the default style for tokens. It does so -by defining a foreground color and background color. - -For example, this gives each token name not defined in the style a default color -of `#f8f8f8` and uses `#000000` for the highlighted code block's background: - -```xml - -``` - -Also, token types in a style file are hierarchical. For instance, when `CommentSpecial` is not defined, Chroma uses the token style from `Comment`. So when several comment tokens use the same color, you'll only need to define `Comment` and override the one that has a different color. - -For a quick overview of the available styles and how they look, check out the [Chroma Style Gallery](https://xyproto.github.io/splash/docs/). - -## Command-line interface - -A command-line interface to Chroma is included. - -Binaries are available to install from [the releases page](https://github.com/alecthomas/chroma/releases). - -The CLI can be used as a preprocessor to colorise output of `less(1)`, -see documentation for the `LESSOPEN` environment variable. - -The `--fail` flag can be used to suppress output and return with exit status -1 to facilitate falling back to some other preprocessor in case chroma -does not resolve a specific lexer to use for the given file. For example: - -```shell -export LESSOPEN='| p() { chroma --fail "$1" || cat "$1"; }; p "%s"' -``` - -Replace `cat` with your favourite fallback preprocessor. - -When invoked as `.lessfilter`, the `--fail` flag is automatically turned -on under the hood for easy integration with [lesspipe shipping with -Debian and derivatives](https://manpages.debian.org/lesspipe#USER_DEFINED_FILTERS); -for that setup the `chroma` executable can be just symlinked to `~/.lessfilter`. - -## Projects using Chroma - -* [`moar`](https://github.com/walles/moar) is a full-blown pager that colorizes - its input using Chroma -* [Hugo](https://gohugo.io/) is a static site generator that [uses Chroma for syntax - highlighting code examples](https://gohugo.io/content-management/syntax-highlighting/) - -## Testing lexers - -If you edit some lexers and want to try it, open a shell in `cmd/chromad` and run: - -```shell -go run . --csrf-key=securekey -``` - -A Link will be printed. Open it in your Browser. Now you can test on the Playground with your local changes. - -If you want to run the tests and the lexers, open a shell in the root directory and run: - -```shell -go test ./lexers -``` - -When updating or adding a lexer, please add tests. See [lexers/README.md](lexers/README.md) for more. - -## What's missing compared to Pygments? - -- Quite a few lexers, for various reasons (pull-requests welcome): - - Pygments lexers for complex languages often include custom code to - handle certain aspects, such as Raku's ability to nest code inside - regular expressions. These require time and effort to convert. - - I mostly only converted languages I had heard of, to reduce the porting cost. -- Some more esoteric features of Pygments are omitted for simplicity. -- Though the Chroma API supports content detection, very few languages support them. - I have plans to implement a statistical analyser at some point, but not enough time. diff --git a/vendor/github.com/alecthomas/chroma/v2/biome.json b/vendor/github.com/alecthomas/chroma/v2/biome.json deleted file mode 100644 index a5bec2e194..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/biome.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "$schema": "https://biomejs.dev/schemas/2.0.5/schema.json", - "formatter": { - "indentStyle": "space" - } -} diff --git a/vendor/github.com/alecthomas/chroma/v2/chroma.jpg b/vendor/github.com/alecthomas/chroma/v2/chroma.jpg deleted file mode 100644 index a747dbf804..0000000000 Binary files a/vendor/github.com/alecthomas/chroma/v2/chroma.jpg and /dev/null differ diff --git a/vendor/github.com/alecthomas/chroma/v2/coalesce.go b/vendor/github.com/alecthomas/chroma/v2/coalesce.go deleted file mode 100644 index f5048951a2..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/coalesce.go +++ /dev/null @@ -1,35 +0,0 @@ -package chroma - -// Coalesce is a Lexer interceptor that collapses runs of common types into a single token. -func Coalesce(lexer Lexer) Lexer { return &coalescer{lexer} } - -type coalescer struct{ Lexer } - -func (d *coalescer) Tokenise(options *TokeniseOptions, text string) (Iterator, error) { - var prev Token - it, err := d.Lexer.Tokenise(options, text) - if err != nil { - return nil, err - } - return func() Token { - for token := it(); token != (EOF); token = it() { - if len(token.Value) == 0 { - continue - } - if prev == EOF { - prev = token - } else { - if prev.Type == token.Type && len(prev.Value) < 8192 { - prev.Value += token.Value - } else { - out := prev - prev = token - return out - } - } - } - out := prev - prev = EOF - return out - }, nil -} diff --git a/vendor/github.com/alecthomas/chroma/v2/colour.go b/vendor/github.com/alecthomas/chroma/v2/colour.go deleted file mode 100644 index e33d010609..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/colour.go +++ /dev/null @@ -1,192 +0,0 @@ -package chroma - -import ( - "fmt" - "math" - "strconv" - "strings" -) - -// ANSI2RGB maps ANSI colour names, as supported by Chroma, to hex RGB values. -var ANSI2RGB = map[string]string{ - "#ansiblack": "000000", - "#ansidarkred": "7f0000", - "#ansidarkgreen": "007f00", - "#ansibrown": "7f7fe0", - "#ansidarkblue": "00007f", - "#ansipurple": "7f007f", - "#ansiteal": "007f7f", - "#ansilightgray": "e5e5e5", - // Normal - "#ansidarkgray": "555555", - "#ansired": "ff0000", - "#ansigreen": "00ff00", - "#ansiyellow": "ffff00", - "#ansiblue": "0000ff", - "#ansifuchsia": "ff00ff", - "#ansiturquoise": "00ffff", - "#ansiwhite": "ffffff", - - // Aliases without the "ansi" prefix, because...why? - "#black": "000000", - "#darkred": "7f0000", - "#darkgreen": "007f00", - "#brown": "7f7fe0", - "#darkblue": "00007f", - "#purple": "7f007f", - "#teal": "007f7f", - "#lightgray": "e5e5e5", - // Normal - "#darkgray": "555555", - "#red": "ff0000", - "#green": "00ff00", - "#yellow": "ffff00", - "#blue": "0000ff", - "#fuchsia": "ff00ff", - "#turquoise": "00ffff", - "#white": "ffffff", -} - -// Colour represents an RGB colour. -type Colour int32 - -// NewColour creates a Colour directly from RGB values. -func NewColour(r, g, b uint8) Colour { - return ParseColour(fmt.Sprintf("%02x%02x%02x", r, g, b)) -} - -// Distance between this colour and another. -// -// This uses the approach described here (https://www.compuphase.com/cmetric.htm). -// This is not as accurate as LAB, et. al. but is *vastly* simpler and sufficient for our needs. -func (c Colour) Distance(e2 Colour) float64 { - ar, ag, ab := int64(c.Red()), int64(c.Green()), int64(c.Blue()) - br, bg, bb := int64(e2.Red()), int64(e2.Green()), int64(e2.Blue()) - rmean := (ar + br) / 2 - r := ar - br - g := ag - bg - b := ab - bb - return math.Sqrt(float64((((512 + rmean) * r * r) >> 8) + 4*g*g + (((767 - rmean) * b * b) >> 8))) -} - -// Brighten returns a copy of this colour with its brightness adjusted. -// -// If factor is negative, the colour is darkened. -// -// Uses approach described here (http://www.pvladov.com/2012/09/make-color-lighter-or-darker.html). -func (c Colour) Brighten(factor float64) Colour { - r := float64(c.Red()) - g := float64(c.Green()) - b := float64(c.Blue()) - - if factor < 0 { - factor++ - r *= factor - g *= factor - b *= factor - } else { - r = (255-r)*factor + r - g = (255-g)*factor + g - b = (255-b)*factor + b - } - return NewColour(uint8(r), uint8(g), uint8(b)) -} - -// BrightenOrDarken brightens a colour if it is < 0.5 brightness or darkens if > 0.5 brightness. -func (c Colour) BrightenOrDarken(factor float64) Colour { - if c.Brightness() < 0.5 { - return c.Brighten(factor) - } - return c.Brighten(-factor) -} - -// ClampBrightness returns a copy of this colour with its brightness adjusted such that -// it falls within the range [min, max] (or very close to it due to rounding errors). -// The supplied values use the same [0.0, 1.0] range as Brightness. -func (c Colour) ClampBrightness(min, max float64) Colour { - if !c.IsSet() { - return c - } - - min = math.Max(min, 0) - max = math.Min(max, 1) - current := c.Brightness() - target := math.Min(math.Max(current, min), max) - if current == target { - return c - } - - r := float64(c.Red()) - g := float64(c.Green()) - b := float64(c.Blue()) - rgb := r + g + b - if target > current { - // Solve for x: target == ((255-r)*x + r + (255-g)*x + g + (255-b)*x + b) / 255 / 3 - return c.Brighten((target*255*3 - rgb) / (255*3 - rgb)) - } - // Solve for x: target == (r*(x+1) + g*(x+1) + b*(x+1)) / 255 / 3 - return c.Brighten((target*255*3)/rgb - 1) -} - -// Brightness of the colour (roughly) in the range 0.0 to 1.0. -func (c Colour) Brightness() float64 { - return (float64(c.Red()) + float64(c.Green()) + float64(c.Blue())) / 255.0 / 3.0 -} - -// ParseColour in the forms #rgb, #rrggbb, #ansi, or #. -// Will return an "unset" colour if invalid. -func ParseColour(colour string) Colour { - colour = normaliseColour(colour) - n, err := strconv.ParseUint(colour, 16, 32) - if err != nil { - return 0 - } - return Colour(n + 1) //nolint:gosec -} - -// MustParseColour is like ParseColour except it panics if the colour is invalid. -// -// Will panic if colour is in an invalid format. -func MustParseColour(colour string) Colour { - parsed := ParseColour(colour) - if !parsed.IsSet() { - panic(fmt.Errorf("invalid colour %q", colour)) - } - return parsed -} - -// IsSet returns true if the colour is set. -func (c Colour) IsSet() bool { return c != 0 } - -func (c Colour) String() string { return fmt.Sprintf("#%06x", int(c-1)) } -func (c Colour) GoString() string { return fmt.Sprintf("Colour(0x%06x)", int(c-1)) } - -// Red component of colour. -func (c Colour) Red() uint8 { return uint8(((c - 1) >> 16) & 0xff) } //nolint:gosec - -// Green component of colour. -func (c Colour) Green() uint8 { return uint8(((c - 1) >> 8) & 0xff) } //nolint:gosec - -// Blue component of colour. -func (c Colour) Blue() uint8 { return uint8((c - 1) & 0xff) } //nolint:gosec - -// Colours is an orderable set of colours. -type Colours []Colour - -func (c Colours) Len() int { return len(c) } -func (c Colours) Swap(i, j int) { c[i], c[j] = c[j], c[i] } -func (c Colours) Less(i, j int) bool { return c[i] < c[j] } - -// Convert colours to #rrggbb. -func normaliseColour(colour string) string { - if ansi, ok := ANSI2RGB[colour]; ok { - return ansi - } - if strings.HasPrefix(colour, "#") { - colour = colour[1:] - if len(colour) == 3 { - return colour[0:1] + colour[0:1] + colour[1:2] + colour[1:2] + colour[2:3] + colour[2:3] - } - } - return colour -} diff --git a/vendor/github.com/alecthomas/chroma/v2/delegate.go b/vendor/github.com/alecthomas/chroma/v2/delegate.go deleted file mode 100644 index 298f2dbbd1..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/delegate.go +++ /dev/null @@ -1,161 +0,0 @@ -package chroma - -import ( - "bytes" -) - -type delegatingLexer struct { - root Lexer - language Lexer -} - -// DelegatingLexer combines two lexers to handle the common case of a language embedded inside another, such as PHP -// inside HTML or PHP inside plain text. -// -// It takes two lexer as arguments: a root lexer and a language lexer. First everything is scanned using the language -// lexer, which must return "Other" for unrecognised tokens. Then all "Other" tokens are lexed using the root lexer. -// Finally, these two sets of tokens are merged. -// -// The lexers from the template lexer package use this base lexer. -func DelegatingLexer(root Lexer, language Lexer) Lexer { - return &delegatingLexer{ - root: root, - language: language, - } -} - -func (d *delegatingLexer) SetTracing(enable bool) { - if l, ok := d.language.(TracingLexer); ok { - l.SetTracing(enable) - } - if l, ok := d.root.(TracingLexer); ok { - l.SetTracing(enable) - } -} - -func (d *delegatingLexer) AnalyseText(text string) float32 { - return d.root.AnalyseText(text) -} - -func (d *delegatingLexer) SetAnalyser(analyser func(text string) float32) Lexer { - d.root.SetAnalyser(analyser) - return d -} - -func (d *delegatingLexer) SetRegistry(r *LexerRegistry) Lexer { - d.root.SetRegistry(r) - d.language.SetRegistry(r) - return d -} - -func (d *delegatingLexer) Config() *Config { - return d.language.Config() -} - -// An insertion is the character range where language tokens should be inserted. -type insertion struct { - start, end int - tokens []Token -} - -func (d *delegatingLexer) Tokenise(options *TokeniseOptions, text string) (Iterator, error) { // nolint: gocognit - tokens, err := Tokenise(Coalesce(d.language), options, text) - if err != nil { - return nil, err - } - // Compute insertions and gather "Other" tokens. - others := &bytes.Buffer{} - insertions := []*insertion{} - var insert *insertion - offset := 0 - var last Token - for _, t := range tokens { - if t.Type == Other { - if last != EOF && insert != nil && last.Type != Other { - insert.end = offset - } - others.WriteString(t.Value) - } else { - if last == EOF || last.Type == Other { - insert = &insertion{start: offset} - insertions = append(insertions, insert) - } - insert.tokens = append(insert.tokens, t) - } - last = t - offset += len(t.Value) - } - - if len(insertions) == 0 { - return d.root.Tokenise(options, text) - } - - // Lex the other tokens. - rootTokens, err := Tokenise(Coalesce(d.root), options, others.String()) - if err != nil { - return nil, err - } - - // Interleave the two sets of tokens. - var out []Token - offset = 0 // Offset into text. - tokenIndex := 0 - nextToken := func() Token { - if tokenIndex >= len(rootTokens) { - return EOF - } - t := rootTokens[tokenIndex] - tokenIndex++ - return t - } - insertionIndex := 0 - nextInsertion := func() *insertion { - if insertionIndex >= len(insertions) { - return nil - } - i := insertions[insertionIndex] - insertionIndex++ - return i - } - t := nextToken() - i := nextInsertion() - for t != EOF || i != nil { - // fmt.Printf("%d->%d:%q %d->%d:%q\n", offset, offset+len(t.Value), t.Value, i.start, i.end, Stringify(i.tokens...)) - if t == EOF || (i != nil && i.start < offset+len(t.Value)) { - var l Token - l, t = splitToken(t, i.start-offset) - if l != EOF { - out = append(out, l) - offset += len(l.Value) - } - out = append(out, i.tokens...) - offset += i.end - i.start - if t == EOF { - t = nextToken() - } - i = nextInsertion() - } else { - out = append(out, t) - offset += len(t.Value) - t = nextToken() - } - } - return Literator(out...), nil -} - -func splitToken(t Token, offset int) (l Token, r Token) { - if t == EOF { - return EOF, EOF - } - if offset == 0 { - return EOF, t - } - if offset == len(t.Value) { - return t, EOF - } - l = t.Clone() - r = t.Clone() - l.Value = l.Value[:offset] - r.Value = r.Value[offset:] - return -} diff --git a/vendor/github.com/alecthomas/chroma/v2/doc.go b/vendor/github.com/alecthomas/chroma/v2/doc.go deleted file mode 100644 index 4dde77c818..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/doc.go +++ /dev/null @@ -1,7 +0,0 @@ -// Package chroma takes source code and other structured text and converts it into syntax highlighted HTML, ANSI- -// coloured text, etc. -// -// Chroma is based heavily on Pygments, and includes translators for Pygments lexers and styles. -// -// For more information, go here: https://github.com/alecthomas/chroma -package chroma diff --git a/vendor/github.com/alecthomas/chroma/v2/emitters.go b/vendor/github.com/alecthomas/chroma/v2/emitters.go deleted file mode 100644 index 1097a75764..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/emitters.go +++ /dev/null @@ -1,233 +0,0 @@ -package chroma - -import ( - "fmt" -) - -// An Emitter takes group matches and returns tokens. -type Emitter interface { - // Emit tokens for the given regex groups. - Emit(groups []string, state *LexerState) Iterator -} - -// ValidatingEmitter is an Emitter that can validate against a compiled rule. -type ValidatingEmitter interface { - Emitter - ValidateEmitter(rule *CompiledRule) error -} - -// SerialisableEmitter is an Emitter that can be serialised and deserialised to/from JSON. -type SerialisableEmitter interface { - Emitter - EmitterKind() string -} - -// EmitterFunc is a function that is an Emitter. -type EmitterFunc func(groups []string, state *LexerState) Iterator - -// Emit tokens for groups. -func (e EmitterFunc) Emit(groups []string, state *LexerState) Iterator { - return e(groups, state) -} - -type Emitters []Emitter - -type byGroupsEmitter struct { - Emitters -} - -var _ ValidatingEmitter = (*byGroupsEmitter)(nil) - -// ByGroups emits a token for each matching group in the rule's regex. -func ByGroups(emitters ...Emitter) Emitter { - return &byGroupsEmitter{Emitters: emitters} -} - -func (b *byGroupsEmitter) EmitterKind() string { return "bygroups" } - -func (b *byGroupsEmitter) ValidateEmitter(rule *CompiledRule) error { - if len(rule.Regexp.GetGroupNumbers())-1 != len(b.Emitters) { - return fmt.Errorf("number of groups %d does not match number of emitters %d", len(rule.Regexp.GetGroupNumbers())-1, len(b.Emitters)) - } - return nil -} - -func (b *byGroupsEmitter) Emit(groups []string, state *LexerState) Iterator { - iterators := make([]Iterator, 0, len(groups)-1) - if len(b.Emitters) != len(groups)-1 { - iterators = append(iterators, Error.Emit(groups, state)) - // panic(errors.Errorf("number of groups %q does not match number of emitters %v", groups, emitters)) - } else { - for i, group := range groups[1:] { - if b.Emitters[i] != nil { - iterators = append(iterators, b.Emitters[i].Emit([]string{group}, state)) - } - } - } - return Concaterator(iterators...) -} - -// ByGroupNames emits a token for each named matching group in the rule's regex. -func ByGroupNames(emitters map[string]Emitter) Emitter { - return EmitterFunc(func(groups []string, state *LexerState) Iterator { - iterators := make([]Iterator, 0, len(state.NamedGroups)-1) - if len(state.NamedGroups)-1 == 0 { - if emitter, ok := emitters[`0`]; ok { - iterators = append(iterators, emitter.Emit(groups, state)) - } else { - iterators = append(iterators, Error.Emit(groups, state)) - } - } else { - ruleRegex := state.Rules[state.State][state.Rule].Regexp - for i := 1; i < len(state.NamedGroups); i++ { - groupName := ruleRegex.GroupNameFromNumber(i) - group := state.NamedGroups[groupName] - if emitter, ok := emitters[groupName]; ok { - if emitter != nil { - iterators = append(iterators, emitter.Emit([]string{group}, state)) - } - } else { - iterators = append(iterators, Error.Emit([]string{group}, state)) - } - } - } - return Concaterator(iterators...) - }) -} - -// UsingByGroup emits tokens for the matched groups in the regex using a -// sublexer. Used when lexing code blocks where the name of a sublexer is -// contained within the block, for example on a Markdown text block or SQL -// language block. -// -// An attempt to load the sublexer will be made using the captured value from -// the text of the matched sublexerNameGroup. If a sublexer matching the -// sublexerNameGroup is available, then tokens for the matched codeGroup will -// be emitted using the sublexer. Otherwise, if no sublexer is available, then -// tokens will be emitted from the passed emitter. -// -// Example: -// -// var Markdown = internal.Register(MustNewLexer( -// &Config{ -// Name: "markdown", -// Aliases: []string{"md", "mkd"}, -// Filenames: []string{"*.md", "*.mkd", "*.markdown"}, -// MimeTypes: []string{"text/x-markdown"}, -// }, -// Rules{ -// "root": { -// {"^(```)(\\w+)(\\n)([\\w\\W]*?)(^```$)", -// UsingByGroup( -// 2, 4, -// String, String, String, Text, String, -// ), -// nil, -// }, -// }, -// }, -// )) -// -// See the lexers/markdown.go for the complete example. -// -// Note: panic's if the number of emitters does not equal the number of matched -// groups in the regex. -func UsingByGroup(sublexerNameGroup, codeGroup int, emitters ...Emitter) Emitter { - return &usingByGroup{ - SublexerNameGroup: sublexerNameGroup, - CodeGroup: codeGroup, - Emitters: emitters, - } -} - -type usingByGroup struct { - SublexerNameGroup int `xml:"sublexer_name_group"` - CodeGroup int `xml:"code_group"` - Emitters Emitters `xml:"emitters"` -} - -func (u *usingByGroup) EmitterKind() string { return "usingbygroup" } -func (u *usingByGroup) Emit(groups []string, state *LexerState) Iterator { - // bounds check - if len(u.Emitters) != len(groups)-1 { - panic("UsingByGroup expects number of emitters to be the same as len(groups)-1") - } - - // grab sublexer - sublexer := state.Registry.Get(groups[u.SublexerNameGroup]) - - // build iterators - iterators := make([]Iterator, len(groups)-1) - for i, group := range groups[1:] { - if i == u.CodeGroup-1 && sublexer != nil { - var err error - iterators[i], err = sublexer.Tokenise(nil, groups[u.CodeGroup]) - if err != nil { - panic(err) - } - } else if u.Emitters[i] != nil { - iterators[i] = u.Emitters[i].Emit([]string{group}, state) - } - } - return Concaterator(iterators...) -} - -// UsingLexer returns an Emitter that uses a given Lexer for parsing and emitting. -// -// This Emitter is not serialisable. -func UsingLexer(lexer Lexer) Emitter { - return EmitterFunc(func(groups []string, _ *LexerState) Iterator { - it, err := lexer.Tokenise(&TokeniseOptions{State: "root", Nested: true}, groups[0]) - if err != nil { - panic(err) - } - return it - }) -} - -type usingEmitter struct { - Lexer string `xml:"lexer,attr"` -} - -func (u *usingEmitter) EmitterKind() string { return "using" } - -func (u *usingEmitter) Emit(groups []string, state *LexerState) Iterator { - if state.Registry == nil { - panic(fmt.Sprintf("no LexerRegistry available for Using(%q)", u.Lexer)) - } - lexer := state.Registry.Get(u.Lexer) - if lexer == nil { - panic(fmt.Sprintf("no such lexer %q", u.Lexer)) - } - it, err := lexer.Tokenise(&TokeniseOptions{State: "root", Nested: true}, groups[0]) - if err != nil { - panic(err) - } - return it -} - -// Using returns an Emitter that uses a given Lexer reference for parsing and emitting. -// -// The referenced lexer must be stored in the same LexerRegistry. -func Using(lexer string) Emitter { - return &usingEmitter{Lexer: lexer} -} - -type usingSelfEmitter struct { - State string `xml:"state,attr"` -} - -func (u *usingSelfEmitter) EmitterKind() string { return "usingself" } - -func (u *usingSelfEmitter) Emit(groups []string, state *LexerState) Iterator { - it, err := state.Lexer.Tokenise(&TokeniseOptions{State: u.State, Nested: true}, groups[0]) - if err != nil { - panic(err) - } - return it -} - -// UsingSelf is like Using, but uses the current Lexer. -func UsingSelf(stateName string) Emitter { - return &usingSelfEmitter{stateName} -} diff --git a/vendor/github.com/alecthomas/chroma/v2/formatter.go b/vendor/github.com/alecthomas/chroma/v2/formatter.go deleted file mode 100644 index 00dd5d8df8..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/formatter.go +++ /dev/null @@ -1,43 +0,0 @@ -package chroma - -import ( - "io" -) - -// A Formatter for Chroma lexers. -type Formatter interface { - // Format returns a formatting function for tokens. - // - // If the iterator panics, the Formatter should recover. - Format(w io.Writer, style *Style, iterator Iterator) error -} - -// A FormatterFunc is a Formatter implemented as a function. -// -// Guards against iterator panics. -type FormatterFunc func(w io.Writer, style *Style, iterator Iterator) error - -func (f FormatterFunc) Format(w io.Writer, s *Style, it Iterator) (err error) { // nolint - defer func() { - if perr := recover(); perr != nil { - err = perr.(error) - } - }() - return f(w, s, it) -} - -type recoveringFormatter struct { - Formatter -} - -func (r recoveringFormatter) Format(w io.Writer, s *Style, it Iterator) (err error) { - defer func() { - if perr := recover(); perr != nil { - err = perr.(error) - } - }() - return r.Formatter.Format(w, s, it) -} - -// RecoveringFormatter wraps a formatter with panic recovery. -func RecoveringFormatter(formatter Formatter) Formatter { return recoveringFormatter{formatter} } diff --git a/vendor/github.com/alecthomas/chroma/v2/formatters/api.go b/vendor/github.com/alecthomas/chroma/v2/formatters/api.go deleted file mode 100644 index 9ca0d01ddc..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/formatters/api.go +++ /dev/null @@ -1,57 +0,0 @@ -package formatters - -import ( - "io" - "sort" - - "github.com/alecthomas/chroma/v2" - "github.com/alecthomas/chroma/v2/formatters/html" - "github.com/alecthomas/chroma/v2/formatters/svg" -) - -var ( - // NoOp formatter. - NoOp = Register("noop", chroma.FormatterFunc(func(w io.Writer, s *chroma.Style, iterator chroma.Iterator) error { - for t := iterator(); t != chroma.EOF; t = iterator() { - if _, err := io.WriteString(w, t.Value); err != nil { - return err - } - } - return nil - })) - // Default HTML formatter outputs self-contained HTML. - htmlFull = Register("html", html.New(html.Standalone(true), html.WithClasses(true))) // nolint - SVG = Register("svg", svg.New(svg.EmbedFont("Liberation Mono", svg.FontLiberationMono, svg.WOFF))) -) - -// Fallback formatter. -var Fallback = NoOp - -// Registry of Formatters. -var Registry = map[string]chroma.Formatter{} - -// Names of registered formatters. -func Names() []string { - out := []string{} - for name := range Registry { - out = append(out, name) - } - sort.Strings(out) - return out -} - -// Get formatter by name. -// -// If the given formatter is not found, the Fallback formatter will be returned. -func Get(name string) chroma.Formatter { - if f, ok := Registry[name]; ok { - return f - } - return Fallback -} - -// Register a named formatter. -func Register(name string, formatter chroma.Formatter) chroma.Formatter { - Registry[name] = formatter - return formatter -} diff --git a/vendor/github.com/alecthomas/chroma/v2/formatters/html/html.go b/vendor/github.com/alecthomas/chroma/v2/formatters/html/html.go deleted file mode 100644 index c1c8875b2d..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/formatters/html/html.go +++ /dev/null @@ -1,647 +0,0 @@ -package html - -import ( - "fmt" - "html" - "io" - "sort" - "strconv" - "strings" - "sync" - - "github.com/alecthomas/chroma/v2" -) - -// Option sets an option of the HTML formatter. -type Option func(f *Formatter) - -// Standalone configures the HTML formatter for generating a standalone HTML document. -func Standalone(b bool) Option { return func(f *Formatter) { f.standalone = b } } - -// ClassPrefix sets the CSS class prefix. -func ClassPrefix(prefix string) Option { return func(f *Formatter) { f.prefix = prefix } } - -// WithClasses emits HTML using CSS classes, rather than inline styles. -func WithClasses(b bool) Option { return func(f *Formatter) { f.Classes = b } } - -// WithAllClasses disables an optimisation that omits redundant CSS classes. -func WithAllClasses(b bool) Option { return func(f *Formatter) { f.allClasses = b } } - -// WithCustomCSS sets user's custom CSS styles. -func WithCustomCSS(css map[chroma.TokenType]string) Option { - return func(f *Formatter) { - f.customCSS = css - } -} - -// WithCSSComments adds prefixe comments to the css classes. Defaults to true. -func WithCSSComments(b bool) Option { return func(f *Formatter) { f.writeCSSComments = b } } - -// TabWidth sets the number of characters for a tab. Defaults to 8. -func TabWidth(width int) Option { return func(f *Formatter) { f.tabWidth = width } } - -// PreventSurroundingPre prevents the surrounding pre tags around the generated code. -func PreventSurroundingPre(b bool) Option { - return func(f *Formatter) { - f.preventSurroundingPre = b - - if b { - f.preWrapper = nopPreWrapper - } else { - f.preWrapper = defaultPreWrapper - } - } -} - -// InlineCode creates inline code wrapped in a code tag. -func InlineCode(b bool) Option { - return func(f *Formatter) { - f.inlineCode = b - f.preWrapper = preWrapper{ - start: func(code bool, styleAttr string) string { - if code { - return fmt.Sprintf(``, styleAttr) - } - - return `` - }, - end: func(code bool) string { - if code { - return `` - } - - return `` - }, - } - } -} - -// WithPreWrapper allows control of the surrounding pre tags. -func WithPreWrapper(wrapper PreWrapper) Option { - return func(f *Formatter) { - f.preWrapper = wrapper - } -} - -// WrapLongLines wraps long lines. -func WrapLongLines(b bool) Option { - return func(f *Formatter) { - f.wrapLongLines = b - } -} - -// WithLineNumbers formats output with line numbers. -func WithLineNumbers(b bool) Option { - return func(f *Formatter) { - f.lineNumbers = b - } -} - -// LineNumbersInTable will, when combined with WithLineNumbers, separate the line numbers -// and code in table td's, which make them copy-and-paste friendly. -func LineNumbersInTable(b bool) Option { - return func(f *Formatter) { - f.lineNumbersInTable = b - } -} - -// WithLinkableLineNumbers decorates the line numbers HTML elements with an "id" -// attribute so they can be linked. -func WithLinkableLineNumbers(b bool, prefix string) Option { - return func(f *Formatter) { - f.linkableLineNumbers = b - f.lineNumbersIDPrefix = prefix - } -} - -// HighlightLines higlights the given line ranges with the Highlight style. -// -// A range is the beginning and ending of a range as 1-based line numbers, inclusive. -func HighlightLines(ranges [][2]int) Option { - return func(f *Formatter) { - f.highlightRanges = ranges - sort.Sort(f.highlightRanges) - } -} - -// BaseLineNumber sets the initial number to start line numbering at. Defaults to 1. -func BaseLineNumber(n int) Option { - return func(f *Formatter) { - f.baseLineNumber = n - } -} - -// New HTML formatter. -func New(options ...Option) *Formatter { - f := &Formatter{ - baseLineNumber: 1, - preWrapper: defaultPreWrapper, - writeCSSComments: true, - } - f.styleCache = newStyleCache(f) - for _, option := range options { - option(f) - } - return f -} - -// PreWrapper defines the operations supported in WithPreWrapper. -type PreWrapper interface { - // Start is called to write a start
 element.
-	// The code flag tells whether this block surrounds
-	// highlighted code. This will be false when surrounding
-	// line numbers.
-	Start(code bool, styleAttr string) string
-
-	// End is called to write the end 
element. - End(code bool) string -} - -type preWrapper struct { - start func(code bool, styleAttr string) string - end func(code bool) string -} - -func (p preWrapper) Start(code bool, styleAttr string) string { - return p.start(code, styleAttr) -} - -func (p preWrapper) End(code bool) string { - return p.end(code) -} - -var ( - nopPreWrapper = preWrapper{ - start: func(code bool, styleAttr string) string { return "" }, - end: func(code bool) string { return "" }, - } - defaultPreWrapper = preWrapper{ - start: func(code bool, styleAttr string) string { - if code { - return fmt.Sprintf(``, styleAttr) - } - - return fmt.Sprintf(``, styleAttr) - }, - end: func(code bool) string { - if code { - return `` - } - - return `` - }, - } -) - -// Formatter that generates HTML. -type Formatter struct { - styleCache *styleCache - standalone bool - prefix string - Classes bool // Exported field to detect when classes are being used - allClasses bool - customCSS map[chroma.TokenType]string - writeCSSComments bool - preWrapper PreWrapper - inlineCode bool - preventSurroundingPre bool - tabWidth int - wrapLongLines bool - lineNumbers bool - lineNumbersInTable bool - linkableLineNumbers bool - lineNumbersIDPrefix string - highlightRanges highlightRanges - baseLineNumber int -} - -type highlightRanges [][2]int - -func (h highlightRanges) Len() int { return len(h) } -func (h highlightRanges) Swap(i, j int) { h[i], h[j] = h[j], h[i] } -func (h highlightRanges) Less(i, j int) bool { return h[i][0] < h[j][0] } - -func (f *Formatter) Format(w io.Writer, style *chroma.Style, iterator chroma.Iterator) (err error) { - return f.writeHTML(w, style, iterator.Tokens()) -} - -// We deliberately don't use html/template here because it is two orders of magnitude slower (benchmarked). -// -// OTOH we need to be super careful about correct escaping... -func (f *Formatter) writeHTML(w io.Writer, style *chroma.Style, tokens []chroma.Token) (err error) { // nolint: gocyclo - css := f.styleCache.get(style, true) - if f.standalone { - fmt.Fprint(w, "\n") - if f.Classes { - fmt.Fprint(w, "") - } - fmt.Fprintf(w, "\n", f.styleAttr(css, chroma.Background)) - } - - wrapInTable := f.lineNumbers && f.lineNumbersInTable - - lines := chroma.SplitTokensIntoLines(tokens) - lineDigits := len(strconv.Itoa(f.baseLineNumber + len(lines) - 1)) - highlightIndex := 0 - - if wrapInTable { - // List line numbers in its own - fmt.Fprintf(w, "\n", f.styleAttr(css, chroma.PreWrapper)) - fmt.Fprintf(w, "", f.styleAttr(css, chroma.LineTable)) - fmt.Fprintf(w, "\n", f.styleAttr(css, chroma.LineTableTD)) - fmt.Fprintf(w, "%s", f.preWrapper.Start(false, f.styleAttr(css, chroma.PreWrapper))) - for index := range lines { - line := f.baseLineNumber + index - highlight, next := f.shouldHighlight(highlightIndex, line) - if next { - highlightIndex++ - } - if highlight { - fmt.Fprintf(w, "", f.styleAttr(css, chroma.LineHighlight)) - } - - fmt.Fprintf(w, "%s\n", f.styleAttr(css, chroma.LineNumbersTable), f.lineIDAttribute(line), f.lineTitleWithLinkIfNeeded(css, lineDigits, line)) - - if highlight { - fmt.Fprintf(w, "") - } - } - fmt.Fprint(w, f.preWrapper.End(false)) - fmt.Fprint(w, "\n") - fmt.Fprintf(w, "\n", f.styleAttr(css, chroma.LineTableTD, "width:100%")) - } - - fmt.Fprintf(w, "%s", f.preWrapper.Start(true, f.styleAttr(css, chroma.PreWrapper))) - - highlightIndex = 0 - for index, tokens := range lines { - // 1-based line number. - line := f.baseLineNumber + index - highlight, next := f.shouldHighlight(highlightIndex, line) - if next { - highlightIndex++ - } - - if !(f.preventSurroundingPre || f.inlineCode) { - // Start of Line - fmt.Fprint(w, ``) - } else { - fmt.Fprintf(w, "%s>", f.styleAttr(css, chroma.Line)) - } - - // Line number - if f.lineNumbers && !wrapInTable { - fmt.Fprintf(w, "%s", f.styleAttr(css, chroma.LineNumbers), f.lineIDAttribute(line), f.lineTitleWithLinkIfNeeded(css, lineDigits, line)) - } - - fmt.Fprintf(w, ``, f.styleAttr(css, chroma.CodeLine)) - } - - for _, token := range tokens { - html := html.EscapeString(token.String()) - attr := f.styleAttr(css, token.Type) - if attr != "" { - html = fmt.Sprintf("%s", attr, html) - } - fmt.Fprint(w, html) - } - - if !(f.preventSurroundingPre || f.inlineCode) { - fmt.Fprint(w, ``) // End of CodeLine - - fmt.Fprint(w, ``) // End of Line - } - } - fmt.Fprintf(w, "%s", f.preWrapper.End(true)) - - if wrapInTable { - fmt.Fprint(w, "\n") - fmt.Fprint(w, "\n") - } - - if f.standalone { - fmt.Fprint(w, "\n\n") - fmt.Fprint(w, "\n") - } - - return nil -} - -func (f *Formatter) lineIDAttribute(line int) string { - if !f.linkableLineNumbers { - return "" - } - return fmt.Sprintf(" id=\"%s\"", f.lineID(line)) -} - -func (f *Formatter) lineTitleWithLinkIfNeeded(css map[chroma.TokenType]string, lineDigits, line int) string { - title := fmt.Sprintf("%*d", lineDigits, line) - if !f.linkableLineNumbers { - return title - } - return fmt.Sprintf("%s", f.styleAttr(css, chroma.LineLink), f.lineID(line), title) -} - -func (f *Formatter) lineID(line int) string { - return fmt.Sprintf("%s%d", f.lineNumbersIDPrefix, line) -} - -func (f *Formatter) shouldHighlight(highlightIndex, line int) (bool, bool) { - next := false - for highlightIndex < len(f.highlightRanges) && line > f.highlightRanges[highlightIndex][1] { - highlightIndex++ - next = true - } - if highlightIndex < len(f.highlightRanges) { - hrange := f.highlightRanges[highlightIndex] - if line >= hrange[0] && line <= hrange[1] { - return true, next - } - } - return false, next -} - -func (f *Formatter) class(t chroma.TokenType) string { - for t != 0 { - if cls, ok := chroma.StandardTypes[t]; ok { - if cls != "" { - return f.prefix + cls - } - return "" - } - t = t.Parent() - } - if cls := chroma.StandardTypes[t]; cls != "" { - return f.prefix + cls - } - return "" -} - -func (f *Formatter) styleAttr(styles map[chroma.TokenType]string, tt chroma.TokenType, extraCSS ...string) string { - if f.Classes { - cls := f.class(tt) - if cls == "" { - return "" - } - return fmt.Sprintf(` class="%s"`, cls) - } - if _, ok := styles[tt]; !ok { - tt = tt.SubCategory() - if _, ok := styles[tt]; !ok { - tt = tt.Category() - if _, ok := styles[tt]; !ok { - return "" - } - } - } - css := []string{styles[tt]} - css = append(css, extraCSS...) - return fmt.Sprintf(` style="%s"`, strings.Join(css, ";")) -} - -func (f *Formatter) tabWidthStyle() string { - if f.tabWidth != 0 && f.tabWidth != 8 { - return fmt.Sprintf("-moz-tab-size: %[1]d; -o-tab-size: %[1]d; tab-size: %[1]d;", f.tabWidth) - } - return "" -} - -func (f *Formatter) writeCSSRule(w io.Writer, comment string, selector string, styles string) error { - if styles == "" { - return nil - } - if f.writeCSSComments && comment != "" { - if _, err := fmt.Fprintf(w, "/* %s */ ", comment); err != nil { - return err - } - } - if _, err := fmt.Fprintf(w, "%s { %s }\n", selector, styles); err != nil { - return err - } - return nil -} - -// WriteCSS writes CSS style definitions (without any surrounding HTML). -func (f *Formatter) WriteCSS(w io.Writer, style *chroma.Style) error { - css := f.styleCache.get(style, false) - - // Special-case background as it is mapped to the outer ".chroma" class. - if err := f.writeCSSRule(w, chroma.Background.String(), fmt.Sprintf(".%sbg", f.prefix), css[chroma.Background]); err != nil { - return err - } - // Special-case PreWrapper as it is the ".chroma" class. - if err := f.writeCSSRule(w, chroma.PreWrapper.String(), fmt.Sprintf(".%schroma", f.prefix), css[chroma.PreWrapper]); err != nil { - return err - } - // Special-case code column of table to expand width. - if f.lineNumbers && f.lineNumbersInTable { - selector := fmt.Sprintf(".%schroma .%s:last-child", f.prefix, f.class(chroma.LineTableTD)) - if err := f.writeCSSRule(w, chroma.LineTableTD.String(), selector, "width: 100%;"); err != nil { - return err - } - } - // Special-case line number highlighting when targeted. - if f.lineNumbers || f.lineNumbersInTable { - targetedLineCSS := StyleEntryToCSS(style.Get(chroma.LineHighlight)) - for _, tt := range []chroma.TokenType{chroma.LineNumbers, chroma.LineNumbersTable} { - comment := fmt.Sprintf("%s targeted by URL anchor", tt) - selector := fmt.Sprintf(".%schroma .%s:target", f.prefix, f.class(tt)) - if err := f.writeCSSRule(w, comment, selector, targetedLineCSS); err != nil { - return err - } - } - } - tts := []int{} - for tt := range css { - tts = append(tts, int(tt)) - } - sort.Ints(tts) - for _, ti := range tts { - tt := chroma.TokenType(ti) - switch tt { - case chroma.Background, chroma.PreWrapper: - continue - } - class := f.class(tt) - if class == "" { - continue - } - if err := f.writeCSSRule(w, tt.String(), fmt.Sprintf(".%schroma .%s", f.prefix, class), css[tt]); err != nil { - return err - } - } - return nil -} - -func (f *Formatter) styleToCSS(style *chroma.Style) map[chroma.TokenType]string { - classes := map[chroma.TokenType]string{} - bg := style.Get(chroma.Background) - // Convert the style. - for t := range chroma.StandardTypes { - entry := style.Get(t) - if t != chroma.Background { - entry = entry.Sub(bg) - } - - // Inherit from custom CSS provided by user - tokenCategory := t.Category() - tokenSubCategory := t.SubCategory() - if t != tokenCategory { - if css, ok := f.customCSS[tokenCategory]; ok { - classes[t] = css - } - } - if tokenCategory != tokenSubCategory { - if css, ok := f.customCSS[tokenSubCategory]; ok { - classes[t] += css - } - } - // Add custom CSS provided by user - if css, ok := f.customCSS[t]; ok { - classes[t] += css - } - - if !f.allClasses && entry.IsZero() && classes[t] == `` { - continue - } - - styleEntryCSS := StyleEntryToCSS(entry) - if styleEntryCSS != `` && classes[t] != `` { - styleEntryCSS += `;` - } - classes[t] = styleEntryCSS + classes[t] - } - classes[chroma.Background] += `;` + f.tabWidthStyle() - classes[chroma.PreWrapper] += classes[chroma.Background] - // Make PreWrapper a grid to show highlight style with full width. - if len(f.highlightRanges) > 0 && f.customCSS[chroma.PreWrapper] == `` { - classes[chroma.PreWrapper] += `display: grid;` - } - // Make PreWrapper wrap long lines. - if f.wrapLongLines { - classes[chroma.PreWrapper] += `white-space: pre-wrap; word-break: break-word;` - } - lineNumbersStyle := `white-space: pre; -webkit-user-select: none; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;` - // All rules begin with default rules followed by user provided rules - classes[chroma.Line] = `display: flex;` + classes[chroma.Line] - classes[chroma.LineNumbers] = lineNumbersStyle + classes[chroma.LineNumbers] - classes[chroma.LineNumbersTable] = lineNumbersStyle + classes[chroma.LineNumbersTable] - classes[chroma.LineTable] = "border-spacing: 0; padding: 0; margin: 0; border: 0;" + classes[chroma.LineTable] - classes[chroma.LineTableTD] = "vertical-align: top; padding: 0; margin: 0; border: 0;" + classes[chroma.LineTableTD] - classes[chroma.LineLink] = "outline: none; text-decoration: none; color: inherit" + classes[chroma.LineLink] - return classes -} - -// StyleEntryToCSS converts a chroma.StyleEntry to CSS attributes. -func StyleEntryToCSS(e chroma.StyleEntry) string { - styles := []string{} - if e.Colour.IsSet() { - styles = append(styles, "color: "+e.Colour.String()) - } - if e.Background.IsSet() { - styles = append(styles, "background-color: "+e.Background.String()) - } - if e.Bold == chroma.Yes { - styles = append(styles, "font-weight: bold") - } - if e.Italic == chroma.Yes { - styles = append(styles, "font-style: italic") - } - if e.Underline == chroma.Yes { - styles = append(styles, "text-decoration: underline") - } - return strings.Join(styles, "; ") -} - -// Compress CSS attributes - remove spaces, transform 6-digit colours to 3. -func compressStyle(s string) string { - parts := strings.Split(s, ";") - out := []string{} - for _, p := range parts { - p = strings.Join(strings.Fields(p), " ") - p = strings.Replace(p, ": ", ":", 1) - if strings.Contains(p, "#") { - c := p[len(p)-6:] - if c[0] == c[1] && c[2] == c[3] && c[4] == c[5] { - p = p[:len(p)-6] + c[0:1] + c[2:3] + c[4:5] - } - } - out = append(out, p) - } - return strings.Join(out, ";") -} - -const styleCacheLimit = 32 - -type styleCacheEntry struct { - style *chroma.Style - compressed bool - cache map[chroma.TokenType]string -} - -type styleCache struct { - mu sync.Mutex - // LRU cache of compiled (and possibly compressed) styles. This is a slice - // because the cache size is small, and a slice is sufficiently fast for - // small N. - cache []styleCacheEntry - f *Formatter -} - -func newStyleCache(f *Formatter) *styleCache { - return &styleCache{f: f} -} - -func (l *styleCache) get(style *chroma.Style, compress bool) map[chroma.TokenType]string { - l.mu.Lock() - defer l.mu.Unlock() - - // Look for an existing entry. - for i := len(l.cache) - 1; i >= 0; i-- { - entry := l.cache[i] - if entry.style == style && entry.compressed == compress { - // Top of the cache, no need to adjust the order. - if i == len(l.cache)-1 { - return entry.cache - } - // Move this entry to the end of the LRU - copy(l.cache[i:], l.cache[i+1:]) - l.cache[len(l.cache)-1] = entry - return entry.cache - } - } - - // No entry, create one. - cached := l.f.styleToCSS(style) - if !l.f.Classes { - for t, style := range cached { - cached[t] = compressStyle(style) - } - } - if compress { - for t, style := range cached { - cached[t] = compressStyle(style) - } - } - // Evict the oldest entry. - if len(l.cache) >= styleCacheLimit { - l.cache = l.cache[0:copy(l.cache, l.cache[1:])] - } - l.cache = append(l.cache, styleCacheEntry{style: style, cache: cached, compressed: compress}) - return cached -} diff --git a/vendor/github.com/alecthomas/chroma/v2/formatters/json.go b/vendor/github.com/alecthomas/chroma/v2/formatters/json.go deleted file mode 100644 index 436d3ce8c9..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/formatters/json.go +++ /dev/null @@ -1,39 +0,0 @@ -package formatters - -import ( - "encoding/json" - "fmt" - "io" - - "github.com/alecthomas/chroma/v2" -) - -// JSON formatter outputs the raw token structures as JSON. -var JSON = Register("json", chroma.FormatterFunc(func(w io.Writer, s *chroma.Style, it chroma.Iterator) error { - if _, err := fmt.Fprintln(w, "["); err != nil { - return err - } - i := 0 - for t := it(); t != chroma.EOF; t = it() { - if i > 0 { - if _, err := fmt.Fprintln(w, ","); err != nil { - return err - } - } - i++ - bytes, err := json.Marshal(t) - if err != nil { - return err - } - if _, err := fmt.Fprint(w, " "+string(bytes)); err != nil { - return err - } - } - if _, err := fmt.Fprintln(w); err != nil { - return err - } - if _, err := fmt.Fprintln(w, "]"); err != nil { - return err - } - return nil -})) diff --git a/vendor/github.com/alecthomas/chroma/v2/formatters/svg/font_liberation_mono.go b/vendor/github.com/alecthomas/chroma/v2/formatters/svg/font_liberation_mono.go deleted file mode 100644 index 70d692ec45..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/formatters/svg/font_liberation_mono.go +++ /dev/null @@ -1,51 +0,0 @@ -// Digitized data copyright (c) 2010 Google Corporation -// with Reserved Font Arimo, Tinos and Cousine. -// Copyright (c) 2012 Red Hat, Inc. -// with Reserved Font Name Liberation. -// -// This Font Software is licensed under the SIL Open Font License, Version 1.1. -// This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL -// -// ----------------------------------------------------------- -// SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 -// ----------------------------------------------------------- -// -// PREAMBLE -// The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others. -// -// The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives. -// -// DEFINITIONS -// "Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation. -// -// "Reserved Font Name" refers to any names specified as such after the copyright statement(s). -// -// "Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s). -// -// "Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment. -// -// "Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software. -// -// PERMISSION & CONDITIONS -// Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions: -// -// 1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself. -// -// 2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user. -// -// 3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users. -// -// 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission. -// -// 5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software. -// -// TERMINATION -// This license becomes null and void if any of the above conditions are not met. -// -// DISCLAIMER -// THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. - -package svg - -// Liberation Mono as base64 encoded woff (SIL Open Font License)[https://en.wikipedia.org/wiki/Liberation_fonts] -var FontLiberationMono = `d09GRgABAAAAAqtYABIAAAAEycAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAKrPAAAABwAAAAcdooU5UdERUYAAp6sAAAAcAAAAIZxBHoIR1BPUwACoNwAAApfAAAzLnW/WuJHU1VCAAKfHAAAAb4AAALi0BntuE9TLzIAAAIQAAAAYAAAAGAAbrqGY21hcAAADmgAAARSAAAGPmw6RjVjdnQgAAAbpAAAAZ8AAAKuZwZtV2ZwZ20AABK8AAAEqQAAB7R+YbYRZ2FzcAACnpwAAAAQAAAAEAAYAAlnbHlmAAA0mAACOjQAA8hUF/4NBGhlYWQAAAGUAAAANgAAADYELjhMaGhlYQAAAcwAAAAhAAAAJAjCBstobXR4AAACcAAAC/UAACV4+gaVVWxvY2EAAB1EAAAXVAAAJXwSZmZ8bWF4cAAAAfAAAAAgAAAAIA3VBMBuYW1lAAJuzAAABTkAAAumb4o3f3Bvc3QAAnQIAAAqlAAAW+Bx9Ia5cHJlcAAAF2gAAAQ8AAAFesjzjI8AAQAAAAIAABUZ4O5fDzz1Ah8IAAAAAADIQ3qnAAAAANiiczX8Jf2ZBfEH2QAAAAgAAAABAAAAAHjaY2BkYGBb+XcmAwNr5B/VX1WsHxmAIsiAMw4AmuUGmAAAAAABAAAJXgEiAEgAWwAGAAIAEAAvAFwAAAO5AxEAAwABAAMEzQGQAAUAAAWaBTMAAAEdBZoFMwAAA2EAZgISCAUCBwQJAgIFAgQE4AAK/0AAeP8AAAABAAAAADFBU0MAQAAg/iME5/5+AAAGqQJnYAABv9/3AAAEOgVFAAAAIAAOeNqlWglwVdUZvuc1tBiVzYBCEJSGarG4UMMmU9lk0QhWBAybVGoEpGkfJNIqiokELVQibQVEFptQi4hKiTjEWrApWNbijB1gKkyhTq3aCAiU0Zq82+8/5zvJn+t7SRjfzDf/uffs//nPv92Xtj+YH+CXtt8j9rW0/aY9yr2BwXx/Dd6dA8YBd+D5M6AAZWk7CjiF59nAPODXwNPAY8D9pMuBNUAJ8JRrb6a6MeowBfgO5ysD4qSCKvW8B9jE8idAEct5EToayAGWAOkcN4sYiflXgs4BbeXWFX6B8i+53gqgGFjENQstBSpJC4FqtL8QdJpqX8G2p4HfAdvY5xagPfcoPP0V8D54fQnbzarnvZ2vL/l1I9usxVyyn67AX4H55P8o986ufTjfoa/pxb087dra85kLejnoP4EHgEygLSB7eLb+/L8EEzmLMnUOGpmK/1Gs5p6WRJDFPkvI92TIIG9LIiiN4BF1DlGIfOXzLDQGKxpwviiNc4xUtIznksmzL+P6mqJxrjsVLePaYkA2eVzaDHovcJh3pJDjVBNyXxY6amVXnv+unnuzvoy8jNIWpBU81+IkVM6rM/ucJt2rnkdT5lPRHN4bofeR7qKMVJ4HDXjnsni+vPf27kWokXvSH/foqNprGtAPGK/2lsk2/XjWxbxLoucmo+4Y6Mc8Q+HVDPJ1jzqHhdSVY9F+r+KlnwN3N/gW56lkvx8CL1JP/IP8yVB8kj2/5vZgywHf+31eCgxTuvhh4KfA89SfmCd2EdY6263B6qFcopcqB6o8Rt0RL3t+D809o5Ik981wb3GOp+9DdRJ5g44MFlPW9Zp9v8lKZ72dZJ6+1A3y/h5VX+bsQ919nU1e6b3OUevQ7U9zj4+ovUblW/i/Tt3zMspoLuf3Z6fXU9LIvfPUy/tB4EmueZhDGIJ+m7yaxvKrwAbgu7xnV9ImpHPOnyldIjxdwDVtYLvuwA28D143LFb2c5HS2ddxvkXUaQvJB6/DiznWNyjPlcrmwv8I9rOP4DjrphPYT5jg/JUcqy/lQ8pbFU47mM6R93I+oYOJ8cx/z/MaSR6UK3s+FLiJ5yR4SJ1TifId8rimh7iWLRwP6zYXRHjUi+hCPoNnYTXLw9T9ebneRpshwEAAZ2L2ATIuZNnI3n8EejH9N6w5FlOAnjEngN4OVpeJrD3oYDIdYteCfh94w/lt9vkuYBvxhUPdeBUK0rYn/UrxTyrJY/gi4Qd4xh00VwCyjz5AJ66nIAnmED04biblu4iyu8v5lwIZO/w38BHmhi42zzWEtX3Q1ea2IKitCYLEM8CWIKgZAvoJ3r0EeiQIwhdAPwIuRbkv6HzXLtwN5PL5CNs+p3AWmAiMBm4GpqDNE3C1v+fGDHOA2wHMn5Cx2gb2V/NfN5/MFT4L3Mq2f3T9E6uBSrcGP29ipVrzbj7/Bs8vg2LMxAfoX+76h0NBy0C7A8vRZiOeK9CoHeg6vFsFinHCNzjfxSgPB7I57gpgLXDS7a22A2gBxz/CcQscEh+CYswAewoH4Xk79zUmNRJbgTdR3uHWlTgMQMoTu4DjwGXk6XiUXwRex/ifA4XAKaV7FjtZNe85ubL3BPXhgXq/1pdD8amfUbGH2PGLWB6p/Fpvx9NV3PEE68r5PIs6XvRwS9IbqCf28LmIerCC85bz3UbqxZ+wfivbLGe7auqkVcAkYDv32oE+9ia+92P2ok9wN8f174tJs1m+3u098TB5IO+upj+YF/F3q5zOCs9Rn11NOzqWejif+qmMOmwC/Zd0+sh+vHzyrrfy0wtV/TJlG+OKz7fRJ4uTetse8NzitLV7VKwodcNJ17N9BvkYqDGO0W/z4w1RdetpX6Lxpo9VczimP/PH6E+IPR/H8Waw/Xi+u5HtfuH2aW1BB9oBQ7vgbaD46V/nvFuUHdExz2DaiCnc90q2n0TbPxPYxzh9GO2YtzvZnH8p7WCpinU7Uq6yuQ4fM8n8I2if2hM307dI5/j+Wfb1TT5fS34t47rac51F7DdG0a6E1A8gH69S88bpR+U7vWZ1x1qH2nehT6GPah5QsiR+/R183sh4+CzQh/t9hTz1se8QnsN67t3TNJVXGMDxttA/Evm/ixgTuT85yk+7JUKncLyWlJ2VinL9Ys+s7iK1Mu7Xut7ZQCunF1KutrPvdjVWkeOnjU1S+d/ej7mfdLry1zVfbld+T6WiqfzT8ZS/DMpQlPo1HqM8zqDc9mHckkW/2tN8rkP28gOei/Rrw7XLeltznHHqHDpQH01yuraOZ3kcz8aPQWDWA7BhBrIUywDdDPwZOADcxPJOYBPLgq6wRZNA48CfOIZvx3qzm+U463eq/jJuKeaDz2H6AeMc7PM6gm3lnX0/l2X4i2aE1MHv6ejrxfap8ijUP0UeSQ7pVD1/Y5BpI/bicXfe8hxM5V1Zyvet2K47dcMwxj6Fzt8MbmWOairrr3KyVge5YwdcG8ld1dkPOZff0m7s5z0UudtM27eLtnFrvY23OimbcUhnxj2PE3sZq/djPFFO/XMZqffjxXd/E/gUEF90Iuv2cIx0ygbahZ+jvg31xBH6sodoSxCzx6CrTDuUTzq/3PLsKAEbZi5xeVObozns+ob/cX6wzSn2dPZYqEVX4k5CfOkeLs8XPAqKfRjwy/Qn7cJ+r7k6yzdp19qt11xJH7uLW5NpyfEkbhjq2plupBn1beQcwyreIdyPELF0iBgs3EEb/inPah718TruX2RCxl/tEAyiXuxBHwf60oynTRA+lNNebHI8lrVYvVZE2Srk+N6GjqOsvUNAdk2ti4+sfitxsmB50p/50U6MZ14hejJ+Oux4YfmBsoHuNqKHjjNHNJ/rkPtyBu8GKZ5L7IK1mS0uP27jmoFEa8ZiZxmLSftrYKugMxILYKtK6Mu+DfxN0Xsdwh97fzqSD0iWo9N5yUXNpM3JV1axfTQ/GaU/p5/pn6P5SZ/HiVKdk4zkKC0tolxEqc/rpKJN5UuS8fF0ClrQjPxlsjxmMtrcHJn3ozz1ec2mqPcnNB2cOgdq59rGvoOdjFmZX9ZIblzowCbqm0Obkr2ZtA+p6qMyluqsRzIWakommqLnm4v2VOeik9GiJsB8TyJsiDDDwerTJAiHO5+y9q2GqMvXpYD0Cwey/buqb7mDveeNoEH/t5L0L06O8CUAOj6RRTzpYO13I0gc4fjw6WpXKN8gBRrM061+nkSuQx3fX1XxeoXaY7GKpcvV2F/1HM/nXDRKHM5r31mN7LuRtTfAGfoKZxiXtE2+7sQ51Peqp/b+9nAITzYiS4zlE7Cf4dxIn6gcrCb8M7/5Jv4AnHB8Cz92sL5dMv5c7+bx1OZuztBO4RceBK4ADsEm5/A77AYHyYtYSE5UvnVDH5nJwBLmkjcT4j++7mC/qRdyPMkJtvNg3oq52+AF0AlAvrOL1nfeJ/lN1acN0db1N/cBhj5kF/o+XemzxYlujImn0V/vSR85ULn9iYz7clTM25H9fYwVb5EbLMEe+N3C+pgdGL+nkY/3MI+x28mJ5GntuBfQh+/H3Db0lXnwy9SWZzA/N4MxXKHjg/3OPcrllm1uZZXzKW1Ozv7PAOsrYKxSwH2hHOviZEHOTcoCX9Y0CjPT1QkV6Lrzfd8cRO9dLC/ybq77Xmzz/9OZR2hNXrTmt+Q5vBfTKYPdHaxMZRIiIwPoZ+cxrha6oEWulZ9OEoeBlxKLrXBnatbwXNvzXuczF1+mbGA1bfA6ys1U5a/w25rp6O6ruZO5b8kBnxCobzOfeeD98wIX+9k8f7qLTW3cyhxMLB3x7uX0Iycw7vX5BB3XTmVuaT5lu6WibRQiMbN5lDEhdK9ZGomXW6k42cfISeJju95R7GdzbkFQI98BakFr3H90bC67Bel7rp0d+3/87rwTz3LPakDl/kMvJCQGLAU9SBwgFZ5WAdhD+C/PY76r4rcN+cZwkD5VUzatCV+gcdsdNPHjGtZQntZgXfuwxrtBjwLvcN2yt0N8d4jfDuSbwlhgHtv8RaGK9YJZ/PZQoUHfc4S6Y9CN4YfME3R038Hsd83reJ7+TD1EBqCPgx3A+wLRPf8H1ZqAPAAAAHja5dT7U1ZFGAfw73sOr+dEvspVkHzZPQf3pICIigiEpHIJK5QSMzURbzWaZnQzHTUtSjJSHLyDDmSFERUgApqXbExnzIwGS/Ey5p55z5pZUVlT885wOonDL03TH9Azs7vz/LA7z35mngeAjJ41CC5nR0CSk7lu5QEBkYBLchIFElZLyfJS+Xl5tbxeLpNr5DPuULfXfdJ93X3Teyq6Mnp39J8knHhJNskj08h0MpPMIqtIMzlOOshF8hO5SbqpQoNoONWpQRNoIk2iaTSdZtAsWkiX0pfoZrqfHqVdmlsL1SI0XTO0BG2SVqAVaiXaFm2vLul99P56iB6uR+lEH6rH6bn6XH1BjBQTFKMxMIn1ZUEsjEWyQWwwi2dJLJ0tZmtYCStlZayC1bB61sQOskPsODvNvmSdzDLSjXHGBKPImGc8biw2lsYviV+WEFGr1Zb5JX+yP92f4R/vz/JP7o6xbceEolpKkZ+TV8gljsEGeY/c7o5yb3K3u7u88HY7BtUEJJJQkkvybxvMJmtICzlBviGXyS/kd8egLw2hEY5BrGMwkqb2GixyDMppda/BgNsGedoUbaZjUN5rEOwYDNSjbxsU6fNvGdB/McjvNShn1ayu1+CUY3DeMUjrNVhgLHQMiuKLHYOI2lK/y+/1pzgG4/yZ/pxuatu2aX9qH7MP2wfsZnuf3WQ32g12nT3GHm7HXiPihrguvhOmuCquiMviorggOsV5cU58Lc6KDvGVaBdnxBfiM3FMfCKOikPigGgTrWKfaBKNol5UiFKxXCwUhWKqYCJYBAjJ+sP6zfrRardOWyesGmurVWLFWUMsahHLa0VZEVY/y+P72XfB1+kb60v0aWamOcFMNZPNUWaiOcw0TGJGmsG8m3/Pr3Ef5/wK7+Cf8xP8KD/CW3kTb+B7eRWfyHN4Nh/CDc54DNcujbiUcGHjnPI5sZ4WT5Wn0rPTs8Oz3bMt8GRPj/zPo48U+Pfhwj80XM6c6AnpP97ouSkjAG70ceaLijsQiDvRFx70Q38EIRghCEUYwjEAEYjEQEThLmcqeREN4nSiBh0xGAwGA3djCIYiFnGIxzAkYDgSMQIjMQpJGI1kjEEKUpGGe5COscjAvRiH8ZiATGQhGzm4D7mYiPvxAB5EHiZhMvLxEB7GFBRgKh7BNDyK6ZiBmXgMs1CI2SjCHKf+17AOr+MNVGA7dmMP3sLbeBfvoBbv4X3UoR4f4CN8iAY0Yh/2oxktaEMrDuFjHMYR5QqewXwswELlKl5EDZ7Gk2oUXsAiNQ2l2KmOxrPqWDUDT2CZOkxNVIfLxWoKFmOlPAN7cRBrMQ9PqUmuAjVVTcASrFI45uJlvIptrjBXuNKhnFUuKpeUc8p5HFBX4pgrTelSA5Ubyg9qq9qmfIvlSqdyWbmGEpThFbyJ9diIcmzCBmzBVueHm1GFXajEr9I6aReKpR3STqkSK6TdUpVU+heLM5/fAAB42nVVz1PbRhTeFQYMGCJTyjDVIatu7MJgl3SStkApbG3J2HXTYgwzK+hBIiZjeuKUQ6ad8a2MSP+XJ3IxOeXaQ/+HHNpbOSbX9L2VTSAz1Qhr3/d+7vfeLmr78CDQ+3vt3dbOTz8++qH5faO+XfO9auU7tbX57cY362urX3/15Rf3Vz4vlxY/KxbuyU/duwtzefvOzPTU5ER2fGw0M2JxVhLAQx9GCiJfi6Qvo3q5JPyFrlcu+bIWgogE4CdTlPW6gWQEIhRQxE90Aw5BoeWTDyxVaqmuLbktNtgGpZAC/vKk6PODlsb1H54MBFyZ9SOzzhSNMI2C66KHqYqqFT7UnnZjP8QaeTI1WZXV48lyiSWTU7icwhUsytOEL25ys7AW/fXEYtlpSos79aMO7LS07zmuG5RLDZiRnlGxqgkJY1UYNyHFCZXOzkVSehU/79vsKFzOdWQn+lnDSIS+8Ygfx79DfhmWpAdLz/5ewJ0fQ0l6PixT1ObudZ7m+5QcRgu2FPEbhtuRV//eRqIBMlaw3zBaglUFvqtdepwach3HNSlqcRhH/Xe9IylsGSe5XHzqI91sR2OI/ruX5w7Ungdgh12+Hgy2XtttwketQw1WoSa6ESL4bkl31XHz1zY7/6dmSAuSgwy7LtFw3lfsCAXotXQqC3bkXDC1shyAFZLm1VDz8T5pekPNtXsosbfNto4hU2h0pI+Mn0fQO8Lp+oUaI22Yeeu4Mp7Ni7WVwNgKrKrROREwWkSS0OumA84NucS2EWbepp8rBxMU87NiTWIYiuNLPxy8T7sLGEAg0fXldBD2NCgPFyoadMxP7q+gRxRiw04800xYkacwJyvX3aWy/JO2Ni4DN5irAgsfD7xgxTfnSvhx6KUlUCzZ0pfswbvXyUPhvHjAHrLAI+P5Kk5Z0Y915wncDZ0OnrsnQjsuqAA7HEh9HNDYIUNLrx0zHIGZlT3dbMtm60CvDgpJFRQuU/A/CCO1k4bBAYRsISu05YwEaGgjIGq4kJUN/IXxQhb/bCTcoDS4lQ2hucOG1lgGLAn/2BvYkXwr6CiNU7U+jDZGIsap1h03cNOnXLJQLQaJ0SNLpNaHKrymUJHF+azWDURcLtDQCy2PZSC7AtSOpr0RPYblARmG80Gv9m5JN8hCmpiL6qFAZEJt2blJLmwb+Vqsf6BuDNUizspmO6bgchCQYeUNYDTCajXvmLuADrTEu1fYeKTNgY4Tpegwd9cpiGx0YtnWG8Ya75PfnGeUa5Y1eXOvUi7h1VZJJD9rJYqftQ/0pc2YONvTFxa3qmElSO6hTl8KxpRBLUIJJEGQQJF2Ucgae+dSMdYz2owBjPy4z5nBskOMs8d9K8XsNFHRJFLMQk0m1aihdQaxbIr1DGaehBFlanJUZdWEylnTlpNwgi4QeckZm+DsRY5PcydBr10D93kvmVBOatFDC5VWeLb/PvX+gX6RY+hmfjFRhR4cl4UuNhv/rfiiQ4Pya9CNw4AOG5vH1uDLgctNbJPcxELGcjApjyswJSuEbxG+leJjhI/jiPJ5ju497P0OcJqAQ+3ikRSf/OnE9hV1KsBLJbb/Kf8HKfchKQAAAHjaPVTdTyNVFL9nBhZZ2L3lq3QFvPNCg1ZpKYsx2tJbdO8ioAx0xyxggBgS3yzJdJ9pkHUxUloFWU1IwNfdJR0ghME0pcofsPwBXVsR9cENoyY+mnqmgDf5nd855875mntnwm6IEID3iAajF/wB3CGNhIGGzJCHSTe8j/4hZHs/SIIQQA7g828iv4W2zT1wcyfOSLgTbhIHQiqjE3e6ST/4iUbiKAFx7u3COB96KUpAnHu96EUmCspphEQISqWsVUPnDhDNhNd2gja9uktKbDZcB+9gAhu9mOBtTNCH3Hdhh9Du5R9r5F/4R+1gf4sO9pd4hf0peljybOMsfSZHraQlHVqwaQGzpqyoJZPn/Ll09Q9RYr+futlvp0H26+lLjJ5C2y8ngtET4CfCyX4uCnZYfFosFGVe7H5dFIWLZaCR9EI91m3gtUFZKwSfaT8F8xoJ14MTO7LRhOOlUQKO1URUhIQvAW2o4xG5xJ5BXlPyaj6eN/IVNA/HTd1s6ih6NHckH/4IP6huNpsFJevL5rLybDaelWiGZSRvJpSJZtKZQqbyYMvNFNNnquasGTcrzVKOt5oNLwvHPij76n5839iviO8ZexLdDe1au7IJ17jnUT+LGylDMoyccWzI3nQoLW1uGVtSbut4S/I+CT2RNh5D7tHxIyl8DSjxw3Wcg6B0IBSEjFM4eBOo69Prs+vyt2tu9o1wM99D/lDCHnbXnK3C7qV67Xqd+G41wDbD1XCLBPCO3b5gAbd4xwz7uqXE6Gp69XBV5qttXYKvOltQ1FJBV7wroZW5FWulkn4PtSQKtVyRvkq42ZeREiukwJcClvKmpGhqLiWRpCOpJGW7qJJ0tQpl2bcsDSemEtGE7FsCusSWvEsyX3I0CMch1OAUNcSHkEs5qNlpVsSBrXDV0Si+mHezzwcCbPFBkD1YCLDPBkps4z44FpQF34Ls+xTm5oHPV9cKHc8nipfrE8SL4NJudLu0qm5Zu4InO417U4iDUhGqdphblBXOGlrF5Hg/+1B0sQnkceQGf71WCbJW4Zfxpr+w1xJgVIYDuAGunR7GTaTmDmHCVd6OCUfVFmaNlEYkPtLzhuAj7R3iqQqFIRgSbWxQ9DPVhBb+EQzgebyLjfUjbiPSAgrCElJcQDM0aU5/k1YHVHP4qSbhlwb4fbW2zDBGQ3SKztEKSr10mEZpkhZoiVaF0GdROUrwJwGbTqgEE1LbdyIez6BZVRodNKrVCQMWjfaILfnIuHFl0SDa+MTdbYDlsfuJBOlrGzT8kbvGdNvYoDGDCreVOCqOtm0n6RvTY3rsnud8wYWqE48nFkMuG+UdBPFcLrAN8OixmH7hwQi0Yp57ZenR9ctA+1lUCJbB9HqM2EExjw46sQmj7KIYDTFSDtNRXJbETJO6h0zqZXMSQzCDft7L/71N6ued6pcVy8v1H5x2ib942q2SvUucQRDGf7vvu+JHiCmMpYKFTVqrFHavhZwiprA48A6xOBGMQkI05usSgt9oJIhyghYenAqCh6JJFAPXRLQTIeA/kKCEoMEm576O5wkeImkyA7PPzsw+M8OO2TW7vDQe9wlnbI64DynhGfhHFzf/yA9dYttkm/iPkn95rLDJArN8E/Q+G+rnFXG+5qRvsc0iw2wQY4SqW2k/Cc+LDPpI6PbqKsFjupmTuu+E7wvNalA5hHlClHWp3eAuuykb4FAlSakCetUDPSE9THBgvrv7NwjHSdAudk1s7MKhjxnX1XTouOMxIBOGdUDcKaldz5wK0swb2qQLBEVyuCqdWvroFfT0esS8TS9T5P+RjgcYlU7a6CJIYzac1I7YEadcplliNeMbunqbN+906g2dfzbFB9E60VZaVZQZEjZip4kpT3mM2VP/J8+Np+u44/8yk+kTOgjQQg0//vWjslXF6TL/WP/lrltKod2TX8uKE+TeWYVsU7f/24btI8kpdktN3CRNih5CeVE3Qom7k9m4PftaZjyQvfjM7DkU4YO8AHjajdd33I512D/w73VdKqtSCSG7ImQWyczeI4SIjMyMsiqVShnJjWRkl+w9b3veNhHKjOy9V+bz9nv9/nr+enp1vK7r/J7HcXzGcZyX8w7h//1X4X/FKHE6hGjyEGJNQkhUO4THOovJITyeWLQK4YkUwvkTQ8RGcTuExAXF5RCSqEniOun5EJJ1DCF5duH6SflPiaddP91d7A0hRVGxLIRn0osdITzn+rndIaQcGMLzVcSqEFLhlMpn6nZCTZoyYn4IL8B7Qf+0KYX8dD7T+UwvPz28F/HK4CwDrAwHQ8iIaybXmXqK4yFkVp9ZfWa9s8DPAi9LrxCyys/mOtuREF7qE8LLhQWOr4wLIbv67M5yJBLycuD8quucrnPqm4u2XFtDyF0yhNd49Zp7efiYh395cwke5oObD5f8vMjvfgG4BfQpAK+ge6/DeP16CG84K6RnIZ9vZhI9Qiii91vxIRRtKCYIPhRTV0x+cRgl8C5BT8npgsZSzko9+nT/bXzf9r20WhaGMnDLwC+jZ1k4ZWcLvcqZbTn8y6ktB6M83PKPPs2lAp0VcKxgByoMFzyuwOuKtFW0M5XSCP5XglWJ1krmVZn+ynpVqSHgVIFTBU5VOqsiUlWPas6qOasutzrs6jCr01Yd35o8ram2ptqadNXUsxZva8mrZSdqwall794RtemvTVdt+LVxrs27OrTW6R9CXbl17XZdeHVxfhfnd+uF4P9QL6+wt/XsTz3+1bO79fGrbx/rq6tPa3119fnYIJvApwE+DfBpYLfesx/v8bEhHQ3paERHI7WN+NRIbaN1Qs/39Xyf5vf58T5+7+PXGH5jXBqbS2PzaKxnYxqb0NgElw/0aEpXU7qa8qWp+01hNoPRzG42w7uZumb2ornZNYfXAnYLvFvY5xbyW5jdh+byIV8+vBdCSxpa6tfSdUv+tcSjpfNW+rfWozVvW3s2WuvVGofWvG2DQxu629qBtri31RNEaMe7dri34107Oj+C1/5R4NiBhg7ud2ByBxw74NjBnnTkQ0c+dITREUZHGB1hdILRyXknmjs576Tfx64/du8Tz8An8D/h+yd8/oTPnXHtrHdn8+2sR2fz6WIHu+DfRe8untkutHXFs6u97dpc4NlVblfz6AavG1+6yevOq0/d/9RsPjOPz+zf57z9XM8e5vsF/l/g9CVvvzTrr1z3pK2n2q9x/MY8vuHLt7B70dcLxncM+o6n3+P+Pe29ed7bbPvwva8Z9OV9X+d97VY/un7Q7wd8+7v/o5ofaRyAV5zfioGuB7o/kBeDYA6GMRjHn5z/pMcQOD/T+DOuQ2kaap7D5A3HbTgNI3z/xflImkfqOwreaN9Hm9MYeGNwGcOTsb6PpW2cGC/nVxi/6fubvAm8+12PiTyeqOckGibhNgnHSfImeV4nm8lkHkzm/2Q9J9M2hf9T8JxiVlP0n2J+U+icgsdUvabiPtXZNLXT1E7j23S8Z/Brhnsz7NMM+DPxmWkGM+XOhDVL7SzzmGX/ZuE7W+1suufQMZe2ubjOVTcP5jxc5uGyAJeFuC5UvwjeIjWL4C3izyI7HW+/4+mNt4Pxfi/izTpez8W8X2w/FvvtXmwvF/sNWWJPlsBeYv+WmPcSnizlyVKeLMVnqVksxWUZLsvoWQZnmfplzpe7v0K/Fa5XurcSp1XwV/NlDX1rcVhrrms9L+voXAd/HT3reLCOpgTcEzwPCa4T+JPAy/Vq1uu53pw2+L5RzUbcN9O02ecWvbfC3iZ/u57bYf5Byw5ad9irnfj9qX6XXd6F826fe3DbA+8vfP/2fa9nei9++2jc7/5+dQfs9EE7cMhv9SF6/zGzw+4fsaNH1P7r3lFeHdPz2KNPMzuu1wm8Tuh7koaTOJ/C+ZT80/qdUX+G9rNmcM7v3Dk+neP5edgX7NYFc7no7BIPLuN0mf4rcK/CvKrnVXtyjZ7r8K7jdMOcbqi5qe9Ne3DL9S29buNwG8Z/sO/w6w5v7tq7u3Lu6X+fT/f1emB3H9rhh3Ie9g+RkEYMF/dCJNInRKJlxPkQie0IkUQNxekQeax7iHhnijw+W6wKkSfUJW4uOodIkrxislCTdHqIJGsXIslzhciTKULkKb28I0VSyHumSYg82zNEnusYIimrCH2e1yeVvFTqU7ufWl4afNIMDJEXEgnXaYOYECLp9Eq3TuwWx0MkfXYBKz1O6XF/Uc8XD4ZIBmcZegi9vS9FMuKSUZ+M8DJeDpFM2QTumfTMpFdmujLrnRm3zDRngZulhhgljoRIVvnepSJZ5WdzL1ttAe8lfF/C4+UKQu7LzrxbRbLLyb4xRHLomUNuDjy8X0VeTSnqCdpedT8n3Tn1yEl7Lppz4ZSLllzXQyR3YQEvN/zXSgr98+CZR30e9XnUG18kr7y8tOadHyL59MuHSz468tGVH35+XudXW0BtgYKCDwX2hkhB9wrqX/B2iLxO3+uthJ5vyHnDDrzhe6Hkgg+FhoitIWJ1I4WLCniF4RVW+6Zr73ORN5eFSBH6iuBapJdQX4T3b6UXrt9yXRSmd71IUb2K4VqML8XkFDef4jgX51EJ9SXMr4R9LEF7STMtyfuS6krSVIq3pZyVUltK/tu+v82z0nahNK2l7V9p+1qGT2XoLkt3WTlleVZWfTkcy7kuT0t5vleAW0GfivhUwbWKeVRxXjWTwNs7XaSaHtV4Uk1edfXV9aqhRw2+1IBVk66afK2JYy1z9C4XqYXHOzTUNo/aeNRxXsd1XVrr2pl3+V2P7/X0qA+7Pu71PT8N6GiAQwP9GsB/j/8N1TZ03lDfhmob4dDIXjVS+755eQeLeAeLNOZdE/2bqG+iXxPampjLBzh8wA/vX5EPeNnUzjR11tRZU/ebmof3sEgz95u538xz0ozW5p795jCbm28LPFro28Jufkjbh2bTEo+WMFvKaUlbS89mSzvRSm1rmtvQ18autZXfzm63w/0jc2vP+/Y0tze3Drzr4H5HWjrS0Mk+dTKnj+V5T4p84nnqbC6dnXVx1tV37zuRbu5140E3Grup7wanOx2f4vAZrp/R8hkOn7n3Of49xBcwv9DvS15+iedXcr6iuyceX5vx1zR9Y87fqu+lfy87/p05f4f39/r3lteH1315189M+sH6gc/91fY3qx+dD3A+QP8BPB7w6FrPONhxuMfhE4fPQL4M1GuQXoPUDYoXNA2mbTDsn/D8ia9D/K4OefTpbIi8ITz6meah/Bvq+1D4Q81jmH7D9B+m/3D74D0pMlzecL91I+SOoPUX30ea00g5o3AbBXOU3R5F1yg7PBrWaFijYY0259FqxtA1hp4x+I+RM5YXY9WM03uc6/Fm+qvc33j1G++9V0Um0Pc7X3/3DE3EY6LcSfpOxnEyzpPt1hQYU/SZqnbqo08cprk/DfdpaqZ5vqaZ03T3p/N3uvsznM/QcyYs70yRWbydpXY2vDly5vqtmmt35tI4j755OMyHM1+P+e7P12++ugW+L9RjIb4LaVxkVotwXMSPeDmL4SymbYk9WKqHd53IMrqWq1uh7wq/8Sv5vso8Vjtb4xlaq1cC/xLs6Hr4G9Rs9GxspGOTWW5yvclztZlfW3i41fU2XLfb9z/sxw4+79B7Bz079fvTzP6E/ae+u9Tvwm8XzD18/Msc//Z9r977+LUP5n6zP4DPAc/dQTt00PVBPA/Z33/wOezeEWf/8v8ojcf4chzmcX1OeH5O6nOS5lM0n+bHaXVn8DvDr7N0nYV5js/nxQWcL9JyifZL5nIZp8v6XTbXK3Rdweeqe9f0vwb3ut/r6/reoOOG+d00t5v634R9yy7elvuf35k7au/QeUfNHffvwrjn7B7v79u/B/bwgRk9xOvhxhANNcTeEI0MD1HvK9FobdFTzBbHQzSWRmQXhUUrMURMEPPF6RBN5H6iKqKHUJPoSIg+NlCMEzvEvRB9PK9oItQ+vi5En+geoomziXqij1gmzodokvSigtAryXShV9KUwllSNUl3h2gyvZI1F3olxzf55RB9EtZTeD91O0Sfxi1FJiEvBf7P4PlsrxB9zv2UKcTWEH1e/1TwU9GfWi/vStHUctIkFv1D9IWGol2IpnXtfSmaVo+0eKeFn1bPdPikOxii6fFNL//F5KKo0OtFOjLAzyAnwyjBgwx0ZMQn4/UQ9b4UzRQfopn55l0pmhlOZvwz05EFpywFBcwsML0zRbPinFW/rOqzwsoqL9uqEH1J3ktyXoLnvSn6MpyX6X9F7iswXoGdXb/sfM9OW3azyY5zDlxzyM9hxjnofzUIs30V5qv05XSeE89cZpgLfm6+5Taj3Hq/xpfX3MuTS+iZx1le3uXlST54+XDIr1d+e1HAbAu4LkhfQZxf1/cN2G/gU8hMC00WPC0Eo5AdKUxPYfreTCTwesvOFZVflMdF4Rejv5idKA6vuP4l8CpBZwkYJfUsaa4l6SvJj1LOS/l8216Vdl4G1zLulcWtLB+8t0TLuS4Po7yz8vIq2ImK5lFR34rqK8KpBLsyrpVhVDGHKrytQk8VuVVx814TreazGj7VzaIGnjX5WZOOWmprwX5Hz3fs7jv41Pb81IZfB0YdM6xLU1278C6sd/laj4f1eFWfzw30acCX99Q1NJtG7r9Pf2PcmtidJvh/oLapOXnXiDaD1dxcW6hrIf9Ds/8Qp5Z4t+wYoq1obcXz1mbX2mcbXNrwvy0t7fBpx4OPaGsvr73z9n4T2sPuoF8HHnTgQUdaOuLUCY9O+H+s/ydm1Vl0cdYVx274f+q5+ZQn3hmin9Pbw35/QeOXfmu+VPeV35qear/G7WuefiP/G7nfOu+Fz3f0f+9eb89Ubxz62KW+sPvJ6+f6B89+fx7/iPePrgfoH4f3wJIhOojuwTgPtlc/2echuP3Mj6F0D5Xr3/focPMf4XqEnF/gjeTfKJij9RtN9xjfx/BiDC1jeTdW/Vjn4+zKOPrHyxuv7684/krnb/An4DfB99/NZ6KdmAh7kplMhjXZczKFv1Ptx1QcptnXaa6n4zBdjn+PozNhznI9C9Zsnszm9xz655jvHLOeS9dcXOY6n0frPM/TPHOar/983vp3OTrfvfk4LMBrAa4L4CyAuQDXhbxb6GwhLxeqXQhzoXz/dkcXwVtkdxbpv8gMFuEU7zmMlx/vLN5ZvLnF671Y78VyF/NtsZktwXsJT5fQs4S2pXov1Xup3sv0WOb7MrXL+LfcXJbjvtweLOf5cruxQs4Kz/4K91e6v9L9le6vdH8lTStxX2mvVtGxSv4qeavlrZa3mpbVzld7Dlb7DVrD9zV6rTGDNfit4eUavNY8umdua3m4lqdraVpr9us8R+t8XycvQc8EtQn8TsA3gZb1nuH1tK7HZb2c9XxZj8sGfm1wvkHtBt5swHGD843yN9qDjfI38mYjjE2enU32cpPnbZPcTXI32avNsDc73+x8M8zNNGyWv4WGLXhs4esWvy9b9NnifKud28rnrfZqG8+2+e3YRv82fm/jyzY5281mO33b8drOu+1msJ3uP+j+w578wZM/zOMP+7QDzg65O+DvwGuHXdpB8058dzrfycOd8HbSvFOPP+3mnzj9CX+X/F082mUfdtOxmxe79d6Nx25e73G2B94e3PZ4zvfI+4tnf8H6y2/cX3j9TcPf9utvz9nfuP6t7147upcne/m319leXu21n/vMeh+t+/ixj0/78Nyv336e7Df//Wa8n6cH6Dxg5w/gd0DtAbUH5R3E7yBPDjo/6Pyg80P0HJJ7yG/JIWeHaPyHp//Q/Y+8f3A8jM9hHA87OyzvMI8Om/MROEdgH8HniPkcwf2I+n+d/+v8X+f/0v2v86N0HnV+1PlRuo7y/yi8o/ge0/+Y/sf4cswOHHPvmP32Thk97vw43ONwvV9Gj+N8AucTOJ9wdkKPEzBPmtdJ5yft3UnzOem34KS5nbSvJ/lyklen7OUpz9QpvE7x75Sz03id5s1pOKfdO43DafM6bYan7dIZfc/w7Yy5en+NnjHXs+bqPTZ61vlZPM7Scxbvs3iftQ9ncT+H+zk9z5nrOTM8x4Pzzs7bqfNmcN68zjs/j8d5Hp+3Gxc8exf0vqD3BX0v6HmB5gs0X6TtojPvytGLzi/CugjrIqyLPLxEwyX8L9F2Sc9LtF12dpnfl2FdhnXZ+WVYl2FdgXMF/yt0XaHrCl1XnV21r1fpv2r2V51f5e9VPlzF4Zrn6podvGY3r9FwTc9r+l3j/3X8rttN7+bR62Z+XT/v6NEbcm/w4IZ9v6HXTRpv8uWm+dzU/yaet/S8Zca39LtF0y14t+Xdxv+2+tt038bptvu3PYe3cfnPLv1H73/4/8eL//h7R80dNXfU3FFzR80dNXf0vKPnXffv4nkXz7t8ugv/rt+Ae+Zyz2/NPTX31NxTc0/NPTX31dzX876e992/z/v77t3H+4HdeGCeD+h7YBcfmNUDz8VDvykP8XvIy4fOHx4MsZBNDAmxSFHRSvQU08XeEIsGkUbkFRVEE9EnxGLOY91DLFEu0VD0F/HieIg9llJUET2EPo+tE3Aery22htgTvcR8ITdxCgE3cTsxSrifJJGAlwRWEhhJBorJIebvjFhS3JLql/RyiCXDK1lJodbfGrFksJK5lwxWsushljy9qCem//+g50lcn1wWYk+pfSq7KCxofmq42BhiT/Pi6eZigsAvhesU9KY4HWLP1BCwntkdYs/i8Sys5zIJup6j/7kdIZaSHyl9f15+Kvip9E6lPpXr1PxLDSM1fmloSQPzBZ8v0PjCbIFzWhj+lomlwysdD9PxIF1noUc6/qSH/6K6DLzNyLtMfMrs098ksaw4Z8P5ZZxePhJir/Axe2LhPAeOr54PsZw8yG12ueW9hlNe5/nU5qMln3v5b4dYgXshVtC91+W/gVchmIXpehOHN50VSS5cF8GrCC/fgvEWX/0dECvKl6L0FTPTYngW53Fxe1FCj5Jm4f0/VspZKfMo9ei7fm/r9bbepeWUNucy+pehr6w9KafG3wGx8vqVXxViFcqIcQI/fwvEKvpe0Twq0VqJv5V4X8kOVeZJZd5VhlOZniq8rEJLVVyr8rgqj/1dEKsGp5r+1XlQnU813K9BSw09auJVE4ea5lLLTtQyu3fUvkNzbR7XxrUOzXVorquurl51+f4uHfVc16O/Pn/r61EfXn2eNzDvBng30qs5zm3sYRvXbfD2rh9ry5u2atqqaaumLZ3t1LQz+4/MuoM97wDDe36so89OsD7Gxzt+rLP6Lvp0tXPdzLgb7d31786H7uo/xfVTWj5z/TmvPud9D/Vf8OoLM/rSPL/iRU/fv9b/a/2/6Rhi3+L5rXvf4u/dP9bLjnwH83vPXm+1veH1dt2HR33w6OusLw/7mk1fO9WPj/141M/z8QPfftDrB7Psz//+8vrL60/nj+79aN4DnPt7ITaAnjjY/m6IxXke4nCOcz8OXpxnJs7OxPE4zhzicB6obqC8ge4PxGcQHoNcD8JrkNkP8psxmLeDeTGYlp/0+onHQ3g1xG/MEFx/pulnGn/2fajvQ/k5FI9hcoapHQZvmNrhvBwub7h5DIc13NkI+CNcj+DhL343fqHzF36MxGMkn0fiMJL/o+COsrOj1Y/hy1h1Y/kxjv7xcsfjPB7H8XJ/5c+vdvE3e/ebnAl2YQLOv+Pzuz6/6zmRRxPlT+LPJF5MljNZ7ylypnhupvBqipop9E/VeyrMqXhNgzXNczGNj9NonC5/uh7TeTGd/hn4zIA/g+YZ+M6UPxPmTLOZaV6z8v4fwq7N9izM1mOO3nPwmGN/5nrW5sGdj/t8XBbgu4BvC81xke/xuMR7Bhab/WJ76G+Y2BKclvJ0mbNlOCy328vlr+DtCv6vlLNS71U8WIWfvz9iq/Vabe/WmNcautbwdC3Na3mwVu4639fhsY7+BPoScEyw8wnuJ/B9vV4b9NnA5421/wfAjkaUeNqMfQdglEX2+JSvbO81m2yyqUCAQJYkBIEsSgkgEEDKAiEBAQFFmoCASu+9ifQiIiD9IkVFsIOCXe9+clZsdzY8u2S//N/Mty0h5/2BTZZkvjdv3rx5bd57iwiagxCdR75HFMnIHzJISKaIarQilhAquFJwxWrDpaXWoDXYulXQGrDSgDUwh5J5CiKIfB+xkQmKAyFECIUvl8TOHE6zkJ3KMhEEjRZj+CbuGCrAgLKCfKsNlXoKGExrkMPEWTRIi4JOcmKj58WXn8er6Ok/n7l0CTGY2El70VPiZQ4zEDLJEqESww0hiSBUFgwWFCahx0BxcCtXN/lEca5q+gntReZE5hFYIkHFCAkrxC7Ih9LRidB4TVqqU3BorQaD1mY26QWd3e5wpftlQXILGHkFjyhKDkkXoClu6tF5MgIawWA0HAunYWMqslgtx8Jep3WOcY1xl5H2MVYZSR8r7mOtsv5gpdZQema50Wq0im471YmoIFgWtJWWFhTkV06unAzrzrcitvjod74AN3zn67C5S/mLvyssVL/D2mjAGaBZdvbKKgrCK2APUvYKws8Ddrr3NiwoXwy+d6Cy6Y5777j06W0/Yjl872B89+B7B78TCXXB42+jnZQX7lHG4kfY6x7c4R71nTL2HuUF3AHYAN1aN1V4SHwRZaPmqA06EBrjySikgsHZFLZQbGHTajQ5tlRfCx+yoaLi9GbOZlPDrY1NjVPDGU2bOqXUVI/TFcrIK3eFbO5yl8spFRokw9Qw0lq0IW2Ftlorsm+7tce117WiViutFbEoUsnDd7LSCq/JjCSesmBBfj7QB/iktIBTib2iOx1km82+2DjV3GzjHZLszCrKpiV+7LbmtSRFbYpLgKfgf3JLnGf1U+xgvzFh3Ib9vyMWHrr+yVxlSNdDKbuX+g/s6H71rblPvdriqGvuhMNbh7WsPV4wZMZD88m+klHL1m7ED+w9p92zx4TDOQ89KON/aZqOWDp80+Py/PnyuoOB8ffIysBm5cNmkpalvYLpeIc4OtLs1oGlWUpT7TSEgFXrfhZeF/sCdU0oBeWg1mhoqBhhs9Q8i1CaJWHBkJuW5jQYgoW+pqfCGb7TQzMK4LtX6zkVFrSnhwo2+C4TCQGdysry8/ORh31VzxAwiMotwegRzcLBnAyrQ8rKzAUq4Da5WZmS0+EKFhaLjf/4w3V034ba3di3ftWq9StxelmPXrfeenu324jmph+J3TXK8cePHj74+EHl+IwJ42fdN2niTzf9BFaaX/etsEfsxVd7Cxofuq1Y09yYa8/2paba/dRb6G7ZRmfUGNp36FKItYVYj7wWb4aXmmlLnbuNz+svpFrRYmnaN2yhgVKxtG8YiS5gEpU5mAxxl1YNrxxeWQlEcMd4gi1fzMzN42u05LTEsNBgocvpMGHZ5S4ucUuyHwcLS5xSbPnujoTCeJUOQqvuqwq3PP/KVZydkX92//pjfTb9beG6wTnrmk/PH9GkXU4rZVv17eGJHfaMbNOjZunflt8fetDQ9ZZlF09iw+b2W7os3bt2ds9po3t+tfPUJ/nfflYctCxxCd279h3Z794pnct61r722vcjXpm6tATkGsa/gmB6n8s1d0hLCRFEJqFghVHJqMoycjgqwvgzA5VBdDY8Y0SZIbNOrxcoSEXZZNYhwQeMERepqii02NxZucRqsZUEJUKshy48e+HxfS88e+EQsSnfKZ2//RY/jV3Yik9f/1a5jcOvAPjTYvD1Oh0VBBkhBp82Bp/IWcU2q4XkBV02Ou2xCxdePHDgxQsv7CUO5Wul27c/4nPYiA343I/XldsZfPQ7qaXviq/BKbgz1MpkNOqIjpgtRKeD7TdQraCZZlhkIBpJaxDkOfo1eqLXG8VJ8lx5rUzlM3UXTmkN5bJs5FTKrwSBWlAJnF8ZY30uEZiAsKn0y3GLblmP80pySkQg5S6saaF8eXbGw9tnnFO+boH1hqXCvrsWdv+zHJM6VP5798V346Ycz/tQjTBI2In0yBHSEoNRFI6Exb+hMn7gALA1yxooCsBsASc5tkEZjA9swAdItXIHPrweH1buWA+0pMom8iTOh/3NCFkowqAqBRGj7UMFvG0oUs9uTGnZAzD+INYql+ChhyPj2V70xm/Sh8gkeN4bMiDKnn0qXIAxRgWV6sPwYFHAiXuTVvjN3bvZM9eBha7yOd0hHShj4Ck2GSrIj/EUQxpf/wbnK+/BOqfAGQ1zHkwNGTBoZwKPUC9G0c2O4ufGQTyFFp2sfcMhfvJnBtPLFD0Az/YRhwCN3KBP7wi1TPEabDbJgCSUmmb2YLMn3UOMnpDZm+4lTur1Uq3WPDWslalzaph6gZhIPcdgC8BBTrkyHPRibE6mCDmHZWUyBg4U2mjsfbDQlgNyXejzx08//fw9qvvju9Or9u5ft2H3ro3K4G/Io8pRZRu+E9+BK/EQ5VFlP87EtA4pV5Vryh/YtPOPP2DdG4E048EOMKG2oTSjQcI6bIAjaLbI0tSwLFOdZMAIg9bysD3n2igYpaE7JmRh/yUhq6gwu4SxwQ58Okf5ZvFGLLfZj0eso5He922cf+eN29dxfloL87UHWqWi9qG0FISMplTZYXKk+Y1Gq1U3NWyVcQpKSZ6Pfy1IqLvonB1xSUeQaUx0yXkdMRdtkgzCLeBc2/qNk7tWLp87ZZXxjOP759/7/pHNr+8KkHemTfhw9ZxnBk28/8HJ1kOvXDg+9Yv7923rvp7jNRf2sCfg1QxND3XKy4bta57m98uSOzub7WN+8zyb1WadGjaDiKU2Gw2kpQUCgGdAptqp4RAcS8K+XIfTKbMt5dobJbAvZTvL97gRxW0r5Vo7KzM7r8QVKCwuAr2cj4uChY2sENS40LP2s/frkPupbGxeum3o9hFjRg5c02/RghkbDE86fnv+3W92Ltt8Gk956vLzz1j/fGhmz7tKtpeO7TZ+xqyJpiPPP/34jOOpgvUkMPhdsBejYe91IOW6hvIMolEiGi2hWMQmMxIMwtSwRjQb0g0FhokGwWDAeknCTO1ycRNMMkPccUnI5QGG904tDtCDNZEpZPYrzyhrFQP+GZcpz+GylXRW7dLV9LZIzwTdu6A0NDjUwuux250Oh0Y2upj5ne7wTg07HD6fZWrY5xOcTs/UsFMSgEs0GoHTOOngqITOr8cn7B+jrAmDEgTSBhlpOT3BdARDkSlEoef0a9te+k/GqdJvVx3Yv6L7Q2XHC2ggsiht2tHLN/AzK96eevhR51sH1j2ws2UJ+cc6ZdCQb5h22gx4lwO/uFAWWDCFVr9fMuj1bmCV7BwH8EWVAyOHxUF01OGA424CzjFgKwX7WqaBxKkPxtmCH/3K/GTusAajbAGHHQUz7DKgTpycE2S2DBOO6uryn979VsGa67is/+Giv2051Prk1Atfn96yoMfCnnsemrMZP/uugsO4Ax6GH1A+TT+s/PvG0KrvXl+7+7YZPR+5fIDz/07ghRawD1rUPOQES0zWg+uDdHoka2Sgt0TYvifZnTHFgqxZFpsdVIDQQsl75pf/RNLpGuGpyODI91gmIzCceooWAa26Aq18KBcVgv1T6nG20OUZU52ZRmMLyZkHRAu2QVaLlZhpOiUW0aPT5TTLAXM6J4darelMKtBWN4lK9TQFq1TDJ7HrDc5ULjd/mf3DKOfH0UNE40Zfhj3J/hO6/vHVZ3U7Z09aOvHVBcsu37N80vxtHy2ZM3vZ8gewkLV91dJtm9dvWItnnXn/7afmPekUfEcnjdw9OLxz9OSjLsF5Av8ycfKUeyfOUubeP2/FlCWrljNeWQXrL4vySlWorSxJaTaD2w1uQ3aOOWNq2GA2p5t3mY+ZfzDXmSUdNZup0wk85OSyhSl9Ehcq9VVFMKE746YIivG6rYTxPbP+gxmJ1YJMEcqUX39+7JX8w8Vnth4hTZ6/79wXNz7AH764e878hx+ee/uS3uS8sl9ZsmKb7zh2/zpkAqq78u5virDn0tEVa451mc19Ua5fhXbcF80L2SUqgpLVakRh21DRHFO1Kq5x55ZpXKpq3W+43qVmrn0ZvGplE7VF4bUKpRCMJVkQJUEC/1bYPlQjbhuKEbzMKGbt81VHuZABZZbD9W+URdx4UCHfWKyaENyO2Qp2zCFgtVtCGQIC/0GSNRgJAhHLpInSHIlKIZuzXKJmAvYJSDfVqupQEAwmqX97EQa55ryPXqvdT4eQW67gvVuV9cq6LWwN6D48WBhEv+VrGBi6RYATgEGgCuKRsFmYKKwRdgnHBDGFCiGbqxzc6iPhVrgCV+NJWKiAL3PxcfwmFs2qYcPVR0G+Kh6SEAAzB14MgzR6jQ7euFFBGzeiBmssDaXH1iiJhFCzgAVchiaiOYAcWyfbncpCWGbDFZYUaXERW+EQWOG1rVvwRHzvVmX4Fba+4SAjWgMfp6EA6hIKaAIBrd+P3B4rKOvMLK3W5/en7xjqd7t9PkdV2CdENXhBcpwjvmtR6QYK2wTGc0dS0pHEdF1xdrBQwMyyad28/7B7uzXFx0iLPlV339Zk19IlB01nUrD+jY8xiqx5gf67+5QRt1b0GFjSdWJlt949BpRMmLb+IcNL7z134y4WNSGoufKF8BjYde1Rd7Qm1M/jc3fwUbFFy84mk9iSFmWgvCJU1KNnWld91/fDMtXbQu+H3W6tE+ucNrM+XV+ln6ifoxf1yAZ2UQu9zaZvQVuXlma9Fy5FrZu9F24dZ3PwwmCpBdwTswaHMw5iAY1kmRl3Tt0xtyErswMuyeL6qaiNjekjd7AkSOGkwvktYr+XiJNZeuCw8VGkyGID8rhsYlQDWOB3NuGxx1auIVLm7N7jZ4x4/K5uQ11ixn13Nmnd+84PajZ+/sDXrw4/Orrb1H/MeOzG4q3Y/8zOfz2kjOx6S9n4TlN6TC8lPynvK7t2aPyD7754dg/2P9Z/yGZFfLvzYNzsD2zDA/6uzPpDeU1Z3XXwoDuHPI8nfI/9+Okfn1SefGb8hEU/LVS+eha34/wPf4TLoENksCf6h5rpCQXbURJBWYNrBg6U2SRjoidVYdCUQzS4pwYDd1IB5GBZIZiVlZXR8EYsIlYY5RSwgLkRHKABCg69FpsxvBN0yyNXlr2Ilf/Dv0S2G7psxm8cwQ8p88Uufz4tPJn3rhLGP6v2+V7Aay7gZURO5EcVoSZ6n4khZQejwoUElJ6ht6fYU6rCdrsgiraqMCDlqwoLtkbUTULccg2oahkhK2ANsHgCuNTgTeeDPGJKBb6DMSfMVb7/WWmCt+Prax94/LTy/ebNH3+Km/c9ebwW6449hh+ouSh2Uc7O2ue1ncTX7h6qVCvzptyvZM7kZ3oy6I7pXHeMDpVZLRZJlj3IYHB7kMliImZtupYYRRMcN6vVJCCplRSSKJIqpN3ScekT6bokGagkabW0Kqy1x84jsOhkbjzFVGfyiYwyGwlkgEYOgNHRkikR3O6J46P3le7apJxU/lC+IB7cf86BnB13PfEYOaj8oPywbF0nZSUej/uTE8qJTpMXKCwgujdqX2qQFTUJOUyCFohts4tGTmFTPQonPEALagp0y0DUwglZaBNGK1eUz5TVuAR3x7dd+OcPM/e++zo5rjypbAPCnVZqsObHGz9hHacXm3MkzKlHg0LFolaLqE4nIwqOq6YqnC4WiMQMX8rEKnGOeEz8WJTTqQiuIRaqwpgibVUY2Rr6Y5Pzo3GVeNjXGYi+9tLNkSZke2QU2MxdtitDtirB7aosfh7w6MDtqdtDBVgUJQ2RqE7P5jHjPrgKg4YqA+FKDRSHnE3LMRZlGVWBCBJt3NJSeQ6mn5KYnmk6NjHY2E48j+yLDDtPZwsHFdvOyDWYP8YvzBf1Ap+b3D6LqNc5dUhEKT7NmbrrIa/RWu5xV4U9HqLRwD7o9RqBAMcTe8wejc2M6pmijM9zwJgCnkAB1RKVgD2AU5j7L/T64l9/Kt9iDdbiIVOfqHjz4B48oPP6lspV/PGiLXgq7oGH4oHKk22/qlW+inzULANX7I7uVTO+V6CTZUoFDUJ6QW8wyiAjKmS8Wz7OLB9tQkaUFqi7UZoU44N9AIKwYDxYF3dHfj1/nujOk4mRdWKXyKuk+M+n+X68CnNhPldpKFWC/ZaBF7Vag1HQyMAZso3qkR52nya7nXHbJap8oxsP/m7gVVqivIjb117C7ZUXgfY3ftq+XTCqe3+87lv6AcxlAUvGY7LJPBJgtZmB482U6qqYX21Pcl/iWjFmseaVsNCcF8NM9IO3n33ictbTtmnht5RL+Be8762vTl5Inz4Xe6k2ymuMjq/xtZWHcjVarQ44Wc/oqRcMRpyht5YTWYeny4uBmliTRE01XpRMUJCzKlGxzInKpC39RvE+ClRt/6miIV3IQweVfCBtFdkTebH2Nzb/dzD/7TC/iNJDJjADRUkGDGjiLEUnYGeHnZ7vzpPdYpcbg7bDs/PgWeb/eQB3lwshj0a2W4xGk8nuoSleQa8328/UXQgZTNZyu0bjMlNTnBUAcTXM5U4YwCpDtCkD65Fm0dw8O1uF3eUuw3bgjoOUhtL3Ldtv6y3s/u6ssyCl+dlP6aglt456fYDSA59q+YvyTu12kCnuopNDVuJ/c9ZJ4lMj6hzKlQVBRHq9QTSYzPqVGM/CeBxYbBJdoMHTNHgMKDXEjjDTZ5Vl7EuwIcNil5OhhXOLGMt2jvxuOfQRsdgOC+MP96vdCJRZvXY+rWazEzQGzvMYHltyMhlq4bzkcmuBl7QCtVeFqb1RGaoe1WAhiFHQTDxWJIxRfvv9D+VPLER+w5pLyqvKxZ1bHt0IAvyYshGPwYNwXzDDH1MOEWfkG+U/cJ49/N6Jr7+K85cdtQmlGJBFkmQkOx2iBSQ5iDaNuSqsoVKy4Epac9QD52KrUJDbBGDtoBarZny4TvnqPL78PaYXlDO/KpueoCcefPHeiCJ2ee95JfLder5+5UFhMtd/Gei2UDY1mZDPqnEjZLLSQKbDWxV2CCY/kMFk10vV4So91iPVSwrGqBINiUddBQuJxb3ZQcslN1PppdNNF48uaV854OEXyq5+eTO1PlL2NH9oinGx6+CrLnwnDjVCNpVmW6I2R1WoCBmNWmwwUJPWBudSK7hdBmIDKdfHhs22MttE23nbDzbRQG02JIpWrh9VPq+nhlCw3lFNMFQWpy2PD4Fj25TbHfScsv778/izf/389A689nflTeU69qzZQsoiz4ldnqvZdDkl8gS98rHSbC7j8T7AZ2OBzs1Rj1ATScx0paUaEEp1iUKLlpkGL/VmVIfT0rwCBRUZAvuCSJIqwyqT1EZp0mFU913IyqBcmLGYFskDi5vfQrCLqKwMp8NP3H5BGKv89IdS0uNs6vENux7rNH5R5z3L+jX76dq7nzR/xrP2QeWLoqEzu6yYVdU5D0858zoekzNv2gNTug5um2VtduuAe3sceXrj8cCk0e+179k6w5ZV0L7fvWw9t0dtPhnlhmwyyHsCnhgSRIHRFtuSghn1IlcBJ3npWaWL0EY4eGOQcHA716mrgTZMl1tRTsiqlcxwAm12CwhYQ+L4BesdP8ZbXhy08pACnHKhw+e1P189P23rnvnP4n8rv/z0DcZ0Qu2Ry7v2vUu7sjnAehGe57G4wpCXgtksEa2O6PQGLaEDJNxZwhLCUbESn4xbbYXAAGAVY3apg4Pk0suKfAmH0ouaNMcdL4ldamcNfG7TfLoY5ojZ5240NNRaIxutFnBCHQ7BqBVcbp1W6/Z4hQJLH0uVhVosRpeWOozZRmzUgHkka/jcbH2gM6IBwPiS3aVJ4bZAlg7nmTCIXyZ4O4LgddncPhykf77Zo1d+WusZb75zboLFmpE/61iXPq2zxp7DDpxx4cFXlf6A7LkFf19eg89FlI/+iYfQ21T5mw14H+TyJxQKUAlpBQH8CKCORhRkjaAxGpCWSgLWCDam+soYfu7SJL0adbpAv2qZQsvi/4JkDO51RemF/3lFWa6suIL/qfS6QjsTHHkgUkY6RF4gz5GF8fkPcDu2YyjAptRI4E4TotNKNIQqUDWiZYy8WBZU1uLkqQzG2MtWWmiN8xhDIEhefEZJvYKn4/uukPLIGVJOIpEd5E4A0h3mWsDtxqJQiqAhWgpKW6eXo5xLQL2ApWpraKWUxqjfFLx3xsY4ICy48TItjLjp87Wv0xFrhJTtK258xu+2tiqD6DnwiWWmUcDAEhHSaLHwSxjWIP4SRr4kjRI/Hartg7eSLGUdnqgMkqet+GPPCk6fqXA+hsTuTghGFFNBBHfQW//uRAQmpftq3zhJi2KXJxibAJfWMVwEkPiyzCI+v4QBKfxfcGH2F7ywCfBYB/gMWiFVrfhdxWURfkroCvSTUOuQRxRAMRPwh6gka5h/ii2YYIGxSGVysgQ/R8AchJ0jehh8iqcewbNeww/gp2hW7Yd0Re00eLbuRl228FbdQlinM6SlIhiU6GmgGcg+zBGTge6i8P4/q6s53+L1wgnaTqwBu8gT0jNUwBFZORRtQGXxSyicUxR0O8mzyrsvXRNOfJn2gwN0B4uJLxV6o0xUgEaF2rUwe1Nsmry8jIwUM23V2takb9hmM6SavRO9H3t/8NZ5RT31elNTXRXhVIshqwJI1xfUssbg4pkE+YlrCNAi7CYi4VBE5XROTB1GIxGWnJJYLMbG1ArIsZzCjrgDi9U4HS6hV0qgc7dRQyWp04n5O3fjl78df9/0sbpnWuKZFy81i3xQvbHfs9Mf6BKeKE+yjJs0c/zhh3GlKNyyYOodg604++kTSsuKvtKwrf3CAml1Z79+o5ie/xus+VbgAycKsJuoVNFkMrrY7WuWw1sRtjosRqRz0nRYHOV337CmsrL64c9oQCUvC7RgFpO6VoccrB/7LBZufe3cz0OITI5KNYIw9Ce85KnZCzYtXbh5yUySqXyufHmm1VhD8UHhOyXcadjFyOVPLl396K1X31Ll0HzAsS3sSwoaG/IbkSxJdgdy+FIn2TGyW+zV9kn2ufYLdklLuc2a4fOX2+0ej6Ui7HFRXUU4XZ4jr5GpHIJfgAtgUe9uE9vDvL3JyV4XuBzMOlHVZWwJJW4TrBLNx+TnU9+mXrDMnb5zw4Yd96y2Pmuc8eLMX+oQ8cPJyDy20TR03ItXP7oyfoKhekcYZ6i23PK6LwUv0NkF3NUulOaW0pDJZJbMWdl2pwlpMirCeo2FplSAJxSjs0rsOKVVjuGhZeYButzBPEZqd1ZLED2OxB0LHd5678xXn8VLZz7ampAa6bAgRT6dsXj9yiWbltx/dFwVdmEPKR44cjN+9Ib9YLH5vnx8z0evvfPl3198HfDkdwZAawdQu0+oOViiRkn22u2ykfpSPQhI6tFZLM6KsMWioxXhj6UfJDIXlKSkc3GrpLJ+5KaBWeKKB9Si96hWJwZuDxB8656Vd21L2dn8m0e/Vf745pv/KDmLt4ukPBX/dur1cK8WDyzEudiG9Thd+Uz52IPfPrYFlzPeWM79mMvgxwRDKS4mdojRm6KzVoSZZheFirBLNGMnKkvK24htdNz4iBpHTrbbJpyGwRrpXAMGu/Tcp+WPN/OfLhg7vjX+hh6uvYMeXu29ctioWScaWo6t1K3me7tGGSz4hZ5wggpQ31C+QGkTa6Zbq023prdq7TM7cirCbofF1BxwMjmRXBHOEFoJRBCYkC1MMpqDST5bUpJDzC+1FmUlKAfb36a4JCiBjJBi9yhsUEdM7jpwOfWMdfKw30nro/e/fPrFy5Mfb0E1whPSu4GHFyybFbxnxIB5XZXBy+d5e/bFtzx/13hMgSd8WD9uhH+NofhQ7cvXvqBvPPfh+Y83H6uoOq2ewbNATca/DvCt3QKx2x06vUPvdDl0TtlcERZkC0KcyPVsMi4d7DGB4AV7WUXVmnX2SS0d9288/MlxUx/YVSNeVmbdsvyKsiBSQE4vXfjktsgqRlcex7oMOtmI2ofS9QYDZnsqggOo6x/WIw2QUmNGAoVdps64aq6nttRTEw0eFAXyWI7fv/ADtc3wfuU5/NPFi6tXr6b+1W9fuKCe02mgFzvDnBZYaXEo1epwIGSQDE6Xzdo/bENmU0XYbKZamDCmIev5gFzfqrGEItUGjU5KO3/yRp99LR6ePXe5Mo70vHgx9em3U6wrMxfOoC+ps2P0bXS9etQhlIZ1Wh6a0WrV2AwLJchYYwb1B8IaPJSyWJ5C8sWlGq9NDiKsV9YvrKnBV99RuuPX8U8jlYni5doRxKgURDYjEbw2JAyDOc2wYiu4PrDcHNGZAx5aHlf2LrfLnefOK6K3Ya+yenIbF1U+xu9hj7P0LsuLG8TVgqOrf7HQfvWNQAuXXVv13er7VH65E+COAjmSh7qEMl15eQhp09P9Zo1G69c2aZol2GHPUlxmu8VgTtfyBcGKgg3C9knB3kCcc6xt8kB1B/l1rFv9xn+q/prYW3cK9TkobZJI5tjegwfZSZOJA6aPOdC60629yNGtsy/si+yh/c81m9NqTGX1qPFDDr8FLAc/P3AAWA7w/hvjc8DbgwpCbiugizxajzcF+AAQdgC22ij1GyDaEEPwsII878tKR3EWlw5hQgkd9+ORQzEWZ3iIzUv7XHn6+UgB8B7Tc91hbpbPAlaZmsni8WrhfGktFGQuUw03xxwSWSn1NG73G999/Vvk65+/P7dsy7a1a9fuWk38yg+we9mgptywm/9Wvvz7u/945+2r7zM7QBkk3CpUwMxZzA7ws6V74ORl5zh9YAc4YeUaHwnASSd/ZQcEwAxwxUmg7lJ9tG5V7v91gCg8KR3DIJ4Ltz348vNPzVqwefHiTYtmkczIq2c0OxUwNg4VC8E7PeOqAONrnz139aP3Xn5V1aOAZ4rQg+vRopAvzemmBoPeqc/KtoEONdlceh8CLUqBncsKOZZJSKoES5KdWdaSmExNTkYk1nlbWxNZPCY9KZCinQ+8+ix5b+nGxTNnLdiwQugRrvLPMRR/fqMYnz5w92jsxU5SHPnk3Vcuf/zh5Q8YD/0HeMgJ++hETUMOkyTJstPlNtntpF/YbtGbJSfPoEzmH8Aqzju5eUHG1yRY6Back0btebnG532iiUYsrF5YNXYMfdj+n6cVgZy7/fU7l0+aNK7Iqp63x4F3skEH5aLeoWaylG5P8RrAEbBLQl6TdIOLutLAtEiZlEL0NCXFZWFmEZhCrlg0NJEPcXMsIR4ZzQADIy87ltGoGkdAsHTsJ0L2v15//e+BXfYHN2PTyNHK76tvf/fS8bdT9urvn/FL/2EzHl3TDxdtPTZvRfrAPk+E+ng79ZjYf8P+RXMc5T02ty93pTfpPU1dx7N11+kf4h1Au+KQT9RqicNhdrmtBuBBFzjEYICImFJ2HR0ssDam0u1FQbt6VcC2UrWvi6zPHmp3Pz6uVAwYsfjRg/v37gU9jlOUL1dH7utze+aylss2kl1RPQd0TBfaAemi5x97PNoUn9XphPPvdBmdGhCVjZ5/HI86cKOMxIx6K54w8qF5Dz8ZFQAdH5158jGhXaTf9pnHd5OptUdUGTCp8sRlErV3uwD/LAEcdCzqFw1JUKIjBr2WmONBCWeDoETcneJRiXRchsHffe09pc+r2GBtk5WHHZdg2lDRmWnTyfN8HifMc4avdUioJUY2s4lKot5G9VT2eDWyV/alUJNJL3u9Ho1stumn6RfpiV4EjPjcQTUkEUuQrn/ZmhSWoHkyD0rYnMUldhabaNORwBv65+U1pXkHXjt9sjKQZ1/y3PwMt8ZgoKOP47+/uiLyb8B1j/J7x93F+IAyaNw9/iFVA72kiuPN7sMnAN56ZhWwuLuMBXAu9ZIoEkrZPYZOwIJGNFNVVgfd9ZK/AD9VYKvhCP6P7lPOK+eex7uUqa/g5rjZJWUq3oefUTqT5sSkDMWPRX6OvM3mvhXkzzKY24FKQz6b1kRMOotVr9NZnS6TVitadGYkVsTd52B9wpSqG4QzVeOA7RB2uUvgqwnj7B6FuS37rGhlU5pdwJqhclNc/KzSNnxeGaRfIk2f11ooiDz0if9earvx8jfPcjpsADo0B1x4zEKmWEOAMXR6iQpgmQtmLDNbEzn/a8wiGAtZODeQg5E59PbIQPLGMpq7YlntBysA/jVYaw7YBlloYKjQkuXya/T+LK9IaXYOsIdG/iVs1hRo1mje0PygEa1Uo7FkWay/hMESzKwXQYgGUuMXufEMRsyOB8iUoo4YvhcHA04uBNVEIeb93oKdNHX+vvXz5q/buxBr3xtaMfeuMfMqhr6nDDq4GFfdfb+4TJw1Flcv279i8N3K/pGbvMSz4S7lsfFhwJ/YlUHkLI+PuEJanosK9mMii1jNXyH2/SyowsMYTI6C/fcvvuYhoSKtx0cz7GB9ZlBRzM7R+lJ9qbBoX4Fvje+Y7w3fDz7JSn0+O7LbfgnbGwZOGl+2W5VRTFBE86Os7Ma6KOrvu50mtnIp6/H3hvadO2bM3Iph72Htoj2MBPvmK4NWhMfjoWM2eoj34RF4yLghK/YvU3aPmwl0mDle2bPkAFvDPaSpUE3zYOfbhjLsssuNLEfCMgq5U8tRSGsoR/qQXa9n2THRqD0wRorHciU/vzCe1lvoVqP1agofj0kUFeOpYxZtGJQ9f0r7qQO6rOs+b/Bt93WaSPNaBh3DNjXLbZ7SomnBmjuAjHV1KPrHIgH1eV2O8iu5FM0zahGyg/dDWcQJIfDLpR1DZTM9g02Je4zksFPQnmV3ZhURHy/NIUdqu4udL11iMae6F4Su4p0oHc0KdbMD+2m1RsHtclEhzSgYMwIWMATS3XPca9zU7bZbZF0GxYhaaDWdROfSC1TSUkp1OtApFp1FpzFbsVWDCgoq1SqZ+JU9txwKKuuZEdbExb3q0bLKj1xS1MaWqPhQzQkye/IG6ynn+3vmvvnF11fm7ricdta6YNb2PQewcdI4w+ozphdeMGP719ex13bmjPHgStPQey6de/kS28e2wLIbxCGg0+8N3ZKLkMOeSX3phnRKNXZNXhO/Tq+bGvbBJhqoXk8tFvfUMM991FKHwyILmTRzajg3l3q4ko9WtNRLe2yQSZqIMkhZgaKOpAPOKgomK3uJucYBdtvBbqCFDYVnatcM6pbz1FP/d2XL5cyjrmm9Z93PKnnK+5PBt5Tqr1/f2rz35H6rVv/z+VdnTigtC0198B+rV8xd07yoiNtyO9GnQoEwFY5MHhoRCqaiTBMyNWlq83icWtFALCl2tzuFiILsdKYfD1ucrZzE7ITFOnWCIMs5x4Gno9sUjCVxooTpYmU/T07halOSV+KGxbhL3LLL6ZDdMivSyJPzSnJLkuInp3qPGnvnlJXLpowYW13Rb9SY0VOWrZkwbsyY3lv3TZuy/7Gp0/aRw8unjLprdL+KEeOqpy2B9+NG964YN27MlJVT9u+dft9jj8PetYG9e0TsAnbqkFCB3WYDT1mLBBfVGK0aykL+st6grw4LBmq2mKvDDmQxwF+N00Y10Ug28GC0OMsa3ye11Mim5ugA77HdiCYmFAVK4KVGuWtxJ2UenqPMO6kswA8SeB9SRr+Cx+EJr5DHVy9bW8cSwpetJjsjm8k47veCrCwFWXmUn8/ckBUOJ2J1cyISERZ8PB1fRSk5Nq2mFYIE3b+f7KO62l9vbKL62l/Y3u6qu0NoDnK0DeqEloe6lzlv8dzSvKBtka6wsHm639+8yJbj8dgESm3Nbbfe1tZUUNbU6SjILiDGAmwWCpzI58vsG0bp1elgsaan+5DcNywILMZQyAzWgiSDlWfTqAZH8oVv4m+0pE2Va4mgHpxScFF48pAz6fqfZ4HncSu3hH8FzyCPpfzC+I6Y3H/kPd8e07wJD85rP3H+hu0DZ4yaNPqrt9+6mrnHsWb5godD03a9cGj2uOqJ7+BPVxyfMO+WifNmLBEvg6Xbp2+4W6uubdKz+k/ve+fDnlbzhm48uGhFeuWQ6gFte7fNa7F9UnijP2PxwBXbal8rH9tUGn9H6+7FATJarUHsI7xAHxBn8/0pDmWAUJX5/mCE1w4VwCRFVegYOg/bFXL5o2mGDW/aQDIFWPzj/x6NvPOY8MIZ+MPztNJRrnCEx9CaoCK0MzS6FTJKdrtsM9oCTb0Bb3EJkizSXGmttFsSEX9DWXqTTkcvhS2uS2G73VKlw2Zdum6Obo3uB12dTjpuuWAhyGKxTLLMtQhaCgLWkpaT0/xiOAelBS+G095M0pMsgY9JWiZrWc1dXPLGrttiplth/SBiLhdO0Q0VHUTIysxmMpjlMdpkdhnPsvjYPTNePX18p+qsqW22jD9w9uSB/xs4JWVE6O5JNH218vuJE8ofa1Zj7fHjWLt6mFL71ear01Hdv/6FCbmx5UiPflnT77722qsfvRW4reue3deUswefwF0/+wx3feKQ8vTnuAXutk754qLynnKKRSQZ779OVtCI+Ah4qC3RyBCIaX0WShWaNbMhW0ErZ25G7udhmg8vakpNyTiDXSGbWYddVBcyWct1OpNJ/jxsOoNjdhsPT5ex2yyVNDcFCO1twJIsapNUrpBwfaJOSImagMwuEvDrNSfP19wxTL/Jdnz9lv3p+V5PYZutkpC/fszMZRv6de0y9dat86fTMdNmEyH/VOdeuvH3L16kfNiuvWa4cXev8JQHQz06TygOCvySkNXtrgJb4zDPNbsj1BRpNFQQJKy1Wg1GsxGDerXZ9YRIOozNkoQMFNEfhmrR98w7h8VEM32DsUhWrKIhKXaHizAranAGYm/oYeUo7ncSvtwRmagcxxUnlBO47yo8oQxPTVdWKuvSkt7Ga6nIf+BsNAnZsUAFSTYj0CMI/LEjYfo3zomWl/ktTTRhJocHv+jLtUfptRp8eH3k+bq6WD0U2DQs2CnEz40ZpaJmKIgeDHVxa5r6/bmtMjICac2a5ecGcjUWIE2borRA0/RW6RfDmQUXwyjTkknMgfQAKOpAq8zMVgEqGAz2i2EDElIuhoWkkxFPba1Utz5404mI5SOwg/EX/C/SpFQFO1VzJQuLhSN/yf/KR6/smYODqzePHfDhrqq+h05V3EH++OsTMA1XKMdp2UMTx8y2K3tJRZdy5Z0BdXV1N8T/CG9J/WwyuhUh6XUu07rRDLooWr8VZPktyCZJHi91HgsjiplxptWaj4W1QlICZb0LyViZQawwIxq+oYsOTp9+8PH77398wl09e941rnuPsUKHGfsPTJt2YP+M28eO79Fj/DieNw6bOEh4AeY3o7GhEjBGJUoFs94g6AUL8O+RsEEgprAsmswyNsvpcpU8UT4mn5fB6pdFdrtwJKwVz9Rd+JvdVS6CyFXjEZyTJufzNPJGUq+TKvdYRnmieo8llpMDyjS8Yh1erkxfFxm8jtdu4bYkSDeKq4DLOocyjSZTCvLJDuRI88MBM1JewPV52PoRK+D6PIw+rF/AleDqeAAs77/XcLlxO5I+954Rg7v16DxYs8i476EF64ZXLxzlwa8REryry9yet05p37Fn986aexbMmdRzcefKYYV3MxwLSR7dAjjmoIdC3TLTTSYRebxeSbSlp7M0yNy8TJPRZPw8XGWaaCIGU6qJaE0mmspK9Ao81Eg9ntRU5+fh1I+o5vNwiF0o0Y+TCi+SblGjht5f1XNl8DqMoja8lqu4sVIuumXbauWzjKW2fbvPdSitGNajW+c7pCXGHXPmbxw4ZOh46rtv7jXj0o3LJpR3at+layfDhPtnjOx5L5jW4xreL4MmlmSRrBwq1rtfLioJOkW8/tpLyrvCCccPaV8yk0uZIbQHH8jHciGtOqPRBH6Jx+RJTXObzSafZK8Ia6nkQvy2Sg2x1jdpWNACTJIs9c5YzWbj2aBq0IluJBph/Of95mYIwqlTWLPg+JOSfm/K1VC7/D7KCvGFyAPKC8+BxVd77HwzJhfnKM8IbcFGNYNFYRYliegI1mGLVTCbzGew5XRYlrGJSpi1DuDX1zdVIVmz+F/1EAac9PTClxYdeP6lI6Sb8NofP0rmP36kz549dPD8LOYT4ut4H7lK3rBJmiD3tWconfE1eGdHZaGAxWo1m0yCFk47cjithvVha8hoKbdaZTORV4XJJi4VC1QtGJUBSfUMATWmwvdaLgmyhPBryvelgcLsDR3K802d7s4bPlxRnhJGSgObNCOnRtH+aq5AGpytbeJ8ZEJFoVSjAUs6OPO8DPNzXob5T1aGmXyq6pVhqkkRoGKLwCRhxXc4C2u9OwffuSkw81sSvJuMLOw0oXtZJPVuJm8+A7vg32AX6MEraBEyWnl83+3Rmj8Pa0Hf11AHGAVgDzQS5G8o6dRYI/33ladOvfb66XMvb7p/yo/TJ0+bI9hOv/n+iVNvXjq3ebFybeX6RWzeu0FH3x7V0QND+eBwg1kvU4x1BovZpDVZuJa2guq2yLKBUmSWkPQ/tXS8oILryyxWvxLEQIDoG/LnSdxPAZ3Sr/adGvbuJO6zKg1PxPelK6vKlA3xt2q8wAey+IrYxZKnua78ipAlV76OkFXW/IQfiZwCve2mxOGhpMKJQ06YpdqCLSgDeMhaWcT/VYJPWcb8SoBlBVjHo7C+VWFdZ7B+xIcjNXBmjcTuaQgBHubP6jkefeHZ/9QF1Ge9CTwyQjZKmjE8CnCoABegUAxAfH6g9xblY+EeoZTX65SHWLGOJhDwWGGrkSczS6MJ+AIZO4YGzLGCnTO8uorLuLL/WrJT0oZJbVISNBE1G4RbwRJT+diZVbSl8Yod5Zc3Pq5DZPILfbpPGXFbH7Vgp2ufpIIdYculS2q8RrgsPW7LZVlXVhndVvco+gk5a4hJzCVn6h6tMdsEOQfnFyH4Fx9/ID5+OqpEPyN7SM8fqDRZE6NRI+PJEviBOt4M45HD1Oj4HfHxO+LjGXzkyWl0fGUcH1Z99hlyh4yUPUAJslnUJ9gj9Z6pjj4jkW10AHKFDJRkUUpoDKXEvrLb5ye4vHSi+aHbdUazA1sJiEsqmTQGg9NsNlIQ6S4Hrgpr9FXhdE2BhrAQaZmmSjNHc0zzsUZOpw6NQ2MWrLIgV4UFama5jGYbiqXNIu6oRv2hWMGdrTRRYFkafTHvn2bhRE1EwJolERogi5UTqw/gL8k25RjuppzFsyJXuwu95uNUvF0ZJXZ5ROn3sFLwiHDSotQqGzgdJiudWa0L0CGX024WHgnr1Z/CPp/boJKZj+M1HnwPm0R55CzsibMGG8RcfKZuR43RgnRJPNJw/HQ0VN1D/kCZwZwY3Rj8KI8AfCOH/3mNzdAI/Mo4/PHIAXvuPUUYfAJP/F5jMalPqLsOz/B6BD5H8+gajiWv4ThbA06ao+H46eiupDXcBWvA9dbQYHyCz/kiEKygsfGVcfhxvo0uAsEKcDLfAh/6ovU97IJvWKiN1+4xmzWCHTySFJ9JkqWqsKeMGaws6+m8/IMsGqgsg2Z1V4F9IZhvqrBirBZs6FpyDuM1QVlFQVYXhAOsKMjKq4MCsdqgJUvU6iAlTfl477uv//OHmTiglgiRAZvIUOW0Ela6gVGhw5oflU7RPWsm7YT1to6f6184fUyMPp4c0VCPPjwPn9OzMLpfh/h+EReXS4dq3CkSStqvhuOno5FRucEeGOnyJkY3Bj9JLrmZnEl1NTp+R3x8Qi4x+CijRaPjK+P4jEc0JpdcTC6RFI/6RHx/MdqBPhVaClNBF2WHzIJOpyFI0iCNwSjjk8jb4MIP/H8tLtFitxbLWrwDj1R2j8XD8fBxyl5cPUbZpWzHPfBIXH2XsgtXjVP2KbvH4RHKDhb3aVv3gbBenAT2lw9lonCo0JXu9gupDptZ1AgoVdY5rEiHsrLdfle6EPAaA1VhUWMzC9RiFKi3Kqxmoqv3XO7SaPQ14WtEe0hFyyJ4nJUn/fP4K22Th1mtNHa4cW5WBq+R+GDutOGrqrAQ+b+59w1fWX3Jr6A+jzy6MbLeT1CvLcpFtWJi+fZO546CndUXVy/e3unpQ8rH+6ZE+i3HHqzbfx85vEClO88d5/vaNso3u9RzbuPnfHeN3VWPbxqOn44GRs8te2CgzdlgXxuMTzrnds7HtkbHV8bhJ51zGz/nLkd9PoBneP4zn6N9FKfR0Tm0MMdorUHQJOZIqhcxgn1ZHEq16yRw6pAMdodorw7rbNVhUSfqpGjFiHrL0TCDg1eMOMGvcPKakVicoOq+qw8rX50/j40/YHJh375flS2Pk5q5r0xUxC7ffHR58abIhW1Izdm/JqwRL8PpHhgqkNINzW2ePFseSs8wgLFVGDQ099Bsmu2rCGejDCfLo6qWJklzJQr+nivu75XV46VEJnm8UqsARyO1udFAbcyd5RkUar8lmbdpcPuxsObZA09MIu22dhk2st+oYUNLi9sVLZ6wcUXNN18/++nkbs1unRGuwnmPHG69L5Bd1ee2cR1KHurXYVSLVncU9qrcvbeWCvTal3uWLh9d1j6zWZeK9g/zveG5wmIN7E1nZjug21YjJpVaWZlUmlTTuo2Z1Nv/huOn90JcarAHCloFE6NvHkuWfI+Q9zRpDUMzioF536wpbsUfqGwI/2D8mR2/I5QZMnH4rdrhjHbY0g4e/aCmXTf10crow/FnZ8dxGw+mtz+ko+xhSjLawHNv17QpjE4ZZdDYc5I+Puc2mJNLtiB7zlbcKiU9iaMpcsD4M0JvHmVuj5aFehgyW5cC2Vq3tuWlpqU1tUmy3A64pUPHYm+GtyJciirCztZ9w6XOUqc5OzPDnDoxlehpamqGhTY3N68IG7RmnntqVlknel0SveZSC5gZi/+Xtm3BWL4cdkZrb5lbfVMmNgsbsGsjm9UpJsKohOettsTkcbGmZ9iyvPOvM5dlttk0Yt483OPxUHmP2+QD9m2rjncbsGf/wVqxtDRUXTyrT9+WZGe/SorHaQfj36zKquHlLerQvbNm3btvJ8/UXjKx71Dr5lUrVihfKP/0XO43Krx5MEvWHkV6Hd36xA5G8/lgq7UVegPNu0Zttb6qrRZI9yFHwlZTe38wHipX+fME508f58+TNanpRns9/mw4fvpElT/ZAxN9/sTom8eSJbI6NhXGygFfI2Nnx+GO10R5xMd4RJOepo6O22dqzieD/ZOK9znGi3qss+biaj2u0AMzHqzRmyjmTBzn4YbPTR/LceLP3aEz0mSbrsFYskTHzwrWszksuMKCW1lgml9rLLroNA3nmR2fZ3xThApC6YRNRPBaE55rwpNMuNqEK0wYYCKTQdKqMCor44eHoAeBLr3Ff6AUsLnnhHoIssEsmCSTZPUQn88a8HiseU2MQprQQqDEYDNkGqhZMMhmQRCNyF8RZkUVFkRYNYSItE5nNktOMhmNWt6YLFjvWoVXmqq96irrp1bG9HOhOzdPBPXMMs9y3DKyOnlSYYMWfWTUsuEDlii1JR9MWPRWxRCsKXkH97zx69e//05SV23fsW7tuj2b6Du3vDBr6r3DB3XLvnXKPcOUd5SApNxQfsLkp58VxXThyNHzz548BnTkeZZcXvVV5ZVO3S8v7IE2q5XBnbRfPC+S71c/lSee4rzs4bz8dI03tYGubTh++miVP9kDoz2+enq/wViux9lYwIMgv6eRsQfjY3egBFyUWdDI2NlxHJi+53zvYXyPUlPqaXuK7kMfC4OEafx+T48GhIr0RMOasYiSaDRotEfDgsY0FIvAUEfDZozVWvZj+AdchyXgbjHeHw7F488NvEf1ApD3a2OXgNYDkafptchTB+izp08re9evV+acPq32bbgXcK8EOc3sQtY5p6hRuzA7J93ldwvegDFQodqFRla+ZqEguWPaXE0ttP5/WodFcetQVq3D4hxuHWZKQqVS+/vlOb1uv+NOjH9/b1Z574oR5wIK7bX2wJbIikwc6blp3zbiV64rH909qHPV6u+wBWeM6td5yLLfNlRFLlS994/1w0go/HeVP3iOH9/zwSo/7WX8hFOszDLcXuPze+r7IA3HTx+i8ip74I6UtMTom8dyfgLYPg77z5qMlEZhz47DZnzCPNgUK/dg/6zxp6pPJNmFPAeNzzFMxeduFR8nTHK306Ozxmcg6CzL6+U55RmoYyg9TUpJ8SGbzxbITAVv0eVwgAnmcBnMZloRNlvqXR0k1Z6otmGSLMA8sdeayPdlOf50aSyRN/I1T+yNpvrWCCQzmsNLeqkpvdE8X3kaq/dJrGl2fE3jRaRax05GCNHrVlcV1xNq7GZ4PD60HBGsT8SHzA3jSaqN0z9uqyy/mmSv/VzTOmqrNIgnHYzD3xLzU1X4Vm+j8BM225bvEvadHLwlAZ3BVqqFj8Uucdjb8UXYH/0pYmOV+AkdPlcZwOrRojDZuMnwC9NZROqeryktJdxmZPEb1quE+wm5UT9hYdRPAB8WT3enGOSb5GNbjmtXlX/GqPzDmBR0fdSMUHFVYR+MwQZ+dkT9dQ/AltLcfw07Jk9xKpPrAV8jsMfEYW9FfrQ1jrfV7W0U9uU47K2OBN5+X9pf4r0UWaN4M9jUm/4/8F5am4AtpmXVg837q3DYeSrsumsAG7jJxmMSL9c4UoSERqIove5L4Q04gyy3vikaFHI1zc7OzcvL90h+ZDZbJEuzfIczt+kZbAjZw7m5ZqQFiWrUWqjvpnIwVaTWy0RrWBqmFgc1XhuGi+xBJyWbWy8acej0M4+NXBirEFM6Vo6buGzRlLuqyWd9XnqClYllYT024qb1C8X+783rl8599CZeH8DZOconidj9aOBnCa2P17o9DOv1o2ZoVChPduXQlBTkSzeZfPnNwRt19w3ziz9ipx6PJQVZmlSE7RZWumfSGsotZn1mRVjWuwRnrKAon39Vezk2DFS51dRrvtSsetVxRayyK+gEnZdEAcHOlisml8gp7+LmNQtqj05fsmHFos2LZwqHa4N8uUAEM7aQfCDBjgU7diyIVP39hdevvvH8a/HY4/B4rHI5soH8iccRf6kx1o9VqnZw/7jNvJwk7GucWt9mVmEfjMNWZU8c9uc1ZncjsBP2+BYhAVvw5zYCe0wc9laAvTUB+4sag6kR2G/HYW8lUhw29aXVhw3yaiSXa02i8qqnKq8wyCunU6eLyqtFMK4rl2sqzO0dVammfF+TnS1HA86N0GFpQzqYHH9Jh6V/JPk8f9akZTXweXjPHg6/WTyGo8oIH5NtGSli/fg0r/Pj8Huosu03lc7MMZeKW1lTG8ifZNhbQA6osFMAtjYt53/A3vJbQn9IwVsagT0mDnsrWGNb47CtKamNwr4ch701CbbcqrA+bCXM+hhFYUuab1TvUkxJiwKNwZNQDJ7m+zoVXiHAMwbr00GN9zI65DegcTQeLujqxbB4naF0ELSMHyRlS15p6E/zeHxulyvFp9fpfA6anqGWHMrIoXP6PavDbv/KcIqb9RB6vTA/nndfr9w6foXy3woSsTMrL0vOKioJ1i9NJL+Pu0q+HqvsE7soL6k1ineT2byA65J41rFihYO1ZGRd2IRXxS5gM/MuDw7B4KZmM7IYZL1F7/G6TVVhl85mt1WHZWqvcOPd7uNu4ra77diit4mx7gksXpHozd9YU1V7NIkv6OQJPez6vYjZ9HtZ96Xdu89Hfj2/m46L/CrMexH+bKy1s45M9LuNyuqPPmLxuaJoHWcqGhZqqiFut8dsMoGN6Unze0xOMcWX0jcMHijS6+2gfPT4E/11PdFHG1/rzbzIM583g2I3B7F4S6KZWZzEPDP1ZjKz24SzT7ImkclEXrhQvLxjwUKVvL3IFk7eJwQWzI3fkeyM36nsgHX8Er+Dwa6sBncqqo9+MO7f71BtcB23wb+tcQRoY3cww+Pw47akCt9oaBR+/zj85Zok+D/V6HX0r++EtsRjxQw+AmneGPxEfGKLIxHLQEZnvVjGqyBLMZe5zVVZagRZehocRGsM62jcAsaN5jLgdnVcWzaOkFy7iSaPU3EdE8dV1Q9xWhhMybjCPnBceQ1K85BLLc/V6/5LYW5S6laiIje5GletxeVyYCTIuEVwnlgJzy0hP6F2m2ww2Ch1ue12s5m1c7PrWNs4HaW2uJ0Qa2KY6BoHZz0rJ1qHa41n+Y48f57sHFul/IivvPrMgbM5TznuYu0Ll6xZTrXba6ve+eLIS+nzprEcv39Ea2CYX+5CKag81AQEDyHUnZLi0llgdl+qEY6K0ecR3a2EaoHMFbBAY2VicJqj4ZjkTwiIIcY+cUQMWpPrhdmPvvtbjeMifqsmXjHsuCi0u/GyaLhw4e0bh2J1w2IOr1mGPTsOtGrKZWyLqIy9P3o+2N3FFre1QXxkGqzJw/hL8wOr0CBL7orev4Lsf43zUsu47Ofa+1iNwSzo43r5Wxin8lLv+uPOJY2L1TNH67QS9cwgWrQCjRc0i+ZoPXMwXs+cyOH/X+XM349U7hPaRb4kKbycGXDjPdE4LQpUX6hup2ozSNxmGFsjaZGQ5B8vZvXPoG+0sF/dQtkGo9Gs04kqI1stZsPKsFkT4vxMby40T/FYXs+v16zupnJzlgZGPomy+Mf4vSssIwz4XGi6utpxPe0rjjPQ83ZO9wKVnrooPd9JYMvyp/Qwbhine5/6dP+5Jh7hjNMgDk/WfIObi48jW0iHNRT/HAdZxmyxD3iNyWULwHyDjf0O7wOojr9hEB9n8KUE4LJGYYN82B65g1kIYyRNDFWOK4y7O44rjMO7YZz1BAaoD9foDAmhg/ln4tzO763KwVvQ6wXWnt6spVgnyAIxa1geBTVTDdEQJFLeLjB6gc0VJjgF7ENqgslVoEGrnFcCG5LjFlnju2m3nj6Pszsou8hu/GqHmdXk48jCzTPPKvfyPlOLozXwVtQn1ExEgsYoUK3WZtdRIxL0vL4GfCG9RbaA2WFBrHMhOCjJci0ea432P1LTmMExKeHzM26Q83hOMfnk047Kpyo/fBDCKcoRItP75k3eFzm6ejX+bvakXaRgdT27qXXUp5+VdE8+y2RtcE+uxlNrovFUNn4ZSkRUl3lTExHV+FlvxvextcpLn0Z56ZOaOGwOF8Z5ua3eVx33RXTc5zVxmOhmfMFWl5LwlSyuv8RX4rZ9DFvkC9SL/4owdr7YFXi07zjOz0oz8QDynMI+isG4OBO5EMMlmsfF6vhBJg4Qh4DHfVsoU5Yko9/pBNXocmXn+AMBa3U4IHipy9awK2SirteWaIQbLbKP14fcXOgfyLAKA/aeGLag44L8ri379LjvgVWnYhX/47EH3038yjvKjbLwqPZ5z3yK9yxbcHpL7TyhKlr/ryxQcQa5zHoPsE48fr/DyD7uyOGlmVluX0XY7TNaLKxUzaIxi/EK8kSnvVhF5c0NCJh6yStyq4iTpfV7Edw/s1dhxy5tx9EXGnQkqD24eaV2hVQ+lmYuXZicyzA8nvuQiLnx3Ae3q9E4fP94vDzm87J4OfZ6GsnbOBiHnYi3cdjewF/H+Pn4eCzel/VXOSFkJ24B9lciB6Mq1XvT3TuD3z8Onz0TqhfBn+L3NcjbIMhRd0N4SewJvks6mhnqYTG400STzeY22O1ukWYETFawWkx9TFUmWmZiidBrTLtMx0wfm2Sz6byJGFixtcNpd9irwoQ4bCkGvaEqrNHoaXIBXzRFTM3amVK/xQ6/IA9IsU8scSeSw3IKS6y56s/JiNKmdd9+h1G7IGmpTGG9vPDpyC3lqbkdHt20VcT98DA8HHeWHlHKH1ZKH1kpCQGpDinXle9YYiaLZ6UCbWp4P6YcsBInhm7RO31NEfL5vAHWJ7mZ1+Jt0bIp8GrTpkZ7rt/uB+512i00y5hVEdZrjYmmQcZo06DEzW0wvr4GfXDj5kCsAIi1nJJiES83uBlWZ456MFlr7tj17MVBfTv1Ni0v+/JU3/6ndxw4tPfpPgOO4rLI3X2GDh1waHg/fHv5QIo7ayrwb+de4fexp0/jALayDhknTkSe8+RdffPNq0r/t8iSI9ue2BGXdVs4rxZFZW15Eq9aXF7BWI9XeT8IzksD1HhrWJV1LpB1t7i8elQvhhJm/SujsEHeRqIR35dq4nDZuNdgnJPL5QGqjleuR60B5e2aGMybcSVL675TY5Vq/tSpGo8/ge3NuJKlDu7buLhv8xuM1tc/h7x/JYdfHKVFzPZsAXJ/fotWYv3xvE8Fhz9QpcVAlRZ5MMHAvGb1zm0D2GDXClHYLQG2Kdjir2GTJWYVdhOAbW6RVx+20pn13YzjPQvfrkY60lrHwKowYVy20DMKk40bGB2XHwOYRIcDcVyXxn08RgddQdH/wHWpmKCD2LT+XeLtsNdzOU+UqDxxLaqDP6vR6AUpzhPPKmHWOwPGDVLHiRxTk8uLTLHYDe/PyWlakhRTYzNrmC+qs0ThxfAcXXcdZBqzDwc9rtqH78MvuB1H2tbEIRcl9/40o66hLK3RKBGTCYuiTpIsVmQwgjAD85+1UdRqRaPab7vhJ+tF7wZjHd6tapiDZyDyHqHXrz97/braJ1QZvCmykdyzCR/YHu3HfBFwpeIdKA31CzVP84KvaDNpfNjksEj+9FSH01ERJharpSKcZrVKXqfb7TTrJZBIrlgPbmuwAT7cZ4uaciycEe8owkujGV7RXiP03URvkQMHDkS7jZAlC69F+4v8uhDnqC1HlKuJfLCd8fyxREyD+Ww4tWkDfafeEx6M3yvuwEl3ljdqsls3uFdU4Q+Pw0/ENDh8u61R+P3j8JmuToLvS2kU/sE4/Li+5vCRM61R+Il70S0oCf6fNWk5/wM+yy7biVqeJNjJLgo8Dk/5Wiee5MQWJ8yGnSSRc1eErCzXAt7E5uU5Suq826L3q2mx+9XYjWyS7mdz90yaeyduC2tL5OqN9zhvshfYPH3j62PPdETRG0x+lTs+I+3meZQBrL9tdB6JbL+Fn9cO7tjmMLgwpq3QLg53Ow6o8gdlZhqNCfmTuK9sp8rKulrV7/Vyv7e2xu/RJtvUvPcLx3eIKitrk+6pa4Eqsrfefqi5iAdjuYgJ+LoofLM2kY148x11DL6qRyI1PmfSLXUCfmU813E8nIdofqSW50ca9Sr8JPrxnq0cpw5R3TMmyoMMqTE6I67Pg7xfCsepUtU9AxJxtaE6I0rGX4U9JgYb/FxjNA7GYJt0hkZhX47BJlsjCdiCztAI7ANx2EuRLqorGGydwfbXeJOlOAFbNtgSsBHGa6P9EC0oLWSC/2usNtHAWpPyqrL8eIFrIJonGWt6yDoeJnU7FPonuhxy27ZdtE9oGmqKxoRaZjtkSlOJ30zMzfK9TlteRdhhc8lpKK1vWDCD/UvsFLx4wnJDdMZo+NhoITx8HGzQgaKxzoc8QlaUHEW21msympWcjdBuTg1urbyhNhaNNxqdQ3vPWrhp6aKHl8wUSzdsWLCOdRZ9O9FslP49Muaj1/754duXeN8lWvdhVH95wANrioaFWrrsfruA8vwao9EveMH6aJbvykvLS6sK5+nz9IIlV7SI1WELFfzJOfXxEo76n1zS4BOy2GeX8E//lNXiuejHmMRTbqM1uhnqx5is7HWrbZt122rcFl9f8+Djp587efyR/cce67t58+wHcXP2WSbCic7dWre1dmq/aLNydtajKbaT0/mnmZB32UebxO3Wjeyelj6Hknu/snvpbiGXCflFi8XoAU7PznGBy2l3WYyWM1gXMoSNWOekgXpdYNU76eQUEVtpw1awvA3XXzWDJR9F3o/2g43tVf1+sLuU33lD2MRGEdgHvg6e59wmlKKz2yXBBD91e3S2qrBOJ2ioYE/sSLTzbnILOHCJA9a8opyg2hk/l32ODOC1se7LyE87cU5bfOt/UN2FffuU93Bw33a87PTb9PRjgYuRVy9fmDlVaTJJ9fdKo/TzgPRqF/Kni1aryegFtHJy3alwINwWCyNb5n9tnttY91yO1V/SbC7Gwb+gGa2qCZyNttGNUQ2jQYDrMN7Pv30oDZw0qwXpLXq3xypZJZOWfZCNyc4/rUZo0JehAeX4RyOx9sQZ/BNJ1Cbz/4+07wCPqkrfv+e26XPvnd5rZiaQRjIJIbQMvUMS6lBMUERARLog0ovUoPQSpCtFmoZiRRRZURDBsq64a1t727WsheTyP+fcOy1Bd3/P/+EJEgxzv+/cc752vu99DdT6fY/ftSN0YD4YSNrET8XfxCc27myz/87jh8mDMJeiF0/pBAY0DhCPiJvA9E4PrQQCitdgXs7ksQG4epWxFoRO8Ho9Hiur0ClCYbOjOm7mBC/HelmvmuMCMHOm1VA+tbGZfGX8+WSumMY3kCRvwoQ6RVYJK8IcxjA2MrtOgcSuU/HDbold5+n7V9zfunNeTo+OTUh2zj0pkeyMV618hNth6NHvS4lsJ4lPLDIUzIaHxrw2gjEYBMGj9hLecIQxUB6DxxCkgvA8BS1KHTpOqriSwnCOvNSvd76pQs20wXDEVtyJnK5Ac2TiozMUy6YVFGfldC79Q4TiynnLtZv4Hv2uNQMqbt7LgW3infhe00V0iHmhJbTTJnjW3B4NNIC8rToum0B7mglsOsSYRjCUMnntQHOuoR9kM/emzDhk7phgHEo3bxnUQ+gcQhlz8DwU9HExn0LQEbQgqAiVxYqZOii1Qs3DrWNAo1EKqim7VBqzAwLTyIpKMOf+QBaCzUB/YMuImz+Azo0tqE2NP356k3ihbh+Iim/v2wdWPH0JbKv7/ZmrTzwwGbw7LRPrGdmFHjHezrNeQq+HJw3uazPPoS0gxHmgDEigz65mXT6Z3tBQVtQM+BnfZv0X6OfGd8h/sI9TCgn9edmmJujP9E7U1cPOawkmfnjxzc/eefl1JPsiGLchDFID4SE6xgJ2HSqOEhTJ6hivj7eg+iPFMjBrYlwkFJw0p7xes1okzwBU+pbQdG4BUCr2AtUNv5KKMf8Yf88QGal067p1tdvXkR6R8IjXlzwcPzZsxJsHUnCl1/72yrXX0Jm7W37nGvTGlTShYUlSQ2gQUTLiRiFUKNFUUQRoxiyV04TiNyrD2qOvuynQOIasa8ymNteBy9vAo3USFw1J3AXP+J3QfgrQW3aLBaH9Mmt0JhOjYWx2rbk6rhW0gpJSQv+jNFIc3HRN7WgzxkgjPM7IiCLGmBI/6Q8ogM/o94Dtff+2nVSLv/z6q3iDKjGJr18YA8pA0NT4sGYnPWnGfdCMIt6Y28HQCnDxUMM08NYX30h2aBSUcQETh3ZoUCzPTZmVnF4fCAbtrJJiwhHW6rA6auIBK8dZAxSh0UBZNTThgwtkbIo4kohcmrCaZ6FRG/hbVjo2uj9qThJ6WlmarPlO/PrkGvELwP7tpV97Hig5OmfJVnB7jx6vvnBiC1Dct32o+Ivp6qmlZwxdPtn7et0TnRZPmX3Xextmz528FPD9nt2FriDgHkS8HwZiSCxKCqiEwHGC0UQD5AUG0NU0xdHl9L00paVoROJF00qeJ6ApohC3lpLI4KdNUHmVlaXmGqXABNXFMVBEktZr7eIOVcFo1rgEu9fotVtMdcIO5gl8T/QVlCuPQYiK/WIRA2fUq7RKpc6o0+tJi1XLC3xlXEUIgKcEgdA5CWZanFAkQ5AmrWvyVJMMSmXFxF4c8Cv8VNAYLI2WdgTUmgGV2a37DuprcoJ8u3j1x/ofG5w33FlPMnHrcmOH6hWLbxTRry/esm2+zD/G5LKo23F4rMDNqG02qzXAIzBnKpKth1ZQrwxlQRtoU4ZsIURCBh2skia9KQqydAckeaW0AojkhpJMZE296R/Skj0zHTnUNr4eHQ9XXkHsZJ1Xt85kJ7sz6VFllrJIELGUoTPHwPX+C+Z/cROdY35Wa6ZUBs5GUZyK0igRO4fG4zWrCDW06U64jaX3Lq1rM+JHCW2yGGFuqkAUWBESSERG9sLTDeOmL+3XXaQugm1g00WR6jlgmdvZrq0rPzs7Xxy6fOqY2iX0vIZS6uKNxYvX3jl1eUOL6tmzq1sUlhTjszcenr0xGDeySyxo4LVa6Ce9gQCto7JCPs5gNisr4mZeD3RmAtl7ueSUuMTJqOLjoybhQsrXTHJAmEB2wnAfPNVrzJx27bt3G3LwoILqv272lOL2HUsOmvpt3wjiGyce3dy4iLkkzru/8Njjz4nbt0ybtZ58ujEqzpfvZtE9MovuZtM42oxETSxKQNGBCibzSkGnM5kVGJ6ORkhex3nKSPG8hlDiiwmNAXoGY3PqtibQgmnswAkqN1TUky5FcWEPU7pduSKRul25gmndxLFrREddHfhsDdiWxrU2nDARvWMhI1ADSjAYCMLEUxRtoi1mYDTyJEULkgWgCRSLRKWzh1c2ExnOICfBuLMguZPNCdo1/+GzW1Z37lxUNg+Rr/FkB3LaE2I5XbR2K7ffsEGcSJ5sPNnIEumY7SaiZywLyYUlQrKZaJPZkhCLU+qq4oj31nwrsf4XqXDjA5aq84J0NHd6nyRV42YZ0z39PrtvLMwrEYofTevQjTal0Wrg7tNqFTy+ywa3vMuW+7oy3x4C4sx8b+gy++pV6Sr7449RcwOVt6bxu9pa0rCGFGolnzQVylIFZTFCm9lSpTYgwARWo+VouEwkSfB6NWMyGzigpY1GHQ9YjVrHU2q8SnA5kOG0JhGp0S2/IC8SUADEM6cHIAjQ8Egkai2l8neB889faWHjWoofPwPOdTud/2yvE6130Dfa3+hEdpk8Nn984zzq1ee7zux2eX2ZJN9geG5nw73vJ7rG/GoVaTQaDCqfw+FUOQNBr8FhUFFWPaOvjvugPTISCYh6dFNVnjGHLVlIJiAPEArRNDhoCyIVxP3YEZbyLu/om9Fvy8q95RW9Ou/p0HPjHtVKZUfTY31HvH2dOthw1/aVix6kTjaMWPcgcFJ7b+yZde+ybVjWm69Be9gSY0qWxOw8Tav0hMlk1putNhPgKAU8kwoBs5fhhCIDDjFFgCfdBmOvl86Et3xBj6LcNtNkPrzj/RsM6zZq9uih60ux4kn9APiO2sBS41J3wsxwA0tvIRK8eZ8xC3H/Zs9YyM7qBMFMsITXh2kYVRpjTVyjoSQwAppyZRDpSQSYNv5CTiYbS4pXz2dsXQI3n9mksCiaE+ypfgV9Z1YNe2lP4FYse3EwTLxSPvWxCW9Nmn+kKdcezOEYCmO2+5GvcSG5LVDuQBBKy3H6qjjHqewYiN+bBsSfkrupxAlU/qTErCIDpCyBzw/WdKse9lLNbTQOfm8B0/9gl4WPTZj6ZGluKxT+IrR+JG+ROAzz8/EwY+sSC1gYmAs59Tqdk6FcboFXq0kNrTRiHw8zMz1y8hcSEku9sJkw76HUVWooiq5cIpj03gT/opSyLl3/8dc/XJ07BdyRU/9ofU6PmQ+umdcx3Kcar2tXcE+P2G8MG1XmiJ/daBSv+6B8YYyT3R/aIIRaFjSr9BTlIATBoaLcHiep1xs4XmOACRDP2irirAX+WHn5nwmIsKbSciAoJJCXspQKU9efLNta+e0P4NOqjVHQtmXj0kfWrNoYawOKxaFMecPBSC660yVb5Xg7/W5gpl55/52/Wqh8k5zfjsdnyoPQ1TQ8r3CyrMIKIzevz8lUx516p15hdCiNypq4kVKkGOyaRfUpzsUcJGx6cS+NfnH8fX9/+OzZRDlvqkTCWLcvScKYlugm2BjT57hQ/bULyj+yrCqV2kOoiZY5Tj9qD+H1pqq4HqhdZARmZ+R/rdP5kxhiyNV4geRrbs3YMOdghKFPrlvbOhJq034uXbR93oUXn561NMXacNtwNM7F9nt4s1L5qGmD+MNdo9GY198vSMwNJLFHPEfvx3eDVqJPLAzttgaVkGk0AKOhNTa7njSR0IDBLWtSmBQ0Q2EXfiEJU0A0cZaywVVhDkaEVoCh3VQgwcJ4UVz01dmzIPjlT8/uArvEBomHcd0m8Rz5qTic6bb1XP361x2NDD1NomKEvmAMtF2z4JnKJqpiLfUcRwSzsqArMrdo6VaHDUSQD5I6KhgMh2HOFDbCLWzQ1sQNdBp2UwqmrixTWlRYQFzrVEmx35eEotODNCgnmAFmjYlW797dbf4d7cRPxZ/yThd8+7ePvh986tiRRb0P71x/2FnfWyz7RfwJ3FM5/7beYd5X1Lf922/7H9/yzJHRD90eDne8ree0ObPmhcRtF7A+B6E+AboPEYH5YA7Ux0n4AwG1iTBlt3CqQwa/PxTyVMRDFkI/WU9qKKxQRdzAp8EtJltqy5ri7aVpFAxgjXwCVgiY0xFaD+YMXrau08T+OT9f9z7iuHYcbI3v+3VcTe2CpWvM2/1vvn7tU+DqeMeAWERwt2iXv26dZd4S8frg+wd3cAworxxeNTCwfOEW5GcmwnO6G9euB+Hz8IE4lNrIvI1rLANjep1CYbAThNdgCIUtrmegVYcx9s0XYiqVrqfFQnFU4Ayw1cehJVefAeon4pwrUXqTvU5OU87h4taZSKrQVaagVOV6ywf33rZsSbu2rYu7dVqwhuvgHDSuX/tWhe3bFbVqz1iG37llxe9vdO2je0S3dS3dqDHcNbiwffvCVu3bY54LKD/iufDBuIhHPBdeo8PB6r16f8ClhSLWx10WwYJKRbq44JKZLzDvxYVoE56jzJeSSX8h8LK3b90BNGfCaOzStU1R+9Yj+jYhxIDO8zNhl6Fzj7laiRkDIF4gfDcioNhDodWSPAAkaTBCR8MRNO7Hpsg045iAcE8338F0k4gIP1+VzOBmqq1E+9keWb7eHZatrkvjAnmP8BKdYlpOaTSSHo/N53fiZTHEnRZWUxVngQEvDoc5QSQAzvNN1kZal4yUtRlByLHVyzq3bpNf3qYJTcikLdv0B0y9+kxozhXSF9pkaU1yYxZeAQCn1RqMhJ7DJMHwi4Op0fmczFg6QRSSeLDU19CquH1R944LV0mtDb9/VdmXf0TYsJxpnehtqIXxSRaMq3AV1oTwuR2ERtC4oQeogZmvnqGdlIHSW1EdX84toxfSbj6SgUlHkAhHhOZ0qaA6PuyldQ+//e0nr58dv/zh6c9TN9z3DnxswtYX/GI/8ZefvwIkok99Y/uedxB9KpSrHtqY7+m28BQOijlBEEZNJpdCoTYFTaFwFuejK+I+i8utNp0B9pg27la71UqbmdMr0cuKlqeQ9tNrnuneNBVFpwnehF9l3JCZs1eerOo+7KU5y+XWxtiWSYe2IpaVHbNO7CSnidOD44Y/NmHjU4XiJqnDcdrwFN9K25tf0+vge0S5u59Ta1mPjbVRDrOf8meFPC5WhQYN7GqKMKRqZdKETtInyQg1RUUoBSCEYkMpizgdzKxs3kuKyUgJoreIWAxmniDH/ix+dHTvjNxXwCfLFj2+78ChxUvBJ6/kzth7VPzIDCMq43Og10RN3Ye3i78+/uEX37x/BChu/7BOc494+lnxG/G55J7AHNVOIi9mYymd1WqkYPRn5qvjZkSIokqJW55OZs+k5ScGXGVQRKQLVj0g49/9/ewD6yZt6DNgeNsiRZf+oFf5/JdNvzVSdzQcef7IdjAAeHfUqndoxS7il+KRv06W+G2ZPlAOI9E25uL0eh7xEWi1JrNOzfO0Vk9pDQQLZZFLouUyerFsHzBLq4zMjhFXEmytHQF9R/mkdoP6tSsotoiHZOZWXyvoovOiy7vlZzV+kqBwBdcH9E+eSebfePa0e4x3KZU6lcUCjavPqjKZ7Mhu8HETcCn1ekIlMbW4iFTIWZ66sY0mE03JfspcLdHWpXj0HYuqQLQtLbsXhVseqxEwawtfQXJ9gZC77N5FE6u69hwdFXsNlQhcGnIRf0v2G7E3KNWcWaMWdFxxY+S3z0oyJ7hnBWJkrFChZjUamD5wJKtlKY42GDmNXlMdVwuEUBOXgasJWm9ANC8IQTCRuqfVGNO6lwSDrAuqvSToXvzoqwT454DHwSDEVCvuAqPE9uJGavSNC2Cm+Cz5M6ivWyW2Wyrm1q0FH6VxzfyJjBVYxgosowbLaE5Q0fx/yLgfLAYmRE4jfgU84lTxffJKw10gJH5LjgfdV60QzywVH1u1AoyAMlrFIfQ0uI4uGGFmGwTWBRibSsW4SIFxe3Tm6rjOwDqhtWRZymBgoJlAd0NpokUzyp4JE6SSJKIJMwbYzgdJmoBwDgCrwU8Nv1HviwqgBro14o1HV15+qMOe8qeXHb/yxW+9yWfAd3W7Rasg/uu3x8WfN/Ras6TP2oVfXn75FfTeu0N5YUxDOIjesQgt2M2ESa3R2ExmgXG6HCYTqImbTGqLBSZwFkqvgKZdbUAOJf0ug2iWJwUDdBo6qA8aIyKETJEfUOW9vxNvvHJ66XMddg8Sv38FBsXvgAgAopJ6v+E38BOZ/8Gll95euqrPqX0w+yT/DQqc4NvddSJysAugr+uOuaLg2iqMwEpZtDodYbEaGYfTAs08adHCX7zNBiriNo5XV8R5V9PCcrQZI6gfJC8PpICRQBQqUFxa39gbrKjac2bPCiBknbA2/O29m8Q/z4qLqPHUEXHeQ8/t2Pdcg/aZ54mbf70CNHYw4bh0ljbDNR0H5cyGUWFuUGET9E6jNZsgrE7BpGBbtLTiNkCDzQY3arYt20aZqTAa6uHQwqbuajL3Z+oKhMU7oKQ4iaAtUyghColkNO8rpcdliz9eW/nX8YM3Hjw89aVzYExjLTVGnP7EqQErj68YXbx6OTB0vnP7ob4rRg6Y1D+nZWXb3h1WgZar7xOf1626r2piz5xAfqdWvaouYp3mwLNUCe2rH/N0+Sg35VCpoRux291uNU/BtM1P+GEmQhAuncteE3cZVKj7siauo5viyjY9dshlJU5eU6BsBcyq9KQCHUOorn8OOX7F8kVT1+jOmL596d2vJ2wUP/5p3jAr+VXDoOiLZ8VS8uf7FkycNHeKcPCVZ48sn7707IzJbdfNmPflBqzDLOirusG97iR6xMIK1iagYQzByDIutw36K5uNMllx57uJomBEkz6TkdERnna9aKLTOTvQRXKwBJeXi2i6m/ifr87+GngyuHHK+r1H91w/RU1pbOz6JQDghb/dePGwed6Mw5vWPQxerasTr36J5NsF5fPDfeNA8lnMGpSYqmjWDE+iBpowjcYAE4yKuMVisKhZBYutXHmqJ78Z3y2GS0mIZJaAx5M8etTEh3a+/BY1UnT0fvuLT66++FnoqGHLeKABw8eNActXrxaPPHb0xd2HtKOn4LVbCGUrZD6BmT+6eeThic3yWdVqH0+1zCECwUBl3KqLhIOcDu5sQdAlkXfOQ9+asY0TkkncJ1RT1hMyki9x/gilCMr6UmDw4B1L+rf85P2/fxfa6Xx0/dLlkb7T+syZX755y5M/U6dHD+yaawq36317bOdjS9d4h1YOqCksz/UZPQMXVk9bDEb0F4cuTtUu6AqY+zuI8pjOqmYYlidYwumirZJLpmlWh6Yo1TpewbGoFFQevcUFvcxywKCM32KOpuH+Cx1JunOt+Ffxk5MH1fSIz1+6/PTCObUPXf7wHnLaXvH7d8aJ7zCfjO998aevju279G7jj/2OvIftBamFAr6A5ztNp2WKMGhjLydw3BFOP6mtZy79XizxsEwlCGq4PA/qjekoglYQiDkd+gdUeb1clIba7ZcNB5i6/5H96CPwxwBiEXxOb1wTh/GmktZqBYCvWvB1Ck1oOJ6rjit5Av4idagIInEBNaECSjQmGyUuARkCWLrKXgRWHwW14lT0dVScDlaL02kWXBDbbhUvbRVrwK6toBjXc0moM3mR6WpgUVcV/IK5BP0Ou4ZQ4Y6PMDE7FrPrTWqVkqJYEgC/P+RlWNaXleV2e9V6OpKd5ffbOFt1PMBR3lDIrofOyqM3MEAFVo9QUbVxFUOU5yS6/LAGyT9k7suokD6mj9GqrNHSqFkRpHgSd4lYDIpEvwjwJ7jryPfGbSI3jDv86M8XL+6/f++5+GP3zqFtd0wj32t8HTwgXgZfivPBQna2ac4c01uNGnGveITptkT8ugGQv9z4EWjFYbW0s27ljY+IpP4vMVuT+s+IdUrX3+fL8kD9vcFgKOTB+ruzauJ+H/zi0CpwFFoAd8YCCGkLkKgZ5/x/6G5M0vaRp2Xdr2XqfgDUiK+AT8XtYCWzVFL85i0UX0LlrFrS8PYqpHfRzc/oy5hr2UvkECXE6lg/Hx/22Gz2hOoFBXlQ8/yi4qI8O8+0Li0qaFVQEW/F5UVzoxXxXLPbbAOGFhVxs4FHcz5qneWP1yCafvmZ3msvpJGapIoaqeUAcgk4HeMmXEJlQNwkV+c1eXXEEb7+3e6f+l2Pvl6S3MVsUTW07dq5TZtOnTuA15IrtUBeqRuvDS0HZmAnW7cbvBisvWF8Is82Bjzy8V/++vFbf/lLI5lcNJKIQ7t8H/RpDGba81KEhufNDEHDoEhZHTca9ToYslGAIqhUE0qybJNIxqL49JZKWW5QHlKPxPeANve17zGi31kwesf+e6uYbjeG1h2NLFuP5tO7v/uXbDSHFYd2dRbmnzHDuKxfzG7kLRqNnSB0ZoaHYZnVMnCElRAoSomsLBenXDw0MLxBr6uI67m0G4z0BDGdxDqNwxrIhCVRMz3r8tO3jxwyfOZc8U1w5cZHe0AdyD3pevaq5WHD0pnUy7U3LmBp0bi6NC9GQDnLsJxGwk0MjrXgNRojYbLbGYLyelzOirgLmGxWGxoTE/iBIwRCkhDL/QQUO1PUpr1Gt5QXcW4DDJWBFpUuQzIPHgFl/hw8c/JkY/uXGy+8+SaYkSb2tRdeuLGotpY+XkukvVsBY/hHVCTLKlCt2uH1Ym69oNsFzzllsFbHYfYDlJTCoMYeAFF3NHnJSecVooIw/UfeC0TDJMrBrUmZpVcPPv+NpdU7dgDAUvpdz7Upyi+u7LIZlD0MqJFe8aUysYzp2vCwA3QaAF7+/Vmzbrdx9Rq8Ja68Ia012hP34btfP+5HLEhKHnC7QwYDb1XQ4UgwMHBEkPF5K+I+DgmP2y1dagJdb8jiN9Ei+l8UyVj/oLz+GcqAr6V9M2P+B2DByZO3VMiNX0eKE50iBsr6oL3TkhgVywu4XG5TS7yDiJaMm87JDYTDcOuEeR9nckv7B/zp/omW39LkNNlDCR0yeccTfOP0fQllXgV3w/20o7RTjxG7Eeu4f/Kweye5MvT4/Sfy9IrF9XXSfO2x6jH1FxsLmnMiqPoApzzFijkRBOt/wZhb/gvGNyrE+EZ/q4+WcdSf4Y6kPl/C3uHMGvbWuCPK36TPp/DMhgbPbHxfrzPS5J9hp6fJj7HT7d7/MrO7PB1r0+n/MzzuNNkxvrbZqRD+dL5oeSbuojtov8V8kSIn8fnK38mx8H84YxxFopEZ+DuwmqVnSCMn6c9hJ0jP4cPEBEDwClUFDCVtt/zcG2mf65U+1+38w8+9lPm5xExi0R98bgMmBpQ+N4A/l7CZ/tfPRavzB5/b2Fxeu/d/lrfLzQ3y52IsLtQnQDpS80n4OVmZ601TpJkJw98Jo8wZkvEcCWO6Qtrz6DnffQt3Q8XNbwmR6BwT6LYxh6tn25jJBH/jDT3bouEwQaeH32m0PdtiCGv42WkA1vLHCwgfVZ6bbCqbiGXDs94C5g4xmZtxhzSRi9xGYLng/xSJjjGBKkFylSC5SpBcJUguDspVguQqkZC1kVQJ6G/00ekyYa4RPL+3XJ7fOyDP2qOzdcpmp/QZ+xljazNV8OcPoP2PJYE/TXWED4JJlyE7NSOE8cMuM8MJHzEh1sakcnpdNhvB6b0qPa2i/QHK4XTUxAmn1wPjWS/QUk4vx3mdFAsTleq4lmYt1XHWeAuSuvRBToSfIFUX0rqHzIn+QZ8x2TJYimH6cNfgggXJvkEwfJrcMLh2vngVFMCvD8CpRceSbYPiSbldsM/ti+7eJd2RjxWH0cPpPjBqLybujrXyeb35ykiIgzvYorSUtPb5XIQrAIMNJ8kUMhXxwkLCwGlyoKfQ8PYwET4D7E/GMftWUVqoKhNf3aLPI0moFkXUK2nYi8WtS6PQY0CFJfZkHNyV+kFxqme/IxhL3iRH//uls69emHIgj1TCl925j+vqud1/zTpZ8NT4WdZGLXmz58KKZXNnr66c3wMwfyFuAhYAoBg/2rNB0fpQw6Oj9j86e5pn0fDx5J4Zx0Y+e/7iU6OOpeHaHUjgw6XZToxr5w7+F+y55Z+k+ZUfoV9JIbol54hew5+fL3++TbK2Ek/LkXrOzGjSMHZwjxx7gNDAta2ItVADoJGggFQaWgODZU7HrR6hE2rjOpJUALVCTTMIPQo3gZ2Xb1bKM7kvU+wXaehAZDAiJwqZMEHi3H3iuC/I6+NxwxzTreELqVWO2f+9aeVKk+TLxMG4jwn7Mp4l67JknwX/vhees6+S/j5CpH4+gYXBR6T5WjTDGSBujYiR+Cx8RtFnhdEZRf8i7w9QMfBzisUh9EPsAT4MZrultUb/Q/kk8DDhBCb5KhgjVTH10AoNFBIz+/An3AL6CQnviTqRwHtKw1oxIGQYk0PBp2GVSvlvN5gHGmD+2zcWcVlgImFWExxNE2YH7XE7rFJDnI2hzE4nh/hkTLjb8o+y+7Q5pz9J4x/6s/SdPP7neXtTuQfHcjlaTTgsJqfZbjcRNO322C1WS03caqUZJD1DmRwOLLwxQ/jmhfVoelPXn+TiD/1hDn5L6ZN5JJXMvVHvWQ4xJta6ZVZ2i1DQZdLrOQvLcsFsOi83OxQOwSiXC7YIwCQ7YDaa9UDplSZI7M0mSG6RWwvpMIKh/0MeDa7+L+nzA/9j2py0T9uT9qkXOCXvSBhxgKlOz5/bJ2JmZ+nElMATU1lYnGadpBmIWXAfWFFXnAnm44ROB92hoLLZTZzUWyRYDJRg0FA1cU3yqly+iE6wq8I1ki4lU+3Wfp8d+LGl8QtR8q32PXrEton/EK+LV/buBYV7wcy1U6fVkssbR4jrwQTgaVzNdGt8lWyNeVng+RwP/a0eZuntYm6LimFYjmAJh5O1xCx0ddxiQJ5VpaXRcFKiSuSw8Zeb1T4JbOzwJBhqgESDu1RrwkCPf1nc+fHZM6B9/YQ3P3pJ/CleWwm2A+Nm6q6/iuPEF4eLv7Df7Rs2+rffwNDRh+5oONEeWMGYFG5TXQK3SdWTeFGy5UZsy7fV80Y2HR/kgjSLjLCYjBg7/QVsa+zY1uAaIp5DJ3ioK6ok7Y3FXG631+EgNKzFTBkUYY1GZWCsNkqgfXBxBIOgpCmFklLm5Xpdq+NePcNa2Oq41WJoURsXVKTBgEInk0rb02KwGGi9Plgb17+vVFD42Eaj6RM2cnOuzMKak8kfE5U6iFN/SGOPRM3EiE1NplikggpWAf8iTGH8Nms6t+ywoeC1F1c2Xl5xHlwdtfSeexd/btCHzKvBUw92noSw3YZ0alPapUtpm070M3eV3fgUdBGfo61ld8cn3St+2GJygXgCDDgMriDot69C+fmhcH4+rjtK8eRBIo9oS8SIvsS1WLxDx46xdlSoHZXdieiRHQgS2UGKbWNzCkVFrI3t198ZrYxzAW+gIEBZqEAMrlAgEApRlLd3LKdrbTwnZvf3zGm303nMCbOrmJPUEL0n9yYFqjdirFXperZD/xXs+L8xi4br6ezdrl1vJ5XfQZVvzq+IC3ozsinSchbAFSvAZCow0Ltt1Ci4vNIWxQuMp2wy5loTgxfRxJLjqVsFbQep5pdEB0ca2YpMuQ7fAUgQrcB1NzZ/Df2jJYBs2c7h79pjzAiW7XRi0SO7wIVvJkyfOU79bNYvha3QqxEfqdlQ9fzMB7rFx6JXMyr5ar4oHu5qL34o5ldUKibz4yfPnvD4JszAsnjaoGHClwWuYUXwhd0oGbmtCvGv3FFVNYa5w/Scu/5fyXeWjNEPJmJ0mK39nIatA5h6i51KPztSjF6fiNETPAJUBxijD+8QM0TSfhZzc+HP3iZ/9hgJ24AKwpTkzmC4Sf6LORvwZz8tffYY6bOz4GePyYqoiWbcjXVJ/Pk3SBfxE2E/RZE48z1z83S9xZie8cB/U41rDweSWPRvgA8xkgZFtpNSmVH1bUqk+kMTjP6jyedcg3mVxJVmx/UB4Zb1jaeTz7hGVmJbhB4Bn3C5vl00VeFI4kPXJfGh3yCzsB4kwnhH6B57600C0GTINA1jRB+QMaKRHj/JeoQlPdbWB306U8a/kZ5zNPmca+T9EpeYFdvIX+utHNA0w6F+OvmMazifRHqHUaUj7NGZMvSeius0dUnM1TfAj5l61EI9pFpNUqaFuFZzQMaIRbqTMrKJWUI2WVFv4GjyFtyHR5PPSb4PrAhh5W5ZD3o6+Yxr5GTJN5hxVeU/9WYdTTbDWatL4qy9QerlfeWX9tXB+kzUNPl99MJ6VDV5H8HE+/C5m/wb6TlHk89J7Ss/2ld++y3rTk8nn5F6H0H0PoLOJj8vYWbVJTGz3iBbZeqxHurB6DL1wLhZBxJ4XEk9SBg04PcxBf4bjbnZvtqK9SiR5ZoocRv6MTbXlXq/nWmOzfV08hnXyCVy3ORHqIl+u/T5TTB06pI4NolzTgK3tK9O1zusikxejbm4jnYgiTfzBhBlPUKSHuvrA167NuPfSM85mnxOal+50b5ym29Zq3s6+QzpfcB9FZKrdSG3XZuB1VWWjtVFfk5OkjBw+MLWmVhdZelYXamfY3NapWN19YU/l8LTSvs5RiswaXynz4tlaXha6c91eAEn/xzqbYB5XSGM7wLE0Fie2aLyadwakoO7lnCTFjqYhablfCqVWQN/kXaSqo6TdruhOm6n05uQUQiDQpKMe4NEExoPSrIIRHfHMiW5GdTtqPMEAYfQhQ1rwVBwW8vQcZjzjgVdV82ftqPj1sG/HFjy8j3tuscqwLjG78Sbj44GRS/3WpL94MNHJn33yL1TB00c8NDiEQfGj1jTs/0RqMs+mG/ydH8iTFTHzA5nlsav19NKwuT3E7STjmTrOaknOUujcejhL9pDMxKmAe3xWCviHv5/1SlkYmlZmQhLK0pQJ3kTonaoFX9GXCiKoCPomZdzl/jmtk/eX9x1zqypy0IHi9977tLbsbLSzp9sbHy59fZ+P+4o72svvs25oajytum9xk4cPNJf++DRwxW1JQWziTSM0gMJLPrm9fC0qkUKi/5ZPMtUGculjUaT3WYxO1xujVrtdthMjNfnsllsq0dYHLVxC6NB45IVcZpQwEU4LyVjybpFWgqWAIC+BTw6SJYwMlHowS9yCYPpKkoo6QXkaYySvoZ5SqpiAJxndID70EAUxKxapRLmwiqD0aSFb7AmrqfVFKHCIxXlTUopqM1WWno8SiE1vlPLpy4c/ESb+icO/+2ZQ+JQps8ja+/qd+NTpvvmw9c++/0kyrmz4F55Fc+8FhDtiAmxsizWHWhtMLTUBVpZrQEfS7fvEGjtppyUs6wi7nW6OGCKVsQNJhOlUuUh+j6eimSmrlL2XYaTsgtJzij5ni81h9yM6sTaWh6oQKCQKIzMpD2RtJPmfFflLRl3YseexycsySHJerJT+wWre87p/dSAnoMnzZ4oVsXvmTN+3P33jKD6l7UNd/T16FBcfvTuocAEbMAFHMNvnw3O3TDutD5438ApHZ/rev+MgzXvgcmfv3D1479deKlhQKtOblPFbWXS/kF3iNOYTUQE+qk7YsX5vIc1UVYqKyvitNJ8tppXR4tZkynH78+piTuc8Mvv8BM6IlITh1lrYU1cZ2x6mCRojeTgqCHVPoneomQLzOg/iBccTeuXSPyY5sRYBjptKegkH3n/9V9r5z28W/zqP43i94eWrFj46fsrFu+vXffIwytBpzO760498RioYjYxL+954ISVtpxZc+69d8+tetZEh+aOXrmZXkQPHBS/bf7sifOZhuUPrN6yaOEaSXcUy/VjrkHdi4nusVCONeRRU4WCQOlYp8eqKGmtc8BoKrsyThAKv8mUj1ioZGWLyqSGqrKmzYKS9KWZWobTtLRKlJ+JJKGkOB+QY+eurOzVa9Wc+ZMXbRFvfvGZuGXRvQvmrOrVq3LF3FWPbt+8eVuvVdSE5XMr5wWndD06ef5RH+29uPbtz79466G/wD8eXTD5aNcpwXmV8x5c/NiKHbv31A1d1R/17N4EdC2emYYZPUsRnFoNGIIxmQnWCNNXrbFZg+n5ZjSUha1K5RoLbreL4N3q70UVoZbchtfJgUs2CtsNPfo1fLmWdtStuvHx4nn9+gXQML3kd9bf1NDldNtbywCPl9GMZKiIU9z/VYb15EHUcts4BFxcv8y43dSjX+OiFVR41YqG9yZP6zEkUBgpb5+OOzc2GeMnuUjQ1Qmp4W4d419K3mFukyL8KI7wP6kvjDa5w9wjdk1xyvAIf3OmdL8E/z7JIcPLuJyJ2BDf5RQ1u2dyS/dMzgTab/o9E44R8b1eVeI+S0jc67U/RfvRdY4fJcoqo7GnH13p4O8MOn1PP4WYL+l0Vr/UFVPJLWS6mbpfwld3RCD/lvjDvXDshuVBeI+yPL0Jb8xIRWMqVc+ozCaY4B6ULpHSYuSxyRg59V5Q7qWx3jpGvpS8m91GpPET2Z3N8ZTT9Em7L8MJJOFy/4E+yfUlcVYrr2/RCcqdWFo3Wlr8HQ+X1i0pmBQgcUtWkoYZOCGBGSh/WgJHj9Bk8CMnMQmrEpiEiTsyDEoIrJm8ee+IQ6j/4D4KN9EpFtAKNoLQCwZWYD1ehN0EeJuWpii1ANTOirhO7ZLna/HAek4zInUhzT8h9yRkuKS7u7aTndCOSfNvB/uSnoe59Ps0m+Rqnp/x5BDm199WJD0MSSyH/vcyjNUiRBT5F16hUObbbMFIttsdUVLFJfkRG+XI8gf9Sn9hRdzv4qHjhXaWd+RUxh0OpYZTmiUI1oyuGuiA+QtCut9N62jNxD2XmyGa6Makq7YuNnjInTLgONlqXnzFnK7t5q6UdZ09EexK6koerZt9dE8Kg3zqiJOvNE6yLZ0taX+wZn7KuZLEwptfU68ygwi7hHbjs8BXqdNwDivDMeGIXTAIFXHSDYMLzqehSVJlMRk4rUUVrIirEtgbF6LSy8q0iUm816ZvLAn2akzXz9G18/wVUJ3nK5E6CeDXH6FWbX1d2xeXg7eS7+9gDdlFHrLriFQZNLxMurvoDs/GMhxH5cGMZFSsVZbSF422gDE3R5It8p1OqoWSblMmgMIcdF1pM+k1fEmEgaGTz0My+MYyHZcg2gxTJK3HxR8uybirRMGTIiqzOUo4dAocOqHJQRa/SnRL0BpaKqp039LpS+f0ujNAkrtIMnBnrznw+z1lFCN26dRj984eXcgfOvfcubt756Lb9gEKtEABU+eqKWC3WD2lqrP4mfhP8R1R3HdbEel59wp4Eux8669vvyOOFvtdltcBns9lGP++JdzRQ2K5AXsByfMRr0fIUSoFO9zSfi6vhasFTDMY0sUXhqyhirhRp7ZaBNefr0HqshZIjcOYuzIcCVrhbi5FdUgJS8AaLS5Nqg/4hPKHGKpsz6L7YCo62oeV940ecJOYuXhfKVT+tU69du5eTv6wfPfOnp3ptlB58XvxauM/uvefLPYAT03u14MMgAIgQMUb3712BewET4oDwAmxnzj6EsadvHlzNX0Jvn8dzDSsxORYO61Kp1QaLJyeIymKN1sBTCkMBpbQ6HR2iqZZ1gZIPYmK5Cotb6YVej1rUCsomkDE7tEL0s6GsaGMpg5SrVsGKWhMVGclfhXKD4KlQRC1GqMqMgpF5YBV4afVK8V7xPo9/foC8W/Dft8jPgLuaKjPB4ZSv7bbRweIm2CeqJ/OdPsezGz8tqEHaQR1e8ZE3jrcgM9ni5v30Ycxz1QWcU+sg9MFfYLPS9CkVqMxK5RKk9nMOUg6FGZVPr2XIxxK2mUjEI6FyWSzCdVxm5EOwDhKq6BpNPOaslGo04A/b7A2wadC4CD4zqY0jOH+SqMUGiiTeGSl2ZKIIggkQlny2wdI247J0/YcaRs8oNOLpkEbZRzAFxct2QOECHi/712H9585CdqTJ3o9I37ae2SnkKvh/RoMBXjHu1TR03MoTTkGACQxn85QPJsfIibGOrrcbp1Wa1FzCj/v9BFKUqlSWUhLOKJQ+zkfTziVjNtOmGvMJEeZzXa7oSJutzDQMul0Sob/Y2WRgSpIFNaxqqGwtGmNt9CVSujKguFb/vVhr/ZP1F5c6HtKExCfL62sWcidMn/4+PRhL9cCVR5oFchduyD+ECgBAvDyoFbsMOSAvmt+Y35w3ERt3dMhsTv12vE7yUPq53HceUeSrwXGnYivRUVoCa2eU+OIVwFD3qYsLQVp0FcG+T1h+Oxk6/q3K1eeBevFe+DhGllH9mt8sk6M1aXtIx4jyEQYllWpKK1Ox/MCScJHmcxGAs9nCgDuFEqvVVMsIoQ6jw6BFY8/NIMhSsx1oTnDIEDdoqVRRdTMlAap38RLz4vn94B/iN2oCQP3DMwWu61bRx8UVY39wZzGBkpHhuoefLDu++/ROhyD/tdD94G57+2xiM0aDefleghCl8uErWz7DtHSgIemWrRoBZ1QHjBQeXkteF4lwanyFOL2tNkkXFD8vqWh5ajUR5OR9wpJzNJAxIpnNaRXXADCkbT5lwKQT0pXJ0loNjzlQXs+f8Pf/SVnNyfMxWva3NVm27w1vbr045aWLZ2xYv6w2xduX9z7zVeffNO1h1s86f7prW7bvHZer2yQs/VR9TW3zeWf0q7ltv1Vg0Zbhw7rMGhQrMIRyO43qWLD9nmrTD379e6T375lKKtD79FwPQ7B9ZgK8xE30SVmJqx2t8btsNIer9vhdFTEnZwe9yFr4nqrDdo51O0r5yWJge20Qgnc3EUe4AVIO0ndfGiY8kFO4l56esfKzl0PuYt8xe2RUoX9u7XdFerav47c2LiearPKXFBxMejqOqVdoadNj3O5vlVU1qoVUMYo3rubCAtRGnNZEFYnoaWsNspcA1M1jtBoOE5ZE+cIPGiXwD4oSG/Y9gswbxYS91VZUR8hmEiFAJ4r7gMGHalfctBxMguo3gQMMN18n7TpwYILT82Y6d5/SvxZvPGV+IVSXIKw6qEcNPR1JqJNzG0iaJ4n1BTCi6qMA6Aj0ACXAloEXoZtvrUgcn0jrWImkJa1e++Zf9b1lOOvey9f37sZHH9oztKF5/Wbjlx7ae2rYfEC9LP+5Cy/hwgTc2M9OW2W1elU0l6tgSC0NpqOZDtYBVsTtyq4LEuWpTo+PwsQWb6sVllURda/skhOgQCHshRZtEoVRDiLtDMdATnFhzRqyhS5YnGLToQUEDLGk0pHQMa4z/6mKMjZCxeCuiQAcgO4HfokNUZB/uAjCQUZ9FxKzUrhHx9aeiwJgEwSGhhnvQj1RvW8HrGgg+c1nN1opEycyetzUJihQCDgwhuhcmYERiLPeiMDFk2akszRBNTWhgfphRLZnglRgOAW/Oj80R2WLv1nww9/X7z4LFn0vOjdvajx9eIZ5LdbJ4g///gloB7YSg5rPEAOu9F531uDb1+/sQvKU9Tw/byIsS764bhoz00fzIEvYW5JJ7E2NgR6SJq1mB12iiUVhMDrtCpWifAYaOhZjbTR5dZaGWt1nHea4HvReU0FJpKDv5Wbqk3zTcdMH5gUXuhnaZWCoQQbbauOkxJg2gUpbMLxA+KXyeBmSKOZkbjb5W2ogMGDIJnQIBVFU/Nm4EdTScYgeGf02tH7ya/a1rb13n7qffGjC2Tvhpug6JRoa3Hh+w8/ZLpBYyoO3yZG6ygKPHrjR3CZoInZ4jB6BI4dgjC3ySG2xob5srIES8AfCXOs3qoFRE5LO2vT6RCqqsJqs2W7XAqBys2zgkDLMKAptwmF/nDDVsRztJzabjH5fGoTr3eqYQKUop9Ry/Qz8lR6gQG1LZbJSuPGxvJm7e8ZugMqw+Ma0/yxYMYUNMYwdMPGEHT+5KP7S8ru2u54JPfrvSP7nl3719d++7p6wKnaK0+LoWV1DOBXFotbBi0EM/SlY8Av4lpjvF/eA0ss4hDw8YPgDqABXjvYLLZaIdbZwLVjW+HGE/OfGgf8Kx/u/4FUD0I8gDUYv7xnLEsD9eUJWk3bHZTBiJELjAqrFZ5lK6XQV8c1GkXahGUm6ltZBuZb+pigUCJDpVLvLVt27fnDl4LPGKaOvCr+BhTiRfAz+e2WE1c/f+IF74yFwH5yC3i2LhEfdcd4uC6iIpZlh4K5kGRuj8M+MO4ASL6KhHzQLXAKHW7cV7gykMGiaTSSabwcCSjPcNr0R2IChOoKSFFM8iiKy8D94niyzyuvkOOXikSCSRE0LgVd8MABSUwRhzI2Zjg8aQGEB2VTunUkaeGVfDBLT2l88DRpaIx6yDDwaFEYEi7lvTNBLKQV9AklKdjM0mgC/AMDVEukTPRD4m9j94ri9zD8UpwYv9TbpjRa0LZh5OHjW4cPOHZ4vzgU+N6qBpNBP1AJakb2+71zZRf9Hj1dhcCpZ1MdF8hx6BK4zu9Dn+IjclHNIqL0630+p1lpzst326ribpfAq7NQsYJnWlbEAZPZMZbTRPBQaQadttzUmg5dkt6PcQdNtn5k/usvgNo5u1qTSvqIok1puFVR7wcWrty8YtbsZVtXFi68ewSwAAvZeuidnvVMu28aJlZ20e7RblxPHn7z0qUPPjn/HmLRRXei2DehiaaIhaKUNA8IQTDodPBgO5w8ySIYZ4tCAX2PGWP8yliPabukyXCHjH6XpJKRfCWgElhRz4nrvju7Zw/4+MufntkBHvo1gRVFljeeI8s3kZPP1W+85Gg8TF1OYkUdQnexcK1d8KzZWJeZUan0arXL7TE7HGRV3MEroTuRLsYYnU5t4NTmNLobW3mTogN2hTikkKY4gwiuJhyJwoXvSEKLQpsnj1l0xgemiIvqH3jAaT+crWSKapZUjxtLbTLuX71OdIDP1nXr+/odKydPHl8iSDV4jdwTKUCPNy4W5Yy83qQzGASdRsmqtVqWJygGCAIDg2qzRUEbTBSMpGviesKgVrO8lmIxsSqUuSzh/VKoHbipKvlfzGpQJoHZIg8ANaD8JdFI1Ar9Aij106qnxS+/ePZL8ZszOy9vBWe2Xm48u0i8QfdeJz6EMDzA5HU3btxo3CFh24XgPj4M40gn3MlTYWTttbqsJrPBIsAsn3LStMfucjiA0+lSW2h/QKBdXspoMkqTxNDGmExKh4VT6iriSlfKgWfqIG0OKLAMKIn/KE/CI5tHIUR1yaCUAzQSTUWNfiNUxeg3UL898f2NLtPXxHsXhfMHrGplEG/+8MTGF1aD08ueb/ykxUzx7Dby03WNR44cHKh5kJ25sJDsuQ4MFg+DwQ0LJoEccRXSsRDa6jK4fwJEATEklpetNBq9dkcexzm8VKvCbENl3J5tz3YxLmgQXRYtzA6VWi3DEJVxJonPFW0GMJ0BImsMKEpwOiDX6XhGkYY1hs8vE9ADNyjtCBOH8MSMXiqxrdxLlS8++MrFlmQ40UlFvZbsmBL3JjqmxPefOQGuVVSyaQ1TKSx0J91b5khwe1kNATNeFsF0mWGo7ZIaWAPNG1gzweNDtzJF1mA4ko5UR40u2TH3tefAgwu3FUITdIxVHIE54fINy2bPWrp+1am77wQ2ZH7i1d4lbPTzxucHPNR7Ipj+1l8ufXD99fcSfBh0BcwNAigqNzAwkbfCLDeYZYb5i8HMc/AUU74/pHO4BZtDcUQaVP8jLgf2cfUfMzmQ4zePKJudTn6R4uxAvZUIaZhwMuGw1gcT8Nw8D9wlTg/Pm6vimHiixf+ZryMdIetPOSg2rOs8oG238m5/xkPxcu024VFz355TMgk8ALEK6tAJ7n0r4qIQDAYF3BQsYbMrBBjEWSz6iriFp1RpKJt/xEVByNMVyXQM2kof3Un89ceTX7heCP4dlK57BNMfPPDqHPAFGRH/Jb59dKP+PDh0/eUJ92hve2S4jP35GN0NyoPWdEAs16IWeD7L7W5hI5VqNjfPGYapegslSTsFJ0oPjDgvQ9sAwThfyJBQqv2nz9EiQFhUPw6XIA4HGePIbEItvD4EQV2EcESQ8B5Arj41V+1oM6dnqBqQP538yvtC4NNH1rnjn84HMIe/bWHXh4Y/NcR7n2mAPjQ6Pr1o5XeIzeHwFv35l69vrBo+4dOH65Zld825u3qUNyKdPWhH34V7xQmj6C6xgEsbMNA0YdFasluYgD6EOjx5lRfqobKQ9qo4mbCWfxjKQLdvB8FMJgI5oEm/bqffLer9iyKdiqAeBQMNExM8BOIdWpANCtLZCPb+dg5GA5Q5SUUg2Q4GMO/BbK0lisWQ7QiFDDbWlpPrNONdrlRm/4EBkQKypiFNhuglqEwooV7+NyoF4OzUvW272X/MprACZHMHzBsa2jVlVEB6yLNw0As7EYKHXqezEXaTSUEoXG4bURHX2/Q2Na0WKuLQoZkr4jT/X7kDJDoFIYOWVqa8XPr7t5//KH6z/8vcRxzb71qzS/zowa1ashezCfxiA3YQhif0B/Fb8fqSB/L6xV8/Ba4d3LntaBM5HUhOVqGwGwmbTWfUOV0me0XcxJpYXs1DCXkLSqTU/1VOkNbRI0lLCiUADUMZqBW7V8vZ0Dfib19//QO4DrOgxjMussup13HqI74nfif+LH4EPMBvE/OPbRXPSOtZcPMbhsH3BC2I8TFouhQBH5Gd7dRptSanz9kyxyKgYMAXD9hbENAI+rXwoLIsYaE8ag/c9p5m0ksjbDILaTSnKQ6dpAsuqklIl8ZSq1SYwnkHdK1kEIb5UnGuJEK+5ZhXPXKh5ZGc17eC4RVTLZrscIsOrYf06TeRo//5rtjntG7O7NnLKfLNhdOGDshbsEDc51jYtUv26nYb7s8uEf8jfkiW2+49c/ji0wPwveUxyV4aWGos/n4l/D6Ev/8cx6IlN79lFHA9ojBasjqcTgUb8PvNBS21BFFQKLBMcUluGC1IVrxQwPyHBX6/w6PIFRwOIVdBUx6PDTVuNTW50qJgPhqpMSenyURMqi4pz7hhFJ6SaGZZylqaKFriH0SGjrrjrRdOv8mfML09cfrk6TXDR00ef9sR75PmV/esfDqwwsUVFIU6BNrNGzxigcNfP3sB8K/df+CI/oPbRg2tWTOyf9WoS/yWg3eOtME1swrri2dPXlRqWom43G9+S/fDGM4R1HNCWHiXwu93eTQWJruFR4uxz7XakD1EI9RTO7Tjdr4pNQhR1gRkKAUvlFSMVWBTbjYpJNinoI8AXTrXLpq1etJMpMyCu4/ueg6QP7769fVZCya9tlD88SZBhjecq5kWrxoEFaiovnodqEFk18rj5abZU2/bMhBYpT7CSTAmbAtjpeIYQngkLDoLzN4xMoIabelTcTVrNSOgy/Lo+Sb3ltC6ScV0OV0vQYKjFnp/CTm/HrDi72n0bqK5lnq8YVCtPcXypq7FZ2utOIyhoc1FM5TDY/k0ReXxEatK5QnxoZLWTn9V3GlU6wphcE0X0oUwZ4eZpMXIEwpogJ1JaMQ0HC1bGjtTmitJFRQyriMTpHTSRTOfiD4kXci7DlxynRGmjPyVHPvvC6fPX5ryWB65bq0vXFpUFuv05KbFK+6PThw9eGF3cdjKhfY+laDdi1cBBW20E2jGjwaFD2+mNI8a+ne/8YDYhrpy7u9nP9h8rKL6dGrGiO5jYNGMkczplI3zO2gJzS4Fyen1Dhj6uD2Yv4EjOEYj4Vcz8O0wlj+whNIlWxEqUwj4krHYkFGhR66zJEjOBscGfDBHpGZ8tv7gP9xPcTMmbtq6bf+aCb+RbvG2br1JzwlAPvz4Zv3wCR+89db5LtclO1gI/ft2jMmH/EoWCSx6lqAMSpphlBTclyzqw6BMlAZooPXWuGgMkSoLmYmwnUABl8gxZLAqBHNmLY7I0R/4j9juMhgDJr0mtpo/9+4Jc62hX/r2iWSFIpuofY0s+XvDqH/MuGfBgnuyh498d+DylZX5xVFJTsXNL+gLdCcYo7Yh+sdMWbbiYtpPOHlnLlXWVuU3ZRdkS8mbQBfn5Hh0BZxHg6x0WvImFeUAzHmk4ps00QMFLs4HET1lNkWLMIBkBB9PyprUoBxQaKk5IBkjL1kO4EY6rja30DpMuh49Adn3oTZT/eXlwTzr4mgV0quicLE1L1jeMTC1zUN9R89oUWoxl2bPeMfcMtrX2qpVgW0U9UrNyHuLRpSUiFdve7hywqxZE4asHgValZSMKLp3ZM3QSZu7d998zzCpJlcP35EJviML0SpmVbEWzmiE2Y/VZnTxCo7SZoQtt8p5MpkEggLU586Oe2c/sb/+9nkLN52sp+mnJo9CUKaNVXWzj+8ip/3uBlvnS3sY96/Cs+xCuJy0QQszZqPBZXB7jC4zqYABH8dZoUXk+IwaVlNCrESUlMgI0ttVnwKubr1KOs9Lb1WlnwDZ/H5j7ZgmfarSeiAsMCRTCKHCQ5myskIug8EaosKRkNkMt6nZJYvmayaaHNFZ/1y6DLr7W4mZoLxvLmwG531CZlKeg0C9QGZiYCwHQfzQBh261bUaDQNHGEFTWg3uz2g15ApmoifhlsQaqHZJfvnOOxK5xpdfiufAj1LR8lBtLRiSKFfC9fzPze+paXB/6YlQTEeo1Ryvg5tKxykpXEJVpgyTBGiWHL9C44wlfvJUWak/tygPRlo/gRdAqLK7ZpcaZJMba+FnX0aDafCzNURhzMbQaGBbq0uoRmkIDTaEmZOmCWdklBHJUC32MhUVXwCxhsugXDxHt61t+Li2lvJI+yHBVeIjKmMtdXAJXbwg+AM2lYqEyaypIs46VfAX5/V6KuJeoOU5GL9wmQsrY0s2Q0aTrsOjeEPIsuANEYSmwCrxl/A+r4NdNLwmaJKW2uGIOBeRdw8qxXQmerag1dSpjMjW1pIdlK0Kxj3AgK8lP5mQG/EG3B4rcun1CoWKhRvDalCpvD5KbVVXxgmrzW6wV8atBqtBYUbAk+ZbM64knGUzeLcknWHaFglI7Hm4Cl+CvUiU/PDgQUkBZszShWMVSPp6RbTdJPK9hWIJ3DKvLb77jjnAXtuof7d9dDxc94/EodQaKL+eCMSE1L4BSqoqWTZLbhoGB7tpmwaUlZYWdMsTP0cPmlbZhdvDgWzmbG3qjC/FNYoxsSjl9RKs0804GRVMqwmrilD5/IKgI3Ae7WI8FHyxLtbBop40igMA33iWlyVBOJsiLyQHOhMxmtREIENwJmJRjM6JL4uFp+rJn8S1z707//N1z34ZOVH6yegNA57bUQXmN77KXBInPSFusInnVvxz4ZZN5lPVj43ecuYhsKhhINRjHIwBxsP9H0HZp89tASDMKRRqddhNZbeIKD0cHXQE4W40Gi0Oi07qwhKSLUgZlqoJljXMNwuAjA4RbGrmyacKO8UGHGQ3MoAMjOs/bKiRzL538MyxBwo7de6HMK23zXlhH1ndcOS5lvNbjR1VM2bC8MevIgewbc6BA+Q06R2Mg+/gDih7GGfOLjMAIYVGo1aHXFQkO6x0c3TADpNmvcFgtls0rv+D7ND6l/4X0R9TkME7u/2R4NBDBXc8EO9/C8EBcQeUewyMu1oRFbGWnFKpVVlatSKygx4PoaIKi/wh1MhocTiMubSRRmvPazlChaEiksAD0QzYquSYrz8TyskslUWTXYzN/QZplF8ESwbG90uqM2t2DPkPpBR5FKnUuBv1LKbeRcqN2JFm0I2Am6LEmwNz1rKY26FU6gyE3+APBB1uN1TDzZs5DYdiNOm+X7qPSbt2zVQgXVSpE1Oe2RiDnNqsWdi/yUjo4/995JDsghVbV0piPS91WF5+5sXGArjmiNPnV3xvVBpzMYRDgOfNEPBD0XSSaAazgqxKXsfdYn6EMSXtQ9MeUSwZbZ/RMTfWTvwcO900yaZt4PfpQTbVRvK3id5PKJkcv6DYiYexk0VD6PWcEk3Os4KB0nAMzyk5/N4zCN/kKqwKWKyoNhUEKD1HjT53gcvmEH3oMbE02684CHfjQE/vueSWGxfIZ9r2uL1T413wQYk+ZZRb01uxnW8Dv9+Fa5UBYmysjUdrpSibgTXTNGC1dDDLSlbGOSvQUFYrC+1ARdzIcc6KuIHjVTCAUagsLAV9mLlpZS3FgJ2TMd8iwbNKnjMtL8K4tjLUKWpIpG8XZ4JXGnd1WrTz0QO7O8ezyL5i3x0DRowYfLC6ipyySNy0tE818AEDTH4cwVblK8QXBn742ut/FwdegzoVQ5224DoPtg66LA8ARoXNZsyCtsFjMvnNNO+Hbtbpt5jViLYuDfIeA/GmcmTZOiRB7jFnkEQ3YUSNMTgVlae8CfJU//6Derz63PMXew7q338AUICcPZtGL7HZF4/YvgPkkv0mvHS8/vQXgBR//+eZJ4+/NIEEYr34tx8al81ZMlf8N4iAvrgfAnOUYkw4C+GGGUULq0nFcQ4WbhdeS2s9XpURETUpAAvfBMubHMABLR2QOIbS2DPKMwAf0BtAiZoQhquOcmmLQeAZwVgcjggdQchkscIMjtQ/dwWs3vfWS+L498ZNnTK+8ck7J0yENgtsswIYB4LfisBicZ5J/FpsFIk8cSz1l7+8amo4ably7swbLqqr4xKycWdufkNdh9vNTLSImfQsqzArLFa90QjPmNGiNbMov888Y4WtSlNkYujaI4jvp85MHrP7Qn36beA+4w/PgIbGLmk3gfLzML7IrZ8H/v+eR9XeOJH5PIRLibGUS2JGI8vqFQ4FTD1sNvhAm4XXYHoT3oX1TGv8ShYyStOJ0/BlM6o6pwRA1+PteohMfs3ikQmVb/Sv7KLfpQHZ4O6xd0YF7Et+gHKYcT1I1lthTurNaziF6xZ6g6T5anL72kRxahN8bMMIemzGnWvqmV6iKGa3aVlWELw+v83thg9FppRTVSXIZ5qa+OTDJbUVsjltKkab0tY5AW+++HUzcRofruyi28ew0J52TIkFgEu+q9YR7pheRxCsnqOhGHSiuUySAPkX3KMgF1+AC4ZUmvF3jRl37lmSBk5QYHzMfO09kSLkd0ydSHwmoVPo9JyKroKnTiLySn6mNFmILiJ9hB0ekOdeGDfmrvFABXzwAx69ftX8mFG8Jv4TxlskcQbKOQnuGx2Uq1csS6XVwi1CABi1GFjAWqwqHQcdEscBktRXwBRRA8xpF//NKaJkgKhg8sI/CIIwgC1CRTwwsR68+cwbc1eD0e+J9e8Dw/Xpd9Nt92yc/0hQ7ABOg9/F2mdGjpDyv4RcCkkurUql5JQKhVGNqOGMnAXNWrIVcaXSqDZxRgX0AeZU6aK5WII8xIgMZtBvB1H4C8+0BRGyzP0Tp10Xv3sf9H1P3Ll67pVnxbz6FSNGPiPWgt/BabFDYOf8DXuhLOgdPAb3WhbdhyhG0x8anjCwLM/neMOhkA3uv5LWthwqgMCCiPDkMKmhwuEAr1dWxfUuCvopg4FKAoVndJ42Y3rCEicaUM2m1N4s9ZBRH2pTyEqAdkh1LbMJOn4PRWd9+frpO+8vaxnIyhG/2qnrOm4S0N8+VhTX9Xvr4vFrjj26GbN+zuk/sVOnFVN6gZJtx9rtXKvdwyjgGZ7t7dDTd7i8wh7rfe+g9Y8unW/q1WtzflkYJoctut+DdL8Jt89LuKcoP6bmLBZSpbI7dAZsWnSAYHD2S2QmMtE0Po+OIP22E4VUYOmA0vZlrTs4N6+/O7ewc78+W8Shxl223MHj6LVHThoec45fcGNG/bG0Z/tQn6teIQhW4PX6A3r4FxVxwWc2O7AYZhcjkU0xIAVA2hy/OxTNECTRcCVL2QFu2k7ntjwyvBCJdOjQlu2ylOdWU/944jgWq6HH6u71xyRZQ/C8k1C+p+HZxGtj5Xk1RdkdWgUWSssTpj9ZG7mrR2ocgKsiJ35U8daH+vTpXJg7dM82W5visval4tDHT1O6xWOdjxkOHm3459ihubZdRnhWpopD8Nq4YNZUFfMwwSDv1mh4C0HwfHYLdOnIE0GGhumyzMeijpuAAoZKlMKVfplqS4xRCRlN2wzcYgXoHlLecdb0tZPv79CfyTNjZ0/qPqjybK85vVYtjHVNvFNxcKeCjr36l7VtXTj80Ixhdz7bYcqgmcttdE7iDfNtWlcPKOyEz9cJGGx8w4yBp75dzEKazQw89hYrieH/zQqFQAuow+fJuICg6s7fuokOBUdBSoJlT19Z6ptDbWeJFeB4gmoKHKgVPwOOWnK1zDLVODqdJ8xMtI5pEE+YyQQNDn7wHzODpT++CSGYuTkLmEx0hSeTblyXn063kWxfL8QpDu2NiwjBSCsSIAiby8+jriwXHY4ElHaHHT4eOBxaysWhrkveBEOKBIrVLTtnk3cAAgbIR/s9jc9JIiBIdNBawDjwy8mJE+WUAVc+774bbFi4SVTdTrcVC8BVsWBpo5Q1oELonKXgakOH47vcw+pmo/WbAeUfCuUvIMpjXrNOUHqzldlU0JlH5bUqDGlR0SOg4whbipM54wVm8jqVFJcm6grS/U9y0Dgi1WRkMhNUfibIsR+J/xoU9efkVD0Qv6dL18fW1h7o0nXSsAeqcnJ8xYPEH0yAeGv1zJ4xl7flqruGVk+fPmrn88/vHDV9evWwsataet0de81cfVVslGYX90I9utJtDSw1E+/NbtAnPQj1UhPZMaNKDQiWIklWTWm0lNrMorJcUXk0EyIbupkgHu4BQRK8DU68Kv4kFAcj4jcX6bYwDXqh9ekZMxs7EqgAQ9BncPzWMmbiOUpJOSini+J5lcNs1EofXgQ/vqwg2UqF4AyM1o4A/h6kyBJWQSF2XpOehH9489LaMnXR+tdOPzHKHzE+eG6Rz6rUaqk7j8P31+LVnIPgMnx6NVB23NVaHAYOjp/oGV49xN64G+vZFcqyivkE5ir5MatBpVdTenjcLCq9nhAwf5NGQEHA+dRcvCwPkK0CUhcmgcj5d/x/pH0FeFRXFvC97z4Zd41PJkYSCJmJYhncQ9AwuBfXFpfg0OLW4sUqlAolFCpAhbbQ0tJ2q7vdytZb6rLbknnzn3vfzGQmwO7/fz+QkfCunXvusXsEkwejPlv43Wfl/wyVmsmvnMeXgheEzxRXretvcis+SZvW8D3f6rvzdPzWMP5WgIUK5DmnIIq8SoVo4WKk1kiY5wXOqITfVTbxjfMpApVyn2LmRLn0TVyLR70uN8NnuRWyAf8SWiT3jMRxAx//GsawUS8Nq0mvtdkMFr3F7gAtkpmT9VYdaDQ6e6Jx7kY3QqV2eOycU2fdSHA3X1hQXprdsdVPIVc0tJu7OqdvR+0hHc5bHgntpud9e7iav4vdV1CLbIHDmqRBBt6UBoKs3WT3ZNqZry5x1tBwCasxyeQwgjCh0xgjuwAnXcmZ2qTWPY3OAl4XDVQowKKUWx6dXnamKCmXq5xm/LnRc9dtuCfUMvOucvmqEs0Rmsy1KBrX5UTvLmV3HT+w6Lb5C0YMaHtHZNZn+k4oLM9tDnBcCHBsz/wGewXygOVxNlHk3Ml6ISXVDVo76IDEQDSIOVqkcMkoOdF+HW+Hjb8DtiYaF+MuhLGnnkySl1/8eO77G96XnY9b96xbf/jMkX54fagn3+oxeZf7+st3fb7s/NO61fNePrqvfgteoeQDHMQvh3lmoHw0IlDmFtO5PIsFpXlBkOREdWGBnTopEALU1Kny6ng7sRMDMnj6BrWGFC6Duh41zvulBN8j5C+46dwlejcWxzZjC8C+8oiDV2Qp7dt1HLd4xwfL6kce3//0u5Yn7+1PV4MnnR79yNHu/eezZblCL62cXtF9ybq1nRf2uGPFzqoe+0/B2q4XTtrYqrRtD4rTq+HcFIMc4EStAmk6vROJVivSE5ebyp5ER3QgD6hpBfKoDnKjE6MSauNLKEtkUWJtzpZ0PnRk04EpdzqeTPv9zC8/ffsPLs3y7qX3zk8aa9hxRr4m//Yf+WOzvFQ5X4lz0TqRmeeRlrhdNlwTtOlsOqRSwTlT/Y+55HDmEsVkSKXcjEiBTa7H558u+XT749+mP+lYP1V++8ihziV4hRkbMHns38sf320YO0meculdS+hfylxYLR86l9Z0LtgBc3FoAS5OrNOpMJuHA9tqgtiY4JpQleiWQI0TcQipOMBJZm5q/GRwIZ2McEWebJZ/kUPR6eCdMB3Op8DmTsDFAMiKDtQ2kKpFoiCYzMjsdJlEk2jjbKBn2ThOBdrWDXl9EgMFrMypijq3KTYrFhORwd2J5ZNfZDyb9+6BvXvu/TjzvPPnJ2X5V9yfu/7AXsNF+W/yS/J5+crbur1P08o6iETribNcwW6gh1aT2+EQdSxbpiPgdKqJ2sAEWTUhViW9vyOxlGvSa3FWHV988XAfIrGa4dm0kkVj3fB/Y1WsZLg88YUmVcOPyccb64Vf+Mc/aA4rwKlWjB//i8lJC8PfU7sh8z2pCRQaU6RM5HDo0jNThLxm6Rq9hmqumo81oIdpNO5s5oJiUkI/E/Y5qoQ1KSUVdRegIkZGJIN0uYm58ZbEciYisqH7hkUzVqxe2Dogf7Nx3fz13c6F5evv/1q3YMa0H17/HTSDwq2na0f0rR628al+E4ZfpAlMPzuybcZ6W+aswRselD9HMd+HDwUCKxkVsKAMLkNK0mdnuy2cxOU1M9mp6JkSNGlRbk1Qn6QFMSFJ0GpTmS+E9ya+EKA9xgrrVTZebClKZbxbBEtrGnU/vbWHxL0TpPVzikqyCjqU38JTos+Stbpdpq6934pzmIA9Ow175mJ79j3Dte6RuiRWlIYy6f1jpsBx6S5zit6sz/JmpPcfmoEFt8lNsd8EfMNG+QayRqjvLQNT4iszMX8cxf6p3NlZqWCrLAwkc/uf+CdcIz/WZ8dtB89s239OvnjnoGFnerfv+8klvlVD1l3ZY/YF71qydDmpvl45ZYqrTWVFezH32WfZ/c508im7m4Vzq1Kro0m1tbxOz0kaLGE10RrFZDW7TYtdmDVmRI2EEKtxObvTwV41xq3x9FX19XL23/AZ2QfSmX4M3vpXCTkY+hW/yU2iuIHVzJbUCgkoM6DhMcidEmfEPDuJOGL2iBl/mrGqMby94bd6bjAsKGJPuVOuFQTml5BH41S8yam8xaI1J5ub5btygOC4HJYUlaEfJchUMUQmmpE9WqfG3zROBcf8hqI1zCMR/ZQS4Tj3Zc685ICf27a5nBUxP81zzFuceyfqIM73GDQOZ0YqmP95Cp95IOoxHvok6iSewE/S0dCAT29wpaTgVFBnUw0kw5OcjtL7Bl2IBwnJyKfzHI1P0et5RMypdrOmJmiOGAOUfKqJWfMTqrRZb8H9WGikt9SzGvtv4II0zKBefg3bsOZGdjh90e7dTeY/POA3GZPT03lkB7nWSDwZaaBm9Q0mExfI1kZXugvmT1wmk4sQpGNCaCOTvFne/4QVKIn9b8426SK4HjQo4ibs0y+/tnvR9Bt5qPzHot0sX/Y1li/bBac2G40LlLpVDq/XYkkzcOYsp91uVoHuYc+20uQQRjM2arUZjDilwEEW7F4HAhEExS7g/Y3SdJO6MH7/f02boSTHjuXKUGMPZ2iSJMNEM2M36JTsGPgyHivvvyE3xnSaFjuWESO0jvjoGfEBbaJ2lCJUiVYFurZ06TMzSy0eVJSj1WWLzZpla4s8LrEVqCeF9kJSEyxMydZ7gcd4jR6szcnR9A3m5NjTk5PLa4LJJjvNumZ3mGJ6OV2nJWIzdVVVNb1mTyhbFLW8NMq9uYCaNF34TSBCqLDJnJIbAcM95+rdof/omSNbCN/IBzUHmsDI9kPdovoja+/Ol08rcFpV2/niifuP3o7vbXh9yY3gWiYP93xy+Wf5rzvu4Z6KQE2p3ZYW7s/wIgu1QMUAt6WBTtl6VFqaUsEnJxc5nfmSo2VSRWZmkkPPt2qdVOwqrgmm+2qCRenpgsvowKZCEEhNmryaoMRpHKXJAlUQBHu0rDi1r0SpEPVJuyGzX9RhIxoYS1Wcm4MJRy6dbZ4E/MFMDyotIc18lpXNdzZFptDPrXttGDn+NvnLkCWGUiPkw3hm8y65PTfOL62446bYtadu7LAvYxgmb+PyQjO79xzKcghRwO0VCuEklaDRAb+huFgrJTW322zZCDWXSGlZUraZN1PziB1bCJwtU0u1Rt03aNBpTHxJTZCP0Pyo7SnRjNw0Bo/akFnokbeU5jj0JNqMabQ/9tGsbbk0lUG5l9IKfu97F+Tg7dOWrPLMx2s6dLz7ced+3dh+xz1tBpZOGTdeHv+Lt8uMNYs7NP+yTSWu2nNs4SLu+ZW//GJeepete6+dhRW5qWavZ638r2Mt2+Z7cnpP79e/W2h8dQfmRw5nrAHwhdaxGB+wCHl5XHZzMSPDpbNmW4taZhYwQTPT4UhWAvkcKYRgjcao5HDQ4FzF9tZYeD4mrCfUn48zeUWMcaWJluc4Y68Y509Rbi5iVrqYPTpq+t2+8fDh+oGjJ2+JWO1axpmnFStweSatUk8L1rtBc4S1hq8BzXwB9rklaoNuD5QZgOFKWe70tLSS5s1b53BOtyS1bZfiqQmmmMxsg/OBcuQ4W3N8fnp+OmLbbY8k+nSg4kZzmbL5LH9+JJfSDUXDooEwyuKUraf+TGyROTSUIVIPhobFcJG0S7lR1mfEDjLk3nEzNkxfRXHgsccqurat6vXOy7hlybGkE0tmZvYfNbJ8zup+h6aPnVLhKxpW3r65bdy49Qu5S4AGK0NTBnYp3fQ2jZSRzxkuvvn65vG13XOWTBm8vOuarl1ati5r3b4L5Ym0Rt044RWgG2MDpfnFxenpWRk4KSklWW+xqNXJGcTnz2teE8zDaazgarHXlJxh15r6BbUpgoMG00Y8FSMVxvxNi9TFX6fAOYh5nZg8yuY3Oiuac73RANC4aCxuk8RlThy6cLrc0KZDi8DU0h49Bt2H379v/vz5izv5mqe2r+Rb7amtrb/c8Ij8vumoZQfxHJjH0mmt8jd0J2dWLty5XLde1W3IaEWGoTmnngDcb0HrJJMWLVCa2QXaVW6uGZGils3z88WaYL5DnYZsNqCCW1zY5bKZos5Z/qLIEXfdopIafXPw/z0viZK9Mdfepb4ahTfv2H+rTCTyX3+/M9xfuHK9X9/BtX1vmX+k3baHu7aZEcvbugPWpgLpuE0gTQSNC2klAQk6vaBmUQ5GjDUiEuPFgJuZ0vwxLm/GT9YTLvQMN6nhA66Kuo2tb/j7XeTRho9IJhtzE8J8OxhTB1rrbYESq8UiCpKNM2qcLrdbq9M5jTZBSEoGMV3ieZfFaLfAX7PKaTDYzHZOhbX0kshP/0byMlGXRphEkb+xlEp8DT6l1LcWe4k/GdN/JOHLwtWbd6y+sHjN7kV7Vy+8GP+FqDlv6J/cC6FLXAX9+as08Tus5WGAXzqsRQI9p1Mgk9fpBD1Wq5FKrzKZDdp+gO0G+Cuq9XaR9AuKOHbbWRkt8t0kSYbXzErTRn/49EdC3z1KZiuv5AvqF4q/+qtEeUfKeRzE5/K9QDOrDKTYjFJSWlqqlJqekWw06/oFzaY0nkrYiI84T5teitc8olUKo/5pTH2WchX34JgfG4zccvvMQ/e4SlvmtWhZNRGbg1NmrKs/vaVm4Mkr2LR2ZuvkHc3kIfIXh+c8uotb9ldKhE4IAZhXHqoKeOi88vK8MLFm+dkZ/YLZKdHpJUyuqml8/f+enZXRRhYxU3qLeeLO/YsqXb3bn9hxiwlff7xuju2g8+m/ge6LO+JvyWYRmSRSwI1BjAbgAPxug6gBGHcJGNNSTCazSpKcZpKeYXO31+BuKIhs2A/HyIxbgNitw90fDyJyFhfHHNYT6Bvsc4SoeeM87fyN/tn4TLMZA+bOWdSl3+AJi54rbplZNEjkx/TutGibzOPPZ/VbMlFuR/q8qb3DMK7TzDSl3vJx9BR3lNVbNoGmayQ8r0YGg9liNEpY0p7F3euDEpClp2G2Q2FJhfG2oCVFjRetrIhsguecn2u2qGZAZWp+iWeRUHvHHQ3Nxo8WR/KV7Ugz6OgKwCaP/xVZUHFAqxUsFth6q43anro9HhTUzwAQCG4JUGyBYkHAsUJHjaUiY84Ub/C3CyStRxdHSkp2dR/8LddjVmDvmK7S7dKdS+TZyn5MxB9yF/kvaP7mM1oBWSxWm+VpGARWrIz6FC5CPBsxFp4Z8SCnHqXKBVo0Cwb3LB0xpRcbsU81/0XoCRhxVHc2It5ExxuJzpMuMJ4LIKuVEDLrXC53ktEGazwd1BmNatd5NjrPUEGNS+LTecVDtvFqsS1OmMOZnJzcFH/Ow+7qbo6UtKzeffgvGh6rLNLMUr35r5rOsanAPpcAvE/AXGgOvMEBG7UsSMB7tDQBnqSV7A7eCpsNYhfmaaUTntdyOjo7LaBod5idloIl5nNxQwhf1Iva6icxVwsriJoFQNkfWfevHT8Pn7B9ifzSwrN373iaPIZL5YuW+cMmzOGuh8YvXy3/pfDMafg7fhTM0YG6B5watUrSm4w8RqBZOSy8Xi04XbyR7pcdYNWy3oKxXnWWTovOglL2eP24kTQS6iBHgHRbHc5yeotWhWGWGzfdoXVrjKs3vr5gsUNluHvl8nS9Zfl8/B2+lru0ZffQ19xfob/6VbbhBoZ+X9OuNycimjbqPHkW5mdGFQGzUdIatJyKt1jhkxbpVRRatAAEhRaK7mXEOzZ2a5atnI5ygBSdDOwm3lDsrawYXiB/uHJvx6JDK+Qv2i87rxrJD76d+4885NW78Jch4UQdta/hP0hv7l3hikWkGYzgu530Jk+w7wKrtc7xhHuV1ZhODmjVgHAarSTR/6u6Uhk9qvScKvH9fjvHZRcsGBnkybbR2zuuX/LCLfpQqWj3iX3YlYB2byn3KutDuHKrPjikVmu0HHeTPrwsLLgt5l4MjlxQmCVceWHJ+i7bR2yjfeTw87mPhV8BX5MCIErQayWDUdKjotfjnckUGbaUXXl5uZz88vL8AePHD+BfqyguLh84obb2NnoOf4C+7md9pQY0GiIBsTMYkXgWd0VVCd0xK6Lfrhi0uPsHjhs3kHbJz584qHbCwPLi4gpGR8rgLG1lsQmdAwatzoHEWJYzeobUNCk1TXSmPseQwQhUU6FjkUo/lU2uPnCjISou1Zidk9LyJwVrJ663L7XtnHng6IZV+Fs8Rr997abVqzUT5zz7xLGL2v/cMB8TcEUtCGQ8zMeKlflYrTAfSdIr85H+53xKG/2NYua9cjPXZdWGowdm7bAtta+fWBuclJ+Gv/2P9uKx08/NmahZvXrT2u16+QC1A09Be/hq/rhJROn/Zjmp4ftY9t2jo+d8Lvqer+XPIhHlBMyEFwUOiD9Hq1RxIpz3Iv9rvsSb9WyvGnuxn6+9Xz4tn70f73nge2Jo+IW8qtCNxP6gM55eJHPQn0Bu0R+7N+bOPiBPuB93wz3v/568Cv0ZFD6RzJ+k9fxorfaAiaax0tIa65x6w1CB2055c2O0jx24guQtLfeTk5P+wX09UT7Kv0irBfyY2E9mwKwiBI4jj/kNQ7G4KYi3o6q4iBpKqKKVCbhzkVoE/MlI/UQ4Dy34Ou4g49OOJ6BrXsAcw9/XGtsDxz04axZfh3vBA335t8l8oT99PqChEEFkcxDtQBExid4MlHrI/NAHXC7/9jJl3U/xp4kWxhDoOQHGAEdWlISEcSL4YfXbJfzUiqu/8qdtmKQq9BuP4k9zJ6PtkSBQjwmJCjRN28NKrXau/69XV/Cn/0qVQzakrFGezB0MPwFztkbWSFDRDQuUJzM3ZXhggHyNLAhPaVwjQZuDZGeTNS4I/YPLlq9F1nhenkyM4eUwx6T4OcbGiZ/gSZigPDk6wSZto/C5oa0CnPMAHHlyFDgcvg4vb/Gt4GkJ5QUsAsZAh+CQEpUai7yd3nhUKZ6B8VFJkjfXXO53cm+N14+Hf3yr9967/tJ778FcrpOxkf7cdO2IEAAX8xxR+mCXP9CcNaXtKE1Fw7iP8Xv/naZm34KmnowjqZSmQl/3R/uK0lQRNenrFgR1WCI9PYUeJklYBshkBPSSKAJo1SoRWAac3SuRW5XoyfWA3u63+0mSvHvRrEUPT/3iC3RjHwjaMsgKggTbc8WX0Af22r3AuTwkCXrAt+FtX3wxNdLHEZLEUa02P2DVIE6QYCZEp4duNKKophtdGdUXK83OiDCq9BaZFfRIO81YsmTq4sW0zxbYSg7gewE85tMURTlKj+LR80BoCzcTWzfCs82BXhwEeqEHDLHxQC6I1mDU8AhIBpLg9MaTjEaWletXwv/9BsyNX3y/fZl5UL+BA83LXMf4k5vuqOrSpWreBuV8EUHH+DJBJYFMAtgHAEa40oRq0Ci0BfEt4e1e9Bj6BAl1VBUrGj5r9ojhRbEDSIMmySVBRyMjKU7fzi8mg0UtwMuJhgTaAW23iKLLrTZuChrV6WrORNRUllQTYt8ULCJ9yAzyMeGNpIhUsS/LyEFygahIwOHuBsAtGD5L0S2ite4SMiAoDElKKBW4csbMFbQO3YJo4TmhU+2sWbXB6TMGN9b+w/hJeSBxwicz5Q8qULSRThAsVhUHE+V2MkGtKDZeNBELu/j1R8p6lBNnVa9Jk/t3Wx3oX9y8rK08M3nCwE4rm2Ut6ZDf0sX8ZWHvrggPIjcqCrjVGodT40xKdhgMAuybAfbPujmophvoK7hxC1tw3kwDHFZqm0vjIntJuPwBNb297jSbdoa2qF9V4YCaHp7sPM1M01j+ZHbzbGtWYNSYMvhQ1O3O6cq9XyrMwQr4IygRpSo1o1FapCaiqNOrOIHbMFQrbEdxTrLOOJsZKwLoYa94/dWn5bflMvrKn7T9mPol/YF1hr/E47kkogMcTQvoMNLpVAajDj8raACtk674ompBcUsSl8KDSElfpBr8vpKa1ksHvpVfzX3jXdepTd72Eqyzwv7YSHNyVniTnTuHBok8L6g4LRL1OpVW4Hi1RBQmHpezlxK3XCm3PLfcWe6UyNnBf/01+Pp19kpWRz/BK8PTDPQU6D5Pw/4noa6BVA47jDYayK/mBUFNjFhIThFBFyJuTucGgelUUMdzMGDRTQP5o9BipiDcGAhfHovk55Kvr3ju5RVySNOjb/fu/Xqs9PmTXT6uPbdQ5rAcWmtd3r9bMNit//I32gRHlaZ7GY4i/A3gTxhkhXJGz2FqIHlLTzOJTYV9p4BX8Mo3wlSxhEhncyRRI4twpvGjjlAJbvMXvp1rP3gwmaDEyuNy/BHZBTp3LuoVsAGdzbAlJyXpQCHMa6bLIE5n6llqgUh2Pk2Vb6ShXwC0oBPHVw+qvNH6FJe/Mna5kCA9puM0juzau7lun3uqaUztKU/b+bcN9W9Zv3Czdbp9d/8+Ze1rFtSWcBem3jFoiqNt5dys5ukZKWW9KydNGzzWMMlfluezODxlA+gakkDWPQU6mBZVBdwi8G8NyFS00rUWU1ItaeBNJTzNdDEGKBq/lpDsObaDWpAp2S4STApeenkVFv5ce/aJ9X9hNcjZreSX8Ho8W34f58mbZVYTJSpnW0RuBYPn7TDEYCbvuALAHTAWJSZvFvljSo6HeSaTwbvkx/HnQpc1Ce0orzIgIhAMKyA8jyXa2FJZFD2b0fZmv9JD9S7y+Ro8pmkfeoEOfrMu/P6b9MHtW8Md///sA9euIT829vGqAgMOxBAqMdLj2qjoNcNKSzkFGq4ROjMYzIF2Q8hMpR3fCLuEdtQ8TIbI7ul4AZnZ8Gd8OwlkagPICEiRoESAYuKklSOhFBSGPtZOh07wBvl2MlNeCP3ky7XkSHgG6Az5AQsHHB7Ol0ilM5XA1QFvLPIlveZLcOegdyzUjOAsJ0c+ffb9xzZv2Cp/jV3nzzMa04J/jxwQU5h8R6GJYU0IZkbqRCGBNCrziiR5Zcyf/gj3zZWfngv9JINI6Ga6sxUVBKwgI6qtZo1aY7NbVCqjYKVatO+KL7LOOJYV08g9sU/4c6ab4/8kqugxTZ3yreXyQS47rOhOJkIlFJ4TQSRW8ZhC1B8FgqUyGr/HQODHi/s9OHvUqNnyQew+fvxmfVG1jgPhBdG+OPHmfeVKXqufy6Y9PdhPPnj8OHYrfV2SB+FPw39BX7DPnMADokgq6BJ6BBkz6g0cgadgl5z27FL86fHj8lei0lnTPoCR0FQpKlgiT2dzYx9CaXku9CF/dfz4o8rioMFGuZZLDb/NZBzgeFEZx06MaljRFV8ctgm3kFO41Pk1NfPn9e03d1Tr5s3btGnevPW3fafPqKmZPr2meXl58+aVlcqaN2Ijp+c6JOomFBfj9Qs1proJflT+6OpJbMSOVPlTG+KALxu551hbLUiP5khrrVatUulUhArmPgA/TjSOKX152Cs3lvYod43vN9I7vd/8Cvp/PtI/7C6luFRQBxWoafe0+gDrnVBNCPvZq/vkVfmjEH3BRhtOT5W/VV7pusPfyFO5J8LzAcJwcmx2O3TusqiRXQDVxA9YE5t3VFgSG2UlKirha/kDqruml5eph2pb9gVJqbpz2jjzMPM4eSrIR+0qJ0xqC+/zdsynegHexl1iMrBEve+pSxdCVFLaOpTjA7ywdSgPkiitvHwlgbnSZMdU/hVeeOEFPnT1asPOq1cpPdoLMnBxlAdQeUuU2MGJnXfGmIF6kmL52gq8S+j7Dq5p2g7OHdA/Rd2Nb0eZOd6Ld62QrwlX5Mfeoe2AbhWH74/QTeYfxt/YjuaILZYnr8A2uRbX3NAOA7UEzfWGedLkKDCeDbRe+a135McAJ7+Hdh9DO4liP9AERtV4LMbTBn/jqKV+8nHIsA5/up4OfPkyw+tv5cHkX9GxOSDgosR0u7g5O/3U7erbzdykkCp4aa0ir/SEdivQPqCFLQI2FWUREuEYSdFosUoFSmfRlRghjKQhYE53gsfppdgnecgKedCTM999d+aT+PjpX3GyASf/SvsONYi6cG/Jq8yJnhZM10SPWiOuMSuA/OOvV1eIOsUKgOWd0O5L1s5+hqF/fCtfVP2Xd4L6L+oabSPyaf4k7in8DdbSLGBRq4BPAtMRsajh1XUisyolsQPkj2M3UeuS1Y97MuvSt1f4F20PPmjD1FCFGzoKDWGTpKKx8wFD5NzYBH0dnB1UdNGf9E/fxf9xcuQutzg5QkOTk0PX8D3/NrYwm5KxnnC8ospif4ShYQs1tCjGJBx6SPRyA8Rj7FkO81Sb9EWeBQ4Veoh/UPSuWKHA5kN+M84CvUSPKgJejVZrAB5o0PB1khEVIY6+VKE+aBk6iC6gH5GKKaY+ylFx7ELcnKAHz99vnKQb26sHCI+WPfzmjfNad+/aduGdlNbcx7+DhgjLmT5OVWAc2z1KsPz2IfX8OydOMH1K/oZ/ATuERYxWpAZ0iEggg6soI9kBTLhxu5jfCcV9+5wjob8d4184C39gXU7hcviSVIAslGIajEYRaTSiaKWmCb2RcQ/TS5E1KPYeopiAgYEwA7C3tB3+2J/frUv6kMnf9x06s3NLcXl6pmts2s7WA7W++SQN6HIFyMKXxDFR/mQRgUMBgzKq7UThT40wst6CP126gT0JR2/Cnzh5GeDwCuFzxgOaBayMB3BASQhjAnUi028VNAbh1RdvEIuwAXnZB1flJ0L0BdTKJnwg8YxgeihBdCAqKuLXifjmZ8QKB10xm0658m3EaooN9JAw3Apf5utQK+V+8zQCPATyU0X320ebmv2tIgZTxuOC8Oz9Ed6QHNAKPMhwIHMobXwU1X0Knnhp7QWzv2zWrH8q7eX6SB8RGD3AYFQQsDE+LGrVWo4wRtwUSI1KVDYsw+5hrzhLfuLqB8CK4ZU/+ffUz2z0R+n/Q/4UzhLHwVkxo+YBm9FkIhotT7TEoiFEMhkk1j/se6VyNhuRK/GIEMCuhGOSWs+fih4UfBKOAD2XT8C5fArGSg/oI/YoCdVpebYVV+Lw3wzKnlfJ3+lth+fttUwyjunRa6xukvGA8NT6Re26dG89byPbj73kOzSOybfOgFotIU3cDRVmcYAkdj81Pidv0YjB5LsHJm9qv27pP5q0T2Z3qmq1Ju5+CkdRPSYDj2N9CFdu2QfH+oi7n2rsI3o/NWLwiEV5OcKVfyxdF9g68QHWx2/kG/SicFnpQ1SDmAUrIeqmfdhYsVxvqf/FgTWFE8URzwlZ21dmd80/8Cb0MVSehE6E6xp5EEhsijk5RrWtjAdVU0P0pIghGof7yJPRvcwOTXkQMKFYK6XyExO8pJNxFmgcrpJHosPh04DZKQEtoYY/FVP1FJsmG9DHzoRiyzw847ffZsgj58yaDW1HQNvnWFugMETEtDFI4lRNjDVmh1Fifmd2L2vdc/YsJVeSvJZ/ES8Q18F8Yc9BludBW8M76JlSxlUcWICDLNgc2s/9Ak9XUlqN2vEES/9zrxs1HyzdcBcZvk+uRSPDbwEOW5/QiMBXEJX9FQDTFO7xBuqRUfu0XBtnoMbhXtDHqfADyvqhD0TJAgf8O2Japmk2KxWXcsUOfIoZp+VaZp3G4d7Qvp61B/mWo+0FQYUpeYvYt3HskDojtul6Zpq+SC3TONwT2j8efgYoCshBGlaWi3ahU+zS5FnQRJKilmkcn5HJGmebflwxTctvR0zTsC+X5XdxZXgs49GUNpJEfl5JFVP5XeXcmukc0F4aN3RGRFot0DLElh+BZHmcp93j8lf+gb7O8/fKnyu+coq8Qn178KH4PoiqSR+NaY4en9/ZN9Avf7VX/mWH5agJ59EsG+Fww+/yhdC58DIQe/4d+glF+DT06wgbGd0G7I7waVAZOUVIvTmblmsZm6Y8FNZ26QYdz06eZTpeVNBgPTj/r3noDSoeDu+WK9GY8AHA57SAIUIzeKQ2qTkYZ/gVfwylnVGM9o8pzLtjxOAXrtTeUTRuyP3QRw+5E3qC1lVFrQMZJrPZaDDwasSrid2s2xY0B/SmbmazZOSkjTHTthItip1+cyNi2KKbRf3NpXK/lIafkH+o9BRnb2/bLSW1/ZTcESNk+Sl+jDgoL597Yhzpz87BQFqXAzhPJtMAkaCj6VATzOjYGYX1DTb049SEXtsp3oTeZVVO1IQO/Z+DfegIdCYOH+NYdcc1a2CfR1B6Au8LojqJYitVCbiOHqeIhBC76SlluhdesF5OX8f9ItdevoxrGO7vl7fgseElyI1aBuzIYNDrRZCgJVFMMms0xGXT085AfvJFzlTkWNFrNbPiV+ZXfMlib7BeV+9OI4aNbtGivP2w9uUtWoweNmK2/F1O6fKpvTr26Ny5R6eeU5fTsZ+E+XcODwU8ALkQ5BwQc1S01q2I6wAfEtZgqVSEnOjd8Pgrn0z8CIQcufZH+1132SO6BfTXnvUHmn9EtwDlQtSIXB2vbtphgmpR7sftQbX4aOInV+SptMcfKd+XZ+Os8FzFxg/yOBXHge9r+Kan4b9I3fLsRqkbNe2TLhbEfC2I+MzSFt+n/daixJ0xSQLLe2DNtwHtitd9LCpUZ1OMBkkJVgPrzXSf/bcyGtTeoPpQ3Ud+BlvCrW9FK5nuIz8T0X3kSdwA+buo7kM94f2Juo88SdF9OKDBtUCD9zHaBZChdkMmdNaxERKELCFiNVQIM/35OzMasvntQT/j23DoRl2QklifLxEe5f8v8Pi5CTiwfAhb8Eig5BFYNNUDR4Y6cOexZTODxcM4hRuEd9/iWW7Q9Vr+QZyyhK0BhT/nEPlMeZbj6a3Pa8qzapwLUnjD2LFkP1nRMGY0OUCf/zL8T5wufBV9nsI59rwX43R58Fb8oPDVn3+IGkZfjsjVaFj4MuAgtbloNIB8BnrOX2+EDEm4/R4evfyWjzTefsfTH+A2AqJaAo/rmEkkoqD44i0ieEGCRYQLdwI690z4KtvzpAAcKwl6kBSbypXG9jS8kZR67c/I6/D8kU9B8/nyV089pez3YXknHhFeAfsN9IuVGEJOp1bnMsMHHadW26iCCUt6LULB6FuEflmVJK1M1/QyJ0olfKzB3KO8zbA25T3MY/RDqmdWZlSXVY/Uy3/vQWlXj+ohQ/15Q6opHLP52ejvYjaTR5wCp9Ly9M5Op6FqYNMLO9xYPhZGjruz+3vtqpWDVq6qXbVq0Cr+5YFrVvdfvXrg6lX9Vyl62938VDRJXI9clKbZ9HrerKIVHd02ldkk8AxQldHeY8K2AUulNIEIu4Aqt1PGk8ZNKqrpX1ic6k0dOad5S3gTNMVVWZreYk6+s7i0TWanan0vVVahy1faGs5j6ISo4wZKLaPnkRb9JUjFi3W4kVLFLkw99mx6oE/wD1I0FnUTJpyfMEHZn1P88fCPwvMg84LsShNawBahOgKaU1KceE9AySCle9bPvyg8L/+mw2qajwtZ+OO4mrV1BzQCu1RJbEolZjvxllpx9cX564XnjfK/dVjHxj0K+udw4RyNkw6YLVRHd5hAcha0WmudmnZxxQcH0B+R2hlvjRIDSyMt2JDftX377CK/enzqI4XdO7XPGmqcYJzEP52enV5SiTl4m7ZuIdunfTxB4/8f9LHxTUV0ROSH+Ku4v/AZrFcNZ9MXcEB7EJNFjV4t6kWDVpI0FABUyvVHhNxGE4DSPQNGRLo7ee6OlfKDu/DiXcJnRvm6DqvkaydOMKMODsMxQntAd9JRGqATtVo9UdXpoOtGMdQZ523rb2d3GTyFOZtWNXic4kztPduYPvMW6DOZEZso6FICKFNSHTVpxlsobpQ/+Lci8gcn6+E4/xReGsMzjsccVgl8HeMWiXQfOqE/sp581pBKPrs2efK5yZOBjnSFtZxn8hKjI3AseOgiZpuN0pGoucK/Zs3PigwlH6ZyVLgU2r+aYEsWCOA5BbMyOmh0zAb9KjNBB6kFmvEa/g58m/AnSkLDAy2QLklncOnd7qQkgKWFt1itII8la+HkGojO7RZMDoegoyTJUidEEdBXxFDQT4tomyuj5yFS9zFSNQwmrlAompoPCIZDQU1WLr4mL3WslfGpdn3ajm6b72acamDrvm1HCy7rQmBWLaeWTbUt3DG/eFo5w7F7+DF4ksSxGokZqEMgLT0lJc3tVtsdDjgjHkGvt1tArbXD39T0JHeEwBRF55kgBN5cpmAykBC5JzhQ0LdX5/Ryn3qitmW/qsJ+PTullflUk83j5RP19fVCeUYuYGpweJkn11PuWz7lnRMn8G+AoZx8kH8OzxRPwzyLUdeAx5OZqW5RpEzSl5aTU5RZ4HZnZsJ0HWqYr3oHTTHnMykwhWmyT7FrHp/5v0yV3PS3x2418YG3+g/+uSaLwaomv6A48yPgnTn8pCKjUg8PNRBUQUMkicdqUQF31GIVmbYgAfPLLbf7S7F51x+7dv3xx6m6ulOPzp2r2EBq0UnQ2USqU4vUfZTnJIHeB4MQEKUREatqqbcc9OrWc0+eXCzX/rB58w/IFXJAk2/Z/Yua5UOktcWbo1LUFnVGPVFfFESj0SQ0Cy1Ay9F6tBXtRvvRIXQ/bhO4f0+3++47Mnvu5BUrpq/pcrjftm2DdpXdeWerTdLBFgsX+pY6xoxJmiAeMAwZYhmR1q5dZoecfNK7d36HEQcmLD24adfhNXP1vfZ2P6LFfZCmD+l1pNcD2r33La6rOTpuw4aJW4bt2DHqnsCqVZ3W5d1+e+H8jKlTs2aaBgywDcbdXRUVKW1altQd3XLPuvkzB3dvU1LSpvvgmfPX3bPlaJ22x73V9913sPcR3T6JdO2q4ntQ/k+R4CVf5IMSER/905h80P/fX8x+00WFGjmjdYVvDLn7H5+j8SvMtkHlWOrMmW3zZpaW+H25kXdr5N0ZeceRd6nJd+pxBzSV2Vrw/3i26ffsJmNFx86G+VCBVKAym5/7dtonuHfoHHV14DpOmyZvLamoKNlZUllZ8md5WUVpFv0qg4hRXvZIRWlpBTeovKysvGHVJ9Nwb36tfOqTaQ3qMvjD3Ulfd5VWVJSGHiytKCv30u/4FdpQDtI2f9Lmu+hv5S3TppEsOmLoGfnUtE/4lR9OmzatYQ6u3g7PFcKP/Cb08wV8wLvgwxD4EJpNB7/+Ie7+V8m0D7n3yvytQu1KS8v3lJRUchmRp0Ph8vLSL+FB+a2Kksp8+G/os2HOtGm4+4eKrHU7vwRtFD3Re3IOlFAk0XtykYvek8fdIij35BvpNbkwP3JPDrI1Px8NYz729jPUHRQZFGfQmASQYGkbdnPXembffgdniWuYfbss4DYbDFRVtIDGaOG1WiMyGLcMlZDhEMgXvmh6kEYhs/JGYzS1+SRokWn14pqoIin3Ue56QKaVO6C/h39nnnNOLfWVQ7woNsq0BKulG2TaiKvbrcRa+e54sRbgLA9CG5k/ArUDKj4NiS4NMZ7vVDwaNsY7NCh7FeuDaovMpSHRo0GhoLSHxn2KujMAfL+WB+GHWXs96hbw6HVqtUTvU5GWU0mSEWZjgP4kNU/LOemUbiupY43PH48HloRs4JGxIu4cmA7JvajMOjK0fIy5duDwUcCT4QxPFB0MsMSguCDfQgcbdrOgDox+5+/Hp4TxsF8O6suMdGqydSgVcAsil3lWZqNTvPN+r8jNrajMya0QROWd+R2H2wMsz4dfQAbUPuAxUC6i44lOr1aJGk7DGbGWqJFOVOuIVisJBmqprCyKpW5g/MVZGTPcwt47o3iQ689Y7d40vGPP6g4jNrjXqPu/4u+ZvbDZsqXNFmT3Kt1E5ZELzAZ0DllZVcQ2gWTBmJOTlKTJQMim0RR6U1P1zZxOWj/cGPWC8MVGjjNHVUb8TnJjdkknXbcQV2pPiLNT4s6TqoN+f7DPxEnVQ3y+IX0mhi61LSxs3bqwsC3+Nvrpj+rx3buPr64e363b+Gp/Gfy6bZk/8g5wq+BvQ5fEkojkytNrVBUvSZRaXIm7doI9IN5yj9UvXRo5KxBG8CIsl788hZNOKbjcX64V1oRfgT1MDxi0IA6AEsmpNgfZgfBdKWhECYHzZBA/jXjOKhfWfBN6I3T1m9UjcI9r13DPEWXyRjxnxdy5K1if/AVhjeiDPrMCJi3rEg5JgHVLox+YZ4evUY36bx2LvsaeWd9CKtkvUFuNPaCmAQqY2xwEeTmKcsyfe//1J/geQuoytr53yf7wwMbnWXzCzZ6X32XP8y8Iq4UwSCM5AZMdDqXWYSVEKxkMqE5LVZTKJqobCwbMzopQOqrDw0LKhdXN69fslr+Rv9404va01c2fXxR8bSs2Ht9TKYTvvXvQwAHDdhzJaz7oMWVNMOYasQzgRS3nWq0oSTqiZma5eKsczoFReNARPRlWARSI09euyU+MWP0t15Ir+pZ/gcIIz5E3xvaVXAVZj9EokRpoeYleNokJ90U+JuHRDDbk6q6GJPIliHdT51IadRZ/iFfxvyIvKkKjAmaD0WgjzTJUKputOSEtxXwa1KQJekSDaEBms1bxijXj4lOuLJTFfFhTEQsM9DVJPVgZQylzo3TIjk0VjuYBKvOwxLyxXK406jOX5Y6QmCF70swZe44e6923by+pLgNLd25MybM6/IVdWgt80YJAh0lt1ywZ0x5/uGDy/KWE5I+sblWle33VEvlsZaXQR9ur96AeIwPT2rTjSJ++VR1hrc/AWnvAWq2gTQUDBgC/zZoE3/T65CREF2oIJlEnejFJTNKYTM72GrZaEy5GGkTYZw310E2sjpawTrrISF3iaKYsf4bZnquwyBcmjasZZZ6Svm/W0ePH78WdlmpHDw/eJpDeqzZ18GcMDV66dO4VeYp59ILpC6aDznkRf4vaiojpnC3O0CJ6PK8S2qtxSxY5SwMKlEhhXyQHexxdp7oRTKnNggULhLULFjSM5a6HBIDBKYBBJ4CBGjDfF1ADzzUJgkPSR9YqwVo5ZGWfuca1NuKmiaY8ofnx4m9kcCe5fs9DuMeJvXVDJ08dNWLC9JFkonz7C5fxXS++dGDztr277tkOesn7MHYu/wWMXBnQ61X0VsNudxh0KjtbkzkS0GmGcXVKzFwkqhM3Gp5IY/GWaJRwTqn5kQ7AqRbyt/Nc/vQBi6bzX8gp0wcunIOfCj1wZEWvTss24QYY/zUYP4f/DTlRl4DFarFQQ55O5xKsglVtNNojIDACCNSw+O4sTrjpdse59cFkTIk7HXXDPvVUh0HaxYa7591z7NDe2dttSx3rxwwiU+V3uvdSTVt9+eL51+ZP1dy5jp6/SzCnVrDHtE5zz4DBkWo0AuaJohdkIVt7I4DBCNurQhkR53TqLZ4UcU0vasxaUmWpjAMTZQeRQhWsPGxprlKnJyehLOwz3hkDNqzAhgEzvBgv5O8Q5fV9h08cMeK2Yf258T2qnn8Jbw50dlbhNg1rx1fk98Xk0Ppd++/euIHZJT7F3+LmbN6VAY1Kcpgkk9nstJzFvlMOojKfj0bZs4kWxwJ0qxL28sYQe5im9EBcZP2iG4LqeYf8Ewuox7IL5vA14DLN5mxxZIOKnppiUKUAXuV4eAvPqJMLplRcbzcY1NqzuOXjqUgdCWOuoiQpEp0Rm1PkxobEJTCJK65Tljjb1hXV1cMWkjkClzO+14DRNq7jvpnjF1T0qR4K8/p8yuCFc+Qu3OAjo7zVHbv03LpsE13DlMHz5spdqE4NZ/shFpNfFFALFguwZKvaAOdACU8vBnm1MSa/Mv4Ikhsj8h/+XwH5OFyLP0ZPC5uRDeQfndZoVAEtsQMJFFkQhlYt0ZBqDlkST/5LcfCJ3TTekPbm6dbttw8cktVv3brMgqTm+CfzCRwafvz4cDm9vBB4sfwgwGMwnHs1rNVIfY04muSPcJxGxdHoAYHGbrHogQTtgl3G4Ugq5s5b5d9XHG5psJ1ZAeu7LhvvL+nIeRT77xPQf59InEISdM1LWMMLlMHCUEQnaXgQB24WqKCY6n3MYq4sLy5O4eX/GaZA7cd/8g9xZcy2Qf1blDhFoY56McXbnq3US4T8Of3qx/xDNqxPlRtYPm+QSx8Pz1dsgswOK5I6RG2CMfcSQbG2Pg4t19nkX1MxHw6jn6DdG+HlJomIuAwpObXvitbV5eyROuDX+Aq+GjhdGpoQaKdHacmSaLXZxGTEp2ekJPcLpqS4CLKarKOsM6111metoppYrS6XqSbochBNTTBdWiZtloDrEJoOqGh4LLUczYplbhLIrKRNRU3KgVLayHkzEU1QugJzv526lv6sqW7uge3b97NS5vMuLvg9jPDBei4tUv576KSL//jotcnTdKP2B3HGy1Rj5OJqrCejiYEqs0USk11wYFyihU9Jdbv6Bd1u4gDSbDSnm5eZN5t5NTGb44qvm6SZUp30hgSCs1IoInExs262mltUZKeG71tWZQ89Xn+zwuyh1bCOcBiPkneCZt3KBLIa87n9B3+S+1H4A/bfkxgDrHt8qLAdJUYcMQzC/+jz4kP8SQ/OypY/Ychczp8ku8T2Edsa4L/ipKTWazRqRIwGlVaj3RJUa4T4fmnkn69pxrfGUcojxn1OXfbitp2bQ4e20iFnZMs7LYobB+AbTb9wRehiyUFZCJklUiHnhGuQ7RRnItxZObveYOalbFxQiqpK2Vp/wke5f3D0Hi474IzEQ+4dasRVeAY+iK/iHzEIr0XDG6O9qfL103f4KC6Q3wmHw1ehyQtCF1MOyhvNxgv9BuPl1GMDwcaz4WdP2VO60ffH1ZZuZ8Of1BuNCMH4BcoMlNxwk4TOQCPMaEjAbtbpQNTlqUu6CiEtr7VYDWYAUMAVNBgEiRsZrJHwvdJjEidJaoHwQKerWJb44bMUtClIqNIVV9YsEgZDp8+ASR6VB1+4gB946vrdsHfcjNBWoXPoFa7sr6d5FN1HgCeV3OvY+gqXNcIzbn0Wa2R9RljflcT1UfjAGTkhDIH2vi6N8IH9cMF+hB6ud7hF1LgfCjweBXioQCMPBhwGtVqr0wnUsKtSiRhznNGkNVCAOINaXiQBFrdKqpjQCWootiCWibVo+HCl1l4kENoXg0Uk24LXzJI4RWDR+xn5wOX//HH5el8Ki26hs1w3LhS6nwvKT8dwmgu/zvL4DQHMykdjAkm5eXnZ+dmeNLeodWtJst2jNhIPKSjMzafzswdzic7lUicnJY8MapMsyDIyiPi48gewWf74hEWN9pToSfchmouUljzwsCvNiGDrpIfA58zhSkssZcoCuI2fYeuxe0a2uCQXL55/YMeOe+cvlosvtRh5z7Gln4fegUUJQ+Sz8s+vyhcmaPd9MlQ+997PP35wLjTsk33a8bj9lZPYskO+L7ZU2PedsG/DxfaWHDIZzpFIKn9FyH2acBj+nQ1/Wp/k0ot030pLEf2JO3udLSI9e/D9MMMd+j2b8STomh8KeyuwekYYsxiAkUGOUCyOr5HEynDigxfIolAnofM+ihc6aPssa2tA3QO51KGW14A6LRKTMVXERhHr4TNHtDz8UkvD2gHcFhYj6fTTHKogWgFJHZ6YTMlfCihgxwYOe3BOrg7/8zf8WegoqSqSPyAl8kv+rK18/fXq7fx5zZMLQklEv3JOdF1j2Lry2Dq7w/eV7Hvb2Lrz2feCm+TbHhyoNFEPbcB8PinZ7RoZLHKPdB90P+rmje7N8HbB/bH7R3fYLTmJ201zcY8MqnliHRkk1qZprGcVxEfD3jQJNwFsiSXh5kPxSbg3yyfjknD3BT6QkIQbD9qzh63nFeojz9ZTGFvfq+w7i62mmWj452FvNKC5JWnUPEbUmQkRnXYIj3uCkKNRE1WEUvmbboGHVo5gdaP8/POX5edbZpWmy89exn++RNZsWfvcoIaFQmcYczmM0ZON2bIJjIsZjNfC9y4wB6qTalFtoFSrApqBeYnX67SAC+naIi1nhJcq7UjtMu2j2o+1UjrRagXMAwryFoxGBjG5KXyj4X/UeYFWUoAfCtS95O6GgeTC1tBY/sF9+67X7ttHCAAM5hbZb5ibj8HniDJXmJk3YAZlmSAWr0gHjBDwgrggGn8kh9sRsvZC6N9CZyDID16vja55JFuzn/U7Fb4fgn51qH8gH1gGVnGcQYMFLdbqDQSkCkAcFQjNqdT3AGhj/KFQKkjAEv3+hFh0SywDjL9UTZfqwTQ531QuKfRv8lXDT/gV2UGmHeay8T8P7ZNHL5YN+9h+9Iqd9XL2HSgA/wD73obtjyr8O/+i0IfGd6FmaFCgRapNNGeLRPLoXUgvIVKQn5xjzhkVtJnTslXZo4KCaosZm1VmlWghIiB+Fct8NzxSvTcxF3IsD4PNgAsw9XdlRRhQayoVwWmQqIcjCNRl2TS7uxnIKP/i/Pc2NDvd7K7352Pxk7TTqZ9g6flj9wi67UcaXj6yXafaeYx7/s6vVn7wwYpv1n+IhRMn5IZPjz4e6vbcocPPcmcfi63xQbbG1mw/ABP5fbAfyTQjojE5WYesDpWABAdJTTHqsG5UMAljm15U6J3fX1nkv5mwQ8sPc0qC0taYWcmUQn0crIFzt3r1s0NbVvn3+ldvPvT5K63wRuz8CZ+Uez7xImnZ8MalU/i03Ocn+Rs5UqOW1lbZDrTHS2uBA4+i3MqoJkTr9vBZ2f+dQTVNitiUJ5VZojzJ0siTTIi77Xec/siROwovyalrVpw4+sDxlavl1EuFdxx5BKcDH3pG/v6cfGYq8KExWHXik6+vffiw/OcY4ETTcPdnsA13jNEccQ3IcYVUjkOTAY+1yBnQc1gn5HCYMwEHYQwIFUT5D8M51qZNpI0l2kZN25j1Wl7VpM1yOKtbhD+Az41hfK4CmlpBYwJc5Fw5zQQjE07gHzz7KJX32bMTlGdr2LM4z5yD2+YVaPi4Z0+xGuz02YkJz7rh2T7uFJ0z7lnGa9mzCq+tSFOeNcGzGpNVYbSRZ1mNIsaX5yp8+ed4vvx5fXqqIk/F+DLwTrZG0FPcwIcHB1omCVqUkWFx2O0galoEC63eajCqvLTQj0nLmXitysSl1gQXue9yc26OKiZML6H8UzHnxVXMbcynxMVlYKbBG5zksNA7OCVLNS2gAKhC5s757bXnPnhz6anmnNP3jG+ASmhddMblFUIXZ6+afywp9Z556xZ8L4cBDVw0wfKaBfNunyy/NuZe+cptbTd7cPFHl7+6+Le3L7N1nQAY36bU3ES9A81SQXl3mL0AFmuuRsgvsObm5ObUBHNzDcTgrgkakDqZ0Fz3jlhlyEhNw8RSELF0Brlexaqi3CFJaThadzeapZvGZvG3ff/hmbWiWP/5v1588+Mdx+XfFkzfvjxwrO/Ge15/8e59eOdLn42YPVh+TzgBz90Xqk29wrUeM3Pv/Q1vFBTvWbv5wCbtNnZOS+XBsEetkBEFAlkGXtLqJBUyGnUqYjbN5dfwXGt1T/VQkAZ4g0GbLCnFp6i/fwI/ZUxKjdOwsx0GyUYk3rJyjMLYqO/Bi2U450W5Z+esC+6A3IxvFZqRccVi38Rdu379CfmDZ3/liyhMZwKuDGQ5VjNAa8uU3IbUDGS1Un1W8GSmZqQDBPkUI3GkIwco4w5HLNN+0yy1SkmN3IjndxngQRpnt1ERBeTWcsZF76noO+bspfu3bD8k/7QHt6mb0Ub+7Ysv5V9++UF+jruG3xu0Y+GE9j/tPvLCWd6mkl9eevDExI/kH7H683M4qR/utmKzQuMejejhuWh4wJetoVl2Cc87PXqzRsxrpvdkejJrgh6PTaJpdpELawlNtEuo4bomKDki/LAoLq/2zbEiO96oWl6aWJCRWRbsGfSNmzb1QmBSze973/1w77wpa76+uONvHeuKtk6qm3fh+zC6tGr2gN7jRo85evfUXVpOv27M6n2Dxg7u2mlgj8GD144dP3R4pPbnTr4a9iETdQh4XOnpBpUqKxXZ7d6s9JTUlJrgBJ5iBeHNZk0q0pzFasYhi/zD42ofWhqz57D0G4DEuUyPYNk5EC4VvbQ0FA+kdd6cOYt37+zaf6kzY82pR54chqvx9G4DZR/JlH+TP1mHF1WPdaV6u40NjN9Ykd4vxd/D6x25Zfg5/CFuI4qb7vxVPiH/yOZ9KlKD24VaBlxmlUqNXGqXO8lss/E1QZtJZ1TbgT9W3azANTbftK51pOJ2fEVrGGPUDcWsr6+hcsbdgAtlwqsgi5phDu0C6XajUXQYaMiPO8lu7Bu024lKZekbVBFtjBYUNW46rkywtShEzeOzYJ/F6knC1kyOeDSYL/vp80++w2/++LGcv3mVEPqnsHzLphUi5xWWcP+UV8ob8BJ8O/eDvLnBic04Xb4mf85/IP8uf4GTgSNRODGaz857q0AGvQDXak1mgx7IlBEJJiFDIDoiCCoVobWKUKNNKNH4EpfBlnqFc+tqBkwfP2LZqZP3yc/hX/GQGeMnz99w8lmuzybKO64BfxxPa7Ogv9gcZsP3fqzGQ5dAjtNlQDaT0WiTXDxNUIoNvM2AAkZLN4Q0LqNdA/sHgn5c/k8/s7clVL+j3mRK+kIgQdhL4PxT0Z7zDypt5Uvze5PHZPUcN6A1fuj8VU2RKq1CDj9NXrw2Lle3SmWqWLnv+l1c++S7s4YsDT1H57cP9nkJwCgNlQeSUzkOOzUakG3TM4xiklgTdNqSHBpsZOhEczo3QShm+oukeU+sdJyT62Wv5n2np8yr21bvLXCntm85dKRAJj/XcVq6XCt8Fup3512PHObmNLzRs4tquW3EuOeb5cgpMKdhALMymJOB1gTkiSQKABRBIkaTTjBKvFIsvUnGXhCYQLvBVFzK9Tv4srefPy5POId77lxffLKEVJ+Su3zKt2oY9STuc2Tt9Eju8AvyHt4Le9MSZPukFGRX5WdlWVyUNSNVsY93uV3uvsHmGWex5omgq7mruSkHaMCZSDE71CjiV7KbwKbFjqwl7XCEgJWXSgJ1UeUV04LI228kFhcWfHHo5ItbD6SE0QjuIzn00Ys/X5cvz5y+cMfcjpRkzNtz/MxgPOb2C8scnHbz7ZPrklRY2rQufcGo0dPMK9Oe29JnQnJaVrsRXUYx6lHeJS1zxEZF/orVgkf92Lod8P0wwJfVdjY49LRInseAHKmOmmCq0WJXAxqqHXG1nRPSaJkTDoTdBPzP0pZWfABO7QeG825+SbrX1rvDnAnyhk7P5DarWeFwTSkh75AToRG9OsNGz1rDXe4WOib/ey++9GeNS79LZ2a5c9F+wMUBfB+Q3NNQccDtBky0UqeFDFqaz2jSJBMgyiKJZqOuKkgkbUq9johAQWUkC72nzHBjJkvwA359fsrBTjxf/8s7mz5f+txDW+Q/W983aNkGjv9Bfrd9dZsquZb88Du2b5V/Pfbm9/I8+YVuPd9m8HpM3sfnAb3NQh0DHpKcadUl67JzOMkiZQJS8pLTmW70etPTgdOlm4wKn1CICTUuR45wYx1VWlo+kjleVPY/ksvJErlF5B7b9VDbu/ZULhjXPqsItr5k8pJzJwfe+dn2WU+2mzWHPCd//X6/KX1bmHPaDOlUOK0P3e5Mf2FGyxkP1j2GK/dW95i9hMFzGK0vA/tsguPbMuB20vAMvVUEOUNrU9tgj43E3SirJahJFJwRS0czGsNkT8NSSS7lHECoy/gy+foXP4URLsQOrmjvjgGdzi0OPvUGzr/7AP7uZ/kX7KZ1m3D2JpFf+rc7fnvjvZflsc+hGE1OgTnReAqXUaXSaonD4XJbgSpbHRrEpAXjjWm3WJrFGI55lADGyAUw3tpvB0Ux7g35zsUVNc7ZFXXzyAkFr0ID1mpWioZ5ddxlZfxI/VFkQ0UBl1qkPMvuMJJ0wpkEs2SMY1hVcRsXY1SsqAUFQWkJB3TGwnf667vPPjiNjfds6N7smdJWXGv5X/LV9z/m7g6Nlf/+3jcrsL96rnxN0RFoLZzdfD/gBRmocyDLpE7neYvgBtqmV/OeTH2KI6VvUOcwpVtEYJ5EtPOM7EbL+9ykMhHMSQJsp6WJLFRsssMiqLzEMD/TjbP43dd/vPeb39551r5wLS45sPPeMw8O7bsTt+dK5R/l9/TyJHy3FnQA3Re4wLMu5fOH5VEmrtMLH8r//OPCx/LHoSf1FGatQG7exNeADjAm0BZznMZssdhtNqsJEY3ocJqNvGmAaZyJjEQzEFcA6jDnRliPQAZEVmLiQSuXaoI6kx0nR8ucOyupnRD+uKoS1V8QAOktXDSTPBwHK00h6+XmyDufwe+ebz3Cn56aWd59yOKBh3HO0/JsXH/+x9AkUolrp8w0rnRP3yd/wCWHuja8B/MeDPCeJbQBXAMZBWk0dq3FSETQzYnL7XDwJiOy6+xwDHQOTTyg/UVNrQXZtMo2MDeRAruF8hnW7efqDy05+Mb3915749Cie++dze04wa0JLf71HU6egndy7/zKrQotfGibwL+i4F4p4N5uoG/NUL9AgRWl5XrUIJXkepJEvT4tN4nPL8jLc2pIljOrJkjv5TiryelI1ZgYv4tKnU0qG1lYRpbKiJxCNabccoclUrtIqR5WGsEN9kBb7OfODOvetedto9P3nT28adwqF+9aPXbjkTP700ff1rNrz6EH8XN7nnjz/PPfJ63JkM999R/54+3zF2zDGX9+iTt61iR9/fK5t87sbmjUqRdFdWo0+XPQk5/gqE5NFeU3622WiAG70RbAzh9rMzehjV1p8249kCnUpA3jX1R3p/wrzn7ggjatXcmRy4043Z3p+YruXmFT9HzoHwt2V8KzbD/YswuVZ5srz+bDswX5zZP00WdB5qVz6AmyQjJoQC3RqEAFas7lceY8Z6ZG4zSTYp+UXRMsSgLFDUkmKUN6THpWEtREKpKK9DZbAcjlWJ/eN6hvWlQQzkFlQUHijtLdZDVkcMyzkmr9nsgXEufHwdRlGrKBe+bypWcm//OnX/9+4rNpMsaHzp7Z+WDdjlVrt21at34bfn10/5OD5u49zufX3VNVUTP0w9de/+xu3A578CI8Y93C2atDL23bvX/Lll27ufvK22zpQ+lVS1jzPFhzAfLDiu1uk1ScZdcWZmTkY6zNkviSUoueltJJDuKMQtBZ8wst8FfIzS3qG8zFtEzZjTUU/fG1XRN91m2cSCsolsPSoqe/sTS1pTQnS/GzsVj9jLrB7/l5o1d/s0t+0+VqVTzKNbnP8Ikud78utx0Y8bL86Z1Xjl+8KowOr5r7+vfcnx/JW5/FuuLhw71tijeWjR3sGz7c16H7ftz6JBl9Yu7uevkD+WN8Wb68aCW95QKKXCUMAR5REUgGcd2sJzqdXm93GLRms95I9BYkNdrxqizxNZMjFZNxTGWVlHswNcCaH91+bKuhyaU5BaUO+YFn5JTX8FycUrxAGJJfvMLpLfSGPonciu3Hb9UMorgvL2JzuQI4ugLRqhfFoRXReyChitrh6O/NkroXpvkt6UlKEdhJerk+yWUkjSeJniOgh91ZXsVKxo/ywt/xx4AX0lqf/QOFqRZtdnamSxQzLSSvmSPdmA5U24i8Ji+nJl4vUhsdycSO7I1Ve/2KmgI4bKlMYE+WSJoGuzdSR41ESVG5F/vMplyPaDbFVIY8fskSf9vDO1/28e65k3ccmbmYZN87PvT0uEPd+hzsy7e6a/A3S/+Uf8Pauruw5voPbza8jO/A2ifPyP+R1zy8H4+WD+57hNLXMljfVr4dao5mBtLMBs7AA7NSq/nmtvx8Z25ystNqszl5Z4uiXDeriJXrSPNS/NUE01IsiLMatSL7vdbI2SMeaHAYE4pgmeMLMcQ+UnuQx2KOQ1tOcmKPCIIeTehuilaSaIupOmApJxNCH8j//mFeakVmh56LF5ZlCVwG1s9YMC/f91OgY0FpecXY0aWZJL3hU1yDJ31l2G295/Qd8g/dOZK8S95w4Su9/LX8vu6QvlPfcYad923Ajg5sPyfA+ukdmAEkDJDsrQbQo4waXuNOkswjgxKPHaOCwJatqOo1f/yiogVmqRzBbrbMVKywxq63ONWr7ym1Zd+79G6sumwt3peOR+OyaGVZ+U15X6Y8lu/XeLtFfVEozoHsbEBJyB9IskfnlJwiWUDUM2EXEEXsQCmNJf1umFQpmwWrmGyNz/enOn8p9PVvP7zywhvrd+/etmXLwU0wqb0pOP1nUIzd8rfyl3/IXyTL48nL77391gdv/eNdwJFZ7H50CMgEFYFUE3E4NWq1k4BAYEUjg1aNVSM6LaJ+ZFDko0VCKptWUMb0Vripu0u52cuVfPw5zvzt2HedHsjdN/HeRw4/2qrFBZxix/rf/8QtjpxoP3fpS+dfPq+R29PatACXMoBLIeoZMDrUQGVQRkaOmjRvwUeqtPEm3uTVefOVb94UVrXS1NQDNdEaKDBVgpQmeuOkcYqyQUWCUqYMkcEthk7dc/y2Msz//Pj3Gc+alt1xcEf5uM217RaMbPXltxNOlSzc033Vqnn55VlWd828E7OxGac9uMcwZPKlj6Yt6eq16DPaje+353Ca44GCVFYn+3mAa1vmYwGylkZFsKTklNLp6SUcj1nyWACxmqgsTYtTV1bGnSRs9hBvKbues+Pl3FF8WrZcIIv4B2WLvPXN0GfsrhpjNcikSaxubCBg4FQqgefVWrWWFo2lADMGBU7g1BoNrglqjOrkmwwZKx2LmeOGMiSfFDrCFRyQ59QTMzkBsvzjTzaMFP6l+Fv/Ef6e/054DeWjHoGsZg5HjtuMkIG4SUGhOb+ZPR/+ZmozU0cGM7EWFq213sD8zP4bs/pSKtGoUQN1ECXqHm0pjdVT8jEiKmG+NruqqnV666zAgBVr0+2rf/p8S2pGwNY8N6MV/GrIFF+ahfuKr94ht90xbprxXtvhk3dg6/gR+3ZO0C7B3z48sE9z+GX3O+vmya/U4q8VmXQhs08tR2qUFTCrBIIEWomE7xdUqag7WdXFyqL4i1MQxa2eUuwnHr6ffO35r0OO/0PZdwBGUW1/z526bdrOzvZNdrPpgSRkUyCULL1DQnVpCb0jHSlKFwUEBERAka5UBV8UERWwICKoD58NG8/efXYfZIfv3ju7m02Cvu9vJNlAsnPOvfe0e875HWB7/ivyG7IuSpNrW5AvRvU+HyJbi9CzoZylEKPDxbJgMdIGh8MpShQN3x5V3UhOJtVvNlmMkiwYTYLoMIkOh2iiKI/HVh3x0LFSJdxLh13cWL9io7GeMm54BxLBwEja2hYwWSAzC2QB3fbiazLaSs+GWuto2Ssfj9eq24LL1lytsC34Z4+HJoza12fWhKsbT4KUB8Ab2oNa1ZitXc8C+UTgxiJgv2Oa9h38snDM+DlTN87/VhuB+LJpg2g38y/oG1SGs628YDByJotIywxDEEZBplW70cCZBItoMoi81cAbeMqqI+a2ujkfsSY/qOoybBSHrq+YrIxM9InMKKMJ2p3/fFkz7cEu4I7mXbUVXcH0y9q+I+BB8NykDzStFHi+eW3j0fWn5s04ueEJYDg88MWonrceCOVjOpTHHEhnlslIKoo1YDVmud0eowfGGSTjthqpQFpNJMA4BEaA7gyjxMc/Si/i8BcXyySl5uNmnUnLikXejS7+XCCEh7kHSgJ4OjRLpd7Vzj+n99bVeysqu3fY07bbfXv6P7EtepasWL+ICtse6TX0rfepg3XjH1i9bBX1RN3QjauAh9p73fXClYmbdjwduhvPh76FHg3lvBnRN5yVHvQQRDOhWdBmMBiDxub5qje1mSEo0tmp2ZURZ6pdECsjgicpv/o3bIAk4tkEzfos+mBjBsmTLdqH+x78+LPoZ2Tq9pUgOLbzLYMVMvvWgXPHHWjRvkNvujzab/vCM/vI6uvvffbOmjV7lkf61IyZNOTIP8l/on85cICchfZlGq5TGAKtYUU4QNtMCBHHbaM8XgdZHXHQooxNNSqwEKwwfq6IG6DGUxiRGQqm6eTpk6/rAZMc5LhWnZ69+/beBzqdPv3wgVc/O32k6/h8em2x9taWvQV55Pprp0jnoF/fu/JTViaiaV2MJi/U3X4r5yIIr5fnKF8KjSZCQjXrpk2ESewXMdGJockJbz6ZpEAMsgfdkDj0GdY2PZEH/52a0/Ifq848AVzdwuVt5xRMrrnnSC2ZM7Ty2CVQBrKlR9TN2rWZtxY/ej/449opfIb3wL0fC8+wj2gd9sk87xM4h+BISZVtNlN1xGYTRMoHTYpPgBblXGyiV4MLav0eNlTUjtKH/uDyvPgAanRQ99RtWz+5Z85992zYePr0iHVdPv2x14YfXtPe0r5P673q9U0ffjUkWsl01rhQBvRu3n5J+/LJaujTpMC4qITeQmTDuGho2Aq9ymYZPqORI1NbZLDFJQ4ZWaDUSEFaZYTkWqTSBQ74QdhUiwdacDuRg4JEKUZywseQHclxYKw4zVEKzQJnV9HVE7r3V4O48wzXpcaEsLgdcMR9kHxA5h1YUhxc1C1j0Z8/dJvQp42vw9Y5wwdWjxgEAqXV705btWXqswsXb+zW/h97g1PpvpV9ug+bXbTxC+0n7eOUYErPsQuKisDudYOqx86YH1nbaVVVl+Kyp9PwGRkCeZ4Gz0gzFCmkZZlUQfQRhKhm0fnNTT5rLpEhZZA8lZGRm+uvjuQqgmC1WmoiVjqR+UuuH26c9VOK25FlaJcC/sRkJgFwAjaNiNcyOx6zmT4kVL17d+fFo1trn2u/Nj9R8P17//5x4JOPHV3W4+Ae0C/9SJH2+W//1X4DU6sWj+iRKfmLerV5663Aka2njo7cMCozs92IbjNuB0r3/i0njXrp2/OQrzGQrwGQr2yiWzg1jVFsottN2Bg6JzdNJB2K4nDIlVAus7NJMgMPhyftjThqxA7U41AS00v+jiMosnSXb377Q/v1L9k5vHP+ewtLe5w79ZeMzFqYGdTvFU24PnYLESDSobbPczjThBTRlB5EeCjmdMHJZGSyihsVtznSTWKKg+EJN59WHeGtemZObzS/yRTo2CHksnANNIXqUfS7OcgJDnRSQVk7AAIUdWT33En+8nBOC9si0LrucVC6SCnKcec3y5w0d9+w2c26ds2cC43V2z8wW86NKRyQma+9HU29917y3yA3P9NdUD763NBZZ85MGHfdTHbTeYKKnn6cbg9fBYkBYafLDf1CK0+QAseibjQ3k55hsvvsSNKsEc7lgrzQEuUTJejwSWo8hfZ3fFEhBfnIiDeOUiBrCmZNBPp2QdZKyQlTP3i514aWEwId2vTKmH8wev2RBWrLYJv2aRNabug1an56y1Y9wGYtSh2rGXZraNQIqCSmrlkDNoJQSeao0K3DauZOPXz4Uz02w/VqnaHfkIo0v+TxMCpBmBjKH7A6ayKS1UoZjRbkH1O+msZViI3ULCpCRKFZKboKR3uBbkUoPTLC1/PjtJ9+1sDkLy6BPtq5+Ysr5fmvfn3t/Mb9+7aAlru2kbwW1T4hBwATGPjwfeWLp94Fv9eef/rUWW3cS0jW0V1XfxibpEF7oMqsA7prKSwdTPe7KyN+P6ST12MSo0TZkvMHifxufQ6BxrldIqM0pDLxs491sQhK0AGi+2s3Pv8hCi1A+wdu166cfbjHjl2btyzZ0a11wayxH1wEC069CdKBHZIqmpgtnKHy0Yde+dc9i+dNMxvudDwZs6fVuB6sQ9gvKIoJ+mEuo9FuMnl9pGywqHBNXbKqmhyUyarn71vFytvqR13Wp5DgscbDFIMyumBycKiLCsM6+ulqZZOwfcJzE7YJmxTQqua5UaAl1aND+9SWvmV1Halnl/laprbvAKRvv8W2a9WNn+guzLuETLQKe0hCkhA0kFURLSbAmThoAYykZBKRMsHzZnW/61xR/ThKPTDJQFDhHCpVZBAYA91FW6h9P1Z7u4cTrIW+PVhJPVrXcYyXarsZ+MFDYzzav9E9CNy/++l2UBv0CCtGQJICDW2U1xtw0I6MzBR0+XEikmInYhceT0TMokzirGr9NNRWDcZeh/7+hiMRuvzlxUbsL/7uUgP/ReIuYxnOBfYh/NDidAuLQlYW4bDbAwbC0DzfY0XnT4l4PGaH15wLXT6zyqRXRhgp7vnFfYEGfCAzY9WtP07lZCEwlhTgCCLLmk+BpKuFZaWzn7nrz+9+/2X6vnbs8EePbV0V5nay6X3Xr3xqfkcYS6/asXPd6q1714KRPwHDnn7az9pX2g/aN737rNrdPX3gELvd2G7yjnNgw5WXL7zzxpuvxu6wW+IcbBd8fzdHG0x1wjMlexMN6lnprfj8LIPnugz6vQpRFS7gJUlE6JPQh+Clyshj/Mf8jzwl8q/DF5SZ4nkYbZtQ4gxYocOm/mWFbexyMgdgocTag0V48FIOoMs03+ffEzc+A5e1zDX3k4ujS0EQvAdEhCkOstY++sAK7TCkawuqEcb5s/7hQjNDSBxNS4Sk2lkGEsZ+zP7IUiL7OnwBCWNZmwUGShHo+pjxXeJfl/5CKwpDoDKUWYOuONwK5JDjjQpsAe+tuy+6lFy8eZ2WCT747vu6qxok6JEVex5Zq/2mXdNuaO8SDWt3d+HvT8Iz1AGv8Rn8/Qy4xnNxzXCmLqPw5zvj2t5wONXAMCxFoqZYi8XIUrwAaJozInQsjiJYq943hhvD5VDjaejI86WCFHIvPTAGorZ9dee1Q9e///dv9IboB2T6dRiIRb8kXdithc9F93Tj8Rq2CadYjEYTQ4tWgrDZYPir2uGqWc2iyStCA6HisouK0F88swLAPcL5bjR0tbRMgc9+jWK0T7dpV9jt186XiPb88z+S/5o5q64rdeLBrteXM59GFx+8e+cmcun1c1jOesZy7m4iC2qLrDQYkCgiNL4WkcrOcaRA30fiZSv0gUzQQoleKiM5A2+NVdcmhyaJegw9Ge9D45J0dNykpHyiwo8ecPnUtF1hmkYjs2sXLPjkn2vfn3P2gbV3zCk7cMucaST9p3a1U882Fbev2r9/Ffn8NSBt0H478PZXJ9/QXujc56yeHxoM93UY2lfQrcE+Z6J9ljmog9uRCuEKy8AZluRuzjDPw09GYzcnIeMumqT3yETvgX7nxr/+5+/gHgX2AHxONv6djjdOEr8Sai2QmUzw1I0dtYIMzEn5Jv3nhyd+fhI8AZ/gO3uLfmf/Z60kEKak7BeA/HxHr4ZnNI24JVxAmVwOWbZZTX6rP5juRVG795iXtFBeL6E6baqtOqJSVpydoGmoOiqKChI1HDhzGJ/4ltgpdOPGxIdKwfg3HiahmrUADpXgDtpYamyfZYGxvvbNm7WprJn10nPaFapMO7p0Vcsnj223VbabGQqNm/bygqlF0VxUp689l+44/szVw89BnnE/CnvQmkl1xjzPJW4jfsNZNhYuUpg1AiqRZUP8xvaOcBIbwzVO1myHzockigxrZl1ugpd4P1R8hlQDyTN2oiZSYK+2k6J9vf0x+2n7x/Yf7TfsnIOy2w08D/1dSeJpA4yrUa1XIVPDTGfglyXMG8xVBmHZKrgdcAY2GQXJWomIdbE0nLwMT7U1gMoTyYCfgCGuX4lleAIqaK2CzmP3tdp5n/a49l/tc9IJ+i8+kLFj/K79JnCYHKll3n1ve20tmAT6k8e14+1nLP/063vxWe0L+Z2AdVLpTftA9Brt4Uk12gCemfoabXCTGu1jN76jruD3aK73e934D30cniE39KV7hXNY1eH30x6CVnmCzkh3pNZEHA5aVdkaeHrMUk3ErND+mghtrW8xb+LbJUp4ka9EmQAbS3G0A1YlIOugzXo7AH384u5/P+GzV8y6rcSr+MtbZflLwbe5h1/bM3dIi1ZDpoG7j35An9QGaI9qJ5aZVnDtdwKVfC965tLxKXdqNtQnT3SFa4Dot0Ivr3c4EzidMvRBFUZCWTnG63OYJXNNBEAfizBCX5o3WgWCwp0w9f5zg7K1+qJNOZZhre/dA3HCyQ+GHX7t4m7te+3E7t2gO/ho7pDRk4dMg6r8zKXHjn5Azo+uQq/JcF2HGKWEnjvE8mpH2lTkoV02EHaD3eG00tWRJVZAWIEFiahZMKGWGXO8aSdZRGc0lFGk6W8il6pMXWwsjGSgkRBGke9xANK0A8vghZgMDo7JoA3KoNvmICz1Mhjv+2EfhD9/HucWuxGX4D9AvaZgvba/VlKAIUmv2eAZfhK//5vo5w2o3EV/fxX+guhItUgNZBzVHBbiXEFx2GWGO8waGZI0WniOotCEgOoIaSU88SKqioaNMzhDEOuyDMikRdtwmrSf1jZog8FBpvP1ofT+a6e0wU175eA5QnxtxvZeJbqGM1jCaLXSUAYIu8MoV6PW+xQY3CDNUB1hKNpaXS8DCeWQ1+AY6VXsAdRKJweKaGTa0ItSevONL6K/UFuiOaDDz8SNM/v2aW+B0L4Hwd0nLjOdH9TGXTwzf5aWPZ1o2sMX15noe6QzId2MNgH3awqQ7u7hdJWQeBsUAIJCY6tIjrQ7eAlG85SNMGDSrRz5FDDotTY4SZvUYZV0TRHCLVBovoa1TAlwAYoluQBNPLarbsuuecMnpnYkhz2svdciEOlOerZEL4Ot2gQyfzbo/ivQtmh3/qK9Mqdxn17s/MM1h1HusnBXl9edSrEEI6emQtrtdo/bhNaXYNxUwO9ivRRLAVkgBEnwC5TIoEbwmkiqACqEHwVSEFTRSHkYLB9FuJVHb8BFV0iJRs6k9FfiE76QQVUUAbkAUKj3Dcb60NHHl3/QSaJQvSwlApm0u3r/cRKUt8175ejmnOpOuzpV52w++kp2e9D65B/SILKatUVXka+3HQne1e4YP0oih0b3S6PGg2Va9rD20UJyPqNGd+tnuiOUgelMBK7CHeGeabw11ely8alUBk0ZM6iMnNw0gRd4aK+EaoFcLzwmnBY+Fm4IjCAQXtEJHJTT6fWq1REvTbBQT9Bv0FdpKm7Dm7bfYxVBtGq8rbo1T88qs+IKNajIShKVIjBuS49NPEfpJAGQU1/Vfh+4fx7gth07c6Fr19pHty6541jRY12A4fyb0Q13bX709u9se57urf1n9ZwFMzcvmDh25tylbY8eeH7n3J0B+8FF808hfLBYjyDBE53CmTxJAoS3DwyCuNYCFljARAuwsIAyLmfAHAaMY4C+ncOHD9f7FIc3KiYOYRQQgI5mcRnYc8RKSh8dkqJ/Mp3rdi3bQM+8doqa0u/I9S1JeupgXE8ZvrvxA9Q7UE8JWE/V1UpOgktoHqDrQUirQlSGc82CxcpyHG8hrVbFoqg21JjjN1MmxiyQMgn1AUkq8EdilqRVbEppck1g4rShS2a5CPnf8ASjNksBBOXggdPDH+p+/YL2bk63MhD9SBuYPi54GpqMf4ydChZq/dr0z4kGyFWiI7qTADc0aKOH4/uhFmEnkGWDTVHsBlWxyqA6IlOsuTrCKvUGWQYxXDI9gdnQAkNphkZ5r3ZnXtGojSvKvUpG217lpe625DtP0/uhnZ2jPbbKtJXrtRd4XwdXYVTyt72fecTN+i33JPdbUjTB0ZwBanGsOJv2WwZi/ZbU5Ojvp6m76P3Xh6Kmy8b9lo1jtMY9jyj/hmwNXqfu4WzBLFMST1lEyQIjUL9QKJAU0iakQAtmMyFaKCRNhFJfUY+UR3X9Dupw2YyO9VDUjizD8+pRr7LUblV+1YhumeWlrXpGv3gH7AbDL0W/6zPldlumf0NrW8ktG6h7oj7y0+v/3bqkHNIZ672EOnvwTfsWl0CbdwLbvKKwy2DW0dzMCAWPocy4jZS2goY2L0lV48XTbR59orbu9tOk6fSu6Im4xbs+FD+jGr5lC/gMNLHIbuAIQRA50aqYKehnmDnJKsBItiKUfDMSc+Pqs12okAEKHzXrkfvavXbxuW/m/fbcc+CjDPXU42Rx9OqXLci3Y7mZCHzWLMxPKOzkaMgKYTATZsQPoOBzqJqkLthQYxMeShjwkBzZA9zof8hKV/ok+hOPkwfBNUO2RCTahVOMLMszpEgQJp7kJdkMfQX4LJKpSXYWkp8VurnHgP6ablfn3AMA+n9dzG+IPfp61+irCYyE5TFfoW04lbBaTQYYTNB2B4FcBchszH2DXoLB2uQGNCn/hDLQMRezJFDvXQoroGNw4wsNhgOkAJ7Yt2/qnH0PUuLFp09chu5bXYf5t2rZswnc1zsR0jIa935boV8ZDvuhz0TbOVGkFTskyMkJNRGOo21Q9MSaiIKcllCihaRhfUXsVjZP73mFXnogiKhB31IdtRuf/Xa43e/X92hPde69/wHgOKz7K9Ez55/8WbPdrv2OhJZo4EuZoHTBE81JEm3GF1ScWI2IgbRI9f5T0yOHFyR0E6fp9M08puiFeocJxGN1uOsPhscZjMAoqDbS4xFsgteHYGAKZIqwSBa/heIZAINEEYAKUA1uBdDmnwY/AspCgXB6TjcAZIvshLupFqphlSLUSnWXeky9qv5HZS2UqsqKwWCxQHfUQjfsX5sR32n0emaDcDGRZMa49fVVCH5ZIgKJQLsMfAkOmXbuH78j40Cnrx4mndrn2n/3/Nx3Z8v9Y/ccMZMj7/3km+Uz2h/dE+2rHdW21J5pv2H1Vz+jdR+E7nYh71bCSwwOF7h4FrqxFoPBqBBGwpdi4SC7ltMW0kJZLEaTZK+JSLSJMlopT31WoeIv/Fk5PrQEt2RRQRwRhdzoxpSKdWnBs3z/+ecef9G8bffubeZzjz9z/sikW6dOeuc98qB2SNsGOoBQdCfcr6OgGBRrB7RHgB0YtT+0b6L/0s9NMTw3edhfUInh4WILACaeIATaajIZaaPdASyypTrSF+H5VMi3yqflH2XGQskywXE2eLAoU8K41N8hNojt6nUM0JsHkeUJAsVmh68C/mKwYcep374Cn5z+Qdvo3boBOLX/aG+QA90X76s9e+0UWRE9S126bTF4G+rwJXCt78J3tp0w7WtRXoT5COq8DKJfWPWKapBlVUIU1cysoMVCVUZcKXpCyuKyuKwej7dfxGM1VkasyS1wMeDAhn1UOJRIuoCmYpfUqO63tKy0TGU5geLaAWrLivt23rfmvt1rf/no8rUffv96yhevrP7xtRUPbB6QQ+dfAL9fOH32/PMvnCLf0a5r1+DCR+GW9AEs6Phkliew2+3ydrr1+IYld2O9chLuRTnuj3MSAVTPwkopaCKkW5IEm0kwpQVZt9PtrIq43YIouiojoihIlRFBbazukjzR2CnC/OjeporcTSTtiu6UBgMuEHtFrjp/fvbkpUvfP6t5aoFt9fR567U/oa2cOm4+Xb52+YhFNk5ePmnTfrq8rufA4WP7g+e1M92G9OuF6r8g7aj+C+OcIE8ZoSdVRhiRUhvgnAAV7T8q66qly9fVDYC/gvfSDmOqufj3FaJnOJ3mgcRLisnMWK0Gg2JWbCrOJIpW2mK0VEaMKkqV3DymSsLpRb6YCXAIdjsWWaHbEKpCezF9aBhcB2V7677YO6/PtDxy+kbqiPabNn9t9AoOrDKXgIugpm4A8h1WwnPWBZ+7bljfIXygVyGtAWJ2ONvt8wRojrAGAtAWsh67w+H1mE0mhvVAD9DN+WiOFv1ABHoVnLVABKLoMEmih0W3yfFACt+I1MdQySVp8elVcn0UlQ+yYBiVD6iQIx5GVYBYGAUdXpl0pZTx0ZOgr9rmt8c3tx+Sv70wEt78+Ltds0HlyailLBVcpR2m6HWyxlEFZv44oUYG57WW1pHjftROTcqL7iIZo5PW/IjX1ZD3DLoP9P5mhtv7LZIXho0WL5UO46h0Kj0r289beLgfPO8iwlBf1yC1PV19Aypt6IKoqstlhVIoESjDBuP6+A1oE7ivv4qddAXt13GRcSE6m5y+188yOeSlKy12urcuB4Y3T5544Y+lSyx7nO+cPfdl9yXdlhz+3jZvVbMBlSerJ949pN+urt1td8/ftqL9pI4GUtg4cfshyCOSOxXuJ08Uh93QlvMUyzI8I4irTcBE8SK7kgSkBSXkhuPGj8YdszKlB0jo+l8G403gl5eOcJTGnqHLo8e0b6mx18+Rm9uPKay7Hz4E5UHQ85haGCd9hfocDN/9ovc5CHImICSnhU6Kka7Anx0Gf81KdAkHeZOZlGUUJlnMVigT0PWSSKgBCiB9pNWsxlrk0YHSVVvDO9MGkRE+LXpgdKV2xuYetc9/0qcbWHpReyFtWgmUTS1zxK2A107dWhx9FERFm6bnaFh4HpyYnoKwk0RXfFajVbFJJBJOzoJ7y+PF2smlwzjmSAqLsCRSo7Xl+el9500qaubKK+/eoSN5Dkrh09oN7bdp/FLjZtAbfIXzIoAYB9dBz9F0C2cwtCjaTChTg9M0pniSJixWimQFlDCGMKHtQhFtPFnTqlWDWnH9Fq/sJvkaQ5N0TckxlK7puTXaDG5ocroG0vUEpMuJ615Lwh6AJmrCs2NiLDwwVEUKAPzPxECZSN6XRocnIMcvfsBEcL22VmPQ6peCC9fPge81BSnIm/SMxp+L4z2GhXE+MBg5GiUdWaASSVnjOPYX1rtO/e2vw3WO6d4YbkcHuhK+d//EsxK50Vjuswd+VlbYCqAcM4zBSKsUh8SaSHQHJjVpKwGs5gPLqPPa3FptLlb11BH43h3gs+7G/djDsM3rAr9fyVyEMZKD8BF9wtlekbbYaIph4MFyopGBqTzhwX1hItQ+NhZVOLD2Jp14zorkkMZR34WM2/FQLhz+k90KJEYWAFOcmSWn0yt/+OSBT37+z2cPfPt53R3Acc9q8qU77wEKmVKnfapq48FWBQSuR4HXBpZqixXtW2jCl+VRfWz/PPPCP611/8hBazUCrs1UzM/QWG/qBPphfB5KwyrJMEZgMrIm1gI9XxOoiphUAzRbj8cORMVN2rdBLCZCGwbGwAOxaW/dUWhwu1Mn6rpHPwdb0a4BYjtcvCh8KRN5YZWA4RdnkA1WhaeRLjaqCbCMRm6+3ixcX58ogz5jR845U1v75Z6Nm+Gxm9ZnQDFJwJN3eehDq8EDRAPZu1lsKaLYsiqCZP7/I7YctwtIu4C8K84PdSIuR8Pguj2LfZ8OYUl/Bi8I6DGSLMAlC+OHmRs+DT+uoml8GUrGAoSsDtv1X/ixfn39Y/WlJEh0K03fAZ+L4srO4XQLXDxOhgGz3WFRq+CRA2bouHPQGUZ16xxfFeHUv76CjhVo2RPhpSuGmpIHyI8vXX73nDZeewrUXVh22+yVr5LTN+3cvo86sk4r1cRho0cMxvIwCd3fQnpQHIewkdNFiuJsDpMZ7rDD6TIpkCgTJMpk4lSDyJmrIjZEUSK+bHIl3oCkUD1BGNTxICbqzL4Hbp81444HyWP7dKKQ/tHEESNHDNZ4pCygf3YR0pUTo6s8nILoEeEy2dRkinSC4ivUlJqbU0KuxlS0r/0PWpefkkmILQs8H4ugTmoD/RAfcXu4r8PplAgDJwsCwuJPlcSqSKpUIJ2WfpRuSEyq9DF8QUkS5REd0IA7HB4P1BoeCTUT+w3TDUsM8ABLhhrDGQNtMMRQSGfc/FK3SRCJAOeg/xWLGwPJMWURQbfRbvw6/5VF/HPi5pn3bjZqy8Adhs2b5q6WzqT+VvsrtNIp2g/a1chD1ZZxM46dWv74oYlDhS1HtY+wD9wF8rgV8mglUomh4RYKD4AEBVmUXKiFMSCLkkoIcLWJ14mPCQpKCGGiTXZ4MO20D/pXUpOD2QC4qN7wKaH6qhsyC4eV8W5VzMw3B+XXHjn+2oUnH3+dfWTfPjDg1gkTppWMaDtlBjn9kzrtDU3T/qu9A5QfkHWKfvLq1Q9eX/Ps2A8xD53hIb4ek6ee4QyCohiTajabIOsytIsOOwVNODy0NmAwQF4MojlhrfTghQg1SfTGGh1ApqyHj65Yl09rQPbUXnoV3PLfd18Hx2q/WXbb5EVRcAHazneKAX3fFqjGLoCfhg0fMVy3c9iPR34X8uNlluh4HGXRSD80EE/deLzW5+dtDfJu+s8vTPz8JAOBMr0U6ZEzKdKQ6uOVBrUBJRj/6iKMRmvCKYoQYEi/PyPgFAJCZhYTTA9WRch0s7cyYjCbn7pxJmw1Wrqlm9PNRECVoXmTPWh6XHKTU6w3s2EBtR6bKiFUJ6TauFBpyO/SoZtKHKiwO4EnEywJnXwCIbYaqYnfgBG33da7qF2XUgwrs2IFc3HH8hWtV1/Slte9vG21cQ3bbQJFY3iZw/SR5Tdu6PEc9lE/jeUoNxG6l8pCL3U8a6SJBjnEe+FaVWH5XB7u7xAIKpWXoNvPsnYH4YA2XILnlk/l9VIpJqlUykN5FCiW9un2JfBs2CV7jf2MnTZSdrsnBn0MGsAeN7jwSU7Oxs8LHriY3HDFwZXSpVVHQL4XkL+e+M17Rlo9d8NmM7hDW2bevH7GZuk5ftH5Bb/dIHQA5OMbhaET9z21/Mzh6eMt1Q9FgB+fiUcgn+l0T2jvcT8osR7hy+Capl5J36Mz84t+ZnIIvTrAhBqqbYKFAg16QBvUnUH5ccH3fwTKj4vwE4PD+QaHy+1mHazoI0UykObyw2V0QWXrcjlYB/QwHSIPAyzezrqrIqzapEAgSf9ak5SwX44VCqD1iGUpyhRsrVC1JeUFa1575vX92bZ2Y0YUZKgZhcVBawk4H/ri82JyuvbalgPUWa3zO59Vm5dynY+cIn1QVTOvnNYxLiD/x3B84IH0N2MUheR52QgkSXYYZaPX54HueVWEEQHkAgCe4KH9kPmEi1xPeKjpnUzcu9RdJGxK8oDuOseNye+g5/ZSZE/+qT2xnVxcumTB7JVluj+tlSLDAv7QjNAPaD1m7IiRSGYhvUhmvcSAsI8SGBLG705RcAq+FMbtgatKesxKQmQtUGQ9Zo9ZcKpYWEN/J6g3kdPgX4rnE00EM9qb3JaQSHy2cCyIZfIbfLbmTtIlUoESWaLYieTapkYxJtHxil4xIKNM3Hu1ksIzDXQd9suxbhymx6Q/1ffpE45Uk5wUkz4Bf1aPeYrDLqPJRNDQLSM46A96oI8GlWRDh7DiLx3CoPxELfRwtV17dc/s+jl0+4/1STcoByuZIUQ+URXOzfE5ASDSg7xgUBQhSPiYgkJzpj8TXfy7JT/NNHM3q4447W5UQRSPCuqbTxxJ10J6BgAXu+kGENfP6i/RLKE4nB+aHaG/LiNTttgrCnv279cjLzi0y+337N2zadPgAVu2PbB3fcUt2ZFA8x79+vUY0JLcoU0r7wOlGw3IcRQNmqmtgaHsSW3z4cPQj+8LuoFZpa0HF2nf4JvAq4v1HkaET/Uw7vnuG84yGiyiwHMsI0mcYKFNCknaHWaTyS5ZeM7CGVXBJLJGHW8pIdAgccfXCLYSFwUHEYp+CChUSMFYTPTsog1rd9266pC25wQwb7z7xNX+wwrp8vnrHtGGfw3u0m6DOzENPAo+q5u2HfS8/8EFUKbVWG4ByTSMvkXC6bQYFNpAe32EozpiNZlNNRERuuqE2cBTBmd9BkbvpElgDCTX0IBAPA0TRAPtkJiAeOYBjMRJB5R+uOee0+BVrYScFU9A6CkZ6otNFy9uiu6IJSF0Gh9mXoU0uomu4XQDrShAslski8drgFJsMEiEBDWNpHJWAmpMmkT65lwoaVBOo0SRPog4FCslibv0IDY6XgXNa0Gu9jaQL11+7yWtXHsT/PuPa7NX/kmXg3u1W9donx/YueMY9VjdG6+NGIfOcwU8zxcxjvbEcJnH7TakQXkUhHTZYIOqEQVvGZmOVNRyRog2sTqShpD7PDaOkq3wf5wyjGcL9HmGclKlZ5KKTC6vxkBLULNj/L5E/gDhVkDLSOqWkexgXHB7qHe4xbYuz959/mP+0N69h1xg05qzLXcHW/ctWTjLCLqQI+s+Khp5R8tzjwLoOEb3opw5OWrvY+0mDct/+/d7sbyOhvztxD0KE8MtGQAUu51NS1NJL2+BW0B6g+mpTmjM7UapMmKU7AQDnUCFKWCAh+F5xkORlN7krzM3PMFd0jVSMoNF8VuNELrUbWjrrYlBMGQW4PbtO2S58OQ9J51HzUMHTBnHgj7a4/yl3mMth5VnNz15yQw+0VKgfcj7hrjxyH3CkEmHTi7X7h0/1fJALXQT6vt5nse5VRv0aTNlEiojs4lmJA4leoyMhaDtKgV9dFThaLSYKAYYrXiuSWMlhMnHA83wRW4Q7wn8DEIiYEUQyMrMop9/5Zllj93+DEKDHmXIyugLOvfJC5C26HfoD9P5YMr6iR9+uOh23demV2E9bEV0WeJ0WTkR0yUStE2hOCtXGbFajaJJhHSp/0e6EKCoSNKrXtmwcN/stRfA8bfy+/pzhbJeYLq2Af2BEcBzF27ZVHzyPF6rCkjTJVzT4SXGh0tQSaCTQ+2hNCOb0FWhi7RBMgkbY+QZXwpHmSUzVN2SxNuslEDBIJ/HSxfSIe1DcbizxITcIjlxTZ6oZkjQq8TOuJK0npf2bKveM3Tbnt1P79379Su7+nI+fxhwFS41vqb6ukYnkVsOpqyc9eGHt4yAfIxGew7XliTsxORwKcEBlmXsIiSRtPA0QDd9vKDKstUqmBja6VBEi0FSoZdLqiolmFirCihRV9T1fCTQleqtEWQizokONAPNeQg0ZihArVt4W8ldYNJDMwZsq5q29/YrMCxjwJ9gozaN7ADjnNhmgBnaerghT8dyKpCHp3AvTgpRHS7weVKgR8PYXITXiys1FRvLMDZ/qllwCTURL+Fy2dzulOqIm+JZm36A4wWbTQGzYygriRvGFNIHghg6DVIs6N9A3QMCQAlQhZsO9axteefC5xavLq/t++h92ivUD5p4VptJMcK8f3186fLzm7vQ0XXkTKb7tpOXL1155zaRDEdPgsOYjyDk4xDcCzeMLoaGCwTRa7MrPh/HGTwqPEqqwSYyKal2RfGxRp+xKuLziTYbjLNsogGIajIfsUajUAP42PoC/gT9aQLADJQi+lNIFQQU+tCh1nctP7hodbtDT76nXaDe1c5vPtpb26r1fbvLhns70VoVeKzzfeu7dNE+sJFs9Jow+dxj1ETtjphM7MU14xnE7HB5elpGIC3Aqn4iGBR4mwrPkeBlUz0eLwyXvFmZosWd6q6OBInUVG8gkFEdCVA+ShU4b1wwGmxKqIn+T7jKSZtDNd2c0rL42YJbFKRWTJ5Tanw4UNlzX5/+wYfd7jv37AHz3yQvaLtm/0Ix/PDNL825dPmdlWF9mzquvXj50nMHWkbvg5JzlqxI7FU+5LUW58bSiZnhVmlskGEZi4ej09Ntituj2Dw2grdQgQBhITIzVKsfwROncxRFMEwQ5QuB6LHxemqs6G9Y/QtOQzpDVIPTWL+bMFAIKvm1YMVl8sKFGQtKDvl79z7Ys1fgUMs275Abf1kEZeca2jx+2GNvd+lyal4xhba19I4nunTZvi9Pq6IegxuK7V0v6AMPY78lBhD3hKtEqbSnagsq9vZhYybRrFlm2JtjZ2w9JdPAQW07VkeK+tZEchiaoWsiQQVaRkt1BOpigWpbxIh2u8gUtWW6ubu1rI607+ZOrYnY3EQBavmHnzA2mxMPLsaxnA4DD9ekIUZVks1vXGUIZRD6fmV4RBUeiCYCnDTTqw4p3AGLSq1QOBUsDqYJZKyLuawdTT2AChGfOHrvqjuOhB4vO3v/Uw/uHerrVtq/eQfZK6j8LTtqN9y19VBhvznrHrh/aut95ZNHD28+YurWHr5BU+7oeNeeAQ/u3jRlcEUQbFo5d/O8hZMXzlnW9u5H3KC/durdji17t0sRfee9z65d/LDf8diKocuHtU63yv5QzhRPwLtsTG9vmnfDgsHT2omCPaNdBPU6wVj5GnMQRsr3hFNaETbV5cxyuIVcQ4tOHTu28Oc2d5tgXGbq0zfcBWVb1UhzM3RNKyOdwmabzRzuRPd09GyNEYV6ehHSkCssRFKyHA6nO+yWKyNuKTYn80O4ki/Go+jY8uuLfvM1d+DVIkuKAyVJ1Z1/seyqXu1583Xf0m3l6hWTW2lP7N46enhkhmVP+r+eabjkQ6ffde/4+dv6HfnH9L65W8uH9evTfOgkuOCdB0/ptPChnX1Gt7EpzXu1PX/3gFt6DOrRxXahGYjUr/Yb7vXjxt5lJPn1U6tXVrqV1Pz02anpqbdP6O0L+rageORGDM/fR3QKp/lkiRAkShQ5u8ORkmrguBQvrgmWBcGObv4bYvrXRyKJDExATssncbkvFWoC679idp8uuWN2j/E3b9GlCoP7f/5KObgne/SLTyF0/3V3dk+px/f/Wfs2ju+vQtkbge9I2oVTTC6X2elkrDJ0MGDE7qRlkXBYHBhG0OxNhhFsYL5ugiOo00kiHMENe9bu+vf3O6cs65cx75El9tx2ZTvnkQ8dJ2dGN/zxuY4mWPXoK+SKaL/bphYA6gWi0cwT1L3VLZwZEATW5vMRLJGd47FDlQ4F3xP0BCmjMRUPOJEbDTiJ1aI0RmSun3EC0jg3vspiEQBBBgxOA34KIdKQiXknGBgq2rd7W/qh+9ZtlvIy24yvGQ7G5mYZtMvaj2ltO1aMHVadNANFh4s64NRuaP996xKfV5InmIGmTXE0K26m84Ww9LtB394EVxz15Wem8TzrVRTIV06uW4X62wylJ92dThkMqZURg0RJjdqQ/4KveqTpNC6lAVu6M68z1u3aD9//DD7/85vobZ3bMvesu3+NsXtp8eA+PUBmRVvznevvXiu3qyjq27MvmaJ9pn0DLbZMFmo/al8FX3vh2El/ICeQGnjy0W27UgLZgfjsFqYF0xf6qIVhJyBYluR5lSJJm2qSqiMmGIuwADcYxgFPk3LGKJi2OzygfsAkR166oHGvgHB2s6pXWu/sNjpvZF6zlOY2pnPdgtt2gmbk8QsleTPy23TAz+4P5es1uJY2Ij9sN5skiYIBkkrZLaJkVgm2X4SIN80m1xTHEez0vn/kltsdZUo7QP2ZeFzdx9q8Mz/wLcP3+2fTffQn1r0JDVo4+6VvSdPUav2eB/PO7rBm0nhWGPkG6SR+wz1vqXrP28Jar4vkG9xRYpqZA/B3MmK/UxTDtvPrKJF7an1uSxK2HTwzqVBGX2EGEzL0PdEdTvMsp9mUahWNFl4QLKTV5GQLCj3BmoiHVvNqIqrCm0TRAsMmpiaCwMd0xJtYC3ReQ5xVHbVXLyOoAHimFSWAeEkcbmqkinVYBNWmx8Dkc8WZ3rRWfTN47addx+7Z+VPxspdXPrB1xcrtkxeW7bQXFxWXOOzFhSUlTm2weRU7b0keXVL3A2W9fu6b03QvbaX2IugA5oClILRc+1L76odPxkz65ur73906/sc4r3BPjVA+8oj+4eZWOiPdROQEM7OyszO9RDrNNmuelS7mZAZVNxQQt5cTqiKcRNqrdPiK+KVtjOebcFs/2qgRY03XgRyqXdU+W7N502rMV6ndHmpRUuoAZJMVIFOir5FFwAUc2m/a+08e6d3/yYcfeWJg36fqPm28BjHMhJ1Qv+0lHJDLseGyNIs/3Z3rJIjcdAvdrLnP5/aL/uqIKorWVCtppKxWkcpNz8pKN6ZXRwhWYkmWpfTAuGB4DKsjpN/ny/HpYE0G/5GcjgCEETfL9OGfcHslHW0li5UlHZbTUUqPe/yofVBJ6UDHY489ecQxIBTq73j0iVcecvQrbNHP+eAuZ9/CwkrnTqj5vtcebtm8ZVmzUjAMqNA17F2UW1ycW6Q9rn0GFk7NKijImqKt0BbPymxWkHkr5LvNjfX0BvootHa5xNRwG4XItqd5U41Gr52g85rBzy5golwuu2SvjOBydyMFz7hkz8hIy6ayKyMcJTKpDMkwsTRGglu0EjG3Ts86hprgsFjLEMAMjcD2UI4nk1Rs9hjHOlK5vg4CaPP6xWZjRjUH2y+fbz5qZPNz7zw7aYa1Z2lJd2X2+AkzlR4l8NWcCWTKn8DjHDO6uQaua1+5RtcowAPA85cdhW3K8z2XTj9/yZlf3qq5+59IhlGv66vce0QBUQ59rtvDnXxSx04tCwvLg+Yclu1NmMvtnSRDn77lrWoivVu37tTMrbiRQSvvVKoopZ3K6a581/brIl35TD8PD0bQbDby+IZWTuBa1TtY8SFHjdA1EiehPmXZ4JoWSYP+TWlZ/aUuVJLYyQqWlgRLUBUZhm6LzQqHP0Z+4+/QYsfxl49vuWXwluMv/2NHi47+Mr7U1rX3wgnlE1JSJ5RPXNCzq1LKTzDbMyb170N27Lm+3+DZZU+mL3U/uaLNwpphS9szg31p2nLtUe2INn/qVHAnGAgGgIVpvs1qmvYuFKg67ezALl0GgvaAhB8t/A4yPCq3TXH5qK73LClp2abFh/tr89uUF8J1zkI5H3YzjHPzifbEvHAzp1zWsll6en6KheC49pQlX20pGzp0bF2yLtLa1r6goKUtv3llJN8GmVSRpytHcmmbFPAInspIisViEuxJq1wROhdDs0AAbueKCkJ43ZuuMK6xa7TEamJ6KLbP4G9Xlfp60cZ/f/vII+vGjF/z8IFv/71x0cDhbeekpM5uO3yg9sZfrySZ9uHJLdrH2k/aJ9p3/fsDBaQCEQS2PPXR16fb5OW1OUOvuOnKIduE8wTs19A2Sbg3kiDHgQmE+UlAlBf4cHoW2z39np1ZCn9Ojv1c91g+048yHAG7iWzY96wNxLiUdqJ1OMVmoGiB52kD5XAKAmMyQb/NRNMehqiOMErD0ToNG0UQDiWG8QwkH1byvvbNT3/2I+l8+MvOqCv58P7Dq8ToafCgB0wAJeTxPUfbz1iuaVBR/YhHjEB69kEbk0P3groX0iPTDsKM8i6U02U2A44TMHSnDYNNeOur75rQo6N3NsXKJDu9dhkQXz38vvekMHPitnXbNrfN1waDndAxqwM8cB25Xxgy6YXL/3zPGn1Jp2fajat0NXMF927lcAb4LNpqEEysTWWNRsoCPSpFsjBmCYiMGYgiMDO0wWpAwHv4grcgBpSdVOVaj1LDZVAM/BNUMsoY/CdE0dU52s4+YEyO9sCS3Wu1h3PAsN7a7hww8o6dd1P3bh2hfVu9tUYrAb8M3zoCqCO2VYMXNBXNI95DLwQ1DJpznhYWGLPZDo+JnVIMggCJCRVIF4sSc45jXRA6MCeuVNfh20BN9xJtf8f8og7dS8BQ9JWZUdTG1rJNuFj/gp7zDP0q6MWchesRCIuEohhtErUuIhEmo5EgCpDQXURzo3Wtrnu3rB6ol2H8ll/IkpJAh8zZE8ZNLL4ld2SX0ePpV3uEMx3d1vtt+bfPx7minXR3YhRzEfoZnrCZJghUbUgyKBF5sVVBjA347mrQhmZQtQWjIn3mBVOYi0+PmBya2Wtj0/fg8HsYDDd5DxgTYTEf5c2Y1yfCXNzYY2r55BHoYhFE32Rak/lQXyloHgjK/9l4dn2EN4UJZX2EgC4mXFgcSF9KsAxi2oJNVsL5406OnXl3l7mrnEv9H+9rv3zxrYeGMe1KWlbkT52+74nccCs05pAw1GVoh6j3mROQZgXGpVlEC6I10ZnoS+wOD2zRt3lPV/v2PftSrcUypazS19mY1TlLYYJBRalKCXaherbr6O/WLaO3SSyiyizFxXIrgsmmmttcZG4uV9CzY++yVs1dBQWu5q3KenfsafC0b2P3IPpDsXOqm6ZQ/cS9pK/4FWh4G4CuohxF9ToVYcRJoSJVSbwCf/uKusnfZSRekXUzZ45/7z0Zf667B38hm+Mv11biLx/rf3cv/hJ14S/Ui/fdh7CrWfyF/AF/ufYF/kJnJv9b3VX85Vf8Ga/9ZG0ptZP5ssnaHw+PtHlat2nTqVVHxiDKskkBgOvSolnP3n3ogsysrIIWnMnQsdTT3uRMS6tyVhqM4Y6F4eYFBdle1RUJZmSklJcVterb2yQbO3bO9nhTWvXuIcs9erdK8XqyO3c0mhmRqdcWiY2II4ZJcZvmvpSUBMUaxNGw+i8BMOZInGkZXQWGWDWkYt8J+s8loQx0KFXooAcpVFPPZWZxWSALFXrBSMtBcRhhrSyrDAGsIQxAB9fZ7R3ToSf+FJ20oNPwnFuqHqCPxF60HVRYYOoqtiqZVtcZvjR2gS9vtQxq0b9F1ynlJdOoNwcVDmjRdVqrkqmt8W9UPkh/FHsR9eL3LMaftT8Gwx/sMrUl/B0O/85U9J7t9LdH73TXoBb56EmlU/U+MG0cfYE9COMuHzElXC6TJLTZHq/JbGZ53mgweG2ATkn1iLZUW4GNMlI2a9jqXBexgrCZ5w0Ig05iAcXEJ5di0Ndzbuk1XZ6hj1pU3+LdwH1IdAqHcNaiuAwofiqkR/UhUu8c3vXMkdVTpOif72nbjfuYYZMmDmf2GeOtxNcnRE+C7dSUPseub2H2A7p3t2690Wx2kjipvUK/wPwH8uRB6LUiNOCqzeXmDAbKZGIZxm2T0aw20QYQP1YHZEcWKFkkJdVgMjH9Iia9MkY6h/MxOpDt37CiF/TH+CgtA0E5A7KCDGWI1Mv7H33+yD3zcYk/OKY9aN5nOX3ass8cL/evG69lgzJyc/rGVFTyPxeEX35ZO6PnZOikXDrU76LZ6TTwtAL/3usTHdURAdqFmoiZE+EHbaRoZ3LTXpNkuhXlw0KJ/j09kx5Sg2rTPr6HHjr98stNe/mozzddurTp7fp2PkhjJar1hDYiRiNHKQohOsyi2evjPFURVrbKVRHKysEPEYio/lMFoDEOadOMv6LTVp9ND5YkynYu1M6bByy4DrRiAcj/GVWC/sIoJ08uj17F5aAbll+foleD6r2OizD+gpsYFs532UVFgXYQmjIRGh+PlyENZgWeZbtLcdKK06nQFDz/VtQeaoqDXeOo43YMFtmgVULX4PFknA3KeRYmVe+MxN2ZUAvAaLN6yLzJ8+c9on15Glz8AVBntKd+1+b2mTpltJs6vm3mkpplXaIa0/mt57Xo983njpzSKja7sTvdG3pozWEcWZbD5NJ0MzKPonxEXm66necFIZegCvIZknO7/ZURu1vKaZaVlyeLNM0JXi6rMmLk6rGeFhU4K1ohIONY1VSrhvcGDRiRdEYS8x3RrDlVLwPFQIWxcSQ6a51HjBozYvD8a4MYupZ9FNAMXfjQ0vPnnl2wcvL8iru23dJy7tjqIJmmfbt20pCxpc8Y9mgRhn2klG4xThkzXPtV+/CT54ec3vbWhdzFQyeMwvg4gJ4LdRJHZIStDAtIlkS9CtURaDIoBt8hFzTsVtCLg6jna6N5p5nOYIxGXL+F6YT8zl/h3rPwbHJEZtgK35cBqBeBILnKCCkmOk+SW91jrdrgQC15697oHrocbIxexT5sWWw2N4/wbFmTCRjMlJkSRCNP8DURFh41szU2rLsiGV4rjldeVKTj2eo1IrjjIVh2EA3wRi1kpw+SX5PDHtTCm6KHyEHoeetjPXI80TacQnGchTGgme8ii7MUlNls4HmyMsKLhgSqr/NmT0Q9dEiQcBEZ7qV79dXaBQvo8nXalRVRjSRXgFr0vEdRjgpjf/QJ5xBut4e3KCzrs3hof4CyV0cIivJ4vanVES+qwzQapeqI0QO348XYo28Kd9koGI910MJv8N2krI8xn1p+X4//fPHf7x9+t/yJvFnjtmy8d2vF0u54tjk1MyNHe0F7XHtAW3Xn1pTqbsAHmgHmu7Tm0RwdSx73o1TAdfIjXAiPqtoNnEAQTs5OB9I8Pp+1MuLz2R0Od2XEIRoMtF2lzWhAZ2KTGhUTNxhnadPvS8pi80xxBKsTLWNgd7pi9ptrjr+R/3jK/HEb7xv44KjZ42rJkVr/2bM2frpo2M5vF65dzw/o+eyT0/cN8muj6fI12uzgnI9iWEPaBFz7kEVsDFf50tJSvcEsp8vlT7VlZcmskbBYoMkiUqmc7CDLGr0UDDxtMiFLsl+mREYGNRERN9hSqMHW4g+EA77qSMDqtFoowqAj3oX0DNWlWG09oV8axXrm4tZML5OI994mIB/yqaybg68oIVxsgDsH7aZUv4u+KQjLb11r2T+4XgpZDQwGjvwbJJY3oufBVnI+pdDR3ahfEq0L3M8MYkU40+P3+9yBDJRQ8lkzMkSaI1C3JEv4qKxMNxeg6fRYt6QnYuX8KHSkRNGU4vdD0+NX7RJU8qxK1Fvyc/GJJ4kBzv97Jf6yfzJpJVyOtsLNeyi5nnudUaGNE1wlnea/6qLUgqjDhGRMLhJ1UmJMGniuESZNCXFruA3LuD25ZDPCFjBnZQXSCVJs4WGMpWXpkiiJNRFJIlPc7pQU6BKk0AXFNZECMpckoVFjWRLjpCUhw9fPtms6wTU+hwK7sv8bhgaBW9viPXrkePXFa1UNEWkWH2uRhEjz8enUJbNn9Y8MWrqvsj2z9x8YnGb+LAxOc9viJHCa/e85FvWrnpa2Koh6SuE6oJ7SMnSbSlN2R3ZZbonkM2Zk+AIlZZYCB2Vs2ap5UVWkuTcQby91E3a7262gLG020aCdNFYF12AJGmKzJ1ahSTtp5k37SZPXAP5QFjnk5Q+a6/2l79aeeGHOskUr+D3Ot58/92WPpV2WHH5oc2DebeMHDO4Tbm23LViBek1rJtw9pF/3wV162O5asH15+0mdWdRsevsu96z+k2cEVqS1rejZSz8TB6Bs7MD4ZMPDBSTUdSYZCoPZLEkIiV62Uw6n3SqbbAxpQwg4hCCheinJyjAYCKcgIQIx56uiCd+xiD4kF8XxcPAhj2PinFwTh8RZd2ttrjbQNTULg+JcjmPinMXCvMriRrg4xBVI70Aoy3ZibLhYp5fluIb0qpBelrRVRkQSIMxrTDSqvYRSLjYgOj57+O/pjrerJtGd1LLarM/etKZNq1oLJH7xxtV6rCEXMSJcSDqdLpFTFNoG/UJZkmwuyu2xiqroMJFQ4GiOZGwkA5eckl1WUwxxKD75Iu4vNsa6Sl5o+DIJfQg326G1Li2ZVVCWhEB056zyFnixreCoti23sh6GqK32NFggwRVP7gF2EqPCIdLhcAqc1UorkHZJFBUn5XLLgk2wm0h7Jaa9gAQKIl+hJKdqihXWx+oq/0/06z3CMfKv1LYKTuzQrb5PeGKzQrzkBtBD+7TZlPpmYW0v6GCI9QvTsXV3E5Fwvol1wZW2qrxgUxRBddMer2p18iYY5BgBCe0fS5rgB21zW3maikG8Jgc9RCOk+lhgkYh76s94/Hzv23f6xIn6M45gn9AJp/676eTJTdqNy0nIT/iEx/LD0G96VY8ubIJoVUVV0WlX3F4PJFkwOSsjJpNgc6uIcBgTkSQtiDQRm0idXILesA87boaKGpLduCP7jTdqr15t2pX95PKNG5dHDzXpzNZx3l7FOEx9wlkWhjXxLI+axW1Ws9Wu8iaJISWsQCxWK0MRNuT9xS6ub0ZmPZXQe24ApMVhIfzH/qWJJf2X1tM1xHv6V3SQxReSF9RBRXfSej1/G4SZg+vce4ezSatVVcwCZ+AtFoOg0HaHYJY5EkaVkEBeUTkxMdWsCYENNh/XaBe1IxssnhxoA95PKSzu8MIz7w4PgpHntW+U9u5a7T10WKXQMNBaO3WXL3oM/GSwaEHqsdhsiwkY01JEuWqOomg0FAdqNDNNSZA0uFycxB2DoTCaoG5EaITQJYWamLDGrxaS2y+TNVkcbSuUaOzFqFsIMmoVDEmi9yI4HbL0+lCkZ/XebkjLvbgXtnc4B8CwkIQekoHjGAHSAixVkVjzjAk6RgK+4qhKuuL4azrqW4uT+s3n712d6DjXu2JjXeeAWBGr5eWJirA/tiYmnuYFES0Ix9ExhHx4nuhEvURyIf1NViAATzvl0bJPnwbvgsd/qef/weuD47NPLuEYqWs4HZjNFhJ6+JyFE0ReBKYE65TBolIsDJrEeiyxWMdj42cDOR6cYZ47gOPginalVusbY3pNXVW8zx4+fwD0TR6APCP8ldwAQfl8KarBIKQQdFqQgXoKNaYD4IexK1x8Qr9VSMG3Zf8zakLsl940btKlKiAPIEcPHLp9+8NHZu7I3GXv3Hp4Va++qSV5Wfu0z5nOWvM+2kvaMW2dtnn9+pTKwUACrQD7rexOj+bQB6/H+mQx/XRrGPMNCaupBOWBKhbS7yVgzCeiHg2M1S5EzF4GqjCdmxQMOg9ELy67rKf/pkmkJE70OSj1wVQcExXx0Xv0A9v2H43xMaxfz8pb+kAu6NbRf5Z/8Yv2q/Y75qH2zcd2tNMWUzvrRhIk0f/Gd/SPzBAihygmhoYLbcbmXlHIcBUWpaUVCl4jU1KamlsdSU3lLBYZgUBlOThorV0ZhYXQ2HGxzHIcvL8pRm4oeSBIZhYb1Esq9FYfFbf6YKQAuCuocwZdhwCcIXOUysWZ9I+VY9oOK5y0N/pD3bcL+/ct7X7X/UfPZPQdPHb3umUPjhicWVjRUXu2becu7Wa2z27j9pWRZ0APMKZ0RZr2ye/aVe03uT9IOf4OMGnfXzmsfTZQakbdUrtx3Z+dDwLnlqd1jH3I/3a6F5FJFBHVYRXy7xGFoLMwKxAoFDxGJlScgqfPuSMpKSxcAzR/Lt3BOqoizmBhIU2TrP3/tAboQoioXwOcDCzTQZrQ3nKOojIqjoHkaAfo7V0mD+k3aN7X2vXPXu0XDufmTV25b3uXTl03zp2/fnVhp8LnyvILiksL8kuCZRkZIAANowAKPIttP7908QrV58M5j3/y0ePaH5upLHDb3LtWz554trj4aT3XOhhjTGeijkfCY3Sa1YAfepV+1emQPFxWNhtgA0afL7064qMFpSYiGJ1GI1UTMSqxJjPpxYaD3ZpoPr1AwEEySa49mkyfSSSnZkH54WMINXqp9kc8rlHBH9r1pEQteRDlZBF69Om8Fb1wRLO4sj0PJoNOibwtEZsn2BLGONnEwnAeTzgyXekcq9hsbHpmCsHm5HoDVRGvN9NBKJJSo6DpwmcU1kgpqMvQ70nphibdSFURR6wHdjG3nqO4MPyHeDNsXhIKaR6+BqhoqvGVJrle3BnTOMDJJJcB8td/fJd6Rloy96FNm3ZMWSc/Zz2zPhHXOD79We+KPbxVGDrxxfc/ujRpqmXpCfuizrFwprKrEaToddETED4kYSbKwh4zAAaWpljKwhMGowHZCpplAQxiE1az6XwoELdQJQGVfGnt8W1aZ7oYKrg/kH1ESMo6Jgl8Tg/c+9Iy7CFp2mzkWCNr4Tmjka6KGFUKqrpkcBL8tEaDqJBViD0LA5XM3rtShyp5B5lB6kgcN/IAxo1sg5/bGe7rqhhWkJOBMmfheQNAMz1EijAYSAstkl59iEhiCi0e8xA3hKhXFdgdaE5PiHymVmt7AVjk4qBFAd5XUPcjXR7tlffU9Mwy8gJ6Xuz5hEB0CgcQrhQvCOgmiaYZRpQozsBBTQgfzPCm2FUq8j8Tl4ax8sH6hGTMEpYEMLImlQ7aaGOe0caBcm0Rmn47+xJ5dSsaeruVHBvdQY5uwLOCZrpAGqzQeWcImjYyjE0VDFaTiOiAq21QmeSKW2urpHnx8aatHFBPQf06gHba87Xa8/BL8nqs1v4NUlc3WBG8JnDvX8K+Wr9wnigIZrj8lIngabgqRiPHsRZWkgmKN9FGIFAWKzoT8Owle2qOhghpDkxekQ40gBYGnQojgP+HyHGg9yWtN5h+V22Jtlpbcwl8oPW+RHUiQXRR9GMcG7eNvkCeJVdg2kZA2qZh3w36D/B8cAaDkWApGrpwosjzFtIiyVDO4erxooj8GZWj9c63+G3WTUmLQSDoxMXoI0drzz4PdmqzXgbNQO4r2izQfszeLPCM1olsRgraULA/+qs2EOOcoLtJHe9UJNqHA0azmaUtMDoHInJvTSzHVkd4jhLNNHRpSRrPb7vJlPt42TQ28jr0eRwC9YamkS9oGrhLx0FFcnr9D4yECggDXJPzMWyXNCirIs8Y4DEy8PDZBpqH8mrmVVaEvpyYLLI6DY0frsSfqkPkBAzkk9oN8CKCyflMu0GXr617Kw7vQj2qn5dqhC2DY6N2Yb+BsdhsolWWRYZS7SaqGsZxrNWGei7ReHSKqAgl36k0vPeG8YUfT1XUQXT020KEzaqNw9isUFshdFYwNY7OGvPqAbEd0rAe35tAGoysSBDQybBZWcrhRECFFgshcaIK/zbWOq1nK29CQyAG3BOqnzWIY4ruCMGnduzIrkc61G7cG8PvQXg+AYUkYnA3SZi0DpTZMxtkihJoaGrsdtpAOV0kIzDVEVmAsawo0JTRYbUZdYzapJ7TppNPAMuhkSL60rQG+PZAh61dNX6hjNaGWjh6DUKu9Yu/fh1bHfCzZrf4dADbejwjF9ErnAWcnCzTViOUF4vVSbk9iqTSMCLkaCtUe7QVirZL5LHQJBN2M8rQKiXokTGdceCjMSOnT43U1o4ZNT1YGAc/AoXau7JHR0DKcb5/jtFRkHR85dkYy7cg7EBIvgZO5KwKZcZpFKiJDaI1BubbqhHkTWw6QBBPa8JgKzVJaL7UeITmG71I+r9sEc1lOsd6910YE6In8gtvfA39wn9A/8gHrcGIcGHA4WAFo1FifUSa3Q6VS0amg5WgBAcks1nywQ9KUVKqIwpNuW/SXyCH/mIfsWjrrcKo/glVSNgcbgSVGsfPAKjBNh/Qi6surv/tF37uYnmHfYRw7VPwdd0vpg1ba1YUae+vW20mu5rXvnvHNFAMWixfXN66ddEoCygCraNdK7/8ZMAg6p6rv37xA/J3AeRrH8YMwXzZRNECzZ3DwnIpPh9ngXwRvIOvjKQ7ZBm6uazD6HYH0A2wEUqM0f5/4QvEfB8ygBqh02LctQYYCVaNlSaBD9asGLnS+dBw7ak3v+L8N+RH7AtY21fnwOlTwpL5c9bQ4I9nzg/u2/wGASyA+LZtu9ZF0//9XfSsc/XhHY9tI/S90l7Fe+UnslD/a7rbbZQtFsVIM34iw+UiGCOdneM2KsbqSLoiCIoffrB2e6A6YqdZH4LrRrDioUv/k7WGm6bDnP3Pfevy8Iw733vP8rcbN2WqoF0BQQluX+rfbB/aP+0C3r9U6LlPDbe0y7KQSRAuwWRmOT8M08wCnZVNiC6o1TNdiuJi4YfF6w1WRryS2RI2WixUFRrAifU9ymr9f3Mc306WgXyn/88N7a/9ulK7R/rrHf3Krn0AMnPAx0039SYzYPBMBfZzayZ1DteSAmCNzdfwM5mASMtm3A2wNTBeKPMf+PNfJH5erz1NQ7Wn6bmsp0Ht6QFoqw/iO4h+4VwixW1HIBC+FKirU0wOOi1IqG63Wh1xu31Oymx2cJxQHeEcyYnb0M1TQRgF1k7A6JZNjtvTA3onKL48Zbn/R9qbgEdRZQvAde+tqt6X6u7qLel0Op0VyNokIUFII6vIEsLaQACRfd9X2RUEBEQUBJFdRUQQiBhFwWXEBRccHXVGfajz1NFxXOfpKHTlP/dWdacTwP+9/5dP6E66655z7tnvuefgu/6Dcm7/afcTP3Q41WbjzIdPKP9SPup3Tjsp6NcXf+pUvvzlWeWbe7fdnVHf/9vP33+H9RhWjwxmlzIcXmVzrKq5MDc8WhjKcOl1gQxdhsx5XeAygoXLzgnRygwIXb1ywE2PceWrjnEjV/UGbXHF9VqnuW3VngCJlKCb4wfN+fNm7Tx36/YZL922sqFByw0Oyv0C4ZH7v1nCjnSfeWrFqXolMyVHeFu2W/mZ1kwqtKaK2czO0SCyu2TZ43HaHQ6f3muHYMZOHCaDCALtkWlccz6S7EhLL/A4tBPIqwYDVDjSUEitMiITlReTswH6xnrmdsIPPPrs0Q13pI4HuB0Vozz0qVomxWhsUl7jXwEae7ie0VzeaXLKHhBL7JZlr88JXpXTZrDSe3DgVBncWK6LYa1D0Pm2yb4KCaHSups5wacysv7zLWAksU3LlfUdo72nD6GtOiu7Vobb4beOvKi8hirJU0of5e3dvS2rDDPgm3rUndY/UfjuAh5ow+jWK5ot2e1EBD9d5/EYidHrY2GgqOeJJBGLxUXnpVzNwaldOzUKJjOpLbJoyZTq//yo1Rzs3JSSW/1BuV/ZoFYbeFAehe0cwGZltOsfzec8FoPHYLSKomSUvD6OcxldYGJc6RbaxNOCLBajzWQzylp4Vd8yM1bV0uUQtAnLzZCqs9fQEue0qcsXKb6GBvRVw6WXT72ZtXJI75NPoodp8pGlX4VLyq937NDy0SrP2bju0TAEWtRjNEKUaREtdomFMwZs0hHRgS3ggeDExOUWPeZbaExnODULTcjYDas0ku2j8d+uFGoBh3EqjV7jX2N+e/9oG50ei3pgX4vFagQv8TqJ6LrrJKKT++hJzUSzCjsWEs8Fkpx58eimzUAejRisiC6Zi6Y+fCnz4aPgP+udLhe22ex6u+xmDeHNelrIyI2OORw2vebDa3USLcrQtEE7rfx4Gkx9vaHZjb+3YR/qnOrG/35GmaTqZvDjmZ/qprMCOTdE/3aI8NwGj5enbWV4k95tM1kHxCwmoMObV3f9b9GIU/NK6a40d+OkDvyyg9OaG3JSB/7yeWUSTkP9RyT80VUafwS4QdE2DiCF0SAHwPhinJ6WJttJRlA2ChaLZDRin0TsDpx2FZs4Wk3saeE3w8Y4K3X0siEpRk6tQ24la5HLmKergExFuYfWP1ydy+/719Pp+f6w4enPVjBWIuOQLRC+d6rSG51+bKHy3pXdQnfFM2D78Pke9A3jLjpz8TWW5/dyfaN5VpPJrBMlLwgexhCLSGbi8wt6vctiM8sSp5OxO0V5tRzAeA3ArzGGEWAevSnjqlGME5gGax7ImNrhV9ViYL+RiZ0HUn+8f4r93+PIpdkZiOb7q9YcW4VczEk+XpfSh4v1rGd9tbrRz+Kd/2I9B0tYz8G3GyIdbaSFr6A+u157Np0vx6nz5QiWhVyCOaekPj9lvpy6xtLEGtyUH+jtTIIraZvCxqY/N5RHbKTVd6hP8hjzae7kEjPDGlnP38Nc82zEPdpsRMDRxfqHmdkkn/802DzNkxSv1VsR7zSqNEkDRI0Zuc2dFeGzE+Gz44XhdhEN4FL6q9tF7GfvJ9F71OJaey4agKi/1AfRwdqMBl5KA2Bxs9AKn2SvRvoMSgOkfSOLEgFlZrha3mlV6bw26cMl18Aoj16E5XLCqhfXimYX6BrMj0uugVEBvQbL5eWoflxyDTaDiq3xirZGQWKNErqGs6gdyWm1Buu3ztb4Sl3jP9o3iugaYrs2JLtFz8m+8Pm1wirOT31FnoDEOJ0Gj8diJ3xautXlsoyJuVwS57RLdgjsOTp/J2UUJb0Jps25S3G2UwpmWsyuQjTlg7RpVQvfUP4zJFEbVIMar7zP65XKt75f8a1r/5m+yg/7192x7R60efdDymzTxyfXXJyv4rcE7G4X2i8ZD0yZGTUqMTMKb+AwyBv1jW3UlwYzo2/BZ2pfu7pEXztDreZJ21jvdKm5q13y2WuTc/NS9lhme+zUnp5Cf/X5S5N985J7LEvqNyxCiz2eoPKqg57ZtOLVAJPXNJ/ItVqD9fJm8lrXkleDjFcDaS2+kdpXgHbJ7httK9tsottq5UTO65Nto2M2ub+8Qt4i83RKCjEYHKy5gHl067nlrY1x6+YCmU4IGJ00WGzVTkDhUNgVv8e0Z8s9D5jwDHfr9gFX7kTv/eNbvvKzf6DX1J4BWr9y1pvKR6f7ue120WOzAcz+NDftBuoG18HtBmidtCMYMV81ufya0CbveDsQbb+rgQux7U2X//WPX+P/+Pd3ivveLYb4k7ot927YasE9zetxhvK9cgllg3PqQT7lm3jVMy898xIZ9tjjjz/GtdhDOus5dQ95EhRyecK12pEWe8jvTN1DnoQk+AYKBlK/kZhny3jxE20NWbtDH1bv3Tc1hIIua4vvsJ7HjBfj6hq/a7yYQ3mRhEO6lmuocx9HJeY+psiSG2QJebypcx+TPR/rEj0fk7Lkltinm3s+Jp+9NvFsgD+SkKV0ioDk156eQiP1+UsTz2+WpXQKP/JrK7SCf3dyjX6oMrFGJl1jsjt4nTUSfSt1eA/KSX6HrjI03Ze6CvsOy4EyXD7QcLElvuOj6xg9sq71Oiw/yfbiVxWX7xLfoKvoPbJkaKGXPwV/ldaWG2iPCQ4TIugEndFEw0SR0GN3Ohey+RBMq+9mFTc52pmUHEJ7N57YSYum99EsMquO5uisFXg2rSNnzyYCRFGcnjOaDBgEySbq9WRATC9f+9koeeRFy8bnHbwjedylzRlgs60YbT5qLQsZTBbS/YK7FW1Yz3JGm8stZSEoqdKj97SgTSXs2QitFq9MtNkkjudlo+TBEvGnEafLOSbG2VzITMByud2+0TE3kSDikRx6iHX06dfqcpuaK0oJetQTPntIjWY7IbVinlEWHVJGxpSvOt5U1n3p9EdZ1T7+9zalWvlv5UP7Pse9C/Et2/AAVo++FOD1s9z0SIjFHA4X0em8FhfHuwBe0e1xg+ryeFw+H2yAz+bSsRZDLtlkhxcnY6arAb4OtFpZ/9UAqyX+A5WvIjeVdl4+OlHqr+zUgN26JFnznw2wvsnq7XpH8xw2p8nk9nhlzuUCD0Byejg+PU32Omy85HbS1pJ6sBHpyTIrT0rCSG0JqF4fEVJPi3PzUg6i3Pyb+1Z2vKm6U3nXXDpfSjseQ33UQ7OGPgfn3WPfJ99QkznkZmxTz8niTezsbNksCu8ygHcc6+3WNxr+Y3htkkz0jKT/V5CLEEkFedzWRQByh6rq7BnnlY9eRKuUra+AcTC/pmxF3Ybcv+xegLhLWc6IR1FRi7O00qXa+aM6SxCs8eBoW7NosBkgBkSYcDpJstOqTKzjnQ6DaLECvxKOHlDaid7UPLO+9WlFM+CsnpGOPKQ8Sk8gETsoVQ8hV6BRyiF0+E31GPKwcgCNVlaqR5Gv3B+/i51DzrsfVzG6Aoy1bD7EiGjQziOkAx0hmcxGi0Ey6EEf6c0SAGlHgijQmhJzzGIURWLS2zgi/zGgyTacpSWhJIQJmMk65RNK01rlDVSinNfo+jKqUF5Fg+jZJPryHvQiJajS+R7Fz/LIM7QZZGCr6AQeMyfYbKDSXDIvUW/VIBqs9PiWns1d3apVbZPRGUXYLZ+s7EpXCBRcljhj4Sdbke+c0v47Jf486vWLct9j6N5lf5qB8e9n/vKigp33aP72l9pZS08Giwls0ONMN2VzXaNhv2zH2JepN5kyZZKTKwQcgTExbxb8b/Aa7FaHk1ZR0hZYVc1DxLRKm2SvYbW1Puszpdbc5Ja3z+6ItJb7FFY880DnLl2qD6zd9WR00J8fexbpv56rdJ4wbumyJTuPC92vFN0xf95a9I5S+vYzW7b85aUXv1L6L7tr3UpUuIfBfAvAPE14gwtybWgf0EyBs9vNuW6fL1cgbduB1+PBen1+bcyktzvDmKbfOexO6ZScyLm1hj0npdFGJE9qhUlunoaBnWJQXnnojnl3LL1pQhbGBzpGGTIT1+UqF7v0HDjgQM+udx8CGSxA6ch/Y91stP/yI+vmJlDqNwRt/vDtz/6M9r6nyhcP+BwTYoDN4GhhGy5bTDM7XS4QtCAntm1nyAxmBsfE6MGJl3htsBXONm0IyQNRax4L2Nx16qo0OLCLVvCvXnlogVPr2xF8zZk7jrx028Tl67QNum/99oO51StXjp/Sb05bfuLyeS/uXbYr6Dm2oXmLnn/ljkX3Tlk8bm6v/io+BsDnKKsFAnyMJt6e68kIBj12F2cSC9o46UCx2hjEVRlhS9hfGwu7jUaLRVcbs9j/d/iglLsMjlByyptHS0QmtqsIIX2ir1wRuvnwW1snrl9lMFd36lgFiK3fYDHsRz8n+sYhvHc57RRnmzb29tGz16uYPXhoykgA1g7+x9OwP1ncoGg7m93gDmZmZgUCbh9vF8LZPrXRoSA4M7OyAqNjWQ4bxKRmeh7ZjE7qpYXWUSf6gxsqAe2GzowPX7j6PsqDD+1s2IFuWbml1f0Tz7H176nFtYibCLB3Z32Kh0QLnS6Ln7pmHOfPMLgA9gyjgU16MQoeVoBVG/PYqbM2ICbIqRVLV9+2ibQY4x3+wxsm5K2FB9e8/mLrmyR3bVlDHbFflq6+6vKIbe8Gmn0APjrBzoVujGYafWl6n17i6MyxLI6z+XzGMTEfyXDZXEB8Gz1EbFEDmOwmlrhkmeB4oGaLacXOkCbnvO3AXTu3b3sy4K6Zu6g83ZlZXZWXWYH+WXNjlxrSTSl9p/H586SnMkg5pjy12ni7rsteJOO/XilatXj+HYzvbQDvVtYLtCaaieyOkM/vD9n1fFbY5xPtdjQgZrfJJtFUG8tglYst4W3Rt6T1qIJWqqgcDzue74pOvqV5WsHfq1SB3XonHVbw3ufjEsMK4lVr5yVE9Zk3KJyTAc5FTOf3j7Y16nw+8IzoUQVxQKhqGRNzO+lhRa2I9olPiFiURInoeUK0aivQ/InhMS3n7rQ8rmgNcLXy54MHUVFC8W/b2JyAT9X3z2o1T3TO6ELmg94Uzb0KxtqY2y0CPYtFpIGnzl3UwPu/Q9dWudTQgEINmibfvl1NxNPEfLyqWXWfeyUxI7o/mxHdJhkb59NcIg4z2N20vxHQV+ZuiAZoAaBstsk2t8dicWCHYUzM4RQQRto921Y8kFoYqFYctQIV3aesIs8qq8ZPnjLxydfOnnuDlh5d+WnHujt3oiNK9zff+4DV0aVpczUYDBjiDafR4rS4PeCtcXbQtXY3EEwekFoxeC0YnEkIOqGI1ilGCqWRfOX8/OXLFz35z3Nnv1HO89Vr4vG9e/bsPf/18198eQ7najOuAIb1wnDVDmQSj0Gy5+Tm2tNFAwE7IPoDfnAu/H6OHYdJkoXPgVg2rA3MToy7bTXlM9UOCFnZtLMFreClCodvrvvsiGStADTT6RF5PP475Yuj27esn/+3jbCDPU5GHlq67oHHn+zZ8/XnT+1GZP5DMeWy68tnVh50Zd23aPKhEYeOdbp91uyJ82dvmrV84QZk7/vsPtjn44BPF7rPZAKnnpMOZTPT07kO0QCy2z36dIcjQx+Q/aNjcrp6VNp6cHrbVL10zRPS5nrdFiPU1WPSD3bc0zHa7sbbrnFQ+nv15l3WffZ7Oe2sdCgfgP2nsPnMafSKT5qTD2SkmQfE0mwShHCSG+tYdIFbBmzJvkRCIiyjh3utD0n5gPJVp2i7bpXVV5+TrlI+tO62dx3Al7U+KVXj5wnKMn42k5/2qk/K4s3e8H5Q85kAy9WrMTqdddDIZs4NZ/mAw8oKEm66wLm4UNQpCVar8RICpyKKatEYxCM7V/xGfX0ZdeepJlVtktYQuTzCDFJ4Ym5JJG/cjT0n9uqqrCiuKCqqKC4dXG8aNcpUP5jm89AhoR/JE58FH93Dhbn8qFs2GGw2go6T70kTISRqsPQiaaFGVAeK/I229bO1q+pqLTkTlMqU17qU1+hQUWZWUVFWZtEXiRdzCuFFSWZmoTgzs7BQ/aH673H6Gn5H8X5X6Id/F6/QuRMnOJEt/QZtH+WBP+HKPPiDf98N/z2xkP69W7wyJPkf9ZuxC75/WsMpK+o0tEbHJqeg0xKXVPixByArKQ5nFhIAuaQ4lFUkTs8qLAQ8KLj0Z0WMhieBhj5tvTRKQx/x/vGif7L/qeW6cioMwJZ4MVCmpIRSJjNUTEn3yszmxVVgiorQDOUeoNdLwCfGpmOcjrOe5ng7j3mOsgYNlt0Rmar90jkTHzxSN2LKlP2b4fNvC8OwIh6GEMd0giAG1puUvkBX5f4dO0Tu8OHDdB86CrVkq7gG7Hxm1CKlc6Z0+GPzII+2J/XqHT61DxQtTtLlqncMNA+1fV6lhhL1US+k51anTa+7sWxQUX5lJn0zbUDnstqKolKxKjcn6u6Vu6hLXcduVcXsTf6CLnXtb64poHC8BPQ1iisAP+m0jQ9S/DQAEt3t3DLePXvSA0eFfiMnTd+3Fb7zMtBEbPqKEzj9CcQDOaiI5FVGdETccvLklpPKioaGBg6jJ+Bzgaaf4NlOzvGUThcliEgmrjgC2BWr6Qbq7wkp+0MCR/ZMnNfEJXambtOBKZNHmrVNaQ0vCRKwfyqR69VNp8330EuP7Z44R+h39/7pk0Y2NSW+Yxf5dykPoyC8P8aeYePcUYNJfY5efVDZm/VlzY8Kaf/iCUd3T5ir9FYfvOXA9PGj2dOpmuFGCh352boCeFoa15arBI1i9xFSXFyACpzl5YbaMApzxfXUGP6p/ioRzwPWyK3URslRLSNoDVSytA3XpYzUxi8sj8VWLh/RsWhY3bD0RZX5+dU35OZUK++mw/vi6pHLlo+ILV9cnZ17Q3V+bgexLrZ82fDhy7zDBg0r6ZjfoSovr6pDfscSeOtdNjy2fHksv0N1LvwMaDJb6EhGajjIUaOvGPbKWWtABgr5n+rL/hhmdAzgWn7biOqSIYOGpS3skE8fnFtNAaC/oAC0q8nvQH/eQc3HvgB7YBZ3cRLnBRHmeYONFj1rrEf1Ls3tsbVodk9WvQdiHjo0yzNunDFUkivuKhs2wTgB9dlgLqwsa6HTaT85J7YKwiUeAuMoX8uP4XneYWScV6/qdKCyHC6nHd8icsI3IeGNE/t1HJcXKcmdOOGIPHKkZVy/0tLykpJyVp8FuuAQ6IJPgO+tTxKgGWaqAEgjSKHySDkxKk9/FFZemfK2JiP6a8qIfktDw5YGVUZS9Yv9KZ4jdsrQXDHjwYR8ECPlurot+6ZMGaHyL3znGPuOjfNF6b0Gk/pNG22b96bGY4mvh7R/8QT6GHT6sQcTD4O/pg4HGF6D5+Gm/8DzzA1RhJCgajgklFfm5cg6gpW/bz6CMrYoJyO17k8jfXwtZOoig6kV/zhpBZCvVod0zfzzB3xNgmnDBg0p6zDituWxoSsXAlNWdyjIBwauaUeZlfIQZdaqPJV/YH1tr2H9v7K9eRng0Yungd6mEzxK2rVUkgv9KMmTOmQdfFZ6krIdwZr5qGdVNomtFNfRvaS4qnsEa73J1tZ0N7x/m+G+RVhKOgHu1EbZT8tUdGwGxmytLGALkdmiisyI20BcCjpU5zWLC0VVFRWMPcoKfLrpO/ZsT9Rs42QUlffJWDYQtgI1ssJ1jB32FKsuQTGYNqpBC8eyt8zKJUwsJ6AqwG+btgZoKq4jlxeVI2lpVVwIRUP7QjhUKBtseQYCS7I+fm8kXBXhf+Gq5FzPhalKeC5fwgtmfecWqfAWod6JH+GSzFARRWMMgK19vijVqfle+xnzGqiNIGgI4DMf8CGMGwNR2GPk5Hwo6tvnwz6LTiMcUzICxEeV16EfGoJ6VbJFUnyFA9OnR5upqJqllDWprQuC/pFYoOnhAiga2BfAAc3usVXV/FMYVg5ff+2XZ6JeUw+0Xl35ds706XNOtgYAAZ8cAj65EfZQf4KxRkvOa2YF5Sfty6z2Gh0CnVbQ1I3tvbWBOqj0y5E/8kPRoYTL9lUSrH9rPltWkiTU/wWaFCT5CvYhLclQKQtdzcN/4PRmqet8lWCUecUMlMxilbPVxemHjlM2YRwO8t7kA/ldA/xgbiA6UHBUJ8GSNPf+EuqpPL1sSop+XwN7KD6BueLmTcKlM1DPKcqh+VOmzKe0Frz4tNBI8YpaSX/DCsNew9sGnlOtZf01SK/CKEwKlqpiR5/xMPjRPZgfTgyNaCDon+t+75fE9whaCDQd1PSDRtO0qEW22dLSVKJqKqHMoXJ2yrM813mNFibk7MEE9fYlXozRBOsmVVeU9Gp2yyn8eDY+TawAh/U04QwlBmxQqXo1CpTr8NlwYSF4+4X0u8XAq3vYfuhPcFjlVQiqcPFM5dClS6p/0ItfTNYIfeAz0pOYCGAa4XMsr6AeUaJeuGP8ZaHPu0yf9yRG4QR8xP4UB9pXDwo4sRHJPRZOTKFr+5Qx+KTuA/is8zRHCC8gsJnFalWveo8S+3YqYwwLf1mv4il0gb3+DPAE3inW/KHrbtTWxEZp3/3/sscY/QCC+RFfBTDqQJOYIeLQEWLQI14AF7UfV3O+LJIyN56moght5/nDP//5Tzock1jp33R90QPrn2Y6gRiuqRPU3REn0MWz6O4wuJUpoEv0/wtd0piiSxCAxpHD/AXQuu2jRtFqtlltkp3XdTGiQVyM41Ff+I2ZvbZRNFIzbKzKvn1nxJIuViSz8+Z+3e7Zf+TEzX0z0YH4w/iH0xeGH7lh4574d0dgrU0gB52a9nAGkFUdlVUh7AGHrhIElnRqcE63n0RPvLnP5do3Vc1l2MFRfwZg83G9oxlWn4UzYWQxCyLinC4XJ5r5NL8JW6l5cJ0B4AT4Tl/WA6aqqtXwKzXvwg5MnRFU4QQHw4pZIw2sI2FnZ1zZ5+/ope3p7nMe4w23TkSTvo7/0LY8x1f70qCsziP78hfi2+5C+NJHU49un6CE8ZtyzYSVynS05aFtsaAKK9CRX8boWBU16TmDSRQNkh1xZxjtEOp7SjQajOo7A6Nki6mGjirWODKU6faBcxsqD9EBqsvQYuT67o7L7+AftzXyoSPfKj/EPzpyBOedVuvigefIJ7BmGheNuvQunUv0W6w6UbQG0vUuV5rOehYWSuP8bNE0SptEnW7KVWRH1brn6dSNDOxx0uyzDYUrO+MalFeEaSlcwy2Tu1W1P3Z69qC+Ze7Qs1nhHgvG32gpKOtUtY6/EOx+12dxEf1HvmHBsobTpzcNDTgix+/scETrOdgDYNNx7Z6CDeOoLIAgnNIRnpxJ8pZGhUQdt9rFkKpvcrQx3pW37QKsj7Czv6XwvDp4HvUPyqNWI4cEnkeSHWOTgCieJk5lWVMqns1oskdH1MG0IUpnCfV6+mlibLzvKaUQ/QXoTAJX/o7fabyfklmVKSMs/BJb0/ckwRgU2jPwcEJ3ryapfSJSGBuffpq/cJnWfKBhgOoe/hPOylVEXRad3oyQ3m7DZguHLFZ4bX0G9eH07BEUvgRnNoOJ5DwrZrfoKipzysme6R2LXI0DblGO8L5zOcGKm6viw/GeKbdnzj3LeGAN0KUPwGjhCqNGQbSYzaLNahEpRXRAYkoRXZIiqb0nWddUoDbluDDZtq1R+bkRvQJ0eBq/c3rX5Uv8BcpupXQNWnM6nL/EBbiOUbPVLxK/k5BghlvqomoGN6BEd5PTtoBD/Zt7xTenFbNyWSm6Os9D7aJRznoRynYs4j4/v9fYft7k5Zujw6ZOGN1v/foHb57ypet/kAe/G4+s39ltzKufX3yhyxOdFsRfV+LK3zbR/cE9tP1JixrZBtmoFWmk+L5Zf/UOxbW6hjGghz6C75m43NPAmkA04KAB1IVoSS+NXDQkaWYb8hFlmfVMNJUVfB0wzDfKd+y5R2EvgvBciepSC6EDgp0Oq0XTpVbKO9qWkNa6VC36K0DlIRrVaotJfDD+pvI86nb29FPPKc+iKI7gQfGjR979S95f3j0SP6rOI3+XzxNXga6silpAcfMWo86ic0icvYsB1XJGwIYuaITF9ai31jY0ktoEtrQkpyLbUd4+zAoLMiU7RBfmc8hx9zeK9WnUB21V6pRtB3p+yDWt/QiPUXorDygfK87VIJMJ3hNZlwCjHgwt4qw2nLAeGBZFsKyqAa+BcQGSmCRKTN3xfa5UMg688j0eBgqPMiCqu7I+qe+sbL1LnJ8bGpUF2Ut4j9ttl3Q8L9HqGa/g7mKDJSVq1DSjxQFrCtq+CkkQ2HRZtTNY8szDQeepozKHDzHty04UTAhsA50r5+mM8BMfvRB/GO1tN3rYkt3R2edXSO2d31yY3/sQf0m5pDwdX38EnX78woj/KG/Hf8G+fg3FaNWFRRNVPQLx4LX0yIBr6pHfWLybA8yzgtmTMuBt+ImBSHajQaOskVEWX01ZT5VKVxUFdrxM894rAPIDoX69nziyb1u3I9ixb0PHI7ELT2lz2MfCOnaIgLpHHbxdIsTlsqcZjXQUDy/w2ooCrGjhPOy1JSHfVw3LVItUKqhFh32V7VwoE0tIlFjGoDNinD2luqABl6L0K02c8ovy+z+Qrts9Dy7e2Hn3M3jNop/aH/lZ+XWY8oTyMipEPdELi5TPy795f8Tzrw57kt0H6dF0iR/F9F0ZQEsErDcYMIiVzYoFwlnOAM/rgbR9WWmP1KKTVmlJZWYlAvPvkCJ2zAs9kGuPsukC6rVp8fOvKl2V6Qci5JcrwyagI+h+pTj+78suWG8uyHgPtg+domYLb7KC2bFKdpO1EQ1qiJlMNoGqDpum+WwJ1dHiLgxzlJieZWpEAgMv4W5U1YLW/ee/lTrG6pef4OtO71IePoKPwbrzgdeHwLpurk/UIumsgt5tteq9HkEPC5+OCYJkMCT2xkCZnnOw11IKN7QsIGIuBkoCEMrkYINUjVNOdj98kkGC3kEWREDrjESHz53GR557hgGk/Kz8ow40z3vv0T2YDjSpBNhkauNMlFtFkEJREj1u2WRCdpGyN2Ls3dLZSLAII0QxioDPQV0NOs1Jh8c2Dl097q+bh7bTjZxUbpKf9ztfuwSK+sC8d1/bdemRuwZ4atct+4/y9fsftaMw9Ab6dGO6tmfUbTSZiF2UBOYSgM61iyIyCmAHTkkY4TMpYpJs2NFq1q4mNMAdrEUq8w75blf64wtXvv0CLevX3eI+J9sqJo5E0SN8KP57aM2aSx9t3Tw6W6lVe4mvAJr0YTLuBE6x2/ROBK6JnsguCFjMJlDG/TmecyY9H8zIk+KneKqSfWHCEqHVLaCIy+ksc9gxNKUxgsVfLyonlM/f+Wz+lvhPJHB5LL8HHTvxhvKlUrDo3VGo/8W1EzT7BrrjKvvW7w/sW+g69o25Q9S6IdATv/BHmC9eG5UhsPL5vGYPL0gOh+DxgiPOmRrRkNOgcD0S7z0LK3hAAw+G1TwJhoxc3eVBa9qt9uelrqezTH1tRHyIRFC/6YPM3nNBa83yNe5I4+vTfTUvRLMfUo4rJ78+i8d6l2xFPZTGPftGBEXlX2P+9mdsif+u/Fn56Db+L4wOeZp98nFdolarz6dDTr1O50zzO1wgRCdjeif1SC0IozNJe1XTXCuWwrSsiWEoIcJtkeSyqsoVHJkfzmEPcv3w9H2NeyD2Mdq712aD1/pP5ft4KaVf/BkaA5VOmpu8Y0XAFtjzBL4J9sauE3jW1LDV7+jP4Hf6JpT4He6h/U6vfU+vfg8Y+xgvkiD4AIQLRMExRrTUh0e4kdr7N1OiTrBmEVy5fv0/eBEvBZ59G76nsO/pwHt08IIo6OC7HNIhg15AovqEyJtlqa3mkk9ywv9o2Pr1X324YcNX9InxO/BSVRaA7n35aniqESKTLF7QiQYAFlS1kQg6kxkTI6mN0WuUBp1oQ4LW5Til7binuRIhFCYhNgnQhPi+RxYo8+cdR/ce7rF7BypXLvDV8TXoTSWi9iS4DOs+z+5xOrn50c4mnVVntxNedDqR0WqVEBLAJZN5QXDZYX2jpTZmMyLQHEa7EYlOg2iojYk2QUZWNl8o4cGye0O0JI3e02ibnIPiaC6GSoy1Vh0aADbRJz1ErTr/fPxp5YNtLyIF9OhaNFB5HG27cvFrL+qjNNC+2i9sUB5CN6O/qvdJtPtpXD5Xzt3AHYyOr84TdVnmqlJZ5qrSAwUOR6BKlyd06uyryK6ojZXKA2L51bWx/Pzi0prS/qXnSvlg6ejSLaV7S/nSqNvfq7TUkJWZ/Xb6pXTMpc9Kx0aSnp7tbkdoawmb2UALaURDYlxbolCSolovqQJbPztS3Lbt1f0mmgusyrFakafOamMt1QRdcxOuxJSt8hy1AX+AzpDVLrXgHKHh5ph9Q7dfFq/Pan/fLatWKacfifbq3VV32PnApid6Dt7/8KPkclVVdEzFkv4DiuJj6+qJssMwDHeV0NxRvQoRN2PJkhmH9igHBb7jupkDRkg7Nm3ciNJQtveNunGxHcNiPC4ZFz91bNdjD6r0HQw8Mh54xAXRTC43I9rJpNe7w6LosAbdbuTwWx3WvHzZ5OJctbGg3gZe0XGO2Li3uUscMYEf5sAOd23MIeMM1oi/VXn+7NYDnFMmxWot9GlGRheRw6wDMw3B2OwKquWRpB00DJ6Pjj/z/s2PbAwVnn9dKZuPCpB18YQZs5Wfvl88YcJiPBZ9uOfucT02ZNRH7rkffag8UVcXG4j+qpwYXFc3RKtL6sDuOPZg8vgQ4NyRyaOdy4eolNeDKZIcgpnOoeZBDHj5WtEIx9xzwvQdQMZ3VL4AP+AeNAPnP/34nxrPPPUULlT+pXwJQvg/rz955ZMLdK0MbS0T56U39ZwGQZJlZDALBsHnd7FmZZKNQ5SUBmyQa2MGGduvRcpI645pTMCcWogCoIVzVMjoWWNZRcY6CpcK4ToyDuD78UcK4Sz0evxnCiX68qbXn1ReBGG7QG3Dm8AMXzA4b4rmgiqlYxF4+LnZQtWATQQIwYkAZ53ChozNGuE6l7YS0p+QfPLFlX/gpviTODv+MR6XkHPVPp9q+pZ8CjKeTfsA8kR229IMWVlpGSY3EXNyM8wms4l2SvJyMgQ1jtqY187zYMZrY5w7pVD2+r3QtQ7g6rlV6NpFs/AP7vPIy4V7y18bM7t5DrNWL7t45weuZavaHRo14tXWhbKWLdPvP6r6PJOUGXxndj/HQrs9mcxmA616MxisNrNl4AhzukGk+0uL3rQdTrSoa9mTobnmDf6nGUH038rt5H1lOKpRLK++So5u3nzl881/fv55oN1JoB3tEW3n2kXdBBus2Co5GL1slEJgvdzanc8W3CxkEq15hgSGXHKJKK583X63bXS0/6jv0YFGFwrkjRs+aQ6+dWNc2Nug1it9q+oKkKPf1V4fwDOvsp54FdE0vdksIGS16QUT5g2gTw0IbJm5mVFYSaLW5UyzZcAgunJ6F75S1gGLvBpfuHBhw5kz6C9o7/i949EVZdbevXuVlXStWbB2PdNT0WhQjwWa9TS5rJJkt5tEYBkXxladTTIhdUhAhM5TTc15Jq+Ls1m+7JJ4SL0kTrM+NQg/t1+5Ih5D3n0VVlfJPmR5nAhky+6e8UEgzhdfWLrtUVxy+Tw+OkebRd0I8LgY7iVRtwlznMUIAiJYBKvNSCw2EZsZGDWtdF8kOWYoMWIITaCDhY6yoUKJQUKwUGKIUPLOIdNfdWwfNibq77DM+K6cK+V3kP+Ad+Gm01GsehehEwtFaWBM5EwDwQml+99y1EomL7t4UB3ts4XEATZIBR6P0pEb4vfv4xeRhIKfXnj74w/ev0j+kxjF/NwdD+7ZtPG+AxspDcq5qbDuf4E/WRz1EqPHbneJRt6fZuEGxiwgVuLAmJMeVGrNKlNH/am9RXW0ZDE7RGFhxdIUgqkfXpw0zbz7GRRETgoCG0F4lmTduX7MKttp+dOjf//+h0+1gYVbVjIbltP0Pv8IP4pzcH4ui4tFyzLkgJv3Znp1JNNuNlslvUDEcLac4Q7waU69YJV4oJVzYMxu54xpA2M6nTa6zlus1llSJvVUpTYaYNmQnMzs8vaVeeWeikim5NJ55Dwxr6wSUVScWTrECDiZjqIeO+/9Df+NS0ZMfu2OH1aNjL817OInqwfj0gFvl/3+3UsLxj3SOFBJe23uiEceH/CcB/292/oDG3Ffr5LR9a49myg+6bC/DaAP/VwO145bEe3Txgc6ypSWxhWE7PYCnY8vLMrI9eTWxvxtwCr7kc3f37/Cv8XPm4g/mp3Xy089Hb/fIDs97jBzbSym67g2zKehfURnX3WNJSUzqvkznoqUWayZUrnQfBEk4cDohw7o0s+6oebL0wMGPvXg4SMHzvQffEx5Ad/Xf8SIwUdG1SkNvYYQ5Vl9Le763CvMY3nqKcpvytfKVydO4Bpv3kcXL36EHn8nvvjxB5iTgrn3Qcf9yu6K5XA9ojmZFtnl59J0Oo6XXBYxN49I3oA3UBfzeo1+l80YHhAzuptz3tfoIM7mZmlaX63lqCwHVoxQdCSnvbmk49NNi2/fefH5Fy7uX7R4Y+OEkc+HPp82Z96M6bP56jWNXt79wqaXLv753KaXXHzgqVUr7kS6eFdkXr9m9V13slw0zuB7wz6aQSolUceZdWaLldMZWBszddy3/U9lrZLQsHaYjkaXyCYqa89RqcMZVBDZcPPP6HOBP3rjDNA98FzOIuosOqtNtBhpFKFh3uq56j5F1FvUKEoF+Dkq0jjj/Q8ufpKYnk5pfYHOAANaGxN3sjhkB8ZxyWYjtcE0iGcegHy9O1mh5kFfPpTw5FY0oLdO/teHjeB2WCcvmD+Frz517+4GbFWWjB8z6la6bhUw/vewrpmTuZujOeAOCUZYTBJkk8koGN0eCAW4ATGXC+v11gExvc2EWZjUcuRPakse1cWkF9VyJTrUUwr7klXRuEZ5+QIa9tuHb6MnGr5ZvWjqbXH0ulKBPogg4b7tl8+j19GPI+tH1at2PRW2G6NZJqNR0hngjUyIWUfcHjMAZDCbeWS08a4BSe9RC+Cual3PxlwB19lp8s2TAIl0bFBq3/7wN+XwBdTxSvy2qYtWf0O9tcvnt9+HhAj6QKlYBhDRezhgjnkv81/zog7M8zpB0BsEmeg4XWohe4qhdWrtXxvIOOVwg3IY2PfKTeQpsCUHgZe6UZtOFjC7VsMN4zeRsyBrhVGPgRPcbouD49PS/aDT/Q6D0TAwBsryao3uDGmHGOC4lFXKVpwQr1ANPjZ1QfuTe+KbyMDn2gjtqvrPqj/xRrwYWdqMjK3e3iAegQAdk84HF598SI1JvADDkwyGDNDntdG2oUAgK8PgZ8D4M4RwdjCrLpaRVhcLZgQzjP7rwKZdnGrbupMoui6oiDnPchgVoy8ZzMpgvDEF5l+Vrxvhv2tBjjofxIWaP1vTFOM38f/mCmhPSz4nR07nDIbMTK9kThfatvEWcAV1YJPhJ6G6WKakN+gHxgwt4L5qhFWCxBXXADsJfXni90DxBxc9sa+Z4HOHj506fczJC/Fi+pvj++Ob8G1DZs1de0rDoHr7tKVb0kmHvbMP3XdyyKwFa1R/rzvw2Trm78Wurj+H99vgfTv2vp7h/Szo6a/ZXZXaRE8Sg8fjtNiJ4E+jPUmo/HIS7UnCoh4xZZpPMnt+7fldKQ58y44kIh6see2L1+8qQRXxr/DXyiOHn1T99XHDp45djwo2rlNeJI/tUP10xP3Y9E/yEd+Hy+NWR2/m7YEMzunNNhiN2c4Mu5BfwOWBFLmiLieIsjfU3zXTtcJFAPqQLbAigI0kEAiF0mpjITtnmGWA9waDemsvGYyANW1+RUOSeqmqKjEY96oW5clpzCw3oBqjZFv9vOSVRfx8x0UTxw7aV34keGHHIy/uWtXqLTpaOyA65DHX5m3b183bJN6WeLdjLbxT8c5k9xH7cm258miaz5QfkvNtRGhXCC9NnMMe0NH5StlsQ1QN4kgdF9M8R6msgh6HJ/rFu8DNVwu6NQyKkc6KUPbQ+R2GhYYXZvX01W/tXf3S041/qu69td7XM6tweGhY1dxhQ5dUV1ZWLXZV1szNa58VXnNyxJ1d79m/d1vXDcNPrglntc+bW1PZc8TgwcN70ZzeCFAMtwFvCVwgaiXANqJOwANovK5ZosTRJFN05DZlWwNTcmy8Qyov476MFrS3I2E6NByVBBEjEdHZhANiOhsWE5YlZTKh2q+MJw1KMTz48nnaazjxbM1mOkShMjlH5kUmB51pnYbPBMGqw6kTRac/zYtMEPxZTSaHWVTnFkYiLcYLNqfSaFlMFpBZvaZFuxuq15/osBNs2fGvFY+fPHTioZOP3/btblQx7exCdKvyxgNP4BXxVY/tQ+2VBxefnaKwO1D0bnOA9fEujHo5J5YMkpPILgnoJ9l0EKLp3MkJiqk6PXSNnoBk0tX3XK7uBHj5PLWb29A3fBWb2WjhukUlwouCntPp9Dyx2uhpdSPq9VQMrCmvF4UzqB2tQ0dFf5T7RGrq04B08CKXPDpdGTbzHnTnbrRaKY4sREOW2hE4Msol8vmVDDL+PuV51CWPw02/ARzPAxw0D7ox6hFog2E7pwOe53mr1SUDO7mcFJqTYMbhn2gwZnMGncXOJidvMwQNxYYmA7jWToMTDKJDL+i7mFEvdgbYjkEMwR97z1Hor5ElTaZJHWpc0dwMrkVyVAYuI3ixcv/ae9C7+K/KLWiBsgE9E396+McJtOYpr89Rjs1Dd6MvlDRWnwgYk98ANwvsYICbFJVNeqffz1v1bo4DQmcETU6f00eRsmtIEcDEyQuCo4uxGQvOz17zCQxaZHVapVPY8R3L1YUy1du5iZyYs72aGiO/nXlUWYpGoCGDB8+c+/KkW95667XKf3z545yphL99O/n85/5LvdIaNKH/jcpbypdHlQPDmN0/BvsUYfNnaRw3Keo16jxpgmA3Z3o8yO40283hbLdRQhJFxxDL1CFkx3aPhocdYMdckL3GgFOLxhvXTUMmcmhqEjIxoFZIIKIhdmwURabHsxv6UMRG4cavAJkpFQwxvhDt/XnKjYu6Tb99O7rwCMUGyxQz5jvC1vFeNnfdQWsCbIIRVJjTJVo1qEWAVOBs2k4UXSPvSOU9pI6hTWQevfM+3KDsQjf8igybz50++tq+RvLFrq+WkM/j35w+F8fvgsw3AV/8D6xr4kZELYLBoCOgloxmCz0v7RV1xGxCUCgWmgTgazYLhtfgQUwODS35+aocHz0k1Dg4yb1cE/5b/BTOiX+EJ8PiCV4FWD6At28yWOqjVj3PmUSIIjgTAMNfCxiDQa8BY2DAoP8XYJIHZ85y1p2e/f8BngyA5ABAf0PfzEN1c1DFvCsZqh3cjT7mS4SPQF5qozYLpxOdXi/ofD4j6JYBoNMxtzuNpNnPsnXTUDGwJsBzKqbTkUZUyIZwcNeYsaIe9juuGrxRTuGhapTbffmLg6+1v71g05T9R0/vH7a3XPkc7ev12R1fKE3k05+QYe7SgkH93zjz9IeVkeMLlUf6jUROCu8nQL8fGP26Ra2JGVU80E9HlVbUEivW1ej66widzNRKkbKupa2baaU0BCW3KIZNm9CvW0DDQABEPldGoQManXAQfYMfh3VpnQZlEQE/Aw9H9NHNdRrwJPz45s10x+lWOdDHZCh8x85V0hqkRD5SpaWZwSZSWhJal1R8rdQkymqVmsQdfinZYKnr3LXfU6jb/ehjZPAOGj52DO45L97r7sNAn+9BxnyMPjdG/ZQ+RrDlnMlkQDxvtkAYqUM6Xn8VZa4uilQDRtarXaJmhkxT1i4A8rx0SJmI3gYS/a1eWQM08qMvldr4WxTfroD4SVhb4HJP06BV1KGzbB3SkmubHRRKeRl13YQ+pzS7cs88xpNbAYcb4Dl+rmvU67DabHaDXvbyHOf3y3aSls5bvBbQe+0aOINM7I30sZ7rpziR1L4GqV08wR3zsObzbk8NAlVHnjVgMeD4ddxlq10iK57kmgzphozLT8Be7xhS7/cvKoqPxIdCHTrsiU8GhVLnnRK6BR8DlmjmQzP4j5KIgNB0hitwosVqQgIAd1JHb94BaGVl10p8GjRI2BQD0luxCCv2of+Iq+CxFQfi04AYLw8aiTe2WMtC17IIGCOzCIoB6a02MxLpWnrhj9ZyJsbSs5H0n6wU0X/2rxQUK6V5fL71AOl4JQPfO7zXldfVGH8d6ITuoBNoTTroaYdoZl32DLakKioEOZDZa0IZ92o9TZMrbIwUl3otiO/e9NmlJuXzS1zT3ace2Hvy5IP7j5NPv1O+QY6fvkdm5efvnnmTivxF9S6DE71OnhH2g++YA9GjJ2D3uAkfBh9J53Tbxdw8pw5YxN+IbqK1BZm8JRNenoLYg+eKW94RvyrjRRNAiWmvWpyh5rw8qQngiQPHrhrYc8gtDx9//KExQ3vVrRwVu3Xu+Nmzb53Dn1g5a9qBtLRHFz/X8OSzSw8HPA/OWbDk1nsXbbvjzrsX3QuwEyDuj7BnRk4Cz9dsEwTRBFR0OG08U6s2m6jTWZ9jNNSBkIhMk1wzi6TNtaepJB21xaEy8mPDLuVfm9D9Dz+x6a+XEXqX37vpEWUF+Xz/pmeVVWwPPwQZCmi+0KCobEbI4AAm5SwWq4E3uD1m7MAMEAcdJyGdTbo/Sa1wdTYp5XSb+Z9SIr2lA69HPaskt/2qfLoJvfLwE0unIdvpvyjvosjoWaAtdikTyOf3r52+Q1YG45ceV3aNVu0PwEn+zfziwqgZnBgeY9BXvMA/l4QIa6ThUqvkUWI60tG7lEaSLgy7cg+ZMU/VHx+A3v0FninRuleLVeCtvNNh4c+2MOfF16h7TZkpojZXwLecfm/TqttW3rnpQ/Txa8fxovi2OzZuvROPi9/X8A677/9PoPPnsJabuykaMBoskl1AnMslWIhJdru9ZpPJ47IIdpmYqJxakJHJaSRSQy9eNRcMNHfxVTt90MCRqiwUcVJN5XR7nBHy0aFHzFYbPOyRQ8pv977uDTy89hFH9qsQWuAF7eoGBW6ti28AxXFi9nww+Du67SN9VTlyAT0+5X9md8GmRaVCCDky9fn5smwjpKRUbANiE3XGRJGTbNagtdhKbMRqlSTTGXQTqxorPeXN5rKZcGUGEoomdeawFtq3GrGmErQ9BMjJJjaUXRh9K2V21TlsRXms9g+iZJA79POsmbsOPdR3wIA+upWZSLdhU3q+0x1p16OjwBcvjt44udPaZWO7oI8XT1m0nJA2o/tV15jfun2Z0lhVJfQ39ek7pPfo6PQbOmPSf0BNV1WXfQu4N2q4j41KBZl6vctqKyTE5gLcC3QUd2OsoICTWqBclEC5AVCmOJdS81x2jUHLqRlNqlnUJECixEGkyU0pWc/s9kQ6I49W6MCOeP6qYdyvj3FlpvJbKsZtlnXpNrkjxZj/OYlxeTeKMeqlYTyw7+guM6qTGGNUCPju5X8CfsziekfNHtA6gYAkSuFs13OwcVZUwum5THTTyZhJfwawIhDtwBuOMA+EzTtkf9W06jui5mPYnLhI+8qITnJ5wrnlKOUCJAmFZw66azWyDpoVRrr5PD9fVNYPqJ80atTEkQPx+N41L55Hm7t0j/S4U2kzvkObAYjsX7/9wR133cXinRKwObthn/K59lxHbnc0vTxfpy+AWIfrmBEsdDqDlnBHfb7uhk5pHXI6NFKQCzzsn/xyuoWeWH5+sKC4oKaAFBSYQjlcBrKSjIwcwOpUCW/i6WesMbvFNFMbI6czsT29qrRFYm7itcpaUlpNqZM1WD7Kk0hKtdhz7UioUqtlB+ZWO+JX4ko8cVTtGGlqzv0z/9qzcvOtc+bsfuxgn7q6/sZVmcpPj3UdsEs5g1ffsXJit5oeU6riV0y31A+5VSCrzatvvzGSOXrwk7fWJXmhoqv5rbFj0X2SjEldv07du0y7YcPiGYtnJPlA5Dgvl831jFqCgt1u80HUn5PrTmd0c7jPAQFsqAw8URosZtEfCriZDWpSC91U5raHqMy6rFgOMwWpizDsW9z83av8NGhmmE4jW8AvIYTxxMoEG5Cpyuya7o68LC/pMJ4sVt6fBmzx+oObtu3dsfkuLhXuJP8GOPD/RLvGvxTe/9/8W876uF2ffwF8tORa7Lsl2h0cxxuurEvh300q3EGA+3HgXyebmGz3c/QsyuV06iyEHhhQ/jPH/FGDuZffb7TbPaqisaPSBlE0Gon61sisUkq3M2/LlH3q2JdEgjR11Mu+yeMobwV3zz505Mg+1G05cE9sokD63r4ZmGdE7NVXn3tdmSrdwpikGWbanXhm1O50iDrO5zObdQ46CtxJYbbHbI6go9gBJsHhsBlsbhVQGyqOWm1iUCwW4TcieKMaBgYqVKmZ39T4tAUaCZOgXUMDcdESp6SdikX0W4qE8mwCidUMiQaKA7C8igNCdYDDUsAhi5sbdfuJbLTbgpmZNo9opMfcosfr8aq091DaezzgADmYJbPbLaABokYuiGwkGOS4gIoB17wHFINmR/KaXeeaD0xpAjgxQjQiZyXT2Hj8qnsmDO41ZtOsv2fMkFbVdH3v077R9dnTMu5AHy+ZcvNEA9aN6TF85mnr+BvaLxmzKdp1XnDEMLV2M4FbmJsRdfPEJVv9hlDIn0HH/mbnBGgtEMXNFqNzhHqZzZzH5fJ4wJe7idXWlrL4EpzjMTwEf4kQM2VkJrNg10ErccIQLi8rb7lViQqhSXPvyJiWvT7a99P3utZEb9bNyPj77LvG9hg8YRv6eNiI4Lyu0U1jlrS/obzEenrm8J6jddgwqfeUJUzGubNgo37kglxbbkLUnmvjSaas1wcCwEvtCn1nwEY5uDAVa9lBZdzMFdA3BvMZlmAEnKIGQGoWjxla7ZNoNYt/a08kR8OoEwo3dywAS1ZRGbEhcPScqU05Jizf4Fzq39CIez5815ING/rNzcQ6PAeRHRlTh40aUjcmNu3spMGOGf+19N6Xzr1xrnf37JFEXh9/ev9+/Ohde+/au3ctqyfEuA33Nj7If6HV0BoEhETq3eoogpgGxSdHYJG5U+cTYXFCXcnhcjpwAh9cvHgx6rV4MXkwLuDLwBMdwF++D/SjiesS9UB8T8N7A4d4lgMx6hCQRP8cPF9AZc2ufE1yoKKjSqWImrEiKeG98NvwJUtQ17uVv6CO4K+P7Kv8yLvjc9EcpVHpq/rqy8HX7Qf8mAMWRbbq9YYcLpCezhlIbp5s9VohkniOsZ4D9syESk4GOEPC261Rc46tj7KQpNIdwMiLeGTVnHgiFYlhceovcdsO/fqNXELmCjh3fJ9Bt7hw192zxi/u0L/fCID0v6cOWzJX6YGHHRwT7te1x81bV2xWePrThQuUHkyOaoDfNgPcGeCj2z2S5DAAZRwkmOlJS7N0sTKY0wBmF2U8Zgx1Wua0vZbDrmnlDFA1nOjIdS0UZLL5XEGbtMLaG4cOnbiUAt5u+sClM9CWd4zzTJNw+bShSZBru6zYDCtlgKwfBxgNEK9BzG1nuVG3R0dviN3EYsRSgMvJXuNrxtz2kGbgWpjj40rDrsdQ76MPrBwxZdqYURNmjCaTlHkvvYY2vnyedrLffv82RqNqWH8brO/hukYtgig6HZzZYfb6bG6mLZ1OG+iPBkG4lqZXlWQLc9vywC45pIg4h469071c3j5z54GDu+bvtC41DbvxaTL1wTs3GmcseOPcCxfWzND3uYnO4yaTGD3MXNuopUW9SOryf1A0AntQTFFeSZEnkyiuFGeKK6M1mQTPLo7aRMEMlIZnc2YBY8OZFhSGp6dcFE0QOaJ6DSptVzbTFGj5QLN++4n5XuB2Bh0CyIoPtraV82UGfjMAj2nOF/8Hzpe2dl6YyUUxirgysHxt7+vRG3iyhKAFBFywrGlD1t+xctDwqSMS3tftYk/lMbJxnYx92W0cN9Wcu3Bg7Y4HdmzaAnRpQJeIV9jCZoRaTFarXuAEt2wVdSLjAZNBd5ZpLkdLLjwfaZkjoLMww1k0YxmpjMi0jIDZQuLt2GXb4OHZdXfemdXWX4h+kI6ieP2RI/VKsLKdgckp7Mtm0JcyVx01c7IFqCYb3B693IhKTlkkSVMvEixsTuYEWtxYbJ4qRN1TT5gGmOpQoaepJC7h5/G4zYxBS2fwXyjpMwYvmYueiR8+uLpPtxWb0RWm477FHvIZPwFgiEQteo6HmNDC8W6PDIam15MxAMpATw1OtKhSSK38SJQlVMrJYoRv0UW6ljIcdzu4um9X0E9evLUlPJp+/QT065dcLtcn6swIyByXS7WsITdA8vJz9QFKBj7Ll8XCUtlh9T2TpESkuYgtRU1pmZpUihQjlSRJyiTzHXi/pmV5hNuO7U3VbOakobPHMT3Lf6mkUz3L6DUmPLBzj5u79qNEoz9euADRGebIBrbpLOyfAaydjWDECQC8gInRpMfU5glqvjxS0/ook6Y5IJByRvBjW5X/WX2gxOp6ajX6Bl9WbI+074pDQJuP0SfkR9AHecCbksNtMPMkQPILAgZ3tpsD3VR6yifS/ncgR5maq5Nybo+KtfPGZt+mBuXlpp7aN3vVRSjPitGmyMC2N7TvXJnZfVJs5epVK3Paj41mtQ928nRsWxfJ69i+201lleiTcFldl4KhK2eMm7hw4YTCW7ovHVqUHagrC8vt6se0dYKMhEAXPAb22gWR7ZioDG6OIcuexnF2R4ZBKGjjoFU7LIMZDBKLJaeLgbG4Baw31QyE87KwLCW6qfmD5peINdiijRMkDTNdBtJmsdHeb1o4KsrksYfuWVrP80sf2HXnXTvGz43/mDv7hlvHLZg5tG/dzWOHE/3mPTdu/jPPHd61av6JGnnzlbTcGfUTZo5zjh3SrXbqIthHP+B1CvZaz3WIymAveL2eA43DcQYjzeKx8xHaoLA9Zc7E6UKSLcvUEcookoYiSMK5yr9Xv35htfKvs6gQ/x7fgBfEBeU9FlcxXQ30Az8d4kG36IV4ikvnHI6MdC+fGSJpciAQ1GxkAKgmcyoF5RQbmZIABm5IGIo8qxqxk6w8DyjTZCI4rzwEpqNn/3nrpo165Xik4oORXbJPbH/g+O69H6KfSEW/AwPbHJ696HYyWfxi3JRF3Q+caTy47nzV94PqWb7pE6DLD/wvYEczuQFRyZbB8w5B8FoMIBWhLDntOQ06qv1LT2U4RAfjWSJSWRZUcmmjn5PnixFVr5appZqg/1m4UekRQXQ9kj1hA2SpMyI/PP7IvP1HdqyzHh0/4b1Zt6/qWDF2xniy6IV3DHSOuPja2X3vu8fkK79t3ySinShw4fj6e88q44WdVH713DnyMv9voGHvqNeIsOSg85mddthY0e2xEyfHYwloXQKWU8fwABzg0xiVaxOja1qUCqtJAxJGLD5VA4ggSDlBYTz17ytRu3nFRekOyZNVXNWrakzDit+RaxW+RynEPX4aV6Ebab1x8UV0m+KKn29qwm2aFuGDZLNdR3LxhPhmdu/tjaZFJB+vsuvwPI7TftataQrZhufadcJCTtB+ZoPPnWU/W6J+DiDOUm4hj5HNTC67Rb1XyWVGBghkjuUZ1A0YKnrSS0WwRnVlWUGGo7Xs5fxfZW/JrgfWbbp/wpz4j9kLqsaOnz9zaJ9BN40dvp2K3nPkn1T0jkfluy/782bWj2ei17MviB7Vs8oY8hyeo/aRQJzVQCes82aOt9kNVivPQ5zUBUIODt1IO560PNrT+l473UzfIlEXrqhEttWPZFlI0aFVyq+l7tWWYjxHyZ7QxbYTfRRvs/HEuDM0hwxrNuJVrEtRr6jDmJHBSXa7FzyE7ByLy6WTGlGXqDFktOmCumIdgRinhkuD73WlnFEfYUOhW50jAM2Yn8ayShnM8w8XMf2LUlwa5KIOnNJQOynHse6he8fqZwqVK3btuRFL1LsbPX7G6F/QxvMvK3PLS28f1WGwbBv/HQpSb28HeLYgj7DPP+CVnI/LgojJbs/keSd4sX4Qx3B2wPMMAGhGXRsynU4qgjUgglFOna1Xk3QsHNeRP6ZAPFJz97ukBO577P611oHDxk2YPBVksLoSZBARKoO/IZ34yvP733OPcWxfu30zyOD6+y48ocrgLsqreqUveRmvBl5dmeBVdg+f3vujFfCTo9VGHWcv8Pud9sxQG58vZNfxhUVybm3MKcOPa2MFBUTS2wIWYqmNhcmlzO8z8cpMlJnJETbvoJje3kvedS5WI+bW1/eSY7CTJVfMf9Cxmnc5JDvUQdKgMbXRU7hX5oJZc1dUPlrdo65mP6J38+LfJ+7vzd3w77p6giYbYo9Or+2+Yz9+J1734KI5B/GxhRuVL5SPvZKyaVSvwiZuJFml3sbDTS8Czn2FN7hCrorOVQ5mZrbPFnw+r8PptHiLwLWu7ugM0zHKQbfbVhtzp6e723rbltbG8travcgo48ramMAmPDS706wI9jbmtl11gYw52c0+fl7YRUWjXFLjCXC0PeVq18rKCAh6Hi2Rod63g6Qeb/ZV5iw9GMF6fEz0+/PSVuOpgyob0l1Bv7h6+JhKni97aMmbLzy3aN39G+/ceedinBV/PXZrcIWx4lFyRV9SPOk2YfLjuuKSOXPEeV2GTRqufKt8/vc/Xfz8LxdeU88yaP/zvwFN2nEduPpoSaEYaWf1+XL8or+qukB2ZQeya2OZrGN/wBPw6H1IX8EGXpCS2pi6+8n8CLuAlCBEc5MdSaOBOgJdUtOleeXXIQLNoQKDtEiiljMc0ealh8owvgYRxKNEF//bonU7N2zYcefiY5OGg3x7ccXwsYsvtiTBlR6PVtjntUGz/v6n9y598Opr4ANugLD9ZsC/hBsWtRQhqzXDb7PllJZlFdDpLcFYFuLSA+nADCY6RdnnqI3pfTz8sRUFbLbmVvDA/s2YJ+fEJooFIs340RFRzajT40YtbyRTNUUPcUIy7oaSuKEGv09FuEL5HYkvfNbrkTYZTxVPmlKK/kmOKotUxJSx6FMVVdRts+/Noxb9VsFcNKneCMJOmiBA5X8DWS8Cvu/K3R7t3gnUlUX0c8VFRVGurKAgixPzxfxu3SuqPdW1MR3pTAbEciyds0rblg6I5RkLUXGUb9sZ/ogZfqfHbrcVaLfAWJCQuHimnt9pRx/NwpBIDzUXXrLSx9ww1XogEJ1RZXn71EwN+yeAgGBMMeqy8nzIHanUTB2duV5Z5qHnXM71fds+6tettvfvJt4n4qzJfYcNdeL8mYMXTLDwtwcXHO5aO+O2Xp1Ku9zYV/myUz++YuTMUvRuAVZE1OhN6zcuGH+uzYqSCfVjxk0ZfvSdhQ5pW5XSH63D6cpo3C6XP7Rr6eHDqPb4Thys3bUU9MdnQMdvgY55XIQbF43ke3U6u74dx2Xm6fPalxuAhqAd7fmZ7VC72liuBeXDn3R9OigQb7rdaeP0rO61WW0Ua7RK/NPy1jujUhHJAxKAUQjTlDCQKQM3E4jVG0jI7XF7ytUGMmRil9UrllY3tCtcveSW1PL5fqtn3hIfNPrI8RpWWo/6GvOLCq2KF/1k6phbv87+1+Yq/F+zly180KucwLNcnWosH01d0P4U4P4nZSh/M98XeKgjvcVcka93uTLlYtr3v1O7stpYfjt72Bb01saswXRJMoLlcOszeQkMuoRtJCgFJSyn46raGJ9UoIxvRo+qB9ZRqaCOnmqR9klJUgRQUopow98UBSIxusgpylNzwyv4m5U5vw8R+ExNnLzhBo8mThHxGOIFvmTPqlfPP7fkjqmLa+7cuXYp1Z/P6g8c1VOx0i94SkeFiievPFLBl05wjqtX/q188vmLw8/t/MvrL7P4uoLOtQSeaMeNirbPESGGcDq5wqKAuzZmDoAq0dfGJJeYwdtsgWAA20nAFrA5c9q0wXWxNvYsm5OqEJZzSFazNpMjRYMCFdTu8ik0aKFJ6PywCBUeHCnz8PKscfvP+4Iq0unhBq9LRbo4zfdYvl4oG3P76EkTyHbnT2fKDQxT5RxaIzJcT/V569YNs2ZNLpfUWn7W24P6CYOjxRZqGfxibl52ADY4O8TMpDfNksO7bdnBbEAvG0Jn3i/zhroYb0+5l3odvNSGfgCx/MfYoc9Gnl3ZMSf7httmNGP1RBIrfGzlMxOMDxk3Hj7eGh2KA517O56/mavkbomWlVTkc/k6UcwK+VxpFgvHhdJIh6oKn6e9RSrM50l7T3tPBsnIqY1l2Imx1fBMJrQeVp+ZEv2x1Lc2Hw2lZCap/SpGVDBl8IgTBwSJ2sUMHEzgq3PzOV9dfP2j0F7P3SvXrxg0ceXgtW1vXs2vDb77+ql30w/Y1sxYMq9t32ldbt5QnOYRV98SQm13PnzHpuDQAYMGde4TyPHnTz5ZUN773geWb3T16tv75oLK/KBDzs+IPNLuBjXPflvTD+Q3YRD4PtOibQ2Cx9MOZ2UFiorznU5zbawtWHl7O0PYzbe1tQ22hY10tnW2DaKgn1pBCzhEejZMSSDIxmnJuRSSqLtb1jZVi2llYuURJxsMKKkHcRGVPHJzvUYnlJeU47NHqhehJ5RaIYLVTRaq8eBb1h589OEDB3LVvS4gRzcjv/LlZmUbZkKqwzv798laX7T+3u8EuuMEtaH4HtLu2YW4W6OVMtG5eK/OmxX2ym4Z/Dumobg00FZY73PynI3qJzsBdcWJbpuOiKQ2Ri1cMt3TEseW2podbuXROvNylGTZMo96hybB0WRw5JDyAz5zZSmKdEjPy1iNZw4uX474+DbSQXm/dxuGLzqepzy5cT1aaKGYZKJOG9cr9zlLAEvmqx0CHdwJ+DgIu1gbLch0GwwZPMmz20kGKSpOS7e0oV1GLP8Pa98BJlWRBNz94uScZ3d2Zmc2L5uG3WVJO+ScwzJkkHwkQUBABMQIR1Awi4piAAVUBsVwYj4V9PTOuzOcd3qeekHRU8+7U/ftX90vzJvZBe7/v18l+La6urq6qrqqurvajdwwnT53AbluwnHIoZ4CTWrPJOp3s7KnTKhoRp3epHYNNeuzOtweLe4E88qsePTXkROujfOkb5nF3/7y6dfeWH2ohjFwDwnHh26bsP3ytbsnXTmUG7FjS2jEOOnlo29L/wGn/GPpq8VzIrstTYfZXvjVn3peeWr+qx/98QWIBck5zw/Y7dyDyIz6dD6DG0zZ00UiLhJbRUYUjQJ5X6GhNtlCHgg63+Fbl/TgunV4yqX4AzxA+gXzhvQuLm9PUl6uAV62gXxEwXKPS1UlkMts58RKCH7sogXx3Wq42Ni0S7RyXKG1sAy83wK7xQqaYs1/xwaEoyprC5RdsGZi1WhE10rFgCf6zpGHqmgoqjsQuObyP26LVlS1PNr+EFsi/atbnxk/m9Fny+e7dn+yEX9527333XL74UM9rn1/fbR3aUXv6ut2XPNhorCgacCkS26bv+uDS9d9gD999L4HMo/fd/AxWc8rO37Jm/h/oHp0TWpIqKjUWVlZFC4oiBcWIWN9rc1WZa+rr+c5zl7ENiTr66txhTFWHBuXrnQWhriAucrB2mtLE6jYEXCDaYcQiLNTT69WPtn2SpKcK1NMOT3fkpOaUcq0aNEPvcoQwfK+WxXEqeRvrKr7ZWK8uVSf0ydnd0WcZM9eNPXB+n74KuOD/wgPSAxMzxhWV3PgMsumKxuXv/kmNmYYPOMAN9L08Mvkwt1tG1/qPbZ9J/5JOlRquyoQHvh4t17Mr7d988229iN4G/OpdPlM3EH3oyAIZOtoDY6alI8zGLDRCPJFa4SARDFGL6kZ0aq7GqMtUnQ0XuK7x/H+ZZlVqzLLmMX4ban2KqkA/4XE2Apul8DfRs8e9QP5+jn4SxEaYc9I1VbEjeEwLiiurHQ7ChzdamBO3BEUgdjaQYoEeYvGpv1enxVibqPVwdlpzk6vs0mF4/leIi3z0qjzgMAJ8MYZbV8nnvuec7+lmt/z9MuW0aP80nbiIGWWMv02XSa2/8mwY8+ua8xMoXEjs/g71ev5x3+vkgzgFklpdqe088grzz/Gjjv60BP3gB5NJG98KfVthqUSIZZ1M0FBMIOiRopCcl0bA3DXztjB8Np9AuFxsut7I7qrmElFhWEocha1DyYD6QNW1uObuPAEPnti/vw/n3nt44WMa+s6ybVOng46JRufeOXlkxulvdt3TJmy81qgsRJovAdojMNMgAdQacYxzuC2W8rKfKGQ3RDjutVUBOMoTqI8hCJCBMxnxOe2G3iBh3VRsCtvqCWTXVx40T1Sp84GRDRE6W2YMJykfoH9ZFL8Xg95FFw/lMoZvmmLpf/gV0avCzOjwutG419K/1443TdrJJa++cvH0tfDmV67H2zf+wCzeNzuBTt2lN6/Yf0DpTt2zN89/iqX622pHaN3EtLNz95lsdz1LLFrx0DuhkI8m4CIdnyqrMoVDocsLKnuKIY4CGvLYWjFjhBmrFa/114DNs7u4030fSZeeZ9JljunEqnkrRIOUfeKrqBfIch58C7yF0Nnyo8Bb2odquYxMp2zFtLZ3ZKkPBDsURIY3JdSusucxZUwxpUwRmK7p6bcMQEiDnsZstnsIF8sON8O+lJwodcTJO6LO+0psGFDpZy3SHTKW+Tdy8tmEnMSFvSr7gHh/CTFRfokRUZ5AXnT5HNlJvDzP/xKexI5NyeB26Q2di3/Ovgu41NFRRi7RJuFDbA2tjjuC49L+xByOB3jwIux2zAdqc2bN4WK5VCTEcrAtNvxee8gy+eMFBc86WXunSh93jSotnXTrFtuueLqEd27xQf1/Q37xE9/IQTb73buW8c+sW3Dviss1xkGT5+zjc5JDczJGfBN6lBftC5V1iNss/JVVYb6Yre7wmCwhtnWVIm9QiSpxEAk0jg2HYs4ahgyPZ50TU3AFOg1Nu0JeE1O8MlspgL1EpBq/vL/rq8dkr3ELL/REpezv8QFjzob48osurTDObAIKa+fsd2z94j6YvYDiy/kWyr1UlwbbGWSj63T+zbYPL1/MvpG1sO5WagMfLRA6kH9HNzr6KLF2IDDuAg7wdHZJzYdbn9SWjN+uYEdpfN10D+AV3NAfv0gvQEbz1vNomiwWCFGZJxOq9fABYJuRFjjTLsLbGZe4DiL3YgNXs5OZ1ktgEDP4GgTnHTmnqUns6u7a6POOttrU5l0w5WZDP7gN9IwPPViKqnSv/atw2eXSZv5Mz/NYaxSrdSgSCfI470gjxX0fmdjysKZzUajXRAcTiuZvsfT1gIRC0ZKmODV1WHO3sPkFVFTNQjfW9W4eV6mTfq8W6rDsm8df0bWBTPw5iLgzSsQbybR9JTHbjAYk6giGq2KRBLIyHVvrIpQga/yFpfJql1cUMu5ubHpkM/udljsyKjkWNS9a71u60Qllj1h0zn35M1TEfXIkLu+X2rMofxU01xF1eeQPBNxR5472H6AVAbIppbaX8++fn6UZJXadxJf7RFix2CspWhMyumzWm1MNMrBSG1sWXmxIgDFBbBGGWF8DtB2LxfJE4BcHdddRqF0y9Itj1FLHGVHxw7ftKBzpYWpmkB0XVhCHYtsi4/CGIaAn1OCGiAmKe1W5PP5rWwpWW/8XLJ7vAKirbgjZPcXOOpgsbExjk7LTVJ/OiV/tfFqjwPS5UZxas6d8BlymfQPMh19Uk3N1LE5R5pHenHHB3QYA8attFLXhhe6TvKAuw7yfxjmqQgNTtmYYNDk9xdynCMaC9NJsqXDBTb3+LTJ5hDtnD93hpL6M1XaXpk8PWVJnzwG2fZmJwZfv2mmcNjAVa1ckChJ9F65Vn6inswJ23fV9pMlO0i24/mMtFA3Fxg9CHNRAja4O5qbqnPY7VWRkoTP1L17gotwjU1VtSEfZ4nFwANAJdjFlpTEHBZw8h0OkyX/icakYn3VC8p5O7A5rzYqboA+48HkpzqwP8J6uRJFU5beo6U6pszdevu24bosR93Mm3dfPqx8q6wuNyWVJEdqbKi4fNTysVqGo6Z3ZUmiz/A5fWHcW2F+3gH7VIImpxwBs8cVjZYIhR7BU1rmC8sJDBe41z6XzxU3xhlqQeIFRhsdshHn5XeqchKQ8sVXuj40EldAnaqYzkLE5EfItjbGmnqFcO+26vr+o0bgZ6UvK2q6la+VPt53W/dkB7JVjVvG7cZzXfeGF2/56XXpQ+ldw37TzTtOZ46Z5flbJk3mZoGf6gM589ltVohJGa/PxwguG+8PeG12jpjZlDnNWV1WK4JgVE1ROF5S7x3lVDQp0duxGN2hJTd/mI6zKm0PSuueO2vtES/7/tQO6VuZInDn21PlL69Zy7wg07UG6JoCdPnRlFSQ1DxmRIPBbzJ5LRaHUUAsIwaCNjchzZu2+QUjizg/5zeRgEbk7AzdJWmVxYhQmrd2K7dC40a6SmUXKmp7menk0fut0vXKg/fX45KLFdp7klfvmWrGRh69b/9OmqHRT/M/QHMFrcnQmvIJyCWKmOctDOI8XrdA9jVNZC1NGdOmMMuMTbP2zm+TqkW85UROzoQfZG4kiZv2JczTCjXtoevY0h3X/fS+jgpiH9ukyXwT2I4K1IQ2pvzdWZu9VKyp8cZDoUiE3pZq7hErIKRUpWNhoW6ccmdqhe1Ptq9sHTbeLN+bGpt2OvyVCJxYiM6957ospaPepSvVJNcWybk25ZKvTZFI3COH4+Ar5VyeYsjlqTvvPfjh99+uvHT9cvMzNfjKM2/OCMXWlkO8JH15t1EY9MTUi25Lv7x52+BZnodvejAjcL2uXDV+qhMnnn5Uqjkgnr3ZtN+Ay9eb37hs4TVT90+g1VHHTZlN9h1hfv5D3wuvAS+oosITtMbjUXKIlot6orV1hQ4fhMJBn8NZDXLu9Jlj4L57STIIdFYM691c3fnsltyBkwfutMHFyzRfMKZzBZM50Uo3ZXDjGK7pzs1vPgf+/N1N4PsdEQf+Z/vN1126/upbt18qj+qKdb1+Ng37sI9papsf2cv3+qJ9Cb7rN2fO/OmTl96X91bBHv+ef5+OcXzKGRcjbnegAtntATFQWxelpsmfjhY4fePTTmSEgVqMDg6GjbicACX3WG42Ponn7qiq1kmZVjLonAilhdOHKDjcb3DPXus3pCpb+0h/7TpIeQCX2x/07vvh43322+y4nLlLjVFI/fE2XoT5K4RIc0mqMYGQ3yWIEWtBgehnS0BGx6YTCU8oFCOui8szS1ghMEjATlYQPB4WfH2fXXYD7AXZ2v4BpRBw/t1/3e0/5aZKdoiNguLe6+6s9L5t35qdwTuVsS068PWPP/4Nf/iUfc81224V8L+fen3m0G7SrfKgHh2IIziELTjS/nxg+0P7j91Kbd5bMHcfw/hqYXTeQtZncthrKorjcXtINLFCXX1VKZm9WLqqQAiGgiEQ1SCyWulyanXUoOJihKL6AqowqNz7wzo7o6/CpLv6EXVnyxx4tSJG+pEz80799qbLfrbz7fvwiJp7LCunzrjopnsfeGDF/Nca71IGf5HnoZuW7rUyxqsu2npAkjyDh08e3jbpugVzJi44WC3dLvPgUG91zGw7HfPiVBLWJGNhxB93VFbGS3l3xCjW1Zd63B4YogcUtFs3KyikuZuvsDAaheFHHapu5swnHTTZ3OrqcGGOggaxWn8qfs4KsrDI4i3KwO5qfG3+igce0BWSPfjrXUs23vzOc1dftFEeFv5Z9cH5k+YsyJaUvfuKi64yMtYblt30UG/ZPk8BOR5KfbtS8JoS0YgggvMa9NisVjECfngwWgTzaC0qKjCRkyEFPp+TTLwl7Sugl6zGpk2O7P0qXUUU3el+/T0/ZVzUc3UnndnR27DuvhLz49aNUy/z3Vl9eu+vPjQ+Ig/5U88fnpUmPWVdu3LpZp4Z8PRrbWO6bdsk/Vf6oX2goqC9Pv6SaSVSfPQ2xOB2mM+vlbo8A1I+xmh020TRwcEa6HSMn+bEvJ0TqTcE7qqZzh7SJRB0UZzithIrSkcik00eZGMvkf46KzONUCiNzEhtuHwr1/OnOdLfCUXCaw8/DHJ1BHQpCjyOkzgHBYPFFqvgdkesxVyiRLaCPrCCAZ8PuImQzwduhcNINAnlSpE+maGwM7snoTJVLp/pzTIWX2TfOnv7NVt3LV5le7LwvQc++vqrT3YsUKQIj1666O3f//kXS6babn6YbFBIX0ofDzmqyM+L8p0pM/DxeeBjDPVJkeUYeb3h4nhQDkWDYNPoX5xes0B5aM5751zb6yyh5QGyG1+KV5nNvniZxy/bzNT2IrTt2Ny7BdT95r0/o+7km0cOmfv3BLK27z0cKBu9kL32yAnXA+BJkveSQIZJ/akEGpcqQAmIJE0FRqPLlDCVlBoT9oJolAcF9QXMlM6A1yOnETw5dOpPvevLpzmVfR/dvNPVtIbJHoTvKUeR6Q39Eq09pL+OygaT4EqOp0Eks1oVCpAQNZZk3pbflAL5GA70l4CtrQT5SDhNFgdIiCNqsiaE0rKg308lw292Ok3j0n6n31lsKy6UfeHiAofVBrbIlrsxQz15ut3cRb07Ohmq6Gjl7jha+qs4uzlJhKfRffOOq+6/9+R4vLZ9Erta2oIPrv/99l+tHdhXFqAz29bsWrhr6xY8aedNUqZQ2rXwsflLG4aNkAWon3L/9AP2bu5bcNti5P5pgddms/sEu1Acd5FrVXZcgwyoSL1/SsrhBNX7p/Vd3z+Vo2Ol+D09WkbPiJKAMuec48PFKyb+fJv0z4krihlmI7dGxGvHkuunC6ZO4paQ66fSytSgSTFmxpWh+uHST/t33XzHzbt2ZO/ufAc+/+iUFVncLhcvWIRAkDyjrt7dqU9ZEO/gmUKW3OFh1Es0ne86ZoWKxPS5V01JmEjfun3qqf6TzZfZbl53y30Hbl+113O577q5k9ml0m+HjTQsu+q1l55949Klpu3XAj974MPsPqCtEJWhrakC8sCCwW4rDoVspRAsGcTyCkYo9XEBLpCQ72jbA0UBxsoGAshsdpJP5rTdXmSHT3Y7ubOdIfXOI53uambj32ypLn9Lp3KXxWUCeetaPxivh5TyJft9ZbQWZrxY9DFbl46KBycOH3DgNjI69445bf6t1zzeun5aj1EVE1deVIs/7NHcvd+aBff+4k0y0m0HZg3acU+fmS0zI3WFI7bJb06Ap/Ihe1zwoTCMfUmquJh1eR1Bh8lqsBsKCoJBt9nO8uUVLqvXxJlhkoQiGO4TaYNgFszI/iy9wFeiG6d6PkOpIe3SD4+ea3cpVXWUyfKXlomNzfSoSbNX9LkKcd49xzn7Dz9478zU8Mln9rUu2N299a09KzceKp+xbPmsuXNXzMMfnnj4oROVt4ydMbZ/Y69A3Ywx/RZLnz3MPXEKz7lq09atV2/aRB7yAX3ZyH0D9uC6lE8UQmFvzIJQLO4IC2AN4k6H00EmsTg9xjnLucLJFjlrna1O1klurDqdbMQewjaWxFcB+dpqhN7pNtIrnilxLNlDVi4/6G+uqjEU3VPu+hpETo3MTjUkSaG2jddfcdke83rLDSNGjRrdr0/rqAGD1ng3WLevuPTam8ZPYTLz1qzbYLpzUGufgfP6NTcN2mNesn7VnE11trn0XRX8d7aIl2gNdrPLQq92en0mm3qRu+E4KWIiX/biyVUIuYqJ/tShdiDBqc/slymJ/T0bFy6cMr2lsKm2cjd3Xfsc5q7pkxZNN8wR6vsNnK687YLeZou4TykNVlYULcjp9PoE8PuoILEejwmbbJQGEz4JNLS+lOfxtOh3GuhNLeK3Nfppar6R6aOjgenAn0mh6dI3ChHt0+nZeuUur0vgl1KaUsCXn9P7+80pi0FEDodTdPoDrAXIOAFmkhXd5BavA4kg363JVrUusO4CV/7FJLluEeutWDFx3aqNQ8ZNWbBxo8BeO2rgpj3k/tElYzYtwi/8+HfsWBmR9e5d/HfmX/SOrB0NTlntopmzkEclHE6r5Wk8FE0j92uOmxjyTviwTFpkWV6+rEJmSNlRVufIr81Ro7qxzJK3basmTFg/btz69fjveMkU3CL9cop0E7t//XpSK6wS+pfv/QZPQLccj7Poc16mrVxPLjm18/9vbeRxQhszSqYsotkMhtFiPf+wcivoaENShqMfDGLxBHSKXQ98dIAFKyLVU4JsgddrFYusrIk1RWOFBTI3C4GbVp/gk621SUgZbUMFARnIbUGEnIoJa8y+fpZ79tafXeep5eqFtc3kMiqI1GC5Cdd7L7vsop9t3TBjxvoNvfpu6l7dfP+GU3PS6anMk+1D5oaWXDNv1HBHRUVZDTePzASRx4/QKeZLGIMFlT9BrhGZrDbzs7SIhFyUzKDSpV5PUuJW6veB7DHTykoSxdXFpzbiW1tqTatMb3EXE7wfA95/AEL69pt+n0Wph2kFvETEBaXgkKCrh6nfb8HZ/RYvuVKMP44WTx64ofep8jhuMiyayPl+anv1LZGOZQ/oVh+Yb1JfjcMYCSJDWIwRR1mMO9dXo882sn2kCZeC40TEZjnx4TajZ+k97m5oSsrtAw0tFEVDt0Si3ODkampLq56mFJfi7ieihb5QyKJcSguBaXbT+jFO5Vq5bqM9v5Jvdsvm3Be8tSvU7G/J1cP19DdutUBueU+Y42YH3LFy3qnKhpLqcewbS+l1bvzJ0ikbV+Ve9m4/9LZltXUxyS3DuEYCf+LgubkKgi5cDEphMhUH2URJ3BCi1yeLfEVUO1x2i49cuTLLV666vD6Zf5807jzX1cl7W0YB6ZeWzh8BdDPRxW0r560nn8g102WTybXJH9/DD4zsM2hE/9GX74JgD77Ktyblt3qfZT+E+SB7Flbe5wsV2axF1mgsUNhPFp4AEGkDnhvJ1dvH0rzxKXIbnBj07J3A3OvXuqvo2TnQ+I2v5y6hV9I3rNjYf3LbwlPljcW1Y7n+uz3yfXSJw5+snLhxVfs/3rassiwmNH4LNL6v3KG30zv0PHKhc16hF4E8ubRZ/hV6vXvp0fSsyzv0/cdWFVZWnuo/acrCDUQsqpeN37gc37rYconpbaYvIVB/hx7jfmTt4f5C31m2m0mpMwPPCzZQS7P9FBDGUiYa4BdPeafcRG3Rb2MZsc9Pzg/EcWkZqdCHn8B9nD72klXSL11RfjX3F6kwXDMFv9Mu4C/CqdVSNfMDLXAo39//DqbIQf1wm8dm471WKyhrIOix0SueHg94M86cC/2mThf68+u/5d7tzz0glL3dLx1fMFOUVouz5l00W8Q7xWnsYmn1i6/jHa9Ilo1bN21mpm/ctHUdoRNs+jFqt3yoAE1Pufycx2i3BwXksFgQxxZGxJNgzt0hIUQdB6NA7tZ6gjhI/9eGidJQY676MtkrJNmjC7I1J/ekHCXwjTzjyzvB9yxz9sUlDj/oEVO19efYunLPldIX+4aOHDFMWrFz2MBTOOZ4/gk8L4Ed0te2F5+QbopIf2IO/XyPtf2ofc926acEM9qzi9rCZvQcexP4nfVoccqFysqCVo+bt7rrYnWxhmRNhWzCoP+UKVhg5DlHaSLB0mgIoQSJ2xzIR/7P43EodaDkPTSaAPO3BLKXL1t09TJIGEpO75dld80Ud7oIK1dItWwGCDW+1zG37Xisz6ULpzfsuW7Dbvdy760TxjT1G7u+rfvtu1ePmRBNVBX/gsn0aVmb6FYULWga02PRsikX2RYnm8obXL5Y08S+S9dUrpxvWGV4C9vk9WwNzF8bzB+tzGj3kURRIGhV6xdbadDAKyXuGlHee0pkhaUWIC+V4fTgt+or66KJCvf8BcMi8aqmhlPWi52RniPZ5vVbLGvdI9I/naHvHOET0H+A3wN2YFLKYULIGwy6OJutKBqQPf3jaa/b2c8K+mVGBVS4zcDtbEWNxmwe45U8LzS3rgZd+LsoIvBwdV1JIl5p3DspTUsJVEfK8dW/tFxsLW8ZcwS3T3/ooelSUY9qE/T5H4i/fgvrQQBi+WkpD3iHnkChhWUNEG4WxyMGLylxC44yj30+MxsgV9QdcjhvcchrQ412tI/4qfkH4LJLhHr8Tas4QNznpFM7Ooafxm0bhg2jVnf5uI0rhg7F7ikLpUP9YYF4Eg+Rnpx5/J4rxrVevqttJh7SPnXzanvf5ZMovz0whpMwhno0JOWpjDkNXK3PwpYW1LK1Dckyi9VC1TJhlX2tYG64mH/4Wb0A39i9L6MGRhAM0e0jGiJRue6Fvcqhd1LmZ8EtTyUqE4WFPSb2HlFYXLhqzuzV8MeI3hN7FBbCD57EHx6/qW/bgMZCX+Hcwa21g/sNqrn4qitX1QzqN7i2dfBc+Nw4oK3vjRkaG3wI9vlTsD3kPXLObOEsYJo5mXRDHuld1GUkxVZoVcYFN+zb+NBDG/fhD3fdhT+QCl98EX8ildy1S9eHh/RhFGzggHl9Tlq4gkUW2gfbZR/y/W9lTXeSGxoQIv78wN69V20c2fZIRcmWWBW76Zfv7b0H/0aqWLgI95rxwsihr6JOdQ8MRox48pKzkTWZWSMJdngAqiNXcTtdw8VxtsyG2ThTfD02K3UPuE/befzPB7oPaP8T4O4OuG+luFMpm4ERRBYL2GwSWE4phMKBV4NFJKoZkZpsai3/4LuSO4P/uuMXpDRTL/XFH+C/z2Za5s5u/+Vc6ot8B+v8e5R/bSmn2241Cx6PzWV1eX0uu8OuVi2rO251W9zKSmahOTHVne6u21LIp0EmQ3OvQTdUkth0YWmsoD5xr+TWkXZrS53hYuPb0wiFc9pfJbGdFS9jTwF9PvCWVqcCpmAQDKPg87kchYLg9Dq80ZjX5VYu1fvl0l92tohlrCzL2iEwrssEHT6lqo2FbCwTV/Yl5cAuaLn8kmf+DS/tGQKs1rSpwiSTFFcGUFIsKkVjLYM39x8/deaihyOhmSW/ws9LU5k6GMzG/uPWdK8rZUauXzFl6MTJPQdUjZ/D9CB837o1WlpQROvSAO+PwdiCaGbKY7WwvgDjEgTGF7TwobCfZX3Ui2BZIzLa5VK3VuNJ3P04E0RBdfrrtFdqz/F8ihwXkHqE3k5pEhzDfZm09OM1Nz11x7UH7esjD85ftXFlD2yWirlPL5fcR3fe/sJ1W42P7VizfPN87CB+TxX+M3uPwNM6twG0LGWze72CzecDvQuGvITMVCy9wrvZe8x7ysvZvUXeMd5Z3hXe3d67vKKZ9XpZg8GlCJIBJ0FJzblKqntAs7NbxCh7qq48v+ieg7fvvQ/3OXiT9NycNCftZKfMnTOFw6u5Sey/pG+lHzCH7YxD+m97v+dff/519mdPvfYa9cVZ6RHuBTxWqACdJS8X9ktFiTLzjMFqMtkEg8FmMO6ZZjCwKRJKmvdMM+1TE5ChNxpq9S/AqhVh2Mak29sMwSsPv6p//eyspnvbZ98HvfQvkZ6KHTt58ujJk9DvlfBlk75fhuWBGXn9Mime/9/6ZRvdSS9bovT781nP/hqH720XoeMYHlwiPat0TGvYXiWNRgs6DqNq8spVBVNkERMJZGE4nzMU8nWrEIucXDVyB1Bt8kwDiBFOqhVrlSEWy+sJWTzIn0qpB3ldIYsIXV/8U4/HKmLwHywa9VW1xt69F0dLooWwsiQKyxqk0SmHx2YSjAaTw2X3uhxGp6cu1jdQ6LYaBIPF43S4LUZRdDBAr3SI+wTP4H8rv+FhMhrdHjfanXa7TSSpaBIE6660cECp31Qlc0d9XsZGLsrIBZz6Mr0wnlHcY/bshallV2/u39J96ozFA+L81JJuJVctaxlSXlcOfb3CvYOr+XdgXmpTAcxxDPgVglyjnzWyPMOwu9MMfVPQ8RLJSuKk+toW5kkVIFwt/VM6hHt+wS/at2UL5bf0DuDsSXGWpbwqTsztpoaqFuwURrVvzKjS44qVNPtjuKd0SPpn6gvck3tn39ItFFeWPgUXzzMChwEXV8TVciy5fpOLy10GdPFffCG9gtuwnXtny5Z956KJB7YqY+VhkC/l0SSWlRCaXvkiBUtgGz9xy9J9lKa5gOsAzI9I5IkRBVZkEcchA0Q/KjaBDhJm5aUZDfTQq5K9pojFMhGG24wP9Pnoe+mdPl/8g++3bMOGfctU/mXx16UCPMIc4kTowyBgddBALaptaHhjRkNDLm53GRDtb/av/ccXfXD19x/1IeNftm/DhmWgByukNrS043WwZAUps4l3OpHbCvrIotp3ziQJkQ10AWPpMVQSpKrnsHexEznG31yfcBX2aZTacKCvb3hdjJ3KDWm+A/Bewm1CO4UYmMTilA0miEOiQKq4I5ZUKn+zga4tgF2m0Cv6vSWNOw8flj4XYqtmz151aDxipL9Kk/GRjh8AhxWiy4RBNJuNFohwQfxtHM0+26zgeXBmzmCEf8FmCTJuct+b1NtRy00nnTmHj6FHP5iI5rJG8EWS/uYklj4/fJgpGH+IdH1M/kO6DwcPH6bv+yBydpwf5CpFCYScIvMZQx6Wtz7BMshj48QSXNXYSOC2SHXctdxogBuowA3seA85HmWZkx3PZZrq7KwMSmDvQYjbIiwA2BIKS27l3Ia8GbaYL2VPdvwuEy3mEQFHVRT38Y4vuP78GYAfhJBDYG4bKb89dI90ittCaaN4DP9mPfAD25OI7fhCw0HaA5zWnsAx38hwTMfHmXiJSYW7R3pGj4/5htmi4vsqE9Pje0aPD+CaVXzPZBJZfBdLA7m1wu0AVwp0lxmH4dMEHm3AxPcqSMEizZcy4VihBfi41h+yUHbKw6Zvn0L7HnwG2g8m7dFadEBpP05pH3aWMrGSGPKU4BXhCPlD357weT7lc5nM5453KZ8ZL3R7Emh1e3P4vL3jM/KWBMAPAXjg8zMIiY8xMPGtjSq/51P+lCl8/Js67l9puAgegMviIXBnAc78OMMnSgUX7VCZv2f0+ICPU1R872Q8enzP6PEB3EQZH1OSh68lB9/nzGQV31sZX1iHryUH3+e0X8DHlVXn4mvLwXeWma3iezcTdOvwteXgO8tMV8ZbmcjBB/MxV6wCuHICZ2SYDSSGe5zBbpgQfLLjvzBqbJYVRdGrq0D2Bwu/hDZDqQwM6HgRu2FutoPF86esLFPsLGUZXByzunPa5ffFMlci2oLBZPYxLNH6nlBXfa1Fff63vmD8cymfypXx30THj+1uq9yJgh/gBlMbMVSBu0Tmk7G4wOrJ5bse3z+ZfTI+lzd2Pnz/ZJbK+MREXS6+gdxc4ZCMD8a1Aa+h8OQ02b+IPkSpPvwlE69CJp0+XAXtBlP9G6q0k/XiVlhk3SkzWwvs4Bp6ytxQ2rwAfO9Dda5CsW31oHMAja18KQ6YraJRhaZnnGiNE2EB+NIFaEKquCAYZKxWHzXwhRGypTg27YMl3hQMXT8taEqZnPSciIll5EfLQgHHm13s8Tmzq7b8bkLnQibkgBAzMNOpcIk06VW25KcP2JLcWiXM1ueeI+O7GGRkjDATxldJx7cdlWIzHV8YxldZUMibsuMD+N3SFC7Cjwf44YR3xrGfI8Lxeifh+L8zsAYW5MATua2k/KvSrQ0Evx3wY6udN+fw70mADwL/PMDB/qk443Z7Al6zyeT1sBCP+K6f5oX1lxPNHq9oJ7fLRIfy2BvN8HQ6tAROtEdMNiWjwezdkjhh1ZMnjOziv+OZJxavvuyuDB72Kj+oo9f2N6Rt7bXME9deeeL29p38/cAi1U5WUvmtUuxfuyy/SCOfwj2p2ckROjiwL7ijPeMLeEzqukR5crWKzzgSx1VdpoYDORW0qi5DICHz5WrKlwI0NFVKOFMQlHkT9HCFEV8oGNqT9gZ5hTccsIbV8l+tyS5P5pyTP7FOPGJi97b/5r4u2PQmeUeUjP860C+NTw4BbXDJfLkRvmt8Id8jqh6v0vOV+Yr6IoSvdn8uX1fp+arAKXwNRDW+vg72A1N81Yr9UPBhb8wsZPHtpusAwTdSgdsg2xnkj3NMFo68q4ipzaX4DD9SfGFaGzPIE9OJ/V4ZsTxVKn66Tp+Edt/CeEvRkvfJKr8WDQdPN5mKQTsTNbx7bHiLDa+04dk2PNaGUzaMbBaB2JMZ9B8NqyIzp6nvUUNlZhh+D1GrhZ2gR32tjjw9ou/bCy8iM3jDU1I1JozN5Ka/zW53WkjFabPZwrEut42EXDYLrz4sZefB1ZevdSk+d+sbVXn3UbL33mLZO29MYzOEquwNuutub7bf/96vpNfxt3OlFfygn/5Krrq138y/4flz4XuaXp2m81Wj+HvV6rz+KaOqFsB9Qf0UMl+jFbiACveeHo74Hzp84FfcqML9MWPT43tGjw/gNqlw7+jhvoR+R1J8tUq/FSrc9xnRiHkZDpsBbjrFN0aBC8ty5zZb9fJE8VFbW0vWHxmfZnMNxxkTXypPIIuull7jpgszaTbBicakKq0mE4/JwQLeZoeJsztIaGcQx6YNrNk0fpqZTZFHQMemWeWeCl1JUJeX8urrSkgBDfq4HDkM4YY/mY/wZT9V4vulP+HfPp65p/09pmzXrl1cxa7/Xvnww6Jvs0z/M3p+AN9uV/khZQx6fjyj5wfAXS3zw2PJ40dbDr6zzEEZjrGKMjIKR86E5uA7y+yQ4bxOsx7fVrr2Eh2pU3TkjKIjEdCRK0KF9kDO2nQRwM+j/sBYJGvoLQp8N2cpvq2i2hLJgZfxL1Dx69ayArKWhQq6xH9GwS9QeAJdBdjZiqosdoIbZGME5UVd3hqjoZVxAtw86iONzYVjNIR56259Hq3EXmC7U7Dm0ErqllXzZ8BajXPTmKwQ5a199Xl0aSjk9gBXzY1W2hMdcGoxga49yIJq4x157Z/Rtwe4DZrvqG9/lvmZ0t5rz23fltP+LLOZfl8A/s0CasMbqExwtH/q/UaICUeRSgHl+c1XQJthwn3QZjyx38x+LEvTr5AJNLEX27ClsHBoQyoUht/8fvjN6RnasMXhgL9ZrfA3iwX+ZjLD34zGoQ1MgBh7VFyb7cdZpf7TmKVxgkYjr64zHMuU8qXwOyptUFrr1xmZzj15dBJvwoQaUwmObSL0NBF6mgg9TYSeJkIPpydIo0jFm88zJsuzQplnRefg2c9UWoxUOo1D0V86foV6parYohTwrCgVCA8t2gI8K0r5fPCbxwO/AXlFhChYVAOCGr86O/EnSw+bpaeI0lMUOQc9S/LoGYbX/X+gh+jWLGpnkgrWa2XNZsArYOLegAHl6NZxkM3+1M5MIHYArZ0lQ1dAH8NLyi36mF3GvUDFreVSGD+NaT7PeP2GnFwKxX1Gxc3cViDjLgPchpKyTrhvpbgbc3EHKe7XM/4gb9XBf0PqrVHck2TcxbL9CoL94v1Bs1ePG/T/Vqqnjbm+L9PxmoaX4AQ4L7VfkxS4QnUNYTMqThUfXSsb5bWS4NOtlWxYWStVnDQmmaTAFsqxCbjVsKqGnQRSsUU6GhVbRGl8NRPI0ngJwOloZL7B12RpDGRpHAMytojys0nhp1OxsXVgYwtq6vhcOXgA4BOUn5NlfrplflYCPz3llYJ+rsbAmBbxU1XcMCZJtntmDa2ME+AS3AgFJ7G7RhnOoiGkcDKtT6n4jAIzTY05mkjMMaW2kc/XIZneV1Xc0GZch01uU0fUY2BFbSe9k/v5XutHZNap/TSQfsLde3bdj8Bq/YjMwg6r3Kaa9INrunfuh/BH5T31pRidTMOs12flg/JI5bsmSzL/AbJKlY+RWh6zOW/NNJM102jmxZz5fJbUeaPwbQr8DAUeFAov8gexPQd+pJbfbM5bSzXUMl7pFKkfp+IFuEdU+Xs2o2Kl+J7R49OtraY8fM/o8QHcHhmue0AlUaGvLQdfdq21G3PxteXgO0vnGOB8hX49vl3Si1wfiq8HhfsU6FuKrE9AhOv3ik4t1/wkwBVxPQFuig7O8ShJof2QKSoMWrK55l2kLpsOZzbGC5fJKNWYsS0H5z+zMeOPmXitjLILfNkxB93nwyfDUXw/ZGLhLD6Q5T50reqR628wOETkH4dK1ZFrsvwktCmi68mUHH/jcfjx+FQj00L8jRbib7QQf6OF+BstxN9oIet7C1nfW8j63kLW9xYcctLk44+ZRH3A0pXLgbqg06CLbcNybKsyIMfnkGmdo9Iqr6toCeLRZ6iUtC5OFRUNLSZEsDIV4ZBChUyGMo8m0LUXhLsATwvtfxQOKN6xB3QHeWJMbt5pEMBfw5OcX5rqLvCIQnvBdiJvMaPP85lAz16gc9qSp2cWmwIo4wS4a+icps8LRx5iOkPzjT3paAd0vEzzjDgApJ7seDkTLDD6df17Af4kXe+n0vV+wLUkR0ZYAtDXZsIRMZgztnz8a9FCwE9GRzpYGAhnsaOu8K+dKfOCdDAjVJjFruGeqeFegjD6RJbHAM01FYRk7Dp5lPFv1PAvwaoEE8lCkQK5By1fLPexQO1DZzdJDhEHu6b/jIpfi4sKyVyG8+iHOZL3q3rmzZGGVsYJcCfpXE7Ng9MQUrgE9H2I0torb80m+Uin1W7gcmgF1nLLKK3Tcmi1O2n2kjXraJVxX63i7iqvJ2PX8VrGv1HFn+W1m658TqUHjdekjwcp/b3z6LcA/S6ThTPk0N8f7NZ1lP7pOfQHCP2+gMmpo38Y4N4mPAiwfSj9w+mdOgLtANylTjNjzMG9l8aMRA5nUNzXqNCAW3CasVGPG+ZnG53HPoqfYlD8GbNVQSvjpHFkTwUngbMosb7ZinVww2Dt0+GDNW2Vgs+Sh+8ZPb7sGilYcvA9qe1JjVDgVipwfiVxq1/zZ6trH+iTBX2K4ik/gwtT5eVDC4n5KySz7QsriyuwoCpXtwSzJvu3qxJSSHUrGsrTLTp/FH56LjwNUFDYa3LmwG8B+3wt/62ybyswm39N8/N9aH7+7UyfnvLGrZonxHuU/QoH8qC6lAthj9PgxKzX53RdP83J8xa6P8Gz2Ivyi7fV18WUtzLUfQivW96E0G1ANL7KnsnuO+C/kZQ6Oad2E9C5iZ8M8jwiVR4KFztc9N6ZQwjzJaXO4mL77HRxcbioyDsrXcSFXZxxVppzZ29gnOtglHyrNHskqtmtUOaM07oFbhzB3KYlz2+6Zn146tqtl910ewU+W3LVwNnrepx69zscvV+SDjyO92w5NT96Z9muzVeuvxUXNPWf+dgDP7WzLO6DfVKH9EvnW4rd1mxTIsfmMMju5HT+0haA0+2lA9wXatzxdqY+Kc+Iakfpmizvzb/OblXiSiJQJk+Ay/U/5bn+Xtujf52dLZ0ms91KZ/tMpkk32xr+kIrf2IN5Q42jaTp7YdihngDQ5JX2IZSqfRhTzCm1TS+yxPfq06AeBdDa5PfTgtvpvqjSzcmOWzIur74naJOi/US1fvrhLzt+oG36OGmbxZnuLfqeuuinJ3NApS1BOupV6j/HeBZp/fRnHuj4Vm4zhHQUH9ZywfH0yuYfymj+wVd8jn4+1foZwIzp+J6Op1kez5lM/2T+eIg8UfubyIl5iV39DnlTFpbyT5MudV6pfFE7PJD6j9d8J0vZ76FdaYZpdJJTGG+njL36QIdMtAm8kLfIEQ6SOp2hO1+QP87e2XF6aMf+onOM82ttnAOZ0cpc18njfD2TvNC89WGW5PTD/Q/9DGKG5/bzyoX76Zsdj42Oxxnsuh+qg3I/g+nev66fdy/cT2t+P8W15xjPV1o/Q5h0bj+/7aIfKh+HVPmQ97s1uwPy0cWwupKPW7+U5eNjpRXtUUz2ChVprbTcr27fHtbiUnlNtFrtufv2p/T79gDHy3bQUBDJ2bfPPcMA9mqv4jEQPxG5fNicY9/o+QVq34Yq8OvBvhF7WAkGjo2VKMhz8At3avj3wzpD/XQf9dM/zfjiWO+vyfgPKfi1mIJJkKW1pCGLXcG9i85xuWI7P1ZXYpKZw7OCti7PX1xFbedQxXa+q8pFKWH5qvJCuQ9dmyWUR9l+WhivcqbEL58p2ZdxuPPOlEyi5zyy/fQj77hRWSqXZWl/piih70mbi2w/PZnj6niKSUf1CW+X4xkjrNH66c88pY6ngXQ0qXui03jy++nFrFXGUyKP518ZT7TLMzJfaf0MYJYh/YkVQ7dI536IrFLbSc+EyDZT24vznyDHNUh3f8m4LPKhEJ2cEfnVzoWA/RRlKXYo+lFA9SMWzh6T6XJ/GORzba48K5vOVTn7wuDLGf6rwksfEfkM0sjwi4zDo2xnyTL3OtCl28/OOXeQu599Sr+fDZQHFf2DlUK3P7YA4BbQnGJDnr/iD+pzhVcA3DCqz+Pz4IJhPVxeXj47fobMLSqICrn5Tzknb1bxKuNXs9UoUpwHT/Avo7LToOjcc6ocxIihmxoPdJn330B1Ybyic5qPEyfTuLAk1KnNMDqObD8t+DtFf2Kyv7I7EyrUt4I2U+hYsv30Y3ilTYmsc3dnCmJ5bRbk9dOTOarSVk06GlrT9b7KcKpz4xWdO6G2IceVmLH1sU5t8vvR+Su159/z+krrZ0B2TS4i/fCV4c79EHmiOteQq3PaeuSn3RX4sk01+aL6Ju9bXaOTMtIqSDfMIrrJzY7rM9IfOW9J8yRzwS+iFhvkrTgaF5z58sazpB98kZwnma/bG4mXCvrYNx/3gI7DxOfKkB0mmM0lmVgiBz4f94CnaJxVTD3vpzOJsi5k+TOiKzJ+kH1yfg9a1FD8b2ZKKjrjJ7pC8RP4DdRWKCetHsiUV3dB/34N/37ZZ8ww5RT/c5mKpi7oP6TST+EBuopivzdT3ZLHSzLXn/FbVfxgY4Ts/k60WIaW55Znie2Q6dbvAx3MxEs0uF2AT5d31dk2tzc373pKn3fVn6n6IRMuPFfeVWeLY8QWBwrE3PHIeUyzls99nV0h2+IKaou/zUQTMm6FX4CfT1D5uFiRvcmUv2S1BPhPMpGYS9TBE/zfUflYxVPZm0T2GshWD1LpzcE3oOMuGV8hxVedKSruCp9DxTdgP8VXkoOPytfFynjSdEZxNcW3MhMv64xPMCv4CPxCGD9g7O7U9k1kGu/UcO7veF/2p8oozoWZsu5d0HhIpZHZ305prNVoBNlIUBm6WJnLP6pzuTwTicq4lDn/jusp4yFnCZi/o2zu65Ca+wKePSXTY6T0PJUxWbPZLy33lVFzJ2jAy5QjXjrDr2R8QVOuTCSg3wepTPZWZBzLMslpabVsTo3KJOAl9HEVWfqoDPZW5uBieQ7kPPGPGbu7M31abofAr5ZlMEEpbM+Ei3Lyc/L479Twy/4tkXE3kXF3tMvc3yEtd6TmzItI7q+oOgf3Vpi7PUKdq5Sl+i1ej9rRvKxFeCNTVcbbzwN/Gn0rw1c75bPodVXnhb8b/RfgyXpZL6+Xv8jUKz1o62V+myPoC6VNg9zmkUzThdocwPW5/fyQqS+/QJujuDS3n68yTV22EYdrbe7BWGkzUG7zZqa29wXaHEPfK20GyW1e7NyGxpbUtyMxnyBef50uJ6H7fnov/S515HwHPku/7fL7kXN8P3CO70fl7x0emuv/TPt+T0dJl9+Pyd/RMRhzP8rbBbJc4XIYs3rGytCtwpSbb8+HP42tVK5wDdWJzzMN3bItuoC/W5k7BiflbbAfMkmlD42n+W2OYKfSprvc5tNMjwu1OYAHQBsaL9GOCpKVpvzcfn6bo3i82oZ2VNWjU5uOISReonwvp3y8XppIcRkQ4iv5M44y+P4q/cnpjgJE27Q/l9fm7vabuvx+5BzfD5zj+1H5Oz1jEqTjWKTMYbEyhxFyciESsgQ6nXfRw5/GFQo8sTyeeOQC8HfjkMonGoqjhNKDjrf5bY5k25TQNhUXbnMAe/P6CV+wzdFsG6Wfc7Sher5IsQ1OtU0zbVNce8E2x3CZ2qYHaePr3IbKSiWdryq9rHSk8r6flr/T+dV/V+XkN3nfj7Qf6hJeLyf674qctN9Lzxx+pn2/pz3T5fdj8nd0I+jHDMrbJcqa8wdZ1+UV+pmM12kTdLqeD38avSvD+yj8o5mQ97zwd6PPFD0Py3r+ZCas9KDpeX6bI+jPSpsCuc2JTPRCbQ6gT3L7eToTdl2gzVH0p9x+nshEu2xDZURucw96T2lTI7d5PBMsvUCbY1qb2nO1oXKF6fxWd5Ir/Xe9XOm/6+2P/vuRc3w/cI7vernCVH6qO8mV/rsqV3IsW6fGsmCvbLL9YegmW2Gwy7xEFv401XECHyHwxYUXgNfslZJjQPHgOeLrbJsj2TYJ2qb8wm00e6X1E7pgm6PZNko/ndp0PETyBZTvDcp8n6TfD+Z9Py1/lxJ53+9u/6HL70eU79fmfT8gzezy+1H5O7oXvg+kurFWsQuSrOfyCYpPMiGfqD8rlw9/Gp2V4cMU/kymKHRe+Lupr0t0IirrxO8yUaUHTY/y2xxR/FcGx+Q2v86UXKjNAVyt2nTakTHqF/PnL7/N0Wwb2pGx5BxtqI6v1a03Oh/o20ykqivadG2O5ftAndtIfyDxB52v3rI8tH+t6a3+u6rn0/O+H21voN9voXHMZ9r3Y/J6gxqBplvp2Dfk6i2xVRjVVoVyz6znw2t6S44nYtS99gLwst6SMTfKY+7INCp9aHzKb3NEa9Oktul5oTYHqP9D55B25G6s1rfokraj2Ta0I3fPc7Shc7gh388YSv2MZOqCbY5l2ww7R5uOh2C+9pJ5ZKfm2oe875p9yPuu2odi+H4DuWPATu2Q5eQ/sh3Ig9fsQ953xT5IafKdyI/y/R5pSZffj8nflfhO1OKuU+hhfbZrfaa8i1iV7DtReIHtEdNBS5mySt7eRcwian7+KfQ7Oe7vRu3P8UxlFzELxb9Axj83e+tkTEV1Dqzsf4qaX3gKfSjjjii2LazzplV4inuRjLsNaZ765FBhDqzsg4iab3AK3YV0GZKNGVcX/hTFvUTGHciewSMFvYXc/CKsQ6K2Dp1Cv5Z5Xki5+IKWUdfD072+8RrP1RU7GiwQOttvUbNdp8gt3ez6cDDj78LeU7rXyrhD2fNyZl8wB1bWQ1HTj1PoKRl3LcX9YKZaZ1VUeIp7g4y7F9IsVktVTQ7sVpgbLc/gKIN17Qc0zymyAjNQL4+dcy157U6j73LbnSvnQttVaO3uRt+iGVq7C+Re8vo8ktPnBXIweW0PYHde2/PkYvLaHu3U9jw5GdJWza9A23vQv/Panic3k9f2GPo6r+15cjS0poaaKykVr98P1gdaLkIIdfXz07k/lzpyfl4m52xUiC5+fuQCPz9wgZ8fzf15h4f8XMvdlMk5nfP8/Fjuz3NjZCLXJGdDeEfP9BqOE+Oj5pTzYU+T9ed/hL0bszpYU4aG7WQSuoA9gjr+Z9gDOPo/wx7FsfPDigM12HsAZmYObFMe7HAN9lgOzwhsswrbMYTegVPj7TI5HqP8ny/HZXk/P5378/bn8n5O47Pz/PzIBX5+4AI/P5r3c1LXIRv/A18u8PNjuT9HjfBzzTei8mVTdHM50u0wdAlLfcL/EZb6gxosmYNGbb7yYY90gm06J+wBnPyf8R7tBJuHV/XdqHw582CHnhP2WCfYYZp8PQSwWT+rTPbvKP/Xyn5e3s9P5/5cSuT9nPp75/n5kbyfX5v3c+r/nefnR/N+niY/1/y+MtkfPM/Pj+X+XPH3Mqq/R89VwapaSlfVP2Yq6vP8PRl+vApP7kAQ+DIFvrwiH56uaaK2tpwip2K0tcVwnPSkyiSFJfunsq+qwND9088y9dW8eveHwqk+KnjUPYpzMGp3mmRaD2ljI3tAQGudQmtdn65oVeHVuyhZvHUq3uydhYSu9grx2Gzk7Id6BC3vjsNMDX47YuQ6I4ydwDucXcKL2n7CqY7Fun2P79XvbA9pbVd1rRQ5Nz/ONAQ92llcUgebuwo/y59BJlSYshhoFUCLgTyajlrfaKnVFZEnL2HF++LGeCN+tqjb5m41bfyZUW3LG5Mj4/eRuq5SG/6uYyuyoHDKYhHMZqvNwI5LG8yo9g21YC95cStbKzOJb/EGbLHq0l1X/hTzCyvNt9zw/4+ejr9xjzKP879AfhRP2T1er8FoDHh56xaXEe0lLxiG3qCl1LR3VGoY8oxTvC+TbIjAr+akDeMvKieOHlLU3GScZq4b11o9cfSgyDzndOc87tGSbiV9WxYs7gN/rtt3KalP4OReZG4XnoO/iagIDUxFRQ6xHOsMFxQ4nM5o0GkwFFg9XArzHL9nGuL2Ke+6hwKOMw0NpBivSk22bpxS7NCtEYc14hh86t72z+77d+nIwf0KknWGCdYZo8tHDk6Fp9knWCqHci+dPInhP1NxeXGP7ltXwR9LZ81syo+fqO49IMuH6m8E8/wNqnuLZPtAYPJjKkcZ24Pc6zgfDqo/i2R9M8nxQBziAWO8rotY7ZCGl+JT2uh0TfqenmsUtX2ZU1IVtcsNdL/me/U726O9jdq772m+XdTy7Xr4SgpfpYfX3bGvUnRnhbzvnfS7tDosiEGV3FXMcpBVHjlQSwriPcHBcxyDHdjpstl4bCKvDVuOT3PwSJlt8hZd7jtXRJLjbGMylpVnZvmqX3wmvSULNfewBUdsmmBr/V6a2y/LcUjpF7MmrPSLz9tv0svGG1mdHt3w2S9WTVR1ySb92YKjuo6Zjq+4jcwzwmcogOJocModCwbjcaPX5wPdSsRi8Ug8At2mjNNAx5CPt8ZP4iGoVZFu5Y5CVsidXSteE9E8UUfUN1klrB3fWj1p7JBIU4NhuuOifQqlZwsThd1b5lzUUlRS1Nhj+/LqLM1ajJ5RY3Tm1idp9Oqg0ev9GXfYlnsmUYYfr8Ibx75K4Z0U/vGMy90VvPBvGZ7UtvmlHCXfAvGS5QTLkJ7odUEN9rMs7OtEunogz7lgqS7IdO9/SxfR/yITKuuSjue03MWNCGIaFEkZAa1fuXv4WCZWbdOX51HPbNIza9XauvWddn8K2f15ZzZl+JkavLZu0fpf2GbPhZe+o/CitidxSqJnQzrW0b2N79XvoHt3dKVTBr1OGQw8UGX5v9CpuMfnj9fgPljWqTNtNSAzRbJO3RcfmWxaPnlUlzpl0OuUwYBZC7b8X+iU1i/VqSlyt6pO6TrO1alhqYKwXqfC4XgR6FGK6FM8XvQ0tqBpKE6USi6Vm0zSVczV8j+rVZauc6rVLQqxndRKR7aWQ8qoOSTFR1QyZd9mAlExd49Ihh+vwis+orJT+W3GH+gKnurVWllXsKxX76u64s3qigz7WS4s6NWgLmD3g22fSOOLVUpO3S2f00lQD/DbTCKaUyMiH/40TAKFL6Hwn2YqEpbOubVDGl9k/5Ju9BPsRdVdjvM5LXd3IylDrehtgaK332ZK60WUq7e5Z58E4xjldB85+oUsnpxzVTLsTO2cVFZnTQTanHdHUnqawovafsQpeV9DOkv3L75Xv4POurV90Fk03k1m90ER2/F37i3mef4T8v4ZsqLGVFDgeaPBYAaWmMxmm4XBzJ5pZqOAiTP0plyQTSfISo3jxqRItRkUK8k8f+TI39c899gvjhzh3nrqiBWLFunLp7rsi+N5sVNfYECgrzeT5+6rhGqwqPQl3fjYc2t6087SFum/VutTxGc+zb2A/ySIYCtiKRPiSXV8QeQZsA+PTeNpIWvdq1S0Xjbe99qvBkGraIn0h5gu1ha1ePQUOq3z07WTkVlYboyag9V8eVzfWBfS1fyhcGrulcRAQ1HnSF/L0R5Sc7TaObjudJeoX24+l+I8pOLU4h8FZ3cFZ0cd2bukMtOg2Hk5F7OO7ml+r36X7TyBp3sTorY3ocHTPY7v1e8qPOpFY96p8nenEqsSHrTUVoZN+njmIWYg/wLMDcQPDEtu3ggiu4U4/aE3dPPiJvXExW+v+BU08GC28Ado+wXEHk/Q2KMiZWXk2INhkIAEOrUkBlHdGF0ckrWpx1U7r5lK3PE76StUyYskQjiBGYYjhZxlcw00OOPOyom8+N+/CgFStzwKsB/xVyMbeFfFZmSyWMxI4BDPsdhuZc28jWEMLA+rIMtio4gBESlbXgv41AqG4KE26B5ed8edYllzWbO/2S/6xbLKiZubDx1S/tssfcWntzQ/+ECPw4d7PPBgs1yLuuP30lf4ONBgQnUpr5HhkYFlEeIFMydi+FcwCYgUYG6hnUI80qA+10jrXDfHSTnOsmZ8/E/NV/5nPB5+ZTN36IPmTT8s4/+8qQepdT0SxlhO8Ven3AZOMLKsICBsJtXHjZgOSn4UMouc4IaRxGEEMI5Y+fj/XNn8J8CPh8MQ9m5q/uDDHptoXbTR+C32cmalQ4A1nMjMYfwiV8yMdAnib6hsKP8Pc+EDvWU5HqMn0/gZRWFJL40x72H2UvziddcRXnwP8L9T4UGSuCw8VorSx7wm7qPO8F6w3yo8qu0SHNb+H0Gm3+64ksaMTSmryDBGDmMDxz+d5k52PJeyGR1DAcfTaUyqEhJEVSgAv2nV8evrREDJk1/c736s5H73h9mz35g9m7y9sJOdybaCLLOwlthY8oofw/EI36FKsc5AxTDbekj6N27mz7TfQBUb2u+G9v3U9tBYfsOPvWMazm/vjgH0IWyUXmNnMsvbb5Dbz5BuZO2YhfbRlENrj+6YxuHbp6GqThhmUAzSjTIGjHdB/ym1f8SS+hukCvod05i8/o045mZell7DxkPZ/hn0KDuTC9H2IkqmAiLH8YLAyIwwGGEkwAqRVX053RN2OrbE4BdzEWUN06DjkMwlBj0GfYSVPmpTPl6g4xQQxxmMIkuYxeNOPaieIgw6Br+YxXTg7W/qOCiPAvBL+7gwZhT5CCv4RSSwpAdwThHpwUAZCl1o3fgv1I20L9sN6MlRGAdLzlKK73dEqTV+H9Hnp6GHxzuqOB9/GplhhH4T2B5RtFjNHM89nzbxIv/CNBEIrW3N6V/lYJzlG3k2yZZ4mSO21TbpFrwo9GIIL2Y//HE095jzoBsvl25wH8zpx4vGpiqR08naRQtnsbM2m8/vMlvMz6edFpvlhWk2hERBfD6NBU54YRqHatWeA62deKAS4i1xx91Ailujp4R1cz7pZqCGEFVcrJEm3VxcjCsPuqUb8HL3QSeei+dqdDqlO6U7iWyOxdezG9lngCfeJ5AgWKzkCZPaZK32rqX89g4tBcBufGDVinvvWbn6fubwmoMH16y+6y5az3IN6MMU9AGdWzOqSfnMBpIxYjkDa7GCfCKYVZL2qm1oUF9pyr5QEVMK0pJf7OGj7U8+3H7y2Af0H82Gc2/DGuh9ggOZERDLINmk0iwcWXdi3soJ+A/cFcQyjwG7PArscoXSBoN8CUS8yJiw+thODFpJo/AfJnBXjPkhwu+V1wsXtDvLb4NRRFIWxDA8a8DgEYFqEUOumXHZgpN+z7408SX8B/btHyPcn/FjOTjMZE0w8QaQfZ6BiIu8DcIaBZYudASXblHQYfTGVKzSGrxDxTxG+kcu7pqUBwuCgTWbIbYiz4vCDBjpiwW1GnJdKMfScqC0h/hZvANQ/wH64Iqwd4w0mnRBxi8q+ddtMI92FEIlqB71QUPRNakxoKm4Oh4vLSzELGsd2KtX30ZQLJ/VCh4hN3xYQ7/H0z0anpjWYwj8GQxXPJ6Ohp+YRl6p4KLRWvi/oCn4eJozPTGNc8OffwCjV6U9H0MfGKf/V5VfjNaVU9fUHcdJTJ/3kQVS91yyu8HZxdemc0DvvZ4ZsldyrFmx7uJLLln1h25NLXUNTfMOfLru4tVrV31Y171HfV2PZAO+iQCsol8IwHy8g9mM19+498Zbbtu7b5/07typbfPnt0mPS+/eeMstN5Iv89smL5g1I413EKBb98mfCBDo2ffsKOZ31L76STxEFjBEzL9O0+Jsknl4Z8VHALmZ1u/wsqPYxxWbHIOVj2FEmHQjcQNp02Rtg95GQXvyi/35rvKPJK+CqH0rQ+u73s+O4iqoXfyb9Ajdqf4bJtbxb3gCXeOmop3sDPZhZEANKT8yGIjaYGw0MSBnsLSwX01DZxWXsU9tMmcJqK8rwY046TViL3NYegSPfVR6FI/biZe14tVF0s+l6wsB/3LAf7GCP8AaBB7xBpZ0YBBZct1M6KoDv1rSNt5oxI1JwB99DI+XHnkE0BfiFfiSImlnKxVb9CXQ+BE/ULFBdtQ7VciQosjE8bRzdofTiDFj5Tl+f9rCmUCggfNa6kP/oJRfYSUpnqv9efu+wEuvvMAE6R/gjzzxwzOvvab+SX39H/mHubcFi0tE/WEw19J14Ax5tIgfBDQVgD3BDCyjsO4LKIB0T9CTSisg2P3XMqdWAyyMhdw2ZV5V5p2MZWiq1E4qPFuIEXU4Lda7phkNd02zGC1GiNi4u8jSjO+ahly6V5lktVIf8KNPP8q2ltX9YvgX5X8++ID75wcfSNPgV1q2u6qtsZP8v2AyGSzgAtktrNWKTDyLrA6z3Q7GjbMSJtPXYqjlUU0PMXL6dYtNOuPg2sXpi8bECr0EJu6ll1QrBAZOs0OM1jerWDpRNIIfYjSZgAHAAZ74r+exdKxTNnX7yfs344ipI31I+/FjmrHDHQ7o42vog64rYN5gDcZqNJNsoAaZjbGVE1/BH70CrnkpWTaz7baDZwRrhIBhSRIRedmH6bRGEBrCGDB8/bVix5+UhtDxOQHHVxA3CBA5VKZcnMFkwiLPQ/gAdJgNlBBtXGSJkDecgCQSNDSXif7KiS9/9dXLEy+//HKgjT/x4YcnTlx88Ur9vFkh5vEZBBNrxSaIt8w2o9UKasaZs6uEwjy/+ryqPEf6GQpoEyTdoc0PxvNBs7Zx+8G/6Z2KWg0GI/IavT6/1enk/pJ2Ou1mbE6ZXUPNRgcoAaqd0VBbNSNZq3u4TfHncl6WVV/EZZmmwUMnbeHWCUz8ouHL5zAi3jV18LyZ0j7csWNFv55L10tjID7CHQvZN5jLHSI/t+PL9h00ZirqWMIeYbbCt0UIte+i3yIdi9ljzBb4djF820m/hTouZY8zqyEir2PmKXBFAHeEwi2W4YD0JuDXbv4dFEFLUi18AMZn8KCI2eWyRzwBvijq8Bq8s9NWg9EyO203YDtLnvfxMB7n7LTHhVCYCc9OE0sjZzizekmescv6d7oXjSlXlHXKLzsDyq9SxtndRaoxMf/pdnz/dT+/lZklTcJXSpfhl9qv/eYr6W93vJXgHr790WdeOonxiR3Sb7dLT+7Av2LAMPD/xfz124ifdnHHbm4t2JUoIpnq61KDy8L+gMtdFAVPjbjCVi7qDoSFbjVBX6IiZuQZn6fCYmQMyGKwwMg9AZcjVWpymGalHe7KOIrPSrNFEbC9rQ1vNGTdVlKcvIGG0aBOZAOwxZV9liCnVrkmCD5/c1L0QUyMm9x+G46XifHmUvjNXep0uFpx0l1aBjCsx+8WGOatCYPqdg0dVfegV/rp7aV3jf3mQFl4V/Hwwc270pf+47P4roH9x0tf1E94z/z6yvn8ZGPxge/HbejX/afrWOzv9/xxPPMSX8MzuPYEbsIpPMW7VnoiKf40fnScMS8cwTxWJXXIsQJ5O2MtPxVVoJmpBhQxeL0sk4jH/YGAnYlwlVUW56y0wWLh/XwiwfvZcDRaNisd5Rhv2DsrHXZnH3p0IT+Z81onXW/yq+2Th/L85M0qn/yysvpqlcyHKCIP6AFjSKErBvd8SThs4KpWLkiUJHqvXHtqARm89F/pUyZw/+eDHizZv/Ch+5hD0tyL8H2rtp8s2bHAdJ/p+czTHsyTgS/BE5hH7znS7+JtkiSPkZzZHQlrjhNNSHXjsdFoMzkYE+tyGyxWEGneirlZaTs+hRmw+9iKjXY7gg+s0YVazyfNipdNBJf8S6xJYxL+D+9hDrZPx9dI608dO8Zu5A5JA+88vVVqx+xW9vk7ZJrGAk0LgO/V6O7UyNKieNxSwXEOo6UaoYDf4u9WU2oym1an4+Zim922Ol1kbzWvMG827zZzdju2sGa72V7h8YRXpwMBj8hXcBWr047qaDVTfbLjueO+0qHkz8cd7qHV1VyAPi1cNSPnTUZlRDOc8oCSnZ6bzD5HjWGGYo19MX1PtpH8Ut4dJrMlkHdb5H89YqyhmVvgfGRP++CFQ5+Cf958ae+rxUc9K4auWolvkRaRX4fwJ0cLcfNNB25r2viz4K5bdo588bX1y1paR67eNHHnLbvE3095hPLnoo4e3Dw+hSrR3FTSbbE4rIXlBRBKhyorORQuiBcXFyDWyldVh9xuf7nBbxibxlwFay30O+IMspLnH84kW4lrLY/PmWOCqKa6WlSXMtbIxnFj9rl43TPx7qSoPWBehVkn4z6yHw+v75cac0i4UWCKF49qa3M/fut8fu2CB+v74V3vSrNZz9zbNj53sP0AO+EXlZvrFsyYNRcf/+bht9trmaO3bZQOte+D1TgI838MZDKMilAclcE4b0tNwrHiSq4clVdUsPaigjIuYbNFWfBIWC5RWooiTl/Iybo4V1U1EypjBVGYlfYXRFkxXuQDYQGJdVew5gQnlputolk0c04rizgXeQgjqVopJ3VXaHSalP/iV6bdr066nIlQ31akz/XGWEW4yew7k271qWGyhGL4yCfLyFvlcexPsgOfkV46fB3888cn8aCHr4J/pBduaJdOf7dkOzPQKI6UDLZB+FZpIb719s9vx7uli8kv+Ku0kOn++eeft59MXc28naG+breO77kM8MgIWtKIhqE7UuNh3n0mp8NRXtAN9Wpt7TG0gecFYSgqMPEjhvdtam66JF3uK7IWlV6SjseLino1t7Q0N3Cr080NzQ1WsZ/b6r4kPRgWOGtQrF+dhjBDLQkI8YmiA7JLSZcyYEStqi9drWJZC0cTCFXkYaNkFOe+aVpWg/UKQ5Y8HybCBD5Pkzv7tLT2ZDcz+PD1fQ78Gg9hls+eOnyueamjT6i4W92ofjPbBk8xLOPj7ubG5Lafvh41rkdqxIjg1F5DbrxxYLdwsvuD7L/ve6l9FT/ox0UT5k0Y65xSUp7oG+s+v8eYyZOHWqrjw0pa4mnmffAx5q+S7piza9ccactocY75AL6B5jcCsBacAX5bkQ/1QjtTIy0QuLiJ32u12oyRwsLGqvq6uN9fV2Xk+N59GuPdQt2Ss9OofmU9Y2br67s5QrHZ6Ugk5LYwbmZW2u3meN41K82rYqgrehjQnjundpVwOJ+7uc+0sMRbk5+9Fd2syj+V1/pX0eWlpFRmdYTBb/2mx5FfP/3ivJln31+w3lewbCnr2r/7iv/D25vAR1Fkj+NV1df03PeRSTKZTA5CgIRMQrgkrVxBBMLNcCUccomAgIDcp4ggGDkEVETBC0RQIMT7vkHwWtz1xGNdb3Zl3ZVkOr9X1T2TScDd7/fz+//+k3RPd0/3q1ev3lld9Wp71lZXVcUd4V7jR48qwt6FW+w73Nctq7h+2thOpCL+otD75SfWHY/Eb+NOzZmttr0x/qdddy/bEho14GBJr9I2OYNuGIpz1y9z33Hn1de0aztkEdBPZAHaqaRM09WoOqC7lNH+SFYBn+/zeZwOK2/xWsz52aFCxPESbwga5EBmRi6fk5YWDOYU5nuFomLJlFcAgZytOsanZ7Xj7VwoUsi73K7qmB+57fBnSfNyOfn5soXSlK5uo0t3VBfnZrFm5AQJpi+cfck1uHxddLGGWDYiwcbpf2UgxmVRDuTbFcXRchDr8giGr/KIF0vRfP42ZVTO0m0VZ2Y9MueMsnVxzogePZ4tJT+WPKuOvDXjr2rFLcpfyQpflYo6D/DgjA5jQlwdE+xW4t74C5Xz2/7+97+/Q9o8v1Lr++0ItNvDvw1xWAiNUuwuuyD6gxZrULRb+XBWoB4POCE6RIfdZnddacbD2ArQA+Fu7diGByArnFe0DAwrWqfWLMmkWTQpozBZxfQyW4g+6qBZN/HuQy/E6jvOnX2oHnevPzL7huInx7x4kH97xndvqf9u3HVv34bP+bcbysif4+/23bed3B8f8vb307T3eLeqf+J3sPep77N3wrCPu+hKhe19dKVCZtPGgHxNApvfBt2sVOYgZMjGeVZfHud0FmSkp0sGg7NtAYaWnxfLt+d6vJ55sWxvhR3bvGDw7V671xQIhObFMjICoNvnxYolCBhNAWrcx2mS9D8x7LqiTyyfSuWmU7mPrRdPGz+/tBz2zoQEiRIYdskX5qarZY677ux/64RrJj8349OmjDULeX7hqq745Rl1Y4bcevv+bW58Ss2FyP8v+PSjdxdesb5nl/Pnb+9fmLMZ/6msYtPk2oO3Dbya0oAu//M2yIgbVSkFTuS22lzYbjFD2CuAH2ZzC16PiyOSQQLn22wwCFYjh4SEDSuKJkzXJf41W8kpIuk+GPzhKHVMMPeDmpO27fn77nt+DD53TrWQK9SO+D0ye7daSGbvJZ3ib9Ftb7wWMGO58wE3HxqhtPdRR9HttBqN/gBye9zVMZPBzNsEK293YpGY7eCii3Yzb/RwRuonam/1tEjAB6FAl5Su9US/BHbkegQPbICmUJZbBhvtsPSQV3Ff9Um6Pad9wdabLwXH8c+P3nvgAdjUcVh5ZPfBB2HDG+9mPqSAkPoU/5pQgJyoHPUEjzIGfDWgMxpYKhs75laGvYOHp6cPDucaS5E0ZnSv3MLcCbGOhfZuE2KhoRNi3srBYT4UUmRXpb0wFLIXcoEOV48KjJoQ466cEBM5zmUMQL1eoyawUDOHrIpLgc3AqbpMYNcsZ7maVpZEKdKp3MUcKQznjMuYLfSVp+FyK5bKOoGbVe4TJa/T4yZibmqnpghsQA+cYEOxps2jJfxr08ZGytJz/O4bI56rfeMHDZ0cb6NM7uwd3KlL9ytLox09eSO6D7q3zZJXiyvzsqIl2w5MfZhYOxZ2BM7pUBo/OLhnceaIsQOWXL1AHdymY8/cjH7/nr8+lPnOqo5j5uDpS65bqO7r2r2kV0+la+/sTbgNHlIjtE0v7X/lgLD3irGC+sP3j6sf7v5m+NDRA4eOGscdfkidq54fU7MdB+5588fGidmV+bmgy7qrI3n6Hi+M2qPRSseABzzXNAhC7IKQZkz3+MQORS5PgPMVkjQu1+/35eaGamK5nM9psNTEDG4Iql5JzREMZKfauxXLU4+Dc2kdv/llmq+RbyJSBAcx0RwOKUFOXw/MV/ztqG/3psqqob17KM7F5x5Z8TDO23do/z0rl+94sEe0WCkrKL+Gr3tGHRvfMVBZvsF1V3b38uhV+EV1DHZdJJnqn3Av/OPtK3fumFvWp2fngeryVX+jPhr1Y58HmUmHKCufRTNXOyyZ4dwCPqNNfpbR6LKZ0niSkYHy5epYnmCxQhWziDUUdDgdNbE2EGrnZ+UX5x/JfyH/TD4o+yxrsfWIlbdZQec56QtVt2yuzLc6ndZ8zuR2t6uOuTlTIi7TIs5Cqu7GOXTdkPguxH7WWwd/mvhR7mVUoyaPhjTNLm0Z1XdwFSJz0BmdhJLysMcRBheDr+Yn39b5q3vUb5+nLi0++dRfi1dNwC9w8VdJZ1F9Yf9Q1YTVIXW/cY9nZa67YUlcJT+vm7juh+XXr3N68iem/zZ8OH5xiNYn0Y4fBDzhZZSappT75EyPlecDJiGMnA4HEmQ+kuNOM6VVxzwZsHlEE1TaZIIA1cRnBsQA9aNE4I3oqeY+COqjglosbO2c6htIIhtBVpZHHHa6DnsmBrWe7wgLdsFhxdgBwufgB1z/0pil5/6J/7T0tte6HOx9N7618Sds2bAWb+g0u3BdZR/Dyy978BxcRjZGblxg2XN355czVdmvppfzhZ64ulidJual4yqoY8L/8YEHlI1uVfpLgbQMPksUfRyPkYd3C+4sk9Xm5F1Gl8EfTOezZNluzhKMgjEnYuAhGAcfB1uCyO6wV8fSPQ4L/BmzXJxoTI1iWjW0ZtycXaKab6O7OszNiSYcHdq4rggHTqQLmrscdK4LvByPEM4Pl0fzirAkco8Ne3vrLW+ujP9l5Zvra98cpn6Fhz/22iE8svFp/GyV+lXZsQ45BkM78sW57eoOPINu289tx2fU4u3nzm1fvSKYztYdRzaw8c+BjS9Dp5Q1bXJD6XwQIlaz2e3Jy8gIWowC4ZHNFizu2DHoQXyn8jYcz1XHcvmQyWyCOpsreMybeXPUj4rtxUoxR7+y4KCquKb4fLEkc8XF0Wj76ljUFXKDuQy5i9yz3SvcW9zPu0+7P3fLNs5NBx643X4/yJefT/TKUSG5QT+mh1q/VWsvoTnoS/rhJRoJXcwx6EEqMBAPVE0YfIN8rSuTyRORmK+gK+9yHwln51TzwzZnj1+4e078Bu5ag/rNstv9z7T74oNz/+Q2vhYaPWfF7W3IN43TjQ/cu/2x9CevVst/V3/Fc7Mzt7evKCrI2J6W+eG1c8JHtj19qGx7m67twjnW7Rl5c5cuWJmr7j7FfMYbmtysn8+HMtH1ypV+pwSBStBj5YiRWJ18KEtM96SDKHlrYhwH/CcFbcHqmNVmttnlLLkYaCmvlG+Xz8hfyIIs21zMlbrBEbXrEhaNtpKs5IsgzLsgmMt30IoKunw5ISrDbqfPAY7B+9g9/+HMhf0fGXPvLeo3S79v/O38UnXqpto7bxZGZKtnrxy93NXwUd7PV6qPhz/52IWnYgX3wyNt8xs//bf6Dx9f5FYvgDxtbrILZjEMdqSAjsQSImURKIv6N1RnQdhItywHBETg1rr5QqyHlVku9h0u6UTerB23vX7v3hdvG1prxOdvX/rQCfXnC1fgjnfe+fk53G7wE0casfHwA+fhcwsfvfUT+KhPLt4fcD6x/tgb3F+vG6PWqKvmLlKzb6JjCbfyQTxb/N4OZI7fhUMsRkdNF0Dmq5ARNFsHwHKtck3HkqLikmIUcYiiCaHStunpBRkZvkgk2lEs8qN0e/r5dM7EpadnZaXVxfKy6sfkta+L2dqCwm/bNk+SrXUxTq4fw7nhO5B4haqFiYVJ/q2oSLw3SAnEm2dhJF/mZ3GpLgWbyeJrdkP0kJy+ceVPbV65csO6W7BxW+ceV3XuUnFFt8ZY7y5DPbdZVk9cf9um9eMXe7YYC9svO0JfYOFtb549++b776ljHqi9Y//undvI07c/8Ih8067PX33ro/VLTZXDG8L0JRfBmU0/cvcI20Hr56GNiiPDC6GeTebA3/Vy+W3MlnrsPx4zm402IxwplpjNFrIRmbPZAjkQ9PjrYjk5LuTKoj86YjZXhWuQa7ZrhUuQOZeI6nHgWIznRS/SoulkLK3H2Ik+S3qa5GHdRaPDiwkQ4gosghtWri2CAE6YBLTSXyI7OjnJa9GBjt5tPp63Ljp4UNmaJdOXH9lSeXdleUl0yvKB065X33xw2+FgqF8onfTfunPfhifVF4ZcuHYh7560dupNqtAbuyiPeGH3JJDDivwoB6Kfa5UyZDZbckNui1u0GQRBDLSxibaCts7supjTmevNzQN/yOlNB7bwYq/NjCVORiILd+n/uGSQp1WseTi3M3lIwwEf67eL4jwa3zGecNhT3SLKEuB94wPqPzhu0wvYa7iNVC5a88/fVy7cXtCpc7v8sq7t1VfwUT5tVJfrG78Wejd8tncuZ7/4NHnizAm8Ht/89Nt3rli2a8eqm+I/3nKL9n42hPL4Q6CTbNDi+agY1SilvvaZmaE2OfZQjgEZUMeSjPZvxDLaKe2y3oihdrTTFqShnc3seiNmxqFQGp/2RkwfI0NfpkBVaSvSVbVPFSZsXRed60sorxM+kp0DLp8zB/xjp2RHUDvisaNoCcqlYy200QGuRJcJf2iz+vsTR9Tfb9+M5SNHsLx5rNr47Z0fL0BN332HSfzWFTi6+c7bl2+pHnygrmoY+f1r9alHDuBe33yJ+xw8oD79NW6P+9aq37yhfqjW4cqP1SNcxfLZCzZh1LtSfX84HQ3BXc2/IbyN7NDeU5ROPGc2G4wSxLd2l9/p9Lis4Aq77IE0B8S4b8SwKFplL7KZQ2ZiNtj4EA8m0vUubexx8F/BtG6rl2paW2sjDfVOeImLkHza3C5fuQuam3l3YQ9fLb4R21U0/e56yxUbdzaOmH0Qv8ldTZBTdeK1S1VEVqlFkT14RHwFyY1/THLHjtVi9W5sTOtoFEF9lQi4X6aAKQxyG/SEuXBOrtnvl4NpYExMaU7krI7Rl0NMTemeSTNTpkwNK0EOEK9O3bAnXMaiGsaFTh8dElTiyyNldkSm/hOHHtt3Y7s31IybVz+6/+EDa9apGW+0u3HfYzgkjFafUX96Vj0x03T3FxOx4dEv/vbjJ4fU3yd+cbfpetzvGezGPZldrG76jF/DV4JdDKFhissSCvFuj8cPbkVW2O22OEIWpllCITrBDQ6PxQx25ICDJ2IgqxUtpQtdZsqEkJ1H+Y1qDKcn7Eh2IrgcVJ1KDjJ3z/l1N/9rx85fb258tWTf8LVPDqyc+Mn26P0jj96YXYulex5ETbdvVtUH1Ls79Zm5vO1di8mt2FN25Y3q91SGxKYm/lU2nsAEOqMMHVImWkTgH0yMslUw87zJ6/F0iHCooE3QZmuDIiYzMRg6lQc7OPOcgbqY1+t08oa8wroYKri9YG/BkQLexhUU5AmiRayLQQRiwRUWbMizWPIMHDHLHMcRGlJU6ENzmztPmjVosnulRcCb1Dopw15lHJFxfkSKgIuJuejleihZCCxp7Q8ueSbhxzbGr+dI/Ey393vM/LrmnPrzoL3cmBU3Tlvmnmjt2WdDoHTUqMo2C+a8lTHJObd7RbBT5dhr2gm9Lz4t9I57//xn8n3cS2LqZ/FeU+eMm+rtpszOaZcVzIj2LZ0847j12tIOobYhb3rZIODrNyEYeYPvimQ6OlHiiCwIBPwlE1uF2cAhffllG6porWFZRWmnoSOx7LL7WByT/vFPSA7fteG1jbjiVq0vzNH0C12j0p5vOK/+yMbgnD9Pc8z+Az8aP9bU1PRX9vtg+P3vl/sdYfApXtaf/0T7/Qeay/Y3/Gz8GMpR3DxH2vlhV9wOF7XD7XCNHdsd48oc2nLjFWX6+mwyg0PL+UdTSIPT2BpOHwanHy7qh/shBQh0GTi5SXwuNIU1OIZmOG0UH4DozOB0w0XdcDcKp5iBuhRWF4C1j8H6Z9MVGqzjGqx7AFaxkg5gCigsVrFqMzajGgTRFdZwYxDpfxImXD4EMUcWPxBi8WlKttslUjdYcnFpQbuvKjbHjWm3cY17jnul+wW3KLtpVJ0ZzIQYwe61ibPFFSJn5EQFroii0chVxYz21KiBcj4EDIUtRjNipr20CMDpsJMki3fiJq/aPH2u9cmMPz/0xflfvjp4zlNnW1Vz63qS/eWzM0Zb73xUPaf+ov6knnvqbvPMae9S/A1oMv8K6YUsqL3iNttMEAsTIghWDikmdFifj8wMoD6KmulUiEm8vkhePjgvURp7fNulR+WKLVtWVPbown2KC3qu3t4vp9/21T1HsLEcC5pe5kbwK6CMPMUhm83EYoFAAJnk2QQTARW9Mq6kS2KuslZD5hZFvT4PBMwR0q0ZHre3uaTGSAv8CxSnCRFZFG1mq2xWLObDMWJBRe8w7N/RsS9hA+/z8ils1kMWLuO+SQWJV6Qi3wp3gpBsMjHcSY2MZfEyuOd2KqeQgTZenyNKapvB3Z9KpFTa+1CFkmF2Wj0epzOQaAG/1WDyEK0VoBG0NiiB/9R20A5atUZK7VLahajNxyktlDxIqauPjWxzu32yzWY2+3z+gNlnrfFgDxA40WYnWb3ZPjG5I8mfqa2XQo2UdkwepLZnnDQfs7GJC5oqGT4cCqKhSoGIAoGgBTuddnswmJ5hDzpRANu4gFdB3OEYQl4bb5ktYlFOYBfVqHYSBKkFmolOawGCZtcfIIsX4C/UrFcvxXhaFT/qj3FG05u+4ScJr0JU3A5NVMoDKM8Qsrtc0NbtO4Tsdosle3DMZglZiiyDLNWW2RbRzlksQnogkJ7urYqlI6GgKiYkHQGkdzLpltDR7IfpDY/dRqzFW3TmotcX7aT5NlI5mDknx0YJEM3ddvKTxj7yQ+3xV4ZtevnGybtzeeGO2u63luYvXfze13/23Dz82v0zZk+ufuBG7sBRdbX6zw1v1i1oODp50rCKTq+8m5+ztYf6Y/xfsbnr1N9Xzbt5O6bD2M3gMLwgrEICRKD9lFyOiCJvwDKPeZM5Q8Q2EVt4kSM8D1cx+N/gqzkT2s0RLQLvkr0sSVTJqbmT0TIcxR7M4TA2408v4K/i+yeqb3Gl6mu1/PkG51b+ovpD4wmun+YrTle70DWGkISyFTvHI4mXDLJAaIcdGw1eUZgyChKzUXthB3cgvvx57ne1izjj9x2S+d8XNFhBgPU4wDKhq5UcieOwgRAjJ2PRiI1mCwegq2MGOumEwzKSoTZ6pFBB34608JKjzqS2dtFhpcBoMg57gmRJfDt/VeMTpDL+MHe/2uV6LptzzdgZz4hLOzUcbiQ1/Cjyj9Q5N4di+GjLOTc3cl+RmjvuoDZNH/9pF6XzTNeex/vJx+Q0PJ+reNkkEjoynr7Zq4BritVRSbEeV5gcEUzDs/M/4P24UP0Qyh/Y9A9+mTgM+LVY8WEkigaBSAZikI0CORwTBCkgMrJ2SfFN9IYTIhi8fheOkg0z1G/qsPUf+LFVVs5/Y3ygsJ72w2agt/mD3FnkRlmoEI1WyvL9diHMmzLpSPb2nhxrzqGYPyyE7ZzBaQ22NbQ9FOMqDNWGJgNnUILtKg2K01tpoNN6xkX1Gb2styyF9LQTUu+D4Jr7Glx0WFtuNu2r0cYFCEwwtLcaB/cufnJh5z1Dlu+5b8mJeasfW7FLfeeKqcXtp1xVOX68WtNuas++Y8f2u5EMfPBTnLZ8xweHD36kfoM9Hw5Zvnrlyi3zrtt6ceXKO+bM26i1XymQfCf/OshEUDGDGufoTEcgHJ3GlqAYNCIdqhQuHc+LDXfzrzfcOZ49e3eTyhfzBuRCYcXmQiYjMro9gg2eNlGaF6Wyss9RytJbYG14DOsyuHv+u6vXvL9w6it773+BELTjl3Vr/7ENwizy3NdfvqSPx/pB7cKdE76CWCNPcbp5XrZafX4n8JhTMh+KSYh1ZbSYbUQhJ190lLG+ClCW3Kyhscf2DSrv3uXAYw+ObNdRGLVwbkP7R0+4tvq/4999tM65Lcj04UxcxddwF8CmtEdLlWvyDEGPwdOhqCByKJZWoPjSKwtol2lBppKXmek/FKvOxJmK01OJMu2ZIHuZbpNJOBQz0RtN9EYT+HfOQzFDhT7qU4/NmzuntKFW2sWSFrIPXhLTjGU0dAphygrlHivm2D6S+qsvE3Nje9f2WzesYm7fudsHbO1jiw3MWD23+7zesLtxKPup5/wrZ++csm7rSPJbYVr73Ojtw9oFhEzb+O1t89Svxm5tn9suraig6LZhHaJuSvf5qJwfKdihbTcoIy12B+Kx2SiJHG/CBEIos9XAu6y81e2xG2TDoZjFVCxXyTXyHJmvgt1K+Yh8RhZs4HNwskPggSYEhfgV/L38Yf55XuCpZNCOixuiryVJMe6G11pqJd1lYC+0WNc865IPu1iXPBem4bUH/7qz9s6fcPlzqolcsXvLTuxR73+eZOBR6uc4vA3P3IZz1E+2qdu2gTzPRxf4kXyVPoZ8kFJk4JFJgjjGbKF1kGUBU0x5qsJm43vxYXwa/4KFKoxtOIQJhgYcN07nt1b9SVFN0WF9m8991Zihbdwz27bFO2/bhicDDkDXpk+BrjeBh4DgAe3tAhf1hNnLc1qlCK1e+Xz89dj4C2TV2tvXvKv+NBbPVqvGEnP86JLaJWoD7jOWjNp2ZhsuUM/C15lt6nfYt+0M4995dN4Rf5qNox6kdJB4ZCQiEk1mCWooYTYu+4yIi8QKkYjcHLKSHCGcjQwi1YROIho3Lko3J5tvcGkNMZ3QIGgavfFBbnRjEDT7wlN44271YfXhXT/W1lIc5gMOI3UcBijtW+EgCoRwc/iV/BGes/GD+Gqe4/EZhItA49PZs+PGlVAULotBOTVOWCfxaMCAkfjHXXgUHrVbvfFUfAPFgOIA4SV/Fd8N8RC9guYQ6ERb3mgiBvCykXCY2ULkb6Giog4ZO3LDsL8Vf4I/abyLc6oL1YVkCX5BVeLrhhOE56qboQ3noWP8SLB5AspXvHTipQhMdChm4yq4XziOq8CYskrRuGb9iR3QrB4sbsXUEqrDSI87ECaZ8V08ER8BGUtTjAaaZMljNzHNe+pUMqUSjmijnNnLW5b1wUMO1+7f3ufakkh+YUbQGy2M75Iyv8Nyv875HXMKc+58iM1hj+8ih5Owict1WdhRh5skjA5LI1FGMmsf3JoCW3zk31/+pDakwm76jRTyZ8kzdBTYcQIyg1E9Rk/EcGPrmbPnSKHWHqyuDB/qJ8iEo5M+VHRRn/ShpdaAyCmztlZ85LfzOm1oGQL4SUZeEEQs8SriWEGoUfM3oazE2BQ6opZkkifjH9WSZ2obZrH5DL/RMhMwOJ6nMyvVVGRTYXBsMpiRPFkLSF/8lL9Dx5vWFfAWUOgEmEeRk4gAAI7FSCNDv7AZCWYjoQqkTbyv+Eijq1anFas3wwE4n+JwkYF4goK4FIco4NCG4sD91LA6STuGgwQxoxmcVkkycLKotkKkGVAzNoykgM9HtQyhVLowePmKRQCAMjIIKnexFWkS4JKIRRhqGm6/nefv0GGxdpJQW8UqgPtFZAzA6OzCFKagTifjjGQ92RBo4BDaYMAkDbMYwXXeYrhReIQYRIDHXRTwf4HnoPVllGvD8GPkT+AH8EyoTHEJskyMRrNowWYZ6mvQkDwaEyhUfZZpM9xoKuiwXntGzEQJDGvS9BteyJ/l5jC70kExJuZ5CzxrHyGeQL0hESY1z+/mdIMBlGgIgbx8Xlur7tR1GJ4R38VNYjIjoSzFSjiwv6JBlgiQF5q8pCKa6i9A+7BtRm0tnqbJkWxvliXAT0ZdFBtvMMiy0STSWTUqLzEU+XhCshIoIp2+jiQ/JQeua2LG6MDNqT1b25hN/fgZOh/IqL1ikQw8Z+CMyEREWQTAx2Nyo4FTtWGdLDFHc0+3R5+D6eDPqpsAHBNf/o6GWUJEpwHDXYAW7KZYecFkFCC4gQDNIsoA+kRMjJuaNYOOfzRB5OZyGO76fgZ3fTwHqEQEKBIqcfEpfrZWD002GK3KFatEDAajCeIyo6QmWrMh0Zrxy5FKa9KysK5MgEigUPBCqNfFAu4zDT43idGpg2LX6GRCRiCOeKnEtCAUl5is6jBy11M6aVpKExyiwW2mkygRLGHwa3jebJQZ5sY4q8JxqIKEtbZoZsZmOtGAswxHWKftpNp4DhFq1U1E4OZcLBD6sFrUMp1EeR54k9LJQlUI8JSB40yiVpgYT2inhqR2KmzFUdHEZAhdR+l683WonDanaoauC2TQBSaDIBMBXGw4AMB1MWJoFHUpKGzBUJq0wjF5rxbPb9xae5bpPn55o4vyk463TiciADyD2WLkOIvBxDA2NDDUj8dIXC/gsnRixej7GbXkk8atIHV4frxBfKShulYogXpoOSMWMl3L+EkWCTEZGT9d/F/zU1TnpzYaP3FdLr6j6UumIxg/gXWiL0Kw0cBfhKJws5W5lJ+wBhP+uEmA+3yNpaha437SdBqDq9PJYKIvWICfMNb46UTM2CDyFxNlxP9Y7mgx4ajGT41bySe1qlQbb8DzoRb8fY2dalvaOBPqAfUALW0ygZRDqxjV/8RSrfRUC7ZKGr+EAXxd11ZJvcLsjAl1VGxGk0REk2jmLCbdsEL7Nxqa2z9JuxbWlTktlM1Aj1C9rVtZpne5ZBk0Z5EN9VUcVkFwIGyTZbMBG+wOs43Vx9zA1LAigx42kosyUhlXJ96tpb5O0+Y001kVTG1q3NdQW3uWaTLGfvFdsh0YsDFbtjMWTLH3JtRdcciUuGYLMCHYwP/Mhql82IIRI0lWTPDib+e5z1BSDyXp6gTvwmQUjRZkNgmq4RIXI5rKkyl+BqWrEXiSWbKkv8EvB7IiLllGkq6i0SibOGIidodFkuxWC6uTNW7Q6WpoMDXbzMuIc6oBpREZ037QrrRNKavWMhWoWVTgWE0JEs23AJ1L66ooNvB+LGbOZLIYKG0NWtFyQ6ozFE+IYooT4GjpE+neAHBs/CP+HJAXmpL7jNIBpfpbJlSquGSjKBgFYFpkNgJ5L3G6dJl3tLAiSYMLpWgWV/e/dB+MS9ZLYDOt+ylOhE1GbHTYLQaDw8pxdpuVqWBbg8zxHDsU+bhJ59vEiMOU+nVJci7QNapJjgesTAOjq8a8RGgIQbt+RusrnK2tTfhVOi9R+hJiMZskqSV946nOYcN/pC+TF0Zf5sjpDhfXBeREd7qa/U9GX+BemchmE9BX4i7Klzihl6WvXiqUwpQqnp9Uq5pPyiXrlaSvwSQA8zrsNp53mGXZbjEzolrigsyULVg70LZJa/eH9E3apLIwrSbTTPEGnYnVTfw5pgS5t4CHQQnXpvrHLjRCSbPIDodInE6P22Y0epAguB2gIsw8UxInYrLQYE+4zBbKyzouLTxnR7PKaGW+mqc+JrRHUjnrWkTX0EyVtMCtn+J1Go02k0tiatrNeyxumQ4QpkxgijmJtRH0tj0h4YnRnsmmiaZKebME6CYwocHPAjvSNtO1uCYRrO3YeJ0kPrTdHMiHJippblH0SYLDQeySPeDnrNaAR5b9gsfrYRQj3gab1oSKMWY2xh2i6kwimUK8Vo3ZGl0uVXCiunKiTXs2RYD0ZmZNfPEpTZCYumL9qIjM408xnemsQxCzk4sIFVXo0ToOO8L8qYYofwru6qTdD3WFs+b7qXQXXXI/3PWX5vsZfNcJHb6KKiou84Bs1+8nUxP348vdT6bSW/T7yZQkfEcdRkLz7SUJ6M13I5oRMd7AT9VjJyplLjbSWJs/WYiKUBSVo26oAvVEfVF/NAgNRSPRGFSNJqGp6Do0G81DC9EStAKtQevRRrQFv6XMsOb1GbFYmDXLlt935BJhtpjZaeCtwpQpUqh80EZhqrNtj9HLhblzXYUVY1YI84zZXa/eLEycaIp0679FmDRp3tTZ/HULSVrJkJuFGTO4YHToeuG66273FfWsXiMs9Ha4avxqYeGCBbVTJ1037bp6zINqm1wzrXrMyGEjtbOxo4YN6j+0aqh2dk1lVc+Kvr36amdK917dyqPFUe2sc2lxUWF+Tr521q5NTiQU9Ae1s6x0v89lo44HPXPbzaz/UzsD+7FmxZJFS+hZKLZy6aJpw6p6Fef4zWjRImT25xT3qho2zbh2/pyZs2dqTyycN3vLxvVr18PZsdimW9ZeRAnR8yem3zi1cff655Lx2P+335RdfHq+Bh+bpsoGJOuHl/vqWEyno+bqm/C/PJb+4LrvD+5JvY7/4HjqVLxb2+K7pkzBu7Wtoem/Xz+lXWo8OWUKmTp1qjpF2041333qslfpA5eDJ7SZSD8Tapo/ky49nkA/E8fTz0R2rF2WfmIP4wg7Q6iSyeA7/9/JINqK7kR3oXvRPvQQOogOo6PoBHoaPY9eRq+jt9Fp9D46iz5Gn6Ov0LfoB/QL+hX9CzWgJsxBKGzCNuzCPhzEIc50lJRMfLAeG+uEP/2Ji056qB6bFI9wNnPg5sd+Ez77LDRoy+F/CZ+LnabcX4+tdcJ770nlU/fVYxvc9H72kOVPXBS+/DIydMXRBuErY9cZe+qxs0545x1Tt+vurccuuOl03ojVdarw17/mj1xzokn41tpj1u567K0T3nrLVjH7rnrsOy683Xb0zU/VY1InfP994Zj1T9dj7rjwg/OquTvqcVqd8Nprrp7z7qzHwePC6x3G3/pcPRbrhJ9/Lqre+Hw9lpSQ8Msvr//w9renv3r/87PGj19Ou3rxgX8If/lLsP+Sg78KH39cj7OO+vou3FqPQ8eFl719FtxRjzOPCi+/9FI9Divyy6+/ffp94ewHZ6kcO2IvvPLGyTPCB4ePnnj6eeHgwwe1q48eOVb/jPDw1jvvunef8ND+h7Srt2/befdeYf+KNes3bhF0beGILV259pZNwqKp182et1CYVDNJuzp52sw584WaQUNHjqkW+lf2165eUzVs1FihsrxbRc++gq61HLHSzt2VXkJxKJJfWCTo+soRS8/KadNO8Esmm8sn6JrKFOMNZrtbQP9qaHqSNu5R4dfzv8IvR2MX/t34JEZwj084/8HD+xfVVBb70fnzyF9cWbNo/8MfGOuxQZE/+eLrv/0ofPTxR/DMidjnX337wy/Cx1e6mjkEDJgJG2DjUQybsR27sR+nw1UWEOpzZv1F+kErFedrNbX2//b7f6/i/udf9M2uJ1J+mU34/+F6bqtrCaWaf5lN+gM4vv/l/fh/eZ0qzpb/DaCMT7X8b7z2/+IupqaT94Bm5nZfct+US4BN+R/c09D0P8FBV/oTL1H9NX9gBv7w+oTmj2YexqcYiQkppqKFwZiYaja0D+rM/ElqO3qjfmgAGoyGoxgahyaga9F0dD26Ad2IbkLL0Cq0Dm1At6FatB3tQveg+9AD6BF0CD2OjqMn0bPoRfQqehOdQu+iD9Gf0afoHPoGfYd+Qn9H/0S/ozjGWMAytmAH9uAAzsBhzqFclzZ50QNfC6++qiud/tfVHjwvvP125bRbHv6n8EZmzZL7vhBefDF47U33fyO8NGj2xsM/CqdPXzNz86N/F05mj11xzyfCs8+GJizdc054bui8rUf/Jrz/ftWcTUd+Es7kjVqz6yPhyScj41bu/lR46l9Nz4JlsuEs0Cw+7FPkYfO3HftO+KBt47Og1ixM43iwR7Hnx9bu+LNQV0x1pNCr17+fAx1nALUUhhv82K+Y6j546sxzJ196gzNiMEaKve/U9Q9dEF5/XZAtDg+ErfU4WzF1KOnUtcdVIkKF8ecwj404Ax53wl9EMet61tvzrXfeA0t1VHiNvMa8uiefffHVeuw5LpD6Z154pR67jwrCQwL7STl4+CgYxePCQxUHHnsCLOVR4UHxQfbTrnvue6AeW44LIhiL/TSxviCvl9lP3TfWglWSjgvru916O1gl8ahws/Fm9tOiJSvWMDNoXLh4+WqwjUcFy1SLZgg6g2VpEqaWz5g1VxWmWKdoV0eNrZncKFjBvExqEBx9Hbop6T9o6L+EvtGrBw75Tejj7MOAfwRavx6nHxecZz/+/CswrEcFzwUP+6n4bz+eB4OppAsXyEPieuNUa1/nhQvOvtapxvXiQ8To7QXWEoz2UeF1/Do8URfDahEYDTCuYHq8vzIzkpaZnddW8KKEVWDD4f5fGwe//TVfiZaw7P+ZhYDoKloWucymTyprtUU8UcdlNtzqRh9cy0/ZpFa/C3CtPPUctjBsUlnEkwvfLm1+W3Jr/fx//b1V+bj1uY4jfS4DQ7k6zBbf8DsHG/9OQ8mU5s/U5r/UT8POxOVUlaxfizclnms8ORVHQS+DP54ElXyw9XkzIIJTVDo5xX6bSv/p3Wyj+/gunD2B/kdqcHgi+09Ruy9OVD+vUT/V/sfDXpyR+OmF1vbhhcTBy83Pq59fov6bLyXvEk8lVH62fgClQgETGNCXNTATtUe12+FG1sewEN3Ij+CHabnWBdQy13rYEV7Ifd4Y5oc1hhHNs4r4t/k3WexBsxISIgscZ9BHWRZFU97B0kddjrCD8G82lF/Dd6Rf/LKG03xHhPE0vIKbzC0BOGk0XyWmOUrtDH7RqXHJsQs0w+JklceNeAVuZO8Xmp+TUBeFvvORMDbISAK1pphjDIjMIUJEuPB4jLDhKPZXtEl5zYPZ9NSNGvBr1LspfLUKT1T3sPHYffhXSfYf0sPAP9vQk2SrOXSuMSrhn+UfA7w9J+iQFcTh5N2OLh2Ly2VsI6PIiBJ+acNaOi6w6Rug36NwP8DmaYLhFNgyLuXvbJjOPxrfE78L6XOZvwH4E3T4gEsr+DLhn40fiD/MT2hYyy/VniHwzC69jJZP0PeQmN9Fi2joQq7VxzXFhL1IQDKqUtrwnIiwyBkM0KwSfS9okgUiSZyBE4/EbByW6WjYIyw5e8pUxyuKotHU4WVafhOabVTGUZknm4eo5fjNIfht1aruwRNxDTlN3o13JGXxt+MvkR50XNE+dD/fli9guWeKFaPfYLAjlBU2u6EZ6eRMnk9nDZqclZfanK7EGEiaQCa7Ay5301F9PTCd6xPJtuJ9i969afF7N9307pLFZxaNmPjQpImPTJ54cOKERyaSyfT6+/DTokVnFk98ZELNgYnwy8RHKCNNQyP4a/khwGk2No8rH2Lrcoir+0JMPRLi6akQSy9EK8DD6Fw1bdqwmZ0XLeq+tM2cOe3mZ9XU5Ew2VFaar0GKwveyFxe7S0t7XTN5/tKZkn/U2HT/WP/KVQMXzF1QjwN1savn9lm+eDk7vGpxp1kzZrHDkhmZ40ePZ4dpo70jhoxgh84hYo+uPdgh6Wrt0LYDHCremLHt3MUzRg/p2rZt1yGjZyyeK03MmziFTU2dmJeXDQdPxPLs7N2Q/ZXmrA1a11HK7PP/vE82cMu8gn+wo8NvI9llpdGSfP3bpX/79O/E71Krc/xffm99ntsKfqI87rPSzp1Lt9Hdv8rLysty6JFa3gk+h8rLysrJELqPp9ELZE3y3vhjpZ07dWI34zfob+pYuv8XvXkbPeJ2wK4dnKnvl5eXfQUneCscjKbAFsIOP9kp2iXeC452lZZ2Jun6TSoHB1/Txz7sXNq5LRyArD6GNvAh7iKyIFcdbzRabRII66mkAmRMjSLZqAxYnEyZ9ee5qnqiTlVnn+Uuzv/LjBOqirm6mR8uZGPzcuk6MzzNZeuiupk3g0LyYLcdwmuAWXQq+W6OjskLO3ArKcnl1zTyC95euODUggUnYX8jv6ZhGblywckFcAwXF9IswallRFhGWbc53Z0OJeXiHEMWtvuhrE/fgf9WL6xZia3kNP8yGAyeeGDCBBBCth9wKTrJ32CfihrYhll4HTeeuxFoGaC2wYqQW5LSgpxPtw2cnQPbwBmNDqZKjH9gG9iAQC1fnK/FRGVu/J0Tes3ptfXaqX2vvmZKnz5TJl49oJosu+62K+f2nlp7dd+pfaZM6dP32uk0L1AQEf5xfifTZ4WgNXqjpYo7L6tdSUVJVm8egX7rCwquT4/O9U1fnJAtlZ07d+t2JfOaywoiBfTFhj1WFOmmmO2V3SLdItCYVBM+EWNqEL7MqOhkYXP2ZU1Cdc3YbIT1JBJUQ2ozkz36TOXWGrJcn3pO55DkphxjfV4pI0l+8B5s37MH2/bco57fs0c9f0/Fpl9v2/Trpk3/gP1tPxZkZLRtm5FRgI8mjtRpXZcNrFrapeuc033njexABuzB9nsSD1Ng8NhtFzbS5y9YtEcSjxao/xjYtduAjo+36dUb8Sn0DIIeLkMTFVd6ttfexp7dgTcgQznqFHIFXNq7y9xAUVlZSUk7GrV4YrYAtgHVB5XMLllRIgRKAiWUeK+w1Bv6zPyEgsMpiTcupRlLXaDPqxFSjjFbW1LLrHQpiXDhZcjSof3Iuf1Oz+kK1Bm0rMslZMGdUuhAv9X1vXoVPN6REgTkPK3pZv4JPhPoEEXViqtNTjjMdbDY7T5RTOO40jJfIfAIRE4+nz2cE2b8InbUZICbI2JRtIRycA4qGheNwlaYeLFQmJpoPTE3yuXrVA6OvZcuhcPy84h0RRyRJbTJl/LLWcayTuX5rhSCfLF/5NTKKSMfiD7QR/7uO2NvOBg5pXLqyP3R/b2Nf/ub3Gf/3Q8sWvTAQwsWPMRtfKC38bvv5D4p9/SR//Y3Y2840KCoixc8RG99iPl/3VEf7nZ+G/KibOABr88r2Fwu7M5wmEyCm4vkuJ1e5KXdvzEb3E7SaLVNMSs8aeaIwZDFJN/QLPklOgekLhaRUn2IUBKpI2nSQ5olkoY9qbXFo76fu+3wkiWHt839/vvK79utHV+9Zu34MevxoresB+YsOXx4yewDtrcqv/+edB2/9uax49atprp6P5rL89x7yIPCaKbi9yKLaDCYTSargNLtyJ4dEaycyxWg6AdixS7s4kSLSVJshpChyMDJ4KFxXIhVhkPNiSbSTp3s0sX+SnMyRzYXhqUqSE7YZHoNF+Gwz1GEsS7n5SkV2n94yZTBGH9JcH9fuVttUmjlKpPVunvJYQVjd7lPPU6+VJsGT6FVTNaM+p9TaF5d/iDUrFhJM3tEu8cRFLIjst/s8YT8Rf4KP+f326lT2qVoXJeUvLBU+Xp91D6w+dqAkydcBmglZvCUg8IiKzdfv3r6LZO6r809XBvPqj2ct7bb5PWTbrl+M39wxIcjptw5aObqLoXr7uzc+c51hV1Wzxxwx/XDzw5neE0AvK4DvNpSvBxpJk+aN0sobGfNcKSlhTKKMioyuIwMz+XxYlZLlMoTivFS5KI+yinUSg9f2qtntHz9w7dMuuIWHcmc9RWT1z+8vjzas9dS/uAV1ys91+VwG26YubpbgYZqQbfVM+fewuWs66lcfwWlYVMT0HAaSqNrIrktZoEPpsvMj6codSwWSvPySVmpliA3mjCrnJV4yDUL1/7Qc64Sq80UM+8Ypczt+cPMWCfc6909OOO+PnOVNZMmr1bm9b5P/WrdzQs7UrqshbIqIYYx0XhBNFsgqioqSk4zc7qiTpeHcBGy9vevzF/9TndkOIfTacp79WtO/Vp9DXel4wrTkJ/s5KfQVaSwKx17mpdz8TnIWvctI3qP2TC0a1t+SmMME1wxuVfnKyf7uF5If5Z7BJ5NRzmKzSlJFi5gCWRkii4jgCuKnipqlc+dmq68fEdqEVGddSTOHSmYNTpRXJ75ppEDyouxPW/eldMeyIwf6DVJL3j+ktgDUypviVIazGl6j+8Ofk0QLVf6p3tNJkeGwRBwBLLCG4zYmH5LOp6ajoel4/QNMpYz8jOwJwPzGTjDf1NoQ4iEfAt9631khA/7/EgU3RsycabfWuHGbtCygPs4Zxdwv6I0qQH9Z9/6V0q1mMbJTdZHaFG7XDjjxmtVip9PVI5suqUdqw05Mbjx00TNek5urOo1ifmEzfUKIfSfYOPcMuGy8NWuxB4/r5WCjw6On2tZCvn34EWDtbkhO5s686XCSVbWIkURTTZOSndxXjBKRCJZ4ZDT53N5Axk2Z6Y5PQ3zppBgMDszvLzdYgjxaXxQtluCshy02Hm3xDlRxSuvJRI6alOVWuY4dERLinCR5mJqCZNZtxrNP0mTO0pl5WyLQvWijnKP5CgX4Ae+9I0a9VjNG/CpwdfQb/Uj9Rh+Nqbeja/Yq96Fe8TujeF/0l1f9Yu9eKz6NhyrpthK/M+9qonySrWey9wD1rejzeRyGXiLw4HcCJSXk3CkBiJlqyiJNTGTZJPA8HASJyEZXGZ95iuiU0W7sByhlwZYdIxPCc1lwZzmZMLn5DCfsOenzfB5Hq9Tl+K16hKyF3+9bts6/LJ6BXyp9XczedqDENcB2sKFeikRwJE3uDjwhz0UvyodvyrAj6ImY0RTMGuJ3Vqik4zkUxBJZJ0m5lnwOUZ3xAxFk+z4Z/AVv0BpJOo0CqKBShuny2UJBJAgikaE0jO8tpqY6HXJMlDKK3tlZOJQoBVpEmhcssBY1JEP/jhd0xsk3sESnUXZtERKmEh+cDW5blje8+lpoTRx9eiacDrZS57ki4umLeWIGH9CKCqeO1dQ295N+dXD1t/szXzKa5R8v1sUTV7JDvF+eoZfqI75ZKNcE3Mb/fAnmc3QemZOapGPPuF2Jwyt3mzY3Zzb0BEu4aXScIS1Hk39U73w01r12+dvuw2f/BlzL6j1v+Fx6j51+0Hu8WWvzIqr3MR1ePyHL6mvrntTX5PtfraWZG/WBzFYaevyeu3pCJk8brffbhdNXFbY5Uv3VcfS080epzlI0TRw1TFDevOQU5qgsEXS/Oaszs1ry+eV6YmKJByBv9IClr8MTygq7V7Sp8eqjfjL7y48fQ++/RP1jp+Jop5Rz2P/HTuuH3yNfY9j2y3Cey8e234yLX6QVODNn6ttV7JcTLPUUXwt8GEBKkadUDd0QLk2v21x1y4e0V1Q0JGzWLtFOnTwOw1iaRSLyOWiSfOsHOK7X2HoYoy2zW9bFSst6lY0OCY5PbZuoW4kwHXrZo/gfG9WcHAsy+PCdmMVm0lPiixbLE0WzgKeMDRoBUskp+XwpCNio9r0efCFEpGSMzWRjDMlM5eebi+Imc8RdWlpNpzhEp8rynk9jmaC5UesuBBzrh7kCiwJbp/LinFpvlQ+67kTn/5mWFk84KZZpmc64LWTB9dtfndu225p4V59J48Rxd4n1piOnZ+wc/g2db3y0JKZxGIdMEYdhQ9c9f3Dx0Qc8g4Z7cA5AXyn2m58vdqharA0xz59ztKp6kwSxNW7Bse4v00twgtts7DSr81jtNf0NqDzVKBzOvDIHKWNkJER9FrMMm/w+cTMAOeX/CRIsxsHnVlhfzDDEvDyYJ1s9dioOGJur4RDZroiQkwWOGxjKWf1gZiJJJ8VLVI/pSR5ZBMYo3QmM5txGcEJ6uRzERewVBBHnjvQdRG2PLH5Cc8wtT5/yc37Hnlw2TWvbvk17dg773CPbsZp6l/xHeqszfGAkr2hQ756JcnrPpTcq7bH71Ndcr86jT/O5HSI0t4kSQYzz9sIxjaDze4wiaA5THbTERPn4kwm3gK+sZOnmbudJKgPZ6+IJnInpBpbPQmbNmJRG/UNG3/88V3x355/nhif3xt/A+8ks+O1Qm+aorhhDODyJOCymdG5QslK93i8RroomlfKyPSBL22WBsfMHmOQc1TR7gY6kjPBgBWXrHmtL0ITZQiUajPRGRpUAKd13bfsyEM37lvftmb4il3HjkmYWzVj0uF34k/EvwGkHps7u/TI9vhq4aS6/IrVRs3v3gy4vcXoNEhpY5FlI5KsNpuIMQ8WyMjZHQaLhCxItJo4o1PE1THRyaeSqEvLZVNSiCRjhiWzrTRMJnPxqY2PX6UG9gGhup/j5PidjFbLH1ELgVjV5D6Kz4+Az2SWh61KKTCKomThTWYzZ7XSBNQS4CMYeQtdMchmwJKHswJbe3ASoYr/hBBOxQaw4yfvK1LvWHvsGP74fbUfnjmBrnSBf52ozhZONk4gFrVITWM06gc4rWG5HborISNPIGyUZZGnU5XZYg4Sxxs5Y3WMc2qYJNO8pqpOfcg1nYPhwWF+zeONC7mSuI97qfEdjpW8hU+7e2PDl1DefiivgO8K5V2hhCRsMhiIKHIYyjMGRY7nqmK8DUtIAn7xoJTi/BUtC4wmSoM67yfb41u5zvEZ5Ol9G7i8jRsa/xL/FO/U83H+yPcVRiMrCqCuSoZNMhO3GyxaWtDCGcFGmI0876yOEd6FqSWLahnTUIp46+uElYEEI4cdgdYrj2K7E4TaAYqQ8H2fm7JPVX/BDiw9Pn1dqPHXg0d2jR50+OAD/avxHDwAD8Y1YwfEx6u/qL/cxPVYyRaAwaiG5qXlB4KT1F6xyAZJNLvNBs7jdRJQQSdiTrvBZpboiiFM4SRqri9RRO1R1OX1VWCWyNrH3xwMty3xqd9+qC584WdLZ3vXzW0XTxvak7vf3rVX40m+a1xp82pZHT6zYVkBHROLkOCGNg+DL5IPJdusHEZOJwdmMhiMyAZDNvCk5PdnVsf8YDmdZiyxPIfRZP6tZI9acwp/7f2GiaatjXAUuU4uug9iLQGLlrmde+PM6EEZwTkfvP/s9Q579q2HJwWKI4NN5SMHpfWwFvqd2fkmvAlP27xWzRR6Nz674d37yGh1+tQ4Hk2Gj5hWbJa2iF16M/p5aKci0K8NQuEIV4RtmBWbyXmAKFGXr7Tc2Ynmekkt++QCRxtP3pK3Tzwxjq7e6IvMenF6eVpZUWnJeEHQEWhjxId7Hxq7Wx0OVLvPPyg2PKPmVrxSXfFd70fx6L93ilIcrriS8dYqaMP+fG/kR9lotJIXdAQ8AUHkDIRANGT1I2T1GPhIDucIOgbHxGCQ+G2mLGje4zGT3UM8ialxKVlSmnPcavnbnHryNo72LDV3u/i8IQzVBAOrd1Hw/dWZH742o+P1eatnjr1h0qzhrhyrvetv8bPZ07MzMopoKjQSyVmWP7dyyupFk2IrS7/quL6srI689FnpwG4DsgvzGU3fYgvg0ZwxHZWggOmKn3TFw+pYlYD3CkcEQvOyaWnpAGct/VbqfD427WEDaMCbEkZiL/O9A+B7HwOZl1Ch4sV0cRRikDE/OFaE4SNKNrbiCQXZKimNNlHlFP5WDcDzaqc1qgvAMNrngFw/wg8BPshE3ZSQWUi3eRGyyQIfypIDrkBVzGU32NNtxFYVI96U6Rqo5RKo2B7OQo5SJ00VyFb+okR2sl7uAFgk/pF4vfqJ+u3nr3qWrtxy1+49Dz3/7Miq2+/bQcriJyDkD3yL22bdEvxL/TsnZXLlix+on/zzxffVX+PPSB9p87+GoI3cEm69vvZumoDp5BmDTLC2DjYnCsjGhTjC0e7HokQ2aUeLGbc0JT9s3JL4WVJAN/LN+fvPxy/Ajs2FupqrQ8ea16rk6bxthOhEfx7CjopTXVq8hqaLD9JQoW738CX8vK1bnyXe+PcMzlHuX3i9DifEVi6XaIoijmNgolH9jQlLsCTjfMAr6sHr1a0j8fXqmt3CZHXrCHz9qq1bAZb6M1+NnTqsDMUMgGi9iYZR9CQdTMLyZGoz92gecOykWfvU+3bz1TdNACA4CUOg63ZiuvIyEuhSy/rT2rPAdOrP+KFl8U/4jy6oWykfN4ExfUdagGSUrVjZWrKc0URXkzUkV5Nt8eqb2a4o5t5Rv9yqfonHOPAk0RiPE86Hh6sHNF+iBUxZkniI3UwGnodA/lKYILFYm4oCMO9xqA/gzK04UxinHsDDfYSLxzXe+Df3IPlAOsVoVKA46WqOdFFpjAVO4PeMETgtN07zQvHJtUbZApJ3Te/8l0/O8u+RhoY/79x5KTy6VikdCwDqSJLEPWPYouiXgwf60hMpIx/8pfP00rMAowG30+DhB8gHehu2VRyXwKvH7fRXqF3+A0AAogGkdFT38tNxZ4Apo1zFTuia8KIkGaFxaDpd2rTJZSX1bAf60BpHGHf+ZdnhZWSnMOivf/0rnkRhAcDOcCTTPjKDAPjxmM5J5cGhQEWnWoOC8E0flYM7x6cBrF/wJACltW+6OpJsb5oPcXpbxUkAH0Rf/XPIINH1N6CNo2mnSlpndgqCFY7kS+k/PPrlge13qCNxhvrVc8/RtiUCepPQnJa6LLGVOkHuBZ4jEE5EX2mxemzqkqDcdadPx8efPg30N6IL3EvcjMTYEh7RORQGGRGBriN5siRVRySSwhhJfbyS1JM/bdumZm5j+d+JkcTIy0yO3CcEnpdEwlO1kHypCpazLEpeLhscfZL/IT6L3HFOmytr5KpSnxOl//Scei2+iz3HoWHQELnwnAd8rgw0UilymUHNE28gkJZBMjJDPuS1e494v/DyDs5rBAVtpPm4wB4EXYItDTPDGE3MP9OGVbRI95pY405bK0FPvMSWfYt6XJSWtN33Htu5c/XN/UvbR3r3eF89duwYd6KxH3dizeJtq80bDH3GTliDpz/66MUvqG0Ee5KKs6JkJTAmgbSgD6XiCCh6dRSTGLZwFv8YtcugdQlSjf2EkxdLWc5SYsR55GX+bWceXcraIfG/IqQeR8ZjuMaKrTQpKGj4DOFB7oj4FYQxtqMiMnL1eChdjqEkmXA8qr3J4I4c27Hj6H2jBw4YI35V++iR2waMG39NUxM24e4clGHP538Gto3Y8wVDE6ZrtwsG5ijSXGqjmz7n58I9ouBw03M7kOIpwEvkm9jv5XDeh56DnNDzJXA+hJ1z7PxROA+xcyM7r216n88XV8G5iZ2voX1j7HczOwffmPuYnfvYeX7y9wCT1RWEwPk0kIp2ikXk6HgeLBtEgsF3Hv5EDPP1uD9dr6RFF2JyJnqYv6Yxitc/jTcS8hR+VB3Gygg0/cYfEc4Brf2M1v/GF6Esp2LCad407EvLcjhzceE4Rxnca4B7D6TeG/873Os+xm6tb/r8WFqWP6DdnYT9QuJ+oPSvqL7pcfocoYFqkRIied48nJ/XjpbxegZWMqBdl2TgbRl4dcb9GYR2jJehcePKdJCoNQ6pMBkuRccYSMBF8ea1o8ikgMMZUAACSHhcS5j2pgBr1zzarg6R//kn8Kgex2n1TeOPpaVZXLmFcCe9T93f4r5f4D7XMZzBZ2B6a0YGvXWcfq/OK9q9wMNNm1VQzooL94jgNpFRESJF+kYWRjhPBB6+XzFGIvA0jtgjGoqF4yiSGn4DAdYyJg9IhzW96TDKqcNuF852weN/VywuFzLnYtd2Fz7jAgg6CK0d6KTuT9nzWH/eha5BfZVS3CdUFyIPhLA7hIeGcHYIo1BxqAbcslAokJaLQ0WhQSHydggHwO8O4W2h/SGCKGJJDJM4JmQhj8oCK6NN01TUrg57TXi4CXD8t+IymQiXi007TLjChItM2GbCqBlYWQsZyqMyxOA0UThHSYBW9ILidbk4MZe4drjwAy5c4cJFLmxz4RSsGBy8HOpcALKbJ/BTNDhTgWYjlTbYOMyI3zPiVcbHjS+CpjdiZMwyFhtvN/J9jZjrZcQu4z4jIfVNhxSXERg1F0tbJLxCwtUSHiQ1Y1w9bhz836AxKSsT2px7lv8UyhRCrEz1d8D9SiWAPX09eIcHD/fg+R7s8uDVHojksjxQyDbF7vHIci72V/hxkR/b/KyEZvrq/LQO/P7R/OdAF4nx3q9Qm9I6LIWxNwyE+V0JhMOiFRjodAQ/FcGbInhpBFdH8KCITpsElQHPWtKH685oY7hJo81i0FXzlP5YKpJWQG25UxI+K4FPIRrxAiP+0IhLjRjIFjHiNcajRpJtxC8aMSMdJRynE26fERMfHLrgG8h3jFEP6ET/ErS6ge5vYGKdlL8adQXTe3mCrLf5dUC3QiUTe2y4zoa323C2DdtsNiLm0q8iW4XtjI2/RE4S+jaP6ltKozcOowFKN+z29PLM96z18C978DmN8sWeKk+NZ6/niOeMx5AHLWDJxZ7THvyUB2/y4KUeXO3BgzwtSZcsJ6HH86gep+WA9w3xB3b0dWCPA2c7MHJAm1w85vDxUq72aKKuVqbTaTtatGc7HkY9FScO9g2eCJJAEK8K4qxgTRAI+CclEAyL0n9vU51HcC7w3wpWf1uKnhighLHkKnf1dXEPuupcZJhrresV1wcuHlSHzwWt5aKt9Yzicrl44EMXCFobJlwfuFKZvVqXdqbXf+QnsnLsWh3IYYicw3S9K28Ek0jElZ5L/isjavSYp67Q9YZTgzXnMPiNbhw4HcBPBfCmAF4awIMC2Blofpw+dyPQcQR7zqU9N/8wiig+nHU6Cz+VhTdl4aVZuDoLD8rCzqzEo/qzV8OzvdizHp1OYfUDmmcHjwrivkHsDmIUhAbcrHiCQaqyghVBXBTENcE5QWILpiqtZD1WQD2uYTC9Gj6/fgQcbCLufm7sd2PJDfA+USzuNGTLJRnbM/AcsEU3JKBoeCXsfx61/0k5AMpeVg522HCFDRfRC60x0m3vAQbLr/tQTzU9jtIVxx9bxBY+Rx71OdhzRYBDTyUN+yP4ociJCOkTWRAhH0bw2gjOjuAaar7+pbgjEZlqH1ukKFIRuT2yF5pfRKlqrEz37cDbelnsA/DBp7aL/N9Rio0THtdtnMj/dhdC1icRblp5TDNthWXNMs7u02T8t5P6feuPeTwGS/I+xh/sPo0/fntJvy8EJh1cXnYf+FR0zbRj4irkQFcpXoddNiIBgilBtBntostpE0Xe8TweiGQ8AG7mYU/w1bS/lPbbOKKt1rR0Rdhqh51c5VHJSiQcqbvnqRH45R3p3ud9xu6TpuJp3/FFZIh6dXzrJkw+//i6R3dMUSMUj8bv+OcRL5ZATJemmGVeEEwy2hKThW0QG2q5KBj8bF6KdMoJR3kIPE6MX7cIL8cWv3Biwernjms5HeL885yfwUlXLBC80N5/w5YYSgHEOkOiWbwvkpdTiDk/NuMVi9aNV0/8AAgcf271AopPI/8KQsIZ8K8BH8lgQFYTtyVmMgCYU4WJbgiHNmhQirDe2Jojfcbc0MN5R9YnTy08yzf4CnwdSrYs09fbRPwrnADwrBDRWUTJapNMCoO4jYbSej55mmxAX8EiamV57Cc83nvtave2wPVPLB54aJRwl79tac8pN5Rle2j/2sdqjPzStAfitDzFCDE1DdRZ+kBz3RhE7ITQhJsthnSWuSBKwh8PevWgGgvjnFz1CwpH4I9wXwnHkAm1UdwckY3EaLbIEHNuGoPEzTG0la58lDrwGSBlcVEdUULmq7vl/cLYGdPHCftl/gjmB1RWDlAbWR/gx/x68guLJcPNOArgsJufGCNs1dM4X4oevz6BHoPxNPlFRBoMAABg9Ho+MYZsawXDw0XKXOQXgCGisPpJLs7S8kirI7leEJfbaR1tohkCfofTZq2K2WycXBXjgqhFPiTa1SVoA5y09QxZfqleX5wetL/9jiUrb1Wnk/7pT7+X5tiUvXYh9+pmhmcuGUBeZ2sL9VUCFrOZiOBCEGKzS+LXMSRhmZMkzliPHXVmjDBcqsfOZO6saFGL8beJ8D7qsOJIGaWzI+rB/da7Z7QvmRa8aT4ZcB3B+Z0XVpTF510H9btIBnC8MBiloUFKeiDgckkSSjdbLMjvRzYztnJms90ufx2z12NXHfYjf8vikyPncBFdfbookfCqiL7U7IHpgLPSSPMya24JuD7suRi8bvSQPrOv6Gb4P609CXiU1bX3/uv8s/+zz2QmM5PJBoFMMpMhhCTkZ0kIBJAQFoddWYQgEJAgIJiwBkFBBQEVBQpoXUAsiCmtBcVK7QuVfrYqWn19KVTs02Lra7++An/evff/ZzJZsJUnMSaE3HvOPdu995xzz1lv2LZk5aoDjTUiXEONuWvwsuHls2KrBpez85Y33LNhZXxEzkJFD/5ElVJfITxzwcPSMFMWNDNpXm+GXbRzwMAb+nJZZlE0X47vEOEd4kxxiUibRL8YRt80iTtEThBF2o92ICOdlub3ozX48YN4La29HB+HW9Cia7At2YQ2uSZcMX7G9KXLiA8MusKWkkTdlkg4CtAvJC7NatuIWFEeInwiDTC5Zo63p0Pqq633L9xi2iIMKRgw9Ik+WcOlAX36D+VaDJsXLHpgWOX4Gtozd3XDHENZedmQlYtKhsYiFSX6OcsWTxs60UNZ5hAf9s+pGjqG5EQLTKBGyhQEDYRGjqJEAwMYA3M5rmGVkvj7DWcMrMEAddxpKCIBI5Eq7C9XvCS4q2SyEk4Yy34ohj2aSFJojg6K1E+a5IfggkdW/yPjKhSoLw8enA3/LuvnwktR+QwcQmSWoaqo6wgXD5guZTrsZrNFFNH93IpTt72i40pcFF0uw+W4y2WhLfYrcQsWXxoJEscliN2lRw/oVlM36RohuSlq5xlMVVywNsjjyAZ1fcOKT0KbdCWRxuW5Efu6IHxRfstaNL7hAXrY6g1nTAPCu7akp8NTSz8sfZDI0A0k6zSJXeZLItoqBA0y93oDELTClbgWk4qBFpB0+iv6TNTJSNlDRRZcFZmm10zP27R0j7ya4pnfv9z6xrLD0PfOUuzHgiIl0RySUR2wg35gkRTpmx4EOVwwmOMQvXqH19E/v296umAUjJfjM4UlAmUS/EJYoNGHkOnOpC/HM5FYnnRbL8fdhEYpFJqptC8BJWLPOtSkF0dKnr21iHyLrayapVYcS0aDiDAuzI8OzI3mhwvtKwaVoP82P7hm9bpVcx+oX7xq3tASprmssDQycFCR/Hnz4KEbS6V7l9+3aGc2XdgUv7d+WnM+bZ1C9kxWPtNxoQP3lTCdpAFD3p4plW+wd/L6L+QzZ89iH24FW93xNfcwsGC/K46oA62W46z43ZsJhNsi5neSvTjIHouXwucgdInuhJAdeT3at7rKP6X+q9qpDZUFbLs/wzU7/YnSiTrbFDqd8HYH2innkp5A/SQH3jZZVm0IZAKM2hAoabNSuowgYVI6AVFfwDU3+sLn5DfhN9u3b6fTsW2m5Q/YH8E8Pk+tFVIkOTQCA2iaZxi9oAMSiwzyo1MZZBKrQEVELZneFkk09rMoKaA40zVqz0JQthy6+dIh+BTu0sX+qBX9+WcTUOH8kMDB78gMoERyIx2jGUbLCYJBqzXqeI5HcBh0tSSgom1qQlISUOIpV9TOhmJOFeTgdvn6+msYJp+nf0n7AYaowHsPwYsieBqgR3vbCCnA0BoNh4AKer2B5zizwSAatYIWAUU/hwZBBRspScn178wrUx3cCDofyolFnYk173364rlfP72nRUFBe/Ql/V3yZwoWvaxZazBwFD5XMALHqWumKPYWa+48PtpDWTES48Ag56+Xr7d/dQiaDnEPal/Sy2vVRVPyn9mfQqvKy/7oxIJOBgzLaHhmR5zH/Y4enarwUel2opzWEkXaonas/ZMPnSes+2lr69dNZM632HOwgsyZhk77AQD1TpfLq9PrvS6zWbM9bjbbaMa2PU6jUymtZ1rhCLyQvBS71/nYhOgxtjEZSg39EA6FOx3qsQ5aMehd0QkTM/v310zV5Y2uKK6ryyjI46bp+9ZwLzfJe7OzQrnjq3OzsrOzakeRGK1czPwMvsuuQ7KbJumATo+4CbQcPv1EoxciJOBBkj5DuNsX+YTvTskN/zZMPqew687NRX/OEX2/whynzrFfEx2zo7MtTVFaXnnUiEipHvgS7wISXFLOfDinKUrBCfI+3WH9mTP6wzp03pPOn5fPEr58RPiC5aAPjqZAEnXg0RlIo2Gb+QOgwtMWFUvCyvk5IemE65hezZjjcCAmj8Lyo00qvzvnzZFEGscUNRpByzAcB5uFbtPi3MOE/uCK99lYd3bijnpEd3K68tsJfKBUcqNDiMvt1lhttnREkHQbg45LXrdZAwijIxFkCnDH9xQeJ7Dvlcc01p9Y0y14vLf98/Xsua5MhvP1G7RIlxS86pT4EdZnFmkSB80IwYDJbA549TYbOr0hVeZ3IHNp1iiS+LvpESIFlm5YJqsg4/6DoRjsXSLzDsl/OQRfuAW6fB3WPLmhm1RSHXH2CLyTO03qZBZJHgGHingdwIdeuCOODr68nw/zyMa2wkp0bZqO1R6m5rCiozpSd8yqQEtLwaX35FNczkPy32wQ+v6BePQamr+G+zuaH1sVD0DiJECB1+t5I5BoSTBU07SOb9ayZH4cqIuE8zwXVH1PcggBsRJjFi2O2oe3tOS0/Wn+VeqTBdyih+RXrtm3bbP32B+ikl0jAIbn9UgjcEl0KPHgrFY1np7fRTyqzqVqfILGuDoioShVjkWZzyPka2nqsr+JoErKZAGjMTDo1GCx0jq9blwcoLWZzaZxcbMJ2TPNuDifutuRDJzuGcm4sIyo7H4kyxbvgB98oOyBX3yBd0FqwSb5xe3b4aRNcNh27BtY1/El8yhfZMmm78Zd34Rx3wCR5w9AAc4H7lNUjpjN0FRrx2cnc/uwJuwpiMVAnurn6X3sQRi87bFHwY3bHnsMGr7z2BzqPDUckBUDGY3OlkwMXYKbqZRQ2clp+hSmTCOir98yz0HQkZinCM9TdJvzHAV//F7mOfYd53kCzTOdzFOv0PYdhTq/I7SFophNU7C149RJi9XIdaNt72MPgpu3PfYo+Pi2xx4DX3znsZhu2ao8XFLoRlMhTLcQNKvTPHfSmpYyTa9065znILj8vcxzFLR9L/McA+3faZ5DaJ7hZJ4VCm2/UKij6Cl0qIO/Oel08aAbbXsfexB6b3vsUfDP2x57DNq/81hMt/GKPEBNgm65mG650J6cxhVImaZXunXOcxBmfS/zHE3Ymf/nPMcg853mIXsWn27JBqPxeLAC3A/rgVXSUVYqm5ptsjAU8Sfnqb7OZ+XJTIyNgyAolwIui8WKtji/n7bSGSFXWpphZjyNsdNWC8AZ6+rbjB4ZeokWVcWK9w1fJY2ktxc6g9qj5Aosmilqw8zDpU1T6pvrZ68c+/ikM0wrzzRef/3oB/LkUaPuW/zB/1Lb3n3p3uOzb7zJaGD5U2OuX++4OU1+S1ZqyuL3JH3ZSvJK3mcziqLFqbej/Z61MJ40l9FK2y0WWjMzTnuT1cS7ohhVnYTERzgYluNnpMku30zftavHDynK7V9ov3nB/OJnlNny8ubdjxj36rxD6mYw9cfH3tjFVl7/+NH1tE2lG+IXplsGOhuEvA6HE93fnAZ0RA1lev1+cWbczzidtJvGedk8T1sTzhd06Kvo1pQ6keSY0gy1HCpE9MFUIjKxv7Wf+qTfCde6Jet3dSUiNV7+UD63bW/65InffPYPQsejcIVKRnyGbgP1MIJsjQ44QOB1C3aqOk3CT2ApQCcqWA7U8uvRSLKcgOq9SCkmACPP7tn99BMH9j3x+Oi6SWPGjv8B/NMb594889bP3jyzrXnd1o0til//TrAWPE/PBhwISALgOIqnKMicRrAALMNuscTxv7CAPHeLiv7zF5vWUvGVD6+66VFy0D4Fa2EmwtcL7pB8BqMRpvE2m8+DTpu8CAyS0VKNLsui9kpcbIWlp6AHeK5gJ2lZVydpHr5LJo+xyr0yK+Ej7eYwJF5S+dPM1XOmVVaVD6rTbNbtW7XhsQm1qyfa4Z61w6rWVEl1/QYMHBDz3bmwYU7ligG1lZmLMa4XEW0LEK4hsEqKutw2vz9ocjMASUSmHoDMoNlkNl2Om8x+c9hMa2mzmfa6JJOlGl1avY4rcS9awUlauBLnWzvOvoZWRnyj5URiOn2jeclemtgh1aNYQsIp6lB9osXkK/bpJLzAdgcseOrxDYeMOy3bq8efrjBGJ495eJP+YbTKjTuPnYc196xeNMPTIJXWLwwXzr3bNHVxw4yWIEXqXaM7GOLHEMRT/LS1THKZWFY0c+iuCLEHz8RciWtMJgr7PkvJg3fF9xnt4TogV8ik49MEOT56cbk8Dz6ybumXmScMrhvQu3//BPiN3HcpfCX2n3YcO5HfQ/QtpKei29/dUsBps+Fu8FaHFXAsm44InG4xmZCtom0255W4rRUOIsTkVGIS32cqMZWjeVTscfXqJGQg6VzO7nR/EjrCwiPb5I7CnbY7Bo+ePHJcRW2g0QdvysvE0ISK9bvh6rU733WVxupGDBufmw73NL7qDbUo9PsQLIB9kIzgGgA1UkD0+fQ6HQe4kBOAkEc8YDtuo2w22ijs10O9nihmIKmY4emi6kpO5vRjh3g3VVU7gxM8U0uAwD77Nux+5vldbxe3eGeMneqcVb3isceqaodVj6yqHAuX3L/jpyfO/8eT7tEPrM0obH6gZtio4ZVjxyo6uAaG6GmI5wWSBd3kNUCj4wEyIRpBcyUunIaDAEN4nepSUb23XNJ7C0P71+5qPiJXUlXUjZfkj47uhqHWJdgX9aGqN25Ek/5gkhRKN3isVodgYEAfjssPAZDvEILZwezL8WAQqY2XhESQruRdjitM7d5y/paKgR/Fda2KkA5ppB6EQk6VWJhWBc/s2PHsrHE1d+x5sOmp2tG1dx3e+lBl5UOW2pqR454ZOwoOXbCk4Z7qeXrKNGPwpHvr4+UzjJTubmhbsGBASfugUql4nUT4/RHid1+0NhfIBHVSrtXv5wx6ZHS5LDcAWY47vDO9S7yveM94Wa+XNgvNhkcNlMGA+F6OiEEj7nfheypxE420OwueJKSVvOpPrYogf7Rvw679ew/N3eJtMY3NS/B+dI3Ce2rO/Tt+cvIXv6wb4+6TsxJzf+14aXRV5ahRiszWoTv9Ud4DWBL7yDIZcbMSntfp9Wbi14FmrcnoN1JGDcNAfMWHeo1yvX87ryRsvtDpkOrFYxlz2onvK2aN/uZS+6zlCz6hPpv/+zbeoz+ufcX2wgs2aMQ4TEQ4vKziMEIKYRwwAggNM/FZoXMFg0EzKioJDBBwjAR2jUe6w6ft2MUAk/AXzGq/RD2oIsDN1x7Xy/sTGGAc1iAcNiIczCRil+VxI0tjtVgcTmca2plYFghCmt1tbTYZjRSPkeEd1gQdIsgKehKdr5OtdTtxgUWdfnecRh3hk2hBd2k01zZo2N5hA8prxAR6J0JmyTar30Dn2N+k4vgWwrEC4ehEZqNWyvZ5XS5PwO+32mxBt8fDazRBl9esQdupF9gYPUZS7wkoSLblRSLKk4ZkMnYPjvXqizLBENq8ER9v5Tx7Y8/Tvz538Wnuzq7uqIZh+kd2aBW8zyO8Swh/raBYcioeeMEsijatINgYURDgWQOnOo3aEDHf7sWvp8gTUoREnBtpQvun6+PrjlgWivUTJswXFzoOIcl6XPtfm5YPLx44bOW6XmCzDINEKgmbQrDZfw2byJK1C+xp6z9tD3SBzW3WPq6XtyWBd8I2oF2tQvIanU6vFT+B0KUzNJ3uTUvjdTTNm+1neUAQiHgUtyaRoC5GDslzF+h0ikTlwVgEdsFktipTo0aGatgjCYSgkUhVQVFxqizpkO2qlBBCGoEWbIFgMAuJU5bPphdoPfoIiq6zXCd2kcSzmF58moQ+xB9thMWkc6UiSqTPJHFrzttknOh7qMU30b7OHRo+pDytVpyKJEjKrJJKPVicdH1Hs0fqp9fVzZn9Cdr8y4aUBNAXv08q9RNbxbwKj3LZxE6US94etsoMJYbRGpv1mp2K+7EkTLyPPa3Dt1knLjvVOnWHWyH5eE6nE5BRQAKk2idGopBV4pqNWhWweEvIil1y4ocZBPZCZJd+2/b7+Z9RnyxglyOzVCf/FcPGcO9FcJ/gGoEI0hCPAmkeu91ls1pxICRhk7wUjyySw9PssiXXHG37tyyREgGkO02RcXR5zFMVPzt05NS+MYdKDfZ/+lnHuRoKKoXsGZRFwS1Bl1aE30juGhDQzXKklAEBy2qQZPvS0zOQMRItlgwOeCxadLbQphsdGmYnCXT9KztEJ2nTu3d8tkot2HoLi8S+r6I5v0fchpJPIJzHcF+Tji7FkttoMol6PRJ+wYIwtwi0iD5MHI64RNpUYe9hD+gUSaeRdbSzcOMpS6P3jdO+RvuJv1x6T/4l8+qL2558cvvzcKSt3XepJ1zENL0opsDFyvav4KZqGJ2FpMgOW35kb/SdfsPbaDm1Tf7le5eYV3/4yJNPPvwCHHnJ125LwOXzEFxsg3xonxBFvd2OIRMrlObxCDRttJ5VYCMdL+l+cE7eqrqsu4ckpdJg/PSUsHKSFh8Xu2anbyudqMtdTKcnaXIN4RbCuPkDAYRVJrI/CLFMb8IEBcwulS7dzU+X0EUqbr1HVVLwE24hOklU1/QQHQBBPfscZeH24d6wkg4JO01RHE83K+bRcyE160nhzgHMEvY5wgo0vhrZ3K+5p5XxidwrMr6q23grkapqLEnsESJBJGeNPULt5n6I9C1PEgUNTZOgLsdpGaGZo5JBly6xaxIHIdpUHKV2I6W+Ol8+zP7YtnWr7VqPOQF+nIdUF9FfyzPNHLzlnMn4DfzBYZlEb9gj1/CkOJ+mP/sragq3mcRuciSzEtbXCCwFKCWmP0KN6Xd7e4WjzPD1QzffP8L+Sgkuw46r7PPUa9x+dMbOkox2hwNJiNvBGpotgror4dBPalBU6ZncdeuB8L/7Thg3JpSVrVuiC4+v6Ddh3KhgVq62wTybfT6rf1a4etbdA8jXrYsR/gH2CNLFfaTvU6FkQyB1HAcUhuEmhc3JHfFCpGchGIV3UfL/wM8RB2/+XGHjH3wf40+l16UbwTjBPYvOBiHJwKBDAa0zmrRMc+pRoGtz+M7dn5q76TVLo7ho6tSFYqP9JHtk65JYWXnRshY07wTmfXoVO570XdZCwLCQ2hGHB9WkvEQgfBUOhDHvNyn+1nDH+8yz3DpzNqu7H79h+Vp2KTnDnA1MloyUbwQpK5XhgwC/LPm71M8XwonkTqsTmp2Ss8FJA2fAWYC+Heechf7a7HzUecB53HnWedFpaO1456TTqdFk5U3H+cWd+eFd4Yq8AhcMlHJub+Zec/evdUyktSAo2SFjhgEzfMZsxtnK5plmWGBOfZjSy9jPOxaSsTYKJzwHEqnOFDQVmEiasjJUyW+Wm3DeriVb80dCu6vXAYhIafidISxrLYM5ZdBRNq9sRRnNlsGiso1lSF/HnCwrA2JWnpoKjv+A3ub66ipAFsOOZsp0Z8ItmZDNrMykLmZmqoPxUGXc4S7jvkQabpIENOxD5XdF5fe6v/v63t4GAQ68jXDnO/6MNMeJrHqY9PvJkqxlJWkgCKXggSAVtAtCeY6JBrg4M5LutulLI5FIYYEz5babWvaTv0UJUHvq7yA1eTs/IyO/IBAo+Dw/QL7JXx5GfwsHA2GqID8jUFCAfpwfCIbR9/nnl9yt/HI4iH6IB74SQP8YKMj/a0b//ugX8l9R/y0fLpZJvSMG/EFupq+itdGkMpMfpEnIsviBG0ruA27Knc7j16BoNSVhtJqgPfht2P4BjpB/TM3tiVesfnDvGHTC59FdBndVIvADAD9UO+CjfEFdCnwYI9Fv+7fhAGsXwxH1cEtPJOQvG+vrG0/0iggFlnd8yZRyMYQFYjosyqdyjLTdho3tYEqADqdS7w4nTOfjUoBUMYxlqg8w6QcLK0d7Rm6eVxYauWRMbUOlX14GwxNt0ZzcQumBk/ctO7l26MimF2bJ7dD9+T3TaycdhB9OfOy+SWme2mWPTx29YVbxgJkb6HfkN6Y6SoYP23/X4lMbqoc3vX5fw/GWu4Jw0P3rPRt9APwfXHnEdnjanVVNbxw1GH43mzbZtE0vCImqVAYJKZWykw81EuqtTdMPadNUTT8uXLwznh0ns+OR7d1VcuVXICR+AEJI3Dhx4c6ZXwAXuCEuXHj8jjfZpCEIMprsM/b75dePHxPRnVZFLWr+3tC3EbfoZuuTiOdoobUTcZtutT6PeB42P0R8hZZbv0V8lZbnPoh4gY7bdyJepPfaP0bcoeX2nxEvtdzV3yO+RrcXv4z4OiWd9yO+QVud7yJepltLH6KS1nwHX99wVQG3sJYrEc+hnq2I23SvtRvxPGy+ivgK3W79FPFV4L8iXqA/5lYiXqSV9hcRd+h2++eIl+Z+mZ/mukafLsqIr9Nni99HfIMOOjsRL9O9zq/0iDQN8Hq8x6QoI4FX4lsCpWSopiOybFVgVNAKRu/id5PWaQOvoCewMpgv4S9oG9jCK/yXHNdQRQkt8czl0TaBXsYqnrL3KtAz+KeIQI/0QHt9rDKRSS9FauojqweFFyvpXbG5vrEunhgzKJXYNrY2VnptqmRp+7zZpniJEE+lXxXPqhRxeyioj7SzBQva5V+Dad1XTTCxayoMhBIHNMKCJXzopRqMSgnwgBwKVfDKOJqgLt5/if7AparKlBVd8U6i/1rYG7Z1J5ab6No6noS2MKmsC6abyfp6snVx8AtCX1aJRi7BTPE8E5Y95KYcYsxQful+CtgpZp/DjOKvjKOG2K9hsc9WL9gztNVztoqtXl2QcQ8Zc/inzMSpZcqxA6ObyAa4iBt0gG20XEHGftO1ucC3mf5qJ6TwVmZqKO2hMPlZDgmrBtp5ZTGoK/E62U/EC+lV5YWsMvHqxHEvz3WqeDBV1ksYG19g9w9GVrtMpyGbSy7i0sUH65Q/M6QndC50bMx92GXz8O0al32vxkrsSu+VC8YPYeBi85uNDblGTKQK42HTJmhZaFDBWPLGZxwyHOYqevdxvMWlyUX0lZFAFfNtHFc0jtkCFXL+7zhvhRwCWPLWCK42bFt+rgrBWyuZKA05h5j1bJtivMRzFIVtiF42WftRuiYshMXJ+oNX0/vn+J189DHT8WxvGprn8eCFrCGu5TWddrTLuxnWo7jKgCQLbR8eJedt6iqYzJKpqCI1PVfvZijdEFjwCkL0Ha42yKuKnX0LWe5dGLHp3uxRCjtTcr1uJnbF1WY8Zk46HazKmKlZccnyf3iySzkztOlmxtG6/9DvnHvjY1bDFWV4mn1vGGbgO+JdbI5/w3//Tuck99dEv5q12cdahs1xfigdjicO87YZOV2pVTEpdFqIiXQiU04PKkz3j8TZ4yEwKyEAVWXGOFxjuFmVW+UKXQ2Ek5UTTlmdxxDCF9IHuRgqb3Uqy/IIF9WwhmsfN9NE+yLktxon9rmafJ1Mq4Gm5FBooYe1NWMutOtSq1SFfDKTfV1qj1iFtDKF0kBudOpYSSAgopZVd2dkTa1Q7NsnvVNDlNeokDPlWDm2rpTKXFCxDEst4YTEpTGHYUm5sSgz80V3pu7cVB6uRsgsw9rRMJOOhkHfoDl+WpxMrcFcXUqPKMOgYwWf/pru0xqeCT8Ja8CsuqVR25LIlDU4el/fX1ubTCaJjBKXQuESFLX2/8MGstRM61npskyQEHMI4lya2h/VKpLFuqTww7K5HJu0UxUdzej29Dzt4+Lr8SVVRxV4HPkvzkUICnj+Kt9AgRvhSkI9gcYj1vywl/vPemKvBk0eY49ENFgV0+t+I9k4365GizS+PS/c8UlKuFkDzO+hst5JG0BCXXuXOF0mxg7W9h736G8BvYf9AAAAeNptnAV421bbhg+fozSldczM62rp2I7HtqPTdevarbCuo85N3MRrEqex3a4dMzMzMzMz8/aNmZmZt9+2nkDzZ9fVvEeyrPtIdnQ/r+WMMFL/75/nyTQyxH/e7tUflDDCiSCSKKKJIR5pIMNIIxlORpCRZBQZTZYgY8iSZCmyNFmGLEuWI8uTFciKZCWyMlmFrEpWI6uTNciaZC2yNlmHrEvWI+uTDciGZCMylmxMxpEY8UlALImTBEmSJpIim5BNyWZkc7IF2ZJsRdIkQ7KkmYTEkfFkazKBbEO2JRPJdmQSmUy2JzuQKWRqdf7TyY5kBtmJzCQ7k13IrmQ3sjuZRfYgOcrIxeQQcii5l5xGPieHkePI0eRcciW5hHJyFBXkYHIy+ZH8RI6lkhxBFXmX/EDOI1eRX8jP5FdyEbmWPEkeJ9eR2aSFnEBaydMkT54gT5HnyTPkWfIc+YLMIS+RF8iL5HrSRr4nJ5JXycvkFdJOviLfkCPJnqRA5pJO0kG6yAWkSOaRbtJDSqRCymQ+WUC+JHuRRWQh2ZvsS/Yhd5ALyf5kP3IAOZB8Tb4ld1FNDfVoAx1GG8k/5F86nI6gI+ko8h8ldDRdgo6hlC5Jl6JL02XosnQ5ujxdga5IV6Ir01XI7+QPuipdja5O16Br0rXo2nQdui5dj65PN6Ab0o3oWLox+ZO8RsfRGPVpQC2N0wRN0iaaopvQTelmdHO6BfmQfES3pFvRNM3QLG2mIXV0PN2aTqDb0G3pRLoduYHcSCfRyXR7ugOdQqfSaXQ63ZHOIH+Rv8nH5BO6E51Jd6a70F3pbnR3OovuQXN0Nm2hrTRP59A22k4LdE86l3bQTnI37aJF2k3nkU/JZ7SHlmiZVuh8uoDuRRfSRXRvug/dl+5H96cH0APpQfRgegi5jB5KD6OH0yPokfQoejQ9hh5Lj6PH0xPoifQkejI9hZ5KT6On0zPomfQsejY9h55Lz6Pn0wvohfQiejG9hF5KL6OX0yvolfQqejW9hl5Lr6PX0xvojfQmejO9hd5Kb6O30zvonfQueje9h95L76P30wfog/Qh+jB9hD5KH6OP0yfok/Qp+jR9hj5Ln6PP0xfoi/R/9CX6Mn2Fvkpfo6/TN+ib9C36Nn2Hvkvfo+/TD+iH9CP6Mf2Efko/o5/TL+iX9Cv6Nf2Gfku/o9/TH+iP9Cf6M/2F/kp/o7/TP+if9C/6N/2H/kv/Y4RRxhhngkmmmGaGeayBDWONbDgbwUayUWw0W4KNYUuypdjSbBm2LFuOLc9WYCuyldjKbBW2KluNrc7WYGuytdjabB22LluPrc82YBuyjdhYtjEbx2LMZwGzLM4SLMmaWIptwjZlm7HN2RZsS7YVS7MMy7JmFjLHxrOt2QS2DduWTWTbsUlsMtue7cCmsKlsGpvOdmQz2E5sJtuZ7cJ2Zbux3dkstgfLsdmshbWyPJvD2lg7K7A92VzWwTpZFyuybjaP9bASK7MKm88WsL3YQraI7c32Yfuy/dj+7AB2IDuIHcwOYYeyw9jh7Ah2JDuKHc2OYcey49jx7AR2IjuJncxOYaey09jp7Ax2JjuLnc3OYeey89j57AJ2IbuIXcwuYZeyy9jl7Ap2JbuKXc2uYdey69j17AZ2I7uJ3cxuYbey28jr5AN2O3mT3cHuZHexu9k97F52H7ufPcAeZA+xh9kj7FHyFnmbvEPeJ2+Q99hj7HH2BHuSPcWeZs+wZ9lz7Hn2AnuR/Y+9xF5mr7BX2WvsdfYGe5O9xd5m77B32XvsffYB+5B9xD5mn7BP2Wfsc/YF+5J9xb5m37Bv2Xfse/YD+5H9xH5mv7Bf2W/sd/YH+5P9xf5m/7B/2X+ccMoZ51xwyRXX3HCPN/BhvJEP5yP4SD6Kj+ZL8DF8Sb4UX5ovw5fly/Hl+Qp8Rb4SX5mvwlflq/HV+Rp8Tb4WX5uvw9fl6/H1+QZ8Q74RH8s35uN4jPs84JbHeYIneRNP8U34pnwzvjnfgm/Jt+JpnuFZ3sxD7vh4vjWfwLfh2/KJfDs+iU/m2/Md+BQ+lU/j0/mOfAbfic/kO/Nd+K58N747n8X34Dk+m7fwVp7nc3gbb+cFviefyzvIFbyTd/Ei7+bzeA8v8TKv8Pl8Ad+LL+SL+N58H74v34/vT87nB/AD+UH8YH4IP5Qfxg/nR/Aj+VH8aH4MP5Yfx4/nJ/ATyen8JH4yP4WczU/lp/HT+Rn8TH4WP5ufw8/l5/Hz+QX8Qn4Rv5hfwi/ll/HL+RX8Sn4Vv5pfw6/l1/Hr+Q38Rn4Tv5nfwm/lt/Hb+R38Tn4Xv5vfw+/l9/H7+QP8Qf4Qf5g/wh/lj/HH+RP8Sf4Uf5o/w5/lz/Hn+Qv8Rf4//hJ/mb/CX+Wv8df5G/xN/hZ/m7/D3+Xv8ff5B/xD/hH/mH/CP+Wf8c/5F/xL/hX/mn/Dv+Xf8e/5D/xH/hP/mf/Cf+W/8d/5H/xP/hf/m//D/+X/CSKoYIILIaRQQgsjPNEgholGMVyMECPFKDFaLCHGiCXFUmJpsYxYViwnlhcriBXFSmJlsYpYVawmVhdriDXFWmJtsY5YV6wn1hcbiA3FRmKs2FiMEzHhi0BYERcJkRRNIiU2EZuKzcTmYguxpdhKpEVGZEWzCIUT48XWYoLYRmwrJortxCQxWWwvdhBTxFQxTUwXO4oZYicxU+wsdhG7it3E7mKW2EPkxGzRIlpFXswRbaJdFMSeYq7oEJ2iSxRFt5gnekRJlEVFzBcLxF5ioVgk9hb7iH3FfmJ/cYA4UBwkDhaHiEPFYeJwcYQ4UhwljhbHiGPFceJ4cYI4UZwkThaniFPFaeJ0cYY4U5wlzhbniHPFeeJ8cYG4UFwkLhaXiEvFZeJycYW4UlwlrhbXiGvFdeJ6cYO4Udwkbha3iFvFbeJ2cYe4U9wl7hb3iHvFfeJ+8YB4UDwkHhaPiEfFY+Jx8YR4UjwlnhbPiGfFc+J58YJ4UfxPvCReFq+IV8Vr4nXxhnhTvCXeFu+Id8V74n3xgfhQfCQ+Fp+IT8Vn4nPxhfhSfCW+Ft+Ib8V34nvxg/hR/CR+Fr+IX8Vv4nfxh/hT/CX+Fv+If8V/kkgqmeRSSCmV1NJITzbIYbJRDpcj5Eg5So6WS8gxckm5lFxaLiOXlcvJ5eUKckW5klxZriJXlavJ1eUack25llxbriPXlevJ9eUGckO5kRwrN5bjZEz6MpBWxmVCJmWTTMlN5KZyM7m53EJuKbeSaZmRWdksQ+nkeLm1nCC3kdvKiXI7OUlOltvLHeQUOVVOk9PljnKG3EnOlDvLXeSucje5u5wl95A5OVu2yFaZl3Nkm2yXBbmnnCs7ZKfskkXZLefJHlmSZVmR8+UCuZdcKBfJveU+cl+5n9xfHiAPlAfJg+Uh8lB5mDxcHiGPlEfJo+Ux8lh5nDxeniBPlCfJk+Up8lR5mjxdniHPlGfJs+U58lx5njxfXiAvlBfJi+Ul8lJ5mbxcXiGvlFfJq+U18lp5nbxe3iBvlDfJm+Ut8lZ5m7xd3iHvlHfJu+U98l55n7xfPiAflA/Jh+Uj8lH5mHxcPiGflE/Jp+Uz8ln5nHxeviBflP+TL8mX5SvyVfmafF2+Id+Ub8m35TvyXfmefF9+ID+UH8mP5SfyU/mZ/Fx+Ib+UX8mv5TfyW/md/F7+IH+UP8mf5S/yV/mb/F3+If+Uf8m/5T/yX/mfIooqprgSSiqltDLKUw1qmGpUw9UINVKNUqPVEmqMWlItpZZWy6hl1XJqebWCWlGtpFZWq6hV1WpqdbWGWlOtpdZW66h11XpqfbWB2lBtpMaqjdU4FVO+CpRVcZVQSdWkUmoTtanaTG2utlBbqq1UWmVUVjWrUDk1Xm2tJqht1LZqotpOTVKT1fZqBzVFTVXT1HS1o5qhdlIz1c5qF7Wr2k3trmapPVROzVYtqlXl1RzVptpVQe2p5qoO1am6VFF1q3mqR5VUWVXUfLVA7aUWqkVqb7WP2lftp/ZXB6gD1UHqYHWIOlQdpg5XR6gj1VHqaHWMOlYdp45XJ6gT1UnqZHWKOlWdpk5XZ6gz1VnqbHWOOledp85XF6gL1UXqYnWJulRdpi5XV6gr1VXqanWNulZdp65XN6gb1U3qZnWLulXdpm5Xd6g71V3qbnWPulfdp+5XD6gH1UPqYfWIelQ9ph5XT6gn1VPqafWMelY9p55XL6gX1f/US+pl9Yp6Vb2mXldvqDfVW+pt9Y56V72n3lcfqA/VR+pj9Yn6VH2mPldfqC/VV+pr9Y36Vn2nvlc/qB/VT+pn9Yv6Vf2mfld/qD/VX+pv9Y/6V/2niaaaaa6FllpprY32dIMephv1cD1Cj9Sj9Gi9hB6jl9RL6aX1MnpZvZxeXq+gV9Qr6ZX1KnpVvZpeXa+h19Rr6bX1OnpdvZ5eX2+gN9Qb6bF6Yz1Ox7SvA211XCd0UjfplN5Eb6o305vrLfSWeiud1hmd1c061E6P11vrCXobva2eqLfTk/Rkvb3eQU/RU/U0PV3vqGfonfRMvbPeRe+qd9O761l6D53Ts3WLbtV5PUe36XZd0HvqubpDd+ouXdTdep7u0SVd1hU9Xy/Qe+mFepHeW++j99X76f31AfpAfZA+WB+iD9WH6cP1EfpIfZQ+Wh+jj9XH6eP1CfpEfZI+WZ+iT9Wn6dP1GfpMfZY+W5+jz9Xn6fP1BfpCfZG+WF+iL9WX6cv1FfpKfZW+Wl+jr9XX6ev1DfpGfZO+Wd+ib9W36dv1HfpOfZe+W9+j79X36fv1A/pB/ZB+WD+iH9WP6cf1E/pJ/ZR+Wj+jn9XP6ef1C/pF/T/9kn5Zv6Jf1a/p1/Ub+k39ln5bv6Pf1e/p9/UH+kP9kf5Yf6I/1Z/pz/UX+kv9lf5af6O/1d/p7/UP+kf9k/5Z/0JuIjfrX/Vv5DZyO3lE/05uIbeSR/Uf5CDyEDmcXK3/1H/pv/U/+l/ymP7PEEPJfeR+wwwn9xhhpFFGG2M802CGmUYz3IwwI80oM9osYcaQ38ySZimztFnGLGuWM8ubFcyKZiWzslnFrGpWM6ubNcyaZi2ztlnHrGvWM+ubDcgxZkOzkRlrNjbjTMz4JjDWxE3CJE2TSZlNzKZmM7M5OcNsQc4iZ5LvzJbkYXIpOclsZdLkHHI5Od5kTJacQk41zSY0zow3W5sJZhuzrZlotjOTzGSzvdnBTDFTzTQz3exoZpidzEyzs9nF7Gp2M7ubWWYPkzOzTYtpNXkzx7SZdlMwe5q5psN0mi5TNN1mnukxJVM2FTPfLDB7mYVmkdnb7GP2NfuZ/c0B5E5zoDnIHGwOMYeaw8zh5ghzpDnKHG2OMcea48zx5gRzojnJnGxOMaea08zp5gxzpjnLnG3OMeea88z55gJzobnIXGwuMZeay8zl5gpzpbnKXG2uMdea68z15gZzo7nJ3GxuMbea28zt5g5zp7mLPEAeNHebe8y95j5zv3nAPGgeMg+bR8yj5jHzuHnCPGmeMk+bZ8yz5jnzvHnBvGj+Z14yL5tXzKvmNfO6ecO8ad4yb5t3zLvmPfO++cB8aD4yH5tPzKfmM/O5+cJ8ab4yX5tvzLfmO/O9+cH8aH4yP5tfzK/mN/O7+cP8af4yf5t/zL/mP4941GMe94QnPeVpz3ie1+AN8xq94d4Ib6Q3yhvtLeGN8Zb0lvKW9pbxlvWW85b3VvBW9FbyVvZW8Vb1VvNW99bw1vTW8tb21vHW9dbz1vc28Db0NvLGeht747yY53uBZ724l/CSXpOX8jbxNvU28zb3tvC29Lby0l7Gy3rNXug5b7y3tTfB28bb1pvobedN8iZ723s7eFO8qd40b7q3ozfD28mb6e3s7eLt6u3m7e7N0pWuwrhx6XGozV5xfr6n1FLsyfPOSqyhs9DaWiyPHTcuptOduZaeYpfORVWlZ/fk5+dVrl50uthW7MrP1bmoDsu2FHpaKp1zOvJ7DWvpHzdkq7vLtbTku8oNLX1D1dySq+2yNSrN1f3nyjoEMA9gGAHz9dIQ9u8o3zfUIaaRj6oKoz3m62XY+AGTahswqfH9+2rrGzaObyl2duaw0DZgYdjWA/bT3j8WW8/O9Yj26g81oVzoaM2rQr3oCTiSAo5kQnQkhejUTcCcC1FlE7ZhhT2HbTOAsWf/uHHbgbOau9hCW08+39WR62ottKiJuZZKOa866qVx4sDtOgYsqInRCeqoFzGxevSio/pDTYqe3xU9f9LA53cNfP6k6Pld0QnuynUXS+WeYnd7noddbTzf1aYn4+CLOPjJ0cEX62X45PZKV1uup9LZkauUhxcHLqkp0Rx6ojlMGTiHnoFzmBLNoScqU6Nnlepl2NQBp7E04DROG7i38sC9TYt2U47OyLTaS1quvaTTo5e0Er2k03FUFRzV9OioKvUip/cUutpkpfZz+PTFjrAycElPx0tfwW/NjAGzXTBgPHPAeGH/WO0cHeuiemnYuf9tvKhvKDuKXW2l+q93rGkcagzVRw1QLWocNYGaRG1CTaGmUTOoWdRm1BDVRTUFfgr8FLgpcFPgpsBNgZsCNwVuCtwUuClwU+CmwE05Obm92FNthGo/o3VpHHMa7DTYabDTYKfBToOdBjsNdhrsNNhpsNOhnF5nVvqZGRxvBuwM2BmwM2BnwM6AnQE7A3YG7AzYGbAzYGdw3Bmc7yzOdxb8LPhZ8LPgZ8HPgp8FPwt+Fvws+Fnws+Bnwc+CnwW/Gfxm8JvBbwa/Gfxm8JvBbwa/Gfxm8JvBbwa/Gfxm8JvBbwY/BD8EPwQ/BD8EPwQ/BD8EPwQ/BD8EPwQ/BD8EPwQ/BN+B78B34DvwHfgOfAe+A9+B71IN6dq1JPo1z/UNdTqMai4fXe0mlzpypfZoXOwf1/fijxuHGkP1UQNUixpHTaAmUZtQU6hp1AxqFrUZNUSNzoYfAz8Gfgz8GPgx8GPgx8CPJRunDrxalwYsYAvMJIaZxDCTGGYSw0ximImPmfiYiY+Z+JiJj5n4mImPmfg4Ez7OhI8z4YPvg++D74Pvg++DH4AfgB+AH4AfgB+AH4AfgBuAG4AbgBuAG4AbgBuAa8G14FpwLbgWXAuuBdfiuC34FnwLvgXfgm/Bt+Bb8OPgx8GPgx8HPw5+HPw4+HHw4+DHwY+DHwc/Dn4c/Dj4cfAT4CfAT4CfAD8BfgL8BPgJ8BPgJ8BPgJ8APwF+AvwE+Anwk+AnwU+CnwQ/CX4S/CT4SfCT4CfBT4KfBD8JfhL8JPhJ8OF/H/734X8f/vfhfx/+9+F/H/734X8f/vfhfx/+9+F/H/734X8f/vfhfx/+91PgIwf4yAE+coCPHOAjB/jIAT5ygI8c4CMH+MgBPnKAjxzgp8BHm+OnwUcW8JEFfGQBH1nARxbwkQV8ZAEfWcBHFvCRBXxkAR9ZwE+DnwY/Az7ygI884CMP+MgDPvKAjzzgIw/4yAM+8oCPPOAjD/jIAz7ygI884CMP+MgDPvKAjzzgIw/4yAM+8oAP//vwvg/v+/C+D+/78L4P7/vwvg/v+/C+D+/78L4P7/vwvg/v+/C4D4/78LgPj/vwuA+P+/C4D4/78LgPj/vwuA+P+/C4D4/78LgPj/vwuA+P+/C4D4/78LgPj/vwuA+P+/C4D4/78LjvwHfgO/Ad+A58B75zXltPbn6+KrzZXt3ktVH9sWCc79U7kQFrLGocNYGaRG0a3l4szs3NLs4f+Kw0agY1i9qMGqJG5yKAxQNYPIDFA1g8gMUDWDyAxYMYZhFrQk2hgg93B3B3AHcHcHcAdwdwdwB3B77fWO11Zuc7igv6DwoCDyDwAAIPIPAAAg8g8AACDyDwAAIPIPAAAg8g8AACDyDwAAIPIPAAAg8g8AACDwLwIfIAIg8g8gAiDyDyACIPIPIAIg8g8gAiDyDyACIPIPIAIg8g8gAiDyDyACIPIPIAIg8g8gAiDyDyACIPIPIAIg8g8gAiDyDyACIPIPIAIg8g8gAiDyDyACIPIPIAIg8g8gAiDyDyACIPIPIAIg8g8gAiDyDyACIPIPIAIg8g8gAiDyDyACIPIPIAIg8g6gCiDiDiACIOIOIAIg6SoSwXu4ql4a2FfE++VCjVlxrSHd3tufrQy3UVy/mOfCHXGHaXCtWevb7ahGU8PqGIUePkzkLtE4doYfqAjRsmd+bboo1GF6qbL8aSdZbI5Ms5OT5Xzc8aHLFzdRWvcuS09upI1EBy21x3d05NzHXObs2x7SpsUoXtVNAgs+0LfEp7UU4ttHXm+LRcRWMWfPv2As9W/21fKjROGDCDkdigd7kh13fgjfmBh5vvPdxC7+EuWVn8qdHB1J8vZtcOpq12MLI131HOaexLLKodUu3Bcv2QajuTc+uH1BEdUleF7VXQxeh4eE97UZVqBxOT9cLL1WMCl3dXj6el+q+6KIu1E9w48NyOHDS9xuLAV6cy8NUp9r060XsCkgwgyQCSDCDJAJIMIMkAkgwgyQDNcYDmOEBzHKA5DtAcB2iOA0g1gFQDSDWAVANINYBUA0g1gFQDSDWAVANINYBUA0g1gFQDSDWAVANINYBUA0g1gFQDSDWAVANINYBUA0g1gFQDSDWAVANINYBUA0g1gFQDSDVwEd+iHbZohy3aYYt22EKnFjq10KmFTi3aYYt22EKkFiK1EKmFSC1EaiFSC5FaiNRCpBYitRCphUgtRGohUguRWojUQqQWIrUQqYVILURqIVILkVqI1KIJtmiCLRxq4VALh1o41MKhFg61cKiFQy0cauFQC4daONTCoRYOtXCohUMtHGrhUAuHWjjUwqEWDrVwqIVDLRxq4VALh1o41MKhFg61cKiFQy0cauFQC4daONTCoRYOtXCohUMtHGrhUAuHWjjUwqEWDrVwqIVDLRxq4VALh1o41MKhFg61cKiFQy0cauFQC4daONTCoRYOtXCohUMtHGrhUAuHWjjUwqEWDrVwqIVDLRxq4VALh1o41KIZtmiGLZphi2bYwrEWjrVohi2aYYtm2KIZtnCwhYMtHGzhYItm2KIZtmiGLZphi2bYohm2aIYtmmGLZtiiGbZohi2aYYtm2KIZtmiGLZphi2bYohm2aIYtmmGLZtiiGbZohi2aYYtm2KIZtmiGLZphi2bYohm2aIYtmmGLZtiiGbZohi2aYYtm2KIZtmiGLZphi2bYohm2aIYtmmGLZtiiGbZohi2aYYtm2KIZtmiGLZphi2bYohm2aIYtmmGLZtiiGbZohi2aYYtm2KIZtmiGLZphi2bYohm2aIYtmmGLZtiiGbZohi2aYYsPxy0+HLdoji0+HLdoki2aZIsm2aJJtmiSLZpkC/9b+N/C/xb+t/C/hf8t/G/hf9vc5OXmFAqxcU29VyYkAIsEYJEALBKARQKwSAAWCcAiAVgkAIsEYJEALBKARQKwSAAWCcAiAVgkAIsEYJEALBKARQKwSAAWCcAiAVgkAIsEYJEALBKARQKwSAAWCcAiAVgkAIsEYJEALBKARQKwSABxJIA4EkAcCSCOBBBHAogjAcSRAOJIAHEkgDgSQBwJII4EEEcCiCMBxJEA4kgAcSSAOBJAHAkgjgQQh9HjMHocRo/D6HFcOeK4csRx5YjjyhHHlSOOK0ccV444rhxxXDniuHLEceWI48oRT/VyMG9cOeK4csRx5YjjyhHHlSOOK0ccV444rhxxXDniuHLEceWI48oRx5UjjitHHFeOOK4c8bSTpfb8/FxDtXfIzSnl24od0bC7+qN9WH04L9eZK5dke6GnME+WS9VULusbyvo2qvfhYrURiHaaSat5ldmVckm15trypXbZmS/n22Rnbl5ujujJzclXn1nKz9Ol9kJX7cZ4qV5MqVillirzvEp3d75nVm1VR3FBvqc6iPabTQyLYPOq4C6R68jP4dWGRbYVOvMdsrW6XGbteT4/N18uyi0sdPFqq8LL1X8Li61mTqEr1zE3N4dX/8nqVPNY1Znv5NV/0UJXpYtX/6lS9fG57aK2E11/oDvPuvMN9WG5VG1VZP0nn1esHlD1CEXtUKo9znxVhc+PShWqqv9qpa3WybR71VJqr+6zfppizdHvSrXGUH3UANWixlETqEnUJtQUaho1g5pFbUYNUV1UY+DHwI+BHwM/Bn4M/Bj4MfBj4MfAj4EfAz8Gfgz8GPgx8H3wffB98H3wffB98H3wffB98H3wffB98H3wffB98H3wA/AD8APwA/AD8APwA/AD8APwA/AD8APwA/AD8APwA/At+BZ8C74F34JvwbfgW/At+BZ8C74F34JvwbfgW/Dj4MfBj4MfBz8Ofhz8OPhx8OPgx8GPgx8HPw5+HPw4+HHwE+AnwE+AnwA/AX4C/AT4CfAT4CfAT4CfAD8BfgL8BPgJ8JPgJ8FPgp8EPwl+Evwk+Enwk+AnwU+CnwQ/CX4S/CT4SfCbwG8Cvwn8JvCbwG8Cvwn8JvCbwG8Cvwn8JvCbwG8Cvwn8JvBT4KfAT4GfAj8Ffgr8FPgp8FPgp8BPgZ8CPwV+CvwU+Cnw0+CnwU+DnwY/DX4a/DT4afDT4KfBT4OfBj8Nfhr8NPhp8DPgZ8DPgJ8BPwN+BvwM+BnwM+BnwM+AnwE/A34G/Az4GfCz4GfBz4KfBT8Lfhb8LPhZ8LPgZ8HPgu/AiTJZLIRnQngmhGdCeCaEZ0J4JoRnQngmhGdCeCaEZ0J4JoRnQngmhGdCeCaEZ0J4JoRnQngmhGdCeCaEZ0J4JoRnQngmhGdCeCaEZ0J4JoRnQngmhGdCeCaEZ0J4JoRnQngmhGdCeCaEZ0J4JoRnQngmhGdCeCaEZ0J4JoRnQngmhGdCeCaEZ0J4JoRnQngmhGdCeCaEZ0J4JoRnQngmhGdCeCaEZ0J4JoRnQngmhGdCeCaEZ0J4JoRnQngmhGdCeCaEZ0J4JoRnQngmhGdCeCaEZ0J4JoRnQngmhGdCeCaEZ0J4JoRnQngmhGdCeCaEZ0J4JoRnQngmhGdCeCaEZ0J4JoRnQngmhGdCeCaEZ0J4JoRnQngmhGdCeCaEZ0J4JoRnQngmhGdCeCaEZ0J4JoRnQngmhGdCeCaEZ0J4JoRnwqRTM+r3OtWCqMyIvtq4oF68Gb0fsHsLekfR8+CZEJ4J4ZkQngnhmRCeCeGZEJ4J4ZkQngnhmRCeCeGZEJ4J4ZkQngnhmRCeCeGZEJ4J4ZkQnglToZfuvV/p5XpHDem+O7MNub7hqHT/Vz3rp2FUbvCKAVvUT9vALeorlhywRd+Ol8wNsXLgvup3lgfuq75izIAtemc+Jvf/1w2LvhoefQ0tN2Acra/PC+vr45HR+r6ZjMwtvozn1eeA59XHI6L1vdgRucUWvbBv1LeuIew/z/37V2H01d5or6PCwSc5P3hFOPis5wef9XCos54f6qyHg896fvBZD4c46/n/v65hQv+xFfqG3oS+s1DoG03uGxX7nj25/9nF/tlNHnzoxcErJg8+F8XB52LyUOeiONS5mDz4XBQHn4vJQ5yL4hDnov613+jrksX+YX1tfVLR2vpwRH1t3yRGFBdbjJ5Th0fPqQ+H19f20oYXBy550/tGlb75TO/fYaV/OL1/apX+4fT+WVb6Zzl98VlWFp/l9P5ZVvpnOX2xWVYGLqmZ0WV2Yb14M/vmvLBvzjP7d7+w/3dlZvS7sjD6GnztmuaQ2Rwym0Nmc8hsDpnNIbM5ZDaHzOaQ2Rwym0Nmc8hsDpnNIbM5ZDaHzOaQ2Rwym0Nmc8hsDpnNIbM5ZDSHjOaQ0RwymkNGc8hoDpnMIZM5ZDKHTOaQyRwymUMmc8hkDpnMIZM5ZDKHTOaQyZzfy8PxIZM5ZDKHTOaQyRwymUMmc8hkDpnMIZM5ZDKHTOaQyRwymUMmc8hkDpnMIZM5ZDKHTOaQyRwymUMmc8hkDhnMIYM5ZDCHDOaQwRwymEPmcshcDpnLIXM5ZC6HzOWQuRwyl0PWcshYLt67X8wfmcohUzlkKodM5ZCpHDKVQ6ZyyFQOmcohUzlkKodM5ZCpHDKVQ6ZyyFQOmcohUzlkKodM5ZCpHDKVQ6ZyyFQOmcohUzlkKodM5ZCpHDKVQ6/u0Ks79OoOvbpDr+7QqztkKIcM5ZChHDKUQ4ZyyFAOGco19fJwvMhQDhnKIUM5ZCiHDOWQoRwylEOGcshQDhnKIUM5ZCiHDOXQqzv06g69ukOv7tCrO/TqDr26Q6/u0Ks79OoOvbpDr+7Qqzv06g69ukOv7tCrO/TqDr26Q6/u0Ks79OoOvbpDr+7Qqzv06A49ukOP7tCjO/ToDj26Q4/u0KM79OgOPbpDj+7Qozv06A49ukOP7tCbO/TmDr25Q2/u0Ju7LLhZcLPgZsHNgtsMbjO4zeA2g9sMXjN4zeA1g9cMXjN4zeA0g9MMTghOCE4ITghOiOML8bqG4IbghuCG4IbghuCGOM4Q/BD8EHwHngPPgefAceA4cBw4DhwHjgPHgRN9BuKPi3xYrVnUZtTex11UI99Vq48aH17pasWfbbbO7hg+r1Is52tZuKeUb8U2eG7knmrNoILlg+WHqrPQVf8DunxLsQvPDqyX36ulI9dZ3bvXk2sttOSqaSt6LI7ZJbDnBPacwJ4T2HOidzvndZUq3fmeQrEnWpPC8UTXi2rFcUXXi2q1UU1juzS2S/uio9CTw0IcNaG686V8uXd1E2pKldrz8/IdorXY1SbCSk8RD2B6aUwvjROVASwDWAaTymBSGUwqA24Gz4tuavqxKOz4sSiEVGsCNcknt3d6+VK50Jkr4+WJRSqs1tAUu/Ll9kJPq1deUKwPSl51Vb7Q1l5ubyy39+QxLg2bU5jfO24sVV/tLixEu2qyXq6np7igIz+nrOujSndDvfbUNosebC0u6IpGs6swD5u1djX2jWaX6inPx58D+X4s3lDsKbfX/mIx19FY6CrX3mUt5UKxa1h+XqUwv/rO6GrBcxK+bC9WSvnh1TdjR7Gt9rbpKpYbak+q5s6OcnffcHb9tpmPe7I+7sX6uIfq415ptVrUJlQ87mM93s/xAMsBluN4fpQxqhX7jzJGtWL7KGNUawI1iQpelDWqNY2aQe3lNKOGqNHbIp4APwF+AvwE+AnwE+AnwE+AnwA/AT5+2+L4bYvXftu6Z3cUW+bq6mtWqzJa6pgT1Z4ylsul9lxrXtZ/6ta59erNKXR0VC8dxeh3Gnd2fdyZrdZMQ7RFT/WV1uWeQq6t0h3VHiy3dkW1Y46q9WMd0TsgnsV5yTqv0DV/dqW6k3JtFG3TUOzOd2FlqbNQfavmWvLV99T8vgVeqnSpOfnO6rtK1H7IUnd1vqKlozJbtudzVXprIdfZe6FKJFLDOislvM/yWJdBzaJGL0kWL0kWL0kWL0kWL0kWL0kWL0kWL0kWL0kWL0kWL0kWL0kWvCx4WVwAs0lwkuAkwUmCkwQnCU4U/3x8tJxO9tUm1BRqGjWDmkVtRg1RXVSjdqZaY1Ftwv6asL8m7K8J+4viXjXNNKOGjdGt4ln1e+ojq7/H+WrvWq5ejWr3oE3tVveCQvVNVb/JXRup9nyt6Lm56IH6He3aqLH3rnZtwdTuO9e3K+fm1x+t7nlWd0elVCq0dQ2r3bXGTfiG+rg+HF1fVb9zjwdHDVhTX+HVJlSfakNtFN2Vr6/szHUX5nmz8+Vo82H1e/MY1ycfjU17Php483Pz8XD9nj3Wlns39KonJRqN6L2Djwf6RsPqx4611QPHqKuCnTVGd/OjheG4nY9p9A6G1e/n45nzithzQ+30Ydh/Crxy75RNdfLR9x6qB1z7YkPt5ajVqi9rpX5G6rOrv8y4E+FwJ8LhTkS1BqPqaWPAX2EOb1nYU708FFrqH8CNqv/l/ICHRw8Y99S+2J031ZelI18q7TmsqrbqJCJ9VIXXOx5eF13vUuOcYqWnf6H6Ruvbru69vqW6APuWej/JGFt9H8VG9H2EUVu0wzGDQv3BkfgDmdof0YxtyXUPWI4NWs4OWh43YDk56PlB33LvCZpVLHfmeuZ69RM1troWW9pBe7KDyMEQy00DlmM1+oDl7KBl27t94+xcT2EsDn5M/cFMLNogVtvpuCHWxQats0NsZwdtlxhif4kh9pcYYn+JQftLDTG/1BDzSw0xv9QQ80sNMb/UEPNLDTG/1P+fXzb+/+e32LrB29khthu8v8QQ+0sMsb/EEPsb6vw19b7Jhlg3eLvEENslBnEH7W+xdYO3SwyxXX1/tb/cqkbgQv1zTxN2tdV/GXsHfu8gMIvyPcXaSFcvF/VavVTUqle/TNRGpnaJiAaF6Fdclwp71bepXyLqo/rlob5RVyHa0chBH2ePHPTh9YjFP6YeOejz6Ib+mxsN/fczvL7bFw39NyuWGEQa29GyxCBYddXoxXmLb1TfT3XV8H5q31LvDhr72H0P9T7NRNtUWkz01ErL8P5911bXr9vVwbDeW2y1ldGzKy0jB/6PS2oPRJew6gPR/wFlVk9+Tr6n2n+OqjukbhrYqH9FnxYjCQ/vXax/rW9Mn4D6v983om/doMX6V/tGDYge9bV1wUOS0bf7qn1Yphljf8A4qI3F1FmZ8P8AjHyfawAAAAMACAACABEAAf//AAN42iXNuw2DUBBE0dn3JtiVnLg3LH8EbTikL+MCTCNAA+YTGMxIBFc62YUBOKknaiScAX5gbPlF5shRnjjJM2d54U9eucobN/nvL5g33iD72zu59x7JhyhgcYkrUtziLj+iRI4qKhioY1J2tAPvjxreeNpNkj1IXEEQx//73o637xn1OE9RESNWFhbBQiyukBQWkkJNCJikEDUkSgQR66tTW4aU1vYigoUYP8iX5sNovv0KBlRikLvq8n+bY5DHzvxmdnZn5s3CAIjRihzM44cj03Cw9KBUQkBlEIyOTk6heuzJ+CPU0xMkPr8DRsbIoAltJMOvtaxvoCLR5s9/O+igzHA5LuuOEEhl4rclxjxHI7pxE7dwF8OYwAzyeIpnmMM8lrGLAwbGJmtaTLvpNDnTa/rNbHJPdA+B/evpvtIDpSHShc/3UumV0mulN54CVnzN/SSfu7e6t6W0fSXqXcJugfI3QvZUjWx0h9ZxdJvyzL3XUx88JTFp1EcDCO2FPY8GfZaPGrWj9ElpV2lP6bPSF6WvSt88pZipgXNo5wy6kHPrzFlktes+d9GtURdor3m74L77Xl5QFt0qZcHf9aPcbcr+siccc0kEoaQ4tViqpAo1UiNppCUjtchInTQiyy6Tt5HlWzDo8K8jpBSehcRSK820Qntqz+wl40L6mwGXd3m0uCW3guvc74Ow/jae70JP+W9v+n+6QXnqa9snXXo6UDpUWizHXcn7Dy3Idx0AAHja7VsBaBbZEZ55721u4+WiiTHVNMSYSBCxkgaRIBLsESSENFgRCTaIFZsGa0MIIiIicgSRIBJEQhArVkRERMQeQbyc53mpl6bRU2s9L5d6aZrTv+p5wQtBrDWd93bjzv/vv8n+MbFeW8J8O//svJl58+bt7nu7AQSAaZADZYC1v9zYADYoksDICOgz+JtfNPyaZADT9S8QIOm8BUnwFkmTqeXbkALvQCpkwmJYCiWwEiphLWyCBtgN+6EFjsAJaIdeuAePYRheYBKmYibZQPobpONbgLLZ+S3bnKPa4xynrSQfCGpGw4yOtMy0WudX2un0+eknZi5wfs08MHMgY2nGXudXRvesyllXMsuc9pnnnOOczc4xO9No2TmX5xbObZo7kFuS25r7ZF6Fkb4zb++88/MiebPzyvK2553Mu5Nv5xfn1+a35nea8yL/zvwkx878hc6x4LZzXNjiHH900/QKf3zAPR6ifOljG6BoEXWEhylbFXAIjlJWTsM5OA8XoQO64Drcphz1Q4SyNATPqFESpmA6zsYcnI8LsRCX4nJ8F8uwEtfgOtyANbgFG3A77sJGbMJmbMHDeAxP4hl8Hy/gJbyC3XgT7+BdHMAHOIjD+FwIYYtUkSGyRK4oEItEkSgWJaJUlItVYq2o1iNutRBmGOw0CB6KXxm+N1aOzbGSkf5Y3tFBxTRzYlsF4UgHk2z34Sbrdy/5IAv9Y1ke2RDLx7ETkBPsjs2JK/F5d/OgJtJrv01XZ0PcmAUkqRErG8DeZe+CHPsD+wOYa39od0CufcX+GhYk/yx5jZ7xNNcGzTxPotGtsTYTn00zGSGP6hR1VcuIsYpkR2s/ZdpafoXmN0I3aadDASyCIiima0AplMMqugpUw0aohTrYCjvoarAH9ul2omoUcYVoJ/738idk42ORTVikJVAkd4yiq18Ay0n/Mmt7XuwmPCOuE74w8mPiIOEZ/HQUId1KslKsVCvNyrCyrB9a2ZSPD+2L9kf2Jftj+xO7g7LxqenXd16/dARqWF0DQRmk2YpFWIwlWIrluArXYjVuxFqsw624A3fjHtyHB7AVj+BxPIVnsQ3b8TJ24jW8hT3Yh/fwET7BpxShEtPEDJEpskWeWCAWiyVimVghVooKsVpUifVik9gs6sU2sVO8J/aK/eKgOCSOihPitDgnzouLokN0ievitugV/SIiHosh8UyCTJIpMl3OljlyvlwoC+VSuVy+K8tkpVwj18kNskZukQ1yu9wlG2WTbJYt8rA8Jk/KM/J9eUFekldkt7wp78i7ckA+kINyWD5XQtkqVWWoLJWrCtQiVaSKVYkqVeVqlVqrqtVGVavq1Fa1Q+1We9Q+dUC1qiPquDqlzqo21W5qY6XGpOM0NkOaxyHDdxu+W/Mi2+hkG77S8JWGZ22jeK4ToI99xn5frF9RZXSqfG3bDd/u81Vg+AKffr3h6w1favhSH899cXmh4QtNbJdNbJfH7GNQHsbmbZ88IM9h8hMVJ4+tyfBPQ/NOPAfH4qPqxOFrffHzOM3YYarnC4/77F/3dFybzYa/7fFRNo0dmWJ42+isYDZ3szGtCuBt31j3sdh4Tgp47RlNN04PnQp050shw8fML+Pd8WqO4cPfDdLUH1WX+pPqVtfUZ+rP6i/qtrqjvlL96u/qHl0T/2lfgDS6Tq4kqiBaTVRFtJ5oE9FmonqibUQ7id4j2ku0n+gg0SHycZSOJ7wanTSsY3WfavhDL6/ji/9/HZ/QdbxSP/O7WMiwxkP5Uw+5PAqrxzzrQzzOcIghkwe1pScQT1LKsIrhQQ/xvIdimYfykpG/iLUjnb5sMXyj0bnss1+TIPJWNkOW/6A8h8mPE6EbJ/d7PTHEWpa32thMusjqhPuVJewsz38qw0UeipMe4myGTh/XGOxmyPvO29ayaLmc5S1q7BhGjfUSps8zw/te4/UlKg8sTm4/qs79uCaGD38dz1Kd6qq6qb5QPepL1av+qu6qv6n7KqL+oR6oh+qR+kY9Vt+qJ2pIPVcvktcl/zy5GrJCXcHBvYIDrV+BVrAAeu5cJOog6iLSeblN1EvUT9FE6PiYSOfumZ6ivjmQEYBBOhBaP0hSFGhHmjUQ6t9ay+x80OpfDdO9T4CMGgGd+7l0NnWs+yZZFGRxubEJMRbHaxvf4zgxmsoAUxNoamLeVMcYx6OOsdyNcYOxOINwTgKVOVqXQVmfFs/Wa/A7fZx2kxpB3LH8z0cQlHsBS6KqKG3c6hl7bumeLHF7Uh7SYtC4OX5eMcaASp9AjHHz6sVYDltYjOkTHL/xayUo7zqCjZMSQfxaGcvva+t53NF8DT2PN/buDvHRN3yHeFCvsYJQbHN2DOLLo/SB8ft8bTsZDiaGuD4WuTywLYQ+C4nF4+xCOPsJXBLH/j5fBsL3ui/g7Cm9GnbRk4d/lpTquupTX9O8ANBPtnpWZOldErNXstrgb02vnPo98mbXr8oyETeaiJs8XkbYbkKPJ+FymcuwPr6Osx/D5VHYFutRVmt0o3LOLvFhxMs1j9+V86iYTcealeG14rwfA3PSxOSO5IjPL9cPysCYvY7y28iywdHzGL5+hbqlPid9/ZbTPAehs3O48/tTszJiVqBlBnPNquWp4Y8ZPt3bqXAkXK4qvNW305bruNZ6YuXqrLe/IQYMv4Oti7mdVoMpPowwv5HYmF0L3E6N5zEqQo4RHwblZJuXAS4JygbPAO+7m4Gq+NlzbLoxlDD9dg8djwYTqdkbaiCqZv8ACwg/od/OSq2EPZ/MfNli/GcehEwLLWEpy7Js621ruvUD+6J5F3bN/sy+Yd+0b9mf21/YX9n9FM1q8iYhB+bDQt0yjj9UDw3enwLLQ1Ns+eGUWX40ZZYfT5nlbydgWVdiXkAlOnYTt+hEOmpRr6mSzFO08wQ9FDV+YfV73FFJzP6jBO1/E1r/RoL6V92xD6t/3x3RsPoPE9S/mqD+jQT1exLU/zJB/SGmn0dXVkEzI9ttMYtZ7H35hQRaaSG1v3O1vz/Pwy2jX3nQk5XGViZpZGgkqjhW4kfXZuP4mvIWQ+ZRVTBJvQ+ZPMpXZHy0ej37nHfscAzMSZsncTXbQuQhoO/cF48kjh2H3+XLQyShL35Gd7JePls4X/K46NRs95tdswm/X+PvwhbFvmdMtNXUYfh43Hevqz1M2GN72Gy8et+j3mp57/jC1+xEdt/mkAftXb+9ayDaTrSLSD+hNxE1E7UQHSbST/P6reAZoveJLhDp979XiPRbu5tEd4juEunV0AOiQaJh6skyfY8JhbNDayaINCc1PvPQncdtb/o8dr6P8mGYLz6YprNLMglfkZROjp1x4mkP4F8BsXnys+HYHP0GzFi+5SHTDD+Px34noncX9bcXKxL+wmh0Ny4ITzO+i+0nBbeq+1+4F45z1R4KodPMvrzpfB33yMBIgr5xmWKcpF7/V9wLZb2+98h681QyyvsRzH96xNeJGOxiWB8KIdiv/u8NXMF21cya8F8Do38v6uOsETOc/+DQX8HTuq5zpNhZ5/0b9HXxHAAAAAABAAAAANWkJwgAAAAAyEN6pwAAAADYonM1` diff --git a/vendor/github.com/alecthomas/chroma/v2/formatters/svg/svg.go b/vendor/github.com/alecthomas/chroma/v2/formatters/svg/svg.go deleted file mode 100644 index 6d457f90a5..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/formatters/svg/svg.go +++ /dev/null @@ -1,222 +0,0 @@ -// Package svg contains an SVG formatter. -package svg - -import ( - "encoding/base64" - "errors" - "fmt" - "io" - "os" - "path" - "strings" - - "github.com/alecthomas/chroma/v2" -) - -// Option sets an option of the SVG formatter. -type Option func(f *Formatter) - -// FontFamily sets the font-family. -func FontFamily(fontFamily string) Option { return func(f *Formatter) { f.fontFamily = fontFamily } } - -// EmbedFontFile embeds given font file -func EmbedFontFile(fontFamily string, fileName string) (option Option, err error) { - var format FontFormat - switch path.Ext(fileName) { - case ".woff": - format = WOFF - case ".woff2": - format = WOFF2 - case ".ttf": - format = TRUETYPE - default: - return nil, errors.New("unexpected font file suffix") - } - - var content []byte - if content, err = os.ReadFile(fileName); err == nil { - option = EmbedFont(fontFamily, base64.StdEncoding.EncodeToString(content), format) - } - return -} - -// EmbedFont embeds given base64 encoded font -func EmbedFont(fontFamily string, font string, format FontFormat) Option { - return func(f *Formatter) { f.fontFamily = fontFamily; f.embeddedFont = font; f.fontFormat = format } -} - -// New SVG formatter. -func New(options ...Option) *Formatter { - f := &Formatter{fontFamily: "Consolas, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace"} - for _, option := range options { - option(f) - } - return f -} - -// Formatter that generates SVG. -type Formatter struct { - fontFamily string - embeddedFont string - fontFormat FontFormat -} - -func (f *Formatter) Format(w io.Writer, style *chroma.Style, iterator chroma.Iterator) (err error) { - f.writeSVG(w, style, iterator.Tokens()) - return err -} - -var svgEscaper = strings.NewReplacer( - `&`, "&", - `<`, "<", - `>`, ">", - `"`, """, - ` `, " ", - ` `, "    ", -) - -// EscapeString escapes special characters. -func escapeString(s string) string { - return svgEscaper.Replace(s) -} - -func (f *Formatter) writeSVG(w io.Writer, style *chroma.Style, tokens []chroma.Token) { // nolint: gocyclo - svgStyles := f.styleToSVG(style) - lines := chroma.SplitTokensIntoLines(tokens) - - fmt.Fprint(w, "\n") - fmt.Fprint(w, "\n") - fmt.Fprintf(w, "\n", 8*maxLineWidth(lines), 10+int(16.8*float64(len(lines)+1))) - - if f.embeddedFont != "" { - f.writeFontStyle(w) - } - - fmt.Fprintf(w, "\n", style.Get(chroma.Background).Background.String()) - fmt.Fprintf(w, "\n", f.fontFamily, style.Get(chroma.Text).Colour.String()) - - f.writeTokenBackgrounds(w, lines, style) - - for index, tokens := range lines { - fmt.Fprintf(w, "", 1.2*float64(index+1)) - - for _, token := range tokens { - text := escapeString(token.String()) - attr := f.styleAttr(svgStyles, token.Type) - if attr != "" { - text = fmt.Sprintf("%s", attr, text) - } - fmt.Fprint(w, text) - } - fmt.Fprint(w, "") - } - - fmt.Fprint(w, "\n\n") - fmt.Fprint(w, "\n") -} - -func maxLineWidth(lines [][]chroma.Token) int { - maxWidth := 0 - for _, tokens := range lines { - length := 0 - for _, token := range tokens { - length += len(strings.ReplaceAll(token.String(), ` `, " ")) - } - if length > maxWidth { - maxWidth = length - } - } - return maxWidth -} - -// There is no background attribute for text in SVG so simply calculate the position and text -// of tokens with a background color that differs from the default and add a rectangle for each before -// adding the token. -func (f *Formatter) writeTokenBackgrounds(w io.Writer, lines [][]chroma.Token, style *chroma.Style) { - for index, tokens := range lines { - lineLength := 0 - for _, token := range tokens { - length := len(strings.ReplaceAll(token.String(), ` `, " ")) - tokenBackground := style.Get(token.Type).Background - if tokenBackground.IsSet() && tokenBackground != style.Get(chroma.Background).Background { - fmt.Fprintf(w, "\n", escapeString(token.String()), lineLength, 1.2*float64(index)+0.25, length, style.Get(token.Type).Background.String()) - } - lineLength += length - } - } -} - -type FontFormat int - -// https://transfonter.org/formats -const ( - WOFF FontFormat = iota - WOFF2 - TRUETYPE -) - -var fontFormats = [...]string{ - "woff", - "woff2", - "truetype", -} - -func (f *Formatter) writeFontStyle(w io.Writer) { - fmt.Fprintf(w, ``, f.fontFamily, fontFormats[f.fontFormat], f.embeddedFont, fontFormats[f.fontFormat]) -} - -func (f *Formatter) styleAttr(styles map[chroma.TokenType]string, tt chroma.TokenType) string { - if _, ok := styles[tt]; !ok { - tt = tt.SubCategory() - if _, ok := styles[tt]; !ok { - tt = tt.Category() - if _, ok := styles[tt]; !ok { - return "" - } - } - } - return styles[tt] -} - -func (f *Formatter) styleToSVG(style *chroma.Style) map[chroma.TokenType]string { - converted := map[chroma.TokenType]string{} - bg := style.Get(chroma.Background) - // Convert the style. - for t := range chroma.StandardTypes { - entry := style.Get(t) - if t != chroma.Background { - entry = entry.Sub(bg) - } - if entry.IsZero() { - continue - } - converted[t] = StyleEntryToSVG(entry) - } - return converted -} - -// StyleEntryToSVG converts a chroma.StyleEntry to SVG attributes. -func StyleEntryToSVG(e chroma.StyleEntry) string { - var styles []string - - if e.Colour.IsSet() { - styles = append(styles, "fill=\""+e.Colour.String()+"\"") - } - if e.Bold == chroma.Yes { - styles = append(styles, "font-weight=\"bold\"") - } - if e.Italic == chroma.Yes { - styles = append(styles, "font-style=\"italic\"") - } - if e.Underline == chroma.Yes { - styles = append(styles, "text-decoration=\"underline\"") - } - return strings.Join(styles, " ") -} diff --git a/vendor/github.com/alecthomas/chroma/v2/formatters/tokens.go b/vendor/github.com/alecthomas/chroma/v2/formatters/tokens.go deleted file mode 100644 index 3bdd57ccfc..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/formatters/tokens.go +++ /dev/null @@ -1,18 +0,0 @@ -package formatters - -import ( - "fmt" - "io" - - "github.com/alecthomas/chroma/v2" -) - -// Tokens formatter outputs the raw token structures. -var Tokens = Register("tokens", chroma.FormatterFunc(func(w io.Writer, s *chroma.Style, it chroma.Iterator) error { - for t := it(); t != chroma.EOF; t = it() { - if _, err := fmt.Fprintln(w, t.GoString()); err != nil { - return err - } - } - return nil -})) diff --git a/vendor/github.com/alecthomas/chroma/v2/formatters/tty_indexed.go b/vendor/github.com/alecthomas/chroma/v2/formatters/tty_indexed.go deleted file mode 100644 index d48fb993cc..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/formatters/tty_indexed.go +++ /dev/null @@ -1,284 +0,0 @@ -package formatters - -import ( - "io" - "math" - - "github.com/alecthomas/chroma/v2" -) - -type ttyTable struct { - foreground map[chroma.Colour]string - background map[chroma.Colour]string -} - -var c = chroma.MustParseColour - -var ttyTables = map[int]*ttyTable{ - 8: { - foreground: map[chroma.Colour]string{ - c("#000000"): "\033[30m", c("#7f0000"): "\033[31m", c("#007f00"): "\033[32m", c("#7f7fe0"): "\033[33m", - c("#00007f"): "\033[34m", c("#7f007f"): "\033[35m", c("#007f7f"): "\033[36m", c("#e5e5e5"): "\033[37m", - c("#555555"): "\033[1m\033[30m", c("#ff0000"): "\033[1m\033[31m", c("#00ff00"): "\033[1m\033[32m", c("#ffff00"): "\033[1m\033[33m", - c("#0000ff"): "\033[1m\033[34m", c("#ff00ff"): "\033[1m\033[35m", c("#00ffff"): "\033[1m\033[36m", c("#ffffff"): "\033[1m\033[37m", - }, - background: map[chroma.Colour]string{ - c("#000000"): "\033[40m", c("#7f0000"): "\033[41m", c("#007f00"): "\033[42m", c("#7f7fe0"): "\033[43m", - c("#00007f"): "\033[44m", c("#7f007f"): "\033[45m", c("#007f7f"): "\033[46m", c("#e5e5e5"): "\033[47m", - c("#555555"): "\033[1m\033[40m", c("#ff0000"): "\033[1m\033[41m", c("#00ff00"): "\033[1m\033[42m", c("#ffff00"): "\033[1m\033[43m", - c("#0000ff"): "\033[1m\033[44m", c("#ff00ff"): "\033[1m\033[45m", c("#00ffff"): "\033[1m\033[46m", c("#ffffff"): "\033[1m\033[47m", - }, - }, - 16: { - foreground: map[chroma.Colour]string{ - c("#000000"): "\033[30m", c("#7f0000"): "\033[31m", c("#007f00"): "\033[32m", c("#7f7fe0"): "\033[33m", - c("#00007f"): "\033[34m", c("#7f007f"): "\033[35m", c("#007f7f"): "\033[36m", c("#e5e5e5"): "\033[37m", - c("#555555"): "\033[90m", c("#ff0000"): "\033[91m", c("#00ff00"): "\033[92m", c("#ffff00"): "\033[93m", - c("#0000ff"): "\033[94m", c("#ff00ff"): "\033[95m", c("#00ffff"): "\033[96m", c("#ffffff"): "\033[97m", - }, - background: map[chroma.Colour]string{ - c("#000000"): "\033[40m", c("#7f0000"): "\033[41m", c("#007f00"): "\033[42m", c("#7f7fe0"): "\033[43m", - c("#00007f"): "\033[44m", c("#7f007f"): "\033[45m", c("#007f7f"): "\033[46m", c("#e5e5e5"): "\033[47m", - c("#555555"): "\033[100m", c("#ff0000"): "\033[101m", c("#00ff00"): "\033[102m", c("#ffff00"): "\033[103m", - c("#0000ff"): "\033[104m", c("#ff00ff"): "\033[105m", c("#00ffff"): "\033[106m", c("#ffffff"): "\033[107m", - }, - }, - 256: { - foreground: map[chroma.Colour]string{ - c("#000000"): "\033[38;5;0m", c("#800000"): "\033[38;5;1m", c("#008000"): "\033[38;5;2m", c("#808000"): "\033[38;5;3m", - c("#000080"): "\033[38;5;4m", c("#800080"): "\033[38;5;5m", c("#008080"): "\033[38;5;6m", c("#c0c0c0"): "\033[38;5;7m", - c("#808080"): "\033[38;5;8m", c("#ff0000"): "\033[38;5;9m", c("#00ff00"): "\033[38;5;10m", c("#ffff00"): "\033[38;5;11m", - c("#0000ff"): "\033[38;5;12m", c("#ff00ff"): "\033[38;5;13m", c("#00ffff"): "\033[38;5;14m", c("#ffffff"): "\033[38;5;15m", - c("#000000"): "\033[38;5;16m", c("#00005f"): "\033[38;5;17m", c("#000087"): "\033[38;5;18m", c("#0000af"): "\033[38;5;19m", - c("#0000d7"): "\033[38;5;20m", c("#0000ff"): "\033[38;5;21m", c("#005f00"): "\033[38;5;22m", c("#005f5f"): "\033[38;5;23m", - c("#005f87"): "\033[38;5;24m", c("#005faf"): "\033[38;5;25m", c("#005fd7"): "\033[38;5;26m", c("#005fff"): "\033[38;5;27m", - c("#008700"): "\033[38;5;28m", c("#00875f"): "\033[38;5;29m", c("#008787"): "\033[38;5;30m", c("#0087af"): "\033[38;5;31m", - c("#0087d7"): "\033[38;5;32m", c("#0087ff"): "\033[38;5;33m", c("#00af00"): "\033[38;5;34m", c("#00af5f"): "\033[38;5;35m", - c("#00af87"): "\033[38;5;36m", c("#00afaf"): "\033[38;5;37m", c("#00afd7"): "\033[38;5;38m", c("#00afff"): "\033[38;5;39m", - c("#00d700"): "\033[38;5;40m", c("#00d75f"): "\033[38;5;41m", c("#00d787"): "\033[38;5;42m", c("#00d7af"): "\033[38;5;43m", - c("#00d7d7"): "\033[38;5;44m", c("#00d7ff"): "\033[38;5;45m", c("#00ff00"): "\033[38;5;46m", c("#00ff5f"): "\033[38;5;47m", - c("#00ff87"): "\033[38;5;48m", c("#00ffaf"): "\033[38;5;49m", c("#00ffd7"): "\033[38;5;50m", c("#00ffff"): "\033[38;5;51m", - c("#5f0000"): "\033[38;5;52m", c("#5f005f"): "\033[38;5;53m", c("#5f0087"): "\033[38;5;54m", c("#5f00af"): "\033[38;5;55m", - c("#5f00d7"): "\033[38;5;56m", c("#5f00ff"): "\033[38;5;57m", c("#5f5f00"): "\033[38;5;58m", c("#5f5f5f"): "\033[38;5;59m", - c("#5f5f87"): "\033[38;5;60m", c("#5f5faf"): "\033[38;5;61m", c("#5f5fd7"): "\033[38;5;62m", c("#5f5fff"): "\033[38;5;63m", - c("#5f8700"): "\033[38;5;64m", c("#5f875f"): "\033[38;5;65m", c("#5f8787"): "\033[38;5;66m", c("#5f87af"): "\033[38;5;67m", - c("#5f87d7"): "\033[38;5;68m", c("#5f87ff"): "\033[38;5;69m", c("#5faf00"): "\033[38;5;70m", c("#5faf5f"): "\033[38;5;71m", - c("#5faf87"): "\033[38;5;72m", c("#5fafaf"): "\033[38;5;73m", c("#5fafd7"): "\033[38;5;74m", c("#5fafff"): "\033[38;5;75m", - c("#5fd700"): "\033[38;5;76m", c("#5fd75f"): "\033[38;5;77m", c("#5fd787"): "\033[38;5;78m", c("#5fd7af"): "\033[38;5;79m", - c("#5fd7d7"): "\033[38;5;80m", c("#5fd7ff"): "\033[38;5;81m", c("#5fff00"): "\033[38;5;82m", c("#5fff5f"): "\033[38;5;83m", - c("#5fff87"): "\033[38;5;84m", c("#5fffaf"): "\033[38;5;85m", c("#5fffd7"): "\033[38;5;86m", c("#5fffff"): "\033[38;5;87m", - c("#870000"): "\033[38;5;88m", c("#87005f"): "\033[38;5;89m", c("#870087"): "\033[38;5;90m", c("#8700af"): "\033[38;5;91m", - c("#8700d7"): "\033[38;5;92m", c("#8700ff"): "\033[38;5;93m", c("#875f00"): "\033[38;5;94m", c("#875f5f"): "\033[38;5;95m", - c("#875f87"): "\033[38;5;96m", c("#875faf"): "\033[38;5;97m", c("#875fd7"): "\033[38;5;98m", c("#875fff"): "\033[38;5;99m", - c("#878700"): "\033[38;5;100m", c("#87875f"): "\033[38;5;101m", c("#878787"): "\033[38;5;102m", c("#8787af"): "\033[38;5;103m", - c("#8787d7"): "\033[38;5;104m", c("#8787ff"): "\033[38;5;105m", c("#87af00"): "\033[38;5;106m", c("#87af5f"): "\033[38;5;107m", - c("#87af87"): "\033[38;5;108m", c("#87afaf"): "\033[38;5;109m", c("#87afd7"): "\033[38;5;110m", c("#87afff"): "\033[38;5;111m", - c("#87d700"): "\033[38;5;112m", c("#87d75f"): "\033[38;5;113m", c("#87d787"): "\033[38;5;114m", c("#87d7af"): "\033[38;5;115m", - c("#87d7d7"): "\033[38;5;116m", c("#87d7ff"): "\033[38;5;117m", c("#87ff00"): "\033[38;5;118m", c("#87ff5f"): "\033[38;5;119m", - c("#87ff87"): "\033[38;5;120m", c("#87ffaf"): "\033[38;5;121m", c("#87ffd7"): "\033[38;5;122m", c("#87ffff"): "\033[38;5;123m", - c("#af0000"): "\033[38;5;124m", c("#af005f"): "\033[38;5;125m", c("#af0087"): "\033[38;5;126m", c("#af00af"): "\033[38;5;127m", - c("#af00d7"): "\033[38;5;128m", c("#af00ff"): "\033[38;5;129m", c("#af5f00"): "\033[38;5;130m", c("#af5f5f"): "\033[38;5;131m", - c("#af5f87"): "\033[38;5;132m", c("#af5faf"): "\033[38;5;133m", c("#af5fd7"): "\033[38;5;134m", c("#af5fff"): "\033[38;5;135m", - c("#af8700"): "\033[38;5;136m", c("#af875f"): "\033[38;5;137m", c("#af8787"): "\033[38;5;138m", c("#af87af"): "\033[38;5;139m", - c("#af87d7"): "\033[38;5;140m", c("#af87ff"): "\033[38;5;141m", c("#afaf00"): "\033[38;5;142m", c("#afaf5f"): "\033[38;5;143m", - c("#afaf87"): "\033[38;5;144m", c("#afafaf"): "\033[38;5;145m", c("#afafd7"): "\033[38;5;146m", c("#afafff"): "\033[38;5;147m", - c("#afd700"): "\033[38;5;148m", c("#afd75f"): "\033[38;5;149m", c("#afd787"): "\033[38;5;150m", c("#afd7af"): "\033[38;5;151m", - c("#afd7d7"): "\033[38;5;152m", c("#afd7ff"): "\033[38;5;153m", c("#afff00"): "\033[38;5;154m", c("#afff5f"): "\033[38;5;155m", - c("#afff87"): "\033[38;5;156m", c("#afffaf"): "\033[38;5;157m", c("#afffd7"): "\033[38;5;158m", c("#afffff"): "\033[38;5;159m", - c("#d70000"): "\033[38;5;160m", c("#d7005f"): "\033[38;5;161m", c("#d70087"): "\033[38;5;162m", c("#d700af"): "\033[38;5;163m", - c("#d700d7"): "\033[38;5;164m", c("#d700ff"): "\033[38;5;165m", c("#d75f00"): "\033[38;5;166m", c("#d75f5f"): "\033[38;5;167m", - c("#d75f87"): "\033[38;5;168m", c("#d75faf"): "\033[38;5;169m", c("#d75fd7"): "\033[38;5;170m", c("#d75fff"): "\033[38;5;171m", - c("#d78700"): "\033[38;5;172m", c("#d7875f"): "\033[38;5;173m", c("#d78787"): "\033[38;5;174m", c("#d787af"): "\033[38;5;175m", - c("#d787d7"): "\033[38;5;176m", c("#d787ff"): "\033[38;5;177m", c("#d7af00"): "\033[38;5;178m", c("#d7af5f"): "\033[38;5;179m", - c("#d7af87"): "\033[38;5;180m", c("#d7afaf"): "\033[38;5;181m", c("#d7afd7"): "\033[38;5;182m", c("#d7afff"): "\033[38;5;183m", - c("#d7d700"): "\033[38;5;184m", c("#d7d75f"): "\033[38;5;185m", c("#d7d787"): "\033[38;5;186m", c("#d7d7af"): "\033[38;5;187m", - c("#d7d7d7"): "\033[38;5;188m", c("#d7d7ff"): "\033[38;5;189m", c("#d7ff00"): "\033[38;5;190m", c("#d7ff5f"): "\033[38;5;191m", - c("#d7ff87"): "\033[38;5;192m", c("#d7ffaf"): "\033[38;5;193m", c("#d7ffd7"): "\033[38;5;194m", c("#d7ffff"): "\033[38;5;195m", - c("#ff0000"): "\033[38;5;196m", c("#ff005f"): "\033[38;5;197m", c("#ff0087"): "\033[38;5;198m", c("#ff00af"): "\033[38;5;199m", - c("#ff00d7"): "\033[38;5;200m", c("#ff00ff"): "\033[38;5;201m", c("#ff5f00"): "\033[38;5;202m", c("#ff5f5f"): "\033[38;5;203m", - c("#ff5f87"): "\033[38;5;204m", c("#ff5faf"): "\033[38;5;205m", c("#ff5fd7"): "\033[38;5;206m", c("#ff5fff"): "\033[38;5;207m", - c("#ff8700"): "\033[38;5;208m", c("#ff875f"): "\033[38;5;209m", c("#ff8787"): "\033[38;5;210m", c("#ff87af"): "\033[38;5;211m", - c("#ff87d7"): "\033[38;5;212m", c("#ff87ff"): "\033[38;5;213m", c("#ffaf00"): "\033[38;5;214m", c("#ffaf5f"): "\033[38;5;215m", - c("#ffaf87"): "\033[38;5;216m", c("#ffafaf"): "\033[38;5;217m", c("#ffafd7"): "\033[38;5;218m", c("#ffafff"): "\033[38;5;219m", - c("#ffd700"): "\033[38;5;220m", c("#ffd75f"): "\033[38;5;221m", c("#ffd787"): "\033[38;5;222m", c("#ffd7af"): "\033[38;5;223m", - c("#ffd7d7"): "\033[38;5;224m", c("#ffd7ff"): "\033[38;5;225m", c("#ffff00"): "\033[38;5;226m", c("#ffff5f"): "\033[38;5;227m", - c("#ffff87"): "\033[38;5;228m", c("#ffffaf"): "\033[38;5;229m", c("#ffffd7"): "\033[38;5;230m", c("#ffffff"): "\033[38;5;231m", - c("#080808"): "\033[38;5;232m", c("#121212"): "\033[38;5;233m", c("#1c1c1c"): "\033[38;5;234m", c("#262626"): "\033[38;5;235m", - c("#303030"): "\033[38;5;236m", c("#3a3a3a"): "\033[38;5;237m", c("#444444"): "\033[38;5;238m", c("#4e4e4e"): "\033[38;5;239m", - c("#585858"): "\033[38;5;240m", c("#626262"): "\033[38;5;241m", c("#6c6c6c"): "\033[38;5;242m", c("#767676"): "\033[38;5;243m", - c("#808080"): "\033[38;5;244m", c("#8a8a8a"): "\033[38;5;245m", c("#949494"): "\033[38;5;246m", c("#9e9e9e"): "\033[38;5;247m", - c("#a8a8a8"): "\033[38;5;248m", c("#b2b2b2"): "\033[38;5;249m", c("#bcbcbc"): "\033[38;5;250m", c("#c6c6c6"): "\033[38;5;251m", - c("#d0d0d0"): "\033[38;5;252m", c("#dadada"): "\033[38;5;253m", c("#e4e4e4"): "\033[38;5;254m", c("#eeeeee"): "\033[38;5;255m", - }, - background: map[chroma.Colour]string{ - c("#000000"): "\033[48;5;0m", c("#800000"): "\033[48;5;1m", c("#008000"): "\033[48;5;2m", c("#808000"): "\033[48;5;3m", - c("#000080"): "\033[48;5;4m", c("#800080"): "\033[48;5;5m", c("#008080"): "\033[48;5;6m", c("#c0c0c0"): "\033[48;5;7m", - c("#808080"): "\033[48;5;8m", c("#ff0000"): "\033[48;5;9m", c("#00ff00"): "\033[48;5;10m", c("#ffff00"): "\033[48;5;11m", - c("#0000ff"): "\033[48;5;12m", c("#ff00ff"): "\033[48;5;13m", c("#00ffff"): "\033[48;5;14m", c("#ffffff"): "\033[48;5;15m", - c("#000000"): "\033[48;5;16m", c("#00005f"): "\033[48;5;17m", c("#000087"): "\033[48;5;18m", c("#0000af"): "\033[48;5;19m", - c("#0000d7"): "\033[48;5;20m", c("#0000ff"): "\033[48;5;21m", c("#005f00"): "\033[48;5;22m", c("#005f5f"): "\033[48;5;23m", - c("#005f87"): "\033[48;5;24m", c("#005faf"): "\033[48;5;25m", c("#005fd7"): "\033[48;5;26m", c("#005fff"): "\033[48;5;27m", - c("#008700"): "\033[48;5;28m", c("#00875f"): "\033[48;5;29m", c("#008787"): "\033[48;5;30m", c("#0087af"): "\033[48;5;31m", - c("#0087d7"): "\033[48;5;32m", c("#0087ff"): "\033[48;5;33m", c("#00af00"): "\033[48;5;34m", c("#00af5f"): "\033[48;5;35m", - c("#00af87"): "\033[48;5;36m", c("#00afaf"): "\033[48;5;37m", c("#00afd7"): "\033[48;5;38m", c("#00afff"): "\033[48;5;39m", - c("#00d700"): "\033[48;5;40m", c("#00d75f"): "\033[48;5;41m", c("#00d787"): "\033[48;5;42m", c("#00d7af"): "\033[48;5;43m", - c("#00d7d7"): "\033[48;5;44m", c("#00d7ff"): "\033[48;5;45m", c("#00ff00"): "\033[48;5;46m", c("#00ff5f"): "\033[48;5;47m", - c("#00ff87"): "\033[48;5;48m", c("#00ffaf"): "\033[48;5;49m", c("#00ffd7"): "\033[48;5;50m", c("#00ffff"): "\033[48;5;51m", - c("#5f0000"): "\033[48;5;52m", c("#5f005f"): "\033[48;5;53m", c("#5f0087"): "\033[48;5;54m", c("#5f00af"): "\033[48;5;55m", - c("#5f00d7"): "\033[48;5;56m", c("#5f00ff"): "\033[48;5;57m", c("#5f5f00"): "\033[48;5;58m", c("#5f5f5f"): "\033[48;5;59m", - c("#5f5f87"): "\033[48;5;60m", c("#5f5faf"): "\033[48;5;61m", c("#5f5fd7"): "\033[48;5;62m", c("#5f5fff"): "\033[48;5;63m", - c("#5f8700"): "\033[48;5;64m", c("#5f875f"): "\033[48;5;65m", c("#5f8787"): "\033[48;5;66m", c("#5f87af"): "\033[48;5;67m", - c("#5f87d7"): "\033[48;5;68m", c("#5f87ff"): "\033[48;5;69m", c("#5faf00"): "\033[48;5;70m", c("#5faf5f"): "\033[48;5;71m", - c("#5faf87"): "\033[48;5;72m", c("#5fafaf"): "\033[48;5;73m", c("#5fafd7"): "\033[48;5;74m", c("#5fafff"): "\033[48;5;75m", - c("#5fd700"): "\033[48;5;76m", c("#5fd75f"): "\033[48;5;77m", c("#5fd787"): "\033[48;5;78m", c("#5fd7af"): "\033[48;5;79m", - c("#5fd7d7"): "\033[48;5;80m", c("#5fd7ff"): "\033[48;5;81m", c("#5fff00"): "\033[48;5;82m", c("#5fff5f"): "\033[48;5;83m", - c("#5fff87"): "\033[48;5;84m", c("#5fffaf"): "\033[48;5;85m", c("#5fffd7"): "\033[48;5;86m", c("#5fffff"): "\033[48;5;87m", - c("#870000"): "\033[48;5;88m", c("#87005f"): "\033[48;5;89m", c("#870087"): "\033[48;5;90m", c("#8700af"): "\033[48;5;91m", - c("#8700d7"): "\033[48;5;92m", c("#8700ff"): "\033[48;5;93m", c("#875f00"): "\033[48;5;94m", c("#875f5f"): "\033[48;5;95m", - c("#875f87"): "\033[48;5;96m", c("#875faf"): "\033[48;5;97m", c("#875fd7"): "\033[48;5;98m", c("#875fff"): "\033[48;5;99m", - c("#878700"): "\033[48;5;100m", c("#87875f"): "\033[48;5;101m", c("#878787"): "\033[48;5;102m", c("#8787af"): "\033[48;5;103m", - c("#8787d7"): "\033[48;5;104m", c("#8787ff"): "\033[48;5;105m", c("#87af00"): "\033[48;5;106m", c("#87af5f"): "\033[48;5;107m", - c("#87af87"): "\033[48;5;108m", c("#87afaf"): "\033[48;5;109m", c("#87afd7"): "\033[48;5;110m", c("#87afff"): "\033[48;5;111m", - c("#87d700"): "\033[48;5;112m", c("#87d75f"): "\033[48;5;113m", c("#87d787"): "\033[48;5;114m", c("#87d7af"): "\033[48;5;115m", - c("#87d7d7"): "\033[48;5;116m", c("#87d7ff"): "\033[48;5;117m", c("#87ff00"): "\033[48;5;118m", c("#87ff5f"): "\033[48;5;119m", - c("#87ff87"): "\033[48;5;120m", c("#87ffaf"): "\033[48;5;121m", c("#87ffd7"): "\033[48;5;122m", c("#87ffff"): "\033[48;5;123m", - c("#af0000"): "\033[48;5;124m", c("#af005f"): "\033[48;5;125m", c("#af0087"): "\033[48;5;126m", c("#af00af"): "\033[48;5;127m", - c("#af00d7"): "\033[48;5;128m", c("#af00ff"): "\033[48;5;129m", c("#af5f00"): "\033[48;5;130m", c("#af5f5f"): "\033[48;5;131m", - c("#af5f87"): "\033[48;5;132m", c("#af5faf"): "\033[48;5;133m", c("#af5fd7"): "\033[48;5;134m", c("#af5fff"): "\033[48;5;135m", - c("#af8700"): "\033[48;5;136m", c("#af875f"): "\033[48;5;137m", c("#af8787"): "\033[48;5;138m", c("#af87af"): "\033[48;5;139m", - c("#af87d7"): "\033[48;5;140m", c("#af87ff"): "\033[48;5;141m", c("#afaf00"): "\033[48;5;142m", c("#afaf5f"): "\033[48;5;143m", - c("#afaf87"): "\033[48;5;144m", c("#afafaf"): "\033[48;5;145m", c("#afafd7"): "\033[48;5;146m", c("#afafff"): "\033[48;5;147m", - c("#afd700"): "\033[48;5;148m", c("#afd75f"): "\033[48;5;149m", c("#afd787"): "\033[48;5;150m", c("#afd7af"): "\033[48;5;151m", - c("#afd7d7"): "\033[48;5;152m", c("#afd7ff"): "\033[48;5;153m", c("#afff00"): "\033[48;5;154m", c("#afff5f"): "\033[48;5;155m", - c("#afff87"): "\033[48;5;156m", c("#afffaf"): "\033[48;5;157m", c("#afffd7"): "\033[48;5;158m", c("#afffff"): "\033[48;5;159m", - c("#d70000"): "\033[48;5;160m", c("#d7005f"): "\033[48;5;161m", c("#d70087"): "\033[48;5;162m", c("#d700af"): "\033[48;5;163m", - c("#d700d7"): "\033[48;5;164m", c("#d700ff"): "\033[48;5;165m", c("#d75f00"): "\033[48;5;166m", c("#d75f5f"): "\033[48;5;167m", - c("#d75f87"): "\033[48;5;168m", c("#d75faf"): "\033[48;5;169m", c("#d75fd7"): "\033[48;5;170m", c("#d75fff"): "\033[48;5;171m", - c("#d78700"): "\033[48;5;172m", c("#d7875f"): "\033[48;5;173m", c("#d78787"): "\033[48;5;174m", c("#d787af"): "\033[48;5;175m", - c("#d787d7"): "\033[48;5;176m", c("#d787ff"): "\033[48;5;177m", c("#d7af00"): "\033[48;5;178m", c("#d7af5f"): "\033[48;5;179m", - c("#d7af87"): "\033[48;5;180m", c("#d7afaf"): "\033[48;5;181m", c("#d7afd7"): "\033[48;5;182m", c("#d7afff"): "\033[48;5;183m", - c("#d7d700"): "\033[48;5;184m", c("#d7d75f"): "\033[48;5;185m", c("#d7d787"): "\033[48;5;186m", c("#d7d7af"): "\033[48;5;187m", - c("#d7d7d7"): "\033[48;5;188m", c("#d7d7ff"): "\033[48;5;189m", c("#d7ff00"): "\033[48;5;190m", c("#d7ff5f"): "\033[48;5;191m", - c("#d7ff87"): "\033[48;5;192m", c("#d7ffaf"): "\033[48;5;193m", c("#d7ffd7"): "\033[48;5;194m", c("#d7ffff"): "\033[48;5;195m", - c("#ff0000"): "\033[48;5;196m", c("#ff005f"): "\033[48;5;197m", c("#ff0087"): "\033[48;5;198m", c("#ff00af"): "\033[48;5;199m", - c("#ff00d7"): "\033[48;5;200m", c("#ff00ff"): "\033[48;5;201m", c("#ff5f00"): "\033[48;5;202m", c("#ff5f5f"): "\033[48;5;203m", - c("#ff5f87"): "\033[48;5;204m", c("#ff5faf"): "\033[48;5;205m", c("#ff5fd7"): "\033[48;5;206m", c("#ff5fff"): "\033[48;5;207m", - c("#ff8700"): "\033[48;5;208m", c("#ff875f"): "\033[48;5;209m", c("#ff8787"): "\033[48;5;210m", c("#ff87af"): "\033[48;5;211m", - c("#ff87d7"): "\033[48;5;212m", c("#ff87ff"): "\033[48;5;213m", c("#ffaf00"): "\033[48;5;214m", c("#ffaf5f"): "\033[48;5;215m", - c("#ffaf87"): "\033[48;5;216m", c("#ffafaf"): "\033[48;5;217m", c("#ffafd7"): "\033[48;5;218m", c("#ffafff"): "\033[48;5;219m", - c("#ffd700"): "\033[48;5;220m", c("#ffd75f"): "\033[48;5;221m", c("#ffd787"): "\033[48;5;222m", c("#ffd7af"): "\033[48;5;223m", - c("#ffd7d7"): "\033[48;5;224m", c("#ffd7ff"): "\033[48;5;225m", c("#ffff00"): "\033[48;5;226m", c("#ffff5f"): "\033[48;5;227m", - c("#ffff87"): "\033[48;5;228m", c("#ffffaf"): "\033[48;5;229m", c("#ffffd7"): "\033[48;5;230m", c("#ffffff"): "\033[48;5;231m", - c("#080808"): "\033[48;5;232m", c("#121212"): "\033[48;5;233m", c("#1c1c1c"): "\033[48;5;234m", c("#262626"): "\033[48;5;235m", - c("#303030"): "\033[48;5;236m", c("#3a3a3a"): "\033[48;5;237m", c("#444444"): "\033[48;5;238m", c("#4e4e4e"): "\033[48;5;239m", - c("#585858"): "\033[48;5;240m", c("#626262"): "\033[48;5;241m", c("#6c6c6c"): "\033[48;5;242m", c("#767676"): "\033[48;5;243m", - c("#808080"): "\033[48;5;244m", c("#8a8a8a"): "\033[48;5;245m", c("#949494"): "\033[48;5;246m", c("#9e9e9e"): "\033[48;5;247m", - c("#a8a8a8"): "\033[48;5;248m", c("#b2b2b2"): "\033[48;5;249m", c("#bcbcbc"): "\033[48;5;250m", c("#c6c6c6"): "\033[48;5;251m", - c("#d0d0d0"): "\033[48;5;252m", c("#dadada"): "\033[48;5;253m", c("#e4e4e4"): "\033[48;5;254m", c("#eeeeee"): "\033[48;5;255m", - }, - }, -} - -func entryToEscapeSequence(table *ttyTable, entry chroma.StyleEntry) string { - out := "" - if entry.Bold == chroma.Yes { - out += "\033[1m" - } - if entry.Underline == chroma.Yes { - out += "\033[4m" - } - if entry.Italic == chroma.Yes { - out += "\033[3m" - } - if entry.Colour.IsSet() { - out += table.foreground[findClosest(table, entry.Colour)] - } - if entry.Background.IsSet() { - out += table.background[findClosest(table, entry.Background)] - } - return out -} - -func findClosest(table *ttyTable, seeking chroma.Colour) chroma.Colour { - closestColour := chroma.Colour(0) - closest := float64(math.MaxFloat64) - for colour := range table.foreground { - distance := colour.Distance(seeking) - if distance < closest { - closest = distance - closestColour = colour - } - } - return closestColour -} - -func styleToEscapeSequence(table *ttyTable, style *chroma.Style) map[chroma.TokenType]string { - style = clearBackground(style) - out := map[chroma.TokenType]string{} - for _, ttype := range style.Types() { - entry := style.Get(ttype) - out[ttype] = entryToEscapeSequence(table, entry) - } - return out -} - -// Clear the background colour. -func clearBackground(style *chroma.Style) *chroma.Style { - builder := style.Builder() - bg := builder.Get(chroma.Background) - bg.Background = 0 - bg.NoInherit = true - builder.AddEntry(chroma.Background, bg) - style, _ = builder.Build() - return style -} - -type indexedTTYFormatter struct { - table *ttyTable -} - -func (c *indexedTTYFormatter) Format(w io.Writer, style *chroma.Style, it chroma.Iterator) (err error) { - theme := styleToEscapeSequence(c.table, style) - for token := it(); token != chroma.EOF; token = it() { - clr, ok := theme[token.Type] - - // This search mimics how styles.Get() is used in tty_truecolour.go. - if !ok { - clr, ok = theme[token.Type.SubCategory()] - if !ok { - clr, ok = theme[token.Type.Category()] - if !ok { - clr, ok = theme[chroma.Text] - if !ok { - clr = theme[chroma.Background] - } - } - } - } - - writeToken(w, clr, token.Value) - } - return nil -} - -// TTY is an 8-colour terminal formatter. -// -// The Lab colour space is used to map RGB values to the most appropriate index colour. -var TTY = Register("terminal", &indexedTTYFormatter{ttyTables[8]}) - -// TTY8 is an 8-colour terminal formatter. -// -// The Lab colour space is used to map RGB values to the most appropriate index colour. -var TTY8 = Register("terminal8", &indexedTTYFormatter{ttyTables[8]}) - -// TTY16 is a 16-colour terminal formatter. -// -// It uses \033[3xm for normal colours and \033[90Xm for bright colours. -// -// The Lab colour space is used to map RGB values to the most appropriate index colour. -var TTY16 = Register("terminal16", &indexedTTYFormatter{ttyTables[16]}) - -// TTY256 is a 256-colour terminal formatter. -// -// The Lab colour space is used to map RGB values to the most appropriate index colour. -var TTY256 = Register("terminal256", &indexedTTYFormatter{ttyTables[256]}) diff --git a/vendor/github.com/alecthomas/chroma/v2/formatters/tty_truecolour.go b/vendor/github.com/alecthomas/chroma/v2/formatters/tty_truecolour.go deleted file mode 100644 index 43b0964769..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/formatters/tty_truecolour.go +++ /dev/null @@ -1,76 +0,0 @@ -package formatters - -import ( - "fmt" - "io" - "regexp" - - "github.com/alecthomas/chroma/v2" -) - -// TTY16m is a true-colour terminal formatter. -var TTY16m = Register("terminal16m", chroma.FormatterFunc(trueColourFormatter)) - -var crOrCrLf = regexp.MustCompile(`\r?\n`) - -// Print the text with the given formatting, resetting the formatting at the end -// of each line and resuming it on the next line. -// -// This way, a pager (like https://github.com/walles/moar for example) can show -// any line in the output by itself, and it will get the right formatting. -func writeToken(w io.Writer, formatting string, text string) { - if formatting == "" { - fmt.Fprint(w, text) - return - } - - newlineIndices := crOrCrLf.FindAllStringIndex(text, -1) - - afterLastNewline := 0 - for _, indices := range newlineIndices { - newlineStart, afterNewline := indices[0], indices[1] - fmt.Fprint(w, formatting) - fmt.Fprint(w, text[afterLastNewline:newlineStart]) - fmt.Fprint(w, "\033[0m") - fmt.Fprint(w, text[newlineStart:afterNewline]) - afterLastNewline = afterNewline - } - - if afterLastNewline < len(text) { - // Print whatever is left after the last newline - fmt.Fprint(w, formatting) - fmt.Fprint(w, text[afterLastNewline:]) - fmt.Fprint(w, "\033[0m") - } -} - -func trueColourFormatter(w io.Writer, style *chroma.Style, it chroma.Iterator) error { - style = clearBackground(style) - for token := it(); token != chroma.EOF; token = it() { - entry := style.Get(token.Type) - if entry.IsZero() { - fmt.Fprint(w, token.Value) - continue - } - - formatting := "" - if entry.Bold == chroma.Yes { - formatting += "\033[1m" - } - if entry.Underline == chroma.Yes { - formatting += "\033[4m" - } - if entry.Italic == chroma.Yes { - formatting += "\033[3m" - } - if entry.Colour.IsSet() { - formatting += fmt.Sprintf("\033[38;2;%d;%d;%dm", entry.Colour.Red(), entry.Colour.Green(), entry.Colour.Blue()) - } - if entry.Background.IsSet() { - formatting += fmt.Sprintf("\033[48;2;%d;%d;%dm", entry.Background.Red(), entry.Background.Green(), entry.Background.Blue()) - } - - writeToken(w, formatting, token.Value) - } - return nil -} diff --git a/vendor/github.com/alecthomas/chroma/v2/iterator.go b/vendor/github.com/alecthomas/chroma/v2/iterator.go deleted file mode 100644 index b1e0b57b66..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/iterator.go +++ /dev/null @@ -1,87 +0,0 @@ -package chroma - -import "strings" - -// An Iterator across tokens. -// -// EOF will be returned at the end of the Token stream. -// -// If an error occurs within an Iterator, it may propagate this in a panic. Formatters should recover. -type Iterator func() Token - -// Tokens consumes all tokens from the iterator and returns them as a slice. -func (i Iterator) Tokens() []Token { - var out []Token - for t := i(); t != EOF; t = i() { - out = append(out, t) - } - return out -} - -// Stdlib converts a Chroma iterator to a Go 1.23-compatible iterator. -func (i Iterator) Stdlib() func(yield func(Token) bool) { - return func(yield func(Token) bool) { - for t := i(); t != EOF; t = i() { - if !yield(t) { - return - } - } - } -} - -// Concaterator concatenates tokens from a series of iterators. -func Concaterator(iterators ...Iterator) Iterator { - return func() Token { - for len(iterators) > 0 { - t := iterators[0]() - if t != EOF { - return t - } - iterators = iterators[1:] - } - return EOF - } -} - -// Literator converts a sequence of literal Tokens into an Iterator. -func Literator(tokens ...Token) Iterator { - return func() Token { - if len(tokens) == 0 { - return EOF - } - token := tokens[0] - tokens = tokens[1:] - return token - } -} - -// SplitTokensIntoLines splits tokens containing newlines in two. -func SplitTokensIntoLines(tokens []Token) (out [][]Token) { - var line []Token // nolint: prealloc - for _, token := range tokens { - for strings.Contains(token.Value, "\n") { - parts := strings.SplitAfterN(token.Value, "\n", 2) - // Token becomes the tail. - token.Value = parts[1] - - // Append the head to the line and flush the line. - clone := token.Clone() - clone.Value = parts[0] - line = append(line, clone) - out = append(out, line) - line = nil - } - line = append(line, token) - } - if len(line) > 0 { - out = append(out, line) - } - // Strip empty trailing token line. - if len(out) > 0 { - last := out[len(out)-1] - if len(last) == 1 && last[0].Value == "" { - out = out[:len(out)-1] - } - } - return -} diff --git a/vendor/github.com/alecthomas/chroma/v2/lexer.go b/vendor/github.com/alecthomas/chroma/v2/lexer.go deleted file mode 100644 index 602db1c4f0..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexer.go +++ /dev/null @@ -1,179 +0,0 @@ -package chroma - -import ( - "fmt" - "strings" -) - -var ( - defaultOptions = &TokeniseOptions{ - State: "root", - EnsureLF: true, - } -) - -// Config for a lexer. -type Config struct { - // Name of the lexer. - Name string `xml:"name,omitempty"` - - // Shortcuts for the lexer - Aliases []string `xml:"alias,omitempty"` - - // File name globs - Filenames []string `xml:"filename,omitempty"` - - // Secondary file name globs - AliasFilenames []string `xml:"alias_filename,omitempty"` - - // MIME types - MimeTypes []string `xml:"mime_type,omitempty"` - - // Regex matching is case-insensitive. - CaseInsensitive bool `xml:"case_insensitive,omitempty"` - - // Regex matches all characters. - DotAll bool `xml:"dot_all,omitempty"` - - // Regex does not match across lines ($ matches EOL). - // - // Defaults to multiline. - NotMultiline bool `xml:"not_multiline,omitempty"` - - // Don't strip leading and trailing newlines from the input. - // DontStripNL bool - - // Strip all leading and trailing whitespace from the input - // StripAll bool - - // Make sure that the input ends with a newline. This - // is required for some lexers that consume input linewise. - EnsureNL bool `xml:"ensure_nl,omitempty"` - - // If given and greater than 0, expand tabs in the input. - // TabSize int - - // Priority of lexer. - // - // If this is 0 it will be treated as a default of 1. - Priority float32 `xml:"priority,omitempty"` - - // Analyse is a list of regexes to match against the input. - // - // If a match is found, the score is returned if single attribute is set to true, - // otherwise the sum of all the score of matching patterns will be - // used as the final score. - Analyse *AnalyseConfig `xml:"analyse,omitempty"` -} - -// AnalyseConfig defines the list of regexes analysers. -type AnalyseConfig struct { - Regexes []RegexConfig `xml:"regex,omitempty"` - // If true, the first matching score is returned. - First bool `xml:"first,attr"` -} - -// RegexConfig defines a single regex pattern and its score in case of match. -type RegexConfig struct { - Pattern string `xml:"pattern,attr"` - Score float32 `xml:"score,attr"` -} - -// Token output to formatter. -type Token struct { - Type TokenType `json:"type"` - Value string `json:"value"` -} - -func (t *Token) String() string { return t.Value } -func (t *Token) GoString() string { return fmt.Sprintf("&Token{%s, %q}", t.Type, t.Value) } - -// Clone returns a clone of the Token. -func (t *Token) Clone() Token { - return *t -} - -// EOF is returned by lexers at the end of input. -var EOF Token - -// TokeniseOptions contains options for tokenisers. -type TokeniseOptions struct { - // State to start tokenisation in. Defaults to "root". - State string - // Nested tokenisation. - Nested bool - - // If true, all EOLs are converted into LF - // by replacing CRLF and CR - EnsureLF bool -} - -// A Lexer for tokenising source code. -type Lexer interface { - // Config describing the features of the Lexer. - Config() *Config - // Tokenise returns an Iterator over tokens in text. - Tokenise(options *TokeniseOptions, text string) (Iterator, error) - // SetRegistry sets the registry this Lexer is associated with. - // - // The registry should be used by the Lexer if it needs to look up other - // lexers. - SetRegistry(registry *LexerRegistry) Lexer - // SetAnalyser sets a function the Lexer should use for scoring how - // likely a fragment of text is to match this lexer, between 0.0 and 1.0. - // A value of 1 indicates high confidence. - // - // Lexers may ignore this if they implement their own analysers. - SetAnalyser(analyser func(text string) float32) Lexer - // AnalyseText scores how likely a fragment of text is to match - // this lexer, between 0.0 and 1.0. A value of 1 indicates high confidence. - AnalyseText(text string) float32 -} - -// Trace is the trace of a tokenisation process. -type Trace struct { - Lexer string `json:"lexer"` - State string `json:"state"` - Rule int `json:"rule"` - Pattern string `json:"pattern"` - Pos int `json:"pos"` - Length int `json:"length"` - Elapsed float64 `json:"elapsedMs"` // Elapsed time spent matching for this rule. -} - -// TracingLexer is a Lexer that can trace its tokenisation process. -type TracingLexer interface { - Lexer - SetTracing(enable bool) -} - -// Lexers is a slice of lexers sortable by name. -type Lexers []Lexer - -func (l Lexers) Len() int { return len(l) } -func (l Lexers) Swap(i, j int) { l[i], l[j] = l[j], l[i] } -func (l Lexers) Less(i, j int) bool { - return strings.ToLower(l[i].Config().Name) < strings.ToLower(l[j].Config().Name) -} - -// PrioritisedLexers is a slice of lexers sortable by priority. -type PrioritisedLexers []Lexer - -func (l PrioritisedLexers) Len() int { return len(l) } -func (l PrioritisedLexers) Swap(i, j int) { l[i], l[j] = l[j], l[i] } -func (l PrioritisedLexers) Less(i, j int) bool { - ip := l[i].Config().Priority - if ip == 0 { - ip = 1 - } - jp := l[j].Config().Priority - if jp == 0 { - jp = 1 - } - return ip > jp -} - -// Analyser determines how appropriate this lexer is for the given text. -type Analyser interface { - AnalyseText(text string) float32 -} diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/README.md b/vendor/github.com/alecthomas/chroma/v2/lexers/README.md deleted file mode 100644 index 60a0055ad8..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/README.md +++ /dev/null @@ -1,46 +0,0 @@ -# Chroma lexers - -All lexers in Chroma should now be defined in XML unless they require custom code. - -## Lexer tests - -The tests in this directory feed a known input `testdata/.actual` into the parser for `` and check -that its output matches `.expected`. - -It is also possible to perform several tests on a same parser ``, by placing know inputs `*.actual` into a -directory `testdata//`. - -### Running the tests - -Run the tests as normal: -```go -go test ./lexers -``` - -### Update existing tests - -When you add a new test data file (`*.actual`), you need to regenerate all tests. That's how Chroma creates the `*.expected` test file based on the corresponding lexer. - -To regenerate all tests, type in your terminal: - -```go -RECORD=true go test ./lexers -``` - -This first sets the `RECORD` environment variable to `true`. Then it runs `go test` on the `./lexers` directory of the Chroma project. - -(That environment variable tells Chroma it needs to output test data. After running `go test ./lexers` you can remove or reset that variable.) - -#### Windows users - -Windows users will find that the `RECORD=true go test ./lexers` command fails in both the standard command prompt terminal and in PowerShell. - -Instead we have to perform both steps separately: - -- Set the `RECORD` environment variable to `true`. - + In the regular command prompt window, the `set` command sets an environment variable for the current session: `set RECORD=true`. See [this page](https://superuser.com/questions/212150/how-to-set-env-variable-in-windows-cmd-line) for more. - + In PowerShell, you can use the `$env:RECORD = 'true'` command for that. See [this article](https://mcpmag.com/articles/2019/03/28/environment-variables-in-powershell.aspx) for more. - + You can also make a persistent environment variable by hand in the Windows computer settings. See [this article](https://www.computerhope.com/issues/ch000549.htm) for how. -- When the environment variable is set, run `go test ./lexers`. - -Chroma will now regenerate the test files and print its results to the console window. diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/caddyfile.go b/vendor/github.com/alecthomas/chroma/v2/lexers/caddyfile.go deleted file mode 100644 index 82a7efa487..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/caddyfile.go +++ /dev/null @@ -1,275 +0,0 @@ -package lexers - -import ( - . "github.com/alecthomas/chroma/v2" // nolint -) - -// Matcher token stub for docs, or -// Named matcher: @name, or -// Path matcher: /foo, or -// Wildcard path matcher: * -// nolint: gosec -var caddyfileMatcherTokenRegexp = `(\[\\]|@[^\s]+|/[^\s]+|\*)` - -// Comment at start of line, or -// Comment preceded by whitespace -var caddyfileCommentRegexp = `(^|\s+)#.*\n` - -// caddyfileCommon are the rules common to both of the lexer variants -func caddyfileCommonRules() Rules { - return Rules{ - "site_block_common": { - Include("site_body"), - // Any other directive - {`[^\s#]+`, Keyword, Push("directive")}, - Include("base"), - }, - "site_body": { - // Import keyword - {`\b(import|invoke)\b( [^\s#]+)`, ByGroups(Keyword, Text), Push("subdirective")}, - // Matcher definition - {`@[^\s]+(?=\s)`, NameDecorator, Push("matcher")}, - // Matcher token stub for docs - {`\[\\]`, NameDecorator, Push("matcher")}, - // These cannot have matchers but may have things that look like - // matchers in their arguments, so we just parse as a subdirective. - {`\b(try_files|tls|log|bind)\b`, Keyword, Push("subdirective")}, - // These are special, they can nest more directives - {`\b(handle_errors|handle_path|handle_response|replace_status|handle|route)\b`, Keyword, Push("nested_directive")}, - // uri directive has special syntax - {`\b(uri)\b`, Keyword, Push("uri_directive")}, - }, - "matcher": { - {`\{`, Punctuation, Push("block")}, - // Not can be one-liner - {`not`, Keyword, Push("deep_not_matcher")}, - // Heredoc for CEL expression - Include("heredoc"), - // Backtick for CEL expression - {"`", StringBacktick, Push("backticks")}, - // Any other same-line matcher - {`[^\s#]+`, Keyword, Push("arguments")}, - // Terminators - {`\s*\n`, Text, Pop(1)}, - {`\}`, Punctuation, Pop(1)}, - Include("base"), - }, - "block": { - {`\}`, Punctuation, Pop(2)}, - // Using double quotes doesn't stop at spaces - {`"`, StringDouble, Push("double_quotes")}, - // Using backticks doesn't stop at spaces - {"`", StringBacktick, Push("backticks")}, - // Not can be one-liner - {`not`, Keyword, Push("not_matcher")}, - // Directives & matcher definitions - Include("site_body"), - // Any directive - {`[^\s#]+`, Keyword, Push("subdirective")}, - Include("base"), - }, - "nested_block": { - {`\}`, Punctuation, Pop(2)}, - // Using double quotes doesn't stop at spaces - {`"`, StringDouble, Push("double_quotes")}, - // Using backticks doesn't stop at spaces - {"`", StringBacktick, Push("backticks")}, - // Not can be one-liner - {`not`, Keyword, Push("not_matcher")}, - // Directives & matcher definitions - Include("site_body"), - // Any other subdirective - {`[^\s#]+`, Keyword, Push("directive")}, - Include("base"), - }, - "not_matcher": { - {`\}`, Punctuation, Pop(2)}, - {`\{(?=\s)`, Punctuation, Push("block")}, - {`[^\s#]+`, Keyword, Push("arguments")}, - {`\s+`, Text, nil}, - }, - "deep_not_matcher": { - {`\}`, Punctuation, Pop(2)}, - {`\{(?=\s)`, Punctuation, Push("block")}, - {`[^\s#]+`, Keyword, Push("deep_subdirective")}, - {`\s+`, Text, nil}, - }, - "directive": { - {`\{(?=\s)`, Punctuation, Push("block")}, - {caddyfileMatcherTokenRegexp, NameDecorator, Push("arguments")}, - {caddyfileCommentRegexp, CommentSingle, Pop(1)}, - {`\s*\n`, Text, Pop(1)}, - Include("base"), - }, - "nested_directive": { - {`\{(?=\s)`, Punctuation, Push("nested_block")}, - {caddyfileMatcherTokenRegexp, NameDecorator, Push("nested_arguments")}, - {caddyfileCommentRegexp, CommentSingle, Pop(1)}, - {`\s*\n`, Text, Pop(1)}, - Include("base"), - }, - "subdirective": { - {`\{(?=\s)`, Punctuation, Push("block")}, - {caddyfileCommentRegexp, CommentSingle, Pop(1)}, - {`\s*\n`, Text, Pop(1)}, - Include("base"), - }, - "arguments": { - {`\{(?=\s)`, Punctuation, Push("block")}, - {caddyfileCommentRegexp, CommentSingle, Pop(2)}, - {`\\\n`, Text, nil}, // Skip escaped newlines - {`\s*\n`, Text, Pop(2)}, - Include("base"), - }, - "nested_arguments": { - {`\{(?=\s)`, Punctuation, Push("nested_block")}, - {caddyfileCommentRegexp, CommentSingle, Pop(2)}, - {`\\\n`, Text, nil}, // Skip escaped newlines - {`\s*\n`, Text, Pop(2)}, - Include("base"), - }, - "deep_subdirective": { - {`\{(?=\s)`, Punctuation, Push("block")}, - {caddyfileCommentRegexp, CommentSingle, Pop(3)}, - {`\s*\n`, Text, Pop(3)}, - Include("base"), - }, - "uri_directive": { - {`\{(?=\s)`, Punctuation, Push("block")}, - {caddyfileMatcherTokenRegexp, NameDecorator, nil}, - {`(strip_prefix|strip_suffix|replace|path_regexp)`, NameConstant, Push("arguments")}, - {caddyfileCommentRegexp, CommentSingle, Pop(1)}, - {`\s*\n`, Text, Pop(1)}, - Include("base"), - }, - "double_quotes": { - Include("placeholder"), - {`\\"`, StringDouble, nil}, - {`[^"]`, StringDouble, nil}, - {`"`, StringDouble, Pop(1)}, - }, - "backticks": { - Include("placeholder"), - {"\\\\`", StringBacktick, nil}, - {"[^`]", StringBacktick, nil}, - {"`", StringBacktick, Pop(1)}, - }, - "optional": { - // Docs syntax for showing optional parts with [ ] - {`\[`, Punctuation, Push("optional")}, - Include("name_constants"), - {`\|`, Punctuation, nil}, - {`[^\[\]\|]+`, String, nil}, - {`\]`, Punctuation, Pop(1)}, - }, - "heredoc": { - {`(<<([a-zA-Z0-9_-]+))(\n(.*|\n)*)(\s*)(\2)`, ByGroups(StringHeredoc, nil, String, String, String, StringHeredoc), nil}, - }, - "name_constants": { - {`\b(most_recently_modified|largest_size|smallest_size|first_exist|internal|disable_redirects|ignore_loaded_certs|disable_certs|private_ranges|first|last|before|after|on|off)\b(\||(?=\]|\s|$))`, ByGroups(NameConstant, Punctuation), nil}, - }, - "placeholder": { - // Placeholder with dots, colon for default value, brackets for args[0:] - {`\{[\w+.\[\]\:\$-]+\}`, StringEscape, nil}, - // Handle opening brackets with no matching closing one - {`\{[^\}\s]*\b`, String, nil}, - }, - "base": { - {caddyfileCommentRegexp, CommentSingle, nil}, - {`\[\\]`, NameDecorator, nil}, - Include("name_constants"), - Include("heredoc"), - {`(https?://)?([a-z0-9.-]+)(:)([0-9]+)([^\s]*)`, ByGroups(Name, Name, Punctuation, NumberInteger, Name), nil}, - {`\[`, Punctuation, Push("optional")}, - {"`", StringBacktick, Push("backticks")}, - {`"`, StringDouble, Push("double_quotes")}, - Include("placeholder"), - {`[a-z-]+/[a-z-+]+`, String, nil}, - {`[0-9]+([smhdk]|ns|us|µs|ms)?\b`, NumberInteger, nil}, - {`[^\s\n#\{]+`, String, nil}, - {`/[^\s#]*`, Name, nil}, - {`\s+`, Text, nil}, - }, - } -} - -// Caddyfile lexer. -var Caddyfile = Register(MustNewLexer( - &Config{ - Name: "Caddyfile", - Aliases: []string{"caddyfile", "caddy"}, - Filenames: []string{"Caddyfile*"}, - MimeTypes: []string{}, - }, - caddyfileRules, -)) - -func caddyfileRules() Rules { - return Rules{ - "root": { - {caddyfileCommentRegexp, CommentSingle, nil}, - // Global options block - {`^\s*(\{)\s*$`, ByGroups(Punctuation), Push("globals")}, - // Top level import - {`(import)(\s+)([^\s]+)`, ByGroups(Keyword, Text, NameVariableMagic), nil}, - // Snippets - {`(&?\([^\s#]+\))(\s*)(\{)`, ByGroups(NameVariableAnonymous, Text, Punctuation), Push("snippet")}, - // Site label - {`[^#{(\s,]+`, GenericHeading, Push("label")}, - // Site label with placeholder - {`\{[\w+.\[\]\:\$-]+\}`, StringEscape, Push("label")}, - {`\s+`, Text, nil}, - }, - "globals": { - {`\}`, Punctuation, Pop(1)}, - // Global options are parsed as subdirectives (no matcher) - {`[^\s#]+`, Keyword, Push("subdirective")}, - Include("base"), - }, - "snippet": { - {`\}`, Punctuation, Pop(1)}, - Include("site_body"), - // Any other directive - {`[^\s#]+`, Keyword, Push("directive")}, - Include("base"), - }, - "label": { - // Allow multiple labels, comma separated, newlines after - // a comma means another label is coming - {`,\s*\n?`, Text, nil}, - {` `, Text, nil}, - // Site label with placeholder - Include("placeholder"), - // Site label - {`[^#{(\s,]+`, GenericHeading, nil}, - // Comment after non-block label (hack because comments end in \n) - {`#.*\n`, CommentSingle, Push("site_block")}, - // Note: if \n, we'll never pop out of the site_block, it's valid - {`\{(?=\s)|\n`, Punctuation, Push("site_block")}, - }, - "site_block": { - {`\}`, Punctuation, Pop(2)}, - Include("site_block_common"), - }, - }.Merge(caddyfileCommonRules()) -} - -// Caddyfile directive-only lexer. -var CaddyfileDirectives = Register(MustNewLexer( - &Config{ - Name: "Caddyfile Directives", - Aliases: []string{"caddyfile-directives", "caddyfile-d", "caddy-d"}, - Filenames: []string{}, - MimeTypes: []string{}, - }, - caddyfileDirectivesRules, -)) - -func caddyfileDirectivesRules() Rules { - return Rules{ - // Same as "site_block" in Caddyfile - "root": { - Include("site_block_common"), - }, - }.Merge(caddyfileCommonRules()) -} diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/cl.go b/vendor/github.com/alecthomas/chroma/v2/lexers/cl.go deleted file mode 100644 index 3eb0c23070..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/cl.go +++ /dev/null @@ -1,243 +0,0 @@ -package lexers - -import ( - . "github.com/alecthomas/chroma/v2" // nolint -) - -var ( - clBuiltinFunctions = []string{ - "<", "<=", "=", ">", ">=", "-", "/", "/=", "*", "+", "1-", "1+", - "abort", "abs", "acons", "acos", "acosh", "add-method", "adjoin", - "adjustable-array-p", "adjust-array", "allocate-instance", - "alpha-char-p", "alphanumericp", "append", "apply", "apropos", - "apropos-list", "aref", "arithmetic-error-operands", - "arithmetic-error-operation", "array-dimension", "array-dimensions", - "array-displacement", "array-element-type", "array-has-fill-pointer-p", - "array-in-bounds-p", "arrayp", "array-rank", "array-row-major-index", - "array-total-size", "ash", "asin", "asinh", "assoc", "assoc-if", - "assoc-if-not", "atan", "atanh", "atom", "bit", "bit-and", "bit-andc1", - "bit-andc2", "bit-eqv", "bit-ior", "bit-nand", "bit-nor", "bit-not", - "bit-orc1", "bit-orc2", "bit-vector-p", "bit-xor", "boole", - "both-case-p", "boundp", "break", "broadcast-stream-streams", - "butlast", "byte", "byte-position", "byte-size", "caaaar", "caaadr", - "caaar", "caadar", "caaddr", "caadr", "caar", "cadaar", "cadadr", - "cadar", "caddar", "cadddr", "caddr", "cadr", "call-next-method", "car", - "cdaaar", "cdaadr", "cdaar", "cdadar", "cdaddr", "cdadr", "cdar", - "cddaar", "cddadr", "cddar", "cdddar", "cddddr", "cdddr", "cddr", "cdr", - "ceiling", "cell-error-name", "cerror", "change-class", "char", "char<", - "char<=", "char=", "char>", "char>=", "char/=", "character", - "characterp", "char-code", "char-downcase", "char-equal", - "char-greaterp", "char-int", "char-lessp", "char-name", - "char-not-equal", "char-not-greaterp", "char-not-lessp", "char-upcase", - "cis", "class-name", "class-of", "clear-input", "clear-output", - "close", "clrhash", "code-char", "coerce", "compile", - "compiled-function-p", "compile-file", "compile-file-pathname", - "compiler-macro-function", "complement", "complex", "complexp", - "compute-applicable-methods", "compute-restarts", "concatenate", - "concatenated-stream-streams", "conjugate", "cons", "consp", - "constantly", "constantp", "continue", "copy-alist", "copy-list", - "copy-pprint-dispatch", "copy-readtable", "copy-seq", "copy-structure", - "copy-symbol", "copy-tree", "cos", "cosh", "count", "count-if", - "count-if-not", "decode-float", "decode-universal-time", "delete", - "delete-duplicates", "delete-file", "delete-if", "delete-if-not", - "delete-package", "denominator", "deposit-field", "describe", - "describe-object", "digit-char", "digit-char-p", "directory", - "directory-namestring", "disassemble", "documentation", "dpb", - "dribble", "echo-stream-input-stream", "echo-stream-output-stream", - "ed", "eighth", "elt", "encode-universal-time", "endp", - "enough-namestring", "ensure-directories-exist", - "ensure-generic-function", "eq", "eql", "equal", "equalp", "error", - "eval", "evenp", "every", "exp", "export", "expt", "fboundp", - "fceiling", "fdefinition", "ffloor", "fifth", "file-author", - "file-error-pathname", "file-length", "file-namestring", - "file-position", "file-string-length", "file-write-date", - "fill", "fill-pointer", "find", "find-all-symbols", "find-class", - "find-if", "find-if-not", "find-method", "find-package", "find-restart", - "find-symbol", "finish-output", "first", "float", "float-digits", - "floatp", "float-precision", "float-radix", "float-sign", "floor", - "fmakunbound", "force-output", "format", "fourth", "fresh-line", - "fround", "ftruncate", "funcall", "function-keywords", - "function-lambda-expression", "functionp", "gcd", "gensym", "gentemp", - "get", "get-decoded-time", "get-dispatch-macro-character", "getf", - "gethash", "get-internal-real-time", "get-internal-run-time", - "get-macro-character", "get-output-stream-string", "get-properties", - "get-setf-expansion", "get-universal-time", "graphic-char-p", - "hash-table-count", "hash-table-p", "hash-table-rehash-size", - "hash-table-rehash-threshold", "hash-table-size", "hash-table-test", - "host-namestring", "identity", "imagpart", "import", - "initialize-instance", "input-stream-p", "inspect", - "integer-decode-float", "integer-length", "integerp", - "interactive-stream-p", "intern", "intersection", - "invalid-method-error", "invoke-debugger", "invoke-restart", - "invoke-restart-interactively", "isqrt", "keywordp", "last", "lcm", - "ldb", "ldb-test", "ldiff", "length", "lisp-implementation-type", - "lisp-implementation-version", "list", "list*", "list-all-packages", - "listen", "list-length", "listp", "load", - "load-logical-pathname-translations", "log", "logand", "logandc1", - "logandc2", "logbitp", "logcount", "logeqv", "logical-pathname", - "logical-pathname-translations", "logior", "lognand", "lognor", - "lognot", "logorc1", "logorc2", "logtest", "logxor", "long-site-name", - "lower-case-p", "machine-instance", "machine-type", "machine-version", - "macroexpand", "macroexpand-1", "macro-function", "make-array", - "make-broadcast-stream", "make-concatenated-stream", "make-condition", - "make-dispatch-macro-character", "make-echo-stream", "make-hash-table", - "make-instance", "make-instances-obsolete", "make-list", - "make-load-form", "make-load-form-saving-slots", "make-package", - "make-pathname", "make-random-state", "make-sequence", "make-string", - "make-string-input-stream", "make-string-output-stream", "make-symbol", - "make-synonym-stream", "make-two-way-stream", "makunbound", "map", - "mapc", "mapcan", "mapcar", "mapcon", "maphash", "map-into", "mapl", - "maplist", "mask-field", "max", "member", "member-if", "member-if-not", - "merge", "merge-pathnames", "method-combination-error", - "method-qualifiers", "min", "minusp", "mismatch", "mod", - "muffle-warning", "name-char", "namestring", "nbutlast", "nconc", - "next-method-p", "nintersection", "ninth", "no-applicable-method", - "no-next-method", "not", "notany", "notevery", "nreconc", "nreverse", - "nset-difference", "nset-exclusive-or", "nstring-capitalize", - "nstring-downcase", "nstring-upcase", "nsublis", "nsubst", "nsubst-if", - "nsubst-if-not", "nsubstitute", "nsubstitute-if", "nsubstitute-if-not", - "nth", "nthcdr", "null", "numberp", "numerator", "nunion", "oddp", - "open", "open-stream-p", "output-stream-p", "package-error-package", - "package-name", "package-nicknames", "packagep", - "package-shadowing-symbols", "package-used-by-list", "package-use-list", - "pairlis", "parse-integer", "parse-namestring", "pathname", - "pathname-device", "pathname-directory", "pathname-host", - "pathname-match-p", "pathname-name", "pathnamep", "pathname-type", - "pathname-version", "peek-char", "phase", "plusp", "position", - "position-if", "position-if-not", "pprint", "pprint-dispatch", - "pprint-fill", "pprint-indent", "pprint-linear", "pprint-newline", - "pprint-tab", "pprint-tabular", "prin1", "prin1-to-string", "princ", - "princ-to-string", "print", "print-object", "probe-file", "proclaim", - "provide", "random", "random-state-p", "rassoc", "rassoc-if", - "rassoc-if-not", "rational", "rationalize", "rationalp", "read", - "read-byte", "read-char", "read-char-no-hang", "read-delimited-list", - "read-from-string", "read-line", "read-preserving-whitespace", - "read-sequence", "readtable-case", "readtablep", "realp", "realpart", - "reduce", "reinitialize-instance", "rem", "remhash", "remove", - "remove-duplicates", "remove-if", "remove-if-not", "remove-method", - "remprop", "rename-file", "rename-package", "replace", "require", - "rest", "restart-name", "revappend", "reverse", "room", "round", - "row-major-aref", "rplaca", "rplacd", "sbit", "scale-float", "schar", - "search", "second", "set", "set-difference", - "set-dispatch-macro-character", "set-exclusive-or", - "set-macro-character", "set-pprint-dispatch", "set-syntax-from-char", - "seventh", "shadow", "shadowing-import", "shared-initialize", - "short-site-name", "signal", "signum", "simple-bit-vector-p", - "simple-condition-format-arguments", "simple-condition-format-control", - "simple-string-p", "simple-vector-p", "sin", "sinh", "sixth", "sleep", - "slot-boundp", "slot-exists-p", "slot-makunbound", "slot-missing", - "slot-unbound", "slot-value", "software-type", "software-version", - "some", "sort", "special-operator-p", "sqrt", "stable-sort", - "standard-char-p", "store-value", "stream-element-type", - "stream-error-stream", "stream-external-format", "streamp", "string", - "string<", "string<=", "string=", "string>", "string>=", "string/=", - "string-capitalize", "string-downcase", "string-equal", - "string-greaterp", "string-left-trim", "string-lessp", - "string-not-equal", "string-not-greaterp", "string-not-lessp", - "stringp", "string-right-trim", "string-trim", "string-upcase", - "sublis", "subseq", "subsetp", "subst", "subst-if", "subst-if-not", - "substitute", "substitute-if", "substitute-if-not", "subtypep", "svref", - "sxhash", "symbol-function", "symbol-name", "symbolp", "symbol-package", - "symbol-plist", "symbol-value", "synonym-stream-symbol", "syntax:", - "tailp", "tan", "tanh", "tenth", "terpri", "third", - "translate-logical-pathname", "translate-pathname", "tree-equal", - "truename", "truncate", "two-way-stream-input-stream", - "two-way-stream-output-stream", "type-error-datum", - "type-error-expected-type", "type-of", "typep", "unbound-slot-instance", - "unexport", "unintern", "union", "unread-char", "unuse-package", - "update-instance-for-different-class", - "update-instance-for-redefined-class", "upgraded-array-element-type", - "upgraded-complex-part-type", "upper-case-p", "use-package", - "user-homedir-pathname", "use-value", "values", "values-list", "vector", - "vectorp", "vector-pop", "vector-push", "vector-push-extend", "warn", - "wild-pathname-p", "write", "write-byte", "write-char", "write-line", - "write-sequence", "write-string", "write-to-string", "yes-or-no-p", - "y-or-n-p", "zerop", - } - - clSpecialForms = []string{ - "block", "catch", "declare", "eval-when", "flet", "function", "go", "if", - "labels", "lambda", "let", "let*", "load-time-value", "locally", "macrolet", - "multiple-value-call", "multiple-value-prog1", "progn", "progv", "quote", - "return-from", "setq", "symbol-macrolet", "tagbody", "the", "throw", - "unwind-protect", - } - - clMacros = []string{ - "and", "assert", "call-method", "case", "ccase", "check-type", "cond", - "ctypecase", "decf", "declaim", "defclass", "defconstant", "defgeneric", - "define-compiler-macro", "define-condition", "define-method-combination", - "define-modify-macro", "define-setf-expander", "define-symbol-macro", - "defmacro", "defmethod", "defpackage", "defparameter", "defsetf", - "defstruct", "deftype", "defun", "defvar", "destructuring-bind", "do", - "do*", "do-all-symbols", "do-external-symbols", "dolist", "do-symbols", - "dotimes", "ecase", "etypecase", "formatter", "handler-bind", - "handler-case", "ignore-errors", "incf", "in-package", "lambda", "loop", - "loop-finish", "make-method", "multiple-value-bind", "multiple-value-list", - "multiple-value-setq", "nth-value", "or", "pop", - "pprint-exit-if-list-exhausted", "pprint-logical-block", "pprint-pop", - "print-unreadable-object", "prog", "prog*", "prog1", "prog2", "psetf", - "psetq", "push", "pushnew", "remf", "restart-bind", "restart-case", - "return", "rotatef", "setf", "shiftf", "step", "time", "trace", "typecase", - "unless", "untrace", "when", "with-accessors", "with-compilation-unit", - "with-condition-restarts", "with-hash-table-iterator", - "with-input-from-string", "with-open-file", "with-open-stream", - "with-output-to-string", "with-package-iterator", "with-simple-restart", - "with-slots", "with-standard-io-syntax", - } - - clLambdaListKeywords = []string{ - "&allow-other-keys", "&aux", "&body", "&environment", "&key", "&optional", - "&rest", "&whole", - } - - clDeclarations = []string{ - "dynamic-extent", "ignore", "optimize", "ftype", "inline", "special", - "ignorable", "notinline", "type", - } - - clBuiltinTypes = []string{ - "atom", "boolean", "base-char", "base-string", "bignum", "bit", - "compiled-function", "extended-char", "fixnum", "keyword", "nil", - "signed-byte", "short-float", "single-float", "double-float", "long-float", - "simple-array", "simple-base-string", "simple-bit-vector", "simple-string", - "simple-vector", "standard-char", "unsigned-byte", - - // Condition Types - "arithmetic-error", "cell-error", "condition", "control-error", - "division-by-zero", "end-of-file", "error", "file-error", - "floating-point-inexact", "floating-point-overflow", - "floating-point-underflow", "floating-point-invalid-operation", - "parse-error", "package-error", "print-not-readable", "program-error", - "reader-error", "serious-condition", "simple-condition", "simple-error", - "simple-type-error", "simple-warning", "stream-error", "storage-condition", - "style-warning", "type-error", "unbound-variable", "unbound-slot", - "undefined-function", "warning", - } - - clBuiltinClasses = []string{ - "array", "broadcast-stream", "bit-vector", "built-in-class", "character", - "class", "complex", "concatenated-stream", "cons", "echo-stream", - "file-stream", "float", "function", "generic-function", "hash-table", - "integer", "list", "logical-pathname", "method-combination", "method", - "null", "number", "package", "pathname", "ratio", "rational", "readtable", - "real", "random-state", "restart", "sequence", "standard-class", - "standard-generic-function", "standard-method", "standard-object", - "string-stream", "stream", "string", "structure-class", "structure-object", - "symbol", "synonym-stream", "t", "two-way-stream", "vector", - } -) - -// Common Lisp lexer. -var CommonLisp = Register(TypeRemappingLexer(MustNewXMLLexer( - embedded, - "embedded/common_lisp.xml", -), TypeMapping{ - {NameVariable, NameFunction, clBuiltinFunctions}, - {NameVariable, Keyword, clSpecialForms}, - {NameVariable, NameBuiltin, clMacros}, - {NameVariable, Keyword, clLambdaListKeywords}, - {NameVariable, Keyword, clDeclarations}, - {NameVariable, KeywordType, clBuiltinTypes}, - {NameVariable, NameClass, clBuiltinClasses}, -})) diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/dns.go b/vendor/github.com/alecthomas/chroma/v2/lexers/dns.go deleted file mode 100644 index 7e699622ac..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/dns.go +++ /dev/null @@ -1,17 +0,0 @@ -package lexers - -import ( - "regexp" -) - -// TODO(moorereason): can this be factored away? -var zoneAnalyserRe = regexp.MustCompile(`(?m)^@\s+IN\s+SOA\s+`) - -func init() { // nolint: gochecknoinits - Get("dns").SetAnalyser(func(text string) float32 { - if zoneAnalyserRe.FindString(text) != "" { - return 1.0 - } - return 0.0 - }) -} diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/emacs.go b/vendor/github.com/alecthomas/chroma/v2/lexers/emacs.go deleted file mode 100644 index 869b0f3f43..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/emacs.go +++ /dev/null @@ -1,533 +0,0 @@ -package lexers - -import ( - . "github.com/alecthomas/chroma/v2" // nolint -) - -var ( - emacsMacros = []string{ - "atomic-change-group", "case", "block", "cl-block", "cl-callf", "cl-callf2", - "cl-case", "cl-decf", "cl-declaim", "cl-declare", - "cl-define-compiler-macro", "cl-defmacro", "cl-defstruct", - "cl-defsubst", "cl-deftype", "cl-defun", "cl-destructuring-bind", - "cl-do", "cl-do*", "cl-do-all-symbols", "cl-do-symbols", "cl-dolist", - "cl-dotimes", "cl-ecase", "cl-etypecase", "eval-when", "cl-eval-when", "cl-flet", - "cl-flet*", "cl-function", "cl-incf", "cl-labels", "cl-letf", - "cl-letf*", "cl-load-time-value", "cl-locally", "cl-loop", - "cl-macrolet", "cl-multiple-value-bind", "cl-multiple-value-setq", - "cl-progv", "cl-psetf", "cl-psetq", "cl-pushnew", "cl-remf", - "cl-return", "cl-return-from", "cl-rotatef", "cl-shiftf", - "cl-symbol-macrolet", "cl-tagbody", "cl-the", "cl-typecase", - "combine-after-change-calls", "condition-case-unless-debug", "decf", - "declaim", "declare", "declare-function", "def-edebug-spec", - "defadvice", "defclass", "defcustom", "defface", "defgeneric", - "defgroup", "define-advice", "define-alternatives", - "define-compiler-macro", "define-derived-mode", "define-generic-mode", - "define-global-minor-mode", "define-globalized-minor-mode", - "define-minor-mode", "define-modify-macro", - "define-obsolete-face-alias", "define-obsolete-function-alias", - "define-obsolete-variable-alias", "define-setf-expander", - "define-skeleton", "defmacro", "defmethod", "defsetf", "defstruct", - "defsubst", "deftheme", "deftype", "defun", "defvar-local", - "delay-mode-hooks", "destructuring-bind", "do", "do*", - "do-all-symbols", "do-symbols", "dolist", "dont-compile", "dotimes", - "dotimes-with-progress-reporter", "ecase", "ert-deftest", "etypecase", - "eval-and-compile", "eval-when-compile", "flet", "ignore-errors", - "incf", "labels", "lambda", "letrec", "lexical-let", "lexical-let*", - "loop", "multiple-value-bind", "multiple-value-setq", "noreturn", - "oref", "oref-default", "oset", "oset-default", "pcase", - "pcase-defmacro", "pcase-dolist", "pcase-exhaustive", "pcase-let", - "pcase-let*", "pop", "psetf", "psetq", "push", "pushnew", "remf", - "return", "rotatef", "rx", "save-match-data", "save-selected-window", - "save-window-excursion", "setf", "setq-local", "shiftf", - "track-mouse", "typecase", "unless", "use-package", "when", - "while-no-input", "with-case-table", "with-category-table", - "with-coding-priority", "with-current-buffer", "with-demoted-errors", - "with-eval-after-load", "with-file-modes", "with-local-quit", - "with-output-to-string", "with-output-to-temp-buffer", - "with-parsed-tramp-file-name", "with-selected-frame", - "with-selected-window", "with-silent-modifications", "with-slots", - "with-syntax-table", "with-temp-buffer", "with-temp-file", - "with-temp-message", "with-timeout", "with-tramp-connection-property", - "with-tramp-file-property", "with-tramp-progress-reporter", - "with-wrapper-hook", "load-time-value", "locally", "macrolet", "progv", - "return-from", - } - - emacsSpecialForms = []string{ - "and", "catch", "cond", "condition-case", "defconst", "defvar", - "function", "if", "interactive", "let", "let*", "or", "prog1", - "prog2", "progn", "quote", "save-current-buffer", "save-excursion", - "save-restriction", "setq", "setq-default", "subr-arity", - "unwind-protect", "while", - } - - emacsBuiltinFunction = []string{ - "%", "*", "+", "-", "/", "/=", "1+", "1-", "<", "<=", "=", ">", ">=", - "Snarf-documentation", "abort-recursive-edit", "abs", - "accept-process-output", "access-file", "accessible-keymaps", "acos", - "active-minibuffer-window", "add-face-text-property", - "add-name-to-file", "add-text-properties", "all-completions", - "append", "apply", "apropos-internal", "aref", "arrayp", "aset", - "ash", "asin", "assoc", "assoc-string", "assq", "atan", "atom", - "autoload", "autoload-do-load", "backtrace", "backtrace--locals", - "backtrace-debug", "backtrace-eval", "backtrace-frame", - "backward-char", "backward-prefix-chars", "barf-if-buffer-read-only", - "base64-decode-region", "base64-decode-string", - "base64-encode-region", "base64-encode-string", "beginning-of-line", - "bidi-find-overridden-directionality", "bidi-resolved-levels", - "bitmap-spec-p", "bobp", "bolp", "bool-vector", - "bool-vector-count-consecutive", "bool-vector-count-population", - "bool-vector-exclusive-or", "bool-vector-intersection", - "bool-vector-not", "bool-vector-p", "bool-vector-set-difference", - "bool-vector-subsetp", "bool-vector-union", "boundp", - "buffer-base-buffer", "buffer-chars-modified-tick", - "buffer-enable-undo", "buffer-file-name", "buffer-has-markers-at", - "buffer-list", "buffer-live-p", "buffer-local-value", - "buffer-local-variables", "buffer-modified-p", "buffer-modified-tick", - "buffer-name", "buffer-size", "buffer-string", "buffer-substring", - "buffer-substring-no-properties", "buffer-swap-text", "bufferp", - "bury-buffer-internal", "byte-code", "byte-code-function-p", - "byte-to-position", "byte-to-string", "byteorder", - "call-interactively", "call-last-kbd-macro", "call-process", - "call-process-region", "cancel-kbd-macro-events", "capitalize", - "capitalize-region", "capitalize-word", "car", "car-less-than-car", - "car-safe", "case-table-p", "category-docstring", - "category-set-mnemonics", "category-table", "category-table-p", - "ccl-execute", "ccl-execute-on-string", "ccl-program-p", "cdr", - "cdr-safe", "ceiling", "char-after", "char-before", - "char-category-set", "char-charset", "char-equal", "char-or-string-p", - "char-resolve-modifiers", "char-syntax", "char-table-extra-slot", - "char-table-p", "char-table-parent", "char-table-range", - "char-table-subtype", "char-to-string", "char-width", "characterp", - "charset-after", "charset-id-internal", "charset-plist", - "charset-priority-list", "charsetp", "check-coding-system", - "check-coding-systems-region", "clear-buffer-auto-save-failure", - "clear-charset-maps", "clear-face-cache", "clear-font-cache", - "clear-image-cache", "clear-string", "clear-this-command-keys", - "close-font", "clrhash", "coding-system-aliases", - "coding-system-base", "coding-system-eol-type", "coding-system-p", - "coding-system-plist", "coding-system-priority-list", - "coding-system-put", "color-distance", "color-gray-p", - "color-supported-p", "combine-after-change-execute", - "command-error-default-function", "command-remapping", "commandp", - "compare-buffer-substrings", "compare-strings", - "compare-window-configurations", "completing-read", - "compose-region-internal", "compose-string-internal", - "composition-get-gstring", "compute-motion", "concat", "cons", - "consp", "constrain-to-field", "continue-process", - "controlling-tty-p", "coordinates-in-window-p", "copy-alist", - "copy-category-table", "copy-file", "copy-hash-table", "copy-keymap", - "copy-marker", "copy-sequence", "copy-syntax-table", "copysign", - "cos", "current-active-maps", "current-bidi-paragraph-direction", - "current-buffer", "current-case-table", "current-column", - "current-global-map", "current-idle-time", "current-indentation", - "current-input-mode", "current-local-map", "current-message", - "current-minor-mode-maps", "current-time", "current-time-string", - "current-time-zone", "current-window-configuration", - "cygwin-convert-file-name-from-windows", - "cygwin-convert-file-name-to-windows", "daemon-initialized", - "daemonp", "dbus--init-bus", "dbus-get-unique-name", - "dbus-message-internal", "debug-timer-check", "declare-equiv-charset", - "decode-big5-char", "decode-char", "decode-coding-region", - "decode-coding-string", "decode-sjis-char", "decode-time", - "default-boundp", "default-file-modes", "default-printer-name", - "default-toplevel-value", "default-value", "define-category", - "define-charset-alias", "define-charset-internal", - "define-coding-system-alias", "define-coding-system-internal", - "define-fringe-bitmap", "define-hash-table-test", "define-key", - "define-prefix-command", "delete", - "delete-all-overlays", "delete-and-extract-region", "delete-char", - "delete-directory-internal", "delete-field", "delete-file", - "delete-frame", "delete-other-windows-internal", "delete-overlay", - "delete-process", "delete-region", "delete-terminal", - "delete-window-internal", "delq", "describe-buffer-bindings", - "describe-vector", "destroy-fringe-bitmap", "detect-coding-region", - "detect-coding-string", "ding", "directory-file-name", - "directory-files", "directory-files-and-attributes", "discard-input", - "display-supports-face-attributes-p", "do-auto-save", "documentation", - "documentation-property", "downcase", "downcase-region", - "downcase-word", "draw-string", "dump-colors", "dump-emacs", - "dump-face", "dump-frame-glyph-matrix", "dump-glyph-matrix", - "dump-glyph-row", "dump-redisplay-history", "dump-tool-bar-row", - "elt", "emacs-pid", "encode-big5-char", "encode-char", - "encode-coding-region", "encode-coding-string", "encode-sjis-char", - "encode-time", "end-kbd-macro", "end-of-line", "eobp", "eolp", "eq", - "eql", "equal", "equal-including-properties", "erase-buffer", - "error-message-string", "eval", "eval-buffer", "eval-region", - "event-convert-list", "execute-kbd-macro", "exit-recursive-edit", - "exp", "expand-file-name", "expt", "external-debugging-output", - "face-attribute-relative-p", "face-attributes-as-vector", "face-font", - "fboundp", "fceiling", "fetch-bytecode", "ffloor", - "field-beginning", "field-end", "field-string", - "field-string-no-properties", "file-accessible-directory-p", - "file-acl", "file-attributes", "file-attributes-lessp", - "file-directory-p", "file-executable-p", "file-exists-p", - "file-locked-p", "file-modes", "file-name-absolute-p", - "file-name-all-completions", "file-name-as-directory", - "file-name-completion", "file-name-directory", - "file-name-nondirectory", "file-newer-than-file-p", "file-readable-p", - "file-regular-p", "file-selinux-context", "file-symlink-p", - "file-system-info", "file-system-info", "file-writable-p", - "fillarray", "find-charset-region", "find-charset-string", - "find-coding-systems-region-internal", "find-composition-internal", - "find-file-name-handler", "find-font", "find-operation-coding-system", - "float", "float-time", "floatp", "floor", "fmakunbound", - "following-char", "font-at", "font-drive-otf", "font-face-attributes", - "font-family-list", "font-get", "font-get-glyphs", - "font-get-system-font", "font-get-system-normal-font", "font-info", - "font-match-p", "font-otf-alternates", "font-put", - "font-shape-gstring", "font-spec", "font-variation-glyphs", - "font-xlfd-name", "fontp", "fontset-font", "fontset-info", - "fontset-list", "fontset-list-all", "force-mode-line-update", - "force-window-update", "format", "format-mode-line", - "format-network-address", "format-time-string", "forward-char", - "forward-comment", "forward-line", "forward-word", - "frame-border-width", "frame-bottom-divider-width", - "frame-can-run-window-configuration-change-hook", "frame-char-height", - "frame-char-width", "frame-face-alist", "frame-first-window", - "frame-focus", "frame-font-cache", "frame-fringe-width", "frame-list", - "frame-live-p", "frame-or-buffer-changed-p", "frame-parameter", - "frame-parameters", "frame-pixel-height", "frame-pixel-width", - "frame-pointer-visible-p", "frame-right-divider-width", - "frame-root-window", "frame-scroll-bar-height", - "frame-scroll-bar-width", "frame-selected-window", "frame-terminal", - "frame-text-cols", "frame-text-height", "frame-text-lines", - "frame-text-width", "frame-total-cols", "frame-total-lines", - "frame-visible-p", "framep", "frexp", "fringe-bitmaps-at-pos", - "fround", "fset", "ftruncate", "funcall", "funcall-interactively", - "function-equal", "functionp", "gap-position", "gap-size", - "garbage-collect", "gc-status", "generate-new-buffer-name", "get", - "get-buffer", "get-buffer-create", "get-buffer-process", - "get-buffer-window", "get-byte", "get-char-property", - "get-char-property-and-overlay", "get-file-buffer", "get-file-char", - "get-internal-run-time", "get-load-suffixes", "get-pos-property", - "get-process", "get-screen-color", "get-text-property", - "get-unicode-property-internal", "get-unused-category", - "get-unused-iso-final-char", "getenv-internal", "gethash", - "gfile-add-watch", "gfile-rm-watch", "global-key-binding", - "gnutls-available-p", "gnutls-boot", "gnutls-bye", "gnutls-deinit", - "gnutls-error-fatalp", "gnutls-error-string", "gnutls-errorp", - "gnutls-get-initstage", "gnutls-peer-status", - "gnutls-peer-status-warning-describe", "goto-char", "gpm-mouse-start", - "gpm-mouse-stop", "group-gid", "group-real-gid", - "handle-save-session", "handle-switch-frame", "hash-table-count", - "hash-table-p", "hash-table-rehash-size", - "hash-table-rehash-threshold", "hash-table-size", "hash-table-test", - "hash-table-weakness", "iconify-frame", "identity", "image-flush", - "image-mask-p", "image-metadata", "image-size", "imagemagick-types", - "imagep", "indent-to", "indirect-function", "indirect-variable", - "init-image-library", "inotify-add-watch", "inotify-rm-watch", - "input-pending-p", "insert", "insert-and-inherit", - "insert-before-markers", "insert-before-markers-and-inherit", - "insert-buffer-substring", "insert-byte", "insert-char", - "insert-file-contents", "insert-startup-screen", "int86", - "integer-or-marker-p", "integerp", "interactive-form", "intern", - "intern-soft", "internal--track-mouse", "internal-char-font", - "internal-complete-buffer", "internal-copy-lisp-face", - "internal-default-process-filter", - "internal-default-process-sentinel", "internal-describe-syntax-value", - "internal-event-symbol-parse-modifiers", - "internal-face-x-get-resource", "internal-get-lisp-face-attribute", - "internal-lisp-face-attribute-values", "internal-lisp-face-empty-p", - "internal-lisp-face-equal-p", "internal-lisp-face-p", - "internal-make-lisp-face", "internal-make-var-non-special", - "internal-merge-in-global-face", - "internal-set-alternative-font-family-alist", - "internal-set-alternative-font-registry-alist", - "internal-set-font-selection-order", - "internal-set-lisp-face-attribute", - "internal-set-lisp-face-attribute-from-resource", - "internal-show-cursor", "internal-show-cursor-p", "interrupt-process", - "invisible-p", "invocation-directory", "invocation-name", "isnan", - "iso-charset", "key-binding", "key-description", - "keyboard-coding-system", "keymap-parent", "keymap-prompt", "keymapp", - "keywordp", "kill-all-local-variables", "kill-buffer", "kill-emacs", - "kill-local-variable", "kill-process", "last-nonminibuffer-frame", - "lax-plist-get", "lax-plist-put", "ldexp", "length", - "libxml-parse-html-region", "libxml-parse-xml-region", - "line-beginning-position", "line-end-position", "line-pixel-height", - "list", "list-fonts", "list-system-processes", "listp", "load", - "load-average", "local-key-binding", "local-variable-if-set-p", - "local-variable-p", "locale-info", "locate-file-internal", - "lock-buffer", "log", "logand", "logb", "logior", "lognot", "logxor", - "looking-at", "lookup-image", "lookup-image-map", "lookup-key", - "lower-frame", "lsh", "macroexpand", "make-bool-vector", - "make-byte-code", "make-category-set", "make-category-table", - "make-char", "make-char-table", "make-directory-internal", - "make-frame-invisible", "make-frame-visible", "make-hash-table", - "make-indirect-buffer", "make-keymap", "make-list", - "make-local-variable", "make-marker", "make-network-process", - "make-overlay", "make-serial-process", "make-sparse-keymap", - "make-string", "make-symbol", "make-symbolic-link", "make-temp-name", - "make-terminal-frame", "make-variable-buffer-local", - "make-variable-frame-local", "make-vector", "makunbound", - "map-char-table", "map-charset-chars", "map-keymap", - "map-keymap-internal", "mapatoms", "mapc", "mapcar", "mapconcat", - "maphash", "mark-marker", "marker-buffer", "marker-insertion-type", - "marker-position", "markerp", "match-beginning", "match-data", - "match-end", "matching-paren", "max", "max-char", "md5", "member", - "memory-info", "memory-limit", "memory-use-counts", "memq", "memql", - "menu-bar-menu-at-x-y", "menu-or-popup-active-p", - "menu-or-popup-active-p", "merge-face-attribute", "message", - "message-box", "message-or-box", "min", - "minibuffer-completion-contents", "minibuffer-contents", - "minibuffer-contents-no-properties", "minibuffer-depth", - "minibuffer-prompt", "minibuffer-prompt-end", - "minibuffer-selected-window", "minibuffer-window", "minibufferp", - "minor-mode-key-binding", "mod", "modify-category-entry", - "modify-frame-parameters", "modify-syntax-entry", - "mouse-pixel-position", "mouse-position", "move-overlay", - "move-point-visually", "move-to-column", "move-to-window-line", - "msdos-downcase-filename", "msdos-long-file-names", "msdos-memget", - "msdos-memput", "msdos-mouse-disable", "msdos-mouse-enable", - "msdos-mouse-init", "msdos-mouse-p", "msdos-remember-default-colors", - "msdos-set-keyboard", "msdos-set-mouse-buttons", - "multibyte-char-to-unibyte", "multibyte-string-p", "narrow-to-region", - "natnump", "nconc", "network-interface-info", - "network-interface-list", "new-fontset", "newline-cache-check", - "next-char-property-change", "next-frame", "next-overlay-change", - "next-property-change", "next-read-file-uses-dialog-p", - "next-single-char-property-change", "next-single-property-change", - "next-window", "nlistp", "nreverse", "nth", "nthcdr", "null", - "number-or-marker-p", "number-to-string", "numberp", - "open-dribble-file", "open-font", "open-termscript", - "optimize-char-table", "other-buffer", "other-window-for-scrolling", - "overlay-buffer", "overlay-end", "overlay-get", "overlay-lists", - "overlay-properties", "overlay-put", "overlay-recenter", - "overlay-start", "overlayp", "overlays-at", "overlays-in", - "parse-partial-sexp", "play-sound-internal", "plist-get", - "plist-member", "plist-put", "point", "point-marker", "point-max", - "point-max-marker", "point-min", "point-min-marker", - "pos-visible-in-window-p", "position-bytes", "posix-looking-at", - "posix-search-backward", "posix-search-forward", "posix-string-match", - "posn-at-point", "posn-at-x-y", "preceding-char", - "prefix-numeric-value", "previous-char-property-change", - "previous-frame", "previous-overlay-change", - "previous-property-change", "previous-single-char-property-change", - "previous-single-property-change", "previous-window", "prin1", - "prin1-to-string", "princ", "print", "process-attributes", - "process-buffer", "process-coding-system", "process-command", - "process-connection", "process-contact", "process-datagram-address", - "process-exit-status", "process-filter", "process-filter-multibyte-p", - "process-id", "process-inherit-coding-system-flag", "process-list", - "process-mark", "process-name", "process-plist", - "process-query-on-exit-flag", "process-running-child-p", - "process-send-eof", "process-send-region", "process-send-string", - "process-sentinel", "process-status", "process-tty-name", - "process-type", "processp", "profiler-cpu-log", - "profiler-cpu-running-p", "profiler-cpu-start", "profiler-cpu-stop", - "profiler-memory-log", "profiler-memory-running-p", - "profiler-memory-start", "profiler-memory-stop", "propertize", - "purecopy", "put", "put-text-property", - "put-unicode-property-internal", "puthash", "query-font", - "query-fontset", "quit-process", "raise-frame", "random", "rassoc", - "rassq", "re-search-backward", "re-search-forward", "read", - "read-buffer", "read-char", "read-char-exclusive", - "read-coding-system", "read-command", "read-event", - "read-from-minibuffer", "read-from-string", "read-function", - "read-key-sequence", "read-key-sequence-vector", - "read-no-blanks-input", "read-non-nil-coding-system", "read-string", - "read-variable", "recent-auto-save-p", "recent-doskeys", - "recent-keys", "recenter", "recursion-depth", "recursive-edit", - "redirect-debugging-output", "redirect-frame-focus", "redisplay", - "redraw-display", "redraw-frame", "regexp-quote", "region-beginning", - "region-end", "register-ccl-program", "register-code-conversion-map", - "remhash", "remove-list-of-text-properties", "remove-text-properties", - "rename-buffer", "rename-file", "replace-match", - "reset-this-command-lengths", "resize-mini-window-internal", - "restore-buffer-modified-p", "resume-tty", "reverse", "round", - "run-hook-with-args", "run-hook-with-args-until-failure", - "run-hook-with-args-until-success", "run-hook-wrapped", "run-hooks", - "run-window-configuration-change-hook", "run-window-scroll-functions", - "safe-length", "scan-lists", "scan-sexps", "scroll-down", - "scroll-left", "scroll-other-window", "scroll-right", "scroll-up", - "search-backward", "search-forward", "secure-hash", "select-frame", - "select-window", "selected-frame", "selected-window", - "self-insert-command", "send-string-to-terminal", "sequencep", - "serial-process-configure", "set", "set-buffer", - "set-buffer-auto-saved", "set-buffer-major-mode", - "set-buffer-modified-p", "set-buffer-multibyte", "set-case-table", - "set-category-table", "set-char-table-extra-slot", - "set-char-table-parent", "set-char-table-range", "set-charset-plist", - "set-charset-priority", "set-coding-system-priority", - "set-cursor-size", "set-default", "set-default-file-modes", - "set-default-toplevel-value", "set-file-acl", "set-file-modes", - "set-file-selinux-context", "set-file-times", "set-fontset-font", - "set-frame-height", "set-frame-position", "set-frame-selected-window", - "set-frame-size", "set-frame-width", "set-fringe-bitmap-face", - "set-input-interrupt-mode", "set-input-meta-mode", "set-input-mode", - "set-keyboard-coding-system-internal", "set-keymap-parent", - "set-marker", "set-marker-insertion-type", "set-match-data", - "set-message-beep", "set-minibuffer-window", - "set-mouse-pixel-position", "set-mouse-position", - "set-network-process-option", "set-output-flow-control", - "set-process-buffer", "set-process-coding-system", - "set-process-datagram-address", "set-process-filter", - "set-process-filter-multibyte", - "set-process-inherit-coding-system-flag", "set-process-plist", - "set-process-query-on-exit-flag", "set-process-sentinel", - "set-process-window-size", "set-quit-char", - "set-safe-terminal-coding-system-internal", "set-screen-color", - "set-standard-case-table", "set-syntax-table", - "set-terminal-coding-system-internal", "set-terminal-local-value", - "set-terminal-parameter", "set-text-properties", "set-time-zone-rule", - "set-visited-file-modtime", "set-window-buffer", - "set-window-combination-limit", "set-window-configuration", - "set-window-dedicated-p", "set-window-display-table", - "set-window-fringes", "set-window-hscroll", "set-window-margins", - "set-window-new-normal", "set-window-new-pixel", - "set-window-new-total", "set-window-next-buffers", - "set-window-parameter", "set-window-point", "set-window-prev-buffers", - "set-window-redisplay-end-trigger", "set-window-scroll-bars", - "set-window-start", "set-window-vscroll", "setcar", "setcdr", - "setplist", "show-face-resources", "signal", "signal-process", "sin", - "single-key-description", "skip-chars-backward", "skip-chars-forward", - "skip-syntax-backward", "skip-syntax-forward", "sleep-for", "sort", - "sort-charsets", "special-variable-p", "split-char", - "split-window-internal", "sqrt", "standard-case-table", - "standard-category-table", "standard-syntax-table", "start-kbd-macro", - "start-process", "stop-process", "store-kbd-macro-event", "string", - "string-as-multibyte", "string-as-unibyte", "string-bytes", - "string-collate-equalp", "string-collate-lessp", "string-equal", - "string-lessp", "string-make-multibyte", "string-make-unibyte", - "string-match", "string-to-char", "string-to-multibyte", - "string-to-number", "string-to-syntax", "string-to-unibyte", - "string-width", "stringp", "subr-name", "subrp", - "subst-char-in-region", "substitute-command-keys", - "substitute-in-file-name", "substring", "substring-no-properties", - "suspend-emacs", "suspend-tty", "suspicious-object", "sxhash", - "symbol-function", "symbol-name", "symbol-plist", "symbol-value", - "symbolp", "syntax-table", "syntax-table-p", "system-groups", - "system-move-file-to-trash", "system-name", "system-users", "tan", - "terminal-coding-system", "terminal-list", "terminal-live-p", - "terminal-local-value", "terminal-name", "terminal-parameter", - "terminal-parameters", "terpri", "test-completion", - "text-char-description", "text-properties-at", "text-property-any", - "text-property-not-all", "this-command-keys", - "this-command-keys-vector", "this-single-command-keys", - "this-single-command-raw-keys", "time-add", "time-less-p", - "time-subtract", "tool-bar-get-system-style", "tool-bar-height", - "tool-bar-pixel-width", "top-level", "trace-redisplay", - "trace-to-stderr", "translate-region-internal", "transpose-regions", - "truncate", "try-completion", "tty-display-color-cells", - "tty-display-color-p", "tty-no-underline", - "tty-suppress-bold-inverse-default-colors", "tty-top-frame", - "tty-type", "type-of", "undo-boundary", "unencodable-char-position", - "unhandled-file-name-directory", "unibyte-char-to-multibyte", - "unibyte-string", "unicode-property-table-internal", "unify-charset", - "unintern", "unix-sync", "unlock-buffer", "upcase", "upcase-initials", - "upcase-initials-region", "upcase-region", "upcase-word", - "use-global-map", "use-local-map", "user-full-name", - "user-login-name", "user-real-login-name", "user-real-uid", - "user-uid", "variable-binding-locus", "vconcat", "vector", - "vector-or-char-table-p", "vectorp", "verify-visited-file-modtime", - "vertical-motion", "visible-frame-list", "visited-file-modtime", - "w16-get-clipboard-data", "w16-selection-exists-p", - "w16-set-clipboard-data", "w32-battery-status", - "w32-default-color-map", "w32-define-rgb-color", - "w32-display-monitor-attributes-list", "w32-frame-menu-bar-size", - "w32-frame-rect", "w32-get-clipboard-data", - "w32-get-codepage-charset", "w32-get-console-codepage", - "w32-get-console-output-codepage", "w32-get-current-locale-id", - "w32-get-default-locale-id", "w32-get-keyboard-layout", - "w32-get-locale-info", "w32-get-valid-codepages", - "w32-get-valid-keyboard-layouts", "w32-get-valid-locale-ids", - "w32-has-winsock", "w32-long-file-name", "w32-reconstruct-hot-key", - "w32-register-hot-key", "w32-registered-hot-keys", - "w32-selection-exists-p", "w32-send-sys-command", - "w32-set-clipboard-data", "w32-set-console-codepage", - "w32-set-console-output-codepage", "w32-set-current-locale", - "w32-set-keyboard-layout", "w32-set-process-priority", - "w32-shell-execute", "w32-short-file-name", "w32-toggle-lock-key", - "w32-unload-winsock", "w32-unregister-hot-key", "w32-window-exists-p", - "w32notify-add-watch", "w32notify-rm-watch", - "waiting-for-user-input-p", "where-is-internal", "widen", - "widget-apply", "widget-get", "widget-put", - "window-absolute-pixel-edges", "window-at", "window-body-height", - "window-body-width", "window-bottom-divider-width", "window-buffer", - "window-combination-limit", "window-configuration-frame", - "window-configuration-p", "window-dedicated-p", - "window-display-table", "window-edges", "window-end", "window-frame", - "window-fringes", "window-header-line-height", "window-hscroll", - "window-inside-absolute-pixel-edges", "window-inside-edges", - "window-inside-pixel-edges", "window-left-child", - "window-left-column", "window-line-height", "window-list", - "window-list-1", "window-live-p", "window-margins", - "window-minibuffer-p", "window-mode-line-height", "window-new-normal", - "window-new-pixel", "window-new-total", "window-next-buffers", - "window-next-sibling", "window-normal-size", "window-old-point", - "window-parameter", "window-parameters", "window-parent", - "window-pixel-edges", "window-pixel-height", "window-pixel-left", - "window-pixel-top", "window-pixel-width", "window-point", - "window-prev-buffers", "window-prev-sibling", - "window-redisplay-end-trigger", "window-resize-apply", - "window-resize-apply-total", "window-right-divider-width", - "window-scroll-bar-height", "window-scroll-bar-width", - "window-scroll-bars", "window-start", "window-system", - "window-text-height", "window-text-pixel-size", "window-text-width", - "window-top-child", "window-top-line", "window-total-height", - "window-total-width", "window-use-time", "window-valid-p", - "window-vscroll", "windowp", "write-char", "write-region", - "x-backspace-delete-keys-p", "x-change-window-property", - "x-change-window-property", "x-close-connection", - "x-close-connection", "x-create-frame", "x-create-frame", - "x-delete-window-property", "x-delete-window-property", - "x-disown-selection-internal", "x-display-backing-store", - "x-display-backing-store", "x-display-color-cells", - "x-display-color-cells", "x-display-grayscale-p", - "x-display-grayscale-p", "x-display-list", "x-display-list", - "x-display-mm-height", "x-display-mm-height", "x-display-mm-width", - "x-display-mm-width", "x-display-monitor-attributes-list", - "x-display-pixel-height", "x-display-pixel-height", - "x-display-pixel-width", "x-display-pixel-width", "x-display-planes", - "x-display-planes", "x-display-save-under", "x-display-save-under", - "x-display-screens", "x-display-screens", "x-display-visual-class", - "x-display-visual-class", "x-family-fonts", "x-file-dialog", - "x-file-dialog", "x-file-dialog", "x-focus-frame", "x-frame-geometry", - "x-frame-geometry", "x-get-atom-name", "x-get-resource", - "x-get-selection-internal", "x-hide-tip", "x-hide-tip", - "x-list-fonts", "x-load-color-file", "x-menu-bar-open-internal", - "x-menu-bar-open-internal", "x-open-connection", "x-open-connection", - "x-own-selection-internal", "x-parse-geometry", "x-popup-dialog", - "x-popup-menu", "x-register-dnd-atom", "x-select-font", - "x-select-font", "x-selection-exists-p", "x-selection-owner-p", - "x-send-client-message", "x-server-max-request-size", - "x-server-max-request-size", "x-server-vendor", "x-server-vendor", - "x-server-version", "x-server-version", "x-show-tip", "x-show-tip", - "x-synchronize", "x-synchronize", "x-uses-old-gtk-dialog", - "x-window-property", "x-window-property", "x-wm-set-size-hint", - "xw-color-defined-p", "xw-color-defined-p", "xw-color-values", - "xw-color-values", "xw-display-color-p", "xw-display-color-p", - "yes-or-no-p", "zlib-available-p", "zlib-decompress-region", - "forward-point", - } - - emacsBuiltinFunctionHighlighted = []string{ - "defvaralias", "provide", "require", - "with-no-warnings", "define-widget", "with-electric-help", - "throw", "defalias", "featurep", - } - - emacsLambdaListKeywords = []string{ - "&allow-other-keys", "&aux", "&body", "&environment", "&key", "&optional", - "&rest", "&whole", - } - - emacsErrorKeywords = []string{ - "cl-assert", "cl-check-type", "error", "signal", - "user-error", "warn", - } -) - -// EmacsLisp lexer. -var EmacsLisp = Register(TypeRemappingLexer(MustNewXMLLexer( - embedded, - "embedded/emacslisp.xml", -), TypeMapping{ - {NameVariable, NameFunction, emacsBuiltinFunction}, - {NameVariable, NameBuiltin, emacsSpecialForms}, - {NameVariable, NameException, emacsErrorKeywords}, - {NameVariable, NameBuiltin, append(emacsBuiltinFunctionHighlighted, emacsMacros...)}, - {NameVariable, KeywordPseudo, emacsLambdaListKeywords}, -})) diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/abap.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/abap.xml deleted file mode 100644 index e8140b738c..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/abap.xml +++ /dev/null @@ -1,154 +0,0 @@ - - - ABAP - abap - *.abap - *.ABAP - text/x-abap - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/abnf.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/abnf.xml deleted file mode 100644 index 3ffd51c6c6..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/abnf.xml +++ /dev/null @@ -1,66 +0,0 @@ - - - ABNF - abnf - *.abnf - text/x-abnf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/actionscript.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/actionscript.xml deleted file mode 100644 index d6727a103b..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/actionscript.xml +++ /dev/null @@ -1,68 +0,0 @@ - - - ActionScript - as - actionscript - *.as - application/x-actionscript - text/x-actionscript - text/actionscript - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/actionscript_3.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/actionscript_3.xml deleted file mode 100644 index e5f653848a..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/actionscript_3.xml +++ /dev/null @@ -1,163 +0,0 @@ - - - ActionScript 3 - as3 - actionscript3 - *.as - application/x-actionscript3 - text/x-actionscript3 - text/actionscript3 - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/ada.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/ada.xml deleted file mode 100644 index 5854a20e9c..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/ada.xml +++ /dev/null @@ -1,321 +0,0 @@ - - - Ada - ada - ada95 - ada2005 - *.adb - *.ads - *.ada - text/x-ada - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/agda.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/agda.xml deleted file mode 100644 index 6f2b2d5088..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/agda.xml +++ /dev/null @@ -1,66 +0,0 @@ - - - Agda - agda - *.agda - text/x-agda - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/al.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/al.xml deleted file mode 100644 index 30bad5ae99..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/al.xml +++ /dev/null @@ -1,75 +0,0 @@ - - - AL - al - *.al - *.dal - text/x-al - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/alloy.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/alloy.xml deleted file mode 100644 index 1de9ea6cc3..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/alloy.xml +++ /dev/null @@ -1,58 +0,0 @@ - - - - Alloy - alloy - *.als - text/x-alloy - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/angular2.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/angular2.xml deleted file mode 100644 index 230ef868c2..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/angular2.xml +++ /dev/null @@ -1,109 +0,0 @@ - - - Angular2 - ng2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/antlr.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/antlr.xml deleted file mode 100644 index e57edd4047..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/antlr.xml +++ /dev/null @@ -1,317 +0,0 @@ - - - ANTLR - antlr - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/apacheconf.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/apacheconf.xml deleted file mode 100644 index 7643541c1b..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/apacheconf.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - ApacheConf - apacheconf - aconf - apache - .htaccess - apache.conf - apache2.conf - text/x-apacheconf - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/apl.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/apl.xml deleted file mode 100644 index 959448ca40..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/apl.xml +++ /dev/null @@ -1,59 +0,0 @@ - - - APL - apl - *.apl - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/applescript.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/applescript.xml deleted file mode 100644 index 5a6224ac00..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/applescript.xml +++ /dev/null @@ -1,151 +0,0 @@ - - - AppleScript - applescript - *.applescript - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/arangodb_aql.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/arangodb_aql.xml deleted file mode 100644 index 434b395a11..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/arangodb_aql.xml +++ /dev/null @@ -1,174 +0,0 @@ - - - ArangoDB AQL - aql - *.aql - text/x-aql - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/arduino.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/arduino.xml deleted file mode 100644 index 6a75df5b9f..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/arduino.xml +++ /dev/null @@ -1,322 +0,0 @@ - - - Arduino - arduino - *.ino - text/x-arduino - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/armasm.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/armasm.xml deleted file mode 100644 index 340278d371..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/armasm.xml +++ /dev/null @@ -1,126 +0,0 @@ - - - ArmAsm - armasm - *.s - *.S - text/x-armasm - text/x-asm - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/atl.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/atl.xml deleted file mode 100644 index 623dc205e7..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/atl.xml +++ /dev/null @@ -1,165 +0,0 @@ - - - ATL - atl - *.atl - text/x-atl - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/autohotkey.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/autohotkey.xml deleted file mode 100644 index 6ec94edeb8..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/autohotkey.xml +++ /dev/null @@ -1,78 +0,0 @@ - - - - AutoHotkey - autohotkey - ahk - *.ahk - *.ahkl - text/x-autohotkey - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/autoit.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/autoit.xml deleted file mode 100644 index 1f7e15df38..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/autoit.xml +++ /dev/null @@ -1,70 +0,0 @@ - - - - AutoIt - autoit - *.au3 - text/x-autoit - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/awk.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/awk.xml deleted file mode 100644 index 07476ff745..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/awk.xml +++ /dev/null @@ -1,95 +0,0 @@ - - - Awk - awk - gawk - mawk - nawk - *.awk - application/x-awk - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/ballerina.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/ballerina.xml deleted file mode 100644 index d13c123191..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/ballerina.xml +++ /dev/null @@ -1,97 +0,0 @@ - - - Ballerina - ballerina - *.bal - text/x-ballerina - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/bash.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/bash.xml deleted file mode 100644 index d704a8ffaa..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/bash.xml +++ /dev/null @@ -1,220 +0,0 @@ - - - Bash - bash - sh - ksh - zsh - shell - *.sh - *.ksh - *.bash - *.ebuild - *.eclass - .env - *.env - *.exheres-0 - *.exlib - *.zsh - *.zshrc - .bashrc - bashrc - .bash_* - bash_* - zshrc - .zshrc - PKGBUILD - application/x-sh - application/x-shellscript - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/bash_session.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/bash_session.xml deleted file mode 100644 index 82c5fd6d0f..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/bash_session.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - Bash Session - bash-session - console - shell-session - *.sh-session - text/x-sh - true - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/batchfile.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/batchfile.xml deleted file mode 100644 index d3e0627280..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/batchfile.xml +++ /dev/null @@ -1,660 +0,0 @@ - - - Batchfile - bat - batch - dosbatch - winbatch - *.bat - *.cmd - application/x-dos-batch - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/beef.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/beef.xml deleted file mode 100644 index 031a220f29..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/beef.xml +++ /dev/null @@ -1,120 +0,0 @@ - - - Beef - beef - *.bf - text/x-beef - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/bibtex.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/bibtex.xml deleted file mode 100644 index 8fde161b36..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/bibtex.xml +++ /dev/null @@ -1,152 +0,0 @@ - - - BibTeX - bib - bibtex - *.bib - text/x-bibtex - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/bicep.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/bicep.xml deleted file mode 100644 index db90f31b30..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/bicep.xml +++ /dev/null @@ -1,84 +0,0 @@ - - - Bicep - bicep - *.bicep - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/blitzbasic.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/blitzbasic.xml deleted file mode 100644 index 591b1ad0f4..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/blitzbasic.xml +++ /dev/null @@ -1,141 +0,0 @@ - - - BlitzBasic - blitzbasic - b3d - bplus - *.bb - *.decls - text/x-bb - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/bnf.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/bnf.xml deleted file mode 100644 index 5c9842477b..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/bnf.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - BNF - bnf - *.bnf - text/x-bnf - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/bqn.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/bqn.xml deleted file mode 100644 index c1090ea5a3..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/bqn.xml +++ /dev/null @@ -1,83 +0,0 @@ - - - BQN - bqn - *.bqn - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/brainfuck.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/brainfuck.xml deleted file mode 100644 index 4c84c33082..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/brainfuck.xml +++ /dev/null @@ -1,51 +0,0 @@ - - - Brainfuck - brainfuck - bf - *.bf - *.b - application/x-brainfuck - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/c#.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/c#.xml deleted file mode 100644 index f1e21db03f..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/c#.xml +++ /dev/null @@ -1,121 +0,0 @@ - - - C# - csharp - c# - *.cs - text/x-csharp - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/c++.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/c++.xml deleted file mode 100644 index 680a19afba..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/c++.xml +++ /dev/null @@ -1,331 +0,0 @@ - - - C++ - cpp - c++ - *.cpp - *.hpp - *.c++ - *.h++ - *.cc - *.hh - *.cxx - *.hxx - *.C - *.H - *.cp - *.CPP - *.tpp - text/x-c++hdr - text/x-c++src - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/c.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/c.xml deleted file mode 100644 index 35ee32dce6..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/c.xml +++ /dev/null @@ -1,260 +0,0 @@ - - - C - c - *.c - *.h - *.idc - *.x[bp]m - text/x-chdr - text/x-csrc - image/x-xbitmap - image/x-xpixmap - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/cap_n_proto.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/cap_n_proto.xml deleted file mode 100644 index 3e7d1470bf..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/cap_n_proto.xml +++ /dev/null @@ -1,122 +0,0 @@ - - - Cap'n Proto - capnp - *.capnp - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/cassandra_cql.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/cassandra_cql.xml deleted file mode 100644 index 1a78f99a14..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/cassandra_cql.xml +++ /dev/null @@ -1,137 +0,0 @@ - - - Cassandra CQL - cassandra - cql - *.cql - text/x-cql - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - 6 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/ceylon.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/ceylon.xml deleted file mode 100644 index 4c4121835b..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/ceylon.xml +++ /dev/null @@ -1,151 +0,0 @@ - - - Ceylon - ceylon - *.ceylon - text/x-ceylon - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/cfengine3.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/cfengine3.xml deleted file mode 100644 index 4950305050..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/cfengine3.xml +++ /dev/null @@ -1,197 +0,0 @@ - - - CFEngine3 - cfengine3 - cf3 - *.cf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/cfstatement.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/cfstatement.xml deleted file mode 100644 index 46a84cf6ab..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/cfstatement.xml +++ /dev/null @@ -1,92 +0,0 @@ - - - cfstatement - cfs - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/chaiscript.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/chaiscript.xml deleted file mode 100644 index 860439aa8a..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/chaiscript.xml +++ /dev/null @@ -1,134 +0,0 @@ - - - ChaiScript - chai - chaiscript - *.chai - text/x-chaiscript - application/x-chaiscript - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/chapel.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/chapel.xml deleted file mode 100644 index c89cafc6ab..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/chapel.xml +++ /dev/null @@ -1,143 +0,0 @@ - - - Chapel - chapel - chpl - *.chpl - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/cheetah.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/cheetah.xml deleted file mode 100644 index 284457c6c6..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/cheetah.xml +++ /dev/null @@ -1,55 +0,0 @@ - - - Cheetah - cheetah - spitfire - *.tmpl - *.spt - application/x-cheetah - application/x-spitfire - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/clojure.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/clojure.xml deleted file mode 100644 index 967ba399cb..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/clojure.xml +++ /dev/null @@ -1,71 +0,0 @@ - - - Clojure - clojure - clj - edn - *.clj - *.edn - text/x-clojure - application/x-clojure - application/edn - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/cmake.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/cmake.xml deleted file mode 100644 index b041cfd016..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/cmake.xml +++ /dev/null @@ -1,90 +0,0 @@ - - - CMake - cmake - *.cmake - CMakeLists.txt - text/x-cmake - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/cobol.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/cobol.xml deleted file mode 100644 index a8a80291d4..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/cobol.xml +++ /dev/null @@ -1,90 +0,0 @@ - - - COBOL - cobol - *.cob - *.COB - *.cpy - *.CPY - text/x-cobol - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/coffeescript.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/coffeescript.xml deleted file mode 100644 index e29722fb83..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/coffeescript.xml +++ /dev/null @@ -1,210 +0,0 @@ - - - CoffeeScript - coffee-script - coffeescript - coffee - *.coffee - text/coffeescript - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/common_lisp.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/common_lisp.xml deleted file mode 100644 index 0fb9a7a4b3..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/common_lisp.xml +++ /dev/null @@ -1,184 +0,0 @@ - - - Common Lisp - common-lisp - cl - lisp - *.cl - *.lisp - text/x-common-lisp - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/coq.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/coq.xml deleted file mode 100644 index 62f64ff992..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/coq.xml +++ /dev/null @@ -1,136 +0,0 @@ - - - Coq - coq - *.v - text/x-coq - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/core.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/core.xml deleted file mode 100644 index c5aa432c9f..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/core.xml +++ /dev/null @@ -1,79 +0,0 @@ - - - Core - core - *.core - text/x-core - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/crystal.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/crystal.xml deleted file mode 100644 index 94853db33f..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/crystal.xml +++ /dev/null @@ -1,762 +0,0 @@ - - - Crystal - cr - crystal - *.cr - text/x-crystal - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/css.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/css.xml deleted file mode 100644 index 5491fe4643..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/css.xml +++ /dev/null @@ -1,323 +0,0 @@ - - - CSS - css - *.css - text/css - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/csv.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/csv.xml deleted file mode 100644 index b70c2f8b1d..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/csv.xml +++ /dev/null @@ -1,53 +0,0 @@ - - - - - CSV - csv - *.csv - text/csv - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/cue.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/cue.xml deleted file mode 100644 index 2a12f39539..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/cue.xml +++ /dev/null @@ -1,85 +0,0 @@ - - - CUE - cue - *.cue - text/x-cue - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/cython.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/cython.xml deleted file mode 100644 index 15dfe4d4f2..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/cython.xml +++ /dev/null @@ -1,372 +0,0 @@ - - - Cython - cython - pyx - pyrex - *.pyx - *.pxd - *.pxi - text/x-cython - application/x-cython - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/d.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/d.xml deleted file mode 100644 index 3c030e2272..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/d.xml +++ /dev/null @@ -1,133 +0,0 @@ - - - D - d - *.d - *.di - text/x-d - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/dart.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/dart.xml deleted file mode 100644 index f1b454fafc..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/dart.xml +++ /dev/null @@ -1,213 +0,0 @@ - - - Dart - dart - *.dart - text/x-dart - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/dax.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/dax.xml deleted file mode 100644 index 2bb3a1aa7f..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/dax.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - Dax - dax - *.dax - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/desktop_entry.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/desktop_entry.xml deleted file mode 100644 index ad71ad4715..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/desktop_entry.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - Desktop file - desktop - desktop_entry - *.desktop - application/x-desktop - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/diff.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/diff.xml deleted file mode 100644 index dc0beb7fdf..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/diff.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - Diff - diff - udiff - *.diff - *.patch - text/x-diff - text/x-patch - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/django_jinja.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/django_jinja.xml deleted file mode 100644 index 3c97c222ea..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/django_jinja.xml +++ /dev/null @@ -1,153 +0,0 @@ - - - Django/Jinja - django - jinja - application/x-django-templating - application/x-jinja - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/dns.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/dns.xml deleted file mode 100644 index ef8f663f96..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/dns.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - - dns - zone - bind - *.zone - text/dns - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/docker.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/docker.xml deleted file mode 100644 index 261834f425..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/docker.xml +++ /dev/null @@ -1,68 +0,0 @@ - - - Docker - docker - dockerfile - containerfile - Dockerfile - Dockerfile.* - *.Dockerfile - *.docker - Containerfile - Containerfile.* - *.Containerfile - text/x-dockerfile-config - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/dtd.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/dtd.xml deleted file mode 100644 index 0edbbdeace..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/dtd.xml +++ /dev/null @@ -1,168 +0,0 @@ - - - DTD - dtd - *.dtd - application/xml-dtd - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/dylan.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/dylan.xml deleted file mode 100644 index 3660d14404..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/dylan.xml +++ /dev/null @@ -1,176 +0,0 @@ - - - Dylan - dylan - *.dylan - *.dyl - *.intr - text/x-dylan - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/ebnf.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/ebnf.xml deleted file mode 100644 index df5d62ffa6..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/ebnf.xml +++ /dev/null @@ -1,90 +0,0 @@ - - - EBNF - ebnf - *.ebnf - text/x-ebnf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/elixir.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/elixir.xml deleted file mode 100644 index 286f53a241..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/elixir.xml +++ /dev/null @@ -1,744 +0,0 @@ - - - Elixir - elixir - ex - exs - *.ex - *.eex - *.exs - text/x-elixir - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/elm.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/elm.xml deleted file mode 100644 index ed65efc638..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/elm.xml +++ /dev/null @@ -1,119 +0,0 @@ - - - Elm - elm - *.elm - text/x-elm - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/emacslisp.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/emacslisp.xml deleted file mode 100644 index 668bc621ea..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/emacslisp.xml +++ /dev/null @@ -1,132 +0,0 @@ - - - EmacsLisp - emacs - elisp - emacs-lisp - *.el - text/x-elisp - application/x-elisp - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/erlang.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/erlang.xml deleted file mode 100644 index b186588682..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/erlang.xml +++ /dev/null @@ -1,166 +0,0 @@ - - - Erlang - erlang - *.erl - *.hrl - *.es - *.escript - text/x-erlang - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/factor.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/factor.xml deleted file mode 100644 index 4743b9a2e8..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/factor.xml +++ /dev/null @@ -1,412 +0,0 @@ - - - Factor - factor - *.factor - text/x-factor - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/fennel.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/fennel.xml deleted file mode 100644 index b9b6d59506..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/fennel.xml +++ /dev/null @@ -1,68 +0,0 @@ - - - Fennel - fennel - fnl - *.fennel - text/x-fennel - application/x-fennel - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/fish.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/fish.xml deleted file mode 100644 index deb78145e3..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/fish.xml +++ /dev/null @@ -1,159 +0,0 @@ - - - Fish - fish - fishshell - *.fish - *.load - application/x-fish - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/forth.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/forth.xml deleted file mode 100644 index 31096a225d..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/forth.xml +++ /dev/null @@ -1,78 +0,0 @@ - - - Forth - forth - *.frt - *.fth - *.fs - application/x-forth - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/fortran.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/fortran.xml deleted file mode 100644 index 6140e70414..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/fortran.xml +++ /dev/null @@ -1,102 +0,0 @@ - - - Fortran - fortran - f90 - *.f03 - *.f90 - *.f95 - *.F03 - *.F90 - *.F95 - text/x-fortran - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/fortranfixed.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/fortranfixed.xml deleted file mode 100644 index 11343c0e73..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/fortranfixed.xml +++ /dev/null @@ -1,71 +0,0 @@ - - - FortranFixed - fortranfixed - *.f - *.F - text/x-fortran - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/fsharp.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/fsharp.xml deleted file mode 100644 index e1c19ffb45..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/fsharp.xml +++ /dev/null @@ -1,245 +0,0 @@ - - - FSharp - fsharp - *.fs - *.fsi - text/x-fsharp - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/gas.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/gas.xml deleted file mode 100644 index 7557bce0f2..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/gas.xml +++ /dev/null @@ -1,150 +0,0 @@ - - - GAS - gas - asm - *.s - *.S - text/x-gas - 0.1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/gdscript.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/gdscript.xml deleted file mode 100644 index 811f38d028..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/gdscript.xml +++ /dev/null @@ -1,259 +0,0 @@ - - - GDScript - gdscript - gd - *.gd - text/x-gdscript - application/x-gdscript - 0.1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/gdscript3.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/gdscript3.xml deleted file mode 100644 index b50c9dd7b6..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/gdscript3.xml +++ /dev/null @@ -1,270 +0,0 @@ - - - GDScript3 - gdscript3 - gd3 - *.gd - text/x-gdscript - application/x-gdscript - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/gherkin.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/gherkin.xml deleted file mode 100644 index c53a2cbb5b..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/gherkin.xml +++ /dev/null @@ -1,263 +0,0 @@ - - - Gherkin - cucumber - Cucumber - gherkin - Gherkin - *.feature - *.FEATURE - text/x-gherkin - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/gleam.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/gleam.xml deleted file mode 100644 index 3966322039..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/gleam.xml +++ /dev/null @@ -1,100 +0,0 @@ - - - Gleam - gleam - *.gleam - text/x-gleam - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/glsl.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/glsl.xml deleted file mode 100644 index ca0b696de6..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/glsl.xml +++ /dev/null @@ -1,65 +0,0 @@ - - - GLSL - glsl - *.vert - *.frag - *.geo - text/x-glslsrc - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/gnuplot.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/gnuplot.xml deleted file mode 100644 index ee6a245f38..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/gnuplot.xml +++ /dev/null @@ -1,289 +0,0 @@ - - - Gnuplot - gnuplot - *.plot - *.plt - text/x-gnuplot - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/go_template.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/go_template.xml deleted file mode 100644 index 36f737b93f..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/go_template.xml +++ /dev/null @@ -1,114 +0,0 @@ - - - Go Template - go-template - *.gotmpl - *.go.tmpl - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/graphql.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/graphql.xml deleted file mode 100644 index b06227357d..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/graphql.xml +++ /dev/null @@ -1,88 +0,0 @@ - - - GraphQL - graphql - graphqls - gql - *.graphql - *.graphqls - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/groff.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/groff.xml deleted file mode 100644 index 3af0a43e7a..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/groff.xml +++ /dev/null @@ -1,90 +0,0 @@ - - - Groff - groff - nroff - man - *.[1-9] - *.1p - *.3pm - *.man - application/x-troff - text/troff - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/groovy.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/groovy.xml deleted file mode 100644 index 3cca2e9a5b..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/groovy.xml +++ /dev/null @@ -1,135 +0,0 @@ - - - Groovy - groovy - *.groovy - *.gradle - text/x-groovy - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/handlebars.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/handlebars.xml deleted file mode 100644 index 7cf2a648a9..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/handlebars.xml +++ /dev/null @@ -1,147 +0,0 @@ - - - Handlebars - handlebars - hbs - *.handlebars - *.hbs - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/hare.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/hare.xml deleted file mode 100644 index c1f7e9433c..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/hare.xml +++ /dev/null @@ -1,98 +0,0 @@ - - - Hare - hare - *.ha - text/x-hare - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/haskell.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/haskell.xml deleted file mode 100644 index 1fad082316..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/haskell.xml +++ /dev/null @@ -1,275 +0,0 @@ - - - Haskell - haskell - hs - *.hs - text/x-haskell - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/hcl.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/hcl.xml deleted file mode 100644 index d3ed208af9..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/hcl.xml +++ /dev/null @@ -1,143 +0,0 @@ - - - HCL - hcl - *.hcl - application/x-hcl - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/hexdump.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/hexdump.xml deleted file mode 100644 index a6f28eab1a..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/hexdump.xml +++ /dev/null @@ -1,189 +0,0 @@ - - - Hexdump - hexdump - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/hlb.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/hlb.xml deleted file mode 100644 index 9723fd9c23..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/hlb.xml +++ /dev/null @@ -1,131 +0,0 @@ - - - HLB - hlb - *.hlb - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/hlsl.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/hlsl.xml deleted file mode 100644 index 41ab32395b..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/hlsl.xml +++ /dev/null @@ -1,110 +0,0 @@ - - - HLSL - hlsl - *.hlsl - *.hlsli - *.cginc - *.fx - *.fxh - text/x-hlsl - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/holyc.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/holyc.xml deleted file mode 100644 index cd2d9d16b2..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/holyc.xml +++ /dev/null @@ -1,252 +0,0 @@ - - - HolyC - holyc - *.HC - *.hc - *.HH - *.hh - *.hc.z - *.HC.Z - text/x-chdr - text/x-csrc - image/x-xbitmap - image/x-xpixmap - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/html.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/html.xml deleted file mode 100644 index 2f1a8a9790..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/html.xml +++ /dev/null @@ -1,159 +0,0 @@ - - - HTML - html - *.html - *.htm - *.xhtml - *.xslt - text/html - application/xhtml+xml - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/hy.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/hy.xml deleted file mode 100644 index a0dae46aec..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/hy.xml +++ /dev/null @@ -1,104 +0,0 @@ - - - Hy - hylang - *.hy - text/x-hy - application/x-hy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/idris.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/idris.xml deleted file mode 100644 index 9592d88228..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/idris.xml +++ /dev/null @@ -1,216 +0,0 @@ - - - Idris - idris - idr - *.idr - text/x-idris - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/igor.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/igor.xml deleted file mode 100644 index 1cc0205705..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/igor.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - Igor - igor - igorpro - *.ipf - text/ipf - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/ini.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/ini.xml deleted file mode 100644 index 08f3870be2..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/ini.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - INI - ini - cfg - dosini - *.ini - *.cfg - *.inf - *.service - *.socket - .gitconfig - .editorconfig - pylintrc - .pylintrc - text/x-ini - text/inf - 0.1 - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/io.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/io.xml deleted file mode 100644 index 9ad94fa52a..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/io.xml +++ /dev/null @@ -1,71 +0,0 @@ - - - Io - io - *.io - text/x-iosrc - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/iscdhcpd.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/iscdhcpd.xml deleted file mode 100644 index 645cb05d50..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/iscdhcpd.xml +++ /dev/null @@ -1,96 +0,0 @@ - - - ISCdhcpd - iscdhcpd - dhcpd.conf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/j.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/j.xml deleted file mode 100644 index 872d08122b..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/j.xml +++ /dev/null @@ -1,157 +0,0 @@ - - - J - j - *.ijs - text/x-j - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/janet.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/janet.xml deleted file mode 100644 index fe139e8567..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/janet.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - Janet - janet - *.janet - *.jdn - text/x-janet - application/x-janet - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/java.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/java.xml deleted file mode 100644 index 3ce33ff6dc..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/java.xml +++ /dev/null @@ -1,193 +0,0 @@ - - - Java - java - *.java - text/x-java - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/javascript.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/javascript.xml deleted file mode 100644 index efe80ed375..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/javascript.xml +++ /dev/null @@ -1,160 +0,0 @@ - - - JavaScript - js - javascript - *.js - *.jsm - *.mjs - *.cjs - application/javascript - application/x-javascript - text/x-javascript - text/javascript - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/json.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/json.xml deleted file mode 100644 index a34abfa498..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/json.xml +++ /dev/null @@ -1,112 +0,0 @@ - - - JSON - json - *.json - *.jsonc - *.avsc - application/json - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/jsonata.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/jsonata.xml deleted file mode 100644 index c0eafabe34..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/jsonata.xml +++ /dev/null @@ -1,83 +0,0 @@ - - - JSONata - jsonata - *.jsonata - true - - - - - - - - - - // Spread operator - - - // Sort operator - - - // Descendant | Wildcard | Multiplication - - - // Division - - - // Comparison operators - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/jsonnet.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/jsonnet.xml deleted file mode 100644 index 1633a5e403..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/jsonnet.xml +++ /dev/null @@ -1,138 +0,0 @@ - - - - Jsonnet - jsonnet - *.jsonnet - *.libsonnet - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/julia.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/julia.xml deleted file mode 100644 index 776dcdbcbb..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/julia.xml +++ /dev/null @@ -1,400 +0,0 @@ - - - Julia - julia - jl - *.jl - text/x-julia - application/x-julia - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/jungle.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/jungle.xml deleted file mode 100644 index 92c785d0c3..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/jungle.xml +++ /dev/null @@ -1,98 +0,0 @@ - - - Jungle - jungle - *.jungle - text/x-jungle - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/kotlin.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/kotlin.xml deleted file mode 100644 index ec02c4ef14..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/kotlin.xml +++ /dev/null @@ -1,224 +0,0 @@ - - - Kotlin - kotlin - *.kt - *.kts - text/x-kotlin - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/lean.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/lean.xml deleted file mode 100644 index 6ac5151bbc..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/lean.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - Lean4 - lean4 - lean - *.lean - text/x-lean4 - text/x-lean - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/lighttpd_configuration_file.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/lighttpd_configuration_file.xml deleted file mode 100644 index 1319e5c838..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/lighttpd_configuration_file.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - Lighttpd configuration file - lighty - lighttpd - text/x-lighttpd-conf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/llvm.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/llvm.xml deleted file mode 100644 index f24f1522b2..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/llvm.xml +++ /dev/null @@ -1,73 +0,0 @@ - - - LLVM - llvm - *.ll - text/x-llvm - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/lox.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/lox.xml deleted file mode 100644 index 602885a205..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/lox.xml +++ /dev/null @@ -1,83 +0,0 @@ - - - lox - *.lox - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/lua.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/lua.xml deleted file mode 100644 index e3d778f12a..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/lua.xml +++ /dev/null @@ -1,160 +0,0 @@ - - - Lua - lua - luau - *.lua - *.wlua - *.luau - text/x-lua - application/x-lua - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/makefile.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/makefile.xml deleted file mode 100644 index a82a7f8d56..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/makefile.xml +++ /dev/null @@ -1,131 +0,0 @@ - - - Makefile - make - makefile - mf - bsdmake - *.mak - *.mk - Makefile - makefile - Makefile.* - GNUmakefile - BSDmakefile - Justfile - justfile - .justfile - text/x-makefile - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/mako.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/mako.xml deleted file mode 100644 index 782414087b..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/mako.xml +++ /dev/null @@ -1,120 +0,0 @@ - - - Mako - mako - *.mao - application/x-mako - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/mason.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/mason.xml deleted file mode 100644 index 5873f2afc5..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/mason.xml +++ /dev/null @@ -1,89 +0,0 @@ - - - Mason - mason - *.m - *.mhtml - *.mc - *.mi - autohandler - dhandler - application/x-mason - 0.1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/materialize_sql_dialect.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/materialize_sql_dialect.xml deleted file mode 100644 index 7094ddc3ee..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/materialize_sql_dialect.xml +++ /dev/null @@ -1,155 +0,0 @@ - - - Materialize SQL dialect - text/x-materializesql - true - true - materialize - mzsql - - - - - - - - - - - - - - - - - - - 6 - 12 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 12 - 4 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/mathematica.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/mathematica.xml deleted file mode 100644 index 0b8dfb617f..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/mathematica.xml +++ /dev/null @@ -1,60 +0,0 @@ - - - Mathematica - mathematica - mma - nb - *.cdf - *.m - *.ma - *.mt - *.mx - *.nb - *.nbp - *.wl - application/mathematica - application/vnd.wolfram.mathematica - application/vnd.wolfram.mathematica.package - application/vnd.wolfram.cdf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/matlab.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/matlab.xml deleted file mode 100644 index ebb4e2c331..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/matlab.xml +++ /dev/null @@ -1,114 +0,0 @@ - - - Matlab - matlab - *.m - text/matlab - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/mcfunction.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/mcfunction.xml deleted file mode 100644 index a6aa6dbe8c..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/mcfunction.xml +++ /dev/null @@ -1,138 +0,0 @@ - - - - MCFunction - mcfunction - mcf - *.mcfunction - text/mcfunction - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/meson.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/meson.xml deleted file mode 100644 index 130047df6a..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/meson.xml +++ /dev/null @@ -1,85 +0,0 @@ - - - Meson - meson - meson.build - meson.build - meson_options.txt - text/x-meson - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/metal.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/metal.xml deleted file mode 100644 index 62d04ba842..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/metal.xml +++ /dev/null @@ -1,270 +0,0 @@ - - - Metal - metal - *.metal - text/x-metal - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/minizinc.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/minizinc.xml deleted file mode 100644 index 1ad6860f4d..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/minizinc.xml +++ /dev/null @@ -1,82 +0,0 @@ - - - MiniZinc - minizinc - MZN - mzn - *.mzn - *.dzn - *.fzn - text/minizinc - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/mlir.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/mlir.xml deleted file mode 100644 index 025c3dc56b..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/mlir.xml +++ /dev/null @@ -1,73 +0,0 @@ - - - MLIR - mlir - *.mlir - text/x-mlir - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/modula-2.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/modula-2.xml deleted file mode 100644 index 0bf37bcc3c..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/modula-2.xml +++ /dev/null @@ -1,245 +0,0 @@ - - - Modula-2 - modula2 - m2 - *.def - *.mod - text/x-modula2 - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/mojo.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/mojo.xml deleted file mode 100644 index 677811eb1c..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/mojo.xml +++ /dev/null @@ -1,228 +0,0 @@ - - - Mojo - mojo - 🔥 - *.mojo - *.🔥 - text/x-mojo - application/x-mojo - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/monkeyc.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/monkeyc.xml deleted file mode 100644 index 7445a639d3..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/monkeyc.xml +++ /dev/null @@ -1,153 +0,0 @@ - - - MonkeyC - monkeyc - *.mc - text/x-monkeyc - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/moonscript.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/moonscript.xml deleted file mode 100644 index 293f538cdb..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/moonscript.xml +++ /dev/null @@ -1,83 +0,0 @@ - - - - MoonScript - moonscript - moon - *.moon - text/x-moonscript - application/x-moonscript - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/morrowindscript.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/morrowindscript.xml deleted file mode 100644 index 724a19fc62..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/morrowindscript.xml +++ /dev/null @@ -1,90 +0,0 @@ - - - MorrowindScript - morrowind - mwscript - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/myghty.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/myghty.xml deleted file mode 100644 index 6d03917e52..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/myghty.xml +++ /dev/null @@ -1,77 +0,0 @@ - - - Myghty - myghty - *.myt - autodelegate - application/x-myghty - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/mysql.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/mysql.xml deleted file mode 100644 index b6c2046d5e..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/mysql.xml +++ /dev/null @@ -1,121 +0,0 @@ - - - MySQL - mysql - mariadb - *.sql - text/x-mysql - text/x-mariadb - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/nasm.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/nasm.xml deleted file mode 100644 index defe65b3c4..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/nasm.xml +++ /dev/null @@ -1,126 +0,0 @@ - - - NASM - nasm - *.asm - *.ASM - *.nasm - text/x-nasm - true - 1.0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/natural.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/natural.xml deleted file mode 100644 index 707252b4c1..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/natural.xml +++ /dev/null @@ -1,143 +0,0 @@ - - - Natural - natural - *.NSN - *.NSP - *.NSS - *.NSH - *.NSG - *.NSL - *.NSA - *.NSM - *.NSC - *.NS7 - text/x-natural - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/ndisasm.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/ndisasm.xml deleted file mode 100644 index 74d443b649..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/ndisasm.xml +++ /dev/null @@ -1,123 +0,0 @@ - - - NDISASM - ndisasm - text/x-disasm - true - 0.5 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/newspeak.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/newspeak.xml deleted file mode 100644 index b93265706b..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/newspeak.xml +++ /dev/null @@ -1,121 +0,0 @@ - - - Newspeak - newspeak - *.ns2 - text/x-newspeak - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/nginx_configuration_file.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/nginx_configuration_file.xml deleted file mode 100644 index a80d049931..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/nginx_configuration_file.xml +++ /dev/null @@ -1,101 +0,0 @@ - - - Nginx configuration file - nginx - nginx.conf - text/x-nginx-conf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/nim.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/nim.xml deleted file mode 100644 index bfdd6156ab..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/nim.xml +++ /dev/null @@ -1,211 +0,0 @@ - - - Nim - nim - nimrod - *.nim - *.nimrod - text/x-nim - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/nix.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/nix.xml deleted file mode 100644 index dd54d36fd5..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/nix.xml +++ /dev/null @@ -1,258 +0,0 @@ - - - Nix - nixos - nix - *.nix - text/x-nix - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/nsis.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/nsis.xml deleted file mode 100644 index 6c3a7be966..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/nsis.xml +++ /dev/null @@ -1,59 +0,0 @@ - - - NSIS - nsis - nsi - nsh - *.nsi - *.nsh - text/x-nsis - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/nu.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/nu.xml deleted file mode 100644 index 326558086c..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/nu.xml +++ /dev/null @@ -1,121 +0,0 @@ - - - Nu - nu - *.nu - text/plain - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/objective-c.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/objective-c.xml deleted file mode 100644 index 0dc932857c..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/objective-c.xml +++ /dev/null @@ -1,510 +0,0 @@ - - - Objective-C - objective-c - objectivec - obj-c - objc - *.m - *.h - text/x-objective-c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/objectpascal.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/objectpascal.xml deleted file mode 100644 index 0b7213121b..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/objectpascal.xml +++ /dev/null @@ -1,142 +0,0 @@ - - - ObjectPascal - objectpascal - *.pas - *.pp - *.inc - *.dpr - *.dpk - *.lpr - *.lpk - text/x-pascal - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/ocaml.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/ocaml.xml deleted file mode 100644 index 1770d1d15c..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/ocaml.xml +++ /dev/null @@ -1,153 +0,0 @@ - - - OCaml - ocaml - *.ml - *.mli - *.mll - *.mly - text/x-ocaml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/octave.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/octave.xml deleted file mode 100644 index 0515d28986..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/octave.xml +++ /dev/null @@ -1,101 +0,0 @@ - - - Octave - octave - *.m - text/octave - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/odin.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/odin.xml deleted file mode 100644 index 8a529497d3..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/odin.xml +++ /dev/null @@ -1,127 +0,0 @@ - - - Odin - odin - *.odin - text/odin - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/onesenterprise.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/onesenterprise.xml deleted file mode 100644 index 530bad70e7..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/onesenterprise.xml +++ /dev/null @@ -1,92 +0,0 @@ - - - OnesEnterprise - ones - onesenterprise - 1S - 1S:Enterprise - *.EPF - *.epf - *.ERF - *.erf - application/octet-stream - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/openedge_abl.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/openedge_abl.xml deleted file mode 100644 index 04a80f3ce2..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/openedge_abl.xml +++ /dev/null @@ -1,101 +0,0 @@ - - - OpenEdge ABL - openedge - abl - progress - openedgeabl - *.p - *.cls - *.w - *.i - text/x-openedge - application/x-openedge - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/openscad.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/openscad.xml deleted file mode 100644 index 84d0fe135f..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/openscad.xml +++ /dev/null @@ -1,96 +0,0 @@ - - - OpenSCAD - openscad - *.scad - text/x-scad - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/org_mode.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/org_mode.xml deleted file mode 100644 index 259e54ef59..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/org_mode.xml +++ /dev/null @@ -1,329 +0,0 @@ - - - Org Mode - org - orgmode - *.org - text/org - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2 - 4 - - - - - - - - - - - - 2 - 4 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/pacmanconf.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/pacmanconf.xml deleted file mode 100644 index caf7236757..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/pacmanconf.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - PacmanConf - pacmanconf - pacman.conf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/perl.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/perl.xml deleted file mode 100644 index 8ac02ab40e..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/perl.xml +++ /dev/null @@ -1,400 +0,0 @@ - - - Perl - perl - pl - *.pl - *.pm - *.t - text/x-perl - application/x-perl - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/php.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/php.xml deleted file mode 100644 index c9e22ea577..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/php.xml +++ /dev/null @@ -1,212 +0,0 @@ - - - PHP - php - php3 - php4 - php5 - *.php - *.php[345] - *.inc - text/x-php - true - true - true - 3 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/pig.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/pig.xml deleted file mode 100644 index 5acd773991..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/pig.xml +++ /dev/null @@ -1,105 +0,0 @@ - - - Pig - pig - *.pig - text/x-pig - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/pkgconfig.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/pkgconfig.xml deleted file mode 100644 index 875dcba6ae..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/pkgconfig.xml +++ /dev/null @@ -1,73 +0,0 @@ - - - PkgConfig - pkgconfig - *.pc - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/pl_pgsql.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/pl_pgsql.xml deleted file mode 100644 index e3e813ad5b..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/pl_pgsql.xml +++ /dev/null @@ -1,119 +0,0 @@ - - - PL/pgSQL - plpgsql - text/x-plpgsql - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/plaintext.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/plaintext.xml deleted file mode 100644 index d5e3243ee9..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/plaintext.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - plaintext - text - plain - no-highlight - *.txt - text/plain - -1 - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/plutus_core.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/plutus_core.xml deleted file mode 100644 index 4ff5a97039..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/plutus_core.xml +++ /dev/null @@ -1,105 +0,0 @@ - - - Plutus Core - plutus-core - plc - *.plc - text/x-plutus-core - application/x-plutus-core - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/pony.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/pony.xml deleted file mode 100644 index 4efa9db508..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/pony.xml +++ /dev/null @@ -1,135 +0,0 @@ - - - Pony - pony - *.pony - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/postgresql_sql_dialect.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/postgresql_sql_dialect.xml deleted file mode 100644 index e901c1855a..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/postgresql_sql_dialect.xml +++ /dev/null @@ -1,155 +0,0 @@ - - - PostgreSQL SQL dialect - postgresql - postgres - text/x-postgresql - true - true - - - - - - - - - - - - - - - - - - - 6 - 12 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 12 - 4 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/postscript.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/postscript.xml deleted file mode 100644 index 15a3422d0e..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/postscript.xml +++ /dev/null @@ -1,89 +0,0 @@ - - - PostScript - postscript - postscr - *.ps - *.eps - application/postscript - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/povray.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/povray.xml deleted file mode 100644 index f37dab9088..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/povray.xml +++ /dev/null @@ -1,58 +0,0 @@ - - - POVRay - pov - *.pov - *.inc - text/x-povray - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/powerquery.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/powerquery.xml deleted file mode 100644 index 0ff1e35574..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/powerquery.xml +++ /dev/null @@ -1,51 +0,0 @@ - - - PowerQuery - powerquery - pq - *.pq - text/x-powerquery - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/powershell.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/powershell.xml deleted file mode 100644 index b63a15081d..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/powershell.xml +++ /dev/null @@ -1,230 +0,0 @@ - - - PowerShell - powershell - posh - ps1 - psm1 - psd1 - pwsh - *.ps1 - *.psm1 - *.psd1 - text/x-powershell - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/prolog.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/prolog.xml deleted file mode 100644 index 391bae36b2..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/prolog.xml +++ /dev/null @@ -1,115 +0,0 @@ - - - Prolog - prolog - *.ecl - *.prolog - *.pro - *.pl - text/x-prolog - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/promela.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/promela.xml deleted file mode 100644 index 84558c3b65..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/promela.xml +++ /dev/null @@ -1,119 +0,0 @@ - - - - Promela - promela - *.pml - *.prom - *.prm - *.promela - *.pr - *.pm - text/x-promela - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/promql.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/promql.xml deleted file mode 100644 index e95e333d52..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/promql.xml +++ /dev/null @@ -1,123 +0,0 @@ - - - PromQL - promql - *.promql - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/properties.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/properties.xml deleted file mode 100644 index d5ae0a283e..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/properties.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - properties - java-properties - *.properties - text/x-java-properties - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/protocol_buffer.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/protocol_buffer.xml deleted file mode 100644 index 157d321f8b..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/protocol_buffer.xml +++ /dev/null @@ -1,118 +0,0 @@ - - - Protocol Buffer - protobuf - proto - *.proto - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/prql.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/prql.xml deleted file mode 100644 index 21f21c65c1..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/prql.xml +++ /dev/null @@ -1,161 +0,0 @@ - - - PRQL - prql - *.prql - application/prql - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/psl.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/psl.xml deleted file mode 100644 index ab375dae47..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/psl.xml +++ /dev/null @@ -1,213 +0,0 @@ - - - PSL - psl - *.psl - *.BATCH - *.TRIG - *.PROC - text/x-psl - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/puppet.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/puppet.xml deleted file mode 100644 index fbb587cf5a..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/puppet.xml +++ /dev/null @@ -1,100 +0,0 @@ - - - Puppet - puppet - *.pp - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/python.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/python.xml deleted file mode 100644 index a58686ff10..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/python.xml +++ /dev/null @@ -1,593 +0,0 @@ - - - Python - python - py - sage - python3 - py3 - *.py - *.pyi - *.pyw - *.jy - *.sage - *.sc - SConstruct - SConscript - *.bzl - BUCK - BUILD - BUILD.bazel - WORKSPACE - WORKSPACE.bzlmod - WORKSPACE.bazel - MODULE.bazel - REPO.bazel - *.tac - text/x-python - application/x-python - text/x-python3 - application/x-python3 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/python_2.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/python_2.xml deleted file mode 100644 index 3297a2260e..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/python_2.xml +++ /dev/null @@ -1,356 +0,0 @@ - - - Python 2 - python2 - py2 - text/x-python2 - application/x-python2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/qbasic.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/qbasic.xml deleted file mode 100644 index 193fe18074..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/qbasic.xml +++ /dev/null @@ -1,173 +0,0 @@ - - - QBasic - qbasic - basic - *.BAS - *.bas - text/basic - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/qml.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/qml.xml deleted file mode 100644 index 43eb3eb3db..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/qml.xml +++ /dev/null @@ -1,113 +0,0 @@ - - - QML - qml - qbs - *.qml - *.qbs - application/x-qml - application/x-qt.qbs+qml - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/r.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/r.xml deleted file mode 100644 index c1fba4e5ef..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/r.xml +++ /dev/null @@ -1,128 +0,0 @@ - - - R - splus - s - r - *.S - *.R - *.r - .Rhistory - .Rprofile - .Renviron - text/S-plus - text/S - text/x-r-source - text/x-r - text/x-R - text/x-r-history - text/x-r-profile - 0.1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/racket.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/racket.xml deleted file mode 100644 index 6cdd303129..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/racket.xml +++ /dev/null @@ -1,260 +0,0 @@ - - - Racket - racket - rkt - *.rkt - *.rktd - *.rktl - text/x-racket - application/x-racket - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/ragel.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/ragel.xml deleted file mode 100644 index 69638d2ecd..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/ragel.xml +++ /dev/null @@ -1,149 +0,0 @@ - - - Ragel - ragel - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/react.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/react.xml deleted file mode 100644 index a4109b0941..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/react.xml +++ /dev/null @@ -1,236 +0,0 @@ - - - react - jsx - react - *.jsx - *.react - text/jsx - text/typescript-jsx - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/reasonml.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/reasonml.xml deleted file mode 100644 index 8b7bcc5064..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/reasonml.xml +++ /dev/null @@ -1,147 +0,0 @@ - - - ReasonML - reason - reasonml - *.re - *.rei - text/x-reasonml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/reg.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/reg.xml deleted file mode 100644 index 501d380338..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/reg.xml +++ /dev/null @@ -1,68 +0,0 @@ - - - reg - registry - *.reg - text/x-windows-registry - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/rego.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/rego.xml deleted file mode 100644 index 517b7133b0..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/rego.xml +++ /dev/null @@ -1,94 +0,0 @@ - - - Rego - rego - *.rego - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/rexx.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/rexx.xml deleted file mode 100644 index e682500cbf..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/rexx.xml +++ /dev/null @@ -1,127 +0,0 @@ - - - Rexx - rexx - arexx - *.rexx - *.rex - *.rx - *.arexx - text/x-rexx - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/rpgle.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/rpgle.xml deleted file mode 100644 index a74f3c66fd..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/rpgle.xml +++ /dev/null @@ -1,176 +0,0 @@ - - - RPGLE - SQLRPGLE - RPG IV - *.RPGLE - *.rpgle - *.SQLRPGLE - *.sqlrpgle - text/x-rpgle - text/x-sqlrpgle - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/rpm_spec.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/rpm_spec.xml deleted file mode 100644 index 8362772a6f..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/rpm_spec.xml +++ /dev/null @@ -1,58 +0,0 @@ - - - - RPMSpec - spec - *.spec - text/x-rpm-spec - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/ruby.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/ruby.xml deleted file mode 100644 index baa7e43594..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/ruby.xml +++ /dev/null @@ -1,724 +0,0 @@ - - - Ruby - rb - ruby - duby - *.rb - *.rbw - Rakefile - *.rake - *.gemspec - *.rbx - *.duby - Gemfile - Vagrantfile - text/x-ruby - application/x-ruby - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/rust.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/rust.xml deleted file mode 100644 index 083b96ffe0..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/rust.xml +++ /dev/null @@ -1,375 +0,0 @@ - - - Rust - rust - rs - *.rs - *.rs.in - text/rust - text/x-rust - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/sas.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/sas.xml deleted file mode 100644 index af1107bf9b..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/sas.xml +++ /dev/null @@ -1,191 +0,0 @@ - - - SAS - sas - *.SAS - *.sas - text/x-sas - text/sas - application/x-sas - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/sass.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/sass.xml deleted file mode 100644 index f80159491f..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/sass.xml +++ /dev/null @@ -1,362 +0,0 @@ - - - Sass - sass - *.sass - text/x-sass - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/scala.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/scala.xml deleted file mode 100644 index 2f8ddd49ec..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/scala.xml +++ /dev/null @@ -1,274 +0,0 @@ - - - Scala - scala - *.scala - text/x-scala - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/scheme.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/scheme.xml deleted file mode 100644 index 0198bd7226..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/scheme.xml +++ /dev/null @@ -1,106 +0,0 @@ - - - Scheme - scheme - scm - *.scm - *.ss - text/x-scheme - application/x-scheme - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/scilab.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/scilab.xml deleted file mode 100644 index 9e109495fd..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/scilab.xml +++ /dev/null @@ -1,98 +0,0 @@ - - - Scilab - scilab - *.sci - *.sce - *.tst - text/scilab - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/scss.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/scss.xml deleted file mode 100644 index ee060fc2b6..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/scss.xml +++ /dev/null @@ -1,373 +0,0 @@ - - - SCSS - scss - *.scss - text/x-scss - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/sed.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/sed.xml deleted file mode 100644 index fd77d083fa..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/sed.xml +++ /dev/null @@ -1,92 +0,0 @@ - - - - Sed - sed - gsed - ssed - *.sed - *.[gs]sed - text/x-sed - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/sieve.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/sieve.xml deleted file mode 100644 index fc605638a6..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/sieve.xml +++ /dev/null @@ -1,61 +0,0 @@ - - - Sieve - sieve - *.siv - *.sieve - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/smali.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/smali.xml deleted file mode 100644 index e468766d1e..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/smali.xml +++ /dev/null @@ -1,73 +0,0 @@ - - - - Smali - smali - *.smali - text/smali - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/smalltalk.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/smalltalk.xml deleted file mode 100644 index 00271118f9..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/smalltalk.xml +++ /dev/null @@ -1,294 +0,0 @@ - - - Smalltalk - smalltalk - squeak - st - *.st - text/x-smalltalk - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/smarty.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/smarty.xml deleted file mode 100644 index dd7752c586..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/smarty.xml +++ /dev/null @@ -1,79 +0,0 @@ - - - Smarty - smarty - *.tpl - application/x-smarty - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/snbt.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/snbt.xml deleted file mode 100644 index fdb12d0fe8..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/snbt.xml +++ /dev/null @@ -1,58 +0,0 @@ - - - - SNBT - snbt - *.snbt - text/snbt - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/snobol.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/snobol.xml deleted file mode 100644 index f53dbcba12..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/snobol.xml +++ /dev/null @@ -1,95 +0,0 @@ - - - Snobol - snobol - *.snobol - text/x-snobol - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/solidity.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/solidity.xml deleted file mode 100644 index 24c4ccbae4..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/solidity.xml +++ /dev/null @@ -1,291 +0,0 @@ - - - Solidity - sol - solidity - *.sol - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/sourcepawn.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/sourcepawn.xml deleted file mode 100644 index caca401e3e..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/sourcepawn.xml +++ /dev/null @@ -1,59 +0,0 @@ - - - SourcePawn - sp - *.sp - *.inc - text/x-sourcepawn - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/sparql.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/sparql.xml deleted file mode 100644 index 7dc65af71f..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/sparql.xml +++ /dev/null @@ -1,160 +0,0 @@ - - - SPARQL - sparql - *.rq - *.sparql - application/sparql-query - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/sql.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/sql.xml deleted file mode 100644 index b542b65fe9..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/sql.xml +++ /dev/null @@ -1,90 +0,0 @@ - - - SQL - sql - *.sql - text/x-sql - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/squidconf.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/squidconf.xml deleted file mode 100644 index cbd8dbce3d..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/squidconf.xml +++ /dev/null @@ -1,63 +0,0 @@ - - - SquidConf - squidconf - squid.conf - squid - squid.conf - text/x-squidconf - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/standard_ml.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/standard_ml.xml deleted file mode 100644 index 39cf4f2af2..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/standard_ml.xml +++ /dev/null @@ -1,548 +0,0 @@ - - - Standard ML - sml - *.sml - *.sig - *.fun - text/x-standardml - application/x-standardml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/stas.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/stas.xml deleted file mode 100644 index 56b4f92382..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/stas.xml +++ /dev/null @@ -1,85 +0,0 @@ - - - stas - *.stas - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/stylus.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/stylus.xml deleted file mode 100644 index c2d88073ac..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/stylus.xml +++ /dev/null @@ -1,132 +0,0 @@ - - - Stylus - stylus - *.styl - text/x-styl - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/swift.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/swift.xml deleted file mode 100644 index 416bf90c54..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/swift.xml +++ /dev/null @@ -1,207 +0,0 @@ - - - Swift - swift - *.swift - text/x-swift - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/systemd.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/systemd.xml deleted file mode 100644 index e31bfc29f9..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/systemd.xml +++ /dev/null @@ -1,63 +0,0 @@ - - - SYSTEMD - systemd - *.automount - *.device - *.dnssd - *.link - *.mount - *.netdev - *.network - *.path - *.scope - *.service - *.slice - *.socket - *.swap - *.target - *.timer - text/plain - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/systemverilog.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/systemverilog.xml deleted file mode 100644 index fac3da2356..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/systemverilog.xml +++ /dev/null @@ -1,181 +0,0 @@ - - - systemverilog - systemverilog - sv - *.sv - *.svh - text/x-systemverilog - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/tablegen.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/tablegen.xml deleted file mode 100644 index a020ce804b..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/tablegen.xml +++ /dev/null @@ -1,69 +0,0 @@ - - - TableGen - tablegen - *.td - text/x-tablegen - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/tal.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/tal.xml deleted file mode 100644 index a071d4c1a9..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/tal.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - Tal - tal - uxntal - *.tal - text/x-uxntal - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/tasm.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/tasm.xml deleted file mode 100644 index 1347f53968..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/tasm.xml +++ /dev/null @@ -1,135 +0,0 @@ - - - TASM - tasm - *.asm - *.ASM - *.tasm - text/x-tasm - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/tcl.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/tcl.xml deleted file mode 100644 index 7ed69bc26f..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/tcl.xml +++ /dev/null @@ -1,272 +0,0 @@ - - - Tcl - tcl - *.tcl - *.rvt - text/x-tcl - text/x-script.tcl - application/x-tcl - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/tcsh.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/tcsh.xml deleted file mode 100644 index 9895643c4b..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/tcsh.xml +++ /dev/null @@ -1,121 +0,0 @@ - - - Tcsh - tcsh - csh - *.tcsh - *.csh - application/x-csh - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/termcap.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/termcap.xml deleted file mode 100644 index e863bbd058..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/termcap.xml +++ /dev/null @@ -1,75 +0,0 @@ - - - Termcap - termcap - termcap - termcap.src - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/terminfo.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/terminfo.xml deleted file mode 100644 index 9e8f56ec42..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/terminfo.xml +++ /dev/null @@ -1,84 +0,0 @@ - - - Terminfo - terminfo - terminfo - terminfo.src - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/terraform.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/terraform.xml deleted file mode 100644 index f8df6be2ab..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/terraform.xml +++ /dev/null @@ -1,149 +0,0 @@ - - - Terraform - terraform - tf - hcl - *.tf - *.hcl - application/x-tf - application/x-terraform - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/tex.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/tex.xml deleted file mode 100644 index 809bb9a297..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/tex.xml +++ /dev/null @@ -1,113 +0,0 @@ - - - TeX - tex - latex - *.tex - *.aux - *.toc - text/x-tex - text/x-latex - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/thrift.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/thrift.xml deleted file mode 100644 index f14257d4fb..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/thrift.xml +++ /dev/null @@ -1,154 +0,0 @@ - - - Thrift - thrift - *.thrift - application/x-thrift - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/toml.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/toml.xml deleted file mode 100644 index 87bd19df4b..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/toml.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - TOML - toml - *.toml - Pipfile - poetry.lock - uv.lock - text/x-toml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/tradingview.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/tradingview.xml deleted file mode 100644 index 3671f61edc..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/tradingview.xml +++ /dev/null @@ -1,81 +0,0 @@ - - - TradingView - tradingview - tv - *.tv - text/x-tradingview - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/transact-sql.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/transact-sql.xml deleted file mode 100644 index b0490aa7c7..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/transact-sql.xml +++ /dev/null @@ -1,137 +0,0 @@ - - - Transact-SQL - tsql - t-sql - text/x-tsql - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/turing.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/turing.xml deleted file mode 100644 index 4eab69b731..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/turing.xml +++ /dev/null @@ -1,82 +0,0 @@ - - - Turing - turing - *.turing - *.tu - text/x-turing - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/turtle.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/turtle.xml deleted file mode 100644 index 7c572f9ca1..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/turtle.xml +++ /dev/null @@ -1,170 +0,0 @@ - - - Turtle - turtle - *.ttl - text/turtle - application/x-turtle - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/twig.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/twig.xml deleted file mode 100644 index de95c5f913..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/twig.xml +++ /dev/null @@ -1,155 +0,0 @@ - - - Twig - twig - *.twig - application/x-twig - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/typescript.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/typescript.xml deleted file mode 100644 index a3e3be2391..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/typescript.xml +++ /dev/null @@ -1,302 +0,0 @@ - - - TypeScript - ts - tsx - typescript - *.ts - *.tsx - *.mts - *.cts - text/x-typescript - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/typoscript.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/typoscript.xml deleted file mode 100644 index bc416d4726..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/typoscript.xml +++ /dev/null @@ -1,178 +0,0 @@ - - - TypoScript - typoscript - *.ts - text/x-typoscript - true - 0.1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/typoscriptcssdata.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/typoscriptcssdata.xml deleted file mode 100644 index 62c42c1537..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/typoscriptcssdata.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - TypoScriptCssData - typoscriptcssdata - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/typoscripthtmldata.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/typoscripthtmldata.xml deleted file mode 100644 index 1b0af3a4e4..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/typoscripthtmldata.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - TypoScriptHtmlData - typoscripthtmldata - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/typst.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/typst.xml deleted file mode 100644 index 330dc40fa2..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/typst.xml +++ /dev/null @@ -1,108 +0,0 @@ - - - - Typst - typst - *.typ - text/x-typst - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/ucode.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/ucode.xml deleted file mode 100644 index 054fa8913c..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/ucode.xml +++ /dev/null @@ -1,147 +0,0 @@ - - - ucode - *.uc - application/x.ucode - text/x.ucode - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/v.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/v.xml deleted file mode 100644 index e1af3d1cd1..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/v.xml +++ /dev/null @@ -1,355 +0,0 @@ - - - V - v - vlang - *.v - *.vv - v.mod - text/x-v - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/v_shell.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/v_shell.xml deleted file mode 100644 index 34ce610650..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/v_shell.xml +++ /dev/null @@ -1,365 +0,0 @@ - - - V shell - vsh - vshell - *.vsh - text/x-vsh - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/vala.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/vala.xml deleted file mode 100644 index 17c1acf487..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/vala.xml +++ /dev/null @@ -1,72 +0,0 @@ - - - - Vala - vala - vapi - *.vala - *.vapi - text/x-vala - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/vb_net.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/vb_net.xml deleted file mode 100644 index 9f85afd0e5..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/vb_net.xml +++ /dev/null @@ -1,162 +0,0 @@ - - - VB.net - vb.net - vbnet - *.vb - *.bas - text/x-vbnet - text/x-vba - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/verilog.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/verilog.xml deleted file mode 100644 index cd4b9ff09f..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/verilog.xml +++ /dev/null @@ -1,158 +0,0 @@ - - - verilog - verilog - v - *.v - text/x-verilog - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/vhdl.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/vhdl.xml deleted file mode 100644 index aa42044868..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/vhdl.xml +++ /dev/null @@ -1,171 +0,0 @@ - - - VHDL - vhdl - *.vhdl - *.vhd - text/x-vhdl - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/vhs.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/vhs.xml deleted file mode 100644 index ee84d12924..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/vhs.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - VHS - vhs - tape - cassette - *.tape - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/viml.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/viml.xml deleted file mode 100644 index 43e6bfa744..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/viml.xml +++ /dev/null @@ -1,85 +0,0 @@ - - - VimL - vim - *.vim - .vimrc - .exrc - .gvimrc - _vimrc - _exrc - _gvimrc - vimrc - gvimrc - text/x-vim - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/vue.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/vue.xml deleted file mode 100644 index e2f75e1dc9..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/vue.xml +++ /dev/null @@ -1,295 +0,0 @@ - - - vue - vue - vuejs - *.vue - text/x-vue - application/x-vue - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/wdte.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/wdte.xml deleted file mode 100644 index c663ee2fe7..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/wdte.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - WDTE - *.wdte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/webgpu_shading_language.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/webgpu_shading_language.xml deleted file mode 100644 index ea2b6e1ef3..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/webgpu_shading_language.xml +++ /dev/null @@ -1,142 +0,0 @@ - - - WebGPU Shading Language - wgsl - *.wgsl - text/wgsl - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/webvtt.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/webvtt.xml deleted file mode 100644 index 08a7efc3ae..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/webvtt.xml +++ /dev/null @@ -1,283 +0,0 @@ - - - WebVTT - vtt - *.vtt - text/vtt - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/whiley.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/whiley.xml deleted file mode 100644 index 1762c966ef..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/whiley.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - Whiley - whiley - *.whiley - text/x-whiley - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/xml.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/xml.xml deleted file mode 100644 index 2c6a4d9904..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/xml.xml +++ /dev/null @@ -1,95 +0,0 @@ - - - XML - xml - *.xml - *.xsl - *.rss - *.xslt - *.xsd - *.wsdl - *.wsf - *.svg - *.csproj - *.vcxproj - *.fsproj - text/xml - application/xml - image/svg+xml - application/rss+xml - application/atom+xml - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/xorg.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/xorg.xml deleted file mode 100644 index 53bf432866..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/xorg.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - Xorg - xorg.conf - xorg.conf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/yaml.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/yaml.xml deleted file mode 100644 index 0707554164..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/yaml.xml +++ /dev/null @@ -1,122 +0,0 @@ - - - YAML - yaml - *.yaml - *.yml - text/x-yaml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/yang.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/yang.xml deleted file mode 100644 index f3da7ceb37..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/yang.xml +++ /dev/null @@ -1,99 +0,0 @@ - - - YANG - yang - *.yang - application/yang - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/z80_assembly.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/z80_assembly.xml deleted file mode 100644 index 5bb77a9adc..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/z80_assembly.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - Z80 Assembly - z80 - *.z80 - *.asm - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/zed.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/zed.xml deleted file mode 100644 index 929f495320..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/zed.xml +++ /dev/null @@ -1,51 +0,0 @@ - - - Zed - zed - *.zed - text/zed - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/zig.xml b/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/zig.xml deleted file mode 100644 index 6f17bcafc1..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/embedded/zig.xml +++ /dev/null @@ -1,116 +0,0 @@ - - - Zig - zig - *.zig - *.zon - text/zig - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/gemtext.go b/vendor/github.com/alecthomas/chroma/v2/lexers/gemtext.go deleted file mode 100644 index 2fed8d62f6..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/gemtext.go +++ /dev/null @@ -1,37 +0,0 @@ -package lexers - -import ( - . "github.com/alecthomas/chroma/v2" // nolint -) - -// Gemtext lexer. -var Gemtext = Register(MustNewLexer( - &Config{ - Name: "Gemtext", - Aliases: []string{"gemtext", "gmi", "gmni", "gemini"}, - Filenames: []string{"*.gmi", "*.gmni", "*.gemini"}, - MimeTypes: []string{"text/gemini"}, - }, - gemtextRules, -)) - -func gemtextRules() Rules { - return Rules{ - "root": { - {`^(#[^#].+\r?\n)`, ByGroups(GenericHeading), nil}, - {`^(#{2,3}.+\r?\n)`, ByGroups(GenericSubheading), nil}, - {`^(\* )(.+\r?\n)`, ByGroups(Keyword, Text), nil}, - {`^(>)(.+\r?\n)`, ByGroups(Keyword, GenericEmph), nil}, - {"^(```\\r?\\n)([\\w\\W]*?)(^```)(.+\\r?\\n)?", ByGroups(String, Text, String, Comment), nil}, - { - "^(```)(\\w+)(\\r?\\n)([\\w\\W]*?)(^```)(.+\\r?\\n)?", - UsingByGroup(2, 4, String, String, String, Text, String, Comment), - nil, - }, - {"^(```)(.+\\r?\\n)([\\w\\W]*?)(^```)(.+\\r?\\n)?", ByGroups(String, String, Text, String, Comment), nil}, - {`^(=>)(\s*)([^\s]+)(\s*)$`, ByGroups(Keyword, Text, NameAttribute, Text), nil}, - {`^(=>)(\s*)([^\s]+)(\s+)(.+)$`, ByGroups(Keyword, Text, NameAttribute, Text, NameTag), nil}, - {`(.|(?:\r?\n))`, ByGroups(Text), nil}, - }, - } -} diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/genshi.go b/vendor/github.com/alecthomas/chroma/v2/lexers/genshi.go deleted file mode 100644 index 7f396f4b86..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/genshi.go +++ /dev/null @@ -1,118 +0,0 @@ -package lexers - -import ( - . "github.com/alecthomas/chroma/v2" // nolint -) - -// Genshi Text lexer. -var GenshiText = Register(MustNewLexer( - &Config{ - Name: "Genshi Text", - Aliases: []string{"genshitext"}, - Filenames: []string{}, - MimeTypes: []string{"application/x-genshi-text", "text/x-genshi"}, - }, - genshiTextRules, -)) - -func genshiTextRules() Rules { - return Rules{ - "root": { - {`[^#$\s]+`, Other, nil}, - {`^(\s*)(##.*)$`, ByGroups(Text, Comment), nil}, - {`^(\s*)(#)`, ByGroups(Text, CommentPreproc), Push("directive")}, - Include("variable"), - {`[#$\s]`, Other, nil}, - }, - "directive": { - {`\n`, Text, Pop(1)}, - {`(?:def|for|if)\s+.*`, Using("Python"), Pop(1)}, - {`(choose|when|with)([^\S\n]+)(.*)`, ByGroups(Keyword, Text, Using("Python")), Pop(1)}, - {`(choose|otherwise)\b`, Keyword, Pop(1)}, - {`(end\w*)([^\S\n]*)(.*)`, ByGroups(Keyword, Text, Comment), Pop(1)}, - }, - "variable": { - {`(?)`, ByGroups(CommentPreproc, Using("Python"), CommentPreproc), nil}, - {`<\s*(script|style)\s*.*?>.*?<\s*/\1\s*>`, Other, nil}, - {`<\s*py:[a-zA-Z0-9]+`, NameTag, Push("pytag")}, - {`<\s*[a-zA-Z0-9:.]+`, NameTag, Push("tag")}, - Include("variable"), - {`[<$]`, Other, nil}, - }, - "pytag": { - {`\s+`, Text, nil}, - {`[\w:-]+\s*=`, NameAttribute, Push("pyattr")}, - {`/?\s*>`, NameTag, Pop(1)}, - }, - "pyattr": { - {`(")(.*?)(")`, ByGroups(LiteralString, Using("Python"), LiteralString), Pop(1)}, - {`(')(.*?)(')`, ByGroups(LiteralString, Using("Python"), LiteralString), Pop(1)}, - {`[^\s>]+`, LiteralString, Pop(1)}, - }, - "tag": { - {`\s+`, Text, nil}, - {`py:[\w-]+\s*=`, NameAttribute, Push("pyattr")}, - {`[\w:-]+\s*=`, NameAttribute, Push("attr")}, - {`/?\s*>`, NameTag, Pop(1)}, - }, - "attr": { - {`"`, LiteralString, Push("attr-dstring")}, - {`'`, LiteralString, Push("attr-sstring")}, - {`[^\s>]*`, LiteralString, Pop(1)}, - }, - "attr-dstring": { - {`"`, LiteralString, Pop(1)}, - Include("strings"), - {`'`, LiteralString, nil}, - }, - "attr-sstring": { - {`'`, LiteralString, Pop(1)}, - Include("strings"), - {`'`, LiteralString, nil}, - }, - "strings": { - {`[^"'$]+`, LiteralString, nil}, - Include("variable"), - }, - "variable": { - {`(?>=|<<|>>|<=|>=|&\^=|&\^|\+=|-=|\*=|/=|%=|&=|\|=|&&|\|\||<-|\+\+|--|==|!=|:=|\.\.\.|[+\-*/%&])`, Operator, nil}, - {`([a-zA-Z_]\w*)(\s*)(\()`, ByGroups(NameFunction, UsingSelf("root"), Punctuation), nil}, - {`[|^<>=!()\[\]{}.,;:~]`, Punctuation, nil}, - {`[^\W\d]\w*`, NameOther, nil}, - }, - } -} - -var GoHTMLTemplate = Register(DelegatingLexer(HTML, MustNewXMLLexer( - embedded, - "embedded/go_template.xml", -).SetConfig( - &Config{ - Name: "Go HTML Template", - Aliases: []string{"go-html-template"}, - }, -))) - -var GoTextTemplate = Register(MustNewXMLLexer( - embedded, - "embedded/go_template.xml", -).SetConfig( - &Config{ - Name: "Go Text Template", - Aliases: []string{"go-text-template"}, - }, -)) diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/haxe.go b/vendor/github.com/alecthomas/chroma/v2/lexers/haxe.go deleted file mode 100644 index 9a72de865b..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/haxe.go +++ /dev/null @@ -1,647 +0,0 @@ -package lexers - -import ( - . "github.com/alecthomas/chroma/v2" // nolint -) - -// Haxe lexer. -var Haxe = Register(MustNewLexer( - &Config{ - Name: "Haxe", - Aliases: []string{"hx", "haxe", "hxsl"}, - Filenames: []string{"*.hx", "*.hxsl"}, - MimeTypes: []string{"text/haxe", "text/x-haxe", "text/x-hx"}, - DotAll: true, - }, - haxeRules, -)) - -func haxeRules() Rules { - return Rules{ - "root": { - Include("spaces"), - Include("meta"), - {`(?:package)\b`, KeywordNamespace, Push("semicolon", "package")}, - {`(?:import)\b`, KeywordNamespace, Push("semicolon", "import")}, - {`(?:using)\b`, KeywordNamespace, Push("semicolon", "using")}, - {`(?:extern|private)\b`, KeywordDeclaration, nil}, - {`(?:abstract)\b`, KeywordDeclaration, Push("abstract")}, - {`(?:class|interface)\b`, KeywordDeclaration, Push("class")}, - {`(?:enum)\b`, KeywordDeclaration, Push("enum")}, - {`(?:typedef)\b`, KeywordDeclaration, Push("typedef")}, - {`(?=.)`, Text, Push("expr-statement")}, - }, - "spaces": { - {`\s+`, Text, nil}, - {`//[^\n\r]*`, CommentSingle, nil}, - {`/\*.*?\*/`, CommentMultiline, nil}, - {`(#)(if|elseif|else|end|error)\b`, CommentPreproc, MutatorFunc(haxePreProcMutator)}, - }, - "string-single-interpol": { - {`\$\{`, LiteralStringInterpol, Push("string-interpol-close", "expr")}, - {`\$\$`, LiteralStringEscape, nil}, - {`\$(?=(?:_*[a-z]\w*|_+[0-9]\w*|_*[A-Z]\w*|_+|\$\w+))`, LiteralStringInterpol, Push("ident")}, - Include("string-single"), - }, - "string-single": { - {`'`, LiteralStringSingle, Pop(1)}, - {`\\.`, LiteralStringEscape, nil}, - {`.`, LiteralStringSingle, nil}, - }, - "string-double": { - {`"`, LiteralStringDouble, Pop(1)}, - {`\\.`, LiteralStringEscape, nil}, - {`.`, LiteralStringDouble, nil}, - }, - "string-interpol-close": { - {`\$(?:_*[a-z]\w*|_+[0-9]\w*|_*[A-Z]\w*|_+|\$\w+)`, LiteralStringInterpol, nil}, - {`\}`, LiteralStringInterpol, Pop(1)}, - }, - "package": { - Include("spaces"), - {`(?:_*[a-z]\w*|_+[0-9]\w*|_*[A-Z]\w*|_+|\$\w+)`, NameNamespace, nil}, - {`\.`, Punctuation, Push("import-ident")}, - Default(Pop(1)), - }, - "import": { - Include("spaces"), - {`(?:_*[a-z]\w*|_+[0-9]\w*|_*[A-Z]\w*|_+|\$\w+)`, NameNamespace, nil}, - {`\*`, Keyword, nil}, - {`\.`, Punctuation, Push("import-ident")}, - {`in`, KeywordNamespace, Push("ident")}, - Default(Pop(1)), - }, - "import-ident": { - Include("spaces"), - {`\*`, Keyword, Pop(1)}, - {`(?:_*[a-z]\w*|_+[0-9]\w*|_*[A-Z]\w*|_+|\$\w+)`, NameNamespace, Pop(1)}, - }, - "using": { - Include("spaces"), - {`(?:_*[a-z]\w*|_+[0-9]\w*|_*[A-Z]\w*|_+|\$\w+)`, NameNamespace, nil}, - {`\.`, Punctuation, Push("import-ident")}, - Default(Pop(1)), - }, - "preproc-error": { - {`\s+`, CommentPreproc, nil}, - {`'`, LiteralStringSingle, Push("#pop", "string-single")}, - {`"`, LiteralStringDouble, Push("#pop", "string-double")}, - Default(Pop(1)), - }, - "preproc-expr": { - {`\s+`, CommentPreproc, nil}, - {`\!`, CommentPreproc, nil}, - {`\(`, CommentPreproc, Push("#pop", "preproc-parenthesis")}, - {`(?:_*[a-z]\w*|_+[0-9]\w*|_*[A-Z]\w*|_+|\$\w+)`, CommentPreproc, Pop(1)}, - {`\.[0-9]+`, LiteralNumberFloat, nil}, - {`[0-9]+[eE][+\-]?[0-9]+`, LiteralNumberFloat, nil}, - {`[0-9]+\.[0-9]*[eE][+\-]?[0-9]+`, LiteralNumberFloat, nil}, - {`[0-9]+\.[0-9]+`, LiteralNumberFloat, nil}, - {`[0-9]+\.(?!(?:_*[a-z]\w*|_+[0-9]\w*|_*[A-Z]\w*|_+|\$\w+)|\.\.)`, LiteralNumberFloat, nil}, - {`0x[0-9a-fA-F]+`, LiteralNumberHex, nil}, - {`[0-9]+`, LiteralNumberInteger, nil}, - {`'`, LiteralStringSingle, Push("#pop", "string-single")}, - {`"`, LiteralStringDouble, Push("#pop", "string-double")}, - }, - "preproc-parenthesis": { - {`\s+`, CommentPreproc, nil}, - {`\)`, CommentPreproc, Pop(1)}, - Default(Push("preproc-expr-in-parenthesis")), - }, - "preproc-expr-chain": { - {`\s+`, CommentPreproc, nil}, - {`(?:%=|&=|\|=|\^=|\+=|\-=|\*=|/=|<<=|>\s*>\s*=|>\s*>\s*>\s*=|==|!=|<=|>\s*=|&&|\|\||<<|>>>|>\s*>|\.\.\.|<|>|%|&|\||\^|\+|\*|/|\-|=>|=)`, CommentPreproc, Push("#pop", "preproc-expr-in-parenthesis")}, - Default(Pop(1)), - }, - "preproc-expr-in-parenthesis": { - {`\s+`, CommentPreproc, nil}, - {`\!`, CommentPreproc, nil}, - {`\(`, CommentPreproc, Push("#pop", "preproc-expr-chain", "preproc-parenthesis")}, - {`(?:_*[a-z]\w*|_+[0-9]\w*|_*[A-Z]\w*|_+|\$\w+)`, CommentPreproc, Push("#pop", "preproc-expr-chain")}, - {`\.[0-9]+`, LiteralNumberFloat, Push("#pop", "preproc-expr-chain")}, - {`[0-9]+[eE][+\-]?[0-9]+`, LiteralNumberFloat, Push("#pop", "preproc-expr-chain")}, - {`[0-9]+\.[0-9]*[eE][+\-]?[0-9]+`, LiteralNumberFloat, Push("#pop", "preproc-expr-chain")}, - {`[0-9]+\.[0-9]+`, LiteralNumberFloat, Push("#pop", "preproc-expr-chain")}, - {`[0-9]+\.(?!(?:_*[a-z]\w*|_+[0-9]\w*|_*[A-Z]\w*|_+|\$\w+)|\.\.)`, LiteralNumberFloat, Push("#pop", "preproc-expr-chain")}, - {`0x[0-9a-fA-F]+`, LiteralNumberHex, Push("#pop", "preproc-expr-chain")}, - {`[0-9]+`, LiteralNumberInteger, Push("#pop", "preproc-expr-chain")}, - {`'`, LiteralStringSingle, Push("#pop", "preproc-expr-chain", "string-single")}, - {`"`, LiteralStringDouble, Push("#pop", "preproc-expr-chain", "string-double")}, - }, - "abstract": { - Include("spaces"), - Default(Pop(1), Push("abstract-body"), Push("abstract-relation"), Push("abstract-opaque"), Push("type-param-constraint"), Push("type-name")), - }, - "abstract-body": { - Include("spaces"), - {`\{`, Punctuation, Push("#pop", "class-body")}, - }, - "abstract-opaque": { - Include("spaces"), - {`\(`, Punctuation, Push("#pop", "parenthesis-close", "type")}, - Default(Pop(1)), - }, - "abstract-relation": { - Include("spaces"), - {`(?:to|from)`, KeywordDeclaration, Push("type")}, - {`,`, Punctuation, nil}, - Default(Pop(1)), - }, - "meta": { - Include("spaces"), - {`@`, NameDecorator, Push("meta-body", "meta-ident", "meta-colon")}, - }, - "meta-colon": { - Include("spaces"), - {`:`, NameDecorator, Pop(1)}, - Default(Pop(1)), - }, - "meta-ident": { - Include("spaces"), - {`(?:_*[a-z]\w*|_+[0-9]\w*|_*[A-Z]\w*|_+|\$\w+)`, NameDecorator, Pop(1)}, - }, - "meta-body": { - Include("spaces"), - {`\(`, NameDecorator, Push("#pop", "meta-call")}, - Default(Pop(1)), - }, - "meta-call": { - Include("spaces"), - {`\)`, NameDecorator, Pop(1)}, - Default(Pop(1), Push("meta-call-sep"), Push("expr")), - }, - "meta-call-sep": { - Include("spaces"), - {`\)`, NameDecorator, Pop(1)}, - {`,`, Punctuation, Push("#pop", "meta-call")}, - }, - "typedef": { - Include("spaces"), - Default(Pop(1), Push("typedef-body"), Push("type-param-constraint"), Push("type-name")), - }, - "typedef-body": { - Include("spaces"), - {`=`, Operator, Push("#pop", "optional-semicolon", "type")}, - }, - "enum": { - Include("spaces"), - Default(Pop(1), Push("enum-body"), Push("bracket-open"), Push("type-param-constraint"), Push("type-name")), - }, - "enum-body": { - Include("spaces"), - Include("meta"), - {`\}`, Punctuation, Pop(1)}, - {`(?!(?:function|class|static|var|if|else|while|do|for|break|return|continue|extends|implements|import|switch|case|default|public|private|try|untyped|catch|new|this|throw|extern|enum|in|interface|cast|override|dynamic|typedef|package|inline|using|null|true|false|abstract)\b)(?:_*[a-z]\w*|_+[0-9]\w*|_*[A-Z]\w*|_+|\$\w+)`, Name, Push("enum-member", "type-param-constraint")}, - }, - "enum-member": { - Include("spaces"), - {`\(`, Punctuation, Push("#pop", "semicolon", "flag", "function-param")}, - Default(Pop(1), Push("semicolon"), Push("flag")), - }, - "class": { - Include("spaces"), - Default(Pop(1), Push("class-body"), Push("bracket-open"), Push("extends"), Push("type-param-constraint"), Push("type-name")), - }, - "extends": { - Include("spaces"), - {`(?:extends|implements)\b`, KeywordDeclaration, Push("type")}, - {`,`, Punctuation, nil}, - Default(Pop(1)), - }, - "bracket-open": { - Include("spaces"), - {`\{`, Punctuation, Pop(1)}, - }, - "bracket-close": { - Include("spaces"), - {`\}`, Punctuation, Pop(1)}, - }, - "class-body": { - Include("spaces"), - Include("meta"), - {`\}`, Punctuation, Pop(1)}, - {`(?:static|public|private|override|dynamic|inline|macro)\b`, KeywordDeclaration, nil}, - Default(Push("class-member")), - }, - "class-member": { - Include("spaces"), - {`(var)\b`, KeywordDeclaration, Push("#pop", "optional-semicolon", "var")}, - {`(function)\b`, KeywordDeclaration, Push("#pop", "optional-semicolon", "class-method")}, - }, - "function-local": { - Include("spaces"), - {`(?!(?:function|class|static|var|if|else|while|do|for|break|return|continue|extends|implements|import|switch|case|default|public|private|try|untyped|catch|new|this|throw|extern|enum|in|interface|cast|override|dynamic|typedef|package|inline|using|null|true|false|abstract)\b)(?:_*[a-z]\w*|_+[0-9]\w*|_*[A-Z]\w*|_+|\$\w+)`, NameFunction, Push("#pop", "optional-expr", "flag", "function-param", "parenthesis-open", "type-param-constraint")}, - Default(Pop(1), Push("optional-expr"), Push("flag"), Push("function-param"), Push("parenthesis-open"), Push("type-param-constraint")), - }, - "optional-expr": { - Include("spaces"), - Include("expr"), - Default(Pop(1)), - }, - "class-method": { - Include("spaces"), - {`(?:_*[a-z]\w*|_+[0-9]\w*|_*[A-Z]\w*|_+|\$\w+)`, NameFunction, Push("#pop", "optional-expr", "flag", "function-param", "parenthesis-open", "type-param-constraint")}, - }, - "function-param": { - Include("spaces"), - {`\)`, Punctuation, Pop(1)}, - {`\?`, Punctuation, nil}, - {`(?!(?:function|class|static|var|if|else|while|do|for|break|return|continue|extends|implements|import|switch|case|default|public|private|try|untyped|catch|new|this|throw|extern|enum|in|interface|cast|override|dynamic|typedef|package|inline|using|null|true|false|abstract)\b)(?:_*[a-z]\w*|_+[0-9]\w*|_*[A-Z]\w*|_+|\$\w+)`, Name, Push("#pop", "function-param-sep", "assign", "flag")}, - }, - "function-param-sep": { - Include("spaces"), - {`\)`, Punctuation, Pop(1)}, - {`,`, Punctuation, Push("#pop", "function-param")}, - }, - "prop-get-set": { - Include("spaces"), - {`\(`, Punctuation, Push("#pop", "parenthesis-close", "prop-get-set-opt", "comma", "prop-get-set-opt")}, - Default(Pop(1)), - }, - "prop-get-set-opt": { - Include("spaces"), - {`(?:default|null|never|dynamic|get|set)\b`, Keyword, Pop(1)}, - {`(?!(?:function|class|static|var|if|else|while|do|for|break|return|continue|extends|implements|import|switch|case|default|public|private|try|untyped|catch|new|this|throw|extern|enum|in|interface|cast|override|dynamic|typedef|package|inline|using|null|true|false|abstract)\b)(?:_*[a-z]\w*|_+[0-9]\w*|_*[A-Z]\w*|_+|\$\w+)`, Text, Pop(1)}, - }, - "expr-statement": { - Include("spaces"), - Default(Pop(1), Push("optional-semicolon"), Push("expr")), - }, - "expr": { - Include("spaces"), - {`@`, NameDecorator, Push("#pop", "optional-expr", "meta-body", "meta-ident", "meta-colon")}, - {`(?:\+\+|\-\-|~(?!/)|!|\-)`, Operator, nil}, - {`\(`, Punctuation, Push("#pop", "expr-chain", "parenthesis")}, - {`(?:static|public|private|override|dynamic|inline)\b`, KeywordDeclaration, nil}, - {`(?:function)\b`, KeywordDeclaration, Push("#pop", "expr-chain", "function-local")}, - {`\{`, Punctuation, Push("#pop", "expr-chain", "bracket")}, - {`(?:true|false|null)\b`, KeywordConstant, Push("#pop", "expr-chain")}, - {`(?:this)\b`, Keyword, Push("#pop", "expr-chain")}, - {`(?:cast)\b`, Keyword, Push("#pop", "expr-chain", "cast")}, - {`(?:try)\b`, Keyword, Push("#pop", "catch", "expr")}, - {`(?:var)\b`, KeywordDeclaration, Push("#pop", "var")}, - {`(?:new)\b`, Keyword, Push("#pop", "expr-chain", "new")}, - {`(?:switch)\b`, Keyword, Push("#pop", "switch")}, - {`(?:if)\b`, Keyword, Push("#pop", "if")}, - {`(?:do)\b`, Keyword, Push("#pop", "do")}, - {`(?:while)\b`, Keyword, Push("#pop", "while")}, - {`(?:for)\b`, Keyword, Push("#pop", "for")}, - {`(?:untyped|throw)\b`, Keyword, nil}, - {`(?:return)\b`, Keyword, Push("#pop", "optional-expr")}, - {`(?:macro)\b`, Keyword, Push("#pop", "macro")}, - {`(?:continue|break)\b`, Keyword, Pop(1)}, - {`(?:\$\s*[a-z]\b|\$(?!(?:_*[a-z]\w*|_+[0-9]\w*|_*[A-Z]\w*|_+|\$\w+)))`, Name, Push("#pop", "dollar")}, - {`(?!(?:function|class|static|var|if|else|while|do|for|break|return|continue|extends|implements|import|switch|case|default|public|private|try|untyped|catch|new|this|throw|extern|enum|in|interface|cast|override|dynamic|typedef|package|inline|using|null|true|false|abstract)\b)(?:_*[a-z]\w*|_+[0-9]\w*|_*[A-Z]\w*|_+|\$\w+)`, Name, Push("#pop", "expr-chain")}, - {`\.[0-9]+`, LiteralNumberFloat, Push("#pop", "expr-chain")}, - {`[0-9]+[eE][+\-]?[0-9]+`, LiteralNumberFloat, Push("#pop", "expr-chain")}, - {`[0-9]+\.[0-9]*[eE][+\-]?[0-9]+`, LiteralNumberFloat, Push("#pop", "expr-chain")}, - {`[0-9]+\.[0-9]+`, LiteralNumberFloat, Push("#pop", "expr-chain")}, - {`[0-9]+\.(?!(?:_*[a-z]\w*|_+[0-9]\w*|_*[A-Z]\w*|_+|\$\w+)|\.\.)`, LiteralNumberFloat, Push("#pop", "expr-chain")}, - {`0x[0-9a-fA-F]+`, LiteralNumberHex, Push("#pop", "expr-chain")}, - {`[0-9]+`, LiteralNumberInteger, Push("#pop", "expr-chain")}, - {`'`, LiteralStringSingle, Push("#pop", "expr-chain", "string-single-interpol")}, - {`"`, LiteralStringDouble, Push("#pop", "expr-chain", "string-double")}, - {`~/(\\\\|\\/|[^/\n])*/[gimsu]*`, LiteralStringRegex, Push("#pop", "expr-chain")}, - {`\[`, Punctuation, Push("#pop", "expr-chain", "array-decl")}, - }, - "expr-chain": { - Include("spaces"), - {`(?:\+\+|\-\-)`, Operator, nil}, - {`(?:%=|&=|\|=|\^=|\+=|\-=|\*=|/=|<<=|>\s*>\s*=|>\s*>\s*>\s*=|==|!=|<=|>\s*=|&&|\|\||<<|>>>|>\s*>|\.\.\.|<|>|%|&|\||\^|\+|\*|/|\-|=>|=)`, Operator, Push("#pop", "expr")}, - {`(?:in)\b`, Keyword, Push("#pop", "expr")}, - {`\?`, Operator, Push("#pop", "expr", "ternary", "expr")}, - {`(\.)((?!(?:function|class|static|var|if|else|while|do|for|break|return|continue|extends|implements|import|switch|case|default|public|private|try|untyped|catch|new|this|throw|extern|enum|in|interface|cast|override|dynamic|typedef|package|inline|using|null|true|false|abstract)\b)(?:_*[a-z]\w*|_+[0-9]\w*|_*[A-Z]\w*|_+|\$\w+))`, ByGroups(Punctuation, Name), nil}, - {`\[`, Punctuation, Push("array-access")}, - {`\(`, Punctuation, Push("call")}, - Default(Pop(1)), - }, - "macro": { - Include("spaces"), - Include("meta"), - {`:`, Punctuation, Push("#pop", "type")}, - {`(?:extern|private)\b`, KeywordDeclaration, nil}, - {`(?:abstract)\b`, KeywordDeclaration, Push("#pop", "optional-semicolon", "abstract")}, - {`(?:class|interface)\b`, KeywordDeclaration, Push("#pop", "optional-semicolon", "macro-class")}, - {`(?:enum)\b`, KeywordDeclaration, Push("#pop", "optional-semicolon", "enum")}, - {`(?:typedef)\b`, KeywordDeclaration, Push("#pop", "optional-semicolon", "typedef")}, - Default(Pop(1), Push("expr")), - }, - "macro-class": { - {`\{`, Punctuation, Push("#pop", "class-body")}, - Include("class"), - }, - "cast": { - Include("spaces"), - {`\(`, Punctuation, Push("#pop", "parenthesis-close", "cast-type", "expr")}, - Default(Pop(1), Push("expr")), - }, - "cast-type": { - Include("spaces"), - {`,`, Punctuation, Push("#pop", "type")}, - Default(Pop(1)), - }, - "catch": { - Include("spaces"), - {`(?:catch)\b`, Keyword, Push("expr", "function-param", "parenthesis-open")}, - Default(Pop(1)), - }, - "do": { - Include("spaces"), - Default(Pop(1), Push("do-while"), Push("expr")), - }, - "do-while": { - Include("spaces"), - {`(?:while)\b`, Keyword, Push("#pop", "parenthesis", "parenthesis-open")}, - }, - "while": { - Include("spaces"), - {`\(`, Punctuation, Push("#pop", "expr", "parenthesis")}, - }, - "for": { - Include("spaces"), - {`\(`, Punctuation, Push("#pop", "expr", "parenthesis")}, - }, - "if": { - Include("spaces"), - {`\(`, Punctuation, Push("#pop", "else", "optional-semicolon", "expr", "parenthesis")}, - }, - "else": { - Include("spaces"), - {`(?:else)\b`, Keyword, Push("#pop", "expr")}, - Default(Pop(1)), - }, - "switch": { - Include("spaces"), - Default(Pop(1), Push("switch-body"), Push("bracket-open"), Push("expr")), - }, - "switch-body": { - Include("spaces"), - {`(?:case|default)\b`, Keyword, Push("case-block", "case")}, - {`\}`, Punctuation, Pop(1)}, - }, - "case": { - Include("spaces"), - {`:`, Punctuation, Pop(1)}, - Default(Pop(1), Push("case-sep"), Push("case-guard"), Push("expr")), - }, - "case-sep": { - Include("spaces"), - {`:`, Punctuation, Pop(1)}, - {`,`, Punctuation, Push("#pop", "case")}, - }, - "case-guard": { - Include("spaces"), - {`(?:if)\b`, Keyword, Push("#pop", "parenthesis", "parenthesis-open")}, - Default(Pop(1)), - }, - "case-block": { - Include("spaces"), - {`(?!(?:case|default)\b|\})`, Keyword, Push("expr-statement")}, - Default(Pop(1)), - }, - "new": { - Include("spaces"), - Default(Pop(1), Push("call"), Push("parenthesis-open"), Push("type")), - }, - "array-decl": { - Include("spaces"), - {`\]`, Punctuation, Pop(1)}, - Default(Pop(1), Push("array-decl-sep"), Push("expr")), - }, - "array-decl-sep": { - Include("spaces"), - {`\]`, Punctuation, Pop(1)}, - {`,`, Punctuation, Push("#pop", "array-decl")}, - }, - "array-access": { - Include("spaces"), - Default(Pop(1), Push("array-access-close"), Push("expr")), - }, - "array-access-close": { - Include("spaces"), - {`\]`, Punctuation, Pop(1)}, - }, - "comma": { - Include("spaces"), - {`,`, Punctuation, Pop(1)}, - }, - "colon": { - Include("spaces"), - {`:`, Punctuation, Pop(1)}, - }, - "semicolon": { - Include("spaces"), - {`;`, Punctuation, Pop(1)}, - }, - "optional-semicolon": { - Include("spaces"), - {`;`, Punctuation, Pop(1)}, - Default(Pop(1)), - }, - "ident": { - Include("spaces"), - {`(?:_*[a-z]\w*|_+[0-9]\w*|_*[A-Z]\w*|_+|\$\w+)`, Name, Pop(1)}, - }, - "dollar": { - Include("spaces"), - {`\{`, Punctuation, Push("#pop", "expr-chain", "bracket-close", "expr")}, - Default(Pop(1), Push("expr-chain")), - }, - "type-name": { - Include("spaces"), - {`_*[A-Z]\w*`, Name, Pop(1)}, - }, - "type-full-name": { - Include("spaces"), - {`\.`, Punctuation, Push("ident")}, - Default(Pop(1)), - }, - "type": { - Include("spaces"), - {`\?`, Punctuation, nil}, - {`(?:_*[a-z]\w*|_+[0-9]\w*|_*[A-Z]\w*|_+|\$\w+)`, Name, Push("#pop", "type-check", "type-full-name")}, - {`\{`, Punctuation, Push("#pop", "type-check", "type-struct")}, - {`\(`, Punctuation, Push("#pop", "type-check", "type-parenthesis")}, - }, - "type-parenthesis": { - Include("spaces"), - Default(Pop(1), Push("parenthesis-close"), Push("type")), - }, - "type-check": { - Include("spaces"), - {`->`, Punctuation, Push("#pop", "type")}, - {`<(?!=)`, Punctuation, Push("type-param")}, - Default(Pop(1)), - }, - "type-struct": { - Include("spaces"), - {`\}`, Punctuation, Pop(1)}, - {`\?`, Punctuation, nil}, - {`>`, Punctuation, Push("comma", "type")}, - {`(?!(?:function|class|static|var|if|else|while|do|for|break|return|continue|extends|implements|import|switch|case|default|public|private|try|untyped|catch|new|this|throw|extern|enum|in|interface|cast|override|dynamic|typedef|package|inline|using|null|true|false|abstract)\b)(?:_*[a-z]\w*|_+[0-9]\w*|_*[A-Z]\w*|_+|\$\w+)`, Name, Push("#pop", "type-struct-sep", "type", "colon")}, - Include("class-body"), - }, - "type-struct-sep": { - Include("spaces"), - {`\}`, Punctuation, Pop(1)}, - {`,`, Punctuation, Push("#pop", "type-struct")}, - }, - "type-param-type": { - {`\.[0-9]+`, LiteralNumberFloat, Pop(1)}, - {`[0-9]+[eE][+\-]?[0-9]+`, LiteralNumberFloat, Pop(1)}, - {`[0-9]+\.[0-9]*[eE][+\-]?[0-9]+`, LiteralNumberFloat, Pop(1)}, - {`[0-9]+\.[0-9]+`, LiteralNumberFloat, Pop(1)}, - {`[0-9]+\.(?!(?:_*[a-z]\w*|_+[0-9]\w*|_*[A-Z]\w*|_+|\$\w+)|\.\.)`, LiteralNumberFloat, Pop(1)}, - {`0x[0-9a-fA-F]+`, LiteralNumberHex, Pop(1)}, - {`[0-9]+`, LiteralNumberInteger, Pop(1)}, - {`'`, LiteralStringSingle, Push("#pop", "string-single")}, - {`"`, LiteralStringDouble, Push("#pop", "string-double")}, - {`~/(\\\\|\\/|[^/\n])*/[gim]*`, LiteralStringRegex, Pop(1)}, - {`\[`, Operator, Push("#pop", "array-decl")}, - Include("type"), - }, - "type-param": { - Include("spaces"), - Default(Pop(1), Push("type-param-sep"), Push("type-param-type")), - }, - "type-param-sep": { - Include("spaces"), - {`>`, Punctuation, Pop(1)}, - {`,`, Punctuation, Push("#pop", "type-param")}, - }, - "type-param-constraint": { - Include("spaces"), - {`<(?!=)`, Punctuation, Push("#pop", "type-param-constraint-sep", "type-param-constraint-flag", "type-name")}, - Default(Pop(1)), - }, - "type-param-constraint-sep": { - Include("spaces"), - {`>`, Punctuation, Pop(1)}, - {`,`, Punctuation, Push("#pop", "type-param-constraint-sep", "type-param-constraint-flag", "type-name")}, - }, - "type-param-constraint-flag": { - Include("spaces"), - {`:`, Punctuation, Push("#pop", "type-param-constraint-flag-type")}, - Default(Pop(1)), - }, - "type-param-constraint-flag-type": { - Include("spaces"), - {`\(`, Punctuation, Push("#pop", "type-param-constraint-flag-type-sep", "type")}, - Default(Pop(1), Push("type")), - }, - "type-param-constraint-flag-type-sep": { - Include("spaces"), - {`\)`, Punctuation, Pop(1)}, - {`,`, Punctuation, Push("type")}, - }, - "parenthesis": { - Include("spaces"), - Default(Pop(1), Push("parenthesis-close"), Push("flag"), Push("expr")), - }, - "parenthesis-open": { - Include("spaces"), - {`\(`, Punctuation, Pop(1)}, - }, - "parenthesis-close": { - Include("spaces"), - {`\)`, Punctuation, Pop(1)}, - }, - "var": { - Include("spaces"), - {`(?!(?:function|class|static|var|if|else|while|do|for|break|return|continue|extends|implements|import|switch|case|default|public|private|try|untyped|catch|new|this|throw|extern|enum|in|interface|cast|override|dynamic|typedef|package|inline|using|null|true|false|abstract)\b)(?:_*[a-z]\w*|_+[0-9]\w*|_*[A-Z]\w*|_+|\$\w+)`, Text, Push("#pop", "var-sep", "assign", "flag", "prop-get-set")}, - }, - "var-sep": { - Include("spaces"), - {`,`, Punctuation, Push("#pop", "var")}, - Default(Pop(1)), - }, - "assign": { - Include("spaces"), - {`=`, Operator, Push("#pop", "expr")}, - Default(Pop(1)), - }, - "flag": { - Include("spaces"), - {`:`, Punctuation, Push("#pop", "type")}, - Default(Pop(1)), - }, - "ternary": { - Include("spaces"), - {`:`, Operator, Pop(1)}, - }, - "call": { - Include("spaces"), - {`\)`, Punctuation, Pop(1)}, - Default(Pop(1), Push("call-sep"), Push("expr")), - }, - "call-sep": { - Include("spaces"), - {`\)`, Punctuation, Pop(1)}, - {`,`, Punctuation, Push("#pop", "call")}, - }, - "bracket": { - Include("spaces"), - {`(?!(?:\$\s*[a-z]\b|\$(?!(?:_*[a-z]\w*|_+[0-9]\w*|_*[A-Z]\w*|_+|\$\w+))))(?!(?:function|class|static|var|if|else|while|do|for|break|return|continue|extends|implements|import|switch|case|default|public|private|try|untyped|catch|new|this|throw|extern|enum|in|interface|cast|override|dynamic|typedef|package|inline|using|null|true|false|abstract)\b)(?:_*[a-z]\w*|_+[0-9]\w*|_*[A-Z]\w*|_+|\$\w+)`, Name, Push("#pop", "bracket-check")}, - {`'`, LiteralStringSingle, Push("#pop", "bracket-check", "string-single")}, - {`"`, LiteralStringDouble, Push("#pop", "bracket-check", "string-double")}, - Default(Pop(1), Push("block")), - }, - "bracket-check": { - Include("spaces"), - {`:`, Punctuation, Push("#pop", "object-sep", "expr")}, - Default(Pop(1), Push("block"), Push("optional-semicolon"), Push("expr-chain")), - }, - "block": { - Include("spaces"), - {`\}`, Punctuation, Pop(1)}, - Default(Push("expr-statement")), - }, - "object": { - Include("spaces"), - {`\}`, Punctuation, Pop(1)}, - Default(Pop(1), Push("object-sep"), Push("expr"), Push("colon"), Push("ident-or-string")), - }, - "ident-or-string": { - Include("spaces"), - {`(?!(?:function|class|static|var|if|else|while|do|for|break|return|continue|extends|implements|import|switch|case|default|public|private|try|untyped|catch|new|this|throw|extern|enum|in|interface|cast|override|dynamic|typedef|package|inline|using|null|true|false|abstract)\b)(?:_*[a-z]\w*|_+[0-9]\w*|_*[A-Z]\w*|_+|\$\w+)`, Name, Pop(1)}, - {`'`, LiteralStringSingle, Push("#pop", "string-single")}, - {`"`, LiteralStringDouble, Push("#pop", "string-double")}, - }, - "object-sep": { - Include("spaces"), - {`\}`, Punctuation, Pop(1)}, - {`,`, Punctuation, Push("#pop", "object")}, - }, - } -} - -func haxePreProcMutator(state *LexerState) error { - stack, ok := state.Get("haxe-pre-proc").([][]string) - if !ok { - stack = [][]string{} - } - - proc := state.Groups[2] - switch proc { - case "if": - stack = append(stack, state.Stack) - case "else", "elseif": - if len(stack) > 0 { - state.Stack = stack[len(stack)-1] - } - case "end": - if len(stack) > 0 { - stack = stack[:len(stack)-1] - } - } - - if proc == "if" || proc == "elseif" { - state.Stack = append(state.Stack, "preproc-expr") - } - - if proc == "error" { - state.Stack = append(state.Stack, "preproc-error") - } - state.Set("haxe-pre-proc", stack) - return nil -} diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/html.go b/vendor/github.com/alecthomas/chroma/v2/lexers/html.go deleted file mode 100644 index c858042bf9..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/html.go +++ /dev/null @@ -1,8 +0,0 @@ -package lexers - -import ( - "github.com/alecthomas/chroma/v2" -) - -// HTML lexer. -var HTML = chroma.MustNewXMLLexer(embedded, "embedded/html.xml") diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/http.go b/vendor/github.com/alecthomas/chroma/v2/lexers/http.go deleted file mode 100644 index b57cb1b84e..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/http.go +++ /dev/null @@ -1,131 +0,0 @@ -package lexers - -import ( - "strings" - - . "github.com/alecthomas/chroma/v2" // nolint -) - -// HTTP lexer. -var HTTP = Register(httpBodyContentTypeLexer(MustNewLexer( - &Config{ - Name: "HTTP", - Aliases: []string{"http"}, - Filenames: []string{}, - MimeTypes: []string{}, - NotMultiline: true, - DotAll: true, - }, - httpRules, -))) - -func httpRules() Rules { - return Rules{ - "root": { - {`(GET|POST|PUT|DELETE|HEAD|OPTIONS|TRACE|PATCH|CONNECT)( +)([^ ]+)( +)(HTTP)(/)([123](?:\.[01])?)(\r?\n|\Z)`, ByGroups(NameFunction, Text, NameNamespace, Text, KeywordReserved, Operator, LiteralNumber, Text), Push("headers")}, - {`(HTTP)(/)([123](?:\.[01])?)( +)(\d{3})( *)([^\r\n]*)(\r?\n|\Z)`, ByGroups(KeywordReserved, Operator, LiteralNumber, Text, LiteralNumber, Text, NameException, Text), Push("headers")}, - }, - "headers": { - {`([^\s:]+)( *)(:)( *)([^\r\n]+)(\r?\n|\Z)`, EmitterFunc(httpHeaderBlock), nil}, - {`([\t ]+)([^\r\n]+)(\r?\n|\Z)`, EmitterFunc(httpContinuousHeaderBlock), nil}, - {`\r?\n`, Text, Push("content")}, - }, - "content": { - {`.+`, EmitterFunc(httpContentBlock), nil}, - }, - } -} - -func httpContentBlock(groups []string, state *LexerState) Iterator { - tokens := []Token{ - {Generic, groups[0]}, - } - return Literator(tokens...) -} - -func httpHeaderBlock(groups []string, state *LexerState) Iterator { - tokens := []Token{ - {Name, groups[1]}, - {Text, groups[2]}, - {Operator, groups[3]}, - {Text, groups[4]}, - {Literal, groups[5]}, - {Text, groups[6]}, - } - return Literator(tokens...) -} - -func httpContinuousHeaderBlock(groups []string, state *LexerState) Iterator { - tokens := []Token{ - {Text, groups[1]}, - {Literal, groups[2]}, - {Text, groups[3]}, - } - return Literator(tokens...) -} - -func httpBodyContentTypeLexer(lexer Lexer) Lexer { return &httpBodyContentTyper{lexer} } - -type httpBodyContentTyper struct{ Lexer } - -func (d *httpBodyContentTyper) Tokenise(options *TokeniseOptions, text string) (Iterator, error) { // nolint: gocognit - var contentType string - var isContentType bool - var subIterator Iterator - - it, err := d.Lexer.Tokenise(options, text) - if err != nil { - return nil, err - } - - return func() Token { - token := it() - - if token == EOF { - if subIterator != nil { - return subIterator() - } - return EOF - } - - switch { - case token.Type == Name && strings.ToLower(token.Value) == "content-type": - { - isContentType = true - } - case token.Type == Literal && isContentType: - { - isContentType = false - contentType = strings.TrimSpace(token.Value) - pos := strings.Index(contentType, ";") - if pos > 0 { - contentType = strings.TrimSpace(contentType[:pos]) - } - } - case token.Type == Generic && contentType != "": - { - lexer := MatchMimeType(contentType) - - // application/calendar+xml can be treated as application/xml - // if there's not a better match. - if lexer == nil && strings.Contains(contentType, "+") { - slashPos := strings.Index(contentType, "/") - plusPos := strings.LastIndex(contentType, "+") - contentType = contentType[:slashPos+1] + contentType[plusPos+1:] - lexer = MatchMimeType(contentType) - } - - if lexer == nil { - token.Type = Text - } else { - subIterator, err = lexer.Tokenise(nil, token.Value) - if err != nil { - panic(err) - } - return EOF - } - } - } - return token - }, nil -} diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/lexers.go b/vendor/github.com/alecthomas/chroma/v2/lexers/lexers.go deleted file mode 100644 index bef42edecc..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/lexers.go +++ /dev/null @@ -1,85 +0,0 @@ -package lexers - -import ( - "embed" - "io/fs" - - "github.com/alecthomas/chroma/v2" -) - -//go:embed embedded -var embedded embed.FS - -// GlobalLexerRegistry is the global LexerRegistry of Lexers. -var GlobalLexerRegistry = func() *chroma.LexerRegistry { - reg := chroma.NewLexerRegistry() - // index(reg) - paths, err := fs.Glob(embedded, "embedded/*.xml") - if err != nil { - panic(err) - } - for _, path := range paths { - reg.Register(chroma.MustNewXMLLexer(embedded, path)) - } - return reg -}() - -// Names of all lexers, optionally including aliases. -func Names(withAliases bool) []string { - return GlobalLexerRegistry.Names(withAliases) -} - -// Aliases of all the lexers, and skip those lexers who do not have any aliases, -// or show their name instead -func Aliases(skipWithoutAliases bool) []string { - return GlobalLexerRegistry.Aliases(skipWithoutAliases) -} - -// Get a Lexer by name, alias or file extension. -// -// Note that this if there isn't an exact match on name or alias, this will -// call Match(), so it is not efficient. -func Get(name string) chroma.Lexer { - return GlobalLexerRegistry.Get(name) -} - -// MatchMimeType attempts to find a lexer for the given MIME type. -func MatchMimeType(mimeType string) chroma.Lexer { - return GlobalLexerRegistry.MatchMimeType(mimeType) -} - -// Match returns the first lexer matching filename. -// -// Note that this iterates over all file patterns in all lexers, so it's not -// particularly efficient. -func Match(filename string) chroma.Lexer { - return GlobalLexerRegistry.Match(filename) -} - -// Register a Lexer with the global registry. -func Register(lexer chroma.Lexer) chroma.Lexer { - return GlobalLexerRegistry.Register(lexer) -} - -// Analyse text content and return the "best" lexer.. -func Analyse(text string) chroma.Lexer { - return GlobalLexerRegistry.Analyse(text) -} - -// PlaintextRules is used for the fallback lexer as well as the explicit -// plaintext lexer. -func PlaintextRules() chroma.Rules { - return chroma.Rules{ - "root": []chroma.Rule{ - {`.+`, chroma.Text, nil}, - {`\n`, chroma.Text, nil}, - }, - } -} - -// Fallback lexer if no other is found. -var Fallback chroma.Lexer = chroma.MustNewLexer(&chroma.Config{ - Name: "fallback", - Filenames: []string{"*"}, - Priority: -1, -}, PlaintextRules) diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/markdown.go b/vendor/github.com/alecthomas/chroma/v2/lexers/markdown.go deleted file mode 100644 index bcd5b17841..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/markdown.go +++ /dev/null @@ -1,46 +0,0 @@ -package lexers - -import ( - . "github.com/alecthomas/chroma/v2" // nolint -) - -// Markdown lexer. -var Markdown = Register(MustNewLexer( - &Config{ - Name: "markdown", - Aliases: []string{"md", "mkd"}, - Filenames: []string{"*.md", "*.mkd", "*.markdown"}, - MimeTypes: []string{"text/x-markdown"}, - }, - markdownRules, -)) - -func markdownRules() Rules { - return Rules{ - "root": { - {`^(#[^#].+\n)`, ByGroups(GenericHeading), nil}, - {`^(#{2,6}.+\n)`, ByGroups(GenericSubheading), nil}, - {`^(\s*)([*-] )(\[[ xX]\])( .+\n)`, ByGroups(Text, Keyword, Keyword, UsingSelf("inline")), nil}, - {`^(\s*)([*-])(\s)(.+\n)`, ByGroups(Text, Keyword, Text, UsingSelf("inline")), nil}, - {`^(\s*)([0-9]+\.)( .+\n)`, ByGroups(Text, Keyword, UsingSelf("inline")), nil}, - {`^(\s*>\s)(.+\n)`, ByGroups(Keyword, GenericEmph), nil}, - {"^(```\\n)([\\w\\W]*?)(^```$)", ByGroups(String, Text, String), nil}, - { - "^(```)(\\w+)(\\n)([\\w\\W]*?)(^```$)", - UsingByGroup(2, 4, String, String, String, Text, String), - nil, - }, - Include("inline"), - }, - "inline": { - {`\\.`, Text, nil}, - {`(\s)(\*|_)((?:(?!\2).)*)(\2)((?=\W|\n))`, ByGroups(Text, GenericEmph, GenericEmph, GenericEmph, Text), nil}, - {`(\s)((\*\*|__).*?)\3((?=\W|\n))`, ByGroups(Text, GenericStrong, GenericStrong, Text), nil}, - {`(\s)(~~[^~]+~~)((?=\W|\n))`, ByGroups(Text, GenericDeleted, Text), nil}, - {"`[^`]+`", LiteralStringBacktick, nil}, - {`[@#][\w/:]+`, NameEntity, nil}, - {`(!?\[)([^]]+)(\])(\()([^)]+)(\))`, ByGroups(Text, NameTag, Text, Text, NameAttribute, Text), nil}, - {`.|\n`, Text, nil}, - }, - } -} diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/mysql.go b/vendor/github.com/alecthomas/chroma/v2/lexers/mysql.go deleted file mode 100644 index 32e94c2f2e..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/mysql.go +++ /dev/null @@ -1,33 +0,0 @@ -package lexers - -import ( - "regexp" -) - -var ( - mysqlAnalyserNameBetweenBacktickRe = regexp.MustCompile("`[a-zA-Z_]\\w*`") - mysqlAnalyserNameBetweenBracketRe = regexp.MustCompile(`\[[a-zA-Z_]\w*\]`) -) - -func init() { // nolint: gochecknoinits - Get("mysql"). - SetAnalyser(func(text string) float32 { - nameBetweenBacktickCount := len(mysqlAnalyserNameBetweenBacktickRe.FindAllString(text, -1)) - nameBetweenBracketCount := len(mysqlAnalyserNameBetweenBracketRe.FindAllString(text, -1)) - - var result float32 - - // Same logic as above in the TSQL analysis. - dialectNameCount := nameBetweenBacktickCount + nameBetweenBracketCount - if dialectNameCount >= 1 && nameBetweenBacktickCount >= (2*nameBetweenBracketCount) { - // Found at least twice as many `name` as [name]. - result += 0.5 - } else if nameBetweenBacktickCount > nameBetweenBracketCount { - result += 0.2 - } else if nameBetweenBacktickCount > 0 { - result += 0.1 - } - - return result - }) -} diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/php.go b/vendor/github.com/alecthomas/chroma/v2/lexers/php.go deleted file mode 100644 index ff82f6eafa..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/php.go +++ /dev/null @@ -1,37 +0,0 @@ -package lexers - -import ( - "strings" - - . "github.com/alecthomas/chroma/v2" // nolint -) - -// phtml lexer is PHP in HTML. -var _ = Register(DelegatingLexer(HTML, MustNewLexer( - &Config{ - Name: "PHTML", - Aliases: []string{"phtml"}, - Filenames: []string{"*.phtml", "*.php", "*.php[345]", "*.inc"}, - MimeTypes: []string{"application/x-php", "application/x-httpd-php", "application/x-httpd-php3", "application/x-httpd-php4", "application/x-httpd-php5", "text/x-php"}, - DotAll: true, - CaseInsensitive: true, - EnsureNL: true, - Priority: 2, - }, - func() Rules { - return Get("PHP").(*RegexLexer).MustRules(). - Rename("root", "php"). - Merge(Rules{ - "root": { - {`<\?(php)?`, CommentPreproc, Push("php")}, - {`[^<]+`, Other, nil}, - {`<`, Other, nil}, - }, - }) - }, -).SetAnalyser(func(text string) float32 { - if strings.Contains(text, ">|>|»|\)|\]|\})` - colonPairPattern = `(?:)(?\w[\w'-]*)(?` + colonPairOpeningBrackets + `)` - colonPairLookahead = `(?=(:['\w-]+` + - colonPairOpeningBrackets + `.+?` + colonPairClosingBrackets + `)?` - namePattern = `(?:(?!` + colonPairPattern + `)(?:::|[\w':-]))+` - variablePattern = `[$@%&]+[.^:?=!~]?` + namePattern - globalVariablePattern = `[$@%&]+\*` + namePattern - ) - - keywords := []string{ - `BEGIN`, `CATCH`, `CHECK`, `CLOSE`, `CONTROL`, `DOC`, `END`, `ENTER`, `FIRST`, `INIT`, - `KEEP`, `LAST`, `LEAVE`, `NEXT`, `POST`, `PRE`, `QUIT`, `UNDO`, `anon`, `augment`, `but`, - `class`, `constant`, `default`, `does`, `else`, `elsif`, `enum`, `for`, `gather`, `given`, - `grammar`, `has`, `if`, `import`, `is`, `of`, `let`, `loop`, `made`, `make`, `method`, - `module`, `multi`, `my`, `need`, `orwith`, `our`, `proceed`, `proto`, `repeat`, `require`, - `where`, `return`, `return-rw`, `returns`, `->`, `-->`, `role`, `state`, `sub`, `no`, - `submethod`, `subset`, `succeed`, `supersede`, `try`, `unit`, `unless`, `until`, - `use`, `when`, `while`, `with`, `without`, `export`, `native`, `repr`, `required`, `rw`, - `symbol`, `default`, `cached`, `DEPRECATED`, `dynamic`, `hidden-from-backtrace`, `nodal`, - `pure`, `raw`, `start`, `react`, `supply`, `whenever`, `also`, `rule`, `token`, `regex`, - `dynamic-scope`, `built`, `temp`, - } - - keywordsPattern := Words(`(?)`, `(>=)`, `minmax`, `notandthen`, `S`, - } - - wordOperatorsPattern := Words(`(?<=^|\b|\s)`, `(?=$|\b|\s)`, wordOperators...) - - operators := []string{ - `++`, `--`, `-`, `**`, `!`, `+`, `~`, `?`, `+^`, `~^`, `?^`, `^`, `*`, `/`, `%`, `%%`, `+&`, - `+<`, `+>`, `~&`, `~<`, `~>`, `?&`, `+|`, `+^`, `~|`, `~^`, `?`, `?|`, `?^`, `&`, `^`, - `<=>`, `^…^`, `^…`, `…^`, `…`, `...`, `...^`, `^...`, `^...^`, `..`, `..^`, `^..`, `^..^`, - `::=`, `:=`, `!=`, `==`, `<=`, `<`, `>=`, `>`, `~~`, `===`, `&&`, `||`, `|`, `^^`, `//`, - `??`, `!!`, `^fff^`, `^ff^`, `<==`, `==>`, `<<==`, `==>>`, `=>`, `=`, `<<`, `«`, `>>`, `»`, - `,`, `>>.`, `».`, `.&`, `.=`, `.^`, `.?`, `.+`, `.*`, `.`, `∘`, `∩`, `⊍`, `∪`, `⊎`, `∖`, - `⊖`, `≠`, `≤`, `≥`, `=:=`, `=~=`, `≅`, `∈`, `∉`, `≡`, `≢`, `∋`, `∌`, `⊂`, `⊄`, `⊆`, `⊈`, - `⊃`, `⊅`, `⊇`, `⊉`, `:`, `!!!`, `???`, `¯`, `×`, `÷`, `−`, `⁺`, `⁻`, - } - - operatorsPattern := Words(``, ``, operators...) - - builtinTypes := []string{ - `False`, `True`, `Order`, `More`, `Less`, `Same`, `Any`, `Array`, `Associative`, `AST`, - `atomicint`, `Attribute`, `Backtrace`, `Backtrace::Frame`, `Bag`, `Baggy`, `BagHash`, - `Blob`, `Block`, `Bool`, `Buf`, `Callable`, `CallFrame`, `Cancellation`, `Capture`, - `CArray`, `Channel`, `Code`, `compiler`, `Complex`, `ComplexStr`, `CompUnit`, - `CompUnit::PrecompilationRepository`, `CompUnit::Repository`, `Empty`, - `CompUnit::Repository::FileSystem`, `CompUnit::Repository::Installation`, `Cool`, - `CurrentThreadScheduler`, `CX::Warn`, `CX::Take`, `CX::Succeed`, `CX::Return`, `CX::Redo`, - `CX::Proceed`, `CX::Next`, `CX::Last`, `CX::Emit`, `CX::Done`, `Cursor`, `Date`, `Dateish`, - `DateTime`, `Distribution`, `Distribution::Hash`, `Distribution::Locally`, - `Distribution::Path`, `Distribution::Resource`, `Distro`, `Duration`, `Encoding`, - `Encoding::GlobalLexerRegistry`, `Endian`, `Enumeration`, `Exception`, `Failure`, `FatRat`, `Grammar`, - `Hash`, `HyperWhatever`, `Instant`, `Int`, `int`, `int16`, `int32`, `int64`, `int8`, `str`, - `IntStr`, `IO`, `IO::ArgFiles`, `IO::CatHandle`, `IO::Handle`, `IO::Notification`, - `IO::Notification::Change`, `IO::Path`, `IO::Path::Cygwin`, `IO::Path::Parts`, - `IO::Path::QNX`, `IO::Path::Unix`, `IO::Path::Win32`, `IO::Pipe`, `IO::Socket`, - `IO::Socket::Async`, `IO::Socket::Async::ListenSocket`, `IO::Socket::INET`, `IO::Spec`, - `IO::Spec::Cygwin`, `IO::Spec::QNX`, `IO::Spec::Unix`, `IO::Spec::Win32`, `IO::Special`, - `Iterable`, `Iterator`, `Junction`, `Kernel`, `Label`, `List`, `Lock`, `Lock::Async`, - `Lock::ConditionVariable`, `long`, `longlong`, `Macro`, `Map`, `Match`, - `Metamodel::AttributeContainer`, `Metamodel::C3MRO`, `Metamodel::ClassHOW`, - `Metamodel::ConcreteRoleHOW`, `Metamodel::CurriedRoleHOW`, `Metamodel::DefiniteHOW`, - `Metamodel::Documenting`, `Metamodel::EnumHOW`, `Metamodel::Finalization`, - `Metamodel::MethodContainer`, `Metamodel::Mixins`, `Metamodel::MROBasedMethodDispatch`, - `Metamodel::MultipleInheritance`, `Metamodel::Naming`, `Metamodel::Primitives`, - `Metamodel::PrivateMethodContainer`, `Metamodel::RoleContainer`, `Metamodel::RolePunning`, - `Metamodel::Stashing`, `Metamodel::Trusting`, `Metamodel::Versioning`, `Method`, `Mix`, - `MixHash`, `Mixy`, `Mu`, `NFC`, `NFD`, `NFKC`, `NFKD`, `Nil`, `Num`, `num32`, `num64`, - `Numeric`, `NumStr`, `ObjAt`, `Order`, `Pair`, `Parameter`, `Perl`, `Pod::Block`, - `Pod::Block::Code`, `Pod::Block::Comment`, `Pod::Block::Declarator`, `Pod::Block::Named`, - `Pod::Block::Para`, `Pod::Block::Table`, `Pod::Heading`, `Pod::Item`, `Pointer`, - `Positional`, `PositionalBindFailover`, `Proc`, `Proc::Async`, `Promise`, `Proxy`, - `PseudoStash`, `QuantHash`, `RaceSeq`, `Raku`, `Range`, `Rat`, `Rational`, `RatStr`, - `Real`, `Regex`, `Routine`, `Routine::WrapHandle`, `Scalar`, `Scheduler`, `Semaphore`, - `Seq`, `Sequence`, `Set`, `SetHash`, `Setty`, `Signature`, `size_t`, `Slip`, `Stash`, - `Str`, `StrDistance`, `Stringy`, `Sub`, `Submethod`, `Supplier`, `Supplier::Preserving`, - `Supply`, `Systemic`, `Tap`, `Telemetry`, `Telemetry::Instrument::Thread`, - `Telemetry::Instrument::ThreadPool`, `Telemetry::Instrument::Usage`, `Telemetry::Period`, - `Telemetry::Sampler`, `Thread`, `Test`, `ThreadPoolScheduler`, `UInt`, `uint16`, `uint32`, - `uint64`, `uint8`, `Uni`, `utf8`, `ValueObjAt`, `Variable`, `Version`, `VM`, `Whatever`, - `WhateverCode`, `WrapHandle`, `NativeCall`, - // Pragmas - `precompilation`, `experimental`, `worries`, `MONKEY-TYPING`, `MONKEY-SEE-NO-EVAL`, - `MONKEY-GUTS`, `fatal`, `lib`, `isms`, `newline`, `nqp`, `soft`, - `strict`, `trace`, `variables`, - } - - builtinTypesPattern := Words(`(? 0 { - if tokenClass == rakuPod { - match, err := podRegex.FindRunesMatchStartingAt(text, searchPos+nChars) - if err == nil { - closingChars = match.Runes() - nextClosePos = match.Index - } else { - nextClosePos = -1 - } - } else { - nextClosePos = indexAt(text, closingChars, searchPos+nChars) - } - - nextOpenPos := indexAt(text, openingChars, searchPos+nChars) - - switch { - case nextClosePos == -1: - nextClosePos = len(text) - nestingLevel = 0 - case nextOpenPos != -1 && nextOpenPos < nextClosePos: - nestingLevel++ - nChars = len(openingChars) - searchPos = nextOpenPos - default: // next_close_pos < next_open_pos - nestingLevel-- - nChars = len(closingChars) - searchPos = nextClosePos - } - } - - endPos = nextClosePos - } - - if endPos < 0 { - // if we didn't find a closer, just highlight the - // rest of the text in this class - endPos = len(text) - } - - adverbre := regexp.MustCompile(`:to\b|:heredoc\b`) - var heredocTerminator []rune - var endHeredocPos int - if adverbre.MatchString(string(adverbs)) { - if endPos != len(text) { - heredocTerminator = text[state.Pos:endPos] - nChars = len(heredocTerminator) - } else { - endPos = state.Pos + 1 - heredocTerminator = []rune{} - nChars = 0 - } - - if nChars > 0 { - endHeredocPos = indexAt(text[endPos:], heredocTerminator, 0) - if endHeredocPos > -1 { - endPos += endHeredocPos - } else { - endPos = len(text) - } - } - } - - textBetweenBrackets := string(text[state.Pos:endPos]) - switch tokenClass { - case rakuPod, rakuPodDeclaration, rakuNameAttribute: - state.NamedGroups[`value`] = textBetweenBrackets - state.NamedGroups[`closing_delimiters`] = string(closingChars) - case rakuQuote: - if len(heredocTerminator) > 0 { - // Length of heredoc terminator + closing chars + `;` - heredocFristPunctuationLen := nChars + len(openingChars) + 1 - - state.NamedGroups[`opening_delimiters`] = string(openingChars) + - string(text[state.Pos:state.Pos+heredocFristPunctuationLen]) - - state.NamedGroups[`value`] = - string(text[state.Pos+heredocFristPunctuationLen : endPos]) - - if endHeredocPos > -1 { - state.NamedGroups[`closing_delimiters`] = string(heredocTerminator) - } - } else { - state.NamedGroups[`value`] = textBetweenBrackets - if nChars > 0 { - state.NamedGroups[`closing_delimiters`] = string(closingChars) - } - } - default: - state.Groups = []string{state.Groups[0] + string(text[state.Pos:endPos+nChars])} - } - - state.Pos = endPos + nChars - - return nil - } - } - - // Raku rules - // Empty capture groups are placeholders and will be replaced by mutators - // DO NOT REMOVE THEM! - return Rules{ - "root": { - // Placeholder, will be overwritten by mutators, DO NOT REMOVE! - {`\A\z`, nil, nil}, - Include("common"), - {`{`, Punctuation, Push(`root`)}, - {`\(`, Punctuation, Push(`root`)}, - {`[)}]`, Punctuation, Pop(1)}, - {`;`, Punctuation, nil}, - {`\[|\]`, Operator, nil}, - {`.+?`, Text, nil}, - }, - "common": { - {`^#![^\n]*$`, CommentHashbang, nil}, - Include("pod"), - // Multi-line, Embedded comment - { - "#`(?(?" + bracketsPattern + `)\k*)`, - CommentMultiline, - findBrackets(rakuMultilineComment), - }, - {`#[^\n]*$`, CommentSingle, nil}, - // /regex/ - { - `(?<=(?:^|\(|=|:|~~|\[|{|,|=>)\s*)(/)(?!\]|\))((?:\\\\|\\/|.)*?)((?>)(\S+?)(<<)`, ByGroups(Operator, UsingSelf("root"), Operator), nil}, - {`(»)(\S+?)(«)`, ByGroups(Operator, UsingSelf("root"), Operator), nil}, - // Hyperoperator | «*« - {`(<<)(\S+?)(<<)`, ByGroups(Operator, UsingSelf("root"), Operator), nil}, - {`(«)(\S+?)(«)`, ByGroups(Operator, UsingSelf("root"), Operator), nil}, - // Hyperoperator | »*» - {`(>>)(\S+?)(>>)`, ByGroups(Operator, UsingSelf("root"), Operator), nil}, - {`(»)(\S+?)(»)`, ByGroups(Operator, UsingSelf("root"), Operator), nil}, - // <> - {`(?>)[^\n])+?[},;] *\n)(?!(?:(?!>>).)+?>>\S+?>>)`, Punctuation, Push("<<")}, - // «quoted words» - {`(? operators | something < onething > something - { - `(?<=[$@%&]?\w[\w':-]* +)(<=?)( *[^ ]+? *)(>=?)(?= *[$@%&]?\w[\w':-]*)`, - ByGroups(Operator, UsingSelf("root"), Operator), - nil, - }, - // - { - `(?])+?)(>)(?!\s*(?:\d+|\.(?:Int|Numeric)|[$@%]\*?\w[\w':-]*[^(]|\s+\[))`, - ByGroups(Punctuation, String, Punctuation), - nil, - }, - {`C?X::['\w:-]+`, NameException, nil}, - Include("metaoperator"), - // Pair | key => value - { - `(\w[\w'-]*)(\s*)(=>)`, - ByGroups(String, Text, Operator), - nil, - }, - Include("colon-pair"), - // Token - { - `(?<=(?:^|\s)(?:regex|token|rule)(\s+))` + namePattern + colonPairLookahead + `\s*[({])`, - NameFunction, - Push("token", "name-adverb"), - }, - // Substitution - {`(?<=^|\b|\s)(?(?:qq|q|Q))(?(?::?(?:heredoc|to|qq|ww|q|w|s|a|h|f|c|b|to|v|x))*)(?\s*)(?(?[^0-9a-zA-Z:\s])\k*)`, - EmitterFunc(quote), - findBrackets(rakuQuote), - }, - // Function - { - `\b` + namePattern + colonPairLookahead + `\()`, - NameFunction, - Push("name-adverb"), - }, - // Method - { - `(?(?[^\w:\s])\k*)`, - ByGroupNames( - map[string]Emitter{ - `opening_delimiters`: Punctuation, - `delimiter`: nil, - }, - ), - findBrackets(rakuMatchRegex), - }, - }, - "substitution": { - Include("colon-pair-attribute"), - // Substitution | s{regex} = value - { - `(?(?` + bracketsPattern + `)\k*)`, - ByGroupNames(map[string]Emitter{ - `opening_delimiters`: Punctuation, - `delimiter`: nil, - }), - findBrackets(rakuMatchRegex), - }, - // Substitution | s/regex/string/ - { - `(?[^\w:\s])`, - Punctuation, - findBrackets(rakuSubstitutionRegex), - }, - }, - "number": { - {`0_?[0-7]+(_[0-7]+)*`, LiteralNumberOct, nil}, - {`0x[0-9A-Fa-f]+(_[0-9A-Fa-f]+)*`, LiteralNumberHex, nil}, - {`0b[01]+(_[01]+)*`, LiteralNumberBin, nil}, - { - `(?i)(\d*(_\d*)*\.\d+(_\d*)*|\d+(_\d*)*\.\d+(_\d*)*)(e[+-]?\d+)?`, - LiteralNumberFloat, - nil, - }, - {`(?i)\d+(_\d*)*e[+-]?\d+(_\d*)*`, LiteralNumberFloat, nil}, - {`(?<=\d+)i`, NameConstant, nil}, - {`\d+(_\d+)*`, LiteralNumberInteger, nil}, - }, - "name-adverb": { - Include("colon-pair-attribute-keyvalue"), - Default(Pop(1)), - }, - "colon-pair": { - // :key(value) - {colonPairPattern, colonPair(String), findBrackets(rakuNameAttribute)}, - // :123abc - { - `(:)(\d+)(\w[\w'-]*)`, - ByGroups(Punctuation, UsingSelf("number"), String), - nil, - }, - // :key - {`(:)(!?)(\w[\w'-]*)`, ByGroups(Punctuation, Operator, String), nil}, - {`\s+`, Text, nil}, - }, - "colon-pair-attribute": { - // :key(value) - {colonPairPattern, colonPair(NameAttribute), findBrackets(rakuNameAttribute)}, - // :123abc - { - `(:)(\d+)(\w[\w'-]*)`, - ByGroups(Punctuation, UsingSelf("number"), NameAttribute), - nil, - }, - // :key - {`(:)(!?)(\w[\w'-]*)`, ByGroups(Punctuation, Operator, NameAttribute), nil}, - {`\s+`, Text, nil}, - }, - "colon-pair-attribute-keyvalue": { - // :key(value) - {colonPairPattern, colonPair(NameAttribute), findBrackets(rakuNameAttribute)}, - }, - "escape-qq": { - { - `(? - { - `(?`), - tokenType: Punctuation, - stateName: `root`, - pushState: true, - }), - }, - // {code} - Include(`closure`), - // Properties - {`(:)(\w+)`, ByGroups(Punctuation, NameAttribute), nil}, - // Operator - {`\|\||\||&&|&|\.\.|\*\*|%%|%|:|!|<<|«|>>|»|\+|\*\*|\*|\?|=|~|<~~>`, Operator, nil}, - // Anchors - {`\^\^|\^|\$\$|\$`, NameEntity, nil}, - {`\.`, NameEntity, nil}, - {`#[^\n]*\n`, CommentSingle, nil}, - // Lookaround - { - `(?`), - tokenType: Punctuation, - stateName: `regex`, - pushState: true, - }), - }, - { - `(?)`, - ByGroups(Punctuation, Operator, OperatorWord, Punctuation), - nil, - }, - // <$variable> - { - `(?)`, - ByGroups(Punctuation, Operator, NameVariable, Punctuation), - nil, - }, - // Capture markers - {`(?`, Operator, nil}, - { - `(? - {`(?`, Punctuation, Pop(1)}, - // - { - `\(`, - Punctuation, - replaceRule(ruleReplacingConfig{ - delimiter: []rune(`)>`), - tokenType: Punctuation, - stateName: `root`, - popState: true, - pushState: true, - }), - }, - // - { - `\s+`, - StringRegex, - replaceRule(ruleReplacingConfig{ - delimiter: []rune(`>`), - tokenType: Punctuation, - stateName: `regex`, - popState: true, - pushState: true, - }), - }, - // - { - `:`, - Punctuation, - replaceRule(ruleReplacingConfig{ - delimiter: []rune(`>`), - tokenType: Punctuation, - stateName: `root`, - popState: true, - pushState: true, - }), - }, - }, - "regex-variable": { - Include(`regex-starting-operators`), - // - {`(&)?(\w[\w':-]*)(>)`, ByGroups(Operator, NameFunction, Punctuation), Pop(1)}, - // `, Punctuation, Pop(1)}, - Include("regex-class-builtin"), - Include("variable"), - Include(`regex-starting-operators`), - Include("colon-pair-attribute"), - {`(?] - { - `\b([RZX]+)\b(\[)([^\s\]]+?)(\])`, - ByGroups(OperatorWord, Punctuation, UsingSelf("root"), Punctuation), - nil, - }, - // Z=> - {`\b([RZX]+)\b([^\s\]]+)`, ByGroups(OperatorWord, UsingSelf("operator")), nil}, - }, - "operator": { - // Word Operator - {wordOperatorsPattern, OperatorWord, nil}, - // Operator - {operatorsPattern, Operator, nil}, - }, - "pod": { - // Single-line pod declaration - {`(#[|=])\s`, Keyword, Push("pod-single")}, - // Multi-line pod declaration - { - "(?#[|=])(?(?" + bracketsPattern + `)\k*)(?)(?)`, - ByGroupNames( - map[string]Emitter{ - `keyword`: Keyword, - `opening_delimiters`: Punctuation, - `delimiter`: nil, - `value`: UsingSelf("pod-declaration"), - `closing_delimiters`: Punctuation, - }), - findBrackets(rakuPodDeclaration), - }, - Include("pod-blocks"), - }, - "pod-blocks": { - // =begin code - { - `(?<=^ *)(? *)(?=begin)(? +)(?code)(?[^\n]*)(?.*?)(?^\k)(?=end)(? +)\k`, - EmitterFunc(podCode), - nil, - }, - // =begin - { - `(?<=^ *)(? *)(?=begin)(? +)(?!code)(?\w[\w'-]*)(?[^\n]*)(?)(?)`, - ByGroupNames( - map[string]Emitter{ - `ws`: Comment, - `keyword`: Keyword, - `ws2`: StringDoc, - `name`: Keyword, - `config`: EmitterFunc(podConfig), - `value`: UsingSelf("pod-begin"), - `closing_delimiters`: Keyword, - }), - findBrackets(rakuPod), - }, - // =for ... - { - `(?<=^ *)(? *)(?=(?:for|defn))(? +)(?\w[\w'-]*)(?[^\n]*\n)`, - ByGroups(Comment, Keyword, StringDoc, Keyword, EmitterFunc(podConfig)), - Push("pod-paragraph"), - }, - // =config - { - `(?<=^ *)(? *)(?=config)(? +)(?\w[\w'-]*)(?[^\n]*\n)`, - ByGroups(Comment, Keyword, StringDoc, Keyword, EmitterFunc(podConfig)), - nil, - }, - // =alias - { - `(?<=^ *)(? *)(?=alias)(? +)(?\w[\w'-]*)(?[^\n]*\n)`, - ByGroups(Comment, Keyword, StringDoc, Keyword, StringDoc), - nil, - }, - // =encoding - { - `(?<=^ *)(? *)(?=encoding)(? +)(?[^\n]+)`, - ByGroups(Comment, Keyword, StringDoc, Name), - nil, - }, - // =para ... - { - `(?<=^ *)(? *)(?=(?:para|table|pod))(?(? *)(?=head\d+)(? *)(?#?)`, - ByGroups(Comment, Keyword, GenericHeading, Keyword), - Push("pod-heading"), - }, - // =item ... - { - `(?<=^ *)(? *)(?=(?:item\d*|comment|data|[A-Z]+))(? *)(?#?)`, - ByGroups(Comment, Keyword, StringDoc, Keyword), - Push("pod-paragraph"), - }, - { - `(?<=^ *)(? *)(?=finish)(?[^\n]*)`, - ByGroups(Comment, Keyword, EmitterFunc(podConfig)), - Push("pod-finish"), - }, - // ={custom} ... - { - `(?<=^ *)(? *)(?=\w[\w'-]*)(? *)(?#?)`, - ByGroups(Comment, Name, StringDoc, Keyword), - Push("pod-paragraph"), - }, - // = podconfig - { - `(?<=^ *)(? *=)(? *)(?(?::\w[\w'-]*(?:` + colonPairOpeningBrackets + `.+?` + - colonPairClosingBrackets + `) *)*\n)`, - ByGroups(Keyword, StringDoc, EmitterFunc(podConfig)), - nil, - }, - }, - "pod-begin": { - Include("pod-blocks"), - Include("pre-pod-formatter"), - {`.+?`, StringDoc, nil}, - }, - "pod-declaration": { - Include("pre-pod-formatter"), - {`.+?`, StringDoc, nil}, - }, - "pod-paragraph": { - {`\n *\n|\n(?=^ *=)`, StringDoc, Pop(1)}, - Include("pre-pod-formatter"), - {`.+?`, StringDoc, nil}, - }, - "pod-single": { - {`\n`, StringDoc, Pop(1)}, - Include("pre-pod-formatter"), - {`.+?`, StringDoc, nil}, - }, - "pod-heading": { - {`\n *\n|\n(?=^ *=)`, GenericHeading, Pop(1)}, - Include("pre-pod-formatter"), - {`.+?`, GenericHeading, nil}, - }, - "pod-finish": { - {`\z`, nil, Pop(1)}, - Include("pre-pod-formatter"), - {`.+?`, StringDoc, nil}, - }, - "pre-pod-formatter": { - // C, B, ... - { - `(?[CBIUDTKRPAELZVMSXN])(?<+|«)`, - ByGroups(Keyword, Punctuation), - findBrackets(rakuPodFormatter), - }, - }, - "pod-formatter": { - // Placeholder rule, will be replaced by mutators. DO NOT REMOVE! - {`>`, Punctuation, Pop(1)}, - Include("pre-pod-formatter"), - // Placeholder rule, will be replaced by mutators. DO NOT REMOVE! - {`.+?`, StringOther, nil}, - }, - "variable": { - {variablePattern, NameVariable, Push("name-adverb")}, - {globalVariablePattern, NameVariableGlobal, Push("name-adverb")}, - {`[$@]<[^>]+>`, NameVariable, nil}, - {`\$[/!¢]`, NameVariable, nil}, - {`[$@%]`, NameVariable, nil}, - }, - "single-quote": { - {`(?>(?!\s*(?:\d+|\.(?:Int|Numeric)|[$@%]\*?[\w':-]+|\s+\[))`, Punctuation, Pop(1)}, - Include("ww"), - }, - "«": { - {`»(?!\s*(?:\d+|\.(?:Int|Numeric)|[$@%]\*?[\w':-]+|\s+\[))`, Punctuation, Pop(1)}, - Include("ww"), - }, - "ww": { - Include("single-quote"), - Include("qq"), - }, - "qq": { - Include("qq-variable"), - Include("closure"), - Include(`escape-char`), - Include("escape-hexadecimal"), - Include("escape-c-name"), - Include("escape-qq"), - {`.+?`, StringDouble, nil}, - }, - "qq-variable": { - { - `(?\.)(?` + namePattern + `)` + colonPairLookahead + `\()`, - ByGroupNames(map[string]Emitter{ - `operator`: Operator, - `method_name`: NameFunction, - }), - Push(`name-adverb`), - }, - // Function/Signature - { - `\(`, Punctuation, replaceRule( - ruleReplacingConfig{ - delimiter: []rune(`)`), - tokenType: Punctuation, - stateName: `root`, - pushState: true, - }), - }, - Default(Pop(1)), - }, - "Q": { - Include("escape-qq"), - {`.+?`, String, nil}, - }, - "Q-closure": { - Include("escape-qq"), - Include("closure"), - {`.+?`, String, nil}, - }, - "Q-variable": { - Include("escape-qq"), - Include("qq-variable"), - {`.+?`, String, nil}, - }, - "closure": { - {`(? -1 { - idx = utf8.RuneCountInString(text[:idx]) - - // Search again if the substr is escaped with backslash - if (idx > 1 && strFromPos[idx-1] == '\\' && strFromPos[idx-2] != '\\') || - (idx == 1 && strFromPos[idx-1] == '\\') { - idx = indexAt(str[pos:], substr, idx+1) - - idx = utf8.RuneCountInString(text[:idx]) - - if idx < 0 { - return idx - } - } - idx += pos - } - - return idx -} - -type rulePosition int - -const ( - topRule rulePosition = 0 - iota - bottomRule -) - -type ruleMakingConfig struct { - delimiter []rune - pattern string - tokenType Emitter - mutator Mutator - numberOfDelimiterChars int -} - -type ruleReplacingConfig struct { - delimiter []rune - pattern string - tokenType Emitter - numberOfDelimiterChars int - mutator Mutator - appendMutator Mutator - rulePosition rulePosition - stateName string - pop bool - popState bool - pushState bool -} - -// Pops rule from state-stack and replaces the rule with the previous rule -func popRule(rule ruleReplacingConfig) MutatorFunc { - return func(state *LexerState) error { - stackName := genStackName(rule.stateName, rule.rulePosition) - - stack, ok := state.Get(stackName).([]ruleReplacingConfig) - - if ok && len(stack) > 0 { - // Pop from stack - stack = stack[:len(stack)-1] - lastRule := stack[len(stack)-1] - lastRule.pushState = false - lastRule.popState = false - lastRule.pop = true - state.Set(stackName, stack) - - // Call replaceRule to use the last rule - err := replaceRule(lastRule)(state) - if err != nil { - panic(err) - } - } - - return nil - } -} - -// Replaces a state's rule based on the rule config and position -func replaceRule(rule ruleReplacingConfig) MutatorFunc { - return func(state *LexerState) error { - stateName := rule.stateName - stackName := genStackName(rule.stateName, rule.rulePosition) - - stack, ok := state.Get(stackName).([]ruleReplacingConfig) - if !ok { - stack = []ruleReplacingConfig{} - } - - // If state-stack is empty fill it with the placeholder rule - if len(stack) == 0 { - stack = []ruleReplacingConfig{ - { - // Placeholder, will be overwritten by mutators, DO NOT REMOVE! - pattern: `\A\z`, - tokenType: nil, - mutator: nil, - stateName: stateName, - rulePosition: rule.rulePosition, - }, - } - state.Set(stackName, stack) - } - - var mutator Mutator - mutators := []Mutator{} - - switch { - case rule.rulePosition == topRule && rule.mutator == nil: - // Default mutator for top rule - mutators = []Mutator{Pop(1), popRule(rule)} - case rule.rulePosition == topRule && rule.mutator != nil: - // Default mutator for top rule, when rule.mutator is set - mutators = []Mutator{rule.mutator, popRule(rule)} - case rule.mutator != nil: - mutators = []Mutator{rule.mutator} - } - - if rule.appendMutator != nil { - mutators = append(mutators, rule.appendMutator) - } - - if len(mutators) > 0 { - mutator = Mutators(mutators...) - } else { - mutator = nil - } - - ruleConfig := ruleMakingConfig{ - pattern: rule.pattern, - delimiter: rule.delimiter, - numberOfDelimiterChars: rule.numberOfDelimiterChars, - tokenType: rule.tokenType, - mutator: mutator, - } - - cRule := makeRule(ruleConfig) - - switch rule.rulePosition { - case topRule: - state.Rules[stateName][0] = cRule - case bottomRule: - state.Rules[stateName][len(state.Rules[stateName])-1] = cRule - } - - // Pop state name from stack if asked. State should be popped first before Pushing - if rule.popState { - err := Pop(1).Mutate(state) - if err != nil { - panic(err) - } - } - - // Push state name to stack if asked - if rule.pushState { - err := Push(stateName).Mutate(state) - if err != nil { - panic(err) - } - } - - if !rule.pop { - state.Set(stackName, append(stack, rule)) - } - - return nil - } -} - -// Generates rule replacing stack using state name and rule position -func genStackName(stateName string, rulePosition rulePosition) (stackName string) { - switch rulePosition { - case topRule: - stackName = stateName + `-top-stack` - case bottomRule: - stackName = stateName + `-bottom-stack` - } - return -} - -// Makes a compiled rule and returns it -func makeRule(config ruleMakingConfig) *CompiledRule { - var rePattern string - - if len(config.delimiter) > 0 { - delimiter := string(config.delimiter) - - if config.numberOfDelimiterChars > 1 { - delimiter = strings.Repeat(delimiter, config.numberOfDelimiterChars) - } - - rePattern = `(? 1 { - lang = langMatch[1] - } - - // Tokenise code based on lang property - sublexer := Get(lang) - if sublexer != nil { - iterator, err := sublexer.Tokenise(nil, state.NamedGroups[`value`]) - - if err != nil { - panic(err) - } else { - iterators = append(iterators, iterator) - } - } else { - iterators = append(iterators, Literator(tokens[4])) - } - - // Append the rest of the tokens - iterators = append(iterators, Literator(tokens[5:]...)) - - return Concaterator(iterators...) -} diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/rst.go b/vendor/github.com/alecthomas/chroma/v2/lexers/rst.go deleted file mode 100644 index 66ec03cdfb..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/rst.go +++ /dev/null @@ -1,89 +0,0 @@ -package lexers - -import ( - "strings" - - . "github.com/alecthomas/chroma/v2" // nolint -) - -// Restructuredtext lexer. -var Restructuredtext = Register(MustNewLexer( - &Config{ - Name: "reStructuredText", - Aliases: []string{"rst", "rest", "restructuredtext"}, - Filenames: []string{"*.rst", "*.rest"}, - MimeTypes: []string{"text/x-rst", "text/prs.fallenstein.rst"}, - }, - restructuredtextRules, -)) - -func restructuredtextRules() Rules { - return Rules{ - "root": { - {"^(=+|-+|`+|:+|\\.+|\\'+|\"+|~+|\\^+|_+|\\*+|\\++|#+)([ \\t]*\\n)(.+)(\\n)(\\1)(\\n)", ByGroups(GenericHeading, Text, GenericHeading, Text, GenericHeading, Text), nil}, - {"^(\\S.*)(\\n)(={3,}|-{3,}|`{3,}|:{3,}|\\.{3,}|\\'{3,}|\"{3,}|~{3,}|\\^{3,}|_{3,}|\\*{3,}|\\+{3,}|#{3,})(\\n)", ByGroups(GenericHeading, Text, GenericHeading, Text), nil}, - {`^(\s*)([-*+])( .+\n(?:\1 .+\n)*)`, ByGroups(Text, LiteralNumber, UsingSelf("inline")), nil}, - {`^(\s*)([0-9#ivxlcmIVXLCM]+\.)( .+\n(?:\1 .+\n)*)`, ByGroups(Text, LiteralNumber, UsingSelf("inline")), nil}, - {`^(\s*)(\(?[0-9#ivxlcmIVXLCM]+\))( .+\n(?:\1 .+\n)*)`, ByGroups(Text, LiteralNumber, UsingSelf("inline")), nil}, - {`^(\s*)([A-Z]+\.)( .+\n(?:\1 .+\n)+)`, ByGroups(Text, LiteralNumber, UsingSelf("inline")), nil}, - {`^(\s*)(\(?[A-Za-z]+\))( .+\n(?:\1 .+\n)+)`, ByGroups(Text, LiteralNumber, UsingSelf("inline")), nil}, - {`^(\s*)(\|)( .+\n(?:\| .+\n)*)`, ByGroups(Text, Operator, UsingSelf("inline")), nil}, - {`^( *\.\.)(\s*)((?:source)?code(?:-block)?)(::)([ \t]*)([^\n]+)(\n[ \t]*\n)([ \t]+)(.*)(\n)((?:(?:\8.*|)\n)+)`, EmitterFunc(rstCodeBlock), nil}, - {`^( *\.\.)(\s*)([\w:-]+?)(::)(?:([ \t]*)(.*))`, ByGroups(Punctuation, Text, OperatorWord, Punctuation, Text, UsingSelf("inline")), nil}, - {`^( *\.\.)(\s*)(_(?:[^:\\]|\\.)+:)(.*?)$`, ByGroups(Punctuation, Text, NameTag, UsingSelf("inline")), nil}, - {`^( *\.\.)(\s*)(\[.+\])(.*?)$`, ByGroups(Punctuation, Text, NameTag, UsingSelf("inline")), nil}, - {`^( *\.\.)(\s*)(\|.+\|)(\s*)([\w:-]+?)(::)(?:([ \t]*)(.*))`, ByGroups(Punctuation, Text, NameTag, Text, OperatorWord, Punctuation, Text, UsingSelf("inline")), nil}, - {`^ *\.\..*(\n( +.*\n|\n)+)?`, CommentPreproc, nil}, - {`^( *)(:[a-zA-Z-]+:)(\s*)$`, ByGroups(Text, NameClass, Text), nil}, - {`^( *)(:.*?:)([ \t]+)(.*?)$`, ByGroups(Text, NameClass, Text, NameFunction), nil}, - {`^(\S.*(?)(`__?)", ByGroups(LiteralString, LiteralStringInterpol, LiteralString), nil}, - {"`.+?`__?", LiteralString, nil}, - {"(`.+?`)(:[a-zA-Z0-9:-]+?:)?", ByGroups(NameVariable, NameAttribute), nil}, - {"(:[a-zA-Z0-9:-]+?:)(`.+?`)", ByGroups(NameAttribute, NameVariable), nil}, - {`\*\*.+?\*\*`, GenericStrong, nil}, - {`\*.+?\*`, GenericEmph, nil}, - {`\[.*?\]_`, LiteralString, nil}, - {`<.+?>`, NameTag, nil}, - {"[^\\\\\\n\\[*`:]+", Text, nil}, - {`.`, Text, nil}, - }, - "literal": { - {"[^`]+", LiteralString, nil}, - {"``((?=$)|(?=[-/:.,; \\n\\x00\\\u2010\\\u2011\\\u2012\\\u2013\\\u2014\\\u00a0\\'\\\"\\)\\]\\}\\>\\\u2019\\\u201d\\\u00bb\\!\\?]))", LiteralString, Pop(1)}, - {"`", LiteralString, nil}, - }, - } -} - -func rstCodeBlock(groups []string, state *LexerState) Iterator { - iterators := []Iterator{} - tokens := []Token{ - {Punctuation, groups[1]}, - {Text, groups[2]}, - {OperatorWord, groups[3]}, - {Punctuation, groups[4]}, - {Text, groups[5]}, - {Keyword, groups[6]}, - {Text, groups[7]}, - } - code := strings.Join(groups[8:], "") - lexer := Get(groups[6]) - if lexer == nil { - tokens = append(tokens, Token{String, code}) - iterators = append(iterators, Literator(tokens...)) - } else { - sub, err := lexer.Tokenise(nil, code) - if err != nil { - panic(err) - } - iterators = append(iterators, Literator(tokens...), sub) - } - return Concaterator(iterators...) -} diff --git a/vendor/github.com/alecthomas/chroma/v2/lexers/svelte.go b/vendor/github.com/alecthomas/chroma/v2/lexers/svelte.go deleted file mode 100644 index 39211c4fc5..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/lexers/svelte.go +++ /dev/null @@ -1,70 +0,0 @@ -package lexers - -import ( - . "github.com/alecthomas/chroma/v2" // nolint -) - -// Svelte lexer. -var Svelte = Register(DelegatingLexer(HTML, MustNewLexer( - &Config{ - Name: "Svelte", - Aliases: []string{"svelte"}, - Filenames: []string{"*.svelte"}, - MimeTypes: []string{"application/x-svelte"}, - DotAll: true, - }, - svelteRules, -))) - -func svelteRules() Rules { - return Rules{ - "root": { - // Let HTML handle the comments, including comments containing script and style tags - {``, Other, Pop(1)}, - {`.+?`, Other, nil}, - }, - "templates": { - {`}`, Punctuation, Pop(1)}, - // Let TypeScript handle strings and the curly braces inside them - {`(?]*>`, Using("TypoScriptHTMLData"), nil}, - {`&[^;\n]*;`, LiteralString, nil}, - {`(_CSS_DEFAULT_STYLE)(\s*)(\()(?s)(.*(?=\n\)))`, ByGroups(NameClass, Text, LiteralStringSymbol, Using("TypoScriptCSSData")), nil}, - }, - "literal": { - {`0x[0-9A-Fa-f]+t?`, LiteralNumberHex, nil}, - {`[0-9]+`, LiteralNumberInteger, nil}, - {`(###\w+###)`, NameConstant, nil}, - }, - "label": { - {`(EXT|FILE|LLL):[^}\n"]*`, LiteralString, nil}, - {`(?![^\w\-])([\w\-]+(?:/[\w\-]+)+/?)(\S*\n)`, ByGroups(LiteralString, LiteralString), nil}, - }, - "punctuation": { - {`[,.]`, Punctuation, nil}, - }, - "operator": { - {`[<>,:=.*%+|]`, Operator, nil}, - }, - "structure": { - {`[{}()\[\]\\]`, LiteralStringSymbol, nil}, - }, - "constant": { - {`(\{)(\$)((?:[\w\-]+\.)*)([\w\-]+)(\})`, ByGroups(LiteralStringSymbol, Operator, NameConstant, NameConstant, LiteralStringSymbol), nil}, - {`(\{)([\w\-]+)(\s*:\s*)([\w\-]+)(\})`, ByGroups(LiteralStringSymbol, NameConstant, Operator, NameConstant, LiteralStringSymbol), nil}, - {`(#[a-fA-F0-9]{6}\b|#[a-fA-F0-9]{3}\b)`, LiteralStringChar, nil}, - }, - "comment": { - {`(? 0 { - // Exhaust the iterator stack, if any. - for len(l.iteratorStack) > 0 { - n := len(l.iteratorStack) - 1 - t := l.iteratorStack[n]() - if t.Type == Ignore { - continue - } - if t == EOF { - l.iteratorStack = l.iteratorStack[:n] - continue - } - return t - } - - l.State = l.Stack[len(l.Stack)-1] - selectedRule, ok := l.Rules[l.State] - if !ok { - panic("unknown state " + l.State) - } - var start time.Time - if l.Lexer.trace { - start = time.Now() - } - ruleIndex, rule, groups, namedGroups := matchRules(l.Text, l.Pos, selectedRule) - if l.Lexer.trace { - var length int - if groups != nil { - length = len(groups[0]) - } else { - length = -1 - } - _ = trace.Encode(Trace{ //nolint - Lexer: l.Lexer.config.Name, - State: l.State, - Rule: ruleIndex, - Pattern: rule.Pattern, - Pos: l.Pos, - Length: length, - Elapsed: float64(time.Since(start)) / float64(time.Millisecond), - }) - // fmt.Fprintf(os.Stderr, "%s: pos=%d, text=%q, elapsed=%s\n", l.State, l.Pos, string(l.Text[l.Pos:]), time.Since(start)) - } - // No match. - if groups == nil { - // From Pygments :\ - // - // If the RegexLexer encounters a newline that is flagged as an error token, the stack is - // emptied and the lexer continues scanning in the 'root' state. This can help producing - // error-tolerant highlighting for erroneous input, e.g. when a single-line string is not - // closed. - if l.Text[l.Pos] == '\n' && l.State != l.options.State { - l.Stack = []string{l.options.State} - continue - } - l.Pos++ - return Token{Error, string(l.Text[l.Pos-1 : l.Pos])} - } - l.Rule = ruleIndex - l.Groups = groups - l.NamedGroups = namedGroups - l.Pos += utf8.RuneCountInString(groups[0]) - if rule.Mutator != nil { - if err := rule.Mutator.Mutate(l); err != nil { - panic(err) - } - } - if rule.Type != nil { - l.iteratorStack = append(l.iteratorStack, rule.Type.Emit(l.Groups, l)) - } - } - // Exhaust the IteratorStack, if any. - // Duplicate code, but eh. - for len(l.iteratorStack) > 0 { - n := len(l.iteratorStack) - 1 - t := l.iteratorStack[n]() - if t.Type == Ignore { - continue - } - if t == EOF { - l.iteratorStack = l.iteratorStack[:n] - continue - } - return t - } - - // If we get to here and we still have text, return it as an error. - if l.Pos != len(l.Text) && len(l.Stack) == 0 { - value := string(l.Text[l.Pos:]) - l.Pos = len(l.Text) - return Token{Type: Error, Value: value} - } - return EOF -} - -// RegexLexer is the default lexer implementation used in Chroma. -type RegexLexer struct { - registry *LexerRegistry // The LexerRegistry this Lexer is associated with, if any. - config *Config - analyser func(text string) float32 - trace bool - - mu sync.Mutex - compiled bool - rawRules Rules - rules map[string][]*CompiledRule - fetchRulesFunc func() (Rules, error) - compileOnce sync.Once -} - -func (r *RegexLexer) String() string { - return r.config.Name -} - -// Rules in the Lexer. -func (r *RegexLexer) Rules() (Rules, error) { - if err := r.needRules(); err != nil { - return nil, err - } - return r.rawRules, nil -} - -// SetRegistry the lexer will use to lookup other lexers if necessary. -func (r *RegexLexer) SetRegistry(registry *LexerRegistry) Lexer { - r.registry = registry - return r -} - -// SetAnalyser sets the analyser function used to perform content inspection. -func (r *RegexLexer) SetAnalyser(analyser func(text string) float32) Lexer { - r.analyser = analyser - return r -} - -// AnalyseText scores how likely a fragment of text is to match this lexer, between 0.0 and 1.0. -func (r *RegexLexer) AnalyseText(text string) float32 { - if r.analyser != nil { - return r.analyser(text) - } - return 0 -} - -// SetConfig replaces the Config for this Lexer. -func (r *RegexLexer) SetConfig(config *Config) *RegexLexer { - r.config = config - return r -} - -// Config returns the Config for this Lexer. -func (r *RegexLexer) Config() *Config { - return r.config -} - -// Regex compilation is deferred until the lexer is used. This is to avoid significant init() time costs. -func (r *RegexLexer) maybeCompile() (err error) { - r.mu.Lock() - defer r.mu.Unlock() - if r.compiled { - return nil - } - for state, rules := range r.rules { - for i, rule := range rules { - if rule.Regexp == nil { - pattern := "(?:" + rule.Pattern + ")" - if rule.flags != "" { - pattern = "(?" + rule.flags + ")" + pattern - } - pattern = `\G` + pattern - rule.Regexp, err = regexp2.Compile(pattern, 0) - if err != nil { - return fmt.Errorf("failed to compile rule %s.%d: %s", state, i, err) - } - rule.Regexp.MatchTimeout = time.Millisecond * 250 - } - } - } -restart: - seen := map[LexerMutator]bool{} - for state := range r.rules { - for i := range len(r.rules[state]) { - rule := r.rules[state][i] - if compile, ok := rule.Mutator.(LexerMutator); ok { - if seen[compile] { - return fmt.Errorf("saw mutator %T twice; this should not happen", compile) - } - seen[compile] = true - if err := compile.MutateLexer(r.rules, state, i); err != nil { - return err - } - // Process the rules again in case the mutator added/removed rules. - // - // This sounds bad, but shouldn't be significant in practice. - goto restart - } - } - } - // Validate emitters - for state := range r.rules { - for i := range len(r.rules[state]) { - rule := r.rules[state][i] - if validate, ok := rule.Type.(ValidatingEmitter); ok { - if err := validate.ValidateEmitter(rule); err != nil { - return fmt.Errorf("%s: %s: %s: %w", r.config.Name, state, rule.Pattern, err) - } - } - } - } - r.compiled = true - return nil -} - -func (r *RegexLexer) fetchRules() error { - rules, err := r.fetchRulesFunc() - if err != nil { - return fmt.Errorf("%s: failed to compile rules: %w", r.config.Name, err) - } - if _, ok := rules["root"]; !ok { - return fmt.Errorf("no \"root\" state") - } - compiledRules := map[string][]*CompiledRule{} - for state, rules := range rules { - compiledRules[state] = nil - for _, rule := range rules { - flags := "" - if !r.config.NotMultiline { - flags += "m" - } - if r.config.CaseInsensitive { - flags += "i" - } - if r.config.DotAll { - flags += "s" - } - compiledRules[state] = append(compiledRules[state], &CompiledRule{Rule: rule, flags: flags}) - } - } - - r.rawRules = rules - r.rules = compiledRules - return nil -} - -func (r *RegexLexer) needRules() error { - var err error - if r.fetchRulesFunc != nil { - r.compileOnce.Do(func() { - err = r.fetchRules() - }) - } - if err := r.maybeCompile(); err != nil { - return err - } - return err -} - -// Tokenise text using lexer, returning an iterator. -func (r *RegexLexer) Tokenise(options *TokeniseOptions, text string) (Iterator, error) { - err := r.needRules() - if err != nil { - return nil, err - } - if options == nil { - options = defaultOptions - } - if options.EnsureLF { - text = ensureLF(text) - } - newlineAdded := false - if !options.Nested && r.config.EnsureNL && !strings.HasSuffix(text, "\n") { - text += "\n" - newlineAdded = true - } - state := &LexerState{ - Registry: r.registry, - newlineAdded: newlineAdded, - options: options, - Lexer: r, - Text: []rune(text), - Stack: []string{options.State}, - Rules: r.rules, - MutatorContext: map[interface{}]interface{}{}, - } - return state.Iterator, nil -} - -// MustRules is like Rules() but will panic on error. -func (r *RegexLexer) MustRules() Rules { - rules, err := r.Rules() - if err != nil { - panic(err) - } - return rules -} - -func matchRules(text []rune, pos int, rules []*CompiledRule) (int, *CompiledRule, []string, map[string]string) { - for i, rule := range rules { - match, err := rule.Regexp.FindRunesMatchStartingAt(text, pos) - if match != nil && err == nil && match.Index == pos { - groups := []string{} - namedGroups := make(map[string]string) - for _, g := range match.Groups() { - namedGroups[g.Name] = g.String() - groups = append(groups, g.String()) - } - return i, rule, groups, namedGroups - } - } - return 0, &CompiledRule{}, nil, nil -} - -// replace \r and \r\n with \n -// same as strings.ReplaceAll but more efficient -func ensureLF(text string) string { - buf := make([]byte, len(text)) - var j int - for i := range len(text) { - c := text[i] - if c == '\r' { - if i < len(text)-1 && text[i+1] == '\n' { - continue - } - c = '\n' - } - buf[j] = c - j++ - } - return string(buf[:j]) -} diff --git a/vendor/github.com/alecthomas/chroma/v2/registry.go b/vendor/github.com/alecthomas/chroma/v2/registry.go deleted file mode 100644 index a309af9dbf..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/registry.go +++ /dev/null @@ -1,228 +0,0 @@ -package chroma - -import ( - "path/filepath" - "sort" - "strings" -) - -var ( - ignoredSuffixes = [...]string{ - // Editor backups - "~", ".bak", ".old", ".orig", - // Debian and derivatives apt/dpkg/ucf backups - ".dpkg-dist", ".dpkg-old", ".ucf-dist", ".ucf-new", ".ucf-old", - // Red Hat and derivatives rpm backups - ".rpmnew", ".rpmorig", ".rpmsave", - // Build system input/template files - ".in", - } -) - -// LexerRegistry is a registry of Lexers. -type LexerRegistry struct { - Lexers Lexers - byName map[string]Lexer - byAlias map[string]Lexer -} - -// NewLexerRegistry creates a new LexerRegistry of Lexers. -func NewLexerRegistry() *LexerRegistry { - return &LexerRegistry{ - byName: map[string]Lexer{}, - byAlias: map[string]Lexer{}, - } -} - -// Names of all lexers, optionally including aliases. -func (l *LexerRegistry) Names(withAliases bool) []string { - out := []string{} - for _, lexer := range l.Lexers { - config := lexer.Config() - out = append(out, config.Name) - if withAliases { - out = append(out, config.Aliases...) - } - } - sort.Strings(out) - return out -} - -// Aliases of all the lexers, and skip those lexers who do not have any aliases, -// or show their name instead -func (l *LexerRegistry) Aliases(skipWithoutAliases bool) []string { - out := []string{} - for _, lexer := range l.Lexers { - config := lexer.Config() - if len(config.Aliases) == 0 { - if skipWithoutAliases { - continue - } - out = append(out, config.Name) - } - out = append(out, config.Aliases...) - } - sort.Strings(out) - return out -} - -// Get a Lexer by name, alias or file extension. -func (l *LexerRegistry) Get(name string) Lexer { - if lexer := l.byName[name]; lexer != nil { - return lexer - } - if lexer := l.byAlias[name]; lexer != nil { - return lexer - } - if lexer := l.byName[strings.ToLower(name)]; lexer != nil { - return lexer - } - if lexer := l.byAlias[strings.ToLower(name)]; lexer != nil { - return lexer - } - - candidates := PrioritisedLexers{} - // Try file extension. - if lexer := l.Match("filename." + name); lexer != nil { - candidates = append(candidates, lexer) - } - // Try exact filename. - if lexer := l.Match(name); lexer != nil { - candidates = append(candidates, lexer) - } - if len(candidates) == 0 { - return nil - } - sort.Sort(candidates) - return candidates[0] -} - -// MatchMimeType attempts to find a lexer for the given MIME type. -func (l *LexerRegistry) MatchMimeType(mimeType string) Lexer { - matched := PrioritisedLexers{} - for _, l := range l.Lexers { - for _, lmt := range l.Config().MimeTypes { - if mimeType == lmt { - matched = append(matched, l) - } - } - } - if len(matched) != 0 { - sort.Sort(matched) - return matched[0] - } - return nil -} - -// Match returns the first lexer matching filename. -// -// Note that this iterates over all file patterns in all lexers, so is not fast. -func (l *LexerRegistry) Match(filename string) Lexer { - filename = filepath.Base(filename) - matched := PrioritisedLexers{} - // First, try primary filename matches. - for _, lexer := range l.Lexers { - config := lexer.Config() - for _, glob := range config.Filenames { - ok, err := filepath.Match(glob, filename) - if err != nil { // nolint - panic(err) - } else if ok { - matched = append(matched, lexer) - } else { - for _, suf := range &ignoredSuffixes { - ok, err := filepath.Match(glob+suf, filename) - if err != nil { - panic(err) - } else if ok { - matched = append(matched, lexer) - break - } - } - } - } - } - if len(matched) > 0 { - sort.Sort(matched) - return matched[0] - } - matched = nil - // Next, try filename aliases. - for _, lexer := range l.Lexers { - config := lexer.Config() - for _, glob := range config.AliasFilenames { - ok, err := filepath.Match(glob, filename) - if err != nil { // nolint - panic(err) - } else if ok { - matched = append(matched, lexer) - } else { - for _, suf := range &ignoredSuffixes { - ok, err := filepath.Match(glob+suf, filename) - if err != nil { - panic(err) - } else if ok { - matched = append(matched, lexer) - break - } - } - } - } - } - if len(matched) > 0 { - sort.Sort(matched) - return matched[0] - } - return nil -} - -// Analyse text content and return the "best" lexer.. -func (l *LexerRegistry) Analyse(text string) Lexer { - var picked Lexer - highest := float32(0.0) - for _, lexer := range l.Lexers { - if analyser, ok := lexer.(Analyser); ok { - weight := analyser.AnalyseText(text) - if weight > highest { - picked = lexer - highest = weight - } - } - } - return picked -} - -// Register a Lexer with the LexerRegistry. If the lexer is already registered -// it will be replaced. -func (l *LexerRegistry) Register(lexer Lexer) Lexer { - lexer.SetRegistry(l) - config := lexer.Config() - - l.byName[config.Name] = lexer - l.byName[strings.ToLower(config.Name)] = lexer - - for _, alias := range config.Aliases { - l.byAlias[alias] = lexer - l.byAlias[strings.ToLower(alias)] = lexer - } - - l.Lexers = add(l.Lexers, lexer) - - return lexer -} - -// add adds a lexer to a slice of lexers if it doesn't already exist, or if found will replace it. -func add(lexers Lexers, lexer Lexer) Lexers { - for i, val := range lexers { - if val == nil { - continue - } - - if val.Config().Name == lexer.Config().Name { - lexers[i] = lexer - return lexers - } - } - - return append(lexers, lexer) -} diff --git a/vendor/github.com/alecthomas/chroma/v2/remap.go b/vendor/github.com/alecthomas/chroma/v2/remap.go deleted file mode 100644 index bcf5e66d17..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/remap.go +++ /dev/null @@ -1,94 +0,0 @@ -package chroma - -type remappingLexer struct { - lexer Lexer - mapper func(Token) []Token -} - -// RemappingLexer remaps a token to a set of, potentially empty, tokens. -func RemappingLexer(lexer Lexer, mapper func(Token) []Token) Lexer { - return &remappingLexer{lexer, mapper} -} - -func (r *remappingLexer) AnalyseText(text string) float32 { - return r.lexer.AnalyseText(text) -} - -func (r *remappingLexer) SetAnalyser(analyser func(text string) float32) Lexer { - r.lexer.SetAnalyser(analyser) - return r -} - -func (r *remappingLexer) SetRegistry(registry *LexerRegistry) Lexer { - r.lexer.SetRegistry(registry) - return r -} - -func (r *remappingLexer) Config() *Config { - return r.lexer.Config() -} - -func (r *remappingLexer) Tokenise(options *TokeniseOptions, text string) (Iterator, error) { - it, err := r.lexer.Tokenise(options, text) - if err != nil { - return nil, err - } - var buffer []Token - return func() Token { - for { - if len(buffer) > 0 { - t := buffer[0] - buffer = buffer[1:] - return t - } - t := it() - if t == EOF { - return t - } - buffer = r.mapper(t) - } - }, nil -} - -// TypeMapping defines type maps for the TypeRemappingLexer. -type TypeMapping []struct { - From, To TokenType - Words []string -} - -// TypeRemappingLexer remaps types of tokens coming from a parent Lexer. -// -// eg. Map "defvaralias" tokens of type NameVariable to NameFunction: -// -// mapping := TypeMapping{ -// {NameVariable, NameFunction, []string{"defvaralias"}, -// } -// lexer = TypeRemappingLexer(lexer, mapping) -func TypeRemappingLexer(lexer Lexer, mapping TypeMapping) Lexer { - // Lookup table for fast remapping. - lut := map[TokenType]map[string]TokenType{} - for _, rt := range mapping { - km, ok := lut[rt.From] - if !ok { - km = map[string]TokenType{} - lut[rt.From] = km - } - if len(rt.Words) == 0 { - km[""] = rt.To - } else { - for _, k := range rt.Words { - km[k] = rt.To - } - } - } - return RemappingLexer(lexer, func(t Token) []Token { - if k, ok := lut[t.Type]; ok { - if tt, ok := k[t.Value]; ok { - t.Type = tt - } else if tt, ok := k[""]; ok { - t.Type = tt - } - } - return []Token{t} - }) -} diff --git a/vendor/github.com/alecthomas/chroma/v2/renovate.json5 b/vendor/github.com/alecthomas/chroma/v2/renovate.json5 deleted file mode 100644 index 9ade48124f..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/renovate.json5 +++ /dev/null @@ -1,24 +0,0 @@ -{ - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "config:recommended", - ":semanticCommits", - ":semanticCommitTypeAll(chore)", - ":semanticCommitScope(deps)", - "group:allNonMajor", - "schedule:earlyMondays", // Run once a week. - 'helpers:pinGitHubActionDigests', - ], - "packageRules": [ - { - "matchPackageNames": ["golangci-lint"], - "matchManagers": ["hermit"], - "enabled": false - }, - { - "matchPackageNames": ["github.com/gorilla/csrf"], - "matchManagers": ["gomod"], - "enabled": false - } - ] -} diff --git a/vendor/github.com/alecthomas/chroma/v2/serialise.go b/vendor/github.com/alecthomas/chroma/v2/serialise.go deleted file mode 100644 index 645a5faabc..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/serialise.go +++ /dev/null @@ -1,479 +0,0 @@ -package chroma - -import ( - "compress/gzip" - "encoding/xml" - "errors" - "fmt" - "io" - "io/fs" - "math" - "path/filepath" - "reflect" - "regexp" - "strings" - - "github.com/dlclark/regexp2" -) - -// Serialisation of Chroma rules to XML. The format is: -// -// -// -// -// [<$EMITTER ...>] -// [<$MUTATOR ...>] -// -// -// -// -// eg. Include("String") would become: -// -// -// -// -// -// [null, null, {"kind": "include", "state": "String"}] -// -// eg. Rule{`\d+`, Text, nil} would become: -// -// -// -// -// -// eg. Rule{`"`, String, Push("String")} -// -// -// -// -// -// -// eg. Rule{`(\w+)(\n)`, ByGroups(Keyword, Whitespace), nil}, -// -// -// -// -// -var ( - // ErrNotSerialisable is returned if a lexer contains Rules that cannot be serialised. - ErrNotSerialisable = fmt.Errorf("not serialisable") - emitterTemplates = func() map[string]SerialisableEmitter { - out := map[string]SerialisableEmitter{} - for _, emitter := range []SerialisableEmitter{ - &byGroupsEmitter{}, - &usingSelfEmitter{}, - TokenType(0), - &usingEmitter{}, - &usingByGroup{}, - } { - out[emitter.EmitterKind()] = emitter - } - return out - }() - mutatorTemplates = func() map[string]SerialisableMutator { - out := map[string]SerialisableMutator{} - for _, mutator := range []SerialisableMutator{ - &includeMutator{}, - &combinedMutator{}, - &multiMutator{}, - &pushMutator{}, - &popMutator{}, - } { - out[mutator.MutatorKind()] = mutator - } - return out - }() -) - -// fastUnmarshalConfig unmarshals only the Config from a serialised lexer. -func fastUnmarshalConfig(from fs.FS, path string) (*Config, error) { - r, err := from.Open(path) - if err != nil { - return nil, err - } - defer r.Close() - dec := xml.NewDecoder(r) - for { - token, err := dec.Token() - if err != nil { - if errors.Is(err, io.EOF) { - return nil, fmt.Errorf("could not find element") - } - return nil, err - } - switch se := token.(type) { - case xml.StartElement: - if se.Name.Local != "config" { - break - } - - var config Config - err = dec.DecodeElement(&config, &se) - if err != nil { - return nil, fmt.Errorf("%s: %w", path, err) - } - return &config, nil - } - } -} - -// MustNewXMLLexer constructs a new RegexLexer from an XML file or panics. -func MustNewXMLLexer(from fs.FS, path string) *RegexLexer { - lex, err := NewXMLLexer(from, path) - if err != nil { - panic(err) - } - return lex -} - -// NewXMLLexer creates a new RegexLexer from a serialised RegexLexer. -func NewXMLLexer(from fs.FS, path string) (*RegexLexer, error) { - config, err := fastUnmarshalConfig(from, path) - if err != nil { - return nil, err - } - - for _, glob := range append(config.Filenames, config.AliasFilenames...) { - _, err := filepath.Match(glob, "") - if err != nil { - return nil, fmt.Errorf("%s: %q is not a valid glob: %w", config.Name, glob, err) - } - } - - var analyserFn func(string) float32 - - if config.Analyse != nil { - type regexAnalyse struct { - re *regexp2.Regexp - score float32 - } - - regexAnalysers := make([]regexAnalyse, 0, len(config.Analyse.Regexes)) - - for _, ra := range config.Analyse.Regexes { - re, err := regexp2.Compile(ra.Pattern, regexp2.None) - if err != nil { - return nil, fmt.Errorf("%s: %q is not a valid analyser regex: %w", config.Name, ra.Pattern, err) - } - - regexAnalysers = append(regexAnalysers, regexAnalyse{re, ra.Score}) - } - - analyserFn = func(text string) float32 { - var score float32 - - for _, ra := range regexAnalysers { - ok, err := ra.re.MatchString(text) - if err != nil { - return 0 - } - - if ok && config.Analyse.First { - return float32(math.Min(float64(ra.score), 1.0)) - } - - if ok { - score += ra.score - } - } - - return float32(math.Min(float64(score), 1.0)) - } - } - - return &RegexLexer{ - config: config, - analyser: analyserFn, - fetchRulesFunc: func() (Rules, error) { - var lexer struct { - Config - Rules Rules `xml:"rules"` - } - // Try to open .xml fallback to .xml.gz - fr, err := from.Open(path) - if err != nil { - if errors.Is(err, fs.ErrNotExist) { - path += ".gz" - fr, err = from.Open(path) - if err != nil { - return nil, err - } - } else { - return nil, err - } - } - defer fr.Close() - var r io.Reader = fr - if strings.HasSuffix(path, ".gz") { - r, err = gzip.NewReader(r) - if err != nil { - return nil, fmt.Errorf("%s: %w", path, err) - } - } - err = xml.NewDecoder(r).Decode(&lexer) - if err != nil { - return nil, fmt.Errorf("%s: %w", path, err) - } - return lexer.Rules, nil - }, - }, nil -} - -// Marshal a RegexLexer to XML. -func Marshal(l *RegexLexer) ([]byte, error) { - type lexer struct { - Config Config `xml:"config"` - Rules Rules `xml:"rules"` - } - - rules, err := l.Rules() - if err != nil { - return nil, err - } - root := &lexer{ - Config: *l.Config(), - Rules: rules, - } - data, err := xml.MarshalIndent(root, "", " ") - if err != nil { - return nil, err - } - re := regexp.MustCompile(`>`) - data = re.ReplaceAll(data, []byte(`/>`)) - return data, nil -} - -// Unmarshal a RegexLexer from XML. -func Unmarshal(data []byte) (*RegexLexer, error) { - type lexer struct { - Config Config `xml:"config"` - Rules Rules `xml:"rules"` - } - root := &lexer{} - err := xml.Unmarshal(data, root) - if err != nil { - return nil, fmt.Errorf("invalid Lexer XML: %w", err) - } - lex, err := NewLexer(&root.Config, func() Rules { return root.Rules }) - if err != nil { - return nil, err - } - return lex, nil -} - -func marshalMutator(e *xml.Encoder, mutator Mutator) error { - if mutator == nil { - return nil - } - smutator, ok := mutator.(SerialisableMutator) - if !ok { - return fmt.Errorf("unsupported mutator: %w", ErrNotSerialisable) - } - return e.EncodeElement(mutator, xml.StartElement{Name: xml.Name{Local: smutator.MutatorKind()}}) -} - -func unmarshalMutator(d *xml.Decoder, start xml.StartElement) (Mutator, error) { - kind := start.Name.Local - mutator, ok := mutatorTemplates[kind] - if !ok { - return nil, fmt.Errorf("unknown mutator %q: %w", kind, ErrNotSerialisable) - } - value, target := newFromTemplate(mutator) - if err := d.DecodeElement(target, &start); err != nil { - return nil, err - } - return value().(SerialisableMutator), nil -} - -func marshalEmitter(e *xml.Encoder, emitter Emitter) error { - if emitter == nil { - return nil - } - semitter, ok := emitter.(SerialisableEmitter) - if !ok { - return fmt.Errorf("unsupported emitter %T: %w", emitter, ErrNotSerialisable) - } - return e.EncodeElement(emitter, xml.StartElement{ - Name: xml.Name{Local: semitter.EmitterKind()}, - }) -} - -func unmarshalEmitter(d *xml.Decoder, start xml.StartElement) (Emitter, error) { - kind := start.Name.Local - mutator, ok := emitterTemplates[kind] - if !ok { - return nil, fmt.Errorf("unknown emitter %q: %w", kind, ErrNotSerialisable) - } - value, target := newFromTemplate(mutator) - if err := d.DecodeElement(target, &start); err != nil { - return nil, err - } - return value().(SerialisableEmitter), nil -} - -func (r Rule) MarshalXML(e *xml.Encoder, _ xml.StartElement) error { - start := xml.StartElement{ - Name: xml.Name{Local: "rule"}, - } - if r.Pattern != "" { - start.Attr = append(start.Attr, xml.Attr{ - Name: xml.Name{Local: "pattern"}, - Value: r.Pattern, - }) - } - if err := e.EncodeToken(start); err != nil { - return err - } - if err := marshalEmitter(e, r.Type); err != nil { - return err - } - if err := marshalMutator(e, r.Mutator); err != nil { - return err - } - return e.EncodeToken(xml.EndElement{Name: start.Name}) -} - -func (r *Rule) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - for _, attr := range start.Attr { - if attr.Name.Local == "pattern" { - r.Pattern = attr.Value - break - } - } - for { - token, err := d.Token() - if err != nil { - return err - } - switch token := token.(type) { - case xml.StartElement: - mutator, err := unmarshalMutator(d, token) - if err != nil && !errors.Is(err, ErrNotSerialisable) { - return err - } else if err == nil { - if r.Mutator != nil { - return fmt.Errorf("duplicate mutator") - } - r.Mutator = mutator - continue - } - emitter, err := unmarshalEmitter(d, token) - if err != nil && !errors.Is(err, ErrNotSerialisable) { // nolint: gocritic - return err - } else if err == nil { - if r.Type != nil { - return fmt.Errorf("duplicate emitter") - } - r.Type = emitter - continue - } else { - return err - } - - case xml.EndElement: - return nil - } - } -} - -type xmlRuleState struct { - Name string `xml:"name,attr"` - Rules []Rule `xml:"rule"` -} - -type xmlRules struct { - States []xmlRuleState `xml:"state"` -} - -func (r Rules) MarshalXML(e *xml.Encoder, _ xml.StartElement) error { - xr := xmlRules{} - for state, rules := range r { - xr.States = append(xr.States, xmlRuleState{ - Name: state, - Rules: rules, - }) - } - return e.EncodeElement(xr, xml.StartElement{Name: xml.Name{Local: "rules"}}) -} - -func (r *Rules) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - xr := xmlRules{} - if err := d.DecodeElement(&xr, &start); err != nil { - return err - } - if *r == nil { - *r = Rules{} - } - for _, state := range xr.States { - (*r)[state.Name] = state.Rules - } - return nil -} - -type xmlTokenType struct { - Type string `xml:"type,attr"` -} - -func (t *TokenType) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - el := xmlTokenType{} - if err := d.DecodeElement(&el, &start); err != nil { - return err - } - tt, err := TokenTypeString(el.Type) - if err != nil { - return err - } - *t = tt - return nil -} - -func (t TokenType) MarshalXML(e *xml.Encoder, start xml.StartElement) error { - start.Attr = append(start.Attr, xml.Attr{Name: xml.Name{Local: "type"}, Value: t.String()}) - if err := e.EncodeToken(start); err != nil { - return err - } - return e.EncodeToken(xml.EndElement{Name: start.Name}) -} - -// This hijinks is a bit unfortunate but without it we can't deserialise into TokenType. -func newFromTemplate(template interface{}) (value func() interface{}, target interface{}) { - t := reflect.TypeOf(template) - if t.Kind() == reflect.Ptr { - v := reflect.New(t.Elem()) - return v.Interface, v.Interface() - } - v := reflect.New(t) - return func() interface{} { return v.Elem().Interface() }, v.Interface() -} - -func (b *Emitters) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - for { - token, err := d.Token() - if err != nil { - return err - } - switch token := token.(type) { - case xml.StartElement: - emitter, err := unmarshalEmitter(d, token) - if err != nil { - return err - } - *b = append(*b, emitter) - - case xml.EndElement: - return nil - } - } -} - -func (b Emitters) MarshalXML(e *xml.Encoder, start xml.StartElement) error { - if err := e.EncodeToken(start); err != nil { - return err - } - for _, m := range b { - if err := marshalEmitter(e, m); err != nil { - return err - } - } - return e.EncodeToken(xml.EndElement{Name: start.Name}) -} diff --git a/vendor/github.com/alecthomas/chroma/v2/style.go b/vendor/github.com/alecthomas/chroma/v2/style.go deleted file mode 100644 index cc8d9a602f..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/style.go +++ /dev/null @@ -1,481 +0,0 @@ -package chroma - -import ( - "encoding/xml" - "fmt" - "io" - "sort" - "strings" -) - -// Trilean value for StyleEntry value inheritance. -type Trilean uint8 - -// Trilean states. -const ( - Pass Trilean = iota - Yes - No -) - -func (t Trilean) String() string { - switch t { - case Yes: - return "Yes" - case No: - return "No" - default: - return "Pass" - } -} - -// Prefix returns s with "no" as a prefix if Trilean is no. -func (t Trilean) Prefix(s string) string { - if t == Yes { - return s - } else if t == No { - return "no" + s - } - return "" -} - -// A StyleEntry in the Style map. -type StyleEntry struct { - // Hex colours. - Colour Colour - Background Colour - Border Colour - - Bold Trilean - Italic Trilean - Underline Trilean - NoInherit bool -} - -func (s StyleEntry) MarshalText() ([]byte, error) { - return []byte(s.String()), nil -} - -func (s StyleEntry) String() string { - out := []string{} - if s.Bold != Pass { - out = append(out, s.Bold.Prefix("bold")) - } - if s.Italic != Pass { - out = append(out, s.Italic.Prefix("italic")) - } - if s.Underline != Pass { - out = append(out, s.Underline.Prefix("underline")) - } - if s.NoInherit { - out = append(out, "noinherit") - } - if s.Colour.IsSet() { - out = append(out, s.Colour.String()) - } - if s.Background.IsSet() { - out = append(out, "bg:"+s.Background.String()) - } - if s.Border.IsSet() { - out = append(out, "border:"+s.Border.String()) - } - return strings.Join(out, " ") -} - -// Sub subtracts e from s where elements match. -func (s StyleEntry) Sub(e StyleEntry) StyleEntry { - out := StyleEntry{} - if e.Colour != s.Colour { - out.Colour = s.Colour - } - if e.Background != s.Background { - out.Background = s.Background - } - if e.Bold != s.Bold { - out.Bold = s.Bold - } - if e.Italic != s.Italic { - out.Italic = s.Italic - } - if e.Underline != s.Underline { - out.Underline = s.Underline - } - if e.Border != s.Border { - out.Border = s.Border - } - return out -} - -// Inherit styles from ancestors. -// -// Ancestors should be provided from oldest to newest. -func (s StyleEntry) Inherit(ancestors ...StyleEntry) StyleEntry { - out := s - for i := len(ancestors) - 1; i >= 0; i-- { - if out.NoInherit { - return out - } - ancestor := ancestors[i] - if !out.Colour.IsSet() { - out.Colour = ancestor.Colour - } - if !out.Background.IsSet() { - out.Background = ancestor.Background - } - if !out.Border.IsSet() { - out.Border = ancestor.Border - } - if out.Bold == Pass { - out.Bold = ancestor.Bold - } - if out.Italic == Pass { - out.Italic = ancestor.Italic - } - if out.Underline == Pass { - out.Underline = ancestor.Underline - } - } - return out -} - -func (s StyleEntry) IsZero() bool { - return s.Colour == 0 && s.Background == 0 && s.Border == 0 && s.Bold == Pass && s.Italic == Pass && - s.Underline == Pass && !s.NoInherit -} - -// A StyleBuilder is a mutable structure for building styles. -// -// Once built, a Style is immutable. -type StyleBuilder struct { - entries map[TokenType]string - name string - parent *Style -} - -func NewStyleBuilder(name string) *StyleBuilder { - return &StyleBuilder{name: name, entries: map[TokenType]string{}} -} - -func (s *StyleBuilder) AddAll(entries StyleEntries) *StyleBuilder { - for ttype, entry := range entries { - s.entries[ttype] = entry - } - return s -} - -func (s *StyleBuilder) Get(ttype TokenType) StyleEntry { - // This is less than ideal, but it's the price for not having to check errors on each Add(). - entry, _ := ParseStyleEntry(s.entries[ttype]) - if s.parent != nil { - entry = entry.Inherit(s.parent.Get(ttype)) - } - return entry -} - -// Add an entry to the Style map. -// -// See http://pygments.org/docs/styles/#style-rules for details. -func (s *StyleBuilder) Add(ttype TokenType, entry string) *StyleBuilder { // nolint: gocyclo - s.entries[ttype] = entry - return s -} - -func (s *StyleBuilder) AddEntry(ttype TokenType, entry StyleEntry) *StyleBuilder { - s.entries[ttype] = entry.String() - return s -} - -// Transform passes each style entry currently defined in the builder to the supplied -// function and saves the returned value. This can be used to adjust a style's colours; -// see Colour's ClampBrightness function, for example. -func (s *StyleBuilder) Transform(transform func(StyleEntry) StyleEntry) *StyleBuilder { - types := make(map[TokenType]struct{}) - for tt := range s.entries { - types[tt] = struct{}{} - } - if s.parent != nil { - for _, tt := range s.parent.Types() { - types[tt] = struct{}{} - } - } - for tt := range types { - s.AddEntry(tt, transform(s.Get(tt))) - } - return s -} - -func (s *StyleBuilder) Build() (*Style, error) { - style := &Style{ - Name: s.name, - entries: map[TokenType]StyleEntry{}, - parent: s.parent, - } - for ttype, descriptor := range s.entries { - entry, err := ParseStyleEntry(descriptor) - if err != nil { - return nil, fmt.Errorf("invalid entry for %s: %s", ttype, err) - } - style.entries[ttype] = entry - } - return style, nil -} - -// StyleEntries mapping TokenType to colour definition. -type StyleEntries map[TokenType]string - -// NewXMLStyle parses an XML style definition. -func NewXMLStyle(r io.Reader) (*Style, error) { - dec := xml.NewDecoder(r) - style := &Style{} - return style, dec.Decode(style) -} - -// MustNewXMLStyle is like NewXMLStyle but panics on error. -func MustNewXMLStyle(r io.Reader) *Style { - style, err := NewXMLStyle(r) - if err != nil { - panic(err) - } - return style -} - -// NewStyle creates a new style definition. -func NewStyle(name string, entries StyleEntries) (*Style, error) { - return NewStyleBuilder(name).AddAll(entries).Build() -} - -// MustNewStyle creates a new style or panics. -func MustNewStyle(name string, entries StyleEntries) *Style { - style, err := NewStyle(name, entries) - if err != nil { - panic(err) - } - return style -} - -// A Style definition. -// -// See http://pygments.org/docs/styles/ for details. Semantics are intended to be identical. -type Style struct { - Name string - entries map[TokenType]StyleEntry - parent *Style -} - -func (s *Style) MarshalXML(e *xml.Encoder, start xml.StartElement) error { - if s.parent != nil { - return fmt.Errorf("cannot marshal style with parent") - } - start.Name = xml.Name{Local: "style"} - start.Attr = []xml.Attr{{Name: xml.Name{Local: "name"}, Value: s.Name}} - if err := e.EncodeToken(start); err != nil { - return err - } - sorted := make([]TokenType, 0, len(s.entries)) - for ttype := range s.entries { - sorted = append(sorted, ttype) - } - sort.Slice(sorted, func(i, j int) bool { return sorted[i] < sorted[j] }) - for _, ttype := range sorted { - entry := s.entries[ttype] - el := xml.StartElement{Name: xml.Name{Local: "entry"}} - el.Attr = []xml.Attr{ - {Name: xml.Name{Local: "type"}, Value: ttype.String()}, - {Name: xml.Name{Local: "style"}, Value: entry.String()}, - } - if err := e.EncodeToken(el); err != nil { - return err - } - if err := e.EncodeToken(xml.EndElement{Name: el.Name}); err != nil { - return err - } - } - return e.EncodeToken(xml.EndElement{Name: start.Name}) -} - -func (s *Style) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - for _, attr := range start.Attr { - if attr.Name.Local == "name" { - s.Name = attr.Value - } else { - return fmt.Errorf("unexpected attribute %s", attr.Name.Local) - } - } - if s.Name == "" { - return fmt.Errorf("missing style name attribute") - } - s.entries = map[TokenType]StyleEntry{} - for { - tok, err := d.Token() - if err != nil { - return err - } - switch el := tok.(type) { - case xml.StartElement: - if el.Name.Local != "entry" { - return fmt.Errorf("unexpected element %s", el.Name.Local) - } - var ttype TokenType - var entry StyleEntry - for _, attr := range el.Attr { - switch attr.Name.Local { - case "type": - ttype, err = TokenTypeString(attr.Value) - if err != nil { - return err - } - - case "style": - entry, err = ParseStyleEntry(attr.Value) - if err != nil { - return err - } - - default: - return fmt.Errorf("unexpected attribute %s", attr.Name.Local) - } - } - s.entries[ttype] = entry - - case xml.EndElement: - if el.Name.Local == start.Name.Local { - return nil - } - } - } -} - -// Types that are styled. -func (s *Style) Types() []TokenType { - dedupe := map[TokenType]bool{} - for tt := range s.entries { - dedupe[tt] = true - } - if s.parent != nil { - for _, tt := range s.parent.Types() { - dedupe[tt] = true - } - } - out := make([]TokenType, 0, len(dedupe)) - for tt := range dedupe { - out = append(out, tt) - } - return out -} - -// Builder creates a mutable builder from this Style. -// -// The builder can then be safely modified. This is a cheap operation. -func (s *Style) Builder() *StyleBuilder { - return &StyleBuilder{ - name: s.Name, - entries: map[TokenType]string{}, - parent: s, - } -} - -// Has checks if an exact style entry match exists for a token type. -// -// This is distinct from Get() which will merge parent tokens. -func (s *Style) Has(ttype TokenType) bool { - return !s.get(ttype).IsZero() || s.synthesisable(ttype) -} - -// Get a style entry. Will try sub-category or category if an exact match is not found, and -// finally return the Background. -func (s *Style) Get(ttype TokenType) StyleEntry { - return s.get(ttype).Inherit( - s.get(Background), - s.get(Text), - s.get(ttype.Category()), - s.get(ttype.SubCategory())) -} - -func (s *Style) get(ttype TokenType) StyleEntry { - out := s.entries[ttype] - if out.IsZero() && s.parent != nil { - return s.parent.get(ttype) - } - if out.IsZero() && s.synthesisable(ttype) { - out = s.synthesise(ttype) - } - return out -} - -func (s *Style) synthesise(ttype TokenType) StyleEntry { - bg := s.get(Background) - text := StyleEntry{Colour: bg.Colour} - text.Colour = text.Colour.BrightenOrDarken(0.5) - - switch ttype { - // If we don't have a line highlight colour, make one that is 10% brighter/darker than the background. - case LineHighlight: - return StyleEntry{Background: bg.Background.BrightenOrDarken(0.1)} - - // If we don't have line numbers, use the text colour but 20% brighter/darker - case LineNumbers, LineNumbersTable: - return text - - default: - return StyleEntry{} - } -} - -func (s *Style) synthesisable(ttype TokenType) bool { - return ttype == LineHighlight || ttype == LineNumbers || ttype == LineNumbersTable -} - -// MustParseStyleEntry parses a Pygments style entry or panics. -func MustParseStyleEntry(entry string) StyleEntry { - out, err := ParseStyleEntry(entry) - if err != nil { - panic(err) - } - return out -} - -// ParseStyleEntry parses a Pygments style entry. -func ParseStyleEntry(entry string) (StyleEntry, error) { // nolint: gocyclo - out := StyleEntry{} - parts := strings.Fields(entry) - for _, part := range parts { - switch { - case part == "italic": - out.Italic = Yes - case part == "noitalic": - out.Italic = No - case part == "bold": - out.Bold = Yes - case part == "nobold": - out.Bold = No - case part == "underline": - out.Underline = Yes - case part == "nounderline": - out.Underline = No - case part == "inherit": - out.NoInherit = false - case part == "noinherit": - out.NoInherit = true - case part == "bg:": - out.Background = 0 - case strings.HasPrefix(part, "bg:#"): - out.Background = ParseColour(part[3:]) - if !out.Background.IsSet() { - return StyleEntry{}, fmt.Errorf("invalid background colour %q", part) - } - case strings.HasPrefix(part, "border:#"): - out.Border = ParseColour(part[7:]) - if !out.Border.IsSet() { - return StyleEntry{}, fmt.Errorf("invalid border colour %q", part) - } - case strings.HasPrefix(part, "#"): - out.Colour = ParseColour(part) - if !out.Colour.IsSet() { - return StyleEntry{}, fmt.Errorf("invalid colour %q", part) - } - default: - return StyleEntry{}, fmt.Errorf("unknown style element %q", part) - } - } - return out, nil -} diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/abap.xml b/vendor/github.com/alecthomas/chroma/v2/styles/abap.xml deleted file mode 100644 index 36ea2f1d08..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/abap.xml +++ /dev/null @@ -1,11 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/algol.xml b/vendor/github.com/alecthomas/chroma/v2/styles/algol.xml deleted file mode 100644 index e8a6dc1b82..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/algol.xml +++ /dev/null @@ -1,18 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/algol_nu.xml b/vendor/github.com/alecthomas/chroma/v2/styles/algol_nu.xml deleted file mode 100644 index 7fa340f32b..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/algol_nu.xml +++ /dev/null @@ -1,18 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/api.go b/vendor/github.com/alecthomas/chroma/v2/styles/api.go deleted file mode 100644 index e26d6f0a56..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/api.go +++ /dev/null @@ -1,65 +0,0 @@ -package styles - -import ( - "embed" - "io/fs" - "sort" - - "github.com/alecthomas/chroma/v2" -) - -//go:embed *.xml -var embedded embed.FS - -// Registry of Styles. -var Registry = func() map[string]*chroma.Style { - registry := map[string]*chroma.Style{} - // Register all embedded styles. - files, err := fs.ReadDir(embedded, ".") - if err != nil { - panic(err) - } - for _, file := range files { - if file.IsDir() { - continue - } - r, err := embedded.Open(file.Name()) - if err != nil { - panic(err) - } - style, err := chroma.NewXMLStyle(r) - if err != nil { - panic(err) - } - registry[style.Name] = style - _ = r.Close() - } - return registry -}() - -// Fallback style. Reassign to change the default fallback style. -var Fallback = Registry["swapoff"] - -// Register a chroma.Style. -func Register(style *chroma.Style) *chroma.Style { - Registry[style.Name] = style - return style -} - -// Names of all available styles. -func Names() []string { - out := []string{} - for name := range Registry { - out = append(out, name) - } - sort.Strings(out) - return out -} - -// Get named style, or Fallback. -func Get(name string) *chroma.Style { - if style, ok := Registry[name]; ok { - return style - } - return Fallback -} diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/arduino.xml b/vendor/github.com/alecthomas/chroma/v2/styles/arduino.xml deleted file mode 100644 index d9891dc538..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/arduino.xml +++ /dev/null @@ -1,18 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/autumn.xml b/vendor/github.com/alecthomas/chroma/v2/styles/autumn.xml deleted file mode 100644 index 74d2eae988..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/autumn.xml +++ /dev/null @@ -1,36 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/average.xml b/vendor/github.com/alecthomas/chroma/v2/styles/average.xml deleted file mode 100644 index 79bdb95f34..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/average.xml +++ /dev/null @@ -1,74 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/base16-snazzy.xml b/vendor/github.com/alecthomas/chroma/v2/styles/base16-snazzy.xml deleted file mode 100644 index a05ba24e52..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/base16-snazzy.xml +++ /dev/null @@ -1,74 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/borland.xml b/vendor/github.com/alecthomas/chroma/v2/styles/borland.xml deleted file mode 100644 index 0d8f574c64..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/borland.xml +++ /dev/null @@ -1,26 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/bw.xml b/vendor/github.com/alecthomas/chroma/v2/styles/bw.xml deleted file mode 100644 index fb0e868d15..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/bw.xml +++ /dev/null @@ -1,23 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/catppuccin-frappe.xml b/vendor/github.com/alecthomas/chroma/v2/styles/catppuccin-frappe.xml deleted file mode 100644 index 66a361fb71..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/catppuccin-frappe.xml +++ /dev/null @@ -1,83 +0,0 @@ - diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/catppuccin-latte.xml b/vendor/github.com/alecthomas/chroma/v2/styles/catppuccin-latte.xml deleted file mode 100644 index c87c8765d0..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/catppuccin-latte.xml +++ /dev/null @@ -1,83 +0,0 @@ - diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/catppuccin-macchiato.xml b/vendor/github.com/alecthomas/chroma/v2/styles/catppuccin-macchiato.xml deleted file mode 100644 index 5dba9c6474..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/catppuccin-macchiato.xml +++ /dev/null @@ -1,83 +0,0 @@ - diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/catppuccin-mocha.xml b/vendor/github.com/alecthomas/chroma/v2/styles/catppuccin-mocha.xml deleted file mode 100644 index 9f9b9152a0..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/catppuccin-mocha.xml +++ /dev/null @@ -1,83 +0,0 @@ - diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/colorful.xml b/vendor/github.com/alecthomas/chroma/v2/styles/colorful.xml deleted file mode 100644 index 32442d716d..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/colorful.xml +++ /dev/null @@ -1,52 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/compat.go b/vendor/github.com/alecthomas/chroma/v2/styles/compat.go deleted file mode 100644 index 4a6aaa6652..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/compat.go +++ /dev/null @@ -1,66 +0,0 @@ -package styles - -// Present for backwards compatibility. -// -// Deprecated: use styles.Get(name) instead. -var ( - Abap = Registry["abap"] - Algol = Registry["algol"] - AlgolNu = Registry["algol_nu"] - Arduino = Registry["arduino"] - Autumn = Registry["autumn"] - Average = Registry["average"] - Base16Snazzy = Registry["base16-snazzy"] - Borland = Registry["borland"] - BlackWhite = Registry["bw"] - CatppuccinFrappe = Registry["catppuccin-frappe"] - CatppuccinLatte = Registry["catppuccin-latte"] - CatppuccinMacchiato = Registry["catppuccin-macchiato"] - CatppuccinMocha = Registry["catppuccin-mocha"] - Colorful = Registry["colorful"] - DoomOne = Registry["doom-one"] - DoomOne2 = Registry["doom-one2"] - Dracula = Registry["dracula"] - Emacs = Registry["emacs"] - Friendly = Registry["friendly"] - Fruity = Registry["fruity"] - GitHubDark = Registry["github-dark"] - GitHub = Registry["github"] - GruvboxLight = Registry["gruvbox-light"] - Gruvbox = Registry["gruvbox"] - HrDark = Registry["hrdark"] - HrHighContrast = Registry["hr_high_contrast"] - Igor = Registry["igor"] - Lovelace = Registry["lovelace"] - Manni = Registry["manni"] - ModusOperandi = Registry["modus-operandi"] - ModusVivendi = Registry["modus-vivendi"] - Monokai = Registry["monokai"] - MonokaiLight = Registry["monokailight"] - Murphy = Registry["murphy"] - Native = Registry["native"] - Nord = Registry["nord"] - OnesEnterprise = Registry["onesenterprise"] - ParaisoDark = Registry["paraiso-dark"] - ParaisoLight = Registry["paraiso-light"] - Pastie = Registry["pastie"] - Perldoc = Registry["perldoc"] - Pygments = Registry["pygments"] - RainbowDash = Registry["rainbow_dash"] - RosePineDawn = Registry["rose-pine-dawn"] - RosePineMoon = Registry["rose-pine-moon"] - RosePine = Registry["rose-pine"] - Rrt = Registry["rrt"] - SolarizedDark = Registry["solarized-dark"] - SolarizedDark256 = Registry["solarized-dark256"] - SolarizedLight = Registry["solarized-light"] - SwapOff = Registry["swapoff"] - Tango = Registry["tango"] - Trac = Registry["trac"] - Vim = Registry["vim"] - VisualStudio = Registry["vs"] - Vulcan = Registry["vulcan"] - WitchHazel = Registry["witchhazel"] - XcodeDark = Registry["xcode-dark"] - Xcode = Registry["xcode"] -) diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/doom-one.xml b/vendor/github.com/alecthomas/chroma/v2/styles/doom-one.xml deleted file mode 100644 index 1f5127ef90..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/doom-one.xml +++ /dev/null @@ -1,51 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/doom-one2.xml b/vendor/github.com/alecthomas/chroma/v2/styles/doom-one2.xml deleted file mode 100644 index f47debaf09..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/doom-one2.xml +++ /dev/null @@ -1,64 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/dracula.xml b/vendor/github.com/alecthomas/chroma/v2/styles/dracula.xml deleted file mode 100644 index 9df7da11c2..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/dracula.xml +++ /dev/null @@ -1,74 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/emacs.xml b/vendor/github.com/alecthomas/chroma/v2/styles/emacs.xml deleted file mode 100644 index 981ce8e40f..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/emacs.xml +++ /dev/null @@ -1,44 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/evergarden.xml b/vendor/github.com/alecthomas/chroma/v2/styles/evergarden.xml deleted file mode 100644 index da1d9b843b..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/evergarden.xml +++ /dev/null @@ -1,33 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/friendly.xml b/vendor/github.com/alecthomas/chroma/v2/styles/friendly.xml deleted file mode 100644 index f49801040e..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/friendly.xml +++ /dev/null @@ -1,44 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/fruity.xml b/vendor/github.com/alecthomas/chroma/v2/styles/fruity.xml deleted file mode 100644 index bcc06aa7bc..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/fruity.xml +++ /dev/null @@ -1,19 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/github-dark.xml b/vendor/github.com/alecthomas/chroma/v2/styles/github-dark.xml deleted file mode 100644 index 711aeafc4a..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/github-dark.xml +++ /dev/null @@ -1,45 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/github.xml b/vendor/github.com/alecthomas/chroma/v2/styles/github.xml deleted file mode 100644 index d747f65383..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/github.xml +++ /dev/null @@ -1,39 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/gruvbox-light.xml b/vendor/github.com/alecthomas/chroma/v2/styles/gruvbox-light.xml deleted file mode 100644 index 8c4f0642c6..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/gruvbox-light.xml +++ /dev/null @@ -1,33 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/gruvbox.xml b/vendor/github.com/alecthomas/chroma/v2/styles/gruvbox.xml deleted file mode 100644 index 2f6a0a2a05..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/gruvbox.xml +++ /dev/null @@ -1,33 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/hr_high_contrast.xml b/vendor/github.com/alecthomas/chroma/v2/styles/hr_high_contrast.xml deleted file mode 100644 index 61cde204a4..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/hr_high_contrast.xml +++ /dev/null @@ -1,12 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/hrdark.xml b/vendor/github.com/alecthomas/chroma/v2/styles/hrdark.xml deleted file mode 100644 index bc7a6f315e..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/hrdark.xml +++ /dev/null @@ -1,10 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/igor.xml b/vendor/github.com/alecthomas/chroma/v2/styles/igor.xml deleted file mode 100644 index 773c83b603..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/igor.xml +++ /dev/null @@ -1,9 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/lovelace.xml b/vendor/github.com/alecthomas/chroma/v2/styles/lovelace.xml deleted file mode 100644 index e336c930a4..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/lovelace.xml +++ /dev/null @@ -1,53 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/manni.xml b/vendor/github.com/alecthomas/chroma/v2/styles/manni.xml deleted file mode 100644 index 99324bd3b1..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/manni.xml +++ /dev/null @@ -1,44 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/modus-operandi.xml b/vendor/github.com/alecthomas/chroma/v2/styles/modus-operandi.xml deleted file mode 100644 index 023137aae5..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/modus-operandi.xml +++ /dev/null @@ -1,13 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/modus-vivendi.xml b/vendor/github.com/alecthomas/chroma/v2/styles/modus-vivendi.xml deleted file mode 100644 index 8da663dcc0..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/modus-vivendi.xml +++ /dev/null @@ -1,13 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/monokai.xml b/vendor/github.com/alecthomas/chroma/v2/styles/monokai.xml deleted file mode 100644 index 1a789ddec5..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/monokai.xml +++ /dev/null @@ -1,29 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/monokailight.xml b/vendor/github.com/alecthomas/chroma/v2/styles/monokailight.xml deleted file mode 100644 index 85cd23e008..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/monokailight.xml +++ /dev/null @@ -1,26 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/murphy.xml b/vendor/github.com/alecthomas/chroma/v2/styles/murphy.xml deleted file mode 100644 index 112d6205c5..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/murphy.xml +++ /dev/null @@ -1,52 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/native.xml b/vendor/github.com/alecthomas/chroma/v2/styles/native.xml deleted file mode 100644 index 43eea7fd53..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/native.xml +++ /dev/null @@ -1,35 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/nord.xml b/vendor/github.com/alecthomas/chroma/v2/styles/nord.xml deleted file mode 100644 index 1c1d1ffb26..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/nord.xml +++ /dev/null @@ -1,46 +0,0 @@ - diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/nordic.xml b/vendor/github.com/alecthomas/chroma/v2/styles/nordic.xml deleted file mode 100644 index 4c36b8e4ae..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/nordic.xml +++ /dev/null @@ -1,46 +0,0 @@ - diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/onedark.xml b/vendor/github.com/alecthomas/chroma/v2/styles/onedark.xml deleted file mode 100644 index 6921eb5eeb..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/onedark.xml +++ /dev/null @@ -1,25 +0,0 @@ - diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/onesenterprise.xml b/vendor/github.com/alecthomas/chroma/v2/styles/onesenterprise.xml deleted file mode 100644 index ce86db3fbc..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/onesenterprise.xml +++ /dev/null @@ -1,10 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/paraiso-dark.xml b/vendor/github.com/alecthomas/chroma/v2/styles/paraiso-dark.xml deleted file mode 100644 index 788db3f7cb..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/paraiso-dark.xml +++ /dev/null @@ -1,37 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/paraiso-light.xml b/vendor/github.com/alecthomas/chroma/v2/styles/paraiso-light.xml deleted file mode 100644 index 06a63bae17..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/paraiso-light.xml +++ /dev/null @@ -1,37 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/pastie.xml b/vendor/github.com/alecthomas/chroma/v2/styles/pastie.xml deleted file mode 100644 index a3b0abde5c..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/pastie.xml +++ /dev/null @@ -1,45 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/perldoc.xml b/vendor/github.com/alecthomas/chroma/v2/styles/perldoc.xml deleted file mode 100644 index 9e5564c3fb..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/perldoc.xml +++ /dev/null @@ -1,37 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/pygments.xml b/vendor/github.com/alecthomas/chroma/v2/styles/pygments.xml deleted file mode 100644 index a3d0d8bab5..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/pygments.xml +++ /dev/null @@ -1,42 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/rainbow_dash.xml b/vendor/github.com/alecthomas/chroma/v2/styles/rainbow_dash.xml deleted file mode 100644 index 5b0fe49d63..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/rainbow_dash.xml +++ /dev/null @@ -1,40 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/rose-pine-dawn.xml b/vendor/github.com/alecthomas/chroma/v2/styles/rose-pine-dawn.xml deleted file mode 100644 index 788bd6f65c..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/rose-pine-dawn.xml +++ /dev/null @@ -1,29 +0,0 @@ - diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/rose-pine-moon.xml b/vendor/github.com/alecthomas/chroma/v2/styles/rose-pine-moon.xml deleted file mode 100644 index f67b804324..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/rose-pine-moon.xml +++ /dev/null @@ -1,29 +0,0 @@ - diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/rose-pine.xml b/vendor/github.com/alecthomas/chroma/v2/styles/rose-pine.xml deleted file mode 100644 index 3fb70a5ac7..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/rose-pine.xml +++ /dev/null @@ -1,29 +0,0 @@ - diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/rpgle.xml b/vendor/github.com/alecthomas/chroma/v2/styles/rpgle.xml deleted file mode 100644 index 678fd70fa1..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/rpgle.xml +++ /dev/null @@ -1,30 +0,0 @@ - diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/rrt.xml b/vendor/github.com/alecthomas/chroma/v2/styles/rrt.xml deleted file mode 100644 index f2c5feb936..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/rrt.xml +++ /dev/null @@ -1,19 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/solarized-dark.xml b/vendor/github.com/alecthomas/chroma/v2/styles/solarized-dark.xml deleted file mode 100644 index a3cf46fddb..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/solarized-dark.xml +++ /dev/null @@ -1,39 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/solarized-dark256.xml b/vendor/github.com/alecthomas/chroma/v2/styles/solarized-dark256.xml deleted file mode 100644 index 977cfbe3f3..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/solarized-dark256.xml +++ /dev/null @@ -1,41 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/solarized-light.xml b/vendor/github.com/alecthomas/chroma/v2/styles/solarized-light.xml deleted file mode 100644 index 4fbc1d4a67..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/solarized-light.xml +++ /dev/null @@ -1,17 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/swapoff.xml b/vendor/github.com/alecthomas/chroma/v2/styles/swapoff.xml deleted file mode 100644 index 8a398df8d9..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/swapoff.xml +++ /dev/null @@ -1,18 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/tango.xml b/vendor/github.com/alecthomas/chroma/v2/styles/tango.xml deleted file mode 100644 index 5ca46bb75e..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/tango.xml +++ /dev/null @@ -1,72 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/tokyonight-day.xml b/vendor/github.com/alecthomas/chroma/v2/styles/tokyonight-day.xml deleted file mode 100644 index c20d9a41e6..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/tokyonight-day.xml +++ /dev/null @@ -1,83 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/tokyonight-moon.xml b/vendor/github.com/alecthomas/chroma/v2/styles/tokyonight-moon.xml deleted file mode 100644 index 3312f029d1..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/tokyonight-moon.xml +++ /dev/null @@ -1,83 +0,0 @@ - diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/tokyonight-night.xml b/vendor/github.com/alecthomas/chroma/v2/styles/tokyonight-night.xml deleted file mode 100644 index c798bad4dc..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/tokyonight-night.xml +++ /dev/null @@ -1,83 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/tokyonight-storm.xml b/vendor/github.com/alecthomas/chroma/v2/styles/tokyonight-storm.xml deleted file mode 100644 index c081152479..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/tokyonight-storm.xml +++ /dev/null @@ -1,83 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/trac.xml b/vendor/github.com/alecthomas/chroma/v2/styles/trac.xml deleted file mode 100644 index 9f1d266780..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/trac.xml +++ /dev/null @@ -1,35 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/vim.xml b/vendor/github.com/alecthomas/chroma/v2/styles/vim.xml deleted file mode 100644 index fec6934347..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/vim.xml +++ /dev/null @@ -1,29 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/vs.xml b/vendor/github.com/alecthomas/chroma/v2/styles/vs.xml deleted file mode 100644 index 5643501549..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/vs.xml +++ /dev/null @@ -1,16 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/vulcan.xml b/vendor/github.com/alecthomas/chroma/v2/styles/vulcan.xml deleted file mode 100644 index 4e690945e2..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/vulcan.xml +++ /dev/null @@ -1,74 +0,0 @@ - diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/witchhazel.xml b/vendor/github.com/alecthomas/chroma/v2/styles/witchhazel.xml deleted file mode 100644 index 52f2299133..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/witchhazel.xml +++ /dev/null @@ -1,31 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/xcode-dark.xml b/vendor/github.com/alecthomas/chroma/v2/styles/xcode-dark.xml deleted file mode 100644 index 93439791fd..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/xcode-dark.xml +++ /dev/null @@ -1,31 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/styles/xcode.xml b/vendor/github.com/alecthomas/chroma/v2/styles/xcode.xml deleted file mode 100644 index 523d746cf6..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/styles/xcode.xml +++ /dev/null @@ -1,22 +0,0 @@ - \ No newline at end of file diff --git a/vendor/github.com/alecthomas/chroma/v2/table.py b/vendor/github.com/alecthomas/chroma/v2/table.py deleted file mode 100644 index ea4b7556a7..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/table.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env python3 -import re -from collections import defaultdict -from subprocess import check_output - -README_FILE = "README.md" - -lines = check_output(["chroma", "--list"]).decode("utf-8").splitlines() -lines = [line.strip() for line in lines if line.startswith(" ") and not line.startswith(" ")] -lines = sorted(lines, key=lambda l: l.lower()) - -table = defaultdict(list) - -for line in lines: - table[line[0].upper()].append(line) - -rows = [] -for key, value in table.items(): - rows.append("{} | {}".format(key, ", ".join(value))) -tbody = "\n".join(rows) - -with open(README_FILE, "r") as f: - content = f.read() - -with open(README_FILE, "w") as f: - marker = re.compile(r"(?P:----: \\| --------\n).*?(?P\n\n)", re.DOTALL) - replacement = r"\g%s\g" % tbody - updated_content = marker.sub(replacement, content) - f.write(updated_content) - -print(tbody) diff --git a/vendor/github.com/alecthomas/chroma/v2/tokentype_enumer.go b/vendor/github.com/alecthomas/chroma/v2/tokentype_enumer.go deleted file mode 100644 index c3b15f03ca..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/tokentype_enumer.go +++ /dev/null @@ -1,583 +0,0 @@ -// Code generated by "enumer -text -type TokenType"; DO NOT EDIT. - -package chroma - -import ( - "fmt" - "strings" -) - -const _TokenTypeName = "IgnoreNoneOtherErrorCodeLineLineLinkLineTableTDLineTableLineHighlightLineNumbersTableLineNumbersLinePreWrapperBackgroundEOFTypeKeywordKeywordConstantKeywordDeclarationKeywordNamespaceKeywordPseudoKeywordReservedKeywordTypeNameNameAttributeNameClassNameConstantNameDecoratorNameEntityNameExceptionNameKeywordNameLabelNameNamespaceNameOperatorNameOtherNamePseudoNamePropertyNameTagNameBuiltinNameBuiltinPseudoNameVariableNameVariableAnonymousNameVariableClassNameVariableGlobalNameVariableInstanceNameVariableMagicNameFunctionNameFunctionMagicLiteralLiteralDateLiteralOtherLiteralStringLiteralStringAffixLiteralStringAtomLiteralStringBacktickLiteralStringBooleanLiteralStringCharLiteralStringDelimiterLiteralStringDocLiteralStringDoubleLiteralStringEscapeLiteralStringHeredocLiteralStringInterpolLiteralStringNameLiteralStringOtherLiteralStringRegexLiteralStringSingleLiteralStringSymbolLiteralNumberLiteralNumberBinLiteralNumberFloatLiteralNumberHexLiteralNumberIntegerLiteralNumberIntegerLongLiteralNumberOctLiteralNumberByteOperatorOperatorWordPunctuationCommentCommentHashbangCommentMultilineCommentSingleCommentSpecialCommentPreprocCommentPreprocFileGenericGenericDeletedGenericEmphGenericErrorGenericHeadingGenericInsertedGenericOutputGenericPromptGenericStrongGenericSubheadingGenericTracebackGenericUnderlineTextTextWhitespaceTextSymbolTextPunctuation" -const _TokenTypeLowerName = "ignorenoneothererrorcodelinelinelinklinetabletdlinetablelinehighlightlinenumberstablelinenumberslineprewrapperbackgroundeoftypekeywordkeywordconstantkeyworddeclarationkeywordnamespacekeywordpseudokeywordreservedkeywordtypenamenameattributenameclassnameconstantnamedecoratornameentitynameexceptionnamekeywordnamelabelnamenamespacenameoperatornameothernamepseudonamepropertynametagnamebuiltinnamebuiltinpseudonamevariablenamevariableanonymousnamevariableclassnamevariableglobalnamevariableinstancenamevariablemagicnamefunctionnamefunctionmagicliteralliteraldateliteralotherliteralstringliteralstringaffixliteralstringatomliteralstringbacktickliteralstringbooleanliteralstringcharliteralstringdelimiterliteralstringdocliteralstringdoubleliteralstringescapeliteralstringheredocliteralstringinterpolliteralstringnameliteralstringotherliteralstringregexliteralstringsingleliteralstringsymbolliteralnumberliteralnumberbinliteralnumberfloatliteralnumberhexliteralnumberintegerliteralnumberintegerlongliteralnumberoctliteralnumberbyteoperatoroperatorwordpunctuationcommentcommenthashbangcommentmultilinecommentsinglecommentspecialcommentpreproccommentpreprocfilegenericgenericdeletedgenericemphgenericerrorgenericheadinggenericinsertedgenericoutputgenericpromptgenericstronggenericsubheadinggenerictracebackgenericunderlinetexttextwhitespacetextsymboltextpunctuation" - -var _TokenTypeMap = map[TokenType]string{ - -14: _TokenTypeName[0:6], - -13: _TokenTypeName[6:10], - -12: _TokenTypeName[10:15], - -11: _TokenTypeName[15:20], - -10: _TokenTypeName[20:28], - -9: _TokenTypeName[28:36], - -8: _TokenTypeName[36:47], - -7: _TokenTypeName[47:56], - -6: _TokenTypeName[56:69], - -5: _TokenTypeName[69:85], - -4: _TokenTypeName[85:96], - -3: _TokenTypeName[96:100], - -2: _TokenTypeName[100:110], - -1: _TokenTypeName[110:120], - 0: _TokenTypeName[120:127], - 1000: _TokenTypeName[127:134], - 1001: _TokenTypeName[134:149], - 1002: _TokenTypeName[149:167], - 1003: _TokenTypeName[167:183], - 1004: _TokenTypeName[183:196], - 1005: _TokenTypeName[196:211], - 1006: _TokenTypeName[211:222], - 2000: _TokenTypeName[222:226], - 2001: _TokenTypeName[226:239], - 2002: _TokenTypeName[239:248], - 2003: _TokenTypeName[248:260], - 2004: _TokenTypeName[260:273], - 2005: _TokenTypeName[273:283], - 2006: _TokenTypeName[283:296], - 2007: _TokenTypeName[296:307], - 2008: _TokenTypeName[307:316], - 2009: _TokenTypeName[316:329], - 2010: _TokenTypeName[329:341], - 2011: _TokenTypeName[341:350], - 2012: _TokenTypeName[350:360], - 2013: _TokenTypeName[360:372], - 2014: _TokenTypeName[372:379], - 2100: _TokenTypeName[379:390], - 2101: _TokenTypeName[390:407], - 2200: _TokenTypeName[407:419], - 2201: _TokenTypeName[419:440], - 2202: _TokenTypeName[440:457], - 2203: _TokenTypeName[457:475], - 2204: _TokenTypeName[475:495], - 2205: _TokenTypeName[495:512], - 2300: _TokenTypeName[512:524], - 2301: _TokenTypeName[524:541], - 3000: _TokenTypeName[541:548], - 3001: _TokenTypeName[548:559], - 3002: _TokenTypeName[559:571], - 3100: _TokenTypeName[571:584], - 3101: _TokenTypeName[584:602], - 3102: _TokenTypeName[602:619], - 3103: _TokenTypeName[619:640], - 3104: _TokenTypeName[640:660], - 3105: _TokenTypeName[660:677], - 3106: _TokenTypeName[677:699], - 3107: _TokenTypeName[699:715], - 3108: _TokenTypeName[715:734], - 3109: _TokenTypeName[734:753], - 3110: _TokenTypeName[753:773], - 3111: _TokenTypeName[773:794], - 3112: _TokenTypeName[794:811], - 3113: _TokenTypeName[811:829], - 3114: _TokenTypeName[829:847], - 3115: _TokenTypeName[847:866], - 3116: _TokenTypeName[866:885], - 3200: _TokenTypeName[885:898], - 3201: _TokenTypeName[898:914], - 3202: _TokenTypeName[914:932], - 3203: _TokenTypeName[932:948], - 3204: _TokenTypeName[948:968], - 3205: _TokenTypeName[968:992], - 3206: _TokenTypeName[992:1008], - 3207: _TokenTypeName[1008:1025], - 4000: _TokenTypeName[1025:1033], - 4001: _TokenTypeName[1033:1045], - 5000: _TokenTypeName[1045:1056], - 6000: _TokenTypeName[1056:1063], - 6001: _TokenTypeName[1063:1078], - 6002: _TokenTypeName[1078:1094], - 6003: _TokenTypeName[1094:1107], - 6004: _TokenTypeName[1107:1121], - 6100: _TokenTypeName[1121:1135], - 6101: _TokenTypeName[1135:1153], - 7000: _TokenTypeName[1153:1160], - 7001: _TokenTypeName[1160:1174], - 7002: _TokenTypeName[1174:1185], - 7003: _TokenTypeName[1185:1197], - 7004: _TokenTypeName[1197:1211], - 7005: _TokenTypeName[1211:1226], - 7006: _TokenTypeName[1226:1239], - 7007: _TokenTypeName[1239:1252], - 7008: _TokenTypeName[1252:1265], - 7009: _TokenTypeName[1265:1282], - 7010: _TokenTypeName[1282:1298], - 7011: _TokenTypeName[1298:1314], - 8000: _TokenTypeName[1314:1318], - 8001: _TokenTypeName[1318:1332], - 8002: _TokenTypeName[1332:1342], - 8003: _TokenTypeName[1342:1357], -} - -func (i TokenType) String() string { - if str, ok := _TokenTypeMap[i]; ok { - return str - } - return fmt.Sprintf("TokenType(%d)", i) -} - -// An "invalid array index" compiler error signifies that the constant values have changed. -// Re-run the stringer command to generate them again. -func _TokenTypeNoOp() { - var x [1]struct{} - _ = x[Ignore-(-14)] - _ = x[None-(-13)] - _ = x[Other-(-12)] - _ = x[Error-(-11)] - _ = x[CodeLine-(-10)] - _ = x[LineLink-(-9)] - _ = x[LineTableTD-(-8)] - _ = x[LineTable-(-7)] - _ = x[LineHighlight-(-6)] - _ = x[LineNumbersTable-(-5)] - _ = x[LineNumbers-(-4)] - _ = x[Line-(-3)] - _ = x[PreWrapper-(-2)] - _ = x[Background-(-1)] - _ = x[EOFType-(0)] - _ = x[Keyword-(1000)] - _ = x[KeywordConstant-(1001)] - _ = x[KeywordDeclaration-(1002)] - _ = x[KeywordNamespace-(1003)] - _ = x[KeywordPseudo-(1004)] - _ = x[KeywordReserved-(1005)] - _ = x[KeywordType-(1006)] - _ = x[Name-(2000)] - _ = x[NameAttribute-(2001)] - _ = x[NameClass-(2002)] - _ = x[NameConstant-(2003)] - _ = x[NameDecorator-(2004)] - _ = x[NameEntity-(2005)] - _ = x[NameException-(2006)] - _ = x[NameKeyword-(2007)] - _ = x[NameLabel-(2008)] - _ = x[NameNamespace-(2009)] - _ = x[NameOperator-(2010)] - _ = x[NameOther-(2011)] - _ = x[NamePseudo-(2012)] - _ = x[NameProperty-(2013)] - _ = x[NameTag-(2014)] - _ = x[NameBuiltin-(2100)] - _ = x[NameBuiltinPseudo-(2101)] - _ = x[NameVariable-(2200)] - _ = x[NameVariableAnonymous-(2201)] - _ = x[NameVariableClass-(2202)] - _ = x[NameVariableGlobal-(2203)] - _ = x[NameVariableInstance-(2204)] - _ = x[NameVariableMagic-(2205)] - _ = x[NameFunction-(2300)] - _ = x[NameFunctionMagic-(2301)] - _ = x[Literal-(3000)] - _ = x[LiteralDate-(3001)] - _ = x[LiteralOther-(3002)] - _ = x[LiteralString-(3100)] - _ = x[LiteralStringAffix-(3101)] - _ = x[LiteralStringAtom-(3102)] - _ = x[LiteralStringBacktick-(3103)] - _ = x[LiteralStringBoolean-(3104)] - _ = x[LiteralStringChar-(3105)] - _ = x[LiteralStringDelimiter-(3106)] - _ = x[LiteralStringDoc-(3107)] - _ = x[LiteralStringDouble-(3108)] - _ = x[LiteralStringEscape-(3109)] - _ = x[LiteralStringHeredoc-(3110)] - _ = x[LiteralStringInterpol-(3111)] - _ = x[LiteralStringName-(3112)] - _ = x[LiteralStringOther-(3113)] - _ = x[LiteralStringRegex-(3114)] - _ = x[LiteralStringSingle-(3115)] - _ = x[LiteralStringSymbol-(3116)] - _ = x[LiteralNumber-(3200)] - _ = x[LiteralNumberBin-(3201)] - _ = x[LiteralNumberFloat-(3202)] - _ = x[LiteralNumberHex-(3203)] - _ = x[LiteralNumberInteger-(3204)] - _ = x[LiteralNumberIntegerLong-(3205)] - _ = x[LiteralNumberOct-(3206)] - _ = x[LiteralNumberByte-(3207)] - _ = x[Operator-(4000)] - _ = x[OperatorWord-(4001)] - _ = x[Punctuation-(5000)] - _ = x[Comment-(6000)] - _ = x[CommentHashbang-(6001)] - _ = x[CommentMultiline-(6002)] - _ = x[CommentSingle-(6003)] - _ = x[CommentSpecial-(6004)] - _ = x[CommentPreproc-(6100)] - _ = x[CommentPreprocFile-(6101)] - _ = x[Generic-(7000)] - _ = x[GenericDeleted-(7001)] - _ = x[GenericEmph-(7002)] - _ = x[GenericError-(7003)] - _ = x[GenericHeading-(7004)] - _ = x[GenericInserted-(7005)] - _ = x[GenericOutput-(7006)] - _ = x[GenericPrompt-(7007)] - _ = x[GenericStrong-(7008)] - _ = x[GenericSubheading-(7009)] - _ = x[GenericTraceback-(7010)] - _ = x[GenericUnderline-(7011)] - _ = x[Text-(8000)] - _ = x[TextWhitespace-(8001)] - _ = x[TextSymbol-(8002)] - _ = x[TextPunctuation-(8003)] -} - -var _TokenTypeValues = []TokenType{Ignore, None, Other, Error, CodeLine, LineLink, LineTableTD, LineTable, LineHighlight, LineNumbersTable, LineNumbers, Line, PreWrapper, Background, EOFType, Keyword, KeywordConstant, KeywordDeclaration, KeywordNamespace, KeywordPseudo, KeywordReserved, KeywordType, Name, NameAttribute, NameClass, NameConstant, NameDecorator, NameEntity, NameException, NameKeyword, NameLabel, NameNamespace, NameOperator, NameOther, NamePseudo, NameProperty, NameTag, NameBuiltin, NameBuiltinPseudo, NameVariable, NameVariableAnonymous, NameVariableClass, NameVariableGlobal, NameVariableInstance, NameVariableMagic, NameFunction, NameFunctionMagic, Literal, LiteralDate, LiteralOther, LiteralString, LiteralStringAffix, LiteralStringAtom, LiteralStringBacktick, LiteralStringBoolean, LiteralStringChar, LiteralStringDelimiter, LiteralStringDoc, LiteralStringDouble, LiteralStringEscape, LiteralStringHeredoc, LiteralStringInterpol, LiteralStringName, LiteralStringOther, LiteralStringRegex, LiteralStringSingle, LiteralStringSymbol, LiteralNumber, LiteralNumberBin, LiteralNumberFloat, LiteralNumberHex, LiteralNumberInteger, LiteralNumberIntegerLong, LiteralNumberOct, LiteralNumberByte, Operator, OperatorWord, Punctuation, Comment, CommentHashbang, CommentMultiline, CommentSingle, CommentSpecial, CommentPreproc, CommentPreprocFile, Generic, GenericDeleted, GenericEmph, GenericError, GenericHeading, GenericInserted, GenericOutput, GenericPrompt, GenericStrong, GenericSubheading, GenericTraceback, GenericUnderline, Text, TextWhitespace, TextSymbol, TextPunctuation} - -var _TokenTypeNameToValueMap = map[string]TokenType{ - _TokenTypeName[0:6]: Ignore, - _TokenTypeLowerName[0:6]: Ignore, - _TokenTypeName[6:10]: None, - _TokenTypeLowerName[6:10]: None, - _TokenTypeName[10:15]: Other, - _TokenTypeLowerName[10:15]: Other, - _TokenTypeName[15:20]: Error, - _TokenTypeLowerName[15:20]: Error, - _TokenTypeName[20:28]: CodeLine, - _TokenTypeLowerName[20:28]: CodeLine, - _TokenTypeName[28:36]: LineLink, - _TokenTypeLowerName[28:36]: LineLink, - _TokenTypeName[36:47]: LineTableTD, - _TokenTypeLowerName[36:47]: LineTableTD, - _TokenTypeName[47:56]: LineTable, - _TokenTypeLowerName[47:56]: LineTable, - _TokenTypeName[56:69]: LineHighlight, - _TokenTypeLowerName[56:69]: LineHighlight, - _TokenTypeName[69:85]: LineNumbersTable, - _TokenTypeLowerName[69:85]: LineNumbersTable, - _TokenTypeName[85:96]: LineNumbers, - _TokenTypeLowerName[85:96]: LineNumbers, - _TokenTypeName[96:100]: Line, - _TokenTypeLowerName[96:100]: Line, - _TokenTypeName[100:110]: PreWrapper, - _TokenTypeLowerName[100:110]: PreWrapper, - _TokenTypeName[110:120]: Background, - _TokenTypeLowerName[110:120]: Background, - _TokenTypeName[120:127]: EOFType, - _TokenTypeLowerName[120:127]: EOFType, - _TokenTypeName[127:134]: Keyword, - _TokenTypeLowerName[127:134]: Keyword, - _TokenTypeName[134:149]: KeywordConstant, - _TokenTypeLowerName[134:149]: KeywordConstant, - _TokenTypeName[149:167]: KeywordDeclaration, - _TokenTypeLowerName[149:167]: KeywordDeclaration, - _TokenTypeName[167:183]: KeywordNamespace, - _TokenTypeLowerName[167:183]: KeywordNamespace, - _TokenTypeName[183:196]: KeywordPseudo, - _TokenTypeLowerName[183:196]: KeywordPseudo, - _TokenTypeName[196:211]: KeywordReserved, - _TokenTypeLowerName[196:211]: KeywordReserved, - _TokenTypeName[211:222]: KeywordType, - _TokenTypeLowerName[211:222]: KeywordType, - _TokenTypeName[222:226]: Name, - _TokenTypeLowerName[222:226]: Name, - _TokenTypeName[226:239]: NameAttribute, - _TokenTypeLowerName[226:239]: NameAttribute, - _TokenTypeName[239:248]: NameClass, - _TokenTypeLowerName[239:248]: NameClass, - _TokenTypeName[248:260]: NameConstant, - _TokenTypeLowerName[248:260]: NameConstant, - _TokenTypeName[260:273]: NameDecorator, - _TokenTypeLowerName[260:273]: NameDecorator, - _TokenTypeName[273:283]: NameEntity, - _TokenTypeLowerName[273:283]: NameEntity, - _TokenTypeName[283:296]: NameException, - _TokenTypeLowerName[283:296]: NameException, - _TokenTypeName[296:307]: NameKeyword, - _TokenTypeLowerName[296:307]: NameKeyword, - _TokenTypeName[307:316]: NameLabel, - _TokenTypeLowerName[307:316]: NameLabel, - _TokenTypeName[316:329]: NameNamespace, - _TokenTypeLowerName[316:329]: NameNamespace, - _TokenTypeName[329:341]: NameOperator, - _TokenTypeLowerName[329:341]: NameOperator, - _TokenTypeName[341:350]: NameOther, - _TokenTypeLowerName[341:350]: NameOther, - _TokenTypeName[350:360]: NamePseudo, - _TokenTypeLowerName[350:360]: NamePseudo, - _TokenTypeName[360:372]: NameProperty, - _TokenTypeLowerName[360:372]: NameProperty, - _TokenTypeName[372:379]: NameTag, - _TokenTypeLowerName[372:379]: NameTag, - _TokenTypeName[379:390]: NameBuiltin, - _TokenTypeLowerName[379:390]: NameBuiltin, - _TokenTypeName[390:407]: NameBuiltinPseudo, - _TokenTypeLowerName[390:407]: NameBuiltinPseudo, - _TokenTypeName[407:419]: NameVariable, - _TokenTypeLowerName[407:419]: NameVariable, - _TokenTypeName[419:440]: NameVariableAnonymous, - _TokenTypeLowerName[419:440]: NameVariableAnonymous, - _TokenTypeName[440:457]: NameVariableClass, - _TokenTypeLowerName[440:457]: NameVariableClass, - _TokenTypeName[457:475]: NameVariableGlobal, - _TokenTypeLowerName[457:475]: NameVariableGlobal, - _TokenTypeName[475:495]: NameVariableInstance, - _TokenTypeLowerName[475:495]: NameVariableInstance, - _TokenTypeName[495:512]: NameVariableMagic, - _TokenTypeLowerName[495:512]: NameVariableMagic, - _TokenTypeName[512:524]: NameFunction, - _TokenTypeLowerName[512:524]: NameFunction, - _TokenTypeName[524:541]: NameFunctionMagic, - _TokenTypeLowerName[524:541]: NameFunctionMagic, - _TokenTypeName[541:548]: Literal, - _TokenTypeLowerName[541:548]: Literal, - _TokenTypeName[548:559]: LiteralDate, - _TokenTypeLowerName[548:559]: LiteralDate, - _TokenTypeName[559:571]: LiteralOther, - _TokenTypeLowerName[559:571]: LiteralOther, - _TokenTypeName[571:584]: LiteralString, - _TokenTypeLowerName[571:584]: LiteralString, - _TokenTypeName[584:602]: LiteralStringAffix, - _TokenTypeLowerName[584:602]: LiteralStringAffix, - _TokenTypeName[602:619]: LiteralStringAtom, - _TokenTypeLowerName[602:619]: LiteralStringAtom, - _TokenTypeName[619:640]: LiteralStringBacktick, - _TokenTypeLowerName[619:640]: LiteralStringBacktick, - _TokenTypeName[640:660]: LiteralStringBoolean, - _TokenTypeLowerName[640:660]: LiteralStringBoolean, - _TokenTypeName[660:677]: LiteralStringChar, - _TokenTypeLowerName[660:677]: LiteralStringChar, - _TokenTypeName[677:699]: LiteralStringDelimiter, - _TokenTypeLowerName[677:699]: LiteralStringDelimiter, - _TokenTypeName[699:715]: LiteralStringDoc, - _TokenTypeLowerName[699:715]: LiteralStringDoc, - _TokenTypeName[715:734]: LiteralStringDouble, - _TokenTypeLowerName[715:734]: LiteralStringDouble, - _TokenTypeName[734:753]: LiteralStringEscape, - _TokenTypeLowerName[734:753]: LiteralStringEscape, - _TokenTypeName[753:773]: LiteralStringHeredoc, - _TokenTypeLowerName[753:773]: LiteralStringHeredoc, - _TokenTypeName[773:794]: LiteralStringInterpol, - _TokenTypeLowerName[773:794]: LiteralStringInterpol, - _TokenTypeName[794:811]: LiteralStringName, - _TokenTypeLowerName[794:811]: LiteralStringName, - _TokenTypeName[811:829]: LiteralStringOther, - _TokenTypeLowerName[811:829]: LiteralStringOther, - _TokenTypeName[829:847]: LiteralStringRegex, - _TokenTypeLowerName[829:847]: LiteralStringRegex, - _TokenTypeName[847:866]: LiteralStringSingle, - _TokenTypeLowerName[847:866]: LiteralStringSingle, - _TokenTypeName[866:885]: LiteralStringSymbol, - _TokenTypeLowerName[866:885]: LiteralStringSymbol, - _TokenTypeName[885:898]: LiteralNumber, - _TokenTypeLowerName[885:898]: LiteralNumber, - _TokenTypeName[898:914]: LiteralNumberBin, - _TokenTypeLowerName[898:914]: LiteralNumberBin, - _TokenTypeName[914:932]: LiteralNumberFloat, - _TokenTypeLowerName[914:932]: LiteralNumberFloat, - _TokenTypeName[932:948]: LiteralNumberHex, - _TokenTypeLowerName[932:948]: LiteralNumberHex, - _TokenTypeName[948:968]: LiteralNumberInteger, - _TokenTypeLowerName[948:968]: LiteralNumberInteger, - _TokenTypeName[968:992]: LiteralNumberIntegerLong, - _TokenTypeLowerName[968:992]: LiteralNumberIntegerLong, - _TokenTypeName[992:1008]: LiteralNumberOct, - _TokenTypeLowerName[992:1008]: LiteralNumberOct, - _TokenTypeName[1008:1025]: LiteralNumberByte, - _TokenTypeLowerName[1008:1025]: LiteralNumberByte, - _TokenTypeName[1025:1033]: Operator, - _TokenTypeLowerName[1025:1033]: Operator, - _TokenTypeName[1033:1045]: OperatorWord, - _TokenTypeLowerName[1033:1045]: OperatorWord, - _TokenTypeName[1045:1056]: Punctuation, - _TokenTypeLowerName[1045:1056]: Punctuation, - _TokenTypeName[1056:1063]: Comment, - _TokenTypeLowerName[1056:1063]: Comment, - _TokenTypeName[1063:1078]: CommentHashbang, - _TokenTypeLowerName[1063:1078]: CommentHashbang, - _TokenTypeName[1078:1094]: CommentMultiline, - _TokenTypeLowerName[1078:1094]: CommentMultiline, - _TokenTypeName[1094:1107]: CommentSingle, - _TokenTypeLowerName[1094:1107]: CommentSingle, - _TokenTypeName[1107:1121]: CommentSpecial, - _TokenTypeLowerName[1107:1121]: CommentSpecial, - _TokenTypeName[1121:1135]: CommentPreproc, - _TokenTypeLowerName[1121:1135]: CommentPreproc, - _TokenTypeName[1135:1153]: CommentPreprocFile, - _TokenTypeLowerName[1135:1153]: CommentPreprocFile, - _TokenTypeName[1153:1160]: Generic, - _TokenTypeLowerName[1153:1160]: Generic, - _TokenTypeName[1160:1174]: GenericDeleted, - _TokenTypeLowerName[1160:1174]: GenericDeleted, - _TokenTypeName[1174:1185]: GenericEmph, - _TokenTypeLowerName[1174:1185]: GenericEmph, - _TokenTypeName[1185:1197]: GenericError, - _TokenTypeLowerName[1185:1197]: GenericError, - _TokenTypeName[1197:1211]: GenericHeading, - _TokenTypeLowerName[1197:1211]: GenericHeading, - _TokenTypeName[1211:1226]: GenericInserted, - _TokenTypeLowerName[1211:1226]: GenericInserted, - _TokenTypeName[1226:1239]: GenericOutput, - _TokenTypeLowerName[1226:1239]: GenericOutput, - _TokenTypeName[1239:1252]: GenericPrompt, - _TokenTypeLowerName[1239:1252]: GenericPrompt, - _TokenTypeName[1252:1265]: GenericStrong, - _TokenTypeLowerName[1252:1265]: GenericStrong, - _TokenTypeName[1265:1282]: GenericSubheading, - _TokenTypeLowerName[1265:1282]: GenericSubheading, - _TokenTypeName[1282:1298]: GenericTraceback, - _TokenTypeLowerName[1282:1298]: GenericTraceback, - _TokenTypeName[1298:1314]: GenericUnderline, - _TokenTypeLowerName[1298:1314]: GenericUnderline, - _TokenTypeName[1314:1318]: Text, - _TokenTypeLowerName[1314:1318]: Text, - _TokenTypeName[1318:1332]: TextWhitespace, - _TokenTypeLowerName[1318:1332]: TextWhitespace, - _TokenTypeName[1332:1342]: TextSymbol, - _TokenTypeLowerName[1332:1342]: TextSymbol, - _TokenTypeName[1342:1357]: TextPunctuation, - _TokenTypeLowerName[1342:1357]: TextPunctuation, -} - -var _TokenTypeNames = []string{ - _TokenTypeName[0:6], - _TokenTypeName[6:10], - _TokenTypeName[10:15], - _TokenTypeName[15:20], - _TokenTypeName[20:28], - _TokenTypeName[28:36], - _TokenTypeName[36:47], - _TokenTypeName[47:56], - _TokenTypeName[56:69], - _TokenTypeName[69:85], - _TokenTypeName[85:96], - _TokenTypeName[96:100], - _TokenTypeName[100:110], - _TokenTypeName[110:120], - _TokenTypeName[120:127], - _TokenTypeName[127:134], - _TokenTypeName[134:149], - _TokenTypeName[149:167], - _TokenTypeName[167:183], - _TokenTypeName[183:196], - _TokenTypeName[196:211], - _TokenTypeName[211:222], - _TokenTypeName[222:226], - _TokenTypeName[226:239], - _TokenTypeName[239:248], - _TokenTypeName[248:260], - _TokenTypeName[260:273], - _TokenTypeName[273:283], - _TokenTypeName[283:296], - _TokenTypeName[296:307], - _TokenTypeName[307:316], - _TokenTypeName[316:329], - _TokenTypeName[329:341], - _TokenTypeName[341:350], - _TokenTypeName[350:360], - _TokenTypeName[360:372], - _TokenTypeName[372:379], - _TokenTypeName[379:390], - _TokenTypeName[390:407], - _TokenTypeName[407:419], - _TokenTypeName[419:440], - _TokenTypeName[440:457], - _TokenTypeName[457:475], - _TokenTypeName[475:495], - _TokenTypeName[495:512], - _TokenTypeName[512:524], - _TokenTypeName[524:541], - _TokenTypeName[541:548], - _TokenTypeName[548:559], - _TokenTypeName[559:571], - _TokenTypeName[571:584], - _TokenTypeName[584:602], - _TokenTypeName[602:619], - _TokenTypeName[619:640], - _TokenTypeName[640:660], - _TokenTypeName[660:677], - _TokenTypeName[677:699], - _TokenTypeName[699:715], - _TokenTypeName[715:734], - _TokenTypeName[734:753], - _TokenTypeName[753:773], - _TokenTypeName[773:794], - _TokenTypeName[794:811], - _TokenTypeName[811:829], - _TokenTypeName[829:847], - _TokenTypeName[847:866], - _TokenTypeName[866:885], - _TokenTypeName[885:898], - _TokenTypeName[898:914], - _TokenTypeName[914:932], - _TokenTypeName[932:948], - _TokenTypeName[948:968], - _TokenTypeName[968:992], - _TokenTypeName[992:1008], - _TokenTypeName[1008:1025], - _TokenTypeName[1025:1033], - _TokenTypeName[1033:1045], - _TokenTypeName[1045:1056], - _TokenTypeName[1056:1063], - _TokenTypeName[1063:1078], - _TokenTypeName[1078:1094], - _TokenTypeName[1094:1107], - _TokenTypeName[1107:1121], - _TokenTypeName[1121:1135], - _TokenTypeName[1135:1153], - _TokenTypeName[1153:1160], - _TokenTypeName[1160:1174], - _TokenTypeName[1174:1185], - _TokenTypeName[1185:1197], - _TokenTypeName[1197:1211], - _TokenTypeName[1211:1226], - _TokenTypeName[1226:1239], - _TokenTypeName[1239:1252], - _TokenTypeName[1252:1265], - _TokenTypeName[1265:1282], - _TokenTypeName[1282:1298], - _TokenTypeName[1298:1314], - _TokenTypeName[1314:1318], - _TokenTypeName[1318:1332], - _TokenTypeName[1332:1342], - _TokenTypeName[1342:1357], -} - -// TokenTypeString retrieves an enum value from the enum constants string name. -// Throws an error if the param is not part of the enum. -func TokenTypeString(s string) (TokenType, error) { - if val, ok := _TokenTypeNameToValueMap[s]; ok { - return val, nil - } - - if val, ok := _TokenTypeNameToValueMap[strings.ToLower(s)]; ok { - return val, nil - } - return 0, fmt.Errorf("%s does not belong to TokenType values", s) -} - -// TokenTypeValues returns all values of the enum -func TokenTypeValues() []TokenType { - return _TokenTypeValues -} - -// TokenTypeStrings returns a slice of all String values of the enum -func TokenTypeStrings() []string { - strs := make([]string, len(_TokenTypeNames)) - copy(strs, _TokenTypeNames) - return strs -} - -// IsATokenType returns "true" if the value is listed in the enum definition. "false" otherwise -func (i TokenType) IsATokenType() bool { - _, ok := _TokenTypeMap[i] - return ok -} - -// MarshalText implements the encoding.TextMarshaler interface for TokenType -func (i TokenType) MarshalText() ([]byte, error) { - return []byte(i.String()), nil -} - -// UnmarshalText implements the encoding.TextUnmarshaler interface for TokenType -func (i *TokenType) UnmarshalText(text []byte) error { - var err error - *i, err = TokenTypeString(string(text)) - return err -} diff --git a/vendor/github.com/alecthomas/chroma/v2/types.go b/vendor/github.com/alecthomas/chroma/v2/types.go deleted file mode 100644 index 3009f98095..0000000000 --- a/vendor/github.com/alecthomas/chroma/v2/types.go +++ /dev/null @@ -1,355 +0,0 @@ -package chroma - -//go:generate enumer -text -type TokenType - -// TokenType is the type of token to highlight. -// -// It is also an Emitter, emitting a single token of itself -type TokenType int - -// Set of TokenTypes. -// -// Categories of types are grouped in ranges of 1000, while sub-categories are in ranges of 100. For -// example, the literal category is in the range 3000-3999. The sub-category for literal strings is -// in the range 3100-3199. - -// Meta token types. -const ( - // Default background style. - Background TokenType = -1 - iota - // PreWrapper style. - PreWrapper - // Line style. - Line - // Line numbers in output. - LineNumbers - // Line numbers in output when in table. - LineNumbersTable - // Line higlight style. - LineHighlight - // Line numbers table wrapper style. - LineTable - // Line numbers table TD wrapper style. - LineTableTD - // Line number links. - LineLink - // Code line wrapper style. - CodeLine - // Input that could not be tokenised. - Error - // Other is used by the Delegate lexer to indicate which tokens should be handled by the delegate. - Other - // No highlighting. - None - // Don't emit this token to the output. - Ignore - // Used as an EOF marker / nil token - EOFType TokenType = 0 -) - -// Keywords. -const ( - Keyword TokenType = 1000 + iota - KeywordConstant - KeywordDeclaration - KeywordNamespace - KeywordPseudo - KeywordReserved - KeywordType -) - -// Names. -const ( - Name TokenType = 2000 + iota - NameAttribute - NameClass - NameConstant - NameDecorator - NameEntity - NameException - NameKeyword - NameLabel - NameNamespace - NameOperator - NameOther - NamePseudo - NameProperty - NameTag -) - -// Builtin names. -const ( - NameBuiltin TokenType = 2100 + iota - NameBuiltinPseudo -) - -// Variable names. -const ( - NameVariable TokenType = 2200 + iota - NameVariableAnonymous - NameVariableClass - NameVariableGlobal - NameVariableInstance - NameVariableMagic -) - -// Function names. -const ( - NameFunction TokenType = 2300 + iota - NameFunctionMagic -) - -// Literals. -const ( - Literal TokenType = 3000 + iota - LiteralDate - LiteralOther -) - -// Strings. -const ( - LiteralString TokenType = 3100 + iota - LiteralStringAffix - LiteralStringAtom - LiteralStringBacktick - LiteralStringBoolean - LiteralStringChar - LiteralStringDelimiter - LiteralStringDoc - LiteralStringDouble - LiteralStringEscape - LiteralStringHeredoc - LiteralStringInterpol - LiteralStringName - LiteralStringOther - LiteralStringRegex - LiteralStringSingle - LiteralStringSymbol -) - -// Literals. -const ( - LiteralNumber TokenType = 3200 + iota - LiteralNumberBin - LiteralNumberFloat - LiteralNumberHex - LiteralNumberInteger - LiteralNumberIntegerLong - LiteralNumberOct - LiteralNumberByte -) - -// Operators. -const ( - Operator TokenType = 4000 + iota - OperatorWord -) - -// Punctuation. -const ( - Punctuation TokenType = 5000 + iota -) - -// Comments. -const ( - Comment TokenType = 6000 + iota - CommentHashbang - CommentMultiline - CommentSingle - CommentSpecial -) - -// Preprocessor "comments". -const ( - CommentPreproc TokenType = 6100 + iota - CommentPreprocFile -) - -// Generic tokens. -const ( - Generic TokenType = 7000 + iota - GenericDeleted - GenericEmph - GenericError - GenericHeading - GenericInserted - GenericOutput - GenericPrompt - GenericStrong - GenericSubheading - GenericTraceback - GenericUnderline -) - -// Text. -const ( - Text TokenType = 8000 + iota - TextWhitespace - TextSymbol - TextPunctuation -) - -// Aliases. -const ( - Whitespace = TextWhitespace - - Date = LiteralDate - - String = LiteralString - StringAffix = LiteralStringAffix - StringBacktick = LiteralStringBacktick - StringChar = LiteralStringChar - StringDelimiter = LiteralStringDelimiter - StringDoc = LiteralStringDoc - StringDouble = LiteralStringDouble - StringEscape = LiteralStringEscape - StringHeredoc = LiteralStringHeredoc - StringInterpol = LiteralStringInterpol - StringOther = LiteralStringOther - StringRegex = LiteralStringRegex - StringSingle = LiteralStringSingle - StringSymbol = LiteralStringSymbol - - Number = LiteralNumber - NumberBin = LiteralNumberBin - NumberFloat = LiteralNumberFloat - NumberHex = LiteralNumberHex - NumberInteger = LiteralNumberInteger - NumberIntegerLong = LiteralNumberIntegerLong - NumberOct = LiteralNumberOct -) - -var ( - StandardTypes = map[TokenType]string{ - Background: "bg", - PreWrapper: "chroma", - Line: "line", - LineNumbers: "ln", - LineNumbersTable: "lnt", - LineHighlight: "hl", - LineTable: "lntable", - LineTableTD: "lntd", - LineLink: "lnlinks", - CodeLine: "cl", - Text: "", - Whitespace: "w", - Error: "err", - Other: "x", - // I have no idea what this is used for... - // Escape: "esc", - - Keyword: "k", - KeywordConstant: "kc", - KeywordDeclaration: "kd", - KeywordNamespace: "kn", - KeywordPseudo: "kp", - KeywordReserved: "kr", - KeywordType: "kt", - - Name: "n", - NameAttribute: "na", - NameBuiltin: "nb", - NameBuiltinPseudo: "bp", - NameClass: "nc", - NameConstant: "no", - NameDecorator: "nd", - NameEntity: "ni", - NameException: "ne", - NameFunction: "nf", - NameFunctionMagic: "fm", - NameProperty: "py", - NameLabel: "nl", - NameNamespace: "nn", - NameOther: "nx", - NameTag: "nt", - NameVariable: "nv", - NameVariableClass: "vc", - NameVariableGlobal: "vg", - NameVariableInstance: "vi", - NameVariableMagic: "vm", - - Literal: "l", - LiteralDate: "ld", - - String: "s", - StringAffix: "sa", - StringBacktick: "sb", - StringChar: "sc", - StringDelimiter: "dl", - StringDoc: "sd", - StringDouble: "s2", - StringEscape: "se", - StringHeredoc: "sh", - StringInterpol: "si", - StringOther: "sx", - StringRegex: "sr", - StringSingle: "s1", - StringSymbol: "ss", - - Number: "m", - NumberBin: "mb", - NumberFloat: "mf", - NumberHex: "mh", - NumberInteger: "mi", - NumberIntegerLong: "il", - NumberOct: "mo", - - Operator: "o", - OperatorWord: "ow", - - Punctuation: "p", - - Comment: "c", - CommentHashbang: "ch", - CommentMultiline: "cm", - CommentPreproc: "cp", - CommentPreprocFile: "cpf", - CommentSingle: "c1", - CommentSpecial: "cs", - - Generic: "g", - GenericDeleted: "gd", - GenericEmph: "ge", - GenericError: "gr", - GenericHeading: "gh", - GenericInserted: "gi", - GenericOutput: "go", - GenericPrompt: "gp", - GenericStrong: "gs", - GenericSubheading: "gu", - GenericTraceback: "gt", - GenericUnderline: "gl", - } -) - -func (t TokenType) Parent() TokenType { - if t%100 != 0 { - return t / 100 * 100 - } - if t%1000 != 0 { - return t / 1000 * 1000 - } - return 0 -} - -func (t TokenType) Category() TokenType { - return t / 1000 * 1000 -} - -func (t TokenType) SubCategory() TokenType { - return t / 100 * 100 -} - -func (t TokenType) InCategory(other TokenType) bool { - return t/1000 == other/1000 -} - -func (t TokenType) InSubCategory(other TokenType) bool { - return t/100 == other/100 -} - -func (t TokenType) Emit(groups []string, _ *LexerState) Iterator { - return Literator(Token{Type: t, Value: groups[0]}) -} - -func (t TokenType) EmitterKind() string { return "token" } diff --git a/vendor/github.com/alecthomas/go-check-sumtype/.golangci.yml b/vendor/github.com/alecthomas/go-check-sumtype/.golangci.yml deleted file mode 100644 index 758ae1a9e4..0000000000 --- a/vendor/github.com/alecthomas/go-check-sumtype/.golangci.yml +++ /dev/null @@ -1,92 +0,0 @@ -run: - tests: true - -output: - print-issued-lines: false - -linters: - enable-all: true - disable: - - cyclop - - depguard - - dupl - - dupword - - err113 - - errorlint - - exhaustive - - exhaustruct - - exportloopref - - forcetypeassert - - funlen - - gci - - gochecknoglobals - - gocognit - - goconst - - gocyclo - - godot - - godox - - gofumpt - - govet - - ireturn - - lll - - maintidx - - mnd - - mnd - - musttag - - nestif - - nilnil - - nlreturn - - nolintlint - - nonamedreturns - - paralleltest - - perfsprint - - predeclared - - revive - - stylecheck - - testableexamples - - testpackage - - thelper - - varnamelen - - wrapcheck - - wsl - -linters-settings: - govet: - enable: - - shadow - gocyclo: - min-complexity: 10 - dupl: - threshold: 100 - goconst: - min-len: 8 - min-occurrences: 3 - forbidigo: - exclude-godoc-examples: false - #forbid: - # - (Must)?NewLexer$ - -issues: - max-issues-per-linter: 0 - max-same-issues: 0 - exclude-use-default: false - exclude-dirs: - - _examples - exclude: - # Captured by errcheck. - - "^(G104|G204):" - # Very commonly not checked. - - 'Error return value of .(.*\.Help|.*\.MarkFlagRequired|(os\.)?std(out|err)\..*|.*Close|.*Flush|os\.Remove(All)?|.*printf?|os\.(Un)?Setenv). is not checked' - - 'exported method (.*\.MarshalJSON|.*\.UnmarshalJSON|.*\.EntityURN|.*\.GoString|.*\.Pos) should have comment or be unexported' - - "composite literal uses unkeyed fields" - - 'declaration of "err" shadows declaration' - - "should not use dot imports" - - "Potential file inclusion via variable" - - "should have comment or be unexported" - - "comment on exported var .* should be of the form" - - "at least one file in a package should have a package comment" - - "string literal contains the Unicode" - - "methods on the same type should have the same receiver name" - - "_TokenType_name should be _TokenTypeName" - - "`_TokenType_map` should be `_TokenTypeMap`" - - "rewrite if-else to switch statement" diff --git a/vendor/github.com/alecthomas/go-check-sumtype/.goreleaser.yml b/vendor/github.com/alecthomas/go-check-sumtype/.goreleaser.yml deleted file mode 100644 index 33bd03d060..0000000000 --- a/vendor/github.com/alecthomas/go-check-sumtype/.goreleaser.yml +++ /dev/null @@ -1,32 +0,0 @@ -project_name: go-check-sumtype -release: - github: - owner: alecthomas - name: go-check-sumtype -env: - - CGO_ENABLED=0 -builds: -- goos: - - linux - - darwin - - windows - goarch: - - arm64 - - amd64 - - "386" - goarm: - - "6" - main: ./cmd/go-check-sumtype - binary: go-check-sumtype -archives: - - - format: tar.gz - name_template: '{{ .Binary }}-{{ .Version }}-{{ .Os }}-{{ .Arch }}{{ if .Arm }}v{{ - .Arm }}{{ end }}' - files: - - COPYING - - README* -snapshot: - name_template: SNAPSHOT-{{ .Commit }} -checksum: - name_template: '{{ .ProjectName }}-{{ .Version }}-checksums.txt' diff --git a/vendor/github.com/alecthomas/go-check-sumtype/COPYING b/vendor/github.com/alecthomas/go-check-sumtype/COPYING deleted file mode 100644 index bb9c20a094..0000000000 --- a/vendor/github.com/alecthomas/go-check-sumtype/COPYING +++ /dev/null @@ -1,3 +0,0 @@ -This project is dual-licensed under the Unlicense and MIT licenses. - -You may use this code under the terms of either license. diff --git a/vendor/github.com/alecthomas/go-check-sumtype/LICENSE-MIT b/vendor/github.com/alecthomas/go-check-sumtype/LICENSE-MIT deleted file mode 100644 index 3b0a5dc09c..0000000000 --- a/vendor/github.com/alecthomas/go-check-sumtype/LICENSE-MIT +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015 Andrew Gallant - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/vendor/github.com/alecthomas/go-check-sumtype/README.md b/vendor/github.com/alecthomas/go-check-sumtype/README.md deleted file mode 100644 index 287aa68b7f..0000000000 --- a/vendor/github.com/alecthomas/go-check-sumtype/README.md +++ /dev/null @@ -1,127 +0,0 @@ -**Note: This is a fork of the great project [go-sumtype](https://github.com/BurntSushi/go-sumtype) by BurntSushi.** -**The original seems largely unmaintained, and the changes in this fork are backwards incompatible.** - -# go-check-sumtype [![CI](https://github.com/alecthomas/go-check-sumtype/actions/workflows/ci.yml/badge.svg)](https://github.com/alecthomas/go-check-sumtype/actions/workflows/ci.yml) -A simple utility for running exhaustiveness checks on type switch statements. -Exhaustiveness checks are only run on interfaces that are declared to be -"sum types." - -Dual-licensed under MIT or the [UNLICENSE](http://unlicense.org). - -This work was inspired by our code at -[Diffeo](https://diffeo.com). - -## Installation - -```go -$ go get github.com/alecthomas/go-check-sumtype -``` - -For usage info, just run the command: - -``` -$ go-check-sumtype -``` - -Typical usage might look like this: - -``` -$ go-check-sumtype $(go list ./... | grep -v vendor) -``` - -## Usage - -`go-check-sumtype` takes a list of Go package paths or files and looks for sum type -declarations in each package/file provided. Exhaustiveness checks are then -performed for each use of a declared sum type in a type switch statement. -Namely, `go-check-sumtype` will report an error for any type switch statement that -either lacks a `default` clause or does not account for all possible variants. - -Declarations are provided in comments like so: - -``` -//sumtype:decl -type MySumType interface { ... } -``` - -`MySumType` must be *sealed*. That is, part of its interface definition -contains an unexported method. - -`go-check-sumtype` will produce an error if any of the above is not true. - -For valid declarations, `go-check-sumtype` will look for all occurrences in which a -value of type `MySumType` participates in a type switch statement. In those -occurrences, it will attempt to detect whether the type switch is exhaustive -or not. If it's not, `go-check-sumtype` will report an error. For example, running -`go-check-sumtype` on this source file: - -```go -package main - -//sumtype:decl -type MySumType interface { - sealed() -} - -type VariantA struct{} - -func (*VariantA) sealed() {} - -type VariantB struct{} - -func (*VariantB) sealed() {} - -func main() { - switch MySumType(nil).(type) { - case *VariantA: - } -} -``` - -produces the following: - -``` -$ sumtype mysumtype.go -mysumtype.go:18:2: exhaustiveness check failed for sum type 'MySumType': missing cases for VariantB -``` - -Adding either a `default` clause or a clause to handle `*VariantB` will cause -exhaustive checks to pass. To prevent `default` clauses from automatically -passing checks, set the `-default-signifies-exhasutive=false` flag. - -As a special case, if the type switch statement contains a `default` clause -that always panics, then exhaustiveness checks are still performed. - -By default, `go-check-sumtype` will not include shared interfaces in the exhaustiviness check. -This can be changed by setting the `-include-shared-interfaces=true` flag. -When this flag is set, `go-check-sumtype` will not require that all concrete structs -are listed in the switch statement, as long as the switch statement is exhaustive -with respect to interfaces the structs implement. - -## Details and motivation - -Sum types are otherwise known as discriminated unions. That is, a sum type is -a finite set of disjoint values. In type systems that support sum types, the -language will guarantee that if one has a sum type `T`, then its value must -be one of its variants. - -Go's type system does not support sum types. A typical proxy for representing -sum types in Go is to use an interface with an unexported method and define -each variant of the sum type in the same package to satisfy said interface. -This guarantees that the set of types that satisfy the interface is closed -at compile time. Performing case analysis on these types is then done with -a type switch statement, e.g., `switch x.(type) { ... }`. Each clause of the -type switch corresponds to a *variant* of the sum type. The downside of this -approach is that Go's type system is not aware of the set of variants, so it -cannot tell you whether case analysis over a sum type is complete or not. - -The `go-check-sumtype` command recognizes this pattern, but it needs a small amount -of help to recognize which interfaces should be treated as sum types, which -is why the `//sumtype:decl` annotation is required. `go-check-sumtype` will -figure out all of the variants of a sum type by finding the set of types -defined in the same package that satisfy the interface specified by the -declaration. - -The `go-check-sumtype` command will prove its worth when you need to add a variant -to an existing sum type. Running `go-check-sumtype` will tell you immediately which -case analyses need to be updated to account for the new variant. diff --git a/vendor/github.com/alecthomas/go-check-sumtype/UNLICENSE b/vendor/github.com/alecthomas/go-check-sumtype/UNLICENSE deleted file mode 100644 index 68a49daad8..0000000000 --- a/vendor/github.com/alecthomas/go-check-sumtype/UNLICENSE +++ /dev/null @@ -1,24 +0,0 @@ -This is free and unencumbered software released into the public domain. - -Anyone is free to copy, modify, publish, use, compile, sell, or -distribute this software, either in source code form or as a compiled -binary, for any purpose, commercial or non-commercial, and by any -means. - -In jurisdictions that recognize copyright laws, the author or authors -of this software dedicate any and all copyright interest in the -software to the public domain. We make this dedication for the benefit -of the public at large and to the detriment of our heirs and -successors. We intend this dedication to be an overt act of -relinquishment in perpetuity of all present and future rights to this -software under copyright law. - -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 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. - -For more information, please refer to diff --git a/vendor/github.com/alecthomas/go-check-sumtype/check.go b/vendor/github.com/alecthomas/go-check-sumtype/check.go deleted file mode 100644 index ff7fec728a..0000000000 --- a/vendor/github.com/alecthomas/go-check-sumtype/check.go +++ /dev/null @@ -1,190 +0,0 @@ -package gochecksumtype - -import ( - "fmt" - "go/ast" - "go/token" - "go/types" - "sort" - "strings" - - "golang.org/x/tools/go/packages" -) - -// inexhaustiveError is returned from check for each occurrence of inexhaustive -// case analysis in a Go type switch statement. -type inexhaustiveError struct { - Position token.Position - Def sumTypeDef - Missing []types.Object -} - -func (e inexhaustiveError) Pos() token.Position { return e.Position } -func (e inexhaustiveError) Error() string { - return fmt.Sprintf( - "%s: exhaustiveness check failed for sum type %q (from %s): missing cases for %s", - e.Pos(), e.Def.Decl.TypeName, e.Def.Decl.Pos, strings.Join(e.Names(), ", ")) -} - -// Names returns a sorted list of names corresponding to the missing variant -// cases. -func (e inexhaustiveError) Names() []string { - list := make([]string, 0, len(e.Missing)) - for _, o := range e.Missing { - list = append(list, o.Name()) - } - sort.Strings(list) - return list -} - -// check does exhaustiveness checking for the given sum type definitions in the -// given package. Every instance of inexhaustive case analysis is returned. -func check(pkg *packages.Package, defs []sumTypeDef, config Config) []error { - var errs []error - for _, astfile := range pkg.Syntax { - ast.Inspect(astfile, func(n ast.Node) bool { - swtch, ok := n.(*ast.TypeSwitchStmt) - if !ok { - return true - } - if err := checkSwitch(pkg, defs, swtch, config); err != nil { - errs = append(errs, err) - } - return true - }) - } - return errs -} - -// checkSwitch performs an exhaustiveness check on the given type switch -// statement. If the type switch is used on a sum type and does not cover -// all variants of that sum type, then an error is returned indicating which -// variants were missed. -// -// Note that if the type switch contains a non-panicing default case, then -// exhaustiveness checks are disabled. -func checkSwitch( - pkg *packages.Package, - defs []sumTypeDef, - swtch *ast.TypeSwitchStmt, - config Config, -) error { - def, missing := missingVariantsInSwitch(pkg, defs, swtch, config) - if len(missing) > 0 { - return inexhaustiveError{ - Position: pkg.Fset.Position(swtch.Pos()), - Def: *def, - Missing: missing, - } - } - return nil -} - -// missingVariantsInSwitch returns a list of missing variants corresponding to -// the given switch statement. The corresponding sum type definition is also -// returned. (If no sum type definition could be found, then no exhaustiveness -// checks are performed, and therefore, no missing variants are returned.) -func missingVariantsInSwitch( - pkg *packages.Package, - defs []sumTypeDef, - swtch *ast.TypeSwitchStmt, - config Config, -) (*sumTypeDef, []types.Object) { - asserted := findTypeAssertExpr(swtch) - ty := pkg.TypesInfo.TypeOf(asserted) - if ty == nil { - panic(fmt.Sprintf("no type found for asserted expression: %v", asserted)) - } - - def := findDef(defs, ty) - if def == nil { - // We couldn't find a corresponding sum type, so there's - // nothing we can do to check it. - return nil, nil - } - variantExprs, hasDefault := switchVariants(swtch) - if config.DefaultSignifiesExhaustive && hasDefault && !defaultClauseAlwaysPanics(swtch) { - // A catch-all case defeats all exhaustiveness checks. - return def, nil - } - variantTypes := make([]types.Type, 0, len(variantExprs)) - for _, expr := range variantExprs { - variantTypes = append(variantTypes, pkg.TypesInfo.TypeOf(expr)) - } - return def, def.missing(variantTypes, config.IncludeSharedInterfaces) -} - -// switchVariants returns all case expressions found in a type switch. This -// includes expressions from cases that have a list of expressions. -func switchVariants(swtch *ast.TypeSwitchStmt) (exprs []ast.Expr, hasDefault bool) { - for _, stmt := range swtch.Body.List { - clause := stmt.(*ast.CaseClause) - if clause.List == nil { - hasDefault = true - } else { - exprs = append(exprs, clause.List...) - } - } - return -} - -// defaultClauseAlwaysPanics returns true if the given switch statement has a -// default clause that always panics. Note that this is done on a best-effort -// basis. While there will never be any false positives, there may be false -// negatives. -// -// If the given switch statement has no default clause, then this function -// panics. -func defaultClauseAlwaysPanics(swtch *ast.TypeSwitchStmt) bool { - var clause *ast.CaseClause - for _, stmt := range swtch.Body.List { - c := stmt.(*ast.CaseClause) - if c.List == nil { - clause = c - break - } - } - if clause == nil { - panic("switch statement has no default clause") - } - if len(clause.Body) != 1 { - return false - } - exprStmt, ok := clause.Body[0].(*ast.ExprStmt) - if !ok { - return false - } - callExpr, ok := exprStmt.X.(*ast.CallExpr) - if !ok { - return false - } - fun, ok := callExpr.Fun.(*ast.Ident) - if !ok { - return false - } - return fun.Name == "panic" -} - -// findTypeAssertExpr extracts the expression that is being type asserted from a -// type swtich statement. -func findTypeAssertExpr(swtch *ast.TypeSwitchStmt) ast.Expr { - var expr ast.Expr - if assign, ok := swtch.Assign.(*ast.AssignStmt); ok { - expr = assign.Rhs[0] - } else { - expr = swtch.Assign.(*ast.ExprStmt).X - } - return expr.(*ast.TypeAssertExpr).X -} - -// findDef returns the sum type definition corresponding to the given type. If -// no such sum type definition exists, then nil is returned. -func findDef(defs []sumTypeDef, needle types.Type) *sumTypeDef { - for i := range defs { - def := &defs[i] - if types.Identical(needle.Underlying(), def.Ty) { - return def - } - } - return nil -} diff --git a/vendor/github.com/alecthomas/go-check-sumtype/config.go b/vendor/github.com/alecthomas/go-check-sumtype/config.go deleted file mode 100644 index 5c722b75c4..0000000000 --- a/vendor/github.com/alecthomas/go-check-sumtype/config.go +++ /dev/null @@ -1,8 +0,0 @@ -package gochecksumtype - -type Config struct { - DefaultSignifiesExhaustive bool - // IncludeSharedInterfaces in the exhaustiviness check. If true, we do not need to list all concrete structs, as long - // as the switch statement is exhaustive with respect to interfaces the structs implement. - IncludeSharedInterfaces bool -} diff --git a/vendor/github.com/alecthomas/go-check-sumtype/decl.go b/vendor/github.com/alecthomas/go-check-sumtype/decl.go deleted file mode 100644 index 9dec9eefd5..0000000000 --- a/vendor/github.com/alecthomas/go-check-sumtype/decl.go +++ /dev/null @@ -1,69 +0,0 @@ -package gochecksumtype - -import ( - "go/ast" - "go/token" - "strings" - - "golang.org/x/tools/go/packages" -) - -// sumTypeDecl is a declaration of a sum type in a Go source file. -type sumTypeDecl struct { - // The package path that contains this decl. - Package *packages.Package - // The type named by this decl. - TypeName string - // Position where the declaration was found. - Pos token.Position -} - -// Location returns a short string describing where this declaration was found. -func (d sumTypeDecl) Location() string { - return d.Pos.String() -} - -// findSumTypeDecls searches every package given for sum type declarations of -// the form `sumtype:decl`. -func findSumTypeDecls(pkgs []*packages.Package) ([]sumTypeDecl, error) { - var decls []sumTypeDecl - var retErr error - for _, pkg := range pkgs { - for _, file := range pkg.Syntax { - ast.Inspect(file, func(node ast.Node) bool { - if node == nil { - return true - } - decl, ok := node.(*ast.GenDecl) - if !ok || decl.Doc == nil { - return true - } - var tspec *ast.TypeSpec - for _, spec := range decl.Specs { - ts, ok := spec.(*ast.TypeSpec) - if !ok { - continue - } - tspec = ts - } - for _, line := range decl.Doc.List { - if !strings.HasPrefix(line.Text, "//sumtype:decl") { - continue - } - pos := pkg.Fset.Position(decl.Pos()) - if tspec == nil { - retErr = notFoundError{Decl: sumTypeDecl{Package: pkg, Pos: pos}} - return false - } - pos = pkg.Fset.Position(tspec.Pos()) - decl := sumTypeDecl{Package: pkg, TypeName: tspec.Name.Name, Pos: pos} - debugf("found sum type decl: %s.%s", decl.Package.PkgPath, decl.TypeName) - decls = append(decls, decl) - break - } - return true - }) - } - } - return decls, retErr -} diff --git a/vendor/github.com/alecthomas/go-check-sumtype/def.go b/vendor/github.com/alecthomas/go-check-sumtype/def.go deleted file mode 100644 index 71bdf2f72d..0000000000 --- a/vendor/github.com/alecthomas/go-check-sumtype/def.go +++ /dev/null @@ -1,195 +0,0 @@ -package gochecksumtype - -import ( - "flag" - "fmt" - "go/token" - "go/types" - "log" -) - -var debug = flag.Bool("debug", false, "enable debug logging") - -func debugf(format string, args ...interface{}) { - if *debug { - log.Printf(format, args...) - } -} - -// Error as returned by Run() -type Error interface { - error - Pos() token.Position -} - -// unsealedError corresponds to a declared sum type whose interface is not -// sealed. A sealed interface requires at least one unexported method. -type unsealedError struct { - Decl sumTypeDecl -} - -func (e unsealedError) Pos() token.Position { return e.Decl.Pos } -func (e unsealedError) Error() string { - return fmt.Sprintf( - "%s: interface '%s' is not sealed "+ - "(sealing requires at least one unexported method)", - e.Decl.Location(), e.Decl.TypeName) -} - -// notFoundError corresponds to a declared sum type whose type definition -// could not be found in the same Go package. -type notFoundError struct { - Decl sumTypeDecl -} - -func (e notFoundError) Pos() token.Position { return e.Decl.Pos } -func (e notFoundError) Error() string { - return fmt.Sprintf("%s: type '%s' is not defined", e.Decl.Location(), e.Decl.TypeName) -} - -// notInterfaceError corresponds to a declared sum type that does not -// correspond to an interface. -type notInterfaceError struct { - Decl sumTypeDecl -} - -func (e notInterfaceError) Pos() token.Position { return e.Decl.Pos } -func (e notInterfaceError) Error() string { - return fmt.Sprintf("%s: type '%s' is not an interface", e.Decl.Location(), e.Decl.TypeName) -} - -// sumTypeDef corresponds to the definition of a Go interface that is -// interpreted as a sum type. Its variants are determined by finding all types -// that implement said interface in the same package. -type sumTypeDef struct { - Decl sumTypeDecl - Ty *types.Interface - Variants []types.Object -} - -// findSumTypeDefs attempts to find a Go type definition for each of the given -// sum type declarations. If no such sum type definition could be found for -// any of the given declarations, then an error is returned. -func findSumTypeDefs(decls []sumTypeDecl) ([]sumTypeDef, []error) { - defs := make([]sumTypeDef, 0, len(decls)) - var errs []error - for _, decl := range decls { - def, err := newSumTypeDef(decl.Package.Types, decl) - if err != nil { - errs = append(errs, err) - continue - } - if def == nil { - errs = append(errs, notFoundError{decl}) - continue - } - defs = append(defs, *def) - } - return defs, errs -} - -// newSumTypeDef attempts to extract a sum type definition from a single -// package. If no such type corresponds to the given decl, then this function -// returns a nil def and a nil error. -// -// If the decl corresponds to a type that isn't an interface containing at -// least one unexported method, then this returns an error. -func newSumTypeDef(pkg *types.Package, decl sumTypeDecl) (*sumTypeDef, error) { - obj := pkg.Scope().Lookup(decl.TypeName) - if obj == nil { - return nil, nil - } - iface, ok := obj.Type().Underlying().(*types.Interface) - if !ok { - return nil, notInterfaceError{decl} - } - hasUnexported := false - for i := range iface.NumMethods() { - if !iface.Method(i).Exported() { - hasUnexported = true - break - } - } - if !hasUnexported { - return nil, unsealedError{decl} - } - def := &sumTypeDef{ - Decl: decl, - Ty: iface, - } - debugf("searching for variants of %s.%s\n", pkg.Path(), decl.TypeName) - for _, name := range pkg.Scope().Names() { - obj, ok := pkg.Scope().Lookup(name).(*types.TypeName) - if !ok { - continue - } - ty := obj.Type() - if types.Identical(ty.Underlying(), iface) { - continue - } - // Skip generic types. - if named, ok := ty.(*types.Named); ok && named.TypeParams() != nil { - continue - } - if types.Implements(ty, iface) || types.Implements(types.NewPointer(ty), iface) { - debugf(" found variant: %s.%s\n", pkg.Path(), obj.Name()) - def.Variants = append(def.Variants, obj) - } - } - return def, nil -} - -func (def *sumTypeDef) String() string { - return def.Decl.TypeName -} - -// missing returns a list of variants in this sum type that are not in the -// given list of types. -func (def *sumTypeDef) missing(tys []types.Type, includeSharedInterfaces bool) []types.Object { - // TODO(ag): This is O(n^2). Fix that. /shrug - var missing []types.Object - for _, v := range def.Variants { - found := false - varty := indirect(v.Type()) - for _, ty := range tys { - ty = indirect(ty) - if types.Identical(varty, ty) { - found = true - break - } - if includeSharedInterfaces && implements(varty, ty) { - found = true - break - } - } - if !found && !isInterface(varty) { - // we do not include interfaces extending the sumtype, as the - // all implementations of those interfaces are already covered - // by the sumtype. - missing = append(missing, v) - } - } - return missing -} - -func isInterface(ty types.Type) bool { - underlying := indirect(ty).Underlying() - _, ok := underlying.(*types.Interface) - return ok -} - -// indirect dereferences through an arbitrary number of pointer types. -func indirect(ty types.Type) types.Type { - if ty, ok := ty.(*types.Pointer); ok { - return indirect(ty.Elem()) - } - return ty -} - -func implements(varty, interfaceType types.Type) bool { - underlying := interfaceType.Underlying() - if interf, ok := underlying.(*types.Interface); ok { - return types.Implements(varty, interf) || types.Implements(types.NewPointer(varty), interf) - } - return false -} diff --git a/vendor/github.com/alecthomas/go-check-sumtype/doc.go b/vendor/github.com/alecthomas/go-check-sumtype/doc.go deleted file mode 100644 index 2b6e86764e..0000000000 --- a/vendor/github.com/alecthomas/go-check-sumtype/doc.go +++ /dev/null @@ -1,53 +0,0 @@ -/* -sumtype takes a list of Go package paths or files and looks for sum type -declarations in each package/file provided. Exhaustiveness checks are then -performed for each use of a declared sum type in a type switch statement. -Namely, sumtype will report an error for any type switch statement that -either lacks a default clause or does not account for all possible variants. - -Declarations are provided in comments like so: - - //sumtype:decl - type MySumType interface { ... } - -MySumType must be *sealed*. That is, part of its interface definition contains -an unexported method. - -sumtype will produce an error if any of the above is not true. - -For valid declarations, sumtype will look for all occurrences in which a -value of type MySumType participates in a type switch statement. In those -occurrences, it will attempt to detect whether the type switch is exhaustive -or not. If it's not, sumtype will report an error. For example: - - $ cat mysumtype.go - package gochecksumtype - - //sumtype:decl - type MySumType interface { - sealed() - } - - type VariantA struct{} - - func (a *VariantA) sealed() {} - - type VariantB struct{} - - func (b *VariantB) sealed() {} - - func main() { - switch MySumType(nil).(type) { - case *VariantA: - } - } - $ sumtype mysumtype.go - mysumtype.go:18:2: exhaustiveness check failed for sum type 'MySumType': missing cases for VariantB - -Adding either a default clause or a clause to handle *VariantB will cause -exhaustive checks to pass. - -As a special case, if the type switch statement contains a default clause -that always panics, then exhaustiveness checks are still performed. -*/ -package gochecksumtype diff --git a/vendor/github.com/alecthomas/go-check-sumtype/renovate.json5 b/vendor/github.com/alecthomas/go-check-sumtype/renovate.json5 deleted file mode 100644 index 77c7b016cc..0000000000 --- a/vendor/github.com/alecthomas/go-check-sumtype/renovate.json5 +++ /dev/null @@ -1,18 +0,0 @@ -{ - $schema: "https://docs.renovatebot.com/renovate-schema.json", - extends: [ - "config:recommended", - ":semanticCommits", - ":semanticCommitTypeAll(chore)", - ":semanticCommitScope(deps)", - "group:allNonMajor", - "schedule:earlyMondays", // Run once a week. - ], - packageRules: [ - { - matchPackageNames: ["golangci-lint"], - matchManagers: ["hermit"], - enabled: false, - }, - ], -} diff --git a/vendor/github.com/alecthomas/go-check-sumtype/run.go b/vendor/github.com/alecthomas/go-check-sumtype/run.go deleted file mode 100644 index f32942d7a0..0000000000 --- a/vendor/github.com/alecthomas/go-check-sumtype/run.go +++ /dev/null @@ -1,26 +0,0 @@ -package gochecksumtype - -import "golang.org/x/tools/go/packages" - -// Run sumtype checking on the given packages. -func Run(pkgs []*packages.Package, config Config) []error { - var errs []error - - decls, err := findSumTypeDecls(pkgs) - if err != nil { - return []error{err} - } - - defs, defErrs := findSumTypeDefs(decls) - errs = append(errs, defErrs...) - if len(defs) == 0 { - return errs - } - - for _, pkg := range pkgs { - if pkgErrs := check(pkg, defs, config); pkgErrs != nil { - errs = append(errs, pkgErrs...) - } - } - return errs -} diff --git a/vendor/github.com/alexkohler/nakedret/v2/.gitignore b/vendor/github.com/alexkohler/nakedret/v2/.gitignore deleted file mode 100644 index b4822913a0..0000000000 --- a/vendor/github.com/alexkohler/nakedret/v2/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# editor specific -.vscode - -# binary -/nakedret - -# usage video for docs -.github/images diff --git a/vendor/github.com/alexkohler/nakedret/v2/LICENSE b/vendor/github.com/alexkohler/nakedret/v2/LICENSE deleted file mode 100644 index 9310fbcffb..0000000000 --- a/vendor/github.com/alexkohler/nakedret/v2/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2017 Alex Kohler - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/alexkohler/nakedret/v2/README.md b/vendor/github.com/alexkohler/nakedret/v2/README.md deleted file mode 100644 index 54f6ce6c24..0000000000 --- a/vendor/github.com/alexkohler/nakedret/v2/README.md +++ /dev/null @@ -1,125 +0,0 @@ -# nakedret - -nakedret is a Go static analysis tool to find naked returns in functions greater than a specified function length. - -## Installation -Install Nakedret via go install: - -```cmd -go install github.com/alexkohler/nakedret/v2/cmd/nakedret@latest -``` - -If you have not already added your `GOPATH/bin` directory to your `PATH` environment variable then you will need to do so. - -Windows (cmd): -```cmd -set PATH=%PATH%;C:\your\GOPATH\bin -``` - -Bash (you can verify a path has been set): -```Bash -# Check if nakedret is on PATH -which nakedret -export PATH=$PATH:/your/GOPATH/bin #to set path if it does not exist -``` - -## Usage - -Similar to other Go static anaylsis tools (such as `golint`, `go vet`), nakedret can be invoked with one or more filenames, directories, or packages named by its import path. Nakedret also supports the `...` wildcard. - - nakedret [flags] files/directories/packages - -Currently, the only flag supported is -l, which is an optional numeric flag to specify the maximum length a function can be (in terms of line length). If not specified, it defaults to 5. - -It can also be run using `go vet`: - -```shell -go vet -vettool=$(which nakedret) ./... -``` - -## Purpose - -As noted in Go's [Code Review comments](https://github.com/golang/go/wiki/CodeReviewComments#named-result-parameters): - -> Naked returns are okay if the function is a handful of lines. Once it's a medium sized function, be explicit with your return -> values. Corollary: it's not worth it to name result parameters just because it enables you to use naked returns. Clarity of docs is always more important than saving a line or two in your function. - -This tool aims to catch naked returns on non-trivial functions. - -## Example - -Let's take the `types` package in the Go source as an example: - -```Bash -$ nakedret -l 25 types/ -types/check.go:245 checkFiles naked returns on 26 line function -types/typexpr.go:443 collectParams naked returns on 53 line function -types/stmt.go:275 caseTypes naked returns on 27 line function -types/lookup.go:275 MissingMethod naked returns on 39 line function -``` - -Below is one of the not so intuitive uses of naked returns in `types/lookup.go` found by nakedret (nakedret will return the line number of the last naked return in the function): - - -```Go -func MissingMethod(V Type, T *Interface, static bool) (method *Func, wrongType bool) { - // fast path for common case - if T.Empty() { - return - } - - // TODO(gri) Consider using method sets here. Might be more efficient. - - if ityp, _ := V.Underlying().(*Interface); ityp != nil { - // TODO(gri) allMethods is sorted - can do this more efficiently - for _, m := range T.allMethods { - _, obj := lookupMethod(ityp.allMethods, m.pkg, m.name) - switch { - case obj == nil: - if static { - return m, false - } - case !Identical(obj.Type(), m.typ): - return m, true - } - } - return - } - - // A concrete type implements T if it implements all methods of T. - for _, m := range T.allMethods { - obj, _, _ := lookupFieldOrMethod(V, false, m.pkg, m.name) - - f, _ := obj.(*Func) - if f == nil { - return m, false - } - - if !Identical(f.typ, m.typ) { - return m, true - } - } - - return -} -``` - -## TODO - -- Unit tests (may require some refactoring to do correctly) -- supporting toggling of `build.Context.UseAllFiles` may be useful for some. -- Configuration on whether or not to run on test files -- Vim quickfix format? - - -## Contributing - -Pull requests welcome! - - -## Other static analysis tools - -If you've enjoyed nakedret, take a look at my other static anaylsis tools! - -- [unimport](https://github.com/alexkohler/unimport) - Finds unnecessary import aliases -- [prealloc](https://github.com/alexkohler/prealloc) - Finds slice declarations that could potentially be preallocated. diff --git a/vendor/github.com/alexkohler/nakedret/v2/import.go b/vendor/github.com/alexkohler/nakedret/v2/import.go deleted file mode 100644 index dea8423336..0000000000 --- a/vendor/github.com/alexkohler/nakedret/v2/import.go +++ /dev/null @@ -1,310 +0,0 @@ -package nakedret - -/* - -This file holds a direct copy of the import path matching code of -https://github.com/golang/go/blob/master/src/cmd/go/main.go. It can be -replaced when https://golang.org/issue/8768 is resolved. - -It has been updated to follow upstream changes in a few ways. - -*/ - -import ( - "fmt" - "go/build" - "log" - "os" - "path" - "path/filepath" - "regexp" - "runtime" - "strings" -) - -var buildContext = build.Default - -var ( - goroot = filepath.Clean(runtime.GOROOT()) - gorootSrc = filepath.Join(goroot, "src") -) - -// importPathsNoDotExpansion returns the import paths to use for the given -// command line, but it does no ... expansion. -func importPathsNoDotExpansion(args []string) []string { - if len(args) == 0 { - return []string{"."} - } - var out []string - for _, a := range args { - // Arguments are supposed to be import paths, but - // as a courtesy to Windows developers, rewrite \ to / - // in command-line arguments. Handles .\... and so on. - if filepath.Separator == '\\' { - a = strings.Replace(a, `\`, `/`, -1) - } - - // Put argument in canonical form, but preserve leading ./. - if strings.HasPrefix(a, "./") { - a = "./" + path.Clean(a) - if a == "./." { - a = "." - } - } else { - a = path.Clean(a) - } - if a == "all" || a == "std" { - out = append(out, allPackages(a)...) - continue - } - out = append(out, a) - } - return out -} - -// importPaths returns the import paths to use for the given command line. -func importPaths(args []string) []string { - args = importPathsNoDotExpansion(args) - var out []string - for _, a := range args { - if strings.Contains(a, "...") { - if build.IsLocalImport(a) { - out = append(out, allPackagesInFS(a)...) - } else { - out = append(out, allPackages(a)...) - } - continue - } - out = append(out, a) - } - return out -} - -// matchPattern(pattern)(name) reports whether -// name matches pattern. Pattern is a limited glob -// pattern in which '...' means 'any string' and there -// is no other special syntax. -func matchPattern(pattern string) func(name string) bool { - re := regexp.QuoteMeta(pattern) - re = strings.Replace(re, `\.\.\.`, `.*`, -1) - // Special case: foo/... matches foo too. - if strings.HasSuffix(re, `/.*`) { - re = re[:len(re)-len(`/.*`)] + `(/.*)?` - } - reg := regexp.MustCompile(`^` + re + `$`) - return func(name string) bool { - return reg.MatchString(name) - } -} - -// hasPathPrefix reports whether the path s begins with the -// elements in prefix. -func hasPathPrefix(s, prefix string) bool { - switch { - default: - return false - case len(s) == len(prefix): - return s == prefix - case len(s) > len(prefix): - if prefix != "" && prefix[len(prefix)-1] == '/' { - return strings.HasPrefix(s, prefix) - } - return s[len(prefix)] == '/' && s[:len(prefix)] == prefix - } -} - -// treeCanMatchPattern(pattern)(name) reports whether -// name or children of name can possibly match pattern. -// Pattern is the same limited glob accepted by matchPattern. -func treeCanMatchPattern(pattern string) func(name string) bool { - wildCard := false - if i := strings.Index(pattern, "..."); i >= 0 { - wildCard = true - pattern = pattern[:i] - } - return func(name string) bool { - return len(name) <= len(pattern) && hasPathPrefix(pattern, name) || - wildCard && strings.HasPrefix(name, pattern) - } -} - -// allPackages returns all the packages that can be found -// under the $GOPATH directories and $GOROOT matching pattern. -// The pattern is either "all" (all packages), "std" (standard packages) -// or a path including "...". -func allPackages(pattern string) []string { - pkgs := matchPackages(pattern) - if len(pkgs) == 0 { - fmt.Fprintf(os.Stderr, "warning: %q matched no packages\n", pattern) - } - return pkgs -} - -func matchPackages(pattern string) []string { - match := func(string) bool { return true } - treeCanMatch := func(string) bool { return true } - if pattern != "all" && pattern != "std" { - match = matchPattern(pattern) - treeCanMatch = treeCanMatchPattern(pattern) - } - - have := map[string]bool{ - "builtin": true, // ignore pseudo-package that exists only for documentation - } - if !buildContext.CgoEnabled { - have["runtime/cgo"] = true // ignore during walk - } - var pkgs []string - - // Commands - cmd := filepath.Join(goroot, "src/cmd") + string(filepath.Separator) - filepath.Walk(cmd, func(path string, fi os.FileInfo, err error) error { - if err != nil || !fi.IsDir() || path == cmd { - return nil - } - name := path[len(cmd):] - if !treeCanMatch(name) { - return filepath.SkipDir - } - // Commands are all in cmd/, not in subdirectories. - if strings.Contains(name, string(filepath.Separator)) { - return filepath.SkipDir - } - - // We use, e.g., cmd/gofmt as the pseudo import path for gofmt. - name = "cmd/" + name - if have[name] { - return nil - } - have[name] = true - if !match(name) { - return nil - } - _, err = buildContext.ImportDir(path, 0) - if err != nil { - if _, noGo := err.(*build.NoGoError); !noGo { - log.Print(err) - } - return nil - } - pkgs = append(pkgs, name) - return nil - }) - - for _, src := range buildContext.SrcDirs() { - if (pattern == "std" || pattern == "cmd") && src != gorootSrc { - continue - } - src = filepath.Clean(src) + string(filepath.Separator) - root := src - if pattern == "cmd" { - root += "cmd" + string(filepath.Separator) - } - filepath.Walk(root, func(path string, fi os.FileInfo, err error) error { - if err != nil || !fi.IsDir() || path == src { - return nil - } - - // Avoid .foo, _foo, testdata and vendor directory trees. - _, elem := filepath.Split(path) - if strings.HasPrefix(elem, ".") || strings.HasPrefix(elem, "_") || elem == "testdata" || elem == "vendor" { - return filepath.SkipDir - } - - name := filepath.ToSlash(path[len(src):]) - if pattern == "std" && (strings.Contains(name, ".") || name == "cmd") { - // The name "std" is only the standard library. - // If the name is cmd, it's the root of the command tree. - return filepath.SkipDir - } - if !treeCanMatch(name) { - return filepath.SkipDir - } - if have[name] { - return nil - } - have[name] = true - if !match(name) { - return nil - } - _, err = buildContext.ImportDir(path, 0) - if err != nil { - if _, noGo := err.(*build.NoGoError); noGo { - return nil - } - } - pkgs = append(pkgs, name) - return nil - }) - } - return pkgs -} - -// allPackagesInFS is like allPackages but is passed a pattern -// beginning ./ or ../, meaning it should scan the tree rooted -// at the given directory. There are ... in the pattern too. -func allPackagesInFS(pattern string) []string { - pkgs := matchPackagesInFS(pattern) - if len(pkgs) == 0 { - fmt.Fprintf(os.Stderr, "warning: %q matched no packages\n", pattern) - } - return pkgs -} - -func matchPackagesInFS(pattern string) []string { - // Find directory to begin the scan. - // Could be smarter but this one optimization - // is enough for now, since ... is usually at the - // end of a path. - i := strings.Index(pattern, "...") - dir, _ := path.Split(pattern[:i]) - - // pattern begins with ./ or ../. - // path.Clean will discard the ./ but not the ../. - // We need to preserve the ./ for pattern matching - // and in the returned import paths. - prefix := "" - if strings.HasPrefix(pattern, "./") { - prefix = "./" - } - match := matchPattern(pattern) - - var pkgs []string - filepath.Walk(dir, func(path string, fi os.FileInfo, err error) error { - if err != nil || !fi.IsDir() { - return nil - } - if path == dir { - // filepath.Walk starts at dir and recurses. For the recursive case, - // the path is the result of filepath.Join, which calls filepath.Clean. - // The initial case is not Cleaned, though, so we do this explicitly. - // - // This converts a path like "./io/" to "io". Without this step, running - // "cd $GOROOT/src/pkg; go list ./io/..." would incorrectly skip the io - // package, because prepending the prefix "./" to the unclean path would - // result in "././io", and match("././io") returns false. - path = filepath.Clean(path) - } - - // Avoid .foo, _foo, testdata and vendor directory trees, but do not avoid "." or "..". - _, elem := filepath.Split(path) - dot := strings.HasPrefix(elem, ".") && elem != "." && elem != ".." - if dot || strings.HasPrefix(elem, "_") || elem == "testdata" || elem == "vendor" { - return filepath.SkipDir - } - - name := prefix + filepath.ToSlash(path) - if !match(name) { - return nil - } - if _, err = build.ImportDir(path, 0); err != nil { - if _, noGo := err.(*build.NoGoError); !noGo { - log.Print(err) - } - return nil - } - pkgs = append(pkgs, name) - return nil - }) - return pkgs -} diff --git a/vendor/github.com/alexkohler/nakedret/v2/nakedret.go b/vendor/github.com/alexkohler/nakedret/v2/nakedret.go deleted file mode 100644 index 9f53d2a744..0000000000 --- a/vendor/github.com/alexkohler/nakedret/v2/nakedret.go +++ /dev/null @@ -1,311 +0,0 @@ -package nakedret - -import ( - "bytes" - "errors" - "fmt" - "go/ast" - "go/build" - "go/parser" - "go/printer" - "go/token" - "log" - "os" - "path/filepath" - "strings" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/inspector" -) - -const pwd = "./" - -func NakedReturnAnalyzer(nakedRet *NakedReturnRunner) *analysis.Analyzer { - a := &analysis.Analyzer{ - Name: "nakedret", - Doc: "Checks that functions with naked returns are not longer than a maximum size (can be zero).", - Run: nakedRet.run, - Requires: []*analysis.Analyzer{inspect.Analyzer}, - } - - return a -} - -type NakedReturnRunner struct { - MaxLength uint - SkipTestFiles bool -} - -func (n *NakedReturnRunner) run(pass *analysis.Pass) (any, error) { - inspector := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - - nodeFilter := []ast.Node{ // filter needed nodes: visit only them - (*ast.FuncDecl)(nil), - (*ast.FuncLit)(nil), - (*ast.ReturnStmt)(nil), - } - retVis := &returnsVisitor{ - pass: pass, - f: pass.Fset, - maxLength: n.MaxLength, - skipTestFiles: n.SkipTestFiles, - } - inspector.Nodes(nodeFilter, retVis.NodesVisit) - return nil, nil -} - -type returnsVisitor struct { - pass *analysis.Pass - f *token.FileSet - maxLength uint - skipTestFiles bool - - // functions contains funcInfo for each nested function definition encountered while visiting the AST. - functions []funcInfo -} - -type funcInfo struct { - // Details of the function we're currently dealing with - funcType *ast.FuncType - funcName string - funcLength int - reportNaked bool -} - -func checkNakedReturns(args []string, maxLength *uint, skipTestFiles bool, setExitStatus bool) error { - - fset := token.NewFileSet() - - files, err := parseInput(args, fset) - if err != nil { - return fmt.Errorf("could not parse input: %v", err) - } - - if maxLength == nil { - return errors.New("max length nil") - } - - analyzer := NakedReturnAnalyzer(&NakedReturnRunner{MaxLength: *maxLength, SkipTestFiles: skipTestFiles}) - pass := &analysis.Pass{ - Analyzer: analyzer, - Fset: fset, - Files: files, - Report: func(d analysis.Diagnostic) { - log.Printf("%s:%d: %s", fset.Position(d.Pos).Filename, fset.Position(d.Pos).Line, d.Message) - }, - ResultOf: map[*analysis.Analyzer]any{}, - } - result, err := inspect.Analyzer.Run(pass) - if err != nil { - return err - } - pass.ResultOf[inspect.Analyzer] = result - - _, err = analyzer.Run(pass) - if err != nil { - return err - } - - return nil -} - -func parseInput(args []string, fset *token.FileSet) ([]*ast.File, error) { - var directoryList []string - var fileMode bool - files := make([]*ast.File, 0) - - if len(args) == 0 { - directoryList = append(directoryList, pwd) - } else { - for _, arg := range args { - if strings.HasSuffix(arg, "/...") && isDir(arg[:len(arg)-len("/...")]) { - - for _, dirname := range allPackagesInFS(arg) { - directoryList = append(directoryList, dirname) - } - - } else if isDir(arg) { - directoryList = append(directoryList, arg) - - } else if exists(arg) { - if strings.HasSuffix(arg, ".go") { - fileMode = true - f, err := parser.ParseFile(fset, arg, nil, 0) - if err != nil { - return nil, err - } - files = append(files, f) - } else { - return nil, fmt.Errorf("invalid file %v specified", arg) - } - } else { - - // TODO clean this up a bit - imPaths := importPaths([]string{arg}) - for _, importPath := range imPaths { - pkg, err := build.Import(importPath, ".", 0) - if err != nil { - return nil, err - } - var stringFiles []string - stringFiles = append(stringFiles, pkg.GoFiles...) - // files = append(files, pkg.CgoFiles...) - stringFiles = append(stringFiles, pkg.TestGoFiles...) - if pkg.Dir != "." { - for i, f := range stringFiles { - stringFiles[i] = filepath.Join(pkg.Dir, f) - } - } - - fileMode = true - for _, stringFile := range stringFiles { - f, err := parser.ParseFile(fset, stringFile, nil, 0) - if err != nil { - return nil, err - } - files = append(files, f) - } - - } - } - } - } - - // if we're not in file mode, then we need to grab each and every package in each directory - // we can to grab all the files - if !fileMode { - for _, fpath := range directoryList { - pkgs, err := parser.ParseDir(fset, fpath, nil, 0) - if err != nil { - return nil, err - } - - for _, pkg := range pkgs { - for _, f := range pkg.Files { - files = append(files, f) - } - } - } - } - - return files, nil -} - -func isDir(filename string) bool { - fi, err := os.Stat(filename) - return err == nil && fi.IsDir() -} - -func exists(filename string) bool { - _, err := os.Stat(filename) - return err == nil -} - -func hasNamedReturns(funcType *ast.FuncType) bool { - if funcType == nil || funcType.Results == nil { - return false - } - for _, field := range funcType.Results.List { - for _, ident := range field.Names { - if ident != nil { - return true - } - } - } - return false -} - -func nestedFuncName(functions []funcInfo) string { - var names []string - for _, f := range functions { - names = append(names, f.funcName) - } - return strings.Join(names, ".") -} - -func nakedReturnFix(s *ast.ReturnStmt, funcType *ast.FuncType) *ast.ReturnStmt { - var nameExprs []ast.Expr - for _, result := range funcType.Results.List { - for _, ident := range result.Names { - if ident != nil { - nameExprs = append(nameExprs, ident) - } - } - } - var sFix = *s - sFix.Results = nameExprs - return &sFix -} - -func (v *returnsVisitor) NodesVisit(node ast.Node, push bool) bool { - var ( - funcType *ast.FuncType - funcName string - ) - switch s := node.(type) { - case *ast.FuncDecl: - // We've found a function - funcType = s.Type - funcName = s.Name.Name - case *ast.FuncLit: - // We've found a function literal - funcType = s.Type - file := v.f.File(s.Pos()) - funcName = fmt.Sprintf("", file.Position(s.Pos()).Line) - case *ast.ReturnStmt: - // We've found a possibly naked return statement - fun := v.functions[len(v.functions)-1] - funName := nestedFuncName(v.functions) - if fun.reportNaked && len(s.Results) == 0 && push { - sFix := nakedReturnFix(s, fun.funcType) - b := &bytes.Buffer{} - err := printer.Fprint(b, v.f, sFix) - if err != nil { - log.Printf("failed to format named return fix: %s", err) - } - v.pass.Report(analysis.Diagnostic{ - Pos: s.Pos(), - End: s.End(), - Message: fmt.Sprintf("naked return in func `%s` with %d lines of code", funName, fun.funcLength), - SuggestedFixes: []analysis.SuggestedFix{{ - Message: "explicit return statement", - TextEdits: []analysis.TextEdit{{ - Pos: s.Pos(), - End: s.End(), - NewText: b.Bytes()}}, - }}, - }) - } - } - - if !push { - if funcType == nil { - return false - } - // Pop function info - v.functions = v.functions[:len(v.functions)-1] - return false - } - - if push && funcType != nil { - // Push function info to track returns for this function - file := v.f.File(node.Pos()) - if v.skipTestFiles && strings.HasSuffix(file.Name(), "_test.go") { - return false - } - length := file.Position(node.End()).Line - file.Position(node.Pos()).Line - if length == 0 { - // consider functions that finish on the same line as they start as single line functions, not zero lines! - length = 1 - } - v.functions = append(v.functions, funcInfo{ - funcType: funcType, - funcName: funcName, - funcLength: length, - reportNaked: uint(length) > v.maxLength && hasNamedReturns(funcType), - }) - } - - return true -} diff --git a/vendor/github.com/alexkohler/prealloc/LICENSE b/vendor/github.com/alexkohler/prealloc/LICENSE deleted file mode 100644 index 9310fbcffb..0000000000 --- a/vendor/github.com/alexkohler/prealloc/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2017 Alex Kohler - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/alexkohler/prealloc/pkg/prealloc.go b/vendor/github.com/alexkohler/prealloc/pkg/prealloc.go deleted file mode 100644 index 72d8b95f7f..0000000000 --- a/vendor/github.com/alexkohler/prealloc/pkg/prealloc.go +++ /dev/null @@ -1,267 +0,0 @@ -package pkg - -import ( - "fmt" - "go/ast" - "go/token" -) - -type sliceDeclaration struct { - name string - // sType string - genD *ast.GenDecl -} - -type returnsVisitor struct { - // flags - simple bool - includeRangeLoops bool - includeForLoops bool - // visitor fields - sliceDeclarations []*sliceDeclaration - preallocHints []Hint - returnsInsideOfLoop bool - arrayTypes []string -} - -func Check(files []*ast.File, simple, includeRangeLoops, includeForLoops bool) []Hint { - hints := []Hint{} - for _, f := range files { - retVis := &returnsVisitor{ - simple: simple, - includeRangeLoops: includeRangeLoops, - includeForLoops: includeForLoops, - } - ast.Walk(retVis, f) - // if simple is true, then we actually have to check if we had returns - // inside of our loop. Otherwise, we can just report all messages. - if !retVis.simple || !retVis.returnsInsideOfLoop { - hints = append(hints, retVis.preallocHints...) - } - } - - return hints -} - -func contains(slice []string, item string) bool { - for _, s := range slice { - if s == item { - return true - } - } - - return false -} - -func (v *returnsVisitor) Visit(node ast.Node) ast.Visitor { - - v.sliceDeclarations = nil - v.returnsInsideOfLoop = false - - switch n := node.(type) { - case *ast.TypeSpec: - if _, ok := n.Type.(*ast.ArrayType); ok { - if n.Name != nil { - v.arrayTypes = append(v.arrayTypes, n.Name.Name) - } - } - case *ast.FuncDecl: - if n.Body != nil { - for _, stmt := range n.Body.List { - switch s := stmt.(type) { - // Find non pre-allocated slices - case *ast.DeclStmt: - genD, ok := s.Decl.(*ast.GenDecl) - if !ok { - continue - } - if genD.Tok == token.TYPE { - for _, spec := range genD.Specs { - tSpec, ok := spec.(*ast.TypeSpec) - if !ok { - continue - } - - if _, ok := tSpec.Type.(*ast.ArrayType); ok { - if tSpec.Name != nil { - v.arrayTypes = append(v.arrayTypes, tSpec.Name.Name) - } - } - } - } else if genD.Tok == token.VAR { - for _, spec := range genD.Specs { - vSpec, ok := spec.(*ast.ValueSpec) - if !ok { - continue - } - var isArrType bool - switch val := vSpec.Type.(type) { - case *ast.ArrayType: - isArrType = true - case *ast.Ident: - isArrType = contains(v.arrayTypes, val.Name) - } - if isArrType { - if vSpec.Names != nil { - /*atID, ok := arrayType.Elt.(*ast.Ident) - if !ok { - continue - }*/ - - // We should handle multiple slices declared on same line e.g. var mySlice1, mySlice2 []uint32 - for _, vName := range vSpec.Names { - v.sliceDeclarations = append(v.sliceDeclarations, &sliceDeclaration{name: vName.Name /*sType: atID.Name,*/, genD: genD}) - } - } - } - } - } - - case *ast.RangeStmt: - if v.includeRangeLoops { - if len(v.sliceDeclarations) == 0 { - continue - } - // Check the value being ranged over and ensure it's not a channel (we cannot offer any recommendations on channel ranges). - rangeIdent, ok := s.X.(*ast.Ident) - if ok && rangeIdent.Obj != nil { - valueSpec, ok := rangeIdent.Obj.Decl.(*ast.ValueSpec) - if ok { - if _, rangeTargetIsChannel := valueSpec.Type.(*ast.ChanType); rangeTargetIsChannel { - continue - } - } - } - if s.Body != nil { - v.handleLoops(s.Body) - } - } - - case *ast.ForStmt: - if v.includeForLoops { - if len(v.sliceDeclarations) == 0 { - continue - } - if s.Body != nil { - v.handleLoops(s.Body) - } - } - - default: - } - } - } - } - return v -} - -// handleLoops is a helper function to share the logic required for both *ast.RangeLoops and *ast.ForLoops -func (v *returnsVisitor) handleLoops(blockStmt *ast.BlockStmt) { - - for _, stmt := range blockStmt.List { - switch bodyStmt := stmt.(type) { - case *ast.AssignStmt: - asgnStmt := bodyStmt - for index, expr := range asgnStmt.Rhs { - if index >= len(asgnStmt.Lhs) { - continue - } - - lhsIdent, ok := asgnStmt.Lhs[index].(*ast.Ident) - if !ok { - continue - } - - callExpr, ok := expr.(*ast.CallExpr) - if !ok { - continue - } - - rhsFuncIdent, ok := callExpr.Fun.(*ast.Ident) - if !ok { - continue - } - - if rhsFuncIdent.Name != "append" { - continue - } - - // e.g., `x = append(x)` - // Pointless, but pre-allocation will not help. - if len(callExpr.Args) < 2 { - continue - } - - rhsIdent, ok := callExpr.Args[0].(*ast.Ident) - if !ok { - continue - } - - // e.g., `x = append(y, a)` - // This is weird (and maybe a logic error), - // but we cannot recommend pre-allocation. - if lhsIdent.Name != rhsIdent.Name { - continue - } - - // e.g., `x = append(x, y...)` - // we should ignore this. Pre-allocating in this case - // is confusing, and is not possible in general. - if callExpr.Ellipsis.IsValid() { - continue - } - - for _, sliceDecl := range v.sliceDeclarations { - if sliceDecl.name == lhsIdent.Name { - // This is a potential mark, we just need to make sure there are no returns/continues in the - // range loop. - // now we just need to grab whatever we're ranging over - /*sxIdent, ok := s.X.(*ast.Ident) - if !ok { - continue - }*/ - - v.preallocHints = append(v.preallocHints, Hint{ - Pos: sliceDecl.genD.Pos(), - DeclaredSliceName: sliceDecl.name, - }) - } - } - } - case *ast.IfStmt: - ifStmt := bodyStmt - if ifStmt.Body != nil { - for _, ifBodyStmt := range ifStmt.Body.List { - // TODO should probably handle embedded ifs here - switch /*ift :=*/ ifBodyStmt.(type) { - case *ast.BranchStmt, *ast.ReturnStmt: - v.returnsInsideOfLoop = true - default: - } - } - } - - default: - - } - } - -} - -// Hint stores the information about an occurrence of a slice that could be -// preallocated. -type Hint struct { - Pos token.Pos - DeclaredSliceName string -} - -func (h Hint) String() string { - return fmt.Sprintf("%v: Consider preallocating %v", h.Pos, h.DeclaredSliceName) -} - -func (h Hint) StringFromFS(f *token.FileSet) string { - file := f.File(h.Pos) - lineNumber := file.Position(h.Pos).Line - - return fmt.Sprintf("%v:%v Consider preallocating %v", file.Name(), lineNumber, h.DeclaredSliceName) -} diff --git a/vendor/github.com/alfatraining/structtag/LICENSE b/vendor/github.com/alfatraining/structtag/LICENSE deleted file mode 100644 index 4fd15f9f8f..0000000000 --- a/vendor/github.com/alfatraining/structtag/LICENSE +++ /dev/null @@ -1,60 +0,0 @@ -Copyright (c) 2017, Fatih Arslan -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of structtag nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -This software includes some portions from Go. Go is used under the terms of the -BSD like license. - -Copyright (c) 2012 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -The Go gopher was designed by Renee French. http://reneefrench.blogspot.com/ The design is licensed under the Creative Commons 3.0 Attributions license. Read this article for more details: https://blog.golang.org/gopher diff --git a/vendor/github.com/alfatraining/structtag/README.md b/vendor/github.com/alfatraining/structtag/README.md deleted file mode 100644 index 4d0094bec6..0000000000 --- a/vendor/github.com/alfatraining/structtag/README.md +++ /dev/null @@ -1,92 +0,0 @@ -# structtag [![](https://github.com/alfatraining/structtag/workflows/build/badge.svg)](https://github.com/alfatraining/structtag/actions) [![PkgGoDev](https://pkg.go.dev/badge/github.com/alfatraining/structtag)](https://pkg.go.dev/github.com/alfatraining/structtag) - -`structtag` is a library for parsing struct tags in Go during static analysis. -It is designed to provide a simple API for parsing struct field tags in Go code. -This fork focuses exclusively on **reading struct tags** and is not intended for modifying or rewriting them. -It also drops support for accessing the options of a struct tag individually. - -This project is a fork of [`fatih/structtag`](https://github.com/fatih/structtag), originally created by Fatih Arslan. -The primary changes in this fork are: - -- struct tag values are treated as blobs, options are not treated individually, -- the API surface is minimized, just so that the functionality used by [`4meepo/tagalign`](https://github.com/4meepo/tagalign) is provided. - ---- - -## Install - -To install the package: - -```bash -go get github.com/alfatraining/structtag -``` - ---- - -## Example Usage - -The following example demonstrates how to parse and output struct tags using `structtag`: - -```go -package main - -import ( - "fmt" - "reflect" - - "github.com/alfatraining/structtag" -) - -func main() { - type Example struct { - Field string `json:"foo,omitempty" xml:"bar"` - } - - // Get the struct tag from the field - tag := reflect.TypeOf(Example{}).Field(0).Tag - - // Parse the tag using structtag - tags, err := structtag.Parse(string(tag)) - if err != nil { - panic(err) - } - - // Iterate over all tags - for _, t := range tags.Tags() { - fmt.Printf("Key: %s, Value: %v\n", t.Key, t.Value) - } - // Output: - // Key: json, Value: foo,omitempty - // Key: xml, Value: bar -} -``` - ---- - -## API Overview - -### Parsing Struct Tags -Use `Parse` to parse a struct field's tag into a `Tags` object: -```go -tags, err := structtag.Parse(`json:"foo,omitempty" xml:"bar"`) -if err != nil { - panic(err) -} -``` - -### Accessing Tags -- **Retrieve all tags**: - ```go - allTags := tags.Tags() - ``` - -### Inspecting Tags -- **Key**: The key of the tag (e.g., `json` or `xml`). -- **Value**: The value of the tag (e.g., `"foo,omitempty"` for `json:"foo,omitempty"`). - ---- - -## Acknowledgments - -This project is based on [`fatih/structtag`](https://github.com/fatih/structtag), created by Fatih Arslan. -Inspiration for the style of this README was taken from [tylergannon/structtag](https://github.com/tylergannon/structtag), created by Tyler Gannon. diff --git a/vendor/github.com/alfatraining/structtag/tags.go b/vendor/github.com/alfatraining/structtag/tags.go deleted file mode 100644 index 227df3c2fb..0000000000 --- a/vendor/github.com/alfatraining/structtag/tags.go +++ /dev/null @@ -1,138 +0,0 @@ -package structtag - -import ( - "bytes" - "errors" - "fmt" - "strconv" -) - -var ( - errTagSyntax = errors.New("bad syntax for struct tag pair") - errTagKeySyntax = errors.New("bad syntax for struct tag key") - errTagValueSyntax = errors.New("bad syntax for struct tag value") -) - -// Tags represent a set of tags from a single struct field -type Tags struct { - tags []*Tag -} - -// Tag defines a single struct's string literal tag -type Tag struct { - // Key is the tag key, such as json, xml, etc. - // i.e: `json:"foo,omitempty". Here key is: "json" - Key string - - // Value is the value stored for this tag key. - // i.e.: `json:"foo,omitempty". Here the value is: "foo,omitempty". - Value string -} - -// Parse parses a single struct field tag and returns the set of tags. -func Parse(tag string) (*Tags, error) { - var tags []*Tag - - hasTag := tag != "" - - // NOTE(arslan) following code is from reflect and vet package with some - // modifications to collect all necessary information and extend it with - // usable methods - for tag != "" { - // Skip leading space. - i := 0 - for i < len(tag) && tag[i] == ' ' { - i++ - } - tag = tag[i:] - if tag == "" { - break - } - - // Scan to colon. A space, a quote or a control character is a syntax error. - // Strictly speaking, control chars include the range [0x7f, 0x9f], not just - // [0x00, 0x1f], but in practice, we ignore the multi-byte control characters - // as it is simpler to inspect the tag's bytes than the tag's runes. - i = 0 - for i < len(tag) && tag[i] > ' ' && tag[i] != ':' && tag[i] != '"' && tag[i] != 0x7f { - i++ - } - - if i == 0 { - return nil, errTagKeySyntax - } - if i+1 >= len(tag) || tag[i] != ':' { - return nil, errTagSyntax - } - if tag[i+1] != '"' { - return nil, errTagValueSyntax - } - - key := tag[:i] - tag = tag[i+1:] - - // Scan quoted string to find value. - i = 1 - for i < len(tag) && tag[i] != '"' { - if tag[i] == '\\' { - i++ - } - i++ - } - if i >= len(tag) { - return nil, errTagValueSyntax - } - - qvalue := tag[:i+1] - tag = tag[i+1:] - - value, err := strconv.Unquote(qvalue) - if err != nil { - return nil, errTagValueSyntax - } - - tags = append(tags, &Tag{ - Key: key, - Value: value, - }) - } - - if hasTag && len(tags) == 0 { - return nil, nil - } - - return &Tags{ - tags: tags, - }, nil -} - -// Tags returns a slice of tags. The order is the original tag order. -func (t *Tags) Tags() []*Tag { - return t.tags -} - -// String reassembles the tags into a valid literal tag field representation -func (t *Tags) String() string { - tags := t.Tags() - if len(tags) == 0 { - return "" - } - - var buf bytes.Buffer - for i, tag := range t.Tags() { - buf.WriteString(tag.String()) - if i != len(tags)-1 { - buf.WriteString(" ") - } - } - return buf.String() -} - -// String reassembles the tag into a valid tag field representation -func (t *Tag) String() string { - return fmt.Sprintf(`%s:%q`, t.Key, t.Value) -} - -func (t *Tags) Len() int { - return len(t.tags) -} diff --git a/vendor/github.com/alingse/asasalint/.gitignore b/vendor/github.com/alingse/asasalint/.gitignore deleted file mode 100644 index d0fc531c8c..0000000000 --- a/vendor/github.com/alingse/asasalint/.gitignore +++ /dev/null @@ -1,18 +0,0 @@ -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib - -# Test binary, built with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -# Dependency directories (remove the comment below to include it) -# vendor/ -.vscode - -asasalint diff --git a/vendor/github.com/alingse/asasalint/.goreleaser.yml b/vendor/github.com/alingse/asasalint/.goreleaser.yml deleted file mode 100644 index e45d5860d6..0000000000 --- a/vendor/github.com/alingse/asasalint/.goreleaser.yml +++ /dev/null @@ -1,72 +0,0 @@ ---- -project_name: asasalint - -release: - github: - owner: alingse - name: asasalint - -builds: - - binary: asasalint - goos: - - darwin - - windows - - linux - - freebsd - goarch: - - amd64 - - arm64 - - arm - - 386 - - ppc64le - - s390x - - mips64 - - mips64le - - riscv64 - goarm: - - 6 - - 7 - gomips: - - hardfloat - env: - - CGO_ENABLED=0 - ignore: - - goos: darwin - goarch: 386 - - goos: freebsd - goarch: arm64 - main: ./cmd/asasalint/ - flags: - - -trimpath - ldflags: -s -w -X main.version={{.Version}} -X main.commit={{.ShortCommit}} -X main.date={{.Date}} - -archives: - - format: tar.gz - wrap_in_directory: true - format_overrides: - - goos: windows - format: zip - name_template: '{{ .ProjectName }}-{{ .Version }}-{{ .Os }}-{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}' - files: - - LICENSE - - README.md - -snapshot: - name_template: SNAPSHOT-{{ .Commit }} - -checksum: - name_template: '{{ .ProjectName }}-{{ .Version }}-checksums.txt' - -changelog: - sort: asc - filters: - exclude: - - '(?i)^docs?:' - - '(?i)^docs\([^:]+\):' - - '(?i)^docs\[[^:]+\]:' - - '^tests?:' - - '(?i)^dev:' - - '^build\(deps\): bump .* in /docs \(#\d+\)' - - '^build\(deps\): bump .* in /\.github/peril \(#\d+\)' - - Merge pull request - - Merge branch diff --git a/vendor/github.com/alingse/asasalint/LICENSE b/vendor/github.com/alingse/asasalint/LICENSE deleted file mode 100644 index a7c39f2e3d..0000000000 --- a/vendor/github.com/alingse/asasalint/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2022 alingse - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/alingse/asasalint/Makefile b/vendor/github.com/alingse/asasalint/Makefile deleted file mode 100644 index 12f8ba9283..0000000000 --- a/vendor/github.com/alingse/asasalint/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -.PHONY: clean check test build - -default: clean check test build - -clean: - rm -rf dist/ cover.out - -test: clean - go test -v -cover ./... - -check: - golangci-lint run - -build: - go build -ldflags "-s -w" -trimpath ./cmd/asasalint/ diff --git a/vendor/github.com/alingse/asasalint/README.md b/vendor/github.com/alingse/asasalint/README.md deleted file mode 100644 index 3fa7e65b34..0000000000 --- a/vendor/github.com/alingse/asasalint/README.md +++ /dev/null @@ -1,76 +0,0 @@ -# asasalint -Golang linter, lint that pass any slice as any in variadic function - - -## Install - -```sh -go install github.com/alingse/asasalint/cmd/asasalint@latest -``` - -## Usage - -```sh -asasalint ./... -``` - -ignore some func that was by desgin - -```sh -asasalint -e append,Append ./... -``` - -## Why - -two kind of unexpected usage, and `go build` success - -```Go -package main - -import "fmt" - -func A(args ...any) int { - return len(args) -} - -func B(args ...any) int { - return A(args) -} - -func main() { - - // 1 - fmt.Println(B(1, 2, 3, 4)) -} -``` - - - -```Go -package main - -import "fmt" - -func errMsg(msg string, args ...any) string { - return fmt.Sprintf(msg, args...) -} - -func Err(msg string, args ...any) string { - return errMsg(msg, args) -} - -func main() { - - // p1 [hello world] p2 %!s(MISSING) - fmt.Println(Err("p1 %s p2 %s", "hello", "world")) -} -``` - - - -## TODO - -1. add to golangci-lint -2. given a SuggestEdition -3. add `append` to default exclude ? -4. ingore pattern `fn(a, b, []any{1,2,3})` , because `[]any{1,2,3}` is most likely by design diff --git a/vendor/github.com/alingse/asasalint/asasalint.go b/vendor/github.com/alingse/asasalint/asasalint.go deleted file mode 100644 index f34516a465..0000000000 --- a/vendor/github.com/alingse/asasalint/asasalint.go +++ /dev/null @@ -1,166 +0,0 @@ -package asasalint - -import ( - "bytes" - "fmt" - "go/ast" - "go/printer" - "go/token" - "go/types" - "log" - "regexp" - "strings" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/inspector" -) - -const BuiltinExclusions = `^(fmt|log|logger|t|)\.(Print|Fprint|Sprint|Fatal|Panic|Error|Warn|Warning|Info|Debug|Log)(|f|ln)$` - -type LinterSetting struct { - Exclude []string - NoBuiltinExclusions bool - IgnoreTest bool -} - -func NewAnalyzer(setting LinterSetting) (*analysis.Analyzer, error) { - a, err := newAnalyzer(setting) - if err != nil { - return nil, err - } - - return &analysis.Analyzer{ - Name: "asasalint", - Doc: "check for pass []any as any in variadic func(...any)", - Run: a.run, - Requires: []*analysis.Analyzer{inspect.Analyzer}, - }, nil -} - -type analyzer struct { - excludes []*regexp.Regexp - setting LinterSetting -} - -func newAnalyzer(setting LinterSetting) (*analyzer, error) { - a := &analyzer{ - setting: setting, - } - - if !a.setting.NoBuiltinExclusions { - a.excludes = append(a.excludes, regexp.MustCompile(BuiltinExclusions)) - } - - for _, exclude := range a.setting.Exclude { - if exclude != "" { - exp, err := regexp.Compile(exclude) - if err != nil { - return nil, err - } - - a.excludes = append(a.excludes, exp) - } - } - - return a, nil -} - -func (a *analyzer) run(pass *analysis.Pass) (interface{}, error) { - inspectorInfo := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - nodeFilter := []ast.Node{(*ast.CallExpr)(nil)} - - inspectorInfo.Preorder(nodeFilter, a.AsCheckVisitor(pass)) - return nil, nil -} - -func (a *analyzer) AsCheckVisitor(pass *analysis.Pass) func(ast.Node) { - return func(n ast.Node) { - if a.setting.IgnoreTest { - pos := pass.Fset.Position(n.Pos()) - if strings.HasSuffix(pos.Filename, "_test.go") { - return - } - } - - caller, ok := n.(*ast.CallExpr) - if !ok { - return - } - if caller.Ellipsis != token.NoPos { - return - } - if len(caller.Args) == 0 { - return - } - - fnName, err := getFuncName(pass.Fset, caller) - if err != nil { - log.Println(err) - return - } - - for _, exclude := range a.excludes { - if exclude.MatchString(fnName) { - return - } - } - - fnType := pass.TypesInfo.TypeOf(caller.Fun) - if !isSliceAnyVariadicFuncType(fnType) { - return - } - - fnSign := fnType.(*types.Signature) - if len(caller.Args) != fnSign.Params().Len() { - return - } - - lastArg := caller.Args[len(caller.Args)-1] - argType := pass.TypesInfo.TypeOf(lastArg) - if !isSliceAnyType(argType) { - return - } - node := lastArg - - d := analysis.Diagnostic{ - Pos: node.Pos(), - End: node.End(), - Message: fmt.Sprintf("pass []any as any to func %s %s", fnName, fnType.String()), - Category: "asasalint", - } - pass.Report(d) - } -} - -func getFuncName(fset *token.FileSet, caller *ast.CallExpr) (string, error) { - buf := new(bytes.Buffer) - if err := printer.Fprint(buf, fset, caller.Fun); err != nil { - return "", fmt.Errorf("unable to print node at %s: %w", fset.Position(caller.Fun.Pos()), err) - } - - return buf.String(), nil -} - -func isSliceAnyVariadicFuncType(typ types.Type) (r bool) { - fnSign, ok := typ.(*types.Signature) - if !ok || !fnSign.Variadic() { - return false - } - - params := fnSign.Params() - lastParam := params.At(params.Len() - 1) - return isSliceAnyType(lastParam.Type()) -} - -func isSliceAnyType(typ types.Type) (r bool) { - sliceType, ok := typ.(*types.Slice) - if !ok { - return - } - elemType, ok := sliceType.Elem().(*types.Interface) - if !ok { - return - } - return elemType.NumMethods() == 0 -} diff --git a/vendor/github.com/alingse/nilnesserr/.gitignore b/vendor/github.com/alingse/nilnesserr/.gitignore deleted file mode 100644 index 6f72f89261..0000000000 --- a/vendor/github.com/alingse/nilnesserr/.gitignore +++ /dev/null @@ -1,25 +0,0 @@ -# If you prefer the allow list template instead of the deny list, see community template: -# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore -# -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib - -# Test binary, built with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -# Dependency directories (remove the comment below to include it) -# vendor/ - -# Go workspace file -go.work -go.work.sum - -# env file -.env diff --git a/vendor/github.com/alingse/nilnesserr/.golangci.yaml b/vendor/github.com/alingse/nilnesserr/.golangci.yaml deleted file mode 100644 index 6882e0f354..0000000000 --- a/vendor/github.com/alingse/nilnesserr/.golangci.yaml +++ /dev/null @@ -1,75 +0,0 @@ -linters: - enable-all: true - disable: - - wsl - - varnamelen - - nilnil - - ireturn - - gochecknoglobals - - nolintlint - -linters-settings: - depguard: - rules: - main: - list-mode: lax - files: - - $all - allow: - - $gostd - - github.com/alingse/nilnesserr - cyclop: - max-complexity: 12 - lll: - line-length: 200 - -issues: - exclude-rules: - - path: internal/typeparams - linters: - - nonamedreturns - - nlreturn - - intrange - - mnd - - forcetypeassert - - exhaustruct - - exhaustive - - err113 - - gofumpt - - prealloc - - funclen - - gocritic - - funlen - - cyclop - - gocognit - - - path: nilness.go - linters: - - nonamedreturns - - nlreturn - - nilnil - - mnd - - forcetypeassert - - gochecknoglobals - - nestif - - funlen - - godox - - gocognit - - gofumpt - - exhaustive - - cyclop - - unparam - - gocyclo - - - text: "analysis." - linters: - - exhaustruct - - - text: "newAnalyzer" - linters: - - unparam - - - text: "indent-error-flow" - path: nilness.go - linters: - - revive diff --git a/vendor/github.com/alingse/nilnesserr/LICENSE b/vendor/github.com/alingse/nilnesserr/LICENSE deleted file mode 100644 index 6caf1ea1c6..0000000000 --- a/vendor/github.com/alingse/nilnesserr/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2024 alingse - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/alingse/nilnesserr/README.md b/vendor/github.com/alingse/nilnesserr/README.md deleted file mode 100644 index 2299488edb..0000000000 --- a/vendor/github.com/alingse/nilnesserr/README.md +++ /dev/null @@ -1,89 +0,0 @@ -# nilnesserr - -nilnesserr = nilness + nilerr - -`nilnesserr` is a linter for report return nil error in Go. It combines the features of [nilness](https://cs.opensource.google/go/x/tools/+/refs/tags/v0.28.0:go/analysis/passes/nilness/nilness.go) and [nilerr](https://github.com/gostaticanalysis/nilerr), providing a concise way to detect return an unrelated/nil-values error. - -## Case - -case 1 -```go -err := do() -if err != nil { - return err -} -err2 := do2() -if err2 != nil { - return err // want `return a nil value error after check error` -} -``` - -case 2 - -```go -err := do() -if err != nil { - return err -} -_, err2 := do2() -if err2 != nil { - return errors.Wrap(err) // want `call function with a nil value error after check error` -} -``` - -case 3 - -```go -err := do() -if err != nil { - return err -} -_, err2 := do2() -if err2 != nil { - return fmt.Errorf("call do2 failed: %w",err) // want `call variadic function with a nil value error after check error` -} -``` - - -## Some Real Bugs - -- https://github.com/alingse/sundrylint/issues/4 -- https://github.com/alingse/nilnesserr/issues/1 -- https://github.com/alingse/nilnesserr/issues/11 -- https://github.com/alingse/nilnesserr/issues/15 - -We use https://github.com/alingse/go-linter-runner to run linter on GitHub Actions for public Go repos - -## Install - -```bash -go install github.com/alingse/nilnesserr/cmd/nilnesserr@latest -``` - - -## TODO - -case 3 - -```go -err := do() -if err != nil { - return err -} -_, ok := do2() -if !ok { - return err -} - -``` - -maybe this is also a bug, should return a non-nil value error after the if - -## License - -This project is licensed under the MIT License. See the LICENSE file for details. - -This project incorporates source code from two different libraries: - -1. [nilness](https://cs.opensource.google/go/x/tools/+/refs/tags/v0.28.0:go/analysis/passes/nilness/nilness.go) licensed under the BSD license. -2. [nilerr](https://github.com/gostaticanalysis/nilerr) licensed under the MIT license. diff --git a/vendor/github.com/alingse/nilnesserr/internal/typeparams/coretype.go b/vendor/github.com/alingse/nilnesserr/internal/typeparams/coretype.go deleted file mode 100644 index 7a744d123b..0000000000 --- a/vendor/github.com/alingse/nilnesserr/internal/typeparams/coretype.go +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package typeparams - -import ( - "go/types" -) - -// CoreType returns the core type of T or nil if T does not have a core type. -// -// See https://go.dev/ref/spec#Core_types for the definition of a core type. -func CoreType(T types.Type) types.Type { - U := T.Underlying() - if _, ok := U.(*types.Interface); !ok { - return U // for non-interface types, - } - - terms, err := NormalTerms(U) - if len(terms) == 0 || err != nil { - // len(terms) -> empty type set of interface. - // err != nil => U is invalid, exceeds complexity bounds, or has an empty type set. - return nil // no core type. - } - - U = terms[0].Type().Underlying() - var identical int // i in [0,identical) => Identical(U, terms[i].Type().Underlying()) - for identical = 1; identical < len(terms); identical++ { - if !types.Identical(U, terms[identical].Type().Underlying()) { - break - } - } - - if identical == len(terms) { - // https://go.dev/ref/spec#Core_types - // "There is a single type U which is the underlying type of all types in the type set of T" - return U - } - ch, ok := U.(*types.Chan) - if !ok { - return nil // no core type as identical < len(terms) and U is not a channel. - } - // https://go.dev/ref/spec#Core_types - // "the type chan E if T contains only bidirectional channels, or the type chan<- E or - // <-chan E depending on the direction of the directional channels present." - for chans := identical; chans < len(terms); chans++ { - curr, ok := terms[chans].Type().Underlying().(*types.Chan) - if !ok { - return nil - } - if !types.Identical(ch.Elem(), curr.Elem()) { - return nil // channel elements are not identical. - } - if ch.Dir() == types.SendRecv { - // ch is bidirectional. We can safely always use curr's direction. - ch = curr - } else if curr.Dir() != types.SendRecv && ch.Dir() != curr.Dir() { - // ch and curr are not bidirectional and not the same direction. - return nil - } - } - return ch -} - -// NormalTerms returns a slice of terms representing the normalized structural -// type restrictions of a type, if any. -// -// For all types other than *types.TypeParam, *types.Interface, and -// *types.Union, this is just a single term with Tilde() == false and -// Type() == typ. For *types.TypeParam, *types.Interface, and *types.Union, see -// below. -// -// Structural type restrictions of a type parameter are created via -// non-interface types embedded in its constraint interface (directly, or via a -// chain of interface embeddings). For example, in the declaration type -// T[P interface{~int; m()}] int the structural restriction of the type -// parameter P is ~int. -// -// With interface embedding and unions, the specification of structural type -// restrictions may be arbitrarily complex. For example, consider the -// following: -// -// type A interface{ ~string|~[]byte } -// -// type B interface{ int|string } -// -// type C interface { ~string|~int } -// -// type T[P interface{ A|B; C }] int -// -// In this example, the structural type restriction of P is ~string|int: A|B -// expands to ~string|~[]byte|int|string, which reduces to ~string|~[]byte|int, -// which when intersected with C (~string|~int) yields ~string|int. -// -// NormalTerms computes these expansions and reductions, producing a -// "normalized" form of the embeddings. A structural restriction is normalized -// if it is a single union containing no interface terms, and is minimal in the -// sense that removing any term changes the set of types satisfying the -// constraint. It is left as a proof for the reader that, modulo sorting, there -// is exactly one such normalized form. -// -// Because the minimal representation always takes this form, NormalTerms -// returns a slice of tilde terms corresponding to the terms of the union in -// the normalized structural restriction. An error is returned if the type is -// invalid, exceeds complexity bounds, or has an empty type set. In the latter -// case, NormalTerms returns ErrEmptyTypeSet. -// -// NormalTerms makes no guarantees about the order of terms, except that it -// is deterministic. -func NormalTerms(typ types.Type) ([]*types.Term, error) { - switch typ := typ.Underlying().(type) { - case *types.TypeParam: - return StructuralTerms(typ) - case *types.Union: - return UnionTermSet(typ) - case *types.Interface: - return InterfaceTermSet(typ) - default: - return []*types.Term{types.NewTerm(false, typ)}, nil - } -} diff --git a/vendor/github.com/alingse/nilnesserr/internal/typeparams/normalize.go b/vendor/github.com/alingse/nilnesserr/internal/typeparams/normalize.go deleted file mode 100644 index 0302872f47..0000000000 --- a/vendor/github.com/alingse/nilnesserr/internal/typeparams/normalize.go +++ /dev/null @@ -1,200 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package typeparams - -import ( - "errors" - "fmt" - "go/types" -) - -var ErrEmptyTypeSet = errors.New("empty type set") - -// StructuralTerms returns a slice of terms representing the normalized -// structural type restrictions of a type parameter, if any. -// -// Structural type restrictions of a type parameter are created via -// non-interface types embedded in its constraint interface (directly, or via a -// chain of interface embeddings). For example, in the declaration -// -// type T[P interface{~int; m()}] int -// -// the structural restriction of the type parameter P is ~int. -// -// With interface embedding and unions, the specification of structural type -// restrictions may be arbitrarily complex. For example, consider the -// following: -// -// type A interface{ ~string|~[]byte } -// -// type B interface{ int|string } -// -// type C interface { ~string|~int } -// -// type T[P interface{ A|B; C }] int -// -// In this example, the structural type restriction of P is ~string|int: A|B -// expands to ~string|~[]byte|int|string, which reduces to ~string|~[]byte|int, -// which when intersected with C (~string|~int) yields ~string|int. -// -// StructuralTerms computes these expansions and reductions, producing a -// "normalized" form of the embeddings. A structural restriction is normalized -// if it is a single union containing no interface terms, and is minimal in the -// sense that removing any term changes the set of types satisfying the -// constraint. It is left as a proof for the reader that, modulo sorting, there -// is exactly one such normalized form. -// -// Because the minimal representation always takes this form, StructuralTerms -// returns a slice of tilde terms corresponding to the terms of the union in -// the normalized structural restriction. An error is returned if the -// constraint interface is invalid, exceeds complexity bounds, or has an empty -// type set. In the latter case, StructuralTerms returns ErrEmptyTypeSet. -// -// StructuralTerms makes no guarantees about the order of terms, except that it -// is deterministic. -func StructuralTerms(tparam *types.TypeParam) ([]*types.Term, error) { - constraint := tparam.Constraint() - if constraint == nil { - return nil, fmt.Errorf("%s has nil constraint", tparam) - } - iface, _ := constraint.Underlying().(*types.Interface) - if iface == nil { - return nil, fmt.Errorf("constraint is %T, not *types.Interface", constraint.Underlying()) - } - return InterfaceTermSet(iface) -} - -// InterfaceTermSet computes the normalized terms for a constraint interface, -// returning an error if the term set cannot be computed or is empty. In the -// latter case, the error will be ErrEmptyTypeSet. -// -// See the documentation of StructuralTerms for more information on -// normalization. -func InterfaceTermSet(iface *types.Interface) ([]*types.Term, error) { - return computeTermSet(iface) -} - -// UnionTermSet computes the normalized terms for a union, returning an error -// if the term set cannot be computed or is empty. In the latter case, the -// error will be ErrEmptyTypeSet. -// -// See the documentation of StructuralTerms for more information on -// normalization. -func UnionTermSet(union *types.Union) ([]*types.Term, error) { - return computeTermSet(union) -} - -func computeTermSet(typ types.Type) ([]*types.Term, error) { - tset, err := computeTermSetInternal(typ, make(map[types.Type]*termSet), 0) - if err != nil { - return nil, err - } - if tset.terms.isEmpty() { - return nil, ErrEmptyTypeSet - } - if tset.terms.isAll() { - return nil, nil - } - var terms []*types.Term - for _, term := range tset.terms { - terms = append(terms, types.NewTerm(term.tilde, term.typ)) - } - return terms, nil -} - -// A termSet holds the normalized set of terms for a given type. -// -// The name termSet is intentionally distinct from 'type set': a type set is -// all types that implement a type (and includes method restrictions), whereas -// a term set just represents the structural restrictions on a type. -type termSet struct { - complete bool - terms termlist -} - -var ErrNilType = errors.New("nil type") -var ErrUnreachable = errors.New("unreachable") - -func computeTermSetInternal(t types.Type, seen map[types.Type]*termSet, depth int) (res *termSet, err error) { - if t == nil { - return nil, ErrNilType - } - - const maxTermCount = 100 - if tset, ok := seen[t]; ok { - if !tset.complete { - return nil, fmt.Errorf("cycle detected in the declaration of %s", t) - } - return tset, nil - } - - // Mark the current type as seen to avoid infinite recursion. - tset := new(termSet) - defer func() { - tset.complete = true - }() - seen[t] = tset - - switch u := t.Underlying().(type) { - case *types.Interface: - // The term set of an interface is the intersection of the term sets of its - // embedded types. - tset.terms = allTermlist - for i := 0; i < u.NumEmbeddeds(); i++ { - embedded := u.EmbeddedType(i) - if _, ok := embedded.Underlying().(*types.TypeParam); ok { - return nil, fmt.Errorf("invalid embedded type %T", embedded) - } - tset2, err := computeTermSetInternal(embedded, seen, depth+1) - if err != nil { - return nil, err - } - tset.terms = tset.terms.intersect(tset2.terms) - } - case *types.Union: - // The term set of a union is the union of term sets of its terms. - tset.terms = nil - for i := 0; i < u.Len(); i++ { - t := u.Term(i) - var terms termlist - switch t.Type().Underlying().(type) { - case *types.Interface: - tset2, err := computeTermSetInternal(t.Type(), seen, depth+1) - if err != nil { - return nil, err - } - terms = tset2.terms - case *types.TypeParam, *types.Union: - // A stand-alone type parameter or union is not permitted as union - // term. - return nil, fmt.Errorf("invalid union term %T", t) - default: - if t.Type() == types.Typ[types.Invalid] { - continue - } - terms = termlist{{t.Tilde(), t.Type()}} - } - tset.terms = tset.terms.union(terms) - if len(tset.terms) > maxTermCount { - return nil, fmt.Errorf("exceeded max term count %d", maxTermCount) - } - } - case *types.TypeParam: - return nil, ErrUnreachable - default: - // For all other types, the term set is just a single non-tilde term - // holding the type itself. - if u != types.Typ[types.Invalid] { - tset.terms = termlist{{false, t}} - } - } - return tset, nil -} - -// under is a facade for the go/types internal function of the same name. It is -// used by typeterm.go. -func under(t types.Type) types.Type { - return t.Underlying() -} diff --git a/vendor/github.com/alingse/nilnesserr/internal/typeparams/termlist.go b/vendor/github.com/alingse/nilnesserr/internal/typeparams/termlist.go deleted file mode 100644 index cbd12f8013..0000000000 --- a/vendor/github.com/alingse/nilnesserr/internal/typeparams/termlist.go +++ /dev/null @@ -1,163 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Code generated by copytermlist.go DO NOT EDIT. - -package typeparams - -import ( - "bytes" - "go/types" -) - -// A termlist represents the type set represented by the union -// t1 ∪ y2 ∪ ... tn of the type sets of the terms t1 to tn. -// A termlist is in normal form if all terms are disjoint. -// termlist operations don't require the operands to be in -// normal form. -type termlist []*term - -// allTermlist represents the set of all types. -// It is in normal form. -var allTermlist = termlist{new(term)} - -// String prints the termlist exactly (without normalization). -func (xl termlist) String() string { - if len(xl) == 0 { - return "∅" - } - var buf bytes.Buffer - for i, x := range xl { - if i > 0 { - buf.WriteString(" | ") - } - buf.WriteString(x.String()) - } - return buf.String() -} - -// isEmpty reports whether the termlist xl represents the empty set of types. -func (xl termlist) isEmpty() bool { - // If there's a non-nil term, the entire list is not empty. - // If the termlist is in normal form, this requires at most - // one iteration. - for _, x := range xl { - if x != nil { - return false - } - } - return true -} - -// isAll reports whether the termlist xl represents the set of all types. -func (xl termlist) isAll() bool { - // If there's a 𝓤 term, the entire list is 𝓤. - // If the termlist is in normal form, this requires at most - // one iteration. - for _, x := range xl { - if x != nil && x.typ == nil { - return true - } - } - return false -} - -// norm returns the normal form of xl. -func (xl termlist) norm() termlist { - // Quadratic algorithm, but good enough for now. - // TODO(gri) fix asymptotic performance - used := make([]bool, len(xl)) - var rl termlist - for i, xi := range xl { - if xi == nil || used[i] { - continue - } - for j := i + 1; j < len(xl); j++ { - xj := xl[j] - if xj == nil || used[j] { - continue - } - if u1, u2 := xi.union(xj); u2 == nil { - // If we encounter a 𝓤 term, the entire list is 𝓤. - // Exit early. - // (Note that this is not just an optimization; - // if we continue, we may end up with a 𝓤 term - // and other terms and the result would not be - // in normal form.) - if u1.typ == nil { - return allTermlist - } - xi = u1 - used[j] = true // xj is now unioned into xi - ignore it in future iterations - } - } - rl = append(rl, xi) - } - return rl -} - -// union returns the union xl ∪ yl. -func (xl termlist) union(yl termlist) termlist { - return append(xl, yl...).norm() -} - -// intersect returns the intersection xl ∩ yl. -func (xl termlist) intersect(yl termlist) termlist { - if xl.isEmpty() || yl.isEmpty() { - return nil - } - - // Quadratic algorithm, but good enough for now. - // TODO(gri) fix asymptotic performance - var rl termlist - for _, x := range xl { - for _, y := range yl { - if r := x.intersect(y); r != nil { - rl = append(rl, r) - } - } - } - return rl.norm() -} - -// equal reports whether xl and yl represent the same type set. -func (xl termlist) equal(yl termlist) bool { - // TODO(gri) this should be more efficient - return xl.subsetOf(yl) && yl.subsetOf(xl) -} - -// includes reports whether t ∈ xl. -func (xl termlist) includes(t types.Type) bool { - for _, x := range xl { - if x.includes(t) { - return true - } - } - return false -} - -// supersetOf reports whether y ⊆ xl. -func (xl termlist) supersetOf(y *term) bool { - for _, x := range xl { - if y.subsetOf(x) { - return true - } - } - return false -} - -// subsetOf reports whether xl ⊆ yl. -func (xl termlist) subsetOf(yl termlist) bool { - if yl.isEmpty() { - return xl.isEmpty() - } - - // each term x of xl must be a subset of yl - for _, x := range xl { - if !yl.supersetOf(x) { - return false // x is not a subset yl - } - } - return true -} diff --git a/vendor/github.com/alingse/nilnesserr/internal/typeparams/typeterm.go b/vendor/github.com/alingse/nilnesserr/internal/typeparams/typeterm.go deleted file mode 100644 index 35c66003d6..0000000000 --- a/vendor/github.com/alingse/nilnesserr/internal/typeparams/typeterm.go +++ /dev/null @@ -1,166 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Code generated by copytermlist.go DO NOT EDIT. - -package typeparams - -import "go/types" - -// A term describes elementary type sets: -// -// ∅: (*term)(nil) == ∅ // set of no types (empty set) -// 𝓤: &term{} == 𝓤 // set of all types (𝓤niverse) -// T: &term{false, T} == {T} // set of type T -// ~t: &term{true, t} == {t' | under(t') == t} // set of types with underlying type t -type term struct { - tilde bool // valid if typ != nil - typ types.Type -} - -func (x *term) String() string { - switch { - case x == nil: - return "∅" - case x.typ == nil: - return "𝓤" - case x.tilde: - return "~" + x.typ.String() - default: - return x.typ.String() - } -} - -// equal reports whether x and y represent the same type set. -func (x *term) equal(y *term) bool { - // easy cases - switch { - case x == nil || y == nil: - return x == y - case x.typ == nil || y.typ == nil: - return x.typ == y.typ - } - // ∅ ⊂ x, y ⊂ 𝓤 - - return x.tilde == y.tilde && types.Identical(x.typ, y.typ) -} - -// union returns the union x ∪ y: zero, one, or two non-nil terms. -func (x *term) union(y *term) (_, _ *term) { - // easy cases - switch { - case x == nil && y == nil: - return nil, nil // ∅ ∪ ∅ == ∅ - case x == nil: - return y, nil // ∅ ∪ y == y - case y == nil: - return x, nil // x ∪ ∅ == x - case x.typ == nil: - return x, nil // 𝓤 ∪ y == 𝓤 - case y.typ == nil: - return y, nil // x ∪ 𝓤 == 𝓤 - } - // ∅ ⊂ x, y ⊂ 𝓤 - - if x.disjoint(y) { - return x, y // x ∪ y == (x, y) if x ∩ y == ∅ - } - // x.typ == y.typ - - // ~t ∪ ~t == ~t - // ~t ∪ T == ~t - // T ∪ ~t == ~t - // T ∪ T == T - if x.tilde || !y.tilde { - return x, nil - } - return y, nil -} - -// intersect returns the intersection x ∩ y. -func (x *term) intersect(y *term) *term { - // easy cases - switch { - case x == nil || y == nil: - return nil // ∅ ∩ y == ∅ and ∩ ∅ == ∅ - case x.typ == nil: - return y // 𝓤 ∩ y == y - case y.typ == nil: - return x // x ∩ 𝓤 == x - } - // ∅ ⊂ x, y ⊂ 𝓤 - - if x.disjoint(y) { - return nil // x ∩ y == ∅ if x ∩ y == ∅ - } - // x.typ == y.typ - - // ~t ∩ ~t == ~t - // ~t ∩ T == T - // T ∩ ~t == T - // T ∩ T == T - if !x.tilde || y.tilde { - return x - } - return y -} - -// includes reports whether t ∈ x. -func (x *term) includes(t types.Type) bool { - // easy cases - switch { - case x == nil: - return false // t ∈ ∅ == false - case x.typ == nil: - return true // t ∈ 𝓤 == true - } - // ∅ ⊂ x ⊂ 𝓤 - - u := t - if x.tilde { - u = under(u) - } - return types.Identical(x.typ, u) -} - -// subsetOf reports whether x ⊆ y. -func (x *term) subsetOf(y *term) bool { - // easy cases - switch { - case x == nil: - return true // ∅ ⊆ y == true - case y == nil: - return false // x ⊆ ∅ == false since x != ∅ - case y.typ == nil: - return true // x ⊆ 𝓤 == true - case x.typ == nil: - return false // 𝓤 ⊆ y == false since y != 𝓤 - } - // ∅ ⊂ x, y ⊂ 𝓤 - - if x.disjoint(y) { - return false // x ⊆ y == false if x ∩ y == ∅ - } - // x.typ == y.typ - - // ~t ⊆ ~t == true - // ~t ⊆ T == false - // T ⊆ ~t == true - // T ⊆ T == true - return !x.tilde || y.tilde -} - -// disjoint reports whether x ∩ y == ∅. -// x.typ and y.typ must not be nil. -func (x *term) disjoint(y *term) bool { - ux := x.typ - if y.tilde { - ux = under(ux) - } - uy := y.typ - if x.tilde { - uy = under(uy) - } - return !types.Identical(ux, uy) -} diff --git a/vendor/github.com/alingse/nilnesserr/linter.go b/vendor/github.com/alingse/nilnesserr/linter.go deleted file mode 100644 index 2f57246280..0000000000 --- a/vendor/github.com/alingse/nilnesserr/linter.go +++ /dev/null @@ -1,50 +0,0 @@ -package nilnesserr - -import ( - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/buildssa" -) - -const ( - linterName = "nilnesserr" - linterDoc = `Reports constructs that checks for err != nil, but returns a different nil value error. -Powered by nilness and nilerr.` - - linterReturnMessage = "return a nil value error after check error" - linterCallMessage = "call function with a nil value error after check error" - linterVariadicCallMessage = "call variadic function with a nil value error after check error" -) - -type LinterSetting struct{} - -func NewAnalyzer(setting LinterSetting) (*analysis.Analyzer, error) { - a, err := newAnalyzer(setting) - if err != nil { - return nil, err - } - - return &analysis.Analyzer{ - Name: linterName, - Doc: linterDoc, - Run: a.run, - Requires: []*analysis.Analyzer{ - buildssa.Analyzer, - }, - }, nil -} - -type analyzer struct { - setting LinterSetting -} - -func newAnalyzer(setting LinterSetting) (*analyzer, error) { - a := &analyzer{setting: setting} - - return a, nil -} - -func (a *analyzer) run(pass *analysis.Pass) (interface{}, error) { - _, _ = a.checkNilnesserr(pass) - - return nil, nil -} diff --git a/vendor/github.com/alingse/nilnesserr/nilerr.go b/vendor/github.com/alingse/nilnesserr/nilerr.go deleted file mode 100644 index 093fc1eb81..0000000000 --- a/vendor/github.com/alingse/nilnesserr/nilerr.go +++ /dev/null @@ -1,192 +0,0 @@ -// some code was copy from https://github.com/gostaticanalysis/nilerr/blob/master/nilerr.go - -package nilnesserr - -import ( - "go/types" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/ssa" -) - -var errType = types.Universe.Lookup("error").Type().Underlying().(*types.Interface) // nolint: forcetypeassert - -func isErrType(res ssa.Value) bool { - return types.Implements(res.Type(), errType) -} - -func isConstNil(res ssa.Value) bool { - v, ok := res.(*ssa.Const) - if ok && v.IsNil() { - return true - } - - return false -} - -func extractCheckedErrorValue(binOp *ssa.BinOp) ssa.Value { - if isErrType(binOp.X) && isConstNil(binOp.Y) { - return binOp.X - } - if isErrType(binOp.Y) && isConstNil(binOp.X) { - return binOp.Y - } - - return nil -} - -type errFact fact - -func findLastNonnilValue(errors []errFact, res ssa.Value) ssa.Value { - if len(errors) == 0 { - return nil - } - - for j := len(errors) - 1; j >= 0; j-- { - last := errors[j] - if last.value == res { - return nil - } else if last.nilness == isnonnil { - return last.value - } - } - - return nil -} - -func checkNilnesserr(pass *analysis.Pass, b *ssa.BasicBlock, errors []errFact, isNilnees func(value ssa.Value) bool) { - for _, instr := range b.Instrs { - pos := instr.Pos() - if !pos.IsValid() { - continue - } - - switch instr := instr.(type) { - case *ssa.Return: - for _, value := range instr.Results { - if checkSSAValue(value, errors, isNilnees) { - pass.Report(analysis.Diagnostic{ - Pos: pos, - Message: linterReturnMessage, - }) - } - } - case *ssa.Call: - for _, value := range instr.Call.Args { - if checkSSAValue(value, errors, isNilnees) { - pass.Report(analysis.Diagnostic{ - Pos: pos, - Message: linterCallMessage, - }) - } - } - - // extra check for variadic arguments - variadicArgs := checkVariadicCall(instr) - for _, value := range variadicArgs { - if checkSSAValue(value, errors, isNilnees) { - pass.Report(analysis.Diagnostic{ - Pos: pos, - Message: linterVariadicCallMessage, - }) - } - } - } - } -} - -func checkSSAValue(res ssa.Value, errors []errFact, isNilnees func(value ssa.Value) bool) bool { - if !isErrType(res) || isConstNil(res) || !isNilnees(res) { - return false - } - // check the lastValue error that is isnonnil - lastValue := findLastNonnilValue(errors, res) - - return lastValue != nil -} - -func checkVariadicCall(call *ssa.Call) []ssa.Value { - alloc := validateVariadicCall(call) - if alloc == nil { - return nil - } - - return extractVariadicErrors(alloc) -} - -/* -example: fmt.Errorf("call Do2 got err %w", err) - -type *ssa.Alloc instr new [1]any (varargs) -type *ssa.IndexAddr instr &t4[0:int] -type *ssa.ChangeInterface instr change interface any <- error (t0) -type *ssa.Store instr *t5 = t6 -... -type *ssa.Slice instr slice t4[:] -type *ssa.Call instr fmt.Errorf("call Do2 got err ...":string, t7...) -*/ -func validateVariadicCall(call *ssa.Call) *ssa.Alloc { - fn, ok := call.Call.Value.(*ssa.Function) - if !ok { - return nil - } - if !fn.Signature.Variadic() { - return nil - } - - if len(call.Call.Args) == 0 { - return nil - } - lastArg := call.Call.Args[len(call.Call.Args)-1] - slice, ok := lastArg.(*ssa.Slice) - if !ok { - return nil - } - // check is t[:] - if !(slice.Low == nil && slice.High == nil && slice.Max == nil) { - return nil - } - alloc, ok := slice.X.(*ssa.Alloc) - if !ok { - return nil - } - valueType, ok := alloc.Type().(*types.Pointer) - if !ok { - return nil - } - - // check is array - _, ok = valueType.Elem().(*types.Array) - if !ok { - return nil - } - - return alloc -} - -// the Referrer chain is like this. -// Alloc --> IndexAddr --> ChangeInterface --> Store ---> Slice. -// Alloc --> IndexAddr --> Store --> Slice. -func extractVariadicErrors(alloc *ssa.Alloc) []ssa.Value { - values := make([]ssa.Value, 0) - - for _, instr := range *alloc.Referrers() { - indexAddr, ok := instr.(*ssa.IndexAddr) - if !ok { - continue - } - for _, instr2 := range *indexAddr.Referrers() { - store, ok := instr2.(*ssa.Store) - if !ok { - continue - } - value := store.Val - if change, ok := value.(*ssa.ChangeInterface); ok { - value = change.X - } - values = append(values, value) - } - } - - return values -} diff --git a/vendor/github.com/alingse/nilnesserr/nilness.go b/vendor/github.com/alingse/nilnesserr/nilness.go deleted file mode 100644 index cd5a691070..0000000000 --- a/vendor/github.com/alingse/nilnesserr/nilness.go +++ /dev/null @@ -1,374 +0,0 @@ -// This file was copy from https://cs.opensource.google/go/x/tools/+/master:go/analysis/passes/nilness/nilness.go -// I modified some to check the error return - -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package nilnesserr - -import ( - "go/token" - "go/types" - - "github.com/alingse/nilnesserr/internal/typeparams" - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/buildssa" - "golang.org/x/tools/go/ssa" -) - -func (a *analyzer) checkNilnesserr(pass *analysis.Pass) (interface{}, error) { - ssainput := pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA) - for _, fn := range ssainput.SrcFuncs { - runFunc(pass, fn) - } - return nil, nil -} - -func runFunc(pass *analysis.Pass, fn *ssa.Function) { - // visit visits reachable blocks of the CFG in dominance order, - // maintaining a stack of dominating nilness facts. - // - // By traversing the dom tree, we can pop facts off the stack as - // soon as we've visited a subtree. Had we traversed the CFG, - // we would need to retain the set of facts for each block. - seen := make([]bool, len(fn.Blocks)) // seen[i] means visit should ignore block i - - var visit func(b *ssa.BasicBlock, stack []fact, errors []errFact) - - visit = func(b *ssa.BasicBlock, stack []fact, errors []errFact) { - if seen[b.Index] { - return - } - seen[b.Index] = true - - // check this block return a nil value error - checkNilnesserr( - pass, b, - errors, - func(v ssa.Value) bool { - return nilnessOf(stack, v) == isnil - }) - - // For nil comparison blocks, report an error if the condition - // is degenerate, and push a nilness fact on the stack when - // visiting its true and false successor blocks. - if binop, tsucc, fsucc := eq(b); binop != nil { - // extract the err != nil or err == nil - errValue := extractCheckedErrorValue(binop) - - xnil := nilnessOf(stack, binop.X) - ynil := nilnessOf(stack, binop.Y) - - if ynil != unknown && xnil != unknown && (xnil == isnil || ynil == isnil) { - // Degenerate condition: - // the nilness of both operands is known, - // and at least one of them is nil. - - // If tsucc's or fsucc's sole incoming edge is impossible, - // it is unreachable. Prune traversal of it and - // all the blocks it dominates. - // (We could be more precise with full dataflow - // analysis of control-flow joins.) - var skip *ssa.BasicBlock - if xnil == ynil { - skip = fsucc - } else { - skip = tsucc - } - for _, d := range b.Dominees() { - if d == skip && len(d.Preds) == 1 { - continue - } - - visit(d, stack, errors) - } - - return - } - - // "if x == nil" or "if nil == y" condition; x, y are unknown. - if xnil == isnil || ynil == isnil { - var newFacts facts - if xnil == isnil { - // x is nil, y is unknown: - // t successor learns y is nil. - newFacts = expandFacts(fact{binop.Y, isnil}) - } else { - // y is nil, x is unknown: - // t successor learns x is nil. - newFacts = expandFacts(fact{binop.X, isnil}) - } - - for _, d := range b.Dominees() { - // Successor blocks learn a fact - // only at non-critical edges. - // (We could do be more precise with full dataflow - // analysis of control-flow joins.) - s := stack - errs := errors - if len(d.Preds) == 1 { - if d == tsucc { - s = append(s, newFacts...) - // add nil error - if errValue != nil { - errs = append(errs, errFact{value: errValue, nilness: isnil}) - } - } else if d == fsucc { - s = append(s, newFacts.negate()...) - // add non-nil error - if errValue != nil { - errs = append(errs, errFact{value: errValue, nilness: isnonnil}) - } - } - } - - visit(d, s, errs) - } - return - } - } - - // In code of the form: - // - // if ptr, ok := x.(*T); ok { ... } else { fsucc } - // - // the fsucc block learns that ptr == nil, - // since that's its zero value. - if If, ok := b.Instrs[len(b.Instrs)-1].(*ssa.If); ok { - // Handle "if ok" and "if !ok" variants. - cond, fsucc := If.Cond, b.Succs[1] - if unop, ok := cond.(*ssa.UnOp); ok && unop.Op == token.NOT { - cond, fsucc = unop.X, b.Succs[0] - } - - // Match pattern: - // t0 = typeassert (pointerlike) - // t1 = extract t0 #0 // ptr - // t2 = extract t0 #1 // ok - // if t2 goto tsucc, fsucc - if extract1, ok := cond.(*ssa.Extract); ok && extract1.Index == 1 { - if assert, ok := extract1.Tuple.(*ssa.TypeAssert); ok && - isNillable(assert.AssertedType) { - for _, pinstr := range *assert.Referrers() { - if extract0, ok := pinstr.(*ssa.Extract); ok && - extract0.Index == 0 && - extract0.Tuple == extract1.Tuple { - for _, d := range b.Dominees() { - if len(d.Preds) == 1 && d == fsucc { - visit(d, append(stack, fact{extract0, isnil}), errors) - } - } - } - } - } - } - } - - for _, d := range b.Dominees() { - visit(d, stack, errors) - } - } - - // Visit the entry block. No need to visit fn.Recover. - if fn.Blocks != nil { - visit(fn.Blocks[0], make([]fact, 0, 20), nil) // 20 is plenty - } -} - -// A fact records that a block is dominated -// by the condition v == nil or v != nil. -type fact struct { - value ssa.Value - nilness nilness -} - -func (f fact) negate() fact { return fact{f.value, -f.nilness} } - -type nilness int - -const ( - isnonnil = -1 - unknown nilness = 0 - isnil = 1 -) - -var nilnessStrings = []string{"non-nil", "unknown", "nil"} - -func (n nilness) String() string { return nilnessStrings[n+1] } - -// nilnessOf reports whether v is definitely nil, definitely not nil, -// or unknown given the dominating stack of facts. -func nilnessOf(stack []fact, v ssa.Value) nilness { - switch v := v.(type) { - // unwrap ChangeInterface and Slice values recursively, to detect if underlying - // values have any facts recorded or are otherwise known with regard to nilness. - // - // This work must be in addition to expanding facts about - // ChangeInterfaces during inference/fact gathering because this covers - // cases where the nilness of a value is intrinsic, rather than based - // on inferred facts, such as a zero value interface variable. That - // said, this work alone would only inform us when facts are about - // underlying values, rather than outer values, when the analysis is - // transitive in both directions. - case *ssa.ChangeInterface: - if underlying := nilnessOf(stack, v.X); underlying != unknown { - return underlying - } - case *ssa.MakeInterface: - // A MakeInterface is non-nil unless its operand is a type parameter. - tparam, ok := types.Unalias(v.X.Type()).(*types.TypeParam) - if !ok { - return isnonnil - } - - // A MakeInterface of a type parameter is non-nil if - // the type parameter cannot be instantiated as an - // interface type (#66835). - if terms, err := typeparams.NormalTerms(tparam.Constraint()); err == nil && len(terms) > 0 { - return isnonnil - } - - // If the type parameter can be instantiated as an - // interface (and thus also as a concrete type), - // we can't determine the nilness. - - case *ssa.Slice: - if underlying := nilnessOf(stack, v.X); underlying != unknown { - return underlying - } - case *ssa.SliceToArrayPointer: - nn := nilnessOf(stack, v.X) - if slice2ArrayPtrLen(v) > 0 { - if nn == isnil { - // We know that *(*[1]byte)(nil) is going to panic because of the - // conversion. So return unknown to the caller, prevent useless - // nil deference reporting due to * operator. - return unknown - } - // Otherwise, the conversion will yield a non-nil pointer to array. - // Note that the instruction can still panic if array length greater - // than slice length. If the value is used by another instruction, - // that instruction can assume the panic did not happen when that - // instruction is reached. - return isnonnil - } - // In case array length is zero, the conversion result depends on nilness of the slice. - if nn != unknown { - return nn - } - } - - // Is value intrinsically nil or non-nil? - switch v := v.(type) { - case *ssa.Alloc, - *ssa.FieldAddr, - *ssa.FreeVar, - *ssa.Function, - *ssa.Global, - *ssa.IndexAddr, - *ssa.MakeChan, - *ssa.MakeClosure, - *ssa.MakeMap, - *ssa.MakeSlice: - return isnonnil - - case *ssa.Const: - if v.IsNil() { - return isnil // nil or zero value of a pointer-like type - } else { - return unknown // non-pointer - } - } - - // Search dominating control-flow facts. - for _, f := range stack { - if f.value == v { - return f.nilness - } - } - return unknown -} - -func slice2ArrayPtrLen(v *ssa.SliceToArrayPointer) int64 { - return v.Type().(*types.Pointer).Elem().Underlying().(*types.Array).Len() -} - -// If b ends with an equality comparison, eq returns the operation and -// its true (equal) and false (not equal) successors. -func eq(b *ssa.BasicBlock) (op *ssa.BinOp, tsucc, fsucc *ssa.BasicBlock) { - if If, ok := b.Instrs[len(b.Instrs)-1].(*ssa.If); ok { - if binop, ok := If.Cond.(*ssa.BinOp); ok { - switch binop.Op { - case token.EQL: - return binop, b.Succs[0], b.Succs[1] - case token.NEQ: - return binop, b.Succs[1], b.Succs[0] - } - } - } - return nil, nil, nil -} - -// expandFacts takes a single fact and returns the set of facts that can be -// known about it or any of its related values. Some operations, like -// ChangeInterface, have transitive nilness, such that if you know the -// underlying value is nil, you also know the value itself is nil, and vice -// versa. This operation allows callers to match on any of the related values -// in analyses, rather than just the one form of the value that happened to -// appear in a comparison. -// -// This work must be in addition to unwrapping values within nilnessOf because -// while this work helps give facts about transitively known values based on -// inferred facts, the recursive check within nilnessOf covers cases where -// nilness facts are intrinsic to the underlying value, such as a zero value -// interface variables. -// -// ChangeInterface is the only expansion currently supported, but others, like -// Slice, could be added. At this time, this tool does not check slice -// operations in a way this expansion could help. See -// https://play.golang.org/p/mGqXEp7w4fR for an example. -func expandFacts(f fact) []fact { - ff := []fact{f} - -Loop: - for { - switch v := f.value.(type) { - case *ssa.ChangeInterface: - f = fact{v.X, f.nilness} - ff = append(ff, f) - default: - break Loop - } - } - - return ff -} - -type facts []fact - -func (ff facts) negate() facts { - nn := make([]fact, len(ff)) - for i, f := range ff { - nn[i] = f.negate() - } - return nn -} - -func isNillable(t types.Type) bool { - // TODO(adonovan): CoreType (+ case *Interface) looks wrong. - // This should probably use Underlying, and handle TypeParam - // by computing the union across its normal terms. - switch t := typeparams.CoreType(t).(type) { - case *types.Pointer, - *types.Map, - *types.Signature, - *types.Chan, - *types.Interface, - *types.Slice: - return true - case *types.Basic: - return t == types.Typ[types.UnsafePointer] - } - return false -} diff --git a/vendor/github.com/ashanbrown/forbidigo/v2/LICENSE b/vendor/github.com/ashanbrown/forbidigo/v2/LICENSE deleted file mode 100644 index dc1d47ad54..0000000000 --- a/vendor/github.com/ashanbrown/forbidigo/v2/LICENSE +++ /dev/null @@ -1,13 +0,0 @@ -Copyright 2019 Andrew Shannon Brown - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/vendor/github.com/ashanbrown/forbidigo/v2/forbidigo/config_options.go b/vendor/github.com/ashanbrown/forbidigo/v2/forbidigo/config_options.go deleted file mode 100644 index 3f0ed6682a..0000000000 --- a/vendor/github.com/ashanbrown/forbidigo/v2/forbidigo/config_options.go +++ /dev/null @@ -1,129 +0,0 @@ -package forbidigo - -// Code generated by github.com/launchdarkly/go-options. DO NOT EDIT. - -import "fmt" - -import "github.com/google/go-cmp/cmp" - -type ApplyOptionFunc func(c *config) error - -func (f ApplyOptionFunc) apply(c *config) error { - return f(c) -} - -func newConfig(options ...Option) (config, error) { - var c config - err := applyConfigOptions(&c, options...) - return c, err -} - -func applyConfigOptions(c *config, options ...Option) error { - c.ExcludeGodocExamples = true - for _, o := range options { - if err := o.apply(c); err != nil { - return err - } - } - return nil -} - -type Option interface { - apply(*config) error -} - -type optionExcludeGodocExamplesImpl struct { - o bool -} - -func (o optionExcludeGodocExamplesImpl) apply(c *config) error { - c.ExcludeGodocExamples = o.o - return nil -} - -func (o optionExcludeGodocExamplesImpl) Equal(v optionExcludeGodocExamplesImpl) bool { - switch { - case !cmp.Equal(o.o, v.o): - return false - } - return true -} - -func (o optionExcludeGodocExamplesImpl) String() string { - name := "OptionExcludeGodocExamples" - - // hack to avoid go vet error about passing a function to Sprintf - var value interface{} = o.o - return fmt.Sprintf("%s: %+v", name, value) -} - -// OptionExcludeGodocExamples don't check inside Godoc examples (see https://blog.golang.org/examples) -func OptionExcludeGodocExamples(o bool) Option { - return optionExcludeGodocExamplesImpl{ - o: o, - } -} - -type optionIgnorePermitDirectivesImpl struct { - o bool -} - -func (o optionIgnorePermitDirectivesImpl) apply(c *config) error { - c.IgnorePermitDirectives = o.o - return nil -} - -func (o optionIgnorePermitDirectivesImpl) Equal(v optionIgnorePermitDirectivesImpl) bool { - switch { - case !cmp.Equal(o.o, v.o): - return false - } - return true -} - -func (o optionIgnorePermitDirectivesImpl) String() string { - name := "OptionIgnorePermitDirectives" - - // hack to avoid go vet error about passing a function to Sprintf - var value interface{} = o.o - return fmt.Sprintf("%s: %+v", name, value) -} - -// OptionIgnorePermitDirectives don't check for `permit` directives(for example, in favor of `nolint`) -func OptionIgnorePermitDirectives(o bool) Option { - return optionIgnorePermitDirectivesImpl{ - o: o, - } -} - -type optionAnalyzeTypesImpl struct { - o bool -} - -func (o optionAnalyzeTypesImpl) apply(c *config) error { - c.AnalyzeTypes = o.o - return nil -} - -func (o optionAnalyzeTypesImpl) Equal(v optionAnalyzeTypesImpl) bool { - switch { - case !cmp.Equal(o.o, v.o): - return false - } - return true -} - -func (o optionAnalyzeTypesImpl) String() string { - name := "OptionAnalyzeTypes" - - // hack to avoid go vet error about passing a function to Sprintf - var value interface{} = o.o - return fmt.Sprintf("%s: %+v", name, value) -} - -// OptionAnalyzeTypes enable to match canonical names for types and interfaces using type info -func OptionAnalyzeTypes(o bool) Option { - return optionAnalyzeTypesImpl{ - o: o, - } -} diff --git a/vendor/github.com/ashanbrown/forbidigo/v2/forbidigo/forbidigo.go b/vendor/github.com/ashanbrown/forbidigo/v2/forbidigo/forbidigo.go deleted file mode 100644 index 913b45e957..0000000000 --- a/vendor/github.com/ashanbrown/forbidigo/v2/forbidigo/forbidigo.go +++ /dev/null @@ -1,405 +0,0 @@ -// Package forbidigo provides a linter for forbidding the use of specific identifiers -package forbidigo - -import ( - "bytes" - "fmt" - "go/ast" - "go/printer" - "go/token" - "go/types" - "log" - "regexp" - "strings" -) - -type Issue interface { - Details() string - Pos() token.Pos - Position() token.Position - String() string -} - -type UsedIssue struct { - identifier string - pattern string - pos token.Pos - position token.Position - customMsg string -} - -func (a UsedIssue) Details() string { - explanation := fmt.Sprintf(` because %q`, a.customMsg) - if a.customMsg == "" { - explanation = fmt.Sprintf(" by pattern `%s`", a.pattern) - } - return fmt.Sprintf("use of `%s` forbidden", a.identifier) + explanation -} - -func (a UsedIssue) Position() token.Position { - return a.position -} - -func (a UsedIssue) Pos() token.Pos { - return a.pos -} - -func (a UsedIssue) String() string { return toString(a) } - -func toString(i UsedIssue) string { - return fmt.Sprintf("%s at %s", i.Details(), i.Position()) -} - -type Linter struct { - cfg config - patterns []*pattern -} - -func DefaultPatterns() []string { - return []string{`^(fmt\.Print(|f|ln)|print|println)$`} -} - -//go:generate go-options config -type config struct { - // don't check inside Godoc examples (see https://blog.golang.org/examples) - ExcludeGodocExamples bool `options:",true"` - IgnorePermitDirectives bool // don't check for `permit` directives(for example, in favor of `nolint`) - AnalyzeTypes bool // enable to match canonical names for types and interfaces using type info -} - -func NewLinter(patterns []string, options ...Option) (*Linter, error) { - cfg, err := newConfig(options...) - if err != nil { - return nil, fmt.Errorf("failed to process options: %w", err) - } - - if len(patterns) == 0 { - patterns = DefaultPatterns() - } - compiledPatterns := make([]*pattern, 0, len(patterns)) - for _, ptrn := range patterns { - p, err := parse(ptrn) - if err != nil { - return nil, err - } - compiledPatterns = append(compiledPatterns, p) - } - return &Linter{ - cfg: cfg, - patterns: compiledPatterns, - }, nil -} - -type visitor struct { - cfg config - isTestFile bool // godoc only runs on test files - - linter *Linter - comments []*ast.CommentGroup - - runConfig RunConfig - issues []Issue -} - -// Deprecated: Run was the original entrypoint before RunWithConfig was introduced to support -// additional match patterns that need additional information. -func (l *Linter) Run(fset *token.FileSet, nodes ...ast.Node) ([]Issue, error) { - return l.RunWithConfig(RunConfig{Fset: fset}, nodes...) -} - -// RunConfig provides information that the linter needs for different kinds -// of match patterns. Ideally, all fields should get set. More fields may get -// added in the future as needed. -type RunConfig struct { - // FSet is required. - Fset *token.FileSet - - // TypesInfo is needed for expanding source code expressions. - // Nil disables that step, i.e. patterns match the literal source code. - TypesInfo *types.Info - - // DebugLog is used to print debug messages. May be nil. - DebugLog func(format string, args ...interface{}) -} - -func (l *Linter) RunWithConfig(config RunConfig, nodes ...ast.Node) ([]Issue, error) { - if config.DebugLog == nil { - config.DebugLog = func(format string, args ...interface{}) {} - } - var issues []Issue - for _, node := range nodes { - var comments []*ast.CommentGroup - isTestFile := false - isWholeFileExample := false - if file, ok := node.(*ast.File); ok { - comments = file.Comments - fileName := config.Fset.Position(file.Pos()).Filename - isTestFile = strings.HasSuffix(fileName, "_test.go") - - // From https://blog.golang.org/examples, a "whole file example" is: - // a file that ends in _test.go and contains exactly one example function, - // no test or benchmark functions, and at least one other package-level declaration. - if l.cfg.ExcludeGodocExamples && isTestFile && len(file.Decls) > 1 { - numExamples := 0 - numTestsAndBenchmarks := 0 - for _, decl := range file.Decls { - funcDecl, isFuncDecl := decl.(*ast.FuncDecl) - // consider only functions, not methods - if !isFuncDecl || funcDecl.Recv != nil || funcDecl.Name == nil { - continue - } - funcName := funcDecl.Name.Name - if strings.HasPrefix(funcName, "Test") || strings.HasPrefix(funcName, "Benchmark") { - numTestsAndBenchmarks++ - break // not a whole file example - } - if strings.HasPrefix(funcName, "Example") { - numExamples++ - } - } - - // if this is a whole file example, skip this node - isWholeFileExample = numExamples == 1 && numTestsAndBenchmarks == 0 - } - } - if isWholeFileExample { - continue - } - visitor := visitor{ - cfg: l.cfg, - isTestFile: isTestFile, - linter: l, - runConfig: config, - comments: comments, - } - ast.Walk(&visitor, node) - issues = append(issues, visitor.issues...) - } - return issues, nil -} - -func (v *visitor) Visit(node ast.Node) ast.Visitor { - switch node := node.(type) { - case *ast.FuncDecl: - // don't descend into godoc examples if we are ignoring them - isGodocExample := v.isTestFile && node.Recv == nil && node.Name != nil && strings.HasPrefix(node.Name.Name, "Example") - if isGodocExample && v.cfg.ExcludeGodocExamples { - return nil - } - ast.Walk(v, node.Type) - if node.Body != nil { - ast.Walk(v, node.Body) - } - return nil - // Ignore constant and type names - case *ast.ValueSpec: - // Look at only type and values for const and variable specs, and not names - if node.Type != nil { - ast.Walk(v, node.Type) - } - if node.Values != nil { - for _, x := range node.Values { - ast.Walk(v, x) - } - } - return nil - // Ignore import alias names - case *ast.ImportSpec: - return nil - // Ignore type names - case *ast.TypeSpec: - // Look at only type parameters for type spec - if node.TypeParams != nil { - ast.Walk(v, node.TypeParams) - } - ast.Walk(v, node.Type) - return nil - // Ignore field names - case *ast.Field: - if node.Type != nil { - ast.Walk(v, node.Type) - } - return nil - // The following two are handled below. - case *ast.SelectorExpr: - case *ast.Ident: - // Everything else isn't. - default: - return v - } - - // The text as it appears in the source is always used because issues - // use that. It's used for matching unless usage of type information - // is enabled. - srcText := v.textFor(node) - matchTexts, pkgText := v.expandMatchText(node, srcText) - v.runConfig.DebugLog("%s: match %v, package %q", v.runConfig.Fset.Position(node.Pos()), matchTexts, pkgText) - for _, p := range v.linter.patterns { - if p.matches(matchTexts) && - (p.Package == "" || p.pkgRe.MatchString(pkgText)) && - !v.permit(node) { - v.issues = append(v.issues, UsedIssue{ - identifier: srcText, // Always report the expression as it appears in the source code. - pattern: p.re.String(), - pos: node.Pos(), - position: v.runConfig.Fset.Position(node.Pos()), - customMsg: p.Msg, - }) - } - } - - // descend into the left-side of selectors - if selector, isSelector := node.(*ast.SelectorExpr); isSelector { - if _, leftSideIsIdentifier := selector.X.(*ast.Ident); !leftSideIsIdentifier { - return v - } - } - - return nil -} - -// textFor returns the expression as it appears in the source code (for -// example, .). -func (v *visitor) textFor(node ast.Node) string { - buf := new(bytes.Buffer) - if err := printer.Fprint(buf, v.runConfig.Fset, node); err != nil { - log.Fatalf("ERROR: unable to print node at %s: %s", v.runConfig.Fset.Position(node.Pos()), err) - } - return buf.String() -} - -// expandMatchText expands the selector in a selector expression to the full package -// name and (for variables) the type: -// -// - example.com/some/pkg.Function -// - example.com/some/pkg.CustomType.Method -// -// It updates the text to match against and fills the package string if possible, -// otherwise it just returns. -func (v *visitor) expandMatchText(node ast.Node, srcText string) (matchTexts []string, pkgText string) { - // The text to match against is the literal source code if we cannot - // come up with something different. - matchTexts = []string{srcText} - - if !v.cfg.AnalyzeTypes || v.runConfig.TypesInfo == nil { - return matchTexts, pkgText - } - - location := v.runConfig.Fset.Position(node.Pos()) - - switch node := node.(type) { - case *ast.Ident: - if object, ok := v.runConfig.TypesInfo.Uses[node]; !ok { - // No information about the identifier. Should - // not happen, but perhaps there were compile - // errors? - v.runConfig.DebugLog("%s: unknown identifier %q", location, srcText) - } else if pkg := object.Pkg(); pkg != nil { - pkgText = pkg.Path() - // if this is a method, don't include the package name - isMethod := false - if signature, ok := object.Type().(*types.Signature); ok && signature.Recv() != nil { - isMethod = true - } - v.runConfig.DebugLog("%s: identifier: %q -> %q in package %q", location, srcText, matchTexts, pkgText) - // match either with or without package name - if !isMethod { - matchTexts = []string{pkg.Name() + "." + srcText, srcText} - } - } else { - v.runConfig.DebugLog("%s: identifier: %q -> %q without package", location, srcText, matchTexts) - } - case *ast.SelectorExpr: - selector := node.X - field := node.Sel.Name - - // If we are lucky, the entire selector expression has a known - // type. We don't care about the value. - selectorText := v.textFor(node) - if typeAndValue, ok := v.runConfig.TypesInfo.Types[selector]; ok { - if typeName, pkgPath, ok := typeNameWithPackage(typeAndValue.Type); ok { - v.runConfig.DebugLog("%s: selector %q with supported type %q: %q -> %q, package %q", location, selectorText, typeAndValue.Type.String(), srcText, matchTexts, pkgPath) - matchTexts = []string{typeName + "." + field} - pkgText = pkgPath - } else { - // handle cases such as anonymous structs - v.runConfig.DebugLog("%s: selector %q with unknown type %T", location, selectorText, typeAndValue.Type) - matchTexts = []string{} - } - } - // Some expressions need special treatment. - switch selector := selector.(type) { - case *ast.Ident: - if object, hasUses := v.runConfig.TypesInfo.Uses[selector]; hasUses { - switch object := object.(type) { - case *types.PkgName: - pkgText = object.Imported().Path() - matchTexts = []string{object.Imported().Name() + "." + field} - v.runConfig.DebugLog("%s: selector %q is package: %q -> %q, package %q", location, selectorText, srcText, matchTexts, pkgText) - case *types.Var: - if typeName, packageName, ok := typeNameWithPackage(object.Type()); ok { - matchTexts = []string{typeName + "." + field} - pkgText = packageName - v.runConfig.DebugLog("%s: selector %q is variable of type %q: %q -> %q, package %q", location, selectorText, object.Type().String(), srcText, matchTexts, pkgText) - } else { - // handle cases such as anonymous structs - v.runConfig.DebugLog("%s: selector %q is variable with unsupported type %T", location, selectorText, object.Type()) - matchTexts = []string{} - } - default: - // Something else? - v.runConfig.DebugLog("%s: selector %q is identifier with unsupported type %T", location, selectorText, object) - } - } else { - // No information about the identifier. Should - // not happen, but perhaps there were compile - // errors? - v.runConfig.DebugLog("%s: unknown selector identifier %q", location, selectorText) - } - default: - v.runConfig.DebugLog("%s: selector %q of unsupported type %T", location, selectorText, selector) - } - default: - v.runConfig.DebugLog("%s: unsupported type %T", location, node) - } - return matchTexts, pkgText -} - -// typeNameWithPackage tries to determine `.` and the full -// package path. This only needs to work for types of a selector in a selector -// expression. -func typeNameWithPackage(t types.Type) (typeName, packagePath string, ok bool) { - if ptr, ok := t.(*types.Pointer); ok { - t = ptr.Elem() - } - - switch t := t.(type) { - case *types.Alias: - return typeNameWithPackage(t.Rhs()) - case *types.Named: - obj := t.Obj() - pkg := obj.Pkg() - // we either lack a package or the package is the "universe" (i.e. builtin) - if pkg == nil { - return obj.Name(), "", true - } - return pkg.Name() + "." + obj.Name(), pkg.Path(), true - default: - return "", "", false - } -} - -func (v *visitor) permit(node ast.Node) bool { - if v.cfg.IgnorePermitDirectives { - return false - } - nodePos := v.runConfig.Fset.Position(node.Pos()) - nolint := regexp.MustCompile(fmt.Sprintf(`^//\s?permit:%s\b`, regexp.QuoteMeta(v.textFor(node)))) - for _, c := range v.comments { - commentPos := v.runConfig.Fset.Position(c.Pos()) - if commentPos.Line == nodePos.Line && len(c.List) > 0 && nolint.MatchString(c.List[0].Text) { - return true - } - } - return false -} diff --git a/vendor/github.com/ashanbrown/forbidigo/v2/forbidigo/patterns.go b/vendor/github.com/ashanbrown/forbidigo/v2/forbidigo/patterns.go deleted file mode 100644 index 5f05cec94d..0000000000 --- a/vendor/github.com/ashanbrown/forbidigo/v2/forbidigo/patterns.go +++ /dev/null @@ -1,145 +0,0 @@ -package forbidigo - -import ( - "bytes" - "fmt" - "io" - "regexp" - "regexp/syntax" - "strings" - - "gopkg.in/yaml.v3" -) - -// pattern matches code that is not supposed to be used. -type pattern struct { - re, pkgRe *regexp.Regexp - - // Pattern is the regular expression string that is used for matching. - // It gets matched against the literal source code text or the expanded - // text, depending on the mode in which the analyzer runs. - Pattern string `yaml:"p"` - - // Package is a regular expression for the full package path of - // an imported item. Ignored unless the analyzer is configured to - // determine that information. - Package string `yaml:"pkg,omitempty"` - - // Msg gets printed in addition to the normal message if a match is - // found. - Msg string `yaml:"msg,omitempty"` -} - -// A yamlPattern pattern in a YAML string may be represented either by a string -// (the traditional regular expression syntax) or a struct (for more complex -// patterns). -type yamlPattern pattern - -func (p *yamlPattern) UnmarshalYAML(value *yaml.Node) error { - // Try struct first. It's unlikely that a regular expression string - // is valid YAML for a struct. - var ptrn pattern - if err := unmarshalStrict(&ptrn, value); err != nil && err != io.EOF { - errStr := err.Error() - // Didn't work, try plain string. - var ptrn string - if err := unmarshalStrict(&ptrn, value); err != nil && err != io.EOF { - return fmt.Errorf("pattern is neither a regular expression string (%s) nor a Pattern struct (%s)", err.Error(), errStr) - } - p.Pattern = ptrn - } else { - *p = yamlPattern(ptrn) - } - return ((*pattern)(p)).validate() -} - -// unmarshalStrict implements missing yaml.UnmarshalStrict in gopkg.in/yaml.v3. -// See https://github.com/go-yaml/yaml/issues/639. -// Inspired by https://github.com/ffenix113/zigbee_home/pull/68 -func unmarshalStrict(to any, node *yaml.Node) error { - buf := &bytes.Buffer{} - if err := yaml.NewEncoder(buf).Encode(node); err != nil { - return err - } - - decoder := yaml.NewDecoder(buf) - decoder.KnownFields(true) - return decoder.Decode(to) -} - -var _ yaml.Unmarshaler = &yamlPattern{} - -// parse accepts a regular expression or, if the string starts with { or contains a line break, a -// JSON or YAML representation of a Pattern. -func parse(ptrn string) (*pattern, error) { - pattern := &pattern{} - - if strings.HasPrefix(strings.TrimSpace(ptrn), "{") || - strings.Contains(ptrn, "\n") { - // Embedded JSON or YAML. We can decode both with the YAML decoder. - decoder := yaml.NewDecoder(strings.NewReader(ptrn)) - decoder.KnownFields(true) - if err := decoder.Decode(pattern); err != nil && err != io.EOF { - return nil, fmt.Errorf("parsing as JSON or YAML failed: %v", err) - } - } else { - pattern.Pattern = ptrn - } - - if err := pattern.validate(); err != nil { - return nil, err - } - return pattern, nil -} - -func (p *pattern) validate() error { - ptrnRe, err := regexp.Compile(p.Pattern) - if err != nil { - return fmt.Errorf("unable to compile source code pattern `%s`: %s", p.Pattern, err) - } - re, err := syntax.Parse(p.Pattern, syntax.Perl) - if err != nil { - return fmt.Errorf("unable to parse source code pattern `%s`: %s", p.Pattern, err) - } - msg := extractComment(re) - if msg != "" { - p.Msg = msg - } - p.re = ptrnRe - - if p.Package != "" { - pkgRe, err := regexp.Compile(p.Package) - if err != nil { - return fmt.Errorf("unable to compile package pattern `%s`: %s", p.Package, err) - } - p.pkgRe = pkgRe - } - - return nil -} - -func (p *pattern) matches(matchTexts []string) bool { - for _, text := range matchTexts { - if p.re.MatchString(text) { - return true - } - } - return false -} - -// Traverse the leaf submatches in the regex tree and extract a comment, if any -// is present. -func extractComment(re *syntax.Regexp) string { - for _, sub := range re.Sub { - subStr := sub.String() - if strings.HasPrefix(subStr, "#") { - return strings.TrimSpace(strings.TrimPrefix(sub.String(), "#")) - } - if len(sub.Sub) > 0 { - if comment := extractComment(sub); comment != "" { - return comment - } - } - } - return "" -} diff --git a/vendor/github.com/ashanbrown/makezero/v2/LICENSE b/vendor/github.com/ashanbrown/makezero/v2/LICENSE deleted file mode 100644 index dc1d47ad54..0000000000 --- a/vendor/github.com/ashanbrown/makezero/v2/LICENSE +++ /dev/null @@ -1,13 +0,0 @@ -Copyright 2019 Andrew Shannon Brown - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/vendor/github.com/ashanbrown/makezero/v2/makezero/makezero.go b/vendor/github.com/ashanbrown/makezero/v2/makezero/makezero.go deleted file mode 100644 index 18bcad3d0a..0000000000 --- a/vendor/github.com/ashanbrown/makezero/v2/makezero/makezero.go +++ /dev/null @@ -1,230 +0,0 @@ -// Package makezero provides a linter for appends to slices initialized with non-zero length. -package makezero - -import ( - "bytes" - "fmt" - "go/ast" - "go/printer" - "go/token" - "go/types" - "log" - "regexp" -) - -// a decl might include multiple var, -// so var name with decl make final uniq obj. -type uniqDecl struct { - varName string - decl interface{} -} - -type Issue interface { - Details() string - Pos() token.Pos - Position() token.Position - String() string -} - -type AppendIssue struct { - name string - pos token.Pos - position token.Position -} - -func (a AppendIssue) Details() string { - return fmt.Sprintf("append to slice `%s` with non-zero initialized length", a.name) -} - -func (a AppendIssue) Pos() token.Pos { - return a.pos -} - -func (a AppendIssue) Position() token.Position { - return a.position -} - -func (a AppendIssue) String() string { return toString(a) } - -type MustHaveNonZeroInitLenIssue struct { - name string - pos token.Pos - position token.Position -} - -func (i MustHaveNonZeroInitLenIssue) Details() string { - return fmt.Sprintf("slice `%s` does not have non-zero initial length", i.name) -} - -func (i MustHaveNonZeroInitLenIssue) Pos() token.Pos { - return i.pos -} - -func (i MustHaveNonZeroInitLenIssue) Position() token.Position { - return i.position -} - -func (i MustHaveNonZeroInitLenIssue) String() string { return toString(i) } - -func toString(i Issue) string { - return fmt.Sprintf("%s at %s", i.Details(), i.Position()) -} - -type visitor struct { - initLenMustBeZero bool - - comments []*ast.CommentGroup // comments to apply during this visit - info *types.Info - - nonZeroLengthSliceDecls map[uniqDecl]struct{} - fset *token.FileSet - issues []Issue -} - -type Linter struct { - initLenMustBeZero bool -} - -func NewLinter(initialLengthMustBeZero bool) *Linter { - return &Linter{ - initLenMustBeZero: initialLengthMustBeZero, - } -} - -func (l Linter) Run(fset *token.FileSet, info *types.Info, nodes ...ast.Node) ([]Issue, error) { - var issues []Issue - for _, node := range nodes { - var comments []*ast.CommentGroup - if file, ok := node.(*ast.File); ok { - comments = file.Comments - } - visitor := visitor{ - nonZeroLengthSliceDecls: make(map[uniqDecl]struct{}), - initLenMustBeZero: l.initLenMustBeZero, - info: info, - fset: fset, - comments: comments, - } - ast.Walk(&visitor, node) - issues = append(issues, visitor.issues...) - } - return issues, nil -} - -func (v *visitor) Visit(node ast.Node) ast.Visitor { - switch node := node.(type) { - case *ast.CallExpr: - fun, ok := node.Fun.(*ast.Ident) - if !ok || fun.Name != "append" { - break - } - if sliceIdent, ok := node.Args[0].(*ast.Ident); ok && - v.hasNonZeroInitialLength(sliceIdent) && - !v.hasNoLintOnSameLine(fun) { - v.issues = append(v.issues, - AppendIssue{ - name: sliceIdent.Name, - pos: fun.Pos(), - position: v.fset.Position(fun.Pos()), - }) - } - case *ast.AssignStmt: - for i, right := range node.Rhs { - if right, ok := right.(*ast.CallExpr); ok { - fun, ok := right.Fun.(*ast.Ident) - if !ok || fun.Name != "make" { - continue - } - left := node.Lhs[i] - if len(right.Args) == 2 { - // ignore if not a slice or it has explicit zero length - if !v.isSlice(right.Args[0]) { - continue - } else if lit, ok := right.Args[1].(*ast.BasicLit); ok && lit.Kind == token.INT && lit.Value == "0" { - continue - } - if v.initLenMustBeZero && !v.hasNoLintOnSameLine(fun) { - v.issues = append(v.issues, MustHaveNonZeroInitLenIssue{ - name: v.textFor(left), - pos: node.Pos(), - position: v.fset.Position(node.Pos()), - }) - } - v.recordNonZeroLengthSlices(left) - } - } - } - } - return v -} - -func (v *visitor) textFor(node ast.Node) string { - typeBuf := new(bytes.Buffer) - if err := printer.Fprint(typeBuf, v.fset, node); err != nil { - log.Fatalf("ERROR: unable to print type: %s", err) - } - return typeBuf.String() -} - -func (v *visitor) hasNonZeroInitialLength(ident *ast.Ident) bool { - if ident.Obj == nil { - log.Printf("WARNING: could not determine with %q at %s is a slice (missing object type)", - ident.Name, v.fset.Position(ident.Pos()).String()) - return false - } - _, exists := v.nonZeroLengthSliceDecls[uniqDecl{ - varName: ident.Obj.Name, - decl: ident.Obj.Decl, - }] - return exists -} - -func (v *visitor) recordNonZeroLengthSlices(node ast.Node) { - ident, ok := node.(*ast.Ident) - if !ok { - return - } - if ident.Obj == nil { - return - } - v.nonZeroLengthSliceDecls[uniqDecl{ - varName: ident.Obj.Name, - decl: ident.Obj.Decl, - }] = struct{}{} -} - -func (v *visitor) isSlice(node ast.Node) bool { - // determine type if this is a user-defined type - if ident, ok := node.(*ast.Ident); ok { - obj := ident.Obj - if obj == nil { - if v.info != nil { - _, ok := v.info.ObjectOf(ident).Type().(*types.Slice) - return ok - } - return false - } - spec, ok := obj.Decl.(*ast.TypeSpec) - if !ok { - return false - } - node = spec.Type - } - - if node, ok := node.(*ast.ArrayType); ok { - return node.Len == nil // only slices have zero length - } - return false -} - -func (v *visitor) hasNoLintOnSameLine(node ast.Node) bool { - nolint := regexp.MustCompile(`^\s*nozero\b`) - nodePos := v.fset.Position(node.Pos()) - for _, c := range v.comments { - commentPos := v.fset.Position(c.Pos()) - if commentPos.Line == nodePos.Line && nolint.MatchString(c.Text()) { - return true - } - } - return false -} diff --git a/vendor/github.com/aymanbagabas/go-osc52/v2/LICENSE b/vendor/github.com/aymanbagabas/go-osc52/v2/LICENSE deleted file mode 100644 index 25cec1ed48..0000000000 --- a/vendor/github.com/aymanbagabas/go-osc52/v2/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2022 Ayman Bagabas - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/aymanbagabas/go-osc52/v2/README.md b/vendor/github.com/aymanbagabas/go-osc52/v2/README.md deleted file mode 100644 index 4de3a22d14..0000000000 --- a/vendor/github.com/aymanbagabas/go-osc52/v2/README.md +++ /dev/null @@ -1,83 +0,0 @@ - -# go-osc52 - -

- Latest Release - GoDoc -

- -A Go library to work with the [ANSI OSC52](https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands) terminal sequence. - -## Usage - -You can use this small library to construct an ANSI OSC52 sequence suitable for -your terminal. - - -### Example - -```go -import ( - "os" - "fmt" - - "github.com/aymanbagabas/go-osc52/v2" -) - -func main() { - s := "Hello World!" - - // Copy `s` to system clipboard - osc52.New(s).WriteTo(os.Stderr) - - // Copy `s` to primary clipboard (X11) - osc52.New(s).Primary().WriteTo(os.Stderr) - - // Query the clipboard - osc52.Query().WriteTo(os.Stderr) - - // Clear system clipboard - osc52.Clear().WriteTo(os.Stderr) - - // Use the fmt.Stringer interface to copy `s` to system clipboard - fmt.Fprint(os.Stderr, osc52.New(s)) - - // Or to primary clipboard - fmt.Fprint(os.Stderr, osc52.New(s).Primary()) -} -``` - -## SSH Example - -You can use this over SSH using [gliderlabs/ssh](https://github.com/gliderlabs/ssh) for instance: - -```go -var sshSession ssh.Session -seq := osc52.New("Hello awesome!") -// Check if term is screen or tmux -pty, _, _ := s.Pty() -if pty.Term == "screen" { - seq = seq.Screen() -} else if isTmux { - seq = seq.Tmux() -} -seq.WriteTo(sshSession.Stderr()) -``` - -## Tmux - -Make sure you have `set-clipboard on` in your config, otherwise, tmux won't -allow your application to access the clipboard [^1]. - -Using the tmux option, `osc52.TmuxMode` or `osc52.New(...).Tmux()`, wraps the -OSC52 sequence in a special tmux DCS sequence and pass it to the outer -terminal. This requires `allow-passthrough on` in your config. -`allow-passthrough` is no longer enabled by default -[since tmux 3.3a](https://github.com/tmux/tmux/issues/3218#issuecomment-1153089282) [^2]. - -[^1]: See [tmux clipboard](https://github.com/tmux/tmux/wiki/Clipboard) -[^2]: [What is allow-passthrough](https://github.com/tmux/tmux/wiki/FAQ#what-is-the-passthrough-escape-sequence-and-how-do-i-use-it) - -## Credits - -* [vim-oscyank](https://github.com/ojroques/vim-oscyank) this is heavily inspired by vim-oscyank. diff --git a/vendor/github.com/aymanbagabas/go-osc52/v2/osc52.go b/vendor/github.com/aymanbagabas/go-osc52/v2/osc52.go deleted file mode 100644 index dc758d2869..0000000000 --- a/vendor/github.com/aymanbagabas/go-osc52/v2/osc52.go +++ /dev/null @@ -1,305 +0,0 @@ -// OSC52 is a terminal escape sequence that allows copying text to the clipboard. -// -// The sequence consists of the following: -// -// OSC 52 ; Pc ; Pd BEL -// -// Pc is the clipboard choice: -// -// c: clipboard -// p: primary -// q: secondary (not supported) -// s: select (not supported) -// 0-7: cut-buffers (not supported) -// -// Pd is the data to copy to the clipboard. This string should be encoded in -// base64 (RFC-4648). -// -// If Pd is "?", the terminal replies to the host with the current contents of -// the clipboard. -// -// If Pd is neither a base64 string nor "?", the terminal clears the clipboard. -// -// See https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands -// where Ps = 52 => Manipulate Selection Data. -// -// Examples: -// -// // copy "hello world" to the system clipboard -// fmt.Fprint(os.Stderr, osc52.New("hello world")) -// -// // copy "hello world" to the primary Clipboard -// fmt.Fprint(os.Stderr, osc52.New("hello world").Primary()) -// -// // limit the size of the string to copy 10 bytes -// fmt.Fprint(os.Stderr, osc52.New("0123456789").Limit(10)) -// -// // escape the OSC52 sequence for screen using DCS sequences -// fmt.Fprint(os.Stderr, osc52.New("hello world").Screen()) -// -// // escape the OSC52 sequence for Tmux -// fmt.Fprint(os.Stderr, osc52.New("hello world").Tmux()) -// -// // query the system Clipboard -// fmt.Fprint(os.Stderr, osc52.Query()) -// -// // query the primary clipboard -// fmt.Fprint(os.Stderr, osc52.Query().Primary()) -// -// // clear the system Clipboard -// fmt.Fprint(os.Stderr, osc52.Clear()) -// -// // clear the primary Clipboard -// fmt.Fprint(os.Stderr, osc52.Clear().Primary()) -package osc52 - -import ( - "encoding/base64" - "fmt" - "io" - "strings" -) - -// Clipboard is the clipboard buffer to use. -type Clipboard rune - -const ( - // SystemClipboard is the system clipboard buffer. - SystemClipboard Clipboard = 'c' - // PrimaryClipboard is the primary clipboard buffer (X11). - PrimaryClipboard = 'p' -) - -// Mode is the mode to use for the OSC52 sequence. -type Mode uint - -const ( - // DefaultMode is the default OSC52 sequence mode. - DefaultMode Mode = iota - // ScreenMode escapes the OSC52 sequence for screen using DCS sequences. - ScreenMode - // TmuxMode escapes the OSC52 sequence for tmux. Not needed if tmux - // clipboard is set to `set-clipboard on` - TmuxMode -) - -// Operation is the OSC52 operation. -type Operation uint - -const ( - // SetOperation is the copy operation. - SetOperation Operation = iota - // QueryOperation is the query operation. - QueryOperation - // ClearOperation is the clear operation. - ClearOperation -) - -// Sequence is the OSC52 sequence. -type Sequence struct { - str string - limit int - op Operation - mode Mode - clipboard Clipboard -} - -var _ fmt.Stringer = Sequence{} - -var _ io.WriterTo = Sequence{} - -// String returns the OSC52 sequence. -func (s Sequence) String() string { - var seq strings.Builder - // mode escape sequences start - seq.WriteString(s.seqStart()) - // actual OSC52 sequence start - seq.WriteString(fmt.Sprintf("\x1b]52;%c;", s.clipboard)) - switch s.op { - case SetOperation: - str := s.str - if s.limit > 0 && len(str) > s.limit { - return "" - } - b64 := base64.StdEncoding.EncodeToString([]byte(str)) - switch s.mode { - case ScreenMode: - // Screen doesn't support OSC52 but will pass the contents of a DCS - // sequence to the outer terminal unchanged. - // - // Here, we split the encoded string into 76 bytes chunks and then - // join the chunks with sequences. Finally, - // wrap the whole thing in - // . - // s := strings.SplitN(b64, "", 76) - s := make([]string, 0, len(b64)/76+1) - for i := 0; i < len(b64); i += 76 { - end := i + 76 - if end > len(b64) { - end = len(b64) - } - s = append(s, b64[i:end]) - } - seq.WriteString(strings.Join(s, "\x1b\\\x1bP")) - default: - seq.WriteString(b64) - } - case QueryOperation: - // OSC52 queries the clipboard using "?" - seq.WriteString("?") - case ClearOperation: - // OSC52 clears the clipboard if the data is neither a base64 string nor "?" - // we're using "!" as a default - seq.WriteString("!") - } - // actual OSC52 sequence end - seq.WriteString("\x07") - // mode escape end - seq.WriteString(s.seqEnd()) - return seq.String() -} - -// WriteTo writes the OSC52 sequence to the writer. -func (s Sequence) WriteTo(out io.Writer) (int64, error) { - n, err := out.Write([]byte(s.String())) - return int64(n), err -} - -// Mode sets the mode for the OSC52 sequence. -func (s Sequence) Mode(m Mode) Sequence { - s.mode = m - return s -} - -// Tmux sets the mode to TmuxMode. -// Used to escape the OSC52 sequence for `tmux`. -// -// Note: this is not needed if tmux clipboard is set to `set-clipboard on`. If -// TmuxMode is used, tmux must have `allow-passthrough on` set. -// -// This is a syntactic sugar for s.Mode(TmuxMode). -func (s Sequence) Tmux() Sequence { - return s.Mode(TmuxMode) -} - -// Screen sets the mode to ScreenMode. -// Used to escape the OSC52 sequence for `screen`. -// -// This is a syntactic sugar for s.Mode(ScreenMode). -func (s Sequence) Screen() Sequence { - return s.Mode(ScreenMode) -} - -// Clipboard sets the clipboard buffer for the OSC52 sequence. -func (s Sequence) Clipboard(c Clipboard) Sequence { - s.clipboard = c - return s -} - -// Primary sets the clipboard buffer to PrimaryClipboard. -// This is the X11 primary clipboard. -// -// This is a syntactic sugar for s.Clipboard(PrimaryClipboard). -func (s Sequence) Primary() Sequence { - return s.Clipboard(PrimaryClipboard) -} - -// Limit sets the limit for the OSC52 sequence. -// The default limit is 0 (no limit). -// -// Strings longer than the limit get ignored. Settting the limit to 0 or a -// negative value disables the limit. Each terminal defines its own escapse -// sequence limit. -func (s Sequence) Limit(l int) Sequence { - if l < 0 { - s.limit = 0 - } else { - s.limit = l - } - return s -} - -// Operation sets the operation for the OSC52 sequence. -// The default operation is SetOperation. -func (s Sequence) Operation(o Operation) Sequence { - s.op = o - return s -} - -// Clear sets the operation to ClearOperation. -// This clears the clipboard. -// -// This is a syntactic sugar for s.Operation(ClearOperation). -func (s Sequence) Clear() Sequence { - return s.Operation(ClearOperation) -} - -// Query sets the operation to QueryOperation. -// This queries the clipboard contents. -// -// This is a syntactic sugar for s.Operation(QueryOperation). -func (s Sequence) Query() Sequence { - return s.Operation(QueryOperation) -} - -// SetString sets the string for the OSC52 sequence. Strings are joined with a -// space character. -func (s Sequence) SetString(strs ...string) Sequence { - s.str = strings.Join(strs, " ") - return s -} - -// New creates a new OSC52 sequence with the given string(s). Strings are -// joined with a space character. -func New(strs ...string) Sequence { - s := Sequence{ - str: strings.Join(strs, " "), - limit: 0, - mode: DefaultMode, - clipboard: SystemClipboard, - op: SetOperation, - } - return s -} - -// Query creates a new OSC52 sequence with the QueryOperation. -// This returns a new OSC52 sequence to query the clipboard contents. -// -// This is a syntactic sugar for New().Query(). -func Query() Sequence { - return New().Query() -} - -// Clear creates a new OSC52 sequence with the ClearOperation. -// This returns a new OSC52 sequence to clear the clipboard. -// -// This is a syntactic sugar for New().Clear(). -func Clear() Sequence { - return New().Clear() -} - -func (s Sequence) seqStart() string { - switch s.mode { - case TmuxMode: - // Write the start of a tmux escape sequence. - return "\x1bPtmux;\x1b" - case ScreenMode: - // Write the start of a DCS sequence. - return "\x1bP" - default: - return "" - } -} - -func (s Sequence) seqEnd() string { - switch s.mode { - case TmuxMode: - // Terminate the tmux escape sequence. - return "\x1b\\" - case ScreenMode: - // Write the end of a DCS sequence. - return "\x1b\x5c" - default: - return "" - } -} diff --git a/vendor/github.com/beorn7/perks/LICENSE b/vendor/github.com/beorn7/perks/LICENSE deleted file mode 100644 index 339177be66..0000000000 --- a/vendor/github.com/beorn7/perks/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (C) 2013 Blake Mizerany - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/beorn7/perks/quantile/exampledata.txt b/vendor/github.com/beorn7/perks/quantile/exampledata.txt deleted file mode 100644 index 1602287d7c..0000000000 --- a/vendor/github.com/beorn7/perks/quantile/exampledata.txt +++ /dev/null @@ -1,2388 +0,0 @@ -8 -5 -26 -12 -5 -235 -13 -6 -28 -30 -3 -3 -3 -3 -5 -2 -33 -7 -2 -4 -7 -12 -14 -5 -8 -3 -10 -4 -5 -3 -6 -6 -209 -20 -3 -10 -14 -3 -4 -6 -8 -5 -11 -7 -3 -2 -3 -3 -212 -5 -222 -4 -10 -10 -5 -6 -3 -8 -3 -10 -254 -220 -2 -3 -5 -24 -5 -4 -222 -7 -3 -3 -223 -8 -15 -12 -14 -14 -3 -2 -2 -3 -13 -3 -11 -4 -4 -6 -5 -7 -13 -5 -3 -5 -2 -5 -3 -5 -2 -7 -15 -17 -14 -3 -6 -6 -3 -17 -5 -4 -7 -6 -4 -4 -8 -6 -8 -3 -9 -3 -6 -3 -4 -5 -3 -3 -660 -4 -6 -10 -3 -6 -3 -2 -5 -13 -2 -4 -4 -10 -4 -8 -4 -3 -7 -9 -9 -3 -10 -37 -3 -13 -4 -12 -3 -6 -10 -8 -5 -21 -2 -3 -8 -3 -2 -3 -3 -4 -12 -2 -4 -8 -8 -4 -3 -2 -20 -1 -6 -32 -2 -11 -6 -18 -3 -8 -11 -3 -212 -3 -4 -2 -6 -7 -12 -11 -3 -2 -16 -10 -6 -4 -6 -3 -2 -7 -3 -2 -2 -2 -2 -5 -6 -4 -3 -10 -3 -4 -6 -5 -3 -4 -4 -5 -6 -4 -3 -4 -4 -5 -7 -5 -5 -3 -2 -7 -2 -4 -12 -4 -5 -6 -2 -4 -4 -8 -4 -15 -13 -7 -16 -5 -3 -23 -5 -5 -7 -3 -2 -9 -8 -7 -5 -8 -11 -4 -10 -76 -4 -47 -4 -3 -2 -7 -4 -2 -3 -37 -10 -4 -2 -20 -5 -4 -4 -10 -10 -4 -3 -7 -23 -240 -7 -13 -5 -5 -3 -3 -2 -5 -4 -2 -8 -7 -19 -2 -23 -8 -7 -2 -5 -3 -8 -3 -8 -13 -5 -5 -5 -2 -3 -23 -4 -9 -8 -4 -3 -3 -5 -220 -2 -3 -4 -6 -14 -3 -53 -6 -2 -5 -18 -6 -3 -219 -6 -5 -2 -5 -3 -6 -5 -15 -4 -3 -17 -3 -2 -4 -7 -2 -3 -3 -4 -4 -3 -2 -664 -6 -3 -23 -5 -5 -16 -5 -8 -2 -4 -2 -24 -12 -3 -2 -3 -5 -8 -3 -5 -4 -3 -14 -3 -5 -8 -2 -3 -7 -9 -4 -2 -3 -6 -8 -4 -3 -4 -6 -5 -3 -3 -6 -3 -19 -4 -4 -6 -3 -6 -3 -5 -22 -5 -4 -4 -3 -8 -11 -4 -9 -7 -6 -13 -4 -4 -4 -6 -17 -9 -3 -3 -3 -4 -3 -221 -5 -11 -3 -4 -2 -12 -6 -3 -5 -7 -5 -7 -4 -9 -7 -14 -37 -19 -217 -16 -3 -5 -2 -2 -7 -19 -7 -6 -7 -4 -24 -5 -11 -4 -7 -7 -9 -13 -3 -4 -3 -6 -28 -4 -4 -5 -5 -2 -5 -6 -4 -4 -6 -10 -5 -4 -3 -2 -3 -3 -6 -5 -5 -4 -3 -2 -3 -7 -4 -6 -18 -16 -8 -16 -4 -5 -8 -6 -9 -13 -1545 -6 -215 -6 -5 -6 -3 -45 -31 -5 -2 -2 -4 -3 -3 -2 -5 -4 -3 -5 -7 -7 -4 -5 -8 -5 -4 -749 -2 -31 -9 -11 -2 -11 -5 -4 -4 -7 -9 -11 -4 -5 -4 -7 -3 -4 -6 -2 -15 -3 -4 -3 -4 -3 -5 -2 -13 -5 -5 -3 -3 -23 -4 -4 -5 -7 -4 -13 -2 -4 -3 -4 -2 -6 -2 -7 -3 -5 -5 -3 -29 -5 -4 -4 -3 -10 -2 -3 -79 -16 -6 -6 -7 -7 -3 -5 -5 -7 -4 -3 -7 -9 -5 -6 -5 -9 -6 -3 -6 -4 -17 -2 -10 -9 -3 -6 -2 -3 -21 -22 -5 -11 -4 -2 -17 -2 -224 -2 -14 -3 -4 -4 -2 -4 -4 -4 -4 -5 -3 -4 -4 -10 -2 -6 -3 -3 -5 -7 -2 -7 -5 -6 -3 -218 -2 -2 -5 -2 -6 -3 -5 -222 -14 -6 -33 -3 -2 -5 -3 -3 -3 -9 -5 -3 -3 -2 -7 -4 -3 -4 -3 -5 -6 -5 -26 -4 -13 -9 -7 -3 -221 -3 -3 -4 -4 -4 -4 -2 -18 -5 -3 -7 -9 -6 -8 -3 -10 -3 -11 -9 -5 -4 -17 -5 -5 -6 -6 -3 -2 -4 -12 -17 -6 -7 -218 -4 -2 -4 -10 -3 -5 -15 -3 -9 -4 -3 -3 -6 -29 -3 -3 -4 -5 -5 -3 -8 -5 -6 -6 -7 -5 -3 -5 -3 -29 -2 -31 -5 -15 -24 -16 -5 -207 -4 -3 -3 -2 -15 -4 -4 -13 -5 -5 -4 -6 -10 -2 -7 -8 -4 -6 -20 -5 -3 -4 -3 -12 -12 -5 -17 -7 -3 -3 -3 -6 -10 -3 -5 -25 -80 -4 -9 -3 -2 -11 -3 -3 -2 -3 -8 -7 -5 -5 -19 -5 -3 -3 -12 -11 -2 -6 -5 -5 -5 -3 -3 -3 -4 -209 -14 -3 -2 -5 -19 -4 -4 -3 -4 -14 -5 -6 -4 -13 -9 -7 -4 -7 -10 -2 -9 -5 -7 -2 -8 -4 -6 -5 -5 -222 -8 -7 -12 -5 -216 -3 -4 -4 -6 -3 -14 -8 -7 -13 -4 -3 -3 -3 -3 -17 -5 -4 -3 -33 -6 -6 -33 -7 -5 -3 -8 -7 -5 -2 -9 -4 -2 -233 -24 -7 -4 -8 -10 -3 -4 -15 -2 -16 -3 -3 -13 -12 -7 -5 -4 -207 -4 -2 -4 -27 -15 -2 -5 -2 -25 -6 -5 -5 -6 -13 -6 -18 -6 -4 -12 -225 -10 -7 -5 -2 -2 -11 -4 -14 -21 -8 -10 -3 -5 -4 -232 -2 -5 -5 -3 -7 -17 -11 -6 -6 -23 -4 -6 -3 -5 -4 -2 -17 -3 -6 -5 -8 -3 -2 -2 -14 -9 -4 -4 -2 -5 -5 -3 -7 -6 -12 -6 -10 -3 -6 -2 -2 -19 -5 -4 -4 -9 -2 -4 -13 -3 -5 -6 -3 -6 -5 -4 -9 -6 -3 -5 -7 -3 -6 -6 -4 -3 -10 -6 -3 -221 -3 -5 -3 -6 -4 -8 -5 -3 -6 -4 -4 -2 -54 -5 -6 -11 -3 -3 -4 -4 -4 -3 -7 -3 -11 -11 -7 -10 -6 -13 -223 -213 -15 -231 -7 -3 -7 -228 -2 -3 -4 -4 -5 -6 -7 -4 -13 -3 -4 -5 -3 -6 -4 -6 -7 -2 -4 -3 -4 -3 -3 -6 -3 -7 -3 -5 -18 -5 -6 -8 -10 -3 -3 -3 -2 -4 -2 -4 -4 -5 -6 -6 -4 -10 -13 -3 -12 -5 -12 -16 -8 -4 -19 -11 -2 -4 -5 -6 -8 -5 -6 -4 -18 -10 -4 -2 -216 -6 -6 -6 -2 -4 -12 -8 -3 -11 -5 -6 -14 -5 -3 -13 -4 -5 -4 -5 -3 -28 -6 -3 -7 -219 -3 -9 -7 -3 -10 -6 -3 -4 -19 -5 -7 -11 -6 -15 -19 -4 -13 -11 -3 -7 -5 -10 -2 -8 -11 -2 -6 -4 -6 -24 -6 -3 -3 -3 -3 -6 -18 -4 -11 -4 -2 -5 -10 -8 -3 -9 -5 -3 -4 -5 -6 -2 -5 -7 -4 -4 -14 -6 -4 -4 -5 -5 -7 -2 -4 -3 -7 -3 -3 -6 -4 -5 -4 -4 -4 -3 -3 -3 -3 -8 -14 -2 -3 -5 -3 -2 -4 -5 -3 -7 -3 -3 -18 -3 -4 -4 -5 -7 -3 -3 -3 -13 -5 -4 -8 -211 -5 -5 -3 -5 -2 -5 -4 -2 -655 -6 -3 -5 -11 -2 -5 -3 -12 -9 -15 -11 -5 -12 -217 -2 -6 -17 -3 -3 -207 -5 -5 -4 -5 -9 -3 -2 -8 -5 -4 -3 -2 -5 -12 -4 -14 -5 -4 -2 -13 -5 -8 -4 -225 -4 -3 -4 -5 -4 -3 -3 -6 -23 -9 -2 -6 -7 -233 -4 -4 -6 -18 -3 -4 -6 -3 -4 -4 -2 -3 -7 -4 -13 -227 -4 -3 -5 -4 -2 -12 -9 -17 -3 -7 -14 -6 -4 -5 -21 -4 -8 -9 -2 -9 -25 -16 -3 -6 -4 -7 -8 -5 -2 -3 -5 -4 -3 -3 -5 -3 -3 -3 -2 -3 -19 -2 -4 -3 -4 -2 -3 -4 -4 -2 -4 -3 -3 -3 -2 -6 -3 -17 -5 -6 -4 -3 -13 -5 -3 -3 -3 -4 -9 -4 -2 -14 -12 -4 -5 -24 -4 -3 -37 -12 -11 -21 -3 -4 -3 -13 -4 -2 -3 -15 -4 -11 -4 -4 -3 -8 -3 -4 -4 -12 -8 -5 -3 -3 -4 -2 -220 -3 -5 -223 -3 -3 -3 -10 -3 -15 -4 -241 -9 -7 -3 -6 -6 -23 -4 -13 -7 -3 -4 -7 -4 -9 -3 -3 -4 -10 -5 -5 -1 -5 -24 -2 -4 -5 -5 -6 -14 -3 -8 -2 -3 -5 -13 -13 -3 -5 -2 -3 -15 -3 -4 -2 -10 -4 -4 -4 -5 -5 -3 -5 -3 -4 -7 -4 -27 -3 -6 -4 -15 -3 -5 -6 -6 -5 -4 -8 -3 -9 -2 -6 -3 -4 -3 -7 -4 -18 -3 -11 -3 -3 -8 -9 -7 -24 -3 -219 -7 -10 -4 -5 -9 -12 -2 -5 -4 -4 -4 -3 -3 -19 -5 -8 -16 -8 -6 -22 -3 -23 -3 -242 -9 -4 -3 -3 -5 -7 -3 -3 -5 -8 -3 -7 -5 -14 -8 -10 -3 -4 -3 -7 -4 -6 -7 -4 -10 -4 -3 -11 -3 -7 -10 -3 -13 -6 -8 -12 -10 -5 -7 -9 -3 -4 -7 -7 -10 -8 -30 -9 -19 -4 -3 -19 -15 -4 -13 -3 -215 -223 -4 -7 -4 -8 -17 -16 -3 -7 -6 -5 -5 -4 -12 -3 -7 -4 -4 -13 -4 -5 -2 -5 -6 -5 -6 -6 -7 -10 -18 -23 -9 -3 -3 -6 -5 -2 -4 -2 -7 -3 -3 -2 -5 -5 -14 -10 -224 -6 -3 -4 -3 -7 -5 -9 -3 -6 -4 -2 -5 -11 -4 -3 -3 -2 -8 -4 -7 -4 -10 -7 -3 -3 -18 -18 -17 -3 -3 -3 -4 -5 -3 -3 -4 -12 -7 -3 -11 -13 -5 -4 -7 -13 -5 -4 -11 -3 -12 -3 -6 -4 -4 -21 -4 -6 -9 -5 -3 -10 -8 -4 -6 -4 -4 -6 -5 -4 -8 -6 -4 -6 -4 -4 -5 -9 -6 -3 -4 -2 -9 -3 -18 -2 -4 -3 -13 -3 -6 -6 -8 -7 -9 -3 -2 -16 -3 -4 -6 -3 -2 -33 -22 -14 -4 -9 -12 -4 -5 -6 -3 -23 -9 -4 -3 -5 -5 -3 -4 -5 -3 -5 -3 -10 -4 -5 -5 -8 -4 -4 -6 -8 -5 -4 -3 -4 -6 -3 -3 -3 -5 -9 -12 -6 -5 -9 -3 -5 -3 -2 -2 -2 -18 -3 -2 -21 -2 -5 -4 -6 -4 -5 -10 -3 -9 -3 -2 -10 -7 -3 -6 -6 -4 -4 -8 -12 -7 -3 -7 -3 -3 -9 -3 -4 -5 -4 -4 -5 -5 -10 -15 -4 -4 -14 -6 -227 -3 -14 -5 -216 -22 -5 -4 -2 -2 -6 -3 -4 -2 -9 -9 -4 -3 -28 -13 -11 -4 -5 -3 -3 -2 -3 -3 -5 -3 -4 -3 -5 -23 -26 -3 -4 -5 -6 -4 -6 -3 -5 -5 -3 -4 -3 -2 -2 -2 -7 -14 -3 -6 -7 -17 -2 -2 -15 -14 -16 -4 -6 -7 -13 -6 -4 -5 -6 -16 -3 -3 -28 -3 -6 -15 -3 -9 -2 -4 -6 -3 -3 -22 -4 -12 -6 -7 -2 -5 -4 -10 -3 -16 -6 -9 -2 -5 -12 -7 -5 -5 -5 -5 -2 -11 -9 -17 -4 -3 -11 -7 -3 -5 -15 -4 -3 -4 -211 -8 -7 -5 -4 -7 -6 -7 -6 -3 -6 -5 -6 -5 -3 -4 -4 -26 -4 -6 -10 -4 -4 -3 -2 -3 -3 -4 -5 -9 -3 -9 -4 -4 -5 -5 -8 -2 -4 -2 -3 -8 -4 -11 -19 -5 -8 -6 -3 -5 -6 -12 -3 -2 -4 -16 -12 -3 -4 -4 -8 -6 -5 -6 -6 -219 -8 -222 -6 -16 -3 -13 -19 -5 -4 -3 -11 -6 -10 -4 -7 -7 -12 -5 -3 -3 -5 -6 -10 -3 -8 -2 -5 -4 -7 -2 -4 -4 -2 -12 -9 -6 -4 -2 -40 -2 -4 -10 -4 -223 -4 -2 -20 -6 -7 -24 -5 -4 -5 -2 -20 -16 -6 -5 -13 -2 -3 -3 -19 -3 -2 -4 -5 -6 -7 -11 -12 -5 -6 -7 -7 -3 -5 -3 -5 -3 -14 -3 -4 -4 -2 -11 -1 -7 -3 -9 -6 -11 -12 -5 -8 -6 -221 -4 -2 -12 -4 -3 -15 -4 -5 -226 -7 -218 -7 -5 -4 -5 -18 -4 -5 -9 -4 -4 -2 -9 -18 -18 -9 -5 -6 -6 -3 -3 -7 -3 -5 -4 -4 -4 -12 -3 -6 -31 -5 -4 -7 -3 -6 -5 -6 -5 -11 -2 -2 -11 -11 -6 -7 -5 -8 -7 -10 -5 -23 -7 -4 -3 -5 -34 -2 -5 -23 -7 -3 -6 -8 -4 -4 -4 -2 -5 -3 -8 -5 -4 -8 -25 -2 -3 -17 -8 -3 -4 -8 -7 -3 -15 -6 -5 -7 -21 -9 -5 -6 -6 -5 -3 -2 -3 -10 -3 -6 -3 -14 -7 -4 -4 -8 -7 -8 -2 -6 -12 -4 -213 -6 -5 -21 -8 -2 -5 -23 -3 -11 -2 -3 -6 -25 -2 -3 -6 -7 -6 -6 -4 -4 -6 -3 -17 -9 -7 -6 -4 -3 -10 -7 -2 -3 -3 -3 -11 -8 -3 -7 -6 -4 -14 -36 -3 -4 -3 -3 -22 -13 -21 -4 -2 -7 -4 -4 -17 -15 -3 -7 -11 -2 -4 -7 -6 -209 -6 -3 -2 -2 -24 -4 -9 -4 -3 -3 -3 -29 -2 -2 -4 -3 -3 -5 -4 -6 -3 -3 -2 -4 diff --git a/vendor/github.com/beorn7/perks/quantile/stream.go b/vendor/github.com/beorn7/perks/quantile/stream.go deleted file mode 100644 index d7d14f8eb6..0000000000 --- a/vendor/github.com/beorn7/perks/quantile/stream.go +++ /dev/null @@ -1,316 +0,0 @@ -// Package quantile computes approximate quantiles over an unbounded data -// stream within low memory and CPU bounds. -// -// A small amount of accuracy is traded to achieve the above properties. -// -// Multiple streams can be merged before calling Query to generate a single set -// of results. This is meaningful when the streams represent the same type of -// data. See Merge and Samples. -// -// For more detailed information about the algorithm used, see: -// -// Effective Computation of Biased Quantiles over Data Streams -// -// http://www.cs.rutgers.edu/~muthu/bquant.pdf -package quantile - -import ( - "math" - "sort" -) - -// Sample holds an observed value and meta information for compression. JSON -// tags have been added for convenience. -type Sample struct { - Value float64 `json:",string"` - Width float64 `json:",string"` - Delta float64 `json:",string"` -} - -// Samples represents a slice of samples. It implements sort.Interface. -type Samples []Sample - -func (a Samples) Len() int { return len(a) } -func (a Samples) Less(i, j int) bool { return a[i].Value < a[j].Value } -func (a Samples) Swap(i, j int) { a[i], a[j] = a[j], a[i] } - -type invariant func(s *stream, r float64) float64 - -// NewLowBiased returns an initialized Stream for low-biased quantiles -// (e.g. 0.01, 0.1, 0.5) where the needed quantiles are not known a priori, but -// error guarantees can still be given even for the lower ranks of the data -// distribution. -// -// The provided epsilon is a relative error, i.e. the true quantile of a value -// returned by a query is guaranteed to be within (1±Epsilon)*Quantile. -// -// See http://www.cs.rutgers.edu/~muthu/bquant.pdf for time, space, and error -// properties. -func NewLowBiased(epsilon float64) *Stream { - ƒ := func(s *stream, r float64) float64 { - return 2 * epsilon * r - } - return newStream(ƒ) -} - -// NewHighBiased returns an initialized Stream for high-biased quantiles -// (e.g. 0.01, 0.1, 0.5) where the needed quantiles are not known a priori, but -// error guarantees can still be given even for the higher ranks of the data -// distribution. -// -// The provided epsilon is a relative error, i.e. the true quantile of a value -// returned by a query is guaranteed to be within 1-(1±Epsilon)*(1-Quantile). -// -// See http://www.cs.rutgers.edu/~muthu/bquant.pdf for time, space, and error -// properties. -func NewHighBiased(epsilon float64) *Stream { - ƒ := func(s *stream, r float64) float64 { - return 2 * epsilon * (s.n - r) - } - return newStream(ƒ) -} - -// NewTargeted returns an initialized Stream concerned with a particular set of -// quantile values that are supplied a priori. Knowing these a priori reduces -// space and computation time. The targets map maps the desired quantiles to -// their absolute errors, i.e. the true quantile of a value returned by a query -// is guaranteed to be within (Quantile±Epsilon). -// -// See http://www.cs.rutgers.edu/~muthu/bquant.pdf for time, space, and error properties. -func NewTargeted(targetMap map[float64]float64) *Stream { - // Convert map to slice to avoid slow iterations on a map. - // ƒ is called on the hot path, so converting the map to a slice - // beforehand results in significant CPU savings. - targets := targetMapToSlice(targetMap) - - ƒ := func(s *stream, r float64) float64 { - var m = math.MaxFloat64 - var f float64 - for _, t := range targets { - if t.quantile*s.n <= r { - f = (2 * t.epsilon * r) / t.quantile - } else { - f = (2 * t.epsilon * (s.n - r)) / (1 - t.quantile) - } - if f < m { - m = f - } - } - return m - } - return newStream(ƒ) -} - -type target struct { - quantile float64 - epsilon float64 -} - -func targetMapToSlice(targetMap map[float64]float64) []target { - targets := make([]target, 0, len(targetMap)) - - for quantile, epsilon := range targetMap { - t := target{ - quantile: quantile, - epsilon: epsilon, - } - targets = append(targets, t) - } - - return targets -} - -// Stream computes quantiles for a stream of float64s. It is not thread-safe by -// design. Take care when using across multiple goroutines. -type Stream struct { - *stream - b Samples - sorted bool -} - -func newStream(ƒ invariant) *Stream { - x := &stream{ƒ: ƒ} - return &Stream{x, make(Samples, 0, 500), true} -} - -// Insert inserts v into the stream. -func (s *Stream) Insert(v float64) { - s.insert(Sample{Value: v, Width: 1}) -} - -func (s *Stream) insert(sample Sample) { - s.b = append(s.b, sample) - s.sorted = false - if len(s.b) == cap(s.b) { - s.flush() - } -} - -// Query returns the computed qth percentiles value. If s was created with -// NewTargeted, and q is not in the set of quantiles provided a priori, Query -// will return an unspecified result. -func (s *Stream) Query(q float64) float64 { - if !s.flushed() { - // Fast path when there hasn't been enough data for a flush; - // this also yields better accuracy for small sets of data. - l := len(s.b) - if l == 0 { - return 0 - } - i := int(math.Ceil(float64(l) * q)) - if i > 0 { - i -= 1 - } - s.maybeSort() - return s.b[i].Value - } - s.flush() - return s.stream.query(q) -} - -// Merge merges samples into the underlying streams samples. This is handy when -// merging multiple streams from separate threads, database shards, etc. -// -// ATTENTION: This method is broken and does not yield correct results. The -// underlying algorithm is not capable of merging streams correctly. -func (s *Stream) Merge(samples Samples) { - sort.Sort(samples) - s.stream.merge(samples) -} - -// Reset reinitializes and clears the list reusing the samples buffer memory. -func (s *Stream) Reset() { - s.stream.reset() - s.b = s.b[:0] -} - -// Samples returns stream samples held by s. -func (s *Stream) Samples() Samples { - if !s.flushed() { - return s.b - } - s.flush() - return s.stream.samples() -} - -// Count returns the total number of samples observed in the stream -// since initialization. -func (s *Stream) Count() int { - return len(s.b) + s.stream.count() -} - -func (s *Stream) flush() { - s.maybeSort() - s.stream.merge(s.b) - s.b = s.b[:0] -} - -func (s *Stream) maybeSort() { - if !s.sorted { - s.sorted = true - sort.Sort(s.b) - } -} - -func (s *Stream) flushed() bool { - return len(s.stream.l) > 0 -} - -type stream struct { - n float64 - l []Sample - ƒ invariant -} - -func (s *stream) reset() { - s.l = s.l[:0] - s.n = 0 -} - -func (s *stream) insert(v float64) { - s.merge(Samples{{v, 1, 0}}) -} - -func (s *stream) merge(samples Samples) { - // TODO(beorn7): This tries to merge not only individual samples, but - // whole summaries. The paper doesn't mention merging summaries at - // all. Unittests show that the merging is inaccurate. Find out how to - // do merges properly. - var r float64 - i := 0 - for _, sample := range samples { - for ; i < len(s.l); i++ { - c := s.l[i] - if c.Value > sample.Value { - // Insert at position i. - s.l = append(s.l, Sample{}) - copy(s.l[i+1:], s.l[i:]) - s.l[i] = Sample{ - sample.Value, - sample.Width, - math.Max(sample.Delta, math.Floor(s.ƒ(s, r))-1), - // TODO(beorn7): How to calculate delta correctly? - } - i++ - goto inserted - } - r += c.Width - } - s.l = append(s.l, Sample{sample.Value, sample.Width, 0}) - i++ - inserted: - s.n += sample.Width - r += sample.Width - } - s.compress() -} - -func (s *stream) count() int { - return int(s.n) -} - -func (s *stream) query(q float64) float64 { - t := math.Ceil(q * s.n) - t += math.Ceil(s.ƒ(s, t) / 2) - p := s.l[0] - var r float64 - for _, c := range s.l[1:] { - r += p.Width - if r+c.Width+c.Delta > t { - return p.Value - } - p = c - } - return p.Value -} - -func (s *stream) compress() { - if len(s.l) < 2 { - return - } - x := s.l[len(s.l)-1] - xi := len(s.l) - 1 - r := s.n - 1 - x.Width - - for i := len(s.l) - 2; i >= 0; i-- { - c := s.l[i] - if c.Width+x.Width+x.Delta <= s.ƒ(s, r) { - x.Width += c.Width - s.l[xi] = x - // Remove element at i. - copy(s.l[i:], s.l[i+1:]) - s.l = s.l[:len(s.l)-1] - xi -= 1 - } else { - x = c - xi = i - } - r -= c.Width - } -} - -func (s *stream) samples() Samples { - samples := make(Samples, len(s.l)) - copy(samples, s.l) - return samples -} diff --git a/vendor/github.com/bkielbasa/cyclop/LICENSE b/vendor/github.com/bkielbasa/cyclop/LICENSE deleted file mode 100644 index b4a776a409..0000000000 --- a/vendor/github.com/bkielbasa/cyclop/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2020 Bartłomiej Klimczak - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/bkielbasa/cyclop/pkg/analyzer/analyzer.go b/vendor/github.com/bkielbasa/cyclop/pkg/analyzer/analyzer.go deleted file mode 100644 index 1972379df4..0000000000 --- a/vendor/github.com/bkielbasa/cyclop/pkg/analyzer/analyzer.go +++ /dev/null @@ -1,111 +0,0 @@ -package analyzer - -import ( - "flag" - "go/ast" - "go/token" - "strings" - - "golang.org/x/tools/go/analysis" -) - -//nolint:gochecknoglobals -var flagSet flag.FlagSet - -//nolint:gochecknoglobals -var ( - maxComplexity int - packageAverage float64 - skipTests bool -) - -const ( - defaultMaxComplexity = 10 -) - -//nolint:gochecknoinits -func init() { - flagSet.IntVar(&maxComplexity, "maxComplexity", defaultMaxComplexity, "max complexity the function can have") - flagSet.Float64Var(&packageAverage, "packageAverage", 0, "max average complexity in package") - flagSet.BoolVar(&skipTests, "skipTests", false, "should the linter execute on test files as well") -} - -func NewAnalyzer() *analysis.Analyzer { - return &analysis.Analyzer{ - Name: "cyclop", - Doc: "checks function and package cyclomatic complexity", - Run: run, - Flags: flagSet, - } -} - -func run(pass *analysis.Pass) (interface{}, error) { - var sum, count float64 - var pkgName string - var pkgPos token.Pos - - for _, file := range pass.Files { - ast.Inspect(file, func(node ast.Node) bool { - funcDecl, ok := node.(*ast.FuncDecl) - if !ok { - if node == nil { - return true - } - if file, ok := node.(*ast.File); ok { - pkgName = file.Name.Name - pkgPos = node.Pos() - } - // we check function by function - return true - } - - if skipTests && testFunc(funcDecl) { - return true - } - - count++ - comp := complexity(funcDecl) - sum += float64(comp) - if comp > maxComplexity { - pass.Reportf(node.Pos(), "calculated cyclomatic complexity for function %s is %d, max is %d", funcDecl.Name.Name, comp, maxComplexity) - } - - return true - }) - } - - if packageAverage > 0 { - avg := sum / count - if avg > packageAverage { - pass.Reportf(pkgPos, "the average complexity for the package %s is %f, max is %f", pkgName, avg, packageAverage) - } - } - - return nil, nil -} - -func testFunc(f *ast.FuncDecl) bool { - return strings.HasPrefix(f.Name.Name, "Test") -} - -func complexity(fn *ast.FuncDecl) int { - v := complexityVisitor{} - ast.Walk(&v, fn) - return v.Complexity -} - -type complexityVisitor struct { - Complexity int -} - -func (v *complexityVisitor) Visit(n ast.Node) ast.Visitor { - switch n := n.(type) { - case *ast.FuncDecl, *ast.IfStmt, *ast.ForStmt, *ast.RangeStmt, *ast.CaseClause, *ast.CommClause: - v.Complexity++ - case *ast.BinaryExpr: - if n.Op == token.LAND || n.Op == token.LOR { - v.Complexity++ - } - } - return v -} diff --git a/vendor/github.com/blizzy78/varnamelen/.editorconfig b/vendor/github.com/blizzy78/varnamelen/.editorconfig deleted file mode 100644 index 7b64615455..0000000000 --- a/vendor/github.com/blizzy78/varnamelen/.editorconfig +++ /dev/null @@ -1,13 +0,0 @@ -root = true - -[**] -charset = utf-8 -end_of_line = lf -insert_final_newline = true -indent_style = tab -indent_size = 4 -trim_trailing_whitespace = true - -[**/*.yml] -indent_style = space -indent_size = 2 diff --git a/vendor/github.com/blizzy78/varnamelen/.gitignore b/vendor/github.com/blizzy78/varnamelen/.gitignore deleted file mode 100644 index 1a4a71669f..0000000000 --- a/vendor/github.com/blizzy78/varnamelen/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/cmd/__debug_bin diff --git a/vendor/github.com/blizzy78/varnamelen/.golangci.yml b/vendor/github.com/blizzy78/varnamelen/.golangci.yml deleted file mode 100644 index 566572363c..0000000000 --- a/vendor/github.com/blizzy78/varnamelen/.golangci.yml +++ /dev/null @@ -1,70 +0,0 @@ -# https://github.com/golangci/golangci-lint/issues/456#issuecomment-617470264 -issues: - exclude-use-default: false - exclude: - # errcheck: Almost all programs ignore errors on these functions and in most cases it's ok - - Error return value of .((os\.)?std(out|err)\..*|.*print(f|ln)?|os\.(Un)?Setenv). is not checked - # golint: False positive when tests are defined in package 'test' - - func name will be used as test\.Test.* by other packages, and that stutters; consider calling this - # gosec: Duplicated errcheck checks - - G104 - # gosec: Too many issues in popular repos - - (Expect directory permissions to be 0750 or less|Expect file permissions to be 0600 or less) - # gosec: False positive is triggered by 'src, err := ioutil.ReadFile(filename)' - - Potential file inclusion via variable - -linters: - enable: - - asciicheck - - bodyclose - - cyclop - - durationcheck - - errname - - errorlint - - exportloopref - - forcetypeassert - - gocognit - - gocritic - - goerr113 - - gofmt - - goprintffuncname - - gosec - - ifshort - - nakedret - - nestif - - nilerr - - noctx - - nolintlint - - prealloc - - predeclared - - promlinter - - revive - - rowserrcheck - - sqlclosecheck - - stylecheck - - thelper - - tparallel - - unconvert - - unparam - - varnamelen - - wastedassign - - wrapcheck - - wsl - -linters-settings: - gocognit: - min-complexity: 15 - nakedret: - max-func-lines: 0 - nolintlint: - allow-unused: false - allow-leading-space: false - require-explanation: true - require-specific: true - unused: - go: 1.16 - varnamelen: - check-return: true - ignore-type-assert-ok: true - ignore-map-index-ok: true - ignore-chan-recv-ok: true diff --git a/vendor/github.com/blizzy78/varnamelen/LICENSE b/vendor/github.com/blizzy78/varnamelen/LICENSE deleted file mode 100644 index c45156a2c3..0000000000 --- a/vendor/github.com/blizzy78/varnamelen/LICENSE +++ /dev/null @@ -1,18 +0,0 @@ -Copyright 2021-2022 Maik Schreiber - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/blizzy78/varnamelen/README.md b/vendor/github.com/blizzy78/varnamelen/README.md deleted file mode 100644 index 02131ff298..0000000000 --- a/vendor/github.com/blizzy78/varnamelen/README.md +++ /dev/null @@ -1,155 +0,0 @@ -[![GoDoc](https://pkg.go.dev/badge/github.com/blizzy78/varnamelen)](https://pkg.go.dev/github.com/blizzy78/varnamelen) - - -varnamelen -========== - -A Go Analyzer that checks that the length of a variable's name matches its usage scope: - -Variables with short names can be hard to use if the variable is used over a longer span of lines of code. -A longer variable name may be easier to comprehend. - -The analyzer also checks method receiver names, named return values, and type parameter names. - -Arbitrary declarations such as `f *foo` can be ignored, as well as idiomatic `ok` variables. -Conventional Go parameters such as `ctx context.Context` or `t *testing.T` will always be ignored. - -**Example output** - -``` -test.go:4:2: variable name 'x' is too short for the scope of its usage (varnamelen) - x := 123 - ^ -test.go:6:2: variable name 'i' is too short for the scope of its usage (varnamelen) - i := 10 - ^ -``` - - -golangci-lint Integration -------------------------- - -varnamelen is integrated into [golangci-lint] (though it may not always be the most recent version.) - -Example configuration for golangci-lint: - -```yaml -linters-settings: - varnamelen: - # The longest distance, in source lines, that is being considered a "small scope." (defaults to 5) - # Variables used in at most this many lines will be ignored. - max-distance: 5 - # The minimum length of a variable's name that is considered "long." (defaults to 3) - # Variable names that are at least this long will be ignored. - min-name-length: 3 - # Check method receiver. (defaults to false) - check-receiver: false - # Check named return values. (defaults to false) - check-return: false - # Check type parameters. (defaults to false) - check-type-param: false - # Ignore "ok" variables that hold the bool return value of a type assertion. (defaults to false) - ignore-type-assert-ok: false - # Ignore "ok" variables that hold the bool return value of a map index. (defaults to false) - ignore-map-index-ok: false - # Ignore "ok" variables that hold the bool return value of a channel receive. (defaults to false) - ignore-chan-recv-ok: false - # Optional list of variable names that should be ignored completely. (defaults to empty list) - ignore-names: - - err - # Optional list of variable declarations that should be ignored completely. (defaults to empty list) - # Entries must be in one of the following forms (see below for examples): - # - for variables, parameters, or named return values: - # - - # - * - # - for type parameters: - # - - # - for constants: - # - const - ignore-decls: - - c echo.Context - - t testing.T - - f *foo.Bar - - e error - - i int - - const C - - T any -``` - - -Standalone Usage ----------------- - -The `cmd/` folder provides a standalone command line utility. You can build it like this: - -``` -go build -o varnamelen ./cmd/ -``` - -**Usage** - -``` -varnamelen: checks that the length of a variable's name matches its scope - -Usage: varnamelen [-flag] [package] - -A variable with a short name can be hard to use if the variable is used -over a longer span of lines of code. A longer variable name may be easier -to comprehend. - -Flags: - -V print version and exit - -all - no effect (deprecated) - -c int - display offending line with this many lines of context (default -1) - -checkReceiver - check method receiver names - -checkReturn - check named return values - -checkTypeParam - check type parameter names - -cpuprofile string - write CPU profile to this file - -debug string - debug flags, any subset of "fpstv" - -fix - apply all suggested fixes - -flags - print analyzer flags in JSON - -ignoreChanRecvOk - ignore 'ok' variables that hold the bool return value of a channel receive - -ignoreDecls value - comma-separated list of ignored variable declarations - -ignoreMapIndexOk - ignore 'ok' variables that hold the bool return value of a map index - -ignoreNames value - comma-separated list of ignored variable names - -ignoreTypeAssertOk - ignore 'ok' variables that hold the bool return value of a type assertion - -json - emit JSON output - -maxDistance int - maximum number of lines of variable usage scope considered 'short' (default 5) - -memprofile string - write memory profile to this file - -minNameLength int - minimum length of variable name considered 'long' (default 3) - -source - no effect (deprecated) - -tags string - no effect (deprecated) - -trace string - write trace log to this file - -v no effect (deprecated) -``` - - -License -------- - -This package is licensed under the MIT license. - - - -[golangci-lint]: https://github.com/golangci/golangci-lint diff --git a/vendor/github.com/blizzy78/varnamelen/doc.go b/vendor/github.com/blizzy78/varnamelen/doc.go deleted file mode 100644 index d63c71cfb7..0000000000 --- a/vendor/github.com/blizzy78/varnamelen/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package varnamelen implements an analyzer checking that the length of a variable's name -// matches its usage scope. -package varnamelen diff --git a/vendor/github.com/blizzy78/varnamelen/flags.go b/vendor/github.com/blizzy78/varnamelen/flags.go deleted file mode 100644 index ee80774f96..0000000000 --- a/vendor/github.com/blizzy78/varnamelen/flags.go +++ /dev/null @@ -1,109 +0,0 @@ -package varnamelen - -import "strings" - -// stringsValue is the value of a list-of-strings flag. -type stringsValue struct { - Values []string -} - -// declarationsValue is the value of a list-of-declarations flag. -type declarationsValue struct { - Values []declaration -} - -// Set implements Value. -func (sv *stringsValue) Set(values string) error { - if strings.TrimSpace(values) == "" { - sv.Values = nil - return nil - } - - parts := strings.Split(values, ",") - - sv.Values = make([]string, len(parts)) - - for i, part := range parts { - sv.Values[i] = strings.TrimSpace(part) - } - - return nil -} - -// String implements Value. -func (sv *stringsValue) String() string { - return strings.Join(sv.Values, ",") -} - -// contains returns true if sv contains s. -func (sv *stringsValue) contains(s string) bool { - for _, v := range sv.Values { - if v == s { - return true - } - } - - return false -} - -// Set implements Value. -func (dv *declarationsValue) Set(values string) error { - if strings.TrimSpace(values) == "" { - dv.Values = nil - return nil - } - - parts := strings.Split(values, ",") - - dv.Values = make([]declaration, len(parts)) - - for idx, part := range parts { - dv.Values[idx] = parseDeclaration(strings.TrimSpace(part)) - } - - return nil -} - -// String implements Value. -func (dv *declarationsValue) String() string { - parts := make([]string, len(dv.Values)) - - for idx, val := range dv.Values { - parts[idx] = val.name + " " + val.typ - } - - return strings.Join(parts, ",") -} - -// matchVariable returns true if vari matches any of the declarations in dv. -func (dv *declarationsValue) matchVariable(vari variable) bool { - for _, decl := range dv.Values { - if vari.match(decl) { - return true - } - } - - return false -} - -// matchParameter returns true if param matches any of the declarations in dv. -func (dv *declarationsValue) matchParameter(param parameter) bool { - for _, decl := range dv.Values { - if param.match(decl) { - return true - } - } - - return false -} - -// matchParameter returns true if param matches any of the declarations in dv. -func (dv *declarationsValue) matchTypeParameter(param typeParam) bool { - for _, decl := range dv.Values { - if param.match(decl) { - return true - } - } - - return false -} diff --git a/vendor/github.com/blizzy78/varnamelen/typeparam.go b/vendor/github.com/blizzy78/varnamelen/typeparam.go deleted file mode 100644 index a1f3de99a3..0000000000 --- a/vendor/github.com/blizzy78/varnamelen/typeparam.go +++ /dev/null @@ -1,35 +0,0 @@ -//go:build go1.18 -// +build go1.18 - -package varnamelen - -import "go/ast" - -// isTypeParam returns true if field is a type parameter of any of the given funcs. -func isTypeParam(field *ast.Field, funcs []*ast.FuncDecl, funcLits []*ast.FuncLit) bool { //nolint:gocognit // it's not that complicated - for _, f := range funcs { - if f.Type.TypeParams == nil { - continue - } - - for _, p := range f.Type.TypeParams.List { - if p == field { - return true - } - } - } - - for _, f := range funcLits { - if f.Type.TypeParams == nil { - continue - } - - for _, p := range f.Type.TypeParams.List { - if p == field { - return true - } - } - } - - return false -} diff --git a/vendor/github.com/blizzy78/varnamelen/typeparam_go1.16.go b/vendor/github.com/blizzy78/varnamelen/typeparam_go1.16.go deleted file mode 100644 index 7856651b90..0000000000 --- a/vendor/github.com/blizzy78/varnamelen/typeparam_go1.16.go +++ /dev/null @@ -1,11 +0,0 @@ -//go:build (go1.16 && !go1.18) || (go1.17 && !go1.18) -// +build go1.16,!go1.18 go1.17,!go1.18 - -package varnamelen - -import "go/ast" - -// isTypeParam returns true if field is a type parameter of any of the given funcs. -func isTypeParam(_ *ast.Field, _ []*ast.FuncDecl, _ []*ast.FuncLit) bool { - return false -} diff --git a/vendor/github.com/blizzy78/varnamelen/varnamelen.code-workspace b/vendor/github.com/blizzy78/varnamelen/varnamelen.code-workspace deleted file mode 100644 index 68c485c968..0000000000 --- a/vendor/github.com/blizzy78/varnamelen/varnamelen.code-workspace +++ /dev/null @@ -1,13 +0,0 @@ -{ - "folders": [ - { - "path": "." - } - ], - "extensions": { - "recommendations": [ - "EditorConfig.EditorConfig", - "golang.go" - ] - } -} diff --git a/vendor/github.com/blizzy78/varnamelen/varnamelen.go b/vendor/github.com/blizzy78/varnamelen/varnamelen.go deleted file mode 100644 index a5b9603114..0000000000 --- a/vendor/github.com/blizzy78/varnamelen/varnamelen.go +++ /dev/null @@ -1,891 +0,0 @@ -package varnamelen - -import ( - "go/ast" - "go/token" - "go/types" - "sort" - "strings" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/inspector" -) - -// varNameLen is an analyzer that checks that the length of a variable's name matches its usage scope. -// It will create a report for a variable's assignment if that variable has a short name, but its -// usage scope is not considered "small." -type varNameLen struct { - // maxDistance is the longest distance, in source lines, that is being considered a "small scope." - maxDistance int - - // minNameLength is the minimum length of a variable's name that is considered "long." - minNameLength int - - // ignoreNames is an optional list of variable names that should be ignored completely. - ignoreNames stringsValue - - // checkReceiver determines whether method receivers should be checked. - checkReceiver bool - - // checkReturn determines whether named return values should be checked. - checkReturn bool - - // ignoreTypeAssertOk determines whether "ok" variables that hold the bool return value of a type assertion should be ignored. - ignoreTypeAssertOk bool - - // ignoreMapIndexOk determines whether "ok" variables that hold the bool return value of a map index should be ignored. - ignoreMapIndexOk bool - - // ignoreChannelReceiveOk determines whether "ok" variables that hold the bool return value of a channel receive should be ignored. - ignoreChannelReceiveOk bool - - // ignoreDeclarations is an optional list of variable declarations that should be ignored completely. - ignoreDeclarations declarationsValue - - // checkTypeParameters determines whether type parameters should be checked. - checkTypeParameters bool -} - -// variable represents a declared variable. -type variable struct { - // name is the name of the variable. - name string - - // constant is true if the variable is actually a constant. - constant bool - - // typ is the type of the variable. - typ string - - // assign is the assign statement that declares the variable. - assign *ast.AssignStmt - - // valueSpec is the value specification that declares the variable. - valueSpec *ast.ValueSpec -} - -// parameter represents a declared function or method parameter. -type parameter struct { - // name is the name of the parameter. - name string - - // typ is the type of the parameter. - typ string - - // field is the declaration of the parameter. - field *ast.Field -} - -// typeParam represents a declared type parameter. -type typeParam struct { - // name is the name of the type parameter. - name string - - // typ is the type of the type parameter. - typ string - - // field is the field that declares the type parameter. - field *ast.Field -} - -// declaration is a variable declaration. -type declaration struct { - // name is the name of the variable. - name string - - // constant is true if the variable is actually a constant. - constant bool - - // typ is the type of the variable. Not used for constants. - typ string -} - -// importDeclaration is an import declaration. -type importDeclaration struct { - // name is the short name or alias for the imported package. This is either the package's default name, - // or the alias specified in the import statement. - // Not used if self is true. - name string - - // path is the full path to the imported package. - path string - - // self is true when this is an implicit import declaration for the current package. - self bool -} - -const ( - // defaultMaxDistance is the default value for the maximum distance between the declaration of a variable and its usage - // that is considered a "small scope." - defaultMaxDistance = 5 - - // defaultMinNameLength is the default value for the minimum length of a variable's name that is considered "long." - defaultMinNameLength = 3 -) - -// conventionalDecls is a list of conventional variable declarations. -var conventionalDecls = []declaration{ - parseDeclaration("ctx context.Context"), - - parseDeclaration("b *testing.B"), - parseDeclaration("f *testing.F"), - parseDeclaration("m *testing.M"), - parseDeclaration("pb *testing.PB"), - parseDeclaration("t *testing.T"), - parseDeclaration("tb testing.TB"), -} - -// NewAnalyzer returns a new analyzer. -func NewAnalyzer() *analysis.Analyzer { - vnl := varNameLen{ - maxDistance: defaultMaxDistance, - minNameLength: defaultMinNameLength, - ignoreNames: stringsValue{}, - ignoreDeclarations: declarationsValue{}, - } - - analyzer := analysis.Analyzer{ - Name: "varnamelen", - Doc: "checks that the length of a variable's name matches its scope\n\n" + - "A variable with a short name can be hard to use if the variable is used\n" + - "over a longer span of lines of code. A longer variable name may be easier\n" + - "to comprehend.", - - Run: func(pass *analysis.Pass) (interface{}, error) { - (&vnl).run(pass) - return nil, nil - }, - - Requires: []*analysis.Analyzer{ - inspect.Analyzer, - }, - } - - analyzer.Flags.IntVar(&vnl.maxDistance, "maxDistance", defaultMaxDistance, "maximum number of lines of variable usage scope considered 'short'") - analyzer.Flags.IntVar(&vnl.minNameLength, "minNameLength", defaultMinNameLength, "minimum length of variable name considered 'long'") - analyzer.Flags.Var(&vnl.ignoreNames, "ignoreNames", "comma-separated list of ignored variable names") - analyzer.Flags.BoolVar(&vnl.checkReceiver, "checkReceiver", false, "check method receivers") - analyzer.Flags.BoolVar(&vnl.checkReturn, "checkReturn", false, "check named return values") - analyzer.Flags.BoolVar(&vnl.ignoreTypeAssertOk, "ignoreTypeAssertOk", false, "ignore 'ok' variables that hold the bool return value of a type assertion") - analyzer.Flags.BoolVar(&vnl.ignoreMapIndexOk, "ignoreMapIndexOk", false, "ignore 'ok' variables that hold the bool return value of a map index") - analyzer.Flags.BoolVar(&vnl.ignoreChannelReceiveOk, "ignoreChanRecvOk", false, "ignore 'ok' variables that hold the bool return value of a channel receive") - analyzer.Flags.Var(&vnl.ignoreDeclarations, "ignoreDecls", "comma-separated list of ignored variable declarations") - analyzer.Flags.BoolVar(&vnl.checkTypeParameters, "checkTypeParam", false, "check type parameters") - - return &analyzer -} - -// Run applies v to a package, according to pass. -func (v *varNameLen) run(pass *analysis.Pass) { - varToDist, paramToDist, returnToDist, typeParamToDist := v.distances(pass) - - v.checkVariables(pass, varToDist) - v.checkParams(pass, paramToDist) - v.checkReturns(pass, returnToDist) - v.checkTypeParams(pass, typeParamToDist) -} - -// checkVariables applies v to variables in varToDist. -func (v *varNameLen) checkVariables(pass *analysis.Pass, varToDist map[variable]int) { //nolint:gocognit // it's not that complicated - for variable, dist := range varToDist { - if v.ignoreNames.contains(variable.name) { - continue - } - - if v.ignoreDeclarations.matchVariable(variable) { - continue - } - - if v.checkNameAndDistance(variable.name, dist) { - continue - } - - if v.checkTypeAssertOk(variable) { - continue - } - - if v.checkMapIndexOk(variable) { - continue - } - - if v.checkChannelReceiveOk(variable) { - continue - } - - if variable.isConventional() { - continue - } - - if variable.assign != nil { - pass.Reportf(variable.assign.Pos(), "%s name '%s' is too short for the scope of its usage", variable.kindName(), variable.name) - continue - } - - pass.Reportf(variable.valueSpec.Pos(), "%s name '%s' is too short for the scope of its usage", variable.kindName(), variable.name) - } -} - -// checkParams applies v to parameters in paramToDist. -func (v *varNameLen) checkParams(pass *analysis.Pass, paramToDist map[parameter]int) { - for param, dist := range paramToDist { - if v.ignoreNames.contains(param.name) { - continue - } - - if v.ignoreDeclarations.matchParameter(param) { - continue - } - - if v.checkNameAndDistance(param.name, dist) { - continue - } - - if param.isConventional() { - continue - } - - pass.Reportf(param.field.Pos(), "parameter name '%s' is too short for the scope of its usage", param.name) - } -} - -// checkReturns applies v to named return values in returnToDist. -func (v *varNameLen) checkReturns(pass *analysis.Pass, returnToDist map[parameter]int) { - for returnValue, dist := range returnToDist { - if v.ignoreNames.contains(returnValue.name) { - continue - } - - if v.ignoreDeclarations.matchParameter(returnValue) { - continue - } - - if v.checkNameAndDistance(returnValue.name, dist) { - continue - } - - pass.Reportf(returnValue.field.Pos(), "return value name '%s' is too short for the scope of its usage", returnValue.name) - } -} - -// checkTypeParams applies v to type parameters in paramToDist. -func (v *varNameLen) checkTypeParams(pass *analysis.Pass, paramToDist map[typeParam]int) { - for param, dist := range paramToDist { - if v.ignoreNames.contains(param.name) { - continue - } - - if v.ignoreDeclarations.matchTypeParameter(param) { - continue - } - - if v.checkNameAndDistance(param.name, dist) { - continue - } - - pass.Reportf(param.field.Pos(), "type parameter name '%s' is too short for the scope of its usage", param.name) - } -} - -// checkNameAndDistance returns true if name or dist are considered "short". -func (v *varNameLen) checkNameAndDistance(name string, dist int) bool { - if len(name) >= v.minNameLength { - return true - } - - if dist <= v.maxDistance { - return true - } - - return false -} - -// checkTypeAssertOk returns true if "ok" variables that hold the bool return value of a type assertion -// should be ignored, and if vari is such a variable. -func (v *varNameLen) checkTypeAssertOk(vari variable) bool { - return v.ignoreTypeAssertOk && vari.isTypeAssertOk() -} - -// checkMapIndexOk returns true if "ok" variables that hold the bool return value of a map index -// should be ignored, and if vari is such a variable. -func (v *varNameLen) checkMapIndexOk(vari variable) bool { - return v.ignoreMapIndexOk && vari.isMapIndexOk() -} - -// checkChannelReceiveOk returns true if "ok" variables that hold the bool return value of a channel receive -// should be ignored, and if vari is such a variable. -func (v *varNameLen) checkChannelReceiveOk(vari variable) bool { - return v.ignoreChannelReceiveOk && vari.isChannelReceiveOk() -} - -// distances returns maps of variables, parameters, return values, and type parameters mapping to their longest usage distances. -func (v *varNameLen) distances(pass *analysis.Pass) (map[variable]int, map[parameter]int, map[parameter]int, map[typeParam]int) { - assignIdents, valueSpecIdents, paramIdents, returnIdents, typeParamIdents, imports, switches := v.identsAndImports(pass) - - varToDist := map[variable]int{} - - for _, ident := range assignIdents { - assign := ident.Obj.Decl.(*ast.AssignStmt) //nolint:forcetypeassert // check is done in identsAndImports - - var typ string - if isTypeSwitchAssign(assign, switches) { - typ = "" - } else { - typ = shortTypeName(pass.TypesInfo.TypeOf(ident), imports) - } - - variable := variable{ - name: ident.Name, - typ: typ, - assign: assign, - } - - useLine := pass.Fset.Position(ident.NamePos).Line - declLine := pass.Fset.Position(assign.Pos()).Line - varToDist[variable] = useLine - declLine - } - - for _, ident := range valueSpecIdents { - valueSpec := ident.Obj.Decl.(*ast.ValueSpec) //nolint:forcetypeassert // check is done in identsAndImports - - variable := variable{ - name: ident.Name, - constant: ident.Obj.Kind == ast.Con, - typ: shortTypeName(pass.TypesInfo.TypeOf(ident), imports), - valueSpec: valueSpec, - } - - useLine := pass.Fset.Position(ident.NamePos).Line - declLine := pass.Fset.Position(valueSpec.Pos()).Line - varToDist[variable] = useLine - declLine - } - - paramToDist := map[parameter]int{} - - for _, ident := range paramIdents { - field := ident.Obj.Decl.(*ast.Field) //nolint:forcetypeassert // check is done in identsAndImports - - param := parameter{ - name: ident.Name, - typ: shortTypeName(pass.TypesInfo.TypeOf(field.Type), imports), - field: field, - } - - useLine := pass.Fset.Position(ident.NamePos).Line - declLine := pass.Fset.Position(field.Pos()).Line - paramToDist[param] = useLine - declLine - } - - returnToDist := map[parameter]int{} - - for _, ident := range returnIdents { - field := ident.Obj.Decl.(*ast.Field) //nolint:forcetypeassert // check is done in identsAndImports - - param := parameter{ - name: ident.Name, - typ: shortTypeName(pass.TypesInfo.TypeOf(ident), imports), - field: field, - } - - useLine := pass.Fset.Position(ident.NamePos).Line - declLine := pass.Fset.Position(field.Pos()).Line - returnToDist[param] = useLine - declLine - } - - typeParamToDist := map[typeParam]int{} - - for _, ident := range typeParamIdents { - field := ident.Obj.Decl.(*ast.Field) //nolint:forcetypeassert // check is done in identsAndImports - - param := typeParam{ - name: ident.Name, - typ: shortTypeName(pass.TypesInfo.TypeOf(field.Type), imports), - field: field, - } - - useLine := pass.Fset.Position(ident.NamePos).Line - declLine := pass.Fset.Position(field.Pos()).Line - typeParamToDist[param] = useLine - declLine - } - - return varToDist, paramToDist, returnToDist, typeParamToDist -} - -// identsAndImports returns Idents referencing assign statements, value specifications, parameters, -// return values, and type parameters, respectively, as well as import declarations, and type switch statements. -func (v *varNameLen) identsAndImports(pass *analysis.Pass) ([]*ast.Ident, []*ast.Ident, []*ast.Ident, []*ast.Ident, //nolint:gocognit,cyclop // this is complex stuff - []*ast.Ident, []importDeclaration, []*ast.TypeSwitchStmt) { - inspector := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) //nolint:forcetypeassert // inspect.Analyzer always returns *inspector.Inspector - - filter := []ast.Node{ - (*ast.ImportSpec)(nil), - (*ast.FuncDecl)(nil), - (*ast.FuncLit)(nil), - (*ast.CompositeLit)(nil), - (*ast.TypeSwitchStmt)(nil), - (*ast.Ident)(nil), - } - - assignIdents := []*ast.Ident{} - valueSpecIdents := []*ast.Ident{} - paramIdents := []*ast.Ident{} - returnIdents := []*ast.Ident{} - typeParamIdents := []*ast.Ident{} - imports := []importDeclaration{} - switches := []*ast.TypeSwitchStmt{} - - funcs := []*ast.FuncDecl{} - methods := []*ast.FuncDecl{} - funcLits := []*ast.FuncLit{} - compositeLits := []*ast.CompositeLit{} - - inspector.Preorder(filter, func(node ast.Node) { - switch node2 := node.(type) { - case *ast.ImportSpec: - decl, ok := importSpecToDecl(node2, pass.Pkg.Imports()) - if !ok { - return - } - - imports = append(imports, decl) - - case *ast.FuncDecl: - funcs = append(funcs, node2) - - if node2.Recv == nil { - return - } - - methods = append(methods, node2) - - case *ast.FuncLit: - funcLits = append(funcLits, node2) - - case *ast.CompositeLit: - compositeLits = append(compositeLits, node2) - - case *ast.TypeSwitchStmt: - switches = append(switches, node2) - - case *ast.Ident: - if node2.Obj == nil { - return - } - - if isCompositeLitKey(node2, compositeLits) { - return - } - - switch objDecl := node2.Obj.Decl.(type) { - case *ast.AssignStmt: - assignIdents = append(assignIdents, node2) - - case *ast.ValueSpec: - valueSpecIdents = append(valueSpecIdents, node2) - - case *ast.Field: - switch { - case isReceiver(objDecl, methods): - if !v.checkReceiver { - return - } - - paramIdents = append(paramIdents, node2) - - case isReturn(objDecl, funcs, funcLits): - if !v.checkReturn { - return - } - - returnIdents = append(returnIdents, node2) - - case isTypeParam(objDecl, funcs, funcLits): - if !v.checkTypeParameters { - return - } - - typeParamIdents = append(typeParamIdents, node2) - - case isParam(objDecl, funcs, funcLits, methods): - paramIdents = append(paramIdents, node2) - } - } - } - }) - - imports = append(imports, importDeclaration{ - path: pass.Pkg.Path(), - self: true, - }) - - sort.Slice(imports, func(a, b int) bool { - // reversed: longest path first - return len(imports[a].path) > len(imports[b].path) - }) - - return assignIdents, valueSpecIdents, paramIdents, returnIdents, typeParamIdents, imports, switches -} - -func importSpecToDecl(spec *ast.ImportSpec, imports []*types.Package) (importDeclaration, bool) { - path := strings.TrimSuffix(strings.TrimPrefix(spec.Path.Value, "\""), "\"") - - if spec.Name != nil { - return importDeclaration{ - name: spec.Name.Name, - path: path, - }, true - } - - for _, imp := range imports { - if imp.Path() == path { - return importDeclaration{ - name: imp.Name(), - path: path, - }, true - } - } - - return importDeclaration{}, false -} - -// isTypeAssertOk returns true if v is an "ok" variable that holds the bool return value of a type assertion. -func (v variable) isTypeAssertOk() bool { - if v.name != "ok" { - return false - } - - if v.assign == nil { - return false - } - - if len(v.assign.Lhs) != 2 { - return false - } - - ident, ok := v.assign.Lhs[1].(*ast.Ident) - if !ok { - return false - } - - if ident.Name != "ok" { - return false - } - - if len(v.assign.Rhs) != 1 { - return false - } - - if _, ok := v.assign.Rhs[0].(*ast.TypeAssertExpr); !ok { - return false - } - - return true -} - -// isMapIndexOk returns true if v is an "ok" variable that holds the bool return value of a map index. -func (v variable) isMapIndexOk() bool { - if v.name != "ok" { - return false - } - - if v.assign == nil { - return false - } - - if len(v.assign.Lhs) != 2 { - return false - } - - ident, ok := v.assign.Lhs[1].(*ast.Ident) - if !ok { - return false - } - - if ident.Name != "ok" { - return false - } - - if len(v.assign.Rhs) != 1 { - return false - } - - if _, ok := v.assign.Rhs[0].(*ast.IndexExpr); !ok { - return false - } - - return true -} - -// isChannelReceiveOk returns true if v is an "ok" variable that holds the bool return value of a channel receive. -func (v variable) isChannelReceiveOk() bool { - if v.name != "ok" { - return false - } - - if v.assign == nil { - return false - } - - if len(v.assign.Lhs) != 2 { - return false - } - - ident, ok := v.assign.Lhs[1].(*ast.Ident) - if !ok { - return false - } - - if ident.Name != "ok" { - return false - } - - if len(v.assign.Rhs) != 1 { - return false - } - - unary, ok := v.assign.Rhs[0].(*ast.UnaryExpr) - if !ok { - return false - } - - if unary.Op != token.ARROW { - return false - } - - return true -} - -// isConventional returns true if v matches a conventional Go variable/parameter name and type, -// such as "ctx context.Context" or "t *testing.T". -func (v variable) isConventional() bool { - for _, decl := range conventionalDecls { - if v.match(decl) { - return true - } - } - - return false -} - -// match returns true if v matches decl. -func (v variable) match(decl declaration) bool { - if v.name != decl.name { - return false - } - - if v.constant != decl.constant { - return false - } - - if v.constant { - return true - } - - if v.typ == "" { - return false - } - - return decl.matchType(v.typ) -} - -// kindName returns "constant" if v.constant==true, else "variable". -func (v variable) kindName() string { - if v.constant { - return "constant" - } - - return "variable" -} - -// isReceiver returns true if field is a receiver parameter of any of the given methods. -func isReceiver(field *ast.Field, methods []*ast.FuncDecl) bool { - for _, m := range methods { - for _, recv := range m.Recv.List { - if recv == field { - return true - } - } - } - - return false -} - -// isReturn returns true if field is a return value of any of the given funcs. -func isReturn(field *ast.Field, funcs []*ast.FuncDecl, funcLits []*ast.FuncLit) bool { //nolint:gocognit // it's not that complicated - for _, f := range funcs { - if f.Type.Results == nil { - continue - } - - for _, r := range f.Type.Results.List { - if r == field { - return true - } - } - } - - for _, f := range funcLits { - if f.Type.Results == nil { - continue - } - - for _, r := range f.Type.Results.List { - if r == field { - return true - } - } - } - - return false -} - -// isParam returns true if field is a parameter of any of the given funcs. -func isParam(field *ast.Field, funcs []*ast.FuncDecl, funcLits []*ast.FuncLit, methods []*ast.FuncDecl) bool { //nolint:gocognit,cyclop // it's not that complicated - for _, f := range funcs { - if f.Type.Params == nil { - continue - } - - for _, p := range f.Type.Params.List { - if p == field { - return true - } - } - } - - for _, f := range funcLits { - if f.Type.Params == nil { - continue - } - - for _, p := range f.Type.Params.List { - if p == field { - return true - } - } - } - - for _, m := range methods { - if m.Type.Params == nil { - continue - } - - for _, p := range m.Type.Params.List { - if p == field { - return true - } - } - } - - return false -} - -// isCompositeLitKey returns true if ident is a key of any of the given composite literals. -func isCompositeLitKey(ident *ast.Ident, compositeLits []*ast.CompositeLit) bool { - for _, cl := range compositeLits { - if _, ok := cl.Type.(*ast.MapType); ok { - continue - } - - for _, kvExpr := range cl.Elts { - kv, ok := kvExpr.(*ast.KeyValueExpr) - if !ok { - continue - } - - if kv.Key == ident { - return true - } - } - } - - return false -} - -// isTypeSwitchAssign returns true if assign is an assign statement of any of the given type switch statements. -func isTypeSwitchAssign(assign *ast.AssignStmt, switches []*ast.TypeSwitchStmt) bool { - for _, s := range switches { - if s.Assign == assign { - return true - } - } - - return false -} - -// isConventional returns true if v matches a conventional Go variable/parameter name and type, -// such as "ctx context.Context" or "t *testing.T". -func (p parameter) isConventional() bool { - for _, decl := range conventionalDecls { - if p.match(decl) { - return true - } - } - - return false -} - -// match returns whether p matches decl. -func (p parameter) match(decl declaration) bool { - if p.name != decl.name { - return false - } - - return decl.matchType(p.typ) -} - -// match returns whether p matches decl. -func (p typeParam) match(decl declaration) bool { - if p.name != decl.name { - return false - } - - return decl.matchType(p.typ) -} - -// parseDeclaration parses and returns a variable declaration parsed from decl. -func parseDeclaration(decl string) declaration { - if strings.HasPrefix(decl, "const ") { - return declaration{ - name: strings.TrimPrefix(decl, "const "), - constant: true, - } - } - - parts := strings.SplitN(decl, " ", 2) - - return declaration{ - name: parts[0], - typ: parts[1], - } -} - -// matchType returns true if typ matches d.typ. -func (d declaration) matchType(typ string) bool { - return d.typ == typ -} - -// shortTypeName returns the short name of typ, with respect to imports. -// For example, if package github.com/matryer/is is imported with alias "x", -// and typ represents []*github.com/matryer/is.I, shortTypeName will return "[]*x.I". -// For imports without aliases, the package's default name will be used. -func shortTypeName(typ types.Type, imports []importDeclaration) string { - if typ == nil { - return "" - } - - typStr := typ.String() - - for _, imp := range imports { - prefix := imp.path + "." - - replace := "" - if !imp.self { - replace = imp.name + "." - } - - typStr = strings.ReplaceAll(typStr, prefix, replace) - } - - return typStr -} diff --git a/vendor/github.com/bombsimon/wsl/v4/.gitignore b/vendor/github.com/bombsimon/wsl/v4/.gitignore deleted file mode 100644 index b37c694812..0000000000 --- a/vendor/github.com/bombsimon/wsl/v4/.gitignore +++ /dev/null @@ -1,72 +0,0 @@ - -# Created by https://www.gitignore.io/api/go,vim,macos - -### Go ### -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib - -# Test binary, build with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -### Go Patch ### -/vendor/ -/Godeps/ - -### macOS ### -# 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 - -### Vim ### -# Swap -[._]*.s[a-v][a-z] -[._]*.sw[a-p] -[._]s[a-rt-v][a-z] -[._]ss[a-gi-z] -[._]sw[a-p] - -# Session -Session.vim - -# Temporary -.netrwhist -*~ -# Auto-generated tag files -tags -# Persistent undo -[._]*.un~ - - -# End of https://www.gitignore.io/api/go,vim,macos - -.idea/ diff --git a/vendor/github.com/bombsimon/wsl/v4/.golangci.yml b/vendor/github.com/bombsimon/wsl/v4/.golangci.yml deleted file mode 100644 index f4948e0539..0000000000 --- a/vendor/github.com/bombsimon/wsl/v4/.golangci.yml +++ /dev/null @@ -1,79 +0,0 @@ ---- -version: "2" - -output: - formats: - text: - path: stdout - print-issued-lines: false - -linters: - default: all - disable: - - cyclop - - depguard - - dupl - - dupword - - exhaustruct - - forbidigo - - funlen - - gocognit - - gocyclo - - godox - - lll - - maintidx - - mnd - - nakedret - - nestif - - nlreturn - - paralleltest - - prealloc - - rowserrcheck - - testpackage - - tparallel - - varnamelen - - wastedassign - - settings: - depguard: - rules: - main: - deny: - - pkg: github.com/davecgh/go-spew/spew - desc: not allowed - gocognit: - min-complexity: 10 - gocritic: - # Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` - # to see all tags and checks. Empty list by default. See - # https://github.com/go-critic/go-critic#usage -> section "Tags". - enabled-tags: - - diagnostic - - experimental - - opinionated - - performance - - style - misspell: - locale: US - - exclusions: - presets: - - comments - - common-false-positives - - std-error-handling - -issues: - max-issues-per-linter: 0 - max-same-issues: 0 -formatters: - enable: - - gofmt - - gofumpt - - goimports - settings: - gofmt: - rewrite-rules: - - pattern: 'interface{}' - replacement: 'any' - -# vim: set sw=2 ts=2 et: diff --git a/vendor/github.com/bombsimon/wsl/v4/LICENSE b/vendor/github.com/bombsimon/wsl/v4/LICENSE deleted file mode 100644 index 4dade6d1c9..0000000000 --- a/vendor/github.com/bombsimon/wsl/v4/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2018 Simon Sawert - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/bombsimon/wsl/v4/README.md b/vendor/github.com/bombsimon/wsl/v4/README.md deleted file mode 100644 index e98fe1b4a8..0000000000 --- a/vendor/github.com/bombsimon/wsl/v4/README.md +++ /dev/null @@ -1,92 +0,0 @@ -# wsl - Whitespace Linter - -[![forthebadge](https://forthebadge.com/images/badges/made-with-go.svg)](https://forthebadge.com) -[![forthebadge](https://forthebadge.com/images/badges/built-with-love.svg)](https://forthebadge.com) - -[![GitHub Actions](https://github.com/bombsimon/wsl/actions/workflows/go.yml/badge.svg)](https://github.com/bombsimon/wsl/actions/workflows/go.yml) -[![Coverage Status](https://coveralls.io/repos/github/bombsimon/wsl/badge.svg?branch=master)](https://coveralls.io/github/bombsimon/wsl?branch=master) - -`wsl` is a linter that enforces a very **non scientific** vision of how to make -code more readable by enforcing empty lines at the right places. - -**This linter is aggressive** and a lot of projects I've tested it on have -failed miserably. For this linter to be useful at all I want to be open to new -ideas, configurations and discussions! Also note that some of the warnings might -be bugs or unintentional false positives so I would love an -[issue](https://github.com/bombsimon/wsl/issues/new) to fix, discuss, change or -make something configurable! - -## Installation - -```sh -# Latest release -go install github.com/bombsimon/wsl/v4/cmd/wsl@latest - -# Main branch -go install github.com/bombsimon/wsl/v4/cmd/wsl@master -``` - -## Usage - -`wsl` uses the [analysis](https://pkg.go.dev/golang.org/x/tools/go/analysis) -package meaning it will operate on package level with the default analysis flags -and way of working. - -```sh -wsl --help -wsl [flags] - -wsl --allow-cuddle-declarations --fix ./... -``` - -`wsl` is also integrated in [`golangci-lint`](https://golangci-lint.run) - -```sh -golangci-lint run --no-config --disable-all --enable wsl --fix -``` - -> **Note**: If you're not sure what the diagnostic is trying to tell you, use -> any of the fix approaches to fix the code for you. - -## Issues and configuration - -The linter suppers a few ways to configure it to satisfy more than one kind of -code style. These settings could be set either with flags or with YAML -configuration if used via `golangci-lint`. - -The supported configuration can be found [in the -documentation](doc/configuration.md). - -Below are the available checklist for any hit from `wsl`. If you do not see any, -feel free to raise an [issue](https://github.com/bombsimon/wsl/issues/new). - -* [Anonymous switch statements should never be cuddled](doc/rules.md#anonymous-switch-statements-should-never-be-cuddled) -* [Append only allowed to cuddle with appended value](doc/rules.md#append-only-allowed-to-cuddle-with-appended-value) -* [Assignments should only be cuddled with other assignments](doc/rules.md#assignments-should-only-be-cuddled-with-other-assignments) -* [Block should not end with a whitespace (or comment)](doc/rules.md#block-should-not-end-with-a-whitespace-or-comment) -* [Block should not start with a whitespace](doc/rules.md#block-should-not-start-with-a-whitespace) -* [Case block should end with newline at this size](doc/rules.md#case-block-should-end-with-newline-at-this-size) -* [Branch statements should not be cuddled if block has more than two lines](doc/rules.md#branch-statements-should-not-be-cuddled-if-block-has-more-than-two-lines) -* [Declarations should never be cuddled](doc/rules.md#declarations-should-never-be-cuddled) -* [Defer statements should only be cuddled with expressions on same variable](doc/rules.md#defer-statements-should-only-be-cuddled-with-expressions-on-same-variable) -* [Expressions should not be cuddled with blocks](doc/rules.md#expressions-should-not-be-cuddled-with-blocks) -* [Expressions should not be cuddled with declarations or returns](doc/rules.md#expressions-should-not-be-cuddled-with-declarations-or-returns) -* [For statement without condition should never be cuddled](doc/rules.md#for-statement-without-condition-should-never-be-cuddled) -* [For statements should only be cuddled with assignments used in the iteration](doc/rules.md#for-statements-should-only-be-cuddled-with-assignments-used-in-the-iteration) -* [Go statements can only invoke functions assigned on line above](doc/rules.md#go-statements-can-only-invoke-functions-assigned-on-line-above) -* [If statements should only be cuddled with assignments](doc/rules.md#if-statements-should-only-be-cuddled-with-assignments) -* [If statements should only be cuddled with assignments used in the if statement itself](doc/rules.md#if-statements-should-only-be-cuddled-with-assignments-used-in-the-if-statement-itself) -* [If statements that check an error must be cuddled with the statement that assigned the error](doc/rules.md#if-statements-that-check-an-error-must-be-cuddled-with-the-statement-that-assigned-the-error) -* [Only cuddled expressions if assigning variable or using from line above](doc/rules.md#only-cuddled-expressions-if-assigning-variable-or-using-from-line-above) -* [Only one cuddle assignment allowed before defer statement](doc/rules.md#only-one-cuddle-assignment-allowed-before-defer-statement) -* [Only one cuddle assignment allowed before for statement](doc/rules.md#only-one-cuddle-assignment-allowed-before-for-statement) -* [Only one cuddle assignment allowed before go statement](doc/rules.md#only-one-cuddle-assignment-allowed-before-go-statement) -* [Only one cuddle assignment allowed before if statement](doc/rules.md#only-one-cuddle-assignment-allowed-before-if-statement) -* [Only one cuddle assignment allowed before range statement](doc/rules.md#only-one-cuddle-assignment-allowed-before-range-statement) -* [Only one cuddle assignment allowed before switch statement](doc/rules.md#only-one-cuddle-assignment-allowed-before-switch-statement) -* [Only one cuddle assignment allowed before type switch statement](doc/rules.md#only-one-cuddle-assignment-allowed-before-type-switch-statement) -* [Ranges should only be cuddled with assignments used in the iteration](doc/rules.md#ranges-should-only-be-cuddled-with-assignments-used-in-the-iteration) -* [Return statements should not be cuddled if block has more than two lines](doc/rules.md#return-statements-should-not-be-cuddled-if-block-has-more-than-two-lines) -* [Short declarations should cuddle only with other short declarations](doc/rules.md#short-declaration-should-cuddle-only-with-other-short-declarations) -* [Switch statements should only be cuddled with variables switched](doc/rules.md#switch-statements-should-only-be-cuddled-with-variables-switched) -* [Type switch statements should only be cuddled with variables switched](doc/rules.md#type-switch-statements-should-only-be-cuddled-with-variables-switched) diff --git a/vendor/github.com/bombsimon/wsl/v4/analyzer.go b/vendor/github.com/bombsimon/wsl/v4/analyzer.go deleted file mode 100644 index 12adbfa7a9..0000000000 --- a/vendor/github.com/bombsimon/wsl/v4/analyzer.go +++ /dev/null @@ -1,169 +0,0 @@ -package wsl - -import ( - "flag" - "go/ast" - "go/token" - "strings" - - "golang.org/x/tools/go/analysis" -) - -func NewAnalyzer(config *Configuration) *analysis.Analyzer { - wa := &wslAnalyzer{config: config} - - return &analysis.Analyzer{ - Name: "wsl", - Doc: "add or remove empty lines", - Flags: wa.flags(), - Run: wa.run, - RunDespiteErrors: true, - } -} - -func defaultConfig() *Configuration { - return &Configuration{ - AllowAssignAndAnythingCuddle: false, - AllowAssignAndCallCuddle: true, - AllowCuddleDeclaration: false, - AllowMultiLineAssignCuddle: true, - AllowSeparatedLeadingComment: false, - AllowTrailingComment: false, - ForceCuddleErrCheckAndAssign: false, - ForceExclusiveShortDeclarations: false, - StrictAppend: true, - IncludeGenerated: false, - AllowCuddleWithCalls: []string{"Lock", "RLock"}, - AllowCuddleWithRHS: []string{"Unlock", "RUnlock"}, - ErrorVariableNames: []string{"err"}, - ForceCaseTrailingWhitespaceLimit: 0, - AllowCuddleUsedInBlock: false, - } -} - -// wslAnalyzer is a wrapper around the configuration which is used to be able to -// set the configuration when creating the analyzer and later be able to update -// flags and running method. -type wslAnalyzer struct { - config *Configuration -} - -func (wa *wslAnalyzer) flags() flag.FlagSet { - flags := flag.NewFlagSet("", flag.ExitOnError) - - // If we have a configuration set we're not running from the command line so - // we don't use any flags. - if wa.config != nil { - return *flags - } - - wa.config = defaultConfig() - - flags.BoolVar(&wa.config.AllowAssignAndAnythingCuddle, "allow-assign-and-anything", false, "Allow assignments and anything to be cuddled") - flags.BoolVar(&wa.config.AllowAssignAndCallCuddle, "allow-assign-and-call", true, "Allow assignments and calls to be cuddled (if using same variable/type)") - flags.BoolVar(&wa.config.AllowCuddleDeclaration, "allow-cuddle-declarations", false, "Allow declarations to be cuddled") - flags.BoolVar(&wa.config.AllowMultiLineAssignCuddle, "allow-multi-line-assign", true, "Allow cuddling with multi line assignments") - flags.BoolVar(&wa.config.AllowSeparatedLeadingComment, "allow-separated-leading-comment", false, "Allow empty newlines in leading comments") - flags.BoolVar(&wa.config.AllowTrailingComment, "allow-trailing-comment", false, "Allow blocks to end with a comment") - flags.BoolVar(&wa.config.ForceCuddleErrCheckAndAssign, "force-err-cuddling", false, "Force cuddling of error checks with error var assignment") - flags.BoolVar(&wa.config.ForceExclusiveShortDeclarations, "force-short-decl-cuddling", false, "Force short declarations to cuddle by themselves") - flags.BoolVar(&wa.config.StrictAppend, "strict-append", true, "Strict rules for append") - flags.BoolVar(&wa.config.IncludeGenerated, "include-generated", false, "Include generated files") - flags.BoolVar(&wa.config.AllowCuddleUsedInBlock, "allow-cuddle-used-in-block", false, "Allow cuddling of variables used in block statements") - flags.IntVar(&wa.config.ForceCaseTrailingWhitespaceLimit, "force-case-trailing-whitespace", 0, "Force newlines for case blocks > this number.") - - flags.Var(&multiStringValue{slicePtr: &wa.config.AllowCuddleWithCalls}, "allow-cuddle-with-calls", "Comma separated list of idents that can have cuddles after") - flags.Var(&multiStringValue{slicePtr: &wa.config.AllowCuddleWithRHS}, "allow-cuddle-with-rhs", "Comma separated list of idents that can have cuddles before") - flags.Var(&multiStringValue{slicePtr: &wa.config.ErrorVariableNames}, "error-variable-names", "Comma separated list of error variable names") - - return *flags -} - -func (wa *wslAnalyzer) run(pass *analysis.Pass) (any, error) { - for _, file := range pass.Files { - filename := getFilename(pass.Fset, file) - if !strings.HasSuffix(filename, ".go") { - continue - } - - fn := pass.Fset.PositionFor(file.Pos(), false).Filename - - // if the file is related to cgo the filename of the unadjusted position is a not a '.go' file. - if !strings.HasSuffix(fn, ".go") { - continue - } - - // The file is skipped if the "unadjusted" file is a Go file, and it's a generated file (ex: "_test.go" file). - // The other non-Go files are skipped by the first 'if' with the adjusted position. - if !wa.config.IncludeGenerated && ast.IsGenerated(file) && strings.HasSuffix(fn, ".go") { - continue - } - - processor := newProcessorWithConfig(file, pass.Fset, wa.config) - processor.parseAST() - - for pos, fix := range processor.result { - textEdits := []analysis.TextEdit{} - for _, f := range fix.fixRanges { - textEdits = append(textEdits, analysis.TextEdit{ - Pos: f.fixRangeStart, - End: f.fixRangeEnd, - NewText: []byte("\n"), - }) - } - - pass.Report(analysis.Diagnostic{ - Pos: pos, - Category: "whitespace", - Message: fix.reason, - SuggestedFixes: []analysis.SuggestedFix{ - { - TextEdits: textEdits, - }, - }, - }) - } - } - - //nolint:nilnil // A pass don't need to return anything. - return nil, nil -} - -// multiStringValue is a flag that supports multiple values. It's implemented to -// contain a pointer to a string slice that will be overwritten when the flag's -// `Set` method is called. -type multiStringValue struct { - slicePtr *[]string -} - -// Set implements the flag.Value interface and will overwrite the pointer to the -// slice with a new pointer after splitting the flag by comma. -func (m *multiStringValue) Set(value string) error { - var s []string - - for _, v := range strings.Split(value, ",") { - s = append(s, strings.TrimSpace(v)) - } - - *m.slicePtr = s - - return nil -} - -// Set implements the flag.Value interface. -func (m *multiStringValue) String() string { - if m.slicePtr == nil { - return "" - } - - return strings.Join(*m.slicePtr, ", ") -} - -func getFilename(fset *token.FileSet, file *ast.File) string { - filename := fset.PositionFor(file.Pos(), true).Filename - if !strings.HasSuffix(filename, ".go") { - return fset.PositionFor(file.Pos(), false).Filename - } - - return filename -} diff --git a/vendor/github.com/bombsimon/wsl/v4/wsl.go b/vendor/github.com/bombsimon/wsl/v4/wsl.go deleted file mode 100644 index 88693f5466..0000000000 --- a/vendor/github.com/bombsimon/wsl/v4/wsl.go +++ /dev/null @@ -1,1464 +0,0 @@ -package wsl - -import ( - "fmt" - "go/ast" - "go/token" - "reflect" - "sort" - "strings" -) - -// Error reason strings. -const ( - reasonAnonSwitchCuddled = "anonymous switch statements should never be cuddled" - reasonAppendCuddledWithoutUse = "append only allowed to cuddle with appended value" - reasonAssignsCuddleAssign = "assignments should only be cuddled with other assignments" - reasonBlockEndsWithWS = "block should not end with a whitespace (or comment)" - reasonBlockStartsWithWS = "block should not start with a whitespace" - reasonCaseBlockTooCuddly = "case block should end with newline at this size" - reasonDeferCuddledWithOtherVar = "defer statements should only be cuddled with expressions on same variable" - reasonExprCuddlingNonAssignedVar = "only cuddled expressions if assigning variable or using from line above" - reasonExpressionCuddledWithBlock = "expressions should not be cuddled with blocks" - reasonExpressionCuddledWithDeclOrRet = "expressions should not be cuddled with declarations or returns" - reasonForCuddledAssignWithoutUse = "for statements should only be cuddled with assignments used in the iteration" - reasonForWithoutCondition = "for statement without condition should never be cuddled" - reasonGoFuncWithoutAssign = "go statements can only invoke functions assigned on line above" - reasonMultiLineBranchCuddle = "branch statements should not be cuddled if block has more than two lines" - reasonMustCuddleErrCheck = "if statements that check an error must be cuddled with the statement that assigned the error" - reasonNeverCuddleDeclare = "declarations should never be cuddled" - reasonOnlyCuddle2LineReturn = "return statements should not be cuddled if block has more than two lines" - reasonOnlyCuddleIfWithAssign = "if statements should only be cuddled with assignments" - reasonOnlyCuddleWithUsedAssign = "if statements should only be cuddled with assignments used in the if statement itself" - reasonOnlyOneCuddleBeforeDefer = "only one cuddle assignment allowed before defer statement" - reasonOnlyOneCuddleBeforeFor = "only one cuddle assignment allowed before for statement" - reasonOnlyOneCuddleBeforeGo = "only one cuddle assignment allowed before go statement" - reasonOnlyOneCuddleBeforeIf = "only one cuddle assignment allowed before if statement" - reasonOnlyOneCuddleBeforeRange = "only one cuddle assignment allowed before range statement" - reasonOnlyOneCuddleBeforeSwitch = "only one cuddle assignment allowed before switch statement" - reasonOnlyOneCuddleBeforeTypeSwitch = "only one cuddle assignment allowed before type switch statement" - reasonRangeCuddledWithoutUse = "ranges should only be cuddled with assignments used in the iteration" - reasonShortDeclNotExclusive = "short declaration should cuddle only with other short declarations" - reasonSwitchCuddledWithoutUse = "switch statements should only be cuddled with variables switched" - reasonTypeSwitchCuddledWithoutUse = "type switch statements should only be cuddled with variables switched" -) - -// Warning strings. -const ( - warnTypeNotImplement = "type not implemented" - warnStmtNotImplemented = "stmt type not implemented" - warnBodyStmtTypeNotImplemented = "body statement type not implemented " - warnWSNodeTypeNotImplemented = "whitespace node type not implemented " - warnUnknownLHS = "UNKNOWN LHS" - warnUnknownRHS = "UNKNOWN RHS" -) - -// Configuration represents configurable settings for the linter. -type Configuration struct { - // StrictAppend will do strict checking when assigning from append (x = - // append(x, y)). If this is set to true the append call must append either - // a variable assigned, called or used on the line above. Example on not - // allowed when this is true: - // - // x := []string{} - // y := "not going in X" - // x = append(x, "not y") // This is not allowed with StrictAppend - // z := "going in X" - // - // x = append(x, z) // This is allowed with StrictAppend - // - // m := transform(z) - // x = append(x, z) // So is this because Z is used above. - StrictAppend bool - - // AllowAssignAndCallCuddle allows assignments to be cuddled with variables - // used in calls on line above and calls to be cuddled with assignments of - // variables used in call on line above. - // Example supported with this set to true: - // - // x.Call() - // x = Assign() - // x.AnotherCall() - // x = AnotherAssign() - AllowAssignAndCallCuddle bool - - // AllowAssignAndAnythingCuddle allows assignments to be cuddled with anything. - // Example supported with this set to true: - // if x == 1 { - // x = 0 - // } - // z := x + 2 - // fmt.Println("x") - // y := "x" - AllowAssignAndAnythingCuddle bool - - // AllowMultiLineAssignCuddle allows cuddling to assignments even if they - // span over multiple lines. This defaults to true which allows the - // following example: - // - // err := function( - // "multiple", "lines", - // ) - // if err != nil { - // // ... - // } - AllowMultiLineAssignCuddle bool - - // If the number of lines in a case block is equal to or lager than this - // number, the case *must* end white a newline. - ForceCaseTrailingWhitespaceLimit int - - // AllowTrailingComment will allow blocks to end with comments. - AllowTrailingComment bool - - // AllowSeparatedLeadingComment will allow multiple comments in the - // beginning of a block separated with newline. Example: - // func () { - // // Comment one - // - // // Comment two - // fmt.Println("x") - // } - AllowSeparatedLeadingComment bool - - // AllowCuddleDeclaration will allow multiple var/declaration statements to - // be cuddled. This defaults to false but setting it to true will enable the - // following example: - // var foo bool - // var err error - AllowCuddleDeclaration bool - - // AllowCuddleWithCalls is a list of call idents that everything can be - // cuddled with. Defaults to calls looking like locks to support a flow like - // this: - // - // mu.Lock() - // allow := thisAssignment - AllowCuddleWithCalls []string - - // AllowCuddleWithRHS is a list of right hand side variables that is allowed - // to be cuddled with anything. Defaults to assignments or calls looking - // like unlocks to support a flow like this: - // - // allow := thisAssignment() - // mu.Unlock() - AllowCuddleWithRHS []string - - // ForceCuddleErrCheckAndAssign will cause an error when an If statement that - // checks an error variable doesn't cuddle with the assignment of that variable. - // This defaults to false but setting it to true will cause the following - // to generate an error: - // - // err := ProduceError() - // - // if err != nil { - // return err - // } - ForceCuddleErrCheckAndAssign bool - - // When ForceCuddleErrCheckAndAssign is enabled this is a list of names - // used for error variables to check for in the conditional. - // Defaults to just "err" - ErrorVariableNames []string - - // ForceExclusiveShortDeclarations will cause an error if a short declaration - // (:=) cuddles with anything other than another short declaration. For example - // - // a := 2 - // b := 3 - // - // is allowed, but - // - // a := 2 - // b = 3 - // - // is not allowed. This logic overrides ForceCuddleErrCheckAndAssign among others. - ForceExclusiveShortDeclarations bool - - // IncludeGenerated will include generated files in the analysis and report - // errors even for generated files. Can be useful when developing - // generators. - IncludeGenerated bool - - // AllowCuddleUsedInBlock will allowing cuddling of variables with block statements - // if they are used anywhere in the block. This defaults to false but setting - // it to true will allow the following example: - // - // var numbers []int - // for i := 0; i < 10; i++ { - // if 1 == 1 { - // numbers = append(numbers, i) - // } - // } - AllowCuddleUsedInBlock bool -} - -// fix is a range to fixup. -type fix struct { - fixRangeStart token.Pos - fixRangeEnd token.Pos -} - -// result represents the result of one error. -type result struct { - fixRanges []fix - reason string -} - -// processor is the type that keeps track of the file and fileset and holds the -// results from parsing the AST. -type processor struct { - config *Configuration - file *ast.File - fileSet *token.FileSet - result map[token.Pos]result - warnings []string -} - -// newProcessorWithConfig will create a Processor with the passed configuration. -func newProcessorWithConfig(file *ast.File, fileSet *token.FileSet, cfg *Configuration) *processor { - return &processor{ - config: cfg, - file: file, - fileSet: fileSet, - result: make(map[token.Pos]result), - } -} - -// parseAST will parse the AST attached to the Processor instance. -func (p *processor) parseAST() { - for _, d := range p.file.Decls { - switch v := d.(type) { - case *ast.FuncDecl: - p.parseBlockBody(v.Name, v.Body) - case *ast.GenDecl: - // `go fmt` will handle proper spacing for GenDecl such as imports, - // constants etc. - default: - p.addWarning(warnTypeNotImplement, d.Pos(), v) - } - } -} - -// parseBlockBody will parse any kind of block statements such as switch cases -// and if statements. A list of Result is returned. -func (p *processor) parseBlockBody(ident *ast.Ident, block *ast.BlockStmt) { - // Nothing to do if there's no value. - if reflect.ValueOf(block).IsNil() { - return - } - - // Start by finding leading and trailing whitespaces. - p.findLeadingAndTrailingWhitespaces(ident, block, nil) - - // Parse the block body contents. - p.parseBlockStatements(block.List) -} - -// parseBlockStatements will parse all the statements found in the body of a -// node. A list of Result is returned. -func (p *processor) parseBlockStatements(statements []ast.Stmt) { - for i, stmt := range statements { - // Start by checking if this statement is another block (other than if, - // for and range). This could be assignment to a function, defer or go - // call with an inline function or similar. If this is found we start by - // parsing this body block before moving on. - for _, stmtBlocks := range p.findBlockStmt(stmt) { - p.parseBlockBody(nil, stmtBlocks) - } - - firstBodyStatement := p.firstBodyStatement(i, statements) - - // First statement, nothing to do. - if i == 0 { - continue - } - - previousStatement := statements[i-1] - previousStatementIsMultiline := p.nodeStart(previousStatement) != p.nodeEnd(previousStatement) - cuddledWithLastStmt := p.nodeEnd(previousStatement) == p.nodeStart(stmt)-1 - - // If we're not cuddled and we don't need to enforce err-check cuddling - // then we can bail out here - if !cuddledWithLastStmt && !p.config.ForceCuddleErrCheckAndAssign { - continue - } - - // We don't force error cuddling for multilines. (#86) - if p.config.ForceCuddleErrCheckAndAssign && previousStatementIsMultiline && !cuddledWithLastStmt { - continue - } - - // Extract assigned variables on the line above - // which is the only thing we allow cuddling with. If the assignment is - // made over multiple lines we should not allow cuddling. - var assignedOnLineAbove []string - - // We want to keep track of what was called on the line above to support - // special handling of things such as mutexes. - var calledOnLineAbove []string - - // Check if the previous statement spans over multiple lines. - cuddledWithMultiLineAssignment := cuddledWithLastStmt && p.nodeStart(previousStatement) != p.nodeStart(stmt)-1 - - // Ensure previous line is not a multi line assignment and if not get - // rightAndLeftHandSide assigned variables. - if !cuddledWithMultiLineAssignment { - assignedOnLineAbove = p.findLHS(previousStatement) - calledOnLineAbove = p.findRHS(previousStatement) - } - - // If previous assignment is multi line and we allow it, fetch - // assignments (but only assignments). - if cuddledWithMultiLineAssignment && p.config.AllowMultiLineAssignCuddle { - if _, ok := previousStatement.(*ast.AssignStmt); ok { - assignedOnLineAbove = p.findLHS(previousStatement) - } - } - - // Contains the union of all variable names used anywhere - // within the block body (if applicable) and is used to check - // if a preceding statement's variables are actually used within - // the block. This helps enforce rules about allowed cuddling. - var identifiersUsedInBlock []string - - if firstBodyStatement != nil { - if p.config.AllowCuddleUsedInBlock { - identifiersUsedInBlock = p.findUsedVariablesInStatement(stmt) - } else { - identifiersUsedInBlock = append(p.findLHS(firstBodyStatement), p.findRHS(firstBodyStatement)...) - } - } - - var ( - leftHandSide = p.findLHS(stmt) - rightHandSide = p.findRHS(stmt) - rightAndLeftHandSide = append(leftHandSide, rightHandSide...) - calledOrAssignedOnLineAbove = append(calledOnLineAbove, assignedOnLineAbove...) - ) - - // If we called some kind of lock on the line above we allow cuddling - // anything. - if atLeastOneInListsMatch(calledOnLineAbove, p.config.AllowCuddleWithCalls) { - continue - } - - // If we call some kind of unlock on this line we allow cuddling with - // anything. - if atLeastOneInListsMatch(rightHandSide, p.config.AllowCuddleWithRHS) { - continue - } - - nStatementsBefore := func(n int) bool { - if i < n { - return false - } - - for j := 1; j < n; j++ { - s1 := statements[i-j] - s2 := statements[i-(j+1)] - - if p.nodeStart(s1)-1 != p.nodeEnd(s2) { - return false - } - } - - return true - } - - nStatementsAfter := func(n int) bool { - if len(statements)-1 < i+n { - return false - } - - for j := range n { - s1 := statements[i+j] - s2 := statements[i+j+1] - - if p.nodeEnd(s1)+1 != p.nodeStart(s2) { - return false - } - } - - return true - } - - isLastStatementInBlockOfOnlyTwoLines := func() bool { - // If we're the last statement, check if there's no more than two - // lines from the starting statement and the end of this statement. - // This is to support short return functions such as: - // func (t *Typ) X() { - // t.X = true - // return t - // } - if len(statements) == 2 && i == 1 { - if p.nodeEnd(stmt)-p.nodeStart(previousStatement) <= 2 { - return true - } - } - - return false - } - - // If it's a short declaration we should not cuddle with anything else - // if ForceExclusiveShortDeclarations is set on; either this or the - // previous statement could be the short decl, so we'll find out which - // it was and use *that* statement's position - if p.config.ForceExclusiveShortDeclarations && cuddledWithLastStmt { - if p.isShortDecl(stmt) && !p.isShortDecl(previousStatement) { - var reportNode ast.Node = previousStatement - - cm := ast.NewCommentMap(p.fileSet, stmt, p.file.Comments) - if cg, ok := cm[stmt]; ok && len(cg) > 0 { - for _, c := range cg { - if c.Pos() > previousStatement.End() && c.End() < stmt.Pos() { - reportNode = c - } - } - } - - p.addErrorRange( - stmt.Pos(), - reportNode.End(), - reportNode.End(), - reasonShortDeclNotExclusive, - ) - } else if p.isShortDecl(previousStatement) && !p.isShortDecl(stmt) { - p.addErrorRange( - previousStatement.Pos(), - stmt.Pos(), - stmt.Pos(), - reasonShortDeclNotExclusive, - ) - } - } - - // If it's not an if statement and we're not cuddled move on. The only - // reason we need to keep going for if statements is to check if we - // should be cuddled with an error check. - if _, ok := stmt.(*ast.IfStmt); !ok { - if !cuddledWithLastStmt { - continue - } - } - - reportNewlineTwoLinesAbove := func(n1, n2 ast.Node, reason string) { - if atLeastOneInListsMatch(rightAndLeftHandSide, assignedOnLineAbove) || - atLeastOneInListsMatch(assignedOnLineAbove, identifiersUsedInBlock) { - // If both the assignment on the line above _and_ the assignment - // two lines above is part of line or first in block, add the - // newline as if non were. - _, isAssignmentTwoLinesAbove := statements[i-2].(*ast.AssignStmt) - assignedTwoLinesAbove := p.findLHS(statements[i-2]) - - if isAssignmentTwoLinesAbove && - (atLeastOneInListsMatch(rightAndLeftHandSide, assignedTwoLinesAbove) || - atLeastOneInListsMatch(assignedTwoLinesAbove, identifiersUsedInBlock)) { - p.addWhitespaceBeforeError(n1, reason) - } else { - // If the variable on the line above is allowed to be - // cuddled, break two lines above so we keep the proper - // cuddling. - p.addErrorRange(n1.Pos(), n2.Pos(), n2.Pos(), reason) - } - } else { - // If not, break here so we separate the cuddled variable. - p.addWhitespaceBeforeError(n1, reason) - } - } - - switch t := stmt.(type) { - case *ast.IfStmt: - checkingErrInitializedInline := func() bool { - if t.Init == nil { - return false - } - - // Variables were initialized inline in the if statement - // Let's make sure it's the err just to be safe - return atLeastOneInListsMatch(p.findLHS(t.Init), p.config.ErrorVariableNames) - } - - if !cuddledWithLastStmt { - checkingErr := atLeastOneInListsMatch(rightAndLeftHandSide, p.config.ErrorVariableNames) - if checkingErr { - // We only want to enforce cuddling error checks if the - // error was assigned on the line above. See - // https://github.com/bombsimon/wsl/issues/78. - // This is needed since `assignedOnLineAbove` is not - // actually just assignments but everything from LHS in the - // previous statement. This means that if previous line was - // `if err ...`, `err` will now be in the list - // `assignedOnLineAbove`. - if _, ok := previousStatement.(*ast.AssignStmt); !ok { - continue - } - - if checkingErrInitializedInline() { - continue - } - - if atLeastOneInListsMatch(assignedOnLineAbove, p.config.ErrorVariableNames) { - p.addErrorRange( - stmt.Pos(), - previousStatement.End(), - stmt.Pos(), - reasonMustCuddleErrCheck, - ) - } - } - - continue - } - - if len(assignedOnLineAbove) == 0 { - p.addWhitespaceBeforeError(t, reasonOnlyCuddleIfWithAssign) - continue - } - - if nStatementsBefore(2) { - reportNewlineTwoLinesAbove(t, statements[i-1], reasonOnlyOneCuddleBeforeIf) - continue - } - - if atLeastOneInListsMatch(rightAndLeftHandSide, assignedOnLineAbove) { - continue - } - - if atLeastOneInListsMatch(assignedOnLineAbove, identifiersUsedInBlock) { - continue - } - - p.addWhitespaceBeforeError(t, reasonOnlyCuddleWithUsedAssign) - case *ast.ReturnStmt: - if isLastStatementInBlockOfOnlyTwoLines() { - continue - } - - p.addWhitespaceBeforeError(t, reasonOnlyCuddle2LineReturn) - case *ast.BranchStmt: - if isLastStatementInBlockOfOnlyTwoLines() { - continue - } - - p.addWhitespaceBeforeError(t, reasonMultiLineBranchCuddle) - case *ast.AssignStmt: - // append is usually an assignment but should not be allowed to be - // cuddled with anything not appended. - if len(rightHandSide) > 0 && rightHandSide[len(rightHandSide)-1] == "append" { - if p.config.StrictAppend { - if !atLeastOneInListsMatch(calledOrAssignedOnLineAbove, rightHandSide) { - p.addWhitespaceBeforeError(t, reasonAppendCuddledWithoutUse) - } - } - - continue - } - - switch previousStatement.(type) { - case *ast.AssignStmt, *ast.IncDecStmt: - continue - } - - if p.config.AllowAssignAndAnythingCuddle { - continue - } - - if _, ok := previousStatement.(*ast.DeclStmt); ok && p.config.AllowCuddleDeclaration { - continue - } - - // If the assignment is from a type or variable called on the line - // above we can allow it by setting AllowAssignAndCallCuddle to - // true. - // Example (x is used): - // x.function() - // a.Field = x.anotherFunction() - if p.config.AllowAssignAndCallCuddle { - if atLeastOneInListsMatch(calledOrAssignedOnLineAbove, rightAndLeftHandSide) { - continue - } - } - - p.addWhitespaceBeforeError(t, reasonAssignsCuddleAssign) - case *ast.IncDecStmt: - switch previousStatement.(type) { - case *ast.AssignStmt, *ast.IncDecStmt: - continue - } - - p.addWhitespaceBeforeError(t, reasonAssignsCuddleAssign) - - case *ast.DeclStmt: - if !p.config.AllowCuddleDeclaration { - p.addWhitespaceBeforeError(t, reasonNeverCuddleDeclare) - } - case *ast.ExprStmt: - switch previousStatement.(type) { - case *ast.DeclStmt, *ast.ReturnStmt: - if p.config.AllowAssignAndCallCuddle && p.config.AllowCuddleDeclaration { - continue - } - - p.addWhitespaceBeforeError(t, reasonExpressionCuddledWithDeclOrRet) - case *ast.IfStmt, *ast.RangeStmt, *ast.SwitchStmt, *ast.TypeSwitchStmt, *ast.ForStmt: - p.addWhitespaceBeforeError(t, reasonExpressionCuddledWithBlock) - } - - // If the expression is called on a type or variable used or - // assigned on the line we can allow it by setting - // AllowAssignAndCallCuddle to true. - // Example of allowed cuddled (x is used): - // a.Field = x.func() - // x.function() - if p.config.AllowAssignAndCallCuddle { - if atLeastOneInListsMatch(calledOrAssignedOnLineAbove, rightAndLeftHandSide) { - continue - } - } - - // If we assigned variables on the line above but didn't use them in - // this expression there should probably be a newline between them. - if len(assignedOnLineAbove) > 0 && !atLeastOneInListsMatch(rightAndLeftHandSide, assignedOnLineAbove) { - p.addWhitespaceBeforeError(t, reasonExprCuddlingNonAssignedVar) - } - case *ast.RangeStmt: - if nStatementsBefore(2) { - reportNewlineTwoLinesAbove(t, statements[i-1], reasonOnlyOneCuddleBeforeRange) - continue - } - - if !atLeastOneInListsMatch(rightAndLeftHandSide, assignedOnLineAbove) { - if !atLeastOneInListsMatch(assignedOnLineAbove, identifiersUsedInBlock) { - p.addWhitespaceBeforeError(t, reasonRangeCuddledWithoutUse) - } - } - case *ast.DeferStmt: - if _, ok := previousStatement.(*ast.DeferStmt); ok { - // We may cuddle multiple defers to group logic. - continue - } - - if nStatementsBefore(2) { - // We allow cuddling defer if the defer references something - // used two lines above. - // There are several reasons to why we do this. - // Originally there was a special use case only for "Close" - // - // https://github.com/bombsimon/wsl/issues/31 which links to - // resp, err := client.Do(req) - // if err != nil { - // return err - // } - // defer resp.Body.Close() - // - // After a discussion in a followup issue it makes sense to not - // only hard code `Close` but for anything that's referenced two - // statements above. - // - // https://github.com/bombsimon/wsl/issues/85 - // db, err := OpenDB() - // require.NoError(t, err) - // defer db.Close() - // - // All of this is only allowed if there's exactly three cuddled - // statements, otherwise the regular rules apply. - if !nStatementsBefore(3) && !nStatementsAfter(1) { - variablesTwoLinesAbove := append(p.findLHS(statements[i-2]), p.findRHS(statements[i-2])...) - if atLeastOneInListsMatch(rightHandSide, variablesTwoLinesAbove) { - continue - } - } - - reportNewlineTwoLinesAbove(t, statements[i-1], reasonOnlyOneCuddleBeforeDefer) - - continue - } - - // Be extra nice with RHS, it's common to use this for locks: - // m.Lock() - // defer m.Unlock() - previousRHS := p.findRHS(previousStatement) - if atLeastOneInListsMatch(rightHandSide, previousRHS) { - continue - } - - // Allow use to cuddled defer func literals with usages on line - // above. Example: - // b := getB() - // defer func() { - // makesSenseToUse(b) - // }() - if c, ok := t.Call.Fun.(*ast.FuncLit); ok { - funcLitFirstStmt := append(p.findLHS(c.Body), p.findRHS(c.Body)...) - - if atLeastOneInListsMatch(assignedOnLineAbove, funcLitFirstStmt) { - continue - } - } - - if atLeastOneInListsMatch(assignedOnLineAbove, identifiersUsedInBlock) { - continue - } - - if !atLeastOneInListsMatch(rightAndLeftHandSide, assignedOnLineAbove) { - p.addWhitespaceBeforeError(t, reasonDeferCuddledWithOtherVar) - } - case *ast.ForStmt: - if len(rightAndLeftHandSide) == 0 && !p.config.AllowCuddleUsedInBlock { - p.addWhitespaceBeforeError(t, reasonForWithoutCondition) - continue - } - - if nStatementsBefore(2) { - reportNewlineTwoLinesAbove(t, statements[i-1], reasonOnlyOneCuddleBeforeFor) - continue - } - - // The same rule applies for ranges as for if statements, see - // comments regarding variable usages on the line before or as the - // first line in the block for details. - if !atLeastOneInListsMatch(rightAndLeftHandSide, assignedOnLineAbove) { - if !atLeastOneInListsMatch(assignedOnLineAbove, identifiersUsedInBlock) { - p.addWhitespaceBeforeError(t, reasonForCuddledAssignWithoutUse) - } - } - case *ast.GoStmt: - if _, ok := previousStatement.(*ast.GoStmt); ok { - continue - } - - if nStatementsBefore(2) { - reportNewlineTwoLinesAbove(t, statements[i-1], reasonOnlyOneCuddleBeforeGo) - continue - } - - if c, ok := t.Call.Fun.(*ast.SelectorExpr); ok { - goCallArgs := append(p.findLHS(c.X), p.findRHS(c.X)...) - - if atLeastOneInListsMatch(calledOnLineAbove, goCallArgs) { - continue - } - } - - if c, ok := t.Call.Fun.(*ast.FuncLit); ok { - goCallArgs := append(p.findLHS(c.Body), p.findRHS(c.Body)...) - - if atLeastOneInListsMatch(assignedOnLineAbove, goCallArgs) { - continue - } - } - - if !atLeastOneInListsMatch(rightAndLeftHandSide, assignedOnLineAbove) { - p.addWhitespaceBeforeError(t, reasonGoFuncWithoutAssign) - } - case *ast.SwitchStmt: - if nStatementsBefore(2) { - reportNewlineTwoLinesAbove(t, statements[i-1], reasonOnlyOneCuddleBeforeSwitch) - continue - } - - if !atLeastOneInListsMatch(rightAndLeftHandSide, assignedOnLineAbove) { - if len(rightAndLeftHandSide) == 0 { - if p.config.AllowCuddleUsedInBlock { - continue - } - - p.addWhitespaceBeforeError(t, reasonAnonSwitchCuddled) - } else { - p.addWhitespaceBeforeError(t, reasonSwitchCuddledWithoutUse) - } - } - case *ast.TypeSwitchStmt: - if nStatementsBefore(2) { - reportNewlineTwoLinesAbove(t, statements[i-1], reasonOnlyOneCuddleBeforeTypeSwitch) - continue - } - - // Allowed to type assert on variable assigned on line above. - if !atLeastOneInListsMatch(rightHandSide, assignedOnLineAbove) { - // Allow type assertion on variables used in the first case - // immediately. - if !atLeastOneInListsMatch(assignedOnLineAbove, identifiersUsedInBlock) { - p.addWhitespaceBeforeError(t, reasonTypeSwitchCuddledWithoutUse) - } - } - case *ast.CaseClause, *ast.CommClause: - // Case clauses will be checked by not allowing leading of trailing - // whitespaces within the block. There's nothing in the case itself - // that may be cuddled. - default: - p.addWarning(warnStmtNotImplemented, t.Pos(), t) - } - } -} - -// firstBodyStatement returns the first statement inside a body block. This is -// because variables may be cuddled with conditions or statements if it's used -// directly as the first argument inside a body. -// The body will then be parsed as a *ast.BlockStmt (regular block) or as a list -// of []ast.Stmt (case block). -func (p *processor) firstBodyStatement(i int, allStmt []ast.Stmt) ast.Node { - stmt := allStmt[i] - - // Start by checking if the statement has a body (probably if-statement, - // a range, switch case or similar. Whenever a body is found we start by - // parsing it before moving on in the AST. - statementBody := reflect.Indirect(reflect.ValueOf(stmt)).FieldByName("Body") - - // Some cases allow cuddling depending on the first statement in a body - // of a block or case. If possible extract the first statement. - var firstBodyStatement ast.Node - - if !statementBody.IsValid() { - return firstBodyStatement - } - - switch statementBodyContent := statementBody.Interface().(type) { - case *ast.BlockStmt: - if len(statementBodyContent.List) > 0 { - firstBodyStatement = statementBodyContent.List[0] - - // If the first body statement is a *ast.CaseClause we're - // actually interested in the **next** body to know what's - // inside the first case. - if x, ok := firstBodyStatement.(*ast.CaseClause); ok { - if len(x.Body) > 0 { - firstBodyStatement = x.Body[0] - } - } - } - - // If statement bodies will be parsed already when finding block bodies. - // The reason is because if/else-if/else chains is nested in the AST - // where the else bit is a part of the if statement. Since if statements - // is the only statement that can be chained like this we exclude it - // from parsing it again here. - if _, ok := stmt.(*ast.IfStmt); !ok { - p.parseBlockBody(nil, statementBodyContent) - } - case []ast.Stmt: - // The Body field for an *ast.CaseClause or *ast.CommClause is of type - // []ast.Stmt. We must check leading and trailing whitespaces and then - // pass the statements to parseBlockStatements to parse it's content. - var nextStatement ast.Node - - // Check if there's more statements (potential cases) after the - // current one. - if len(allStmt)-1 > i { - nextStatement = allStmt[i+1] - } - - p.findLeadingAndTrailingWhitespaces(nil, stmt, nextStatement) - p.parseBlockStatements(statementBodyContent) - default: - p.addWarning( - warnBodyStmtTypeNotImplemented, - stmt.Pos(), statementBodyContent, - ) - } - - return firstBodyStatement -} - -// findUsedVariablesInStatement processes a statement, -// returning a union of all variables used within it. -func (p *processor) findUsedVariablesInStatement(stmt ast.Stmt) []string { - var ( - used []string - seen = map[string]struct{}{} - ) - - // ast.Inspect walks the AST of the statement. - ast.Inspect(stmt, func(n ast.Node) bool { - // We're only interested in identifiers. - if ident, ok := n.(*ast.Ident); ok { - if _, exists := seen[ident.Name]; !exists { - seen[ident.Name] = struct{}{} - - used = append(used, ident.Name) - } - } - - // Continue walking the AST. - return true - }) - - return used -} - -func (p *processor) findLHS(node ast.Node) []string { - var lhs []string - - if node == nil { - return lhs - } - - switch t := node.(type) { - case *ast.BasicLit, *ast.FuncLit, *ast.SelectStmt, - *ast.LabeledStmt, *ast.ForStmt, *ast.SwitchStmt, - *ast.ReturnStmt, *ast.GoStmt, *ast.CaseClause, - *ast.CommClause, *ast.CallExpr, *ast.UnaryExpr, - *ast.BranchStmt, *ast.TypeSpec, *ast.ChanType, - *ast.DeferStmt, *ast.TypeAssertExpr, *ast.RangeStmt: - // Nothing to add to LHS - case *ast.IncDecStmt: - return p.findLHS(t.X) - case *ast.Ident: - return []string{t.Name} - case *ast.AssignStmt: - for _, v := range t.Lhs { - lhs = append(lhs, p.findLHS(v)...) - } - case *ast.GenDecl: - for _, v := range t.Specs { - lhs = append(lhs, p.findLHS(v)...) - } - case *ast.ValueSpec: - for _, v := range t.Names { - lhs = append(lhs, p.findLHS(v)...) - } - case *ast.BlockStmt: - for _, v := range t.List { - lhs = append(lhs, p.findLHS(v)...) - } - case *ast.BinaryExpr: - return append( - p.findLHS(t.X), - p.findLHS(t.Y)..., - ) - case *ast.DeclStmt: - return p.findLHS(t.Decl) - case *ast.IfStmt: - return p.findLHS(t.Cond) - case *ast.TypeSwitchStmt: - return p.findLHS(t.Assign) - case *ast.SendStmt: - return p.findLHS(t.Chan) - default: - if x, ok := maybeX(t); ok { - return p.findLHS(x) - } - - p.addWarning(warnUnknownLHS, t.Pos(), t) - } - - return lhs -} - -func (p *processor) findRHS(node ast.Node) []string { - var rhs []string - - if node == nil { - return rhs - } - - switch t := node.(type) { - case *ast.BasicLit, *ast.SelectStmt, *ast.ChanType, - *ast.LabeledStmt, *ast.DeclStmt, *ast.BranchStmt, - *ast.TypeSpec, *ast.ArrayType, *ast.CaseClause, - *ast.CommClause, *ast.MapType, *ast.FuncLit: - // Nothing to add to RHS - case *ast.Ident: - return []string{t.Name} - case *ast.SelectorExpr: - // TODO: Should this be RHS? - // t.X is needed for defer as of now and t.Sel needed for special - // functions such as Lock() - rhs = p.findRHS(t.X) - rhs = append(rhs, p.findRHS(t.Sel)...) - case *ast.AssignStmt: - for _, v := range t.Rhs { - rhs = append(rhs, p.findRHS(v)...) - } - case *ast.CallExpr: - for _, v := range t.Args { - rhs = append(rhs, p.findRHS(v)...) - } - - rhs = append(rhs, p.findRHS(t.Fun)...) - case *ast.CompositeLit: - for _, v := range t.Elts { - rhs = append(rhs, p.findRHS(v)...) - } - case *ast.IfStmt: - rhs = append(rhs, p.findRHS(t.Cond)...) - rhs = append(rhs, p.findRHS(t.Init)...) - case *ast.BinaryExpr: - return append( - p.findRHS(t.X), - p.findRHS(t.Y)..., - ) - case *ast.TypeSwitchStmt: - return p.findRHS(t.Assign) - case *ast.ReturnStmt: - for _, v := range t.Results { - rhs = append(rhs, p.findRHS(v)...) - } - case *ast.BlockStmt: - for _, v := range t.List { - rhs = append(rhs, p.findRHS(v)...) - } - case *ast.SwitchStmt: - return p.findRHS(t.Tag) - case *ast.GoStmt: - return p.findRHS(t.Call) - case *ast.ForStmt: - return p.findRHS(t.Cond) - case *ast.DeferStmt: - return p.findRHS(t.Call) - case *ast.SendStmt: - return p.findLHS(t.Value) - case *ast.IndexExpr: - rhs = append(rhs, p.findRHS(t.Index)...) - rhs = append(rhs, p.findRHS(t.X)...) - case *ast.SliceExpr: - rhs = append(rhs, p.findRHS(t.X)...) - rhs = append(rhs, p.findRHS(t.Low)...) - rhs = append(rhs, p.findRHS(t.High)...) - case *ast.KeyValueExpr: - rhs = p.findRHS(t.Key) - rhs = append(rhs, p.findRHS(t.Value)...) - default: - if x, ok := maybeX(t); ok { - return p.findRHS(x) - } - - p.addWarning(warnUnknownRHS, t.Pos(), t) - } - - return rhs -} - -func (p *processor) isShortDecl(node ast.Node) bool { - if t, ok := node.(*ast.AssignStmt); ok { - return t.Tok == token.DEFINE - } - - return false -} - -func (p *processor) findBlockStmt(node ast.Node) []*ast.BlockStmt { - var blocks []*ast.BlockStmt - - switch t := node.(type) { - case *ast.BlockStmt: - return []*ast.BlockStmt{t} - case *ast.AssignStmt: - for _, x := range t.Rhs { - blocks = append(blocks, p.findBlockStmt(x)...) - } - case *ast.CallExpr: - blocks = append(blocks, p.findBlockStmt(t.Fun)...) - - for _, x := range t.Args { - blocks = append(blocks, p.findBlockStmt(x)...) - } - case *ast.FuncLit: - blocks = append(blocks, t.Body) - case *ast.ExprStmt: - blocks = append(blocks, p.findBlockStmt(t.X)...) - case *ast.ReturnStmt: - for _, x := range t.Results { - blocks = append(blocks, p.findBlockStmt(x)...) - } - case *ast.DeferStmt: - blocks = append(blocks, p.findBlockStmt(t.Call)...) - case *ast.GoStmt: - blocks = append(blocks, p.findBlockStmt(t.Call)...) - case *ast.IfStmt: - blocks = append([]*ast.BlockStmt{t.Body}, p.findBlockStmt(t.Else)...) - } - - return blocks -} - -// maybeX extracts the X field from an AST node and returns it with a true value -// if it exists. If the node doesn't have an X field nil and false is returned. -// Known fields with X that are handled: -// IndexExpr, ExprStmt, SelectorExpr, StarExpr, ParentExpr, TypeAssertExpr, -// RangeStmt, UnaryExpr, ParenExpr, SliceExpr, IncDecStmt. -func maybeX(node any) (ast.Node, bool) { - maybeHasX := reflect.Indirect(reflect.ValueOf(node)).FieldByName("X") - if !maybeHasX.IsValid() { - return nil, false - } - - n, ok := maybeHasX.Interface().(ast.Node) - if !ok { - return nil, false - } - - return n, true -} - -func atLeastOneInListsMatch(listOne, listTwo []string) bool { - sliceToMap := func(s []string) map[string]struct{} { - m := map[string]struct{}{} - - for _, v := range s { - m[v] = struct{}{} - } - - return m - } - - m1 := sliceToMap(listOne) - m2 := sliceToMap(listTwo) - - for k1 := range m1 { - if _, ok := m2[k1]; ok { - return true - } - } - - for k2 := range m2 { - if _, ok := m1[k2]; ok { - return true - } - } - - return false -} - -// findLeadingAndTrailingWhitespaces will find leading and trailing whitespaces -// in a node. The method takes comments in consideration which will make the -// parser more gentle. -func (p *processor) findLeadingAndTrailingWhitespaces(ident *ast.Ident, stmt, nextStatement ast.Node) { - var ( - commentMap = ast.NewCommentMap(p.fileSet, stmt, p.file.Comments) - blockStatements []ast.Stmt - blockStartLine int - blockEndLine int - blockStartPos token.Pos - blockEndPos token.Pos - isCase bool - ) - - // Depending on the block type, get the statements in the block and where - // the block starts (and ends). - switch t := stmt.(type) { - case *ast.BlockStmt: - blockStatements = t.List - blockStartPos = t.Lbrace - blockEndPos = t.Rbrace - case *ast.CaseClause: - blockStatements = t.Body - blockStartPos = t.Colon - isCase = true - case *ast.CommClause: - blockStatements = t.Body - blockStartPos = t.Colon - isCase = true - default: - p.addWarning(warnWSNodeTypeNotImplemented, stmt.Pos(), stmt) - - return - } - - // Ignore empty blocks even if they have newlines or just comments. - if len(blockStatements) < 1 { - return - } - - blockStartLine = p.fileSet.Position(blockStartPos).Line - blockEndLine = p.fileSet.Position(blockEndPos).Line - - // No whitespace possible if LBrace and RBrace is on the same line. - if blockStartLine == blockEndLine { - return - } - - var ( - firstStatement = blockStatements[0] - lastStatement = blockStatements[len(blockStatements)-1] - ) - - // Get the comment related to the first statement, we do allow comments in - // the beginning of a block before the first statement. - var ( - openingNodePos = blockStartPos + 1 - lastLeadingComment ast.Node - ) - - var ( - firstStatementCommentGroups []*ast.CommentGroup - lastStatementCommentGroups []*ast.CommentGroup - ) - - if cg, ok := commentMap[firstStatement]; ok && !isCase { - firstStatementCommentGroups = cg - } else { - // TODO: Just like with trailing whitespaces comments in a case block is - // tied to the last token of the first statement. For now we iterate over - // all comments in the stmt and grab those that's after colon and before - // first statement. - for _, cg := range commentMap { - if len(cg) < 1 { - continue - } - - // If we have comments and the last comment ends before the first - // statement and the node is after the colon, this must be the node - // mapped to comments. - for _, c := range cg { - if c.End() < firstStatement.Pos() && c.Pos() > blockStartPos { - firstStatementCommentGroups = append(firstStatementCommentGroups, c) - } - } - - // And same if we have comments where the first comment is after the - // last statement but before the next statement (next case). As with - // the other things, if there is not next statement it's no next - // case and the logic will be handled when parsing the block. - if nextStatement == nil { - continue - } - - for _, c := range cg { - if c.Pos() > lastStatement.End() && c.End() < nextStatement.Pos() { - lastStatementCommentGroups = append(lastStatementCommentGroups, c) - } - } - } - - // Since the comments come from a map they might not be ordered meaning - // that the last and first comment groups can be in the wrong order. We - // fix this by sorting all comments by pos after adding them all to the - // slice. - sort.Slice(firstStatementCommentGroups, func(i, j int) bool { - return firstStatementCommentGroups[i].Pos() < firstStatementCommentGroups[j].Pos() - }) - - sort.Slice(lastStatementCommentGroups, func(i, j int) bool { - return lastStatementCommentGroups[i].Pos() < lastStatementCommentGroups[j].Pos() - }) - } - - for _, commentGroup := range firstStatementCommentGroups { - // If the comment group is on the same line as the block start - // (LBrace) we should not consider it. - if p.nodeEnd(commentGroup) == blockStartLine { - openingNodePos = commentGroup.End() - continue - } - - // We only care about comments before our statement from the comment - // map. As soon as we hit comments after our statement let's break - // out! - if commentGroup.Pos() > firstStatement.Pos() { - break - } - - // We never allow leading whitespace for the first comment. - if lastLeadingComment == nil && p.nodeStart(commentGroup)-1 != blockStartLine { - p.addErrorRange( - openingNodePos, - openingNodePos, - commentGroup.Pos(), - reasonBlockStartsWithWS, - ) - } - - // If lastLeadingComment is set this is not the first comment so we - // should remove whitespace between them if we don't explicitly - // allow it. - if lastLeadingComment != nil && !p.config.AllowSeparatedLeadingComment { - if p.nodeStart(commentGroup)+1 != p.nodeEnd(lastLeadingComment) { - p.addErrorRange( - openingNodePos, - lastLeadingComment.End(), - commentGroup.Pos(), - reasonBlockStartsWithWS, - ) - } - } - - lastLeadingComment = commentGroup - } - - lastNodePos := openingNodePos - if lastLeadingComment != nil { - lastNodePos = lastLeadingComment.End() - blockStartLine = p.nodeEnd(lastLeadingComment) - } - - // Check if we have a whitespace between the last node which can be the - // Lbrace, a comment on the same line or the last comment if we have - // comments inside the actual block and the first statement. This is never - // allowed. - if p.nodeStart(firstStatement)-1 != blockStartLine { - p.addErrorRange( - openingNodePos, - lastNodePos, - firstStatement.Pos(), - reasonBlockStartsWithWS, - ) - } - - // If the blockEndLine is not 0 we're a regular block (not case). - if blockEndLine != 0 { - // We don't want to reject example functions since they have to end with - // a comment. - if isExampleFunc(ident) { - return - } - - var ( - lastNode ast.Node = lastStatement - trailingComments []ast.Node - ) - - // Check if we have an comments _after_ the last statement and update - // the last node if so. - if c, ok := commentMap[lastStatement]; ok { - lastComment := c[len(c)-1] - if lastComment.Pos() > lastStatement.End() && lastComment.Pos() < stmt.End() { - lastNode = lastComment - } - } - - // TODO: This should be improved. - // The trailing comments are mapped to the last statement item which can - // be anything depending on what the last statement is. - // In `fmt.Println("hello")`, trailing comments will be mapped to - // `*ast.BasicLit` for the "hello" string. - // A short term improvement can be to cache this but for now we naively - // iterate over all items when we check a block. - for _, commentGroups := range commentMap { - for _, commentGroup := range commentGroups { - if commentGroup.Pos() < lastNode.End() || commentGroup.End() > stmt.End() { - continue - } - - trailingComments = append(trailingComments, commentGroup) - } - } - - // TODO: Should this be relaxed? - // Given the old code we only allowed trailing newline if it was - // directly tied to the last statement so for backwards compatibility - // we'll do the same. This means we fail all but the last whitespace - // even when allowing trailing comments. - for _, comment := range trailingComments { - if p.nodeStart(comment)-p.nodeEnd(lastNode) > 1 { - p.addErrorRange( - blockEndPos, - lastNode.End(), - comment.Pos(), - reasonBlockEndsWithWS, - ) - } - - lastNode = comment - } - - if !p.config.AllowTrailingComment && p.nodeEnd(stmt)-1 != p.nodeEnd(lastStatement) { - p.addErrorRange( - blockEndPos, - lastNode.End(), - stmt.End()-1, - reasonBlockEndsWithWS, - ) - } - - return - } - - // Nothing to do if we're not looking for enforced newline. - if p.config.ForceCaseTrailingWhitespaceLimit == 0 { - return - } - - // If we don't have any nextStatement the trailing whitespace will be - // handled when parsing the switch. If we do have a next statement we can - // see where it starts by getting it's colon position. We set the end of the - // current case to the position of the next case. - switch nextStatement.(type) { - case *ast.CaseClause, *ast.CommClause: - default: - // No more cases - return - } - - var closingNode ast.Node = lastStatement - for _, commentGroup := range lastStatementCommentGroups { - // TODO: In future versions we might want to close the gaps between - // comments. However this is not currently reported in v3 so we - // won't add this for now. - // if p.nodeStart(commentGroup)-1 != p.nodeEnd(closingNode) {} - closingNode = commentGroup - } - - totalRowsInCase := p.nodeEnd(closingNode) - blockStartLine - if totalRowsInCase < p.config.ForceCaseTrailingWhitespaceLimit { - return - } - - if p.nodeEnd(closingNode)+1 == p.nodeStart(nextStatement) { - p.addErrorRange( - closingNode.Pos(), - closingNode.End(), - closingNode.End(), - reasonCaseBlockTooCuddly, - ) - } -} - -func isExampleFunc(ident *ast.Ident) bool { - return ident != nil && strings.HasPrefix(ident.Name, "Example") -} - -func (p *processor) nodeStart(node ast.Node) int { - return p.fileSet.Position(node.Pos()).Line -} - -func (p *processor) nodeEnd(node ast.Node) int { - line := p.fileSet.Position(node.End()).Line - - if isEmptyLabeledStmt(node) { - return p.fileSet.Position(node.Pos()).Line - } - - return line -} - -func isEmptyLabeledStmt(node ast.Node) bool { - v, ok := node.(*ast.LabeledStmt) - if !ok { - return false - } - - _, empty := v.Stmt.(*ast.EmptyStmt) - - return empty -} - -func (p *processor) addWhitespaceBeforeError(node ast.Node, reason string) { - p.addErrorRange(node.Pos(), node.Pos(), node.Pos(), reason) -} - -func (p *processor) addErrorRange(reportAt, start, end token.Pos, reason string) { - report, ok := p.result[reportAt] - if !ok { - report = result{ - reason: reason, - fixRanges: []fix{}, - } - } - - report.fixRanges = append(report.fixRanges, fix{ - fixRangeStart: start, - fixRangeEnd: end, - }) - - p.result[reportAt] = report -} - -func (p *processor) addWarning(w string, pos token.Pos, t any) { - position := p.fileSet.Position(pos) - - p.warnings = append(p.warnings, - fmt.Sprintf("%s:%d: %s (%T)", position.Filename, position.Line, w, t), - ) -} diff --git a/vendor/github.com/bombsimon/wsl/v5/.gitignore b/vendor/github.com/bombsimon/wsl/v5/.gitignore deleted file mode 100644 index 1c8eba613e..0000000000 --- a/vendor/github.com/bombsimon/wsl/v5/.gitignore +++ /dev/null @@ -1,70 +0,0 @@ - -# Created by https://www.gitignore.io/api/go,vim,macos - -### Go ### -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib - -# Test binary, build with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -### Go Patch ### -/vendor/ -/Godeps/ - -### macOS ### -# 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 - -### Vim ### -# Swap -[._]*.s[a-v][a-z] -[._]*.sw[a-p] -[._]s[a-rt-v][a-z] -[._]ss[a-gi-z] -[._]sw[a-p] - -# Session -Session.vim - -# Temporary -.netrwhist -*~ -# Auto-generated tag files -tags -# Persistent undo -[._]*.un~ - - -# End of https://www.gitignore.io/api/go,vim,macos diff --git a/vendor/github.com/bombsimon/wsl/v5/.golangci.yml b/vendor/github.com/bombsimon/wsl/v5/.golangci.yml deleted file mode 100644 index f97571f8e4..0000000000 --- a/vendor/github.com/bombsimon/wsl/v5/.golangci.yml +++ /dev/null @@ -1,83 +0,0 @@ ---- -version: "2" - -output: - formats: - text: - path: stdout - print-issued-lines: false - -linters: - default: all - disable: - - cyclop - - depguard - - dupl - - dupword - - err113 - - exhaustruct - - forbidigo - - funlen - - gocognit - - gocyclo - - godot - - godox - - lll - - maintidx - - mnd - - nakedret - - nestif - - nlreturn - - noinlineerr - - paralleltest - - prealloc - - rowserrcheck - - tagliatelle - - testpackage - - tparallel - - varnamelen - - wastedassign - - wsl - - settings: - depguard: - rules: - main: - deny: - - pkg: github.com/davecgh/go-spew/spew - desc: not allowed - gocognit: - min-complexity: 10 - gocritic: - # Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` - # to see all tags and checks. Empty list by default. See - # https://github.com/go-critic/go-critic#usage -> section "Tags". - enabled-tags: - - diagnostic - - experimental - - opinionated - - performance - - style - misspell: - locale: US - - exclusions: - presets: - - comments - - common-false-positives - - std-error-handling - -issues: - max-issues-per-linter: 0 - max-same-issues: 0 -formatters: - enable: - - gofmt - - gofumpt - - goimports - settings: - gofmt: - rewrite-rules: - - pattern: "interface{}" - replacement: "any" -# vim: set sw=2 ts=2 et: diff --git a/vendor/github.com/bombsimon/wsl/v5/CHECKS.md b/vendor/github.com/bombsimon/wsl/v5/CHECKS.md deleted file mode 100644 index e630a83115..0000000000 --- a/vendor/github.com/bombsimon/wsl/v5/CHECKS.md +++ /dev/null @@ -1,1316 +0,0 @@ -# Checks - -This document describes all the checks done by `wsl` with examples of what's not -allowed and what's allowed. - -## `assign` - -Assign (`foo := bar`) or re-assignments (`foo = bar`) should only be cuddled -with other assignments or increment/decrement. - - - - - - - -
BadGood
- -```go -if true { - fmt.Println("hello") -} -a := 1 // 1 - -defer func() { - fmt.Println("hello") -}() -a := 1 // 2 -``` - - - -```go -if true { - fmt.Println("hello") -} - -a := 1 - -defer func() { - fmt.Println("hello") -}() - -a := 1 - -a := 1 -b := 2 -c := 3 -``` - -
- -1 Not an assign statement above - -2 Not an assign statement above - - - -
- -## `branch` - -> Configurable via `branch-max-lines` - -Branch statement (`break`, `continue`, `fallthrough`, `goto`) should only be -cuddled if the block is less than `n` lines where `n` is the value of -`branch-max-statements`. - - - - - - - -
BadGood
- -```go -for { - a, err : = SomeFn() - if err != nil { - return err - } - - fmt.Println(a) - break // 1 -} -``` - - - -```go -for { - a, err : = SomeFn() - if err != nil { - return err - } - - fmt.Println(a) - - break -} - -for { - fmt.Println("hello") - break -} -``` - -
- -1 Block is more than 2 lines so should be a blank line above - - - -
- -## `decl` - -Declarations should never be cuddled. When grouping multiple declarations -together they should be declared in the same group with parenthesis into a -single statement. The benefit of this is that it also aligns the declaration or -assignment increasing readability. - -> **NOTE** The fixer can't do smart adjustments if there are comments on the -> same line as the declaration. - - - - - - - -
BadGood
- -```go -var a string -var b int // 1 - -const a = 1 -const b = 2 // 2 - -a := 1 -var b string // 3 - -fmt.Println("hello") -var a string // 4 -``` - - - -```go -var ( - a string - b int -) - -const ( - a = 1 - b = 2 -) - -a := 1 - -var b string - -fmt.Println("hello") - -var a string -``` - -
- -1 Multiple declarations should be grouped to one - -2 Multiple declarations should be grouped to one - -3 Declaration should always have a whitespace above - -4 Declaration should always have a whitespace above - - - -
- -## `defer` - -Deferring execution should only be used directly in the context of what's being -deferred and there should only be one statement above. - - - - - - - -
BadGood
- -```go -val, closeFn := SomeFn() -val2 := fmt.Sprintf("v-%s", val) -fmt.Println(val) -defer closeFn() // 1 - -defer fn1() -a := 1 -defer fn3() // 2 - -f, err := os.Open("/path/to/f.txt") -if err != nil { - return err -} - -lines := ReadFile(f) -trimLines(lines) -defer f.Close() // 3 -``` - - - -```go -val, closeFn := SomeFn() -defer closeFn() - -defer fn1() -defer fn2() -defer fn3() - -f, err := os.Open("/path/to/f.txt") -if err != nil { - return err -} -defer f.Close() - -m.Lock() -defer m.Unlock() -``` - -
- -1 More than a single statement between `defer` and `closeFn` - -2 `a` is not used in expression - -3 More than a single statement between `defer` and `f.Close` - - - -
- -## `expr` - -Expressions can be multiple things and a big part of them are not handled by -`wsl`. However all function calls are expressions which can be verified. - - - - - - - -
BadGood
- -```go -a := 1 -b := 2 -fmt.Println("not b") // 1 -``` - - - -```go -a := 1 -b := 2 - -fmt.Println("not b") - -a := 1 -fmt.Println(a) -``` - -
- -1 `b` is not used in expression - - - -
- -## `for` - -> Configurable via `allow-first-in-block` to allow cuddling if the variable is -> used _first_ in the block (enabled by default). -> -> Configurable via `allow-whole-block` to allow cuddling if the variable is used -> _anywhere_ in the following block (disabled by default). -> -> See [Configuration](#configuration) for details. - - - - - - - -
BadGood
- -```go -i := 0 -for j := 0; j < 3; j++ { // 1 - fmt.Println(j) -} - -a := 0 -i := 3 -for j := 0; j < i; j++ { // 2 - fmt.Println(j) -} - -x := 1 -for { // 3 - fmt.Println("hello") - break -} -``` - - - -```go -i := 0 -for j := 0; j < i; j++ { - fmt.Println(j) -} - -a := 0 - -i := 3 -for j := 0; j < i; j++ { - fmt.Println(j) -} - -// Allowed with `allow-first-in-block` -x := 1 -for { - x++ - break -} - -// Allowed with `allow-whole-block` -x := 1 -for { - fmt.Println("hello") - - if shouldIncrement() { - x++ - } -} -``` - -
- -1 `i` is not used in expression - -2 More than one variable above statement - -3 No variable in expression - - - -
- -## `go` - - - - - - - -
BadGood
- -```go -someFunc := func() {} -go anotherFunc() // 1 - -x := 1 -go func () // 2 - fmt.Println(y) -}() - -someArg := 1 -go Fn(notArg) // 3 -``` - - - -```go -someFunc := func() {} -go someFunc() - -x := 1 -go func (s string) { - fmt.Println(s) -}(x) - -someArg := 1 -go Fn(someArg) -``` - -
- -1 `someFunc` is not used in expression - -2 `x` is not used in expression - -3 `someArg` is not used in expression - - - -
- -## `if` - -> Configurable via `allow-first-in-block` to allow cuddling if the variable is -> used _first_ in the block (enabled by default). -> -> Configurable via `allow-whole-block` to allow cuddling if the variable is used -> _anywhere_ in the following block (disabled by default). -> -> See [Configuration](#configuration) for details. - -`if` statements are one of several block statements (a statement with a block) -that can have some form of expression or condition. To make block context more -readable, only one variable is allowed immediately above the `if` statement and -the variable must be used in the condition (unless configured otherwise). - - - - - - - -
BadGood
- -```go -x := 1 -if y > 1 { // 1 - fmt.Println("y > 1") -} - -a := 1 -b := 2 -if b > 1 { // 2 - fmt.Println("a > 1") -} - -a := 1 -b := 2 -if a > 1 { // 3 - fmt.Println("a > 1") -} - -a := 1 -b := 2 -if notEvenAOrB() { // 4 - fmt.Println("not a or b") -} - -a := 1 -x, err := SomeFn() // 5 -if err != nil { - return err -} -``` - - - -```go -x := 1 - -if y > 1 { - fmt.Println("y > 1") -} - -a := 1 - -b := 2 -if b > 1 { - fmt.Println("a > 1") -} - -b := 2 - -a := 1 -if a > 1 { - fmt.Println("a > b") -} - -a := 1 -b := 2 - -if notEvenAOrB() { - fmt.Println("not a or b") -} - -a := 1 - -x, err := SomeFn() -if err != nil { - return err -} - -// Allowed with `allow-first-in-block` -x := 1 -if xUsedFirstInBlock() { - x = 2 -} - -// Allowed with `allow-whole-block` -x := 1 -if xUsedLaterInBlock() { - fmt.Println("will use x later") - - if orEvenNestedWouldWork() { - x = 3 - } -} -``` - -
- -1 `x` is not used in expression - -2 More than one variable above statement - -3 `b` is not used in expression and too many statements - -4 No variable in expression - -5 More than one variable above statement - - - -
- -## `inc-dec` - - - - - - - -
BadGood
- -```go -i := 1 - -if true { - fmt.Println("hello") -} -i++ // 1 - -defer func() { - fmt.Println("hello") -}() -i++ // 2 -``` - - - -```go -i := 1 -i++ - -i-- -j := i -j++ -``` - -
- -1 Not an assign or inc/dec statement above - -2 Not an assign or inc/dec statement above - - - -
- -## `label` - -Labels should never be cuddled. Labels in itself is often a symptom of big scope -and split context and because of that should always have an empty line above. - - - - - - - -
BadGood
- -```go -L1: - if true { - _ = 1 - } -L2: // 1 - if true { - _ = 1 - } -``` - - - -```go -L1: - if true { - _ = 1 - } - -L2: - if true { - _ = 1 - } -``` - -
- -1 Labels should always have a whitespabe above - - - -
- -## `range` - -> Configurable via `allow-first-in-block` to allow cuddling if the variable is -> used _first_ in the block (enabled by default). -> -> Configurable via `allow-whole-block` to allow cuddling if the variable is used -> _anywhere_ in the following block (disabled by default). -> -> See [Configuration](#configuration) for details. - - - - - - - -
BadGood
- -```go -someRange := []int{1, 2, 3} -for _, i := range thisIsNotSomeRange { // 1 - fmt.Println(i) -} - -x := 1 -for i := range make([]int, 3) { // 2 - fmt.Println("hello") - break -} - -s1 := []int{1, 2, 3} -s2 := []int{3, 2, 1} -for _, v := range s2 { // 3 - fmt.Println(v) -} -``` - - - -```go -someRange := []int{1, 2, 3} - -for _, i := range thisIsNotSomeRange { - fmt.Println(i) -} - -someRange := []int{1, 2, 3} -for _, i := range someRange { - fmt.Println(i) -} - -notARange := 1 -for i := range returnsRange(notARange) { - fmt.Println(i) -} - -s1 := []int{1, 2, 3} - -s2 := []int{3, 2, 1} -for _, v := range s2 { - fmt.Println(v) -} -``` - -
- -1 `someRange` is not used in expression - -2 `x` is not used in expression - -3 More than one variable above statement - - - -
- -## `return` - -> Configurable via `branch-max-lines` - -Return statements is an important statement that is easiy to miss in larger code -blocks. To better visualize the `return` statement and that the method is -returning it should always be followed by a blank line unless the scope is as -small as `branch-max-lines`. - - - - - - - -
BadGood
- -```go -func Fn() int { - x, err := someFn() - if err != nil { - panic(err) - } - - fmt.Println(x) - return // 1 -} -``` - - - -```go -func Fn() int { - x, err := someFn() - if err != nil { - panic(err) - } - - fmt.Println(x) - - return -} -``` - -
- -1 Block is more than 2 lines so should be a blank line above - - - -
- -## `select` - -Identifiers used in case arms of select statements are allowed to be cuddled. - -> Configurable via `allow-first-in-block` to allow cuddling if the variable is -> used _first_ in the block (enabled by default). -> -> Configurable via `allow-whole-block` to allow cuddling if the variable is used -> _anywhere_ in the following block (disabled by default). -> -> See [Configuration](#configuration) for details. - - - - - - - -
BadGood
- -```go -x := 0 -select { // 1 -case <-time.After(time.Second): - // ... -case <-stop: - // ... -} -``` - - - -```go -stop := make(chan struct{}) -select { -case <-time.After(time.Second): - // ... -case <-stop: - // ... -} - -x := 0 - -select { -case <-time.After(time.Second): - // ... -case <-stop: - // ... -} - -// Allowed with `allow-whole-block` -x := 1 -select { -case <-time.After(time.Second): - // ... -case <-stop: - Fn(x) -} -``` - -
- -1 `x` is not used in expression - - - -
- -## `send` - -Send statements should only be cuddled with a single variable that is used on -the line above. - - - - - - - -
BadGood
- -```go -a := 1 -ch <- 1 // 1 - -b := 2 -<-ch // 2 -``` - - - -```go -a := 1 -ch <- a - -b := 1 - -<-ch -``` - -
- -1 `a` is not used in expression - -2 `b` is not used in expression - - - -
- -## `switch` - -In addition to checking the switch condition, switch statements also checks -identifiers in all case arms. If a variable is used in one or more of the case -arms it's allowed to be cuddled. - -> Configurable via `allow-first-in-block` to allow cuddling if the variable is -> used _first_ in the block (enabled by default). -> -> Configurable via `allow-whole-block` to allow cuddling if the variable is used -> _anywhere_ in the following block (disabled by default). -> -> See [Configuration](#configuration) for details. - - - - - - - -
BadGood
- -```go -x := 0 -switch y { // 1 -case 1: - // ... -case 2: - // ... -} - - -x := 0 -y := 1 -switch y { // 2 -case 1: - // ... -case 2: - // ... -} -``` - - - -```go -n := 1 -switch n { -case 1: - // ... -case 2: - // ... -} - -n := 1 -switch { -case n < 1: - // ... -case n > 1: - // ... -} - -x := 0 - -switch y { -case 1: - // ... -case 2: - // ... -} - - -x := 0 - -y := 1 -switch y { -case 1: - // ... -case 2: - // ... -} - -// Allowed with `allow-whole-block` -x := 1 -switch y { -case 1: - // ... -case 2: - fmt.Println(x) -} -``` - -
- -1 `x` is not used in expression - -2 More than one variable above statement - - - -
- -## `type-switch` - -> Configurable via `allow-first-in-block` to allow cuddling if the variable is -> used _first_ in the block (enabled by default). -> -> Configurable via `allow-whole-block` to allow cuddling if the variable is used -> _anywhere_ in the following block (disabled by default). -> -> See [Configuration](#configuration) for details. - - - - - - - -
BadGood
- -```go -x := someType() -switch y.(type) { // 1 -case int32: - // ... -case int64: - // ... -} - - -x := 0 -y := someType() -switch y.(type) { -case int32: - // ... -case int64: - // ... -} -``` - - - -```go -x := someType() - -switch y.(type) { -case int32: - // ... -case int64: - // ... -} - - -x := 0 - -y := someType() -switch y.(type) { -case int32: - // ... -case int64: - // ... -} - -// Allowed with `allow-whole-block` -x := 1 -switch y.(type) { -case int32: - // ... -case int64: - fmt.Println(x) -} -``` - -
- -1 `x` is not used in expression - - - -
- -## `append` - -Append enables strict `append` checking where assignments that are -re-assignments with `append` (e.g. `x = append(x, y)`) is only allowed to be -cuddled with other assignments if the `append` uses the variable on the line -above. - - - - - - - -
BadGood
- -```go -s := []string{} - -a := 1 -s = append(s, 2) // 1 -b := 3 -s = append(s, a) // 2 -``` - - - -```go -s := []string{} - -a := 1 -s = append(s, a) - -b := 3 - -s = append(s, 2) -``` - -
- -1 `a` is not used in append - -2 `b` is not used in append - - - -
- -## `assign-exclusive` - -Assign exclusive does not allow mixing new assignments (`:=`) with -re-assignments (`=`). - - - - - - - -
BadGood
- -```go -a := 1 -b = 2 // 1 -c := 3 // 2 -d = 4 // 3 -``` - - - -```go -a := 1 -c := 3 - -b = 2 -d = 4 -``` - -
- -1 `a` is not a re-assignment - -2 `b` is not a new assignment - -3 `c` is not a re-assignment - - - -
- -## `assign-expr` - -Assignments are allowed to be cuddled with expressions, primarily to support -mixing assignments and function calls which can often make sense in shorter -flows. By enabling this check `wsl` will ensure assignments are not cuddled with -expressions. - - - - - - - -
BadGood
- -```go -t1.Fn1() -x := t1.Fn2() // 1 -t1.Fn3() -``` - - - -```go -t1.Fn1() - -x := t1.Fn2() -t1.Fn3() -``` - -
- -1 Line above is not an assignment - - - -
- -## `err` - - - - - - - -
BadGood
- -```go -_, err := SomeFn() - -if err != nil { // 1 - return fmt.Errorf("failed to fn: %w", err) -} -``` - - - -```go -_, err := SomeFn() -if err != nil { - return fmt.Errorf("failed to fn: %w", err) -} -``` - -
- -1 Whitespace between error assignment and error checking - - - -
- -## `leading-whitespace` - - - - - - -
BadGood
- -```go -if true { - - fmt.Println("hello") -} -``` - - - -```go -if true { - fmt.Println("hello") -} -``` - -
- -## `trailing-whitespace` - - - - - - -
BadGood
- -```go -if true { - fmt.Println("hello") - -} -``` - - - -```go -if true { - fmt.Println("hello") -} -``` - -
- -## Configuration - -One shared logic across different checks is the logic around statements -containing a block, i.e. a statement with a following `{}` (e.g. `if`, `for`, -`switch` etc). - -`wsl` only allows one statement immediately above and that statement must also -be referenced in the expression in the statement with the block. E.g. - -```go -someVariable := true -if someVariable { - // Here `someVariable` used in the `if` expression is the only variable - // immediately above the statement. -} -``` - -This can be configured to be more "laxed" by also allowing a single statement -immediately above if it's used either first in the following block or anywhere -inside the following block. - -### `allow-first-in-block` - -By setting this to true (default), the variable doesn't have to be used in the -expression itself but is also allowed if it's the first statement in the block -body. - -```go -someVariable := 1 -if anotherVariable { - someVariable++ -} -``` - -### `allow-whole-block` - -This is similar to `allow-first-in-block` but now allows the lack of whitespace -if it's used anywhere in the following block. - -```go -someVariable := 1 -if anotherVariable { - someFn(yetAnotherVariable) - - if stillNotSomeVariable { - someVariable++ - } -} -``` diff --git a/vendor/github.com/bombsimon/wsl/v5/LICENSE b/vendor/github.com/bombsimon/wsl/v5/LICENSE deleted file mode 100644 index f881b648ef..0000000000 --- a/vendor/github.com/bombsimon/wsl/v5/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2018 - 2025 Simon Sawert - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/bombsimon/wsl/v5/README.md b/vendor/github.com/bombsimon/wsl/v5/README.md deleted file mode 100644 index 449e887108..0000000000 --- a/vendor/github.com/bombsimon/wsl/v5/README.md +++ /dev/null @@ -1,183 +0,0 @@ -# wsl - whitespace linter - -[![GitHub Actions](https://github.com/bombsimon/wsl/actions/workflows/go.yml/badge.svg)](https://github.com/bombsimon/wsl/actions/workflows/go.yml) -[![Coverage Status](https://coveralls.io/repos/github/bombsimon/wsl/badge.svg?branch=main)](https://coveralls.io/github/bombsimon/wsl?branch=main) - -`wsl` (**w**hite**s**pace **l**inter) is a linter that wants you to use empty -lines to separate grouping of different types to increase readability. There are -also a few places where it encourages you to _remove_ whitespaces which is at -the start and the end of blocks or between assigning and error checking. - -## Checks and configuration - -Each check can be disabled or enabled individually to the point where no checks -can be run. The idea with this is to attract more users. Some checks have -configuration that affect how they work but most of them can only be turned on -or off. - -### Checks - -This is an exhaustive list of all the checks that can be enabled or disabled and -their default value. The names are the same as the Go -[AST](https://pkg.go.dev/go/ast) type name for built-ins. - -The base rule is that statements that has a block (e.g. `for`, `range`, -`switch`, `if` etc) should always only be directly adjacent with a single -variable and only if it's used in the expression in the block itself. - -For more details and examples, see [CHECKS](CHECKS.md). - -✅ = enabled by default, ❌ = disabled by default - -#### Built-ins and keywords - -- ✅ **assign** - Assignments should only be cuddled with other assignments, - or increment/decrement -- ✅ **branch** - Branch statement (`break`, `continue`, `fallthrough`, `goto`) - should only be cuddled if the block is less than `n` lines where `n` is the - value of [`branch-max-lines`](#configuration) -- ✅ **decl** - Declarations should never be cuddled -- ✅ **defer** - Defer should only be cuddled with other `defer`, after error - checking or with a single variable used on the line above -- ✅ **expr** - Expressions are e.g. function calls or index expressions, they - should only be cuddled with variables used on the line above -- ✅ **for** - For loops should only be cuddled with a single variable used on - the line above -- ✅ **go** - Go should only be cuddled with other `go` or a single variable - used on the line above -- ✅ **if** - If should only be cuddled with a single variable used on the line - above -- ✅ **inc-dec** - Increment/decrement (`++/--`) has the same rules as `assign` -- ✅ **label** - Labels should never be cuddled -- ✅ **range** - Range should only be cuddled with a single variable used on the - line above -- ✅ **return** - Return should only be cuddled if the block is less than `n` - lines where `n` is the value of [`branch-max-lines`](#configuration) -- ✅ **select** - Select should only be cuddled with a single variable used on - the line above -- ✅ **send** - Send should only be cuddled with a single variable used on the - line above -- ✅ **switch** - Switch should only be cuddled with a single variable used on - the line above -- ✅ **type-switch** - Type switch should only be cuddled with a single variable - used on the line above - -#### Specific `wsl` cases - -- ✅ **append** - Only allow re-assigning with `append` if the value being - appended exist on the line above -- ❌ **assign-exclusive** - Only allow cuddling either new variables or - re-assigning of existing ones -- ❌ **assign-expr** - Don't allow assignments to be cuddled with expressions, - e.g. function calls -- ✅ **err** - Error checking must follow immediately after the error variable - is assigned -- ✅ **leading-whitespace** - Disallow leading empty lines in blocks -- ✅ **trailing-whitespace** - Disallow trailing empty lines in blocks - -### Configuration - -Other than enabling or disabling specific checks some checks can be configured -in more details. - -- ✅ **allow-first-in-block** - Allow cuddling a variable if it's used first in - the immediate following block, even if the statement with the block doesn't - use the variable (see [Configuration](CHECKS.md#allow-first-in-block) for - details) -- ❌ **allow-whole-block** - Same as above, but allows cuddling if the variable - is used _anywhere_ in the following (or nested) block (see - [Configuration](CHECKS.md#allow-whole-block) for details) -- **branch-max-lines** - If a block contains more than this number of lines the - branch statement (e.g. `return`, `break`, `continue`) need to be separated by - a whitespace (default 2) -- **case-max-lines** - If set to a non negative number, `case` blocks needs to - end with a whitespace if exceeding this number (default 0, 0 = off, 1 = - always) -- ❌ **include-generated** - Include generated files when checking - -## Installation - -```sh -# Latest release -go install github.com/bombsimon/wsl/v5/cmd/wsl@latest - -# Main branch -go install github.com/bombsimon/wsl/v5/cmd/wsl@main -``` - -## Usage - -> **Note**: This linter provides a fixer that can fix most issues with the -> `--fix` flag. - -`wsl` uses the [analysis] package meaning it will operate on package level with -the default analysis flags and way of working. - -```sh -wsl --help -wsl [flags] - -wsl --default none --enable branch,return --fix ./... -``` - -`wsl` is also integrated in [`golangci-lint`][golangci-lint] but since v5 which -had a bunch of breaking changes it's renamed to `wsl_v5`. The previous version -of `wsl` is deprecated and will be removed from `golangci-lint` eventually. - -```sh -golangci-lint run --no-config --enable-only wsl_v5 --fix -``` - -This is an exhaustive, default, configuration for `wsl_v5` in `golangci-lint`. - -```yaml -linters: - default: none - enable: - - wsl_v5 - - settings: - wsl_v5: - allow-first-in-block: true - allow-whole-block: false - branch-max-lines: 2 - case-max-lines: 0 - default: ~ # Can be `all`, `none`, `default` or empty - enable: - - append - - assign - - branch - - decl - - defer - - err - - expr - - for - - go - - if - - inc-dec - - label - - range - - return - - select - - send - - switch - - type-switch - - leading-whitespace - - trailing-whitespace - disable: - - assign-exclusive - - assign-expr -``` - -## See also - -- [`nlreturn`][nlreturn] - Use empty lines before `return` -- [`whitespace`][whitespace] - Don't use a blank newline at the start or end of - a block. -- [`gofumpt`][gofumpt] - Stricter formatter than `gofmt`. - - [analysis]: https://pkg.go.dev/golang.org/x/tools/go/analysis - [gofumpt]: https://github.com/mvdan/gofumpt - [golangci-lint]: https://golangci-lint.run - [nlreturn]: https://github.com/ssgreg/nlreturn - [whitespace]: https://github.com/ultraware/whitespace diff --git a/vendor/github.com/bombsimon/wsl/v5/analyzer.go b/vendor/github.com/bombsimon/wsl/v5/analyzer.go deleted file mode 100644 index 38a84973f4..0000000000 --- a/vendor/github.com/bombsimon/wsl/v5/analyzer.go +++ /dev/null @@ -1,198 +0,0 @@ -package wsl - -import ( - "flag" - "fmt" - "go/ast" - "go/token" - "os" - "strings" - "sync" - - "golang.org/x/tools/go/analysis" -) - -const version = "wsl version v5.3.0" - -func NewAnalyzer(config *Configuration) *analysis.Analyzer { - wa := &wslAnalyzer{config: config} - - return &analysis.Analyzer{ - Name: "wsl", - Doc: "add or remove empty lines", - Flags: wa.flags(), - Run: wa.run, - RunDespiteErrors: true, - } -} - -// wslAnalyzer is a wrapper around the configuration which is used to be able to -// set the configuration when creating the analyzer and later be able to update -// flags and running method. -type wslAnalyzer struct { - config *Configuration - - // When we use flags, we need to parse the ones used for checks into - // temporary variables so we can create the check set once the flag is being - // parsed by the analyzer and we run our analyzer. - defaultChecks string - enable []string - disable []string - - // To only validate and convert the parsed flags once we use a `sync.Once` - // to only create a check set once and store the set and potential error. We - // also store if we actually had a configuration to ensure we don't - // overwrite the checks if the analyzer was created with a proper wsl - // config. - cfgOnce sync.Once - didHaveConfig bool - checkSetErr error -} - -func (wa *wslAnalyzer) flags() flag.FlagSet { - flags := flag.NewFlagSet("wsl", flag.ExitOnError) - - if wa.config != nil { - wa.didHaveConfig = true - return *flags - } - - wa.config = NewConfig() - - flags.BoolVar(&wa.config.IncludeGenerated, "include-generated", false, "Include generated files") - flags.BoolVar(&wa.config.AllowFirstInBlock, "allow-first-in-block", true, "Allow cuddling if variable is used in the first statement in the block") - flags.BoolVar(&wa.config.AllowWholeBlock, "allow-whole-block", false, "Allow cuddling if variable is used anywhere in the block") - flags.IntVar(&wa.config.BranchMaxLines, "branch-max-lines", 2, "Max lines before requiring newline before branching, e.g. `return`, `break`, `continue` (0 = never)") - flags.IntVar(&wa.config.CaseMaxLines, "case-max-lines", 0, "Max lines before requiring a newline at the end of case (0 = never)") - - flags.StringVar(&wa.defaultChecks, "default", "", "Can be 'all' for all checks or 'none' for no checks or empty for default checks") - flags.Var(&multiStringValue{slicePtr: &wa.enable}, "enable", "Comma separated list of checks to enable") - flags.Var(&multiStringValue{slicePtr: &wa.disable}, "disable", "Comma separated list of checks to disable") - flags.Var(new(versionFlag), "V", "print version and exit") - - return *flags -} - -func (wa *wslAnalyzer) run(pass *analysis.Pass) (any, error) { - wa.cfgOnce.Do(func() { - // No need to update checks if config was passed when creating the - // analyzer. - if wa.didHaveConfig { - return - } - - // Parse the check params once if we set our config from flags. - wa.config.Checks, wa.checkSetErr = NewCheckSet(wa.defaultChecks, wa.enable, wa.disable) - }) - - if wa.checkSetErr != nil { - return nil, wa.checkSetErr - } - - for _, file := range pass.Files { - filename := getFilename(pass.Fset, file) - if !strings.HasSuffix(filename, ".go") { - continue - } - - // if the file is related to cgo the filename of the unadjusted position - // is a not a '.go' file. - unadjustedFilename := pass.Fset.PositionFor(file.Pos(), false).Filename - - // if the file is related to cgo the filename of the unadjusted position - // is a not a '.go' file. - if !strings.HasSuffix(unadjustedFilename, ".go") { - continue - } - - // The file is skipped if the "unadjusted" file is a Go file, and it's a - // generated file (ex: "_test.go" file). The other non-Go files are - // skipped by the first 'if' with the adjusted position. - if !wa.config.IncludeGenerated && ast.IsGenerated(file) { - continue - } - - wsl := New(file, pass, wa.config) - wsl.Run() - - for pos, fix := range wsl.issues { - textEdits := []analysis.TextEdit{} - - for _, f := range fix.fixRanges { - textEdits = append(textEdits, analysis.TextEdit{ - Pos: f.fixRangeStart, - End: f.fixRangeEnd, - NewText: f.fix, - }) - } - - pass.Report(analysis.Diagnostic{ - Pos: pos, - Category: "whitespace", - Message: fix.message, - SuggestedFixes: []analysis.SuggestedFix{ - { - TextEdits: textEdits, - }, - }, - }) - } - } - - //nolint:nilnil // A pass don't need to return anything. - return nil, nil -} - -// multiStringValue is a flag that supports multiple values. It's implemented to -// contain a pointer to a string slice that will be overwritten when the flag's -// `Set` method is called. -type multiStringValue struct { - slicePtr *[]string -} - -// Set implements the flag.Value interface and will overwrite the pointer to -// the -// slice with a new pointer after splitting the flag by comma. -func (m *multiStringValue) Set(value string) error { - var s []string - - for _, v := range strings.Split(value, ",") { - s = append(s, strings.TrimSpace(v)) - } - - *m.slicePtr = s - - return nil -} - -// String implements the flag.Value interface. -func (m *multiStringValue) String() string { - if m.slicePtr == nil { - return "" - } - - return strings.Join(*m.slicePtr, ", ") -} - -// https://cs.opensource.google/go/x/tools/+/refs/tags/v0.35.0:go/analysis/internal/analysisflags/flags.go;l=188-237;drc=99337ebe7b90918701a41932abf121600b972e34 -type versionFlag string - -func (*versionFlag) IsBoolFlag() bool { return true } -func (*versionFlag) Get() any { return nil } -func (*versionFlag) String() string { return "" } - -func (*versionFlag) Set(_ string) error { - fmt.Println(version) - os.Exit(0) - - return nil -} - -func getFilename(fset *token.FileSet, file *ast.File) string { - filename := fset.PositionFor(file.Pos(), true).Filename - if !strings.HasSuffix(filename, ".go") { - return fset.PositionFor(file.Pos(), false).Filename - } - - return filename -} diff --git a/vendor/github.com/bombsimon/wsl/v5/config.go b/vendor/github.com/bombsimon/wsl/v5/config.go deleted file mode 100644 index 7bed5ef42c..0000000000 --- a/vendor/github.com/bombsimon/wsl/v5/config.go +++ /dev/null @@ -1,279 +0,0 @@ -package wsl - -import ( - "fmt" - "strings" -) - -// CheckSet is a set of checks to run. -type CheckSet map[CheckType]struct{} - -// CheckType is a type that represents a checker to run. -type CheckType int - -// Each checker is represented by a CheckType that is used to enable or disable -// the check. -// A check can either be of a specific built-in keyword or custom checks. -const ( - CheckInvalid CheckType = iota - CheckAssign - CheckBranch - CheckDecl - CheckDefer - CheckExpr - CheckFor - CheckGo - CheckIf - CheckIncDec - CheckLabel - CheckRange - CheckReturn - CheckSelect - CheckSend - CheckSwitch - CheckTypeSwitch - - // Check append only allows assignments of `append` to be cuddled with other - // assignments if it's a variable used in the append statement, e.g. - // - // a := 1 - // x = append(x, a) - // . - CheckAppend - // Assign exclusive only allows assignments of either new variables or - // re-assignment of existing ones, e.g. - // - // a := 1 - // b := 2 - // - // a = 1 - // b = 2 - // . - CheckAssignExclusive - // CheckAssignExpr will check so assignments are not cuddled with expression - // nodes, e.g. - // - // t1.Fn1() - // - // x := t1.Fn2() - // t1.Fn3() - // . - CheckAssignExpr - // Force error checking to follow immediately after an error variable is - // assigned, e.g. - // - // _, err := someFn() - // if err != nil { - // panic(err) - // } - // . - CheckErr - CheckLeadingWhitespace - CheckTrailingWhitespace - - // CheckTypes only used for reporting. - CheckCaseTrailingNewline -) - -func (c CheckType) String() string { - return [...]string{ - "invalid", - "assign", - "branch", - "decl", - "defer", - "expr", - "for", - "go", - "if", - "inc-dec", - "label", - "range", - "return", - "select", - "send", - "switch", - "type-switch", - // - "append", - "assign-exclusive", - "assign-expr", - "err", - "leading-whitespace", - "trailing-whitespace", - // - "case-trailing-newline", - }[c] -} - -type Configuration struct { - IncludeGenerated bool - AllowFirstInBlock bool - AllowWholeBlock bool - BranchMaxLines int - CaseMaxLines int - Checks CheckSet -} - -func NewConfig() *Configuration { - return &Configuration{ - IncludeGenerated: false, - AllowFirstInBlock: true, - AllowWholeBlock: false, - CaseMaxLines: 0, - BranchMaxLines: 2, - Checks: DefaultChecks(), - } -} - -func NewWithChecks( - defaultChecks string, - enable []string, - disable []string, -) (*Configuration, error) { - checks, err := NewCheckSet(defaultChecks, enable, disable) - if err != nil { - return nil, fmt.Errorf("failed to create config: %w", err) - } - - cfg := NewConfig() - cfg.Checks = checks - - return cfg, nil -} - -func NewCheckSet( - defaultChecks string, - enable []string, - disable []string, -) (CheckSet, error) { - var cs CheckSet - - switch strings.ToLower(defaultChecks) { - case "", "default": - cs = DefaultChecks() - case "all": - cs = AllChecks() - case "none": - cs = NoChecks() - default: - return nil, fmt.Errorf("invalid preset '%s', must be `all`, `none` or `` (empty)", defaultChecks) - } - - for _, s := range enable { - check, err := CheckFromString(s) - if err != nil { - return nil, fmt.Errorf("invalid check '%s'", s) - } - - cs.Add(check) - } - - for _, s := range disable { - check, err := CheckFromString(s) - if err != nil { - return nil, fmt.Errorf("invalid check '%s'", s) - } - - cs.Remove(check) - } - - return cs, nil -} - -func DefaultChecks() CheckSet { - return CheckSet{ - CheckAppend: {}, - CheckAssign: {}, - CheckBranch: {}, - CheckDecl: {}, - CheckDefer: {}, - CheckErr: {}, - CheckExpr: {}, - CheckFor: {}, - CheckGo: {}, - CheckIf: {}, - CheckIncDec: {}, - CheckLabel: {}, - CheckLeadingWhitespace: {}, - CheckTrailingWhitespace: {}, - CheckRange: {}, - CheckReturn: {}, - CheckSelect: {}, - CheckSend: {}, - CheckSwitch: {}, - CheckTypeSwitch: {}, - } -} - -func AllChecks() CheckSet { - c := DefaultChecks() - c.Add(CheckAssignExclusive) - c.Add(CheckAssignExpr) - - return c -} - -func NoChecks() CheckSet { - return CheckSet{} -} - -func (c CheckSet) Add(check CheckType) { - c[check] = struct{}{} -} - -func (c CheckSet) Remove(check CheckType) { - delete(c, check) -} - -func CheckFromString(s string) (CheckType, error) { - switch strings.ToLower(s) { - case "assign": - return CheckAssign, nil - case "branch": - return CheckBranch, nil - case "decl": - return CheckDecl, nil - case "defer": - return CheckDefer, nil - case "expr": - return CheckExpr, nil - case "for": - return CheckFor, nil - case "go": - return CheckGo, nil - case "if": - return CheckIf, nil - case "inc-dec": - return CheckIncDec, nil - case "label": - return CheckLabel, nil - case "range": - return CheckRange, nil - case "return": - return CheckReturn, nil - case "select": - return CheckSelect, nil - case "send": - return CheckSend, nil - case "switch": - return CheckSwitch, nil - case "type-switch": - return CheckTypeSwitch, nil - - case "append": - return CheckAppend, nil - case "assign-exclusive": - return CheckAssignExclusive, nil - case "assign-expr": - return CheckAssignExpr, nil - case "err": - return CheckErr, nil - case "leading-whitespace": - return CheckLeadingWhitespace, nil - case "trailing-whitespace": - return CheckTrailingWhitespace, nil - default: - return CheckInvalid, fmt.Errorf("invalid check '%s'", s) - } -} diff --git a/vendor/github.com/bombsimon/wsl/v5/cursor.go b/vendor/github.com/bombsimon/wsl/v5/cursor.go deleted file mode 100644 index 0d275829f2..0000000000 --- a/vendor/github.com/bombsimon/wsl/v5/cursor.go +++ /dev/null @@ -1,88 +0,0 @@ -package wsl - -import ( - "go/ast" -) - -// Cursor holds a list of statements and a pointer to where in the list we are. -// Each block gets a new cursor and can be used to check previous or coming -// statements. -type Cursor struct { - currentIdx int - statements []ast.Stmt - checkType CheckType -} - -// NewCursor creates a new cursor with a given list of statements. -func NewCursor(statements []ast.Stmt) *Cursor { - return &Cursor{ - currentIdx: -1, - statements: statements, - } -} - -func (c *Cursor) SetChecker(ct CheckType) { - c.checkType = ct -} - -func (c *Cursor) NextNode() ast.Node { - defer c.Save()() - - var nextNode ast.Node - if c.Next() { - nextNode = c.Stmt() - } - - return nextNode -} - -func (c *Cursor) Next() bool { - if c.currentIdx >= len(c.statements)-1 { - return false - } - - c.currentIdx++ - - return true -} - -func (c *Cursor) Previous() bool { - if c.currentIdx <= 0 { - return false - } - - c.currentIdx-- - - return true -} - -func (c *Cursor) PreviousNode() ast.Node { - defer c.Save()() - - var previousNode ast.Node - if c.Previous() { - previousNode = c.Stmt() - } - - return previousNode -} - -func (c *Cursor) Stmt() ast.Stmt { - return c.statements[c.currentIdx] -} - -func (c *Cursor) Save() func() { - idx := c.currentIdx - - return func() { - c.currentIdx = idx - } -} - -func (c *Cursor) Len() int { - return len(c.statements) -} - -func (c *Cursor) Nth(n int) ast.Stmt { - return c.statements[n] -} diff --git a/vendor/github.com/bombsimon/wsl/v5/wsl.go b/vendor/github.com/bombsimon/wsl/v5/wsl.go deleted file mode 100644 index 9bf62c2aec..0000000000 --- a/vendor/github.com/bombsimon/wsl/v5/wsl.go +++ /dev/null @@ -1,1464 +0,0 @@ -package wsl - -import ( - "bytes" - "fmt" - "go/ast" - "go/format" - "go/token" - "go/types" - - "golang.org/x/tools/go/analysis" -) - -const ( - messageMissingWhitespaceAbove = "missing whitespace above this line" - messageMissingWhitespaceBelow = "missing whitespace below this line" - messageRemoveWhitespace = "unnecessary whitespace" -) - -type fixRange struct { - fixRangeStart token.Pos - fixRangeEnd token.Pos - fix []byte -} - -type issue struct { - message string - // We can report multiple fixes at the same position. This happens e.g. when - // we force error cuddling but the error assignment is already cuddled. - // See `checkError` for examples. - fixRanges []fixRange -} - -type WSL struct { - file *ast.File - fset *token.FileSet - typeInfo *types.Info - issues map[token.Pos]issue - config *Configuration - groupedDecls map[token.Pos]struct{} -} - -func New(file *ast.File, pass *analysis.Pass, cfg *Configuration) *WSL { - return &WSL{ - fset: pass.Fset, - file: file, - typeInfo: pass.TypesInfo, - issues: make(map[token.Pos]issue), - config: cfg, - groupedDecls: make(map[token.Pos]struct{}), - } -} - -// Run will run analysis on the file and pass passed to the constructor. It's -// typically only supposed to be used by [analysis.Analyzer]. -func (w *WSL) Run() { - for _, decl := range w.file.Decls { - if funcDecl, ok := decl.(*ast.FuncDecl); ok { - w.checkFunc(funcDecl) - } - } -} - -func (w *WSL) checkStmt(stmt ast.Stmt, cursor *Cursor) { - //nolint:gocritic // This is not commented out code, it's examples - switch s := stmt.(type) { - // if a {} else if b {} else {} - case *ast.IfStmt: - w.checkIf(s, cursor, false) - // for {} / for a; b; c {} - case *ast.ForStmt: - w.checkFor(s, cursor) - // for _, _ = range a {} - case *ast.RangeStmt: - w.checkRange(s, cursor) - // switch {} // switch a {} - case *ast.SwitchStmt: - w.checkSwitch(s, cursor) - // switch a.(type) {} - case *ast.TypeSwitchStmt: - w.checkTypeSwitch(s, cursor) - // return a - case *ast.ReturnStmt: - w.checkReturn(s, cursor) - // continue / break - case *ast.BranchStmt: - w.checkBranch(s, cursor) - // var a - case *ast.DeclStmt: - w.checkDeclStmt(s, cursor) - // a := a - case *ast.AssignStmt: - w.checkAssign(s, cursor) - // a++ / a-- - case *ast.IncDecStmt: - w.checkIncDec(s, cursor) - // defer func() {} - case *ast.DeferStmt: - w.checkDefer(s, cursor) - // go func() {} - case *ast.GoStmt: - w.checkGo(s, cursor) - // e.g. someFn() - case *ast.ExprStmt: - w.checkExprStmt(s, cursor) - // case: - case *ast.CaseClause: - w.checkCaseClause(s, cursor) - // case: - case *ast.CommClause: - w.checkCommClause(s, cursor) - // { } - case *ast.BlockStmt: - w.checkBlock(s) - // select { } - case *ast.SelectStmt: - w.checkSelect(s, cursor) - // ch <- ... - case *ast.SendStmt: - w.checkSend(s, cursor) - // LABEL: - case *ast.LabeledStmt: - w.checkLabel(s, cursor) - case *ast.EmptyStmt: - default: - } -} - -//nolint:unparam // False positive on `cursor` -func (w *WSL) checkExpr(expr ast.Expr, cursor *Cursor) { - // This switch traverses all possible subexpressions in search - // of anonymous functions, no matter how unlikely or perhaps even - // semantically impossible it is. - switch s := expr.(type) { - case *ast.FuncLit: - w.checkBlock(s.Body) - case *ast.CallExpr: - w.checkExpr(s.Fun, cursor) - - for _, e := range s.Args { - w.checkExpr(e, cursor) - } - case *ast.StarExpr: - w.checkExpr(s.X, cursor) - case *ast.CompositeLit: - w.checkExpr(s.Type, cursor) - - for _, e := range s.Elts { - w.checkExpr(e, cursor) - } - case *ast.KeyValueExpr: - w.checkExpr(s.Key, cursor) - w.checkExpr(s.Value, cursor) - case *ast.ArrayType: - w.checkExpr(s.Elt, cursor) - w.checkExpr(s.Len, cursor) - case *ast.BasicLit: - case *ast.BinaryExpr: - w.checkExpr(s.X, cursor) - w.checkExpr(s.Y, cursor) - case *ast.ChanType: - w.checkExpr(s.Value, cursor) - case *ast.Ellipsis: - w.checkExpr(s.Elt, cursor) - case *ast.FuncType: - if params := s.TypeParams; params != nil { - for _, f := range params.List { - w.checkExpr(f.Type, cursor) - } - } - - if params := s.Params; params != nil { - for _, f := range params.List { - w.checkExpr(f.Type, cursor) - } - } - - if results := s.Results; results != nil { - for _, f := range results.List { - w.checkExpr(f.Type, cursor) - } - } - case *ast.Ident: - case *ast.IndexExpr: - w.checkExpr(s.Index, cursor) - w.checkExpr(s.X, cursor) - case *ast.IndexListExpr: - w.checkExpr(s.X, cursor) - - for _, e := range s.Indices { - w.checkExpr(e, cursor) - } - case *ast.InterfaceType: - for _, f := range s.Methods.List { - w.checkExpr(f.Type, cursor) - } - case *ast.MapType: - w.checkExpr(s.Key, cursor) - w.checkExpr(s.Value, cursor) - case *ast.ParenExpr: - w.checkExpr(s.X, cursor) - case *ast.SelectorExpr: - w.checkExpr(s.X, cursor) - case *ast.SliceExpr: - w.checkExpr(s.X, cursor) - w.checkExpr(s.Low, cursor) - w.checkExpr(s.High, cursor) - w.checkExpr(s.Max, cursor) - case *ast.StructType: - for _, f := range s.Fields.List { - w.checkExpr(f.Type, cursor) - } - case *ast.TypeAssertExpr: - w.checkExpr(s.X, cursor) - w.checkExpr(s.Type, cursor) - case *ast.UnaryExpr: - w.checkExpr(s.X, cursor) - case nil: - default: - } -} - -func (w *WSL) checkDecl(decl ast.Decl, cursor *Cursor) { - switch d := decl.(type) { - case *ast.GenDecl: - for _, spec := range d.Specs { - w.checkSpec(spec, cursor) - } - case *ast.FuncDecl: - w.checkStmt(d.Body, cursor) - case *ast.BadDecl: - default: - } -} - -func (w *WSL) checkSpec(spec ast.Spec, cursor *Cursor) { - switch s := spec.(type) { - case *ast.ValueSpec: - for _, expr := range s.Values { - w.checkExpr(expr, cursor) - } - case *ast.ImportSpec, *ast.TypeSpec: - default: - } -} - -func (w *WSL) checkBody(body []ast.Stmt) { - cursor := NewCursor(body) - - for cursor.Next() { - w.checkStmt(cursor.Stmt(), cursor) - } -} - -func (w *WSL) checkCuddlingBlock( - stmt ast.Node, - blockList []ast.Stmt, - allowedIdents []*ast.Ident, - cursor *Cursor, - maxAllowedStatements int, -) { - var firstBlockStmt ast.Node - if len(blockList) > 0 { - firstBlockStmt = blockList[0] - } - - w.checkCuddlingMaxAllowed(stmt, firstBlockStmt, allowedIdents, cursor, maxAllowedStatements) -} - -func (w *WSL) checkCuddling(stmt ast.Node, cursor *Cursor, maxAllowedStatements int) { - w.checkCuddlingMaxAllowed(stmt, nil, []*ast.Ident{}, cursor, maxAllowedStatements) -} - -func (w *WSL) checkCuddlingMaxAllowed( - stmt ast.Node, - firstBlockStmt ast.Node, - allowedIdents []*ast.Ident, - cursor *Cursor, - maxAllowedStatements int, -) { - if _, ok := cursor.Stmt().(*ast.LabeledStmt); ok { - return - } - - previousNode := cursor.PreviousNode() - - if previousNode != nil { - if _, ok := w.groupedDecls[previousNode.End()]; ok { - w.addErrorTooManyStatements(cursor.Stmt().Pos(), cursor.checkType) - return - } - } - - numStmtsAbove := w.numberOfStatementsAbove(cursor) - previousIdents := w.identsFromNode(previousNode, true) - - // If we don't have any statements above, we only care about potential error - // cuddling (for if statements) so check that. - if numStmtsAbove == 0 { - w.checkError(numStmtsAbove, stmt, previousNode, cursor) - return - } - - nodeIsAssignDeclOrIncDec := func(n ast.Node) bool { - _, a := n.(*ast.AssignStmt) - _, d := n.(*ast.DeclStmt) - _, i := n.(*ast.IncDecStmt) - - return a || d || i - } - - _, currIsDefer := stmt.(*ast.DeferStmt) - - // We're cuddled but not with an assign, declare or defer statement which is - // never allowed. - if !nodeIsAssignDeclOrIncDec(previousNode) && !currIsDefer { - w.addErrorInvalidTypeCuddle(cursor.Stmt().Pos(), cursor.checkType) - return - } - - checkIntersection := func(other []*ast.Ident) bool { - anyIntersects := identIntersection(previousIdents, other) - if len(anyIntersects) > 0 { - // We have matches, but too many statements above. - if maxAllowedStatements != -1 && numStmtsAbove > maxAllowedStatements { - w.addErrorTooManyStatements(previousNode.Pos(), cursor.checkType) - } - - return true - } - - return false - } - - // FEATURE(AllowWholeBlock): Allow identifier used anywhere in block - // (including recursive blocks). - if w.config.AllowWholeBlock { - allIdentsInBlock := w.identsFromNode(stmt, false) - if checkIntersection(allIdentsInBlock) { - return - } - } - - // FEATURE(AllowFirstInBlock): Allow identifiers used first in block. - if !w.config.AllowWholeBlock && w.config.AllowFirstInBlock { - firstStmtIdents := w.identsFromNode(firstBlockStmt, true) - if checkIntersection(firstStmtIdents) { - return - } - } - - currentIdents := w.identsFromNode(stmt, true) - if checkIntersection(currentIdents) { - return - } - - if checkIntersection(allowedIdents) { - return - } - - intersects := identIntersection(currentIdents, previousIdents) - if len(intersects) > 0 { - return - } - - // We're cuddled but the line immediately above doesn't contain any - // variables used in this statement. - w.addErrorNoIntersection(stmt.Pos(), cursor.checkType) -} - -func (w *WSL) checkCuddlingWithoutIntersection(stmt ast.Node, cursor *Cursor) { - if w.numberOfStatementsAbove(cursor) == 0 { - return - } - - if _, ok := cursor.Stmt().(*ast.LabeledStmt); ok { - return - } - - previousNode := cursor.PreviousNode() - - currAssign, currIsAssign := stmt.(*ast.AssignStmt) - previousAssign, prevIsAssign := previousNode.(*ast.AssignStmt) - _, prevIsDecl := previousNode.(*ast.DeclStmt) - _, prevIsIncDec := previousNode.(*ast.IncDecStmt) - - // Cuddling without intersection is allowed for assignments and inc/dec - // statements. If however the check for declarations is disabled, we also - // allow cuddling with them as well. - // - // var x string - // x := "" - // y++ - if _, ok := w.config.Checks[CheckDecl]; ok { - prevIsDecl = false - } - - // If we enable exclusive assign checks we only allow new declarations or - // new assignments together but not mix and match. - // - // When this is enabled we also implicitly disable support to cuddle with - // anything else. - if _, ok := w.config.Checks[CheckAssignExclusive]; ok { - prevIsDecl = false - prevIsIncDec = false - - if prevIsAssign && currIsAssign { - prevIsAssign = previousAssign.Tok == currAssign.Tok - } - } - - prevIsValidType := previousNode == nil || prevIsAssign || prevIsDecl || prevIsIncDec - - if _, ok := w.config.Checks[CheckAssignExpr]; !ok { - if _, ok := previousNode.(*ast.ExprStmt); ok && w.hasIntersection(stmt, previousNode) { - prevIsValidType = prevIsValidType || ok - } - } - - if prevIsValidType { - return - } - - w.addErrorInvalidTypeCuddle(stmt.Pos(), cursor.checkType) -} - -func (w *WSL) checkBlock(block *ast.BlockStmt) { - w.checkBlockLeadingNewline(block) - w.checkTrailingNewline(block) - - w.checkBody(block.List) -} - -func (w *WSL) checkCaseClause(stmt *ast.CaseClause, cursor *Cursor) { - w.checkCaseLeadingNewline(stmt) - - if w.config.CaseMaxLines != 0 { - w.checkCaseTrailingNewline(stmt.Body, cursor) - } - - w.checkBody(stmt.Body) -} - -func (w *WSL) checkCommClause(stmt *ast.CommClause, cursor *Cursor) { - w.checkCommLeadingNewline(stmt) - - if w.config.CaseMaxLines != 0 { - w.checkCaseTrailingNewline(stmt.Body, cursor) - } - - w.checkBody(stmt.Body) -} - -func (w *WSL) checkFunc(funcDecl *ast.FuncDecl) { - if funcDecl.Body == nil { - return - } - - w.checkBlock(funcDecl.Body) -} - -func (w *WSL) checkAssign(stmt *ast.AssignStmt, cursor *Cursor) { - defer func() { - for _, expr := range stmt.Rhs { - w.checkExpr(expr, cursor) - } - - w.checkAppend(stmt, cursor) - }() - - if _, ok := w.config.Checks[CheckAssign]; !ok { - return - } - - cursor.SetChecker(CheckAssign) - - w.checkCuddlingWithoutIntersection(stmt, cursor) -} - -func (w *WSL) checkAppend(stmt *ast.AssignStmt, cursor *Cursor) { - if _, ok := w.config.Checks[CheckAppend]; !ok { - return - } - - if w.numberOfStatementsAbove(cursor) == 0 { - return - } - - previousNode := cursor.PreviousNode() - - var appendNode *ast.CallExpr - - for _, expr := range stmt.Rhs { - e, ok := expr.(*ast.CallExpr) - if !ok { - continue - } - - if f, ok := e.Fun.(*ast.Ident); ok && f.Name == "append" { - appendNode = e - break - } - } - - if appendNode == nil { - return - } - - if !w.hasIntersection(appendNode, previousNode) { - w.addErrorNoIntersection(stmt.Pos(), CheckAppend) - } -} - -func (w *WSL) checkBranch(stmt *ast.BranchStmt, cursor *Cursor) { - if _, ok := w.config.Checks[CheckBranch]; !ok { - return - } - - cursor.SetChecker(CheckBranch) - - if w.numberOfStatementsAbove(cursor) == 0 { - return - } - - lastStmtInBlock := cursor.statements[len(cursor.statements)-1] - firstStmts := cursor.Nth(0) - - if w.lineFor(lastStmtInBlock.End())-w.lineFor(firstStmts.Pos()) < w.config.BranchMaxLines { - return - } - - w.addErrorTooManyLines(stmt.Pos(), cursor.checkType) -} - -func (w *WSL) checkDeclStmt(stmt *ast.DeclStmt, cursor *Cursor) { - w.checkDecl(stmt.Decl, cursor) - - if _, ok := w.config.Checks[CheckDecl]; !ok { - return - } - - cursor.SetChecker(CheckDecl) - - if w.numberOfStatementsAbove(cursor) == 0 { - return - } - - // Try to do smart grouping and if we succeed return, otherwise do - // line-by-line fixing. - if w.maybeGroupDecl(stmt, cursor) { - return - } - - w.addErrorNeverAllow(stmt.Pos(), cursor.checkType) -} - -func (w *WSL) checkDefer(stmt *ast.DeferStmt, cursor *Cursor) { - w.maybeCheckExpr( - stmt, - stmt.Call, - cursor, - func(n ast.Node) (int, bool) { - _, previousIsDefer := n.(*ast.DeferStmt) - _, previousIsIf := n.(*ast.IfStmt) - - // We allow defer as a third node only if we have an if statement - // between, e.g. - // - // f, err := os.Open(file) - // if err != nil { - // return err - // } - // defer f.Close() - if previousIsIf && w.numberOfStatementsAbove(cursor) >= 2 { - defer cursor.Save()() - - cursor.Previous() - cursor.Previous() - - if w.hasIntersection(cursor.Stmt(), stmt) { - return 1, false - } - } - - // Only check cuddling if previous statement isn't also a defer. - return 1, !previousIsDefer - }, - CheckDefer, - ) -} - -func (w *WSL) checkError( - stmtsAbove int, - ifStmt ast.Node, - previousNode ast.Node, - cursor *Cursor, -) { - if _, ok := w.config.Checks[CheckErr]; !ok { - return - } - - if _, ok := cursor.Stmt().(*ast.LabeledStmt); ok { - return - } - - defer cursor.Save()() - - // It must be an if statement - stmt, ok := ifStmt.(*ast.IfStmt) - if !ok { - return - } - - // If we actually have statements above we can't possibly need to remove any - // empty lines. - if stmtsAbove > 0 { - return - } - - // If the error checking has an init condition (e.g. if err := f();) we - // don't want to check cuddling since the error is now assigned on this row. - if stmt.Init != nil { - return - } - - // The condition must be a binary expression (X OP Y) - binaryExpr, ok := stmt.Cond.(*ast.BinaryExpr) - if !ok { - return - } - - // We must do not equal or equal comparison (!= or ==) - if binaryExpr.Op != token.NEQ && binaryExpr.Op != token.EQL { - return - } - - xIdent, ok := binaryExpr.X.(*ast.Ident) - if !ok { - return - } - - // X is not an error so it's not error checking - if !w.implementsErr(xIdent) { - return - } - - yIdent, ok := binaryExpr.Y.(*ast.Ident) - if !ok { - return - } - - // Y is not compared with `nil` - if yIdent.Name != "nil" { - return - } - - previousIdents := []*ast.Ident{} - - if assign, ok := previousNode.(*ast.AssignStmt); ok { - for _, lhs := range assign.Lhs { - previousIdents = append(previousIdents, w.identsFromNode(lhs, true)...) - } - } - - if decl, ok := previousNode.(*ast.DeclStmt); ok { - if genDecl, ok := decl.Decl.(*ast.GenDecl); ok { - for _, spec := range genDecl.Specs { - if vs, ok := spec.(*ast.ValueSpec); ok { - previousIdents = append(previousIdents, vs.Names...) - } - } - } - } - - // Ensure that the error checked on this line was assigned or declared in - // the previous statement. - if len(identIntersection([]*ast.Ident{xIdent}, previousIdents)) == 0 { - return - } - - cursor.SetChecker(CheckErr) - - previousNodeEnd := previousNode.End() - - comments := ast.NewCommentMap(w.fset, previousNode, w.file.Comments) - for _, cg := range comments { - for _, c := range cg { - if c.Pos() < previousNodeEnd || c.End() > ifStmt.Pos() { - continue - } - - if c.End() > previousNodeEnd { - // There's a comment between the error variable and the - // if-statement, we can't do much about this. Most likely, the - // comment has a meaning, but even if not we would end up with - // something like - // - // err := fn() - // // Some Comment - // if err != nil {} - // - // Which just feels marginally better than leaving the space - // anyway. - if w.lineFor(c.End()) != w.lineFor(previousNodeEnd) { - return - } - - // If they are on the same line though, we can just extend where - // the line ends. - previousNodeEnd = c.End() - } - } - } - - w.addError(previousNodeEnd+1, previousNodeEnd, ifStmt.Pos(), messageRemoveWhitespace, cursor.checkType) - - // If we add the error at the same position but with a different fix - // range, only the fix range will be updated. - // - // a := 1 - // err := fn() - // - // if err != nil {} - // - // Should become - // - // a := 1 - // - // err := fn() - // if err != nil {} - cursor.Previous() - - // We report this fix on the same pos as the previous diagnostic, but the - // fix is different. The reason is to just stack more fixes for the same - // diagnostic, the issue isn't present until the first fix so this message - // will never be shown to the user. - if w.numberOfStatementsAbove(cursor) > 0 { - w.addError(previousNodeEnd+1, previousNode.Pos(), previousNode.Pos(), messageMissingWhitespaceAbove, cursor.checkType) - } -} - -func (w *WSL) checkExprStmt(stmt *ast.ExprStmt, cursor *Cursor) { - w.maybeCheckExpr( - stmt, - stmt.X, - cursor, - func(n ast.Node) (int, bool) { - _, ok := n.(*ast.ExprStmt) - return -1, !ok - }, - CheckExpr, - ) -} - -func (w *WSL) checkFor(stmt *ast.ForStmt, cursor *Cursor) { - w.maybeCheckBlock(stmt, stmt.Body, cursor, CheckFor) -} - -func (w *WSL) checkGo(stmt *ast.GoStmt, cursor *Cursor) { - w.maybeCheckExpr( - stmt, - stmt.Call, - cursor, - // We can cuddle any amount `go` statements so only check cuddling if - // the previous one isn't a `go` call. - func(n ast.Node) (int, bool) { - _, ok := n.(*ast.GoStmt) - return 1, !ok - }, - CheckGo, - ) -} - -func (w *WSL) checkIf(stmt *ast.IfStmt, cursor *Cursor, isElse bool) { - // if - w.checkBlock(stmt.Body) - - switch v := stmt.Else.(type) { - // else-if - case *ast.IfStmt: - w.checkIf(v, cursor, true) - - // else - case *ast.BlockStmt: - w.checkBlock(v) - } - - if _, ok := w.config.Checks[CheckIf]; !isElse && ok { - cursor.SetChecker(CheckIf) - w.checkCuddlingBlock(stmt, stmt.Body.List, []*ast.Ident{}, cursor, 1) - } else if _, ok := w.config.Checks[CheckErr]; !isElse && ok { - previousNode := cursor.PreviousNode() - - w.checkError( - w.numberOfStatementsAbove(cursor), - stmt, - previousNode, - cursor, - ) - } -} - -func (w *WSL) checkIncDec(stmt *ast.IncDecStmt, cursor *Cursor) { - defer w.checkExpr(stmt.X, cursor) - - if _, ok := w.config.Checks[CheckIncDec]; !ok { - return - } - - cursor.SetChecker(CheckIncDec) - - w.checkCuddlingWithoutIntersection(stmt, cursor) -} - -func (w *WSL) checkLabel(stmt *ast.LabeledStmt, cursor *Cursor) { - // We check the statement last because the statement is the same node as the - // label (it's a labeled statement). This means that we _first_ want to - // check any violations of cuddling the label (never cuddle label) before we - // actually check the inner statement. - // - // It's a subtle difference, but it makes the diagnostic make more sense. - // We do this by deferring the statmenet check so it happens last no matter - // if we have label checking enabled or not. - defer w.checkStmt(stmt.Stmt, cursor) - - if _, ok := w.config.Checks[CheckLabel]; !ok { - return - } - - cursor.SetChecker(CheckLabel) - - if w.numberOfStatementsAbove(cursor) == 0 { - return - } - - w.addErrorNeverAllow(stmt.Pos(), cursor.checkType) -} - -func (w *WSL) checkRange(stmt *ast.RangeStmt, cursor *Cursor) { - w.maybeCheckBlock(stmt, stmt.Body, cursor, CheckRange) -} - -func (w *WSL) checkReturn(stmt *ast.ReturnStmt, cursor *Cursor) { - for _, expr := range stmt.Results { - w.checkExpr(expr, cursor) - } - - if _, ok := w.config.Checks[CheckReturn]; !ok { - return - } - - cursor.SetChecker(CheckReturn) - - // There's only a return statement. - if cursor.Len() <= 1 { - return - } - - if w.numberOfStatementsAbove(cursor) == 0 { - return - } - - // If the distance between the first statement and the return statement is - // less than `n` LOC we're allowed to cuddle. - firstStmts := cursor.Nth(0) - if w.lineFor(stmt.End())-w.lineFor(firstStmts.Pos()) < w.config.BranchMaxLines { - return - } - - w.addErrorTooManyLines(stmt.Pos(), cursor.checkType) -} - -func (w *WSL) checkSelect(stmt *ast.SelectStmt, cursor *Cursor) { - w.maybeCheckBlock(stmt, stmt.Body, cursor, CheckSelect) -} - -func (w *WSL) checkSend(stmt *ast.SendStmt, cursor *Cursor) { - defer w.checkExpr(stmt.Value, cursor) - - if _, ok := w.config.Checks[CheckSend]; !ok { - return - } - - cursor.SetChecker(CheckSend) - - var stmts []ast.Stmt - - ast.Inspect(stmt.Value, func(n ast.Node) bool { - if b, ok := n.(*ast.BlockStmt); ok { - stmts = b.List - return false - } - - return true - }) - - w.checkCuddlingBlock(stmt, stmts, []*ast.Ident{}, cursor, 1) -} - -func (w *WSL) checkSwitch(stmt *ast.SwitchStmt, cursor *Cursor) { - w.maybeCheckBlock(stmt, stmt.Body, cursor, CheckSwitch) -} - -func (w *WSL) checkTypeSwitch(stmt *ast.TypeSwitchStmt, cursor *Cursor) { - w.maybeCheckBlock(stmt, stmt.Body, cursor, CheckTypeSwitch) -} - -func (w *WSL) checkCaseTrailingNewline(body []ast.Stmt, cursor *Cursor) { - if len(body) == 0 { - return - } - - defer cursor.Save()() - - if !cursor.Next() { - return - } - - var nextCase ast.Node - - switch n := cursor.Stmt().(type) { - case *ast.CaseClause: - nextCase = n - case *ast.CommClause: - nextCase = n - default: - return - } - - firstStmt := body[0] - lastStmt := body[len(body)-1] - totalLines := w.lineFor(lastStmt.End()) - w.lineFor(firstStmt.Pos()) + 1 - - if totalLines < w.config.CaseMaxLines { - return - } - - // Next case is not immediately after the last statement so must be newline - // already. - if w.lineFor(nextCase.Pos()) > w.lineFor(lastStmt.End())+1 { - return - } - - w.addError(lastStmt.End(), nextCase.Pos(), nextCase.Pos(), messageMissingWhitespaceBelow, CheckCaseTrailingNewline) -} - -func (w *WSL) checkBlockLeadingNewline(body *ast.BlockStmt) { - comments := ast.NewCommentMap(w.fset, body, w.file.Comments) - w.checkLeadingNewline(body.Lbrace, body.List, comments) -} - -func (w *WSL) checkCaseLeadingNewline(caseClause *ast.CaseClause) { - comments := ast.NewCommentMap(w.fset, caseClause, w.file.Comments) - w.checkLeadingNewline(caseClause.Colon, caseClause.Body, comments) -} - -func (w *WSL) checkCommLeadingNewline(commClause *ast.CommClause) { - comments := ast.NewCommentMap(w.fset, commClause, w.file.Comments) - w.checkLeadingNewline(commClause.Colon, commClause.Body, comments) -} - -func (w *WSL) checkLeadingNewline(startPos token.Pos, body []ast.Stmt, comments ast.CommentMap) { - if _, ok := w.config.Checks[CheckLeadingWhitespace]; !ok { - return - } - - // No statements in the block, let's leave it as is. - if len(body) == 0 { - return - } - - openLine := w.lineFor(startPos) - openingPos := startPos + 1 - firstStmt := body[0].Pos() - - for _, commentGroup := range comments { - for _, comment := range commentGroup { - // The comment starts after the current opening position (originally - // the LBrace) and ends before the current first statement - // (originally first body.List item). - if comment.Pos() > openingPos && comment.End() < firstStmt { - openingPosLine := w.lineFor(openingPos) - commentStartLine := w.lineFor(comment.Pos()) - - // If comment starts at the same line as the opening position it - // should just extend the position for the fixer if needed. - // func fn() { // This comment starts at the same line as LBrace - switch { - // The comment is on the same line as current opening position. - // E.g. func fn() { // A comment - case commentStartLine == openingPosLine: - openingPos = comment.End() - // Opening position is the same as `{` and the comment is - // directly on the line after (no empty line) - case openingPosLine == openLine && - commentStartLine == openLine+1: - openingPos = comment.End() - // The opening position has been updated, it's another comment. - case openingPosLine != openLine: - openingPos = comment.End() - // The opening position is still { and the comment is not - // directly above - it must be an empty line which shouldn't be - // there. - default: - firstStmt = comment.Pos() - } - } - } - } - - openingPosLine := w.lineFor(openingPos) - firstStmtLine := w.lineFor(firstStmt) - - if firstStmtLine > openingPosLine+1 { - w.addError(openingPos+1, openingPos, firstStmt, messageRemoveWhitespace, CheckLeadingWhitespace) - } -} - -func (w *WSL) checkTrailingNewline(body *ast.BlockStmt) { - if _, ok := w.config.Checks[CheckTrailingWhitespace]; !ok { - return - } - - // No statements in the block, let's leave it as is. - if len(body.List) == 0 { - return - } - - lastStmt := body.List[len(body.List)-1] - - // We don't want to force removal of the empty line for the last case since - // it can be use for consistency and readability. - if _, ok := lastStmt.(*ast.CaseClause); ok { - return - } - - closingPos := body.Rbrace - lastStmtOrComment := lastStmt.End() - - // Empty label statements needs positional adjustment. #92 - if l, ok := lastStmt.(*ast.LabeledStmt); ok { - if _, ok := l.Stmt.(*ast.EmptyStmt); ok { - lastStmtOrComment = lastStmt.Pos() - } - } - - comments := ast.NewCommentMap(w.fset, body, w.file.Comments) - for _, commentGroup := range comments { - for _, comment := range commentGroup { - if comment.End() < closingPos && comment.Pos() > lastStmtOrComment { - lastStmtOrComment = comment.End() - } - } - } - - closingPosLine := w.lineFor(closingPos) - lastStmtLine := w.lineFor(lastStmtOrComment) - - if closingPosLine > lastStmtLine+1 { - w.addError(lastStmtOrComment+1, lastStmtOrComment, closingPos, messageRemoveWhitespace, CheckTrailingWhitespace) - } -} - -func (w *WSL) maybeGroupDecl(stmt *ast.DeclStmt, cursor *Cursor) bool { - firstNode := asGenDeclWithValueSpecs(cursor.PreviousNode()) - if firstNode == nil { - return false - } - - currentNode := asGenDeclWithValueSpecs(stmt) - if currentNode == nil { - return false - } - - // Both are not same type, e.g. `const` or `var` - if firstNode.Tok != currentNode.Tok { - return false - } - - group := &ast.GenDecl{ - Tok: firstNode.Tok, - Lparen: 1, - Specs: firstNode.Specs, - } - - group.Specs = append(group.Specs, currentNode.Specs...) - - reportNodes := []ast.Node{currentNode} - lastNode := currentNode - - for { - nextPeeked := cursor.NextNode() - if nextPeeked == nil { - break - } - - if w.lineFor(lastNode.End()) < w.lineFor(nextPeeked.Pos())-1 { - break - } - - nextNode := asGenDeclWithValueSpecs(nextPeeked) - if nextNode == nil { - break - } - - if nextNode.Tok != firstNode.Tok { - break - } - - cursor.Next() - - group.Specs = append(group.Specs, nextNode.Specs...) - reportNodes = append(reportNodes, nextNode) - lastNode = nextNode - } - - var buf bytes.Buffer - if err := format.Node(&buf, token.NewFileSet(), group); err != nil { - return false - } - - // We add a diagnostic to every subsequent statement to properly represent - // the violations. Duplicate fixes for the same range is fine. - for _, n := range reportNodes { - w.groupedDecls[n.End()] = struct{}{} - - w.addErrorWithMessageAndFix( - n.Pos(), - firstNode.Pos(), - lastNode.End(), - fmt.Sprintf("%s (never cuddle %s)", messageMissingWhitespaceAbove, CheckDecl), - buf.Bytes(), - ) - } - - return true -} - -func (w *WSL) maybeCheckBlock( - node ast.Node, - blockStmt *ast.BlockStmt, - cursor *Cursor, - check CheckType, -) { - w.checkBlock(blockStmt) - - if _, ok := w.config.Checks[check]; ok { - cursor.SetChecker(check) - - var ( - blockList []ast.Stmt - allowedIdents []*ast.Ident - ) - - if check != CheckSwitch && check != CheckTypeSwitch && check != CheckSelect { - blockList = blockStmt.List - } else { - allowedIdents = w.identsFromCaseArms(node) - } - - w.checkCuddlingBlock(node, blockList, allowedIdents, cursor, 1) - } -} - -func (w *WSL) maybeCheckExpr( - node ast.Node, - expr ast.Expr, - cursor *Cursor, - predicate func(ast.Node) (int, bool), - check CheckType, -) { - w.checkExpr(expr, cursor) - - if _, ok := w.config.Checks[check]; ok { - cursor.SetChecker(check) - previousNode := cursor.PreviousNode() - - if n, ok := predicate(previousNode); ok { - w.checkCuddling(node, cursor, n) - } - } -} - -// numberOfStatementsAbove will find out how many lines above the cursor's -// current statement there is without any newlines between. -func (w *WSL) numberOfStatementsAbove(cursor *Cursor) int { - defer cursor.Save()() - - statementsWithoutNewlines := 0 - currentStmtStartLine := w.lineFor(cursor.Stmt().Pos()) - - for cursor.Previous() { - previousStmtEndLine := w.lineFor(cursor.Stmt().End()) - if previousStmtEndLine != currentStmtStartLine-1 { - break - } - - currentStmtStartLine = w.lineFor(cursor.Stmt().Pos()) - statementsWithoutNewlines++ - } - - return statementsWithoutNewlines -} - -func (w *WSL) lineFor(pos token.Pos) int { - return w.fset.PositionFor(pos, false).Line -} - -func (w *WSL) implementsErr(node *ast.Ident) bool { - typeInfo := w.typeInfo.TypeOf(node) - if typeInfo == nil { - return false - } - - errorType, ok := types.Universe.Lookup("error").Type().Underlying().(*types.Interface) - if !ok { - return false - } - - return types.Implements(typeInfo, errorType) -} - -func (w *WSL) addErrorInvalidTypeCuddle(pos token.Pos, ct CheckType) { - reportMessage := fmt.Sprintf("%s (invalid statement above %s)", messageMissingWhitespaceAbove, ct) - w.addErrorWithMessage(pos, pos, pos, reportMessage) -} - -func (w *WSL) addErrorTooManyStatements(pos token.Pos, ct CheckType) { - reportMessage := fmt.Sprintf("%s (too many statements above %s)", messageMissingWhitespaceAbove, ct) - w.addErrorWithMessage(pos, pos, pos, reportMessage) -} - -func (w *WSL) addErrorNoIntersection(pos token.Pos, ct CheckType) { - reportMessage := fmt.Sprintf("%s (no shared variables above %s)", messageMissingWhitespaceAbove, ct) - w.addErrorWithMessage(pos, pos, pos, reportMessage) -} - -func (w *WSL) addErrorTooManyLines(pos token.Pos, ct CheckType) { - reportMessage := fmt.Sprintf("%s (too many lines above %s)", messageMissingWhitespaceAbove, ct) - w.addErrorWithMessage(pos, pos, pos, reportMessage) -} - -func (w *WSL) addErrorNeverAllow(pos token.Pos, ct CheckType) { - reportMessage := fmt.Sprintf("%s (never cuddle %s)", messageMissingWhitespaceAbove, ct) - w.addErrorWithMessage(pos, pos, pos, reportMessage) -} - -func (w *WSL) addError(report, start, end token.Pos, message string, ct CheckType) { - reportMessage := fmt.Sprintf("%s (%s)", message, ct) - w.addErrorWithMessage(report, start, end, reportMessage) -} - -func (w *WSL) addErrorWithMessage(report, start, end token.Pos, message string) { - w.addErrorWithMessageAndFix(report, start, end, message, []byte("\n")) -} - -func (w *WSL) addErrorWithMessageAndFix(report, start, end token.Pos, message string, fix []byte) { - iss, ok := w.issues[report] - if !ok { - iss = issue{ - message: message, - fixRanges: []fixRange{}, - } - } - - iss.fixRanges = append(iss.fixRanges, fixRange{ - fixRangeStart: start, - fixRangeEnd: end, - fix: fix, - }) - - w.issues[report] = iss -} - -func asGenDeclWithValueSpecs(n ast.Node) *ast.GenDecl { - decl, ok := n.(*ast.DeclStmt) - if !ok { - return nil - } - - genDecl, ok := decl.Decl.(*ast.GenDecl) - if !ok { - return nil - } - - for _, spec := range genDecl.Specs { - // We only care about value specs and not type specs or import - // specs. We will never see any import specs but type specs we just - // separate with an empty line as usual. - valueSpec, ok := spec.(*ast.ValueSpec) - if !ok { - return nil - } - - // It's very hard to get comments right in the ast and with the current - // way the ast package works we simply don't support grouping at all if - // there are any comments related to the node. - if valueSpec.Doc != nil || valueSpec.Comment != nil { - return nil - } - } - - return genDecl -} - -func (w *WSL) hasIntersection(a, b ast.Node) bool { - return len(w.nodeIdentIntersection(a, b)) > 0 -} - -func (w *WSL) nodeIdentIntersection(a, b ast.Node) []*ast.Ident { - aI := w.identsFromNode(a, true) - bI := w.identsFromNode(b, true) - - return identIntersection(aI, bI) -} - -func identIntersection(a, b []*ast.Ident) []*ast.Ident { - intersects := []*ast.Ident{} - - for _, as := range a { - for _, bs := range b { - if as.Name == bs.Name { - intersects = append(intersects, as) - } - } - } - - return intersects -} - -func isTypeOrPredeclConst(obj types.Object) bool { - switch o := obj.(type) { - case *types.TypeName: - // Covers predeclared types ("string", "int", ...) and user types. - return true - case *types.Const: - // true/false/iota are universe consts. - return o.Parent() == types.Universe - case *types.Nil: - return true - case *types.PkgName: - // Skip package qualifiers like "fmt" in fmt.Println - return true - default: - return false - } -} - -// identsFromNode returns all *ast.Ident in a node except: -// - type names (types.TypeName) -// - builtin constants from the universe (true, false, iota) -// - nil (*types.Nil) -// - package names (types.PkgName) -// - the blank identifier "_" -func (w *WSL) identsFromNode(node ast.Node, skipBlock bool) []*ast.Ident { - var ( - idents []*ast.Ident - seen = map[string]struct{}{} - ) - - if node == nil { - return idents - } - - addIdent := func(ident *ast.Ident) { - if ident == nil { - return - } - - name := ident.Name - if name == "" || name == "_" { - return - } - - if _, ok := seen[name]; ok { - return - } - - idents = append(idents, ident) - seen[name] = struct{}{} - } - - ast.Inspect(node, func(n ast.Node) bool { - if skipBlock { - if _, ok := n.(*ast.BlockStmt); ok { - return false - } - } - - ident, ok := n.(*ast.Ident) - if !ok { - return true - } - - // Prefer Uses over Defs; fall back to Defs if not a use site. - var typesObject types.Object - if obj := w.typeInfo.Uses[ident]; obj != nil { - typesObject = obj - } else if obj := w.typeInfo.Defs[ident]; obj != nil { - typesObject = obj - } - - // Unresolved (could be a build-tag or syntax artifact). Keep it. - if typesObject == nil { - addIdent(ident) - return true - } - - if isTypeOrPredeclConst(typesObject) { - return true - } - - addIdent(ident) - - return true - }) - - return idents -} - -func (w *WSL) identsFromCaseArms(node ast.Node) []*ast.Ident { - var ( - idents []*ast.Ident - nodes []ast.Stmt - seen = map[string]struct{}{} - - addUnseen = func(node ast.Node) { - for _, ident := range w.identsFromNode(node, true) { - if _, ok := seen[ident.Name]; ok { - continue - } - - seen[ident.Name] = struct{}{} - idents = append(idents, ident) - } - } - ) - - switch v := node.(type) { - case *ast.SwitchStmt: - nodes = v.Body.List - case *ast.TypeSwitchStmt: - nodes = v.Body.List - case *ast.SelectStmt: - nodes = v.Body.List - default: - return idents - } - - for _, node := range nodes { - switch n := node.(type) { - case *ast.CommClause: - addUnseen(n.Comm) - case *ast.CaseClause: - for _, n := range n.List { - addUnseen(n) - } - default: - continue - } - } - - return idents -} diff --git a/vendor/github.com/breml/bidichk/LICENSE b/vendor/github.com/breml/bidichk/LICENSE deleted file mode 100644 index 47a8419ce9..0000000000 --- a/vendor/github.com/breml/bidichk/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2021 Lucas Bremgartner - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/breml/bidichk/pkg/bidichk/bidichk.go b/vendor/github.com/breml/bidichk/pkg/bidichk/bidichk.go deleted file mode 100644 index 39d3cd44ec..0000000000 --- a/vendor/github.com/breml/bidichk/pkg/bidichk/bidichk.go +++ /dev/null @@ -1,181 +0,0 @@ -package bidichk - -import ( - "bytes" - "flag" - "fmt" - "go/token" - "os" - "sort" - "strings" - "unicode/utf8" - - "golang.org/x/tools/go/analysis" -) - -const ( - doc = "Checks for dangerous unicode character sequences" - disallowedDoc = `comma separated list of disallowed runes (full name or short name) - -Supported runes - -LEFT-TO-RIGHT-EMBEDDING, LRE (u+202A) -RIGHT-TO-LEFT-EMBEDDING, RLE (u+202B) -POP-DIRECTIONAL-FORMATTING, PDF (u+202C) -LEFT-TO-RIGHT-OVERRIDE, LRO (u+202D) -RIGHT-TO-LEFT-OVERRIDE, RLO (u+202E) -LEFT-TO-RIGHT-ISOLATE, LRI (u+2066) -RIGHT-TO-LEFT-ISOLATE, RLI (u+2067) -FIRST-STRONG-ISOLATE, FSI (u+2068) -POP-DIRECTIONAL-ISOLATE, PDI (u+2069) -` -) - -type disallowedRunes map[string]rune - -func (m disallowedRunes) String() string { - ss := make([]string, 0, len(m)) - for s := range m { - ss = append(ss, s) - } - sort.Strings(ss) - return strings.Join(ss, ",") -} - -func (m disallowedRunes) Set(s string) error { - ss := strings.FieldsFunc(s, func(c rune) bool { return c == ',' }) - if len(ss) == 0 { - return nil - } - - for k := range m { - delete(m, k) - } - - for _, v := range ss { - switch v { - case runeShortNameLRE, runeShortNameRLE, runeShortNamePDF, - runeShortNameLRO, runeShortNameRLO, runeShortNameLRI, - runeShortNameRLI, runeShortNameFSI, runeShortNamePDI: - v = shortNameLookup[v] - fallthrough - case runeNameLRE, runeNameRLE, runeNamePDF, - runeNameLRO, runeNameRLO, runeNameLRI, - runeNameRLI, runeNameFSI, runeNamePDI: - m[v] = runeLookup[v] - default: - return fmt.Errorf("unknown check name %q (see help for full list)", v) - } - } - return nil -} - -const ( - runeNameLRE = "LEFT-TO-RIGHT-EMBEDDING" - runeNameRLE = "RIGHT-TO-LEFT-EMBEDDING" - runeNamePDF = "POP-DIRECTIONAL-FORMATTING" - runeNameLRO = "LEFT-TO-RIGHT-OVERRIDE" - runeNameRLO = "RIGHT-TO-LEFT-OVERRIDE" - runeNameLRI = "LEFT-TO-RIGHT-ISOLATE" - runeNameRLI = "RIGHT-TO-LEFT-ISOLATE" - runeNameFSI = "FIRST-STRONG-ISOLATE" - runeNamePDI = "POP-DIRECTIONAL-ISOLATE" - - runeShortNameLRE = "LRE" // LEFT-TO-RIGHT-EMBEDDING - runeShortNameRLE = "RLE" // RIGHT-TO-LEFT-EMBEDDING - runeShortNamePDF = "PDF" // POP-DIRECTIONAL-FORMATTING - runeShortNameLRO = "LRO" // LEFT-TO-RIGHT-OVERRIDE - runeShortNameRLO = "RLO" // RIGHT-TO-LEFT-OVERRIDE - runeShortNameLRI = "LRI" // LEFT-TO-RIGHT-ISOLATE - runeShortNameRLI = "RLI" // RIGHT-TO-LEFT-ISOLATE - runeShortNameFSI = "FSI" // FIRST-STRONG-ISOLATE - runeShortNamePDI = "PDI" // POP-DIRECTIONAL-ISOLATE -) - -var runeLookup = map[string]rune{ - runeNameLRE: '\u202A', // LEFT-TO-RIGHT-EMBEDDING - runeNameRLE: '\u202B', // RIGHT-TO-LEFT-EMBEDDING - runeNamePDF: '\u202C', // POP-DIRECTIONAL-FORMATTING - runeNameLRO: '\u202D', // LEFT-TO-RIGHT-OVERRIDE - runeNameRLO: '\u202E', // RIGHT-TO-LEFT-OVERRIDE - runeNameLRI: '\u2066', // LEFT-TO-RIGHT-ISOLATE - runeNameRLI: '\u2067', // RIGHT-TO-LEFT-ISOLATE - runeNameFSI: '\u2068', // FIRST-STRONG-ISOLATE - runeNamePDI: '\u2069', // POP-DIRECTIONAL-ISOLATE -} - -var shortNameLookup = map[string]string{ - runeShortNameLRE: runeNameLRE, - runeShortNameRLE: runeNameRLE, - runeShortNamePDF: runeNamePDF, - runeShortNameLRO: runeNameLRO, - runeShortNameRLO: runeNameRLO, - runeShortNameLRI: runeNameLRI, - runeShortNameRLI: runeNameRLI, - runeShortNameFSI: runeNameFSI, - runeShortNamePDI: runeNamePDI, -} - -type bidichk struct { - disallowedRunes disallowedRunes -} - -// NewAnalyzer return a new bidichk analyzer. -func NewAnalyzer() *analysis.Analyzer { - bidichk := bidichk{} - bidichk.disallowedRunes = make(map[string]rune, len(runeLookup)) - for k, v := range runeLookup { - bidichk.disallowedRunes[k] = v - } - - a := &analysis.Analyzer{ - Name: "bidichk", - Doc: doc, - Run: bidichk.run, - } - - a.Flags.Init("bidichk", flag.ExitOnError) - a.Flags.Var(&bidichk.disallowedRunes, "disallowed-runes", disallowedDoc) - a.Flags.Var(versionFlag{}, "V", "print version and exit") - - return a -} - -func (b bidichk) run(pass *analysis.Pass) (interface{}, error) { - readFile := pass.ReadFile - if readFile == nil { - readFile = os.ReadFile - } - - for _, astFile := range pass.Files { - f := pass.Fset.File(astFile.FileStart) - if f == nil { - continue - } - - body, err := readFile(f.Name()) - if err != nil { - return nil, err - } - - b.check(body, f.Pos(0), pass) - } - return nil, nil -} - -func (b bidichk) check(body []byte, pos token.Pos, pass *analysis.Pass) { - for name, r := range b.disallowedRunes { - start := 0 - for { - idx := bytes.IndexRune(body[start:], r) - if idx == -1 { - break - } - start += idx - - pass.Reportf(pos+token.Pos(start), "found dangerous unicode character sequence %s", name) - - start += utf8.RuneLen(r) - } - } -} diff --git a/vendor/github.com/breml/bidichk/pkg/bidichk/version.go b/vendor/github.com/breml/bidichk/pkg/bidichk/version.go deleted file mode 100644 index 4cfc57dd1e..0000000000 --- a/vendor/github.com/breml/bidichk/pkg/bidichk/version.go +++ /dev/null @@ -1,19 +0,0 @@ -package bidichk - -import ( - "fmt" - "os" -) - -var Version = "bidichk version dev" - -type versionFlag struct{} - -func (versionFlag) IsBoolFlag() bool { return true } -func (versionFlag) Get() interface{} { return nil } -func (versionFlag) String() string { return "" } -func (versionFlag) Set(s string) error { - fmt.Println(Version) - os.Exit(0) - return nil -} diff --git a/vendor/github.com/breml/errchkjson/.gitignore b/vendor/github.com/breml/errchkjson/.gitignore deleted file mode 100644 index 0362de3016..0000000000 --- a/vendor/github.com/breml/errchkjson/.gitignore +++ /dev/null @@ -1,29 +0,0 @@ -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib -/errchkjson -/cmd/errchkjson/errchkjson - -# Test binary, build with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out -coverage.html - -# Log files -*.log - -# Env files -.env - -# Exclude todo -TODO.md - -# Exclude IDE settings -.idea/ -*.iml -.vscode/ diff --git a/vendor/github.com/breml/errchkjson/.goreleaser.yml b/vendor/github.com/breml/errchkjson/.goreleaser.yml deleted file mode 100644 index 1113690539..0000000000 --- a/vendor/github.com/breml/errchkjson/.goreleaser.yml +++ /dev/null @@ -1,37 +0,0 @@ ---- -version: 2 - -# This is an example .goreleaser.yml file with some sane defaults. -# Make sure to check the documentation at http://goreleaser.com -before: - hooks: - # You may remove this if you don't use go modules. - - go mod tidy -builds: - - main: ./cmd/errchkjson - binary: errchkjson - env: - - CGO_ENABLED=0 - goos: - - linux - - windows - - darwin -archives: - - name_template: >- - {{- .Binary }}_ - {{- .Version }}_ - {{- title .Os }}_ - {{- if eq .Arch "amd64" }}x86_64 - {{- else if eq .Arch "386" }}i386 - {{- else }}{{ .Arch }}{{ end }} - {{- if .Arm }}v{{ .Arm }}{{ end -}} -snapshot: - version_template: "{{ .Tag }}-next" -changelog: - disable: true -release: - github: - owner: breml - name: errchkjson -gomod: - proxy: true diff --git a/vendor/github.com/breml/errchkjson/LICENSE b/vendor/github.com/breml/errchkjson/LICENSE deleted file mode 100644 index 08db5cb6fc..0000000000 --- a/vendor/github.com/breml/errchkjson/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2019 Lucas Bremgartner - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/breml/errchkjson/README.md b/vendor/github.com/breml/errchkjson/README.md deleted file mode 100644 index a387ea23d2..0000000000 --- a/vendor/github.com/breml/errchkjson/README.md +++ /dev/null @@ -1,131 +0,0 @@ -# errchkjson - -[![Test Status](https://github.com/breml/errchkjson/actions/workflows/ci.yml/badge.svg)](https://github.com/breml/errchkjson/actions/workflows/ci.yml) [![Go Report Card](https://goreportcard.com/badge/github.com/breml/errchkjson)](https://goreportcard.com/report/github.com/breml/errchkjson) [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) - -Checks types passed to the json encoding functions. Reports unsupported types and reports occurrences where the check for the returned error can be omitted. - -Consider this [http.Handler](https://pkg.go.dev/net/http#Handler): - -```Go -func JSONHelloWorld(w http.ResponseWriter, r *http.Request) { - response := struct { - Message string - Code int - }{ - Message: "Hello World", - Code: 200, - } - - body, err := json.Marshal(response) - if err != nil { - panic(err) // unreachable, because json encoding of a struct with just a string and an int will never return an error. - } - - w.Write(body) -} -``` - -Because the `panic` is not possible to happen, one might refactor the code like this: - -```Go -func JSONHelloWorld(w http.ResponseWriter, r *http.Request) { - response := struct { - Message string - Code int - }{ - Message: "Hello World", - Code: 200, - } - - body, _ := json.Marshal(response) - - w.Write(body) -} -``` - -This is ok, as long as the struct is not altered in such a way, that could potentially lead -to `json.Marshal` returning an error. - -`errchkjson` allows you to lint your code such that the above error returned from `json.Marshal` -can be omitted while still staying safe, because as soon as an unsafe type is added to the -response type, the linter will warn you. - -## Installation - -Download `errchkjson` from the [releases](https://github.com/breml/errchkjson/releases) or get the latest version from source with: - -```shell -go install github.com/breml/errchkjson/cmd/errchkjson@latest -``` - -## Usage - -### Shell - -Check everything: - -```shell -errchkjson ./... -``` - -`errchkjson` also recognizes the following command-line options: - -The `-omit-safe` flag disables checking for safe returns of errors from json.Marshal - -## Types - -### Safe - -The following types are safe to use with [json encoding functions](https://pkg.go.dev/encoding/json), that is, the encoding to JSON can not fail: - -Safe basic types: - -* `bool` -* `int`, `int8`, `int16`, `int32`, `int64`, `uint`, `uint8`, `uint16`, `uint32`, `uint64`, `uintptr` -* `string` -* Pointer type of the above listed basic types - -Composed types (struct, map, slice, array) are safe, if the type of the value is -safe. For structs, only exported fields are relevant. For maps, the key needs to be either an integer type or a string. - -### Unsafe - -The following types are unsafe to use with [json encoding functions](https://pkg.go.dev/encoding/json), that is, the encoding to JSON can fail (return an error): - -Unsafe basic types: - -* `float32`, `float64` -* `interface{}` -* Pointer type of the above listed basic types - -Any composed types (struct, map, slice, array) containing an unsafe basic type. - -If a type implements the `json.Marshaler` or `encoding.TextMarshaler` interface (e.g. `json.Number`). - -### Forbidden - -Forbidden basic types: - -* `complex64`, `complex128` -* `chan` -* `func` -* `unsafe.Pointer` - -Any composed types (struct, map, slice, array) containing a forbidden basic type. Any map -using a key with a forbidden type (`bool`, `float32`, `float64`, `struct`). - -## Accepted edge case - -For `encoding/json.MarshalIndent`, there is a (pathological) edge case, where this -function could [return an error](https://cs.opensource.google/go/go/+/refs/tags/go1.18:src/encoding/json/scanner.go;drc=refs%2Ftags%2Fgo1.18;l=181) for an otherwise safe argument, if the argument has -a nesting depth larger than [`10000`](https://cs.opensource.google/go/go/+/refs/tags/go1.18:src/encoding/json/scanner.go;drc=refs%2Ftags%2Fgo1.18;l=144) (as of Go 1.18). - -## Bugs found during development - -During the development of `errcheckjson`, the following issues in package `encoding/json` of the Go standard library have been found and PR have been merged: - -* [Issue #34154: encoding/json: string option (struct tag) on string field with SetEscapeHTML(false) escapes anyway](https://github.com/golang/go/issues/34154) -* [PR #34127: encoding/json: fix and optimize marshal for quoted string](https://github.com/golang/go/pull/34127) -* [Issue #34268: encoding/json: wrong encoding for json.Number field with string option (struct tag)](https://github.com/golang/go/issues/34268) -* [PR #34269: encoding/json: make Number with the ,string option marshal with quotes](https://github.com/golang/go/pull/34269) -* [PR #34272: encoding/json: validate strings when decoding into Number](https://github.com/golang/go/pull/34272) diff --git a/vendor/github.com/breml/errchkjson/errchkjson.go b/vendor/github.com/breml/errchkjson/errchkjson.go deleted file mode 100644 index 7c8cd82e96..0000000000 --- a/vendor/github.com/breml/errchkjson/errchkjson.go +++ /dev/null @@ -1,348 +0,0 @@ -// Package errchkjson defines an Analyzer that finds places, where it is -// safe to omit checking the error returned from json.Marshal. -package errchkjson - -import ( - "flag" - "fmt" - "go/ast" - "go/token" - "go/types" - "reflect" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/types/typeutil" -) - -type errchkjson struct { - omitSafe bool // -omit-safe flag - reportNoExported bool // -report-no-exported flag -} - -// NewAnalyzer returns a new errchkjson analyzer. -func NewAnalyzer() *analysis.Analyzer { - errchkjson := &errchkjson{} - - a := &analysis.Analyzer{ - Name: "errchkjson", - Doc: "Checks types passed to the json encoding functions. Reports unsupported types and reports occurrences where the check for the returned error can be omitted.", - Run: errchkjson.run, - } - - a.Flags.Init("errchkjson", flag.ExitOnError) - a.Flags.BoolVar(&errchkjson.omitSafe, "omit-safe", false, "if omit-safe is true, checking of safe returns is omitted") - a.Flags.BoolVar(&errchkjson.reportNoExported, "report-no-exported", false, "if report-no-exported is true, encoding a struct without exported fields is reported as issue") - a.Flags.Var(versionFlag{}, "V", "print version and exit") - - return a -} - -func (e *errchkjson) run(pass *analysis.Pass) (interface{}, error) { - for _, file := range pass.Files { - ast.Inspect(file, func(n ast.Node) bool { - if n == nil { - return true - } - - // if the error is returned, it is the caller's responsibility to check - // the return value. - if _, ok := n.(*ast.ReturnStmt); ok { - return false - } - - ce, ok := n.(*ast.CallExpr) - if ok { - fn, _ := typeutil.Callee(pass.TypesInfo, ce).(*types.Func) - if fn == nil { - return true - } - - switch fn.FullName() { - case "encoding/json.Marshal", "encoding/json.MarshalIndent": - e.handleJSONMarshal(pass, ce, fn.FullName(), blankIdentifier, e.omitSafe) - case "(*encoding/json.Encoder).Encode": - e.handleJSONMarshal(pass, ce, fn.FullName(), blankIdentifier, true) - default: - e.inspectArgs(pass, ce.Args) - } - return false - } - - as, ok := n.(*ast.AssignStmt) - if !ok { - return true - } - - ce, ok = as.Rhs[0].(*ast.CallExpr) - if !ok { - return true - } - - fn, _ := typeutil.Callee(pass.TypesInfo, ce).(*types.Func) - if fn == nil { - return true - } - - switch fn.FullName() { - case "encoding/json.Marshal", "encoding/json.MarshalIndent": - e.handleJSONMarshal(pass, ce, fn.FullName(), evaluateMarshalErrorTarget(as.Lhs[1]), e.omitSafe) - case "(*encoding/json.Encoder).Encode": - e.handleJSONMarshal(pass, ce, fn.FullName(), evaluateMarshalErrorTarget(as.Lhs[0]), true) - default: - return true - } - return false - }) - } - - return nil, nil -} - -func evaluateMarshalErrorTarget(n ast.Expr) marshalErrorTarget { - if errIdent, ok := n.(*ast.Ident); ok { - if errIdent.Name == "_" { - return blankIdentifier - } - } - return variableAssignment -} - -type marshalErrorTarget int - -const ( - blankIdentifier = iota // the returned error from the JSON marshal function is assigned to the blank identifier "_". - variableAssignment // the returned error from the JSON marshal function is assigned to a variable. - functionArgument // the returned error from the JSON marshal function is passed to an other function as argument. -) - -func (e *errchkjson) handleJSONMarshal(pass *analysis.Pass, ce *ast.CallExpr, fnName string, errorTarget marshalErrorTarget, omitSafe bool) { - t := pass.TypesInfo.TypeOf(ce.Args[0]) - if t == nil { - // Not sure, if this is at all possible - if errorTarget == blankIdentifier { - pass.Reportf(ce.Pos(), "Type of argument to `%s` could not be evaluated and error return value is not checked", fnName) - } - return - } - - if _, ok := t.(*types.Pointer); ok { - t = t.(*types.Pointer).Elem() - } - - err := e.jsonSafe(t, 0, map[types.Type]struct{}{}) - if err != nil { - if _, ok := err.(unsupported); ok { - pass.Reportf(ce.Pos(), "`%s` for %v", fnName, err) - return - } - if _, ok := err.(noexported); ok { - pass.Reportf(ce.Pos(), "Error argument passed to `%s` does not contain any exported field", fnName) - } - // Only care about unsafe types if they are assigned to the blank identifier. - if errorTarget == blankIdentifier { - pass.Reportf(ce.Pos(), "Error return value of `%s` is not checked: %v", fnName, err) - } - } - if err == nil && errorTarget == variableAssignment && !omitSafe { - pass.Reportf(ce.Pos(), "Error return value of `%s` is checked but passed argument is safe", fnName) - } - // Report an error, if err for json.Marshal is not checked and safe types are omitted - if err == nil && errorTarget == blankIdentifier && omitSafe { - pass.Reportf(ce.Pos(), "Error return value of `%s` is not checked", fnName) - } -} - -const ( - allowedBasicTypes = types.IsBoolean | types.IsInteger | types.IsString - allowedMapKeyBasicTypes = types.IsInteger | types.IsString - unsupportedBasicTypes = types.IsComplex -) - -func (e *errchkjson) jsonSafe(t types.Type, level int, seenTypes map[types.Type]struct{}) error { - if _, ok := seenTypes[t]; ok { - return nil - } - - if types.Implements(t, textMarshalerInterface()) || types.Implements(t, jsonMarshalerInterface()) { - return fmt.Errorf("unsafe type `%s` found", t.String()) - } - - switch ut := t.Underlying().(type) { - case *types.Basic: - if ut.Info()&allowedBasicTypes > 0 { // bool, int-family, string - if ut.Info()&types.IsString > 0 && t.String() == "encoding/json.Number" { - return fmt.Errorf("unsafe type `%s` found", t.String()) - } - return nil - } - if ut.Info()&unsupportedBasicTypes > 0 { // complex64, complex128 - return newUnsupportedError(fmt.Errorf("unsupported type `%s` found", ut.String())) - } - switch ut.Kind() { - case types.UntypedNil: - return nil - case types.UnsafePointer: - return newUnsupportedError(fmt.Errorf("unsupported type `%s` found", ut.String())) - default: - // E.g. float32, float64 - return fmt.Errorf("unsafe type `%s` found", ut.String()) - } - - case *types.Array: - err := e.jsonSafe(ut.Elem(), level+1, seenTypes) - if err != nil { - return err - } - return nil - - case *types.Slice: - err := e.jsonSafe(ut.Elem(), level+1, seenTypes) - if err != nil { - return err - } - return nil - - case *types.Struct: - seenTypes[t] = struct{}{} - exported := 0 - for i := 0; i < ut.NumFields(); i++ { - if !ut.Field(i).Exported() { - // Unexported fields can be ignored - continue - } - if tag, ok := reflect.StructTag(ut.Tag(i)).Lookup("json"); ok { - if tag == "-" { - // Fields omitted in json can be ignored - continue - } - } - err := e.jsonSafe(ut.Field(i).Type(), level+1, seenTypes) - if err != nil { - return err - } - exported++ - } - if e.reportNoExported && level == 0 && exported == 0 { - return newNoexportedError(fmt.Errorf("struct does not export any field")) - } - return nil - - case *types.Pointer: - err := e.jsonSafe(ut.Elem(), level+1, seenTypes) - if err != nil { - return err - } - return nil - - case *types.Map: - err := jsonSafeMapKey(ut.Key()) - if err != nil { - return err - } - err = e.jsonSafe(ut.Elem(), level+1, seenTypes) - if err != nil { - return err - } - return nil - - case *types.Chan, *types.Signature: - // Types that are not supported for encoding to json: - return newUnsupportedError(fmt.Errorf("unsupported type `%s` found", ut.String())) - - default: - // Types that are not supported for encoding to json or are not completely safe, like: interfaces - return fmt.Errorf("unsafe type `%s` found", t.String()) - } -} - -func jsonSafeMapKey(t types.Type) error { - if types.Implements(t, textMarshalerInterface()) || types.Implements(t, jsonMarshalerInterface()) { - return fmt.Errorf("unsafe type `%s` as map key found", t.String()) - } - switch ut := t.Underlying().(type) { - case *types.Basic: - if ut.Info()&types.IsString > 0 && t.String() == "encoding/json.Number" { - return fmt.Errorf("unsafe type `%s` as map key found", t.String()) - } - if ut.Info()&allowedMapKeyBasicTypes > 0 { // bool, int-family, string - return nil - } - // E.g. bool, float32, float64, complex64, complex128 - return newUnsupportedError(fmt.Errorf("unsupported type `%s` as map key found", t.String())) - case *types.Interface: - return fmt.Errorf("unsafe type `%s` as map key found", t.String()) - default: - // E.g. struct composed solely of basic types, that are comparable - return newUnsupportedError(fmt.Errorf("unsupported type `%s` as map key found", t.String())) - } -} - -func (e *errchkjson) inspectArgs(pass *analysis.Pass, args []ast.Expr) { - for _, a := range args { - ast.Inspect(a, func(n ast.Node) bool { - if n == nil { - return true - } - - ce, ok := n.(*ast.CallExpr) - if !ok { - return false - } - - fn, _ := typeutil.Callee(pass.TypesInfo, ce).(*types.Func) - if fn == nil { - return true - } - - switch fn.FullName() { - case "encoding/json.Marshal", "encoding/json.MarshalIndent": - e.handleJSONMarshal(pass, ce, fn.FullName(), functionArgument, e.omitSafe) - case "(*encoding/json.Encoder).Encode": - e.handleJSONMarshal(pass, ce, fn.FullName(), functionArgument, true) - default: - e.inspectArgs(pass, ce.Args) - } - return false - }) - } -} - -// Construct *types.Interface for interface encoding.TextMarshaler -// -// type TextMarshaler interface { -// MarshalText() (text []byte, err error) -// } -func textMarshalerInterface() *types.Interface { - textMarshalerInterface := types.NewInterfaceType([]*types.Func{ - types.NewFunc(token.NoPos, nil, "MarshalText", types.NewSignatureType( - nil, nil, nil, nil, types.NewTuple( - types.NewVar(token.NoPos, nil, "text", - types.NewSlice( - types.Universe.Lookup("byte").Type())), - types.NewVar(token.NoPos, nil, "err", types.Universe.Lookup("error").Type())), - false)), - }, nil) - textMarshalerInterface.Complete() - - return textMarshalerInterface -} - -// Construct *types.Interface for interface json.Marshaler -// -// type Marshaler interface { -// MarshalJSON() ([]byte, error) -// } -func jsonMarshalerInterface() *types.Interface { - textMarshalerInterface := types.NewInterfaceType([]*types.Func{ - types.NewFunc(token.NoPos, nil, "MarshalJSON", types.NewSignatureType( - nil, nil, nil, nil, types.NewTuple( - types.NewVar(token.NoPos, nil, "", - types.NewSlice( - types.Universe.Lookup("byte").Type())), - types.NewVar(token.NoPos, nil, "", types.Universe.Lookup("error").Type())), - false)), - }, nil) - textMarshalerInterface.Complete() - - return textMarshalerInterface -} diff --git a/vendor/github.com/breml/errchkjson/noexported_error.go b/vendor/github.com/breml/errchkjson/noexported_error.go deleted file mode 100644 index 07b7a07d26..0000000000 --- a/vendor/github.com/breml/errchkjson/noexported_error.go +++ /dev/null @@ -1,23 +0,0 @@ -package errchkjson - -type noexported interface { - noexported() -} - -var _ noexported = noexportedError{} - -type noexportedError struct { - err error -} - -func newNoexportedError(err error) error { - return noexportedError{ - err: err, - } -} - -func (u noexportedError) noexported() {} - -func (u noexportedError) Error() string { - return u.err.Error() -} diff --git a/vendor/github.com/breml/errchkjson/unsupported_error.go b/vendor/github.com/breml/errchkjson/unsupported_error.go deleted file mode 100644 index 1a38c3f532..0000000000 --- a/vendor/github.com/breml/errchkjson/unsupported_error.go +++ /dev/null @@ -1,23 +0,0 @@ -package errchkjson - -type unsupported interface { - unsupported() -} - -var _ unsupported = unsupportedError{} - -type unsupportedError struct { - err error -} - -func newUnsupportedError(err error) error { - return unsupportedError{ - err: err, - } -} - -func (u unsupportedError) unsupported() {} - -func (u unsupportedError) Error() string { - return u.err.Error() -} diff --git a/vendor/github.com/breml/errchkjson/version.go b/vendor/github.com/breml/errchkjson/version.go deleted file mode 100644 index 77d8ef8bb0..0000000000 --- a/vendor/github.com/breml/errchkjson/version.go +++ /dev/null @@ -1,19 +0,0 @@ -package errchkjson - -import ( - "fmt" - "os" -) - -var Version = "errchkjson version dev" - -type versionFlag struct{} - -func (versionFlag) IsBoolFlag() bool { return true } -func (versionFlag) Get() interface{} { return nil } -func (versionFlag) String() string { return "" } -func (versionFlag) Set(s string) error { - fmt.Println(Version) - os.Exit(0) - return nil -} diff --git a/vendor/github.com/butuzov/ireturn/LICENSE b/vendor/github.com/butuzov/ireturn/LICENSE deleted file mode 100644 index a9752e9726..0000000000 --- a/vendor/github.com/butuzov/ireturn/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2021 Oleg Butuzov - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/butuzov/ireturn/analyzer/analyzer.go b/vendor/github.com/butuzov/ireturn/analyzer/analyzer.go deleted file mode 100644 index 86cc464c64..0000000000 --- a/vendor/github.com/butuzov/ireturn/analyzer/analyzer.go +++ /dev/null @@ -1,278 +0,0 @@ -package analyzer - -import ( - "flag" - "go/ast" - gotypes "go/types" - "runtime" - "strings" - "sync" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/inspector" - - "github.com/butuzov/ireturn/analyzer/internal/config" - "github.com/butuzov/ireturn/analyzer/internal/types" -) - -const name string = "ireturn" // linter name - -type validator interface { - IsValid(types.IFace) bool -} - -type analyzer struct { - once sync.Once - mu sync.RWMutex - handler validator - err error - disabledNolint bool - - found []analysis.Diagnostic -} - -func (a *analyzer) run(pass *analysis.Pass) (interface{}, error) { - // 00. Part 1. Handling Configuration Only Once. - a.once.Do(func() { a.readConfiguration(&pass.Analyzer.Flags) }) - - // 00. Part 2. Handling Errors - if a.err != nil { - return nil, a.err - } - - ins, _ := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - - // 00. does file have dot-imported standard packages? - dotImportedStd := make(map[string]struct{}) - ins.Preorder([]ast.Node{(*ast.ImportSpec)(nil)}, func(node ast.Node) { - i, _ := node.(*ast.ImportSpec) - if i.Name != nil && i.Name.Name == "." { - dotImportedStd[strings.Trim(i.Path.Value, `"`)] = struct{}{} - } - }) - - // 01. Running Inspection. - ins.Preorder([]ast.Node{(*ast.FuncDecl)(nil)}, func(node ast.Node) { - // 001. Casting to funcdecl - f, _ := node.(*ast.FuncDecl) - - // 002. Does it return any results ? - if f.Type == nil || f.Type.Results == nil { - return - } - - // 003. Is it allowed to be checked? - if !a.disabledNolint && hasDisallowDirective(f.Doc) { - return - } - - seen := make(map[string]bool, 4) - - // 004. Filtering Results. - for _, issue := range filterInterfaces(pass, f.Type, dotImportedStd) { - if a.handler.IsValid(issue) { - continue - } - - issue.Enrich(f) - - key := issue.HashString() - - if ok := seen[key]; ok { - continue - } - seen[key] = true - - a.addDiagnostic(issue.ExportDiagnostic()) - } - }) - - // 02. Printing reports. - a.mu.RLock() - defer a.mu.RUnlock() - for i := range a.found { - pass.Report(a.found[i]) - } - - return nil, nil -} - -func (a *analyzer) addDiagnostic(d analysis.Diagnostic) { - a.mu.Lock() - defer a.mu.Unlock() - - a.found = append(a.found, d) -} - -func (a *analyzer) readConfiguration(fs *flag.FlagSet) { - cnf, err := config.New(fs) - if err != nil { - a.err = err - return - } - - // First: checking nonolint directive - val := fs.Lookup("nonolint") - if val != nil { - a.disabledNolint = fs.Lookup("nonolint").Value.String() == "true" - } - - // Second: validators implementation next - if validatorImpl, ok := cnf.(validator); ok { - a.handler = validatorImpl - return - } - - a.handler = config.DefaultValidatorConfig() -} - -func NewAnalyzer() *analysis.Analyzer { - a := analyzer{} - - return &analysis.Analyzer{ - Name: name, - Doc: "Accept Interfaces, Return Concrete Types", - Run: a.run, - Requires: []*analysis.Analyzer{inspect.Analyzer}, - Flags: flags(), - } -} - -func flags() flag.FlagSet { - set := flag.NewFlagSet("", flag.PanicOnError) - set.String("allow", "", "accept-list of the comma-separated interfaces") - set.String("reject", "", "reject-list of the comma-separated interfaces") - set.Bool("nonolint", false, "disable nolint checks") - return *set -} - -func filterInterfaces(p *analysis.Pass, ft *ast.FuncType, di map[string]struct{}) []types.IFace { - var results []types.IFace - - if ft.Results == nil { // this can't happen, but double checking. - return results - } - - for _, el := range ft.Results.List { - switch v := el.Type.(type) { - // ----- empty or anonymous interfaces - case *ast.InterfaceType: - if len(v.Methods.List) == 0 { - results = append(results, types.NewIssue("interface{}", types.EmptyInterface)) - continue - } - - results = append(results, types.NewIssue("anonymous interface", types.AnonInterface)) - - // ------ Errors and interfaces from same package - case *ast.Ident: - - t1 := p.TypesInfo.TypeOf(el.Type) - val, ok := t1.Underlying().(*gotypes.Interface) - if !ok { - continue - } - - var ( - name = t1.String() - isNamed = strings.Contains(name, ".") - isEmpty = val.Empty() - ) - - // catching any - if isEmpty && name == "any" { - results = append(results, types.NewIssue(name, types.EmptyInterface)) - continue - } - - // NOTE: FIXED! - if name == "error" { - results = append(results, types.NewIssue(name, types.ErrorInterface)) - continue - } - - if !isNamed { - - typeParams := val.String() - prefix, suffix := "interface{", "}" - if strings.HasPrefix(typeParams, prefix) { //nolint:gosimple - typeParams = typeParams[len(prefix):] - } - if strings.HasSuffix(typeParams, suffix) { - typeParams = typeParams[:len(typeParams)-1] - } - - // todo: write test for this (1.18&1.19 only?) - goVersion := runtime.Version() - if strings.HasPrefix(goVersion, "go1.18") || strings.HasPrefix(goVersion, "go1.19") { - typeParams = strings.ReplaceAll(typeParams, "|", " | ") - } - - results = append(results, types.IFace{ - Name: name, - Type: types.Generic, - OfType: typeParams, - }) - continue - } - - // is it dot-imported package? - // handling cases when stdlib package imported via "." dot-import - if len(di) > 0 { - pkgName := stdPkgInterface(name) - if _, ok := di[pkgName]; ok { - results = append(results, types.NewIssue(name, types.NamedStdInterface)) - - continue - } - } - - results = append(results, types.NewIssue(name, types.NamedInterface)) - - // ------- standard library and 3rd party interfaces - case *ast.SelectorExpr: - - t1 := p.TypesInfo.TypeOf(el.Type) - if !gotypes.IsInterface(t1.Underlying()) { - continue - } - - word := t1.String() - if isStdPkgInterface(word) { - results = append(results, types.NewIssue(word, types.NamedStdInterface)) - continue - } - - results = append(results, types.NewIssue(word, types.NamedInterface)) - } - } - - return results -} - -// stdPkgInterface will return package name if tis std lib package -// or empty string on fail. -func stdPkgInterface(named string) string { - // find last "." index. - idx := strings.LastIndex(named, ".") - if idx == -1 { - return "" - } - - return stdPkg(named[0:idx]) -} - -// isStdPkgInterface will run small checks against pkg to find out if named -// interface we looking on - comes from a standard library or not. -func isStdPkgInterface(namedInterface string) bool { - return stdPkgInterface(namedInterface) != "" -} - -func stdPkg(pkg string) string { - if _, ok := std[pkg]; ok { - return pkg - } - - return "" -} diff --git a/vendor/github.com/butuzov/ireturn/analyzer/disallow.go b/vendor/github.com/butuzov/ireturn/analyzer/disallow.go deleted file mode 100644 index 36b6fcb4f3..0000000000 --- a/vendor/github.com/butuzov/ireturn/analyzer/disallow.go +++ /dev/null @@ -1,45 +0,0 @@ -package analyzer - -import ( - "go/ast" - "strings" -) - -const nolintPrefix = "//nolint" - -func hasDisallowDirective(cg *ast.CommentGroup) bool { - if cg == nil { - return false - } - - return directiveFound(cg) -} - -func directiveFound(cg *ast.CommentGroup) bool { - for i := len(cg.List) - 1; i >= 0; i-- { - comment := cg.List[i] - if !strings.HasPrefix(comment.Text, nolintPrefix) { - continue - } - - startingIdx := len(nolintPrefix) - for { - idx := strings.Index(comment.Text[startingIdx:], name) - if idx == -1 { - break - } - - if len(comment.Text[startingIdx+idx:]) == len(name) { - return true - } - - c := comment.Text[startingIdx+idx+len(name)] - if c == '.' || c == ',' || c == ' ' || c == ' ' { - return true - } - startingIdx += idx + 1 - } - } - - return false -} diff --git a/vendor/github.com/butuzov/ireturn/analyzer/internal/config/allow.go b/vendor/github.com/butuzov/ireturn/analyzer/internal/config/allow.go deleted file mode 100644 index da101c7862..0000000000 --- a/vendor/github.com/butuzov/ireturn/analyzer/internal/config/allow.go +++ /dev/null @@ -1,17 +0,0 @@ -package config - -import "github.com/butuzov/ireturn/analyzer/internal/types" - -// allowConfig specifies a list of interfaces (keywords, patterns and regular expressions) -// that are allowed by ireturn as valid to return, any non listed interface are rejected. -type allowConfig struct { - *defaultConfig -} - -func allowAll(patterns []string) *allowConfig { - return &allowConfig{&defaultConfig{List: patterns}} -} - -func (ac *allowConfig) IsValid(i types.IFace) bool { - return ac.Has(i) -} diff --git a/vendor/github.com/butuzov/ireturn/analyzer/internal/config/config.go b/vendor/github.com/butuzov/ireturn/analyzer/internal/config/config.go deleted file mode 100644 index 46c73170ae..0000000000 --- a/vendor/github.com/butuzov/ireturn/analyzer/internal/config/config.go +++ /dev/null @@ -1,66 +0,0 @@ -package config - -import ( - "regexp" - "sync" - - "github.com/butuzov/ireturn/analyzer/internal/types" -) - -// defaultConfig is core of the validation, ... -// todo(butuzov): write proper intro... - -type defaultConfig struct { - List []string - - // private fields (for search optimization look ups) - once sync.Once - quick uint8 - list []*regexp.Regexp -} - -func (config *defaultConfig) Has(i types.IFace) bool { - config.once.Do(config.compileList) - - if config.quick&uint8(i.Type) > 0 { - return true - } - - // not a named interface (because error, interface{}, anon interface has keywords.) - if i.Type&types.NamedInterface == 0 && i.Type&types.NamedStdInterface == 0 { - return false - } - - for _, re := range config.list { - if re.MatchString(i.Name) { - return true - } - } - - return false -} - -// compileList will transform text list into a bitmask for quick searches and -// slice of regular expressions for quick searches. -func (config *defaultConfig) compileList() { - for _, str := range config.List { - switch str { - case types.NameError: - config.quick |= uint8(types.ErrorInterface) - case types.NameEmpty: - config.quick |= uint8(types.EmptyInterface) - case types.NameAnon: - config.quick |= uint8(types.AnonInterface) - case types.NameStdLib: - config.quick |= uint8(types.NamedStdInterface) - case types.NameGeneric: - config.quick |= uint8(types.Generic) - } - - // allow to parse regular expressions - // todo(butuzov): how can we log error in golangci-lint? - if re, err := regexp.Compile(str); err == nil { - config.list = append(config.list, re) - } - } -} diff --git a/vendor/github.com/butuzov/ireturn/analyzer/internal/config/new.go b/vendor/github.com/butuzov/ireturn/analyzer/internal/config/new.go deleted file mode 100644 index d6914af862..0000000000 --- a/vendor/github.com/butuzov/ireturn/analyzer/internal/config/new.go +++ /dev/null @@ -1,73 +0,0 @@ -package config - -import ( - "errors" - "flag" - "strings" - - "github.com/butuzov/ireturn/analyzer/internal/types" -) - -var ErrCollisionOfInterests = errors.New("can't have both `-accept` and `-reject` specified at same time") - -func DefaultValidatorConfig() *allowConfig { - return allowAll([]string{ - types.NameEmpty, // "empty": empty interfaces (interface{}) - types.NameError, // "error": for all error's - types.NameAnon, // "anon": for all empty interfaces with methods (interface {Method()}) - types.NameStdLib, // "std": for all standard library packages - }) -} - -// New is factory function that return allowConfig or rejectConfig depending -// on provided arguments. -func New(fs *flag.FlagSet) (interface{}, error) { - var ( - allowList = toSlice(getFlagVal(fs, "allow")) - rejectList = toSlice(getFlagVal(fs, "reject")) - ) - - // can't have both at same time. - if len(allowList) != 0 && len(rejectList) != 0 { - return nil, ErrCollisionOfInterests - } - - switch { - case len(allowList) > 0: - return allowAll(allowList), nil - case len(rejectList) > 0: - return rejectAll(rejectList), nil - } - - // can have none (defaults are used) at same time. - return nil, nil -} - -// both constants used to cleanup items provided in comma separated list. -const ( - SepTab string = " " - SepSpace string = " " -) - -func toSlice(s string) []string { - var results []string - - for _, pattern := range strings.Split(s, ",") { - pattern = strings.Trim(pattern, SepTab+SepSpace) - if pattern != "" { - results = append(results, pattern) - } - } - - return results -} - -func getFlagVal(fs *flag.FlagSet, name string) string { - flg := fs.Lookup(name) - - if flg == nil { - return "" - } - - return flg.Value.String() -} diff --git a/vendor/github.com/butuzov/ireturn/analyzer/internal/config/reject.go b/vendor/github.com/butuzov/ireturn/analyzer/internal/config/reject.go deleted file mode 100644 index b2cde910ce..0000000000 --- a/vendor/github.com/butuzov/ireturn/analyzer/internal/config/reject.go +++ /dev/null @@ -1,17 +0,0 @@ -package config - -import "github.com/butuzov/ireturn/analyzer/internal/types" - -// rejectConfig specifies a list of interfaces (keywords, patterns and regular expressions) -// that are rejected by ireturn as valid to return, any non listed interface are allowed. -type rejectConfig struct { - *defaultConfig -} - -func rejectAll(patterns []string) *rejectConfig { - return &rejectConfig{&defaultConfig{List: patterns}} -} - -func (rc *rejectConfig) IsValid(i types.IFace) bool { - return !rc.Has(i) -} diff --git a/vendor/github.com/butuzov/ireturn/analyzer/internal/types/iface.go b/vendor/github.com/butuzov/ireturn/analyzer/internal/types/iface.go deleted file mode 100644 index 0f4286515f..0000000000 --- a/vendor/github.com/butuzov/ireturn/analyzer/internal/types/iface.go +++ /dev/null @@ -1,54 +0,0 @@ -package types - -import ( - "fmt" - "go/ast" - "go/token" - - "golang.org/x/tools/go/analysis" -) - -type IFace struct { - Name string // Interface name - Type IType // Type of the interface - - Pos token.Pos // Token Position - FuncName string // - OfType string -} - -func NewIssue(name string, interfaceType IType) IFace { - return IFace{ - Name: name, - // Pos: pos, - Type: interfaceType, - } -} - -func (i *IFace) Enrich(f *ast.FuncDecl) { - i.FuncName = f.Name.Name - i.Pos = f.Pos() -} - -func (i IFace) String() string { - if i.Type != Generic { - return fmt.Sprintf("%s returns interface (%s)", i.FuncName, i.Name) - } - - if i.OfType != "" { - return fmt.Sprintf("%s returns generic interface (%s) of type param %s", i.FuncName, i.Name, i.OfType) - } - - return fmt.Sprintf("%s returns generic interface (%s)", i.FuncName, i.Name) -} - -func (i IFace) HashString() string { - return fmt.Sprintf("%v-%s", i.Pos, i.String()) -} - -func (i IFace) ExportDiagnostic() analysis.Diagnostic { - return analysis.Diagnostic{ - Pos: i.Pos, - Message: i.String(), - } -} diff --git a/vendor/github.com/butuzov/ireturn/analyzer/internal/types/names.go b/vendor/github.com/butuzov/ireturn/analyzer/internal/types/names.go deleted file mode 100644 index 1092c9667c..0000000000 --- a/vendor/github.com/butuzov/ireturn/analyzer/internal/types/names.go +++ /dev/null @@ -1,9 +0,0 @@ -package types - -const ( - NameEmpty = "empty" - NameAnon = "anon" - NameError = "error" - NameStdLib = "stdlib" - NameGeneric = "generic" -) diff --git a/vendor/github.com/butuzov/ireturn/analyzer/internal/types/types.go b/vendor/github.com/butuzov/ireturn/analyzer/internal/types/types.go deleted file mode 100644 index 5c0bd74077..0000000000 --- a/vendor/github.com/butuzov/ireturn/analyzer/internal/types/types.go +++ /dev/null @@ -1,12 +0,0 @@ -package types - -type IType uint8 - -const ( - EmptyInterface IType = 1 << iota // ref as empty - AnonInterface // ref as anon - ErrorInterface // ref as error - NamedInterface // ref as named - NamedStdInterface // ref as named stdlib - Generic // ref as generic type parameter -) diff --git a/vendor/github.com/butuzov/ireturn/analyzer/std.go b/vendor/github.com/butuzov/ireturn/analyzer/std.go deleted file mode 100644 index ce007be8ba..0000000000 --- a/vendor/github.com/butuzov/ireturn/analyzer/std.go +++ /dev/null @@ -1,214 +0,0 @@ -// Code generated using std.sh; DO NOT EDIT. - -// We will ignore that fact that some of packages -// were removed from stdlib. - -package analyzer - -var std = map[string]struct{}{ - // added in Go v1.2 in compare to v1.1 (docker image) - "archive/tar": {}, - "archive/zip": {}, - "bufio": {}, - "bytes": {}, - "cmd/cgo": {}, - "cmd/fix": {}, - "cmd/go": {}, - "cmd/gofmt": {}, - "cmd/yacc": {}, - "compress/bzip2": {}, - "compress/flate": {}, - "compress/gzip": {}, - "compress/lzw": {}, - "compress/zlib": {}, - "container/heap": {}, - "container/list": {}, - "container/ring": {}, - "crypto": {}, - "crypto/aes": {}, - "crypto/cipher": {}, - "crypto/des": {}, - "crypto/dsa": {}, - "crypto/ecdsa": {}, - "crypto/elliptic": {}, - "crypto/hmac": {}, - "crypto/md5": {}, - "crypto/rand": {}, - "crypto/rc4": {}, - "crypto/rsa": {}, - "crypto/sha1": {}, - "crypto/sha256": {}, - "crypto/sha512": {}, - "crypto/subtle": {}, - "crypto/tls": {}, - "crypto/x509": {}, - "crypto/x509/pkix": {}, - "database/sql": {}, - "database/sql/driver": {}, - "debug/dwarf": {}, - "debug/elf": {}, - "debug/gosym": {}, - "debug/macho": {}, - "debug/pe": {}, - "encoding": {}, - "encoding/ascii85": {}, - "encoding/asn1": {}, - "encoding/base32": {}, - "encoding/base64": {}, - "encoding/binary": {}, - "encoding/csv": {}, - "encoding/gob": {}, - "encoding/hex": {}, - "encoding/json": {}, - "encoding/pem": {}, - "encoding/xml": {}, - "errors": {}, - "expvar": {}, - "flag": {}, - "fmt": {}, - "go/ast": {}, - "go/build": {}, - "go/doc": {}, - "go/format": {}, - "go/parser": {}, - "go/printer": {}, - "go/scanner": {}, - "go/token": {}, - "hash": {}, - "hash/adler32": {}, - "hash/crc32": {}, - "hash/crc64": {}, - "hash/fnv": {}, - "html": {}, - "html/template": {}, - "image": {}, - "image/color": {}, - "image/color/palette": {}, - "image/draw": {}, - "image/gif": {}, - "image/jpeg": {}, - "image/png": {}, - "index/suffixarray": {}, - "io": {}, - "io/ioutil": {}, - "log": {}, - "log/syslog": {}, - "math": {}, - "math/big": {}, - "math/cmplx": {}, - "math/rand": {}, - "mime": {}, - "mime/multipart": {}, - "net": {}, - "net/http": {}, - "net/http/cgi": {}, - "net/http/cookiejar": {}, - "net/http/fcgi": {}, - "net/http/httptest": {}, - "net/http/httputil": {}, - "net/http/pprof": {}, - "net/mail": {}, - "net/rpc": {}, - "net/rpc/jsonrpc": {}, - "net/smtp": {}, - "net/textproto": {}, - "net/url": {}, - "os": {}, - "os/exec": {}, - "os/signal": {}, - "os/user": {}, - "path": {}, - "path/filepath": {}, - "reflect": {}, - "regexp": {}, - "regexp/syntax": {}, - "runtime": {}, - "runtime/cgo": {}, - "runtime/debug": {}, - "runtime/pprof": {}, - "runtime/race": {}, - "sort": {}, - "strconv": {}, - "strings": {}, - "sync": {}, - "sync/atomic": {}, - "syscall": {}, - "testing": {}, - "testing/iotest": {}, - "testing/quick": {}, - "text/scanner": {}, - "text/tabwriter": {}, - "text/template": {}, - "text/template/parse": {}, - "time": {}, - "unicode": {}, - "unicode/utf16": {}, - "unicode/utf8": {}, - "unsafe": {}, - // added in Go v1.3 in compare to v1.2 (docker image) - "cmd/addr2line": {}, - "cmd/nm": {}, - "cmd/objdump": {}, - "cmd/pack": {}, - "debug/plan9obj": {}, - // added in Go v1.4 in compare to v1.3 (docker image) - "cmd/pprof": {}, - // added in Go v1.5 in compare to v1.4 (docker image) - "go/constant": {}, - "go/importer": {}, - "go/types": {}, - "mime/quotedprintable": {}, - "runtime/trace": {}, - // added in Go v1.6 in compare to v1.5 (docker image) - // added in Go v1.7 in compare to v1.6 (docker image) - "context": {}, - "net/http/httptrace": {}, - // added in Go v1.8 in compare to v1.7 (docker image) - "plugin": {}, - // added in Go v1.9 in compare to v1.8 (docker image) - "math/bits": {}, - // added in Go v1.10 in compare to v1.9 (docker image) - // added in Go v1.11 in compare to v1.10 (docker image) - // added in Go v1.12 in compare to v1.11 (docker image) - // added in Go v1.13 in compare to v1.12 (docker image) - "crypto/ed25519": {}, - // added in Go v1.14 in compare to v1.13 (docker image) - "hash/maphash": {}, - // added in Go v1.15 in compare to v1.14 (docker image) - "time/tzdata": {}, - // added in Go v1.16 in compare to v1.15 (docker image) - "embed": {}, - "go/build/constraint": {}, - "io/fs": {}, - "runtime/metrics": {}, - "testing/fstest": {}, - // added in Go v1.17 in compare to v1.16 (docker image) - // added in Go v1.18 in compare to v1.17 (docker image) - "debug/buildinfo": {}, - "net/netip": {}, - // added in Go v1.19 in compare to v1.18 (docker image) - "go/doc/comment": {}, - // added in Go v1.20 in compare to v1.19 (docker image) - "crypto/ecdh": {}, - "runtime/coverage": {}, - // added in Go v1.21 in compare to v1.20 (docker image) - "cmp": {}, - "log/slog": {}, - "maps": {}, - "slices": {}, - "testing/slogtest": {}, - // added in Go v1.22 in compare to v1.21 (docker image) - "go/version": {}, - "math/rand/v2": {}, - // added in Go v1.23 in compare to v1.22 (docker image) - "iter": {}, - "structs": {}, - "unique": {}, - // added in Go v1.24 in compare to v1.23 (docker image) - "crypto/fips140": {}, - "crypto/hkdf": {}, - "crypto/mlkem": {}, - "crypto/pbkdf2": {}, - "crypto/sha3": {}, - "weak": {}, -} diff --git a/vendor/github.com/butuzov/mirror/.editorconfig b/vendor/github.com/butuzov/mirror/.editorconfig deleted file mode 100644 index 4d9c20d8d9..0000000000 --- a/vendor/github.com/butuzov/mirror/.editorconfig +++ /dev/null @@ -1,28 +0,0 @@ -# top-most EditorConfig file -root = true - - -[*] -end_of_line = lf # Unix-style newlines -charset = utf-8 - -indent_style = space # default identation - spaces -indent_size = 4 # default identation - size - -insert_final_newline = true # new line at the end of file -trim_trailing_whitespace = true # no extra sapces at the end of lines - -[*.{go,gohtml,gotpl}] # Go -indent_style = tab -indent_size = 2 - -[{Makefile,makefile}] # CMake -indent_style = tab - -[*.md] # Markdown -trim_trailing_whitespace = true -max_line_length = 100 -insert_final_newline = true -indent_size = 2 - - diff --git a/vendor/github.com/butuzov/mirror/.gitignore b/vendor/github.com/butuzov/mirror/.gitignore deleted file mode 100644 index 109f33b98e..0000000000 --- a/vendor/github.com/butuzov/mirror/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -# artifacts -coverage.cov -bin/* -dist/* -tmp/* -out* -sandbox* -demo* -.task* -.ipynb* -.jupyter* diff --git a/vendor/github.com/butuzov/mirror/.goreleaser.yaml b/vendor/github.com/butuzov/mirror/.goreleaser.yaml deleted file mode 100644 index fa91fa97e2..0000000000 --- a/vendor/github.com/butuzov/mirror/.goreleaser.yaml +++ /dev/null @@ -1,46 +0,0 @@ ---- -project_name: mirror - -builds: - - binary: mirror - env: - - CGO_ENABLED=0 - main: ./cmd/mirror/ - flags: - - -trimpath - ldflags: -s -w - goos: - - linux - - darwin - - windows - goarch: - - amd64 - - arm64 - -changelog: - sort: asc - filters: - exclude: - - '(?i)^docs?:' - - '(?i)^docs\([^:]+\):' - - '(?i)^docs\[[^:]+\]:' - - '^tests?:' - - '(?i)^dev:' - - Merge pull request - - Merge branch - - -checksum: - name_template: 'checksums.txt' - - -archives: - - format: tar.gz - name_template: >- - {{ .ProjectName }}_{{- tolower .Os }}_{{ .Arch }} - format_overrides: - - goos: windows - format: zip - files: - - LICENSE - - readme.md diff --git a/vendor/github.com/butuzov/mirror/LICENSE b/vendor/github.com/butuzov/mirror/LICENSE deleted file mode 100644 index a9752e9726..0000000000 --- a/vendor/github.com/butuzov/mirror/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2021 Oleg Butuzov - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/butuzov/mirror/MIRROR_FUNCS.md b/vendor/github.com/butuzov/mirror/MIRROR_FUNCS.md deleted file mode 100644 index da30c8e00f..0000000000 --- a/vendor/github.com/butuzov/mirror/MIRROR_FUNCS.md +++ /dev/null @@ -1,55 +0,0 @@ - - -| Function | Mirror | -|----------|--------| -| `func (*bufio.Writer) Write([]byte) (int, error)` | `func (*bufio.Writer) WriteString(string) (int, error)` | -| `func (*bufio.Writer) WriteRune(rune) (int, error)` | `func (*bufio.Writer) WriteString(string) (int, error)` | -| `func (*bytes.Buffer) Write([]byte) (int, error)` | `func (*bytes.Buffer) WriteString(string) (int, error)` | -| `func (*bytes.Buffer) WriteRune(rune) (int, error)` | `func (*bytes.Buffer) WriteString(string) (int, error)` | -| `func bytes.Compare([]byte, []byte) int` | `func strings.Compare(string, string) int` | -| `func bytes.Contains([]byte, []byte) bool` | `func strings.Contains(string, string) bool` | -| `func bytes.ContainsAny([]byte, string) bool` | `func strings.ContainsAny(string, string) bool` | -| `func bytes.ContainsRune([]byte, byte) bool` | `func strings.ContainsRune(string, byte) bool` | -| `func bytes.Count([]byte, []byte) int` | `func strings.Count(string, string) int` | -| `func bytes.EqualFold([]byte, []byte) bool` | `func strings.EqualFold(string, string) bool` | -| `func bytes.HasPrefix([]byte, []byte) bool` | `func strings.HasPrefix(string, string) bool` | -| `func bytes.HasSuffix([]byte, []byte) bool` | `func strings.HasSuffix(string, string) bool` | -| `func bytes.Index([]byte, []byte) int` | `func strings.Index(string, string) int` | -| `func bytes.IndexAny([]byte, string) int` | `func strings.IndexAny(string, string) int` | -| `func bytes.IndexByte([]byte, byte) int` | `func strings.IndexByte(string, byte) int` | -| `func bytes.IndexFunc([]byte, func(rune) bool) int` | `func strings.IndexFunc(string, func(rune) bool) int` | -| `func bytes.IndexRune([]byte, rune) int` | `func strings.IndexRune(string, rune) int` | -| `func bytes.LastIndex([]byte, []byte) int` | `func strings.LastIndex(string, string) int` | -| `func bytes.LastIndexAny([]byte, string) int` | `func strings.LastIndexAny(string, string) int` | -| `func bytes.LastIndexByte([]byte, byte) int` | `func strings.LastIndexByte(string, byte) int` | -| `func bytes.LastIndexFunc([]byte, func(rune) bool) int` | `func strings.LastIndexFunc(string, func(rune) bool) int` | -| `func bytes.NewBuffer([]byte) *bytes.Buffer` | `func bytes.NewBufferString(string) *bytes.Buffer` | -| `func (*httptest.ResponseRecorder) Write([]byte) (int, error)` | `func (*httptest.ResponseRecorder) WriteString(string) (int, error)` | -| `func maphash.Bytes([]byte) uint64` | `func maphash.String(string) uint64` | -| `func (*maphash.Hash) Write([]byte) (int, error)` | `func (*maphash.Hash) WriteString(string) (int, error)` | -| `func (*os.File) Write([]byte) (int, error)` | `func (*os.File) WriteString(string) (int, error)` | -| `func regexp.Match(string, []byte) (bool, error)` | `func regexp.MatchString(string, string) (bool, error)` | -| `func (*regexp.Regexp) FindAllIndex([]byte, int) [][]int` | `func (*regexp.Regexp) FindAllStringIndex(string, int) [][]int` | -| `func (*regexp.Regexp) FindAllSubmatchIndex([]byte, int) [][]int` | `func (*regexp.Regexp) FindAllStringSubmatchIndex(string, int) [][]int` | -| `func (*regexp.Regexp) FindIndex([]byte) []int` | `func (*regexp.Regexp) FindStringIndex(string) []int` | -| `func (*regexp.Regexp) FindSubmatchIndex([]byte) []int` | `func (*regexp.Regexp) FindStringSubmatchIndex(string) []int` | -| `func (*regexp.Regexp) Match([]byte) bool` | `func (*regexp.Regexp) MatchString(string) bool` | -| `func (*strings.Builder) Write([]byte) (int, error)` | `func (*strings.Builder) WriteString(string) (int, error)` | -| `func (*strings.Builder) WriteRune(rune) (int, error)` | `func (*strings.Builder) WriteString(string) (int, error)` | -| `func strings.Compare(string) int` | `func bytes.Compare([]byte) int` | -| `func strings.Contains(string) bool` | `func bytes.Contains([]byte) bool` | -| `func strings.ContainsAny(string) bool` | `func bytes.ContainsAny([]byte) bool` | -| `func strings.ContainsRune(string) bool` | `func bytes.ContainsRune([]byte) bool` | -| `func strings.EqualFold(string) bool` | `func bytes.EqualFold([]byte) bool` | -| `func strings.HasPrefix(string) bool` | `func bytes.HasPrefix([]byte) bool` | -| `func strings.HasSuffix(string) bool` | `func bytes.HasSuffix([]byte) bool` | -| `func strings.Index(string) int` | `func bytes.Index([]byte) int` | -| `func strings.IndexFunc(string, func(r rune) bool) int` | `func bytes.IndexFunc([]byte, func(r rune) bool) int` | -| `func strings.LastIndex(string) int` | `func bytes.LastIndex([]byte) int` | -| `func strings.LastIndexAny(string) int` | `func bytes.LastIndexAny([]byte) int` | -| `func strings.LastIndexFunc(string, func(r rune) bool) int` | `func bytes.LastIndexFunc([]byte, func(r rune) bool) int` | -| `func utf8.DecodeLastRune([]byte) (rune, int)` | `func utf8.DecodeLastRuneInString(string) (rune, int)` | -| `func utf8.DecodeRune([]byte) (rune, int)` | `func utf8.DecodeRuneInString(string) (rune, int)` | -| `func utf8.FullRune([]byte) bool` | `func utf8.FullRuneInString(string) bool` | -| `func utf8.RuneCount([]byte) int` | `func utf8.RuneCountInString(string) int` | -| `func utf8.Valid([]byte) bool` | `func utf8.ValidString(string) bool` | diff --git a/vendor/github.com/butuzov/mirror/Makefile b/vendor/github.com/butuzov/mirror/Makefile deleted file mode 100644 index dab6f160ae..0000000000 --- a/vendor/github.com/butuzov/mirror/Makefile +++ /dev/null @@ -1,132 +0,0 @@ -# --- Required ---------------------------------------------------------------- -export PATH := $(PWD)/bin:$(PATH) # ./bin to $PATH -export SHELL := bash # Default Shell - -define install_go_bin - @ which $(1) 2>&1 1>/dev/null || GOBIN=$(PWD)/bin go install $(2) -endef - -.DEFAULT_GOAL := help - -# Generate Artifacts ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -generate: ## Generate Assets - $(MAKE) generate-tests - $(MAKE) generate-mirror-table - -generate-tests: ## Generates Assets at testdata - go run ./cmd/internal/tests/ "$(PWD)/testdata" - -generate-mirror-table: ## Generate Asset MIRROR_FUNCS.md - go run ./cmd/internal/mirror-table/ > "$(PWD)/MIRROR_FUNCS.md" - - -# Build Artifacts ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -build: ## Build binary - @ go build -trimpath -ldflags="-w -s" -o bin/mirror ./cmd/mirror/ - -build-race: ## Build binary with race flag - @ go build -race -trimpath -ldflags="-w -s" -o bin/mirror ./cmd/mirror/ - -install: ## Installs binary - @ go install -trimpath -v -ldflags="-w -s" ./cmd/mirror - -# Run Tests ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -tests: ## Run Tests (Summary) - @ go test -v -count=1 -race \ - -failfast \ - -parallel=2 \ - -timeout=1m \ - -covermode=atomic \ - -coverprofile=coverage.cov ./... - -tests-summary: ## Run Tests, but shows summary -tests-summary: bin/tparse - @ go test -v -count=1 -race \ - -failfast \ - -parallel=2 \ - -timeout=1m \ - -covermode=atomic \ - -coverprofile=coverage.cov --json ./... | tparse -all - -# Linter ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -lints: ## Run golangci-lint -lints: bin/golangci-lint -lints: - golangci-lint run --no-config ./... --exclude-dirs "^(cmd|testdata)" - - -cover: ## Run Coverage - @ go tool cover -html=coverage.cov - -# Other ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -test-release: bin/goreleaser - goreleaser release --help - goreleaser release --skip=publish --skip=validate --clean - -# Install ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -bin/tparse: ## Installs tparse@v0.13.2 (if not exists) -bin/tparse: INSTALL_URL=github.com/mfridman/tparse@v0.13.2 -bin/tparse: - $(call install_go_bin, tparse, $(INSTALL_URL)) - -bin/golangci-lint: ## Installs golangci-lint@v1.62.0 (if not exists) -bin/golangci-lint: INSTALL_URL=github.com/golangci/golangci-lint@v1.62.0 -bin/golangci-lint: - $(call install_go_bin, golangci-lint, $(INSTALL_URL)) - -bin/goreleaser: ## Installs goreleaser@v1.24.0 (if not exists) -bin/goreleaser: INSTALL_URL=github.com/goreleaser/goreleaser@v1.24.0 -bin/goreleaser: - $(call install_go_bin, goreleaser, $(INSTALL_URL)) - -# Help ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -help: dep-gawk - @ echo "==============================================================================" - @ echo " Makefile: github.com/butuzov/mirror " - @ echo "==============================================================================" - @ cat $(MAKEFILE_LIST) | \ - grep -E '^# ~~~ .*? [~]+$$|^[a-zA-Z0-9_-]+:.*?## .*$$' | \ - gawk '{if ( $$1=="#" ) { \ - match($$0, /^# ~~~ (.+?) [~]+$$/, a);\ - {print "\n", a[1], ""}\ - } else { \ - match($$0, /^([a-zA-Z/_-]+):.*?## (.*)$$/, a); \ - {printf " - \033[32m%-20s\033[0m %s\n", a[1], a[2]} \ - }}' - @ echo "" - - -# Helper Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -dep-gawk: - @ if [ -z "$(shell command -v gawk)" ]; then \ - if [ -x /usr/local/bin/brew ]; then $(MAKE) _brew_gawk_install; exit 0; fi; \ - if [ -x /usr/bin/apt-get ]; then $(MAKE) _ubuntu_gawk_install; exit 0; fi; \ - if [ -x /usr/bin/yum ]; then $(MAKE) _centos_gawk_install; exit 0; fi; \ - if [ -x /sbin/apk ]; then $(MAKE) _alpine_gawk_install; exit 0; fi; \ - echo "GNU Awk Required.";\ - exit 1; \ - fi - -_brew_gawk_install: - @ echo "Installing gawk using brew... " - @ brew install gawk --quiet - @ echo "done" - -_ubuntu_gawk_install: - @ echo "Installing gawk using apt-get... " - @ apt-get -q install gawk -y - @ echo "done" - -_alpine_gawk_install: - @ echo "Installing gawk using yum... " - @ apk add --update --no-cache gawk - @ echo "done" - -_centos_gawk_install: - @ echo "Installing gawk using yum... " - @ yum install -q -y gawk; - @ echo "done" diff --git a/vendor/github.com/butuzov/mirror/Taskfile.yml b/vendor/github.com/butuzov/mirror/Taskfile.yml deleted file mode 100644 index 4bc7cfeda5..0000000000 --- a/vendor/github.com/butuzov/mirror/Taskfile.yml +++ /dev/null @@ -1,73 +0,0 @@ -version: '3' - -tasks: - default: task --list-all - - # Continues Development ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - watcher: - desc: watcher - sources: - - ./**/*.go - method: timestamp - cmds: - - task: lints - - task: test-summary - - task: build-race - - # Generating assets ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - generate: - desc: Generate Assets - sources: - - ./checkers_*.go - - ./cmd/internal/**/*.go - method: timestamp - cmds: - - task generate-mirror-table - - task generate-tests - - generate-mirror-table: - desc: Generates Assets at testdata - cmd: make generate-mirror-table - - generate-tests: - desc: Generate Asset MIRROR_FUNCS.md - cmd: make generate-tests - - # Run Tests ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - tests: - desc: Run Tests - cmd: make tests - ignore_error: true - - test-summary: - desc: Run Tests (Summary) - cmd: make tests-summary - ignore_error: true - - testcase: go test -v -failfast -count=1 -run "TestAll/{{ .Case }}" ./... - - # Build Artifacts ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - build: - desc: Build binary - cmd: make build - - build-race: - desc: Build binary with race flag - cmd: make build-race - - install: - desc: Install binary - cmd: make install - - # Linter ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - lints: - cmd: make lints - - # Other - cover: - desc: Run Coverage - cmd: make cover - - test-release: - desc: Testing Release - cmd: make test-release diff --git a/vendor/github.com/butuzov/mirror/analyzer.go b/vendor/github.com/butuzov/mirror/analyzer.go deleted file mode 100644 index b15019ce1f..0000000000 --- a/vendor/github.com/butuzov/mirror/analyzer.go +++ /dev/null @@ -1,144 +0,0 @@ -package mirror - -import ( - "flag" - "go/ast" - "strings" - - "github.com/butuzov/mirror/internal/checker" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/inspector" -) - -func NewAnalyzer() *analysis.Analyzer { - flags := flags() - - return &analysis.Analyzer{ - Name: "mirror", - Doc: "reports wrong mirror patterns of bytes/strings usage", - Run: run, - Requires: []*analysis.Analyzer{ - inspect.Analyzer, - }, - Flags: flags, - } -} - -func run(pass *analysis.Pass) (interface{}, error) { - withTests := pass.Analyzer.Flags.Lookup("with-tests").Value.String() == "true" - // --- Reporting violations via issues --------------------------------------- - for _, violation := range Run(pass, withTests) { - pass.Report(violation.Diagnostic(pass.Fset)) - } - - return nil, nil -} - -func Run(pass *analysis.Pass, withTests bool) []*checker.Violation { - violations := []*checker.Violation{} - // --- Setup ----------------------------------------------------------------- - - check := checker.New( - BytesFunctions, BytesBufferMethods, - RegexpFunctions, RegexpRegexpMethods, - StringFunctions, StringsBuilderMethods, - MaphashMethods, MaphashFunctions, - BufioMethods, HTTPTestMethods, - OsFileMethods, UTF8Functions, - ) - - check.Type = checker.WrapType(pass.TypesInfo) - check.Print = checker.WrapPrint(pass.Fset) - - ins, _ := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - imports := checker.Load(pass.Fset, ins) - - // --- Preorder Checker ------------------------------------------------------ - ins.Preorder([]ast.Node{(*ast.CallExpr)(nil)}, func(n ast.Node) { - callExpr := n.(*ast.CallExpr) - fileName := pass.Fset.Position(callExpr.Pos()).Filename - - if !withTests && strings.HasSuffix(fileName, "_test.go") { - return - } - - // ------------------------------------------------------------------------- - switch expr := callExpr.Fun.(type) { - // NOTE(butuzov): Regular calls (`*ast.SelectorExpr`) like strings.HasPrefix - // or re.Match are handled by this check - case *ast.SelectorExpr: - - x, ok := expr.X.(*ast.Ident) - if !ok { - return - } - - // TODO(butuzov): Add check for the ast.ParenExpr in e.Fun so we can - // target the constructions like this (and other calls) - // ----------------------------------------------------------------------- - // Example: - // (&maphash.Hash{}).Write([]byte("foobar")) - // ----------------------------------------------------------------------- - - // Case 1: Is this is a function call? - pkgName, name := x.Name, expr.Sel.Name - if pkg, ok := imports.Lookup(fileName, pkgName); ok { - if v := check.Match(pkg, name); v != nil { - if args, found := check.Handle(v, callExpr); found { - violations = append(violations, v.With(check.Print(expr.X), callExpr, args)) - } - return - } - } - - // Case 2: Is this is a method call? - tv := pass.TypesInfo.Types[expr.X] - if !tv.IsValue() || tv.Type == nil { - return - } - - pkgStruct, name := cleanAsterisk(tv.Type.String()), expr.Sel.Name - for _, v := range check.Matches(pkgStruct, name) { - if v == nil { - continue - } - - if args, found := check.Handle(v, callExpr); found { - violations = append(violations, v.With(check.Print(expr.X), callExpr, args)) - return - } - } - - case *ast.Ident: - // NOTE(butuzov): Special case of "." imported packages, only functions. - - if pkg, ok := imports.Lookup(fileName, "."); ok { - if v := check.Match(pkg, expr.Name); v != nil { - if args, found := check.Handle(v, callExpr); found { - violations = append(violations, v.With(nil, callExpr, args)) - } - return - } - } - } - }) - - return violations -} - -func flags() flag.FlagSet { - set := flag.NewFlagSet("", flag.PanicOnError) - set.Bool("with-tests", false, "do not skip tests in reports") - set.Bool("with-debug", false, "debug linter run (development only)") - return *set -} - -func cleanAsterisk(s string) string { - if strings.HasPrefix(s, "*") { - return s[1:] - } - - return s -} diff --git a/vendor/github.com/butuzov/mirror/checkers_bufio.go b/vendor/github.com/butuzov/mirror/checkers_bufio.go deleted file mode 100644 index 0985edad32..0000000000 --- a/vendor/github.com/butuzov/mirror/checkers_bufio.go +++ /dev/null @@ -1,52 +0,0 @@ -package mirror - -import "github.com/butuzov/mirror/internal/checker" - -var BufioMethods = []checker.Violation{ - { // (*bufio.Writer).Write - Targets: checker.Bytes, - Type: checker.Method, - Package: "bufio", - Struct: "Writer", - Caller: "Write", - Args: []int{0}, - AltCaller: "WriteString", - - Generate: &checker.Generate{ - PreCondition: `b := bufio.Writer{}`, - Pattern: `Write($0)`, - Returns: []string{"int", "error"}, - }, - }, - { // (*bufio.Writer).WriteString - Type: checker.Method, - Targets: checker.Strings, - Package: "bufio", - Struct: "Writer", - Caller: "WriteString", - Args: []int{0}, - AltCaller: "Write", - - Generate: &checker.Generate{ - PreCondition: `b := bufio.Writer{}`, - Pattern: `WriteString($0)`, - Returns: []string{"int", "error"}, - }, - }, - { // (*bufio.Writer).WriteString -> (*bufio.Writer).WriteRune - Targets: checker.Strings, - Type: checker.Method, - Package: "bufio", - Struct: "Writer", - Caller: "WriteString", - Args: []int{0}, - ArgsType: checker.Rune, - AltCaller: "WriteRune", - - Generate: &checker.Generate{ - SkipGenerate: true, - Pattern: `WriteString($0)`, - Returns: []string{"int", "error"}, - }, - }, -} diff --git a/vendor/github.com/butuzov/mirror/checkers_bytes.go b/vendor/github.com/butuzov/mirror/checkers_bytes.go deleted file mode 100644 index b8819879cc..0000000000 --- a/vendor/github.com/butuzov/mirror/checkers_bytes.go +++ /dev/null @@ -1,331 +0,0 @@ -package mirror - -import "github.com/butuzov/mirror/internal/checker" - -var ( - BytesFunctions = []checker.Violation{ - { // bytes.NewBuffer - Targets: checker.Bytes, - Type: checker.Function, - Package: "bytes", - Caller: "NewBuffer", - Args: []int{0}, - AltCaller: "NewBufferString", - - Generate: &checker.Generate{ - Pattern: `NewBuffer($0)`, - Returns: []string{"*bytes.Buffer"}, - }, - }, - { // bytes.NewBufferString - Targets: checker.Strings, - Type: checker.Function, - Package: "bytes", - Caller: "NewBufferString", - Args: []int{0}, - AltCaller: "NewBuffer", - - Generate: &checker.Generate{ - Pattern: `NewBufferString($0)`, - Returns: []string{"*bytes.Buffer"}, - }, - }, - { // bytes.Compare: - Targets: checker.Bytes, - Type: checker.Function, - Package: "bytes", - Caller: "Compare", - Args: []int{0, 1}, - AltPackage: "strings", - AltCaller: "Compare", - - Generate: &checker.Generate{ - Pattern: `Compare($0, $1)`, - Returns: []string{"int"}, - }, - }, - { // bytes.Contains: - Targets: checker.Bytes, - Type: checker.Function, - Package: "bytes", - Caller: "Contains", - Args: []int{0, 1}, - AltPackage: "strings", - AltCaller: "Contains", - - Generate: &checker.Generate{ - Pattern: `Contains($0, $1)`, - Returns: []string{"bool"}, - }, - }, - { // bytes.ContainsAny - Targets: checker.Bytes, - Type: checker.Function, - Package: "bytes", - Caller: "ContainsAny", - Args: []int{0}, - AltPackage: "strings", - AltCaller: "ContainsAny", - - Generate: &checker.Generate{ - Pattern: `ContainsAny($0, "f")`, - Returns: []string{"bool"}, - }, - }, - { // bytes.ContainsRune - Targets: checker.Bytes, - Type: checker.Function, - Package: "bytes", - Caller: "ContainsRune", - Args: []int{0}, - AltPackage: "strings", - AltCaller: "ContainsRune", - - Generate: &checker.Generate{ - Pattern: `ContainsRune($0, 'ф')`, - Returns: []string{"bool"}, - }, - }, - { // bytes.Count - Targets: checker.Bytes, - Type: checker.Function, - Package: "bytes", - Caller: "Count", - Args: []int{0, 1}, - AltPackage: "strings", - AltCaller: "Count", - - Generate: &checker.Generate{ - Pattern: `Count($0, $1)`, - Returns: []string{"int"}, - }, - }, - { // bytes.EqualFold - Targets: checker.Bytes, - Type: checker.Function, - Package: "bytes", - Caller: "EqualFold", - Args: []int{0, 1}, - AltPackage: "strings", - AltCaller: "EqualFold", - - Generate: &checker.Generate{ - Pattern: `EqualFold($0, $1)`, - Returns: []string{"bool"}, - }, - }, - - { // bytes.HasPrefix - Targets: checker.Bytes, - Type: checker.Function, - Package: "bytes", - Caller: "HasPrefix", - Args: []int{0, 1}, - AltPackage: "strings", - AltCaller: "HasPrefix", - - Generate: &checker.Generate{ - Pattern: `HasPrefix($0, $1)`, - Returns: []string{"bool"}, - }, - }, - { // bytes.HasSuffix - Targets: checker.Bytes, - Type: checker.Function, - Package: "bytes", - Caller: "HasSuffix", - Args: []int{0, 1}, - AltPackage: "strings", - AltCaller: "HasSuffix", - - Generate: &checker.Generate{ - Pattern: `HasSuffix($0, $1)`, - Returns: []string{"bool"}, - }, - }, - { // bytes.Index - Targets: checker.Bytes, - Type: checker.Function, - Package: "bytes", - Caller: "Index", - Args: []int{0, 1}, - AltPackage: "strings", - AltCaller: "Index", - - Generate: &checker.Generate{ - Pattern: `Index($0, $1)`, - Returns: []string{"int"}, - }, - }, - { // bytes.IndexAny - Targets: checker.Bytes, - Type: checker.Function, - Package: "bytes", - Caller: "IndexAny", - Args: []int{0}, - AltPackage: "strings", - AltCaller: "IndexAny", - - Generate: &checker.Generate{ - Pattern: `IndexAny($0, "f")`, - Returns: []string{"int"}, - }, - }, - { // bytes.IndexByte - Targets: checker.Bytes, - Type: checker.Function, - Package: "bytes", - Caller: "IndexByte", - Args: []int{0}, - AltPackage: "strings", - AltCaller: "IndexByte", - - Generate: &checker.Generate{ - Pattern: `IndexByte($0, 'f')`, - Returns: []string{"int"}, - }, - }, - { // bytes.IndexFunc - Targets: checker.Bytes, - Type: checker.Function, - Package: "bytes", - Caller: "IndexFunc", - Args: []int{0}, - AltPackage: "strings", - AltCaller: "IndexFunc", - - Generate: &checker.Generate{ - Pattern: `IndexFunc($0, func(rune) bool {return true })`, - Returns: []string{"int"}, - }, - }, - { // bytes.IndexRune - Targets: checker.Bytes, - Type: checker.Function, - Package: "bytes", - Caller: "IndexRune", - Args: []int{0}, - AltPackage: "strings", - AltCaller: "IndexRune", - - Generate: &checker.Generate{ - Pattern: `IndexRune($0, rune('ф'))`, - Returns: []string{"int"}, - }, - }, - { // bytes.LastIndex - Targets: checker.Bytes, - Type: checker.Function, - Package: "bytes", - Caller: "LastIndex", - Args: []int{0, 1}, - AltPackage: "strings", - AltCaller: "LastIndex", - - Generate: &checker.Generate{ - Pattern: `LastIndex($0, $1)`, - Returns: []string{"int"}, - }, - }, - { // bytes.LastIndexAny - Targets: checker.Bytes, - Type: checker.Function, - Package: "bytes", - Caller: "LastIndexAny", - Args: []int{0}, - AltPackage: "strings", - AltCaller: "LastIndexAny", - - Generate: &checker.Generate{ - Pattern: `LastIndexAny($0, "ф")`, - Returns: []string{"int"}, - }, - }, - { // bytes.LastIndexByte - Targets: checker.Bytes, - Type: checker.Function, - Package: "bytes", - Caller: "LastIndexByte", - Args: []int{0}, - AltPackage: "strings", - AltCaller: "LastIndexByte", - - Generate: &checker.Generate{ - Pattern: `LastIndexByte($0, 'f')`, - Returns: []string{"int"}, - }, - }, - { // bytes.LastIndexFunc - Targets: checker.Bytes, - Type: checker.Function, - Package: "bytes", - Caller: "LastIndexFunc", - Args: []int{0}, - AltPackage: "strings", - AltCaller: "LastIndexFunc", - - Generate: &checker.Generate{ - Pattern: `LastIndexFunc($0, func(rune) bool {return true })`, - Returns: []string{"int"}, - }, - }, - } - - BytesBufferMethods = []checker.Violation{ - { // (*bytes.Buffer).Write - Targets: checker.Bytes, - Type: checker.Method, - Package: "bytes", - Struct: "Buffer", - Caller: "Write", - Args: []int{0}, - AltCaller: "WriteString", - - Generate: &checker.Generate{ - PreCondition: `bb := bytes.Buffer{}`, - Pattern: `Write($0)`, - Returns: []string{"int", "error"}, - }, - }, - { // (*bytes.Buffer).WriteString - Targets: checker.Strings, - Type: checker.Method, - Package: "bytes", - Struct: "Buffer", - Caller: "WriteString", - Args: []int{0}, - AltCaller: "Write", - - Generate: &checker.Generate{ - PreCondition: `bb := bytes.Buffer{}`, - Pattern: `WriteString($0)`, - Returns: []string{"int", "error"}, - }, - }, - { // (*bytes.Buffer).WriteString -> (*bytes.Buffer).WriteRune - Targets: checker.Strings, - Type: checker.Method, - Package: "bytes", - Struct: "Buffer", - Caller: "WriteString", - Args: []int{0}, - ArgsType: checker.Rune, - AltCaller: "WriteRune", - Generate: &checker.Generate{ - SkipGenerate: true, - Pattern: `WriteString($0)`, - Returns: []string{"int", "error"}, - }, - }, - // { // (*bytes.Buffer).WriteString -> (*bytes.Buffer).WriteByte - // Targets: checker.Strings, - // Type: checker.Method, - // Package: "bytes", - // Struct: "Buffer", - // Caller: "WriteString", - // Args: []int{0}, - // ArgsType: checker.Byte, - // AltCaller: "WriteByte", - // }, - } -) diff --git a/vendor/github.com/butuzov/mirror/checkers_httptest.go b/vendor/github.com/butuzov/mirror/checkers_httptest.go deleted file mode 100644 index c28bb1ade4..0000000000 --- a/vendor/github.com/butuzov/mirror/checkers_httptest.go +++ /dev/null @@ -1,36 +0,0 @@ -package mirror - -import "github.com/butuzov/mirror/internal/checker" - -var HTTPTestMethods = []checker.Violation{ - { // (*net/http/httptest.ResponseRecorder).Write - Targets: checker.Bytes, - Type: checker.Method, - Package: "net/http/httptest", - Struct: "ResponseRecorder", - Caller: "Write", - Args: []int{0}, - AltCaller: "WriteString", - - Generate: &checker.Generate{ - PreCondition: `h := httptest.ResponseRecorder{}`, - Pattern: `Write($0)`, - Returns: []string{"int", "error"}, - }, - }, - { // (*net/http/httptest.ResponseRecorder).WriteString - Targets: checker.Strings, - Type: checker.Method, - Package: "net/http/httptest", - Struct: "ResponseRecorder", - Caller: "WriteString", - Args: []int{0}, - AltCaller: "Write", - - Generate: &checker.Generate{ - PreCondition: `h := httptest.ResponseRecorder{}`, - Pattern: `WriteString($0)`, - Returns: []string{"int", "error"}, - }, - }, -} diff --git a/vendor/github.com/butuzov/mirror/checkers_maphash.go b/vendor/github.com/butuzov/mirror/checkers_maphash.go deleted file mode 100644 index 345a64123e..0000000000 --- a/vendor/github.com/butuzov/mirror/checkers_maphash.go +++ /dev/null @@ -1,67 +0,0 @@ -package mirror - -import "github.com/butuzov/mirror/internal/checker" - -var ( - MaphashFunctions = []checker.Violation{ - { // maphash.Bytes - Targets: checker.Bytes, - Type: checker.Function, - Package: "hash/maphash", - Caller: "Bytes", - Args: []int{1}, - AltCaller: "String", - - Generate: &checker.Generate{ - Pattern: `Bytes(maphash.MakeSeed(), $0)`, - Returns: []string{"uint64"}, - }, - }, - { // maphash.String - Targets: checker.Strings, - Type: checker.Function, - Package: "hash/maphash", - Caller: "String", - Args: []int{1}, - AltCaller: "Bytes", - - Generate: &checker.Generate{ - Pattern: `String(maphash.MakeSeed(), $0)`, - Returns: []string{"uint64"}, - }, - }, - } - - MaphashMethods = []checker.Violation{ - { // (*hash/maphash).Write - Targets: checker.Bytes, - Type: checker.Method, - Package: "hash/maphash", - Struct: "Hash", - Caller: "Write", - Args: []int{0}, - AltCaller: "WriteString", - - Generate: &checker.Generate{ - PreCondition: `h := maphash.Hash{}`, - Pattern: `Write($0)`, - Returns: []string{"int", "error"}, - }, - }, - { // (*hash/maphash).WriteString - Targets: checker.Strings, - Type: checker.Method, - Package: "hash/maphash", - Struct: "Hash", - Caller: "WriteString", - Args: []int{0}, - AltCaller: "Write", - - Generate: &checker.Generate{ - PreCondition: `h := maphash.Hash{}`, - Pattern: `WriteString($0)`, - Returns: []string{"int", "error"}, - }, - }, - } -) diff --git a/vendor/github.com/butuzov/mirror/checkers_os.go b/vendor/github.com/butuzov/mirror/checkers_os.go deleted file mode 100644 index 40973576b6..0000000000 --- a/vendor/github.com/butuzov/mirror/checkers_os.go +++ /dev/null @@ -1,36 +0,0 @@ -package mirror - -import "github.com/butuzov/mirror/internal/checker" - -var OsFileMethods = []checker.Violation{ - { // (*os.File).Write - Targets: checker.Bytes, - Type: checker.Method, - Package: "os", - Struct: "File", - Caller: "Write", - Args: []int{0}, - AltCaller: "WriteString", - - Generate: &checker.Generate{ - PreCondition: `f := &os.File{}`, - Pattern: `Write($0)`, - Returns: []string{"int", "error"}, - }, - }, - { // (*os.File).WriteString - Targets: checker.Strings, - Type: checker.Method, - Package: "os", - Struct: "File", - Caller: "WriteString", - Args: []int{0}, - AltCaller: "Write", - - Generate: &checker.Generate{ - PreCondition: `f := &os.File{}`, - Pattern: `WriteString($0)`, - Returns: []string{"int", "error"}, - }, - }, -} diff --git a/vendor/github.com/butuzov/mirror/checkers_regexp.go b/vendor/github.com/butuzov/mirror/checkers_regexp.go deleted file mode 100644 index 2cd4dc9f80..0000000000 --- a/vendor/github.com/butuzov/mirror/checkers_regexp.go +++ /dev/null @@ -1,187 +0,0 @@ -package mirror - -import "github.com/butuzov/mirror/internal/checker" - -var ( - RegexpFunctions = []checker.Violation{ - { // regexp.Match - Targets: checker.Bytes, - Type: checker.Function, - Package: "regexp", - Caller: "Match", - Args: []int{1}, - AltCaller: "MatchString", - - Generate: &checker.Generate{ - Pattern: `Match("foo", $0)`, - Returns: []string{"bool", "error"}, - }, - }, - { // regexp.MatchString - Targets: checker.Strings, - Type: checker.Function, - Package: "regexp", - Caller: "MatchString", - Args: []int{1}, - AltCaller: "Match", - - Generate: &checker.Generate{ - Pattern: `MatchString("foo", $0)`, - Returns: []string{"bool", "error"}, - }, - }, - } - - RegexpRegexpMethods = []checker.Violation{ - { // (*regexp.Regexp).Match - Targets: checker.Bytes, - Type: checker.Method, - Package: "regexp", - Struct: "Regexp", - Caller: "Match", - Args: []int{0}, - AltCaller: "MatchString", - - Generate: &checker.Generate{ - PreCondition: `re := regexp.MustCompile(".*")`, - Pattern: `Match($0)`, - Returns: []string{"bool"}, - }, - }, - { // (*regexp.Regexp).MatchString - Targets: checker.Strings, - Type: checker.Method, - Package: "regexp", - Struct: "Regexp", - Caller: "MatchString", - Args: []int{0}, - AltCaller: "Match", - - Generate: &checker.Generate{ - PreCondition: `re := regexp.MustCompile(".*")`, - Pattern: `MatchString($0)`, - Returns: []string{"bool"}, - }, - }, - { // (*regexp.Regexp).FindAllIndex - Targets: checker.Bytes, - Type: checker.Method, - Package: "regexp", - Struct: "Regexp", - Caller: "FindAllIndex", - Args: []int{0}, - AltCaller: "FindAllStringIndex", - - Generate: &checker.Generate{ - PreCondition: `re := regexp.MustCompile(".*")`, - Pattern: `FindAllIndex($0, 1)`, - Returns: []string{"[][]int"}, - }, - }, - { // (*regexp.Regexp).FindAllStringIndex - Targets: checker.Strings, - Type: checker.Method, - Package: "regexp", - Struct: "Regexp", - Caller: "FindAllStringIndex", - Args: []int{0}, - AltCaller: "FindAllIndex", - - Generate: &checker.Generate{ - PreCondition: `re := regexp.MustCompile(".*")`, - Pattern: `FindAllStringIndex($0, 1)`, - Returns: []string{"[][]int"}, - }, - }, - { // (*regexp.Regexp).FindAllSubmatchIndex - Targets: checker.Bytes, - Type: checker.Method, - Package: "regexp", - Struct: "Regexp", - Caller: "FindAllSubmatchIndex", - Args: []int{0}, - AltCaller: "FindAllStringSubmatchIndex", - - Generate: &checker.Generate{ - PreCondition: `re := regexp.MustCompile(".*")`, - Pattern: `FindAllSubmatchIndex($0, 1)`, - Returns: []string{"[][]int"}, - }, - }, - { // (*regexp.Regexp).FindAllStringSubmatchIndex - Targets: checker.Strings, - Type: checker.Method, - Package: "regexp", - Struct: "Regexp", - Caller: "FindAllStringSubmatchIndex", - Args: []int{0}, - AltCaller: "FindAllSubmatchIndex", - - Generate: &checker.Generate{ - PreCondition: `re := regexp.MustCompile(".*")`, - Pattern: `FindAllStringSubmatchIndex($0, 1)`, - Returns: []string{"[][]int"}, - }, - }, - { // (*regexp.Regexp).FindIndex - Targets: checker.Bytes, - Type: checker.Method, - Package: "regexp", - Struct: "Regexp", - Caller: "FindIndex", - Args: []int{0}, - AltCaller: "FindStringIndex", - - Generate: &checker.Generate{ - PreCondition: `re := regexp.MustCompile(".*")`, - Pattern: `FindIndex($0)`, - Returns: []string{"[]int"}, - }, - }, - { // (*regexp.Regexp).FindStringIndex - Targets: checker.Strings, - Type: checker.Method, - Package: "regexp", - Struct: "Regexp", - Caller: "FindStringIndex", - Args: []int{0}, - AltCaller: "FindIndex", - - Generate: &checker.Generate{ - PreCondition: `re := regexp.MustCompile(".*")`, - Pattern: `FindStringIndex($0)`, - Returns: []string{"[]int"}, - }, - }, - { // (*regexp.Regexp).FindSubmatchIndex - Targets: checker.Bytes, - Type: checker.Method, - Package: "regexp", - Struct: "Regexp", - Caller: "FindSubmatchIndex", - Args: []int{0}, - AltCaller: "FindStringSubmatchIndex", - - Generate: &checker.Generate{ - PreCondition: `re := regexp.MustCompile(".*")`, - Pattern: `FindSubmatchIndex($0)`, - Returns: []string{"[]int"}, - }, - }, - { // (*regexp.Regexp).FindStringSubmatchIndex - Targets: checker.Strings, - Type: checker.Method, - Package: "regexp", - Struct: "Regexp", - Caller: "FindStringSubmatchIndex", - Args: []int{0}, - AltCaller: "FindSubmatchIndex", - - Generate: &checker.Generate{ - PreCondition: `re := regexp.MustCompile(".*")`, - Pattern: `FindStringSubmatchIndex($0)`, - Returns: []string{"[]int"}, - }, - }, - } -) diff --git a/vendor/github.com/butuzov/mirror/checkers_strings.go b/vendor/github.com/butuzov/mirror/checkers_strings.go deleted file mode 100644 index 3bd59a62fa..0000000000 --- a/vendor/github.com/butuzov/mirror/checkers_strings.go +++ /dev/null @@ -1,304 +0,0 @@ -package mirror - -import "github.com/butuzov/mirror/internal/checker" - -var ( - StringFunctions = []checker.Violation{ - { // strings.Compare - Targets: checker.Strings, - Type: checker.Function, - Package: "strings", - Caller: "Compare", - Args: []int{0, 1}, - AltPackage: "bytes", - AltCaller: "Compare", - - Generate: &checker.Generate{ - Pattern: `Compare($0,$1)`, - Returns: []string{"int"}, - }, - }, - { // strings.Contains - Targets: checker.Strings, - Type: checker.Function, - Package: "strings", - Caller: "Contains", - Args: []int{0, 1}, - AltPackage: "bytes", - AltCaller: "Contains", - - Generate: &checker.Generate{ - Pattern: `Contains($0,$1)`, - Returns: []string{"bool"}, - }, - }, - { // strings.ContainsAny - Targets: checker.Strings, - Type: checker.Function, - Package: "strings", - Caller: "ContainsAny", - Args: []int{0}, - AltPackage: "bytes", - AltCaller: "ContainsAny", - - Generate: &checker.Generate{ - Pattern: `ContainsAny($0,"foobar")`, - Returns: []string{"bool"}, - }, - }, - { // strings.ContainsRune - Targets: checker.Strings, - Type: checker.Function, - Package: "strings", - Caller: "ContainsRune", - Args: []int{0}, - AltPackage: "bytes", - AltCaller: "ContainsRune", - - Generate: &checker.Generate{ - Pattern: `ContainsRune($0,'ф')`, - Returns: []string{"bool"}, - }, - }, - { // strings.Count - Targets: checker.Strings, - Type: checker.Function, - Package: "strings", - Caller: "Count", - Args: []int{0, 1}, - AltPackage: "bytes", - AltCaller: "Count", - - Generate: &checker.Generate{ - Pattern: `Count($0, $1)`, - Returns: []string{"int"}, - }, - }, - { // strings.EqualFold - Targets: checker.Strings, - Type: checker.Function, - Package: "strings", - Caller: "EqualFold", - Args: []int{0, 1}, - AltPackage: "bytes", - AltCaller: "EqualFold", - - Generate: &checker.Generate{ - Pattern: `EqualFold($0,$1)`, - Returns: []string{"bool"}, - }, - }, - { // strings.HasPrefix - Targets: checker.Strings, - Type: checker.Function, - Package: "strings", - Caller: "HasPrefix", - Args: []int{0, 1}, - AltPackage: "bytes", - AltCaller: "HasPrefix", - - Generate: &checker.Generate{ - Pattern: `HasPrefix($0,$1)`, - Returns: []string{"bool"}, - }, - }, - { // strings.HasSuffix - Targets: checker.Strings, - Type: checker.Function, - Package: "strings", - Caller: "HasSuffix", - Args: []int{0, 1}, - AltPackage: "bytes", - AltCaller: "HasSuffix", - - Generate: &checker.Generate{ - Pattern: `HasSuffix($0,$1)`, - Returns: []string{"bool"}, - }, - }, - { // strings.Index - Targets: checker.Strings, - Type: checker.Function, - Package: "strings", - Caller: "Index", - Args: []int{0, 1}, - AltPackage: "bytes", - AltCaller: "Index", - - Generate: &checker.Generate{ - Pattern: `Index($0,$1)`, - Returns: []string{"int"}, - }, - }, - { // strings.IndexAny - Targets: checker.Strings, - Type: checker.Function, - Package: "strings", - Caller: "IndexAny", - Args: []int{0}, - AltPackage: "bytes", - AltCaller: "IndexAny", - - Generate: &checker.Generate{ - Pattern: `IndexAny($0, "f")`, - Returns: []string{"int"}, - }, - }, - { // strings.IndexByte - Targets: checker.Strings, - Type: checker.Function, - Package: "strings", - Caller: "IndexByte", - Args: []int{0}, - AltPackage: "bytes", - AltCaller: "IndexByte", - - Generate: &checker.Generate{ - Pattern: `IndexByte($0, 'f')`, - Returns: []string{"int"}, - }, - }, - { // strings.IndexFunc - Targets: checker.Strings, - Type: checker.Function, - Package: "strings", - Caller: "IndexFunc", - Args: []int{0}, - AltPackage: "bytes", - AltCaller: "IndexFunc", - - Generate: &checker.Generate{ - Pattern: `IndexFunc($0, func(r rune) bool { return true })`, - Returns: []string{"int"}, - }, - }, - { // strings.IndexRune - Targets: checker.Strings, - Type: checker.Function, - Package: "strings", - Caller: "IndexRune", - Args: []int{0}, - AltPackage: "bytes", - AltCaller: "IndexRune", - - Generate: &checker.Generate{ - Pattern: `IndexRune($0, rune('ф'))`, - Returns: []string{"int"}, - }, - }, - { // strings.LastIndex - Targets: checker.Strings, - Type: checker.Function, - Package: "strings", - Caller: "LastIndex", - Args: []int{0, 1}, - AltPackage: "bytes", - AltCaller: "LastIndex", - - Generate: &checker.Generate{ - Pattern: `LastIndex($0,$1)`, - Returns: []string{"int"}, - }, - }, - { // strings.LastIndexAny - Targets: checker.Strings, - Type: checker.Function, - Package: "strings", - Caller: "LastIndexAny", - Args: []int{0}, - AltPackage: "bytes", - AltCaller: "LastIndexAny", - - Generate: &checker.Generate{ - Pattern: `LastIndexAny($0,"f")`, - Returns: []string{"int"}, - }, - }, - { // strings.LastIndexByte - Targets: checker.Strings, - Type: checker.Function, - Package: "strings", - Caller: "LastIndexByte", - Args: []int{0}, - AltPackage: "bytes", - AltCaller: "LastIndexByte", - - Generate: &checker.Generate{ - Pattern: `LastIndexByte($0, 'f')`, - Returns: []string{"int"}, - }, - }, - { // strings.LastIndexFunc - Targets: checker.Strings, - Type: checker.Function, - Package: "strings", - Caller: "LastIndexFunc", - Args: []int{0}, - AltPackage: "bytes", - AltCaller: "LastIndexFunc", - - Generate: &checker.Generate{ - Pattern: `LastIndexFunc($0, func(r rune) bool { return true })`, - Returns: []string{"int"}, - }, - }, - } - - StringsBuilderMethods = []checker.Violation{ - { // (*strings.Builder).Write - Targets: checker.Bytes, - Type: checker.Method, - Package: "strings", - Struct: "Builder", - Caller: "Write", - Args: []int{0}, - AltCaller: "WriteString", - - Generate: &checker.Generate{ - PreCondition: `builder := strings.Builder{}`, - Pattern: `Write($0)`, - Returns: []string{"int", "error"}, - }, - }, - { // (*strings.Builder).WriteString - Targets: checker.Strings, - Type: checker.Method, - Package: "strings", - Struct: "Builder", - Caller: "WriteString", - Args: []int{0}, - AltCaller: "Write", - - Generate: &checker.Generate{ - PreCondition: `builder := strings.Builder{}`, - Pattern: `WriteString($0)`, - Returns: []string{"int", "error"}, - }, - }, - { // (*strings.Builder).WriteString -> (*strings.Builder).WriteRune - Targets: checker.Strings, - Type: checker.Method, - Package: "strings", - Struct: "Builder", - Caller: "WriteString", - Args: []int{0}, - ArgsType: checker.Rune, - AltCaller: "WriteRune", - Generate: &checker.Generate{ - SkipGenerate: true, - Pattern: `WriteString($0)`, - Returns: []string{"int", "error"}, - }, - }, - // { // (*strings.Builder).WriteString -> (*strings.Builder).WriteByte - // Targets: checker.Strings, - // Type: checker.Method, - // Package: "strings", - // Struct: "Builder", - // Caller: "WriteString", - // Args: []int{0}, - // ArgsType: checker.Byte, - // AltCaller: "WriteByte", // byte - // }, - } -) diff --git a/vendor/github.com/butuzov/mirror/checkers_utf8.go b/vendor/github.com/butuzov/mirror/checkers_utf8.go deleted file mode 100644 index fd3010c37e..0000000000 --- a/vendor/github.com/butuzov/mirror/checkers_utf8.go +++ /dev/null @@ -1,138 +0,0 @@ -package mirror - -import "github.com/butuzov/mirror/internal/checker" - -var UTF8Functions = []checker.Violation{ - { // utf8.Valid - Type: checker.Function, - Targets: checker.Bytes, - Package: "unicode/utf8", - Caller: "Valid", - Args: []int{0}, - AltCaller: "ValidString", - - Generate: &checker.Generate{ - Pattern: `Valid($0)`, - Returns: []string{"bool"}, - }, - }, - { // utf8.ValidString - Targets: checker.Strings, - Type: checker.Function, - Package: "unicode/utf8", - Caller: "ValidString", - Args: []int{0}, - AltCaller: "Valid", - - Generate: &checker.Generate{ - Pattern: `ValidString($0)`, - Returns: []string{"bool"}, - }, - }, - { // utf8.FullRune - Targets: checker.Bytes, - Type: checker.Function, - Package: "unicode/utf8", - Caller: "FullRune", - Args: []int{0}, - AltCaller: "FullRuneInString", - - Generate: &checker.Generate{ - Pattern: `FullRune($0)`, - Returns: []string{"bool"}, - }, - }, - { // utf8.FullRuneInString - Targets: checker.Strings, - Type: checker.Function, - Package: "unicode/utf8", - Caller: "FullRuneInString", - Args: []int{0}, - AltCaller: "FullRune", - - Generate: &checker.Generate{ - Pattern: `FullRuneInString($0)`, - Returns: []string{"bool"}, - }, - }, - - { // bytes.RuneCount - Targets: checker.Bytes, - Type: checker.Function, - Package: "unicode/utf8", - Caller: "RuneCount", - Args: []int{0}, - AltCaller: "RuneCountInString", - - Generate: &checker.Generate{ - Pattern: `RuneCount($0)`, - Returns: []string{"int"}, - }, - }, - { // bytes.RuneCountInString - Targets: checker.Strings, - Type: checker.Function, - Package: "unicode/utf8", - Caller: "RuneCountInString", - Args: []int{0}, - AltCaller: "RuneCount", - - Generate: &checker.Generate{ - Pattern: `RuneCountInString($0)`, - Returns: []string{"int"}, - }, - }, - - { // bytes.DecodeLastRune - Targets: checker.Bytes, - Type: checker.Function, - Package: "unicode/utf8", - Caller: "DecodeLastRune", - Args: []int{0}, - AltCaller: "DecodeLastRuneInString", - - Generate: &checker.Generate{ - Pattern: `DecodeLastRune($0)`, - Returns: []string{"rune", "int"}, - }, - }, - { // utf8.DecodeLastRuneInString - Targets: checker.Strings, - Type: checker.Function, - Package: "unicode/utf8", - Caller: "DecodeLastRuneInString", - Args: []int{0}, - AltCaller: "DecodeLastRune", - - Generate: &checker.Generate{ - Pattern: `DecodeLastRuneInString($0)`, - Returns: []string{"rune", "int"}, - }, - }, - { // utf8.DecodeRune - Targets: checker.Bytes, - Type: checker.Function, - Package: "unicode/utf8", - Caller: "DecodeRune", - Args: []int{0}, - AltCaller: "DecodeRuneInString", - - Generate: &checker.Generate{ - Pattern: `DecodeRune($0)`, - Returns: []string{"rune", "int"}, - }, - }, - { // utf8.DecodeRuneInString - Targets: checker.Strings, - Type: checker.Function, - Package: "unicode/utf8", - Args: []int{0}, - Caller: "DecodeRuneInString", - AltCaller: "DecodeRune", - - Generate: &checker.Generate{ - Pattern: `DecodeRuneInString($0)`, - Returns: []string{"rune", "int"}, - }, - }, -} diff --git a/vendor/github.com/butuzov/mirror/internal/checker/checker.go b/vendor/github.com/butuzov/mirror/internal/checker/checker.go deleted file mode 100644 index fb9ba41729..0000000000 --- a/vendor/github.com/butuzov/mirror/internal/checker/checker.go +++ /dev/null @@ -1,147 +0,0 @@ -package checker - -import ( - "bytes" - "go/ast" - "go/printer" - "go/token" - "go/types" - "strings" -) - -// Checker will perform standard check on package and its methods. -type Checker struct { - Violations []Violation // List of available violations - Packages map[string][]int // Storing indexes of Violations per pkg/kg.Struct - Type func(ast.Expr) string // Type Checker closure. - Print func(ast.Node) []byte // String representation of the expression. -} - -func New(violations ...[]Violation) Checker { - c := Checker{ - Packages: make(map[string][]int), - } - - for i := range violations { - c.register(violations[i]) - } - - return c -} - -// Match will check the available violations we got from checks against -// the `name` caller from package `pkgName`. -func (c *Checker) Match(pkgName, name string) *Violation { - for _, v := range c.Matches(pkgName, name) { - return v - } - - return nil -} - -// Matches do same thing as Match but return a slice of violations -// as only things that require this are bytes.Buffer and strings.Builder -// it only be used in matching methods in analyzer. -func (c *Checker) Matches(pkgName, name string) []*Violation { - var matches []*Violation - checkStruct := strings.Contains(pkgName, ".") - - for _, idx := range c.Packages[pkgName] { - if c.Violations[idx].Caller == name { - if checkStruct == (len(c.Violations[idx].Struct) == 0) { - continue - } - - // copy violation - v := c.Violations[idx] - matches = append(matches, &v) - } - } - - return matches -} - -func (c *Checker) Handle(v *Violation, ce *ast.CallExpr) (map[int]ast.Expr, bool) { - m := map[int]ast.Expr{} - - // We going to check each of elements we mark for checking, in order to find, - // a call that violates our rules. - for _, i := range v.Args { - if i >= len(ce.Args) { - continue - } - - call, ok := ce.Args[i].(*ast.CallExpr) - if !ok { - continue - } - - // is it conversion call - if !c.callConverts(call) { - continue - } - - // somehow no argument of call - if len(call.Args) == 0 { - continue - } - - // wrong argument type - if normalType(c.Type(call.Args[0])) != v.getArgType() { - continue - } - - m[i] = call.Args[0] - } - - return m, len(m) == len(v.Args) -} - -func (c *Checker) callConverts(ce *ast.CallExpr) bool { - switch ce.Fun.(type) { - case *ast.ArrayType, *ast.Ident: - res := c.Type(ce.Fun) - return res == "[]byte" || res == "string" - } - - return false -} - -// register violations. -func (c *Checker) register(violations []Violation) { - for _, v := range violations { // nolint: gocritic - c.Violations = append(c.Violations, v) - if len(v.Struct) > 0 { - c.registerIdxPer(v.Package + "." + v.Struct) - } - c.registerIdxPer(v.Package) - } -} - -// registerIdxPer will register last added violation element -// under pkg string. -func (c *Checker) registerIdxPer(pkg string) { - c.Packages[pkg] = append(c.Packages[pkg], len(c.Violations)-1) -} - -func WrapType(info *types.Info) func(node ast.Expr) string { - return func(node ast.Expr) string { - if t := info.TypeOf(node); t != nil { - return t.String() - } - - if tv, ok := info.Types[node]; ok { - return tv.Type.Underlying().String() - } - - return "" - } -} - -func WrapPrint(fSet *token.FileSet) func(ast.Node) []byte { - return func(node ast.Node) []byte { - var buf bytes.Buffer - printer.Fprint(&buf, fSet, node) - return buf.Bytes() - } -} diff --git a/vendor/github.com/butuzov/mirror/internal/checker/imports.go b/vendor/github.com/butuzov/mirror/internal/checker/imports.go deleted file mode 100644 index 4015de5970..0000000000 --- a/vendor/github.com/butuzov/mirror/internal/checker/imports.go +++ /dev/null @@ -1,89 +0,0 @@ -package checker - -import ( - "go/ast" - "go/token" - "path" - "sort" - "strings" - "sync" - - "golang.org/x/tools/go/ast/inspector" -) - -// Imports represents an imported package in a nice for lookup way... -// -// examples: -// import . "bytes" -> checker.Import{Pkg:"bytes", Val:"."} -// import name "bytes" -> checker.Import{Pkg:"bytes", Val:"name"} -type Import struct { - Pkg string // package name - Name string // alias -} - -type Imports map[string][]Import - -// we are going to have Imports entries to be sorted, but if it has less then -// `sortLowerLimit` elements we are skipping this step as its not going to -// be worth of effort. -const sortLowerLimit int = 13 - -// Package level lock is to prevent import map corruption -var lock sync.RWMutex - -func Load(fs *token.FileSet, ins *inspector.Inspector) Imports { - lock.Lock() - defer lock.Unlock() - - imports := make(Imports) - - // Populate imports map - ins.Preorder([]ast.Node{(*ast.ImportSpec)(nil)}, func(node ast.Node) { - importSpec, _ := node.(*ast.ImportSpec) - - var ( - key = fs.Position(node.Pos()).Filename - pkg = strings.Trim(importSpec.Path.Value, `"`) - name = importSpec.Name.String() - ) - - if importSpec.Name == nil { - name = path.Base(pkg) // note: we need only basename of the package - } - - imports[key] = append(imports[key], Import{ - Pkg: pkg, - Name: name, - }) - }) - - imports.sort() - - return imports -} - -// sort will sort imports for each of the checking files. -func (i *Imports) sort() { - for k := range *i { - if len((*i)[k]) < sortLowerLimit { - continue - } - - k := k - sort.Slice((*i)[k], func(left, right int) bool { - return (*i)[k][left].Name < (*i)[k][right].Name - }) - } -} - -func (i Imports) Lookup(file, pkg string) (string, bool) { - if _, ok := i[file]; ok { - for idx := range i[file] { - if i[file][idx].Name == pkg { - return i[file][idx].Pkg, true - } - } - } - - return "", false -} diff --git a/vendor/github.com/butuzov/mirror/internal/checker/violation.go b/vendor/github.com/butuzov/mirror/internal/checker/violation.go deleted file mode 100644 index c2c1492086..0000000000 --- a/vendor/github.com/butuzov/mirror/internal/checker/violation.go +++ /dev/null @@ -1,209 +0,0 @@ -package checker - -import ( - "bytes" - "fmt" - "go/ast" - "go/printer" - "go/token" - "path" - "strings" - - "golang.org/x/tools/go/analysis" -) - -// Type of violation: can be method or function -type ViolationType int - -const ( - Function ViolationType = iota + 1 - Method -) - -const ( - Strings string = "string" - Bytes string = "[]byte" - Byte string = "byte" - Rune string = "rune" - UntypedRune string = "untyped rune" -) - -// Violation describes what message we going to give to a particular code violation -type Violation struct { - Type ViolationType // - Args []int // Indexes of the arguments needs to be checked - ArgsType string - - Targets string - Package string - AltPackage string - Struct string - Caller string - AltCaller string - - // --- tests generation information - Generate *Generate - - // --- suggestions related info about violation of rules. - base []byte // receiver of the method or pkg name - callExpr *ast.CallExpr // actual call expression, to extract arguments - arguments map[int]ast.Expr // fixed arguments -} - -// Tests (generation) related struct. -type Generate struct { - SkipGenerate bool - PreCondition string // Precondition we want to be generated - Pattern string // Generate pattern (for the `want` message) - Returns []string // ReturnTypes as slice -} - -func (v *Violation) With(base []byte, e *ast.CallExpr, args map[int]ast.Expr) *Violation { - v.base = base - v.callExpr = e - v.arguments = args - - return v -} - -func (v *Violation) getArgType() string { - if v.ArgsType != "" { - return v.ArgsType - } - - if v.Targets == Strings { - return Bytes - } - - return Strings -} - -func (v *Violation) Message() string { - if v.Type == Method { - return fmt.Sprintf("avoid allocations with (*%s.%s).%s", - path.Base(v.Package), v.Struct, v.AltCaller) - } - - pkg := v.Package - if len(v.AltPackage) > 0 { - pkg = v.AltPackage - } - - return fmt.Sprintf("avoid allocations with %s.%s", path.Base(pkg), v.AltCaller) -} - -func (v *Violation) suggest(fSet *token.FileSet) []byte { - var buf bytes.Buffer - - if len(v.base) > 0 { - buf.Write(v.base) - buf.WriteString(".") - } - - buf.WriteString(v.AltCaller) - buf.WriteByte('(') - for idx := range v.callExpr.Args { - if arg, ok := v.arguments[idx]; ok { - printer.Fprint(&buf, fSet, arg) - } else { - printer.Fprint(&buf, fSet, v.callExpr.Args[idx]) - } - - if idx != len(v.callExpr.Args)-1 { - buf.WriteString(", ") - } - } - buf.WriteByte(')') - - return buf.Bytes() -} - -func (v *Violation) Diagnostic(fSet *token.FileSet) analysis.Diagnostic { - diagnostic := analysis.Diagnostic{ - Pos: v.callExpr.Pos(), - End: v.callExpr.Pos(), - Message: v.Message(), - } - - var buf bytes.Buffer - printer.Fprint(&buf, fSet, v.callExpr) - noNl := bytes.IndexByte(buf.Bytes(), '\n') < 0 - - // Struct based fix. - if v.Type == Method && noNl { - diagnostic.SuggestedFixes = []analysis.SuggestedFix{{ - Message: "Fix Issue With", - TextEdits: []analysis.TextEdit{{ - Pos: v.callExpr.Pos(), End: v.callExpr.End(), NewText: v.suggest(fSet), - }}, - }} - } - - if v.AltPackage == "" { - v.AltPackage = v.Package - } - - // Hooray! we don't need to change package and redo imports. - if v.Type == Function && v.AltPackage == v.Package && noNl { - diagnostic.SuggestedFixes = []analysis.SuggestedFix{{ - Message: "Fix Issue With", - TextEdits: []analysis.TextEdit{{ - Pos: v.callExpr.Pos(), End: v.callExpr.End(), NewText: v.suggest(fSet), - }}, - }} - } - - // do not change - - return diagnostic -} - -type GolangIssue struct { - Start token.Position - End token.Position - Message string - InlineFix string - Original string -} - -// Issue intended to be used only within `golangci-lint`, but you can use it -// alongside Diagnostic if you wish. -func (v *Violation) Issue(fSet *token.FileSet) GolangIssue { - issue := GolangIssue{ - Start: fSet.Position(v.callExpr.Pos()), - End: fSet.Position(v.callExpr.End()), - Message: v.Message(), - } - - // original expression (useful for debug & required for replace) - var buf bytes.Buffer - printer.Fprint(&buf, fSet, v.callExpr) - issue.Original = buf.String() - - noNl := strings.IndexByte(issue.Original, '\n') < 0 - - if v.Type == Method && noNl { - fix := v.suggest(fSet) - issue.InlineFix = string(fix) - } - - if v.AltPackage == "" { - v.AltPackage = v.Package - } - - // Hooray! we don't need to change package and redo imports. - if v.Type == Function && v.AltPackage == v.Package && noNl { - fix := v.suggest(fSet) - issue.InlineFix = string(fix) - } - - return issue -} - -// ofType normalize input types (mostly typed and untyped runes). -func normalType(s string) string { - if s == UntypedRune { - return Rune - } - return s -} diff --git a/vendor/github.com/butuzov/mirror/readme.md b/vendor/github.com/butuzov/mirror/readme.md deleted file mode 100644 index f5cfa47a68..0000000000 --- a/vendor/github.com/butuzov/mirror/readme.md +++ /dev/null @@ -1,121 +0,0 @@ -# `mirror` [![Stand with Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/badges/StandWithUkraine.svg)](https://u24.gov.ua/) [![Code Coverage](https://coveralls.io/repos/github/butuzov/mirror/badge.svg?branch=main)](https://coveralls.io/github/butuzov/mirror?branch=main) [![build status](https://github.com/butuzov/mirror/actions/workflows/main.yaml/badge.svg?branch=main)]() - -`mirror` suggests use of alternative functions/methods in order to gain performance boosts by avoiding unnecessary `[]byte/string` conversion calls. See [MIRROR_FUNCS.md](MIRROR_FUNCS.md) list of mirror functions you can use in go's stdlib. - ---- - -[![United 24](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/banner-personal-page.svg)](https://u24.gov.ua/) -[![Help Oleg Butuzov](https://raw.githubusercontent.com/butuzov/butuzov/main/personal.svg)](https://github.com/butuzov) - ---- - -## Linter Use Cases - -### `github.com/argoproj/argo-cd` - -```go -// Before -func IsValidHostname(hostname string, fqdn bool) bool { - if !fqdn { - return validHostNameRegexp.Match([]byte(hostname)) || validIPv6Regexp.Match([]byte(hostname)) - } else { - return validFQDNRegexp.Match([]byte(hostname)) - } -} - -// After: With alternative method (and lost `else` case) -func IsValidHostname(hostname string, fqdn bool) bool { - if !fqdn { - return validHostNameRegexp.MatchString(hostname) || validIPv6Regexp.MatchString(hostname) - } - - return validFQDNRegexp.MatchString(hostname) -} -``` - -## Install - -``` -go install github.com/butuzov/mirror/cmd/mirror@latest -``` - -### `golangci-lint` -`golangci-lint` supports `mirror` since `v1.53.0` - - -## How to use - -You run `mirror` with [`go vet`](https://pkg.go.dev/cmd/vet): - -``` -go vet -vettool=$(which mirror) ./... -# github.com/jcmoraisjr/haproxy-ingress/pkg/common/net/ssl -pkg/common/net/ssl/ssl.go:64:11: avoid allocations with (*os.File).WriteString -pkg/common/net/ssl/ssl.go:161:12: avoid allocations with (*os.File).WriteString -pkg/common/net/ssl/ssl.go:166:3: avoid allocations with (*os.File).WriteString -``` - -Can be called directly: -``` -mirror ./... -# https://github.com/cosmtrek/air -/air/runner/util.go:149:6: avoid allocations with (*regexp.Regexp).MatchString -/air/runner/util.go:173:14: avoid allocations with (*os.File).WriteString -``` - -With [`golangci-lint`](https://github.com/golangci/golangci-lint) - -``` -golangci-lint run --no-config --disable-all -Emirror -# github.com/argoproj/argo-cd -test/e2e/fixture/app/actions.go:83:11: avoid allocations with (*os.File).WriteString (mirror) - _, err = tmpFile.Write([]byte(data)) - ^ -server/server.go:1166:9: avoid allocations with (*regexp.Regexp).MatchString (mirror) - return mainJsBundleRegex.Match([]byte(filename)) - ^ -server/account/account.go:91:6: avoid allocations with (*regexp.Regexp).MatchString (mirror) - if !validPasswordRegexp.Match([]byte(q.NewPassword)) { - ^ -server/badge/badge.go:52:20: avoid allocations with (*regexp.Regexp).FindAllStringSubmatchIndex (mirror) - for _, v := range re.FindAllSubmatchIndex([]byte(str), -1) { - ^ -util/cert/cert.go:82:10: avoid allocations with (*regexp.Regexp).MatchString (mirror) - return validHostNameRegexp.Match([]byte(hostname)) || validIPv6Regexp.Match([]byte(hostname)) -``` - -## Command line - -- You can add checks for `_test.go` files with cli option `--with-tests` - -### `golangci-lint` - With `golangci-lint` tests are checked by default and can be can be turned off by using the regular `golangci-lint` ways to do it: - - - flag `--tests` (e.g. `--tests=false`) - - flag `--skip-files` (e.g. `--skip-files="_test.go"`) - - yaml configuration `run.skip-files`: - ```yaml - run: - skip-files: - - '(.+)_test\.go' - ``` - - yaml configuration `issues.exclude-rules`: - ```yaml - issues: - exclude-rules: - - path: '(.+)_test\.go' - linters: - - mirror - ``` - - -## Contributing - -```shell -# Update Assets (testdata/(strings|bytes|os|utf8|maphash|regexp|bufio).go) -(task|make) generate -# Run Tests -(task|make) tests -# Lint Code -(task|make) lints -``` diff --git a/vendor/github.com/catenacyber/perfsprint/LICENSE b/vendor/github.com/catenacyber/perfsprint/LICENSE deleted file mode 100644 index 14c2b9e737..0000000000 --- a/vendor/github.com/catenacyber/perfsprint/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 Catena cyber - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/catenacyber/perfsprint/analyzer/analyzer.go b/vendor/github.com/catenacyber/perfsprint/analyzer/analyzer.go deleted file mode 100644 index 42eb0259ae..0000000000 --- a/vendor/github.com/catenacyber/perfsprint/analyzer/analyzer.go +++ /dev/null @@ -1,917 +0,0 @@ -package analyzer - -import ( - "bytes" - "fmt" - "go/ast" - "go/format" - "go/token" - "go/types" - "sort" - "strconv" - "strings" - - "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/inspector" - - "golang.org/x/tools/go/analysis" -) - -type optionInt struct { - enabled bool - intConv bool -} - -type optionErr struct { - enabled bool - errError bool - errorf bool -} - -type optionStr struct { - enabled bool - sprintf1 bool - strconcat bool -} - -type optionConcatLoop struct { - enabled bool - otherOps bool -} - -type perfSprint struct { - intFormat optionInt - errFormat optionErr - strFormat optionStr - concatLoop optionConcatLoop - - boolFormat bool - hexFormat bool - - fiximports bool -} - -func newPerfSprint() *perfSprint { - return &perfSprint{ - intFormat: optionInt{enabled: true, intConv: true}, - errFormat: optionErr{enabled: true, errError: false, errorf: true}, - strFormat: optionStr{enabled: true, sprintf1: true, strconcat: true}, - concatLoop: optionConcatLoop{enabled: true, otherOps: false}, - boolFormat: true, - hexFormat: true, - fiximports: true, - } -} - -const ( - // checkerErrorFormat checks for error formatting. - checkerErrorFormat = "error-format" - // checkerIntegerFormat checks for integer formatting. - checkerIntegerFormat = "integer-format" - // checkerStringFormat checks for string formatting. - checkerStringFormat = "string-format" - // checkerBoolFormat checks for bool formatting. - checkerBoolFormat = "bool-format" - // checkerHexFormat checks for hexadecimal formatting. - checkerHexFormat = "hex-format" - // checkerConcatLoop checks for concatenation in loop. - checkerConcatLoop = "concat-loop" - // checkerFixImports fix needed imports from other fixes. - checkerFixImports = "fiximports" -) - -func New() *analysis.Analyzer { - n := newPerfSprint() - r := &analysis.Analyzer{ - Name: "perfsprint", - URL: "https://github.com/catenacyber/perfsprint", - Doc: "Checks that fmt.Sprintf can be replaced with a faster alternative.", - Run: n.run, - Requires: []*analysis.Analyzer{inspect.Analyzer}, - } - - r.Flags.BoolVar(&n.intFormat.enabled, checkerIntegerFormat, n.intFormat.enabled, "enable/disable optimization of integer formatting") - r.Flags.BoolVar(&n.intFormat.intConv, "int-conversion", n.intFormat.intConv, "optimizes even if it requires an int or uint type cast") - r.Flags.BoolVar(&n.errFormat.enabled, checkerErrorFormat, n.errFormat.enabled, "enable/disable optimization of error formatting") - r.Flags.BoolVar(&n.errFormat.errError, "err-error", n.errFormat.errError, "optimizes into err.Error() even if it is only equivalent for non-nil errors") - r.Flags.BoolVar(&n.errFormat.errorf, "errorf", n.errFormat.errorf, "optimizes fmt.Errorf") - - r.Flags.BoolVar(&n.boolFormat, checkerBoolFormat, n.boolFormat, "enable/disable optimization of bool formatting") - r.Flags.BoolVar(&n.hexFormat, checkerHexFormat, n.hexFormat, "enable/disable optimization of hex formatting") - r.Flags.BoolVar(&n.concatLoop.enabled, checkerConcatLoop, n.concatLoop.enabled, "enable/disable optimization of concat loop") - r.Flags.BoolVar(&n.concatLoop.otherOps, "loop-other-ops", n.concatLoop.otherOps, "optimization of concat loop even with other operations") - r.Flags.BoolVar(&n.strFormat.enabled, checkerStringFormat, n.strFormat.enabled, "enable/disable optimization of string formatting") - r.Flags.BoolVar(&n.strFormat.sprintf1, "sprintf1", n.strFormat.sprintf1, "optimizes fmt.Sprintf with only one argument") - r.Flags.BoolVar(&n.strFormat.strconcat, "strconcat", n.strFormat.strconcat, "optimizes into strings concatenation") - r.Flags.BoolVar(&n.fiximports, checkerFixImports, n.fiximports, "fix needed imports from other fixes") - - return r -} - -// true if verb is a format string that could be replaced with concatenation. -func isConcatable(verb string) bool { - hasPrefix := (strings.HasPrefix(verb, "%s") && !strings.Contains(verb, "%[1]s")) || - (strings.HasPrefix(verb, "%[1]s") && !strings.Contains(verb, "%s")) - hasSuffix := (strings.HasSuffix(verb, "%s") && !strings.Contains(verb, "%[1]s")) || - (strings.HasSuffix(verb, "%[1]s") && !strings.Contains(verb, "%s")) - - if strings.Count(verb, "%[1]s") > 1 { - return false - } - return (hasPrefix || hasSuffix) && !(hasPrefix && hasSuffix) -} - -func isStringAdd(st *ast.AssignStmt, idname string) ast.Expr { - // right is one - if len(st.Rhs) == 1 { - // right is addition - add, ok := st.Rhs[0].(*ast.BinaryExpr) - if ok && add.Op == token.ADD { - // right is addition to same ident name - x, ok := add.X.(*ast.Ident) - if ok && x.Name == idname { - return add.Y - } - } - } - return nil -} - -func (n *perfSprint) reportConcatLoop(pass *analysis.Pass, neededPackages map[string]map[string]struct{}, node ast.Node, adds map[string][]*ast.AssignStmt) *analysis.Diagnostic { - fname := pass.Fset.File(node.Pos()).Name() - if _, ok := neededPackages[fname]; !ok { - neededPackages[fname] = make(map[string]struct{}) - } - // note that we will need strings package - neededPackages[fname]["strings"] = struct{}{} - - // sort for reproducibility - keys := make([]string, 0, len(adds)) - for k := range adds { - keys = append(keys, k) - } - sort.Strings(keys) - - // use line number to define a unique variable name for the strings Builder - loopStartLine := pass.Fset.Position(node.Pos()).Line - - // If the loop does more with the string than concatenations - // add a TODO/FIXME comment that the fix is likely incomplete/incorrect - addTODO := "" - ast.Inspect(node, func(n ast.Node) bool { - if len(addTODO) > 0 { - // already found one, stop recursing - return false - } - switch x := n.(type) { - case *ast.AssignStmt: - // skip if this is one string concatenation that we are fixing - if (x.Tok == token.ASSIGN || x.Tok == token.ADD_ASSIGN) && len(x.Lhs) == 1 { - id, ok := x.Lhs[0].(*ast.Ident) - if ok { - _, ok = adds[id.Name] - if ok { - return false - } - } - } - case *ast.Ident: - _, ok := adds[x.Name] - if ok { - // The variable name is used in some place else - addTODO = x.Name - return false - } - } - return true - }) - - prefix := "" - suffix := "" - if len(addTODO) > 0 { - if !n.concatLoop.otherOps { - return nil - } - prefix = fmt.Sprintf("// FIXME check usages of string identifier %s (and mayber others) in loop\n", addTODO) - } - // The fix contains 3 parts - // before the loop: declare the strings Builders - // during the loop: replace concatenation with Builder.WriteString - // after the loop: use the Builder.String to append to the pre-existing string - for _, k := range keys { - // lol - prefix += fmt.Sprintf("var %sSb%d strings.Builder\n", k, loopStartLine) - suffix += fmt.Sprintf("\n%s += %sSb%d.String()", k, k, loopStartLine) - } - te := []analysis.TextEdit{ - { - Pos: node.Pos(), - End: node.Pos(), - NewText: []byte(prefix), - }, - } - for _, k := range keys { - v := adds[k] - for _, st := range v { - // s += "x" -> use "x" - added := st.Rhs[0] - if st.Tok == token.ASSIGN { - // s = s + "x" -> use just "x", not `s + "x"` - added = isStringAdd(st, k) - } - te = append(te, analysis.TextEdit{ - Pos: st.Pos(), - End: added.Pos(), - NewText: []byte(fmt.Sprintf("%sSb%d.WriteString(", k, loopStartLine)), - }) - te = append(te, analysis.TextEdit{ - Pos: added.End(), - End: added.End(), - NewText: []byte(")"), - }) - } - } - te = append(te, analysis.TextEdit{ - Pos: node.End(), - End: node.End(), - NewText: []byte(suffix), - }) - - return newAnalysisDiagnostic( - checkerConcatLoop, - adds[keys[0]][0], - "string concatenation in a loop", - []analysis.SuggestedFix{ - { - Message: "Use a strings.Builder", - TextEdits: te, - }, - }, - ) -} - -func (n *perfSprint) runConcatLoop(pass *analysis.Pass, neededPackages map[string]map[string]struct{}) { - insp := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - // 2 different kinds of loops in go - nodeFilter := []ast.Node{ - (*ast.RangeStmt)(nil), - (*ast.ForStmt)(nil), - } - insp.Preorder(nodeFilter, func(node ast.Node) { - // set of variable names declared insied the loop - declInLoop := make(map[string]bool) - var bl []ast.Stmt - // just take the list of instruction of the loop - switch ra := node.(type) { - case *ast.RangeStmt: - bl = ra.Body.List - case *ast.ForStmt: - bl = ra.Body.List - } - // set of results : mapping a variable name to a list of statements like `s +=` - // one loop may be bad for multiple string variables, - // each being concatenated in multiple statements - adds := make(map[string][]*ast.AssignStmt) - for bs := 0; bs < len(bl); bs++ { - switch st := bl[bs].(type) { - case *ast.IfStmt: - // explore breadth first, but go inside the if/else blocks - if st.Body != nil { - bl = append(bl, st.Body.List...) - } - el, ok := st.Else.(*ast.BlockStmt) - if ok && el != nil { - bl = append(bl, el.List...) - } - case *ast.DeclStmt: - // identifiers defined within loop do not count - de, ok := st.Decl.(*ast.GenDecl) - if !ok { - break - } - if len(de.Specs) != 1 { - break - } - // is it possible to have len(de.Specs) > 1 for ValueSpec ? - vs, ok := de.Specs[0].(*ast.ValueSpec) - if !ok { - break - } - for n := range vs.Names { - declInLoop[vs.Names[n].Name] = true - } - case *ast.AssignStmt: - for n := range st.Lhs { - id, ok := st.Lhs[n].(*ast.Ident) - if !ok { - break - } - switch st.Tok { - case token.DEFINE: - declInLoop[id.Name] = true - case token.ASSIGN, token.ADD_ASSIGN: - if n > 0 { - // do not search bugs for multi-assign - break - } - _, local := declInLoop[id.Name] - if local { - break - } - ti, ok := pass.TypesInfo.Types[id] - if !ok || ti.Type.String() != "string" { - break - } - if st.Tok == token.ASSIGN { - if isStringAdd(st, id.Name) == nil { - break - } - } - // found a bad string concat in the loop - adds[id.Name] = append(adds[id.Name], st) - } - } - } - } - if len(adds) > 0 { - d := n.reportConcatLoop(pass, neededPackages, node, adds) - if d != nil { - pass.Report(*d) - } - } - }) -} - -func (n *perfSprint) fixImports(pass *analysis.Pass, neededPackages map[string]map[string]struct{}, removedFmtUsages map[string]int) { - if !n.fiximports { - return - } - for _, pkg := range pass.Pkg.Imports() { - if pkg.Path() == "fmt" { - insp := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - nodeFilter := []ast.Node{ - (*ast.SelectorExpr)(nil), - } - insp.Preorder(nodeFilter, func(node ast.Node) { - selec := node.(*ast.SelectorExpr) - selecok, ok := selec.X.(*ast.Ident) - if ok { - pkgname, ok := pass.TypesInfo.ObjectOf(selecok).(*types.PkgName) - if ok && pkgname.Name() == pkg.Name() { - fname := pass.Fset.File(pkgname.Pos()).Name() - removedFmtUsages[fname]-- - } - } - }) - } else if pkg.Path() == "errors" || pkg.Path() == "strconv" || pkg.Path() == "encoding/hex" || pkg.Path() == "strings" { - insp := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - nodeFilter := []ast.Node{ - (*ast.ImportSpec)(nil), - } - insp.Preorder(nodeFilter, func(node ast.Node) { - gd := node.(*ast.ImportSpec) - if gd.Path.Value == strconv.Quote(pkg.Path()) { - fname := pass.Fset.File(gd.Pos()).Name() - if _, ok := neededPackages[fname]; ok { - delete(neededPackages[fname], pkg.Path()) - } - } - }) - } - } - insp := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - nodeFilter := []ast.Node{ - (*ast.File)(nil), - } - insp.Preorder(nodeFilter, func(node ast.Node) { - gd := node.(*ast.File) - fname := pass.Fset.File(gd.Pos()).Name() - removed, hasFmt := removedFmtUsages[fname] - if (!hasFmt || removed < 0) && len(neededPackages[fname]) == 0 { - return - } - fix := "" - var ar analysis.Range - ar = gd.Decls[0] - start := gd.Decls[0].Pos() - end := gd.Decls[0].Pos() - if len(gd.Imports) == 0 { - fix += "import (\n" - } else { - id := gd.Decls[0].(*ast.GenDecl) - start = id.Specs[0].Pos() - end = id.Specs[0].Pos() - if removedFmtUsages[fname] >= 0 { - for sp := range id.Specs { - is := id.Specs[sp].(*ast.ImportSpec) - if is.Path.Value == strconv.Quote("fmt") { - ar = is - start = is.Pos() - end = is.End() - break - } - } - } - } - keys := make([]string, 0, len(neededPackages[fname])) - for k := range neededPackages[fname] { - keys = append(keys, k) - } - sort.Strings(keys) - for _, k := range keys { - already := false - knames := strings.Split(k, "/") - kname := knames[len(knames)-1] - for i := range gd.Imports { // quadratic - if (gd.Imports[i].Name != nil && gd.Imports[i].Name.Name == kname) || (gd.Imports[i].Name == nil && strings.HasSuffix(gd.Imports[i].Path.Value, "/"+kname+`"`)) { - already = true - } - } - if already { - fix = fix + "\t\"" + k + "\" //TODO FIXME\n" - } else { - fix = fix + "\t\"" + k + "\"\n" - } - } - if len(gd.Imports) == 0 { - fix += ")\n" - } - pass.Report(*newAnalysisDiagnostic( - checkerFixImports, - ar, - "Fix imports", - []analysis.SuggestedFix{ - { - Message: "Fix imports", - TextEdits: []analysis.TextEdit{{ - Pos: start, - End: end, - NewText: []byte(fix), - }}, - }, - })) - }) -} - -func (n *perfSprint) run(pass *analysis.Pass) (interface{}, error) { - if !n.intFormat.enabled { - n.intFormat.intConv = false - } - if !n.errFormat.enabled { - n.errFormat.errError = false - n.errFormat.errorf = false - } - if !n.strFormat.enabled { - n.strFormat.sprintf1 = false - n.strFormat.strconcat = false - } - - neededPackages := make(map[string]map[string]struct{}) - if n.concatLoop.enabled { - n.runConcatLoop(pass, neededPackages) - } - removedFmtUsages := make(map[string]int) - var fmtSprintObj, fmtSprintfObj, fmtErrorfObj types.Object - for _, pkg := range pass.Pkg.Imports() { - if pkg.Path() == "fmt" { - fmtSprintObj = pkg.Scope().Lookup("Sprint") - fmtSprintfObj = pkg.Scope().Lookup("Sprintf") - fmtErrorfObj = pkg.Scope().Lookup("Errorf") - } - } - if fmtSprintfObj == nil && fmtSprintObj == nil && fmtErrorfObj == nil { - if len(neededPackages) > 0 { - n.fixImports(pass, neededPackages, removedFmtUsages) - } - return nil, nil - } - - insp := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - nodeFilter := []ast.Node{ - (*ast.CallExpr)(nil), - } - insp.Preorder(nodeFilter, func(node ast.Node) { - call := node.(*ast.CallExpr) - called, ok := call.Fun.(*ast.SelectorExpr) - if !ok { - return - } - calledObj := pass.TypesInfo.ObjectOf(called.Sel) - - var ( - fn string - verb string - value ast.Expr - err error - ) - switch { - case calledObj == fmtErrorfObj && len(call.Args) == 1 && n.errFormat.errorf: - fn = "fmt.Errorf" - verb = "%s" - value = call.Args[0] - - case calledObj == fmtSprintObj && len(call.Args) == 1: - fn = "fmt.Sprint" - verb = "%v" - value = call.Args[0] - - case calledObj == fmtSprintfObj && len(call.Args) == 1 && n.strFormat.sprintf1: - fn = "fmt.Sprintf" - verb = "%s" - value = call.Args[0] - - case calledObj == fmtSprintfObj && len(call.Args) == 2: - verbLit, ok := call.Args[0].(*ast.BasicLit) - if !ok { - return - } - verb, err = strconv.Unquote(verbLit.Value) - if err != nil { - // Probably unreachable. - return - } - // one single explicit arg is simplified - if strings.HasPrefix(verb, "%[1]") { - verb = "%" + verb[4:] - } - - fn = "fmt.Sprintf" - value = call.Args[1] - - default: - return - } - - switch verb { - default: - if fn == "fmt.Sprintf" && isConcatable(verb) && n.strFormat.strconcat { - break - } - return - case "%d", "%v", "%x", "%t", "%s": - } - - valueType := pass.TypesInfo.TypeOf(value) - a, isArray := valueType.(*types.Array) - s, isSlice := valueType.(*types.Slice) - - var d *analysis.Diagnostic - switch { - case isBasicType(valueType, types.String) && oneOf(verb, "%v", "%s"): - fname := pass.Fset.File(call.Pos()).Name() - if _, ok := neededPackages[fname]; !ok { - neededPackages[fname] = make(map[string]struct{}) - } - removedFmtUsages[fname]++ - if fn == "fmt.Errorf" && n.errFormat.enabled { - neededPackages[fname]["errors"] = struct{}{} - d = newAnalysisDiagnostic( - checkerErrorFormat, - call, - fn+" can be replaced with errors.New", - []analysis.SuggestedFix{ - { - Message: "Use errors.New", - TextEdits: []analysis.TextEdit{{ - Pos: call.Pos(), - End: value.Pos(), - NewText: []byte("errors.New("), - }}, - }, - }, - ) - } else if fn != "fmt.Errorf" && n.strFormat.enabled { - d = newAnalysisDiagnostic( - checkerStringFormat, - call, - fn+" can be replaced with just using the string", - []analysis.SuggestedFix{ - { - Message: "Just use string value", - TextEdits: []analysis.TextEdit{{ - Pos: call.Pos(), - End: call.End(), - NewText: []byte(formatNode(pass.Fset, value)), - }}, - }, - }, - ) - } - case types.Implements(valueType, errIface) && oneOf(verb, "%v", "%s") && n.errFormat.errError: - // known false positive if this error is nil - // fmt.Sprint(nil) does not panic like nil.Error() does - errMethodCall := formatNode(pass.Fset, value) + ".Error()" - fname := pass.Fset.File(call.Pos()).Name() - removedFmtUsages[fname]++ - d = newAnalysisDiagnostic( - checkerErrorFormat, - call, - fn+" can be replaced with "+errMethodCall, - []analysis.SuggestedFix{ - { - Message: "Use " + errMethodCall, - TextEdits: []analysis.TextEdit{{ - Pos: call.Pos(), - End: call.End(), - NewText: []byte(errMethodCall), - }}, - }, - }, - ) - - case isBasicType(valueType, types.Bool) && oneOf(verb, "%v", "%t") && n.boolFormat: - fname := pass.Fset.File(call.Pos()).Name() - removedFmtUsages[fname]++ - if _, ok := neededPackages[fname]; !ok { - neededPackages[fname] = make(map[string]struct{}) - } - neededPackages[fname]["strconv"] = struct{}{} - d = newAnalysisDiagnostic( - checkerBoolFormat, - call, - fn+" can be replaced with faster strconv.FormatBool", - []analysis.SuggestedFix{ - { - Message: "Use strconv.FormatBool", - TextEdits: []analysis.TextEdit{{ - Pos: call.Pos(), - End: value.Pos(), - NewText: []byte("strconv.FormatBool("), - }}, - }, - }, - ) - - case isArray && isBasicType(a.Elem(), types.Uint8) && oneOf(verb, "%x") && n.hexFormat: - if _, ok := value.(*ast.Ident); !ok { - // Doesn't support array literals. - return - } - - fname := pass.Fset.File(call.Pos()).Name() - removedFmtUsages[fname]++ - if _, ok := neededPackages[fname]; !ok { - neededPackages[fname] = make(map[string]struct{}) - } - neededPackages[fname]["encoding/hex"] = struct{}{} - d = newAnalysisDiagnostic( - checkerHexFormat, - call, - fn+" can be replaced with faster hex.EncodeToString", - []analysis.SuggestedFix{ - { - Message: "Use hex.EncodeToString", - TextEdits: []analysis.TextEdit{ - { - Pos: call.Pos(), - End: value.Pos(), - NewText: []byte("hex.EncodeToString("), - }, - { - Pos: value.End(), - End: value.End(), - NewText: []byte("[:]"), - }, - }, - }, - }, - ) - case isSlice && isBasicType(s.Elem(), types.Uint8) && oneOf(verb, "%x") && n.hexFormat: - fname := pass.Fset.File(call.Pos()).Name() - removedFmtUsages[fname]++ - if _, ok := neededPackages[fname]; !ok { - neededPackages[fname] = make(map[string]struct{}) - } - neededPackages[fname]["encoding/hex"] = struct{}{} - d = newAnalysisDiagnostic( - checkerHexFormat, - call, - fn+" can be replaced with faster hex.EncodeToString", - []analysis.SuggestedFix{ - { - Message: "Use hex.EncodeToString", - TextEdits: []analysis.TextEdit{{ - Pos: call.Pos(), - End: value.Pos(), - NewText: []byte("hex.EncodeToString("), - }}, - }, - }, - ) - - case isBasicType(valueType, types.Int8, types.Int16, types.Int32) && oneOf(verb, "%v", "%d") && n.intFormat.intConv: - fname := pass.Fset.File(call.Pos()).Name() - removedFmtUsages[fname]++ - if _, ok := neededPackages[fname]; !ok { - neededPackages[fname] = make(map[string]struct{}) - } - neededPackages[fname]["strconv"] = struct{}{} - d = newAnalysisDiagnostic( - checkerIntegerFormat, - call, - fn+" can be replaced with faster strconv.Itoa", - []analysis.SuggestedFix{ - { - Message: "Use strconv.Itoa", - TextEdits: []analysis.TextEdit{ - { - Pos: call.Pos(), - End: value.Pos(), - NewText: []byte("strconv.Itoa(int("), - }, - { - Pos: value.End(), - End: value.End(), - NewText: []byte(")"), - }, - }, - }, - }, - ) - case isBasicType(valueType, types.Int) && oneOf(verb, "%v", "%d") && n.intFormat.enabled: - fname := pass.Fset.File(call.Pos()).Name() - removedFmtUsages[fname]++ - if _, ok := neededPackages[fname]; !ok { - neededPackages[fname] = make(map[string]struct{}) - } - neededPackages[fname]["strconv"] = struct{}{} - d = newAnalysisDiagnostic( - checkerIntegerFormat, - call, - fn+" can be replaced with faster strconv.Itoa", - []analysis.SuggestedFix{ - { - Message: "Use strconv.Itoa", - TextEdits: []analysis.TextEdit{{ - Pos: call.Pos(), - End: value.Pos(), - NewText: []byte("strconv.Itoa("), - }}, - }, - }, - ) - case isBasicType(valueType, types.Int64) && oneOf(verb, "%v", "%d") && n.intFormat.enabled: - fname := pass.Fset.File(call.Pos()).Name() - removedFmtUsages[fname]++ - if _, ok := neededPackages[fname]; !ok { - neededPackages[fname] = make(map[string]struct{}) - } - neededPackages[fname]["strconv"] = struct{}{} - d = newAnalysisDiagnostic( - checkerIntegerFormat, - call, - fn+" can be replaced with faster strconv.FormatInt", - []analysis.SuggestedFix{ - { - Message: "Use strconv.FormatInt", - TextEdits: []analysis.TextEdit{ - { - Pos: call.Pos(), - End: value.Pos(), - NewText: []byte("strconv.FormatInt("), - }, - { - Pos: value.End(), - End: value.End(), - NewText: []byte(", 10"), - }, - }, - }, - }, - ) - - case isBasicType(valueType, types.Uint8, types.Uint16, types.Uint32, types.Uint) && oneOf(verb, "%v", "%d", "%x") && n.intFormat.intConv: - base := []byte("), 10") - if verb == "%x" { - base = []byte("), 16") - } - fname := pass.Fset.File(call.Pos()).Name() - removedFmtUsages[fname]++ - if _, ok := neededPackages[fname]; !ok { - neededPackages[fname] = make(map[string]struct{}) - } - neededPackages[fname]["strconv"] = struct{}{} - d = newAnalysisDiagnostic( - checkerIntegerFormat, - call, - fn+" can be replaced with faster strconv.FormatUint", - []analysis.SuggestedFix{ - { - Message: "Use strconv.FormatUint", - TextEdits: []analysis.TextEdit{ - { - Pos: call.Pos(), - End: value.Pos(), - NewText: []byte("strconv.FormatUint(uint64("), - }, - { - Pos: value.End(), - End: value.End(), - NewText: base, - }, - }, - }, - }, - ) - case isBasicType(valueType, types.Uint64) && oneOf(verb, "%v", "%d", "%x") && n.intFormat.enabled: - base := []byte(", 10") - if verb == "%x" { - base = []byte(", 16") - } - fname := pass.Fset.File(call.Pos()).Name() - removedFmtUsages[fname]++ - if _, ok := neededPackages[fname]; !ok { - neededPackages[fname] = make(map[string]struct{}) - } - neededPackages[fname]["strconv"] = struct{}{} - d = newAnalysisDiagnostic( - checkerIntegerFormat, - call, - fn+" can be replaced with faster strconv.FormatUint", - []analysis.SuggestedFix{ - { - Message: "Use strconv.FormatUint", - TextEdits: []analysis.TextEdit{ - { - Pos: call.Pos(), - End: value.Pos(), - NewText: []byte("strconv.FormatUint("), - }, - { - Pos: value.End(), - End: value.End(), - NewText: base, - }, - }, - }, - }, - ) - case isBasicType(valueType, types.String) && fn == "fmt.Sprintf" && isConcatable(verb) && n.strFormat.enabled: - var fix string - if strings.HasSuffix(verb, "%s") { - fix = strings.ReplaceAll(strconv.Quote(verb[:len(verb)-2]), "%%", "%") + "+" + formatNode(pass.Fset, value) - } else if strings.HasSuffix(verb, "%[1]s") { - fix = strings.ReplaceAll(strconv.Quote(verb[:len(verb)-5]), "%%", "%") + "+" + formatNode(pass.Fset, value) - } else if strings.HasPrefix(verb, "%s") { - fix = formatNode(pass.Fset, value) + "+" + strings.ReplaceAll(strconv.Quote(verb[2:]), "%%", "%") - } else { - fix = formatNode(pass.Fset, value) + "+" + strings.ReplaceAll(strconv.Quote(verb[5:]), "%%", "%") - } - fname := pass.Fset.File(call.Pos()).Name() - removedFmtUsages[fname]++ - d = newAnalysisDiagnostic( - checkerStringFormat, - call, - fn+" can be replaced with string concatenation", - []analysis.SuggestedFix{ - { - Message: "Use string concatenation", - TextEdits: []analysis.TextEdit{{ - Pos: call.Pos(), - End: call.End(), - NewText: []byte(fix), - }}, - }, - }, - ) - } - - if d != nil { - pass.Report(*d) - } - }) - - if len(removedFmtUsages) > 0 || len(neededPackages) > 0 { - n.fixImports(pass, neededPackages, removedFmtUsages) - } - - return nil, nil -} - -var errIface = types.Universe.Lookup("error").Type().Underlying().(*types.Interface) - -func isBasicType(lhs types.Type, expected ...types.BasicKind) bool { - for _, rhs := range expected { - if types.Identical(lhs, types.Typ[rhs]) { - return true - } - } - return false -} - -func formatNode(fset *token.FileSet, node ast.Node) string { - buf := new(bytes.Buffer) - if err := format.Node(buf, fset, node); err != nil { - return "" - } - return buf.String() -} - -func oneOf[T comparable](v T, expected ...T) bool { - for _, rhs := range expected { - if v == rhs { - return true - } - } - return false -} diff --git a/vendor/github.com/catenacyber/perfsprint/analyzer/diagnostic.go b/vendor/github.com/catenacyber/perfsprint/analyzer/diagnostic.go deleted file mode 100644 index f1d8d090e5..0000000000 --- a/vendor/github.com/catenacyber/perfsprint/analyzer/diagnostic.go +++ /dev/null @@ -1,24 +0,0 @@ -package analyzer - -import ( - "golang.org/x/tools/go/analysis" -) - -func newAnalysisDiagnostic( - checker string, - analysisRange analysis.Range, - message string, - suggestedFixes []analysis.SuggestedFix, -) *analysis.Diagnostic { - if checker != "" { - message = checker + ": " + message - } - - return &analysis.Diagnostic{ - Pos: analysisRange.Pos(), - End: analysisRange.End(), - SuggestedFixes: suggestedFixes, - Message: message, - Category: checker, // Possible hashtag available on the documentation - } -} diff --git a/vendor/github.com/ccojocar/zxcvbn-go/.gitignore b/vendor/github.com/ccojocar/zxcvbn-go/.gitignore deleted file mode 100644 index e032cc2fcb..0000000000 --- a/vendor/github.com/ccojocar/zxcvbn-go/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -zxcvbn -debug.test - -# SBOMs generated during CI -/bom.json diff --git a/vendor/github.com/ccojocar/zxcvbn-go/.golangci.yml b/vendor/github.com/ccojocar/zxcvbn-go/.golangci.yml deleted file mode 100644 index 765d3b5ea6..0000000000 --- a/vendor/github.com/ccojocar/zxcvbn-go/.golangci.yml +++ /dev/null @@ -1,46 +0,0 @@ -version: "2" -linters: - enable: - - asciicheck - - bodyclose - - dogsled - - durationcheck - - errorlint - - ginkgolinter - - importas - - misspell - - nakedret - - nolintlint - - revive - - unconvert - - unparam - - wastedassign - exclusions: - generated: lax - presets: - - comments - - common-false-positives - - legacy - - std-error-handling - paths: - - third_party$ - - builtin$ - - examples$ -formatters: - enable: - - gci - - gofmt - - gofumpt - - goimports - settings: - gci: - sections: - - standard - - default - - prefix(github.com/ccojocar) - exclusions: - generated: lax - paths: - - third_party$ - - builtin$ - - examples$ diff --git a/vendor/github.com/ccojocar/zxcvbn-go/.goreleaser.yml b/vendor/github.com/ccojocar/zxcvbn-go/.goreleaser.yml deleted file mode 100644 index 2b786c5d84..0000000000 --- a/vendor/github.com/ccojocar/zxcvbn-go/.goreleaser.yml +++ /dev/null @@ -1,27 +0,0 @@ -version: 2 -project_name: zxcvbn-go - -release: - extra_files: - - glob: ./bom.json - github: - owner: ccojocar - name: zxcvbn-go - -builds: - - main: ./testapp/ - binary: zxcvbn-go - goos: - - darwin - - linux - - windows - goarch: - - amd64 - - arm64 - - s390x - ldflags: -X main.Version={{.Version}} -X main.GitTag={{.Tag}} -X main.BuildDate={{.Date}} - env: - - CGO_ENABLED=0 - -gomod: - proxy: true diff --git a/vendor/github.com/ccojocar/zxcvbn-go/LICENSE.txt b/vendor/github.com/ccojocar/zxcvbn-go/LICENSE.txt deleted file mode 100644 index e8f59e06d2..0000000000 --- a/vendor/github.com/ccojocar/zxcvbn-go/LICENSE.txt +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) Nathan Button - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/ccojocar/zxcvbn-go/Makefile b/vendor/github.com/ccojocar/zxcvbn-go/Makefile deleted file mode 100644 index 0690f37538..0000000000 --- a/vendor/github.com/ccojocar/zxcvbn-go/Makefile +++ /dev/null @@ -1,61 +0,0 @@ -GIT_TAG?= $(shell git describe --always --tags) -BIN = zxcvbn-go -FMT_CMD = $(gofmt -s -l -w $(find . -type f -name '*.go' -not -path './vendor/*') | tee /dev/stderr) -IMAGE_REPO = ccojocar -DATE_FMT=+%Y-%m-%d -ifdef SOURCE_DATE_EPOCH - BUILD_DATE ?= $(shell date -u -d "@$(SOURCE_DATE_EPOCH)" "$(DATE_FMT)" 2>/dev/null || date -u -r "$(SOURCE_DATE_EPOCH)" "$(DATE_FMT)" 2>/dev/null || date -u "$(DATE_FMT)") -else - BUILD_DATE ?= $(shell date "$(DATE_FMT)") -endif -BUILDFLAGS := "-w -s -X 'main.Version=$(GIT_TAG)' -X 'main.GitTag=$(GIT_TAG)' -X 'main.BuildDate=$(BUILD_DATE)'" -CGO_ENABLED = 0 -GO := GO111MODULE=on go -GO_NOMOD :=GO111MODULE=off go -GOPATH ?= $(shell $(GO) env GOPATH) -GOBIN ?= $(GOPATH)/bin -GO_MINOR_VERSION = $(shell $(GO) version | cut -c 14- | cut -d' ' -f1 | cut -d'.' -f2) -GOVULN_MIN_VERSION = 17 -GO_VERSION = 1.20 - -default: - $(MAKE) test - -install-govulncheck: - @if [ $(GO_MINOR_VERSION) -gt $(GOVULN_MIN_VERSION) ]; then \ - go install golang.org/x/vuln/cmd/govulncheck@latest; \ - fi - -test-all: fmt vet lint sec govulncheck test - -test: - go test -v ./... - -fmt: - @echo "FORMATTING" - @FORMATTED=`$(GO) fmt ./...` - @([ ! -z "$(FORMATTED)" ] && printf "Fixed unformatted files:\n$(FORMATTED)") || true - -vet: - @echo "VETTING" - $(GO) vet ./... - -lint: - @echo "LINTING: golangci-lint" - golangci-lint run - -sec: - @echo "SECURITY SCANNING" - gosec ./... - -govulncheck: install-govulncheck - @echo "CHECKING VULNERABILITIES" - @if [ $(GO_MINOR_VERSION) -gt $(GOVULN_MIN_VERSION) ]; then \ - govulncheck ./...; \ - fi - -clean: - rm -rf build vendor dist coverage.txt - rm -f release image $(BIN) - -.PHONY: test test-all fmt vet govulncheck clean diff --git a/vendor/github.com/ccojocar/zxcvbn-go/README.md b/vendor/github.com/ccojocar/zxcvbn-go/README.md deleted file mode 100644 index 3f742a9da6..0000000000 --- a/vendor/github.com/ccojocar/zxcvbn-go/README.md +++ /dev/null @@ -1,78 +0,0 @@ -This is a goLang port of python-zxcvbn and [zxcvbn](https://github.com/dropbox/zxcvbn), which are python and JavaScript password strength -generators. zxcvbn attempts to give sound password advice through pattern -matching and conservative entropy calculations. It finds 10k common passwords, -common American names and surnames, common English words, and common patterns -like dates, repeats (aaa), sequences (abcd), and QWERTY patterns. - -Please refer to https://dropbox.tech/security/zxcvbn-realistic-password-strength-estimation for the full details and -motivation behind zxcbvn. The source code for the original JavaScript (well, -actually CoffeeScript) implementation can be found at: - -https://github.com/lowe/zxcvbn - -Python at: - -https://github.com/dropbox/python-zxcvbn - -For full motivation, see: - -https://dropbox.tech/security/zxcvbn-realistic-password-strength-estimation - ------------------------------------------------------------------------- -Use ------------------------------------------------------------------------- - -The zxcvbn module has the public method PasswordStrength() function. Import zxcvbn, and -call PasswordStrength(password string, userInputs []string). The function will return a -result dictionary with the following keys: - -Entropy # bits - -CrackTime # estimation of actual crack time, in seconds. - -CrackTimeDisplay # same crack time, as a friendlier string: - # "instant", "6 minutes", "centuries", etc. - -Score # [0,1,2,3,4] if crack time is less than - # [10^2, 10^4, 10^6, 10^8, Infinity]. - # (useful for implementing a strength bar.) - -MatchSequence # the list of patterns that zxcvbn based the - # entropy calculation on. - -CalcTime # how long it took to calculate an answer, - # in milliseconds. usually only a few ms. - -The userInputs argument is an splice of strings that zxcvbn -will add to its internal dictionary. This can be whatever list of -strings you like, but is meant for user inputs from other fields of the -form, like name and email. That way a password that includes the user's -personal info can be heavily penalized. This list is also good for -site-specific vocabulary. - -Bug reports and pull requests welcome! - ------------------------------------------------------------------------- -Project Status ------------------------------------------------------------------------- - -Use zxcvbn_test.go to check how close to feature parity the project is. - ------------------------------------------------------------------------- -Acknowledgment ------------------------------------------------------------------------- - -Thanks to Dan Wheeler (https://github.com/lowe) for the CoffeeScript implementation -(see above.) To repeat his outside acknowledgements (which remain useful, as always): - -Many thanks to Mark Burnett for releasing his 10k top passwords list: -https://xato.net/passwords/more-top-worst-passwords -and for his 2006 book, -"Perfect Passwords: Selection, Protection, Authentication" - -Huge thanks to Wiktionary contributors for building a frequency list -of English as used in television and movies: -https://en.wiktionary.org/wiki/Wiktionary:Frequency_lists - -Last but not least, big thanks to xkcd :) -https://xkcd.com/936/ diff --git a/vendor/github.com/ccojocar/zxcvbn-go/adjacency/adjcmartix.go b/vendor/github.com/ccojocar/zxcvbn-go/adjacency/adjcmartix.go deleted file mode 100644 index 34526685cc..0000000000 --- a/vendor/github.com/ccojocar/zxcvbn-go/adjacency/adjcmartix.go +++ /dev/null @@ -1,105 +0,0 @@ -package adjacency - -import ( - "encoding/json" - "log" - - "github.com/ccojocar/zxcvbn-go/data" -) - -// Graph holds information about different graphs -type Graph struct { - Graph map[string][]string - averageDegree float64 - Name string -} - -// GraphMap is a map of all graphs -var GraphMap = make(map[string]Graph) - -func init() { - GraphMap["qwerty"] = BuildQwerty() - GraphMap["dvorak"] = BuildDvorak() - GraphMap["keypad"] = BuildKeypad() - GraphMap["macKeypad"] = BuildMacKeypad() - GraphMap["l33t"] = BuildLeet() -} - -// BuildQwerty builds the Qwerty Graph -func BuildQwerty() Graph { - data, err := data.Asset("data/Qwerty.json") - if err != nil { - panic("Can't find asset") - } - return getAdjancencyGraphFromFile(data, "qwerty") -} - -// BuildDvorak builds the Dvorak Graph -func BuildDvorak() Graph { - data, err := data.Asset("data/Dvorak.json") - if err != nil { - panic("Can't find asset") - } - return getAdjancencyGraphFromFile(data, "dvorak") -} - -// BuildKeypad builds the Keypad Graph -func BuildKeypad() Graph { - data, err := data.Asset("data/Keypad.json") - if err != nil { - panic("Can't find asset") - } - return getAdjancencyGraphFromFile(data, "keypad") -} - -// BuildMacKeypad builds the Mac Keypad Graph -func BuildMacKeypad() Graph { - data, err := data.Asset("data/MacKeypad.json") - if err != nil { - panic("Can't find asset") - } - return getAdjancencyGraphFromFile(data, "mac_keypad") -} - -// BuildLeet builds the L33T Graph -func BuildLeet() Graph { - data, err := data.Asset("data/L33t.json") - if err != nil { - panic("Can't find asset") - } - return getAdjancencyGraphFromFile(data, "keypad") -} - -func getAdjancencyGraphFromFile(data []byte, name string) Graph { - var graph Graph - err := json.Unmarshal(data, &graph) - if err != nil { - log.Fatal(err) - } - graph.Name = name - return graph -} - -// CalculateAvgDegree calclates the average degree between nodes in the graph -// on qwerty, 'g' has degree 6, being adjacent to 'ftyhbv'. '\' has degree 1. -// this calculates the average over all keys. -// TODO double check that i ported this correctly scoring.coffee ln 5 -func (adjGrp Graph) CalculateAvgDegree() float64 { - if adjGrp.averageDegree != float64(0) { - return adjGrp.averageDegree - } - var avg float64 - var count float64 - for _, value := range adjGrp.Graph { - for _, char := range value { - if len(char) != 0 || char != " " { - avg += float64(len(char)) - count++ - } - } - } - - adjGrp.averageDegree = avg / count - - return adjGrp.averageDegree -} diff --git a/vendor/github.com/ccojocar/zxcvbn-go/data/bindata.go b/vendor/github.com/ccojocar/zxcvbn-go/data/bindata.go deleted file mode 100644 index 3db0f1b100..0000000000 --- a/vendor/github.com/ccojocar/zxcvbn-go/data/bindata.go +++ /dev/null @@ -1,446 +0,0 @@ -// Code generated by go-bindata. -// sources: -// data/Dvorak.json -// data/English.json -// data/FemaleNames.json -// data/Keypad.json -// data/L33t.json -// data/MacKeypad.json -// data/MaleNames.json -// data/Passwords.json -// data/Qwerty.json -// data/Surnames.json -// DO NOT EDIT! - -package data - -import ( - "bytes" - "compress/gzip" - "fmt" - "io" - "io/ioutil" - "os" - "path/filepath" - "strings" - "time" -) - -func bindataRead(data []byte, name string) ([]byte, error) { - gz, err := gzip.NewReader(bytes.NewBuffer(data)) - if err != nil { - return nil, fmt.Errorf("Read %q: %v", name, err) - } - - var buf bytes.Buffer - _, err = io.Copy(&buf, gz) // #nosec - clErr := gz.Close() - - if err != nil { - return nil, fmt.Errorf("Read %q: %v", name, err) - } - if clErr != nil { - return nil, err - } - - return buf.Bytes(), nil -} - -type asset struct { - bytes []byte - info os.FileInfo -} - -type bindataFileInfo struct { - name string - size int64 - mode os.FileMode - modTime time.Time -} - -func (fi bindataFileInfo) Name() string { - return fi.name -} -func (fi bindataFileInfo) Size() int64 { - return fi.size -} -func (fi bindataFileInfo) Mode() os.FileMode { - return fi.mode -} -func (fi bindataFileInfo) ModTime() time.Time { - return fi.modTime -} -func (fi bindataFileInfo) IsDir() bool { - return false -} -func (fi bindataFileInfo) Sys() interface{} { - return nil -} - -var _dataDvorakJson = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xb4\x98\x57\x57\x1b\x41\x0c\x85\xdf\xf9\x15\xb0\x74\x30\xbd\xf7\xde\x7b\x6f\xa6\x77\x30\xbd\x17\xf3\xdb\x33\x26\x39\x99\xef\x9e\x78\x96\x7d\x88\x5e\x72\xc6\x61\xf9\xa4\x95\xae\x34\xd7\x7c\x14\x14\x16\x46\x63\xf7\xfb\xb7\x67\x51\x67\x61\xee\x83\xfb\x58\xef\x8e\x5b\xdf\x47\xf7\xa1\xa3\x22\x4a\xfd\x39\x5f\x3f\x65\x32\xf9\xce\xd1\xd6\xc7\xdf\x67\xa2\xcc\xb4\x3f\xdf\x2f\x46\xdf\xc7\xed\xdf\xff\x13\x35\x10\xbc\xf7\xf5\x33\xb8\xb1\xdf\xc3\xca\xd3\x91\xfc\x82\x90\x1b\x49\x6e\x28\xfa\x99\xdc\x54\xec\xc9\xa9\x6e\x8d\x22\xe4\x26\x92\x91\x4f\x90\xdc\x5c\xe2\x69\xb5\xbd\x12\x45\xc0\xcd\x04\x23\x9d\x20\xb8\xa5\xd4\xc3\x6e\xe7\x25\x88\x80\x5b\x08\x46\x36\x41\x70\xeb\x8e\x87\xbd\x6d\x48\x10\x01\xb7\x12\x8c\x6c\x82\xe0\xb6\x32\x0f\x3b\x19\x95\x20\x02\x6e\x23\x18\xd9\x04\xc1\xed\x55\x1e\x76\x3a\x26\x41\x04\xdc\x4e\x30\xb2\x09\x82\xa1\xf6\xe8\x70\x48\x82\x08\xb8\x83\x60\x64\x13\x04\xd7\x57\xca\x58\x30\x88\x80\x8b\xcc\x46\xc4\xfd\xcc\xa3\x05\x81\x79\x11\x1c\xe7\x62\x7f\x20\x4c\x2e\xb6\x1a\x91\x12\xab\x11\x29\xb5\x1a\x91\x32\x2b\x25\x97\x5b\x35\xaf\xc2\x4a\xc9\x95\x56\xb7\x48\x95\xd5\x50\x57\x13\x5c\xd7\xe7\x1f\xdc\xce\xe6\x0d\x12\xa5\xd3\x9f\xf9\x7f\x50\xb3\xab\xe4\x14\xc9\x9c\x52\x69\x19\xef\x24\x8e\xc5\xcd\x9c\xb4\x52\xc8\x35\x24\x3f\x2c\xf9\x07\x99\x7f\x4f\xf5\xcf\x45\x7a\xdf\x54\x70\x2d\xc1\x14\x13\xb3\xe4\x20\x73\xde\x8e\x47\x24\x7b\x01\xd7\x11\xcc\x3e\xb3\xff\xa8\x38\xb3\xcf\x15\x36\x85\xb7\x15\x70\x67\x68\x44\x20\x7f\xa9\xe5\xdd\x42\xb0\x2c\x02\xee\xb2\x02\x77\x9b\xc9\xa2\xc7\x4c\xca\xbd\x56\xba\xe8\xb3\xd2\x45\xbf\x99\x37\x1c\x08\x09\x43\x7a\x49\x04\x7b\xd6\xd5\x19\xde\xca\x83\xcc\xf9\x75\xdd\xff\xd2\xd1\xb0\x3f\x9f\x8d\xfb\xf3\xd5\x4c\x32\xc9\x0d\x11\xcc\x0b\x87\x17\x11\x17\x26\x57\xfc\xe3\xb2\x04\x17\xf0\x30\xc1\xe7\x13\xf9\x8d\x1f\x03\x32\xfb\x83\x41\x7f\x76\x6f\x2b\xe0\x11\x82\x59\x3f\xce\x02\x45\xf6\xb4\xe2\xcf\x17\x93\x32\x95\x02\x1e\x25\x98\x97\x3a\x2f\x7b\x5a\x58\x66\xcf\x3e\xb8\xb7\x15\xf0\x18\xc1\x7c\x7d\xc2\x58\x6f\x5e\x4a\x2c\x8b\x0b\x22\xe0\x71\x82\x99\x01\x33\x23\x8c\x0d\x83\x42\x72\xf5\x16\xf0\x04\xc1\xac\x1f\xcb\xc2\x37\x61\x70\xca\xf3\x72\x4a\xc1\x93\x04\x63\x2d\xca\x26\x60\x40\x07\x48\xa4\xe3\x29\x82\xd9\x65\xc2\x28\x43\x64\x19\x0b\x9e\x26\x98\xe2\xa7\xef\xe1\x4a\xe2\x76\xe5\x05\x7c\x3d\xab\xa5\x98\x21\x98\x82\x67\xc7\xd9\xb0\x97\xb5\x64\x19\xcf\x12\x4c\x00\xb3\xe7\x42\x65\x96\xcf\xab\x12\x50\xc0\x73\x04\xf3\xae\xe3\x46\xe3\x14\xb2\xa9\x6c\xb6\xdb\x74\x02\x9e\x27\x98\x00\xde\x1b\xf4\xf2\x94\x21\x1b\xec\x02\x0a\x78\x81\x60\xec\x57\xd9\x1b\xcc\x12\xca\x89\xad\xf1\x22\xc1\x9c\x30\xae\x4a\x2a\x84\xf5\x76\x4a\x60\x83\x05\xbc\x44\x30\x1f\x24\x80\x12\xe3\x4d\xe7\x3c\x1b\x1b\x29\xe0\x65\x82\x29\x31\x66\x4f\x85\x30\x38\xa4\x97\xdb\x1b\x02\x5e\x21\x98\xb5\xe4\x0e\x66\xc3\x38\x85\x18\xef\x5c\xed\x05\xbc\x4a\x30\x33\x60\x66\xd4\x2e\x5e\x3f\xb6\x79\x6b\x04\x73\x0d\x72\x58\x18\x04\x43\x11\x0b\x5e\x27\x98\xaf\xc6\x57\xe6\xaa\xc4\xd8\xc7\x82\x37\x08\x66\x5d\x39\x14\xbc\xa6\xb8\x9b\x19\xdc\x0d\x8b\x80\x37\x09\xe6\xec\xb3\xae\x90\x58\xc8\x23\xfd\x93\xf1\x16\xc1\x18\x84\xa0\xc9\xa2\x93\xa3\xbe\x9d\xee\x05\x9c\x4e\x93\x9c\xe0\x9b\x4c\xe2\x94\xb7\x09\xc6\x46\x4f\x02\x13\xf3\xe9\xd2\x17\xf0\x8e\xd5\xdf\xc9\x76\xad\xbe\xec\xed\x05\x8c\x6c\x10\x10\x63\xa3\x05\xbc\x6f\xe6\x90\x0f\xac\x1c\xf2\xa1\x95\x43\x3e\xb2\x72\xc8\xc7\x56\x0e\xf9\xc4\xca\x21\x9f\x5a\x39\xe4\x33\x2b\x87\x7c\x6e\xe5\x90\x2f\xac\x1c\xf2\xa5\x95\x43\xce\x58\x39\xe4\x2b\x2b\x87\x7c\x6d\xe5\x90\x6f\xac\x1c\xf2\xad\x95\x43\xbe\xb3\x72\xc8\xf7\x56\x0e\xf9\xc1\xca\x21\x3f\x5a\x39\xe4\x27\x2b\x87\xfc\x6c\xe5\x90\x5f\xac\x1c\xf2\xab\x95\x43\x7e\xb3\x72\xc8\xef\x56\x0e\xf9\xc3\xca\x21\x7f\x5a\x19\xe4\xac\x95\x41\xfe\xfa\xef\x76\xd3\xfd\x9b\x2d\xc8\x16\xfc\x0a\x00\x00\xff\xff\xd5\xc4\xca\x21\xce\x20\x00\x00") - -func dataDvorakJsonBytes() ([]byte, error) { - return bindataRead( - _dataDvorakJson, - "data/Dvorak.json", - ) -} - -func dataDvorakJson() (*asset, error) { - bytes, err := dataDvorakJsonBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "data/Dvorak.json", size: 8398, mode: os.FileMode(420), modTime: time.Unix(1452717629, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _dataEnglishJson = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x5c\xbd\x4b\x9a\xe3\xca\x0e\x34\xb6\x15\x7f\x9a\xf4\xe4\xae\xc0\x6b\xf0\x0e\x3c\x4a\x92\x29\x31\x4b\x24\x93\x87\x0f\xa9\xd4\xde\xbc\x81\x88\x40\x52\xfd\x0f\xee\xed\xea\x3e\x55\x2a\x32\x1f\x78\x04\x02\x81\xff\xef\xf6\xff\x94\xfd\xb8\xfd\xdf\xff\xef\xff\x75\xfb\xd4\xf3\xf6\xbf\x5b\xb1\xff\x1d\xd5\xff\x6f\xcc\xf6\xff\xc9\xff\xb7\x0c\xf8\x7b\x3a\xfc\xbf\xfb\xff\xd5\xbb\xfd\xdf\xec\xff\xfd\xad\x7f\xdd\xfd\xff\x16\x7c\x1b\xbe\x7e\x2e\xf5\xed\xff\xf4\x67\xb6\xff\xbf\xd7\xcd\xfe\x7f\xf1\x4f\x1d\xd3\xcb\x7f\x6c\xfe\xd8\xff\x0d\x75\xf9\xe3\x3f\xfc\x73\xee\x07\xfe\xfb\x81\x7f\xb4\xff\xeb\xfc\x7b\xaa\x7f\x9c\x3d\x94\xff\xec\x3b\xf9\x87\xbe\x33\x1e\xe0\x0f\xbe\x2e\xc7\x68\x7f\xec\xf8\xf6\xd3\x7f\x32\x4d\x13\xbe\x07\x7f\xa4\xcd\xbf\x17\xaf\x50\xfd\xfb\x52\x57\xf1\x4d\x5b\x79\x8c\x07\x3f\xf7\x0f\xbe\xe5\x91\x0f\x7c\x23\xfe\xc2\xef\x79\xd4\xb2\x3c\xec\xcf\xa9\x3c\xfd\x1f\x3f\x39\xf9\x27\x94\x3b\xbf\xcf\x7f\x29\x3e\xb7\x4f\xfe\x80\xe7\x8a\xc7\x5b\x0e\xbe\xfb\xf2\xd4\x52\xe1\x21\xb9\x08\x0f\xbc\x78\xf1\x95\xc0\x62\x8d\xfa\x57\xfe\x88\x7e\xf3\xe2\xff\x3f\x94\x01\x6b\xea\xab\xb3\x67\xfc\x92\x8a\x65\x7e\xd4\xca\x3d\xc8\xfe\x9f\xb6\x6c\xef\xea\x5f\x70\x55\xea\x39\xf9\x7f\x9c\x6a\x7d\xe2\xa7\x33\xf6\xa1\x70\x7f\x0a\x96\xa3\x3e\x93\x7f\x7f\x97\xfa\x27\x9f\x1c\x0b\x3f\x67\xbc\xc2\xc1\x25\x2b\x7f\xf0\xc7\x7d\xab\x33\xde\xf4\x83\xd5\xd4\x3a\xe2\x75\x7a\xfd\x26\x7b\x4c\x7e\xc0\x27\xef\x78\xb5\x1d\x7b\x86\xdf\x8b\xad\xde\xed\xa9\x7d\x31\x1e\x78\x1e\xee\x68\x9f\xce\x3d\xeb\xbf\xe1\x20\xe8\x85\xfc\x87\x76\x3c\x1d\x1e\xff\x48\x58\x74\x3c\xd8\x1b\xff\x7c\xee\xd8\x8b\xe3\x98\x70\x72\xf8\xdf\x97\x9c\x07\xac\xcb\xb2\x24\xfc\xf5\x85\x9d\x79\x67\xee\xea\x51\x2b\xf7\x09\xcf\x5d\xfe\xe0\xd0\xed\x27\xff\xdb\x98\xfd\x05\xe7\xca\x85\xe7\x0f\xf2\x98\xed\x75\xdb\x3e\x5c\xc3\x2d\x4e\x37\x3e\x61\xca\xb1\xbf\xfe\x4a\x09\x3f\x9f\x3e\x38\xa6\x43\x7d\x2f\xf8\xeb\x82\xb7\xf2\xef\x3e\xfd\xbc\xd8\xe7\x62\xc9\x3f\xb1\xcb\xf8\xa0\x7d\xd4\x1a\xa6\xe5\x13\x1f\xb7\x27\x6c\xfb\x7c\xf6\x23\xff\x03\xde\xf7\xee\x1f\x6e\xaf\x85\x45\xbd\xdf\xf1\x9b\xf8\xfd\x76\xbc\x70\xcc\x1e\xe5\xc5\xa3\x33\xf1\x77\xd4\x93\x67\x7b\xcc\x93\x1f\xca\xe3\x8d\x6b\x9c\x26\xff\xde\x35\xd7\x75\xe2\x49\xf2\xdf\xb5\x1f\x3c\x17\xef\x84\xfb\x5c\x16\x5c\xf9\x7b\xc1\x4d\xb7\x8b\x18\x2f\xfa\x48\x71\xa9\x97\x87\xd6\x01\xaf\x31\xd4\xbc\xf3\x08\xf4\xbc\x76\x47\xc5\x5b\x3d\xec\x68\x1e\xd8\xee\x3b\x97\xb7\xcb\xc7\x81\x05\xd6\x06\x2d\xba\x7f\xfe\x0e\xfe\x0b\xb8\xc5\xf7\xb2\xed\xfc\xb1\xa9\x64\xbe\xd4\xc1\xab\x76\xcf\x79\xd2\x4f\xb7\xf5\x7a\xd7\xcd\x5f\xc9\xaf\x30\xbe\xd7\x1e\x1b\x27\x8a\x07\x2b\xdd\xf9\x0b\xa7\xb4\xeb\x82\xe1\xd8\x0d\xf8\x45\xcf\x9c\x57\x3d\xbe\x2f\x0a\xed\xc6\x56\xcf\x85\x8b\x52\x57\x5d\x32\x9e\xa2\xf2\x07\xef\x74\xfa\x4f\x16\xbd\x6f\x9a\xec\x91\x79\x22\xf7\x23\xf3\x94\x2e\x07\x0e\xe3\xbc\xf1\xbb\x71\x27\x70\x06\x6c\x4f\xf0\xcb\xbb\x02\x7b\x82\x1b\x3f\xa6\x75\xcd\x4b\x1e\x62\x23\x79\x85\xf9\xe1\xc7\xf6\xe1\x2b\x3e\xb9\x13\xef\xad\x6a\xc7\x37\xdf\x5c\x6d\x27\xbf\x65\x4e\x03\x2f\xc2\x1b\x0b\xc7\x7f\x7c\x9c\x79\xe7\x95\xc4\xd6\x70\x0b\x70\xd3\x66\xdc\xea\x2d\xcf\x79\xee\xb0\x3e\x66\xf8\x0e\xad\x67\xfe\xa3\x3d\xb4\x7f\xe3\xb2\x0f\xf8\x99\x29\xd3\x5a\xaf\x53\xea\xfd\x4f\x5b\xa6\x6c\x1b\x45\x7f\x00\xb3\xa3\x35\xe9\x8f\x53\x16\x69\xcc\x69\xc3\xef\xc4\xb9\x5f\x0a\x7e\xee\x9e\xf4\xb1\x79\xa2\x09\x38\x92\xec\x3f\x2e\x59\xd2\xd2\xda\x37\x15\xff\x2e\x33\x33\x1b\xbe\x6f\xd6\x61\x99\xb9\x1a\x59\x57\x2a\x2f\xb1\x18\x1b\x7f\x25\x9e\xbe\x4f\x73\x98\x17\x7e\xae\x9f\x0f\x1a\x3f\x5c\xd0\x7b\x9a\xcb\xc4\xcb\x5d\x27\x9a\x98\x38\x64\x76\x73\x76\xfd\x84\xfd\xe2\xc9\xef\x5a\x19\x32\x5c\xdf\xfe\xc4\xea\xe2\x28\xcd\xf4\x53\x66\x92\xb9\x6e\xb5\x99\xdd\x38\x97\x34\x02\xef\xb1\xe0\x26\x9b\xe3\xd8\x7c\x33\xb6\x8a\xb5\x9f\xf2\xdd\x7f\xfc\xc9\x1d\x3b\x6a\x5c\x05\xb7\xe6\x78\x70\x18\x90\xba\x62\x57\xf5\x32\xfc\xe3\x9d\xe1\x5e\x4e\xd8\xe5\x79\xd6\x21\xf2\x77\x59\x37\xdb\x45\x78\x8b\x04\x9f\x52\x36\x7c\x54\xa1\x97\x82\x9f\xb9\x6f\x25\x63\xf9\xd2\x64\xbf\x69\xe0\x37\xeb\x98\x2d\xf9\x97\x0b\xbf\xc1\xd9\xfc\xd4\x0e\x9f\x59\xbb\x89\x26\xb2\x2c\xe7\x81\x0d\xd4\x0d\xb1\x9b\x37\xf1\xe0\x9a\xa3\xe3\x47\xb8\x43\xe7\xf6\xf9\xd6\x0f\x78\x85\x05\xbe\x63\x4e\xba\xfa\xf3\x47\x8b\xda\x5f\x47\x26\xff\xda\xa1\xe1\x89\x49\x2f\x19\x9b\x51\xbf\x3c\x75\xfa\x0f\x7e\x51\x78\x3e\x71\x0c\xc7\x73\x83\x91\xa8\xb0\xab\x15\xfe\xdf\xd6\x1a\x9b\x69\xdb\x45\x7f\x70\x1c\xd8\xb7\x89\x67\x60\x2f\x0b\x4e\x60\xfe\xed\xcf\x38\x7a\xf8\x90\x27\xed\xdf\xc8\x47\xf6\xa3\x82\xf7\xaa\x34\x13\x3d\x0e\x71\x2c\xd7\xb9\x98\xb5\xbc\x31\xe4\x60\x84\xe0\x57\x1e\xd7\x8c\x47\xc0\xfe\x0a\x2f\xf4\x81\x97\xd8\xe9\x08\x07\x6e\xeb\x41\xaf\x5c\xf9\x1c\x0f\x3e\x96\x1b\x4d\x9a\x8c\xba\x2d\x72\x02\xe7\xba\x9a\xb1\x18\xda\x8e\xed\x5c\x52\x1a\xa6\x13\x0e\x60\xae\x38\x80\x27\xbf\xed\x2d\x67\xb5\xe7\xbe\x62\x77\x56\xbe\xda\x44\xb7\x70\x6c\x27\x23\xa4\x7e\xac\x15\x8e\x9d\x97\xd8\x0c\x33\x63\x1e\xfb\x06\x98\x87\xd3\x16\x89\x56\x23\x27\x9c\xdb\xcb\x53\xe3\x48\x7a\x28\xe7\xff\xf5\xce\x73\x6b\xb7\x4d\xc7\x9d\x2e\xca\xae\x13\x5c\x02\x7f\xa6\x37\x93\x86\x5f\xb3\x9d\xf0\x8a\xf5\xc5\xab\xf6\xe1\x8b\xaf\x66\x3f\xf0\xa1\xdd\x27\x2e\x6b\x57\xb1\xc8\xc3\xa6\x23\x84\x25\xa4\x2b\x9c\x0b\x1e\x6b\x4e\x9b\xad\x08\xde\xd0\x3c\x20\x5e\x31\xe9\x64\xa5\x30\x86\x19\xaf\x64\xbf\x87\x0e\x65\xa6\x17\x5d\x47\xfe\x5a\xdb\x49\xfe\xda\x21\xcd\x0b\xee\x2c\x16\xd2\xaf\x2e\x42\x97\x8d\x9f\xd2\x27\xbc\xc3\x71\x6e\x38\x76\x65\x87\x91\xa9\xb6\x49\x1b\xae\xd2\xb3\x60\x57\x6c\xe1\x68\x08\xc6\xcc\x70\xca\xde\xf9\x81\x53\x86\x6d\xf0\x87\xe3\xb3\x28\xc4\xb8\x73\x43\xcc\x9a\xd2\x23\xd1\x1e\x99\x71\xd6\xbd\x49\xdc\x4c\xbd\xca\x87\x16\xd4\xe3\x1c\xfc\xb2\xeb\x15\xd3\xc2\x87\x0d\xb3\x65\x66\x99\xf7\x84\xbf\x0f\x61\xe6\x4e\xe7\xd4\xe5\x74\x1e\xe5\x7e\xfa\xbe\x3f\x68\xc4\x6d\xfb\xf1\xd0\x5b\xfa\xfb\xd1\x61\xc1\xe9\x61\x40\xcf\x9b\x96\xee\x1b\x63\x11\x73\xdb\x6f\x1e\xe3\x32\xaf\x75\x3b\x18\xdf\x6e\xb4\x83\x77\x6c\xed\xb3\xe8\x10\xf2\x06\x1c\xd8\xb1\xc7\x94\x9a\xa5\x56\x48\xcb\x07\xda\xdd\x5b\xe2\xbd\x60\x53\xf6\xf8\x26\xed\x7e\x57\x68\x59\x4f\x06\x29\x76\xa6\x7c\x51\x72\xd1\x9b\xce\x1b\x0f\x60\xd6\xd1\x1b\x92\x87\x3a\x8c\xf8\x18\x4c\x67\xdc\x47\x33\xd7\x38\x27\x70\x54\x58\xab\x9c\x10\xfd\x58\x4c\x5b\x18\x06\x54\x06\xa8\x38\x2e\xfd\x44\xf7\x3c\xd2\xa3\xd9\xfe\xf8\xb3\xfc\x67\x3e\xf4\x28\x38\x2e\x87\xce\xdd\x3d\x31\x09\x41\x28\xe5\xa1\xe7\xce\x37\x61\x38\x19\xde\xc8\x22\x6e\xc4\x46\xe5\x7e\xb7\x70\x6f\x09\x33\x93\x69\x14\xf7\xb5\x98\xf3\xe6\xc1\xd0\x5b\x9b\x45\x96\x0f\x78\xe7\x61\x90\x1d\x18\x19\x94\x74\x34\x6b\x45\xb7\xe6\x9e\xb1\x7b\xe1\x7c\x3d\x2d\xa0\x9f\xe7\xbf\x56\x58\x82\x8f\x2f\x1a\xfc\x83\xc7\x75\x5a\xaa\xb2\x2c\x58\x0b\xc4\x72\xb1\x7f\xb8\x1d\xe3\xb9\x77\x49\xae\x41\xa6\x65\xc5\x89\xb2\x83\xf6\x66\xf4\xc5\xb0\xd8\xc2\x4f\x3a\xf2\xcc\x80\xdf\x3c\x18\xd2\x01\xb3\xbd\x30\x4f\xe3\x65\xd7\xc7\x04\x4b\xbf\x97\xa1\x39\xd4\x1b\x82\x0f\xae\xc7\x3e\x31\x00\xdb\x68\xd8\xde\x57\x5c\xec\x76\x99\x26\x91\x19\x81\x7b\x1c\xfc\x87\xca\x87\x5d\x0b\xee\x1a\x32\x0b\x2d\x34\x7c\x54\x97\xf9\x02\x48\x04\x07\x5e\x85\x89\x3b\x63\xf7\x83\x2e\x95\x0f\xf1\xb5\xd9\xf8\xe0\xbc\x95\x7a\xf2\xb2\x8c\x0c\x30\x6c\x7d\xf8\xdc\x63\xc1\x8e\x26\xd9\x5f\xbb\x0a\xc8\xac\xaa\x1f\x2b\x5e\xaa\xbb\x36\x6e\xe5\x9d\xee\xb1\x69\xff\x9d\x05\xbf\x7f\x39\x15\x63\x8d\x8a\xac\x76\x3e\xbc\xa5\xae\x13\x6f\x24\xdc\x3a\x43\xe5\xa5\xea\x34\x3c\x18\x94\xba\xeb\x62\x56\xc0\xa4\x25\xe7\x19\x87\xbf\x2c\x0a\xb1\xdc\xbe\x33\x68\x0c\xb3\x78\xae\x3a\xcf\x69\xc3\x77\xcc\x99\x7e\x12\x9e\xa7\xdb\x22\x2f\xf0\x8f\xc2\x12\xd2\xc6\xa6\x3b\xd7\x4a\xee\x17\xbb\xb9\xc9\xe1\x86\x6d\xf2\x08\x90\xff\xd9\xd2\x42\xee\xe0\x58\x69\x3a\x5f\x5c\xf8\x5d\xe6\xc9\xec\xbd\x3c\x59\x3f\xd1\x82\xd9\x12\x31\xe1\xe2\x4f\xdc\xf3\x84\x9f\x2f\xbf\x58\x36\xbf\x20\xb8\x2d\x1b\x73\xe6\xd4\xed\x75\x32\xcb\x40\xd7\x5f\xdf\x4c\x33\xd2\xa0\x8b\x52\xb4\x18\x0b\x03\xc3\x4c\x83\xc4\x10\x01\xbb\xb9\xe6\xbe\xe0\x7a\x75\x7c\xf9\x89\x19\xb3\x9d\xf9\x3f\xbc\x88\x71\xc1\x26\x5c\x29\xdb\xc5\xe9\x46\xbf\xa1\x7b\xc2\x87\xb6\x35\xd2\x3d\x54\xc8\x73\x4f\xe7\x44\x97\x4f\x7b\xa3\x98\xbf\xf2\x98\x76\xc8\x0d\x66\x5b\x9a\x71\xd7\x51\xe3\xc3\xc0\xec\x4c\x8c\x1f\x7e\x72\xe4\x50\x4f\x5e\x9b\xcd\x8c\xe1\x8c\x4c\x51\x5b\x6f\x46\x54\x59\xe8\x11\x27\x30\xe1\x29\x2c\x24\xd8\x0b\x4d\x81\x6d\xf7\x2e\x44\x60\xa5\x77\x33\x93\xa6\x6c\xb9\x02\xe3\xf0\x93\x8d\x6f\xb5\xdf\x4f\xc8\xa6\x1e\x3a\x33\x8f\xb6\xcb\xf6\xa8\x1b\xc2\x81\x76\xf5\xe0\x5e\xd3\x43\x7e\x72\x2a\x7f\x71\x77\xcc\xd6\xdb\x93\x30\xee\x5c\x26\xc6\x07\x7b\xfe\xe5\x26\x20\x4b\x34\x33\xc8\x2c\xc6\x9e\x01\xbe\x95\x87\x71\xf7\xb4\x63\xe0\x8d\x3d\x94\x71\x9b\xe1\xd4\x69\x61\x6e\xb4\x0c\xfc\x16\x7a\x4e\x19\x34\x33\xfd\xda\xfe\xfc\x6b\x57\x17\x89\xa7\xbb\x38\x3d\x78\x36\x2f\x54\x98\xea\xee\xe5\x81\xc5\xaf\x70\x2d\x5b\x36\x8f\x6b\xf6\x7a\x1f\xcb\xaa\x93\x89\xdf\x92\x10\x05\x4f\xf1\xf3\x63\xa5\x0d\xf3\x18\x41\xe9\xfd\xfd\xd4\x03\xbe\x2d\xf1\x80\xeb\x3e\x69\x64\xe2\xde\x7a\x24\x80\xc7\xf3\x18\x08\x9b\x58\x19\x99\x3c\x19\x99\x98\x33\x85\xa5\x09\x97\xe1\xff\x56\xbb\x97\xdb\x15\xa6\x1a\x55\x8e\x68\xe5\xeb\x78\xdc\x17\xc7\x6b\xce\xf1\x18\x9e\xdd\xb9\x13\xdb\x0f\xf3\xbe\xbc\xaa\x3d\x03\xcb\x3b\xad\x8b\x3b\x59\xd8\x00\x9e\xe9\x45\x9e\x75\xe3\xa5\x90\x5b\x44\xb0\xe0\xa9\x2b\x13\x7b\x8b\x27\x68\x4e\x13\xa3\xc4\x49\x9f\x3c\x6c\x48\x72\x7b\x0b\x59\x2b\x8d\x02\xf6\xb8\x2f\x07\xa3\xb0\x0c\x70\xc3\x1c\xe6\x41\x8f\x73\x78\xf2\x81\x98\x78\xe2\xee\xed\xe7\xb6\x6e\x74\xa6\x05\x37\xd8\x7c\x85\xa7\x8d\x8c\xdc\x56\xfa\x57\x8f\xac\xf4\xeb\xe1\x59\x7f\xfb\xbc\x02\x5a\x43\xe8\xf0\xf9\x23\x78\x70\x50\xb0\x78\x28\xd8\xb1\xeb\xbc\xf9\x3d\x86\x15\xcd\xba\xd3\xda\x72\x4b\x31\xe5\x95\x3b\x1c\x4d\x26\xf0\x8c\xe2\xcb\xac\x0c\x63\x8c\x5c\x92\xc1\x8e\xad\x02\x63\x60\x5b\xe9\x32\x10\x71\x98\xd3\x5f\xc1\x28\x58\x08\x07\x51\x16\x9e\x39\xbe\xf0\x16\xc9\x6a\x59\x5e\x75\xa2\x95\xb3\x57\x84\x75\x58\x4b\xee\x15\x33\x63\x4d\x91\x74\x0d\xf6\x94\xbc\x09\x34\x47\x0a\xd7\xea\xab\xf0\x68\x21\xb3\xe8\x15\x20\x59\x88\xb3\x30\x6d\xd5\x9d\x32\xdf\x6e\x3f\x46\x17\x08\xd7\x78\x17\x8e\xe9\x3f\x20\x30\x80\x6b\x37\x98\x75\x97\xad\xaa\x8c\xbf\xf1\x3e\x85\x19\xec\x82\x75\x67\x7c\x9d\x26\x3d\x00\xdf\x93\xa9\x4e\x1a\x66\x04\x0b\x4a\xef\x70\xf3\x4f\xd9\x9d\x91\x0f\x99\x5f\xc8\x73\x86\x6c\xce\xa6\xe8\x2e\xfa\xe9\x22\xb8\x6b\x89\xc3\x1c\x5b\xe0\x71\x35\x8e\x66\x46\x1c\x6f\x3e\xe6\xc9\x84\x7d\x67\x6e\xe2\x3e\x8c\x40\x42\x9d\x26\x66\xc1\x47\xe1\x9d\x77\x48\x4b\xa9\xe3\xc9\x7c\x19\xbe\x5f\x5e\x84\xdf\xb2\xf8\x37\xdf\x10\x7f\xe1\xb0\x4e\xa7\x27\xa6\x8b\xa5\x7a\x3c\x81\x48\x95\x78\x9f\xfc\xb4\x96\x39\x3d\xe8\xf2\xef\x5c\x8e\x3e\xc9\xe5\x75\x93\x12\xe9\x63\x63\x86\x60\xe7\x48\xbf\xea\x9e\x5e\x58\xb2\xe4\x91\xb0\xc2\x13\x47\x1e\x70\xe8\xb3\x99\x44\x9a\x5d\xf7\x66\x48\x19\xec\x04\x2c\xba\x58\xb8\x8b\x5b\xda\x4b\x66\x9a\x38\xa5\x5f\xbc\xbc\x5d\x6e\xac\x4e\xea\xfb\xb0\x9d\x6f\x1a\x68\x5b\x74\x3a\xb0\x99\xd7\xc4\x02\x98\x9d\x26\xd7\x97\x4c\x0f\x64\x89\x59\x15\x1a\x97\x3d\xd4\x96\x75\xe5\x73\x2c\xdd\xbe\xe2\xec\x0b\x11\x9e\x2b\xd3\x3b\xbb\x30\x8f\x85\xde\x70\x36\x1f\x87\xef\x6d\xe9\xcc\x96\x19\xad\xec\xa3\x50\x3a\xde\xee\x8d\x3e\x86\x0e\x9a\x01\x4e\x12\x62\x40\x9b\x70\x30\x5e\xb9\xdb\xe6\xe1\x9e\x9a\x95\xc6\x99\xf5\x00\x52\x21\xd1\xc6\x50\xc7\x31\xb3\x95\x9b\xa6\xe0\x63\x13\x74\xbb\xdd\x14\xae\x5e\x6f\x47\x7b\xf5\x93\x98\x4d\xdb\x0f\x5c\x60\x97\x47\xae\xd3\xb9\xf0\x8e\xb8\x7f\x2c\xf8\x98\x2c\xab\xf5\xb0\xed\x33\x2f\xc4\x14\xfa\xa0\x0f\x1e\xeb\xca\x9f\xb7\x2c\x2f\x77\x11\x8a\xef\x8c\x68\xed\x15\xb1\xbc\x6b\x5a\xe9\xb6\x1b\x7e\xb6\x0a\x06\x38\x72\x5c\xc7\x1b\x5c\x49\xc3\x49\x6c\xaf\x4e\x38\xab\x07\x51\x91\xae\x98\x11\x21\x2e\xb0\x0b\x8f\x85\x9d\x25\x26\x51\x22\xf8\xb6\x35\x26\xa0\xec\xd1\x3f\x4e\x37\x0d\xef\x9d\x07\x8f\xae\x20\x62\x8d\xbe\xec\xb2\x65\xa7\x45\x5d\x82\x93\x96\xac\x40\x8f\x89\xe7\x4b\x0e\xcb\xac\x91\xac\x1b\x20\x37\xfe\x5e\x47\x1f\x75\x8e\xf0\x81\x16\xcd\xbe\x08\x18\xfb\xc9\xc3\xcf\xf5\xc4\x6e\xcc\xa4\xef\xfb\xd7\xa9\xd2\xdd\x33\xfb\xee\xbb\x60\x21\x2b\x43\x47\x07\x28\xe4\xec\xb6\x2a\xd4\x21\x7c\x6f\xc7\x48\x15\x86\xbe\x30\xfe\x5a\x64\x08\x2c\x85\x72\x84\xb5\x3d\x37\xd3\x25\x22\x72\xcb\x95\xbf\x21\x29\xb9\x23\xf4\xdb\x60\xd7\xf1\x79\x2b\xef\x88\xbb\x13\xde\x1b\xdf\xd9\x66\x61\x62\x5d\xdc\x69\x32\xeb\xe0\x99\x92\xff\x41\x9a\x8a\x7f\x71\x50\x57\xf0\x67\xb9\x33\x2c\x54\x36\xb2\x9e\x71\xdb\xcd\x78\xc2\xb3\x73\x21\x2b\x2a\x49\xa7\x2e\x5e\x2c\xf3\xa4\x4f\x59\xdc\xd0\xc1\x64\x9e\x42\x1b\xde\x9f\xdc\x4c\xc5\xad\xc5\x22\x37\xa6\x18\x3b\xce\xf4\xef\x8d\xf0\x5b\x3b\x46\xf7\x89\xae\xd0\xbc\x7c\xa0\x9f\x0d\xc4\x46\xdc\xe5\x21\x16\x17\xc0\x7d\xe7\x88\x53\xf8\x8b\xad\x20\x54\xfe\x73\xf2\x08\x5b\x74\x6f\xbf\x0d\x36\x74\xa7\x35\xb1\x74\x0a\x05\x34\x45\x87\x8c\x34\x88\xa0\xfb\xc1\x0e\x23\xa4\x57\x37\x6b\x44\x07\xd2\x4d\x2d\xcc\x20\x5e\xe1\x29\x06\x83\xaf\xc5\x7e\xe5\x1e\x3f\xe9\x2f\x85\x5f\x63\xbe\xf2\x86\x22\x8f\x9d\x1c\x5e\x80\x89\x31\x9e\x9d\x9a\x9e\x01\xae\xbc\xc4\x7e\x30\x72\xda\xf2\xca\xec\x22\x92\x60\x62\x41\x45\xf0\x3a\x2e\xc8\x2e\x6f\xd3\x25\x9c\xad\xc8\x4e\x86\x7a\x76\xc7\x2d\x70\x75\x41\x4c\x0d\xed\xee\xeb\xca\x83\x4e\xfc\xde\x5f\x60\x53\xf6\x76\xde\xef\x78\x84\xa9\x1d\x83\x7e\x9c\x2a\x7e\x2f\x53\x9c\x7d\x1c\xf1\x68\x3d\xb1\x8a\x89\x7f\xcc\xca\x60\x7e\xaa\x42\x33\xfc\xab\xd9\x1e\x16\xdc\x6c\x67\xcc\x4b\x32\xd8\x2f\x17\xe4\xb5\x0c\x58\xc3\x2d\x07\x48\x14\xa1\xed\xc3\x2e\xf2\xc1\x25\x7a\xea\x3e\xd8\x7b\x45\x0e\xee\x09\x34\xf3\x08\xcb\x2b\x26\xfc\xd6\x27\xfd\x95\x39\x21\x5a\x52\x33\x7e\x93\x5c\xc5\xac\xe3\xbd\x9e\xdd\x54\xfa\x1b\xc1\x4e\xc6\x24\xfb\x44\xfb\xa6\xec\x15\x8b\xdf\xf3\xba\x4d\xb4\xcc\x1e\x5a\xe9\xda\xba\x57\xc6\x51\x18\x5e\x3c\xe3\x1e\x75\x12\x15\x5e\x89\xf3\x58\x4e\x2c\x1b\x7a\xc2\xe6\xf8\x25\x60\xc0\xdb\xde\xf9\xdc\x03\xdb\x77\x0b\x4f\x97\xd7\xd5\x9d\x89\xb3\xb9\xdd\xe5\x2a\x96\x32\x87\x5e\x6a\xcf\x63\x3d\x54\x7f\xf6\xed\xa4\xd7\xee\x11\x6e\xc1\x8d\xaa\xf8\x51\x88\x40\xd9\x65\xc6\x59\x6a\xf5\x08\xa4\x4f\xb2\x89\x40\x1e\x36\x9e\x21\x5f\x42\xee\x39\x22\x00\x9c\x33\x54\x7b\x16\x02\x95\x5d\xc5\x96\xa4\xb5\x4e\xf5\xc1\x34\x66\x57\x8e\x6d\xd6\x91\x3f\x99\xfa\x8d\xcf\xbe\x57\x1d\x95\xb4\xc9\x51\x98\x69\x93\x2f\x88\x2a\x2d\x8e\xe9\x48\x67\x39\x64\x0f\x88\x4b\xd4\x43\xe2\xb5\x17\xd5\x9e\xce\x07\xe3\x20\x7b\x72\x05\xed\x63\x6d\x31\x04\x3d\x7d\x7a\xd3\x19\xaf\x0e\x04\x32\xef\xf0\x10\x3e\x60\xf4\xe5\xa1\x9d\xb0\xab\xc5\xa0\x93\xdb\xea\xa0\x02\xde\x8a\x39\x33\x76\x62\x08\xfc\xbe\x1e\xdc\x58\xbb\xc1\x0f\x0b\x5c\x4f\x65\x42\x78\xb1\x92\x61\xea\x16\x65\x79\x9e\xa3\xda\x9f\xaf\xb2\x07\xd6\x16\xbe\xa4\xff\x33\xd7\x45\x3b\xc0\xa0\x0d\x11\xad\xee\x24\x33\xca\x44\xcf\x48\x57\x62\xbe\xfc\xcd\xeb\x72\x27\xb4\xec\xa5\x06\x3e\xf3\xcc\x87\x76\xa8\x81\xff\xb0\x66\x25\xda\x33\xdd\xa4\xb2\x42\x6c\x81\xec\x11\xf0\x6b\x25\x86\x8c\x33\x6c\x0b\x36\xe2\xbd\xf6\xb0\xf2\x07\x2d\x5c\xd8\xea\x5f\x1c\x50\x8b\x8f\x33\x2b\xaf\x7f\x92\x58\x06\x04\xb8\xb9\x44\xe7\x16\xa7\x89\xb8\x37\x51\x2a\xbe\xb1\xf2\x5c\xa6\x26\x16\x20\x14\x19\xaa\x27\xcd\x1a\x6e\x9b\x3f\x90\xad\x69\x87\xb5\xf3\x7f\x20\x22\x51\xf6\xfe\xdc\x77\x9d\x5f\x45\xf6\xb8\xed\x77\x1e\x66\xf3\x6e\xb6\x01\xda\xf8\x7b\x52\x81\x47\xae\xcc\xce\x70\x65\xdd\x7c\xc5\x29\x1e\xcc\x57\xb3\x90\xff\xd0\x95\x31\x5b\xbb\xb1\xbe\x61\x06\x95\x60\x73\x52\x4e\x4a\x78\x68\xb7\xcb\x45\x4c\x90\xaf\x95\xb6\x99\x86\x51\x7b\x88\x25\x9d\xca\x8b\xd9\x47\x5f\x01\x69\x31\x05\x5d\xf9\x52\xb6\x31\xc5\x7c\x2a\xee\x6a\x6f\xf1\x5f\xe0\x0b\x85\x19\xca\xb0\x9d\x04\x64\x0e\xb3\xd7\xac\xe4\x38\xe6\x2f\x52\x07\x9e\x45\x15\xd0\x87\x80\xa8\x21\x7f\x85\xd0\x0b\x23\xf3\xfd\xf9\x09\x28\x1d\x3f\x69\xb6\x19\x7e\xd2\x16\x9e\x17\xd1\x7e\x0d\xf3\xe0\x4a\x78\xd2\x83\xd5\x9d\xb7\x83\xf9\x66\xfe\xb5\x57\xc7\x2f\x27\x3e\xae\x00\x81\xab\xf1\x88\x9a\xed\x5b\x15\x56\x8b\x86\x51\xf8\x71\xa8\x8e\xfe\x97\xe5\x27\x00\x65\x9e\xcc\xfa\x27\x7d\x56\x6d\x4a\xec\xe6\xa3\xc2\xea\x55\x58\x93\x73\x61\x0e\xec\x88\x77\x43\x5d\x3a\x95\x08\xde\x76\xa9\x85\x8b\x1c\xc2\x3f\x12\x4f\xf8\xcf\x39\xfb\x66\x9a\xa1\xd1\xfd\xdd\x6a\x65\xb1\x8b\x88\x06\x0e\x3a\x1d\xb0\xbf\x23\x03\x89\x4d\x50\xba\x1b\x0c\x12\x6d\x84\xf1\xd2\x99\xdb\xa6\xde\x98\xdd\xd2\x54\xbe\x05\xbf\x46\xca\xf1\xa0\xcf\x1a\xe2\x77\xee\xb4\x11\x9b\x17\x20\x0f\x78\x0c\x5f\x5e\x5a\xdd\xf9\xee\xf8\xbd\xce\x63\xe1\x45\x43\xe5\x82\xa1\x5a\xa1\xb7\x7e\xe9\xf2\xc0\xa4\x63\x3d\x3d\xe8\xe4\xfe\x02\x26\x87\x0d\x3e\x99\x72\x4e\x0d\xf3\xde\x67\x96\xdf\xa6\x14\x15\x59\x1a\xdc\x47\x1d\xfe\x10\xb2\x27\x72\xee\x3c\x0a\xd5\xd2\xf1\xef\xb8\x50\x6f\xa2\x08\xf9\xb7\x2f\x82\x7e\x99\x19\x98\xc5\x0d\xa7\xaf\x98\x86\x05\x5b\xbf\xc8\xa8\x2a\xc3\xea\xf1\xe9\x95\x30\xfe\xba\x0f\xe4\x01\x74\xa8\x10\xe1\x85\xdf\x7f\x6d\x09\x5c\x8f\x39\xd1\x03\x85\xd8\x85\xc7\x81\xd7\xcf\xff\x43\x72\x04\x06\xff\xe9\x1e\x30\x09\x13\x5c\x41\x0f\x4a\x60\x70\x75\x1d\xbb\x25\xea\xa4\xaa\x74\x47\x32\x06\x1d\x89\x98\x49\xaa\xa7\xf9\x72\xeb\x09\xbc\x82\xce\xeb\x9c\x59\x15\x21\x32\x6a\x66\x4e\xe4\x8d\x24\x6c\x38\xc2\x74\xbc\xb7\x2a\xc3\x85\xfe\xd7\xb1\x3b\xe2\x1a\x87\x2a\x75\x66\x14\x56\x7c\xfa\xc9\xbd\xf6\xaa\x27\x39\x3c\x99\xb5\xab\xad\xe8\xa2\xbf\xb4\xc4\x5b\xc5\x6f\xd9\xcc\x22\x55\xbc\x05\x3f\x68\xcc\x48\xbc\x2c\xff\xe3\x96\xcc\xd9\x5e\x66\xe9\x09\x09\x45\x86\x07\x63\x81\x6a\x11\x21\x2e\xfc\x13\x42\x9e\xaa\xd3\x34\x05\xe6\x40\xc3\xfd\x22\x18\xce\xd2\x8c\x67\x53\x74\x22\x27\xd3\xb8\x3a\xb0\x08\xe8\xd6\x3f\xac\xfc\xe3\x94\x5f\x31\xeb\x87\xb3\xf6\x20\x34\xd6\x47\xe0\x0b\x00\x6c\x48\x3c\x5d\xc0\x37\xf1\x14\x69\xe5\xc3\x44\xbe\x22\x0c\x9d\x05\x32\xb7\x4e\x34\x32\xb6\x1e\x3d\xeb\x41\xb6\x41\x74\xc1\x15\xc1\x21\x2f\x1c\x52\x25\xbe\x2a\x68\x5d\x16\xed\x30\xc2\x64\x21\x8e\x16\x60\xc9\x2a\x44\xa8\xbc\x1a\x54\x27\x12\xbe\xc4\x5c\xd8\x12\xcf\xb6\x65\x47\x3b\x2f\x3e\x16\xca\xcd\x16\xf8\x62\x66\xcc\x19\xe4\x03\xfe\x0e\x5a\x8f\x25\x95\x83\x8c\x82\xfe\xed\xae\xeb\x25\xbb\xcb\x60\x03\xf7\x31\x92\xf0\x70\x72\x55\xe5\x1b\xfd\xfd\x38\x09\x9c\xdb\x6b\x92\x15\x13\x95\x17\xb3\x10\x5c\xbb\x33\x2a\xcf\x53\x7e\x60\x15\x5f\xe5\x59\xb0\x78\x83\x2e\x03\xbc\x3a\x49\x3b\xcf\x3a\x25\xbe\x88\x9d\x8c\xc4\x07\x9b\x6e\x51\x58\x55\x4c\x70\xb0\x92\xf7\x20\xf2\xb3\x90\xc9\x40\x0b\x77\x43\x34\x68\x0e\x05\x26\x5e\xd5\xf3\xc9\xd6\x20\x90\x2a\x2c\xf4\x23\xd3\xa3\xc1\xe2\xdf\xeb\x04\xcb\x4b\xc3\xe2\x67\xbf\x2c\x38\x39\xf7\xda\x9f\xbc\x67\xe4\x22\x58\x80\x89\x73\x9a\x11\x46\x7a\x2e\xa3\xa2\x7f\x3f\x29\xa2\x73\x7e\xc3\x9b\x57\x15\x11\xdd\xb9\x1d\xaa\x19\xc4\xfd\x4c\x02\x3a\xcc\xe1\xb3\x20\x86\x0a\x18\xbe\xc9\xc3\x54\xde\x6f\x40\x4b\xf8\x4e\x5d\x25\x3e\xda\x40\x63\x6c\x21\x0f\x5d\x8a\x6d\xec\x22\x67\x18\xb9\x4d\x9e\x57\x46\x07\xf2\x5a\x24\x4d\xbe\x69\x40\x7c\x99\x71\x43\xde\x34\x0a\x4e\x1c\xd0\x2d\xa2\xb3\xf3\x6a\x47\x20\x66\x01\x94\x09\xec\xde\xcf\xee\x87\xc9\xb4\x33\x7f\x80\x08\xd4\x99\xd9\x25\xf6\x74\x16\xec\x48\x87\xc3\x88\x2c\x91\xdc\x61\x0b\x75\x17\x93\xc0\xae\xc2\x43\xd4\x1a\xa0\xa0\xad\x22\xd2\xe3\x52\x9e\x0e\xfd\x99\x7b\x8c\x64\xcf\x8c\x7b\xd4\xd1\x11\x1e\xad\x49\xb7\xc6\x2d\x2c\xbd\x66\xfe\x54\xb9\xe7\x1c\xd4\xbc\x95\xa1\xa2\x83\x36\x11\xd1\x4d\x42\xfe\x19\xba\x00\x06\x64\x90\xa0\x5c\xdd\x0c\x0e\xfe\xe1\xde\x60\x73\xaf\x07\x64\x56\x1f\x7a\x87\xd0\x18\x2d\xda\xba\xf1\x08\xa4\xa5\xd7\x42\x65\x77\x52\xbe\xf5\xf6\xda\xca\x3e\x68\x42\x3d\xe9\xbf\x29\x84\xc7\x27\x0d\xf8\x8c\x44\x52\xe0\xf1\x76\xa7\xe7\xbf\xdc\xa2\x00\x5a\x66\x95\x3e\x68\x8e\xea\x9d\xd8\x93\x87\x7b\xac\x8f\xdb\x21\xca\x58\xe2\x45\x8e\xa1\xd8\x95\x83\x61\x71\x6c\x15\x36\x01\xc4\x16\xd4\xef\x70\x63\x76\x4b\x04\xf9\x48\x03\xd7\x0a\x9c\xb7\x56\x04\xb1\xd8\x8c\x1b\x75\xce\x64\x6c\x59\x0e\xb3\xf1\x37\xd4\xa8\x18\xe4\xbd\x27\x8e\x85\xdb\xb6\x47\x6d\x3e\x9d\x1b\x91\x40\xcf\x05\x04\xfd\x21\x7d\xf3\xef\x64\xbe\x9a\x86\xc0\x83\x9c\xcd\xc2\x83\x6b\x16\x2c\x18\x5e\x7b\xcf\x9b\x02\xa8\xa2\xd5\x27\x36\x82\x1d\x76\xe7\xf9\x44\x66\xca\xe9\xe4\xeb\x20\x4f\xa7\x52\x14\xa3\xc1\xc3\xdc\x38\x5d\xa4\x62\xe1\x32\x31\xb2\xda\xcf\x80\x7e\x7a\x0f\x2d\x89\x3c\x6f\x28\xdc\x9e\x73\x77\x13\xee\x7a\x47\x00\x73\xb7\xa3\xce\x9c\xf7\x41\x96\xeb\x08\x4a\xa7\xb8\x5b\x48\x27\x68\x34\xea\x9f\x5e\xe6\x91\x70\x25\x0f\x80\xdd\x6c\x9e\x13\x54\x57\x69\xf1\xbc\x4c\x71\x63\x14\xa3\xdc\x64\x62\x6a\x55\x36\x65\x93\x5d\x80\x9a\x79\xe9\x68\xe6\xeb\xc4\xe8\x79\x2a\x81\x90\xbe\x5b\x98\xa7\x9b\xe7\xc8\x81\x40\x38\x0b\xe2\x88\x2b\x3a\xc7\xb4\xc5\x4f\xab\x87\x78\x0a\xcb\xd2\xcc\x64\xd0\x56\xe6\xc9\xca\x91\x79\x24\x86\x19\xa2\xeb\xcd\x69\xc3\x81\x49\xf7\x3b\x81\x8a\x97\xc2\x95\x1c\x0c\x58\x62\x64\x3c\xbc\xa7\xd0\x4c\xde\x0a\xcf\xb5\x6f\x0a\xef\x02\xfc\x27\x4a\xb9\xa9\x50\x1c\xb9\x14\xc3\x40\x82\x7e\xfe\xe2\x13\xb6\xdd\xae\xb8\x1d\x21\x40\x5f\x53\x9f\xfe\xe2\x95\xcd\xf0\xcd\x6b\x7a\x2c\x72\xd5\x8b\xdb\x07\x92\x23\x3c\x51\x25\x0d\xca\x92\xd3\xe0\x10\x79\x95\x00\x56\xe6\x15\xe0\x6e\xe0\xdb\xa3\xce\x75\xd4\x28\xf8\xd6\x67\x1c\x60\xf3\xc9\xab\x2a\x87\x00\x45\x6f\xf0\x4c\xbe\x05\x24\xa7\x82\x8c\x88\x75\xae\xef\xa5\x21\x62\x7c\x88\x1b\x6a\xeb\x84\xcb\x65\x72\x27\x85\x32\x76\x60\x08\x50\x25\x50\xa8\x76\xf8\x96\xe1\x3c\x14\x50\xc1\x57\x10\x8e\xd8\x62\x6b\x87\x7c\x57\x9d\xf9\xd9\xea\x19\xf9\x41\xf4\xc0\x31\x24\xb9\x4d\xa2\xc4\xeb\xe6\x40\x1b\x2f\x8f\xaf\xde\x20\xa2\x75\xc7\xd3\x69\x81\x45\x23\x14\xe3\x01\xcd\xc8\x47\x85\xa8\xd8\x8f\x72\xbf\x3c\x3c\x90\xc3\x8f\x7a\x65\x37\xd1\x3b\x9c\x0f\x3e\xbf\x45\x7a\xeb\xb5\x8e\xbb\xee\x6d\x64\xf7\xbb\xc2\xd6\x4e\xd0\x7e\x4f\x0c\xc3\x9f\x97\x18\x26\x00\x6f\x06\xf3\x01\xd4\x5b\xc8\x9c\x3b\x9d\x57\xfb\x39\x33\xb1\x49\x25\x8b\x25\x90\xc3\x81\x39\x3e\x9d\x07\xaf\x01\xd2\x38\x73\xc0\x07\x2b\xd7\x0e\xf5\x90\x13\xef\x96\x43\xbb\x17\x41\x08\x31\x98\xa3\x06\x13\x17\xee\x90\xa5\xae\x53\xf5\x11\x07\x05\xb9\x52\x1e\x6c\xc8\x53\x6c\xf5\x6e\x87\xa9\xd4\xb0\x98\x49\xf6\x03\x48\x3c\x76\xe3\x17\xc7\xda\x32\xbc\xe2\x9f\x84\x47\x7d\xd9\x63\xf3\x6e\xc1\x89\x37\xce\xe9\x9e\xe6\x82\xd5\xc2\x91\xaa\xc1\xbd\xc5\x37\x01\xdf\xec\xb2\x80\xa0\xe5\xd1\xd6\x95\xbb\x68\xdf\x83\x0f\x57\x46\x27\xe6\x95\xd6\x9b\x1f\x93\x10\x3e\xce\xd7\x06\xae\x1e\x33\x89\x78\xb5\xb1\x68\xcc\x5f\xd5\x18\xcd\x2a\xd9\xb7\x4a\x21\x7d\x6e\xab\x8d\x35\x2a\xad\xd3\x4d\x09\x57\x38\x19\x75\xbf\x29\x53\x8a\xd4\xc8\xd6\x4a\xdc\x24\xcb\xc1\x68\x9d\xba\x0a\x2b\xaa\x56\x07\xf3\xd6\xf9\x15\x75\x06\xcb\x34\xcc\xcb\xf2\xd0\x4f\x55\x5c\xbb\x17\xed\xce\x98\x07\xda\x0d\x42\xa4\x8c\xf3\x56\xa5\x8c\x3a\xdf\x7a\x26\xbb\x2d\xd3\xd9\xb2\x33\x3b\x17\xb4\x80\x93\x02\xb3\xad\x15\x67\xca\xec\x30\x43\x44\x0c\x66\x1f\x9c\xb9\x17\x24\xa0\x2a\xaa\x06\xcc\x0d\x43\x1e\xd4\x2f\x08\xab\x04\x85\xdc\x19\x1c\xcc\x2e\x16\x7e\x0a\x3c\x2a\x2d\xf7\xc8\xb2\x9e\x19\x7e\x7c\xd0\x4f\x92\x15\x18\xc9\x79\x11\x8c\xd2\xf8\x08\x7c\xf4\x97\x57\x3f\x1e\x0d\x1f\xef\x58\x92\x63\x6e\x74\x53\xf5\x2b\x36\x91\x4c\x4a\x3b\x85\xac\x72\x6c\x65\x96\xff\x7e\x34\x33\x01\x9a\x24\x0c\x74\xb1\x15\x9a\xaf\x83\x5b\x49\x9d\x6a\x81\xe2\xfd\x34\x5f\xc7\x17\xae\x57\xaa\x10\xd0\x8c\xae\x7b\x0b\xc7\xbd\x54\xb9\x3c\x78\xce\x09\x55\x5a\x74\x4c\x72\x6f\xc2\xc9\xdb\x05\x6b\x34\xfe\x1c\x2d\x80\xff\x15\xbf\xc4\xa1\xdc\x96\x1e\x1c\x39\x5c\xfc\xf5\x9d\x23\xdd\xa5\x7f\x5f\x8b\x96\x18\xe2\x56\x3b\x1c\x34\x08\x20\xf2\x2b\xa2\xb4\x54\x66\xd3\x69\xb0\x3d\xb7\x7d\x1c\x2b\xe2\x1a\xb7\x39\xb3\x38\xe6\x9b\x18\x08\x7f\x93\x18\x0f\x9e\x0f\xdb\xc9\x21\x5c\x9c\x45\xce\xb6\xb3\xca\xbc\xd1\x2e\x21\xec\xa2\x65\x6e\xfb\x78\x0b\xda\x28\xdf\x23\x62\x72\x3f\x8d\x8f\x85\x36\x84\xf1\x1c\xa1\x41\xad\xd8\x3d\xab\x56\xfc\x48\x8f\xf0\x2b\x02\x9e\xdd\xbf\xd1\x6c\x97\x25\xb2\xee\x70\x3e\xe7\xa6\xda\xf1\x73\x21\x7f\x15\x14\x3c\x22\x52\x89\xbc\x2b\xb2\xc5\x89\x0c\x30\x3d\x1f\x59\x8e\x76\x16\x07\xd3\xac\x6d\x68\xd5\x3b\x9c\xd5\xec\x2c\x66\xec\x3b\x92\x33\x9a\x51\x78\xd6\x87\xd3\x6d\xf9\xd2\x76\x4f\x11\xd7\x9e\xdb\x4b\xcc\x0d\x07\x5d\x64\x95\xb6\x38\x97\xa8\x1f\xea\xd5\x18\x57\x10\x60\x12\xa3\x30\x18\xfc\x7a\xbf\x7c\xda\x0e\xab\xfb\x48\xd6\x8a\x5d\x05\x8d\xf1\xa3\xe0\x6d\x73\xdb\x42\xa4\x7b\xfc\xec\x02\x00\xd3\xcb\x42\xb5\x76\xd1\xab\x19\x2a\x1e\xe3\xcc\x12\xa6\xb3\xf8\x79\x64\x56\x6e\xb3\x19\x03\xc4\xd9\x65\x77\xa6\x83\xbc\x75\x12\x65\x09\x2e\xa6\x5d\x71\xd2\xf4\x6e\xc8\x5e\x0e\x2e\xa8\x67\xd0\x2c\x67\x20\x27\x94\x1b\x75\x87\x2d\x74\xf4\x50\x79\xee\x60\x6e\x73\x30\xdb\xb7\x23\xc6\xcb\x6d\x1e\x9c\x39\x98\x08\x7d\x43\x5e\xb5\x44\xb3\xaa\x71\x64\xad\xf0\xd3\x7e\x4e\x5c\xfb\x05\xeb\x8a\xb7\x35\x67\xc7\xda\xa9\x20\x7f\xb7\x1a\x7f\x5a\x69\x54\xb7\xcc\xe2\xf4\x87\x70\xd2\xb3\xd9\x1b\x10\x92\x96\x56\x1f\xdb\x6a\x2f\xf2\x46\x89\x38\xab\x4b\x4a\xa5\x8e\x0f\x57\xd3\x99\x22\x00\x0f\x26\x46\x73\xbb\x5f\xdc\x24\x9f\xb7\x05\x3d\x22\x91\xf4\xce\x20\xcd\x89\x89\x2c\xee\x9f\x0b\xb3\x02\x6d\x8d\xf7\x0a\x71\x31\x97\x70\xde\x66\x01\xe1\x46\x82\x69\x4b\x54\x2d\x3d\x87\x14\x11\x05\x83\xe6\xbc\xc9\xa9\x46\x81\xd8\x41\xc5\x30\x72\x85\x79\x38\x00\xe1\xe0\x4f\xf4\x07\xe1\x4e\xe1\x45\x8e\xd6\xe2\xa2\x96\xad\x3f\x67\x7f\x03\x5d\x53\xf9\x5a\x1e\x05\xff\xa4\x20\x12\xa0\x89\xcb\x19\xd2\x3a\xa1\xbd\x62\x29\xda\xbe\x1b\x13\xbe\xc0\x5a\x0f\xdd\xff\xab\xb3\x44\x46\x70\x22\xf1\x03\xf9\x25\xa8\x78\x3c\x6a\xa2\x53\x88\x21\x3f\xc6\x39\x99\x89\x62\xd9\x6f\x67\x80\x4b\x27\x22\x4f\x3f\x7f\xdc\x62\x7e\x6e\xaa\x26\xd1\xf5\x58\x12\x73\x4e\x64\xf9\x17\x2e\xd0\x2b\x33\xd1\xd0\xa3\xf0\xec\x81\x2e\x97\xc4\x0b\x22\x40\x9a\xf6\xe6\x0d\xf7\xc0\xcc\xef\xe6\xe1\x19\xc5\x23\xfb\x13\xc4\x9a\x88\x21\xdd\xe3\x26\x58\xc8\xf3\x09\x2b\x22\xd7\x9f\x64\x32\x08\xef\x34\xb6\x43\xda\x3a\x2e\xef\x7b\x24\x24\x74\xf0\x3b\xd5\x50\x32\xa0\x9d\x68\x6f\x4c\xfc\xbd\x95\xce\x2c\x66\xcc\x17\xb3\x2e\xc2\xb0\xf8\xca\xbe\x29\xf0\x30\xaf\xa5\x25\x02\x50\x41\x62\xe2\xcd\x4d\xaf\xca\x6e\xb4\x80\xc2\xee\x41\x61\x06\xf7\x4d\x2e\x95\x95\x5c\x36\x95\x45\x5d\x84\x26\xe1\xa6\xde\x0e\x1c\x6b\x95\x0d\xa2\xa2\x35\x12\x66\xdb\xf0\xbb\xc8\x2e\x02\xb0\xf0\x05\xac\x37\x9b\xb5\xab\x9a\xb8\x7b\x4e\xab\x2e\xa2\x06\x48\xbe\x74\xc6\x19\x6f\x02\xed\x6b\x1e\x89\x2e\x8e\xe9\xb1\x45\x3a\x79\x4a\x45\xf7\x93\xbb\xa1\xa8\x53\x20\xde\xb2\xd0\xc2\xdd\xed\x1c\x46\x5a\xa3\xf6\x1e\xc7\x22\xbd\xb5\x4b\x19\xd5\x1e\xf1\x35\x37\x86\xe9\x9b\x1d\x4d\xe2\xe6\x2a\x1f\x32\x82\xc9\x2c\x75\x99\xa7\x7a\x28\x6a\xe8\x82\x48\x08\x5a\x17\x17\xa3\x55\x85\xdc\xea\x91\xf2\x51\xc9\xbf\xda\xc4\x14\x35\x73\x37\x85\x6b\x2b\x44\x3e\x09\xdf\xfa\x15\x72\xdf\x0e\xdb\x64\x51\x5e\x3a\x18\x73\x6c\x39\xff\xe5\x5d\x0b\x68\x9d\x34\x91\xbd\x8f\x0a\xd7\x4a\x0b\x9a\xf5\x16\x29\xf8\x20\x7b\x12\xb1\x21\x2b\x4c\x5c\x71\xc6\xce\xe5\xdf\x02\xc2\x9a\xb9\x32\x8b\x6c\xc0\x76\xc1\x94\x30\x76\xec\x98\x7d\xe7\x08\xbe\x1d\x14\x51\xf9\x31\xd0\xf4\x63\x6b\xc4\x37\x70\x9f\x18\x8c\x6d\x9b\x60\x7b\xe4\x61\xb0\xb2\x28\xc2\x04\x74\x60\x67\x6a\x5e\x55\x91\x51\x37\x86\x6d\x6d\xe6\xae\x32\x64\x71\x58\x9f\x89\x04\xd2\xc5\x62\xe6\x9e\x15\xc7\xcd\xdd\x2b\x3e\x65\xc9\x1e\xfe\xa9\x1d\xa2\x8b\x6a\x32\xa2\xee\x1b\x7b\x03\x58\x62\x73\x16\x24\xdf\xec\x37\xe2\x19\x33\x21\x20\xd6\x3b\x50\xbf\xc9\xaf\x01\x6a\xcf\xc1\x91\x42\xd9\x99\xf4\xf9\x87\xda\xca\x96\xfc\x99\x59\x9b\x7e\x93\x95\xcc\x02\x87\x5d\xc0\x67\x14\x70\xbf\xfd\x56\x25\xca\xf2\xfb\x15\xd7\xcb\x96\x78\x1c\xc3\x33\x6f\xb9\x38\xd9\xaf\x73\x62\xe7\x31\x0e\x0e\x4a\x24\x44\x21\x97\x86\xbc\xa3\x7e\xd0\xd8\xaf\x3c\xff\xf9\xf8\xaa\x0a\xdd\xd4\x44\x24\x72\xc3\x08\xd4\x77\xad\x8a\xa5\x67\x5b\x56\xb4\xee\x4e\x66\x52\x2e\x58\x59\xa7\x9c\xe5\x54\x92\x12\x1e\x8b\x1a\x5d\x9c\x3e\x07\xa4\xca\x2d\x99\x6d\xd4\x48\x2b\x7a\xef\xd0\x55\x9e\x54\xa1\x39\x48\x22\x31\x2b\x17\x3e\x24\xb7\x12\x66\x04\x3c\xbc\x2c\xa8\xf1\xaa\x0a\x5a\x96\x20\x9a\x33\xc3\x55\x5d\x74\xae\x03\x40\x64\x52\x24\xc2\x7c\x0c\x30\x44\x0f\x82\x59\x76\xa6\x93\x90\xae\x3b\x49\x53\x9e\xe1\x92\xe6\xe1\x79\xca\xad\x01\x1b\xa2\x3e\xa8\x48\xc6\xb4\x75\x7f\x06\xab\x83\x16\x4b\x09\xf3\x29\xee\xfd\x78\x8a\x6a\xd1\x8a\x8a\x40\x55\xdc\x6d\xa8\x60\x88\x55\x15\xe1\x0f\xc7\x8d\x9f\xeb\x2e\xf0\xc6\xd8\x63\x51\x75\x05\xc7\x08\xb9\x0d\xac\xac\x2a\x0b\xd8\x8a\x45\xa9\xad\x02\x4e\x7a\xba\x5d\xe7\xb2\xc5\x30\xdb\x29\x96\x2d\x0d\x91\x99\xc5\x53\x4e\xfa\x90\x11\x75\xd4\xb7\xf1\x72\x10\x16\x47\xc4\x36\x56\xb9\xb7\x16\xc3\x79\x6a\x2f\xab\xa1\xb2\xc6\xc3\x39\xc0\x3c\x92\xa9\x2b\xc4\x86\xdd\x7d\xb2\x6d\xaa\xbe\x85\x84\x6d\x16\x98\x25\xa6\x0e\x76\x57\xd9\xa5\x43\xe0\xfb\xf0\x10\x8c\xc0\x4d\x8a\x02\x42\x1c\xfc\x3a\x5c\xf1\xfc\x1c\xc0\xbd\xc5\xc5\x2b\xd9\xb2\x51\xcd\xb5\x53\xd2\x22\xba\x8d\x86\x68\x4e\x0f\x27\xf5\x22\xa6\x33\x0b\x78\xbb\x18\x76\xcc\xe7\x4f\x72\x86\xd8\x33\xf4\x47\x59\x66\xb8\x35\xcf\x46\xf3\xf1\x69\xab\xcc\x28\x8e\x71\x86\x9d\x3e\xf6\xdd\x31\x37\xf5\x92\xb4\x3d\x1a\xc9\x30\xe0\xa8\x32\x51\x47\x77\x0b\xbf\xc1\xdb\x11\x78\xfb\x80\xbc\x04\x58\xcf\x32\xd0\xb3\x0c\x4b\x52\x31\x6d\xff\xef\x64\x4c\x6d\x3e\xe8\x4f\x00\x33\x4b\x03\xf7\x71\x50\x57\x25\x63\x65\x5e\x5b\x65\x0a\x0c\x0b\x5d\x09\x7d\xd4\xcc\x98\xef\x60\xf3\x41\x12\xd1\x19\xc5\xfa\x88\x05\x36\x99\xb3\x74\x20\x9c\xe1\x13\x5a\x18\x7c\x72\x77\x19\xf3\x89\x3f\x6f\xe6\xeb\xe4\x69\xb3\x44\xc3\x0c\x73\xa0\xfb\x04\x20\xe1\x8e\xec\xea\xf1\x3b\x26\xd2\x88\xec\xc1\xed\x21\x60\x7c\x1b\xbf\xd6\x0e\x9d\xcc\x73\x77\x06\x35\x8d\x98\x5d\x9a\xa2\xbe\x8d\x05\x58\x68\x14\x17\x05\xa8\x8d\x94\xc0\x4a\x38\x8b\x40\x03\x8b\x30\xf6\x11\xc8\x85\x98\x04\x63\xd9\x40\x88\x55\x78\x43\xd6\x2e\x6e\x29\x02\x44\xb1\x96\xf6\xa2\xea\xc0\xbc\x88\xf1\xd5\xe1\x5c\x9c\x9e\x69\xb5\x87\x7d\x9c\xcd\x17\x1e\x0d\x6b\x33\xdb\xa2\xf0\x70\x8b\xa2\xb4\x53\xa4\xe0\x9c\xf3\xa0\x84\xdb\x63\x1f\xe1\x63\x9d\x02\x34\xb4\x83\x82\x6a\x44\x5c\x56\x6c\x53\x44\xa5\xda\x3b\x6c\x79\x02\x6e\x60\xf1\x64\xb9\x7b\x27\x68\xe2\xc5\xc0\x2b\xe7\x07\x62\x9a\x7c\x57\xeb\x97\x39\x81\x9e\xe2\x12\x8c\x6d\x5b\xe1\x8f\x1c\xaf\xe2\x7d\x1d\xc3\x79\x5d\xf2\x70\xad\x6d\x13\x23\x51\xc1\xc7\xea\x48\xa9\xea\xca\xa7\xf2\xce\xc3\x3f\xba\xbf\xe7\xc5\x23\x04\xe7\x82\xe1\xf7\xcc\xb2\xaa\x53\xcc\x26\x85\x10\x62\x31\xd2\x04\xe1\xf7\x9d\x1b\x2b\x7f\x3d\xab\x5c\x5c\x66\x1d\xb7\xb8\xd7\xe0\xf5\x71\x89\xde\xb0\xa2\xde\x0e\xc1\xb6\xfe\x7b\x14\xcd\x7a\xcb\x2a\xfa\x8b\xcd\xea\x06\x0c\x39\x2b\xe8\x8c\x5c\x56\x1c\xd8\x55\x98\xe7\x5e\x59\xba\xf1\x16\x6a\x6f\xef\x21\x43\x52\x6d\x64\x6b\x11\xa5\x91\x17\x6a\x8a\xa2\xe7\xc3\x92\x04\x11\x09\xc9\x11\x97\x05\xc7\x79\x37\x3f\xcd\xef\xaf\xe7\x41\xa2\xc4\xac\xf6\x48\x96\x34\x57\x11\x96\xe7\xf4\x89\xf8\x2b\x3d\x15\x93\x3e\x1e\x0d\xc5\xa0\xa5\xcb\xcb\x4f\x0d\x6c\x17\x3e\x03\xed\xe2\xc1\x04\x8d\x04\x5b\x25\x30\x4b\xdc\x32\x4b\xff\x8f\x45\x67\x6c\x6b\x11\x02\xf0\xe9\x41\xff\x95\x05\x86\xb2\x10\x72\xfc\x7c\xf3\x36\x36\xda\x60\x0b\xd2\x76\x6e\xde\x29\xa3\x2a\x32\x86\x97\x63\x2c\x1f\xe2\xdb\xdf\x27\x46\x80\xad\x9b\xbd\x3b\x8f\xa3\x8a\xca\xad\x7a\x49\xf9\x3d\x18\x1a\x1e\x2d\x8d\xa0\x33\xb0\xdf\x50\xb8\x70\x4c\xc4\x18\xa0\x7d\x5a\x82\x32\xa9\xe0\x90\xa2\x5d\x9b\xed\xa6\x7e\x4e\xdb\x06\xd7\xeb\x36\xde\xc5\xf8\x2d\x2a\x96\xdc\x65\x2f\x10\xef\xd1\x00\x2d\x00\x12\x82\xa6\x85\xfc\x07\xbf\x57\x38\xe6\x9d\xdd\xc8\x4e\xda\x73\xd3\xa7\x80\x7b\x9a\xc8\xfa\x71\x3c\x76\x4d\x37\x61\x1e\x0c\x47\x1d\xec\x2a\x77\xbe\x57\xdc\x15\x0f\xc0\x0e\x06\x91\x6c\x1f\x42\x7e\x08\xc4\xf7\xf1\xc1\xc5\xdd\xce\xcc\xce\x70\x26\x20\x5d\x55\x2c\xe3\xe7\x3c\xce\x97\xf3\x48\x93\x12\x5f\x98\x85\x46\x4a\x46\xdc\x87\xd5\x47\xf5\x16\x5f\x94\x8d\x0f\x09\x5e\x1a\xb1\xa5\x25\xf3\xf0\xdd\xc5\x21\xf1\x36\xe5\x1d\xab\x0a\x6b\x16\xd1\xd2\x61\xd9\x83\x1a\xd0\xbd\x70\xca\xe7\xde\x17\x66\xe4\x33\xb8\xd7\xf7\xb2\x51\x3d\x00\xd8\x24\xb9\xa1\xce\xcb\x98\x1b\x11\xfb\x95\x98\x63\xa9\x5a\xe0\x3c\x47\x50\x83\xf9\x61\x73\x1c\x0e\xb2\x5f\x70\xf6\x40\x3c\xe8\x1b\xc0\x76\xd8\x5a\xe0\x36\xbd\x83\x9a\xd4\x3b\x58\xa2\x3e\x84\xe8\xc3\x66\x88\x7d\xbb\x50\x50\xb9\xe2\xa9\x10\x0e\x6b\x2c\x46\x24\x3a\x57\x40\x42\x8c\x8d\xdc\x03\x17\x93\xa0\xe7\xdc\x48\x5e\x4d\xb3\x85\xf4\x8a\x73\xde\xde\x61\x4f\x6a\xd3\x7e\x61\xe5\x01\x00\xb0\xb2\x0b\xb7\xa3\x56\x26\x10\x61\x5a\x3e\x45\xd1\x95\x55\xf7\x6d\x4a\xde\xb0\xa6\x74\x75\xa6\x2d\x0b\xfa\x88\x97\xde\xf0\xba\xcf\xc2\xe6\x9d\x22\x1b\x15\x4d\xfa\xaa\xc7\xf8\x92\x07\xfe\x56\x57\xe5\xde\x20\xc3\x36\x07\xe4\xbc\xc2\x20\xd5\x17\x9e\x6f\x47\x9d\xc0\x1f\xf8\x6d\x3d\xe6\x5d\x36\xe7\xf1\x11\xc3\x09\x1d\xdf\x47\x03\xa1\x14\x8c\xf1\x7a\x12\x26\xc4\x39\x11\x8d\xc3\x02\x72\xc5\x0b\x8b\x7e\xd1\x5e\xd1\x78\x81\xf6\x28\x96\xc7\xd4\xc1\xca\x56\x42\x56\x73\x82\x37\x90\x17\xa5\x99\x13\xfb\x03\x50\xf5\xc3\x07\x9b\xd5\x51\xca\x03\xde\x49\xd0\x34\x67\xed\x05\xf0\xb2\x41\x74\x9b\x9e\xed\x34\x7b\xb3\x66\xf6\x55\xdb\x68\xae\xac\x59\xb5\xd8\xf1\xb3\x88\x89\x1a\xc7\xcd\x8e\x95\x1f\x9b\x86\x14\x74\xe9\x90\xa5\xf1\x07\xb3\xe5\x12\x8c\x67\x4b\xcb\xe0\xc6\x16\x6e\x8f\x34\x3b\x1d\xb4\xb6\x95\x3d\x21\xfe\x3b\x49\xf7\x50\x0d\x1e\x01\xcc\x39\xb3\x3c\x62\xdf\x04\xbb\x68\xa1\xd8\xc8\x2b\x1e\x2e\xd7\xfb\x54\x75\x32\x1c\x68\x46\x76\xe8\x40\xdb\x9e\x08\x96\x26\x51\xe2\xbc\x6b\x00\xb0\x44\x65\x43\xbf\xd9\x22\x82\x4f\x53\x40\xeb\xde\x67\xcc\x20\x05\x05\x7d\xf8\xd8\x73\xb8\x72\x75\x61\xbe\xa0\x2d\xd1\xc3\xee\x4c\xe8\x41\xca\x8a\xd4\x8e\x9c\x42\xd2\x3a\x83\x2d\x6b\x1f\xcc\x6a\xd3\x44\x26\x98\xa7\x00\xf6\x29\x64\x09\xda\xe3\xb3\x9c\xeb\xd5\xa6\xab\x79\x85\xec\x90\x65\x78\x53\xbe\xc4\xcf\x80\x32\x51\xca\xb6\x74\x8d\xe3\xd8\xa0\x9e\xb7\x87\x16\x0b\x8d\x93\xcb\xab\xfc\xa1\x95\x0f\xf7\x6b\x21\x3d\xfe\xc1\xf1\xa6\xa9\x65\x1c\x41\x77\x62\x4e\xc6\x02\x70\x60\xfa\x02\x2b\xdf\xea\x38\x29\x4a\x19\xd1\x0a\x48\x62\x40\x3f\x7d\x7f\x93\x3a\xb0\xfe\x3b\xa3\x88\xcc\x7a\xc1\xac\x7e\x27\xd5\x16\xc5\x52\x8c\xc7\xca\xd1\xfe\x73\x8a\x8a\xe2\xaf\xaf\x37\x73\xc2\x54\x00\xc8\xc3\x43\xe7\x10\x4c\x87\x68\xa0\x24\x57\x12\x68\x4c\xf6\xa6\x7e\x98\x81\x73\x8b\x46\x88\x20\xba\xd2\x9b\x22\x10\xe3\xee\xa3\xa2\x83\xe6\x86\x20\x7b\x90\x4d\x09\xaa\x11\x0b\x49\xe7\xb4\xb4\x52\x4b\xa7\x06\xc1\xe1\x02\x23\x9c\x97\x25\x3c\xc0\x8d\xcd\x5f\x72\x27\xcc\x02\x7b\x32\x82\x93\xb5\x46\xc1\x7a\xe1\x0b\x3e\x05\xc1\x1d\x42\x0e\x9f\x4b\x0e\x44\x41\xa2\x39\x9b\x36\xad\xf3\x0c\x1b\x9b\x15\xc4\x3f\x5b\x93\x17\xd9\x78\x43\x56\x2b\xd4\xb9\x04\x9d\xc4\xc5\x3f\xf0\x73\x3f\x35\x6a\x22\x0a\x12\xf1\xbc\x22\xd1\x6d\x8c\x46\x5f\xe1\xd8\x5d\x38\x20\x3a\xb2\xa8\x9b\x83\xff\xce\x84\xf8\x21\x78\xde\x42\xa7\x5b\x04\x3c\x3c\xdf\x71\x64\x40\x8c\xf3\x5f\xea\xb9\x53\xc8\x49\xfc\x0a\xa7\xb6\x5f\xcf\xb6\x2b\x88\x1a\xd0\xd1\xdb\xdd\xe5\x81\x7c\x8a\xaf\x7e\x54\xb2\x2d\x2d\x4a\x62\x89\x77\x53\xdc\x65\x9e\x07\x2f\x6d\x29\x9a\x5e\xab\x35\x9e\x98\x7b\x3d\x4a\x6b\x77\x8a\x04\x98\xcc\x3a\x44\xa1\x70\x6a\x21\xd8\x50\xff\x32\xb4\x51\xc6\xac\x27\x75\x00\x82\x66\x0c\x3d\x82\x84\x3b\xec\x93\x36\x5e\xc8\x88\x93\xc8\x9d\xb9\xa1\xe1\x5d\x70\xce\xf6\xd2\x51\x9b\x5a\xa8\xd6\xb7\xae\x8d\x97\xa5\x43\x65\x13\x1f\xb5\x45\x47\xce\x82\x52\xf7\x21\x71\x99\x57\x62\x81\x56\x1f\x6e\x16\x57\xce\x2b\x51\xae\x43\x95\x0e\x2c\x5f\x11\x74\xa0\x05\xf3\x03\x7e\xa3\xbf\x0e\x25\x32\xe1\xf9\x43\xa8\x21\x2d\x17\xba\xd8\x49\xd7\x81\x67\x3a\x48\x04\x0d\xaa\x54\x33\x26\x2a\xae\x61\xa9\x1e\x1b\xfb\x14\x9c\x49\x1c\xac\x37\x12\x2b\x0f\x09\x35\x74\x96\x6c\xdc\x5a\xa3\x23\x8f\xa6\xad\xd8\xe7\x4d\x70\x89\xdd\x63\xea\x5b\x40\xb6\x86\xd2\xfd\x29\x2c\xe2\x55\x36\x46\xf7\xa3\x84\x06\x2c\x54\xb6\xd5\x10\xa4\xec\x80\x69\xec\xb3\x73\x61\xb0\x68\x1b\xa9\x3f\xa2\x8d\xf2\xf6\x9a\x57\x9a\xeb\x8d\x34\x40\x54\xfe\x0a\x3f\x7e\x8a\x7b\xf0\x56\xc7\x6a\xee\xc7\xa5\x15\x08\x98\x1c\x71\x69\x26\xc9\xbe\x2c\xbf\xb1\x8d\x3c\xee\xf0\xd8\xd1\xf2\x56\x24\x97\x02\x96\x86\x02\x88\x7d\x54\xd7\x2b\xca\x86\x03\x6f\x6d\x94\xa0\xdd\x4d\x73\x91\x08\xb0\xa0\x19\xfe\xca\xfa\xed\xcf\x0f\xd0\x0f\x0b\x39\xb0\x6b\x1e\x2d\xca\xbc\x55\xf5\x29\x6d\xdc\x95\x8e\xa4\x4f\x75\x0a\x39\x1d\xdd\xdb\xe0\x14\x9b\xf7\x16\x73\xca\x54\xba\x49\xe6\x3f\xae\xa4\x82\x2e\x76\x02\x74\x26\xee\x28\xa6\xca\xc0\x39\x4f\x27\xb4\x6e\x2c\x6a\xb2\x45\x61\x60\x38\x15\xe1\x16\x43\x11\x99\xb4\x6b\xb4\x2d\x08\x4c\xa9\x9e\x1d\xd1\xd0\x77\x7f\xff\x17\x8a\xa2\xd3\x05\xe9\x31\x1e\x54\xdc\xbb\xc2\x1e\xe6\xad\xfe\x7e\x64\x95\x54\x6a\xb1\xdc\xb8\x35\x90\x4f\x61\x51\xdf\x4c\xc4\x6b\xb7\xb7\x72\xc7\x46\x2e\xfd\xe1\x95\x09\x55\x39\xc8\x57\x62\x58\xe5\x94\x03\x7d\x4c\xbe\x0b\x44\x85\x4c\xc5\x9f\x88\x57\x1b\x62\xbc\x65\x31\x1a\x9c\xfb\x13\x4a\x64\xe2\x80\x14\x42\xd3\x54\x7d\x68\xd0\x61\xb0\x1a\x8b\xf8\xde\xe7\x12\x3c\x25\x05\x0c\x68\x40\x65\xf6\xb5\xd1\xee\xce\x6a\xe4\xbc\x23\xc0\xbc\x85\xe1\xc4\x07\xa0\x94\xa5\xde\x5e\xaf\xed\x32\xaf\x18\x53\x84\x74\x0c\x7b\xe2\xd6\x45\x51\x48\x00\x4a\xe3\x20\xab\x8d\x78\x52\xbd\xae\x17\xd6\x14\xdd\xe9\x8e\x6c\x36\x53\x89\xab\xce\x78\x1a\x66\x9f\xc4\x8b\xab\xab\xd3\xad\x85\x3b\x6b\x55\x11\x3b\x69\x82\xa4\x1e\xb4\x3f\xc1\x66\x82\x85\xd5\xfb\x85\x87\xf6\xdc\x59\x26\xa4\x57\x73\x0a\xd8\x05\x30\x36\x08\x46\xf0\x71\x30\xe9\x1f\x5a\x2e\xb6\xe8\xc9\x42\x4b\x87\x6a\x39\x45\xd8\x13\x78\x0b\xbd\xaf\x3f\x2d\xfd\x53\xe9\x03\x0f\x4c\xbc\x73\x0b\x6d\xbf\x57\xa9\x71\xee\x47\x02\xff\xcc\xc2\x1b\xac\xe6\x14\x5f\x2c\xb9\x6a\xd4\xdb\x45\xeb\x74\xe7\x72\xa8\xe2\x3e\xd5\x0f\xfe\x74\xa5\x03\x25\xcb\xde\x06\x45\x6b\x31\xf1\xf2\xb3\xff\x74\x62\x17\xd0\x5f\x87\x33\xd3\xd4\xd7\xb1\x32\xb3\x60\x0c\x1e\x5d\xb0\x08\x68\xf7\x8f\x6d\x46\x3a\xb6\x12\x44\x3a\x7e\x58\x11\x7c\x83\xb0\xc9\x65\xba\x06\x3c\x60\x11\x45\x4f\x64\x4b\x65\x5e\x04\x12\x24\x8b\x64\x31\x3a\xfe\xf9\x2f\x9f\x30\x20\xa7\x9b\x3a\x0f\xb4\xf1\x27\x65\x34\xa3\x6e\x61\x31\x38\x44\x9b\x16\xcb\x0d\x05\xe8\xcb\xc1\xf5\x66\xae\x5b\xbc\x2f\x50\x87\x31\x63\x99\xc2\x13\x1d\x65\xd7\xb3\xb0\x9b\xff\x52\x1a\x90\x92\x84\xd7\xcb\x3c\x47\xbb\x85\x84\x59\x63\x42\x9d\xb6\x59\xe4\x34\x79\xfd\x38\x73\x95\xc4\xab\x40\x23\x02\x76\xcd\x23\x62\x4a\x16\xfc\x77\x96\x55\x81\x5d\x97\x88\x62\xb9\x34\x13\x3b\xce\xd1\x1f\xa7\x68\x85\x6c\x48\xdd\x87\x70\xec\x7e\xc8\x61\x9a\xc4\x2e\xa3\x15\x9d\x52\x27\x35\x01\x4f\x2f\xb6\x12\x38\x9f\x7a\xa9\xb6\x59\xc5\x2d\x36\xa8\xd3\x61\xf7\x59\xf6\x7c\x38\x17\x88\xe3\x7a\xbf\x0b\xe9\xfa\x7e\x9c\xaa\xea\x57\x0e\xbb\x34\x2d\x2e\x80\x76\x38\xcb\x7f\xa9\x02\xf2\x6c\xd9\xdf\x0f\x7f\xd7\x28\xb7\x9a\x3a\x4a\x23\x9d\x8b\x74\x6c\xaf\x1a\xbb\x36\xc7\x2e\x1d\xda\xe6\xc9\x93\xdf\x69\x9f\x10\xdb\x04\xe6\xa8\x56\x96\xa8\xf8\x6f\xaf\xa8\x32\x7b\xc0\xde\x5f\xdc\xcf\x49\xac\x10\xa4\xb0\x8a\x64\x5a\xe8\xa2\x7e\x63\xa6\xa2\x57\x2b\xdc\x02\x25\xb9\x47\x5c\x2a\xb6\xfa\xa4\xd3\x96\x68\x0b\xb6\xb0\x7d\x40\x99\xa6\x56\xb9\x78\x6b\xf9\xf3\xa6\x22\xbe\x87\x16\x1b\xa3\x2c\xea\xaf\x28\x8b\xa0\x2b\x74\x3e\x0f\xe1\xfc\x8e\x54\x9c\x1a\x5c\x79\xef\x22\x26\x2f\x0d\x68\xf2\xbb\x21\xe9\xe8\xf2\x62\xbd\x9d\x06\xc0\x73\x25\x9a\x33\xa7\x84\xe1\x7d\x2b\xbf\x15\xc7\x1d\xb6\xe9\x3a\xda\x1e\x9f\x0b\x61\x9c\xbd\x66\x4a\xbb\x6c\xe1\xd1\x12\x11\x2c\xea\x70\x24\xbb\xb3\xa1\xd9\x09\xc5\x2a\x80\x86\x14\x4e\xf2\xf8\xb5\x06\xe4\x36\xe8\x2a\x21\xb2\x91\xd5\x0e\xf5\x2f\xfd\x50\x54\x1f\x3c\x72\x1f\xc4\x68\xa4\xb0\xef\x18\x19\x92\xb7\x0b\xf3\x9c\xda\x6d\xd8\x5a\x74\x52\xd7\x20\xc9\x7a\xb7\x53\x73\x19\x8b\x5a\x36\xc0\x4f\xa2\x33\xde\x5e\x82\xbf\xf6\x74\x46\x52\x3f\x97\xc0\xa1\x42\xe8\x07\x04\x06\xf8\x09\xb6\xe2\x82\x6a\x26\x13\x3c\x31\xce\x93\xb6\x8f\x52\xa0\x53\xec\x51\xa7\x97\x20\x7e\x26\x97\x4e\xf5\x8d\x65\xbf\x2b\xbf\x03\x91\x5c\xe9\xfc\xc2\x1e\x27\x18\x11\xa9\xd6\x84\xe2\x1a\xdd\xa6\xed\x2a\x43\x3e\x54\x8e\xbc\x43\xf7\x08\xb3\xbe\x05\xcc\x76\x46\x57\x2f\xdc\x49\x57\xd0\x32\x4c\x13\xbd\x5a\x42\x8d\x02\x81\xca\x17\x1e\xfa\xe2\x98\x14\xe1\x87\x4e\x8e\xd9\x5a\x5b\x40\x24\x58\x53\x6e\x6a\x83\x11\xe0\x38\x8d\x41\x98\x41\xbf\xa9\x13\x23\x88\x72\xf0\xdf\xfc\x34\xca\x35\x8e\x39\x6a\x32\x51\x53\x7f\xa8\x4f\xd6\x3e\x98\xc4\xac\xb4\x3f\xc3\x72\x04\x36\xc5\xa8\xa7\xaa\x3b\xbe\x48\xea\xcd\xcc\x89\x50\x18\x34\x96\xe2\x01\xfd\x32\x6c\x4c\x66\x13\x5b\x43\xf0\x06\xe9\x62\xe7\x7b\xcf\x17\x93\xf9\x9f\xd3\xad\xe1\xc5\x8d\xfa\x22\x51\x3d\x0a\xd9\xc9\xcc\xd9\xc0\x86\xe1\x66\xb5\x1e\x2e\x8b\xf9\xa8\xd9\x1b\xb8\xf1\x76\x52\x56\x54\x8a\x52\x7f\x68\x36\x24\xf9\xe7\x4c\xe2\x99\xc6\x01\x20\xe2\x29\xd9\xe0\x6d\x3e\x71\x96\x59\x1e\xc4\x5a\x2f\x49\xd2\x71\xbd\x52\xfd\x59\x28\x49\x5a\xaa\x84\xb3\xd3\x4d\xd8\x55\xf0\x6b\x8e\xd0\xeb\xb0\x3b\x5e\x42\xbe\x35\xd4\x5e\xd0\xb2\x87\xeb\x0e\xf9\x86\x9d\x09\x02\xef\xba\x88\x8b\x01\x19\x95\xb0\x4a\xad\xce\x2a\x92\x88\x5a\x23\x64\x3e\xb6\x1c\x5a\xb2\xfb\xc8\xf8\xd3\xcb\x96\x6c\xcc\x35\xc7\xaf\x4f\x40\x17\x44\x95\x24\x04\xb7\x07\xd8\xb6\x64\x5c\x9c\x38\x7b\x0b\xcd\x52\x46\x90\x5b\x3c\x88\xa7\x92\x8b\x40\x89\xb3\x45\x5e\xde\x5c\xb2\xc8\x28\x0e\x59\xa0\x96\xed\xaf\xb4\xcb\x8e\x10\x36\x89\xf6\x30\x77\xda\xa4\xc2\x81\xc9\xe9\x2c\x0f\xcf\xe2\x98\x97\xa0\xd6\x4e\xa0\xd0\x7e\x3f\x9c\x3c\x9a\x90\x59\x52\x20\x0a\xc9\xad\x20\xb3\x4a\x3f\x76\x2e\x21\x4a\x7b\x48\x7b\x95\xe5\x7b\x5e\x84\xd5\xd2\x7e\x75\xec\x47\x66\xe9\xf9\x3f\x3e\x4b\x64\x81\x1b\x91\x45\x72\x03\x4e\x95\xbc\xa6\x41\x1c\x02\x67\xdb\xea\x2e\x29\xab\x5d\xcb\xb7\x9a\x18\xe3\xbf\x70\x16\x2e\x74\xde\x7a\x84\x0f\xd2\x68\x67\xa8\xdb\x82\xcd\xea\x4f\xf9\x02\x1d\xa1\x88\x3a\x77\xa8\x5d\x7e\x37\x57\x42\x0e\xcd\x54\xbb\x8e\x30\xc8\xc8\x4b\xf3\x87\xc2\xdd\x0f\x56\x98\xf3\xaf\xbb\x21\xb2\x6c\xa0\xbc\x69\xee\x66\xa6\xf4\x2c\x09\x45\x92\x9e\xba\x27\xb5\x24\x75\x11\xc8\x74\xd4\x26\x17\x67\xc9\xc3\x81\xee\xdc\x70\x5a\x91\x3c\x31\x88\xff\x43\x35\xfe\xee\x8c\x3c\x41\x41\x1b\xf8\x7e\x83\x58\x98\x51\x63\x82\x85\x62\xa2\x30\x47\x0f\x05\xf5\x66\xb2\x8a\xee\xc8\x89\xa2\x94\x39\x52\x8e\xc5\x99\x5f\x2c\x27\x29\xe7\xf3\xb8\x8b\x26\xf0\xa7\x9e\x6a\xfd\xbe\x13\x0f\x90\x6f\xa7\x4f\x3a\xd7\x55\x75\xef\x2d\x51\x49\x6e\x5a\x89\xef\xa3\x56\xc8\x2d\x37\x2b\x3e\x07\x33\xd9\xfb\x97\xa2\xbd\x21\x93\x6d\x76\x15\xb4\xcd\x46\x4e\x2d\x3c\x69\x7b\xb6\xb2\x2d\x48\x35\x7b\x5a\x07\x95\xb1\xb0\x40\x2f\xf6\xcc\xd1\x85\x25\x42\x5f\xc7\xd7\x61\xc2\x43\xd3\xed\xf7\xe1\x1e\xb7\x38\xbd\x66\x1f\xcf\x49\x46\x40\x57\xcc\xfe\x08\x91\xbb\xff\xce\x44\x8f\x75\x09\xb4\xac\x28\xad\xc2\x32\x56\xdd\x0d\x08\x4f\x04\xe1\x21\x0d\x20\xee\x6f\x0c\x15\xf6\x88\xc3\xc1\xea\x21\x1c\x87\xc0\x1a\xfc\x18\x6e\x70\x34\x5f\x28\xf9\x32\x6b\x5b\x61\x1a\x48\x27\x9c\x12\x63\x28\x08\xa2\x30\xf5\x60\xd9\x54\x04\x65\x5e\x11\x6c\x62\x12\x6e\xee\x5c\x9f\x3f\xa8\x89\x91\x39\x19\x9f\x2f\xc5\xb4\x49\x94\x29\xc7\xd1\xe9\x7b\xbd\xf6\x4c\xa8\x07\xc8\x66\x14\x7e\xd5\x08\x06\x5f\x86\x15\x76\xb8\x4e\xa5\x59\x51\x2f\xf0\x53\x9f\x55\x67\xc5\x42\xd6\x4e\xca\x1b\x7b\xd0\xc4\x42\x6f\x8d\xd5\xcd\xd8\xd2\x84\x9a\xdb\x04\xd3\x61\x61\x4d\xb4\x50\xf4\xe7\x26\x9c\xbb\xa3\xb1\xc9\x51\x9e\x38\xd8\x5a\xcd\x0a\xb2\x62\x49\x69\x32\xbb\xa0\x16\x5d\x38\xfa\x2d\x43\x28\xdc\xfc\x57\x94\x18\x7b\xc1\x05\x5d\xc6\xc5\x8e\xb2\xd4\xc9\x03\xdd\xd5\x5f\x85\x33\x13\x53\x42\x33\x96\x83\x50\x71\x66\x2b\xf8\x26\x25\x87\x9e\x91\x0e\x44\x0e\xed\x41\x24\x6d\x6f\x31\x49\x89\xfe\x94\x60\xff\x87\x18\xf5\x43\xb9\xff\xbb\xac\x82\x87\x1f\x59\x4d\x8e\x96\x97\x32\xed\x3b\xb2\xc2\x84\xc5\x1c\x3c\xdb\xaf\x88\x7a\x4f\x82\x9a\x54\x1d\x85\xd1\x34\x4b\x45\x3b\x00\xdf\x41\xe3\xad\x35\x24\x85\xb4\xb0\x81\xae\xb0\x47\x4c\xa8\xba\x28\xef\x2e\xcc\xa4\xe3\xee\x5a\xf9\xcc\x82\x9c\x26\x2e\x72\xb7\xc7\x24\x96\x7c\xb1\x41\xa6\xc7\x7e\x20\xe3\x22\xc2\x70\xf7\xd6\x84\xf0\xcb\x66\x60\xc9\x0e\x3b\xde\xa2\x16\xda\x77\x37\x7e\xae\xfd\x45\x2a\xd3\xa8\xf9\x88\x01\x8c\xc2\x98\xe2\x4f\x8a\x96\xf2\xac\x45\xfb\xe9\x22\x55\xbd\x47\x48\x37\xee\x35\x91\xe5\xf1\xb8\x3a\x44\x1a\xcf\x18\xa6\x20\xbd\x49\x83\x5c\x3c\x5e\x64\xaa\x5a\xd9\xcf\xbe\xd3\xe5\xad\x22\x5b\xb1\xc3\xef\x2e\x3a\x31\x53\xc5\x9b\xc4\x86\x64\x55\x14\x4b\x7b\xc9\x2e\x88\x70\x59\x2b\x33\xa6\xab\xde\x89\x72\x9a\xae\xeb\x98\x24\x25\x3b\x4d\x6f\x69\x30\x4f\x77\x7e\x45\x1e\x1a\x33\xaf\x5d\x3d\x98\xae\xe5\x7c\xb2\xf9\x7a\x40\x20\xf7\x08\x7e\xa4\x3a\xf0\xf0\x24\x70\xfa\x6c\xb0\xde\xb9\xd4\xfd\x53\x8a\x08\xfb\x67\x5e\x0f\x62\xff\x22\x57\xa0\x0d\x4d\x8d\x2d\x54\xbf\x1b\xe2\xe3\x28\x35\x51\x1e\xc9\xb5\xe1\x79\x18\xa0\x6f\xc1\x43\xc3\xce\x49\xdc\x5c\x0f\xc5\xab\xae\xda\x07\x0f\xff\xc6\x22\xda\x71\x3f\xe1\xca\x24\x76\x39\x65\x2a\x7c\xdb\x41\x08\xe8\x52\x1d\x23\x20\x0b\xb7\x45\x83\x3c\xb8\x58\x2a\x95\x92\xa4\x10\x72\x69\x35\x23\x11\x77\xfd\x32\x88\x73\x36\x4a\xe6\xfb\xff\xe4\x7f\xcf\x2e\x26\x26\x31\x1a\xdb\x6c\xe6\x30\xe4\xf8\x8f\x04\x69\xdc\x10\x2b\xef\xc5\x92\x22\x2e\xbb\xb3\x61\x95\x3d\xd8\x55\x6d\x28\xab\x52\x8c\x4b\x50\xd1\xf2\xc1\x18\x6c\xb1\xb9\xcf\xf3\x0f\x87\x4a\x3a\xcf\xa5\x27\x1b\xd7\xc5\xc1\xb5\x5b\x8e\x88\xeb\x46\xcd\x88\x80\x7b\x26\xb3\x90\x81\x11\x96\xaa\xf2\x8d\x9c\xb6\x3c\x91\x52\xea\x81\x1e\x0b\x2c\x14\xe4\xa0\x78\xe5\x8d\x14\x11\xe5\x7b\x54\xbe\xa5\x75\x28\x7d\xf0\x64\xf3\x9d\x4e\x61\xaf\x8c\xbd\x00\xb2\xc2\x57\x31\x73\x5c\x1a\x42\xf7\x41\x88\x82\x24\x4d\xa7\xf5\x1d\xfa\x39\x13\xd1\x0f\x74\x84\x32\x0d\x20\xff\x42\x3d\x20\x6a\xea\xb2\xdf\x7b\xb6\x38\xdb\x35\x7d\x18\xa8\x4c\x74\xb2\x66\xd5\xbb\x16\xfa\x8a\xcf\x5c\x24\x15\x94\x86\x1a\x05\xab\xcf\x9f\x10\x19\x8c\x8a\xb1\x4a\x7b\x61\xf8\xb4\x5d\xd9\xd2\x03\x1c\x5c\xf3\x6f\xa1\xc2\x87\xec\x46\x38\xc5\x1a\xa4\x7a\x04\xe5\x28\x5c\x06\x9e\x63\x7e\x65\x52\x23\x22\x5a\xb3\x14\x68\x65\x32\x62\x9d\x5a\x48\xe8\xf0\xa0\x36\x26\x59\x60\x52\x12\x9e\x97\x12\xf5\x8a\x70\x53\x68\x6a\xc0\xe5\x3f\xaf\xec\x85\x74\xf4\xa0\xb7\x22\x70\x3c\x59\x35\x87\xbe\x80\x07\x3b\x8a\x14\xee\x8d\x17\xab\xa4\x96\xbf\x28\x84\x36\xba\x4e\x5d\x07\x80\x1d\xc2\x11\x6b\x00\x92\x97\x64\x9a\xb3\xb4\x45\xa4\xa0\xb6\xc7\x07\x12\x5f\x60\x7b\xbe\x4a\xa5\x48\xa0\xc8\x9f\x0d\x48\x45\x4a\xb5\xf3\x55\x08\xdb\x43\x88\xd7\xc1\x2c\x44\x83\xca\xad\xb0\x5f\x7f\x5d\x02\x00\x07\x3d\x8a\x07\x2b\xf1\x22\x36\x26\xba\xe0\x86\x48\xcb\x93\xb4\x66\x83\xc2\x60\xbf\x96\x81\xbb\xfb\x1d\x26\x41\xaf\xdc\xdb\x5d\xa2\xc1\x75\x58\x82\xa2\x06\xe6\x84\x35\xce\xc5\x4e\x10\x6f\x0e\x3b\xda\x1b\xd8\xe6\x18\x12\x03\xa6\x43\x39\x89\x77\x1f\x52\xa0\x22\xe4\xe4\xf9\x18\x20\x40\x85\xe6\x42\xf0\xa3\xd9\xc0\x52\x33\x05\x54\x49\xad\xc1\x67\x58\xc6\x7d\xc4\xc3\xec\x3c\x43\x3d\x19\x14\x5e\xf0\xbc\x05\xcb\x36\x6c\x64\x3b\xee\x30\x0b\x64\xc2\x67\x6f\x65\x67\x60\xfd\x0a\xaa\xcf\x21\xc9\xa5\x83\x89\xe1\xde\x34\x8a\xc8\xb4\x24\x35\xaf\xd9\x43\x21\xca\x34\x56\xce\x2f\xfe\xa3\x72\x07\x7b\x48\xcf\x46\x60\x8e\x56\x0b\xbb\x09\x5c\xa5\x7b\x13\x5b\xcb\xbf\x3a\xa4\x87\xfa\x6b\xfa\xea\xbd\xe9\xaa\x56\xaf\xd1\x69\xe5\x11\x38\xbd\x28\x6c\x2a\xe3\xb4\x2d\x04\xd8\x1a\xd9\x97\xd1\x34\xe3\x77\xd1\x98\x7c\x3f\x1a\x95\xda\xb3\x77\x3a\xe5\x70\xe0\x5f\xea\x84\x04\xad\xf7\x5b\xab\x62\x33\x98\x60\x40\x63\xa7\x4a\xdc\xd7\x14\x42\xa6\x76\xf0\xe1\xc0\x68\x20\x3b\x17\x2f\x54\xc7\x04\x13\xab\x95\x15\x67\x4f\x42\xe5\xfa\x08\xc5\x90\xd0\x72\x93\xf4\xd0\xff\x01\x6b\xdd\xd4\x8a\xc4\x0e\x63\x8a\x97\x32\x13\xbe\x9b\x93\x02\x0e\x37\x21\x4f\x0a\x0a\xd0\xd2\x9a\xa1\xec\x52\xad\x5f\x12\xaa\xd8\x0b\x73\xa3\x89\x6d\x84\xf1\x34\x99\x9b\x8f\x36\x23\x24\xe3\x0c\xcf\xa7\xe0\x3e\xd8\xcd\xbe\x78\x92\x60\x75\x6b\xa0\x88\xad\x63\xfd\x50\xcb\xc7\x1c\x54\x54\x4a\xf0\xea\x5e\x23\x21\xf9\xc8\x23\xab\xbe\x50\x8a\x63\x25\xb8\xff\xa3\xd8\xc2\xcb\x04\x22\x94\xf7\x81\xc0\x0c\x9b\xbf\x8b\xa3\x93\xa1\x12\xc5\x23\x6f\x7e\xe8\x3f\x16\x70\xb7\x56\xcf\x6a\xcc\x03\x65\xd8\x99\xb8\x06\x42\x38\x4f\x9a\x50\x99\x4b\xd4\xce\x5f\x52\xf8\xfe\xe5\xbc\xa9\xad\x99\xa7\x42\x2c\x05\x4a\x43\x08\x7b\x2d\x82\xfc\xc8\x7e\xa4\x2d\xdb\x43\xc8\x80\x12\x61\xd1\xcf\xf4\x4a\x60\x52\x88\x0b\x81\x6b\x18\x91\xbb\xd4\x49\x78\x43\xd9\x36\x4c\x93\x7b\x94\xbf\x92\x4e\x9f\xd4\x8d\xd0\x69\xb2\xc5\x46\xce\x53\x28\x4a\x01\xfa\xfa\xcd\xfd\x79\x04\xa1\x7a\x11\x7f\xed\xa8\xe1\x2c\x85\xa5\x25\xb5\x3e\x8e\x69\xeb\xc2\xed\x3b\x5e\x43\xc7\x8b\xd4\x87\x6d\x23\xba\xa3\xa4\x6c\x49\x6e\x5b\x78\x2c\x79\x72\xfe\x3e\x27\xc3\x80\xb9\x86\xe2\xd7\x6c\x29\x52\xe0\x6d\x35\x93\x8a\x18\x85\x21\x28\x2f\xe3\xab\x4f\x28\x02\x89\xab\x12\x6d\xdc\x94\x98\xe7\xdb\x04\xe7\xcd\x35\x90\x83\xdb\x63\x0e\x41\xb7\x1f\x6a\x2d\x2a\x27\x7c\x1a\xd4\x5e\xf6\x56\xe7\x52\x55\x4f\x35\x7a\x2f\x35\x47\xcf\xc9\x40\x4b\x62\x77\xa5\x92\x15\xc6\x29\x7c\x45\x24\x68\x50\x1e\x35\x02\x45\x52\xd1\x5e\x62\x50\x67\x4b\x76\xde\xfb\xa6\x25\x39\x32\x3e\xd0\x36\xc3\xd5\xa9\xfe\x34\x23\x03\xcf\xb2\x89\x80\xba\x30\x82\xe4\xc0\x0e\x42\x2f\xfd\x33\xb2\xe1\x43\xd1\x9d\x46\xf1\x49\x9d\x91\x74\x31\xe6\x1e\x6b\xd9\x29\x7e\x02\x0d\x73\xe1\x2f\x0b\xe9\x20\x76\xb0\x37\xbe\xe0\x7a\x95\x96\x78\xe9\xd8\x00\xca\x68\x5d\x34\x59\x33\x06\x21\xa5\xb4\x65\xd7\x08\x14\x18\xb0\x49\xdd\xd3\x23\xc1\x18\x4c\xb4\x9c\x31\x9a\x60\xca\x6c\xfb\xf0\xaa\x43\x50\x4c\xfb\xcb\x3b\x10\x87\xeb\x32\xb3\x71\x0c\xe5\xc2\x99\xfe\x85\x90\xc0\x28\x29\x67\x1e\x5e\x8b\xa6\x49\x05\x2b\x33\x9f\x5a\x45\x1a\x9a\x8b\x22\xc6\xbc\x8b\xe5\xf3\x58\x17\xa6\xeb\x24\x5e\x5c\x45\x10\xb6\x82\xc4\xaf\x76\xb0\x47\xb0\x4b\xa8\x10\xc3\x09\xf1\x96\x68\xda\x90\x4a\xac\x38\xff\x27\x41\x27\x08\xb5\xed\xd8\x6f\x46\x11\x1e\x7f\x45\x8b\xbd\x1d\x33\xd5\x2e\xe2\x25\x59\x62\x9c\x14\x5f\x76\x1e\x4a\x44\xed\xfa\x14\xca\x2e\xc9\x16\xe1\x38\xd3\x57\x39\x15\xb9\x9d\xb3\xa8\x19\x43\x4e\x93\x04\x40\xc6\x68\x52\xdc\xa2\x72\x94\x3e\xe4\x39\x8c\x41\x02\x83\x05\x46\x25\x31\x34\x96\xa8\x91\xac\x92\xd8\x2d\x4a\x9a\x6e\x0e\x2e\x70\xc2\x4f\x1d\x7e\x2b\x3a\x1b\x2e\x8e\x96\x7c\x59\x08\xf6\x65\x8d\x20\x09\x11\x6e\x3d\xe0\x3b\x82\x65\x92\x9a\xcd\x85\x3a\x72\xc9\xda\x08\xa6\x7b\x6c\x22\xfe\x59\xca\xe9\xec\x1b\x8d\x46\x58\xc4\x00\x71\x82\xba\xc2\xbe\x31\x54\xb1\x9b\xe0\x0b\xa3\xad\xad\x15\x79\x0f\xc5\x34\x2e\x36\xad\x54\xd7\x6b\xad\x8c\xba\xc0\x26\x50\x09\xe3\xc8\xdc\xa4\x05\xe3\x6e\x1e\x31\xf9\xe7\x47\xc5\x98\x3b\xed\xa2\xf9\x20\x09\x7e\xf5\xad\x6e\x1d\x43\x2f\x58\x7d\x20\x3e\xa5\xb1\x77\x22\xa5\x47\x91\xee\xa6\x3a\xbf\xaf\xc9\x7f\x67\x55\x75\xca\xcc\x44\xff\x91\xfa\x08\x55\x50\xbe\x98\x7d\xac\xad\xbd\x5a\x14\x11\x55\x24\x35\x49\x0a\xb6\x1b\x94\x36\x23\xc4\x93\x1b\x82\x32\xb1\x48\xd6\x85\x71\x00\x4a\x6c\x98\x50\x72\x34\xfe\xa4\x39\x1e\x75\xda\x51\x7b\x62\x68\xef\xa0\x1b\xbf\xb4\xd0\xda\xc9\x42\x4d\x4e\x93\x1a\xe2\xa1\x34\x93\x25\x62\xe3\x8d\x81\xbf\xb7\x86\x7e\xde\x22\x09\x67\x08\x57\xa5\x03\x65\x1b\x10\x4a\xdd\xa9\x17\x11\x16\xbf\xeb\xc7\xfd\x7b\x9f\x54\xed\x78\x95\xd6\x4a\x4b\x68\x45\xba\xef\xfe\xe1\x6d\x8a\x50\x6f\x07\x50\x64\x2a\xb3\x98\x78\x43\x9a\xd3\x80\x2b\x1c\xba\x10\xf5\xbd\xe5\xb4\x3f\xa9\x0b\x79\xf7\xa2\x2a\xe1\xe0\xdf\x46\xd7\x9f\x53\x93\x07\xe6\x83\x80\x6b\x0c\xa0\xaf\x0e\xb2\x26\x94\x9d\x56\x5c\x84\xfb\xa5\xb8\x23\x92\x7d\xe2\x06\xed\xdf\xbb\x4b\x91\xde\x89\x87\x0c\xa6\x2d\x76\xd4\xec\x2c\xbd\x20\x24\x0f\x9b\x16\x5c\x62\x92\x83\xa9\x6e\xcc\x03\x34\x70\x68\x43\x1f\x5c\x9a\x54\x0e\x92\x0d\x54\xc7\x09\x74\xb9\xb0\xe0\xb5\x69\x20\x79\x67\x1e\x4b\x1f\x16\xbd\xb0\x3f\xa2\x78\x1d\xb8\x55\xbe\xdc\xbe\xa6\xa6\x0a\xe2\xfd\x06\x3a\x15\x3e\xee\x4c\x79\x4e\x7a\x6d\x95\xb0\x07\x05\x24\xd4\x10\xdb\x9a\xc0\x54\x79\x6e\x3a\x27\x4d\x4c\x10\x89\xf2\xa8\xe2\xc5\xb2\x07\x93\xfa\x20\x28\xb8\x06\x8d\xaf\xfe\x7e\x1e\x70\x6d\x3e\xaa\x90\xe3\x75\x5c\xe8\x8c\xdd\x05\x85\x65\x64\x86\x8a\x44\xdb\xda\x89\x13\xbb\x62\x59\x2c\x76\xee\x23\x56\x05\x79\x80\xe0\xf3\x97\x68\x9a\xbf\x08\x51\x4f\x06\xbf\x78\x80\x09\x3d\x20\x76\xa0\xd3\x62\xb9\x59\xb4\xc0\x69\x9a\x4d\x65\xfd\xb5\xfe\x59\x32\x7f\xf9\x7c\x8a\xe6\xe4\xb1\xdb\x19\x59\x33\xe2\xa1\xa0\x82\xc3\xa1\x7c\xcc\xa6\x92\x2f\x4b\x0f\x71\x91\xc0\xef\x32\x1d\x90\x55\xfd\x42\x8f\xba\x14\xf2\xc2\x39\x45\x70\x9b\x3a\x62\x1d\xe6\xd0\x65\x2d\xdf\x0d\xe0\x15\x5d\xe3\xce\xc5\xda\x72\x50\x68\x57\x4e\xb7\xec\x4e\xea\x90\x27\x94\xe2\x30\xc0\x91\x1a\x36\xd4\xd9\x8d\xb3\x1b\x11\xdd\x7c\xb5\x00\xf7\xb2\x65\x29\xc4\x7f\x49\xe0\x29\xad\xaf\xdd\xc5\x1e\xa4\x97\xfe\xab\xba\x75\xb6\xeb\x6a\xee\xb7\x9d\xa0\x41\xed\x17\xd0\x1f\x90\xb5\x71\x2a\x0d\x0f\xbc\x57\x9b\x95\xa5\x77\xb5\x52\x1f\xfa\xcd\xda\xee\x2e\x48\xb7\x77\x4d\x50\xa5\x9c\xf6\xbc\x93\xfa\x5c\x24\x3a\x96\x96\xd1\x2b\x1c\xe2\x7e\x5d\x38\x6c\x28\xe7\x42\x36\x19\x27\x04\xcd\x4a\xda\x19\x8e\x50\x76\x98\xbd\x0a\x6f\x15\x8b\x75\xf7\x36\x96\x9d\xda\xe4\x8d\x55\xf3\xa0\x6f\xc1\xc4\xc5\x38\x16\x98\x36\xc4\xd2\xb3\x9c\xab\x8b\x0f\xd3\x47\xec\x4f\xce\x40\xb9\xd4\x4e\x07\x56\x8a\x86\x96\xe5\x31\x2b\x38\x97\x2f\xa1\xa1\xdd\x2b\x77\x33\xb1\x56\x4a\xf8\x2d\xbd\x98\x2c\xb3\x07\x7e\x79\x52\x95\x76\xdb\x55\x90\xf0\xcb\xa9\x03\x04\x0e\x33\x0f\x0a\xe1\xae\x63\x83\x4e\xb4\x3c\x51\x1b\x63\x18\xdd\xf8\x2e\x72\x7e\x4a\xe5\x5c\x75\x4c\xc4\x7d\x61\x56\x4f\xdd\x7b\x81\x37\xd3\xf9\x54\x5f\x47\x52\x71\xa6\x8b\xf9\x48\x80\x09\x23\xea\x01\xfe\xce\xb7\x99\x6a\x12\x6a\x43\x08\x9f\xda\xc2\x64\x08\xdc\x69\x5e\x21\x08\x14\xdc\x94\xf5\x94\xd1\x9d\x4a\xf7\xe5\xc1\xcd\x6a\xac\x2e\xca\x85\xbf\x4c\x6d\x0a\xae\x84\xab\xd4\xc2\x62\x01\x1c\xbb\x37\x82\x2a\x2f\xd9\x62\x75\xcc\x2c\x12\xbf\x93\xba\x97\x9c\x8a\xfd\xfa\x00\xe0\x43\x41\x60\xd8\x24\x1c\x0b\x89\x09\xde\xc5\xdc\xc6\x6a\xf9\x99\x25\x32\xe9\x1d\xde\x61\x0c\x43\x0d\x7f\x6f\x83\x69\xd4\x04\x5d\x64\xce\x9c\x9d\x12\xe5\xc7\x36\xd9\x66\x0b\xef\xd6\x9f\x7f\x79\x1e\x74\xe3\x2d\x48\x4e\xca\xc9\xfb\x88\x5d\x64\x91\xd4\x28\xd2\xab\x64\xa8\x59\x38\xbc\x89\x76\xb7\xd8\x0d\xc3\xe6\x27\xf0\x6c\x82\x8b\xa5\x1a\xa7\x37\xef\xb7\xb4\x19\xb0\xbd\xea\x7f\x54\xbf\x77\x1d\x59\x78\x84\x81\x87\xd7\x7b\x9c\x68\xf2\x04\xdb\xbb\x78\xba\x54\xaa\x38\x7e\xe6\xb1\x91\xae\x70\x8f\x30\xce\x1c\x26\x60\x85\x83\x4d\x6d\x0e\x70\x6f\x34\x65\xd0\xd7\xc0\x53\x48\x6d\xfa\xa3\x85\x69\xb0\x1d\xef\x50\x7f\x46\xb3\x9f\x25\xa7\x7a\x54\x7b\x4b\xa7\xa4\x08\x6f\xb0\xbc\x68\x2b\x9c\xaa\x88\x38\xbd\xe9\xbf\xaa\x48\x16\xb7\x12\x2a\x46\x41\xba\x5d\xf3\xd5\x01\x74\xa3\x2e\xe3\xd5\xbc\xfe\x93\xa2\xdd\x17\xc3\x6f\x14\x59\x46\x93\xcb\xe8\x24\xef\x2a\xbc\xfa\x1e\x53\x28\xcc\xc8\xb7\x36\xe2\x4d\xe0\x70\xba\x8b\xf0\xec\xe2\x80\x38\x30\x2d\x74\xf2\xb2\x58\xd5\x98\x93\x98\xb8\xe0\x7f\x32\x10\x75\x90\xb8\x69\xc4\xaf\xa4\x8d\xb8\xed\x3f\x4a\x0c\xad\x6c\x3a\x51\xef\x00\x8f\x2c\x10\xfc\xef\xa4\xa1\xda\x3f\x73\x57\xc5\xc6\x96\x6a\xc2\x9a\x34\x50\xcc\x2d\x31\xa5\x1b\x65\xc2\x52\x04\x61\x54\x78\x9e\xa3\x94\xf5\xe1\x08\x82\xa3\x29\xba\xef\x92\xf1\xd9\x13\xb5\x4b\x37\xa9\x77\x78\xf5\x97\xa6\xc4\x7c\x6c\x63\x90\xb2\xa9\x60\x0c\x4e\x9d\xe7\x80\x9e\x01\xd2\xb6\x02\x29\x9d\xce\xfe\xa3\x94\x21\x4d\x02\x9b\xae\xb8\xa4\xf3\xbc\x43\x7c\xc1\x16\xbd\xde\x38\xaa\x47\xb8\xc0\xf9\x78\x68\x90\x5a\x15\x75\x7d\x17\xfd\xeb\x6b\x05\x6f\x68\xd6\xc7\x8f\x7c\x82\x6c\x2e\x09\x0a\x68\x05\xf3\x79\x38\xd5\x95\x91\x05\xe5\x07\x1a\x1f\x76\xd7\x5f\x1e\xa2\x96\xbc\x23\x8a\x06\x83\x86\x3f\xbe\x5f\x26\x1b\x71\x1a\x3e\xe8\xbf\xd3\x1b\x86\x8b\x1a\x1f\x1e\xb7\x7f\xc4\xcd\xe4\x2f\xff\x25\x22\x36\x39\xb6\x9b\xc2\xe4\xa5\xb4\xb4\x9d\x17\x16\x5e\xcd\xf9\xc9\xaa\xd9\xc5\x0c\xa0\x89\x24\x01\xfc\x50\x73\xd5\x76\xfc\xd0\xcc\x74\x0b\xf5\x15\x95\xc4\xef\xed\x61\xfb\xb4\xdd\x79\x4c\x9c\x24\xc1\x66\xa0\xee\x32\x09\x6c\xb5\xd7\x89\x98\x04\x2f\x4d\x0d\x8d\xf9\x49\x72\x01\x16\x06\x37\xec\x1c\x18\xc6\xd7\xe4\x4f\x94\xaf\xd4\x5d\x97\x1d\xfe\x56\x3c\x33\xf5\xac\x10\x99\xf9\xde\x35\x7e\xd1\xce\x7f\xc8\x6e\x86\x4c\x1f\x46\x6b\x84\xb6\x48\x21\x14\x19\xa0\x1e\x8f\x8e\x86\xe8\xf5\x6c\x23\xdb\x62\xa5\xbe\xa9\x32\xe9\x0d\xc9\x06\x0d\xe3\xa7\x4b\xa4\xe4\x22\x23\x99\xfd\xa4\x82\x67\x6b\xdd\x38\x54\x64\xa2\x04\x94\xe6\x25\xad\xda\x40\x59\x2d\xbb\xf8\x1d\x23\xcf\xe8\xf9\xe5\xf3\x38\xdd\x58\xc8\x04\xa3\xb0\x08\x3e\xf1\x08\x90\xeb\xe4\x1d\x70\x25\x09\x5d\x2c\x3b\xfe\x3b\x9b\x4f\x51\x8f\x60\xce\x4e\x5d\x22\x5b\x62\xf5\xca\x59\x48\x94\x42\xfb\x7e\x91\x6c\x96\xf7\x45\x4b\xb2\xb4\xf6\xd1\xb6\xed\x6a\x44\xbc\x04\x2f\x26\x89\xce\xea\x7b\xe8\xd5\x2e\xbd\x16\x1e\x2d\xd2\xf4\xfd\xa3\xc8\x70\x44\xfe\x12\x2c\x48\xc1\x38\x7e\xe2\xa3\xe7\xde\x52\x27\xc1\x2a\x28\x95\xee\xd1\x2c\xc7\x2a\x1c\x31\x46\xa7\xd8\xe8\xa9\xca\xde\x86\x8d\x85\x3a\x1f\x41\x0a\x5f\x47\xc6\x54\x0f\xc9\x07\x6f\x6a\xad\x53\x2f\xce\x57\xc2\x8c\x75\x98\xc9\x47\xb0\x2b\xb9\xcb\x3e\x69\xbe\x41\x5a\xaa\xcf\xf0\xe5\x4e\x0f\xaa\x70\xdb\xa1\x55\x61\xd2\xe7\x96\x70\x35\x1e\xad\xc8\x69\x17\x97\xb8\x01\x05\x29\xf8\x35\xe5\x5b\x60\x97\x02\x07\xfc\x02\xe1\xd1\xd9\xa3\x9b\xe9\x7c\x27\x31\x0e\x42\x33\xc9\x05\x68\x39\xac\xb8\xbc\xfc\x47\x53\xcc\x55\xab\x6a\xb2\xe2\x8c\x1b\x8b\xbb\x73\x3a\x6f\x82\xbd\x63\x7a\xad\x48\x79\x89\x48\x8e\xd3\x2c\x06\xe1\x7c\x14\xd6\xb2\x5f\xa2\x64\xda\x22\x5f\xcc\x28\xaf\x95\xa7\x31\xc2\x6d\x22\x00\xde\x24\x1f\x36\xcf\xac\x7b\x58\x19\x0b\xbf\x81\x29\xc5\xee\xea\x7e\xcc\xdd\x45\xdf\x76\xf5\xd8\x4e\x83\x7a\x91\x42\xbc\x52\xcc\xc1\xd9\xb2\x1c\x49\x2b\xcd\x98\xb5\x4d\xaa\xb9\x38\x1f\xee\x86\x6a\xef\xe1\xb2\x74\x2b\xca\xb0\xe9\xd3\xb5\x78\xe7\x1f\x99\x2e\x9f\xee\x09\x75\xe0\x4b\xf0\x26\x99\x09\xa2\x71\x70\x10\x86\xfe\xd5\x11\xd4\xab\x47\xd2\x17\xa1\x0b\x40\x2b\x6d\xcf\x28\x0a\xba\xb2\x89\x4a\x17\x49\xfd\x40\xfb\x11\x4a\x5b\xe5\x57\x43\xb5\x55\x47\xf5\x01\x2e\x53\xd6\x04\x19\x6a\x96\x2a\x4a\x90\x9e\xa5\xd9\x4f\x4d\x67\xf0\x0b\x91\x85\xd5\x5a\x66\xd3\xe9\xec\xd6\xab\x7d\x02\x83\x99\xed\x53\x6a\x8c\x40\xd4\x18\x3c\x68\x90\xf3\xa8\x99\x23\xde\x22\xc2\x3a\x02\xe1\x84\xe9\xde\x9a\x96\xe4\xcc\x9c\x11\x24\x2e\x6c\xfd\x03\xe1\xa4\x22\x5e\x0e\x38\x9f\xce\x6e\xd7\x19\x46\x85\x20\xc4\xc3\x97\x50\x97\x04\xae\xad\x25\x79\x5c\x0c\x0f\xc6\xf2\xfe\x09\xb6\x8d\xea\xef\x83\xfd\xe6\x82\xb9\x89\x52\x3b\xa1\x25\x39\x83\xb8\xcd\xec\x8e\x08\xe4\x8a\x36\x04\x44\x23\xd9\xd3\xfb\xc4\xce\x54\xb3\xdd\xf0\x23\x7d\xd0\x6b\x45\x85\xbe\x11\x9f\x9f\xb9\xf0\x48\xcf\x98\x91\x0d\x27\x8b\x8c\x13\x23\x72\x8c\x7b\x0c\x1a\x97\x93\x09\x9a\x1e\x0d\x75\xba\xf6\x7f\x4e\x94\xdc\x2f\x2d\x01\xd1\xd8\x1f\xcd\xc3\x53\x96\x1d\x55\x1f\x8b\xc4\x34\xb4\x84\x3b\xd7\x5a\xb6\xfd\x2f\xb7\xab\x46\x7d\x63\xc4\xf1\x6f\x54\xc9\xb8\x60\x78\x52\xbc\x53\x53\x2c\xbf\x36\x13\x1b\x86\x68\xfb\x1a\x0b\x14\x3d\x5f\x20\xba\xb4\xfe\xb4\x90\x2a\x88\x49\xbd\x5a\xe8\x92\xef\x1a\x5c\xee\x6c\x23\x86\x44\xf6\x40\x0c\x60\x88\x49\x6f\x6a\xb1\xdc\xc2\xc7\xac\xe5\xc1\xa8\x9a\xd8\xa7\x6d\x40\x08\xcb\x33\xbd\x63\x45\x07\xcd\x13\xb7\xff\x49\xb5\x1a\xd9\x2c\x14\xde\x15\x14\x7a\xab\x12\xad\xd5\x67\x55\xbd\x74\x85\x71\xde\x38\xe5\xc6\xf3\x34\xea\xfb\x34\x4e\xc7\x2c\x2b\x13\x44\xc3\x62\x51\x05\xd6\xcd\x91\x78\x16\x7e\x9a\x5e\x09\x6f\xb1\xd4\xcb\x43\x8b\x3e\xcd\x51\x14\x4f\xd3\x81\x4d\x47\x73\x23\xd7\x53\x7a\xa1\x4c\x5d\xca\xa2\x19\x6d\xde\xbc\xcb\x2d\x91\xf4\x50\x6f\x81\x25\x83\x9f\x43\xc2\x80\xec\xad\xc3\x6f\xda\x9f\x92\x9a\x51\xa1\x3e\xda\x0b\xe9\xe2\x28\xc4\x2e\x5c\x6e\x54\x05\x13\x43\xbc\x98\xd5\x06\x0f\xfb\xef\xdf\x8f\x36\x8a\x23\x15\x38\xf7\xb4\x0b\x3e\xb2\x0f\xe4\xda\x55\xd0\x03\xc9\x3d\xd8\x6d\x9b\x86\x87\x6d\x79\x84\x85\xa6\x38\xdf\x75\x66\x89\x4d\xf8\xe8\x1f\x66\xa3\x53\xe6\x0b\x10\xb0\x53\xe2\xf7\x25\xd5\x8f\x4a\x7c\x50\x14\x2c\x98\x68\x87\xcf\x5c\xe9\x9d\x3c\x21\xd4\xe3\x84\x2d\x34\x6f\xf0\x64\xa5\x83\x60\x99\xc3\x42\x1c\x35\x89\x34\x31\xba\x7f\x42\x44\xd4\x8b\x01\x73\x54\x30\x1c\x8a\x1b\xb8\x67\xa3\xba\x14\x58\xc3\x13\x76\x90\x34\x35\x3d\xa2\x0a\x9d\xf2\x45\x23\xc2\xa6\x13\x73\x05\x3a\x75\xa6\x1c\xe4\x5c\xa0\xa2\x26\xba\x1e\x29\x77\xa7\xa4\xf1\x49\x29\xf6\x82\xcb\x57\xf1\x51\x6a\xaa\x78\xcc\x91\x75\xe1\xbb\xf3\x7c\x02\x43\x76\x7e\x61\x2f\x3f\x1c\xcd\xac\x1e\xf2\xf3\xd4\xb7\xc1\x75\x7c\x22\x11\x33\x16\xf1\x3f\xbd\x6b\x1b\x12\xa6\x81\x56\xd9\xb2\x23\x6e\xa1\x4c\x4e\x6b\x22\x0f\x72\xa3\x10\x41\x9c\xb1\x72\xe8\x9e\x5e\xd6\xc8\x5f\x00\x86\xa1\x47\x90\x66\x1e\x4e\x2b\x09\x84\x5e\x97\x06\xc7\xd9\xe7\xfa\x30\xf5\x29\x40\x29\xa2\xd6\x1f\xbd\xbc\x64\x81\xe9\xa5\xcd\xee\xd1\x22\xf7\x13\x67\x29\x7c\x38\x44\x49\x1d\x62\xef\x36\x6d\xe6\x38\x3b\x26\x88\x2d\x32\xda\x29\x52\xbb\x12\xb7\x5f\xe9\xe6\x16\x0d\x61\x1b\x13\x87\x9f\x4f\x4d\xb1\xad\xf5\xe8\xe2\xc6\x4b\xbd\x26\xdd\xd1\xed\x79\x8b\xde\x47\xa6\x14\x73\x89\x8a\xe9\x9b\x0a\x7a\x39\x08\x36\x97\xac\xbc\xff\x0d\x23\x29\x89\xbc\x9d\xd2\x81\xf1\xb1\x59\xbc\x69\xc1\x9b\xdf\x92\x04\x5e\x96\x4f\x6b\xc1\x13\x47\xdd\xa5\x38\xb1\x23\xb3\x9d\xaa\xc2\x1e\x02\x34\x4c\x30\x42\xab\x0a\x14\xb6\x43\x63\x2d\x29\x04\xe4\xc5\xec\xd0\xb8\x8f\x59\xe7\x5d\xdb\x51\xef\xc0\xe0\x9c\xa9\x50\xea\x25\xc6\xb3\x50\xd8\x57\xba\x41\x16\x08\x94\x86\xed\xfb\xfc\x4f\x5f\x05\xc2\xd6\xbf\x57\x8b\xe4\xb9\x5c\x31\x88\xcf\x9a\xc3\x33\x9f\xd0\xb8\x37\xc3\x57\x1f\x12\x89\x0d\x9c\xde\x25\x35\x74\xf8\x99\x20\x91\x76\x29\x3a\x6b\xfa\x48\xdd\xb7\x27\x31\x43\x8a\x1c\xab\x57\x6c\x14\xd3\x8f\x27\x04\xc2\xa3\x61\xc1\xce\xab\x78\xae\x96\x9f\x57\xce\x17\xdc\x17\xc6\x55\xdb\xd5\xe7\x71\x69\xba\x36\xca\x30\x1a\x0e\xc2\x3f\xf6\x4d\xf7\x73\x9d\x44\x47\x27\xf9\xc1\x21\x20\x11\x30\x50\x41\x82\x43\xca\x98\xbe\xee\xff\x7a\x2e\x40\x0c\x55\x6c\x73\xaf\x4e\x7b\x87\x9e\x8b\xe1\xeb\x71\x83\x55\xf0\xcd\xd5\xa9\x6b\xb9\x26\x52\xb1\x7a\x49\xfd\x31\x14\x8d\x61\x59\x3d\xea\xa3\xe4\x7e\x21\x76\x87\x31\x2d\x54\x44\xdf\xa5\x5f\x0c\x8e\xeb\x4d\x7e\xe8\x86\x21\xc6\xb0\x4e\xff\xd1\x70\x0d\xae\x40\xd9\xbc\xee\xa1\x5a\x33\x14\x77\x77\xa8\x1e\xfb\x03\x17\x01\xf2\x4e\xcd\x67\xcf\xde\xd3\x4c\x02\x63\x9b\x31\x10\x9b\xf1\x6b\xd5\x5b\xdb\x55\x16\xb4\x85\xc6\x31\xbe\xa5\x2a\xb0\xd1\x00\xb3\xcb\x70\x88\x6a\xed\x7a\xce\x81\x44\xda\x97\xc2\x21\x6b\x0c\xdc\x8c\x40\x0a\x8d\x4e\x39\x8a\x19\xcf\x80\x01\x89\x31\xce\xe4\x2f\x5b\xda\x3d\x7d\xc8\x0d\xf8\x48\x35\xce\xf5\x36\xf1\x6b\x44\x03\xd8\xdb\x99\x93\x4b\x6a\xca\x73\x13\xdb\x04\x5c\xae\xe0\x2b\x7e\x89\x68\x1d\x97\x3c\x09\x3e\x7f\x4a\xb0\xa4\x4d\x4d\xc4\x81\x80\x68\x0e\xe1\xcd\x12\x38\xd8\xbb\x70\xa2\xe6\x51\x67\x30\x34\x18\x50\xc4\x10\x15\xc0\x6e\xec\x24\x8b\x11\x3d\xff\x4c\x15\x09\x2a\xf1\x4a\x31\x87\xfc\x13\x4b\xda\x1a\x65\x34\xfe\x3e\x06\xb3\x0a\x15\x1a\x04\xf8\x42\x06\x53\x5b\x9d\x43\x80\xa0\xab\xbc\xd6\x16\x2e\x0c\x0c\x4c\x11\x4d\xb8\xce\x36\x16\xe0\x27\x11\x12\xfd\xd6\xda\xa4\x65\xc2\x12\x17\x16\x9d\xca\x2a\x08\x29\x84\x06\x35\xf8\xb6\xd1\x75\xa2\x9f\xcf\x1b\xa8\xff\xe9\x2c\xe2\x35\xf0\x99\x37\x62\x50\xf4\xca\xec\xa1\xc4\x79\x6b\x92\x50\x58\x3e\x33\xf5\x96\xda\xd3\x59\x8a\x40\xe1\x45\x45\xe7\x9f\x70\x04\x11\xd9\x87\xe4\xff\x9c\x31\x93\x66\xa8\x12\x33\xd8\xc2\xce\xe1\xc3\xc0\xbe\xe3\xc7\x72\xcb\x90\x65\xa1\x35\x3a\x12\x12\x2d\xf8\x03\xf4\x5c\x3e\xbf\x65\x02\x7a\xd9\x9f\x33\x44\xb4\x1c\x9e\x0b\xbc\xd5\x8b\x31\x41\x25\xba\x73\x0c\x43\x5e\xfe\x8a\xe2\xfe\xfa\xea\x0d\x0f\xdb\xc8\x84\x36\x40\xe5\xd0\x2c\x94\x50\x2c\x59\x2c\xe6\xc2\x48\x80\x74\x31\x41\xec\xbd\x5b\x14\x05\xfb\x4d\x53\xcc\x9b\xda\x35\x70\xae\x9b\x2e\xe9\x7f\xc7\xc2\x18\x88\x96\x67\x54\x69\xcf\x2d\x09\x32\x44\x4e\x1b\x85\x2a\xfe\x8d\x87\x46\x63\xd9\x86\xf4\x2a\x41\x2a\x0d\xf9\xe0\xaf\xf9\x9b\xe4\x3a\x2c\xde\x4a\xc7\xa9\x20\xef\x72\xfc\xcd\x5b\x9b\xdb\xfa\x22\x47\x59\xf2\xa5\xeb\xf9\xf7\x2f\x33\xc9\x33\x6f\xf0\x01\xde\x9a\x18\x8a\xc7\xba\x5e\xe0\x85\x66\xea\x70\x47\x35\x0b\x93\xcd\x99\x51\xad\x71\x07\x50\xdf\xb5\x4b\xe9\x28\xbf\x6b\xca\xdd\x30\x33\x28\x0a\xdb\x55\xb2\x70\xde\x48\xfd\x05\x85\xf4\xce\xea\x96\x66\x94\x8f\x24\xc2\xbf\xa1\x1d\x93\x31\xb2\x25\xaa\xbd\xc8\x67\x6a\x33\xb4\xdc\x7b\xf9\x0c\x29\x8e\x77\xd3\x45\xea\x85\x32\xbb\x5a\xe8\xd9\x58\x1c\x95\x80\x4d\xaf\x69\x59\xe8\x3b\xa1\x11\x70\x88\xbc\xf9\x52\x28\x10\x69\xff\x22\x04\xb2\x74\x99\xb4\x16\x07\xfd\x90\xaf\xa4\x46\xae\xc7\x88\x3b\x42\x5b\x79\x79\x91\x3d\xc7\x74\x33\xc6\x87\xff\xd1\xf3\x1f\xe4\xe2\x45\xc5\x77\xaf\x77\x46\x5c\xa5\x41\x3e\xc8\xa5\x71\xa7\x31\x5e\x97\x26\xfc\x31\x2a\x18\x1e\x68\x69\x35\x56\x96\x5d\x0c\x79\xba\xd3\x0f\x78\xff\x41\x0d\x4d\xd1\xac\x29\xcd\x07\xc5\x8b\x24\x71\xea\x20\x32\x7f\xf1\x9c\xdf\xd4\x44\xdc\x3e\x7a\x3c\x0d\x22\xdd\x63\xb1\x6e\x0c\xd9\x71\x6d\x30\x4f\x3b\x72\x1d\xb6\xc6\xbc\xa5\xc2\x13\x64\x79\xe5\xe7\x67\xa8\xcf\x1c\xd1\x27\x88\xce\x5f\x62\x07\xae\xbf\x26\x53\x1e\xc2\x04\xe9\x57\x39\x12\x0d\x86\x77\x1d\x65\xa6\x83\xa9\x0d\x54\xb9\xa7\x72\x8c\x74\x35\x9d\x3c\xab\x68\xab\x7f\x0b\xbb\x61\xc5\x00\x7f\xa7\x6b\xb0\x39\xa1\x30\xdd\x7b\x52\x16\xa1\x97\xc1\xb0\x35\xbb\xec\x4b\x20\x0a\x99\xb2\x15\x21\x57\xbe\xc5\xd0\x0a\x94\xc3\x9a\x20\xce\x91\xd4\xa6\xe3\xaa\xa7\x02\xe0\x0e\x0e\x66\xc6\x3a\xd2\xf2\x39\x25\xf8\xa6\x6e\x7f\xbd\x99\xc8\xb0\x31\x37\x3e\xa6\x7d\xee\x78\xf6\x47\x9a\xbb\x4b\x71\x87\x0a\x81\xb8\x09\x1d\x18\xac\x75\xf7\xe1\x05\xa4\xbe\xaa\x66\x21\x2e\x11\x4f\x3f\x94\x17\x02\xb6\x94\x6e\x9a\x8f\x11\x0a\xac\x86\x8d\x34\xed\x8d\xbc\x27\x65\x66\x29\x68\x6d\xde\x66\xcb\xae\x95\xe2\xb1\x64\xe5\xa6\x5c\xaa\xbc\x54\x83\x94\x04\x41\xcc\xd8\x60\xb8\xf9\x83\x26\x31\x97\x5b\x8e\xec\x46\x0d\x63\xf5\x21\x73\xe1\x26\x7c\x8f\xcb\x10\x08\x93\x10\xfc\xef\x29\x13\x9d\x32\x6c\xbf\x84\xaa\x8b\x38\x6a\xb0\xc6\x4e\xee\x75\x75\x10\xa1\x0d\x23\x13\xd2\x0b\x3a\x87\x59\x66\xa2\xe9\x57\xd5\x01\x01\x2f\xe9\xfb\x80\xe5\x19\xdf\x37\x6d\x88\x5e\x38\x03\x0a\x65\xff\x44\x56\x01\x19\x36\x60\x8e\xab\x8e\x60\xb8\xe7\xd8\xf0\xb1\x11\xa7\x6b\x78\x52\xc4\xc1\xf5\x8c\xac\xbf\xcd\xb8\x65\x6a\xd4\xa4\x85\x34\x40\xe6\x21\x90\x43\xe2\x34\xaa\x44\xfa\x93\x33\xe5\x77\x95\xe5\x5e\xf1\x17\xd5\xbb\x60\x70\xa3\xe3\xc3\xfb\xc9\xaf\xbc\xae\x91\xab\x59\xed\x88\xb2\x21\x06\x19\xcf\x1f\xcd\x72\x75\xbe\x3a\x41\xdb\xca\x62\xaf\x03\xde\xfd\x29\x6a\x9f\x32\x68\x87\x4f\x88\x12\xd8\x7f\x9c\x35\x6f\x44\x42\xab\x31\xc2\x9a\x29\x64\xa7\x42\x62\x30\xf1\xc0\x93\x5b\x19\x98\x60\xb8\x91\xf8\xb5\x30\x5c\x49\x4a\xc4\x80\x9f\xa2\x4f\x8c\x41\xb4\xfe\x76\x57\x0a\x6e\x67\x8e\x5d\x3c\x03\xf7\x0b\xd0\xf1\x8d\x55\x2c\x78\x96\x56\xf3\xa0\x0c\x29\xcd\x74\x14\xc2\x2c\xda\x91\x09\x9b\xcb\x35\xb2\x65\x0a\x6a\xd0\x52\x08\xc3\x63\x0c\x3e\xcd\xa8\x1c\x00\x24\xe0\x42\xde\x91\x53\x1d\x89\xf5\x2c\x7d\x5c\xf2\x5e\x54\x29\x47\x82\x58\x4e\x1d\x54\x1a\xdc\x17\x35\x3e\xc4\xa0\xd6\xe8\xd6\x96\x35\x25\x77\xa3\x31\xa0\x96\xca\x11\x93\x4d\x78\x0c\xf7\x28\x31\x40\x92\x9b\xf1\xcf\x66\x25\x00\xa0\xcd\xc3\x4e\x6f\x68\xa2\x16\x7f\x26\x9e\x01\x7b\xc5\xa1\xcd\xca\x92\x68\x80\x52\x37\x8f\x6e\xa6\x12\xcd\xea\xaf\x88\x4a\x91\xfa\x37\xb0\xd9\x1c\xe1\xe4\x6c\x0a\x8e\xac\x48\x31\xf3\x20\x06\xa9\x3a\x53\x57\xfe\xa6\xbc\xda\x9c\x9e\x73\x1a\xc8\xe3\xd9\xcd\x05\xd3\xb0\x1d\x81\x8d\xba\xae\x6b\x12\xeb\xf3\x64\x5f\xab\x4f\x37\x60\x8d\x27\x75\x59\xf0\x9a\x03\x0c\x11\x05\x4f\x64\xae\x02\xab\x6f\xea\x31\xa0\x62\x6c\x5f\x43\x1c\xbe\x26\x35\x39\xee\x81\x38\xcd\x0c\xae\xa0\xb2\x2e\x2b\x91\xa3\xae\x97\x1a\x90\x62\xe3\xde\x31\xf6\x0d\x82\x61\xec\x73\x84\xb4\x4b\x0b\xe0\xa4\xd5\x27\xa3\x42\x59\x58\x90\xb3\xfc\x8b\x05\x30\xd9\x12\x63\x0f\x42\xa3\x84\x5f\x0f\xcd\x18\xb9\x50\x17\x22\x5c\x56\x4d\xd0\x7a\x5b\x42\xaf\x54\xfa\x74\xd2\xb8\x29\xca\x92\xf6\x26\xb9\x6a\xa1\x2c\x7b\xaa\xa3\x47\xc5\xfe\xee\x41\x1e\x77\x9c\xb3\xbd\xef\xd1\x36\x81\x49\x70\x41\x56\xb2\x48\xc2\x8e\x81\x50\xa0\x35\xab\x64\x13\x92\xb4\x6c\x48\x25\x34\x1f\x83\xf1\x26\x1f\x63\xcb\xda\xaf\x67\x2b\xea\xf5\x68\x2c\x94\xab\xb3\x00\x81\xf0\xb6\x7f\x5f\x0c\xd8\xb4\xf4\xa5\x9b\x84\x1a\xa2\xce\x08\x74\xb2\x18\xd7\x61\xdc\x7e\x2f\x6a\x46\xac\xc9\xd7\xc8\xb1\xc8\x03\x9d\x1d\x8d\xe4\x81\x52\x12\x5f\xf3\x7b\x1e\x8f\x4b\x55\x06\xbd\xe2\xc4\x1d\x26\xb6\x5b\x64\x2f\x42\xe8\x3c\xf8\x2c\xfa\xb6\x90\x6a\x4c\x8f\x44\x6e\x49\x9a\xcb\x80\xb1\xae\x38\xd3\xd2\x56\x22\x97\x11\x07\xef\x52\x77\x1a\xce\x28\x7e\xb9\x51\xc6\x0e\xa7\x4f\x5c\xea\x21\x80\x03\xf5\x06\x07\x3d\x87\xfd\xb0\xac\x0b\x3a\xb9\x51\x04\x7f\x41\xe1\xe9\x0c\x45\x8d\x70\x32\x2f\x8a\x53\x84\x0c\x37\x0c\x28\xf8\x58\x5b\x24\xc8\x98\x42\x41\x33\x10\x8f\xaf\x5e\x4a\x0c\x00\x6d\x69\x7c\xd4\x05\x24\x3d\x0b\xe5\x2f\x6e\xd4\xb6\xd2\x4b\x08\x85\xde\x6b\x97\x23\xcc\x8a\xc4\xd7\x89\xa3\xf5\x6b\xbc\x93\xf0\x14\x4b\x58\xa8\x51\x8a\x81\x44\xf4\x5f\xad\x82\x0e\x7e\x88\xea\xd3\xa8\x32\xe7\xa6\xaf\x09\xe0\x60\x6b\xd5\x6b\xfd\x2d\x49\x8a\xfc\x2b\x59\xea\x95\xde\x39\x39\x50\xd3\x0c\xde\x42\x0e\xbd\xa9\xbc\xd9\xa6\x13\x93\x70\xe3\x18\xcf\xa5\x0d\x6c\xf4\x20\x21\x24\x30\x29\x21\xc8\x08\x5c\x27\xf8\x8f\xb7\xe9\x4c\x95\xfb\xb4\xff\x13\xbe\xc9\x8c\x4f\x5e\x10\x42\xba\xb2\x9d\xd4\xc3\xf1\x30\x3c\x32\xd7\x60\x9e\xbf\xd3\x43\x83\x66\xbf\x64\x30\x70\xa1\xe2\xce\x5e\x7d\x29\xce\x22\xb8\x08\x18\x3e\x23\x6f\xf9\x03\x4f\x2b\xb5\x96\x87\xe0\x8c\xbb\xc4\x06\x07\x47\xa1\x5b\xcd\xf8\x1f\x9a\x63\xdc\x40\x41\x2b\xda\xdb\x3d\x02\x5b\xb3\x3c\xbb\x36\x4c\x73\x5c\xc1\x6a\x99\x88\x28\xfb\xc8\xf1\x00\x9c\x73\xda\xa2\x15\x05\xd8\x42\xf4\x91\xa3\x75\x8b\x7d\x12\xd3\x94\x56\xae\xd0\xb9\xca\x8f\xec\xd7\x2c\x80\x99\xc9\xa0\x5d\x6a\xb5\xc2\x50\xfb\x0c\x66\x9e\x12\x69\x50\x83\x69\x05\xe3\xb3\x0d\x47\xec\xc3\x47\xf8\x84\x19\x75\xe9\xd1\xdf\x3a\x02\x41\x5c\x27\x8a\xbe\x2b\x47\x98\x00\x4d\x07\x21\xf8\xd6\xd2\x20\x4a\xab\x22\x1b\x61\xff\x1c\x71\xa3\x35\x46\x7f\xbb\x85\x66\x55\x3f\xbf\x6e\x01\x55\xd4\x96\x50\x83\x6b\x7e\x9c\x97\xc2\x97\x47\x23\xc8\xf3\xcd\xd2\x6b\xda\xf0\x17\xf0\x89\x8b\xe3\xb3\xc6\x83\x0e\x50\x8b\xd8\x7d\xd0\x33\x55\x16\x19\x32\xc7\xf6\xbb\x79\x4d\xfc\x42\xac\x91\x62\xbb\xf0\x62\x0c\xdb\x62\xbb\xad\x0e\x6d\x5d\x58\xa0\xf4\xc8\x7e\x69\x8a\xe9\xb0\x2c\x4c\x67\x7a\xdf\xd1\xa6\xd3\xe2\xa9\x0f\x8d\x88\xb7\xa1\xf1\x88\x2a\xfa\x52\xd0\x37\xfc\x50\xe9\x12\xba\x90\xf4\x72\x55\x74\x88\x26\xf4\x23\xde\xa7\xf4\x15\x10\x84\x20\xf7\xfd\x52\x15\x62\x2b\x18\x89\xa4\x6e\xdd\xf3\xc9\x1b\xff\x13\xbe\xeb\x1e\x33\xf2\x4a\xf8\xde\x7b\xd0\xd2\xfa\xd1\x73\x5a\x75\x33\x45\xa0\x78\xe3\x38\x30\x06\x9a\xcf\xca\xa9\xd9\xa2\xe7\x95\xaf\xca\x8b\x96\xa0\xb4\xc9\x3b\x88\x00\xcb\x15\x9a\x37\x71\x2a\x0e\x74\x9c\xbe\x1b\x05\x61\x3f\xda\x7c\x77\xbb\xda\xeb\x28\x7d\xa7\xe3\x6c\x45\xab\x33\xf4\x9f\x36\x44\x6d\x5e\x54\xd6\xcd\xf5\x58\xa2\xb5\x4d\xd8\x82\x8f\x84\x7f\x3c\x53\xbe\x51\xa9\x47\xb1\xb0\x6f\x0f\x38\xb4\x4d\x9f\xb2\x67\x9b\x73\x3f\x4e\x55\x78\xf2\x54\x30\x47\x26\x75\xa1\xa9\xe9\xf9\x24\xaa\x18\xf5\xf9\x41\xe3\xfa\x18\x42\xfe\x4e\xe0\x0a\xd2\x1c\x87\x5e\xf9\x43\x29\xe8\x20\x77\x6e\x3e\x67\xe0\xc4\x33\x5f\xf2\xa7\xe6\xcf\x37\x52\x22\xb3\x37\x86\x40\x16\x5b\xa0\xbf\x39\xdd\xf7\x29\x17\x0b\xeb\x18\xb9\xdf\x9b\x63\x34\x53\xa8\xc2\xa3\xe4\x06\xe2\x18\xb5\x16\xe3\x77\x51\xe3\x97\x65\x2b\x2c\x60\x35\xd5\x50\xac\xe1\x40\x3c\x68\x5d\x5b\x56\xeb\xbf\x34\x0c\x20\x06\xde\xa8\x06\x97\x21\x14\x51\xb6\x86\x89\x4e\xac\x3c\x08\xf0\x97\x14\xf4\x07\xe3\xd4\x29\xe8\xe8\x5f\x41\xbf\xe6\xee\xbc\x2d\xa6\x1f\x1c\x65\xd5\xf4\x06\xae\x76\xfd\xdc\x07\x0e\xef\x79\x3b\x35\x96\x62\x68\x80\xaa\x0e\x97\xb6\xef\x16\xaa\x62\x71\xf0\xf1\x97\x36\x26\xc2\x15\xfb\xb9\x01\x98\x91\xbf\x91\x10\x77\xf2\xb2\xfc\xc8\xec\x5d\x09\x25\x75\xde\x49\xe0\xd5\xa0\x1d\x33\xe4\x6d\xd4\xc7\x68\x5e\x6f\x61\xf4\x3b\xb6\xa9\x69\xa2\xc6\x13\x1d\x22\xe6\xa8\x5c\x2f\x75\x5b\x78\x80\x68\xee\x3a\x41\xf1\xe9\x1a\x4f\xbc\x3b\x91\xc8\xbf\xa9\x04\x35\xe5\xac\xea\x2f\x9a\x52\x60\x8f\xc6\x32\xd5\x5d\xe7\xdf\xb9\x8e\xa4\x95\x7a\x1f\x26\x53\xa3\x81\x4c\x98\x21\xf7\x93\xf8\x59\xa7\x63\x73\xd4\x55\xd8\xb8\xf6\x87\x2a\xc8\xfb\xd9\xd1\x62\xc2\x11\x78\x76\x11\x46\x82\xa4\x3b\xaa\x79\x4c\xe4\xb8\x4e\x49\x8c\xcc\x91\x7a\x4b\x3c\x27\xee\xe8\x0e\x4a\x13\x0d\xad\xbb\xfd\x9e\xaf\x0e\xcd\x50\x51\x09\x89\x4b\xcc\xda\xa0\x5f\x96\x1c\x86\xff\x9a\x06\x79\xff\x2b\xd3\xe0\xdf\xf6\xc9\xa0\x45\x56\xa8\x0b\xb8\x81\x9d\xa3\xac\x0c\x7e\x3d\x0d\x9e\x73\xf4\xe1\x1d\xf3\xc3\x42\x1c\x75\x7e\x38\xe4\xbd\x2c\xc4\x58\xe7\xf4\x13\xda\x59\x93\x8b\x8e\xb0\x6c\xad\x09\xa7\x25\x84\xb4\x25\xe0\xc4\x44\xd4\xe7\x4e\x36\x37\x1c\xda\x7e\x24\xbb\x9c\xd0\x62\xd1\x3c\xcd\xcc\x55\x7b\x16\xcb\x84\x9e\x85\x07\xc8\x3d\x81\x62\xb5\x93\x47\x2f\xa3\xdf\xff\xe2\x90\x59\x50\xc6\x36\x75\xea\x53\xea\x01\x60\x12\x99\xea\xad\x4d\x84\x4c\xba\x6f\x9b\xb8\x9c\x21\x67\x80\xbf\x41\xd5\x88\x0f\xc5\xb6\xd2\x18\xf7\x86\x15\xf2\xd3\xbe\x28\xaf\xf4\xf3\x19\xed\x35\x52\x26\x3c\x17\xb6\xea\xb3\x82\x1a\xe6\xd7\x0f\xe7\x5f\x42\x50\x10\x36\x69\x14\x2a\x4e\x52\xe5\x81\x8d\xd9\x58\x7e\xec\x71\xa2\xce\x98\x91\xd5\x48\x36\xbb\xea\x5d\x5e\x20\x27\x6b\x9b\xb2\xc0\x37\x58\xe4\x5d\x6b\xb9\x72\x7a\xca\x58\x73\x97\x15\x0b\x1f\x9a\x23\x29\xb9\xdf\xe8\x60\xad\x11\x69\xcf\x62\xb7\xb8\xa0\x89\x68\xe1\xe5\xe2\x14\x8c\x1e\x80\xf3\xfa\x9d\x64\x30\xd7\x98\x12\x09\x36\x59\x1c\xb5\x87\x34\x17\x2e\x66\x57\x6a\x9d\xf4\x3e\xc7\x4c\x78\x14\x04\x72\xa2\xd9\xd9\xd1\xa2\x45\xfb\xee\xb7\x73\x55\x5c\xdd\x5d\x43\x39\x81\x1b\xb7\xbf\x52\x31\x4b\x49\x33\xdb\xa0\x69\x4e\x78\x7b\xee\x12\x83\x53\x0f\x5c\x23\x5d\xe1\xc9\xd2\xa6\x9c\xc6\x5d\x66\x0a\x06\xc2\x91\x62\x66\xe2\x1e\xf2\x6d\x53\xe8\x45\x5a\x64\x99\x7a\xb9\x0f\xf7\xa8\x72\x1a\xe8\x2e\xa5\x91\xda\x6a\x61\x17\xec\x4b\x7f\x0a\x3e\x88\x9c\x28\x9c\xc7\x14\x22\x15\xfc\xca\xa5\xc1\xb4\xf3\xf5\x73\x95\xb0\xba\x48\x91\xbb\x14\x60\x5c\xbc\x82\x7c\x4c\x1b\x98\xfb\x6e\x4d\xc5\x9e\x61\x4a\xe1\x0d\xfd\x1a\xac\x1e\xb8\x23\x57\x08\x9c\xdb\xa8\x84\x77\xce\x51\x68\xbe\xf6\x97\xe0\xe9\x3e\xa6\xb7\xc0\x6b\xc8\x51\x81\x8c\x2c\xdf\xe4\x40\xfa\x4a\xf5\xb7\x15\xc9\xa6\xbb\x87\xb7\x19\xeb\xd8\x88\xe9\x69\x41\x3d\xdb\x13\xe7\x90\xa4\x1e\x85\x8b\x4d\x92\x1b\x81\xc6\xba\x80\xb1\x2d\xba\x3b\x7d\x22\xa6\x2a\x34\x48\x3a\xf8\xd5\x9c\xfe\x8a\x6e\x9c\x19\x9e\x36\x60\x96\x14\x55\x39\x7c\x9d\x8d\x88\x49\xbc\x8e\x49\xaf\x4d\x35\xf3\x28\x8e\xc1\xb1\x7c\x2c\x7b\x57\xaf\x4a\xab\x44\xdf\xd0\x0b\x96\x03\x14\x12\x14\xc6\x8e\xa6\x60\x8a\x0c\x7f\x3e\xbc\xb9\x67\x24\x86\xd0\x72\xdd\x2f\x8b\x82\xed\x9a\xcc\xcd\x44\x5b\x4e\x44\x0c\x0e\xa9\xe0\x8f\x41\x53\xe9\x24\xf7\x0b\x97\xf5\xca\x8f\x7c\x34\x78\x3f\x91\xad\x24\x17\x8c\x4d\x59\xb7\x6b\x90\xe4\xea\x06\xa6\x34\x13\x10\xb0\x69\x95\x88\x61\x54\x72\x97\xaa\x11\x89\x7f\xb9\xa2\x3f\xa2\x01\xab\x71\xdb\x25\xd9\x5f\xd1\x8d\xa4\x52\xe9\x3d\x68\x44\x13\xb8\xb6\xea\x5e\xdc\xa3\x31\x07\xaf\x1d\xe5\x1a\x47\xc2\x71\xc9\x28\x60\xc0\x2b\x05\x27\xf2\x91\xc0\x97\x47\x3b\x2c\x0f\xb4\xa1\xc1\xcc\x9d\x97\x7a\xf7\x8b\xd1\x87\x9e\x4d\x12\xcc\x9f\x62\xae\x1c\x68\xdb\xe2\xca\x58\xc4\xf1\xf9\x2b\xd3\x0b\x77\xe9\xaa\x19\x37\xce\x02\xf0\x6f\x6f\x03\x3c\x91\x89\x60\x2c\x15\x7e\x72\x50\xe4\xe7\xa2\x76\x16\x91\x07\x1a\x6a\x8b\x1a\x9c\x12\x86\x95\xa1\xbd\xd1\x92\x69\x85\xd5\xa0\xdc\x69\xeb\x26\x86\x0d\xa4\x92\x09\x83\x3a\x66\x8b\x0a\x46\x96\x03\xde\xe8\x18\xf3\x97\x3e\x11\x58\x38\x91\x32\x9a\x1e\xf0\x7a\x3c\xb5\x77\xb1\x49\xa3\x54\xe0\xdc\x6c\xf5\x89\x78\x97\xd1\x16\x4d\xa9\xae\xdd\x89\x57\x63\x24\xd7\x3a\x5d\xf2\xd4\x16\x71\x50\xa3\x5f\xcf\x26\x0a\xb3\xe1\x9b\x02\x24\x54\xd0\xe5\xe5\xfb\xef\x19\x5e\x28\xa6\xca\x1c\xfc\x92\x10\xf2\x4c\xad\x50\x61\x57\x80\xc7\xef\xbf\xb3\x48\x24\xc6\xac\xb9\xc4\x2c\x2d\xae\x03\xd2\xd8\x2e\xba\x70\x57\xf3\x8e\x1d\x71\xaf\xe8\xe0\x13\x14\x49\xb5\xdf\x74\x0d\x24\xbb\x27\xae\x76\x5e\xa2\x70\xe4\x83\x7d\xde\x5a\xbf\x41\x64\x03\x79\x44\x5f\x6a\xa6\x10\x5d\x0c\xf8\xf1\x15\xee\xd1\x6d\x48\xa5\x63\x36\xc8\x40\x44\x40\xca\xf0\x63\x1b\xb8\x24\x51\x8b\x2b\x7a\x0d\xde\x36\x98\x8e\x76\x56\xd9\xa8\xf0\xf2\x26\x33\xce\x87\x44\x6c\xc5\xa5\x9e\x1a\x6c\xaf\xf4\x63\x60\x6e\x30\x94\xf4\x58\xaa\x06\x60\xe9\x9e\xa3\xca\x19\x81\xa5\xda\x03\xca\xa6\xa3\x96\x94\x05\xf9\xbc\xb5\x8e\x03\xeb\x5f\x29\x30\x67\x78\xf1\x48\x5d\x38\x0e\x7b\x2b\xec\x58\xd8\x44\x24\x5e\x5d\x8f\xa3\x25\x76\x2e\x46\xd3\x5e\xa2\xc9\xd8\xc7\xf0\x02\xe2\xcd\x73\xb1\x0c\x5a\x12\x01\x3e\x48\x27\x22\x42\xef\x54\x68\xc2\x6c\x8b\xb8\x01\xc7\xce\x31\x73\x75\x13\x62\xbf\x6b\x78\xda\xa6\xa9\x67\x4d\x6e\xdc\x4f\xca\xcc\xa9\x85\xda\x3a\xf4\x09\xde\xa0\xc9\x45\x93\xcf\xd9\xa0\x88\x09\x4a\x48\xa7\x78\xf7\xa6\xf4\x82\x7f\xc7\x42\x1d\xd8\xfc\x82\x77\x66\x3b\xef\x19\x73\xc5\x5c\xf7\x9e\xba\xea\x57\xfb\xb5\xce\x76\x12\xfc\xa5\xa9\x02\xe6\xb0\x9e\xf2\x8d\x27\xa7\x7b\x1f\x63\xe6\xac\xdf\xb3\x25\x82\x51\xd5\xb7\x6b\xef\x53\xfa\x69\x52\xa0\xf6\xd5\x8a\x72\xea\x38\x64\x1b\x63\x24\x6c\x18\xa7\xcb\xb8\xa7\x69\x88\xb1\xae\x89\x57\x94\xec\xf6\x36\x4b\x32\x71\x04\x53\x7f\x24\x55\x11\x48\x6c\x30\x76\x79\xa2\xee\xa1\xfe\xf6\x88\x37\x6e\x21\xea\x4d\x6c\xc8\x20\x15\x00\xcc\xdb\xf5\xfe\xd2\x51\xf4\x4c\x25\x3a\xb4\xb6\x69\xd0\x84\xa9\x7d\x6e\x7d\x82\xf9\xf7\x8c\x01\xd5\x19\x83\x4e\x65\xcf\xf6\x4c\xe5\x0f\x14\xea\x79\x48\x30\xb4\x98\xf0\xad\xe3\x4d\x02\x42\x9f\x39\x28\xbb\x0d\x71\x19\xb0\xa9\xe1\x26\xb6\x45\x96\xa9\xb7\x67\x81\x53\xdc\xc4\x46\xc8\xdb\xa6\x0a\x7a\xeb\x57\x6f\x6c\xe9\x36\x11\xc0\x41\xfd\x9b\x2c\x2a\x83\x97\x4e\x23\xd9\xd3\xfb\x1f\x81\x28\x19\xab\xb9\x83\x3c\x23\x1e\x1e\xed\x6d\x38\xa6\x6c\x61\x88\x11\xf0\x18\x2b\x11\xb7\x3c\x8a\x96\x67\xd7\x35\x2b\x76\x11\x84\x6e\x5f\x72\x39\x5f\xc6\xe0\xc9\x2f\x52\xa8\xb5\x84\xe0\x3c\xd1\xc4\x8a\x52\x59\x9e\x3b\x4d\x40\x70\xd1\x1c\x71\x65\x5a\x81\x12\x13\x89\xa2\x7e\x4a\x7a\xc4\xb3\x41\x44\x79\x57\x37\x1e\x55\x2e\xe2\xca\x62\x79\x23\x66\xc5\x5d\xc5\xdc\x50\xc2\x44\x01\x20\xcf\x16\xe9\xe8\xf6\x7a\xef\x2d\x80\x38\x07\x7c\xb0\x0d\x16\x5a\x06\xaf\x63\x3b\x94\xe9\xd9\xb7\x55\x96\x80\x04\xc8\x12\x4a\xc9\x79\x6b\x23\xab\xcc\x80\xee\xd0\x08\x71\xa9\x0f\x8e\x9d\xa0\xee\xdc\xb9\x5c\x63\x48\xdb\x92\xaa\x58\xe6\xd8\x2c\x9f\xe4\x7b\xb0\x8d\xe0\xba\x80\x0e\x77\x61\x5c\x47\x7e\xc0\x1d\x9f\xbf\xa7\xd2\x7d\x89\x9f\x3f\x3f\x9a\x1a\x6e\xde\xa4\xb4\x12\xc1\x0d\x11\xd7\x4d\x79\x04\xaf\x4e\xf4\x4d\x3d\x8a\x6a\xa7\x8f\x58\x39\xf3\x98\x30\xff\x3c\x70\xd8\x1a\x0b\xc7\x28\xfe\xa3\x46\x3e\x50\x64\x70\x98\x3a\xaf\xbb\xab\x95\x3a\x6c\x22\xc6\x74\x97\xe8\xf8\xa3\x6f\xd9\x9f\x21\xce\x39\x6a\x74\x90\xb7\xb5\x47\xe0\x08\xcd\x3c\x4e\x09\x60\x2f\xfb\x21\xae\x65\x48\x60\xad\xca\x8e\xe8\xba\xe6\xab\x67\x7a\x72\x8d\x55\xfc\x20\x9a\xe5\x70\xcf\x2c\xe8\xda\x6f\x5f\xba\x85\x32\x8e\x9f\x2c\xd1\x7d\x5e\xa1\xf1\xdc\x4b\xda\x5b\xf1\x44\x72\xe9\xe6\x72\xd6\x50\xc5\x4d\x85\x82\x5d\x3e\xbf\x83\x49\x39\x9b\xcb\x14\xbe\x8f\x12\x85\xdb\xa3\x21\x05\x43\x2b\x03\xeb\xff\x51\xda\xb5\x86\x5c\xbd\xeb\xdd\x53\x05\xe5\x6f\xc1\x56\x4c\x32\x45\x13\x27\xaa\x31\x9e\x8d\x8c\xa2\x6b\x2d\x9c\x4e\x21\xd3\xe0\x0d\x52\x30\xd9\xbb\xac\xa9\x6d\x40\x8b\xb7\x78\x3c\x2f\xee\x6a\xc1\x80\x59\xa2\xe5\x98\x18\x02\x59\x8a\x6e\xb1\xc8\x7e\x66\x4b\x44\x3b\xf9\x58\x4b\x6a\x7d\x30\xee\xc2\xb8\x97\x4b\x3f\xc1\xb5\xed\xba\x8e\xf7\x42\x43\xc7\x70\x43\x3d\xa0\xa7\xc1\xac\x00\x79\xc6\x4a\xfa\xf3\xab\x3c\x79\xfe\x5e\x89\x93\x07\x7d\x1c\x94\xba\xf2\x3a\x80\x8d\xab\xba\xb4\x95\x4f\x8a\x43\xdc\x2d\x35\xa6\xf8\xcc\x4a\x1a\x5d\xf6\x87\xe5\x55\x8f\x5c\x10\xfb\x3c\xa4\x9b\x78\x57\x55\xdf\xcb\xdb\xec\x53\x19\xed\x79\x58\xf8\x82\x49\x0b\x64\xad\x6b\xe4\x02\xce\x4c\xa0\x09\x21\x9c\x0d\xa5\x79\xec\xa3\xa2\x6f\x8b\x07\x7a\xe9\x90\x36\x3d\x8e\x19\xd9\xc5\xf7\xb1\x0a\x50\x1c\x40\x51\x59\x82\xe3\x36\xab\x55\xd7\xf6\xb5\x46\xc4\xd2\xf6\x92\x8b\x4a\x42\xc2\x69\x8e\xab\xc4\x70\x4b\xf3\xcb\x8c\xda\x3b\x16\x3c\x8e\xab\xcd\x4c\x09\xe4\x26\xeb\xe8\x93\x22\xe5\x8c\x2e\xc6\x06\x2d\xf0\x94\x2e\xa2\x77\x70\xe0\x2e\x78\x66\xdd\x94\x61\xa8\xbc\x78\x64\x46\x99\xb8\x9e\xf6\x00\x5f\x1a\xa1\xd5\x6c\x93\x3e\xc9\x82\x59\x80\xe0\x7e\x7b\xd1\x3d\x58\xa4\x6e\xa0\x86\x03\x80\x2e\x51\xfd\x69\x60\xf7\x40\xa0\x5b\x73\x83\xb6\xfe\x6c\x03\x08\xd9\x08\x38\x50\x85\xb4\x05\x8c\x6f\x4a\xb4\xb8\xf6\x3b\x03\xea\x6b\xf2\x22\x67\xa9\x7c\xae\x3c\x1a\x11\x88\xa7\x32\xa3\x86\x02\x7e\xb0\x1a\x6f\xcd\x2f\xc6\x84\xce\x2f\x97\x14\x4e\xe8\xfe\x35\x4c\x02\xd4\xb0\xc0\x56\x3f\x04\x68\x96\x65\xff\x4c\x96\x36\x80\x6d\xe0\x31\xde\x14\xf7\x25\xb0\x1a\xc7\x2e\x10\x81\x59\x54\xb8\x0f\x0d\x44\x32\x07\xbd\x97\x28\xf3\xbb\xf8\xad\x60\xaf\xab\x88\xd5\x6f\x67\x1f\xaa\x5e\x6c\x35\xd2\xd4\x52\xf3\x1a\x48\xc7\x91\xcd\x25\x5e\x9b\xbd\x84\xc4\xe7\x7a\x71\x9a\x40\x78\x6b\x5c\x40\x76\xd7\xef\x3d\x3b\x0a\xfd\x5e\xea\xb5\x76\x0d\x7a\xde\x28\xf9\xb8\xd4\xab\x6c\xc4\xa0\xbb\x78\xa9\xe8\xaa\x62\x73\x01\xd9\xbf\x82\xaf\x1a\x90\x3e\xa0\xac\x1f\x75\xc7\xef\x12\x14\x30\x04\x69\x60\x75\xac\x37\x36\x40\x5b\x44\xd2\xf5\x62\xb8\x47\x1b\x78\x2f\x1a\x54\xcb\x64\xdf\x31\xcb\x09\xa2\x5f\x3c\xcf\x12\xa3\xed\xbd\xca\x79\x8b\xfa\xf8\x4d\xb2\x03\xba\x2a\x8e\x0b\x21\x6c\x38\x1f\x8d\x20\xec\xa3\xc6\x64\xbc\xf7\x5e\xa3\x78\x3d\xd6\x7b\x7e\xe2\x8b\xb8\x85\xa1\x61\x5f\x87\x0f\xc6\x98\xf9\x13\x2e\xbf\x1a\x52\xae\xfe\x62\x26\xc6\x6e\x60\xf8\xa0\xa3\xb8\x99\x4d\xc0\x80\xe9\x5c\xd8\xdd\x1b\xe5\x43\xf7\x5b\xc8\x88\xd2\x4f\x94\xa5\xe9\x1b\x37\x49\x09\x0a\xdf\xc5\x80\x90\xa3\xf6\x55\xda\xf1\x2f\x89\x62\x3d\xd2\x46\x68\xc2\x4f\x0f\xe7\xb1\xf9\x65\xc2\x4a\x33\x76\x53\x5b\x58\x72\x20\xec\x86\x4e\xad\xfa\xc8\x8a\x79\x35\x7f\x88\x30\x94\x27\xad\x43\xf0\xb8\xec\xf8\x9c\x5b\x64\xc4\xb2\xba\x5b\xbd\x7f\xc9\x48\x44\x34\xe2\x50\xbc\xf9\x98\xc9\xfe\xa4\x4c\x31\x32\x6c\x56\x86\x81\xb8\x9e\x22\xf5\x6e\xf2\x82\x3e\x3c\x15\xfb\x91\x33\xe9\xe4\x9c\xae\x4b\x1f\x8b\x29\x27\xca\x0c\x1a\x43\x01\x11\x85\x1d\xaa\x4a\xa4\x40\xe4\xaa\xa1\xb6\xc6\x56\x4c\x0c\x2f\x91\x00\x46\xc4\xce\x7e\xc0\xa0\x35\x05\xb7\x0d\xf3\x03\xf1\x64\x9d\x77\xaf\xb5\xab\xd5\x95\x98\xb2\x1b\x86\xd5\x85\xe4\xdd\x8f\x47\xcd\x08\xcb\xe4\x12\x56\x21\x70\x69\xc7\x6d\x23\x6b\xab\xc1\x5a\x7b\x18\x0b\x95\xb9\xa1\x43\x1e\x88\x8f\x08\xec\xde\xcb\xa9\x00\x92\xfc\x20\x4b\xb6\xb9\x67\xa3\xbd\x2f\xc6\xfa\xfb\xd7\x19\x8c\x25\x1e\x57\xdb\x01\x51\x47\x9a\x30\x36\x1a\x24\x9a\x54\xca\x45\x20\x68\xd0\xa4\x28\xb7\x5d\xb0\x2b\xb5\x90\x2e\xbd\x22\x5e\x7f\x54\xbc\xdd\xbf\x0d\x51\xfc\xde\x02\x6b\xf4\x3a\x8d\x7c\xd4\x36\x7e\x8e\x91\x04\x14\x74\x38\x04\xe3\x33\xaf\x2d\xc6\x5e\x4f\xea\x05\xef\x24\xf1\xa6\x0f\x54\x8e\x6f\x5f\x8d\x87\x42\x1d\xfb\x11\x70\x17\x22\x5f\x45\x7f\x9e\x2c\x26\xcd\x73\xf9\x39\x5d\x8e\x91\x04\xf6\x3a\x6a\xec\xc9\x2c\xe4\xf6\xe1\x42\xe6\x94\x3b\x71\xc6\xb1\x46\xac\xed\x31\x75\x20\x12\x20\x0c\x36\xe3\x9d\x76\x30\x5b\x89\xbe\x26\x9e\x63\x8f\x43\x12\xde\x9c\xc2\xc3\x52\x43\x85\x1d\xad\xb7\xfd\x5c\x48\xf8\x15\x0c\xd3\xf9\x3d\xc7\x8a\x21\x78\xfb\x2c\x83\x14\xb0\xb6\x16\x93\xaf\x9a\x16\x00\x09\x25\x29\xcd\x60\x53\x98\x6e\x53\xb2\x47\x1b\xc7\x46\x37\x1c\xe1\x12\x92\x76\x7d\xfd\x27\xb2\xf3\xaf\x4b\xaa\x38\xa4\x90\xee\xce\x93\x39\xaf\xbf\x95\x73\x50\x26\x45\xec\xf6\xa1\x9e\xf8\xb0\x3f\xde\x3b\xbb\x43\x2a\x84\x2c\x04\xc0\x36\xa9\x93\xf1\x7f\x27\x35\x13\x14\xbe\x06\xfc\x06\x6f\x3e\x9b\xef\x8f\x36\x2a\x87\x53\xe3\x8e\xc0\xd3\x2d\x0b\xc1\xff\x53\x89\x65\x3b\xa7\x56\x4f\xde\x63\xca\x93\x97\x11\xff\x8f\x2c\x95\x77\xac\xf8\x0c\x26\xe2\x0b\x1a\x06\xca\xb3\x9d\x5b\x3a\x3e\x24\x3a\x3f\x0c\xc4\x08\x52\x85\x25\xe5\xda\xc8\x81\x4a\xeb\x5e\xa0\x80\xdc\x40\xe8\x3b\xd8\x72\xb3\x69\xa9\xc9\xbd\x1c\x68\xb1\x8e\xa1\xf6\xa3\x5c\xef\x25\xf7\xe2\xf5\x3c\x29\xa7\xee\x54\x64\x85\x0e\xe4\xce\xd3\x78\x69\xae\x09\x79\x71\x35\x43\xee\xe3\x10\x33\xe6\x8e\x28\x35\xf4\xae\xca\xcd\x9a\x45\x6a\x35\x4b\xe9\xb1\xa2\x66\xf7\x7b\x95\xe7\xbe\x48\x7c\xb4\xbf\x73\x84\x5f\xae\x45\x90\x35\x76\x52\xb8\x32\x3c\xc1\x49\x62\x48\xda\xa8\x84\x18\xc0\xf9\xeb\x1a\x75\xdc\xf8\x0b\x0c\x44\xb6\x8b\xfc\xba\x4a\x53\xcb\xb5\xff\x20\xfa\x55\x45\xca\x38\x5c\x90\x3c\xb2\x9c\xe2\xc5\x41\x6e\x50\xa8\x3f\xf8\x03\xb0\x12\x47\xe1\x8d\xd6\x73\xc1\x70\xa4\x35\xdf\x31\xef\x09\x63\x4a\x39\x69\x66\x1f\x02\xd2\x5e\x59\x90\x8f\x03\x56\x4d\x7e\x19\x7f\x06\xc5\xe6\x48\x61\x78\x42\xe5\x85\x2c\x18\x6a\x68\x2d\xb5\x46\xa2\x3b\x0a\x2d\xdf\x33\x98\xb5\x90\x4c\xf8\xfb\x92\xc4\x85\xc7\x59\x0f\xbd\xb4\xc3\x80\x0f\x69\x91\x37\xe1\xf1\x9f\x5c\x57\x17\x83\xf8\x4b\x10\x6c\x51\xef\xa7\x26\xce\x6f\x7a\x70\x2a\x7c\xf0\x3d\x19\xa1\xa6\x7f\x7b\x60\xd4\xbb\x79\x86\x64\x51\x1f\x05\x16\xff\x31\x99\x56\x8f\xc6\x2e\x6a\x01\xbe\x38\xd1\x84\xa2\xd6\xe0\x73\x61\xdb\x63\xd4\x0e\x4e\xb5\xa1\xd6\x17\x55\x7f\xf7\x31\x96\x24\xb3\x9d\x76\x97\x62\xd1\x0e\x0e\x27\x53\x45\x6a\x83\xfd\xa4\x39\x71\x87\x4f\x5e\x12\xe7\x20\x10\x2c\x32\xb7\xce\xee\x6a\x0d\xf2\x2b\xdb\x57\x0f\xe1\x60\xbf\x9e\x90\x56\xb4\xed\x79\x70\xad\x7a\x7e\x57\xe7\x4e\x39\xa4\x9d\xb1\x18\x30\xe9\x84\xdf\xfd\xf8\x2a\x45\x37\x61\xb4\x97\x43\x9b\x88\x3e\x2d\x84\x67\x2c\x04\xc5\x27\xbe\x15\x95\x9d\x25\x59\xb2\xb3\x96\x03\x48\x8c\x7b\xc8\xe4\xd6\x81\xd3\x56\x75\xff\xd2\xf5\xc5\x2b\x15\x1c\x25\x9f\x8f\xca\x03\xfb\x42\x12\xca\xc6\x2c\x01\xd8\x51\x18\xc7\x76\x12\xc5\xfb\xee\x19\x92\x25\xf1\xf0\x28\xf6\xf2\x62\x85\x58\xd4\xd5\xc9\x3d\x86\x50\x9b\xc5\x49\xee\x8a\xdc\x7e\x0c\x73\x1b\xd8\x0b\xdb\x43\x7a\x1e\x99\x7a\x4d\x27\xf8\x0c\xf1\x13\x4c\xe1\xa4\xfd\x01\xef\xfc\xcd\x49\x48\x80\x9f\x3e\xdc\xda\xfb\x3f\x28\x57\x8e\x5a\x5c\x68\xeb\x71\x0c\x9c\xac\xa4\x6b\x0c\x33\xa1\x19\xa3\x66\xe6\x72\x5b\x18\xdb\x31\x9d\x08\x18\x5a\xad\x4b\x6f\xb3\x69\xd4\x93\x7d\xa1\x80\x07\x0d\xbc\xbd\xc6\x36\x51\x59\xbe\xe7\x14\x79\xae\x51\x7a\x53\x2b\x07\xca\xe5\x28\x60\x6b\xb6\x20\x03\x04\x17\x41\x8e\x0b\x1a\x0d\x7f\xa2\xee\x86\x1f\xb7\xe5\x6f\x7a\x37\x0a\x7d\x44\xb7\x15\xe8\xee\x6d\x9d\x6b\x11\xb5\x72\x66\x72\x4e\x84\x11\xc6\x35\x75\x20\xbe\x90\x63\x42\x4a\x89\x6f\x23\x2e\xcb\x03\x2a\x78\x8f\x44\x64\x29\x9c\x92\x37\x54\xc4\x40\x1c\x46\x8c\x1a\xf8\x14\x12\x05\x4d\xce\x70\xbf\x86\x90\xba\xf2\x43\x9b\xe4\x6f\x61\x9b\xa0\xe3\x6e\x93\xe1\x49\xcb\xe7\x52\x59\x77\xd8\x9a\x91\x91\x8f\x53\x51\xfa\x28\x40\xf7\xcd\x49\x1e\x66\x9b\xa9\x53\xba\xdb\xca\x5d\x85\x8c\xa3\x49\x92\x44\x23\x93\xa2\x68\x49\xaa\xde\xa2\x1b\x07\xf7\x78\x5b\xa5\xb1\x54\x29\xdb\x6f\x49\x97\x62\x87\x10\x5a\xe2\xe9\x6e\xac\xa7\xca\x52\x23\xc6\x48\x46\x0c\x21\xc9\xfe\xfc\xeb\x6a\x60\x25\x4a\x80\xea\x4b\xb8\x7d\x71\xc6\x14\x57\xa8\x82\x95\x36\xf6\xfa\xbe\x6a\x9b\xfc\x6e\x21\x84\x5a\x0f\xf7\x13\x1b\xde\x82\x42\x9c\xe7\xa9\x11\x23\x7d\x24\xab\xc8\xf0\x2d\x74\x1c\x2f\x5c\x6d\x3b\x9b\xde\x87\x39\x2b\x05\x8e\xf9\x5e\x94\x99\x79\x5a\x22\xa0\xfb\xa3\x74\x6d\x39\xc1\xac\x99\x6b\x93\x96\x74\x1e\xfd\xcf\x99\x20\xa9\x6c\x91\x04\xac\xd0\x8f\xc5\x8f\xdf\x6c\x30\xa1\x28\x3c\xd6\x0d\xd8\xbe\x81\xf9\x79\x8c\x16\x15\x23\x10\x1d\xb6\x82\x6b\xe7\x13\xd0\x75\xae\x06\x6f\x7e\x38\x32\x87\xcf\x40\xae\xf3\x12\xc6\x61\xc2\xd6\x41\x0f\x90\xb8\xed\xc5\xb9\xe2\x41\xe1\x71\x87\x11\x50\x84\x76\x04\x17\x05\x5c\x3e\x75\x02\x53\x45\xd8\xd6\xf1\x12\x0a\xa4\x58\x9b\xc7\x7c\x02\x55\xbe\xee\x86\xb2\x02\xf9\x05\x4f\xbf\x43\xd2\x41\xb5\x5e\x6f\x3d\x85\x7f\x3e\x17\x73\x87\x82\xbd\x55\x93\xc7\x7c\xf3\x2b\x8e\x8c\x3a\xc5\x5d\x64\x4a\x4c\x8e\xe5\x35\x18\x43\x94\xdd\xbe\x82\xa4\x40\x6f\xaf\x77\xf6\xf6\xbb\x10\x63\x6e\x6a\x65\xad\xa7\x65\x3e\xc8\x65\xe7\x53\x8d\x7a\xc3\x05\x5b\x38\x52\x87\x98\xc1\x42\xc9\x39\x9c\xdc\xc4\x86\x3c\x10\xe8\x02\x0a\x60\x97\x01\xb5\xf1\x34\x4c\x98\x21\xcc\x94\x7e\xa3\x60\xb3\xd0\xd8\xad\x27\x53\x42\x33\xf4\x23\x53\xf7\xab\x3d\x58\xfc\x6a\x07\x8c\x9b\xc8\xaa\x0f\xe8\x89\x40\xc4\xa5\x86\xdb\x78\x6d\x57\x71\x16\x1e\x9a\x1f\x74\x15\x24\x97\x80\x30\x19\x05\x62\x5e\x1a\x0d\x4e\x62\xd8\x7c\x29\x32\xf2\x5d\xc9\xb6\x62\x63\x8b\x37\xdf\x84\x44\x95\x72\x5f\xa2\xca\x51\x8f\xa2\xff\x5d\xe2\x13\x66\xd2\x05\x19\x60\x4d\x3c\xa5\x0f\x89\x35\xcc\x64\x8f\xdc\xd8\x07\x17\x25\xe4\x8d\xc0\xb9\x8f\xdb\xd7\x15\x9f\x75\x68\x67\x1a\xb3\xfe\x8b\xc6\xc6\xa8\x8b\xe3\x7b\xe5\xc8\xce\xab\x85\x4c\xbc\x34\x07\x7f\x57\x0d\x66\xf6\x8f\xe7\x77\x02\x75\x55\x85\x44\xbd\xe6\x4d\xd6\x43\x4d\xac\x50\xe1\x7e\x39\x8d\xe0\x7b\xe3\x08\x00\x0c\x0d\xaa\x59\xc1\x56\xd0\x8c\x2c\x0b\x41\x04\x13\x85\x2f\x50\xfe\x73\x43\x34\x22\x45\xe3\xa7\x8f\xd6\x50\x3c\x62\x8e\x45\x3c\x02\xf7\xdb\x37\x51\x1f\xf1\x67\x78\x40\x28\xb8\x28\x19\xbf\xfb\x95\x96\xdc\xf5\xd0\x2c\x7f\x0b\x3a\xa1\x3c\x01\x33\xe8\x80\xda\x2e\xf3\x2f\x21\x4f\xca\xfa\xf7\xed\xe0\xc4\xbc\xf6\x26\x9e\x17\x3a\x5f\x18\xd6\xfd\x50\x2d\x13\xe7\xd2\x0e\x48\xd9\xda\x6a\x86\x2c\xbd\x47\x9b\x08\x8b\x06\xf5\xd6\xbe\x32\x83\xed\xe3\xcd\xa6\xb6\x03\xf1\x3c\x63\xf8\xed\xd1\x46\xb2\x61\x80\x46\xcc\x11\x3a\xf6\x28\x71\x95\x16\x07\xad\x41\xbe\x0e\xd9\x6d\x0d\x88\x40\x52\x12\x53\xab\xda\xd8\x3e\x20\x72\x52\x93\xb0\x17\x99\xae\xd2\xf8\x22\xba\x65\x93\xee\xa3\x68\x9d\x5a\xbe\xb2\xa6\x89\x6b\xe6\x26\x63\xc0\x28\xfe\xf6\x82\x49\xed\x98\x5e\xcc\xd8\x1d\x9d\x2f\x6c\x06\xb8\xc6\xc9\x39\x1d\x29\xa4\x69\xd2\xf4\xe2\xda\xf8\x84\x02\xb5\x5a\xb4\x49\x39\x8d\x48\xb5\x36\x1e\x31\x68\x2f\xad\x44\x0e\x28\x86\xad\x03\x28\x79\x20\x74\xad\x6f\x67\x93\xdf\xd0\xbf\x7e\x93\x40\x77\x19\x5a\x79\x57\x3c\xf2\x6b\x5a\xd2\x4a\xb3\xe1\xe5\x28\x8a\x04\xf9\x85\x8e\x48\xb0\x5e\xe0\xa4\x8f\xc8\xeb\x34\x11\xae\x8f\x41\x59\x43\x8a\xc9\x38\x30\x57\x1d\xb4\x7f\xfd\x8b\x1a\x0d\xcb\xb8\x47\xd2\xd9\xc6\x02\x89\x3d\xc3\x81\x9a\x51\x6a\x04\x9b\x43\xf6\x5e\x13\x09\x28\xc1\xec\xad\x57\xaa\xc6\xba\x5a\x16\x6e\x93\x07\x24\x1a\xb2\x71\x5d\x87\x95\xd5\x10\x1f\xe9\xa2\xa4\x2e\xc6\x80\x53\xf3\x71\xaa\x7b\x0c\xf8\x65\xfd\x8d\xa1\xd3\xed\x5b\x10\x4e\x37\x26\x4b\xa9\xe0\xba\x2b\x89\xed\x28\xde\xc7\x70\x32\xcb\x12\x31\x9a\xf9\x0c\xca\x36\x61\x48\x6d\xab\x38\xde\x1f\xd7\xe1\x55\xd8\x31\x52\x39\x12\xfa\xa8\x4f\x4d\x1e\x8f\x5a\x12\x47\x63\xb3\xaf\x0a\x16\x64\x6f\x9b\x8a\xbf\x6a\x6e\x37\xfe\xca\xc1\x3d\x29\x7a\xeb\xb6\x1c\x62\x5f\x8a\x0e\x1a\x55\x3f\x5c\xe3\xfe\xd5\x62\x84\x71\xfd\x34\xb2\xde\x2b\x1a\x72\x28\x4e\xa4\xe5\xbe\x47\xb7\xf8\x33\x85\x1c\x17\x6e\xf6\x74\xfe\x70\x68\x68\xe2\xe8\xbb\x2f\x31\x96\xec\xc1\xbf\xfa\xee\x62\x0e\x4e\x5f\x39\x38\x27\x54\x1b\x83\x2a\x9e\x24\x24\x7b\x25\x71\xe7\xc2\x91\xfd\xf6\xd7\x4b\xb6\x8a\xc6\x73\x0e\x2d\xe4\x39\x37\x10\x5e\x2b\xbc\x7b\x2b\x93\xc6\x40\x2f\x90\x6e\x56\x41\x1a\xa4\xc6\x4e\xb1\xa2\xd7\xfd\xb9\x44\x8f\xef\xa2\x87\xa7\x49\x31\x67\x3e\x72\x5e\x04\x92\x1b\x0b\x9a\x17\x57\xd4\xd7\x61\x74\x06\x21\x74\x08\xd5\x8c\xa6\x4e\xdc\x53\x64\x5e\x8f\x27\x11\x5a\xc0\xa4\x9b\x9d\x51\xac\x76\xb7\xcc\x70\x8c\xee\x2f\x07\x9b\x34\xbd\xad\x3a\x57\x1c\xd7\x62\xaa\x75\x10\x85\x8e\x3d\x3b\xcc\x1d\xdf\x12\xfc\xb7\x3c\x34\xb2\xab\x98\xc8\x29\xae\xc8\xdb\x57\x1f\xff\xed\x94\x5a\xf5\x09\x69\xd2\xfd\xad\x0f\x71\xe6\x00\x43\xcc\xe6\xb5\x39\xc3\x33\x45\xae\x81\xbd\x27\x35\x68\xb2\x93\x2b\xc7\x5b\x1c\x5b\xc7\xf5\xf8\x6c\xec\x1f\xbe\xdc\x3e\x47\xaa\x45\x34\xed\xd5\xf8\xa0\x6d\xa3\x4a\xdf\x94\x31\x12\x8d\x46\xaf\x81\x3c\x9c\x60\x50\x76\x45\x88\x5e\x7b\xa3\xb1\x70\xef\x11\xa2\xd8\x9b\x79\xc6\xfe\xc6\xfa\x54\xe4\x19\x58\x5f\x52\xb3\x4f\xa7\x93\xe3\xab\x20\xdc\xb3\xbf\x6b\x0f\xd5\x43\xaf\xf7\x2b\x4c\x34\x8f\xf7\x72\xae\x36\xef\x88\xea\x51\xfb\x05\xfa\x6c\xd7\x14\x77\xcb\x21\xb4\x04\xab\x33\x3c\x17\xa2\xca\x2a\xc9\xba\xec\x25\x0a\x70\x80\x27\x6e\x08\xa0\x71\x98\xc6\x98\xe5\x36\x51\x55\x4d\xaa\x09\xc8\x25\x62\xa8\x52\x70\x5f\x02\x82\x77\x90\x99\x11\x26\x24\x3e\x6f\x52\x2d\x8c\x82\x55\x04\x95\x1b\xa8\x10\x11\x94\xec\x9c\x4a\xd9\xff\x51\xf1\x1d\xfa\x83\xa7\xc6\x31\x09\x97\x0e\x12\x9d\xc3\xed\x5d\xa9\x6a\xf1\xbf\x64\x28\xfc\x2f\x9d\x3b\xc3\xc8\x4f\xfb\xb1\x97\x4c\x9a\xc5\xa1\x4d\x63\xd8\xeb\x9d\xcc\x5a\x7d\x2c\x33\x56\x72\xbd\xee\x9c\x34\xde\x31\x4e\x90\xf9\x08\xf8\x14\xba\x62\x0d\x18\xf4\x22\x7c\x73\xc0\x07\x09\xa0\x18\x8c\x10\xec\x2d\xb7\xe0\x7c\xc0\x25\x6b\x75\x29\xdf\xa2\x58\x3d\x06\x17\xcf\x1a\x0a\xee\x3a\xbd\x43\x0a\xe4\x8d\xf5\xd2\x28\x05\x23\x34\x24\x08\x1a\x9a\xec\x1e\xf5\x61\x46\x80\xd7\x82\x7b\x69\x9e\x7b\x41\x27\xed\x57\xcc\x17\xf2\xd6\x63\x0d\x24\xce\x65\x5d\x74\x0a\x03\x9b\xea\x4e\x89\x15\x76\x27\xa5\xf5\xcf\xb9\xe9\x7b\x80\xca\xc2\x9c\x0f\x19\x3e\x96\x2f\x7d\x26\x29\x66\xec\xa3\x5a\x88\xa4\x36\x63\x67\x70\x90\x35\xc2\x3c\xa0\x5b\xe4\xb0\xca\xeb\x2e\x5d\x36\xe4\x49\x1c\x6e\xe2\xf6\xff\xe4\xa1\xd0\xb4\x6d\x2c\x0b\x4b\x51\x17\x34\xcc\x1c\xc0\x0c\xf6\x9d\x32\x29\xde\x2f\xe8\x27\xd3\x9c\x8b\x34\x5c\xbc\x41\x49\x89\x9e\xdf\x51\xe2\x20\x41\x21\xc5\x75\x9d\xa8\xa4\x60\x71\x23\xc7\x18\xfd\x8a\x30\xeb\x4e\x25\x04\xab\xca\xfe\x50\x0d\x3c\xa4\x25\x5a\xc5\x28\x7f\x51\xca\xc0\x85\x6a\x23\xde\x2c\x07\x24\xce\x7e\x4a\xf4\xd6\x69\x81\xc1\x17\xea\x38\x66\x36\x7d\x09\x1e\xbd\xa2\xe7\xc4\xc2\x41\x0e\x21\x31\x63\xde\x18\x95\x9c\xac\x83\x05\x35\x67\xf6\x66\xf6\x05\xb1\xa2\x4e\x52\x33\x97\xb2\x48\x45\xbd\x89\xf1\xf4\xea\x61\x8f\x8a\x48\x61\xd6\x61\xea\x29\xdc\xcc\xef\x07\x1d\xde\x93\xc6\x3b\x5b\x03\xb6\x45\x17\x1e\xc0\x27\x92\x67\x1f\xd3\x84\x73\x77\x55\xb6\xbd\x60\x17\x0c\xc7\xa1\xb4\xc1\x34\x0c\x16\x75\xb3\xf7\x50\xbb\x39\xb7\x6b\xde\xd7\xf0\x1d\x2f\x7f\x67\x20\xec\x21\xd0\x34\xc8\x4f\x62\xf5\xa1\xb8\xa2\x5c\xb4\x48\x43\x7a\x4e\x22\x2d\x0b\x52\x4a\x02\xdf\x5c\xe1\xa3\x72\x60\xae\x1d\x72\xba\xd2\x2e\xb8\x30\xfb\x21\xac\x60\x07\xdc\x82\xdb\xcc\x11\xf6\x5b\x06\x1f\xe2\x06\xf5\x9e\x51\x84\x4a\x8a\xc7\xec\xba\xb5\xee\xfd\x6f\x54\x63\x4d\xfc\x82\xfc\xc6\xfa\xc7\x59\xc3\x20\x13\xf2\x9a\xcc\xe9\x57\xdc\x6b\x33\x0f\x77\x99\x16\x8e\x86\xe9\x19\x66\x7a\x9f\x6d\xf8\xa0\xbb\xa6\x0a\x48\xf3\x1a\x0b\x56\x2f\x1a\x36\x7b\x7e\x55\xc8\xd8\x25\x04\xa4\x9b\xad\xde\xd7\xdc\xda\x8e\x29\x65\x2d\xac\xca\xee\xea\xd6\xcb\x3a\x74\x2e\x4b\x23\x24\x82\x01\x7f\x44\xe5\xce\x32\x44\x1a\xfb\x32\x33\x4e\x20\x42\xf4\x50\xfa\x1c\x3d\x9d\x07\xbc\x58\x4c\x10\x31\x74\x02\x65\x70\x7c\xc6\x13\x2b\xe9\x4d\x22\x20\x13\x26\xc7\x58\xc5\x7e\x93\xb8\x17\xaa\x6c\xcd\x32\x82\xe7\x2a\x56\xd9\xce\x7d\x5d\x59\xd8\xba\xb1\x0c\x6c\xbe\x5b\xdd\xe7\x2b\x3b\xac\x66\x08\xd2\x31\xc4\xf1\x77\x43\x8f\x21\x19\x69\x9c\x85\xc2\x30\xd3\xc2\x09\x8e\x91\x2d\xcb\xef\x4d\xfd\x19\xd0\xae\xf7\xba\x67\x76\x15\x5c\x31\xac\x01\x7d\x79\x14\x5b\x9a\x22\x54\x09\x4e\xd4\xc6\x0e\xc5\x89\xc5\x5c\x4c\xec\x68\x1c\xf0\x10\x84\x55\x76\x43\x41\x31\x5f\xbd\xa0\x66\x7e\x36\xea\x5c\xfb\x9c\x45\x49\x58\x65\x4e\x3c\xbe\x7c\xef\xdc\xc5\x40\xfb\x2f\x1d\x55\x12\x81\x23\xb7\x69\xb5\xae\xb5\x12\xd8\xfd\x2b\xc9\x24\x71\x2d\xa5\x02\xcc\x92\x02\x44\x7d\x19\xa6\xda\x1d\xd3\xa0\x26\xb5\x4e\x20\x04\x63\xdb\xe8\xa6\x29\x75\x9e\xaf\x9f\x57\x65\x62\x4d\xa1\x76\x35\x35\xda\xa8\x6d\x33\x2b\xd7\xd0\x12\x93\x6b\xc0\x3c\xfc\xf4\x6e\xbc\xf3\xde\x5c\x7a\xb8\xb6\xb7\x43\xc7\x81\xe4\x90\xe7\x68\x29\x1d\x37\xd9\x67\x64\xee\x6d\x21\x6e\xad\x21\x99\xa1\xb9\x0f\xe8\xd1\x11\x70\x59\x2f\xf9\xc1\x0f\x2a\x0c\xb3\x6d\x67\x84\x8f\x97\x4e\xbe\xeb\x61\xf0\xdb\x9e\x69\x5f\x2a\x18\x63\x1c\xa8\x27\x28\xa4\xf1\xe1\x95\xd0\x70\x4a\x51\xfb\x57\x0d\x48\xa6\x73\x92\x38\x3c\xb5\x8f\xf9\xe0\x21\x15\x19\x94\x6f\x82\x60\x1d\x8b\x9f\x88\x40\x24\x3f\x78\x43\x00\xab\xff\xec\x24\x19\x59\x59\x8f\x44\x86\xaa\xc9\x0b\xe8\x66\xb8\x89\xa6\x1f\x22\x33\x03\x47\xf1\xb3\x10\x70\x70\xd1\xea\xed\xd2\x80\x6a\x63\x15\x8e\xb3\x51\xf8\xcf\x5e\x3d\xba\xb4\x62\x67\xf7\x2d\x59\xbf\xfb\x7e\x89\x64\xe6\x42\xf1\xf4\xbb\xac\x9f\x39\x61\x26\xf8\x6c\x5b\x73\x22\x9b\xf3\x6f\x2d\x12\xe5\x8d\xf4\xc0\x01\x4e\x01\x3a\x06\x37\x28\x5d\xfb\x1f\xcf\x45\xeb\x24\x4d\xa9\x8d\x31\xb4\x5c\x8e\xac\x99\x12\x6a\xa7\x6f\xab\x55\x15\xb2\xbf\x4c\x8d\x08\x28\x50\x8d\x41\x78\xe2\x9d\x0a\xdc\x1e\x12\xc6\x31\xb4\xe0\x1d\x38\x50\x7f\x29\x8e\xb7\xce\x55\x86\x1d\xd1\x47\xe4\xb6\xf8\xa1\x14\x60\x7a\xc6\xb8\xe7\x65\xbf\xa2\xe6\xc3\x3c\xf8\x0d\x81\xf0\xa6\x04\x5a\x4d\x75\xb6\x20\xa8\xb2\xb2\x29\xbe\x8f\xdc\xb1\x8b\x49\xf6\xce\x09\x18\x44\x4c\x74\x01\xb4\x08\xda\x38\x55\xa2\x9e\x87\x08\x18\x9e\x2d\x60\x35\x5c\xce\x90\xef\x7e\x15\xa0\xa2\x55\x3b\xb5\xb4\xc0\x57\x9c\x5f\x0f\x4a\x26\xa5\xd6\xe0\x7a\x24\xe0\xd7\x4a\xfa\x5d\x72\x41\x21\xa2\x4b\xf3\xe1\xbc\x22\x61\x7b\x43\x99\x4e\x73\xe0\xb7\xa8\x20\xdf\x64\xf5\xf7\x5b\x33\xff\x3c\xbe\x12\x19\x21\x76\x5b\x66\x69\x92\xa7\x46\x1c\xe0\x4c\xd0\x1b\x7a\xe2\x5d\x10\xea\xe6\x83\xd6\x41\xc9\x7b\xa5\xfe\x44\xd9\xd0\xa1\x15\x16\x18\x03\x0f\x3d\x6c\x23\x19\x29\x27\x8e\x2c\xf4\x5c\x48\x0c\xb1\xd2\x1c\x83\xf7\x5e\x30\xf8\x63\xd1\x39\x37\x19\x64\x8d\xfb\xad\x14\xfa\x0e\xe6\xae\x0f\xfe\xe6\x7f\x26\x8c\xba\xaa\x60\x3f\x73\x66\x3e\x3a\x4a\x75\xfe\xec\x9d\x1e\x18\x66\xa8\x13\xa6\x6c\x6b\x92\x80\x43\x62\xca\xec\xeb\x35\xea\xe4\x0f\x28\xe1\x9e\xbf\x5a\x95\x73\x0e\x52\x59\x53\x1c\xe1\x19\x6d\x9c\x00\xff\x7a\xae\x96\x40\xfa\x2f\x7f\x95\xe7\x21\x72\xba\x19\xe9\x59\xef\xde\x2b\xc1\xb8\xe6\x8c\x66\x25\x0b\xe1\x70\xcd\x53\x3f\x46\x6f\x03\xc3\x7a\x94\x90\xc3\x3f\xa4\xe1\xea\xa3\x84\xc3\xe2\x69\x31\xc8\x6a\x5c\x27\xc9\xbe\xfa\x17\x14\x67\xe7\xf9\x7b\x2a\x8e\xf0\x48\x64\xa9\x20\x47\x2d\x3b\x0b\x1b\x65\x11\x3f\x90\x40\xd5\x4f\x8d\x01\x1b\xd7\x24\x48\xf3\xcc\x15\x72\xa8\xbf\xe9\xf1\xb8\x24\x94\x33\x66\x55\x37\xa9\x0b\xbb\xe5\xae\x73\x1d\xd5\x4e\x37\x6f\x0b\x2d\x9e\x4f\xf5\xda\xa2\xe9\xd8\x87\xd8\xb2\x8c\x7d\x8a\xdd\xa3\xb9\x23\xe1\x4d\x3c\xa0\xea\x2c\xb1\xc3\x1f\x2d\x28\xc0\x44\x79\xde\xe3\xe5\x13\xb5\xb7\x84\x4b\xe9\x48\x88\xb7\x6d\xf8\xa3\xfe\x05\xb2\x42\xb6\xc9\x1e\x17\x7b\x8a\xbe\xd1\xd6\x63\x67\x6b\x1d\x73\x04\xf7\x89\x51\xee\xaa\x86\x22\xa2\x5d\x5f\xad\x8b\x94\x5e\xc6\x89\x3a\x1b\xcf\xdb\x8b\x43\x84\xb2\xa6\x73\x0b\xad\xc8\x1a\xb2\xe1\xcd\xb7\xb6\x01\xf4\x9c\x28\x49\x2d\x66\xde\xca\x11\xd2\x6c\x0f\xd7\xdc\xc5\x8c\xc7\xed\x1a\x07\xfb\x48\x9a\x11\xed\x29\x49\x50\xa5\x21\x46\x86\xdf\xe8\xf2\xaa\xaa\x79\x7d\xcd\x39\xe3\x7f\xf2\xc1\x9b\x4c\x3d\x26\x8e\xb7\xe5\xac\x6f\x86\xcf\x5d\x92\xb0\xc3\x40\x91\xd4\x8f\xfe\xc6\x83\xbc\xc7\xcd\xdf\x8f\x10\x79\xa2\x38\x09\x6c\x00\xa7\x25\xf6\x3e\xb5\xe0\xc6\x22\xd5\x1a\x28\x1d\x21\x6b\xba\xb6\x32\x24\xa6\x29\x4a\xce\x9c\xf9\xa7\xb1\xf6\xea\xdd\xfe\xb6\x1f\xc2\xa1\x5c\xff\x75\x0e\xba\x29\x1f\xff\x03\xe9\x2a\x29\xd3\x1c\x9c\x2d\xce\xe4\x0a\xf3\xf3\x1e\xe5\xd5\x90\x2f\xbb\xd4\xe8\x77\xb9\xa9\x47\x0a\x77\x0c\x60\x92\x24\x0e\x79\xbb\xcc\x4c\xb9\x92\x2c\x0e\x42\x9e\xee\x31\x0d\xc0\x09\xb7\x3d\x75\x42\x97\xb7\xc4\x62\xf7\xc0\x61\xe4\xd6\xe6\x16\x76\xb6\xc2\x0b\x11\x8f\x67\x66\xae\x43\x63\x3e\xe7\x23\xad\xa3\xf8\xe9\x42\x48\x5d\xa5\x45\xd3\x0e\xa0\xea\xcb\xe6\xe8\x2f\xb9\x02\x0d\xd2\x48\x1e\xee\x91\xdb\x1a\x55\xcf\x7b\xeb\x08\xd4\x58\x5c\x5e\x25\x8f\xd7\xbb\xd4\x0c\x75\x93\x94\xc0\x1c\x9f\xe5\xd6\xaa\x32\xb2\xd8\x20\xba\x5a\x08\x10\xdd\xcc\x1e\x3a\x8a\xb4\x84\xc6\x13\x62\x62\xb3\xfc\x09\x35\x4d\xe6\x26\x6e\xe8\x08\x23\x9f\xd0\xcb\x0a\x9a\x97\xba\xcd\x9c\x9c\x69\x21\x4c\x12\x25\xa6\x81\xa7\x5e\xb3\x8c\x6a\x2b\xb5\x9d\xcc\x3b\xe6\xbe\x8f\xde\x90\x2c\x0b\xc6\x21\xdb\x20\xbe\x88\xb5\x15\xb3\x7e\x5c\x19\x4b\x60\xb2\x43\x03\xea\x1d\x78\x84\x82\x99\xf7\x8e\x7b\xe1\x94\x8b\x31\x67\x22\x65\xfd\x27\x54\x32\xbc\xe7\xc2\x73\xd2\xab\xdf\x59\x03\x5a\x5e\xf5\xc3\xb4\xba\x31\x61\x99\x27\x6f\x5d\x22\x2b\xe6\xdf\xf2\xa7\x8f\xfb\x17\x86\x0e\x9e\x32\xc6\xb5\x33\x71\x09\x6e\xec\x3e\x4a\x43\x95\xb3\xc0\x2c\xaa\x7d\x08\x40\x7d\x9c\xd3\xd7\x34\x87\x47\x00\xa6\x2e\xf6\x44\x4f\x35\x9d\x21\xb0\xe0\xf0\x90\x33\x28\x6e\x98\xed\x4c\x8d\x64\xef\xbe\x8a\x1e\x4f\x1e\xb1\x87\xaa\xa2\xee\x8d\xde\x1c\x6d\x82\x76\x43\xe1\xd1\x31\x6c\x85\xa3\x75\x99\xe3\x79\x2c\xac\xa9\x11\x70\x84\x90\xce\xe2\x1d\x47\x7e\x61\x17\xd7\xa7\x69\x9e\x84\x17\xbc\x67\x92\xcd\xc6\xa1\x77\xef\x31\x8d\xea\xbf\xef\xdc\xa9\xac\xef\xb2\xf0\x7b\x5c\xb4\x4b\x26\x6a\x6d\x22\xdd\xaa\x30\x91\xb5\xe9\x93\x5c\x88\xe7\x4c\xd1\xf6\xb7\xe7\x8b\xc8\xce\x60\x0a\x67\x04\x6d\x5f\x2e\xc1\x16\x7c\x58\x4f\xe6\x74\x80\x2e\x85\x00\x7f\x25\xcd\xfe\xb1\x50\x45\xf4\x0d\x80\xf5\xdf\x73\xa4\xa8\x32\xe8\x2b\x75\x8c\x91\x18\x2c\x1d\x5a\x12\x81\x93\x35\xe4\x1e\xf1\xb2\x97\x06\x6b\xdc\xca\xef\x3a\xdd\xc3\xfc\xc2\xaa\x60\x93\x33\x21\xef\xa5\xd3\x7c\xa9\x48\x3e\x2d\x9b\xf5\xff\x5f\x62\x3c\x07\x14\xf3\x04\x65\xac\xfc\x16\x8e\xc8\x60\x7c\x55\x59\xee\x3f\x2f\xa5\x0a\xf6\xf3\x47\x9c\x55\x63\xaa\xa1\x8c\x47\x27\x62\xe8\xac\x0a\xc7\xfb\x94\xc6\xdb\x74\x67\x6d\xf6\xed\xcd\x35\x38\xbc\x4a\x42\xc4\x99\xe1\x46\x1f\x55\xfd\xf8\xee\x67\xbf\x9a\x10\x30\xbe\x47\xa9\x66\xa1\x40\xa0\xd3\xa4\x46\x26\xbe\x76\xb9\xc0\xb5\x38\x00\x47\xd3\x74\x4a\x01\xcd\xc2\x60\x4a\x21\x7a\xf3\x10\xfe\x44\x45\x09\xa7\x7c\xff\xef\xc4\x25\x40\xb9\x00\x57\x9c\x1c\xdc\x31\xc6\xee\x7b\x52\x1e\x39\xf9\x49\x8b\xbe\xa8\x15\x6d\x66\x1d\x4d\x89\x1b\xb3\x87\x39\x7d\x04\x06\x16\x4b\x7a\x6e\x51\x5e\x6b\x94\xab\x73\xd2\x4e\x43\x3e\xe8\x19\xa3\xf1\x1f\x90\xf7\x86\xef\x0c\x95\x87\x7b\x65\xa3\x2e\x2e\x5a\x4c\x61\x24\x85\x5b\xda\x2f\x2f\xa1\x49\x31\x22\x36\x48\x94\xba\xe7\x6f\x0d\x8f\x3c\xc6\x53\xdd\x0c\x5b\x70\xfe\x87\xa0\x2e\x3a\x22\x21\xbb\xe7\x47\x40\xc8\x38\xe0\xeb\xe6\x3c\xe0\x4a\xf8\x5f\x1c\x81\x27\x37\x99\x97\x6d\xb1\x77\x1c\xd8\xcb\xb1\xe4\xf7\x2c\x11\xe0\xb9\x4d\x8a\xb2\xcc\x39\x58\x27\x49\x81\x94\x7b\x33\x76\x74\xea\x2f\xfe\x07\x0b\x16\xee\x20\x19\x0b\xdf\xaf\xe6\xc7\x3b\x07\x27\xdd\x1b\x4a\x32\xa8\x34\xe7\xca\x4a\x92\x39\x96\xbc\x04\x5d\xb0\x23\xd5\x58\x86\xe5\x9f\xe9\x15\x8d\x3c\xea\xb7\xb1\xfd\x45\x7f\x50\xfa\x54\xc5\xaa\xa8\xdf\xbf\x8a\x3c\xb5\xc7\x64\xb5\x49\x12\xd7\x4b\x61\xcd\xcd\x1c\xad\x87\x74\x44\xf6\x0a\xea\xb5\x1a\x2a\x72\x6e\x4a\xd2\x1b\x5a\xcc\x68\x65\xa1\x52\x02\x51\xa1\x55\x0d\xc8\x5e\xbe\x8e\xb4\x40\x54\x63\x69\xdb\x62\x93\xcc\x40\x7c\x0d\x0d\xb0\xc3\x87\x43\x98\x5d\x3a\x86\x91\x1c\x7a\x70\xa6\x90\xd3\x23\x22\x80\xaf\x52\x14\xf1\xa4\x8e\xfb\x50\xdb\xe7\x7d\x6a\xb3\x4c\xcb\x74\x50\xfe\xad\x4d\xad\xa2\x00\x9f\x1a\xaa\xf2\x10\xe3\xf8\x1d\x49\xa7\x8d\x18\xe8\xae\x9d\x1d\xac\xd5\xbf\x5f\xa3\x9b\x5d\x29\x89\x72\x71\xb9\x29\xe5\x11\xaf\xa2\x22\x59\x1c\xd2\xa6\xcb\x74\x7c\x75\x88\x73\x5a\x77\x6c\x44\xee\xca\xee\xa9\xc4\x5b\x8d\xda\xec\x5e\x51\x06\x4c\x00\xe8\x95\x22\x0f\x5e\x5b\xd8\x8c\xde\xbf\x36\x13\x2b\xaf\xad\x3d\x99\x62\x0b\xea\x04\x51\x61\x94\xc9\x88\x4e\x8a\x44\xd5\xc5\xb2\xdf\xf6\x10\xf7\xf9\x2d\x57\x72\xb1\x45\x3d\x85\x23\x6a\x82\x60\x44\x56\x51\x33\x66\x43\xb1\x2f\xaf\xd9\x6e\x3e\x9f\x1f\x35\xd1\x4d\x02\x1f\x88\x80\x62\xd2\x5c\xef\xd3\x8c\xb8\x94\x0e\x2a\x06\x2a\xac\xdb\xda\x9d\x0b\x8b\x08\x41\x1f\x65\xc4\xd3\x84\xff\x10\x0e\x54\xc2\x0c\x20\xe2\xd1\x1a\x26\x49\xc2\x7b\xca\x10\xc0\x47\xbd\xda\x87\xd1\x98\xe5\x5f\xb1\x1e\xc4\x09\x8c\x58\x99\x10\xe4\x71\x9d\x7f\x02\x0f\x2b\x75\x83\xfc\xd2\xab\xd0\xae\xd4\x7b\x81\xae\xf1\x92\x1f\x2d\x70\x9b\xff\x3c\x13\x5b\x63\x17\xef\x4c\x51\x13\x3d\x86\xd2\x42\xbf\x75\xb1\xf5\x13\xbf\x87\xda\x9e\x38\x9e\x76\xa1\xcf\x17\xb2\x09\x1f\xf4\xc2\x53\xe5\xfd\x45\x1a\xf9\x03\x0a\xad\x26\x6f\x6e\x30\x01\x5b\x1b\x03\xa4\xd6\x14\x9d\xaa\x2c\xe5\x84\x34\xe9\xe4\xa7\x61\x68\x2a\x21\x0e\xdb\x85\x5a\xa4\xe6\xd6\x9c\x18\xab\xb0\xd1\xa8\xed\x8e\xca\x60\xc5\x2e\x5a\xe2\x2a\x9f\xb4\x4f\x2a\xe9\x6c\xe3\x47\xda\xd7\x93\x88\xe7\x12\x2f\x26\xb2\x14\xf6\x51\xbd\x8c\x51\x83\x57\x1f\x8f\xd9\xcf\x10\x4e\x59\x05\xae\x79\xbd\x62\x00\xe0\x08\x89\x44\xe5\x33\x0b\x42\x25\x55\xe9\x1b\xbd\xe3\xe1\xcd\x45\xdb\x9d\x72\x6f\x1e\x70\x86\x9a\x7c\x54\x69\x39\xa2\x70\x55\xb4\x7e\x7c\x0f\xa0\xc7\x64\x1d\x40\xa6\xe8\xb9\xc5\xb2\x57\x96\x96\xee\x2e\xf2\x47\x57\x91\x3f\xb9\x13\x59\x6e\x10\x71\xd8\x51\x85\xdb\xff\xbe\xa4\x74\x95\x27\x07\x13\xa2\x44\x90\xd0\x37\xce\xd0\x16\x28\x19\xf4\x0e\x7e\xc9\xfd\x06\x56\xd1\x6b\x3a\x61\x9f\x84\x31\xf5\x0e\x27\x23\x14\xee\xec\x96\x1e\xa8\x4a\xa4\x97\xa5\xca\xd8\xc5\x4d\x79\xa9\x86\x5a\x7b\x08\xcf\x06\x53\x37\x55\x92\x21\xd1\x74\x44\xd5\x84\xb9\xab\x4e\x30\x8d\xb6\x8b\xfb\x9d\xa1\xdc\x5a\x86\x18\x08\xc4\x6c\x75\xcb\x8a\x8b\xb6\xc8\xd5\xd7\x73\x1f\xd5\x26\x16\x89\xc1\x8a\x7a\x12\xfe\x51\x52\x40\xfe\xaf\x75\x64\xe5\xdd\x75\x67\x10\x8c\x91\xb6\x3f\x17\x4d\x60\x6c\x23\x3d\x91\x32\xad\x59\x89\xe9\xd8\x46\x40\xb0\x09\x47\x32\x89\x1b\x11\x4c\x76\xd6\xee\x02\x17\x2c\x26\x5b\xb5\xcc\xf4\x7a\x96\xa2\x35\x19\x85\x26\x3d\xc9\x53\x1f\x03\x6e\xc1\xa5\xb8\x6b\x31\xf9\x07\x4d\x76\x0a\x64\xda\x8c\x02\x9a\x64\xde\xb2\x97\xef\x82\x3a\x2f\x13\xa4\x5c\x62\xca\xd2\xab\x16\xe0\x18\x47\xb1\x1c\x72\x94\x5d\xe1\xb5\xdc\xdf\x57\x69\xf8\xad\xb1\x00\x5e\x6b\xa0\x66\x81\x06\x88\x30\x45\x77\xaf\xb7\xf2\x86\x38\x1a\x88\xbd\x51\x97\x7d\x17\xfa\xa0\x3e\x9b\x19\x21\x6e\xf3\x8f\xa1\xe1\xc2\xd1\x1b\x25\x50\x46\x3b\x69\xb4\xc0\x54\xa3\x0a\x03\x5c\x64\x7f\xa3\x49\x80\x0c\x6d\x9e\x6a\xb1\xfd\x1c\x5e\x0c\x7d\xb4\xbe\x6e\x5f\x92\xc4\x93\x26\xff\x39\x01\x57\x4b\x79\x32\x95\xf1\xcc\x33\x6d\x8c\x23\xb2\x5b\x9b\x59\xab\x1a\x7e\x6a\x27\xfe\x6a\x81\x11\x9a\x9a\xbc\x17\x41\x8b\x72\x76\x6b\xcd\x20\xdf\xee\x9c\x41\x2b\xe7\x1f\x86\x17\xf2\x6f\x4c\xd2\x35\x6a\x91\x68\x0d\x79\x8d\x33\x59\xc4\xcf\x1c\xd6\xb2\x3c\x64\xdb\x30\x33\x8a\x63\xfc\xbd\x9d\x11\xde\x5c\xeb\x9b\x97\x6b\xd2\xec\x00\xa3\xef\xef\x4c\xfe\x56\x09\xdf\x85\x1e\x69\xce\x2d\xc1\x71\x2a\x9b\x1a\x1d\x7d\x42\x0b\x4f\x55\xa7\x0c\xde\x3c\x36\x3b\xb1\x3a\xe8\x80\xce\xec\x6b\x75\x22\x57\xb4\x6a\xf4\xde\xf0\xcd\x72\xd0\xba\x46\x9d\x20\xb9\x16\x40\x4c\xa6\xa4\xc7\x52\xa1\x44\xb9\xf8\x07\x7d\x58\xef\x2d\xc7\x5e\xc3\xfe\xd2\xea\xe1\x6f\x5f\x65\x29\xe1\xcb\x3b\xeb\xb3\xfb\xec\x3d\x83\x21\x01\xd2\x24\xb1\x38\x89\x9a\xfe\x0b\x94\x4a\x84\xfb\x17\x15\x70\x6a\x4a\x52\x6e\xd2\x77\x67\x8f\x22\xde\xca\xdb\x89\x35\xff\xb0\x84\x82\xfc\xac\x2f\x2b\x97\x26\x06\x86\xfb\x97\xeb\x06\xde\xd3\x42\x5d\xca\xd9\xd5\x6f\x61\x71\x2b\x63\x75\xfb\x13\x7a\x86\x0a\xb7\x44\xb3\x25\xa2\xe7\x8d\x17\xac\x7b\x7a\xdb\x50\x53\x6e\x85\x7e\x0c\xbd\xe8\x18\x39\xfc\x88\x0e\x8a\x1b\xb3\x00\x6c\xac\xfb\xc0\x98\x61\x82\x3a\x56\xb9\x1a\x87\xb6\x36\xa1\x45\x9d\x14\xbd\x05\x80\xd2\x17\xf3\xe6\x56\x39\x55\x17\xe9\x52\x8f\xa6\x0b\xd5\x68\x8a\xa5\x03\x93\x8a\x1f\xa0\xe5\x8a\x8d\x7b\x85\x30\x33\xc0\x7b\x5c\xe4\xc3\x12\xfd\xa6\x36\x26\x8d\x2a\x1a\xcd\xef\x4e\x05\x4d\x28\xbc\x98\x55\x1a\xc0\xcb\xb6\xb6\xe8\x31\xda\x34\x82\x97\xb0\x09\xde\xb8\x2e\xd1\xb8\x31\x47\xde\x7e\x89\xee\x7b\xdc\x40\xe0\x29\x6d\xad\x1b\x7e\xbf\x7d\x75\x60\x05\x27\xa9\x69\x15\x78\x7f\xf7\x50\x14\xce\x8d\xe7\xcc\x8b\xfd\xd8\x58\xe4\x7d\xb8\xc9\x60\x45\x86\x57\xff\x6b\x00\x90\x84\xa6\x88\x6d\xe6\xc1\x0c\xab\x46\xe1\x6c\x51\x2f\xb1\x5c\x29\x75\x8c\x17\xd4\xfb\x2d\x56\x93\xb6\x84\xa9\x2c\x1a\x9d\xf3\x15\xef\xf2\x1e\xa1\xda\xda\xf1\x29\xd2\x6f\x40\x59\xba\x37\x58\x8e\x1b\x78\xf1\xa1\x7e\x73\x8c\x96\xb4\xe1\xea\xa0\x01\xfa\xd6\x26\x8d\x45\x77\x25\xe6\x96\x2b\xfd\xa0\x84\x29\x01\x43\xf2\xe6\xb8\x75\x79\xe9\xb2\xd4\xc0\xf7\x35\x0a\x15\x6b\x3d\xa2\x9e\xb8\x8b\xa9\x2f\xf2\x5c\x14\xaf\xc9\xa4\x8b\x5c\x30\xa2\x70\x12\x0c\x6f\xa8\x9a\xe1\xff\x7b\x8d\x98\xd9\xea\x4b\xa9\x72\x59\x03\xa5\x0f\x36\x90\x3b\x4d\x42\x1b\x67\xc1\x35\x22\x72\xc1\x3a\xb5\xf7\x5a\xb0\x3b\x01\x32\xbc\xa4\x59\xe9\x0d\x7f\xd0\x7d\x03\xa5\x72\xfe\x49\x41\x1f\xdf\xd4\x4b\x98\x75\xac\xca\x04\xef\xf4\x56\x16\x0c\x08\xc7\xe0\x31\x71\x6a\x31\x99\xbb\x30\x85\x54\xb3\x12\x27\xa3\x63\x49\x97\xb3\x5e\x19\xb8\xa4\xf7\x74\x85\xe4\x57\xf7\xbd\xd9\xcb\x25\x90\xe2\x66\x17\x11\x64\x7b\x21\x94\xa5\x19\x8b\x2e\xb1\x71\xee\x39\xdd\x40\xbc\xdb\x0c\x77\x4a\xb8\x9c\x07\xcc\x07\xe5\x09\xb5\x6b\xf5\xf9\x07\x8a\xed\xfb\xd5\x2b\xea\x66\x2c\xbe\xac\xd2\xd6\x80\xd0\x4e\xe0\x75\x97\x7e\x63\xef\xc5\x4b\x5d\xcc\x74\x1c\x52\x59\xab\x77\x95\x4c\x5c\x3e\x9c\x2d\x8b\x11\x12\xce\x8b\x5a\x6a\xaf\x21\x3b\x37\x10\x09\xf0\x2a\x66\xc0\xae\x4b\xc7\x5f\x3c\x95\x19\xbc\x21\xff\xe4\x67\xea\xe9\x87\x5e\x0d\x73\x6d\x77\x90\x2e\xf8\xd4\x5c\xd6\x98\x42\x89\x2f\x6b\xe8\x25\x51\xec\x45\xd7\x88\xf3\x26\xed\x5e\xbd\x85\x35\x65\x47\xc6\x53\xa3\x79\x90\xdc\x21\xd3\x66\x5e\x52\xa9\xa5\xd7\x45\xbf\xc6\x06\xcc\x59\xb1\x83\xb3\xf9\x99\xb1\x78\x17\x2b\xf7\xf2\xd2\x03\xd2\x5f\xd3\xaa\xb4\xca\x7b\xd8\x82\x6f\xa8\x09\x6c\x9d\x0b\x9f\x47\x36\x1a\xba\x8c\xa9\x3b\x79\x54\x3e\xf5\xc1\x09\x93\x39\x56\xf2\x1d\x03\xca\xee\x77\x4d\x8c\x2d\xfe\x53\xb4\x9c\x3e\xd3\xc4\xff\xcd\xe2\x32\x97\x10\xc5\x47\x9c\xcb\xd7\xcc\x21\xe2\xfd\x89\x07\x97\x3c\x84\x7c\xfb\x5f\xd3\x45\xe1\x31\x48\xd2\x2b\xdd\x31\x00\x9e\xf7\xaf\xae\xba\x93\xd0\xf5\x0a\xa6\x6b\xcb\x5d\x31\x4a\x23\xb8\xe2\x31\xe0\x35\x22\x0c\x0b\x59\x7b\x9a\x59\x8c\x8a\x65\x69\xc9\x45\x82\x2e\x5d\x51\x73\xd9\x55\x97\xf6\x8f\x45\xc4\xd4\x7a\xcd\x6f\xfd\x29\x66\x88\x39\xbe\x55\x60\xd2\x14\x74\x70\xcc\xbf\x6c\xc1\xd4\x14\x00\xae\x67\x82\xa1\x70\xc3\x76\x7f\x8e\x89\xc6\xed\xf6\x76\x60\x81\xf4\x3f\x28\x23\x89\x4d\xe9\x87\x0a\xe0\x3f\x51\x21\xd4\xf0\x24\xb9\x5f\x6c\x11\x63\x14\xab\x34\x6d\x27\x21\xcb\x0b\x49\x72\x0f\xcb\x29\x9c\xbb\x13\x8e\xf3\x6a\x70\xb6\xc8\xfa\x04\x92\x96\x82\xb2\x4d\xb6\x72\xeb\x91\xae\x94\x16\x76\xa8\xe6\x12\x56\x6f\x43\x8e\xd9\x31\xd2\x8e\x5e\x6b\xa0\xb9\x02\x7a\x8f\xc4\xeb\x42\x69\x52\x1c\x2d\x7b\xec\x2a\x0c\x8e\x99\x8b\xd0\x0d\x18\x8b\xfd\x33\x21\x38\x4b\x8c\x42\x3c\x72\x8a\x59\x9f\xca\x27\x3e\xc8\x73\x43\xdf\xf8\x1d\x6a\x86\x8a\x0d\xbd\xa3\x9e\x9d\x93\xcd\x34\x40\x3b\x21\xc0\xac\xc3\x91\xc3\x98\xb5\x99\x37\xa7\x00\xe1\x54\x95\x2d\x62\xd3\xb5\x68\x74\x7a\xdd\x42\xc2\xd8\xdb\x82\x17\x8a\xc0\xba\xe6\xa8\x78\x3b\xab\x3a\x9a\xbd\x5b\x8e\x36\x66\xc9\xa7\x37\xe9\x40\xa6\x45\x5c\xd8\xfa\x0e\xa1\xc4\x8d\x41\x9f\x67\x43\x22\xaf\xc0\xe6\xfc\xa8\x05\x6d\xff\xca\x88\x1a\xad\xc1\x67\xb7\x48\xc1\x81\xaa\xc2\x96\xd0\x9d\x1a\xfb\x11\xed\x0a\xb7\x0b\x72\x61\xdb\xb1\xab\x87\x90\xc7\xb8\x29\xfb\x76\x91\x6c\x1c\x02\x4e\xce\x6a\x3a\xd9\x2c\xee\x92\x96\xcb\x96\x06\x8c\x71\x0a\x1e\x8c\x93\xc4\x98\x1b\x65\x3d\x86\x87\xcc\x9d\x90\x45\x8b\x63\x24\x82\x9a\xa5\x17\x45\xd1\x44\xfa\x0d\x2c\x61\x8f\x86\x7e\xd4\x24\x43\xcf\xce\xd9\x59\x64\x0e\x79\x19\x47\x43\xaa\xfc\x22\xf7\xa2\xa3\x25\x97\x9c\xae\x21\xa5\x3d\x42\xbc\x17\xe7\xc1\xeb\xe9\xcb\xdc\xa2\x81\x73\x0a\xe6\x47\x30\x42\xd0\x5f\x14\xb3\xda\x5c\xb2\xec\x86\x12\x10\xed\x1f\x3b\xdf\x37\x56\xd1\xbc\xfe\xc3\xc3\x70\x86\x4e\x4a\xd3\x65\x3a\xbc\xcc\x4a\x3f\xee\xca\x8b\xd1\x8c\x72\x88\x50\xe9\x75\xfc\x99\xda\x5a\xab\x72\xa7\xbd\xf5\x0a\xee\x44\x55\xd5\x96\xa6\x7f\x4b\x12\x93\x54\x56\x13\x59\x34\xd5\x8f\xa4\xab\xb9\xeb\x8c\x88\x04\x71\x21\x9a\x49\x62\x56\xe0\x5e\x32\xcf\x5b\xec\xf1\x80\x28\x79\x86\x57\xc3\x62\xf8\x7f\xf9\x29\xd2\xb6\x08\x09\xf5\x8b\x8a\xdf\xf4\x08\x6f\x6d\x18\xac\x70\xa3\x36\xe3\x7d\x8a\xd1\x65\x68\xff\x45\x76\xe8\xbd\x20\xbe\xfb\xbb\xc5\xc9\x81\x68\x44\x5a\x82\x54\x49\x49\x13\x32\x46\xd1\x0c\x8b\x67\x09\x28\xfc\xb8\x1b\x66\x24\xb8\x2d\x92\x0f\xb9\x6c\x7a\x34\x0f\x2b\xa3\x04\xed\xb7\xab\x4d\x99\xdc\x75\xc0\x29\x96\x62\x8e\x88\x96\xc6\xb1\x6a\xa5\x61\x1f\x0d\xcc\x7e\x87\xba\x98\x1d\x39\x0b\x45\xe5\xdf\x25\x5a\x4e\xd5\xd9\xd1\xee\x28\xf1\xaa\x36\x4b\x6e\xd1\xf4\xb6\x9e\x75\x35\x9f\xc5\x4f\x74\xdf\x32\x58\xc1\xfc\xc7\xd6\x70\xab\xa9\xe9\x23\x7b\x80\x7c\xf5\x14\x09\xf9\x71\x58\xda\xb1\x9c\x20\x28\xb7\xce\xbe\xc5\xb5\x67\x79\x76\x43\x25\x5d\xc5\xd0\x9c\x07\x4e\x2f\xc1\x0c\xcd\x1b\x1b\xfb\x14\x39\xcc\x7c\xdf\x14\x23\xe2\xbd\xae\x34\xb2\x87\x71\xce\x4e\x6b\x54\x25\x74\xfa\x0c\x59\x84\x1e\x2f\x65\xdd\x98\xf4\x53\xa5\x57\x01\x20\xc0\x02\x95\x5a\x7b\xc2\x47\x0f\xa7\xdf\xb0\xda\x45\xfc\xea\x2e\x09\xf6\xfc\xf8\x60\x61\x21\x12\x15\xb1\xc6\x57\x2b\x87\x33\xf0\xef\xb8\xe1\xef\x98\xfc\x23\x89\x1b\xc6\xf7\x8e\x4d\x52\xe5\xac\x2b\xa1\x7e\x3f\x62\x22\x25\x0b\xb2\xd1\xb8\xe3\x5a\x20\xbc\x50\x48\xf6\x26\x91\xef\xce\x45\x8d\x84\xde\xe6\x99\x18\x16\xa0\xda\x96\x44\xda\xb5\xef\x93\x8c\x51\x14\x3f\xa4\xcb\xce\x60\xde\xc2\xa5\xce\x9b\x77\xb1\xcf\x35\x44\xc8\x96\x90\x14\xee\x47\x22\x38\xc4\x66\x40\x22\xd1\x5e\x2a\x32\x7c\x45\x9b\x96\x6d\x60\x00\xdf\xfe\x5f\xff\x28\x37\xdb\xcf\x14\x7a\xd1\x9f\x3d\xc4\xc4\x67\xea\xf2\xb3\x88\xb3\x71\x1f\xe7\x60\x48\xce\x31\xfb\x79\x76\xc9\xd4\x99\xd5\x37\x9f\x41\x25\xfa\x3e\x0b\x55\x48\x36\x62\x26\x89\x2b\xee\x06\x71\xe3\xf9\xf0\x10\xff\x87\x70\xe1\x78\x4d\x97\x01\x51\xb5\x04\x7f\x24\x3a\xee\x1a\x63\x51\x5f\xa7\xe5\x9a\xf8\x5e\xcc\x4c\x69\x3a\x40\x3e\xc2\xad\xf4\xa7\x3a\xf4\xce\xb5\x44\x24\x5f\xa7\x6b\xfc\xf9\x1c\x4d\xbc\x50\xe0\x54\xa1\xaa\x3b\x27\xb0\x77\xec\x86\x1f\xc1\x09\xf5\xe4\x2d\x82\x42\x17\x7c\xa1\x0b\xdf\x53\xc8\xf1\x7b\x33\x2a\x08\xf7\xc9\x3f\x3f\xf4\x24\x49\x44\xe0\x37\x74\x9c\x85\xf1\xa1\xf4\x93\xcb\x70\xdd\xa8\x59\xce\x9c\xdb\x15\x6c\x59\x04\x1d\xda\xc4\xc6\x60\x81\xfa\xc2\xde\xfe\x47\x79\x35\xc5\x86\xb1\xe3\x47\x0a\x29\xf7\xd6\xc9\x0e\xa9\x50\x81\x9b\xcf\x8f\x42\x48\x0e\x70\x24\x64\x22\x12\x60\x3e\x14\x3b\xef\x5e\x46\x54\x7b\x4c\x93\x83\xdc\x30\x09\x67\xc3\x52\xde\xc4\x09\xcc\xa1\x95\xc7\x19\x8e\x5f\x3d\x54\x57\xdb\xec\x5a\x9d\x65\xb6\xf6\x2b\x0b\x82\x4b\xbe\xca\xd7\xce\x22\x69\x67\x25\x07\xb8\x30\x27\xde\xed\xa4\xbe\xa0\x91\x69\x9b\x39\x98\x67\x6b\x57\xc0\xa9\xc0\xbf\x22\x85\x7e\xa4\x05\x33\x3e\x08\x24\xdc\xf3\x14\xc3\xa2\xee\x12\xc2\xf2\x3e\x3d\x19\xc1\x26\x79\x15\xfd\x37\x29\xe2\x9f\xc1\x02\xdc\x81\x53\x3a\x37\xf2\x81\x06\x62\x35\x43\x5d\x4e\xda\x88\x87\x50\x33\xfe\x7f\x2f\xf1\x28\xca\xfd\x07\x5f\x9a\x20\xa2\xb2\x7f\x28\x2e\x07\xe4\x62\x87\x3a\xa8\xe3\x9d\x8c\xa8\x65\x19\x39\x2e\x70\xeb\x75\x23\xaf\xa8\x7f\xde\x55\x8e\x88\xaf\xfd\xd4\xb8\x2a\xc4\x8d\x4c\x5a\x42\x52\x17\xbf\x45\xa7\xb1\xbf\x7a\xf7\xa4\xe3\xf2\x72\x8a\xec\x8d\x6d\x14\x33\x29\xc7\xaf\xc2\x4c\xf0\xdc\xd8\x7b\xda\xb7\x16\xff\x73\x9e\xe1\x3e\x18\x20\xd0\xf4\x1c\x47\xad\x02\x12\xb6\x2f\x45\x6f\x9f\xc1\xc2\x6e\x3c\xb3\xc4\x3c\x49\x50\x46\xc6\x57\x5d\x1b\x48\xc3\xe0\x55\x82\xb0\xc2\x8c\xda\xf4\x02\xf9\x9a\xa5\x9d\x32\x32\xa1\x15\x25\xdc\xfe\xc7\x51\x4c\xcc\x57\xb2\x05\x58\x6c\x96\xf4\xc3\x26\xee\xc6\x4a\x39\x98\x43\xca\xc5\xf5\x26\x19\x8c\x1c\xe6\xa6\xc3\x01\x74\x8a\x5a\x04\xfe\x1e\x5b\x76\x85\x4c\x2e\x2a\xcc\xf2\x76\x3c\x17\x29\xa9\x3f\x43\xe0\x8c\xa3\xdc\x5a\x37\xb5\xb4\xd4\x34\xc9\x00\x62\xd5\x83\x97\xec\x24\x92\x15\xa3\xc8\x74\x46\xe4\xe8\x55\xf0\x5b\xaa\x19\x07\x65\xb6\x18\x59\xcd\x33\x97\xf6\x51\xcc\x97\x7e\x0b\xfb\xdd\x18\x1b\x6d\x10\xdc\x11\x05\x69\x9f\xa0\x06\x04\x81\xed\x42\xef\xb4\xad\x4a\x26\xbf\x06\x57\x93\x33\x76\xe1\xe3\x87\xf8\x14\x52\xdc\x14\xd9\xc4\xde\x5b\xb1\x2d\x74\xa7\xb4\x5b\x87\x4a\xf7\x6e\x3f\xc2\x26\xbb\x1a\x60\x69\x3d\x0c\x1a\x7d\x94\x09\x54\x51\xa0\x2c\xcb\x5a\x78\x55\x11\x5b\x15\x4d\x52\xeb\xd5\xc2\x1b\x49\x83\x45\x0d\xac\x15\xb0\x99\xe6\x41\xa7\xe1\x2a\x94\xbb\x27\x2e\xb4\x06\x66\x24\xde\xd1\xef\xc5\x14\x30\x26\xe5\x68\x7d\x4b\xc0\x9b\x4e\x2b\x9e\x38\x74\xd4\x1b\x8b\xba\x26\xe9\x70\xf6\x57\x48\xc0\xe9\xa7\x51\xc2\xd2\xc8\x34\x33\x0a\x92\xd2\x5d\x7e\xea\x27\xae\xb4\xc7\x20\xe2\x17\x7b\xb6\x76\xf2\x82\xef\x5f\xb3\x64\x3d\xea\x17\x46\xe1\xb5\x41\x0d\xc9\x5e\xa5\xfc\x13\xe3\x9f\xbf\x66\x74\xf9\x5c\xba\x20\x3f\xf4\x89\x39\x96\x43\xc1\x16\x94\x90\x0e\x3a\xa9\x1c\xf3\xe0\xf0\x4f\x91\x08\x5b\x93\xde\x39\x34\x25\x84\x36\xb8\x83\x20\x2d\x4c\xc2\x4c\x8f\x64\x07\xfc\x68\xf6\xe0\x85\x21\x91\x0c\x15\xcb\x31\x0e\x54\x1a\x79\xdb\x95\x22\xde\xf0\x66\xe8\xf4\xca\x63\x88\xc6\x52\x9b\xed\xc6\xa6\x5b\xbb\x5e\x41\x67\x58\x34\x53\xb0\xd1\x7c\xc9\xb9\x23\x1a\xcf\xaf\x1a\xf3\x69\x8a\xfa\xbd\x1b\x82\xb4\x8a\x96\x98\x04\xc4\x59\xb8\x69\xd9\x8b\x54\x4b\xbe\x7a\x4f\x27\x19\x01\x99\xc9\xf5\x54\x1b\x92\xb8\xc1\xf8\xd9\x4a\x25\x4e\x57\x26\x6f\x10\xc4\x9b\x11\xdc\xe2\xf5\x05\x89\xd3\xd6\xc2\xc3\xe4\x43\xc5\x05\x1b\x4f\x3c\x9a\x96\x31\x4a\xee\x7b\xe5\xb5\xd7\x0b\x3e\x31\x3d\x5b\x4f\xe5\xf9\x44\x23\x9d\x46\x85\x34\xd0\x64\x10\x6a\xd4\xab\x39\x86\x42\x17\x05\xf2\x1e\xe2\xbd\xab\x56\x07\x0a\x05\x72\x1c\x0d\xcb\x4a\x3b\xce\x62\xd0\x27\xd6\x51\xc4\x12\x33\x12\x13\xa7\x08\x8b\x10\x70\x23\xc4\xa0\x8e\x27\x65\x17\x38\x57\x9a\xe1\x10\x1a\xe9\x51\xa4\x12\x93\xdf\x5b\x8a\x62\x6c\xca\x21\x7e\x53\x17\x78\x50\x97\x46\x09\x5a\x9d\x4b\x7a\x99\x45\x8c\xbd\x7d\xbb\xd9\x65\x74\xe9\x79\x31\x00\x66\xe2\xfc\x64\x17\x97\x4b\xef\xb6\xcd\x44\x01\x94\x1c\xb5\x2c\x0b\x49\xf5\xcf\x87\xc7\x53\xb2\x16\x4f\xa9\x4c\xe7\x98\x0e\x00\x0d\x83\xd6\xe6\xe3\x73\xeb\xb9\xdf\x77\x85\x99\x2e\xb5\x96\x8f\x08\x1d\xee\x79\x53\xbf\xf7\xaa\xdc\xc2\x22\x00\x8e\xce\x61\x3f\x6e\xfe\x92\xdc\x5a\x4e\x16\x5a\x1d\x1a\xe7\x49\xc1\x71\x00\x13\x1c\x2d\x52\x38\x16\xa7\xc6\xd0\xd1\xdb\x79\xd8\xc1\xc3\xc1\xbc\x62\x9f\x65\x67\x98\x4a\xba\x8f\x91\xf1\x1f\x85\x83\xba\xee\x5a\x09\x95\x74\xca\xea\x99\xd1\x13\x7d\xe1\x51\xe9\x55\xf2\x6f\x2f\x70\x30\x4b\xd6\x6e\x38\xe7\xce\xfd\x11\x84\x72\x22\xb7\x98\x4a\x6b\x0c\x4c\xf3\x35\x07\xa7\x2b\xfd\xd4\xf0\xa3\x98\x27\x59\x67\x76\x26\x4d\x51\x07\xb4\x2f\x73\xf4\xa8\x8a\x56\x07\x11\xc8\xa0\x3e\xb2\x38\xa1\x79\xb1\xaa\xa0\x6b\x92\x2f\x0f\x87\x6d\x08\x45\x62\x6b\x53\xe7\x1a\x44\xe4\xf3\xa6\x97\x77\x89\x31\xf2\xe3\x4d\xec\xff\xda\xb1\xe2\x90\x5c\x7a\x48\x88\xc4\xa4\xb6\xd8\xd4\xed\x8e\x8a\x30\x9c\x95\x1e\x24\x88\xdd\x31\x14\xdc\xf5\x6c\x62\x2e\xc8\x30\xa0\x6a\xaf\x20\x24\x8e\x59\x2b\x73\x5c\x73\xc6\xd5\xeb\xbf\x40\xa6\x53\xf2\x3f\x2d\x48\xb3\x0b\x83\xef\xd6\xfd\x06\x14\x2a\xf6\x4a\xa2\x38\x06\x85\x11\xd5\xdc\xcd\x68\xde\xcb\xca\x9b\x4a\xf7\x68\xb1\x63\x7b\xc1\x56\xdb\x20\x8b\xb5\x8d\x56\x3f\x48\x3f\xd5\x01\x84\x52\xdb\x8d\xa9\x50\x63\x90\xaf\x8e\xe4\xac\xd7\xe4\xa5\x1e\x3a\x79\xf8\x71\x61\xa8\xd0\xfe\xb2\xcf\x16\x4c\xfa\x18\x3b\x3b\x7b\x23\xfd\xfc\xd2\x12\x07\xc7\x25\xa5\x6f\x33\xe5\x18\xb6\x04\x51\x17\x79\x3e\x9f\x5b\x5c\x32\x55\x5f\xbc\x08\xb9\x14\x21\x62\x1d\xe7\xd9\x50\xed\xe2\x47\xad\x95\x0e\xe4\x35\xc0\xdc\x87\x52\xaa\x2e\x31\x92\x00\x36\xd6\x4f\xc4\xcc\xfe\x74\x8f\x74\xe2\x91\xef\x16\xfc\x35\x65\x0b\x4b\x96\x21\xc3\xc9\x0e\xdf\xb8\x64\x50\x20\xbd\x45\x0b\x26\x4d\x13\x8c\x66\x73\x88\x64\x56\x80\x8a\xbf\xdf\x82\x75\xd3\x66\x2a\x07\x46\xaf\x98\x78\xfe\x9e\x01\x36\xd5\x4d\x63\x2a\x39\x7f\xb7\xd7\x68\x73\x73\xd2\xfd\x18\x73\xc9\xbc\x5d\x82\x35\xbb\xce\x96\x81\xf4\xbd\xed\xd1\xba\xcb\xd3\x1b\x07\x14\x82\xf0\xd4\x61\xcf\x53\xe3\xa2\x63\x70\x18\xbf\xf4\xde\x7f\xc6\x70\x2f\xb6\x3b\x46\xc5\x2c\xca\x2c\xe5\xd9\xa2\x20\x5a\x8e\x9d\x04\x8e\x7d\xe6\xa4\xed\x9d\x41\x38\x64\xba\x14\x3a\x21\x55\x52\x3f\x63\x6b\x10\xe5\x2c\x16\x02\x2a\x7e\x2d\x94\x6a\x5c\x33\x32\x55\x23\xfb\xff\xb9\xba\xb2\x34\xc5\x75\x25\xbd\x17\x5e\xea\xe5\x6e\x4a\x1e\xc0\x4e\x6c\xcb\xc7\x03\x14\xb9\xfa\xd6\x3f\x84\x4c\xf5\xed\xfe\x0e\x82\x24\x29\x12\xac\x50\x0c\xff\xf0\xc5\x01\x1a\x7d\x65\x85\x4c\x00\xe9\xcd\xaf\x80\x00\x0d\xfa\xf7\x65\xb9\xc6\x05\x30\x5b\xf2\xf6\xad\x3d\x96\xb8\x96\xe2\x6c\xe2\x3c\xda\x4e\x74\xfa\xc4\x07\x7e\xc4\x93\x68\x04\xcf\xd1\x3d\xf9\x1f\xc0\xb5\xdc\xdb\x10\xa1\x15\xa2\x90\x0a\x7b\x53\xb4\x54\xb0\xa9\x25\xfb\x45\x53\xe0\x80\xf2\xb7\x17\xb0\x94\x99\xf2\x54\x4d\x7a\x5f\x29\x6a\xf4\x0e\x26\x17\xee\x97\xad\x55\x75\x14\xe2\x60\x5c\x5a\x7d\x9d\x61\xe7\xb3\x0a\x88\x48\xcb\x21\x7e\x94\x4d\x4e\xb5\x4f\xd0\xd4\x19\x70\x6a\x95\xdb\xa4\xb6\x1d\xab\x7f\x11\x0e\x00\xc9\x8b\xdd\x84\x21\x26\x71\x70\xaa\x34\x15\xc6\x1b\x7c\xe2\x2e\xa2\xb9\x99\x80\x7e\x55\x62\x73\xcd\x59\xc6\x2d\xac\x3e\xfb\x52\x40\x5a\xe1\x00\x5f\x2e\x23\xcf\xc2\x92\x73\x9f\xd1\x74\x55\x83\x2d\x2a\x1d\xe0\x88\x79\x7d\xb8\xb7\xb4\xc5\xa4\x79\x1b\x0d\x74\x51\x65\xa2\x1a\xa8\x24\xa8\x86\xa4\x0a\x59\xaf\xc6\xc4\x7a\x5a\x13\xc0\xb8\x7a\x5d\x27\x6d\x78\x4d\x80\xdc\xef\xd6\xfc\xaa\x4b\x34\x82\x91\x9a\x34\xe3\x86\x61\x46\xf8\x05\xe2\x0a\xd0\x59\xcf\x02\x5b\xbb\x99\x89\x71\x17\x56\xea\xc1\x32\xc7\xb0\xf5\xd4\x04\xd6\xfd\xe8\x69\x6c\xb6\x68\x1b\xff\xf8\xb8\x00\x5a\xb9\x02\xdd\xa1\xa1\x27\xe2\x08\x7f\x34\xcf\x76\xff\x85\xa7\x98\xb4\x29\x1d\x46\xd9\x97\x37\xb2\xa9\x7c\x20\xb3\x7a\x73\x49\x1d\x79\xb5\x9f\x19\x7d\xfa\x40\xe6\x44\xea\x7a\x4f\x7f\x75\xa0\xfe\x3d\x2a\x00\xb6\x64\xed\x15\xb2\x57\xc9\x02\xf2\xd1\xc9\xef\x25\x38\xb8\xdd\x68\xb4\xbe\xfd\xba\xb6\x00\x9f\x43\x79\x3c\x0a\x6e\x34\x09\xe2\x34\xdd\x04\xb5\x4c\xfb\x99\x02\xb4\xd6\x7c\x1e\x39\x1a\x40\xbf\xbf\xd1\xaf\xdd\x02\xa2\xea\x4e\xac\x9c\x5b\xa2\x0d\xaf\x73\xd3\xcd\xe8\x77\xaf\xc0\x70\x61\x12\x38\x19\xb5\x5d\x31\xa9\x99\x1e\x55\x1f\xd1\x65\x86\x5c\xab\xcc\x0c\x21\x02\x15\x13\xde\xa3\x5f\x65\x6e\xae\xd8\xf4\xa5\x3f\xaf\xcb\xad\x3e\x02\x2d\xe2\xcd\x6c\xea\x52\x63\xc6\x20\x38\x5a\x7c\x67\x24\x5c\x59\x57\x0e\xda\x42\x65\xfb\xde\x42\xfa\x47\x5c\x71\x68\xe7\xc9\x01\x7a\xac\xf9\x46\x49\xb8\xfd\xca\x73\xbf\x05\x16\x09\x76\x32\xea\x90\xcc\xb0\x70\x9b\x54\x22\x94\xf4\x15\xcd\xdb\x53\x47\x93\xc3\x0a\xb5\x11\x74\x1a\x95\x5c\x2a\xc4\x83\xfa\xc5\x6d\xc1\xa1\xfe\x09\x8f\xbe\x67\x09\x4e\xb0\xb7\xa6\x73\xc6\x76\xf9\x8b\xf7\x88\xa6\x14\xfd\x1e\xcc\x6c\x2a\xd1\x14\x9a\x41\x24\xba\xa9\xc4\xbe\x49\xe0\x23\xb2\x55\x1e\x42\x02\x1e\x4f\x7d\x53\xfd\xb5\x49\xfe\xd4\x35\x92\x6c\xdb\x17\xa2\xe5\xfe\xea\x3b\xdb\x0d\x96\xf4\xc7\x85\x16\x34\x3d\x2f\x67\xe7\xb4\x3c\x5d\x41\x55\x46\xc7\xf1\xa9\x03\xb8\xb1\x01\xbe\x66\x64\xa4\xa9\x02\x0d\x80\x92\x3a\xc4\xb0\xa9\x51\xe1\xc8\x4b\x50\xb1\x4b\xb0\x35\x2f\xa7\xff\x1b\xce\xd5\x25\x32\x18\x49\xb1\xb7\x97\x26\x64\xa9\xa9\x30\x18\xf5\x64\xee\x6d\x2f\xbf\x12\x52\x50\x3d\x05\x71\x47\xa7\x1e\x29\xb5\xbe\x00\xda\xfa\x51\x02\xb5\xcf\xc4\x7a\x43\x5d\x72\x23\x9f\x84\xfb\xb8\xd4\x51\x75\xc0\x52\xd6\x5f\xf6\x45\x8c\x2c\xc2\x40\x19\x07\xed\x41\x70\xa9\x87\x3d\xb4\x6b\x43\x8c\x71\xea\x3d\x01\x0e\xde\xc1\x94\xaa\x23\xcb\x94\x42\x77\xb2\x1c\x50\x25\x4a\x58\xb9\xf4\x0c\xb6\xd5\x0f\xf7\x87\xcb\xfd\x64\x60\x30\x44\xfe\xcf\xf5\x8a\x41\xd6\x57\xc5\xa1\xf4\x70\x24\xa0\x08\x42\x1b\xa0\x89\xc7\xe4\xe6\xe8\x03\x2f\xa7\x3c\xc7\x20\x62\xbb\x1b\xc4\xdc\xd7\xad\x1a\x1c\xac\x67\xc4\x91\x7d\x0d\xdb\xb3\x1d\xe3\x08\x2b\xe0\x3d\x94\xc0\x0f\x51\x2b\x74\x1a\x66\x97\x3a\xad\xb7\xfa\x57\x49\x0b\xce\x2a\x22\x08\x5b\x38\xf5\xce\x61\xbc\x11\xd8\xe4\x50\x02\xe3\xc5\x57\xb2\xa4\x29\x62\x0c\xfe\xea\xfb\xe4\x28\xd4\x3b\x48\x2b\x2f\xdf\x28\x43\x78\xa3\x7e\xe4\x1e\x3d\x4c\x52\xbf\xaf\x0b\x72\xd2\xcc\x23\x8a\x8b\x5f\x0c\x97\xd4\x0a\xe0\x25\xc8\x93\xa2\x54\xf9\xda\xcf\x07\x1b\xf8\xd0\xd2\xbd\x5a\x40\x21\x93\x0d\x62\x9b\x35\xb5\xd6\xb2\x0d\x2b\xd2\x68\xaf\x72\x0b\xbb\x58\x35\xe5\x3b\xbe\xd2\xc5\x4b\x47\xfb\xd2\x79\xd8\x6b\x7f\x6f\x8e\x5e\x12\xca\xca\x9c\x62\xe4\x17\xec\x9e\xb0\xbf\xf5\xb9\x55\x51\x90\x4c\x92\xca\x21\x90\xef\x12\xd4\x5c\x95\x10\xbd\xbf\x21\x45\xf2\x96\x73\xbe\x44\x58\xc3\xa6\x16\x72\xee\xd4\x04\x80\xcb\x8f\x0a\x42\x31\x5e\xf7\xdb\xb7\xb7\xfb\x35\x4f\x8e\x91\xf9\x38\x7f\xd1\x2c\x70\xa7\x0d\x81\xbb\xb1\xc5\x7c\xb7\x24\xa8\x36\x59\x1f\xac\x33\xd1\x73\xc6\x02\x3c\x49\xc8\x4d\xc8\xa5\xd9\xc1\x6d\x0b\xf0\xc9\x23\x84\x2e\xa0\xcb\x8f\xf9\x4c\x5c\x7a\x8f\x73\x0f\xd9\x0d\x57\x89\xbd\x26\xdc\xb7\x6f\x8c\xe6\x78\x79\x99\xc7\xa9\xf6\x3b\x86\x33\xe5\x12\xd4\x4c\x39\xbf\xfb\x84\x53\x11\x40\x77\x93\xbe\xea\x64\x96\x38\xa2\x7a\x8f\xa6\x08\xce\xbb\x11\xa8\x5c\xab\xe0\xa4\x1c\xa3\x3a\x9c\x6c\x30\x72\xf1\x5a\x79\x95\x49\xbf\x6f\x59\x4c\x6d\x00\x7e\x46\x07\x23\x87\xd2\xbc\x54\x3b\x28\xf0\x79\x77\x8b\x95\xb9\xc5\xca\x9f\x67\x00\xf1\x95\xd4\xa9\x83\x7d\xfb\x9f\x9d\x4a\xa4\xef\x25\x48\x11\x28\xe7\x25\xf6\x24\x23\xde\x26\x5f\xcc\xe5\x63\x5d\xdd\x54\x39\xc2\x6f\x1c\xc4\xc5\xf0\x05\x01\x2f\x62\xab\x1d\x2c\x5e\xe5\x5b\xb6\x32\xfa\x91\xb3\xfa\xa1\x25\x1a\x59\xa7\x49\x43\x70\xf2\x7a\x14\x6f\xcf\x29\x5c\x92\x09\x5b\xc6\x6d\x8c\x94\x30\x12\xd9\x2a\xf2\xa6\xe4\x37\xad\xc1\xc6\x22\x8d\xb9\x97\x61\xa5\x17\x5e\xe9\x52\x09\x88\x51\x5b\x77\xfb\x9e\x98\xf0\x27\xc0\xd1\x8b\xfa\x37\x7d\xb5\x3c\x17\xe4\x36\xed\x44\x10\x3c\x91\x5c\x92\x4f\x80\xf3\xd8\x10\xc4\xaa\xc0\x6d\x00\x2e\xe9\x90\x4c\x8c\x9d\x99\xe5\xe3\x9e\x00\x62\x70\x7f\x83\x1a\xc8\x2e\x17\x47\xda\x5f\x9d\x84\x83\x0d\xa7\x8d\x9c\x6c\xec\x7d\x1f\x0d\x5d\xb8\x13\x61\xcf\xab\x32\x6b\xda\x61\xae\xb0\xc8\x66\x1e\x8e\x87\xad\xe8\x1c\x96\x17\xba\xc2\xcb\xe5\xac\x76\xf6\x76\x5e\x80\x55\x2b\x32\x34\xb5\xf7\x31\x55\x8c\x1d\xa2\x61\x04\xca\x68\x8c\x0f\x94\xfe\xad\x40\xae\xf8\x71\xdf\x3e\x6d\x2c\x59\x12\xb8\xc1\x92\x68\x38\xcf\x55\x42\x4c\x9a\xc4\x69\xbe\xa2\x4b\x2f\x34\x9c\x61\xa9\x1b\x2d\x87\x34\x29\x6c\x9a\x05\xa9\x0f\xe9\x93\x34\x9d\x33\x86\x0c\xee\x9b\x0a\xa0\xc7\x39\xd6\x06\x99\xf7\xba\xcc\x9c\xb5\xaf\x8f\x5c\x2e\x0f\x8f\x4f\xda\x18\x9c\x96\x65\x76\x3f\x63\xdc\xcc\x53\xdb\x57\xf9\x5d\xd1\xc1\x53\xb1\x16\xfa\x72\x92\x2f\x8c\x6c\x40\xd3\x35\x37\x35\xca\xb7\x13\x57\x1b\x8d\xdc\x74\x05\xf1\x50\xf5\xe1\x7e\x84\xcd\x99\x98\xa5\x96\xf2\xc3\xdb\x5a\x4a\xb9\xeb\x77\xb8\x94\xc3\x3c\x6d\x82\x03\x62\xcb\xdf\xcf\x90\x49\x9a\x47\x7b\x71\xcd\xde\x67\xcf\xcf\x92\x76\x35\xe8\x9e\x8b\xf6\x4f\x39\xcc\xd5\x08\x86\xd1\x69\xb5\x7f\x8e\x6a\x31\x8e\xf5\x52\xd7\x4c\x1e\x7b\x97\xb2\x91\x87\x71\xee\x6a\x2a\x7b\x87\x54\x9c\x4e\x54\x28\xaa\xda\xe4\x55\xbd\xb6\x9b\x9c\x87\x97\x36\xde\xff\x7d\x0c\xb3\xd5\x3b\x00\xcf\x46\xea\x1a\x31\xd7\x7d\xf6\x28\x46\x93\x06\x78\xda\xd3\xd2\xde\x7a\xd4\x1a\x9f\xb2\x50\x56\x2b\xbb\xf7\x15\xb9\x71\x86\x03\x4d\x6b\xfa\x91\xc1\x1c\xbf\xba\x2a\xbf\xf2\x8d\xe8\xbf\xe6\x0a\x3f\xd4\xe1\xd0\x5a\x6e\x99\xbe\x5a\x35\x9f\x23\xc7\x4d\xc7\xfb\x64\x36\x49\xb3\x55\xbc\x0d\x26\x64\xee\xd0\x8e\xdb\x31\x98\x28\xd9\x90\x75\xdd\x04\xa0\xa5\x41\x8b\x42\x90\x60\x36\xf5\x0c\x86\xbf\xe6\x7f\x37\x07\x5f\x5e\xb9\x54\xc7\x0d\x6d\xfd\x81\x43\xe2\x72\x53\x2e\x8c\x97\x9d\xd7\xf0\xd6\x8c\x42\x60\x1f\xa5\x6a\xc3\x97\x4f\xcf\xa9\xbe\x79\xcf\x5a\x52\x83\x22\xcc\x0a\x76\xa8\xfb\xf0\x0a\xc5\xeb\x45\x8b\x2d\x94\xd8\xff\x9f\x23\xf9\x7f\x92\x92\xd3\xe0\x9a\xaa\x9a\xda\x96\x40\xdd\x87\xbe\xe6\x16\xa0\x01\x78\x6a\x54\xb1\x23\x66\x52\xca\x46\xaf\x95\x12\x4f\xaa\xf0\xb4\x82\x08\x95\xd0\x28\xb8\x09\x8b\x96\x85\xd1\x5e\xa5\x4a\xed\x87\xe0\x5e\xda\xda\x90\x3e\x54\xe5\x0e\xcd\xb7\xb2\x35\xb3\x12\xd9\xae\x9b\x62\x04\x0d\x5d\xb2\x5d\xb0\xd7\xfc\x34\xfe\x55\x7d\x36\x95\x75\xd7\x0c\xca\xd0\x43\xd2\x2f\xbc\xe6\x00\x56\x66\xbf\x20\xe0\x5a\x30\x62\x48\x9f\xda\xfc\x78\xc0\x12\x51\xfd\x29\x5a\xc2\xba\x90\x99\x5e\xa6\x4d\xee\xe5\x80\x69\xbc\x37\x41\xa7\xc2\x09\xe5\x0c\x60\x8d\x0a\xb3\xe3\x97\xeb\xe6\xf0\xb6\xd5\x52\x1c\xc8\x73\x3f\x3a\x35\x51\xd3\xf6\xbd\x5b\x6b\xa4\xad\xa8\xad\x82\x84\xc9\x69\x65\x15\xe4\x6b\xd2\x6e\x69\x48\x9b\xdd\xa8\xca\x39\x04\x46\xd4\x64\x03\x9c\x76\xee\x0c\xb6\xd3\xf0\xf3\x73\xdd\x15\xdf\xce\xe5\xd2\xf0\x38\x46\xe6\xa6\xfb\x1b\x2d\x6b\x56\x34\x6f\x6e\x51\x5e\x4c\x6f\x9d\x9b\x1c\x15\xb8\x73\x12\x79\xe3\x8d\x35\xcd\xb4\xb2\xb9\xbe\x55\x84\xc1\x91\x4b\x25\xe5\x66\xc8\x1a\x67\x26\xdc\x54\x9d\x0e\xc2\x23\x56\x07\xa6\x3b\xd3\x20\x58\xf2\x1a\xe2\x80\x4f\xa3\x02\xd1\xe9\x1b\x8b\xf3\x39\xfd\x1b\x82\xb4\x33\x9f\xd3\x5b\xda\xff\xc6\x22\x5d\x57\xc3\x97\x55\xe9\xe4\x73\x7a\xd2\x1e\x9d\xaa\x25\xcd\x53\xf8\xf9\x67\x8f\xff\xfe\x28\xa2\xcb\x31\xd6\xc5\x34\xcd\x26\x16\x22\xd2\x3c\xae\x9c\x23\xd3\x44\x45\xaa\xe8\x51\x2e\x8c\x6e\x18\x6f\x55\x21\xd6\x60\xb4\x90\x80\x05\x7a\xa1\x9a\xc0\x7d\x9b\xd4\x54\x49\x1f\x27\x8f\x54\x23\xaf\x26\x0d\xf6\xf9\x8e\xc1\xe3\xf6\x31\x91\x87\xc4\x5c\x23\x99\x60\xea\xea\x0b\xc7\x72\xf9\x21\xf2\x55\x63\x58\xe7\x32\xb9\x4e\x43\x1d\xc2\xf8\x0d\x36\x3d\x1c\x51\x5e\x42\xac\x05\x6b\x4f\x2d\x11\x5b\xb6\x71\x6c\xa0\x39\xa5\xba\x63\x36\x86\xe6\xe1\x5a\x5e\x91\x20\x98\xf7\x07\x80\x7a\x5b\x88\x2b\x74\xbf\x72\xc9\xb5\xd1\xed\x62\x07\xa5\x65\x97\xe4\x9c\xa8\xee\x53\x52\xc9\xeb\x60\xd5\x25\x75\x97\x16\xfe\x24\x2a\x3b\xf9\xe3\x01\x60\x5d\x46\x33\x1f\xfa\x47\x35\xd5\x7a\xf5\xd3\x97\xee\x5c\x39\x7a\x0d\xc7\x2a\x5f\xf9\xea\xcb\xed\x16\x44\xbf\x68\x9e\xb0\x64\x8e\x6c\x2d\xd4\x99\xd7\x3c\x7d\x38\x9a\xba\xb1\x13\xc7\xdf\xea\x17\xef\x31\x81\x3f\x0c\x00\x83\x8e\x6c\x95\xc3\x84\xae\xae\xd0\x8d\xbd\x10\x07\xec\x9d\x85\xa3\xe1\xf1\x09\xae\x97\x82\xfd\x34\xda\x61\x6e\xea\xef\x47\xb6\x16\xc3\x4f\xb6\xf3\xc4\xcf\x38\x7b\x02\x3c\x7e\x95\xca\x8c\x4a\x73\x15\xb0\x18\xaa\x82\x51\x09\x4f\x4c\xd9\x06\xff\xfa\x00\xb4\x4c\x5e\x83\xf4\xd9\x7b\xac\x99\x2a\x8b\x79\x3b\x9a\xcd\x9a\xd4\xe5\x38\x47\x77\x85\xd3\xaf\x20\xdf\x6a\x88\x30\x85\xed\xde\x1d\xa8\xc3\x41\x73\xf5\xfb\x18\x0e\x1a\x6b\xed\xf8\x83\xe9\xec\x5e\xf0\x3d\x3c\xba\x5a\x20\x96\x63\xe4\x85\xe6\x4b\x5c\x9c\x55\x2d\x13\x50\x8a\xda\xc8\x09\x3d\x03\x55\x30\x53\xf8\x90\x0c\x62\x61\x35\x25\x3d\x72\xda\x97\x3a\xcf\x12\x42\x46\xa1\x01\xe9\x89\xe3\xbe\xb4\x92\x4a\xba\x94\xf8\x64\xbf\x96\x98\x4c\xa7\x80\xb0\x38\xbd\x7e\x4b\xba\xe9\x1d\x22\x0d\xef\x5e\xe4\xb7\x12\xd8\x9e\xb5\x4b\x54\xc5\x57\xa2\xcd\x97\xab\x06\xab\xfc\x1b\x7c\xc6\xfe\x63\xfc\x74\x78\xa6\x7b\x94\x78\x26\x76\x36\x2a\x04\x71\x45\x89\xb4\x71\x4d\xba\x9f\x0d\x74\x99\x16\xaf\x47\x0f\x2b\x92\x89\xdc\xa1\x50\x42\x61\x8b\x9b\x81\xba\x77\x6b\x71\x2d\x34\x7a\xd9\xab\xc4\xdf\xee\x1e\x77\xab\x0e\x3f\x28\xdf\xfa\xe2\xb9\xa7\x5d\xb7\x8c\x1c\x2e\xdc\xe8\x80\x8f\x67\xff\x77\xff\x3b\xff\x48\xcc\x65\xb5\xff\x1b\xe6\x65\x51\xa2\x57\x60\xec\xca\x3a\xa1\xd3\x1e\x68\x05\x74\xa2\x48\xe8\x47\x43\xb6\x45\x06\x76\x33\x4e\xf3\x08\xb3\xcf\x3e\xbf\x4c\x58\x46\x02\xab\x68\x9b\x03\x9b\x53\x2a\xa5\xcf\xe2\x2a\x12\x34\x31\xb3\x80\x5a\xf4\x63\x71\x81\xef\x41\x0f\x90\x36\xe0\xcd\x0a\xcc\xba\x74\x2d\x43\x7d\x13\x83\xce\xff\xcc\xc3\x46\x3f\x48\xe2\x6c\x86\x60\x7f\x0d\x20\xac\x84\x6f\x06\x5a\xc2\x0d\x17\x57\xe4\x2e\x63\xb6\xa0\xff\xa4\x98\x58\xf9\xca\x03\xfa\xac\x8d\xb6\x49\xd9\x2e\xa9\xfb\x72\x2d\xdb\xd8\x23\x69\x28\x37\xe2\x87\x92\xcd\x10\x9c\xb1\x09\xd1\x33\xf9\x54\x14\xd3\x56\xe8\xd0\x7f\x04\xa5\xa0\x65\xad\xbc\x6c\xea\xc3\x05\x61\xfc\xeb\x46\xe6\x3e\xa8\xca\xd9\xad\x36\x40\xf7\xf3\xc4\xaf\x73\x37\x45\xe4\x20\x7a\xba\x7c\xa9\x2a\x0e\xca\x39\x6c\xa7\x8d\x89\xd9\x6e\xf2\x3c\xc1\x8c\x3b\xe4\x64\x91\xf9\xad\xf1\x85\xe5\xf3\x90\x6b\x49\x89\x22\x5e\x34\x55\x33\xbb\x7c\x3a\xaa\x39\xdd\x1e\xd4\x89\xf9\x8e\x17\xf9\x21\xfd\xbd\xf6\x5c\x10\x45\x53\xa5\x9f\x1f\x1a\x63\xdc\xbe\xd9\x7a\x0c\x35\x25\x63\xe1\x5c\xe2\x31\x29\xd5\xba\xc6\x7e\x3e\x2c\x7d\x67\xea\xd5\x4e\xc1\x48\xdf\xdf\xd7\x4b\x29\x93\x28\x1b\xfa\x02\xaf\xba\xb3\xbc\xe9\xe8\xec\xb8\x57\x17\x33\xf7\x4b\xdd\x1a\x87\x6b\x05\xc2\x03\xc5\x63\x23\x90\x4c\x11\xd5\x8b\xfe\xaa\x6f\xdd\x69\x09\xf4\x8b\xe3\x6b\x3e\x86\x8b\x1c\xcc\x41\xfb\x8d\x70\xd1\xad\x37\x76\x20\xc9\x2b\x90\x23\xad\xdd\x22\xa0\x89\x3b\xdf\x7a\x98\x72\xca\xe4\x53\x4b\x26\x31\x31\x72\x97\xeb\xf6\x29\xc6\x8c\x54\xa6\x83\x3a\xb6\x55\x22\xa8\x6d\xb3\xae\xcd\x55\x76\x11\x0f\x4a\xfb\x8f\x84\xf8\x85\x40\x38\xae\x48\xa7\xe7\x37\xf0\xab\xb6\xfd\xda\x3e\x44\xc1\x4b\x14\x61\x30\x79\x3a\xa7\xda\x47\x9f\xab\x61\x1d\x81\x19\xba\xae\xb4\xf0\xc1\xb3\xe8\x7e\x34\xfc\x9c\xec\xd3\x7f\x40\x41\x64\x8e\x31\xf1\x8a\x0b\x26\x52\x3c\xb4\x97\x4e\xa7\x76\x5b\xff\x73\xda\xa3\x05\xea\x49\x39\x86\xee\x9c\x9d\x74\x8e\x30\x71\x04\xcf\xda\x03\xf3\x39\x9b\x98\xa4\x6a\x48\x45\xad\xf0\x3f\x63\x9d\x58\xcd\x3e\x01\xe7\x74\xd9\xff\x1f\x76\x2d\xdf\xcc\x66\x72\xee\x0e\x6c\xb6\x22\x92\xd0\x82\x37\x9a\x44\xf4\x31\xf9\xc5\x77\x58\x52\x4d\x09\xe0\x9d\xc6\x89\x80\x9c\xa8\x19\x23\xa5\x40\x70\xe9\x9e\x71\x5e\xe0\x57\x55\x02\x4f\xca\x65\xee\xd1\xcc\x80\x3f\xde\x7e\x0b\x9f\xbc\xa8\x11\xc6\xdf\x54\x25\xff\x89\x58\xd7\x58\x0e\x00\x93\xea\xc9\x32\xbc\x93\x69\x15\x12\x10\xf3\x29\xcb\x7c\x39\xc0\x27\xb5\x5c\xad\xa6\xf7\x3e\x7b\x79\xe5\xc7\x66\x78\x8d\x17\xc0\xc8\xde\xc8\x51\x58\x5b\x22\x32\x76\x4a\x95\x2b\xc2\x1d\x7c\x9b\x7b\x1d\x93\x3d\x9c\xba\x35\xa7\xf4\xb7\x44\x77\x6e\x00\xa2\x7c\x07\xd6\xa6\xb1\x16\x6f\x09\xac\xd2\x1f\x98\x68\xd1\x93\xee\x76\x8e\x7a\xa9\x35\x08\x2e\x97\x61\xe0\x09\xa0\x19\x95\xb7\x62\xcd\xdf\xe4\xb7\x59\x9b\x87\xe7\x22\xd6\xd5\xcd\xec\xa7\x8a\x67\x2a\x1f\xb9\x91\x6c\x30\x4d\xb4\xd5\x86\x6b\xa5\xc0\xb5\x6a\x53\x98\xa4\xb9\x97\x4b\x4f\xe7\x69\x0d\x32\x72\x90\x68\xed\x53\x1e\x03\x8d\x2b\xc1\x17\x1e\x0e\x2a\xef\xda\x18\x9e\xf5\xa9\x5c\xd6\xb9\x9b\x36\x6b\xd1\x56\xfd\x3d\x16\x3e\xb8\x2d\x5f\xb8\xde\x4d\x9a\xfa\xa0\x63\x58\x87\xda\x12\x09\x15\xaa\x2f\x8b\x16\xd7\x3e\x57\xdb\x90\x9a\xd1\x71\x6f\x4a\xd6\x64\x80\xac\xa4\x7f\x13\xa3\x70\x95\xd7\xa0\x65\x79\xdb\x06\xdb\xe6\x66\x77\x2c\x27\xa6\x3a\x83\xe7\x5e\x1a\x9c\xd0\xe1\xeb\x05\xc2\x9b\xdb\xf9\xdc\x04\xc6\xa2\x1a\xb3\x3b\x8e\x5f\xae\x1f\x73\x00\x77\xca\x77\xd5\x9f\x3e\xdf\x25\xe1\x09\x85\x21\x6e\xfe\x72\x30\x7c\x42\x06\x7c\x03\xb4\xfc\x2a\xaf\xa3\x97\xce\xb0\xbf\x89\xfa\x9e\x77\x15\x87\x0f\x0d\xa7\x09\x36\x08\xaf\x6f\xc0\x9d\xa6\x00\x7c\xb7\x97\x6c\x3c\xf8\x5d\x9e\xfd\xf7\xa8\x39\x25\x8c\x75\x59\x17\xf6\x2d\x87\xa9\x6d\x2c\xe5\xf8\x75\x4e\xee\x68\xe6\xcd\x1f\x1b\x27\x42\x97\x34\x74\x07\xd5\x6a\xe1\x5e\x1a\x19\x00\xd6\xce\x57\x7b\xf9\x37\xa2\x51\x1b\xc0\x85\x56\x4e\x35\xed\x64\x7c\xb1\x8c\x21\x3d\x10\x22\x40\x4b\x7b\xe6\x2b\x65\x08\x51\xa2\x26\x06\x23\x65\xaf\x94\x42\xdb\xed\xfa\x3a\x69\x4c\xe4\xb3\xd9\xbd\x3e\xea\x2e\x1d\x1d\x98\x7d\xd8\xd9\x9d\x26\x84\xdc\x68\x9d\x21\xd8\x12\x41\xe4\x43\xc4\x70\xdd\xa8\x70\xab\x9d\x75\x12\x53\x77\xae\x4e\x45\x4b\x12\xe2\x1d\x51\xbe\x6b\xde\xe4\x92\x31\xec\x9c\x19\x96\xf3\xad\x6e\x8e\x63\x10\x8f\x20\x5c\x00\xd8\x05\x85\x79\x0d\x37\x58\xf5\x39\xa4\x64\x8e\x6a\xe3\x92\x9d\xaa\xa5\xbe\x60\xcc\x84\x05\xe8\xfe\x15\x37\x1e\x29\x6f\x2f\x42\x74\x9b\xfd\xd7\xef\x61\x63\x9a\xe4\x6b\x65\xb2\x95\xb4\x24\x6e\xff\xbb\x6c\x2f\xab\x40\x21\x55\x1c\x32\x58\x01\x6e\x3c\x51\xbf\x8a\xff\x24\xa2\xb4\x39\x65\x6a\x85\x6e\x4a\xb0\x67\xa8\x1b\xbb\x83\x2e\x71\x26\x00\x23\x2a\x9f\x15\xf3\x4d\x7e\xcc\xcf\xde\x34\xeb\x9f\xfc\xc9\xb6\x53\x7a\xc1\x3a\xb6\xb9\x5c\x61\xb1\x61\x6f\xd6\xd8\x39\xeb\xe4\x59\x92\x3b\x5a\x41\x79\x48\x6a\x10\xf7\x34\xfb\x65\x18\x5d\xf5\xcc\xe9\x62\x9d\x96\x2f\xc5\x43\x4d\x0f\xd1\x4b\x26\xfb\x98\x2f\xa3\x55\x69\x21\xe9\xa0\x00\x39\x86\x7d\xac\x90\x85\xe3\x89\xb0\x19\xac\x6a\xe5\xcd\x9e\x95\xb3\xab\x31\xf7\xe0\xcc\x80\x52\x27\x34\x09\x8f\xd2\xae\x1e\x2f\xad\xee\x38\x95\x5c\x34\xec\x5a\xf3\xf2\x63\x8f\x2b\x1c\x0f\x4e\x92\x39\x66\x8f\x16\x6b\xda\xba\x90\x74\x68\x2a\x91\xa3\x99\x84\xe9\x9a\xc2\x12\x4a\xc2\xf2\x80\x23\xc9\xf3\x3b\x91\xd5\xa0\xb2\xcc\x06\x51\xae\x9b\x4b\x46\x02\xbe\xf4\xe6\x6b\x99\x3e\xb9\xd5\x52\xe5\x8d\xfa\x81\x68\xd6\x1b\x31\xcf\xea\x54\x22\xc1\xb6\xef\x55\x89\x63\xfc\x46\x5e\xc0\x0f\xf1\x22\xc3\x40\x4c\xc7\xc7\xe5\xa6\x54\x2a\xb7\x53\xa3\xf1\x63\xb3\x11\x6c\xb8\x92\x2a\x3b\x3a\x34\x68\xc2\xc6\x2c\xf1\x8e\xd7\x7b\xcd\xfa\x39\x50\x55\x66\x65\x8e\x96\xd3\xf4\xa3\xd4\x8d\xce\xb8\x94\xcb\x3f\x45\x00\xa2\xda\x68\xb4\xfb\xc9\x38\x7e\x79\xdc\xd4\xbf\xa5\xc0\x78\x13\xdc\x11\x6e\x97\x3c\x1c\x72\x18\x4c\x46\xed\x66\x0c\x7e\x00\x80\x25\xda\xe5\x4b\xfe\x5c\x43\x47\x9a\xa4\xaf\x98\x14\xf0\x44\xf3\x5a\x4a\xeb\x90\xe9\xb8\xac\x46\xdf\x3e\xb8\x78\xb6\xf0\x36\x1b\xa7\x54\xb1\x61\x6b\x8f\xba\x25\x49\xbf\x72\x72\x53\xad\xeb\xd4\x52\xdb\x62\x1a\x35\x86\x6e\x3f\x99\x7d\xc1\x40\xa4\x1b\x83\x76\x9b\xba\xff\xe2\x87\x07\x84\xf1\xa7\xb7\xaf\x4b\x10\xfc\x58\xe1\x7d\x1e\xa5\x38\xf0\xc4\x61\x85\x5c\x71\x0c\x5a\xd7\xfe\xbe\x9d\xa3\xc0\x45\xbf\x7d\x23\xcb\x25\x34\x63\x2c\x18\x66\x6c\x10\x1b\x6b\x3e\x01\xca\xc6\xc3\xc5\x60\x6d\x61\xff\x23\xec\x59\x70\x10\x65\xba\x4f\xd6\xa6\x48\x6d\x30\x00\xcf\x2a\x2c\x28\x9c\x63\x72\x6e\x44\x85\x88\x90\x1c\xbc\xb9\x9a\xb8\x7a\x9c\x25\xee\x73\x08\x4b\xfc\x1d\x9c\xbf\x04\x15\xb0\x76\x58\x9b\x20\xfa\xaf\xa9\x7c\x09\xc5\x2f\x49\xc0\xa6\xa9\xfd\x92\x5d\x85\x88\xa6\x60\x71\x99\x23\xba\x06\x6e\xb1\x1b\x79\xd7\xc9\xdf\xea\x2f\x72\x4b\x5e\xef\x0b\xca\x0f\xaa\x84\x18\x54\xf9\x06\x97\x58\xa1\x42\x7f\xb5\xfb\x70\x90\x5b\x8f\xe6\x16\x67\xa9\xaa\x54\x78\xd9\xc7\x75\x75\x80\x6b\xe6\x2c\x06\x0a\xab\xbe\xb8\x73\x40\xe5\x92\x65\xde\x25\x28\x17\x3a\xc4\x10\xe9\xae\x56\x41\x7c\x62\xae\x13\x1d\x8c\xfe\xa2\x13\x88\xa4\x49\xd6\x65\xb2\xc1\xb1\x81\x7e\xd9\x6e\x76\x15\xaa\x82\x80\xeb\xd9\x84\xe4\x16\x81\xf0\x36\xc8\xe9\x75\x20\xa1\x18\x68\x07\xbd\x93\x0c\x05\xc4\x87\x57\x74\x26\xbd\xd5\x9e\x70\xa7\xa5\xf4\xf9\x10\x1b\xe3\x7b\x9f\xf3\x05\xa4\x0c\xa7\xe7\x98\xac\x4d\x01\xd7\xaa\x42\x6a\x8c\xce\x95\xe1\x52\x3e\xf0\x3a\x14\xc4\x68\x07\x45\x62\x95\x41\xc0\x5a\xd1\x64\x38\xe7\x48\x57\xe8\x2e\x68\x6c\x00\x84\xfc\x8d\xc2\xdd\xe6\x40\x94\x57\xe5\x57\xb4\x7d\x55\x65\xab\x87\xa4\xeb\xf5\xe1\x63\x26\xe4\x67\x19\xf6\xa7\x50\x8e\xed\xb6\x52\x8b\xd8\x55\xa7\xcb\xbb\x3e\x0b\x58\xd8\x8a\x4b\x2c\x37\x9a\x48\x71\xaa\xc2\x79\xbf\x45\x77\xa2\xe4\x37\x15\xb5\x5b\x22\x21\x87\x21\x2d\x2d\x38\x3c\x37\xc3\xec\x34\x8e\x00\xe3\xf2\x03\xe3\x8b\x73\xd5\x75\x33\x46\x62\xf3\x17\xf1\xa8\x7c\x5c\xf3\xd2\xeb\x2a\xc6\xee\x54\x4a\x33\x55\x01\xe2\x66\x84\x66\x85\x2d\xcf\xa7\xc7\x68\x55\x04\x8d\x95\xed\x1b\xc1\xb8\x0f\xfc\x40\xe0\x41\xa9\xdd\x77\xfb\x5f\xb8\x30\x45\x4b\x65\xb2\x96\xf1\x05\xa6\x43\xab\x6e\xb6\x40\x87\x8a\x54\xc8\x1a\x31\x9c\xa3\x80\xae\xf5\x42\x8a\xd9\x4a\xc9\x2d\x59\xfd\x42\x62\x2a\x9a\x68\xa8\xbb\x44\x7c\x4b\x9f\x60\x56\x8e\x9e\x99\x8d\x92\x97\x41\x8e\x63\x34\x01\x60\xab\x8a\xeb\x90\x2e\x30\xdc\x1d\x9b\xc0\x54\x18\x61\xae\xb7\xb1\xeb\xaa\xfb\xc9\x3b\x20\x05\xc8\x6a\x34\xdf\x0d\xd8\x67\x25\x5e\xde\x54\x0a\xfc\x4a\xed\x2b\x76\x83\xa2\x75\x74\x74\x74\xc7\x9c\xb9\x52\x00\x3d\x2f\xb8\x4c\xe2\xb0\x82\x46\xb9\xd7\xb0\xcc\x35\x09\x02\xf6\x9c\x94\xec\x3f\xcb\x76\x56\x79\x86\xb4\x1e\xc8\x5b\x2e\xb7\x34\xb8\x34\x7e\x39\x72\x5b\x9a\xa6\x7e\x24\xe3\x9e\xa7\xaf\x06\xcf\x76\xfa\x4d\x13\x55\x03\xc5\xd4\x80\xaa\x4b\xf3\xca\xc3\xb3\x2c\x00\x8d\xbd\x5c\x19\xd9\xdf\x35\xd5\xf1\x65\x01\xb5\x6c\xba\x87\xf1\xce\xa4\xb6\x22\x94\x60\x79\x9f\x5c\xaf\xc8\xb2\xee\xc1\xed\xbd\xf7\x25\x19\xe6\xb6\x81\x95\x83\xd5\x9d\x08\x66\x5c\x9c\x16\x76\x23\x8a\x6c\x67\x45\x55\xeb\x27\x94\x67\x6e\xb5\x7e\xd6\xb5\x5f\x2f\x28\x61\x6f\x2c\xf9\xbf\xad\x6e\x69\xe7\x50\x30\xcc\x48\x06\xbb\xca\x30\x26\x34\xc8\xb3\xf4\x52\x14\xf3\x22\x87\x5d\xa5\xbe\xc4\xa6\x3a\x20\x43\xb5\x8f\xb8\x59\x6d\x8e\xe4\x1e\x24\xe5\x01\xc2\xf2\xa9\x41\x02\xcc\x8d\x54\x2e\x5c\x37\x84\xd3\x0a\xfc\xee\x47\x12\xcf\x04\xde\xe8\x1f\xfe\x15\xbd\xfe\x66\x83\x40\xb7\x96\xe1\xaa\xb9\x5a\x05\xe7\x35\x56\xce\x97\x1b\xad\x25\xb3\x09\x4c\x0d\x32\x43\x35\x31\x6c\x3d\x6f\x2f\x23\x38\x95\x5a\xf8\xcf\xc2\x11\x9a\xf1\x91\xad\xa0\x95\x12\x2b\xc8\x2f\xb6\x01\x5f\xcc\x1d\xbf\x29\xc0\x1d\x8d\x78\x28\x9f\x66\xb4\xaa\x78\x39\x70\xb7\xf4\xf6\x91\xbb\xf0\xb3\x5b\x0f\x9b\xa6\x0a\xbb\xf1\x61\x4b\x20\x84\xb0\x49\x5b\xcc\xb3\xe5\x64\x1e\xbf\x05\x90\xf4\x59\x4b\x63\x52\xce\xe2\x47\xc4\x8b\x42\xa9\x0c\x1d\xeb\xf1\x9a\x0a\xe9\x81\xfe\x56\x65\xcc\x76\x0f\xb2\x5f\x31\x9e\xec\x6b\xad\x87\x5a\xfb\xb8\x76\x16\xcd\x8b\xb0\x66\xe1\x91\xd5\x54\xce\x7f\x16\x99\x97\x2d\x25\xfc\x78\xb2\xbb\x64\x41\x27\x90\xf2\x5f\x70\x1e\xb2\x22\x5d\x7a\x94\x2d\xeb\xb4\xc9\x6d\xc6\x99\xa3\xe8\x09\x1a\xe4\xfd\x18\xd0\xc9\x6e\x12\x26\xf0\x1b\x79\x7d\xd3\xd0\xc7\xd3\x9f\x12\xf1\x46\x51\xea\x9d\x40\x97\x13\xed\x3a\x98\x20\x35\xa7\x07\x3d\x51\xf3\xd8\xa7\x27\xf8\x65\x48\xd5\xd6\xee\x61\x3e\xf5\x7d\xb3\x35\xdc\x08\x64\x0f\xb7\xe2\x8d\xf5\xb6\x5d\xa0\x4a\xe9\x61\xee\x72\xff\x77\x48\x95\x9b\x5c\x0e\xb4\x21\x0e\x17\x1c\x6e\xeb\x45\x31\x01\x9e\xd0\xc6\x6c\x64\x68\x57\xb7\x1b\x5a\xae\xdb\xd8\xbd\x4b\xf1\x9c\x7a\xde\x44\xcf\xaa\x56\x7c\x49\xad\xf9\x0a\x0d\x7a\x6d\x76\x97\x4c\x04\x3b\x73\x80\x79\xf6\x4b\x8e\x43\xa7\x8b\x43\x47\xe2\xdd\x4d\xaf\x4e\x1f\xc4\x1c\x6b\x1b\xb7\x7b\x54\x83\x98\xc0\x5d\x98\x9a\xd9\x61\x4c\xc9\xad\xf4\x4b\xf5\x61\x1d\x36\xd8\x61\x1c\xa2\xde\x38\x27\x3f\xea\xf4\x0b\x72\xfc\x97\xdb\x02\x1f\x50\x54\x3f\x97\x81\x32\x41\xc1\xf8\x4f\xae\xb7\xe7\x6c\xc3\xbb\x33\x94\xa2\x0e\x9c\x43\x2b\xe2\x01\xee\xf0\xd8\xbe\xd1\x9f\x0c\x88\x55\xa7\x5d\x65\xd3\xa5\x23\x7d\xac\x23\xd6\x5f\x2e\xba\xd4\x77\x7c\x68\x68\xba\x9e\x3a\xa6\x20\x87\x2c\xb5\x74\xd0\x3e\x7c\x9a\x81\xf9\x16\xd2\xa8\x83\x2e\xae\xfd\xab\x40\x04\xf8\x4d\xf9\x94\x8e\xaa\xd8\x4c\x77\x71\x8a\x4a\x2a\xce\x43\x4b\xf2\x88\xfa\x87\x30\x53\x4d\x06\x83\xe4\xcb\xe9\x1d\xca\x01\x74\x94\xab\xdd\x2c\x8b\xba\x52\xa6\x39\x26\x4c\xc1\x33\xc4\xdf\xcd\x9f\x06\x29\xc6\x9b\xee\xb1\x09\x13\x42\x91\x22\x6e\x2c\xbb\x2f\x1a\x0c\x62\x12\xc4\xf1\xd2\x06\x7b\x84\x12\x39\xa0\x73\xa6\x84\x47\x57\x77\xb4\x38\x46\x39\x4d\x1e\xea\xbc\xff\xe4\x20\x6c\xfd\x08\x57\x80\x8c\x4f\xd5\xfa\x3e\x2e\xe7\xc5\xb8\xda\x9d\x81\x83\x92\xdc\x7a\x02\x3b\x8f\x8f\x8a\xd7\x8c\x7a\xc5\xb9\x5f\xde\x66\x5d\x8f\x50\xa7\x49\x81\x83\xdf\xc2\x24\x62\xe9\xd6\xe4\x63\x4f\xac\xd2\x98\xb8\x1e\x43\x25\x37\xdd\x4d\xd1\xbf\x83\x60\xa8\x9e\x17\x07\x06\x87\x8e\xb7\x25\x58\x8b\xe2\xe3\x68\xdf\x75\x31\x71\xe8\xa4\x3d\x13\xfe\x84\x15\x52\x90\xac\x20\xd7\x8d\x8d\xce\x42\x44\xd7\x8f\x97\xab\xa7\x49\xf2\x2f\xec\x6e\x41\x67\x0f\xd1\x36\x00\x76\x03\xf4\xd7\x06\x4b\x9a\xd4\x68\xd7\x84\x80\xff\x99\x17\xd6\x9d\x15\x48\x45\xc9\xda\x3d\x1c\xb3\x19\x76\xae\xbc\xd1\xb2\x49\x16\x95\x83\x34\x47\xb9\x5c\xa4\x92\x60\x06\xf5\x58\x27\xbd\x56\x59\x64\x03\x72\x0f\x78\xf4\x76\x30\x77\x95\x18\x69\xa7\x55\x8a\xfa\x35\x91\x31\xa5\xee\xd8\xd7\x74\x20\x68\xd3\x49\xd4\xa2\x10\x44\x7f\xe5\xc0\xa1\xa2\x62\x55\x1a\xf9\x18\x11\xff\xd5\x58\x40\xec\x95\xa4\x42\xa7\x2f\xf7\xd8\x3c\x30\xa6\x51\x99\x91\xb9\x28\xcc\xdc\x37\x3a\x44\xc7\x3b\x06\xc9\x15\x97\xd4\x80\xbb\x41\xbf\xcb\x6d\x76\xd3\xa1\x7b\x64\x69\x7e\xd8\xb8\xe3\x0c\xb4\x60\x59\xb4\x29\x78\x92\x79\xd6\xf9\x3b\x5a\x22\x67\xff\x22\x94\xac\x75\x30\xb5\x2f\x55\x4f\x17\xd2\xa9\xba\x9a\xc5\x46\x51\x4c\x48\x73\xec\xf4\xaa\xa2\xea\x3b\xfd\xe5\x92\x8e\x29\x96\x4c\x0c\x27\x3b\xcc\x3c\x2e\x08\xf8\xfd\x74\xe3\xba\xd4\xbc\xe3\x1c\x31\x41\xa5\x5c\xd6\x98\x59\x93\x8f\xf5\xfc\xfd\x9d\xdc\xa3\xd8\x00\x25\x34\x0d\x2a\x40\xb2\xf6\x44\x64\xac\x98\x9c\x0b\xc3\x5c\xc8\x53\x0b\x69\x66\x5f\x4c\x06\x31\xc7\x1b\x05\x0b\x89\x44\xb0\xec\xbb\xdf\xf7\xd5\x4f\x5b\x3e\xbc\x20\xad\x62\x13\xb0\x54\x4a\x12\xad\xe6\x8a\x2f\x16\x24\x2f\x19\x2f\x34\x27\x16\x67\xbf\xad\xf0\x92\x93\x38\xe4\x4f\x98\xd6\x6e\x26\x8e\x3f\x7b\xe9\x4c\x7c\xf3\x13\xb8\xa3\x73\xc2\xc3\x0f\xa8\xb3\x6d\xc2\xfa\x70\x2b\xdd\x61\xa5\x24\x04\x78\x1c\x84\xdc\xa8\x0b\xed\x61\xd4\x81\x68\xa4\x53\xd0\x9d\xe2\x9b\xb0\x7a\x43\x97\x63\xaf\xbb\xae\xd2\x31\xa5\xa1\x6e\x35\x92\xc9\xdc\x17\x56\x89\x2d\xf1\xc2\x44\xff\x48\x99\xa0\x1c\xdd\xe6\x2a\x8c\xc6\xc5\xa1\xa9\x47\x41\x67\xcb\x73\xc7\x6a\x39\xbe\xc6\x3e\x10\xbc\xbc\x19\xa3\x5b\x9b\x83\x12\x05\xe6\x0a\x8a\x59\x7a\xee\x64\x01\xb8\xb6\x52\xd5\xaa\x9a\x8e\x4a\xbd\x4f\x1f\x69\xaf\xc7\x40\x18\xa4\x06\xda\x31\xa0\x9a\x69\x0b\x68\x21\x6c\x22\xa4\x79\x62\x21\x6b\xf2\x8f\x55\xe1\x65\x92\x96\xb8\x0d\x21\x9a\xc4\x8d\x07\xf5\x70\x95\x71\xda\x2a\x98\x03\xed\x92\x86\x11\x05\xf0\x6b\x76\x50\x9b\xd5\x3c\x6f\x71\xd1\xbb\x33\x75\xb0\xea\x69\x2b\x8c\xe8\xd3\x05\x30\x0e\x52\x99\x89\xe7\xa5\x54\x70\xb9\xda\xbe\xe4\x38\x4f\xbb\x07\x49\x11\xc7\x33\x9e\x61\x3e\x85\x3b\x2f\xaf\x48\x2d\x7b\x41\x2f\x6e\x91\xc8\xde\xfe\x67\xc3\x64\x67\xaf\xe8\xce\xd4\x2d\x68\x25\x11\xad\xc7\x50\x7c\x64\x33\xc7\xe7\x6d\xb4\x4b\x46\xfe\xe5\x9c\xb0\x8e\xd0\x5f\x0a\x2d\x69\x2a\x96\xcb\xb5\x15\x7d\x70\x03\x1d\xd6\xe9\xd4\x0b\x94\x45\x9d\xfa\x47\x64\x10\xa5\x42\x3c\x8a\x3b\x3d\x72\x9b\x5a\x14\x95\x93\x36\x1b\xd6\x95\xff\x90\x09\xc9\x3e\x0a\xcb\x62\x41\x01\xb8\x14\x75\xcc\xe8\x3a\x1b\x57\x76\x26\xe3\xcb\x08\x00\x38\xf5\xaa\x06\xb4\x9c\xea\xb7\x4c\x53\x6a\x74\x28\xeb\x1c\x9b\xa0\xe4\xcd\x1a\x33\x7d\x14\xcb\x9e\xc2\xb5\x3c\x47\x8b\x75\x3e\x91\x09\xa8\x03\x04\xf2\xe6\xc3\x5c\x6a\x40\xa1\xa6\x51\x60\x10\x1d\xcd\xc6\x13\x68\x29\x35\xb4\xbb\xcd\xbf\x28\xa4\x6c\xd8\x7b\x1c\xaf\xbd\x09\x43\x50\xfc\xf3\xf1\xb9\x6a\x5e\x54\x72\x54\x43\x32\x6d\x8a\xdd\x8d\xd2\x06\x7c\xc0\x4b\x43\x1b\x90\x22\xb9\x3a\x01\xc3\x46\xbe\x3d\x89\x5d\xd6\x96\xda\x73\xc8\xe0\xb7\xa1\xf9\x80\x48\x6e\x81\xa9\x72\xd0\x10\xbc\x59\xa2\xea\xb2\x5c\xfc\x1f\x03\x47\x74\x11\x00\xf9\x5b\xfd\x8c\x12\x19\x79\x7f\xe2\x24\xf3\x74\x67\xd3\x57\x98\x1a\x2b\x6f\x03\x88\x10\x94\xdd\xb2\x7d\x9e\x90\xfb\xe5\x12\xe9\x6b\x34\xfb\xde\x3a\x82\x4b\x6a\x67\x07\x73\xcc\x58\xff\xb0\x61\xf0\x4e\x3a\xfe\xb2\xfd\x7d\x80\x46\x10\x0e\xa7\x5a\x01\x9a\xd2\x08\xc1\x32\x1f\x51\x7b\xa8\x52\x9d\x15\x1a\x5b\x4e\x26\x4d\x04\xf7\x6a\xb2\x34\x5d\x33\x51\x3a\xea\x0a\x73\x9c\xd7\xcb\xd7\x74\x1f\xfc\x87\xcb\x70\x49\xbf\x56\x5b\x11\x68\x9a\x6f\x81\x35\xb0\x7b\xe4\x7f\xe7\xf8\x3b\x87\x7f\x06\xad\x64\x0d\x97\xb7\x7f\x2e\xf2\xf1\x0a\xf1\x10\x23\x3b\x76\xc9\x45\x60\x5d\x87\x52\x30\x94\xeb\xd3\xcc\xec\x29\xc2\x7e\x9e\xca\xb9\x1c\xae\xe5\x7d\x5c\xc8\x9c\x20\xd8\xad\xfc\x3c\x8e\x5b\x00\xec\xcd\xa9\x91\x56\x5a\xc0\x02\x99\x1f\x5a\x3b\x75\xfc\xfd\x1d\x43\xf4\x72\x12\xf2\xf8\x2e\xe5\xf0\xbe\x9c\x2f\x33\xbb\xbc\x01\x01\xe4\x6e\x50\x6f\xeb\xc9\x56\x04\x2e\xf7\x8e\xc8\x49\x58\x89\x2b\x99\x9c\xa6\x41\x97\xd8\xf0\x87\x4a\x12\x8f\x72\xf1\xf3\xd2\x47\x03\x5c\xfb\x81\x5d\x47\x5c\xea\x67\x25\xdd\x6e\x63\x24\x83\x40\xe0\x4b\xbf\xd7\x82\x0f\xae\xf0\x8c\x44\xc5\x51\x57\x43\xc2\x65\x0b\xc3\x27\x22\x5f\x72\x46\x5a\xd2\x2f\x7d\x3f\xdd\xfc\xba\x59\x34\x47\x9e\x05\xcb\x68\x27\xad\xf6\xb4\x05\xef\x65\x86\x44\x8c\x4e\xf5\x6e\x25\x9a\x59\x47\x89\x4c\x88\x13\x91\x88\x00\x25\x13\x86\x0a\x9f\x6a\x6e\x90\x7e\x11\x8a\xa6\x49\x17\x92\xb9\x0e\x39\xd0\x95\x00\x2b\x49\x8d\x12\x2b\x2b\xd0\x9f\xd6\x8d\xfd\xf4\x08\xb4\xc3\xed\x7f\x5f\xae\x71\xda\x49\xa7\x5b\xb1\x32\xcd\x77\x33\x65\x74\xd8\x7f\x0f\xf5\x04\x00\xb1\xc3\x6d\xf5\xf2\x2f\xa7\x67\xb5\xf4\xa3\x26\xae\x9b\xec\x21\x54\xa9\x83\x07\x33\xb9\xa4\x42\xaf\x1c\x50\xc0\x64\xa8\xed\x32\x90\xe1\xb5\x68\x57\xfd\x3d\x4c\x72\x51\x5f\xe6\x76\xe1\x79\xfa\x58\xa3\x0a\x0e\xe3\x5b\x70\x43\x04\xdb\x74\x0d\xd8\x07\xbe\xc1\xe7\x58\xd9\xaf\x97\x55\x3c\x34\xa0\xdc\xba\x91\x8c\x82\x9a\x36\xe5\x0b\x2a\x71\xdc\xed\x7b\x3b\xc6\x4c\xee\xb9\x97\x83\xda\xe0\xf5\x30\x30\x52\x69\x78\xd2\x3b\xb7\x94\x11\x39\xc4\xa4\xb6\xfc\xf7\x13\x3b\x74\x0b\x18\x81\x18\x03\x7b\x9c\x77\x57\xe7\xe5\xa7\x76\xa5\xcb\xe6\x85\x6d\xde\x2d\xd8\xf0\x4e\xf3\xb2\xf1\xb5\x6b\xdf\xbb\x9f\xb9\x32\x87\x5e\x53\xe6\xb6\x71\xe3\xdf\x07\x15\xd0\x69\xe4\x0a\xfe\xe1\x31\xca\x20\x36\x07\x04\x60\xce\x29\x0c\xba\xd2\x89\x78\x7c\x4a\x0c\x66\x72\xc3\xdf\xc8\xcd\x67\x2e\x07\x00\xed\xf3\xa7\xf3\x00\xd8\x6f\xdc\xd2\x7f\xb7\x6f\xf2\x60\x9d\x00\x94\x20\xea\x33\x10\x77\x42\x5e\x96\x16\x15\xda\xa4\x70\x43\xaa\xce\xc0\x56\x0b\x56\xef\xf3\xa3\x46\x1c\x75\xac\x7c\x65\x0c\xe4\x50\x99\xd4\xea\x37\x03\x71\x23\xb7\x63\xa0\x6d\x2c\x2d\xfb\x5e\x5e\x05\x8f\xfe\x49\xd9\x83\xfb\xa6\x54\x39\x70\x8e\x5c\x03\xd9\xa2\xc9\xc0\xdd\xde\x16\xc8\x49\xbd\xb5\xef\x81\xd5\x45\xba\x1d\x1e\xd0\x04\x21\x89\x22\x2b\x57\x54\x0d\x1b\x4c\x36\xe8\x4a\x54\xf2\x84\x6c\x97\x6c\x74\xcd\x46\xc3\x30\xee\xf2\x26\xd8\x3e\xbb\x4d\xfc\x49\xc6\xdf\x72\x30\x66\xcb\x53\x2a\x5f\xf1\xdc\x6c\xb3\xed\x23\x91\xcb\xbb\x85\x01\xa0\x9f\x47\x87\xa3\x1b\x1b\x3c\xc6\xd1\xb7\x43\xe8\xa4\xb7\xc9\x9a\x7a\x17\xc1\xac\x29\xa5\x46\x79\xe7\x9e\x3b\xcf\x01\xd0\xb3\xde\x56\xef\x33\x55\xb3\x5d\x82\x83\xc3\xb9\x13\x91\x2c\x31\xd5\xa0\x5a\x66\x85\xe3\x39\x0a\x93\x70\x3b\xc6\xa3\xa3\x4f\xad\x12\x22\x64\xf0\x8a\xc3\xf6\x3a\x61\xc3\xd6\x15\x15\xe5\x50\xd9\x4d\x6f\x83\xc2\x44\xbc\xd5\xe2\x19\x53\xba\x38\xef\x4f\xe1\xdd\xb3\xf8\xf8\x07\x9a\x76\x3e\x61\xa1\xd0\xbc\xab\xe3\x7a\xbf\xe7\xf6\xda\xc6\x96\x2e\x0c\x17\xde\x7b\x8e\x31\x39\x90\x6b\xd6\x88\xec\xd3\x5c\x41\xc3\x31\x96\x47\xf3\xe2\xad\xda\x84\xd0\x0b\x0d\xa9\xd1\x1d\x6a\x55\x3e\x06\x91\x80\x22\xf3\xdc\xd4\xd1\x94\x2e\xab\x90\x23\x2f\x71\x4c\x70\x0d\x23\xff\xea\x54\xba\xbf\xb0\x62\xee\xa7\xfe\x3a\x8d\x65\x4f\x9d\xa7\x73\x64\xad\x1e\x73\xbc\xcc\xfa\x5b\x7b\xf4\x7c\x31\x3d\xd2\x4f\x7a\x27\xaa\xaa\xf1\x30\x36\x9a\xac\xc7\x96\xa5\x8a\xb7\xc8\x61\xb1\x7c\x88\xb9\x44\xa5\x27\x71\x1d\x27\x34\x0a\x6f\x6a\xf9\x3c\xca\x09\x1c\x7a\xa4\xe3\xf1\xfb\x52\x39\x88\x5c\x32\xdc\xbe\xe7\x51\x04\x78\x71\xff\xc9\x71\x9f\xab\xd1\xb6\x1c\xa1\xb4\x6a\x4d\x5f\x2f\x81\x99\x19\xab\x8d\x65\x9f\x27\xc8\x86\xe4\xc9\x2d\x1c\x48\xff\xf4\x74\x2e\x20\xc4\xa9\xb2\x8b\x43\xd6\xfc\x56\xb9\x98\xfc\x65\x70\xda\x6d\x01\x52\xde\xa8\x95\xa2\x6b\xdf\x34\xb8\xed\x5c\x32\xdc\x11\xda\xbc\xd8\xd1\xe5\x91\xd3\x9f\x53\x67\xe1\x63\x54\xc7\xe5\x61\x16\x1f\x10\x70\xe7\xee\x33\x9e\x5d\x03\xcd\x4d\x2a\x8e\xa0\x44\x05\x62\xa3\xc7\xda\x37\xa2\x3a\x87\x68\x79\xf4\xb2\x44\xf3\x28\xdb\xc2\xbb\xdb\x38\xb1\xc3\x2a\xe7\xcd\x9d\xa4\xf6\xf2\x61\x28\x27\xb3\x82\x4c\x17\xca\x72\x6d\x68\x9b\x70\xd3\x7b\x4f\x87\x42\xe6\x4d\xe5\x24\x67\x8c\x25\x8c\x2f\x96\x6f\xb7\xed\x6b\xb6\xfd\x99\x1d\x00\x30\x74\x60\xc1\x9a\xca\xd3\x42\x3c\x86\x98\x22\x3a\xc7\x31\x14\x86\x6c\x5e\x85\xd7\x6a\x6b\xcf\x16\xe9\x4a\x30\xf5\x37\x7f\x6e\x7a\x00\xaa\xc2\x55\xff\x77\xe4\x96\xae\x42\x33\x43\x6c\x64\xa5\xc1\x52\xc8\x7b\x07\xc6\x18\x4a\x0f\x91\x25\x1e\x24\x9f\x1c\x25\x5f\x75\x17\x36\x2f\xee\x20\x42\xb9\xc9\x90\xc3\xc1\xd0\xbe\xfd\x53\xfe\x56\x99\xa9\x9c\x84\xe5\xa9\xef\xca\x92\x7d\xcf\xf7\x68\xc4\xf4\x53\xa9\xf8\x9f\x82\x41\x41\x6c\xd3\xb9\xef\x64\x7e\x28\xf7\xc0\x76\xea\xee\x36\xfa\x60\x55\x41\xbc\x95\x7c\xf5\x1d\xe5\x24\x38\x8e\x95\x82\x0f\x5a\x73\xa4\xc9\x6f\x95\x6e\xc8\x97\xd5\xce\xa2\x64\xb2\x07\x1c\xfb\x5e\x21\xb9\x82\x4b\x5b\xd1\x75\x2b\x61\x65\x22\x6c\x8a\x6c\x14\xe3\x2a\xec\x8c\xe3\x96\x6c\xe3\xaa\x56\x27\xb0\x3b\x2f\xe5\x15\x25\xcd\x06\x2c\xbc\xe6\xed\xe3\x52\xe1\xb8\x9d\x25\xdc\xca\x45\xcf\x1d\x09\x70\x88\x9a\xde\xa4\x0c\x18\x51\xf8\x18\xab\x4d\x11\x2a\x37\x8f\x04\x61\xae\x73\xba\xe6\xbb\xdc\x74\x42\x2a\x3e\x4e\x67\xe2\x4a\x8d\xb4\x12\xc4\x29\xce\xe1\x50\xdc\xbc\x99\xd1\xaa\x82\x61\x88\xb2\x78\xc8\x4b\xae\xfe\x22\x08\xe1\xdc\x7e\xae\x29\x73\x57\xa2\xec\x9e\x94\x6c\xdd\x3d\x5d\x26\x35\x66\x73\xcb\xb6\x9f\xb3\xd8\x31\x39\x4f\x65\xa3\x73\x2e\x04\xa2\xab\x90\x29\x58\xf0\x80\x96\x89\xa5\xd8\xae\xa8\x18\x0f\x1b\x5f\x8a\x08\xeb\x8e\x6f\xb9\x36\x6c\x6a\x46\x7c\x23\xdb\x17\xc2\x38\x02\xef\xa5\xb7\xd4\xb7\x94\x3b\x91\xb3\xc6\x56\x47\x99\xb9\x73\x23\x3b\x9c\xf4\x63\xc2\xf2\x08\x4f\x1a\x18\xc3\x97\x28\x10\x21\xaa\x3d\xb7\xcd\xde\x63\x44\x81\xfb\x6c\xb6\xdf\x64\xcc\x5e\x5a\x08\x62\x6a\xd8\x39\x87\x7d\x26\xb7\xeb\x19\x27\xf4\xb2\xe6\x67\x16\x2a\x17\xc6\x43\x56\xd7\x82\xb6\xfa\x91\x05\x82\x14\xca\x45\xe7\xf3\x19\x86\xb1\x9d\x6a\xa4\x7a\x1c\xab\xf9\x13\xa2\xd2\xa9\x95\x0b\x78\x05\x34\xee\xcc\x42\x94\xac\x77\xc4\x74\xe0\xb5\x25\xcf\xfa\x5b\x76\xb2\x86\x33\x5b\x30\x97\xdf\x8c\xe8\x37\x14\xb3\x2f\xfe\xb7\xad\x76\x1d\xfd\x72\x1a\x27\xa6\x72\x11\x6d\x04\x66\x86\x80\xcd\x6c\x2e\xd2\xce\xf5\x61\xb5\xe8\x73\xad\x1d\x79\x38\x30\x9d\x4a\xf7\x5b\xd7\x69\xc7\x9b\xd3\xff\xa3\xd4\x05\x77\x59\x4c\x6f\xb0\xab\x0e\xd4\x3e\x9b\x53\x0a\x13\x94\xf5\x62\x58\x81\x47\x98\xd8\x19\x18\x78\xa9\x39\x05\xc8\xbb\x9e\xd7\x07\x24\xa7\x0e\xe6\x0e\x90\x6d\x8d\xc9\x4c\x2a\xbf\x27\x77\x80\xcf\xf2\x31\x35\x2e\x09\x4a\x65\xaa\x24\x1d\xe4\x32\x2e\xa6\x88\x74\xbb\x0f\xe4\x5d\x21\x5f\x78\x05\xeb\xfd\x4b\xf5\x55\x87\x7f\x0a\x71\xac\xf4\x7a\x09\x85\x79\xca\xce\x0c\x6c\x2b\xb1\x3a\x53\xbb\x91\xa9\xac\x10\x73\x36\x8d\xc2\xff\x16\x82\x09\x63\x58\x13\x6e\x6e\x96\x63\xc4\x1b\xa9\x81\x11\x5c\x80\xb1\xe9\xd9\x16\x16\x99\x22\x2b\x40\xf1\xd3\xba\x26\xb8\xf3\x3b\x8f\x18\x75\x8c\x61\x99\xb9\xf2\x14\x87\x7e\xbc\xa6\xb6\xfd\x26\x74\x50\xaf\xde\x03\x5d\x15\x35\x7a\x55\xd0\x62\x26\x05\x08\x28\x07\xb4\xf0\xbb\x52\xb0\xb1\xe3\xdf\x1c\xa4\xbb\x59\xb4\x29\x8c\x09\x4e\xc7\x2c\x7c\x2f\x0a\x56\x0a\x44\x73\xd9\x3f\x65\xcb\x85\xb9\x67\x89\x5c\x31\xc0\x7d\x2c\x66\xa9\x52\x67\x38\x1a\x59\xd5\x4c\xf2\x67\x54\x8c\x7a\x05\x15\x40\xd8\xd1\x2c\x4a\x69\xd9\x2b\x25\x30\x07\xdb\x6b\xd4\x39\x3a\xc0\xb5\xc9\x50\xb8\xcd\x4e\xbd\x40\xe1\x86\x95\xd3\x90\xce\x2a\xe0\x36\x3a\x3f\x38\x17\xca\x4b\xdc\xe4\xbe\xbd\xbc\x55\xd7\x3c\x4c\xba\x85\x92\x36\xfd\x74\xb7\xda\x03\xa3\xac\x9b\xab\x06\x8c\xe4\x95\x29\x30\x01\xb9\x13\x63\x3e\x29\x44\xf1\xbf\x66\x93\xdd\x53\x30\x57\xab\xf2\x0b\x9a\x9b\x12\x13\x2c\x39\x50\x27\x5c\x5a\x77\xb9\x05\x42\x24\x8e\xca\x4d\xf9\x4b\xc2\xbd\x3f\xaa\x7e\x32\x0d\x64\x24\x9a\x9a\x34\x32\x2a\x1f\xcd\xb7\x5b\x5f\x09\x4a\x50\xb6\xa8\x84\x68\x54\xf5\x5e\x0f\x6a\x7c\xa7\x29\xc2\x43\x28\x3c\xe9\xf2\x6e\x4e\x4c\xa5\x9d\xdd\x0a\x7a\x7d\xa4\x0a\x51\xd5\x0c\xbc\x99\xa2\xfa\x6a\xc2\x68\xb8\x49\xd4\x70\x61\xf0\xd1\xf4\x07\xdd\x83\x14\x73\xb6\x74\x01\x4b\x4a\x5d\x70\x93\xd0\xbb\x9a\xd6\xf2\xb9\xf3\x7c\x49\x5d\x84\x87\x18\x93\xef\x21\x33\xc3\x78\x4b\x81\x04\xc3\x65\x4d\x89\xcd\x03\xc0\x54\xe9\x6c\x42\x6e\xb9\x6c\xbc\x43\xfd\x18\x29\x52\xbc\xad\x73\x04\x79\xf8\xde\x27\x58\x89\x29\x55\x92\x62\x84\x95\xbf\x31\x1e\xe9\xef\x5a\xa1\x4b\x47\x3d\x21\x76\x41\x02\x6a\x71\x10\x7d\xb9\xda\xdc\xa6\x6c\xbc\x5b\xe2\x9c\x3f\x44\x5c\xb8\xc2\x48\x13\x5d\xcf\x52\x84\x19\xb0\x3d\x60\xcf\xe2\x6f\xd4\xbd\x6a\x48\xba\xf7\x36\x26\xc0\x57\xe7\x3d\x07\x1f\x51\xc5\x95\x99\xe4\x2b\xc6\x87\x73\x51\x74\x78\x5c\x0d\x72\xe8\x98\x54\x80\x77\x6b\xc5\x3d\x4c\x1f\x35\x3c\x0e\x5e\x27\x00\xab\x61\xce\x1f\xe6\x40\x31\x3d\xcf\x9f\xf0\x8d\x25\x6a\xe3\x54\x78\xca\x13\x0d\x1f\xa4\xb6\xc2\xcb\xbc\xec\x5b\x76\x4a\xb9\x24\x24\x4f\xa8\xd6\xbc\x83\x4b\x27\x33\x9b\x09\x3e\x35\xf6\xb0\x01\x7f\x72\xb2\x9a\xc2\x4c\xe4\xaf\xf8\xbc\x40\x4f\x0d\xe5\x70\x3b\x5c\x3c\x2c\xa7\x5a\x3d\xbe\x73\xaf\x94\xc4\x72\xcf\xcd\xc2\xe9\x94\xfb\x8e\x88\xcd\xc0\x23\x0b\x63\x95\x93\x3e\x87\x52\xfb\x10\xc9\x30\x5e\x3e\x7b\xc3\xb9\x4d\xde\xfb\x2e\x18\x3c\x2c\x41\xd7\x0f\x90\x38\x6e\xef\x9e\x68\x69\xef\xef\xe8\x76\x2f\xb6\x9f\xa1\xcf\x28\x7f\x98\x42\xf8\x65\x9c\xfc\x4d\x2b\xcb\xf0\x9e\x06\x87\xc4\xa4\x0a\x9a\xa9\x6d\x1e\xdb\x75\x17\x28\xb2\xfb\x93\x00\x30\x10\x63\xa2\x35\x8f\x9f\x06\x29\x4e\x19\x16\xf2\xb8\x83\x3e\x31\x8d\x15\x2b\x9b\x2d\x30\xd0\x4e\x6c\x2d\x4c\xce\x25\xec\x10\x5b\x4e\x62\x37\x04\x77\x55\x02\x9c\xf9\x79\x74\x6d\x79\xd0\x18\x24\xa5\x50\x92\xe1\xf0\xd2\x08\x72\x68\x79\xa1\xa0\x66\xde\x3f\x87\x47\xe5\x51\x91\x1e\x40\x98\x2f\x76\x04\x34\xaa\x30\xc4\x8a\x9a\x3e\x82\xb6\xb3\x09\x26\x16\x79\xea\xd5\x34\x7f\x45\x8f\xef\x50\x22\x60\x7b\xc1\xf2\x55\xbe\xd5\x4d\x3f\xef\xb4\x05\xd5\x61\x72\x64\x95\x69\xd1\xe7\xa3\xda\xbe\x8e\x7c\xeb\xf9\xee\xef\xe0\xfa\xc6\x36\x0d\x35\x2e\xd5\x0c\x93\x7d\x1c\x26\xc3\xff\x08\x41\xd4\x69\x3d\x80\x5b\x7c\x88\x3f\x11\x81\x4b\xb2\x94\x3c\x7f\xf3\xc3\xdb\x84\xde\xcf\xb6\x7a\x1f\x75\x68\x6e\xe2\x53\x83\x14\xdb\xa9\x84\xef\xfa\x79\xad\xea\x1e\xbd\x41\x79\x74\x80\xaf\x30\x55\xaa\x7b\xf8\x4a\xb1\x9d\xb1\x9e\x35\xe0\x42\xcd\xab\x7d\x7f\x52\xeb\xde\x6c\x5e\x91\xa1\xf3\xf8\x95\xa2\xc7\x8d\xfd\x73\x7f\x47\xf3\xc9\x7d\xc6\x97\x74\x97\x4e\x2f\xdf\x69\x3f\x3d\x63\xd1\xea\x58\x4e\xa0\x78\x58\xfc\xb2\x02\x86\xcb\xa6\x61\xe3\x7c\xbc\x53\x49\x0d\x9b\x26\x9b\x28\xf7\xcc\x3f\x23\x37\x51\xe7\x76\xf8\xcf\x29\x64\x9a\xa0\x8b\x6a\xdc\x99\x99\xea\x4a\xc1\x14\x0e\x95\x10\x63\x55\xd7\x41\x57\xcf\x54\x23\xe3\xfd\x8e\xf8\x09\xf9\xd2\xc3\x29\x9c\x95\xe5\xc3\xe9\x60\x61\x44\x41\xd5\x2a\xc7\x6c\x4a\xe2\xd2\x95\x53\xf3\x98\x6c\x08\xfe\xa0\xf0\xd1\xc3\x14\x28\x55\x05\x98\x43\x56\xb5\xf2\xfb\x24\x34\xc7\x1d\x04\x2b\x15\x0d\xae\x24\xca\xc9\x6f\xbc\xa0\x7d\xad\x2a\x16\x0b\x41\x4a\xc9\x3d\x20\xff\x01\x15\xd9\x04\x1d\xd9\xf2\x14\x30\x90\x1d\x7b\xd1\x1e\x8a\xbd\x80\x90\x91\xe6\x5b\xfc\x4e\x7b\xf2\xdc\x02\x76\x75\xae\xd1\x56\x32\x94\xeb\xde\x8f\x1a\x2b\x7f\x19\x73\x77\xb4\x45\xa9\x4a\xc0\xe8\xf8\x05\x9b\xb0\x36\x5e\x41\xef\xd7\x01\x8f\x49\x06\x91\x11\x82\x10\x0b\x48\x5f\x89\x84\x1b\x13\x79\x88\x06\x97\x93\x7f\xe4\xd2\x1e\xc7\x25\x83\xaf\x50\x51\xe2\xbd\xee\xa2\x35\x35\x34\xe9\x69\xea\x47\xdd\x20\x4e\x88\x9e\x55\x36\x8a\xba\x8c\x09\x22\x36\xc6\x1f\x13\x31\xe2\xce\x01\xb0\x66\xf6\xb1\x25\xf7\x82\xd5\x88\xf3\xf4\x8f\x8e\xf4\xbf\x5f\x70\xb0\x8f\xdb\xf5\x6f\x50\x78\x2b\x20\x19\x12\xc5\xfd\x35\x4b\x73\x22\x73\xae\x21\x61\x7a\x62\x3e\x18\xa1\x04\x90\xc5\x0a\xcf\x94\x21\xca\x51\x4d\x7d\xd5\x4b\x10\xaa\x0b\x7a\x2b\xe5\xe0\xe5\x10\xbf\x7c\x5c\xe3\x52\x12\x9a\xf0\x66\x46\xdf\x8f\x81\x62\x35\x2f\x6d\x27\x64\x01\x5e\xac\xe1\xfb\x35\x55\x44\x66\xae\x4c\xf3\xe8\x67\x94\xed\x36\x59\xa6\x1d\xfd\x55\x93\x50\xa6\x20\x97\x83\x85\x66\xed\xc9\x6f\x7b\x0f\xfd\x74\x1d\xb6\xe4\xa8\xb2\x86\xb6\x04\x68\x9d\x25\x91\xae\x98\xe7\xae\xef\x2b\x50\xc4\x54\x96\x5a\x26\x95\x83\x76\x92\x22\x01\xea\x0f\xb5\x27\x3e\x81\x81\xc6\xe9\xdd\x44\xd3\x62\xac\xb8\xb2\xfd\xcb\xdb\x88\x8e\x88\xed\xc7\x77\x28\x21\xa3\xb5\x7b\xc7\x6b\x55\x65\x33\x89\xd2\xd1\x0c\xc8\x17\xb5\x93\x6a\x04\x33\xb8\x72\x55\xb1\x23\x8f\xa4\xce\x8d\x4a\xb6\xc1\x20\xd6\x82\xd9\x7b\xeb\x06\xa5\xc5\x2c\x43\xa2\x50\x49\xc6\x09\xd0\x8e\x40\xa2\xd4\x5c\xed\x18\x3b\x96\x8c\xf6\x9a\xc1\xa1\xf8\x7e\x1f\xea\xfe\xcd\x9f\x83\xc2\xd1\x02\xaa\xa8\x4b\x66\xbd\x1a\x85\xc0\xf2\x4f\xe6\x40\x66\x57\x02\xd8\x9c\x00\x5e\x1e\xd9\x2f\xba\x99\xc8\x60\xfc\x24\xa2\x21\x00\xbd\x66\x32\x8f\x97\xdc\x3f\x36\x9c\x71\xdc\x73\xa3\xce\x0a\x63\xa6\x36\x4a\xf4\x2d\xb7\xaa\x9d\xb8\xec\x11\x0d\x69\xbd\xed\xd2\x85\xd3\x2d\x0f\x00\x87\xcb\x32\x46\xfa\x6d\xc8\x8e\xca\x11\xc4\x5a\xf8\x21\x42\xf7\xc3\xf8\xbb\xc7\x20\x70\xd0\x43\x55\x95\x0c\xff\x9d\x9e\x94\xeb\xe5\x57\xfd\x94\x8f\xfb\x26\xb9\x33\xd1\x0d\xd0\x7d\x2d\x80\x64\xe3\xaa\x9c\x7c\x55\x32\xe7\x6f\x82\x38\x94\xa7\x17\xf8\x1a\x2a\x4d\xab\x7a\x63\x7b\x96\x5f\xc3\x01\xf2\xec\xc9\xb0\xf0\xc7\x68\xb7\x06\xb7\x39\xba\xfe\x95\x0d\xb5\xb9\x57\x94\x78\x5b\x22\x9c\x9a\x55\xdd\x9f\xdc\x9f\x2f\x7b\x8e\x12\x0a\xd0\xe6\x52\x6a\x54\x63\x10\xea\xdf\xa7\x2a\x6c\xb2\x07\x54\x96\x22\x27\x0e\x86\x53\xcc\xb8\xe0\xd2\x54\x62\x99\x9a\x24\xe8\xf3\x72\x51\x12\x97\x2e\x1e\x8c\xe6\x5a\x73\x56\x9b\xf2\xec\x4a\x1b\x04\x3b\x5b\x0b\x25\xab\x10\xb0\xc8\x6a\x52\xf3\xd9\x47\x4f\x37\x46\x52\x33\x18\xf7\x10\x8f\x63\xf8\x19\x26\xde\xa7\x7d\x87\x56\x8e\x5e\xac\xec\x68\xe4\x7a\x59\x94\xbc\x5e\xdc\x53\xfc\x4f\x75\x8d\x1d\x37\x68\x51\x4c\x56\xdc\x7b\x18\xad\xe0\x38\xee\xcf\xbc\xe2\x1d\xbc\xd3\xa4\xc1\xde\xeb\xf2\xda\x7d\xb1\xab\x8b\x17\x03\x15\xf5\x0a\x88\x15\x49\xbb\x40\x5f\xd1\x21\xd1\x32\x66\x62\x25\xd5\xd9\x07\xe8\xa3\x31\xe6\x6c\x9f\x94\x1a\x56\x89\x03\x4d\x94\xa0\x1d\x2d\x3a\x3f\x19\xda\xf8\x3e\x0c\x2d\xd8\x4e\x13\xf1\x36\x75\xaa\x76\x4b\x11\x93\x99\x57\x55\xaa\x7a\x28\xfa\x64\xf7\x42\x66\x25\x4c\x5d\xd7\xbb\x8d\x91\x27\xf7\x31\xe0\x76\xe3\x28\xf7\x38\xbf\x86\x9b\xe8\xbd\x56\x49\xc8\x10\x92\xfb\xef\xcc\xc7\x77\xa7\x55\xd1\xc4\xa0\x03\x45\x1b\x50\x56\x2b\xe3\x0e\xcd\x1e\x96\xe5\x8c\x24\x46\xf8\xe7\x79\x7c\xb0\x66\xc8\x92\x68\x59\x50\x12\xe7\x35\x22\xc9\x5d\x7c\x8f\x25\xa9\x81\x81\x3c\x9b\x83\x91\x9e\x56\x76\x9e\x62\x70\x7f\xa3\xa5\x20\x29\xf0\xb1\x69\x42\x9e\xf7\x25\xe0\x5b\x0c\xd6\x26\xe8\x48\xee\x8a\x0b\xb9\x5a\x16\x3c\xc3\xa1\x56\x2e\xb7\x5e\x85\x71\x8f\x07\xa1\x4b\x6e\xeb\x00\x04\x49\x0a\xe5\x5c\x91\x34\xed\x55\xd2\x57\xce\x68\xe3\xfc\x8f\xce\xf2\x70\x06\x3a\xa4\xb6\x38\xf8\x70\x32\x7a\x13\xed\x0c\x7e\x5f\x0f\x9b\x37\x3e\x90\x0a\x39\x8f\xea\x89\xe8\x0b\xc2\xec\x22\x3e\x4b\xc9\x99\x0e\xdd\xaa\xfd\x1a\x8a\x12\xf0\x91\xf5\x7c\xe2\x3e\x32\x43\xbc\xf7\xce\xb2\x4a\xd6\xcb\x7c\x09\x2a\x80\x6b\x38\x88\x75\xdc\x4a\xdd\xc7\xc3\x90\x77\x58\xf9\x71\x1e\x32\xdf\xf5\xd7\x40\x94\x61\xb9\xbc\x63\x8f\x1c\x6d\x5b\xc9\xbb\xf9\x70\xef\x7a\xd9\xc1\x80\x01\xca\x05\xd1\x83\x4a\x6f\x49\xae\xdd\xdb\x2b\x72\x70\x44\xea\xee\x47\x39\xf5\x3c\x42\xa9\x1f\x9a\xee\xce\xf9\x6b\x5d\xd1\x14\xe5\x92\x94\x5c\x66\x49\x8e\x77\xed\x60\x69\x9f\x4b\xa2\x33\x59\xba\x97\x72\x0d\xea\x76\x94\x04\x83\x88\x5b\x32\x46\xa4\xf9\xba\xcd\x56\x4c\x7a\xb3\x46\x85\xf9\x5e\x66\x82\x21\x92\x56\x4c\x50\xf8\x26\xba\xfa\x3d\x7e\xce\x27\xdf\xcf\xc7\x49\xc8\x3b\x84\x95\x06\x05\x27\xb5\x65\xdd\x4d\x2d\xdf\x95\xf2\x2f\xea\x13\xaa\xb3\xa9\x4d\x74\xfb\xd6\x75\x60\x3e\x34\x6c\xee\x83\x00\x00\x23\x24\x12\x2d\x78\x88\xab\x40\x19\x7e\x44\xff\xe7\xc0\x71\xa9\x96\x28\xfd\x6c\x0c\x9e\xfd\xd8\x72\xcc\xde\xdb\xe1\x97\xbe\x29\xd4\x48\x0d\xd9\xc1\xa2\xac\x93\x3c\xb5\xd6\xab\x79\x52\x72\x21\x62\x24\xf7\x3a\x2b\x90\xe5\x75\xd9\x34\x5f\x00\xa6\xa3\x96\x98\xe5\x8e\x84\x56\x77\x87\x67\x8c\x56\xdf\xbc\xc0\xb6\x5c\xc9\x19\x20\xbe\x45\x74\x79\x3a\xa4\x94\x74\xe6\x54\x9c\xd1\x25\x0f\x58\xa0\x73\x2f\x99\x3c\x56\x3e\x0a\x42\x4b\x64\x41\xa6\x74\x85\xf0\xac\x03\x0e\xe6\x20\x61\x50\x41\xa7\x01\x77\x55\x26\x09\x99\xac\x56\x0b\x1a\x6b\xdf\x70\x05\x88\xc3\xf8\x04\x18\x61\x1e\x6e\xb1\x22\xb2\x29\x54\xc9\xe4\xc2\x79\x52\x39\x62\x42\x4f\x92\x1c\x05\x56\xa3\x8b\xb8\x95\x4b\x15\xc3\x5c\xd2\x6b\x34\x29\x69\x29\x51\x06\x56\x1d\x5a\xcf\xbd\xe1\xb9\x7b\xaf\x43\x87\x52\x69\xbd\x82\xd8\x3b\x9d\x4f\xee\x13\x24\x40\xf5\x13\x9b\x71\x3e\xb2\x01\xab\x2c\x68\x0b\x12\x79\xf9\xfb\x0f\x51\xf9\x83\x01\x30\xa5\x4a\xe9\x5c\x57\x5e\xe0\x50\x29\x1a\x23\x8a\x49\xe1\xf1\xe6\x4c\xa7\xc2\x61\x81\xe6\xb8\xdf\xab\x6e\xad\x70\x1c\xc6\x43\x96\xa3\xbd\x1a\xa7\x61\xaa\x0b\x6c\x91\xfa\x30\x8c\xa9\xa5\x10\x14\x09\xb4\xd4\x01\x2f\x77\x6e\x61\xd4\x1b\xf9\x51\x12\xb7\x15\x15\x62\x85\xad\x95\x6b\x86\xb2\xbc\x49\x77\x7c\x71\x63\x10\x6c\x40\x10\x84\xc4\x0f\xed\xae\x07\xd9\x68\x37\x26\x56\x02\x84\x60\x0e\xf5\xc7\x05\x23\x82\xa0\x96\xed\x33\x82\x61\x05\x7b\xb9\xc5\xa5\x69\x93\x39\x73\x01\x1b\x2a\xd5\xe2\x76\xb6\xd5\xc9\x95\x8e\x69\xfe\xeb\xfb\x65\x88\x3e\xa8\x97\xb7\x4b\xd6\x1a\x4b\x18\x85\x8d\xce\xbe\xbb\x60\x4e\x76\x91\xbe\x83\x75\x87\xe2\x25\x09\x3e\x49\xae\x81\x9e\x01\x86\x41\x0d\x8b\x77\x29\x0a\x2a\x78\x36\x9b\x1c\x18\x3d\xc4\x68\xa9\xdf\xca\xc0\x76\xb6\xf1\x0f\xb4\x67\xa3\x51\x73\x39\x0c\x20\x08\x70\x53\xee\xd5\xef\x36\xdd\x08\xed\x61\xc5\x4f\x58\x59\x0c\x42\xc0\x40\xb8\xe3\x8f\xfb\x4e\x81\x2c\x81\x5e\xc7\x1c\x5a\xdb\xa4\x55\x6d\x4e\xce\x6c\x36\x6c\x02\x37\x1c\xb6\xf5\xbb\xe5\x80\xee\x75\xdb\x4d\x7d\xf4\xe3\x09\x53\x8b\xd3\xb6\xd9\xce\xe8\x11\x68\xa9\x6b\x86\x85\x73\x74\x9a\x07\xdb\x12\x41\x13\x21\xd4\x0e\x42\x11\x8c\xeb\x6e\xab\x72\x9d\xa1\xcd\xdd\x1b\x94\x0c\x82\xb2\xbe\xed\x92\x8a\xc4\x0e\x4c\xa5\x80\x6e\xac\xf6\x49\x0b\xe5\x12\x81\x42\x57\xe3\xcd\x12\x3b\xcf\x4e\xd9\x58\xf5\xbc\xfa\xa0\x26\xbe\x38\x6a\xc4\x02\x42\x34\xd6\xd5\x41\x39\xa4\x88\x5a\xa2\xa0\x54\xb7\xbf\x7c\x16\x8f\x1c\x7e\xa5\xe3\x31\x79\x10\x5e\x22\x8f\x43\xb0\xd8\x98\xa8\x49\x15\xab\x71\xb5\x2b\x81\xa6\xb1\x18\x6f\xc3\xcb\xf4\x34\x07\x9f\x91\x59\x8b\x10\xd5\x83\x39\xc6\xd0\x57\xd3\xd3\x71\x6b\x55\x68\xca\x63\x41\xc9\x5f\xb9\xa2\x85\x7c\x61\x97\x60\x47\xe9\xe1\x51\x33\xd7\x7d\xf2\x3a\xc7\xce\x17\xaf\x57\xcb\xf1\xab\xf9\x6d\x14\x2f\x2e\x1c\x34\xde\xfd\x0e\xfa\x49\xa6\x5a\x25\x7c\x9f\xd5\x74\x15\x32\xe1\x5e\xc2\xa1\x41\x9f\x98\x98\x9e\xa6\xb4\xeb\xf8\x13\x0e\x5c\x9f\xe2\x26\xfc\xca\x36\x76\x06\x84\x7f\xcb\xce\x6c\x3d\x8d\xef\xa3\x76\xbe\x6f\x81\x1a\x6f\xf9\xdf\x54\x65\x6f\x36\x29\x63\x73\x49\x74\x84\x45\x51\x8e\xcb\x83\x7b\xcb\x3f\x01\xaa\x00\xe5\x82\x91\xbc\x24\x43\xd9\x87\x6d\xa9\x7b\xff\x63\xd8\x5b\xc7\x29\xb9\x8f\x6e\xb4\x2e\x25\xa5\x9d\x85\x4a\x9e\xf7\x4f\x79\x63\x93\x79\xf4\x59\x7e\x49\x33\xca\xd8\xf6\x63\x67\xc1\x4b\x5e\x3a\x7a\x78\x7c\x25\xb4\xf2\x42\xf1\x92\xbc\xac\x24\x81\xa6\x29\x78\x02\x93\x54\xbf\xa6\x51\xae\x45\xa1\x16\x59\xea\x52\xe5\xa2\xe5\x0f\xc6\xe2\xe7\xd2\x8c\xf9\x29\x05\xb8\x57\xa5\xc6\xba\x82\xb8\x32\xcc\xfe\x45\xa0\xef\x77\x60\xf6\xb9\x37\x7c\xd6\x30\x02\x1b\x02\xa3\x82\xb8\xdc\x63\xdc\xa2\x12\xb6\xb1\x85\x02\xb4\xbc\xd4\xcf\x67\xac\xbe\xf7\x93\x06\x6d\xdb\x64\x4c\xc0\xb8\x49\x4b\x81\xd5\xec\x46\xf2\x05\x9a\x2b\x82\x9c\x03\x45\x00\xde\xda\x2d\x4a\x5b\x05\xe3\xb0\xe2\x08\x2d\x97\x9b\x66\x6d\x15\x96\x03\x94\x06\x53\x5a\x62\xd4\x95\xa3\xf6\xc7\xa9\x92\xd7\x6d\x33\x29\x06\x9c\x6e\x12\xf4\xff\x55\x05\xd4\x1e\x1e\xa6\xa1\x2a\xcc\xfa\xd8\x02\x47\xfb\x85\xd1\xc2\xfd\x3e\x2a\x4e\x44\xcc\x86\x3b\x05\x2e\x4b\x87\x6e\x1f\x02\xf1\xa9\xcb\xde\x66\x04\x23\x9b\x93\xa2\xbf\x17\x32\x30\xa8\xc3\x8f\xba\x6c\xbf\x44\xb3\xb1\x77\x0c\x24\x90\x35\x66\x2d\x79\x8d\xcd\xb5\x25\xd4\xd5\x1d\xb4\xa0\x76\xa9\x66\x8c\x16\x60\x2b\xd0\x3f\xa7\x8d\x81\x01\x4c\xf6\xae\x35\xd3\x84\xe8\x02\xc7\x60\x9b\xe6\xfd\xb1\x56\x2d\x4c\xa5\xdc\x2e\x0c\x42\x71\x03\xb6\x8d\x7e\x9a\x77\x3b\xe3\xd9\xa1\x77\x2c\x85\x0a\x78\x04\xaa\x9b\x31\xd2\xc9\x9b\x89\x75\x28\x39\x1c\x75\x79\x09\x8a\x6d\x76\x53\xcc\x05\x88\x90\xe9\x30\x1d\xa0\xdd\x31\xec\x8d\x71\x7f\xe7\xcc\x1e\x46\x60\x01\x6f\xe6\x96\xa9\x11\x78\x4e\x8f\x24\x2a\xb6\x8a\xfb\xf3\x30\x6e\xe4\x5c\xce\x9a\x9c\x9f\x0b\x7a\xec\x83\x1b\x83\xe5\x45\xcc\x1f\xe5\x90\x4e\x6f\x83\x1a\x1e\x1a\x1a\x18\x86\xe0\x67\x57\xed\x54\xbe\x3c\xc4\x95\x69\x18\xb3\xf9\x0e\x0b\xeb\xb7\x49\x23\x34\x20\x52\x8e\x6c\x94\x71\x17\x77\x4a\x3a\xdf\x2b\x50\x37\xa7\x98\xc3\x65\xb5\x02\xb3\xe0\x90\x8c\x04\xd7\xc1\x6f\xf9\x54\xd7\x9a\x85\x65\xcc\xfe\x04\xdd\x49\xe7\x3d\xb5\x04\x2b\x02\x11\x69\xb2\x23\x2a\x04\x70\x8c\x36\x84\x03\xf5\x6e\x37\xf3\x9c\xa7\xc7\xc8\xf1\xd6\x96\x67\x72\x71\xfd\xa1\x6c\x71\x1c\x20\x4b\x1e\x45\xab\xa1\xd9\x92\xf3\x65\x4b\xfc\xaa\xec\x86\xf0\xc7\x4d\x7c\xb5\xaa\x08\x7c\x9f\x7c\x1d\x6e\xb5\xa7\x03\x49\x7d\xb7\x3f\x56\x7e\xcd\xab\x69\x79\xa6\xd3\x38\x7f\xd6\xd1\xb2\xe6\x5c\xc5\x34\xfd\xe5\xac\xca\x71\x65\x60\x1c\x7d\x64\x80\x19\xdb\xa0\xad\x94\x03\x9a\x66\x11\x9e\x4a\x6e\x47\x08\x33\x2f\xe7\x56\x59\x6d\x9a\x87\x9b\xaf\xba\xf5\x7f\x18\x3b\xf3\xc2\xe4\x90\xe1\x73\x1e\x08\xee\x27\x5a\xd1\x93\xc5\xed\x69\x33\x41\xe2\xd7\xf4\xbc\x29\xdb\xcb\x87\x93\x10\xe5\x4b\x3f\xb9\xea\xde\xfe\xc8\x0b\x0e\xd0\x92\x7b\xe8\xaa\xde\xc7\x29\xa0\x56\x32\xda\x61\x40\x25\xf6\xf5\x08\xfc\xed\x70\x6a\xe8\x4c\x04\x82\x0d\xc4\x61\xec\x44\x3f\x89\x5e\x02\x64\x8f\xd0\xa7\xda\x82\xa1\x77\xdf\x20\xf9\xc5\xc7\x72\x0c\x07\xee\x79\xa2\xf3\x81\x03\x9d\xdc\x39\xca\x82\x5f\xe7\x9d\x82\x68\x0a\x7d\xb0\x53\xe5\xeb\xf6\x32\x35\x53\xe8\xe3\x57\xd4\xaf\x23\xd4\xe2\x15\xf7\xa8\xd6\xc8\xbc\x74\xa2\xa6\xd1\x70\x33\x4d\xe1\xc6\xac\xb4\x6f\xab\x51\x64\x27\x85\x9f\x71\x2f\x11\x7b\x39\xae\xb9\x87\x65\x87\x2e\xb5\x6d\x59\x87\xab\xe3\x37\x41\xb7\xab\xba\x7e\x8f\x9e\x6d\x95\x2c\xb5\x82\x9f\xc9\xbc\x3b\x1b\x87\xd5\x52\xa2\x84\xcf\xc5\x7a\x0d\x3d\x2a\xdd\xa0\x5d\x34\xf6\x94\xe1\x31\x9d\xfb\x95\x6e\x96\xec\xc0\x57\x14\x54\xb8\x77\x66\x5d\xca\x2d\xd1\x75\x17\xca\xa7\x39\xa7\xa7\xc2\x99\x52\xcb\x14\x9a\x35\x40\x3d\x03\x46\x48\x2a\x11\x6c\x06\x62\xbc\xd0\x48\x10\x22\x59\x36\xe5\xcd\xb9\x4a\x9a\xc5\xaa\x4c\xd3\x39\xd3\xb4\x2a\xe9\x63\xf2\x14\x94\x86\x2d\x41\x7d\x67\xe2\x88\x87\x7f\xfb\xa0\x2f\xc3\x1d\x43\x9b\x9c\x14\x78\xfd\x91\xaf\x72\xa9\x45\x58\xeb\x0f\x14\x74\xbb\xc6\xa2\xac\xd3\x2b\x39\x62\xef\x7b\xf1\x66\xe5\x25\xef\x80\x05\xb6\x73\xee\x38\xa6\x60\x50\x1b\xc2\x53\x04\xb1\x2c\x57\xc6\x44\x15\x03\x65\x1e\xaa\x4c\xb3\x52\x58\x0f\x7b\xdf\xb0\x1b\x90\x63\x4a\x5f\xee\x21\x9e\x5f\xc9\xea\x75\xff\xa6\xf4\x34\xaa\xe2\xa3\xc2\x1f\x8e\x64\x38\xe0\x91\x58\xd7\x7f\x16\xa9\x2d\x68\x5d\x35\xd3\xf6\xb7\x54\xe1\x61\x69\x3a\xb9\xcd\x40\x09\x3e\x33\x72\x6b\x5a\xea\xfc\x31\xe3\x83\xe1\x43\x39\x08\x15\x14\xc2\xeb\x15\xf4\xa0\xf8\x15\x49\x65\x32\x98\x60\x4f\xe0\xf3\xdd\x94\x15\xf2\x7c\x0f\xc8\x9e\x21\x54\xc6\x4e\x2d\x96\x71\x76\x95\xbb\xc2\xdf\x22\xf2\xc1\x9f\x6a\x1f\x00\x55\x8b\x4a\x84\x5d\xf3\xbb\xab\xaa\x5f\x46\x60\x67\x69\x2c\x2b\x9a\xb5\x21\x31\x8f\xce\xab\x46\x21\x4b\x1f\x71\x62\xbd\xe0\x59\x98\x81\x64\xeb\xf2\xa7\xca\xab\x2e\xd7\x3e\x03\xe1\x62\x63\xb5\x92\x78\x95\xe7\x99\xac\xaf\x22\xa3\xe3\xfa\xdc\xbe\xba\x08\xc2\x6f\x2b\x06\xbe\x6f\x41\xa2\x12\x59\x03\xa1\x5f\x91\x10\x4a\x96\x86\x60\x04\xab\x83\xed\x8d\x50\x56\x07\x48\x42\x83\xbb\x19\x26\xac\x4e\x33\xf3\xa9\x54\x66\xaa\x58\x25\x21\xca\x45\xae\xe2\x95\xfb\x63\x6a\x1b\xd5\xfc\x07\x37\x2f\xbb\xe0\x04\x8e\x5f\x94\x58\x48\x70\x88\x59\xcb\xf7\x5d\x2e\xbd\x24\x91\xa9\x21\x4f\x71\x3c\x4b\xea\xc1\x59\x64\x9a\x67\x7f\xda\x43\x9a\x68\x9a\x73\x23\x4a\xcb\x0b\x08\xdb\xf2\x23\x7c\x4c\x52\x38\x29\x05\x7d\xf5\x42\x2e\xdb\xea\x13\x12\x01\xbb\x84\x0c\xd0\xdd\x6c\x1d\x57\x01\x7d\xd5\xf6\xe2\x74\x38\x30\xa6\x6f\x27\x90\xf8\x90\x84\x4a\x4d\x27\x36\x58\xff\xa6\x6d\x2d\x28\xb0\xce\x56\xca\xd2\x7c\x3b\x4e\xfe\x63\x8c\x4c\xd5\x9c\x9b\xf4\xa5\x2a\xa0\x54\x49\x4f\x97\x5b\x33\x42\x36\x16\x18\xa6\x24\x97\x22\x24\xf4\x68\xcb\xa5\x46\x86\x8a\xa5\x02\xb8\xc2\xf4\xcb\x55\xf9\xa6\x32\x03\x2a\x01\x06\x80\x97\xa3\x1d\x40\x50\xad\xe1\x13\x18\xb2\x69\xc8\x31\x85\x3f\x4e\xe2\x28\xd3\x58\x56\xb9\xe4\x94\x2b\x8d\xcc\x28\x5b\x70\x0e\xb8\x6b\xdb\xaa\xc7\xce\x02\xdf\x95\x52\x3b\xc8\x08\x3c\xec\xb2\x34\xae\x2e\x79\xbd\x41\xbe\x94\x95\xf6\x4b\xaa\xea\xaf\xb2\xd0\x34\x10\x8c\x8a\x9e\xd5\xba\xbd\x6b\xf5\x58\x49\x3a\x23\x26\xe3\x26\x47\x4b\x45\xf6\x2f\xfa\xc5\x31\xb4\x6c\x9b\x74\xfa\xc2\x6b\x00\x2a\x13\xce\x8c\xf0\x31\x96\xf3\x81\x4d\xe9\x90\xdf\xff\xe3\x90\xa5\x76\x5c\x6a\xac\xed\x45\x00\xac\x80\xaf\xf6\xb0\x7c\xab\x34\x7b\x5b\xca\xff\x5d\x95\x4f\x5e\xa3\x9c\xe0\x97\xfe\xd7\xf4\x95\x13\x68\x2d\xcb\x50\x9e\x93\xe2\xcc\x61\x9a\xeb\x81\xd9\x72\x00\x90\x21\xf4\xff\xfc\x12\x88\xd3\x44\x26\x86\x06\xfb\xdb\x02\x9e\xef\xb2\x73\x85\xea\xdc\xdf\xc6\x80\x9d\xa8\xf8\xf6\xe3\x32\x74\xe4\x70\x3a\x96\x01\x0e\xaa\x5a\xd4\x37\xd6\xf3\x23\x67\x82\x3b\xa2\xd2\xae\xed\x51\x52\xca\xac\x9f\x0e\xe7\xfd\xae\x80\x09\xf9\x5d\x9b\x43\xf7\x1a\x26\x02\xbf\xea\x07\xd2\x5d\xb8\x2a\x33\xd6\x04\x34\x7b\x49\x63\x21\x75\xe1\x1f\xbc\x05\xfe\x1b\x00\x55\xdc\x94\x28\x0f\x29\xf9\x64\x7b\xbb\x29\x86\x39\x93\x36\x10\x27\x39\xa1\xbb\x6b\xc5\x82\x5a\x69\x97\xc3\x3a\x74\x47\x59\x73\x3a\x6d\x44\xc3\x5e\x51\xb4\x64\xf0\x81\xd6\x5b\x7b\x73\xa4\x34\x56\xae\x5e\xc0\xa8\x49\x55\x6c\x4f\xf6\x14\x5d\xce\x43\x57\x4c\xb5\x97\xe6\xfa\xb1\x65\x3e\x11\x46\xef\x8a\x9b\xbc\x4a\x60\x17\xa6\xc0\x28\x16\x7a\xf9\xa4\xcb\x55\x91\x0f\x4d\x80\x10\x2b\x2d\x55\x3d\x53\x1a\xf5\x16\x63\x64\xe3\x6b\xb6\x30\x86\x82\x0a\x5b\x28\x13\x05\x5e\x4d\x78\xb4\xc3\xb1\x34\x3c\xa4\x26\x94\x4a\xf6\xbf\x9f\x42\x52\x5e\xd6\x8f\x31\x41\x5a\xac\xae\x02\x25\x84\xe9\x0a\xa9\x3e\x5c\x0c\xd0\x77\x5f\x14\x05\x7a\xb0\xb3\xa8\xaa\xfb\xac\xfa\x5b\x43\x49\xe7\x71\xd2\x2b\xca\xce\xab\x5a\xa5\x13\x6d\x6e\xeb\xd0\x41\xce\x7b\x37\xba\xb5\x97\x60\x62\x1d\x5e\xd4\x12\x0c\x9a\x25\xdd\x66\x72\x20\xf4\x1b\x74\x1d\xa2\xda\xc6\xa7\x45\xff\x8a\x3d\x48\xaf\x04\xc8\x2b\x28\x2e\x8f\x54\xe3\xdf\x9b\xed\x44\x2e\xed\xe8\x03\x56\x8c\x78\xea\x55\x62\xe5\xe5\x32\x7c\xf7\x9c\xf0\x4a\x29\x75\x87\x63\x56\xff\x04\x28\x33\x01\xf8\x89\xb6\xa9\x49\xe7\x2b\xba\x45\x50\x78\xd8\xea\x10\x89\x7c\x44\xd6\xee\x16\x9a\x70\xf2\xea\x89\x8e\xb4\x29\x03\x99\x9f\xe7\x1a\xd7\x38\x30\x12\x23\x59\x4f\x9c\x4b\x32\x55\xf1\xff\x83\x88\xb9\x43\xb4\xc9\x01\xbc\x71\x26\xd0\xc6\x06\x02\x0a\xc7\xe6\x83\x78\x9f\x9e\x4a\x8f\xe5\x9a\xd4\xaa\x1b\x2f\xcf\xeb\x92\xa7\xda\xd7\x8a\x0d\x74\xc5\x45\xa2\x9e\x9a\xfc\xb6\x04\x5a\x36\x0d\x20\x87\x39\x61\x39\x8d\xab\x78\x2c\xe0\xa5\xda\x87\xf0\xc2\x84\x67\x2d\x47\x9c\xe9\x0d\xfa\x45\x80\xfc\x3e\x1a\x49\x97\xc8\xce\x58\xd8\xe9\xa4\x53\x55\xde\x2a\x1b\xea\x62\x5d\x3d\x59\xac\xb3\x7c\xcd\xab\xf0\x21\xfe\x02\x65\x8a\xc5\x27\x1c\xed\x2d\x8a\x45\xac\xad\x92\x5e\x24\xd2\x6e\x62\xbe\x07\x9a\x4b\x71\x99\x36\x49\xcc\x2e\x1d\xc2\x84\xc8\x03\x6a\x03\x41\x3d\x54\xc1\x75\x0d\xdb\x8a\x93\xb3\xda\xb5\x66\xc3\x24\xc4\x3a\xd1\xc5\x21\x51\xd2\x16\x75\x5c\x79\x25\xdd\x9c\xf6\xa2\xab\x1b\x34\x82\xe0\x0d\xfb\x0e\x00\x33\x6e\x44\x20\x27\x16\x95\x60\x83\xb2\x7a\xb4\xe1\x8e\xfc\x57\x8d\x15\x4c\x0e\x2a\xd7\x20\xba\xd3\xd8\x0f\xe5\xec\x3f\x6d\x25\x40\x2d\xcb\x52\xe4\xeb\xdf\xf0\x2c\xfc\x6c\x6a\xde\xcd\x2e\x6c\x0a\x31\xc7\x1d\xba\xcf\xea\x10\x40\xd0\xc9\x61\x9d\xe2\xe9\xba\x5c\xf7\x92\x1c\x9e\x3c\x6b\xf6\x3c\x50\x20\x1a\x94\x27\xfe\xa4\xec\xf3\xc3\x68\xc6\xda\x43\x18\xaa\x0e\x2d\xec\x70\x2f\xef\xa8\x93\x17\x02\xf2\x95\xe8\xb4\x5a\x07\x08\x8c\x44\xdc\x8c\x73\x23\xc1\x9f\x4d\x1a\x34\x14\xab\x52\x96\x2c\xd4\xb3\x96\xe3\x34\x46\x1f\xc0\x0a\x40\xb7\xaf\x7e\x2b\xd7\x83\xca\x32\x70\x17\xa7\xa9\x26\xce\x5b\x72\x5b\xb0\x7c\xdc\x4b\xe0\x21\x89\x7d\xaa\xc8\x23\xb0\x81\x83\xaf\x50\x8a\x2d\xb1\x99\xf3\xba\x8f\x52\x5c\x87\x22\xd1\xee\xba\x90\xb4\xbf\xca\xb2\x02\x6e\xb7\x5c\x93\xe7\x51\x01\x47\x86\x15\xdd\xfe\x57\x15\xac\xa3\x13\x7b\xf8\x28\x41\x73\xf6\x4b\x9e\xcc\xba\xa7\x58\x91\x0e\x8e\xbf\x00\x1e\xaa\x93\x1c\x89\xd9\xae\xe5\x63\x34\xf3\xd0\xf0\x4d\xc7\x89\xdb\x10\xfd\xc3\xe5\x32\x1a\xe8\x59\xe9\xf7\xcb\x5f\xf2\x3c\xfe\xad\x92\xbe\x78\xf5\x24\xca\x24\xfb\xbf\xed\x03\xfd\x38\x9f\x14\xdb\x8e\x06\xb1\xd9\x5b\x81\x6f\xf6\xfe\x9a\x65\x56\x32\x31\x1f\x28\x19\xee\x6a\xc1\x02\x60\xb5\x6d\xa8\x60\x69\x1b\xa3\x93\x60\xcc\x6b\x2d\x90\xc0\x90\x3e\x7b\x31\x51\x7e\xe4\xd2\x86\x41\xef\x65\xd1\x66\x9f\x26\x61\x35\x2b\x2d\x8c\x77\xfc\x14\xad\xb9\x2c\x69\x72\xef\x51\xd6\x48\x9f\x83\x98\xe3\x41\xc0\xb3\x5f\x42\xdf\x1b\xdf\x40\x49\xad\x79\xe1\x5a\x72\x6f\x13\x2f\xd8\xd4\x6d\x4a\xe8\x29\xd8\x97\x1f\x65\xa5\x41\xe5\x68\x3e\x35\x62\x84\xa6\x7d\x30\xb8\xb7\x14\x76\xa1\xa2\x71\x56\x50\x25\xd0\xda\xbb\xb9\xae\xf0\x32\x77\x3e\xf9\xe0\x1f\x79\xdf\x2e\x2b\xb9\x03\x4d\xfe\x6a\x0e\x36\x2a\xbc\x86\xa3\x31\xd7\xec\x5d\xf2\xc7\x62\x16\xdf\x78\xd6\x18\xa8\xbd\x7f\x09\x23\x02\x2e\x56\x01\xd8\x04\x37\x8d\x71\x66\xa5\xb7\x30\x13\x5d\x7a\x99\xf3\x1d\x58\x8f\xce\xc5\x7a\xe7\x91\x6a\x97\xe6\x5d\x87\xc0\xb9\x55\x53\xa7\xed\xf8\x04\x1e\xd4\x52\x7d\x71\xfa\x34\xe7\xfe\xc5\xd9\xe8\x2f\x5a\x19\xc8\x1c\x96\x61\xe2\x9d\x87\x1f\xbe\x39\x19\xbf\xfd\x4f\x52\x60\xba\x6e\xcb\x39\x93\xad\x25\x91\xb6\x58\x58\x3a\xd9\xf0\xa8\x79\x8d\x9e\xef\x68\x6e\x22\x3d\x5b\x74\xe8\x94\x77\x07\x2c\xd0\xcd\x79\xf9\x1e\x0b\x5b\x49\x99\x5f\xd0\xa0\x2d\xe5\x43\x09\x99\x8e\x5f\x10\x03\x24\xe5\xec\x10\xf5\xba\xfb\xa8\x28\x19\xfc\x13\xe9\x38\xbb\xde\x54\x35\xb7\x04\x4b\xc9\xb5\x1f\x01\xaa\xe2\xd4\xd1\x24\x92\x08\x9f\x49\x8e\x95\x58\xdd\x1f\x88\xaa\xbb\x68\x10\xe5\x25\x96\x72\x4a\xf6\xee\xe3\x51\x91\x82\x6f\x00\xaa\x38\x96\x07\xfc\xf4\x6a\x1b\x81\x6d\x12\xb8\x8a\xb2\xbd\x85\xf4\x7b\x63\x50\xc6\x53\x8c\x0a\x85\x42\x04\xbd\xf2\x1c\xd4\xd0\x97\xae\x54\xbe\x3f\xbd\xdc\x59\x9d\x15\xce\x65\xad\xbc\x8d\x13\x32\xf5\x50\xcb\x94\x49\x51\x17\x63\xbe\xd0\x43\x22\x56\x49\x27\x8e\x9c\x77\xb5\x73\x8e\xcc\x91\xe3\x31\x5e\xfd\x14\xb0\xe5\x66\xad\xdc\x0c\x39\xe1\xde\xa1\x43\x44\x62\x85\x7d\xdc\x89\xc1\x5f\x2d\x0e\x82\x7f\xcc\xb2\x5d\x3f\x0c\x0f\x8e\xc3\x62\xb4\xac\x1a\x36\x4d\x30\x29\x00\x66\xb0\x7e\xf8\xae\xf7\xb7\x0a\x0e\x8b\xb6\x77\x3d\x53\xf7\xe7\x68\x11\x57\x68\x67\x66\xdf\xea\x94\x1a\x48\x9a\xe6\x4a\xb2\x19\x35\x43\xda\xfb\x5e\xc2\x8b\xed\x00\x8d\x68\xbe\xe4\x9f\x18\xb2\x6d\x62\x90\xd3\x6c\xc4\x0f\x2c\xc4\x2f\x54\xdb\xf6\x57\xb4\x80\xfe\x19\xce\x84\xb1\x30\x97\xab\xd1\x63\x4b\xb4\x69\x60\xf6\x9e\x89\x2e\xb0\xed\xbb\x99\x77\x7d\x38\x8a\x97\x53\xeb\x99\x2b\x71\xc6\x43\xe8\x1b\xfb\x43\x5d\x28\x47\xcd\x1a\x64\x3b\x12\x58\x3b\xfe\x7a\x60\x3d\xcb\x75\xf0\x6b\x15\x1d\x11\x16\xae\x16\x52\x9c\x7b\x6c\xd0\x63\x2d\xf0\x70\xb9\x41\xdf\xc7\x23\xc5\x72\xb0\x3e\xad\x3a\x95\x30\x69\xe4\x39\xd6\x07\x56\x75\x25\x52\x47\x87\x6c\x59\x4b\xab\x82\xeb\xb4\x6b\xb3\xf3\x30\xe3\xf5\x59\x56\x34\xcb\xc0\x92\x96\x13\x10\x7e\xf4\x51\x74\x06\x98\x71\xae\xbd\x89\x12\xd3\xf0\x65\xeb\x00\x1a\x21\xff\x75\x88\x4f\x04\xa7\xe2\xcd\x13\x41\x74\x36\xcb\x93\xaa\x1a\x9c\x1c\x10\x82\x9a\x0c\xde\xa0\xcf\xaf\x07\x59\x49\xae\x81\x56\x3b\xf5\x4e\x30\x1a\xaa\x06\xf7\xf9\xc2\xd3\x65\xdd\xd4\x1e\xd4\x04\x71\x74\x8f\x31\x0f\x1b\x5c\x4c\x4e\x0b\x27\xc3\xcf\x9f\xe5\x92\xc0\xa7\xf8\x93\x87\x65\xb1\xe5\x59\x1f\x2b\x1c\x52\x63\x7b\xd1\x94\x45\x39\x68\xc5\xfc\x51\xef\x89\x64\x93\x41\xc6\x99\x30\xe5\x65\xcb\x89\xf0\x16\x35\x9f\x00\xa2\x97\x45\x22\xef\x7e\xe1\x5f\x4b\xa5\x7a\x36\xa1\x44\x89\xe5\x4d\xcd\x2a\x77\xaa\x1a\x1c\xac\x37\x76\xa7\x96\x60\x2c\x04\xef\x15\x4b\xdd\x8c\xee\x5b\xe9\x10\xe3\x11\x5e\xce\x32\xb2\xcc\xd9\xc3\x52\x97\xea\x13\x13\x4f\x78\x04\x86\x86\xdb\xbd\x5c\xcf\x54\x2f\x91\xea\x29\xe6\x10\xfd\x66\x9a\xd2\x08\xa1\xd0\xb7\x6d\xfb\x35\x0c\x05\xd0\x08\xd7\x56\x68\xcc\xd6\x23\x90\xa7\xde\x8a\x14\x07\x9b\xc4\xf5\x7d\x3f\xb0\xff\xff\x78\x2c\x99\x27\x20\x1a\x1a\x46\xfd\xa6\x7b\x30\xa1\x8d\xd1\x4b\x9a\x88\x52\x93\x57\x75\x17\x30\x2c\xec\xf4\xff\x49\x9b\xf9\xd0\x59\x83\x8f\x36\x33\x25\x51\xb3\x69\x0b\xd3\xfb\x96\x2e\x17\x37\xb7\xa9\x30\xc5\xaf\x78\xdf\x12\xe1\x42\xef\x00\x6a\x7f\x31\xfd\x6c\xcd\x6f\x74\x3f\x27\x87\x83\x68\x6b\x3e\x51\x39\xec\x64\x7a\x8f\x1a\xaa\x3f\x82\x46\x6e\x2c\x4c\x43\xe8\xb2\xc3\x1f\x95\x7b\x7d\xc2\x69\x4b\x35\x17\xe4\xb9\x51\x01\x93\x90\xbb\x72\x78\x09\xb0\x9e\x0a\xa5\xe9\x2c\xdf\xa6\xe8\x0e\x93\x9c\x7e\x21\x8e\xf4\x70\xd2\x5e\xb2\xd7\xc3\xc3\x83\xd4\xbd\x82\x47\x52\x96\xe8\x87\x59\x6f\x1a\x83\x5d\xc9\x2b\xd5\xa2\xcb\xa5\x96\xa1\xc3\xcd\x1e\x1a\xc1\x29\xf1\x0b\x79\x97\x8f\x4c\xe7\x99\xa4\x36\x65\xa5\x68\xdb\x4f\x24\xd2\x15\x3c\x7b\xae\x8d\x6c\x41\xce\xe5\x7b\xe4\x5b\x0e\x1b\x15\x3d\x55\xe1\x1a\xa9\xae\x35\x2f\x8e\xa8\x73\x0f\x93\x26\x34\x33\xc0\x9f\xe1\xae\x3f\xaa\x0c\x23\x52\x22\x29\xb3\xf6\x9f\x60\x91\x47\x30\xa5\x41\x85\x4f\x9a\x7a\xce\x21\x00\x86\x0e\xd6\xf2\x90\x7e\x0c\xc2\x75\xdc\xe2\x38\x51\x5f\x6a\x4d\xd2\xde\x54\x33\x73\x27\xf2\x4c\x8b\xe4\x5e\x23\x1a\x56\x84\xa5\x0c\x15\x30\x12\x56\x5f\x7b\x15\x58\xea\x7b\x9a\x72\xb3\x30\x62\x94\x7d\x4b\x72\x83\x1b\x50\xc7\x02\x15\xf0\xaf\x29\x40\x77\x86\x05\xab\x37\x55\x39\x04\xce\x2f\x8d\x7e\x54\x32\x00\x84\x5e\xc0\xcc\xcd\x56\x38\xb8\x30\xf0\x7d\x00\x40\xc3\xaa\x62\xef\xcf\x4e\xd6\x20\x99\x72\xc7\x26\x47\x6c\xd1\x38\xc7\xb9\x8a\xaa\x63\x8a\x02\xe8\x08\xac\xc6\x0a\x8e\x87\xbd\x41\xca\xd7\x23\x1d\xfa\x21\x1f\x6a\x61\x7b\xa2\x70\xdd\x17\xec\xf9\xbb\xee\xe1\x13\xa2\x27\xb5\x86\xa0\x37\x32\x65\x7c\x00\xa2\x52\x6c\xe3\x63\x74\x07\xa9\x7c\x6b\xd9\x96\xd3\x4b\xff\xde\xd5\x84\xba\x7d\x35\xc9\x74\x32\xc0\x5e\xd1\x34\xb1\xab\xd3\x5f\x96\xbd\x92\xcc\xb9\x47\x82\x19\xe8\xc1\x0f\xb4\x48\x74\x7d\x93\xc2\x19\x3a\x14\x5b\xb6\x35\x70\x5b\x75\xa8\x27\xb8\x3a\xdf\x28\xdf\x76\x23\x62\xc5\x17\x54\x65\x58\xf0\x59\x4f\x5e\x12\x3f\xa7\x80\xcf\x6a\x0b\x5f\x42\x52\xc1\x33\x93\xc4\x82\xeb\x95\x9f\xb3\x0a\xf4\x8e\xf3\x5a\x8d\x61\x87\x88\xbe\x97\x5e\xb7\x43\xb5\xa1\xb9\x83\x8f\x94\xc7\xe4\xce\xf8\xc3\x5a\x3b\x40\x0f\xfd\xb2\x92\xb0\xa8\x4d\x39\x55\x56\xf7\xbc\x4e\x8b\x79\x9b\x1f\x46\x38\xdf\xae\x79\xaf\x86\x02\x2b\x22\xe4\x43\x30\xbf\x07\x7d\x77\xf8\x37\x58\x01\x2e\xd4\x5a\x7b\xe0\x56\x07\x87\xec\xae\x6a\x80\x77\x15\x07\xd4\x6d\x31\xef\xef\x72\x4c\xa1\xbb\xcb\x16\x40\x98\xaa\xea\xbd\xa5\xa6\x18\xf9\x23\x5d\xfa\x20\x7a\xb3\x33\xf5\x51\x65\x53\x8e\x7f\x9b\xa8\x6c\x67\x28\x91\xb5\x61\xfe\x2c\xb8\x8a\x56\xaf\xd0\x4e\xb3\xd6\x69\x44\xe5\x8a\xb4\x8a\x10\xec\x8c\xcd\x00\x6e\x67\x09\x6d\xd6\x63\xed\x73\xf5\x80\xc0\x1e\xae\x2d\x7d\x47\x93\x1e\x2b\xf9\x15\x47\xad\xb7\xff\xd9\x41\xf2\x5f\xd6\xf9\x3b\xeb\xf3\x6a\x36\xf5\xa2\x81\x46\x51\xd0\x6c\xe4\x18\x51\x82\xb5\x41\x8a\x30\xfd\x53\xf5\xb0\x45\xad\x11\x23\x48\x75\xbc\xb4\xdc\x77\x8b\x8e\x04\xfc\x4f\x8f\x36\x54\x13\xbe\x51\xf7\xee\xa3\x1b\x87\x8d\x72\x86\xdd\x48\x5b\x1f\xb2\xf3\x8a\xf4\x94\x87\xcc\xb6\x46\x63\x16\x8a\x1a\x53\x35\x4b\xb1\xd2\xaa\x52\xef\xf7\xa5\x48\xf9\x1e\x3e\x7f\x36\x23\x06\x27\xdb\x97\xc2\xa7\x92\x2f\xfa\x42\x45\xf7\x69\x5c\x67\x8c\xe8\xd7\x28\x2c\x52\x07\xbd\x92\xfb\x8d\x68\xe1\x0a\x5e\xd7\x6d\x10\xdc\x8f\x37\x0e\x00\xa9\xc1\x94\x02\x78\xc1\xc4\xf4\xc6\xa0\x1e\xf6\x97\xcb\x1e\x7d\xb2\xc3\x73\x0e\x68\xe6\xf5\x6e\x61\x45\xba\xae\x66\x96\x13\x7c\x2a\x22\x13\xdc\xb8\x0b\x50\x5c\x6a\x6b\xfa\x5a\x96\x58\x3e\xee\xe9\x72\x01\x74\x84\x07\x7f\x5c\xa3\xb7\x72\x9a\x95\x0f\x2c\x14\x62\xa1\xd8\xef\x22\x63\xcd\x55\x9b\xa7\x5c\x17\x81\x62\xb4\x4f\x37\x1f\x5e\xc2\xf5\x69\xb9\xb8\xf4\xec\x65\xc4\x01\xb9\x57\x64\xd7\x8e\x71\xa2\x7b\x5c\xe3\xf4\xa2\xcd\x95\x06\x1b\xa3\x85\x65\xab\x5a\x28\x00\x87\xeb\x14\x12\x7c\x67\xe3\x85\x2b\x25\x50\x26\x93\x08\xbf\x6b\x34\xea\xfd\xa4\x2d\xc7\x28\x09\x36\xfe\xb1\xba\x57\x4d\xcd\xaa\x83\x89\x39\x05\xfb\x7d\x31\xe8\x10\x23\xbe\x54\x11\xf2\x29\x92\x6e\x90\x16\x98\x43\xeb\x7d\x6f\xc9\x54\xe2\xd4\x59\x92\x80\x40\xc4\xf0\xd8\xde\x07\x2b\xa3\xac\x12\xc1\x58\xa7\x6b\xd8\xe0\xf0\x3f\xee\x81\x34\x0f\x4d\xbe\x95\x3a\x7e\x21\xe7\xb1\x72\xe0\xac\xd7\xbb\x82\x72\x79\x4f\x31\xb4\xc7\xc4\x3a\x96\xb0\x38\xe1\xcc\x64\x84\x02\x87\xe7\x23\xf1\x35\x2c\x29\xec\xba\x31\xf1\xb2\x1d\xc3\x26\xd5\x4e\xd2\x49\xb9\xca\x96\xff\xb8\x1a\xe5\x73\xee\x02\x04\x3f\xd7\x5e\x70\xa9\x28\xdc\xaf\x4d\x55\x43\x8b\xde\xcd\x29\x7a\x61\x6d\xed\x8a\x39\xb5\xac\x4e\xf3\x59\x80\x9d\xe9\x7e\xc5\xfa\x49\x0c\xf1\x69\x0c\x26\x5e\x25\x9e\x4e\x69\xd5\x40\x45\xdd\xaa\xe7\xf8\x4a\x42\xb1\x1b\x5f\x23\x21\x42\xe9\xce\xc1\xc6\x77\xab\xd0\x6d\x40\x1f\x6d\x40\x60\xf4\x3a\x62\x5d\x8c\x52\xa6\x4e\x28\xf5\x51\xdd\xa6\xc1\xa6\x11\x32\x8b\x70\x8d\x60\x43\x63\xcb\xef\xab\x58\x48\x1d\xc4\x56\xf4\x3b\x9c\x68\xd7\xaa\xa0\x7c\x1e\x0e\x3a\x0f\x42\x50\x05\x2c\xa5\xf6\x48\xd8\x23\x62\x38\x13\xe8\xb6\x47\xf8\x1d\x82\xb2\x63\x04\xff\x23\x9d\x8c\x1a\x0f\x8c\x17\x38\xc4\x61\x6b\xdf\xee\x30\x1e\x80\x8f\x25\xd8\xe8\x4c\x07\xb6\x68\x72\x26\x8c\xb5\x2b\x0d\x9f\xfe\x16\xc4\xf3\x83\xfd\xa9\x59\xf8\xb6\x25\x0b\x97\x9c\x93\x8d\x24\xcb\x17\xbd\x47\x87\x55\xba\xa7\x25\x03\x1c\x5b\x4b\x0b\xbb\xe6\xb8\x71\x34\x9e\x14\xa5\xc1\x13\x8b\x81\x37\xdc\x23\x3d\xa5\x21\xd5\x47\x83\xee\x35\xc4\xbd\xe1\x76\x1f\xca\x93\x5d\x4f\xa5\x6c\xaf\xc1\x0c\x5f\xfc\x9b\x08\xc9\x30\x2d\xf6\xd9\x58\xea\x63\xb2\x09\xcf\x70\x02\x6d\x31\xf4\x14\x66\xb8\x75\x6b\x41\x06\x7d\x5e\x95\x53\xed\xe3\xa6\x53\x2b\xf7\x26\x61\x2f\xbf\xe8\x41\x38\xe7\x2c\xc1\xbf\xfa\x88\xe3\x81\x17\x03\x72\xf3\xb1\xe9\x33\x89\xee\x6c\x23\x16\xe3\xd0\xdf\xdd\x63\x2b\x6f\x25\x6b\xb5\xe5\x0a\xdd\x85\x4a\xeb\xe9\xf1\x78\x08\x3d\x94\xb3\x45\xfe\xec\x7b\x93\x05\x7a\x37\x16\x13\xb4\x46\x75\xd9\x44\x09\x6d\xc6\x0b\xe1\x80\x09\x8f\x58\xb5\xf6\xbf\x54\x9b\x6d\xb7\x00\x1f\x99\xda\x8a\xf1\x89\x51\x64\xd4\xb9\xf6\x30\x4c\xa6\xc2\x97\x3c\xcd\xe1\xa1\xfd\x9b\x7c\x8c\x7d\xb2\x95\x68\x3f\x89\xc1\xac\x5c\xa7\xb3\xfb\xcf\x14\x63\x14\xda\x3d\xa8\x87\xec\x10\xf1\xf5\xcb\x3d\xf8\x2e\x73\x25\xb6\x9a\x8d\x33\x17\x8a\x7e\x1d\x55\x64\xe5\xad\x36\xe3\xf1\xd2\x79\x24\x73\x62\x1c\x64\x8a\x7b\xc0\xc7\xe0\xc6\x9c\xeb\x23\xdf\x31\x31\x0b\xa1\x57\xd5\x24\xa6\x2d\x25\x15\x1e\x70\xd1\x51\x97\x8c\x78\x22\x2f\xfb\xad\x91\x72\x00\xa5\xc9\x3f\x3e\xd3\xa2\x1f\x75\xc8\x4c\x4a\x14\xee\xa3\x5f\x77\x9b\x3f\x33\x42\x61\xb5\xb3\x0e\xbb\xca\x16\x9d\x63\xc9\x06\x66\x7b\x3e\x21\x0e\x60\x79\xba\x76\xcc\xab\xd8\x28\x7b\x08\x54\xed\x93\xcf\x43\xd3\xc3\x55\xd3\x8c\x55\x07\x90\x23\x1b\x75\xc6\xca\xde\xd7\x3c\x1e\xc7\xa5\x88\x4f\x13\x8a\x7c\x03\x4b\x78\x74\x99\xd2\x42\x7c\xe7\x28\xff\x72\x62\x3c\xba\x68\x93\xed\xba\x4d\x82\x50\x22\x87\xe4\x4d\xd3\x84\xb9\x4f\x08\x6f\x40\x4f\x7d\x33\xe4\x73\x4a\x7f\x2f\x0e\xe6\x45\xe7\xe4\xb7\xfa\x5b\x7f\x72\x79\xbe\x28\x5d\xb8\xb1\x08\x12\x16\x14\x61\x91\x0a\x95\x06\x8a\x5b\x91\xf6\x6a\x7e\x9d\x62\xf3\x93\x53\xee\xb9\x4c\xde\x03\x3f\x9a\x5d\x0f\x4d\x95\x22\x5d\x5e\xdf\x8f\x55\x67\xbb\x5a\x08\xa9\x37\x76\xbf\x07\xc1\xfc\x72\x40\xe8\x6d\xe5\x65\x9d\xd4\xf2\x2d\x1d\x9f\x41\x4a\x56\x40\x09\xa8\x20\x3a\x43\x15\xca\x8a\x7c\xb5\xc2\xab\x9e\x39\xbc\x93\x07\xf5\xce\xca\x99\x62\x4c\x01\xd0\x76\x26\x43\x2c\x71\x66\x01\x88\xc5\xab\xcf\x56\x2a\x3a\xa7\x96\x46\x3a\x7e\x9a\xd5\x95\xdb\x21\x2c\x55\xe0\x1c\xa6\x24\x0f\x62\xb3\xbc\x59\xca\x35\xa3\x48\x5f\xd6\xcb\x38\x24\x01\x0c\xb6\x6b\x42\x54\xaa\x8b\xf9\xa3\x75\xe0\x07\xf2\x07\x3a\x0b\x96\xe1\x8d\x41\x80\xf3\xa2\x29\x7d\x34\x8d\x40\x59\x83\x2d\x04\xa1\xe6\xb0\xba\xfc\xc9\xfb\x10\xc8\x7f\x16\x2d\x16\xe8\xc0\x6b\xd8\x4e\xf2\x80\x4a\x7b\x54\x5a\x8e\xc2\x23\x53\x4f\xb4\xa3\xc2\xba\x65\xcd\x47\x08\x02\x22\x23\x48\x95\xd4\x55\x4d\xcb\xc7\x40\xbe\x6e\xb6\x2c\xb6\x0c\xe8\x45\x3c\x46\x7b\x21\x78\x03\xae\xd0\x7c\xd4\x96\x77\x8e\xf0\xad\x3e\xda\x67\xdd\xad\xc7\x7d\xa6\x12\x31\x15\x83\x1e\x80\x02\x48\x10\x04\x9c\xae\x89\xf3\xd2\x47\x06\x30\x50\x07\x64\xd9\xc3\xab\x4c\x2e\x65\x0a\x19\x99\x43\x52\xf3\x6c\x9a\x67\xd7\x83\x3c\xdf\x1e\x89\x7a\x2e\xf7\xbe\x37\x6f\xeb\xd3\x87\x72\x23\x35\x7d\x62\x08\xa4\x8f\x61\xae\x33\xcc\x7e\xf9\xcd\x9e\x29\x75\xc0\xf8\x06\xeb\x75\xf9\x82\x44\xf5\x32\xdf\x17\x1d\xbf\x3b\xeb\xb8\x8e\x6a\x55\xe6\x17\x40\xdd\xdc\x1b\xbd\x14\x75\x40\x6f\x4f\x01\x81\x18\x4b\x30\x73\xdf\x8c\xfe\x33\x31\x73\x90\x00\x58\xb6\xb5\xcc\xa5\x23\x59\x0e\xd2\x2c\xd8\xed\xbd\x0e\x8c\x88\x86\xd0\xad\xaf\x7e\x30\xd0\x82\xcd\x4f\xfd\xc4\x1b\xcb\x43\xcf\x28\x5a\x02\xdf\x19\x61\x00\x2b\xd3\xe6\xa5\x2e\x51\xf4\xf2\x72\x4c\xaf\x28\x70\x78\xf3\x71\xb9\x54\x08\x05\xb9\x8f\x7a\x73\xc4\x94\x39\xcd\xc1\x61\x2e\x72\x1d\x1d\x6c\x46\x03\x29\x36\x48\x5d\x3c\xfb\x7f\xee\x70\x9d\x23\x5c\xb4\x09\x66\x1a\x3a\xe1\x18\xbd\x5b\x06\x1d\x96\x89\x2e\xfe\x72\xb8\x88\x80\xd9\x7f\xe8\x16\x97\x01\xdb\x82\xa0\x3b\x1b\x59\x56\x0e\x45\x08\xe0\xd8\x13\x07\x79\xf9\xa0\xc2\xa6\xa1\x74\x40\x2c\x78\xbb\xc1\xc9\x80\xab\xe5\x27\xeb\x56\xc3\x27\xfa\x5e\xe9\xbc\x6d\x4c\x29\x7b\x8b\xe5\x45\xa3\xe9\xb0\x67\x07\x18\x2e\x85\xbe\x7a\x0e\x75\xd5\xf2\xe3\x26\x44\xe6\x89\x26\x33\x67\x2c\xfa\x82\x91\xbd\xff\x6b\xde\x8b\x67\x7f\x92\x8d\x06\x34\xad\x51\xf1\x89\xa4\x7a\xb2\x46\xda\x68\x1d\x16\x80\x2d\x24\xb8\x34\x1d\xce\xd3\xc2\x0a\x3e\xc6\x59\x2c\x42\xc5\x5a\x1b\xb9\x7d\xc2\xac\xe7\xc6\x76\xe2\x45\x53\x00\xfe\x78\x32\xee\x1d\x0a\x79\xab\xd3\x3c\xe0\x30\x21\xe0\xa5\x32\xd5\x84\x26\x34\xfd\x0c\xc7\x48\xe2\x51\x09\xff\x86\xb3\x7f\x0c\xe4\xef\x66\xd5\x0b\x9f\xc6\x3a\x73\xb7\xb1\x02\xdb\xb6\xe6\x6c\xc3\x08\x18\x38\x1d\xad\xa6\x90\x2f\xa8\xe6\xf2\x47\x12\x78\xc2\xb4\x94\x7d\x39\x55\xbb\x2e\xa5\x36\x90\x9c\x81\x8e\x46\x89\x36\xc7\x91\x0b\x06\xb2\x64\x9f\xbe\x2d\xa7\xc5\xab\x48\x61\x45\x8c\x5e\x89\x94\x19\x80\x42\x82\x07\x2c\x4f\xe7\xf0\xda\x2f\x0b\x69\x74\xef\x3e\xe9\x37\xc8\xcf\x51\x8f\x64\xcb\xbf\x96\x8d\xca\x6c\x66\x5b\x38\x2a\x60\x6a\x98\x5d\x65\xb7\x00\x01\xaf\x08\xce\xe5\x57\x93\xf2\xa6\x53\x79\xb5\x28\x0c\x8c\xc3\xfc\x74\xb7\x25\xe3\x1c\xde\x57\x98\x27\x4b\x0e\x26\xa4\x5d\x60\x5b\x7c\xd9\x61\x82\x5e\x35\xab\x23\x89\x53\xd8\xad\x1a\xc1\xc8\xd3\x97\x39\xbe\x67\x52\x9e\x46\x29\xf2\xe1\x40\xb6\x78\xcb\x18\x20\xb6\xd5\x73\xf3\x92\x10\xa5\x4a\x79\xf3\x57\x8f\x03\xb7\x1a\x90\x21\x93\xd3\x89\x8b\x0c\x65\xea\x09\xbe\x89\x1a\x54\xe7\x6d\x2d\xad\x16\xf3\xe8\x97\xbb\xcf\x52\x88\x5d\xf1\x63\x88\x35\xeb\x95\xa5\xca\x56\xcd\xe7\x11\x35\xd1\x7c\xb6\x83\xca\xd0\xd3\xbb\x77\xa6\x06\xab\x5b\x98\x18\x39\x08\x89\x35\xc3\x04\xe5\x46\x14\xdf\xe1\xa3\xf5\xe8\xc3\xc5\x3c\xa8\x71\x17\x74\xaf\xde\x4f\x8f\xaa\x18\x33\x85\x8f\x28\xef\x8d\x44\x8d\xc5\x58\xeb\x6d\xab\xb4\xb1\x62\xfb\xa7\x1c\xc8\x3e\x9c\x73\xf1\x20\x3e\x5b\x0d\xc0\x38\x8b\xbc\x99\x66\x8d\x47\x9e\x06\x52\x3f\x93\xb8\xe8\x3e\xb8\xab\x60\xc1\xcf\xb9\x31\x2c\x7c\x35\x3c\x7f\xce\xc9\x73\xf1\x1f\xb9\x90\x61\x2e\x16\x86\x0d\x3f\x08\x06\x77\x09\x9f\xfe\x44\x3f\x26\x20\x20\x37\xfb\x8e\x86\xb0\xc4\xf2\x8d\x5e\x1a\x69\xcb\x5c\x19\xdc\xf7\xb0\x9a\xfe\xc2\xd6\x52\x94\x7b\x5e\x0f\x64\xe5\x21\x67\x3a\xcc\xf3\x2c\x0d\x9b\xfb\xe1\x7a\xb5\xec\x00\x16\xa5\xd4\x98\xe0\x2f\x3e\x3a\x22\xb6\x59\xa6\xdc\x58\x9c\x72\xc6\xc6\x02\xf3\x12\x53\x2c\xa1\x7c\x3f\xdc\x47\x41\x58\x57\x21\x4b\x15\xd0\x3b\xe0\xfd\x3a\x99\x43\xba\x46\xad\xd7\xa3\x9a\xf3\xf6\xcb\xcb\x1a\x06\x9a\xe0\x05\xbf\x25\x48\x26\xd8\xa9\xa6\x0c\x77\x25\xef\x13\xcb\xa5\xdf\x4d\x64\xc1\x75\x79\xd1\x5a\xca\xbd\x20\x5a\x97\xe3\x37\x2a\x6b\xe1\x11\xa3\x91\xa2\x47\x5c\x39\x75\xe3\x3c\x56\xa7\xa6\x0e\xe2\x83\x6e\x85\x74\x63\xaa\xe8\xc4\x35\x57\xd4\xe2\x37\x03\x9c\x4a\x39\x5c\x60\xb0\xe8\x21\x17\xea\x5e\x4f\x77\x50\xde\xba\x6d\xfb\xea\x55\xa5\x32\x3a\xfb\xa4\x45\xdb\xb6\xd2\x08\xed\x05\x09\xa1\x4d\x41\xd2\xdb\xe9\x6a\xff\x0a\xd1\x6d\xf9\xb0\x4e\x12\xa0\x7b\x23\x33\xba\x04\x02\x6d\xaf\x02\x75\x72\xdf\xa0\x4d\x83\xa5\xb5\xda\xa4\xc9\x1a\x91\x3d\x66\x68\x8f\xf1\xba\x74\xab\xe2\x82\xc8\xc3\x46\xaa\x07\xe8\xd4\x4a\x20\xa3\x97\x8a\x5d\x93\x02\x77\x80\xfe\x27\xd3\x15\x09\xfe\xa7\xf3\x7b\xdc\xc1\xa3\x34\x98\xed\x12\x1e\x0b\xd7\x3a\xd4\x91\xac\x94\x13\xfc\x62\xc7\x90\x5e\x49\x10\xe5\xaf\xf0\x11\x72\xf2\xf5\xba\x38\x72\x83\x70\x91\x90\xb6\x7f\x88\x3a\xa4\x90\xa1\x8d\xef\x81\xff\xeb\xe0\x3b\x5e\xd6\xbf\x27\x31\x0d\xbf\xdf\x66\x40\x95\xc5\xe3\xdb\xae\x93\x8b\xa4\xca\xe1\xbe\x42\x47\x66\x03\x8a\x5e\x69\xc7\xf9\x37\x0b\x20\xc2\xfa\xb4\xad\x88\xc4\xd1\x03\xa1\xe3\x32\xef\x3e\xb2\x50\x7f\x07\xbc\x20\x1f\x5a\x2d\x2e\x82\xc3\x4d\xa0\x7a\xf8\x90\xf0\xd5\x88\x24\x4e\xbf\x03\xbb\xee\x13\xf8\xe0\x4c\xd2\x82\xa7\xf5\x1f\xd8\x3f\x30\x8f\x12\x10\xfc\x6d\xb5\xf8\x70\x48\x70\xb9\x2c\x13\xee\xfd\x6c\x70\x05\xb5\x95\xf6\x82\x23\xf9\x55\x3d\x6b\x03\xb2\x58\x62\xac\x5e\x03\xdc\xca\xd0\x41\x43\xbe\x2f\x93\x85\xa5\xdc\x1e\x72\x1b\xd8\xe7\x91\xe9\x1f\x55\x18\x55\xdc\x96\xb3\xbc\xab\xbd\xde\xa5\xb3\xbd\xed\x3c\x7f\xf9\xdc\x26\xad\x66\xb9\xe5\x95\x22\x40\xc4\x77\x40\xde\x46\x1d\xdf\x9c\x81\xfa\xf4\x36\x68\x0e\x22\x44\xe1\x7d\x84\xdc\xc9\xd8\x47\xd3\xca\xf3\x5b\x72\x8d\x39\x5c\x11\xb6\xdc\xc5\x81\x1b\xc2\xd6\x5b\xff\x45\xcf\xc5\xa9\xb9\x6d\xfd\xd7\x5d\x6c\xe8\xe8\x0e\x87\xbf\x29\x2c\xc9\x52\x1c\xe9\xa5\xe2\x48\xf6\xf9\x03\xbc\xb1\x3b\x85\xae\xf4\x80\x51\x4f\x67\xe3\x58\x6a\x48\x15\x8b\x44\xce\x7c\x89\x55\xfe\x86\xa1\xa2\xb2\xfb\x14\xff\x0b\x73\x1c\xaf\x5f\xf9\x59\xe1\xf3\x25\xfe\x86\xf4\x73\x73\x55\x06\x6b\x28\xe6\x73\xf6\x18\xb3\x46\x39\xb1\x78\x3a\xd9\xbb\x1e\x2f\x01\xf6\xea\x27\xad\x68\xcb\x4d\x6a\xcb\xac\xd6\xae\x5b\xc3\xd9\xa6\x7c\xc7\x6e\xca\xae\xe3\xc3\xa9\x40\x0c\x51\x57\xbe\xf3\xb2\x80\xa6\xbe\xdd\x9f\xca\xa5\x11\x0a\x12\x65\xbd\x8a\xaa\x9b\x37\x2b\x00\xe0\xf0\x07\xd2\x44\x7d\x04\x60\x2e\x33\x40\x8e\xd2\xc3\xaf\x79\xc9\x72\x86\x70\xf3\x92\xeb\x5f\x57\xc9\x4f\x2a\xc5\x23\xc1\x5a\xca\x4b\x34\x52\xba\x3c\xf7\x68\x44\xce\x00\x6c\xbb\x7f\x3d\x85\xb3\xcc\x0c\x72\x37\x1b\x17\xb1\x53\x29\x90\x82\x32\x70\xe9\x93\xd9\xf7\xb7\x40\xf9\x9b\x72\x35\x43\xcc\x39\x20\xff\x3a\xf9\x7d\x07\x3e\x42\x97\x35\x55\x53\xcf\xa3\xf2\xef\xf9\xcf\x98\x3c\x73\xc1\xf4\xb0\x43\xef\x46\x65\xfa\xd2\x91\x41\xc4\xb5\x95\xde\xa8\x1c\xc5\xdf\xfe\xc9\x53\x94\xe3\xa5\x06\x99\xb9\x64\x00\xd1\xaa\xbc\xd3\x90\xd6\xdc\x52\x38\xea\xdc\xd3\x71\x5e\x30\xce\xee\x9c\x1e\x17\x5b\x60\x47\x72\x1b\x3f\x0a\x79\x8f\x48\x03\xa4\xc9\xc9\xb6\xc0\x5c\xb5\xb9\x86\x72\xdd\xf3\x3c\x18\xce\x05\xb8\x1e\x7e\x32\x43\xc9\x73\xa2\x1d\x8e\x1d\xca\xbd\x3c\x60\xe4\xc0\x3a\xbe\x7c\x62\x84\xc5\xc0\x5c\x72\x37\x6f\x6b\x39\x9f\x4f\xbe\x0e\xb5\x3c\x59\x9c\xb3\x76\xbf\xa0\x31\x65\xbb\x50\xc1\x37\xd8\x5b\xa2\x74\x25\xb7\xb5\x1d\x1b\x1e\x25\xe1\x46\xee\x45\x01\xee\xd3\x0a\x67\x25\x79\x70\x4f\xef\x6e\x06\xe1\x7d\xfc\x6b\x6d\x2a\x26\xfe\x77\x97\xf8\x7d\x67\xf6\x2d\xab\xf9\xb1\x5a\x2e\x67\x68\x7e\x0a\x26\xa3\x57\xec\x4b\xd4\xd6\x26\xc1\x98\x7e\x0e\x15\x17\x16\xf7\x37\x53\xbd\x0c\x8c\x31\xd9\x84\xd3\x56\x65\x10\x12\xb7\xf2\xd4\xd6\x40\xc4\x2e\xb7\x21\x44\x88\x64\x02\xda\x19\x5e\xe7\xa6\xaf\xeb\xa5\xff\xb8\x82\xb3\xc7\x2c\x57\xfd\x23\x9b\x18\x36\x7c\xba\xad\xfa\x59\x3a\x1d\x93\xc0\xbf\x11\x35\xbb\xec\x2b\xe9\x6c\xff\x1b\x45\xba\x74\x06\xea\x14\xb7\x87\x77\x4a\x55\x13\x5e\xf6\xf0\x94\x45\x0d\xbf\x56\x78\x4d\x8f\xdc\x4f\xa9\x03\xd0\x86\xee\x7b\x4f\x9e\x10\xc0\xb2\x5d\xb7\xe5\xd7\x4e\xff\x92\xad\x87\x7a\x57\xfb\x4e\x7b\x5b\x5c\x58\x0b\x46\xd6\x37\x0e\x83\xb7\x2b\xf7\x00\xc2\x2d\x24\x8b\xa7\x6a\x47\x2d\x13\xea\x1b\x49\x64\xfd\x5c\x45\xfe\x12\xdb\x99\x29\xa4\x63\x84\x6d\x2d\xe7\x44\xf2\xa4\xf8\x9c\xa4\x6e\x5c\x0e\xaf\x98\xe4\x03\xbb\x3a\x56\x0d\x83\xa4\x5b\x4c\x6c\xd5\x40\x80\x7b\xa0\x16\x41\xc7\x6a\x66\x4a\xa4\x42\x0f\xd5\x42\x4e\x4d\xb2\x0f\x7d\x68\xfa\x97\x4c\x85\x19\xc3\xd9\x59\x1c\x10\xc0\x0b\x4b\x7a\x6d\x82\x83\x55\x85\x83\xdd\x77\xca\xc6\x43\x9b\x98\x78\x64\x15\xfb\x24\x8b\xaa\x09\x90\x2c\x47\x51\x5e\x37\xeb\x6d\x43\x3b\xb0\x84\xfd\x4d\x63\x20\xf1\xd5\xf8\xf9\x7f\x94\xd4\x7c\xbe\xa6\x47\xef\x51\x86\x45\x6f\x28\x11\x2a\x35\xa1\x75\xbe\x97\xe3\xd6\x39\x0b\x78\xa3\xd3\x63\x13\xfb\xe6\xaa\xf9\x5e\xbc\xa8\x6f\xae\xe2\x9f\x2e\xe2\xed\x99\xa8\x5c\xe2\x5d\xf6\xf5\x8d\x15\xfd\x8e\x39\xa2\x97\xbc\xa1\x30\x84\xab\x7c\x51\x2d\xf4\x2b\xb4\x10\x8d\x9a\x42\xd2\xe9\x6c\xf6\xe3\x13\x1f\xb5\xb2\x27\x20\x34\x6a\x6e\x4c\x68\x42\x56\xe7\x18\x36\xb6\xf8\x61\x64\xb3\x55\xaa\xf1\x66\x26\x82\xf3\xa7\x40\x16\x25\x55\x0d\x57\x1f\xa0\x56\x58\xfb\xea\x52\x18\x92\x5b\x4c\x26\xb2\x7a\xf7\xfe\x71\xc9\x55\x35\xb0\x1e\x65\xa9\xb9\x03\xc8\x6a\x63\x6f\x68\xaa\x3a\x9d\xd8\x64\x96\xcd\xb6\xbb\xe7\xc9\x9e\xe1\xed\x54\x3c\x16\x2b\x6e\x13\xc0\xac\x6c\x59\xd0\xaf\x1f\x92\x4e\xc8\x36\xfa\x1e\x1f\x32\xfa\x1e\xbb\xf1\x0b\x3d\xe9\xbb\x46\xb4\x5a\x85\x68\xab\xd0\x24\xce\x99\x2f\x14\x12\x7d\xf6\xf9\x2a\xb5\x93\x90\xac\xf7\x03\xf5\xb2\xc4\xdb\xf1\xaf\x24\x37\xd7\x13\x04\x20\x8f\x87\x4d\xad\x5f\xad\x0f\x4f\x76\xf3\x4d\x19\xc4\xd8\x99\xf0\x5c\x32\x4d\x04\x58\xeb\x37\x4c\x01\x36\x0b\xf0\x6a\xd0\x34\xa0\x51\xe8\xbc\x01\xc4\x29\x37\xed\x8f\x35\xb2\xe3\x75\x12\x73\x4e\xb3\x67\x61\x27\x57\x5a\x72\x28\x4f\xd8\x46\x43\x57\x57\x3e\x6a\x7e\xb4\x4f\xba\xe8\x20\x68\x09\xb6\x90\x27\xd3\xf4\xa1\xb8\x11\xc3\x14\x29\x5d\xbe\x4c\xf1\x11\x7c\x4c\xdd\x5f\xf2\xc1\xed\xb1\xd4\x91\x03\x78\xd3\x69\x92\x97\xfb\x92\xbf\x64\x0a\x60\xea\x27\x8d\x08\x52\x04\x85\x80\x5d\x9e\x7d\x18\x5e\x95\x1d\x94\xc5\x01\xd4\xfd\x29\xc6\xb0\xb3\xcd\x18\x4b\xaa\x20\x09\x9c\x39\x7d\x80\x99\xb2\xfb\xb1\x9a\xf4\x37\x4e\xa5\x35\x9c\x2e\xb9\x88\x82\x03\xc6\x84\xd3\x18\x92\xf5\xa3\xe4\x1e\xf5\xa4\x52\x31\x9a\x04\x38\xa2\x82\xd8\x9d\x24\x84\x87\xca\x13\x1c\x58\x7e\x99\x4f\xa1\x1c\x9e\x18\xd9\x61\xf1\x63\x8e\x1e\x34\x7d\x94\x2e\xf4\xe5\xab\xdc\xba\xb8\xc8\x7f\xd2\xef\xaf\x93\x82\x57\x15\x36\x82\x30\x5b\xa4\x0a\xdf\xdc\xae\x71\x19\x92\x0b\x7d\xe8\x05\x06\x91\xe3\x3e\xa5\xaf\x84\x81\x39\x30\xd6\x0f\x16\x1d\x63\x17\x6a\xdd\xd9\x07\x2f\x74\x27\x6d\x91\x46\x2d\x8a\xf1\x88\xe4\x60\x9a\x15\x76\x87\x12\x94\xcc\xd3\x2e\x4b\x13\x46\x06\xdb\x0d\x00\xd9\x60\x29\xf7\x01\x78\x24\x55\xbe\xa0\xd0\xb2\x91\xc0\x96\xaf\x72\x87\x33\xe2\x45\x49\x1d\xdc\x2c\xb8\xd8\x21\x7c\x4a\xce\xf7\x78\xbc\xd3\x40\xef\x31\x25\xfb\x4b\x6f\x21\x21\x74\xe9\xee\x1a\xf3\xcc\xac\x81\xba\x64\x77\xb6\xe2\xb5\x7a\x9c\x1a\x0a\x89\x0a\x49\xbf\x02\x2c\xb8\x65\x68\x31\xa4\xab\x11\x66\x80\x06\x9b\x94\x0c\xa2\xad\x69\x58\x29\x7c\x05\xe6\xd6\xf7\x18\xca\x6f\xd7\x98\x60\x32\x94\xaa\x9c\xcd\xe5\xa3\x90\x72\x9b\xb3\x82\x33\xd2\x8c\x2e\x30\x5f\xbf\xce\x28\x64\xd8\x02\x1b\x5b\x2a\x89\x74\xa3\x8d\xa9\x41\x9e\x04\xf8\xf3\x4b\x93\x63\x0b\x01\x4e\x73\xce\x4d\x40\x4f\xd1\xfb\xb7\xde\xb3\xb2\x0c\x5d\x54\x31\x38\xe7\x7a\xb3\x82\x09\xd9\xe5\x32\x1a\x33\x84\x06\xd7\xc4\xb9\x46\x76\xb1\xe5\x25\x7d\x29\x1a\xf5\x98\xfc\x06\xd8\x17\xbd\x88\xf5\xfa\xa1\x52\xcf\xc0\x8c\x59\x5c\x2e\xc4\xcd\x4b\x5a\x61\x87\x83\xbe\x1c\xdc\x8f\xc8\x11\xd4\x8c\xa0\x5b\x84\xd2\x00\x28\x99\x39\x21\xb0\x84\x4b\xf3\xe1\xd8\xd6\xbc\xc9\x73\x8f\x86\xc4\x19\x60\x5c\x12\x5a\x2e\xe5\xce\xa8\x4d\xe1\x78\xa8\x03\x7e\x5c\xa2\x39\x61\x6e\x25\x55\xcf\x4f\x7e\xd7\x65\x9d\xbd\x43\x1b\x9a\xa2\xfa\x44\x97\x1a\x5e\xc2\x48\x59\x0d\xff\x52\x62\x26\xe5\x04\x80\x10\x93\x99\x32\x4b\x6c\x59\x27\x7c\x0f\xf1\xf3\xcd\x4e\xc4\x77\x69\x83\x76\xa8\x63\x4f\xb7\x2c\x53\x97\xa3\x36\x4c\x1d\x38\xbf\x7b\x5d\xf9\x51\xba\x39\xb9\x93\xf5\x41\x1b\xe2\xc6\xc6\x7f\xb4\xfd\xde\xa3\xc1\x67\xb0\xf4\x90\x86\xa4\x72\x82\x19\xc8\xb9\x8f\x26\xf8\xa2\xec\xbc\xfb\x6e\xd2\x39\x0c\x61\x51\x6d\xd3\x37\xcd\x91\x04\x51\x3b\x27\xb4\xed\x6a\xe9\xf5\x32\xd6\x8b\x89\x04\xaf\x60\xc2\x9b\x75\x54\xbf\xbc\xfd\xce\x93\x16\x2e\xe7\x46\xf6\xc1\xe9\xa6\x18\xba\x54\x75\x80\x7c\x2e\x99\xba\x87\x49\x30\x81\x6a\xc2\x41\x78\x50\x40\xae\x6c\x1b\xae\xd5\xdd\xd4\x99\x00\xb9\x1e\x54\x3d\xc1\x37\x58\x47\x71\x25\x02\xe7\x63\xf8\x18\xdd\x86\x6d\xa3\x15\x14\xd5\xed\x10\x99\x8c\x71\xb3\x54\x74\x29\xe2\xde\x02\x1c\x7f\x20\x60\xae\x93\xfc\xe4\xf1\xee\x4f\x97\x70\x74\xf5\x2b\xce\xb0\x60\x81\xc5\xcc\x5f\x02\xd0\x8e\x00\x14\xed\x6b\xb8\xbe\x66\xcb\x97\xcc\x15\xfe\x36\x55\x65\xde\x7d\xfc\x5b\x3b\x91\x7b\x78\x48\xb2\xd1\x11\x08\xb6\x4b\x07\x75\x0e\x9c\xdc\x70\x09\xe9\x6d\x8f\x9e\xde\xb1\xbd\xcd\xea\xf7\x5e\xde\x13\xe1\xba\x60\x54\x74\x8a\x3c\x5b\x8d\xd5\x72\x51\x2d\x61\x95\x3e\xe7\x70\x97\xb5\x98\x2b\xfa\x16\xaf\xaa\x31\x5f\x2e\xb0\xbb\x10\x01\x54\x49\xd1\xef\xb4\xe3\x1a\xfc\xcf\xf4\xaa\x7d\x36\x9a\xcf\x5a\xe4\xfd\x5c\x25\x74\x42\xe1\xa7\xaf\xa1\x3f\x49\xfc\x22\x77\xc6\xb0\x78\xcd\x59\x82\x50\x95\xa7\xb5\x0e\xb9\x6f\x9c\x25\x54\xc8\xe9\x1a\xb8\x24\xd0\x3a\x4d\x5e\x81\x2f\x0d\x88\x38\xb7\x2a\x98\x12\xd3\xeb\xfc\x6b\xe6\x8b\x35\xe4\xdd\x61\x38\x8f\x2f\xcb\x75\x8c\xfd\x75\xb2\x67\x18\xe5\x10\x5d\x0c\xef\x54\xc7\x8b\x52\xa3\x0a\xf9\x86\xc2\x54\x5d\x06\xc7\xe5\x25\x2c\x0c\x96\x51\x3d\xed\x59\xca\xaf\x33\x00\x44\xd1\x5a\x28\x1b\xd3\x8c\xcd\x1c\x76\x7d\xbb\x0c\xaa\xb6\x3e\x7a\x0e\xce\x31\xe1\xdb\xd7\x7b\x9c\x2b\x7f\x0a\xfb\xe5\x98\x35\xb3\x41\x02\xd1\x26\x1d\xde\x3a\x73\x12\x5f\x6c\x3a\x57\x7b\xc0\xcf\x4d\x0a\x62\xcd\x2e\x10\x1a\x52\xb7\x0a\x7f\x93\xd2\x8b\xfa\x11\xcf\xaf\xdc\xc3\xaa\xbc\x6c\x43\xd4\x79\x44\x52\x7c\xff\x51\x50\xff\x71\x48\x42\x78\x34\x29\xdf\x7d\x06\x2a\xb1\x47\x66\x50\xc5\x5d\x90\x25\x60\xc8\x55\x9b\x0e\x06\x03\xc2\x93\xab\xfc\xa1\x15\x48\x30\x27\xfb\xfd\x0d\x1c\xa5\x75\xd2\x6c\x55\xbf\x73\x00\xaf\x18\x80\x77\xe5\x01\x4b\x57\xc2\x4f\x89\xf9\xfd\xdd\x77\xc5\xf8\xfc\x2c\x60\x17\x47\xdb\xe7\x01\x9e\x7a\x39\x0c\x7a\xf8\x54\x08\x48\x37\x64\xf5\x13\x2a\x68\x41\xc8\x39\xed\x5a\x10\x46\x9b\x8f\xa1\x01\xc4\x21\x69\x56\x87\xc1\x1a\x0f\x74\xd0\x46\xa4\xf7\x72\xc8\x31\x04\x42\xba\x37\x8b\x0a\x46\xef\xe0\xd3\x4f\xe1\xcd\xe9\xf5\xcd\x22\x83\x76\xf4\x92\x53\xc8\x9f\xaf\x34\xc0\xe3\x08\x8e\xf6\x08\x8d\x93\xa5\xbf\x54\xb9\x16\x1b\x80\xf0\xf9\xd5\xe0\x03\x1d\x00\x9e\x4c\x98\xf0\xef\x9a\x06\x94\x7f\xa1\x0e\xeb\x1f\x61\x13\x2a\x7d\x64\x80\xfa\x83\xdc\xd1\xc2\x6a\xd1\x5c\xd0\x15\x82\xb3\x0f\x0f\x09\x96\x9f\xf3\x91\x34\xa6\x87\xc5\x72\xa5\xf1\x44\x4d\x63\x7d\x98\x2a\x81\x60\xc3\xfd\x6c\x53\xe2\x01\xb5\xb5\xce\x62\xcc\x0d\xd0\x19\x53\x19\x10\xca\x30\xae\xce\xa9\x3c\xd8\x40\xa1\x54\xc7\x34\x52\x39\xc0\xd7\xf9\x3e\x5d\xd4\xeb\xdf\xd5\x3c\x10\x28\xfa\xac\xdb\x70\x30\xdf\x82\xf4\x06\x70\x5c\xa8\x35\x94\x12\xd9\x67\xf8\x49\xcc\x97\xea\x7d\x56\xa7\xcd\xf9\x78\xe8\x4c\x3f\x17\x65\xe6\xcd\x96\xcb\xd7\xf7\xda\x9f\xb2\x3a\xa9\x4e\x20\x8d\xfa\xd2\x4d\x06\xc3\xc1\x63\x5c\xd0\x58\x6d\x5d\x36\x55\x06\xd0\x19\x98\x74\xe8\xcd\x68\x71\x54\xae\xce\x31\x40\xcb\x58\x87\xfe\x5e\x45\x91\x58\xc3\x04\x67\x32\x79\xa2\x61\x13\x55\xfe\xda\xd4\x3f\x01\x9f\xe6\x71\x3f\xe0\x7f\x58\x00\xe8\x59\x2d\xd4\x1f\x25\xe8\xcf\x8b\xd5\x16\xe4\xa8\xa4\x9f\xfc\xb2\x5f\x58\xc2\xbb\xfc\x02\x40\x09\xd2\xe1\x20\x79\x42\x9d\xf9\x1b\xa2\x05\x69\xac\x25\x3b\x4c\x83\x1d\x4f\xde\x59\x72\x0c\x25\x47\x6a\x12\xf9\x76\xc0\x05\xac\xfe\x5b\xde\x66\xef\xbc\xc6\xe7\x73\xd4\x81\xdf\x57\xf1\x6a\xda\x0c\xe0\x1f\x3c\xd7\xae\xaa\x2d\xbc\x01\x82\x32\xe1\x35\x54\x5a\x6a\xe7\x60\x0f\x1d\x02\x42\x00\x6e\xd1\x0d\xc8\x3e\xdc\xeb\xbd\x9b\x99\x47\xb3\x94\xd2\x0f\xd5\xae\x00\x82\x2e\x5a\x5c\xc0\x7a\x68\xfc\xbe\x95\x03\x0c\x74\x61\xf2\xec\x03\x56\xca\x75\x69\x36\xed\x90\xe5\xbb\xc1\xc9\x08\xd9\x5f\x5c\x49\x48\xfa\x1f\x2f\x50\x0e\x49\xc2\x7f\xae\x94\x29\xa2\x48\x25\x17\xda\xa5\x0a\x21\xe2\xfd\xc4\x44\xb4\xff\xc7\x23\xde\x90\xc1\xf2\xf2\x87\x18\x84\x94\x29\xd3\xb9\x9b\x75\x19\xee\xf5\x5d\xee\xa1\x84\x52\x2e\x44\xdf\xa8\xed\xf0\x1b\x33\x18\x9b\x49\xaa\xf5\x10\x80\x87\xa1\x7c\x93\x8b\x91\x80\x2f\x43\x03\x17\x8b\xac\x5f\x84\xd2\x72\xcc\x57\x65\xc8\xea\x88\x0f\xad\x07\x73\x72\xed\x5e\xb2\xe5\xbf\xc8\x8f\xd5\x37\xe8\x6b\x3f\x73\x33\x18\x29\x8c\xe2\x4e\xf5\x15\xaa\xb4\xe3\x11\xb3\x06\xcc\x3e\x27\x1f\xe7\x8b\x50\x7e\x9e\x8d\xc6\xf8\xe0\x38\x61\xe3\xab\x43\x3e\x9c\xad\xaa\x8c\x4d\x49\x0c\x4a\x3c\x9e\x7d\xbc\x1f\x81\x0c\x5b\xab\x3c\xcd\x5a\xf6\x38\xf6\x13\x97\xf6\x21\xca\xaf\x8b\x97\x0e\x32\xab\x35\x45\xf2\x1a\xd0\xec\x5b\x60\x07\xb4\x0d\x81\x60\x67\xaf\x7c\x29\xa5\xca\x16\x88\xd7\x85\x1e\x32\xea\x0a\xcc\xee\x42\x2d\xfd\x5b\x98\x82\xf7\xce\x52\x41\x6b\x56\x82\x5c\xae\x49\xf6\xf7\xce\xb8\xec\x5f\x19\xe7\xb2\x4d\xae\x6f\xff\xe8\xfb\x08\x96\x4e\x8c\x80\x9e\xf7\x83\xbe\x98\xe1\x02\x00\x3b\xf5\xa2\x41\xed\x61\xbd\x35\x55\xb5\x0e\x08\x3a\xf0\x11\x9b\x38\xa1\xf0\x47\xbe\xa4\xd2\x7f\x3b\x3b\x05\x30\xb0\xda\x83\xdd\xf6\xec\x3f\xad\xbe\xf4\x27\x15\x1f\x03\x51\xfc\x73\x2e\xcf\xf0\xe8\x22\xd3\x91\xcf\xf9\x29\x67\x86\x73\xec\x9f\x4c\x0c\x19\x56\xfa\x50\x84\x02\x88\xf9\x3e\xed\xeb\xe3\x8e\xc4\xa8\xca\x97\x91\xff\x5e\x1a\x43\xc1\xb9\xd2\xb2\xec\x50\x0f\x16\xca\xe1\x77\xee\xf5\x57\x21\xfc\xc9\x05\xe8\xb1\x66\xdf\x22\x9b\x39\xc2\xb6\x07\x6d\xec\xac\x33\x69\x40\x45\xe0\x2f\x6b\x20\xc7\x84\xad\x16\x5c\x4d\x07\xef\x10\xb9\x3d\xe4\xd9\x74\x5c\x35\x1b\xe6\xa0\x9b\x94\x08\x37\xe9\x73\x1e\xf0\xef\xde\xd8\x75\x10\x26\x16\xe5\xc4\x85\x23\x7c\xc8\x5c\xac\x7c\x77\xd1\x9d\xf8\x96\x3f\xba\x91\xb0\xbb\x0f\xd9\x6e\x63\xb3\x6e\xc6\x45\xee\xd1\x96\xa5\xf0\x52\x3b\xfc\x91\x2d\x0a\xfb\x20\xac\xa3\xf1\x2c\xe9\x31\x56\xa5\xe5\x92\x61\xcc\xbd\x90\x30\xe5\x6f\x95\x6c\x52\x70\xda\xe9\xd7\x92\x64\x33\x38\x06\x09\xfb\x5e\xd3\xe1\x7b\x2f\x60\xf1\x5d\xe3\xfe\x3b\x45\x51\x9c\x6f\x98\x2a\x84\xae\x43\xb4\x2e\xca\xc7\x3f\x54\xff\xbe\x0a\x87\x70\xeb\xa1\x44\x2a\x8f\xf9\x4a\xe9\x80\xd8\x2f\xd1\xcf\xdb\x97\xb1\xcf\xd5\x87\xf8\xb4\x08\x57\x1d\x3f\xc0\x52\x9e\x3e\xd4\x26\xd8\x6b\x85\x8f\xd9\x45\x2f\xef\xbb\xb2\x24\x00\xf5\x66\x89\x26\xaa\x14\xdf\x84\x7b\x70\x43\xa2\xb7\x80\x06\x8a\xb3\xdd\xba\xf4\xd3\xa0\x1f\x4d\xa9\xdd\x32\xdb\xe2\x5d\xff\x05\x0b\xe9\xe2\xcd\x76\x7d\xcb\x7c\x21\x88\x6c\x81\xe6\x2f\xa5\x87\xb1\xfb\x50\xa1\x56\xe6\x53\xaa\xed\x26\x74\xf4\xd8\x76\x58\x42\xcf\x6e\x79\x20\xcf\xbf\x9a\x0e\xcc\x59\xf7\xdb\x77\x02\xe4\xbc\x67\x85\xad\x79\x45\xfc\x4f\xfd\x17\xfc\x5f\xa3\x10\x65\x42\x40\xf9\xf1\xa5\xd1\xb1\x71\x45\xc5\xe9\x85\x7e\x3e\xf4\x40\x15\xda\xd2\x39\x55\xaf\x22\x81\xfe\xec\xe2\x2c\x97\xa1\x0f\x8c\xb9\xb1\x38\x15\x84\x9b\xf2\x6a\xf7\x30\xbb\x69\x68\xc3\x17\x6c\xb6\x69\x7a\x48\x37\xae\x49\x31\xb2\xa2\x54\x06\x64\xe4\x02\xef\xb0\x23\x0d\x51\x6f\xc1\x60\x43\x2e\x3d\xf6\x34\x46\xe5\x26\x3e\x1b\x02\x7a\x0c\x1d\xae\xbb\xa3\xf9\xcd\xbf\x43\x3f\x06\x77\x17\xdd\x80\x87\x89\x66\xe8\x59\xe8\xc1\x71\x63\x73\xfd\x66\x62\xf3\x9e\xcc\x66\xce\x13\x3d\xe5\x5b\xe1\x99\x92\xbc\xb6\xdc\x85\xa7\x11\xf5\x3f\x9c\x39\xbd\x9d\x46\x14\x5c\xfd\x0b\x0d\xd5\x05\x55\x2c\xa6\x06\x99\xcb\x2f\x8d\x2b\x7f\xa1\x06\x86\xcd\xfd\x5b\x76\x32\xb3\x20\x6e\xfe\x4f\x85\x09\xbd\x09\x33\xa1\xde\xd4\x87\x8b\xa5\x66\x44\xe3\x64\xf6\xe6\x7b\xb0\xd1\x52\x0a\xc0\x46\xb2\x8c\xcc\x9b\x96\x96\x5e\x72\x46\xf9\x1a\x37\xbf\x5b\x60\x22\xd1\xa8\xc1\xb2\x77\x6a\x00\xab\xd9\xa9\xf6\x30\x28\x65\xae\xd5\xf8\x1a\xbb\xab\x83\x61\x42\xa8\x9f\x37\xf1\x8e\x22\xcb\xf1\x96\x40\x33\x62\xe9\xd3\x46\x38\x32\xbc\x76\x7b\x23\x04\xa8\x6d\x11\x10\x30\xb4\xb2\x6a\x07\x25\x47\x95\xaa\x8e\x9b\x40\x8e\x8c\x53\xb0\xb4\xd5\xe1\x80\xc2\x94\xa9\x73\xa0\x6d\x49\x9f\xaa\x9a\x39\x1d\xf6\x72\x72\x56\xc3\xd4\x61\xcd\xc6\x62\xef\xab\x13\x2a\xa8\x4e\xd9\x13\x6a\x0c\xbf\x97\x69\x54\x2b\xa2\x53\xdb\x84\xf9\x91\x33\x0f\xdb\x12\x80\x78\x2f\x63\xa5\x8d\xf5\x18\x7d\xf7\x85\x50\x44\x13\x47\x7d\x89\x44\x54\x10\xf5\x3c\xea\xa8\x03\x9c\x79\xe1\x30\xf6\x50\x26\xde\xfa\x9f\x4b\x77\xda\xa6\xac\x41\xe0\x96\xbc\x5b\x9d\x93\x9c\x5b\xa5\xec\x41\xe5\x5c\x2d\x03\x30\x21\x85\x8d\x2c\x75\xe9\x2c\xa0\x04\xa6\x90\x29\xf8\xd7\xf9\x4b\x6d\x87\xd9\xce\xf6\x25\x54\x08\xdb\xdc\x20\x2d\x44\x6f\x2b\xe8\xdb\x5a\xf2\x80\x8d\xa7\xb4\xf2\x87\x02\x6b\x2f\x08\x0e\x36\x4d\x59\xcb\x47\xa2\xc4\xc8\x02\xc2\xab\xbf\xae\x2a\x5a\x35\x1a\x4a\x89\xf5\xd3\xdc\x85\xcb\xd3\x6e\x4d\x9d\x3b\x20\xad\x99\x3d\xab\x69\x60\x79\x7b\xd9\xbe\x0e\xfe\xa0\x01\x79\xcb\x0d\x87\x37\x56\x02\x5d\x6a\x72\xcf\x56\x86\xeb\xb6\x12\x76\x5f\x79\x17\x4d\xe1\x75\x4d\x24\x60\x88\x27\x76\x9f\xa6\x24\xe3\x62\x6e\x9f\xec\xba\x7b\x64\x04\x16\xfd\x38\x37\xe3\x20\xfb\xc9\xba\xda\x27\xff\xeb\x3b\xe5\xc2\x0a\x80\xbd\xd1\x95\x7a\x5c\x98\xa5\xe9\x7c\x64\x9a\xbf\x4d\xe3\x5a\xde\x20\x16\xf0\x45\x6c\xe1\x57\x75\xc3\xe0\x43\x98\xfd\x67\xba\x93\x79\x4b\x42\x4b\x0a\x57\xbd\x7f\xfa\x4c\xe3\x22\xe7\x86\x3e\xee\x6c\x2f\x0d\xee\xd4\xb1\x48\xdf\xb6\x34\x74\xfa\x3a\x7d\x87\x00\xd8\x48\x5c\xbe\xa4\x5a\xc8\xd4\x9c\xfd\x2b\xd4\xbc\x32\x9f\x1c\xe8\x47\x76\xa8\x1c\xb4\x9c\xd9\x04\xf3\xcf\x34\x03\xe4\xf1\xa9\x11\x5c\x77\x20\xa7\x40\x7d\x3d\x2e\x2c\x70\x3b\xc3\xe7\x20\x60\x54\x03\xfb\xfb\x58\xa4\x5f\x4d\x3f\x3e\x24\xcf\xde\x94\xa9\x98\xfe\x34\xe0\x00\xe0\x2d\x79\x0e\xdb\x69\xf4\xf9\x03\x1a\x02\x81\xaa\x48\x0b\x1a\xb5\x76\x2c\x5f\xba\xe7\xd8\xf9\xf1\xff\xa7\xa7\x25\x2e\x61\xee\x76\x95\x69\x0f\x9e\x6d\x78\xea\xfd\x43\x3f\xaf\xb3\x3a\xd3\xde\x6d\x32\x52\x76\x9f\xb0\x9a\xfc\x92\xe1\xc4\x10\xbe\xd9\xc4\x5d\xf0\x29\xa3\x52\xe5\x3b\xd2\xff\x89\x28\xc4\x7b\xa3\x0b\xef\xee\x3a\xb3\xe4\x30\x25\x52\x73\xb6\xc2\xbb\x7f\xbf\xbc\xbd\x68\x86\x5e\x3f\x6b\xa0\xa6\x36\xcf\x45\x9a\x80\x36\xf7\x54\xa0\xea\x9f\x6c\x83\x9c\x9d\x05\xb6\xca\x7b\xc1\xe9\x2e\x00\x86\xde\x42\x97\xff\x11\x26\xdf\x2a\x0a\x5d\x62\x91\x37\x69\x79\x2d\xd7\x97\x87\xa4\x24\x1c\x77\xfa\xeb\xf3\xea\xbe\xc8\x50\x1d\x4d\x2c\x94\x16\x41\x7c\xd6\xa4\x43\x77\x4f\x40\xb4\x57\x3a\x41\x34\xe6\xa4\x41\x09\xa6\xe2\x72\x28\x13\x75\xbd\xcd\x19\xdc\xca\x98\xa3\x10\x9e\xe1\x06\x07\x00\xe1\x8b\x6c\xf3\xff\x45\xde\xb1\x75\x53\xe5\x7a\x29\x89\x72\x7e\x81\x38\xa0\x77\x50\x1b\x38\xff\xe8\x54\xa6\x00\x67\xb5\xd9\xc4\x0a\x7c\xba\xd5\x8d\xae\x6d\xdd\x64\x39\x5b\xe3\x3b\x91\xc6\x97\x2f\x95\xc3\x8e\xf3\x7e\x67\x0e\xd6\x40\xcd\x48\x59\xca\xe6\xd6\x6d\x93\x09\x8a\x6f\xb2\x35\xb8\x9b\x29\x9c\x26\x9b\xcb\xd7\xba\x01\x89\x81\x7c\x89\xf1\x87\xe7\x77\xd3\xf3\x8c\x56\xa7\xa5\x6c\xd0\x57\x94\x10\x8d\x35\xe8\x9a\x8b\x30\x4b\xc4\x05\x13\x89\x4d\xdc\xc5\xcb\x51\x16\x19\xde\x22\x4f\x6a\x6b\x80\xcd\x49\x9c\xbc\x34\x95\x5a\x65\x4b\x68\x07\x7e\x29\x57\xf2\x27\xcd\xf7\xe5\xf0\xce\x5b\x58\x30\x42\x43\xce\x28\x04\x38\x4e\x44\x49\xe8\x0e\x89\x32\x87\x98\xae\xa4\x8f\xe1\xc2\x65\xe5\xa2\xeb\x5d\x71\x95\xaf\x71\xf9\x70\x02\x02\x94\x94\xb7\xd2\x2b\x5d\xa0\xd4\x73\xdd\xdb\x64\xed\x4a\x9e\xe4\x97\xae\xfb\x6a\xc5\x61\xba\x4f\x50\x19\xac\xfe\x2c\xbd\x72\x95\xa8\xa6\x99\x7d\x68\xa1\x01\x36\x17\x13\x92\xc3\x79\xc3\xb2\x73\xce\xeb\x4e\xca\x29\x6b\x49\x28\x56\x0a\x34\x3a\xc7\x04\xa4\x9f\x9d\x28\x08\x33\xea\xd7\x09\x86\xcf\x91\xca\x49\x8f\x10\x60\x98\xc5\x5b\x07\x35\x11\x90\x55\x50\x0b\xf4\x4a\x9a\xb8\x7c\xdf\xb9\x31\xad\xa8\xe2\x63\x97\x1d\xa3\x68\x1d\x5c\x94\x3d\x68\xfe\x22\x47\x6f\xf1\xf3\x0c\x1f\x06\xbd\x40\x0e\xd7\x22\x19\xed\x6b\xf0\x02\x10\xe3\xc3\xc7\x16\xd2\x94\xf2\x35\xf5\x36\xd9\x97\xb4\x80\x7e\xc7\x56\x6c\xc0\xa2\x2a\x7b\x19\x05\x61\x26\x2d\xd3\x27\xe9\x9e\xcd\xfe\x9f\x2d\xfa\x40\xa9\x32\xf1\x4d\x77\x39\x88\xed\x52\x08\x53\x8f\x85\x1b\x66\xb1\xb0\x00\xf7\xad\x3e\x97\x96\xe6\xbb\x82\x87\xd4\xf3\x9e\xf8\x90\x1b\x89\x20\x4b\x60\x4b\x99\x0b\x29\x63\x09\x65\x1f\x8a\x6b\x8e\xf5\xb8\xf9\x76\xdf\x85\x7a\x59\xd2\x02\x18\x43\xab\x75\xd2\x88\xe3\x66\x68\xc8\xdf\xe0\x81\x7c\xda\x20\x63\xb6\xb3\x4c\xed\xde\x9d\x79\x9a\x86\x5f\xa1\xe5\xcc\x7e\xff\x7f\x27\xf1\x47\x14\xa9\x21\x47\xf3\x5b\x73\x0b\x53\x9b\x51\xad\x61\x78\xe0\xf1\x49\x44\x00\x71\xe1\x46\x50\x09\x64\x61\x1d\x40\x92\x26\x78\x1e\x56\x6d\x9e\x42\xa9\x67\x75\xfb\x66\x1d\x34\xc1\x89\x61\xd6\x8a\x81\x87\x61\xa7\xd4\xaa\x51\x02\x03\x19\xe1\xa3\xc2\x43\xc3\x77\xa1\x2c\x4b\x79\xad\xd6\x0f\xf4\x45\x99\x52\x72\x56\x18\xb0\xd2\x3f\xa8\x37\xc3\x0e\xb8\x6e\x5b\xd3\x48\x72\x1a\x9c\xe9\x98\x93\xb5\xf4\xef\x59\x79\xc3\xd2\x97\x7f\x25\x14\x36\xe6\x93\xca\x49\x66\x8b\x5c\xec\xc5\x72\x28\x9c\xd5\x34\x3c\x24\x9a\x94\xff\x54\x3f\x08\x65\x3f\x4b\x55\x3f\x6b\xa1\xca\x32\x75\x6e\xf9\x7c\xee\x93\x45\x5d\xe6\x04\x36\xff\x96\xac\xa8\xbf\xc8\x9e\x18\xb5\x91\xa6\x76\x13\xf6\xb4\x66\xc8\xd3\xc9\x63\x15\xe3\x9c\xcd\xda\x68\x2f\x6f\xfc\x29\x9f\x55\x89\xbf\x36\x63\xc0\xca\x95\x64\xcb\x34\x06\x23\x6f\x2a\xdf\xca\x63\x91\xf7\x53\xc9\xc4\xd5\x2e\x02\xf4\x0b\xb7\x7d\xef\x80\xf6\x73\xbe\xec\xe3\xd7\x99\x0c\x92\x2b\xc3\xf3\x38\xc7\x6a\x43\xca\x24\x37\x06\x3f\x4a\xa6\xa9\xf7\x3a\x7d\x63\x42\xb6\x80\x3c\x63\xd8\x73\x69\xb3\xca\xde\xb8\x9a\xf6\x7d\xf6\x60\x12\x56\x9d\xea\x1b\xa5\xff\xd7\x9a\xff\xbc\x3e\xb4\xf9\x61\xdb\x87\xa8\xb9\xd1\x7d\x19\x0f\x74\x98\x7b\x40\x34\x2d\xe0\x1e\x10\xb0\x77\x9b\xba\x94\x40\x74\x91\xaa\x5d\x90\xc7\x9f\xc5\xaf\x75\x3f\x8d\x30\xba\x67\xf7\x99\xa8\xf4\x1f\x2d\x97\x71\x16\x2f\x94\x9a\x3e\x41\x3a\xf9\x9b\xc2\xe5\xf4\xf8\xc5\x48\x5c\xd5\xee\x7d\xfc\xa2\x8e\x56\xa1\xf9\x3b\xfd\xaf\xd5\x7a\xf9\xf4\x76\x59\xef\xff\xe6\xe5\xa2\xa4\x1c\xea\x19\xc7\x84\x07\x12\x40\x91\xed\x93\x30\xbc\xc7\xf0\x1c\x04\x58\x79\x14\x40\x0c\xc8\xf8\x0f\xa1\x32\xb2\x73\x70\x14\x99\x55\x8b\x54\x83\x07\x0b\x61\x1a\x57\xea\x1f\x40\xa4\x37\xa9\x39\x03\xea\x89\xa9\xa2\x17\x3c\xa3\x24\x41\x53\xbe\xb2\xa1\x4a\x5f\xe9\xa9\xc6\x8f\x55\xfa\xfd\xad\xd4\xd0\x77\xe8\x96\x2e\x7f\xf8\x9a\x69\x5e\x7a\x83\x92\x3a\xc8\x9b\x84\xae\xd0\x1e\xb2\x42\x67\xab\x7f\xb3\xc5\x98\x65\xb2\x3a\xc3\x65\x47\xf0\x89\x7b\xa9\xd1\x71\x7b\xf9\x0e\xfa\x89\xec\x90\xd5\xfc\x66\x3e\x97\x4b\x00\xb5\x44\xef\xf8\x41\x75\x29\xc8\xae\x98\x68\x8b\x1f\x0b\x59\xc0\x80\x61\x2a\x1c\x38\x96\xd1\xa8\xb1\xdd\x21\x30\xca\x2d\x2e\xcd\x40\x72\xb4\xb4\x4f\x99\x42\xac\x1b\x7a\x3c\x76\xcd\xda\x9a\xb2\x05\x9c\xb4\xa5\x20\x0e\x34\xc1\x3f\x4d\x46\x9c\xf6\x68\xc9\x72\x99\x95\x44\xd1\x16\xcd\x9a\x45\xc8\x35\xbe\x9c\x0d\x76\xb7\x0b\x4a\xc6\x15\x9d\x9c\x26\x48\xbe\x30\x6b\xff\x44\x62\xd2\x54\x53\xe1\x86\xff\xb2\xb8\x90\x58\xab\x23\xf3\x1a\x89\x6e\x85\xa0\x3d\x5d\x6d\x6e\x6c\x03\x85\x08\x7a\x82\x10\x42\xf8\x55\xa2\xe3\x43\x85\xa8\xb4\x94\x23\x57\x7d\x97\xe5\xc1\xf1\x1b\x1a\x3b\x38\xa7\xb1\x7c\x5c\xd2\xc9\xa9\xa3\xfe\x3c\x56\xf8\xb2\xaa\x23\xdc\x6f\xf2\x67\xfe\xc9\xa7\x6e\x2f\xed\xdc\x8f\xcc\x5a\xdf\x5b\xf4\x76\x61\x2f\xe9\x86\x0c\x53\xff\x8a\x5e\xb5\xae\xdd\xe0\xb6\xcf\x5b\x13\xc1\x92\x66\xed\xe9\xad\xc5\xaa\x9b\x41\x0d\xd6\x37\xde\x1a\x53\xab\x72\xd9\x55\x48\xca\xb9\x4b\x74\xc2\x51\x8a\x57\xcb\xce\x05\x48\xe5\x6a\xc9\xc8\x4f\x49\x4b\xd9\x8a\x9d\x4b\xc3\x0f\x4c\x3d\x9b\xc7\x64\xd9\x6c\xb0\x06\x4b\xdc\x8d\xc2\x55\x93\x28\xd9\xdc\x64\xc0\xfe\xf8\xe0\xb8\x1e\xd9\x70\xd5\xfe\x82\xae\x42\xfe\xcf\x12\x4b\xd0\xca\xdf\x25\x06\x09\xb3\x06\x66\x50\x1f\x10\xd7\x85\xf3\x78\x57\xb2\x54\x59\x2a\x35\x3a\xb7\xeb\x40\x0e\x43\x31\x27\x15\x67\x73\x4c\xbd\x72\x95\xe3\x8c\xf6\x4d\x75\xfe\x87\x3a\x93\x52\x27\xb9\x7b\x7b\x6d\xd2\x2b\xf9\x70\xf5\x99\xe5\xad\x28\x7b\x59\x37\xb5\xe9\xe1\xce\xfb\x31\x52\xd6\xfc\x8d\x7d\xa9\xd6\x3a\xf3\x65\x17\xfe\x3c\xdd\x11\x92\x97\xcb\x18\xa9\xd3\xfb\xf2\xea\xf5\x44\x53\xe2\x15\x58\xb4\x84\xaa\xc8\x09\xa8\x64\xe0\x95\x35\xb4\x9d\xb3\x20\x79\xdb\x05\xc0\x83\xf3\xc3\x71\x50\x5d\x6f\xcc\x6e\xf0\xe0\xc2\xb6\xb8\xeb\x6a\x74\xb4\xed\xbf\xb5\x74\x56\x75\x81\x4e\x74\xb7\x5c\xc9\x42\x54\x22\x85\xb2\xba\x52\x8f\x2b\xc1\x12\xb3\x7d\xff\xa5\x4f\xde\x77\xe3\x4d\x28\xdb\x47\xbd\xe6\x37\xab\x36\x20\x8d\x8a\x47\xba\x9a\x40\x6e\xa8\x2d\xfa\xc3\x9d\xf8\xad\x6a\xfe\x96\x5c\xcb\xce\x49\x04\xc6\x58\x28\x6b\xfd\x00\xb0\x22\x9f\xb3\x73\x9a\x43\xfd\x72\x25\x3e\x4a\x58\xdd\x2a\x68\xbe\x49\xa4\x84\xe8\xdc\xfd\x6a\x42\xcd\xdc\x14\xe2\xeb\x54\x95\xa1\x95\x7f\xdc\xb9\xf5\xce\xe0\xc8\xdf\x57\xcb\x09\xb4\x78\x4d\xb6\xd7\x48\x70\x56\x78\xf5\x95\xc2\x8c\xa9\x9d\x93\x31\x83\x6c\x6c\x60\x14\x90\x56\x40\x6c\x02\x6c\x13\x21\x98\x6a\x82\x71\x3a\x33\x82\xf7\x81\xb5\xd9\xd8\xab\xa9\xf9\x2f\x72\xb7\x4d\xa8\x0a\xd0\x78\x76\xa5\x6b\x18\xff\x1b\xa5\xfb\x41\x92\x43\x4a\x0f\xc7\x6d\x18\x25\xbf\xe9\xed\xb1\xe8\xee\x6c\x4d\x8d\x1c\xc4\xb0\x85\x1d\xfc\xe8\x63\xe9\x8e\xf2\xaf\x73\x17\x53\x4a\x77\x1e\xf2\xd2\x15\x24\xc7\x98\x5e\x78\x6c\x3a\xf7\x72\x52\x77\x23\xf8\x66\x1b\x6d\x77\x14\xa2\x5f\x90\x2d\x2c\x79\xaf\xf3\x37\xe7\x6c\x7e\x95\xc4\xfe\x9a\x99\xc4\x69\x2b\x25\x6b\x95\xaa\x7a\xa8\xcc\xa0\x0e\x8b\xb5\x10\x99\x86\x95\xbc\x46\x30\x60\x11\x31\x27\xc3\x87\x45\x01\xe6\x62\x0a\xdd\x8e\x66\x24\xbc\x79\x4a\x6f\x35\xa5\x9e\xa7\x9c\xd6\x9e\x4b\xa0\x2d\x9e\x0c\x15\x3a\x81\x9f\x90\xf8\x71\x31\xfe\x73\x1a\x6f\xf6\x73\x76\x8f\x38\xc0\x21\xed\x71\xda\xae\x4e\x7a\x4d\x3f\x8a\xc5\x3f\xa0\x13\xfb\x71\xa6\x7a\x11\x7f\x30\xe3\x9b\xbe\x8c\x9a\x39\x24\xdf\x2b\x21\x58\x9a\x20\x95\x10\xcc\x56\xe9\xd5\x24\xe3\x36\x32\x54\x58\xa1\x1b\x5c\xb3\x25\xbe\xa2\x0b\x00\x54\x95\x19\xb7\x2c\x84\xc2\xf8\x8f\x0b\x3b\xa0\x41\x2c\xcf\x95\x7a\x3a\x0d\x44\xd7\x5a\x5d\x31\x78\x44\x01\x4b\x6c\xfe\x11\x3f\x9a\x20\xbd\x0f\x39\x64\x39\x4b\x51\x13\x7e\xd0\xfd\xb8\x55\x27\xa9\x0d\x5a\xc8\x6a\xae\x7d\x42\x77\x6f\xa0\x48\x1b\x64\x7a\xd9\x4a\x3b\xf9\xe2\x02\x15\x61\xb6\xa8\xac\x12\x4a\x00\xc2\x1d\x5d\x6e\xe1\x68\x9f\xd5\xbe\x4c\x89\x8d\x04\x14\xa3\x1b\x08\x5f\x2a\xb7\xcb\xa6\x7b\xa9\x14\x02\x62\x7c\x3e\xc6\xf8\x38\x98\xd4\x70\x41\x75\x6b\x26\xa3\xc0\xea\x3c\x2b\x04\xf9\x11\xcf\xc4\x18\xbd\xef\xab\x37\x15\x04\x7a\x77\xad\x36\x33\x9b\xaa\x5a\xcf\x7d\xac\x8e\xa8\xa3\x2f\x19\x0c\x0e\xa3\x5f\xa4\xb5\xf2\x59\x2b\x76\xf1\x29\x6c\x9e\xf8\xe1\xd1\x6a\xaa\x77\x77\x11\xfb\xbf\xeb\x65\x63\x07\x68\x53\xaa\xe8\x2e\xc9\x6f\x63\x71\xb2\xb7\x53\xbe\x5c\x9f\x52\x06\x2f\xf3\xd5\x89\x28\x8c\x4a\xb9\x1f\xef\x77\x4e\xbf\xc0\x6a\xe4\x4f\xd3\x66\xc5\x93\xd3\x64\xe9\xd3\xee\x07\x55\xcb\x52\x42\x25\x40\xe2\x6f\x75\xf4\xe8\x7f\x87\xf8\x66\xcf\x1a\x35\x8e\xd4\x73\x23\xd4\x95\x8c\xd7\x60\xe7\x3b\xa9\x97\xee\x26\x76\x63\x29\x8d\xf2\x1e\x86\x31\x07\x90\x94\x76\x26\xdc\xd9\x09\xe4\xd0\x53\xf9\x6f\xe4\xbd\x25\x05\xe6\x54\x12\x0a\x5d\x4c\xfc\x3e\x53\x54\xe4\x6d\xed\xc7\x95\x70\x27\x24\x1e\x84\xa5\x57\xe5\x66\x2d\x04\x93\x3f\x5a\xb4\x4f\x49\xb1\x50\xe3\x3f\x32\xd7\x60\x93\x2a\xdd\xdd\xba\x30\xe8\x5a\x3f\xb5\xcb\xb7\x9f\x97\xd5\xeb\x17\xd9\x3f\xc6\x98\x9e\x48\x56\xe4\x74\xcc\x2b\x25\x76\x6b\xa7\x00\xa5\xc2\x7d\x12\x6c\xa3\xc4\xff\xb2\xfd\xb6\x18\x33\xb6\x84\xdc\xc6\x6a\xd4\x9b\x1c\xa0\x76\x92\x6c\x21\xb0\x9a\x07\xda\xa2\x09\xdd\x3b\x78\xb5\xb5\x47\xd9\x45\xf7\x70\xea\x4c\xd9\x4a\x47\x15\x2e\x6f\xd3\x2a\xcc\x70\x10\xb8\xa6\x0a\x8d\x82\x3c\xb3\x0a\x37\xd0\xb5\x4c\xc7\xb2\x3a\xf3\x61\x32\x79\x5f\x65\x58\xf2\x2e\x43\x25\xd8\xde\x0c\x5a\xcc\x4d\x74\x09\x01\x7f\x31\x18\xa0\xe4\xd7\x6f\x75\x71\x9a\x28\xbf\xcb\xe1\xba\xde\x9c\x6d\x07\x6e\x7b\x4a\xbf\x91\x6b\x97\xb3\xa7\x4b\xee\x6c\x8e\xff\x34\x44\x60\xa2\xa3\x34\x7e\x4c\xbb\xfb\x95\x3b\x84\xc9\x6f\xec\x4c\x96\xff\xe7\xdf\xd8\x04\x30\xb1\xe4\x02\x5b\xfa\xb9\x99\x18\x96\xed\x64\x5a\xee\x24\x27\x4a\x82\x89\x69\x16\x0a\x07\xa3\x75\x1b\x2b\x09\x8b\x09\x7a\x1b\x04\xf7\x25\xfc\x49\x94\x7d\x4f\x6d\x26\x8e\x8b\x3f\x1b\x23\x0d\x06\xa4\xaf\x23\x38\x21\x51\x02\x0b\x9a\x31\x47\x68\x82\xa6\x2e\xd9\xe1\x2c\x04\x36\x79\x47\xbc\x58\xff\xf1\x25\x69\x17\x99\x0c\x7a\x05\xcc\xbc\x47\x18\x33\xec\xbd\x06\xa8\xc7\x30\xd8\xcc\x47\xa3\xce\x60\x91\x95\x7b\x46\x9d\x41\xc3\x90\xcf\xed\x61\xce\x6d\xbe\x59\x32\x1a\xf8\x1d\x00\xc9\x57\xf9\x8c\x4f\x1d\x10\xaf\x91\xdd\x5e\xbe\x43\x0c\x4a\x4b\x36\xb8\xfa\x39\xc9\xf6\xe9\xca\xce\xd7\xe9\x74\xf3\x4a\x86\x0a\x5e\x02\x05\x61\x23\x5f\xf5\x3f\x4b\x41\x16\xe2\xbb\x5f\xc9\x70\xc9\xde\xb3\xfb\x1c\xc7\x76\x39\xf9\x00\x54\x33\x84\x34\xcd\x2c\xd7\xea\xc9\xd4\x35\x8e\xcf\xba\xba\x8e\x5f\x4e\x21\x5d\x84\x2c\xc2\xbf\x5b\xb6\x97\xb1\xe5\xa3\xc9\xf9\xc3\x67\xcb\xea\xaf\xf6\x61\xf6\xa2\xc1\x6b\x0a\x3f\x92\xa3\xf7\x25\x74\xa4\x77\x67\x1d\x1c\x95\x05\x76\x4a\xf8\x50\x1e\x71\xbc\xaa\x01\x03\xd0\x62\x74\x4d\xcd\x3a\xc3\xce\x25\x90\x80\x4c\xff\xf0\x2d\x10\x48\xdc\xaf\xe0\xfd\x55\x73\xa1\xf7\xa8\xe7\xf5\x6b\x97\xd4\x19\x0d\x3f\x67\xb0\xf8\x08\x41\xcb\x5f\x1a\xdc\x98\x18\xe9\xcd\x3c\x8d\x20\x1f\xe7\xaa\xb8\xc9\x91\x99\xde\xd4\x50\x29\x38\xd4\xe4\xd6\x63\x39\x40\x6b\x38\x90\xf5\xdb\x0f\x41\xd3\xe7\xca\x79\x64\x8b\xd4\x7d\xd3\x61\xfc\xcd\x6b\xf9\x75\xc5\x89\xdd\xc3\xc4\x9d\x4c\x0f\xad\x8e\x71\x17\x18\x82\xe9\xf6\x27\xfd\xa1\xe5\x5c\x39\xac\x79\xbf\xc4\x0c\x61\xd5\x80\x3f\xb1\xb7\x71\xea\x9a\xb0\x2c\xdb\xe4\xcb\xbf\xd1\xb8\xb9\x0e\x96\xf3\x53\xed\x53\x22\x16\x54\x53\xac\xc1\xf9\x5f\xf2\xeb\x92\xbe\x9b\xae\x81\x32\x4b\x86\xa0\xe6\x3d\xfc\x5b\x1e\x3a\x1b\x2c\x9f\x5f\x55\x05\x16\xdc\xd8\x78\x94\x7a\xd8\xfb\x85\xa9\xef\x7d\xae\xd3\x52\xcf\x4c\xbe\x92\x8f\xb1\xf2\x50\x35\x71\x93\x43\x12\x7f\x01\xe5\x03\xab\xf8\x15\xc4\x09\xa4\xb8\x5c\x07\xe3\x3f\x34\xd1\xa4\xf2\xd3\x5e\x62\xe3\x3f\x21\x4e\x0b\x25\x80\x92\x90\x48\x91\x5c\xfa\x08\x66\xf1\x41\xa6\x9b\x55\x05\x26\x10\x37\x31\xf8\xa2\x6c\xd8\x8f\xd6\x1d\xc5\x15\x7b\x48\xd8\x3e\x9b\x5a\xaf\x06\x3f\x50\xc3\xf4\xa3\x85\xc4\xf1\x6d\x45\x11\x0d\x86\x15\xa5\x53\x4c\xaf\x2b\x04\xf0\x72\x5d\x8a\xfb\xa0\x40\x08\x91\x0e\xca\x9a\x94\x7f\x08\xe8\x63\x61\x91\x1d\xa6\x2c\xe9\x94\x87\x99\xff\x75\x81\xb9\x7c\x28\xed\x0a\x64\x7f\xf4\x7c\xc1\xae\x93\x14\x80\xcc\x52\xb5\xea\x05\xe2\xe7\xe4\x47\x28\xc0\x51\x5a\xe7\x49\x71\x08\xdd\x7c\xde\xb0\x90\x84\xe2\xad\x86\xe1\xd5\x18\x77\x3e\x9d\x02\xcc\x2c\xd7\xd0\x26\x3e\x43\xdc\x76\xf3\x41\x07\xab\x6f\xd1\x60\x4b\x0c\xfe\xe5\x8d\xa0\xd5\x7a\xde\x38\x8f\xa6\x15\x76\x6f\x49\x8c\x04\xfa\xdf\xc4\x81\xb6\x9d\x92\x09\x84\x7f\xc3\x38\xaa\x04\x8f\xa7\xd4\x07\x48\x52\x98\xa9\xe4\x3d\x53\xba\xeb\x46\x24\xe1\x70\x53\x99\xc1\x22\xe2\x6c\x47\x63\x09\x77\x4b\x90\x70\x19\x5a\x44\x06\x16\xbe\x97\x39\xbc\x38\xa2\x5d\x5f\xf2\xba\x2c\x7f\xf6\xe7\x96\xfb\x41\xdf\xc2\x73\xe3\x10\xd6\x35\x86\x3b\x01\x3f\x31\x6a\xfd\xf1\xeb\xfd\x8c\xcb\x5f\xbc\xfe\x0f\x86\x40\x38\x64\x7f\x04\xab\x29\x75\x86\xd3\x96\x9f\x74\x11\x27\x7f\x6a\x91\xcc\x66\x73\x1c\xb3\xd4\x1e\xb2\x3e\xc4\xb8\x30\xcb\xbf\x5d\x75\x45\x14\x19\x14\x34\x30\xd3\xc0\x66\x5d\xb2\x9b\xda\xbf\xcb\x8a\x57\x05\x51\xa3\xb4\x50\x9b\x05\xab\x64\x70\xf2\xa8\x93\xba\x54\x0b\xb3\x9b\xb8\xe5\x0a\xf6\xe0\x0d\x08\x2e\x78\xe8\x89\xaa\x08\x11\xf0\x0b\x3d\x58\x0e\x5c\x33\x12\x21\x3c\xeb\xa2\x22\x9d\xe6\x2b\xc6\x76\x1e\xd0\x44\x55\x20\x2b\xcb\xe8\x6a\x27\x02\xe1\x20\x67\xd0\xbf\xc2\xe2\x0a\x02\x33\x9c\xe2\x3f\xf8\xe5\x3d\x04\x3f\x94\x4b\x4b\x49\x50\x45\x6a\x74\xc7\x3a\xda\x49\x28\x07\xc6\x87\x07\x4a\xf7\x6c\x1b\xa7\xfb\x24\x27\xd8\x92\x0e\x6e\xd1\xb0\x46\x8e\x06\x85\x2c\xdc\xe9\xa4\xc2\x8b\x0f\xe3\xca\xe5\x65\x31\x17\xf7\xca\x1f\x9e\x2a\x82\xa6\xa7\x12\x54\x90\x15\x7e\xf2\x27\x80\x81\x60\x9a\x70\xea\x8e\xf1\xb7\xdb\xbe\xa7\x53\xe2\x4e\x82\xa5\xdd\xd9\xb8\x10\x84\x46\x1a\x1f\x61\x50\xe0\x73\x73\xd5\xb3\x1f\x77\xdb\xe6\x44\x4e\x4f\xfc\x44\x20\x89\xcb\x7d\x0a\x4a\x68\x59\x39\xf7\x1a\xde\x07\x2d\xa2\x95\x50\x53\xb5\x7b\xe9\x40\xe8\x8f\x01\xbe\x1f\xa1\xbe\x21\xf3\x63\xa8\x23\x44\x72\xbd\xc1\x5a\x53\x49\xf9\x18\xfa\x49\xa7\x08\x3a\xea\x1f\x99\x7c\xb8\xb9\xdd\x14\x34\x08\xc3\xa9\x91\xa6\x3b\x5d\xe7\x7f\x9d\xd4\x87\x2e\x7e\xa4\xea\x16\x58\x08\x30\x62\x0a\xce\x0f\x58\xdc\xa7\x47\xfe\x38\x0f\xc2\x1c\x17\x19\xfb\x5e\x3f\x02\x41\x0c\x5d\x30\x94\x0f\xea\xae\x0c\x3e\xa9\x5b\x3d\x86\xa6\x30\x75\xdb\x97\x00\x1d\x96\xfa\xa3\x65\xb7\x99\x00\x44\xe5\xc0\x25\x94\xb3\xad\x58\xd2\xf0\x3f\x4a\xcd\xe7\x35\x68\x93\x53\xab\xfc\xb4\x39\x75\x01\x41\x4b\xd1\x87\xa7\x52\x73\x25\xe4\xd9\x6d\x7f\xb0\x27\xd4\x45\x21\x65\xd2\x8f\xa5\x51\xd9\xf9\x5f\x67\xe9\xa7\xc6\x97\x50\x4f\x68\xc8\x90\x55\xb6\x7d\x22\x3d\x74\xc2\xcd\x06\xf8\x61\x5f\x82\xa6\xbc\x28\x33\xc8\x86\x17\x50\x83\xf1\x94\x12\xed\x0a\xc9\x81\x3d\x98\x3a\xdc\xd4\xe7\x65\xe2\x1b\xd2\x50\x7c\xf8\xe0\x3c\xf5\x6b\x19\x78\x48\x18\xf8\xf0\xfd\x95\x5c\x5d\x22\x8a\x1b\xf1\xfc\x14\x84\x5a\x2c\xde\x16\x32\x07\x4a\xbb\xbb\xb0\x16\x9b\xc9\x4f\xc1\x6a\xaa\x51\xa0\xfc\xb1\xae\xee\xd3\x20\xc1\x29\x9e\x48\xbf\x8c\x57\x6f\x22\xe8\xb0\x18\x15\x90\xdf\x63\x67\xd0\x21\x16\xf6\x15\x2b\xd9\xeb\x7b\x0c\x6c\x01\xf1\x7f\x6f\xd6\x38\x81\x3c\x14\x6a\xa5\xdc\xfa\x3e\x3b\xff\xaf\x91\xb6\x6e\x9b\xf2\x64\xbc\xe9\x17\xe7\x13\x49\x89\x30\x30\x89\x01\x44\xcc\xfc\x6f\x97\xe3\x7e\x03\x99\x40\xdf\x69\x25\x29\x05\x1b\xd9\xcd\x40\x77\x5e\xb5\x8a\x83\xe5\x13\xe5\x8c\x2a\x04\xa3\xd8\x45\x88\x55\x5f\xb9\x12\x4a\x72\x4b\xf1\xa7\x14\x56\x1e\x18\x3b\x26\x7b\xf6\x01\x78\xf7\x78\x99\x6a\x06\x03\xc6\xbf\xc0\xb8\x7a\x26\xe4\xa4\x66\x96\x29\x4e\x61\xe9\x0b\x63\x6a\x05\xe7\xff\x4e\x5e\x2b\x46\x84\x53\xdd\x80\xae\x96\x3b\x77\x4b\xee\xc3\x32\x33\x94\xa6\x4a\xe9\x64\x53\xb2\x2c\xb9\xce\x1d\xbd\x46\xfe\xc2\x4c\x71\x32\xbd\x12\xf7\x4b\xf4\xa9\xf3\xdb\x22\x8d\x65\x79\x46\x66\xdb\x83\x7c\xd6\x39\x91\x9d\x6a\x96\x2b\xeb\xd5\xbd\x27\x78\x3d\x54\x98\xa5\x9b\x68\x8d\x08\x81\x20\x87\x10\x43\xd5\x52\xb2\x64\x25\xb7\xe5\x3b\xb1\xca\x56\x02\x64\xa0\x7c\x1a\x34\x4a\xfb\x33\x9b\x2a\xb1\x39\xd7\xa2\x7e\xda\xf8\x2f\x4d\x43\xeb\xb9\xda\x60\x97\x34\x14\xc3\x2c\x2d\xc1\x50\xdf\xa2\x4d\xdd\x87\xe1\xd8\x3d\x70\x85\xa0\x15\x05\x87\x98\xda\x0c\x4e\xe0\x7a\xc8\x32\x2f\x4e\xd6\xcc\x58\xda\x7c\xaf\xcb\x97\x5c\xe3\xba\x19\xd7\x88\x3b\x4d\x1d\x78\x62\x50\x1f\x3d\x5f\x93\x85\x73\xc8\xe8\xc9\xa9\xb4\x64\x6b\xe3\x23\xab\xbd\x1b\xda\x8e\x79\x7b\xf7\x0f\x75\xef\x96\x6a\x2d\xb4\x8c\x7e\x53\x50\x5c\x2a\x7f\xe1\x31\x24\x71\x2f\xe0\x49\x77\x64\xf3\x2a\x69\x25\xee\x29\xfd\x18\xbd\xe9\x39\xf3\x93\x9d\x85\x8a\x98\xc7\xe9\x29\x2e\xe5\x2e\xaf\x05\xfa\xd3\xdc\x02\x75\xb8\xdb\xaf\x19\x3a\xd9\x65\x3f\x29\xc3\x2a\x57\x09\x12\x6e\xad\xc1\x05\xeb\xd5\x12\x1e\x63\x8a\x6f\xa3\x54\x4e\xeb\x53\xe7\xc1\xfd\x78\x4d\xe7\xf3\x53\x02\xcb\x19\x87\x0c\x1f\x2a\x67\x96\x25\x1d\xee\x3d\x40\x23\x7c\xb0\xb7\xd3\x59\x5a\x3c\x98\x7f\x12\x02\xff\x44\x55\x7f\x43\x3e\x65\xee\x10\x08\x18\xe6\xfe\x8d\x0c\xd5\x21\xc9\x8e\x7b\x31\x24\x81\xb2\x32\x9b\x91\xfc\x0d\x86\x08\x65\x97\x30\x33\xdb\x3a\xdb\xc5\xd3\x63\x93\x59\x49\x16\x77\x7a\xc8\x73\x23\x62\x65\x7e\x54\xc4\xa1\x92\x15\x96\x38\x82\x1c\x6a\x26\x5f\xce\x0d\xdd\x45\xe4\x8c\x3c\x66\x94\x08\xc7\x90\xee\x96\x76\x8a\x13\xfd\x61\x6c\xe0\xe3\x84\xf0\x44\x0a\x27\xe9\x1d\xa6\xc3\x4a\x10\xe8\x2b\x7d\x21\x0c\xb1\x28\x7f\x57\x24\x86\xf0\x1c\xa8\x7c\xe8\x92\xd9\xec\x9e\xaa\xdc\xcb\xe7\x4b\x24\x24\x66\xf0\xe0\x33\x18\x5c\x71\xaf\x4d\xcb\x92\x14\xbc\x55\x40\xdc\xe1\x6d\xe4\xae\x66\x1f\xdf\xcf\xbd\x8f\x79\xc8\xbd\x37\x2e\xef\x5e\x4a\x39\x4b\x38\xf0\x3c\xb5\x0a\x94\xf2\x9d\x73\x25\x03\x95\x2a\x50\xc0\x67\x6d\x61\xdf\x43\x24\x85\x90\x87\xec\x61\xa2\xa3\x25\xfe\xc4\x04\x0e\xb1\xcc\x7f\xa6\x98\x86\x9f\x34\xee\x87\xf8\x0b\x5b\xd8\x65\xf5\x54\x8a\xd9\x59\x6f\x1f\xbc\x57\x79\x59\xa3\x02\x64\xba\x92\xcb\x45\xab\x9f\x59\x03\xbd\x24\x3f\xd1\x33\x00\xe1\x3f\x0c\xac\xc7\x92\x10\x0d\x72\x3c\x50\x2f\x93\x2f\x03\xb3\x21\x3f\x17\xa2\x73\x7a\xec\x2e\x55\x36\xa5\x43\x7f\x4a\x96\xaf\xcc\x03\x47\xba\xd3\x0c\x34\x49\xea\x54\x7e\x5c\xce\x2f\x17\xec\xaa\x15\x62\x79\xa8\xe8\xda\x10\x9f\xb8\xbd\x02\xaa\x08\xbd\xca\xe8\xfe\x0b\xa0\x58\x5b\x92\x53\xff\xcf\xec\xfe\xff\xe5\x39\xf1\xef\x4e\x8e\x3b\xed\x3f\xb2\x51\xca\x6f\xc0\x76\x33\xd7\xd4\xb3\x38\x74\x26\x83\x7f\x59\xd6\x73\x9e\x43\x10\x22\xe0\x00\xec\x30\x9e\xfb\xed\x6a\x36\x8a\x4d\xb1\xb1\xb5\x75\x53\x57\x31\xe0\x87\xf9\xd3\x96\xd2\xe7\xf6\x3f\xe9\x44\xeb\x31\x34\x04\xa3\x37\xf8\x04\xf0\xe7\xa6\x1c\x24\xf8\x9f\x53\x9d\xb1\x41\x6f\xb2\x4e\x2e\x41\xbf\x38\xa7\xca\x01\x2d\x47\x19\x6f\x9b\xf1\xa8\x79\x77\x9d\xc1\xdf\xd8\xe1\xe3\x11\x9a\x66\xe9\x3a\x9a\x21\x1a\xfd\xbe\xd1\x78\x9a\x80\x19\x81\x58\xd1\x43\xcf\xd0\x94\x8b\x2a\x0e\x5d\xd5\x21\x2e\x39\xe7\x84\x03\xc4\xa4\xc8\xbf\x25\xce\x03\x77\x4a\xaa\x28\x53\x8a\xbc\x05\xdb\x80\xb4\x08\x86\x23\xd9\x71\x7b\x1c\xdf\x63\x4b\xd9\x4f\x8d\xb8\x17\xc2\xb4\x5f\xe8\x95\x6b\x67\x9f\x8a\xae\x22\x83\xf2\x81\xe5\xdd\x4f\xad\x8a\x16\x8c\xdf\x29\x4a\x61\x5f\xd4\x05\x96\x6c\xee\xd8\xad\xd2\x76\xe3\xd4\x63\x0e\xb9\x5c\x8c\xdc\x23\xe7\xf8\x94\x7f\x81\xdd\x9d\xe3\xec\xf7\x2e\xcc\x8b\x50\x64\x88\xcb\x40\xda\x68\xf5\x89\xfe\x92\x66\x3c\x0c\xf8\x38\x7a\xc1\x1e\x01\x01\x32\x91\xa2\x0e\x6f\xdd\x4b\x8b\x61\x7a\xb9\xf2\x71\x08\xba\xa3\x76\x97\xf2\xaa\x59\x0e\xc7\xa9\x14\xa0\x64\x27\x34\x2d\x0d\xe7\x09\x2c\x74\x13\x90\xa5\xb2\x2f\xee\x77\xfd\x4e\xf2\xa1\x54\x56\xe3\xa6\x62\x71\xdf\x77\x59\x46\x84\x70\xd5\x45\x09\x30\x60\xd1\x77\x96\x53\x37\x7d\x1f\xd2\x54\x73\x9f\xc2\xf0\x88\x14\x8a\xdd\xfe\x25\xfb\x24\x13\xbc\xa7\xe8\x17\x68\xd0\x01\x05\x59\xd5\x39\xd5\xb1\xb3\xf1\xb8\x52\x18\xa7\x36\x76\x3a\xdc\x7b\xff\x2d\xfd\x5b\xc1\xad\x44\x99\xa3\x64\xdf\x4c\x51\x5a\xf6\x23\xbc\x9c\x67\xa7\x32\x22\xc1\x26\x0c\x1f\x90\x15\x6b\xb3\xef\x69\x1e\x65\x9a\xe4\x2e\xef\x16\x0d\x5b\x68\x81\x3a\xa7\x99\x2d\xe6\xb8\x5d\x5c\x95\xad\x1e\xfc\x50\x21\x54\xee\xb9\x41\x14\xb6\x6a\x5f\xf6\xb0\x5e\xf1\x8c\x7e\x0f\x56\xf1\xd6\x97\x7c\x43\x19\x0f\xfb\xe4\x5c\x2d\xfe\x5b\x28\x67\x21\x88\x64\x39\xb9\x63\x56\x6f\x60\xcd\x66\x6f\x37\x61\x1f\x0f\x53\x3f\x2c\x58\x01\x55\xec\xba\x71\x80\x7a\x4c\x9e\x0a\xaf\x46\x63\x4a\x4c\x6b\xeb\x07\x4e\xa1\x64\x38\x51\x72\xaa\x96\x66\xa4\x6a\x7d\x49\xfe\x2a\xd4\xba\x69\x73\x22\xa2\x6c\x56\x27\x69\x35\xe6\x7b\x2d\xb1\x2e\x1a\xf1\x65\xcd\xd6\xce\x1a\x98\x79\xa0\xb6\xb4\x65\xd6\xaa\x5a\x00\x8f\xa7\x94\xed\xf4\xfa\xe2\xcd\x62\x57\xb6\xb5\x9f\x5e\x76\x38\xf7\x08\x9f\xde\xe6\x5e\xee\xec\xf9\xa5\x90\xd0\x20\xc2\xb2\xf3\xd3\x97\xde\x66\x81\x95\x17\x44\xba\xad\xdf\x45\x8a\x81\x3b\x3e\xcf\x52\xfc\x2b\xf5\x2b\x11\x31\x77\x8c\x23\x76\xca\x50\xa3\x6e\xe9\xa5\x40\x9f\xcb\xe9\xf4\x1a\x45\x38\x81\x87\xd4\xc5\xb4\xc8\xe9\xd9\xa5\x29\x74\x3b\xf9\x0c\x9b\x8e\x20\xeb\x43\x8b\x8d\x0f\x61\x8a\x08\xe4\x4b\xcf\xcf\x66\x49\xa1\x1b\x8b\x3a\x81\x37\xbb\xb2\x6a\x2e\x92\x57\x1a\xde\x02\x8e\x69\x01\x07\xe4\x7f\x9e\xd6\x8f\xe5\x90\x83\xff\x98\xb9\x2a\x87\x45\xd7\x6e\xd2\xf7\x84\xf9\xab\x5a\x75\xb8\xf4\x2d\xa9\x51\xd6\x00\x0e\x45\xfb\x68\xae\x96\xbf\x33\x2a\xc0\x51\x79\x64\x3b\x28\xc0\x4c\x9f\x8e\xa0\x26\x25\x75\x20\x12\xe1\x36\xa3\x6f\xac\x4c\x0c\xb3\xa6\xe4\x94\xef\x63\x69\xef\x97\x20\x7a\x93\x69\xbb\x4b\xb6\x64\xcc\x73\x28\x7b\xa8\xbc\x32\xbe\xe1\x67\xf9\x76\xb2\x9b\x6e\x36\xcb\xf8\x21\x3e\x92\x8b\x87\x31\x6c\xc4\x62\x55\x27\xe6\x1f\x9d\xeb\x3f\x65\x33\x08\x97\xf4\x93\x1a\x6a\x10\xea\x6b\xed\xaf\xc1\xfd\xd1\x73\x1e\x78\x5e\x8d\x37\x50\x1c\xcc\x82\x01\xa4\x73\x0e\x32\x2f\x10\xc3\xa3\xa7\xf7\x50\x0f\x0d\x64\x28\x32\x1c\x1a\x2e\x56\x9e\x6f\xdf\x84\xae\x87\x46\xf9\xbe\x53\x85\xc5\x29\x6a\x53\x93\xd3\xea\x54\x6a\x44\x68\x39\xf3\xf8\xb3\x73\x0b\xa7\xdb\xb2\x94\x49\x2f\x40\xe9\x41\x90\x05\x90\x4a\x4d\x50\xe8\xbc\xe9\x73\x1c\xfa\xf2\x7f\x37\x75\xe4\xec\xe6\x08\x2c\x6c\x68\x89\x59\xb8\x69\x00\x5d\x7b\x72\x2e\x1b\xd9\x0e\xe0\x7d\x6a\x90\x60\xd5\x24\x8d\xf4\x4b\x8a\x82\x82\x00\x6b\x73\x80\x27\x36\x48\x1e\x96\xe3\x7c\x4c\xd1\xde\xc6\x80\x3e\x29\xc4\x97\xa2\x99\x53\xd5\x07\x0a\x2a\x26\x9f\x27\xcc\x61\xa4\x1f\x72\x56\xeb\xae\xfb\x56\x5b\xec\xf0\xa4\x2f\x27\xb4\x1f\x76\x97\x4e\x90\x1f\x7b\x6e\x45\xdf\x2f\x1c\xef\x35\xf9\xd7\xa3\xe5\x3d\x3c\x75\x3b\xcf\x17\x30\xe0\xa9\x24\x19\x7d\xbf\xfe\x4a\x86\x75\x79\xdc\x53\x55\xe7\xc6\xb8\x7f\xd1\xdc\xff\xa1\x1f\xb5\x98\xcd\xea\x9b\xea\xff\xf6\x82\x18\xc1\xd1\x72\xfd\xe2\x1e\x22\x38\x4b\xb7\x6c\xd7\x91\x8c\x92\x89\xfb\x07\xbd\x42\x90\xb5\xb0\x81\x6f\xa6\xea\x54\x18\x40\x65\xb7\xa3\x15\x56\x22\x89\x80\xaf\x73\xd3\xa3\x99\x1e\x4d\x45\x05\xa3\xee\xa4\x1c\x7f\x77\x1a\x22\x80\xc2\xfc\x9e\xdc\x40\x3c\xc2\xfb\x92\xd5\x41\xa7\x11\x0e\x21\x02\xc1\x3c\xb0\x80\xaa\x56\x40\x0d\xa7\x2d\xbe\x29\x3c\xd0\xbd\x80\x78\x50\xba\x3d\x4a\x44\x2e\x74\xd9\xb9\x4c\xeb\x50\xf2\x7c\xa9\xac\x9c\x61\x46\xc6\xb7\xec\x7e\x62\xf5\x15\x7b\x8d\x5d\x28\x6b\x85\xc9\x19\xaf\x90\xf6\xdc\xaa\x22\x5a\x6f\xad\x75\xe4\x93\x91\x16\x5f\xbd\xc4\xd6\x79\x33\xb0\x45\x91\x28\xa3\xc3\xab\xe7\x61\x24\xa0\x07\x23\x43\x2d\xb9\xb0\xc7\xf7\x69\xfb\xd6\xff\x6f\x47\xf3\x8b\x4f\x8b\xb3\xa1\x17\xa8\x99\xff\x10\xc4\xc1\xca\x6e\x0c\x39\x55\x67\xc8\x90\x4b\xd5\x70\x3e\xea\x0b\x48\xad\x18\x85\x90\x56\x76\xab\xa1\x46\x2c\x90\xeb\xb2\xc4\x4f\x40\xb8\xf7\x1f\x9f\x9c\x1f\xb6\xe9\xe1\x09\xfe\x7e\xb8\x89\x58\xae\x41\x4f\xf7\x83\xbb\x2c\xf7\x10\xad\xf8\xa3\x9c\xe7\x01\x7a\x2a\x37\x0d\xe9\xf5\x33\x44\x4c\x40\x32\x2b\x18\xf6\x46\xee\x10\xf2\x73\x8a\xb7\x8c\xdb\x17\x47\x3a\xc4\x0c\x1a\xa8\x0c\x6f\x75\xfa\x3e\x51\x53\x97\xaf\x5b\xd3\x3e\xf4\x0a\xc3\x92\x15\xee\x6c\xf2\x3b\xdb\x4b\xac\xaf\x68\x58\x04\x5f\x93\x8c\x12\x1a\xec\x7c\x6a\xf9\xb3\x3f\x56\xda\x46\x97\x40\xda\xad\x63\x45\xc0\xa0\x55\xc8\x1b\xa0\x88\x75\x71\xa5\xe8\x17\x71\xeb\x95\x24\xd0\xf4\xe9\x06\x5c\x07\x26\xb8\x54\x79\xf1\xae\xe5\x65\xd9\xc6\x46\x28\xf9\xfd\x16\xd9\x3b\xaf\xa6\xde\x6c\xe8\x4e\x4a\x0b\x25\x23\xbf\xe3\xdf\x7b\x8f\xd2\x4b\xa2\xaa\xab\x50\xb3\x9c\x3e\x88\xa3\x94\xf6\xc1\x30\x08\x63\x65\xd9\x31\xcc\x93\xaf\xfe\x17\x61\x59\x4b\x70\x9a\x01\xeb\xd0\xb2\xa5\x75\x1a\x93\x7a\xe0\x61\xd8\xc2\x3d\xd7\x77\x80\x66\xc3\xa8\xd1\x42\x7d\x20\x28\x7d\x07\xfb\x73\x90\xca\x9b\xe7\x72\xc7\xfb\x22\x7f\x81\xcd\xc1\x9b\x1e\x25\xcb\x24\xbe\x73\x49\xe2\x53\x9d\xec\x1c\xd9\xd2\x56\xc7\x78\xbf\xa7\x25\x34\xdb\xfa\xba\x00\x82\xf6\x76\xa9\xb6\x38\xdf\xef\x09\x12\x94\x72\x9b\xbe\xd2\x23\xd4\x90\xca\x89\xf1\x8c\xba\x68\x7f\x4b\x3e\xa9\xd2\x96\x22\xfb\x67\x7b\x37\x60\xb5\xf8\xe3\xda\x0a\x98\xf5\x6c\x7d\x14\x97\x75\x57\xfb\x53\x4b\x25\x36\xe2\x22\xfd\x67\xc4\x3d\x66\x19\xe1\x48\x0a\x14\x6d\xa4\xf7\x4a\xd3\xd7\x6a\x48\x0b\x35\x7c\x8f\x26\xf6\xea\x2a\xba\xdb\xe1\x6e\x5f\x64\xa5\xc9\x0a\xc0\x69\xbf\xf9\x49\x4f\xeb\x5e\xee\xb1\x8b\x4a\x5a\x2a\x58\xee\x00\x60\x35\x17\xe5\x97\xa3\x29\x89\xb5\x3d\x8c\xa2\x9b\xf9\xc7\x3d\xcc\x4d\x5b\x9a\x92\x72\x4a\xec\xcf\x69\x0d\x7c\x02\x06\xf0\xf1\x89\x24\x82\x1a\x4a\xe0\xb4\x99\x69\x49\x76\x04\x72\x2d\x95\x9f\x3c\xe7\x4e\x3a\x46\x73\xd9\x29\xe1\xd9\x80\x1b\xbe\x23\xbf\x10\x53\xe9\x35\x06\xcc\x36\x3c\x77\x91\x72\xe7\x4a\xcd\xde\xbf\xb0\x65\x5b\x3f\x06\x7a\xa4\xec\x0f\xfe\x0b\x64\x35\xc5\x1c\xfd\xf4\x84\xde\x5d\x7e\xa8\x5d\x8d\xb6\xa0\x31\xd5\x1c\xb7\xc9\x48\x01\xf3\xba\x23\xa5\xa7\xc4\xad\x49\x4c\x1b\xc1\xd8\x5a\x52\x0e\xbf\xba\x6f\xa3\xce\xf0\xc6\x2c\x35\xda\x24\xc5\x8e\x12\xb2\x3f\x87\x0e\xe8\x72\x1c\xf8\x1c\x42\x88\x79\x07\x49\x09\x80\x5a\xdd\x3e\x0e\x9b\xff\xac\x63\xb2\x94\xfd\x4a\x41\xeb\x95\x03\x18\x8a\x0a\x42\xa9\x20\xd8\xde\xdd\x54\x87\xe0\x6e\x19\xe7\xf7\x1b\x97\x8c\x60\x26\x95\x8f\x9a\xb7\x46\xb7\x16\xdf\x90\x52\x1d\x53\xed\x3f\x28\x0f\x6e\xd2\xba\x6d\x23\xac\x5c\x12\xb7\xcc\xac\xcb\x85\xed\x2c\xf6\xb3\x1d\x4e\xc4\xe7\xf2\x35\x8a\xf2\x39\xcb\x91\x10\x52\x75\xd3\x28\xb2\xb7\xdf\x21\xf2\x84\xfb\x28\xf4\x4f\xc9\x9f\xcb\x11\x69\xf6\x77\xa9\xb4\x46\xaf\x34\x6d\x9a\xa1\x55\xe3\x41\xf1\xac\x6b\x28\xd2\xe6\x12\x4b\x55\xad\x80\xc2\x76\xdf\xa4\x5f\x01\x8c\xa7\x0a\xb2\xb2\x72\xa2\x45\x7d\x1c\x65\x26\x53\x39\xc9\x79\x93\xa2\x0b\x33\xd5\xca\x70\xea\x75\x05\x97\x1a\x20\xe4\x72\x2e\xca\x93\xb6\xe0\x94\x9c\x8b\x03\x71\xca\x56\x02\xbd\x93\x94\x88\x77\x1f\x6b\xc9\x12\x48\xa7\x6a\xfd\x67\x54\xfd\xfe\x13\xd3\xf0\x9f\xf4\x64\xc9\x3a\x2e\x46\x8b\xfc\xab\xde\xc7\x7b\xcb\x95\x40\x27\x3f\x07\xa8\xca\xd1\x39\x31\xe9\x50\xa3\x85\x7a\xc0\x15\x67\xcf\xab\xba\xc8\xd6\xec\x07\x16\x17\x52\x10\x18\x94\xff\x95\x0f\xb9\xda\x26\x0f\x99\xc2\x55\x43\x9e\x15\xbc\x5d\x80\x2a\x95\xae\x6c\xa3\x01\xea\xbb\x31\x99\xa6\xf9\x6c\x34\x76\xa7\xa9\xd1\xbf\x52\x3e\x98\x4e\x3f\x8f\x89\xce\x90\x6a\x6e\x3c\x87\xaf\x35\xba\xbb\x16\x42\x7b\xc0\xd8\xeb\x6d\xa9\x7d\x08\xf5\x87\xd1\xea\x03\x13\x78\x94\x43\x37\x72\xb1\x56\x8f\xb2\x2f\x86\x57\x6d\x4a\x4b\x85\x57\x21\xe9\x91\xb5\x47\x1f\x19\x20\xb1\x49\xf9\xf3\x23\x93\x6d\x12\xa2\x2f\x4c\xaf\x7b\x5b\xcb\x9e\xbf\xc0\x4f\xdc\x43\x33\xfb\x5e\x12\x25\xf6\x9d\xb9\xf0\x68\xc4\xd0\xd8\x1b\xfd\xfb\x8e\xa0\x9d\x4f\x0a\x6c\x77\x08\x4c\x19\x02\x4b\xf8\x94\xbe\xf5\x7b\x4f\xa7\x01\x63\x5c\xf7\x2f\xdd\x9f\xfe\xaf\x14\x0e\x7d\x87\xb3\x5b\x46\x80\xb2\x6e\x4f\x11\x50\x71\x8f\xa1\x84\x79\xeb\xd1\xb2\x1f\x76\xbb\x2c\xdf\x99\xdd\x42\x76\x4b\xfc\xf6\x68\x35\xe0\xd4\x89\x68\x4f\x91\xbf\xcd\xf8\x26\xb2\x0f\xac\x2c\x58\x75\x49\xcb\x53\xd1\x24\x63\xb6\x19\x62\xe3\x5f\x68\x58\x67\xb4\x50\xe2\xa9\xa3\x74\xe6\x14\xfa\xc1\xec\xdc\xf5\x95\x22\xcc\x75\xfd\xa1\xce\x13\x5c\x86\xf6\xd1\xec\xae\x10\xee\xd2\x3d\x1c\xe4\x76\x1c\x0a\xe6\x58\xda\x9e\x56\x8b\xe5\xbd\x90\xf4\xfb\x2c\xa3\x2d\x12\xda\x4f\xb2\x9d\x5a\x5b\xb1\x60\xa5\xe4\x5e\xa2\x0d\xfc\xca\xd1\x46\x1e\x97\xb3\x36\x87\xd9\x61\xfe\x27\x05\xae\x1d\xe6\x7b\xb4\x6d\x38\x17\x5f\x6a\xf8\x13\xad\xbd\x32\xd3\x78\x77\xb9\x04\x7b\x60\x2e\x7d\x98\xe6\xde\xc4\x0b\xdc\x75\x5a\x91\x15\xcb\x9f\x51\x56\x4b\xb9\xb1\x25\x0b\x9d\x16\xf7\xb5\x93\x5c\x8e\x9d\x26\xf4\x0f\x01\xd8\xd8\x91\xe8\x09\xc0\xda\x24\x29\x1e\x60\x3e\xae\x06\xf2\x59\x52\xaf\xc5\x79\x6f\xd7\x0d\x8a\xf6\xcd\x76\xf6\xa6\x37\x80\x20\x3f\x33\x71\xb8\x29\xfd\xbd\x79\x68\xee\xa6\xf3\xaf\x44\x0b\xd1\x64\x6f\x45\x89\x9f\xca\x11\x67\x0b\x83\xc9\x2c\xf6\xb2\xa8\x00\xa4\x06\x2c\x4f\x91\xe8\x2b\xe2\x01\x72\x6d\x36\x08\xee\xd3\x09\x3b\xe3\x9b\xf8\xf2\xfe\x31\x84\xfc\x7b\x3d\xc6\x11\x53\xa3\x7d\xdb\x88\xe9\xc6\xcb\x2e\xfd\x65\x73\x5b\x0e\xf9\x37\xf6\xb3\xb7\x64\x9c\x6a\x0a\xfb\xbf\xb4\x4b\x26\x5d\xa2\x07\x32\x42\x70\x3f\x84\xa5\x16\x3f\x58\x94\x50\x19\x40\x8e\x24\x53\x25\x8d\xd4\xab\x9e\x21\xdc\xed\x23\x17\xf6\x54\x1d\xb0\x4a\x35\x3a\x90\x0b\x56\xe4\x5d\x6a\x79\x48\x7c\xca\xdf\xcd\x8c\x76\xb3\x10\x35\x86\x3c\xeb\xc5\x23\x83\x77\x0a\xaf\x2a\x0c\xd3\xf3\xdb\xa4\x32\xf1\x2d\xd0\xd6\x5e\x63\xe0\xce\xd1\xbb\xc6\xed\x7d\x5f\x3b\xdc\xbd\x9e\x58\xfe\x7e\x3d\x90\x94\xf4\xbd\xca\xc1\xaf\x53\xa1\x42\x53\xf1\xab\x50\x42\x8c\xe4\xa0\x6c\xad\x20\x12\x92\xe2\x7f\x54\x8e\x99\x74\x79\x94\x30\x4f\x81\xf2\x05\xcb\x2c\xe4\xbe\xce\xc5\x41\x8b\x59\xeb\x5b\x7f\xfc\x41\xf6\xdb\x8d\x6d\xee\xfb\x3d\x6c\x13\xc7\xc7\xe3\xc2\x9f\x06\xd1\x11\x22\x6c\xfc\xd5\x72\xa9\x13\xe5\x89\x35\xa5\x4f\xf9\xcc\xb1\xe3\x77\x7a\x5c\x74\x5a\xc8\x20\x3a\x8b\x1e\xb7\x50\x40\xde\xc4\xa5\xe0\x78\xa7\xad\x52\x41\x01\x59\x5d\x2c\x8a\x58\x4e\xda\xb0\x29\x2f\xd7\x28\x74\xcb\x3d\xd5\x3b\xe8\x3a\xcf\xc5\x24\xcb\xa9\xd4\xda\x7c\x52\x20\x80\x74\x5c\xf4\xb5\x37\x8f\x14\x25\xd9\x63\x6b\xc7\x17\x18\x4b\x55\xf9\x80\xa6\xfc\x01\x41\x55\x2b\xbb\x4a\x8d\xf4\xad\xba\x54\x90\xfa\x58\x76\x93\x21\xb2\xc7\x55\x58\x40\xd0\x6c\x0b\x78\x80\xa4\x74\x58\xa2\x70\x17\x80\xb9\xc3\x0f\x83\x82\x01\x4f\xbf\x96\xf5\x02\x6a\xa7\xbc\xfc\x96\x6d\x2f\x20\xdd\x58\xd3\xf6\xf0\x9f\xc2\x09\x06\xb8\x15\xd6\x8b\xc9\x79\x0b\xcf\x91\x7d\x09\x5e\xfd\xae\xf2\x1f\x72\x8e\x55\xd8\x99\x1e\x6f\x6d\x40\xd8\x4b\xb2\x7e\xa1\x0c\xde\x2e\xce\xb0\xb4\x22\x21\x2d\xfe\x27\x67\xee\xc7\xe3\xb4\x2b\x74\x86\x34\x9a\x3e\x97\xa1\x7c\x42\x9a\xd7\x94\xe5\xdd\x7c\xbb\xb2\xf7\x6d\xc2\xa9\xbc\x7e\xb7\x6c\x41\xf9\xb7\xf8\x84\x5e\xff\x64\x5f\x9d\x2e\x40\xf0\x52\x11\xd3\x02\xfb\xa1\xc6\x3f\x8a\xfc\x47\x36\x38\xe1\x83\xca\x46\x79\xff\x61\x94\x4b\xa9\x00\x3a\x3b\x4e\x9c\xc1\xd8\x9b\x2b\x7b\xaf\xfc\x2d\x6a\x4f\x81\x9a\x76\x63\x13\x3f\x42\x1c\x7b\xe7\xf2\x7e\x90\x95\x65\x64\xfd\xff\x60\xac\x00\xb9\x3d\x03\x1c\x5b\xca\xf5\x00\x3d\x54\x99\x50\x62\x68\x29\x11\x1f\x77\x87\x64\x69\xa9\x70\x19\x0f\xe8\x2f\x88\x79\x7c\x12\xa5\x0e\xf6\x9b\x0c\xa9\xcd\xd8\x5c\x99\xee\xf1\xed\x88\x6a\xf7\xe7\x2b\xeb\x0f\xe2\x5c\x79\x57\x51\x33\xd8\xdf\xa6\x1c\x93\x7b\x2d\x11\x72\xae\x30\xc6\x15\x2a\xf1\x50\xe0\x56\x96\x4f\xc2\xa4\xd5\x2c\xca\xe1\xad\x13\x7d\x75\xdf\x86\x1a\x09\x21\xa1\x43\x22\x85\xfe\xbd\x29\x3d\x4e\x43\x6a\x03\x28\x3b\xc6\x24\x74\x1d\xdb\x45\x78\x69\x7c\xb1\x6a\xe5\xbf\xa3\x5a\xd8\x21\xea\xab\x84\x8f\xb8\x8d\xda\xe1\xbf\xa1\x82\x70\xef\x9e\xbc\x79\x66\x11\xd8\xc4\x3d\x25\xd9\xb2\xe0\x27\x20\xc0\xf1\x24\x09\x5f\x0c\x55\x10\x2d\x61\x41\x04\xcc\x8e\x28\xe0\xb9\xb0\x6e\xc2\x5f\xf5\xed\x4d\xf5\x09\x7b\x6b\x35\xe4\x4f\x01\x64\xcd\xc9\x28\xd9\xa4\xfc\x37\x4b\x6e\x23\x5b\x93\x79\xfc\x2b\xfc\x04\xe6\x0f\x51\x5b\xf4\xd0\xca\x61\x5d\xd0\x36\xda\xa8\x94\x48\xeb\x55\x1e\xa0\x92\xf3\xca\xee\x9a\x65\xdb\x79\xa8\xe5\x22\x63\x38\x5d\x56\x98\x8c\xc2\x9a\xc2\x11\x0a\x90\x8d\xaa\x93\x90\xee\x21\x7e\x7d\xbc\x84\xa5\x62\x5e\x33\x84\x99\x29\x30\x1a\x04\x2d\xdc\x84\x8d\x55\x9d\x70\x3e\x10\x65\x82\x77\xfd\xcc\x1d\x55\x47\x9f\x1a\xc0\xb1\xcd\x6e\x89\x62\xc0\x5e\xc3\x73\xb3\xbc\x3c\xfe\xf6\x51\x73\xea\x71\x19\xc6\x66\xb4\xee\x25\xe4\xd4\xaa\x48\x76\x95\x3b\x21\x7a\x75\xf9\xc7\x58\x63\xcd\x97\x0f\xd7\x3f\xf8\x40\x98\x6c\x5f\x26\x1d\x01\x0c\x61\xe3\x7e\x6e\xfa\xd6\x85\x07\xd4\x64\x88\x85\x18\xce\xd8\xb8\xbc\x66\xbf\x70\xac\x6a\xaa\x33\xe1\x2f\x85\x62\xc4\x64\x60\x60\x6f\xb5\xc4\x88\x4d\x35\x8c\x18\xe6\xf0\xe7\x25\x44\xa1\x0a\xbb\xa9\xeb\x7e\x33\x62\xc4\x48\x11\x87\x01\x08\x3c\x3b\x2d\x7a\x9c\x41\x55\xe7\x4a\x75\x42\x34\x1b\x1f\xb9\xeb\xd2\xcc\x4b\xec\x21\x7b\x02\x90\xb2\xd9\x5b\x37\x17\x2e\xa4\x30\x33\xcc\xd4\xb4\xe8\x4e\x75\xba\xd9\xc0\x73\x27\x5c\x31\x09\xfe\x14\x2c\xf9\xfe\x8f\xaa\x2b\xcb\x52\x5d\x47\xb6\x73\xe1\xe7\xfc\xbc\x49\xc9\x0d\xc6\x89\x6d\xb9\xdc\x40\x92\xa3\x7f\xda\x4d\xc8\xdc\x5b\xb5\x16\x32\x09\x1c\x1a\x5b\x52\xc4\xee\xa0\x87\x0a\x6f\x07\xfe\x60\xf7\x51\x0b\x66\x30\x43\xd4\x18\x17\x05\xe6\x8e\xf5\xef\xc5\x13\x5b\xd5\x82\x31\xad\x52\x5c\x83\x91\xe5\x1a\x21\x08\xb5\xb5\x50\xed\x7f\x99\xf7\x2f\xde\x48\xae\x86\x95\xe8\x98\xf7\xe1\xfb\x3d\xb2\x61\x07\x1f\x83\x66\xaa\xbe\x3f\xec\x57\xc5\xd2\xd3\x2f\x6c\xee\xf3\xe1\xa5\x58\xfc\xb8\xb4\xef\xe7\xce\x36\xe2\x34\xba\x8a\x46\x7a\xa9\xff\xbb\xa0\x9e\x8c\x8e\xde\x2d\x5b\x99\x6f\x5f\xab\xcf\x82\x8e\x2e\xb7\xee\xa7\x15\x8f\x65\x25\xdc\x6c\x1a\xf1\xb6\x36\x2e\xa3\x65\x26\x2a\x2e\x9e\xbc\x58\x3c\x47\x0b\x1a\x57\x16\x12\x5d\x54\x5e\x2e\x33\x4f\xe2\x40\xe9\xe3\xf5\x28\x70\x8a\x6e\x6c\x1a\x3d\x1b\x4e\x60\xf6\x2a\xaf\x7e\x48\x1d\x49\x0b\xea\xa3\xf3\x14\x0e\xf7\xad\x7b\xe0\xff\x61\xdf\x77\x85\x93\x5f\xee\x14\xe9\x78\x34\x6e\xc2\x27\x8b\x13\x25\xc7\xe3\x7d\xae\x4a\x4e\x7b\xaa\xb5\xee\x64\x81\xdf\x12\xc5\x04\xe4\x1d\xbc\x75\x93\xb0\xdd\x02\xd5\x6e\xcb\xf4\x67\x3e\xcb\x3e\xc3\xfc\xb2\x6c\xf1\xa4\x9d\xdb\x0e\xe0\x3d\x87\xe9\x29\xeb\x47\xec\xbd\x6a\xd8\xe5\x67\x2f\x90\x7c\x5c\x21\x27\x58\x80\xda\xa0\x02\xd7\x28\xe0\x36\xdb\x2b\x37\x9e\x84\x54\x51\xf3\x89\xcb\x69\x34\x2f\x5f\x35\xcf\x78\x15\x3c\x67\xf5\x3d\x07\x71\x26\x02\xd8\xd2\x21\xae\x4f\x9b\x2f\x95\x69\x9b\x1f\x14\x37\xde\x54\xee\xd8\xbd\xe2\x8a\xce\xa5\xef\xc5\x7c\x51\x26\xda\xc7\xb9\xae\x4a\x76\x75\x38\x6a\xb9\x7d\x96\xb9\xa4\x63\x63\x8f\x9d\xa7\x88\x72\x2b\xdb\x00\xb8\x37\x39\x83\xaf\xec\x15\x68\xbd\xb7\x8b\x56\x8c\x6c\xc0\xa1\x3a\x9b\x36\x6a\x24\x97\x52\x27\xc9\x7f\xb9\x81\x88\x7f\x8e\xea\x25\x47\x00\xac\x28\x99\x94\xeb\x55\x33\x0c\xcc\x4c\x15\x23\x2e\x77\x3c\x5d\xfd\x64\x01\x00\x76\x04\xdb\x80\x9c\x6b\xa4\xd7\xe8\x1f\xe9\x35\xba\x7c\x6e\xca\xee\x21\x99\x9d\xb3\xb9\xfa\x59\x9e\x30\x9e\xd2\x50\x15\x47\xd9\x0e\xb3\xdc\xb0\x4d\xaa\xfd\xd9\xb7\xdd\x0a\x24\x9a\xa6\x57\x17\x52\x34\x07\x1d\xbc\xfe\x14\x1e\x29\xab\x76\x1a\x8d\xdd\x27\x6d\x9a\x52\x57\x66\x7d\xf7\xef\x5b\xc1\x51\x2a\x68\xa8\xe5\x74\xff\x07\x56\xa7\x2e\x83\x1a\x7d\xc8\xbf\x48\x07\x2e\x53\x0e\xdf\xd2\x5f\xf0\x50\xfe\xcc\xa9\xf8\x9c\xf6\x8b\xfc\x60\xaf\x16\xce\x43\x9f\xbc\x79\x13\x07\x4d\x13\x6e\x40\x60\xd7\x40\x22\xba\xb7\x3b\x76\xef\xc7\x67\xf9\xc7\x3f\x00\x26\xe0\xbf\x51\xaa\xa0\xa5\x72\x6a\x4c\x28\xd6\xb0\x14\x58\xb0\xe9\xbf\x5d\xa6\x65\x37\x74\xff\x69\xf4\x7f\x63\x65\x03\xd7\xbd\xcb\xa7\xcc\xa6\x14\xae\x69\xc2\x04\x6a\x09\x03\xd4\x55\x94\x70\x40\x9f\x59\xcf\xb7\x8b\xdd\x52\x5f\xa2\x8d\xf8\xf6\xb2\xe9\x10\x6d\xe7\x9c\x73\xd4\x3b\x3c\x75\x3d\x5e\xf6\x0a\x15\x1f\xe8\x9b\x38\x27\x1f\x78\xbf\x12\xe4\xc6\x59\x38\xc9\x31\x72\x71\x2a\xc5\xcf\x36\x88\x0e\xc8\xee\xe1\x2e\x7e\x02\xc6\xaa\x6f\xca\x35\x7e\xaa\xa8\x71\x50\xee\x4d\x42\xbd\xa3\xee\x2e\x60\x80\x06\x8e\xd4\x8d\x88\x42\xb8\xab\x95\xf3\xdd\x7f\x96\x73\xd7\x7e\x2d\xa9\x65\x77\x77\x8f\x94\xb9\x93\x51\xa6\x2e\x56\xce\x80\xa0\x1d\x46\xbd\xd5\x83\xf1\xf8\x89\x94\x54\xc0\x66\xbe\xfd\x26\xee\x54\xe6\x3a\x31\x87\xaf\x8d\x2e\xe0\xae\xe3\xf2\xf1\xd8\x02\x8b\xa8\xb1\xb9\x6b\xdf\x5e\xa6\x80\x7b\xd9\xc9\xb6\x61\x4a\x3f\x4d\xf9\xef\x8f\xa4\xe3\x0c\x20\x4e\x95\x44\x96\xd3\xd9\x02\xd1\x26\xff\xbd\x19\x3e\x5a\xa0\xbe\xf3\x7d\xb8\x17\x55\x7e\x06\x93\x8e\xf8\x5e\xcb\x43\x93\x7d\x22\xb0\x2d\x88\xbc\x5e\xa8\x48\x6a\x82\xbe\xb9\xb8\xc4\x23\x44\x41\x77\x35\xb3\x56\x1b\xb5\x47\x5f\x9e\xa1\x37\xd7\xbf\x22\xa7\x1e\x96\x89\xe6\x29\x4d\x55\xef\x01\x8a\x52\x74\xaf\x41\x8a\x34\x3f\x19\xc1\xfc\x4d\x13\xc3\x9c\x5d\xd5\x6c\xfd\x5b\x65\x20\xf3\xfa\x54\xf4\x80\x8d\xed\xef\xa4\x4d\x76\x0e\xd9\xc1\xd8\xf2\x15\xb1\x13\x45\x53\xac\xff\xd2\xe1\x7a\x70\x05\x54\x0e\x48\x7c\xd9\xcb\x14\xb5\xcf\x0e\xf5\x0b\x4a\x3d\x09\x4e\xad\xd1\x0d\x48\xe2\xa3\xce\x79\x29\xc1\x44\x54\xa6\x5a\xfc\x84\x37\x2f\xeb\xa0\x64\x47\x92\x52\xa2\xf6\x2e\x87\x18\xac\x15\xd4\x19\x64\x8a\x6e\xd5\xca\x0a\x05\x8f\xe6\x23\x44\xef\xc8\x5c\xce\x8f\xd5\x59\x0c\x45\x11\x7f\x11\x44\x01\xaa\x28\x08\xa1\x8b\x9c\xde\x9a\x64\xe2\x2d\x73\x83\xbf\xdd\x46\xd8\xa2\xa8\xd9\xc1\x53\x1f\xad\x2f\x6c\x20\x22\x08\xde\x05\xd3\xbd\x5a\x44\x48\x44\xc8\x7f\x27\x5f\xdb\x9c\xb5\x02\xd7\xab\xfc\xf1\x95\xee\xe3\xe2\xa7\x4c\xff\xb6\x3d\x99\xbc\x7e\x21\x48\x66\x62\x7b\xca\x99\x3f\xaa\x7a\x7c\x32\xda\x84\x84\xf7\xa5\x1a\x04\xb8\x7b\x2b\xc7\x50\xc0\xca\x01\xc8\xe7\xd1\x8d\x31\xa8\xd8\xc9\x18\x0e\x6e\x5a\xbc\xb5\x08\xe6\x8d\x1b\x16\xe8\x0c\x17\x9f\x8b\xa0\x2d\x6d\xb1\x48\x2e\x68\xaf\x8a\xc2\xe5\xc0\x00\x0e\xcb\xa0\x72\x94\x61\xd3\x1d\x46\xf6\x70\x90\x5b\x24\x06\x3c\x8f\x47\x99\xb7\x55\xb5\x94\x5f\x41\xbc\xa2\x1c\x8b\x31\x60\x16\xc3\x2e\xb0\x24\x17\xc9\xbd\x7e\x27\x73\x88\xf6\x09\x16\x88\xbe\x2e\xdc\xa5\x5e\xfc\xb3\x58\x60\x33\xf3\x13\x6e\x02\x63\x54\x50\x85\x9e\x00\x29\xc6\xa4\x14\x6b\x4c\x74\xda\x4f\x4d\xfb\x74\x55\x5f\xf6\xe2\x35\xe1\x16\x0a\x2d\xbd\x1d\xc4\xa1\xbf\x22\xbf\x40\x63\xbf\xf7\xb2\xa3\x73\xf7\x02\x2c\xa8\x48\x1b\x98\x82\xef\xc1\x8e\x97\xcc\xda\xe0\x8e\x67\x0e\xd4\x3d\x1a\x98\x93\x03\xbb\xc3\x98\x6b\x42\x6a\xd8\x56\xdd\x4f\xfa\x90\xb8\x4d\xe5\x2a\xe2\x6b\xf4\x83\x27\x61\xf0\x5d\xc4\x98\xb7\x4a\xe0\x59\x7e\x8f\x56\xf8\xcf\xb3\x2c\xa4\x24\x9e\x3c\x47\xd4\x7c\x18\xa4\x95\x78\xea\x0f\xf8\x08\xf7\x58\xcc\x7e\x4a\x99\xc1\x09\xac\x7c\xb3\xa7\x8b\xaf\x32\xa5\x89\x04\x31\x06\xbb\xd9\xe3\xae\x5a\x99\x2c\x27\x1a\x44\x1a\x3a\x08\xa1\x14\x58\x63\xf8\x93\x8d\xf2\xfa\xbe\xc8\x54\x1d\x10\xf1\x10\x26\xf6\x6d\x60\x3c\xf4\x34\x71\x19\x37\xd1\x33\xe9\x06\xe6\xd3\x2c\x0f\x93\xe8\x90\x51\xf6\x28\xdc\x67\xd7\x4e\xeb\xcf\x05\x1c\x52\xfe\x1f\x7a\x92\x0c\x24\x1f\x59\x6f\xcb\xee\xc1\x5a\x28\xd0\x12\x52\x82\x52\x99\x28\x1e\x26\x71\x3e\xd2\xe7\x3d\x3a\x4b\x69\x8e\x6d\xc4\xa3\xbc\x76\x63\xf2\xd3\xb8\x31\x1e\xef\x26\x32\xbf\x63\x15\x4f\xee\xe2\x91\x77\xa0\xf9\x63\xd8\x46\x1b\x9d\x40\x54\x6d\xe9\x17\xdd\x67\xcb\x76\x9e\xdf\xd5\x30\x41\x3b\x46\xe6\xd4\x14\xb9\xed\xc3\x48\xcd\x17\x5f\x7c\x40\xb4\xa3\x5e\xa2\xff\x0a\x6e\xa2\x61\xca\x76\x33\x0c\x54\xed\x54\x84\x09\x69\x43\x30\xf4\xbd\x52\x1f\x85\x49\xdf\x4f\x43\x44\x0f\xe5\x6d\x7c\x19\xc4\xdd\x41\x6c\x1e\xe9\x83\x70\xe7\x64\x7f\x63\x8d\x88\x96\xab\x7f\x0a\xa4\x58\xee\xba\x8d\xb2\xd0\xb6\x5f\x40\x8e\xe6\x6a\xc0\x82\x0e\x81\x0b\x40\x07\x48\x33\x2f\x78\x57\x01\x18\x66\x7b\xbd\x75\x95\xdb\x95\x20\x00\x5d\x25\xe1\x9c\x90\x2e\x81\x91\xb9\x49\xfc\xc7\xa3\xf2\x29\x6a\x53\x3c\xf2\x1f\x2b\x5f\xca\x85\x5b\x3f\xf0\x9a\x86\xdf\x70\x50\xfe\x43\xb5\xe3\x96\x1a\x2f\xf0\x6b\x4b\xc0\x78\x69\x0b\x26\x3a\x2b\xcc\x15\x03\x19\xb5\xda\x0e\x3a\xb7\xc7\x53\x4d\xf8\x57\x24\xe4\x9a\x44\xf7\x60\x7c\x83\x2f\xfd\x4e\x9d\x8e\xae\x5c\x8c\xbc\xbc\x48\xfa\x0b\x06\x17\x02\x1b\x09\x89\x97\x82\x2e\xd2\x91\x3a\x7e\x2a\x05\x46\xf4\xed\x18\xe1\x55\x09\x11\x25\x1a\xf1\x77\x21\x80\x84\xdb\xed\x72\x6a\x68\x33\x68\x26\xa3\x41\xa1\xb7\xab\x9a\x57\x1f\xa2\xcb\x37\x13\x16\x75\xf0\xe4\xda\xce\x71\x7e\xba\xe3\x86\x42\xea\x4a\xa1\x91\xf5\x71\x77\x85\x3d\xd4\x28\x2b\xbd\xc4\x74\xce\x86\x8e\x22\xe9\x3c\xc9\x71\xa5\x79\x2b\x7a\xae\x9d\xb2\x03\xbc\x18\x5e\xed\xf7\x38\x55\x0b\x89\x52\x5b\xed\x34\x51\x19\xe1\x5e\xb9\x18\x59\x6c\x71\x65\x06\x07\xbd\xfc\xf6\xd2\x6b\x3e\x1c\x8e\xf9\x9f\x7c\x96\x16\x57\x82\xb9\x53\xb1\x6a\xb6\xd0\x91\xf1\x76\xd2\xb5\x83\xfd\x47\x59\x93\x09\xee\x9c\xd3\xd4\xe5\xa1\x4a\x30\x1f\x61\x8d\x92\xfe\xfa\x8a\x2b\xbd\x2f\x6b\xc0\x0d\x28\x37\x06\xd1\x0c\x84\x61\x8a\x65\x98\xe5\x1b\x73\xdb\xb9\xf1\xf7\x25\x31\xe6\x19\x9f\xae\x99\xaa\xc6\xa8\x0c\x53\xf0\x8a\x3c\xe6\x13\xfa\xc9\x02\xae\xb2\xef\x5a\x3d\x88\x56\x80\xdc\x9a\x07\x13\xb0\xb0\x9f\xd2\x45\x9c\xde\xa2\x36\x24\xa5\x01\x90\x7c\x65\xe6\xd5\x5e\xab\xc8\x04\xae\x4c\x1a\x94\x7b\x59\x76\x19\xbc\x5d\xe5\x6b\x23\x42\x56\xdf\x76\xca\x87\x82\x7f\x1e\x7f\x37\x32\xae\x2e\x07\x15\xed\x24\xd2\x44\x12\x33\x46\xc3\x80\xc8\xef\x80\x96\xee\x12\xeb\xc2\x69\x81\xb1\xfd\x41\xff\x6a\x05\x24\x56\xf1\x85\xb3\x29\xf8\x4f\x7d\xd2\xd3\xdf\x0d\xa1\x28\x41\xf1\x65\x69\xc2\x0f\x1f\xb9\x13\xe5\xdf\xeb\xe5\x1c\x5d\x2e\x48\x07\x70\x5a\x3e\xfb\x1e\x87\xf0\x36\xcc\x79\x77\x46\xf7\xfe\x34\x71\x0b\x36\x23\x50\x3f\xf2\xe0\xb8\x92\xb8\x60\x04\xa2\x91\x14\x52\xac\xd3\xf2\xe4\x80\x2e\xb9\x69\xc3\x48\xc5\xa8\xf3\x6b\x34\x0d\xbe\xd4\x72\x46\xa6\x94\xe1\xc3\x82\x6c\xd7\x6f\x78\x46\x57\xed\x24\x2d\xe5\xa6\x04\x8b\x5d\x05\x59\xad\xa3\x4a\x79\x07\xaa\xa9\x86\x22\x2d\xfa\x62\x2e\x85\xdd\xb9\x84\xec\xea\x5c\xa0\x9a\x8a\x6e\x3f\x2b\xbc\x97\x7c\x70\xf9\xb3\x1c\xa7\xe2\xe8\xbe\xbc\x9f\xc1\x00\xdb\x1d\x92\x14\x32\x0e\x95\x72\xbf\x63\x1b\x96\x7a\x47\x2e\x97\xa3\x0a\xc3\x52\x35\x64\xbd\x3b\x07\x7b\xfa\xee\x7c\x3c\x92\xe3\x2f\xa2\xc0\xae\x91\x73\xc8\x5d\x1e\x47\x71\xd0\xca\x9e\x42\xfd\x1c\x94\x84\x55\x4a\x82\x9e\x07\xfd\x75\x51\xff\x41\x4f\xa8\x8a\xaf\x1a\xb5\xfc\xfb\x3a\xae\xe6\xbf\x40\xc3\xd0\xd9\xd2\xdf\x3a\x3f\xa6\x7d\x2c\x5c\xc9\xc2\xdc\xc5\x15\x41\x19\x4d\xff\x84\x2f\x80\x87\xa6\x2a\x35\x79\x65\x25\x88\xa8\xba\xe2\x33\x37\xa3\x4e\xe6\xdd\x39\x20\xd0\xa0\x64\xe7\xac\x81\x93\xd6\xff\xef\xfc\xd2\xa3\xac\xce\xe9\xde\xa3\x42\xe6\x38\x3a\x95\x65\x69\x6f\x03\xe6\x22\x51\x0f\xf1\xcf\x81\x8e\xc1\x89\xdb\xf8\xd8\xb8\x54\xc1\xac\x48\x99\xc2\xbc\x22\x20\x95\x16\xe4\xbb\x9a\xcb\x3c\x74\x34\x2c\x9c\x2d\x2d\x68\x59\xf2\x1b\xdd\x55\xbe\xde\x04\x1c\xd5\x56\x44\x3b\xf7\xf9\x8f\xe4\xc5\x7f\x37\x78\x8c\x5d\x96\xca\xc1\x43\x39\xc8\xe6\xa2\xe5\xf7\xe0\x4f\x4d\xfc\xcb\x6f\xe4\x51\x76\xc8\xab\xaa\xc6\xb4\x3d\x11\x74\xa3\xb1\x7a\x19\x3b\x14\xb0\x29\x40\xac\x74\x19\x5f\x7e\x59\xc9\x24\x1d\xab\x84\x71\xe5\x57\x56\xd2\xf8\xd6\xdb\x70\x9b\x91\x8f\xdc\x47\x43\xc4\xcf\xf1\xf3\x26\x27\x76\xef\xe0\xcf\x87\x1d\xef\x66\x44\x67\x33\x0b\xed\x94\xe3\xd1\x96\x8f\xb0\x7f\xf9\x3c\x7f\x4a\x4d\x26\xda\x9a\xd3\x97\xe1\xf1\x8d\xb2\xce\x60\xd8\x75\x19\x61\x37\xa2\x77\xa4\x3f\x7d\x87\x6f\x5f\x16\x34\x2a\x12\xe7\x64\xb7\x9a\x49\x21\xdd\xaa\x17\x7f\xf2\x68\xc8\xec\x21\x67\xad\x8b\x45\x17\xf5\xa3\x0e\x9e\xc1\x70\x44\x0e\x8a\x19\x74\xcd\x39\x4e\x1e\x01\x2b\xe4\xa8\x72\x61\xe3\x28\x28\xb0\x1b\x8b\xee\x7d\xf1\xdb\x08\x9f\x73\xb4\xa6\x49\x02\x29\x95\x26\x2d\x69\xb6\xfc\xd6\x59\x85\xf2\xf1\x26\x19\x8d\xea\xb7\xcd\x3e\x0d\x2b\xfc\x35\xbf\xf2\x60\x53\x35\x15\x2f\xe5\x89\x46\x8a\x1e\x58\x83\x93\xba\x56\x67\xc2\x15\xa0\x84\x98\x75\xa8\xfd\x84\xb9\x31\x5c\x3e\x38\x22\x6b\xaf\x69\x67\xed\x9f\x9c\xfe\xd6\x8a\xf4\xaf\x0c\x6b\xbc\xa9\x92\x74\x58\x3d\xdc\xce\x76\x87\xac\x84\x1e\xa0\x8c\xd2\xbf\x28\x33\x05\xad\x89\xf5\x57\x36\x7e\xe1\x00\xab\x72\x53\xbf\x62\x76\xec\x2e\xe4\x93\xd4\x2f\xa0\x4c\x74\xe2\xca\xfd\x4e\x28\xae\x81\x48\x52\x5f\xfb\x92\xd5\x8c\xe2\x90\xff\x71\xb4\x44\xce\xc5\x4d\x46\x97\xfc\x2c\x0b\xca\x47\x3e\xb2\x17\x32\xd7\x0f\x53\x8d\xdf\x5f\xd2\x89\x4e\x88\x2b\xb2\xd8\x72\x97\xc1\x85\xc6\xa9\xab\x34\x9f\x4b\xf0\xd4\xe7\x6b\xab\x35\xc7\x96\x80\x85\xaa\x40\x9b\x19\x16\x31\xab\xc8\xa7\x40\xef\xca\x94\x76\xaa\x7c\x9d\xed\xc1\x39\xbb\x80\x04\x50\x70\x0a\xb5\xeb\x7b\xd7\x9f\xe9\x77\x9c\x6d\xa3\x5e\xce\x9b\xde\xf1\xf8\xf0\xaf\xae\xe6\x98\x60\x7a\xf1\xbd\xd1\x3b\x71\xbc\xa9\x94\x74\x01\xaa\x30\x9b\x29\xbf\x51\x2a\xb2\xfe\x83\x01\xc5\xac\xe0\x12\xa4\xd8\x08\xa3\x7b\x29\x39\x6f\x54\xb5\x5b\x36\x63\x60\xcd\xd5\xd2\xb1\x5a\xa1\x97\x22\x83\x95\x62\xd4\xa1\xe5\xd6\x5c\xe6\xa9\xaf\x19\xb7\xb0\x27\xc6\x87\x20\xca\x17\xce\xea\x61\x54\x26\xe7\x74\xdd\xf5\x65\x58\xf9\x04\x09\x93\x83\xa4\x45\xe5\x59\x96\x29\x2a\x72\xf2\x16\x8e\x10\x3f\xb0\x34\xa8\xa0\x60\x60\x82\xb3\xb3\xb7\xc6\x8d\x86\xfe\xb5\x8d\x0a\x8b\xf5\x26\xa0\xbe\x2f\x6f\x61\xe5\xef\x6f\x75\x24\xcc\xb0\x7a\x18\xfe\xe7\xa8\x0d\x60\x50\x56\x0e\x84\x08\x43\x89\x03\x38\x83\x65\x1f\x7e\x7d\x62\x79\x19\x1b\x7f\xfd\x7e\x90\x3d\x6a\x76\x7c\xc0\xcd\xf5\x46\xc6\xdf\x93\x37\x50\x84\x1e\xc1\x02\x2c\xbb\xfe\x80\xbc\x87\x2f\x8b\x5e\x8d\x99\xc5\x58\xef\xc8\xb3\x8b\xc2\x71\x75\x71\x68\xd9\xf1\x00\x59\x73\x8d\xe6\x4f\x72\x7d\xa0\xc1\x8d\xaa\xbb\x49\x5c\x9a\x3b\xed\x5f\x54\x74\x9d\x9e\x67\xee\xdb\x49\xf5\x57\xa9\xf1\x9a\xa8\xb7\xee\x5b\x7f\x76\xda\x7f\xde\x69\xe6\xa6\x99\x9b\x05\xdf\xfe\x70\x0f\xba\x2c\x50\xde\x75\xdd\xc7\x70\x63\xbb\xf7\xb3\xd4\x39\xc0\xe9\xf8\x4a\x97\xa4\x06\xa3\x90\xd2\x94\x0a\x31\xeb\x76\xd4\x85\x20\xf5\x8c\x4d\xaa\xee\xb4\x4a\x74\x6d\x68\x17\x4d\xdd\x3f\x5a\x50\x48\x23\xf8\x18\xb6\x95\xb0\x89\x88\x60\x41\x19\xa5\x80\xc4\x9e\x74\xd0\xef\xcd\x23\x6c\x46\x98\x04\x91\xa6\xb8\x4b\xed\x2a\x4b\x11\xb1\xd7\x72\xdb\xa0\x47\x7a\x88\xcb\x42\x83\x07\x14\xdd\x84\x02\x5d\x68\xa2\x79\x8c\x0b\x6c\xcc\x49\x9d\xfb\x2f\x66\xa8\x82\x93\xde\x9c\x7c\x52\x17\x16\x77\xa5\x72\xb8\x5f\x16\x93\x9c\xec\x54\x6f\x46\x86\x02\x81\x43\x90\x5b\x6e\x36\xe0\x74\x1d\xb9\x56\x07\x24\x98\xce\x27\xc7\x01\xa2\x7f\xa9\xd2\x12\x29\x18\x9e\x7f\x83\x9d\x18\x10\x1f\x20\xc9\xab\x25\x20\x36\xa2\xc5\x0f\x5d\x4f\xd5\x14\x47\xcd\x89\xb6\x8b\x5e\xa0\x94\x16\x61\xc8\x29\x16\x54\x87\x2f\x9d\x58\xde\x29\xfb\x40\x10\xdb\x65\xc0\x09\x0b\x7a\xc1\x99\x48\x5b\x58\x3d\x02\xd9\x45\x65\xe0\xb9\x1d\x51\xc3\x29\xaf\x27\xd4\xf0\x8e\x8e\x12\x6b\xb1\xd6\x8f\x08\x92\x6a\x2f\x42\x23\xb5\xa3\xef\x3c\xa7\xb0\xe4\x1c\xab\x0c\x94\xd9\x82\xbc\x4a\xf7\x38\xea\xfa\x2b\x9e\xb0\xcd\xdf\xde\x9d\xe5\x6b\x0d\x2b\x22\xf4\x01\x96\xce\x90\xdf\x17\xe8\x6f\xff\x7b\xb1\x2f\x31\x39\xf3\x76\x12\x89\xd4\xc5\x6d\xef\x3e\x3d\x44\x43\x21\x1f\x1a\x2f\x9f\xad\xf6\x41\x95\xb1\x6d\x83\xdc\x53\xa2\x59\x50\xd8\x7b\x66\x73\x1e\xcb\xa7\x02\xe1\xe5\xc6\x22\xd5\xd6\x9c\x2d\xce\xb1\x2b\xf4\xa1\xbc\xa8\xb3\xd6\x9b\x0d\xff\x1a\xa1\x36\x78\xe6\x6e\xc9\x65\x67\xd7\xb3\x65\xa3\x12\x93\x83\x84\x68\x6f\xb9\xfd\x4c\xe1\x1b\xdf\x8c\xd2\xc1\x37\xea\x39\x34\xb2\xed\x6b\x30\xc7\x23\xe0\xc7\x32\x1f\x86\x34\x0b\xff\x4b\x16\x1a\xf5\x76\xa9\xa3\x11\x67\x1d\x6c\x66\x81\x20\x1b\x71\xad\xfe\x14\xf0\xe3\x8c\x9f\x02\xa4\x99\x5d\x57\x04\x9c\x14\x3e\xc7\x63\x16\x3e\xe8\xb3\x95\x31\x8d\x7e\x9a\xd5\xfb\xc2\x01\xcb\x16\xec\xf6\xed\xdb\x69\x85\x0e\xa4\x65\xf0\xc9\x67\x61\x5a\x3d\xd6\xc9\x70\x79\xf4\xfa\x3e\x59\xa6\xd6\x8e\x7b\xc2\x02\xa6\x7f\x7f\xe0\x09\xa4\x97\x67\x8a\xa2\xf5\x46\x5d\x5e\x6b\x31\xca\xef\x58\x90\x62\x58\x07\xa0\xa3\xc0\x66\x5f\x4a\x49\x90\xe4\xfb\x9a\x8d\xd1\x37\x25\xfc\x81\xc1\x18\xa2\x7f\x69\x5f\x6e\x12\x12\x99\x2e\x69\xb3\x47\x82\x86\x7e\x6e\xf5\xeb\x78\x83\x23\x3e\xc7\x40\x36\x2a\xef\xf4\xeb\x32\xb3\xa9\x8b\x2e\x6d\x01\x38\x55\xf1\x1a\x30\x28\xce\xaa\xb4\xfa\x0d\x96\x0b\x9e\xbb\xc0\x52\x96\x66\x97\xa7\x63\xe7\x40\x69\xbb\x6a\x94\xa2\x54\xae\xcd\x52\x1e\x55\xb7\x10\x06\xeb\x6b\xb0\xb7\xe1\x05\x8b\x22\xf5\xae\x9a\xb4\x1a\x66\x23\x07\x09\xf3\x68\x64\x94\x92\x6c\x39\x44\x34\x34\xd6\x2e\x3b\x15\xb4\xec\x7c\x82\x76\xe9\x98\xdc\xa3\x76\x3f\xb0\x24\xdf\x2a\x13\x53\x23\x9f\xa5\x48\x44\x98\xc2\x84\xa0\x9c\x82\x29\x52\x1a\x55\xd5\xb2\x36\x45\x55\x2b\x5a\x0b\x86\xe5\x6c\x71\x2c\x01\xd0\xca\x52\x4a\x65\xb1\x14\x71\xb5\x66\xde\xce\x8a\x57\x2a\x2b\xa6\xab\x58\x85\x83\xb2\x16\x37\x5e\x49\x52\xb4\x2a\x57\x86\x0a\x70\x5f\x74\xc8\xe7\xd7\x75\xe7\xea\xc4\x6a\xa5\xac\x62\x92\xdc\x9c\x2f\x19\x76\xc5\xa8\x43\x45\xc7\x0c\x8b\xff\xf7\x55\x42\x6a\x6b\x85\x40\x48\xde\x98\xb1\x54\xea\xcf\xea\x22\xb9\x1f\x1f\xa3\xfe\xca\x72\x0a\x62\x66\x28\x98\x8e\xf1\x12\x47\xd5\x0c\x13\x56\xa1\x99\x97\xb2\x1c\x9b\xf8\x4a\xa4\xe4\xb9\xb4\x34\x31\xf3\x2a\x46\xc1\xe8\x74\xd5\xd9\x22\x6a\x49\x7f\x01\x13\x5d\x40\xa5\x89\xfb\xa8\x40\x5d\x89\xaa\xc9\x50\xea\x93\x9a\xc7\x3d\xd3\xfe\x49\xc3\x70\xb3\x66\x99\x2a\x44\xf1\xb1\xc9\x66\x01\x98\x64\x50\x26\x73\x6f\x7c\xcf\xe8\x1f\x62\xeb\x1f\x1e\xf0\x26\x85\x6a\x62\x87\xd9\xbf\x4d\x4e\xfb\xae\x1a\xd0\x33\xf9\xb2\xd2\x52\x5b\xca\x77\x84\x48\x42\x36\xc8\x51\x3a\x3e\x7c\x4f\x29\x7c\x63\xf7\xf4\x60\x54\x4d\x59\xde\x10\x7d\xfe\xb1\x82\xca\xc0\xdd\xa6\xf9\xb2\xda\x99\x62\x8c\x7e\x6e\x23\xe9\x2f\x63\x34\xf9\x80\x72\x7a\xb4\xb5\x92\x04\x97\xd1\x7c\xcc\xb2\xce\x4d\x53\xd8\x9a\x46\x97\x08\xe1\x51\xbb\x74\x4d\xb0\x31\x75\xcb\x6e\xeb\xef\xa7\x04\x9b\x2e\x1f\x3d\xac\x0b\x20\x8a\xc7\x29\xfe\x0d\x50\xe0\x93\xc1\x49\x68\x2d\x38\x71\x96\x33\xfd\x4f\x94\xf5\xff\x9d\x32\x63\x5c\x1c\x65\xf7\x3f\x40\xe0\x4a\xf4\x3e\xbd\x81\x5b\xad\xbc\x11\x40\x69\xbe\x16\x66\xd4\x73\xda\x2b\x20\x69\xcb\xd2\x8c\xfc\x5b\x8d\x1c\xd3\x0b\xfe\xc9\xcc\x7b\xbc\xf1\x42\xfc\xc1\x18\x19\x9c\x5d\x80\x06\xdf\xe1\x9d\xa6\x27\x04\xeb\x72\xe9\x2d\x1c\x1b\x07\xb9\x75\xae\x8f\xcf\x0e\x55\x43\x08\xb6\xf4\x57\xac\x3c\x6e\x95\xac\xcc\xb8\xd9\x22\x97\xf3\xc3\x05\x53\xb5\xe2\x51\x1d\x43\xe0\xbe\x60\xfe\x24\xba\x98\x5d\x94\x9f\x7c\x35\x54\x8e\x29\xa0\xec\xfc\x0a\xdc\x0b\xa1\x38\xdb\x14\xe3\x64\x32\x76\xd9\x4c\x70\xb2\xcd\xb6\x5a\x95\xde\xcb\xf5\xdf\x29\x94\x6b\xe9\xe1\x0a\xc5\x7f\x6d\xc1\x0e\xbe\xc9\x92\x77\x23\x7c\x99\xdb\xe9\x52\x28\xc6\x95\xb8\x24\x9b\x10\xcd\xce\x18\x97\xd8\x4b\x71\xf3\x3c\x6c\xc6\x88\xc2\x52\xcd\x60\x93\x05\xff\x79\x9c\x9e\xb0\x0e\xd1\x1f\xca\xef\x65\x35\x59\x7f\x6c\x5f\xa4\xa9\xb9\xf7\x42\x0d\x43\x05\x15\x7e\x9f\xe4\x0a\x51\x95\x29\xd4\x08\xc7\xea\x0c\xa5\x99\x04\x6f\xdd\x3f\x9c\xac\xd9\xce\x45\x1a\x14\x38\x94\xc9\x06\xa9\x6c\x35\x16\x74\x36\x0d\x25\x22\xd3\x2e\x9b\xc1\x79\x54\x52\xa7\x73\x14\xda\xec\x04\xd2\x52\x10\xea\x1f\x9e\x70\xb6\x4f\x61\xc9\x52\x76\x1e\x7e\x4a\x99\xa3\x9b\x93\x17\xc1\xb3\x9c\x3a\x42\x89\x9e\xe8\x0a\xf2\x6c\x79\xe6\xcc\xa9\x52\x41\xeb\x18\xa8\x5d\x82\x50\xf5\x8f\x93\xd4\xc7\xf0\x42\xd5\x0c\xf2\x53\x26\xf6\xab\xdd\xf6\x23\x5d\xbd\x1c\xef\x82\xe6\xf9\x9c\x62\xf4\x48\x5f\xa1\x59\x0c\x14\x6d\xed\xb1\x70\x9f\xaa\xb9\xa9\xa4\xfd\x26\xca\xd9\x05\xd5\xcf\x6f\x2d\x17\x1b\x97\xe6\xaa\xfa\x78\x6e\xe9\xc7\xa6\x49\x18\x1a\x23\xae\x32\x25\x6d\x83\x44\x4c\x6c\x69\x1c\xfc\xd3\xde\xf1\xf1\x59\x69\x83\x21\xfe\xe7\x69\x44\x99\xf5\xa2\x71\x47\x53\x56\xaf\xd8\x75\x2d\x67\xcc\x8c\x13\xd1\xef\x91\x9f\xbd\xee\x52\xf7\xe6\x81\xa6\xcd\x23\xb8\xf4\x17\x3c\xa9\x52\x33\x75\x0f\xfa\x6c\xe2\x20\xed\x76\xf4\x78\xd8\x28\x10\xe4\x51\x6f\x58\x6e\x02\x26\xdb\xd3\x7f\x40\x86\x0a\x76\xb5\xa5\x1e\x43\x64\x87\xd4\x67\x3d\x1a\x78\xd2\x92\xa5\x3f\x25\xb2\x71\x2c\xa8\x65\xd0\x1f\x96\x3f\x07\x37\xd8\xa5\x1c\x09\xda\xd8\x82\x3a\x86\xdd\x05\xde\x29\x9c\x9e\xe2\x0c\xe7\x32\xe4\xe3\xdd\xab\x2e\xcd\xda\x3a\x43\x98\xae\xd2\xb2\xff\xbd\x02\x87\xf0\xa3\x1d\xa6\xbc\xde\xd1\x44\xe0\x75\xc5\xc7\x45\x82\x43\xb9\x8a\x59\x0b\x62\x8f\xe5\xba\xf1\xa2\x81\x22\xbd\xfd\xac\x05\x19\x2d\x5a\x4d\x2d\x05\x9d\xf4\x46\x12\x69\x64\xe4\xf7\x8b\xc2\x60\x02\x57\xb4\xda\xb4\x94\x1b\x61\x4c\x66\x67\x05\x31\x45\x33\xbb\xc7\x37\xc2\x89\x0a\x26\xb9\xd1\xae\xd5\xfd\x88\x4e\x06\x47\xe0\xe2\xf3\x16\x7e\x2b\x1f\x0d\xc4\xd1\x56\x96\xea\x3f\x0f\xef\x7a\x54\x56\x8c\x22\x62\xc8\x04\xd3\x23\xd1\xc5\xfe\xab\x91\xc2\xd5\x8d\xbf\xf1\xbc\xd0\xad\x45\x61\xc8\x09\xcf\x7f\x01\x84\x1a\x06\x0d\x8c\x51\xe7\x70\x90\xc2\xb9\xa3\x97\x81\x5e\xa4\x3f\x52\xfb\x98\x6b\x46\x43\x1f\xe1\x09\x1d\x88\x33\xaf\x18\xcf\xb2\x03\x75\xaa\xc3\x74\xc5\xbd\x97\x1a\xb2\xa6\xb9\x76\x97\x6f\x09\x79\xa6\xa7\xc8\xaa\xf1\xc6\xd3\xa7\xfe\x7c\x65\xcc\xfe\x06\x87\xfb\x83\x84\x45\x8e\x41\x28\xe1\x60\xbe\xc8\xb7\xff\x00\xe3\x4e\xd9\x64\xd4\x2a\xec\x95\xd1\x6c\x8c\xc7\x48\x38\x28\xc5\xe7\x5f\x24\xa5\xa1\x0c\xbd\xa9\xf2\x6c\xc7\x29\xaa\xc8\x32\x5f\xbb\x32\x34\xe3\xb4\xb2\x4c\x91\x33\x2e\xbf\x09\x32\x4e\xaf\xca\x8f\xd3\x8d\x46\x94\x4b\xa4\xe3\x2b\xd3\x3e\x58\xa3\x90\xec\x57\x24\x45\x87\x55\x8c\xf7\x48\x49\xa7\x59\x3b\x9d\x55\x63\xd3\x4e\x61\x97\x50\x46\x51\x4e\xce\x86\x49\xed\xb9\x42\x96\xa0\xdd\x26\xb0\x70\x3b\x04\xab\x2c\x92\xff\x3b\x43\x64\x87\xe8\x0b\xb1\xdc\x60\xe3\xa6\x3b\xb1\x37\x8a\x2f\x2a\xb2\x03\x5b\x06\x5d\x9b\xc3\x8a\x3e\xb4\x5d\xdc\xb6\x70\xf3\x03\x4e\xba\x33\xbc\xb2\x4d\xa6\x50\x82\x96\xba\xeb\x43\xa0\x12\x9b\x90\x77\x7a\xab\xc5\x6a\xc0\xab\xb0\x6a\x52\xe5\x8d\xab\x0f\xfd\x21\x1f\x34\x59\x7b\x18\x00\xae\x56\x5f\x20\xe0\x2d\x9d\x48\xec\x10\xce\x5a\x4e\x83\x7b\xda\x9d\x4e\x51\xf3\x25\xcb\xf0\xdf\xc1\x8b\x0a\xa8\xaa\xb9\xab\x27\xce\x49\x45\xd9\x96\x4d\x67\x37\x56\x3d\x9f\xff\x9e\x4c\x56\x6b\x46\x4d\xa8\x1c\x4a\x52\x38\x1a\xe1\x05\x80\x60\x66\x66\x35\xba\x50\x14\x1c\x5b\xd9\xa1\xed\x8b\x02\xd5\x70\x43\x7a\xa9\x5f\x0d\xaf\x8b\x66\xd4\xb5\xc0\x42\xd2\x32\xb1\xb4\x79\xe3\x99\xca\x46\x41\x02\x3e\xd7\xc2\xe5\xb7\x3e\xfa\x1a\x1e\xc0\xe2\x56\x33\x17\x0a\x8b\xf2\xd3\x39\xd6\x5f\xac\x49\xb4\x70\xf7\xde\xbd\xef\x54\xb6\x3b\x9f\x58\x78\x10\x05\xa8\xfd\x54\x9a\xd6\x47\x6a\xfa\xfa\x07\x88\xc0\xc3\xe3\x62\xaa\xe6\x1a\x53\x3f\x3e\x4f\xa5\x63\x74\x2f\xcc\x0c\x9f\x6b\xb8\xc7\xf0\xf2\xc6\x38\xa7\xb0\x89\x67\xa0\xef\xe5\x94\x11\xec\xaf\x3f\xc8\x3f\xcd\xae\x2d\x5b\x17\x56\xb0\x98\xce\x35\x1d\xbe\xe1\x39\x29\x69\xe0\xf1\xb0\x2f\x36\xf5\x80\x86\x66\xcb\x57\x2b\xdb\xf2\xf7\x65\x69\xf9\x06\x9e\x25\x3c\x36\x6c\x57\xdf\xa5\x90\xd2\x45\xaa\xa9\x58\xdf\x0d\xc3\x2d\x8c\xc3\x52\xba\xfa\x4f\xd5\xef\xa0\xb5\xe7\x45\xfa\x0f\x4b\xd4\x5d\xa7\x1d\xd2\x86\x66\x17\xa9\x63\xb9\x4a\x0c\xbc\xfe\x87\x28\x04\xcd\xe0\x32\x5e\x84\xd9\x20\x39\xb8\x93\x83\x99\x25\xc4\x09\xe7\xd2\x6c\xa3\xd5\x1e\x65\xd9\xea\xff\x8c\x35\xbe\xe6\xf2\x16\xf6\x48\x05\x8e\x3c\xde\x03\xa1\x24\xeb\xc3\x49\x76\x5b\xd5\xad\x61\xa6\xee\xa3\xbc\xed\x2a\xe5\x96\x04\x5c\xdf\xef\x9a\x36\x5e\x3f\xc0\x04\x67\xe6\x1e\x65\x5b\x69\x1f\xae\xe3\xa1\x76\xf2\x21\xfe\x43\x29\x96\x89\x78\xec\x67\x18\xe4\x39\x28\x38\xf8\xb3\x6d\xcb\x8b\x45\x07\xcd\x15\x3b\x45\x35\xaa\x6a\xcb\x72\x1a\xbf\xc5\x70\x29\xe3\xe1\x2b\xd5\xe2\x0c\x95\x32\xed\xab\x5c\x88\x2a\xd2\x0e\xbe\xae\xac\xf1\xd6\xc0\xd0\x11\x8d\x59\xad\x3a\xfa\xf0\xc3\xab\x29\x4c\x70\xe8\x18\xeb\x48\xe5\x20\x74\x1a\x9b\xef\x83\x7b\xea\x26\x02\xed\xd4\xcf\x8b\xeb\xd2\x7b\xec\x00\x1c\xa5\xb1\xdb\xcf\x43\x61\x7c\xcb\xb8\xae\xae\x52\xf5\xd9\x59\xa2\xfa\xc3\xc2\xba\x9f\xb7\x65\x5e\x36\x81\x67\x87\x4d\x98\x95\x84\xf2\xff\x00\xdd\x48\x4d\xf2\x7d\xac\xd1\x29\x28\x59\x34\x00\x98\x1f\xb6\x1e\x11\x47\x0d\xf8\xb4\x7f\xc0\x4b\x27\xec\x8b\xcb\x12\x67\x15\x62\xd9\x41\xd6\xd5\x61\xef\xcb\xf6\xdb\xdf\x5a\x1b\xfe\x5b\x20\xd5\xc2\x31\xd8\x2e\x7f\x28\x0a\x67\x7d\x51\x65\x56\x34\x62\x7a\xd8\xa2\x54\xc3\x60\xca\x5e\x41\xc6\xf8\x4a\xd9\x83\xda\xea\x6a\x56\x4a\x5d\x5d\x2f\x5b\x6e\x18\xee\xff\x7b\x53\x89\xbb\x4b\x47\x5e\x76\x76\xae\x2d\x80\x9d\x2a\xd2\xe2\x26\x06\x2d\x53\x92\xa2\xca\x3d\xf2\x97\x6d\x48\x3c\xb7\xec\x0b\x52\xd4\xdd\x40\x58\xe5\xb0\x1d\x72\xc3\xde\x63\x25\x24\x19\xc4\xec\x45\xd5\xfa\x76\x85\x81\x8b\x60\x17\xab\x12\x50\xd7\xa1\x42\xb1\xb1\xb0\x56\x40\x75\x2c\x2f\x6d\xb0\x5e\x69\x1e\x7c\xb3\x65\x41\x49\x53\x18\xa2\x90\x31\x99\xaa\x07\x61\x2b\x6c\x19\x6e\x31\xe4\xbb\x82\x94\x6b\x95\xdf\x9e\xec\x45\x28\x80\x0b\x2f\xfd\x95\xb5\x65\x52\xae\x35\x8b\xb9\xf9\x67\xaa\x2e\x73\x5f\x55\xfa\x02\x43\x3a\xf5\x1a\x60\xfe\x05\x1a\xdb\x9b\xc9\x7a\xfb\x46\x60\x75\xd0\xf6\x9d\x75\x8d\xa7\x73\x9d\x8f\x10\x9d\x40\xf9\xeb\xfa\x95\xb1\xcc\x16\x07\xac\xbd\xce\xe4\x15\xbd\xbe\x87\x06\xc1\xf5\x85\x52\x4f\xb5\xaf\x76\x8f\xa8\x78\xa7\xf8\xec\x04\x4e\x73\x55\x26\x56\x6a\x5f\x39\x3f\x5d\xfc\x36\xbd\x1b\x9f\xcb\x67\x96\xa7\xfb\x12\x7d\x9c\x32\xe8\xb1\xc2\xea\x4e\x32\xbe\x96\xf1\x99\xa7\x84\xef\x70\xa9\xce\x0a\x18\x09\x53\x3c\x2b\xb6\x80\x76\x39\xd2\x46\xcc\xb3\xc5\x56\xda\xff\x4c\xc4\x39\xab\x94\x1d\x27\xfb\x3a\x8f\xbd\xca\x5c\xb8\xe6\xec\xa6\xd3\x96\x12\x26\x2a\xde\x09\xf2\x28\x8f\xbb\x6a\x7e\x34\xc3\x5f\x4e\x95\x08\xf6\xd9\x62\x3d\xcf\xb0\x8f\x77\x91\x04\xef\x93\x6a\x77\x3f\x97\x22\xc8\x90\xda\xfc\xcf\xff\xee\x74\xfe\x9e\xc1\x25\x9e\x62\x37\x55\x06\x69\xb7\x88\xf1\x10\xac\x69\x6e\xc4\x45\x4b\x9b\xca\xea\x31\x3a\xfb\xf9\x5e\xbe\x25\x9e\x45\x53\xef\xd9\x53\xf0\xa7\xee\x4a\xdb\xe2\xc8\x0f\xf0\xa5\x26\x8e\xf6\xbf\x49\x91\x83\xdb\xcb\xd1\x1f\x3c\x6b\xa0\x72\xc4\x2d\x92\x3d\x5c\x90\xbe\x32\xec\x09\x92\xeb\x51\xf4\x75\x4d\x72\x45\xeb\x77\xbe\x29\x18\xba\xf9\xcf\x66\xb5\x94\xba\x17\x60\x39\x54\x51\x23\x0a\xa6\x74\x39\x07\xae\xb2\x85\x37\x7d\xb6\xec\x35\xc2\xeb\x7a\x11\x15\x76\xac\x62\x63\x54\xab\xc3\xf4\x69\x7b\xf5\xea\x1f\x4c\x77\xe4\x00\x09\x2c\x2a\x3e\x4f\xd0\xaa\x3d\x2e\x9b\x05\x49\xb3\x91\x24\xe1\x76\x53\x19\x46\x79\x09\xd1\xb9\x9d\x00\x55\xa4\xda\x62\xa5\x9f\xec\x94\xad\x13\xcb\xc6\x28\xa0\x0d\xdd\x1c\xf3\x11\xf5\xe9\x32\x24\xdd\x37\xdd\x0d\x6c\xb1\xa2\xe1\xed\x50\xb6\xd2\x8f\x7e\x14\x89\x76\x93\xfb\xb5\x43\x4d\x01\x8c\x56\x0b\x39\x1e\xcc\x22\x6b\x0f\x99\xa5\x2d\xef\xce\x11\x30\x02\x8e\x4c\x10\x68\xf3\xa9\x6a\xb7\x5c\x90\x0f\xf5\x26\x08\x8e\xa9\xf6\x2c\x1b\x00\x27\x98\xd9\x41\x50\xb5\xea\x69\xf6\xc3\xbd\x6c\x8b\xcd\xc4\xc5\xde\x77\x15\xe7\x02\x60\x95\x8a\x5b\x1a\xcb\xeb\xe9\x7d\xfd\x8c\xf7\xe0\x4e\xdc\x23\x07\x1b\x01\x81\xf7\xd3\x05\x71\xb5\xde\xbd\xa7\xb2\xff\xe0\x3c\x56\x2a\xd8\x0b\xaf\xc2\xc1\xad\xba\x6b\xeb\xcf\xda\xac\x22\x49\xf0\xe4\xbc\x4d\xad\x64\x04\x0a\xf6\x1b\x3c\x1e\x84\x54\xc2\x03\x5d\x77\xef\xab\x6e\x20\xcb\x73\x9d\x2c\x08\x54\x70\x27\xf2\x84\xac\xaf\xb4\xdc\xab\x7c\xf5\x5f\xb6\x6a\x20\x70\xbf\x5d\x32\x13\x0d\x0d\x92\x2d\xca\xe6\x00\x42\xcb\xa4\x14\x05\x26\x7e\x04\xd7\xbc\x12\x4a\xbe\x97\xc0\x2d\xcb\x10\x53\x9a\x8b\xc9\x2c\xe1\x12\x34\x95\x6f\x9b\xa6\x64\xda\xb9\x08\xa3\x1c\x5f\xe7\x64\xc3\xc1\x9d\xfb\x82\x1a\x5c\xb2\x47\x01\x0c\x51\x95\xf3\x0f\x41\xbd\x85\xfa\xb5\x9a\xba\x6c\x87\x3c\x29\x19\x50\x38\xe6\x8a\xb6\x5c\xc7\x2a\x62\xb1\x02\x04\x03\x57\x5b\x2a\xab\x28\x97\xc8\x42\x59\x46\x15\xb9\xf7\xfe\x7a\x8d\xb2\xc0\xff\x69\x00\x87\x5c\x43\xad\x76\xe1\x10\x9c\xfa\xe9\x30\x5f\xb1\xe4\xfa\x53\xa8\xe1\xb9\x4d\xaa\x6f\xa7\x55\xda\xb3\xd6\xe5\xdd\xf6\x69\x64\x10\x5d\x5e\x15\x24\x69\xfe\x0d\x32\xa0\xff\xb1\xbb\x02\xfd\xc8\x5a\x2b\x62\xf3\x46\x4a\x71\xb5\x5c\xe9\x20\x6d\xc0\xa9\xe7\xea\x5c\xee\x0c\x7d\x19\x07\x51\xe5\xe5\xe5\x65\x91\xaa\x94\x97\x31\xc4\x67\xaa\x78\xeb\xe1\xfe\x8d\xbc\xc7\x2b\x0e\x4b\x46\x70\x8c\xe6\x5c\x31\x58\x18\xc6\x7c\x15\xca\xa5\xc6\x0b\x25\x78\x3b\x55\xaf\xc4\x71\xf3\xe7\x78\x9c\x11\x6b\xdd\x3e\xd4\x87\x2c\x17\xca\x2b\x4d\x9b\x90\xd5\x5e\x31\x13\x69\xd5\x61\xa9\xb3\xb0\xa0\xfe\x8b\x62\x17\xc5\x68\x8e\x22\x16\x65\xea\xe0\xaf\x0f\x29\x43\x0f\xbb\x60\x32\xac\xc5\x58\xeb\x96\x7d\x97\x56\x2a\x0e\x81\xad\xaa\xfe\xe3\x85\xad\x52\x32\xaa\x55\x15\x65\x4d\xd9\x78\xc9\xab\x66\xfa\x49\x8b\x00\x98\xe6\x6c\x82\x01\x24\x2b\x0d\x95\xb2\x58\x9e\x45\x20\x1e\xe7\xb0\x13\x21\x99\xb8\xaa\x36\xcb\xa2\x91\x35\x30\x7d\x38\x08\xc5\x9d\x63\x1b\x49\x73\x35\x8a\xdb\x2a\x86\xb9\xe9\xc7\x1f\x3f\x4c\xc4\xc0\x26\x75\xa4\x1b\xf9\xce\xa4\x2b\xbc\x14\xae\xac\x21\x4b\xbd\xba\x96\x35\x93\x55\xde\x11\x7e\xde\xbb\x8e\x84\x21\x94\xdd\xc2\xac\x3b\x1e\x36\x5c\x48\x7b\x2b\x52\xfd\x4d\x60\xae\xcc\x20\x05\xc6\x96\x1d\x09\xb8\x22\xa2\x19\xc3\x88\x19\xb7\x8a\x63\x81\x64\xd5\xc7\xdc\x46\xc0\x0c\x5c\x05\xab\x53\x28\x19\x6e\xd9\xe8\x2e\xf9\x7e\xa4\xa9\x7c\x1c\xfe\x93\xa3\xbe\xed\x34\xba\x20\x45\xfe\x55\x2d\x42\x63\x1a\x2e\xd7\x81\x5c\x1e\x9b\xdd\xe9\xa8\xa5\xf2\x71\x95\x96\x52\x22\xd3\x26\xf1\x3f\x8c\x90\xbd\xc8\xef\xe2\x93\x5d\x7f\x7c\x42\xfa\x86\x0c\x75\xd5\xab\x9f\xa5\x7b\x70\xe3\x40\xff\xf6\xd8\x45\x61\xa2\xdc\xcb\x4b\xe3\xd7\x79\x8f\xb1\x1d\x78\x3f\x04\xfb\x22\xf7\xc6\x8e\xb5\x6f\x4a\xc8\xb8\xe7\x29\xe5\xd3\xf1\xe7\x82\x76\xb2\xc4\x97\xee\xee\xc6\xa2\x5f\x60\x5b\x39\x96\xb1\xa9\x5b\x6c\x86\x3c\xbb\x9e\x1d\x9c\x3c\x63\xd7\x9b\x5b\x05\x72\x75\x50\xca\x5a\x50\xd7\xf6\x60\xad\x9c\x4b\xdd\x01\x62\x23\x56\xce\xa6\xfd\x76\x99\x49\x46\xed\xaa\x99\x29\x68\xc4\x30\x6a\xc2\x08\x95\x96\x57\xc3\xe3\xc3\x4d\xd9\x71\x79\xc9\x94\x2a\x72\x25\xb6\xdc\xeb\x60\xb1\xf5\xf7\x81\x98\x3c\xac\x7e\xba\xdf\x49\xd0\x44\x6e\x86\x6a\xac\x93\x6c\xb6\xd3\xd7\xec\x09\x9e\x75\xb8\xcd\xa3\xe0\xd7\xae\x11\x88\x3b\x86\xb1\x4d\xa9\x67\x75\x63\xa3\x2d\xb2\xa2\x20\x11\x27\x1a\x8b\x33\x5b\x34\x5f\x39\x54\xea\x4c\x04\x89\xd8\x24\xf5\xa3\xef\xe3\xf4\x3f\xc0\x92\xe3\x7d\xe4\x06\xb3\x6e\xfa\x48\x37\xe4\x92\xf7\x03\xbf\x7d\xe3\x8d\x6f\xb3\x51\xe9\xa7\x19\x3d\xc8\xfd\x0d\xa1\x1c\x47\x27\xc8\x28\x35\x85\x58\x51\x3b\x39\x64\x94\x32\xe1\x0f\x34\xb7\xb2\x89\x97\xfe\x3f\x77\xf8\xa0\x45\xf5\x7f\x63\xc5\x5d\x56\x66\x95\xd9\x65\xaa\x08\x84\x17\x06\x01\xc6\x4b\x0f\xe4\x08\x06\xe7\x18\xdd\x01\x39\x4d\x1e\xfd\x3d\x3c\x63\xca\x46\x71\x7f\x86\x54\x55\x85\x23\x84\xb4\x49\xfe\x96\xe8\xde\x84\x70\x96\x2e\x3d\x1e\x67\x27\x98\x97\x2b\x67\x44\x9b\xf5\x88\xe2\x5a\xb5\x3e\xb6\xfe\x82\xb5\x4b\x45\x7d\x11\x86\xdd\xcb\xd9\xe7\x51\x69\x1a\xe0\x1e\x4d\xab\xf0\xdc\x49\x7e\xc1\xbb\x9c\x64\x11\x5c\x1f\x9f\x67\x0c\xf4\x09\x9a\x55\x31\x7f\x47\xee\x85\x19\x71\xb9\xf7\x7d\x3c\x0e\x70\x81\x40\xe0\xd3\x31\x30\x0e\x34\x71\x55\x2d\xdc\x18\xb3\xb6\xe0\x65\x34\x35\x55\x64\xcf\x07\x0d\x63\x77\x46\x86\x8b\xbc\x8c\x1e\x4e\x18\x73\x52\xc2\x1a\x6a\x56\xf5\x60\x09\x23\x2f\xab\x32\x9d\xca\x7e\x40\x81\x43\xb8\x6c\x6e\xc2\x92\x3b\x15\x19\x28\xb9\xcb\x59\x9c\x5d\x74\xdf\xfb\x27\xe1\x6d\xbe\xe1\x90\xc8\x6d\x88\xcc\xbe\x85\x5d\x0f\x47\x39\x7c\x4a\xca\xc8\xa4\x39\xca\x58\xed\xd3\x1f\xd1\x1b\xe5\x07\xeb\xa2\x06\x4f\x2e\x9c\x0f\x47\x50\xa0\x14\x2f\xa5\x75\xa5\x3d\x53\xc9\xfc\xe5\xf7\x53\x33\x96\x15\xce\xaf\x90\x45\xda\xf6\xf3\x76\x3d\x8f\x2f\x6e\xf3\xd3\xb1\xf9\xa0\x33\xeb\xef\xf7\xf2\xb4\x68\xf4\xe3\xab\x28\x57\x65\x3d\x42\x27\x5a\xa5\x36\x64\x0f\xca\xcb\x8c\x28\xcd\xc5\x9f\x19\xf3\xfb\xe2\x2a\x9c\xe9\x00\x29\x44\x18\x5b\xaa\x99\x99\x9e\xcd\x24\x65\x08\x25\x2b\xba\x69\x66\x5c\xac\xa7\x95\xa7\xb0\x0d\x5d\xda\xa8\x9d\xb3\xce\x68\x85\xf0\xc7\x03\xea\xf5\x85\x70\xcd\xb1\x7f\xbb\xe6\x5e\xdd\x5b\x5d\xd1\xfa\xc0\x8f\xb3\xf3\x14\x5e\x29\x03\xd5\x1f\x10\x03\xa0\x57\x99\xe8\x1f\xc0\x20\x80\xb2\x33\xe4\xbf\xd1\x1f\xe7\x14\x1e\xff\x07\xa9\xf8\x86\xa4\x37\xaa\xa4\x83\x3a\x4d\x63\xf7\x9a\x26\xe0\xe8\x01\x61\xdd\x7a\x78\xa4\x39\xc9\xd4\x66\x85\x07\xb1\x8d\xff\x71\x41\x5b\x54\xbb\xd9\xbf\x92\x11\x01\xf6\x59\x5d\x6d\x38\xbb\xc6\x36\x1b\xf3\xeb\x5f\x9f\x6c\xa0\x8f\xa3\x32\x15\xb2\xce\x0d\xc1\x58\x46\xb6\x86\x56\xf6\xf2\x55\x71\xc7\x98\x61\xdf\xb8\x54\x21\x6e\xd9\x2c\xc9\xb4\x74\x8d\xce\x30\x62\x64\x28\xe9\x05\xc0\xbd\xbb\x11\x60\x73\x79\xf5\x0a\xc8\x41\xc1\xd5\xfe\xe1\x11\x24\x04\x5b\xed\x18\x74\x2e\x6e\x3d\x94\x70\xb7\xfc\x68\x1e\x70\xc6\x35\x1f\x74\x21\x89\x4b\xc0\xb9\x6c\xe1\x16\x6d\xb3\xe6\x37\x57\xe2\xf9\x74\x70\xe7\x69\x44\xbc\xfa\xa5\x03\x2b\x0f\x98\x9c\xbd\x5a\x33\xa2\x29\xb7\x95\xf8\x37\x37\xc1\x8e\x4e\x35\x7c\x00\xe3\x7e\x31\x6d\xba\xac\xb5\xbd\x74\xe3\x73\x99\x65\xd4\x71\x68\xcb\xd9\x23\xd6\xe1\x1c\xf6\x4c\x88\x03\x0d\xca\xc1\x0c\x23\xc1\xa4\xd7\x4f\x7f\x56\xe6\x9e\xbb\x49\xd3\xd0\x44\x37\xd5\x22\x69\x7f\x98\x69\xbd\x9c\xa8\xc9\x20\xb1\xd1\xf1\x23\x0f\x49\x06\xa8\x9f\x5d\x51\x31\xec\x22\x70\xcf\xb6\x84\xb5\xeb\x34\x3e\x83\x03\x8d\xb9\xef\xdd\xdb\xd7\xd6\xc4\x6a\xfe\xa1\x7f\xb9\x51\x3e\xf5\x87\xbb\x88\x53\x6f\x1f\xd6\x52\x3c\xb9\x89\xf0\x59\x7e\x35\xe8\x92\x14\xbf\x98\x1b\xf8\xcf\x07\x19\xb7\x4c\xc4\x7c\xab\x4f\xe6\x24\x70\x20\x32\xf5\xd8\x2d\x97\xeb\xc3\xb3\x17\x49\xe9\x09\x83\x05\xec\x11\x7f\x54\xd3\x00\x77\x17\xbb\xba\x6f\xcc\xa9\xde\x53\x63\xbe\xe6\x18\x1d\x86\x2d\xfd\x0f\xb3\xc3\x98\xf9\x61\xc7\xb2\x53\x55\x23\x61\x29\xf5\xd8\x52\xb5\xeb\x68\x62\xec\xb5\x89\x01\x57\x63\x05\x6e\x21\xc4\xb1\xad\xac\xec\xb2\x38\x74\xe9\x2b\x3a\x61\x53\x22\x92\xbb\x15\x7b\xe8\x2b\x31\x9c\xbf\x3b\x1f\x58\xe2\xf4\x12\xb5\x9d\xf1\xf3\x85\xe1\x53\x42\x1c\x50\x3f\x1d\x79\xe2\x5f\x57\x80\xae\xb5\xc5\xe1\x06\x55\xdd\xa1\xa6\xaf\x7f\x63\x5e\xcf\x48\x36\x4d\x9a\xea\xc7\x59\xc1\x44\x1c\x4f\x64\x46\xf8\x1f\xff\xc7\xd9\x70\xfc\x37\xd2\xbd\xa9\xd4\x71\x6a\x86\x9c\xfa\x87\x1e\x20\xef\x4a\x14\x43\xd5\x8c\x62\x8b\xd0\x08\x71\x7b\x64\xf2\x72\x4f\x37\xf1\x63\xcb\xee\x7f\xc0\x38\x56\x29\x2c\x0f\xa5\x82\x3e\xd8\xcb\x60\x59\x8f\xe1\x68\xf9\xf6\xf0\x99\x97\x52\xcc\x9f\x56\x14\xbf\xa7\xa0\x82\xc3\x1f\xd6\x12\x5f\x8e\x39\xd8\xa4\xf5\x55\x9f\x6f\x18\x37\x79\x4c\x0c\x68\x4a\x08\xf5\x47\x08\xf6\x43\x7b\xf2\x21\x12\xdc\xcb\xc0\x66\xd4\x64\x35\xf1\x76\x52\x8e\xdb\x1d\x9b\x52\x26\x28\x6c\x16\x6e\xdd\xc1\x47\x37\xde\x4f\xce\xb8\xe1\xfd\x9a\x0c\x0f\x8b\xa9\xe8\x80\x94\x13\x95\x75\x28\x52\xc6\xe4\x23\x7e\xef\xcb\x95\xeb\x5e\xdd\x5d\xc1\x8d\xee\x8d\x1c\x91\xd5\x80\x74\x28\xab\x86\x9f\xf5\xf6\x4b\x2b\x2c\x21\x55\x39\xd0\x59\x02\x87\xd9\x9b\xfa\x1f\xff\x4a\x65\xc5\xbf\x71\x7f\xcc\x36\xc5\xbe\x6b\x55\xd5\xc1\xd3\x0a\x88\xb2\x77\xab\x4b\x69\xef\x1b\x71\x7a\x22\xdd\x10\x12\xea\xc1\xec\x53\x74\x3e\xd0\xe3\xa4\x59\xed\x3c\x8f\xbc\x41\x2f\x53\x0e\xb7\x73\x93\xcd\xaa\xa2\xc9\x97\x5c\x81\x20\x27\xe3\xb2\xd5\x29\x32\x9d\xcd\x04\x20\xd7\xb8\x75\x52\x61\x57\x1b\x91\x5d\x6e\x4f\xca\xe5\x02\x12\xcf\xbe\xd0\x28\x43\x36\xb6\xbf\x87\x3c\x01\x22\xe4\xf1\x19\xe0\x3f\x6d\x26\x0f\x2b\x90\xa5\x90\xbe\xb9\x25\x02\xab\xdc\xe8\x88\xac\x53\xb6\x77\x95\x86\x36\xac\x7d\x8d\x29\x98\x01\x6d\xa4\x53\x4a\xa0\xec\xe1\x7a\xc5\xc2\xf2\x93\x77\x97\xbb\x60\x19\x4e\x02\x19\xe8\x46\xe5\x36\xca\x5d\x5e\x59\xfd\xbd\x0d\x0f\x2a\x37\x46\xc4\x1c\x17\x28\xd3\x6e\x17\x69\xde\xe9\xb1\x1a\x22\x71\x2f\xee\xde\x9c\x1f\x63\xaf\xa8\x4b\xfe\x46\x57\xa8\xa0\x52\xfb\x0e\x12\x81\xb5\x4c\xe0\x88\x18\x77\x45\xec\xdd\x77\xc8\x13\x7a\x16\xc9\x30\x7d\x13\x7e\xb7\x53\xd6\xcd\x68\xe8\xb1\x9d\xc2\x2d\x90\x90\xbc\xae\xbd\x72\x0a\xcc\xc6\xe3\xc9\xfe\x76\x67\x42\xbb\x96\x72\x6b\x56\x35\x8c\xd3\xd5\x1e\xe9\x81\x86\x98\xdc\x81\xee\x45\x30\x11\x5b\x85\x8d\xea\x6e\x03\xef\xaf\xc0\xd9\x6b\x32\x5b\x59\x6c\xd0\x60\x51\x0b\x03\x58\x86\x43\x25\xca\x9b\x66\x9f\xa1\x6c\xc4\x84\xa8\xa3\x9d\xe8\xd6\xc0\xa5\x42\xde\xce\x49\x19\x12\xdb\x68\xdc\x7d\xdc\x65\xa5\x0b\x78\x53\xf7\x80\x5f\xea\x10\xda\x1a\xdf\x5a\x46\x9d\xb6\x9d\x7c\xb7\x4d\xd0\x17\x1a\xf7\xb4\x9b\x9e\x20\x87\xe8\xe3\xd3\x29\x7a\x7a\x1f\xf5\x7f\xd3\x3f\xca\xab\x8a\x64\xfe\xf0\xf6\x12\xde\x6b\xd1\xb9\x00\xf5\x51\xe7\x37\x74\xce\x63\xc4\xc1\xa1\xa0\x35\xff\x7c\x12\xb7\x9d\x72\xcf\x58\x61\xa3\xff\x71\x13\x27\xdd\x01\x11\xa5\x88\x8a\x78\x8a\x43\x56\x52\xf0\xc3\x0f\xd6\x39\x4e\xf5\xda\x4c\x2a\x13\xcf\xaa\x26\xc4\x06\xeb\x75\xb6\x15\x96\x0f\xf6\x37\x1c\xe5\x1a\x1e\xab\xc4\x8a\x28\x07\xe1\x5d\xc4\xd3\xce\x5b\xa6\xb2\x7d\x5b\xfe\x6c\xb8\x7b\xc7\xf9\x8a\x8f\xc8\x83\x3b\x98\xe5\xce\xa4\xb8\xc3\x44\x2f\x78\xea\xdd\x26\x3b\x85\xff\xf8\x97\xa7\xb2\xdb\x82\x82\x96\x97\x85\x1b\x32\xc0\xe4\x4d\x0c\xfd\x94\x5f\x11\xff\x3c\x5a\x18\xa4\x9b\x63\xc5\x30\xf6\x4e\x6f\xc8\xf7\x63\x74\x5f\x99\x01\xb8\x96\x19\xbc\x41\x97\xe3\x59\xcf\x38\x8b\x8e\xa7\xf4\x1b\x65\xa3\x50\x69\x40\xef\x01\xc2\x8b\x73\xf6\xca\xb3\x97\xd1\x17\x04\x91\xb3\x2a\x41\xb0\x64\x6f\x8c\xc7\x65\xd3\x02\x0a\xaa\xaf\x70\x8b\x57\x6a\xed\x76\x70\x35\xd0\x4e\x2d\x74\x88\xb0\x53\x13\x82\x9a\xcc\xe8\x48\xc8\x5a\xdf\x63\xd8\x5e\x99\x4e\xfe\x14\xc2\x78\x2e\x3f\x92\x54\x95\x7a\xa2\xce\x2b\x84\xeb\xcb\x92\x11\x47\xa4\x2f\x54\x97\x73\x10\x1d\x35\x65\xf0\x68\x98\x84\x38\x1f\x9f\x40\x24\x8e\xf7\x88\x9d\x14\x1b\x1b\xec\xdf\x1d\x04\x51\x6f\x96\x53\xf7\x12\x56\xa7\xd9\xcd\x52\x0c\xfb\x08\xd6\x68\x05\x3d\x1e\xd2\xf3\x1d\x59\xb2\x5e\x7a\xec\xf2\xb1\x65\x97\x70\x3e\x0f\x0a\xa0\x1f\xef\x20\x10\x70\x33\xdf\xc8\x1d\xf3\x78\x28\x5e\xe3\x11\xb6\x4e\x65\x34\x47\x90\x1e\x26\x2d\x07\xf5\x21\x60\x07\x75\x0a\xc7\xc1\x6a\x2e\xa3\xe4\x87\x3e\xfb\x28\x0d\xf6\x0f\x55\x2c\xf2\xc9\xfd\xcc\x20\x8e\x8a\x8c\x6e\xfb\x5a\x58\x66\x55\x26\x80\xed\xb3\xf8\x3c\x5b\xe1\x9e\xe1\x7b\x75\x29\x1c\xe8\xa7\xe5\x80\xbe\x74\x9c\x66\x4a\xa2\xdd\x30\x79\xfb\x8a\xf1\xf0\x08\x5e\x80\x12\x01\xd0\x85\xe0\xfa\x05\x63\x46\x3e\x19\xfd\x87\xd9\x6f\x63\xcd\x4f\x61\x4e\xe0\x08\xd4\x93\x83\x17\x65\x8d\xcb\x2a\x47\x4a\xc9\x5b\x83\x42\x40\xc0\x5f\xad\x8a\x35\xc5\xbe\x80\x84\x02\xfc\x18\xa4\xd4\xcf\x95\x51\xb2\x4f\x0e\x01\x9c\x92\x0f\xeb\x5f\x9e\x61\xd3\x52\x96\x78\xa7\x7e\xf4\xb2\x07\x7b\x26\x9b\xf2\x62\xab\x57\xce\x45\xb6\x29\x1e\x5b\x9d\x96\x20\xa5\x36\xb9\x1d\x46\x5b\xa7\x9d\xb5\x44\xfb\x80\xf5\xe6\x54\x1f\x58\x4a\xd1\x60\x07\xc8\x58\x5c\x1f\xaa\x9c\x99\x77\xed\x92\xb9\xd7\x90\xec\x3d\xbc\xb8\x5a\xf7\x2e\x36\xba\x14\x55\xff\x2d\x39\x9b\x3b\xfb\xf3\x7e\x99\x93\xc1\x6d\x28\x14\xda\x8f\xde\x52\x70\xf5\x2e\x22\x34\x50\x96\x5b\xee\x5e\x38\x62\x25\x89\x54\x4f\xe9\x9c\xfb\x17\xda\xba\x6c\xb2\x1f\x2b\x53\x58\x57\x6a\xc4\xf6\xb1\xf4\x96\xc1\x6f\xf6\xf0\xdd\x1e\x9f\xb0\xe2\x7a\xf4\x91\xcf\x47\x2b\x2e\x35\x0e\xa8\x47\x31\x66\xff\x32\xe0\x6f\xe6\x9c\xc6\xc6\xca\x30\x9a\xc6\x2f\x62\x81\x48\x07\x1c\xcf\xc2\x6c\x18\xc0\x0c\x17\xcc\xe0\x0a\x84\x11\x68\x29\x66\x4a\xcd\x5a\x05\xd4\x34\x58\xb9\x38\x04\x7e\xc8\x28\x01\x29\x48\xf8\xd1\x02\x19\x2c\x75\x06\x05\xdf\x6f\x8d\x3d\x10\x07\xa8\x44\xb3\xb7\x8c\xaa\x5d\x6d\x19\xf7\x7d\xf5\x46\x46\x42\x8a\x86\x72\xd4\xf0\x98\xae\x61\xee\x89\xac\x96\xf6\xfe\xef\x9c\x53\x68\xb5\x43\x1b\x0d\xba\x41\xb5\x6c\xd0\x91\xd9\xf8\xec\xdf\xc4\xa3\xfa\x9f\x13\xf6\x2c\xee\x6e\xb4\xd5\xf6\x6a\xcd\xef\xb7\x2c\xbe\xf2\x45\xa1\x58\x61\xca\xaa\x57\xe1\x48\x4d\x0e\xb5\x25\x5e\xce\x72\x45\x8f\x4b\x1d\x33\x8c\x3c\xf1\xac\xa0\xb6\x3a\x83\x50\x8c\x7c\x4d\xe1\xeb\x63\xea\x19\xcd\xb5\xf6\xdb\x3d\x68\x20\xf0\xac\xc1\x87\xe6\xf0\x89\x72\x9b\xcb\x76\xfe\x15\x1d\x04\x14\x7b\xb6\x0c\xce\x43\x6e\x50\x65\x50\x77\x1c\x59\xdc\x23\xb5\x25\xd6\xa4\xfa\x31\xe7\x2c\x1d\x55\x06\x9c\xcc\xb2\x26\x5b\xb4\x92\xff\x1d\x59\x78\xe9\x72\x6e\x26\x30\x2d\xe8\x23\xcd\xf2\x39\x44\x00\x2f\xd9\x7e\x18\x57\xee\xeb\x52\x36\xd0\x6a\x5d\xce\x5c\x6a\xdc\x19\x20\x23\x54\x96\x5b\x75\xb7\x33\xe7\x41\x4a\xec\xb2\xa1\xdc\x47\xf5\x07\x76\x18\xea\x24\x99\xb1\xcf\xf4\x5a\xdd\x9c\x7d\x3d\xb2\xcc\x9e\xc5\x78\xe6\xae\x82\x51\xd0\x35\xb5\xa5\xb3\xb4\xba\x47\x08\x90\xd8\x0c\xe0\x5f\x79\x87\x8f\x26\xc3\xc3\x25\xa6\x1d\x99\x93\xba\x0b\xdb\x80\x94\x83\x68\x25\x40\x8d\x7d\xf1\x28\x50\x1f\x02\x3f\x3e\x74\xd0\xf5\x53\x93\x4e\xb1\x19\x96\xb2\x5d\xf7\xde\x61\x06\x9b\x92\xb7\x53\x88\x48\x4d\x90\xd0\x87\x82\xb0\xda\xeb\x00\xc6\xc8\xd2\x32\xe7\xa1\xec\xda\x62\x8b\x04\xc5\x87\x9a\x05\x7c\x0b\x9f\xc9\x32\x6f\x25\x98\xd0\xe0\xf7\x90\xa0\x7b\xa5\x1b\xb8\x16\x09\xb9\xa8\x90\xb8\x5f\xb6\x4e\xb4\x61\x7e\xe6\x9f\xd1\xdd\x06\x19\xa8\x3e\x7b\x97\x82\xcf\xb2\xb7\xd2\xfc\x23\x93\x30\x6f\x3f\x7f\xfa\x32\xeb\x94\xe5\x8b\x7c\x86\x7d\x4b\xbd\x5c\x87\xa0\x85\xb8\x49\xbf\xcd\xb9\xe4\x6a\x20\x2c\xb5\xa2\xb7\x6d\xa6\xfa\x02\x07\x64\xff\xd3\x1e\xe3\x52\x8a\x92\x9e\x7f\x53\xc4\xe2\x76\x56\x5b\x11\x26\x2e\x56\x2a\x39\x9c\xc7\xc0\x05\xd7\xab\x5f\x1c\x47\xe2\x9b\x67\x3c\x06\x30\xf1\x74\xb5\x2b\x08\xb7\xd8\x65\x0c\x1d\xcb\xdb\x77\x68\xf8\xe5\x15\x7d\x11\xa8\x6b\x70\x38\xc6\xdd\x3f\x36\x02\x10\xc1\x78\x23\x7d\x02\xd9\xe1\xe5\x45\x9f\x3a\x22\x7b\xe2\x54\x90\xa4\x5c\xa4\x55\xd1\x3f\xf2\x1c\xf0\x12\xd8\xba\x9e\xa9\x1f\xf6\x3d\x78\x84\xaa\xf0\xe1\x7e\xe6\xc3\x04\xb8\xc7\xf8\x13\xed\x69\xe8\xcf\xdd\x53\x58\x0d\x11\xc0\xbd\x4c\xbe\x08\x28\x45\xa2\xe1\xb0\x1d\x72\x26\xdb\xf7\xc8\xad\x59\xba\xf6\xe4\xa6\x08\x0a\x01\x9e\x1f\x1c\x77\x2c\x6e\xd5\x6b\xb0\xf1\xc7\x70\x7e\xec\xfe\x39\x9c\x4e\x6e\x2a\xd7\xd9\xaa\x1b\x51\x29\xce\xb0\xa1\x1d\x36\xbb\x76\x0f\x30\xed\xb0\xa5\x19\x7a\xcd\xc7\x65\xc7\x38\x6c\xf2\xb0\x82\xa0\x3d\xd9\xe1\x2c\x67\x87\xe4\x4c\xc1\x12\x1a\xa4\x2d\x18\xe4\xe3\x3c\x84\x2b\xcc\x90\x42\x56\x81\xf3\xe1\x57\x53\xc0\x90\xba\x41\x7d\xc8\x72\xbd\x74\xf6\x9b\xe1\x21\xd6\xbf\x8b\xc3\x7d\xdf\xf2\xe5\x3f\x75\xdf\x54\x86\xdd\xc1\x54\x60\xeb\x62\x83\xb6\x45\xbd\x0d\x34\x87\x75\xb5\x7d\x25\x4d\x40\xcd\x30\xe5\xec\x9c\x75\x1b\x3d\x52\x7b\x22\x4f\xb4\x71\xab\x57\xba\xac\xb4\x2d\x67\xb8\x5c\xd0\xa4\x72\xc0\x08\x53\x11\x9b\x1c\x23\x92\x0a\xf5\x4a\x50\x6c\x3b\x20\xf1\x0e\x1b\xaa\xea\xf3\x0a\xfb\xec\xa0\x92\x5c\x91\x98\xd5\x37\xf5\x5e\x36\xe3\x62\x81\x40\x06\x61\x6d\x3c\x7a\x04\xea\x95\xa0\x1d\xaa\x59\xba\x7f\x05\xeb\x02\x76\x94\x5c\x72\x7a\xd1\x6a\xfa\xe5\xef\xa3\xaa\x96\xfd\x0e\x4b\xed\xb1\x51\x7a\x48\xd1\x04\x23\xed\x8f\x5a\x26\xa4\x7a\x07\x2b\xa4\x9c\x00\x4d\xbf\x89\xfd\x51\x16\x15\x14\x5c\x65\x76\x72\xbb\xa4\xcc\x96\x6c\x95\xa4\x2d\x4c\xf4\xcb\x06\x1e\xde\xf5\xb4\x37\xab\x74\xc8\x6e\x4b\xef\xd0\x03\x76\x9b\xd7\xf2\x2e\x7f\xec\x35\xd3\xe5\x33\x50\xf7\x2e\x07\xf5\x02\x3f\x83\xff\x6a\xc9\x43\xce\x94\xe8\xc8\x91\x3b\x94\x12\xaf\x08\xc3\x51\xff\x64\x8c\xf6\x08\x1a\xbf\x6e\x9b\x48\x3c\xe6\xfb\xd1\x4e\x71\x67\x65\x38\x77\x87\xfc\xbc\xe4\x0b\xd8\x95\x6d\xd1\xef\x4d\x1d\x92\x2f\x2f\xcf\xb2\x9f\xd2\x3f\x29\x87\xb9\x5e\x04\xb9\x8b\x23\x52\x97\x1f\x10\x22\xb7\x0a\x32\x42\x37\xd1\x89\x62\x52\xd6\x00\xc8\x2e\x79\x2f\x12\x7a\x3c\x83\x77\xff\x18\x58\x5c\x7e\xa8\x31\x26\xa7\x96\x96\xa5\x6a\x19\x54\xbc\xa6\xcd\xef\x6a\x67\x6c\x01\x84\x02\x34\x35\xfe\xea\x9c\x0c\x57\x6a\xa6\x4d\xa6\xa2\x89\x42\xfb\x14\xd6\x73\x3e\xd2\x88\x32\xc4\xe8\xab\x4c\x94\xa4\x87\xec\xfe\x7e\xee\x55\x8f\x8f\x93\xb9\xde\xef\x05\x94\x3a\xfd\xbd\x3e\xa6\x3b\x47\x73\x48\xc2\x9d\x8f\x01\xf6\xe5\x72\x30\xb5\x43\xfe\x72\xa1\xa8\x68\x3c\x28\xab\x58\x35\x12\x88\xce\x11\x56\xb9\x68\xd8\x98\x91\x40\x73\xee\xea\xd5\x8b\x23\x8a\xfa\x6d\x67\x0f\x1e\xd6\xa2\xef\x17\x7e\x64\xcd\x16\x92\x30\x13\x48\xd4\x5b\x21\x14\xee\x6f\x31\x59\x81\x58\x06\xf6\xd5\x6d\x53\xcd\xf7\x93\x7f\xb7\x94\xfb\xeb\xb5\xee\x80\x60\xa2\x3b\xfd\x05\xa4\x11\xf6\xc2\x7e\x76\x17\x74\x94\x2e\xbd\x4c\x42\x09\x07\x2b\x30\x4d\x3e\xd1\xc2\xe9\xf2\x9f\x7d\xeb\x22\xb8\xa6\x39\x23\x0a\xb0\xd9\xce\x45\xd3\x3d\xb5\x14\x41\x3f\x81\x6a\xcb\x46\x72\x5b\x7c\x85\xa4\x9f\xb0\x85\x52\x1d\x76\xc9\xfd\x3c\x82\x81\x02\x2b\x81\x46\xe6\x68\xcd\x34\xd6\xee\x0e\x13\xa8\xde\xaa\x98\x9a\xf1\x72\x93\x00\x41\xc5\xad\x9d\xe3\xb8\x52\x93\x44\x0f\x69\x2a\x6e\x8a\xfc\xa4\x43\xb7\x4c\x41\x7e\x6a\x2c\xfb\xbd\x04\x40\xdc\x7a\xd6\x06\x25\x73\xa8\x01\x1a\xec\x99\xec\x7b\x0e\x1e\x85\x9a\x3d\xed\x53\xf6\x28\xee\xf2\x04\xfb\xe3\x55\x7e\x33\x77\x69\xca\x95\x42\x0d\x9a\x44\x14\xfb\x6e\x05\xc7\xe5\x4a\xce\x27\x6c\x73\x99\xf4\x26\xa2\xd2\x14\x69\xa8\x57\x83\xbd\x2b\xc9\x64\x6a\x14\xad\x97\x09\x6f\xa2\x95\xa6\xda\x40\xe2\x88\xdd\xa8\xc5\x70\xeb\x87\x51\x72\x8c\xbf\xaf\xae\x77\x68\x25\xa8\x17\x9d\x06\x26\xd9\x7a\x73\x0b\x21\x90\xed\x11\x20\x83\xe7\x6a\x53\x3e\xd6\x52\x0a\x87\xbe\x8b\xa6\x15\xb6\xb1\xaf\x2b\xdf\x49\x86\xe7\x0e\x70\xb2\x7b\x9e\xde\x01\x82\x0c\xca\xd9\xd3\xb0\x88\x4d\x44\xf4\x6e\x70\x40\x5f\x5a\xde\x4c\x3c\xd5\x3f\xca\x0a\xf9\x18\x27\xfb\x2d\xdb\x4a\x4c\x59\x6f\xf6\x9e\x4d\x6e\x81\x36\x99\x4e\x07\xf9\x9c\x3a\x76\x96\x46\x2f\xeb\x6f\x24\xd4\xa9\xc3\xa4\x44\xc2\x37\x6c\xde\x82\xde\x01\xe3\x3d\xf7\x9d\xf8\x65\xbc\xcb\xdc\x40\x9b\x7b\xf5\xa0\xfa\x66\xb7\x06\xf2\x0d\x2d\xfd\xb2\x89\x2b\xb3\xf3\x5f\x28\xcb\xb1\xd0\xb5\x17\xb3\x9d\xf8\xf5\xbe\xc6\x21\x18\xa7\xaf\x91\x67\x1c\x49\x8c\xb3\x05\xa0\xe5\x20\x4b\xf8\x73\x92\x8f\xe6\x9e\x0f\x68\x0d\x6d\xed\x2a\x95\xbd\xd2\xc5\x59\x82\x53\x41\x7b\x86\x9d\xfa\xbd\xbf\x3a\x53\xcb\xbd\x1a\x59\x55\xc3\xbd\x2a\x09\xe9\xa5\xdc\x0f\x3e\x8d\xab\x15\x1e\xe2\x1c\x67\x97\xe8\x64\xe7\xcb\x8e\x7c\x3d\x26\x1b\x57\x18\xc7\xf6\xd9\x25\x00\xc9\x3e\x56\xcf\xc9\x16\x06\x97\xe5\x3a\x9d\x84\x44\xb4\x41\xa2\x56\x28\x3e\xe0\xb4\x85\xc1\xb8\x69\x09\x87\xe1\xac\x0b\x46\xd4\x1d\xbc\xc5\x76\xa6\x06\x4c\xdd\x27\xc7\xb6\xd2\x3b\x58\x96\x06\xf8\x28\xaa\xff\xdf\x94\xa1\x68\x74\xb7\xc0\xa1\x9c\x9a\x7f\x49\xa6\x04\xd4\x02\x5c\x2d\xa2\x68\x18\x73\x3c\x46\xb7\x08\xdb\xde\xa3\xa6\xda\xf1\x98\x96\xba\x37\x31\x5c\x70\x03\x5b\xc2\xbc\x2d\x91\x94\x4a\xa8\x39\xd2\x4f\x49\xd0\x8e\x98\x57\x18\x9f\xf9\xa9\xa1\x3c\x89\xce\x93\x5c\xda\xc5\x95\x19\xef\xf7\x68\x42\x55\x67\xbb\xe3\x6a\xea\xd0\xb2\x4d\xbd\x21\x73\x40\x60\xe3\xa3\x1e\x13\x31\x9f\xb2\x4d\x2f\x55\x15\xbb\x3b\x33\x14\x5a\x37\xb2\x56\xd8\x91\xdf\xa7\x20\xb6\x72\x91\xdb\x2c\xfa\x28\xfb\x1e\x1b\xa6\x43\xff\x61\xee\xca\x63\x93\x9f\x23\x60\x2b\x35\xa6\x90\x13\xe5\x5e\xcd\x72\x31\x82\xfa\xe8\xf2\xf4\x41\xc0\xe9\x3b\xb5\x13\x61\x2a\x56\x4e\x1a\xfd\x18\xad\x3c\x5f\xcb\x2d\xfb\xd7\xb2\x4e\xb7\xf8\x59\x95\xa8\xc9\x26\x6a\x9c\xa5\xed\x19\xcd\x9c\xf2\xf6\x48\xcd\x28\x5b\x90\x10\x51\xe4\x5f\xab\xad\xcb\x0c\x23\xa8\x6d\xeb\x7f\x7d\x63\xb1\x87\x3b\x5f\xa5\xbe\x0a\xbb\x3c\x59\xe7\xa9\x0b\xa2\xdf\xde\xd6\x79\xa0\x90\x54\xf9\xc6\x39\x45\xc0\xec\x6a\xd1\x39\xb4\x1c\x97\x97\x1e\xb5\x1c\xb7\xda\x91\x89\x3e\x8c\x5b\x2e\x41\x37\x8f\x47\x0f\xb6\xf1\xbd\x85\xda\x43\x44\x04\xdf\x81\x0d\xa8\xce\x9a\x30\x5d\x17\x1b\xc5\x3d\x1f\x35\xd4\x39\x2a\xb3\xa0\x1d\x11\x39\xb6\x12\x24\xc4\x9f\x32\x44\xd0\xaf\x49\x33\x8c\x73\x35\x05\x65\x6e\x12\x59\x20\x54\xbe\x78\x7e\x81\x2d\x42\xac\xa2\xd2\x84\x8c\x32\x3f\xc8\x4d\x34\x67\x88\x4c\xe9\xb1\x4e\x82\xda\xe0\x05\xda\xd5\xe6\x0d\xaa\xfc\xba\xbf\x2f\xbb\xeb\x23\x0c\xbb\x31\x0e\xcf\xfd\x55\xd6\xa4\xce\xaa\x0a\x5a\x0c\x5c\x1d\x94\xf3\xb7\xaa\x49\x8a\xc4\xde\xe5\xa1\x3b\xb4\x83\x29\x9b\x8f\x72\x9d\xd8\x40\x69\x35\xc5\xfa\x66\x47\x3e\xbb\xce\x96\x8f\x20\x36\x2f\x28\x28\x63\xd9\x0a\xcb\xc1\x41\x5e\x6d\x30\xde\xfb\x68\x00\x73\x55\x13\x3f\xb0\x6e\x9e\x84\x0f\x3c\x0c\x16\x0a\x34\x5f\x6b\x15\x95\xb4\x52\x3c\x94\x21\x7f\xd4\x72\x91\xe1\x3a\x72\xc3\xc7\xbc\x93\x60\x89\x6c\x5d\x70\x95\xd8\xeb\xc1\xed\xd2\x5e\x3b\x85\x7c\xa9\xce\xac\xf8\x2e\x73\xb4\xd9\x5a\xb9\xd3\x15\x21\x8f\x78\xeb\x4d\x3e\x65\xff\xc2\xcb\x6f\xc9\xa0\xb9\x69\xf2\x5f\x32\x10\x5c\x55\x9d\x0b\x2d\x16\xfa\x18\x01\xb0\x53\x63\xe8\x8d\x9d\x0a\x75\x2c\xe2\x13\x60\x94\xd4\x9b\xd4\xf9\xf8\x56\x17\x6b\x09\xb5\xe8\x22\xbe\xe8\x5c\xa6\x6c\x93\xaa\x67\xc5\xe5\xcf\x26\x3e\xce\xe0\xc6\xb7\x7a\x3b\xe8\x5f\x49\x5e\x92\xb9\x06\xbb\xe1\x42\xc4\xd1\x7a\x97\x5c\x7d\xa8\xe6\xcc\xc9\x0a\xd1\xea\x3c\x6a\xc2\x22\x7c\x26\x23\xdd\xd1\xe3\x98\x2d\xc2\x41\x70\xfc\x32\x80\x78\x18\x55\x93\x4d\x3d\x7a\x76\x49\x16\x10\x00\xad\x07\x2f\x62\x94\xa7\xeb\xb6\xd3\x6d\x97\x42\xad\x4f\x94\x6b\xae\x46\x9b\xb3\x33\x7a\xe6\x4a\x8e\xc3\xa8\x7d\x44\xe3\x69\x3b\xf2\x79\xf7\xa8\x66\x7d\xd1\x7b\x48\x31\xc4\x8b\xfc\x9b\xe6\xb0\x5d\x81\x08\xc7\x2f\xfc\x63\x83\x0c\x94\x79\xb5\xe3\x33\x13\x8e\x33\xbb\x26\x98\x24\xd3\x87\x6c\x7f\xf8\xda\xb3\x0d\x75\x56\xb1\x0d\xd2\x6b\x06\x79\x4b\x20\x9b\xd8\x42\x67\xb8\x54\x94\x6d\x35\x49\x30\xe3\xfe\x27\xee\x0c\x7f\x57\x35\xae\xca\x6a\x1a\x62\x1d\x30\x6a\x64\x52\x01\x5d\xda\x2e\x6e\x4c\xf9\xab\x4c\x0d\xb9\x6d\x73\xfe\xd8\xac\x5a\x79\x42\x7a\x99\xa9\x0d\xd0\x0a\xf9\x77\x7a\x6e\xda\xae\x3e\x45\x93\x78\x0a\x23\x7d\x8e\x41\xb3\xff\xc9\x9f\x4d\xa7\x10\x8c\xa1\x37\x31\x4d\x98\xf7\x68\x2e\xcc\x92\xdb\x1e\xdc\xb6\x5b\x8d\x29\xf3\xaa\x89\xcc\x67\x34\x59\x25\x4d\x86\xd3\x60\x05\xed\xcb\x7c\x79\x5e\xf4\x99\xb6\xcc\x57\xa1\xee\xa9\xb1\x65\x7e\x18\xab\x34\x32\xb2\x74\x87\x42\xf3\xcd\x56\xd9\x10\x43\x51\x73\x90\x55\x4a\xc2\x9e\x42\x1d\x9f\x0f\x35\xc7\xda\xa2\x3c\x3e\x91\xde\xf7\xb8\xd6\x13\x0e\xcd\x5f\x29\x05\x2e\x1f\x97\xdf\xff\x24\xf4\xa1\x4f\x7e\x66\x43\x28\x67\xfb\x52\xc8\x49\xe7\x91\x91\x83\x70\x63\x6e\xb2\xb3\x94\x7f\xd4\x76\xa6\x15\x22\x27\x24\x04\xcd\xcb\x64\xbf\x1f\xe7\xb2\xfa\xaa\xf3\x84\xa4\x90\x48\x54\x4e\xf3\xb9\x94\x7a\x6a\x13\xe9\xa5\xfc\x20\xca\x43\x4b\xe3\xf3\xe4\xad\x7d\x41\x1e\x89\x33\xf9\x70\xca\xd7\x6c\xd8\xce\xe8\x14\x0e\x50\x48\xc4\x50\x1c\x16\x20\xac\x6a\x21\x61\xcd\x8b\xbd\xf9\xb0\x39\x53\x0b\xd1\xbe\xaf\x8f\x07\x6e\x62\xd5\xb0\x6d\x69\x89\x8e\x2a\x49\x1f\x72\x07\xee\xa1\x03\x98\xbd\x91\x18\x22\x98\x61\xd0\x81\x1b\x56\xd8\x70\xf1\x0b\x28\x9b\xfd\xdc\x8e\x66\xcd\xac\xd1\x63\x42\x55\x21\xfb\x8b\x52\x87\x4c\x91\xe9\x82\xa6\x12\x14\xdc\xfe\x4b\x0f\x2b\xf3\x9b\x1a\x4c\xa1\x7b\xbf\x57\xd1\xe9\x3d\x8b\xaf\x75\x77\x8e\xfd\xdd\x2d\xb6\xfb\xe8\x66\x0f\x1d\x19\x35\x48\x9b\xb9\x33\xfd\x3f\x5d\x0d\xb0\x64\xb4\xd3\x7f\x29\x55\xa9\x23\xfa\x98\x95\xdb\xff\x1a\xdd\x84\xd9\xfe\x36\x7e\xd3\x4e\x70\x4f\x27\xe4\xcb\x22\x21\x3f\xc5\x50\x0e\xea\xbd\x7e\x7d\x6c\xba\x0e\x98\xd0\x3c\xb9\x7b\x74\x8c\xf6\x4f\xc4\x3e\xc5\x7a\x21\x9f\xa8\xbd\x97\x06\x75\x91\xe0\x05\xa8\x87\x86\x57\x44\x2f\xe4\x40\x7e\xfd\xfe\x07\x3b\xff\x44\x6c\x61\x96\x85\x5e\x6c\x17\x1e\x05\x79\xa2\x2f\x75\x96\x1b\x38\xe7\x12\xd0\x48\x77\x0e\xda\x2a\xb2\xa1\x14\x4d\xa3\x13\xf2\xcf\xde\x82\xa4\xe8\x29\x8d\xf4\x69\x0e\x6a\x0d\x84\xad\xf5\xfe\x14\xd6\xb9\xf5\x60\xbb\x99\x52\x33\x7d\xa5\xab\x95\xad\x27\xe5\xfe\x49\x1a\xa4\x25\xbc\x39\x08\xef\x77\x63\x67\x65\x50\xa9\x6e\xbc\xc7\xe8\xc6\xf4\xd7\xaf\x8e\x78\x23\xdf\xc6\x50\x42\xf9\xc9\x73\x8d\xdf\x77\xce\x9b\x29\x36\x97\xa5\x46\x7f\x0f\xa5\x52\xeb\xb6\x29\x7a\x48\x7e\x65\x10\xc1\xf1\x33\x97\x57\x94\xf7\x34\x52\xdd\x1e\x9b\x16\x78\xc5\x05\x58\x6e\x74\x8a\x87\xe3\xee\x92\xee\x23\x71\xcd\x4b\x5d\x4b\xb7\x92\x6b\x57\xc2\x63\xf7\x65\x4a\xe5\xf8\x4f\xbe\x89\x44\xf7\xa2\xb5\x8b\xe2\x75\x8a\xf6\x8e\x75\x37\x35\xd2\xad\x9a\x6f\xa0\xba\x88\x2c\xb6\xda\xc3\x5a\x0c\x9d\x52\xbf\x95\x6a\xa4\x81\x8c\x1b\xfb\x5b\x90\x78\x5a\x7f\x4e\x9b\x38\x5a\x52\x84\x34\x82\xe0\xf3\x94\x95\x38\x95\x05\x6b\xd4\x1f\x52\x2c\xc4\xb6\xe0\xd0\x30\x23\x50\xc3\xdd\xa4\xea\x3e\x8f\x61\x68\x03\x4a\xb9\xb5\x45\xe2\x75\xb9\x30\xfe\x92\x86\x08\xbf\x66\xf3\x86\x61\x70\xed\x18\xb1\x75\x65\x82\x37\xbf\xa7\xac\xb1\x5c\x07\x21\x5c\x62\x3e\x74\x15\x2e\x9d\x4f\xa5\xc5\x49\x71\x93\xe4\x23\xc9\x96\x53\x04\xdd\x80\x1c\xe4\x09\x1e\x6a\x26\x30\x66\x9d\x11\x07\xd5\x93\xdb\x47\x66\x21\x35\xe7\xdf\x9f\x65\x4b\xbb\x23\x4a\x9a\x13\xc1\x24\xea\x9e\x9c\x8a\xd0\x6c\xe0\x46\x53\x05\x4b\xea\xf6\x50\xae\xa4\x76\x52\x9f\xec\xb7\xb1\xb9\x29\x45\x2f\x24\xbb\x64\x94\x59\x27\xb4\x4e\x39\x18\x52\xcd\x04\x34\x97\xff\xc2\xb8\x3d\xbd\x3d\x6f\x7a\x2c\x35\x9d\x28\x40\xce\xa5\xeb\x11\x93\xa1\x0e\xbe\x68\x41\xea\x18\x95\x79\x5b\xf2\x82\xa6\x6f\x9f\xef\x2c\x54\xa2\xe9\x9d\xe6\xd6\x98\x2e\x0d\xe5\xb7\x8b\x84\x26\x0d\xab\x13\xd9\xca\x70\xd0\x5f\x9b\xb2\x43\x8a\xa8\xf4\x74\x85\x07\xa6\xf3\x17\x95\x9c\x0c\x30\x0e\x1b\xe6\xa8\x51\x14\x1a\x27\x14\xa1\xe1\xbc\x0f\xef\x54\xde\xec\x55\x59\x04\x92\xc2\x95\x81\xb0\x2d\xd9\x4c\xec\xb2\x16\x68\x5d\x85\x57\xca\xe1\x2e\x47\x19\x27\xed\x79\xd2\x5a\xca\xa2\xe9\x13\x6e\x1e\x91\xb2\x6e\x2a\x91\x92\x79\xd9\xc2\x01\x53\x49\xba\x29\x01\xe1\x69\x6e\xce\xe9\xab\x8d\x94\x75\x03\x2e\x9e\xd2\x19\xca\x56\x47\xb9\xe2\xd3\xe0\x02\xa2\xcc\xc5\xfb\x53\x29\xe2\xe3\xe6\xa6\xd3\xfd\x8e\xcf\xed\xcf\x50\x13\xc9\xbb\xd7\x05\x9f\xc3\x1e\x1a\x96\x6f\x22\x23\xcd\x96\x21\xa4\x0e\x5b\x04\xf5\xc3\x2e\x7a\x38\x43\x1c\xd6\xb4\x78\x6f\xf7\xd7\xf3\x6b\xfa\xe4\x0f\xf3\xd5\x3f\x99\x2c\xf7\x4f\x6a\x35\x19\xd1\x2e\x53\xcd\xa3\xed\x72\xfc\xb0\x33\x77\xb9\xf5\x1d\xee\xad\xbd\x91\xff\xa3\x1f\x1b\x71\xe3\x1e\x4c\x65\x82\xe1\xa9\x02\xa7\x10\x5e\xb7\x6f\x98\x07\x6b\xe2\x7f\x33\x0b\xd5\x43\xef\x20\x21\x5d\xe8\x9d\xe1\xb0\xc8\x17\xfd\x25\x72\x52\xb4\x93\x2e\xbf\xe0\xf2\xa9\x5a\xc5\x3c\x44\x70\x4e\x99\xa6\x45\x49\x7b\xb1\x73\x27\xd2\xd2\x8a\xc0\x9b\xe8\x10\xd1\x9e\x9b\xa7\xa7\xda\x4a\xd8\x7a\x0e\x95\x75\x64\x24\x21\x6c\x30\xd1\x3e\x3a\xc2\x3a\xb3\xbb\xdc\x38\xd8\x40\xa2\xb3\xd2\xd4\xdb\x9a\x73\x51\xde\xfd\x8d\xba\xac\x71\xf2\x6e\xfd\x78\x2b\xbb\xf5\x70\xdf\x15\x8e\x59\xd5\x47\x73\xfb\xdf\x19\xe9\x0d\x78\x53\x96\x4d\x6d\x67\xf0\xdf\x68\x3c\x62\xfa\x12\xb3\xce\xa3\xe1\xa4\xcc\x11\x53\x9c\x62\x8a\x3b\xa8\x5e\x9e\x39\x72\x6f\xfe\xa0\xa2\xc0\x7f\xcd\x48\xdd\x12\x7d\x29\x93\xd3\x77\x60\x02\xfd\xc4\x80\x8f\x1f\x93\xe8\xa3\x87\xcd\x6f\x39\x14\xc3\xa9\x5c\xf0\x9c\x29\x0f\x68\x4e\xfc\x5b\x7c\x65\x40\xf0\x08\x67\xb7\x4e\x86\x32\xee\x92\x6c\x35\x95\x9e\x7f\x58\x14\xb8\xbf\xdd\x86\x79\x07\x99\x72\x3f\xf7\x2b\x0a\x74\x87\xd5\x69\x50\x68\x38\xb6\xfe\x4b\xf6\x27\x1a\x36\x6e\x7e\x95\x01\x5a\x3d\x4b\x1f\xfd\x2b\xf4\x4d\xfd\xd4\xa6\xb3\x59\x0f\x7a\x56\x0c\xf8\x2f\xf3\xc3\x4a\xda\x9c\xc6\xed\x53\xd6\x1f\x3c\x2a\xef\xe9\x9d\xc2\x21\xa5\x37\x70\x89\x4d\xe3\x10\xfd\xaa\x20\xd6\xa9\x5f\xa5\x06\x52\x59\xa0\x7a\xb9\x42\xa2\x67\x15\x00\x83\xfa\x57\xa2\x3e\x4d\x4a\x0d\x5f\xc7\xff\x50\xa1\x9c\x39\xb1\xa6\x3f\xdd\x40\x41\x87\x11\x42\x44\xe9\x0d\x1a\x32\xb7\xb2\x91\x46\xde\x39\x5f\x75\x96\xe7\xde\x6e\xfb\xc1\x9d\x35\x97\x9a\x4b\xd3\x58\x19\xd6\xfb\xd3\xa8\x04\xa9\x51\x7e\x43\x65\xe3\x0a\x66\xa0\x3b\x62\x76\x0a\x7d\x98\x35\x84\x01\x56\x4c\xdf\x39\xf6\xd1\x98\xa3\xfc\x5f\x3d\x40\xc0\xd5\x62\x77\xec\xbd\x63\x64\x77\x06\xd1\xa9\x7b\xa6\xda\x75\x97\xda\x50\xf2\xab\x9e\xc1\xeb\xa6\x4e\x0d\x35\xcb\xb0\x4d\x01\x88\xee\xe9\xdd\x89\x14\xa8\x94\x89\xf8\xc8\xe5\x2b\xd7\x64\x48\xa7\x14\xf1\xe1\x12\xf8\xfe\xf6\xca\xdf\xd3\xe3\xe7\xe1\x1c\x8a\xb6\x9e\x7a\xd0\x38\xb0\x13\xc6\xca\x87\x83\xd5\x0d\x91\x4d\xee\x31\x54\x2a\xa9\xd9\x16\xbe\xc5\x1b\x6c\xb8\xf2\x76\xbf\xd9\x76\x25\xfa\x50\xb9\xf3\xdb\x2d\x65\x98\xde\xe2\x36\x9a\x60\x55\x83\xde\x69\x88\xac\x1e\xd9\xab\x9f\xbe\x14\x5b\x4c\x9e\xd4\x88\x71\x16\x8d\xdb\x79\xeb\x77\xe7\x4c\xfc\x3d\x77\xf6\xd6\xca\x7e\x5a\xd3\x15\x01\xbf\x84\x30\x0c\x1d\x0a\xbd\x04\x9d\x44\xbf\x7a\x75\xf1\x6a\xa1\xdf\xea\x47\x05\x26\x57\x3d\x18\x01\xf3\xe8\x04\x76\x63\xa5\x6a\xd1\x6c\xec\x26\x75\xd8\xf2\x96\x63\xd4\x15\x93\xe8\x77\x50\xea\x38\x75\xe5\xe6\x3d\x1c\x67\x48\xa1\x54\x2b\x4f\xe2\x00\xec\xfd\x78\x0a\x96\x8b\xa2\x66\xe0\xad\x9f\x9f\xf2\x83\xb1\x95\x75\x12\xa6\x52\xb0\xa2\xda\x6f\x67\xf9\x12\x92\xed\x5a\x22\x5e\xd1\x4d\xbc\xb3\x8b\x16\xde\x41\xd9\xc9\x7e\x1d\xf4\x71\xc0\x32\x3c\x94\x65\x3c\xd0\xf0\xab\x2f\x09\x33\x9b\xae\x8a\xcf\xbe\x4c\xd3\xa3\x37\xe8\xbf\x8d\x33\xc0\x98\x24\x56\x97\x33\xa9\x38\xb0\x6f\x8c\x7c\x52\x3d\x86\x0f\x8c\x15\x63\xa8\xfa\xa2\x6f\x98\x86\x1a\x02\x89\xbe\xff\x95\x7c\xbf\x57\x70\x09\x63\x91\xf5\xf1\xa3\xfb\x6b\xc8\x0c\x6a\xd7\x1b\x51\x6e\x04\xad\xdf\xd4\x4f\x7c\x65\x31\x5f\x56\xc0\x5c\x6c\xfa\x29\xd0\xa3\xaf\x92\x36\x72\x68\x37\x77\x16\x0f\xfa\xea\x29\x1b\x52\x1d\xc9\xbe\x75\x1f\xf1\xd1\x5f\xf1\x67\xb0\x08\x56\x07\x71\x4b\x66\x4d\x52\xd1\x62\x0d\xdb\xd2\xe5\x2d\xb2\x3d\x66\xb0\xc9\xf4\x61\x43\xd1\x6d\x35\x5b\x30\xc5\xa3\x87\xa8\xbf\x21\xc3\x98\xbf\x29\x3f\x20\x8a\x4b\x86\x7e\x2c\x6d\xa0\x93\x79\x8c\x5e\xa1\x1b\x79\xe7\x01\xeb\x03\xad\x21\xe5\x20\xbe\xb7\x45\xfe\x1b\x3e\x7f\xcb\x66\xe2\xf8\xdb\x95\x62\xb4\x8c\x55\x9c\xbf\xf4\xef\xe9\x23\x16\x72\x19\xb6\xd9\xdf\xc4\xd2\x5b\xba\x42\x53\xd7\x49\x2f\x9d\xc0\x8e\x30\xe2\x3d\x7f\x1c\xbe\x0f\x52\xb8\x5b\x69\x78\xe4\x97\x0f\x4e\x67\x2e\xd8\x19\x54\xdd\xb9\x3a\x41\xce\x11\xb7\x30\xdb\x28\xa3\x9c\x3d\xd6\xe3\xa0\xaf\xd8\xcf\x1e\x98\x29\x37\x67\xed\x6b\xe9\xb5\x32\x45\xcf\x71\x4a\x5e\x97\xe7\xdc\x91\x0f\x1a\xff\xf4\xb8\x57\xcf\x57\x94\x9f\xac\x7e\xbe\xfe\x2a\x85\xd8\xcc\x14\x1b\x25\xfa\x8f\x1d\x98\x5f\x37\x6a\xe0\x76\xdd\x44\x12\x3a\xcd\x1b\xe2\x2a\x96\x93\x03\xb6\x23\x8a\xba\x44\x62\xba\x3e\x23\x90\xd4\x21\x3a\x7c\x7b\x90\xec\x98\x4c\x3b\xeb\x01\x35\x8f\xb3\x94\x37\x91\xac\x49\xfe\x07\xff\xc1\x64\xff\x1d\x98\xf2\x38\x93\xe4\xed\x9b\x1a\x22\x92\xdf\x21\x84\x43\x3e\x73\xdc\x59\x66\xf2\x8d\x55\x2c\x58\x6c\xfe\xd7\x4a\x75\x96\xf7\x8a\x24\x94\x09\xed\xc4\x36\xc3\xdb\xec\x69\xec\xca\x4c\xa1\x0a\x72\x42\x5c\x22\xdf\xc1\xd4\xbf\xd9\x7a\xec\x5f\xa1\xb5\x85\xb1\xbf\x37\xa0\x53\xef\x24\xa6\xa9\xaf\x3e\xca\x53\x2a\x03\x47\x6e\x26\x50\x0c\xed\xf5\x83\x1d\xbc\xbc\x15\x70\x4d\x3a\xf5\x64\xeb\x95\xaa\x39\xb8\xed\x08\x4b\x5f\x8c\x9e\x80\x20\x3e\x72\x02\x2a\x45\x41\xa9\x38\x44\x9b\xc3\x4a\xad\x5e\x59\x79\xa0\xd7\xca\xa7\xda\x0d\x8a\x9f\x41\x26\x0a\x18\xa7\x27\x1b\x63\x65\x97\x8f\x3b\x7f\x4e\x00\x4f\x66\xd9\x79\xd3\xf0\xa3\x65\xf9\x27\x7f\xb4\xef\xfc\x19\x1f\xac\xc4\x7e\xb0\x4c\xc6\x83\xcd\xee\x1f\x37\x30\xdd\x92\x3a\x88\x2f\x27\x1e\x71\x23\x02\xe7\xf6\x3e\x7a\x9a\x9b\x8d\x64\x38\x46\xb3\x74\xbf\xc9\x8d\x28\xea\x7b\x1e\xfe\x58\x2c\x57\xfe\x99\x8a\x9d\xc3\x57\xd7\x74\x09\xf4\x39\xf5\xa3\xc3\x07\xa7\xef\x4c\xb5\x3b\x25\x0f\xa4\xa6\x67\xa8\xbc\x3f\xba\x4c\xd6\x7e\xe9\x1c\x7d\x2f\xd0\xec\x2a\xbd\x88\x09\x98\x7b\xf0\xef\x70\x22\x6b\x67\x50\xf6\x62\x22\x76\xf1\xa5\x9e\xfa\x41\xc7\x41\x12\x4a\x9b\x2f\xd0\xab\x57\x89\x2d\x1f\xcc\x49\x88\x77\x98\x75\xc8\x42\x9c\x33\x8a\xba\xa5\xe1\x1f\xf1\xa0\x81\x9d\xf8\x78\x59\x7d\xcb\x5c\x2e\xac\x9a\x36\xfb\xa0\x69\xbb\x9b\x98\xe2\x8d\x3c\x20\xf3\x36\x57\xfe\x51\x6e\x77\xdf\xea\xf1\xe5\x4b\x92\x8b\x52\x99\x7d\x7f\x79\x2b\x8b\xf7\x07\xa5\x97\x18\x40\x1d\x23\x5f\x0a\x90\xf3\xac\xfc\x2f\xc3\x1e\x04\x1b\x8d\xa1\x1f\x88\xc6\xe9\x32\x44\xf2\xe8\xf3\x5c\xdc\x1c\x0d\x8b\xa3\x73\xb7\x31\x52\x15\x34\xc1\x33\x49\x2d\xd1\x7e\x88\x46\xe7\x9f\x7b\x9f\xe9\xf8\x9e\x5e\xd8\x01\xed\x4f\x71\xf1\x36\xa2\xc5\x43\xee\x10\xba\xc3\xe6\xea\x12\x3a\xa8\x61\x8a\xa0\xcf\x32\x2a\x3f\x76\xcd\x16\x5d\xae\xf4\x20\x10\xf3\x74\x3e\x0e\x49\xc6\xa3\x77\x38\xbe\x78\x47\x5c\x36\x1c\x30\xce\x12\xcb\xed\x62\xeb\x99\x81\x57\x56\xc2\x46\x97\xcb\xdd\x16\x11\xf7\xf2\x96\xed\xc5\x5b\x86\xe7\xd4\xdb\xb1\x89\x36\xe1\x31\x87\x95\xd5\xee\x38\x11\x2a\x6c\x8c\x4f\xdd\xd6\xae\x7f\x7c\x3a\x91\xf5\xc0\xd7\xa0\xa7\x07\x9a\xa9\xee\x97\xdc\xa7\x53\xfd\x86\x3b\xd9\xb0\xfe\x8e\xe9\x3e\x1c\x6c\x34\xa7\xde\x68\x08\x5b\xf7\xaa\x3b\x0a\x9a\xd3\x3d\xc8\x83\xa3\x5d\x32\xee\xfd\x61\x66\xd4\x1d\xc2\x34\x7d\x4e\x10\xfd\x6b\x2c\xce\x15\x63\xe3\x30\xd3\xdf\x03\x8c\x78\x17\x94\x0c\xad\xe9\xbc\x83\x91\xb6\x51\x77\x47\x8f\xd6\x7f\x18\xab\xd9\x31\xf7\x38\xfb\x35\xf4\x03\xfc\xb4\x72\xf5\x85\x03\xd4\xaf\xdd\x21\x65\x99\xfc\x4a\x6b\x38\xf8\xf4\xd8\x0a\xdf\xa8\x86\x1c\x91\x27\xac\x16\x53\xbf\x96\xca\xd5\x4d\x0d\x34\x7b\x93\x8c\xf3\x7a\xf4\xf3\x6c\x99\x8c\xc6\x6f\xe5\x0a\x46\xdf\x10\x08\xf0\xe0\x95\xbb\x1f\x06\xc4\x01\xe8\xd1\xe1\xb5\xda\x9d\xef\x24\xfb\x0c\x9a\x24\xeb\x56\xa1\xab\x5b\xff\xf1\x79\xdf\x6d\x69\xff\x4e\x66\x7d\xf5\xba\x3d\x1b\xdf\x91\xff\x74\xbb\x78\xda\xed\xb2\xc2\x5e\x82\x00\x78\x13\xd1\xcf\x49\x5b\xd5\x42\xb9\x36\x77\x8f\xab\x54\xef\xb0\x5d\x3b\xfa\xa1\x7a\x4e\xd1\x42\xe2\x08\x52\x60\x02\x52\x10\xf5\x49\xa7\x58\x15\x18\x2b\x8b\x7f\x58\xeb\x59\x5a\x4a\xcd\x55\xfe\xc8\xb6\x6e\x90\x00\x85\x2f\x87\x91\x32\x5d\x95\xc5\xfd\x9b\x94\xf4\x8a\x98\x8e\xeb\xef\x6a\x2c\xfa\xe5\x45\x37\x8b\x2e\xb0\x9b\x38\x5d\xef\x26\x5e\x17\x36\x9c\xa5\x94\x7e\x3a\x56\xba\xb3\x6f\x02\xa2\xe5\xdd\x29\x8e\xc4\x72\x2a\x1d\x70\x4f\x7b\x8a\x51\xa1\xb0\x6e\x75\x7f\xcf\xb5\x75\x7f\x1d\xd4\x60\xcb\x34\xf3\xb9\x4a\x57\x55\x86\x9c\x17\x68\x49\xd5\xba\x40\x45\x2e\x7c\x18\x4b\x9d\x21\x10\x81\xd5\x06\x10\xe6\xec\x86\xee\xfa\xd9\x3c\x43\xa2\x29\xdc\x57\xa7\xe5\x71\x39\xab\x07\x73\xaa\x3f\x1a\x8e\x74\xb3\xc3\x74\x23\x3a\xce\xe4\x11\x7c\x8f\x5b\x3f\xaa\xcb\x7e\x3d\x04\x01\xd5\x84\x9f\x2b\x05\xa1\xf2\x0c\xf7\x38\x60\x39\xa2\x04\xdb\x60\x3a\x4e\xc0\x56\xfc\x08\xf0\x65\xfd\x4c\xff\x7b\x68\x15\xb2\xa9\xcb\x66\xb0\x68\x92\x60\xb2\xbd\xf2\xc7\xbc\x4c\xf3\x0f\xf9\xfe\x1f\x59\x4a\x18\x73\xa3\xb4\xb6\xb3\x9e\x8a\x9e\x33\x4c\xad\x9c\x7f\x86\x68\xdb\x3e\xac\xc2\xd1\xdc\x1e\xbe\x52\xca\x5b\x6e\x08\xda\x30\xb2\x12\x38\x8a\xc4\xee\x73\xfa\x62\x22\x3a\x73\xa0\x75\x9a\x67\x73\x12\xa7\x30\xb5\x70\xeb\xa4\xb3\x04\x53\xfb\x51\xf9\x48\x8d\x3d\xd5\x9a\x30\x49\x6c\x36\x07\x9f\x96\x01\xdc\x79\xc4\x26\x8c\x1b\x84\xe4\xb8\x1f\x0b\xb1\xc8\x71\x51\x0c\x51\x84\x55\x7e\x61\x5c\x4e\xb0\xb9\x4a\x22\xfd\x37\xe5\xb7\xb2\x8e\x34\x37\x2c\x2e\x9a\x2c\xac\xab\xec\xd5\x59\x74\x97\xf3\xf2\xd4\x4d\xef\x43\xc7\x8a\x31\xd8\x28\x4b\x86\xd5\x8c\xbb\x3a\xfd\x0d\xeb\x57\xed\xe2\xc1\x49\x64\xbf\x9e\x07\x58\x0d\xdc\x46\x46\x88\x48\x7c\x01\x32\x6b\xe3\x30\x7d\xe0\x94\xa6\x16\xb2\x2f\x1a\xd0\x10\x27\x8b\x35\x9a\xb4\xf2\x8d\x40\x7c\x91\xbd\xe2\x80\x8e\x68\x9d\xea\x54\xd5\xab\xcf\x29\xd1\xe7\xb1\x21\xab\x2f\xc8\x8a\x77\x4f\xd4\x4d\x6a\x78\x99\xa4\xf7\x13\xad\x4b\xf7\xb1\x6b\x3f\xba\xd3\x81\x56\x20\x34\xa6\xa5\x28\xe0\x63\xca\xce\xbf\x26\x0c\x62\x33\x70\x4e\xbe\x7f\x7d\xa4\x49\xba\x55\x64\xb0\xba\x25\x5d\x7e\xa6\x72\x21\x6a\xcc\xd4\x08\x36\x77\x95\xb3\xa4\x1e\xf8\xca\xc2\x56\x32\xdf\xb4\x94\x2d\x27\xfb\xcb\x0b\xb8\x0f\xd1\x2d\x9e\x5a\x67\x81\x81\xab\xd8\xda\xd9\x1a\x8e\xd1\x21\x63\x45\x96\xd2\xf1\x6d\x20\x8d\x6e\xa7\xd3\x67\x53\xc3\x7a\x48\x49\x4a\x8e\x4f\x62\x8e\xd2\x0d\xde\xd1\x50\x0b\xde\x68\xce\xb5\xf3\xc6\xec\xa6\x4f\x29\x38\x6f\x72\xe8\x2a\xd5\x80\xe7\x08\x68\x5c\xc3\x9b\xf4\x53\xb6\x36\xec\x22\xbe\xcf\xae\x93\x97\xf4\x95\xb0\xfa\xce\xf6\x2c\x66\x54\x98\x9d\xac\xdf\xb5\x0b\xf5\xbe\x1e\x08\x7f\x74\x3e\xb9\x8f\x93\x1e\xd1\x9a\xf4\x12\x82\x44\xf6\xe3\x8e\x72\xdc\x02\x86\xd9\x44\xee\x84\xed\x97\x02\x9e\x94\x05\x7d\x5c\x9d\x68\xc9\x65\x39\xc9\xbe\x10\xd9\x61\xf3\xae\x8c\xaf\x91\xeb\xe4\x2b\x97\x42\xdb\xce\xd6\x57\xff\xa5\x7c\x9f\x51\x1e\xd1\x75\xc7\xd3\xce\xcb\x41\xf7\xa6\x3b\x0e\x63\xd8\x4e\xc0\x03\x27\x8c\xde\x99\x44\x5c\x59\xe3\x2f\x63\x51\xb0\x75\x8c\x66\xf6\xd8\x89\x7b\xf4\x4a\x6d\x99\x4f\xdd\x7c\x66\xb4\x11\x97\x5d\xb4\xb6\x69\x22\x7d\x2e\xaf\x7e\x54\x9b\x7a\xca\x2f\x77\xa4\x2f\x23\x46\xe4\x3e\x5d\xfb\x87\xb2\xbb\xe4\xc9\xa9\x83\xe7\xe6\xda\xea\xf8\xd0\x8b\x92\x2d\x6a\x35\x71\xdf\xf2\x16\xc3\x0e\x4f\x1e\xd5\x30\x04\x62\x29\x79\xec\xad\xb4\xb6\x50\xc0\x3a\xf0\xa9\x5c\x03\x7a\x9d\xe0\x47\x46\x17\x5b\xfe\xd8\x59\x3e\x63\xc9\x0d\xca\x23\x0c\x47\x0f\x9a\x1f\x93\xf7\x18\x0a\x80\x23\xaf\xf6\x2c\x86\xf1\x9d\x3b\xe9\x39\xd2\xda\x0e\x6b\x65\x8e\xb1\xb3\xd1\x58\x5f\xa3\x91\xcb\x24\xa0\x5d\xab\xa2\x8b\x75\x1f\x6b\x11\x42\x21\x57\x20\x71\x4c\xc3\x47\xe2\xf6\x55\xa3\xc1\xd3\x05\xf6\xac\xba\x8a\x11\x20\xe1\xb8\x89\x23\x0d\xd4\x3e\x96\xe1\xfe\xb7\x46\x10\x01\x59\x99\x6e\x84\xbe\x8d\x71\xed\x67\xd8\x48\x95\x12\x2b\x5c\xc7\x44\x61\xdb\xcb\xb6\xd4\x59\x52\x73\xb5\x2e\xde\x4f\x37\xb6\x1d\x31\x07\x26\xe6\x41\x03\xab\xaa\xea\x3d\x6b\x19\x1b\xad\x6b\x76\x46\x8f\x7e\x9d\x79\xc6\x52\xa5\x1b\x9d\x5b\x06\x45\x5d\x59\x1a\x08\xa9\x53\xf3\x97\xc6\xde\xb3\xbc\x2b\x60\x68\xa2\x9f\x79\xcf\x91\xe4\xb5\x33\xaa\xc6\x1a\x5b\x71\x71\xeb\x7b\x84\x64\xd5\xfa\xe4\xd9\x05\x14\x7a\xd2\xfe\xe8\x33\xa5\xe8\x6c\x4a\xeb\x35\x05\xc3\xfa\x0d\x3d\x3f\x55\x72\xfc\x2c\x2b\x83\x58\x9a\x47\x4c\x54\x90\x74\xd9\x28\x1b\x74\x17\xfd\x6a\x74\xf1\x76\x1b\x7d\x44\xb0\xa1\x58\x3f\x65\x6c\x75\xee\x19\x2e\x3b\x68\x5a\x2f\x8e\x1c\xdf\x1f\x59\x1a\xb8\xfd\xc1\xff\x38\xaa\x09\x07\x1c\x9a\xfb\x59\xb6\x51\xfd\x5d\x23\x74\x9c\x35\x0a\xda\x16\x32\x5a\x75\xbb\xbd\x2a\xc3\x14\x4e\xbd\xe2\xf1\xc2\x52\x2a\x3e\x5a\x5b\xbf\xbb\x16\xfb\x5c\x3e\xab\x75\xa4\x97\x75\xbe\xa6\x54\x2b\xe9\x4a\x5f\x57\x3a\xfb\x2d\x08\x4a\xb0\xbc\xd8\x8d\xfa\xef\xd8\x39\x38\x7b\xd9\x8f\xdc\x3a\xef\x3a\xcb\xb0\x6c\xb7\x1e\xce\x7e\xa7\xc1\x19\xf7\x0c\xf0\xd8\x1b\x83\x5c\x4a\x1a\x0c\xfb\x74\xdd\xcd\x0e\x67\x7a\x53\xa5\x70\x8c\xfc\xac\xb7\x3d\x90\xcb\xf6\xef\xf0\x6b\x6f\x41\x05\x64\x5e\x73\xb4\xc7\xa7\xbb\x0c\xbd\x18\x15\x13\xfe\xe3\xc1\xf4\xa2\xd2\xaf\x52\x51\xfb\x4a\x1d\x25\x15\xf5\x52\x4e\x94\x3b\xf2\x52\x55\xbf\x5f\x8b\x20\x2d\xc0\xbe\x1a\xe7\x79\xed\xc3\x25\x8d\x5c\x62\x8f\x86\x7c\x8c\x61\xa5\x26\x65\xb1\xc6\x12\x13\x1f\xee\xae\x43\xb1\x2f\x9a\x07\xca\x93\x39\x44\xc4\x15\x56\x42\x83\x80\xe7\x2e\x58\xab\x74\x3a\xdd\x7d\x30\x94\x3a\xb3\xf6\xc8\x23\x38\x6b\xeb\x6b\x10\xd5\x96\xde\x0f\x7f\x74\x80\xc2\x68\xe2\xba\x19\x8e\xa6\x47\x92\x6a\x38\x82\x3f\xd7\x33\xca\x59\x78\xa8\x9d\xaa\xdc\xca\x10\xf4\xb0\xb0\x04\x5e\x25\xc6\x5c\xcf\x46\x8d\x63\x36\xc7\x2f\x1f\x0b\x70\xde\xec\x58\xa6\x76\x2c\x16\xae\x3a\x88\xc6\x33\x93\xbe\xdc\x0c\x82\xaf\x9a\x04\x3f\x3a\xa0\x4d\x61\x65\xb6\x4e\x22\xc3\xda\x71\x38\x48\xad\x9b\x1a\xd2\xe3\xee\xee\x7b\x4e\x81\x13\x82\xcf\xea\x46\xb0\xc8\x0c\xbe\x5b\x72\xc9\xc0\xae\x7c\xe8\x4f\x5d\xf6\xb8\xd6\x14\xbb\x39\xad\xa7\x2f\x47\xae\x94\x1d\x07\x2e\x45\x12\xf5\x30\x7c\xdc\x6c\xfe\xc0\x47\xbd\xd7\x30\x8b\x29\x0e\x8c\x9d\x96\xe4\x21\x63\xf6\xee\x02\x2a\xc8\x40\x0f\x12\x35\x8a\xe5\xa6\x47\x9e\x82\x67\x7f\x74\xa9\x1f\x89\x5d\x33\x0c\xef\x53\x84\x2f\xe4\x6d\x80\x43\xac\x89\xad\x33\x43\x4f\xf3\x0f\xcd\xd1\x15\x1c\x66\x7f\xb6\xae\xd3\xac\x6f\x4f\x35\x3d\xf7\xdf\x43\x5e\x99\xf9\x5f\xd9\x0f\x8d\x62\xa0\xe6\xe0\x0e\x2d\xd9\x61\x3c\x26\xb5\xb2\x2d\x3d\xd6\x38\x22\x92\x5a\x49\x3e\xbb\x39\xb4\x5a\x3d\x6a\xf4\xdd\xad\x80\x3e\xcb\xd7\x12\x5f\x2b\xbc\x33\xca\x6e\x20\x0c\xd9\xfa\x8d\x73\x19\x5a\xdb\xd5\x88\x60\x49\xaf\x71\xb8\xf4\x96\x0b\x74\xec\x3e\x55\x17\x6d\xca\x96\x04\xce\x34\xdb\x60\x30\x0c\xd3\x93\x16\xe4\x37\xb2\xeb\xbf\x40\x64\xc9\x6e\x70\xa9\xdc\xd8\xc9\x99\xcb\x2c\x91\x1d\x1c\x3a\x9f\x53\x6c\xa4\x69\x74\x87\xad\x81\xd9\xb3\x4a\xd2\x92\xed\xdb\x3d\x96\xaa\x99\x61\x10\x1c\x2c\x4c\x3a\x8b\xc6\x73\x56\x50\x20\xf3\xb0\x63\x72\x28\x07\xdb\x57\x64\xda\x2e\x03\x19\x8e\xe1\x46\x28\xc9\x36\x5d\xe0\xf5\xd4\xa5\xd4\xd5\x76\x84\x9b\xc6\xf0\x89\x8f\xa4\xb5\x5d\x07\x7d\x6c\x33\x67\x82\x73\xd5\x9a\x6d\x06\x43\x6d\x52\xe6\xd0\x4d\xec\xdb\xf2\x5e\xcb\xc9\x66\xf1\xb8\xe2\x0b\xa9\xee\xe6\x31\x3e\xcf\x52\x09\xb5\x07\x1b\x08\xbd\x0f\xca\x4f\x9d\x44\xb9\xa5\xc3\x28\xf9\xa4\x33\x1c\x69\xc4\xa8\xdd\x3e\x7a\x5c\x99\x9e\xfd\xf4\x32\x39\xb5\xca\xf0\xfe\xf1\xe6\x01\x16\xed\xca\xe4\xc2\xa8\x0d\x12\x6d\x79\x3f\xb3\x5c\xeb\xdf\x4e\x5e\xcb\xfa\xcd\x85\x5a\xe9\xbd\xa1\x97\xb4\xc4\x40\xeb\xdc\x84\x1e\xec\x32\xf7\x1f\x27\xbb\xcd\xfd\xf4\x65\x49\x47\xe7\xfa\x3e\x60\x74\xd0\xd5\xd5\x00\xef\xd3\xaa\xee\xf6\x6f\x9c\x32\x53\x3a\xa2\x0d\xae\xa0\x07\x88\xee\xd6\x6c\x5e\x2d\xa5\xbf\xdc\xee\x4d\xa9\xf9\xa0\x87\x8b\xef\x0c\xa6\x2e\x9e\xc3\x63\xbd\x7c\xf6\x83\x6f\xd4\x27\x7b\x26\x88\x82\xb8\x76\xfc\x04\x3e\xf0\x73\x76\xf8\x21\x7e\xb2\x4e\x9c\x9f\xbe\x6c\x11\xed\xe8\x8b\xd6\xb6\x33\x39\xca\xec\xc3\xfe\xae\xa4\xe5\x37\xf7\xac\x97\xe8\x46\xef\xe7\x57\x32\x9c\xa8\x66\xe3\xd7\xb4\x34\x2e\x5c\x7d\x3c\x0e\x5d\x2a\x05\x82\xb3\x3e\x14\xda\xdc\x7a\xf6\x1d\x04\xeb\x6a\xb2\x8f\x8e\xb3\xdb\x5a\x38\x9a\x42\x4d\x39\xc2\x3f\xa9\xdf\xcd\x02\x86\xbc\x35\x34\x5b\x0c\x12\xdf\xaf\x94\x33\x1c\xcb\x70\x1b\x1e\x24\xc4\x80\xd1\xc9\xae\xad\x8f\xb1\x7c\x9b\x0b\xf7\xd3\x8f\xcf\xba\x38\x42\xb8\x0c\xcd\xd3\xe5\x0f\xcc\xb6\xb5\x5a\xd4\xe0\x24\x44\xff\xad\x1c\xa1\x17\xa0\x37\xfb\x70\xa8\x08\x8c\x4c\x6a\xeb\x7a\xae\xf9\xfb\x60\x10\x84\xcc\x5a\x63\xcd\x98\x8f\x71\x2b\xfb\x91\x72\x79\x4f\x7e\xd8\xa0\x18\x36\xfd\x73\x65\xf6\x16\xa3\x12\x96\x76\xee\x42\xc3\xc9\x8e\x33\x86\x4f\x83\xa0\x0a\x96\x43\xd6\x09\xf8\x3c\x65\x66\x4b\x73\x6d\x4c\x9b\x82\xfb\x79\x78\xae\x40\x47\x3a\x9a\xd5\x69\x91\x5e\x98\xcd\x68\x34\xaf\xf8\x60\x80\x41\xce\x44\xcf\xea\x48\x0c\x48\xf1\xe0\xbf\x3a\x31\xb9\xff\xa3\x61\x2b\xba\xfe\x30\x65\x39\x1d\x0d\x63\xde\xb8\xfb\xc1\x65\x35\xba\xb5\x3e\xf4\xf6\x4c\x02\x6d\xe4\xa0\x63\xd2\x90\x6c\x62\x31\x04\x97\x63\x08\x06\xf2\x7d\xe3\x5c\x11\x81\xe9\x6e\xda\xc3\x02\x0f\xaa\xc3\x67\x68\xc5\xab\xf8\xe9\x9e\x7f\x0d\xec\xdc\xc9\xa4\xab\xc2\xf3\xec\x70\x51\x90\x7d\x0f\xc9\x81\x80\xc3\x1b\xfa\xbf\xe7\x89\x56\x8e\x37\x3a\xe5\xe5\xad\x76\x35\xee\x91\xf8\x7c\x9f\x42\xfe\x7a\x07\x61\xd1\x3d\xe8\x89\xe4\x5e\x8d\xb4\x4f\xbf\x43\xcb\xef\x86\xf4\xd6\xdf\x0d\xfb\xdf\xd5\xf7\xe5\xb0\x0a\xcb\x3f\x3a\x6a\xb5\x9d\xb9\x63\x91\x18\x4e\x09\xcb\xa7\xc9\x5e\x22\xf7\xcb\x46\xbc\x0c\xc3\x3d\xef\xd7\xfe\xcc\xea\x1d\xff\xd6\x8e\x33\x01\x68\x11\x8a\xed\x1a\xe7\x8e\x74\x74\xaa\x5b\x53\xe7\xb0\x2d\xa4\xef\xd6\x20\x85\x07\x36\x27\xbc\xe2\xfb\x52\xce\xc6\x96\xbf\x17\x06\xab\x66\x35\xe2\x06\x82\x6a\xbc\xc9\xb8\xa2\xcc\x77\xa7\xee\xea\x67\x19\xf2\xad\xd2\x35\x4a\xaa\x8e\x01\x30\x2d\xbe\x94\x43\xfc\xf4\x5a\xda\x6d\x44\x86\xbb\xde\x90\xd5\x94\x7d\x6d\xbc\x77\x7e\xd1\xb2\xf1\x0a\xc6\xb1\xd4\xde\xe7\x1c\xea\x00\x24\xc8\xcd\x31\xcc\xd5\x76\x13\xe6\x7e\x7d\xcd\xfb\x83\x87\x56\x97\x5d\x52\x60\x60\xd1\x7a\x7b\x98\x3c\x8d\x4e\x34\x5a\x6a\x35\xc0\x60\xfd\xea\x51\xaf\xe7\x51\xe9\xc7\x92\x14\xf9\x29\x5d\x72\xbc\x5f\xf9\xfd\xd6\x29\x38\xc5\x65\x81\xed\xa2\x29\x8d\x30\x06\x0d\x19\x8a\x6f\x6f\xbf\xa3\x82\x79\x04\x47\xb6\xaf\x70\xbf\xd1\x1d\xe6\x7b\x64\xd9\x81\x5e\x3c\x57\x4b\x29\x51\x8c\xd5\x69\x7e\x2f\xb5\xe5\xec\x10\x3f\x5c\x11\x2f\x36\x17\xca\x3b\xf3\x59\xd7\x4a\x19\xd9\x02\x97\xea\x4c\xce\xdd\x2c\xaa\x77\x9c\xfc\x2f\x87\xa5\x46\x73\xe3\x78\x8b\x56\x73\xbf\x8a\xae\x5c\x7f\x10\x84\xfd\xf5\xba\x7d\x9b\x57\xfc\xea\x2b\x1b\x79\x9d\x42\x45\x6e\x49\x2b\x79\xc9\x60\xd7\x74\xb5\x25\xbd\xd5\xed\x5a\x39\x78\xce\x29\xc2\x00\x68\x43\x1d\x1e\x73\x6d\xce\x47\x64\x29\xe4\x35\x5a\xd5\xca\xda\x89\xe6\xf3\x95\xdd\x2c\x6e\xf3\xfa\xc5\x6c\x3e\xe7\x10\xbc\x73\xe5\xf9\x4f\xda\xfd\xe6\xee\xf6\xfe\xe5\x43\xc8\x83\x78\xe1\x72\x8e\x46\x6f\x7c\x60\x0c\xac\x85\xe5\xe8\x66\x83\x2c\xe2\x96\xbb\x0e\x3d\x82\x29\xe3\x1e\x63\x8b\xa8\x2f\x76\x80\x7d\x00\x70\x98\xa6\x5b\xf4\xc2\xe3\x31\x7d\xa5\xfe\x58\x68\xaf\x3f\x4c\xd3\xe8\xd4\x7c\x58\x5d\xee\x75\x74\x23\x73\x9a\x53\x44\xb9\xcd\x62\x1c\xb4\x20\x2c\x04\x69\x19\xe3\x11\x27\xd2\xae\x23\x65\x85\xb2\x55\xee\xdf\x07\x6c\x48\x7f\xaa\x11\x89\xa6\xda\x69\xa1\xb0\x50\x0e\x44\xa9\xdf\x6a\xf3\x3b\x18\xd4\x6e\x6f\x97\xeb\x5d\x1f\x27\x1d\xfb\xd3\xe1\x22\xad\xae\x78\xda\x25\xae\xd8\x3c\xf9\x01\x69\xf2\xb9\x97\x82\x81\xd6\x3a\x1d\x15\x3a\xff\xc8\xe3\xdf\xe8\xdd\xe5\x9d\x34\x0e\xaf\x70\xc4\x6e\x54\xab\x7d\xb3\xf1\xe2\x0a\x8b\x3e\xcb\xfc\x57\x5a\x74\x87\x2b\x40\x52\x83\xa9\x81\xa0\x92\x8e\x87\x27\xac\xd3\xd5\xfc\x3e\x1d\x85\x5d\x0a\xcf\x10\xc8\x9f\x6e\xaa\x93\x08\xaa\x07\xd9\x51\x91\x49\x74\xb7\x2f\x17\x00\xde\x0b\x02\x77\xaf\x41\xfb\x84\x29\xb3\x38\xdc\x8a\x5a\x84\x89\xe3\xc7\x03\x75\xc1\xc1\xc6\x05\xdb\xff\x14\x12\x0d\x62\x77\xea\xc4\x04\x4f\xd1\xf4\x6c\xa4\xa2\xbc\xd1\x12\x60\xd0\x64\xda\xe4\xa9\xbc\xd7\xd7\x48\xc1\xfe\x54\x36\x2d\x8a\x8a\x80\x4d\xc0\x5c\xf9\x09\x71\xe4\x61\xb7\x47\xea\x34\x3d\x22\xd5\xf7\x68\x62\x93\xc9\xf6\x3d\xb3\xc3\x6f\xff\x67\xbb\x48\xbf\x0a\x8a\x3c\x6d\x4a\x1b\xb8\x4b\x54\x77\x03\x24\x45\x0f\x5e\xa6\xcb\x06\x75\x3c\x44\xd3\x83\xbb\x00\xef\x4a\xe1\xb7\xd5\xf8\xb7\xb4\x89\x40\xbd\xd3\x91\x90\x69\x79\x46\x2f\x19\xcb\x98\x9b\xfb\x8d\x6f\xd4\xc8\x4b\x60\x14\x89\x40\x5e\x46\x4a\xbf\x51\xe8\x22\xd2\x98\x35\x33\x27\x9a\xf4\xe6\x39\xf2\x17\x69\x30\x60\xba\x34\xb8\x79\xe6\x59\x6f\x65\xb9\x11\xc6\x08\xab\x81\xa1\xef\x84\xb8\xa0\x10\x3d\xb2\x3e\x02\xe3\xbd\xf8\x8f\x2d\x9f\xf2\xee\xc8\xe3\x2e\x95\xc4\x27\x7a\xe7\x4b\x3f\x3b\x08\x52\x1e\x01\x4b\x1a\x44\x05\x57\xcf\x26\x4d\x83\xc5\xd9\xe2\x7c\xd7\x91\xf3\x25\x47\x43\x02\xe3\x5c\x4b\x40\x03\xb4\xe9\xc1\x05\xc8\x66\x94\x6a\xf9\x77\x61\x24\x0b\xfa\xb7\x7c\x0a\x20\xc7\x94\x0f\x6c\x4a\xb0\xfb\xd3\x80\xfb\xb3\x3f\x55\xbb\x9f\x3c\x20\xd9\xf8\xc6\x56\x3d\xef\x71\xa0\x86\x3a\xe3\xdb\x18\x28\x0b\x86\x61\x34\x90\x25\xac\x87\x3b\x89\xe7\x99\x52\x6b\x07\x45\x7c\x34\xd3\x02\x1a\x4d\x3e\xea\x91\xf3\x1a\xbd\xfb\xb1\xfa\x5a\xca\x68\x0f\xdd\xfc\x2b\x56\x92\xd4\x72\xb3\xc8\xd3\x9f\x98\xe6\x69\x57\x62\xc7\xa8\xc6\xf6\x4b\x8c\x97\xd7\xb8\x29\x15\xf4\xa5\x3e\xd8\xcb\x65\xd5\x8b\xe9\x3f\x11\x3b\x69\x8f\x13\x0a\xd4\x1a\x19\x28\xf0\x3b\xe2\x2b\xa0\x29\x11\x9e\x97\xe5\xaa\xd2\xe9\xf9\x4a\xe4\x33\x68\xd8\x56\x9f\xe2\xb3\xac\x87\x6c\xb0\xaf\x91\x1c\x75\xa2\x25\x23\x5b\x4b\x27\x88\xb8\xbb\x0e\xd2\x5a\xe7\x4d\xe1\xb9\xa0\xcd\x55\x2e\x83\x38\xec\xd0\x56\x79\x7e\xd1\xc8\x01\x0f\xdf\xc4\x10\x97\x91\x73\xd9\x70\x96\x53\x6b\x11\x47\x93\x2e\xe6\x6c\x8e\x33\x1c\x37\x48\xdf\xb0\xee\x4b\x37\x37\xd7\x3f\x13\xde\x73\x3d\x5c\x23\x29\xe5\xc8\x1f\x77\xd8\xdf\x4b\xcd\xf1\x40\xbf\x84\xb7\xee\xa5\xcb\x71\xc0\xf6\x9a\x8f\x8f\x7d\xd6\x11\x4e\x49\xcb\x84\x4c\x43\xe7\xe3\xa1\xa8\xca\x87\xaa\xaa\x5b\xf5\xbe\xdc\x39\x2c\x05\xfe\xe6\x56\x7c\x7a\x9b\xff\x5d\x79\xe3\x65\x45\xe3\x9f\x80\x8c\x23\x71\xf5\xe6\x36\x3c\x2e\xbd\xa8\x70\x8e\x74\xfe\x63\x13\xf6\x28\x53\xf8\xad\x76\xe5\xdd\x77\x37\x33\xf1\x80\x45\xfa\x16\x1d\xfa\xfb\x5d\xe2\x85\x43\xab\xd7\x11\xb6\x59\x7b\x59\x1d\xd0\xba\xe6\x90\xae\xcd\x5c\x62\x14\x08\xa2\x41\x99\x73\x0e\x77\x10\xf6\x77\xa2\xe1\x71\xb9\x95\xfb\x01\x6c\x14\xa2\x1f\x54\xb6\x64\xf7\x2f\xe3\x84\x77\x0e\xa3\x04\x78\xf2\xeb\xee\x59\x91\x9d\x80\x00\x4c\x65\x03\x53\xfd\x9c\x22\x34\x44\xd9\xab\x7a\x6c\xb3\xe6\x5e\x15\xe0\x7e\xd0\x46\x8c\x23\x89\xca\x77\x70\x28\xcb\x1a\x21\x98\xb7\x6c\x5f\xde\x6e\xf6\xf7\xeb\xea\x74\x90\x1e\x0d\xb1\xf0\xe8\x3c\x22\xd4\x11\x7c\xe3\xca\x3e\xa0\xc3\x85\x5a\xc1\xe8\x01\x71\xb0\x8e\xad\xb2\x20\x30\xe2\x4d\xa4\x01\xee\x19\xd5\xa0\x1a\xdd\x65\xa8\xe7\x41\xbf\xab\xcf\x96\x43\x8e\xbf\x2f\x24\x0a\x95\xc5\xd4\x35\xe6\xbe\x5c\x19\x6f\xbb\x1a\x42\x3e\x80\x2b\x38\x6f\xe3\xab\x9a\x52\xd8\x84\x5f\xb2\x1e\x74\xf9\x6b\xb0\xc7\xc8\x6d\x8e\xde\xfd\x48\xd9\xb1\x47\xa6\x11\xed\xe6\x5d\x95\x8f\x6b\x87\xcf\x0e\xfa\xd5\x37\x87\xa1\x51\xd8\x1f\xe7\x12\xa6\x0e\x5b\x45\x58\xca\xa3\x9a\xf1\x4f\x23\x13\x19\xca\x28\xc7\x6c\x56\xde\x18\x7e\xb6\x80\x06\x70\x42\x20\x0e\xa2\x66\x83\x46\xa3\x7b\x67\x7b\xb5\xef\xd5\xfd\x60\x07\x3b\xc2\x48\x7a\x65\xa3\xef\x7d\xe5\x77\xec\x2d\x5b\xc0\x88\x9e\xd2\xd1\xdc\x28\xeb\x9e\x5d\xd9\x26\x90\x82\xde\x6e\xa4\xb0\x71\xea\x36\x73\xe6\xcb\x8e\xa4\xec\xfd\xfd\x90\xa4\xcc\xd3\xd6\xa7\x65\x3a\xdb\x80\x0e\xbe\x4c\x03\xe9\x05\x6a\x3a\x7d\xd7\x45\xff\xbc\xec\x07\xbd\x90\x60\xb8\xb9\x18\xdf\x90\x01\xe8\x07\x88\x83\xe7\xa0\xd1\xd3\x41\x01\xdb\xfe\x12\x51\xde\xdc\xf7\xd9\xcb\xf5\x86\x22\xc4\xd8\xc1\xa3\xe7\x4c\x8d\x24\x8f\xb0\xa1\xd8\xc3\x85\x0b\xdd\xfd\xe5\xb8\xc6\x5c\x18\xc5\x61\x47\x2b\x39\x87\x81\xc5\xa3\x9e\x12\x18\xb3\x7f\x52\xc1\x83\x01\x42\xee\xda\x8e\x1f\xc6\x6a\x03\x18\xa6\x9f\x7a\x58\x6f\x72\xdf\x76\x31\xe2\x5b\x9c\xb8\x6d\xfd\xe7\x9b\x51\xfa\x33\x52\xdc\xb3\x99\xec\x6b\x50\xdb\xa7\xf5\x11\x4d\x7c\x86\x8f\x6a\x1c\x1a\xa1\xcd\x57\x61\xb9\x84\x42\x30\xb7\x7e\x26\xfa\x9a\xad\x60\x2e\xab\xbf\x0f\x9a\xe4\x4b\x4d\xff\xe0\x35\xab\x97\x4f\x5f\x35\xb6\xf6\xcb\xd7\x6f\xd7\x89\x1c\xa1\x6b\x1e\xda\xff\xc1\xbd\xfe\xca\x75\x47\x07\xe9\xcb\x6a\x74\xa8\x16\x9c\x20\xb5\xeb\xc6\x91\x16\x80\xf8\xdc\x4c\x06\x95\x3d\xee\x54\x7a\x69\xb0\xd3\x3f\xa3\x20\x01\x14\xfa\x3c\x67\x4c\x48\xdf\x2b\x39\x6a\xcd\x33\x26\x65\x97\xfb\x6b\x9e\x06\xd9\x04\xac\x13\xa6\xb4\x78\xa5\xa9\x02\x57\x18\xd6\x3b\x11\xfe\xe0\x8e\x3d\x7a\x85\xfa\xa8\xe5\x2a\xff\xe7\x01\x39\x48\xeb\x23\x1f\x4a\xda\xae\xb9\xa9\xe3\x14\xc1\x08\x38\x44\x8c\x2d\x3f\xaf\x04\x25\x91\xd4\x22\xb8\x61\xd7\x78\x25\x76\xe0\xaf\xa9\xdf\x6c\x74\x3a\xe2\x35\x93\x9f\x8b\x10\x0b\xbd\x1e\x0d\x50\xb3\x86\x91\xbc\xda\xdb\x63\xa3\xb7\x1f\x47\x37\x0e\xea\x39\xac\x65\x95\xb5\x6d\x47\xd9\x4d\x23\x7f\x92\x4c\xfa\xb2\x07\x5c\x8c\x6e\x01\x63\x90\xb9\xc0\x9a\x7e\x94\x99\xb3\x26\x77\xbf\xe1\x66\x7c\xd7\xd2\x59\x96\x5a\x4c\x35\xd5\x7e\xc3\xe0\xc1\x79\xc0\x8f\xd8\xee\x1a\x2b\x7c\x71\xf0\xe6\xf3\x53\x2f\x44\x2b\x09\x2c\xec\x36\xc9\x38\x8f\x3d\xf3\x36\x45\x52\xcb\x69\xf3\x0c\x73\xdf\x49\x7d\xe4\x66\x4e\x43\x61\x08\xf4\x5c\x00\x4e\xa6\x0b\x67\x81\xbb\x27\x6f\xa1\x88\xd6\x2b\x97\x75\xfb\xa3\x5b\xc1\x16\xa3\x94\x75\xf0\xd9\x20\x29\x92\xe3\x17\xda\xa4\xb2\x6e\x05\x01\x7b\x33\x26\x11\x19\xb3\x08\x7c\x7d\x1b\xb5\x18\x4a\x29\xd0\xeb\x91\xed\xe6\x4a\x6f\xe9\x1b\x79\x5d\x07\x46\xa1\xf7\x5c\x49\xf8\xa3\xd0\x89\x52\x45\x2b\x4d\x67\xfe\x4c\xf6\x7e\x75\xa7\x9d\xd7\x94\x3a\x52\xf0\xdc\x7d\x5d\x30\x87\xb3\x64\x38\xa2\xc1\xdf\xf8\x67\x54\x22\x62\xfc\x71\x30\xaf\x72\x7a\xdd\x15\x12\x12\x98\x03\x55\xc7\xeb\xc5\xa6\x5f\xc6\xe8\x08\xcc\xe3\xf3\xa9\xac\x99\xf2\x21\x71\x02\xe9\x1f\x83\x65\x6a\xd9\x7e\xcc\xfa\x4b\xc3\xcc\xaf\x99\x4a\x74\x0c\x40\x35\xe2\x5f\xb0\x08\xce\x35\xce\x26\xed\x42\x4d\xd2\xc6\x52\xee\x76\x39\xc4\xda\xee\x35\x3d\x93\x30\x81\x2e\x0d\x09\x93\x3d\x0e\xfe\x11\xd4\x98\xce\x3f\x19\xd5\x83\xf9\x6c\x9e\x3c\xbc\x23\x36\xfb\x2f\x94\xca\xfc\xc5\xdf\x05\xe9\xb6\x68\x42\xee\x1c\xc7\xb5\xf8\x9f\x4c\x0b\x39\x68\xf0\xca\x29\x8f\xa3\xd7\xec\xd4\xc3\x7d\xc5\x10\xc0\x5d\x7f\x49\x91\x65\x3a\xa5\x4f\xcc\xf4\xe0\xc2\x77\x86\x03\x66\xb5\x64\x9e\xa7\xc0\xa2\xe7\x52\x4d\xb6\x9e\x4a\x01\x7b\x8e\x8d\xb6\x2e\x65\x5b\xbc\xf2\xa6\x5c\xf1\xa6\xb2\x97\xf5\x5d\x96\x80\x3f\xd9\x1e\xb2\xe5\x2b\xe1\xcd\x24\x33\xb0\x9f\x6c\xa4\x00\xf1\x8b\x2f\x8f\xca\xf7\x96\xca\x42\xc7\xab\x1c\x4e\xb2\xd8\x38\x47\x83\x1e\x7e\xb1\xfd\xf2\xdd\xe4\xd7\x6c\x00\xd0\xe6\x75\x41\x02\xf4\xec\x88\xa4\x5c\x39\xe5\xe3\x5c\x60\x6a\x50\x12\x8b\x1d\x0e\x61\x63\x7b\xc5\xeb\xca\x16\xe0\xeb\xb8\xbd\xa2\x66\x08\x0f\xf3\xf7\x03\x87\xbd\x1f\xc2\x77\x2e\x7a\xff\x93\x1b\xff\x9a\x73\x38\x2e\xbb\xb8\x20\x0b\xc2\xd5\xa4\x12\xe9\xa7\x69\x89\x9d\x20\x48\x3f\xce\xe2\x5d\x5c\x3b\xc2\x48\x36\xe2\x79\x83\xf2\x23\x37\xd9\xf1\xe5\x6e\xff\x39\xdf\xe5\xe8\x40\xb4\x38\x5d\x28\x81\xff\x9e\xe3\x81\x79\x9d\x64\x46\x5b\xbe\xec\x21\x19\x57\x98\xed\x02\x22\xe9\x3c\x5c\x67\xb5\xcf\x2f\x7b\xa0\x72\x66\x7e\x84\x4b\x8c\x6c\xca\x43\xfa\x29\xe1\x53\x59\xed\x3f\xba\xdd\x43\x79\x02\xb6\x84\x91\x02\x46\xf4\xda\x83\x05\x07\xa6\xf3\x3d\xd2\xe8\x9a\x0a\xe6\xb3\xc1\x5f\x7f\xa3\x01\xc0\x0e\x3e\xf6\x47\x06\x05\xce\x91\x73\x0e\xef\x2e\x6b\xe5\x10\x46\x20\x83\xee\x01\xdd\x42\xa1\xbf\xa7\x2c\x65\xb7\xc8\xb2\x18\x2a\xb1\x49\x5e\x1d\xbc\x6f\x8a\x7d\xed\x50\xe9\x40\x43\xcf\x6b\x78\xb0\x71\xd0\x40\x32\x9d\x8c\x3f\xc8\xab\x20\x80\x90\x2a\xee\x07\x8c\x00\x9c\x03\x0e\x49\xe1\x18\x90\xda\x8b\x26\x46\xa5\xb4\x5f\xf2\xaf\xfb\x56\xce\x71\x3b\x72\xc0\x40\xa9\x73\x46\xc1\x7d\x63\x68\x60\xc4\xdb\x6c\xbd\xe5\x9d\x77\x5a\xf3\x2b\x5e\x38\x93\xe1\xa7\x66\x0a\x60\x03\xc7\xe6\x94\xcd\x29\x92\xbc\x3d\x34\xdb\x3d\x87\xbf\xac\x7a\xbe\x77\x18\xdf\x2c\x74\xb8\xbf\x8f\xbf\x7a\xcc\xb8\xa9\x56\xff\xe2\xb1\xf3\xc8\x27\xaf\xf8\xeb\xc2\x10\xfa\xbf\xbf\x51\xdd\x7f\xc0\x0b\xee\xd9\xdf\xd1\x30\xd5\xd5\x75\x4f\x1b\xd3\x8d\x7d\x50\x3e\x46\x04\xf6\xcc\x14\xe0\xab\x9a\xba\x9b\x24\x74\x47\x2f\x22\xdd\x35\x04\xb5\xd4\xa9\x43\x4a\x3b\xbe\x1c\x47\x50\xb1\x96\x59\x4f\xfc\x36\x1e\xb6\x95\x04\x5f\xc9\xbc\x0c\x41\xae\xfe\x9d\x8e\x44\xfe\x72\x2d\x99\xd2\x72\xfd\x91\x06\xcf\xce\x44\xce\x93\x60\x40\xfd\x09\x5e\xa8\x93\x3b\x77\xd8\xba\x0b\x18\x38\x97\x93\xb5\x13\x36\x5f\xfc\xcb\xae\xfe\x1e\x86\xf4\x06\xe6\x9d\x4b\x64\xbe\xf5\x94\x52\x1a\xdb\x80\x38\x6e\xaf\x24\x71\x5a\x9e\xf8\x2f\xf3\x7a\x7c\xea\xb0\xdf\xcc\xc8\x40\x89\x40\x45\x58\x19\x94\x39\x2c\x36\x5b\x65\x8f\x8a\xe2\x54\x7f\x11\x5a\xd6\x37\x54\x29\x75\xa5\x26\x25\x98\x50\x3e\x87\xb1\x02\x43\x11\x78\x39\xc6\x2d\xab\x29\x8f\x4d\xaa\xa9\xf2\x83\xc1\x86\xc9\x86\x27\x53\x54\xf8\x9d\xd5\x64\x9d\xc6\xf4\x65\x09\xcc\x81\x71\xca\xfe\x03\x1a\xf1\xb5\xbb\xd1\x01\x8d\x2f\x27\xb0\xe8\xef\x62\xc5\xd7\x67\xf1\x48\xcf\x1a\xd0\x47\xb1\x31\x4a\x67\xdc\xe1\x55\x63\x84\x5e\x63\xe5\xb2\xd7\x44\x66\x43\x10\x61\x9c\x90\xa6\x7a\x18\xd8\x03\x1c\xf5\xf5\xa4\x32\x4f\x67\xfd\x7d\x22\x89\x68\x0a\xa8\x42\x37\xe9\x13\x4f\x81\xe7\xaa\xff\x75\xf1\xa4\x3a\x2d\x57\xa5\x0e\x8b\xf0\x8d\xee\x5f\x9a\x3c\x73\xd8\xb5\xb3\xf3\x90\x1b\x0b\x63\x12\x1f\x5e\x20\x80\x2e\x7c\xc6\xc0\x45\x25\x02\x96\x65\xa8\xa2\x61\x76\x82\x34\x18\xf2\x61\x35\xb2\x79\x3b\x44\x97\x7d\x03\x18\x2f\x77\xec\xff\x3e\x15\x8f\x38\xec\x03\x0e\x03\x95\x73\xcb\x6a\xfb\xe7\xa7\x41\x0d\xe2\x0a\x15\x1a\x28\xdf\x58\x95\x86\xc2\x37\x65\x1a\x2f\x60\x63\xb9\x8f\x9d\x19\xbd\xa0\xc6\x43\x30\xe5\x87\xb5\x7d\xf5\xde\x09\x13\xde\x40\x07\x42\x77\xbc\xff\xf7\xd0\x47\xf4\x5c\x89\xd7\xc7\xe7\xfe\xbd\x60\x09\xf8\x4a\xdc\xbe\x01\x07\xff\x6b\xf0\xb4\xe6\xa0\xc2\x2f\xd7\x4b\x24\x75\x1f\xdb\x29\xbf\x6d\x8e\x8b\xee\xf1\x7b\xf4\xbd\xbd\x99\x3c\x02\x13\x04\xb3\xe0\xcb\xa9\xae\x5b\xed\x43\xf1\xa5\xb8\xd5\xae\xb4\x7d\xb0\xd7\x5a\xcb\x07\x30\xf0\x7b\x15\x14\x02\x12\xb2\x54\x57\x8e\x99\x76\x48\x76\xd9\x4d\xad\x99\xbd\x44\x84\x7a\xf5\x66\xe3\x8f\x8f\x33\x95\xff\x73\xdc\xf7\x12\x21\x02\x89\xa8\xcc\x7d\xd7\x71\x6d\xb9\x12\x1a\xf5\x4c\x5b\x3b\x23\xb4\x11\xf8\x84\xe2\xf5\x82\x12\xfc\x9d\x94\x97\xf8\xd8\x1f\x18\xb5\x8a\x5f\x45\xad\x2c\x84\x54\x1f\xa3\x1e\x56\xd6\xc0\x26\x45\x62\x75\x67\xc4\x43\x69\x56\x4e\xfd\x53\x66\x75\xd9\xb2\xca\xa7\xa0\x39\x23\x00\xca\x5f\x17\x00\x04\xe8\x32\x38\x34\xf5\xa8\x39\x6b\xfa\xd2\x86\xde\xb8\x1a\x43\x65\xdc\xed\xf4\xde\x6a\xf8\x0d\xbe\x8d\x0f\x8c\x7a\x20\xda\x28\xc8\x66\x08\xd4\x80\xbf\x87\x9e\x97\x60\x88\xb6\x3f\x62\x3c\x26\x46\x66\x67\xd0\x72\xd4\xb4\x2f\x3f\x38\xa8\xc5\x37\x11\xfd\x59\x48\x34\x75\xf5\x25\x36\x10\x0e\x2f\xe3\x9a\x85\xdb\x94\x11\xae\xf8\x5d\x56\xc6\xf6\x03\x1e\xe7\x26\x6b\x00\x0b\x78\x7b\x11\xf7\xdc\x6e\x37\xd1\x55\x10\xa2\xa0\x2f\x0d\x90\x02\x3b\x3f\x0d\x71\x05\x6c\x85\x05\x3a\xf4\xec\x1a\x35\x7d\xb7\x26\x3b\x0d\x03\x5f\x30\x5f\x01\x4e\xc8\x10\xcf\x18\x2b\xc0\x6c\x28\x80\xa4\xca\x5e\x1b\x88\x97\x78\xbb\xfd\x89\x06\x55\x46\x8b\xcd\x3c\x1b\x2c\x88\x1e\x34\xc9\x6c\x0a\xe4\x59\x8d\x7a\x91\xea\xf1\xc2\x40\x2b\xff\x23\xed\xf3\x94\xa7\xf0\x8b\xbf\x7c\x52\x32\x51\x3a\x03\xf1\xac\x92\x01\x8d\xc7\xe3\xec\xec\x66\xa3\x6e\xbf\x63\x17\x89\x63\x66\x45\x82\xca\xcb\x26\xa8\xfa\x11\x97\x6f\x3b\x9b\x1d\x3c\x3d\xe1\x1a\xe5\x0d\xb1\xa6\x40\xe3\x67\x0f\x80\x62\x04\x36\xcc\x47\xfe\x8f\xe7\x7f\x02\x1d\xd9\xc5\x05\xbd\x6e\xac\x65\x94\x80\x20\xba\xb2\xc4\x31\x34\x18\x7a\xcb\xdd\x52\x29\x19\x79\x53\xae\xbc\x57\x3c\xac\x0d\xbc\x65\x21\x38\xc7\x21\x54\x3a\xfc\xe7\xa7\xf5\x91\x9a\x2f\x25\x7a\x9a\xb2\xee\x9f\xec\xa4\x8c\x0d\xcd\xc8\x9d\x5e\x1a\x1d\x61\x50\xb6\x17\x51\xa3\xa5\x07\xa9\x6c\x69\x18\x9c\xdc\xaf\x17\x19\x90\x3c\x60\x27\x1d\x98\xc3\xcd\x42\x0b\xc3\x2f\xc7\xae\x41\xe5\x84\x79\xd8\xb0\xbe\xaa\x1d\x0c\x94\x60\xe9\x93\x1a\xa3\x13\x20\x8d\xba\xcc\x88\x89\x66\x46\xbd\x13\x76\x70\xfd\x48\x2c\x3b\xb3\x48\x59\x0e\x2a\xff\x73\x27\xee\x2f\xbb\x45\x86\x04\xd8\x9b\xac\x74\x78\xfb\xcf\x1e\xad\xef\x4f\xd5\x33\x53\xf2\xa0\x3b\xc7\xe3\x1d\x83\x47\x99\x6e\xdf\x75\x18\x9a\xcc\x38\xd2\x05\x00\x60\xc5\x5e\x85\x6f\x06\x4e\x09\x8e\x7a\x8f\x36\x76\x9e\xa6\x60\x99\xc2\xdc\xf9\x2e\xa1\x43\xd9\xe2\x87\xe9\x24\xc6\x6b\xb4\x3c\xdf\x35\xf4\x48\x56\xa8\x1c\x5c\x59\x8d\x65\x3c\xc1\xb0\x58\x80\x10\x5a\xbf\x2e\x30\xdf\xd8\x45\xeb\xde\xb4\xa8\x73\xfb\x4e\x23\x36\x0e\x65\x23\x96\xac\x6b\x78\x09\x91\x79\x09\x9f\x41\x14\x3d\xdf\x40\xa8\x22\x42\x3a\xf1\x14\xa9\x2f\xdc\xa2\x2d\x83\xd8\xbe\xd5\xab\x8a\x54\xc7\xa7\x07\xe7\x5a\xbf\x38\x90\x17\x4e\x2b\xe7\xea\x89\xe8\x5c\xde\x5c\x98\x17\x8f\x39\x43\x9e\x65\x6d\x35\xce\x72\x51\xea\x2b\x48\xb3\x96\xcf\x64\xaa\x0c\x20\x9b\xed\x2c\x27\xac\x96\x8f\x73\xc1\x3a\x5e\x3d\xa5\xff\x77\x6a\x4f\x8e\x51\x9a\x46\x93\x29\xce\xa5\x7c\xd7\xf7\xd8\x99\xa1\x70\x3e\xae\x3d\x0b\xeb\xe8\xc9\x12\x6c\x26\x9d\x7d\x91\xd5\x6e\xa1\xc0\xf8\xf2\xa9\xae\x9e\xe5\x7a\xc6\x3c\x33\x58\xe4\x9c\xdc\xf5\x45\x84\xc7\x92\x65\x28\xd4\x27\xe1\x42\x0a\x28\x83\x36\x63\xd1\x40\x6b\x2b\x89\x9e\xce\x48\x3b\xcb\xcf\x29\x58\x28\xaf\x6c\x4f\x1d\x9b\xa9\xcf\x9c\xcc\x6d\x6a\x8d\x6b\xa6\xb5\x26\x63\x93\x14\xeb\xb8\x28\x2f\x07\x3b\xe6\x1a\x74\x36\xaa\xe6\x08\x03\xfd\xce\xc7\x78\xc9\x98\x21\x62\xda\x23\xba\x0a\x45\xce\xcb\xc0\x10\x74\x83\xbe\xb3\xdf\xd7\xd1\xa3\xb2\x73\xb2\xb5\xa3\x50\x24\x5d\x5c\xe5\x5d\xe3\x6f\x87\xdd\xb0\x7f\x25\x30\xc1\x2e\xa1\xd5\xbf\xdb\x6f\x81\x2d\xf9\xfb\xe9\x13\xe5\x84\x1c\xa7\xdf\xd5\x18\xf4\xc1\x44\x05\xbf\x0c\x5c\xba\x35\x40\x6a\xa7\x5a\xfb\xdc\x8e\xdb\xc2\x23\x22\xe6\x8d\x22\x01\xa7\x75\x7b\xff\x5d\x65\x03\x65\x9f\xbe\x84\x46\xe0\xac\xae\xd8\xa0\xdb\x07\xc7\x1d\x98\x51\x6a\x7d\x3f\xdd\xb6\x53\x04\xb5\xdd\x2b\xcb\xb3\x6c\xf9\x92\x1c\x32\xf7\xd3\x74\x37\xbb\x17\xe9\x8a\xa1\x07\xb7\x16\x49\x68\x3f\x42\xe4\x04\x66\xac\x24\x0f\xf4\xe1\xd6\x9f\xf3\x3b\xc9\xea\xa0\x0c\xf5\x39\x44\x98\xf4\xa8\xcf\xc7\x67\xb5\x79\x37\xb8\xb7\x16\x94\xd8\x66\xdf\xc6\x46\x31\x46\x33\xfe\xaf\x8a\x48\x92\x07\xd9\xac\x3a\x3a\xa8\xc5\x37\x87\x94\xee\xb8\xbb\x37\xf3\xa9\x8c\xca\x8c\x34\xf7\xf5\xfe\x36\x2e\x16\x5e\x6c\x65\x93\xcc\x7f\x1c\x84\x6e\x0b\x4f\x64\x25\xb6\x97\x8d\x2f\x2e\x5f\x3d\x2d\xbb\x9c\x20\xde\xa4\xcf\x31\xcb\xe0\xc8\x60\xcf\xdc\x2b\x5f\x6e\xb6\x90\x7b\x47\x27\x4c\x6f\x60\xc2\x4a\x7b\x5c\x4e\x2c\x48\xde\x17\x30\x15\x8f\x7d\x6a\x35\xdd\x9f\xfd\x05\x61\x3d\xcb\x8f\x5e\x69\x79\xfb\x58\x1b\x14\xfb\xf8\x6b\x59\xca\xa6\x6e\xb1\xf4\x29\xee\x64\xee\x8a\x7d\xac\x7c\x91\xfd\x91\x23\x57\x2e\x4c\xe7\x60\xb4\x6a\x63\x0f\x04\xcb\x09\x46\x7b\xa4\x77\x40\x4c\xfe\x17\x1f\x74\x80\xe2\x13\x7a\xa6\x72\x84\x99\x13\xe4\x66\x34\x77\x87\x6d\xa6\xde\x4a\x7f\x15\xbe\xca\xc7\xe7\x7c\xb2\xe3\x74\x38\x1c\xbe\x51\x0e\x1a\xc5\x7e\x95\x59\xed\xa3\x9b\xd1\x81\xec\xd8\x59\xca\x5e\x09\xcc\xa7\x3d\x06\xfe\xdb\x63\xa4\x54\x26\x4e\x88\x96\x01\x9c\xfa\x55\x90\x48\x77\x99\x34\xd9\x45\x2b\x4d\x91\x9b\x89\x26\x80\xb3\x23\xf6\x7f\xa1\x30\xfa\x47\xd2\xd8\x76\x02\x99\x92\x2d\x78\x2e\x27\xe9\xeb\x66\x74\x69\x74\xbe\xfe\x5c\x97\xe2\x2d\xb3\x5f\x59\x6e\x02\xe7\x2d\x9b\xf4\x1f\x22\x4e\xe3\x5d\xe7\x42\xf9\xf7\x56\xa3\x4a\xaf\xd1\x8a\x0f\xb8\x68\x58\x45\xb2\x9e\xc8\xcc\x92\xcd\xd1\x77\x75\x83\xa3\xd4\xd6\x1a\x9e\x5e\x4b\xc2\x92\x96\xfe\x1d\x0f\xb1\x3f\x4a\x28\x4c\x9c\x92\x37\xa5\x5f\xfb\x2b\x91\xf9\x6c\x68\x2a\x9a\x7c\x17\x66\x25\x25\xca\x40\x23\xfa\x78\x45\x7b\x27\xe8\x81\x70\xde\xb0\xa4\xa9\x9c\x4e\x52\xe5\xe0\x87\xad\x12\x95\x2f\xed\x33\x16\x83\xfa\xd6\x53\x0d\xad\x5b\x81\x50\x6a\xa8\x15\x1b\x1e\xfc\x81\x5a\xe9\x32\xdf\x92\x5d\x7c\x39\xd0\x57\x95\x6c\x23\x57\x55\xbd\xb7\x0b\xfb\xd2\xb3\x61\x65\x26\x78\xe5\x5c\x7e\xcb\xd4\x06\x1a\xa0\xd5\x2a\x41\x86\x58\xf7\xdd\x3e\x4a\x67\x67\xa5\xca\x69\xbd\x04\x51\xad\xf6\xc2\xb1\xaa\x6b\x01\x94\x2a\xe3\x95\xa4\x07\xab\xec\xe0\x5a\xc1\x8e\x89\x36\x00\x4b\xaa\x88\x55\x6e\xbf\x6d\x9c\xaa\x06\x67\xdd\x64\xa9\x48\xa4\x2b\x42\xf9\x33\x11\xf3\x9b\x1c\x96\xaa\x07\xcf\x0a\x56\xa3\xf4\x27\x59\x5e\xa9\xab\x2d\xf6\xd6\x71\x0d\x85\x4b\xec\xce\x57\xe5\x45\x71\x08\x67\xee\x68\x1b\x02\xa2\x82\xe3\x18\xd8\x42\xfa\x7c\x0f\xe4\x00\x29\x01\xac\x8c\xd3\x1e\xfe\xed\xec\xfb\x8e\xe1\xe5\xb9\xd2\x87\x5a\x56\x4c\x19\xb4\xc5\x49\xe0\xd4\x22\xe2\xfa\xcd\x70\x93\x05\x35\x8a\x73\x5c\xa5\x80\x80\xeb\x7b\xb6\xa4\xb0\xea\x5f\xf4\x8f\x80\x3e\xd2\x0f\xbc\xcc\x31\x66\xe9\xab\x67\xe2\xf0\xef\x4f\x80\xd5\xf2\xcc\x7a\xf4\xb5\xc1\x5b\x43\x6a\x19\xa0\x94\x87\xf4\xaa\xe2\x38\x2e\xe8\x32\x71\x51\x38\xa1\xe1\x64\x0e\x07\x2c\x17\xfd\x02\x6b\x1f\x79\x10\x79\x5e\x4a\x51\x67\x2e\x70\x2e\x6f\x0c\x37\x4f\xae\x65\xf9\xc9\x0e\x6f\xee\xaa\xb3\xd3\x1b\x00\xea\xad\x66\x02\x12\x4e\x42\xc3\xda\x20\xd2\x7b\xb7\xa9\x81\x30\xa6\xc9\x71\xa5\x02\x9a\x34\xea\xe5\x73\x2b\x09\x4c\xc8\x66\x41\x8d\x99\xbc\xc8\x96\x45\x82\x2d\x9c\xc5\x60\x11\xee\x9b\x6b\xbe\xce\x4c\x75\x9e\xf5\x2b\xbb\x55\x2d\x9b\x8d\xcf\xf3\x2e\x5f\xa5\x1c\x36\x4e\xb3\x10\xa2\xf2\x69\x75\xbf\xbd\x9b\xf8\x42\x79\xea\x74\xa7\x6c\xe1\xa7\x38\x98\xaa\xe7\x3b\x6d\x26\xb6\xb2\x8d\x93\xfc\xa4\x7c\x61\x10\x69\x3b\xaa\x70\xa9\xe8\xd3\xd8\x08\xf9\xc1\xce\x71\xb1\xef\xfc\xd8\xf2\x3a\x51\xf6\xa0\xe3\xcd\xc0\xe0\x14\x65\x7e\x8e\xc8\x6e\xa8\x3c\xe0\x23\x63\x8b\xf8\xd0\xaa\xd8\x1d\xde\x2e\x53\x89\xf9\x57\x71\x4d\xd1\xe7\xa9\x0d\x0d\xca\xee\x54\xa0\x72\x15\x45\x8e\x2e\xe6\x61\xb9\x91\xc5\xd1\x5d\x14\xf6\x59\x12\xab\x39\x1c\xd3\x10\x1d\xdc\xe4\x5f\x3f\x8c\x39\x60\x7b\x4d\x29\xc4\xed\x3f\x68\x57\x38\x78\x98\x3f\x4a\x81\x0b\x6e\xdd\xd2\x9f\x4e\x5e\x10\xd3\x49\x96\xdc\x64\x77\xa7\x8c\xad\xb6\x50\xa7\x1c\x19\x6d\x53\xbe\xe8\x82\xf6\x3f\x87\xe5\x9d\x6a\x1b\xc5\xf6\xb7\x1a\x1a\x98\xa6\x34\x86\xaf\x01\x6f\xf6\xcd\x0e\x51\xbd\xb2\x51\x90\xc8\xe3\x87\x81\xa7\xc5\xce\xeb\x04\x2b\x80\x6d\x78\xa8\xde\x9f\x10\xfe\x23\x34\xab\x6c\xdd\x09\xba\x3e\x73\xd9\x09\xa9\x81\xf2\x5c\xc0\xcf\x24\x20\xf0\x64\x37\x95\x83\xcc\x74\x81\xe7\x03\xc5\x77\x3a\xad\x83\x01\x0d\x45\x46\x51\xf4\xfb\xe5\x23\xcb\x97\x4d\xc0\xac\x5c\xc6\x63\x97\xcb\x7a\xbb\xe2\xf3\xfc\x84\xa3\xd8\x0f\xcf\xd6\x45\x62\xd0\x9f\xf2\x15\x98\x9c\xf0\x03\x0e\x3b\x25\x34\x7d\x48\x09\x7f\xca\x87\xe3\x3d\xe9\x03\x43\x47\xfd\xc4\x3f\xf8\x61\xe4\x79\x3f\xca\x4c\x1d\xdb\x15\x2c\x50\x5b\x14\xf2\x0e\x62\x34\xaa\x75\x70\x22\xf6\x1f\x7c\xca\xf6\xb2\x71\x72\x9e\x47\xa8\x6d\x8e\x1a\xe9\x32\x2a\x2e\x8c\x23\x90\x36\x34\xa2\x3c\x22\xb0\x37\xb9\xd2\x69\x98\xb6\xeb\x7e\xf8\xa6\x5b\x4c\x23\xe7\x0e\x97\xf0\xa3\x9b\x91\x7a\x7d\xaa\x67\xea\xd8\xe1\x8c\x01\xb6\xc1\xef\x14\xa3\x32\xb3\xb4\x72\x79\x2a\x8f\x68\x24\xc6\x20\xd3\x1d\xb7\xe7\x26\xa3\xc4\x47\x39\xdb\x04\x05\x30\xac\x91\x40\xd9\x59\xfe\x87\x5b\xff\x6b\xf0\xd4\x5c\xb3\xc0\xb4\xad\x7c\xe1\x9e\x10\x61\xee\x11\x20\x5a\x37\xa9\x13\x59\xce\xe5\xa7\x50\xb1\xb2\xe7\x79\x8c\x21\xb2\x51\xb0\x23\x65\x33\xaa\x5a\x1f\x88\xf5\x90\xf0\xb4\x2c\x10\xf6\x9a\x44\x49\xf3\x50\x16\xdf\x43\xa5\xb5\x74\x39\x18\xb7\x93\xcc\x66\x1e\xac\xb3\x5b\x69\x0c\x01\xec\x0d\x3a\x91\x31\x0c\xc7\xea\x47\xe8\x68\xca\xde\xf1\x19\xa3\xad\x97\xb3\xd4\xd2\x85\xbd\xd6\x23\xcc\x6f\x19\xfb\xb8\xea\xeb\x18\x4a\xd5\x09\x1f\x18\x94\x7f\x74\xc5\xb7\x91\x7e\xb8\xe2\xdf\x98\xd0\xb8\xf7\xcd\xa9\xb0\x12\xc4\x35\x1a\x64\x8b\x09\x08\x16\x51\xba\x91\x30\x67\x0c\xf5\xe3\x60\x36\xf9\x20\x7e\xc5\x00\x93\x65\x41\x70\x69\xf7\x3d\xdb\x36\x06\xd7\x4b\x09\x8d\x1c\x00\x7d\xd1\xa0\x37\x55\xe9\x0e\xde\x30\x31\xa7\x72\x1e\x2c\x17\x34\xa6\xde\x98\xc6\x43\x1f\x78\x5b\xd9\x60\xde\xf9\x7d\xf2\xa9\x39\xf8\x49\xf7\xa8\x1d\x94\x15\xa5\xbb\x22\x5d\xf2\x3e\x55\x13\x93\xfb\x94\x62\x57\x72\x1f\x8f\xbf\x01\xdd\x09\x49\x71\xc6\x2b\x12\xeb\x3e\x06\x0f\x10\x53\xf3\x9c\xaa\x39\xd4\xbd\x5c\x55\x9c\x46\xef\x94\x1c\xca\x18\x6a\x9a\xd8\xa6\xba\x3b\x64\xe7\x9e\x42\xf7\x50\xae\x85\xff\x9d\x29\x19\x5b\x73\xad\x46\x60\xcd\x00\x18\x0d\xa2\x76\x9b\x3c\xe1\x20\x3c\xa1\xaa\x04\xb1\xff\x05\x16\xb5\x4b\x7d\xf3\x10\x43\x0c\x86\x4f\x92\xd7\x50\x55\x13\xce\xfb\x38\xdd\x38\x90\xb3\xbf\xfe\x09\x7a\x3d\xed\xa1\xb5\x11\x9f\xb9\x5f\xb6\x24\xa9\x7e\x99\xb3\xce\xf1\x16\xe1\x90\x7f\xbe\xaf\xcb\xef\x88\x81\x04\x7b\xe2\x41\xae\x26\x5f\x79\x5e\xab\x2d\x54\xd3\xd7\x5a\xa9\xec\x67\x35\x89\xd0\x11\x5c\x30\x18\x56\x38\x8f\xc6\xdf\x51\x7f\x64\x8e\xe4\xf4\xb1\x34\x67\xaa\x25\x6f\xd9\x66\xbb\xae\xc2\x64\xcd\xf7\xd0\x0a\xde\x6b\xf9\x20\xfe\x25\x0d\x11\x1b\x09\x55\x08\xf3\x1a\xb7\x8f\x0d\xf9\xb7\xfe\xd7\x2e\x53\x11\xbf\x16\xd1\x93\x37\x03\x67\xbe\xb7\x9c\x8d\x32\x7b\xca\xad\x6e\x9a\x51\x66\x16\xdd\xf8\x82\x7d\xaa\x30\xb4\xaf\x70\x00\x3c\x11\xa6\xbf\x15\x0f\x3b\xa2\xe5\xdb\x41\xd0\x7a\x49\x0e\x81\xbc\x6d\xf9\x65\x10\xae\x14\x31\x9f\xfa\x94\x72\xd0\x8d\x9e\x06\xe9\x48\x85\x8d\xa3\x36\x78\x80\xe2\xfc\x62\xd0\xbd\x6c\x01\xc8\xad\xbe\x01\x97\x52\x43\x21\xe4\xe4\x2e\x09\xe2\x02\x61\xf2\x48\xf5\x19\x04\xe7\xfc\xcf\xf7\x55\x68\x84\x60\x82\xbc\xb9\x19\xae\xc3\x80\xd1\x5e\xe1\xc1\xd1\x45\x31\xd5\x21\x5e\xc3\xdf\x31\x68\x99\xc1\xba\xb2\xba\xc8\xcf\xb3\xa5\x66\x87\x04\xec\xc3\x21\x05\xd0\x01\x4b\xc1\x04\xcb\x23\xdd\xfa\xcd\xf4\x32\xc8\xf2\x81\x0c\xb2\xf4\xa2\x77\xb7\xa5\x31\x4a\x1e\x91\xab\xe3\xc7\x9a\x1d\x18\xff\x6e\xb9\xe4\xdf\x54\xdf\x76\x6e\x94\x77\x40\x5e\x2c\xbb\x12\xaf\xbe\x4b\xf7\x7b\xd9\x81\x0a\x64\x29\xdb\xce\xdd\x46\x58\xbb\x53\x21\xcf\x95\xea\xef\xf6\x54\x94\x5a\xe0\x81\xc4\x76\xce\x1f\x22\x42\x56\xe6\x03\xf3\x7b\x3a\x9e\x80\xd9\x09\x86\xcd\x20\x87\x72\xd4\x26\x62\x3a\x03\xfa\x7a\xc1\x68\x8d\xa3\x73\xab\xda\xa5\x45\xad\x33\x8c\xf6\xba\x55\x84\x85\x16\xcc\x87\x38\x5c\xd8\x95\x0e\x84\x0f\xfb\x6a\x5f\x76\x3e\xaa\xf2\x23\xbb\x68\x5d\x72\x24\xcc\x8d\x61\xb1\xc5\xbe\x81\x89\x2f\x12\x1e\xed\x4a\xa7\xe1\x01\xec\x04\x5e\xc6\xf2\xae\x58\x6f\x0a\xc0\x9c\xc1\x28\x31\xd8\x11\xa3\xa5\x6a\x9b\x66\x99\x34\xd4\x67\x57\x4a\x8e\x34\x46\xf5\x9d\x4f\x86\xbe\xa1\x30\xea\xdb\x2b\x7d\x14\x96\x8a\x4a\x05\x68\xb3\xb7\x02\x61\x08\xd8\x4e\x67\x7f\x48\x70\x84\x1e\xb9\xef\x63\x0c\x43\x17\xc3\x29\x02\xc5\x5a\xf1\x2f\xdb\x29\x55\xb5\xd1\x31\x86\x14\x0f\xa4\x4b\x46\xc5\x95\x01\x69\xb3\x30\xde\xe8\x37\x01\x7d\x96\x4d\x3d\xc4\xce\xc6\x55\xfd\x96\x0b\x3a\x86\xbb\xb5\x5e\x65\xb1\x5d\xb5\xbd\x69\x1f\xe9\x08\x54\xef\x2c\x4b\xf4\xe4\xbd\x01\xd4\x48\x69\xb3\xa4\xc9\x56\x5e\xe1\xeb\xd5\x3e\x02\xfc\xab\x72\xa3\x6e\x1c\x22\x45\x94\x2e\x5e\xdc\x2a\xb7\x69\xc9\xab\x50\x45\x6e\x99\xdb\x34\xb7\x4c\xa8\xe5\x78\xca\x52\xd2\xb7\x57\x7f\xb2\x4d\x8d\xd9\x1f\xcd\x87\x8b\x75\xa4\x86\x42\x19\x2b\x50\xea\x2b\x37\xbd\x89\x04\xe7\x26\x34\xd7\x0d\x1c\xd4\x25\x52\x9a\xa6\xd5\xe2\xa4\x72\x7d\x08\x36\xdb\xb2\x76\xee\xcd\x96\x0c\xf6\xd9\xbc\xa5\x29\x45\xa0\x96\x91\x26\xe7\x70\x04\xcb\xd0\x6f\x09\xfc\xca\x43\xff\x99\x3d\x14\xba\x37\x9d\x71\x12\x63\xd8\xf0\xd6\xa6\x8c\x54\x13\x85\x22\x18\x71\xa4\xbb\xd6\x70\x32\x74\xc1\x96\xe3\x38\x9b\xda\xde\x8c\x03\xf7\x65\x80\xfa\x9c\x7c\x51\xd6\xa5\xbb\x61\x33\xa4\xef\xc5\x00\x04\x44\x4b\x1f\x9b\x68\x40\x36\x7d\x40\xa2\x65\x7b\xc0\x0b\xac\x29\x3b\x93\x37\x9d\x05\x9a\xbe\xda\x86\x85\xf9\x02\x0c\xc4\x96\xd1\x39\xa6\x21\x7e\x4a\x7f\x49\x9f\x29\xed\x0f\xbf\x53\x6c\x62\x9c\xc2\xdc\x54\x2a\x6c\x53\xfd\x3a\x9b\xf4\x23\xcb\xb0\x61\x10\xd3\xbe\x49\xd5\x1a\xec\x2d\xb7\xae\xb7\x92\x15\xca\x1e\x1f\xa2\xa3\x8f\x87\x73\x59\x7a\x8c\x77\x1d\xc0\xc7\x6e\x46\xfe\x46\x67\x57\x5c\xc0\xd3\xfe\xd8\x0c\xea\x69\x42\x2b\xb7\x7a\x6f\xa4\x77\xf3\x76\x5e\x55\x23\xd4\xe4\x68\x6c\xff\x1f\x73\xa0\x5f\xcb\x32\xa2\xab\x21\xc0\x6c\xd1\x64\x8f\xcc\x8a\x6c\x5f\x85\x04\x1e\xba\x11\xbe\xff\xc0\x66\x73\xe4\x78\x96\x82\x69\x1c\xce\x6b\x1c\x02\x27\xfc\x12\xb1\x4c\x60\xf2\xdd\x3a\x43\x6c\x17\xfd\x03\xb1\x14\xc7\x11\x4f\xe8\xe8\xe3\x52\x4f\xdb\xd4\x89\x0c\x9b\xca\x84\x80\x9b\xe6\x23\xd7\xbf\xd4\x94\x29\x2e\x68\x9b\x7f\x11\x26\xf3\x07\x9c\x9f\x33\x3d\x90\x36\xeb\x98\xd2\x9f\xe2\x2b\xca\xce\xdf\xbb\x10\x58\x92\x09\xd2\x2a\xb3\xf8\x50\x51\x31\x6a\x99\x38\x48\x21\xb4\x7e\xe7\xb2\x84\xbc\x25\xd8\x7f\xbb\x27\xfa\xa6\x82\x06\xa7\x90\x8e\xca\xc9\x1e\xd1\xa9\xe5\x5d\x2c\xe1\x47\x06\x5c\xd5\x49\xaa\x79\x95\x73\x19\xc9\x99\xda\xa1\x71\xcc\x78\xf6\xbe\x33\x26\x37\x5a\xf5\x51\x46\xed\x43\xdd\xa1\x37\x1a\xdb\x06\xea\xfa\x7e\x6a\xb9\x75\xbf\x49\x15\xf5\x4f\xb2\xa8\xf2\x6b\x08\x37\xec\x45\x22\xd4\x10\xce\xd7\x1c\x26\x7a\xfe\x40\x81\x54\xa3\x34\x2e\x31\xd2\x3b\x85\x4a\xe7\x8d\x32\x83\x3f\x35\x82\x3a\xb3\x14\x55\x01\x00\xa6\x2e\x24\x57\x56\xd1\xbc\x8c\x7d\xbc\xc6\x0d\xb9\x26\xc2\xee\xf8\x86\x5f\x0e\xe7\x00\x57\x58\x59\xd6\x18\xca\x7c\x8c\x31\xd4\x9b\x06\x8d\x1f\xd5\x84\x39\x1a\xc9\x55\xbb\xee\xb5\xa9\xc8\xab\x6f\xcb\x77\x98\x2d\xbb\x9a\x81\x2f\xdc\xe8\x6f\xc6\x50\x0f\x28\x2c\xf9\xd6\x31\x8b\x79\x71\x2b\x2b\x6a\x36\x02\x5a\x96\xd4\x47\x7a\x56\x04\x0d\xc9\x04\x81\xc5\x6d\xa7\x1f\xbc\x69\x0e\x39\x97\x1a\x77\x07\x57\x34\x41\x01\xe7\x72\x41\x79\x43\xee\xfc\x8c\xee\xac\xf8\xdd\x5c\xf1\x3b\xa8\xb4\xf2\xb7\x64\x8b\x6f\x6f\x09\xf1\xb0\x96\x47\xc2\x7c\xd4\x0f\x57\x54\x11\x13\x8c\xdf\xe0\xf1\xc6\x96\x92\xea\xad\x73\xa1\x06\x8a\xf5\x3f\x51\x2a\x65\x1e\xc2\x02\x33\xe2\x66\x81\x0a\x39\x3a\xef\x80\xeb\x96\x3a\x7e\x07\xa4\x18\xa3\xe3\xb8\x41\x20\x68\x7a\xc9\xc1\x22\x90\xc6\xce\x6b\x95\xf0\x83\x0c\x30\x83\x54\x65\x58\x6a\xe1\x1c\x63\xce\xf8\x65\x32\x1a\x92\x90\x8d\x03\xe2\x61\xdc\x7e\x53\x89\x2d\x02\x6b\xc4\x31\x8b\x23\xb5\x1a\x00\xe8\xa1\x2a\xe5\x93\xcb\xfa\x27\x33\xb5\x87\x35\x59\x0f\x9b\x4c\x13\xb3\xb3\xb7\x15\xa5\xea\xbc\xed\x17\x97\x1e\xff\xb1\x63\xe3\x71\x64\x9c\x21\x36\x44\xef\xa1\x54\x66\x72\x8e\x2b\xbf\x75\xd9\xc4\x72\x24\xf4\x21\xd4\x5d\xfb\x75\xc0\x65\x76\xff\xe0\x27\x90\x4b\x56\x5c\xd1\xbb\xdc\x03\x39\xea\x25\x9c\x3a\x03\x81\xa3\xe2\xcb\x88\x0f\x7d\xda\x22\x54\x02\x2e\x0f\x01\xf6\x21\xde\x45\xe2\xaf\x96\xb1\x7e\x04\x4c\xce\x86\xe1\x68\x1e\x1b\xe2\xf5\x0b\x35\x10\xc6\xa8\x0f\xc1\x34\x12\xeb\xb9\xbe\xd6\xeb\x72\xb0\x66\x89\xc0\x5c\x7b\xa3\xfd\x32\x47\xf8\xc8\x66\x7b\x3b\x79\x61\x0f\x96\xb1\x1d\x34\x11\x9f\x2e\xc5\x57\x45\x6f\x0e\xf5\xf1\xe2\x7e\x57\x0b\x65\x30\x70\x7a\x85\xa6\x2c\x19\x55\x61\x16\x6f\xc0\x58\x08\xac\x38\x57\x8f\x0c\x46\x1e\xc9\x1c\x38\xf9\xca\xed\x1a\xd5\xe6\xc3\xbe\x96\x42\x7b\x5f\xc5\x47\x66\xde\x49\x45\x05\xb9\xdd\xc0\x37\x1a\x7a\x25\xa1\x80\x57\xd2\xc3\xbe\x86\xc5\x40\x19\x89\x63\x0f\x2b\xba\xd1\xd1\xb9\x5a\x5f\xf6\x7c\x3f\xdc\xa9\xd8\x73\xb0\x9b\xf6\x9c\xd6\x86\x29\xfd\xfb\x62\x3a\xd3\x3e\x33\xc3\xc5\x7f\x07\x4c\xd8\xc0\x5a\xed\x46\x50\xd0\xe4\xe7\x5d\x0e\xd0\x1c\xc1\x1b\x94\xa3\x27\xec\x52\xa5\x55\x7b\xd2\x07\xd9\xa7\x8e\x83\x8b\x3b\x8d\x47\xf6\xd0\xa4\x48\x9b\x5e\x84\x13\x24\x52\x33\xe8\x45\x99\x5a\x60\x85\x51\x60\x52\x96\xa6\x64\x13\xc7\x0f\xf3\xb1\x0f\xb4\xa2\xfd\x08\xc2\xe2\x0a\x23\x86\x67\xcc\xc1\xd9\x18\x9b\xf6\xcb\x4e\x66\xef\x4d\xc5\xdf\x61\x7b\xe6\xf3\x48\xf5\xb2\x55\x69\x43\x80\x0d\x7b\x8d\x68\xa7\x31\x9d\xf3\x55\x60\xfe\x1b\x11\xd0\xed\x76\x2a\x2d\x1f\x26\x75\x8a\x8f\x01\x79\xf1\x34\x00\x08\xaa\xf8\xa1\x4c\x21\x1d\x8f\xd0\x74\x3b\x6f\xa5\xdc\xbb\x3c\xad\xe6\x0b\x56\xca\x8e\x06\x17\x6f\xcd\xdb\xdb\x95\x5e\x58\x6e\x46\x83\xb4\x69\x7a\x45\xbe\x40\x19\xcf\x70\x20\x98\x14\xeb\x72\xef\x69\x28\xc3\x71\xbb\x31\x40\xe9\x46\x79\x9a\x74\xa2\x5b\x18\xea\x6d\x27\x99\x60\x72\xa9\x13\x3a\x78\x0e\xa1\x1c\xcb\x47\xf8\xd5\xed\x8f\x2a\x54\x2b\xab\xb6\x76\x7d\xc0\xb5\x0c\x1f\xc6\xc9\xc3\x88\x8f\x07\xfb\x58\x10\x77\x13\x33\xd8\x10\x05\x1d\xfe\x51\xf4\xb3\x0b\x27\x6f\x5a\xaa\x9d\x86\xfd\x0e\x05\x7b\x61\x2d\x01\x5e\xa1\x3b\x77\x5f\x9d\x5b\x4f\xef\x3c\x8e\x10\x0d\x34\x7a\xbc\xba\x16\x08\x18\xd2\xf7\xf6\xc7\x77\xf4\xf2\xcb\x2f\xe1\x00\x99\x50\x44\x13\x37\x14\x0a\x38\x80\x27\xc2\xd1\x7d\xfa\x8a\x78\xee\x00\x81\xe8\xa1\x5d\x0d\xaa\xa6\x0b\xbe\x34\x7d\x3d\x93\xe6\x05\x6d\x6d\x84\x89\x8d\xff\x7d\x7c\x5b\x4e\x3f\x7e\x51\xb6\x96\xa9\xc0\x60\xc8\xe2\x96\x2b\x23\x66\x0c\x79\xdc\x9d\xb1\xd5\xb1\x43\x80\xa1\xc5\xe7\x26\x95\x5c\x75\x0a\x2f\x3f\xe1\xc3\xa2\xb3\x7c\x54\xe6\x01\x94\x6d\xa5\x22\x11\xa7\xad\x1c\x80\xf0\xeb\xfb\x21\xbc\xe9\xcf\x7a\x60\x83\xc5\x32\x26\x19\x62\xf2\x41\xf9\x3a\x0c\x19\xde\x7b\x23\x81\xf9\x4a\x6f\xce\xad\x88\x64\x80\x07\x7b\xab\x70\xf1\xf5\x87\x5f\x6a\x19\xaf\xf6\xd6\x2b\x5f\x1c\xda\x91\x7e\x04\x7a\x0d\x66\xca\xae\x71\x42\xa1\x0c\x2e\x73\xec\x79\x05\xbb\xac\x6b\x20\x8e\xf9\x2b\xe1\x25\xab\xe2\x20\xbf\x31\x4b\x12\x08\x23\x14\x6c\x71\x88\xc3\x4d\xa7\xa3\x55\x26\x07\x86\x60\x42\xf5\x05\xb1\x4e\xe9\x63\xe4\x0b\xc3\xfa\xa2\x93\x57\x1b\x68\xeb\xf4\x22\xc9\x67\xce\x8a\xcd\x43\xd9\x5a\x3f\x39\xde\x03\x7f\x1c\x17\xf7\xb7\x80\x64\x56\xb9\x5e\x55\xdc\xc5\x71\x79\x87\x5c\xef\x29\xa3\x7b\x6a\x90\xac\x9b\x53\x77\xc0\x90\xe4\x06\xe1\x93\x53\x66\x96\xc5\x6f\x06\x6d\x3c\x81\xb9\x7d\xff\x0a\x39\x5d\x08\x3b\x90\x4b\x6d\x17\xc0\xe4\x8e\x2b\xf4\x8f\x6e\xea\x62\xf8\x15\xc0\xe3\xa6\xcd\x0a\x46\xa2\xd7\xd8\xb5\xcc\x18\xbc\x81\xb7\xaa\x4c\xd3\xb2\x3c\x60\xd0\x50\x79\xf3\x92\x3f\xe2\xe8\xd1\x4f\x4c\x59\xfe\xf8\x0e\xd9\x34\x0a\xc1\x2c\x87\xdf\xec\x2c\x5a\x01\x86\xef\x1c\xe0\x4d\xcd\x38\x40\x37\x2d\x81\x2b\xc3\x20\xf7\x52\xc1\x5c\xea\x80\x49\x9b\xc0\x8c\x24\x8b\x25\x1c\x5a\xec\x1d\xc8\xcb\x1e\x26\x06\x63\x05\x26\x2a\x1f\x8a\x8b\x15\x4e\x3c\x1e\xa0\xaf\x47\x1c\x14\xce\x0b\x7a\x60\x23\x98\xbb\xd7\xb8\x87\x60\x5b\x17\x6a\xfe\x27\x69\x9d\x03\x71\x8c\x23\xd7\x43\x8e\xe7\x26\xfc\x00\xcf\x66\xb4\xc0\xef\x3f\xf9\x0e\xcc\xd6\x96\x26\x50\xff\x71\xd8\xd9\x9f\xb0\xc9\xf6\x89\x5f\xfa\x35\x62\xc5\x17\x80\xbd\x0d\x4e\xe7\x6c\xc4\x95\xbd\x85\x52\x1f\x18\x3f\x25\x61\xd0\xc3\xc7\xc9\xdb\x6d\x7d\x44\x28\xce\x84\xcf\x2a\x63\xb8\xf9\x6c\x79\xf5\x7e\xab\xc0\x31\x6e\x5c\x3b\xc1\x16\x70\xa8\xfc\x83\x72\x24\x92\xda\x8c\x32\xe9\xa8\xc8\x69\xd9\x4a\x48\x11\x88\x61\x90\xad\xa4\xdc\xab\xce\xf0\x38\xc4\x1a\xb2\xf4\xda\x22\xe0\x38\x4d\x6d\x5d\xae\x51\x54\xce\xc2\x6c\xe6\x71\x71\x98\x4e\xd9\x1c\xbc\x39\x28\x67\x11\xdf\x2e\x3b\xf6\x5a\xcd\x80\xb4\x36\x46\x24\x6a\x1a\x37\x9f\xce\x0d\xa0\x75\x81\x53\x5c\xbf\x8e\x88\xef\x3d\x34\x60\x33\xa7\x4f\x56\x34\xf6\xef\x48\x81\x8c\x30\x58\x9b\x3f\x28\x65\xc7\x43\xe8\x35\x35\xbd\xcd\xe8\x0f\xf1\xd6\xa2\xa8\x19\x38\x79\x20\xb0\x88\xe3\xd6\xa8\xcc\x07\x72\x9e\x93\xca\x50\x77\xfe\xe4\x00\x6e\x47\x49\x07\xcb\x2f\x37\x24\xcb\xfb\x18\x72\x26\x90\x54\xd2\x87\x72\x33\xee\x61\xc2\x39\x55\xc2\xc6\x84\xd0\x26\xde\x86\x05\xd4\x14\xbe\x98\x97\x0f\x0c\xf2\x79\x76\xde\x76\x35\xbc\x87\x66\x88\x37\x62\xb0\x87\x2d\x92\xa7\xf1\xda\xd2\xe2\xe2\x6a\x42\x7f\x84\x88\xa2\x69\xe4\x0f\x3b\x8d\xff\x64\x4a\x38\x5c\x9e\x0f\x13\xe2\x3d\x3f\xdf\xc2\x43\x7e\x51\x53\x5a\x3b\x9a\x09\x03\xe1\xbf\x0c\x62\x9f\x79\x85\xa5\xa0\xe1\x58\x16\x4c\xcf\x65\xf4\xa4\x8d\xdd\x5c\xf4\x19\x9f\x63\xb7\x68\x37\x52\xde\x45\xde\x25\xe7\x7a\xda\x62\xe4\x89\xd2\x18\x7f\xfb\x29\x35\xdf\x64\x5f\x42\xbe\xc3\x1f\x95\x46\x3f\x39\x92\x7e\x7e\xca\xfb\x71\x0c\xd4\x4f\x4f\x85\xd3\x4f\x39\xf7\x46\x56\xa6\x3f\xa9\xfd\x1f\x43\xaa\x6d\x5a\x58\x2e\x1c\x76\x6f\x46\x84\xe0\x54\x35\x22\x3c\xef\x08\xf1\x39\x9b\x67\xd7\x10\x5c\xd7\x2b\x5f\x47\x89\xe3\x69\xf2\xc1\x56\x49\x2f\x11\x5a\x51\xdd\x0e\xf3\x54\x3d\x09\x77\x9c\xe0\x4e\xeb\xd9\xb1\xea\xaf\x11\x53\x5e\xd6\x2d\xc7\x97\x3f\x52\x85\x6e\x99\x7d\xa1\x7f\xfd\x0e\xca\x8d\xdd\xa4\x75\x47\xbf\x1f\xd7\x3f\x72\x77\x58\x30\x68\xba\xaf\xb1\x3b\x63\x12\x64\xf8\xcf\x52\xf9\x0c\xe3\x12\x79\x18\x56\x3a\x2e\xb0\x16\x73\x16\x12\xc3\xcd\xf7\xea\x17\x87\x43\x74\x9d\x1f\xdc\xde\x5a\x65\x99\xce\xc1\xf1\x8c\x23\x96\xfc\x32\x73\xb7\x01\x09\x6b\xab\xe0\xa3\x6c\x78\x61\x84\x6b\xe6\x72\x25\x0a\x85\xb1\xa2\x3f\x21\x60\x10\x61\xc5\x43\xbc\x09\xe5\xc9\x8e\xff\xc8\x3f\x51\x48\x90\xb8\xa5\x88\x4f\x67\x71\x1f\xfe\x8b\x1b\xb1\x71\xb7\xc6\x78\x07\xfd\xd5\xf9\x8d\xf0\xb0\xfe\x24\x0f\x58\x28\x54\x04\xb9\x73\x48\x50\xa4\x08\xc5\x1f\xb4\xd5\x7a\x64\xcd\xe5\x8f\x4c\xa5\x21\xff\x34\x56\xca\xe1\x63\x5c\xc2\x79\xd1\xad\xcb\x0b\x5a\xfe\x51\x04\x3b\x66\x2c\x36\x55\x68\xd5\x68\x6a\xcc\xa3\x6c\x1a\xe1\x81\x38\x0a\x67\x26\xaf\x00\xa6\xd6\xf4\x9d\x7d\xf4\xe3\xe2\xe0\xa1\x25\x2b\x74\x9d\xef\x70\x90\x29\xc7\x70\x02\xa3\x29\x33\x28\xef\xdb\xb2\x2c\x28\xca\x80\x80\x2d\x5a\x33\xd6\x48\x20\xe2\x25\x2c\x24\xcb\xa9\xb3\xab\xbe\x24\x62\xac\xe4\xf4\x5b\xb5\x71\x14\xdb\x92\x0f\x2c\x2b\xb5\x1e\x97\xa1\x8e\xe3\x5d\x53\xcf\x7e\x53\x55\xe3\x0d\x68\x8a\x6b\x17\x08\xa7\x75\xe2\xd7\xcc\xbe\x05\xef\x97\x63\x33\xdd\x86\x52\x69\xea\x46\x47\x47\xff\xec\x4d\xfb\x1b\xd2\x36\xe4\xcf\x14\xe8\x72\x07\x2f\x35\x8f\x85\x17\x0e\x48\x1b\xe0\xed\x14\xe1\xee\xc9\x19\xc4\x65\x60\x13\x6c\x8c\x0c\xcf\x9e\xa2\x07\xa3\x45\x28\x48\x1a\xdf\x7c\xc8\x3a\x61\x39\xb1\x54\x87\xc8\x4e\x9b\xff\xbb\x8d\x71\x35\x2e\xc5\xf3\x78\x68\x49\x02\x03\xe2\xd4\xf7\xcb\x20\x46\xe9\x35\xb3\xbb\xea\x77\xd8\x0b\x4b\xd2\x99\xd8\x02\xbe\x4f\x39\x3c\x46\xee\x98\x01\x75\x6b\x9d\xe6\x68\xc6\xe2\xee\x83\xfb\x58\xbf\xea\xbb\xff\xe9\x71\x3a\xaa\xaa\x13\xb8\xa1\xa4\xa5\xb1\xb5\xbf\xd7\x24\x0a\x8e\x2a\x1a\x7d\x58\xcb\xca\xaf\x87\x03\x62\x60\xd6\x81\x4a\xb6\x59\x91\xe9\xc4\x32\xc2\x62\x4f\x43\xd2\xd3\xe7\x1a\x1b\xbb\xa5\x70\xd3\x12\xca\x97\x45\x95\x48\x2c\xa8\x49\xef\x67\x3b\x71\x8f\x5c\x76\xfb\x49\x3c\x76\x06\xb7\x0a\x5e\x7e\x19\x09\x87\x47\x9a\xef\x4a\xe1\x55\x82\x5c\x3b\xde\x05\x25\xe5\x33\xa0\x66\x21\x4c\x82\x96\x07\x4a\xbe\x75\x02\xf5\xaa\x13\xba\x53\x2c\x29\x02\x93\xe7\xf2\x76\xa6\x7e\x77\x86\xab\x7f\xb7\x89\xaf\x03\x6b\xc7\x48\x92\x0f\xd8\x19\x5a\x4f\xce\xa6\x1d\xd2\x4f\x22\xad\x5d\x46\x4f\xe5\x66\x5b\x74\x55\x76\x5e\x1c\xbb\xf8\x79\xbb\xb2\x4a\xea\xa1\x7a\xe9\xf8\x47\xcb\xcf\x52\xf6\x40\x01\x9b\x51\x77\x39\x7e\xcd\x5d\x44\x7d\x19\x97\xa3\x3f\xfb\x55\x9d\x3c\x85\x40\xa2\x50\x75\xf6\x8e\x28\x6a\x8f\x2b\x9b\x1e\x72\x1b\xce\xc8\x97\xe0\xd2\x78\xae\x9f\x2f\x5f\xe0\xe8\x7f\x7b\x96\xf6\x2c\x5a\xca\x9f\x2d\xbc\x81\xcb\x78\xaa\x51\xfa\x7d\x82\x96\x59\xdf\x54\xd9\x59\x2a\xbd\x09\x00\xc1\xc9\xe5\xac\xfd\x2c\xc7\xc3\x59\x70\xad\xe6\x16\x04\xce\x93\x1f\xd7\x6e\x70\xe3\x94\xbf\x63\x86\x44\x30\x02\xe9\x47\x51\xc0\xf0\xe1\x95\x37\xdf\x77\x52\x5e\xa2\xf5\x33\x69\x74\xe1\x5e\xf9\x93\xc3\xfa\x10\x18\x6e\x78\x16\x9e\x6b\x7d\xc0\x89\xc5\x12\xe6\xdd\xdb\x75\x78\xef\xc7\xcb\x05\x12\xb1\x57\xd7\x41\xad\x9d\xdb\xbc\x5e\xde\x90\x15\x77\x8d\xac\x10\xe2\xb1\x9f\x1c\xfe\x8f\xe7\xa5\x9c\xf4\x81\xc6\xca\x12\x8f\x87\xd1\x3c\xdb\x2f\xb4\x20\x71\x5f\x59\x6b\xe5\xe8\xa7\x8f\x85\x16\xea\x4d\xb7\x6b\x84\xb5\xc6\xdd\x33\x5b\x02\x55\xad\xd9\x87\x93\x63\x05\xfb\x80\xad\x86\x78\x55\xe0\xea\x05\xb5\x0a\xa7\x46\x0b\xcc\xd8\xad\x20\x56\x0e\xbb\xce\x38\x6d\xfb\xdc\x6b\xa2\x74\x9b\x89\x85\x41\xb2\x79\xd8\x46\xae\x9d\xbc\x62\x91\x90\x64\x79\x66\xbf\xb9\x23\xdb\x96\x89\x09\x6d\x8f\x52\x54\x36\xa3\x11\xd8\x7d\x8f\x36\x08\x6c\x20\x63\x45\x84\xfd\x23\x17\xd8\xf6\xa1\x4e\x69\xb9\x1d\x06\x61\xb0\x28\xf9\x77\xe3\x15\x12\x74\x5a\x6d\xde\xd2\x99\x29\x94\x9d\x63\x38\x29\xb6\x0f\x2b\xf2\xbe\x7d\x22\xf5\xf8\x1a\x49\x55\xf6\x37\xcf\x9a\xe8\xaf\xf2\xcb\x3f\x2c\x0d\x2d\xf8\x8a\x8c\x40\xf5\x9d\xe5\x37\x33\x22\xbb\xfb\x22\x83\x7e\xb3\xac\xfb\x3a\x2f\xd3\x36\x85\x9d\x32\xe0\x5b\x0f\x10\x08\x2b\xa4\x16\x65\x09\x7f\x3d\x88\xe2\x26\xc3\xc0\x1c\x6a\x14\xb2\xce\xb2\x89\x2e\x9b\x10\x8f\xcb\x5a\xad\x3f\x83\x59\xde\xb3\x5b\xea\x04\xa7\xfd\x1a\x1a\xb2\xdd\x1b\x69\xed\xe0\x22\x99\xce\x72\x35\x58\xf8\xb9\x94\x85\x4c\xa2\xc7\xb3\x94\x33\x82\x54\xcf\xee\xdd\x8f\xbb\x05\xa1\xa1\x1d\x68\x4e\x39\x95\xc0\x56\x72\x89\xae\x16\xd3\xff\x27\xf9\x48\x52\x65\x20\x43\xc8\x13\x17\x29\x5f\x3f\x1f\xec\xa8\x22\x16\xc9\x00\x28\x21\x5f\xbd\xc1\xdc\xb1\xe1\xde\x4c\x67\x85\x9e\xa7\xb0\x08\x91\x2f\xa4\x92\xa6\xa6\x60\xa8\x52\xfc\x59\x93\x98\xb0\xdf\x11\xd0\x0a\xac\x37\x22\x4e\x1b\x90\xf8\x0e\x8d\x42\x80\x19\x31\x8f\x52\x7b\x6a\x04\x69\x8b\xc1\xde\xc0\xa0\x7b\x4c\x46\x22\x3d\x34\x80\xd6\xaa\x46\x74\xa0\xc7\x77\xc5\x80\x05\xe0\xf6\x83\x2c\x9d\x01\xee\x5a\xc1\xa9\x9c\xfb\x26\x31\xf1\x5b\x78\x2e\x59\x9c\x65\x71\x41\x27\xfd\x3f\x68\xef\xae\x03\x9f\x14\xb4\xa0\x6c\xcf\xfe\x7b\xdc\x79\xec\x07\x40\x9b\x37\xe4\x4b\x1e\xaa\x7b\xcb\x32\x5b\x47\x72\x9a\x72\xa2\x54\xe0\xcd\x50\x0f\x13\xff\x2c\x45\x42\x4d\x5c\xa2\xf0\x82\x30\xea\xc9\x30\x1c\xa1\xc4\x74\x29\x57\x16\x14\xa8\x25\x01\x1d\xdb\xaf\x2a\x1d\x0e\x68\xa9\xea\x50\xe3\xc0\xc7\x58\xae\x33\x01\xd0\x5b\x39\x39\xec\x1e\x82\xcf\xf9\xd2\x69\x9b\xb6\x6c\xa9\xe8\x9c\x1d\x2f\x05\x4c\xc4\x7a\x48\xb4\xc4\x30\x03\xd4\x03\x63\xd6\xe8\xee\xf0\xc1\x65\x37\xd4\x4a\xe7\x0a\x96\x0b\x6f\x05\xfb\x2e\x8b\x40\xea\x00\x9f\x8d\x06\x03\x6a\x7e\x1b\x6b\xee\x48\xf5\x0c\xe0\x19\xe6\x0c\x5e\x59\x52\xd8\x02\x25\x93\x38\xd3\x5c\x6d\x5b\xe0\x80\xd1\xd5\x68\x2d\x5c\x5a\xfc\xa0\x50\x94\xfa\x33\xe3\x5b\x8f\x18\xac\x3b\xfe\xcf\x51\x9b\x1f\x01\x12\x19\x66\xad\x3c\x40\xb4\x37\x17\xdb\x84\xd2\x45\x33\x68\x55\x80\xab\xbd\xb7\x29\xcb\x22\x2d\x7c\x52\x77\x49\xb5\xca\x2e\x67\x3d\x97\x98\xe6\x53\x2b\x32\x79\x6a\xe4\xcf\xe4\x17\x64\x70\x96\xa2\xb3\x6a\x75\xfd\x37\x96\xf5\x87\x7f\xe6\x48\xf7\x95\x25\x8d\x6f\xfa\x73\x4e\xfd\xa1\x99\xfc\x53\xd6\xc2\xee\xe3\x24\xad\x05\x4c\x4b\x0d\x9d\xc9\xf5\x2b\x55\x02\x34\xa5\x4f\x63\xdc\xd1\xa1\x7d\xe7\xa8\x3c\xde\x57\x40\x3c\x5c\x3a\x77\xdd\x76\xb3\x9d\x76\xdf\x63\x67\x3c\xe5\xfd\xa8\xab\x22\xe0\x6b\xbd\x60\x6f\xd5\x0b\x24\x02\xc6\xc9\xfb\xb2\x21\xb7\x1d\x35\xe3\xb5\x60\x03\x5a\x0f\xee\xe2\x81\x73\xdc\x18\x85\x46\xfb\x92\xe7\xc2\x3b\x2d\x11\xc0\x55\x5e\xde\xaf\x30\xea\x2f\xb1\x1b\x7e\xa7\xa4\x3b\x12\xdb\x96\x2f\xc3\x18\x2f\x5b\xa2\x44\x3b\x03\xcc\xa9\xbe\x4c\x6b\x1e\x03\x8c\xf0\xfd\x4b\xa0\x9e\x02\x9d\x25\x1a\x7c\xd5\xa4\x27\x85\x69\x09\xdb\x95\x32\xfb\xfc\x72\xdb\x2f\xfb\x06\xf9\x53\x9d\x6b\x17\xd7\x10\x90\x64\xd8\x33\x06\xd8\xcc\xf4\xf2\xa7\xd1\x61\xb0\x37\xbf\x80\xe8\xa7\xb0\x5f\x7b\xc2\xf8\x20\x4f\xdd\x85\x1f\xef\xe3\xf6\xad\x13\x8d\x7f\x0e\x63\xcb\x92\xca\x19\xa5\xbd\x16\x8d\x83\x3d\x15\x50\x25\xda\xa7\xaa\x4b\x4d\x4d\x9e\x15\x7b\x7f\xde\xd9\xad\x3a\x3e\x46\x5d\x11\xaa\xc2\xd7\x81\xa9\x68\xc8\x42\x7f\x7b\xf1\x2a\x0e\xf4\xe8\x09\xc4\x82\x16\x7c\x68\x20\x51\xe8\x39\x2f\xf2\xea\x14\xe5\x16\x68\xa4\xb1\x15\x62\xd2\xa9\x93\x23\x3d\x6d\x74\x5b\x0e\x46\x4b\x18\x14\xf2\xe1\xbc\xaf\x3e\x59\x63\x9a\x64\x8d\xdd\xc5\x81\x8d\xd0\x38\xfe\x8a\x6c\x47\x14\xd8\x92\xe2\x7a\x3e\xa2\xe7\x5b\x06\xed\x03\x21\x4f\xba\x57\x02\x9f\x23\x4f\x65\xa6\x16\xd8\x8c\x7f\x48\x23\x55\x44\xb4\x27\x0d\x4f\x52\x45\x97\xa1\xe4\x6d\x4c\x1a\x85\x35\xc8\xeb\x4a\xdf\x04\xf8\xac\x5b\x75\x4f\x0f\xcc\xa4\x83\x92\xb2\x0f\xb0\x6f\x78\x6d\x1c\x69\xfb\x13\x5b\xeb\x28\x7b\x00\x3d\xb1\xb2\xfe\x40\x65\x4b\xc8\xf6\x15\x86\x8e\x1f\xb5\x45\xc0\x35\x1e\xb5\x7f\xca\x24\xf8\x99\x8d\x67\x7e\x16\xec\x82\x16\x83\xb8\x9f\x79\x85\x7a\x29\x74\xa7\xb0\xda\x8b\x0d\xd7\xfe\x61\xc8\x93\x00\x68\x64\x8b\x45\x43\x6f\x87\x38\x1b\x4e\x96\x18\x97\x5f\x2e\xa8\x7b\x10\x9c\xc6\x3e\x88\x8a\xd3\xf5\x52\x99\x2e\x46\x19\xaa\xf8\x54\x63\x2e\xdd\x1c\x96\xeb\x19\x56\x7f\x1c\x77\x36\x37\x25\x70\x6d\xe4\xf9\x5c\x1d\xb8\x4c\x64\x7a\x35\x38\x8c\xfc\x54\xf9\x97\x05\x36\xdd\x5e\x49\x65\x40\x8e\x25\x43\x44\xd6\x9b\x04\x91\x47\xb5\xff\xe5\x2a\xab\xfb\x46\x2b\x73\x20\xc1\xd5\x3d\x64\xc2\x5b\x9f\x3a\x09\x74\x46\x1a\x59\xb5\x73\xa7\xbd\xa9\x46\xbb\xc3\xbd\x90\x76\x18\x88\x28\xc7\x81\x3a\x67\x6b\x73\x57\x8b\x45\x99\x4a\x85\x6e\xb1\x03\xd9\xd6\xc8\xf2\x81\xf5\xa9\xa6\xa6\x3d\x97\xe9\x8a\x0f\xce\xe1\x25\x5b\x96\xd1\x2a\x6b\xc4\x92\x6a\x03\xcf\x05\x5b\xad\xce\x23\xde\x54\xf1\xc2\xbe\x8c\xc0\x2f\xf9\x8c\x25\x29\xcd\xa4\x0c\x9e\xbd\xa3\x8f\x77\x88\x93\xfc\xc1\x67\x60\x0b\x65\xdf\xa7\xdf\x8e\xa9\x6a\x7e\x91\xa9\x9a\x8a\x97\xa1\xfa\x9a\xfb\x94\xe5\x60\xb4\xd3\x17\xe8\xc1\x82\x14\xd8\x76\x40\xdb\xc2\x66\x10\xb0\x36\xc7\x48\x7f\x22\xd7\xca\x71\x8a\x3b\x14\x9e\x81\x4e\x77\x6c\x61\x6a\xa8\xf8\xc9\xdb\xff\x39\x4e\xcd\x0a\xd5\x71\x7d\x6f\xc2\x01\xe9\x96\xca\x0f\xf3\x60\x04\x8a\x1c\x56\xfb\xc6\xfa\xda\x07\x8c\x4f\x96\x80\xb7\xcb\x9d\x8f\x64\xe5\xef\x23\x88\xf3\x40\xb4\x23\x18\xed\xdc\x5e\x02\xa9\x21\xd2\x53\x05\x0b\x47\x3c\xa5\x8a\xa3\xaf\x6f\x41\x2a\x75\x46\x02\xb9\xd3\x6f\x8e\xa8\xa8\x3d\xbd\x4b\x71\xc1\x77\x95\x5e\xa3\xe6\xa4\x1d\x2d\x45\xbe\x8e\x94\xaa\x7a\x81\xc4\x93\xc2\x62\xd5\xa5\x6b\x92\xf1\xe8\xc8\x3d\xdb\xff\xad\xda\xf9\x6c\xf9\x93\xa2\x0b\xe2\x5c\x34\x09\x3a\x19\xf5\xd1\xa8\x49\x40\xf9\xea\xe2\x81\x70\xe2\xb2\x09\x08\x74\x7a\xac\xf7\x71\x49\xd9\xc6\x7b\x4d\x3a\x7b\x55\x8f\x2b\xa5\xa6\xd5\xdc\x32\x04\x45\x6d\x6a\x98\x10\x5e\x1e\xdb\x8a\x0e\xef\x6e\x42\x21\x40\x6d\x7a\xc5\x2b\xed\x55\xc0\xba\xb7\xe1\xb2\x8d\x40\x85\x80\x1e\xca\x18\x51\x5f\x01\x03\x0b\xbc\xfa\xd3\xeb\x2f\x56\x96\x55\xba\x50\x19\xe4\xd7\xa5\x90\x55\x17\x1a\x02\x04\x5f\xff\x5b\x4f\xa5\x95\xb1\x6b\x89\x88\x3c\x9c\x2d\x43\x85\xd9\xa0\x1e\x0a\xd3\xc4\x4d\x6f\xa7\x3d\x2d\xcc\x15\xbb\x75\xaf\xe3\x7f\x31\x5c\xda\xb1\x7e\x39\xce\x60\x0b\xd9\x2d\x0f\x77\x7f\x30\xc4\x0b\x5c\xe8\xf6\xe5\x06\x86\x83\x3e\x1c\x68\x9b\x78\x87\xe8\xca\xa7\xe8\xac\x7e\x65\xcb\xc1\x6d\x51\x9f\x3c\xad\x26\x2a\x42\xfd\x3a\x09\xbe\x2e\x4f\x80\x9a\x80\x5f\x6b\x79\xfe\x83\xfd\xd0\xf5\x33\xcc\x01\x69\x57\x8d\x83\x36\x7a\xb1\xab\x93\xdb\xab\x2c\x4f\x78\x06\xaf\x20\x3a\xdc\x88\x48\x5f\xfc\x49\xba\xba\xee\x15\xee\xf6\x2d\xa0\x91\xda\xdb\x0f\xc1\x6c\x3d\x52\xd9\x42\x55\x8f\x45\xb9\x9b\x30\x09\x2a\xb5\x7e\xa5\xb8\x05\xf7\x5e\xd6\x22\xc4\xb7\xfd\x94\x24\xc0\x1b\x2d\x6b\x03\xd5\xfb\x51\xe7\x4f\xb4\xd3\x83\x02\xb0\xa2\x97\xb0\xc4\x40\xf7\xa4\xa8\x4c\x6d\xff\xea\x51\x13\x77\x1a\xc7\xc6\x76\x9e\xcf\x1c\xc3\xfc\xac\x8c\x82\x2c\xb9\x8e\xff\x53\x61\x04\xa3\xfd\xd6\xfc\xbb\x75\x0c\xa3\x43\x06\x39\x0c\x82\xb4\x07\x14\x22\x7e\xac\x6e\x20\xc2\x95\x01\xc5\x8a\xcd\xc1\x1c\x1c\xa5\xc0\xa9\xf5\x97\xed\xc7\x78\x3f\xf0\x6a\xdf\xb2\x85\x6f\xe0\xfa\x40\xaa\x90\x95\xb7\x0a\xa1\xc2\xd4\xe4\xdf\xa0\xaf\xfa\x5b\x29\xff\xa0\x2d\xab\xa4\x81\xaa\xa6\x2d\x5f\x98\x3e\xcd\x65\x5a\xb4\x42\xc6\xc7\xa9\x06\xfe\x05\x92\xf1\x84\xb5\xbb\x1e\x0a\x8b\xf0\x88\x1f\x93\x0e\x97\x83\x69\xd7\x43\xa3\x9b\x0b\x59\x6e\xc5\xa8\x89\x69\x7b\x8c\x64\x58\x0f\xfd\x65\x96\xab\xd3\xf5\x1e\x18\xd9\x89\x1e\xec\xb0\x94\xcd\x51\xe7\x80\x81\x69\xf6\x40\x19\xea\x8b\xcd\xe7\x48\x3e\x72\x46\x5c\x30\xbf\x87\xec\x20\x50\xe4\xeb\xf1\x57\x65\xdf\x4c\x77\xb5\xa5\x7e\xf1\xaf\x08\x98\x1a\xd0\x50\x60\xd6\x97\x71\x58\x0e\x6f\x0a\x1d\xf4\xf5\x09\x2a\x46\xf2\x3f\xd0\x78\x84\x67\x2f\xf2\xbf\xc9\xff\x1e\x4c\x8a\xc4\x13\x96\xcf\x14\x38\x75\xbe\xd2\x6e\x17\x68\xce\x26\x67\x5b\xb0\x5a\xd2\xb6\x0c\xbd\xd2\xee\x76\x81\xd9\x42\xb3\xf5\x3f\x0d\xd1\xfa\xd1\x06\x69\x61\x1c\xbc\x12\xf9\xf8\x0b\x32\x7a\x4f\xe2\x63\x87\xc4\x2e\xfd\x79\xf9\xd3\x3e\x1f\x79\x73\xcc\x06\x7d\x6b\x19\x00\xa1\xf7\x96\xaa\x30\xdd\xf9\x79\x1c\xe9\x9f\x4c\x3c\x53\x96\x7f\x3a\x99\xe7\x4f\x39\x2b\x9f\x31\x30\xdf\x20\x90\x67\x13\xf9\x88\x91\x2f\x5f\xfe\xb5\xa7\xdb\x71\xc2\xc9\x2d\xc6\x99\x4d\xdd\x9b\xf3\x72\xce\x97\x30\x82\x98\x79\xf2\xce\x11\xb1\x3f\xa5\x60\xb8\x49\x82\x6c\xa4\xdb\x2a\xdc\x71\xcf\xc3\x67\x89\x8b\xe4\x5b\x81\x1c\xc8\x3a\x50\x1a\x95\xd3\x08\x5b\xf3\xb6\x6f\x1e\x67\x3f\xa1\x3b\x14\xa1\x4a\x01\x32\x57\x57\x3e\xb4\xd2\x21\xe7\x7e\x48\xb1\xe8\xce\x6e\xae\x0b\xfc\x8e\x7f\xa1\x4f\x91\xb2\xc6\xa1\xc0\xec\xe8\x80\x96\x45\xe2\xd4\x4d\xd9\x05\x4c\x46\xad\x4b\xa1\x58\x7e\xa3\xd9\xe3\x49\xee\x28\x90\xf5\x23\x82\x52\x43\x20\x55\xa3\x6c\x1a\xc3\x43\xd7\xff\x1c\x66\x77\x23\x2f\xd0\x23\xfb\x25\xd1\x24\xfc\x49\x52\x1a\x93\x22\x33\x9d\x93\x1a\xfc\xd3\xf9\x04\xeb\x91\x40\xb9\x74\xc6\x86\xbf\x5f\xbd\xf7\x72\x10\x2d\xfb\xe7\x98\x72\xf8\x2c\x4f\x65\x3d\xda\xd8\x9f\x9e\xca\x7c\x64\x28\x82\xd9\x5c\x1a\x04\x53\x20\xdc\xcf\x70\x1b\x1d\xb7\xf2\x6f\x9c\xb4\x83\xb1\x06\x79\x16\x0f\x7d\xea\xc7\x3d\xb8\x79\x53\x3a\x59\x2e\xdd\x1c\xc0\xa7\x5b\x7b\x6e\xfa\x1b\x99\x52\x14\xe2\x53\xd2\xa9\xf3\x2c\x2b\x0f\x31\xec\xb2\x87\x98\xe0\xa6\xb3\xbf\xa5\xe6\x7e\xe6\xfd\x23\x6e\xeb\xf3\x01\x87\xd1\x1b\x85\xc8\xfa\xee\x9f\x96\x55\x3d\xfd\xd0\xb2\x23\x9f\x38\xa1\xfc\xd0\x69\x58\xf0\xf6\x89\x08\x35\xae\xdd\x65\x38\x3a\x03\xf9\x87\x42\x79\x41\xe1\x79\x72\xec\xd3\x8f\x34\xab\x3f\xc0\xeb\xc7\x56\xa0\xf8\xa6\x9e\x17\xdc\xc4\xb4\xca\xfe\x54\xd5\x0a\x80\x6f\xed\xa4\x81\x7b\x7f\x87\xe5\x05\xd4\x6d\x84\x5a\xd4\x59\x3f\x72\x1f\xd7\x51\x23\x6d\x4f\x0c\x87\xd3\xf8\x54\xf7\x0b\x6b\xb6\xcd\xef\x9d\xc0\x47\xbc\x6e\xff\x0b\xff\x83\x2b\xbd\x0f\x8e\xa8\x61\x08\xdc\x7d\xd1\x50\x05\x4b\x97\xc3\x80\xa4\x9d\xed\xe7\x7f\x21\x8e\x6e\x55\xc1\xac\xa9\x14\xc0\xfb\x12\xbc\xde\x72\x90\x84\x9b\x37\x5b\x48\x95\x19\x9a\x1c\xfa\xe6\x2f\x03\x92\x4b\xd4\x1c\xe9\x81\x61\x81\x3a\xfa\x0a\x85\x9c\x80\xec\x82\x51\xfa\x86\x87\xe2\xb8\xa1\x6b\x2e\x2f\xb3\xd8\x27\x58\xdd\x1b\x38\xff\xfe\xf3\x60\xd5\x0f\x01\x25\x73\x40\xd0\xb9\x33\x06\x1d\x66\x45\x0f\x1a\xf5\xda\x35\xb8\x9c\xc7\x65\x4f\x72\x24\x3b\x0e\x33\xfd\xf0\x26\x04\x5a\x30\xf2\x21\xd3\x05\xf6\xce\x85\x30\xef\xce\x5d\x05\x88\x8f\x42\x52\x43\x8b\x5f\x01\x40\xc7\x35\xfd\xe8\xcd\x58\x63\x7c\xa0\x2f\x89\x47\x2a\x2b\xc0\x5d\x0a\x65\xed\x44\x1e\xc9\xb6\xc1\x5b\xac\x4d\x65\x88\x56\xb6\x86\x4b\x37\x38\x10\x11\x3d\xbd\x36\x68\x06\x38\x1a\xdf\x21\xf6\x79\x80\x19\x4e\x80\xbc\x36\xf1\x10\xda\x50\x87\xdd\x4f\xb9\x29\xf3\x63\xea\xdb\x8b\x83\x36\x20\x90\x81\x80\x16\x48\xd4\x44\xbe\xd1\x56\x17\xb4\x7c\x26\xea\x26\x6c\x7c\x3a\xa8\xc4\xbe\x90\x67\x1e\x1b\x15\x1f\x97\xfa\xe9\xca\xc1\x9c\x47\x3d\x62\x84\x7c\xb2\xf5\xbd\x9e\xf2\x07\x10\xf5\x47\x81\xe6\xfd\xe7\x7a\x56\xd9\x0e\x4c\x55\x7f\x1d\x26\xc6\x59\xca\xe2\x01\x5a\x65\xaa\xb7\x27\x41\xe8\xe5\xc5\x3e\xec\xfd\x53\x09\xd1\x87\x20\x65\xd0\xde\x63\x20\x83\x54\xe8\xf7\x9f\x5d\x1a\x87\xca\xd6\x1e\xd2\x19\x77\x1d\x01\x84\xbb\xa5\x74\x77\xde\xe4\xfd\x7c\xda\xad\x38\xcf\xb4\x47\xb8\x6f\x97\x9e\xfd\x5e\xbe\x15\x4e\xfd\xf7\x0c\x1d\x25\x17\xda\x7b\x39\xdb\xb4\xe4\x43\x8b\x1d\x6b\xf7\x1d\x7b\x0e\x09\xa9\xcb\x5c\xfa\x16\x5f\x11\xc3\x47\xc4\x22\x2e\x7f\xbc\x19\xf5\x18\x25\x2e\x32\xfe\x90\xc0\xf8\x34\x2e\x15\x10\x1f\xc3\x29\xe5\x3e\x56\x20\xbb\xfc\x86\xf7\x90\x86\x8f\xd8\xf8\x6b\x9b\x04\x24\xbc\xee\xa6\xef\xf2\x30\xd2\xfd\x5d\x24\x95\x72\x0d\x71\xb7\x1b\xfe\x10\x30\xba\xaa\xcf\x00\xd7\x51\x9c\xb0\x7b\x0f\xe7\x09\xa3\xf9\x1c\xeb\x6b\xe9\x0d\xc4\xa7\x17\x66\x9a\x48\x55\xb4\xdf\xdc\x3d\xc1\xf0\xa0\xd7\x28\x39\xb4\x15\x26\x60\x7a\x4d\x44\x2a\x2e\xb1\x93\xea\x7f\x1d\xee\xfc\x75\x20\x50\xfb\xb7\x54\x4d\x75\xd8\xaf\x81\xc1\x43\x97\xe6\xbd\x5a\xff\xab\x1b\x2b\xbe\x8d\xac\xb3\xd8\x44\xec\x7d\x10\xe3\xfa\xe5\xef\xc3\xdf\xa8\x2f\xb3\xaf\x45\xdf\x6f\x6f\x39\xd1\x0e\x0d\xf1\x72\x79\x53\xb4\x8e\xd5\xfd\xd0\xad\x54\xc1\xf7\x80\x13\x53\xff\xd8\x12\x24\xa8\x7e\x1e\x05\xc4\x43\xe3\xa3\x3b\x90\xc6\x15\xcf\x99\x43\xf2\x5d\xe5\xfe\xd6\x7a\xeb\x93\x96\x45\x8c\xf4\xf9\xfe\xb1\xfd\x3f\x57\xdf\xb6\xe5\xaa\xce\x33\xfb\x2e\xb9\xe9\x9b\xfd\x52\x06\x1c\xa0\x03\x98\x8f\x43\x32\xe9\xa7\xdf\x2a\x55\xc9\x64\xfd\x73\xad\x31\x90\x09\x49\x68\x02\xb6\x25\xd7\xc1\x7e\xd9\x41\x57\xc6\x13\x13\x3d\x04\xdd\x35\xe9\x2e\xea\x5c\x6f\x8d\xb4\xe3\x33\x64\xf8\xba\x28\xb9\x74\xee\xa3\xa2\x9d\x10\x3d\xc2\xb6\x50\xfd\xd7\x66\x33\x10\xb7\xa0\xe9\x54\x17\x66\xaa\x5d\x89\xed\x66\xf3\x4d\xbe\xb4\xfa\x75\xf5\x70\x76\x5d\xb9\x58\x38\x97\x88\x0d\x96\xf5\x4b\xf5\x70\x74\x0f\xa6\x4a\xf9\x3e\xc8\x7b\x08\xdf\x46\xbe\xcf\xfe\xec\x0f\xd7\xe4\x77\x37\x4e\x7e\x88\xe7\x0d\x54\x64\x65\x87\x27\x99\x12\x20\x5c\x9d\x2a\xae\x8f\xa4\x0d\x4a\x65\x7e\x43\x0e\xc4\xa3\xf0\xd5\xee\xf4\xfb\x75\x23\x68\x8f\xfa\x74\x5f\x9e\x74\xce\xf3\x98\x62\xf1\x13\x90\x00\x4a\xd1\x8b\xbe\xad\xd5\x7d\x0d\xb0\x8c\xc7\x5e\x1d\x6a\x57\x61\xea\x50\x61\x9e\x58\x1d\x47\x48\xf8\x30\x69\xe9\xd9\x2b\x14\xfc\x98\xa7\x8d\x6e\x21\xbc\xdc\x96\xd8\xdb\xa4\x5b\xab\x39\xb1\x57\xe8\x30\xe7\xf3\xed\xca\xde\xb3\x4b\xb3\x2a\xaa\x16\x05\xd0\x20\x8d\xfb\x25\xf2\x76\x47\x3a\x5c\xf7\x53\xb2\xbc\x0e\x5a\xa7\xca\x08\x65\xb0\xe9\x86\x80\xf1\x3e\x5f\xe4\xdd\xd0\xd2\x0d\x14\xaa\xcc\xb7\xb9\xe0\x66\x23\x19\x83\xbc\x0a\x7e\x60\x93\x13\x2d\x7b\x39\x56\x60\xbb\xd8\xb5\x79\x43\xab\xe9\x5b\xe0\xf0\xd9\x5a\x6e\xdb\xc8\xb5\x9a\x45\x5a\xfa\x5a\x0e\x45\x42\x11\x10\x21\x53\xa1\x06\xa5\x42\x01\x9c\x0c\xc7\x90\x62\xaf\x15\x2f\x00\xf4\x40\x1b\x4e\x94\x0e\x1f\xe8\x6e\xc9\x67\xfb\x75\x26\x31\xe9\x49\xde\xfe\x72\xa7\xb4\xce\xef\x56\x61\x83\x06\xf4\xd9\x86\x07\x65\x17\x00\x34\x97\x86\x9e\xbf\x98\xe2\x33\x7d\x35\xf4\x75\xf3\x2c\x1f\x18\xb7\x8b\xac\x3b\x6f\xa7\xca\xb0\xc4\xb3\xa8\x39\x83\x12\x1e\x4e\x91\x32\x7f\x2c\xc2\x0b\x30\x57\x6f\x03\xb7\xde\x86\x72\x14\x70\x01\x5a\xa6\x1f\x1d\xd3\xcd\x45\x7f\x9b\x43\x48\x5e\xda\xa6\x28\xbb\x82\xb9\xae\xf9\x8f\xcc\x9d\x2c\x00\xb9\x9a\xcb\xff\x23\x96\x8b\x3c\x42\xb7\xc7\x40\x3f\xd8\x90\x33\xb9\xde\x39\xf4\xbc\x3c\x8c\x17\x63\x39\x02\x58\x02\x51\xc6\x87\x2a\xd8\xec\x02\xcf\x12\x74\x46\x77\xac\x9c\x94\x0d\xb1\x6d\x5c\xf2\x79\x92\x9b\x24\xca\x0a\xda\xbb\x55\xb8\x47\x72\x7f\x8e\xda\x50\xca\x82\x3a\x66\x3f\xbe\x05\x3b\x80\xdb\xa4\x64\xc5\xe0\x38\xe9\x9b\xf5\x88\xfc\xbd\xf5\xf9\x06\x61\x09\x98\x4e\xa1\x27\x7a\xed\x6a\x06\xbf\xdc\xa2\x2e\xd4\xa8\x7d\x89\xd4\x23\xac\xb9\x27\xd9\x5f\xda\x44\xde\x7f\xa8\x84\xc5\x7b\x5f\xd6\x86\x24\xa5\xd6\xc3\xb1\x56\xc0\xed\x22\xb9\x68\xae\x51\x9f\xb1\x8a\xd1\x54\xab\x5b\xd0\xc4\xb1\x40\xc8\xa5\x71\x14\x9e\xb9\x74\xed\xac\x34\x5f\x1c\x0f\xe4\x47\x03\x8a\x4d\xe0\xe7\x9b\x2d\x5c\x7f\x6c\x1e\xfc\xd1\x56\x7c\x6e\x24\x3a\xa4\x84\x40\x64\x5a\x48\x06\xdc\xfe\x02\x1b\x9c\x01\x43\x38\xb5\x30\xdb\x94\x9d\x5e\x76\xf6\xb7\x08\xd3\xd6\x4c\x67\x96\x2f\x82\xb3\xc9\xb5\xc0\xd0\xd8\x7d\x47\x90\x83\x3d\xb7\x49\x35\x55\x98\x73\xb1\x0b\x07\x51\xd1\xf7\x10\x02\xdc\xe4\xac\x85\x6b\xeb\x39\x9a\xb3\x67\xd4\x9e\x54\x6e\x6f\xc4\xa7\x69\x00\x41\x14\xab\xfb\xaf\x94\x17\x89\xdd\xd7\x47\x45\xe4\x26\xbd\x6f\x09\xe8\x5d\x03\xbc\xac\x2a\xab\xf8\xf3\xe6\x00\x17\x72\xc8\xb7\x99\x0b\x7a\x16\xf5\x81\x1d\x08\xdc\x40\x22\x74\xbe\x49\xac\x11\x34\x20\x55\x7b\xc1\xa1\x41\x29\xda\x45\xb7\xd3\x8b\x78\x85\x97\xde\x0b\xea\xb4\x9c\x36\x53\x5b\x91\x09\xed\x6b\x95\xbc\x25\xad\x2f\x43\xc3\x13\x69\xe6\x34\x92\xb0\x7d\x48\x4c\x82\x8d\xad\xb4\x9a\xe5\x20\xbf\x22\xa2\x00\xec\x60\x5f\xc3\xde\x03\xe2\x01\x32\x3a\x79\xfb\x96\xd2\xd7\xa5\x75\x74\x5f\xa3\x64\xa7\xd7\xe1\xfa\x77\xab\x2d\xef\x43\xa0\x37\xec\x09\x22\x04\xc7\xeb\x67\x7c\x72\xd2\x26\x54\x00\x5d\x52\x7d\x00\xfc\x17\xd6\x55\xae\x7f\x3b\x54\xdc\x2d\x9a\x36\x38\xf8\x75\x81\x56\x35\x94\xb3\xf9\xed\xcb\x15\x3a\xd4\xb4\x24\x96\x62\xb5\x5e\xc4\x9a\xb9\x0f\x69\x4a\xbf\x5d\xc1\x3a\x56\xd0\x20\x49\x2d\x04\xbf\x5d\xe0\xed\x8c\xc2\x49\x02\x56\x80\x00\x01\xd7\x26\xd1\x29\x58\x2f\xbc\xdc\x0d\xc7\xa9\x2a\x4c\xfc\x88\x2a\xdc\x91\xc6\x0d\xa5\x55\x9e\xd7\x28\xfa\xbb\x4d\xfb\xe9\x3b\xc0\x3f\x02\x2a\xb7\xa8\xd5\x71\xf6\x9a\x9e\x36\xd3\x5e\x14\x8d\x5e\x9f\x48\x36\x54\x0a\xb1\xf0\x55\x64\xb6\x5f\x19\x89\x3a\x25\xa7\x15\x7b\xd8\x9e\x73\x48\x50\x42\xb0\x1a\x88\xd4\x9a\x5d\xa7\xe6\x82\x4f\xad\x47\xee\x41\x8c\xa3\xfe\x46\x97\x14\xbe\x38\xe7\xb8\x4a\x19\xbc\xb4\x76\xcd\x0e\x70\xba\xc2\xa9\xf5\xb2\x5b\x6e\x1f\x2c\xef\xb6\xf8\x73\x72\xfd\xea\xb3\x8d\xf2\x4c\x07\x59\x9e\x03\x1f\x26\xf7\xb3\x2c\x40\xad\x7b\xe3\x93\xe0\x4c\x79\x59\x33\x01\x60\xb0\x8e\x3e\x3d\x73\x3f\xd0\x7f\x0a\xb8\x06\x03\xad\x6a\xad\xfe\xfb\x7c\xfd\x21\xb3\xd0\xc0\x1e\x8c\xa1\xcd\xee\xf2\xd5\x01\x43\x60\xe6\xf6\x51\x25\x0a\x5b\xbd\x94\x34\xb7\x70\xcc\x01\xe9\xf0\x07\x1d\x77\x3f\xb7\xff\xf6\x27\x91\x3f\x00\x71\x7b\x5f\xa6\xf5\x38\x7c\x1b\x81\x36\x70\x9e\xba\xa5\xb7\xce\x65\xc7\x72\x9b\xff\x1e\xef\x32\xbd\xf6\x4f\xea\xfd\xaf\x7d\x8f\x7f\x0b\xf5\x43\xde\x23\x34\x56\x76\x46\x63\xa0\xf2\xdc\x7d\x54\x13\x59\xa2\x0f\xe0\x4f\xce\xe4\x13\x56\x74\x2a\xeb\xbd\x69\x2a\xa2\x08\x6c\x4b\xc6\xc4\xe4\xbd\xf3\x30\xfa\x5a\x25\xe2\x74\x0d\xa7\xf0\x0b\x17\x37\x1c\x18\xde\xf1\x2d\xc9\x2e\x7a\x61\xd4\x8d\x4c\xea\xcf\xd3\x97\x47\x4f\x18\x5d\xf6\xc4\x32\x08\x6c\x72\x42\xbf\x92\x43\xa9\xa5\xd8\x81\x36\x40\x65\x30\x60\x05\xa3\x63\x29\x26\x21\x17\xc6\x50\xa1\xa9\x7b\x64\x5d\xce\x37\x52\x17\xa8\x36\xdc\xcc\xf4\x94\x48\x37\x99\xf2\x4b\xc4\xad\x9e\x8c\x73\x69\xc3\x2b\xc0\x19\xf2\x9b\xe8\xf2\x96\x2f\xee\x0f\x42\x16\x1c\x14\x70\xee\xac\xae\x40\xd9\x5a\x65\x8c\x03\x00\x7c\xe1\x11\x2e\xae\xc9\x1d\xee\xd9\xc6\xd5\x78\x87\x25\xf0\x55\x16\xf7\x6d\xeb\x43\x9b\xf6\xb5\x5a\x11\xc5\x02\xb6\x3e\x25\x2b\x6f\x26\x68\x41\xb9\xb9\xf5\x62\x76\x87\xc8\x75\xd5\x0d\x55\x29\x28\x48\x0c\x83\xb4\xf9\xbd\x81\x62\x50\xc5\x34\x70\xfa\x72\x58\xa7\x26\xbf\x61\x54\x57\x77\xf8\xff\x3f\x82\x8a\xcf\x1f\xff\xc0\x53\xe4\xa0\x08\xa4\xc6\xab\x86\xfc\xc3\x26\x5c\xdc\x42\xbb\x46\xaa\x01\x70\x0c\xf5\x7e\x0e\xd6\xf8\x1a\xf7\x8e\x71\xb5\xfd\xfa\x9b\x85\x7c\x70\x05\xee\x86\xd3\x95\x83\x86\xdb\x07\xcc\xa8\xfc\x34\x98\x11\x57\x07\xd8\xb1\xbb\xe2\xcd\xc4\x74\x1e\xc3\x39\x0b\x0e\x7f\x0c\xdb\x19\xf0\x3f\x8b\xab\x55\xe3\x81\x89\x5a\x64\x76\xe0\x00\x49\xdc\x94\xa2\xdc\xba\x55\x49\x09\x89\xe9\x0e\x50\x9b\xd6\x9b\xf8\xef\x60\x37\xbe\x74\xba\x97\x14\x17\xa7\x26\x79\xc0\x65\x00\x01\xc1\xbd\xc2\x6d\x84\xe5\xeb\xb6\x09\x53\x07\x15\x1d\x3a\xe1\xee\x2e\xa5\xd0\x88\x4c\xe5\x72\x3e\x5c\xe8\x46\xde\xb8\x3f\x2a\x54\x62\xe4\xaf\xb6\x7b\x5f\x90\xef\x90\x41\x38\x82\x9e\x7f\x90\x86\x10\xcb\x7f\x0b\xca\xf2\xb9\x62\x1d\x94\x50\x01\xf4\xad\x84\x46\xcc\xeb\x0f\x83\x9e\xca\x01\x2e\x05\xf0\xa8\xa0\x09\x82\x3b\xce\x46\x29\x81\xb7\x28\xf3\xb0\x33\xa4\x5b\xa2\x5b\x4f\xf7\x2a\x89\xec\x94\x5a\xf7\x48\x42\x9c\x1e\xe7\x8f\x54\xd4\x80\x95\x0d\x03\x45\x36\xd3\x8c\x64\xdd\x63\x22\x40\x8e\x10\x24\x75\xf8\x9c\x76\xc9\x60\x6d\x77\x17\xcb\x10\x94\x06\x7e\x5a\x9c\x7d\x94\x31\x85\xed\xb0\xf1\xb5\x4a\x7c\x83\x22\x7f\xd5\x48\x57\x03\xe0\x09\x99\xf0\x52\xed\x8c\xc4\xfc\x6d\x0b\x68\xc4\x06\x3a\x12\x57\xf9\x89\x94\x47\x99\xe8\x13\x2a\x10\x7b\xe0\x94\xb0\x92\x2d\x6d\x05\x00\xa2\x42\x67\x9a\xd5\xb3\x7d\x71\x64\x04\x61\x15\xe5\x43\x71\x1c\x35\x50\xe9\xe1\xb1\x80\x57\xe8\x98\x24\xd0\xa8\x45\xfe\x84\x07\xb4\x42\xb1\xf0\xfc\xfb\x3c\x06\x71\x60\x9f\x73\xf5\xbe\x8d\x1a\xd1\x3e\x65\x62\x3e\x6c\xbb\x16\x19\xca\xa3\xe1\xf0\x82\x29\x05\x72\xda\x86\x0e\xbb\xb9\xa9\x18\x30\x86\x1a\x38\xd6\x46\xf4\x79\xa3\x2a\x6a\xa2\x66\x09\x61\xe1\x86\xb6\x71\x44\x57\xa5\xe3\xdd\xb8\x56\xf0\x08\xa7\xbb\x33\x74\x55\x00\xc5\x70\x08\x4b\x5a\xe0\xb7\xdf\xe1\x60\x37\x65\x11\x4f\x21\x90\x19\xf1\xba\x34\x06\x30\xd5\xf1\x53\xb3\xe4\x08\x93\x3c\x22\x37\xd2\x07\x90\x0c\xc5\xf3\xc9\xed\x0f\x35\xba\xb1\xec\x28\xb8\x17\x44\xc4\xf4\x41\x19\x65\x75\x55\x66\xf7\x2c\xde\x2e\xf4\xc6\x5b\x16\x5c\x76\x32\x7b\x76\x7b\xf2\x57\x76\x87\xd4\x18\xe7\xc2\xec\xde\xd2\x6b\xd5\xdf\xd4\x06\x7a\xdd\xa2\x2d\x57\xa4\x92\x35\x2a\xda\xa5\xf5\x7a\xbd\x1f\x1d\x5e\xcf\xbb\x93\x8d\xe4\x91\xec\x5a\x02\x02\x74\x4c\x55\x61\xc3\x42\xed\x4a\x73\xb0\x3d\xb6\xb3\x17\x70\x9a\x32\x02\x77\xe4\x90\x80\xb3\x2b\xd5\xfa\x15\xac\xfd\xed\x21\x55\x81\x4a\xa7\x47\x43\xbb\xc1\x74\x11\xd8\x63\x17\x2e\xc4\xce\x5a\x6f\xa6\x58\x1a\xb2\x21\xa2\x44\x22\x8b\x05\x89\x3d\x8e\x69\xb8\xb1\x41\x99\xb0\x10\x69\xec\x6c\x55\x35\x12\x33\xca\x25\x09\x14\x11\x2e\x66\x81\xd6\x20\x52\x8d\xaf\x79\x02\x2f\x14\x84\xd0\x82\x08\x82\xb0\xb1\xe5\xea\x2e\xa1\x96\xcd\xfc\x53\x05\x79\xec\x1a\xbe\xa0\x8e\x1e\x46\xbb\x2e\xa5\x7d\xe3\x47\xa6\x00\x7c\xf8\x8a\x0b\x3f\x7f\x8e\x35\xac\xcd\xe6\x4f\x21\x61\xbe\x41\x75\xab\xda\xf5\x82\xf0\xc4\x23\x74\xdf\x5a\xf0\xd4\x8e\x00\x7b\x74\x00\xd0\x84\xcd\xd8\xe6\xaa\x87\xbd\x34\x16\xda\xf0\xf6\x05\x30\x5d\xc4\x22\x6b\xe4\x6a\x28\x0c\xb3\x9e\x7e\x99\x03\x76\x92\xaa\xae\x7a\x5a\x03\x56\x92\x26\x9d\x01\xc0\x89\x7e\x58\xc5\x88\xd4\xc3\x2d\xb1\x8a\xc7\x1d\x55\x77\xb8\xcf\x51\xda\xc0\x26\xce\xbc\xc4\xff\x3b\x9d\x30\x07\x52\xe7\xe4\x5b\x5f\x09\x50\xd1\xcd\x5a\x1c\x60\xd6\x73\xdb\x4f\x51\xef\xcf\x4d\x7b\xfa\x8a\x0d\x09\xb0\x86\x3d\x13\xa4\xef\x9f\x90\x3b\x0b\x48\x05\x1a\xf7\xf2\x13\xc1\x23\x5c\x96\xa8\xed\x5a\xc1\x42\x69\x70\xd4\x23\x01\x99\xf5\x2a\xb2\x5e\x5a\xa2\xe7\x56\x01\xb6\x57\xc7\x65\x87\xd4\x3a\x16\xe9\xc9\xb0\xc7\x14\xf1\x10\xe4\xcb\x46\xb2\x77\x92\x2e\x2a\x46\x35\x2f\x54\xd0\x61\x18\x8e\x96\xf1\xd3\xb8\x79\xf0\xbe\x96\x30\x1c\xce\xff\x29\x86\xac\x31\x4a\x01\x2e\x72\x86\x5b\xf0\x44\x81\x75\xfb\x89\x5d\x55\x40\x92\xb9\xd0\x31\x38\x42\x7c\x00\x03\x5a\x42\x97\xb3\x8e\xff\xc6\xe0\x6a\xaf\xe3\x9b\x6a\xe5\x63\xcc\xdd\x50\x12\x5b\x88\xd9\x5c\xc7\xdc\xea\xa8\x4e\x04\x7b\x4c\x91\xf4\x07\xc4\x60\x4f\x95\x83\x2c\x13\x61\x2c\x83\x0d\x21\x54\xb6\x0e\x52\x9f\x5d\x9f\xcf\x27\x75\xd9\x8f\x1c\x62\x06\xba\xdc\xd9\x9d\x33\x43\xeb\x40\x58\x13\xc6\x85\x07\x6c\xe7\x9b\x09\x1f\x6e\x35\xe7\xfb\x54\x6b\x62\x99\x08\xdb\x0d\xd2\x12\xd0\x66\x53\x09\x79\x15\x63\xa5\xcb\xcb\x8c\x2b\xa9\xdf\x55\x08\x01\xde\x95\x8c\xec\xc7\x79\xd1\x45\xd8\x45\x8c\x09\x0e\x59\x38\x71\x85\x21\x5f\x72\x4f\xf9\x35\xcd\x12\x4b\x98\x32\x2c\xfb\xbf\x54\x14\x46\x97\x5d\xd4\xab\x10\xd7\xf1\xfd\xe5\xef\x8f\xf2\xeb\x81\x2a\xd9\x1f\xa1\xfc\x1e\xd5\x49\x6f\xc5\xf2\x96\x2b\xc1\x73\xfe\x8f\x70\x4a\x21\x0f\xff\x64\x91\x06\x61\xc7\x97\xcf\xc3\x09\xfa\xc2\xa1\x4c\x5c\x90\xa5\x50\xbc\x7f\x09\x12\xdb\x0e\x24\x36\x9e\x08\x6b\x77\x65\x93\x6d\x0f\xfc\xda\xb8\xed\x64\xf5\x1a\xf3\x23\xdf\xeb\xff\x06\x45\x44\x75\x5a\x1f\xea\x9e\xcb\xfe\x3a\xcc\x69\xc6\xd0\x4e\x38\x84\x75\x91\xbd\x40\x49\xaf\x0f\x6f\xf2\x45\x52\xe3\x55\x3a\xc1\xef\xf0\xc5\x86\x9e\x60\x07\x2c\x05\xc6\xec\x1e\xbc\x0b\x4a\x66\x8c\x8f\x6a\x9a\x5c\xca\x7f\xe5\x13\x1e\x04\x91\xf0\x6a\x2d\x82\x8b\x2d\x70\x0c\xf6\xad\x25\xf2\x5e\xad\xf3\x46\x0b\x61\x7e\x77\xd6\x72\xbc\x89\x66\xc0\x8b\x25\xa5\x9a\x32\x2f\x2e\x7a\xfa\xa0\x5e\x7d\xe8\x39\xa4\x2a\x8a\xef\xbc\x0c\x7e\x01\x78\xac\x61\x95\x2c\xe7\x64\x97\x6c\x00\xf9\x3a\xc7\xa7\x25\x0d\x1b\x8b\x0d\xe7\x84\xaf\xbc\x92\xe5\x0f\x8e\x9f\xb0\x74\xc9\x71\x1a\x96\xbe\x26\x3a\x41\xb8\x50\x9b\x2c\xdd\xe6\x72\xfc\x25\x05\xd6\x35\x3d\x6f\xb7\x20\x78\x28\x50\x9a\x1e\x9a\xd8\x74\x5d\xfe\x52\x6f\xb6\x06\xed\x95\xcb\x16\x0a\x6a\x20\x69\xea\x27\x75\xf0\xea\x83\xd8\x15\xad\x59\xcc\x76\x19\xb4\x4f\xb4\xcb\xb9\xa2\xe0\xe7\x32\x38\xe7\x65\x2e\x9d\x50\x2e\x9d\x65\x11\x0e\x0a\x81\xd4\xba\x66\xc1\x3e\x05\x64\xb6\x20\x51\xb3\xc8\x7d\xad\x09\xb7\xc8\xa4\xb4\xe2\x4b\x0b\xa2\xea\xec\x97\xaa\x7e\x0e\xd1\x07\x45\x59\x44\xd1\x39\x7b\x61\x8e\xfb\x30\x4c\x9c\x84\xb8\xd8\x05\xaf\x23\xd1\x4c\x39\x94\x2e\xfc\x5e\x35\x0c\x49\x07\x22\xf6\xfd\x50\xf0\xe1\x82\x7b\x31\xc1\x66\x92\x82\xa8\x5a\x10\xa8\x12\xa9\x52\xee\xba\xfb\x0a\xfc\x78\x01\x5e\xa0\xe8\x12\xf0\x98\x90\xdb\x03\x87\x2d\xcc\xb0\x51\x37\x2f\x4d\x52\x98\xda\x38\x20\x9f\xef\x1c\xda\xfe\x04\xe1\x24\x57\xa7\x6a\xd5\xb3\xcd\xa9\xab\x35\x95\xe9\x0a\x88\xb9\xf5\xdf\x3e\xc7\x70\x59\x7e\x87\x9c\x08\x1a\xe3\xa1\x80\x33\x85\x1c\x2e\x08\x44\xd4\x4f\x28\xd6\x09\x10\xe2\xf2\x0e\x9d\xfe\xd1\x0b\x45\x94\x80\x10\x38\x66\x72\x57\x0e\x79\x52\x6b\x1f\x62\x46\x2d\x6a\x7c\xfc\xb8\x0c\x89\x37\x56\x33\xfd\x71\x0f\x0d\x09\x8a\x44\x08\x28\x13\xc0\x41\xcb\x30\xdf\x89\x48\x19\x51\x47\xb1\x6e\xa8\x51\xdd\x3d\xf8\x26\x81\x4e\x26\x8d\xd6\x96\x1f\x5e\x55\x52\x29\xc0\x77\xaf\x73\xfb\xf3\x6f\xb4\xe0\xf8\xfb\x50\xb6\xf0\x45\xdb\x99\x97\x25\x1a\x6e\x15\xa0\x2e\xc1\xb2\x06\x21\x83\x60\xfc\xf2\xf3\xe6\xbe\x99\x38\x34\xeb\x0e\x7f\x5d\x8c\xc2\x3a\x18\x01\x6d\x16\xdf\xa6\xbf\x93\x6a\xff\x57\x58\x83\xff\xc2\x9f\xc6\xef\xd3\x5f\x20\xac\xb4\x93\xc3\xc4\xef\x28\x45\xd3\xdf\xb1\x42\x17\x7e\xb3\x25\xb2\x9c\x35\x58\x88\x2c\xc8\x81\x36\xf9\xf9\xdc\x34\x8c\xfd\xa6\xb9\x46\xed\xff\x96\xe2\x13\x61\xac\x45\xec\xbc\x61\x7e\x93\xcf\x3d\xa1\x67\x2d\x03\x80\x9d\x5a\x0c\xdb\x76\x63\x68\x6d\x48\xfb\x9f\xd4\x1c\x3c\x17\xf7\xaa\x23\xdb\x96\x08\xcf\x2c\x29\x0a\x1c\x73\x4b\x5e\xcb\x15\x20\xc8\x1a\x6e\xb9\x2d\x51\x50\x8b\x2b\x58\xc2\x62\x2a\x52\x3c\x27\xf7\x42\x16\xce\x07\xfa\x12\x59\xd8\x99\xee\x9c\x7a\xa1\x6d\xba\x8c\xf4\xa1\xa9\x5f\x27\xc6\xae\x60\x3b\x6d\x19\x42\xe9\x75\x5c\xbe\xf4\x31\x50\x04\x0d\x8c\x8e\x0b\x47\x48\x44\xd8\xa1\x36\x6f\xd5\xb7\xbd\x81\x99\x1c\xdf\x3f\xdf\x9e\x2d\x7c\xd5\xa6\x11\xbe\x8c\x04\x29\x7f\x75\xdb\x8e\xf6\x09\x8d\xb7\x91\x26\x46\xc3\x35\x13\x90\x22\x93\xeb\x73\xd3\xd4\x64\x38\x41\x39\x71\x30\xcb\x09\x37\x60\x0f\xe8\xd2\x30\x58\xe6\x43\x6f\x00\x40\x73\x78\x34\xba\xd6\x2d\x75\xcc\xe2\x06\x0e\x36\xe0\x87\xd3\xf5\x7c\xc0\x92\x1e\x05\x4a\xc0\xbe\x12\xff\x71\x28\xbd\x3a\xef\xa1\x04\x85\x73\xa8\xae\xbe\x00\x0d\xcd\x36\x1c\x9e\x1e\xdb\x87\x6f\x94\x99\x1c\xc6\x4e\x2a\x11\xb7\xc7\x9a\x4d\x0b\x56\x88\xce\x20\x74\xed\x06\x3f\xd0\xc9\x7e\x7a\x92\x86\x58\x3d\x09\x7b\x6f\xfe\x01\x01\xbc\xe1\x21\x2f\x96\x7b\x86\x44\x8c\x31\xb0\x3a\x3e\x1c\x32\x96\x97\x36\x13\xa8\x88\xfc\x0f\xe9\x37\x5a\x5f\xf4\x30\xfa\x11\x60\x86\xef\xda\xea\x40\xeb\x16\x05\x0e\xca\x7d\x54\x95\x89\x00\xdd\x24\x9a\x26\xf7\x50\x4a\xb6\x4e\xce\x7f\xdf\x7e\xfc\xfb\x63\x4a\xd9\x43\xad\xcf\x75\x75\xfa\xb1\x1a\x75\xf6\x10\x47\x93\x2e\xc4\x5e\x3d\x09\xc4\x03\x73\x89\x88\xea\x58\x30\x25\xc9\xcc\xf7\x69\xdc\x3e\x17\xdf\x23\x8c\xe1\xd3\xd7\xa2\x85\x11\x21\x59\xcc\xb1\x2f\xe7\x0c\xbd\x17\x42\x68\x60\x07\xae\x0a\x9d\xb8\x5f\xd1\xc8\x45\x30\x1a\x77\x66\x0b\xad\x05\x00\x31\xb8\xad\xb7\xe3\x53\xfe\x2a\xc0\xd4\xa8\x72\xca\xd0\x03\x1b\x51\x7a\x02\x66\xce\x7f\xbe\x29\x42\x26\x3e\xbd\x83\xa5\xa4\x44\x66\xf9\xe6\x69\xf3\xb9\x5f\x2d\x0a\x3d\xe1\x68\xc6\x03\x39\xdf\xe6\x4e\x64\x26\x15\xb8\xe3\x7a\x57\x02\xd9\xb4\x82\xbf\xdc\x12\xbd\x4f\xa8\x35\x00\x92\xca\x83\x73\x77\x83\xd7\x9f\xe9\xb8\x25\x7d\x9e\x69\x6b\x74\x91\x68\x17\x2e\xe7\x70\x7e\x39\xd7\x35\x1e\x5f\x32\x13\x16\xe7\xab\x1f\xaa\x49\x78\xdd\xf9\x8f\xac\xb7\xdd\xe3\xa4\x2e\x12\x29\xb2\x88\x10\x90\xe7\x13\x3f\xc2\x26\xec\x36\xe1\x27\xf7\x23\x3b\xe9\x9f\x1f\xb7\x30\x81\x7e\x10\xf4\x42\x3c\x8c\xa3\x63\x63\x3c\x07\xa4\xcf\x9f\x6d\x88\xa5\x6f\xb1\x0f\xa5\xb5\x88\x29\x3c\x9a\x6d\x66\x99\x6e\x74\x01\x6e\xa8\xc0\xbc\x34\x2e\x27\xb4\xdf\x5e\x06\x90\x23\x64\xd5\x25\xd0\x2f\xf7\xfb\xb8\x43\xbe\xe4\x4f\x21\x29\xf8\x92\x3d\xa9\x90\xea\x76\x24\x4f\x6b\xfd\xab\x2f\xf6\x0a\xb6\xc6\x31\xdb\x57\x38\x1e\xc0\xc6\xd8\x38\x48\x98\x48\xe8\x24\x76\x9b\xa5\x5d\xb1\x6e\xdc\x6d\x51\x15\x73\xe2\x9c\xfb\x04\xaa\x21\x7c\xcb\x34\x3d\x93\x6c\x08\xde\xf2\x15\x70\x44\x4b\x48\x4a\x40\x08\xeb\x88\xa8\xfd\xde\x7d\xbb\x1c\xf8\x65\x0e\x9f\x83\xb5\xdc\xfe\xe2\x6e\x50\x55\x5b\x18\x7d\x96\x2f\xb5\x8a\x3d\x34\x8d\xe2\x73\x7c\xdd\x4a\xe7\x50\x75\xab\xa9\x70\x21\x68\xc9\xbb\xdc\x66\x05\xe3\xed\x26\x7e\x10\x8e\xce\x3f\x14\xcb\x7d\x22\x32\xf9\xea\x5f\x7b\x1b\x06\xb8\xa1\x7c\x40\x53\x26\x99\x0a\xf0\xd9\xed\xc2\x9c\x2d\xbc\x06\xf8\x8b\x84\x1f\x3a\x8c\xd9\x02\xe7\x32\x47\x56\x0c\xc1\x40\x00\x7e\xf4\xbd\x4d\x33\xc6\x29\xa4\x63\x90\xc2\x46\x22\x40\xa5\x73\x86\xb6\x60\x2e\xcb\x8b\x0b\x6a\xed\x5f\xb6\x19\xf9\x6e\xf3\x2d\x9b\x1b\xf8\x8e\x0b\x0b\x51\xf4\x4b\x68\x2f\x10\x2d\x56\xfe\x38\xed\x79\x34\x7a\x7c\xed\x71\x74\x9c\xc3\x39\xad\xa1\xbd\xef\x68\x72\xc1\x5f\xd6\x70\x30\x07\x3d\x6f\x67\x28\xb2\x03\x23\x79\x95\x9f\x39\xd0\x31\x62\x54\x5a\x70\x46\x09\xae\x75\x8b\x68\x06\x94\xe7\x18\xbf\x2a\xf9\x2e\xd2\x41\xab\x01\x48\xb9\x05\xce\xe4\x13\xdd\x03\x4a\x7c\x92\xa2\xa8\xb4\xf4\x56\x00\x8f\xb2\xbd\x42\x5a\x03\xe6\x3a\x2e\x16\xe2\xd8\x98\xfd\x46\xc7\x3b\xce\xe5\x16\xc5\xb3\x26\x84\x40\xf4\x2e\x80\x5c\x42\xba\x63\x71\xf3\x43\x09\x1a\x84\x76\xc6\x97\xb9\x39\xe0\xbc\xd1\x37\xb7\x45\x32\x1c\x13\x3d\x60\x5b\xa8\x9f\x09\xa6\x52\x97\x8c\xdc\x64\x40\xe2\x19\xee\x49\xee\x03\x37\xe0\x2b\x0d\xcb\x6c\x50\xb5\x08\xa8\xa0\xbf\x57\x60\xae\x76\x54\x3d\x1e\x40\xe1\x60\x72\xb6\x03\x46\x26\x19\x99\xd7\x11\x0d\xd7\x58\x62\x29\x80\xb8\xa4\xe5\x2f\xf3\x08\xd5\x22\x1c\xb5\xe2\xd6\x66\x6a\x25\x2a\xf5\x43\x0a\x7c\xd9\x99\x62\xb7\xde\x47\x65\x45\xd5\xcd\x03\x86\x86\x47\x38\x86\xd8\x0c\x18\x6c\x68\xe9\xa6\xe4\x0c\xf8\x6b\x9b\xde\x15\xfa\x63\x1d\xf5\x7a\x4e\xc4\x89\xec\x7b\xe4\xd7\x10\xc1\xa8\x16\x0d\x09\x9e\xca\x7d\x4f\x63\xf4\xa4\x4a\x2a\xf0\x2a\x5f\x96\xf9\x29\x94\x7d\xa1\x75\x21\x8a\x3e\xc2\x2a\xc2\x6f\x1d\x16\x12\x9a\x50\xdb\x98\xc6\x86\x27\x8e\x04\xed\x08\xf0\x8a\x0d\x0f\xfe\x2b\xc1\xb3\x40\x30\x95\x63\x0a\x59\x8c\xfd\x6a\x0a\xa1\x1b\x67\xcc\x72\xa8\x8a\xa1\x23\x65\xa6\x66\x41\x27\x21\xff\x73\x12\xa7\xc1\xa2\x3e\x51\x40\x1f\xf8\x15\xbd\x79\x3b\xb5\x2d\x1f\x48\x72\x33\xb4\x2c\x41\xf2\x15\x88\x17\x29\xb5\x7b\x3b\x4b\x0a\x17\xe8\x95\x57\x30\x90\xed\xda\x9e\x42\x5c\xa0\x8a\xd8\xc4\x55\x6b\xca\xa5\x4a\x5b\x53\x8e\xb4\xa8\xc3\x6e\xca\xa2\x8b\xd3\xc4\x1a\x01\x2c\x11\xc4\x91\x03\x03\xd7\x37\x63\xd5\xda\x70\xe5\x8c\x12\x2f\xa3\x41\xa1\x6d\xd7\xce\xd8\x19\x28\x8d\x75\x93\x04\x49\x6c\x50\xe7\xac\x19\xed\xa3\x6e\x57\xfc\x06\xc2\x40\xd8\x0e\x69\xf6\x3c\xbb\xc9\xd6\x3f\xe5\x21\x53\x39\x43\x57\xbc\x8a\x76\xe4\x29\x48\x88\x0d\xca\x14\x0f\x2a\x65\x84\x4b\xfa\x87\xe0\x94\x2f\x9f\x09\x79\xe1\x37\x60\x57\x8e\x3a\xde\xd2\x45\xd9\x7e\x3a\x00\xc6\x13\xbb\x1b\x0f\xd3\x0a\x41\x08\x3d\x8d\x80\x2a\xc2\x09\xbf\xba\xb2\x8b\x83\xe6\x22\x19\xb4\x7d\x48\xe1\xf9\x60\x6f\x5d\x90\xa8\xe9\x4d\xed\x6b\x20\x60\x34\xfd\x1d\x6e\xfa\x91\xfe\x51\x13\xe2\xdc\xdb\xe1\x33\x1e\x00\x18\x27\x0a\x56\x5c\xbb\x80\x13\x58\xa7\xdd\x5b\x41\x39\xb6\x9e\x64\x9b\x10\x70\xb0\xb6\x56\xa0\x6d\xf6\xc2\xfb\x09\x12\x62\x5b\x3e\x28\xa6\x61\x5d\x5e\x22\xe8\xc2\x45\x31\xb0\xb8\xeb\x69\x93\xfb\xa6\x07\x6b\xcf\x2e\xbc\x8d\xed\xa3\xec\x15\xfe\x55\x44\x19\xb4\x31\xfa\x52\x39\x3a\x69\x29\x50\x85\xa0\xb0\x44\x2c\x3b\xda\x4c\xa7\x50\x01\x64\xc9\x6d\x27\xe1\xa3\xb4\xe8\xaf\xb4\x34\xa7\xb8\x4d\x0a\x60\x93\x25\x4c\x19\x72\x9d\x47\x02\x35\x94\xc3\x8a\xa1\x30\xed\x02\x06\xd4\xad\xdd\xa7\x6a\xa4\x4a\xf5\x74\x7f\x73\x48\x8f\xd8\xdd\xaf\x29\x6a\x7a\x3a\x44\x2c\xcc\xd3\xa5\x7b\x21\xbf\x74\x49\x5f\x14\x17\x97\x49\x1d\x88\x23\x21\xc3\x61\x43\x48\xe3\xbf\xbf\x7b\xa6\xcf\xa5\xab\x78\x99\x16\xbd\x51\x95\x39\x74\x2b\x87\x26\x62\x61\xbe\x2c\xd8\x2a\x22\xa9\xea\x65\xe8\x8f\x4a\x1f\xfb\xf7\xa0\x74\x86\xdd\x40\xf8\xd7\xf7\xbd\x34\x34\xce\x17\x27\xa2\x7f\x45\xb4\x82\x3f\xfc\x2e\xd8\xc2\xd4\xcf\x57\xfe\xaf\x33\x64\x7b\x2f\x98\x34\x62\xfb\x33\xd0\x58\xed\x73\xf9\xb5\xf9\x6c\xb1\x10\xf1\x01\xc8\x49\x68\x13\x76\xad\xb7\x35\x44\x14\xc7\x2c\x7c\xfa\xc6\xbe\xc0\xd9\x58\x1f\x17\xc0\x64\x30\xb8\x37\x8b\x3e\x61\x74\xc8\x66\x2b\x91\x0d\x94\x81\xe6\x1d\x93\x3b\x36\x03\x25\xf6\x41\xba\x7f\x45\x10\x6f\xcd\x14\xce\x18\x28\xae\xc9\x4c\xef\xc3\xf3\x79\xd0\x12\x82\x32\x96\x88\x76\xbb\x2d\xb5\x6a\x8b\xa6\x8d\x16\x33\x0a\x43\x93\x2f\x3d\x7c\x20\x4a\xe0\x7c\x01\x8b\xba\xf0\x91\xa8\x65\x18\x78\x88\xc7\x97\xa6\x7f\xc4\xcb\x84\x05\x8f\xa5\x9a\xf4\xc0\x48\xdb\x50\x08\x9b\xd9\x9e\x69\x93\x66\xc7\x8a\x7b\xd9\x23\xeb\xfc\xc3\x4c\x42\x1a\x1f\x1d\x51\x88\x1f\xbb\x61\x1f\x40\xcd\x6c\x4c\x5a\xdf\xa5\x0f\xb3\xc9\xb7\x65\x22\x44\x66\xd8\xe4\x9c\x88\x17\xeb\xdd\xce\x56\x6e\xf0\xdb\xe8\x2a\x93\x88\x33\x9d\xe3\xf3\x41\x3d\x14\xbf\x15\xdb\xea\x24\xb1\x05\x88\x40\xfa\x1e\x01\x95\x09\x21\x47\x7f\x8b\x9d\x73\xcb\x55\x92\x77\x68\x03\xbe\x41\x87\x9b\xa4\x25\x45\xc3\x89\x1c\x18\x9a\x12\xdb\x78\xcf\xa4\x57\x5a\xf2\x4f\xf8\x16\xae\xe0\x08\xbd\x22\x59\x22\xf7\xa5\x77\x40\x4d\xdc\x38\xe7\xfa\x22\x38\x95\xe2\x73\x01\x40\xf3\x3c\x39\x3c\x25\xf6\x9c\xc2\xae\xc2\x29\xb5\x8a\x87\xb1\xaa\x7d\xa8\x9f\x3b\x17\x58\xdd\x59\xbf\x11\x92\x21\x58\xa6\x7d\x57\x37\xcc\x13\xc6\x97\xc7\xa0\xf7\xf8\x88\x75\xbb\xca\x2f\xe3\x1c\x3d\x91\xb5\x3a\x98\x7c\x49\x92\x44\x58\xaa\xe3\x42\xff\xb2\xe1\x5c\x0f\xbb\x75\x89\xcc\x38\x99\x85\x1e\x27\xfc\x91\x3c\xc0\x93\xec\x01\xd7\x5b\x8e\x33\xe0\x22\x7b\xa2\x03\xfc\x76\x2a\xc7\x97\x79\x45\xb5\xcb\x73\x43\x0c\x17\xad\x80\x7b\x85\x50\x37\x40\xab\x10\x34\x33\x06\x58\x04\x72\xe8\x21\x1f\xf2\x62\x09\xc2\x11\x36\x7b\xfe\xc7\xa4\x91\xe0\x9b\x3a\x67\xf4\xe6\xb3\x0a\xb4\x61\x4d\x4f\xd4\x6e\x07\xd5\xd8\x90\x2f\xdb\xe2\x70\x4a\x3a\xa8\x80\x74\xb8\x30\x1a\x0f\x1c\x8f\x50\x37\xa1\x8f\xcb\x11\xdc\xf1\x63\xa4\x15\xac\x6b\x3a\x13\xf1\x7d\x7c\xd5\x33\xe5\x84\x51\x91\x31\x1b\x0d\x63\xdd\x12\xa3\xe5\x05\x1a\xc6\xfd\x87\x87\xe6\x10\x1e\x43\xb9\x3d\xc1\x50\x38\x30\x34\x85\x0e\x8e\x87\x3d\xa1\x1d\x51\x9a\x87\x25\xbb\x7e\x68\x5e\x54\x53\x03\xf8\x4a\x2a\x25\x4b\xf8\x52\x00\x2f\x73\x0c\xf2\xc6\x9f\x32\x68\xe5\xd2\xb4\x73\x3f\x8d\xd1\xdd\xb8\x1e\xc4\xd2\xac\x45\xc7\xd1\x1f\x9f\x61\xeb\x3d\xc3\x81\x0c\x85\x7f\x4f\x52\x5f\x76\xb8\x56\xa9\x50\x46\x36\xf0\xbd\xa4\x7b\xe2\x4c\x5a\xdb\x8e\xa5\x0d\x25\x94\x0f\x5d\xa4\x31\xe1\x71\x20\x9d\xbb\x53\x71\xcf\xa4\x9f\x04\x13\x3e\xee\xa1\xdb\x7f\x58\xb0\xdf\x5a\x28\xbe\x7e\xff\x09\x2f\x04\xeb\x0a\x7d\x93\x02\x31\xf1\x49\x2a\x26\xc1\x96\xe3\x96\x8b\xb9\x4d\x3a\xf4\xda\x6d\x69\xbc\x9f\x21\x7e\x61\x41\xda\x02\x91\x33\xbb\x14\x99\x87\xd3\x21\x4b\x8e\xe9\x49\xdd\x08\x4a\x7a\xed\x67\xe3\xf2\xff\x6f\x41\x78\xce\x8d\xd0\x28\xb7\xf5\x48\x4b\xf5\xe5\xbf\xb6\x02\xf9\x4e\xc6\x15\x43\x02\x8f\x7e\x05\x45\x10\xa4\x63\xe3\x80\xe9\x29\xb8\xb4\x4c\xa8\x95\x42\x68\xc8\x51\x6c\xd2\x2f\x80\x8b\x3b\x73\x74\xe1\xf6\xe8\x65\x97\xe8\xa4\x6a\x83\x71\x9a\x04\x15\x82\xdb\x0f\x5f\xb7\x07\x2d\x7c\xe7\x0f\x2f\x29\xd3\xa8\x43\x01\xef\x04\x44\x8d\xb4\x4b\x56\x57\x8a\x12\x1c\x08\xc8\x00\x2c\x34\x30\x9d\xf0\x55\x3e\xff\x24\x40\x7c\x0f\xca\x69\xb8\x70\x8a\x1e\x2d\x37\xf3\xa8\x3a\x19\x6e\xe4\x1f\x78\x1b\x28\xc3\x6e\xa3\x97\x9d\xf7\x12\x36\x11\x65\xbb\x57\x61\x30\x03\xb0\xe9\x89\x9f\x43\x01\xcc\xa0\xfe\x26\xc5\x39\x93\x1e\x3d\xe9\x7d\x61\x5b\xdd\x85\x34\x02\x89\x8f\xc3\x97\x4b\x46\xc5\xc1\x42\xda\xbf\xa4\xaa\xa9\x67\xf1\x76\xef\xe6\x4a\x98\x05\x6d\x45\x00\x5d\xf6\xe0\xf1\x9e\x02\x18\xc8\x83\x29\x6c\x62\x9d\xda\xb8\x4b\x57\xe5\xd6\x33\x77\x68\x50\x05\x06\xa5\xbf\x2c\x19\x91\x49\x52\x0a\x16\x50\x07\x57\x87\xbf\x2e\x4e\x9d\xf7\xd7\xd8\x09\xc0\xf3\xaa\x9e\x22\x6f\x97\x4d\x73\x8c\x75\xa2\xf3\xd6\x3e\x56\x9e\x8b\x85\x2d\xf1\xf5\x3b\x32\x28\x5e\x37\xe8\xaf\xfa\x76\xaa\x6e\x78\x3b\xd7\xae\x19\x76\x59\x5a\x3c\x63\xdb\xea\x4b\xf8\xb9\xc3\x15\x3a\x3f\x83\x16\x2a\xf7\x61\x3b\x25\x57\x0a\xb4\x51\xd6\xbe\x2c\x61\x5a\xe0\x7e\xf9\xa1\x43\x39\xa7\xee\x27\x3d\x84\x44\xca\x4b\x44\x2d\xd3\x62\xaf\x72\xc5\xb0\x06\xa4\x5d\x5c\x5f\x70\x41\x05\x72\xb2\x21\x29\x8c\x5b\x86\x14\x9f\x8b\xc5\x4f\x7e\x95\x73\x2a\x22\x5e\x85\x5f\x1b\x50\xa9\xf6\xd3\xcb\xff\x42\x46\xc8\xad\x0d\xc3\x60\x26\xaf\x9c\x95\xc3\x15\x45\xf2\x49\x79\x42\xd5\x73\x8f\x4b\x93\x89\xcd\xab\x76\xf4\x36\xce\x36\xee\x1d\xb8\x4b\x52\xcb\xad\x4f\x44\x02\x45\x1c\x48\xac\xb6\x6a\x14\xb5\x5a\xcc\x84\x3c\x4d\xfc\x09\x40\x6b\x84\x76\x10\x3a\xd9\xe3\x8f\x9d\x96\xdd\x78\xea\x71\x6c\x40\x0e\xbc\xd2\x15\x1d\x03\xb3\xf7\x1d\x53\xef\x99\x2a\x36\x0b\xef\xf0\xb4\xbc\x12\xed\x87\xa2\xfe\xb0\x27\xe7\x06\xb3\xce\x62\x93\xbb\x30\xe0\xb1\x19\x89\xcc\x57\xa6\x3f\xcd\x23\x21\x60\xf3\x11\x67\x12\x9a\x23\xfc\x9c\x09\x4e\xa4\x1b\xa9\xbb\x7b\x7a\x9d\x53\xe1\x77\x3f\xab\xa3\xed\x9e\x42\xad\x25\x8c\xd9\xad\xdf\x12\x1c\xea\x5c\x04\x96\xfa\xc2\xca\x28\xf6\x70\xfc\x7d\x67\xa2\xa1\xfe\xa9\xe8\x75\xd3\x61\x5d\xdc\x95\x1f\x0c\xea\x0e\x47\x2e\xd7\x51\xfe\xaf\xcb\x8a\xef\xce\xef\xb1\xaa\xd9\x1c\x20\xcc\x56\x0c\x53\xd9\x02\x57\xb4\xe4\x3e\xf6\x7e\x7b\xac\x83\xcd\x50\x75\x62\x26\x27\xc2\x56\xd4\x10\x5d\x45\xf9\xf6\xe9\x16\x73\x80\x56\x8d\x6b\x31\xf3\x15\x00\xf2\xf4\x51\x3d\xa0\x3b\x47\x80\x9d\xfa\xea\x23\x00\xa9\xe5\x49\x3a\x39\x4f\xac\x3b\xb5\xf1\x8e\x90\x0e\x01\xa6\xa9\x0d\x38\xd3\x96\xeb\xfb\x54\x9c\x7a\xdc\x88\xa6\x25\x3c\x60\xda\x54\x55\x69\x54\xd6\x46\xf5\x5f\x7d\xd6\x86\x59\xbb\x5e\xa5\xbc\x95\xdc\xcd\x5d\x9b\xc6\xbb\x12\x40\x90\xf8\xe5\x90\x4a\xf7\xe1\x04\x56\xda\x01\x10\xaa\xa5\x6e\xe2\x81\x76\xc9\xa9\x60\xb9\x05\x73\x26\x41\x8a\x96\x73\x69\xc7\x2f\xd1\x19\xfa\x32\xc8\x93\x05\x4c\xe0\xc0\x1e\xd9\xd5\x12\x6d\x01\x62\x34\x98\xcc\x3d\x28\x47\xd3\x8e\xab\x70\x2e\x9b\xc0\xdc\x36\x2c\x7f\xfb\xde\xac\x71\xcd\x02\x52\x64\x1f\x15\xc7\x25\xc1\xe9\x57\x71\x44\x28\x4d\x43\x4b\x13\x48\x5c\xb6\xc2\xfa\x54\x5b\x0d\x00\x8c\xae\xc4\x8c\x76\x2d\xd5\x64\xca\xc3\x4a\x39\x06\x2a\xa2\xf5\x1c\x34\xac\x58\xf6\x88\xf5\x87\x6b\x4c\x5b\x0b\x68\x8f\x04\x6f\x15\x4b\x07\x08\xf3\x81\xd2\x97\x16\x12\x56\x14\x0a\x03\xb5\x74\xf6\x35\xcc\x39\x27\xf9\xb3\x20\xf0\xeb\x35\x55\xa5\xb1\x15\xe3\x1b\x91\x49\x21\x55\x05\x6a\x60\xab\x67\x68\x1d\xa0\x58\xba\xf3\x54\x87\x52\x7c\xa2\xe8\xb0\x51\xc9\xd1\xdc\x8b\x2c\xd0\x2d\x08\x73\xf8\x15\x17\x51\xc2\xc8\x2e\x6f\xb3\x56\xe0\x18\x4a\x17\xf2\x6c\x84\xb6\x99\xef\x4b\xc7\x3d\x9f\x82\x4e\xcd\xe8\x62\x7a\x42\x6e\x61\x98\xa9\xc2\x35\x69\xba\x7c\x2e\xb1\x12\xb0\x12\x07\xb4\xc3\x29\x4b\x1e\xbb\x2d\x1d\x14\xef\xb0\xaa\xa4\x1f\x22\xc9\xbc\x69\x4d\x76\xe7\xd3\xa4\xe5\x1f\xca\x3d\xb4\x5e\xf9\xc8\xa3\x88\x88\x22\xbf\xe3\x11\x42\x62\x7e\x51\xdc\x71\x31\x0b\x21\xea\xcf\xbc\x27\xbc\x85\x22\xee\xb2\x7f\x23\x94\xda\x50\xc8\x84\xec\xa8\xcd\xa7\xf9\x67\x01\x7d\x92\xa4\x9b\x43\x47\x96\x7c\x87\x71\x53\x7f\x01\xaf\x5d\xfd\x46\x9f\x03\xb1\xbd\x1c\xce\x3c\xc5\xee\x3f\xf6\x79\x6e\xde\xc7\xc2\x41\x59\xda\x28\x76\xab\x6c\x55\x66\xaf\xd0\xc1\x93\xc8\x9b\x2f\x0d\xf6\x96\x8f\xe2\x21\x78\x48\x3a\x47\x10\xc9\xd2\xec\xb7\xd9\x4b\x71\x9c\xcf\xe9\x37\xf9\x72\xda\x3d\x21\x8f\x17\xfb\x0d\x13\x51\x49\xcb\x90\xdd\xbc\x03\x58\x19\xc9\xd5\xa0\x84\xee\xe9\x32\x88\x6e\xab\x14\x70\x8e\xdb\xe2\xc5\xfe\x32\xc7\x04\x41\xe0\xc6\x86\xdd\x36\x33\x23\x5f\xc6\xd7\x48\x24\x10\xba\xdb\x39\xdc\x71\xbd\x05\x91\x29\x8f\x31\xf5\x73\xb9\x1c\xd7\xc2\xf1\x9f\x54\x0e\x30\xe7\x26\x18\xd1\xfb\x52\xf0\x45\xf5\x58\x00\x61\x3b\x1f\xd4\xc1\xd9\xa1\xda\x45\xac\x92\xd4\x0c\x30\x95\x22\x98\xe6\xb4\xdf\x57\xc4\xcb\x19\x80\x8d\x97\x14\x5a\x20\x82\xb3\x4e\x21\x90\x03\xd7\x18\xcc\x61\x08\xd0\x39\x27\x30\xd6\x09\x54\x9a\x08\x13\x3a\x5b\x49\xde\x00\xb9\xe4\x01\xc6\x9a\x87\xf0\x4b\x02\x21\x51\x7a\x9f\x8e\x69\x73\x68\x20\x02\x93\xe4\x97\xc3\xd2\x36\x70\x47\xc9\x3d\x9b\xdd\x99\x41\x68\x10\x6f\x34\x42\xc9\x80\x22\xeb\xdb\x99\x2c\x86\xb9\xd0\x10\x6c\x1e\xff\x79\x6a\x34\xbb\xfd\xb7\xea\xd9\xf3\xb8\xf7\x3e\x64\xa9\x11\xa6\x25\x4e\xcc\x97\x55\x0b\xe4\x20\xfc\x12\xdb\x5f\x58\xf4\x2a\x64\x8a\x24\x53\x67\x59\xa4\xf5\x91\xf2\x8e\xd9\xe7\x2a\x67\x3d\xc7\x9a\x32\xee\x32\x87\xf7\xd8\x28\x26\xb8\x15\x0c\x76\x14\x25\x42\xa0\x9a\xcf\x49\x44\x11\xba\x8c\xa4\xa4\xa0\xb6\x42\x05\xc8\x39\xf5\x57\x8d\xe6\x50\x89\x63\xb3\x65\x81\x19\xb9\x51\xf9\x0f\xe2\x88\x90\xa7\xb4\x9e\x03\x3f\x75\x39\x89\xe8\xe6\x31\x61\x06\x35\xa7\xc9\x9e\x50\x9e\x85\x25\x50\x4b\x7b\x57\x43\x20\xc3\x73\xcc\x49\x11\x01\x4a\x0e\x7f\xf7\xa8\x5d\xd2\xcc\x09\xcf\x9c\x5c\x5b\x45\xbf\x7d\xf2\xd5\x91\xa3\x02\x9d\x40\x9e\x5d\x74\x18\x8c\x61\x3d\x09\x9b\xae\xbd\x10\xb8\xf4\x2f\xcf\xb8\x69\x1d\x26\x74\x52\x72\x16\xb3\x77\xef\xdd\xdc\x12\x84\x77\xd0\x44\xeb\x38\xc7\x35\x51\x90\x77\xc2\x08\xd3\x09\xed\xd4\x4a\x84\x65\x2a\x4d\xa3\x5c\xd3\xe6\xfb\xb2\xd2\x82\xe1\xb8\xd3\xcb\x30\xdb\x26\xb8\x09\x35\x14\x09\x06\xa2\x21\xe4\xd3\xac\x1d\xd5\x97\xc1\xee\xf4\x16\x35\x02\xbb\xce\x94\xfc\x19\x73\x03\xe4\x90\x87\x1d\x8f\x68\xbc\x14\x07\x1d\x52\x02\x9c\xb2\x9d\x61\x95\x41\x23\x0a\x4a\x3c\xf5\x29\x57\x0a\x2f\x2c\x65\xb9\x88\x32\xc9\x5b\x7d\x8a\x84\xc4\xa6\x3d\xba\x76\x53\x7e\x1e\xb1\xcd\x1a\xe8\x6c\xc0\xda\x42\x3d\x62\x72\xb7\xce\x9d\xe1\x95\x28\x60\xe6\x99\x0b\x05\x81\xa6\xb4\x63\xb1\x4b\x17\xd0\xc6\x0e\x1b\x0c\x59\xe8\x9e\xa0\x9a\xb7\x2a\x62\x95\x67\x4a\x85\xed\xa5\x73\x3f\x76\x04\x4f\xfa\xc3\x4e\xf4\x29\xd7\x61\x94\x62\x98\x80\x43\x93\xac\x51\x13\xfe\x4e\xaf\xab\xf8\x43\x07\x24\x96\x1f\x05\x18\x16\xe1\x58\x12\x3a\x5a\x5c\xdb\x5c\xd7\x03\xe8\xac\xac\xe0\xb6\xfd\xf1\x3f\x0d\xfd\x8d\xbf\x61\x9c\xfc\x73\x46\xac\xa4\xc8\x3f\xf4\x05\xda\xa9\x90\x79\x98\x72\x1f\xbe\x6d\xf9\x68\xff\x9e\x28\xe7\x73\x9c\xb4\x38\x11\x6a\xe9\xca\x47\xf7\x13\x05\xf5\xa3\xe4\xdb\x97\x90\x5a\x33\x27\xd9\xbf\x18\xef\x6b\xc8\x0f\xcc\x5c\x08\xfd\x85\x55\x9a\xef\x48\x81\xd3\xe2\xc9\xff\x02\x5f\xc3\x1d\xc0\xf4\x6d\x11\xb6\x59\x87\x2d\x3d\x0d\x86\xb0\xe6\x40\xa1\x26\xcb\xe1\xbd\xfe\xf2\x9b\xc6\xc9\xcb\x7b\x0f\x62\xbd\x84\x10\x83\xec\x92\x2a\x07\xbf\x3f\x9e\x29\xda\xaf\x48\xb4\xd5\x3b\x51\x59\xc0\x1b\xce\x4b\xab\xfa\x46\xb8\x65\x81\xfa\x4a\x5b\x34\xff\xd3\xf5\xfb\x1e\x9f\x75\x08\xb8\xe5\xcd\x4e\x9f\xc4\x35\xfc\x07\xc1\x60\x50\x8c\xe3\xdf\xe1\xbe\x44\xe7\x97\xc2\x92\xf3\x5f\x08\x03\x63\xa7\x06\x38\xd8\x78\xab\x3e\x49\xb7\x45\xa7\x44\x59\x16\x7e\x6c\x7e\x3e\xf3\x0d\xf4\xd2\xb2\x97\x07\x0f\x82\xb8\x8e\xf3\x0b\xde\x35\x06\x76\x05\xcb\xab\xbc\xb9\x20\x82\xba\xed\x3c\x3a\xba\x48\x6f\x34\xb9\x95\x27\xc5\x38\xfb\x24\x8a\xd6\x42\xdc\xd3\x61\xb2\xd6\x7a\x54\xa2\x02\x63\x3f\x0d\x4d\x47\xc7\x1f\x61\x00\x21\xcc\xd4\x02\xaa\x05\xcd\x32\xb6\x07\xbf\x81\x87\xab\xdb\x60\x1a\xef\x3b\xed\xae\x0e\x29\x22\x28\x38\x11\xc9\x85\xd1\x51\xfd\xcc\x40\xb0\xbc\x6d\x46\xbe\x44\x34\x3d\x4c\x13\x88\xd5\x3a\xc3\xac\x66\x70\xc7\x63\x85\xf8\xd5\x1e\x04\x92\xe9\x3a\x0e\xd0\x02\x23\x4e\x2c\xf0\x64\x73\xa0\xcd\xe6\x2c\x57\x01\x17\xf3\x06\x56\xfa\x27\x5a\xc8\x00\x39\x89\x1a\x0a\x3b\xa3\x61\xfc\x95\x38\xf8\x90\xbd\x9b\x42\x26\x71\x68\x39\x68\x80\xdd\x9e\xd4\xa0\x36\x20\x63\x3c\x97\xb6\xe4\x77\x7d\x10\x57\x56\x73\xb1\x21\xe7\x8b\x5b\x68\x9b\x11\x82\xa6\xf5\x03\x3c\xca\x0d\xab\xda\x96\xff\xbf\xb9\x01\x82\x46\x95\x4d\x14\x05\x74\xea\x90\xa2\x0f\x25\x9e\x01\xf5\xfb\x73\xd3\x11\x0d\xef\xb6\x01\x99\x01\x67\x05\x43\x9a\xa1\x9d\xca\xab\x91\x6e\x2d\xaa\x14\xff\x79\x03\x33\x7d\x89\x66\x25\xc1\xcf\xce\x85\x14\xe6\x9e\x95\x81\xfe\x2b\xe3\x85\xaa\x53\xe0\x9c\x2d\x7e\x4a\xbf\x29\x0b\xaf\x66\x7f\x84\xa4\xfc\xa2\x29\x40\xdb\x97\x2d\x52\xa0\xd6\x02\x10\x97\xd8\x41\xf7\x98\xe4\x6a\xd0\xec\x31\xaf\xcb\xea\x9e\xfa\x52\xaf\x6b\x5f\xc0\x0e\xd6\xde\xae\x96\x06\xfb\xe9\x1e\x94\x7b\xeb\x6e\x23\x09\xea\xf3\xc5\xc4\xa4\xb7\x3f\xf1\x8a\xe5\xa6\x3e\x7f\x01\x88\xa4\x1b\x95\xe3\x0d\x12\x4c\xec\x51\x04\xe6\xec\xd0\x42\x5f\x74\xef\xd3\x1e\x7e\x4c\xee\xaf\xa4\xbf\x51\x31\xdf\x8e\x7e\x7f\xf2\x13\x4d\x53\x48\x4a\xd9\x13\x4c\xd7\x24\xad\x7b\x3f\xcf\xd7\x68\xef\xf0\x5b\xec\x0b\x66\xfe\xb4\xc9\x8f\xb3\xca\xdd\x5d\x69\xa9\x18\x39\x38\x2d\x09\x6d\xb6\xe5\xc6\x37\x49\x6c\xf9\xa7\x93\x71\x62\xc1\xe3\xb9\x55\xb5\xa9\x7f\x4d\x29\x84\xb8\x61\x29\x91\xd2\x59\x70\xc9\x24\xde\xac\xb8\x21\x4c\xc4\x4d\xb5\x82\x85\x20\x95\xf6\x8e\xe2\x66\x3e\x27\xa8\x61\x28\x24\x6e\xc4\xb6\xb9\x25\xdc\x2e\x1d\x8d\x70\x76\x36\x7f\x64\xa9\x14\xa4\x0b\x41\xea\xe4\xcd\xe4\x31\xea\x20\x4e\xd0\x60\x4b\x47\xd8\xb0\x7f\x4a\x11\xe2\xe9\x05\x0c\x59\x30\x0d\x53\x08\x0a\x03\x60\xc7\x5b\xeb\x89\xe4\x59\x68\xa6\x67\x9e\x79\x2a\xee\x42\xc8\xf7\x58\xf7\xda\x9f\x01\xb6\x9b\xa3\xb2\xf3\xb4\xf9\x1a\x13\x33\x20\x6c\xd3\xfe\x75\xb5\x08\xc4\xa3\x71\x94\x8d\xab\xcf\x2c\x04\xde\x39\xc5\xca\x50\xbe\x50\x7b\x21\xee\xee\xb8\x55\xf9\xa0\x5b\x45\x8b\x37\xc1\xe8\xfe\xad\x10\x06\x26\xf4\xed\x9f\x97\x85\x17\x02\xd5\xfe\xa9\x47\xa5\x9e\x15\x41\x73\xff\xda\x29\x34\x1b\xb2\xd6\x72\x41\x69\x6b\x2b\x7b\xcc\x21\x7c\x5c\xda\x81\x57\xd4\xc3\x5d\xa2\x2c\x3d\x5d\x59\x77\xb6\x1f\x73\x09\x1e\x75\x76\x07\x58\xa9\x5b\xfd\xef\xcc\xd5\x05\x03\xc6\x71\xfa\xbe\x75\x8c\x9a\x45\x5e\x36\x4a\x7c\x02\xdf\x00\xc1\x2e\x7f\x1b\xcd\xa5\xfc\x8f\x9c\x1b\x94\x09\x84\x57\x77\x10\x5f\xd2\xe2\x55\x34\x14\x4e\x4a\x44\xf3\x2c\xaf\x9c\x3c\x91\x29\x99\xa7\x7d\xe5\xdd\x26\x54\x9f\xb4\x69\xd9\x0a\x4d\x50\x4b\xb1\x78\xcc\x90\x7d\xd3\xf7\x5e\x1e\x45\xc8\x1e\x32\xfb\xe4\xb7\xf5\x59\x66\x16\x67\x29\x7b\x17\xe8\x37\x5e\x86\xe2\xac\x4f\x64\x81\xfa\x73\x5e\x5d\x07\x7d\xd1\x23\xb4\xb1\xe6\x06\xcc\x50\x85\x31\x09\xe8\x4e\x62\x4b\xba\x73\xdc\x45\x7d\xe9\xb6\x58\x16\xe9\x7c\xe9\x8d\x6f\xc7\x82\x8a\x43\xd6\x60\xf7\x4b\x24\x4c\xb7\xb9\x44\xba\xf0\x83\xdb\x4c\x1b\xac\x29\x96\xba\xbb\x32\xca\x95\xea\xfd\xd6\xb6\x6a\x60\x74\x44\x5e\x00\x28\x78\x26\x69\x56\xed\x5b\xf6\xe5\x83\x1b\x1e\x08\x18\xfe\x5c\xf1\x85\xe1\x08\xe3\x50\x41\x0a\x55\x0b\x18\x38\x43\xce\x25\x1a\xbd\x4b\x55\xf6\xfa\xea\xea\x9f\xa5\x77\xb6\x94\x4f\xaf\x92\x5a\xf1\x65\x0b\x47\xab\x6e\x9c\x3f\xbc\x46\x94\xce\xd2\x17\xa2\xf4\x17\x16\x5b\xdd\x2f\xc5\xb6\xe8\x60\xd5\x8d\xac\xdd\x31\xac\x30\xc4\x40\x88\x5a\x1c\xd8\xb4\x2e\xcb\x89\x1e\xf2\x5a\x98\x06\xc5\x11\xa8\xc3\x26\xe7\x28\x74\x10\xef\x4e\xff\xd1\xdd\x0a\x08\xe3\x26\x63\x86\x2e\xdf\xe8\xc2\xd5\xe5\x04\x5a\x02\x09\x9d\x4f\xa5\x43\x66\x37\x42\xd5\x50\x0c\xe6\x8b\x80\xd3\x50\x70\x57\xc9\x58\x3a\x5d\x1e\xd9\x03\xf5\x62\x60\x49\x8a\xff\x71\x0e\x67\xac\xbe\x5f\xa8\x5f\x7a\xd0\xd8\xc4\xe4\xa9\x2f\xb7\xa1\x59\x62\xa1\x5d\xfa\xe3\xe6\x88\x9e\xa8\xb3\x59\x74\x17\x8e\x60\xf3\x12\x90\xca\x34\xd5\x82\xac\x4d\x26\x2c\xc5\xdd\xd0\x05\x75\x3f\xa9\x2f\x92\x29\x3a\xdf\xea\xec\xda\x0a\xe5\xaa\xa0\xfd\x76\xbb\xfc\x32\x63\x48\x13\x5e\x31\x4b\xcf\xc0\x6b\x50\xa7\x8a\x19\x60\x13\xb3\xb2\xee\xc0\x8a\xec\xaa\x4b\x0f\x21\x10\x7d\x5b\x45\xd8\x1d\x89\x18\x62\x5d\xce\xc8\x14\x71\xc8\x77\x1c\xfb\x27\x24\xac\x6c\xce\x04\x2b\x18\x07\xba\x15\xf7\x3d\x05\x2a\x31\x38\x97\x44\x28\x1e\x31\x3a\xfc\x17\xb0\x38\x4a\x14\x4b\xaa\x5e\x55\xc6\x4b\x9e\x60\xd1\xac\x8e\x00\x94\xf8\x22\x6a\x30\x80\x8e\xb7\x93\x58\xda\x14\xb9\x20\x8c\xde\xfc\x74\xeb\x39\x61\x21\x9f\x72\x1a\x57\xb8\xa0\x8a\x34\xc5\x6b\x0e\xc5\x6e\xd5\x6a\x39\x9f\x23\x30\x52\xb7\xba\xcb\x7c\x55\x6d\x2f\x5d\x8d\xb8\x42\xb3\x97\x33\xf4\x6b\xb8\x0a\x58\x1b\xe7\x3c\xcf\xb1\x13\x63\xbd\x0e\x7f\x86\x1f\xa7\xc5\xf9\x5c\xd7\x54\xbf\xa3\x49\xd5\x5f\x6d\x4e\xc1\xd9\x41\x4d\x0d\x5a\xc0\x33\xe3\xea\x92\x66\x93\xcf\xa6\x7c\xe9\x98\xd1\x24\xab\xd8\x38\xa2\x4b\x9b\xfe\x05\x3c\x73\x7c\x3e\xc3\xfd\x0d\xac\xd2\x70\xe8\x9a\xc2\x6c\xba\x0d\x1f\xba\xe1\xbc\xb8\xd1\x0f\x32\x9c\x22\xc7\x57\xe9\x31\x1d\xa7\x72\xb0\x77\xbd\x2c\xbe\x58\x38\x75\x32\xaa\xf5\x38\x6c\x91\xc1\xc8\x7d\xc5\xac\xc4\xe9\xb9\x4e\xfd\x81\x23\x7e\xf9\x70\xd9\x1b\x95\x2a\x4a\x2e\x40\x5d\xac\x9a\x75\x38\x7c\x3d\x1c\xcc\xe6\x55\xe6\xee\x3a\x0c\xec\x46\xfe\xe5\x24\x46\x5a\x56\x46\xac\x4e\x6b\x73\xe2\xb1\x7a\x93\xb9\x2a\x91\x10\x95\xeb\x5d\x67\xb1\xc6\xce\xd2\x8f\x45\x2b\xc4\x51\x89\xd6\x5c\x47\xba\x40\xb9\x2b\xd9\xa2\xf5\x2d\x34\x46\x8b\x19\x76\x13\x98\x45\x6c\xd0\xbf\x2d\xdd\x98\xcd\x2f\xf6\x1c\x16\xf9\x3e\xc9\x65\x4b\x5a\x1b\x18\xfc\x0f\x4a\xd6\x91\x48\x8c\x0f\x70\x05\x07\xfa\x9d\xff\xe4\x27\x76\x4f\x9b\x6d\x5a\xf1\xe2\x2e\xe2\x30\x89\xd3\xec\x25\x28\x86\xd4\x46\x10\x4b\xe0\x45\xa8\x28\x76\x2e\x81\x45\x85\xce\x98\x33\x3c\x6c\x80\x3e\x7c\xd6\x6e\x01\x5f\xb0\x9b\xdb\x7d\xba\xec\xb7\x24\x74\x04\xf0\x4b\xeb\xf1\xe8\x6f\x12\x2a\x63\xbd\xe0\x99\x96\x24\x93\x0c\xee\xf6\x67\x8e\xec\x64\x43\x25\xa0\xc6\x89\x5e\x0c\xb4\x95\xba\x4e\xe3\x8e\x05\xfa\x5b\x6c\x72\x59\x09\x4d\xcd\x14\x53\x38\x8b\x42\x94\x8c\x5f\x47\x80\x08\x95\xc9\x46\x09\x92\xd9\x73\x16\xa6\x8b\xcd\x94\x54\xed\x6a\x46\x96\x2b\x1b\x96\x41\x61\xab\x59\x9b\x02\x7e\xf2\x5e\x6f\x46\x00\xc3\xf5\xa2\x08\xcf\x70\x55\x1b\x77\x79\x2b\x59\x23\x7b\x4a\xd2\xdc\x20\xbb\x26\x9e\x64\x00\x3b\x2f\x6e\xf5\x20\x7a\xcd\xe5\x7d\xf2\x45\xf1\x77\x11\x64\xe9\x5d\x34\x39\x56\xbf\x9a\x3c\xbe\x0a\x45\xc7\x32\x2b\xdf\x36\xf5\xdd\xb1\x7a\xc3\x57\x3b\x41\x47\x53\x88\x9d\x7d\xf8\x55\xc0\x23\x04\x92\x17\x71\xdc\x0e\xb8\x73\xff\x88\x0a\x5d\x2e\x8a\xa9\x4d\xf6\xd3\xfe\x25\x21\x40\xe7\xc2\x49\x5b\x93\x5e\x3b\xbd\xe6\x34\xd5\x6a\x52\x57\x6f\x16\xac\x78\xb9\xe9\x8c\x1a\xb0\xed\xb4\x30\x7d\x5e\x48\x8c\x89\xb3\x7c\x6b\xe5\x27\x01\x19\xe5\x63\x6f\x12\x93\x2a\x1d\xc7\xc9\x99\xb8\x8b\xa0\xf1\x28\x4b\xdd\xc4\xbc\x4f\xee\x31\xe3\x70\x46\x88\x9c\x09\x1f\x95\x02\x36\x09\x93\x34\x74\xb2\x3e\xb9\x86\x9c\x5b\xb5\x1d\xdb\x84\xb2\x4f\x5b\x7f\x4d\x81\x24\x9d\xc3\x5b\x03\x7a\x6f\xae\x20\xf0\x20\x70\xf4\xf0\x49\x08\x21\xa4\x58\x9b\x76\xdd\x08\xfa\x39\xf1\xdc\x56\x24\x6b\x39\x60\xa2\xc7\x38\xc0\x55\x4a\x22\xa5\x68\x93\x5e\xec\xab\xc5\xc8\xcb\x6f\x42\x78\x9a\x4f\xb9\x57\xa4\xc9\x52\x48\x2c\x1a\x7a\x0c\x2c\x51\xc0\x0d\xb5\x90\x93\x26\x5a\x4b\x58\x1e\xb0\x89\xf0\x9e\x46\x25\x2f\xa9\xaf\xf2\x61\x2e\xe9\x4b\xd5\x27\x9e\x5b\x57\x89\x24\x76\x69\xed\xa3\xda\xb8\x06\xf0\x46\x0b\xf0\x6c\xf7\xe5\x11\x80\x2e\xa2\xda\xba\x61\x6f\x5c\x6c\x39\x74\x78\xa8\x1f\xac\x09\x8d\xb9\xc6\xd5\xfc\x05\x2d\x6d\x42\x8e\xd4\xa2\x8e\x7b\x9e\x7e\x69\xf8\x8f\x5e\x6a\x3e\xbb\xfd\x2b\x13\xf5\x79\xfe\x0a\x1f\xc8\xbf\xcc\x2e\xfe\x2f\x39\x5e\xcd\xe5\xcd\xd2\x4c\x41\x33\x4e\x79\x3f\x5b\x8b\x84\x04\x06\x69\xc4\x2e\x96\x12\x5b\x9b\x16\x53\x64\x6c\x84\xc2\x86\x23\x28\xed\xa9\x2d\x9f\x7d\xd4\xee\xc5\xa6\x8b\x5a\x36\x45\xe3\x29\x4d\x32\x9b\x88\x8b\x92\x89\x30\x55\xdc\x28\x94\xcc\x04\xd2\x1c\x67\xee\xb1\x07\x36\x50\x9c\x9d\x90\x99\xe8\x5a\xfc\x69\xb3\xfe\x59\xa7\x94\x47\xdd\xda\xd0\xc3\x62\x6a\xfa\xc9\x4d\xad\x09\x7f\x12\x45\x66\xc1\x0c\x64\x5f\x07\x67\xb5\xc2\x2d\x1f\xbe\xf7\x78\x04\x91\xd6\x86\x95\x7c\x25\xba\x7c\xbd\x51\x81\x9b\x35\xc5\x7d\x43\x14\x8b\x40\xc7\xbc\x75\x49\x58\x4b\xa1\x03\xde\x58\x8d\xf0\x2d\x7d\xd7\x1c\x3d\xe9\x3d\x19\x54\xae\xcb\xf9\x8e\xdd\x36\xe8\x5f\xed\x48\x84\xe5\x34\x06\x7e\xb2\xaa\x9a\xbe\x13\x52\x56\x9c\xa3\x8d\xda\xd6\x2d\x2a\xe9\x3f\x57\xb9\x18\x9d\x37\x29\xeb\x5c\x31\x8b\x55\xbc\xfc\x8d\x02\x51\xa6\x3d\x00\x8e\x30\x95\xaa\x10\xca\x73\x3c\x2a\xd6\x71\x3f\x4e\x1f\x22\x60\xce\xe6\x2b\xd5\x81\xae\xd4\x9d\x9c\x34\x99\x3b\x17\x20\x98\x43\xdd\x8c\x0f\x2b\x0d\xda\x18\xe5\x79\x9d\xca\x75\x83\x2d\x6d\xae\x9c\xaa\xc0\xd9\x19\x1a\x68\xd6\x21\xf8\x45\x3f\x17\xcc\x3e\xab\x9c\x19\x66\x74\xae\xac\x18\x7f\xe2\xbd\x47\xef\x6c\x32\x0a\xd9\x0b\xaf\xc6\x92\xbc\xce\xc9\x4f\x6f\x30\x81\x96\x93\xf4\x71\x01\x1e\x94\x65\xc6\x16\xc0\xc6\x73\x5b\xe0\xdc\xca\x50\xd8\x9e\x43\xda\xde\x87\x5d\xe1\x4e\xc5\x66\x8a\xa3\x31\x8a\x95\x33\xe0\x32\x57\xa9\x9f\xe1\xda\x1c\x04\x03\x6e\x79\x7d\x51\x76\xcd\x01\x98\x0c\x72\x1f\x32\x69\xe9\xa8\x1d\xda\xe1\x4e\xa2\x93\x5e\x41\x9c\x43\x8a\x2d\xad\xf9\x4f\x80\x4d\x9b\xe4\x28\xea\x32\xb5\x31\x50\x51\x70\x80\xa0\x74\x21\x0e\x00\xc5\x37\x97\x98\x38\xbc\x0c\xe9\x81\x34\xc1\x9c\x1f\xe3\x48\xd3\xe0\x45\xbb\x36\x99\x5b\xe1\x78\x63\x2b\x29\xf0\x93\x5a\x55\x3f\x28\xf5\xaa\x38\x2d\x91\xbc\xc1\xfa\x8d\x95\x02\xea\x94\x2d\xa1\xbe\x84\xb2\x37\xbd\xc7\x1d\x3d\x29\x13\x4b\x17\x21\x4b\xdb\x2b\x32\x09\xb4\x5f\xa8\x0b\x13\xbb\x88\x7a\x3e\xd1\x93\x59\x45\x81\xa3\xe5\xa7\x05\x12\x0f\xae\x70\xc2\x95\x26\x5f\xa4\x62\xd7\x7d\xa4\x00\xaa\x78\x83\x72\x68\xe9\x65\xbd\xed\x03\x08\xc7\x22\x0b\x10\x6a\x9a\x59\xca\x5a\xd8\xd8\x6e\xcf\xb7\x58\x63\xb6\xc1\x69\x8d\x42\x05\x94\xca\x42\x0c\xc2\x01\x90\x3c\x75\x36\x91\x2a\x12\xec\x8a\x07\x44\x28\x28\xcc\xbd\xf6\x80\x31\x9e\xee\x96\xee\x77\x12\x44\xcc\xbe\x90\x95\x8d\x04\x4b\x2c\x82\x93\xe3\xd9\x0b\x0f\xe9\x3a\x51\x92\xee\x3a\x9b\xb9\xea\xb6\xec\x00\xfb\xd6\x86\xf5\xb7\x4b\x45\x85\x41\x55\x4a\xf7\x0e\x15\xcf\x58\x46\xc7\x4f\xb2\x1e\x82\x54\x20\xa9\xb5\xfe\x03\x2c\x25\x22\xae\x70\xe3\x04\x7e\x0f\x56\x71\x23\x8f\x92\xb7\xb6\xa3\x26\x19\x8c\x36\xea\x8d\x8c\xfa\x39\x79\xb2\x49\x4b\x39\x0f\x30\xaa\xca\x31\x0e\x4a\x6a\x94\xb7\xb2\x9f\x4a\xbe\x66\xc0\xb9\xd2\x18\x0f\x3f\xcf\x1c\x9a\x6b\xa9\xce\x4f\xf7\xff\x9d\xd9\xee\xe9\x9d\x61\x55\x47\x83\x2e\x90\x90\x6a\xab\x0b\x48\x09\x45\xe9\xcb\x56\x04\x4d\xf2\x0b\xd6\x71\x09\x6d\xb5\x7c\x97\x69\xad\x21\x0f\x46\x07\x52\x3e\xaf\x88\xb0\x98\xab\x3f\x1a\xfc\x3f\x62\x20\xa9\x69\xbc\x63\x74\x9c\xb4\x67\x9a\x55\x02\x00\x33\x1b\x13\xde\x9f\x68\x80\x30\xc5\xb5\x6c\xc1\x29\x03\x32\x69\x77\x1f\xad\x20\xf7\xd2\x54\x84\xa2\xf5\x40\xcf\x49\xa2\xb2\x21\xaf\xa6\x58\x8a\x6d\x22\xcd\xed\xd3\x18\x7c\xbf\xdd\x4d\x7e\xfd\x32\xbc\x2e\x57\xf8\x0a\x61\xb4\xd3\x33\x85\xfd\x35\xbe\xdf\x82\x2c\xbe\x6c\xb0\x94\xa7\x9e\x65\x12\x71\x4d\x3d\xf4\x20\xb4\x99\xf7\xfa\x67\x23\x45\x0b\x2b\xba\xdc\x04\x9e\x91\x5d\xd3\x3e\x9c\x55\x89\x6e\xe0\xa8\xb7\x87\xb7\xf4\x1e\x96\x70\x96\xcd\xff\xbc\xb9\x67\x7c\x73\x23\xd2\xbb\x43\x0d\x03\x5e\xe8\xa0\xc3\x4e\x71\x86\x06\xdf\x0d\x41\xfc\xcf\x5b\xba\x0a\x62\x45\xec\x5f\x81\x47\x40\x08\xcb\x3c\x91\x20\xbe\x7b\xc5\x8f\x69\xa4\x0d\x6d\xf2\x1a\xcc\xd2\xf8\x85\x4a\x1a\xa1\x93\xe0\x5a\x06\xb8\xc8\xa5\x0e\x22\x5f\xda\x41\xee\x11\x60\xb2\xbd\x5d\x12\x5b\x68\xfc\x4c\x53\x4c\xed\xf7\x76\x98\xab\x41\x33\x20\x87\x0b\xaa\xaf\x32\xcb\xcb\xa1\x5e\xd8\x7e\x71\xb4\x76\x50\xf2\x46\x06\xc0\xdf\xfb\x01\xa1\xe3\x66\xd3\xce\x41\xb9\xc7\x4e\xa8\xc4\x8e\xd5\xc8\x54\xc1\x87\xa1\x3b\x97\x96\x20\x00\x03\x46\xc8\x03\x5b\xe7\xde\xb3\x57\xdd\xec\x11\x0f\x9b\x3c\x09\xa2\xed\xb9\xa1\x25\xbc\x85\x09\x17\x99\xa0\xc1\xa5\xe3\xb4\x0a\x72\x68\x51\xb4\x76\xf3\x3c\xe2\xde\x46\x39\xe7\xb5\x05\xfa\xde\x0f\x82\x06\x21\x12\xe0\x37\xc0\x96\x3f\x5b\x11\x50\xef\x4d\x78\x19\xe3\xe4\xab\x4f\x98\xa8\x81\xb6\x14\xa6\x77\xbb\x6c\x9a\xab\xca\x19\x63\x87\x17\x0a\x2d\x48\x67\x16\x59\xc1\x65\xaf\x43\x6a\xc4\x87\x64\x3c\xff\xb6\x5c\xaa\xa3\x21\x74\xd1\x3e\xd4\x56\xd3\xf2\xbf\x5c\xf2\xf8\xd1\x73\x83\x19\x13\x35\xca\xec\x77\x05\x1c\x6e\xb8\x11\x8b\x37\xc2\xf1\xb7\x8c\x15\x4c\x08\xef\x98\x6d\xa9\xd8\xc1\x71\x6e\xce\x6d\xaf\x00\xc4\x8a\xf5\x77\x3c\xdd\xa6\x13\x92\xf3\x03\x4f\x53\xba\x6a\xfc\x7b\x28\xd4\x64\x5b\x7f\xef\xa3\x22\x13\xe3\xdb\xe0\x4c\x1f\x13\x0d\x80\xf2\xf6\x6a\x47\xd8\x7c\xa1\x2b\x29\xb7\xc6\x30\xdc\xc8\xa0\xb5\xb6\xc6\x0d\x8d\x34\x90\x25\xe0\x4d\xd2\xdb\xd6\x7d\x07\x5a\x14\xd4\x51\xee\x3a\x76\xc7\x7d\xda\x30\x48\x84\x08\xf1\xa0\xa8\x5a\xe9\x9b\x52\xf7\x95\xbf\x80\xcd\xe2\x4f\x9d\x05\xac\xd9\xa2\xf3\x7d\x3e\x28\xc3\xf6\xe2\x96\x72\x56\xeb\x85\xfb\xc0\x39\x0e\xd1\x7c\xb8\x08\xdb\xc8\x0c\x60\x95\xfb\x2e\xb0\x91\xf1\xc7\x57\x15\x36\x62\xf0\x5c\x77\x6d\xaf\xe6\xab\x15\x3c\x99\x04\x77\xb4\x53\x69\x18\x1d\x61\x3b\x0e\x1c\xe5\x36\xe6\xc0\xd3\x41\x6e\x63\x0f\xcd\x13\x20\x27\x43\xd5\x7e\x75\xb1\xa4\xf8\x22\x9a\x12\x31\xf9\x85\x7f\x9f\xce\x26\x54\xd6\x6e\xbb\x3f\xfb\x71\x42\x8c\x7b\x75\x10\x69\xf7\x05\x9e\x8c\x77\x81\xa1\x51\xe3\xe5\x55\x0d\xfd\xe4\x66\xb6\x56\x46\x33\x50\x95\x70\xad\xf3\x27\x59\x86\x7f\x8a\xe2\xcc\x5c\x7d\x96\x1e\x7c\x2e\xe6\x16\x6f\x74\xe4\x81\x4d\x7e\x3f\x81\x7c\xac\x97\x10\x9a\xea\x5c\xa8\x02\x7f\x05\x98\x9d\xc2\x78\x97\x11\xe0\x82\x3b\xcc\x3f\x71\x04\x97\xb9\x65\x8d\x86\x0c\xcc\x50\xb8\xf3\x86\xe0\xa3\xae\x1a\xab\xba\x26\xa4\xd6\x76\x81\x1e\xc3\xdc\x8b\x40\xe6\x58\x48\x91\x73\x92\x10\x4f\x98\xed\xdc\xba\x71\x74\x03\xd4\x51\xa3\xd2\x04\x84\x01\x27\x95\xde\x4b\x1c\xdd\x3a\x7e\x52\x2f\xad\x97\xb6\x6b\x76\xe2\x8b\x37\xec\x69\xf6\x2b\x96\x6f\x60\xa6\x1c\xfe\x6c\xf0\xb6\x8e\x93\x36\x83\xb0\x9d\x15\x38\xf2\x18\x0a\xb5\xa1\x31\x3d\xa3\xf3\xc4\x0a\x41\x2f\x61\x33\x37\xa0\x33\x8b\x46\xcb\xaf\xa6\x5a\xe0\x91\xe3\x6f\x4b\x8f\x0a\xd0\xd4\xd7\x06\x29\x6c\x4d\x37\xdb\x68\x4d\x22\xb0\x58\x10\x72\x00\x58\x70\xc4\x88\xab\x8f\xec\xe3\x9b\xda\xe1\xb2\xf7\xcd\x8c\x2b\xe2\x12\xb9\x69\xc0\x32\xed\xb7\xbc\x14\xe2\x17\x99\xd5\x1d\xf9\x43\x40\xb8\x9a\x4d\x72\xb8\x7c\x82\x84\xe2\x25\x45\x5d\x8b\x7b\xce\xe0\x2d\x6a\xa8\x11\xb7\x8d\x72\xfb\xb3\x9c\x7a\x51\x5d\xb8\xd0\x96\xa5\x14\x8e\x3f\xa5\x50\xa3\xed\x96\x79\xf3\xa9\xbe\x2b\xc1\xfa\xd6\xcb\x35\xa5\xeb\x54\xbc\x2c\x0d\x2d\x2e\xf7\x47\x00\x2c\xf9\x9c\x95\x66\xba\x7d\x49\xd1\xa0\xb8\x96\x4c\x0a\x4b\x94\x10\xd8\xe6\x1f\xc4\xf5\xcf\xf2\xf3\xb2\x8e\xc5\x31\x91\x57\xef\x05\x81\xe5\x22\x30\x12\xb9\x2c\xa1\x8e\xf5\x41\xb2\x28\x26\x58\x4b\x51\x1d\x6d\x59\x68\x08\x68\xb7\x9f\x03\x24\x6f\xec\x97\x85\xbd\x9e\xaf\x45\x85\xd8\x25\x7f\x76\x27\x86\xee\x6c\x3c\x7d\x26\xc7\xe1\xc8\x9a\x4d\x61\xc6\x4f\x50\x26\xe6\xf3\xfe\xbb\x2e\xd9\x7d\x93\x74\x0e\xe8\x9c\x85\xe8\x24\xa6\x4c\xb8\xcd\x2d\x5e\xef\x27\xbb\xee\x52\xb0\x73\x47\x43\x04\x28\x8e\xeb\xa7\x84\x5f\x84\x4c\xef\x16\x28\x57\x14\xc1\x3c\xa1\x37\xa7\xcf\x00\x02\x83\x8b\xa8\xae\x3d\x67\x29\xd1\x4e\xf4\xe7\x4a\x0f\xc4\x89\x9b\x11\xbe\xa4\x0f\xa0\x33\xc9\xb1\xf4\x70\x6f\x27\xa1\x3b\x37\x2e\x55\xdb\xac\xdc\x67\x61\x0e\xf7\x94\xae\xac\x70\xa0\xae\x00\x3f\x9f\x31\xdc\xa0\x6a\xb5\xfb\xf6\x45\xb7\xc5\xb9\xea\xb4\xce\xa7\x27\x9a\x42\x7c\x22\x71\x14\x5c\xb2\xd8\x0c\xff\x41\xa5\xba\x5e\x0f\x31\x3c\x94\x4f\x45\x05\x72\xe2\xf4\x61\xa4\x85\xe2\xc5\xb0\x63\x4e\x33\xa3\xb7\xdb\x5f\x8f\x50\xa4\x13\x2e\x14\x61\xd5\x8d\x2b\x61\x48\x58\x3a\x4c\x73\x6e\x64\x22\x68\x08\x3a\x09\xa1\x4b\xc7\x9d\xdd\x96\x05\x91\x9f\xce\x58\xb9\x0c\x23\xbf\x19\xc4\x7d\xdf\xda\x5d\xf3\x61\xd0\x71\x56\x3c\x8f\x73\x21\xff\x15\x88\xd8\x00\x8f\xcc\xe3\x6b\xa0\x22\xcd\x9c\x31\x6d\x1b\xe5\xbb\xb8\xb9\x63\xd4\x83\x28\x51\xcb\xe8\x13\x0f\xd1\x9a\xed\xec\xe0\x00\x5d\x53\xf7\x66\x1c\x3b\x85\xfa\x59\x2d\xd4\x0a\xbb\x45\xc0\xd6\x13\xfa\x31\xb7\x7d\x0a\x05\x67\x3c\xf9\xc2\x8c\x56\x7d\x0d\xc4\xa9\xe5\x34\x71\x16\x95\xca\x66\x53\xf1\x06\xfa\x32\x7e\xc7\x82\x99\xda\xfd\x7f\xc6\xbb\x26\x68\xf6\x48\x37\xcf\x6e\xa4\x6b\x0f\x51\xbc\xdf\xb8\x85\xe7\xd4\x71\x8e\x0c\x28\x28\xa1\xa7\x2d\xbd\xa8\xf5\x3d\x30\x5c\x11\xc2\xf1\xd2\x24\x72\xba\x5a\x87\x92\x4e\xa7\x33\x09\x3d\x93\xf3\x58\x58\x4e\xeb\x76\xc4\xb2\x98\x2c\x9f\x59\xfe\x84\xd8\x8c\x5c\x1b\x3a\x76\xda\xc3\x0a\xfd\x24\xde\x19\xf1\xa0\x74\x88\xb4\xf1\xb9\x0f\x30\x24\x0a\x33\xc2\xd1\x4d\x50\x45\xe1\x8a\x16\xee\x63\x02\x46\x01\x1e\x5f\x02\x15\x5a\x45\xa0\x3c\x8e\x1b\x6b\x1a\x25\x81\xed\xfa\x78\x7c\xb9\x4f\xd2\x4b\x9e\x2c\xef\x60\xb1\x04\x90\xed\xa6\xa4\xb0\x8e\x9c\xc7\x8f\x10\x59\x53\xee\x7d\x78\x76\x44\x27\xd1\xa5\x28\xa2\xf3\xed\xe9\x73\x85\xfa\x1e\x70\x49\x49\xc0\xd8\xa4\x39\x24\xd4\x4c\x5a\x1a\xc7\x43\xe3\x8a\xfc\xe6\x17\xae\x3f\x65\xee\x96\xa2\x25\x86\xd7\xc2\x04\xc6\xfa\xf9\x57\x05\x56\xfa\x26\x23\xa5\xb2\xa1\x4d\x2e\x2c\x36\x82\x5c\xaa\x3e\x58\x58\x76\x5f\xab\x79\x65\xdc\xd4\x8e\x57\x78\x25\xf7\xd1\x75\x0d\x3c\xdf\x52\x72\x8f\x45\xd8\x5f\x15\x61\x7f\x35\x59\xfb\x2d\x57\xa0\x1f\x69\x39\xa9\x98\xee\x2d\xbf\xfc\xf1\x7e\xc7\x70\x2b\xfa\x0d\x7b\x42\x60\x2d\x5d\x8b\xf3\x37\x2b\xbf\xfe\x4d\x4b\xe0\x30\x21\xc7\x98\xf6\xe4\x7d\xd2\x6f\xa8\xdf\xfe\x12\x6e\x00\xb5\x45\xff\x09\x6c\xba\x76\x94\x55\x02\x79\x00\xa6\x3a\x56\x11\x65\xa3\x15\x3e\x4c\xb7\x5b\xe5\xa6\x42\xf8\xb8\x78\xe5\x6b\x09\xbd\x3b\x61\x2a\xa5\xa7\xc7\xe5\x66\x37\x5a\x79\x50\x45\xef\x79\xfb\x65\x05\x38\x52\x9f\xe3\x86\xcf\x01\x9b\x1c\x62\x39\xdf\xc3\x50\x85\x02\x98\x88\xa8\x46\x0b\x96\x93\x50\xc8\x50\x5c\x96\xb0\xde\x5f\x88\xec\xe5\x7f\xd5\xc8\xd2\x7d\x32\x3d\x02\xca\x38\x7d\x79\x6e\xe6\xff\x9c\x8f\x75\x10\xf1\x16\xe0\x01\xe6\xd8\xdf\x55\x9e\x8c\x3b\x66\x1e\xb7\xd4\x1f\xea\x39\x9a\x6c\xa1\xf1\x04\xb9\xe8\x96\xec\x73\x6b\x84\x2a\xa0\x24\x7f\xcd\xed\x4b\xd3\xcf\x8d\xa8\xb4\x38\xa3\x91\xd5\x75\xfb\xde\x51\xfc\xb5\x16\xc6\x48\x7e\xc1\x74\x63\xd7\xec\x84\xca\x26\xbb\x4a\x10\xe8\x75\xf9\xb1\x9c\x39\xba\x88\x3e\x80\x97\x85\xea\x3b\xad\x9a\x72\x8c\xb4\xac\x5b\x0a\xa5\x03\xbc\x23\xf4\x68\x02\x74\x39\x8d\xb5\x73\xb7\x66\x52\x95\x64\xa0\x71\xc6\x70\xea\xda\x0f\x67\x17\xeb\x18\x83\x13\x59\x36\x59\x5a\x96\xb7\x70\x98\x8b\x1c\x29\x86\x92\x7a\x2a\xe7\xcd\x9c\xe6\x0c\x63\x70\x84\x06\x54\xb7\x06\x2e\x30\x0f\x2a\x11\x0d\x7e\x39\x85\xd4\x1b\x60\xa3\x5e\x4d\xc4\xa0\xcb\x36\xea\x6b\x32\x6b\xf6\x83\xbb\x31\xca\x82\xd3\xae\x8c\x80\x9e\x79\xdc\x26\x19\x32\xc1\xd5\x43\x03\xbd\xaf\x77\xee\x64\x7c\xba\x0d\x27\xab\xec\x08\x3b\xd9\xbd\x0d\xd5\x12\x01\x4e\x9c\xa3\x44\xfe\xec\x5d\x6e\x7a\x26\x90\xe4\x97\xf8\x2b\x1b\x71\xb6\x96\x0d\x36\xb5\x0c\x0f\x45\x9b\x58\xdc\x1e\xd2\x1a\x57\xd8\x1e\x45\xca\x0c\x52\x46\x90\x7a\x81\x18\xa9\xf8\xaa\xdd\xfd\x1c\xc7\x06\xb0\x33\xb1\xaf\x3f\x0f\x61\x31\x59\xd7\xed\xcf\xd9\xc7\x6f\xf8\x73\x8a\x42\x63\x61\x97\xb1\x2a\x8b\xd8\x06\x6d\x5f\xae\xe8\x37\x69\x88\xf5\x5b\xa0\x38\xc7\x9d\xed\xb0\x88\x87\x17\x27\xf7\xa8\x73\x71\x91\xc1\xf7\x28\x57\xcc\x8d\xe5\xc3\x7e\xab\x34\x07\x70\x48\xec\x21\xf0\xef\x29\x42\xe7\x58\xf0\x54\xa0\x3a\x4a\xbf\x88\x10\xda\x87\x52\xa3\xcd\xc6\x1c\x05\x65\xdb\x79\x0d\xc8\x66\x0a\x50\x45\x3f\x62\xb9\x93\x7b\xb1\xe4\x1b\x54\x8f\xde\x06\x45\x4c\xf4\x10\x66\x4a\x6d\xf9\xee\xec\x12\xca\x81\xd7\xf4\xc5\x1c\x3f\xcf\x74\x75\x5e\x20\xeb\xb9\xac\xdd\xfb\x64\x2e\x11\xba\x09\x90\xa6\x8e\x5a\xfa\xa6\x5a\x79\xf4\x90\x40\xff\x0e\x85\xd9\x94\x7f\xe6\x49\xe8\xd3\x13\x22\x62\x0c\xca\xa7\x82\x31\x0b\x0b\xe4\x16\xfc\x1c\x7e\x49\x9e\x5b\xe0\x09\x37\xfa\xd4\x3d\xc1\x20\xbe\x84\xee\x04\x39\x4d\x30\x1a\x9f\xf1\xf2\x5b\xad\xdf\xea\xb3\x4c\x0c\x80\xbf\xdc\x69\xfd\x09\x50\x88\x12\xb5\x67\x11\xfc\x12\xa8\x9e\x8b\xd1\x5a\xf1\x8d\xd0\x3a\xfc\xd1\xeb\xb2\x6c\x79\x4e\x4a\x47\x9e\xd5\xef\xd3\xe6\xa5\x4f\xfa\x4f\x54\x58\xa6\x50\x97\x0e\xcc\xdc\xc6\x90\x64\xfb\xda\x21\x8c\x26\xda\xf5\xb5\x34\x09\xb8\x49\x79\x22\x30\x1b\x32\x3f\x55\x57\xce\x61\x9c\x0f\x47\x68\x6a\x01\xfb\xe9\x75\x14\x47\x60\x52\x1e\x91\x9f\xeb\xb1\xfe\xc0\xf4\x47\xa8\xe6\x47\x5e\xab\xe9\xa8\x18\xcd\x3d\xb2\x64\x0f\x43\x1b\xfb\x99\xb6\x80\x6b\x12\xc4\x29\xd5\x49\xfc\x82\x0c\xa6\x3d\x72\xe4\x67\xf2\x34\x2d\xa4\x15\xf5\xa7\xc4\xa2\x17\x80\x9d\x59\x2b\xbe\x37\xae\x53\xd0\x48\xfa\x93\x6a\xd6\x17\xc8\x4e\x1e\xd9\xda\xe5\xff\x63\xb4\xc5\x08\x01\x7b\x52\x08\x53\xeb\x83\xdb\xf4\xbe\x11\xa2\x69\xfe\x62\xf3\x64\x09\xa8\xdb\xe4\xd3\xf1\x8f\xc2\x76\xf9\x02\xb6\x1c\x4d\x77\xa6\x6e\xd2\x70\x64\xe1\xcd\xe5\x4d\xb0\x6a\x42\x70\xe9\xff\x54\xf1\x42\x30\xc9\x5b\x0a\x0f\xaf\x75\xc4\x5f\x9e\xe9\xae\xf1\xc8\x33\x42\xfd\x4d\x7a\x8f\x70\x73\xe0\x17\xa1\xf8\x9a\x15\x02\x5a\x4d\x80\x26\x00\xa2\x5b\x75\x30\x0d\xf3\x95\x0c\x21\xb9\x41\x4b\xf1\x20\x1c\x89\x7f\xe0\x30\x50\xbe\xb1\xef\x65\xc1\x92\x3b\x69\xbb\xa1\x00\x52\xe2\x0a\x57\x32\x61\xd8\x83\xe2\x6b\xe4\xfe\x12\xb5\xb4\xee\xda\x31\x6a\x13\xaa\x29\x8f\xcc\x93\x6e\xa6\xd0\x65\x16\x54\x0f\x66\x49\x42\x1b\x5a\x96\x03\x1e\xdc\xc3\xf1\x9c\x0b\x67\x6c\x44\x76\x0a\xcf\x09\xce\x2a\x51\x9c\xd6\xd3\x07\xfa\xa4\x83\x7c\x95\x0c\xc4\x2c\xee\x29\x4d\x80\x28\xa0\x7d\xe5\xe3\x8f\x1b\x64\xce\xa0\xdc\xaf\x50\x1f\x8a\x1a\x56\x61\xe4\x3f\xed\x36\xfe\xf3\x46\xbc\xac\x4a\x8f\x05\xac\x8b\x38\x24\x54\x32\x7a\x10\x96\x04\x9c\x78\x7f\xdc\xa2\x91\xa1\x04\x89\x25\xd6\xe9\xd0\x51\x3e\x73\x8a\x04\x02\x90\x4e\x64\x8b\x0a\x87\xb4\xdd\x82\x92\x09\x1d\x77\x80\x0f\xc7\x4d\xc3\x42\x67\x87\xa3\xa0\xc7\xef\x59\xfa\x81\x1f\x1b\x95\x38\x22\x40\xe3\xc3\xc1\x29\x5c\x3c\xc9\xb2\x78\xe6\x91\x51\xda\xeb\x46\x27\x83\x22\x71\xda\x46\x02\x6f\x69\xa7\xca\x8f\x71\xda\x6d\x84\x36\xeb\x8d\xab\x6a\x39\x0e\xe0\x5d\x1b\x21\x95\x75\x36\x43\xc5\x4a\xee\x84\x11\x55\xf8\xa6\xee\x79\xbb\x41\xa0\x2b\x37\x04\x70\xae\x3c\xe0\xdb\xc0\x0e\xad\xf4\x0e\xc5\x4a\xe1\x43\xf9\x99\x76\x77\x2f\x81\x4f\xb5\x3e\xbf\xce\xf3\xc2\xca\x55\x2f\x79\x41\x3a\xc7\xa7\x3d\x75\x07\xfb\xec\xad\xd3\x3e\xbf\x43\x74\x46\x79\x6d\x8b\xfe\x12\x87\x8c\x4a\x1c\x13\xd5\xe4\x5d\x21\x14\xb8\xf7\x1a\xa6\x1b\x56\xda\xd6\x0a\x52\xc4\x1e\x36\x02\xb1\xa6\xae\x29\x13\x21\xa4\x76\x1f\x9f\x1a\x7e\xbb\xe4\xcb\x71\xbc\x59\x6d\x40\x15\xfa\x98\x49\x76\xa0\x4a\x19\xf7\x2a\x6d\x75\x96\x2a\x7a\xb5\xa6\xfb\xf1\x9e\xa5\xbd\x00\xd6\xc6\x2b\xd6\x5f\x41\x06\x9f\xe5\x02\x4b\x43\xdf\x11\x20\x95\x23\x72\xd1\x95\x9b\xb9\x77\x1d\x25\x08\x79\x92\x47\xdd\x9e\x30\x5f\x58\x7c\x61\xa9\xdd\x4e\x55\xd4\x2c\x12\x2a\x74\x13\x08\xbf\x85\xa2\x71\x00\xe4\x10\x6b\x8a\xd9\x6e\xe1\x9d\x89\xb4\x19\xde\x60\x94\xd4\x8c\x15\x46\x88\x4d\x54\x20\xeb\xd3\x95\x57\x10\x17\xfa\x3a\x0b\xb0\x9a\xda\x43\x8d\x3d\x07\x6a\xf4\xac\x80\xca\x4d\xb2\x7c\x00\xb0\xe6\xa4\xa0\xd9\xc2\xda\x76\xeb\x12\xb1\xa0\xb0\x10\x96\x90\xaf\xa3\x57\xaf\xc0\x9f\x1e\x55\xb2\xce\x1b\x15\xed\x8f\x56\x3c\x82\x1e\xcf\x6b\x78\xe3\x63\x6a\x7f\x02\x63\x13\xf0\xd4\x6f\xb4\xb3\x37\xc7\xf5\xf6\xa8\xb5\x9b\x6d\x0b\xa7\xdb\x98\x1b\x5b\xf8\x5b\x34\x5f\xb4\x58\xb3\x99\x87\xb0\xae\x31\xe5\x77\xe7\x5a\xbf\x6c\x6c\xb4\x50\x99\xd2\x09\xb4\x45\x97\x65\x69\x25\x21\x6a\x83\x10\x15\x4b\xdd\xc3\x3a\x00\xae\xeb\xd7\xa7\xfd\x87\x59\xce\x6c\x64\xdc\xab\x58\xe8\xfc\x1f\x18\xec\x71\xe8\xf9\x14\x0c\x36\x7f\x35\x51\x9f\x51\x7e\xdd\x86\x22\x76\x7b\xff\x39\x3d\xa4\xf8\x84\x7d\xa5\xcd\x61\x5b\xaa\x3e\xab\x75\x90\xc1\x0e\x69\xa7\xb3\xaa\xe4\x43\x94\xd4\x93\xdf\xd6\xa6\x3b\xcb\x93\x48\x27\x8b\x93\x30\xab\xf0\xc8\xe6\x2f\x3e\x39\x88\x8f\x3b\x09\xf9\x73\xcd\x52\x62\x4b\x5d\xbd\x54\x97\xd8\x85\x4a\x39\xda\xb4\xe3\xd6\x9e\x73\x5b\x5b\x18\x22\x28\x37\x3b\xda\x6c\xf4\xd8\x08\x62\x3d\x8f\xbf\x95\x8f\x8f\x85\x04\x28\x3a\x6a\x36\xe0\xae\xa7\xaa\x02\x14\x6b\xd2\x2c\xad\x1d\xc6\x7a\x5b\x02\x1d\x9b\x14\xa4\xbe\x08\x5f\xfb\xb5\x08\xe9\x86\xbb\x77\x98\x60\x1c\x16\xac\xca\x36\xd4\xc3\x11\xe8\x4f\xc0\x02\xeb\x3f\x06\x59\xcf\x73\xba\x32\x35\x83\x5a\x14\x3b\x88\x44\xdd\xc8\xbf\xe7\xfa\x59\xe8\xb2\x26\x9f\xf6\x48\x23\xd5\x81\xb1\x40\xc6\xf2\xa5\x90\x09\xa5\xa9\x6e\xc7\xa8\x8d\x0b\x67\xd9\x32\x11\xb4\xa8\x0e\x4a\xce\x14\x20\x6f\xf0\x91\x5a\x36\x3b\x0a\x5b\x9e\x7f\x7f\x7b\x72\x03\xdb\x93\x2a\xdb\xf0\xd4\x0d\xd1\xd2\x45\x3f\x79\x73\x4a\xd3\xd2\xe9\x2f\x32\x6b\x05\xa3\x7d\x49\x92\x11\x0d\xae\x3c\x6c\x73\x8b\xf6\xd5\x65\x76\x38\xe7\x6a\xce\x4c\x2d\x37\xce\xec\x1d\xbb\xca\x9d\xc9\xbe\x48\xb2\xa7\xe5\x6a\x6b\xbd\xba\xf1\xe1\x80\x6f\xc4\xce\x56\x29\x45\x53\xa8\x64\xe4\x61\xd9\x8f\xff\x62\x5b\x6b\xab\xa7\xe5\x6e\x38\x79\x5a\x44\x9d\x20\xc0\x5c\x5d\x9c\x36\xb0\xae\xa5\x3b\x6c\xac\xa3\x52\x1c\x56\xb1\x0f\xc2\x24\xdc\x77\x57\x70\x57\x47\xea\x8e\xb0\xe4\x61\x7e\x60\x8f\x31\xbc\x0f\xf9\x55\x28\x78\xb2\x5f\x69\xc6\xbe\x29\xb2\xf5\xcd\xd4\x46\x14\x06\x95\x6e\x98\x9e\x13\x6f\x81\x38\xb5\x7e\x25\xf9\xec\xa7\xb1\xac\x97\xe0\xde\x3c\x94\x22\x2c\x6b\xe5\x50\x37\x90\x8e\x89\x1f\x45\xb1\x87\xd4\x64\xf7\x90\x40\xd2\xdc\xad\x74\xf1\x6a\x72\x17\xea\xa4\xba\xae\x09\xeb\xda\x15\x9e\x6b\x37\x71\xc5\xb8\x86\x4c\xe9\x26\x9d\x49\x44\x99\x93\xd8\x26\x20\xdf\x80\xb8\xca\xd9\x77\x9c\x84\x43\x4e\x82\x26\x3b\x94\x35\x35\x4d\x88\x99\xb6\xa2\x24\xa7\xc8\xb7\xec\xf7\x16\x5c\x1f\x85\x26\x56\xb6\x13\xf2\x38\x07\x75\x9e\x9c\xe1\xc1\x0e\xf7\x46\x67\xde\xcc\x0e\xd7\x3d\xd5\xd4\xd3\x71\xe9\x47\xb8\x80\xa1\x96\x8b\xd5\xba\x74\x1f\xfa\xe5\x69\xe4\x93\xe0\x31\x1c\x7b\x21\x05\xdd\xea\xb4\x36\xa4\xdf\x4e\x4c\x85\xaf\x00\xef\x45\x44\x29\x7f\x01\x50\x37\x7b\x9c\x08\x80\xb5\x59\x08\x95\x52\xb1\x94\x4f\xc4\xe7\xea\x6b\xed\x84\x7c\xae\x7c\x93\xfe\x52\x38\x8b\x2e\x84\xe8\x2e\xa8\x27\x72\x67\x40\x70\xec\x59\xdd\x24\xa8\x02\x42\x41\x91\x52\x02\x63\x1e\x31\xa3\x6c\xe6\xa9\x70\x28\x9c\x58\xfe\xd1\x09\x14\x3b\xf2\x10\xac\x04\x52\x53\x12\xe5\xd0\x40\x97\x3a\x5d\x2a\xc9\x81\xf5\x6e\xf1\x52\xcd\x96\xa8\xa9\xfb\x47\x82\xbc\x8e\x12\x57\x05\x96\xde\x0f\x18\xa1\x36\x41\x87\xe4\x11\xda\x98\x99\x91\xd4\x25\xd2\x10\xff\xbe\x1b\x5f\xf1\xc3\xc1\xb6\x87\xaa\xf3\xee\xcd\xb0\x94\x00\xcb\x3e\xfb\x81\x7f\xa7\xfb\x02\xd7\x1f\x28\x94\x59\x11\x67\x4b\x94\x7c\x67\x07\xad\x04\xb7\xf9\x6d\xc3\x7e\x16\xa8\xda\x42\xcc\x5a\xa2\x0f\x04\x3c\x80\xfc\xf7\x73\x9c\xd7\x97\x39\x74\xdb\x3a\x01\x4f\x16\xc2\xf6\xf8\xcc\x95\x34\x98\x1a\xf5\x84\x09\xa6\xdd\x55\xa3\x15\xaa\x63\x84\xe2\x76\x4e\xfa\x7e\x10\x8e\x1b\xaa\xac\x7f\x98\x92\xfd\x31\xff\xb6\x3c\x4d\x4e\xf8\x7f\x79\xe2\xb5\xb2\xc0\xab\x0c\x17\x47\x8a\x2b\xbf\x7b\xfa\xf8\x5e\xd9\xd9\x0f\x57\xde\x5f\x61\x45\xcc\x32\xd1\x95\x29\x18\x7e\xe5\xe4\x5f\x71\xa5\xf9\x74\x86\xd1\x45\x45\xbd\xcf\x95\x84\x39\xff\xec\xab\x63\x6c\xb7\xb1\x5a\x63\x7d\x90\x51\x4c\x21\xe4\x7a\x4e\x50\x27\x25\x7f\xdb\xad\x8b\xab\xe8\x1d\x30\xbf\x9a\x89\x7d\xc6\x65\x91\x15\xf1\xc2\x81\x18\xbd\x92\xa0\x9c\x40\x91\x55\x20\xfc\x67\x88\xf5\x0b\x07\xfe\xca\x9e\xe3\x03\xa5\x2b\x87\xec\xda\xd8\x41\x7f\x45\x8b\xb2\xfc\x90\x2d\x9a\xf4\x3d\x08\x1b\x2f\xdb\x78\x2b\x85\x16\xab\x2f\x4a\x85\x58\x2c\xf5\xe9\xf9\xb7\xe4\xfc\xd2\x22\x96\x85\xa1\x34\x9b\x93\x90\x25\xae\x05\x66\x13\x13\xfe\x4e\xb4\x3b\x0d\x94\xf0\x3e\x84\xa8\xf4\xc7\x9e\x72\x29\xbc\xb2\xa8\x68\x33\x58\x75\xde\x88\x74\xfc\xf4\xe2\x43\xfe\x91\xe3\xe2\xc7\xee\x4f\xc1\x89\xed\x22\x7a\x31\x00\x4e\x85\x6b\x10\xf0\xdf\xa3\x4c\x73\x09\xa3\x20\x94\x18\x7d\xbc\xa2\xde\xa7\x1c\x99\x8d\x2e\x97\x23\xad\x81\x4e\xbe\x61\xb1\xc0\x55\xf9\x11\xd9\x26\x96\x44\x1e\xdb\xdf\x43\x74\xb1\x3d\xc0\x61\xa1\xf9\xbe\xeb\xcf\xef\xe4\xc8\xe9\x77\xd2\xd4\xfd\x2d\xfa\xa4\x6d\x6d\x36\x2f\xe1\x0a\xb7\x4a\x3e\xc2\x2d\x79\x2d\x44\x2b\x0b\x2c\x0f\xd0\x31\xa7\xed\xe7\x3a\x94\x69\x8f\xa9\x99\xb7\x2a\x02\xd9\x75\x71\xa3\x71\xee\x01\x42\xa6\x77\xab\x4d\xd1\xaf\xef\x5a\xc1\xb9\x6c\x60\x3f\xd5\x46\xf6\xc9\xe1\x5f\xc5\x12\x3b\xf8\xa3\xfd\x2a\xc9\x9f\xcb\x9c\x76\x82\x96\xa1\x2d\x35\xc4\x17\x7d\x99\x2e\xb3\x8d\xca\xc4\x56\x05\x5f\x7b\x1b\x93\xf9\xfd\x55\x0a\xf6\x21\x54\xb2\xc8\x52\x1e\x6f\xe9\xcb\x98\x59\x75\x31\xf7\x53\x12\x33\xea\x5c\xa0\xbe\xee\xfd\x8b\x85\xa3\xc4\x66\x9b\x31\xc5\x9f\x49\x90\xea\x19\x9d\x16\xf0\xc7\xe1\x90\x7a\x54\x81\x2c\x09\xbe\x0a\x0a\x3c\xa6\x8e\x81\x3d\x2b\xc1\x48\x45\x65\x66\xa0\x0c\x0b\x96\x4f\x46\x96\x5b\x0f\xb2\xfa\x78\x00\x4c\x96\x27\x25\x18\x54\x76\x2d\x61\x07\x81\xe6\x12\x7a\xb0\x61\xb3\x49\x14\x78\xbc\xb9\xab\x91\xfd\x71\x45\xdc\x8a\x03\x8b\x49\x80\x06\x38\x70\xd8\xfe\xfa\x4b\xdb\x21\xc0\xb8\xf6\x5b\x6d\x01\x44\x4e\xd5\xf4\x58\xb0\x5d\x14\x9d\xf9\x55\x72\x44\xf6\xd0\xfd\xdb\x6f\x04\x3b\x14\x5f\x17\x39\xd0\x49\xde\x95\x7f\x31\x70\xc8\x52\x0d\x0a\x60\xb2\xb0\xc7\xdb\x36\x2a\xa2\xd2\x87\x6d\x9f\xbc\x9b\x80\x4b\x06\x1c\xf5\x21\x60\xf2\x40\x79\x14\xc5\x52\x9e\xad\x28\x65\xe9\xbd\x46\xdd\xf5\x08\x89\x05\x92\xbf\x15\xe4\xa8\x02\x1d\x29\xfc\xd4\x0f\x49\x98\x1d\x72\x65\x39\xbc\x28\xef\xc1\x2b\x4b\xc9\xd5\x8b\xd3\x9e\xb3\x1c\xa9\x83\xc0\x9a\x7f\x03\x60\x3f\x0d\x87\xd2\xfd\x72\xc9\x3f\xec\x76\x88\xb2\x20\xcc\x58\xb7\x25\x6c\xb9\xba\x0f\x9f\x9a\xb5\x3b\xc0\x61\x67\xf0\xfc\x82\x2d\x63\x59\xbd\xb6\x06\xfb\x56\xf6\x3e\xbb\x3d\x6c\x2b\xb7\x42\xb5\x52\xcf\x55\x1f\x31\x87\x19\xbf\xe5\xa5\x27\x37\xeb\x20\x39\xd7\x09\x9e\x64\x81\x8c\x9e\x9e\x14\x71\xa5\x29\x32\x60\xcf\xa1\x2a\xe9\x6b\x73\xc2\x52\x37\xb4\x4f\xad\x2d\xe1\x85\xcf\xc6\xbe\xa7\x8f\xbd\xdd\x49\x90\xf0\x55\xe1\xc9\x28\x01\xf2\x55\x17\x9f\x20\x2e\xd9\x86\xe4\x1e\xa9\xc3\xae\x56\xae\x08\xe8\xe4\xe5\x68\xa9\xbf\xaa\xa5\xc3\xca\x76\x1d\x81\xad\x47\x2b\x3b\x19\x94\x0d\x51\x5f\x43\x30\x36\xbe\x1c\xf8\xe7\xa4\x63\xaa\x25\xf2\x91\x89\xca\x73\x3a\x09\xb1\x9c\xe8\xd6\xec\xde\x5f\xb5\x94\x66\xed\x95\x6a\x3c\x6a\x38\xd5\x2e\x5a\x42\xe5\x5a\xb0\x06\x90\x9a\xf2\x44\xda\x9d\x5e\x55\x4a\xd2\xa6\x2f\x67\x18\x54\x83\x7b\xa7\xc8\x72\x00\xe8\xf1\x6d\xc0\xc4\xbe\x6c\x7a\x77\xcd\x82\x61\x2f\x1d\x9c\x1c\x69\x5e\x6c\xf7\xdc\x87\x6b\x17\xee\x25\xa6\xf9\x85\xfb\xde\xf0\x13\x51\xf3\x39\x2a\x10\x5b\x0a\x5e\x40\x5f\xcb\x91\x78\x3d\x79\x46\xd6\x85\xfb\x7a\x0b\x02\xa2\xa7\x37\xda\x15\xec\xab\x9d\x67\x52\xb4\x45\xa5\xc5\x12\x92\x71\x09\xf7\x6a\xaf\xa5\x85\xaa\xad\x53\x37\xfd\x84\xd6\xdb\x0a\xdb\x7b\x07\x1e\xe0\x52\xf1\x7e\x3e\x28\xc1\x06\x40\x5b\x28\xdf\xb2\x9c\xdf\x6a\xb6\x40\x66\x0b\x7c\xdd\xd6\xe1\x67\x5f\xce\xea\x5b\x5d\x3e\x22\x0d\x39\xf4\xba\xb8\xe6\x32\x61\xd9\xa3\x0c\xc2\x97\xf4\xf4\xdb\x7a\x06\x59\xd5\x25\x4a\xbd\x35\x4a\xfd\x77\x3a\x43\xfd\xd7\xa2\x95\x5e\xd4\xf2\x5e\xdd\x27\xda\x0e\xbb\x66\x2d\x46\x73\xfe\x2d\x76\xf2\xdc\x2b\x74\x3f\x14\xa0\x08\xed\x7f\x5d\x5d\xe8\x71\x82\x59\xa9\x5a\x83\x43\xb4\xbf\x4f\xed\x95\x88\x43\xd8\xc7\x7f\x3c\x80\x54\x6f\x58\x61\xb3\x59\xbb\x28\x86\x1e\x2c\x7d\xd5\xb5\x75\x99\x1e\x41\xbd\x5d\xbb\x96\x08\xef\xfe\x29\x65\x9c\x7d\xa4\xec\x17\x9e\xbd\xb4\x51\x16\xb7\x93\x65\xea\xee\xc6\xfd\x1e\x34\xf5\xc1\x07\xd1\xf7\x22\xf2\xfb\xa4\x8c\xad\xc3\x87\xaa\xbf\xb4\xf5\xda\xc8\xb2\x74\xf5\x07\x1b\xa4\xc2\x4b\xbb\x7c\xbe\x14\x8f\x07\xac\x36\xf1\x1c\x87\xff\x4c\x12\x5d\xed\x16\xa3\x3f\xe3\x75\xa2\x04\x8c\x85\xa5\xaa\xf5\x0e\x63\xa2\xef\x1a\xe0\xa5\xf1\xdb\x0d\x49\x46\xdb\x54\x7b\xd9\xb1\xa0\xdf\x8d\x2b\x07\x7c\x6f\xc9\xe1\xda\xa5\xeb\x73\x84\x82\xcc\xed\x30\x7a\x09\xd6\xd6\x0e\xfa\x7e\x40\xe5\x73\x0e\x4f\xdd\x3d\x77\x51\xc3\xdb\x73\x68\xdf\xc3\x75\x20\x47\x72\xb7\xdf\x3e\xe7\xf0\x5c\xb1\xcb\x72\xba\x85\x04\xfd\xba\x3d\x28\x9f\x1b\x81\x7e\xd6\x83\x0b\xa4\x4a\x65\xd0\x6d\x5d\xf1\xf6\x07\x29\x56\x75\xe5\xc8\x23\x42\xed\xb9\x1d\xe6\x53\x6a\xde\x50\x89\x8a\xbd\x49\xfa\xb8\x69\x5a\x63\x47\x85\xa3\x3f\x9f\xb7\x98\x6e\x3a\xab\xdd\xb7\x4b\xde\x32\x5e\xa4\x33\xec\xda\xb7\xd2\xb6\xbd\x8d\x67\x76\xff\x2c\xed\xb7\x87\x55\x9e\x2b\x16\xab\x53\xb0\x1b\x9a\x3a\xba\xf0\xbc\xc4\x9e\xed\xea\xd3\x44\x8f\xcd\xed\x8c\xc2\x07\xcc\xb2\x34\x4d\xdd\xce\x5b\xdc\x04\xf6\x48\x42\x8a\x9f\x5d\xb2\x4c\x8e\xea\xb8\x5a\x3e\xb3\x7e\xc0\x65\x59\xcb\x71\x54\x27\x92\x4d\xea\x8c\x7c\xbd\xc8\x2e\x30\x26\x80\x8c\xd1\xa5\x37\x53\xf0\xd9\xac\xdd\x11\x2c\xcf\x8a\x38\xb0\xf0\xb8\x01\x11\x12\x1c\xb0\x81\xec\x4b\xcf\x6d\xd5\x5e\xb7\x21\x3b\xc6\x83\x7e\xe0\x15\xcf\xed\x0d\x41\xb2\x81\xe9\x54\x08\xff\xb1\xb5\x0a\x67\x6d\xd9\x67\x91\x8a\x31\xf0\x26\x01\xe7\x7d\x8c\xd9\x19\xae\xa3\x00\xe5\xfb\x6d\x83\x41\x31\xde\x3b\xa6\x33\xb9\xde\xa0\x95\x4a\xb8\x89\x4f\xbb\x20\xf3\x2e\xce\xae\xc3\xd7\xd0\x6f\x77\x1d\x5f\x9d\x99\x3a\x1e\x0f\x02\xf2\x4e\x61\xde\x47\x95\xdf\xf5\xf9\xf9\xe6\x0a\xe9\xe1\xee\xfd\x94\xc0\xa3\x45\xd3\xed\xda\xe8\x18\xea\x56\x45\x77\x80\xde\xdb\x72\x7b\x92\xc3\xf4\xea\xa8\xe8\xf9\xbb\x5a\x1d\xc2\xbc\xb1\x23\x0e\x67\xf5\xb7\xb6\xdc\x08\x53\xf1\x28\x77\xf2\xf1\x06\xce\xaf\x71\x96\x08\x53\x1b\x46\xe6\x79\x7c\x57\x43\x72\xcc\x7a\x15\x2e\x63\xcd\xe0\x51\xd1\x0c\xc2\x01\x94\xf8\xbc\x27\x27\x66\xde\x3f\x1b\xc7\xed\x11\x38\xd6\xf9\xf6\x31\x3f\x62\x91\x17\x48\x05\x9b\xd7\x6a\xe5\x04\xfe\x1a\x3e\xc8\x5b\xd0\xfe\x25\x5a\x9a\x6f\x12\x10\x0e\xf7\x29\xe9\x0c\xeb\xb3\xe3\xc9\xc2\xf4\x99\xf7\xa0\x4d\xf6\x38\xe5\x82\xa7\x91\xdb\x53\x3e\xdc\x0e\xfd\x10\x4e\xc8\x86\xe2\x3f\x55\x0c\x2c\xf4\xc7\xda\x15\x78\x22\xd7\x03\x46\x3f\x52\x27\x5f\xa1\x7d\xde\x88\x28\x98\xa4\x07\x08\x7f\x9e\x83\x13\xbe\x9e\x14\x92\xa3\x23\x7a\xa8\xd6\x02\x97\x9f\xb1\x5a\x25\x54\xfe\xbf\x91\x36\xd8\xc0\xe1\x0b\x13\x8e\x90\xb0\x75\xdd\xe6\x81\xc0\xf7\x95\xb0\x40\xc7\x7b\x8b\x91\x25\xc4\x7d\xdd\x8d\xc5\x3b\x21\xf3\xcb\x0d\x83\x82\xda\xb1\x13\x25\x42\x14\x19\xde\x5f\xb7\x4b\xfb\x46\xa0\xfb\x37\xa1\xd4\xa5\x8f\xf5\x62\xfd\xd2\xbc\x37\xd7\x11\x63\x93\x35\xa9\x0d\x7b\x43\xfc\x09\xad\x97\x38\xb2\x64\x60\x95\x0d\xf2\xa3\x90\x2a\x3e\x02\xe8\x4f\x68\x7e\xac\xee\xad\xe5\x00\x82\x67\x67\x68\xfb\x37\x1f\x7a\x39\xaf\xd1\x8a\xb0\x35\x58\x84\x74\x9f\xf6\x2c\x9c\xff\xac\x8d\x83\x4a\x78\x6a\xd6\x00\x3e\x43\x00\x03\x9b\xdb\x5f\xa0\x38\xea\xb5\xe9\x92\x1c\xb4\x63\x36\x1d\x90\x1e\x94\x0d\x78\xbb\x67\x6d\x9b\x20\x12\x4c\xe7\xc8\x7d\x48\x8b\x3c\xc8\xbb\xe3\x4c\xb1\x8e\x2c\x67\x74\x8b\x82\xb4\xe6\x19\x5e\xe8\x27\x2f\x15\xea\x3f\xb9\xa1\xf9\x93\x59\x81\xf5\x46\x20\xf5\x12\xe2\x3e\xda\x98\x50\xb4\x1b\x59\x4a\x2b\x1d\x66\xf7\x85\x7f\xfc\x3f\x99\xc1\xfb\xeb\x03\x91\xfc\x83\x5b\xe4\xaf\xa2\x0d\x0c\xe3\x54\x79\x65\xeb\x33\x63\x9a\xac\x33\xcf\x55\x4a\x24\x2c\xe4\x2a\xd1\xe0\x8c\xee\x1a\xb6\x12\x39\x0a\x64\xd1\x90\x3f\xbf\xfd\xd4\x70\xac\xfe\x6a\x4e\x62\x70\x60\xc9\xc9\x7a\x11\xa2\xf9\x3f\x01\xe0\x3f\xf7\x80\xef\x9f\x81\xfc\xc7\x34\x33\x5e\xfe\x52\x71\xe6\xb4\x0c\xb9\xb3\xfa\x37\x90\x39\x2a\x59\x24\x49\x7f\x05\x22\xcf\x5e\x8b\x41\x10\x2a\xce\x40\x6b\xc6\x5f\x95\x90\x15\x33\xb2\x2f\x44\xc5\x4b\xfb\x75\xc6\xd5\x04\xaa\xbc\x6f\xdd\x8f\xa0\x07\x3c\x6e\xe3\xf8\x88\xd7\xdb\xed\xaf\x36\x2b\x57\xa0\x2a\xd3\xa8\x8d\xc5\x05\xbd\x08\xb3\x08\x4a\x3f\x9f\x7f\xe5\x41\x3e\x01\x20\xec\x3b\x63\x01\x77\x2c\x7a\x0a\x17\x67\x21\xb7\xc7\x21\xd7\xf8\xb0\x93\x07\xc1\x20\xb4\x9d\xdd\xe3\xda\x23\x9b\x99\x9f\x24\xff\x94\x15\x0c\x86\x49\x91\x8f\xc0\xf6\x30\xd8\x53\x72\x56\xfb\xad\x52\x5c\x88\x0c\x7c\x04\x27\x12\x94\xff\xb8\xcf\xab\xcc\x51\x96\xeb\x9f\x6f\xe4\xeb\xf0\x70\x8a\xc2\xee\x66\xe4\xfe\x9d\x31\xe5\x2a\x6d\x00\x4f\x6d\xce\xed\x63\x0a\x43\x30\xf2\xfc\x2a\x97\x9f\x0e\xc8\x5c\x8f\xa0\xb4\x24\x36\xc1\x79\xfc\x96\xc6\x83\xc5\x73\xd6\x05\xb0\xf6\x2b\x58\x07\xc8\x0d\xc9\x11\x28\x8b\x97\x47\x6d\xfb\x4c\x64\x29\x34\x32\x52\xb7\x71\x45\x98\xff\x91\x58\x22\x70\x0e\xa8\xf0\xfc\xd9\x3f\x45\x69\xb8\xa8\x04\xa2\x0f\xec\x12\xd4\x42\xe9\x62\x14\x5f\x00\xa1\x12\x14\xb8\x08\xed\xd5\x20\x6a\xc9\x3f\x14\xad\x06\xc8\x98\x65\x01\x90\x74\x29\x10\x40\x4e\x01\x5f\xde\xc3\x87\x7e\x73\xd3\xa7\x05\x0b\x98\x2a\x8e\xcc\xca\xa8\x67\xeb\xfb\x63\x00\x13\x15\xe0\x0a\x0a\x40\x47\xe4\xff\xf1\x16\xd6\x1f\x5e\xbe\xd2\x1a\x9f\x1d\x5b\xfb\x08\x06\x80\xa0\xe6\xc5\xad\x08\x09\x6b\x2f\xd5\x87\x17\x52\x8c\x09\x1a\x83\x3c\x1e\xd9\xa7\xe4\xa0\x49\x14\xe8\x14\x87\xcc\x71\xb1\x7e\x9e\xea\xaa\x01\xc8\x03\x79\x00\xf5\x37\x47\xa0\x97\xb0\x33\x98\xa5\x28\xe1\x6c\x00\xbe\xf3\x56\x60\xa0\x3b\xfd\xdf\x4d\x1d\x68\x1a\xe1\xfe\x0f\x40\xbb\xf5\x27\x62\x0d\x86\x2c\x80\x9d\xf3\xa4\x2c\xc8\x99\xed\x18\x5e\xe2\x0f\x3c\xfd\x2e\xe5\x89\x8c\x7b\x37\x6e\xd5\x78\x15\x54\xb3\x61\x84\xfe\x18\x5f\xb4\x94\x54\x86\xef\xe0\xa6\x23\xc9\x78\x04\x9d\xe0\x41\x36\x81\xce\xdc\x79\x05\xc4\xf4\x8f\x03\xb5\xad\x3b\x82\x03\xe6\x11\x40\x06\x39\x72\x58\x43\xc2\xdd\xf9\xb0\xc9\x7e\x93\x68\xc2\x9f\x0f\x5d\x16\x7b\xb8\x7d\xb3\x1c\x15\xb0\x8f\x51\x2b\xc0\x54\x73\x8b\x69\x18\x99\x01\x57\x58\xd8\x9f\xda\xee\xce\x20\xa7\x12\xb4\xe5\xc2\xc3\x2d\x51\x0d\xe4\x0e\x03\x74\xd0\xfc\x43\xbd\xaa\xa5\x77\x6e\xe3\x6f\xfa\x24\xe9\x40\x6f\x1a\xcf\x66\xd7\x13\x0a\xf6\xc1\x25\x37\x7c\x79\x96\x63\xd6\x0d\x9b\x1f\x86\xa1\xaf\xee\x6e\xf9\xdc\xf2\xfb\xe6\x51\xef\x9f\xf0\x75\x3c\x6f\x77\xcc\x0f\x7f\xfe\x9e\x1d\x87\x07\xf7\xb7\x01\xf5\xcb\xcf\xe9\x9c\xc3\x3e\xa7\x5b\xde\xc4\x25\xac\x79\x1b\xff\xcc\xfe\xa5\x3f\x83\x36\x84\x13\xb9\xf1\xfe\x83\xea\xd5\xbe\xa9\xf0\x37\x48\x0a\x39\xef\xe0\xc4\x9a\x68\x18\xf0\xbf\x73\xf5\x79\x99\x4a\xcc\x44\xc0\x59\x70\xca\x03\x20\x0e\xfe\x69\x25\x75\x22\x14\x1c\xbe\x68\xd0\x3f\xc4\x5a\x08\x71\x6b\x38\xd8\x3c\xc8\x5e\x00\x2e\x5a\xec\x85\x9d\x9b\xfe\x1c\x03\xbf\x34\x49\x95\x08\x8a\xd6\x9b\x6c\x84\xbd\xfe\xd7\x9c\x13\xba\x29\xa0\xac\x59\xc8\x9d\x32\x6b\x1c\xd0\x11\xf5\x73\x00\xbf\x2a\x24\xaa\xb1\x5c\xe9\x5d\x0f\x5b\xd5\xe4\x5f\x85\x79\xcc\x08\xde\xf2\xe5\xbf\xd9\x0a\xd5\xf3\xd5\xba\xda\x8d\x95\x40\x79\xfe\x4b\x2d\x9a\x0c\x22\x1b\xa1\x84\x25\x44\x21\xbc\xaa\x58\xef\xb2\x96\x9d\x92\x8d\x77\x51\xf7\x45\x1a\x37\x15\x2d\x1b\xbb\xd0\x98\xce\x84\xb7\xe7\xeb\x9c\x81\x28\xf4\x28\x51\x7f\x7a\xe3\x54\xe5\x65\x9d\x8c\xa3\x5f\x5f\x5b\x26\x43\x22\x51\x44\xe3\xc5\x1f\xff\x4b\x8e\xda\xf7\x3a\xfb\x4b\x59\xe8\x6b\x7c\x53\x80\xfa\xd8\xb9\xea\xf6\xaa\x26\x82\x2f\xb9\x9e\xbd\x46\xe8\x4e\x7e\x3c\x7a\x91\x44\x71\x51\xe7\x1f\xeb\xf0\x7b\xd2\xbe\x26\x35\xbe\x4d\x7a\xc2\x5e\xd6\x03\xbf\xdc\x60\xd0\x1b\xdb\xc4\x93\x85\x86\x89\x16\x4d\xc0\xa3\xf0\xcc\xf7\xf7\x1c\x59\x57\xf9\x3d\x55\x15\xb6\xa0\xcf\x44\x49\xa2\xb5\xfb\x5a\x34\x90\x38\xec\x82\x7e\x8b\x8f\xbe\xbf\xd9\x66\xf8\xf9\x21\x41\x6b\xbf\x58\xbf\xf9\x75\x79\x89\xea\xd7\x72\x82\xb7\x64\x76\x7f\xb3\x26\x69\xbf\x99\x7a\x1f\xb6\xe5\x74\xc4\x82\xfd\xd4\x2b\x5e\x7e\x02\x13\x83\xcf\xdc\xaf\x3d\x6a\x36\x29\xa2\xa8\x35\xa5\x9d\x5c\xc8\x9a\x70\xd5\xdf\x24\x98\xc1\xaf\x5b\x34\x29\x18\x42\x60\xc7\x65\xae\xd9\x29\x8c\xff\x16\xef\xbd\x50\xdc\x0d\xd6\x2b\xb4\x26\x79\x95\xc4\xe4\xf0\x08\x37\x00\x77\x6e\x5b\x95\x2f\x66\xfc\xc5\xe8\xb0\xbc\xb9\xb4\x41\x4e\xd8\x90\x69\x1e\xb5\x35\x27\xbd\xff\x25\xae\xc3\xbb\xa8\x7a\x3e\xba\xdd\x60\xaa\x1c\x07\xf4\x70\x92\x64\xe7\x9a\x4d\xec\x7e\x90\x00\xd2\x7c\x39\x52\x8c\xff\xc9\x44\xd1\x42\x31\xb2\xb6\xd6\x5c\x17\x71\xc7\x65\xaf\xba\x9a\x16\x43\x2f\x40\x27\x42\xa7\x95\x78\x0f\x67\x7e\xe3\x62\x77\x00\xdf\xe6\xac\x12\x1d\xfa\xf4\x12\x7d\x65\x75\x60\x41\x25\xd5\xac\xcd\xd5\xb6\x7d\x0b\x09\xc8\xca\x4a\x01\xf5\x23\xc8\x22\x80\xf0\xed\xf1\x4d\x2d\x14\x3a\xf9\xc6\x16\xe0\x3b\x8f\x6c\x76\x74\x6e\x37\xfb\x05\xbe\xa6\xb1\xc0\x0e\x5e\x47\x88\x16\x7b\xdc\xc7\x45\x50\xa3\x1e\x36\x15\x51\xd1\xa5\xd8\xed\x27\xf2\x72\x68\x9b\x44\xb8\xfd\x33\xba\x6f\x2d\x63\xd4\x08\x27\x6a\xb5\xdb\x1d\xbf\x8a\xe9\x70\xad\x40\xaa\x43\xda\x95\x2f\x61\x87\x3b\x65\xcc\x41\x0a\xe1\xbd\x02\xe0\x93\x6f\x6c\x28\x1e\x3d\x98\xa9\xed\x32\x9c\x0e\xc2\x91\xef\x2e\x28\x20\xe4\x45\xc0\x6d\x5b\xcc\x0c\x54\xbf\x29\x09\x27\xce\xc7\x12\x2f\x34\x36\x3b\x6b\xbe\x1b\x08\x00\x80\x85\x70\x9f\xf7\xb3\xdf\x82\x5e\xc3\xb8\x95\x61\xf4\xee\x07\xf6\x9e\x0e\xb7\xe0\x59\xda\x85\x57\x4a\xbd\xab\x49\xee\xc4\xe8\xfc\x39\x32\x40\xc6\x17\xfd\x0a\x07\xcd\xfe\xb0\x6e\x72\x04\x36\x79\x00\x89\xde\xfe\x6e\xcb\x7e\xf8\xb5\xa1\xc6\xed\xaa\x75\x40\xe4\x1c\xe5\x49\x88\xa7\x35\x9a\xd0\xb3\x8c\x31\x69\xc8\xcb\x76\x91\x39\x62\xf9\xe7\x53\x1d\xfa\x90\x59\xf4\xb6\x14\x7d\x1b\x25\x11\x0e\xba\x88\x2f\x7c\xa8\xd9\x61\xae\x13\xfc\x92\x0c\x19\x17\x4e\x9e\x07\x77\xac\x3f\x2a\x59\xa4\x42\x75\x06\xaa\xa1\x3d\xc8\x12\xd1\xc4\x85\x61\x93\xd4\xe8\xc7\x43\xf2\xdd\x8d\xcf\x0a\x7b\xfb\x81\xc3\x24\xa7\x3f\x2f\x9a\x2c\x5a\xa0\xad\x33\x6e\x96\x91\x2f\x83\xcd\xe0\xdb\x60\x67\x80\xdd\x3f\x55\x7d\xef\x22\xb3\x33\x8b\xfc\xb2\x3a\x29\x24\x4c\xd7\xfb\x4d\x5a\xa8\x3d\x08\x5f\xdd\xa8\x22\x68\x5f\xd5\xf6\x7a\xe8\x04\x0f\x25\x7a\x79\x58\x2f\xaf\xf5\xa3\x93\x13\x80\x7a\x37\x7b\xba\x65\xc0\xbb\x91\xd4\x3b\xca\x85\xef\x54\x14\x57\x51\xa2\xdf\x94\x0e\xbb\x4c\xb8\x4e\x37\x75\xe4\xc8\x58\xd4\xd8\x65\xd0\x27\x15\x67\xf2\xf5\x48\x5c\x3a\x05\xda\xf2\xcc\x4b\xb7\x4b\xda\xa5\x2f\xba\xd2\x3d\x98\x51\xec\xd4\xfa\x29\x81\xb2\xe0\x4c\xbc\x1e\x02\x1c\x7e\xa6\x40\x4d\xbb\xbe\x5b\x0f\x85\xf9\x2f\xde\x88\x1b\x94\xf8\x49\x83\x8d\xe2\x1c\x93\x3c\x92\xef\xd7\xa7\x3f\x4f\xe9\x6c\x8b\xb5\x2b\x3f\x3c\x6d\xe4\x14\x5a\xd0\xf0\x76\xec\xd3\xd4\xdf\x96\x18\x3d\x46\x03\xa8\xc3\x7a\xfc\x74\x2e\x76\xff\xc3\x79\xe9\xf3\xb2\xd1\x0d\x5b\xac\xdb\xfa\x42\xd1\xf3\x54\x81\xdc\x66\x91\x61\xca\xf5\x0c\xfb\x7a\x0f\x48\x7d\xd8\x80\xd9\xac\xea\xe2\xbe\xae\x36\x4a\x85\x08\xc2\xe2\x9e\x99\x58\x90\x35\xc5\x7a\xba\x23\x23\x0b\xaf\x1e\xdb\xb7\x85\xb2\xf8\xd9\x9d\xe2\xab\x8a\xc9\xe2\xa1\x3d\x2e\x9f\xa4\x6c\x1d\x8d\x76\xe2\x2f\x89\x38\x91\x90\x07\x61\x46\xf2\x12\x9f\x31\xf9\x78\xc6\x93\xef\x34\x17\x91\x5c\x7a\xad\x84\x3f\x65\x93\xf7\x9c\xc2\xa8\xd4\xa2\xe7\x33\x76\x56\x81\x03\x90\x5b\x8e\x5d\x18\x8b\x27\x38\xa1\x64\xb4\xd8\x44\x28\x54\xc2\xc1\xef\x2c\x97\x4e\xd5\x66\x3c\x2e\xa1\x89\xb5\x36\xc8\x5c\x7a\xb8\x89\x5c\x72\xaf\xc8\x80\xe4\x02\xaa\x1e\xd9\x31\x64\xcf\x40\x14\xa2\xf2\x63\x5a\x2f\x3a\xf8\xa0\xfe\x0c\x99\xc8\xa7\x94\xd1\xa5\x55\xf7\x84\x14\x16\xfb\xda\x27\x3d\xc2\x9e\xb7\xc1\xda\x33\x34\x5c\xa5\x58\xde\x31\x1c\x58\x94\x42\x94\x63\x2d\xf6\x29\x3c\xf9\xf3\x3e\x23\x54\xa8\xd4\xd9\x3f\xd3\x28\xf1\x72\x8c\x8f\x64\x53\x5c\x36\x45\x56\xd0\x4f\x01\x33\xb0\x06\x99\x18\xff\x7c\xec\x29\x0c\xed\xc2\xdd\x8a\xb9\xd6\xb6\x39\x2c\x07\x35\x12\x5d\x46\xf2\x56\x80\xf1\x1e\x53\x55\x99\xce\x6f\x09\xed\x6e\x6c\xd9\x45\x8b\xc5\x17\x18\xb6\x5c\x1c\x44\x41\xdc\x3f\x64\x72\x9c\x01\x1b\x21\xc8\x36\x9f\x7d\x48\xf2\xe4\x93\x7a\x8b\x58\xba\x29\xb2\x81\x8d\xf8\xe1\x4c\x18\xef\x22\x82\x81\x82\x75\x46\x97\x92\xca\xe0\x4a\xf0\x4f\xb5\x67\x41\x9f\xb5\x4d\x92\x35\xe7\xd5\xb2\x71\xef\x20\x91\x1b\x11\x7b\x9c\x2f\x5e\xcc\xfe\xf8\x3f\x34\x19\x65\xd0\x58\x75\x72\x59\x43\x18\xcb\x9e\xfb\xf8\xad\x15\x8f\xd4\xd4\x25\x38\xb2\x34\xd3\x8f\xba\xee\x69\x83\x81\xee\x79\x8b\x82\xd4\x32\x7f\x55\x85\xb2\x9b\x29\xef\x8c\x86\x6b\xe7\x0d\x91\x67\x39\x0e\xba\xb2\xba\x57\x41\xed\x85\x9d\x5a\xb3\x7c\x1f\x52\x68\xd8\xd3\xf3\xe2\x00\xeb\x10\x98\x45\xf7\xab\xf6\x4a\x51\xee\x2f\x98\x67\x91\x3e\xf4\xb4\xfb\xd5\xcf\x96\xab\x60\xbe\xaf\x1d\x84\x36\xb3\xc7\x11\x9c\x98\x47\xe5\xd7\xb8\xfa\xf5\xb9\xba\x26\x16\x6f\x67\xb6\x82\xa8\x60\x63\x04\x59\x13\xd0\xb0\xcd\x9d\xb8\x0f\xe7\x53\x87\x56\xac\x6d\x27\x8e\x5c\x77\x2a\x61\xee\x4e\x97\xf6\x7d\x04\x1d\x67\x51\x5a\x82\xaf\xe7\x3a\x6d\x17\x5d\x55\xb7\x91\x5c\xea\xea\xeb\x24\xe5\x8c\x5c\x1d\xec\xb6\xf4\x69\x42\x8d\xc5\xa9\x3a\x73\x65\xe5\x04\x13\xba\x2b\x95\xd8\xe3\x44\x00\xba\x8f\x76\xb0\x0e\xb8\xc2\x3a\xa2\x2b\x35\x37\xee\x28\x43\xcb\x63\x96\x9f\x83\xb3\xb5\xae\x78\x39\xdd\x59\x3c\x55\xd8\xa4\x2b\x1a\xbd\xbb\xd2\xb7\x44\x8d\x79\xa3\x75\x19\xd3\x38\xa6\xad\xa9\x3f\x63\x7f\x2a\x9d\xf9\x43\x32\xc6\xf8\x56\x41\x1c\x12\xf0\x62\xf4\xec\xb0\xfa\x4a\x9b\x1a\xff\x91\x80\x87\xf1\x5c\x66\x3c\x8d\xaf\xba\x3f\x6c\x65\xea\x8e\x01\xce\xe2\x49\x31\x58\xb6\xc1\x0e\x1a\xea\x21\x79\x89\xe2\x8e\xcb\xc2\xfb\xf2\x67\x30\x79\x76\xad\x63\x82\x35\xf4\xd6\x04\x40\x85\x95\xb7\xce\x96\xb6\xc6\x36\x2a\x6b\x38\x04\x21\x28\x58\x42\xe8\xd8\xea\x17\x85\x82\xfb\xf8\x2b\xfa\x92\xab\xc7\x93\x94\x62\x33\x83\xa2\xaf\x6c\xe3\x78\x67\x07\x55\x12\x10\x11\xc0\x08\xf8\xe7\xa0\x07\x29\x6b\xcd\xca\x3a\xe5\x50\x98\x11\x8c\xe2\x9f\x4a\x36\x3e\x38\x39\xce\x89\x48\xa2\x0f\xb9\x1e\x2d\xa3\xfc\x96\x11\x7e\x97\xa1\x59\x59\x19\x46\x2e\xc2\xc7\xfd\xf0\x10\x64\x04\xd9\xdf\x2d\xc4\xda\xb1\xce\x52\xd1\x77\xde\x8a\x9c\xa6\x23\xec\xb0\x4a\xcd\xf7\x89\x5b\x5f\x7f\x2b\x3c\xd1\xa7\xb8\x5e\xe1\xf5\xf8\x08\x3e\x91\xee\x08\xd7\x97\xe7\x39\xda\xaf\xb2\x52\x7e\x1f\x61\xec\x2c\x5d\x5c\x9d\x76\x74\x90\xb8\xef\x4f\x92\xff\x4f\x9f\x4e\xcc\xa0\x73\x1d\xaa\xfe\x7c\xde\xc9\x4d\xf3\x2e\xc9\xbf\x26\x81\xe0\xc1\x20\xe6\x53\xe4\xff\x04\xb2\x1f\x2b\x25\x51\xac\x6d\xcf\xf6\x8c\xce\x08\x3c\x9f\x4d\x69\x4c\xbb\x5d\x50\xef\xa9\x7d\x60\x8b\x95\xe0\x89\xaf\x94\x4f\x17\x7c\x1f\x02\x4e\x3d\x20\x81\x00\x48\xd3\xd0\x5b\xdf\xfc\x2f\x6c\x51\x3f\x10\xbb\x07\xc8\x7a\x9d\x11\x62\x7d\x0a\x7a\xac\x08\x25\xc0\x6d\xcf\x7f\x9d\x2f\xb8\xba\xbd\xe8\x43\x91\x0e\xfb\x2a\xe7\x21\xca\xc9\x3b\xfe\x30\x30\x85\xae\x6f\xd2\x10\x9e\x9e\xe9\xf6\x37\x68\xcb\x66\xd3\xe4\x20\xa5\x6c\x6b\x65\x1a\x6d\xdd\x2d\x1e\xbf\xee\x84\x56\x81\x1f\x74\x4e\x81\xf2\x45\x0b\xeb\xbd\xc1\xc8\x81\x26\x7e\x0c\x8b\xd2\xc1\xbf\x09\x43\x10\xf2\xaa\xab\xb2\x6d\x30\xa7\xca\xf2\xb4\xd1\x34\xb8\x47\x0e\x65\x4a\x15\xcc\x88\x3d\x5e\xe2\x00\xdb\xa7\x4c\xf5\x84\x97\x6e\xfc\x3e\x86\xad\x20\x0f\x75\x63\x0c\x69\x4e\xf1\xd9\x6f\x4a\x4f\x58\x47\x23\x1e\xa7\x4a\xfc\x19\x45\x5c\xb2\xc8\xb2\x4d\xc5\x28\x48\x4b\xbc\x7e\x2e\x9d\xce\x2f\x24\xf1\xd5\xd2\x83\xd3\x3a\x8a\x87\x41\x33\x86\xf2\xba\xcb\xd9\xeb\x7d\x20\x8b\x54\xfd\xfa\x29\x6d\x95\xee\x53\xa9\x56\x36\xb2\x6a\x86\xd6\x42\x58\x84\x5f\x3d\xc1\xca\x81\xe2\xf2\x53\xda\x83\xe3\x03\x66\xef\xb0\x55\x11\x5d\xdf\xa1\x8a\xb9\xed\xf9\x9f\x6f\xb0\x98\x4e\xb6\x0d\x96\x38\xef\x64\x98\xfa\xf6\x36\xa8\x5e\xdf\x0d\xb5\x6c\xde\x8f\x64\xcf\x05\xf8\x91\x68\xfa\x30\x42\xbd\x7b\x8e\x56\xa0\x19\xe9\xb7\x1e\x9c\x20\x2c\x41\x18\x6b\x61\x8d\x2b\xc2\x56\xba\xf7\x76\x7f\x4a\xa3\x7f\x48\x7f\xdc\x9c\x6f\xf4\x95\xda\x47\xbe\x50\x12\xea\xb1\xfd\xca\xeb\x30\x58\x96\x10\xca\xc7\x83\x38\x53\xa7\xc6\x5a\x2f\xea\x74\xb7\x44\xce\x58\x5f\xb7\xab\xb3\x27\x0b\x4b\x21\x54\x0c\x07\xe6\x22\xd6\x40\x67\xc9\x3f\xdf\xe2\x66\xfb\xe2\x01\xbd\xb3\x57\xf7\x5a\xcc\x35\x71\x77\xf8\xfc\xb4\x05\xd7\xba\xf4\xa7\x7e\x48\xe2\xd3\x04\xf8\x00\xa1\x48\xe4\x26\x9b\xe3\x8b\x62\x24\x0e\x19\xbc\x53\xb3\x98\x48\x6b\x98\x3b\xa4\xb5\xea\xe4\x73\x08\xb1\x6d\xb0\x8a\xde\xa9\xda\x5c\x48\x7a\x3f\x4e\x60\x49\x5d\xa8\xf9\x7b\x99\x5e\xf1\x34\xc9\x0f\x0c\x58\x99\x26\x60\x0c\xd6\x88\x99\x80\x85\x3a\xb4\xc1\x8f\xd0\x5c\x55\x04\x16\x7c\x24\xb2\x90\x0e\x67\x74\x3b\x1f\x91\x0d\xce\xf4\xf7\x07\xa9\x4a\x3a\x1a\xf3\x6d\x51\x55\x40\x2e\x24\x31\x89\xa4\x9c\x13\x62\x35\xce\x00\x3a\x5f\x09\x42\x90\x1e\x8e\x00\xec\x78\xd4\x89\x0c\xe4\x3a\xfc\x22\x2f\x49\x79\xbf\x34\x9c\x96\x36\x5b\xc0\x73\x1a\x49\xdf\x36\x40\x3e\x51\xb1\xa7\x01\x2e\x2f\x08\x4e\x89\xea\x59\x4e\x2d\xe0\xf6\x55\x5f\x12\x67\xad\xd9\xbe\xec\xba\xd0\xe0\xde\x72\x31\x31\x74\xc9\x70\xdd\xc1\x4d\x61\x51\xba\x81\xf1\x74\xcf\xa8\xe8\xa8\x22\x4f\xa7\xa6\x2c\x8d\x98\x56\xbc\x07\xa1\x29\xce\xad\x5d\x01\xbf\x6c\xd3\x29\xd9\x95\x06\x0f\x79\x58\xd0\x36\x53\x55\x6e\x43\x38\xdf\x61\xb7\xc7\x02\xb6\xb7\x86\xb0\x22\x85\x36\xd9\x1f\xaf\xed\x34\x8a\xa5\x6d\x13\x4b\x9e\xa2\x3d\xf2\x07\x0f\xb2\x81\x98\x77\x43\xe3\xe5\x7b\x7e\xf3\x28\x83\x81\x91\x76\xb5\x2d\x63\x24\x0c\x2d\x0f\xe5\x2f\x3c\xfe\x92\xa2\x35\xf6\xf2\xb1\x6a\x50\x05\x7b\x38\x71\xca\xd1\x9c\xbe\x2f\x6f\x3d\xdc\xc4\xc4\x9e\xda\x50\x9f\xe7\x7e\x12\xa9\xd4\x70\x6a\x4f\xf3\x25\x21\x65\x71\xe8\x28\x35\xd4\x47\xf5\xef\x12\x7d\x4a\xef\x0a\x2b\xe7\x26\x7d\xfc\x8c\x1c\xb4\xc0\x1d\x47\x5d\x27\x45\xac\x39\x69\x63\x19\x43\x58\x23\x58\xd8\x84\xed\x44\x83\x65\xc3\x2e\x58\x56\xbc\x46\x69\x6b\x94\xf1\x38\xb7\xaa\xd5\x33\x0b\xdb\x38\x79\x41\xdb\xdb\x65\x3a\x30\x56\x26\x5c\xea\x07\x2e\x4e\xe2\x69\x0a\x6f\x74\xc4\x00\x85\xbf\x14\x77\x1b\xd7\xcb\xd2\xe5\xb5\xb0\xf4\xf1\xdb\x05\x65\x4c\x4c\xbd\xe8\x19\xd0\xde\xbc\xaa\xc3\x21\xcf\x24\xcb\x78\x4c\x4a\xcc\x01\x8f\xed\x4b\x91\x1c\xaa\x2c\x19\xcf\xdc\x0e\x48\x30\x5b\x1e\x18\xcc\x9b\xfd\x9a\xf9\x83\x7a\x8f\x65\xf7\xc0\x10\xf2\x93\x58\xe6\xd7\xb6\xda\x11\x60\xb2\xa7\x6f\x0d\x32\x2c\x16\xcc\xda\xea\x50\x9e\xb6\xcd\xa9\x37\xdb\x4c\x5d\x65\x12\x7f\xb6\xd9\x99\x94\x0f\x39\x13\x90\xd6\x05\x3c\x7c\xf0\xc1\xa2\x11\xa7\x81\x19\xd0\x22\x0d\xfe\x95\xf7\x3e\x6a\x58\xd9\xd1\x79\x8f\x70\x2d\xf8\xab\x64\xad\x11\x78\x56\xbe\x15\x12\x8a\x30\x9c\x8e\xd7\xac\xbf\x66\xa6\x05\x62\x2a\x19\x5b\xa1\x5c\xe2\xe2\x66\x62\xdd\x26\x2c\x13\x0f\x22\x8d\x2d\xe1\x62\x6d\xd3\xb8\xb3\xea\x64\xa5\x19\x4b\x3f\xa2\x5e\xe5\xe9\xe4\xa7\x4e\x10\x64\xb1\xab\xe6\x1f\x32\x35\x80\xc0\x93\xc7\xf5\x9b\xc4\xc2\x92\x1a\x3a\x59\x58\x1e\xf0\xe0\x2a\x74\x6f\xf7\x4a\x75\x6e\x90\x95\x42\x5f\x3d\xb3\x53\x75\x82\x4f\x3d\x0a\x7e\x91\x86\x90\x84\xa5\x18\x20\x2a\xcf\xce\x3d\x9a\xe9\xff\x82\x18\x68\x16\x92\xa8\x2a\xb3\xea\x9c\xef\x5f\xab\xe5\x3c\x25\xd2\x09\xb4\x27\x81\x33\x2c\xf6\x42\x03\x2f\x3e\x39\x58\x7e\x6a\x8d\xd8\xea\xa9\xf1\x6e\x86\x91\xdf\x4b\xcd\x82\x42\x7e\xd0\xb4\x9c\xe4\xa1\x2b\x87\x27\x44\xd7\x39\x39\xcc\x81\x46\x09\xce\xcd\x9a\xca\xe1\x00\x99\xbf\xcc\x15\xc7\xbf\xbc\xfd\x9d\xae\xa1\xf6\x97\x56\xa8\xf8\x3a\x41\x8b\xbe\xb7\x7f\xf0\x11\x60\x81\xe2\x3a\xfb\xb2\x4f\xa0\x6c\xa0\x51\xce\xe2\x9b\x0d\x90\xd7\x8b\x45\xd6\x2b\x7b\x19\xcd\x39\x5b\xdc\xda\x38\xc3\x15\x5d\xb0\xb7\xf0\x9d\x17\xdd\x1a\xae\x1f\x08\xdf\xbb\xfb\xc1\xcf\xbc\x03\x23\x68\x3b\xbd\xfd\xa0\x31\x83\x3c\x0e\xb6\x4a\x78\x76\xd6\xd6\x8f\x1b\x24\xd8\x7c\x56\x6f\x80\xfe\x15\xf9\x54\x45\x2a\x48\x1f\xef\xe6\x49\xec\x9a\x9e\xbc\xeb\x2c\xb2\x0f\x79\x79\xc4\x8f\xf5\xeb\xcf\x20\xf7\xf4\xe6\xfe\x60\x0d\x46\x93\xcc\x8f\x32\xf3\x4f\xac\x6c\xc3\xdb\xc1\x09\xb8\x72\x7a\xe8\x7b\xbe\x1c\x7e\x88\x16\xe1\xc6\xce\x74\xb8\xfc\x0c\xae\xdd\xfc\x20\x1f\x4c\x9d\xe1\x67\x08\x32\xd8\xc1\xcd\x96\x55\x78\xff\x78\x4d\xdc\x5f\x94\x85\xfb\x87\xca\x6b\xb0\xe7\x89\x62\xdf\x27\xf3\x8f\x72\x40\x45\x48\xfb\x5b\xab\x17\x65\xeb\xad\xbc\xc9\xf9\x5e\xa3\xbc\x20\x0e\xeb\x5c\xe5\x90\x53\x4d\x43\x3f\xc9\x87\xb8\x8f\xbc\x65\x91\x57\xe7\x4a\xf7\x9a\x14\x50\x14\xf4\x93\xc4\x89\x02\x0b\xd5\x57\x70\xf8\x0d\x2d\xb4\x79\x67\x0f\xe5\xfe\xfd\xde\xae\x97\xdd\xc7\xbe\x28\x0d\x66\x18\xb7\x07\x2f\xde\x9b\x3a\x0f\xb6\xe9\xb9\x7f\x82\x75\x12\x79\x58\x60\x2b\x79\x50\x1d\xd8\xde\xa3\x43\x9e\xff\x82\x17\xb6\xb7\x41\x2d\x63\xc5\x08\x5b\xdf\x94\x38\x6f\x71\xc7\x54\x71\x79\xe7\x8f\x7f\x8c\xfb\xae\x71\xc7\x76\x04\x9f\x8c\xda\x56\x6f\xcb\x6a\x8f\x14\xc6\xe0\x6f\x8d\x0f\xef\x7b\x58\x72\xaa\x58\xf7\x10\x4f\x8c\x42\xb3\x6f\x8c\x37\x2d\x91\xd3\x6f\x5c\x34\xbd\x19\x05\x62\x79\x66\xa4\xea\x0d\xe1\x49\x98\x53\xaf\xe8\x7c\x66\x37\x34\xcb\x29\x27\x8b\xa5\xc0\x58\x47\xb7\x72\xa2\x17\x74\xda\x55\xa0\x34\x2d\xd1\xcd\xa2\x94\x7d\x6a\xe9\x17\x66\x17\xb9\x72\xb8\x58\x8b\x53\x38\x6b\xa7\x74\xbb\x49\x0b\xa3\x29\x03\x5f\x28\xa1\x73\x0e\xf0\x93\x8b\x12\x80\x55\x66\x3f\xc4\x3b\xf6\x4a\x73\xe5\x9b\x72\x36\xdd\x62\xa2\xe7\x42\x5f\xdc\xb0\xf5\x02\x34\x78\xf7\x12\x20\xdf\xee\x32\x26\xef\x78\x73\xe7\x82\x42\xb2\xd7\xb0\x46\x4f\x55\x1d\xb6\xa9\xd5\x10\x67\xd3\xc0\x9a\xc0\xff\xf6\x17\x96\x3c\x58\x13\x3d\xae\x2d\xc8\x5f\xd7\xca\xf1\xe1\xb8\xb8\x86\x71\x5c\xa0\x53\x23\xf8\x14\x09\x57\x42\x91\xd6\x5f\x3a\x49\x0f\x06\x2f\xad\xa3\x3e\xf7\x81\x6c\x5f\x9d\xe8\x71\x36\x90\xce\x84\x34\x0c\x5a\xbb\x8d\x08\x83\xbe\x0e\x4a\x61\xc9\xcb\x32\x16\xca\xd1\xe2\x64\x81\xe5\xd8\x48\x29\x3f\x20\x86\xbe\xb2\x23\x82\x63\x81\xf6\xf5\x50\xf9\xc9\x94\xe0\x85\xd3\xe3\x14\x07\x40\x64\x98\xb4\x36\x7a\x37\x29\x7c\x45\xd4\x08\x66\xe7\x27\x8e\xc5\xe7\x30\xcf\x40\x42\x78\x44\x24\x64\xaf\xff\xee\xa2\x92\x61\xe6\x1c\xa6\x1b\x80\xa4\x85\x19\x08\x5a\xad\x34\x5c\xac\x01\x3a\x13\xfb\xaa\x03\x55\x42\x59\x6d\x2c\xc2\x13\x1e\xf0\x6e\x03\x7a\x9f\x24\x38\x2e\xa5\x1c\xf8\x25\x3c\xf0\x89\x2a\xff\x12\xac\x14\x3b\xee\xf9\x40\xf5\x75\xe3\x4a\xdb\x31\xd6\x75\xf8\x63\x20\x49\x0c\x4b\xa1\xbc\x98\x43\xb1\x99\x44\x65\xdd\xd9\x24\x49\x14\x38\x4c\x24\xb6\x53\xb1\x4f\x3c\x74\x7c\x16\xf3\x6c\x48\x9f\xa0\xd8\x61\x7e\xc5\x80\xb4\xb6\x7f\x87\x2c\x45\x0f\xd7\x25\x2e\x32\xc0\x39\x5c\xb8\xdc\x03\x39\x93\xf2\xfd\x79\x76\x60\xf2\x91\xfe\x8d\x7e\x2b\xf2\x0e\x12\x10\xe6\x70\x64\xa4\x07\x50\x1e\xe1\x4b\xad\xac\xa6\x31\xad\xbb\x90\xef\xf1\x96\xf9\x49\x2f\x12\x4b\xf7\x6b\x71\x9b\x25\xef\x08\x6c\xfe\x06\x3b\xa2\x28\x11\xed\xd6\x4b\xb7\xf4\xe9\xc8\xf9\x70\xf1\x95\x9d\xad\x4e\x94\xb8\x54\x1d\x31\xd0\x25\x8f\xde\x49\x5a\xc8\xb3\xdc\x4f\x7e\x28\x90\xa0\x4b\xa1\x67\x01\x62\x77\xc8\x13\x31\xcb\x9e\x93\x54\xe9\x1e\xa4\xbe\xf1\xab\xed\xc6\x2d\x15\x5f\xbd\x9f\xf6\xbc\x93\x33\xe1\x72\x17\xad\xec\x39\x8e\x91\x18\x62\x71\xd9\x3a\x86\x5e\xe8\x90\xff\x07\xa5\x92\xf5\xf1\xb1\x6e\x6d\x51\x82\x7a\x0e\x26\xa4\xfb\x71\x62\x6d\x96\x1d\x31\x7c\x3d\x44\xc7\xb2\x87\xaa\x11\x35\xec\x14\xde\x0d\x8b\xc0\xef\xca\x89\xb3\x2b\x72\xd3\x8e\xdc\xb2\xb2\xaf\x26\x0f\xce\xda\xfc\x8a\xb1\x6a\x2d\xbe\x1f\x60\x40\xea\x8a\x2d\x96\xb3\x47\x08\x65\x40\x60\xa6\xce\xa7\x48\x7d\xd3\x79\x39\xa4\x97\x51\xfb\x22\x63\xb0\x92\xea\x72\x9a\xc9\xc0\x50\xab\x93\xf7\x9d\xc7\xcf\x24\x22\x9e\x18\x3e\xa0\xb3\xc9\x5a\x03\x33\x41\x89\xca\x02\x76\xa3\x7d\xad\x32\x0d\xeb\xd6\x09\x13\xdd\xbf\x64\xfe\x11\x47\xc1\xdc\x19\x6b\x22\x8b\xb9\x49\x88\x76\xc3\x8b\x60\x65\xe0\x9a\x8c\xb2\x92\x26\x65\x4d\x87\x97\xc3\x17\xcd\xb9\xbf\x04\xb8\xc0\x42\x71\x4e\x5c\xb3\x81\x7c\xc9\xd5\x95\x2d\x44\x87\xcb\xb9\x6b\x64\xe7\xe2\xea\x6d\x12\x6b\x01\xb1\xcd\x7e\x89\x35\x3c\x32\xd6\x24\x62\xdb\x32\x8a\x02\x0e\xbb\x11\x7d\x89\x8b\x80\x8f\xfd\x72\x88\xdc\x76\x0c\x36\xdc\x2c\x8c\x49\xf9\x43\x8a\xbb\x82\xea\xe2\x0d\x4b\x34\xf7\x44\x74\xeb\x1e\xea\x05\x3b\x16\x62\x15\x90\xae\xc4\x86\xdd\xd7\x72\x3b\x91\x12\x37\x8c\x46\x8e\xa0\xc3\x6d\xaf\xa0\x06\xec\xcb\x18\xba\x94\x58\xc5\xaf\x3b\x03\x6f\x01\x86\x9c\xd8\x79\xe0\xca\x91\x0d\xb7\x78\xc7\x17\xc7\x66\xbd\xcc\xb5\x64\x70\xe6\xfc\x01\x43\x2e\xae\x43\xa6\x4c\xcc\xfc\x3e\x55\xdf\xa0\xbd\xde\x5c\x0e\x51\x8f\xc8\x1e\x46\x3d\x00\x53\x02\x34\x04\x51\xf5\x3e\xf1\x86\x7e\xd2\xd7\x38\xb1\xe4\x60\x53\xaf\x29\xb3\xae\xbf\xbf\x12\xe9\x6e\x47\xa6\xff\x0a\x92\x94\xb1\x12\xe3\x7c\x5b\x25\xe7\xdc\x1a\x56\x77\x81\xdd\x01\xc1\x94\xeb\xf2\x4b\x80\xbc\xdd\x9d\x28\x11\x80\xd8\xb6\x47\xe0\xdb\xf2\xf9\xa2\x89\x0e\xe5\x08\x3a\x9b\xdd\xb5\xaf\x80\x4a\x81\xce\x16\x73\x1d\x87\x2d\xf0\x4c\x44\x6c\x8b\xb7\xae\xf1\xd6\x1c\x01\xff\x14\x4a\x99\x32\xda\xe2\xf3\xad\x5b\x86\x3a\x8d\xc7\xc0\x7c\x6f\xfa\x70\x51\x0d\xad\x77\x0f\xa6\xdb\x60\x19\x55\x97\x46\x86\xdb\x2a\x0e\x9d\x5e\x0a\xad\xf3\x7d\x08\xc8\x1b\x28\x74\xd9\x49\x99\x59\x5c\xbf\x40\x89\xc1\x8b\xa5\xe3\x63\x0e\xb3\xd0\x99\x81\x38\x74\xc0\x2c\x88\x56\x96\x81\x06\x24\xc5\x66\x47\xbd\x63\x69\x2b\xcf\x2e\x4c\x8c\xc0\xb3\xd3\x8f\x8b\x65\x6c\xfe\x9d\xf9\x8b\x64\xb4\x67\xfb\x02\xf6\x85\xa0\xe6\xab\xef\xc8\x29\xb2\xbd\x3d\x57\x72\x5b\x4e\x03\xd0\x8f\x0c\x1d\x30\x82\x90\xcc\xbb\x8e\xe1\xa4\xb1\x17\xc4\x3b\x6e\xf8\x94\xb7\x65\xd3\xb2\x1b\x43\x0f\xec\x37\x24\x20\xcf\xc2\xa5\xfc\x31\x98\xa5\xa6\x6f\xe1\xe4\xd5\x1e\x00\x83\x1d\x80\x81\xc0\xeb\xac\xbc\x7a\x61\xce\xe7\x34\xbc\x4a\xbf\x9b\xe4\x33\xd5\xba\x1d\x8c\xa2\xca\xc7\xbb\x58\xed\xb6\xc0\xe6\x67\xf2\x8e\x4a\x5c\x34\xc3\xf2\x59\x3c\x5d\x29\x5c\x12\xf6\xaa\xa9\x84\x08\xbd\x77\x18\xc7\xa4\xe9\x13\xc4\xbc\xb9\x24\x6d\x7d\x33\x9d\x37\x61\xce\x5a\xc1\xe5\xa5\x25\xd6\x0e\xa9\x1c\xfd\x01\xa9\x17\x5d\xf7\xc7\x6e\x30\xa7\x26\x05\x9e\x71\xdb\xdf\xab\x23\x7d\x36\xc8\x07\xe6\x87\x8c\x67\xc8\x8d\xb2\x9b\x8a\xa4\x2a\xeb\xa1\xfc\x60\x08\x80\x91\xa9\x07\x79\xdf\x37\xf7\xe1\x87\x68\x49\xf7\x67\xfb\x39\xf2\x73\x62\x3d\xb3\xca\x33\xa1\xb2\xb9\xa8\x72\xb1\x69\x69\x73\x73\xd9\xda\x00\x32\xe3\xb2\x7c\xa8\x15\xba\x0d\x17\x67\x35\xdb\x90\x6d\x2f\x19\xfd\xf0\xad\x19\x0f\x11\xed\xea\xdc\xdb\xc3\x93\x6b\x95\x63\x7d\xf1\x75\x53\xfb\x64\x93\x44\x66\x1f\x5f\x3f\xc0\x59\x22\x2d\xcd\xae\xb5\x82\x91\xe2\x39\x95\xda\xc7\x0f\xaf\xba\x3e\x7a\x4d\x7c\x40\x19\xdf\x38\x97\x2f\x33\xe4\xd5\xca\xd6\xa5\x37\x61\x2a\x03\xba\xce\x17\x8f\xaf\xd2\xe8\xc2\xd3\x7e\x73\x75\xcd\x5d\x21\xd9\x58\x5b\x5d\xf8\x03\xb7\x75\xe6\x2e\x87\x73\xf3\x84\x26\x18\xd6\xea\x33\x5f\x63\xc8\x64\x6d\xf9\xf7\xb4\x67\xe6\xb6\xa8\x51\xb3\x92\x03\x5d\x94\x5f\xaf\xb1\x75\x7b\xe2\x58\x6f\xc9\xef\xf3\x05\xc8\x8e\xd4\x67\x50\xff\xc6\x6f\xfd\x51\x67\xee\x71\xb8\xb4\xb0\xca\x5e\x90\xbb\x17\xab\x4b\x20\xbc\xae\xa1\x2a\xb2\xe5\xa6\x54\xc6\x21\xca\xec\x73\x98\x02\xa5\x60\xf7\xe9\x57\xce\x52\xaf\xc4\x58\xae\x07\xcf\xc2\xdb\xdd\x72\x03\x56\xaf\x3a\xe4\xd0\x10\x29\xf9\x5c\x6f\xf3\x85\x09\xbe\x62\xc3\x2f\x39\x86\x58\xde\xe4\xdb\xd6\xa0\x57\x2a\x21\xda\xa0\x48\xc8\xa3\xa1\x37\xec\x41\x37\xd6\x4b\x83\x98\x9f\x80\x19\x7a\x96\x8f\x4e\xa9\xf5\x34\x58\x0a\xf2\xb1\xf0\x88\xbf\x93\xcf\x56\x90\xdc\x07\x15\x0d\x3b\xc4\xbd\x87\x7c\x1f\x84\xdc\x19\xda\xd3\xf2\xaa\x91\x07\xc9\x46\xad\xd2\xd1\xa5\xc7\x61\x8a\x81\x98\x53\x93\x34\xa3\xcb\x9f\xb9\x91\x64\x30\xeb\x07\x61\x5b\xea\x64\x0e\x79\xf5\xa8\x06\xb9\x9e\xd2\x57\xb0\x80\xbc\xa6\x93\xd8\xeb\x15\x69\xeb\x10\x39\xe4\x7a\xc6\xc4\x9d\x3c\xc2\x07\x49\x84\xf4\xfe\x91\x93\x0d\x6b\x96\xb4\xf7\x91\x14\x87\x5f\x51\xee\xe1\x59\xc1\x9d\xaa\x85\x9b\x62\x10\xf0\xca\xde\x8e\x90\x40\x61\x23\x5c\x79\x2a\x65\x70\xcd\x41\xa7\x10\xad\x50\x61\x5f\xb1\xad\x20\x0c\x86\xfd\x0c\x98\x84\x98\xed\x2f\xdf\x6c\xc2\xaf\x03\x9b\x74\xe3\x13\x7c\x32\x18\xdf\x33\x56\x82\x1c\xfa\x83\x43\xe7\x9a\xa1\x76\x13\xe9\x37\x9a\x42\x4f\x03\xdc\xa4\x49\xbd\xd3\x49\xb6\x77\xde\xef\x38\x05\xbc\x01\x64\x43\x17\xd3\x5b\x9d\x20\xeb\xd2\x4f\xda\x2f\x61\xa8\xd5\xd1\x00\x1b\xa3\xec\x57\x45\x7f\x20\xb2\xa3\x36\x48\xe8\x6b\xf9\xe8\xf1\xb6\xe9\xe9\xa9\x2d\xcf\x11\x10\x94\x95\xc1\x58\xbf\xb7\xec\xe2\x10\x6e\x36\x8f\xa7\x61\xb6\xc7\xaf\x34\x15\x1e\x50\x26\x29\x6c\xac\x65\x3a\xa0\xb0\x11\x0e\x41\xae\x26\x2b\xce\x23\x4d\x23\xd7\xe9\x14\x00\x16\xc4\xc3\x39\x5e\x9d\xaa\x4c\xe1\xca\xc1\x6c\x85\xe0\xb6\x1c\x8a\x6c\x02\x86\x94\xf4\x41\xf2\x61\x9d\x85\xae\xce\x3b\xf8\x89\xb0\x29\x97\x42\xfb\xc9\xc4\x9d\x04\x13\xb1\x9d\x70\xfb\xf8\x4b\x61\xca\x34\x2e\x6b\x85\xcc\x5b\xe3\x15\x7b\x5f\xdc\x4e\x3d\x7e\x41\xde\x85\x63\xbf\xbf\x64\x89\xf4\x7c\x06\x47\xf1\xeb\x67\x1f\xdb\x96\xea\x37\xc1\x54\xbc\x18\x43\x74\xe7\x41\xfe\x21\x8d\x80\x64\x5c\x2f\x83\x1f\x94\xb1\xf4\x3a\xb4\xf0\x17\x86\xcf\x93\x93\xed\x35\x6b\x4f\xf8\x05\x65\x7a\x25\x31\xe6\xf2\x80\x8d\x02\xaf\xd8\x8a\x74\xf8\x0e\x4a\x22\x54\x7b\x38\xf5\x80\x8c\xe7\x12\x64\xc4\xa8\x4b\x63\xbd\xb1\x3a\x0d\x61\x21\x62\x0c\x47\x4a\x60\x79\xf0\xcb\xb7\x11\xa7\xd0\x27\x41\x8b\x7a\xfd\x1e\x01\x76\xaf\x2b\x00\x8d\xb8\x32\xd5\xb7\xc4\xe7\xae\xa3\x78\x8d\x2b\x7b\x14\x8f\xed\xa2\xc3\x28\x9c\x67\xa6\x5b\x35\xa5\x91\x3d\x6c\xf9\x47\x1b\xa3\x8f\x68\x75\x0e\x94\x90\xf1\x88\xc7\xf6\xc3\xbf\x1e\xb7\xcf\x51\x65\x2b\x6e\x27\x69\x7c\x16\x4e\x95\x26\xfd\x6d\x81\xf4\x08\x56\x63\xb0\x18\xcf\x03\xc9\x00\x7b\x71\xf7\x3e\xca\xf2\x3e\xea\x8a\x3d\x54\x57\xc4\xdc\x86\x9d\x71\xf1\x4c\x74\xa4\x52\x77\xb0\x17\xf5\x65\x9b\x2f\xbb\x87\x83\xd1\xa6\xba\x82\xcd\xca\x05\x9f\x06\x6f\x31\xae\x39\xe2\x25\x8c\x34\xb1\x18\x79\xa3\xf8\x9d\xbb\x48\xf2\xe2\x7c\xae\x9f\x44\x53\xa5\x60\xb3\xdb\xd9\x5f\x5d\x21\xcb\xc9\x9e\xbe\x44\xab\xa7\x21\xd1\x67\xbb\x20\x73\x0e\xfa\xe5\x93\x7e\xa8\xa5\xf3\xc9\x15\xc8\xcb\xdb\x16\x93\x66\x52\x99\x17\x71\x1b\xd1\xc5\x84\xbd\x12\x66\x9a\x41\x1f\x84\x0d\x53\x1f\x64\x9e\x92\xa8\xd7\x51\x7e\xb0\x52\xa1\xc4\xb9\xfc\xf4\x3e\x7c\x2d\x97\xe8\x24\xcb\x79\xd3\xdc\x96\x33\x9c\x96\xce\x5e\x5c\x47\xb7\x02\xd5\x4d\x84\x6c\x91\xb3\x64\x8b\x5a\x4f\xcd\x97\x52\xfc\x96\x5d\x00\x51\x09\x8f\x19\x6b\x60\x62\xaf\xd1\x65\x29\x5f\x35\x22\x6b\x00\xac\xe2\x51\x66\xd1\x7b\xe1\xec\x72\x01\x55\xa7\x7b\x90\x55\x29\xb7\xa3\xb1\x97\x62\x2a\x22\x1d\x8d\x62\x5e\xe2\xe9\xe4\x8f\x8d\x66\x64\x62\xda\x05\x09\x1c\x15\x44\xfc\x79\x68\x1e\x7c\x8d\x64\x71\xbc\x84\x8f\xde\x4b\x46\xdd\x84\xf3\x5a\x30\x29\xfb\x6a\xb9\xb4\x77\xe9\x7f\x1e\x6c\x10\x82\xf3\xc8\xfa\x39\xcf\x1d\x97\x9f\xe5\xc7\xf9\x7d\x97\x5d\xe9\x94\x3d\x4a\xcb\xec\x97\x71\x3e\xc9\xf8\x9f\xcf\xd3\xfe\xf7\x00\xce\xf5\xc1\x4d\x24\x9a\xd1\x23\x9b\x76\x0e\x34\xaf\x16\xfb\xf2\x26\xe8\x87\x33\x13\xdf\xe2\x8a\x5e\x0c\xed\xe6\xf0\x2f\x2e\x7f\x61\x84\xee\x4c\x73\x71\x2d\xcb\xd6\x90\xc2\x24\x3a\x66\xf5\x48\xf2\x96\xf8\x94\x47\x6a\x82\x8d\x19\x96\x4a\x5b\x27\xee\x22\xfd\xc0\x66\xfc\x84\x32\x61\x02\x91\x55\x91\x8b\x8e\x01\x25\x53\xb4\xd5\xd2\x07\x9c\x9a\x78\x02\xb4\x6a\x06\x9c\xc4\x1e\x78\x96\xe8\xe6\xa2\xc5\xcf\x59\x0e\xb1\xf3\xfc\x12\xdb\xd1\x0e\x12\x01\x93\xba\x88\x02\xfc\xfc\x28\xee\x32\x13\x56\xbb\x57\x4e\x24\x6a\x99\x31\x79\xa5\x12\xf9\xb5\x2d\xb0\x28\x89\x64\xcb\xe9\xa8\xef\x9e\xb4\x67\x02\xe6\x8e\x0c\xcc\x97\x78\x95\x3d\x2f\x65\x68\x33\xcd\x63\x7e\x89\xc7\x38\x76\x32\xfc\x7e\x38\xd3\x12\xfe\xa2\x72\x7a\x02\x8c\x17\x2e\x79\x7e\x98\xf3\x74\x69\xaa\x95\x43\x03\xdd\x05\xa9\x78\x35\xf3\x52\xc0\x2b\x4f\xb7\x19\xd4\x46\x52\x25\x97\x8d\x66\xd4\x0b\x94\x80\xcf\xad\xfb\x4d\xb4\x82\xb0\xce\xe9\xa2\xcb\x82\xbf\x96\xfe\x8d\xa4\x20\xcc\x18\x08\xf0\x4b\xf0\x23\xed\x67\xdd\xe9\x6f\x85\xb5\x6a\xbf\xd5\xa8\xad\x27\x86\x10\x5a\x45\xfe\x4f\x7b\x22\xf1\x72\xfb\xc3\xd8\xc0\x90\x55\xcf\x19\x8e\x20\xca\x08\xed\xee\xff\xd3\x3c\x12\xc4\x4d\x00\xba\xab\x51\x14\x34\x53\xca\x16\x44\xcf\xc5\x85\xed\x16\x35\x34\x5d\x46\xe4\x78\x22\xc6\x76\xa3\x31\xb2\x7c\xb6\xba\x58\x4d\x4f\x3a\x4e\xea\xad\xe3\x12\x26\x5a\x58\xf3\xd5\x31\xdd\xa7\xcc\x3a\x49\x57\x47\x8f\x2f\xb5\x2c\xda\x1d\xae\xc9\xd9\x5c\x78\xb3\x59\x50\x6d\xa5\xae\x58\x98\x9c\x4e\x50\xde\xfd\x66\x9a\xce\x5f\x8e\x56\xd3\xe9\xc6\x0b\x34\x5c\x2a\xd2\xa5\x9d\x4a\x65\x6f\xce\xdc\x3c\xbd\x93\x86\x30\x45\x96\xaa\xbb\xc5\x96\x9c\x91\x4e\xf3\xa0\x27\xd5\xb8\xf2\x01\x99\x8a\xcf\x99\xa7\x89\xf8\xd4\xf0\xa1\x0a\x47\x29\x9b\x53\xc7\x9f\xe2\x1c\x4e\x75\xb4\x88\x81\xfe\xf0\x2f\xc2\xc8\x3b\x68\xb7\x18\x90\xf0\x98\x22\xbb\x12\x22\xd3\x7c\xb7\x1d\x7f\xc4\xbb\x7d\x26\x32\xb9\x4b\x84\x07\x24\x47\xb9\x63\x78\x70\x3d\x77\xe2\x0b\xa6\xbc\x2e\x3a\xa8\x54\xa5\x5e\x47\xb8\xf9\x1f\x96\xb9\x66\x3a\xe5\xf4\x8c\xad\xb4\x17\x27\x64\x4d\x64\x8a\xa6\xbf\xcc\x45\x02\xf7\xb3\xf2\x6f\x22\x24\xd2\x23\xe7\xa9\xc6\xf5\xb7\xd6\xf3\x26\x76\xda\x1f\x3c\x8d\x62\x87\x92\xf1\xc9\xfd\x7d\x71\x32\xee\x94\x3a\x5d\x1a\x15\x1a\x5e\xe7\x87\x9c\xc3\x97\x4f\x29\x9d\xae\x09\xb0\x1c\x5f\xac\xca\xed\x2f\x24\x94\xac\xb6\xbe\x90\x68\x7a\xb6\xf1\x2a\x9f\x22\x25\xa1\x57\xd9\xcb\xdb\x69\xa3\xb0\xcd\xd2\xb2\xd3\x0b\x06\x68\x9d\x07\xb9\x6e\x5b\x87\xd9\xbf\xc6\x4e\x38\xcb\x57\x7e\x13\x8a\x8a\x07\xd3\x1f\xd5\x57\xd6\x7a\xdd\x2b\x41\x36\x95\xfb\xd2\xf9\x0c\xd8\xcc\x2b\x01\x4a\x34\x17\x56\x59\x5f\x18\x2a\x82\x05\xaa\xd7\x37\xf9\x6b\xd9\x24\x5d\xa7\x07\x36\x0b\x95\x13\x7e\xcf\x59\xeb\xa1\xbf\xe7\x44\xe6\xd8\xef\x89\xf5\x42\xe7\x62\x16\x08\x11\x93\x09\xf0\xeb\xba\x02\x7e\xa0\xf5\x5a\x3e\x94\xfd\x66\x58\x87\x23\x48\x34\x5c\xfe\x4d\x21\xe5\xf2\xeb\xea\xc5\x22\x27\xee\x96\x39\x4c\xe3\x4d\xb1\xec\xc5\xf2\xab\xf4\x4a\x91\x2d\x85\xff\x54\x33\x96\x73\xf4\x9c\x8e\x36\x82\x53\x94\xdc\x22\xea\x5e\x72\x37\xd6\xdb\xce\x60\x5a\x56\x6f\x01\x5f\xb9\x44\x95\x44\x4c\x46\xb4\xc2\xa8\xd7\x5b\x0e\x40\xcc\xd5\x78\xea\xb8\x0d\xb5\xa4\xaa\x59\x3f\x86\x90\xd9\x78\x75\xaf\x6b\x0c\x4e\xce\x3c\xce\x0a\x48\xf5\xf6\x54\xa3\x18\xbc\xa3\x51\xdf\xe3\x75\xb9\x71\x09\xd9\x09\x7e\xff\x72\x62\x21\x45\x7f\x86\x5b\x7d\xc5\xb9\x3e\xa7\x60\x86\x3e\x6d\x24\xf9\xa2\x52\x3e\xe5\x39\x61\x11\x4d\x0c\xdd\xa2\x2b\xde\x76\x83\xdd\xf7\xaf\x76\x3e\xd4\x28\x8f\x9b\xca\x19\x3c\x55\xc0\x74\x1f\x37\xab\x53\x5f\xd3\x86\x8e\x1c\xc2\xe6\xfe\x7a\x68\x24\x59\xaa\x72\x86\xcd\x99\xcd\x92\xdd\x02\xd7\xce\x96\x97\x6a\x46\x7e\x7e\x44\x28\xe5\x0f\x7a\x79\x05\xe5\xb3\x1c\x82\xf6\x8e\xb3\xe8\x16\x7a\x01\x73\xa8\xb1\xd2\x3f\xe5\xce\x2a\x06\x28\x24\x73\xea\xdb\xe6\x9b\x91\x3b\x4b\x6b\xc1\x1b\x40\xde\x7e\x5d\x2c\x6b\xce\x77\xce\x3d\xda\xdf\x2f\xc2\xb0\x93\x44\x99\x05\x89\x30\xea\x67\xd9\xba\xd0\x97\xcf\x04\xc7\x34\x37\xe2\x86\x62\x3c\xae\x0b\x7c\xc3\x85\x07\x67\xa5\x5a\xd6\x70\xf5\x76\x4e\x22\x49\xc2\x58\xcc\x86\x40\x12\x2b\xe9\x32\x86\xcf\x1f\xce\xbf\xbf\x44\xdf\xb0\x9d\xec\x48\x87\x9e\x47\x41\x1b\xa6\xe5\x11\x68\x08\x19\x42\x0e\x70\xc0\xb8\xc1\xd7\x9a\xc6\x0b\xfa\xee\x33\xd6\x0a\xaa\x06\x5c\x61\x4f\xd6\xa7\x5d\x51\x3e\xf6\x83\x56\xe1\x2d\xcb\x25\x17\x92\x3b\x89\x45\x1d\x50\xb5\xb0\xa7\x59\xd8\x08\xf0\xd3\xab\x9a\x31\x68\x14\x67\xe4\x5c\xce\xa9\xd0\x13\x8a\x05\xa2\x6b\x3f\xb5\x5a\x3d\x94\x39\x57\x07\x18\x34\xfa\x71\xa3\xd7\xd9\x14\x0e\x63\x98\x7a\xe9\x23\x5d\x5c\x42\x15\x16\x87\x18\xfb\x7d\x01\x88\x31\xdd\xd0\xc6\x57\x50\x59\x83\x97\xea\x2d\x1b\x5f\xfc\x07\x03\x2a\x66\x64\x60\xd7\xb5\xac\x47\xe5\xa1\xc6\xd9\x88\x88\xe9\x23\x64\x93\xe5\xbd\x65\x2d\x65\x6e\x03\x4a\x71\xc3\x18\xd6\x40\x4e\x44\x4d\xfb\xfd\x31\xa9\x73\xfe\x1b\xe2\xf4\x61\x65\x77\xb0\x09\x78\x65\x89\x0f\xd0\xf0\xf3\x2f\x02\xb9\x5e\x84\x55\xbb\x66\x9b\x38\xaa\x8b\x24\x88\x06\x22\xf6\x87\xf4\x35\x01\xb4\x09\x3b\x94\x47\x48\xe9\x4d\xae\x8a\xcf\xc9\xf4\xa0\x62\xcd\x50\x59\xb9\x29\xf5\x32\x44\xc3\xbf\x07\x98\xac\x5e\x1b\x01\x67\x55\xb4\xd1\xd3\xaf\x72\x7f\xce\x58\x80\x61\x34\xbb\x29\xd8\x39\xf1\x05\x94\x01\xc8\x82\x3d\x0e\xf7\x26\xdb\x2a\x25\xc0\xc2\x73\xad\xcc\xd6\x1b\x1d\xeb\xe4\xd6\xd8\x3f\xee\x87\x1c\xcf\x44\xa6\xec\x61\xe3\x0d\x3e\x28\xf7\x0a\x36\x6e\xc1\x70\xd3\x52\xb1\x3a\x8c\x08\x5f\xb5\x54\xd6\x4a\x5f\x84\xdb\xec\x4b\x2f\xca\x27\x68\x47\x9e\x15\xf4\x94\xa4\xd0\xb7\x4e\x4c\xd7\x7b\xac\x01\x6a\x4f\x4e\x73\x84\xf1\x95\xf2\x4a\xed\x3d\x05\x7b\x54\xaf\x34\x9e\xc4\xd8\x84\xd8\x86\xc3\x53\xc8\xcb\xcd\x34\x3f\xcb\x37\x56\xd6\x62\xa7\xde\x2a\xfd\x03\x8f\x25\x09\xfc\xd8\xd7\x4a\x5e\x7f\x5b\xcb\xf6\x2e\xcd\x5d\xa3\x87\xd3\x56\xb1\x6e\xc5\xa8\x87\xa4\x08\x99\xc1\x69\x7b\x82\xe2\x35\x31\xee\x62\xe1\xd5\xe2\x36\x68\xb5\xc9\x6d\xc3\xe1\xba\x16\x56\x6c\x96\xb8\xc8\x50\xbf\xb7\x34\xd6\x4f\x16\x25\xb0\x41\x4c\x59\xea\xd4\xc6\x6f\x8f\x3c\x59\xab\x01\xbd\x4d\x5b\x43\xb7\xb7\xe7\xe4\xb2\x07\x54\xd3\xe7\x0e\x4f\x67\x1d\x4c\x14\x62\x43\x83\xf3\xd5\x27\x1d\x6e\xc8\x62\x75\xb2\xac\x07\x3d\x12\xc3\xe7\x66\x39\xb5\xb7\x29\x54\x40\x24\x2f\x04\x30\xfd\xcc\x9f\x40\xa9\x88\xaa\x89\x52\xa1\x26\xee\x16\x7b\xf2\xca\xfd\x89\x82\xab\x4f\x74\x78\x1b\xc7\x44\xf8\xb6\x00\x9b\x38\x50\x11\xdd\x99\xe2\x1f\x82\x22\x61\xf6\x56\x1e\xd5\xf4\x4d\x1d\x0e\xb0\x6f\xbb\x38\xe1\x1e\xfb\x85\x86\x2e\x35\x5c\x45\xfd\xe3\x2d\xd9\x8b\xaf\x2c\xb1\x50\xc0\xc8\x83\xe9\xe5\x37\xcb\x93\x46\x2a\xc1\x8f\x3d\x39\x71\x72\xfa\x6c\xec\xa3\xf1\x5c\x6d\x6d\x32\x8c\x2b\xae\xbe\x26\xd6\xac\xdd\x72\xa9\x52\x5c\x41\x15\xd4\xd1\xae\xcc\x15\x24\xdb\xea\x09\xf7\xf7\xe7\x9b\x7f\xd5\x5a\x6d\x7c\x87\x15\xdc\x3e\x2c\x72\x87\x23\x51\x75\xa4\xc0\xa2\xf3\x62\x6d\x30\xa5\x7b\x9e\xcd\x64\xb6\x1c\xd7\x6a\x7c\x92\xd7\xf8\xc4\x2f\x21\xae\x33\x14\x1f\x34\xc4\x3d\x73\x98\x92\x3d\x2b\x16\x18\xfe\x72\x89\x6f\xca\x59\x34\xb1\x27\xe6\x8f\x62\xe6\x86\x69\x88\xbb\xca\x85\x4f\x9c\xbc\xe4\x3c\xb6\x1f\xab\x39\xa5\x52\xf6\x74\xe3\x38\x1e\x83\xe5\x40\x22\x73\x60\x21\x37\x54\x4e\xee\xa8\xa4\x0a\x91\x48\xb9\xf2\x69\x79\xa6\x51\x3a\x6e\x4f\x16\xfc\xb8\xb3\xf5\x89\x25\x16\xa2\xe4\x64\xd7\xe6\xb8\xbc\xf9\xca\x6b\x22\x4c\x3f\xff\xfb\x27\xaf\x38\xaf\x7f\xc1\x6c\x15\xf5\x47\xef\x8e\x7c\x5f\x47\x3d\x4a\x8f\x6f\x06\x97\x5e\x1e\x99\x10\x78\xc3\x57\x05\x3a\x86\x85\xc9\x13\x38\xbd\xa0\x0e\xd1\x06\x06\xad\xa0\xfb\xe7\x7f\x28\x5a\x54\x5f\xbb\xb1\x0f\x2f\xbb\x61\x74\x0f\x2b\x7d\x50\xb5\xe6\x62\xa8\xb7\xba\x17\x92\x76\xdb\x29\x05\x5d\xc8\x1a\x61\xd6\x0f\x4f\xbc\xfd\xcb\x43\x4f\x0e\x79\x8a\x59\x60\x60\x54\x59\xc4\x5b\x53\x3a\xb2\x8b\x81\x38\x8c\x33\x38\x31\x9c\xa4\x5d\x44\x62\xca\x36\x62\xbb\x66\xb1\x5f\xc1\x6b\xec\xcb\xa1\x90\xe2\xbf\x96\xcd\xec\xc1\x09\xf6\x44\xa2\x55\xe3\xc0\xa0\xaa\x6b\xbb\x0e\xe4\xc5\xde\xbc\xdf\xc7\x4d\xf1\xbd\x19\xc3\x80\xfb\x8a\xf1\xeb\xa1\x47\x3d\x4c\xae\xb4\xd7\xa6\x52\x6f\x9a\x6d\x50\xed\x63\xaf\x91\xbf\x4e\x4e\x70\xf5\xd4\x03\x2f\x31\xcc\xfe\xe6\x75\x48\x61\xaa\x07\x35\x7b\x5e\x15\xa8\xe2\x84\xad\xde\xec\x54\x0f\xed\xa6\xd3\xdf\x0c\x72\x42\xb8\x99\xa1\x80\xd6\x56\xb3\x29\x61\x8e\xed\x4f\x94\x0a\x99\x3d\x0d\x51\x7f\xca\x96\x96\x57\x3f\x3f\x79\x13\xe5\xa7\x33\xd6\xb5\x93\x7e\x7d\x31\xe5\xcb\xee\x86\x01\x45\x47\xcd\x99\x73\xda\xaf\xfe\x26\x15\xcb\x43\xb5\x3b\xe9\xd8\x76\xb2\xf8\xdf\x49\xb4\xab\xb3\xee\x3a\xe8\xbf\x27\x7b\x64\x6c\x49\x67\x84\xe2\xac\x2a\x28\xdd\x16\x38\x0d\x67\x00\xab\x2e\xd2\x6d\xd9\x1f\xa1\x0e\x5d\x2e\xb7\x60\xf4\x7b\xb5\x09\x46\x7d\x74\x95\x41\xaa\xb9\x07\x94\xaa\xa3\x73\x4d\x07\x4f\x52\x72\x76\x97\xf2\xa1\x16\xb6\x53\x7c\x99\x6e\xd0\xb3\x4f\x04\x4d\x61\x3a\x64\xd0\x27\xcb\xb6\x51\x22\x34\x5f\xcd\x40\x2a\x74\xee\xe6\xdb\x05\xbd\x76\x2f\xd3\xbb\x12\x6f\x77\xff\x0d\x18\x7b\x06\xc8\x90\xfa\x9f\x7a\x73\xa8\x33\x90\xca\xfb\xc5\xda\x6d\x4f\xad\x89\xb9\x88\xeb\x22\xbb\xe4\x6f\x78\xa9\x2c\x00\x03\x2b\x86\x26\x78\xf0\xd1\xb0\x74\x04\xeb\x31\xfc\x88\x25\x08\xc0\xc1\x59\xb4\xc4\xe7\xb6\x12\x6c\x2b\xc1\x38\x35\x5c\x7e\xea\xf2\xe9\x0e\x86\xd9\xe6\x70\x95\x6d\x9c\xeb\xb2\x1d\x0f\xb1\xec\xa7\xf2\x77\x01\xcd\x09\x27\x41\xf7\xee\x63\x04\x34\x4d\x4b\x62\x2b\xe5\x06\x48\x8d\x5d\x8b\x5c\xf2\x56\x2e\xd3\x77\xd5\x79\x6f\x76\xe1\xd9\xaf\x2f\xf1\xaa\xcb\x57\xfb\x29\x7b\x89\xae\x6a\xdd\x7e\x35\x82\x2e\xbb\x5d\xd5\x44\xd1\xee\xe0\x6b\x57\x70\xae\x22\x55\x43\xcf\x36\x56\x11\x90\xeb\x35\x99\x1c\x63\x70\x0b\x82\xa9\x9b\xa6\xfa\xf7\xa4\x67\x64\xce\xb0\xe7\x13\x89\xa2\xab\x66\x44\x9d\x80\xd2\x1d\x56\xf3\xf5\x73\xda\x9c\x47\x24\x65\xb1\xdf\x3a\x1a\xdc\x6a\xdf\xac\x99\x5a\x87\x07\x2b\x3e\xa5\xe7\x19\xff\xe4\x83\xdc\xbc\x3f\x10\xf6\xf7\xa9\xbc\xd3\x4b\x8b\x8e\xb0\xb8\x0f\x8b\xb1\xb3\x4a\x7c\x59\x67\x9b\xda\xe4\xdc\xc3\x73\x75\x69\x6f\xee\x75\xdc\x94\xe8\xad\x36\xa6\x1d\x87\xde\x38\x7d\x65\x82\xb5\x45\x36\xde\x4e\xc4\x36\xd4\x81\x09\x7c\x70\xe3\xbe\x41\xe2\x12\xd6\x58\x2e\xed\x75\x77\x32\x22\x09\xa6\x2a\x92\x86\x1d\x44\x23\x51\x2e\x56\x3d\xbd\x13\x79\xf5\x0d\xb7\xe6\x6e\xeb\x4e\xc2\x08\x44\x3c\x17\x4b\xd7\x3e\x61\x57\xc5\xb3\x2d\xdb\x4e\x79\xc3\x16\xb3\x13\x25\x8a\x28\x81\x06\xaf\xb7\xc8\x7d\x0d\x9c\xdb\xea\x9c\x17\x8c\xdb\xca\xc0\x1d\x97\x93\x83\x3d\x7d\xf8\xa2\x66\x31\xdd\xbb\xaa\x0c\x2d\x9a\xbc\x29\x3d\x9a\xc2\xd2\x3e\x9c\xbb\xf5\x15\x0b\xef\x3d\x9d\xc5\xf2\xbc\xd9\xaf\x14\xf9\x94\x17\xa2\xb5\xe2\xae\xf7\xb8\xab\x9c\x71\xb7\xf1\x73\xe3\xbd\xf8\x5a\x0c\x93\xf5\x43\xa0\x95\xfc\x9f\x86\x72\x50\x6f\xa5\xe9\xf6\xdd\x83\xbc\x74\xbd\xce\xa0\xd0\x24\xa9\x26\xb3\xd1\xde\x07\xc6\xaa\xa3\x5b\xfe\x91\xad\x49\xb3\xf1\xd8\x6b\x37\xa5\xbf\x23\x5a\x5d\x44\x5f\x4b\x01\x6a\x72\x99\xd2\x1b\xf5\xdd\xc0\x8a\x6d\x71\xb1\xa6\x73\x5e\xb4\x60\x0d\x42\xf0\xe2\x29\xf8\x15\xad\xfb\x95\x49\x09\x9f\x87\x4d\xb9\xdf\x0f\xbb\xbc\xf0\x35\xac\xca\x52\x76\x89\x1c\x4a\x68\x5b\xc1\x6a\xdd\x19\x30\x5e\xb4\x5e\x45\xcc\x71\x94\x8b\x19\xc0\x7e\x5e\xa7\x8e\xae\xb2\x8d\xf0\xf9\xf4\xfa\x17\xe9\xc6\x20\x96\x7d\x29\x32\xb7\x28\xa2\x62\x3b\x1e\xac\xba\xda\x2c\x85\x54\x61\x58\x06\x8e\xc4\xb5\x57\x86\xf1\xcd\x28\x2e\xab\x6b\x09\x82\xd0\xb6\x07\x9f\x37\x6e\x50\xb7\x5d\xe7\x15\x45\xfe\x9f\x3f\xf2\x04\x14\xeb\x7d\xb0\x13\xe2\x77\x0f\x22\x1f\x21\x48\x0e\x4d\x65\x63\x5b\x4a\x73\x91\xca\x1c\x1e\x93\x48\xbb\xab\xcd\x60\x9a\x57\xf8\xd6\xea\xe3\x12\xad\x98\xc1\x16\xf6\x2f\x42\x2d\x90\x09\x1f\x38\xc2\x81\x75\x45\x1c\xb0\x0a\x70\x82\x37\xb1\x83\x8f\xb0\xed\x4c\x87\x9b\x13\xb6\x8c\xab\x61\x52\x8b\xc5\xee\xc5\x46\xdd\x68\x65\x08\x2d\x3e\xc8\x12\x76\x7d\x14\xbd\xb0\x95\x90\x81\x01\x6b\x78\x7c\x17\x41\x45\xad\xf5\x1b\x84\x5e\x9b\xe2\xa9\x48\xc4\x57\x56\x12\x93\xd7\xf1\x96\x63\x11\x65\x98\x11\x88\x3f\x54\x14\x48\x4b\x15\x41\x6f\x7d\xcd\x23\x66\x10\x6c\x4d\xe4\xbc\xa7\x8a\x20\x6b\xd3\xcc\x9f\x0e\x74\x65\x9d\xd5\xf4\x17\xb7\x0a\x12\x02\xa7\xf4\xb6\x62\x4e\xb6\xa9\x91\xfe\x77\x13\xa8\x6b\xf2\x86\x1b\x1a\x53\x40\x00\x8a\x0b\xf2\xcd\x69\xbd\xd6\xce\x03\xb0\x5c\xce\x00\xf6\xc4\xa2\x65\x5a\x7f\x96\x4e\xb9\xc5\x35\x40\xa7\x8b\x67\x7b\x66\xa2\xd3\x9a\xed\x0a\x12\x28\x90\x85\xf1\x6d\x76\x87\xfd\x05\xa5\x58\xb3\x3f\x8b\xbc\x72\xdf\xc8\xbf\xdd\xb6\x58\x1f\x64\x94\x48\x2c\x06\x73\x35\xdc\x03\xb7\xcc\xa3\xa9\x2c\x0f\x36\xf1\x3e\x4a\x1b\x07\x44\xe2\x49\x47\x25\xd2\x06\xe1\x9b\xd8\x55\xe7\x45\x1b\x39\xf3\x02\xf6\x9c\xf3\x48\xdd\x11\x42\x2f\x7c\xe2\x0c\x81\xdc\xfe\xdf\x29\x96\x70\xf8\x29\xea\x20\x12\xcf\x9a\x12\x85\x6c\x30\x8d\x55\x97\x70\xd2\x71\xd0\x8f\xfb\x5c\xed\x14\x11\x7b\x30\x37\xfa\x90\x89\x9e\xb7\x0d\x45\x18\x6d\xc3\xeb\x25\xd3\x8d\x30\x5a\x69\xa6\xf3\x14\x79\xf8\x2b\xa7\x6d\x26\xb9\x49\xc3\x9e\x91\x14\x63\x0d\x35\x0d\x86\xc3\xa2\x80\xb9\xa7\x18\xcd\xf1\x32\x15\x98\x9c\xb5\x0c\x79\xe0\x88\x47\xbd\x3e\xd2\x2e\x92\xdf\x22\x90\x4b\x33\xa5\xef\xbd\x09\xce\x8e\x33\xef\x77\x6b\xc5\x24\xab\x19\x29\x80\x05\x01\xbd\x88\x98\x1c\x36\x61\x60\x85\xf8\x49\x6b\xbe\x46\x10\x7c\x68\x72\xe4\x4d\x44\x69\x0b\xdc\x49\xd9\xdf\x94\x5d\x68\xde\xa3\xe5\x17\xc3\x2c\xf7\x2e\xc0\x4f\x6a\x32\xd3\x54\xb2\x60\x03\xf0\x20\xef\x92\x3c\xd9\x4d\xf2\x27\x34\x29\xd2\x87\xab\xfa\x5c\x59\x0b\x7d\xb1\x22\x1d\x30\x84\x12\x1c\x8c\x20\xfd\x82\xd9\x2d\xfd\x5b\x6c\xbc\xe1\xce\x90\x64\x6f\xd2\xbf\x10\x38\x05\xe3\x59\x84\xe7\x3d\x07\x11\x3d\x8a\x05\x16\x3c\x6b\xd4\xd0\x25\x72\x91\xa4\x99\x45\xaf\xea\x1b\x64\x8d\x4c\x6e\xf2\x34\xed\x97\x02\x9f\xdb\x32\x7e\xc9\x31\x34\x4d\x6d\xbd\xd3\x92\xca\xa9\x0d\x6a\x74\x64\x43\x3f\x9f\x41\xad\x0f\x63\x1f\x04\x7c\x4d\x9b\xf6\x08\xf6\x75\xfb\xea\x13\xc6\x43\x6f\xa4\x97\x73\x4a\xff\x8e\x0d\x0b\x78\x33\xe3\x4c\xf6\x32\x6f\x27\xcb\xf5\x9c\x5c\x7a\x1e\xa5\x19\xff\x53\x5e\xb3\x5d\x81\x83\x85\x9d\x33\x08\xba\x89\x74\x6a\xac\x1d\x28\xf1\x27\xb7\xfa\x87\x61\x17\x2b\x1f\x08\x65\xc4\x48\xbe\x75\x25\x59\xdb\x04\x46\x2a\x8d\x22\x57\x8f\xe2\x5c\x83\x56\xad\x17\x9c\xf4\x5c\x28\x83\x46\xb3\x05\x9e\x29\x96\xa3\x1f\xff\xef\xcb\xbf\x92\xe7\xb6\xd1\x08\x72\xd3\x4a\x92\xd3\x9e\x8f\x22\xde\xb3\x38\xd0\x08\x2d\x79\x91\xc3\x24\xa1\x80\x8a\x48\xa8\x5d\xd7\x4d\xca\x04\x08\x41\xfa\x14\x95\xc6\xc6\x31\xa4\x13\x69\xb9\x64\xfa\x93\xdc\x71\x83\x13\x15\x5f\xd5\xf6\xf1\x93\x0d\x2c\xc8\xfb\x9b\x48\x98\x6e\x19\xf2\xe7\xb6\x3b\xc4\xd3\x73\xdc\x29\xc3\x58\xc9\xc3\xa0\xe1\xb1\x43\xd7\x5a\xa8\x76\xf7\x63\x71\xe8\xda\x15\xad\x87\x13\xa9\x49\x0b\x9e\xf1\x03\x4c\x14\xa1\x4a\x20\xb1\x51\x77\xd2\x3f\x65\x16\xd1\x5d\xc6\x98\xfc\xe8\xb9\x19\x7b\xcd\x23\x11\xcb\xfb\xd2\x59\x47\xf4\xfe\x9c\xae\x5d\x39\x76\x9a\xbc\x02\x28\xf7\xc7\xa9\xe5\x42\x77\x82\x8a\x05\xcb\xc8\x90\x56\x9e\x75\x68\x6a\x02\x68\xed\x9e\x99\x12\x36\x4c\xc3\x41\xfe\xf5\x66\xaf\xfb\x2d\xf3\xb4\x99\x25\x5c\xce\xfd\x5d\x1d\x56\x0e\xdd\xfb\xdf\x42\x29\x0f\x5b\x84\x6e\x82\x7f\x5e\x07\x90\x42\x5c\x09\x35\x3c\x8c\xbc\x26\x85\xfd\xb2\x5b\xc1\x74\xbc\xae\x2d\xe8\xc7\x53\xee\xaa\xdc\x1a\x68\xda\x62\x59\x8b\xa2\xcd\xd0\x9e\x7b\xbe\x01\xd2\x22\x5f\xf4\x6a\x2f\xe1\x26\x18\xfd\xca\xcd\xb4\xb1\x59\x61\xa7\xab\xd6\xec\x01\xef\x4e\x80\xac\x89\xab\x0d\x10\x31\x0f\x05\x50\x8e\x57\xaa\xa1\x11\x1f\x3d\x34\xab\xb5\x66\x57\x0d\xb5\x53\xd3\xc8\x39\x55\x38\x38\xdb\x36\x3e\xa7\x4a\xd4\x2b\xa1\xe3\xa6\xd3\xba\x55\xd8\xfc\x83\x1d\x8e\xf7\x7d\x7f\x58\x31\x84\xe8\x86\xc7\x33\xde\x99\x3d\xac\x2e\x5b\x7f\x79\x1d\x2e\xef\x41\xfe\xd0\x5f\xb6\x8c\x08\x0e\xbc\xca\xe9\x50\xa2\x0b\x58\x1f\xee\x78\x71\x3e\x7d\x51\xc0\xe2\x42\x06\xa6\x99\xc8\x15\x22\xbd\xd7\x0f\x9d\x07\x0f\x9e\xde\xe7\x5a\x00\x15\x40\xb4\x51\x5d\xe4\xe3\xc2\x1c\x4e\x49\xf6\x01\x1c\x1f\xf8\xd1\x70\x15\xce\x9c\x62\x79\xa3\x2a\xad\xfd\xc1\xbb\x47\x14\xbb\x5e\x54\x8a\xfc\x10\x1e\xf1\x29\x85\x89\xce\x87\x12\xfe\xee\xe4\x79\x45\x10\x1c\xf2\xd2\xb9\x95\xb5\xc7\xbf\xa9\x3b\xad\x07\x8d\xc5\xf2\xcf\xd7\x58\xf7\x01\xf3\x28\x42\x30\x3e\xfc\x1b\x6c\x28\x3a\x12\xbf\xec\xe6\x5b\x7d\x22\x25\xfa\xe0\xf1\x68\xc8\x0b\x87\x9e\xbc\xf6\x0e\xa7\x00\x65\x64\x85\x2b\xf0\xe9\xfd\x07\x58\x96\x3d\x4d\x72\x04\x1d\x6b\xa6\xeb\xd6\xa1\xdc\x89\xd9\xa8\x73\x10\xc9\x12\xe7\xab\xfe\x9c\x7c\xb2\x03\x11\x7d\x8f\x8d\x8c\x1f\xf9\x7a\xe6\xe5\xe4\x2e\x1b\x77\xc5\x76\xcf\x3a\xa8\xe1\x26\xbd\xab\x91\xa8\x0c\x62\x3e\xb9\x9e\x6e\x3a\x4e\xd7\x61\x71\xf6\xb8\x1f\x94\x5c\x4e\xe1\x47\xf1\x73\xcc\x53\x10\xc9\x57\xba\x1e\x03\x49\x11\x29\xbf\xc5\xfb\xd1\xe8\xb7\x4f\xfc\x99\xed\x7e\xf2\x0e\xf4\x4d\x2a\xaa\xb3\xb7\xcb\xe1\xdd\xc3\xbb\x60\x09\xe0\x87\xaf\xca\x81\xef\x3d\xbe\x99\x0b\x5b\x90\x23\xe0\x43\x86\x20\x06\x93\xf7\xc8\x7c\x53\x4e\x48\x8c\x58\xf7\x00\x45\x7c\x64\x3f\x09\x34\x20\xa7\x0a\x96\x66\x2e\xe4\x97\x2f\xad\xf8\xda\x58\x3f\x63\xd0\xeb\xa3\xba\x5c\xf4\x52\xcb\xfa\xe8\xdb\x55\x78\xf8\x6a\xd6\x28\x8f\xce\xc7\x67\x94\x3b\x1b\x4b\x18\x9d\x86\x43\xf3\xdb\x8b\x87\x53\x01\x39\x62\x66\x5b\x93\xa1\xb7\xab\xa9\x71\xb4\x7b\x5b\xa6\x40\xe4\xcc\xdb\xb9\xe8\x47\x8d\x5a\xbe\x4c\xea\x79\xc7\x78\xe4\x76\x71\x1e\x24\xc3\x4e\xd4\xf9\xca\x39\x78\x43\x41\xa2\x96\x3c\xec\xe9\x75\xa8\xdb\x59\x57\x12\xce\xbd\xde\xe0\xe7\xde\x91\x97\x1e\x76\xa4\xdb\x49\x7a\xfa\x6d\xe4\x2c\x8e\x3a\x3f\x0b\x31\x89\xe5\xab\x3d\xda\x5e\x37\x38\xc1\xfe\x0b\x3e\x7a\xf0\x4c\xd5\x5a\x63\x1a\x0f\x69\x21\xcf\x06\x3c\xb0\x8b\xa0\xfc\xde\x9b\xf4\x29\x45\x6d\x60\x0f\xc7\x8b\x13\xcf\x95\x38\xe6\xd3\xf8\xaa\x66\xa9\x53\xc8\x04\x5b\x1e\xef\x25\x4b\x01\x94\xd4\xcc\xd1\x40\x6e\x5e\x39\xed\x20\xbf\x44\xc3\x2d\x44\x65\xb3\x5a\x39\xd9\xe7\x32\x04\xac\xd7\x3a\x27\xbf\x58\xcb\xf3\xe4\x7d\x62\xd1\x96\xf3\x5f\x9c\x96\x56\x82\x6a\xd3\x86\x30\x3d\xac\xe7\x22\x8d\x51\x7d\x4e\x5d\xa4\x41\x48\x99\xb9\x78\x25\x71\xbe\x48\xfa\x7c\x79\xd7\x17\x6a\x89\xb3\xf2\xe9\xdd\x79\x65\x89\x86\x04\xdf\x19\x83\x74\x17\x8d\x58\x6f\x89\x46\x8e\x98\x98\x5d\x1e\xe7\x95\xa2\x98\x65\xc2\x1b\xe9\x3d\x06\x14\x02\x08\x84\xff\x63\xc5\x0f\x09\xcc\x8c\x65\x01\xc4\xbd\x94\x6a\x4f\xfa\x17\x1f\xb2\x63\x39\xdc\xe9\x3e\xc2\x46\x26\xa9\xf8\xed\x26\xed\xa4\xd9\xc4\xe1\x66\xa9\x99\x91\x58\xd9\x1b\x8c\x39\x6e\x32\x38\xf8\x8b\x5c\x64\x85\x75\xac\xdc\x48\x37\xa9\x31\xba\xa0\x74\x70\xe6\x63\x5e\xeb\x44\xfa\xf0\x60\xc5\xe3\xd2\x4b\xd4\xaf\xda\xcc\x8a\x12\x1f\xad\x07\x9d\x66\x33\xdd\xac\x2c\x3c\xe7\xc4\x23\xec\x27\x95\x4c\xab\x2b\xb7\x06\xc5\x7e\xd9\x9d\xd3\x51\xf9\xf9\x09\x34\xa7\xe9\x21\xcf\xd9\x7a\x1a\x90\x46\x8d\xb7\xa8\x0a\x7a\xac\x3f\x64\xb3\x97\x7f\x3e\x23\x9b\xe5\xbe\x7d\x00\xb8\xe1\xdf\x0e\x27\x35\x75\x3b\x16\xeb\x37\xb2\xc8\xc6\x88\xa2\xb7\xd2\x8e\x06\x24\x4e\xfe\xe9\x65\x5d\xa4\x6a\x75\x88\x93\x79\xa0\x48\x47\x5a\x3e\xaa\x8c\xdc\x17\xa7\x0b\xac\xcc\xc0\x60\x84\xba\x2c\xaf\xf3\x38\xe9\x27\x41\x87\x5b\x83\x70\xae\xbd\xed\x47\x8f\xb1\x6b\x24\xa8\x30\x56\x02\xc6\x01\x3e\x9b\x6f\x37\x55\x11\x2c\x82\xaa\xa1\xb3\xef\xab\x0f\x2e\xcd\x65\x21\x69\x3c\x04\x50\x18\x2d\x2e\x95\x43\xec\x77\xe6\xf1\x18\x2c\x26\xee\xfb\xd6\x20\xc2\xfa\x14\x37\xd4\x14\xc8\x54\x45\x85\x1e\x00\x5d\x18\xbf\x8d\x74\xfd\x95\x7c\x0c\xb5\x4a\xe1\xda\x00\xaf\xf2\xf6\x70\xdb\xd2\x97\x67\xb0\xcb\x03\xf0\x32\x64\x76\xa4\x58\xcb\x28\x8b\x8c\xa1\xad\xd1\x10\x92\x09\x43\xdd\x7f\xda\xaa\x64\xef\x21\xd8\xf7\xee\xa2\x8b\xc5\xd6\x26\x56\x6d\x20\x30\xd0\xba\x7a\xa1\x45\xbc\x4e\x92\x91\xe0\xa2\x71\xa7\x30\xf5\x82\x51\x1e\xe0\x33\x68\xf7\x22\x98\xc2\x81\xda\x96\xd7\xbe\xf0\xc4\x87\x70\x05\x00\x23\xab\x64\x0a\x5a\xbe\x95\xca\x86\xbe\x7c\x5e\x03\xa7\xa7\x58\x63\x07\x62\x49\xf4\xd4\x8b\x37\xf4\x7e\x85\xf1\xa6\xb4\x0b\x76\x8f\x6d\x3e\x5f\xf8\x9c\xef\x1f\x17\xa9\xa1\x2e\xc1\xf8\xf7\x47\x1e\xff\x67\xbc\xf7\xc5\x9a\xfb\xfe\x19\x63\xe1\x74\xff\x54\x9d\x0f\xb7\xfa\x05\x4b\xd8\x3f\xf8\x93\xae\xbf\x24\x7e\xfe\x27\xd5\x42\xe6\xfe\xf9\x36\x70\xd8\x6d\x08\x7d\xd1\xb1\x62\x3f\xff\x24\x09\x65\x1d\xf6\x9a\xe4\xc2\xbb\xc6\xc2\xa2\x4b\x20\x50\xc2\xcb\x43\x1d\x39\x57\xa3\xf1\x9d\x1a\x33\xc0\x25\xea\xb5\x9e\xe3\x93\x07\x75\x97\x93\x49\x4f\x79\x0e\x37\x6f\xa2\x44\x2c\x3a\x1d\x9f\xe1\x5e\xbf\x48\xcb\x44\xbb\x76\x81\x04\x1d\x0b\x71\x37\xa5\xa5\x3b\xac\xe9\xe6\x74\x2b\x24\xfc\x82\x96\x20\xd1\x85\xc3\xed\xa1\x6c\x33\x8f\xa1\x89\xb0\x1c\x62\xac\x5a\xfa\xda\x85\x28\xc2\x85\xd4\x52\x8a\x06\x9b\x2b\xdd\x52\xc2\x01\x16\xc1\xf1\x37\xb9\x5e\xc2\xcd\xf9\x47\x9f\x04\xad\xce\x68\xa0\x2b\x1c\xc8\x25\x95\x54\xb4\x1e\x5f\x27\x47\x74\xb7\x13\x71\x92\x23\x9a\xcd\x15\x3e\x90\x54\xe0\x31\xea\x43\x7c\x02\xe1\xba\x2b\xb2\xf7\xad\x1d\x2b\x10\x8b\xc2\xda\x22\xec\x82\x93\x0b\x22\xa1\xfc\x61\xf1\x00\xf8\x75\x3f\xdc\x97\x85\xd1\x71\xea\xd2\x1f\x10\xe2\xd2\xb9\xa7\xe5\x4f\x07\x2e\xc1\xf9\xb0\xb8\x5f\xc2\xa5\xd8\x3d\xa1\xeb\x55\x70\x1d\x05\x04\x96\x77\x3b\x23\x7a\x3d\xf9\x53\xf9\xb2\x3e\xaf\xf4\xea\x62\xee\x3c\x7e\x55\x9d\x8f\x7e\xbe\x98\xc7\xb2\x01\xb1\x51\xfa\xfc\x4e\xc1\x74\xf4\x70\x7f\xab\x02\x88\x29\x01\x59\xbb\x54\x36\xb0\xbb\x5d\xdb\xee\x5b\x3f\x41\xfa\x1a\x6b\x6e\xef\xb5\x25\xb4\x46\x94\x6a\xd9\x48\x62\x4b\x62\x90\xd1\x13\xb5\x26\x7e\x40\x92\x4b\xd9\x5e\xae\x46\xa4\xf5\x72\xbe\x27\x71\x9b\x91\x4e\x91\xcf\x8d\x28\x05\x53\x0d\x0e\xc2\xeb\xc9\xdf\xb3\x9c\xab\x74\x17\xc4\xc1\x77\x1e\xea\xa1\x1f\xa1\xac\x43\x3c\x3b\x25\xe8\x69\xa8\xe8\x01\x42\xe0\x94\x9d\xdd\xa5\x2e\xa5\x5c\x50\x9e\x61\x33\x5d\x6c\xea\x5c\xbb\x32\xca\xb7\x69\x1a\xa0\x06\x29\xf4\xcb\x15\x4e\xc8\x96\x22\x53\xbf\x2f\x5a\xe8\x6a\xa5\xd3\x90\xaa\x34\xc3\x7c\xf6\x71\x1f\xce\x3c\x1f\xff\xb6\x39\x06\x54\xb7\x25\xd6\xd6\x37\x45\xd9\xd8\x3e\x65\x01\x80\xf6\xd7\xe5\x94\x6b\xc6\x7a\x90\x5e\x59\x94\x73\x3b\x49\xcd\x03\xf7\x11\x90\x0e\x5a\xe3\x8e\x6b\xb1\x3c\xcb\xe9\xf0\xb8\x8d\x42\x24\x61\xfe\x52\xd6\x09\x49\x05\xc5\xc0\x76\xf0\x77\x1d\x2d\x3b\xdf\xee\x28\x34\xb6\x20\x3a\x76\xd0\x77\x38\x63\xdd\xd4\xa3\x2e\x7f\xc2\x76\x63\x1f\xae\xf8\x4b\x87\xf3\x9d\x88\xf9\x87\xe2\x82\xfa\x34\x98\x04\xdf\xae\x69\xe8\x1b\xe9\x0e\xc2\x46\xb8\xde\x43\x3f\xa1\x1a\x67\x63\x32\x17\x26\xe4\x96\xed\xda\x54\x68\xd5\xfe\x10\x36\xb6\xf0\x29\x57\x61\x36\xdd\x84\xe1\x47\xf1\x24\x4b\xe2\x3c\x35\x57\xbd\xc7\x07\x58\x08\xbd\xa4\xe9\x40\x21\x90\xc1\x17\x2c\xf8\xa6\xf4\xbf\xb3\x1e\xe9\x6c\x23\x88\x2d\xd8\x5f\xa4\x68\x0c\x47\x62\xf5\xac\xec\xf1\x15\xae\x23\xb5\x6e\x9c\x91\xc1\x3f\xd3\x79\x6d\x60\x16\x84\x7d\xb1\x5c\x5a\xf6\x2c\x50\x97\x05\x14\x69\xf0\xb5\x40\xbe\x07\xa5\xa0\xd0\x28\x0f\x45\x05\x8f\x7d\xe1\x54\xe2\x04\x36\xdb\x6a\xa6\x2a\x87\xb0\xc6\xaf\x1a\x20\x57\xe8\x21\xa4\xf3\x2f\xfc\x88\xe7\x50\x3f\xf8\xa3\xbe\xfa\xde\x42\x12\x5a\x8e\xd4\x2d\xe5\x37\xdc\x61\x95\xf7\x00\xca\x8e\xfe\x29\x76\xbb\xf0\xa7\x06\x28\x8a\x7b\x96\xfd\x45\x15\x67\xac\xfe\xc0\xb6\x50\xbb\xab\x42\x02\x72\x2f\x0f\xa6\x50\x90\xb0\x2c\xbe\xf2\x2f\x76\x47\x69\xf8\x91\x3f\x2d\x7f\xe8\xad\x02\x3b\x2d\x72\x58\x15\x29\xf8\xe7\xc2\x7b\x67\xc3\xe4\xd9\xc7\x72\x10\x12\x49\x2f\x07\x82\x8d\xbd\xbf\x4d\x92\x29\x0d\x80\x99\x16\x96\xd7\xa4\x4d\x10\x7e\x46\x8c\x3a\x8f\xa0\x47\xc4\x59\xb8\xc5\xe8\xe7\x9c\x66\x5e\xc5\x4f\xb7\x60\xba\x57\x3b\x62\xed\x1e\xae\x95\x76\x03\x5b\x51\x71\x34\x24\x0f\x74\xbc\xd4\x4a\xe1\x53\xac\x8f\x1a\xa3\x90\xb0\x01\xe2\xe9\xfa\x01\x63\xf5\x3d\xf1\x50\xc7\xa9\x38\xb0\x29\xcf\xc6\x16\x0c\x92\xe2\x31\x32\x90\x8e\xa1\x16\x3b\x6f\x4d\x84\x9d\xad\xe9\xff\x73\xf5\x6e\x59\xb2\xea\x3e\x13\xe7\x7b\x0f\xa3\x5e\x6a\x54\xfd\x60\xc0\x09\xae\x04\xcc\x9f\x4b\xe5\xce\x5a\xab\xe7\xde\x0a\x45\xc8\xe4\xf9\xea\x9c\xbd\x90\x49\xee\x17\x63\xcb\xd2\x2f\x5a\x7a\xfe\xaf\xa7\xf8\xab\x40\x30\x96\xa8\x00\x68\x84\x47\x70\x21\x44\x0a\xc3\xcb\x04\x9f\xcd\x5c\x1a\x4a\xc0\x95\x71\x94\xbe\xef\xe8\x11\x5a\xad\x59\x03\x7b\x48\x32\x9c\x92\x19\x0b\xf7\x97\x40\x0c\x3b\xe3\xf6\xf6\x2c\xfd\xa5\x38\xcc\x2d\x58\x0a\xd2\x97\x95\xed\x22\x7f\x1f\x18\x02\x7c\xb2\x74\x02\x76\x81\xe4\xae\x34\xdb\xa5\x47\xa5\x4b\x2c\x1d\xd2\x4b\x8b\xdd\x8a\xe0\x3b\x84\x57\x52\x83\x6d\xa2\xff\x20\x41\x61\xeb\x8b\x68\xab\x18\xd1\x0e\xac\x02\x18\x6e\x11\x0a\xea\x41\x2a\x5c\x44\xa9\x15\x0d\xa8\xf0\x1b\x64\x65\x8f\x4a\xe4\x35\x99\x28\x90\x15\x30\x08\x78\x05\x76\x22\x07\x02\x0a\x1f\x5a\xc6\x8f\x2b\x90\x3d\x3b\xc8\xb0\x63\xde\x83\x4b\x86\xb4\xf3\x35\x7e\xca\x8a\x13\xb4\x57\x72\x0f\x51\x64\xd7\x67\xd6\x5c\x0c\x5c\x87\x59\x90\x2e\x9f\xa8\xb8\x8c\x0a\x21\x85\x56\x72\x88\x26\xbf\x28\x9e\x1d\x1f\x99\x1d\xd0\x6c\xce\x09\x95\xdf\x3d\xfd\x64\xe9\x7d\x27\xb9\x5f\x9c\x28\xac\x0d\xd8\x71\x49\xfc\x78\xb4\x9e\x52\xa6\xa5\x6d\x0d\x6a\x42\xa2\x92\x63\xa3\xcd\x07\x9f\x3c\xc4\xee\x2b\x00\x08\x84\x2b\x38\xe6\x00\xb9\x65\x92\xd9\x7d\x7b\x5d\xb2\xbd\xc7\x25\xcd\xa1\x7b\x7c\xe8\x21\xda\x04\x49\xb3\xc6\x0d\x32\x56\x68\xfd\x57\x22\x79\x61\xab\x7f\xbb\xb4\x83\x0d\x6f\xbe\x82\x1b\x1c\x5e\x50\x90\x97\xd7\xb0\x00\x57\x88\x0f\xd7\x5f\xc4\x1b\x64\xda\xf8\xe0\x47\x52\xb6\x8b\x23\xef\xc1\x34\xd8\x4b\x66\x1a\xbf\x87\x9e\x0d\xb4\x9a\x10\x72\x23\x16\x68\x3b\x9f\x9c\x00\x2f\x44\x06\x8c\x4b\x20\xb3\x1e\xb5\xe7\xfb\x1d\xf8\x81\xdf\x26\x30\xbe\xe1\x7d\x6c\xc2\xc6\x91\xe0\x0f\x16\x1f\xe9\x1c\xe0\x11\x30\x02\x83\x04\x82\x40\x0a\xb4\xfc\x7e\x85\x70\x62\xaa\xa6\x9e\x4c\x6e\x13\xbc\x28\x5e\x93\xba\x7d\x7c\xf0\xad\x01\x28\x74\x06\xb8\x02\x4a\x3e\xaf\xf5\x41\x72\x81\xbd\x2a\xbc\xca\x08\x0c\x29\x54\x4d\x76\x91\xe3\x5b\xb6\xd3\x66\xcc\x55\xbf\x40\xf2\xf1\x4b\xf0\x81\x80\x0e\x08\xdf\x30\x7b\xe8\x4e\x30\x07\x44\x7c\x03\x47\x80\xd1\xf6\x2a\x71\xfc\x2a\x0a\xe8\x8f\x86\x9d\xd3\x25\x74\x41\xd2\x38\x16\x35\x90\xdb\x79\xcc\x29\xe8\xe4\x5b\x39\xe3\xdd\xdf\xca\x1d\x99\x00\xe0\xc0\x3b\xac\x10\x21\xdc\x90\xb9\x63\xed\x05\x9e\x4a\xd1\x00\x10\x0c\xd1\x0a\xc6\xf1\x1d\xe9\xf4\x05\x78\x24\x6d\x20\x87\x72\x35\xd2\x4d\x3f\x3a\xe4\x4c\x3f\x8d\xcf\xb4\xf5\x27\x0f\xc4\x6c\xfa\xa1\x20\x87\x98\x18\x44\xd7\x55\xde\x8e\x30\x3b\x32\x0c\x24\x0a\xb3\xc1\xbb\x54\xdd\xc7\x6f\x55\xda\x7b\xe7\x94\x12\xcb\x2c\x1c\xd3\x59\xa8\x87\x6d\xad\x05\x56\x9a\x9e\x6e\x73\x4b\x73\x6c\x2e\xe2\x85\xd6\xe1\x9b\xa5\x2d\x47\xb2\x3c\x39\x79\xf1\x0d\xd8\xa0\xc7\xee\xd3\x35\x7c\x37\x4e\x41\xe0\x94\xc8\xa6\x2d\x2f\x08\xf3\x24\x21\x21\x0b\x82\x30\x04\xbb\xc9\xea\x99\x3e\x2f\xa2\xbc\x42\xb0\x19\x6d\x38\x37\xe3\xeb\xbd\x39\xaf\x85\x57\x48\x3c\x04\x80\x9d\x2f\x1f\x2e\xda\xf4\x89\xf4\x1e\x41\x96\xc5\xf8\x32\x28\x33\xeb\x55\x42\xe3\xe1\x5b\x56\x62\x48\xc3\x96\xe6\x93\x6a\x90\x1b\x50\xef\x52\x77\x8e\x08\x3c\xb3\x44\x3c\xda\xee\x6e\x9e\x83\x0c\x66\xb6\xac\x60\x4f\xed\x53\x88\xd2\xa0\xd8\x49\x4f\x1e\xb2\x7b\xe0\x1d\x07\x2f\x10\xc9\xe3\xba\xcc\x33\x9d\x0d\xd6\x0b\x39\xbc\xe5\x6d\x06\xaa\xc0\xf8\x5c\x50\x86\x59\xf4\x00\xe8\x3c\xd0\x6b\x0e\xb2\xd7\x1e\x14\x83\xe4\x29\x29\xf8\x24\x89\x8e\x05\xd3\x27\xd1\x9d\xfa\xcc\x7e\xab\xb5\x52\x70\xf9\x3f\x4a\xcb\x21\xb4\x6c\xaf\xa2\x42\xcf\xeb\x4c\x79\x27\xb2\x0a\xdc\x0f\xef\x4b\x71\xb9\x51\x54\x87\xe1\x7d\x1c\xf9\xa2\x59\x43\x3d\xea\x96\x5a\xbf\x4b\xab\x0f\x1f\x06\xa1\x80\x36\xd2\x14\x23\xcc\x7a\x7d\x57\x42\x01\xec\x00\xa6\x9b\x54\xb3\xda\x75\xe1\xcb\xb2\x5e\x3e\xb6\x6e\xf5\xc7\x1f\xc3\x94\xd6\x8a\x51\x49\xbf\xb1\xab\x30\xf3\x2b\x3d\x31\x2b\xc9\x6f\x6b\xdd\x5f\x79\x54\xeb\xcd\x79\x05\x07\xc3\x11\x20\xe3\x4c\xbd\x65\x0c\x54\x32\xd5\x68\xad\x90\x19\xf3\x25\xd1\x79\xc0\x40\x2b\x37\xe2\xfd\x5d\x11\x03\x5c\xfd\x88\x80\x75\xb3\x19\x1d\x62\x6f\xc5\xc5\x89\xbd\x04\x5c\xaa\x7f\xae\x82\x12\x99\x9d\x9b\x9a\xf3\x4b\x9a\x1f\x6b\x76\xce\x05\x15\xa5\xf3\x78\x87\x2e\x22\x53\xd5\xb3\x60\xad\x51\xbf\x73\x46\x04\x72\xac\x11\xe1\x6d\x8d\x6d\x6b\x12\x2d\xb4\xbc\x49\x8c\x88\x23\x96\x57\x6f\x33\xad\x50\xcb\xa7\x3c\xb4\x18\x6d\x2b\x6b\xa6\x15\x03\x9d\x98\x7e\x1f\xef\xd5\x55\x7f\xdf\xf7\x7b\xe4\xc5\xe3\x0c\x75\x86\xe5\x96\x6a\x42\xd2\x9f\xe4\x9d\x01\xd2\x7d\x14\x5a\x07\x87\x21\xcd\x22\x59\x02\x46\xe0\x8e\x96\x6b\x3f\x13\x6f\x89\x18\x08\x92\x9f\x6e\x4f\xa4\x99\x52\x09\xbe\x5a\x36\xf7\x62\x9f\x25\x4f\x63\xbf\x82\x2a\x60\xa7\x1a\xfd\xa9\xa5\x4a\x28\x61\xe1\xcd\x05\xc4\xa0\x49\x74\x2f\xc8\x6a\x59\xc1\xd6\x7f\x84\x4a\x74\x95\x62\x35\x52\x4a\x69\x58\x73\x97\x7d\x92\x05\x8c\x9b\x95\x86\x67\xfd\x8b\x80\xe0\xec\x35\xae\xdd\x3b\xf2\x9e\xf6\x37\x8f\xbd\xfc\x0b\x19\xe7\x63\x67\x35\x66\x56\x04\x3d\x40\x39\x3a\x73\xec\x0f\x66\x0a\xaf\xdd\xe2\x79\xa0\x74\xb7\x2c\x1e\x5b\x2d\xd0\x15\xb7\xb4\x96\x0f\xbc\x01\xc2\x0a\x38\xe8\x03\x7a\x41\x28\x2c\x9b\xa9\x0c\xde\xa5\x8c\x7b\x58\x56\x63\x21\x6c\x30\xcf\x1c\x29\x5b\xb2\xe2\x61\x98\x78\x45\x51\x18\xb6\xe8\x40\x33\xb0\x57\x53\xa1\x83\xc0\xf5\xec\xb1\x4a\xae\xc2\x16\x1c\xd5\x7a\x6b\x12\x95\xae\x3b\xb5\xb1\x33\xb6\xce\x4d\x06\x57\x6e\xf1\x64\x00\x69\x62\xe7\x20\xd5\x21\x06\x37\xe4\xc5\xfb\x35\x6b\xc8\x6f\xe9\x47\x74\x9d\xdc\x4a\xfb\x4a\x87\x99\x3d\x97\x7f\x5e\xdf\x2c\x11\xab\x83\x27\x35\x2f\xe9\xd6\x3b\x43\x80\xe0\x7e\xfb\x44\x22\xc1\x98\xe9\x83\xf8\x48\x0a\x4e\x60\xc5\x5e\x7c\x5b\x48\xab\x24\x06\x57\x42\xd4\x5a\x9c\x81\xfd\x37\x9a\xc3\xd0\xb6\x0e\xd0\xc0\x6e\xcf\x50\xa6\x55\x95\x74\x0c\xb3\x01\x07\xac\x11\x39\x5c\x4f\x2d\x11\x88\x85\xbd\x6f\x72\xd7\xeb\xc7\xad\x05\xbb\x3b\x50\x09\x20\x1f\x84\xe9\x9c\x12\xf2\x1a\x56\x7a\xd8\x17\x97\xdc\xa7\xf1\x21\xf2\x04\x36\x82\xb5\x61\xd4\xb0\xb0\x52\x9a\xd8\x46\xc3\xc7\xef\x9c\x64\xc0\xf5\x70\xca\xae\xbf\x41\x88\x28\x4b\x9c\xdc\x98\xfe\xfe\x03\x4c\x38\xbc\x0b\xbe\x24\xb4\x89\x3d\xd9\xde\xc5\xad\x99\x77\x8f\xf4\xf3\xb8\x6c\xb3\x0f\x8a\x71\x2b\xf3\x65\x3d\x14\xdf\xc4\x7c\xf9\x57\x4a\xe8\x84\xe0\x1a\xb8\x64\xee\x48\x8b\xfc\x03\xeb\xca\xd6\x4b\x74\x84\x4a\x29\x34\x34\x7d\x09\x31\x00\x28\x84\xcd\x15\xe1\x35\xe7\x3a\x04\xc8\xc4\x3e\xa7\xd5\xa9\x24\x5c\x85\x5d\xea\xb9\x86\xfc\xc5\x5c\x02\x64\xa0\xc1\x02\xf7\xc4\x7a\xa2\xa9\x7e\xb7\xcf\x1d\x5b\x9d\x80\x26\xa0\xd3\xc0\x1d\x95\x87\xa4\xb7\x35\xf1\xce\xec\x5c\xa4\xd9\x34\xe7\x97\xf0\x08\x60\x9c\xc7\x69\x91\x4f\x59\xdd\x31\xe6\x04\x05\x3f\x26\xb4\x9f\x29\x7b\x9d\x05\xeb\x98\xf3\x72\x91\xa9\xa0\x8d\x8d\xe5\x50\x22\x8b\xd9\x37\x27\x7d\x46\xc8\x35\x52\x81\x09\x39\x78\x2d\x32\xac\x35\xba\x87\x2c\xf6\x71\x3c\xeb\xf6\x70\xd3\xb3\x16\xbf\x04\x4e\x40\xaf\xe6\x50\xe1\xc1\xc1\x14\x88\x48\x5a\x23\x95\x16\x42\x73\xdc\x0a\xaf\xc6\x0c\x46\x09\xb7\xdf\xd3\xf5\x39\x03\x76\xa7\x2d\x76\xd6\x06\x97\x5e\x37\xb2\xc8\x49\x2b\x78\x05\xc4\x80\x7e\x95\x27\x82\x7d\xac\x07\xe2\x24\x84\xed\x1f\x1e\x8a\xa7\x14\x4b\x9f\x90\xce\xf5\x19\xf8\x9a\xd9\xe7\x8c\xd1\x28\x4f\x7b\x98\x1c\xba\xf8\xb4\x1a\x7a\x25\x0f\xcc\x4c\xfb\xee\x9c\xee\xb9\xb2\x8b\x8d\x10\x7e\x5a\x12\x42\x83\x45\x5d\x21\x90\x06\xbf\xa9\xc9\x8d\x47\x4f\x6a\x9b\x00\xb5\x2e\x12\x5c\x7b\x4e\xfb\x75\x58\xdd\xf6\xcb\x5f\x26\x3a\x6b\x9f\xf9\xdd\x12\x0d\x9e\xf9\x45\x70\x03\xfd\xe8\x78\x3d\xb2\x00\x0e\x5c\x07\x94\x93\x2a\x0b\x31\x5f\xbe\x3f\x7b\x2b\x17\x8e\xa7\x41\x97\xd9\x61\x4b\x66\xf0\xf8\x7e\x1a\x97\xe7\xe7\xfa\xb1\x85\x2e\xb7\x86\x60\x74\xfc\xb0\x97\xf7\x03\xa8\x25\xa7\xd6\xf4\x62\x67\xeb\xa7\x9e\x21\xda\xbd\x22\x08\x96\x47\xf0\xc3\xbc\xc4\x9f\xdb\x1f\xfa\x53\x90\x65\x4a\x13\xe3\x9f\xde\x93\x32\x4b\x81\xc2\x3f\x1e\x0e\x49\x17\x35\xec\x98\x9b\x37\x4e\x11\x7e\xc6\x87\xfc\x27\xfd\xfa\xf9\xfc\xd8\x2b\x80\x61\x85\x35\x6c\xfd\xba\xe0\xae\xe7\x2f\xca\x79\xfb\xbc\x22\x66\xae\xdb\x48\xec\x83\xe0\x71\x68\x6a\x87\x24\x66\x09\xa8\x00\x34\x81\xcb\xf8\x29\x49\x1d\x73\xc4\x2c\xf0\x28\x07\x9a\x88\xb9\x6a\xf0\x87\xbd\x22\x58\x8a\x6d\xc5\xc6\x82\x90\x9a\x35\xc6\x01\xaf\xad\xa9\x70\xef\xdb\x9e\x1b\x6d\x01\x45\xb0\x5b\x45\x22\xf3\x19\xca\xeb\x27\x36\x62\x4f\x62\xdf\x48\x8d\xbb\x01\x16\x58\xd2\x66\x0e\xe5\x90\xf1\x68\xe8\x10\x12\x0d\x42\xcd\x2c\xa4\xef\x4a\xc8\x7a\x45\x62\x6e\x83\x3c\xcc\x9e\x7a\x44\xee\x43\x6c\x0e\x39\x15\xf3\x0d\x6a\xb8\x15\xf5\xca\xea\xd9\x8c\x4d\x82\x7b\xb8\x98\x28\x19\x47\x8c\xde\x79\x6a\xec\x0a\x7d\xe9\x65\xaf\xb1\x7b\x04\xb0\xcb\x00\xe9\xf9\x8c\x43\xe9\xa5\xe0\x7d\x2c\x0c\x2e\x36\xb3\xf7\x64\x1b\x1d\x07\xb1\x5b\x24\x3a\x28\xf0\xd1\xb5\xba\x55\x33\x7b\xff\xf2\xd3\x8c\xfc\xc1\xb2\xd8\x47\xf4\x92\x63\x46\x49\xe6\x68\x53\x85\xac\x00\x24\xbd\x7d\xde\x00\x20\x9c\x67\xbf\x51\x69\xf5\x51\xe2\x49\x19\xbe\xfd\x2c\xfa\x48\x07\x2a\x1d\xc2\x4e\x1e\x5e\xbb\x95\xef\xf2\x4d\x69\xef\x85\x70\x81\xf7\xb0\x5b\xdb\xeb\xa0\x0d\x21\x4d\xac\x31\x21\xd4\x04\x38\xd7\x6f\x95\xd8\xbb\x9b\x14\x8f\x60\x53\xde\x58\x33\xec\x78\xf4\x93\x67\x92\xc9\xee\x42\xee\xdb\x7a\x01\xc0\x46\x0f\x6e\x2b\x0f\x6f\x6a\x69\xc6\xee\xd2\x9f\x44\xa3\xf2\x82\x1d\x72\x6a\x8a\xe0\xcd\xe5\x6f\x66\x2f\x45\x66\x40\x99\x09\x5c\x00\x1f\x43\x59\x42\x28\xf4\x1c\x20\xf2\xfc\x8a\xd1\xfb\x4c\x84\x35\xc4\xc6\x18\x87\xed\x9c\x86\xa5\xd6\x9b\xcd\x50\x1d\x1e\xd8\xb3\x50\x04\x73\x58\xf2\x3d\xea\x33\xd5\x47\xe3\xc9\x4c\xab\xd7\xe1\x13\xbc\x0a\x1f\x5c\x06\x8d\xc0\x4e\xc5\xc9\xe0\xd2\x2a\x9f\xe7\x35\x44\xaf\xa7\xfc\x2f\x51\xf5\xc2\x0b\xaf\x97\x13\x1f\x72\xd3\x4e\x81\x2f\xc7\x3b\xb5\x66\x58\xeb\x8f\x90\x48\x0c\x5a\x48\x32\x1c\xf9\xaa\x5c\xd5\xea\x04\xce\xd2\x89\x03\x84\x33\xb2\xcb\x64\x76\xbb\x5e\xd9\x9a\xc7\x6f\xe9\xa1\x6b\x94\x00\x89\xac\x9b\x3b\x61\xa7\xac\xaf\xef\x94\xbb\xdd\xba\x39\xb4\x42\x7a\x3d\x64\xae\xfc\x23\xae\xf7\xd1\x6c\x6a\x98\xb7\xfe\xb5\xc7\xd8\xc9\x2f\x82\x20\xbb\x60\x17\x99\xbd\x87\x10\xd6\x94\x3c\xdc\x47\xf4\x06\x6f\x93\x68\x99\x6d\x7b\xcb\xa2\xc2\x5b\x14\xc6\x68\x31\xa1\xdd\x56\x34\x6d\x72\x2c\x2c\x8c\xfc\x1d\x7a\x5b\x39\x37\x88\x44\x6c\x62\x7e\xec\xf9\x29\xab\x1d\xde\xc8\x08\xe6\x09\x19\x4f\xb8\x3c\xe3\x9b\x4e\x4b\x97\x3f\x27\xb9\x41\x41\x3a\xe3\xf5\x21\xb6\x34\x5e\x2d\x6b\x79\xbc\x42\xe0\xc0\xda\xc9\x18\xab\x56\x2c\xcd\x28\x94\xb8\xc3\x23\xbe\xc3\xea\xa9\x5d\x5e\x91\x4e\x11\x96\x16\xaf\x74\x2b\xd9\x11\x49\xab\x9c\x6e\xd4\x11\x74\xc3\x4a\xe3\xf1\xd0\x86\xb2\x84\xbe\xbe\xa4\xa1\x7e\x30\xaf\x1b\xdd\x0a\x85\x1a\x33\x9a\x3c\xe6\xae\x94\x24\xdf\xbd\x49\x72\x4e\x4d\x56\x1d\x57\xad\xd3\xe2\x03\xbd\xbb\xe3\x1e\xd4\xfa\x51\xb0\x97\x11\x47\xbb\xd1\xaa\xec\x6e\x9b\xd1\xcd\x61\x68\x6b\xf1\xe2\x58\xef\xcc\x3e\xbe\x6f\x72\x2d\xf8\x34\x49\x36\x9d\xd6\x80\xfe\xa4\xae\xd1\x2a\x1d\xf8\x59\xee\x39\x33\x9c\xf4\x60\xcd\x49\xdd\xfa\x71\x96\x80\xf5\x58\xfe\x48\xce\x1d\x8b\x9e\x04\xab\x32\xfe\xa8\xb4\xbe\xb0\xc6\x82\xe1\x5f\x4d\xd7\x53\x0f\x78\x04\x7c\x56\xbb\xb4\xd4\xad\x9e\x9e\x42\x56\xdd\x2f\x76\x3a\x59\x94\x2a\x7c\x10\x33\x20\xb5\xae\x23\xb2\x6b\x34\x95\x1f\xbf\x32\x69\xc6\x28\x65\xac\xe9\xb9\xbc\xdc\x05\x84\x06\xe7\xc8\x0f\x18\x93\xd5\x95\x8a\xdc\x1a\x13\xf5\x99\xec\x4b\xa5\x86\x32\xac\x16\x36\xf8\x00\x7f\x86\x34\x89\xa5\xb4\x20\x88\xc7\x35\x0c\x3e\xe9\x05\x8b\xb0\x0a\x0a\xd9\x86\x54\xa3\x80\x20\x7b\x27\x7a\xc0\xde\x74\xdb\xa3\xf5\xa4\x20\x3b\x59\xe2\x67\xc3\x44\xa6\x95\x96\xb0\x6a\x77\x56\x94\xd3\x03\x12\x8c\x4a\x54\x79\x20\xaf\x87\x6c\x03\xef\x91\x17\x11\x22\x76\x56\x54\x4e\x95\x60\x0e\x5b\xa8\xb4\x93\x04\x60\xa5\x2e\x0d\xb2\x28\x36\x6f\x75\x6e\x93\xa1\x83\x34\x0a\x5e\x71\xfe\x10\x5a\xb2\x8f\x4a\xe4\x3f\xd4\xdb\x51\x29\x34\x53\xfb\x02\x51\x8f\x60\x8a\xf9\xe2\xe4\x56\xc3\x36\xbb\xb5\xfc\xcd\x8e\xc4\xd0\x07\x12\x6d\xa2\x85\x63\x05\xb9\x4c\x60\xf9\xa4\x08\xce\xfa\x98\x1b\x53\xdb\xcc\x44\x49\x33\x6b\x35\xf0\x2b\xf0\x28\xff\xd4\xbf\x01\x8f\x42\x70\x0d\x6b\x16\x30\x10\x02\xf8\x89\x10\xc0\x23\x8a\x22\xed\x77\x69\x0e\x00\x87\x7f\xee\xba\x24\x96\xc5\x7a\xf7\x2b\x1e\x91\x39\xf0\x80\x97\xd7\xa3\xab\x1e\xec\xe0\xa0\xa9\x22\x14\x04\x95\xdf\xc9\x79\x68\x8c\x05\xb3\x1c\x3c\xe7\x66\x19\x89\x94\xf8\x6d\x90\xa1\x07\x69\x02\x0f\xeb\xa1\x78\x5d\x04\xe3\x4b\xc0\x0a\xfe\x10\x6a\x44\x8f\xb4\x3f\xc5\xa9\xa0\xbb\x04\x7d\x14\xb5\x20\x1c\x52\x61\x67\xba\x06\xa7\xe2\x96\xa7\x36\x5b\xc3\x57\x5c\x87\x2b\x58\xfb\x99\x17\xc6\x89\x12\xe8\x69\x93\x60\x43\xc0\x84\xb0\x11\x01\x96\x10\x06\x22\xe4\x65\x1a\x5e\x42\x78\x05\x07\x4d\x90\x4b\x70\x2b\xcb\x7b\xc9\x9a\x0a\x5a\x18\x96\x1b\xe9\xd8\x9a\xc3\x31\xff\x7a\x0e\xbb\xd0\x03\xbf\xcc\xa3\xe5\x0f\x1e\xe0\xeb\x6c\x09\x08\x7a\x73\x7a\xc7\x1e\xe5\x63\x41\xaa\xf9\x90\x64\x7f\x89\xfb\xa0\x41\x5c\x28\xd1\x89\x4c\x41\xfa\x23\x46\x28\xa3\xd1\x6d\x6d\x7a\x8f\x71\xcb\x5b\xf5\xfe\x16\x0e\x57\x7b\x75\x06\x44\x98\xf6\xac\x91\x97\xb1\x1e\x97\xe6\x4d\x49\x79\xbe\x19\xb1\x96\x0f\xcd\xe5\x47\x81\xc7\xb5\xa2\x52\x0f\xdb\x5a\x51\x50\x6a\xe6\x0a\x89\x84\x6e\x87\x66\x90\x1f\x01\x69\x78\xb9\xfd\xf2\xb2\x78\x8f\x24\x2b\xf5\x96\xe6\x1a\x10\xb6\xbc\x04\x15\xc3\x3a\x6d\x88\x50\x13\x03\x22\xed\x2d\xdc\x96\x25\xca\xac\xc6\x3a\x48\x1b\xe6\x6f\xe2\x43\x68\xcb\x0d\xcf\x11\x14\x10\x07\x44\xc4\x8f\x2e\x68\xad\x5b\x12\x09\x37\xb9\xe8\x3a\xda\x97\x45\xc1\x82\xc0\x46\x44\xf3\x3f\x87\xa0\x58\xce\x3e\x9a\x07\x65\x5c\xbf\xc4\x43\x21\x56\xfc\x60\xc1\xc9\x00\xb9\xff\x93\x0a\xbe\x0b\xaa\xc7\x15\x00\x56\x47\x92\xfe\x88\x0e\x7e\xd3\x08\xef\x44\x96\x6f\x6a\x78\x67\x65\xcf\xbf\xd4\x04\x1a\x7e\xbd\xa1\x39\x5c\xbf\x99\x28\x0a\x6b\xc5\x13\x1d\x70\xcd\xbd\x66\x35\x64\xcf\x10\x28\x36\x47\x4e\x84\x1c\x3d\x1b\xdf\x03\x92\xcc\xd3\xd5\x7f\x09\x35\x21\xd5\xee\xfa\x3a\x82\x0b\x60\xbd\xbd\x5d\x42\x70\xb0\xf1\xe5\x65\xf2\x7f\xc4\x0f\x0e\x9e\x30\xf8\x25\xc4\x44\x89\x03\xf9\x04\xee\x5a\xc1\xb3\x56\xf9\xad\x1f\xaa\x64\x27\x90\xa1\x40\xe0\x43\xd5\xf6\x15\xf0\x31\x94\xdf\x6b\x0e\x98\xc3\x6f\x69\x23\x8f\x0d\x58\xd1\x94\xdd\x4f\x02\x07\xbe\x1a\x97\x22\x68\x12\x47\x43\x83\x40\x68\xbe\x49\x19\xa0\x80\x2e\x91\xe4\xea\xbd\xd0\xc4\xd5\x91\x53\x50\x6e\xb5\xfb\x72\x58\x0b\xdb\xbe\x36\xb3\xb6\x72\x8b\x26\xa1\x80\xfe\x56\x5b\x10\x35\x68\x04\xf2\x01\x72\x91\x43\x7d\xcd\x0a\x8e\xfb\x69\x4b\xf6\xd6\x90\x3f\xf2\x57\x23\x5e\x58\x87\x36\x16\x64\x4b\x90\x85\xb5\x21\x2e\x22\xf9\xdc\x85\xe8\xaf\x33\x0e\xe0\x83\x56\x68\x05\x90\x95\x56\x51\x38\x6e\xb1\x78\x6b\xb4\xeb\x8a\x7b\xf3\x9d\x07\x07\x16\xec\xc1\x91\x16\x6b\x07\x6e\xd3\x9e\xc6\x85\xbf\xb8\x54\x3d\xaf\x1f\x55\xf4\x24\x4f\x2f\x49\xfa\xdf\x24\x19\x06\x09\xc5\xb3\x62\x2c\x8d\x9a\x91\x1a\x96\x0f\x6c\x8c\x5e\x6f\x13\x45\xea\xb9\xd1\xed\x56\xc2\x07\xfd\x95\x46\xbd\xda\x1d\xcc\x41\x69\x0e\x0c\xc6\x5d\x4e\x5a\x1a\x8e\xd8\x2f\x21\x34\x78\x18\x0d\x45\x42\xd5\x44\x0a\xd8\x87\x62\x3d\x78\x1d\x7e\x41\xb3\x13\xcd\xe8\x6a\x1c\xfe\x1b\xc1\x30\x64\x67\x5a\xd1\x8a\x4f\x3a\x84\xed\x3b\x47\xac\xdd\x42\xf7\xd1\xc3\x76\xad\x7b\xe9\xd4\x43\xea\xbe\x8f\xac\xcf\x01\xc3\xda\x71\x34\x83\xbb\x31\x55\x70\xfc\xc2\x7e\xf5\x1f\xbc\x8e\xa5\xe1\x41\xa8\x7b\xdf\x16\x05\xa7\x83\x5b\xf3\x8e\xbc\x86\x68\x86\xfc\xe1\xc0\x07\xc3\x63\xbb\xfd\x89\x43\xee\x2e\xbf\xff\xfc\xad\xb3\xcb\x55\x78\xd0\xd6\xcb\x29\xa2\x76\xbc\x62\xec\x10\xd9\x75\xfe\xbe\x27\x60\x99\x75\xc3\xd3\x8e\x4c\x26\x1f\x81\x19\x90\xc3\x7e\xd2\x20\xd9\xc6\xda\x1a\x99\x53\x6b\x28\x22\xa3\x9d\xf1\x14\x94\xdf\xf7\xcb\xe0\xda\xaa\x4e\x00\x78\x9f\xf5\x1f\xd9\x18\xc8\x26\x1f\x42\x64\xff\xac\x1e\x1b\x6d\x86\x90\x32\xfd\x25\xaa\x87\x07\xbb\x7d\xd3\xde\x7f\xa3\x9b\xd0\x7f\x40\xcc\xcc\x7e\xb0\x73\xd7\x83\xfb\xbf\x77\x84\xaa\xf7\x56\xc3\x55\xba\xd2\xfa\xdd\x61\x8a\x32\xfb\x82\x56\x51\x15\xc2\xe3\x52\x52\xb0\x99\xae\x81\x00\x85\x7e\xc8\x99\xf3\x67\xab\x01\xb8\x56\x8b\x57\xea\x71\xd7\xc9\xf3\x28\x1d\x67\xe4\xd7\x12\xb8\x0f\x88\x7f\x29\xb9\xdf\x43\xe0\x35\x9b\x39\x56\x50\xf5\xcf\x6c\xe4\x63\xf0\xc5\x73\xf4\xa1\xe8\xf5\x0e\x43\x8b\xbb\x8a\x1f\x57\x08\x8d\x6f\x0f\x65\xd9\x69\xf5\xcf\x18\xd2\xef\x2b\x1a\xbb\x62\x7f\x38\x36\x64\x4b\xa2\x76\xe0\xad\x01\xed\x58\x05\x4e\x3c\x7d\xee\x5b\x52\xff\x82\x4f\x30\x18\xf7\x5b\x05\xc7\x04\xaa\x80\x5b\x2e\x8b\x43\xc0\x3d\x52\x12\x8e\xcd\x99\x1d\x5a\x1b\x19\x16\x83\x0e\x60\xbb\xef\x08\x41\x24\x5c\x04\x20\x12\x3d\xa9\x31\xa3\x78\x5d\x18\x8b\x9e\x5e\x3b\xca\x9d\x84\x72\xfa\x84\xb1\x54\xb0\x56\x65\x78\x38\xf6\x5a\x37\x29\xf6\x5b\x25\xb8\xdd\xe4\x90\x70\x46\x9a\xf9\xe4\xc4\x23\xb1\xb5\x28\xfd\x4e\xb4\x95\xfe\xd2\x50\x22\xf5\x83\x92\xd2\x0b\x64\x45\x25\xca\x33\xb6\xa8\xe9\xc2\x84\xde\x46\x28\x41\xbe\x47\x6a\x6c\x11\x07\x8d\xf4\xc1\x20\xb9\x2b\x5a\x67\x8d\x30\x7e\x2b\x60\x35\x4e\x0a\x19\x50\x79\x70\x67\xd6\x26\x89\xf3\x87\x29\xd0\x0d\xc2\x76\xe5\xe1\x36\xbb\x2b\x71\x49\x97\x6f\x6d\x77\x6e\xb2\xc4\xb2\xef\x5d\xba\x40\xa0\x7e\x99\x3f\x74\x7d\x9c\x31\xb2\x77\x42\x5f\x34\xe0\x48\x9c\x51\x03\x90\x68\x55\x35\x6c\xfa\x40\x10\xf4\xd5\xba\xed\x97\x8e\x3a\x46\x35\xfb\xaa\x07\xbc\x0e\x08\x47\x1b\xe2\x4a\xdb\xa1\x37\xf5\x0d\x94\x98\x64\x02\x4b\xef\xd2\x7c\x9d\xf1\xfa\x59\xc7\xe8\x6c\xdc\x12\x8c\x43\xe7\xf4\x60\xe1\x50\x9e\x89\x99\xa5\x8d\x8a\x22\x1c\xac\xad\x1a\x72\x96\x3d\x08\xd4\x9c\xee\xa3\x70\x0a\xf0\xb3\xf1\x61\x05\xa1\x2f\x06\x66\xfb\x39\x02\x49\xfb\x72\x47\xd6\x58\xe5\xbc\x5a\x9d\xb7\xd3\xf4\x58\xd6\x7e\xf2\xc4\x25\x5a\x74\x0a\x7a\x8e\x28\x0d\xcf\x1f\xf7\xc3\x04\xf0\x74\xf5\x71\x1b\xba\x18\x6d\x46\xb1\xab\x4c\x86\x49\xf5\x38\x14\x9e\xfc\x34\xa7\xe5\x4d\x0f\x4b\x8f\xe0\x18\x9e\xf2\x54\x90\x06\xe2\xcf\xed\x94\x33\xbd\x29\x6e\xf1\x3a\x4d\xb9\x9f\xd6\x37\xd7\x49\xd7\xaf\x77\xa8\xc8\x23\x99\x92\x57\xca\x08\xe3\x38\xf7\x7c\x69\xdf\xa8\xa2\x45\x5c\xb1\x0f\x81\x78\x29\x5b\xe0\x3e\x26\x88\x2e\x0e\xb4\x06\x22\x28\x81\x46\xc9\x7f\x82\xa4\x5c\xb3\xf0\x45\x79\x97\xb7\x95\x8b\xcc\x47\x61\xd5\x66\xad\xcc\x6b\xa6\x37\x06\x36\xb7\x95\x1d\xad\xc3\x3d\xc0\x07\x28\x6f\x82\xdb\x3d\x7b\xd4\xbd\xe4\xfc\xf1\x01\x16\xb0\xe4\x04\x76\x53\xf7\x24\x11\x2f\x93\x28\x77\x31\xd0\xa6\x88\xa7\x19\x53\xb8\x26\x61\xab\xbe\xb7\xcf\x52\xf2\x51\x77\xb3\x5c\xcb\x94\x7b\x21\x64\x45\xb6\xdd\xc9\x3a\x66\x31\x5d\x76\xa4\xfe\x7f\x87\xbd\x86\xb9\x5d\x22\xc5\xa4\xbb\x9e\x72\xb3\x1d\xc7\x76\xba\xaf\xb9\x87\x40\x95\xde\xb8\x90\x29\xee\x7d\x9c\x99\xc6\xe0\xa4\x24\x6d\x15\x5f\xfe\x3b\xfc\xac\x4f\xcb\x31\x91\xd4\x8b\xd8\x63\xd6\xf5\x69\xd6\x78\x9d\x5b\x3b\x0d\xd4\x0c\xc1\x8e\x99\x3d\xc7\xa0\xea\x6a\x15\x2e\x61\xef\x5d\xeb\x72\xda\xa5\x4d\xbf\x71\x35\x7b\xf8\x78\x89\x93\x4a\x62\xe2\x76\xef\x8d\xa3\x20\xb0\x5f\x89\xaa\xf8\xd7\x1f\xa3\xb0\xbb\xeb\xcd\x0f\x2f\xa9\x17\x45\x9c\x96\x43\x20\x1b\xe0\x5b\xe6\xe0\xc6\x20\x2d\x46\x53\x6e\xa3\x6a\x5b\x6b\x09\x8e\x0b\xdc\x3f\xf5\x25\x7b\x98\xb5\x5a\x7c\x7a\xbb\x6b\x9e\xa7\xc8\xd4\xec\x02\x4a\x72\xf5\xef\x27\xa7\xd1\x1f\xe9\x38\xd6\x46\x99\xd7\x6e\xaf\xaf\xae\x45\x2f\x81\x0b\x43\x42\xde\xa1\x12\x21\x1c\x7b\x5d\x66\x19\xfc\x88\x76\x08\x3f\x1a\xc4\xa5\xb1\x13\x78\xc8\x0b\x02\xbf\xff\x18\xd9\x5b\xee\x13\x56\xe4\xb3\x78\x31\xf3\xfb\x2f\x07\x3e\xe6\x79\x6d\xf1\xcb\x40\x92\x87\x3d\x96\xaf\x8b\x80\xe0\xce\x47\x80\x64\x44\xa0\x08\x58\x32\x43\x33\xb5\xc3\x80\xf2\x81\x2a\xf3\x16\xc6\xaf\xab\x7f\x7c\xf4\x80\x8b\x09\xdc\x8a\x9b\x6d\x6e\x5c\x8c\x7a\x52\x6a\xbd\xab\xcd\x89\x6e\xe6\xe1\xbb\x46\x20\x15\xa9\x0b\x5d\xc3\xcc\x3c\x11\x2d\xff\xa0\x3d\x16\x32\x3d\xec\xf3\x77\x04\x5c\x66\x46\xef\xa3\xf0\xfa\x59\xa5\xce\xb3\x75\x30\x2f\x67\xa5\x3d\xe6\xe9\x19\xec\x66\xe8\x66\x29\x28\x01\x61\x61\xa7\xc4\x07\x1d\x1f\x23\xa2\x0c\x1d\xaa\xdd\x2c\x91\x61\xe8\x97\x08\x62\x32\x23\x82\xb3\x04\x0d\xc6\xea\xc8\x53\x49\xc4\x5c\x2e\x0d\xed\x37\xb0\xe2\x5d\x3a\xe4\xcb\xf9\x30\x88\x6f\x78\xd2\x54\x1e\x99\x59\x7d\x7a\x13\x4e\x02\x6e\x0c\xf9\xf9\x30\x7b\x26\xbf\x74\xe0\x83\xf4\x34\xe8\x31\xe6\x49\xfd\x97\x46\xd2\x15\x09\x83\x59\x87\xa4\xfe\x73\xe6\x4a\xb0\xec\xbb\xc2\x9b\xe9\x99\xeb\x1d\x52\xba\x79\x09\xac\x5d\x27\x35\x43\x38\xad\x34\xcf\xda\x10\x47\x90\x62\xc8\xb7\xb1\x2e\x86\x7e\x9b\x35\x88\x0c\xab\xfe\x4f\x46\x40\x64\xe6\x86\xb3\x01\x5d\xba\xc1\x67\x46\x51\x81\xf2\xa3\xc9\x7a\x77\x19\x51\x32\xbf\xf2\xfe\x77\x9e\x2f\x22\x6b\xfe\xcb\x64\x80\x9b\x4d\xa7\x4b\x97\xd1\x6d\xd7\x13\x04\x9b\x97\xcf\xac\x02\xb6\x05\x6d\x8f\x91\x77\xb3\x7f\xea\xb5\xc5\xf8\xd7\x19\x07\x9e\xae\x33\x8e\x3c\xde\xd4\x74\x09\xdd\x49\xeb\x8b\x48\x9b\x39\x2b\x68\x8d\x05\xc6\xb6\xb6\x22\x37\x91\x90\x12\xda\x69\x5d\x8c\x6d\x38\xbd\x86\xa5\xc6\x11\x85\x8b\x86\x09\x96\x66\xad\xa9\xd7\x1e\x24\xc4\xdc\x85\x38\x60\x17\x84\x64\x33\xa2\x6e\x48\x91\x06\x43\x8b\x47\xb3\x46\xfa\x56\x97\x16\x39\x2d\x21\x0b\xae\x63\x9d\x67\x8a\x7b\x71\x2d\xff\xb6\x74\x69\xda\x93\x76\x26\x39\x49\x07\xe5\x68\xcb\x2e\x7e\x40\x9d\x4b\x14\xda\xb1\x22\xd4\x29\xee\x5d\xea\xde\x07\xb1\x56\x66\xa1\x21\xa6\xad\x74\x42\x5c\xd9\x6d\xfe\xf5\x49\xfe\xe3\x84\x7d\xfc\x04\xa1\x36\x06\xd2\x3b\x19\xe4\x1a\x97\xc8\x06\xf8\x12\x05\x87\x63\xd7\x32\x65\xd5\x93\x91\xe6\x22\xe2\x30\xb4\x2d\x29\xc9\x02\x29\xa5\x4a\xbe\x81\x19\x52\x95\x18\xc5\x72\x30\x08\x6a\x11\xe9\xe5\x79\xf1\x00\x66\xc2\xcf\x22\x44\x0c\x7d\x6b\xfb\x35\x32\x89\x32\x61\x90\x28\x62\xca\x71\xab\xfc\x0c\x5c\xbe\xa1\xd2\x7a\xf8\x44\x8d\x3e\x24\x45\x24\xe2\x6a\xa0\x04\xf0\xcf\xdd\x93\x3c\x9d\xcd\x47\x88\x09\x2e\x21\x96\x33\x0a\xf0\x6d\x51\xf9\x16\x0d\xfc\x09\x6e\x9b\x06\xa1\x59\x41\x1e\x39\xc9\x7c\x00\x60\xfd\x1d\xee\x46\x28\xee\xcf\x61\xe0\xf5\xd2\x59\xac\xa3\xfc\x6e\x8c\x43\xbb\x9a\xa5\x9f\xed\xb9\x45\xc6\x6b\x44\x9e\x81\xe0\x56\xb5\x6f\x4a\x5a\xcb\xab\x06\x62\x1a\xc2\x96\x08\x58\x59\xc1\xb5\xc9\xb4\x1c\x7a\xc7\xce\xb0\x1d\xa7\x3c\xa8\x69\x21\xdd\xc7\x9a\xe9\x6d\x00\x34\x21\x04\x8c\xb7\x62\xf1\xa7\x96\x80\x9c\x6b\x61\x08\x51\xf0\x71\x74\x19\x54\xca\xed\xa7\x76\xe5\xe6\xea\xcd\x06\x3b\xb0\x80\x23\x62\xb8\x46\x40\x1e\xb0\x9e\xfd\x24\xc3\x5f\xef\x43\x83\x83\x7e\xa4\x64\xa9\x90\x3a\x6e\x71\xa4\xc2\x1e\xbc\x78\x04\xda\xab\x9b\x46\x0a\x9d\x5b\x65\xaa\xbd\x40\xee\x77\x9c\x7d\x8c\x39\x3d\xf6\xf0\xdd\xd9\xcb\xb1\x57\xba\x93\xd2\x43\x9a\x0c\xa1\xf7\x90\xf2\xae\x41\x66\x12\x79\x76\x59\x33\xa7\xf0\x9e\x11\x73\x33\xfc\x26\x17\x4a\x5a\x45\xf2\x81\x20\x28\x6f\xe7\xb0\x40\xb9\xfa\x3b\xec\xd5\x53\x4b\xd4\x04\x4a\xc3\xcf\x25\x32\x73\x1a\xa6\x16\x00\x61\x55\xd5\xff\xae\x76\x08\xc3\xd0\x24\x06\x69\xeb\x25\x1c\xd0\xa4\xe3\x89\xc1\x8c\x1b\xd7\x7b\xc6\x67\xeb\x3a\x21\x6a\xe9\xb7\xdd\x14\xa0\x3f\x49\x00\x12\x44\x08\xb1\x0f\x47\x98\x08\x8a\xbe\xcf\xa1\x3b\x5a\x0e\x9b\xbd\xf9\xbf\xd9\x3f\xa6\x2c\xf8\x0d\xea\x82\x11\xe2\xdc\x1e\x9e\xa0\x7d\xf4\x58\xdf\xa6\x44\x19\x9e\xe4\xcc\x1e\x33\xfe\xae\xbf\xcb\x7f\xf9\xbb\x5e\x85\x42\x55\x7f\x95\xde\xfd\x3f\xc6\x0c\xfd\x95\x6d\x76\x04\xe9\x5f\x7a\x22\xb6\xd6\xfb\x0f\xef\xcb\xd1\xbe\xef\x6b\xc1\xf3\x69\xcd\x3b\xef\x11\xbd\xab\xa3\x0c\xdf\x20\x02\x78\x19\xa0\x96\xc3\x8d\x41\x54\xf1\xb7\xf7\x5e\x06\xe6\x53\xbc\x33\xd5\x03\xde\x39\x11\x87\xe8\x86\x1a\x51\x6e\xfb\x89\xbc\x1b\xfe\xf5\x8d\x2a\xd6\xa7\xd3\xf9\xe7\xa3\x96\x6f\xc0\xb3\xfc\x04\xde\xdf\xe2\xa1\xbe\xbf\x29\xdb\xf3\x4f\x08\x98\xeb\x83\xa9\x83\x06\x17\x16\x06\xe5\xe7\x8b\x80\x1f\xb1\x4c\xcd\xb4\x7e\x56\xf5\x01\x0d\xf8\x3b\x8e\x56\x43\xa2\x54\x8a\x36\x50\xa1\xe8\x7c\x12\x81\xc1\x45\xdd\x89\xfc\x52\x38\x39\xcd\x41\x5b\x5c\x9f\x84\xff\x2c\x77\xb6\xd4\xcb\x6a\x04\x6b\x77\x1f\xfc\x65\x7d\xbe\x7c\xe2\xb5\xfa\xab\x88\x56\x8f\xc9\xb0\x27\x6f\xe2\xbe\xec\xb2\xbd\x35\xe5\x42\xfa\x38\xbb\xe1\xd3\xb5\xb2\xac\x98\x78\xa4\x8a\x3a\x00\x21\xab\x00\x31\x5e\xed\xdc\x7d\x61\x0b\xbf\xcd\xaf\x12\xcd\x31\x5a\x83\x2c\xaf\xdf\x5f\x93\xdf\xa0\xd7\xf4\x62\xf2\xe6\x6b\x72\x9e\xc3\x6b\xe2\xbe\xa6\x50\x42\x30\x6b\xb8\xe8\xa8\x33\x93\x3a\x12\xa0\x08\x45\xc3\xd2\x89\x42\xc7\xca\x71\x6c\x2b\xec\x6d\xbe\x1d\x84\xf7\x69\xcd\x0a\xc2\x89\x9b\x5c\x30\x9d\x91\xb1\x0d\x7b\xf8\x0e\xfc\xd0\x99\xc2\x22\xc8\xc1\x0c\xc5\x38\xbe\xd8\xae\x01\x86\x28\x04\x0f\x31\x4e\xe1\x7e\x3c\x18\xf9\x60\x58\xb5\xd9\x3d\x63\xdb\x88\x27\x0a\x13\x71\xee\x22\x1f\xe5\xcc\x9a\xe4\x95\x87\xb1\x08\x5f\x14\xf1\x1c\xaf\x9c\xe8\x52\x32\x63\x53\x4b\xf9\xc5\xe7\x0e\x59\xee\x8c\x60\x7d\xa5\x7f\xe2\x16\xc1\x03\xbf\x8e\x22\x4c\x79\x20\x92\x1b\xba\xa7\x36\xdd\x45\x3f\x7c\xa1\x6b\xa9\xcd\x39\x2f\xcb\x0f\xc0\xae\x9b\x8b\x8b\x03\x6f\x94\xdc\xf3\xce\xcd\x0f\x03\x2f\x03\x5c\xa7\x7e\x5f\x92\xc6\xcc\xad\x43\xba\x7a\xe6\xc0\x6f\xf5\x5e\x1c\x88\x46\x3c\x70\x64\x0b\x34\x1f\x36\x0a\x8a\xdb\xfa\x2d\xff\xb2\xe0\x44\xc7\xb4\xd6\xe0\x19\xb9\xa7\xcf\x4d\x74\xd4\xc3\x3c\xaf\xea\x20\xb1\x5f\x0a\xf8\xdc\xae\x26\x10\x8d\x84\xba\x74\xf3\x9b\xd6\x2c\xc7\xef\x6f\xf1\x5c\xa7\xdf\x32\xe6\x20\x27\x21\xc2\xc0\x3f\x75\xbf\xc5\xd6\x74\x17\x06\xc3\xed\x38\x80\x09\xa6\x91\x03\xd3\x89\x3d\x0a\xe7\xa1\x57\xed\xea\xcc\xb6\x84\x41\x27\x1a\x65\xad\x36\x73\x32\xe6\x26\x55\xfb\x9b\xe3\xf5\x87\xa5\x35\xc8\x55\xfc\x4d\xce\x7c\x76\x6b\xae\x7c\x29\x5d\xd6\x16\x7d\x52\xb7\x47\x69\x5a\x9b\xa5\x69\x7f\x47\x08\x5e\xd7\xe2\xfc\x20\xe4\x7a\x7a\x77\xd5\xc9\x44\x1c\x32\xba\x36\x74\x6f\xb9\xdf\x6b\xf3\x01\x2b\x5f\x65\x7d\xdd\x58\x66\x2b\xa0\x86\x24\xea\xe7\x24\xb3\x9e\x76\xf8\x8d\x02\x4d\x54\xfe\x53\x6a\x99\x29\xd7\xea\x5a\xf2\x53\x5b\xd1\xc9\x45\x5c\x74\xa1\xb4\xd4\x8d\x2f\xaa\xbf\xcd\x06\x79\x6e\xe5\xe1\x90\x5d\x24\x7b\x7d\x04\xdb\xcc\x0a\xcb\x27\x51\x08\x41\x46\x45\xd8\x24\x8f\xde\xd1\xfc\xfc\x6f\x83\x88\x05\x0b\x43\x0e\x8e\x86\xdb\x63\x0a\xec\xbe\x17\x63\x20\x27\x96\x5d\x4b\x03\x31\xb9\xcf\xd3\x5a\x45\x47\x5c\x97\x1e\x3c\xcd\x49\xa6\xb5\x26\xb4\xd2\x7f\x49\x41\x6a\x42\x5d\x2b\xfd\x0a\x5a\x46\xbd\x42\x95\xfc\xa6\x5d\xcb\xe6\x77\x67\xbe\x7c\x14\xed\x9a\xa6\xc9\x51\x2b\x2f\xd5\x37\x27\xd2\x6c\x3c\x8d\xe8\xbc\x8e\x27\x27\xfe\x86\xda\x14\x60\x5d\xbf\xb7\xf6\xf2\xd2\xd7\x61\xc6\x38\xf9\x1b\x0f\xf0\x50\xbc\x1d\x84\x10\xb1\xf3\x70\x5e\x8f\x07\x57\x57\x9c\xcf\x79\xb8\x73\x1c\x83\x2f\xa4\xe8\x5b\x5b\xff\x1f\x99\x3f\xfe\xd1\xb6\xc9\x86\x76\x0f\x67\x81\xf2\x7a\xee\xb2\x37\xd6\xcc\x50\x42\x5c\x82\x2a\x64\x6f\x8c\x40\x46\xa5\x23\x9e\xac\x91\x86\xb8\x2c\x6b\x49\x27\x0e\x85\xcc\x0c\x99\x43\x67\x7c\x87\x1c\x31\xe4\x2f\xdc\x79\x23\x87\x12\x02\xd4\xe8\xf2\x43\xf9\x5b\x3f\xd8\x17\x26\x36\x31\x10\x08\xb3\xb7\x16\x3f\xe2\x70\x59\x47\x9e\xf5\xda\xb3\x88\x64\x27\x32\x92\x02\xec\x03\x8f\x99\x1f\x4e\x95\xf6\xb9\x1b\x3a\xad\xaa\xe4\x34\x87\x12\x89\x13\x64\xfd\x70\xe6\xbc\x9d\xca\xb2\x47\x67\xa2\x97\x31\x72\xba\xf0\x3e\xd5\xa5\x22\x40\x8e\xf3\x82\xba\x7d\x56\xc1\x47\xce\xea\xbe\x24\x3b\xe9\x3f\xe2\x86\xa0\xfc\xeb\x21\xce\x80\x16\xe9\x04\x0a\x35\x8d\x6c\xda\x11\x30\x35\xbd\x9c\x2a\x8c\x80\x04\xd1\x84\xce\x89\x3f\xec\x17\xfd\x98\xb0\x0e\x81\x81\xf6\xd0\xad\xa4\x39\xc8\xb2\xf3\x6f\xcb\x96\x9e\xab\x5b\x3b\x80\xb1\xca\x88\x84\x7c\x06\xe7\xde\x0a\x7e\x75\x10\x9f\x58\xd7\x0b\x9e\xe4\x5d\xe5\xa4\xb8\x3e\x50\x89\x5e\x42\x0c\xe1\x1b\x18\x5b\xe6\x8f\x08\x16\xe1\xe9\xe6\x7f\x6c\x3a\x23\xe8\x58\x6b\x22\xce\xfa\xd1\x5e\x15\xd0\xfd\x78\xdc\x0e\x1f\xba\xad\x2f\x52\x86\xc0\x35\x10\x65\x88\xf4\xa1\x68\x03\xdd\x08\xa2\xb6\xa5\x19\xda\xf9\xf9\x0c\x28\x51\x03\x93\x9d\xf6\x85\xdc\x6a\x6c\x3c\x2d\x81\x8d\x06\xae\x85\xfb\xb6\x66\xb6\x43\x98\xe0\x1b\x3d\xaf\x39\xb8\x44\x9a\x5a\x55\x4f\x9f\x97\x63\x89\x06\x1a\xc4\xfa\xb8\x34\x88\xf6\xe2\x44\x71\x51\xbf\xac\x59\xaa\xe7\x0e\x61\x39\x5a\xa7\x28\xd9\xd1\x2c\xad\x6c\x6d\x11\x76\x99\xad\x8e\xd6\xac\x5e\x31\x4a\x67\x8a\xd1\x82\x53\x62\xe4\xde\x70\xf7\x13\x89\x82\xe7\x22\x1c\x6f\x66\x08\x1d\xf4\x10\x21\x95\xcc\xfb\x69\x8a\x2a\xf0\x32\xa7\xe8\x06\xf4\x61\xb2\x86\x05\xef\x48\x77\xfd\x70\xbc\xa3\x58\x0d\xaf\xb2\x80\x22\x74\xc8\x5e\x02\x03\x63\x6d\x95\x76\x59\x9d\xa9\x10\xae\x6f\x2b\x64\x61\x68\x5e\x0d\xef\x71\xfd\x22\xb3\xcb\x2d\xb1\x8c\xf0\x71\x73\x63\x5f\x99\x73\x89\xa6\x20\x61\x14\x17\x32\xa1\x09\x35\x35\x3b\x84\xe6\x55\x82\x47\x5e\xcb\x6f\x88\x66\x9f\xe1\x52\x3b\xa2\xdc\xd0\x1f\x28\x3c\xe6\x46\x43\x02\xe8\xc2\xd3\x68\x0f\xa7\xef\xf1\x74\x40\xb2\x1b\xd2\x1c\x9c\xa5\x55\x42\x41\xb0\x74\x5e\x00\xeb\xe9\x78\xd7\x48\xca\x3f\xc8\x9e\x3f\x2e\xe2\x6a\x40\xf1\xf6\x9e\xc5\x71\xc5\x86\xfa\x27\x6f\xc3\x65\xdd\xa3\x93\x8d\x20\xa2\x94\xda\x69\x58\x3f\x69\x2f\x6d\xb0\x1a\x38\x25\xe0\x90\xb3\x0a\x18\xc3\x99\x69\x86\x9b\x08\x25\xc8\xa5\xf9\xf5\x39\xe1\x01\x11\x12\x09\x26\x77\x8b\xfa\xb8\x04\xe2\x28\x94\xf4\x1b\x3f\xa9\xd1\x94\xd2\x12\x1c\xbd\xc3\xab\xcf\x23\xac\x86\x55\xa2\xfb\xdc\xa1\x2f\xaf\x06\xb4\x41\x69\xca\xab\x30\x47\x18\xce\xf3\xfb\x6a\x75\xd5\x8d\x90\x41\x8f\x31\x8e\x40\x68\x19\xae\x5b\x9a\xe0\x0b\x6c\x78\x01\x68\xe7\x97\x72\x47\xcc\xfc\x65\xb4\x33\x64\x54\xaa\xa6\x9c\x2c\x8b\xb6\x92\xf3\xfa\x7a\xbb\x47\xef\x70\xb0\xc7\xa2\x25\xcc\x9e\xe8\x54\x86\x3f\x6e\x6c\x47\x83\xdc\x1d\x09\x51\xc2\x9d\xb2\xb4\xa7\xf5\x4c\xc8\x06\xf2\x6b\xfa\xbf\x2b\x1c\x9f\x32\x33\xcd\x26\xc1\x02\x3b\xd6\xdb\x42\x01\x12\xac\x25\xd6\x17\x07\xf2\xf3\x81\x4f\x25\x9b\x67\x03\x00\xcf\x0d\x77\x0c\x73\x09\xe8\xf9\xd3\xa8\xcf\xd8\x92\xab\x4b\x80\x68\xe3\x25\x38\x8d\x19\x35\x78\x6c\x37\x97\x09\xad\x5b\x66\xc9\x98\xed\xcd\xbf\x06\x5c\xd2\x73\x83\x4c\x8b\x3d\x89\xb2\xc4\xd7\x0b\x9e\x24\x6b\x9b\xf2\x67\xb1\xb1\x5c\x0e\xfe\x22\x44\xe9\x25\x96\xd2\x39\x45\x4f\xc4\x0e\x64\xe7\xa4\x17\xf4\x07\x21\xf3\x42\x22\xf1\x5e\x58\x9f\x7e\xca\x9e\xc9\x8a\x4e\xe8\x07\xa0\x8e\x45\x19\x9b\xa0\x4e\x0b\x5c\xe5\xf1\xbb\x93\x96\x2a\x77\xf0\x20\x3e\xa6\x0e\x4c\x73\x3b\xf8\x05\x3c\xaa\x67\x1c\x85\xc5\x0b\x5c\x53\x33\x88\x7a\x02\x6b\x89\xf7\xdb\x39\x4b\x3e\xc0\x1d\xc8\x25\x5d\xd4\x35\x50\x7a\x07\x1a\x8e\xf7\xec\xd2\x90\xdf\xde\xd9\x0b\xf2\xcf\x7a\x53\x68\x16\xca\xe6\x3b\x9f\x89\xcf\xf5\x82\x41\x12\x5f\x6c\x69\xcd\x09\x37\x45\xa0\x3b\x66\x6b\x5e\x8b\x05\x36\x5f\x6d\x43\x60\xc7\x7b\x2b\xeb\x98\x4b\x40\xdd\xe6\x9b\x78\x84\x7c\x74\x49\x2a\x98\x9d\xfe\x22\x96\xe3\x78\x56\x66\xea\xda\xb1\xed\xde\x40\x3c\x58\xd8\x1a\xdb\xed\x99\xa3\xca\x2e\xe7\x93\x0c\xa6\x13\xb4\x6e\xc1\x9b\x0e\xe2\xc4\x8f\x50\x67\x3f\x4a\xf4\xd3\x0e\xa4\xa2\x40\xbf\xe7\x50\x81\x13\xbd\xe4\xa0\x1e\x73\x07\x65\x7e\x6a\x68\x06\x66\xcc\xe2\x35\x28\x10\x9b\x14\x02\xea\xee\x8b\xa2\x43\x19\x0e\x9e\x63\xba\xdc\x21\xee\xe6\x7e\x5f\x10\xb4\x36\xf8\x86\x4f\xd5\x23\xa6\x0e\x38\xf3\x55\xa7\x4c\x1f\x38\x63\xb4\xaa\x9c\x79\xcd\x4b\x6d\x9f\xc3\x50\x85\xc3\x5b\xf2\x8e\xbd\xa0\x4b\xa2\x95\xcd\xaa\x8d\xf3\x94\x79\x3a\x93\x35\x2a\x57\x1a\xe0\x29\x88\x15\x65\x4f\x0b\x01\x68\x53\xc8\xcf\x1c\x4c\x2a\x38\x64\x6a\xb1\xa1\xfd\xa8\x91\x43\xb3\xac\x6f\x3d\xbf\xc3\xe4\xf3\x8b\x01\x04\xbe\x60\x9e\xdb\x1b\xce\xaf\x23\x6f\xdb\xf5\xf4\xef\xb0\x35\x9f\x02\xa0\x66\xed\x7d\xbe\x98\x66\x80\x0b\xbf\x88\xb4\x8e\x6a\xbd\xe9\x6e\x1e\x79\xfe\x5b\x99\xd3\x8a\xb8\x30\x24\x5d\x09\x9e\x86\xe8\x87\x42\xa2\x14\x4f\x01\xf5\xb7\x2e\x7f\x7f\xb1\xe9\x78\x20\xe8\x47\x86\x5f\x9a\x7e\xbf\xac\x0e\x09\x76\x19\x43\x7f\xf8\x78\xf9\x57\x47\xa2\x3a\x28\x74\xca\xaf\x43\x97\xfa\x0c\xab\x91\xcb\x10\xf2\xa0\x99\x45\xea\x35\x07\x44\x4d\xd6\x86\x94\x2a\x83\x20\x58\xfd\xc4\x40\xff\x03\xf2\x21\xed\x2b\xd0\x27\x81\xde\xfa\x06\xf9\x87\x69\xa7\x58\x5f\x5a\x4f\xbc\x3b\x34\xdd\x1a\xbf\x8a\x41\xee\x36\x65\xa2\xe3\x21\x49\xfb\x23\x12\xed\x61\xa8\x7a\x48\x7b\x5f\xad\xe6\x14\xbe\xd1\xd3\x1f\xb8\x44\x08\x5c\x1d\xf0\x23\xcb\xa0\x97\xef\x48\xf4\x64\x81\x51\x0c\xdd\x30\xae\x39\x82\x23\xb2\x73\x74\xdf\x4a\xe2\x54\x3d\xb2\xf7\x27\x39\xb3\x17\x06\xab\x47\x4f\x4f\xac\x42\xeb\x71\x5b\x93\xc3\x6f\x50\xea\x30\xc7\x9e\x8c\x89\xc1\x9e\x20\xba\x0a\x33\x74\x2d\xae\xee\x0f\x6f\x05\xc6\x27\xdd\xec\xba\xa0\x54\x59\x73\x9c\x83\x77\xbb\x7f\x34\x06\x92\x91\x2a\xf1\x4f\xd5\x85\xe5\x19\x66\xbb\x57\x7b\x1e\xf8\x3a\xed\xa1\x80\x6d\x46\x34\x62\x61\xa2\xe5\x20\x7a\x12\xee\xd3\x3b\x4c\xef\xf2\x61\xaa\x95\xa8\x21\xcf\x60\x44\x94\xb4\xdc\x5c\x07\xf7\xe1\x9b\xf5\x88\x59\x21\xfd\xba\xd7\xe1\xde\x60\x27\x4a\xa6\x33\xb0\x38\xaf\x28\xd1\xdd\x23\x42\x76\x05\x5b\xee\x45\xf1\xb4\x3b\xb8\x9a\xfe\x04\x20\x1d\xa6\x59\xa3\x7e\xf4\x04\x3d\xb7\x02\x64\xb2\xe7\xd7\x8d\xcd\x42\x44\xb8\xd6\xc9\xbf\x37\x4c\x49\x0b\x3a\xe7\xea\xa0\xc9\x0f\x57\x40\xad\x62\xc1\x43\x01\xe7\x9e\xf1\x70\x41\x49\xbf\xfd\x82\x1e\xab\x20\x57\x1e\xe0\x1c\x88\xa9\x23\xc0\x51\x60\x39\x22\x1a\xe3\x22\x7a\xe9\xb8\x65\x9d\x44\xc8\x92\x99\xcf\x7b\x77\x56\x25\x44\xb5\x20\x32\x16\xcd\x3d\x5e\xb3\x06\xc1\x5a\x62\x1d\x68\x26\xb0\x0b\x1a\x36\xcd\xea\xa2\x0d\xb4\x91\x9b\xc0\xa3\x5b\xff\x2a\xa7\xce\x1b\xff\x22\xd6\x6a\xe7\x6f\x4b\xb9\x8f\x64\xc9\x9d\x90\x51\x76\x39\xda\x30\x9b\x95\xd2\xbf\x14\xc7\xf7\x73\xfd\xe6\x35\x30\x56\x3f\x77\x2a\xe7\x9e\x7d\x54\xc5\x1a\xce\x70\x75\xc5\x9a\xe2\x5c\xf1\x9e\x5b\xa9\xae\x71\xd4\xa3\xb5\xcb\x65\x31\x7a\x54\x67\x3a\x2a\x24\x6c\xcf\x8f\xda\x0b\xd9\x85\xf8\xd0\x58\x8f\x0d\x3e\xa4\xb4\xd8\xbe\xb5\x8e\xfc\x31\x6a\xfa\x5a\x8d\xf1\x56\x82\x23\x2a\x8f\xf2\x21\x5c\xb6\x67\xc6\x85\xa5\x58\x70\xbe\x81\x5a\x7d\xba\x19\x5e\x7d\x6b\x27\xe0\x61\x39\x99\x20\x8d\xb4\x2b\x28\xd6\xb5\x1f\x66\x29\x28\x00\xba\xd4\x10\x5d\x89\xc3\x3b\xde\x36\xda\x3b\xaf\x69\xf6\xa6\x98\x62\xd6\xe8\xbd\xb4\x5d\xb9\x74\x3b\x47\x86\x57\xe5\x30\xaa\xf8\x45\x16\x17\x39\x63\x09\x3e\x14\x7d\xfa\x1d\xe7\x27\xe4\xd6\xc6\x36\xa0\x7b\x3b\xfc\x63\xb0\x7b\x42\xe5\xc8\x5f\x7f\xfc\x0b\x0f\x44\x57\x71\xcd\x00\xce\xb5\x4f\x9f\x57\x17\xc9\xa3\xbb\xd7\x30\x83\xfa\x35\xb4\x4e\x31\xec\x80\xa4\xe1\xab\xa6\xa3\xef\xbc\xa6\xfb\xdf\x45\x3c\xcb\xff\x2e\x74\x44\xbe\x48\xf6\xf2\xc7\x03\x2c\xc4\xdb\xe0\x85\x32\x33\x73\xad\xec\xb9\x3c\x68\x22\xef\xfa\xa8\x4b\xd5\x90\x0b\x02\xf3\x85\x7d\x83\x56\xaa\x29\x54\x45\x0f\x9a\x48\x1c\x1d\xdc\x8c\x1c\xc1\xcd\xbe\x54\xe7\x75\xd3\xbe\xec\xbb\x05\x8d\x21\xb7\x47\x6f\x61\x6f\x60\xcd\xc6\x29\x39\xf0\x2b\x04\x3c\x59\xd8\xa4\x98\xc0\x92\x8f\x59\x7a\x1d\xb7\xed\x21\x70\x86\x21\xd8\x74\x94\x27\x4d\xab\x0d\x86\x36\xdf\x53\x5c\xfc\x2c\x50\x10\x21\x09\xb8\xb0\xf6\x4a\x44\x69\xfd\x0a\x74\x58\xcf\xc6\x2d\x0a\x19\x41\xbc\xc2\x4f\xed\x2d\x8b\xc9\xf5\x51\xf6\x26\xa4\x8f\xe2\xf4\x6e\x60\x00\x14\x23\x7e\x0c\xbc\xf8\x47\x58\x4b\x0c\xd4\xd1\xce\xda\xc9\x23\xbc\x9e\x8e\x23\xcb\x37\x8a\x6c\x2e\xbf\x91\x17\x6d\xb5\x07\xf4\x65\xc2\x9b\x86\xbe\x8a\xae\x01\xab\x59\x1d\x61\xa4\x4f\xb9\x27\x95\xcd\x75\x87\xf1\x89\x8b\x96\xbd\x7d\xa0\x0d\x66\x7b\x71\x49\xb3\x42\x75\x31\x00\x7a\xa5\xe5\x1f\xfe\xbd\xd8\xf0\x1a\xba\x3e\x5d\x6c\xb2\xb7\xce\x68\x03\x98\x2d\xf4\xed\x6e\xe2\x57\xed\x69\x56\x67\x77\x43\x6c\x7d\xd2\x80\xe8\x76\x67\x84\xb9\xc9\x4f\x39\x7a\x52\xfe\xd1\x52\x97\x2a\xa8\x33\xe8\xc4\xc7\x7c\xd7\x89\xa0\xa9\xba\x86\xd5\x26\x8d\x40\xb1\xc3\x91\xa0\x79\xfb\xf9\xcc\x6f\x59\xe0\x42\x30\x6a\xd0\x4a\x2b\xe3\x64\x82\xb7\xd6\x0e\xc7\x9e\xd0\x5e\xb4\x29\x90\xe1\xce\x30\xb4\x5c\xdd\xe2\x58\x16\x89\x3e\x6c\x95\xdd\x8c\xad\x16\x31\x1e\xb6\xaa\x9d\x0f\x60\xd4\xf9\xde\x67\xf6\x3b\xac\x99\x40\x5f\xaf\xb3\xd2\xf4\xc2\x23\x48\x43\x8d\x05\xc7\xa0\x89\x1c\xec\x49\xf9\xdf\x11\x09\xe2\x01\xb7\x5d\x3d\xc2\xd4\x6d\xfc\xe1\xf9\x96\x7f\x8c\x93\xdf\x02\x53\xb5\xa1\x9f\x60\x6d\x41\xae\x50\x3c\x84\xca\xba\x99\x29\x7e\xdd\x1b\x6e\xad\xac\xd5\x9a\x74\x99\x26\x08\x83\xba\xc0\x56\xd1\x3e\xf8\x9d\x71\x7e\x9a\x66\xaa\x0b\x0d\x43\x57\xb8\xc4\x76\x1a\x90\x0b\x64\xd4\x95\xd3\xe7\xe6\x30\x5b\x2e\x60\xad\x29\x7c\x65\xfe\xc3\x56\xe3\xd6\x9c\xae\xe6\x86\xbd\x8c\xdc\x5c\xa4\x6f\x83\xa4\x56\x09\xfa\x3d\x3e\x8b\xba\x1f\x48\xc8\x56\x8d\x32\x15\x62\x16\x74\x10\x13\x32\x26\xf2\xda\x76\xe1\x90\x17\x1e\xc9\x94\x8e\x58\x08\xe2\x72\x84\xd1\xe5\x97\x5e\x3d\x7c\xdd\xe5\x1f\x07\x5f\xad\x12\x6e\x1b\xb0\x36\xad\x98\x77\x78\xda\x79\x31\x33\xb5\x0c\xf0\x88\x28\x82\xc2\x4d\xd5\x7e\x4e\x69\xbb\x6e\x32\xdb\xee\x28\x27\x9a\xa0\x14\xe9\x85\xb1\x02\x4e\xea\x2d\xdb\x61\x1c\x5a\xff\xa1\x26\x8d\x33\xde\x98\xd1\xe4\x9d\xc5\x8b\xbf\xe3\xd9\x94\xb4\x9e\x78\x6f\xb1\xa6\x67\x2f\x72\xeb\x73\xdb\xff\x3c\x6b\x0b\xf6\x35\xe4\xe8\x1c\x40\x05\xbd\xba\x0a\x66\x53\x78\x5a\x07\x1f\x3d\xe2\x2d\x2b\x1e\x62\x4b\x0e\xce\xfb\x96\xad\x69\x8c\x8c\x6f\xc0\x61\x1d\xa2\xb6\x9d\xe7\xbb\xe7\x90\xeb\x06\xd5\xaa\x99\xbd\x7a\xda\xaa\x07\xd3\x59\x79\x75\x01\x93\xa3\x21\xc5\xcd\x26\x58\x80\xa6\xd0\xea\x23\xdd\x1b\x17\xd8\xc9\xa1\xc3\xc5\xbb\xcf\xf5\x2e\xb2\xc4\xc8\x62\xda\xf6\x1e\x5c\x0d\x5a\xb7\xf9\x18\xcc\x06\xfe\xbc\xd5\xa4\xdc\x94\x9d\x47\xe2\x56\xaa\x22\x67\xb6\x04\x54\xbc\xce\x03\xd2\xfe\xf2\x24\x6f\x01\x1f\x72\x7b\x89\x5a\x21\xcd\xdb\x47\x64\xf5\x26\x1d\x1b\x10\xec\x42\x56\x7d\x83\x36\xf8\xed\xc1\xd8\x92\xbb\x28\xeb\x8b\x18\x38\x80\xa2\x24\xd0\xe1\xb9\xf2\xa7\x1c\x90\x5e\xc0\x3d\x55\x5b\x15\xe5\x35\xdc\x77\xae\x9a\xf1\x2f\xe8\xd6\x28\xa5\xf5\x9f\xbc\x85\x5e\x42\x57\x90\xc9\x6a\xd6\x16\x7d\x35\x80\xdd\x75\xfe\xd6\x66\xae\x97\x04\xa5\xcd\x9e\x55\xa7\xbb\xb9\x36\x93\xf1\x7b\x6e\x29\xfd\xc1\x79\x78\x6c\x8c\x9a\xc9\x1c\x0b\xb8\xbe\x6c\x81\x20\xe3\xd9\xb3\xfc\x76\x43\xcd\xcd\xea\xbe\xdf\x95\x29\xa6\xcc\x2c\x6b\xe3\xa1\x08\xb1\xcc\xd4\x00\x56\x59\x89\x46\x75\xf3\x2f\x96\xce\x7d\x23\x4c\x95\x3b\x00\xc6\x70\x97\xe5\xb4\xbd\xea\x6e\xb3\x3a\x37\x12\x2f\x7a\xb4\x98\x28\xe6\xb5\x3e\xbd\x3d\x2d\x7a\x9e\x00\x7a\x9f\x76\xb8\xf4\xab\xfb\x90\x32\xad\x8e\x08\x58\x7b\xeb\xd2\x1a\x71\x95\x5f\x4e\xd0\xfb\x90\x35\xaf\x9d\x58\x34\x55\x4d\x92\xfa\x8d\xd1\x13\xbe\x1b\xf5\x7b\xe2\x80\x5a\xfd\x86\xda\x9d\x3f\x52\x34\xd9\xf4\xb1\x1b\xb0\xf9\xd7\x73\x55\xd7\x7e\xbd\xf8\xb1\x5e\x49\xee\x5a\xaf\x88\x01\x73\xec\x45\x38\x2b\x57\x34\x86\xb2\x46\x2e\xad\xd0\x2c\x6b\x33\xf0\x7a\x39\x6b\x2f\x3b\xd2\x60\x65\xb1\x73\x44\x5e\x5d\x04\xb7\xf1\x84\x32\x2e\xb9\x88\x4d\x57\xbd\x73\xba\x16\x6a\x38\xac\xc5\x73\xef\x5d\x77\x8d\xdf\x6d\x3e\x7b\x62\x61\xad\xf9\xb5\xf0\xf2\xac\xe8\xb4\xf9\x74\xe1\xeb\xb3\x22\x90\xa1\xab\x3b\x9c\xb5\x9a\x31\xa2\xc9\xcf\x51\x8e\xd5\xe5\xde\xf9\x84\xd3\x76\xa3\xf7\xbe\x6a\xef\x4f\x18\x98\x7b\x5c\xb1\xf7\x0b\x4e\xb4\x4f\xa4\xe6\xaf\xd6\xbe\xbe\x48\xd9\xdb\xc0\x02\x9c\x09\x80\xb0\x9e\x01\xda\x6c\x53\xd3\x68\xc5\x8c\xfe\xcd\xf6\xb3\xd9\x74\xcf\xac\xc9\xae\x8f\x2c\x12\x05\xd6\xef\x37\x49\x18\xce\xde\x6b\x38\xbb\xf7\x64\x47\xed\xf7\xc8\x6b\x6c\xcd\xbd\x8e\x27\x45\x3d\xcd\x6a\xb3\xf2\xc5\x48\xd4\x05\xa3\x16\x27\xad\x45\x81\xa4\x4b\x08\x9e\x2f\xd7\x48\xfc\x9b\xf5\x11\xbd\xc7\xbf\x5c\xbd\x6d\xeb\x29\x58\x5f\x3f\xe1\x70\x7c\x8d\xdd\xaf\xe6\x12\xd9\x49\x8b\xe3\x8e\x84\xd4\xc3\xa8\x3c\xba\xd5\x64\x94\x01\xb7\xb9\xca\xf0\x7d\x80\x3a\x1f\x04\x48\x16\x1e\x14\xf9\x72\x74\x5f\xa1\x3b\x7e\xf1\xf7\x93\xcb\xcb\x8b\xb8\xd8\x9d\xf2\xe1\x30\xc0\xfa\xe8\xa3\x00\x0d\x06\xdf\x88\x9d\x36\xaf\xd5\x52\x3d\x52\x90\x5b\xb1\x13\x73\x4c\x21\x52\x55\xf0\x6c\xf2\x4c\x6a\x21\xeb\x6f\x8a\x10\x3a\x50\x98\xe3\x95\x5e\x2a\xc3\xd9\x17\x7a\x84\x17\x72\x9a\x16\x0d\xff\x2e\xe5\x63\x40\x03\x29\xa6\x5b\x0e\x6a\x5f\xc3\x16\x45\x9f\x01\xce\x53\x77\x8f\x02\xe9\x97\xa8\x58\xea\xe2\x26\x5a\x19\x2f\xc5\xb5\xcb\x4c\x5c\xc3\xea\x2f\x3f\x33\xeb\x56\x46\xaa\x8e\x63\xfe\x08\x64\x67\x89\x6f\xdf\xe2\x19\xf3\x6c\x2f\x90\xf9\x17\x7b\x85\x56\xcc\xf7\x19\x66\x11\x79\x30\xef\x7f\x2f\xe6\xb4\x2c\x65\x78\x29\x20\xcf\xf6\xe2\x2a\x31\x24\x38\xa2\xd0\xeb\x2b\xe6\x85\x2e\x16\x9a\xb2\x46\xa6\x96\xc9\x03\xd9\x96\xfc\x87\xd1\x47\x7f\xa8\x17\xab\x5b\x22\x5c\x69\xc1\x38\xe7\x35\x37\x74\x9d\xd3\x03\xf9\x54\x2f\xd0\x63\x83\xd8\x24\xc3\xbe\x17\xcf\x8f\x8f\x7e\x01\x46\xec\xa9\x2c\xb4\xe4\x42\x1e\x21\x07\xf0\x96\x8c\xb7\xae\x73\xcb\x73\x34\xb9\xa9\xc1\x15\x64\x6d\x1a\x94\x3d\x5c\xac\x55\x50\xbf\x7e\xcc\x2f\x5e\xce\x7e\xb8\xd6\x80\x7e\x2e\x3d\xfd\x32\xae\x92\x88\x69\x7a\x9f\x4e\x67\x30\x43\x84\xc3\x74\xfe\x25\x71\x07\xa1\x5b\xdb\xcb\x26\xf3\xb0\x21\x08\xd5\xf2\x00\x8b\xc5\x1a\x58\x37\x79\xf0\xc8\x7a\xd2\xd3\xfe\x4f\x80\x46\x6b\x18\xbc\xb5\xe9\xfd\x0c\x28\xab\xdb\x29\xe8\x80\xc0\xef\xc5\xec\xd9\x2a\xa4\x2a\xfb\xe9\x6a\x22\x1c\x94\x21\x65\x94\x8f\x52\xda\x23\xa8\xc6\x87\xe9\x74\x41\x40\x8d\x8d\x99\x88\x98\x77\x6b\x2d\x8f\x7c\xdc\x1f\x7d\xcc\xe8\xa5\xb8\xb5\x78\xe8\x14\x37\xb8\x2c\x81\x3d\x5c\xb8\xad\x59\xf5\xb8\x96\x9c\x89\x37\x9c\xc9\x85\x58\xd2\x4f\x25\xea\x66\x49\xf0\x3e\x71\xcd\xa9\xf9\xf7\x16\xe4\x25\xaf\x32\x30\xa2\x1e\xa9\x7d\x4b\xc2\x17\x54\x20\xca\xa6\x3c\xeb\x2c\x42\x8f\xbe\xe0\x88\xb3\x95\x07\xbb\x61\x7c\x44\xe0\xdd\x2c\x0c\x6c\x36\x9b\x71\x7e\x30\x56\x3e\x29\xdf\x07\x53\x2b\xe6\xf7\xfa\x8f\x13\xd1\x04\xdf\x31\xf2\x3a\xbf\x07\xa5\xe0\xcf\x8a\x43\x98\xd5\x8a\x9c\xaf\x80\xf6\x5d\xf6\x32\x8c\x32\x7b\x3e\xaa\xc2\x1a\xae\x02\x17\x5e\x45\x9a\x65\x73\xa8\x09\xcd\x51\x29\x01\x66\x88\x8f\xd5\x79\xdb\xfc\x7d\xf1\xd0\xf2\xb9\xaa\xd9\x3b\x7b\x1c\xd9\x9f\xd6\xe9\xe9\xe5\x77\x9c\x21\xa6\x73\x7d\xf3\x23\x14\xa4\x5b\x37\xad\x32\x0c\x76\x1a\x0a\xd9\xdd\xa6\xb3\xd4\xb6\xf0\xbe\x5d\x91\x76\x36\x17\xa6\xc2\xcd\xc5\x2f\xa3\x36\x25\xa4\xe1\x87\x74\x14\x8e\x74\xe6\xb4\xb3\x57\x9a\x3f\x87\x46\xdf\x8c\x0c\x6a\x19\x0d\x7d\x38\x25\x8f\x1e\x9c\xf3\xab\xb0\xab\x8e\xe1\xe0\x5d\x91\x5b\x73\xf6\xb7\x41\xf3\xad\x32\xa3\x73\x7a\x06\xc3\xaa\x99\xd4\x68\x85\x91\x22\x88\x70\xce\xee\x69\xa4\xd9\x5c\xba\x40\x8d\x01\x9f\xe1\x5d\x66\xd2\xb8\x60\xa4\x7f\x29\xa2\x87\xe7\xf4\x1b\x4f\xa5\x75\x42\x9f\xe4\x1c\xc6\xb0\xc5\x0c\x18\x14\x71\x88\xab\x46\x68\x66\xbe\xa8\x80\xaf\xbc\xbf\x6e\x7e\x22\x1f\x3c\x94\x22\xaa\x7d\x46\xc3\x4f\x97\xc8\x51\x9a\xec\x55\x02\xba\x53\xb4\x40\xff\xc4\x13\x24\x6a\x62\xdf\x1c\x8a\x24\x28\x36\x0b\x9f\x10\xad\xf1\x9d\x16\x0e\x10\x3c\xdf\xfb\xf8\xfe\x93\x2a\xdc\x73\x8f\x21\x3f\xfb\xae\x12\x91\x58\x7f\x8b\x20\x85\xf8\x88\x42\x15\xcb\x59\x84\x35\x34\xa0\x9f\x10\xaa\xc7\x26\x11\x8b\xf6\x4d\x03\xe6\x97\xa8\x8b\x74\x3c\x3b\x7b\x51\xe6\xc2\xac\xe3\xe7\xac\xc4\xac\x67\x79\x49\xff\xe4\x69\x4d\xec\xc0\x29\x9e\xf2\xd0\x3c\xf5\x65\x7b\x42\x42\x9f\x5d\xbd\x67\xd9\xbb\x58\x6c\x1d\x07\x76\x3f\x9f\x45\xa1\x6a\xa7\xbe\xf4\xcf\x62\x9f\xef\xe0\x34\xea\xf3\xf0\x2c\xb3\x10\x8d\x65\x58\xbd\x17\x67\x06\x83\x37\xcc\xa0\x47\xe0\xa9\xf0\x69\x4c\x23\x9f\x36\x6c\x99\x8c\x8d\x73\xcc\xe3\x04\xce\xa3\x17\xac\xcd\x44\xc9\xb0\x67\x7e\x31\x6c\xfa\x69\x75\x0b\x77\x4b\xb7\xed\x13\x21\x3a\x3e\x9d\x43\x50\xf6\xd9\x0f\xf8\x5e\x3d\x51\xa3\xeb\x8d\x87\x4d\xdc\xe3\x9e\x99\x48\xf2\x4c\x85\x33\x1e\x79\x5e\xa5\x4b\xf6\xb4\xfb\xd9\xf9\xd4\x57\xfa\xb9\xd6\x1f\x1f\xb5\xfe\xd1\xf8\xc9\xcf\x35\x3b\xcf\xfb\x07\xd0\xd3\xec\xc6\xea\x01\x8a\x3f\x75\x66\xf7\xf2\x07\xe9\xab\xb8\xb1\x3f\xf9\x95\xe3\x78\x7e\xb2\x32\x69\x7e\xb2\xd4\x44\x7e\xb2\xe7\xed\xaa\x52\xff\x49\xef\x80\x38\xbe\x94\x15\xfc\x83\x76\x61\xd5\x20\x1c\x0a\xde\xe6\x85\x21\x2e\x63\xc8\x84\x14\x74\x81\x51\x1f\x94\xd5\x55\x32\x1b\xea\xd0\x29\xbf\x34\xe1\x63\x6c\xa6\x7f\x6b\x60\x60\x9c\x2c\xbe\xd9\x0d\xc5\x28\xda\x23\x4a\x75\x4c\x37\x53\xd1\x15\xdb\xfa\xe0\x2d\x06\xaa\x51\xac\x43\xb4\xe5\xe5\x28\xf7\x82\xa7\x4f\x9f\xf9\x3f\xc5\x1b\xe2\x08\x07\x7f\xd8\x0d\xc6\xe0\x25\x04\xdc\xad\x5e\x68\xf0\x7e\x33\x11\x41\xa1\xa3\xf7\xec\xf3\xb4\xe6\x80\x52\xc2\xb1\xd1\xf8\x8b\xd1\x23\x15\xcd\x70\xf5\x51\xc8\xc0\x14\xae\x50\x45\xe1\x4a\xab\xea\x29\x00\x20\x0b\xb7\xfb\x13\x5e\xd4\x02\xc9\xb9\x56\xf7\x00\xdc\xef\x13\x6f\x68\x41\x2b\xe0\xeb\x03\x12\xc9\x25\x1e\x3b\xd9\x8c\x88\x0d\xbd\x43\x88\x01\x8d\x2c\x7d\x43\x3c\x3e\xbc\x4d\xa6\x13\x1a\xae\xfb\x87\x81\xed\xb0\x28\xe0\x2b\xce\xcd\x81\x9b\xc2\xda\x7e\x6a\xa7\xe0\x4d\xa1\x2a\xc6\xe6\x10\x75\xbe\x8f\xb3\x47\x23\x09\xfa\x02\xdd\xbd\xd0\x7f\x47\x2a\x50\x6e\x83\xc5\xc8\xad\x06\x21\xa0\xe4\xb5\xdd\x02\xe4\xf7\x5b\x6f\x39\xf6\xa7\x0f\xa3\xfb\x6c\x43\xd6\xcd\x19\x95\x9a\xee\x9f\x5b\x4e\x7b\x03\x26\x95\xb5\xdb\x73\x03\x4e\x02\x55\x89\x5e\xa9\xb6\xba\x6c\xd7\x10\xb7\x8c\x31\xb4\xa5\x06\x9b\xca\x1d\x7a\x4b\x04\x2e\x03\x55\x19\x29\x1f\x66\x7b\x1a\xf2\xda\x4a\xbd\xd6\x28\xe8\x72\xe3\x6d\x2f\xe1\xe7\x2b\x43\xa9\x88\x34\x83\x86\x33\x6f\x52\x2f\xf2\x97\xb5\x4b\x3c\xa9\x94\xf4\xd1\x1e\x23\x53\xfe\x41\xb2\x26\x1a\x7e\x9e\xde\x00\x97\x3a\x09\xf0\xed\x8e\x5c\x75\xf1\x1d\x5b\xd9\x4f\x73\xdd\xd9\xbd\x99\x28\xdb\x3a\x5d\xfa\x2e\x4d\x17\xf9\x9b\x48\x4e\xe7\x0f\x8b\xb7\x97\xa7\x6b\x56\x83\x67\xba\xba\x3e\x89\x66\xd9\x71\x70\x79\x3a\x4f\xd4\x24\x08\x4a\x48\x9c\x76\x4c\x03\x36\x8b\x55\xa6\x3b\x85\x47\x97\x35\x89\x92\xab\xc2\xad\x5e\x3a\x5f\x4c\xb1\x30\x2b\xc2\xc9\xc0\xb0\x8c\x8c\x41\x28\x5d\xa1\x51\x7e\x5e\x5a\x0a\xaf\xaf\xac\x41\xd3\xa4\x48\x74\xa4\x76\x86\xe3\x64\x82\x08\x07\xa7\xac\xb2\x1a\xc3\x92\x4b\x8a\x60\xc9\x43\x5e\xf2\x6b\xcf\xca\xfb\xb7\x52\xb7\x0b\x9a\x89\xc8\x86\xef\x30\x83\x7d\x09\x4b\x5b\x7c\x02\xfa\xcb\xbd\xb8\x93\x63\xaa\x23\x22\xfc\xb9\x5c\x48\x2c\xda\x6e\xaa\xb6\xd7\x35\xc2\x27\x4c\x1e\x7d\x62\xfa\xde\x54\xf8\x9d\x9f\xca\x22\xbc\x09\x5c\xaf\xbd\x44\x46\xa6\xf2\xd3\x1a\x9d\x93\xbd\x83\x8c\x84\x11\x47\x13\xd2\x03\x6e\x74\xf9\x7e\x92\xa7\xcc\xe4\x04\xeb\xa1\x5e\xdf\x17\xb9\x95\xf6\x81\x4e\x9a\xa7\x87\x7a\xca\xf0\x47\xf3\x13\x37\x65\x51\x1c\x79\xc6\xd0\x76\xe2\x25\xcf\x81\xde\x9e\x32\xd5\x3b\xdd\x6c\xff\xdd\x25\xb7\x86\x31\x36\xdd\x92\xb0\xdd\xe4\xdd\xcc\xe9\xf7\x4d\x00\xc8\xe4\xa2\x8e\x71\xb7\x90\x30\x9d\x05\xe4\xb4\x2b\xe8\xb9\x9e\x2c\x0c\x9b\x38\x3c\xce\xd1\x94\x6e\xcf\x94\xbf\xfd\x94\xd3\x9f\x7d\xf3\xf8\xb4\xa5\x3f\x55\x87\x53\x7a\x2b\x9b\x17\x31\x2c\x7e\x77\x24\x22\x30\x41\x5c\x43\xa7\x02\x87\xa8\x40\xad\x49\x11\x72\xa0\x70\x96\x20\x69\x9a\x39\x24\xcd\x8d\x38\x57\x33\x83\x0e\x38\x79\x92\xa2\xac\x5e\xa2\x97\x13\x58\x18\x8d\x9d\x0a\x30\x27\xe9\xe1\x30\x75\x8d\x81\x4c\xd4\x29\x03\x9c\xc0\xe7\xc8\x1a\xd4\x13\xa7\x9d\x2b\xf0\xfa\x3b\x97\xca\xbe\xe9\x67\x08\x00\x9f\xb2\x3c\x76\x32\x0e\x92\x4d\x91\x89\x49\x21\x53\x62\x62\xce\xf4\xfd\xf6\xf2\xf8\xf6\x96\xcf\x78\x51\x69\x6e\x54\xb0\xfb\x78\x89\xfe\x32\x5e\x37\xc9\xd1\x53\x0a\xf8\x6b\x51\x94\x87\x5b\x7e\xae\xe3\x7e\x65\xe2\x34\xaf\xb8\xb9\xe3\xee\x7f\x5f\x24\x77\xfa\x03\xfc\x01\x69\x23\xba\x93\xab\x22\xf1\x85\x8e\xe9\xb1\x45\x55\x8e\x3b\xc8\xd6\xea\x39\x8e\x08\x27\xdd\xf9\xe9\xb0\xcf\x93\xb0\x91\x4e\xee\x3c\x69\x35\xe0\xe2\x18\x8d\x02\xf7\x14\x6a\xb9\x95\xe2\x9d\x76\xad\x67\x06\x88\x8e\xb5\x7a\x27\x83\x44\xce\x43\x56\xe2\x74\x88\xce\x15\xec\x99\x8b\xcd\x43\x70\x0b\xc7\xea\x4f\xd8\xc1\x05\x86\xf4\xa2\x43\x0d\xe6\xe2\xc7\x47\xaf\x8a\x4d\xb8\x8d\xf9\xdd\xab\x2e\x18\x11\x25\xc3\x79\x8c\xce\x1a\x89\x1d\x03\xae\x13\x83\x1c\x11\xc3\x38\x7a\x6f\x87\x27\x31\xe7\x35\x86\xe0\xc6\x39\x5d\x7d\x25\x89\xb4\xec\xb3\x07\x11\xd1\x46\x52\xa4\xaf\xc8\x78\xb3\xb1\xd8\x33\xf2\xa6\xc1\x63\xf0\x50\x4b\xc9\x39\x8e\x13\x93\x18\xc6\x7c\x34\x8f\xda\x98\x3f\x72\xe4\xad\xd0\xb2\xd7\x79\xf6\x20\xd0\x39\xe7\x33\x3f\xc5\x32\x1f\x33\xbe\xd5\xb4\xf2\x53\xb3\xd2\x1e\x6e\x49\xd8\x9c\x99\x42\xa3\x70\x04\x72\x70\xa0\x31\xdf\x2d\x84\x11\x63\xd9\x27\xf7\x6b\x6f\x86\x1f\x58\xe2\x33\x49\x9e\xc1\x08\xaf\x6a\xff\xc7\x48\xd4\xf1\x7b\xa2\xda\x19\xc8\x9f\xe5\xeb\x06\x7f\xfa\xb6\x1e\x37\x1d\xd9\xee\x49\xe4\x50\x3d\x40\x13\xe0\x3a\xfd\xf3\x95\xc2\x62\xbd\x65\xd6\x44\xd7\xd0\x03\xd2\x5f\x82\x62\xee\xf9\x62\x8f\xed\xb1\xb7\x30\x13\x32\x42\x09\xdf\x44\x16\xa8\xc6\xc2\x1c\x18\x2a\x1a\x26\x94\xc4\x98\x37\x6c\xed\xa4\xbf\x12\x73\xdd\x77\xdc\x27\x6d\x30\x15\xa1\x3c\xff\xc5\x30\xea\xa3\x6a\xbc\xfe\x81\x97\x23\xfa\xd0\xd6\xc4\x12\xf3\x15\x8d\xad\x4b\x89\x4e\x66\x3f\x32\xc3\xc3\x31\x30\xf8\x62\x4c\x64\x00\x45\x63\x45\x26\x40\x01\x27\xaa\x57\x11\x44\x51\xb5\x0f\x3c\x28\x24\x96\xa4\xa3\xea\x81\x8f\xbd\x80\x99\xad\xdf\x0f\x1c\xe8\x8e\x30\xc2\xb0\x23\xf6\xf0\xe1\x20\x1c\x6d\x77\xce\xec\xdd\x3c\x66\x8f\x16\x93\x89\x5c\x97\x93\xe6\xf9\x62\x06\x26\x4c\xe4\xc7\xf4\x51\x88\xd1\x8d\x07\xde\xc8\x21\xb5\x1f\x0a\x8f\xa8\x45\x8b\x3e\x42\x0c\xf8\x21\xe8\xdf\xa3\x90\xbc\xff\xb0\x27\xb0\x91\x39\x1e\x68\x2e\xeb\x67\x84\x6b\x14\x59\xf3\x2c\x2b\x8d\xda\xc8\xfc\x24\x2e\x74\x46\x45\x43\xd3\x71\x78\xbc\x38\xb0\x23\x28\xe9\x51\x1e\x5c\x19\x99\xab\xd2\xe4\x7c\x40\x14\x90\xbb\x49\x91\xdb\xf6\xc8\x0c\x12\x7b\x64\xaf\x43\x11\x6b\x53\x7c\x50\xfa\x91\x97\x08\x77\x7f\x84\x8b\xfd\x61\x5f\xfc\x9d\x8b\x79\xc7\x00\xba\x17\x8d\x2c\x2a\x86\x0c\x11\xc3\x31\xd3\xfa\x26\xd7\xf4\xa4\x29\xe8\xab\x5e\xae\x47\x8a\x18\xfa\x47\xfa\xa1\xb2\x22\x84\xe0\xdf\x8d\x59\x5a\x76\x57\x12\xec\xa3\x74\xeb\x81\x3d\x92\x26\xd6\x15\xf0\x6e\x01\xf4\xcf\x4e\x4d\xd5\x26\x71\x48\x29\x7e\xcb\xef\xcc\x51\xb3\x2f\xe7\x8f\x32\xbc\x82\xfe\xbf\xfc\x8f\x90\x79\x0e\xc2\x90\x41\xca\x03\x47\x36\x18\x82\x91\xe3\x07\xc4\x5c\x47\x2c\x24\x8a\x43\x69\x04\xd3\xc4\x63\xca\xff\xea\xde\x53\xcf\x36\xff\xf3\xbe\xce\xd9\x90\xf2\xf9\x9f\x7d\x9f\x8f\x60\x76\xfe\xcb\x3d\x57\xb0\x36\x1f\x86\x2f\x77\xee\x03\x90\x2b\xc8\xe9\x37\x36\x2a\xdc\x18\x5d\x70\x4d\x31\x42\xac\x43\x43\xba\x60\x13\xdd\x05\xe5\x94\x43\x6a\x19\x5f\x41\xbf\x58\xf9\xa2\x1f\x57\x26\xb2\xc8\xbc\x4e\xca\x37\x0d\xf5\xeb\x86\xa1\xc6\xbc\x44\xc0\xb2\xa3\x07\xe7\x08\x0a\x0a\x32\x1f\xea\x71\xeb\xc6\x72\xfc\x4d\x27\x65\xfd\x52\x28\x32\xae\xf9\x52\xdf\x17\xa7\xcc\xb0\xbe\x0c\x7a\xbf\x3c\x2d\xd0\xa2\x59\x74\xb0\xeb\x28\x59\xc0\xbc\x3e\xe4\xbe\xb3\xf5\xfd\x00\x56\x0d\x3a\x85\x22\x25\x62\x33\x7a\xcf\xb2\x63\x8b\x2e\x53\x8c\x96\x97\x60\xe1\xaa\xe0\xe6\xbf\x25\xd5\x68\x05\x0c\xca\xb3\xfa\x01\xec\xf4\x86\x9a\x96\xa6\x20\x0e\xa0\xe9\xa1\xaa\xc4\x7a\x62\x2e\x58\x99\xfd\x46\x7f\x09\x5b\xba\x83\x8f\xee\xc7\xa1\xe0\xb6\x2f\xc7\x94\xd6\xa6\x2c\x2b\x66\x69\x4b\x18\xcd\xc3\x2f\x6b\x96\x6c\x9d\xc5\xe8\xce\xe5\x01\x83\x20\xaa\xc2\x73\x7f\x25\xc2\xf0\xd1\x75\x65\x5a\x52\xee\xcb\xee\xd3\x74\xe8\xe1\xb3\x36\xd8\x24\x3d\xf8\x0c\xfd\x1a\xc2\x02\x65\xf2\xe0\xad\x6d\xe6\x1b\x1c\xde\x87\xcb\x3f\x62\xbd\xc1\xa5\xc5\x79\x59\xe0\x28\x55\x0e\xb9\xa3\x4d\x89\x2a\xbc\x98\x0d\x3a\x58\xfd\xc6\x24\xd4\xe1\x52\x3a\xfa\x70\xad\x1c\x3b\x37\x43\x2d\x6f\x58\xfa\x6d\x19\x3c\x6a\x64\xb8\x40\x5a\xe2\xac\x61\xa6\xe8\x85\x9d\x29\x2e\xd1\xb0\x5f\x41\x13\x1f\x3c\x8c\xdb\x9f\x0b\x98\x3c\x06\xb4\x91\x6a\x58\xd5\xa3\x2b\xbe\x04\x4b\xe5\x3e\xc0\xb2\x94\xa4\xf6\xb0\xcb\x71\xea\xdc\xd4\x20\x40\x22\x77\xfc\x0c\x96\xe3\x9e\x62\x5a\xd6\x8d\x7a\x79\x66\x8f\x6a\xb9\x0e\x55\x43\x15\x78\xff\xb9\x7f\xfa\xf7\xe0\xae\x56\x93\x78\xa8\x82\x3a\xe2\xeb\x34\xd3\x78\x4a\x3b\x71\xb0\x8f\x04\xe4\x52\xf8\x7b\xf5\xc4\x36\x3f\x9e\x0a\xa0\x99\x2e\xbc\xd9\x88\xae\xe1\x79\x60\x40\x4b\x86\x7e\x25\xd9\x38\xec\x9e\xc9\x6c\x43\xa5\x90\xc9\x80\x84\x05\x29\x90\x0f\x3f\xee\x7e\x1e\x90\xcf\xa7\xa3\x2e\xbf\x94\xba\x02\xa1\x75\x10\x17\x68\x00\x4a\xfd\x4b\x64\xd6\x43\x40\xd2\xe3\xae\x15\x07\x68\x58\x8d\x91\xc3\x1a\x30\x56\xd9\x4b\xd2\xaa\x50\xed\x89\x99\x6e\x7f\x09\xb2\x8a\x6a\xfa\x8c\x42\x73\x8a\x70\x06\x02\xcb\xb5\xa0\x67\x50\xc7\x51\x1e\x7d\xd9\x22\x20\x0b\x90\x55\xa7\x94\x68\xeb\x7b\xc4\x29\x0e\xd0\x8a\xf1\xe9\x12\x48\xd5\x2b\x70\xaa\x57\xaf\xc6\xc4\x50\xc6\x7c\xb4\xed\x0a\xcc\x34\xdc\x31\x40\xc8\xcb\xf6\xf7\x49\x03\x5e\xad\xfc\x45\xba\x6a\x83\xd8\x3a\x68\x95\xe3\x3e\x5f\x4e\x56\xd5\xa7\x7c\x40\xf6\x7b\x51\x1c\xe5\x40\x4d\x5b\x5a\xf5\x9f\x76\x91\xcf\xb6\x2c\x2a\x6c\x3f\x44\x45\xfd\x72\xae\xc8\xab\x03\x0b\x7d\xdc\x17\x7c\x24\x69\x78\xd2\xb0\x2c\x5d\xb1\x6c\xaf\xb8\x56\xdf\xca\xcd\x28\x85\xad\x0d\xad\x11\x61\x20\x60\x2b\x57\x5b\x2e\x6d\x69\x71\x8e\x60\xb0\x49\x05\x83\x18\xb2\x34\x9d\x86\xf6\x34\x66\x05\xa9\xc3\xe8\x3e\x09\xac\x73\xb7\x73\xc8\x16\x63\x48\x52\xa1\x1f\x72\x84\xfc\x0d\xf6\xc8\x5c\x6c\x94\x0f\xf9\xd1\x20\xac\xbc\x36\x8f\x56\x59\x03\xdf\x1a\xd0\x59\x34\x41\x6e\x5a\xeb\xaa\xe1\x16\xd8\x7d\x00\x5d\xe1\x2a\xd3\xe9\xf5\xfb\x7b\x6b\xf6\x0d\xa8\x0c\x56\xeb\xb3\x9d\xbc\xb0\xab\x59\x05\x49\xda\x0e\xea\x05\x73\x21\xe8\x2b\xd0\x40\x9e\xa4\xe6\x2d\x1e\xbc\x41\xd3\x07\xc5\x06\x97\x75\xe4\xc3\x97\x9a\x0f\xc2\x4d\x1e\xc8\x37\x02\xbf\xdd\xc0\x50\x1c\x31\xc9\xdf\x31\xec\x6f\xd6\xb8\xa2\x25\x63\x76\xff\x97\x39\x38\xed\x46\xf5\xb4\xfa\x67\x11\x83\x15\x30\x53\x82\x04\xdf\x40\x63\xbb\x61\x57\x7e\x60\x0e\x25\x42\x3a\x89\x69\x33\x4b\x7e\xac\x5e\x02\x12\xa0\xb1\xde\xb0\x53\xe2\x58\x79\x9d\xc9\x63\xd5\x42\x70\x02\xa9\xdf\xd2\x93\x64\xdc\x5f\x4c\x6c\x80\xb8\x2f\xdf\x6d\x67\xb2\xd2\xb7\xd2\x37\x4d\x8d\x3e\x72\x76\xc1\x68\x55\x38\x6a\xdf\x84\x69\xcd\x92\x2b\xad\xf7\x88\xfb\x2e\xd8\x86\xee\x74\xe4\xe6\xf3\x11\xf0\x54\x8a\xe4\x12\x64\xb9\xc7\xbc\xb4\x68\x8d\x14\x0a\xbc\x50\x17\x67\x9d\x05\x7d\x9f\x17\x33\x88\x7a\xc4\x0d\x11\xd6\x07\xa9\x25\xe6\x9a\x82\xd2\x7c\x06\x20\x42\xe8\x55\xd2\x96\x5a\x79\x55\x1b\x1a\xa5\xa3\x91\xa2\x7a\xeb\x55\xaa\xc5\xd0\xd7\xe3\x86\x0d\x59\x81\xa3\x9d\x66\xf8\x01\x20\x79\x9a\x60\x4e\xf1\x3c\x03\xbd\x7a\xfc\xa7\xc4\x42\x84\x7c\xc1\xe4\x04\xba\x41\x4f\xed\x66\xef\x1a\x59\xb3\x2a\xd4\xb8\xf7\x71\xc5\xad\x9e\xcd\x56\x47\xce\x0a\x68\x79\xf2\x91\xb0\x0f\xc8\x70\x30\x5a\x0e\xfe\xda\x6b\x96\xaf\x80\x4c\xd7\x21\x5e\x7f\x21\x5e\x1b\x2b\x15\x78\xd7\xfb\xb8\x81\x6f\x15\x2c\xd6\xcd\x9b\x87\xe8\xcc\xe3\x54\x02\x25\xbb\xfe\xa8\x39\x6a\xe6\x98\x25\xaf\x64\x36\x24\x13\xe2\x52\xae\x6c\xcd\x8f\x51\x18\xf2\xc7\x15\x5a\x09\x18\xf7\x8f\xbc\x63\x5d\x45\xd2\xf6\xd8\x5c\xc5\x9f\x01\x67\x60\xe7\xc1\x26\xaa\x33\x5b\xad\x6d\x7b\x36\xf4\x2a\x22\xe3\x3e\x48\xa9\xee\xea\x15\x43\x77\x59\xea\xf0\xb1\xe4\x92\xf7\xde\x9b\xc3\xdc\x9b\xd5\x3e\x69\xbc\x02\x40\x3b\xb7\xb1\x39\x2f\x3e\x85\x3d\x2d\x22\x65\xd6\x11\xa4\x56\x31\x52\x1f\x51\xfb\xf5\xb5\x7b\xe5\xce\x0d\x96\xd7\xce\xef\x02\x86\x94\x39\x63\x76\x79\x22\x99\xcb\xc1\xd4\x2c\x33\x1b\x62\x75\x16\xc8\xdd\x8d\x95\x06\xc3\xaf\xdc\xc8\x34\x36\x4e\x06\xcd\xbf\xd7\xd6\x10\xa9\x19\x4b\x17\xfb\xc9\x84\xb0\xe6\xb4\x47\xcc\x15\x08\xb9\x51\x17\xcc\xc0\x91\x09\x1e\x0c\x09\x39\x35\x73\x60\x4f\xb1\xd5\xb4\x3e\x6f\x73\x6c\xe6\x22\xc7\x52\x5f\x7e\x7f\x75\x55\xad\xfa\x78\xd1\xcb\x6d\x66\xfc\xba\x0b\x80\xf9\x8e\x92\x3a\x2a\x6a\x6f\x82\xcf\x2a\xe8\x28\xa9\x5c\x41\x16\x9d\x40\xad\xe0\x12\x95\x0d\x31\x24\x6f\xf1\x27\x68\x6e\xba\x61\xaf\x65\x6d\x60\x0d\xe0\x58\xa3\x89\x0b\x7b\x26\x36\x79\x12\x3f\x55\x83\x88\x88\xa2\x3c\xb5\x1d\xf0\x59\xb9\x26\xe8\x6b\xd6\x25\xff\xc7\xc2\xae\x70\x32\x87\xae\xee\x1a\x38\xe8\xa1\x01\x74\x31\x39\xda\x6c\x57\x9a\x4b\x25\x76\x67\xdd\xc1\xc6\x37\xb5\x82\x3f\x55\x50\xed\x8a\xa7\xdb\xda\xfb\x60\x9c\xf1\xe1\xf6\x9e\xca\x20\xeb\x43\x7e\x92\xc5\x07\x45\x2d\x1d\x3e\xca\x6b\x91\xed\x77\xbf\xac\xd6\x99\xe4\xd9\xa0\x6f\x1b\x97\x38\xfd\x66\x7a\xfb\x1c\xd5\x5a\x82\x25\x7a\x21\xc1\x3d\x50\xa7\x57\xf0\x66\xed\x43\x3b\x44\xcd\xd8\x74\x8f\xcd\x9a\x82\xf6\x7a\x46\xee\x3f\x38\xae\x51\xeb\xf9\xf8\xc9\x96\x49\xbd\x4d\x07\x70\xb0\xfa\x61\x0f\xda\xea\x7e\x02\x32\x34\xcb\x76\x4c\xa7\x7e\xd8\x82\xff\x9b\xe8\x60\xb6\xe9\x7c\x74\x49\xb3\x72\x78\x30\x61\xe3\xf9\xe3\x5b\x91\x90\x59\xd3\x7e\x00\x03\x76\xe1\xce\x11\xfa\xaf\x00\x04\x7e\xad\xe7\xc6\xd2\x05\x2a\xb7\xe1\x4e\x43\xf7\xb0\xf7\xd8\xd6\xef\x30\x8b\x30\xc8\x69\x4d\xfc\x84\x82\xec\x06\x2d\x1a\x22\x7b\x01\x77\x13\x49\x76\x6e\x41\x49\xb0\x8b\xfb\xf0\x54\x7a\x68\x48\x1e\xa1\xc0\xda\x72\x0c\xfc\xf7\x09\x98\x67\xd1\x18\x81\x69\x25\xa9\xf0\x3a\x5b\x98\x7f\xe7\x8c\x74\x2d\x70\xbc\x25\x77\xd3\x5d\x72\xdf\x76\xd7\xbe\x69\x3a\xd6\x25\x17\xf9\x61\xba\xcb\x41\x3e\x5d\xcb\xf3\x37\xeb\x19\xa1\xff\x20\xb7\xf6\xf4\x2d\x75\xd7\xfc\xd4\xb7\xa0\xbb\xca\x3c\xc4\xfe\x03\xaf\x78\x59\x6f\x91\xd8\x46\x58\x5c\xac\x7f\x42\xb5\x94\x5b\x45\xf2\x25\xc1\x9f\xfb\x25\x61\x5c\x20\x5c\x0f\x51\x55\xd1\xc5\x10\x52\x1a\xd0\x56\x61\x29\x11\xfc\xfc\xa6\x21\x49\x57\xb3\x62\xf8\x4d\x94\xd6\xe3\x36\x65\x89\xaa\x9a\x45\xf9\xc0\xe8\x9a\xe6\x24\x74\x22\x57\xed\x52\xc8\x5b\x07\xa3\xf0\xc8\xab\x07\xd8\x75\xde\x0b\xa0\xb7\xb8\x6b\xda\xf2\x1d\xf5\x06\xdc\x3a\xf8\x7d\xb7\xaa\x7c\x54\xe4\x59\xd7\x12\x5b\xba\x5a\x41\xbd\xe4\xef\x35\xe6\x11\xa8\x89\x51\x2b\xf6\x30\xbb\x8a\x7e\xbb\x70\x94\x35\x02\xce\x3b\x84\xe4\x12\x1e\x8b\x6f\xc2\xbe\xa9\x59\xda\x55\x77\xb8\x76\xf6\xc1\xf3\x15\x66\x24\x78\x13\xe2\x89\x67\x89\xb7\x17\xb2\x40\x80\x2c\xe8\xa4\xbd\xd8\x88\x8f\x1d\x24\x4e\x05\xdf\x9c\x19\xaf\x6f\xed\x2a\x26\xa9\x77\xb3\x54\xa2\x88\x61\xd5\x42\xa0\xc9\x53\x38\xda\x6d\xf5\x1d\xdd\xa6\x77\x95\x66\x6c\xde\xed\xb0\xba\xe0\x23\x00\xde\xaa\xcd\x75\x4d\xbb\x15\x5c\xd6\x2e\xc0\x9a\x05\x21\xeb\xd6\xbb\x8a\x00\xb3\xae\x54\xd7\x5c\x18\x34\xe0\x0b\x86\x97\xd5\x89\xf4\xe7\x74\x56\x0f\x2b\x9f\xaf\xf3\x00\x23\x0e\x12\x75\x11\x88\xd8\x95\xf1\xfb\xe2\xa5\x2e\x5e\x19\x7d\xcb\xce\xa4\xaa\xc2\x21\xc2\x59\xf9\x08\x29\xcc\x2e\x1f\xfa\x95\x99\x09\x18\x77\x53\x56\x7f\xe7\x1c\x57\xad\x20\xf2\x2b\xe4\xaf\x35\xc3\xba\x75\x7e\x57\x00\x79\x9d\xf8\xeb\x7c\x92\xf3\x82\x1a\xb9\xab\x6f\x2e\x38\xdf\x6c\x35\x14\x42\xc7\xbd\xcb\x53\x11\x14\x37\x43\xad\x4e\x7b\x1f\xab\x70\xb2\x79\x0e\xb0\xac\x2d\xf8\x4b\x8b\x48\x05\xae\x03\x4c\x6b\x6c\x35\xb1\xd3\x09\xa3\xe1\x68\xad\x96\xe5\xbb\x83\xf1\x6a\xe7\x32\x7a\x81\xfb\x4e\x97\xdf\x59\x38\x30\x59\x26\x23\xb0\x43\xd7\x80\x97\x3a\xe9\xcd\x94\x02\x1b\x97\xda\xa3\x47\x63\x66\xf7\x69\xd2\x51\xd0\xb1\xcf\x0f\x0e\x01\xde\x5c\x1d\x1d\x08\x30\x40\x69\x4d\x2c\x0c\x8a\xd9\x72\x0a\xeb\x17\xd1\xab\x7a\xb7\xd3\x28\x6f\x47\x97\x24\x1b\xd8\x25\x41\x10\xf0\xbc\x53\xe1\xaa\x0b\x7c\x1c\x90\xaa\xdc\x45\xfa\x7b\x2a\x63\x2f\xbd\xad\x49\x00\xf0\x25\x6c\x0e\x9a\xa6\x17\xfe\xdc\x48\xcf\x1c\xd4\x55\x86\x7e\x00\xb8\x2a\xca\x22\xba\x12\x6a\x18\x98\x0d\xaf\x22\x49\xd8\xc9\x83\xad\x9c\xcf\x69\xd5\x82\xaf\x74\x61\x18\x2e\xde\x14\x7c\xeb\x7a\x1a\x3b\x75\xe5\x81\x29\xaf\xae\xb3\xad\x92\xd7\x21\xc3\xd7\xcd\x58\xfd\x22\x53\x75\x0f\xb0\x24\x6d\x9e\xca\x81\x04\x6c\x79\x0c\xad\xb1\xc4\x67\x05\xb1\x99\x1c\xce\x4f\x22\x7f\x25\x0c\xd5\x25\x87\x67\xca\xdb\x8c\x18\xcc\x38\x52\xab\xe1\x05\x01\xdd\x07\xc5\x48\x78\x9a\xc7\x1e\xd6\x50\x6a\x4f\x96\x9b\x73\x59\x73\x83\x9e\xee\x5d\x41\x1e\xab\x40\xa9\x7b\x62\xfc\xb6\x3b\x3f\x36\x0f\x30\x19\x54\x4c\xc1\xf0\xdc\xe0\x3f\x0e\x64\x26\x72\x53\xd4\x4b\x48\xeb\x1b\x3a\x4c\xdf\xbe\xc2\xfa\xaf\x84\xac\xbc\x75\xa0\xe4\x17\xf7\x64\xeb\x19\x81\x76\xb1\x06\x61\xbc\x10\x6e\x0b\x66\x6b\x59\xc8\x77\x1d\xe7\x7a\xc8\xd0\x10\xb7\x80\xad\x81\x0d\x05\xad\xf5\xb0\x16\x34\x53\xa7\xbd\x68\xad\x37\xae\x3c\x54\x0e\x49\xc0\x9a\xe9\xf3\xc7\x73\xc8\x43\x5e\xb9\xb5\x85\x6f\x6e\x5a\xe8\x4f\xb0\x66\xe8\x54\xba\xa2\xdf\x56\x5c\x2e\xe8\xa4\xf8\xd7\xc6\xca\x88\x8f\xf1\x43\xb6\xd6\xbf\x7a\x16\xd0\x40\x42\xa8\xa6\xdf\x00\x7c\xfb\x31\x9d\xb5\xd5\xf9\x97\x8f\x24\xdb\x69\x69\x3e\xd1\xc7\x95\x89\x81\xfe\x0d\x59\x33\x7f\x5c\x65\x9b\x00\x04\x65\xf7\xca\x4a\x89\x84\xdb\x19\x4a\xdd\xbe\xcb\x78\x5d\x40\x7d\x8d\xa9\x9e\xaf\x79\xae\xfd\x0d\x87\x9d\x4b\x43\xe2\xc2\x45\x2a\xaf\x25\xec\x51\x73\x41\x9f\x1a\x18\x7c\x65\x85\x5e\x9b\x4d\xe5\xa9\xc3\xb4\xb7\xca\x0d\xc4\xd5\xf9\x79\x15\xbe\x36\x76\x84\x5c\x16\xb1\x5d\x2d\xf6\x22\x8d\x02\x6f\xd8\xdb\xbb\x7b\x0c\x45\x1a\x91\x8b\xc0\x45\x01\xb1\x08\xdf\x5e\x7a\x60\x60\xa7\xf5\xf8\x12\xd2\xa7\x31\x1d\xea\x76\x43\x59\x7f\x22\xcc\x11\x6d\xa0\xfe\x03\xd6\xea\x59\xfa\x3c\x42\x17\xc5\xfa\x6a\x6c\x56\x92\x90\x69\xf3\x48\xfa\xfd\x4d\x3f\x06\xa0\xac\x50\xe5\x90\xbb\xdf\x8a\x0d\x52\x67\xdf\xa8\x4a\x84\xbd\x5d\xf8\x7d\x17\x45\xb6\xf3\x14\x90\xc4\x14\x2a\x0c\xc7\x7f\x70\x58\xdb\x1f\xca\xdf\xc2\xeb\xfe\x5d\x08\x12\xf6\xa7\xeb\x8f\x1d\x0a\x9b\x3c\x83\xf5\xf4\x67\xdd\x92\x4a\x4a\xd6\x5f\x23\x99\xfd\x41\x6a\xcd\xdb\xb6\x7f\xd9\x1a\x81\x7c\x2d\xfe\xbc\x7d\xfe\x76\xab\x9c\x18\xc1\xf5\xad\xa7\x95\x4f\xe6\x1f\x48\xc2\xbe\x19\x5c\x5d\x9b\xbe\x67\xba\x8b\xdf\x8d\x02\xf2\xce\x87\x4b\xdc\xbe\x31\x88\xe1\xd3\xd1\x17\xc8\x76\x80\x53\x18\x98\xa6\x77\xf5\xc9\x6b\xe3\x84\x44\xd7\xa4\x28\x9b\x77\x9a\x86\xc4\xe5\x18\x95\xf0\xfe\x1e\xdd\x33\xf0\xcf\xaa\x19\xa6\xbd\xbc\x5e\xb5\x7a\xe5\xfa\x82\xb7\xe5\x95\x18\x3f\xfa\xda\x9b\xc2\x0f\xa8\xad\x83\x9f\xc0\xab\xfa\xc0\x8e\x80\x9d\x04\xed\xbf\xe8\xf4\x64\xd5\x47\xb2\x2b\x0d\xcf\xee\xc1\xf4\xe4\x40\x23\xcc\x68\xe7\xda\x2e\x49\xd0\xb4\x16\x8e\x83\x5e\xb5\x36\x3d\xb1\x2f\x24\x32\x72\xb1\xd9\x1d\x34\x5a\xc7\x3e\x61\xa7\xb6\x3e\x07\x5b\xb5\x42\xd5\x8f\x68\xd0\x3b\x9c\xc7\x93\xbf\x78\x27\x5e\xe5\x70\x94\x67\x11\xa5\x35\x08\xaa\x08\x54\xe4\x9c\x75\x1c\x62\x2d\x60\x95\x88\x66\x81\x5d\x5f\x80\xbc\x79\x01\x01\xde\x34\xce\x58\x56\x61\x19\x2f\x77\xb2\x3d\x65\x41\xbc\x56\x47\x63\xed\x6b\x2a\x4a\x1d\x2a\x59\x1f\x8f\xad\x2e\x2b\xb8\xfc\x08\xb0\xaf\x17\x77\x26\x60\x2f\x7a\xc8\xe2\xe2\x4e\xef\xb7\x6f\x66\x6a\xb9\xb8\x4e\x7a\xf5\x69\xf9\x6b\xe8\x56\xe6\x93\x90\xf7\x7a\x86\xf5\xe0\xf7\xe9\x05\xc0\xb5\x6e\xe1\x54\xe2\x67\x4a\xee\x3a\x09\xf6\xda\x48\xda\x85\xdd\x69\x6e\x56\xf7\xf6\x85\x10\xa0\x30\xd3\xdf\x1f\x81\xa8\xd6\x17\xd6\xbf\x24\x40\x2d\xa3\x15\x1c\x17\xdb\x68\xb1\xdf\xcd\xdc\xbf\x04\x8b\xf5\xed\xe4\x7f\xd1\xb9\x79\x65\xf5\x33\x61\x7c\x11\x23\x7b\x91\x67\x9b\x43\xae\x17\x4c\x59\x89\x39\x60\x61\x92\x70\x73\x1b\x34\x7a\x49\xab\xfc\x95\xbb\x8d\x09\x3c\x56\x4f\xb7\x94\xbd\x17\x44\x09\x7d\xea\x6a\xfb\x82\xd2\xbd\xf8\x69\xa6\xe5\x55\xc4\x2b\x35\x97\xfd\x4b\x34\x64\x4c\xb3\xfc\xd0\x66\x77\x12\x84\x79\xa5\x59\x9e\x4a\xa0\xc3\xba\x24\x99\xe8\x57\x2a\xe2\x9e\x83\x16\x8b\x7f\x5f\x00\xbd\xca\xd1\xf9\xeb\xba\x25\x44\xc2\xee\x0a\xd1\xfd\x65\xa7\xce\x26\xf0\x31\xb8\x35\xc3\x8d\xbe\x93\xf6\xfa\xeb\x6d\xe3\xdf\x12\x70\x05\x07\xc4\x5e\x6e\x6c\x2c\xe3\xb3\x57\xc9\x83\x1d\x72\x1d\xd3\xa2\xe5\x82\xeb\xf0\x0b\x6f\xc6\xb7\xac\xe9\x7d\x1c\xb5\x04\xf2\x35\xed\xea\x1e\xff\xaa\x1b\x6a\x3d\xf4\xeb\xb7\x68\xd6\x2e\x70\xeb\x3e\x5e\x92\xb2\xf2\xd1\xdb\x86\x71\x85\xdd\x80\xb0\xf9\xef\x42\xb8\x3d\x0b\x9e\x20\xf4\x9b\x67\x64\x9a\x65\xce\x9b\x39\xa0\x05\xa3\x2f\xf6\x85\x61\xc5\x1e\x88\x58\x7f\xf0\x7e\xad\xa9\x9b\x23\xe4\x06\x12\x73\x81\xb5\xb5\x06\x6b\x0f\x5c\x3b\x4f\x2c\x6d\x3a\x2f\xbf\xb9\x93\xf3\x8b\x7f\xed\x63\xca\xe6\x30\xdc\x1a\x83\x3e\x15\xb0\x43\xa9\x0d\xa0\x76\x85\x31\xfd\xda\x37\xe6\x5a\xb8\x40\xdf\xab\x3a\xb9\xfe\xba\xfc\x2c\x8a\xa4\xbf\x8e\xcb\xbf\x11\xd6\x11\xdb\x57\x7f\x27\x2f\x81\x03\x70\xf6\xc4\x79\x5c\xab\xd7\xce\xbc\x18\x60\xc8\x7a\xeb\x58\x87\x7c\xad\xbf\x60\x68\x37\x00\xea\x19\xc3\x96\x66\x3a\x89\x53\xd9\x71\x48\x67\x8b\x7a\xd5\xe5\xc9\xaf\xa0\xb8\x1e\xfd\x1e\x34\x81\x6b\xdd\xf3\xc7\x06\x80\x0c\xdc\x9f\xe9\xfe\x6d\xbc\xa5\x92\xae\xd5\xb9\x11\x6d\xbf\x88\x9e\x76\x02\xed\xc5\xbd\x55\x40\x06\xf5\xdb\xea\xc1\x6c\x2b\x0b\x0b\x55\x7b\xae\x75\x2e\x4d\x27\x1e\x48\xe9\x60\xd2\x06\x6b\xd7\xfa\x27\x76\xf0\xf2\xcb\x39\x9e\x16\x7d\x91\x76\x30\x4e\x05\xde\xd3\xcc\x42\xef\x1e\xc5\x6b\x7d\x04\x5e\xc9\xcc\xe4\x79\xca\x6d\x85\xc1\x73\xe7\x3a\xfd\x6a\xf7\x13\x2c\x9c\xb8\xa6\x2a\xe6\x28\x34\xe2\x49\x94\x9a\xad\x78\x00\x1d\x2d\x5c\xc5\x9b\xa3\x19\x52\x1c\x28\x9a\x18\x42\x02\xc3\x5b\x7c\x8a\x6a\xcb\x77\x0f\x06\x9a\x82\x67\x5b\x00\x6d\xc0\xa0\xe2\xb2\x8f\x02\x57\xc1\x6e\x6d\x93\xbe\xc4\xc5\x81\xb6\x12\xb8\xd2\x51\x24\xe4\x76\xfd\x94\xd7\xb1\xcf\xc4\x3d\xc6\x78\xad\xd1\x9e\x64\xc1\x03\x92\xbe\x9c\x8b\xab\xb7\xe4\x52\x02\xdc\x35\xbd\xdc\x7d\x74\xa9\x38\x92\xfb\x6d\x53\x9f\x3c\xe8\x7f\x01\xf5\xcb\x2f\x0f\x01\x9b\x8e\xb2\xcc\x1f\xe6\x40\x93\x9d\x2d\x33\xd6\x88\xf7\x74\x5b\xd3\x31\xd6\x68\x43\x97\xb4\x71\xcd\x4f\x50\x3e\xb8\x19\xeb\x8c\xce\xac\x55\xcf\x96\x8c\x09\x2b\x29\x98\x58\xe1\xbf\xa7\xdd\x74\x85\x99\x9f\xd7\x82\x01\x21\xc1\x64\x2f\xe5\xab\x9c\x8c\x13\x83\xb5\x33\x69\x18\xe3\x95\x4f\xcd\xb9\x3a\xe4\xe9\xf1\xe4\x30\x24\x34\xd3\x80\xbb\x2b\x11\xd0\x0b\x5f\x8a\x92\xfa\xad\x20\xdd\x0e\x00\x78\x4b\xa2\x90\x0b\x6c\x4e\x12\x24\x6a\x1b\x39\xd5\xe3\xc6\x1a\xf6\xd7\xb5\x2f\xb8\x77\xf1\x78\xb9\x45\xeb\xec\x02\x3b\x71\xc6\x6f\xeb\x71\x33\x08\xbd\x18\x22\x1d\x2c\x28\xc4\xdd\x0b\x0f\xba\xd7\x68\x5b\xa3\xa1\xfd\x00\xb8\x88\xae\xac\x17\xf3\x1a\x1b\xff\x1f\xa7\xcb\xa6\x2d\x96\xad\x91\x83\xcb\x1a\x88\x5f\xc5\x11\x9a\xf5\x48\xf3\x48\x28\x2d\x72\xdb\xb3\xd8\xc2\x9e\x05\xed\x7b\xf6\xbc\x3a\xef\xce\x3a\xf8\xb7\x70\xe6\x19\xc1\x36\x34\x79\x20\x15\x38\x32\xb6\x6b\x4f\x66\xae\xcb\x2a\x73\x98\x81\x13\x86\x87\xcd\xab\xea\x93\x60\xfd\x53\x8d\xb2\x13\xef\x08\xa8\xbf\x6e\xc3\x37\x42\x77\x87\xf7\xd5\x79\xc1\x2a\xe3\xed\xce\x3a\xb2\x48\x37\xcb\x59\x1f\xd7\xce\x61\x12\x47\x04\xc7\x21\x85\x57\xf4\xac\xdd\x7e\x11\x2b\x0c\xd7\x85\xe6\x25\x34\xc5\xaa\x3f\x10\x95\x19\xf7\x8a\x48\x72\x15\x52\x2e\x24\xb9\x0b\x50\x53\xdf\x9a\x9e\x51\xd1\x9e\x1e\x1a\xed\x8d\x9e\xb3\xc8\x6d\x76\x16\x88\xfd\xf0\x58\x27\x6a\xe4\x9f\x71\xe7\xa6\x6b\x1c\xdd\x8f\x4e\xca\xb0\x0e\x12\x03\x0d\x1d\x9f\x68\x33\x73\x18\xaa\x65\x00\x19\x7e\xf0\x5a\x4f\xd5\x69\x67\x9d\x5e\x1f\x08\x01\x4c\x8a\x3c\x47\x8b\x59\xd4\x49\x12\x88\x69\xd9\x91\xf0\x57\xfb\x02\xcf\x89\x38\x5f\x04\xa8\x70\x03\x5e\xbf\x55\x0d\x94\x9d\x1e\xe6\x74\x49\xdd\xfc\x74\x46\x42\x68\x16\x11\x35\x4c\x23\x1f\xfc\x3a\x03\xb5\x86\xcb\x7c\x0a\x22\xbc\x5d\x7e\xe3\xf3\x7a\xc5\xd6\xed\x2b\xd4\x0b\x5e\x1c\x63\x35\xb0\xf2\xae\x81\x4d\x14\xb4\xa9\x96\xfc\x04\x50\x0b\xf5\x78\xa3\xf4\x20\x44\x13\xa6\x4f\xda\x1d\x8d\x81\xf6\x33\xfd\x83\x56\xb8\xf7\x04\x60\x73\x3b\x9e\x84\x27\xc0\xaf\x55\xc1\xe2\xbe\x9d\x10\x11\xd2\x9e\x12\x02\x98\xce\x30\x13\xc4\xc5\x68\x0f\x9c\x7c\x73\x8a\xc1\x7a\x01\xf3\xe3\xb6\x5a\x25\xf0\xd6\x34\xc0\xc2\x84\x55\xda\xbb\xb0\x5c\x5c\x0d\x09\x6c\xda\x4f\x47\x1d\x1c\x7f\x6a\x4e\x0a\x51\x41\xcb\x36\xe0\xd0\xc9\x23\xf8\x79\xa5\x0e\x8c\xb0\x33\x13\xf8\x78\xab\x61\x71\xbc\x81\xcd\x18\x1a\x94\x18\xb0\x9c\x43\xe6\xca\x70\xef\xe3\xc5\xfc\x0c\x9b\x02\x2b\x00\xcb\xda\x4b\x3f\xea\x25\xc0\x1e\x13\x67\x5f\xbf\xbe\x9c\x80\x9d\xd7\xfe\x0b\xad\x19\xc5\x8a\x5a\x71\x61\x23\x0e\x2c\x61\x0f\x0f\xd5\xec\xfc\x60\xba\x06\xd0\xc2\xb1\x04\x21\xc3\x6d\x55\x72\x86\xe3\x0d\x17\x5c\xf8\x60\x9b\xca\x4b\x87\xa4\x2a\xc9\x19\x26\x66\xf2\x72\xfa\xca\xd6\x4c\x3b\xf6\x20\x0e\xe3\xe1\xa1\xd1\x45\x23\xe5\x70\x71\xd6\x7e\x2e\xde\xc2\xb5\x07\x5a\x3c\x68\x34\xea\x83\x1d\x3c\x06\xf8\xf4\x7a\x3c\x4a\x5f\x84\x33\x3a\x40\x07\xe0\xce\x03\x4d\x79\xb5\xa0\x0b\x07\x0e\x73\x6a\x5f\x62\xd5\xaa\xc7\xd5\xe1\xe9\x88\xb3\xe9\xa8\x1c\x1a\x44\x5e\x2b\x17\x64\x85\xdd\x3f\x07\x49\x14\xed\x24\xc4\x76\x88\x3f\x3c\x5d\xc2\x40\x9f\x04\xc2\xe2\x03\x14\x73\x90\x0d\x33\xc8\x1a\x93\xda\xed\x88\xed\x0a\x5e\x2a\x3e\x2f\x23\x32\x24\x74\x48\x56\xb6\x7e\x8b\x9c\x08\x18\xf9\x7e\xb7\x1f\x92\x52\x24\x82\x44\xfc\xdf\x42\xfc\x66\x5f\x99\xf3\x06\xbb\x9e\x20\x86\xc6\xc6\xaa\x5d\x03\x6f\xab\x59\x95\x80\x54\x3a\x1e\x40\x11\x9c\xdb\xab\xaa\xb0\x96\x4f\x62\xf1\x23\x5e\x5c\xd0\x88\x63\xc3\xf6\x56\x05\x5a\x14\x15\x46\xb5\x36\x45\xfb\x89\x47\x92\xb7\xa5\x0a\xba\x69\xf6\x94\x82\x59\x9c\x85\x5f\x25\xa0\x58\x17\xea\x86\x09\x9f\xde\x91\xe2\x8b\x70\x46\x16\x2e\xe2\x34\xdb\xf6\xd3\xa2\x4e\x15\x86\x34\xf6\x50\x33\x0f\xed\xe8\x46\x90\x86\xd6\x0f\x91\x53\x30\x6f\xc0\xd1\xe1\xfc\xb5\x41\x56\xeb\xea\x7b\x01\x53\x30\xc0\xa2\xc1\xe3\x05\x5d\x15\xc7\x18\xf3\xdc\xac\xbb\xeb\xb5\x83\x1b\x99\x19\x99\x66\x3f\xf3\xe1\x62\x31\xad\xa4\x57\x00\xa1\x63\xd1\xce\x76\x7a\x31\x1f\x4f\x67\x4e\x71\x7b\x92\xd1\x3f\x36\x4a\x56\x1e\x1e\x79\xcb\x75\x19\x72\x8c\xa9\x52\x6d\xcc\x84\x9f\xf6\x52\x5a\x13\xb0\xc6\x82\xb0\x83\x6c\xcc\x37\x77\x4b\x7b\xe3\x28\x27\xb1\x4c\x37\xe7\x60\xf9\x61\xd7\x77\x97\x05\x3e\x46\x8b\xf6\xfc\x40\x1e\x0b\x90\xe1\xb6\x3a\xcd\x6e\xab\x2f\x7d\x54\xc9\xfc\x1f\x08\x15\x50\x3a\xee\x51\x39\xe6\x71\x38\x2a\x8c\x86\xbd\x04\x1c\x35\x23\x34\x59\x3c\x56\x7d\xea\xed\xd1\x19\xef\x06\x28\x70\xc8\xdf\x02\x23\xcf\x18\x66\xe5\x01\xcc\x65\xae\xff\xbb\x78\xbc\xac\xa4\x40\x45\x0e\x64\x6b\xd5\x61\xf6\x45\x59\x10\x5e\xea\xec\xcd\xe2\x91\x44\x42\x35\x00\xc8\x87\xa6\x01\xe8\x85\xe9\xed\xb9\x63\x45\x7b\x37\x16\x6c\x6d\xdf\x63\x6d\x88\x9d\x63\x4d\xd7\xa1\x58\x1c\x00\x0b\x35\x17\x14\x64\x2d\x6b\x66\xe4\x15\x98\x6d\xcd\x7a\x57\x36\x38\x88\x50\xa0\x35\x07\x56\x75\x56\xaa\x8e\x19\x11\xa1\x02\x4a\x32\x9f\x98\xb9\x2a\x4c\xfd\xb0\x76\x97\xdc\xf3\xc7\x1c\x70\xd0\x63\xce\x57\xc4\x42\x03\x92\xfc\x1b\x7a\xe1\xc7\x1c\xe3\xe4\x18\x2f\x5e\x1b\x0c\xb9\x34\x2e\xfb\xd3\xda\x66\xe1\xdb\x82\xbe\x1e\x88\x81\x0e\x4d\x3b\x9e\x69\x8c\xc0\x7b\xe7\x23\xfb\xb4\x5e\xff\x7c\xda\x08\xef\x65\xfd\xe1\x21\x14\x6f\x18\x0b\x44\x6d\xaf\xe8\x4b\x06\xbc\xa7\xda\x2d\x6a\x8e\x3b\xff\xf5\x28\x70\xbb\xcd\x4c\x89\x40\x21\x40\xca\xe3\x45\xde\xb7\x63\x52\x04\xf0\x36\x1b\x0a\x3b\x39\x16\x59\x6f\x6c\x75\xa1\x62\xaf\x3d\x9b\xfc\x6d\x40\x80\xb0\x9b\xd3\x3b\xea\x9b\x29\x6a\xca\xe9\x66\xd3\x4f\x27\x69\xbf\x4d\xa6\xc7\xac\x92\x49\x6e\x9e\x5a\x6c\x83\x9b\x3e\x20\xcc\xc2\xf6\x6c\x12\x8a\xc7\xa4\x21\x00\x17\x96\xe5\x77\xc6\xbd\x66\x27\xad\x33\x44\xb6\x61\x7b\x18\xbe\xec\x2e\x71\xcb\x65\x8b\xce\xa5\xa7\xd9\xc4\x2d\x99\xa0\xb4\x42\x23\xa4\xe7\x61\x86\x68\x92\xd9\x85\x7b\xcd\x03\x85\xd5\x0e\xa4\xda\x71\xf7\x99\x78\x06\x80\x9c\x15\x8b\x73\x30\xb2\x44\xa6\xb5\xe2\xb8\x69\xab\x32\xe9\x7a\x26\xca\xf9\x94\xf9\x88\x0b\x96\xbe\xed\xe1\x26\x68\xf9\x9f\xe4\xd2\x88\x6b\xe6\x96\x72\xd4\x4e\x99\x0f\x08\xe3\x6f\xd5\x67\x38\xe0\x1b\xd7\x97\x32\xef\x1a\x1b\x39\x32\xe4\x6c\x90\x00\xc0\x47\x24\x47\x2b\x06\xc1\xf0\x59\x96\xea\x35\x84\xe7\x73\x6a\x15\x11\xdf\xd9\xbb\x85\x08\x82\x46\x8b\xd2\x38\x3c\x42\xfd\x68\x56\x44\x5e\x1d\xb9\xac\x0f\xf9\x3b\x8f\x1c\x07\xdd\xb6\x40\xa7\xde\xa1\x38\xf9\xc3\x23\x35\xa3\x1a\xca\x14\xfa\xa6\x63\x3d\x4a\x6e\x22\x40\x4c\x2b\xf4\x76\x71\xc4\xb0\x4e\x71\x25\x52\x40\x18\xcc\x9c\xe3\x92\x21\x8c\x4b\x9f\xc2\xfe\x6a\xc3\xbb\x66\x7b\x90\xde\x81\x7c\x87\x78\xd2\xa4\x31\x3f\xd0\x2e\xcb\xc2\xae\x31\xe2\x8e\xf3\xca\x1a\xd1\x8b\x76\xb3\x54\x2b\xf4\xb6\x3f\xce\xb3\x8b\x13\x10\x67\xb2\xa6\x27\xe5\x60\x1c\xfd\xb4\x8b\x61\x0b\xf6\x34\xb8\x63\xe4\x67\xf7\xf7\x43\x8b\x28\x26\x1d\x42\x6a\xd5\x88\x87\xaa\xac\x89\x51\x06\x07\xf4\x86\xb9\x39\x3c\x2d\xfa\x48\x27\x09\x51\x99\x61\x87\xca\xeb\xd5\x46\x22\x8f\xb4\x6b\xa3\x70\x59\xf9\x46\x3c\xfb\x7d\x24\x62\xde\xda\xd4\x55\x46\xc7\x1f\x67\xe1\xab\x9d\x2c\x4e\xa3\x88\x0c\xfd\xc8\x3d\x55\x69\xbc\x34\x70\x40\xcc\x0c\x09\x04\x03\x2d\x5d\xc0\xe2\x50\xc5\x92\x3a\xe5\xeb\x98\xa5\xf7\x01\xc4\x47\x36\x75\x76\x04\xc2\xe4\xc2\xf6\xba\x75\xc2\x0e\x45\x9f\x01\x32\x40\xf6\xb1\xa3\xa5\x71\x32\xf0\x11\x04\x00\xb7\x3a\x53\x7c\x75\xf3\xa0\xaf\x01\xc8\x52\x2e\x76\x04\xff\x59\x42\xbc\x60\x6e\x39\x06\xb6\x81\xa2\x8f\x25\x4a\xcc\x27\xc3\xa8\xf7\xe9\x0d\x5f\xa0\xa2\xf9\x8c\xef\x35\x40\xd1\xf6\x35\xe7\x17\x75\x77\xd0\xa3\x58\xb5\xc1\xf4\x47\x8a\xc0\x1e\xe3\xf4\x76\xa6\x5b\xa5\x6a\xf5\xee\x7d\x56\x35\x43\xec\xf9\xf1\x95\x4a\xb4\x72\xed\xcd\xd7\x68\x46\x53\x61\xdc\x4b\x27\xd9\x5b\x9c\x9a\xce\x61\x7a\x9f\x13\x47\xb7\xed\x19\x22\xe4\xf7\x25\x8a\x1e\x48\xd1\xd5\x07\xcd\xb2\x4a\xec\x39\x82\xa5\xc0\x2d\x13\xa5\xe4\xae\x4d\x40\xa3\x0f\x97\x46\xd7\xba\xd6\x7a\x8f\xa5\x08\x8d\xbe\x4b\x8a\x52\x3d\xa2\x48\x78\x6f\x46\xee\x9c\x02\x37\x01\x56\xdd\xf1\xb8\x69\x99\xe6\x6a\x41\x77\x94\xd8\xec\xcc\xc4\xa5\xc8\xb2\xbf\x09\xd1\x77\xd1\x5e\xf3\xd8\xe9\x07\x03\xcf\x0a\x73\xe9\x03\x80\x0c\x38\xd6\x6d\xcf\x73\xb3\x99\x94\x01\xa3\xdc\x58\xe4\xba\x8f\xe9\x43\x34\x7f\x57\xf0\x3a\xf7\x08\xd2\xd9\xf9\x41\xd1\xb6\x66\xe6\x1f\x8d\x14\x07\xe5\xe2\x94\x7d\x50\x9a\x17\xb2\x88\xb3\xdc\xa6\x80\x4e\x0b\x8a\x8c\x18\x0f\x9c\x9f\xb8\xc4\xd9\x3d\xd0\xb4\x20\xa5\xf8\x75\x33\xa9\xdd\x7c\xde\x19\x30\x7b\x06\x00\x20\xf0\xd4\xe3\x1d\x0a\x49\xe0\x74\x40\xac\x47\xf5\x56\xad\xab\x77\xe5\xb8\xb4\x0f\x7b\x69\xee\xf8\x58\x94\xb3\x37\xc5\x09\x44\xce\x48\x16\x64\x17\x1c\x1d\xc4\x35\xcb\xb8\x41\xd1\xf9\x5f\x5a\x62\x7e\x3e\x34\x1c\x6f\xcf\xd2\x1a\x44\xee\xc1\x9e\xac\x0f\x66\xb5\x2d\xd1\xe9\x66\x0e\x7a\x8c\xf3\xd0\xd7\x80\x93\xf7\x77\x87\x1b\xbc\x5c\x1f\x2c\x72\x70\x2e\x94\xae\x1a\x18\xbc\x2f\xe0\xf9\xa6\x8f\x62\x69\x67\xd9\x07\xfe\x97\x40\x6b\xce\xec\x5a\xd8\x85\xf3\xac\x5b\x38\x20\xb2\x2e\xdf\x9a\x16\x31\x68\xc8\xb8\xbe\xaf\x88\x82\x82\x77\x4a\x54\xbb\xf5\xfd\x64\x57\x7b\x4f\xaf\x39\x20\xe8\x5e\x41\xfa\xfa\xa9\x7d\x43\xf7\xe4\x9f\x80\x9d\x3d\x77\xb8\x96\x31\x04\xc1\x03\xb5\xda\x71\xf7\x78\x80\x0f\xc2\x79\xb2\xa7\x82\x17\xd0\x1e\xc0\x61\xaf\x5a\x6d\x62\xbc\x0c\xa2\xa9\xf9\x6e\x0a\x34\x0e\x5c\x35\x4f\xb0\x75\xd2\x61\x71\x03\x9d\x35\x40\xe1\xfa\x04\xb7\xda\x7b\x07\xce\xab\xbe\x64\xc9\xe1\x6b\xdf\x6b\x4d\xd4\xcf\xa5\x1e\x1d\x8d\xf9\xab\x71\xab\x8f\xdb\xe4\xa1\x5a\xa1\x68\x7c\xc4\xcc\x71\xa1\xef\xc0\x4c\xe4\x2b\x11\xe5\x0a\x89\x63\x4c\xaf\xf3\x5a\x38\xb6\x6c\xe6\xb7\x3f\xfe\x80\x5c\x3f\x84\xfc\xa5\x39\xd0\xcc\x32\x56\x85\xff\x6d\x17\x02\x24\x49\xb5\x16\x2c\xf8\x1a\xbc\xeb\x65\xd3\x86\x01\xf6\xae\x10\x8f\xcb\xec\x9e\x1f\x06\x00\xa1\xeb\x60\x97\xeb\xed\xbc\x5f\x87\x5d\x0f\xb8\xc2\x5e\xca\xd7\x00\xc7\x8a\xdb\x49\x38\x67\xd7\x21\x26\xb3\xb9\x62\x44\x6c\xd7\xec\xf3\x13\x57\x26\xbc\xb5\x7b\xf8\x88\xb7\x66\xc5\x09\x3b\x35\x5e\x75\xfd\xa8\xa5\x36\xc8\xcd\x3f\xe2\xa7\x71\xff\x00\x60\x82\x56\x7d\x7b\x30\xc4\xae\xbe\x77\x34\x94\xf8\xde\x35\x7c\xb5\x96\xeb\x62\xcb\x1d\x89\xf5\x41\xb5\x16\x84\x15\x4a\xa8\x6b\x98\x18\x37\x3a\xc3\xb6\x57\x25\xc0\xbe\xf6\xe2\xfb\x44\xbe\x38\xd9\x29\x54\xd8\x36\xaf\xce\x37\x7d\x09\xb6\x9b\x4e\x40\x02\x76\x18\xeb\xe7\xa5\xc9\x1f\x42\x54\x9b\xc3\xf8\xa3\x26\xda\xf0\xe4\xc0\x69\xb2\xc7\xa1\x5a\x4d\xb0\x9d\x61\x15\xed\x03\x09\x49\x08\x61\xd2\xe9\x91\x98\xbd\x7d\xec\x00\xaf\xfa\x19\x48\x6f\x6b\xdc\xf8\xdb\xe2\x28\xec\x8d\xd8\x4f\xb7\xa3\xb7\x43\x30\xf6\x21\x2b\x48\xd4\xe7\x26\x10\xf5\x41\xc1\x02\xbc\x92\xcd\xd1\xe2\xc9\xb0\x3e\xaa\x0e\x0b\x61\x06\x32\x1f\x76\x17\x49\xda\xad\x7c\x2f\x31\x8d\x75\x88\xaa\xad\x9e\xc9\xbf\x55\xd5\xed\x5b\x9d\xdf\x5a\x72\x7e\x2f\x2d\x4e\x7a\xf3\x3c\xa7\x3e\xac\xc8\xa8\x44\x41\x00\x07\xe4\x97\x08\xa4\x1d\x14\x61\x6f\x24\x3c\x81\xce\xf3\x92\x5d\x73\x7f\x8e\x67\x6b\xf7\xb1\xc9\x02\x16\x36\x52\x85\x37\xda\x2e\xb9\x17\x77\x1a\x45\x3e\x0d\xf3\x4d\x09\x0a\x62\x36\xcd\xa3\x09\x95\xa1\xb0\x38\xdf\x5b\x11\x4e\x36\x43\xd5\xc4\x06\x1c\x91\x8c\x1e\xd4\xc1\x66\x73\xeb\xd6\x31\x4a\x1e\x46\x00\x4c\x36\x1f\xe9\xb2\xe5\x06\x32\x2f\x9b\x16\x5b\x01\x98\xac\x34\x5d\x93\x2b\xc0\xd9\xae\xf7\x2d\xfb\x29\x24\x71\x11\xd9\x74\xf3\x2f\x19\xd7\x9a\x67\x0d\xc9\x99\x49\x85\xd5\xad\x84\xc3\x6a\x2b\xa3\x5a\xf3\xb4\xdc\xc8\x42\x54\x97\x9c\xf9\xe6\x96\xde\xf3\x9a\x19\x7b\xbc\xd9\x25\x0c\x7a\xf6\x7e\x23\xae\xcd\xe4\x4e\x00\xd7\xfe\x01\x06\x2d\x92\x80\x7d\x0e\xb4\xf6\x84\xd6\xb6\x6a\xc0\xfa\x05\x97\x0a\x02\xde\xb2\x90\xbb\x58\xc6\xf7\x44\x22\x6c\x5c\x11\x94\xd0\xbf\x8f\x9f\xdc\x4b\xc5\x23\xb5\xeb\x5f\x17\x3d\x57\x53\x8a\x57\x0f\xfa\x99\x95\xba\x81\xdb\x83\xcf\xfb\xc3\x41\x5d\xeb\x85\xf7\x13\x65\x34\xe0\x7e\x69\xb4\x74\xba\xcd\x5f\x2b\x7d\xfe\xed\x6a\xfb\x55\xb4\xc6\x16\x8b\x3b\x74\xb4\xb2\x4c\x7b\x6e\x9c\xe8\x07\x1b\xe3\xf8\xf1\x03\x72\x60\x78\x35\x9c\xcb\xbd\x7f\x70\xb9\x75\x5b\x1d\x21\xa6\x67\x39\xef\xc8\xd3\x21\x23\x7b\x2f\x75\xa8\xa1\xe8\xed\x54\xee\x35\xf4\x4f\x51\x42\x02\x26\x4d\xe9\x7b\xb9\xbf\x98\x9f\xc1\x0d\xd1\x03\x6c\x1d\x7a\x9b\x6d\x89\xfb\x88\x42\x84\x35\x6e\xf7\x20\xc4\xd6\x88\x48\x01\xf4\xa6\xb9\xbe\x3b\x25\x82\xa1\xd0\xed\x95\x80\x35\x2b\x4c\x4c\xdd\xdc\xb2\x64\x56\x90\x61\x47\x87\x88\x5b\x7b\x3c\x54\x0c\xe2\xb6\x49\x43\x7f\x67\xed\x27\x6f\x51\x49\x78\x4b\x89\x1f\x64\x78\xeb\xb4\xbd\xf4\x7c\x6b\x7a\x73\xf9\xed\x73\xc8\x8f\x5a\xfa\xd7\x7b\x47\x68\x4b\x72\xab\x81\x03\x1e\xd1\xa4\x00\x81\x6b\xe6\x21\x6d\x15\x87\x7b\xfb\xd4\x91\xa8\x69\xa6\x1d\x7d\x09\x77\xfb\x59\x17\x95\x4f\x86\x47\xe8\x72\x43\xfb\xd0\x00\xec\xf6\x04\x6d\xe8\x48\xf5\x51\xf8\x78\xe4\x51\x64\x8d\x80\x94\x94\x58\xb9\x7d\xe2\xec\x2d\x81\x02\x27\xd7\xd4\xb7\x37\xad\xb9\xa1\xb9\x15\x32\xe3\x46\x0b\x85\xdc\xec\xae\xcd\x49\x27\x14\x81\x8d\x66\x09\xcd\x6e\x86\x82\x2f\x37\x6f\x76\xd1\xc7\x0e\x12\x38\x5e\x13\xd5\x6d\x56\x42\x55\x39\x69\xd7\xf6\xaa\x07\xfd\x3d\x31\xf2\x42\x2c\xf4\x31\x47\xe3\xc3\xea\xcf\xa8\x22\xac\x45\xc4\x27\x1a\x06\x5b\x1a\xf5\x4d\xb4\x75\x44\x03\x3b\x47\x1c\xfa\x9f\x6b\x14\xbe\x82\x21\xce\x87\x1e\xf6\x5e\x14\xb2\xa1\x02\x37\xf1\x0b\x4f\xce\xfb\xfe\x01\xc9\xdb\xb1\x15\x04\x19\x66\xc8\xb2\xe6\x7b\x46\x5b\x0b\x19\x40\x3c\x42\x7b\x16\x4e\xe5\xe1\x99\x69\xaf\x69\xbe\x1a\x7d\x7c\x8e\x4d\x3b\x5a\xbc\xd9\x0f\x85\xdc\x79\xb2\x61\x18\x9c\xf8\xbe\x2e\x31\xc6\x1b\x73\x57\xb4\x59\xe5\x77\x55\x07\x35\xa4\x88\xee\xa8\xf0\x99\xf9\xb4\x47\xd5\xaa\x0f\xb8\x7f\xfe\x00\x22\xe0\x96\x3f\x7a\x41\x69\xfe\x3f\x33\xfc\xee\xd6\xdd\xbb\xbd\x15\x51\xc3\x2c\x7f\x0f\x59\x99\x3b\x35\x3c\x20\x95\xdc\xe9\xe5\x76\xda\x12\x4f\x4e\x3a\x38\x4c\x60\x72\x60\x57\x86\x5c\x4b\x98\xdd\x0f\x7e\x55\xb0\xab\x23\xe9\xfc\x3c\x16\xde\x79\xbb\xac\x1a\xe6\xab\x4f\xa4\x79\xee\x0f\xf6\xf3\x91\x54\x37\xf0\x5d\xaf\x0f\x9d\xfa\x83\xdf\xd8\xda\x61\x0c\x63\x67\xb8\x76\x2b\xf0\xcc\x3a\xe6\xfb\xdb\xd4\x7b\xc7\xf5\xdb\xbe\xab\x3b\xb7\xf2\xbd\xe7\x32\x37\x40\x79\x5e\xbd\x1a\x5b\xdf\x50\x7e\x71\x23\xb5\xff\xb1\xe6\x7a\x49\xa9\xd0\x0c\x4f\x69\xb7\xe9\x1e\x5d\x15\xb3\x95\x38\xbe\x5e\x3b\x18\xd6\xc5\xcd\xa5\x3b\x9e\x97\x66\xcf\x68\x38\xe6\xe3\xb6\x5b\x40\xef\xda\xf2\xf9\xd6\x0b\xda\xe6\x30\x4e\xff\xea\x7d\x52\x72\xd7\xea\xa3\x75\xde\x6a\x74\xac\xb9\xea\x09\x20\x89\xad\x8a\x52\xab\xd4\x4a\x8f\x96\xb1\xbd\x2a\x4d\x05\x53\xef\x08\xac\x75\xaa\xa4\x7d\xd7\x8e\x3d\x21\x6b\x9c\xbf\x78\x8b\xcd\x22\x70\x63\x65\x48\xd9\x5a\x3a\x4d\x34\x78\xbe\xe6\x57\x24\xcb\x99\x49\x4d\xc8\xb0\x13\xb5\x48\x3f\x8b\x6d\xc1\x3e\xc9\xad\xbb\xe6\xdf\x36\xfb\x8a\x59\xd6\x78\x40\x6c\xb9\x9f\x95\x0f\x75\xbf\xea\xee\x0f\xfc\x2a\x14\x9d\x35\x1d\x1c\x01\xcf\x8f\xbd\xa3\xd2\xf9\x40\xac\x72\x9e\xae\xd6\x5b\x23\x20\xc2\x7d\xce\xe9\x63\xdc\xc8\x66\x70\x7f\x48\x08\x3b\x42\x98\x62\x0d\x45\xef\x35\x11\xe6\xb9\x92\x74\xb4\xa6\x87\xbb\xcd\x97\xb7\xf5\x47\xf7\x81\x35\xf2\xf2\x9e\x95\x5b\xb2\xbc\x9d\x93\xfa\xe5\x28\xf4\x32\xdf\x30\xf4\x00\x8c\x8b\x61\x7e\x3a\x52\x81\xb8\x74\x61\x91\xaf\x53\xdf\x1e\x5a\x6e\x1c\x02\x68\x5f\xc7\x33\x68\xe9\x7b\x90\xb5\xcc\x24\x99\x75\xb9\xe6\xd7\x3d\x73\xb6\x56\x40\x3a\x02\x6b\x6c\xf5\x42\x0d\x4e\xf3\xf5\x93\x3d\x93\x74\x89\x81\xd3\xe5\x1a\xe0\xf6\x1a\x63\x59\x87\xac\xab\xb0\x7b\x47\x76\x61\x0d\xb9\x20\x8b\x3b\xcb\xc0\x47\x72\xa3\xbd\x8b\x5a\x6e\x06\xc7\x7e\x96\xea\xd1\xd7\xda\x06\x11\xeb\x7c\x02\x85\x58\x77\x0b\x83\xa3\x34\xd8\x81\x72\xca\x7a\xac\x63\xa6\xce\xbe\x42\x5f\x99\x3b\xd8\xef\x7c\xbc\xa5\x2a\xd2\xc8\xc7\x61\xde\x61\xc4\xea\x78\x03\x56\xd6\x72\x28\xec\x49\x8c\xf5\xb5\xa2\xbd\xfd\x97\x55\x18\x29\xbb\x03\x93\x2d\x09\x8c\xe4\x4c\x14\x46\x35\x33\xed\x9a\xea\xd8\x1f\xfe\x91\x04\x9e\x5d\x79\x35\xa0\xb3\x5f\xbc\x0a\x3d\x2f\x94\x8f\x45\xea\x28\xca\xf9\xf7\x9b\x88\x7e\x2f\xcc\xc7\x27\xaf\xbd\x5d\x19\x7b\xce\x4e\xc7\xb6\x2e\x40\x5b\x7c\xf6\xab\x38\xef\xe7\x22\xbf\x62\xf9\xbf\xc8\x0a\x8c\xe5\xef\x11\xa9\x62\x85\x0f\x67\x8b\xe8\xee\x45\x5e\x09\x10\xde\x35\x82\xee\x0e\xa9\x67\xd9\x4f\xd9\xcb\x7d\xa0\xeb\xf0\x42\x2a\x25\xd7\x97\x93\x6b\x29\x33\xc4\xb8\x2a\xe5\x2c\x1c\xfb\xde\x44\x56\x96\x32\x5e\xc8\x69\xaa\xb4\xf7\xfb\x8c\x00\x0b\xe3\xa5\xb1\x2e\xc3\x25\xa1\x4f\xd8\xae\xaf\x4b\x7b\xe7\x28\xff\x82\xf1\x1c\x6d\x7c\x48\xdc\xac\x53\xde\x61\xa1\x39\xeb\x5d\x23\x16\x26\x7b\xe0\x98\xd1\x63\x5f\xd2\x41\x11\xab\x0b\x50\x5d\xa4\xb7\xef\xfd\xa5\x24\x1e\x6b\xfa\x5f\xfe\xa6\xc2\x88\x39\x0a\x6c\x35\x8b\x41\x99\x0b\xc2\x65\xed\xa5\xd5\xef\xcb\x42\x7e\x3b\xc6\x64\x38\x67\x6e\x3c\xdb\x25\x8f\x89\xae\x1e\x58\x7b\x92\x31\xbb\xc3\xd7\xe3\x18\x16\x75\x2e\xac\x65\x73\x31\x1a\x0a\x5c\xd9\x5f\xfd\x16\xc0\xd9\xc5\x19\xd2\xf0\x71\x1d\x6a\x2d\x2f\xfd\x8a\x98\x21\xbe\xd0\x3d\x12\x5b\xa7\x37\xbd\xc9\x4b\x7a\x6f\x6c\x5c\x9a\xc5\xe0\xa5\x25\x5d\x9a\xb6\x78\xda\x25\xb5\x20\x75\x0c\x36\xbd\xc3\xd0\x9c\xbb\x6b\xb7\x24\x75\x30\xc9\x82\xe7\x1e\xa0\x15\xbd\x04\x24\x7d\x77\x61\x4f\x99\x59\xcd\x55\x04\x8d\xea\x09\x43\x93\x32\xc8\xf2\x30\xd5\x0c\x5b\x3c\xa6\x6d\x0f\xd3\xbe\xfa\xf4\x52\x7a\x81\x53\x57\x7f\x89\xc3\x58\xfb\x00\xae\xaf\x4c\xbc\x5c\xd2\x22\xce\xfa\xec\x9f\xc8\x78\xbc\x31\x50\xb0\x24\xb1\xea\x67\x40\xa9\xfb\x49\x6b\xce\x1e\x79\xa9\xdd\xcc\xa9\x68\x47\x4f\xeb\x0f\x6a\x89\x9f\x1c\x51\x60\x0b\x94\x1f\xf4\xea\xdb\x64\x11\x69\x1f\xc7\xc4\x1b\x09\x98\xca\x4c\xe2\x92\x00\xf1\x3a\xc9\xd1\x29\xcf\x4b\xca\x33\x6a\x29\x5e\xb1\xa1\x67\x85\x17\x6a\x3e\x80\xc5\x5f\x9c\x3e\xd2\xee\xe2\x53\x9a\x9d\xf8\x00\x26\x4f\xc0\x58\xbe\x39\xfa\xbe\x7c\xe3\x5b\xc2\x4b\xeb\xcd\x3b\x5f\x1a\x1c\xef\x5d\xc8\x73\xf8\xc1\x56\x37\x14\x65\x39\x5f\x8b\xc0\xee\xae\x3a\x13\x20\xf1\x10\xc8\x98\x2f\x0a\x77\xcf\x8a\x30\x17\x28\x5e\x2c\x70\xa4\xfb\x53\x6e\x64\x8e\xc1\x7b\x33\x14\x75\x3e\x57\x0e\x4c\xcc\x80\x45\xf8\x94\xa4\x33\x9b\x72\x68\x67\x6e\xb0\xc5\x19\x48\xa0\xf0\x21\xcf\x55\x6d\xfa\xb9\x16\xad\x88\x71\x60\x0e\xef\xb3\x6d\xa7\xd6\xd4\x6c\x2d\x2f\x2e\xa8\x64\x6d\x37\x76\x5a\x9d\x42\x71\xe6\x9a\xd8\xdd\x77\x19\x1a\x1e\xa3\xb5\xf7\x2f\x49\xc9\x3b\x68\xfe\xe2\xef\xeb\x93\xe3\x19\x4d\x4c\xdd\xf1\xf2\x52\x79\xd4\x8c\xd1\x61\x9d\x5f\xc2\xcc\x07\x8a\x1d\xba\x03\x49\xa3\xad\x28\x34\xdd\x52\x14\x3c\x47\xf6\x8b\xbc\xf9\x90\xa0\x71\xbe\x8c\xb0\xf7\x09\x2e\x35\xce\xfc\x74\xb9\x59\xb3\x93\x2e\x4d\x7b\x41\x30\x0a\xca\xb7\x6a\xce\x91\x40\x0d\x8b\xdc\xf3\xe0\xe8\xcd\xd9\x23\x84\xf9\xbc\x5b\x47\xec\xef\xab\x41\xe6\xf9\x3d\x9a\x51\xab\x04\x94\x9f\x76\x03\xdf\xbb\xf6\x19\x0c\x40\x51\x8f\x30\xfc\xf3\x39\x5b\xa7\x92\x18\x96\x39\xbd\xde\xf1\xca\x9b\x1d\xae\x40\x33\x3d\xcf\x4d\x05\xeb\x10\x88\x1b\x7f\x59\x67\xdb\xbb\x6a\x33\x2a\x12\xfd\x7c\xee\x8d\x42\x1f\x4d\x12\x8f\xd0\xa6\xa1\xcf\xde\x6c\x8d\x36\xea\x18\x24\x17\x2c\xd5\xba\xb1\xbf\x67\x8e\x21\xac\x99\xe9\x0c\x33\x34\xfc\x7d\x0a\xb4\xd8\x65\x4d\x2d\xd2\xf2\xfb\x69\x7f\xdb\xe7\xdf\xcf\xde\xd1\xf5\x7e\x60\xdf\x9e\x77\xcf\x37\xe1\xdb\x5f\xde\xe7\x2b\xd1\xb9\xfb\xbc\xfe\x20\xff\xe1\x56\x38\xb7\x9e\xfb\xd5\xff\xbd\x35\x98\x6c\x4d\x17\x86\x4c\xd3\x7e\xda\x42\xe4\xd7\x5b\x7b\xd4\x19\xf5\x15\x55\x3c\x81\xef\xf5\x7a\xa4\x7f\x6e\x58\x9d\x27\xcc\xba\x75\x45\x9c\xfa\xbe\xd6\x7f\xd1\x6b\x07\xdd\x3e\xd9\x06\xb4\x83\xb5\x48\x82\xde\x19\xf7\x7e\x00\xb3\x47\x4e\x58\x5d\x29\x60\x83\x7d\x63\xc5\x98\xb7\x35\x39\x63\x05\x81\x93\x74\xfa\x96\xd8\xf8\x04\x9c\xba\x0c\xb2\xe7\x3b\xe0\x12\xb4\xfa\xd4\xf4\xad\x41\xa0\x67\xcf\x9e\x58\x7a\x52\xeb\x27\x5d\x6d\xeb\xe9\x78\x52\x15\xcd\x25\xda\xcf\xcf\xfc\x2b\x26\xfd\xaf\xa2\xeb\x9f\x79\x7d\xf3\x7e\x3e\xf3\xa8\x17\x11\x01\x0f\x87\xba\xa0\x4f\x08\x01\x69\xdd\x44\x72\x3f\x38\x10\x4f\xa2\xe8\xd1\x3d\x1d\x2e\x9a\xb1\xe7\x04\xe1\x4d\x3f\x5e\x5c\x73\x62\xf1\xad\x3e\x9f\xf5\xeb\xe8\x0d\xe5\x9f\xeb\xb7\xf8\x64\x47\x2b\xa5\x6f\xdd\xc8\x9f\xeb\xe7\xed\x18\x4f\xb7\x07\xc7\xfa\xfe\xd4\x48\x37\xfa\xa9\x52\x27\xf9\x71\xbd\x75\x36\x3f\x7f\xc4\x4a\xf9\xa9\x6a\x9c\xff\xc0\x6d\xa8\xc5\xa6\x35\x3e\xd8\x3f\xd6\x26\xf3\xad\xd9\xf7\x8d\xd5\xf9\x8f\x23\x55\x65\x71\x19\x75\x18\x6c\xea\xfd\xb3\x9f\xbc\xfe\xf9\x03\xf7\x83\x54\x06\xb1\xef\xf3\xca\xed\x58\x9d\xad\xd7\xf6\x87\x5a\xf6\x3f\x79\xc0\x67\x9d\x30\x7d\x0c\x20\x69\x7c\xfe\x27\xbd\x85\xe7\x8f\x34\xe1\x9f\xb4\x2f\x59\xa0\x7c\x06\x27\xfe\xa4\x51\xa0\x7d\xeb\xf1\xda\x4b\xe4\x0f\xd5\x8f\xc0\xbf\x98\xba\x02\x29\x0f\x2e\x45\x35\xf9\xe3\x99\xf3\x3f\xae\x33\x02\x67\xab\x53\xea\xaf\xc5\x79\xee\xe0\xa2\x07\xc1\x7d\x87\x04\xf0\x2e\xde\xbd\x28\x40\xe0\x9b\xbf\x55\xe6\xc8\xa8\x78\xe7\xfb\x7f\xd4\x6b\x51\xfc\x18\xa5\x03\xa5\xdf\xaa\xf2\xb1\x09\x88\x59\x33\xf2\xd7\x63\x53\x30\x98\x54\x3e\xf0\xfb\x57\x97\x6e\x9a\x3f\x65\x3f\x1b\x7d\xdf\xf5\x8c\xc3\x1d\xed\x64\x7f\x4e\x5b\xe6\x85\xc7\xc7\x51\x28\xc3\xcd\xe3\xd6\x13\x25\xd9\x3f\xb6\x9c\x15\x27\x4a\x6c\x7f\x59\xdb\x61\x5a\x11\x41\x0b\x7b\x14\x7a\x7b\x86\xee\xed\x01\xab\x32\xc6\x82\x63\x2c\x05\xd2\x4c\xac\x7f\x9c\xef\x66\xed\xd7\xf2\xd1\xfe\x76\xc0\xff\x18\xe0\xf8\x0f\xc0\xbf\xce\xc6\xea\x4e\xb6\xc1\x59\xe2\x31\xff\x38\x0b\x45\xe7\xa6\xbb\xc2\xfc\x17\xce\x1a\x35\x91\xcf\xc9\x1b\x84\xd2\x96\xf7\xd4\x8a\xb6\xef\x9b\x16\x07\xac\xff\xd1\x78\xfd\x21\xa2\x05\xbe\x7f\xeb\xb3\xa9\xc0\x23\xf1\xa1\xdb\x9b\xef\x6f\x7d\x75\xaf\xe4\xcd\x4e\x92\x37\x20\xee\x53\x0a\x68\x56\x84\xce\x95\x80\xf4\xf0\xea\xdd\x17\x67\x40\xe3\xe4\xad\xfb\x0f\x0c\x62\x58\x76\x3e\x6d\x75\x80\xf8\x3e\xe4\x0c\xd8\x15\xa1\x49\xa1\xd4\x7b\x49\x8c\xc0\x0f\x0d\xf3\x3f\xfc\xe7\x62\x13\xbb\xd6\x08\xff\xd7\xde\xce\xd9\x11\x52\x94\xfc\x6b\x3f\xdb\x33\xd2\x82\x8e\x34\xc7\xb5\xfc\x75\x84\x7d\x9d\xfc\x3d\xd0\x8e\x7b\xc2\xfb\xbf\xa4\x1d\x10\x17\xad\x2f\x7e\x08\x33\xd7\x49\xe4\xd2\xc7\x0d\x4f\x83\xed\x20\xf5\xba\x2e\xcb\x86\x20\x12\x6e\x62\xf1\x71\xc2\x36\x52\xec\xe5\x6d\x6f\xb9\xed\x28\x97\xa3\xfd\x54\x6e\xd1\x80\xcf\x21\x40\x2b\xd6\x23\xe4\x10\x16\x0c\x34\x49\x16\x1c\x52\x03\x42\x74\x22\x57\x2a\xf2\xed\xa0\x2c\x20\x9d\x02\x64\xfa\xb5\x96\x02\x8a\x8a\x6e\x81\xd9\x15\x2d\xd4\x5d\xfa\xb9\xc3\x78\x7b\x98\x88\xc2\x76\x49\x8e\xd9\xdb\x9d\xf1\x16\xce\xde\xde\xa0\x59\x3c\x1c\xce\xbe\x40\xee\x72\x80\x64\x81\x3f\x3d\xbd\x88\xe9\x1e\x77\xe7\xdb\x90\x14\xc1\x25\x85\x02\xab\xcd\x56\xcd\xa7\xfb\x0c\x2a\x04\xd0\x2f\xe6\x55\x99\xae\x95\x44\x7d\x6b\x81\xa6\x90\xcb\x84\x2e\x81\x20\x26\x66\xaa\x43\x0f\x91\x82\x30\x3c\x41\x5c\xeb\x5b\x27\x31\x06\x8f\x27\x29\xc3\x79\xce\x05\xd1\xe9\x68\x02\xf3\xd3\x37\x9d\x0b\x45\x0a\x3c\xfe\xd3\x26\xb3\xe0\xfe\x27\x89\xfe\x27\x07\x51\xa7\xaa\x37\xc9\x8c\x50\x02\xb0\xfa\x07\xac\xa5\x2f\x4a\x08\xc4\x4b\x0a\x1b\x14\x83\x30\x19\xd6\x08\x01\x98\x5b\xe0\x70\xaa\x4d\x08\x40\xf9\xaf\x53\x2d\xf1\x06\xbb\x8a\xc0\x4c\xb6\xd6\x54\xa3\x29\x3d\x49\xd9\x0d\xd2\x01\x45\x12\x03\xc2\x55\x4c\xcb\x22\xa1\x86\x22\x70\xcf\x54\x10\x84\x2f\x23\x24\x04\xd0\x8b\x61\xe3\x12\xb6\xcb\x43\x14\x72\xeb\xe0\xc2\x70\x3a\x8a\x56\x6e\xd5\x3c\xb4\x06\xd4\x84\x00\xda\xe0\x60\xa4\xdb\x94\xdf\x83\xc7\x24\x4c\xd6\xda\x26\xf5\xdf\x7a\x84\x0a\x4a\xa4\xcc\x00\x1f\xe2\x09\xae\xbb\x6d\xc2\x10\xb5\x3f\xac\x56\x76\x42\xbd\xb5\x76\xad\x2d\x4d\x90\xff\x12\x03\x7f\x32\x69\x31\xec\x6a\xca\xf3\xf6\xd1\x03\xb6\xe2\x72\xcc\x59\xbf\xcc\x13\xa2\x35\xbe\x3e\xb4\x08\xdc\xd6\xcf\x31\x1d\x06\xee\x51\x9d\x30\x57\x17\xe8\x24\x72\x6f\x85\x4d\xc7\x99\x42\xde\x01\x81\x9a\x27\x9b\xe2\x6e\xe7\x58\x72\x50\x64\x9c\x64\x08\x74\xab\xd2\x2b\x06\x55\xa6\xf4\xeb\xcd\x54\x9b\x46\x04\xd5\x94\x24\x1f\x48\x89\x01\xee\x2a\x1d\x9c\xb3\xff\x66\x31\x19\x5d\x61\x80\xd3\x81\xda\x41\x93\x34\x36\xd2\xaa\x4d\xae\x47\xa5\x28\xc0\x3a\xae\xec\xa0\x7a\x54\xdf\x19\xbb\xc6\xad\x6d\xb3\xd9\x60\x98\x62\x9c\x25\x9a\x7e\x13\xc8\xb1\xa7\xcc\x19\x72\x61\xd0\xa3\x5c\x55\xac\x5c\xf4\x6e\x9d\xb8\xec\xa3\x4f\x27\xc9\x0b\x50\xe9\x02\x39\x2a\x83\x7b\x08\x70\x81\xc7\xb7\x1c\x9e\xe3\xa5\xb3\x19\x2f\x6f\x7a\x8f\xe8\x82\xb2\x3c\x7b\x0b\x7c\xe4\xe0\xf0\x88\x18\x92\x99\x81\xe8\xd6\xb3\xfa\xa5\x34\x81\x3d\x2f\xe8\x9d\xaf\x2c\xec\x71\x36\x66\x5b\x57\xc4\x9a\x8d\xa4\xda\xef\x17\xd2\x5f\x76\x99\xcc\x82\x87\x85\x70\xa2\x10\x13\x88\x0c\xf8\xd1\x75\xc3\xbf\x24\x41\xa0\x95\x2a\xbb\x45\x23\xf9\xa4\x63\x0c\x29\x9b\xc1\x10\x49\x33\xec\x30\x86\xa2\x6d\x95\x47\x50\xfb\x19\x32\x27\x73\x98\xab\x76\x9d\xc9\x2e\x30\xc3\x1a\x52\x6f\x5a\xa9\x89\x20\xa4\x5f\x47\x37\x71\x2d\xbb\x1b\x4f\xcf\x26\x18\x11\xb4\xc3\x65\x15\x08\x3c\xba\xec\xac\xcc\x2b\x14\x16\x5c\x99\x89\x07\x52\x01\x81\xa2\x31\x86\x66\xc1\x43\x47\x56\xe7\x61\x61\x48\x03\xcc\xbc\xee\x95\xdb\x29\xc4\xd2\x8d\x4d\xe5\xc0\x61\x9f\xef\x91\x21\xdd\x2a\xe6\x56\x4c\xdf\x97\xba\xc5\xe3\xac\x1b\x05\x72\x7c\x34\x5f\xa0\x55\x30\x4a\x04\x72\x04\x9c\x4f\xe8\x77\xb3\x17\x7f\x72\xcc\xe8\x45\x7b\x1b\x5d\xc1\xc8\xcf\x01\x4d\x6a\xd6\x5a\x66\x32\x88\x60\x2c\x4a\xd5\x1d\x43\xeb\x7a\x54\x23\x7b\x2c\xe0\xd8\x71\x54\x75\x9c\xa0\xbc\x49\x39\x87\xc9\xe6\x79\x5d\x36\xe2\x91\xe6\xaf\x8c\xab\x1a\x73\x3c\x0e\x7a\xae\xc7\x08\xc1\x71\x1b\xec\x19\x8d\xdc\x8c\x08\x3e\x9e\x65\x45\x20\xc2\x98\x5d\x5e\x07\xa8\x3f\x7e\x34\x47\x04\xf1\x15\xaa\x21\x54\xc5\x5f\x24\x7f\x0e\xf1\xdd\xe2\xd4\xeb\x31\x20\x25\xcf\xf8\xc5\x75\xe4\xa8\x55\x81\xf4\x9a\x7b\xa4\x4b\xc5\x2c\x7b\x40\xe3\xde\xcd\xb9\x63\xff\x60\x4c\x7f\xa8\x74\xad\xbd\xe2\x27\x9a\xde\x92\xbc\x48\xed\x21\x48\x72\x7a\x87\xb0\x02\x4d\x46\x8d\x43\xcc\x4c\x57\xdc\x15\x16\x69\x24\xcd\x90\x3f\xd7\xbe\x1e\x1e\xde\x35\x2a\x51\x0d\xd3\xb9\x19\xac\x3e\x46\xa5\xac\x8d\x2d\x92\x1e\xde\x84\xd9\x9d\x94\x66\x39\x6a\x87\x15\xda\x98\x34\x4a\x34\x26\xd6\xab\x23\xe3\x37\x1e\x97\xeb\x93\xd2\xd5\xfe\x60\x18\xd1\xe3\xda\x83\xba\xfa\x68\xa0\x38\x58\xd2\x2a\xb8\xd6\xe7\x5b\x3d\x35\xb3\x07\xc2\x81\xf4\xcb\x90\x3e\x59\xea\x0f\xab\x41\x76\x6f\x94\x3e\xec\xc2\x2c\xf5\x74\x3f\xf2\xe3\xd2\xcd\x40\x94\x22\x0f\xfb\xd1\xf4\x49\x30\x66\xe2\x8e\x76\x1f\x3c\xf1\x7a\xec\x81\x70\x5f\x1e\xc4\xfe\xd1\x98\x79\xec\xd6\xaf\xb7\x7f\x34\x2b\x35\x20\x10\x87\x10\x12\x0f\x15\xae\x34\x6f\x2b\x9b\x3d\x6a\x03\x88\xed\xd7\xea\x25\x22\x86\xd8\xa6\x96\x65\xf7\x2a\xa2\x8b\x50\x92\xc2\x03\x06\xf5\x86\x50\x5c\x84\xbc\xc4\x5c\x93\x46\x8b\xbd\x94\x42\xc2\x0a\x7a\x13\x22\xbf\x3c\x20\xf4\x94\xfe\x84\xf2\xc7\x61\xef\x1f\x61\xa6\x90\xa0\x78\xda\xa5\x96\x40\xc2\xee\x5b\x90\x2e\x01\x0a\xd6\x22\xd0\x21\x25\xc1\xa5\x1e\xb5\x25\xf3\xd3\xbb\xa2\xa5\xeb\xbe\xde\xe3\x86\xad\xc4\xa3\x91\x4a\xc5\x5d\x6a\xce\x1e\x2f\xac\xb1\x85\x31\xe2\x03\x21\x54\x71\x4e\x3e\xb0\xfc\x25\xb5\x0a\xbf\x00\xd0\xaa\x50\x9a\xed\xe3\x6e\xf0\x50\xb7\xa2\xd9\xcf\xb0\x12\xf5\x22\xa4\xac\xf2\xf0\x6c\x98\x30\x05\x0c\x7c\xcc\x1f\xe3\x98\x2e\x76\x21\x54\x9a\xd9\xbe\x47\xe4\x54\xb9\xc2\x03\x67\xe6\xc2\x70\x77\x2d\x93\x87\x90\xc0\x81\x8d\xd6\xca\xc5\x1f\xd2\x5b\x5b\xf4\x76\x8e\x4d\x5e\x2d\xd1\xe0\x31\xb7\x34\x0a\x17\xb8\xe8\x92\x36\x90\x9a\xbc\x46\xc3\x94\x3e\x66\xbd\x5b\x8f\x72\xa8\x83\x02\x58\x8a\xce\xa2\xec\xf1\xa3\xc7\x24\x3b\x68\x02\x76\x3b\x3e\xb3\xbb\x6b\x0c\xab\x50\xa3\x03\x4f\xd9\xfe\x11\x7a\xfc\xf0\x70\x9a\xac\xdf\x24\x45\x51\x80\x0c\x56\xd8\x27\x0a\xca\xd1\x46\x48\x2e\x5b\x34\x8f\x0f\x97\x27\x9a\xc9\xbd\x1e\xca\x92\x1f\x83\xb7\x35\x1e\xa5\x8b\x44\x82\x07\x1c\x9c\x5e\xed\xb3\x20\x37\x03\xc4\x31\x78\x8b\x20\xab\xe6\xbf\x21\x32\x7b\x97\xc1\xee\xcf\xc3\x83\xa8\xdf\x5c\xcc\xba\x8b\xbc\x06\x94\x9a\xfa\x92\x66\x46\x3f\x79\x3e\xf6\xc3\x73\xd7\xb8\x93\xfc\xa9\x93\x01\xf5\x99\xea\x75\xe7\x23\x11\x8c\x63\xd3\x5e\xe7\x61\xb5\xaa\xea\x31\x33\x73\xa4\xf9\x41\x40\x21\x1d\xef\xf6\xcb\x9a\x5a\xec\xfd\xc3\xf9\x59\xbc\x5e\x56\xe3\xa9\x06\x43\x8a\x20\xef\x75\x62\x67\xe1\x91\xe2\xbd\xcf\xff\x90\xd0\xcf\x95\xa5\x91\xe1\xc7\x45\xdb\x37\x64\x26\xfd\x0c\xed\xa7\xe9\xba\xe5\x23\xfe\x79\x8b\xfa\xa3\x98\xa4\xe7\x9a\xff\x21\x5c\x50\x2a\x16\xff\x10\xe9\xa8\xd7\x2a\xff\xeb\x43\xa6\x19\xe6\x4c\x03\x32\x3b\xfb\xbd\x8b\x14\x81\xf3\xf9\x57\xf9\xa3\x66\xf4\x21\x71\x02\xd7\x8e\xfc\x50\x6e\x36\xb0\x5a\xfe\x4d\x11\x3c\x0a\x7d\x8c\xd1\x45\xf7\x5c\xa1\x22\xc4\x2d\x22\x16\x3c\x1f\xde\x07\x95\xf2\x45\x8d\x9e\x1c\xd2\x31\xbd\x79\x96\xa5\x01\xe5\x49\x3e\xcd\x71\x93\xbd\x99\x35\xca\xf2\x43\xd9\xd7\xe3\x55\x18\x15\x90\x37\x30\xf3\xb7\x24\xc5\xdc\xbc\x79\x63\x9f\xfb\xdf\xfa\xda\xb4\x33\x22\xff\x05\x83\x71\x4b\xa0\xe6\x5a\xa1\x89\x6c\x4c\x7b\x70\x23\xf3\x7a\x5c\xda\xed\xea\xf9\xea\xc9\x4d\x3b\xe4\x90\x06\x59\x55\x0b\xe5\x75\x6e\x55\x0f\x42\xbb\x14\x39\x28\xb3\x9d\xfc\x0a\x21\x84\x58\x0a\xa9\x64\x6e\xf4\x7b\xc4\xd2\xb8\xde\xa0\x6b\x85\xac\x49\x83\xa9\xd4\xdc\xd0\x3a\xe8\x8d\x4b\xf0\x62\x41\x1c\x02\xaf\xdd\x62\xf7\xa1\x68\xe1\x2e\x4b\xff\x06\xca\x1b\xa1\x63\x81\xc1\x2e\x56\x78\xb9\x11\x84\x33\x52\x1c\x35\x30\x60\x76\xf1\xc9\x22\x47\x10\xd2\x78\xb7\x68\xa9\x60\xc0\x68\x95\x0f\x2e\xd3\x8d\xa1\xf9\x90\xef\x68\xf2\xcf\xcc\x90\xe2\x71\x5a\xbd\x25\x31\x10\x55\x5a\xd6\x2a\xe4\x60\x25\xd7\x1c\xbd\x21\x99\x43\xb4\x87\x12\x1f\x5c\xe1\xd1\x64\x2f\x73\xf6\x08\x29\x48\xbf\x1c\x9a\xc6\x51\xc4\x37\xd9\xf5\x3d\x10\x35\xea\x36\xc9\x89\xdc\x03\xc9\x62\x19\x92\x5f\x43\xa3\xb2\x63\xac\xb7\x53\x0f\xcf\x2e\xfe\xcb\xc3\x90\xf3\xb7\x64\x3b\xc2\x93\x36\x5c\x6b\x27\x34\xe0\x70\x2d\xcb\xb3\x6e\x0f\x37\x47\x06\xcd\x0f\x40\xe1\x94\x83\x1c\xfb\x26\x0b\x33\xd8\x3d\x44\x1f\x84\xab\x59\x07\xe2\x29\x0d\x8f\x5d\x03\xe8\x03\x20\xf2\xf7\x02\xd5\xbb\xe2\x36\x65\x58\x2b\xd4\x38\x62\xca\x63\x35\x2b\x42\x59\x86\x5d\xb8\xfa\x41\x34\x61\xda\xe9\x2f\x4b\x88\xe3\xe5\x8d\x7f\x4c\x85\x43\x87\xb9\x85\x1a\xc7\x2b\xd1\xed\x08\x31\x0e\x9f\x44\x56\xa9\x3d\x8c\x35\xc0\xc8\x43\x85\x6a\xdf\x2e\x2b\xcf\x63\xc0\xa1\xac\xa8\x85\xef\xcf\xb2\xe4\x3a\xb8\x53\xff\xc4\x20\xcc\xb2\x89\x73\xd4\xdf\x26\xd0\xb1\xe6\x71\xe2\x62\x4b\xe1\x44\x1b\xfb\x71\xf1\x89\xda\xd3\xdf\xa9\x6f\x30\xa4\x38\x56\x5d\x4f\x37\xfd\x26\x43\xa7\x86\x42\x27\xe5\xf2\x1c\xa0\xe3\xc3\xfe\xa2\x58\x07\xde\x20\x06\x7e\xa0\x44\xc9\x21\x2e\x76\x1c\x45\x5e\x33\x88\x77\x5c\xdb\x79\xdc\xe6\xbd\x90\x47\xce\xfb\x5a\x29\x54\x38\x3c\x7e\x8e\x92\x2f\x05\xa9\xcc\x71\x5c\xc7\x82\xb7\x6c\x5f\xda\x46\x59\xfe\x0a\x59\x0f\xba\x1e\x61\xc3\xc3\x55\xea\x7a\x2f\xe9\x9e\x82\xdc\x4e\xeb\x08\x09\x52\xde\x70\x17\xfe\xb0\xdf\xd9\x71\xf0\xa2\x7d\xb0\x18\x27\xec\xa5\x59\xee\x29\xc8\x80\x1c\x77\x92\x12\x8a\x4d\x80\xa1\xec\x67\x89\xab\x85\x80\x37\xf4\x58\xbe\x28\x10\xc2\xad\xc2\x47\xc9\xb5\x46\xae\xf0\x68\xbe\x5d\xd8\x52\x97\x29\xc4\x9f\x0d\x76\x97\x5f\x59\xcb\x87\x1c\x1a\xac\x18\xd9\x1b\xbc\x3f\xd4\xe5\xb0\x27\x45\x6e\x9b\xdd\xb5\x5b\x95\x5f\xa9\xe9\x83\x28\x4a\x12\xea\x20\xa5\xd5\x24\x90\x05\x69\x42\x2e\xf0\xa0\x9e\xb7\x15\x2f\x65\x3e\x53\x7b\x20\xa8\x2d\xa0\xcb\x2a\xc9\x90\x50\xbb\xc0\x45\x8d\xd4\x01\x24\xde\xc7\xb9\xe5\xbd\xe5\x17\x0c\x79\xbb\x4e\x39\x2f\x07\x8e\x48\x48\xe5\x24\xbb\xd3\x44\x32\x22\xb1\x6c\x91\x8a\x09\x3c\xc7\x49\xfb\x5c\x43\x9b\x0a\x82\x22\x7e\x0f\x63\x0b\x0b\xdf\x3a\x0c\xb5\x7a\x8f\xa0\xcd\xb7\xf7\x42\x9f\x9c\x21\xcf\x3a\x41\x10\x16\xa5\xc6\xe1\x29\x58\x4a\xc7\x80\x8a\x48\xaf\xd7\x97\xa2\x20\x3c\x54\x77\xa5\x87\xfb\x16\xc5\xee\x2b\x44\x41\x62\x09\xf5\xff\x87\x9c\xa5\x51\x63\xd5\xe2\xc7\x51\x74\xd4\x9f\xc9\xe9\x7f\xbc\x2a\x29\x44\x70\x12\xa3\x05\x87\x74\xe7\x4a\x0f\xa8\x21\x15\x07\x3b\xb8\x4c\xe5\x18\xf3\x9f\x1f\x62\xa1\x83\x2b\xe7\xc7\xab\x14\x05\xda\xfd\x7f\x05\x44\x06\x9a\x21\x34\xb2\x78\x74\x58\x8d\x82\x4f\xe6\xdd\x9f\x50\xb7\xc7\xda\xb9\x9b\x68\xa0\x7f\x76\xf8\xb6\x9a\xc8\xc3\x1d\x86\x6f\x04\x1a\xef\x6f\xdf\xcb\xb7\x13\x77\x5c\xc9\xe0\x1d\xa4\xf4\xf7\xca\x47\xcf\xc5\x42\xd6\xd0\x8b\x70\xb5\x10\x1a\xd9\xc7\xdc\xcc\x48\x6c\xa1\x59\x67\xe1\xf4\xb4\x4a\x29\x81\xec\x67\x43\xdf\x63\x18\xc0\x9f\x26\xb3\x16\x54\xe6\x04\xde\x5f\xfb\x20\xbd\x91\x35\x97\x07\x89\x8b\x90\x13\x71\xe6\xe7\xc0\xc2\xc6\xf1\x7a\x6e\xd2\xe5\x76\x7a\x64\x11\x6a\x58\xbe\xbf\x22\x67\xd2\xf5\x5b\x8e\x30\xbc\x57\x66\x16\x3c\x69\x3c\xf0\xdd\x47\x77\x3f\x32\x78\xd1\x77\xed\xe6\x50\x05\xb9\x06\x09\x42\x40\xff\xa9\x87\x5f\x92\x05\x1e\xe8\x0e\x19\x73\xf7\x17\xa3\xba\x11\xcf\x1d\x1f\x17\xb6\x5c\x7a\x64\xde\x30\xb4\x1b\x42\x24\x6a\x00\x20\x2b\xd8\xdf\x05\x08\x91\xb0\xd1\x48\x4b\x3f\x32\xb4\x1c\x32\x24\xcf\x43\x06\x27\x8f\x53\xe8\x09\xb7\xe3\xf4\x52\x67\x1f\x4f\x4a\x2f\x40\xcb\x37\x44\x3e\x7c\x60\x78\xa6\x7d\xd9\x5d\xff\xa6\xb4\x08\xb0\x65\xa2\x1d\xf6\xe8\xef\xd1\x38\x9b\xf6\x41\x3d\x5a\xeb\xcd\xec\xd9\xc7\x24\x6f\xc9\x11\x1e\x62\xdd\xb7\x10\x36\x84\xea\x48\xa0\x4c\x21\x3d\x72\x21\x7d\x42\x22\x26\x6b\x6e\x72\x1d\xd4\xff\xb2\xe9\x10\x82\x08\xb5\x86\xf8\x49\x9d\xa5\xb0\x52\x23\x4f\x1e\x66\x48\x64\xd4\x27\xa8\x06\x9c\x0b\xa5\xa1\x10\x91\xc0\xa0\x91\x52\x2c\x69\xfb\xab\x4e\xb3\xbb\xce\x38\xc3\x10\x2b\x09\xd1\x0f\x0d\x52\xc2\x90\x58\x92\xe2\x8d\xda\x96\x5a\x57\xc7\x0b\xcb\x16\x35\x84\x6b\xff\xdc\x42\x27\x4c\x84\x95\xc8\xc7\xea\xe9\x5f\x4d\xc3\xa1\x7e\x0c\xf5\x41\xaa\x04\xfe\x89\x4f\xe9\x93\x87\x9a\x49\x6e\xee\x92\x2c\x79\x94\x33\x8c\xa3\xf5\xe4\xa5\x7a\x12\x07\x70\x5f\x3d\x28\xf8\x95\x5b\xfa\x65\xf5\x0e\x79\xdb\x81\x8b\x44\x48\xc7\x05\xe1\x7e\xb1\x31\x49\xd6\xf8\x08\x96\x36\xb4\x04\x16\xc8\x4d\x49\xda\xc3\x8e\x61\x13\x57\xf2\x8b\x4b\x10\xd2\x27\xa1\x91\xc2\x01\xd5\xa6\x92\xf2\xd1\xdc\xf0\xe2\x52\xf7\xfb\x4c\x96\xc5\x3d\xdc\xba\x44\x4b\xdb\xba\x1d\x1e\x8f\x14\x24\xad\x18\x03\x54\x49\xbb\x45\x7c\x54\x6d\x56\x88\x8e\x54\xf8\x12\xd8\x30\x81\xbd\xaa\xfb\xdc\x13\x4b\xde\xde\x36\x44\x19\x66\x09\xc3\xcc\x91\xc0\xda\xd7\x1f\xf9\x18\xfa\x5a\xd8\x19\xc6\xa0\x62\xd4\x46\x6e\xea\xfe\x85\xf0\x6d\x6f\x15\x5c\x7b\x40\x07\x08\xa2\xb9\xd5\x5b\x97\x26\x16\x68\xfa\x91\x2e\xdc\x72\x28\x03\xa2\x9f\xaf\xb3\x05\xeb\x49\xc8\x25\x2c\x4e\x97\x23\x52\x6c\x50\xd8\x68\x04\xbd\x9e\xf2\x2d\x87\xc6\x5a\x7a\x97\xfc\xe4\x91\xd3\xe4\xb6\xb2\xfb\xa4\xb5\x0d\x25\x7b\xf6\x33\x05\x8b\x21\xe1\xc2\xf3\x9a\xc1\x87\xd1\xca\xe9\xbd\x08\xdf\xd0\x63\xfc\x48\xd5\x14\xcd\x26\xeb\xa2\xb1\xba\xbe\xb8\xfa\x58\x53\x24\x29\x17\x55\x7c\x89\x40\x94\xeb\x20\xf4\x5a\x72\xfb\xa5\xe8\x75\x81\xf6\xfd\x12\x35\x4c\xe1\xb3\x3f\x21\xb0\x99\x73\x30\xce\xa7\xab\xe3\x3a\x2e\xd1\x33\xb5\x12\x42\x41\x42\xcc\x08\x25\xad\x50\xd9\x72\x33\x63\xd9\x42\xf3\xa5\xf6\xd4\x75\xb1\xbb\x3d\xc7\xd6\xca\x2e\xf5\x97\xe2\xf8\x4e\x74\x2d\x59\x97\xa0\x8f\x99\xfa\x49\xfe\x74\x2b\x0a\x46\xef\x52\x2f\xf4\x7c\xbb\x99\xad\xa9\xff\x2f\x0a\x69\xa0\x92\xca\x24\xfd\x09\xdc\x87\x23\xb4\x58\x71\x27\xae\x8e\xc6\x22\x15\x9f\x29\xc1\xef\x75\xed\xad\xd4\x6b\x27\xe0\xac\x9e\x9a\xb9\x8f\xda\x58\x82\x90\x12\xf2\x09\xe3\xe8\x31\x64\xcc\xf1\xd7\x7e\xe2\xb7\x3f\xce\x35\x2d\x7c\x4f\xa7\x34\x5f\x4e\x1c\x31\x0b\xa3\x22\xbc\xf4\x53\xe2\xa7\x38\x33\x27\x19\x53\xe6\xca\xd0\xba\xdd\x86\x28\xbb\x63\x2a\x6b\x39\x64\xc1\xd3\xca\xdd\x2e\xbd\x19\x98\x9c\x89\x86\x99\x5e\x00\xd4\x98\x6b\xe8\x34\xa1\x2b\x1f\x9a\x34\x40\xec\xb1\xae\x45\x3f\xd7\x1b\xcb\x7d\x6e\xb9\x4f\x56\x17\xa5\x90\x85\xf1\xdc\x61\xd7\x8c\x79\xf9\xb8\xdb\x18\x45\x2a\xb1\x1c\x2a\x8e\xf5\x56\xa2\x39\x83\x6f\x6f\x66\xb2\x77\xec\x90\xca\x0f\x24\x66\x86\x10\xa1\x39\x0a\x13\xa3\x61\x29\xff\xaf\x8f\x8f\x2b\x46\xf1\x42\x66\x86\xc3\xbb\xb1\xbd\x5b\x11\xc7\x1a\x8d\xb3\xe6\xb5\x30\x6b\xd8\xf4\x28\xc0\xd2\x36\x6f\xfd\x03\xb7\xad\xe9\xd1\xe6\xb7\xad\xae\x92\x86\xd9\x25\x8b\xb3\x0f\xa5\x5a\x93\x00\xef\xc9\xde\x66\x28\x4c\xbd\x07\x4c\x78\x95\xba\x52\xda\x85\xd7\xe8\xd3\x76\xc9\x07\x68\x66\x08\x27\xa5\x88\xf6\x72\x6e\xa3\x8e\xd1\x9a\xd0\xd7\x1c\x76\xda\xb2\x8c\xa1\x64\x2d\xba\x6c\xa9\x8c\x7a\x48\x92\x7b\x36\x42\xc7\xc6\x9a\x72\x4d\xd9\x67\x46\xbb\xf6\x3c\x69\xa7\xa5\x9c\xa1\x98\xc3\xa7\xca\xb6\x07\x2f\x1c\x67\xd9\x0d\xe1\x82\x5d\xfe\xe3\xd1\x76\x2e\x84\xe9\xc2\x0e\xef\xbf\x46\x71\x87\x9c\xcd\x93\x81\xf7\x30\x43\xd5\xc3\xcc\x6f\x1a\xef\x26\x6b\x63\x4f\xa4\x4f\x8f\xa6\xa8\x71\xb1\x7a\x74\xec\xb7\x97\x91\x8a\x43\x43\x81\x5f\x9d\xd5\x9a\x4f\x0e\xf8\x75\x1e\x95\x4e\x0b\xce\xd3\x98\x3b\xcf\x4d\x59\x67\x9e\x87\xea\x5d\x79\x33\x3b\x9e\x5c\x27\x99\x4f\x28\xdb\xbc\x3b\x77\x6b\x75\x68\x8f\x4a\x40\xe4\xe2\xf0\x49\x77\x75\x17\x7f\xea\x3a\xbe\x33\x1d\x86\x33\x29\x4a\x23\xe7\x1a\x14\x6f\x56\xe6\x01\x76\x90\x0b\x4e\x13\x25\x68\xea\xaa\xf7\x5a\x42\x38\xfe\xea\x98\x2d\x3f\x1b\x44\x6f\x86\xe8\xbe\x76\x56\xd3\x3d\xa5\x8a\x53\xf2\xa3\x57\x2b\x11\xe1\xbf\x52\x41\x81\xd4\x75\x2c\x9b\xf3\xa4\x4d\x78\x7a\xa2\xcb\x27\xb1\x98\x9e\xa1\x94\xee\x85\xd0\x5b\xd9\x7d\xd0\x9c\xe3\xb1\x1d\x86\x3d\x29\x57\xef\x26\xb7\x6e\x2f\x14\x2f\x07\xc6\x41\xe3\x4c\x51\x05\x95\x30\x9b\x40\x8f\xd5\x1f\xaf\xf4\x1b\x8b\x94\x55\x3d\x64\xb3\xc7\x91\x6d\x71\x33\x07\x8e\x4e\x41\x2f\x85\x62\xdf\x6e\xf1\x71\x80\x35\xd0\xe0\x88\x66\xe7\x9a\x7f\xab\x22\xcf\xed\x66\x9c\x8a\xa8\x6c\x32\xb8\x2e\xcf\xf3\xa6\xa1\x4e\x14\x34\xd7\xa4\xc0\x53\x0f\x49\xfd\x40\x80\xe7\x1f\xad\xa7\x23\x99\xb2\xe6\x3f\x11\xe6\x2e\x93\x95\x3d\x2c\xe9\x61\x76\x68\xf7\x59\xdb\x58\xbb\x5c\xc7\x2a\x23\xd0\x5c\x30\xe3\xc7\x38\x62\x38\x04\xd5\xcc\x52\x41\x07\x4a\x25\xd0\xae\x16\x49\xd1\xba\xc5\xa9\x6a\x89\xae\xe2\x3a\x69\x3b\x5d\x57\x35\xa5\xfe\x09\x06\x77\x4f\x19\x9d\x7c\xe5\xd0\x06\xfa\xa9\x12\xdd\x81\x04\xd0\xc4\xe7\x15\xfa\x3f\xa5\x09\x00\xf5\x4d\xca\x09\xb6\x37\xa6\xa4\x1a\x04\xbc\x15\x1f\xae\x99\x1a\x38\x73\x96\x46\x90\x86\x67\x3b\x26\x8e\x73\x69\x44\x36\x72\xe1\x34\x0c\x6d\x26\x95\x83\x5a\xa1\xcb\xd2\x3c\xfa\xa9\x8e\x34\x71\x95\x62\x9f\x52\x7e\xad\x63\x8e\xbd\x4d\x26\x44\x36\x0f\xb4\x35\x18\xab\x5f\x7a\xd7\x76\x26\x75\xff\x2e\x7a\x01\x15\xc1\xc5\x17\xa6\xcc\x7c\xb8\xcb\xb8\x88\xda\x6c\xe6\x14\x7b\x45\x20\xe8\x11\x01\xb3\x5d\xb1\x56\xf1\x56\xa4\xbf\x73\x1d\xd2\xbb\x02\x58\x15\xc2\x6c\x6e\xdb\x17\x64\xef\xa9\xca\x73\x94\x2c\xd5\x1a\xb4\xa4\x28\x85\x64\xfd\x8d\x68\xd5\x9b\x9d\xa9\x96\xe6\xc7\x04\xd7\xf6\x1a\x31\xc4\x28\xd1\x5f\x6c\xd6\x4f\xc9\x61\x68\xc5\x35\xbb\xb8\xf7\xae\x52\x3f\x31\x26\xc6\x4d\x3d\x33\x70\x73\xf9\xd4\x5a\x3e\xe9\x9e\x8b\xa0\x19\x2a\x7a\xe1\xe3\xcf\xa9\x8b\x0d\xee\x3a\xd2\xf0\x1b\x74\x79\xda\x75\x28\xa3\x23\xde\xc2\x8c\x2d\xe5\x55\xeb\xe7\x07\x97\x07\xad\x94\x2d\xe4\x2e\x87\x62\xd2\xc0\xd1\xab\x0e\x90\x2c\x9f\x42\x3c\x07\xa3\x1f\xac\x77\x73\x0a\xe5\xa9\x9c\xfa\x50\x4d\x8a\x31\x71\xb7\xaf\xa1\x5e\x12\xee\xd1\x13\x4d\x54\x6b\x2b\xec\x31\x86\x0c\x9b\x11\xd1\xfa\x45\x4d\x3a\x58\xaa\x8e\xf0\xd1\x7c\xeb\xd7\x2e\xa6\x3a\x80\x04\x31\x71\xd6\xdc\x69\x3b\x15\x30\xec\xa2\x44\x97\xd4\x5a\x51\x68\xf2\x45\x0b\x77\x69\x7d\x07\xcd\xb0\xd7\x32\x8e\xdf\xe3\x99\xb8\xeb\x67\x8c\x87\x76\xf0\x67\x31\xec\x1e\x01\x6c\xd6\xf8\x1e\xb8\x44\xc7\x31\x99\x2e\x25\xbe\x5b\xdf\x0f\x82\xc3\xa0\x40\xe4\x9a\x32\x52\x80\x76\x21\x22\x37\xd0\x0f\x1f\xc3\x5c\x15\xcf\x96\x7e\xd3\xc9\x26\x8e\x44\x89\x24\xe0\x73\x61\xbc\x44\x0e\x36\x2f\x28\x37\x49\xb6\x54\x88\x20\xb3\xb6\x7c\x35\x11\xa3\x33\xdd\x6b\x4c\x88\x99\x8c\x1c\x91\xcf\xb2\x17\x39\xbc\x0b\x01\xa9\x16\xf4\x90\xae\xce\x5d\x3d\xd0\x38\xe2\x43\x05\x2d\x53\x65\xeb\x26\x64\x69\x4d\x45\xb3\xed\xbe\xe8\xe9\xf7\x8a\x22\x5c\x06\xe9\x78\x1f\x27\xd3\x99\x3c\xfc\xc1\x1a\x89\x0f\xb7\x8f\xb2\x94\xe8\x0e\xdc\xa5\xaf\x26\x86\xd4\x54\xc7\xe5\x70\x95\x76\xd0\x01\x07\x6c\x09\x6d\x23\xdc\xdb\x2c\xab\x0f\xc9\x20\xd8\x53\xd5\x05\x46\x54\x9f\x76\xef\x8d\x34\xce\x44\xea\xee\xac\xd1\x13\x6f\x86\x69\x4d\x45\x65\xb8\x54\x92\x9d\xcf\x3b\xec\x81\x46\x40\x17\x13\x30\xa3\x14\x95\xd9\xfc\x05\x0c\x3d\x24\x9a\xc8\xae\xe0\x2a\x9b\x7b\x2e\x75\x83\xad\xa0\x96\x66\xda\x3c\xd8\x9d\x96\x3d\x6c\xdc\xe8\x7a\x82\x68\x42\x6b\x96\x5c\xd1\x59\x10\x9f\xfb\x96\xbd\x6a\x2a\xd7\xa9\x74\x6a\x6c\x86\x22\x14\x13\x86\xd0\x10\xeb\xe2\x63\x6a\xda\xe8\xd4\xa4\x9d\x10\x6f\x45\x3d\x24\x07\x29\xe8\x31\x51\x14\x3d\x60\xe6\x89\x09\xe3\x50\xa3\x54\x27\x2b\x11\xdf\x9d\xec\x3b\x37\xd3\x90\xe6\x12\x9f\xb5\x55\xfa\x4a\x7d\xe4\x37\xe3\xd3\x5f\xd5\x99\x45\x2b\x73\x7a\xcf\xb7\xb8\x53\x92\xac\x5a\x44\xd4\xa5\xe5\xdc\x13\xb5\x96\xa0\x5f\xe0\xfb\x5b\xb6\x2b\xd0\x62\xc4\x33\xcb\xf4\xbc\x0e\xae\x94\x43\x4c\xcb\x5e\x58\xe8\x34\x70\x24\x0d\xc9\x07\x45\xd2\x4b\x54\x5a\x3a\x19\x65\x01\xc7\x66\x89\x1b\x7b\x6b\x2b\xf1\x27\xbb\x3f\x14\x57\xaa\x57\xe6\x47\xc9\x31\x75\xa1\x66\x85\x48\x3a\xfe\x0e\x68\xcb\xfe\xa1\xac\x94\x57\xd5\x8f\xae\xa6\xa4\x13\x76\xf3\x96\x5c\x2a\xe3\x1a\x3f\x78\xfc\x12\x1f\xb7\x59\x1d\xaf\x34\xdf\x1f\x31\xb3\x33\x33\x7a\xd2\xec\xe2\x98\x5f\x2e\xb5\xf4\x52\x46\x2f\x24\x40\xa9\x72\xa4\x06\x63\x9a\x3c\xbb\xcc\xde\xc4\xa6\x13\x4e\x5b\xc7\xf7\xdf\x88\x8d\xf4\xa0\xb8\xd2\x7f\x6e\x1d\xc0\x82\x1b\x35\xfd\x60\x0f\xef\x15\x94\x07\xff\x69\xf0\x70\x6b\xc9\x8c\x0d\x22\x23\x98\xe1\xcf\x8d\x06\x49\x12\x64\xff\x23\x65\xcf\x0a\x48\x2f\x3d\x3f\xc2\xa5\xac\x1f\x60\x55\xf5\xa0\x2c\x19\x34\x5e\x35\xde\x96\xe0\x0a\x3f\x58\xd3\xa6\xfe\xda\x00\x06\xf1\x70\x23\x96\xf9\x94\xd9\xac\x24\x08\x5d\x13\x76\x3a\x54\x68\x72\x10\xa9\x97\x4f\xd5\x76\xb2\xd6\x17\xc2\x3f\x78\xc8\xfd\x24\x59\xa7\xbe\x41\xcd\x20\x5d\xac\xea\xa5\xef\x2f\x39\xaf\x60\x2e\x37\xf5\x1f\x02\x51\x6a\x99\x41\x1c\xca\xf3\x14\xfe\x53\x80\xdd\x1d\x70\x3f\xbf\x69\x42\x40\x59\x5a\x51\x47\x9d\x7f\x6b\x58\x8a\x71\x31\x3b\xc7\xc3\x60\xcd\xdc\x49\xba\xd2\x48\x76\x2a\xa3\x58\xd2\xc9\xc5\x17\xdd\xc0\x10\xdd\x6a\x4f\xa6\xdf\xfc\xf8\xfb\xaf\xe0\x14\x0a\xdf\xac\xa5\xfe\xdf\xff\xef\xff\xf9\xff\x03\x00\x00\xff\xff\x71\x1d\x08\x34\x38\x36\x05\x00") - -func dataEnglishJsonBytes() ([]byte, error) { - return bindataRead( - _dataEnglishJson, - "data/English.json", - ) -} - -func dataEnglishJson() (*asset, error) { - bytes, err := dataEnglishJsonBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "data/English.json", size: 341560, mode: os.FileMode(420), modTime: time.Unix(1452717629, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _dataFemalenamesJson = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x6c\xbd\x4b\xb2\xab\xbc\xd3\xe5\xdd\x7f\x47\xf1\xc6\xbf\xfd\x8d\xe0\x1b\x43\xcd\xa0\xa2\x1a\x32\xc8\x20\x5b\x80\x0f\x17\xef\x83\x2b\x6a\xee\xa5\x14\xde\xe4\x6f\x71\x2a\xe2\x69\x1c\x1e\x6f\x63\x90\x52\x79\x5d\xb9\xf2\x7f\xff\xd7\x7f\xff\xf7\x7f\xfe\x47\x5a\xd6\xff\xfc\xff\xff\xfd\x3f\xcb\xbf\xcb\xd5\x10\xe6\xfd\x3f\xff\xdf\xf1\xef\x57\x58\xe7\xd4\xa4\xf0\x7b\x9d\xd3\xd8\x9e\x17\xb7\x30\x97\xff\xce\xcb\x98\xd3\x27\xdc\xe2\xda\xff\xfe\x8f\x47\x1c\xc7\x74\x8f\xf3\xef\x75\xb9\xb1\xdf\x69\xd9\x96\x30\xe2\x93\x2e\xcc\x71\xfd\xbd\x6e\xa7\x79\x5a\xfb\xdd\x7f\x75\x39\xbf\x37\x86\xb1\x39\x3f\x78\x96\x2f\x9d\x37\x29\x3f\xbd\x9e\x9f\xf4\x31\xfb\x27\xe5\x97\x5a\x7f\xce\x76\x1a\xc7\xf3\xa2\x09\xf3\x94\x7f\x2f\xe6\xcd\x1f\x7e\xe9\xcb\x27\xfe\x80\xa9\x29\x77\xcc\xf1\x7c\xa2\xb0\xf9\x0d\x97\xb2\x08\xe7\xf7\x9e\x69\xb8\xc5\x39\x9f\x0f\xd2\xc6\xdb\x84\x8f\x1f\x71\x59\x52\xe3\x5f\xed\xd3\x9c\xe3\xf9\xc7\xcd\x3e\xae\xbd\xaf\x51\x18\xbb\x98\xcf\xab\xa1\x2c\xf0\xe2\x0b\x71\x2b\xaf\xee\x7b\x11\x86\xdd\xbf\xe5\xaf\x37\xc7\x5b\x6c\xfc\xe7\xde\x69\xee\xd2\xe8\x3f\xf0\x0c\x6b\x9f\xa3\x2f\xd4\x2b\x0c\xfc\xc1\x30\xaf\x7d\xc0\x8b\xcc\xf8\xb9\x80\x1f\x5f\xd6\xf8\xea\xc3\x98\xa2\xac\xea\x7e\xde\xb6\xe9\xe7\x22\x61\x69\x8c\x94\x84\xf3\xe2\x11\x46\xdf\xf9\xa6\x3c\x51\x9c\xf1\xa7\xf7\xb9\x6c\x78\x5c\xf0\x72\xe7\xf7\xa6\xbd\x39\xff\xac\x4d\xc1\xbf\x13\x72\xf2\x4f\x1e\x5b\xf6\xdf\xea\x63\xbd\xff\xef\xe5\x1a\xe7\xb8\x40\x30\xca\x63\xfe\x5e\x74\x79\x82\xb4\xc6\x77\xc4\xfb\x3c\x62\xc0\xbb\xc5\x79\xcf\x2e\x27\xb9\x9d\x63\xcb\xf5\x95\xb7\x79\x4c\xfe\xcd\xb0\xf4\xd8\xfa\xc7\xd6\x26\x97\xbe\x79\x5a\xb8\x3e\x78\x9d\x67\x11\xc3\xf3\x4b\xe5\x83\x29\xe3\x4d\xdb\xfd\xba\xe4\xb2\xd5\xe7\xa7\xf6\x54\x78\xf1\x5b\x79\x3d\x11\xd9\x31\xf9\xcf\xaf\x61\x70\xd9\x4a\x45\xe8\x64\xe3\xce\x03\x51\x56\xeb\x7c\xf8\x60\x87\x85\x7b\x8d\xb5\xb3\xa3\x18\xe5\xa9\x66\xff\x30\x4f\x1b\x7e\x79\x81\x72\x29\xfb\x8e\xdf\x6d\xfe\x6c\xe5\x30\xf8\xff\xf9\xa1\x34\xde\xca\xf9\x4e\xb2\xfd\x7e\x1c\xb6\x9b\x2b\x95\xc9\x37\x9b\x0b\xf5\xea\xf7\x9c\xfd\xa3\x71\x9a\x07\xff\x2c\x6c\x7e\x3c\x4c\xe4\xf8\x7c\xfe\x9b\x39\x95\x3b\xf8\x46\xc7\x22\x15\xbb\xef\xec\x2d\xf9\x79\x8b\x5d\xe7\x5b\x36\xef\xcb\x1a\xb2\x0b\x60\x68\xf7\xf3\x31\xe6\xb4\xfa\x0f\x87\x1f\x17\x3f\x79\xd9\x7b\xd9\x86\x38\xba\xb0\xac\x65\x2b\xce\xfb\xc7\xd6\x1f\x77\x4d\xf7\x7b\x18\x77\x9c\xd7\xc1\xb5\x40\x11\x3e\xd7\x8f\x45\xe1\x9f\x7f\xd6\x95\xdb\xf9\x9a\x47\x7c\xf2\x4e\xcd\x2a\xe7\x85\xc2\x5c\x54\xa2\xeb\xbb\x38\xbb\x75\x59\xf6\xfc\xf6\xef\x3c\x8a\xcc\xbf\x7a\xec\x6a\x91\xd2\x3c\x40\x55\x96\x35\x76\x8d\x5c\xee\x94\x7c\x2f\xe2\x0a\x89\x33\x45\xed\x8b\x9f\x83\x2a\x9e\xc7\x34\x8b\xa2\xe2\x55\xd1\xf9\x79\x5a\x57\xff\xf3\x69\x84\xb2\x8e\x0b\x75\x87\xc9\x02\xee\x1c\x07\x7f\xd4\xc7\x56\x8e\xec\x0a\xd9\xc0\xc5\xdc\x4f\x90\xd5\x3e\x7c\xfc\xb9\x83\x59\x0e\xd7\x38\xd4\xbc\x37\x7f\xc8\xf0\x2a\xe7\xe9\x94\xb4\xb8\x40\xbb\x35\x19\x27\x26\x6f\x4d\x82\xc5\x7a\x84\x21\x89\x1a\xc2\xa3\xe7\xa2\xcf\xa6\xf3\x97\xdf\x21\x47\x2c\x4a\x6b\x8a\x1d\x37\x1a\x62\x07\x1d\x96\xe9\x1d\x2c\xdb\x87\xf7\x3d\x8c\xe6\x79\xd9\x05\x7f\xee\xf2\xa2\x34\x2d\x65\xd9\xa1\x57\x8a\x32\x92\x75\x7f\x94\xf7\x38\x9f\x75\xf6\xd3\xd3\xc5\x39\xe4\x16\x7b\x60\x56\xd9\x77\xbe\xa1\xc6\xab\x6f\x0c\x65\x35\x53\x2a\x8a\x7a\x82\xaf\x00\xfd\x3a\xc7\x0e\x9a\xa1\xfc\x76\x03\x9d\x59\x5d\x23\x5f\xa6\xc9\xce\xde\x82\x17\xa4\xd6\x0e\x5b\xd1\x7a\xe7\x6d\xf7\xf7\x84\x65\xb2\x25\x83\xcc\x3d\x36\xb5\x93\x2e\xf2\x2d\xf4\x4d\xd1\x14\x0d\x2c\x3e\x0c\xfe\x18\xcf\xaf\xa7\x16\x96\xff\x0d\x8d\x54\x94\x50\xd9\x00\x97\xc2\x09\xef\x7c\x2b\xaa\x66\x85\x6e\x30\x8f\x80\xba\xad\xbc\xe5\xea\x5f\xdd\xa7\x4c\xdd\x6b\x96\x91\x2f\x63\x3b\xe2\xdf\x2d\xda\x1e\x17\x66\xa0\x7c\xb7\xde\xe5\x8b\xf0\x6e\x02\x4f\xfe\x06\x51\x5d\xfc\x0e\xea\x6b\x52\xf2\x8a\x3a\x7a\x26\x9c\x71\x57\x14\x2b\x4e\x88\x19\x59\x3a\xbb\x45\xa1\xc0\x17\x2a\xbe\x81\x9b\xb4\x22\x6a\xeb\xbc\xb5\x11\x87\xcb\x8d\xe9\x34\xee\x70\x82\xb3\xec\x91\x6f\xfa\x4f\xc2\x2b\x51\xac\x9e\x87\xa5\xf6\x37\x59\xf0\x8e\x63\x28\x26\x01\x87\xbf\x1b\x5d\xc6\xca\x39\x09\xa2\xba\x70\x86\x6e\x72\x97\x36\x8a\x70\x9a\x27\x89\x4d\x7b\xc5\xf2\xdd\xf3\x17\xe4\x36\x83\x9d\x28\x1c\xa9\x22\x28\xb8\x0c\x66\x28\x5d\x3e\x8b\xa7\x80\xd5\x2d\xee\x99\xaf\xde\x54\xfc\xce\x00\x9b\x55\x96\x06\x66\xaa\xda\x4b\x6a\xb1\xe2\x0b\xf9\x7d\x42\xd9\x4b\x9e\x08\x28\x1c\x93\x53\x8f\x0c\x22\xef\x32\x24\x1a\xc6\x41\x5f\xab\xd8\x8e\xd6\xf7\x36\xd3\x91\xce\x3b\x7e\xfb\x9d\xa6\x8c\xc7\xde\xe6\x75\xf4\x0d\xad\xe1\x8c\xeb\x8d\x95\x5b\x5f\x1d\x60\x68\x98\xe2\x5a\x62\x61\x44\x4c\xf1\x8c\xeb\xca\xab\xbf\xf8\x7e\x82\x13\x32\x94\x20\x8b\xde\xd5\xe2\x8a\x74\xd8\xe7\x15\x41\x4a\x44\x9c\x53\xfd\x41\xb8\x78\x8c\x12\x4a\x94\xb7\x78\xe4\x54\x5c\x58\x97\x53\xb3\xf2\x93\xb8\xbe\x5c\xd6\x11\xaf\x65\x31\x1c\x3e\x49\x8c\xb1\x16\x8d\xc0\x8a\xbd\xe9\x5d\xf8\xc6\x11\xf1\x9c\x47\x9e\xe5\x79\xcd\x80\x21\xf0\x9b\x86\x24\xeb\x7b\xfe\xd8\x94\x3b\xd7\xcb\x22\x4b\xe6\xa3\x8d\xe2\x0e\xf9\xfe\xe5\x38\x8d\x81\xef\x75\x7e\x72\x8f\x6a\xd6\x26\x84\x4c\x43\x2a\xbb\x3e\xf8\x11\xc4\xa1\x2e\xa1\xd6\xd3\xd5\xe8\x44\xa3\x6d\x82\xe4\x41\xce\xf3\xe2\x9b\x17\x0d\x92\xfc\xfe\xd8\xa6\x21\xb8\x33\xdc\xd3\xf1\x6f\x43\xf2\x1d\x9b\xc3\x80\x37\xa9\x2e\x56\x82\xcd\x7a\xd2\xdb\x9e\xb9\x2f\xc5\x35\x9a\x71\x08\xc7\x76\xc1\xea\xd8\x65\xc0\x11\x1e\xe1\x91\x74\x5b\x68\x43\xde\x5e\x50\x37\xa2\x51\x8e\x78\x1e\x5e\xcf\x22\x51\x52\x03\xb1\xb9\x87\xdd\xb5\x5b\x1b\xa8\xf7\x20\xd8\x4b\xb8\xf1\xc9\xd3\x72\x39\x03\xdd\x56\x5e\xd4\xcd\x4e\x2f\x47\xa9\xaf\x4e\xde\xb9\xfa\x03\xad\x5d\x13\x8b\x90\xa5\x8b\x2e\x3e\xdf\xaa\xc4\x9e\xae\x27\x6e\xc5\xd2\x15\x87\xc6\x1f\x09\xfe\x6f\x31\x25\x17\xef\xca\x9f\x15\x41\x65\xdc\xc4\x29\x18\x71\x60\xca\x61\xff\xb8\x0e\x92\xb5\x6c\x25\xd6\xb1\x10\x1d\x29\x82\x2c\x96\xbc\x6e\x53\x2a\xe1\x9c\xbf\xec\x98\xfe\x6c\x78\x34\x7f\x9f\x07\xcd\x7a\x39\x79\x99\x02\xbf\x43\xff\x8e\x17\xb9\x85\xf7\x5c\x9e\xd3\xdf\xe7\x1e\x2e\x2a\x77\x87\xcf\x35\xbd\x3c\xb4\x09\x62\x36\xf6\x37\x3d\x86\xf2\x76\x93\xaf\x6b\xde\xce\x45\x59\x36\x2c\x71\x51\xae\x88\x1c\x2c\xec\x09\x72\x50\x5c\x8e\x9f\xb3\x1e\x28\x78\xc1\x19\xc1\x5c\x86\xa2\x2f\x76\x75\xc4\xa1\x2e\x7f\xd5\xfb\x96\xad\x53\x12\x0f\xc7\xd6\x40\xb2\x0d\x61\x14\x6f\x48\xfe\xf8\xe5\x9a\xc3\xe2\xf8\x73\x2b\x7e\xfa\x44\xcb\x52\x64\xbd\xed\xa0\x2e\xe8\xc0\x34\xdc\xfd\x1c\xd6\x69\xa7\x1a\xf7\x37\xb5\x65\xf0\x3f\xec\xca\xf6\xd2\x1b\xc0\xcb\x26\x28\x2d\x73\x84\xa9\x71\x5c\x8f\x1c\xc6\x6e\x84\xbc\xcc\xb4\xd0\x16\x8f\xbb\x91\x88\xb0\x56\xf5\xd4\xd0\x40\xc1\x0a\xac\xd4\xb2\xe5\xe9\x65\xcf\xe0\xa6\xfd\x0d\xe2\x2e\x77\xa6\x9e\xf1\xf1\x0d\xd9\x85\xb6\x9c\x74\xfc\xb1\x85\xb2\x74\x9f\x72\xfc\x2b\x96\xe8\x36\x4f\xd3\x53\x1c\x4a\x78\xbe\x4b\x68\xe9\x6c\x16\xa1\x68\xb9\x99\x66\x4d\x12\x0e\x96\x8b\x5c\xe4\x4f\x94\x13\xdf\xc3\x56\x59\x72\x24\x50\x77\xdd\xfc\xb3\xf2\x13\x51\xf3\x64\xe6\x3d\x53\xcf\x35\xdc\xba\x48\x03\xff\xd4\xec\xc1\xb1\x4a\x23\xf4\x29\x03\xa5\xb2\x7b\x6e\x21\xaa\xe7\xa2\x16\x53\x12\x1e\xe2\xcf\xd3\xe0\xc3\xe8\x14\xff\x26\x4a\x02\x21\x4a\x8a\xaf\x8d\x4b\xb1\x34\x91\xa7\x68\xa4\x87\x37\x26\x04\x4e\xf0\x45\xbe\x59\x2c\x24\x03\x23\x14\x63\x9c\x25\xcd\x50\x04\x50\xb6\x07\xd2\xdb\x5c\x0c\x6e\xe4\xc9\x8f\xa9\xeb\xfd\x9e\x5d\x0f\x9f\x6e\x7a\x21\x1b\x1b\x2d\x63\x04\xc9\xd2\x8c\x70\x57\xc2\xa2\xf2\x7f\x46\x18\x16\x1e\xc0\x39\xd8\x11\x39\x2d\x52\x1c\xcd\x22\x21\x45\x90\x77\x04\x3f\x0f\xe8\x10\xf3\xc0\x5c\x9f\x60\x6b\x2e\x89\xf9\x60\x5a\x4b\xf4\x23\x32\x78\xb4\xa4\x89\x39\x97\x58\x2e\x90\x19\xe7\x13\x17\x67\x21\x52\xb3\x24\xc8\x00\xe5\x4e\xbc\xee\xa2\xd6\x1f\xfe\x4c\x48\xd0\x64\xbc\x52\x4b\x7d\x36\x30\xc1\x24\x41\xcb\x40\x03\x5b\x7f\x94\x61\xa0\xa4\x8d\xee\xe9\xa2\x74\x19\x07\xcc\x0c\x50\xdb\xf4\x97\x06\x00\x2b\x68\xd9\x6e\x78\x25\x14\x2c\xe4\xc4\x1f\x53\xcf\xf3\x61\x55\x02\x38\xa5\x03\x33\x2e\x25\x1c\x4a\xf8\xbb\x1f\x88\x1f\x0b\x1a\xf1\x36\x49\xb0\x7d\x3b\x3f\xc1\x59\x33\xc9\x4e\xb8\xf3\x2d\x21\x7d\x32\x71\x07\x7e\xd2\x98\xee\x4c\x41\xeb\x09\xb2\x63\x89\xac\x65\x79\x10\xbf\x4f\x48\x83\x9f\x51\xee\x71\xd1\xda\x23\xd7\x89\xe1\xf4\x40\x83\xaa\x4e\x5b\x79\x31\xb8\x80\x2f\xcd\x97\xcc\x4c\x83\x1d\x3e\x2b\xfc\xc0\x96\x67\xbe\x18\x10\x86\x52\x16\xcb\xba\xbe\xb0\x20\x9b\xdf\x9c\x99\x95\x6d\x68\xc2\xca\xa2\x31\x05\x55\x8e\xa7\xa9\x3e\x17\x9b\x1f\x3f\x9f\x0d\x33\xcf\x2d\x72\x58\x56\x4f\x79\xba\x3b\x60\x02\x44\xe1\x9a\x66\xa4\x9c\xe2\xfd\x8e\x2d\xe3\xb2\x97\xbb\xc0\xb3\xe5\xee\x95\x70\x7b\xa2\x85\x64\x80\x45\x7d\x61\x59\x4a\x38\x6f\xf4\xf8\xcb\x2f\x61\x0f\xc6\xf4\x7c\x5e\x54\x7d\xd0\x95\x5d\x1a\x1e\xa5\xa4\xe6\x4d\xe4\x06\x1a\xca\x0c\x88\x17\xde\x2c\x63\x04\xf7\xc5\xea\x02\xac\x95\x95\xb8\xb9\xf5\xe4\x43\x4d\xd2\x41\x13\x32\x2e\xbf\x17\x1d\x06\xd5\x84\xd0\xbb\xfc\x1c\xcc\x57\x39\xff\xfe\x73\x89\xce\x1a\x97\xa5\x1e\x33\x26\x89\x02\x12\x62\x4d\x39\xe1\xd9\xdf\x21\x8d\x5d\x71\xba\xce\xab\x37\x4c\x45\xf1\xa9\xd3\x25\x8e\x76\xed\x3c\xe5\x96\x8b\x84\x14\x51\x51\xd6\x2c\x7e\x1e\x25\x17\x48\xf1\x88\xcd\xc4\xf1\x7a\x5c\x13\x68\x92\x5e\x6a\xa8\x13\x2d\x8f\x52\x8c\xca\x44\x85\xf3\x84\x5f\xb4\x50\x62\x8e\x3a\xa4\x1c\x0c\x57\xef\x8c\x88\x5a\xd1\xa5\xe5\x50\x64\x57\x8a\xbe\xc5\x5a\xe1\x38\xea\xb5\x11\xea\xca\xbf\x65\x79\x33\x28\xf8\x57\x2c\x52\xf7\xb9\x68\x05\x97\xab\xa3\x7a\x1a\xe1\xc6\x52\xdd\xf6\xe2\xf2\x34\x25\x82\x77\x35\x10\xef\x8c\x67\xcc\xf1\x9b\xd3\xe4\x2a\x52\xbc\x0d\x78\x58\xa2\x3c\x19\xd2\x06\x2a\xe9\x22\xc3\x3c\x09\x08\x3e\x6b\x1d\x9b\x79\x37\x6c\x5e\xfd\x4c\xb4\xbe\x87\x0d\x16\x77\x7a\xf0\x57\xe3\x59\x66\x6e\x16\x96\x06\xa7\x86\xde\xf5\x2b\xa4\x0e\x01\xdd\x78\xa9\xbb\xf1\x2e\x78\xed\x36\xbc\x7a\x56\x48\x5d\x32\x4c\x2b\x78\x55\x23\xae\x2e\x25\x5d\x55\x01\x7e\x8f\x34\x4c\x1d\xeb\x7f\x13\xcf\xee\x33\x52\xef\x64\x66\x5a\x2c\xc3\x06\x8f\xc6\x62\x79\xdc\xf5\x09\x1d\xbd\xcd\x0b\x5d\xb3\xf4\xf9\x40\xcb\xa5\x99\x09\x63\x93\x0c\x51\xd2\x52\xe6\xd9\x19\x9e\xec\x52\x3b\xc4\x52\x76\xa2\xe3\x8a\xf3\x02\xbf\xbd\xd6\xc4\xa4\x18\x0e\x79\x38\xe2\x8a\xb1\xf5\xf3\x64\xe9\x0e\xa6\x84\x13\x94\x92\xc9\xf8\x47\x6e\xe4\x98\x03\xab\xd9\x30\x7e\x8c\x22\x9e\xc5\x30\x46\x16\x19\x3b\x79\xcd\x7b\x59\xc7\x96\xee\x16\x8f\xcd\x06\x93\xfd\x6f\x7e\x55\x43\x58\x45\x01\x1c\x3f\x73\xdd\xaf\x0c\x23\xb5\x6e\x83\x27\x05\xca\xb7\x83\xd6\xb8\xa1\x12\xab\x79\x76\x81\xbc\xe8\x51\x0f\x9f\x36\x89\x7b\x98\x55\xcb\x1b\x6d\x96\xe5\x7a\x04\x28\x52\xfc\x47\x26\x38\x96\xa9\xd8\x8a\x79\xc2\x9f\xd3\xef\xb7\x6f\xe3\xb3\xb7\xbb\x11\x8d\x98\xe1\x9a\xbc\xe3\x86\xad\x1f\x3c\x0f\x4f\x6e\x96\xba\xc3\xe1\x7b\xd2\x57\xa1\x8c\x4a\x79\x21\xb3\x0c\x99\x83\x80\x52\x7e\x92\xbc\xf1\xb8\x41\x0e\xbb\xe0\x3f\xbe\x70\x9d\x5a\x2a\xf1\x65\xbf\xb9\xa7\x13\x6e\x5e\xf5\x4e\x6f\xe4\x80\xe9\x34\x6a\xe6\xa6\x41\x06\x06\x62\xff\x90\x8c\x40\xd7\x06\xaa\xe3\xe9\x4e\xa9\x19\x62\x60\x9d\x70\x6b\x99\x29\x5e\x99\x63\xce\x2c\xe4\x96\xdd\x1b\x79\x9b\x5b\x62\xfa\x60\x29\x1a\x48\x75\xed\x8e\xc0\x1a\xb9\xba\x0a\x74\xa1\x11\xa5\x6e\x32\xdc\x12\x94\x5c\x2d\x4e\x88\x9a\xc6\x66\x47\xa4\xb0\xbe\x69\x19\x3f\x38\x73\x3f\xb1\x94\x0b\x95\x6d\xfa\xc8\xad\x21\xd4\xf0\x91\x46\xe0\x19\xce\x13\x83\x1e\x2c\x85\xc9\xb9\x2b\x9c\x6d\xed\x91\x5d\x8f\x58\xbf\x72\x02\xe2\xfc\xa6\x1a\x70\x39\x58\xc5\xaf\xce\x11\x51\x43\x5f\x7e\x0a\xb5\x2f\x73\x0d\xcf\xcf\xde\x21\x33\x7c\xbf\xcd\x92\x14\xa8\xca\x0f\xd9\x9e\x12\x10\x48\x52\xd0\x2a\x56\x10\xfb\x37\x9e\x34\x88\xda\x83\x43\x99\x53\xcb\x02\xd1\x4c\x85\xf2\x9b\xb5\x91\x0a\x52\x13\x5f\x0d\x6a\xa3\x6b\x92\x98\x0c\xd0\xad\xd9\x73\xe8\xed\xa4\xc5\xdc\x27\x6c\x84\xc7\x6a\x31\x8f\xe2\x29\x5d\x4a\x17\xe5\x43\xec\xc3\x9b\xba\x65\xa7\x9b\x20\x41\x5e\x89\xd8\x02\xd6\x7e\x89\x0c\xaf\xa8\x87\x82\x46\xd3\xf7\x24\x71\x2d\x12\xa0\x2d\xab\xa5\xa3\x84\xbc\xdf\x7c\xf7\x0a\x55\xc3\x6a\xf7\xab\x18\xed\x3c\xbd\x10\x21\xe7\xd0\x95\x3d\x3d\xdf\x7f\x60\x46\xfc\x16\x05\xca\x50\x64\x0b\xa9\xdb\x0a\x61\x42\x58\x0a\xab\x17\x97\xa1\x96\xe7\x35\x64\xf0\x8f\xdf\x78\x1e\x13\xa0\xf3\xf2\x43\xa5\x36\x04\xa9\x2b\x8c\x92\x66\x2a\xfe\x6e\x7c\x22\x90\xda\xb8\x51\xbd\xe9\x50\x97\x6f\xe6\x7d\x8b\xf3\x03\x5f\xf5\xd7\x94\xf3\x00\x31\xbf\x1e\xa4\x60\x32\x53\x2a\x1f\x22\x1a\x66\x9a\x1d\x45\x61\x18\x03\x94\x04\x18\xa1\xb5\xd4\xaf\xe5\xe5\x2f\x49\xbf\xc3\xf1\xa0\xfa\x88\x03\x8d\x51\x43\xa0\xd1\x07\xce\xc1\x78\x71\x22\x27\xaa\xee\x78\x2d\xec\xe6\xf2\x84\x04\x00\xf1\x53\x6e\xf9\x22\x3e\xb7\xed\x31\x54\x69\x31\xfe\x40\xb0\x65\x49\x11\xe7\xf0\xe4\x9f\xc6\xf6\x47\x2d\x71\xf1\x7a\xd4\xae\xc7\x99\x29\xd4\x5d\x2c\x1b\x3d\xfb\xbf\xe2\xe6\x43\x13\x55\x34\x19\x56\x72\xd4\x58\xca\x9c\xb4\x41\x70\x1f\x41\x80\x18\x89\x4b\x50\x33\x1b\xe7\x1a\x6c\x1f\xb9\xd1\x34\x4b\x32\x75\xc7\x4f\x68\x1a\x96\x8a\xb0\x15\x57\xa1\x4a\xd9\xa8\x6b\x07\xa9\xe3\x53\x6e\xb0\x41\xcf\xb0\x48\x05\x7a\x17\x20\xcf\xfb\xea\x21\x1a\x3c\x50\x8b\x2b\x30\x14\x41\x60\x73\x7b\x89\x4e\x71\x7e\xcd\x4a\x61\x77\xda\x2e\x72\x95\xa1\x88\x5e\x52\x68\x38\xc0\x43\x90\x5d\x7a\xa1\xeb\x47\x9c\xaa\xd3\xd0\x99\x05\x96\xf5\xad\x08\x00\xc5\x80\x62\x69\x16\xf1\xc3\x69\xa1\x8b\xc8\x49\x14\x72\x04\x67\xfe\xd7\x02\xaa\x4a\xed\x4c\xd1\x58\x92\x14\x4f\x90\xae\x8e\xcc\x98\x16\xcb\x07\xd0\x4f\x4c\x33\xee\xd2\xe1\xa0\xdc\x24\x11\x15\xac\xf2\xec\xf5\x1e\xcb\xad\x42\x6e\x4d\x05\x61\x1b\xad\xe6\xee\xe9\x1c\xea\x79\xa9\xf5\x95\x25\x7c\x23\x34\x13\x97\x20\x68\x7a\xb9\x6a\x0d\x37\x61\x13\xf4\x94\x1a\xef\x85\xf9\xbb\x5a\x79\x44\xe9\x9f\x4b\x59\x51\xb5\xd8\xb2\x56\xe2\x14\xcb\xf0\x28\xb0\xef\x8e\x0f\xbb\x0d\x19\x94\xe3\x1c\xc0\xbe\xd2\x1b\x0a\xa6\xff\xa1\xe1\xdf\xf6\x08\x28\xc6\x85\x72\xa3\x85\x70\x0d\x98\x8e\x03\x39\x23\x92\x02\xa5\x5a\x2b\x5d\xd7\x23\x8d\x4d\x96\x4a\x43\x16\xb4\x44\x18\x5e\xc1\x23\x0c\x3b\x61\x62\x92\x90\x39\xa4\x28\xfe\x24\xb5\x85\xbe\xae\x25\x7a\x89\x40\xc2\x6f\x74\x94\xd3\x3f\x47\x3b\xa8\xd0\xd0\xfd\x84\x92\x64\x05\xb3\x9c\xea\x96\x82\xc1\xd5\x06\x88\xec\xd8\x51\xdf\xec\xe6\x89\xbd\x2f\xcb\x91\x2e\x25\xe9\xa8\xb0\x4a\xc4\xcd\x0a\xe9\xa5\x24\x34\x61\xb9\x94\xdf\x0e\x8f\xda\x77\xd4\xde\x71\x0d\x14\x39\x82\x39\x2e\xb0\x39\xa9\x31\x19\xb8\x8c\x99\x40\x45\x65\x1b\x22\x7c\x5c\xa9\xc2\x22\x1e\xb2\x16\xbd\x60\x0b\xa9\x62\x4c\xc9\x0a\xa2\x34\x7b\x2c\x5f\xe1\x6d\xe7\x0e\x44\xc0\x50\x3a\x6e\xf7\x0c\x77\xa3\xdc\xee\xcf\x96\x14\x7b\x87\xa4\x2b\x45\xc6\xfc\x1b\x22\xa0\x6d\x6d\x10\xea\x7e\x91\xf1\x48\x9e\x69\x4a\x33\x4f\x5c\x4a\xab\x91\x27\x16\x46\x7f\x22\x15\xe3\x0e\x13\xff\x83\x20\xc4\x6a\xfa\x97\xc4\xee\xa9\x72\x00\x45\xab\x0e\x39\x14\x8e\x29\x2a\x3a\x5c\x37\x6e\x79\x97\x70\xf0\x82\x38\x94\x6f\x56\x05\x5e\x61\xf4\x52\x20\x0b\x23\xc5\x23\x92\x34\xd7\x9a\xe0\xfe\xb7\x1a\xb2\x59\x54\x48\x97\x48\x94\x00\x02\xac\x12\xbc\xc6\x46\x83\x08\xba\x03\xf9\x1f\xb8\x3c\x12\xd0\x47\xf6\xce\xb7\x34\xce\x03\xbb\x2c\x2c\x08\xf3\x23\x20\x87\x78\x05\x6c\x7e\x6a\xd6\x40\x38\x74\x68\x99\x2d\x46\x8e\xa8\x8b\xea\xc6\x7c\x9b\x53\xa0\xca\x98\x8d\x1f\x05\x37\x64\xe8\xcd\x5e\x8d\xa0\x8b\xe6\x34\x22\x7f\x9c\x8b\x29\xe0\x6e\x58\x83\xc2\xf9\x13\xbd\x64\xe0\xc3\xb8\x96\xa3\x29\x8e\x86\x25\x5a\xfc\x58\x5b\x34\x9c\x5a\xfa\x65\xbe\xae\xdc\xae\x28\xf5\xa8\x56\x6c\x41\x4e\x48\x63\x54\x1f\xe4\x5c\x0f\x62\x57\xac\x06\x05\xdf\x71\xa0\xcf\x69\xa5\x4a\xd4\x30\xbe\xb9\x66\xe4\x06\x97\xc1\x8f\x8f\x45\x68\x0c\x4a\x5a\x38\xfa\x5c\x15\x29\x2c\x17\xd3\x86\x47\xae\x91\x14\xfc\xfa\x81\x79\x9d\x40\x7c\xd8\x3c\x35\x9e\xac\xae\xe7\x18\xf1\x75\xbb\xaf\x0e\x3b\xaa\x21\x17\x2a\xd6\x8b\xc8\x93\x39\x40\x58\xc1\x8e\xe5\xaf\x4c\x79\x7e\x99\x69\x0d\x94\xa0\x10\x99\x2c\xde\xa5\x45\x4a\x5d\x15\x9a\xe4\x0d\xee\x41\xf3\x47\x10\xf1\xb5\xf7\x48\xd4\x28\x6b\x31\x15\xaf\x80\x0c\x38\x53\xd5\x52\xdc\xba\x69\x95\x3d\x2d\xb2\x15\xdf\xe0\x89\x41\x18\x9a\xa2\x5a\x05\xad\xb4\x71\x88\xeb\x4c\x55\x01\x7f\xe1\x11\x2e\x4d\x25\xa6\x00\x80\x4f\x4e\x92\x25\x92\x63\x74\x2f\xa6\xc7\x6f\xb4\x4a\xb6\xf5\x0b\xae\x67\x74\x87\x52\x1d\x1c\xd2\xa2\x75\xad\xdf\xe1\x62\xe1\x21\x9e\xe6\x1a\x48\xf0\xb2\x6a\xe2\x98\x41\x1a\x76\x8c\xf6\xd7\x3a\x09\x10\x3d\x6c\x6d\xd2\xd4\x25\x57\x26\x01\xf6\xd4\x28\x70\x50\x15\x43\x5f\xf4\x4d\x1c\x89\xca\xed\xe3\x44\xc0\x6b\xed\xb2\x62\x0b\x84\x65\x57\x89\x6a\x57\x47\x32\x4b\x13\xc8\x4d\xb7\x70\xa4\x5d\x6d\xf9\xc8\x56\x89\x75\xac\x5e\x51\x1d\x2e\x5a\xcc\xac\x32\x22\x79\x43\x56\x0c\xc1\x27\x0e\xb3\xa6\xbc\xac\xb4\x82\xde\x9c\xcd\x0a\xfd\xf3\x20\x82\x37\x41\xb7\x1c\xc5\x65\x0d\xea\xe9\xe4\x49\x10\x93\x27\x56\xac\x8b\x32\x45\x75\xa9\x57\x50\x73\xa8\xf2\x0f\x03\x86\x65\x0e\x9d\xa4\x98\x8a\x5f\xda\x06\x77\xfc\x92\x65\x6b\x7d\x8f\xd2\x5b\x23\x63\x05\xe3\x57\x43\x7f\xae\x52\xa4\x49\x16\x1c\x82\x28\xe8\x35\x0a\x18\x38\xb1\xab\x22\x6f\x4d\x39\x31\x04\x97\x30\x3b\x62\x25\xc7\x1e\x9b\xca\xea\x50\x10\xb3\x7c\xd4\x79\x7c\x03\xb5\xcb\x62\xe9\xf9\xcd\x57\x91\x4b\xe6\xa3\xd1\x78\x64\xb6\x0d\x4d\x54\x2d\xdc\xd7\xd5\xa2\xe2\xf3\x6a\x1a\xf8\x5b\x2d\x9f\x6a\xa4\x71\x00\x76\x92\x69\xe8\x39\xdc\x83\x24\x39\x76\x58\x1f\xba\xcc\xe5\x3b\xbc\xf9\x9b\x87\xcd\x9a\x6a\xfc\x0d\xc5\xd6\xd1\xcd\xe6\xc6\x2c\x45\xbb\x13\x20\x32\x73\xeb\x8f\xf4\x3b\xf4\x88\xb8\xbb\xef\x48\xe8\x9d\x24\xff\xec\x80\x51\x43\xa0\x81\xce\x8a\x71\x90\x12\x4b\xbe\xf9\x87\x35\x15\xe6\x1a\x5b\x92\x6d\xcd\x25\x65\x63\xb9\xf9\x73\x5d\x27\x37\x0f\x87\x8b\x85\x23\xed\x26\x41\x4e\xc4\x01\x16\xe4\x8a\x0f\x1e\x21\x48\x3a\x4a\xce\x55\xf5\x0c\xa4\x13\x14\x10\x13\x39\x38\xe2\xe9\x1d\xf0\xce\xe0\x0f\x0c\xcf\x59\xb2\xf7\x51\x6c\xf4\x26\x2d\x34\xcf\x9d\x4e\xc2\x81\x2f\x38\xdf\xf4\x65\x59\x7a\x28\x87\x99\xf0\x3f\x3e\xf2\xd1\xd1\xe7\xa6\x25\x28\x88\x8f\xbf\x1f\x27\x38\xea\xb3\xe8\xfd\x07\xd7\xeb\x48\x44\xf2\xac\xb1\xac\x5f\x8e\x06\x83\x24\x48\x7d\x2d\xca\x75\x3c\x11\x2b\x7d\x30\x96\x07\x33\xa2\xdd\x9a\xe6\xf7\xe7\x97\xe2\x6b\x9a\x89\x38\xa3\xee\x78\xc7\x71\x3b\x77\xea\x00\xee\xfb\xaf\x35\x02\xfe\x3d\xde\x27\x49\x94\x52\x74\x0d\x01\xd9\xa3\xe2\x16\x8b\xfe\xd0\x76\x21\x6d\x6f\x5b\x80\x54\x64\xff\xab\xc9\xa0\xaf\xbe\xe1\xf4\x20\x33\x4f\xdd\xe0\xc7\x36\x76\xbe\xa3\xfb\x82\x2c\xfe\x8e\x0a\x5d\x90\xda\x4d\xc5\xb9\x68\x59\x13\xe7\x41\xa0\x19\xf7\x94\xa7\x01\xbe\xc1\xa7\xfc\x3b\xb1\x6a\x75\xd4\x0a\xc4\x3f\x81\xdd\x78\x03\x93\xbf\x31\x9f\xc5\xc7\x79\x5d\x4a\x40\x47\x97\x25\xd3\x94\x4c\xf5\x5a\x24\x7a\xbe\xb1\x98\xa1\xa8\xfd\xbf\x52\x46\x6a\x43\x35\x7e\xd4\x1b\x52\x75\xbe\x31\xb5\x39\x86\xa7\x00\xfb\x98\xc1\xae\xe9\x54\x44\x84\x9a\xca\x45\xe1\xa8\x15\xc8\x61\x2b\x5d\x9c\xd6\x7c\x4f\x7f\x6b\x95\xac\xca\xc4\x8c\xed\x37\x2d\x0e\x9d\xc1\x4a\x96\xa9\x4a\xd9\x9f\x5a\x5e\xe6\x59\x65\x31\xaa\x9d\xde\x8c\x19\x06\xc9\xae\x0e\x40\xf6\x7f\x1b\xa4\x4f\x99\x40\x8a\x7a\x25\x44\x73\x60\x11\xde\x92\xa0\x2b\xb3\xa0\x56\xbb\xbf\x68\x56\xff\x62\x43\xcb\x56\x02\x47\x7a\x4f\xd1\x0b\xb1\x97\xb4\x64\xf6\x96\xe6\xc7\xd4\x8f\x92\x33\x84\x73\xc2\x44\x8f\x99\xbc\xc8\x96\xf7\x27\xb2\xc8\xd2\xcd\xdb\x5f\x8c\xcb\x1e\x5a\x58\xd9\x57\x9c\xa5\xb8\xda\xb1\x61\xb9\x42\x92\x05\xbb\xd3\x13\xa0\x3f\x4c\x1f\xe9\x81\x35\xf7\xd0\x7b\x0f\x25\x1d\x51\x34\x41\x7b\xcd\x7e\x8a\xab\x95\x24\xff\xb3\x0a\x9e\x2c\x07\xf9\xf0\xdb\x38\x37\xaa\xa7\xe0\x8f\x18\xd0\x10\x6d\x7d\x5b\xb1\x0b\x33\x8e\x6e\x11\x7b\xaa\x89\x2f\x4d\x03\xce\x65\x27\x29\x49\x07\xa5\xfc\x42\x3e\x60\x5d\xd8\x63\x0a\xaf\x68\xbe\x10\x63\x4c\xcc\xa9\x1c\x72\x78\xee\xaa\xf4\x1d\x04\xeb\xcb\x56\x27\x07\x66\xa8\xc8\x39\x96\x68\x22\xa0\x31\x5e\x52\x91\x33\x0b\x40\x70\x8e\xca\xaf\x11\x16\xbc\xc6\xcb\x42\xc4\x91\xfe\xd2\x4d\xb0\xf2\x45\xb7\xa8\xd7\xdd\x48\x10\x2a\xc9\xad\x56\xe3\x44\x96\x16\x0f\x0e\x11\xc2\x5c\xc5\xb9\xbf\x91\xa3\xa4\xd8\xb1\xb8\xfc\x03\x30\x72\x17\x0e\x39\x86\x38\x4e\x6f\x04\x8e\x4d\x2e\x61\xed\xb8\xa6\x4b\xd7\xc3\x8d\x5e\x1c\xb0\xdc\xf5\xea\x1f\x09\x1b\xa9\x9e\x99\x2e\x6a\x82\xd7\xa6\x25\x77\xbc\x02\x62\x55\x5e\x5a\x8b\x0f\xde\xe7\x62\xea\xef\xfc\x77\x24\xf7\xc9\x9b\xd0\xd4\x37\x0f\x67\xcd\xd5\xfb\xae\x5a\xd5\x2a\x09\x42\x52\x4e\x6a\x09\xcb\x47\xd2\xad\x80\x6d\xa5\x91\x22\xac\x96\x0a\x44\x52\xad\x71\x12\x0e\xeb\x85\xf5\xa6\xb6\xbd\x5e\x0a\x89\x0a\x98\x12\x0f\xba\xb6\x5a\xfb\xda\xfc\x40\x28\xc7\x48\x2c\x41\x10\x9c\x58\x76\xa3\xdd\x4b\xc2\xf9\x5e\xa4\x73\x12\xa7\x33\x88\x97\x62\x41\x51\xa6\xcc\x91\x79\xc5\x9c\xaf\x4c\x35\xed\xdb\xb4\x9d\xaa\x22\x27\xa9\x6f\x66\x62\xf2\x61\x49\x25\xb7\xf4\x88\x02\xe9\x17\xc8\x6f\x5d\x20\x46\xbf\xbd\x04\x94\x41\xc1\x4f\x89\x7e\x37\xdc\x8a\x46\x3d\x25\xb3\x85\xc8\xc7\xa6\x0c\x77\xb7\x93\xfa\x7a\x74\xf0\x96\x94\x1b\xec\xf9\x11\x02\xbb\x16\xb3\x7e\x10\x3c\x46\x0c\x84\x44\xb6\x5b\x6e\x90\xba\x5c\xd3\x9b\x0e\x52\x16\xe8\xd4\x13\x38\x92\xe3\x68\xc1\xb1\x92\xfa\x84\x35\x1e\xb9\x2e\xf4\xd3\x53\xa1\x58\x04\xf0\x2f\xe2\xf4\x1b\x0e\x88\x66\x38\x06\x36\xac\xfc\x62\xb2\xb0\xb6\x8b\x58\x9f\x6f\x26\x16\xd1\xde\x28\xb6\x88\x4a\xb2\x52\x13\x11\x8a\x28\x70\x0b\x83\x49\x45\x26\xf4\xda\x24\x61\xea\xb8\x8a\x9c\x43\x70\x9a\x83\x64\x83\x6f\xac\x8d\x94\x8a\x12\x60\x79\x37\x12\x8b\x26\xcc\x27\x2d\xfb\x2b\x1a\xa9\x50\x97\xcd\x04\xb4\x3b\x6b\x47\xbb\x65\x3a\xfc\xaa\x16\x63\xfc\xd8\xfd\x20\xfb\xd7\x3c\x23\x51\x55\xd4\xd5\x87\x5a\xf7\x1d\xba\xed\x17\xd3\x91\x34\xbf\xd3\x06\xb9\x91\xaf\x70\x45\x61\x78\x35\xac\x7c\x79\x94\x6e\xc5\x0d\xdb\x2a\x94\x11\x06\x35\x07\xd6\x3c\x56\x94\x12\x0e\x95\x36\x29\x70\xcb\x2d\x26\x0a\xa0\xd0\x9a\x15\xed\xb3\x86\x0a\x91\x65\x8c\x86\x8f\x5b\x4d\x92\x7d\x0c\x67\x04\xb0\x8e\x91\x13\xb9\x10\xec\xd2\x5e\x5c\x51\xd8\x7e\x27\x40\x2d\x56\x8a\xbb\x91\xf1\xb8\x5e\x7e\xf5\xdb\xe4\xd1\xd2\x73\x57\xfa\x03\x13\xf5\xf3\x45\x6a\xaf\xee\x79\xcf\x30\x5e\x28\x59\xe6\x89\xe6\x7e\x6c\x04\x97\x20\x39\x57\xe9\x1e\xb2\xe2\x95\x38\x89\xc7\x8d\x45\x5e\x11\xd8\x5f\xfb\xde\x2b\x63\x15\xab\xaa\x45\x34\x5e\x78\x07\x65\xb7\x98\x60\xd6\x4a\x00\x1c\x77\x04\x18\xe5\xa0\x3a\xf2\xe7\xb9\x63\x55\x52\x8e\x17\x7f\x31\x66\xe1\x5d\x13\xe4\xbf\x45\x1b\xd0\xa9\x9a\x52\x3e\x8a\x09\x00\x02\x33\x03\x16\xd9\x1b\x19\x06\x81\xcb\xee\xac\x42\x1a\xc6\xc6\xcf\x97\xa5\x8a\x7d\x9b\x3a\x03\x3f\x9d\xf2\x1e\xdf\xec\x3e\xb9\x9c\xb0\x9d\x09\x14\xba\x03\xcf\x1d\x11\xf4\x97\x7f\x44\xde\x76\x4e\x6a\x1d\x2f\xc2\xe5\xac\x18\x89\x29\xb4\x30\xb2\xc5\xbc\xc8\xfd\xc2\x04\xf7\xe6\xba\x40\x51\x34\xd6\xfb\xcd\xfc\xc1\x5d\xba\x12\x6a\xde\x71\x54\x4c\x1c\x5e\xd3\xba\x02\x8b\xc3\x4c\xa6\x27\x56\x2b\x0e\x22\x1e\x78\x25\xd6\x14\x43\x87\x9a\x57\xb7\x5b\x84\x52\xfd\x1b\xc4\x3b\x8c\x9a\x23\xeb\xc6\x89\x4d\xc5\x89\xaf\xa3\x64\x4a\x33\x7f\x3d\xb0\x5f\x4a\x7c\x60\x92\x8b\x19\xc7\x15\x19\x23\xde\x82\x6d\x4b\x92\x1d\x95\x5a\xcf\x23\xaa\x4f\x21\xf8\xc1\x72\x1f\x84\x9b\x59\x6d\xc6\x1f\x65\x03\xf8\x65\x17\x84\xc2\xfc\x52\x4d\xf9\xca\x4b\xc4\xd9\x24\xa5\xe1\xcb\x37\x29\xd9\xfa\x41\x2c\x9b\x8f\x5a\x63\x3d\x5a\xe2\x53\xc2\x0f\xbe\x92\x23\xb2\x19\xe4\x19\xa3\x97\x68\x2b\xc3\xc6\x79\x40\x2c\xb9\x49\xbf\xca\x60\x0d\xa8\x50\xb1\xff\xd5\xae\x16\x0a\x6c\x7f\xd1\xd4\x34\xe5\xcc\x07\x5a\x6b\x95\xc6\x81\xaa\xa2\x58\x92\x9d\x14\xc6\xe8\x7e\x96\xd4\xfb\xe7\x01\x32\xf4\x81\x15\xf8\x9b\x26\x62\x45\x8a\xd7\x0f\xd9\x30\x0f\x03\x05\xe8\x31\x8a\x8e\xbe\xd4\x97\xd9\xc6\xc9\xac\x48\xd5\x00\x6e\x65\xd2\x40\x8a\x05\xcf\x92\xdd\xc3\x8c\x38\x21\x4a\x30\xda\x68\xfd\xf5\x37\xa9\xb8\x70\x17\x32\xb3\x8a\x8e\x34\xd9\xa7\x3c\x49\x02\x82\x15\xe5\x95\x18\xa9\x97\xd1\x09\x81\x03\xe7\xa5\xc4\x2a\xbb\xa0\xef\x8a\xf3\x31\xa2\x13\x66\x9a\x5f\x44\x69\xcd\xef\x08\xc0\xe1\x47\xa4\xec\xc8\x35\x63\x75\x66\xcd\x97\x5c\xa8\x80\x0e\x5e\x15\xe8\x2f\x42\x17\x2a\xf5\x09\x5c\x4f\xcd\xea\x82\xc5\x05\x42\x62\xd2\x2c\x0f\x60\x45\x70\x28\x3c\x44\x35\xbd\x2f\x62\xb1\x3a\x4f\x6f\xed\x3a\x40\x7c\xb0\xe6\x02\x83\xea\x93\xf0\xc2\x3d\x04\x8f\xd5\x5c\x18\x2b\x8a\xfe\x5d\x01\x5f\xae\xa8\x3c\x74\xed\x08\x9e\xb8\x0f\xb2\x97\xb5\x95\xc4\xd7\xb5\xa1\xd3\xcf\xee\x32\xff\x46\xca\xcc\xe6\xa6\x1c\xaf\x1c\x5b\xc9\x8f\x08\xfc\xee\x1d\x8c\x00\x07\x5f\x1e\xe2\xb7\x56\xf3\x9a\xc0\x0c\x08\x0d\xc5\x53\xf2\xf1\xf1\xe6\x6a\x61\x97\x94\xde\x48\x8d\xca\x74\xe7\x10\x81\x51\xb6\x83\x73\x2b\xc1\x8c\x6b\xa5\xe9\x4d\x0b\xd2\x91\xfc\xee\x5b\x4b\x74\xd3\xb9\xb5\x9e\x0a\xfe\x20\x99\xf9\xbe\x64\xc1\x7c\x83\x6b\x9e\x4a\xba\xa0\x12\x71\x1a\x66\x43\xa1\x27\xaa\xf0\x31\x5b\x83\x93\xf2\x08\x9f\x41\x9a\x3c\xcf\x6f\xf5\x93\xff\x53\x6a\x67\x95\x55\x0e\xa7\x9f\x32\x10\x4b\x28\x21\x49\xac\x56\x4b\x7f\x54\xff\xb4\x56\x86\x03\x51\x48\x59\xe2\x29\xb5\x2e\x52\x31\x45\xe7\xbf\x8d\xd6\x10\xa5\xfc\x31\xb6\xe9\xd2\xdd\xbc\x48\x90\x0d\xcd\x8a\x74\x78\xf5\x51\x20\x61\x40\x16\x95\x33\xbd\x8a\x3b\x82\xa5\x33\x33\x88\x78\x8f\xd1\x3e\x1d\xb0\x46\x94\x84\xe1\x53\x04\xf9\x25\x4c\x7f\xab\xb1\xbc\x31\x99\xc7\xa4\x2a\x0b\xf8\x59\x83\x96\xe2\xc2\x02\xf8\xa6\x64\x00\x07\xaa\xc3\x1f\x8e\x29\x96\x86\x05\x9c\x6f\x6d\x3d\x53\x1b\xa0\x65\x6a\xfb\x30\x0a\x0d\x2c\x27\x4c\x42\xba\xb2\x0b\x32\x14\x6f\x57\x31\x2d\x70\x54\x8f\x52\x0f\xb0\xdb\xda\x04\x20\x04\x61\x82\xeb\x97\xae\xf2\xe6\xd2\x1c\x2f\x48\xd2\x90\x87\x48\x10\x83\xb0\xf1\x65\x85\x56\x58\xf7\x16\x9b\x1f\xcd\xb7\xf0\xda\xcb\x9b\x52\xdf\xec\xd8\x8b\x86\x41\x5f\xc3\xce\xef\x4f\xd2\xc2\x12\xa4\x4f\x48\xda\x70\x5a\xbf\x91\x1a\x3e\x95\xd2\xf4\xe1\xa9\xc1\x61\x16\x44\xa0\xb1\x14\x45\x28\x39\xeb\x5b\x64\xe3\xa1\xd0\x2e\xe1\x79\x12\x21\x16\x49\xea\xb9\x35\xa3\xbe\xf0\x8a\xcc\x74\x15\x3f\x48\xe2\x92\xb4\xb2\x60\x09\x2f\x67\x49\x6c\x20\x3f\x88\x79\x15\x10\xb7\x3b\xf1\x5b\x56\x0e\xa1\xde\x7a\x23\x3a\x55\xa0\xda\x0e\x10\xff\x62\x3d\x67\xa5\xc9\xb0\x56\x20\x24\x5b\xb6\x57\x22\xba\x1a\xa9\xde\x1c\xf0\xa6\x51\xf6\xc8\x4e\xf4\x55\xe2\xce\x2b\x6b\x55\xde\x71\x66\x60\x32\xbf\x4d\x27\xe7\x65\xa7\x70\xb8\x1f\x09\xba\xab\x1a\x97\x33\x86\x9a\x4f\xbf\x51\x07\x3a\xac\x6c\x67\x38\x57\x99\x41\x11\x86\x59\x0d\x9a\x55\x84\x74\xdb\x19\xea\x8d\x23\xdd\x95\x4b\x73\xf4\xc6\xb8\x57\x5a\xbc\x60\x98\x9f\x2a\x6f\x48\x54\x3d\x26\xe2\x5b\xee\x24\x5f\x31\x46\x0f\x5f\x3d\xd1\x55\x86\x76\xf5\x55\xff\x6c\xa4\xb7\x83\xab\x31\xa1\x6c\x55\x13\x27\x81\x44\x28\x82\x1e\x78\x08\x03\xc7\x37\xc0\x16\xe2\x27\x56\xed\x03\x6b\x8f\x54\xe2\xef\x8a\x8f\xe6\x99\x25\xf5\x78\xb5\xc8\x6c\xac\x91\xaa\xe9\x28\x98\xda\x0b\x9a\x9f\xeb\x57\x01\x97\x90\x1e\x85\xfe\x77\x6c\x48\xba\x0b\xc7\x53\xd4\xc6\xf3\x98\x6b\xe7\xb3\x5f\xb7\x91\xdd\x88\xab\xe4\x1a\xc9\xcf\x77\xfe\x73\x92\xb4\x87\x64\x70\x93\x32\x5b\x89\x56\xac\x99\x4b\x3f\x96\xda\x16\x3d\xad\xc2\x24\x67\xdd\xea\x09\xba\xbf\x61\x43\x7f\x2f\x59\x8a\x12\x65\xf3\xea\x4a\x6b\xfb\x08\x1b\x8f\x51\x14\x2e\x1d\xcb\x98\xa3\xad\x1a\x99\xb4\x30\x84\x56\x3c\x95\xc4\x73\x24\x79\x5f\xab\x27\xf8\x21\x9a\x6e\x48\x29\x9b\xf4\xba\x7d\x29\xa7\x1f\x7a\x62\xda\x24\xdd\x07\x52\x9e\x81\xf0\xfb\x83\x82\x4d\x0a\xe2\x92\xe3\x20\xd7\xef\x81\x47\xf1\xf3\xb2\x81\x2c\xbc\xc8\x64\x66\x71\x2d\xb2\xcd\x73\x6a\x55\xdd\xd2\x60\x97\x23\x98\x23\xfa\x5f\x90\x9d\x78\xb2\x8e\x5f\x0d\x0a\x5c\xbf\xa4\xc0\xbc\x39\x2b\xb9\xc3\x47\x42\xd7\xea\x5a\x9c\xd7\x01\x1d\xc6\xf3\x51\x8e\x3f\x9f\x8d\xe9\xba\x21\xcd\x1a\x61\x8c\x9a\x9b\x93\x7e\x3a\x82\x31\xbe\xb0\x02\x17\x0a\xb2\xc1\x1e\x20\xca\xf0\x8f\x45\x91\x02\x8d\x1a\xa8\x86\xce\x09\xbb\x80\xaa\x26\x40\x46\x36\x4c\x4c\xdf\x8c\x77\x1c\x76\x7a\x1e\x0e\xf8\x92\x39\x01\xc4\x28\x2d\xbd\xf4\x13\xbc\x82\x34\x7e\x5e\xd4\xb5\xb0\xcf\x10\x12\xf8\xa5\x90\x87\x96\x96\xb2\x85\xad\x13\xa9\xb5\xc4\xd7\x3f\x26\x54\x20\x73\xde\x6f\x54\xdc\x42\x96\x19\xaa\x73\x85\x3e\xb4\xa8\x48\x5d\x28\xd6\x5a\x4d\x6c\xc4\xf6\x43\x0d\x66\x6e\x44\x6d\x74\xe4\xe1\x17\x4c\x6e\x00\x8e\xdf\xb0\xc1\x6c\x36\x25\xc2\xb6\xa5\x14\x37\xc2\xac\xd0\x10\x29\xff\x91\xda\x8f\x14\x50\xde\xe0\xbc\xa9\xea\x81\xf9\xc2\x90\xaf\xc3\x1b\xa0\xf0\x8d\x44\x4b\x55\x3e\xfa\xdc\xd0\xb9\x57\x55\x3a\xbc\x76\x16\x5e\x02\xe3\x9a\x9f\x9d\x20\xdd\x55\x18\x6e\xed\xd4\x4f\x52\x67\x12\x07\xe3\x22\x5d\x2d\x0f\x21\x01\x8a\x69\x7c\x4a\x37\xbd\x22\x0a\x12\xfa\xb8\xb3\xf4\x16\x6c\x34\xe6\x59\xf8\xff\xc8\xab\x19\x85\xf9\x77\x12\xaa\x73\x4b\xe2\x46\x5e\x8a\x84\xed\xd2\x87\x04\x65\x64\x96\x53\xc8\x43\x77\x49\xf0\x8d\xf6\x12\x91\xd8\xa9\x48\xbb\x60\xed\x4e\xf4\xb9\x07\xe4\x57\xe6\x8d\x38\x09\x63\x8e\x83\x23\xf2\xc1\x01\xad\x72\xbc\x5f\xd8\x40\x83\x74\xdf\xee\x33\x3b\x55\xb5\xf8\xaa\x64\xa1\xc6\x71\x87\x45\x1a\x22\xad\x80\xe1\xd4\x67\xae\x99\x52\xd0\x1f\x45\x35\x7f\xf9\x07\x83\x90\xe9\xa6\x5d\x3c\xc2\x18\x83\xae\xce\x5a\x45\x80\x1a\xd9\x9c\x9a\x93\xc9\x1d\x6b\x84\x93\xb6\x00\xa9\x41\xdd\x95\xca\x4d\xa8\x59\xbf\xc8\x7f\x3f\x97\x3b\x93\xca\x8d\xb2\x7e\x57\x3e\x04\x7a\xd2\xb5\xb7\xb1\x11\x5f\xd1\xb5\xe3\x47\x56\x76\x9f\x7c\x33\xd7\x38\xfe\xdb\x00\xcb\xc3\xc3\x08\xd0\xca\x2a\xf8\xb7\x14\x32\x0c\xe4\xc3\xa4\xfa\x2a\xbc\xd0\x65\x41\x50\xcc\x7b\x46\x88\x93\x55\x40\x3c\xd6\x22\x36\xb7\x13\xc7\xf5\xb7\xeb\x17\x4e\x7f\x47\x4c\x4e\xe5\x8c\x84\x88\x44\x72\x4f\x5a\xf5\xe1\x83\x44\x5e\x25\x94\x64\x32\x11\x11\xa7\xb1\xa9\xc4\x0b\x09\x74\xc4\x51\x60\x04\x3f\x5e\xe0\x4c\xc3\x85\xa1\x9b\xb3\x0f\xf2\x26\x9d\x94\x54\x44\x4f\xa9\xe4\xc5\x56\x75\xf7\x8d\x54\x98\x77\xe4\x23\xd7\x4b\xdf\x04\x49\x0b\xca\xde\xb1\x93\xa9\xc3\x4e\xf4\xf8\xd9\x44\x21\xc6\x01\xda\xf5\xfc\x88\xe9\x3f\x92\x34\xcc\x92\xb6\xfc\x6b\x2b\x62\x25\xb0\xa2\x26\xc2\x0e\x8f\x22\xef\x22\x0b\x38\x21\x5f\x89\xf8\x46\xe0\xd7\x03\x6b\xac\x8c\x76\x84\xe1\xe1\x99\x3e\x9e\x94\xb9\x1b\x65\x01\x90\x2d\x47\xcb\x82\x87\xea\xd3\x0d\x85\xf7\x72\xb6\x1b\xd6\x48\x4b\x40\xe3\x5a\x62\xde\xa4\xf5\xca\x55\x70\x6d\xc5\x4d\xff\x16\x8e\xfc\x79\x6a\xcb\xd8\xf9\xf7\x69\x1e\x88\xb8\x4b\x04\xe2\xf4\x6c\x46\xae\xd1\x36\xca\x4d\x08\xd8\xad\x49\x2c\xd2\x2c\x72\xf8\x4e\x4b\x4a\x8d\x86\xe9\xb9\x1f\xf7\xb0\x84\x98\x8a\xa0\xaa\x97\x39\x94\xa4\xb8\xdc\x50\xa5\x5d\x82\x9f\xd9\xbc\xbd\xd9\xfb\x5f\x37\xc1\x2f\x7c\x7d\x8a\x89\x41\xfa\xa8\x73\xa8\xc4\x31\x77\x86\xdd\x01\x82\x96\x35\x4a\x1a\x97\xa7\x89\x55\x9e\xca\xa0\xb9\xd2\x4c\x43\x96\x9e\x20\xce\x1d\xe3\x44\xf7\xf0\x20\x18\xc7\x56\xb5\x8c\xd4\x2a\x31\x23\xbd\x51\xe0\xaf\x03\x01\x69\x8a\x24\x3b\x60\x8f\x91\xbb\xb6\xcb\x9c\x14\xd1\xe7\xbf\xb8\x3b\x57\x3b\x5f\x4a\x10\x66\xc5\xb6\xf2\x57\xee\x58\x25\x75\xba\x2d\x8b\xce\x3a\x77\xf1\x64\x11\x9b\x88\xba\x7c\x09\x53\x72\x62\xe9\xa8\xb6\xc3\xf2\x04\x42\x65\x3d\x26\xba\xd8\xc5\xed\x27\x97\xa0\x98\xab\x9b\xcc\xd0\x61\x0f\xe5\x01\xce\xf4\x0d\x73\x8e\x1b\x22\x95\x89\x71\x3f\xd8\x68\xa1\x0e\xa3\x72\x86\x48\xba\xdd\xcc\xc0\x18\xf5\xa4\x44\x9c\x14\x3c\x7f\xbc\x94\xb7\x0c\x6a\xc7\x10\xe9\x2d\x4d\xf0\xc6\x3c\x48\x26\xb2\x8a\x7e\x85\xc4\x74\x21\x03\x0b\xdb\x26\x71\xca\xa5\x43\xa3\xc4\x46\x0a\x19\xc2\x87\x47\xb7\xaf\x9f\xd8\x79\x13\xb8\x7f\x1d\xde\x73\x2e\xf9\xb7\x2d\x0c\x7b\xc0\xf6\x64\x2b\x0b\x8d\xe8\x61\xe3\x46\x06\x36\x9b\x7d\x70\x62\x76\xe4\xca\x6a\xfa\x37\xea\xea\x9c\x57\x96\xa2\x5a\x59\x72\x41\x43\xef\x32\x0d\x03\x49\x00\xcd\x42\x40\xdc\x28\xd1\x42\x57\x55\xd5\x3f\x29\x67\x40\x8e\x91\x39\x8f\x2f\x0b\x7d\xde\x2f\x67\x9c\x87\x3d\x8a\xf8\x3c\xa4\x96\x61\x1a\x9b\x7f\x28\x4c\x36\xc9\x43\x0a\x03\xcc\x9c\x1f\x6a\x89\xeb\x7d\xf7\x8a\x59\x6d\x44\xf1\x6d\x92\x8c\xd6\x6d\xde\xa4\xd1\xb0\x36\xad\x9f\x6a\xbe\x96\x38\xce\x8b\x59\x6a\x40\x2b\xbb\xc7\x56\x3f\x2a\x2b\x67\x04\x96\xe7\x47\x91\x67\x89\xc2\x0d\x4b\xa4\x4b\x9d\xec\x80\xbd\x46\xfd\xaa\x0e\x3d\xa0\x06\xac\x2d\x76\x8c\x8b\x2f\xe3\x4a\x8c\x1f\xc1\x17\x54\xb8\x5e\x1a\xc1\xa0\x17\x15\x41\x95\x06\xb7\x9c\x49\x95\xb7\xe0\x1e\x8d\x87\x34\x93\x00\x7c\x50\xf2\x6b\x69\x50\x2f\x51\xce\xf0\xe2\x44\x8d\x86\xe5\xde\x2a\x1b\xac\xe1\x3e\xa6\xcc\x88\xbd\x88\x1f\x4f\x22\xb4\x67\x2f\x64\x9b\x31\x2c\x4c\x6e\x64\xa1\x27\x30\x93\x03\x97\xa6\x67\xfd\x35\x58\x43\x86\xbf\xc9\x62\x7b\xd0\xba\x4e\x26\xc9\xcb\x4c\xd8\xc0\xd8\x4d\x8d\x1b\x2b\xc9\x3f\x5d\xcc\x2b\xb1\x44\x59\x4f\x97\x51\xd5\x09\xad\xb7\xce\x0b\x7b\x08\x0e\x1a\x9d\x10\x11\x43\xfa\x5a\xe9\xa9\x6f\x74\x60\x53\xb8\x68\x81\x5e\xda\xb9\x7b\x99\x35\x38\xb2\xc4\x4f\xc7\x62\x60\x13\x46\x66\xd9\x45\xd0\x67\x06\x77\xda\x58\xbe\x49\xc2\x6a\xba\x33\xc8\xfa\xb3\xe1\xfc\xa7\x6e\x64\xec\xd3\x43\xc7\xf5\x69\x46\xb8\xf3\x4b\xa4\x0e\x1b\x4d\xb6\xcf\x56\xd1\x0d\x6d\xe8\xb3\xb0\xcc\xc9\x68\xa3\x4a\xa6\x8b\x4f\xc7\x22\x96\xa8\x7b\x89\x59\xba\x05\x21\x7a\xb5\x23\xc3\xe8\xe3\xff\xe5\x5d\x73\x91\x7f\x46\xad\x66\x03\x76\xf0\x67\x4b\xd2\xba\x27\x07\x09\xb5\xec\x81\x25\x9a\x21\x5e\xc8\xbd\xe6\x2e\xc1\x69\x15\xeb\x9b\x22\x63\xf2\x5d\x0b\x68\xa8\x75\x3d\x64\x0a\xa4\xfe\x40\x64\xcd\xc1\xca\x69\xa4\x0e\x48\x88\x0c\x9b\x20\xf3\xba\xe8\x6e\x84\x9b\x02\x81\xf0\x87\x75\x16\x18\xd6\x8b\xdc\x1f\x75\xf5\x98\x75\x7e\x32\xc6\x50\x17\xf1\xd2\x21\x07\xde\xd0\xea\x2e\x4a\x33\x3d\xf5\xf6\x33\x09\x6a\x73\x93\x72\xcb\x67\x90\xd4\xfc\x88\xf0\xa0\xaf\x69\x18\x34\xfb\xd7\xd1\x52\x13\xb9\x26\xeb\x18\xb1\xf3\xf2\x38\x8c\xa7\x71\x2a\xf2\x08\xe3\x35\x97\xb8\x91\xdc\xc8\x75\xca\x09\xdc\xbe\x7b\x26\x5d\x48\xa3\xf5\xe4\x2f\x47\x89\x4b\xe1\x78\x21\x96\x7e\x13\x74\xbe\x0a\x1b\x84\xa9\x43\x11\x57\x57\x8d\xe2\x08\x8c\xd2\x88\xa3\xa9\x85\x41\x11\x81\x79\x93\xa7\xcb\xd7\xac\x3b\xc7\xfa\x3d\x38\x0b\xcd\xdd\xa1\xde\x73\x01\x8a\x49\xae\x83\x32\xcf\x45\xa1\x9d\x8d\x64\xde\x8c\xa4\x4a\x2d\x7b\x88\xce\xa4\xd6\x30\x17\xf0\xd8\x84\xf3\x2f\xb2\x1f\xaf\xb1\xe9\x8b\x8d\x94\xf3\x7a\xba\xff\xcc\xf0\xbc\xc9\xc8\x50\xd9\xbf\x59\x13\xff\xa1\xf9\x09\xec\x06\x5f\x64\x8c\xda\x12\xc4\x3a\x1e\xa6\x34\x8a\x7e\x10\x16\xbd\x51\xa0\xcc\x32\x3c\xe4\x42\x40\x00\xd7\xbd\xa3\x71\xd2\x06\x95\x59\x8c\x51\xb8\x14\xf3\x74\x0f\x89\x74\x88\x02\x68\x8c\xc8\xb1\x57\x41\xec\x7d\x5b\x19\x18\x9b\xd0\x4b\x8f\x39\x1e\xd3\x5a\x7b\x26\xf4\xf6\xa4\x7f\xc8\x91\x9e\xb8\x6e\x99\x64\xc9\x48\xf1\xec\xe4\xf4\x78\x07\x24\x5f\x66\x06\x5f\xab\x20\x66\xb6\xa7\xff\x93\x31\xc5\xe4\x28\xb5\x62\xb3\xfc\xff\x5f\xaa\x03\x40\x74\xce\x25\x1e\xe0\x48\xe6\x5a\x2b\x90\xba\x15\x90\x4d\x4c\xd7\xe7\x89\xac\x39\x45\x5e\xe7\x0b\x2e\x02\xa4\x30\x65\x7d\x77\x8e\x43\x05\xd3\x15\x07\x01\x35\x52\x3b\x3e\x68\xfc\x3d\xfc\x48\x34\x22\x41\x13\x18\x61\xd9\x46\xd2\xaf\x5e\xe8\x32\x8a\x3c\xbb\xc8\xbe\x25\x6f\xbd\x4a\xde\x7a\x9d\x04\x2d\x2d\x1f\x69\xc2\xc8\x6a\x47\x82\xa5\x5e\xd8\x36\x72\xcc\x6d\x81\x7c\x0b\x70\x8f\x58\xbd\xc8\x54\x84\x5d\xc1\xe2\x09\x99\xa4\x81\xde\x66\xbf\x60\x27\x69\x27\x5e\x45\x65\x37\x4f\xe8\x41\x2f\x76\x87\x41\x48\x50\x4c\x44\x14\xb5\xa9\x93\xe6\x5a\xe7\x4c\x6a\xcd\x07\xc2\x41\x90\x01\x8d\xd2\x3d\x93\x05\x6b\x33\x0c\x42\x66\x71\x63\x9f\x76\x2d\x99\x4a\x95\x72\xbe\xc8\x25\x1c\x8f\x4d\x7e\x66\xd4\x1e\x1e\xcb\xe6\x91\x2d\x85\x72\xf4\x8c\x17\x8a\xd0\xcf\x46\xef\x5e\x08\x92\xec\x65\x30\x46\x20\x08\xca\xa0\x38\x68\xc4\xe7\x37\x79\x12\xe2\x8a\x6f\xbd\x04\x26\x4f\x5d\xdb\x83\x68\x90\x42\xbb\xb5\x52\x4d\xc6\xa6\xfd\x92\xa7\x9e\x4a\x82\x7a\xa1\xfc\xe1\x65\xac\x0b\x18\xa9\x65\x7e\x45\xe5\xe4\xf3\x73\x1f\x65\x74\xc4\x9f\xa4\x9d\x22\xba\x82\x60\xdc\x8e\x4a\x14\xaa\xb4\x3f\xcf\xdd\x5b\x2b\x4b\xf0\x13\x2f\x73\x94\xae\x9d\x9d\xe0\xc9\x60\x66\x33\xb2\x00\x64\xed\x95\xb0\x85\x3a\x2c\x3f\x74\xc0\x06\x34\x32\x3b\x79\x62\xc8\x77\x80\x11\x31\xc0\x5c\x28\xca\x5e\x13\x8b\x78\xaf\x2b\x19\x6d\xcd\xba\x27\x41\x9f\xaa\xef\xc6\xdf\x3d\xb3\xb2\x50\x8d\xb3\xb8\xad\x28\xd6\x28\x49\xcf\xaf\x4f\xc5\x36\xb6\x27\x53\x37\x8b\xa4\x6e\x8a\xbf\x85\x79\x2e\x2d\x59\x47\x1a\x61\xc5\x3d\xf2\x03\x6a\x8d\x22\x39\x9d\x63\x27\x69\xfd\x08\xa7\x75\xd1\x99\xff\x0b\xfa\x02\x8b\x3a\x7a\x0b\x83\x25\x54\xdc\x2c\xc8\xc3\x39\x48\xcf\x99\x35\x91\x08\x99\x51\x59\x30\xa7\x83\x26\x85\x4c\x11\xa7\x1b\xd1\xec\x4f\x0a\xe9\x01\xb7\x63\x81\x4f\xc8\x76\x39\x33\xfc\x21\x39\xc8\x24\x54\xcf\x83\x92\xa7\xc1\xa7\x6b\x09\xdc\xb4\x7c\xea\x40\x26\x14\xc3\x90\x30\x75\x29\x08\x0b\xab\x6b\x83\x81\x4e\xfb\xd6\x66\x76\xcb\x76\x28\x7c\x1c\xb3\xe3\x7c\x63\xc0\xb7\xf1\x21\xd9\xf6\x2f\xb4\x2c\x8a\x16\x60\x31\x66\xce\xc2\x16\xab\x23\x4b\x00\x7e\x99\xcb\xeb\x17\xc9\xf1\x1e\xb6\x28\xf1\xbe\x65\x6b\x91\xe4\x1e\xd8\xcc\x54\x5c\x03\x7c\x32\x09\xcd\xd0\xc1\x31\xe1\x4a\x42\x67\x6f\x90\x69\xa9\x12\x12\x9f\xdb\x64\xd8\x9b\xcb\xc0\x02\x99\xe8\x5f\xe2\x70\x09\x8c\x92\x80\xf4\xea\x38\xd8\x20\xda\x1b\x1a\xa0\x78\x25\x96\x2b\xd4\x90\x24\x42\xfb\xb2\xbb\xaa\x5a\x7e\x99\x80\x86\x68\xd3\xb8\x96\x94\x6b\x86\x25\xce\x3e\x60\xe4\x8d\xbc\x79\xd9\x09\xa9\x2d\x84\xb7\xe2\x9e\x25\x17\x68\xad\xa6\x38\x40\xcc\x99\x4c\x2d\xa1\x5c\x23\xf5\x76\xd2\xce\x29\xf8\x64\xbb\xe4\x2c\x9f\x44\x9e\x95\xd3\x81\xbb\x9b\xd7\xe9\x47\x45\x52\x9b\x8c\x3c\xfa\x1d\x6a\xcc\xd5\x78\x31\x62\x9e\x0d\x31\x83\x06\xe8\xfd\x2c\x94\x34\xd2\x96\xfa\x25\xbf\x81\x35\x9c\xdf\x29\x5f\xbb\xca\xe1\x32\x13\x4f\x54\xdc\xd9\xc4\xae\x96\x11\xce\xd0\x5b\x1a\x5a\xc5\x0d\x5c\xbd\xfd\xe9\x0b\xfd\xc1\x4e\x25\x19\x91\x88\x9a\xa1\xb5\x63\x42\xec\xc7\xc5\xe0\xe5\xc2\x61\x2d\xe3\x51\x2d\x5a\x03\x3a\x52\xda\xcb\x2a\x60\xc3\x77\x04\x64\xb7\xbf\x23\x2b\x3d\xaf\xb4\xbb\x37\xdb\x09\x66\x3d\x66\x1d\x29\x76\xd4\x1d\xaf\xff\x83\x96\x30\x08\x2c\x3f\xac\xf1\x02\x24\xca\x4c\x90\x14\x2f\x16\x01\xa5\x50\xd5\x88\x5b\x55\xcb\xd8\x5a\x3b\x22\x84\x6f\xdb\x3d\xbb\xb1\xec\x25\xf8\x41\xe9\xc8\x4e\xbc\x13\xa8\xec\x12\x2f\xee\xbe\x47\xf5\x0a\xb2\xcd\xf0\x5d\x48\x54\x31\x9c\x85\x63\x58\xb3\xc0\xb9\x7e\x6b\xa5\x11\xba\x07\x75\xce\x49\x7c\xb5\x72\xfb\x56\xe0\x4c\xca\x03\x1a\x08\x94\xff\x81\x15\xce\xc2\x01\xd4\x68\xb7\x4c\x09\x17\xc7\x1f\xcc\x06\xcd\x32\xe0\x02\x6c\xf3\xab\x90\x74\x6c\x3c\xab\x4b\xf1\x01\xd8\xe1\x37\xc9\xd8\x21\x4b\x4d\x05\xea\x7d\xea\xc3\x2f\xbc\x0d\xd9\x54\xe5\x15\x2e\x97\x6c\xdf\x1b\x2e\x4c\x7f\x34\xe8\xaf\x2c\x65\x2b\x24\xb2\x8c\x3e\xfb\xfc\x77\x89\x0a\x2f\xdc\x41\x44\xb9\x4a\xd3\x67\x05\xd6\x5f\xc6\x47\xc2\x66\x48\x07\xcf\x53\x4c\x6d\xbd\xf2\x73\x04\xb5\x06\x2b\x6f\x60\x11\x70\x18\x9c\xdc\x34\xe2\x8d\xba\x5b\xb6\x89\x3b\xfa\x26\x75\xd1\x3f\x2d\x6a\x42\x67\x0b\x6b\xd9\x4e\x32\x17\xb0\x92\x45\xc3\x8d\x05\xda\xa8\x06\x0a\x32\x87\x59\x80\x55\x39\xfd\x85\x1d\x92\xae\x86\xb9\x15\xc8\xe7\x8f\xa6\xc9\x7e\x44\x32\xc2\x26\x23\x53\xc4\x7a\x6b\x57\xc1\xcc\x87\xfb\x4e\xe3\x50\xab\xe2\xe7\x10\x8a\x25\x4f\xcc\x0e\xa4\x45\xd8\x55\x55\x14\x1f\x02\x20\x7e\xb0\x19\x62\xf1\x25\xeb\xf7\xda\xf2\xe3\xa9\x99\xe8\x01\xb6\x59\x7e\x6d\x4b\x62\x3a\x58\x5b\x59\x26\x99\xdd\x70\x99\x40\xdd\x5e\x22\xde\x4b\x63\x67\x93\xd8\x91\x77\xd3\xee\xfb\x4c\x22\xdc\x63\x58\xaf\x9f\xee\x85\xd0\x5d\x13\x75\x66\x3f\x33\x1f\x70\xdf\x98\x9c\x60\xf1\xae\xfc\x5c\xe7\x4a\xe1\x47\xa9\x1a\x2e\x28\x44\xfc\xda\x68\xcd\x3b\x38\xd9\xa9\xdb\xb4\x25\x59\xc6\x26\xed\x37\xc5\xd4\x65\x0d\x0b\x8f\x51\xe6\xf8\x3f\x2d\x71\x0d\x80\xc8\x9b\xb8\x0b\x39\xc6\x44\x9e\xd9\x9a\x0f\x92\xd1\x08\x9b\xf6\xf6\xcb\x0b\x65\x25\x2a\x7a\x2a\x11\xc0\x93\x59\xfc\x27\xe7\x1c\x3d\x82\x75\xae\xb8\x7f\xa8\x58\xfa\xce\x3c\xc4\xeb\x20\x07\x02\x33\xe2\x2b\x89\x57\xd0\xee\x32\x53\x90\x0c\xa1\x11\x73\x16\x0c\x3b\xca\x51\x8a\x95\xd5\x97\xd0\x52\x99\x12\xa8\x03\x50\x1b\xe1\x4c\xb5\x61\x45\x17\xe3\x8c\x8d\x34\x32\x4a\xf1\x82\xd8\xf3\xba\xce\xe8\xde\x30\x22\x0f\xa0\xa0\x16\x2b\xc4\x77\x0c\x17\xc8\xa6\x7b\x94\x7f\x99\x2d\x24\xac\xe4\x3b\x58\xd8\xf7\xbf\x22\xef\xfe\x89\x7e\x21\x20\x6c\x4d\x23\x2c\x2f\x6b\xdb\x5f\xe6\x48\xb8\xa7\x8c\xf0\x8d\x92\x8d\x67\x6a\x9d\xae\x56\xa7\xd5\x22\x65\x65\x32\x37\x0c\x9c\x23\x61\xdc\x14\xe2\xff\xd4\x0d\x61\xe1\x8d\x5a\xf5\x68\x9b\x42\x4c\x28\xe8\x20\x73\x62\xdd\x4d\xbb\xcd\xf0\xdf\xc2\x67\x6b\x64\x04\xc5\xa8\xc9\x9e\x0e\x59\xf3\xb7\xf8\x25\x6f\xad\x6d\x59\x78\x7e\x99\x97\x4c\xbd\x1e\x6f\xc2\x84\x1c\x08\xec\xe3\xcc\x88\x59\x17\xeb\xc5\xae\x7e\xdb\xee\xde\x2f\x50\xb3\x4a\x73\x64\xae\xa9\x0e\x91\x5a\x92\xfa\x6b\x59\x8e\xb1\x8c\x76\x3a\x7c\x2e\x98\x6a\x76\x61\x04\x65\x3a\xf4\x34\x92\x36\x0d\xd6\x09\xc7\x7e\x15\x0d\x42\xea\xc7\x5d\x9a\x27\x4e\x2f\xda\xc3\xc5\xbc\x59\xbe\x45\x1c\x01\x22\xe3\x7b\xb4\x79\x77\xa2\x2b\x0e\xd5\x80\xe2\x96\x96\xad\xe3\x5f\xe2\x29\x51\xd2\x9d\x59\xd7\xb1\xb6\x07\x3f\xbd\xf1\xcd\x83\xec\x59\xac\xb0\x2c\xdb\xc8\x6c\x81\xa4\x57\xcd\x72\x40\x07\xd8\x85\x3f\x7f\x31\x1d\xf0\x54\x0e\xbc\xcd\x79\xf9\x43\x15\xfa\xe3\x0d\x27\x3f\x21\x17\xcb\xe2\x65\xbf\x37\xb5\x48\x64\xcf\xb9\xc9\x9e\x60\xe3\xd2\xc5\xa3\x14\x58\xdd\x2b\x91\xe1\x59\x3d\x0c\xeb\xeb\x15\x8e\x80\xe4\xec\x41\x45\x4a\x88\xd7\xdd\xa4\x21\xe1\x21\xd9\x7a\x43\x69\x6b\xd0\x94\x04\x0b\x4d\xcd\x74\x0f\x50\x0d\xe0\x06\x8e\x4d\x3f\xf9\x0e\xbd\x29\xfb\x25\x54\xda\xfc\x34\xd3\xcb\xb3\x31\xf0\x4c\xef\x0c\xfc\xf0\x3b\x4d\xc7\x13\x6c\x2f\xc8\xf9\xe1\x50\x70\xfb\xa4\x26\x87\x8a\xe0\x26\x85\x08\xe1\x1c\x30\x0a\x73\x4e\xb9\xe6\x3d\x2c\xe7\x70\x49\xaa\x7b\x53\x63\x94\xb0\x66\x8e\x52\xba\xb3\x69\x9e\xe8\x9e\xba\xb5\x9b\xd4\xf6\xa5\xa5\x5d\x06\x3c\xc4\xae\x0b\x5a\x5a\xe5\x55\xc7\xba\xf6\xdc\x5c\x26\xa1\x4a\xba\xa2\x0d\x32\xc8\xa4\xf8\x57\xec\x65\xfe\x70\x14\x6e\xd0\xb7\xce\x57\x38\x3f\x43\x9b\x72\x44\xf0\x11\x4e\x4f\x1a\xa7\x46\x80\xa1\xdd\x0f\x87\xca\x94\x23\x3f\x09\xc8\x40\xe6\x66\x58\xd8\xec\xee\x40\x1a\x10\x05\x1d\x72\x44\x8b\xc2\x1c\x63\xe5\xb4\xe2\x25\xa9\x49\x28\xec\x87\x59\x10\xb4\x13\x06\xaa\xb5\xe5\x7b\x04\x45\x4b\x62\xec\xef\x64\xf0\x10\x4f\x51\x89\xa9\xad\x10\x57\x99\xcb\x2c\x85\xad\x0b\x42\x1f\xd0\xea\xf3\x34\x54\x9e\xb7\xf3\x82\xf8\x24\xeb\xbd\xf4\x7b\x8f\x97\x6d\x1a\xa4\x57\xbc\x4e\x7b\xd7\xd6\x96\xe7\x24\x92\x33\x73\x4a\x20\x18\x10\xd3\x47\x19\x01\xa3\x96\x74\x12\x27\xe2\xcb\x90\x9e\xca\x30\x82\x91\xe2\x92\x5d\x1c\x47\x4e\x18\x1a\x39\x7a\x43\x5a\xde\x7b\xce\xb9\x8a\x3a\x73\xb1\x55\xc3\xd0\xea\x51\xf9\x92\x24\x9d\x92\x91\x25\xed\x78\xf0\x6e\xb8\xda\x30\xb6\x16\xf4\x91\x68\x2a\x3c\x08\x84\x6c\xc7\xa4\x9f\xdd\xcb\xc1\x3f\x7e\x9c\x7e\x02\xf1\x52\x9b\x2f\x9e\x49\x83\x6b\x0b\xf6\xd9\x2d\x02\xff\x3c\x46\x54\xf9\xa5\x0d\xe5\xe1\x14\xa1\xd0\xa1\x8b\xb0\x92\x57\x35\x02\x0a\x86\x9d\x9d\x72\x22\xc4\x6e\x6a\x15\x45\xb4\xa2\x75\x51\x34\x6b\x09\x5d\xc0\xa5\xc2\x42\xd7\x10\x59\x6e\x2d\x82\xf4\x26\xb6\x80\x13\x71\x77\x51\x81\x96\x59\x90\x79\xe6\x1b\x87\x43\x05\x9d\x56\x6f\x23\x03\xaf\x60\x25\xfa\x8a\x4f\x4c\x74\x7c\x4c\x8b\x54\x0b\x1f\xa4\x2d\x7a\x68\x8b\x34\x91\x4c\x87\x15\x73\xd5\xf5\xae\x3e\x96\xc7\x2c\xe5\x2e\x7e\x0e\x94\x1a\xf5\xdb\x4c\x4d\x61\xdb\x21\x6c\x26\x7b\xf2\xa9\x50\x88\xce\x0c\x48\x2d\x53\x75\xfe\x9b\xa6\x26\xe8\xb8\x8b\x4a\xe3\x44\xf7\xc3\xe3\xd3\x5a\xf8\x8d\x48\xd9\x5a\x5d\xa1\x77\x03\x26\x8d\x24\x2e\x71\x65\x37\xb2\x66\xb0\x66\xf1\x38\xe2\x85\x03\x67\x93\x9e\xa0\x45\x8c\xcb\x2c\x5c\xcc\xca\xf4\x2c\x63\xd5\x6b\xbc\x83\x5d\x5e\x05\xf1\xf8\x67\x53\xd2\x0a\xe6\x6f\xb5\x1d\xe7\x99\x83\x36\x94\x25\x61\x93\x86\xd6\x09\x3a\x1c\xec\x81\x74\x5a\x57\x5c\x73\x19\xa6\xb4\x62\x6a\x7f\x1c\x24\xfa\xae\xad\xfc\x88\x1d\x15\x5f\x5c\x2c\xc0\xd8\x71\x4b\x49\x0a\xc5\xa1\xbf\xb3\xcc\xa4\xb2\x89\xbf\xd3\xe9\x7e\xd7\x89\xc0\x73\x2b\xd8\x2d\x2c\x6b\x2d\xf7\x03\x63\x34\xcb\x6c\xee\x20\x6c\x14\x04\x85\x8b\x4f\x8f\xdc\xf6\x7e\x29\x1a\xaf\xd3\x0d\x43\x03\x16\xd6\x25\x59\x16\xae\xae\x28\x2f\xa2\xd4\xbf\xb2\xa4\x41\x95\x65\xc5\x10\x4c\xf0\x88\xec\xed\x5c\x6b\xcd\xd3\x3b\xb5\xe2\x21\x54\xe4\x81\xb0\xec\xf7\xf4\x91\x08\x6f\xba\x76\xa5\xba\xb6\xb2\x8d\x52\x02\xd2\x5d\x5c\x19\xa6\xa8\x9e\x51\x3b\xf5\x59\xe2\x7a\x46\xba\x7a\xdf\xf9\xa2\x10\x2a\xe4\xe7\xbb\x3a\xd0\x14\xd1\xb2\x72\x7c\x44\x1d\xc9\xc3\xc0\x59\xc7\xb8\x1f\x4a\x85\x52\x45\xb5\xa1\x29\xe5\x9b\x8c\x51\x29\xaa\x15\x76\xf2\x97\x26\x18\x02\x22\x9c\xc5\x32\xed\x94\xd3\xb9\x0e\xd2\x32\xd4\x19\x96\x7e\xe5\xc8\xa2\x70\x1d\x3a\x11\xa5\x12\xba\x2b\xdb\xa2\xf6\xc8\x07\x48\x85\xfb\x3a\x01\x1e\xe3\x48\x26\xe9\xb4\x2e\xc8\xd5\x59\x74\x2c\x21\x8e\x52\xcb\xef\x4a\x6a\x58\xcc\xa5\x00\x3e\x6f\x17\xf6\x0f\xc5\x0f\xc8\x7c\x8c\xf5\x52\x4d\x95\x0e\xe4\xac\x5b\x90\x83\x30\x80\x3e\xa5\x04\x67\x69\x58\x5e\x44\x09\xac\x17\x28\xde\x47\x54\xaf\x49\x7f\xe4\x21\x21\xe9\x23\x08\x8b\x68\x22\xc1\x5e\x44\x8e\x47\x26\xbd\x15\x1f\x64\x25\x4c\xb7\x0e\xce\x47\xc7\xad\x10\xe0\xcd\x34\x49\xb5\x8c\xeb\x17\xff\x20\xc6\x48\x0d\x63\x15\x56\x17\xc0\xa4\xe0\x48\xb6\x7b\x7b\x0c\x58\xc4\x8d\xf9\xd8\x90\x39\x7f\x83\x7d\xe0\x49\xee\x87\xae\x76\xab\xaf\x09\x70\x8f\x16\xcc\xba\x15\x85\xf9\x50\x14\xe3\x22\xda\x5e\x89\x75\xe6\x78\xdf\x3a\xba\x54\x17\x84\xf5\x85\xed\x51\x5c\x39\xeb\x69\xa4\x47\x04\x50\xa3\xb5\xa6\x41\xf0\x24\x1e\xa9\x49\x0f\x08\xe2\xa5\x44\x33\x29\xb4\x5e\x80\xd0\x99\x23\x2f\x9e\x6c\x09\xae\x08\x00\x12\xa6\xda\x75\xa4\xbe\x23\xc3\x77\x46\x7b\x45\x94\x6e\x80\xb4\x4c\x68\x50\x3e\x89\xe3\xfd\x7f\x80\xaf\xf6\xe0\x4c\x44\x76\x22\x8a\xba\x39\x86\x07\x21\xe9\x67\xe3\xdc\x57\xe0\x09\x1b\x69\xf6\xbd\xb4\x2d\x37\x75\x0f\xe7\x4b\xb8\xa7\xed\xbf\x2e\x0f\xcc\xd2\x12\x32\x7a\x40\x72\x91\xb3\x3d\xfa\xc3\x12\x45\x07\x46\x6d\x57\x7c\xb4\x52\xcc\xd2\xf8\xc9\x00\x87\x2a\x6f\xa7\x40\x4d\x0b\xe1\x61\xe3\xd4\x63\xb0\xf7\x08\xef\x61\x98\x38\x5e\x42\x67\xd6\x0c\x4a\x56\x10\xc9\x56\xf4\x6d\xd0\x67\x6e\x40\xac\x67\xd0\x5e\x89\x41\x79\xd8\x8f\xa9\xae\xe4\x1f\x69\x13\x33\xbc\x59\xb0\xc0\x93\xf0\x4a\x66\x75\x6f\xaf\x83\xc0\xb5\xfd\xa5\x02\xda\x5a\x11\xe5\x09\x2d\xbf\xec\xb6\xf5\x76\xe6\x28\x2d\x9c\xab\xd4\xee\x9f\x01\x3c\x0c\x8c\x08\x84\x0a\x74\x67\xeb\x8c\x70\x16\xf5\x5e\x9e\xea\xa5\xf4\x7f\x8c\x58\x65\xca\x3b\x49\x28\x1a\x97\x97\x0c\xf8\x66\xd7\x77\x1b\x85\x88\xae\x36\x8b\x36\x82\xd7\x9f\x50\xe6\xbc\x6d\x28\x10\xfc\xd2\x43\xba\xa2\x75\x4c\xd8\xcd\x48\x29\x11\x74\xdc\xd2\x0d\x1d\x83\x41\x6e\x13\x31\xe8\xc1\x82\x74\x5c\x15\x6f\xe5\x25\xf4\x4f\x33\xca\xfd\x6f\xe1\x90\x5f\xb5\x0e\x36\x0d\x03\x7b\x79\xe1\x3c\xce\x8c\x38\x30\xe5\x30\x0c\x83\x1e\x11\xa2\xdf\x42\xeb\x77\xfb\x92\xdb\x23\x20\x6e\xd0\x92\x5a\x42\x4e\x38\x8e\x40\x25\x8d\x92\x15\x35\x86\x7e\x69\x34\x9f\x95\xd1\xdb\xfa\xfe\x84\xe0\xfb\x8d\xb4\x87\xf6\x6e\x66\x16\x46\x6a\x20\x8b\x2b\x75\x30\xc9\x20\x15\x81\xb4\x4f\x34\x7b\x47\xaf\xeb\x45\x67\x42\xd8\x88\x0b\xfe\x81\x49\xbf\x17\x3d\xe1\x97\x03\x5c\x6f\xc0\x0f\xea\x98\x50\x17\x3e\xa9\x7e\xc7\x20\x90\x4e\x01\x99\x34\xca\xc2\xd3\x28\x92\xbf\x09\x25\x56\xa1\xb2\xb5\xff\x51\x8b\x2b\x1e\xdd\x1c\x01\x8c\x5e\xbb\x6e\x96\xe2\x7d\xb8\xf8\xa4\x6f\x19\xa5\x72\x0c\x8f\x77\xd9\x9a\x29\x44\x2b\xdb\x12\x75\xee\xf7\xa2\x44\x98\x07\xcd\x05\x50\xce\x0c\x61\x37\x94\x90\x8b\x42\x06\x1d\x1d\xfa\x74\x67\xe6\xa6\xfe\x6c\x68\x19\xa8\xd0\xd5\xf3\x4b\x46\x59\x84\xfa\x8f\xf6\x6a\x52\x0a\x47\x49\x6b\x8c\xa4\xcd\x02\xfe\x46\x8a\xca\x43\xd8\x27\x45\xea\xe8\x74\x2c\x63\x8b\xea\x71\xd1\x89\x7b\x72\x49\x8b\x09\x93\xad\xf9\x15\x42\x34\xc5\xce\xfa\x1c\x55\x53\x8b\x5a\x97\x42\x65\x16\x0c\xf8\x33\x89\xcf\x11\xd7\x0d\x79\xfe\xaa\xb0\x93\xb4\x87\x10\x3a\xca\xf4\xe1\x41\x8d\xc6\x72\x04\x5b\xd2\xa4\xdd\xaa\x0e\x2d\x71\x25\x5e\x82\x28\xcc\xe2\x4e\x8e\xeb\xed\x05\x73\xde\xa5\x6d\x89\x2f\x2a\xbf\x7a\x2c\x71\x2a\xef\xc6\xe3\xe0\xc7\xf2\xc0\xf3\xc3\x06\x88\x3e\x34\x3b\x32\xb0\xf2\xe1\xd3\xc1\xdb\x0d\x3c\x4c\x36\xd4\xd6\xd3\x03\x3b\x92\x69\x35\x35\x84\x24\x43\xed\x11\xc7\x01\xea\xae\x24\x03\x6f\x66\x47\xff\xd2\xb4\xfe\x04\x90\x38\x69\x9b\xfa\x2a\xa3\x70\x6a\xd2\x98\x40\x3d\x3c\x4f\xd1\xd7\x37\x41\x2b\x8b\x8b\x24\x2d\x18\x7d\x92\xb8\x7f\x13\xb7\x88\xdc\x4f\xb5\xb1\xf4\xcf\xc6\x4f\xfd\x2e\x51\xa2\xbc\xe2\x92\x87\xbb\x94\x58\x05\x2b\x33\x2d\xaa\x41\x5e\xe5\xe4\xb3\x43\x6b\x12\x7d\x33\x86\x96\xc7\x62\x9b\xd8\xc2\xda\x5f\x41\x1a\x4d\x6c\xe3\x87\x27\xce\x12\x5e\xb8\x6e\xe4\x88\x21\x91\xde\x81\x53\x62\x08\x77\x66\x6d\x73\xd0\xf9\x30\x3b\x61\x15\xd5\x05\xc0\xf5\x40\x98\xc0\x53\x9a\xf2\x6c\xd0\xb4\x5f\xc8\xf7\x2a\x8b\xd9\x05\xc4\xcb\xad\x4f\x32\x96\xe3\x34\x42\xea\xe5\xf4\x9c\x24\x5f\x89\x8c\xe8\xf6\xc0\x91\x8a\x3d\xa0\x61\x51\x20\xbe\x36\x29\x47\xfa\x42\xa3\x40\xf5\x78\x0a\x6b\x5e\x03\x26\x48\x46\xfb\xcd\xd3\x9e\x49\x83\x35\x5c\x10\x1a\x9c\xe0\x68\x1e\x03\x52\x20\x3b\x58\x4d\x24\x23\x64\x58\x6f\x06\xa3\x97\xd1\x1c\x45\x97\x61\xe9\x8f\xd2\xcf\xef\x95\xa8\x99\x7d\xba\xa4\xd6\xa4\x80\xb4\x87\x9e\x6c\x36\x06\x97\x66\x5a\x7a\x4d\x92\x2c\x50\x60\xe8\xaa\x2d\x82\xc6\x2f\x48\x8b\xa6\x33\x9e\xde\x97\xb9\x62\xdb\xc8\xd1\x75\x34\xc7\xd5\xdf\xc2\xb9\x64\x63\xda\xce\x86\x82\x0d\xf6\x0f\x1c\x60\x73\xec\x58\x94\xb3\x06\x44\x8c\x27\x35\x23\x44\x0d\xf4\x0a\x03\x02\xae\x41\x28\xe6\x86\x09\xe5\x9f\xef\xc8\x71\xfa\x65\xc4\x39\x64\xe9\x82\x63\xfa\x25\xe9\xc6\xe5\x28\x6d\x62\x6c\x27\xb2\xf9\x25\x52\xb2\x3c\x02\xe1\xf3\x52\xe7\xe4\x1b\xd7\x10\x69\x40\x49\x52\xf2\x24\x38\xd2\xf2\x83\x8e\xaa\x88\x97\xfe\x09\xcd\x7a\x3c\xb6\x0b\x17\x21\x0d\x1d\x5d\xdd\x47\x00\x23\x52\x6f\xa9\x3a\x87\xde\xa5\x16\x15\xde\xee\x9f\x7e\x49\xe9\x67\xb9\x93\xab\xf9\x98\x4b\xee\x5d\x81\xc5\xf0\xdd\xc8\x4f\xf6\xc1\xbf\x15\x3d\x76\xd0\x8a\x72\x0e\x1c\x9b\xd4\x24\x78\x6a\x93\xc0\x59\x2a\x4f\xd7\xc2\x63\x2f\xa3\x42\xbf\x54\x94\x24\x9f\xe8\x95\xe7\x0e\xec\x6a\xb7\x98\x9f\xa8\xf2\x73\x7f\xcc\x28\xe0\xf4\xa2\xac\x69\x1a\x1f\xa7\x73\xf6\xa3\xf9\x90\xa3\x19\x10\xee\xe0\x71\xb6\x3c\xc3\x75\xa8\xb0\x00\x3f\xa1\x86\x56\xc3\x78\xcc\x28\x97\x7d\xfa\x6c\xf4\x41\x47\x65\x39\x52\x0a\xf6\x5e\xc7\x6c\xd4\x4c\xa9\x5e\xff\xd9\x14\x4e\x5a\x6c\x2b\x9c\xd5\x8f\xc6\x49\xd6\x86\x86\xc4\x15\x19\xba\x74\xc0\xef\x1c\x24\xc6\x7f\xf5\xa8\x28\x59\x6b\x8a\x20\x88\xad\xb8\xdc\xb0\xe9\x6f\x04\x89\xad\x75\xa7\xf8\x61\xa6\xf3\x37\x88\xb3\x5b\x71\xce\x51\x5c\xd5\xf7\xa5\x67\xd9\x52\x26\xd2\xae\xd4\xcb\xd5\x95\x09\xf4\x23\x63\x54\x6e\x37\x16\x9a\x7a\xba\xb2\xa1\xc5\x08\xaf\x67\xba\xb4\x9c\x5f\x5a\x9b\x64\x6e\xde\xf3\x42\x57\x23\xdd\xb5\x86\xa6\xe5\x99\x4e\x0c\xe9\xcc\x81\x5d\x94\xc2\x33\xa0\x62\x90\x06\x29\x7a\x3f\x8f\x39\xad\x7e\xf2\x13\x69\xb9\xac\x7b\xcd\xfd\x5b\xf5\xe8\x0d\x48\xc1\x11\x02\x2c\x5a\x15\x57\x81\x03\x7d\xe2\x70\x29\x38\x00\x5d\xdd\x12\x32\x3d\x29\x16\xf7\x7b\x8d\x93\x1e\x67\x45\x61\x82\x9e\xaf\x02\x4f\x78\xea\x39\x0d\x3f\xd9\x69\x95\xd9\x45\xfd\x45\x01\xc4\x45\x60\x7f\x4a\x0a\x56\xee\xbc\x48\x00\x4a\x7e\x89\x85\x04\x9a\x38\x05\xc6\xe1\xe3\x7e\xc2\x91\x51\x89\x8a\x2c\xf6\xbf\x4d\x98\xfb\x76\x73\xcf\xee\x77\x2a\x2c\xe2\xd7\x4e\x5a\xcb\xa2\x60\x8e\x2f\xc0\x31\x38\x4d\xc5\x11\xc0\x91\x34\xb7\x40\xf0\x87\x0a\x91\x3e\x58\xc1\xe0\xb9\x43\xc2\xd7\x38\xbc\x48\xbb\x33\xc8\xa0\x14\x72\x8d\x2d\xc5\x36\x3f\x51\x85\x9b\x40\xf0\x54\xb4\x93\x30\x6a\xcc\x32\x44\x9f\xb3\x1a\x8f\x29\x28\x50\x34\x69\x12\xad\x03\xc7\x20\x02\x2a\x46\x54\xde\xcc\x2c\xca\x24\x63\x6c\xe2\x65\x48\xbd\xef\xde\x04\x1f\x1e\xd8\xa7\x31\xc8\x0c\xca\x21\x65\x52\x78\xcd\x3a\x40\xca\x82\xe2\x59\xe7\xe9\x69\xf3\xc4\x20\xb3\xb9\xb6\x59\x27\x27\x66\x99\x89\x55\x04\xd4\xa6\x16\x4a\x52\x53\xca\x40\x97\x5a\xb9\x39\x1f\xca\x7a\xb6\x37\xa4\x92\x17\xb6\xab\x1d\x9e\xfd\x25\xfa\x0d\x54\x25\x1c\x56\xce\x44\x55\x57\x01\x50\xe7\x55\x0e\x7b\xeb\x10\x86\xf2\x52\x28\xe4\x76\x88\x29\xcc\x7b\x68\xaf\x3e\x80\x1f\xef\x9b\x30\x4a\x07\x01\xd4\x1e\xec\xc8\xd2\xab\xdd\x12\xed\x50\xdc\x51\xe4\xd6\x9b\x49\x43\x81\x78\xe9\xe4\x56\xeb\x56\x29\x37\x50\xe4\xac\x63\xe9\xe0\x06\x08\xb2\x5f\x1a\xc8\xcd\xef\xc5\x40\xac\xf1\x21\x2c\xf2\xa4\x80\x0c\x59\xa9\x26\x82\x22\x9c\x3e\xc0\xc5\xed\x1b\x2b\x48\x06\xbb\x98\x5a\xfc\xe6\x5b\x60\xac\xd2\x70\xb8\xee\x52\xb1\xc2\xc8\xb2\x75\xd2\x2a\x97\xfc\x1d\xeb\x9a\x2b\xe2\x90\x25\xe9\x7c\xce\x9a\xd9\xe4\xb1\xf5\x6c\xc3\xa2\x53\xde\x17\xa5\x09\xb1\x5c\xd7\x8e\x4e\x62\xe6\xc7\x22\x01\xa6\x45\x4d\xb8\xab\x10\x36\xd6\x21\xc6\xe9\x86\xa0\x7d\xec\xd8\x7f\x66\x54\x8d\x08\xb4\x9f\x9c\x14\x7e\x54\x2c\x60\xde\xff\xa6\xe1\x32\xca\xde\xff\x9d\x60\x49\x2d\xe1\x1f\xe4\x74\x5e\xce\x1e\x4f\x1e\xca\xfb\x39\xa0\x93\xa9\x92\xf2\xe3\x14\xae\xbd\x06\xe0\x72\x60\x67\xed\x76\x4e\xec\xe7\x04\x71\x88\x71\xd7\xdd\x2f\xe1\x38\x82\xb5\x03\x6f\x84\xab\x27\x8d\x46\xbf\xbb\xb5\x27\xb9\xe6\x1c\x3e\xa8\x57\xdc\xb3\x64\x6f\xee\x52\x8a\x89\xd7\x21\xf1\x3f\x3a\x1f\x40\x46\x62\x93\x25\xec\x81\x0f\x5a\x58\x72\x70\x87\x49\xf3\x70\x39\xb7\xa4\xcf\xca\x12\xb4\x97\xa7\x77\x71\x68\xb4\x3f\xa6\x39\xc2\x57\x89\xf7\x8d\x1e\x80\xd7\xb0\xef\xa0\x32\xbb\xf1\xa4\x2b\xad\xd6\x2c\x24\xb5\x96\x65\x01\xfd\x4b\x71\x41\xfd\xa3\x41\x1a\x81\x18\x1d\xbc\x27\xe9\x0a\x72\x80\x9f\xb9\xfd\xfe\x49\x14\x08\xdb\x0e\x81\xfa\x36\x65\x9e\x77\x2c\x37\x6c\x12\x1b\x0d\x34\x07\xc7\x5a\xa4\x8e\x9b\x5f\x13\xf1\xbf\x6b\xd4\x2b\x30\xc9\xae\x51\xb1\xa4\xe4\xb7\x5e\xc9\x6c\x5c\xeb\xc3\x88\xfb\xc3\xba\xcd\xe4\x48\xb6\xe4\x08\xd2\x04\x2f\x2f\x31\xbd\xc2\xe2\xa9\x4a\x26\x67\xc7\xed\x26\xbd\x08\xe9\x3a\x13\xff\xe2\xd7\x5b\x69\x5b\xfe\x47\x2b\xbd\x6c\xd2\x9c\xc2\x7a\xb0\xb9\x51\x3a\x2b\x71\x6c\xdd\xe7\x3b\x2c\xf3\x45\x17\x60\xd0\x62\x44\x22\xe7\xe8\x82\xf2\x2b\x49\x60\x3f\x2f\x8d\xbb\xcf\xbe\x32\x99\x81\x4e\x39\x66\xf6\x3d\x2a\x29\xd8\x28\x94\xd7\xe5\x88\x13\xdb\xa1\x23\x08\x50\xa2\x7d\xc8\x88\xc3\x1e\x88\xdf\x4a\x55\x01\x93\x5e\xcd\xf6\xdb\xd3\x6e\x68\xb4\xad\x4c\xd9\x70\xef\x87\xa0\xd9\xba\x3b\x1b\x51\x24\xde\x6b\x55\xea\xca\x7e\x34\x52\xb1\x0c\xd2\x33\x39\x23\xdc\x6b\xb6\x46\x4e\x3e\x61\x70\x49\x66\x6c\x31\x93\xad\xb3\x05\xad\xb2\xc4\x32\xfe\x92\x58\x3d\xf9\x76\xa8\x53\x11\x44\xfa\x60\x15\x45\xe7\x57\x93\x30\xf0\x9d\x28\x3a\xff\x03\xd8\xae\x5b\xf9\x29\x41\xcd\xb1\x67\xc5\xd2\xac\xae\x1f\x58\x26\xfe\x10\x7f\xf1\x61\x9a\xcb\xd0\xc0\xe8\x03\x09\xd0\x7d\x3f\xd2\xb1\x79\x90\x8f\xbb\x7e\xb0\xc9\x0a\xf4\x02\x70\xae\x67\xc9\x00\xac\x02\x08\x32\xa2\x6b\x39\xf6\x3f\x4c\xde\x6b\x52\x91\x48\x9e\x0a\x6a\x60\xc6\x9e\x44\x97\xc2\x49\x28\x45\xbe\x9a\xcb\x40\x60\xd1\xc7\xcb\x28\xf0\x78\x89\x18\x88\x21\x9d\x85\x21\xd6\xa2\x04\x2a\x1d\xc4\x05\x88\x1d\x18\x8f\xcc\x2c\x8a\x5a\x0a\x22\xef\xb8\x1c\x9b\x4b\x2d\x17\x00\x54\xc2\xc1\xb4\xfb\xe5\x79\xe1\x43\x49\xcd\xbc\x31\xd3\xdf\x44\x45\xf7\x48\x6b\x5b\xde\x6e\xd0\x53\x8a\x1c\x23\x2f\x42\x8e\xcd\xa5\x76\x06\x9f\xa4\xaa\x63\x7c\x4a\xb7\xa3\x0f\x6d\x7a\x68\xb5\x4c\x7b\xb5\x16\xd0\xba\xe7\x7c\x49\x3e\xc8\xe8\xa0\x65\x5b\x92\x5c\xaf\xe2\x99\xb0\x99\xec\x11\xef\x77\x49\x54\xec\xc4\xfa\x04\xe5\x2d\xfc\x82\x7d\xdc\x05\x49\x02\x29\x8f\x6f\xc9\x3f\x60\x4e\x09\x01\x09\xf1\x48\x99\x41\x35\x2d\xac\x64\x0b\x1d\x6f\xcb\xe6\x4f\x38\x2a\x23\xc1\xda\xc7\x50\x80\x05\x97\xc2\x44\xb9\x23\x37\x60\x9e\x0c\x3c\x10\x63\xf7\x14\x57\xe6\x9a\x7e\xc8\x52\xac\xb8\x94\xcc\x6b\x31\xd6\x53\x96\x46\x74\x2c\xad\xc8\x30\x1b\xd6\x97\x1c\xe9\x98\x20\x6b\xd9\x6d\x10\xd9\xd0\x8d\xdb\xe2\xfa\x45\xa8\x1e\x12\x0b\xcb\xef\xd4\xac\x02\x58\x5c\x77\x8d\x1f\x24\xe0\x5e\xa7\xa6\x21\x23\x18\x38\x9a\x0e\x92\x1b\xfe\x2d\xc7\x1b\x2c\x93\x14\xf7\xe2\x25\x7b\x39\xe8\x80\x4e\x0b\xe0\xe4\x12\xdc\xd2\xf1\xb5\x46\x92\x05\x2e\x52\x19\xb4\x0e\x46\xbf\x10\x7a\x16\xae\xc1\xac\xdc\xd6\xb5\x2a\xe1\xd9\x82\x95\xc2\x58\x82\x4d\x18\xcb\x63\x22\x01\x69\x18\x1a\xb2\xca\x33\x4c\x32\x2e\x3e\x5c\x68\xa6\x61\x5d\x3c\x43\x33\x70\x32\xe6\x10\x95\xc1\x6f\xee\x90\x92\xe8\x75\xbc\xa1\xd6\xc4\x8a\x32\xd1\xc9\x07\x64\xf8\x93\xa2\xc6\x34\x8a\x9e\x19\x05\x7b\x42\x2f\x36\xd7\xf9\x7c\x59\xf4\x8e\x0e\xb7\xb3\x7e\x7c\x37\x2c\xd6\x31\x4a\x48\xfd\x41\xc5\xc9\x20\x88\xed\xa4\x62\x84\x1e\x13\xe7\xae\x17\x6f\xc5\x3f\x09\x47\x5b\xe8\xef\x75\xef\x60\x96\x8e\x53\x11\xba\x3e\x2d\x9a\xd4\x3c\xf8\x51\x41\xa6\x57\x24\x65\x49\xa8\x4c\xde\x95\xd0\x4b\xa6\x39\x69\x1d\xd9\x7c\x51\x22\xae\xa1\x45\x84\x6b\xa4\x66\xa1\xa2\x5c\xd3\x78\x14\x8d\xb3\x53\xe1\x48\x42\x94\xcf\xde\xec\x25\xb6\xc4\x48\xf4\x9a\x20\x71\x8d\xb1\x5f\x00\xb5\x6c\x6a\xa6\xdf\x77\xdb\x38\xb1\x6e\xe3\x07\x24\x1c\x2b\xa7\x86\xfc\xb9\xe1\x8d\x54\x40\x90\x35\xfd\xe0\x4c\x15\x6f\xc4\x30\x87\xf8\x1f\x0a\x12\x38\x52\x91\x4f\x5e\x67\x85\x82\x17\x37\xea\x09\x84\x8e\x50\xd0\x10\x84\x1b\xa7\x7b\x62\x03\xe5\x4e\x07\x65\x1b\x39\x42\x9d\xe2\xb9\x86\x67\x60\x42\x13\x4d\xd3\x8b\x10\x5e\x2d\xe9\xaf\x62\x0d\x58\x1e\x8d\xcc\x3e\x9a\xff\xc1\x16\x96\x9b\xf0\x77\xef\x46\xee\xed\x39\x8e\x88\xd9\x19\xdc\x15\x99\x83\xa4\xbc\xb7\xc2\x2e\x50\xab\x9a\x50\x0c\x3a\xf5\x77\x53\xc0\xf0\x8c\x2a\xb7\x5d\x5d\x7c\x94\x46\x58\x00\x68\x7f\x86\xf0\xe4\xac\xb5\xe9\xad\x60\xf6\x6d\x26\x59\xcf\x3c\x0b\x0e\x48\xc0\x70\xc7\x40\xab\x20\xda\x82\x94\xfd\xd2\x5c\x9e\x75\x7a\x52\x33\x4b\x7a\xd3\x62\x29\x34\xea\x18\xf0\x94\x0c\x03\x6f\xfc\x3b\x51\xe1\xcc\x13\x6b\xa2\xf0\x47\x12\xe0\xc4\x8f\x18\xb4\x14\xf1\x08\x2c\x8c\x24\xf0\x94\xa4\x4a\xb7\x0d\x8d\xe2\x7f\x78\x0f\x36\x7f\x03\x3e\x8b\x80\x48\xa3\x82\x7a\x12\xfe\x8d\x25\x52\x48\x6c\x5b\x8c\x36\x70\x3c\x32\x67\xa8\x81\x6b\x6a\x05\x10\x71\x27\x8a\x1f\xd6\x92\xa8\x4b\x2e\x95\x7c\xa3\xb9\xea\x64\xab\x79\x44\xed\x34\xca\x54\x2d\xe2\xa8\x28\x74\x2f\x93\xe7\xff\xa6\x1d\x13\xb5\x44\x12\x47\xa4\x5e\xa8\x7c\x80\xe7\x34\x1a\x4d\xa1\x75\x63\x8f\xc9\x2c\x6e\x61\xe5\xc3\x16\xfa\x3d\x9c\xa9\xc0\xa1\xbc\xa1\x92\xd4\x96\x7f\xff\xaf\xff\xfa\x3f\xff\xf5\x7f\x03\x00\x00\xff\xff\x1c\xf7\x13\x7e\x95\xd2\x00\x00") - -func dataFemalenamesJsonBytes() ([]byte, error) { - return bindataRead( - _dataFemalenamesJson, - "data/FemaleNames.json", - ) -} - -func dataFemalenamesJson() (*asset, error) { - bytes, err := dataFemalenamesJsonBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "data/FemaleNames.json", size: 53909, mode: os.FileMode(420), modTime: time.Unix(1452717629, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _dataKeypadJson = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x9c\x94\xcd\x6a\x85\x30\x14\x84\xf7\x3e\x45\xc8\x52\xeb\xff\x5f\xec\x0b\xf4\x21\x4a\x17\xdd\x75\x21\xa5\x14\xba\x2a\xbe\xfb\xcd\xd5\x8b\x99\x91\xe3\x3d\xea\x46\x26\x42\xe6\x3b\x33\x1c\xf2\x1f\x19\x63\xdf\x7e\x3f\x7f\xbe\xec\xab\xb9\x1f\xfc\xb1\xf0\xf2\x7d\x96\xc6\x7c\xff\x8d\xe3\xcb\x43\xdb\xd2\xae\xb2\x0a\xb2\x0e\x32\x5b\x25\xde\xdb\xea\x59\x7e\x2c\x7f\xbc\xa7\x0c\x23\x70\x13\x10\xad\x38\x43\xb1\x0b\x26\x58\x05\x30\x4c\x23\xfb\x77\x4a\xc6\x0d\x95\x48\x35\x92\x2a\xc5\xfe\x59\x59\x32\x97\x58\xcd\x91\x0a\xfb\x70\xdd\x69\x6d\x96\xfb\xb9\x5a\xcc\x05\xb5\xc9\xf6\x83\x56\x26\x41\x09\xd4\x21\xa8\xd5\xdc\x13\xb5\x4b\xa6\x12\xaa\x3f\xd0\x1f\x59\xe5\x5a\x97\xcd\x7e\x81\x0e\x73\xf5\xe2\xd8\xe8\x1f\x6b\x65\x12\x95\x48\x03\x92\x60\x4e\xd9\x3d\xd5\xca\x64\x28\x91\x62\x24\xe5\xe7\xd6\x5a\xe4\x62\x56\xc7\xac\x04\x59\x83\x12\xe5\xc8\x04\x9b\x8c\x04\x4b\x11\x16\x5f\xb6\x25\x04\xa5\x24\x5a\x86\xb4\x42\x79\x6b\xaf\xcc\x40\xb4\xfc\xe4\xd6\x53\x08\x79\x2d\x1d\xbe\x07\x0b\xcc\x7f\xa7\x68\x8a\x6e\x01\x00\x00\xff\xff\x2d\x9a\xa0\x40\x67\x06\x00\x00") - -func dataKeypadJsonBytes() ([]byte, error) { - return bindataRead( - _dataKeypadJson, - "data/Keypad.json", - ) -} - -func dataKeypadJson() (*asset, error) { - bytes, err := dataKeypadJsonBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "data/Keypad.json", size: 1639, mode: os.FileMode(420), modTime: time.Unix(1452717629, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _dataL33tJson = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xaa\xe6\x52\x50\x50\x4a\x2f\x4a\x2c\xc8\x50\xb2\x52\x00\x71\x80\xdc\x44\x20\x33\x1a\xcc\x04\x72\x4c\x94\x74\x60\x4c\x07\x25\x30\x2b\x16\x22\xa0\x94\x84\xac\xcc\x02\x55\x2e\x19\x59\x4e\x03\x61\x44\x35\x82\x19\x8d\x60\xda\xa0\x6a\x4e\x45\xd6\x6c\x8c\x2a\x97\x8e\x2c\x67\x86\x30\xc2\x12\x55\x59\x26\xb2\x32\x43\x84\x32\x45\x04\xb3\x06\x55\x47\x0e\x0e\x1d\x35\x08\xa6\x39\xaa\x8e\x7c\x64\x1d\x06\xa8\x72\xc5\xc8\x72\x2a\x08\x23\x4c\x51\x95\x95\x20\x2b\xd3\xc6\x69\x53\x05\xb2\x32\x55\x54\xb9\x2a\x64\x39\x23\xa8\x1c\x90\xac\xe5\xaa\xe5\x02\x04\x00\x00\xff\xff\xd5\xd6\x71\x46\xdd\x01\x00\x00") - -func dataL33tJsonBytes() ([]byte, error) { - return bindataRead( - _dataL33tJson, - "data/L33t.json", - ) -} - -func dataL33tJson() (*asset, error) { - bytes, err := dataL33tJsonBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "data/L33t.json", size: 477, mode: os.FileMode(420), modTime: time.Unix(1452717629, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _dataMackeypadJson = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x9c\xd4\xcb\x4a\xc6\x30\x10\x05\xe0\x7d\x9f\x22\x64\xd9\xda\xfb\x35\x42\xd7\x3e\x84\xb8\x70\xe7\xa2\x88\x08\xae\xa4\xef\x6e\x6c\xa5\x39\xa7\x4c\x99\xd4\xcd\xcf\xf4\x87\xcc\x97\x39\x24\xf9\x4e\x8c\xb1\x4f\x9f\xaf\x1f\x6f\xf6\xd1\xfc\x7e\xf8\xcf\xca\x97\xcf\x5b\x69\xcc\xfb\xd7\xb2\x3c\xfc\xd5\xb6\xb6\x47\xd9\x84\xb2\x0d\x65\x71\x94\xb8\xee\x5c\x6f\xe5\xcb\xfe\x8f\xef\x29\x63\x04\x77\x81\xe8\xc5\x3d\x54\x97\x30\x61\x0d\x60\x38\x8d\xdc\x7f\x50\x66\x3c\xa9\x24\xb5\x28\x35\x5a\xfb\x4c\xcd\x8d\x59\xa2\xba\x98\x04\xc7\xb0\x7c\xd2\xc2\xac\xaf\xc7\xea\x71\x2c\x48\x4d\x6e\xef\xb4\x2c\x09\x25\x68\x40\xa8\xd7\xba\xe7\x5a\x94\x8c\x92\x34\x46\xc4\x47\xad\x66\x2d\xca\xee\x3a\xbf\x09\xc7\x1a\xe5\xad\x42\xff\x52\xcb\x92\x54\x92\x1c\x4a\xb0\x4f\xb9\x7b\xaa\x64\xc9\x26\x41\x29\x42\x65\xd4\x03\xa0\x46\x9c\xe3\xdc\xa4\x65\xa8\x0d\xca\x61\xb8\xed\xb6\x8c\xe5\x88\x39\x25\xb8\x28\x80\x12\x25\xab\x40\xab\x52\x1e\xda\xff\x84\x4b\x5a\x89\xda\x7c\x6f\x06\xf9\xac\x38\xbc\x15\x64\xcd\x37\x2f\x18\x61\xf2\x0d\x98\xf0\xe5\xd9\x31\xff\xbb\x26\x6b\xf2\x13\x00\x00\xff\xff\xa3\x67\xe0\x02\xd0\x06\x00\x00") - -func dataMackeypadJsonBytes() ([]byte, error) { - return bindataRead( - _dataMackeypadJson, - "data/MacKeypad.json", - ) -} - -func dataMackeypadJson() (*asset, error) { - bytes, err := dataMackeypadJsonBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "data/MacKeypad.json", size: 1744, mode: os.FileMode(420), modTime: time.Unix(1452717629, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _dataMalenamesJson = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x5c\x5a\x4b\xb6\xeb\x38\x6c\x9c\xf7\x2a\xfa\xbc\x71\x56\x90\x35\x64\x07\x39\x19\x50\x22\x2d\xd1\xa6\x48\x3f\x52\xb2\x5b\x37\x27\x7b\x0f\x28\xb1\x0a\x78\x3d\xd3\xf5\x95\xf8\x01\x0a\x85\x02\xc8\xff\xfd\xf5\x5f\xb1\xed\xbf\xfe\xf3\xbf\xff\xfa\xfb\xef\x5f\x4f\xb7\x85\xf6\xeb\x3f\xae\xc7\xb2\xe6\xfb\xa9\x96\x29\xd4\xfd\x7e\xde\xe2\xbc\xba\x90\xee\x3f\xbe\x31\xa5\xe8\xb6\xfb\x0f\xef\x3e\xd1\x8f\x0f\xfa\x4b\x75\xfc\xd1\x1f\x93\x0e\xda\xc2\x7b\xbd\x9f\xf7\xb5\x6c\xae\xe1\xa5\x2a\x8b\x28\xef\x35\x54\x8c\x96\x23\xa6\x79\xbb\x63\x3c\x6d\xae\xbe\xc6\xff\x4b\x76\x69\xcc\xb0\x84\x52\x97\x70\x3f\xbf\x42\xce\x61\x1f\x33\xb4\x3d\x7c\xc2\xd8\x44\xf0\x5f\x2e\x69\xaa\xd1\x71\x6f\x3a\x8e\xcb\xb2\xa4\x7c\x62\xa0\x4f\x1c\xef\x3c\x5d\x2b\x19\x0b\xd8\xf7\x35\x7c\xc7\xbc\xae\x8e\x97\xf7\xb8\x95\x7d\x3d\x75\x8f\xf7\x53\x72\x15\x6f\x3c\xc3\xe3\x51\xc3\xf8\xe3\x51\x5d\x1e\xfb\x68\x73\xd9\x87\x69\x83\x98\x8d\xeb\x16\x4b\x64\xac\xca\x57\xcc\x58\xdd\xb9\x95\x8c\x6d\xd7\xb0\x94\xaa\x93\xae\x87\xc3\x5c\x9c\xd6\x8b\x39\xe2\xb0\xf1\xd7\xa5\x1d\xe6\x7d\xbb\x5d\x66\x1b\x6b\x78\x07\xfe\x2e\xbe\x2a\x30\x87\x2f\xc7\x92\xe0\x20\x59\x0e\xc6\x9c\xc5\x9f\x63\x69\x75\x5f\x8f\xf1\x65\x3d\xd5\xa4\x0b\x86\x7b\x96\x61\x89\xe7\xe1\x68\x4c\x4c\xeb\x92\xc2\xea\x29\x6e\xd8\x57\xbe\x73\xb4\x1d\xc6\xdf\x75\x33\x32\x2c\x7d\xf5\x0a\x91\x5e\x76\xdb\xf1\x07\x22\x03\x8c\x95\x00\xb5\xe4\xbe\x35\xe4\x79\xfc\x23\x0b\x3c\x0b\x77\x56\xcb\x18\x7e\x0a\x59\xe0\x8f\x79\xa7\x7a\xe0\xfd\x49\xdc\xe5\x81\x00\xe7\x01\xf8\x55\xbd\x2b\xae\xf5\x30\xf2\x99\xf1\x99\xac\xe5\x34\x40\x1c\x4b\x29\x07\x1c\x22\x7e\x0a\xdb\x78\xc3\x89\xe1\x61\x3f\x99\x6d\xfc\x1a\x8e\x25\x60\xb8\x6e\xf6\x82\x35\x1f\xad\x85\x34\xf6\x3c\x95\x69\x1a\xef\x7f\xe2\xbc\x97\x0a\x38\xe5\xd0\x86\x79\xdf\x6b\xb7\xcb\x7b\x58\xb4\x78\x8f\x05\x34\x40\x75\xae\x2e\x2e\xf0\x0b\xfc\xd0\x56\xf7\x1d\x8f\xb3\x60\x59\x2d\xd8\x02\x5e\xe9\x23\x63\xe0\x2b\x88\x95\x3c\x10\x49\x81\x78\x79\xc6\x8d\xfb\xcd\x7b\xc9\xb1\x30\xd8\xf1\xf2\xa4\x38\xda\x19\x8b\x89\x26\xdb\xe2\x0b\x4b\xd8\x5d\x4e\x08\xa8\x14\x04\x3f\x88\x6e\x8b\x24\xef\x52\x40\xe4\x66\xa2\xa4\x16\x9f\xf1\xe9\x7c\xd4\x1d\xa3\xe7\x52\x37\xc7\x48\xaf\x24\x00\x79\x98\x43\x1e\xb6\x5c\x92\xc4\x94\x06\x75\x20\x07\x54\x21\xc0\xa6\xff\x20\xfb\x79\x02\xbf\x4c\x63\xec\x90\x38\xb6\x4b\x0a\x9e\xd7\x89\xd5\x76\x86\x98\x31\x9a\xe0\xcf\x73\xab\xe2\xb3\x83\x31\x59\x35\x82\xfa\x28\x41\x63\x5a\x98\x82\x21\x98\xc8\x80\x98\x94\x68\x0e\xde\x33\x5c\xe4\x5b\x6e\x05\x31\xd1\xb1\xe8\x08\x34\x05\xbc\xcc\xab\x06\x17\x53\xc1\x93\x29\xf0\xd3\xb1\x85\xb9\xf0\xa5\xf9\xa0\x17\xe7\x35\xb8\x31\xaa\xf0\x69\xf1\xa5\x02\x87\x29\x3e\x1e\x85\x23\xc7\x85\x4e\x2b\x4d\x22\x00\xa6\x3c\x09\x28\x60\x65\x43\x94\x58\xd3\x86\x7f\x48\x2f\xf0\xbc\xf0\xa1\x89\xcf\xb1\xea\x54\x4e\xcf\x81\x36\x03\x2a\xb0\x68\x0d\xc8\x3b\x62\x03\x46\x9e\x04\x70\xd9\xe0\x31\x1d\x43\x3e\xc4\x02\xb8\x96\x1d\x2b\xfd\x86\x46\x5f\x7a\x86\x51\xe7\x72\x2c\x95\xb9\xcc\x1b\x1a\x7c\x07\x5f\x0b\x57\xa3\x7e\xf6\x18\xe1\xc7\xf5\x44\x0b\x50\x17\xe6\x1a\x01\x89\xc1\xf4\x21\x5f\x8e\xd1\x3f\xe2\xc2\xf2\x47\x86\x2f\x70\xc1\xe9\x83\x62\x1d\xc3\x28\xb3\x08\x2d\x64\x05\x8d\xc0\xa0\x90\x88\x15\x4a\x30\x45\x63\x6e\x99\x2a\x63\xa8\xba\x0d\x53\xef\x82\xf9\xf1\xc2\x12\x4d\x46\x50\xe2\xeb\xc8\x19\x9f\x85\x25\x6a\xba\xae\xc7\x14\x48\xd6\x01\x59\xd4\xe5\x05\x88\xb9\x89\x80\x32\xa2\xba\x87\xd3\x58\x58\x00\xa6\x2d\xa6\x5d\xa9\x17\x4a\x83\x43\xcf\x61\x8e\x09\xfe\xe0\xbe\xaf\xa4\x3c\x86\x4a\x9b\xee\x10\xc1\xbe\x38\xd1\x18\x4a\x37\x34\xb3\x50\x2b\xe9\x80\x61\xef\xbc\xea\x91\x17\xc9\x72\x66\x6e\x17\xee\x3d\xe0\x11\x09\x71\x83\xc4\x13\x3b\x0d\x58\xe3\x2d\xa4\xa2\x66\xdb\x4f\xc4\xea\x1e\x3d\x66\xb3\xa7\x97\x63\xe6\xbe\xf7\xc0\x50\x56\x79\xb3\x9f\xb2\xf0\x60\x60\x3f\x5e\x4e\x26\x86\x64\x3f\xc0\xd3\x5c\x90\xb5\x9e\x47\x02\x1f\xbc\x0e\xf8\x53\x58\xc4\x69\x2e\x39\x39\xf5\x7a\x2c\x2b\xe6\x1e\xd1\xea\x4d\x12\x15\xce\x5a\x56\x0c\xd1\x91\x8c\xf5\x3f\x42\x8a\xff\x90\x05\x36\x2c\x48\xf2\xac\x62\x41\xad\x4a\xa0\x80\x82\x9f\x2e\x6e\x4c\xac\x0d\xc1\x72\x93\x31\xa3\xd7\x04\x85\xa8\xdb\xf1\x7a\xfc\xd0\xb8\x3d\xc9\x61\xe2\x16\x35\xa7\x4c\x27\x5d\xde\x6d\x81\xf7\x63\x73\x6e\x56\x9a\xa3\x09\xba\x68\x21\x99\x8a\xa5\xe1\xd5\x4f\xac\x0b\xfc\xaa\x9a\xa0\x09\xab\x38\x8f\x58\x7c\x45\x28\xe2\x16\xe4\x6d\x44\x22\x25\xf0\x8b\x31\xd7\x85\x94\x7a\xab\x32\xbc\x82\xc0\x9a\x21\xdc\x5f\xd2\x34\x2f\x9a\x2f\xfe\x3e\x98\x92\x4c\xb2\x68\xbb\x7c\x64\x32\x8f\x46\xbc\xfc\x7c\x54\x5a\x30\x3c\x7b\xa4\x14\xd8\x0b\x06\xca\x4a\x10\xc7\x4e\xcd\xff\x0d\xd9\x5b\x6e\x0d\x5b\x74\x2b\xdc\xea\x8c\x41\x91\x47\xbc\x41\x62\x61\x16\xdf\x6b\xf8\xc0\x3c\xe9\x80\x5e\x90\x62\x83\x3c\x23\x3a\xb2\x1a\x91\x4b\x4b\x41\x6f\xac\x87\xf2\xd0\xc5\x27\x85\xc4\x77\x20\x08\x4e\x15\x16\xa4\x9e\xf4\x28\xb9\x8d\x77\x4b\x4d\x0a\xd6\x8a\x44\xd4\x45\x1c\xfd\x7e\x2b\xb4\xf1\xca\xdb\x4d\x98\x26\x09\x7b\xe7\x1f\x8c\xb3\x81\xa8\x04\x26\x13\xd4\xf6\x94\x9c\x6e\xac\x3a\x7a\xb5\x58\x0d\xf0\x52\xe9\x2c\x74\xe4\x56\x4b\xcf\xf0\x44\xac\xce\x30\x1a\xaa\xb1\xd0\x98\x6a\x05\xe3\x46\x4f\x6d\x2e\xcd\x25\x61\x9c\xc3\x17\x4a\x6c\xaf\x94\xfe\x32\xf2\x46\xde\x19\x33\xbd\x6b\xdf\x2c\x53\xb3\x3e\xd6\x79\x8d\x86\xea\xc7\xbe\xbf\x63\x92\x5e\x9c\x80\x9c\xb3\x99\x6f\x71\xa6\x2e\x28\xa6\xb8\xba\x4b\x09\x8c\xde\x69\xe2\x8d\x84\x1f\x14\x2e\x37\x06\x0a\x42\x00\x60\x10\xf9\x8f\x22\xec\xf2\xc2\xf8\x3d\x98\xc4\x24\xfb\xc7\xe6\x96\x43\x22\x57\xf2\x2b\x86\x71\x46\x72\x4f\x0a\xa7\x5c\x8c\xf0\x2c\x02\x92\xb1\x59\x65\x89\xe0\xb7\x03\x89\xe1\x8a\xef\x5d\x05\xd1\x15\x5c\x58\xd2\x97\xf1\xd1\x15\xc3\x02\x58\x9a\x1c\xef\xb5\x6e\x6d\x67\xfa\x98\xfc\x5b\x8b\x14\xa6\x9f\x90\x40\x8e\xad\x32\x1d\x3e\xfb\x00\x11\x8c\x20\xfa\xab\x72\x1f\x5f\x9b\x94\x53\xd0\x04\xd6\x22\x1d\x1e\xbb\x54\x1e\x8b\x91\x25\xd2\xf5\x0f\x04\xea\xb7\x14\x61\x81\x91\x57\x5e\xff\x2a\xf5\x93\xac\xd8\xb8\xbf\xc1\xb6\xa2\xf0\x3f\x88\x88\x28\x99\x48\x7b\x00\x3b\x1c\x1f\xd3\x1f\xba\x25\x82\xeb\xc4\x89\x5a\xe0\x49\xf6\x34\x9c\x16\xdb\xc6\x6d\x17\x59\x77\x42\x1c\x6b\x95\x1d\x54\xf9\xfb\xf0\xd5\xdc\x40\x83\xa8\x62\xef\x65\x37\x38\x63\x19\xeb\x88\x4b\x76\x33\x98\x58\xf4\x68\x18\x29\x67\xd7\x76\x87\x78\x2c\xa9\x06\xd7\x88\xbd\x1a\x03\xd1\xe6\x5c\x02\x47\x58\x28\x2a\x49\xeb\x7e\x9c\xa4\x63\x70\x85\xbc\x82\x19\xd4\x67\x16\xbb\xa2\xbb\x22\xd8\x78\x2e\x99\x72\x25\x17\x10\xed\x22\xbf\x21\x60\xd7\xa8\x52\x44\xcc\x4f\xda\x4d\x8e\x9c\x74\x2b\x1a\x3a\x00\xba\xfc\x1d\xea\x4c\x8d\xfb\xcf\x6e\xf5\x91\x11\xf7\xa1\x26\xdd\x2a\x45\xfb\x06\x04\x5c\xb9\x08\x70\x97\x5f\xc1\x4e\x51\xdd\xd3\xa8\xd7\x44\x88\x6b\xcd\xd7\x57\x9b\x94\x34\x58\x69\x14\xd5\x09\xbb\x96\xa2\xdd\xce\x5a\xf5\x4b\x0e\xd2\x02\x94\x75\x35\x7e\x72\x13\x3c\x32\xb8\x62\x38\x4e\x52\x15\xdd\x23\x96\x7a\xc2\x9c\x33\x25\xf9\xf5\x3e\x20\xe2\x8e\x89\x7c\x15\xb6\x8d\x82\x65\xeb\x35\x3e\x60\x61\x2b\xd6\xa7\x69\x7d\x08\x59\xb0\x07\xd4\xe7\x25\x52\x55\x35\x95\x7d\x27\x56\x3c\xfc\x29\x33\x76\xf1\x5c\xb8\x53\xf4\x5e\x42\xd3\xcc\x89\x08\x5a\x8f\xcd\x84\x96\xac\xd1\x2c\xe6\x6a\x4f\x39\xaa\xc1\x03\x36\xfd\xc4\x5e\x25\x53\x19\xca\x2a\x77\x72\xb5\xf2\x86\x14\x7f\xcc\xea\x82\xf7\xc8\x02\xc3\x41\xb3\x08\x4b\xb2\x83\xe4\x83\x58\xa7\x12\x7a\x41\x53\x91\x89\xa0\x5a\x58\xba\xbe\x63\x47\x0d\x1d\x81\xbd\x9e\x0c\x17\x11\xbd\x24\x3a\x29\x7b\xa6\xa8\x8d\x43\xad\x74\xa5\x88\x65\xab\x43\x60\x98\xc8\x6e\x4b\x2d\x1f\x2c\x2d\x68\x0e\x9b\x53\x27\x56\x6e\xd1\x9f\xaa\x75\xd7\x43\x4b\xb5\x4d\xdb\x8e\x41\x8b\x97\xde\xc9\x00\x13\x5e\x6d\x0c\x88\x86\xab\xc9\x03\x8e\x60\xed\x2e\xdf\x45\xf8\x45\x8c\x81\x92\xba\xd0\xf2\xa2\x0d\xb8\x43\x91\x18\xd8\xe0\x4c\x29\x2e\x92\x2e\xb3\xb0\x74\x8b\xa9\x32\x9f\x12\xd9\xc4\xd3\x47\x5b\x5e\x9a\xb4\xf6\xb3\x19\xd9\x6a\xd4\xf2\x44\x3d\x28\x95\x8d\x78\x90\x81\x03\x43\xfa\xc0\x4e\x64\xb7\x44\xa0\x88\x76\xbf\x0f\x82\xe0\x02\x0a\xde\x6f\x06\xe7\x49\xc2\x6b\x67\xbc\xd2\x18\x77\x0f\x94\xd5\x86\xa4\xb1\x08\xaa\x2b\x6d\x46\xf7\xb1\x27\xc1\x89\x21\xac\x65\x4f\x2b\xa9\x30\x89\xe5\x52\x2d\x69\x92\x63\x72\x51\x67\x3a\x46\x2d\x77\xd8\x17\xaf\xc5\x0c\xac\x37\x29\xb0\x2b\x4a\x8e\x90\x7a\x1a\x54\xb4\xd9\x22\x5e\x11\xbe\x95\x48\xa6\xeb\x74\x80\x61\x1e\xd1\x07\x76\x4c\x9c\xf7\x01\x1f\x5c\x1d\x13\xbe\x3f\xe3\x25\x07\xf0\x57\xf7\xd6\x8e\xbd\x44\x82\xea\xae\x8d\x80\xed\x92\x83\x2a\xbd\x77\xaa\x49\x8d\x00\x92\x68\xf7\xa6\x8d\xfb\x43\xf5\x46\x0e\xd4\x2d\xca\xae\x02\x5d\xe4\xe8\xab\xd7\x93\x14\xa4\xb4\x1f\x7b\xa7\x6e\x32\x61\xb1\x2c\x0c\x48\x36\x13\xa5\x6e\x62\x21\xb0\x60\xdb\x52\x8f\x61\x04\xed\xbc\x48\x7d\x42\x8a\x35\x5a\x71\xb3\x05\x96\x90\x05\x34\xe6\x22\xa9\xd3\x25\x6d\xab\x68\xf7\x4c\xe4\x4a\xc4\x48\x8b\xca\xe8\xfe\xa3\xa1\xc5\xde\x60\x56\xc5\xcf\xad\xc9\x30\xd8\x44\x2e\xa6\xdb\xa2\xd0\xd2\x24\x6d\xe2\xfd\xee\xce\x00\xcb\xab\x28\x73\x9c\xac\x94\x5c\x98\x81\x26\xd7\x40\xf9\x3d\xfd\xa8\xcc\xe9\x27\x09\xe0\x61\x06\x5d\x47\x27\x32\xb1\x66\x82\x26\xd1\x60\x9a\x04\x8f\xbb\x73\x38\x26\x3e\xd2\xd9\x88\x40\x11\x69\xd1\x56\xc1\x52\x70\x31\xb5\x7a\x55\xb8\x8b\x63\xb8\x08\x5f\xd3\x5a\x52\x72\x01\x54\x4e\x79\xc3\x47\x3e\x39\x92\x96\x30\xe8\xc6\xe4\x33\xa3\x87\x58\x4c\x3d\xd8\xfb\xb1\x6c\x88\x1e\x19\x62\xab\x35\xd4\xd4\xfe\xd0\x2e\x69\x73\x59\x85\x86\x68\xc1\x49\xcf\x2e\x36\x96\x73\x57\xf5\x85\x83\x8f\x22\x0c\x03\x4b\xee\xe1\xe1\xb4\x53\x8a\x4d\x92\xe0\x24\x26\x35\x92\xa7\xe0\x8e\xc1\x87\x26\x23\x2d\x8e\x9d\xb3\xd8\x22\x2b\xe0\xbd\x1e\x46\xa8\xa7\xed\x5f\x55\x16\x79\x29\xd2\xab\x68\xeb\x8e\xb1\x94\xf9\xb6\xde\x05\x4c\xec\xfa\xf4\x33\xb6\xd3\xb2\x40\xcc\x54\xa0\x35\x71\xfa\xa0\x5c\xf5\x32\x8d\xef\xae\x90\xa9\x5f\x64\x0a\x15\xb8\x1f\xe6\x9a\xb9\x5b\x88\x6b\xcf\x1f\x95\xef\xaa\xcd\xc3\xc6\xb0\x7e\xbb\xf6\xfb\xd0\xee\x7b\x91\xea\x73\x73\xa6\x61\xec\xb2\x36\xff\x23\x68\x33\x99\x83\x16\xcf\xce\xc6\x75\xfe\x12\xf4\xfc\x05\xcc\x73\x49\x14\xb2\xa0\x8b\x50\x99\x87\xba\x7e\x31\x95\xd1\x64\x92\xa1\xe4\x2e\xb6\x03\x3a\x62\x09\xce\xde\x46\x25\x80\x9f\x6e\x96\x5c\x09\xe9\x21\x59\x0d\x58\x2c\xed\x60\xf7\xe4\xab\x11\xdc\x33\x22\xa7\xee\x7d\x0d\xed\x2b\x9e\xbd\xc0\xe3\x8e\x59\x59\xee\xbd\x16\xd2\x83\x33\x1e\xe4\x88\xa5\xc5\xde\x9a\x95\x59\xb5\x66\xf2\x74\x99\xa5\x3e\x62\x99\x51\x8c\xe6\x5d\x0f\xc8\x95\x9e\x89\x6d\xda\xd3\x9e\x70\x53\x56\xee\xe4\x3f\x86\x8f\x9d\x67\x72\x04\x86\x2b\x14\xd9\x7c\x56\xa6\x9b\xb3\x46\xed\x6b\x66\x73\xc0\xc5\x9e\xa0\xf6\x01\x64\xac\x5d\x95\xf0\x46\x59\xe2\x8e\x5b\x75\x68\x53\x73\x5e\x89\x64\xff\x25\x0f\xdf\x2d\x0f\xd6\x93\xd0\xa9\xdb\x69\x0e\x94\xb3\xe3\xa9\xc2\x6e\x52\x8d\x29\xe2\x7e\x34\x8b\x89\x25\x09\xb5\x1f\x57\xff\xe4\x71\xd3\x67\xd0\xba\xc3\x3d\x8b\x09\xd2\xc8\x81\xaa\x69\x39\x6b\xab\xd7\x4d\xfe\x60\xb7\x98\x39\x30\x1d\xb3\xe2\xbd\x85\x73\x2b\xe8\xe3\x5c\xc7\xbf\xec\x5d\xf6\xd3\x3e\x78\xf4\x8e\x18\x86\x61\xe7\x13\xd5\x6c\x35\x1f\x54\x64\x7d\xf0\x40\x26\xaf\x3e\x66\xa6\xf5\x9d\x87\x4f\xe1\x87\x7d\x9e\xa4\xfa\x72\x52\x8d\x72\x22\x04\x2f\x2b\x8e\x8f\x1c\x0b\x34\xa9\x7b\x18\xba\xbf\x79\x1a\x97\xf4\xdc\xee\x25\x98\x0e\x1b\xad\x0c\x62\x9b\x8a\xc9\xe2\xda\xcd\x93\x84\xac\xdd\x73\x38\x81\x50\x15\x46\x79\x17\x2e\x73\x74\x74\xa9\x43\x5a\x78\xe0\xd3\xc2\xda\xca\x1e\xe8\x1b\x61\x55\x43\x34\x25\x4f\xb7\x14\x45\x8e\x6a\xd4\xaf\xe9\x4b\xf5\xc8\x20\x86\x24\x25\x1d\x0a\x17\xcd\xe0\x13\x95\xf4\xf3\x20\x10\xd9\xa9\x15\x22\x6d\x3c\x00\x5a\xc9\x79\x39\xf2\x5c\x42\xca\x1e\x3d\xdc\xdf\xbf\x14\xa6\x89\x24\x27\xf6\x93\xe8\x23\xf5\xd6\xf0\x38\xd8\xdb\xf5\x64\xf6\xd2\x3e\x66\x73\x58\x48\x3f\x54\xe2\xe1\xc4\x7d\xa2\x09\xd1\x19\xd9\x16\x8e\x9f\xa2\xe7\x96\xec\xca\xde\x0a\x18\xd9\xd1\x89\x13\x78\x04\xd6\x8f\xba\x50\x80\x3e\x64\x65\x3f\xb0\x76\x0b\xe4\xb5\xcd\xd2\x9f\x64\xe0\x05\x0b\x62\x99\x34\x6e\x79\x80\x79\xaf\x86\x29\x9a\x17\xe9\xdc\xb4\xb1\xae\x58\xe9\xe4\xaf\xad\x28\x3d\xa9\xa1\x5e\xe9\x68\xd3\xa2\xe5\x1b\x11\x95\x93\x4d\x76\xa2\x7a\xd1\x9f\x52\x45\xed\x2e\x0e\xd2\xe6\xc5\xe1\x09\x8f\xc3\x33\x23\x2c\x7c\xe5\x3a\x34\xd2\xd3\x81\x30\x1b\x2e\x60\x07\x31\x2b\xb3\xe7\xe8\xe1\xfd\x1d\x0f\xef\x52\x1f\x91\x05\x4b\xf1\x0c\xa5\x90\xed\x8d\x99\x43\x14\x1c\xfc\x53\xd8\x2f\xd1\x0e\xd8\x4c\x11\xf3\xa2\x23\x6f\x52\x05\x4f\xbf\xf4\xea\xcb\x2a\x72\x82\x53\x4e\x87\xf6\x19\xc7\x22\xea\x87\xc1\xef\xd8\xbb\xef\x67\xf2\x20\xa6\xfb\x6c\x91\x2e\x29\x49\xe1\x1b\x27\x25\x8e\xc4\xe0\x52\xfe\xc9\xe3\x1b\x71\x92\x22\x95\xac\xb1\x17\x55\xd6\xda\x05\xbe\x3a\xda\x5c\xaf\x9e\x58\x5e\x94\x48\x4b\x9b\x73\x37\xaf\xdb\xdb\xa0\x06\x7b\x62\x58\x4d\xb0\xf3\xd4\xb0\x4c\x68\x71\xe8\x25\x1c\x26\xcc\x7a\xbc\xb5\x59\x56\x92\x96\xf4\x2f\x03\xa6\x5e\xbe\x2a\xa4\x23\x23\x99\xa7\x65\x5f\x0d\xcb\x71\x38\x42\x2c\x7b\x5c\x09\x79\xe1\xd6\x84\xb0\x09\xea\xba\x53\x38\x14\x4b\xee\x37\x0b\xd8\x7a\x5c\xb9\xed\xaf\xbd\x54\x62\x45\xae\x76\xab\xb7\x22\x14\x06\x9f\xbc\x48\x3a\xb9\xcc\xab\x46\x06\x65\xd6\x55\xbf\x9a\xfa\x3f\x12\xf8\x8f\xab\x03\x3e\xeb\x25\x0d\x73\xec\xbc\x97\x29\x6a\xde\x85\x93\x57\x27\x6a\x9c\x61\x73\xb4\xf0\x7e\xb3\xf8\xb7\xe7\xff\x22\xf6\x89\xd3\xbe\x69\x9e\xc3\x9f\xba\xae\x57\x90\x88\x40\xa7\xa1\x9f\x94\x54\x60\x2a\x68\x5d\xa6\x76\x16\xb5\x24\x72\x90\x13\xac\x81\x6d\xf8\xba\xb3\x90\xea\xd7\xc7\x78\x79\xe2\xe0\x09\xb9\xa1\x15\x51\x73\xe6\x8e\x04\x92\xce\xae\x9d\x7a\x3d\x45\xba\xaa\x52\x0c\x16\x85\x2b\x49\xd7\x8f\xde\x86\xd0\xfe\x0f\xc5\x98\xff\xe3\x44\xb1\x6b\x11\x84\xc1\x75\x03\x02\x08\x96\xea\x31\x1b\x31\xff\x4f\x44\x86\x6c\x85\x4d\xcd\x14\xe2\xa2\x77\x9b\xfe\xe8\x07\x4f\xdc\x6e\x75\x4d\x05\x80\x14\xe7\xbb\x36\x50\x14\xbe\x24\xc6\x7e\x8d\x8a\x94\x20\x91\x0b\xe7\xfe\x66\x0e\x0c\xe2\xd1\x29\x6a\x29\x08\x7e\x17\x9b\xf0\xd4\xc4\x1b\xc9\x79\x1f\x1d\x8c\xb5\x88\x37\xd9\xb5\x2a\x27\x43\xf0\xd4\x4a\x2a\xfc\x84\x17\x85\x94\x10\x4e\xb3\x30\x54\xa2\x0e\x89\x57\x4c\x46\xd1\x88\x9d\x57\xe6\xcf\x1c\x4c\x63\x3f\x78\xc5\xb4\x0f\xf6\x4e\x93\x53\x49\x2f\x3f\xb3\x7b\x3a\xee\x0d\x38\xaa\xfd\xea\x4d\xc5\x4a\x9a\xbb\x32\xc6\xfd\x48\x02\xed\x47\x31\xba\xa3\xfb\xba\x1e\x9f\x4d\x45\x7a\xe5\x41\x52\xa7\xdb\xa6\xca\x4b\x83\x7b\x64\x6c\xac\x9a\x12\x1f\xa6\xdb\x28\x86\x92\xa8\xd5\xd6\xa0\x6b\x1b\x4f\x0e\x49\xad\x5a\x7f\xbe\x48\x06\x6c\x64\x69\x75\x28\xc9\x0b\xab\xed\xd7\x89\xc0\x65\x22\x20\x78\x3f\x6e\xa5\xd0\x7d\xf2\x1a\xc2\xb8\x1b\x88\x70\x93\x8d\x31\x88\x4b\x33\xf4\x27\xbf\xb6\x6f\x61\x1d\x71\x9f\x68\xf3\x1c\xa3\xf0\xc4\xfc\x36\x39\xdb\x54\x6c\x75\x4d\x21\x8b\xfb\xe6\x9d\xcc\xc6\x14\x01\xf4\xc5\x56\x79\x95\x68\xb9\x54\xf9\x30\x58\xcf\xee\xc8\xd5\x0d\xe2\xb7\xd2\x2c\x3f\xbc\x87\xb8\x15\xaf\xc7\xb0\xd7\xad\xa5\x60\x6e\x2d\x65\x06\xc5\xd3\xa1\x0a\x73\x67\xd2\x0a\xd3\xa9\x7a\x7c\xc8\xde\x6c\xb7\x24\xd8\xc3\xe3\xeb\xe6\x2c\x30\xb9\xc8\x34\x06\xa2\x5f\xed\xf8\x25\xdc\xef\xe8\x0b\xd4\x0b\xa6\xbc\x3f\x99\xf5\x9a\xd6\xfc\xaf\x83\x34\x49\x41\xb1\xe8\xad\x99\x34\xe3\x52\xd4\xab\x98\xd3\xd1\xf6\x0e\x2b\x39\x53\xef\x20\xf4\x3d\x8d\x67\x36\x7e\x57\xb1\xb7\x63\x7c\xa8\xb0\xa3\x2e\xed\x07\xc0\x43\x8d\x57\x7d\x62\x8f\x34\x18\xf1\x7d\x8b\x96\xc4\x33\x24\xd1\xe2\x94\x2a\xd7\x3e\x1e\xe6\x0e\xaa\xe6\x5d\x29\x75\x8a\xa9\x58\x02\xbb\xe6\x29\x98\x9b\x05\x2f\xbd\xbd\xf8\x0c\xff\xbe\xa0\x05\x9a\x37\xb7\x98\xe7\x3f\x6f\x2c\x24\x6d\x0b\x98\x8c\x2a\x30\x4e\x7a\x01\x71\x19\x79\x5e\x84\x00\x55\xf4\x53\x64\x0a\x8d\xb1\xe8\x1a\xae\x63\x3c\x49\x66\xe0\x1f\x53\xfb\xb7\xc8\x4b\x62\xf1\xc1\x45\x3a\x2c\xf2\xbe\x51\x0d\x3f\x5c\xd7\x0e\x7f\x78\xf9\x80\x97\x90\x2f\x24\x8d\x61\x4e\xd3\x8b\xea\x77\x26\x60\xc3\x88\x00\x24\x29\xf6\xb6\x03\xaf\xf2\xfd\x79\x53\xa0\x1f\x22\xb6\xf2\xeb\xaf\xff\xf9\xbf\xbf\xfe\x3f\x00\x00\xff\xff\x45\xf8\xc0\x95\x0f\x2e\x00\x00") - -func dataMalenamesJsonBytes() ([]byte, error) { - return bindataRead( - _dataMalenamesJson, - "data/MaleNames.json", - ) -} - -func dataMalenamesJson() (*asset, error) { - bytes, err := dataMalenamesJsonBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "data/MaleNames.json", size: 11791, mode: os.FileMode(420), modTime: time.Unix(1452717629, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _dataPasswordsJson = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x4c\xfd\xeb\x72\xf3\x3a\xd0\x2c\x8c\xdd\x0b\x7f\x24\x55\x7b\xbf\x3b\x65\xc9\xe7\xe4\x16\x72\x07\xf9\x91\x02\x49\x88\x84\x44\x12\x7c\x78\xd0\xe9\xbb\xf9\x6f\xa6\xbb\x21\x2f\xfb\x59\x65\x2d\xd9\x92\x48\x60\x30\xc7\x9e\x9e\xff\xab\xfa\xff\xa6\x75\xab\xfe\xdf\xff\xbf\x6a\x0e\xeb\x7a\xcb\x4b\x5b\xfd\x4f\x75\x38\xbe\x7f\x7c\x7e\xbd\x1e\x7c\xff\xe8\xa1\xfd\xf8\x77\x8b\xcb\xf6\x28\xbf\xb2\x9f\xed\x12\xba\x3c\xd9\x83\x79\x5f\x57\xff\x45\x1d\xd6\x58\x87\x61\xb0\x87\xa7\x9c\x37\x3d\x1c\xe2\x36\xc6\xe4\x7f\x37\xe6\xe9\x12\xfd\x0f\xbf\x7e\xfd\xdb\x1e\x84\xba\xb1\x77\xf3\x5f\xed\xeb\x16\xa6\xce\x1e\xad\x7d\x68\xf3\xcd\x9f\x0a\xeb\x16\x17\xff\x3c\x7c\xd9\x83\xe3\xdb\xdb\x9b\xfd\x38\xdb\xa5\x06\x7f\xbf\x75\x9f\xe3\x32\xe2\x61\x1f\x96\x21\x3e\xfe\xae\xdb\x2f\x61\x6f\x2e\x63\xf4\xdf\xed\x13\xdf\xc8\x9f\x79\xe4\xdd\x1e\x6d\x8b\x7d\xde\x94\xfd\x4d\x17\xfb\x58\xfc\xb6\xde\xf5\x79\x5b\xea\xf8\xcc\x9a\x9b\xe6\xf5\x42\xdc\xdf\xc6\x4f\xdb\xa2\x2d\xdc\xff\x60\xdd\xec\xc7\x25\x0d\x03\xfe\xac\xcf\x0d\xef\xaf\xf1\xcb\x49\xfe\xd9\x43\xbe\x46\x5c\xe9\xb4\xf6\x69\xf2\x87\xf6\x9a\x3e\x0f\x51\xab\xe0\xef\x12\xe7\x19\x2f\x0f\xf6\x69\x78\xc3\xb2\xf6\xfe\xdb\xaf\xcf\x8f\xf7\xe3\x01\xcb\xd1\x75\x78\x4b\x5b\xa8\xe5\x16\x16\xff\xc3\x35\x0d\x57\xbc\xb4\xb5\xa5\x0e\xfe\xcc\x23\xd8\x12\x47\xbd\x09\x97\xf6\x0b\x5f\x7e\x79\x71\x18\xb2\xfd\xcc\xb8\x65\xbf\x9f\xb4\x45\xac\xd0\x69\x89\xb1\xcd\xa3\x5f\x79\x1e\xe7\x9d\xcb\xb0\xc6\xbb\xdf\xcb\x66\xcb\xd7\xe2\x89\x2e\x69\xa5\xfa\x30\x8e\xfc\x93\x5d\x0f\x9a\xbc\x5c\xe3\xb6\x45\xad\x15\x6f\xc7\xd6\x13\xdb\xae\xdd\xb3\xbf\x1c\xf8\xff\x47\xff\xf6\x37\xcc\xc3\x89\x2f\xef\xed\x9a\xfd\xc5\xf3\x92\x26\x2d\x82\x3d\x37\xac\x31\xf8\xcd\xa5\x60\x92\xe3\xd2\xf9\xf0\x3b\xb8\xe1\xca\xbb\x36\x43\x5a\x62\xb3\xc4\x0d\xcb\xda\x9e\xba\xde\x9f\x99\xc3\x72\xc1\x26\xe4\x5b\x9d\xf1\x20\x8c\x61\xc9\x58\xc2\x6d\x49\x77\xbf\xc6\x30\x34\x90\xdc\xe4\xfb\x43\x91\xe8\xf6\x64\x0b\x0b\x69\x5e\x66\xec\xcf\xda\x98\x10\xe3\xfa\xe6\x3e\xc7\x09\xaf\x0c\xf8\xa2\x90\x44\xec\xc1\x9c\x97\xd5\xae\xd5\xdf\x3e\x69\xfb\xc7\x60\xbb\x92\x20\x32\xf6\x16\x17\xec\xda\x14\xd6\x86\x6f\x1f\xc3\xb4\xfb\x15\x1f\xde\xfd\x9b\xc7\x02\x2f\xeb\xf3\x32\xf9\xcf\xd5\xae\x77\xda\xfa\x00\x09\x9b\xb6\x84\xed\x34\xd9\x8c\x03\x3f\x71\x9d\x72\x9e\x71\xde\x72\xe6\xf2\xdf\xfa\xb0\x45\x4a\x42\x6a\x22\x65\x74\x1d\x33\xaf\xa6\xb3\xdf\xdd\xc2\x03\x52\x72\xc9\x5b\x78\x2d\x8d\xbf\x57\x0c\xdd\x10\xb9\xdc\x7e\xf5\x13\x96\x9b\xc2\x3e\x04\xfc\x7c\xde\x9b\x6b\xed\xcf\xdb\x56\x2d\x61\x49\x2e\xf0\x53\xea\xfa\x8d\xa7\xae\xb5\xad\x8f\x12\x9c\xf0\x0f\x0f\x4e\xa7\x18\x79\x75\xf6\x8f\x62\xd6\xf4\x38\x60\xc3\xc0\x5d\xbb\xe3\xcb\x2f\x3c\xda\x46\x40\x04\xe7\x21\x3c\x70\x03\x53\xd3\x1c\xbe\xdf\x5c\x60\x6e\xe9\x19\xa0\x94\x7c\x23\x6a\xbf\x81\xf3\x3e\xa5\x8c\xbb\xf4\x13\x3d\x61\xe3\x5d\x14\x74\xc5\x26\xd7\x2d\x44\x36\x4e\x53\x5a\x71\x0f\xf9\x76\xce\x35\x8e\xee\x64\xdf\x5c\x6c\x1d\xf3\x75\x4e\x94\xeb\x21\x5c\xb8\xb0\x4b\xa8\xed\x5a\x7d\x55\xa4\x30\x6c\x75\x9b\xd8\x62\x7d\x4e\x51\xa7\xe0\x61\xbb\xd3\x4b\x2c\x6b\x9c\xa7\x3a\xaf\x1b\xa4\x09\x32\x81\xfd\x5f\x78\xd6\x7d\x51\x4d\x47\xbe\xb4\xcc\x8a\xed\x98\xec\xb4\x9e\x70\x7f\xfa\x18\xbb\x85\x2d\x6d\xb8\xe0\xb0\x50\x16\x96\xe0\x17\x27\xf9\x9a\xf0\x9b\x96\xd2\xec\xf7\x84\x15\x33\x41\x9f\x20\xe8\xbe\x02\xa1\x6d\xa9\x78\xa2\xee\x6e\xb0\x13\x83\x8b\x1a\x53\x5b\xb6\xab\x1e\x76\x9c\xd0\xe4\xba\xc8\xf7\xe1\x0d\x5f\xd8\xc8\x69\x0a\x38\x3d\x65\x1b\x0e\x87\x97\xda\x35\x45\x60\xff\xfc\xa2\x62\xbb\xe6\x3b\x74\xc2\xfd\x70\x78\xff\xd1\xb1\xe3\x1d\x0f\x75\xc6\x21\x73\x91\xed\xf1\x16\x94\x1c\xd7\x2a\xa6\xad\xe2\x14\xdc\x18\xfc\x0b\xcf\xdb\x7a\xc7\x3e\xe8\xaf\xbe\xf9\xe5\xbb\x1b\x56\x2a\x42\x5b\x98\x89\x1a\x27\x0f\x2d\x64\xb2\xde\x37\xfb\xf3\xe0\xc2\x70\x4d\x17\x5e\x7c\xba\xd9\x27\xf9\xc9\xf5\xa5\x1d\xd6\x97\xf6\xe0\x89\x8f\x0b\xee\xbe\x4b\x0b\x7e\x35\x86\x36\xad\x78\xa6\xc7\xa1\xe6\x91\x0a\xcb\xb6\x44\x1c\xd3\x30\x6f\x81\x36\xca\x56\x12\x32\x6a\x57\x33\x72\x17\xfd\xc3\xb9\x4f\x39\x77\xe5\xba\xfc\xae\x17\xd7\xf7\x1b\xd6\x43\x87\x6e\x48\x76\x0a\x67\x48\xfd\xc9\xf6\x89\xc6\xc3\x0e\x08\xcf\xe6\xb8\x9f\x4e\xf8\x90\x6d\x5f\x36\xaa\x98\x3c\xf7\x50\x0f\xbe\xb4\x76\x5f\x7e\x59\x5b\x7e\xf0\x94\xae\xc9\x4f\x1c\xd7\x43\x12\xd6\x25\xbb\x67\xdc\x6a\x68\x24\xb4\x53\xbc\x3d\xf2\xc2\x9b\xd0\xfa\xd5\x7b\x5d\x07\xec\xe1\xf1\xf8\xfe\x5e\xd1\x0a\xe1\x8f\xc7\x6c\xb6\x90\x37\x6a\x47\x69\x8b\xbe\xa0\xed\x92\x78\x79\xa6\x70\xe7\xb1\xa8\x70\xae\xf1\x5c\xd4\xd7\xe0\xa6\x13\xcb\x73\xb7\x33\xeb\x3b\xf9\xf3\xf5\xfd\xf9\xfe\xe6\x26\xaa\x8e\x81\xc6\xc0\x5e\xb5\x51\xe1\x64\x7c\xda\xe7\xe1\xd3\x85\xeb\x88\x2f\xff\x8b\x3e\x95\x5d\xf4\x8f\x30\x45\x81\x75\xee\xf6\x40\xeb\xb9\x71\xe5\x75\x16\xba\x68\xeb\x9f\xca\xd5\xbf\xb4\x06\xf4\xc6\x4b\x66\x1a\x3b\xd5\x6d\xe0\x72\x2f\x09\x8f\x7e\xf4\x85\x0d\x32\x87\x64\x6f\x71\x92\x37\x33\x91\xa9\xf1\xfb\xcd\xcd\x06\x25\xb2\x2d\x79\xaf\xb9\x0d\x7b\x31\xbd\xeb\xb6\x9b\x5a\xc0\x2e\x8c\x4d\xf0\xbb\x31\x53\xbb\x50\xe9\x98\xe6\xf6\xf3\xe5\x12\x37\xcf\xd4\x9a\x7e\x94\xaa\xe2\x1a\xed\x09\x0b\xd4\xe1\x53\xec\x63\x71\x22\xdb\x3c\xd8\x16\x4f\x54\x2f\x69\xaa\x61\xbe\xba\x5d\x02\xfe\xfb\xf3\x6d\x06\xbe\x82\x05\xe6\xdf\x87\x21\xde\xa9\xbb\x16\xb3\x22\xd0\xcc\x19\xda\xed\x78\x80\xcd\x94\xe9\xb4\x27\x43\x93\x07\xbf\xdf\x7b\xb8\x26\x3a\x01\xfc\xa8\x8a\xfe\x09\x37\xb0\x36\x35\xf0\xf6\xf6\x8d\x15\x18\x6b\xfc\xd9\x35\xe7\x16\x12\xaa\x25\x34\x73\xc3\x93\x11\xe6\x4c\x07\xe1\x94\xa0\xd2\xb7\xa2\x4b\x6c\x83\xaf\xb8\xa6\x6b\x7e\x04\x9e\x00\xd7\x4a\xd0\x6b\xfb\xda\xeb\xca\xea\x48\xb3\x3f\xbf\xac\xe7\x32\x27\xff\x1b\x13\xec\x19\xf6\x6a\x7d\xb4\xd2\x6e\xb1\xa5\x6f\x32\xeb\x8c\xf8\x27\x50\x29\xd3\x06\x9f\x4d\xbc\xe9\x5c\x9d\x86\x07\x45\xd7\xcd\x89\xff\x3c\xbe\xfb\xb7\xab\x17\x7c\xfd\x7d\x12\x6c\x57\x96\x93\x34\xc4\x2e\xc2\x65\xc8\xfb\x0f\xae\x8e\x8e\x51\x05\xbb\xf6\xc4\x47\x2d\x65\x13\xea\xb4\xb4\x49\xfe\x90\x36\xf8\x13\x5f\x10\x83\xd9\x36\xab\xa2\xa2\x93\xb2\xeb\xfd\x62\x27\xa8\x22\x39\x6e\x53\x1a\xc3\x20\x49\xc7\xfb\x74\xd4\xd5\x1f\xf6\x55\x41\x2f\x5d\x03\x9c\xa3\x2e\xb7\x4f\xf3\x16\x03\x54\xc5\x29\xf6\x34\xb1\xb3\xa9\xdf\x0d\xee\xd7\xc2\xbd\x0e\x7b\xb7\xc3\xc3\xb4\xbd\x19\xe9\xcb\x64\x7f\x7f\x33\x92\xb6\xaf\xfb\x88\x15\xba\xe0\x92\x4d\xcd\x35\x19\x17\x75\x09\x5f\x37\x8a\x86\xfc\xc9\x66\x1f\xcd\xd5\xe4\x89\x5c\x4e\x29\x0e\x2d\x74\x89\x5c\xa8\xc6\x34\x81\x7f\xc2\x00\x67\x84\x1e\x39\xfc\x51\x3b\xc4\x5b\x7c\xb9\xd7\x55\xf1\xb7\xb1\xe6\x70\x17\x60\x13\x4c\x59\xc0\x24\xbb\xa6\x35\x23\x57\xc9\x62\x50\x94\x23\x04\xf5\x9d\x8e\xab\x2d\xe9\x15\x66\xca\xcc\xbf\x6b\x80\xd7\x55\xaf\x15\x7d\x1e\x88\xc4\xba\x2f\xf4\x05\xcd\x72\xaf\xd0\xa5\xbf\xf8\xc2\x22\x98\xbe\xc4\x1e\xa4\xa5\xf6\xbf\xf7\x0b\x19\x22\x56\x4d\x5a\xc5\x7f\xd9\x6c\x94\x01\xd3\xf4\x2d\x7c\x61\x9c\xca\x8a\x8e\x96\xbf\xe4\x3e\x9b\x8e\x90\xf4\x9a\x2a\xa0\x81\x5e\x92\xbc\xd4\x36\x36\xe5\x84\xdc\xa8\xde\xd7\x5b\x2c\xda\x5d\xfb\x92\xa7\x81\x26\xc1\x3d\x0e\x69\x32\xbb\x97\x7c\x19\x1e\xfe\x16\x8d\x3b\x7d\x78\xc9\x12\x1a\x29\xd0\x48\x4f\x44\x76\xd6\x9c\x38\xaa\x82\xd8\x9a\x52\xef\xfc\x61\xbb\x44\x3b\x80\x15\xdc\xc7\x3e\x75\x8c\x66\xa2\x6b\x69\x6a\x13\x6e\x37\xf4\x04\xd7\xb3\x2d\x51\x94\x39\xb3\xa6\xc3\xa1\x64\x52\x67\xce\xab\x4b\xc8\x3b\xbe\xfc\x5a\xcc\xb6\xd1\x26\x99\x63\x6b\x82\x5e\x02\x0b\x8b\xb8\xfc\xd6\x66\x73\xf8\xb9\x29\x27\x73\x86\xb3\xb6\xdd\x9f\x99\xd3\x38\x63\x41\xb0\xd7\xfe\xd3\xad\x0f\x03\xb8\x29\x2d\x57\xba\x51\xd7\x60\x7f\x05\x2d\x21\x8d\xec\xfe\x1b\x85\x7e\xde\xc7\xf9\x82\x3f\x37\x47\xf5\xa6\x20\xd0\x75\x09\x8f\xfc\x5a\xe2\x83\xd1\x14\x1d\x44\xd7\x0e\xff\x26\x75\x6a\x3b\x1a\x10\x4a\x36\x71\xd8\xa0\x47\x4d\x7a\x96\x85\x5e\xfc\xba\xe2\x94\xbe\xb4\xfb\x3a\xe9\xfc\xd9\x51\x8f\x6b\xa2\x38\x99\x52\x6f\xb9\xc0\x34\x26\xae\x4f\xcd\xe3\xa2\x8b\x3a\xb8\x5a\x70\x89\x2e\x9a\x0d\x91\xef\x1b\x9c\x4c\x3b\xb4\xd2\xb4\x16\x49\x5d\x63\x07\x11\x5a\x87\x34\x5f\x26\x9c\x21\xad\x6b\x6b\x17\xeb\x2a\xff\xf0\xef\x78\x7b\xc7\xf2\x34\xf6\x37\x08\x5e\xf8\xd4\x07\x54\xf1\x52\x22\x23\xf3\x37\x37\x79\x9e\xfb\x8a\x3b\x52\x00\x61\x1b\x64\x52\x38\xd1\x1d\x37\xc1\xb4\xa8\x17\x22\x64\xef\x9f\x10\x33\x22\x5c\x3b\x40\x69\x64\xca\xe5\xc9\x2d\x1c\x1d\x7f\xfb\x55\x73\xc1\x15\x36\x99\xfb\x66\x1b\xdb\xc6\x53\x45\xeb\xcf\xe5\xec\xc3\x2d\x24\x17\xa3\xd3\x60\xdb\xac\x10\x63\xc5\xaf\x2c\xaa\x1b\xb9\x78\x52\x74\x1e\xc3\x33\xd2\x68\x2d\x7e\x92\xbc\x30\xa8\x3a\xc3\xb9\xb6\x8b\xe0\xef\xdd\xb2\xc1\x01\xb6\x63\xda\x52\xc4\x26\x53\x58\xfd\xc6\x0f\x98\x60\x84\x5d\xc7\xe2\x09\xc5\x9e\xa6\x88\xf8\xff\x08\x76\x0e\xdc\x75\x44\x05\x6e\xdd\xe1\x75\x48\xbc\x57\x93\x3f\xc8\x9d\xf9\x1e\xbd\x5c\x8b\x8f\x0f\x69\x52\xf3\x82\x69\x16\x5a\x58\x38\x7f\x43\xfa\x83\xfe\xdc\x50\xe2\x05\xfb\x13\x5d\x97\x7b\xd8\x13\x16\xd6\x84\xcf\xf4\x81\x3f\xe7\x9f\x57\xff\x39\x14\x7e\xac\xcd\x21\xe0\x33\x83\xef\x2e\x8d\x42\x70\x53\x84\x94\xc8\x9b\x7f\x43\x81\x98\xb7\xc8\x60\x45\x09\x93\x83\x16\x0e\x37\x64\xf1\x92\xf9\x1b\x90\x04\x13\xc3\x31\xa4\x01\x07\xcd\xb4\x03\xf5\xa4\x59\x80\x1d\xd6\xc2\xe4\xeb\x12\x78\x33\x32\xa6\x61\x71\xf7\x14\x31\x64\x58\x1e\xe7\x30\xe9\xfe\x67\x2c\x98\xdd\xd5\x86\x1b\x6d\x63\xc6\xd1\xeb\x28\x36\x16\xc0\x6c\x32\xd5\x7e\x4a\x32\xed\x5b\x93\xf7\x8e\x8b\x76\x7c\xb3\x7f\x65\xd3\xfd\xfa\x2d\x0e\x18\x43\x55\x82\x8b\x0a\x3e\xc6\x13\x97\x59\x7b\xb8\x10\x25\x0d\xc8\xed\xec\xf8\xdf\x76\xc9\x37\x53\xc7\xb3\xf6\x69\x40\x86\xc5\x7c\xf8\x23\x9d\x78\x13\x0a\x6c\xaa\x9d\xc4\x97\x3b\x9a\x8a\x6f\x64\x36\x75\x8d\xfe\xe6\x8b\x44\xd5\xfd\xb9\xe8\xca\xec\x66\x9b\xb7\xa6\x96\x9e\xd7\x73\xbf\x24\x2d\x29\xf5\x77\x5f\x8e\xce\x10\x5a\x4a\x5c\x30\xbf\x26\x48\x75\x60\xfd\x0f\x1f\xdf\xf6\x0f\xca\x6a\xa1\x61\x5d\xa3\x8b\xf3\xc9\xdf\xe9\x6c\x1e\x1c\x4f\xb7\x29\x81\x05\xda\xd3\x4d\xd2\xbe\x52\xb7\xbb\x1f\x40\x4f\x23\x31\x7c\x6a\x77\x73\xf4\x78\x09\x0b\x3d\xaf\x50\x3f\x3c\x6e\xa8\xe0\x79\xb7\xb6\x02\x5c\xec\x25\x31\xe9\xe3\x51\x9b\x42\x49\x1e\xc7\x39\x14\xbf\xa1\x5e\xf6\x6d\xc7\x9f\x8f\xb6\x34\x2e\xde\x66\x00\x5c\x01\x73\x6b\x99\xa2\xf2\x80\x00\xd6\xdd\x0f\xbb\x5f\x1e\xf2\x21\x30\x9d\x26\x1a\x3d\xfe\xf4\x9e\xc6\xfd\x6f\x39\xb1\xfb\x5a\x9e\xd9\xf6\x79\xc4\xa3\xa6\x77\x25\x8c\x87\x2e\x06\x14\x79\xbb\xe0\xc4\xf8\x3f\x9f\x4a\x06\x6e\x36\x03\xcd\x40\xfa\x61\x7a\x8f\x69\x9e\x1a\xb7\x10\xa7\x33\x74\x36\xdc\xfb\x03\x77\x94\x0e\x14\x63\x58\xdc\x4a\x6c\xf6\xa5\xd8\x19\x1e\xe2\xd0\x8e\xb8\x25\x73\x26\x5a\x5b\x3c\x04\x24\x76\x6c\xa1\x3c\xa6\x46\x39\xa2\x85\xf1\x27\xf2\x41\xad\x14\x94\x52\x89\xd4\x55\x08\xe2\xcc\x13\xe0\x85\x9b\xd1\xf5\xac\xc9\xa4\xed\x52\x6e\xcd\xb4\xf2\x82\x57\xaf\xff\xf6\x84\x63\x70\xf6\xb4\x52\xc3\x53\x56\xd7\xb8\x42\x73\xcc\x97\xe1\x8c\xa5\xf4\x88\x7d\x5f\xe8\x78\xdb\x35\xfa\x79\x91\x17\xb1\x78\x02\xc6\x57\xc3\xdc\x05\x7e\xe2\x68\xa6\x7f\xa1\xa2\xab\xf1\x85\xb7\x32\x3f\x8a\x69\x8b\x29\xf0\xba\x4d\xdf\x0d\x0a\xa0\xcd\xeb\x68\xcc\xea\xc2\x82\x9a\xdf\x54\x82\xc8\x4e\x32\x68\xfe\x3d\xa3\x78\x17\x0c\x65\xd8\x3a\x7e\xd6\x33\x8f\x35\xb3\x77\xb7\x34\x8e\xf4\x0d\xda\x1d\x2e\x1c\x83\x87\x03\x05\x2f\x16\x9d\x3e\x04\xb8\xaf\xa6\x16\xe4\x32\xe7\x2c\x9b\x35\x96\x98\x0c\x2a\xe8\x44\xbb\x67\xce\x9c\x1c\x7e\xb3\x29\x97\xc3\x8f\x3b\x82\xc5\x4c\x9a\x7b\xb1\xf3\x77\x1e\x17\x22\xb3\xd2\x33\x69\xe3\x86\x73\xc1\xa2\xf8\x72\x9b\x4f\x0f\x47\x2a\xbc\x92\x5c\xa6\x54\x68\x85\x87\x54\x4b\x9f\x9b\x58\x3c\x33\xd4\x8f\x6f\x62\x85\xf8\x53\x2f\x84\x9f\xcf\x83\x67\xf6\x69\xe3\x01\x77\x11\xa4\x2d\xb2\x18\x00\xd6\x2c\x0c\xca\x18\xc1\xf7\x82\x3a\x08\x54\x14\xc7\x0f\xff\x86\x2c\x8c\x35\x82\xaf\xb6\xa4\x62\x9b\xc1\xf5\x03\x03\x2b\x64\x91\x98\x1a\xc9\x8c\xb5\x43\xd3\x30\x7d\x3d\xe7\xb9\x61\xbe\xc4\x5c\x46\x7a\x49\xb5\xb9\xf9\x34\x3c\x3b\xb4\xa0\x45\x43\x0c\x88\x2c\xcc\x34\xc7\x9d\x77\xc7\xa8\xdd\xaf\x01\xee\x18\x3e\xd2\x83\xf6\x4d\x07\xcd\x1e\x0f\x34\x4a\xeb\xa3\xe9\x21\x1d\x66\x09\xe8\x73\xcc\x66\xe1\x53\x80\xaf\x92\xa7\x09\x91\xa2\x59\x11\xe8\x29\xf3\x32\xa9\xb0\xcc\x15\xd7\xa6\xdb\x41\xd5\xd6\x32\xff\x34\x32\xcd\x67\x52\x95\x19\xf5\x66\x65\x69\xda\x78\x4d\x03\xd5\xa6\x3c\x2d\x58\xe3\x0a\x9e\x43\x9b\x98\x4e\x59\xfb\xd0\x75\xd0\x29\x4b\xe6\x83\x7f\x0c\xa8\x2e\x66\xfa\xd7\x00\xcd\x7a\xc9\xa6\x11\x18\x66\xcc\x90\xf1\xe2\x48\xda\x8d\x68\xbf\x7a\x13\x29\x25\x12\x1f\xf4\x76\x4c\x85\xd7\xd2\x23\x13\x23\x0d\x77\x5d\xab\x57\x7a\xce\x6f\xe0\x1f\xbe\x2a\xf8\xe5\xe6\xfe\x31\x57\x62\x9a\x82\x02\x1b\xae\xb6\xd1\x0c\x23\x3a\xe5\x07\x4c\x36\xb1\x1a\x52\x1b\x38\x94\x8c\xa4\x3c\x37\x7a\x0a\x0d\x3d\x7b\x33\xe3\x35\xbc\x68\xd3\x16\x8c\x8e\xb7\x65\xa7\x09\x71\xcf\x7c\x56\xd0\x14\x97\x2b\xfd\x7b\x53\x10\xf2\xc5\x15\x8c\x30\x5f\x66\x22\x04\x63\x63\xe1\xee\x83\x4b\x75\xa5\x26\x31\xaf\x54\x69\x7c\xcf\xd7\x71\x25\x12\xdf\x7f\x09\x33\x73\x03\x07\xc6\x42\x08\xa3\x97\xc0\xd7\x97\x6c\xf0\x69\x09\x4c\x33\xf9\xd9\x57\x72\xc9\x34\x36\xb6\xd4\x4e\x82\x3f\xf3\xfd\xf3\xcb\x32\x8a\x7b\x33\x16\x5d\xd3\x3d\x31\x25\xc2\x54\xab\x29\x3d\x08\x5e\x1f\xfa\xa0\x3c\xaf\xc5\xbb\x90\x60\x73\xfd\x5b\x26\xa9\xcd\x5e\x5d\xa9\xe8\x56\x4f\x6c\x21\xdb\xed\x1e\xff\x35\xc8\x1e\x61\x5b\x8e\x9f\xfe\x5d\x54\x0d\x34\x13\x8b\x15\xab\xbd\x44\x7e\xd4\x1c\x1f\xd8\xc1\xb0\x6d\x38\x2e\x9b\xb9\xc4\xab\x8e\x12\x23\x9c\xb0\x2f\x34\x5b\xe6\xb5\x64\x85\x40\xcc\x3e\x28\x9d\xe7\x0f\xcf\x61\xa6\x44\x98\xb0\xe2\xb3\xe1\xfa\x70\x23\x71\x98\xe1\x05\x79\xb2\x46\x99\xca\x92\xf0\x77\x85\x0d\x53\x6b\xeb\xd5\x47\xe6\xea\x16\xf7\x37\x83\xb6\xb4\x63\xe9\xc7\x83\x04\x95\x56\x46\x8f\xf9\x98\xca\x33\xdb\x8a\xa8\xfa\xbc\x73\x35\x3c\x4e\x0a\x71\xf0\x0f\x9b\x8a\x7a\x38\x7c\xfe\x7e\x7f\xba\x7b\x0e\x57\xe1\x00\x91\x31\xe5\x20\x4b\x74\xbb\x70\x01\xcc\xae\x04\x9a\xfc\xdc\x96\xec\xbd\x9d\x11\xaf\x3c\xe1\x23\x1b\x95\x68\xe6\xc7\x12\x46\x64\x81\x2c\x0e\x88\xc8\xc5\x5d\x42\xf1\xe2\x4d\x0f\x63\x31\x93\xfc\x88\xc6\xd3\x75\xfe\x4c\x9a\x4e\x25\x1e\x9b\xe3\xbc\x22\x73\xc5\xd2\x17\x75\x3b\x6e\xb1\x77\xfb\x44\xff\xc8\x0c\x56\xc4\x92\xf9\xea\x60\xa7\xf2\x6e\x6a\x1f\xe5\x0d\x73\xbb\x26\x9a\xbf\x61\xb0\xb0\x0a\x96\xa9\xfc\x15\x42\x29\xed\x33\x6f\xc1\x14\x45\x2a\x1e\xc1\xd4\xd1\x45\x6d\x42\x5c\x59\x6f\x30\x85\x23\x67\xce\x1c\x7b\xb9\x5d\x75\xbe\x0d\x14\xa9\xdb\x5e\xea\x6e\xfb\xb4\xb2\x92\x32\x04\x3b\x39\xc8\x70\x97\xd2\xd8\xd3\x4b\x54\xdc\xcb\x19\x5f\x15\x8a\x71\x70\x7f\x65\xcb\xfc\xbd\x99\xbb\xb1\xd3\x60\x7a\x30\x50\x17\x31\xe6\x33\xd9\xcc\x4c\x88\x87\x95\x46\x59\x15\x32\xd4\x85\xf0\x55\x31\xa9\xdf\x31\xe1\xe9\xe9\xf2\x41\xe9\xa4\xc0\xea\xca\xe6\xd1\x78\xd1\x70\x66\x2f\x91\x68\xc9\x75\x38\xc5\x0d\x22\x6c\x2f\x59\xe9\x4d\x31\x3d\xb4\x9a\x12\x56\x92\x15\x5f\xbe\xbe\xe6\x8c\xed\x33\x85\xba\xcd\xf8\x24\x88\xf0\x5a\x54\x0c\x2b\x28\xe6\x41\x21\x67\xbf\x9a\x2a\x80\x4f\x11\xcc\xfc\x79\xa2\xd9\xae\x80\xb1\xe5\x35\x45\x6c\x93\x39\x8a\x6d\x86\x8b\xd5\x4a\xfd\xb6\x69\xa8\xa9\x95\x66\x0f\x21\x71\xa8\xce\x52\xae\x26\xca\xca\x17\x9e\x86\x62\x29\x4f\x25\x69\xda\x46\x93\xd8\xc4\xa3\x64\xd2\x3a\x49\x9b\xee\x4c\x1d\xa2\x98\x53\xc9\x2b\x43\x8a\x2e\x6e\x7c\xab\xfb\x29\x0d\x2a\x10\x95\xf2\xdc\x9c\x9e\x4f\xc6\x17\x35\xb5\x54\x0c\xc3\x46\xb7\x72\xda\x37\xbf\x83\x6e\x37\x07\x05\x7e\xa0\xb9\x3f\xd8\x2a\x53\xd5\x5d\x4f\xcb\x69\x02\x63\x92\x83\xcc\xdd\x38\xd5\xd7\xe6\xee\x39\xb6\x5b\x92\x17\xa7\x42\xad\x6f\x9c\x69\x27\x5b\x21\xbf\x6b\xcf\x00\x2a\x0b\x18\xcc\xb9\x67\x45\xc7\x23\x29\x8a\xc1\xe1\x76\x8c\xef\x8b\x2b\xf2\xde\x42\x5e\xfa\xcc\x97\xa9\xa8\xdc\xd8\x4e\x11\x1a\xcb\x9d\x43\x39\x88\x5d\x7a\x8e\xd8\x02\x3b\x2c\x08\x3a\x58\x6b\x46\xfa\xc3\xed\xa2\x12\xc5\x4b\xb2\x28\x16\xa5\x25\xb3\x99\x9e\xc6\xab\xa0\xa7\x37\xa6\xec\xcc\x97\xbb\x21\x24\x42\x81\x80\x25\x48\x66\x81\x43\x25\xa5\x0d\x8f\x79\x9c\x03\x33\x72\xb6\xea\x38\x46\x76\xfd\x1d\x3c\x1c\x64\x85\x0f\x7e\x41\xa8\x08\xcd\xa8\x7e\x99\x60\x2d\x88\x5c\xd7\x51\x29\x13\xb3\x6b\x4f\x85\x9e\xbb\xdd\x96\x1c\x10\xf9\x8c\x6e\xb5\x75\x57\x76\xbd\xd2\x57\x90\xb6\x0a\x41\xf0\xbe\xb1\xca\x6a\x9a\x97\x7e\xc1\xab\xfa\xfb\x06\x99\x69\x3d\x5f\xd8\xf0\xec\x50\x9e\x4d\xea\xa9\x74\x91\x63\xa6\x2a\xa0\x8f\xe3\x55\x02\x46\x4c\x2b\x8d\xb7\x97\x2e\x2a\x2a\x65\x56\x39\x3d\xa9\xa0\x98\xd1\xd6\x89\x65\x1d\x86\x0c\x2a\x37\x3e\x4b\xf5\x28\x2a\x0b\x66\x97\x6a\xa1\x15\x04\xd3\xd3\x14\x2c\xab\xbd\x4a\xf3\xc7\x57\x31\xd7\xdf\xb5\xc4\x1b\x4b\x6c\x52\xa6\xec\xef\xb2\x42\xc1\x3d\x5a\xa8\x52\x2f\xea\xe0\xdd\x16\xfa\x91\x73\x1e\x14\x78\x6d\x49\x81\xb9\x49\x0e\xf5\x85\xbf\xa1\x2a\xc4\xe5\xc4\xac\x97\x47\x49\xc2\x41\x26\x56\x9e\x3e\x5a\x58\x1d\x61\x8b\xb9\xec\x4f\xe8\x08\xe5\x92\x87\x6b\x18\xe9\x5a\xf0\x1d\x37\x94\x47\x90\x7b\xc4\x3a\x86\x85\xce\xf9\x2d\x6e\x05\xcb\xc0\x45\x91\x80\x52\x50\x4e\xd9\xd4\x0d\x77\xcf\x5c\x09\x7f\xb3\x31\x2f\x73\x1f\x71\xa3\x1e\x06\xd0\x69\xf9\xf0\x6f\xad\xef\xb6\xa3\xc6\x31\xdb\x63\xa4\x3b\x3d\x14\xc6\x8e\xf9\xb9\xff\xff\xdb\xd9\xa6\x3a\x76\x25\xc2\x77\xde\xcd\x76\x42\xc8\xd7\xd4\xb1\x5a\xb5\x6d\xb8\xb4\xe3\x9b\x7f\x57\x25\x54\xf7\x37\xb3\xc3\xf2\x03\xb1\xb5\x13\x09\x49\xbb\x06\x6a\xe0\x2e\x5b\x88\x99\xe8\x5f\x4d\xac\xeb\x87\xba\xf3\x0a\x85\xef\x08\xbe\x20\x4f\x0a\xd5\x78\x3e\x29\xd0\x8c\x50\xe3\x7d\x56\x60\x74\x4d\x4b\x07\xbd\xff\x2c\xeb\x7f\x33\x0d\x74\x61\x12\xd8\xf5\x1f\x7d\x3c\xf3\x7c\xd7\xfd\x95\xf0\xba\x30\xc3\x63\x0e\x4c\x94\x41\x34\xcd\xbc\x2f\xc8\x68\xfe\xfe\xbe\xf2\xba\x48\x93\x33\xa9\x6f\x7b\x12\x37\x25\x9b\xa3\xfd\xab\x0a\xfc\xc3\xdf\xa7\x44\x23\xe6\xaf\x7a\xc9\xe3\xe5\x6e\x6c\xf0\x1f\xec\xaf\x3c\x13\x9c\xb0\x07\xd8\x6b\x3f\x40\x72\x83\x7f\x95\x37\xc5\xd5\xdc\xf7\x80\x4d\xf3\xe0\xda\x5f\xf9\xfd\x57\x7a\xac\x5d\xf9\xc3\x47\xe8\xed\xd8\x16\x07\xdd\x13\x16\x84\x6a\x98\xe3\x30\x97\xb4\x50\xc9\x2d\xed\x1d\x37\xdc\x62\xe7\xc4\xd4\xb5\xf9\xc1\xb6\xf0\x8d\xca\xfd\xb8\xf1\x9b\x99\xb9\x52\xbf\x51\xf6\xb6\xed\x5e\xd1\x0f\x51\x33\xfb\x22\xb8\xc9\x14\x58\x28\x37\x9b\xea\xaf\x90\x57\xe4\x15\xc9\x44\x1c\xcb\xaa\x24\xcb\x9c\x3a\x3a\x6e\x10\xac\xf2\xae\x4c\x25\x79\xd6\x84\xbe\x80\x45\x7b\x8f\xbf\x7b\x63\x10\x36\xf2\x75\x0a\xc0\x7b\xee\x82\x83\x75\xa8\x45\xa8\x9b\xed\x06\x59\x11\xf2\xa3\x2a\x93\x65\x3e\x3c\x4b\xb1\xf6\xba\xa2\x65\xcc\x1f\x2b\x29\x0c\x48\x65\x52\x59\x7a\xa1\x43\xe5\x36\x5e\x77\xe6\x96\x94\x05\x7c\xf3\xf7\x99\x21\xb1\x38\x30\x00\x60\x12\xbd\x7e\xe3\x9f\x8f\x7a\x71\x85\x54\xb2\xce\xa5\x69\x75\x66\x24\xaf\x09\xb9\x36\x05\x1f\x48\x01\xfd\x22\xaf\xe8\x25\x46\x95\x19\x1b\x8f\x38\x58\x09\xeb\xcc\xf9\xa7\xfc\x17\xa9\xcd\xa9\x51\x21\x68\x72\x91\x85\x8e\xb4\x3b\xba\x06\x54\x4e\x6f\x7d\x5a\x15\x2d\x2a\x6d\xef\x1a\x8e\xd9\x5a\x06\x5a\x12\x75\x77\xb4\x87\xcc\x4c\xd2\x62\xf1\x0a\x21\x1d\x76\x8e\x19\xfd\x08\x7d\x43\x53\x33\xd2\x11\xeb\x7d\x31\x07\xfa\x3c\x29\x9e\x90\xe6\x36\x95\x72\x62\x5a\x03\x2e\x69\xc5\xf8\x0d\xe7\x64\x18\xcb\x81\x72\x60\x4b\xd4\xb2\x54\x88\x5f\xc6\x52\x1e\x82\x2e\x4d\x0c\x88\x96\x56\xa9\x92\x25\x8f\x23\xb4\x92\xd2\x95\x76\x84\xdb\xc0\x68\x66\xf4\xe0\xf9\x2a\x77\x9a\x7e\xfe\x38\xe2\x8c\x7a\x0e\x44\x5b\xc4\x3a\x69\x58\xcc\x6e\xe3\x12\x16\x93\x1f\xd6\x15\xb9\x26\x66\x08\xa6\x8b\x72\xaf\xb4\x20\x9e\xdb\xb6\xeb\x1f\x2a\x66\x65\x58\x3b\x2e\xa6\x21\x2d\x14\x9c\x03\x0f\xfb\x39\x7a\xfc\x0e\xd7\xdc\x7c\xf4\x52\x45\x01\xb0\xa7\xd4\x47\xfc\xa2\xd7\x5b\xf1\x62\xec\x7e\x19\x3b\xb8\xc5\x66\xe6\x2b\x6d\x1e\xb1\x54\x2f\xbf\xfa\x88\x1b\xf8\x0f\x6a\x0c\xb1\xdc\x90\xec\xa6\xb1\x38\x84\x22\xd1\xd7\x2e\xe5\x66\xc8\xd4\xe5\x51\xc4\x9d\x81\x9c\xe9\x29\xb3\xf8\x2d\xad\xa2\x39\x1c\x37\x84\x49\x87\x4f\xff\xae\x18\xa2\x08\x54\x63\x07\x82\x22\x26\xf7\xb9\xcb\x6d\x4b\x4d\x69\x7f\xa0\xda\xe8\x5a\x3c\x55\x64\x18\x54\xd7\xf0\x3f\x3e\x15\x88\xcd\x64\xf7\x4f\x4b\x8a\x5c\x7d\x55\x92\xfd\x70\x5c\x93\x85\x0a\xf1\x59\xde\x67\x8e\x54\x72\xb9\x94\xe4\x51\xfe\xf4\x3b\xb7\xbb\x9c\x54\x34\xc8\x9e\xe6\xc6\xb9\x76\x93\x48\xf7\x63\xc9\x67\x9d\x42\x57\x95\x48\x25\x23\x11\x2b\x13\xe1\xf8\x88\x34\x12\xb0\xa1\xc4\x58\xb3\xa4\xb1\x9c\xfb\x4c\xab\x7d\x32\x8d\x14\x8a\x07\x21\x2c\x9b\x17\x0e\xe5\x70\x8e\x28\xeb\x9e\xca\x96\xdd\x4a\x70\x87\xc2\x28\x73\xe2\x2c\xae\x75\x4b\x8c\x52\x2e\xbf\xff\x29\x65\x41\x7b\xcc\x54\x6e\xc9\x74\x99\x5f\xa4\x69\xc1\x97\x6f\x6c\x42\x0e\xa1\x6a\xe9\x2d\xd9\x3d\x8d\x35\x1d\x83\xd0\xee\x03\x7d\x12\x4f\x86\x61\xfd\xf7\x81\x49\x6d\xcf\x2e\xf7\x50\x4a\xf8\xf4\x0c\xe1\x8b\xb8\x7f\xcf\x36\xb0\xe6\x66\x0e\x1b\xc3\xcc\x56\xa5\x0e\xcf\x84\xc1\x83\xbf\x28\x2d\xfc\x6e\x66\xfc\x13\x39\x80\x81\xf0\x22\xa0\x3d\x4a\xc5\x44\x69\x72\x13\xdf\x4e\x01\x21\x4a\x6a\xfe\xde\xf8\xe2\x51\xa3\x9b\x6a\x0e\x3d\x65\xa5\xcf\x88\x6d\xbb\xec\xdf\xd8\x41\xaf\xb4\x22\x01\xe0\x29\x56\x7a\x4c\x44\x9b\x9c\x06\x1e\x4e\x25\x7d\x6d\x2b\xf7\xb0\x28\x8d\x01\x95\xb5\xc5\xa6\xc7\xbd\x0d\xc5\x8c\x0f\x61\xa0\x1f\xeb\xd9\x8c\xde\xed\xa1\x1d\x03\xe2\x92\x96\x74\x4f\xcc\x29\x0d\x70\xc1\xcc\x83\x64\x50\x59\x67\x79\x5c\x17\x99\xce\xdf\x2f\xa4\x0c\xe7\x9d\x8b\x30\xa4\x7f\x3b\x02\xe1\xba\x54\x03\x2d\x40\xa3\xaf\x69\x2a\xfa\x46\xdc\xc9\x05\x5f\x78\xf5\xb7\xa2\x3d\xe6\x90\x6b\x93\x5f\x85\xac\x1e\xc4\x2d\x14\x5a\x13\x56\xe4\xec\xa6\xc0\x2a\x61\x67\x4e\xc2\x5e\x80\x0e\x54\xf7\xb8\x96\x4b\x28\xb9\x7d\xcf\x40\x31\x31\x3f\x75\x97\x7c\xa9\x5e\x48\xce\x23\xc4\xd7\xcc\x2f\x81\x1d\xe1\xb1\xd1\xa5\xb4\x50\xdc\x14\x24\xd7\xeb\xf2\xb8\x85\xe1\xa2\xfc\xac\x4e\xad\xb9\x22\xe6\x4b\xe3\xd3\xaf\xc1\x36\x60\x88\x2c\x3c\x04\xa5\x50\x4d\x5b\x24\x66\x4c\x96\xe7\x2b\xe5\xd1\x4a\x2d\xc5\x62\xd1\x3b\xba\x96\xa6\x10\xb6\x86\xe1\x99\xc9\x64\x1a\x75\xd1\x3d\xdc\x1d\x4f\xdd\x6c\xca\x17\xa0\x1c\xb9\x6c\x4c\x7a\x36\xfc\xbd\xfd\xa0\xbf\x77\x85\x77\x3a\x3f\xa4\x7c\x4d\x43\x9c\xfd\x4e\x1e\xa6\x60\x6f\x9e\x63\x43\x31\xfe\x84\x58\xe8\x85\x0d\xdd\xe8\xe4\x9f\xf9\xd6\xa6\x61\xf7\xb5\x14\xe0\xcd\xeb\x83\xb7\xb1\xbc\xd0\xa5\xe6\x3d\x21\x00\xc8\xc2\xb8\xd9\x8d\xe0\x83\x2c\x22\x1b\xf1\xc4\xf8\xd0\x01\xaf\x93\x85\x5d\x78\xea\x11\x7a\x68\x42\xbb\x99\x95\x90\xa4\x78\xff\x20\xf8\x6c\x54\x50\x3b\xc7\x52\x6d\x9c\x53\x83\x1f\x7d\x62\xc8\xb6\x71\x79\xec\xc6\xa9\x03\x94\x52\xc4\x4e\x87\x86\x4e\x80\xa7\xd2\x2e\xc8\x81\xe0\x0b\x97\x89\xd8\xcd\x64\x00\x2e\x9d\xd9\xd0\x25\x0c\x8a\xeb\x88\x7b\x63\xcd\x87\xfe\x7e\x28\xa0\x0f\xfb\x71\x4f\x58\xca\x3b\x9f\xdc\xc2\x53\x49\xbe\x52\xf0\x31\x0f\xbc\x4f\x35\x23\x10\xf3\xb3\x58\x08\xa3\xa4\xf1\x7c\x9e\x03\xe0\x24\x2e\xbe\xbb\xdf\xc0\x63\xe7\x1b\xe4\x91\xe0\x0c\xdf\x2b\x5c\x74\xb6\x63\x89\xc2\x96\x79\x00\x8b\x47\x50\xd0\x63\x2c\xcc\xc2\x7d\x47\xa9\x57\x65\x0d\x0b\x16\x97\x70\xa2\x3b\x43\x13\xb3\x16\x41\x5b\x79\xaf\xd2\x2f\xe7\xa4\xaa\x84\x97\x11\x33\x5e\xb1\x70\x09\x4f\xd2\x1f\x71\x53\x68\xfd\xcf\x3c\x59\x3a\xd6\x76\xe4\xe0\xbf\xf2\x2f\x6e\xf8\xf2\x4b\xcf\xfe\x6d\x0f\x9e\xbd\x3e\x8a\x7f\xe0\x55\x19\xfa\xfc\xe1\x79\x5f\xfd\x2f\xff\xf1\x53\x1b\x7e\x52\xd3\xf3\x9e\x5b\xfe\xf9\xa4\x03\x91\x63\xd2\x42\xc5\xf9\xa5\x63\x23\xec\x8c\x69\x0c\x56\xf5\x2d\x34\xda\x25\x56\xd8\xf6\x7e\xef\x1c\xe2\x82\xd3\xcf\xe5\x4d\xfc\x8c\x91\xfb\x34\x16\xef\x76\x62\xf2\x9c\x05\x68\x3f\x22\x87\xfa\xd8\x00\xe0\x43\x89\x7d\x96\xe5\xba\xcb\xd4\xbb\xfb\xd9\x64\x56\x57\x1f\x82\x70\xa6\xa0\xcf\xd0\xbb\xc6\xd1\xe4\x10\xa2\x16\xf5\x31\x5d\x6a\x98\x9f\xec\x92\xeb\xce\x72\xb3\x5c\x1c\xf3\x87\x74\x68\x61\x11\xb3\xb0\x82\x9b\x02\xfc\x0b\x57\xc5\x7e\x24\xde\x00\x71\x15\x42\x9e\x8f\xf2\x78\x3a\xfe\xda\x71\xb2\x70\x5f\xbb\xa8\x32\x0f\xfe\x6e\x2e\xf7\x9b\xe8\x47\xff\xe3\xd3\x66\x56\xaf\xf8\xeb\x89\xab\x33\x69\xe5\x4b\x91\xc7\xcd\x41\x56\x2e\x90\x21\xbd\xad\x02\x51\xb5\x81\x1b\xcc\xd7\x3d\xf9\xba\x27\x45\xea\xc1\xa5\x7a\xf2\x77\x77\x7e\xd4\x93\x57\xf0\xf6\xff\xb2\x6f\x3a\x5b\x7c\xde\xb6\x2c\x51\x1a\xf9\xc3\x53\x79\x7c\x50\xa4\x14\x61\x3a\x3f\x60\xe6\x55\xcc\xfc\xf4\x41\x7b\x19\xcb\xce\x8e\xfe\x16\x8b\xe4\x55\xcb\xdb\xf0\xc7\x22\xd1\xd2\x2b\xf9\x7f\xff\x52\x91\x3b\x6a\xc3\x1d\xfe\xcc\xae\x08\xab\x14\xf1\x99\x39\xe5\x0f\x6d\x85\x67\xfb\x68\xf6\xd7\x66\x60\xec\x4e\x0b\xa6\xda\x7c\x45\x57\x6f\xcc\xd8\xc8\x27\xdf\xff\xc9\x5b\xb9\x4b\x4a\x9e\x7d\x7c\xfd\xe4\x0f\xfe\x51\x28\x27\x07\x27\x69\x64\x32\xf4\x49\x85\xfd\xe4\x25\x3e\xa5\x1b\x98\xd0\xc6\x2a\x65\x8a\x3f\x7e\xbd\xe9\x26\xf9\xfe\x97\xfd\x25\x9d\xf0\x2b\xdf\x3f\xbf\x11\xff\x22\x15\xc1\x33\x98\xf1\x83\xdb\xf5\x4f\x97\xe7\xf2\x99\xb0\x00\x5a\x07\xfc\xd5\xa4\xdf\xea\x97\xc7\xe3\x0b\x5e\xf9\xd4\xda\x3c\xf5\xab\xb5\x2f\xfb\xab\xff\x77\x40\x03\x71\x65\xe7\x82\xfe\xf8\xfa\x7a\xb5\x07\x20\x25\x9b\xa1\x84\x91\x62\x85\x2e\x54\xa4\x77\x33\x8d\x6b\xbf\xf4\xcf\x3f\xbe\xbd\x01\x87\x08\x6c\x29\x40\x19\xe6\x13\x4b\xd5\x3a\xc2\x11\xfe\x9f\xbd\x9c\x39\xd4\xe3\xc7\xd7\xcf\x81\x69\x0b\x33\xaa\xc8\x0a\x98\x39\x26\x02\x0d\xe9\x06\xd5\x50\xcd\x39\x24\x74\x83\x70\x1d\xa1\x22\x16\xc4\xa5\xaa\xdc\x9b\xaa\x43\x45\x65\x5f\x4e\x0a\xd2\x6c\xbd\xfe\x83\x39\x44\x68\xb1\xb6\xf6\xcf\x1f\xec\x35\x31\x63\x8e\x6c\x36\xad\x8f\x9e\x14\x77\x3d\x92\xc2\xe4\x89\xbb\x2a\x00\x3a\xd2\x99\x6a\x60\x70\xb1\x11\x5c\x35\x8e\x01\xb2\x75\xf0\xbb\x45\xc2\xd9\x9b\x30\x70\x8b\xdd\x92\x33\x60\x6d\xdd\x90\xf9\xf6\x87\x1f\xff\xe6\x85\xfe\x56\x52\xf7\x2c\xd5\x98\x09\x52\x75\xf6\xa1\x8e\x0b\x7b\x91\xb4\x46\x1b\x6e\x34\x3e\xf6\x57\x6c\x82\xb0\xd7\xbf\xe1\xc7\xd7\x47\xc5\xa2\x68\x85\x2c\x19\x5d\xfd\x86\xfe\x42\x6c\x23\x8b\x21\x8c\x5b\xed\x35\xd8\x95\x6f\xff\xc6\x03\x64\xe7\xdd\x6f\x71\xcf\xf7\x6c\xe1\x06\x9b\x01\xdc\x11\x87\xeb\x1d\x66\x41\xc6\xe6\x02\x6f\xbe\x06\xb9\x38\xd1\xdc\x64\x58\x15\x3b\x64\x7d\xa4\xd7\xe7\xf0\x77\x24\xba\x95\xb6\xed\x53\x4b\x3d\x86\x16\x8a\x1d\x97\xf0\xf3\x06\x99\x6f\x9f\xf0\xb6\x0f\x1f\xdf\xc7\x4f\x5f\x8f\x53\x59\xc6\x7a\xef\x4a\xab\xcd\x49\x69\xfb\x31\x0f\x54\xb5\xca\x6e\xdd\x5e\xc5\x6d\xaf\x79\x6d\xbc\xf4\xc4\x92\xeb\xc1\xfe\xe4\xdd\xff\x88\x60\x7a\x56\x79\x62\x8d\xb3\x6e\xab\x31\x6f\xfd\x92\x99\x17\x35\xb9\x50\x45\x70\xf4\x70\x8e\x81\xee\xc2\x92\xfc\x98\x5b\x06\x29\x76\xbd\x1f\x92\x50\x9e\xdf\x9b\xa2\x0d\x40\x0d\x16\xdc\xad\x29\xbd\x2d\x01\x42\xe2\x18\x4f\xac\x84\x42\xea\x39\xdf\xb8\x5a\xdb\xad\x84\xd0\x5e\xfe\x8d\x0d\x74\xb9\x5d\xcc\x4e\x9c\x22\x32\x91\x15\x4a\xc2\x02\x2a\x2a\x83\xce\xe8\x3d\x2b\x81\xdb\x67\xe6\xac\x57\x7b\xa5\xc3\x93\x2a\xe2\x9f\xa0\x34\xc6\x5a\x48\x5b\x25\x75\xd7\x50\xf3\x3d\xaf\xf9\x41\x48\x91\x4a\x80\xef\x5f\xfe\x5d\x11\xff\xee\x97\xdf\xa1\x3d\x0a\xfb\x9e\x08\x96\x54\xc5\x76\xda\x5b\xba\xa1\x0a\xa7\xd6\xc1\xd6\x8f\xad\x13\x76\xf3\x88\x22\x4e\x9e\xbf\x66\xee\xa4\x76\xa8\xbd\x5f\x79\xb8\x78\xe2\x33\x41\x56\x1c\x34\x93\xe9\xe1\x0c\x6a\x68\xf9\xfd\xf6\x05\x35\xb1\x7f\xd8\x4e\xe3\x32\x26\x39\xe4\x4d\xe3\x95\x2c\x5c\x3b\x73\x43\xde\x7f\x85\x3b\x97\xba\x86\x48\xe6\x61\x1f\x6b\x24\xf5\x2e\x16\xf9\x8c\xdc\x2d\x8f\x18\x06\xa2\xe0\x07\x33\x37\x70\x6b\xed\x68\xb8\x7c\x16\xfc\xef\x25\x28\x87\x31\xee\xaa\x1d\x6e\x7d\x44\x32\xe0\xea\xf9\xe3\x02\xa0\x45\x49\xa3\x0d\x45\x06\xb3\xd0\xbf\x4c\x29\x78\x32\xf8\x05\xfc\x67\xa5\x41\xd0\x1d\xe6\x80\xcd\x25\xe6\x41\x48\x26\xba\xfe\x8e\x3f\xe7\x8f\x47\x7c\xdf\x9f\xb8\x4f\xf3\x74\x18\x76\x03\x93\xe3\xaf\x28\x90\x70\xc4\xb4\x5e\x16\x56\x52\xd1\x6e\x72\x43\xf7\xdc\x1f\x98\xfd\xee\x18\x76\x74\xa5\x05\xd3\x45\xc2\x06\x32\xe5\xde\xe1\x0b\xeb\x76\x62\x4e\xc1\x13\x7c\xc8\x59\xf8\xe9\xc5\x5a\x99\xdf\xbd\xed\x4a\x0b\x3a\x48\x12\xf6\xc7\xbd\x02\xa4\xa5\x1d\x17\xb5\xaa\x0e\xc1\xfc\x82\xd9\xb1\x85\x30\xa4\xfb\x46\x05\x6b\xa2\x4d\xd4\x64\x9f\x37\x96\x6e\xdf\x3f\xfc\xbb\x7a\xb5\x81\x54\x7f\x58\x40\xc8\x95\x62\x5e\xaf\xf5\x0e\x44\x5e\xac\xdb\xab\x91\xee\xe3\xd3\xbf\x2b\xba\x53\xaa\x00\xe7\xac\x8c\xc7\x9a\x9b\xe2\xbe\x17\x00\x04\x6b\x35\x5e\x9b\xc2\xb1\x7c\x7f\x35\x46\xb9\x21\xe0\x3e\x9e\xd2\xb0\xf5\x7e\x61\xb9\x7f\x44\x34\xaa\x84\x93\x60\xc7\xc9\x73\x50\xc4\xec\xb3\x44\xca\xfa\xc7\x2a\xf8\xf8\xa2\x32\xcc\x9c\xb7\x80\xb8\xb3\xc7\x17\x64\x6c\xea\x98\x1c\xbf\xc5\xc8\xb2\x07\xf0\x27\x08\x2a\xbd\x80\x0b\x05\x53\x74\xca\x50\x20\x12\xf3\x4e\x30\xbb\x39\x66\xac\x02\x79\x96\x06\x9e\x08\x52\x48\x28\xb4\x79\xd2\x90\xb5\x95\xe9\x31\xf2\xb7\xed\x2b\x2f\xe0\x69\x6f\x81\x62\x72\xb8\x48\x2c\x32\xbe\x28\x37\xb4\x60\x66\xfd\x59\x34\x6f\x8a\x1d\x54\x3e\x95\xd8\xba\xb5\x51\x57\x44\x5b\x34\x66\xe3\x1d\x3f\x8b\x44\xb9\x94\x85\x16\xc2\x0a\xd7\xd2\x51\x73\xce\xe7\xac\x6b\x55\xda\x70\xf4\x90\x14\xb1\x96\xfd\xbf\x1a\x1d\x4f\xf8\xa2\xae\xb2\x05\xc8\x04\x9c\x9b\xeb\x8a\x15\xff\xcb\xdf\xbc\xba\x30\xf0\x55\xa9\x6e\x87\x9c\x94\x89\x83\xda\x2c\xc6\x87\x3e\xc9\x65\x52\xe5\x18\x53\x15\xc0\x2c\x98\xa9\x55\x23\x80\xa7\x3a\x14\x38\xd8\x19\x40\x1c\xeb\xf0\x3d\x22\xb0\x54\xb3\xf9\xd3\x20\xf4\x58\x5a\x47\x94\xc0\x27\x76\x3c\xec\x5d\x7b\xfa\xf7\x11\xe8\x19\x95\x73\x74\xfc\xf6\xef\x0a\x21\x2c\xa0\x8b\xc4\x7b\x75\x9e\x09\x1a\x1e\x52\x44\xc4\x1c\xc5\x93\x94\xa5\x57\xc9\x99\x1d\xf9\xc3\x37\x8e\x79\x4a\xbc\x2f\xd3\xfb\x14\x9f\x75\x08\x14\x09\xbb\x74\x82\x48\xb7\x95\x4d\x5f\x8e\x2a\x45\xad\x1e\x05\x7d\xec\xd2\x1b\xf2\x5f\x15\x01\xd3\x32\x38\x40\x86\x4c\xb8\x13\x93\xd1\x11\xc9\x8c\x2e\x5f\x5c\x25\x0c\xf8\x82\x5c\x84\xf5\x89\x58\x33\x5b\xec\x4d\x94\xd9\x0a\x5f\x80\xdd\x78\x78\xc6\x44\x67\xd3\x05\x09\xf9\xff\xd7\xd9\x6b\xde\x0f\x4b\x12\xad\x29\xd9\xb2\xf5\x5e\x76\x2a\x49\xab\x0a\x30\x0a\xf3\x4d\x2b\x04\x3e\x43\xa4\x85\x08\x25\x2e\xf3\xa6\x27\x15\xfb\x81\x05\xae\x98\x15\x4c\x84\x70\x2d\xa5\x5e\x88\xdc\x1f\xed\xeb\x17\xf7\x38\xd4\x03\xd1\x9b\x0b\x50\xf5\xaf\xe6\x22\x77\x47\x59\xf7\xeb\x4d\x1c\xb9\x12\xb1\xa3\x51\x31\xbb\x4e\x2b\xbd\x86\x25\xf4\xbe\x84\xa6\x40\x94\x9f\x18\xf2\x3e\xb0\x8b\x97\xc5\x0f\xb8\x96\x4c\x53\xbe\x09\xda\x65\x8a\xb4\x66\x9b\x12\x7b\x78\xfd\x0d\xce\xb1\x45\xf4\x66\x47\x34\x13\x2b\x96\x99\x7a\xf4\x22\x14\xf6\x48\xcb\x07\x24\xbc\x2a\xac\x91\xb9\x8c\x39\x5d\x82\x1d\xc8\xea\xd5\x0e\x4b\xdd\xe0\x0d\x78\xb8\x12\xc2\xd5\xa9\x70\x72\xe9\x1e\x46\xd7\x22\x0e\x83\x59\xec\x9a\xb0\x71\x57\xff\x8b\xa0\x52\xbb\xdc\x66\x34\xbb\xf8\xb5\x96\x86\x16\x4f\x08\x94\xf4\xf2\xdc\x0b\xe2\x6e\xc1\x09\x72\x9a\xee\x91\xab\x51\x75\x11\x48\x74\x2e\x50\x17\xc7\xe2\x09\x37\xb9\x04\xe6\x28\x7a\x22\x9a\xfd\x7a\x59\x3f\xaa\x00\x63\x1c\x99\x2f\xb6\xf0\x68\x64\x8f\x66\x8c\xa7\x86\x40\xaf\xe7\xf3\xaf\xb3\xa6\x57\x00\xec\xe9\x1e\xc8\xa7\x6a\x87\x0e\x0a\xca\x54\x32\xa6\xb7\x6b\xc1\x66\x9b\x0b\xd0\x15\x5d\x5e\xd4\xe3\xe2\xea\x44\xb0\x2e\x73\xf9\x4b\x0a\xcd\x93\x8b\xaa\x64\xd8\x5a\x9c\x94\xbc\xf3\xd4\x24\xde\x6f\x0c\x4f\x02\x47\xed\xa0\x13\xeb\x8d\xe2\x16\x32\xba\x2d\x74\x36\xa3\xa4\x7f\x2f\xfc\x19\x77\x8e\x67\x82\x28\x3a\xc0\xd0\xa1\x02\xdd\xc6\x60\x07\xa5\xbe\xdd\x20\xfa\x7d\xe4\x7e\xf2\xff\x2a\xf8\xa9\x3f\x9f\xc7\xea\xd5\x99\xcd\x2a\x5d\xf7\x82\x18\x48\x0b\x9b\xc7\x52\xfc\xe3\x87\xe9\xb6\x5d\x49\x5f\x13\x01\x75\x63\xc6\x50\xfa\x1a\xec\x46\xe9\xa9\xd9\xbd\xb4\x2c\x0f\xb3\x3f\x1d\xa6\x0c\xbd\xc7\x10\x7b\x40\x14\x51\xbb\xba\xc4\xc9\x7d\x41\x3c\x7a\xd4\x99\x87\x12\x9e\x35\xcd\x88\x29\x33\x3a\xa9\xe1\x89\x75\xb0\x07\x03\x74\x0f\x44\x05\x6e\xb2\xbb\x89\x75\x45\xec\x25\xd3\xe7\xa5\x5b\xdd\x71\xfa\x29\x76\x4c\xba\x74\x93\x72\xad\x16\xb5\x11\x16\xd4\x94\xfe\xba\xd1\x4e\x35\x11\x63\xee\x87\x69\xb5\xee\xd4\xc5\x1b\xd1\x91\x5b\x41\x0c\x12\x1e\xcc\xae\x59\x3f\xaa\x15\xbd\x20\x87\x49\xf0\x38\xd0\x54\xe4\xfb\x89\xda\x27\xaf\x89\x35\x99\xbc\x74\x61\x1d\x25\x05\x44\x14\xb1\x81\x1a\x09\xcd\x3d\xae\xea\x70\x58\xdc\x26\x63\x47\x4b\xc1\xd5\x53\xd4\x61\xc9\xcc\x79\x9b\xc9\x0a\x34\xf4\xe6\xc3\x40\x4f\xd8\x06\xb1\xc7\x41\x9e\x17\x65\x9f\x70\xbc\x73\x69\x58\x3f\x87\x6b\x69\x8c\x84\xa0\xe6\x56\x2a\x58\xdd\xe6\x4a\x9f\x16\x37\xe2\x34\xa8\xa7\xc5\x34\x5e\x8b\xa5\x99\xa2\x9f\x2c\xc2\xf7\x4d\xd6\xa0\x3f\x2e\x05\x76\x70\x8b\xf5\x8b\xb4\xe0\xba\x0f\x04\x22\x1e\x7e\xfd\xbb\xa2\xb1\x53\x1d\xd6\xac\x27\x0d\xe8\x29\x2c\x82\x00\x2c\x7b\x57\x0b\x62\x1d\x65\x38\x01\x45\x20\x45\x80\xb7\xc9\xe1\x08\xdb\x92\xf7\x6c\x16\x37\xcf\x29\xca\x20\x65\x0b\x0e\x59\xbc\x5c\xa4\x52\x3c\x25\xbb\xd2\x76\xba\x72\x3c\x13\x18\x98\x77\x57\x05\x74\xb7\x1c\xce\xc2\xa0\xbd\xb7\xcd\x2e\xd5\x32\xd3\x66\xb0\xbc\xf8\xaa\x4a\x2e\xae\xfd\x80\xc4\xb0\xe1\x2c\xf7\xdc\xda\x38\x5c\x89\xf8\xc3\x27\x40\x49\x78\xb0\x34\x31\x1b\xe2\x29\x7b\xbc\x93\x83\xf5\xd8\x28\xe1\x65\x79\x61\x86\xbd\xe3\x53\x47\xa4\xf1\x9e\x6d\xe1\x2b\x52\xe9\x5a\x74\x38\x28\x0b\xd5\xad\x63\x7d\x2a\x04\xec\x0c\x02\x47\x17\x66\x66\xc0\x00\x5a\x87\xfb\x91\x85\x72\x18\x77\xfb\x2b\x4a\x95\x90\x73\x2c\xf4\xf9\xee\x33\xf7\x20\x67\xf5\x92\xf4\x41\x4c\xce\x9b\xc3\x2f\xfb\xcd\x4c\x95\x93\x57\x28\xb3\x00\x47\x92\xa8\x74\xf9\x44\x27\x47\xb8\x52\x31\xed\xee\xf3\x32\x63\xb8\x32\x98\x76\x0c\xe1\x40\xe1\xf1\x18\x46\xc9\x13\x74\x90\x42\x53\x0f\x8f\xd1\x77\x81\x47\x49\x1d\x4a\x2e\x31\x40\x7c\xf6\x81\xfd\x97\x08\xdf\x36\xa0\x20\xa0\x41\xe9\x94\x45\x7c\xf1\xa2\x7b\x79\xdd\xb6\x9f\xb2\x14\x5e\xda\x52\x60\x63\xdb\x61\xf2\xca\x9c\x7f\xbc\x2e\x44\x30\x6c\x05\xb4\x6a\xfe\x83\xad\x02\x2e\xa1\x77\x48\x34\xd5\xe5\xc8\xb3\xec\x62\x21\xc8\x86\xbf\x2f\x1b\xc1\x1c\xd0\x69\x07\x8e\x10\xbd\x66\xaf\x77\x59\x77\x6e\x3e\x99\x19\x9e\x61\xa6\x55\x35\x93\x31\x64\xf2\x30\x30\x28\x19\x93\x5a\x83\xa0\x1e\xa0\x7b\x5c\x19\xf2\x54\x09\x1d\x0f\xc0\x15\x42\xae\xa5\xf4\xc4\x83\xed\x82\xd5\xe6\x50\xe0\xbd\xe8\xcf\x64\x5a\xc3\xac\x20\xdb\x96\x4c\xe0\x3c\xfb\x53\xd6\x02\xf8\x3c\xb4\x65\xaf\x65\x21\x99\xb2\x5f\xc6\x1d\x26\x29\x9b\xee\x1e\x0a\x78\x55\x96\x61\xb9\x34\xac\x3d\x02\x16\x51\x01\x6d\x3e\x35\x40\x42\x3c\x04\x03\x48\xd3\x29\xb2\xe3\x15\xe2\x2e\xf2\x09\x27\x5d\x60\x45\xfb\x84\xba\x82\x43\xa5\x10\x5a\x0d\x81\x87\x73\x96\x4e\x9a\x97\x0c\xac\x83\xc5\xa3\xbe\xc9\xfe\xc7\xe6\x9b\xb3\x74\x6e\x47\x92\xde\x94\x6d\x20\x53\x14\x0f\x7c\xd9\x03\x74\x1e\x11\x65\x69\xb7\x0c\x25\x6b\xb6\x1b\x7e\x2b\xc3\x42\x0f\x2c\xf7\x8e\x92\x57\x68\x59\xcc\x09\xe0\xfb\x09\x56\x79\x60\xae\x1f\x19\xc2\xbc\xa0\x47\xff\xb6\xa4\x52\xf5\x7f\x21\x24\x9c\xba\xa5\x40\x6a\xe6\x85\x0b\xee\xbd\x04\x0c\x6d\x28\xdd\x8e\xf2\xb3\x1f\x9f\x5f\xfe\x0d\xe9\x9c\x4e\xfb\x5f\xb5\x19\x4b\xfe\xa0\xe5\xe8\xf7\xa5\x40\xb1\xd1\xf2\x05\x99\xb9\x1f\x9f\x97\xee\xc7\x73\x7f\x4f\xa1\xa6\xcc\xd7\xdf\x98\x48\x66\xef\x26\x91\x0d\xbe\xe2\x66\x6e\x19\x1a\x00\xd9\x59\xbd\xfa\x12\x8a\xb8\xe2\x73\xfb\x87\x5d\x3c\x5f\x7a\x89\x57\x21\x6d\x7d\x83\x80\x8f\xfa\x78\xf5\x8d\xad\xee\xd3\x95\x1e\xc3\x85\x2d\xb1\x53\x27\x4c\xee\x69\x27\xac\xcb\xeb\x83\x35\xa3\xbd\x9c\x86\x52\xa0\x2f\x28\x24\xf4\xae\x03\xf6\x90\xc6\xd1\x96\x1d\x0b\x02\x64\x33\x43\xef\x41\xb8\xf9\xfb\xc8\x02\xed\x39\x2e\x82\x1c\x78\x4f\x57\x89\xfe\xfb\x58\x58\x1d\xd6\x15\x79\xa5\xa6\x64\xdf\x46\x8b\x2b\xa1\xf2\x4a\x5b\x07\x0f\x91\x5a\x2b\x04\x18\x87\xde\xa6\x33\xeb\x91\xa9\x84\x9d\x4b\xc7\xf8\xbc\x62\x24\x53\xda\xab\x4d\x66\xfd\xe3\x04\x9c\x29\x66\xeb\x51\x0a\xcd\xb2\x16\xd9\x7c\xa1\x9d\x39\xd6\x2f\x24\x6b\x23\x81\xed\xef\x5f\xc7\x0f\x24\x94\x04\xea\xc1\x96\x25\x35\xec\xd8\x05\x44\xc7\x7a\xe2\x0e\xef\x04\xc0\x0b\xfa\x56\xba\x69\x70\xfe\x14\xbb\xc6\x9b\xa2\x08\x28\xcc\xd3\xae\xca\x36\x9a\x66\x2a\x28\x7a\x0b\x83\x82\xaf\x97\xd9\x33\x05\x8c\xbb\x23\x1e\x29\x4d\x93\x6e\xfc\x66\xfb\x40\xa4\x8e\xfb\x7c\xfe\x8c\x99\xd4\xc7\x5f\x9e\xb5\x42\x1a\x88\x18\x2b\xc7\x51\x9d\x86\xac\x16\x2d\xef\xb0\xc0\x0e\xd9\xdf\xed\x38\x78\xf0\x0a\xfe\xa3\x1e\xa0\x5a\x2c\xde\xe1\x29\x14\xfd\x0b\x62\x0f\x7b\x2d\xa5\x27\xbb\x69\x52\xb2\x2a\x2b\x59\xd5\x2c\xca\xf9\xc4\xbb\xda\x65\x92\x97\x3e\x4a\xc7\x9a\xf2\x1e\x43\x40\xf0\x62\x6a\x5f\x88\x0a\xd7\xc7\x5c\x1c\xf3\xca\xbc\x29\xa4\x52\x45\x11\x6f\xe9\x96\xac\x62\x3f\x85\x44\xc1\x71\x6e\x15\xaa\xbf\x6a\xa4\x35\x0d\x4d\xd4\x67\x2c\x46\xc0\x85\xa1\xa7\xf3\xe8\x19\x13\x75\x2b\x98\x63\xca\x48\xea\xb2\x2f\x6a\x36\x50\xd2\x25\xa3\x39\x95\x65\xa7\x9b\xaa\x75\x38\x5c\x7e\x87\x17\x2f\x96\x2b\xc3\xb7\xa9\x7c\x7f\x43\x3e\x8d\xa5\x71\x46\x93\x66\x1b\x6d\x69\x89\x51\x31\xa1\xe9\x91\x6e\x06\x59\x8d\x9e\xaa\x69\xbd\xe6\x2c\x03\x1e\xdc\xb5\x64\x5b\xeb\xf4\xa4\xb5\xf3\x83\x95\x8a\x33\x40\xdc\x89\x79\x41\x2c\x76\x7b\x3f\x0c\x53\x48\x4d\x66\xc2\xa5\x15\x5d\xc5\xbe\x8e\x0d\x85\x44\x08\x90\x8b\x43\xcb\xe8\x8a\xd8\x71\xbf\x28\x80\xf3\x15\x01\x42\x2d\x35\x0f\x6a\x7e\x73\x72\x96\x91\x91\xfb\xb6\xb7\xc8\x0a\xbe\xbf\xbf\x1a\xa7\xd7\x59\x4d\x78\xe6\x51\x13\x23\xe5\x8a\xb5\x34\xa7\x9a\xad\xe9\x05\x7e\x32\x6d\x31\x6a\xd3\xc0\xd5\x82\xb8\x41\x81\x74\xbc\x37\x05\x34\xee\x72\x8d\xf4\x4a\xf2\x92\x4b\x82\xda\xb0\xcd\x56\xb6\xc3\x8e\xcd\x1d\x77\xb9\xf5\x0a\xfb\x87\x53\xa1\xd0\x0a\x0d\xff\x1a\x75\x0b\xe6\xa5\xc6\xd0\x14\xaa\x17\x77\x73\x85\x2b\xbe\x7a\x57\xda\x7f\x78\x7d\x08\xad\x09\x4f\x5c\xbd\x57\xd2\xe5\x08\x85\x7f\xe6\x77\xa5\xbf\xc2\x3b\x4c\x15\x9d\x1a\xf7\x72\x70\x4e\x08\xee\x9f\xe7\x17\xce\xdf\x4c\x57\x9b\x80\x8c\x99\x8a\x13\x6c\x21\x65\x81\xc9\x5e\x4d\x3f\x21\x42\xb9\xfd\xd5\x38\x92\x52\xee\x6b\xf2\x30\xf3\x85\x09\xe0\x26\x75\x4b\xde\x67\x7a\x01\xf1\x8a\x3f\x2b\xa9\xa3\xee\x95\xec\x6c\xf3\xde\xf5\x72\xbc\x3d\xd4\x82\xbd\x9c\x76\xb5\x2e\x0f\x2c\x81\x0c\x16\xe7\xa4\x19\x66\x7b\xb7\x43\xc5\x93\xe8\x9d\x35\x2c\x93\xe4\x41\x11\xf1\x95\xfc\x20\xb7\x54\x17\xae\x8f\x91\x78\x07\x33\x66\x9f\x90\xb9\x99\x39\xf0\x93\x19\xd2\x27\xfb\x40\xd9\xc3\x4c\xae\x1a\x78\xd1\x9e\xf4\xe3\xf5\x9b\x1a\x61\x53\x98\xe7\x71\xfc\x03\xf0\xe5\x5b\x93\x0b\x8f\x93\xe7\x82\x3b\x1c\x6c\x4f\x89\x88\xb3\x6b\x6f\x21\xce\x26\x8b\x8e\xf7\xb4\x47\x3f\x87\xd3\x7e\xb9\xf8\x9d\x7f\x7f\x1c\x18\x80\x36\x25\x62\xf3\x46\x14\x38\x14\x28\x37\x75\x92\xfe\x8d\xaa\x28\xf2\x50\xda\xfe\xb3\xa1\x19\x3b\x5d\x87\x9a\x7b\x9d\x88\x74\x6f\xbc\x95\x44\x59\xb7\x41\x71\x42\xe9\xe3\x01\x3a\xe1\xc0\xd3\xbc\xc8\x99\x43\xd6\x07\x3c\x44\x08\x87\x5e\x9d\xce\xab\x85\x95\x38\xdc\xab\x30\x86\xa5\x2c\x6d\x87\xb6\xe8\x1c\xd1\x45\x8c\x21\x7a\x30\x56\x09\xc5\xec\x1f\xf0\x42\xfa\x3a\x7d\x0f\xfd\x50\x25\x5f\x1f\x19\x4b\xec\x35\x66\x26\xb1\x7b\x6a\x39\xbb\x46\x75\x86\x21\x27\x46\xb2\xaf\x42\xc9\xd3\x79\x73\x3c\x37\x4b\xa4\x56\x70\xbe\x6a\xfb\x58\xdf\x89\x30\x17\xbe\x12\x3b\x66\x74\x05\x72\x47\x6b\xdf\x27\x19\x12\x6f\x3d\x13\xfe\xdd\xd3\x2e\xca\xf4\x1f\x7e\x7f\xd4\x92\xce\x2c\xa9\xc0\x13\xa8\x94\xbf\x6a\xe5\x82\xb4\xad\x68\x02\xf5\x07\x8e\x00\x56\x01\x73\xd8\x45\x9e\x40\xa2\x30\x44\xcc\x0e\xd0\x62\x4e\x68\x63\x11\x1a\xf0\x33\x04\x45\xe1\xc1\x9e\x32\x3b\xbf\x44\xf2\x1c\xde\x90\xd0\x0c\x43\x4d\xab\x88\x32\x1d\x8e\x4b\x74\x4e\x9f\x85\xa4\x19\xbb\x7b\x7f\x44\x0b\xfa\x77\xe5\x2a\xaf\x94\xb7\x98\xd7\x3d\xfc\xfe\xfe\x60\x23\x2f\xd4\x39\xb7\x9c\x4f\xfe\x5f\x45\xa7\xb2\x62\x9e\x1e\x2a\x3a\x31\x09\xdf\x98\xd2\x5c\xa8\x66\xfe\xd7\xff\x72\x45\x3d\x3d\xce\x74\x9e\x2d\x40\x4f\x6b\x2f\x55\x6b\xce\x2f\x33\x74\x57\xdb\x30\x3a\xb0\x2c\x7c\xb1\x43\xd6\x9b\x47\xd4\xa6\x1c\xd8\xc2\xe3\xbd\xbc\x5b\xa0\xab\x33\x09\x0c\x89\xb7\x1d\x42\x6d\x4b\xe3\xeb\x1f\x27\x66\x90\x18\x33\xd7\xc4\x4d\x8d\xe1\xd1\xa3\x45\x79\x89\xad\x4a\x33\x5d\xbe\xe6\x81\xba\x23\x8e\x34\x06\x9f\x6f\xfe\xed\x4f\x95\x43\xb7\x14\x8a\x23\x81\x4a\x59\x1d\x74\xac\x05\xf1\xce\x93\x99\x78\xdc\x66\x1b\xd7\xcb\x99\xfd\x0c\x7b\xdb\x0e\x6a\xdb\x2e\xfe\xf5\xe8\x5d\x18\xe8\xb2\xef\x05\x2b\x3e\x7b\x89\x1f\xde\xb0\x49\xc9\x91\xa7\x44\xad\x26\x75\x7a\x32\xf9\xb2\xa6\x7b\xb1\xf2\x05\x26\x66\x96\x4f\x1d\x84\xce\xbd\xb2\xaa\x15\x3c\xda\x5a\xab\x6c\x66\xae\x2f\xcd\x8b\xa7\xa1\xde\x0f\x2c\xdb\x99\x0b\x44\x6d\x77\x1a\xe4\x58\x9a\x1d\x07\x3b\x88\x19\x99\x61\xc9\x81\x25\xa4\x15\xc0\xcd\xc6\x42\xf7\x01\x49\xc9\x7a\x79\x6b\xdf\x17\x4a\xf0\x52\xe8\x98\x6e\xb1\x2d\x4e\x64\xb8\x11\x81\x82\x6c\x96\x52\xeb\x70\xa9\x27\x6f\x65\x61\x5d\x38\x33\xb9\xea\xc1\x26\x37\x5d\x05\x09\x27\x5d\x51\xca\xa8\x5e\x82\x10\xb6\x33\x23\xb3\x81\x08\xe5\xb6\x30\x27\x22\x73\x4a\x71\x34\x91\xe1\x03\xef\x06\x60\x0e\xe6\x29\x44\x96\xf2\x21\xc7\x2f\xff\xc6\x95\xa6\xa9\xa8\xb9\x6d\x61\x9a\x01\x80\x57\x62\x03\x4a\xb1\xdf\xdc\xe3\x89\xf2\xe3\x5c\x19\x2c\x66\x38\x31\x0d\xd6\xd0\xae\xa0\x65\xfb\xd4\x68\x3a\xa2\x58\x50\x14\x9e\x09\x48\x50\x4e\xe5\x45\xe9\xd7\xc6\x17\xa3\xdb\xc4\x6e\x46\x74\x47\x33\x89\x38\xc9\x69\xbb\x04\x73\x3c\x55\x7b\x54\x66\xe5\xe3\x20\x96\x0a\x19\x52\xef\xbd\xa0\x6b\x9e\xe2\x22\xd2\x17\xfb\x84\x85\x0c\x53\x76\x8a\xe9\x4c\x0e\x51\x47\xb7\xc0\xbb\x70\xa5\xde\xaf\x87\x17\x2f\xb9\xce\x42\x25\x79\x75\x8c\xa1\x42\x20\xee\x61\xf5\x5a\x92\xf8\x0b\xc1\x30\x51\x11\x3c\xb4\x21\x7e\xd8\x56\xbb\x42\xa0\x6e\xe0\x18\xd0\xf4\xef\xac\xfa\x28\x1d\x0c\x33\xb5\x13\x8b\xe0\x38\x63\x55\xd0\x4c\xe9\xfb\x36\x3c\xc3\xbf\x83\xe8\x1c\xd8\xd8\x89\xcf\x9c\x4b\xe7\xa9\xbb\x16\xf8\xa0\xd5\x62\x74\x14\x27\x91\x30\xaa\x4a\x23\x09\xd2\xc1\x63\xe1\x65\xf4\x9e\x92\x9d\x9e\xdc\x22\xad\xb7\xda\x7e\x51\x49\x06\xc7\x07\x55\x85\x7f\x12\xde\xf4\x65\x08\x3d\x4b\x9e\x03\x81\x29\xad\xf3\xc4\x25\x5d\x70\x55\x7c\x0e\x9e\x51\xd6\x31\x5f\x6d\xb8\xe3\xf8\xea\x1c\xbc\xd9\xa7\xf5\x99\xd8\xcd\x3d\xaa\x81\xfa\x69\xbe\x9a\x1a\x4c\x41\x2c\x40\x28\x69\x3a\xa9\x88\xf1\xd7\x06\x33\x90\x86\xc6\x61\x93\xb1\x68\x92\x0a\xde\xb1\xea\xfa\x8e\xf8\x47\x66\xdb\x24\x63\x0d\x84\x25\x26\xea\x5d\x17\x6e\x99\xa4\x94\xc0\xb5\x62\xcb\xea\x6e\xc5\xe3\x59\x4a\x9b\x66\xd2\x6a\xee\x9a\xa9\x18\xb3\x9e\xb0\x95\x5e\xf0\x90\xf3\x48\x64\x65\x5d\xbf\x38\x08\xfa\x30\xfc\xd2\xe8\x74\xa6\xba\x79\x3a\x95\xf2\xea\x72\x69\xc7\xf0\x42\x1b\x3d\xd2\x91\x6d\x8f\x6b\xb3\xc3\x52\xe7\x69\x78\x40\x53\x6f\xdb\x1f\xa8\xd2\xe2\x7e\x41\xc5\x6d\x9f\xb0\x3f\x83\x77\x3a\x23\xf8\xdb\x59\x8b\x3c\x9b\xe2\x0d\x37\x74\x43\x10\x43\x08\x20\x58\x89\x2f\x28\x15\xeb\xab\x95\x72\x2e\x34\x52\x76\x77\xe6\x23\x40\xb1\xbf\x00\x03\xc3\xe5\xdc\x77\x94\xf0\xc1\xd9\x9c\xa8\xe4\xed\x74\xec\x2b\xd2\xae\x7b\x52\x02\xad\x7b\x8c\x13\x6b\x2e\x8d\x09\x3b\xe9\x01\x72\x18\x14\x28\xb6\xeb\xc8\x56\xef\x81\xd8\x17\x71\x28\x22\x1f\x92\x59\x71\x33\x87\x5e\x90\xf5\xe6\xd5\x52\xd9\xc6\xf8\x54\x2d\xb9\x2f\xe8\x0f\x65\xce\xc0\x14\xc3\xdb\x7e\x64\x6f\xef\x61\xf6\xaf\x30\x54\xac\xf1\xae\xd0\x2a\xde\x95\x78\x4d\xcd\xff\x53\x79\x8a\x51\x4e\xf4\xcb\x5a\xa9\x42\xb3\xc4\xed\x79\xa1\x6b\x67\xd7\xc4\xec\xf5\x69\x49\xac\xcd\x65\x53\xaf\xc8\x49\x51\xe6\xb9\x10\x13\x58\x1a\x2b\xb7\x4a\x71\x69\xd5\x56\x1f\x0f\x1f\xf8\xc4\x3a\x0b\xe6\x78\x21\xa0\x00\xf9\xb0\x26\xef\xa4\x70\x39\x7c\xf9\x37\xa4\xec\xc7\xa5\xec\x99\xd8\x76\x0a\xef\x44\x10\xdd\x4d\x16\x31\xbc\x7a\xa8\xbd\x79\x45\x2d\xd9\x0d\x78\xc0\xb0\xf6\x79\x48\xac\x49\x89\x85\xcc\x03\x47\x95\x65\x2c\xe2\x60\xdd\xca\x3e\x18\xf6\xcd\x7c\x4c\x2e\xb8\xf9\xc4\xf6\xaf\x62\x7d\x57\x3c\xaf\x8d\x08\x8b\xec\x8f\xae\x82\xf3\xd9\x72\x85\x49\xbd\x09\x02\xdd\x7a\xf4\xa5\xa6\x3e\x57\xb4\xa4\x1a\xb3\x55\xe4\xa2\xcc\x11\x70\x85\xeb\x1a\x3b\x38\x86\xe8\x1e\x39\x68\x2b\x0e\x54\x3f\x2c\xc5\xad\xff\x76\x47\x97\xe1\x73\x3c\x6b\x04\xd9\xcd\xa5\xcf\x23\xbf\x0a\xdc\xa1\x50\x0d\x5a\x34\xa7\xd2\x8b\xc7\x1e\x0c\x42\x3d\x0f\xb3\x05\x82\x40\x03\x0a\x42\x88\x38\x51\x43\x16\x41\x27\xc1\x29\xba\x47\x2f\x91\xe0\x8a\xb7\xc7\xa0\xe2\xdf\xc3\x7c\x3d\x1a\xf2\x7d\x6a\x97\x82\xaa\x97\x52\x98\x4a\x8a\xf5\xea\xce\x52\x47\xb0\x8e\xa0\x28\x1e\x14\xbc\x43\xf5\x8a\x9f\x07\xbd\x2f\x28\x4d\x3b\x37\x48\x69\x72\x6c\xb9\xa8\x00\x5a\xe3\xc4\xc5\xbd\x8b\x99\x50\x06\x5b\x2e\xa0\xf3\x2d\x14\x20\xed\xaf\x53\x20\x64\x22\x86\x65\xa7\xbc\xf9\x67\x60\x27\xb2\x39\x64\x33\x1b\x06\x5f\x94\x77\x8e\x29\x20\x89\xcd\x69\xd0\x51\x02\x51\x9e\x1f\x4f\xb3\x2d\x1b\xfd\x78\xdb\xb0\xbd\xf5\x0b\x45\x03\x16\xf2\x48\xf9\x44\xef\xc2\xf3\x62\x10\xfa\x3c\xc6\x91\xb0\xe6\x97\x32\x36\x57\x9e\x27\xd1\xf4\xa8\xb7\x08\x55\x7f\x95\x11\x7f\x98\x48\x2c\x90\xa6\xd5\xf7\x51\xed\x0d\x8f\x33\x99\x74\x2c\x50\xa4\x73\xb1\x95\xca\xa7\x17\xec\x0a\x4d\xcb\x98\x5a\xf6\xdc\x2d\x69\x66\x27\x8d\x93\x3a\x9c\x64\x71\xd8\xbc\x8b\x0c\xa9\xf8\x6a\xba\x3e\x6e\x1b\x55\x47\x67\xae\x0e\x5a\x07\xf6\x75\x0a\x57\x42\x82\x26\x69\x7a\x1a\x4c\x82\xf1\x86\x15\x8e\xb5\xb7\xf1\xaa\xc9\x71\x2f\xbd\xbd\xde\x8b\x19\x55\x21\x9e\x3a\x29\xe2\x31\xad\x27\xfa\x1d\x69\x38\x4d\x68\x0b\x47\xcf\x1f\x5e\x71\x33\xeb\x4b\xc3\x91\x3a\xd1\x29\x23\x3b\xd9\xa3\xcb\xff\x29\x5a\xc4\xad\xd4\xef\x2f\xe6\x47\x9f\x50\xf5\x0f\xcc\x2c\xb9\x14\x0f\x19\x49\xb1\x60\xb1\xcf\x27\x9b\x2e\x3d\x48\xe4\x23\xe7\xb4\xf5\x17\x02\xf7\xe5\x8a\xab\x44\xd0\x60\x94\x82\x34\xdb\x69\x61\x24\x81\x8e\x19\x3c\xb0\xe0\x80\x47\x33\x75\x4c\xf3\x99\x20\xaf\xc4\x45\xc6\xf8\xc8\x6a\xed\xca\x74\xe0\xec\x66\xd0\x8c\x04\x3d\x54\x32\x12\xce\x9b\x13\xd4\x79\x45\xb8\x0e\x04\xd4\x8f\x25\x91\x13\x4e\xa6\xa2\x34\x95\x39\xf4\x54\x8a\x60\x49\x54\xc0\x50\x30\xf9\x1e\xda\x45\x35\xc5\x38\x5f\x10\xa0\x8e\x05\x4c\x42\x36\x38\x51\x40\xa5\x55\xc0\xf4\xd2\xb6\xed\x92\x37\xf3\x68\xc5\x33\x92\x04\x05\x8f\xd6\x67\x13\x6f\xca\xd8\x2a\xe2\x44\x70\x2d\xd4\x99\xde\x27\xf9\xcd\x4b\x06\xe3\xe6\x00\xdf\x8a\xfe\x32\xb9\x48\x7c\x79\xa0\xfd\x66\x6a\xc3\x97\xcd\x43\x2b\x05\xd3\xf1\x53\xc1\x17\xba\x3b\x87\xf4\xab\x59\x51\xd6\x10\x00\x07\x87\x12\x73\x9a\xcf\x20\x94\x2d\x03\xe1\x93\x89\xa6\x1a\x79\x4e\xe6\x3c\xc3\xe1\xb3\x53\xbd\xd0\x34\xac\xa5\xf3\x69\x35\x9d\x05\xab\x89\x12\x17\x83\x5f\x54\x69\x69\x40\xba\xa4\x94\x9a\x7f\x57\xa5\xed\xc4\x57\xee\x51\xfa\x76\xed\x7c\xc2\xc8\x8a\x03\x00\xd4\xc8\x8c\x75\xaf\xfb\x80\x1a\xe8\xd5\xbe\xb0\x32\x4e\xc6\x98\x28\xa3\x0a\x1d\x1e\x3b\x59\x27\xdf\x80\xb8\xf4\xeb\xb1\xe7\x49\x82\x02\xba\x6d\x3a\xc0\x53\x1d\x64\x34\x09\x63\x5b\xed\xc0\x90\xf3\x2c\x9f\x36\x17\x1b\x2c\x54\xd3\xd0\x78\x6f\x7d\x5a\x44\x21\x33\xc4\x3c\xf3\x44\x99\x02\x0b\xac\xb3\xc4\xd1\xe4\x4e\x1c\xc3\xb7\xd2\xa4\xb3\xce\xbb\x18\xc4\xdf\x3f\xbe\x80\xa9\x0d\x53\xe1\xb1\x44\x84\x5c\x07\x02\xa4\xd4\xa4\x76\x7a\xb1\xb7\xad\xa6\x0d\x26\x21\x7d\x3f\x3f\x55\xf5\xf3\x36\xb9\x0c\x95\x43\x64\x8b\xc5\x0e\x66\x3f\xf1\x20\x91\xc2\xcd\x69\x91\x94\xc8\x6d\xe1\xdd\xa7\x54\xbc\x3a\xb2\x5d\xac\x7b\x4d\x2a\x6d\x74\xa9\x31\x9f\x34\xc5\xc2\x1f\xed\x65\x44\x15\xeb\xe6\x52\x17\x28\x39\x33\x11\x20\x02\x20\x49\x44\xcf\x79\x9f\x22\x71\x92\x5e\x31\x10\x74\x60\x60\x3f\xb5\xb7\xc6\xb3\xf0\xe9\x31\xdf\x85\xd8\x49\xf7\x18\x89\x6a\xf0\x5c\x3f\x91\x78\xf5\x8b\x93\x16\xc9\x11\xb8\xff\x5e\x63\x18\x62\x50\x38\x6c\x51\x11\xd3\x28\xf9\xf9\x64\x8b\xca\xfd\x2f\x4d\x62\x8a\x47\xa4\xc8\x16\xaf\xdd\xd2\x89\x79\x54\x76\x73\x91\xfc\x81\xba\xa0\xc1\x3b\x38\x03\x1d\xd2\x45\xc4\x18\x3b\xe3\x8c\x7c\x0d\x94\x01\x57\xae\x13\xb2\x25\x4e\x0c\xc1\xf0\x28\x2e\x60\xad\x13\x24\xd0\x2c\xde\xf1\x83\x30\xac\x76\x2f\x8e\x83\xab\x46\x11\xae\x79\x93\x50\x24\x2a\x06\xf4\xf1\xcc\xbf\x7e\x7c\x02\xfe\xd0\x38\x8c\x86\xdd\xd3\x0e\x99\x54\x1b\x86\x0a\x39\x6c\xbe\x73\xa8\x08\xb2\x9e\x76\x20\x60\x31\xc2\x10\x2e\x85\xe8\xa3\x42\x36\xb3\x16\xab\x6e\x1e\x0a\x79\xa1\xdc\x3f\xd3\xef\x45\x29\x90\xf8\x0a\x48\x54\x2a\x10\x27\x25\x14\xf5\xb2\x03\x0e\x77\xf1\xe7\x99\x06\xc5\xdb\x3e\xbd\xd1\xbd\x87\x36\xc9\x6c\x99\x72\xb5\xc2\x7a\x49\x29\x11\x9b\x32\x62\xfe\x32\x74\x0c\x2a\xc7\x70\x27\x46\xc9\x4b\xe0\xb9\x15\xc0\x7c\xf1\xaa\x80\xa0\xa4\xde\x58\x8c\xb0\x8a\xe4\xec\xc8\x07\x78\x76\x9a\x89\x40\x07\x52\xac\x45\x21\x28\xa3\xbf\x64\x5a\x23\xbb\x91\x07\x8b\x9b\xc5\x0d\x72\xe4\x38\x71\xba\x40\x16\x12\x32\x38\x38\xb1\x95\x98\x22\x92\xfa\x27\xeb\xbd\xbd\xc5\x54\x78\x0c\x85\x23\xb3\x93\x91\x08\xcb\x89\x77\x4f\x63\xc7\xa9\x21\x1d\x88\x93\x11\xe0\x7e\x25\x3c\x87\xdf\x2f\x60\xe7\x37\x95\x42\x9d\x24\xa3\x57\x01\x44\xce\xd4\x0c\x9a\x5d\xd1\xef\x10\x9f\xc6\x75\x99\xd9\xa6\x6a\xaa\x54\xcc\xdb\xde\xfa\xab\xb2\xf5\x5f\x78\x64\x2f\x11\x51\xa7\x05\x4a\x27\x55\x2d\x0a\x27\xa8\x2d\x5a\x23\x72\x4a\x0b\xa4\x73\x57\x78\x2a\x99\x0a\x2f\xe4\x76\x80\x88\x7c\x80\x90\xd5\x8b\x8b\x85\x19\x00\x81\xde\xff\x81\xc1\x4e\xf5\xd7\x5e\xbb\xc6\x31\xb7\xed\x8a\x16\x52\x87\x94\x1d\x8a\x4a\xa8\x54\x7f\x62\x72\xd7\xd9\x37\x68\xe3\xe0\x7c\xb7\x95\x0a\x76\xca\x0f\x2c\x4a\x38\xba\xce\x50\x23\x73\xb3\xed\x5a\x80\x38\x17\xed\x90\xc8\xaa\xb2\x39\xd5\x1a\x73\x0b\x16\x3c\x05\xff\x4f\xe7\x82\xbc\xdd\x43\xda\x44\x49\x20\x7e\xca\xa5\x50\x04\x86\xd7\x89\x71\x66\x49\x9e\x27\xaf\x27\x88\xad\xdc\x3c\xbd\x32\xc9\x61\xc9\x8f\x80\xa0\x0f\x14\x1a\x64\x4e\x4e\x92\x89\xbf\xfe\x99\x31\x38\x4f\x2a\x93\x1b\xe6\x24\x62\x6f\xbc\xc5\x43\xa5\xd1\x29\x5f\x92\xdc\x5e\x76\xbd\xd5\xcb\xe7\x87\x2f\x99\xd3\x76\x8f\xa5\x39\x61\x64\x72\x05\x65\x3b\x92\xc7\x9b\x01\x76\x2d\xa8\x2e\xe6\xf7\x4f\xff\x86\x12\x08\x44\xb3\xa9\x5b\x1e\x39\x55\x16\xe8\x6d\xb9\x58\x79\xdd\x0a\x35\xf1\x50\x33\x66\x31\x03\x05\xba\x18\xd7\xb2\x82\xae\xa2\x19\x19\x6a\xbd\x03\xbc\x51\x65\x07\xd6\x75\xfd\xe6\x70\x69\x39\x90\xbc\x6d\x40\x53\xaf\x20\xae\x83\xc9\x8b\x12\xb4\xaf\x22\xa7\x43\xcb\xc4\x44\x65\xcb\xcb\x3e\x40\x8f\x64\xe0\xa4\x4e\x25\xe6\x04\xc7\x02\xcf\x09\xbd\x92\xff\x53\x09\x69\x8c\x33\x32\x8a\x93\x2b\x99\xfe\xc6\x26\xaa\x54\xef\x20\x13\x01\x4d\xea\x97\xeb\xbf\x15\x27\xfd\xe3\xf3\x8b\x24\x62\x9b\xa3\xda\x52\x91\x93\x48\x0e\x63\xb3\x7f\x64\x9d\x38\xbc\x81\xd7\xc0\xc2\x37\x8d\x62\xb0\xfd\x1e\x90\xb2\x01\x0e\xfb\x43\xfa\x83\xa5\xb6\x6b\x2c\x5c\x26\x4b\x7b\x62\x82\xd3\x1d\x59\xae\x51\x78\x8c\xf4\x80\x2c\x72\x20\xd7\x43\xa1\x0a\x87\x15\x25\x4f\xae\x7b\x18\xf0\xa9\x0b\xfa\x0e\x6e\x24\xe4\xa0\x13\x32\x69\x60\xa7\x50\x2b\x84\xf4\xc5\x5c\xc5\x4b\x00\x9a\xcb\x1d\x62\x86\x06\x29\x6e\x13\xfc\xae\x2b\x05\x9c\xfd\x2f\xb8\x8e\x37\x05\xe1\x45\x31\x00\x5f\xab\x66\x53\x72\xc6\x96\x18\x3c\x29\x0e\x74\xa7\x81\xf0\x39\xb3\x3f\xbe\xb0\xe6\xee\xf9\x09\xe3\xad\x33\x8f\xba\x2b\x39\xb7\x3a\xab\x28\x83\xbb\xc9\x91\xfe\xa4\x59\xa6\xb5\x58\x02\x7b\x2d\xf6\xe9\x32\x31\x4f\x12\x6a\x13\xc7\x9d\xde\x82\x8f\x58\xa1\x97\x20\x63\x59\x21\xff\x73\x2b\x31\x81\x2e\xf2\xf0\xf3\xf1\xfe\xf5\xc9\x76\x1c\xf2\x07\x3c\xef\x8d\xfd\x73\x61\x7f\x7b\x67\x07\x8b\x93\x39\x68\x92\xcc\x62\xd1\x99\xf8\x41\x57\x2f\x9c\x14\x37\x76\x54\xd7\x79\x2c\x58\x80\xc3\xc7\x2f\x50\x8a\x53\x47\xfe\x8c\x5c\x18\x16\x38\x85\x83\xd2\x9f\x17\x46\x43\xce\xae\x41\x37\xd3\xb9\x34\x99\x4a\x30\x83\xdb\xd3\x3b\xb4\xd0\x5f\x9c\xf1\x43\xde\x04\x21\x5d\xa6\xec\x81\x22\xcb\x90\xb6\x10\xab\x00\x2c\x4b\xbb\x0b\x3f\x74\x8d\xe2\xe2\x59\x58\xca\xa6\x53\x59\x89\x1c\x09\x81\xaf\x39\x2a\x6a\xdb\x30\xbf\x40\x0d\xb0\xb1\xf4\xe5\x9b\xf4\xaf\x42\x4e\xb3\x85\x22\x69\x44\x45\x81\xbb\x6c\xe1\x31\xb0\x15\xe4\xe3\xe3\x40\x7a\x57\xd5\x9d\xdd\x9d\x82\x5e\x46\xf2\x71\x22\x31\xa2\x27\xce\x99\xd6\x50\xc5\xc2\x77\x5d\x1c\xbb\x64\xdb\xc5\x93\x60\xb5\x47\x3f\x81\x17\xdf\x54\x3e\xca\x43\x71\x33\x55\x48\x30\x99\x1f\x64\x24\xba\x5e\x54\x91\x73\x68\xe9\x0f\xce\xae\x39\xf9\xe7\x16\x4f\x61\xbb\xcd\x07\x28\x78\x64\x68\xd5\x02\x17\x15\x46\xb4\x19\x0a\x97\x51\x6d\x8b\xcd\x42\x48\x9f\xfd\xbb\x62\x9d\x49\x0d\xf2\xa6\xc5\x37\x32\x9e\xc5\xd2\x91\xce\x1c\x38\x21\x39\x77\x2d\xe2\x39\xde\x62\xb9\x67\xf7\x6c\x61\xf6\x79\xd3\x4b\x4f\x8e\x83\xba\x05\xac\xd2\x53\xdf\x39\xab\x45\x2d\xfd\x87\x7a\x13\x67\xca\x81\x49\x4a\x25\x2e\x79\xdf\x22\x61\xf4\x11\x16\xce\xfe\xff\x12\x34\xd7\xc8\x7c\x1c\x36\xb5\x99\x6f\x41\x90\xf4\x30\xbc\xa0\xe8\xdb\x2d\x15\x42\xd4\x66\x49\x82\xaf\x34\xfb\x2c\xfc\x30\xb0\xf2\xf0\x4d\x3d\xb3\x48\xb4\x80\x00\xf4\x43\x21\x15\x32\x9f\x81\x49\xdd\x34\x79\x97\x9c\xdf\xe2\x3d\x2e\x77\x15\xd3\x12\x51\xf5\x22\x62\x98\xf5\xd3\xe1\xd6\x81\x34\x4a\x63\x2c\x3d\x57\xa6\xb0\x82\x28\x3c\xb6\xc4\x6e\x81\x60\xc6\x41\xa0\x50\x2d\x06\x36\x9c\x86\xe3\xf3\xf3\xb3\x0c\x1f\xb2\xe5\x6b\x79\xc8\xdb\xac\x7c\xe1\x74\xcb\x1f\xa5\x69\xb9\x64\x4e\x47\xe2\x10\xa9\xa5\xdb\xbf\x36\x0e\xa5\x19\x3d\x36\x06\xd9\x8f\xcb\xce\x94\x27\xd6\x9f\x0b\x5d\x18\x79\x97\x95\x7d\x64\xaa\xe0\x97\x26\x72\xb8\x70\x67\xaf\x57\x05\x62\x6a\x1e\x44\x02\x9b\xb9\x3a\x8b\xc7\x48\xdf\xa5\xca\xc0\xf6\x72\x59\xcf\x7b\xd7\x91\xb5\xdd\x25\x1f\x2c\x9f\xe6\x38\x46\xf1\xf8\x7c\xbe\x01\x09\x43\x25\x51\xa0\x3c\x1e\x11\x39\x6b\xe8\x55\xb0\xcb\xbd\x16\x9d\xb7\x39\xae\xc4\x56\x17\x1a\xed\xda\x51\x50\x15\xa2\xc0\x07\xcc\xc8\x7f\xf0\xe0\xdb\x63\x80\xba\x78\x3f\x1e\xc8\xcc\xe9\x05\xdc\x89\x81\xe5\x0a\x42\xce\x0a\x19\xba\x20\xc8\x4a\x50\x0e\x5c\xd3\x8b\x7c\x37\x7b\x8b\xeb\x58\x49\x47\x81\xf4\xdf\x2e\xa7\x58\x4d\x9e\xde\x1b\xeb\xe7\x11\xec\x71\x70\xd4\xeb\xe5\x0b\x31\x85\xa9\x02\xd3\x89\x81\x85\x9d\xd2\x72\xed\x8d\x74\x5b\x81\x9a\x83\x0f\xa2\x5d\x34\x1d\x29\xd7\xe7\xd8\x6c\x2f\x2f\xb3\x2d\x42\x5c\xfd\xe5\x60\x95\xa5\x6a\x5f\x67\xb6\x30\x10\x90\x25\xd2\xc2\x32\x01\xa4\x9c\x6a\x91\x8e\xb0\x73\xae\x21\x71\xe8\x5d\x03\x51\x8c\x9d\xa0\x8f\xe6\x38\x9f\x03\x77\x4e\x6e\x4f\x4d\xf6\xc8\x67\x6a\x89\xf9\xdf\x0a\x27\xaa\xa3\x81\x04\xec\x5b\x89\x12\xf3\x26\x08\x0f\xe1\x2a\x80\xc8\x76\x3a\xf6\x9b\x2a\x5d\x8e\xc7\xa3\xd7\x85\x15\x4d\x15\x55\x98\x1a\x01\x0a\x1a\x4f\x6d\x96\xa7\x5d\x48\x0c\xac\x49\xf5\x82\x56\x54\x40\x37\x2d\x72\xf7\x3a\x11\x2c\xce\x0e\x39\xa2\x2b\x24\x62\x23\x68\xbb\x28\x5b\x3f\xd2\x4e\x6c\x5e\x52\x27\x03\x88\x97\x1f\x05\xd9\x9f\x23\xb9\x19\xa7\xbc\x30\x2c\x36\xdb\xcf\xf3\x82\x26\xc7\x85\x19\x12\x1d\x8e\x73\xe9\xbc\x7b\xbf\x7f\xcf\x77\x08\x0a\xc6\x97\x41\x76\x7c\x52\x40\xd6\x7c\x2c\x55\x49\x59\xf6\x73\x82\x2b\x4a\x88\x47\x86\x22\x52\x9d\xda\x45\x74\x6a\x1e\x1c\xbf\xa0\x4f\xc2\x9a\x1f\xd8\xc3\x72\xf8\x78\xb7\x7f\xbe\x64\x6b\x60\xaf\xb8\xbb\x89\x3c\x5b\x3f\xbf\xfe\x5d\xfd\x4f\x99\xd0\x04\x2c\x36\xe7\x5b\x21\x51\xec\xa9\xd3\xe2\x38\xb6\x27\x97\x45\x3c\x7b\xbb\x48\xea\x96\x2e\x3f\x48\x87\x02\x01\xa4\x43\x56\xb8\x7c\x84\x9d\x36\x4b\x23\x34\x05\xa2\xca\x17\xe4\x6a\x16\xb1\xbb\x17\xe2\x45\xcd\x91\x4a\x25\x32\xde\xc0\xf2\x07\xf1\x5a\x52\x83\x6e\x75\x10\x18\x13\xcd\x70\x27\x18\x2e\x6f\x8b\x02\xd6\x46\x54\x6b\xe6\xff\x08\x65\x3d\x7a\x57\x10\xc6\xe7\xe5\x65\xeb\x5e\x2c\xd4\x1b\xeb\xd4\x3e\x39\x4c\x5d\x8e\xd9\xdb\xc2\x59\x3b\x1d\x84\x45\xc0\xb9\x63\x13\x04\x5c\x26\xd3\x5f\x2c\x00\x85\xd7\x9c\x89\xab\x98\x9b\xfa\xb0\xa8\x6c\xe7\x84\x76\x58\xe5\x4b\x62\x16\x5c\xfc\x35\xcc\x0e\x6f\x35\x7c\xfe\xbe\x60\xe5\xfb\x7c\x03\x7a\xc9\x91\xf9\xfd\x40\x9e\xb3\x8b\x85\x06\xdc\x16\x77\xa5\x8a\x23\xf7\xfb\x43\x75\x68\x8e\x7e\x9d\x14\x6c\x0b\x6e\x61\xc6\x92\xe8\x38\x5a\x4d\xc4\x56\x2c\xff\x30\x87\x1c\x33\x87\xb5\xcd\x05\x61\xe0\xa4\x05\xf9\x55\x8d\x53\xdf\x83\xe3\x0f\xb0\x10\xd3\x39\xeb\x01\xa9\xbb\x5c\xaa\x3c\x53\x8e\xd3\xb6\x60\x31\xc3\xf3\x29\x8b\x1c\xbc\x48\x86\xd0\x29\x45\x41\xed\xda\xbc\x35\x08\x0c\xcc\x73\x0f\x72\xd6\x4c\xae\xc8\xd3\x6b\x7b\x3b\x05\x71\x7a\x79\x3a\x5d\x85\xf3\xfd\xae\x73\x53\x10\xf9\x75\xe9\xa9\x72\x1c\x11\xca\xfb\x63\xa9\x7c\x5e\xbd\x2f\xd6\x7f\xc5\xd1\x37\x64\x54\x35\x33\xc1\x8d\xbc\xbd\x48\x3f\x9e\x3e\xa6\x84\xe9\x8a\x87\x79\x30\x4a\x44\x99\xf7\x4a\x80\xed\x68\x3e\x2b\x81\x2f\x99\x74\xe0\xe1\x36\x3d\x1a\x7a\x43\x4a\x89\x8b\x8d\x18\x98\x83\xff\x6d\x3e\xd7\xff\xfe\xef\x41\x48\xcb\x3a\x48\xa9\x6c\xe4\xd6\xb0\xa7\x4e\x9e\x0a\x20\xf1\x65\x63\x9b\x92\x65\x82\x5f\x63\x24\xc1\x3e\x55\x0f\xb8\xfd\x42\xea\xdd\x3c\x4a\x13\xca\x3e\x67\xd4\x7a\xcd\x88\x35\x61\x2e\xf0\x20\x85\x4d\x1c\x4d\x07\xe9\x1e\x58\xa8\x33\xa7\xbc\xc0\x29\x2d\x88\x74\xf1\x20\xcb\x0b\x41\xcb\xbd\x59\x71\x92\x2d\xba\x6c\x36\x0f\x6d\x76\x26\x33\x45\x4b\x05\xa5\x49\x64\x6c\x5c\x0a\x4d\x99\x56\xb1\x3b\x2c\x06\x75\xe7\x6e\xc9\x84\x87\x99\xc7\x90\x7b\xe6\x67\xbe\x7f\xfc\xbb\x12\x5b\x42\x85\xf2\xc9\x18\xef\x84\x6c\xc9\xcd\x43\x5f\x38\x74\x47\x2a\xcd\xe9\xa7\x9d\x19\x37\x13\x1a\x46\x51\x7f\xfd\x3c\x0e\xc6\x47\x5d\x70\xc7\x97\x3d\xf8\x3d\x1c\x7e\x0f\xac\x37\x80\xdf\x9c\xdd\x1e\xa1\x50\xbe\x4f\x25\x11\xf0\x9f\xa2\xb7\x87\xd4\xac\xcf\x5d\xd3\xb2\x31\x85\x71\x36\xff\x2e\x52\xdb\x82\x4f\xa0\x52\xee\x9b\x05\x26\xb5\x40\x1e\x55\x6a\x1c\x04\x8c\x74\x36\x1c\xa5\xb1\xe6\xfe\xc1\x20\x34\x11\xb8\x8e\xee\x56\x68\x68\x6f\x5b\x98\x89\x2c\x01\x28\x80\xf1\x78\x57\x1a\xf1\xe3\xe5\x22\x78\x86\x66\x0c\x7a\x6d\xee\xf2\x9f\x52\xbb\x80\x02\x9d\xfb\x66\xcc\xe9\xe2\x22\x38\xa3\x84\x99\x3c\x56\x83\x5f\x38\x48\xc1\x44\x11\x0e\xfb\xd5\x7d\x7f\x7f\xff\xbe\x63\x8d\x40\xcc\xc6\x8c\xf9\xe4\x48\xc6\xca\xb9\x7d\xb7\xd2\x0d\x47\xc6\xea\x83\x16\x5c\x29\xf3\x4e\x41\x9f\x99\x6f\x35\x4c\x84\xa5\x10\xca\xfa\xd8\xac\x0a\x8e\x6b\x54\xf7\x5c\xde\x27\x8d\x18\x10\x8e\x85\x33\x3e\x0f\x3a\x9f\x15\x0c\x9c\x39\x39\x89\xeb\xcb\x69\x08\xc7\x37\x24\xcb\x5f\x03\x48\x6f\xb3\x3f\x73\x03\xda\x6a\xaf\x29\x55\x7f\x15\x74\x10\x78\xd3\xdf\x2d\xac\x3a\x4a\xbd\x20\x9a\xe4\x89\x17\x87\xe0\x68\x3a\x8b\xbb\x5f\x78\xff\x2c\xaa\xab\x33\x33\x20\x88\x94\x4c\x9d\x9a\xa9\xa6\xb7\xbf\x2c\x84\x81\x84\x53\xf3\x4b\xc3\xb6\x09\x43\x9c\xed\x06\x61\x42\x73\x7e\x35\x1c\x8f\x25\x3f\x29\xbc\x27\x48\x3c\x88\xfa\x92\x64\xbe\xf9\x77\xa5\xd1\x37\x45\x44\x45\x58\xd8\x17\xfa\x35\x33\x1a\x0f\x11\x1c\xc4\x57\xa7\x8a\x66\xe8\xf9\x6b\xfe\x1f\x2c\xb3\xfa\x8f\xff\x0f\xef\xfe\xd5\x91\xac\xa9\x99\xa8\x52\x13\xba\xd1\x65\x35\xe7\x7f\x7c\xfb\x77\xc5\xa4\xf6\xa5\xf8\x72\xca\xa3\xcf\x41\xcc\x00\xf9\x92\x49\x0b\x36\x9b\x07\x93\x5a\xc1\x33\xfd\xbb\x62\xe3\x5e\xaf\x10\xa5\x76\xa8\x51\x45\xd0\xa6\x2f\xb2\x49\x2a\x1c\xa4\x11\x79\x25\x98\x96\x3e\x6c\x2c\xd9\x15\xbf\x3c\x15\x36\xe0\x57\xc1\x12\x12\xe2\xcd\x1a\x03\xdd\x65\x52\x65\x01\x02\xe3\x77\xfa\x56\x1a\x31\xb0\xc3\x3c\x3b\xfe\xb6\x15\x32\x9f\xbb\x22\xca\xa8\x64\xa8\x89\x2a\x15\x68\x1f\x1e\xa1\xe6\x2e\x8b\xb1\x9c\xe9\xde\xbc\xf0\x74\xfc\x0b\x4f\xc6\x70\xf6\x37\x24\xd3\xb4\x38\x6c\x22\x25\x38\x32\xba\x9a\xf9\xe3\xce\x5b\xab\xbd\xb9\x16\x7f\x81\xbe\xab\x45\xc4\x19\x90\x18\xcf\x25\x73\x52\xdc\x25\x9f\xc1\x3f\x09\x1e\x11\xd6\xfb\xe4\xc4\x1e\xca\x3c\xb0\x9b\x09\x04\x72\xdb\xcf\xc8\xa1\x21\xc5\xde\xbc\x10\xd3\x69\x54\x04\x80\x86\x7e\xfa\x73\xa5\xf1\x05\x05\x5d\xe6\x38\xd9\x39\x5b\x43\x5b\x08\xaa\x44\x3e\x6b\x4e\x41\xb5\x87\x41\xd8\x34\x11\xfc\x9a\x99\x0f\xa4\xf9\x33\xb7\xb9\xe7\xca\xbc\xba\xc5\x1a\x4f\x9d\x2d\xa2\x12\x1d\x63\x53\x38\xd9\x6a\xd1\xa2\x7b\xe2\x83\xca\xb6\xb5\x6b\x51\x9f\x91\x64\x9e\xdc\xad\xaf\xdc\x39\x17\xd8\x29\xb0\x39\x9e\xcf\xdb\x5f\x4a\xe2\xc1\xf3\x22\xac\xaa\x2c\x8f\x75\x28\x3c\x1f\x9b\x88\x6e\xbc\xc6\x7e\x26\xf8\x54\x33\xce\xec\xb6\xa9\xba\xdb\x2e\xf6\xda\x06\x54\x57\xb9\x39\x1a\x7e\xd4\x93\x67\xa7\x8f\x0f\x76\xf3\x21\x55\x26\x22\x42\xdb\x34\xa6\x18\xbc\x86\x26\xd6\xbd\xe4\x03\x5e\xd9\x6a\xbc\xee\x13\x46\x4b\x56\x64\x69\xf0\x67\xe2\x54\x26\x2e\xfa\x3c\x08\x6c\x84\xb0\x57\x79\x22\xba\xca\xbb\xd3\x2e\x05\xd5\xd4\xf4\xca\x25\x2e\xa3\xc6\x48\x78\x4e\xf1\xc4\xac\x13\x0a\xc7\x28\x4f\x1c\x68\x33\x0e\x1f\xc7\xcf\x77\x82\x53\x93\x1d\x51\x98\x4b\x8e\x59\x60\xa6\xb9\x8c\x19\x0b\x02\xff\x76\x9c\x7b\xa3\x92\x85\x0a\x52\xb2\x63\x60\x40\x3c\xe8\x14\xab\xc9\x23\x2f\xb8\x84\xe5\xd8\x1e\x9b\xf7\x99\x75\xe9\x2b\x47\x7f\x99\x3e\x26\xee\xed\x71\x37\xb5\x88\xb2\x5f\xa1\x1a\x74\x6a\xc4\xbc\x2f\x8c\xbb\xd6\x5e\x69\x1d\x51\xf0\xa3\x60\x17\x8e\xf5\xbb\xbf\xcb\xe1\x35\xb7\xfa\x96\x21\x7f\xec\x09\xec\xf3\x99\xcb\x89\x71\xc1\x42\x98\x74\xaa\x95\x98\x5b\xb2\x0b\xb3\x6a\xde\xc5\x4e\x2e\xc9\x49\x8c\x67\x67\x01\x51\x0e\x47\xc8\x6d\xed\x03\x53\xe1\xc1\x79\x6e\x13\x9e\xc3\x7a\x5f\xbe\x45\x49\x2b\x0a\x7a\x8d\x5c\xa5\x57\x30\x0c\x62\xa5\xea\x4a\xab\x60\xcb\xf2\xad\xf7\xac\xd3\x71\x65\x5d\x77\x2e\x14\xc1\x4b\x10\x41\x47\x5d\x66\x23\x79\x58\x44\x4f\xfc\x51\xa8\x86\xa3\x18\x0f\x2f\x79\x7a\x30\x7f\x9f\x34\x99\xea\xf8\xe3\xdf\xf6\xe0\xfe\x90\x0e\xf9\x38\x7e\x79\x34\xed\x8f\xde\xfc\x1b\x52\xe4\x3d\x6e\x03\x79\x34\xa6\x6e\x66\x2b\xe4\x10\x9e\x61\x51\x30\xba\x48\x95\x43\xbf\xc1\xd5\x2f\xa3\x52\x5c\x75\xab\xcf\xdb\xeb\xb2\x7c\xe0\x11\xa0\x2b\x50\x8d\x5b\x69\x9a\xbf\xba\x7e\x47\x78\xfc\x89\x4d\x71\x9d\x53\x16\xb3\x0d\xac\x2d\x95\x29\xd3\x60\x27\x06\x02\x9a\x74\x7a\xd0\x09\x55\xd3\xb6\x0f\xcc\x62\x2e\x60\x63\x31\xad\x19\x70\x7d\xaa\xeb\x4e\x4a\xc7\x5c\xe9\xc0\x99\x78\xb0\xf8\x7f\x31\x9b\x3d\x26\x42\x55\x91\x36\xf1\x28\x29\x15\xe2\x6a\x27\x06\x9a\x84\x7e\x10\x19\xcc\xd5\xaf\x8d\xaf\xa0\xfe\xaf\xe0\x7b\xfa\x1a\x3e\xef\x4d\x99\x68\x37\x0b\x2d\x2f\x24\x04\x4a\xe2\x15\x0b\xe1\x1c\x03\x66\x02\x45\x57\x57\xcb\x3a\x96\xc1\x21\x8b\x2a\x36\x66\x4d\x61\xf9\x9c\xc3\x38\x30\xb8\x09\xbb\xad\x8a\x9f\xef\xcf\xcf\xba\x13\x65\x4a\xf3\xb7\x8a\xde\x5b\xc5\x79\x8b\x9e\x7f\x27\x09\xb4\xc6\x4e\xb6\xd3\x1a\x5a\xb6\xcb\xcf\xb2\xc9\x1c\x31\xd6\x01\x7e\xb9\xbd\x06\x81\x9b\xdb\x11\xca\x2c\x54\xbb\x40\xc2\x4e\x33\xd3\xd1\x4d\xde\x1b\x72\x1b\x38\x12\x57\x74\xf5\xf9\x35\xb6\xa3\x07\xbe\x1b\xe1\x65\x9f\x9e\x29\x30\x1e\xb5\x95\x84\x9b\x57\x06\x8b\x80\x58\xf9\x51\x91\x59\x05\xa7\xcd\xa9\x29\xa9\x90\xc0\x8b\x58\x01\xeb\x34\xc8\xaf\x0c\x65\x78\xf5\x2c\x5c\x1b\x26\xb4\xf8\x0b\x1d\xea\x04\x67\x36\x3e\xd5\x6e\x0e\xcc\x17\x6d\xc8\x13\x4e\x3c\x08\x3e\x8e\xd4\x37\xa5\x69\x6f\x59\x5e\xad\xcc\xad\x5b\x1f\x64\x32\x4b\x73\xfb\x5f\x8f\xcb\x56\x48\x4d\x83\x29\xb9\x07\xf9\x65\x5a\x67\x8c\x42\x55\xd0\x19\x39\x14\xb6\x95\x41\xca\x16\xe3\xaa\xd0\xef\xf7\xcc\x55\x47\xef\x2c\x5e\x71\x71\xa8\x36\xba\x63\x92\xf8\x6f\x3c\xd7\x5c\xf8\x20\x87\x91\x3d\x09\x9e\xdf\xa3\xbb\x83\x91\xa4\x38\x4f\x51\xe7\x29\xe6\xdb\x8e\xa2\x9d\xb3\x73\xd3\x77\x7b\xbc\xba\x42\x3d\x42\xc6\x21\x71\x20\xaf\x1f\xbd\xaa\x38\x1d\x28\x16\x15\x4a\xa7\xc7\xf3\x41\x6c\xa0\x8f\x39\x66\xb2\x3f\x09\x3f\xe0\xa3\xd8\xd9\x79\xe6\x33\x18\x09\xca\xb6\x37\xf8\xfc\x91\x46\x2b\x83\x51\xff\x7a\x24\xeb\x02\xbb\x31\x85\xaf\xc6\x2c\xaf\x8c\xd1\xf9\xf0\x66\x6d\x32\x8f\x9e\x5e\xcc\x31\xad\x73\x9f\x8c\x85\x9f\x53\x52\xe8\x0e\x89\xc0\x0c\x1e\xa8\x92\x66\xd3\x4e\xee\x63\x64\xe5\xaa\x8d\xf0\xad\xcd\x68\xf1\xff\xff\x82\x41\x10\x3a\xa0\xfa\x1e\xc6\x0e\x82\x8a\x14\x2b\x4e\x1d\xa7\x72\xb1\x38\x1d\x5e\x93\xe5\x50\x85\x54\x79\xe7\xa1\x55\x72\x18\xb7\x88\xa8\x38\x83\x88\x3c\x0b\xb3\xb9\x85\x38\x72\xc7\x42\x43\xed\x59\x53\x62\x4a\x9e\xa9\x7b\xc2\xa6\x3e\xfe\x36\x00\x41\x11\x83\x2b\x0b\x62\x18\xc7\xb8\x14\x17\xe8\xde\xed\x65\x6c\x4d\x7c\x45\x24\x59\x66\xfc\x73\x1a\x44\xa5\x49\x35\x75\x99\x5d\xcf\xfa\x10\x5c\x60\x5e\x2a\xc0\x5d\xd4\xa3\x0f\xba\x71\xaa\xce\x40\x0d\x78\xce\x9f\x44\xb8\x1c\x7b\x8c\xc5\xf7\xc9\xc1\xf5\x50\x40\xfc\xaf\xe1\x02\xfb\x82\x5e\x8f\x1d\x83\xbb\xb3\x38\x53\x42\x1b\x46\x0e\x12\x06\x3d\xf4\x58\xba\xa7\x46\x02\x34\xc5\x38\x4f\x7a\x60\x78\x2e\x69\x66\x1d\x80\x49\x6c\x7f\xea\xf8\xeb\xdf\x94\x47\x56\x22\x6f\x7f\xb9\x88\x75\x13\xfb\xbc\x13\xc8\xcd\x3c\xdc\x8b\xf0\xa9\xa2\x95\x9c\x77\x4e\xc1\xd2\x60\xc8\xd9\x01\x45\x43\xe1\x12\xff\x60\x19\xcb\xdb\xe3\xee\x84\x05\xd5\xb1\xa1\xcb\xf1\x27\x63\xee\xe2\x31\xac\xef\x82\xba\x80\xcb\x69\x5f\x0b\x5f\x80\x85\xad\xaa\x15\x8f\xc5\xec\x30\x06\xac\xd0\xc2\xc5\x33\x63\x2e\x1a\xea\xb9\xe3\x43\xa3\xe4\xdd\xf9\xd5\x08\x28\x9f\x0b\x0a\x49\x70\x0b\x1e\xff\xd2\x96\xd0\x78\x0e\x4e\xa4\xf2\x1a\x64\x0a\x7d\x4a\x11\x10\x4d\xf2\xfd\x39\xca\x0f\x7d\xd8\x47\xec\x3b\xc7\x49\x82\x13\x11\xd9\x25\x24\x75\x87\x5d\xb2\xe8\xf3\xbc\xc8\x5b\x6a\xeb\x46\x7e\xa9\x70\xe2\xd4\x7d\x4f\x0a\xe0\x1d\x40\xeb\x4c\x2f\x6a\xa0\x7b\xe7\x2e\x8e\x86\x13\x7b\x79\x56\x0c\xa3\xd7\xd8\x25\xc2\x1f\x39\xdc\x17\xdb\x9e\x39\x8f\x96\xbc\xd9\x30\x92\x9c\x1f\x7e\xd0\xbe\x0b\x28\x0c\x13\x81\x8d\x37\xb7\x20\x32\xb4\xf7\xcf\x90\xa5\x34\xdd\xff\xc4\x4d\x0e\xc3\x8d\x9b\x76\x4d\x6b\xc9\x40\x3c\xd4\x1e\x73\xf8\xfd\x79\xe7\x59\xda\xb7\x04\x5c\xe3\xd3\x47\x91\x81\x8a\xc2\x3b\xe7\x27\xe1\xc8\x5e\x14\xf4\x43\xa1\xe9\x58\xc7\x50\x46\xd4\x83\x7d\x9b\xc1\x85\x99\x4e\xfa\xad\x7e\x95\xa0\x45\xc7\xe4\x24\xaa\xc7\x73\xa6\x06\x37\xaf\x0c\xc9\x9d\x79\x4b\x80\xb9\x01\xa6\x25\x9e\x1f\x87\x2e\x10\x08\xbc\x9b\xed\x62\x1b\x6f\x30\x67\x89\x05\xd3\x8e\x10\xa2\x13\x86\x4c\x12\x43\x84\xa9\xba\x7c\x38\x65\xcf\x9d\x57\xe2\x2f\xf7\x9f\x6f\x47\x6c\x22\x10\xf5\xcc\x66\xd5\xb4\x12\x91\x58\x56\x1f\x4e\x85\xc6\x45\x73\xa0\xc8\x53\x94\xef\x9a\x17\xd0\xc4\x52\x62\xe4\x7c\x8f\xf5\xa5\xc5\xd8\x6c\x22\x94\xab\x2d\xe0\x17\xb5\x12\x9a\xaa\xcd\x58\xc8\x16\x80\x03\xd6\xaf\xeb\x7f\xf9\x17\xd6\xd3\x0c\x39\xd1\x13\x16\x30\xa9\xe4\x92\x97\x91\xb5\x54\xf6\xc0\x7f\x1c\x09\xcd\x32\xc5\x39\xd1\x45\xf3\xfa\xa2\xdc\x61\x4d\x06\x05\xcf\x4f\xe4\x71\x05\x49\x8b\x1d\xfb\x2c\x39\x7f\xf1\x85\x09\x1a\x71\x78\x13\x62\xa9\xb1\xf0\x13\x52\xfc\xdc\x38\xed\xff\x8e\x9e\x5a\x9f\xc0\x86\x68\xab\x0f\x17\xea\x2f\xb3\xe1\xf0\x5d\xc3\x6b\xee\x99\x33\x59\x57\xff\xa3\x79\xfd\xac\xbe\x62\x86\x39\xa5\xbb\x25\x74\xce\x49\x6b\xc8\x93\x7a\x13\x9d\xd6\xfc\xd0\x28\x4c\x30\xc7\x20\xff\xf4\xe2\x31\x98\x32\x55\x42\xed\x04\x04\x5a\x77\xf4\x19\xfb\x64\x0f\x91\xb5\x62\xde\x9d\x5f\x6a\x6c\x05\x06\x70\xe7\x99\x65\xa3\xcb\xe5\xc5\x67\xfe\xf7\x08\x4d\xbc\x39\x31\xf3\x88\xe0\xde\x9c\x40\xb8\xd6\x1f\x5f\x60\xbd\xd4\x1c\x1c\xb8\xc7\xaf\x59\x06\x22\x2a\x86\xa2\x08\x00\x60\xac\x7b\xfd\x64\x4c\x03\x1f\x11\x4b\x7f\xc9\xc3\x05\xcf\x5c\x4a\x03\x06\xa8\x33\x28\xf3\xfb\x36\x25\xd2\xbd\xaf\x9b\x36\xe0\xec\x72\xa5\x2d\x38\x02\xfe\xe2\x35\x38\x92\x64\x61\x18\x9c\xef\xca\x47\xbc\x16\xa0\x37\x3d\x5f\x0d\x49\x87\x53\xb4\x7d\x3d\x04\xa8\x19\x7d\xee\x2c\x95\xc9\x90\xe1\x10\xbb\x5d\x56\x77\x86\x5f\xba\xd0\x29\x8d\x1d\x84\x56\x23\x6f\x26\x8d\x3f\x1a\x1d\x81\x36\x31\x67\x80\xd3\x4a\x91\xfd\x25\x1f\xf5\xc0\x76\xfa\x47\x78\xb0\x0f\x7e\x56\xe4\xef\x4c\x01\x14\xcf\x42\x7f\x25\xce\x4a\x4c\xad\x42\x5d\x30\x9d\x4e\x61\xd2\x48\x5d\x71\x8f\x0d\x25\xa9\x75\xce\x6b\x9c\x7b\xfa\x30\xde\x33\x4a\x74\x77\xb4\xd3\xce\xd2\x4b\x78\x66\x61\x62\x54\xf0\x57\x33\x7b\xf7\x98\x57\x7a\x2d\x65\x18\x74\x18\x0b\x2f\xba\x60\xd8\xa6\xe5\xa9\x5f\xed\x99\x51\xe0\xf8\x14\x59\x5d\xec\x44\xf9\xde\x9a\xbe\xe5\xb4\xf0\xa4\x79\x35\x1c\x42\xa4\xce\x1b\xa7\xc4\x77\x11\x7c\x80\x6e\xf3\x55\x7a\xcc\x4b\xeb\x7b\xe2\xdd\xd7\x50\x9b\xf3\x52\x88\xe5\xec\xd1\xdc\x73\x04\x9f\x53\xfc\xf8\x2b\xf6\xa1\xf4\x72\x37\x65\xc0\x9c\xb9\x57\x0a\xf6\x90\x5c\x85\xde\xda\x91\x03\x9e\x5e\xed\xc7\x28\x0e\x51\x61\x3f\x88\xf7\x34\x2d\x63\xc6\x1b\xad\x24\xde\x96\xc7\x7e\x78\x9f\x0a\x59\x83\xc0\x93\x63\x93\xa1\xf6\x63\xf1\xd4\xd6\x79\x28\xfc\x2b\x28\x15\xa9\x78\x82\xd9\x6f\x34\xfe\xa5\xe0\x34\xfa\x4b\xd2\x0b\x01\x8d\x67\x9c\x9f\x1d\x9f\xec\xad\x9b\xea\x90\x0c\xa4\x1c\x40\xb3\xf7\x4a\x79\xb4\x10\x07\x08\xa4\xa5\xb0\xbf\xa0\xaa\xc4\xbe\x6f\x55\x08\xdb\x32\x17\xb2\x5d\xd2\x49\x24\xa4\x3e\x52\x33\x70\x54\xe9\x6b\xd4\xe0\x1f\x19\x98\xf7\xc3\x7d\xbc\xbf\x7d\x13\xc5\xe3\x6c\x4e\xc0\x3a\xc3\x02\x72\x35\x9d\xb7\x89\xab\xb9\x06\xc4\x73\x6d\x68\xd9\x1a\x3e\x3e\x54\xf3\xaf\xf3\xed\x86\x1b\xf0\x0a\x1b\x07\xa5\xb8\x43\xa9\x8a\x94\x07\x85\x1e\x00\x54\x0c\x15\x39\x68\x60\x18\x0a\x91\x45\x7a\x61\x85\xd5\x49\x05\x6d\xcc\x71\x26\x4c\xcd\x94\x0d\x5d\xcd\xe5\x42\x32\xd4\x74\x00\x7d\x59\xaf\x98\x0f\x8a\x13\x41\x32\x97\x4a\xa3\xd3\x96\x23\x07\xdb\x72\x48\x20\x3d\x0c\x0d\xce\x03\xe5\x17\x1e\xc4\x93\x39\x60\x20\xfe\xd4\x70\x44\x17\xb7\x25\x13\x99\x89\xde\x42\x9c\x09\xfa\x9d\xd3\xc4\x97\xd7\x72\xb7\x00\x0f\xa1\x2b\x58\x02\x05\x80\x4c\xf9\x08\x6c\x65\x0c\x33\xcb\x80\x7d\x1f\xf1\xa2\xd7\x76\x41\xa6\xca\x3b\x84\x54\xfe\x34\x13\xaf\x46\xac\xb4\x6c\x35\xeb\xe0\x19\x23\x56\xa9\xd5\x1b\xb5\x32\xfe\x15\x44\x09\x54\x2d\x18\xaf\xbc\x2a\xa3\xf4\xd7\xbf\x16\x9a\xfd\x3f\xfc\x06\x90\x7f\x53\x43\x10\x90\x10\x39\xac\x65\x8a\xa3\xed\x3b\x8a\x42\xe5\x48\x4c\xf1\xbe\x11\x88\x92\xeb\xf6\x41\x98\x6b\xdc\x97\x78\x21\xc3\xec\x38\x92\xbd\xab\x39\xff\xde\xee\x9f\xc8\x0e\xd8\x76\x2a\x3c\x40\x8f\x3c\x60\xf2\xa6\x9d\xd7\x1b\x22\x80\x1b\xc3\x5d\xc7\x31\x8d\x0a\x22\xa2\x26\x73\x4f\x0a\x85\x93\x26\xad\x01\x28\xba\x11\x6a\xf8\x94\x0d\x7d\x3f\x1c\x58\xbd\xf0\x80\x4c\x82\x84\xee\x1e\x66\x9f\x26\x75\x58\xad\x79\x1f\x34\x43\xc2\x99\x28\x60\x96\x2f\x8b\xda\x6d\xe0\x1a\xb3\x24\x50\x98\x1c\x40\xbf\x06\xbb\xa3\xb8\x62\x07\xcd\xe1\x29\x29\x1f\x1a\x68\x0e\xf1\x0e\xc7\x4a\x59\x02\x6a\x13\xf3\xdb\xf7\xff\x54\x03\xfc\x51\xed\xc8\x30\x65\x02\xbd\x7c\xc3\x99\x40\x3d\x25\xef\x0f\x02\x34\x17\xfe\xf0\x59\x55\xc6\x7d\xe0\xb4\xc9\xab\x85\x3e\x8f\x85\xf9\xc5\x7d\xd6\x54\xdc\x51\x96\xcb\x87\x1a\x99\x2e\x24\x88\x60\x57\xf3\x89\x99\x95\xa0\x6e\x01\x2f\xc0\x30\x26\x9c\xb2\x73\xda\xb2\x5b\x2c\xd7\x1a\x22\x99\x0b\x28\xc0\x3b\x16\x10\x30\x3b\x21\xcf\x8d\xcc\x76\x7d\x34\x95\xca\xa4\x6a\xde\xc9\xc5\x6e\x31\xdc\xa4\x12\x6d\xfc\xab\x49\x38\xfe\x89\x09\x2d\x67\x67\xe4\x2a\x61\x28\x15\x2e\xc1\x3b\x45\x89\x73\xf6\x66\x95\x54\x3a\x46\xc8\xc7\xfd\x41\x76\x6f\x80\x5c\x5f\xec\xe7\x68\x07\x87\x78\x14\xed\xb1\x2a\x6b\x87\xfc\x7f\xd1\xa5\x7a\x34\xec\x1d\xab\x2d\x83\xa7\x0d\x71\x78\xd7\x9a\xa0\xc6\xf3\x4e\xf0\xe1\x18\x5b\x62\xf0\x1c\x97\xc2\xb1\x20\x62\xa4\x83\xfb\x81\x38\x5f\x24\x76\x70\x44\xde\x90\x73\xf2\xf4\x2b\x7b\x4e\x46\xc4\x5d\xdf\x9f\xfe\x6d\x0f\x3e\x7f\xfc\x1b\xc7\x1b\x5e\x4c\x45\x17\x97\x30\xd7\x36\xe5\x1e\x9e\xf4\x3e\x3b\x2b\x0a\xcc\xaf\x1d\x90\x8a\x7e\x80\x8a\xc9\x9a\xbd\xcc\xa8\xc4\xd3\xc7\x3c\x70\xe9\x72\x01\x58\xc2\x01\x44\x74\xb3\x1e\x1b\x13\x21\xf7\x46\xf5\xda\xb4\x68\x0a\x9a\xad\x39\xb1\xe7\x5e\x82\xd6\x9d\xbc\x26\x72\x1d\x5e\xa4\x79\xb5\xf7\x3b\x09\xb1\x50\xcb\xe4\x7a\xbb\x1c\x51\xa9\xc8\x7d\x02\x3e\x85\x91\xc2\x50\x8f\x1e\x54\x16\xa8\x9c\x3a\xac\xcc\xc1\x9d\x34\xab\xa4\x0c\x6d\x9a\x17\x36\xf5\xdb\xaa\x6f\x8f\x99\x55\x42\x1f\x89\x43\x18\x92\xc5\x07\x1c\xba\x32\xb8\xb5\x3a\xe8\x01\x89\x03\x96\x02\xcb\x3d\x90\x9f\xfc\x70\x7c\x11\xb1\x9a\x73\x51\xf0\x97\x66\x3f\x40\x7f\xe4\xee\xb9\x52\xc8\xa7\xcc\xb6\xe9\x36\xb7\xec\xa5\x54\x7b\xba\x27\xe2\x46\x32\x91\x82\xca\x33\xeb\x34\x0b\xa2\x5e\xca\xc1\xce\x2c\x47\x86\x2c\xa9\x40\xb0\x3f\xb0\xb2\x30\x94\xa1\xcd\x73\x3c\x81\xc8\x28\xb6\xbb\x90\x08\x85\x55\xdb\x8c\x7d\xaf\x46\x7c\x73\x4e\x38\xa2\x8d\x93\x12\x28\xf9\x53\x49\x90\xb1\x3f\xbf\x26\x82\x7f\x6a\xc5\xd1\x7a\x7d\xa1\xd2\xae\xa6\x0e\x90\x23\x99\x30\x88\x8b\xf2\x8f\xb2\xc0\xcf\xb7\xfd\xe3\xff\xb3\x5c\x04\xbf\x73\xdd\x57\xfa\x84\x1c\x9f\xc4\xfe\x7e\x2f\xf5\x95\x56\x21\xf6\x04\xf8\x70\x7c\xc6\x19\xe6\xab\x98\xb5\xb9\xe8\x48\x68\x92\xa1\x3f\x0c\xfa\x29\x85\xbf\xe5\x22\x24\xe7\x28\x5f\xd0\x55\xa0\x62\x6c\xf9\xb0\x23\x26\x0e\x2b\x9f\xaa\x0c\x60\x0e\x6d\x19\x56\x89\x14\x17\x1f\x10\x00\xe0\xc3\xbe\x59\xc5\xc0\x4c\xed\x8a\x58\x5a\x69\xa3\xef\x9f\x5f\x92\x73\xfc\x8d\x7b\x6a\x2c\xac\x0c\xfc\x00\x33\xb8\x9d\x46\x26\xaf\x1a\x26\xf3\x97\x6a\xe4\xa6\x5a\xa8\x4d\xb1\xca\x6a\x60\xfe\x63\x2c\x45\x25\x6c\xc3\x6d\xef\xfb\x0b\x03\xf0\xf7\xc8\xdc\x15\xfa\x99\x0e\x0d\x92\xc1\xcb\x52\x97\x6b\x43\xd1\x9c\xcc\xfc\xe3\x0a\xbc\xc6\x83\x49\xec\x41\x49\x21\x87\x63\x31\xa1\xe5\x09\x1c\xf1\x69\x4a\x03\x79\xe8\x83\xfa\xe6\x25\xdd\x84\x5a\x9b\xfe\x66\xa4\xcd\xf4\x14\x50\x3b\xf9\x40\x0c\xff\x0d\x96\x1b\xcf\x87\x31\x21\x6e\x27\xf3\xc5\xc6\xb7\xb4\xa8\xff\x39\xa5\x71\xc5\xa2\x13\x69\xb7\xc0\xfe\x09\xe3\xee\x95\x6d\x01\xf7\x5f\xe8\x1b\xdd\x88\x6d\x63\x24\x01\x46\x28\xed\x6b\x2a\x2f\xf9\x1e\xd0\x42\x15\xf8\x7a\xd8\x6e\xb9\x70\x44\x4e\x6a\x08\x39\x85\x65\x64\xf0\xea\x24\x9a\x82\x8f\xf8\x40\xfb\x95\xde\xe1\xea\xc9\x11\xad\xff\x2a\x59\x38\xc2\x0f\x77\xe3\x75\x49\xa2\x22\xf4\x12\x4b\x05\x7f\xba\xc1\x79\xc5\xe0\xa5\xb5\x3c\xf8\x2b\xfd\xe3\xdc\xbc\x40\x00\x69\x75\x42\x37\x8a\xa3\x5a\x0b\x79\x4a\xe8\x70\xf8\x68\x81\x32\x5e\x80\x1c\x17\x35\x26\xc4\x32\xd9\xeb\x9c\xd7\x78\xea\xf2\x22\x9b\x61\xf0\xbd\x13\x50\xe0\xc9\x52\x55\x53\x00\xe4\x54\x5b\x80\x39\x79\x9c\x28\x65\xb1\x16\x8a\x44\x83\x27\x60\xe9\x53\xed\xec\x99\x07\x4d\xa0\x58\xda\x6a\x21\xfd\xc6\x70\xbf\x59\x34\x86\xe3\xa1\x49\x49\x8e\x95\x53\x5b\xe5\x32\xae\x5b\x69\x60\x34\x4f\x93\x93\x37\x2c\xc0\x23\x0a\xa3\x2e\x94\xee\x41\x3c\x59\xc1\x6b\xbd\x28\xea\x7c\xbe\x33\x00\xfe\x10\x01\x72\x99\xfa\xe4\xad\x97\x87\x9f\x77\x34\x3b\x0e\x8f\x32\xef\x98\x9d\x9c\x08\xa9\xbc\x6f\xa1\x30\x79\xfb\xa8\x73\x6c\x74\x66\x93\x58\xee\xcb\x8c\x84\xd0\xd4\x51\x33\x8b\xdb\xbf\x09\x74\x8f\x92\xec\xd2\x78\x4f\x8b\x50\xa7\xd0\xb1\xa1\x3b\xf3\x14\xfa\xc9\xe1\x64\xb8\xc5\xb5\x09\xb3\x37\xa1\xa0\x60\x27\x0b\x8b\x37\xed\x6e\x4c\x85\x62\xcd\xdd\x12\x02\x8d\xe6\x35\x0d\x62\x13\xf4\x1e\x57\x26\x8a\x27\x5f\x54\xc6\xb9\x20\xf2\x84\x00\xfc\xb9\xfb\xc5\xe7\x83\x29\x63\x77\xbe\xb9\xa4\xf4\x4a\xd7\xd2\x5d\xed\x98\x99\x64\xbe\x11\xb6\xc6\xb7\xb4\x26\x04\xcd\x49\x4a\x61\x80\x89\xf0\xac\x48\xcd\x92\xef\xac\xb3\xa1\x7b\xe0\xa0\xc1\xca\x8b\xcf\x02\xe6\x31\xe9\x3a\xec\x86\x29\xa5\x82\x47\x2a\x45\xf1\x7a\xf9\x7d\x7b\x5b\x08\x48\xaa\x4d\x3d\xd2\x4b\xf7\xc9\xc6\x37\x0e\xf9\x21\xbd\x1d\x8b\x8e\xe4\x28\x00\xa2\x42\x0b\x5c\xfa\x11\x9b\x51\x33\x99\x9c\x2d\xa3\x02\xeb\x4f\x27\x1b\xb3\xf9\x0c\x7a\x5a\x7c\x8b\xa3\x44\xfa\x1d\x42\xe0\x94\x00\x8b\x5a\x03\xb7\xb4\xd1\xdb\xb7\x0e\xa8\x40\x84\xba\xa8\x27\xb2\x2e\xce\x63\x1c\x7c\x0a\x37\xac\xe3\x25\x15\xee\x81\x5b\x7a\x0a\xca\xc8\xa9\x9c\xd8\x37\xcf\xd6\x2b\x0c\x33\x11\xef\x55\x25\x3a\x7e\xfe\xbc\xf9\x7f\x54\x4b\x65\x54\x8d\xf7\x02\x91\x6d\xd1\x2f\x6e\x56\xbe\x71\x09\x37\x56\x7d\x5e\x1d\x18\xb1\x26\xe1\x5f\xba\xcf\x4c\x10\x7b\x77\x09\xcf\x53\xff\x90\xbf\x43\x80\x93\x2f\xff\x46\xee\x1d\xc7\x82\xc8\xd4\x30\xd4\x15\x9a\xbe\x74\xfd\xba\x0a\xc1\x0c\x16\xff\x9b\xaf\x1f\xff\x86\x1e\x63\x63\xb3\xd9\x74\xb5\x69\x64\x44\x50\x07\x3d\x3e\x83\xb9\xd9\x8c\x39\xa9\xea\xd6\x18\x3a\x52\x1f\x65\xce\x24\x1c\x34\x56\xcc\x51\x63\x70\xa8\x6c\x3f\xcc\x83\x46\xf7\xc1\x35\xec\xf7\x9e\x07\x2a\x34\xa9\xd5\xd8\x1b\x93\x25\x10\x70\x3c\x50\x54\x83\x8d\xcb\xf9\xa9\x5e\x25\x07\x68\x36\x1c\x06\x07\xfc\x8c\x63\x74\xd4\x71\x37\x8a\x77\xf0\xc0\xbc\x06\x56\xd6\x8c\x17\xae\xa2\xb6\x33\x51\xef\x82\xa6\x7b\xbc\x06\x61\x74\x80\x26\x51\x68\xe6\xb1\xdd\x4a\x82\x72\xbc\xbd\xc3\x3b\xc5\x8c\xdf\x9a\x3b\x40\x37\xc4\xc7\x56\xac\x65\x34\x1b\x51\xe5\x6e\x0d\xe9\xe8\xfe\x87\x86\xef\x52\xe6\xe8\xed\x1b\xec\x15\xc6\x51\x95\xa1\x7a\xde\x7e\x48\xa0\xc9\xe0\xd8\x9a\x49\x55\xeb\x8b\x5c\x05\x81\x4d\x9d\x4c\x8c\xf8\xcd\xf3\xee\xd4\xd6\x38\x72\x49\x30\xe6\xd1\xd9\x90\xee\x74\x1f\x3c\x67\x88\xc4\xb6\x0f\x29\x45\xf9\x4f\x59\xf4\x8d\x07\xb2\x0e\x8b\xda\x72\xd5\xd4\xe9\x9a\xcb\x8c\x3c\xb0\x8e\x4e\xc6\x8b\x85\x72\xd0\x08\xbd\x89\x56\x31\x3f\xf3\xcc\x42\x65\x71\x8c\x9d\x1b\xb7\xb6\xc4\x66\x76\x05\xd0\x03\x5f\xbf\xc8\xce\x7f\x3b\x41\x05\x10\xfc\xb7\xe5\x98\xbe\x7b\x40\x0e\xdf\x3f\x8f\x1f\x44\x51\x48\xdb\xbb\xf6\xe4\x9f\x9d\x92\x32\xa4\xe6\x20\x6b\xe2\x29\x58\x7e\x57\x54\xd9\x9d\x1a\x16\x8e\xf0\xc9\xce\xe9\xc0\x62\xd2\xc9\x01\x06\xc8\x87\x05\xed\xc1\x49\x70\x99\x35\xf8\x25\xe2\x81\x50\x03\x66\x2c\x80\x04\xe7\x43\x4d\xb5\x6f\xd3\xb5\xac\x19\xc7\xc4\x38\x40\x46\xfd\x45\x0e\xfb\x67\x10\x18\x27\xe0\x61\xcd\x2f\xa0\x6b\xa0\x41\xea\xd5\xff\x14\x9a\x16\x62\x67\xa4\xb3\x4a\x70\x3b\x05\x6f\xf1\x40\x48\xf1\x9f\xbc\xd6\xb2\x13\x80\x53\xef\x6d\x98\xe3\x8b\xa0\x9f\x70\x2d\x53\x0f\x79\xc7\x09\x27\xbd\x1d\xb5\xb4\xa9\x95\xa2\x3f\x0a\xed\x5b\x6f\x2e\x44\xaf\x0c\x98\x1b\x6e\x3c\xeb\x50\xb1\xed\x32\x91\x38\x0d\xf5\x69\xfb\x41\x6b\xdd\x69\x2c\x93\x4b\x3a\x93\x35\xcf\xf0\x8f\x2c\x49\x98\xef\x0d\x17\xf7\xed\xed\x0d\x49\x4f\x0c\x4b\x81\xd0\xc6\x65\xa6\xd0\xac\x23\x3d\x69\x53\xae\xb7\x42\xd5\x9c\xcc\x33\x21\x57\x7b\xee\xe5\xa4\xd6\x59\x63\x03\x4c\xc8\xd8\x29\x83\x70\xde\x4f\xc5\xe1\x8d\x85\x0c\x0b\x59\x70\x6e\x30\xd2\x1d\xea\x33\xc8\x59\x9a\x9e\x41\x2e\xeb\x95\xeb\x82\x90\xcf\xd7\xfb\xf3\x1d\x85\xb9\x53\x20\x2b\x1d\x99\xae\x58\x23\xf4\x34\xe3\x11\xfb\x3e\x09\xdb\xcd\xa8\xb3\x5d\x5e\x2c\xd9\xb6\xdb\x34\xb9\xd9\xe2\x14\x46\x4b\x79\xe5\x87\xce\x4b\x7e\xd2\x32\x2c\xe9\x6a\x07\x94\x51\xe4\x28\x1e\x06\xc5\xf7\x15\xdc\xd6\xc8\x9a\xa2\x89\x86\x2a\x44\x16\x7c\x88\x5e\xaf\x49\x4d\x93\x48\x30\xa2\x16\x41\xfb\x33\x33\xcc\xc0\x89\xb4\x21\xd2\x6d\xab\x5f\xac\x1c\x35\xe8\x78\xfd\x56\xd9\xf4\x1e\xbb\xee\x35\xde\x69\x11\x15\x98\x7b\x61\x88\x2a\x9d\x06\x2e\x4f\x48\x18\xf8\xa8\x5f\xca\xd8\x33\xef\x4f\xf8\x29\xc0\x32\xfe\x62\x79\x31\xc6\x0c\x39\x7a\xf8\x31\x05\x05\x73\x87\xdd\xf6\xae\x65\x66\xe0\x23\x81\xee\x68\xf3\x67\xa2\x6a\x20\xff\xbb\xcf\x18\xea\x59\x1c\x01\x90\x0a\x92\xb9\x3c\x44\xab\x34\x38\x20\x76\xd1\x66\x2b\x3c\x61\xf3\x56\x55\x1c\x30\x6c\xea\x9c\xd4\xb3\xa9\x9a\xbe\xd7\xfd\x74\xce\xe3\xc4\xd4\x8d\xeb\x54\x26\xde\x92\x50\x7b\x7e\x68\xf3\x09\x14\x35\xde\xe7\x4b\xea\xd1\x9c\x47\x91\xe7\xfb\x79\x2c\x6d\x11\x8e\x3d\x8f\xcc\x8a\xfa\xe0\x4f\x46\xf8\x4e\x3f\x8a\xbc\x9a\x7f\xd1\x38\x3c\x38\xee\x2d\x5f\x4c\x5c\x81\x0a\xce\x1a\x33\xb8\x7b\xbe\x90\x66\xbb\x61\x37\x8b\x17\x52\xcc\xcc\xb0\x4c\x38\x31\x16\x8b\xa1\x0c\x84\xb4\xa0\x18\x83\xae\xb1\x3b\x04\x0c\x8f\xa8\xf1\x2d\x44\x44\x28\x3a\x77\x8b\x2e\x3a\x20\x8c\x81\xdf\x68\x61\x82\x48\xe5\x39\x1c\x09\x15\x84\xdc\x25\xf1\x52\xa0\xb0\xe2\xcf\xbd\xfd\xb0\xaf\x72\x1f\x7c\x4f\x3f\x8e\xa5\xe0\xe2\x55\x2c\x22\x49\xa4\x48\xdd\x03\x64\xd7\x34\x28\xa9\xd4\x67\xde\x4d\x00\x9e\x38\x33\xba\x28\x27\xc8\xfc\xb3\x78\x47\x2d\xac\x84\x45\x8a\xfc\xa7\xc7\x95\xfa\x2e\xa9\xde\x95\x46\xb1\xd3\x45\x1d\xe8\x98\xa7\x96\xd5\x85\x1d\xa7\x1f\xa8\x55\x5a\x7c\x53\x08\xda\x58\x04\xfe\x40\xd0\xe7\xfb\xc3\x87\x64\x55\x42\x8d\x93\x3e\xe7\xb4\x6f\x75\x16\xdd\xeb\xaa\xca\x6f\x7a\x30\xc9\x69\x67\x13\x1a\x33\x0b\x98\xe1\x7e\x3c\x75\x74\x49\x32\xec\x2d\xc4\x7b\xda\x37\xf3\x50\x2a\xb4\x29\xd6\x60\x59\xbc\x9a\x36\x8c\x64\xce\xdb\xb2\x9a\x6f\x37\xcf\x04\x54\x6c\x6e\x13\xd6\x07\xf7\xe1\xe4\x2a\x33\x73\x3e\xb5\x23\x9a\xfc\x57\x7d\xde\x0a\x8f\xe8\xe6\x94\xb7\xd8\xec\xf5\xc2\xd1\xd1\x76\x10\x35\x9b\x21\x5f\xe8\xc5\xc5\x45\xb3\x1a\xb6\x45\xf8\xd2\xa5\x55\xf4\x71\xc9\x1a\x0d\x34\xe6\xe2\x6a\x30\x48\xbd\xfe\xa5\x1b\xc4\xc9\xe9\x9b\xfb\x37\xd7\xd0\xab\x18\x17\xc2\x87\xc1\x51\x82\x03\xed\xdc\x1d\xa4\xed\x76\x39\x11\x0e\x4b\xb8\xaf\xf7\x6f\xff\xae\x50\x51\x7e\xbc\x1a\x8c\x38\x89\xcb\x8d\xb4\x5a\x03\x1a\xa6\xfc\x06\x50\x83\x33\x8f\x6e\xb2\x79\xae\x44\xca\x86\xea\xbf\x79\xb5\xbe\x8f\xa5\x8d\xbc\xf7\xe2\x05\xb7\x3c\x10\x88\xdd\x84\xa1\x63\xa7\xad\x9d\xdc\xd2\x9d\x70\x1a\x5e\x61\x9b\x45\xa1\x33\xb3\xe2\xcb\xa6\x2d\x63\x06\xdc\x11\x6e\x1a\x8d\xb2\x5f\x8f\x91\x7a\xd6\xb1\xd7\x75\xbe\xb9\x0d\x22\x6c\x51\x90\xdf\x51\x6a\xc2\x93\xa2\x60\x58\xbe\xd6\x13\x3b\x4e\x1a\x4d\x2a\xf5\xb1\x1f\xd8\x49\x37\x6e\xe4\x7b\x00\x07\x17\xf2\xaa\x51\x33\x85\x1b\x26\xee\xba\x7e\xbb\x69\x6e\x52\x21\x7b\xae\x3d\xf6\xc4\xee\x68\x9f\xfd\x3c\x01\x62\xc3\x62\x92\x4f\x7e\xe5\x91\xba\x58\x80\x47\x0f\x78\xaa\x99\x21\x8a\x37\xb5\x51\x5f\x3d\x65\x88\xd6\x04\xf8\xf0\xac\x96\xfe\xb2\xd1\x7d\xb9\xc4\x42\x7f\x95\x5b\x67\x77\xac\x90\xbd\x23\x21\x82\xab\xb5\x5c\x97\x19\x95\x65\xbc\x0d\xed\xb5\x77\x3d\xb2\x89\x08\x85\x0f\x76\xea\xf4\xda\xe9\x73\x8e\x9a\x7a\x92\xda\x32\x8d\xe4\xc4\x53\x7d\x38\xbe\x7d\x21\x77\xe1\x59\x1f\x9e\xdf\xc8\xe6\x45\xef\x0f\x58\x90\xaf\x73\xba\xf9\xb5\x52\x55\x10\x56\x16\x58\x26\x3e\xf0\xbe\x04\x24\x7e\xbf\x3e\x3f\x35\xae\x1c\x5c\x39\xd8\x6a\xe7\xc1\xd6\x70\x53\xd3\x06\x2c\x43\x3a\xcd\x83\x6c\x1d\xd8\xc4\xb8\x65\x16\x05\xab\xa6\x52\x86\x78\x74\x66\x72\x35\xa2\xc5\x79\xd6\x98\xac\x18\x25\xc3\x8d\xda\x59\xca\x90\x8b\xd9\xe7\x34\x96\x30\x6d\x64\x7f\x2e\xa8\xba\xde\x21\x2e\xca\x0e\xd9\x7e\x0a\x30\xb7\x14\x0d\x6a\xfe\x76\x14\x9f\x86\x3b\x9c\x50\xf7\xed\xc8\xe4\xd5\xef\xd7\xbb\x46\xde\x34\x91\x32\xd8\xa4\x85\x30\x4f\xaf\x95\x90\xca\x15\xac\xf0\xd7\x44\x31\xd9\x56\x72\xc7\x08\xc8\x1b\x07\x33\x4d\xdf\x90\x8b\x42\xe2\xea\x4d\xc7\xb4\x4e\xce\xf9\xa5\x82\xc9\x83\xc6\x15\xad\x2a\xd8\xaf\xc0\x96\x98\x73\xb8\xc4\x33\xdb\x85\x4d\x42\x3e\xf8\x03\xf5\x74\x02\x55\xdd\x74\x9f\x03\x69\xea\xe3\x20\x12\xb1\xd5\x7c\x3e\x06\xb1\xea\x45\x61\xd0\x56\x9a\x27\xdc\x7f\x25\xd1\x4a\x57\xf4\xdd\x18\x54\x51\x77\xe6\x21\x82\xc1\x2d\x0a\x68\xd7\x7d\x6b\x2b\x4e\x85\x2f\x39\xc5\x34\x9e\xd1\x75\xcc\xfa\x32\x6f\xc3\x79\x58\x88\x78\xd8\xcc\x79\x23\x41\x80\x79\x6c\x0d\x16\xf5\xc0\x66\x8f\xc3\x1b\x3a\x6a\x1c\x1c\xac\x83\x1e\x9e\xeb\xbd\x65\x0b\xcb\xc2\x03\x15\xc4\x1f\xe6\x52\xc6\x8a\xa3\x9a\x0f\xbf\x7f\x70\xeb\xde\x75\x12\x58\xac\xb7\x73\x42\xa8\x83\x63\x18\x45\x34\xee\xc5\x4c\xa2\xfc\xcb\x6e\x7b\xee\x31\x11\x56\xec\x98\x44\xa0\xae\x93\x85\x8a\x78\x44\x02\xd7\x40\xb7\xdd\x2d\x2f\xd9\xa2\xc3\x8d\xf3\x60\xb6\xe5\x35\x7f\xab\xb1\xc0\x85\x40\x17\x67\x0e\x25\xf0\xce\xb3\x41\xa3\xb2\xf9\x6a\x43\xce\xb9\x64\xe7\x45\xae\x6e\xce\x48\x1e\x68\x7a\x23\x66\x65\x16\x1c\xb2\xf8\x14\x31\x73\x53\xcd\x69\xde\xe2\x7f\x5b\xe9\x96\x9f\x4e\x1a\xd4\x1b\x06\x71\xe3\x79\xcf\xd8\x46\xb9\xa8\x6b\x65\xd3\x3c\xcf\xc0\x74\xa4\x8f\x9a\x44\x25\xc6\x79\x0e\x68\x67\x92\x0f\x67\xc3\xf8\xb6\xd4\xa9\x49\xca\x45\x05\xbe\x7b\x0d\xa5\xdb\xea\xa9\x77\xa6\xd8\x7c\xdc\x2a\x6b\xdc\x00\xf4\xf9\x1b\x3f\x3c\xc8\x83\x6e\x7e\x0c\xee\x38\x23\xca\xdc\x27\x1d\xd7\x4d\x95\x6b\xf7\x57\xa8\xc2\xdf\xd3\xfc\xfd\x75\x81\xb3\xe8\xa0\x25\x16\x0f\x86\x6e\x81\xbc\x6c\xde\x89\xe8\x32\xb9\x25\x55\x2d\x21\x60\x15\xcc\x4a\x2f\xe8\x78\xd2\xa4\x23\x4f\x58\x9f\xf7\x50\x1e\xd2\x96\x3b\xf9\x93\x90\x75\xed\xc4\x05\xf4\xca\x8f\x05\xa4\xee\xa3\x1c\x0e\xf0\xe4\xed\xb8\x73\x2a\x60\x71\x4c\x2a\x32\x8e\x51\x53\x7a\xc7\x3b\xe1\xab\x40\x17\xe2\xc1\x2c\x7a\xbc\xa5\x2d\xa5\xda\xec\xcc\xd7\xd8\xf8\xef\x6f\xf4\x0d\x7c\xfc\x52\x65\x9a\x67\x32\x15\x5a\x25\x31\x87\xf8\xfc\x1d\xa6\xc4\x4e\xa5\xc1\xff\xe4\x2a\xf2\xc5\x42\x4a\x45\x64\x9a\x6c\x54\xf3\xf5\x48\xc2\x4c\x32\x45\x16\x27\x45\x29\x9b\xf6\xac\x17\x12\xc9\x43\x68\x7b\x1c\xb9\x3a\xbf\xbf\x85\x25\x3c\xd4\x8d\x3a\x7b\x1c\x93\x26\x9e\xc1\x17\xe1\xb8\x85\xa2\x9b\x32\xd9\x37\x91\x7b\x0f\xb9\x9b\x42\xd1\x46\x15\x33\xb5\x67\x08\xed\xc5\xf9\xa8\x58\x7a\x06\x15\xf1\x42\x6d\xc4\xa8\x6f\xb4\x0f\x7f\xaa\xa3\x27\x8f\x54\xb7\x8e\xe3\xd1\x24\x58\x65\x94\x8e\x1c\x06\xc9\x12\xdf\xab\x2e\x0c\x60\x0b\xcc\x28\xa2\x0b\x09\x20\xb1\x1e\x5b\x2c\x8c\xbd\xa7\xb2\xb4\xab\xf7\xe0\x90\x13\xcd\xe4\x81\x7d\xa7\x28\x0b\x12\xf1\x38\xce\x7e\xf4\x20\x3d\xa3\x5a\xf9\x36\xf3\xeb\x09\x53\x8e\x27\x96\x7c\xcd\xd8\xb5\x98\x05\x84\x47\x51\xb4\x07\x9d\xda\xc1\x0a\x35\xaa\xa4\xcf\x14\x94\x48\xb3\x0e\xb8\xf4\x03\x41\x6a\xa6\xa6\x50\xf8\x38\x32\x19\x1d\xea\xd7\xac\xff\xb0\xd4\xa1\xcd\x32\x82\xdc\xcd\xaf\x0f\xff\xae\xe4\xbd\x6a\xa2\x97\xcf\xbe\xa7\x3c\xbc\xba\x2d\xfc\xc4\xf8\x90\xe3\x8a\x60\x8e\x95\xdb\x5f\x7a\x02\xc0\x47\x0b\xed\xa2\x0c\x83\x3b\xad\x1a\xe9\xa3\x99\x6a\xb9\x5e\xcb\xa4\x34\x27\x1c\xc1\xdd\x7b\x64\xcf\x2c\x58\x48\xea\xbe\xf7\xa1\xa8\x13\x1b\xcd\x1b\x1f\x06\x0b\x5f\xb5\x31\x97\x98\xc4\x2c\x8d\x29\x2a\xc0\x5c\xea\x5c\x12\xb5\xbd\xf9\xc3\x24\x40\xf7\x86\x74\xfc\x15\xc6\x55\xa1\xee\x11\x2f\x3e\x59\xa6\xa2\x9d\x62\xcf\x53\x94\x8c\xdf\xc2\xa6\x1e\xf2\x9b\x85\x9e\x2c\x45\x1f\xa8\xab\x0f\xcc\x64\xf8\x98\x62\x8d\x2a\xae\x53\x60\xf0\x5a\x97\xf1\xa1\xde\xa1\xbc\x33\x46\x77\x16\x07\x9e\x3b\xb4\x57\xc2\xf1\x79\x64\x51\x26\x3e\x5c\x51\x45\x70\xe1\xaa\x83\x99\x19\xfe\x7d\x4e\x48\x7c\xae\xae\x21\x99\x2d\xf3\x2c\xd4\x85\xe9\xa2\xd5\x39\xc8\xd8\x4f\x36\x62\x04\x11\x6a\xcd\x0e\x9f\x15\x52\x72\x16\x60\x1d\x54\xa9\xb4\x89\x03\xdb\x2a\x9c\x4c\x93\xce\x94\x7d\x1a\xb3\x99\x79\xdc\x59\x75\x56\x2f\xc0\xd9\xc7\xb1\x31\x2f\x76\x4f\x63\xf9\x89\x27\xbc\x7d\x95\xb0\x1e\xbf\x7e\x22\xae\x0a\xe4\xd7\xa4\xec\xed\x1d\xa2\xf5\xc6\xd9\xd7\x47\xba\xcd\x47\x98\x45\x14\xab\xd9\x9e\xf8\x1a\xd8\xee\x61\x10\xe7\x05\x96\x81\x79\x85\xf3\x8c\x59\x0d\x2f\x06\x21\xa4\xb7\x90\xb8\xcb\x54\x37\x99\x3a\xd6\x7c\x16\xe2\x75\x3f\xbe\x99\x6c\x7e\xcd\x25\x01\x8b\x2b\xb3\xa9\x4b\x21\x0b\x75\x49\x2d\xf5\x07\xb8\x63\x1d\xd9\x16\xb5\x59\x8b\x73\x6b\x91\x3e\xd3\xbc\xaf\x9d\x18\x0a\x0b\xb9\xba\x02\x97\xcb\x24\x73\x6d\x85\x3f\x6d\xc9\x11\xa5\x94\x11\x3a\xec\xc1\x8d\x22\x4c\xe4\x89\x5e\x37\x66\x68\xa3\x90\x3b\x21\x13\x81\x44\xc1\x2e\x4e\xd3\xb1\xb0\xdc\xd5\x3e\x6b\x9a\xf0\xcf\xe1\xd1\x08\x72\xa4\x21\x49\x71\xb2\x7b\x68\x8a\x38\x96\x7e\x25\x73\x8f\x7c\xdf\x8e\xef\x2f\x76\xca\x5a\x73\xa1\x51\x4f\x82\x1e\x32\xc3\x45\xab\xfb\xb4\xd8\xfa\xcc\x73\x05\xc2\x21\x38\x96\x2c\x3b\xe0\x91\x43\x6d\x5a\xa2\xb3\x1d\x01\x4a\x8a\x48\x0d\x30\xc4\x7a\x0c\x65\x50\xb7\x89\xd7\xdf\x00\x48\xe6\xc6\x4d\xe1\x68\x16\xb9\xa9\xf9\x53\x6c\x36\xa6\x5c\x3d\xce\x45\x8f\xb3\xbd\x89\x80\xe7\x18\xa0\xb2\x52\xb6\x54\x36\x31\x07\xd6\xd6\x7a\x62\x88\xcd\xc8\x6a\x5e\x18\x54\x3a\xc7\x35\x24\xf2\xfb\xeb\x9b\x8e\xbb\xa0\x8c\xbe\xc5\x0a\xbf\x1c\xab\x67\x2f\x07\x3e\xc1\xb7\xf1\x20\xb7\xdc\x82\xa2\x6b\xe0\x0c\xc2\x39\x36\x99\xf3\x6f\x54\x9f\x73\xc2\x5a\x21\x0e\x9c\x04\x0c\x92\x61\x87\x74\xdb\x01\x21\xef\x9c\x8a\x06\x1b\x6e\x7e\x73\x26\x92\xc0\xd6\x03\x0b\x82\x24\x2f\x64\xa1\x77\x40\x3f\x9e\xb2\x78\x81\x01\x60\x9b\x56\xf5\xf2\xb9\x7e\x13\x96\xc9\xd4\x14\x9d\xda\x19\xdd\x62\x22\xbe\x1e\x92\x26\x60\x5e\x35\xec\x96\x38\xd6\x32\xdc\xaa\x4c\xfc\x89\x05\x6f\xd2\xdc\xf2\x8e\x7e\xe4\xe0\xc3\x86\x88\xf0\xcc\x85\xe1\x38\xfa\x78\x40\xfe\x9d\x37\xe1\xad\x0c\xff\x62\xeb\x63\x73\x2b\x06\xe2\x0c\xc5\xf3\xa5\xd0\x08\xe4\x55\x84\xbb\x2a\x83\x0b\x23\x46\xa9\x82\x13\xfb\xfb\xfd\xa3\x09\x93\x47\x22\x48\x39\xbd\x39\x15\x08\x7f\x61\x66\xbb\xa4\x9a\x5c\xf0\x0e\xea\xd7\x0c\xb4\x78\xa7\xe1\x9f\x87\xc4\x49\x32\x2f\x22\x6e\x74\x21\xe2\x75\x73\xe9\x28\x01\xcf\x07\x1d\xac\xcd\x1b\x5b\x39\xc9\xd6\xd1\xc5\x5a\x8e\xe8\xe4\x46\x6b\x94\x20\x11\x03\x77\x76\x86\x56\x9a\xbb\x67\x1b\x96\xfb\x37\x74\x51\xa3\x39\xb1\x57\xd0\xbb\x43\x03\x11\x0f\xc3\x89\x69\xa6\x54\xb4\x3f\x6e\xed\xb4\x2d\xde\x9b\x08\xb5\xda\x79\x98\x44\x02\x63\xcf\xa6\xdf\xb0\xe1\xe0\xd6\xf6\x57\xf8\xe4\x07\x52\xce\x04\x60\xc0\x9c\x4c\x34\xd4\x82\xe5\x3b\x88\xc6\x65\xa8\xc5\xd9\xee\xcc\x9d\x61\x2e\xde\xa4\x00\x0b\x81\x94\x8e\x2a\xd0\xe2\x03\xd9\x47\x21\xe3\x2c\xb0\x92\x8f\xdc\x66\x44\x2f\xde\x9a\x2a\x67\xa9\x2d\x90\x3f\xc0\x06\xe0\x41\x16\x38\xa4\xcf\x9e\xce\x1a\x6d\xde\xa5\x06\xae\xad\x3a\x3c\xb7\x1b\x29\x15\xf2\xb5\xb4\xff\x35\x5e\x9c\x8b\xc4\x0e\x5c\x4d\x40\x08\xea\x65\x0b\x97\x8a\xa6\xa5\x03\x14\xc8\xac\x7f\x48\xb8\xfb\xbc\x3b\xe6\x01\xc4\x74\x61\xfe\xd6\x8b\x0f\x72\xbb\x30\x34\xdc\x55\x3a\xe9\x73\x67\xea\x4b\x94\x99\x48\x40\x56\x68\x14\x68\x81\x07\x8a\x5d\x07\xae\xcc\xea\x7f\xca\xa8\xfb\xaf\xaa\x00\x4d\x60\x77\x6f\x61\xc6\xb7\x3f\x8c\x0a\x69\xc8\x8e\x8d\xf2\xff\x35\xd5\x0b\x6b\x3f\xb5\x08\x42\x4c\x62\xb6\xbe\x0d\x0f\x3f\x09\xaf\xbc\x20\xe6\x61\xa9\x87\x60\xaf\x9d\x38\x6d\x92\x64\xd6\x6a\x33\x59\x44\x5c\x80\x01\xc0\x6f\x7a\xce\x9b\xce\xb6\xbf\xa7\xb1\x94\x98\x3d\x0e\xe5\x36\x80\x7f\x00\x2e\x7e\xf4\x11\xb7\x84\x0a\x39\xd4\xb7\x4e\x6c\x94\xdd\xd6\x3d\x4b\x7a\xa7\x2c\x89\x55\xc0\xed\x69\xe0\x8d\xae\xdb\xa8\xc4\x9a\x0b\xb1\x9c\xe0\xf3\xfe\x4a\x5a\xc7\x61\xe1\xfc\x74\x54\x13\xe5\xf1\xd3\xa7\x42\x96\x02\x7a\xc3\x33\xc2\x2f\x12\xc7\xe9\x99\xf9\x9c\xed\xc9\xc4\x47\xdb\x23\x33\x31\x87\x61\x7c\x2e\xf9\x98\xa7\x01\x8d\xe9\x4a\xb5\xd1\x04\x48\x75\x2a\x9b\x6b\xaf\xf9\x78\x26\xb2\x85\xb6\xb5\x2b\x61\xd7\xb2\x4f\xc2\x09\xba\x8a\xe3\x38\x09\xdb\x6d\xaa\x46\xe7\x4b\x11\x67\x4a\x16\x78\x2a\x94\xea\xa0\x9d\xec\xd2\x33\x1b\x7c\x3e\x2e\x74\xa3\x05\xc2\x93\x26\x50\xe6\xf6\xa1\x31\x8b\x18\x72\x36\x88\xa5\x34\x4d\x85\xdf\xc7\xb5\xbe\x10\xfc\x26\x2c\x70\x38\xc4\xa1\xe5\xbd\xd4\xe2\x54\x64\x15\xea\x12\xd8\xab\xee\x6e\xbe\xba\xc8\x46\x76\x33\x11\xc4\x02\x39\x4a\x77\xc8\x3e\x32\x0e\x34\x9d\x30\xc3\xd0\xc0\xd7\xfc\x08\x82\x05\x39\xac\xa6\x62\xbe\xf1\xcc\xea\xaf\x73\xb9\xd2\xc3\x67\xdf\x0d\x9d\x39\x48\xa1\x66\x99\xba\xa5\xfd\x55\x4b\x10\x24\xeb\x61\x1f\x2a\xfa\xfd\x57\x81\xeb\xfd\xdd\xb9\x9e\x2b\xd4\x95\xb7\x07\x1e\xf8\x1c\x05\x56\x9a\x47\x95\x9c\x9d\xa0\x5c\x3e\x9b\x37\xb5\xd4\x64\x9b\xa6\x61\x5b\x7d\x49\xe8\x4c\x0f\x9a\x74\x36\xf7\x09\xdd\x62\xd5\x1f\x9e\xdc\xdf\x18\x88\x79\xda\xe4\xcc\x88\x82\xfd\x30\x6c\xdc\x8d\x3e\x47\x00\x6e\xf6\x10\x6e\xa2\x0d\xcb\x32\x40\x68\x4e\x62\x06\x29\x5b\xe0\x71\xa0\x04\xfa\x46\xc2\x43\xf3\x96\x19\x61\x2e\x9d\x7d\x47\x92\x79\x4d\xc5\x40\x81\x7b\x59\x58\x79\x87\xb2\x92\x94\xad\x7e\xc4\xfa\xa1\x4c\x77\xa1\x28\x6f\xc2\xc8\x5e\x24\x9f\xff\x47\x78\x88\xc5\xbb\x9c\x86\x71\x0a\x57\xef\x23\x8a\xa0\xae\x72\xb4\x1c\x98\x32\x3a\x13\xd7\x86\x3c\x66\xa7\x65\xa7\x8e\xf6\x11\x22\xe6\xaa\xc1\xd8\x7a\xa1\x58\xd3\xdf\x7d\x4a\x18\x51\x85\x6e\x6e\x13\x71\xc6\x3a\x47\x85\xc2\x0e\x9c\xc2\xfb\xc8\x71\x5a\xca\xae\x62\xc9\xec\x22\x68\xa5\x4c\x39\x2f\x91\x31\x85\xc9\x97\xe7\x16\x7e\x3f\x0f\xdf\xe8\xf0\x0d\x4d\xbf\x89\x2a\x87\xa1\x29\x30\x60\xae\x34\x1b\x2a\xdd\x45\x5d\xc2\x1e\x95\xf5\x4c\xfd\x3b\x69\x98\xd8\xdf\x5b\x8e\x23\x9c\xd2\xc8\x6e\xa9\xfa\x95\xae\xeb\xe3\x56\x78\xac\x9d\x6c\x89\xe7\xb2\xff\x8b\x32\xfb\xdd\x0e\x29\x8b\x35\x6e\xdf\xf6\x0d\x99\x9d\x4b\x54\x92\xd4\x84\xbb\x0c\xa9\xbb\x75\x3f\xf1\xfd\x76\x76\xc3\x9b\x5c\xd7\xd6\x00\x04\xa6\xe9\xaa\x5e\x95\x5f\x95\x33\xd5\x36\x8d\xb8\x44\x3d\xd1\xa5\x29\xbf\x8e\xd3\x39\x55\xaf\x9c\x5b\x85\x36\xf1\xa7\xc4\xfa\xa2\x5a\xf5\x16\x12\x7d\x70\x53\xbb\x83\xda\x75\xfb\x50\x68\x0a\xc7\x62\xf0\x87\x7d\xe1\xec\xc4\x7f\x7b\x0c\xc2\x54\xd0\x3c\x00\xca\x57\x40\xee\xf9\xa2\xee\x7a\x35\xd1\x9a\x60\xca\xc4\x33\xb5\xfb\x09\x7d\xe1\x51\xc1\xc0\xb4\xc1\xdd\x3f\xda\x96\xd8\xc3\x55\x6c\xe4\xc6\xb3\x6d\x3b\x47\x5c\x86\x19\x7f\x56\xf5\xde\x89\xd2\x64\x84\x56\x97\x91\x74\x01\x53\xdb\xe0\x02\x2c\x0f\xa1\x3d\x3f\xbf\xd1\x95\x50\x79\x22\xe4\x83\xa0\x5e\x9f\x1d\xb0\xbc\x4a\x6d\xff\xed\x4d\x87\x27\x09\x0b\xca\xc2\xed\x7a\xe3\x2a\xba\x10\xb2\x61\xbd\x0c\x81\x6e\xd9\x77\x66\x72\xa8\x54\xcf\xf4\x18\xe7\x9e\x41\xba\x98\xd6\x90\x83\xa3\xce\x0b\xa3\xb8\x7b\x8b\x17\xe8\x6f\xb3\xa9\x52\xce\x99\x9a\x76\x80\x34\x52\xb4\xd9\xe3\x72\x65\x9e\x4e\x9c\xde\x93\xb7\x37\x20\xf5\x33\xc5\x5d\x40\xae\xda\x19\xc0\x68\xcb\x4f\x18\x4b\xeb\xe3\xd1\x05\xfe\xf3\x05\x75\x0b\xd1\x3f\xe8\xda\xfa\x8c\xe2\x0b\x11\x70\x68\x12\x11\x3a\x74\x8b\x6c\x54\xf3\x3e\x07\xc4\x82\xf6\x27\xfe\xaf\x42\x33\xda\xe1\xc8\x2a\x9c\xe7\xe0\x14\x1c\x99\x0c\x9d\x88\x97\x7f\x04\xf3\x55\x69\x9f\x97\x44\xb1\xd8\x42\x1d\x56\xb5\x3f\xcd\xc0\x18\xbc\xff\xf8\x77\x05\x8a\x5b\xf1\x08\xc6\x29\x36\xa4\x71\xda\xc5\x99\x60\x46\xc4\x27\xc5\xe0\xb4\x86\xad\x3f\x11\x8c\x0e\xa6\x64\x19\x63\x3b\x46\x3d\x61\x54\x1b\x8b\xda\xa3\x58\xc9\x46\x69\xdc\xd1\xbc\x33\x35\x08\xed\xe6\x4c\x70\xd2\x92\xaa\x77\x4e\x33\x12\x45\x1e\x2b\x15\xe7\xd0\x2b\x66\xea\x9c\x72\xbc\xfa\x9f\x32\xe6\x1e\x11\xec\xb0\x65\xce\xc0\xa8\x31\xca\xbd\x02\x55\xda\x2d\xcd\xcc\xa2\xec\x7d\xa0\x8f\x84\x2f\x5a\xe8\x9e\x30\x50\x27\xe4\x21\x89\x9e\x93\x1a\xcd\x22\xc9\x70\x43\x8e\x77\xf9\x71\xe2\x47\x7f\xc1\xd7\x57\xa1\x97\x92\xf7\xf9\xb9\xdc\x1f\x33\x94\x27\xda\xe3\x0a\x97\x46\x71\xe3\x9c\x8f\x63\x79\x41\xea\x58\xb7\x3c\x05\xd5\xad\x4f\xed\xf8\x0d\x0f\xcd\x5c\x88\x70\x42\x77\x4b\xf7\xe2\x4f\x3b\xb9\x85\xc1\x31\x7d\x75\x41\x2d\x4b\x81\x81\x79\x0a\xe7\x46\x50\x5f\x8b\x8c\x03\x0d\x7e\x43\x77\xc7\x53\xfb\x4b\x2a\xf5\x08\x81\x78\xbd\xd5\x9b\x59\x66\x27\x47\xa5\x45\xb2\x28\xf3\x2a\x32\x78\x1f\x9e\xa8\x7c\xf0\x5c\xfc\x5d\x56\xb7\xbe\x71\x06\x12\xa9\x46\xbd\x25\x19\x1e\xbc\xd8\xc3\x38\xd9\x7b\x18\x0a\x53\x79\xf6\xf9\x65\x95\x86\x91\xc0\x4f\x08\x65\xa6\x08\x24\x7d\xa0\xd0\xfb\x54\x0f\x94\x8b\xea\xfd\x72\x09\x9a\xec\xb5\xa8\xa1\xdd\xab\x91\x61\xe7\x6f\x39\x83\xda\xd4\x36\xb3\x8f\x28\x76\x51\xfe\x55\x34\xb8\xca\xfd\x32\xa5\x48\x23\x76\x10\x5e\xfd\x17\x60\x8f\xa3\xb7\x00\xbc\xf3\x1c\xb0\x78\xe0\x07\xa2\x72\xb0\x01\x8b\x60\xf6\x61\x40\x2e\x61\x48\xcf\xa1\x9c\x8d\xcc\x5f\xc9\xa1\x7f\x38\x17\x1b\x0a\xde\x64\x20\x26\xd5\x26\x9d\xda\x45\x0c\x58\x7e\x92\x4e\xca\x52\x17\x06\x82\xad\x4c\x88\x58\x2f\xff\x71\x1b\xa8\xd0\x67\xce\x04\xc0\x3e\x38\x25\x06\x45\x63\x66\x66\xd7\x93\x8e\x9a\x52\xd6\x47\x64\x1a\x2a\xc1\x72\x59\x32\x29\x0c\x72\x43\x50\x0f\xb8\x57\xce\x7d\x11\xf6\x39\x15\xcc\xb8\x60\x25\x76\x5c\xe4\xc7\x1e\xd8\x5a\xea\x4a\x18\xc7\xda\xe1\x9e\xe4\x39\x22\x27\xf9\xbb\x1c\x5a\x02\x1b\x50\x9d\xf5\x85\xf3\xfa\x87\x4f\xb3\xe5\x43\x26\xd8\x5e\xa9\x47\x27\xac\xe3\x14\x9a\x02\xfc\x6e\x3c\xab\xcd\xae\x5d\x2f\x4e\xab\x4c\x82\x01\xe7\xa5\x64\xb2\xaa\xd4\xce\x11\xa9\xc4\xdb\x41\xe2\xdd\x68\xd1\x8a\x9e\xde\xde\xfe\xba\x97\x30\x44\xf2\x58\x89\x42\x68\xaf\x19\xae\x75\xcc\xfc\x78\x6f\x69\x62\x30\xda\xda\x6a\xb7\x54\xf3\x77\x62\xce\xf3\xe9\xb4\xf6\x64\x29\xf0\xe6\xed\x95\x0b\xd3\x84\xa5\x30\x4a\x4f\x1d\x01\x33\xc0\x9b\xad\x92\x7d\xc8\x7b\x36\x5d\x84\xf7\xd0\xb0\x01\x5f\x71\x61\xd8\x7c\x58\xc6\xc4\x19\x2b\xf6\x50\xfe\xc4\xd6\x5f\xc9\xe0\x0f\xde\xbc\x3b\xe3\x35\x07\x36\x94\xfe\x6d\x5a\x87\x3e\xc9\xda\x61\xfa\x1c\x7c\x87\xa1\x71\xba\x5f\xa6\x03\xf2\xc0\x7e\xbd\x0b\xea\xbf\xb8\xdc\x7d\x99\xfb\x12\x7d\x35\xec\x90\x48\xe6\xf6\xe3\xc1\x91\x44\xda\x2e\xe3\x55\xf1\x1b\x16\x25\x39\x99\xe3\x7c\x04\x2f\xaf\x61\x3f\x9e\x25\xe7\x8f\x01\xe3\x40\x68\x90\xcc\xee\xfd\xed\x8d\x1d\x00\xf7\x15\x65\x1b\x5b\xb2\xd7\xb8\xf1\x3b\xbb\x45\x0a\xf5\x27\xc9\x00\x62\x14\x51\xdf\x2c\x97\x56\x2d\x00\x48\x5a\x92\xd9\xc7\xe7\xca\x89\x01\xcb\x42\x95\xba\xa5\xdb\x10\xcb\xa4\x97\x7d\x92\xd9\x31\xeb\x59\x26\xd0\x38\xb9\x09\xf9\xd3\xe2\x76\x24\xf0\x67\xb1\x30\x35\x60\xbb\x3d\x19\x8d\x8c\xf9\xf1\x9d\xe5\xe2\xa3\xf2\x99\x24\x3d\x1a\x3e\x04\x53\xf1\xe2\x1c\x47\xf7\x87\xb5\xe3\xf5\x7e\xfc\xf8\x77\xe5\x7d\xcc\x68\x75\xf7\x39\x2f\x90\xbb\x8d\x55\x7a\xef\xa8\x4b\x6c\xe1\xb2\x98\x6c\x55\x47\x4b\xe3\x24\x34\x65\x8c\xa9\x22\xe5\x13\x28\x2d\xe1\x71\xf8\x64\x37\x56\x85\x5d\xff\x30\xf1\x45\xa5\x5c\xc1\xdf\x30\xe1\x81\x77\x99\xca\xc0\xcb\x2d\x7e\xec\xee\x0c\x10\xb2\x79\x82\x69\xf4\xcc\x3c\x4e\xb6\x73\x84\x11\x0c\xb9\xe4\x59\x94\x39\xf6\x66\xa5\x89\xc0\xa7\x42\x08\xa6\xeb\xbd\x02\x78\x40\xe6\x2e\xf3\x5e\xdb\x13\x87\xca\xa8\x7b\x86\xf8\x3c\x55\x63\xa6\xd2\x6d\x3a\xb0\x8c\xe3\xae\x05\x34\x58\x5c\x31\x83\x86\xde\x05\xfd\x6a\xe7\xda\x19\x33\x7b\xdb\x3f\xba\x1f\x64\x2c\xd2\x60\x31\x08\x40\x48\x18\x97\xab\x7e\x77\x74\x54\x39\x9c\xe7\x28\x1e\x0e\x45\xfe\x2a\xe1\x6d\xc3\xab\xe4\x12\xff\xe3\x81\x30\x9b\x6c\xce\x80\x6a\x1a\x0e\x49\x1d\x30\x10\x17\xcc\x2a\x1c\xe4\x5e\x0a\xd5\x1e\x8e\xdf\x98\x7d\x31\xe1\xf4\xed\xd2\x8c\xfd\x4d\x37\x2e\xd3\x63\xa2\xda\x2a\xab\x77\x1d\x80\x79\x77\xca\xba\xd0\xc8\x37\xb1\xc0\x20\x91\x82\x80\x19\x76\x8b\x88\x92\x62\x7f\x13\xcf\x96\x19\xac\xa1\x64\x54\x07\x8b\xf1\x6e\x24\x6a\xf6\x67\xfd\x1b\x0f\x0b\xdd\xc2\xb9\x54\xb1\xcf\xf9\xc1\x0a\xd6\xe8\x10\xdd\xd2\xe7\x32\x6d\x82\xac\x4e\x2f\xf8\xd8\xb4\x40\xdc\x17\x48\x41\x52\x69\x90\xe3\xf1\x0f\x8e\x18\x27\x74\xc6\x39\xaa\x90\x66\x35\xd5\x0c\x19\x27\x95\x80\xfd\xfe\x8d\xc2\xcd\x6c\x42\x28\x34\x1f\x80\x31\xc3\x18\x7b\xd2\xf2\xa0\xbf\x79\x10\x0e\xe8\x0f\x3b\x02\xbf\x2d\x66\xca\xc4\xf3\x77\x2b\x7b\x46\x3c\x5d\xc1\x0a\x7b\xef\xe3\xc3\x52\x19\x29\xa7\x3c\x15\x18\x34\x7d\x59\x7f\xd2\xa4\x81\x35\x1f\xb7\xdb\x95\xb5\x25\xf3\x24\xd4\x79\x00\x2e\x99\xa4\xe0\xd3\xd4\xf3\x8a\x04\xa4\x77\x75\x2c\xa4\x85\x34\xb3\x82\x23\x48\x96\x06\x14\x65\xc3\x28\xcc\xb4\x12\x92\x5e\x14\x18\x99\xb7\xbd\x87\xcb\x15\x4f\x99\x3d\x3a\x51\x7d\x4b\xfd\x98\xf5\xe5\x3f\x2c\x6b\xcb\x06\x1a\x2f\x1a\xd2\xcd\xfa\x57\x77\xc7\x2f\xf0\x35\xb9\x8e\x56\x6e\xf2\x39\x5f\x31\x8d\xe5\x4a\x2c\x92\x07\x82\xf8\x71\x93\x9f\xe0\xfd\xf2\xae\xae\x70\x78\x6e\x08\xe1\xa7\xed\xb3\x45\x25\xc4\x9c\x92\xe4\x1d\x2b\x78\xe8\xf4\xbd\x48\x43\x9a\xee\x56\xaf\xfd\xf8\xb8\xc8\xbb\x5c\x1e\x65\x76\xb1\x73\x50\xc2\x6b\x4f\xfe\x5d\xa9\x46\xc0\xe4\x74\x02\x53\x12\x6b\x5d\x5b\x99\xc7\xea\x25\x78\x9c\x3b\x4d\xbe\xbc\x84\x7e\x00\x85\xf0\x28\x36\xbe\x31\x3d\x09\x83\xbc\x21\xa3\xc9\x6a\x7c\x6b\x97\xc0\x11\xd9\xb6\x73\x70\x58\x50\x77\x38\x05\xd1\xe4\x0c\xe5\xf4\x89\xdb\xda\xce\x74\xad\x11\x8a\xbb\x2a\x21\x64\xc6\xa1\x25\xf0\x2d\xc4\xc3\xb7\x3f\x37\xee\xed\xfb\xed\x03\x99\xa9\xe7\xbe\x10\xf3\x55\x06\x16\xb2\x20\x91\x06\xcd\x69\x03\x8f\x85\xcb\xc6\xf1\xfb\xf7\x0f\xd2\xa7\xc8\xd3\x55\x0c\x94\xa1\x8f\x04\x24\x5a\x66\x4c\xaa\x88\xe5\xb9\xa7\x39\xb4\xf7\x7c\x08\xfb\xe7\xd8\x26\x32\xb2\xf9\xae\x94\x9e\x5a\xd3\x87\xa7\x21\x3f\x90\xb2\xea\x35\x64\x70\x2e\x33\xca\x7c\x56\x27\x0b\xcf\xde\x16\x78\x52\x57\xa0\xc7\xe2\x10\xf6\xcb\x7a\xab\xdb\x1d\xe7\x95\xa3\x31\xcd\x9e\x2c\x0c\x30\x18\xa6\xf3\xc8\xd1\x8c\xbc\xd1\xa8\xf0\xc0\xe9\x38\x1e\x80\x5b\x74\x02\x85\x40\x0f\xbc\x2e\xc4\x06\xee\x00\xc8\x2d\x41\xfd\x43\xa4\x97\x37\xa7\xd7\x80\xbc\x2f\xaf\x3a\xbe\x88\x46\x9c\x48\x4e\xd4\x36\xa5\x91\xde\xe1\x47\x70\x1a\x00\xfc\xf8\x47\x1f\x5e\x8d\xd7\x6d\x9f\x66\xf4\x8d\x22\x09\x5d\xa8\x3c\xcc\x66\x5c\xa4\x5a\x48\xb0\x35\xfb\x3c\xcb\x38\x48\xf4\x57\x62\x8a\x92\x85\x01\x40\x6c\x84\x2e\xa8\xd5\xa9\x31\x9d\x88\x1c\x43\x0b\x5c\x80\x3f\xb3\x9e\xea\xe5\x13\x04\x49\x0e\x24\x5c\x49\x23\x36\x79\xbb\x2d\xb2\x2f\x53\xd3\x7c\x7f\x90\xa9\xbc\x7e\x0d\x34\xa9\x67\xd9\x63\x13\x77\x31\x55\xd4\x25\x5d\xde\xc7\x07\xe3\x10\xcf\xc3\x96\xca\x6e\x1c\x65\x45\x7b\xb5\x55\x9b\x13\x36\x45\x4d\xfb\xb4\xed\xe6\x4a\xc4\x7b\x23\x36\xc5\xbb\x23\xc5\xcb\x19\x60\x34\x79\x4d\x4b\x97\xa8\xad\x2d\x0a\x69\xd9\xc8\xff\x9f\xba\x9e\x27\x04\xb1\x77\x28\xdd\x56\x18\xe3\x31\xdd\xcf\x23\x7a\x1c\x3c\xb3\xc9\xac\x5c\x3d\xde\xec\x5f\xa5\x09\xba\x2e\x8e\xb7\x7b\x73\xad\xa7\x22\xdd\x13\x8c\xc6\x66\x3e\x3f\xfb\x18\xc2\x65\x97\xe3\xf3\x10\x43\x57\xbc\xa6\x07\x24\x7b\x2c\xb9\x6a\xf7\x7f\x20\x90\xb1\xa0\xbe\x4c\x2e\xb6\x3c\x2a\x39\xfd\x70\xaf\x13\xc2\x29\xa9\xd9\x62\x89\x2d\x41\xa0\xef\x4f\x89\x2b\xd9\x59\xe4\x52\xc9\xa8\x74\x14\x8b\x73\x9c\xce\x1c\x3f\x6b\xb7\xbb\xd0\x4d\x5d\x9d\x02\x8e\x0f\xb7\x2d\x92\x42\xc0\x9c\x46\x64\x39\xd2\xe9\xe4\xc1\x63\x55\xe6\x91\x51\xa0\x59\xe7\x7d\x3b\x0a\x5b\x47\xb7\xdd\x4c\xa8\x8a\x2f\x48\x9c\x59\x18\x4e\x62\x65\x9f\x7f\xca\x71\xdf\xe0\x58\xa6\xc9\xc8\x9b\xcf\x3f\xa8\x10\xd8\xd6\x4b\x6a\x89\xa3\x93\xbb\x2f\xf8\x9e\x39\x05\x51\xca\xd4\x6b\x2c\x2c\xd6\x99\x61\x57\x24\x3d\x64\x8d\x62\x74\xe4\x01\x33\x30\x5d\x49\xd2\x2f\xaf\xea\x25\x78\xcb\xc1\x09\xe7\xd0\x59\xc4\x4b\x3e\x91\x95\xce\x5b\x7e\x28\xae\x98\xc3\x30\x96\x20\x29\x9c\x45\x39\xf9\x79\xbb\xfc\x03\x86\x39\x98\xf5\xd9\x5e\x54\xe7\xdc\xb9\x0d\x11\x37\x09\x02\x43\xe9\xfd\xdf\x57\x82\x7a\xfc\xf7\x8f\xeb\xde\xfd\xf3\xe7\xe6\xad\xcc\x91\xb1\xd8\x00\xd3\xab\x5e\x98\x6b\x90\xb6\xe2\x64\xa2\x3a\x4e\x00\x0e\x87\xa4\xc2\x74\x84\x6b\x38\x33\x0f\x5e\xd7\x81\x02\x96\xcc\xac\x00\x89\xd4\x2f\xa7\x27\xba\x04\xc0\x6b\x80\xaa\xcb\xb4\x10\xde\x49\x16\x6e\x7f\x80\x39\xdd\x6c\x90\xdd\x37\x15\x64\xd2\x73\x87\x2f\xa7\xca\xcc\xb1\xd2\x34\x0e\x9e\x8b\xc8\xb6\xba\x9b\x49\x21\x47\x93\x9a\x49\x18\x44\x22\xed\xb8\x2c\x08\xc0\x2f\xc8\x80\x0f\x9f\xbf\x07\x0c\x31\x3d\x14\x24\x89\xb7\xd8\xc9\x29\x43\x82\xab\x12\xb4\x9b\x8c\xca\x03\x73\xa0\xf7\x7f\x1d\x21\xf0\xce\x5d\xa7\x41\xd4\xcf\x08\x15\xe4\x28\xb9\xcc\x29\x13\xa9\x54\x54\xdf\x7f\x58\x8a\xc4\x90\x7a\x9c\x22\x66\xd7\x56\x4e\xdb\x61\x56\xdd\xc4\x7b\x66\xe9\x96\xb8\x40\xe0\x22\xf2\x44\x87\xd3\x01\x6a\x08\x2d\x2c\x56\x68\x15\x2a\x0f\x05\xed\x37\xbb\x40\xd1\x12\x64\xc2\xf6\xfd\x19\xe6\xe3\x91\xb9\xe4\x19\xf3\xc9\x7d\x15\x8c\x83\x7b\x5e\x78\xce\x09\x3a\xb8\x27\x9e\xbe\x0d\x1a\x66\x58\x86\xb5\xc4\xb9\x8c\xa3\x8d\x35\xc7\x24\x7b\xc6\x9d\x09\xf7\xd8\x32\xb7\x86\xb9\x2d\xc0\x14\x9e\x6f\xdf\x77\x7a\x65\xd0\x84\x3e\xbe\xe0\xeb\xe3\x9b\xe8\xe3\x23\xe9\xac\xba\xdb\x79\x7f\xd7\xb8\xe1\x87\x7a\xee\xbe\xeb\x2e\xfd\xf3\xfb\x11\x39\x39\x06\x69\xf9\x47\x7c\xac\xd3\xf3\x97\x67\x6a\x6a\x1f\xa2\x5e\xc0\x17\x53\xf2\xdb\xa9\x4c\x6f\x21\xe5\xf9\xa9\x10\x70\x9d\x80\xf4\x23\x76\x62\x52\x0f\x9d\x77\x14\x89\x29\xcc\x22\x93\xe7\x48\xf4\xc7\xc3\x14\x0a\x59\x25\x3a\x1a\x6c\x35\xb9\xe7\x38\xb6\x83\x7f\xb4\xed\xc4\xfb\x9d\x0d\x30\x8c\xc5\xbd\x26\x44\xf5\x8a\x74\x10\x9c\xac\xf0\xbc\xad\xf7\xd8\x6a\xe0\x10\x87\xf2\xfb\x74\xf7\x3b\x99\x5a\xa6\x8f\xe3\xbf\x33\xce\x47\xe9\xf6\x02\x03\x35\x73\x64\xd3\xde\xb2\x38\x30\xa5\xb1\x0d\x47\x48\xdb\x9e\xc4\x52\x89\x39\x71\xb5\x93\xc8\x70\x60\x93\x1f\x0e\x92\x35\xe6\x21\x75\xb4\x10\xa6\xc4\x07\xa2\xd8\x2e\x61\x91\x8b\x01\x36\x50\xe5\x40\x85\xec\x30\xb9\x68\x38\x6c\xe2\x56\x26\x04\xb9\x4f\xc4\x15\x49\x93\x83\x6e\x48\x12\x21\x7d\x24\x4e\x3c\x10\x18\xd0\x38\xdf\x1f\xdb\x69\x77\x1d\xf9\xb0\xff\x27\xee\xda\x2d\xc6\x7d\xbd\xf9\x6e\x3f\x1e\x9f\x4b\x7d\x42\xc7\x96\xcf\x98\x84\xd3\xf3\xf6\xf5\x85\xd9\x74\xa1\x57\xc4\x6b\x36\xba\x27\xec\xe0\xfd\x5d\x12\xf1\x9a\x9a\x26\xb6\x5e\xf3\x7f\x25\x17\x9a\x1d\xac\x84\x3c\x07\x79\xad\x2a\x17\xac\xf3\x99\x35\x35\xf5\xa3\x1e\x74\x1c\x3c\xbd\x81\x53\x03\xa6\x04\xd6\xec\x25\xea\xb6\x6f\xac\x6f\xce\x40\xdb\xb0\xd4\x69\xce\xd6\xb2\xc8\x61\xda\xc4\xd4\xb6\xf9\xe8\x43\x74\xea\xa6\x71\x16\xc4\xdf\x3e\xf5\xe3\xed\xfb\x1b\x0f\xed\xd5\xc4\x71\x93\xee\x61\xc6\xa3\x3b\x9d\xf6\x25\x79\x73\x4a\xa5\xce\x18\xa5\x67\x09\x59\x32\x9f\x09\x18\x85\x8f\xef\x9f\xdf\xaf\x77\x1e\x90\x77\x45\x26\x1a\x2c\xeb\x39\x7a\x28\x59\x6f\xe8\xc7\x33\xe6\x97\xf5\x0f\xec\x47\x6d\x16\xae\xb4\x5a\x86\x4d\x29\x59\xcc\x55\x3f\x54\xaa\x64\xf1\xd4\xfa\x73\x2f\x46\x9c\x9f\xd3\x63\xe6\x73\x2d\x3f\xe3\xfb\xfb\xe7\x07\x69\x42\xb7\x1e\x05\x03\x5e\x78\xa3\x4c\x7c\x82\x80\x94\x2d\x41\x10\x8d\xa3\xb6\xc9\x0f\x8e\x51\x95\x54\xf8\xe1\xac\x49\xc5\x05\x52\xb9\x14\x1e\xec\x52\x0b\x3b\xe2\x14\x92\xd6\xf2\xe4\x4c\x45\x64\xde\x3b\xc5\x38\x74\x2c\x23\x77\xa7\xfb\xbf\xfb\x17\x78\xe1\xd6\xb0\x72\x02\x9f\xd9\xb9\x33\x13\x71\xab\x7d\x26\xd1\x29\x43\x2d\xae\xb4\x76\xbf\x44\xff\x0f\x87\xf4\x36\xf5\xac\x30\x39\x77\x52\x4f\x1e\x24\xf3\xa7\x76\x72\xc7\xb9\x67\xa5\x91\x48\xa3\x2d\xaa\xce\x44\x30\x07\x3c\xd1\x02\xda\xe9\xe1\x18\x40\xaf\xa4\xc9\x65\x56\x37\x3d\x24\x64\x17\xc4\x88\xd5\x35\x14\xc9\x30\x52\xed\x50\xbd\x8a\x6f\xfe\x39\xff\x76\x3a\x9d\x6c\x25\xa6\x23\xe3\x53\x7b\x94\xdc\xb3\x0f\x2b\x48\x18\x27\x21\xa1\x7e\x89\x27\x51\x81\xb7\x26\x8f\xa4\xbb\xfd\x75\x3c\x42\x25\xf8\x32\x4d\xe6\xae\xa9\x9d\x93\x77\x6d\x71\x06\xd5\xa5\x04\xde\x35\xe6\xb3\xd0\x44\xe5\x8e\x43\x0a\x6a\x0e\xe4\xe8\xf7\x81\x2e\xe5\xa6\x9b\x8e\x02\x0f\xc5\xfb\x2c\x3e\xfe\x24\xc2\xe0\x4b\x83\xee\x26\x54\x4c\x38\x37\x09\x4a\x83\xbe\x96\x97\x4e\x4a\x69\x5f\xfd\x53\xb7\xf0\xef\xf6\x8e\xa0\x2a\x95\x39\xd2\xb7\xbe\xad\x37\x3c\xd5\x5f\x9e\x0f\x9c\xfc\xcf\x8f\xbd\x8b\xa0\x7e\x3a\x9c\x8a\xe9\x64\x7f\x9e\x29\x92\x85\x3e\x61\x3d\xec\xaa\xd6\xd7\x51\x29\x2b\x07\xc9\x2a\x51\x47\x72\x6b\xb0\x2c\xde\x17\x8d\x59\x56\xb7\xd4\xe6\x0d\x7a\xa4\x81\x58\xf7\xe5\xca\x4a\xb1\x45\xcd\x4c\x72\x6e\x25\x25\xff\x3e\xce\xcf\x0f\x3c\x60\xee\xe5\x5d\xdc\x24\x4e\x5e\x4e\x28\x93\x03\x81\x66\xf6\xb5\xdb\xe9\x42\xb6\xca\x67\xf3\x69\x78\x96\x3b\x14\x42\x95\x81\xeb\x53\x94\xf0\x7e\xa2\xa3\x7a\xb1\x26\xf1\x2f\xce\x85\xbb\x77\x03\xcc\x1d\x4a\x03\xcc\xc7\x88\xa8\x87\x92\xa0\x84\x4f\x4b\xb3\x70\x8e\x6d\xf2\xcc\x65\xa5\x69\x12\xcc\x8b\x3c\xdb\x40\x7a\x85\x11\x68\x0d\x8e\x76\x5a\x3a\x66\xf8\xc1\xa3\x03\xc9\x73\x4b\xab\x60\x4c\x60\xea\x0f\x36\x74\x98\xa3\xcb\xa8\x87\x80\x09\xd8\x9f\xb5\x3d\x75\x3d\x23\xb2\xb4\xbc\x14\x82\x4e\xac\xa3\xbe\x89\x25\xf8\xbe\x8f\x9f\x8b\xbb\x78\x5f\x24\x09\xf1\xa2\xb7\xe0\x4e\x76\xf8\xd9\x06\xe3\x89\xbe\x13\xed\xbf\x0f\x5c\xcf\x04\x9f\xf9\x14\xb3\xa4\x0e\xdd\x11\xc2\xcd\x3c\x1f\x8e\xef\x49\x84\xa6\xe8\x0e\x62\xc7\x6d\xd6\x94\x3c\x33\xa9\x0e\xac\x23\xaa\x02\xfa\x2e\xcf\x89\x41\xed\xe0\x23\xee\x78\xac\xaf\x24\x97\x30\xe9\x1f\x44\x61\x66\x2a\x9d\xdc\xd2\x76\x8f\x23\x46\x12\x1d\x79\x58\xbb\x95\x75\xac\xe5\xf8\xdb\x83\x95\xe4\x8a\x64\xcf\x0d\x8e\x7b\x12\x25\x5c\xa8\x1b\x3b\x7b\x5d\xf1\x53\xa9\xd7\x9b\x42\x43\x3e\xb9\xa4\x91\x54\xc2\x19\x15\xb4\x5c\x26\x89\x8f\xe1\x93\xbf\x36\x93\x81\x11\x69\xf1\xc6\x97\x4e\x7e\xd3\x04\x5f\x38\xdd\x93\xaa\xdc\x60\x1e\x15\xe4\x60\xd7\x69\x76\x5d\xad\x12\x0d\x39\xa4\xed\xcf\xe5\x94\xf4\xcb\xfb\x63\x43\xd6\xd1\x44\x45\xe4\x6d\xbd\x80\xc1\x65\xb2\x10\x4e\xaf\x48\xfa\xa2\x93\xc7\xa9\x91\x29\x8d\x17\xf8\x7e\x97\xa3\xf7\x7f\x57\xe8\x21\x9e\x0a\xb5\x61\xd4\x45\x78\x37\x0b\xef\xdf\x33\x0c\x4c\xee\xef\xa7\xc0\x40\xd2\x01\xe5\x00\xf4\x62\xa6\x29\xce\xf8\x02\xa6\xc1\x8a\xb1\xa3\x0a\x69\xc7\xe3\x37\x11\xc3\xaf\x69\x6c\xe6\x0b\x12\x51\x57\x0f\xaf\xd3\xad\x04\x21\x9c\x85\x82\x44\x71\xa6\x5b\x1e\x78\xfa\x8c\xe2\x31\xba\x39\x11\x30\x40\x9d\x3f\x9f\xdb\xf3\xf9\xcf\xd5\xd1\xf3\xee\xdf\xfe\x60\x1d\xcf\x47\x24\xbb\xf6\x88\xec\xe3\x76\xfc\xea\x26\x94\x56\x0b\xd3\x96\xc7\x00\xf4\x89\x6f\x39\xc3\x1d\xf8\x20\x1e\xfc\xe3\x08\xba\x02\x3b\x13\xbc\xfb\xf7\x9f\xf7\xb9\x3d\x5f\x07\x1e\x79\xb6\xf0\x78\xf6\x45\x65\x11\x73\xe9\x98\x94\x66\xcf\xb5\x0e\xbc\x8a\x66\x3e\xd0\x4c\xa0\x15\x73\x9d\xe8\x40\x88\x18\xce\x3c\x6a\x2a\x9f\xd9\xc7\x90\x32\xff\xbc\xb1\x47\xdb\xb7\xc1\xcc\x2a\xce\xe2\x60\xb6\x8b\x2a\x21\x4d\x3a\xc8\x43\x98\x0a\xd3\xcf\x52\x33\x20\xc1\x94\x08\xba\xb1\x76\xac\xc9\xea\x23\x20\x32\xfe\x2f\x0c\x3e\x2f\x0e\xce\x40\x1e\x56\x95\x81\x2c\x98\xb9\x07\xc6\x97\xde\xbc\xd9\xb0\x1d\xcc\x3d\x49\xb8\x0a\xe6\xba\xc5\xe7\x13\x28\x61\x33\xb6\xea\x40\xe8\x8a\xd6\xfd\xf9\x7a\x0f\x75\xb7\xa2\x81\x82\xdd\x9d\xdf\xbf\xfe\xed\x0b\x08\xc8\x7c\xe5\x44\x0f\xef\x04\xdc\x7f\x3c\xff\x05\x4c\x23\x2a\xc8\x82\xfe\x73\x1a\x19\xf2\x02\x30\x53\x31\xbb\x13\xe5\x40\x94\xac\x13\xca\xbb\x54\x0a\xf6\xd0\x7c\x0f\x25\x45\x69\x95\x98\x28\xc7\xda\xd8\x43\xc9\x3d\xa9\x26\xe1\xcc\xe8\x77\x16\x9a\x28\xc4\xb5\xb8\xdf\xc4\x17\x05\xe7\xf7\xfd\x7c\xe3\x50\xdc\xe9\x0c\x2c\xcc\x7e\x62\x3b\xab\x8f\x47\x29\xf4\xdb\x69\xe5\x92\x38\xda\x4b\x13\x33\x86\xc7\x58\x5a\xc0\x1b\x8a\x51\xf6\x04\x3f\x11\x5d\x2d\xb1\xcb\xee\x41\xac\xe4\x68\x79\x88\x51\xc2\x8e\x03\xe7\x40\x98\xfe\x67\x64\xc5\xfe\x63\x08\xc4\x76\x8a\xef\xf7\x3b\xda\x31\x6f\xf7\xf6\x13\x64\x36\xfb\x22\x70\xbb\x3b\x11\xa1\xcc\xea\x9e\x6d\x3d\xfc\xa3\xf6\xc7\x7d\x42\xca\x6e\x7b\xa8\x97\xda\x14\x54\x81\xf2\x91\x5d\xa0\xb4\x90\xd8\xbf\x8a\xd5\x33\xe8\xe2\x74\x4d\x03\xc9\x1d\x9a\x01\x8c\xfa\x70\x31\x7c\x12\x3c\xb2\x31\x1c\xe7\x88\xe7\x1e\x33\x85\xb9\x0d\xf3\x73\xff\x00\xdf\x13\x06\xc3\xd3\x43\x9d\x72\x99\xaf\x52\xd0\x93\xbd\xc6\xe5\xc5\xc1\xde\xb5\x1e\x58\xf0\x98\x3a\x25\x38\xc7\xbd\xbd\x7a\xfb\x5b\xc5\x18\x82\x4e\xd5\xfc\x93\xbf\x80\x12\xf7\x12\x55\xc7\x69\xe2\x5e\xc8\x0b\x2a\xb9\x7d\xb2\xe4\x46\x38\xf7\x90\x2f\xaa\x66\xb4\x91\xd5\xe3\x91\x68\xfe\x67\xce\x9a\xe3\xf2\xf8\x37\x74\xcb\x17\x53\xac\x3e\xc7\x54\xc3\x66\xbd\x39\x14\xc9\xd8\xdb\xd7\xfa\x38\x57\x04\xf2\x68\x40\x0a\xc6\x91\xe3\x18\xdf\x02\x27\x74\x7f\x7c\x38\x8d\x4c\x05\xf2\x0d\xc6\x56\xef\x3f\x6f\xcf\x81\xee\xce\xea\x1e\x10\x9b\xef\x5e\x4d\xcb\x40\xb6\x4d\x9c\x55\x9a\x1c\x1f\x46\x9b\x5f\x26\x46\x81\xce\xff\x22\xad\xa0\xa9\x34\xb3\x33\x24\x72\x12\x42\xbf\x10\x19\xb4\x95\x26\x05\xb3\x48\x1b\x7b\xa9\x5c\x9b\x43\x03\x98\x55\x61\xaf\x9e\x8f\xe8\xa4\x2e\xf0\xfe\x6d\xfc\x6a\x6a\x85\x86\x19\x5e\x0e\xd5\xe8\x67\x4a\xad\x7a\x4b\xd0\x6c\x76\x33\x75\x8c\x6f\x4c\x90\xdd\x2b\xfa\x1b\x76\x6f\x5a\x8e\x88\x0e\x52\x6c\x05\xb9\x98\x70\x06\xaa\x57\xc4\x00\x21\x7b\x3a\x4a\x01\x60\xec\xf0\x5c\x88\x99\xee\x0b\x64\x02\x23\x45\x35\x65\x73\x38\x75\x1b\xb9\x18\x6e\x1e\xe2\xc1\x46\x1d\xd7\xa1\x51\xab\x30\x4b\x29\x5f\x26\x38\xad\xeb\x26\x8f\x64\x44\x6c\x35\x89\x2c\x27\xac\x24\x44\x08\x4f\x70\x15\x93\xc7\xa7\x62\xcb\xa9\x7e\x33\x3c\xe6\x95\x8f\xe6\x28\x81\x3a\x15\x62\xd6\xd3\x10\xca\x9c\x77\x8c\x73\x26\x0c\xe6\x64\xee\xba\x43\x78\x2a\x40\xde\x35\x36\xf8\xf7\x39\xad\x1f\x55\x81\x83\x54\x2f\xa2\x20\x84\x21\x9e\x91\x62\x66\x3d\x9c\x4e\x9a\x14\x99\xbb\x91\x63\x29\x9d\x2d\x6d\x64\xa4\x83\x6e\x66\x61\xdf\xf2\xce\xde\x1c\x9f\x95\x4b\x9c\x84\xd7\xe4\x84\x1b\x6b\x31\xd8\x9c\x4e\x9f\xe2\xa5\x1c\x2e\xca\xb6\x0d\xfb\x69\xfb\xc0\x91\xdf\x08\xcf\x53\xd6\x70\x5b\x9c\x21\x08\xba\xe2\x6a\x87\xbc\x75\xdf\x04\x4d\x14\x15\x01\xf3\x0f\x98\xab\xed\xd1\xb0\xb6\x14\xfe\x93\x53\xcb\x53\x19\xd0\xeb\x89\x47\xae\x52\xb3\xbc\x12\x32\x0e\xd9\xeb\xd9\xde\xda\x16\x1e\x6b\xb1\xc0\xda\xa5\xaf\x9a\x72\xf8\x1b\xeb\x0b\xa9\x28\x16\xe8\x30\x0b\x38\xbc\xed\x9b\xd5\x76\x99\xab\x7a\x89\x1a\xa6\x50\x3b\x15\x29\xfa\xc9\x7c\x5c\xfe\x0c\xb5\xd2\xef\xa7\xf1\xdf\xad\x7a\xcd\x26\xa8\xc8\x9e\xce\x86\xf3\xe8\xa3\xdc\xc8\xfc\x1f\xb7\xeb\xed\xe6\x4b\x10\x6f\x8f\x1d\xef\xe1\x85\x2e\x7f\x57\x0b\xfc\x18\xfb\x5d\xd2\xca\x91\x9a\x97\x21\x84\x8d\xd3\xaa\x86\x32\x75\xee\x26\x34\xba\xbd\x61\xb3\x1e\xa0\x3e\x12\x49\xb6\x0f\x4e\x56\x26\xfe\x4a\x3b\x47\xc2\x23\xdf\xdf\x3f\xaf\x3f\x1c\x10\xd8\xf9\xeb\x1e\xb7\xeb\x7d\x46\x5e\x6e\xea\x6e\xd9\x55\x85\xb3\x95\xb2\x7c\x83\x46\xa7\x8a\x1c\xe3\x2e\x11\x0e\xa0\xbb\x05\x38\x05\x05\x6b\x6e\x4a\x81\xff\x2a\x64\xdc\x5c\x37\xb3\x59\x24\x2d\x13\x53\xb6\x5e\xe2\x81\x43\xba\xe6\x41\x94\x66\x62\x5e\x9f\x2f\xf7\x88\x9a\xd0\x9c\x86\x2c\xd0\x90\xf9\x50\x44\x1b\xed\x83\xff\x07\xe5\xa0\x29\x2f\xa9\xd9\x40\x3c\x02\xa3\x4f\x7e\xcf\x21\x8a\x8d\xe7\xb2\xd7\x2a\x38\xea\x4e\x51\x6c\xc1\xe3\x95\xa4\x3f\x8f\xf5\xeb\xe6\xb7\x89\x19\x8f\x28\xb8\xbe\xa2\x88\xb3\x68\xda\x1d\xfc\xb5\x91\xfb\x62\x29\x3c\xf1\x07\x72\xbd\xa8\x64\x2a\x3c\x40\x21\xcc\xae\x43\x2b\x6e\xc2\xb0\x6e\x3d\x0e\x5c\xd8\x95\x8b\x06\x8d\xa0\x02\x76\xd1\x7a\x7e\x1d\xbe\x7e\x91\xc9\xf8\xfc\x9e\x66\xf0\xa3\x7d\x7e\xfd\xeb\xef\xa8\x84\x8e\xd3\x35\x92\x27\x6d\x1b\xf6\xeb\x82\xaa\xf4\xe9\xdf\xe5\xf6\x39\x56\xa5\xc9\x57\x44\x2e\x7e\xcc\x99\xa1\xb3\xd3\x36\x11\x4a\x26\xc4\x61\x67\xae\x03\x5b\x81\x6b\x5d\x61\x97\xbb\x32\x18\x0a\x25\x54\xe5\x7b\x0a\x05\xf7\x92\x6f\x65\x24\xba\x1a\x75\x56\x8b\x81\x36\x3d\x20\x22\x1e\xa3\x53\x99\x63\x18\x73\x4f\x2d\xe0\x28\x03\x5c\x62\xab\x86\xe0\xc2\x81\x4d\x44\xe4\x92\x4a\xf7\xd9\xfb\xed\x1f\x92\xb1\xde\xc3\x3e\x90\x24\x29\x4f\xa2\xb2\xf6\x7c\x20\x67\x82\xf8\xe0\xbe\x24\xf7\x61\xea\x34\x66\xd7\x87\xa2\x8b\x60\x76\x5d\x81\xfe\x58\x1c\x02\x2d\x62\xd9\x3b\x7b\x8d\xc8\xa2\xc8\xf8\xca\xdf\x8f\xc3\xaf\x9c\x6f\xa2\x25\x3a\xb3\xd9\xbd\xc5\x6b\x61\x49\x6a\xe0\x14\xee\xf1\xa1\xa9\xac\xd3\xff\xcd\xd4\x95\x6c\xa9\xae\x04\xc7\xbd\xff\xc2\x2c\xbd\x6a\x66\x58\xf9\x4b\xbc\xd0\x50\x12\x42\x13\x68\x44\x9c\xe3\x7f\x77\x46\x44\x16\xd7\xef\xbe\x3e\x57\x07\xba\x6f\x83\xa8\xca\xca\x8c\x8c\x8c\xb0\x7d\xeb\x17\x11\x16\x88\x23\x12\x69\xff\xf3\xf5\xb7\x85\xcc\x6e\x22\x38\x87\x8d\xd2\xfd\x47\xf5\x78\x06\xcb\x06\x79\xe9\x85\x61\x50\x51\x11\x90\xeb\xab\x0a\xb1\xc5\xc7\x9b\x14\x6c\x29\x33\x6e\xdb\x49\x3a\x38\x49\x5c\x62\xb4\xfb\xf8\x7d\xdc\xef\x98\x5e\x57\x2b\x4e\xd0\x3c\x8b\xfa\x00\xb2\x22\x35\x86\xb0\xd3\xc9\xc5\x64\x73\x56\x88\xc6\x1a\x2c\xdd\xe1\xd4\x3a\x04\x30\x99\x4d\xc8\x00\x8b\x1d\x62\x97\xa5\xfb\x4f\x3e\x5f\xbb\xfb\x46\x6a\xb9\x74\x74\x53\xcd\x25\xe3\x18\xdc\x46\x65\xeb\x25\x3f\xb8\x59\xbc\x96\x45\xc7\xe7\x70\xaa\x6a\xbc\xcd\xbf\xcb\x31\xdf\x9e\x1c\x87\xa4\x06\x0b\x85\x7a\xbe\x53\x5b\x64\x6f\x45\x86\x97\xcc\x0d\x27\x28\x40\x72\xfd\x6c\x6d\xbf\xde\x76\xde\xd0\x65\x72\x63\x9f\xeb\x89\x86\x5b\x2e\xbd\x48\xfa\xb0\xb7\x73\xb9\xd2\xba\xc4\x95\xa8\xfa\x62\xf2\x64\x01\xd0\x64\xc8\x75\x22\x91\xed\xee\xba\x61\x40\xdf\x33\x57\x87\xe8\x5c\x6f\x27\xf1\x59\x99\xca\x15\x06\xe6\x27\x1b\xb5\x90\x5a\xe2\xcf\x3f\x31\x57\xa4\x0d\x1f\x19\x59\xb4\x5f\xfa\x8d\x63\x0b\xa5\xea\xed\x54\xcf\x23\x14\xe9\x69\xb4\x85\x86\x35\x3a\xd2\xbd\xe7\x2a\x28\x46\x2c\x80\x45\x1c\xa1\xf4\x16\x98\x5a\xbd\x4c\xc3\x12\x0d\x31\x22\xa9\x60\x64\x68\x5e\xe2\xa0\x27\x76\xf6\x55\xaa\x9f\x68\xf1\xe2\xfa\xa3\x18\xb1\x12\x8d\xa2\x71\xaf\x3a\xc0\x8b\x95\x5a\x41\x57\x3b\x27\x37\xc4\x58\x94\x17\x3b\x21\xfd\x3b\xb9\x60\xee\xe4\x91\xb8\xa3\xaa\x4c\x54\x9c\x28\x96\xfc\xa9\x0a\x05\x5d\x34\xa7\xb4\x96\x89\x73\x4d\x64\x06\xcd\xf8\x60\xeb\xdf\x9b\x99\x65\xf3\x9b\xf3\x8e\x2a\x2a\x1a\x81\xd4\xb0\xa1\xc5\x8c\xde\x69\xd3\x10\xa6\x90\x8f\x2b\xfc\x31\x24\xd5\xd4\x53\x04\xde\xe7\x41\x74\x2a\x42\xf2\xf4\x23\xb4\x37\xb3\xe4\x4f\x95\xdd\xec\xb2\x01\xc0\x2b\xb6\x88\x24\x3a\xb6\x6f\xe7\xb6\xc8\x28\xa4\x86\x7e\x99\x74\xcd\xaf\xae\x68\xa9\x14\x02\x0e\x12\x3f\xef\xc1\x03\xd3\x7d\xb4\xf0\x48\x6a\x7e\xf4\x8c\x4a\xb2\x66\x3c\x90\x9e\x95\x58\xa9\xc1\x5e\x9b\xa5\x4a\x73\xc3\xae\x58\xe2\x81\x39\xeb\x91\xc1\x30\x3f\x80\x1b\x2f\xcb\xaf\xf7\xa1\x7e\xe1\xe7\xf2\x4b\x7f\x7b\x11\xb7\xd9\x40\x87\x91\x77\xa0\x95\xaa\x59\x4c\x18\xdc\x89\x31\xc3\x40\xd7\xe8\x4f\xe2\x8b\x97\xa3\x6c\xb9\xdb\x6f\x78\xb1\xd1\xd7\x6e\x2e\x8b\xd6\x61\x3c\x91\x7b\xaf\x8f\xa2\xb4\x68\x4d\x44\x51\x33\xbd\xae\x74\xea\x9e\x2c\xaa\x88\x68\x44\x6d\x51\xdb\x33\xa1\xa1\x41\x8d\xfd\x46\x4a\x33\x86\xd5\x6e\x25\x71\x48\xd8\xf6\x08\x76\xad\x7b\x32\x39\xea\xee\x67\x02\x09\x66\xd5\x43\x51\x05\x74\xdd\x2e\xf6\xbf\x15\x5d\x62\xaf\xc3\x52\x72\x2d\x3f\x1c\x03\x70\x3d\xe7\xa5\x67\x85\x20\x83\x88\x5d\xbd\x60\x3a\x9a\xb9\x58\x4f\x40\x7b\xa9\x06\x69\x6e\xda\xc7\xfa\x3c\xb2\x79\x0e\x79\x06\x99\x72\xa1\x52\xa5\x50\x43\x03\x11\x73\xc2\x5c\xfb\x38\xdf\x7f\x90\xeb\x8d\x15\xf0\xfe\xf6\x52\x2a\x75\xf8\x30\x70\xe7\xe3\x37\x94\x47\xa5\x0a\xc0\x37\x79\x7f\x46\x04\xf7\xcf\xa0\xb1\x84\x7f\xa2\x50\xb4\xa2\x14\x09\x51\x29\xf8\x04\xe5\x22\x39\x41\x93\x77\x8e\xc7\x5c\x04\xc8\xb5\xd9\x8e\x57\xf2\xfa\x4e\xa7\xe8\x87\x72\xbc\xdc\xc2\xd3\x62\xf9\x4e\xc9\x89\x1a\x88\x9d\x3a\xf3\x5d\xe5\xa0\xa8\x3d\x92\x4c\xb1\x8f\x38\x08\x4f\x73\x9d\x62\x25\x57\xaf\x7a\x6a\x3f\x62\xdd\x5a\x81\xec\x66\x6a\xe1\x23\x8d\x00\x78\x96\x6b\xe5\xdf\x96\xf3\x91\x1a\x36\xfd\xbd\x3e\x3c\xd9\xf9\x81\x7c\xbf\x86\xbc\xed\x8a\xbe\x01\xa2\xd8\xf2\xb9\x79\xa0\xe6\xf6\x2e\x2a\x45\xb8\x31\x75\x1c\x0e\xd8\x9f\xae\x87\xf3\xcd\xf9\x8a\x64\xd9\x08\xd8\xdc\x3b\xbe\xf9\x77\xd7\x30\x36\xc9\x9b\x68\xe1\x8e\x02\xce\xa0\xbc\xa1\xb8\x24\x0f\x0f\x8e\x15\xc5\x51\x1f\x97\xfc\x4f\x13\xe8\x60\x05\x35\x4f\x9a\xb4\xe7\xd2\x8d\xac\x76\x4b\x7a\x92\x54\x59\x43\xd9\xbb\x6e\x26\x62\x96\xe6\x70\xe0\x7c\xe8\xa4\x6f\xb9\xbd\x30\x90\x5c\x2f\x97\xa1\x6c\xde\x24\xbb\x9f\xd9\x56\xbe\x9e\x8f\x6a\x1e\xdf\xf2\xea\x91\xe1\x5d\x5c\xee\x9a\x0c\xda\x91\x44\x79\xbd\x46\xcf\x57\xce\xf2\xd1\xee\xca\x1f\xa8\x7d\x8a\xc8\x0b\x16\x5b\x7a\x3e\xdb\x59\xfc\xe0\x71\x20\x22\xb2\xc8\xef\xf8\x9e\xf8\xf6\x60\x66\x2e\xea\x14\x6d\x99\xf7\x7e\x91\x46\x29\xda\x25\xec\x8f\x13\x45\xc0\x2c\xe1\x70\xc5\x2a\xb2\xd2\x84\x7c\x5b\x78\x9b\x34\xfa\x9a\xd9\x56\x94\xc9\xa6\xd5\x4d\x02\x6d\x5b\xaf\x84\xe0\x41\xe3\x4e\x16\xcc\x88\x98\xf8\xe2\xd2\xfb\xab\xfd\xe0\x53\x23\x30\x11\x71\x28\xb3\x75\xb9\xd4\x77\x77\x39\x1e\xd8\x77\xee\x81\x7a\xf0\x68\xfe\x49\x69\x20\x92\x9c\x1c\xef\xb1\x07\xe7\x4e\x0c\x9d\x25\x34\xfd\x3f\x41\x50\x7c\xc8\x6a\xa5\xcc\xc1\x8d\xe5\xc0\x54\xb3\x33\x81\x39\x6a\x9a\x08\xdb\xa1\x6f\x11\x4b\x4b\xbb\x23\x6a\x60\x11\xd3\xc0\x4b\xbd\xac\xdd\xe0\x64\xd0\x59\x5c\xab\x3c\x3c\x5e\x9b\xc8\xf6\xcb\x36\xca\x80\xa3\x7b\xbe\x33\x16\x2d\x9d\xd5\x57\x3e\x86\x12\x7d\xa0\x49\x2e\xee\x57\x7e\x9b\x25\x7a\x9d\x83\xbe\x78\x54\xd2\x6c\xe9\x1c\x0b\x28\xe0\xbc\x62\xfe\x54\x51\x6a\xce\x1b\xe8\xe0\x0c\xb8\x77\xea\x06\x7e\xc8\x4e\xc3\x51\x3e\x56\x8e\x4b\x09\x1b\x81\xfa\x16\xc8\xb3\x7b\x7c\xbf\xe1\x7e\xb8\x23\xee\xd2\x31\x4e\x5d\x5f\xcb\x39\x1f\xbc\x51\x18\x1a\xd3\x2b\x81\x2d\x2b\xb4\x1d\x70\x79\x7e\x15\xac\xa7\x42\xce\x6e\x49\xb0\xcf\xb5\x69\xbd\xed\xc3\xe9\x8a\x59\xf0\x4e\x28\x74\xf6\x58\x3d\xf6\x95\x65\x04\x38\x70\xb8\x61\x35\xda\xab\x3c\x27\x08\x0a\xab\x61\x3c\x5b\x5c\xdd\x4b\x07\xc9\x93\x6f\x3b\xda\x85\xb4\x23\x06\xa3\x37\xbb\x93\xb0\xba\x0f\xec\xac\x7f\x7f\x13\xcd\xee\x99\xb2\x49\x21\x32\x19\x9e\xb2\x8a\x82\x9c\x27\xf3\xcf\x2e\xdf\x44\x1c\xd8\x4b\x5f\x96\x29\xc7\x85\x64\xf9\xfd\xf5\x6f\x8f\xaf\x1d\x87\x12\xb4\x79\x0e\x17\x26\xa8\xb6\xe4\x1b\x17\xa9\xe8\xa4\x9c\xb6\x55\x93\x62\xd2\x3f\xce\xde\x6f\xe4\x60\x72\x05\xef\x89\xba\xcf\x0c\xe4\x53\xf2\xb5\xff\xf9\x24\x88\xe6\x2a\x0a\x08\xff\x6b\xec\x1b\x24\x9a\x56\x0f\xa2\xb5\xd4\x3b\xa1\x6f\xf0\x31\xc4\xe3\x7b\x79\xb3\x0c\x3a\xaa\xaf\x61\xa1\x4a\xad\x97\xd1\xf2\x34\xc5\xeb\xaa\x7d\xb0\x91\xc2\xae\x11\xcb\xc7\xf1\x35\x7d\x4e\x92\x93\x07\x26\x27\xec\x78\x18\x75\xfa\xbe\xa2\xa4\xf2\xab\x3b\x3f\x97\x55\x3b\xc6\xe1\x53\xfa\xfc\x7b\x8c\xf6\x3d\x87\xb6\x3c\xd3\xdb\x49\x9d\xd9\xe9\xf1\xab\x4f\xd4\x87\xe6\x26\x1d\xa2\x09\xf5\xfe\xe0\x7a\x3b\xba\xbf\xa7\xab\x43\xca\x04\x17\xe1\xb4\x9a\xf0\xf4\x85\xaa\xe2\x20\x82\x13\xe8\x41\x8e\x23\xa5\x0a\x53\xc9\x37\xd1\xfe\x84\xa4\x81\x4e\xba\xcb\xdc\xe4\x0b\xfe\xa9\xdb\x71\xbb\xbc\x00\xd3\xdf\xf4\x1f\x6e\xc9\xd4\x2c\x5c\x80\x18\x3b\x3f\xab\x51\x3c\xd8\x2b\x23\xc0\x03\xf1\xb0\x91\xdf\x26\xd7\x3b\x05\xbd\x21\x38\xda\x8e\x4b\x05\x1f\x5a\xb6\x78\x27\xfb\x97\xdf\xf5\x39\x19\x65\x3b\x22\xc1\xee\x94\x57\x61\x89\x91\xe6\x69\x99\x1e\x4a\x21\x21\x58\x0f\xfd\x68\xb5\xc8\xc9\xd4\x3e\xfe\x8d\xe1\x46\xc4\x74\xef\x4e\x79\x5d\x30\xcc\xb9\xcf\xd6\x22\x42\xaa\xcd\x8d\x41\xb8\x44\xf5\x5f\x52\xfe\x31\x51\x2c\x93\xbb\xcb\x0a\x8e\xb5\x36\x6c\xdf\x35\xce\xa0\xea\xa7\xc8\xbd\x72\x5f\xc7\x36\x29\xaa\x1f\xcb\x4a\xcd\x68\xe8\x3f\x15\x4e\x4e\x74\x75\xb7\xf7\xfb\x71\x3f\x70\x7e\x28\x6b\x8b\x5c\xea\xf0\x83\x1d\x49\x83\x23\xc7\xca\xc1\x5e\x53\x9a\x3f\xb0\x32\xa6\x79\x98\x94\x11\x45\xc1\x7d\xad\x09\xbb\xa5\x05\x3e\xdf\xb9\x0c\xcf\x85\x12\x69\x29\x0f\x9a\xfb\x7e\x3f\x81\x86\x88\x47\x32\xf2\x52\xd0\xfe\xf2\x49\x57\x3b\x91\x1f\xc2\x98\x1a\xc1\x1c\x56\x52\xba\xdf\x6a\x02\x29\x2b\x4a\x36\xf4\x98\x3a\x96\x08\x3f\xb6\x37\x27\x8d\xfa\x21\x49\x45\x46\x4a\x7b\xd7\x6c\x4d\x71\x1a\x69\xf4\x1b\x96\x64\x3e\x4b\xdf\xcb\x7a\xd4\x87\xea\xb1\xe9\x2f\x87\x32\x7d\xef\x9c\xda\xc8\xa0\xf6\xaa\x0f\x6f\xbc\xb0\xf0\x5a\x9e\x29\x5b\x9f\x5d\xba\x48\x00\xd7\x3b\xba\xed\xdc\xf9\xda\x5f\xab\x4c\x3a\xfc\x07\x79\x54\xa6\x96\xc9\x6d\xf2\x64\x4b\xc1\x75\x56\x07\x6a\x74\x3c\xd5\xf6\x50\xa7\x93\x2d\x85\x56\xa6\x46\x42\xed\x84\x97\x7a\xc5\xb6\xd8\x27\x76\xe6\x54\xdc\xd6\xb1\x44\xdf\xc4\xb0\xfc\x36\xdf\x62\xe0\x28\x6a\xdf\x2c\x5c\x27\x56\x1e\x3a\x49\xf4\xbf\xa2\x3f\x1d\xea\xb9\x52\xbd\x4a\xcc\x2b\xea\x4c\xfd\x3c\xde\x9c\x5b\xa7\x34\x89\x84\x1b\x2d\x97\x39\x71\x43\x1e\xeb\xea\x74\x20\xac\x84\xd8\xad\x40\xf1\x88\x5e\x1c\x63\x14\x11\x45\xef\xd8\xfb\xc7\x23\x65\xfa\xc5\xfb\xe5\x70\x02\x7f\x05\xf2\xba\x4a\xbd\x2a\x14\xc0\x6a\x2b\x70\x6c\x89\x17\x56\xe9\xac\x7c\xfa\x15\x29\xc1\x13\x4b\x1e\x1f\x8f\x9a\x7c\xde\x83\x48\xd2\xfe\x57\x27\x12\x23\x6f\x5d\xc3\x08\x91\x43\xf8\x44\x58\xdf\xfc\xab\x8a\x22\x4d\xfb\xbd\x8b\x2e\xc9\x47\x7b\x2f\x26\xb0\x4a\x38\xca\x9e\x54\xaa\x0c\x21\xe3\xa5\x31\x36\x8c\xc8\xab\x32\x8c\x52\x49\xe0\x07\x8b\x5e\x58\xce\x03\x0e\xab\xeb\x21\x3f\x4f\x78\x29\x97\x3f\xfc\x41\xfc\x58\xb3\xf7\xd3\x19\x29\x3e\x4b\x0f\xfd\x49\xfe\x50\xf1\xb3\xe7\x2e\x03\x2b\xea\x32\x7d\x64\x05\x59\x26\x96\xe6\x78\xf2\x53\xcc\xc9\xfb\x4b\x48\x38\x89\x5e\xb6\x80\x8b\xec\xc3\x5c\xf8\x06\xa7\xc4\xc1\xbe\xa8\xa6\x37\x26\xac\x70\x46\xe2\xb5\x52\x26\x0d\x4b\x43\x28\x37\x77\xc7\xc9\x7c\x70\x45\x6f\x28\xfc\xfb\x60\x6c\x98\x33\xe7\xe0\x93\xe1\x87\x28\x90\x4d\xae\x28\x60\xf1\x20\x59\xc5\x31\x19\xa9\x81\xe0\x11\x60\x88\x2e\x51\xe2\x5b\xbf\xef\x73\x4b\x8e\xa0\x65\x41\xee\xd8\x43\x80\x48\x9e\x48\x22\x2a\x63\xd5\xcc\xe1\x56\xbc\x3c\x02\xe8\xb4\xb3\xa2\xf0\x48\x85\x5f\x2b\x74\x40\x4a\xd5\x1c\x4c\xf2\x8d\xc2\xf9\xf3\x54\xb9\x4d\xe4\xaf\x23\x94\x87\x67\xb2\xd0\xdc\x60\xfe\x58\xf8\xc6\x9e\x4e\x97\x2a\x9d\xb8\xb9\x6b\x97\xd4\xac\x35\x19\x83\xe6\x98\x0a\x3a\x8b\x24\xca\x6a\xe2\xa1\xa4\xb2\x4f\x5d\xee\xa6\x59\x5d\xd2\x62\x06\x7b\x69\x2d\xe3\xde\x96\xd8\x2a\x4a\x88\x46\xc3\x23\x74\x7e\x67\xfe\x48\x61\x3d\x6e\xf9\x62\x1b\x38\xb1\xda\x42\xee\x60\x94\x81\x6f\x5f\xae\x8c\x28\xed\xd8\x7d\x38\x1c\xde\xae\xef\xcb\xbb\x61\x17\x01\xec\x66\xde\x7a\xbb\x8f\x9b\xf3\x87\x16\xfb\x4b\x03\xba\x32\x30\x60\x35\x71\xbe\xcb\xcc\x61\x7f\x91\x68\x98\xc5\xc1\x44\xd9\x84\x2c\x8e\x30\xdb\x23\x75\xc1\x34\xe4\x0d\x6b\x16\x7b\x4c\xb8\x02\x70\x31\x7c\xef\xc7\xca\x23\xd2\xf0\xfe\x9b\xff\x61\x7d\xcc\xb6\x51\x79\xb2\xcf\x9d\xd3\x8a\xc6\xb9\x0e\x52\x1b\x5a\x2b\xc9\x9b\x1d\x20\x25\x27\x60\x28\x7c\xb4\xcd\x07\xcd\x4f\x82\xd1\xa6\xc3\x6b\xac\x43\x98\xa2\x8e\x6b\x9c\xb3\x66\x57\xdd\x1b\xd2\x8a\xb8\x56\xca\xd8\xd6\x76\x77\x9f\x46\x6c\x0b\xdb\xec\xb9\xb7\x99\x1e\xb4\x1d\x60\x86\x0c\xfc\x88\xb3\xa7\xed\xf3\xd3\x09\x45\xa1\xa9\xc0\x44\x52\x74\x73\x28\xaf\xf5\x71\xf7\x43\x93\xc5\xe9\x2c\x0a\x7c\xed\x04\x29\xb9\xf3\x4f\x1b\x3b\xea\xa0\x77\x32\xc4\x8a\x93\x82\x05\x5a\xbd\x26\xe5\xab\x54\xf9\x1e\x15\x01\x14\x08\x34\xa3\x7e\x3a\xdc\xce\x1e\x18\xc0\xfb\xdb\xeb\x29\x6a\x22\x0d\x68\xc8\xaa\x5e\x6b\x3a\xef\x72\xa3\xfb\x37\xfb\x3a\x02\xd7\x04\xef\x98\xa6\x4f\xac\x9a\xed\x84\x11\x79\x1e\xe1\x44\x85\xda\x38\xea\xa1\x47\x66\x59\x2a\x33\x63\x34\x60\x3c\x1a\x0c\x89\xc3\x84\x76\x15\x09\xa5\xa8\xe3\x94\x36\xb4\x22\xd4\xdf\x96\xe7\x97\xb7\xf3\x7a\x23\xe7\xd7\xfe\xd2\x59\x78\x9b\xab\xe4\x8b\x73\xd3\xf5\xc6\x4f\xd7\xd3\x33\x5f\x78\x77\xce\xe7\xfd\x98\x29\x49\x3a\xff\xc5\x21\x33\x96\x76\x3c\x3b\x1f\x91\xb9\x8e\xee\xbc\x50\x5f\xe4\x30\xb2\xf3\x42\x35\x37\x49\x34\x81\xd6\xbe\xd5\xcf\xbd\xc2\x92\x0c\x25\x23\x7d\xe9\xbc\x6b\x08\xa7\x88\xd2\x98\x55\x16\x83\x35\xc3\x86\x98\x13\x3d\xa7\xfb\x5c\x27\x7f\x6f\xcb\x54\xa1\x85\xbd\x6c\xee\xa4\x7e\xb0\xbc\x52\x71\xe7\xd1\x6e\xa5\xfb\xcc\x57\xce\x87\x79\x25\x00\x2f\x5c\x3a\xa2\xfb\xc7\x5a\xec\x00\x89\xa8\xbb\xfd\x48\x5c\x98\xa0\x03\x2a\xc4\xd1\xe7\x15\x7f\x70\x51\xce\xcb\xc6\xa1\x93\xcf\xe7\x18\x8a\x49\x20\x57\x54\x7c\x85\x6d\x82\x08\x6f\xf3\x50\xef\x6f\xe4\x5f\xe7\xcd\x67\x26\xc8\x35\x97\x10\x58\xdd\x91\x88\x53\xa9\xe6\x98\xd7\xa1\xb9\xb2\xa1\x0d\xa7\x1a\xcf\x44\xda\xa2\x7b\x71\xb6\x23\x64\x95\x68\x6e\x96\x8f\xa5\x95\x6b\x79\xea\x5c\xcf\x6d\x2f\x24\xd2\xbb\x05\x82\xe1\xd3\xc2\x5d\x35\xba\x3f\x93\x14\x7f\xf8\xef\xc1\x14\x05\x0a\xe6\x7c\xd4\xde\xbc\x4f\x26\x01\x27\x8b\x42\xb0\xa5\x0e\xd9\x2a\xfd\x74\x23\x79\x37\xff\xaa\xac\xbe\x11\xf0\x1a\xf2\x36\x62\xb1\x00\x49\x3b\xde\xb4\x7c\x71\x57\x13\xd8\xed\xe1\x65\xd5\xdd\x2c\x9a\x0e\x51\xee\xc2\x49\x73\xbe\x52\xb1\x20\xb4\x9e\xe5\x2d\xea\xcf\x56\xf2\x7d\x6e\xfb\xa7\xb0\x36\x0a\x14\x38\x05\x61\x70\xc5\x8c\xa5\x4e\x3e\x99\xd0\x29\x3b\x53\x5c\x0a\xa6\x6f\x1c\x90\x59\x8a\xfc\x51\x61\x75\xda\x92\x1a\xa3\x97\xcb\xf2\xfa\x3a\xb0\x9e\xfb\x20\xd2\xca\x09\x6a\x62\x55\xd5\xfb\xfb\x9d\x24\x04\x09\xd5\x16\x37\x85\x16\xc0\x7b\xbf\x9e\xf0\x85\x4b\xa9\x1a\xe1\xea\x7d\x58\x8f\xe1\x34\x9c\xc9\x01\x3e\xb3\xc0\x3e\x1c\xce\x6e\x81\x61\xd5\xec\xaa\xab\xd4\x99\x28\xcc\xac\x32\xaa\x20\x7f\x29\xc2\x8c\x5f\x3f\x65\x09\x01\xf5\xb5\x77\xc6\xcc\x47\xc7\xc2\xe7\xf9\xed\xde\xcc\xbc\x82\x5c\x46\x70\xf9\x58\x3b\x26\x82\x56\xbb\xc9\x22\xfb\x78\xc7\x1f\xfc\xde\xc2\xd6\x2c\x11\x0a\x5b\xfa\x0e\x25\x28\x3d\xe2\xd5\x03\x72\x7e\xea\xc9\x85\xc4\x6b\xea\xb1\xea\x64\x25\x36\x5a\x56\x22\x65\xad\xb1\xad\xaf\x47\xa6\x3a\xb0\x26\xf4\xb6\xcc\xc8\xe1\x5a\xa5\x56\xd4\x4f\xe2\xa5\xd5\xb7\xb2\xf0\xfe\xf5\x59\x5f\x70\x93\x45\x3b\xf1\x95\x57\xe2\x7f\x47\xb1\x4b\x91\x86\x07\xf1\x45\x30\xbe\x22\x44\xbf\x7f\xb1\xc8\x9c\x7a\x1f\xf6\x44\xeb\xf2\xa1\xf3\x53\xfa\xdc\xad\x06\x26\x67\x17\x9f\xb6\xf2\x12\xe6\x3f\xbc\x2c\xbb\xf9\x2e\x85\xa5\x2e\x24\x6c\x90\x62\x14\x94\x24\xa1\xbe\xd4\xa0\xe8\xd0\xb7\x73\xe3\x76\x89\xb9\x65\x8c\x85\xf3\x86\x48\x27\x3e\xb9\x64\x21\xe8\xaf\x8a\xba\xf4\x00\xe4\xa2\x4b\x1a\x4b\xa1\xc4\x83\x4c\x9a\x7b\xc2\xf9\xfe\xa4\x6f\xa2\x85\xbb\x8f\xb6\xbc\xc0\xbf\xe3\xb7\x0f\xa3\x12\x39\xe7\x37\xa6\x69\x2a\x74\x3e\xf9\x44\x94\x1a\x0a\xbb\xdc\x38\xc9\x0a\x2c\xce\xa9\xc7\x79\x11\x9c\x69\xb8\xd6\x22\xf3\x00\xc7\x64\xb5\x05\xcf\x00\x46\xb2\xdb\xf9\xe4\xb2\xcd\xf4\x95\x21\x73\xab\x2b\x2f\x07\xbc\x97\xf3\xf9\x34\x7f\x5f\xfc\xa8\xcf\x27\x9e\x25\xb0\x56\x66\xd4\x3e\x1f\x98\x71\x82\xf7\xdf\xbb\x34\xde\xe0\x59\x62\x85\xbc\x97\xa5\xe0\xaf\xb6\xec\xbf\xc2\x38\x8a\x46\x78\x71\xf1\xf5\x61\x42\xba\x74\xf8\x88\x25\x28\xcf\xca\x00\x55\xfa\x0e\x73\x1c\xb8\x69\x47\xd7\x33\x50\xe3\x1f\x17\x24\xc7\x08\x09\xa3\x36\xa8\x9e\x9d\x20\x63\x87\x9c\x2a\xef\xdf\xcb\xfb\xc8\xa7\x37\x57\xcf\x7e\x89\xd1\xed\xa4\x81\xc4\xf3\xa8\x1e\x8c\x04\x97\x9a\xea\xd0\xf0\x62\x28\xef\x36\xa9\x69\x62\x21\xcc\x61\xa2\x89\xdb\x3b\x2b\x5a\x19\xed\x6e\xc5\x8d\x25\x15\x2c\xdf\xe3\x14\xbe\xa5\x8b\xe2\x33\xb0\xa3\xc8\x5f\x42\x11\x2a\xcd\xf1\x0e\xd5\xa2\xb9\x5e\xcf\xe7\xed\x81\x73\xc2\x0f\x3b\x5f\x74\x9a\xdd\x6f\x04\x57\x93\x72\x5b\xfa\x81\xa1\xb9\x89\x12\xbe\x59\xef\x16\x30\x59\x3f\xfb\x5c\x96\xfc\xf5\xdd\xa2\x6a\x55\x30\xcc\xb6\x6f\xcd\xfa\x94\x52\x16\x1a\xba\xce\x0f\x96\x21\x31\xa8\x27\xf0\x02\xa1\xee\x76\x1e\xae\x2d\x4d\xdd\xbb\xe4\x5b\xce\x12\x8e\xb4\x64\x22\xea\x5c\x7c\x05\x9a\x4d\xfa\x95\x60\x49\x7a\xd9\x43\xa7\x03\x11\x12\x86\xce\x4f\x7c\x2b\x32\x6b\xe5\x2a\xa1\x2b\x81\x3d\xb2\xfb\xd8\xb8\xeb\x44\x4d\xed\x32\x75\x0c\x52\xa5\x5f\xa0\x35\x6b\x58\xcc\x9d\xb5\x2c\xd6\xf9\xe6\x44\x74\x16\xbb\xcb\x12\x34\x69\xe7\xad\x71\xfe\xd9\xee\x89\x3a\xbd\x6b\x22\x9f\x48\x82\x5a\x3a\x62\xab\x2e\x12\x58\x9f\xd1\xb0\x6a\x2f\x9d\x80\xbd\x9d\x55\x1a\x1f\xdf\x8b\xf7\xb2\x1f\xa2\xf5\xd8\xe1\x6f\xff\xb4\xa4\x13\x1f\xa7\xc5\x55\x7e\xf3\x9b\xb1\xc2\xa2\xa9\x33\x8f\x11\x57\x63\x2f\x53\x18\x2f\x4e\x05\x71\xcd\x2d\x4f\xad\x98\x5c\xac\xcb\xf3\xdc\x91\x75\x3d\x9f\x02\xf5\xbf\x25\x60\xc0\xc3\x00\x45\x4a\x13\x48\x9f\x42\x67\x61\xbf\x8b\x22\xad\xc4\xc7\xec\x86\xb8\xa6\xc7\x1f\xdd\xdf\xd9\x4f\xf8\x93\x99\xeb\x2f\xd9\x9d\x9e\x49\x2a\xc0\x0c\xa7\x08\x21\xaf\xa9\xed\x02\xe9\x57\x35\xba\x8a\xdc\x20\x75\x68\xfc\x8a\x26\xb0\x12\x9f\x7e\xf9\xac\xb5\x3d\x96\xb9\x1b\x2c\xfc\x47\x24\x83\xd0\x34\x24\x41\x52\x84\xae\xeb\x45\x48\xa1\x79\x25\xff\x1e\x7d\x6c\xa9\x57\xc6\x16\x29\xc8\x16\x4f\x7d\xfe\xb2\x9e\xcb\xf6\x8a\x25\xd6\x04\x2b\xea\xc8\x76\xc7\x7c\x12\xbe\x76\x1c\x37\x8f\xb5\x18\x04\x60\x5b\xb5\x5d\x9f\xbd\xfe\xf0\xb2\x53\x45\xd8\x56\xf9\x0f\xb1\xde\x0a\xf5\x90\x41\x75\x73\x32\xe6\xb7\xe3\x41\x8b\x6a\xd8\x7d\xbc\x06\x00\x21\xdc\x66\x56\x4b\x7a\x10\x4e\x5c\xdc\x81\xfe\x0a\xd2\x68\xda\x9f\xf6\xde\xd0\xc0\x78\xc7\x8e\x6d\x54\x82\x6d\x03\x72\x45\xf2\x37\x31\xc4\xe4\x60\x85\x6d\x34\xaf\x8f\xb1\x8f\xf1\x24\x7a\x5e\x7a\x5d\xd4\x17\x89\xbd\xd3\xaf\x33\xab\xe7\x8c\xb8\x0c\xb5\x8d\xd9\x5e\x4b\x7e\x5a\x34\xd7\x3a\x0d\x3c\x37\x5c\x6e\xf4\x92\x3e\x17\xaa\xf9\x9c\x9b\x2d\xe4\x54\x88\x92\x71\xea\xf9\x70\x57\xc6\xca\xd9\x74\xc6\xd2\x6b\x33\xac\xac\x0c\xf1\xc2\x46\x3d\x39\xe9\xf0\xf9\x7f\x83\x56\x83\x05\x31\xa1\x63\x45\xf5\xc8\x0b\x44\x3b\xb9\x32\x89\xa3\x5d\xf6\xae\x48\x5e\x26\x41\xe2\x44\xc5\x3a\x26\xb9\x4e\x84\xdc\x0b\xf1\x26\x6f\x49\xe0\x2c\x3e\xc7\x69\x96\xbe\x7b\xaa\x52\xd3\x29\x1d\xfc\x07\xa2\x90\xcb\xf0\x69\xa7\x9a\x19\xe7\xcc\x1d\x03\xab\x6b\x96\x6b\xf9\x1c\x27\x3f\x40\xd7\x26\x61\xbb\xff\x36\x56\x29\xae\x78\xb6\x5f\x8e\xc9\x93\x82\x1a\x7d\xf6\x53\x9a\xac\x93\xcd\xb9\x9c\x59\xb9\x2d\x8e\x98\xda\xb6\x1a\x32\x17\x36\x91\x23\xd0\xf2\x0c\x25\xde\xf7\xfb\x61\xf5\x27\x8f\xfc\x21\x34\xb3\x28\x8b\x13\x10\x70\x86\xd5\x19\x8c\x80\x9d\xfa\xb7\xa3\xab\x60\xcd\x6e\x4a\x25\x94\x4e\xad\x8b\x44\x32\x94\x49\x18\x7a\xec\x81\x1d\xa1\x39\xed\x89\xac\xc1\x98\x85\xc8\x9d\xbf\x59\x91\x58\xaa\xe4\xa1\x01\x61\x84\x71\x76\x7b\xa9\x08\xcc\x21\xc2\xaa\x9c\x78\x91\x54\x4a\x3f\x77\xee\x72\xdb\x85\xcf\x3c\x72\x8e\xac\x77\x2d\x0f\x5b\xc0\x45\xcf\x31\x10\x50\xbb\x26\xc5\x58\x47\xe4\xb0\x92\x25\x16\xc5\xbe\x88\xf3\xd4\x63\xa5\xc5\x57\xb3\x93\x1b\xb1\x5a\x9e\xb6\x9f\x5d\x4c\x06\x4d\x88\x4e\x63\xca\xb3\x76\x1f\x87\xf8\xf3\x20\xcd\x5f\x84\x05\x85\xec\x5e\xd4\x92\xb0\x74\x2d\x32\xcb\xc7\x5c\xf6\xf8\xda\xd1\x94\x50\x59\xf5\x42\x60\x84\xe3\x29\x3f\xfa\x08\x48\xab\xf9\xee\x7f\xfe\xf7\x3f\xfe\x2f\x00\x00\xff\xff\x9c\x84\xb0\xba\xce\x07\x01\x00") - -func dataPasswordsJsonBytes() ([]byte, error) { - return bindataRead( - _dataPasswordsJson, - "data/Passwords.json", - ) -} - -func dataPasswordsJson() (*asset, error) { - bytes, err := dataPasswordsJsonBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "data/Passwords.json", size: 67534, mode: os.FileMode(420), modTime: time.Unix(1452717629, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _dataQwertyJson = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xb4\x98\xd7\x52\x23\x3d\x10\x85\xef\x79\x0a\x18\x72\xce\x39\xe7\x9c\x33\x98\x9c\xc1\xe4\x8c\x31\xcf\xfe\x6b\xf8\xb7\x56\xdf\xa9\xb2\xc6\xbe\xd8\xbe\xd9\x6a\x2f\x33\x5f\xb7\x5a\xad\xa3\x63\x67\x8a\x8a\x8b\xa3\xc9\xa7\xa3\x87\xcb\xa8\xa7\x38\xfe\xe0\x3e\x96\xb8\x70\xf7\x37\x74\x1f\x0e\x7f\xa2\xba\x3f\xf1\xdd\x6b\x3a\x9d\x2b\x8e\x5a\x86\xfe\x3e\x13\x3d\x2e\xcb\xf3\xbf\xe1\xde\xff\xff\x13\xa5\x22\x92\x7b\x7b\xfc\x5b\xbb\x19\x1f\xef\x65\xf3\x67\x6c\x1c\x8c\x84\x5c\x4a\x30\xca\x09\x02\xda\xca\x7c\xc2\xb3\x71\x1f\xbf\x6f\x2a\xb8\x8c\xe0\xd6\xd2\xfc\xe0\xf6\x72\x0f\x7b\x5a\x91\x24\x02\x2e\x27\x18\xd5\x04\xc1\x1d\xfb\x1e\xf6\xb2\x26\x49\x04\x5c\x41\x30\x5e\x0a\x82\xbb\x6a\x3c\xec\x75\xdd\xc7\x9f\xdb\x0a\xae\xb4\xda\xbc\x2a\x82\x51\x4d\x10\xd0\x54\xed\x13\xde\x2f\xfa\xf8\x6a\x5a\xc1\xd5\x04\x77\x57\xe5\x07\xd7\x1f\x78\xd8\xc3\x92\x24\x11\x70\x0d\xc1\x9d\x15\xf9\xc1\x48\x1e\x57\xc9\x7e\x0b\xb8\x96\x60\x54\x13\x02\x4b\x12\xf4\x3e\xde\x13\x01\xd7\x11\x7c\x3b\xef\x1f\xbc\x99\xf5\x71\x7a\xce\xc7\x0d\x03\xc1\xe4\x02\xae\x27\x18\x1b\x13\xac\xb2\xbf\x36\xf7\xe4\xb8\x7e\x0b\xb8\x81\xe0\xba\xbe\xdc\x55\x72\x0c\xdd\x58\x15\x54\x71\x23\xc1\x58\xa6\xc0\x2a\x9d\x56\x15\xd2\x7c\x21\x37\x59\xcd\x5b\xb3\x95\x22\xb7\x10\xdc\x5c\x92\x1f\x0c\x09\x8c\xb5\x92\x49\x04\xdc\x6a\x25\xc8\x6d\x56\x82\xdc\x6e\x25\xc8\x1d\x04\xa3\x9a\x20\x18\x82\x12\x8b\x30\x93\x08\xb8\xd3\x4a\xe9\xbb\xac\xe4\xad\xdb\x4a\xe9\x7b\x08\xa6\x40\xf0\x54\x51\x6d\x78\xbe\xa9\x1c\xb1\x20\x08\xb9\xd7\x8c\xdc\x67\x25\xc9\xfd\x56\x97\xc8\x80\x95\x24\x0f\x9a\x49\xf2\x90\x95\xc0\x0d\x03\x2c\x00\xc8\xad\x00\x9e\x57\x7d\xfc\xb5\x13\x96\xe4\x11\x56\xfc\xb6\xe1\x5f\xba\x98\xf4\xf1\xe5\x94\x8f\xef\x16\x0a\x6b\xf2\x28\xc1\x1f\x5b\x1e\x70\x3a\xe6\xe3\xf3\x09\x1f\x23\x79\x22\x78\x8c\x60\x2e\x93\x3a\x4e\xe9\x65\x92\x93\x51\x1f\xbb\xa2\x04\x3c\x4e\x30\x7b\xc9\x4d\xe2\xc5\xc1\x24\x5c\x95\x2b\x4a\xc0\x13\x04\xf3\x41\x02\xa8\xe9\xec\x3d\xf7\xc4\x55\x2f\xe0\x49\x82\xb9\x4c\xc2\xa8\xe9\xdc\xc8\xe3\x11\x49\x22\xe0\x29\x82\x59\x0d\x61\xd4\xf4\xeb\x99\x9c\x13\x12\x27\x11\xf0\x34\xc1\x04\xf0\xb2\xa0\xbe\x53\x86\xa9\x54\x2e\xa1\x80\x67\x08\xe6\x32\x99\x84\x97\x05\x61\x94\x43\x57\xbd\x80\x67\x09\xe6\x32\x09\x63\x95\x54\x27\xaa\x96\x4b\x22\xe0\x39\x82\x59\x0d\x61\x94\x7d\xaa\x13\x55\xcb\x25\x11\xf0\x3c\xc1\xdc\x0c\x56\xcf\x84\xa8\x32\xf1\xe4\x2d\x10\xcc\xf1\x61\xbf\x99\x04\x7d\x4d\x04\x2f\x12\xcc\xbe\x72\x12\x78\x39\xb3\x2d\xec\xb7\x5b\x95\x80\x97\x08\x66\x5f\x09\xa3\x2d\xe6\xd5\xca\x7e\xbb\x24\x02\x5e\x0e\xe9\x31\x44\x5f\x6c\x31\xf5\xe4\x68\x38\xac\xc7\x2b\xac\x98\x8a\x46\xe1\xa1\xc9\xe4\x51\xa7\x04\x38\x9d\x11\xf0\x2a\xc1\xa8\x40\x2a\x63\x42\x0a\x15\xf5\xdb\xdd\x26\x02\x5e\x23\x98\x8a\xc6\x2a\xe9\x5e\xa9\x21\xd4\x16\x57\xbd\x80\xd7\x09\xe6\x4b\x74\xac\xd4\x0d\x4e\x0e\xc7\xd0\x8d\xa7\x80\x37\x08\xe6\x8d\xc0\xfe\xb1\x32\xcc\x7a\xe2\x1c\x6f\x12\xcc\x9b\x99\x93\xc0\xdb\x84\xfd\xe6\x55\xe6\xf6\x47\xc0\x5b\x04\xe3\x3a\x97\x97\xb8\x61\x58\x55\x62\xc5\xdb\x04\x73\x94\xb8\x61\xec\x37\xe5\x94\xc7\xde\xb5\x4b\xc0\x3b\xa1\x03\xc2\xd1\x63\xf5\x18\xb1\xc4\x8a\x77\x59\x31\x75\x80\xc7\x98\xdf\xfa\x69\x31\xc5\x2d\xbb\xf3\x2d\xe4\x54\x8a\xe8\x02\x7e\x5a\x2a\xd8\x16\xee\x11\x4c\x89\x41\x9d\xd2\xa4\x54\xea\x3b\xf7\x1f\xe2\x05\x08\x7a\xdf\xea\xeb\xde\x81\xd5\x2f\x2d\x87\x81\xc9\x08\x82\x13\x7c\xb4\x80\x8f\xac\x3c\xf2\xb1\x95\x47\x3e\xb1\xf2\xc8\xa7\x56\x1e\xf9\xcc\xca\x23\x9f\x5b\x79\xe4\x0b\x2b\x8f\x7c\x69\xe5\x91\xaf\xac\x3c\xf2\xb5\x95\x47\xbe\xb1\xf2\xc8\x69\x2b\x8f\x7c\x6b\xe5\x91\xef\xac\x3c\xf2\xbd\x95\x47\x7e\xb0\xf2\xc8\x8f\x56\x1e\xf9\xc9\xca\x23\x3f\x5b\x79\xe4\x17\x2b\x8f\xfc\x6a\xe5\x91\xdf\xac\x3c\xf2\xbb\x95\x47\xfe\xb0\xf2\xc8\x9f\x56\x1e\xf9\xcb\xca\x23\x67\xcc\x3c\xf2\xb7\x95\x45\xce\xda\x59\xe4\x9f\x7f\x6e\x38\xdd\xbf\xd9\xa2\x6c\xd1\x7f\x01\x00\x00\xff\xff\x4c\xae\x50\xc0\xce\x20\x00\x00") - -func dataQwertyJsonBytes() ([]byte, error) { - return bindataRead( - _dataQwertyJson, - "data/Qwerty.json", - ) -} - -func dataQwertyJson() (*asset, error) { - bytes, err := dataQwertyJsonBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "data/Qwerty.json", size: 8398, mode: os.FileMode(420), modTime: time.Unix(1452717629, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _dataSurnamesJson = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x54\x7d\x5b\x62\xf3\x3a\xcc\xdc\x5e\xfc\xdc\x15\x74\x0d\xdd\x41\x9f\x28\x89\x96\x18\x51\xa2\x0e\x29\xda\x9f\xd3\xcd\x17\xc0\x0c\xe8\xfc\x4f\x27\x27\x5f\x12\x4b\xbc\xe0\x32\x18\x0c\xfe\xdf\xe3\xff\xa4\x76\x3f\xfe\xf7\xff\x7d\xb4\x23\xdd\xdb\xe3\x7f\x3d\x7e\xca\x76\xb6\x72\xca\x57\xef\x94\x73\x0a\x47\xb3\x6f\x9e\x51\xff\x3b\xd5\xf2\xd6\x7f\x5a\xc2\x2b\xe9\xff\x1f\xf2\x23\xb1\xe2\x67\xf1\x4b\x47\x29\x35\xca\x7f\xef\xf0\xc9\x45\xff\x25\x9c\x4b\xac\xf8\xb7\x9f\x30\xef\xfc\xd3\x5b\xba\xf5\xa7\xb6\x50\x2b\xfe\x50\xa8\x77\xd2\x7f\xb9\xb7\x72\x5c\xf8\xa1\x35\xd4\x39\x85\xf1\x8f\xf1\x57\xbe\xac\x65\x4a\x7c\xbc\x39\x87\xba\xdb\xb7\x96\x9a\xd6\x6e\xff\x9c\xe3\xdb\xfe\x5c\x8e\xfa\xd7\xdf\x21\xef\xf6\x74\x5b\xc8\x59\x1f\x45\x1e\x56\x7f\xf3\x53\xfa\xb9\xea\xb7\x63\x3d\xf5\xf1\xf4\x37\xf7\x64\xdf\x7a\xcb\x9f\xda\x6e\xfd\x0b\xe5\xb2\xef\x6f\xc9\x7e\x75\xad\xd1\x7e\x35\x2c\x58\x90\x29\xe0\x2f\xaf\xe5\xfc\x0d\xd9\x7e\xf2\x8c\x5c\x82\x59\x1e\xd7\xfe\x51\x56\x74\xde\xa2\xfd\xfe\x15\xab\x3f\x7f\xac\xb7\xfe\x85\xbb\xd7\xd3\x7e\xea\xd2\x8f\x48\x57\xb3\xdf\x3c\xae\x89\xbf\x20\x2f\x67\xff\x1c\x5f\xe1\xd4\x7f\x8b\xcb\x3b\xd4\xc5\x7e\xaa\xc8\xcf\xdb\xf7\xda\x1d\xe5\x9b\xfa\xb8\x2d\x9c\xf2\x51\xbf\xb6\x01\x5c\xd2\x5a\x56\x59\x78\xfd\x22\xc6\xc5\x7e\xad\xec\xf8\xf7\x35\xe8\x63\xf2\x83\x8e\x5e\xaf\xed\x63\xaf\x94\x72\xd4\x2f\x6a\x7a\xc5\x1a\xf0\x1b\x97\x3d\x43\x4d\xf3\xa6\x1f\x8e\xd7\x2b\xff\x74\x5d\x8a\x3e\x8e\x2d\xb2\xfd\xe7\x96\x8f\xb5\x23\x72\xc5\xdb\xf7\x7b\xad\xc1\xfe\x5e\x38\x12\xde\xfe\x1d\x6e\xfc\x8b\x9c\xa3\xb2\x37\x3c\xf7\x82\xa7\xbc\xe4\x43\xa2\x3d\xd6\x79\xc6\x5b\xdf\xe9\x5d\xca\x62\xcf\x55\x71\xf8\x6a\x69\xcd\x76\xed\x7b\xa2\x64\x29\xe2\x61\x6f\xf3\x13\xcf\x1d\x8b\x22\x8f\x5c\xf5\x63\xaf\xf2\xc6\x1b\xe6\x62\x5b\x7b\x85\x7b\x3c\xd9\xd6\xd7\xcd\xfe\xe6\x53\x0e\xa9\x7d\xf1\x0e\x6d\x93\x23\x70\xe3\xf1\xfa\x8d\x63\xdd\xd2\x71\x14\xfb\xab\xcf\xd2\xee\xbf\x3b\x8e\xdb\xf0\x09\xe7\x6d\x07\x2b\xfe\xb3\x17\xb1\x97\x4e\xcf\xa7\x1d\xe5\x25\x05\x3b\x41\xe1\x63\x3f\x7d\x7c\xf0\xa2\xcf\x62\x0b\xb6\xc9\xaa\xe4\xdb\xd7\x49\xfe\x4f\x3f\xae\xcb\xce\xbe\xec\x7d\xe4\xec\xe6\x60\x0b\xa2\xcb\xc0\x6d\xb7\xff\x8d\x4d\x3f\x52\x5e\xee\xc4\xe6\x7e\xce\x92\xed\x07\x9e\xa9\x6d\x38\x32\xf2\x57\xda\xb8\x5d\xf8\x88\x34\xf1\x7e\xce\x4b\x39\x43\xb6\x03\x51\xfb\x2f\x6e\x57\xe3\x05\x29\x72\xcf\x7e\xed\x1d\x0f\x9c\xa5\x5e\xb1\x85\x4f\x39\x43\x58\x67\x5d\x53\x5b\xaf\x38\x4d\x58\x20\xde\x56\x59\x9e\x17\x1e\xe9\xee\x33\x8e\xee\x55\x78\x11\xb6\x34\xdb\x6e\xcf\x35\xbc\xf9\xfa\x53\xf9\x2c\xf6\xe1\x6e\x36\x2a\x17\x75\xd7\xfd\x5f\x3e\x38\x59\x35\x62\x21\xff\xd9\x0f\xc9\x41\x2a\x7c\x67\xac\xbf\x5c\xa1\x66\x8f\x5b\x17\x3c\xc3\x16\xde\x76\x36\xf3\x81\x13\x83\x23\xc5\x4b\xc7\x9d\xb7\x1d\x5b\xc2\x99\xa2\xbd\xc8\x15\xe4\x87\x71\x5b\xf1\x66\xa7\x1c\xf6\x62\x5f\xc9\xbe\xd8\x0f\x3f\x63\x5d\xbb\xbf\xa5\x58\x42\x5b\xda\x37\x8f\xdb\xd2\xcf\x13\xa7\x8e\xdf\xd8\x3a\x2f\x4a\xbb\xe2\x39\xe3\x4c\xc8\x1d\xc1\x65\x97\x55\xba\x36\x2c\xd3\x15\x3e\xf6\xa7\xae\x14\x2b\x4f\x3e\x0e\xee\x21\x07\x75\x8b\x6f\xfd\x19\x39\xfa\x25\xe3\x96\xad\xa7\x1b\x5a\x6c\xae\xdc\x25\x7e\x60\xf9\xda\x9d\x5a\x6c\x1f\xe5\x99\x66\xdb\xad\x76\x7e\x16\x5a\x40\x33\x13\xb3\x3c\xac\x9c\x72\x9c\xb6\x1c\xec\xf3\xe5\xe0\x56\x7c\x5a\xed\x09\x07\xb6\xe2\xda\x3f\xed\xa6\x57\x9a\x85\x50\x8f\x76\x57\xdc\xa5\x59\x7f\xe4\xc4\xe6\xbe\x63\x78\xf1\xe4\x8b\x8d\x8c\x3c\x7f\xc5\xae\xb0\x98\x8d\x97\x9d\x24\x39\x27\x5f\xe3\x60\xbb\x9c\xf1\x57\x9f\xb2\xc6\x7b\xb6\xfb\x92\xc3\x1b\x2f\xf2\x94\xad\xb1\x13\xbd\xf6\x5b\x16\x07\xb6\xa3\xcd\xdb\x91\x96\x9b\xef\x29\xff\x79\x85\xf6\x1f\xac\xfe\x1c\xda\x2d\xcb\x52\xf4\x61\xb6\x18\x71\x75\xe5\xa3\x2f\x1c\xd9\x92\x13\x1e\x50\xae\xf2\xad\x47\xbb\xc2\xca\xc1\xa6\x3d\xbe\x8e\x0e\x4e\x4a\xfd\x1f\xcd\x80\x3c\x9a\xdd\x5c\x39\x6f\xfa\xfb\x93\x5c\xb0\x72\xd9\x25\x9a\xcb\xc7\x0e\x1a\x4d\x4c\xc8\xaf\x50\xff\x98\x5f\x1c\x35\x31\xdc\x76\x7e\x9f\x7f\xfc\x8c\x1c\x85\xdf\x80\xb3\x8b\x0f\x39\xd7\xfe\x89\xf4\x8e\x65\xc2\xf1\x4e\xba\xe5\xcf\x4e\xdf\x9a\x3f\x62\xdb\xf1\xab\x15\x96\xb1\xea\x4b\x14\xdc\x46\xfb\x27\x71\x85\x5c\xba\x1a\x7e\x13\x1e\xb6\x8b\x03\xe1\x53\xe0\x8a\x89\xdd\x2c\xf6\xd9\xf2\x8c\xf1\x2c\x76\x09\xdf\x58\xa2\x23\x2e\xe9\x0c\xb6\xe5\x6f\x7c\xe8\x24\x67\x02\x27\xa7\x3c\x9f\xf8\x21\x59\x77\x9e\xb4\x96\xe4\x7d\x6d\x3b\xfd\x73\xe5\xc6\xc8\x71\xb2\xc7\x16\x8b\x0c\x5f\x2a\x26\x19\xef\x2f\x6b\xb3\x06\xbb\xb0\x1f\xbb\xfb\x1a\x3d\x2c\xfe\x7b\x17\x4f\xf1\x61\x86\x66\xd3\xed\x36\xe7\xf3\x0e\x8b\x3e\x7e\x2b\xb7\xbd\x68\xc8\x3c\x39\x67\x0c\xd9\x1e\x26\x2f\xc3\xbe\xbf\x23\x3e\x4e\xcf\x36\xbc\x73\xa5\x0f\x91\x2b\xfc\x32\x53\xf0\x93\xe4\xfd\xe1\xd1\x0b\x57\x5e\xac\x65\xf6\x8d\xf6\x95\x2d\x53\x4d\xf1\xe4\x99\xb2\x25\x6e\xfd\xbe\x69\x39\xe5\x49\x4f\x3b\xb4\xb9\xcf\x81\xe1\x0f\x3d\x93\x84\x20\x7e\x18\xe5\x72\x4d\x78\x54\x59\x14\x0b\x25\xec\x1b\x37\xd6\x46\x23\x82\x8a\xeb\x7b\xe3\x51\xef\x08\x5b\x6d\xd6\xbd\x6e\x65\xa1\x1b\xb5\xfd\x98\xe2\xbc\xdb\x4b\x73\xa3\x36\x35\x1a\xf6\xd1\x33\x4c\x18\x37\xd6\x3e\x7a\xea\x6d\xb3\xe5\x16\xef\x66\x36\x49\x62\x08\x33\x51\x7e\xb1\xc4\xdb\xde\x29\xac\xfa\x5a\xa7\x87\x09\x7a\x09\xf4\x9d\xc4\x32\x45\x7b\x84\xb9\x7f\xfd\xa7\xbd\x86\xdc\xbc\x9e\xef\x5f\xac\x13\xc3\x9e\xfe\x8b\xe7\xb9\xc2\xaa\xbf\x73\xf4\xb3\xe0\x07\x6c\x47\xec\x76\xf3\x12\x9e\x0b\x23\xc4\x38\xf1\xc5\xb3\x3d\x65\xfe\xc0\xb1\x8a\x51\x6f\xb6\xa8\xef\x92\x9f\x11\x1f\x77\xca\x0d\xc0\x8d\xed\x1e\xea\x48\x58\xd0\xdc\xc6\xd7\x0b\x67\x37\x72\xef\xf0\x87\xe7\x7e\x1c\xdc\x7f\xf1\xe4\x70\x10\x7a\x48\x12\x5c\xac\x7a\xe5\x1b\xcb\x93\xb1\x5c\x5b\x9f\x26\x04\x2f\x2d\xe4\xf0\x1b\x2c\xd2\x89\xf1\xc5\x78\xa0\x0e\x8b\xfd\xf2\xcf\x96\x3b\xb5\xc6\xc6\xb8\xe5\x36\x5f\x74\x07\x0b\x64\x67\x06\x27\xab\xff\x9a\x2c\x8f\x1d\x9a\x30\x23\xe8\xb2\x7f\x95\xe0\xb6\x9e\x7e\x9a\x56\x8b\x51\x9f\x62\x56\xed\x17\x96\x98\xd7\xb0\xe8\xd6\x84\xb5\xa7\x6c\x4f\xf3\x8a\xab\x1e\x82\x35\x97\xd7\xf8\xa3\xb8\x5b\x73\xd9\x22\xce\x43\x3d\xe0\x1b\xcb\xe2\xe1\x5e\x99\x26\xac\x99\x9c\x1a\x9e\xef\x1c\x12\xfc\xf0\xba\xe2\x9f\xe4\xaf\x54\x73\x02\xf2\xc2\xcd\x5e\x40\xfe\x34\x3d\x9c\x58\xc6\x9d\x97\xf9\x96\x70\x5f\xee\xf0\x62\xc7\xe1\xf6\x00\xa8\x70\x51\xf5\x52\xf2\xc3\xdf\x30\x35\xc7\x85\x6f\xa8\xe3\xb7\x47\xd7\xa0\x0b\x7f\xf6\xed\x76\x48\x7f\x9f\x56\x47\x76\x42\x82\x11\x7b\xe9\x0f\xef\x81\x1e\x78\x04\x31\xfa\x18\x6e\x24\xe4\xdd\xe0\xcf\x0b\x22\xa1\x13\x8b\x1c\x16\x1a\x0f\x39\x5c\x0c\xcf\xe4\x6f\xba\x87\xd6\xd0\x0d\x16\xc9\x4f\xb2\x18\xd8\xc9\x76\xa3\xd8\x91\xff\xaf\x27\xf8\x6e\x09\x73\xf5\xa1\xdb\x24\xdb\x63\xc7\x79\xd6\x18\xde\xa2\x62\x49\x2c\xd4\x22\xe9\x23\x4a\xe0\x55\x25\xfe\xc7\xee\x2f\xe5\x65\x76\x48\x02\xab\x09\xb1\x02\xb6\x58\x0e\xd9\xaf\x6c\x04\x22\x2c\xf1\x23\xbb\x3d\xf8\x52\x3e\x76\xb7\x5a\xe8\x1e\xef\x4a\xa2\x62\xeb\x5e\x32\x03\xb4\xaf\x23\xc1\x8a\xa8\x3b\xb5\x28\x2a\x2c\xf2\x6f\x30\x89\x6e\x03\x3b\x4c\x99\x5e\x37\x9e\xe0\x79\xd3\x4c\xc0\x3c\xd0\x2c\x36\xcc\x6c\xe7\x56\x3a\x3d\xd9\xbc\xc9\x65\xbf\xdd\x1e\xef\x39\xda\xfe\x5d\x35\x98\xd1\x93\x9f\x5f\x57\x84\x24\x6a\xce\x61\x5e\xb2\x5a\x11\x38\xe6\x5f\x89\x82\x63\xc5\x9e\x49\x24\x08\x6f\x34\x75\xbd\xdc\xc1\x83\x37\x44\xe3\x57\xe4\xc1\xb9\xd2\x7d\xe3\x17\x26\x79\x9d\x0f\xd6\xb4\xd4\x23\xd9\x75\x50\x6f\x21\xf9\x83\x65\x1d\xb5\xd8\xb7\xae\x82\xf0\x36\x17\x66\x27\xa1\x31\x2f\x34\x6b\xb1\xd4\xb0\x23\x18\xa6\x6b\x79\x3e\x3d\x96\xbf\x90\x06\x1e\x6e\xd6\xc3\x34\x21\xf8\x68\x6e\xff\x4e\xff\xa7\xad\x3f\x9f\xf6\x47\x1b\x4c\xce\x53\xf3\xc6\x5a\x2c\xd7\x71\x4f\x36\xf9\x61\xb1\xa8\xb1\xb9\x7f\xc0\x1f\xb8\xf1\xa2\x6a\xd1\x1f\x8c\xaf\x47\xce\x50\x70\xee\x66\x3d\xfb\xe6\x08\x34\x3f\xb5\xd3\x14\xee\xcd\x4c\x6d\x93\x1f\x16\x0f\xe0\xc9\x35\xcf\xee\x1c\x6c\x91\xed\x60\x30\xe5\xd9\xb8\x08\xe2\x72\xe2\x29\xfe\xfc\xc1\xa4\x0f\xe1\x40\x37\xcf\x20\x61\x64\xbe\xb0\x55\x62\x2f\x2c\xe7\xd6\x7d\xc7\x45\xd1\xbf\xee\x0f\x7f\x06\x5b\xc1\xd6\x75\x13\x2d\xa8\xf4\xc0\x51\x7e\x0a\xc9\x9c\xee\x16\x2f\x16\xa2\x32\x59\x76\xba\x33\x8d\xb1\xe1\x1a\xe7\x22\xa7\x08\xfb\xbc\x05\x3b\xbb\xe2\xc7\xe3\xa9\x41\xbe\x3d\xb2\x3d\xf9\xca\x6b\x1c\x3e\x21\xe3\xa6\xbc\x11\x3b\xbd\xc2\x2f\xff\xe2\x92\xe6\xf1\x6c\x76\xb3\xf5\xc7\x67\x49\xaf\x2c\xfe\x90\x60\xe7\xb4\xbb\x76\xa5\x13\xd1\x0a\xe3\x71\xa6\x09\x67\x2d\x11\xbb\x2d\x46\xe7\x01\x24\x81\xb9\x78\x51\xbb\x60\x98\x43\x33\x4f\x0d\x6f\x53\xf1\xe3\x19\xf1\xcd\x9e\xea\xf4\xe1\x49\xc0\xf9\x94\x8b\x77\x00\xb2\x58\x8a\xfa\x0f\x3c\x64\x61\x98\x21\xc7\x19\xe6\xf6\xb0\x5b\xbe\x8b\xd1\x64\x3c\x7d\xce\x38\xb8\xab\xde\xc1\x75\x63\x9c\x4f\xc7\x23\x4e\x4a\x0f\xa8\x7d\x85\xf5\x79\x0f\xd3\xab\xc7\x01\xf1\xb6\x5c\x89\x8c\xcd\x97\xd4\x6d\xc4\x05\x66\x07\xda\x81\xff\x1e\x1e\xa2\x68\xd2\x80\xbd\x99\x60\xd5\x96\x8f\xa7\x9b\xc8\x75\xe4\xe5\x6f\x0d\x9d\x6c\x63\x3f\xbc\xd8\xe1\x1f\xac\x62\x3b\x6d\xb1\xc4\x0d\xe1\x6f\x48\xe8\x23\xe7\xc7\x2c\x87\x86\x8e\x70\x25\x85\x5e\x66\x8a\x81\x3f\x86\x70\x3d\x0e\xc4\x66\x8b\xc1\x92\xb6\xc8\x54\x76\xfd\x26\x98\x92\x3d\x33\x68\x57\x1f\x67\x3b\xff\x42\x6c\x20\x7b\x67\x7f\x41\xde\x50\xf6\xee\x9b\x8e\x30\x9f\x94\x73\x03\x13\x76\x74\x8f\x1a\xf6\x78\xa8\x87\x17\x8f\x18\xfd\x6a\x99\xe7\x16\x67\x12\x19\xfb\x89\x69\xe3\x2d\xb2\x07\x8d\x81\x76\x4e\xb6\x39\xda\x99\x7f\x69\x32\xc4\x3b\x8a\x30\x71\xeb\xc7\xb5\x55\xbc\x97\x3d\xb7\xd9\x95\x8e\x23\xbd\x75\x09\xcc\x1c\x59\xda\xe0\xe3\x97\x52\x61\x26\x26\x89\x42\xb0\xd9\x62\x13\x98\xfa\xc7\xc0\x50\x96\xfb\x23\x21\xad\x1d\x78\x4d\x2b\x1e\xe6\x71\xe7\x9d\xf1\xe9\xa7\x98\x81\xb2\xc4\x02\xff\x74\xca\xb5\x96\x05\xbb\xcc\xa2\xc4\x57\xb2\x60\x5c\x82\x10\x39\xa3\x0e\x03\x15\x60\x22\x3d\xe1\xee\xe9\x21\xdb\x68\x6c\x25\x82\xf8\x04\xbc\xda\x82\xe0\x46\x7d\x94\x05\xf6\x92\xdc\xf3\x43\xe5\x3a\x3d\x99\x6a\xeb\x09\x8d\x6b\x21\x76\xd2\xfe\x9a\x1f\x5f\x5e\x5c\x20\x39\xda\x15\x9f\x07\x13\x41\x57\x8e\xe8\x84\x6e\x79\x2b\xf0\x77\x77\xe0\x0d\xdb\x4f\x98\x90\x20\x07\x78\xb6\xf7\x60\x8a\x0b\xb7\x96\x61\xc7\x6b\xf9\xb1\x57\x6b\xfa\xa4\xf6\xba\x07\x8d\xb3\x62\x03\x38\x0a\x51\xac\x23\x76\xa5\xbd\x35\x93\x44\x54\xca\x8c\x53\xef\x4a\xaf\xb0\x84\x27\x5c\x47\xc5\xa9\x90\xc4\xe1\xc4\x66\x3c\xc7\x5e\x9b\xc7\xc7\x3d\xaf\x06\x97\x9c\x84\x10\xde\x31\x21\x12\xab\xfd\x87\x29\xa3\xa1\x25\x38\xc3\xb9\x00\x4b\xea\x4c\xe6\x24\xcc\xa1\xc7\x15\x7f\x18\xe1\x97\x0a\xed\x99\xfa\x64\xf9\x38\xb3\x12\x1a\x2f\x00\x26\x94\xa4\xd8\x3e\x57\x73\x54\xfe\xfd\xc0\xcb\x22\x3f\x6e\x16\x31\xfe\xbb\xe9\xb7\x2c\xeb\x97\xd8\xda\x9e\x38\xea\xb9\x98\x1f\xc4\x58\x11\xe5\xbd\xc4\x9d\x7a\x92\x2b\x9f\x6f\x27\x4b\xbd\xee\x6a\x7f\x47\x6f\x0b\x36\xd5\xdc\x90\xbe\xa5\x1e\x4f\x5d\x88\x42\x53\x21\xd7\x2c\xc3\x7a\xcb\xde\xce\x88\x2b\xd4\x43\xdb\x33\xca\xd9\x07\x10\xa0\x36\x87\x69\x93\x1d\x03\xd9\x6a\x73\x27\xa1\x13\xfd\x7b\xe1\x83\xd4\x95\x13\x62\xb9\x24\x38\xc0\x03\x02\xd6\x44\xe6\x21\x11\x12\xc3\x9d\x65\xc0\x3a\xe6\x29\xd4\xde\x5c\xc4\x0b\x63\xdc\x79\xc8\xe5\x85\x0a\xee\x92\x27\x61\xf6\x4b\x92\xae\x6b\x1c\xcf\x38\x39\x2d\x8b\xfb\xcc\x66\xf9\x26\x1e\x84\x41\x48\xd6\xdb\x63\x7f\x0e\xf1\xb0\x1c\x52\xbc\x82\xc5\x88\xb8\xf7\xe1\x36\x40\x61\xdc\x18\x5b\xbd\x02\x14\xe5\x29\x61\x9b\xe5\x89\xcc\xe4\xec\xde\xaa\xcf\x7b\x58\x0a\x76\x0e\xf7\xae\x76\x8a\x50\xe7\x33\xb9\x97\x9c\x93\x66\x01\xfa\x20\x7b\xb1\xe7\x91\xcf\x55\x5b\x81\xc5\xb1\x0d\xdd\xf0\x3b\xb2\x86\xc8\x80\x25\x7c\x62\xd0\x14\x7f\x0c\xdc\xde\x81\xc2\x48\x7e\xe3\xd8\xa3\x44\xdf\xf6\xe7\x25\xc0\x94\x6f\xc2\xa0\x1d\x61\x59\x80\xc6\xf4\xd6\x0a\x36\xe9\x24\x54\xad\xbf\x61\x6b\xcd\xc4\x42\x81\x2c\xf8\x69\x79\x39\xf3\x76\x12\xc8\xac\xb6\x2d\x04\xc1\xe4\xca\xe0\x52\xfa\x91\xea\x75\x9c\xad\x07\x6c\x18\x63\xe7\x43\x2c\x7e\x31\x67\xf5\x0c\x3d\xef\xb8\xf2\xe2\x1c\x11\xad\xee\x67\xb8\xd4\x88\xed\x34\xbb\xb2\x08\x16\x4c\x01\xca\x20\x88\x8f\xb4\x5e\xce\x1c\x41\xc0\x8d\x41\xb6\x9e\x09\x2c\xce\x16\x99\x1f\xcb\xad\x59\x22\x6c\xa0\xad\xed\xa7\x12\xc6\xcf\xb4\x3d\x19\x96\x02\x10\xa6\xa3\x5e\xe7\xdd\x71\xd4\x92\x07\xd2\x1a\x3d\xd8\x3d\xe8\x0a\x52\xd9\x7d\x97\xef\x32\x1e\x95\x6f\xb9\x77\xb3\x75\xdb\x61\x68\x24\x5e\xc1\x9a\x78\xc6\xb9\x4a\x90\x67\xb7\x69\x19\x89\x88\x24\xeb\x37\xe3\xf8\x53\x0c\x20\xe2\xc6\x89\x80\xc5\x1c\xeb\x2b\xf0\xe3\x36\x26\x44\xe9\xf4\xc0\xb3\xd2\xf1\x1a\x26\x28\x5f\xfc\x06\x8d\x9a\x1f\x9a\xf8\xd0\xbe\xe9\xa2\xea\x4f\xb8\xf1\x11\xe7\x7b\x5b\x06\x52\xba\x1d\xde\x63\x16\xfb\xc6\xf0\xba\x05\x87\x5d\x65\xc9\xe8\xb5\x81\xd4\xca\xa5\x1a\x00\xaf\x5c\xa1\x6e\xb1\x59\xf4\xe4\x48\xae\x2b\xb1\x02\xcd\x29\x80\x18\x05\x3e\xda\x56\xae\x8b\x51\xcc\x88\xce\x35\xe9\x33\xf4\xa4\x7c\x46\x36\x6c\xab\xac\x39\x6a\xad\xdf\xac\x89\x16\x86\xf1\x03\xa1\x70\xc5\xf6\xcc\x25\x88\x45\xf3\x07\xff\x20\x21\xba\x34\x08\x44\x94\xce\x3b\x2d\x67\xb2\x98\x51\x3a\x73\xb8\xec\xae\x7e\x96\x48\x57\x45\x30\x60\xde\xed\xa1\xe6\x22\xb1\x15\x53\x0a\x31\x70\xe6\xff\xdf\x9e\x16\x17\xbf\x3b\x72\x07\x69\xb0\xe9\xa8\xe6\xc2\x54\x54\x8e\xd1\xc2\x97\x41\xea\xf0\x8c\xee\x37\xf4\x30\xf1\xcb\x67\xa7\x67\xcf\xc5\x5d\xb0\xfc\x16\x2c\x77\xf1\xb4\x6b\xf3\x0a\xc9\xc4\x1b\xa4\x80\x05\x30\x3f\x82\x8c\x6a\xbd\xf4\x8f\xc4\x97\xfe\x7f\x59\x86\x59\x9a\xe8\x6a\x17\x7d\xd2\x88\xd7\xd0\x7b\x0a\x30\x20\xf9\x27\x84\x4c\x43\x28\x7f\xd0\x00\x22\xa6\x6a\x7a\x55\x23\xff\xe4\x61\xeb\xf6\x7c\x22\xa5\xb9\x7f\x25\x4e\xaa\x48\xb4\xcc\x84\xfc\x4a\x60\x85\x32\x1a\x5c\x57\xc8\x0c\x0c\x8e\x59\x83\x40\x9c\x23\x71\x46\xaf\x68\xfe\xc1\xc0\x30\xd6\x7f\x0c\xdb\xa8\x7a\xdb\xb1\xf0\x9e\xdf\xab\xad\xe1\x16\xac\x72\x54\x60\x6c\xc2\xd3\xd6\x29\x47\x96\x4c\xde\x08\xe5\x0d\x68\x27\x54\x93\x90\xac\xde\x81\xf7\xa2\x9d\x04\x7a\xc4\x52\x8d\xa2\x0a\xcd\xda\x1b\xeb\xb3\xc1\x56\xd9\xa6\x99\x71\xd2\xda\x0c\xb2\x86\x81\xc7\xe9\x67\xca\xb5\x86\x5b\xd1\xbf\x1e\x91\xa6\xe7\xc0\xfa\x43\xd8\x08\xdf\x00\x0f\xd3\x2c\x95\x81\xa0\xbd\xa1\x1a\xea\xc0\x3b\x62\xf8\x92\x99\x1d\x89\x78\xdd\x71\xdc\x21\x7b\x62\x34\xa7\xc0\xda\x03\xcb\x6c\xe1\xce\x09\x69\xe5\x3c\xfb\x1d\x5c\xf0\xac\x7b\xe8\x9e\x65\x14\xfb\x91\x19\xb9\xd8\x54\xb2\xa3\x40\x4f\xff\x59\xf3\x64\xe6\x09\x18\x2f\x48\xaa\xe2\x30\xcc\x2e\xc7\x48\x9f\x48\x02\xc9\x01\xc5\xfa\xfa\x4b\x8c\x8c\x93\x98\x35\x49\x79\x20\x8c\x22\x14\x9b\xe0\x25\x9b\x2c\xae\xad\xc2\xf9\x85\xdc\x01\x62\x55\x0d\x58\xb0\x47\x2f\x7a\xee\x37\x51\xb9\x76\x88\xa7\xc1\xb6\x25\x5a\x69\xee\x88\x9c\x1e\x16\x83\xec\x78\xa1\x46\x5b\x68\xbe\x74\x6d\x59\x58\x7a\x79\x08\xb9\xc4\x9f\xd8\xba\xed\xe2\x67\x41\x7c\x52\x27\xfb\xb8\x15\xc8\xfb\xc3\xa0\xfe\xad\x26\xd6\xbb\x6e\x24\x24\x1d\xc0\x9e\x1c\xc8\x6c\xe9\xcb\x44\x14\x45\x5c\x5c\xd8\x86\xb3\x3c\x79\x80\xe4\x46\xe8\x8e\x76\x37\x2c\x9a\xba\x61\xd3\x24\x44\x7d\x67\x26\x49\xc5\x52\x72\x0d\xac\x3c\x1f\xd5\x7d\x76\xa3\x81\xd8\x40\xd2\x1c\xfb\x8b\xbd\xb1\x46\x7d\xfb\xe6\x7f\xfc\x40\x44\x9a\x10\x5d\xca\x04\x20\xee\x84\x3f\xe0\x75\xc8\x7d\x06\x6a\xa4\x51\x8d\x59\xb6\x66\x88\x8a\x1f\x48\x3b\x44\xe5\x1b\xa5\x48\xea\x69\xa9\xeb\x54\x3a\x33\xc1\x50\xf9\xc5\x54\x70\xe5\x97\xf2\xb5\x14\x28\x9b\xda\x32\x9d\x91\x21\xff\x4c\x18\xee\x8d\xd7\x78\xca\x72\x12\x68\x9b\xdc\xfa\xbe\x91\x6e\x2a\xfe\x42\x17\x18\x50\x7b\x92\xe4\x07\xd9\xdb\x27\x54\x09\x40\x11\xc0\xac\x8a\x46\x01\x28\x2a\xf3\x5d\xe0\x41\x10\xbd\x65\xc9\xcd\x11\xc6\xc3\x8b\xc9\x3a\xac\x96\x9b\x4d\xe2\xfa\xed\x68\x58\x10\xd2\xa3\xd5\x09\x24\xf5\x0b\xf1\x39\x2e\xba\x99\x99\x2d\x66\x54\xd2\xcb\xc7\x9e\x60\x05\x7e\xd6\x6e\x3f\x35\x19\x88\x4f\x52\x7b\x64\xc7\x97\x29\x9a\x2d\xf2\x6b\x04\x66\xfa\xd6\x74\x60\xc1\xc1\x75\x45\x5d\x99\xb9\xe1\x06\xbc\x0b\x81\x58\x31\xdd\xbb\x2d\xa5\x5d\x28\x7b\xeb\x8a\x6c\xcf\xbe\x26\x4c\x18\x2c\xff\x7c\x11\x76\x5b\xcc\xf0\xb6\x4b\x83\x6c\xfe\xf9\x8d\xe6\x6f\xf1\x9a\xf9\xa4\x85\x18\xc0\x33\x92\x29\xb2\xda\xb6\x0e\x63\x4d\x74\x43\xe3\x56\x2b\x61\xbd\x03\xad\x99\x64\xe4\xf6\x5b\x77\xb8\xfb\x01\x1b\x02\xe0\x58\x31\x0d\x5b\xe8\x6e\xa0\xde\x55\x3f\xb6\xfe\xa5\x96\xdf\x19\xf1\x5f\xd0\xbc\xe5\x26\x24\x64\x98\xbe\xd6\x55\x08\x3f\x14\xb9\xa1\x48\xd8\xc4\x5e\xca\x83\xd1\xe2\xcb\x59\x69\xe5\x40\x40\x09\xfc\x99\xe5\x0a\xe2\x10\x7a\x50\x68\x99\xd3\x61\xdb\xb3\x96\xe5\x89\xa4\xf9\x29\xff\x16\x56\xda\x7a\x7b\xd8\x59\xeb\xae\xb6\xc1\xb1\x49\xc0\x67\x90\xf5\x32\x92\x97\x26\xd6\x87\xb8\xb3\x46\x24\x5b\x37\x93\x5d\x7b\xe4\x22\xce\xab\x98\xef\x84\xcf\xa8\x84\xc2\x61\x52\xb5\xb6\x4c\x97\x2d\x76\x02\x09\xa9\xc4\x8f\x2c\x08\xdd\xc8\x52\xb4\x7e\xa0\xe7\xb5\x38\xa2\xa0\x27\x67\x25\x20\x26\x46\xd9\x0c\xdf\x25\xa9\x8b\x59\x80\x1a\xc6\x65\xc6\xc2\x8b\xa9\x9e\xc4\xd5\xc3\x8d\xd4\xfd\xeb\x32\xff\x62\x7a\xea\xa2\xfd\x61\x37\xe4\x44\xee\x86\x80\x33\x5b\x7c\x16\x56\x20\xe7\x12\xba\x60\x0d\xae\x82\x18\xef\x4a\xc4\xff\x3e\x8e\x19\x20\xa2\x3b\x34\x4d\xb3\xc7\x4a\x07\x2b\x26\x53\x47\xa0\xa5\xd9\xbd\xfd\xb0\x18\x18\x43\xf3\x70\x6a\x3a\x4c\xcc\x61\x96\x32\x4d\x13\x41\x5a\xe6\xa2\x72\xc9\x79\x03\x22\x53\xa8\x2b\x1b\xda\x67\x7f\x87\xe8\xd6\xec\xd0\x55\x1d\xe5\xf9\xe4\xce\xff\xa9\x9f\x7a\x16\x33\xee\x34\x70\xb5\x4f\xc9\x50\x68\x25\x17\x30\xe8\x8b\xf9\x0b\x1c\xa2\x54\x2e\xbb\x6f\x78\x6e\xe2\x7d\x13\x0f\x85\x27\x91\x2d\x85\xe9\xd9\xc3\xed\xa0\xdf\xc0\x1b\xd4\xb2\x36\x66\x83\x92\x56\x55\xa0\xb2\x33\x00\x3d\x8b\x8b\x08\x5c\x62\x19\x73\xdc\x68\xc6\x46\xe9\xfa\xb7\x4b\xf2\x63\x90\xb8\xd6\xcd\x80\x68\x85\x27\xcf\x8c\x23\x7b\x60\xc7\x18\x4a\x23\xe6\xbe\xc2\x09\x9e\xe9\x9f\xdd\x83\x98\x59\x6a\x0f\xbc\x38\x08\x91\xe4\xfa\x4d\x76\x26\xc4\x28\x30\xe9\x48\xe7\x4e\xe2\x05\x0a\x57\x17\x2f\x81\xae\x0c\x13\xab\xb5\xd0\x2e\x55\xb5\xde\xfa\x85\x1a\x3e\xfd\x8e\x96\x18\xca\xa8\xd8\xc5\x7a\x20\x98\x1c\xf9\x10\xcb\x72\x8a\x7d\x21\x32\xf1\x2c\xd0\x22\x41\xda\x41\x7d\x63\x1e\x64\xb5\x2e\x38\xc7\x8e\x34\x7a\x96\x5b\x1a\x37\x67\xfa\x20\xbf\x0a\x35\x31\xa3\x21\x2c\x3d\xe1\x8a\xc7\x7c\x0f\x18\x57\x22\x7e\x10\x06\xe4\xd6\xc2\xa0\x79\x00\x7d\x77\xa6\x3a\x33\x5f\xe9\x0a\x1f\x8f\x59\x62\xae\x56\xfe\x9e\x15\xbb\xf7\x3a\x6b\x41\x00\xa1\x11\xf9\x20\x51\x2d\x7e\x2e\xf4\xb2\x93\x99\x30\x15\x10\xbe\x64\x07\xf5\x60\xdc\x25\x33\xf9\x5b\xa2\xe4\x34\x08\xe7\x92\xbc\x55\x2d\xc0\x8b\xbc\xc8\x2b\x37\xda\x16\xe2\x95\x56\x0b\x34\xee\x70\x25\x78\x9e\x84\x47\x17\xff\x49\xf8\x5c\x41\xa3\xee\xd9\xab\x91\xd1\x12\xe3\xd6\xbd\x5b\x20\x68\x8c\xab\x40\x1e\xca\x49\x33\x7f\x47\x49\x6a\xcc\x13\x81\xd1\x61\x74\x06\xfe\xc5\x59\xd9\x4d\xf6\x69\x31\xe2\x6a\x17\x5c\x70\x46\x9a\xd7\x96\xae\x0b\x78\x02\x2e\x76\x48\xb0\xeb\x01\xe0\xac\xfc\x49\x46\x97\xca\x62\x00\x20\xa3\xcf\x80\x93\x04\xb0\xdb\x8e\xe7\x54\xde\xb0\x2f\x2f\xa0\xe4\xb6\xe5\x6f\xd4\x63\xab\xd2\xc9\xf0\xd4\xea\x50\x22\xe0\xa5\x2b\x5d\x34\x51\x12\x0a\x32\xf1\xd7\x7a\x21\x50\x40\xb1\x5a\x1b\x0b\xc7\xb7\x6d\xe3\xe2\x89\xb9\x16\x23\x8c\xef\x17\x9f\x1a\x29\x30\xc6\xce\x6a\x43\xe5\x16\xc3\x7c\x2a\x4f\x00\x41\xc6\x11\x0d\x8b\x97\x88\x12\xee\xd3\xc2\x16\x78\x58\xcf\x9d\xee\x72\xe4\xc1\xcd\x1b\xbb\x3a\x25\xfc\xcd\x87\x59\x53\x71\xb2\x76\x7a\x1d\xd5\x6e\xe6\x9c\xbc\x66\x14\xcb\x95\x79\x55\x24\x36\xb3\xcf\x55\x3a\x60\x70\x0a\x13\xf9\x45\x38\x76\x06\xc2\x15\x04\x1d\xca\x0a\x6c\x6e\x83\x71\x4c\x66\x62\x9a\xcd\xcb\x62\x72\x10\x81\xc2\x91\x89\xa3\x20\x87\x07\x63\xd5\x8e\xaf\xee\xc4\xa2\xb8\x87\x43\x4c\x0c\xfb\x42\x1e\x39\xc9\xd1\xc5\xe3\x99\x9b\x98\x4a\x7b\x3b\x81\x8e\xf0\x84\xde\xf5\x1b\x41\xdf\x15\xc4\x74\xdb\x36\x1b\x9d\x09\xa1\x02\x73\xa8\xf3\x2c\x58\xba\x74\xc2\x4e\xd9\xef\x01\x4d\xc8\xfd\x74\xca\x1b\x36\x5a\x63\x90\x08\xf2\x84\x78\x64\x98\x7d\x2e\xd7\xd6\xbd\xa2\x70\x27\xa7\x42\xb4\x3f\x6c\x4b\x45\xad\x89\xac\xeb\xd1\x38\x17\x2e\x90\xb2\x13\x1f\x56\x51\xe3\xc1\x09\x5e\xe0\x5c\x58\xab\x09\x53\x05\xcb\x51\x52\xcf\xd7\xa8\xf9\x9a\x8b\x96\xbc\x00\x56\x96\x94\xa1\x49\xa9\x2d\x86\x7c\x7a\x51\x58\x5e\x90\x7c\x1e\x85\x34\x02\x63\x42\x04\x09\x17\xc9\x2f\x6a\xea\x17\xc6\xb6\xef\x41\x37\x71\x90\x62\x76\x78\xc9\x99\x9d\xf6\xd2\xa4\x7d\x14\x16\x98\xaa\x1b\x40\x35\xd9\xfc\xb8\x99\x69\x6d\x3a\x1d\x2e\x32\x9e\xa1\x9d\x82\x64\xc9\xe9\xd2\x77\xb7\x52\x12\x3c\x99\x7d\x0b\x5f\x47\xab\x51\x63\x75\xdf\x41\x78\xfa\x8b\x5a\xc9\x39\x5e\x40\x86\x8b\x83\x3a\x91\x6a\x1b\x5c\x92\xa7\xbb\x4e\x4d\x3c\x90\xe5\xc8\xad\xc7\xb3\x2d\x08\x6e\x35\x98\xb1\xd4\x2e\x5c\xd9\xf3\xb8\x43\x79\x48\x08\x9d\x73\xb1\x54\x5e\xfd\x61\x72\x00\xd2\x8e\x50\x05\x90\xc1\x24\xa6\xa5\xdf\x48\xa7\xae\x25\x46\x7c\x40\xbf\x10\xcc\x34\x59\x27\x5b\x96\x78\x4b\x84\xf8\x7c\x78\xdc\xec\x95\x0d\x46\x0a\x4f\x87\x7a\xe7\xd0\x3d\x7a\x76\x02\xe5\xda\xb5\x78\xc0\x8b\xac\x0c\x40\x8b\x47\xcd\xf7\xbd\x35\x5b\xc5\xde\x88\x65\x03\xd0\x8d\xfd\x50\x4c\x04\x37\x03\x3c\x0c\x3c\x43\xc3\x69\xd9\xbc\xb2\x83\x83\xf1\xec\x66\x45\xe6\xe2\xa5\xc5\x2b\x48\xd2\x88\xda\xfe\xaa\x55\x10\x4b\x10\x66\x24\x18\x9b\x1a\x7e\xa0\x51\xcd\x03\xf0\x0b\x77\x3c\x9e\x83\x75\xd3\x82\xb3\x27\xd4\xa3\xc5\x3b\xb1\x74\x9e\x9c\xa4\x26\xf6\xd8\x73\xa1\xd2\xc9\xea\xcb\x49\x72\x57\xfb\x90\x5b\x7c\x4f\xf6\x92\x39\x10\x98\xe2\xa9\xd6\xc1\xa2\x97\x46\x95\x6f\x58\x14\x6c\x1d\x2c\xbe\xa1\xbc\xe5\x41\xe8\x18\x64\x0c\xb5\x5a\x4e\xb7\x94\x4f\xed\x04\x0c\xe8\x2b\x2f\x42\xce\x72\xa4\x59\x62\xb9\x87\xb3\x64\x7a\x23\xa7\x82\x06\x0e\xd5\x93\x6e\xe4\x54\xbb\x12\x62\x8f\x19\x75\x6c\x1d\xc1\x4d\x3f\x80\x48\xc4\x33\xa1\xf2\x1c\xaa\x39\x02\x56\x59\x70\x2b\x43\x5f\x12\x71\xa7\xb0\x5a\x09\x3d\x28\x2f\x17\x3e\x44\x62\xf3\x6a\x81\xd0\x9a\xae\x61\xc0\x5f\x08\x17\x98\xc2\xbc\x80\x21\xc9\xb9\x25\x1a\xd6\x5a\xb2\xba\xbe\x98\xfd\x41\xe1\x9a\xb5\x4a\x6d\xa9\xc1\x52\x70\xc0\x17\x86\x67\x9a\x31\x68\x4e\x25\x8e\x3d\x02\xd1\xc8\x8c\xfa\xdd\xf4\x6a\x21\xd3\x7e\x53\xa9\xe5\x8c\x13\x3b\xdd\x89\x12\x15\xdc\x56\xcd\xf8\xfb\x8e\x96\x28\x27\xe3\x76\x16\x4a\x43\xf9\x6c\x2b\x49\x1f\xac\x26\x03\xa7\x73\x5c\xf4\xde\x31\x98\x13\x3b\x4e\x93\x23\xfb\xcf\xf4\x38\x62\x27\x3f\x12\x00\x90\xb7\x8a\x38\xa4\xc9\x53\x7b\x02\x77\xe1\xc3\x3a\xaa\x5f\xea\x3c\x80\xbe\x89\x7d\x74\x6a\x80\x13\x64\x24\x53\x64\x24\xa1\x06\x09\xa6\x75\xea\x9e\x9b\x2a\x55\xd1\xd9\xab\x28\xca\x19\xc1\x97\xc8\x24\xd9\x43\xca\x7e\xe0\x61\xe9\x92\xa0\xb3\x8e\xe1\x11\x5e\xe0\x7f\x7f\x53\x5c\xc9\x53\xbe\xe4\x1a\xb3\xb4\xb1\x85\x85\x31\x78\xe5\xd3\xb6\x7e\x90\x94\xd4\xbd\x28\xf5\x1b\x5e\x2c\xd0\x6f\xb0\x90\x7a\x79\x19\xec\x88\x3d\x6c\x33\x89\xa4\x61\xcb\x38\xcf\xc0\xc4\x2a\x1c\xa4\x3d\xd7\x7d\x06\x64\xac\x7f\xfa\x04\x0e\xc9\x32\xc0\xb8\x3d\x70\xfe\x7e\x0a\x8d\x71\x0b\xe4\x81\x6d\x71\x61\xa6\xb5\x71\xb9\xf5\xbf\x66\x16\x12\x42\x14\x89\x38\x33\x56\x52\x6e\x3e\x3d\xbd\xfc\xb9\xf6\xd7\xbe\xd2\xec\xae\x3d\xa1\x96\x65\x10\x6e\x22\x6a\xc9\x1c\x44\x5d\x2d\x8e\x45\x4b\xf6\x6b\x0e\x0a\x04\x9a\x8c\x78\x82\x2f\x23\x2f\x12\x58\x3f\x1d\xf8\xad\x51\x2f\x4e\x2f\xaa\x9e\x44\x44\x32\xe2\x9f\xe8\x60\x87\x96\xea\xf0\xbe\xf0\xa5\x57\x0c\xa4\x05\xc4\xee\xec\x51\xc9\x6f\x9c\x89\xa4\xdc\x2a\x37\x61\x16\x0d\xb9\xf9\x63\x21\xee\x00\x4b\x36\x0f\x52\x3c\xbe\xad\x3c\x7a\x06\x6d\xb3\xa7\x39\x11\xa1\xe3\x3d\x08\xea\x65\xc3\x3b\xec\x91\xc4\xb0\x83\xc6\x16\x1c\x27\xa3\xa5\x34\xbe\xae\x25\xe5\xa7\xc4\xc6\x01\x95\x93\x16\x09\x70\xa9\x2f\xb2\xc8\xd9\xec\x8c\xfe\xd5\x00\x87\xb9\x77\x44\x51\x24\xde\x3c\x50\x92\x76\x0e\x8f\xbb\xf9\x7e\x27\x00\x1d\x6f\x7c\x68\xe3\xf5\x51\xcf\x4e\xaf\x7a\x79\x31\x2f\x7f\x70\x0d\x32\x41\x61\xcd\x7c\x71\x66\x96\xc1\xad\xde\xfe\xa4\x5a\xce\x26\xfa\x0c\x4a\x4e\x40\x49\x59\x83\x5d\x56\x12\xd6\x8e\x6d\x8c\xf6\xac\xb9\xfc\x85\x02\x9d\x76\xef\x21\xaa\x18\x5f\x52\x10\x36\xef\x45\x90\x9c\x3e\x7b\x0a\x21\xb9\x51\xb2\x9b\x6b\xa8\x9a\x5d\x06\xcb\x35\x4f\x5a\x16\x96\x55\x65\xbd\xf8\x57\x2c\x8e\xc0\xf9\x0d\x6c\x1a\xb1\x3e\x13\xf5\xea\xfa\x17\x3f\x8e\x63\x35\x05\x93\x19\x12\x6b\x7c\x6e\x11\x81\xf6\x68\x30\x7d\xfd\x86\xd6\x62\xf4\xf8\xb7\x2d\xcc\x02\x21\xed\x6d\xf9\x28\x7c\x5a\xc6\xe6\x1c\x86\x5d\x63\xc1\xbe\x09\x59\xe0\x49\x5b\x9d\x31\x8e\xdc\x03\x47\xdf\x2c\xe3\x19\x2e\xb8\x99\x56\xba\xc5\x65\x59\x29\xa5\x88\xf7\x90\xb7\xbc\xa3\x1d\x95\xc2\xb0\x56\x4c\xa9\xd3\xf7\x25\x2e\xd0\x3b\x61\x86\x2c\x4c\x3c\xf4\x12\xa0\xdf\xd8\x82\x26\xa6\x29\x22\xe1\x23\x9f\x4b\x7e\xb7\x59\xd2\x14\x6e\xae\xf1\x1b\x68\xf9\x6b\x30\x2d\x2f\x43\x6c\x2d\x02\x3d\xc3\xc7\xd7\xca\x01\x9c\x27\xb0\xe7\x5e\xf9\x8c\x53\xcc\xfe\x8a\x4a\x1d\x7d\x3e\xc8\xaf\x04\x86\x7e\x9a\x9b\x20\x7b\x09\xc8\xcd\x07\xa1\x52\x7b\x3b\x39\x41\x6c\x2b\xda\x98\x2e\x92\x83\x90\x2a\x2d\xfd\x15\x68\xfd\x40\x16\xfa\x97\xc0\x41\x50\x38\x9f\xd8\xc2\x16\x11\xce\x2b\xd8\xce\xf2\x6d\x49\xb7\xbd\x4d\x46\x85\x50\x31\x13\xbe\x56\x9a\xbd\xb2\xf0\x72\xd0\x98\x55\x21\x09\xf7\x91\x75\xbf\xed\x2c\xd1\x55\xe7\x17\x72\x27\x79\x7b\x22\x21\xd1\x5e\x6f\x8f\x0e\xfb\x2f\x0e\x63\xc9\xfd\xe4\xd5\x95\xf3\x93\x90\x33\x5b\x1d\x42\xcd\x97\x9d\x5e\x65\x9a\x58\xdc\x32\x31\x3e\x13\x4b\xb5\x74\xd4\x35\x79\xac\x25\x21\x25\x58\x78\x97\x89\xcc\xce\xb6\xb1\x0a\xbe\x15\x66\xc5\x8a\xd4\xe0\x80\x0f\x7e\x90\xc4\x12\x2f\xbb\xb1\x5a\x29\x1f\x3c\xa0\x8b\x5b\x16\xd1\x9d\xf1\x53\xb4\xca\xd0\x1c\x75\x4b\x03\x1d\xce\x65\xc2\xf3\x86\x5e\x09\x9d\x9e\x12\x14\x24\xb7\x62\xf0\xa0\xa4\xab\x68\x9e\xd8\xae\x52\xbe\x66\xc4\x36\x4e\x36\xd7\x96\x5d\xb6\x56\xd2\x80\x05\x0f\xc7\x1a\xb7\xc6\xf5\xfa\x0d\x6f\xe7\xc8\xbd\xed\xf8\x6d\x73\x6a\x1a\xda\x5a\x36\x7a\x6f\x2c\x8c\x35\xe7\x39\xab\x8d\xc4\x1d\x94\x70\x9a\xd8\x02\xb9\x26\x4e\xf4\x5a\x71\xce\x02\x69\x68\x4a\x38\x7a\x18\x1a\xee\x0c\x48\x83\x88\xe7\x4e\xb8\x27\xd8\x5a\x2e\x8e\x07\x07\x40\x3b\xb6\xf4\x28\x72\xc6\x76\x8f\x64\xe5\x2e\x3c\x80\x12\x47\xf0\xaf\x1d\x7d\xb0\xf8\xc9\x02\xf4\x0a\x9c\x62\x88\x76\x98\x7e\x98\x56\x6e\xa3\xf4\x5e\x16\x52\xab\xe6\x9e\x5f\x5e\xa6\x84\xf3\x89\xdc\xc1\x33\xae\x95\x01\x9f\x57\x22\xf4\xd3\xcd\x2d\x77\xad\x5d\xd2\xd1\xea\x79\x60\x99\xfc\x26\x8e\x6f\x70\xa1\xa4\x28\x83\x9e\x51\x24\xa0\x35\x67\x7c\xfe\x61\xf8\x1d\x1f\x7a\xfb\x9f\x6e\x90\x3b\xa8\x01\x5e\x0e\xb4\x3f\xbd\xc0\x1f\x69\xca\xc5\x94\x2e\x80\x5b\x3d\x75\xd0\x17\xb4\x4f\x6f\xf1\x96\x8a\x81\xb7\xe7\x70\xe0\xee\xdc\x5f\xaa\x8b\x7e\xf5\x09\xbf\xa0\x4c\x0e\xc3\x7d\x39\xb7\x73\x4d\xce\x89\x9a\xdd\xcf\x83\x19\x9b\xbc\x55\x43\xee\xb1\x36\x27\x90\x3d\x5e\x4f\x22\xf9\x62\x86\x26\x7b\xdf\x83\x39\x8e\x5e\x61\xec\x11\x48\x87\xa8\x64\x00\x3a\xb0\x5d\xc5\x21\x61\x5b\xcf\x4a\x33\x2e\x31\x8a\xbc\x07\x48\xde\xcb\xc2\x1b\x93\xfb\x0f\x49\x0d\x6f\x33\x06\x3f\xf2\xb6\x04\x86\xb6\xfe\x39\x51\x2f\xec\x8e\xfc\x2c\xde\x8e\x50\xb7\x12\xf0\x9c\xc5\x88\x73\xb0\x72\x7b\xf2\x8c\xeb\x0f\x8c\xbd\x81\x04\x89\x04\x85\x5c\x1b\x23\x42\xcb\x1b\xd4\x08\xb4\xd7\x36\x47\xa3\x48\xa6\x24\x2b\x2b\x98\x45\xb2\x0a\x83\x38\x63\x5a\x69\x76\x41\xe9\xb8\xe8\xce\x94\xe0\x95\x1c\x48\x79\x5b\xe8\x23\xf7\x54\xbe\x65\xce\x73\x63\xf3\xc6\x82\x53\x56\x95\x04\x7e\x3c\x10\xd1\xe3\x2a\xc9\x8b\x79\xc5\xc8\x96\x56\x21\x0c\xc0\x96\x28\xce\x5f\xcc\x54\xc3\xc7\xfb\xa3\x0c\x98\x63\x0e\x34\x3b\xd3\x49\x72\x05\xb8\x02\x59\x7c\xa6\xf0\x7b\x60\xf4\x21\x26\x09\xdf\xf2\x03\xba\x8d\x45\x2c\x87\x65\x49\x12\x93\x22\xf6\xc8\xc1\x16\x62\xaf\x28\x17\x48\xc8\x1d\x2d\xe7\xd3\x16\x08\x4b\xad\xb2\x64\xce\x96\x31\x86\x09\x05\xb1\xb2\x0d\xce\x04\x36\xfb\xe8\x0b\xf9\x1b\x1e\x91\x4e\x19\xa4\xb3\x1a\xd9\x8c\xf2\x14\xff\x0f\x4a\xed\x41\xff\x55\x78\x9a\xce\xa0\x68\xd0\xc3\x38\x7d\x2f\x04\x74\x92\x70\x8f\xa6\xab\xca\xbc\x76\xa4\x8a\x56\x51\x7a\x80\xdf\xc2\x9c\x65\x50\x4f\x73\xd2\x95\xde\xcf\x4e\xd6\xcf\xd3\xc1\xe5\xc5\xf9\xda\x9b\x86\x7f\xaf\xb2\xc2\x71\x81\x0b\x5f\xb5\x96\x03\x84\xd2\xd9\xa9\x6a\x83\x12\x13\xd3\x99\xbf\xfb\x1b\x2e\x60\xe7\x1b\xb9\xa6\x9b\xa4\xd0\x8c\x7b\x8c\x2a\x64\x9f\xf3\x82\xe7\xed\x8b\xbc\x7a\xff\x67\x57\x20\xac\xc3\xf4\xd1\x21\xdd\x35\xfe\x60\x49\x07\x27\x44\x0d\x26\xd3\x86\xbc\x00\x1a\xdb\xbc\x19\xcb\xda\x70\x0a\x0f\xe7\xc6\x6e\xa5\xa2\x9d\x19\x40\x96\x77\x76\x07\xae\x23\xad\x7a\x16\x10\x19\xc4\xdd\x36\xe7\x44\x6a\x59\x83\x1d\xcf\x4f\x46\x68\x12\x59\x35\x14\x9a\x1b\xb2\x19\x79\x68\xe7\x61\xcf\x19\x88\xf2\xc6\x44\x20\x36\xd9\xa7\x57\xc4\x96\xb1\xd3\x59\xe1\x1b\x5f\x26\x6f\x6b\xc8\x7d\x79\xdb\xfd\x91\x8d\x72\xc0\xd0\xb8\xa3\xc8\x78\xf8\xf7\xe3\x2f\xfe\x85\xf0\x23\x0c\xf2\x07\x38\x5b\x39\x6d\x0f\x4e\x80\xd2\x46\xae\xb0\xe3\xa1\x89\x1c\xaf\x03\x0e\x85\x42\xeb\x76\x68\x25\x23\xe6\x13\x55\x76\xff\x2d\xa3\x25\x64\x66\x09\x3d\x5c\x5a\xf2\xf1\xfb\x82\x4c\xdc\xe2\x5f\x5c\xbd\xb7\xf7\x67\xe4\x42\x36\xa3\x96\xf0\xf0\x1a\xff\x9c\xef\xce\x97\x00\xaf\x36\x39\xae\x26\xef\x09\xce\x0f\xb9\xf6\xd1\xfa\x21\xec\xe7\x1c\x50\x95\x38\xa7\xfc\x00\xef\x7e\x3a\x85\x43\xdc\x35\x69\xc8\xac\x2d\x69\xf4\x60\xb0\x48\xf9\xd3\xd0\x46\x73\x3c\x95\x77\x63\xbe\x55\xc5\x21\xa1\x84\x93\x10\x89\x99\xf5\x1d\xa6\x0f\x10\x36\xab\x2c\x7d\x06\xc3\x45\xb9\x02\xcc\x66\x99\x33\x3f\xfb\x0a\x26\x88\xa6\xc5\x48\xca\x03\x3a\xd4\x15\x8d\xb2\x87\x6f\x6e\x4b\x01\x96\xbd\x47\xac\xa9\x05\x54\xf0\xb2\x99\xd1\x4c\x85\x5d\x61\xcc\xd1\xe4\x3a\xd8\x9b\xcc\xf4\xef\xb2\xff\x16\x9b\x06\x92\x7d\x64\x39\x16\x42\x5f\x0a\xd8\x9a\xc5\x4c\x60\x11\x4e\x1f\xfe\xcf\xa8\x7c\x19\x0f\x17\xac\xbf\x66\xc1\xd8\x6f\xbc\x50\x83\x30\xd4\x7e\xbc\xb8\x96\xd1\x9d\xd7\x65\x1b\x21\x8f\xcc\xb4\xd8\x5a\x86\x82\x5d\xf9\x0a\x54\xa7\x46\x96\xf7\xcf\xf8\x26\x8b\x44\x33\x30\x84\x9a\x7d\xc2\xb2\x06\xee\x9e\xdc\xe0\xb6\x04\x46\xbd\xba\x49\x91\x75\xa5\x99\x2c\xe4\x0f\xf0\x2d\x6d\x63\x75\xc3\x43\xb6\x84\x2c\x7b\x44\xe6\x8f\xb8\xd7\x9a\x66\x48\x90\x91\xe4\x71\xc3\x46\x5b\x31\x99\x5c\x24\x2d\xfa\xf2\xaf\xd3\x75\x79\x05\x6d\x10\xfa\x9e\x39\x38\x54\xb7\x7c\xbc\xdd\x06\x21\xb8\xd8\x17\x1e\x83\x5b\x23\x30\x64\x8b\x4f\xf2\x06\x4a\x20\x61\xe8\x15\x7e\x0b\xeb\xb3\x4e\x74\x55\x4b\x0b\x06\x76\x20\x51\x5c\x92\x64\xfa\x2b\xd9\x22\x27\x5c\x94\x81\xe4\xb0\xea\xf0\x1e\x40\xa7\x93\xa0\xa6\x18\x6d\xfd\xac\xa9\x0b\xb4\xaa\x4b\xe3\x1c\x42\x3a\x84\x9b\xe7\xd2\x6f\xb0\x9b\xc3\xd7\x8e\x77\x25\xc8\x22\xd8\x8a\xe6\x95\x16\x72\xaf\x27\x60\x6c\x93\x86\xd0\xa0\x7e\xc6\xaa\x7c\x30\x5d\x97\xc8\x9a\xfa\x12\x47\x29\xe6\x76\x4a\x9b\x3a\x8b\x93\xd9\x33\xa9\x31\x5a\xf8\x64\xbf\x1b\x2c\x6f\xe9\x0d\xe4\x17\xb9\x8d\x12\x18\x03\x86\x77\xb6\x43\x42\x62\x6d\x0c\x76\x7b\x91\xff\x3a\xe3\x8e\x51\x7d\x42\x8c\x62\x27\xce\xd8\xcb\x33\xf2\xc6\xd3\x7e\xd1\x10\xa9\x07\xb3\xc7\x37\x57\x5a\x6d\xb7\x7c\xd5\x33\xb3\x8b\xb6\x15\x67\xc0\xea\xee\x23\xe6\x60\xa1\x9b\x2c\xee\xec\xb5\x48\xb9\xfc\xde\x96\x6e\xf1\x04\x8b\x16\x4c\xbc\xfe\xd3\xbe\x18\x8f\x00\x34\xe1\xbd\xd4\x4c\x19\x20\x90\xae\xc6\x83\x3e\x7b\xaf\xff\x1c\x26\x23\x9a\x1a\x3c\x96\x58\x3e\xd7\xbb\x07\x9f\x74\x1b\x95\x9c\xa7\xa9\x54\x4f\xba\xd8\x7f\xa0\xd4\xc9\xd1\x9f\x08\x26\xb0\x15\xf8\x18\x6d\xad\xac\x06\x99\x4a\x82\x61\x13\xc1\x5e\x7f\x4b\x15\xb7\x78\x01\x0f\xeb\x2a\xc9\x5d\xbc\xd2\xbd\x07\x54\x1f\x58\x73\x89\x60\x3d\x07\x64\x23\x77\xf5\xd8\xdf\xe0\xff\x07\x4a\x55\xf2\x33\x50\x84\x20\xa4\x9d\x03\x5b\x7a\x67\x39\xca\x97\x9d\x88\x13\xf5\xdb\xb7\x6c\x27\x5c\x58\x6c\x13\xab\x92\x6c\xfe\xfc\xd1\xc2\xa5\x77\x0a\x28\x55\xe7\x41\x01\x05\xbb\x82\x4e\x6b\x3d\x5c\xcf\x41\x93\x10\x67\x0d\x19\x5b\xdc\x9d\x14\xb0\xa7\x5a\x9e\x78\x7b\xb4\x71\x74\x27\x7d\x9d\xdd\xf9\x67\xf1\x6d\xa6\x2e\x27\xad\x3a\x6b\xa7\x84\x1d\x37\x76\x43\x9c\x4e\x0d\x8c\x23\xf7\x67\x02\xc5\x8e\x2a\x44\x75\xd5\x3a\xd2\x2d\x7d\xbc\x6a\x27\xed\x7d\xde\xf0\x54\x47\x98\xec\x87\x8c\xfd\x8e\xeb\x53\x09\x04\xcb\x76\x8e\x44\x29\xac\xcc\xde\xf9\x0c\x6d\x76\x59\x82\xb2\x79\x73\x8a\x98\x66\x43\xd0\xb7\x32\x84\x4a\x4e\x9c\x10\x74\xa6\xae\x88\xa4\x7e\x63\x22\x9a\x61\xcc\xa1\x4c\x5f\xe1\x7a\x12\x92\xf4\x18\xe5\xc8\x36\xdf\xdb\x57\x36\xea\xaa\xcc\x5f\xcd\x8b\xb7\x73\xcf\x3c\x5c\xda\xdd\x94\xc9\x51\xf9\x0d\xf5\xdb\x6e\x30\x7c\x9e\xd6\xae\xc8\x16\xb8\xd0\xfc\x3c\x1a\x23\x66\xed\x87\xc6\x99\xb4\x45\x68\x17\x43\x3c\x5b\xf8\x81\xb0\x62\xdf\xbc\x63\xc6\xdc\xb1\x5e\x2f\xd6\xc9\x66\x4d\x38\x02\x83\xf7\xc6\x12\xd7\x44\x2c\xa3\x5d\x68\x5b\x94\xc8\x99\x45\x5e\xbd\x86\xd6\x1d\x7c\x21\xf6\xd0\x8e\x31\xc2\xd0\x12\x85\x90\xdb\x5b\x9c\x6e\xab\x46\x8f\xb1\x53\xea\x76\xb4\xfc\x1a\x6d\x1e\xc8\x6e\x0a\x9d\x12\x72\x92\xac\x29\x93\xfb\xcb\x10\x4d\x8c\xcb\xc2\x54\xe2\x62\x4c\x1b\x07\x59\xce\x58\x96\xf6\x5f\xbf\x92\xe2\xd0\xc9\x12\x19\x60\xb3\xda\x39\xef\xe3\x91\xb8\x35\xa7\xd8\x71\xe6\x76\x77\x7c\xef\xb0\x8f\xc5\xd2\xde\x2a\x3a\x29\x03\xce\x11\xf2\xbe\x13\x1d\x24\x35\x08\x56\x32\x17\x25\x79\x59\x11\x2d\x7e\xfb\x2b\x79\xbf\xf4\xc1\xd9\x6b\x15\xdd\xd9\x6a\xd3\x54\x4c\x53\xf4\xac\xdd\x1b\xb3\x9c\x2a\x15\x14\xb2\xb3\xc4\x04\x74\xae\x5e\x27\x24\x3f\x6f\xbc\xba\x3c\xdc\xb2\x56\xf4\xe0\xa8\x4b\x61\x8d\x55\x0c\xab\x73\x80\x8b\x99\x72\x75\xd6\x7a\x48\x11\xdc\xe0\x18\x4b\xf2\x82\x4b\xb1\xb1\x19\xe7\xa3\x84\x1c\x33\x1c\x1a\xc4\xb3\x8a\x4e\x0b\x98\xc5\x9a\x32\x78\xc9\x86\x2a\x6f\x7d\x59\x9d\x48\xdf\x86\x56\x86\x16\x19\x60\xbc\x66\xd2\x52\x08\x33\xbd\x3d\x81\xb9\xd8\xfe\xaa\x26\x61\x08\x62\xac\x9e\x03\x1c\x5e\x9f\x8f\xa0\xc5\xbc\xd5\xb2\xe3\xca\x66\xf2\xc3\x14\x2a\xd5\x15\xff\x41\x58\x94\xe9\xe0\x16\x67\x24\xc9\xee\x1a\xfe\xd3\xc9\x09\xa9\x31\x50\x3e\x84\xa5\x58\x24\x0f\x70\x75\xee\xcf\xf5\xba\xd0\x96\xc3\xbf\x53\xbc\x63\x53\x9e\x15\x7c\x6b\xf4\xa6\xe4\x03\xd8\xa5\x49\x05\x21\x99\x56\x7f\x1f\xf0\x10\x1e\x3a\xc8\x61\x65\x91\xd2\x98\xc7\x56\xaf\x33\x3f\x4c\x1d\xa2\xe8\xe1\x4d\xf3\x60\x5e\x92\x0a\x4a\x3a\x1c\xe8\xff\x32\xc4\x3c\x1b\x00\x27\x97\xe4\xcb\x60\x5b\x3a\xa9\x3e\x8d\xe2\x43\x92\xeb\xb0\x90\x10\x2a\x8e\xff\x93\xf5\x68\x09\x08\x36\x0f\x46\x25\xa0\x95\x4d\xb4\x74\x17\xe5\x50\xbf\x8f\xde\x5e\xba\x39\x6b\xb9\x7a\x77\xbe\xd2\xfa\x3c\x41\xd2\xe5\x9d\x19\xde\xfe\xa1\xa8\x9a\x3d\x12\xc7\x85\x73\x27\xe6\xdb\x70\x01\xe3\x84\x93\x49\x2e\xd9\xaa\x83\xf4\x3b\x0f\xa5\x98\xb8\x9b\xc5\xac\xc8\x26\xcb\x1b\x57\x45\x99\x5c\xe6\x44\x1f\xa8\x40\xb0\x32\x1c\x16\x9a\x83\x77\x71\x4b\xd7\x89\x0d\x9b\x62\x14\xa3\x14\xb9\xa9\xc6\x57\xfb\xe1\xe3\x28\x6a\x30\xfa\x1a\xec\xea\xe9\xc5\x42\x80\xa9\x95\x3d\x3c\xf9\x83\x8d\x55\xcd\xd7\xfc\x64\x7f\xaf\x0a\x03\x10\x14\xa9\x86\xca\x5b\x3d\xb4\x72\x4d\xfe\xeb\xda\x59\x01\x78\x59\x0d\x0b\x5e\x08\xb6\xc8\x5e\xfd\xc7\x41\x27\xd3\x99\xe1\x0e\xa5\x0c\x44\xea\x61\xfe\xbe\x5d\x86\x15\xa5\xdd\x3b\x28\x49\xf3\x30\x3e\x2d\xb3\x7c\xcd\x70\xd0\x20\xf6\x79\xb1\x2d\xd0\xb2\xd7\x85\x95\x92\x77\x20\xfe\x2f\x21\x45\x03\x9f\x4e\xbc\x0c\xab\xb8\x92\xf5\x07\x76\x2b\x51\x90\xe2\xed\xc9\x69\x93\x34\x05\xed\x40\x65\xb4\x32\x6a\xb5\x1d\x2d\xf0\x97\xe7\x81\x9a\x20\x91\x6e\x81\x3e\x24\x25\x13\x06\x14\x67\xad\xbb\x92\x8d\x3d\xbd\x01\xf6\xa2\x4b\x54\x39\x0e\x74\x73\x1e\xe9\xd7\x9e\xea\x43\xbe\x99\x83\x34\x73\xf0\xce\x04\x67\xf2\x24\x09\x57\xf4\xab\xd4\x42\x98\x11\x3e\x29\x05\x66\x2a\x5c\xbc\x8d\xca\x49\xb7\x5b\xdd\x97\xe6\x19\x3b\x59\xa3\x07\x4a\x74\x2d\x01\x05\xde\x7a\x76\x0b\x46\x77\x61\xb4\x72\xe2\x44\x2f\x4d\xf0\xe1\xb1\x09\x15\x49\xb8\x30\xfa\x25\x2d\x1f\xc3\x65\x77\x0a\x43\xd9\x63\x34\xf9\x0a\xf9\xfe\x44\x8c\x98\xc1\xf6\x53\xfd\xb5\x9b\xbd\x49\x97\x9b\x37\x3b\x29\x2a\xeb\xb7\x5c\x8b\xc7\xee\x52\x0c\xc1\xb7\x45\xd8\x8b\xea\x65\xec\xe9\x01\x36\x31\xf0\x50\xf1\x21\x33\x18\x12\x72\x81\x0d\xb2\xad\x68\xf4\x91\x33\x16\x99\x22\x3b\x43\x3e\x7b\xac\x66\x14\x1e\x0b\x32\xbc\x17\x69\xe2\xce\xbf\x3f\x1e\x43\x7b\xc5\x42\xc5\x04\xa6\x07\x61\x2f\x5e\x75\x75\x38\x8d\xa1\x08\x3b\x6b\x00\x49\xdc\x9b\xf8\x17\xd6\xb6\x95\x4f\x6e\x5b\xb0\xba\x83\x90\x5b\x80\x7c\xfe\xea\x95\x3a\x00\xef\xcd\x75\xa1\x0e\x54\xad\x71\xee\x29\x28\xa2\x36\x1f\x5f\x82\xac\xac\x3f\x16\xc9\x86\x82\x10\x1c\xc4\x11\x82\xa6\x18\xce\x2e\x73\x85\xa2\x9b\x7d\xf6\x83\x92\xa0\x4d\xb5\x4d\x5c\xcc\xe7\x31\x78\x56\xa4\xfb\x59\x59\xcc\x1b\x25\x2a\xcb\x4c\xcf\x32\x52\x75\x00\x80\x12\xff\x49\x82\xe2\xa1\xed\xb9\xe2\xb3\x65\x25\xec\xc1\x9e\x5e\x2f\xf0\x0e\x05\x6d\x6a\x65\x29\x57\xcb\x0f\x6b\x00\x75\xf1\x3d\x64\x66\x7c\x87\x15\xa5\x60\x8f\xa7\xd7\x74\x20\xe1\x00\xf9\x2d\x74\x13\x92\x9b\x6f\xe1\x80\xed\x72\xa7\x92\x99\x04\x4b\x08\x1c\x7a\xbd\xe1\x2d\x5b\xcc\x38\x1a\x21\x11\x57\x15\x53\x7a\xb3\xf1\xa9\xe7\x2b\xb2\xb7\x6b\x2e\x23\xea\x50\x9b\xe5\x07\x1a\x00\x1d\x1e\x71\xf7\xd3\x41\xb6\xd1\x1d\x2d\x77\xd2\xe6\xbb\x87\xf5\xfd\xe2\x59\xb1\xf2\x3c\x1a\xb0\x0e\x3b\xda\x6c\x36\x0f\x67\xd7\x70\x50\x9f\xa9\x37\x92\x4a\xeb\x45\xcf\xe4\x2d\x28\xaa\x29\x40\x6f\x02\x6c\x20\x61\x69\xad\x55\xf3\xab\x6b\x15\xce\x5f\x36\xcb\x51\x0c\xaa\x16\x67\xbf\xc9\x9f\x28\x5f\xd6\xf2\xf9\x21\xd0\x7c\xcf\xde\x96\x33\x18\x8a\x47\x71\x77\x4e\x15\x00\x94\x80\x00\x2e\xfd\xbd\x7f\x1f\x8b\xa5\xea\xe8\xbd\xba\xbc\x5a\x70\x8d\xea\xb1\x2e\x0b\x9e\x6d\xfa\x2a\x82\x21\x30\xc9\xdf\xde\x84\xd0\xf4\xb4\xd9\x53\xca\xf9\x67\x00\xdf\x12\xcb\xb6\xc5\xfb\x4a\xac\x8f\x8d\xe5\x9c\xda\x57\x1a\xb9\xc9\x99\xbd\x1d\x60\x4b\x37\x3c\x1c\x34\x4b\x1c\xe7\xd5\x8b\x38\x9d\x72\x33\x46\xfc\x44\x5f\xf1\x33\x7a\x41\x67\xd6\x0d\xa1\x9b\x57\x6a\xd7\x11\x00\xfd\x89\x59\x59\x08\xfd\x6d\x49\x02\x5b\x3b\xdc\x4f\x0f\x93\xf4\xd4\x3c\x40\xd0\x23\x90\x71\x2b\xd1\xa9\x9b\x75\x31\x94\x1a\x50\x9a\x25\xf4\x20\xc7\x4a\xc6\xeb\xe2\x37\x15\xb6\x5d\x2c\x55\x23\x32\xe2\x52\x49\x68\xfc\x63\x30\x04\x2e\xab\x2c\xd1\x2f\xe4\xa8\xda\x9d\xac\x05\x5a\x7b\x3f\x50\x7f\x33\x4a\x3b\x62\x02\x6e\xed\x4a\xf0\x28\x0e\xde\x70\x66\x1f\xeb\x57\x0d\xc5\x3b\x97\xcb\xe4\x12\x69\x49\xc1\xae\xc6\x7b\xcf\x70\x60\xd6\xc6\xc8\xb3\x03\x51\xec\x15\x06\xff\xa2\xef\x1a\x0a\x95\x4e\x08\x8b\xaf\x41\xa4\x77\x24\x6d\x0b\x97\x31\x87\x83\xb3\x5d\x25\x7f\x17\x6f\xf8\xcf\xbb\x2d\xe5\x6e\xda\x17\xb3\x22\x22\x09\xbd\x00\xe2\x4e\xfe\x3d\xd8\x91\x80\x73\xee\x3a\x20\x5b\x01\x06\xf9\x86\xea\x5d\xf3\x36\xb7\x16\x4e\xb6\x58\xee\xee\x6b\x57\xf7\x91\xf2\x7d\x47\x95\xc5\x5a\x64\x04\x43\x13\x0d\x8a\xd3\xdf\xad\x54\x64\x1f\x36\xfa\x30\xd5\x3a\x78\x19\x9d\x21\xd0\x8b\x84\x4a\xe7\x38\x99\x53\x61\x04\x00\xbe\x80\x76\x37\xc3\x88\xcb\x9a\x77\xe3\x74\x6a\xdd\xf2\x6f\xd1\x33\x90\xa3\xbb\xf6\xf0\xc3\x74\x00\x1b\xa9\x6a\x28\x2c\xa8\x42\xd7\xc2\x79\xc9\xb1\xfe\x16\x2b\x30\x29\xa2\x0d\x8d\xcd\xb6\x79\x33\xe1\x9b\x2e\x6a\x04\xd7\x72\xc4\x00\x83\x66\x9c\x0a\xb4\x2e\x3b\xb3\x8d\x45\x86\xa9\xe0\x86\xb8\x5b\x92\x98\x9a\x01\xf0\x9d\xaa\xb3\x04\x4d\x93\x0b\xd5\xf5\x82\xcf\x3d\x8b\xb7\xdb\x9d\x08\x01\xa3\x27\xeb\xba\xcc\x80\x01\x87\x90\x8e\xc7\x04\xef\x33\xb3\x59\x5e\xdc\x3e\x52\x43\x2d\x76\x19\xda\x84\x20\xab\x64\xca\x69\x32\x45\x82\x2f\xef\x1e\x24\x3c\x9f\xd8\x2d\x49\x48\x47\xb5\x75\xd2\xea\xe2\x03\x2d\x60\x5d\xf1\x0d\x3b\x0e\xb0\x33\x92\x05\xb2\x0f\xef\x7a\xc6\xc4\x20\x50\x83\x10\x06\xa8\x91\xa4\x25\x57\x2a\xdd\xa2\x6b\x46\xad\xd6\xfd\x4e\x28\xa8\x1c\x9e\x89\x6c\xaa\x6a\xe7\x09\x68\x26\xea\xf3\xa2\xca\xa4\x3e\xd3\xf4\xb5\x51\x88\x38\xbb\xb9\x57\x5c\x6f\x4b\x07\x8b\x97\x55\x25\xe0\xa2\xfc\xc7\xed\xff\x8d\x66\x08\x24\x1f\xf5\x9f\x69\xb7\xb7\x05\x69\xa7\xa6\x9b\xdc\x62\xa2\x17\x38\x10\x95\xd6\x6c\xf3\x08\xca\x24\x4a\x24\x56\x80\xf6\x1d\xb4\x06\xb4\x01\xca\xfb\x9f\xb6\x04\xf4\x72\xed\x5f\xfa\xb3\x7c\x5a\xfb\xdc\x1b\xc2\xd0\x15\x48\xbc\x1c\x5b\xe7\x67\x68\x7b\x79\x75\x80\x6b\x27\xd7\x65\x80\xd9\xbd\x26\x43\x6d\x6b\xfa\xfd\x85\x5a\x1a\x35\x3c\xbf\x44\xea\x75\x84\x51\x0a\x8d\x90\xf4\xa4\x38\x33\x02\x15\x12\x14\xd6\x4e\xa4\x72\x4d\xf2\xf6\xa8\x31\x5a\x23\xf1\x68\xa0\x5c\x9c\x3e\x4b\x1a\xe9\x25\x77\x0d\xbc\x26\xad\x2f\x11\x25\x27\x0d\x8a\x22\x66\x96\xf8\xd7\xa8\xa5\x8a\x07\x42\x09\x42\x8f\x9e\x5d\x56\x7f\x48\x57\x1e\x04\xe2\x44\xae\x82\xd7\xb8\x0d\x36\xf8\xc0\x2a\xca\x5a\xce\x11\x8c\x1b\x12\x35\x8f\x81\x44\x47\x92\x86\x4c\x06\xce\x42\x5c\xcf\xd5\xad\x62\xc1\x00\x7f\xec\xa4\x92\x71\xb0\xd3\x65\xfc\x8d\x63\x3e\x3b\xf1\xb8\x53\xfe\x08\xbe\xb5\x6a\x8a\x85\x7d\xae\x8b\xcb\xdb\x31\x75\xd5\x36\xca\xea\x0a\x92\x0a\x76\xa0\xf8\x04\xfa\x9d\x69\x84\x51\xe0\x66\x75\x05\x46\x55\xa7\xc4\xe2\x2b\x8b\x08\xf7\x5f\x2c\x42\x7f\x50\x23\xd5\xd2\x8f\xbd\x46\xb3\x6d\x3f\xc4\x7e\xd0\x2b\xc4\xa3\x1c\xc7\x2b\xa8\x75\xa4\xcb\x3d\x59\x5e\x2e\x68\x9b\x6b\x1a\xfa\xd9\xb9\xae\x41\x33\x7f\xd2\x0b\x6e\x87\xc6\x0e\x38\x5f\xb9\xea\x41\x2d\x91\x6a\x21\x46\xb3\x49\xda\xde\x88\x0f\xd5\xf6\x5b\x5b\xd0\x27\x41\xa1\xd9\xf1\x75\x40\xa8\x0c\x39\xa8\x13\x60\x25\x79\xa0\xae\xfd\x9c\xb1\x70\x9a\xab\x77\xa4\x5c\x5f\x79\xbc\xa0\x14\x01\xdb\x3a\x92\x65\x74\x03\x5a\xa9\xd6\xc5\x65\x3a\x7a\xe4\x14\xb0\x02\xf8\x2c\x60\x4f\x68\x76\x05\x57\x32\xef\x5e\x27\x88\x5e\x1d\x38\xe8\xc1\xc4\x91\x02\x8f\xc7\xa7\x69\xce\x27\x11\x00\x68\xcc\xaa\x51\x61\x7f\x51\x92\xa6\x3a\x0a\x74\xe3\xee\xbe\x3f\xd9\x3c\x9f\x84\x75\xd4\x9f\xba\xba\xd7\x3f\xcc\x0b\xd9\xc5\xec\x6e\xa4\x26\x63\xc2\xe1\x6e\x58\x9f\x8f\xea\x5c\x21\x33\x20\xd4\x10\xea\x3f\x7b\x5c\xd8\x25\xed\x34\xe9\xe4\xc7\x33\x20\x9d\xbe\x4d\xf7\x72\xf2\x0f\x0b\xf6\x8d\x6e\xf1\x00\x53\x89\xbe\x1b\x77\xa1\x53\x09\x33\x7a\xc5\xe7\x9d\x66\xe7\x42\x65\x17\x0e\xbd\xb7\x34\x95\x85\xde\xe5\x24\x46\x9c\xc3\xab\x40\x65\x02\x19\xe5\xcc\xb4\xdd\x4a\x1a\x8d\xcd\x42\x48\x79\x02\xc4\x01\xb2\x15\x36\x2c\x43\xda\xe5\xb1\xcd\x70\x1d\x44\xb6\xb7\xea\x61\x96\x24\xdb\xa8\x4b\xbf\x63\x3c\x90\x91\x6f\xe8\xe5\xf1\xb4\xa9\x19\x52\xe9\xb7\x4c\x15\xfc\x6c\x8b\xa1\x27\x17\xeb\x82\xda\x9e\xe2\x61\xbf\x7f\x1f\x5e\x7f\x33\x88\x83\x5e\xd0\xb1\xab\x27\x96\x42\x3a\x31\x79\xeb\x85\x78\x0b\x42\x6e\x3f\x85\xaa\x35\x5a\x59\xb2\xa3\xb8\x7b\x5c\xaf\x64\x5b\x70\x13\xd0\x78\x8f\x9a\x94\x37\xe5\x04\x05\xe4\x58\x4e\xbd\x02\x94\xb1\x23\xfd\xef\x51\x7e\x92\xc5\x0d\x7b\x97\xbc\xdc\x29\x34\xf2\x6f\xe6\x24\xa2\x64\x5b\x87\x37\xdd\xda\x55\xf8\xe0\x12\x3a\x51\x56\x8f\x9f\x27\xd2\x2f\x0d\x59\x1f\x0a\xe3\x0d\xf9\x12\x79\xd3\xf5\x42\xec\x74\x6b\x78\x85\xb8\xbb\x76\x84\x07\x6d\x08\xbb\x0d\x29\xae\xea\x7b\xad\xf8\x15\x14\xbe\xb6\xd1\x6c\x6e\x5d\x18\xa3\x8c\x2c\xf1\xac\x9e\x13\x0b\x24\xdb\x03\xc4\xa9\x88\xd2\x97\x17\x83\xc8\x63\xc9\x65\x6d\x0b\xcb\x54\x1a\x0f\xc2\x92\xa4\x35\xf2\xef\xb2\x6f\x4b\x23\xa7\x27\xc5\xbe\x34\xe4\xfa\xa2\xef\x92\x44\xef\xbc\x64\xde\xd6\xc9\x16\xf3\xf7\x30\xe4\x5f\xd9\x39\x0a\x93\x4f\x09\x6b\x60\x6a\x19\x0f\x00\x5a\xe6\x6d\xe3\xa5\xe4\xaf\x05\xe7\x31\x29\xa1\xc9\x3a\x90\xaf\x5a\xd4\x97\xa0\x13\xed\xf4\x80\xb5\xb5\xc4\xf0\xe1\x04\x43\xe8\x08\x89\x55\x0f\xca\xea\xaa\x2a\x4a\xc1\x06\x9d\x05\x3d\xbd\x53\x60\x8c\xaf\x4d\x0a\x66\xbc\x5d\xdd\x7b\x2e\x68\x7b\x36\x1a\xbc\x9d\x92\xe4\x4a\x43\x33\x41\x10\xc9\xd8\x89\xa9\xdf\xc1\x43\x74\x48\xfd\x3e\x00\x9c\x21\x84\x5d\xbb\xeb\x05\x4b\x44\x16\x67\xe7\xc5\xb4\xa1\xc3\x39\x17\xba\xbc\x29\x7c\x49\xc8\x68\xdd\x79\x4b\xf0\xfb\x1e\x04\x3e\xcd\x4c\x2c\x2b\xb7\x8a\x07\x16\x71\x08\xf6\x06\x23\x03\xa8\xda\x1c\x2a\x44\xfd\xf0\x4d\x11\xdb\xfc\x19\x02\x15\x86\x61\xaa\xa8\xb9\xb7\xab\x7d\x65\x3d\x72\xf4\xe8\x46\x79\x01\xf0\x43\x2b\xe1\x83\xe7\x90\xef\x9c\x3c\x90\x97\x98\xe1\x2f\x24\xf0\xa7\xf3\x8e\x9d\x29\x57\x90\x70\x6b\x22\x20\xae\x9d\xca\xf6\x12\xe7\x6a\xd5\x9b\x0d\x5d\x05\x5e\xe8\x3d\xac\xe2\xfd\x60\x7b\x93\x2d\x46\x64\x7b\x31\x1e\x49\x52\x39\xb6\x9f\xdf\x24\x0c\xbf\x83\xa7\xf1\x97\x07\xfb\xe5\xa6\x14\xe3\xe1\x44\xfa\x83\xfb\x22\x97\xbd\x83\x61\x13\x4f\xa7\x74\xf0\x88\x2e\x29\x80\x31\x7b\x24\x34\xc3\xc8\x46\xf7\x8b\xe8\x6f\x21\x24\xe1\x0a\x36\xb0\x9e\xd6\xed\xe1\x8c\xa8\xb9\x8e\x06\x09\x79\x78\xab\xc4\xb2\x07\x08\x58\xf2\x4d\x37\x7f\x23\x2f\x68\x89\xe0\x1d\xe0\x1a\xcd\xc8\x1a\xff\x4b\x66\xb5\x96\x7a\xb1\x4d\xf3\x68\xf6\x9d\xc3\x33\x02\xb4\xcf\x8d\x3d\x4f\x2a\x1f\xc1\x48\x06\x42\xd5\x6a\x83\x32\x13\x64\x05\x9b\xd7\xd1\xb2\x96\x9c\xc3\x20\xef\xf0\x0d\xd3\x49\xd0\x70\xb2\x7f\xbb\xa1\xc1\x60\x81\x24\x39\x6a\x62\xd9\x9f\x15\xcd\x38\x6d\x28\xd0\xab\x06\x65\xc2\x42\x9c\x8e\x5e\x6a\xc9\x8c\xf6\x90\x50\xfe\xb3\x30\xc5\x75\xbf\xaa\x25\x22\xf2\x99\x6b\xf8\xc2\x37\x64\x3d\x07\x04\x4f\xc1\x45\xf1\xed\x38\x19\xf0\x42\x95\xd2\x76\x80\xb6\xd9\x32\xe5\x10\x54\x6c\x94\xfd\xb8\x38\xbe\x1d\xa2\x64\xdf\x40\x44\x8b\x9b\x16\xb6\x74\xaf\x9f\xb8\xf2\xdb\x97\x3a\x89\xc7\x50\x0a\xd6\xc3\xb2\x2e\x7a\xa6\x50\x71\xdc\x54\x61\x3d\x2d\x83\xfb\x3e\x0e\xf9\xe6\x15\x1b\xf1\x8f\x20\x97\x02\xfa\x38\x25\x20\x62\x59\x21\x7b\xa7\x9b\xe9\x41\xa1\x0e\x21\xa1\x15\x4a\x4e\x12\xc5\x82\x86\xfb\x53\x26\x40\x1e\x15\xac\x31\xb1\xab\x68\x30\x63\x23\x9d\xb5\x44\x23\x6a\xf6\xcc\xea\x2a\x0b\xba\x12\x0d\x19\x46\xa9\xb5\xa3\xb4\x74\x01\x88\x92\x9c\xc8\x23\xca\x2c\x8e\xf2\x54\x1d\x2c\x03\x62\xf7\xa0\xfd\x6d\xf6\xa5\xc4\x2d\xc1\x75\x4c\xbb\x13\xf2\x3c\x38\x0d\xca\x63\xb5\xfd\x4f\x2e\x0e\x96\x31\x78\x42\x25\x52\x8a\x35\xa2\xef\xf2\xaa\x16\x0c\x1a\x61\x93\x6d\x31\xb2\xc7\xcd\x8e\xfd\xf3\xdb\x09\x32\x4b\xda\xe3\x7a\xa1\xa0\x56\x62\xf1\xd0\x27\x0c\xa8\x04\xac\x0c\x89\x4f\xc8\xbc\xbf\x3a\x8a\xc9\x72\x01\xe1\xfe\x67\x6f\x51\x9a\xc3\xc4\x3a\x77\x67\x53\x4c\xa3\xd0\x18\x34\xfb\x87\x2b\xf2\xee\xc0\xf3\x03\x8b\xe0\x3e\x63\x3f\xbb\xf3\xb5\x94\x0f\x83\x27\x5f\xcb\x93\x5b\x2b\x9f\x5d\x2c\x2f\x98\x32\x9a\xed\x40\x94\x26\xe3\xe3\x64\xc2\xde\xa8\x7d\x57\xd1\x5c\xa8\xd4\x1c\x4e\xef\x80\x18\xf8\x6e\x2d\x32\xe8\x04\x29\xf5\x05\x4d\x07\x71\xbb\x24\x01\x3c\x25\xe2\xf5\x52\xba\xdf\xbf\xb9\xe7\xaf\xd6\xbf\xdc\x64\xef\x89\xd7\x49\x01\x10\xc5\x35\x15\x86\xc4\x83\xea\x47\x31\xfc\xf9\x2d\x89\x12\x6c\x47\x4c\x42\x6a\x50\xfa\xc1\x50\x24\x04\x87\x42\xc7\x9d\x7e\xb4\xaa\x13\x78\x72\x1f\xd4\xcb\x74\x6d\x63\x79\x61\x72\x39\x0f\x2a\x56\x30\xee\xdf\x0a\x04\x5a\x96\xa8\x81\x21\x3a\x5e\x92\x37\x07\xb3\x6a\x0c\xd2\x15\x75\xcc\xc9\xbf\x72\xd9\xf2\x3b\xf9\x84\x8c\x26\x41\x17\xca\xf8\x62\x28\x33\x59\x6e\xf4\x2c\x97\x02\xff\xf6\xe1\xe7\x8c\xda\x4b\x4e\x16\x0b\xab\x88\xa7\xb3\x56\x3c\xdf\x9d\xb5\x27\xd2\xd6\x4f\x3b\x4a\x07\xec\xea\xe5\xbd\xa9\x00\x92\x52\xe7\x19\x56\x2f\x6e\xea\x63\xfd\x82\xd2\x66\xa4\xbb\x41\xbf\x8b\xae\xba\x28\xfe\x06\x04\x93\xe6\xd5\x22\xa3\xdc\xc1\xf4\x98\x36\xdb\x03\x64\x30\x6f\x41\x5d\x57\x32\xb9\xa2\xab\x92\x2d\xf1\x05\x57\x66\xbc\x56\x36\x48\x98\xd5\x0d\x33\x84\x70\x5b\x61\xaf\x63\x1b\x7c\x0b\x45\x14\xd9\xeb\xa0\xab\xe1\x05\xf0\xa2\x61\x21\x97\xe7\x27\xc0\x22\x40\xa3\x2c\x7d\x7d\x90\x1f\x7d\x17\x46\x21\x56\xde\x7d\xe2\xcb\x14\x2e\x0d\x30\xec\x5d\x35\x9a\xe1\x6b\x25\x04\x85\xde\x48\x65\xba\xe5\x0f\x30\xb3\x48\xd8\x4f\xa4\x4b\xb3\xba\xa1\x11\x15\x6b\x9c\x69\x5d\x08\x2a\x6b\x23\x0a\x40\x99\x70\xb1\x11\x63\xdc\x45\xc9\x47\x40\x8a\x93\x80\x2e\x11\xc4\x8a\x2c\x4b\xca\x9d\xb7\x8f\xd5\xd2\x1b\xda\x35\x0e\x86\x99\xcc\x37\x7e\x02\x65\x57\x36\x70\x57\xb4\x7e\xf2\xb4\x3b\x64\x47\x53\xe5\x10\x8d\xa1\xc1\xe9\x3d\x26\x29\x7f\x72\x2a\x88\x69\x41\x57\x9e\x64\xb1\x4c\x01\x45\x7d\x58\x10\xeb\x6a\x32\x0f\x69\x14\x64\x58\xa2\x13\x66\xf3\x42\xd7\x9b\xb7\x73\x53\x1c\xd1\x6d\x61\xa9\xd0\xd5\xc8\xda\x93\xf9\x84\x5f\xa2\xc6\x0f\x44\xdc\xb5\xa3\x78\xc0\x02\xe7\xd0\x64\xf5\xf3\x3a\x5b\x7a\x38\x21\xe2\xf9\x4d\xba\x9a\x30\xca\xb7\x23\x33\x77\x95\xe7\x18\x7a\xa8\x97\x8d\x92\x78\x80\x1f\x93\x5d\x06\xf2\xf0\x4c\xf9\x0d\xcd\xbc\x63\xd8\xe1\x68\xde\x7a\xe4\x94\x3e\xdc\xc4\x25\x59\xb5\x8b\x17\x99\x3a\x39\x38\xb2\xf6\x9a\x2e\x96\x3f\x78\x33\x07\x42\xb0\xcd\x2e\x2e\x9c\x73\x81\x7a\xad\xa9\x52\x31\xa1\x12\x0b\xe6\x3d\x8b\x70\xd4\xd6\xb1\x0d\x50\x4e\x83\x46\xe2\x5c\x26\x42\x49\x93\xa5\xc7\xc1\x68\x01\x5a\x64\xa0\xa2\x7f\x82\xe8\x3a\xea\x01\xf6\xd9\x30\xdb\xc9\x73\x64\x53\x1c\xf6\x5b\x9d\x1d\xc6\xd9\xfc\x2e\x64\x73\xed\x04\x78\x47\x8d\x93\xb3\x52\xbc\x4d\xe4\xd6\x35\x96\x74\xcf\x15\x0e\xa6\xc8\x50\x12\x14\xbc\x81\xf2\xb1\xd5\x67\x87\xf1\x63\x4f\x84\x9d\x2a\xd3\x67\x70\x2a\xca\x4c\xcd\xd2\xd9\x65\x33\x8d\x0f\x01\x4e\x45\xc9\x4b\xb7\x7a\x80\x29\x3b\x71\x9e\x94\x83\xb2\x60\x90\x1b\x5d\x41\x76\xd6\xe5\x62\x03\x28\x6a\x2d\x4d\x03\xbd\x7a\xb2\x9b\x6a\x36\x41\x31\x70\xe3\x32\xa9\xc0\xc6\x7b\x71\xbd\xa9\x73\x58\x21\x26\x1d\x8a\xfa\xd8\xa9\x33\x5f\xbd\x44\x86\xaa\x64\xed\xcf\x23\xcb\x19\x03\x58\x9c\xe2\xfd\x1b\x2a\x12\xe0\xf6\xf6\xa1\x3c\x0d\xdd\x5d\x95\x94\xef\xcb\xf2\x6f\xec\xc9\xcb\x19\x5e\xe2\xec\x10\xd8\x3c\x73\x34\x80\x47\xad\x93\x41\x45\x96\x71\x43\x1f\x71\x5d\x47\xa3\x43\xa4\x4f\x1b\x95\x61\x6d\x60\xe5\xc8\x1e\xa8\xe6\x9c\x0f\xb6\xdc\x80\x77\x2d\xb9\xa1\x77\x0c\xb8\x04\xcd\x03\x1e\xa1\xba\x0b\x0f\x43\x39\x0e\x9b\x5f\x51\x3c\x9d\xb4\x8b\x0b\x21\x94\x9c\xcd\x09\x97\xc5\xdc\x66\xe3\xc1\x9c\x9d\xcd\x8f\x62\x41\x2b\x9e\xcd\x39\x6c\x70\x78\x01\x3d\x7f\x35\xda\x24\x0f\x62\x94\xbc\x17\x48\x89\x46\xe6\x64\x5b\xeb\x78\x34\x87\x1a\xeb\x8b\x5f\x2c\x0b\x68\x91\xa4\x9d\xd5\xaf\xcd\x16\x7f\xf3\x4d\xa1\x6e\xbe\x68\xbb\x03\xd9\x60\xc5\x89\xa1\xa1\xd3\x28\xbb\xe8\xa0\xbc\xfd\xac\xc7\xfa\x92\x70\xc5\xbb\xf4\x83\xa7\x74\x34\x3d\x79\x58\x50\xfb\x78\x05\x4d\xcc\x12\x3e\x51\x94\x15\xfb\xf3\xcb\xde\x1e\x6b\x20\x7c\x00\x94\x5b\x0a\x01\xe5\x09\x91\x42\x1d\x29\xed\xe5\x23\xcf\x8e\x32\xa8\x61\x6f\xde\x51\xf5\xdd\xf6\xd0\x6a\xf2\x0d\x75\x22\x9c\x8d\x17\x77\x59\xbd\x17\x69\xf7\x7a\xac\xf9\xb6\xef\xe0\x00\xa5\x4f\x97\xb2\x12\xb6\x57\xb0\xe5\x5c\xd9\xd3\xa6\xca\xfe\xf9\xd5\xc7\x67\x2c\xf1\x3b\x5b\xa2\x82\x56\x30\xbb\x4c\x9c\x5e\xc9\x1c\x9d\x8e\x35\x19\xe5\xce\xbe\xf0\x49\x62\xa4\x83\xbb\x26\xc7\xed\x83\x97\xc2\xc7\xb5\x74\x51\xe6\xa2\xc1\xb4\x30\xb5\xbb\x7e\xc7\xe1\x85\x1f\xf1\x55\x1b\xe2\x3e\x92\xaa\x36\xf6\xcb\x3d\x3b\x67\x34\xcd\x4e\x4e\x99\x46\x27\xea\x6d\xd7\xd5\x6e\xb5\xb2\x0f\x58\xb0\x8a\xab\xdb\xcc\x8b\x83\x7e\x1e\x24\x31\xa0\x52\x5d\x28\xd1\xa5\xd0\x0a\xc2\x6f\x2a\xe7\xaf\x1a\x96\xb0\xc9\x8f\x6f\xf1\x1c\x40\xcc\x42\x39\x94\x59\x36\xdf\xf3\x23\x13\x27\xc7\xdb\x53\x3d\x45\xbc\x4c\x31\x0c\xeb\x95\x6e\x2c\x8c\x45\x90\x48\x50\x29\xda\xd9\x56\x2a\xfd\x7b\xdc\x36\x8d\x72\x82\xa7\x21\x6f\x6f\xb0\xa0\x61\xb5\x08\xf1\xe5\x4a\x06\x2a\x18\xb3\x23\x7f\x91\x8d\x3e\x59\x05\xfa\x3a\x1d\xda\x83\xe2\x8a\x34\x47\xb4\x02\x03\xbd\xa9\xf7\x6b\x61\x55\x57\x9a\xe0\x35\xbb\x18\xe5\x4a\x6c\x37\x51\x8b\x0e\x63\x20\xac\x79\x07\xbe\x9e\x32\x91\xb7\xab\xcf\xb6\x61\x96\x6b\xf9\x70\xe5\xcb\x10\x0e\x3d\x7a\x22\x89\xc4\x25\xe4\xb3\x9b\xff\xfd\x4b\xdf\xd8\xd5\xc9\x60\xdd\x09\x28\xad\x9c\x06\x00\xf6\x1d\x52\x5b\xe0\x05\x1f\x8a\x78\x68\x35\xfb\x03\x9c\x64\xa4\xd6\x2e\x11\xa3\x03\x7f\xa8\x76\x6b\x9d\xa5\x78\xf5\x35\x8d\x2a\x30\x2e\x91\x0d\xc5\x41\xea\x16\xc5\x45\xa3\x67\xa9\xf5\xe3\x1a\x8a\x4d\xb1\x12\x6c\x30\x0b\x65\xe9\x1c\xfc\x88\xfe\xcb\x92\x00\x0f\xc0\x65\xcd\xa0\x0d\x6b\xde\xea\xb5\xc3\x00\x55\x8a\x49\x2e\xbe\x37\x4f\x7f\xe7\x0e\x39\x66\x97\x13\xff\x4d\xcd\x3a\x99\xe9\xb7\x49\x45\xdb\xc9\xee\x2e\x2d\x71\x23\x63\x6a\x8a\xd4\xf9\xa4\x0e\xe5\xc1\x75\x0e\xf4\x5a\xb3\x37\x41\x45\x0c\xe2\x61\x0f\xca\x62\xfa\x8c\xc8\x35\x50\x46\x90\x00\x9e\x9d\x9f\x19\x06\x7b\x1e\xda\x7f\x96\x4c\x79\x4f\xa7\xc4\x34\x88\x5c\x15\x26\x44\x73\xac\xeb\xf6\x19\x98\xc6\x99\x06\x13\xb0\x0c\xee\xea\x8f\x5b\x0e\x08\x2c\x9a\xdd\xda\xe2\x13\xc7\x54\x35\xe1\xd9\xb1\xe4\x7e\x40\x52\x21\x97\x18\x2f\xa3\x47\x31\x07\x52\x5c\x67\x04\x7d\xda\x73\x6b\xee\x7e\x0c\xf4\xba\x71\x41\x9b\x87\xdd\x67\xf8\x41\xa9\xd5\xb4\x4b\x1d\x72\xa2\x7e\xd8\xe5\xb0\x8e\x62\x3d\x60\x41\x8e\x1a\xf5\x52\xd8\x86\xf1\x61\xd7\x31\x7b\x98\xe7\x31\x93\x4c\xb6\x1c\x96\xd3\xa8\xe7\x16\xfd\xcb\xd9\xb4\xff\xca\x4d\x1e\xf1\xe6\x31\xa1\x06\xdf\x6e\x08\x68\xb4\xcb\xab\x6e\x36\x8d\xe4\x70\xf6\xcc\x3b\x3a\x99\xad\x05\x3e\x2a\x08\xfb\xb8\x42\x1c\x33\x15\xc1\x33\x8f\xd6\xc8\xf7\x74\x41\x37\x31\xcb\xa3\x76\xab\x08\xcc\x98\xb3\x32\x66\x4b\x99\xf7\xe6\x56\xf4\x8b\xfd\xdf\xad\xfc\x15\xdb\x6a\x83\xb5\xd3\x38\xd1\xef\xe0\x95\xb2\x66\xb7\xb6\x3b\xf2\x27\x3e\x8a\x00\x6d\xee\xa3\x93\xc4\x78\x26\x74\x8b\xf2\xe5\x8f\xb9\x44\x1d\x5f\x40\xa0\x30\xdc\x89\xf2\x83\xc7\xc4\xea\x12\xf1\xf5\x69\xc8\xb5\x80\xed\x41\xd9\x00\x66\x13\x77\x5f\x51\x5c\xb9\x0b\x86\x6f\xdd\xde\xc3\xa9\x49\xa2\x6d\x1a\x14\x28\x28\x58\x36\xba\x82\x50\x1a\x45\x78\xe6\xcd\x21\x7a\x09\x71\xa4\x28\x36\x75\x7f\x47\x7f\x49\x8e\x40\x45\xba\x76\x39\xd7\xab\x52\x4e\xd1\xe4\x09\x11\xb3\x2b\xe8\x77\xa2\x3f\xe5\x62\x1f\xbc\xb5\x9c\xb1\xf9\x3c\xba\x5e\x59\xbc\x7f\xb3\x43\xe8\xd4\x11\x34\x3c\x13\x71\xcf\x0c\x66\x80\x56\xc4\xbd\xa1\xf9\xf9\x74\x51\xea\x5a\x59\x98\x53\x29\x28\x43\x19\x5e\xf8\x1c\x3f\xae\x57\xfc\x8c\x44\x23\x2e\x6c\x90\x9e\x77\x67\x80\x91\x94\xa7\x93\x54\xc6\xd4\x4d\x6d\x3e\x44\x72\x4b\xb1\xe2\x38\x9f\x54\x67\x65\x0b\x47\x50\xba\x1d\x4c\xb9\xd7\x38\x6f\x30\x33\x6c\x69\xf8\xe0\x31\x7a\x79\xe4\x3b\x2f\x31\x27\x74\x20\xee\x3e\xa2\x61\x27\xa6\x7a\x1b\xdc\x20\x59\xdb\xca\x0e\xd6\x42\x55\x13\x9d\x4b\xc9\x56\x2d\x4d\xc1\xa8\x95\x74\x5a\x51\x07\xeb\x0e\x99\xaf\x07\xe0\x01\xf8\x47\xc6\x0d\xc5\xc5\x91\xeb\xc1\xf1\x2d\xae\x52\x63\x7c\x4b\x78\xb1\xbe\xba\xe4\xc9\x31\x54\x39\xf2\x30\x28\xe9\x1c\x4d\xcf\xfd\x58\x83\xb3\xe2\x54\xbb\x18\xc5\x51\x2d\x08\x80\x55\x76\xeb\xd9\xb2\xf3\xa1\xcd\x57\x08\xe0\xb5\xfe\x6a\x27\x61\xc8\x1a\x90\x48\x6a\xd3\x6c\xf5\x3d\x3b\xe5\xc8\x23\xbb\xc7\xe4\x04\x2e\xcb\x00\xe2\x5f\x3a\xac\x04\xaf\xfc\x21\x01\x6c\x52\x61\x5c\xb4\x19\x4e\x46\x06\x08\x1e\x43\x7f\xe9\xff\x88\xe1\x64\x11\xa6\xee\x58\x19\x09\x92\x65\x94\x6b\x4a\x4b\x5e\xbd\xea\xcc\xa4\xd9\x17\xfb\x9b\x1d\xac\xfc\x29\x63\x0c\xe1\x68\x42\xc1\x8c\x04\x59\x99\xe2\x1a\x92\xe9\x1a\xe4\x2c\x7e\x4a\x22\xc5\xe3\x52\xa7\xf0\x63\x84\x7a\x49\x6d\x21\x3d\x5b\xd0\x72\x60\x8d\x45\x66\x03\x76\x8d\x9a\x11\xb0\xf9\x48\x35\x31\xb2\x44\xce\xe3\xe9\xcd\xfc\xae\xaa\xb4\x71\x3e\x93\x58\x76\x07\x32\x54\x5e\x11\xfc\x0e\x2d\xa6\x74\x10\x27\x15\x24\x28\x00\xc4\xa9\xbf\xb7\x7a\xdf\xc3\x93\xb1\xa8\x26\xe9\x9e\x98\x7e\x7c\xbc\xd1\xe6\xcc\x9e\x77\x32\x08\x47\x7f\xb0\xdf\x43\x80\x7f\x30\xeb\xb5\xff\xd7\x27\x7f\xb0\xa8\x0b\x55\x1e\xd4\xba\x29\x4a\x08\x81\x89\xf2\x67\x36\x6b\x09\x18\x2b\xe5\x94\x86\x57\x20\x43\xa6\x92\x96\x25\x31\xc9\x66\xae\x6a\x3f\xe1\x06\x7e\xe2\xdb\xbb\x4d\x5c\xa4\xd2\x7a\x6a\x6d\x81\x94\xa6\xf4\x80\xf0\x2c\xc0\xb5\xdf\x38\xa6\x2a\x23\x97\xb1\x26\xdd\xe4\xe0\x45\x7f\xba\x94\x72\x3f\x29\x61\xab\xf7\x86\xc9\xe4\x1c\x9e\xcf\x3a\x8c\x37\xf6\xa9\xa2\x31\x58\xe3\x03\xea\x28\x74\xea\x52\x5a\x6b\x86\xae\x67\xf0\x2c\xe0\xc5\xce\x7d\x40\x66\x72\x8f\x00\xe2\x68\x5f\xc2\x48\xb3\xe4\x6b\xdc\x0e\x4c\x41\x81\xe1\xb8\x7d\x44\xc0\x51\x46\x2b\x5e\x1c\xbd\x60\x9c\x38\x79\x0d\x56\xe2\x11\xfa\x45\x38\x64\xc4\xd2\xca\x88\x77\x54\xb9\x35\x2f\x86\xf8\x7e\x6d\xc1\x25\xce\xb5\x42\x87\xc8\xfc\xfe\xfd\x33\xa2\x37\x6c\xd4\x1a\x0b\xe7\x98\x32\x9b\xd9\xed\xe4\xfc\x28\xfd\x4a\xf6\x3a\xa1\x63\xb6\x7c\xc5\xff\x24\x81\x6a\x18\xf1\x43\x7f\xac\xed\xbb\x19\x6c\xb1\x63\x8e\x6f\x8e\x17\x01\xc9\xfb\xd9\xff\xeb\x76\xb6\xe5\xb0\x0c\x7a\xca\x8c\x0c\x7d\x92\x20\x82\xdd\x89\xda\x6a\xd6\x6c\x99\x10\x96\xc8\xf1\x39\xa2\xc7\xef\x13\x29\xd3\x62\x2d\x60\xcb\x9b\x35\xfa\xb0\x38\xfb\x42\x13\xed\xa5\x4d\x6d\x88\x72\x24\xea\xb9\xd8\xe4\xa9\x85\x65\x30\x54\x36\x8a\x7d\x43\xfb\x9a\x47\x0c\x93\x08\xab\xd3\xb9\x75\x78\xef\xe2\x7d\xa6\x94\x96\x51\xce\x1c\xdd\xf0\x27\x70\x1e\x1d\x06\x01\x8a\x33\x76\xc1\xc9\x37\x0a\x0a\x6d\x50\x74\x6d\x24\x1a\x07\x3e\xb2\xa9\x40\xc7\xae\x0d\x91\x50\xb1\x43\x9c\x56\x52\x39\x94\x73\xd7\xb2\x34\x07\x05\xa1\x95\x03\xe4\x7d\x9c\x42\x55\x31\x65\xf7\xe5\x66\xaa\x37\xde\x37\xf8\x27\x05\x6b\x6f\x4c\xc0\x7d\x3a\x05\x70\xf1\x36\x29\xcc\x58\xc2\x6d\x0a\xce\x9f\xc0\xc0\x31\x7c\xf5\x2a\x08\x0a\xa7\xc2\x19\x3e\xae\x7f\xae\xfe\x13\x20\x49\x61\x21\xc9\x47\x56\x64\x96\x22\xc2\x64\x01\xed\x8f\xd8\xb7\x7e\x3d\x7c\x18\xab\x2b\x8e\x93\x6a\x61\xf2\xd0\x27\x59\xf5\x1a\x4f\xe1\x18\x44\x13\x53\xb6\x03\xd1\x41\x44\xd1\x16\xc6\x05\x89\x74\xce\xfe\x51\x6a\x20\x91\x90\x69\xff\x32\xcc\xd5\xc9\xab\x2b\x09\xf4\xe4\x15\x1a\x96\x9d\x9b\x73\xa9\x2a\xdd\x84\xc4\xb8\xae\x9d\x77\x68\x44\x3e\x0a\x86\x26\x8e\xf1\x6d\x0b\x64\x7a\x79\x92\x6f\x8e\xfa\xf8\x80\xea\x75\xf1\x8c\x35\xe7\x35\x19\x85\x71\x9d\x46\x16\x28\xfd\x9b\xae\x8b\x82\x94\x95\x38\xb0\x2a\x3b\x0e\x35\xf4\x53\x32\x02\x53\x58\x4b\xdf\xa4\xce\x5b\xea\x6c\xce\x97\x59\x98\x8c\xfd\x97\x70\x2c\x2c\xa8\x99\x49\xde\x03\x5e\x7b\xf4\xef\x18\x6b\xd0\x9f\xe4\x0a\x2e\x69\x57\x4d\xd2\xc2\x0a\x03\x57\xba\x2b\x98\x25\xec\x04\xb0\xd9\xcf\x48\xf2\xc4\xd3\x17\x16\xa8\x65\xad\x36\xa2\x35\xde\x5f\x9e\x25\xf4\xa4\xe0\x83\x87\x2e\x73\x27\x04\x33\xfb\x34\x73\x9d\x4a\xe4\x1a\x79\x13\x18\x24\xda\xe6\x40\x5e\x14\xe6\xb9\x4e\xce\x85\x08\x1d\xc3\x9e\xc4\x2e\x41\x4c\x4f\x89\x99\xb6\xb2\xec\x77\x96\xc5\x5c\x06\x35\x82\x6c\xbe\xb3\xfb\xf4\x20\xed\xf0\x65\xaf\x80\x3e\x06\x2b\x5f\x3b\x98\x4b\xcf\x38\xbd\x40\xcd\xe6\xc0\x57\x59\x99\xf2\x4e\x2c\x20\x5d\x17\x02\x4a\x33\x88\xa0\x38\x22\x19\x59\xe0\xdb\x39\xab\x0f\x75\x62\x95\x77\x22\x1b\x80\x6d\xae\x0a\x4c\xa9\x79\xfb\x4e\x6e\x07\x1a\xd2\xee\x0a\x69\xce\x46\x19\x26\x68\xce\x96\x11\x12\xb1\x13\x67\x1e\xe4\xfb\x32\x66\x71\xea\xfc\x1d\x4e\x63\x91\x70\xc0\x9e\x33\x21\x57\x07\x4b\x61\x28\x1c\xba\x2d\xa7\x03\xe2\xfc\xd2\x27\x47\x10\x4e\x48\xa0\xc3\x57\xb3\xf4\x9d\x24\x3e\x89\x0c\x67\xc4\x82\xbe\x5d\x90\x5b\x23\xd5\xc3\x6f\x06\xa8\xb1\x6e\xbb\x8f\x82\xb0\xb1\x7f\xe1\xc5\x0e\xd0\xbd\x6c\xc8\x8b\x03\x0b\xc7\xa6\x4d\x45\xe7\xc3\x95\x7e\xda\x7d\x20\xdd\xfe\xc9\xe9\xf9\x0b\x0a\x25\xea\xe2\x1d\xfd\x1d\xd7\x6f\xf2\x36\x68\xa3\xbf\x52\x84\x43\x25\x40\xa1\x16\xe7\xcd\x6f\xed\x00\x80\x07\x11\x45\x3b\xba\xd6\xf7\x87\xd9\x2c\x44\x19\x25\x35\x18\xa4\x91\x1c\xc1\x17\x1c\x57\x9b\x34\x41\x8d\xb6\xec\xfc\x79\x67\x8b\xb6\xe8\x05\x78\x95\xec\xc3\x2f\x35\xdb\x73\xd8\x8b\xc3\xd0\x0e\x8e\xda\x01\x38\xa1\xcb\xa0\x15\x03\x32\x68\x5d\x8c\x3c\x7a\xd3\xc3\xc2\x6e\x13\x0c\xa6\xe5\x9d\x58\x3c\xb9\x5a\x82\x0f\x81\x96\x13\xc0\x1a\xf8\x1c\x48\xa9\x9d\x6a\x77\x76\x52\x58\xa6\x01\x20\x9b\x92\xcd\xc3\x8a\x29\x2c\xcb\xca\xa6\x53\xf0\x52\x76\x49\x99\x22\x07\x4e\xa7\x85\xdc\x61\x72\xdd\x3d\x32\x00\xef\xf8\xc3\xe6\x33\x67\x03\x5d\xb0\x01\x67\xa9\x62\x5e\xd0\xa9\x47\x61\x36\xad\x54\x3d\xd0\x01\x0d\xda\xd2\x1d\xe9\x2a\x54\xed\x7a\x4c\xcb\x8e\xdd\x27\xa5\x9c\x44\x4a\x66\xa0\x3c\xea\x29\xf9\x4e\x81\xf5\xc5\xa9\xc4\x0d\x15\x19\x18\xf0\x4f\xf1\xfe\x3a\xae\xd8\xed\xe4\xc2\xe6\xf1\xb4\xf1\x51\x90\x21\x2e\xae\xd5\x20\x11\x5a\xdb\x47\x45\xec\xcf\x14\x07\xab\x06\x53\x4e\x21\xf8\xbc\x39\x6d\x5f\x27\x09\xec\xa4\xf2\x7b\xa5\x79\x5e\x4d\xcb\xda\x30\xf1\x94\x1d\x12\xa6\x90\x5c\xb3\x1a\x4b\x60\x1a\x6f\x98\xbf\xb8\x85\x5e\xe1\x01\xd8\x51\x6a\xd1\x9b\x1c\x52\xfc\x0f\xa3\xb8\xef\x14\x8d\xa6\x33\x7c\xb3\x53\x0f\x59\xdf\x86\x64\xda\xe9\x10\x30\x06\x2d\x92\x08\xd7\x35\x03\x03\xbc\x07\xaa\xfb\x83\x45\x7d\x84\x79\x87\xa3\x43\x3b\xc7\xd4\xef\xe5\x05\x00\xcc\xe4\x03\xd8\x43\x34\xb4\xac\x35\x86\xdc\xc6\x44\x24\x71\xc0\x7c\xac\x48\x31\xa4\xd3\x39\x41\xda\xd4\x82\x14\xc3\x09\xfc\x93\xea\xdd\xa0\x38\x35\xfa\x32\xdf\x0e\x88\xbc\x51\xab\x95\x68\x03\xad\x67\xa8\x5b\xda\xae\x21\xbf\xd1\x09\x40\x24\x45\xc4\x0f\xe9\x27\xd0\xdd\x45\xcf\x7c\x85\xe4\x13\xa5\xfd\x7f\x71\x0c\x1d\x30\x3b\xc5\x2f\x91\xe0\x93\xbd\x33\x1a\xb9\xad\xe6\x4a\x5c\x93\x48\xc5\xc3\x1c\xa7\xca\x8b\x48\xba\xe2\x3e\xaa\x6e\x9b\x1e\x2b\x80\xa5\x9b\x0f\x40\x5b\xa9\xbf\xd1\x89\x29\x85\xbc\xb2\xb6\x54\x00\xbc\x58\x4b\x00\x60\x6f\x1f\x05\x71\x72\xce\xca\x81\x6e\x3d\x6d\x72\x1c\x42\xdb\x43\x9c\x5c\x7d\xb4\x7d\xbc\xd2\x3a\x98\x21\x7c\xb9\x17\x9d\xc7\x68\x2d\x71\xb2\x34\xef\x99\xa1\x21\x3c\x77\xcf\xec\xe7\x9c\x98\xf0\x7a\x33\xf3\x83\x68\xbd\xdd\x6e\x4b\xbc\x7d\x22\xab\xc2\x5c\x08\x7d\x13\x48\x1b\xd5\x15\xeb\x4e\xa0\x96\xc7\x6c\x8c\x6d\x0c\xa4\xb1\xe9\xb9\x18\x09\x17\xa8\xf7\x89\x60\x7a\x0f\x8d\x89\xb8\x5b\xf0\xa7\xf6\xc2\x5a\xc3\x59\xa1\xf8\x4a\x57\xb1\x28\x2a\xe7\x4c\x75\x94\x2b\x46\x8b\xe1\x5b\x87\xbf\xde\xc4\x60\xd9\xf1\x83\x7e\x46\x5b\xd5\x78\xd1\x84\x36\x1d\x48\xce\xce\xdb\x9e\x7f\x71\x22\x54\x99\xea\x41\x0d\x42\xf3\x85\x53\xfd\x90\xfb\x61\xbe\x4a\xa3\x4c\xc8\xdd\x7b\x37\xbf\x4e\xe7\xc7\x69\x4e\xec\x25\xda\x5c\x22\x7b\xea\x56\x56\xd5\x19\x65\x18\x8b\xe3\x44\xf3\x49\x62\x15\x4f\xbc\x46\x2a\x64\xd2\x9f\x0f\xab\x46\x93\xd9\x7b\x43\x3d\x59\xe2\x8c\xe7\x93\x8a\x25\x15\x65\x67\xea\x32\x98\x1c\xc9\xce\xd9\x25\x3e\x92\x32\x62\xc6\xce\x0e\xa7\xbb\x21\x48\xf4\x29\x69\xb5\x8d\xa9\x22\x4e\x92\xef\x11\xf1\x9f\x0e\x23\x43\x6a\x91\x7e\x7f\x07\x97\x1b\xee\x4a\xbd\x0b\x55\x95\xd2\x93\x71\xb2\xd7\x45\xb5\x14\x15\x7e\x02\x82\xa9\x5f\x57\xe4\x2e\xa9\x31\x2d\x51\x62\x63\xa6\x64\x1c\xb5\x56\x59\x4d\xb4\x5e\x59\xd8\xd4\xa3\x05\x60\x44\x68\xbb\x28\x90\xae\x3e\x0a\x4d\xea\xae\x23\xdc\x71\xbe\xd7\x88\xa9\x2d\x72\xa9\x4c\x48\xdf\xec\x0b\x61\xa3\x5d\x47\xf1\x83\x45\xa9\xfe\x91\x64\xb7\x5a\x30\x8c\x08\x39\xd4\xb3\xc3\x22\xd8\xf0\x0c\x16\xbb\x7d\x10\xfe\x0d\x38\xcc\xa4\x83\xad\x01\x21\x91\x71\x21\x6e\xc1\xac\x0c\x49\xe8\xed\x62\x30\x2e\x67\xc8\x49\x8b\xe7\x87\x6d\x55\x79\x88\x48\x4f\x78\x25\xb6\xa1\xfb\xd9\x97\x97\x29\x6f\x6c\x19\xfb\x03\x33\x5b\xdb\x54\x87\x3b\x8d\xee\xbd\xf3\xdb\x3f\xe1\x56\x51\x7c\xdb\x9f\x11\x23\xfa\x7f\xd1\xb5\xec\x31\x6f\xc2\x6e\x2d\x10\x66\x1d\x7e\x3d\x76\xe8\x98\xdc\xac\xd6\x7d\x8c\xca\x53\xdf\x49\x47\x2e\x3f\xe8\x04\x79\x82\x89\x16\xb5\xd3\xb9\x98\x4c\x08\xa1\x1c\x09\x7f\x6f\xea\x98\xe2\x70\x6a\x25\x76\x1b\x9d\xb5\x1b\x21\xf2\x00\x51\x9f\x8a\xd3\x52\xd1\x0b\xa8\xd6\x95\xbc\xff\xa4\xe1\xce\xb7\x1c\x01\x2e\xac\x8b\xb7\x9d\xe4\xa8\x28\xaa\x0c\xe8\x79\xa4\x0a\x3f\xe2\x17\x3a\x8a\x3d\x30\x85\x6b\xe4\xe5\x73\x3d\xaa\x65\x60\xc5\x8b\x9c\x22\x8a\x4f\x6b\x3c\x0b\x98\xdd\x9b\xfb\x4b\xf8\x8e\x34\xb1\x8e\xe3\x42\x4a\xdb\x42\x56\x94\xf6\xb2\x83\x02\x33\xb9\xc4\xbf\xd9\x6e\xe2\x4c\xd9\xe8\xb6\x96\xbb\x29\xbf\xc7\x3a\xc0\xe4\x93\xe1\x77\xe5\xf5\x9c\x84\x6a\x96\xc4\xab\xc0\xda\x4b\xc9\x17\xf3\xd8\x39\x90\xb6\xba\x8a\x75\xf3\x42\xd8\x53\x4f\x9d\x11\xeb\xac\xd9\x1e\x72\x32\x16\xb6\xa3\x90\xe1\xad\x8a\x3e\x3c\x60\x62\x05\x74\x72\xcd\xe9\xc9\x45\xc0\xb4\x6f\x81\x70\x14\xcf\x95\xf6\x21\xc0\xd1\x70\x14\xe9\xc3\x62\x30\x0e\xd7\xbb\x7c\xba\x55\x0b\x98\xd3\xa9\xc5\xf4\x4a\x94\x27\xbb\x02\x3f\x2d\xba\x26\x8e\x4e\x8c\xbb\x3d\x19\x90\x07\xa7\x2e\xa3\x2a\xa0\x31\xfa\xdb\x3e\x74\xe2\xba\x6b\x56\xfa\x56\x2e\x18\x5e\x10\xb8\xc4\xe2\x0d\x8e\xd6\x39\x4a\x9d\xb0\xd4\xd8\xc8\x11\xfe\xd1\xdf\x6f\x1f\xcf\xc5\x56\x02\xbe\x27\xcb\xb7\xf2\x95\x9c\x56\x1e\xdd\xe4\x76\xdd\xaa\xbc\xac\xf8\x79\x48\x20\xaf\x68\x17\xf3\x52\xca\x87\x61\x05\x97\x58\x06\xa7\xa4\xca\x82\x81\x28\x1d\xce\x5f\x90\x49\x4c\x7b\x91\xb5\x90\x65\xc5\x47\x28\x9b\x43\x91\x69\x33\x2f\x5a\xca\xe5\x05\x78\xc2\xdd\x68\xea\x28\xc1\x4f\x63\x09\xd9\xb6\xed\x23\x56\x45\xfc\x12\x94\xe0\xc0\xaa\x50\xa1\x71\xab\xb8\x6e\x1c\x29\x43\x32\xff\xcd\x45\x46\x01\x58\xf9\xad\x3f\xc4\x68\x31\x0b\x40\xa1\xfb\x05\x0f\x49\x55\x36\x6f\xf0\xb6\xae\x14\x2c\xb5\xc4\xce\x17\x8d\x22\x4b\x89\xaa\xde\x42\xef\xaf\x31\x82\x17\x19\x46\x7d\xd8\x87\xee\xcc\x92\x8a\xa2\xd8\x3d\x69\x1a\xb9\x22\x4e\x76\x4e\xf9\xc4\x34\xcb\xed\x41\x26\xae\x7d\x79\xa0\x76\x05\x4b\x64\xcf\xee\x93\x54\xa8\x5b\xa4\x97\x8d\x21\x92\x6b\x3c\x6f\x63\x24\xa6\xd6\x0f\x57\x3b\x96\x51\x67\x06\x02\xbe\xd3\x59\x10\x1c\x3a\x14\x39\xea\x69\x72\x70\xf3\xfd\xe5\x62\xdf\xce\x62\x36\xe6\x97\x3b\x85\x8b\x65\x40\xa2\xb5\x0a\x02\x61\x8d\xe4\x35\x54\xce\xe3\xe0\xe7\xe3\x41\x46\x07\x60\x0e\xbf\xb8\x64\xb7\x0f\xc6\x57\x46\x10\xd7\xe5\xe4\xee\x2a\x9d\xcc\xba\xfe\xa6\xd3\x2d\x29\x91\xe8\x37\x87\x0a\xd8\xa8\x2e\x42\x80\x56\x97\x6a\xfc\x6a\x51\xbc\x19\x06\x94\x49\xdd\x35\x6a\x33\x62\xc2\x07\x8e\x7d\x45\xbe\x3a\x2a\x57\xd6\x35\x05\x36\xcd\xd9\xef\x6f\xac\xc7\xb0\xf4\xf7\x17\x09\xe7\x7a\xf6\x41\x7c\x22\xf3\x63\x2f\xbf\xd0\x47\x09\xe7\xee\x05\x04\xc9\x3e\x7c\xee\xb1\x44\x04\xce\xd9\xaa\x6f\xd7\xaa\xd6\xe1\xf7\x2c\xaf\x7c\x48\x5b\x60\xb3\x79\x27\xf3\xc9\x5c\x02\x68\xe7\x61\x60\x73\x13\xe4\x9f\x78\x50\x32\x14\x6d\x72\x8a\x43\x31\x49\x51\x6b\xc8\x34\x66\x4b\x04\x01\x78\xa0\x03\x66\x03\xa7\x4c\x62\x4a\x0c\x64\x29\xab\xcf\x81\x1d\x18\xa2\x58\x43\x4e\x46\xd1\xa9\xfe\x9c\x12\xa2\xcd\x84\xe0\x70\xa1\x39\xa3\x01\xf8\xf4\x84\xe7\x95\x58\xea\x56\xdd\x10\x2f\x31\x47\xe7\x8c\xc8\x26\x38\xfc\xb1\x0d\x6c\xf5\x28\xde\x2f\x9f\x93\x8f\x46\xc9\x66\xc0\x73\x78\xb3\x05\x56\x5b\xfa\xf5\x2c\x55\x04\xa5\x62\xe0\xc6\x1c\xda\xac\x58\x1d\x39\x58\x84\xd6\x36\x2d\x99\x5a\xd4\xb2\xca\x49\xa1\xe0\x87\x78\xdf\x21\x93\x01\x1f\x56\x32\xe7\xaa\xf9\xd4\x16\x9b\x23\xeb\xc3\xc7\x27\x96\x84\x13\x02\x5f\x1f\x52\x98\xb2\x37\x82\xbd\x3f\x38\x59\xf2\x92\x2b\x5a\xb9\x6c\xc4\x29\x4e\xdb\x3b\x06\x9b\x53\x80\x13\x29\x87\xca\x22\x30\x09\xe3\x26\xd7\xf4\x48\x43\x0f\xe1\x76\xa6\xe1\x19\x38\x97\x50\x33\x33\x84\xeb\xff\x86\x9e\x09\x00\x2e\x7f\x6b\x74\x3f\x66\x6d\x5b\x28\x48\x4f\xe5\xde\x10\x11\xa8\xc5\xa2\x55\xd6\xea\x16\x57\xe7\x91\x58\xd6\x04\x49\x92\x2b\x94\x7e\xa6\x00\x6d\x42\x09\x6f\x59\x04\x31\x0e\x27\x2a\x32\x56\x0e\x7e\x7c\x8b\x49\x4c\xb6\xf3\xa8\xcf\x7c\x29\x7e\xc8\x64\xb0\xc2\xf8\x4a\x9b\xa4\x6d\x6d\x65\xfd\x9d\xd6\xac\xf2\xa7\xa8\x8b\x0c\x05\xa7\x51\xa1\x98\x86\xda\xba\xcd\x53\x7b\xd8\x70\xe7\x89\x82\xc2\x35\xf6\xdb\x13\x32\x0b\x57\x95\xb6\x73\x70\x4e\x81\xfc\x51\x5e\x9e\x63\x28\xfa\x3a\xfd\x8b\x80\x7a\xf6\x27\xae\x94\x9f\x43\x1f\xfa\x4f\x5f\x7c\x5a\x4f\x52\xcd\x3f\x70\xe3\x15\xac\x82\x6f\x51\x59\x30\xaa\x8f\x8a\x2f\xb6\xa0\xcf\x7a\x6c\x71\x23\x96\x05\x97\x20\x62\xe0\x9e\xfa\x16\x02\x9c\x2a\x22\xc5\x40\xc7\xf2\x7a\xcb\x87\x87\xdc\xa2\x56\xe1\x69\x48\x9b\xc6\x31\x10\x0a\xd7\xb0\x05\x00\x50\x59\xcc\x79\x9c\x5a\xf5\x24\x0f\x49\x2c\x3f\x20\x03\xf3\x48\x4a\xd6\x41\x99\x7c\x4c\xea\x07\xa9\x52\xa7\x73\x11\xaf\x75\x94\x63\x21\xaa\x64\x93\x55\x79\xf8\xbf\x2c\xfd\x27\x78\xcc\xf2\x81\x68\x34\x58\x06\x3d\xed\x0b\x4e\x4e\xfd\xdf\x98\xa9\xce\x51\xaa\x0a\x3e\x9f\xd6\x9a\x3b\x45\x46\x21\x72\xfc\xbb\xf9\x4c\x6b\x5c\x64\xe5\x46\xb3\x26\xfe\xf3\xda\xc1\x30\x0a\xae\x4a\xf9\x21\xe9\x5e\x2c\x5d\xfb\x83\xee\xd2\xb0\x19\xf5\xc2\xbe\x9a\x39\xfb\x7a\x02\x6c\xbf\x11\xb7\xbf\xbc\x00\x50\xd0\xbe\x60\xaa\x0a\xdc\xe4\x85\x4a\x01\x84\xde\x4c\x88\x40\x7f\xe6\x67\x28\x77\x2b\x61\x8d\xda\x74\x36\xb7\x2c\x60\x78\x0e\x3d\xac\x0a\x4a\xa3\x4b\x75\xb6\x6e\x32\xaf\x34\x7a\x93\x4a\x91\xad\xf2\xa5\x88\x75\x34\x03\x9a\xde\x69\x64\x27\xdd\x2f\x9a\xac\x35\xf0\xd8\x5c\x63\xcd\x07\x51\xd8\x20\x98\x07\xab\x04\xf4\x3e\x43\x7a\x40\x23\xfa\xe2\x31\x96\x36\x3f\xa0\xa0\xea\x66\xf1\x4a\x8e\xe0\x5c\x1b\x41\x0a\xf9\xe1\x72\x9f\x78\xf5\x31\xc8\x58\xc3\x6a\x1c\x01\xc8\x55\xad\xde\x79\x25\x57\x79\x76\xe5\x8e\xac\xb2\x1c\x48\x8f\x5f\xa3\x03\xfa\x20\x7b\xc9\xc1\xca\xdb\x59\x48\xe0\xb0\xa0\x09\x14\x62\x2a\xed\xa4\xd6\x3e\xa9\x8b\xd7\x70\x02\x9a\x6e\x78\x38\xae\xb3\xd7\xaa\x43\x8c\x6f\x67\x83\x1e\xe0\x33\x69\x61\xd4\xd5\xac\x95\x22\x8f\xb6\xb6\x3e\xe2\x3e\x2d\x92\xc2\x5a\x49\x30\x25\x3e\x1a\x24\xa8\xf4\x8f\x35\xae\x18\xbc\x59\xfa\xa9\xca\x30\x80\x5a\x3d\xca\x5b\xbc\xfc\xb3\x44\x1b\x22\x62\x5b\x5b\x4f\x74\xa1\xcc\x3e\xae\xc6\xec\xa6\x9c\x3d\xa8\xbb\x97\x8f\xb7\x8a\x68\x59\x00\xf1\x82\x92\x81\x39\x1b\x45\xa3\x27\xd4\x64\x51\x5c\x97\x0b\x4c\xba\x8b\xe6\xcb\x0f\x83\x0b\xa0\x45\x2a\xfe\xb6\x78\x6b\x86\x55\x34\x57\x9f\x98\xa4\x24\x37\xea\x87\x84\xf7\x0c\x94\x21\x42\x5a\x44\x29\x1c\x2b\xee\x80\xd8\xca\x3c\xe2\x73\x72\xc4\x25\xb6\x77\x7a\xa3\x0f\x4c\x99\xc2\x97\x62\x3e\xfd\x99\xc2\xf6\x2a\xa6\xb4\xae\xe9\x80\x73\xb8\xef\x82\x89\x6a\xda\xe2\x44\xf2\x7a\x55\xe3\x03\x71\x13\xc4\xcc\x97\xa4\xbb\x85\xa1\xcd\x0d\xc0\xe8\x27\x1c\xc9\x73\x27\xe5\x77\xfa\x1e\x18\x07\x04\x0f\x2f\x01\x8d\xf7\xfd\xed\xfe\x00\x72\x4d\x09\x6a\x6d\xa6\x40\x39\x7b\x5b\xab\xc2\x38\xd4\x4d\x1b\x62\x77\x9d\x3a\x8f\x3a\x4c\x70\x88\x7b\xfb\x78\x0c\x56\x5b\xb4\x99\x51\xff\x90\xb3\x58\x1b\x67\xf4\x54\xe5\x5d\x42\x91\x3a\x91\x9b\x59\x29\xb6\x70\x25\x8f\xd3\x5c\xc7\xee\xe0\x54\x6c\xe5\xcb\xfa\xc4\x38\x05\x57\x3b\x80\x9c\xc5\xc0\x17\x1d\xbb\x80\x14\xb1\x42\xf5\xf9\x29\x79\x1f\xd4\x86\x9e\x98\x7c\x6c\x83\xb8\x9c\x1f\xc5\x4c\x64\x72\x04\xcb\x00\x61\x9d\xfd\x62\x1b\x60\x1a\xb8\x3e\x0e\x0f\xc9\x99\xb5\xdb\x56\x98\x35\x30\x75\xc4\x9a\x41\x89\xc5\x28\x77\xd9\x73\xbc\x3f\x93\xe5\x73\x14\xb3\xd3\x21\x41\x5d\x49\x18\xd1\x44\x22\xa0\xaf\x17\x0c\x10\xd5\x63\x77\x29\xee\x3c\x86\x47\xa0\x61\x56\xb7\xa4\x3b\x3b\x5f\x45\x83\x5c\x7d\xd9\x27\x94\xc6\x1f\x94\xdf\x39\xe7\xc5\x57\x3f\xe2\xd0\xd8\xf8\x46\x72\xce\x5e\x25\xad\x28\x39\x96\xf7\xe4\xfb\xdd\x8a\xc4\x47\x68\x8f\x67\xa7\x68\x2d\xdb\x82\x33\x25\x77\x26\x50\xe4\x01\x9a\xf6\x64\x97\x9f\x3e\x65\x04\x1d\xce\x18\x1c\xe5\xcd\x5e\xaa\xfc\xb7\x20\xd9\x5a\x86\xea\x82\xb5\x16\x2b\xe7\xac\x43\x89\xd1\x89\x32\xcf\x78\x32\xc7\x43\x20\xb8\x18\x79\x01\x12\x99\x63\xec\xdb\xec\x43\xaa\x59\x8d\x9a\xc3\x2f\xa9\x76\x4a\x2f\x3d\x31\x84\x79\x72\x39\x12\x39\x28\x2e\xd4\x34\xa1\x57\x9c\x97\x8c\x94\x83\x3b\x9c\xcd\xbd\xa5\x09\x70\x1d\x18\x3b\xc8\x5c\xa1\x5a\x1b\x8b\xbe\xab\x98\xf0\x93\x62\x9c\xb3\x4e\x34\xb5\x17\xee\x83\xcd\x7f\x47\x1b\x1f\xf2\x30\xb4\x82\x3a\x1f\xde\xeb\x7c\x70\x3c\x84\x1c\x05\x6b\xe9\x47\x48\x8f\x06\x25\x94\xde\x94\xa8\xfe\x00\xce\x08\x2e\xed\x3d\xda\x11\x5c\x0c\x6e\x95\xc0\xc3\xab\xb7\xae\x17\xe1\x52\xd4\x24\x33\x2d\xb1\xfd\x98\xae\x0d\x91\x01\x90\x0c\x4d\x06\x15\xd5\xe6\x34\xe0\x5f\xb7\x5d\x93\x0b\x1b\x5a\x75\x3c\x43\x57\xec\x8f\xca\x1b\x7a\xa2\xf5\x94\x94\xc6\x21\x84\xd6\xd6\x5b\x99\x76\xdb\x4e\x5c\x60\x95\xa3\x02\xcd\x15\x51\x5e\x30\xa8\x94\x3a\x52\xcc\x9c\x98\x92\x82\x20\xd3\x9f\xc1\xe2\xf6\xe6\x2f\x14\x3b\xe2\x50\xb0\x51\x85\x21\x32\x39\x2a\x1b\x6b\x34\xf0\x78\x80\xea\x64\xa5\x37\xbd\x47\xe6\x07\xe5\x8a\x36\x56\xbf\xc5\x12\x21\x73\x37\x4d\x6e\xfa\xc1\x8e\x99\x68\xb7\x62\x3e\x0f\xeb\x99\x2e\x9c\xa6\xa4\x2b\xec\x99\xa6\x93\x3a\x1a\x4b\x64\x72\xa0\xd9\x58\xd9\xd2\x7a\xb0\x75\x40\xab\x4e\x76\xef\x17\x17\x6e\x8c\x72\xa4\x41\x28\xa7\xae\x4c\xe6\x64\x02\x54\x45\x72\xd8\xc8\x00\x58\xbd\x3a\xf9\xe3\xac\x7c\x65\x1d\x3d\x90\xf7\x24\x1f\xbd\xf5\x1c\x5a\x3f\xde\xb8\xb1\x99\x58\xb1\x43\x5e\x12\x48\xb3\xfc\xc9\x0a\x43\x5c\x0e\x12\xe4\x97\xe0\x73\xd5\xe7\xaf\x8e\xbc\x36\xe3\x0c\x31\xe5\x8b\xad\x83\x43\xfe\x78\xc2\x9c\x93\xb7\x43\xb1\xaa\xf2\x6f\x86\x0f\xf8\x16\x66\x41\x7e\xd5\x38\x39\x6a\xbc\x95\x4c\x1d\x95\x5a\xe2\xd4\x39\x48\xfe\xed\x2c\x4d\x34\x1a\xde\xb0\xc4\x57\xa0\x56\xf6\xca\x01\x8c\x88\xa6\x72\xdf\x59\xf1\x19\x3a\xe5\x3f\x62\xa8\x92\x83\xb6\x04\xd1\x55\x5d\x81\x8f\xba\x48\xe2\x00\x7f\x3c\xbb\xc2\xff\xcc\x2c\x77\x0e\x57\xbf\x01\x7b\xc5\xf7\x57\x09\x22\x2e\xae\x04\x96\x91\x82\x5a\x40\xfb\x66\x59\x43\x92\xf8\x93\x1a\xa9\xc1\x1c\xac\x22\x60\x20\x80\x52\xe3\x05\x50\xdd\x95\x2c\xb0\xbe\xc2\xf7\x54\xef\x43\xac\x35\x4a\xbe\x42\x3c\x61\x0c\x1b\x46\x5b\x9f\x97\x91\x50\x26\xc9\x54\x2a\xcf\xe1\xe5\xc5\xf9\xbd\x86\x08\xf7\xb7\x33\xe9\xdf\x13\x3b\x7e\xb6\x82\x63\x21\xf1\xf0\x1f\x3e\xd0\x40\x0c\x4d\x32\x39\x71\x58\x64\x98\x1c\x98\x30\x45\x1d\xd6\xca\x03\x0b\xda\xcf\xe0\x7d\x4b\x2a\x22\xd3\x60\x1f\x82\x55\x56\xaa\xa7\x11\x06\xd7\x2e\x92\xe1\xea\x22\x28\x1a\xd3\x88\x17\x6a\xe3\x2a\x3d\xe2\x5b\xac\x91\xe9\xc8\xeb\x3a\x69\x85\x86\xf7\xc9\xbe\x71\x47\x9c\xba\x7b\x94\x63\x9a\xac\xe1\x48\x54\x13\x10\x1b\x89\xd3\x39\x87\x8e\x54\x6b\x24\x05\x3a\x83\x02\x02\xfb\xf9\x09\xe8\xc9\xb9\xa2\x87\x85\xa0\x18\xa9\xc8\xc6\x0b\x50\x0a\xed\x72\xbd\x90\x7e\x6e\xe1\x97\x0d\x1a\xf9\xe2\xab\x13\x47\x7e\x62\xd8\xbc\xca\xd4\xe1\xbf\x19\x47\x56\x92\x0b\x40\x9c\x9c\x9f\x81\x80\x1f\xe3\x7c\x27\x09\x62\x3a\x63\x7e\x03\xca\x82\xb6\x95\x60\xde\x43\xf0\xf1\xc8\xaf\x70\x2a\x9e\xfb\x00\x1d\x35\x8c\x40\x6c\x60\x21\x9c\xc0\xdf\xd8\xed\x0e\xa1\xab\x87\xc1\x04\x07\xd1\x53\x0a\x73\x9e\x81\x0d\x31\xc7\xbc\x17\x72\x26\x51\xdf\xd8\x1d\xd8\xd8\x8a\xac\xc2\x9e\xc8\x85\x68\x1c\xda\xef\xfa\x7a\x2b\x07\x0b\x4a\x92\xce\xe9\x14\xd1\xe7\xf8\x1a\x17\x9e\x36\x20\x90\x21\xab\x56\x7d\x05\xee\x69\xfd\x0f\x56\xa7\x99\x81\x16\x7c\xd8\x07\xa1\x27\x60\x54\x88\xbd\x03\x3c\xfc\x1d\x37\x66\x9d\x8c\x05\xdb\x3b\xba\x13\x0c\x7f\xa3\xb5\xc4\x68\x4c\x76\x03\xea\x90\x1f\xc8\xed\xd6\x72\x81\xc3\xa7\xfd\x54\xf6\xfa\xd1\xeb\xf4\x18\x33\x89\x6a\x66\x47\x51\x46\xef\xac\x0e\xfe\xb3\xd5\xe8\x07\x55\x82\xbc\x68\x8d\xba\xf0\xe9\x55\x8f\xdd\xe7\x06\xec\x71\x38\x90\x93\xec\x9c\x6d\x4c\x13\x05\x72\x8b\x12\x5e\x3e\xd8\xe0\xa7\xf7\xca\xac\x88\x7c\x95\x26\x7a\x18\x3b\x31\x6c\xd8\xd4\x88\x82\x65\x54\x57\x0e\x9e\x8a\x4f\x1b\x0f\x1f\xb6\xf9\x05\x42\x93\xc6\x05\x45\xe7\x8a\x77\x36\x6b\x8f\x0a\xc8\x5c\x31\x21\x49\x6b\xbf\xfa\x4f\xb8\xb6\x88\x3e\x3a\x4b\x62\x6b\x79\x8d\x29\xee\xef\xe0\x1d\x5b\x3e\x64\x3d\xd5\x9b\xf8\x2c\xe7\x47\x89\x35\x9d\x19\x68\x88\x51\xfa\xd3\x37\x89\xd2\x8f\xac\x33\xa8\xf6\xbb\x26\x4b\x98\x53\xb5\x67\xa0\x6f\x1a\x04\xb5\x42\x66\x01\x46\x24\xac\xea\x8e\xed\x9d\xe3\xc8\x5d\x3e\xbb\xde\x61\x3b\x59\x2e\xd9\xbc\xc4\xd9\x05\x14\x16\x9f\x2e\xb7\x00\x22\xd3\x45\x1a\xe2\xa3\x86\xf5\xb2\xc4\x5c\x86\xae\xf6\x06\xa6\xd8\x8c\x3e\x40\x33\xc9\x13\x48\x63\x07\xb3\xac\x4f\xf0\x29\x86\x9c\xe6\xf0\x1e\xd3\x27\x22\xdb\x28\x5e\xd6\xb6\x7e\x81\x0d\xad\x2b\x88\xe6\x67\xad\xc1\x90\x0c\x55\x15\xe6\xb4\x2f\xe2\x31\x5c\xc2\xf5\x44\x97\xf7\x15\x3d\x97\x47\xeb\x0c\x86\x64\xd6\x00\xed\x5a\xc8\x2f\x07\xad\xf5\x5c\x38\x74\xa8\x06\xcb\x3f\x38\x52\xa9\x32\xe3\x75\x54\xa1\xc8\x64\xd9\x86\xe9\x5a\x6c\x3c\xd9\x01\xbb\xb3\x71\xc2\x80\x6a\x3e\xbb\xaf\x13\x47\x05\xea\x4c\xf9\x0a\x21\x83\xe0\x3a\x79\x87\x82\x17\x83\x95\x57\x04\xdb\x84\xd2\x41\x22\x2e\x46\x1a\xa8\x42\x7c\x9b\x33\x68\x0d\x12\xec\xd3\x30\xbd\xef\xd3\x2f\x29\x69\x11\xa9\x3a\xe5\x3c\x0f\x5a\x6f\x8a\xf0\x51\x15\x12\x90\xf6\x15\x97\xf9\xfa\x8c\xce\x0e\x98\x29\x05\x65\x69\x0d\x74\x8d\xe2\x6d\x52\x2b\x76\x14\xb4\xa8\x87\x96\x84\x85\xfa\xd7\x1c\x4e\xb2\xf9\xbc\xcd\x8d\x48\x9a\xfc\xf2\xc4\x10\xf7\x3b\xb0\x7a\x0b\x9f\xd1\x02\x78\x24\x3a\x7f\xb2\x2b\x2a\xb9\x70\x98\x21\xab\x8b\x4a\xe5\xa7\x79\x34\xed\xc8\x7a\x3f\x8c\xf9\xb2\x91\x12\x36\x6f\x1b\xf2\xe6\x09\x72\x3b\xde\x63\x43\x56\x5d\x18\x3a\xa1\x81\xfa\xb2\x4a\xf3\xf9\x32\x63\x2e\x8c\x7a\x79\x69\xc7\x1e\x04\xeb\xb4\x55\x9f\x82\x80\xf7\x2f\x6d\xde\x56\x89\x8a\xd7\x0f\x28\x5a\x97\x5a\x7b\xbb\xa9\xaa\xb4\xb1\x7a\x66\x40\x94\x5f\x73\x00\xfc\xf7\x5c\x31\x73\x43\x12\xa2\xc5\xfe\xba\x1e\x21\x92\x61\x02\xa3\x81\xbe\x81\xee\x5d\xbd\x0d\xfb\x38\xfc\x9c\x1d\xcc\xbb\x9f\x5e\x7a\x5e\x0a\x78\x8e\x4b\x1c\x23\x5d\x30\x7a\xca\xa0\x69\x06\xc6\x83\x86\x3e\x51\x68\x6f\x4a\xa6\x15\x6c\xc2\xd1\xca\x2b\xb2\x0b\xa9\xd2\x3d\x00\x4d\xdf\x1f\xf1\x4a\x9c\x5c\x53\x8d\x2e\xe1\xa4\xbe\xa6\x61\x33\xb8\x21\x62\x32\x01\xb5\x49\xa4\x32\x7a\x16\xac\x91\x89\xd4\x2f\x09\x66\x0e\xb0\x2a\x74\x78\x74\x42\x26\x55\xbd\x8d\xac\x86\x99\x3a\x2b\x72\x4c\x2e\x8c\x50\x0c\x2a\xe7\x0e\x84\x3a\xe6\x2d\x9c\xc3\xaa\x79\x63\x7a\x5c\x59\xd9\xcd\x61\x88\x18\xec\x18\xd1\xb5\x57\x06\x55\x3f\xd4\xd7\xdd\xd2\xf0\x95\x1c\x9a\x63\x93\x46\x32\x58\x2e\x36\x2f\xcd\x8e\xd6\x3a\xd4\x73\x5b\xb5\x3e\x12\x44\xd4\xb9\x7e\x38\x36\x66\xf6\xea\xfe\x1c\x06\xc9\x47\x87\x31\x01\x78\x92\x34\x94\x25\xbe\x32\xc4\x1b\x95\x06\x0b\x9b\x02\x1d\xe8\xb7\x8f\x7e\xbc\xad\xb8\x41\x3a\x87\x16\xf3\x9b\xe3\x3a\x96\x8f\xe0\xea\x89\x47\x80\x54\xc5\xa5\x85\x01\xa4\xdf\xdf\xe6\x7c\xad\xd0\x41\xd7\x42\x63\x23\x0a\x48\xc6\x17\xe9\xdb\xa7\xf7\x18\xca\x21\x02\x8f\xa9\xd0\x03\xb2\xed\x62\xd5\x4b\x6a\xff\xa2\xcb\xe5\xfa\x0e\xc8\x5f\xc4\x94\x6b\x6c\xc0\xc9\x6d\xed\x00\xa4\x60\xa0\x0d\x88\x38\x55\xfd\x29\xca\x99\x6e\xd5\x23\x06\xbd\x29\x79\xd5\x9a\xc3\x94\xb7\x42\xc1\x2e\xb9\x66\x54\xeb\xbd\x5b\x81\xc4\x93\xce\x0b\x32\x52\x8f\x1c\x0e\xd4\x52\x34\xd2\xc0\x77\x34\x15\x4d\xa8\x9b\x56\xd8\x83\x5a\x0c\xe5\xab\xdb\x57\xcc\x5d\xdc\x9a\x51\x87\xd5\x74\x72\xa4\xe8\xc1\x89\x48\xdd\x3e\xd9\x6e\x5d\x1d\xe1\xeb\x31\x5b\x1f\x07\x20\x08\xc7\xe0\x72\xa1\x74\xbf\x6a\x2a\xe1\x10\xee\xdd\x4d\xbd\xff\xd0\x8a\x92\xd1\xfa\x2d\xb6\x3a\x59\x70\xf5\x2c\xce\x44\x3f\xa9\x31\x1e\x9d\x4b\xa6\xcd\x89\x38\x41\xa4\xa6\x29\xd3\x18\x23\x62\xd8\xcc\x68\x49\x98\x93\x42\x25\x8a\xf1\x01\x6b\x3a\x36\x8d\x3e\xf3\x43\xb0\x30\xfd\xe3\xd0\x8d\x91\xbb\xc7\xd1\xd0\xa1\xb7\x9c\x3e\x56\x2c\x85\x19\x95\x5f\x7a\x00\xb9\xbf\x5b\xa4\x3d\x23\x00\xfa\x4a\xcc\xaa\xb5\x1f\xf3\xfe\x7d\x5a\xb0\x6b\xec\x88\x05\xfb\xd1\x51\x82\xa5\x70\x56\xed\x93\x77\x01\xc9\xd9\xf7\xd5\x54\xb8\xfd\x2b\x4e\x8f\xa4\x40\x02\x38\x4d\x63\x39\x9c\x75\x00\x1c\xe5\x90\x83\xf4\x30\xe5\x22\xc3\x38\xf4\x9c\x90\x4e\x97\x5d\x72\xd4\xcb\xc8\x7f\x86\xa4\xca\x6a\xc2\xbb\x99\xcf\x25\x6c\x6f\x35\x2c\x56\xdb\xc9\x18\x28\xb8\x17\x16\x56\xb1\x0e\xb3\xa4\xa1\xa7\xa5\x3e\xb8\x7a\xea\x3b\xe8\x63\x12\x9e\x03\xa2\xd4\x56\x51\x28\x10\x2a\xeb\xd5\x87\x12\xce\xd8\x83\x3e\xc8\x94\xa4\xae\x8b\x2b\x42\xab\xda\x87\x90\x1d\x35\x38\x48\xe8\x0b\xd5\xa7\xa1\x18\x4a\xf9\xeb\x58\xe1\xdf\xf0\xd9\xce\xec\x0b\xb0\xa3\x6b\xca\x59\x4c\xa8\xff\xd5\x4e\x46\xb0\x2d\x4d\xea\xe7\x41\xb0\x81\x23\x40\x15\x89\xf2\xc4\xb5\x76\x0e\x4f\x91\x8f\x64\xcd\xcb\xa4\x13\x16\x48\x9d\xe8\xe4\x2a\x1e\x7f\x30\x4d\x4e\x9d\x28\x8a\x73\xfe\xd2\x1a\x9d\x5d\xd0\xdd\x8f\xb1\xce\x75\xf2\xcc\xce\x74\xe0\xb8\x27\x18\x79\xeb\xf0\xe9\xf6\x0d\xe5\x4c\x92\xd6\xfb\x52\x70\xe9\x56\xd4\xe0\x56\x76\xcc\xac\xda\x54\x6b\xd1\xf8\x1a\x07\x51\x53\xb3\x12\x5c\x8c\x4c\x55\xa7\xe8\x6d\x15\xa8\x63\x3c\x20\x28\x12\x79\x69\xec\xa6\xd4\x21\x31\xe7\xba\x65\xbc\x08\x7d\xd4\x1a\x21\x00\x87\xbd\x63\x7d\x7d\x02\x14\x31\xc5\xbf\x78\xba\x09\xb3\xf1\x96\xc0\xdf\x6b\x96\x83\x86\xe5\xe4\x16\x4a\x71\x10\xfb\xcf\xea\xdc\x4c\x38\x91\x5b\x89\xdc\x0f\x4b\x72\xbc\x4b\xf9\x18\xa2\xb2\xea\x43\x01\x5f\xcb\xd3\xb3\xbf\xde\xc6\xe4\xe9\xc1\x2f\x63\xa2\x45\x99\x2a\x9e\xe0\x00\xe6\x72\x30\xe1\xd3\x7e\x31\xe0\xa4\xe2\x1d\x21\x4b\x75\x2e\xce\xf5\xc8\x3a\x0f\xca\xbe\xb2\xf2\xea\x03\xc5\x08\x0b\xe3\x87\x3f\xde\x21\x87\xfa\x13\xd9\x2a\xa6\xa3\xca\xfc\x1e\x95\x0e\x00\xd1\x67\x5e\xaf\xbd\xdd\x54\xaa\xf6\x06\x37\x4a\x53\x89\x37\x39\xc9\x26\x22\xd1\xbb\x9f\x0b\x8a\xc6\xb2\x5f\x99\x3d\x85\xaa\xd7\x06\x8e\xbb\xcf\xd9\x56\x6e\x10\x81\xd7\x8b\xd1\x45\xf7\x32\xb0\xab\x89\x82\xbb\x39\x06\x8f\xa7\x7a\x7c\x49\xa8\xec\xc9\x9b\x02\x88\x45\xbf\xe1\x63\x4f\x21\xd7\xc4\x2c\xd1\xed\xb9\xcf\xed\x0d\xd3\xda\x48\xf0\x00\x0f\x21\xfc\xb2\x2f\xcb\x87\x66\x2a\x8f\x1c\xa5\x37\xa5\x47\x82\xbb\xd0\x06\xc1\x2e\x9e\x88\x38\x0e\xe4\xec\xa7\x57\x64\x21\x43\xe5\x4f\xb4\x33\xe6\xdd\x06\x70\xa6\x58\xb5\xeb\xb9\x47\x62\xd4\x3c\xd7\xe2\x44\xff\x0e\x65\x60\x55\xb1\xbb\xe8\xcf\x64\x58\x91\x1e\x36\x85\xed\x2c\x12\x90\x55\x57\xc1\x9c\x29\x39\xaf\x09\xb3\x2a\x63\x5a\xfc\xc8\x91\x27\xa9\x7c\xec\xfe\x6b\x26\x41\xd5\x8d\xd9\x76\xa8\xef\xba\xb8\x79\xa8\xc5\x27\x04\x87\x09\xfd\x29\xa0\x65\x3b\x47\xfc\x52\x22\x31\x08\x51\x72\x6a\xd0\x48\x3c\xae\xc4\xa9\x90\x79\x72\x8a\xc2\x20\x09\x1e\xb3\x69\x3b\xdb\x57\x4c\x1e\x25\x23\x32\x9b\x61\x89\x65\x25\x0b\xef\xa2\x02\xa6\x3c\x26\xee\xdf\xce\xd1\x23\x03\xb6\x1c\x57\x5e\x07\xb2\x62\x50\x48\x69\x2e\x74\xac\xb6\x2b\x7e\xbf\x7a\x50\xd2\x07\x09\xe0\x13\x3b\x15\xb7\x9a\x51\xd9\x45\x5f\x7f\x41\x0d\x05\x06\x01\xb7\x01\x5a\xbc\x19\xa6\x6c\x0e\xde\x64\xd1\x4f\x12\x64\x26\x4b\xbc\x27\x9d\x44\x3b\x84\x4b\x83\x73\xe1\xc5\xb7\xbc\x50\x6e\xd2\xb9\x31\x9c\x4d\x15\xa8\x20\x26\xef\xfe\xb9\x31\xbd\x53\x1b\x8d\x91\x71\xfd\x9e\x29\x00\x31\x94\xec\xdc\x89\x01\x86\x85\xa3\x98\x0a\xa3\xe0\x13\x6c\x8e\xee\x38\x61\xed\x28\xbd\x68\x08\xee\x33\x84\x64\xa3\x9e\x5f\x7d\x5b\xe3\x6b\xbc\xa9\xf4\x55\x24\x15\xb6\x3c\xa1\x9f\xa8\x26\x14\x9f\x9c\x4c\xb8\x94\x1e\x31\x8f\x59\x09\xbb\x6b\x68\x5b\x0b\x81\x7d\x27\xfd\x92\x1f\xa1\xc1\xa0\x35\x88\xfb\x0c\xbd\x1f\xdd\x6d\xdd\xa1\x3e\x8d\x91\x1a\x6e\xe6\x3b\x55\x8f\x0a\xb1\xd3\xe8\xc1\xec\x22\x09\x6f\xc0\x80\x39\x24\xa2\x73\xaf\xd1\x5b\x8d\x9f\xb4\xca\x63\xfc\x70\xf2\x55\xd0\xaa\x3a\x4b\xea\xa0\x84\x86\x69\xe9\x1a\x2f\xd9\x2a\x56\x56\x7a\x34\x89\xb5\x12\x5b\x1f\x1d\x1f\xd6\x85\x85\xa0\x18\x10\x4f\x63\x67\x4e\x0b\xa0\x09\x48\xde\xd8\xd8\xfd\xe2\xe2\xb1\x98\xea\x02\x87\xd8\xe6\x1e\xf2\x63\x64\x13\xf8\xb2\xee\xae\xc4\x57\x7e\x21\x96\x57\x9a\x0f\xe2\x32\xfa\xad\x9d\xe9\x4d\x5c\x24\x72\x3e\xc2\xb5\xb0\xb7\x24\xa9\xfc\xc8\x09\x29\xc4\x6e\x64\xbd\x80\xbe\xb9\x58\x8d\x0d\xd1\x71\x6d\x7d\xce\x54\x01\x4f\x52\xdf\x8b\x79\x18\x85\x16\xc4\x4c\x8c\x86\x0d\x2f\x71\x28\x98\xee\x24\xf0\x02\x6f\xa6\x8a\xe3\x08\xa4\x2b\xae\x05\x86\xe4\x93\x73\xd9\xa9\x68\xd0\x7e\xc1\x20\x6b\x61\xb4\x47\x9a\xbd\xa9\xfd\xa6\xe9\xaa\x28\x91\x5e\xe4\x8a\x5d\x91\xdc\xc2\x22\xae\xc0\x4c\x83\x4d\xa9\x27\xef\xb0\x71\x02\x14\x67\xc2\x1e\x9e\xf1\xab\x4a\x2b\x75\x07\xda\xe8\x63\x4d\x3e\x7a\x6b\x8f\x23\x6e\x30\x99\xce\xcd\xf2\xb9\x15\xa1\xe7\x5a\x96\x02\x98\xcd\xa7\x50\x8f\x61\x3d\x72\x35\x59\x4d\x91\x5f\xda\x7d\x54\x96\x13\x10\x16\xd2\xd7\x97\x31\x35\xd4\x9a\x8c\x33\xc7\x75\x54\x5c\x1e\x03\xf9\x75\x33\xed\xe6\x7c\x5d\xa0\xde\x29\x12\xe8\x17\xa2\x97\xe4\x02\x24\xe2\x65\x6d\xf3\x5a\x96\xc2\x22\x11\x62\xa1\x95\x64\x0d\x14\x9f\xa3\xb7\x7b\x66\x17\xd7\xa9\x63\xf0\xa0\x4a\x31\xe0\x92\x7e\xd5\x7c\x0e\x3d\x72\xe6\xad\x69\x1b\x0b\xdf\x65\x1f\xca\x73\xaa\xcd\xd8\xb0\x77\x5b\x27\xce\xb5\x75\xcf\x55\x37\x39\x07\x81\x1a\x65\xff\xec\xa0\xbd\x5c\x5c\xf4\xa6\x6f\xb1\x81\x40\xcc\x40\x5c\xb2\x42\x47\x62\x51\xcd\x10\xc5\xc4\xb5\xd0\xa4\x3c\x95\x9f\x82\x23\xf3\xfc\x2a\x5c\x5d\x11\xa9\x89\x9a\x08\xc3\xf8\x20\x62\xa9\x9c\x2e\x5c\x6c\x6d\x66\xea\x0e\x49\xf5\x8a\xee\x6d\x8d\x92\x0d\xb1\xab\x14\xf3\x52\x97\x3c\x06\x4c\xdd\x43\xbe\x52\xce\x95\xcd\x1c\xb2\xd4\x15\x7d\x86\x7a\x3d\x43\xa7\xda\x97\xf6\x05\x1b\x74\x74\x29\xc1\xe2\xc1\x01\x57\xfc\xc2\xbd\xf6\x19\x94\x14\x79\xb3\x78\xd4\x25\xa5\xde\x00\x07\x64\x30\x7d\x76\x88\xc1\x6c\x85\x74\x80\xed\xcf\x84\x87\xcd\x0e\xe6\x49\x9e\x50\x80\xeb\xb2\xc1\x06\x62\x47\x35\xb2\x59\x59\x43\x7b\xf6\x8d\xf6\xea\xe9\x7a\x52\xa6\x2e\xa3\x4b\x32\xc4\x3a\x16\x50\xd2\xd8\xf2\x9c\x6e\x8a\xdf\x01\x9a\x37\xd1\x20\x06\xab\x63\x34\x87\x36\xff\xd0\x33\x35\xd4\xa7\xfa\x0a\x8c\x80\x73\xe0\x19\xb6\x20\xb3\x34\x48\xd3\xc7\xf8\x66\x82\x61\x26\x87\xc1\x93\x2c\xdf\x61\xb7\x4b\x70\x4d\x46\x8d\x8a\xc0\xe8\x71\x16\xed\x6d\xc3\xa1\x40\x76\x39\xfe\x50\x7a\xe5\x6a\xf8\xcc\xf3\x56\x76\xe0\xa6\xd1\x07\xf2\x69\x17\xcf\x98\x69\xc1\xac\x45\xd3\x0f\xf2\x61\x8e\x91\xfd\xd6\x70\x79\x64\xd1\xf3\x3f\x9c\x7f\x67\x7f\xfb\x14\x5d\x53\x4d\x87\xb5\x80\xc2\x92\x49\x6d\x0d\x95\xe7\xcd\xa5\x17\x55\x6f\xc5\x76\x35\x77\xff\x85\x9f\x88\x9a\xed\x26\x0e\xfc\xc3\xc4\xde\x5a\x38\x12\x4e\x75\x3a\x78\xed\x9e\x20\x1f\x98\x4f\xf7\xde\x1a\x37\x21\xe7\x68\x9c\x8c\x99\xae\x6f\x51\xef\xe8\x43\x7f\xad\x26\x07\xc6\xa2\x67\x6f\xb5\x3b\x1b\xc7\x7d\x9a\x95\xc7\xf0\x5f\x07\xdb\x24\xee\x76\x52\x66\xe2\x6c\x12\x71\x6a\x3e\xcb\x57\x05\x64\x08\xf6\x64\xad\xb7\x60\xee\x9b\xea\x54\x44\xff\x8a\x22\xe1\x6f\x47\x91\x55\x71\xee\xe3\xeb\xba\x01\xd5\x71\x85\xdc\xc4\x02\x28\xc7\x26\xa3\xf8\xb5\x47\x97\xd2\x6d\x63\x36\x2c\x6a\x59\x4a\xb3\xf2\x01\x14\x79\xc8\xf9\xe7\xe0\x83\x69\x76\xea\x26\xee\x85\x92\xcd\xc9\xe7\xb2\xfd\xa4\x83\xf4\xce\x4d\x19\x36\x6e\x5a\x2a\x53\xee\xf0\x4b\x18\x67\xb5\xf9\x1e\xc8\xe5\x4e\x56\x1f\xac\x76\x02\x0b\x2e\x36\x89\xf3\xd8\x95\x87\x00\x24\x4d\xa7\xed\xc3\x13\x1e\x18\xaf\xa9\x53\x92\x4e\xd4\xa7\x81\x55\x83\x9e\xc7\x1d\xa0\x56\x8d\x0e\xf3\x46\xfa\xa6\xad\x2c\x5e\x87\xb2\xb7\xb4\x3e\x85\x46\xd1\x77\xa5\xde\xb1\x13\x5b\x47\xb4\x3c\x1f\x44\xba\xc7\xc8\x17\x8c\xfb\x11\x23\x74\x03\x7d\x1c\x7c\xc5\xcb\x37\xe0\x4c\x72\xb4\x61\x6e\xe8\x24\x25\x6e\xa4\x74\x03\xe7\xfb\xb1\xfd\x54\xa2\x2f\xab\x4e\x80\xcc\x20\xcb\x3b\x06\x95\xe5\xfe\x95\x86\xf2\x99\xe3\xb9\xc7\x17\x8f\xb6\x4e\x59\xb4\xff\x26\xe4\x68\xcf\xa7\xce\x59\x7f\x68\xfd\xe5\xc9\x68\x77\x4b\xa7\x03\x49\x18\x43\x2f\x81\xc3\xc3\xe0\x38\x14\xf4\x9a\x1e\x2c\x0e\xeb\xf0\x02\xff\x12\xa8\x9c\x34\xa3\x56\xac\x53\xae\x77\x45\xd3\xc1\xe0\xd1\x5a\x02\x43\x2b\xd5\xa9\xf4\x23\xbb\xa5\xc7\x90\x76\x7e\xa0\x69\x2e\xa1\xba\xeb\x94\x0d\xb1\xf7\xe6\x2d\x6f\x56\x6d\x25\x33\xff\x7c\xcd\x82\x7c\x25\x56\xd9\x15\x7d\x0f\x3a\x22\x6a\xad\x25\xb5\x7f\xf6\xf6\x24\xdf\xaa\x81\xae\x2b\xc5\xed\xb3\x49\x79\x44\x1e\xbd\x46\xe5\x20\xb6\xca\x1b\x06\x01\x8e\x20\xc6\x0b\x79\x4e\x69\x53\x0e\x88\xc3\x89\xd5\xf6\x3e\xdf\xa0\xda\x61\x0f\x6a\x18\xf0\xd3\x74\xd0\x9f\x3d\xa1\xc2\x99\x5e\x93\x12\xa3\x6c\x57\x72\x66\x4a\xa3\x41\xd8\x48\x3d\xd5\x37\x21\xe6\x6a\x9b\xf3\x7d\xa1\x2c\x32\x79\x55\xcb\xc0\x3b\x18\xe2\xb7\xd7\xb7\x5e\xe2\xe7\xb7\x48\x59\xc7\x6e\xd4\xd9\xb6\x55\x50\x06\x6d\x54\xbb\x57\x58\x02\x2c\xaa\x52\xe7\xa9\x4f\x23\x9e\x94\x43\xe2\x7e\x13\x49\xa1\x6d\xd0\x74\xaf\xc4\x9e\x93\x8b\xf3\x5e\x4e\x2f\x65\x9e\xf0\x74\x12\x7f\x5e\x1b\x8f\x9a\x58\x04\x2f\xfb\x8b\x0d\xf8\x33\x43\xd9\xe4\x9b\x01\x65\xb2\x10\xa6\xeb\x4d\x72\x09\xf8\x05\x3a\xa2\xda\x9b\x57\x2c\xb8\x90\xb8\xfa\x85\x03\x26\x5f\x2d\x94\x21\xb0\x59\xfb\x76\xb3\xfb\x8d\x00\xe2\xfe\xf5\x82\xe4\x82\x54\x0f\xcb\xb8\xc4\xc3\xcb\x82\xd4\x92\x9f\xf5\x05\x38\xad\x80\x3a\x1f\x62\xf3\x87\x36\x3f\x27\x5c\xea\x30\xc7\x93\xe4\x5c\x5d\xe3\x2f\xd5\x20\x79\x88\xf3\x56\x48\xcc\xb6\x5f\x6d\x26\x4c\x41\x42\x7c\x76\xab\x50\x01\xff\x26\x3b\x44\x5b\x67\x5c\xd3\x4c\xaf\xc0\x75\xdd\x6e\x6f\x2e\x6e\x91\xd8\x8d\x64\xbd\x3f\x16\xd1\x5c\x9c\xe7\x6d\x5f\xae\x28\x02\xa2\x3e\x24\x77\x9c\x2a\xc6\xc6\xdf\x5f\x88\xf9\x1d\x81\xb1\x7b\xee\x36\x9b\x0b\xe3\x05\x51\x8a\x90\xab\x8e\x76\xdc\x38\x8b\x01\x54\x95\xde\x9d\x5d\xb7\x0a\xd0\x00\xe2\x44\x4f\xb3\x24\x1a\x1e\xe6\x45\x6a\x08\x4a\x22\x71\x39\xdc\x4c\x3b\xb8\x8e\xae\x78\xe0\x58\xcd\xfb\xf2\xb0\x03\x92\x50\xd2\xa6\xbe\x1d\x35\x8b\x43\x81\x40\xe9\x3f\x4e\x39\x95\x1d\x4d\x15\x4c\xfd\x53\x49\xd9\x08\xf0\x00\x2b\xc1\x03\x82\x4a\x93\xaa\x2b\xc3\x1f\x83\x85\x05\x8a\x44\xf6\xe1\xc0\xe1\x4d\x71\x02\x6c\x8a\x31\x71\x41\x93\x8c\x95\x7d\x22\xda\x80\xe6\x3a\xb7\x1b\x6a\x5c\x4d\xeb\xa8\xce\xca\x6d\xf1\xc5\x81\x36\x12\x4b\x42\x5e\x68\x09\x95\xba\x6e\x0b\x95\xb3\x4f\x5c\x13\xad\x4c\xe0\x8b\xf9\x20\xff\x23\x50\x23\xfb\x40\x17\x6c\x0e\x3f\x18\x39\xb4\x17\xdf\xe5\x3d\x0d\x51\xbe\x9d\x14\x91\x8f\xcf\xe3\x55\x55\x49\xa2\x00\x56\x8a\x07\xaf\xe6\xf7\x7f\x98\x18\x08\xf9\x3e\x61\xc8\x11\x40\x80\x04\x5b\xa3\xa7\x23\x72\xcb\x5c\xab\x1d\xe3\xe3\x19\x00\x7e\x58\x8f\x9e\x94\xec\x43\xbe\x85\xab\x85\xd8\x5c\x72\x80\x08\x55\x65\x8d\xed\xab\x9f\x39\x81\x59\x7e\x7e\x25\x8c\x95\x8e\x81\x03\xff\x1d\x9b\xf9\x32\x2d\x20\x8c\x37\xb0\x36\x03\x8b\x4c\xad\x11\x05\x18\xf2\x98\xdc\xaf\xe8\x10\xb1\x88\x3e\x68\xe8\x9d\xf2\xbf\x65\x30\x35\xb8\x41\x99\x92\x6e\x1b\x35\x22\xda\x57\xbd\x94\x3a\x30\x92\x61\xbb\x9d\xa9\x7a\x66\x20\x02\x58\x32\x6b\x77\x0d\x24\x5d\xd5\x6e\x06\xf9\x55\x87\xc3\x93\x1e\x9e\xa9\x81\x20\x51\x21\xc2\xc3\x9c\x89\x78\xb2\x66\x9a\x3d\x9c\xca\xa3\x41\x21\x8b\xdd\x48\xa0\x77\x14\xc0\x19\x11\x9e\x7d\xeb\x3e\x73\x35\x3b\xd8\xc2\x72\x03\x37\xf1\x73\xb2\xb3\xbc\xee\x2e\x1c\xa2\xa2\x05\xe6\x25\x94\x17\x9b\xa2\xe9\x64\x55\x60\x09\x2a\xba\x0f\x36\x94\x38\xf9\xdd\x51\x68\x4f\x2f\xb5\x32\x76\x78\x3f\x7a\xa8\x4e\xb1\xd7\xd4\x17\xc6\xec\x83\x83\x6d\x52\xcb\x1c\x23\x8a\xce\xcf\xe9\x6f\x86\x4e\xaf\x51\xff\x6c\xe3\xb9\x90\xa5\xaf\xb3\xbc\xf2\x77\x7c\xa8\x2a\x4b\x90\x3b\xe3\x53\x3c\xdb\x97\x47\x21\x81\x5d\xc5\x84\x80\x8a\x33\x7b\xe9\x08\x9c\x87\x12\x2d\x19\x23\x9f\x72\xcb\x3d\xe8\x95\x58\x8b\xe3\x5d\x94\x91\xc9\x59\xc9\xc7\x2c\x79\x7f\x42\x40\xb9\xe8\xb0\x3b\x58\xb6\x1a\x38\xa4\x57\x7b\x34\x70\xaf\x4e\x5e\x3e\x55\xdc\x81\xe0\x4e\x56\x02\x26\x65\xb6\x20\x91\xb8\x93\x7d\xeb\xb2\xb4\x12\xae\xb7\x41\xb6\x41\x2b\xc6\x50\xd6\x26\x71\xb3\xfa\x98\xe2\xf4\x13\x60\xa4\x56\x15\x43\xa6\x81\xe3\x96\x46\xde\xbe\xd9\xf1\x87\x79\x04\xe6\xb3\xab\xcb\xcf\xe2\xee\x67\x8e\xc2\xd3\xe4\x74\xd4\xb4\xfb\x9f\x0b\x33\xb1\x2f\x4e\x25\x53\x4f\xfc\xf7\x2b\x36\xab\x24\x28\x0c\xcf\x4d\x36\x18\x0f\xe3\xe5\x7d\xf4\xb1\x46\x40\x50\xfa\xb1\x06\x7b\xce\x83\x90\x7d\xf1\x86\x96\xcd\x95\x7a\x55\x00\x88\xf3\xc2\x4c\x11\xc9\xa2\xcd\x7e\x20\xb6\xc1\x8c\x1b\x33\x6b\x2a\x8a\xe3\x2c\xbc\xcb\xb9\x55\x47\xa1\x4f\x38\x6c\x38\xdb\xe4\x6c\xa9\xbd\x13\xc6\xe3\x87\xac\x15\x85\xea\xd5\xda\xe9\x2c\x43\x95\x90\x1c\xf4\x57\xe4\xe8\xe2\xd5\x9d\x9d\x1f\xb5\x29\xc3\x4b\x5f\x87\x93\x3d\xe3\xf2\xa5\x00\x54\x94\xdf\x95\xaf\xcf\xbe\xb2\xae\x51\x31\xb2\x7a\x54\xa4\xb5\xf6\x45\x35\x6b\x50\xaa\xe4\x40\xee\xae\xb4\x24\xbe\x20\x68\x30\x0c\x40\x2a\x65\x6a\x7d\xbf\x55\x68\x9f\x72\xdb\x4c\x8c\x25\x36\x8a\x63\x92\x95\xb6\x61\xca\x4e\x18\x4d\x80\xed\x3f\x77\x5c\x9c\x22\x18\x9d\x26\xdf\xc4\x51\x25\xe6\xa3\x8c\xc8\x74\x62\xad\xbc\x8c\x41\x06\x5a\x77\x64\x57\xbd\xde\x00\x57\xbc\xf9\x0d\xe0\x03\x2b\x15\xc0\xa2\x55\x95\xfc\xb2\x28\xb6\xb0\x26\x28\x61\xc6\x4c\xfa\x0a\x15\x7b\x21\x9c\x7b\x90\xb2\x92\xdd\x9b\xc0\xf6\xa8\x54\x3e\xce\xf2\xfb\x4f\x91\xf2\xcb\x4c\x76\x99\x4d\xf2\x01\xb6\xb0\x8e\xd2\xd6\xca\x79\xd9\x4a\xb5\xcf\x4e\x2e\xd4\x2b\xcd\xa6\xb9\x43\x9b\xcb\x38\x2a\x27\x0d\x2b\xb3\x84\x0f\x2d\x0c\x5d\xa7\xdc\x9c\xce\x4e\x09\x0c\xf2\xed\x37\x27\x8b\x46\x12\x4a\xef\xcf\xe8\xe0\xb9\xb5\xa3\x8a\x0d\x99\x80\x51\x55\xce\x40\xfd\x87\x7e\xa9\x9e\x19\x3c\xc4\xf2\xd5\xc0\xad\x11\x91\x92\xfc\xd3\xc6\x71\xcd\x92\xc8\x2b\x63\xca\x6c\x37\x18\xae\xb6\x40\x1f\xba\x5b\xbf\x66\x47\xe0\xe4\xbe\xa8\xb2\x1a\x66\xc6\xbf\x0e\x37\x5b\xef\x11\x39\x1a\x38\x19\x3a\xf0\x11\x56\x24\xfe\xc4\xce\x64\xe0\x17\xa9\x91\xcb\x5c\x7b\x05\x58\xf3\x01\x26\xa0\x45\x3e\x9f\x57\x66\x1b\x21\xd2\xea\xa0\xb2\xb6\x8d\xb3\xdb\x1f\x0b\x18\x3b\x26\x20\x9f\xdc\x09\x28\xb6\x3b\x45\x68\xe1\x9a\xca\xc7\xa3\x9c\xbe\x7c\x6b\xbb\xf8\xd6\xfd\x71\x1e\x91\x6a\x44\xa1\x04\xfe\xf6\xa6\x43\x65\x65\x4c\x63\x3e\x86\x18\x9c\xa1\xa8\x9f\xda\x49\xbc\xb1\xf9\xec\xc3\x16\x5c\xf6\x5b\x35\xef\xb5\xf1\xd4\x0e\x2e\xd5\x8f\x90\x40\x17\xb6\x2b\x89\xa5\xfe\xaf\x83\xfd\x0a\x84\xc5\x8e\x26\xa7\xdd\xe9\xf4\xbc\x03\xbb\x94\x7d\x26\x51\xf6\xb6\x8d\x1c\xc9\x2d\x7f\x51\xf4\x16\x34\xff\xad\x70\xf9\x38\xdd\x6a\x53\x66\x80\x2d\x53\xf7\x2d\x8a\xff\xcc\x75\xc5\xd7\x40\xb2\x3a\x57\xdf\xa4\x48\x7c\xe2\x04\xdb\x59\x51\x53\xb5\x07\xb3\x1a\x0a\xa2\x3f\x1d\x46\x4d\xe5\x2d\x9f\x30\xa3\xa9\x84\x1b\x5f\x0d\xe6\x69\x6b\xc5\xf9\x77\x9f\xcd\xe1\x74\xf2\xd6\x8f\xea\x27\xf7\x4b\x38\x6c\xe4\x36\xb5\x21\x2e\x1e\x28\x9f\xa9\x41\x15\x96\x4d\xb1\x11\x24\x46\xa8\x8a\xcc\xab\xb2\x78\x38\x43\x24\x51\x77\x50\x4c\x55\x40\x2b\xc1\xa8\x58\x27\x79\x8d\x2d\x71\x88\xfa\xcb\x55\x34\xcf\xca\xce\x29\x45\xda\xf0\x40\x5a\xa5\x46\x03\x9a\x97\x97\x9f\xe8\x35\x93\x1b\x1f\x51\x0b\xa3\xb0\xb6\xf1\x23\x2d\x56\x28\x95\x63\x4c\x75\x01\x08\x14\xea\x35\x7b\x52\xf2\xa7\xc8\xee\xd9\x28\x05\x93\x40\xf7\xa8\xda\xf3\x4d\xf1\x17\xbe\xe8\x53\x59\x48\x4c\xd0\x84\x90\x9a\x7f\x41\xf3\x0b\x54\xab\x01\x2a\x71\xae\xee\x18\x96\xa7\x14\x04\x42\x23\xcb\xe0\x40\x28\xc4\xed\xfd\x89\x9e\x14\x29\x53\xeb\x4b\xcf\xca\xa5\xb3\xab\x3e\x79\x15\x5e\x75\x59\xfc\x94\xab\x6d\xeb\xac\x2d\xd6\xc3\x3a\x21\x1f\xd0\x7b\x27\x41\x50\x13\x27\xb3\x23\x27\x4d\xb3\xa6\x7e\xc8\xdd\xb5\x8d\xc2\x92\x47\xfd\x54\xa5\x9f\x91\x41\xe8\x74\x19\x33\x34\x0c\xef\x95\x8b\x8d\x3c\xea\x5d\x87\x4c\x44\xf4\x7e\xf7\x77\x66\x52\x4b\xfd\x82\x11\xee\x99\x40\xc4\x8c\x7e\xca\xad\x80\x5d\x2c\x26\xfa\x4f\x70\x6f\x0d\xfc\x34\xd3\xef\xdd\x7b\xe4\xef\xf1\x03\xde\x63\x01\x25\x2a\x09\x6f\xc4\x47\x83\xbb\x30\xa0\xd5\x67\x47\xe0\xff\xe4\x90\x5d\x8b\x19\x2d\xca\x93\xff\xda\x2d\xa9\xbc\x66\xb3\xea\xa7\xbb\x44\xa2\x4b\xc6\x2b\x0b\xbc\x23\x59\x72\x88\x52\x5b\x52\xf8\xa5\x75\xac\xe8\x2f\xfc\x92\x1a\x96\x08\x0e\x8a\xdb\xf4\xb3\x77\x43\xdc\x9d\x44\x63\x09\x44\xfe\x79\x45\xfb\x8a\xbc\x2b\x01\x2a\xd0\x36\xe9\xcc\x35\x53\x19\xca\xeb\x00\x2c\xd6\x21\xcf\xdb\x44\x1c\x51\x1f\xa6\xfa\x91\xfb\xd5\x7f\x66\x9e\xb8\x56\x55\xc7\xc7\x99\x53\xad\xd1\xf5\x56\x7d\x96\xcb\x59\xa8\x9d\xf7\xcf\xd5\x1a\xfd\x92\x9b\x80\x9b\x43\x94\x62\x80\xe8\x31\xbe\x53\x79\x73\x84\x38\x42\x76\x82\x86\x49\x0d\xa1\xd8\x3e\xd2\xb0\xc8\x29\xf3\x26\x61\x5a\x39\xd9\xac\x78\xc3\xeb\xef\x2f\x06\x32\x8c\x2e\xdb\xaf\x6e\xb5\x69\x48\xd9\x46\xe9\x8c\x18\xbb\x9c\x2c\x30\x99\xac\xa0\x43\x41\xec\x85\x96\x2c\x06\x93\xf0\x38\x49\x40\x8b\x1a\xe4\xf3\xa8\xd2\x04\xb7\x8e\xd3\x2e\xcb\xbc\xff\x09\x29\xb3\x03\x6a\xa4\x94\xa4\x3f\x83\x56\xa6\xf4\x37\xfa\xe4\xf4\xb2\x29\x6c\xa0\x07\xca\x36\x4d\xd5\xc3\x46\x87\xc2\x3f\x65\x63\x10\xc5\xbb\x72\x3b\x8b\xe1\x86\x4a\x33\xea\x5a\x5a\x5b\x09\x0f\x0a\xb3\x80\x3c\xde\xef\x6b\x73\x75\x0c\x3a\xfc\xb4\x17\x1c\x0d\x26\xe2\x26\xcb\x35\xc4\xf5\x87\xaf\xb6\xd1\x0e\xe4\x66\x51\x9c\x44\xb6\x7a\x4e\x9c\x01\x2f\x07\x9d\x02\x9c\xce\xef\xcc\xdd\xa8\xbd\x85\xd0\x46\xfa\x65\x75\x96\xca\x08\xa6\x2b\x3a\x5a\xb8\x00\x71\x9a\xbe\x76\x19\xa5\x98\x85\xd8\x72\xbd\xdb\xf7\xf6\x71\xd6\x7b\xa9\x08\x85\x9e\x92\xaa\xd9\x07\x68\x58\xe2\x51\xd3\xd2\xe5\x82\xdf\x63\xee\x24\xac\x69\x2d\x5e\x65\x91\x10\x1e\x49\x80\x91\x9b\x89\xe8\x99\x8a\x45\x44\x2c\x55\x6f\x09\x18\x80\x36\x87\xad\xb0\xed\xdd\xc5\xb9\x8c\xfc\x45\x54\x23\xbe\xb9\x6d\x9a\x24\x0c\x77\xf7\x1d\x7e\xed\x8a\xda\xdf\xd2\x85\xe6\x1d\xa4\x6d\xdc\x2e\x0d\x14\xd1\x0e\xf8\x0a\x33\x65\x8f\x6f\xda\xfd\xd6\x97\xa5\xdf\x23\x05\x77\xb9\x80\xbb\x94\x8b\x14\xc8\xb7\x23\x2c\xf6\xe1\x08\x1e\x4e\x70\x7b\x4c\xaa\x7f\xf0\x05\x26\x40\xad\xd5\x24\xcd\x1e\x9e\x64\xa8\x95\x50\x31\x05\x63\x0e\x98\xe4\x1a\x50\xd8\xa7\x42\xc0\x00\x62\x2d\x7d\x84\xf9\x2c\x20\x07\xb4\xdb\xe5\x13\xb2\xcf\x99\xda\x23\x8b\xd8\xb2\x17\xbc\x5b\x3a\x1c\xed\x2b\x5c\x0b\x5f\xa8\x9a\x67\xe4\x10\x95\x17\xef\xe2\x9d\x7d\xa2\x7e\x1a\xf5\x19\x17\xe6\xe8\x3e\x97\xf9\x99\x03\x7b\x8c\xc5\x2b\x20\x62\x95\x68\x36\x11\xe1\x93\xcb\x9a\xb8\xd0\xca\x47\xf7\xc4\x6b\xe9\x4f\x79\xb3\x93\x08\x4c\x23\xa3\x64\x19\xba\xec\x33\x04\xcd\x8c\x10\xf6\x60\x49\x8d\xc2\x64\x95\x65\x35\xb6\x75\x7d\x4a\xdb\xc0\x91\x33\x9f\x0a\x34\x25\x22\x9c\x35\x9d\xd2\x7e\x33\x35\x9f\x37\xc2\x8a\xd9\xf1\x45\x5e\x25\xd5\xb3\xfc\x78\xcd\x81\x79\x4e\x63\x74\xd2\x36\xa4\xe2\xd5\x26\x36\xd8\x26\x6e\x8c\xac\xa3\x2c\x99\x6d\xce\x89\x64\x84\xa9\x76\x27\xb7\xe3\x14\x47\x12\x4d\x9c\x43\xee\xa9\x9b\xd4\x6b\x63\xbb\x24\x0a\x11\xf6\x65\x34\xaf\x0a\x3b\x3b\x67\x24\x42\x4a\x4d\x29\x64\xe7\xd0\x39\xc6\xf4\x03\xaa\x88\x04\x90\x17\x6e\x6b\x78\xaa\x34\x7a\xa0\x15\x9e\x20\x40\xf1\x13\x9c\x7a\x1f\x03\xef\x65\xf3\x76\x70\x58\xdb\x30\x04\xb3\x13\xaa\x0d\x5a\x14\x45\x89\x22\x0d\x1b\xbb\x7a\xd1\x72\xf9\xa0\xe1\x4a\x2d\x2a\x22\xa2\xbe\x31\xc4\x84\xc3\x9f\xcb\x84\xd1\xc4\x8a\x37\x53\x8e\x69\xfa\x20\xae\x32\x63\xeb\xa2\x0c\x23\x47\x9a\x12\xef\x81\xce\x54\x43\xa5\x74\xed\xde\x79\x73\xe0\x9e\x85\x19\x1f\xff\xe9\x40\xd5\x3c\x6c\x7f\xa7\x95\xa3\x4e\xde\x31\xb2\xf2\xf3\x4a\x4b\x85\x9f\x79\xe9\x38\x76\xd6\x4b\x49\x73\x93\x9b\x68\xfd\x1e\x6d\x4b\xae\xd7\xa4\xca\x57\x0c\x83\x7c\x6b\x54\x80\x5c\x47\x28\x06\x12\xab\xd4\x00\xda\xba\x96\x86\xda\xd6\x99\xc8\xc3\x3b\xc7\xb0\x7f\x4f\x70\xb4\x32\x7a\x8e\xaf\x48\xb1\xd0\x38\x75\xe8\xc2\xcc\x3a\x2b\xe2\x74\xb0\x79\x4c\x39\x52\x84\x86\x15\xf0\xc0\x53\xa5\xa4\x65\x40\x66\x9a\xd8\xd8\x76\x9a\xe5\x57\x3e\x3f\x3d\x6a\xad\xac\x88\x93\x86\x27\xa1\x10\x02\x21\x6b\x00\x5a\xdf\xbc\xc4\x34\xc6\xfa\xd2\xec\xc0\x56\x6d\x3c\x58\xde\xa7\x05\xa0\x0f\x0a\xbb\x47\x0a\xbb\x9b\x2c\x83\xdd\xc3\x72\x96\x67\x25\x1c\xd1\x2c\xc3\xe4\xc4\x07\xaf\x70\xcc\x5e\xa4\x33\x45\x00\x90\x7a\x6d\x13\x41\x06\x52\x9e\xe4\x9c\x10\x08\x1d\x7d\x49\x20\x8c\x8b\x1d\x78\xb1\x54\xda\xc6\x00\x51\xef\xc6\xbe\x7d\x2c\x89\x7a\x44\x90\x33\x39\x89\xa2\x79\x3e\xa4\x60\x33\x89\x71\x2c\x0a\x57\x6c\xad\x24\x15\x07\xb3\x0b\x50\x13\x74\xdf\x98\xc6\x1b\x7f\x03\x88\x4c\x86\xd0\xf0\x21\xee\x7f\x9a\x86\x92\xbb\xe9\x7f\xda\xd7\x14\x52\x97\x2f\x96\x82\x4d\xf9\x14\xa0\x46\x2a\x2a\xe6\x5d\xef\x3a\x40\x16\x8a\x93\x62\x82\x90\xd2\x2d\x85\xb9\xb0\x29\x73\x3e\x4c\xf9\x95\xc8\x9f\x26\xbf\xb6\x50\x3f\xe9\x0f\x7d\x53\xfb\x3f\xbf\x0d\xd1\x53\x60\x3f\xf8\x77\x40\x28\x8a\x3d\x0a\xb0\x2d\x70\xe2\x9c\x76\xf2\x80\x4a\xc5\x37\xbf\x41\x84\x94\x5c\x7a\x3c\xba\x18\xca\x13\xc0\x8e\xca\x43\xa1\xeb\xad\x5f\x95\x1d\xe5\x57\x8a\xa0\xbd\x2e\x3e\x18\x71\xce\x3e\xbf\x4c\x8b\x01\x2e\x2b\xe0\x75\x55\xe5\x40\xc3\x2b\xda\xc9\x75\xba\x33\x1d\xc1\x4b\xbb\x44\x2d\xae\x1d\xfa\xe1\x37\xe9\x2a\xb7\x37\xaf\xdf\x61\x0f\x6a\x85\xcc\x6f\xea\x9f\x21\xbf\x0e\x1b\xd3\x4e\x6a\x5f\x6e\xde\x75\x53\xa8\x40\x65\x38\x86\xdd\x82\xab\x38\xd1\x1b\xda\xec\xd1\xbf\x7a\x18\x15\x0c\x74\x8c\x4b\x7b\xb3\xf8\xc5\x0e\xf0\x83\x1a\xea\x59\x92\x1d\xfb\xd9\xf3\x6f\xa5\xf0\x48\xcb\x4e\xfd\xa4\xe8\x12\xe5\x3a\x20\x1f\x2a\xac\x12\xfe\x5f\xf8\x20\x94\x83\x16\x24\x32\x4e\x99\xc8\xac\x62\xef\x27\x07\xfa\x25\x96\xe5\x3c\x3f\xc1\xff\xaf\xfd\xb2\x2b\xa1\xc2\x0f\x43\x8c\x40\x2e\xe5\x90\x32\xea\xd9\x00\x42\x55\x6b\x86\x7d\xb1\x59\x88\xf8\x8a\xd3\x5d\x6d\x30\x9b\xf7\xc8\x13\xcf\x14\xaf\xf9\xe1\x5d\x05\xd6\x34\x40\x96\x25\x7a\xcb\x91\x76\xd2\xbb\x82\x3f\xca\xa4\x5d\x05\x8b\x51\x29\xb2\x9b\x04\x9e\x25\xda\x16\x4e\x2c\xa2\xa2\xbb\x0c\x9c\xd2\x60\x63\x87\x4a\xa6\x64\xe1\xdb\xab\x64\x22\x44\x73\x6c\xac\xd3\xa8\x40\x90\x66\xd5\xd4\x5c\x8d\xce\x59\x34\x6c\x55\x88\xec\x7f\x5b\xd8\x55\x65\x99\x5c\xab\x00\x63\x71\x41\x4d\xe9\x74\xf9\x2a\xcc\x5c\x60\x47\x64\xce\x2d\x5c\xf6\x95\x37\xad\x81\x60\xaa\xd7\x99\xbc\x56\x67\x16\xf0\x96\xc2\xda\xa2\xa5\x55\xec\x2a\x65\x8a\xa1\xb7\x46\x95\x54\xd5\xd7\xc1\x7f\x41\xe8\x0a\xdd\x1b\xf5\x77\x1c\x4a\xed\x28\xa5\xdd\x45\xde\x68\x7d\x81\xe8\x0a\x58\xb3\x1f\x4a\x31\xad\x63\xcc\xcf\x53\xb5\x1f\xe0\x4d\xd9\xc1\xb1\xa4\x2f\x70\xb0\x04\x17\x8d\xa9\xe2\xbe\xfe\x94\x23\x28\x24\x69\xe3\x7f\x3d\xd4\x1d\xd9\x27\x6a\xfd\x5f\x92\xaf\x62\xb7\x43\xfd\x03\x3c\x6b\x10\xc3\x26\xf8\x7a\x08\x1d\xe9\x4f\xfe\x2a\xb7\x8d\x43\x40\x16\x96\xba\x65\xf3\x86\xec\x1d\x94\x81\x1f\x94\xda\xc5\x2e\x27\x2f\x7e\x1a\x57\xd9\xd2\x89\x5e\xff\xeb\x6c\xd2\xb9\xd1\x68\xae\xb2\x29\x64\x69\xb3\xc6\xf1\x0e\xb6\x0f\xad\x8f\x0d\x66\x41\x4a\x1c\xe5\x49\x14\x2c\xdc\x10\xaa\xf5\x51\x55\xb9\xc0\xdb\x25\x4a\xbd\x67\xe7\x78\xed\xf6\xaa\x66\x0c\xbb\xfb\xe8\x2d\x99\x31\xb6\x89\x9e\x63\x12\x52\xf0\xde\x39\x4a\xf7\xea\x05\xb5\xd6\x9e\x6f\xca\xa1\x81\x27\x9e\x08\x2d\xa9\x0b\x7a\x3e\xb4\xb0\x6d\x5e\xad\x57\xe8\xac\x9c\x4a\x72\xe3\x7c\x70\xd5\x50\xe3\x10\xc4\x1c\xd0\xe0\x13\x5a\x1a\x7a\xcf\x15\xa1\xbf\x7c\x95\x01\xa5\x4a\xa0\x73\x6d\x08\x73\x34\xa9\x01\x9d\x88\x2a\x1d\x71\x10\x4e\xa6\xc8\x82\x92\x82\x43\xd8\x49\x53\xd8\x7d\x18\x24\x44\x01\x3e\xa3\xed\xc1\x16\xe8\x04\xf6\x07\xa7\x50\xa3\x22\xcb\x72\x2c\xeb\x94\x36\x38\x09\xb3\x61\x9b\xa3\x9b\xe6\x21\xb5\xc1\x87\x56\xb6\x16\x26\x29\x3a\xd9\xc6\x54\x54\x1f\x26\x57\xb5\x22\x2c\xbb\xba\x1c\x63\x84\xae\x97\xb6\xff\x1a\x8b\x76\x83\xe1\x3c\xb5\x33\x13\x3a\xbc\x87\x16\xc5\x92\xdf\x45\x70\x2f\xbf\xc3\xff\x24\xb7\x47\xae\xc8\xc5\x27\xa3\xe9\xc7\xa7\x1e\x6c\xa4\x0c\x6d\x92\x5f\xd9\x76\x95\x6f\x0f\x87\x09\xbe\xa3\x5d\x59\xff\xb0\x8b\xa1\x35\x6f\xc3\x3d\x41\x12\x1a\xf5\x6a\xb1\xac\xd0\x48\x48\xa6\xee\xe2\x72\x33\x49\xad\x8f\x5d\xbf\x95\xda\xdd\xd0\x23\x71\x47\xab\x37\x9e\x12\x9a\x9e\x64\x68\x97\x33\xf6\x1f\xa1\xde\x5c\xc3\xd3\xa9\xcf\x63\xf6\x2d\x3f\x55\x4e\xc1\x10\x59\xfb\x16\xce\xbd\x31\x58\xf6\xe0\x43\xf4\xe0\xa4\x4a\x97\xcb\xd5\xaa\x3a\xe7\x97\xae\x67\xf3\xe1\x8d\xc9\x7a\x12\x26\x57\x9b\xfa\xb4\x5b\x07\xda\xb9\xd6\xca\x9c\x0e\xe8\xf3\xf6\x3a\xdd\x2a\xff\x1b\x51\xc0\x11\xaf\xe7\x23\x92\xe4\xe0\xba\xa8\x2b\xe7\xf2\x7d\x67\x00\x8f\x3a\x91\x21\x46\x73\xed\x66\x8c\x63\x82\xf5\xbc\x74\x8a\x0f\xe8\x28\xf4\x90\x54\x0a\x3b\xca\xdb\x8d\x70\xc8\x6c\xa9\x70\x89\xa6\xe4\x92\xd2\xc7\x57\x62\x5c\xfb\xfb\x9c\xbc\xf6\x15\x23\xcc\xe0\x5b\xa7\x3f\x03\xc7\x69\x86\xbd\x71\x2f\xc7\x0b\x7d\x1b\x39\xa8\x04\x91\x59\x65\x49\xda\x2a\x32\x56\x89\xe7\x03\xb2\x58\xba\xa0\xf4\x42\x41\xb8\xc7\xc9\x73\xd9\x65\x65\xc1\x79\x0b\x43\x2c\x42\xc2\x4f\xb3\xc0\xa6\x93\x89\x22\x4d\x67\xbf\xbb\x84\xf3\x34\xcb\x3e\xd0\x6c\x19\xf0\xd3\x32\xba\x6f\x96\xe8\x5b\xa6\x2d\xf0\xec\x23\x92\x6b\xe8\xea\x88\x4e\x7c\x51\x9f\xca\x48\x58\x85\x4c\x31\x8a\xa4\x74\xad\x00\x80\x5c\x08\x61\xa7\x09\xad\x54\x3a\xb5\x79\x1e\xd1\xf0\xa8\x0e\xbe\x03\x86\xb2\xbe\xd0\xd0\x75\x7f\x50\x5d\x23\x74\xe8\x7d\xd6\xed\x3d\xae\x74\xf7\xa1\x39\xe1\x7c\x52\xb5\x53\xb5\x5b\x48\xbc\x6c\xd9\x25\x49\x5b\xba\xd0\xe5\xda\x60\x9a\x95\x48\xc2\x6a\x27\xd4\x12\x15\x45\xfa\x77\x86\x8f\x4b\x5b\xd8\x46\x2b\x77\x03\x85\x0d\xf6\x9b\xf4\xfc\x62\x81\x1a\x44\x8e\x2b\x9e\x3e\xaa\xef\x4c\x2a\x1c\x68\x47\x41\xdb\x8b\x11\x39\x3d\x43\x1d\xc0\x61\x77\xc9\x14\x94\xe8\x02\xd9\x02\x61\xad\xdd\x5d\xc0\xe6\xc8\x30\x78\x46\x39\xf8\xb4\x97\x1f\xf1\x28\x6c\xda\x01\x19\x38\xff\x3a\xe5\x83\x8d\xe6\x09\xa6\xc1\xbb\x6b\xe5\x8f\x02\x07\x5d\x13\x69\xf0\xf2\x28\x6c\x66\x95\x50\x98\x02\x10\x0e\xe6\xca\x17\x63\x06\xc8\x02\x2d\x84\x37\xd2\x1c\x37\xfd\x9a\xa4\xbf\x10\xed\x8b\x7b\x70\x45\xcc\x62\x9a\x30\x8f\x01\x4c\x01\x67\xf4\x0e\x65\x2d\xb4\xb2\xe3\xb3\x57\xf2\xea\x6d\xc6\xe7\x90\xad\x19\xbd\x00\xda\x8e\x49\xaa\x54\xe8\x9e\x9b\xe9\x25\x20\x2e\xe1\xf9\xd8\xad\xcf\x13\x90\x14\x49\xe8\xb1\xa2\xde\x92\x39\x73\xa3\xf5\xe4\x53\x53\x83\x47\xa7\xcd\xb8\x48\xcc\x75\x73\xe7\x64\x96\x4b\x03\x40\x83\xed\x93\x49\x79\xeb\xe3\x88\x95\xa2\x3a\xbb\xa1\x7e\xd6\x31\x60\xb3\x1d\xe0\xb9\x9f\x4f\x44\x46\x47\xbc\x25\x20\x7e\x22\xf0\x8a\xfb\x98\xf6\x11\x07\x8b\xd5\x87\xd8\x9a\xd6\x89\x13\x5a\x55\x10\x17\xed\xb9\x95\xa3\x2f\xb3\x26\x44\x68\xc2\xd0\xa6\x62\x34\x64\xec\x20\x92\xee\xcc\x2e\xe4\xb2\x6b\xec\xf5\xa7\xfd\x73\x2b\xef\x5f\x94\x05\x94\x0f\xe9\x71\xb4\x2a\x0f\xb8\x54\x88\xf6\x2f\x02\x31\xc1\x24\x35\x8b\x6f\xd7\xde\x46\x69\x31\x7a\x2b\xc7\x00\xfc\x57\x5b\xf4\x07\x5a\x7d\x31\xfe\x4a\x32\x28\xc4\x8b\x18\x7e\xab\x5f\x7c\x2b\x60\xca\xcb\x67\x33\x9f\x0e\x72\xa5\x1e\xe7\x41\xe0\x42\xe2\xee\xd0\x90\x58\x4d\x63\x5e\x84\x26\xf1\x0b\xec\xdb\x34\xd2\x1a\x7d\x4e\x16\x0e\xe6\xbd\x71\x02\xb6\xbe\x28\x63\x98\xc9\xe7\x22\x4e\x61\x8c\xc4\x27\x81\x53\x75\x35\x18\xc4\x95\x7a\xbb\x9f\xb8\xc7\x4c\x60\x63\x61\x65\xb9\x96\x96\x2a\xaa\xe9\x28\xb7\xcf\xc9\x5e\x8d\xf8\xd7\xbe\xb3\x82\x8c\x43\x37\xbe\x0e\x07\xdb\x26\xa0\xf3\xd2\xa2\x73\x57\x66\x6b\x2c\x80\x90\x89\xcd\x97\x83\xa9\x40\x27\x71\xb9\x37\xc7\xf4\x34\x7c\xb0\xe5\xbc\x86\xe0\xb9\x29\xbd\x3b\xc2\x12\xcf\xa1\x86\x5d\x09\x5a\x5d\xda\x24\x66\x87\x8f\x1d\xa0\xaa\x60\xe0\x32\xb7\xab\x33\xca\x0b\x59\xd1\x12\xf4\x92\x15\xcd\xb1\xe6\x8a\xa5\xdb\x79\xa9\xb0\x2e\x7a\x2c\x99\x75\x57\x76\x46\xfe\x48\x06\x74\x71\xfa\x61\x3a\xa8\x8a\x60\x11\x24\xc2\x0c\x17\x54\x52\x28\x2c\xb1\x2e\x64\x03\x05\xa0\x33\xeb\xd9\xf0\xb3\x62\x64\xa1\x16\xa6\xb9\x23\x51\xfc\xba\x89\x73\x6b\xf9\x0f\xc4\xe8\x48\xe9\xa5\xa5\x7c\x70\x60\x34\x94\x23\x77\x77\xf6\x3f\x65\xb3\x32\x39\x1b\x42\xfb\x92\x11\xc5\xbb\xbc\xcf\x24\x2e\xc2\x92\x6e\x76\xe1\xbc\x3f\x4d\xcb\x15\x0f\x42\xd1\xc8\xb8\x73\x82\x70\xa1\xd3\x4f\x9a\x41\xf3\xa8\x53\x73\x41\x15\x23\x71\xea\x90\x0e\x72\x61\x21\x88\x38\x95\x32\xbb\xbc\xd5\xe8\x7a\x7a\x9f\x8f\x76\x71\x78\x54\x76\x11\x99\x2b\x7d\x42\x28\x58\x94\x78\x6c\x9c\x23\x9d\xc7\x36\xa8\xab\x0b\x88\x41\x90\x05\x34\xd6\xac\xd6\x8d\x28\xf3\xaa\x50\x8e\x15\x1a\xc4\x88\x9e\xec\x7c\xd8\x29\x80\xab\x85\xad\xdd\xf6\xec\xa0\x32\x6e\xce\xa4\xfa\x99\xd7\x27\x78\xad\x8d\xf7\xd8\x3b\x3a\x02\x00\x24\xc9\x3b\x5f\x37\x94\x53\xd6\x5e\x21\x78\x2a\x1e\x60\x62\x71\x09\xd7\x72\xa5\xed\x5b\x03\x1a\xb5\x56\x27\xc3\xad\x26\xfc\xeb\x02\x8c\xde\xb3\x35\x08\x43\xe2\x1c\x78\x70\xf5\x62\x57\x30\x6d\x0a\xfb\x14\x1d\x39\x36\x65\x7e\x0c\x54\xcb\x71\xa5\x0e\xb6\x76\x31\x72\xbe\xc5\xfc\x9d\xb8\xa7\x7f\x23\x71\x4a\x5e\xb6\xe1\x0e\xd3\x87\x30\xa0\x4e\x6c\x59\xbc\xbc\xa8\x23\xe2\x46\x09\x83\x85\x5d\x89\x22\x0a\x4d\x04\x07\x9c\x6d\xc8\x1d\xb4\x9e\x4f\x99\x13\xea\x1e\xe9\x35\xe6\x48\xb6\x51\x1d\xba\x3d\xd8\xc3\x0c\xc9\x87\x57\x16\xed\x5b\xf3\x98\xba\xd3\x4c\xaa\x07\xb4\x07\x1f\x58\xdd\x42\x00\x45\x67\x89\xe2\xd6\x1e\x06\xc9\x8c\xe6\x9f\x1a\x50\x18\xf6\x79\xf7\x12\xc1\xcd\x1a\xdf\x04\xde\xfc\x31\xa8\x3c\xb7\x5f\x1f\x6c\x26\xa9\x20\x2e\xbc\x8f\xcf\x3d\x53\x6e\xde\x1d\xf4\x22\x3d\xc5\x06\x86\xd9\x59\x93\x5c\x1a\x9d\x10\x07\xa5\x51\x29\x0a\xea\x3a\x6d\x63\x30\xf7\xac\x2c\x18\x4a\x8a\xcc\x1e\x07\x1a\xd4\xfa\xf6\x21\x0c\x1a\x6f\x1c\xc9\x52\x3f\x39\x7b\x83\xa0\xad\x7d\x15\xde\xea\x2a\x16\xca\xc6\x99\x32\x16\xff\x29\x0c\x33\x6a\xfc\xd3\x9d\x15\xc7\x98\xce\x0b\xb0\xbd\xae\x60\x5a\x98\xb7\x3c\x79\xb8\x3a\x25\x6e\xd8\x0d\x1b\xd3\x6d\xca\x98\x2a\x2e\x4f\x93\xab\xcd\x04\x26\xc8\x01\xea\x7f\x19\x3a\x4c\xc9\xcf\x9b\x24\x4d\x6c\x16\xc8\x97\xfd\x67\xed\x94\xa8\xd1\x84\x90\x1a\x08\x3a\xdb\x0f\xbd\x4a\x85\x83\x82\x24\xe8\x22\x17\x75\x0e\x90\xcf\x0b\x8b\xbf\xed\xe4\xba\x96\x56\x52\x21\x3b\xfe\xdf\x04\xd6\x07\xe9\x43\x93\x86\xcd\xde\x72\x10\x07\xab\x26\x54\xd7\xb0\x9c\x02\x41\xcd\x49\x89\x63\xbf\xa8\xac\x05\xd8\xe4\xf0\x61\x2d\x51\x49\x58\x48\xe6\xac\x54\x63\x49\xcf\xc4\xea\xe4\x77\xf6\xf2\xad\x31\x58\x70\x8e\x0e\x53\x2c\xf9\x0a\x33\x38\x4e\xea\x11\xda\x60\x00\x10\x1b\xb6\x94\x99\x00\x4a\x8c\xbb\x60\x68\x51\xe0\xc4\xc2\xa6\x21\x0a\x4e\x32\xa5\x79\x2a\xd4\x76\xea\xa0\x7c\x69\x81\x9c\xa5\xa4\xeb\xe9\xce\x55\x29\x12\xce\x62\x70\x56\xfd\xd9\x4f\x87\x93\xe4\x29\x48\x2f\x39\xbd\x1b\xec\x28\xcb\xb7\x7b\x67\x70\x7c\x7c\x98\xd9\x11\xd4\x69\xf2\xa5\x73\x4c\x93\xf3\xec\x54\xbf\xf6\x17\x13\x9e\xe5\xc1\x58\x60\x2d\x93\x36\xc7\x1b\x38\xba\xf9\xd0\x44\x89\x70\x0f\x6f\xfc\xd9\xc6\x6c\x2f\x2b\xb7\xb2\x59\x62\x4c\xce\x34\x63\x6c\xcf\xf9\x1c\x05\x07\x39\x55\x2e\xe0\x55\x02\x18\x97\x4a\x1d\x87\x65\xd3\xd3\x35\xda\xa1\x74\x9b\xbd\x33\xf5\xa7\x54\x96\x8e\x26\x25\xcd\x62\x30\x2e\xcb\x67\x92\xa6\x7a\xc2\xaa\x2d\x4f\xae\xa8\x44\x05\x93\xfb\xed\xfd\x6a\x3e\x2f\x55\x63\x57\x57\xbf\xf9\xe3\x05\x4d\x58\xf7\x03\xd6\x09\x05\x02\x53\x1c\x04\xe4\xc8\x65\xbe\x18\x53\x03\xac\x45\x76\x9a\xa0\xc0\x7a\x26\x27\x36\x1e\xdd\x85\xd1\x74\x72\x14\xcb\x6a\x26\xd8\x67\x5f\x59\xf9\x73\xec\x51\x3a\x7f\xa1\xce\xee\x23\xcf\x54\x98\xc9\x1f\x2a\xa7\x8b\x9d\x2b\x67\x72\xf2\xda\x19\xb9\xd3\x3b\x45\xaa\x76\xdc\xe4\x1f\xce\xf2\xda\x94\xaf\x5a\xd8\x55\xcd\xa1\x05\x6a\x48\x57\x34\xbe\x52\x8b\x38\xce\x6c\x85\x54\x90\xdc\x02\xc0\x87\xf3\xfe\x01\xde\xca\x7e\x5b\x05\x43\x12\x90\x08\x02\x83\xce\x3a\xfe\x78\x11\x34\x74\x54\x3e\xb4\xeb\xc4\x29\xc9\x1e\xf6\x9b\x9e\xfd\x20\x2a\xe8\xdb\x7a\xbd\x5b\x1c\xed\x50\x1f\x4b\xd6\x90\x35\xa9\x30\x1b\x75\x19\x26\x42\xe1\xa1\x4f\x6c\xd8\x38\xd4\x36\x21\xf5\xd0\xfa\x95\x5d\x54\x26\x90\x2a\xdf\x6b\xb7\xf9\x17\xe3\x92\x6d\xaa\x07\xc6\x23\x71\x2a\xce\x3b\xb0\x0c\x75\x73\xac\xa4\xa9\x91\x3f\xc0\x70\x61\x21\xa7\xde\x8e\x10\x7a\xef\x77\x85\x30\xa3\x05\xbf\xac\x62\xa8\x19\x70\x6d\x3f\x65\x3a\x92\xef\xc0\x22\x5e\x08\xf6\xd0\xd5\x37\xc8\x48\x77\x68\x85\x0e\x3b\xa9\x48\xc3\xe0\x5c\xde\x81\xa4\xc4\x75\x97\x2b\xcd\x61\xe1\x24\x55\x9d\x0f\xc9\xb9\x04\xb7\x8e\x6a\xa4\xce\x6b\x3e\xbd\x74\xb7\x51\xec\x78\x0d\xde\x2b\x42\x42\xb7\x7e\x35\x0a\xeb\xe0\x57\xdf\x37\xba\x75\xb4\xeb\x91\x34\x4f\x09\x7f\x87\x92\x5a\x7a\x21\xa5\x55\xe7\xc3\x17\xd5\xb2\xad\x55\x6d\x0d\xeb\x50\x9a\xc0\xfc\xfb\xd9\x71\xfc\xc6\x84\xe8\xe2\xf8\xcd\x8f\x0a\xc6\xc2\x77\xa6\x05\xd0\x07\xf2\x9d\x4e\x4a\xce\x36\x7a\xb7\xb6\x91\x59\xae\x9d\xac\x96\x55\xdc\x16\xf3\x61\x15\x8e\xd3\xa3\xb6\x4a\xf0\x80\x98\x29\x4e\x84\x74\xd7\x6f\xf6\xf9\x2c\xff\xfc\xec\x28\x6c\x69\x73\x89\x0c\x8f\xc4\x69\x45\xd0\x30\xa7\xc3\x65\x79\x5d\xf5\x5e\xa9\xad\x8e\x8a\xb9\x02\xba\xc3\x21\x9a\xe6\x30\xd8\x9c\x54\x59\x07\x9e\x83\xc7\x26\x7c\x48\x9f\x59\x48\xd8\x79\x7b\x90\xfa\xe2\x74\x00\xed\x3e\x91\x33\x6b\x67\xea\xcd\xca\x52\x43\x37\xdb\x8b\x0a\x8e\xfa\x6e\x1b\x25\x4a\xc5\xdc\xe2\x34\x61\x92\x86\x23\xcd\x98\x3a\x8d\x33\x85\x92\xbe\x86\x3e\xf5\xc9\x2f\x6c\x69\x6d\x42\xff\x7f\x9d\x33\xe2\x47\x2c\x5c\x87\xce\x8a\x7c\x0a\xfd\x84\xb1\x17\xa8\xf7\x8f\x0c\x59\xbb\x0e\x03\xe3\x18\xa6\xc7\x73\xca\x3e\x89\x59\xce\xd2\x86\x43\x35\x53\x36\xd2\x4a\x4d\x93\x9d\x1d\x1b\x32\x1c\x9c\x60\x05\xed\x0a\xb9\x3b\xce\xaa\x0a\xe8\xee\xf9\xb1\x61\xb6\x1d\x7e\xa2\xa1\x11\x61\xeb\xcb\x19\xbc\x6f\xc2\x49\x28\x2a\x8b\x47\xcc\xb4\x82\x7b\xa8\x34\xf3\x38\x06\xa6\x85\x0e\x92\xda\x33\x34\x27\x39\xda\xcd\xd7\x3d\x40\x8d\x62\xcb\x14\xf7\x97\x88\xb7\xa3\x74\xe4\xe0\x38\x5b\x8e\x48\x42\x2f\x59\xbc\x14\x9a\xf7\x8b\xd6\x96\xec\x5f\xb3\xaa\x67\xda\xab\xcd\x81\xc3\x27\x27\xa7\xa3\x4e\x94\xc9\x9a\xca\x1c\x54\x55\xdb\xd0\x91\x21\xa9\xaf\x43\x00\xf5\x24\x5a\xaa\x5b\x43\xc2\xdc\xf8\x93\x17\x37\x64\x58\xac\x5f\x57\xf5\xe1\xd4\xf8\xe8\x82\xa8\x6f\x2f\xcd\xbf\x82\x0f\xf7\x96\x8b\x60\xc5\x10\x33\x4c\x6f\xd8\x25\x67\xb8\x89\x6d\x76\x85\xb6\x4e\x8d\x75\x2d\xd4\x3c\x39\x61\xfb\x9e\x3f\x76\x5e\xb4\x4f\x03\xd1\xb3\x96\x33\xed\xc7\x13\x3a\x85\x08\xa5\x81\x4a\x60\x02\xe3\x66\xaa\x1a\xce\x4f\x74\xf6\xdd\x62\x1a\x5b\xf8\x5a\x4f\xfd\x8d\xaf\x86\x72\xbc\x76\x4c\xe0\x95\x2a\x44\x69\x6b\x08\x13\xcc\xd8\xe2\x72\x04\x56\x2d\x7d\xd8\x18\x68\xd8\xb8\xa3\x7c\xce\xc4\xa1\x2a\x8a\x40\xdc\x5e\xda\x1e\x0c\x04\x39\x72\x7f\xd4\x75\x31\x1c\x31\x74\x97\xdd\xab\xb5\x3f\x71\xce\x7c\xbc\x56\x66\x24\x27\xf6\xc9\x7b\xf0\x51\x69\xdb\x03\xba\x17\x20\x40\x8e\xa3\xb8\x21\xa3\xf8\x09\xca\xfe\xb0\xe3\x37\xe2\x63\x85\x41\x60\x99\x82\xc7\x16\x6b\x92\x13\x58\x68\x7c\xd8\xd8\x5d\x7c\xc4\x89\x31\xc2\xec\xbf\xe6\xf7\xd1\x12\x9b\x38\x6a\xc6\xa8\x4d\x88\x2c\x17\xce\x0c\xc0\x61\x85\xe8\x2f\x96\x1c\x9f\x38\x44\x71\x95\x57\x46\x51\x60\x53\x76\x65\x83\xc9\x4c\x32\xd5\x64\x1c\x33\x78\x47\xf6\x48\x44\x65\x59\x9c\x5e\x40\xb3\xab\xae\x9c\x03\x92\xfc\x64\xab\x2b\xb2\x1f\x6b\xd8\x32\x8b\x13\x66\xf6\x32\x6a\xb2\xe6\x3d\x8e\xfa\x8f\x24\x1b\x9d\x24\x85\x72\x44\xd4\x46\x4a\x7f\x78\x37\xd2\x8a\x8a\x2b\x91\x35\x8d\xb6\x59\xf0\x97\xe0\xce\x85\xa8\x6c\xc8\xc8\x77\x12\xf5\x56\xfc\x94\xd1\xae\x59\xa1\xf0\x64\xbd\x3c\xfa\xdc\x7a\x1d\x4f\x01\x0c\xd7\x73\xb4\x8d\x72\xa9\x61\x54\x9f\xeb\xb7\x41\xa9\x3a\xb1\xeb\xbf\x0e\x0b\xa8\xbd\x48\x3c\x72\xfa\xca\x70\xa6\x92\xe4\x1b\xd1\xc7\x39\xa2\xe5\xcb\xde\x38\xbf\xf3\x7c\xb4\x8d\x15\xc8\xcd\xa1\x41\x0c\xf0\xc1\x0a\x6a\xd6\x81\x32\xab\x0d\xf9\xa3\x4a\x40\x63\x63\x92\x55\x6a\x99\xed\x49\x3e\x04\x24\xb8\xdf\x94\x5c\x5f\xd8\xee\x9c\xcb\x18\x0b\x29\x67\x99\x3d\xd8\x8d\x89\x32\xfc\x26\x68\xe2\x7a\xfc\x69\xb6\xf7\x74\x78\x43\xf2\xf7\x9b\x4a\xb3\x01\x9f\x06\xdd\x97\x54\xf6\x30\x5c\x11\x3d\x21\xac\xab\x6f\xcc\xaf\x56\x1d\x42\x9b\x51\xc2\xc7\x0c\x1a\xf9\xe0\xe6\xa1\x5f\x1a\x8d\xcc\x21\x53\x68\x02\x3d\x15\x94\x5e\x33\x41\x5a\x27\x3e\xd6\x81\x3a\x13\x1d\xa2\x85\x17\x8f\x30\x51\xd8\x71\x76\x62\xa0\x61\xa8\x96\xd5\xb1\x01\x11\x75\x62\xad\xc2\xbd\x87\x34\xea\x54\xd0\x2f\xa5\x8a\x03\x48\x01\xb9\x22\x73\x18\x6d\x55\xa4\x85\x4e\x9f\x2f\x8f\xb5\x33\x06\x9e\x38\xa9\x47\xa9\x1e\x34\x89\xe1\x76\xf4\xc1\xda\xde\x0f\x57\x01\x0d\x8c\xb5\x43\x6e\x06\x94\x4a\x12\x20\x3e\x8b\xd2\xc8\x64\xbe\xbd\x0a\x35\x6a\x94\x50\x14\x59\x2a\xb6\xbb\x7e\x0f\xe9\x88\xf6\x8e\x43\x6a\x4d\x05\x8f\xc8\xeb\x51\xb4\xc7\x35\x9c\x25\x0b\x30\x13\x50\xe3\x81\x73\xf8\x3f\x84\x44\x29\x7b\xf5\x82\x55\xf4\xda\xd5\x85\x5b\x0a\x08\xf1\xc5\x32\x52\x79\x3e\xd9\x46\xa7\xc7\x23\xb9\x87\x55\x55\x00\xce\x74\xde\x49\xbe\xfa\x10\xe3\xee\x1c\x78\x43\xb3\x6a\x1a\x0d\x85\x26\x34\xd4\xa1\x0d\x20\x7f\x07\x7e\xfb\x9f\xab\x5f\xd4\x3f\x67\x98\xf5\x2d\x67\x3d\xca\xf9\xb0\x00\x4a\xcf\x61\x60\x5b\x87\xdc\x0e\x6f\xdd\xe6\x50\x08\xad\xb4\x40\xad\xba\x8f\x3a\x25\x1b\x57\xed\xbb\x35\x70\x1c\xe5\xea\x2d\xfd\x2a\x01\x83\x9e\x6e\x13\x71\x04\x87\xc4\x87\x9f\x12\xd4\xf2\x87\x1a\xa3\xd6\x0c\xd5\xce\x43\x48\x4c\x03\x3a\xd0\x31\x7d\x5c\x8f\xd5\x0a\x4d\x3c\x46\x52\xaa\x8c\xb6\x79\xad\xf5\x31\xa4\x53\x3d\xa4\xc4\xb6\x86\xba\xff\xa1\xf3\x0d\x0d\x38\xf3\xe4\x77\x18\xe2\xb3\xb9\x73\x16\x05\xfd\xbf\x43\xee\x92\x87\x74\x92\x91\xf5\x88\x22\x13\xc9\x24\x49\x58\x07\xb2\x4f\x00\xbe\x1d\xe6\xd6\xa6\x6a\xce\x47\x7b\x59\xb8\x6d\xca\x97\x01\x67\xf8\xd6\x1f\x44\x6e\xc1\x9b\xfd\x60\xea\xc9\x2e\xfd\xc6\xe5\x12\xcb\x0b\x7c\x5b\xb6\x11\xdc\xde\x16\xc6\x7c\xc4\x32\xa4\xa7\x1a\x9e\x84\x58\xc6\x59\x14\xdb\xb2\xfc\xd3\x74\x6b\x1e\x46\x43\xa9\x30\x71\xbb\xd3\x51\x16\x4e\xd9\x10\x7f\x4c\x60\xf6\x88\x3f\x9c\xe9\x3c\x1f\xfd\xdb\x78\x8e\xea\x91\xe6\xa2\x0e\x0c\x1c\x6c\x23\x3e\xa0\x50\xca\x48\x50\xeb\x68\x9c\xb7\xc4\x9c\x43\x72\xbb\x6b\x10\x25\x20\x01\xe2\xa3\xdb\x0c\xfc\xc6\x5f\x96\x2f\x47\xc7\xd5\x14\xd8\x92\x5e\xc9\x06\x75\x2e\x84\x72\x60\xbe\xd3\x74\x9b\x6b\x10\xe7\x81\x74\xe1\x10\xba\xca\xbd\x99\x3d\x62\x5b\x1c\x93\xb6\x06\xce\xd3\x59\x6d\x1a\x36\x07\xbe\xa8\x88\x03\xe8\x86\x09\x75\x6a\xa5\xa2\x6d\x78\xfc\xa8\xf5\x0e\x54\x0b\xac\x7b\xce\xc0\x2d\x37\x79\x4b\x94\x5f\x65\x21\xbe\xfb\xf0\xec\x59\x65\x9d\x0c\x36\x57\xa9\xf3\xe1\xcc\xc5\xe3\x26\xbe\xa2\x9a\xa9\xaf\xf9\xf3\x49\x18\x28\xa4\xfc\x1d\xae\xa7\x33\x31\x50\x87\x09\xd0\x53\x55\x58\x6c\xe4\xcf\x5a\xcb\x27\x4b\x95\x7a\xdd\xf5\x0b\x7c\xfd\xb2\x5c\x07\x40\x67\x82\xab\x1c\x95\xb8\x60\x1a\x44\x0f\x74\x4b\xe9\x0f\xfc\x6a\x03\xa9\x99\xcd\x77\xaf\x3e\x75\x1b\x1d\xe1\x8b\x8b\xc5\x84\xd5\x6f\x89\xca\x2f\xdd\xe8\xfc\x56\x83\xa8\x42\x63\x2c\xfa\x79\x0f\xb1\x0b\x89\xc8\x6f\x40\xb7\xab\x65\x88\x8d\x68\x71\x12\xb1\xe6\xba\x92\x39\x4e\x08\xb5\x46\xcc\x6d\x79\x98\x01\x75\xdf\x76\xa1\xfc\x31\xd4\x2e\x2f\x12\x01\x2f\xa2\x5b\x9a\xf8\x55\xb3\xef\x27\x47\x28\x1f\xca\x39\x02\xee\x1a\x31\x8a\xfb\xf0\x41\x0c\x7a\x54\x69\xfe\x56\xae\x7f\x76\xc2\x5f\x1e\xfd\xea\xec\xd0\x16\xc7\xb0\x23\xda\x9c\x5c\x56\x5c\xcb\x26\xf6\x4b\x9a\x0e\x5b\x65\x20\xb9\xa8\xd3\xae\xcf\x65\x69\x70\xaf\x20\x3d\x6a\x76\xf3\xff\xb9\x7a\xb3\x05\xd5\x75\xdf\x69\xf4\x5d\xb8\xfe\x5e\xca\x49\x4c\xe2\xce\xe0\xfc\x32\xc0\x86\xa7\x3f\x2a\x55\xc9\xac\xff\xb9\xd8\x1b\x77\xaf\x9e\x80\xc4\x96\x4a\x35\xa8\x25\x99\x9a\xd7\xd6\xf4\xc3\xcd\xf0\xa8\x24\xd9\xe9\x27\x78\x1b\xdd\x25\x9b\xc7\xb3\xae\xc9\x9a\x27\x99\x0f\x3e\x7f\x69\xa9\x6e\x5e\xfa\x70\x46\x00\xeb\xf4\xe1\xa0\x13\xc8\x50\x23\x86\x27\x13\x80\x5d\x12\x1b\x24\xbe\xee\x03\xb5\xd7\x3d\x88\xcd\x62\x03\x08\x89\xdd\x04\xe8\xf7\x61\x4b\xea\x61\x66\x72\x95\x76\xca\x6b\x43\x68\x6e\x97\x67\xd1\xa1\xab\x03\xa3\x43\x69\x5a\x0b\x27\x2b\x56\xa3\x7e\x7c\x88\x82\x1b\x99\x71\xaf\xb3\x9c\xd1\x9c\x8b\x28\x1c\x15\x83\x06\xdf\x57\x21\xcd\xa2\xb4\xcc\xbf\x2a\xb9\x1a\xe5\xeb\xd8\xb2\x57\xd9\x9f\xb0\x09\x7b\xd7\xe5\xa9\xa1\x61\x95\xdc\xef\x55\x5b\xe6\xf5\x41\x4f\x0b\x7b\x1f\xfe\x0b\x05\xe5\x41\x5f\x15\x4f\xca\xe4\xc6\xb9\x97\x9f\xc4\x17\xac\x04\x72\x8f\xec\xfc\x1e\x3d\xec\xce\xd5\x2a\x2d\x6b\x38\xb9\x35\x97\x75\x1d\xad\x6a\xe5\x71\x0b\x09\x84\xcc\x13\x4b\xdf\x83\xab\xec\xa4\xce\x7c\x04\xd7\x60\x64\x91\x0f\xee\xf0\x75\x7b\xc3\x5e\x9b\x64\xac\x0e\xb0\x95\xf6\x8b\xd7\x5f\x24\x9c\xd8\x41\xc5\xb6\x4d\x58\x17\xea\x51\xa3\xeb\xb1\xbf\xa8\x57\x5c\x53\x5a\x6e\x47\x11\x30\x9c\x62\xd2\xba\x55\x5a\x8d\xa4\x92\xce\x76\xbc\xcd\x6f\xeb\xf0\x7f\x1f\xd9\xe5\x47\x84\x96\x15\x11\x72\x63\xc3\xe0\xfe\x13\xfb\xe9\xab\xa9\x2b\xe2\x68\x99\x12\xcf\x4d\xdb\x56\x9b\xed\x71\xf6\x8b\xce\x37\x56\xb5\x49\x8e\xc8\x78\xb5\xf8\xb4\x83\x36\xa4\xb2\x4f\xee\x66\x31\xf5\xc8\xc0\x99\x49\x5c\xda\x26\xfa\x82\xd0\x37\x00\x0a\xce\x5f\x22\x5b\xf8\xe0\x77\xe1\xd1\xe1\x6e\x2c\x24\x6d\xea\x2c\x84\xfd\x8a\xb6\x23\x8e\x97\xed\xef\x16\xcb\xf8\x62\xe9\x74\xb5\xfc\xee\xf3\x2d\xc7\xf6\xf3\x65\x1d\xdf\xf0\xcb\x59\xd2\x8c\x09\xfc\x74\xa5\x36\x34\xed\xe3\xd9\x6c\xcf\x4f\x72\x34\x74\xb6\xb4\x00\xb5\x33\x48\x76\x3e\xc1\x54\xf2\xda\x5a\x20\x06\xf0\x2b\xe3\xa3\x22\xca\xae\x15\x62\x56\x47\xab\xd3\xad\xc1\x73\xea\xc0\x7e\x2f\x99\x2a\x27\x70\x8c\xf8\xf3\x37\x5d\x44\x80\x88\xc3\x67\xbe\x0c\x43\x0a\xdc\x6e\x71\xac\xd5\xbe\x8f\xfb\xcf\xc5\x7a\x6f\xbe\xff\xd2\x9b\xc7\x27\xf4\xdc\x7c\xaf\xc1\xc3\xf7\x31\xaf\x9d\x38\x8b\xfa\xed\x09\x51\xe6\x82\xdc\x32\x1d\xb5\xa6\xbc\x47\x9e\xcf\xba\xc5\x62\x0d\xe2\x5a\x33\xb7\x60\xa2\xb9\x37\x68\xa3\x77\x24\xdc\x8a\x10\x87\x54\x42\x98\xca\xe4\x78\x7f\xdf\xfd\xe5\xf5\xad\x2a\xb0\x9b\xb4\xcc\xfc\xf1\x56\x6d\xa8\x51\x1b\x6e\x9e\x79\x3e\x7e\xd6\x41\x9a\xc2\x5a\x11\x4f\x44\xad\xf2\x94\x86\x5f\xa4\x2b\x8c\xf7\x5a\x2f\x40\x34\x99\x2a\x6e\x28\xa8\xe8\x81\x76\x04\x27\xb3\xab\xef\x58\x2c\x83\x34\x38\x3a\x52\x6d\x2f\x57\x2e\xa9\x2d\x8b\x7c\x18\xbe\x31\x59\xee\x9a\xe8\xd2\xd3\x07\xa2\xb2\xa3\x49\x15\xcd\x7c\xf8\xfc\x61\x93\xcb\x0b\x02\xfa\x0d\x9e\x25\x57\x64\x67\x5b\x3b\x55\x3b\xd6\x2e\x9e\x3f\xf0\x1b\x6a\x8e\xc1\x7a\x51\x6f\x87\xfd\xc8\x8f\xc7\x3d\xf7\x24\x33\x9f\xb5\xc5\x41\xae\x59\x58\x8a\x03\x81\x7e\xa5\xf6\xb5\xb9\xe8\x25\xc2\xdb\x87\x33\xaf\xdc\xb4\xac\x8d\x8d\x4e\x5e\x7f\x4b\x98\xa4\x54\x7e\x62\x94\xdf\xab\x58\x3f\xf0\x25\x7b\x38\x94\xe3\x9b\x56\xb4\x58\x8c\x6d\x88\x21\x53\xd8\xbd\xee\x59\x50\x33\x8d\x55\x1e\x9c\x3b\x11\x34\xc4\x36\xd7\x93\xc5\x6b\x4d\xdf\x6f\x32\xaa\x91\xc7\x40\x61\xd8\x1a\xd5\xcf\x8a\x19\x06\xbb\x17\xf7\x05\xa1\xc8\x3c\x2f\xa3\x46\x52\xd0\x67\xd3\xc7\x0f\x54\x2c\x81\x02\xab\xac\x79\x96\x0f\x4f\x29\x1c\xd7\x38\x61\xfd\xa6\xf8\x74\x61\x9c\x9c\x5f\x52\x16\x8d\xcd\xa4\xfa\x99\x22\x7d\xd3\x2e\x9b\x90\xf7\xcb\x76\x6d\xf6\xb3\x71\x06\x67\xf5\x9c\xf1\xe4\xff\x52\xe0\x7a\xb0\xc2\xfc\x39\x60\xfa\xdd\xf4\x16\x06\x33\x31\xe7\xd5\xbf\xaa\x08\x5f\x03\x69\x5e\xcd\x77\x91\x41\x32\xa6\x5c\x34\x91\x18\xb1\x3d\xd0\xf1\xd2\xba\xcc\xb8\x31\xc2\xc5\xed\x19\x3c\x9f\x67\x8a\x30\x5c\x94\x42\x1a\xcd\x87\x64\x26\x93\x60\x34\x88\x1a\xd8\xc6\x31\x40\x48\x02\x26\xc1\x9c\x97\x69\x11\x0c\x0c\xeb\xad\xf2\xde\xa6\xc6\x0c\xf3\x31\x4c\xb3\xa4\xaf\xfe\x7a\x91\x24\xb0\xd4\x0f\x19\x01\xa9\x00\xd6\xe3\xc8\xff\x5e\xfe\x89\xcf\x91\x19\x9d\x1d\x41\x8a\x2a\xe8\x23\x4f\xdf\x09\x00\x72\xe3\xc4\xed\x1c\xa3\x39\xc5\x6f\xd6\x61\x93\x6a\x5f\xdb\x1a\x16\xbd\xdf\x7e\x8b\xec\xec\xa7\xc8\xa4\xb7\xfa\x74\xaa\x92\xc8\xc9\x68\xe0\x1d\x29\x3a\x90\x9a\x57\x9e\x04\x52\x71\xa0\x96\x50\xe4\xe5\x75\xb4\xb1\x5e\x26\xd1\xfd\xb2\x56\x29\x45\x3e\xdf\xf9\x19\xe2\x44\x08\x57\x08\x87\xc2\x25\xad\x5a\xaf\xc2\xad\x1f\x1b\x03\xff\x15\x4b\xd1\xdc\x62\xfd\x60\xff\x2f\x01\x48\x96\x37\xb9\x7b\x53\xd2\xa6\xf5\xd4\x20\xe4\xa0\x17\xd2\x71\x2b\x66\xba\xec\x3b\x41\x02\x69\xd8\x6c\xe1\x35\xed\x01\x2e\x5d\x74\x53\xff\xbb\xa9\xff\x03\xe5\x88\x88\x15\x47\x25\x5b\x24\x90\x6d\x1b\x37\x1e\xe4\x73\xbd\x5b\x83\xcf\xb7\x16\x3a\x82\x81\x7b\x3e\x66\x43\xa1\x1a\xb8\x83\xb3\x76\x29\xac\xdd\xae\xbe\x4d\x63\x89\xf9\x90\x06\x44\xdb\xdd\x9c\x78\x31\xfe\xe5\x3d\x62\x11\xc8\x5a\xb5\x22\x42\x8f\xfc\x58\x41\x39\x1c\x28\xea\x66\x74\x30\x24\x1c\x32\xbf\x55\x59\x89\x73\x18\xc1\xae\x30\xbc\x7d\xb8\xe9\xb6\x2e\x6a\x6b\xd1\xd4\x9f\x8f\xcb\x1d\xb0\x14\x3d\x3b\x1d\x9f\x6a\x81\x53\xa3\xbd\x54\x7e\x47\x3f\x23\xa6\xef\x29\xe0\x30\x7f\xe8\xb7\x71\xb6\xee\x30\xa7\xc8\x5b\xb7\x7b\xac\x84\x2b\xfa\x02\xc9\xbe\x84\x61\x88\xff\x0a\x68\xf5\x12\xfa\xd5\xb7\x88\x7d\xbb\xb6\x9b\xe3\x66\xf8\x23\x20\x5d\xcb\xcb\x51\x14\x2a\x5b\x14\x2a\x57\x0e\x4b\x04\xe9\x0b\x61\x90\xe6\xbf\x5a\xe0\x27\xb3\xfa\xed\x56\xeb\x63\x2b\x7d\x37\xfb\x4d\x51\xa2\x70\x61\xc7\x5f\x6e\x4d\xd6\xcf\x9b\x53\xaa\x0a\xa2\x4e\x2e\x1a\x04\x81\x83\xf2\xc1\xa4\xcd\xe9\x8e\x3e\xf8\xba\x35\xf3\xbd\x1a\xd2\x7f\x95\x65\xd4\xc8\xe7\x8a\x67\x64\xd7\xb0\x48\x96\x84\x64\x4e\xca\x49\x44\xa1\xa1\x07\x5a\xb4\x3f\x07\x19\x24\x47\xe5\xa8\xbb\x93\x67\x1b\xae\x56\x0d\xbd\x77\x58\xc3\x3d\x5c\xa5\x2d\x7d\x13\xfb\xbe\x1a\xec\x2d\x09\xf9\xb6\x4f\x7c\x62\xb3\xd2\x1c\xb9\xf1\x58\xa6\x36\xf6\x05\xbe\x80\x07\xb7\x31\xa4\x5b\x31\xc8\x33\x7a\xd4\xef\x5d\x7f\xcc\x99\xd2\x34\x8b\x7d\x63\x70\x06\x25\x17\x15\x33\x2d\x74\xd6\x34\xff\x0c\x09\xff\x72\x5b\xb6\x69\xd2\x72\xcb\x1a\x53\x30\xb0\x95\xad\xcd\xa3\x01\xcd\x9e\x7f\x4d\x92\x5b\x69\x14\x49\x2e\x51\xe5\xb9\x80\x3b\x51\x86\xb0\x9e\x00\x1c\xe8\x03\x70\x0e\xff\x0a\x79\xfb\xc0\x48\x40\x1c\xef\xa5\x58\xd5\xa2\xf3\x01\xb4\x06\xc9\xe3\xc4\x27\x47\x39\xbd\x0b\xa7\xf8\xb9\x0a\xd8\xee\x46\x24\x0d\x05\x96\x9f\x1d\xc0\x5c\x45\xf3\xa1\xc1\xcf\x15\x57\x3d\x2e\x6e\x04\x8f\xfa\xd1\x50\xd5\x80\xda\x13\xfe\x1d\x0c\x32\x30\xb0\x3f\xfc\x94\x07\x39\x06\x11\x11\x37\x0c\x2f\xcf\xed\x2b\x9e\xd8\xa2\x01\xb1\x9d\x0a\xed\x75\xe9\x3d\x68\xde\x57\x53\x49\xba\x5d\x80\x5e\x2a\x2e\xce\x7a\xc5\xdd\x7a\x6a\xf6\x8a\x2c\xaa\x8e\x3a\x27\x85\xd8\x23\x5a\x4a\x07\x04\xb7\x7c\x64\xca\xa9\x67\x2c\x2d\x3f\xc6\xd3\xf2\x89\xd8\xca\xdc\xc3\x4a\x1c\xa5\xf7\x47\x38\xd2\x37\xfd\xa5\xfe\x21\x09\x42\x15\x42\x21\xd9\x64\xcb\x23\xb0\x97\x2d\x0a\x31\xcc\xdc\xbd\x15\x0c\xc8\xe9\x72\xb7\x66\x3a\x13\xdc\xc1\x41\x8e\xf9\x2f\xaa\x30\x1a\xe9\xd7\xff\x63\x58\x8c\x39\x21\x8b\x7f\xc4\x43\x7b\x6d\x56\xc6\xe8\x22\x43\xb4\xe0\xe7\xac\x08\xea\x6d\xbe\xb6\xd2\xbc\xb4\xb1\x47\x4f\xf0\x7e\x1e\x4d\x44\x9f\x44\xf0\x21\xef\x0f\x16\x37\x85\x1e\x26\x4e\x81\x80\x5f\x57\xe1\x94\x65\x6f\x11\x10\xdb\x27\xac\xa4\x1c\xfa\x70\x2a\xc6\x86\xee\x8d\xfc\x00\x2b\xb7\xaa\x14\x2f\x56\xee\x84\x73\x2f\xd5\x0d\xd4\xf5\x76\x61\xd1\x0d\x0c\x18\x90\xa2\xdf\x0b\x78\xc3\x97\x90\xca\x92\xec\xf1\x64\xb4\x24\x7c\xc8\xe5\xbe\x76\x11\x6a\xb0\xea\xea\x16\x51\x28\xf5\xfc\xd4\x2c\xd4\xc8\xdb\x0f\x62\x7c\x24\xf8\xcc\x29\xc8\x93\x78\x0f\x1f\x60\x48\xab\x0d\x81\x78\x9f\xa6\xe3\xb2\x0c\xb4\xb2\x4a\x06\x94\x42\x42\x56\xa2\x73\x56\x71\x17\x11\x59\x2f\xfb\xbd\x9c\x03\xcb\x93\x02\x6c\x14\x41\xeb\xc3\x1d\xde\x7d\x43\xa5\x66\xaa\x8c\x05\xbe\x00\x9b\x7b\x5c\xe5\x68\xab\x06\x14\x7f\xf4\x1e\x3b\x8a\xbc\x7f\x8f\xdd\x25\x26\xb6\xb0\xa3\x9e\x95\x93\x2c\xcd\x40\xd1\xde\x74\xfc\xf7\x22\x40\xb8\xdb\x5e\xc0\xc7\x41\xe8\xf5\x45\xa3\x0c\x1c\x63\x50\xa1\x3a\xbb\x62\xf8\xb9\x1f\x63\xa1\x0b\x6b\xfc\xce\x67\x1d\x74\x7a\x05\x46\xe2\x67\x4e\xd2\x88\xef\x37\xfe\x4a\x11\xb3\xf0\xbd\x55\x0d\xbe\x9b\xfe\xc3\xb9\x4d\x67\x9c\x0f\x11\xc4\x17\x21\x4b\xf6\xc3\x5d\x15\xe6\xf7\xc2\xbd\xee\xba\xdc\x05\x8b\xe2\x58\x20\xc0\x5c\xe2\x82\x5d\x1a\x8b\xdc\xf1\x0f\x6f\x3a\xec\xee\x20\xea\x71\x51\x87\x73\xaa\x15\x38\x42\x95\x0f\x76\x34\x09\xd0\xa2\x52\x85\xcc\xbc\x92\x62\x88\x58\x60\x4d\x80\x7d\xeb\x70\x23\xe9\x5e\x83\x60\x4d\x54\x56\x98\xf6\x08\x64\xde\xe2\xc2\x4d\xbe\x0d\xb2\xf3\xff\x2d\x7c\x23\xcf\x9c\x54\xec\x52\x2f\x07\x03\x63\xc6\x64\xc7\xc7\xbc\x39\x6d\xe1\x2d\xd4\x86\x9a\x2e\x5d\xce\x82\x8d\xdf\x01\x24\xcb\x16\xa4\x53\x13\x1c\x68\xcf\xf8\xdb\x2b\xc7\x5b\x36\x30\x76\x35\x3f\x5c\xcf\xcc\xc9\x19\xd8\x97\xa4\xb1\xe1\x30\x6f\x38\xf1\x27\xfc\xbf\x97\xaa\x8b\x34\x54\x95\xde\x47\x0f\xcd\x81\xa8\xbf\xb5\x15\xd7\xa8\x4b\xec\x8e\x6e\x04\x7a\xf8\x3c\x96\x2b\xb6\xd7\xd2\xa6\x63\xea\xe9\xbb\x5b\x9b\x69\xb6\xfe\x35\x29\x64\xe4\xc6\x50\x89\x99\x75\x50\x5c\xaa\x62\x21\x1e\x8d\x47\x22\x6f\xb6\xb5\x7d\x71\x45\xbb\xe9\x6a\x96\x86\x63\xa0\x04\x14\x8d\x2f\xef\xc0\xe4\x5d\xf3\xe5\x1a\xc1\x77\xa8\xca\xde\xda\x14\xad\x8d\x71\x3a\x87\x73\xa7\x84\xca\xb9\x43\x8c\x9e\xc9\x25\x12\xf3\xf5\x8f\x70\xfe\x74\xb3\x76\x5f\xa4\xf0\xac\x80\x8b\x99\xae\xbe\x7a\xcf\xcc\x60\x03\x3f\x91\x7d\xaf\x06\x64\xf0\x12\x12\x47\x3c\x38\xdd\x27\x70\x44\x0e\x54\xf0\xea\x49\x4f\xe2\xc8\x1c\xdb\xaf\x23\x7b\x81\xbb\x6b\x98\x82\x9c\x37\x46\xb5\xfd\x93\x9a\x6c\xc5\x88\x04\x0c\xd0\x8c\x75\xec\xa8\xed\xfb\xbf\xff\x0a\x78\x4f\x2d\x25\xb9\xb7\x8a\x92\x3a\x68\x90\xa9\x08\xe8\xac\xa0\x08\x56\x7d\x72\x88\x09\x5b\xbf\x51\xeb\x03\xbd\x67\x11\xfb\xd4\xae\x48\x32\x07\x96\xe6\x6c\x0b\x63\x6e\x31\xf8\xdc\xfe\xd9\xaf\xe2\xc0\x2b\xe7\x72\xf0\x52\xf3\x4c\x25\xd2\x17\xd4\xc1\xfc\xd1\xaf\xc9\xce\x43\x31\x20\x6d\x67\x55\x88\x43\x73\x0a\x4c\xa2\xf8\xda\x5f\x1f\x23\xe2\x3d\x90\xe8\xdc\x54\x8a\x87\x22\xce\x80\xef\x04\xbc\x93\x35\x25\xe1\x56\xf4\x94\xf6\xea\x59\x82\x81\xfb\x94\x92\xfd\x9f\xe1\x31\xae\x78\x3d\x13\x4c\x4a\x24\x62\xcb\xd2\x81\x0e\x08\x36\xe3\x5d\x40\xc8\x62\x28\xe7\x7a\x47\x30\xb2\x4f\x53\x7d\x09\x3b\x02\x96\x22\x83\xb5\xe5\x61\x5d\xb6\x3d\x5b\x0f\x4b\x72\xcf\xa2\x43\xa3\xe7\xec\xaf\x87\x2a\x5a\x2d\xaa\x24\xe8\x7d\xe4\x8a\xf5\xe9\x7d\xc9\xfe\x23\x29\xe7\xc2\xfd\x27\x49\x9e\x58\x6e\xc6\x9f\x3a\xa0\xad\xa0\x98\xe6\x27\xc0\xb0\x6e\xec\x18\x4a\xea\xba\x69\x1b\xb1\x4a\x07\xb9\x3c\xed\x14\x4f\x1a\x4d\xbe\x43\xc0\x85\x4b\x54\x43\x44\x0c\x55\x04\x13\xb9\xcc\xa5\x0b\x31\xec\x41\xec\xd2\x4e\x6b\x3b\xe2\x1d\x9f\xa1\xa7\x8d\x6d\x08\x7a\x0b\xae\x8f\xd7\x4c\xd7\x3b\xb2\x7b\x55\x98\xd3\x26\xc4\x17\x9b\x72\xe8\x81\x6a\x86\xc8\xc6\x37\xa1\x8e\xcd\x24\x7c\x41\x55\x4a\x9d\xe9\x4c\xba\x6f\xf6\xbd\xcd\xd5\x4f\xf7\x81\x9d\xa3\x3d\x9d\x78\x1d\xb0\x53\xc5\x77\xd9\x21\xf6\xc7\xb7\x60\xf7\xf7\x6c\xb7\xd7\xb6\xd1\xe5\x6d\xcf\xd3\xb8\x66\x0a\xbf\x28\x4f\xe1\x63\x19\x0e\xa2\x79\x8e\xb0\x1b\xb5\x49\xf5\x3f\x4c\x1c\xfd\x38\x84\x23\x04\xef\xc7\x7a\x34\xf6\x32\xef\xbe\x83\x36\xb1\xf0\x92\x3c\x64\x81\xdd\x9c\x6a\xfa\x59\xaf\x3d\x49\x69\x4a\x2e\x95\xc8\x06\x3d\x8e\x46\x92\x42\x8b\x97\x9b\x9b\xfd\x22\xe2\x28\xec\x2e\x54\xe7\x37\xd3\x48\x34\x87\xac\x65\x3a\x3f\x03\x1c\x4e\x85\x18\x27\x1c\xe1\xc9\xc8\xc0\x79\xd2\xa5\xfd\xc2\x6d\x8b\x9b\xed\x6b\x45\x50\x61\xe0\x27\x82\x96\xea\x29\xf1\xc6\x84\xd1\xac\x22\xba\x30\xa4\x54\xc7\x6b\xc7\x8a\x4e\x95\xa2\x3d\x0d\x18\x98\x9f\x1d\x20\xb7\xd0\x33\xe1\x54\x4d\x83\x3e\x9d\xa5\x3c\xad\x51\xd1\xb8\xfa\xc7\x0e\x1b\x06\x2a\x03\xce\x9b\x6a\x41\x2b\xeb\x27\x7f\xb5\x78\x99\x2b\x09\xb1\x77\x80\xdb\xf9\x16\x56\x57\x46\x27\x0a\xd5\x41\x34\xc1\x77\xe8\x7b\xee\x16\x44\x11\xd6\x7e\x38\x72\xc8\x47\xd2\x6b\xd9\x05\x4f\xba\x93\x9d\x14\x8c\x72\x26\x1f\xf3\xd4\x31\xfd\x42\xc6\xfe\x99\xa5\x47\x67\x9d\x0e\x1d\xed\xee\xd3\xa0\x09\x7f\x1a\xe6\x00\x63\xbe\xde\x8c\x12\x63\xa5\xb2\xb8\x1e\xff\x68\x8d\x83\xf4\xec\xdd\x31\x1d\x75\xfc\xc9\xc4\x0b\xe1\x74\x54\xef\xb8\x91\x2a\x98\x34\x0c\xca\x9a\x06\xdc\xd9\xe9\xc5\xbe\x4e\xef\x08\x2b\x79\x87\x98\xf9\xaa\x7e\x3f\xf8\xaa\xe3\xf7\xe6\x18\x28\xdb\x2f\x79\xe5\x16\xed\x90\x9c\xc7\x79\xc6\xdf\x70\x4a\xc5\x9a\xc3\x93\x98\xe9\x7b\x4a\xd2\x3a\xa1\x1e\xa4\xd1\xdd\xfd\x9b\xc4\x40\xe9\xb3\x45\x99\x60\xbd\x1c\xe1\x13\x18\xf9\x48\x10\xb1\x43\xc4\x2d\xdc\x96\xce\xb2\x41\x24\xe9\x04\xd4\xec\x59\x25\xd7\xb5\x91\x90\x5c\xff\xa1\x8d\x57\x57\x2b\xf0\x6e\x3a\x7f\xba\x94\x07\xdb\x01\x2e\x64\x45\x81\xb0\xdb\x68\x04\xe0\xf5\x33\x8a\x40\x62\xbd\x19\x8f\x0a\x59\x1e\x46\x00\xe3\x22\xce\x32\x82\x49\xdd\xd5\xd2\xaa\x75\x15\xf6\x5e\x56\xfe\x55\xb9\xfc\x3a\xbf\xce\x27\x9c\x3e\x42\x60\x85\xdf\x6a\x23\x08\x20\x64\x84\x10\x16\x5a\xb8\x4d\xc8\x05\x5e\xa4\x0e\xc8\x0c\x59\xb1\xe7\xc5\x79\x7e\x1d\x48\xe9\xa4\x41\x82\xb7\xcc\xb9\xe8\x26\x1a\x22\x26\x80\x7e\x99\x48\x3e\xe2\xdd\x87\x13\x8a\x6e\x7c\x8d\x93\x88\xbb\x41\xb3\x88\xe6\x77\x6a\xdb\x19\x26\x48\x3d\xcb\x2b\x54\xbf\x2a\xde\x46\xee\xea\x79\x40\xf5\xaa\x31\x56\xba\x56\x49\x14\xdc\x6b\x12\xa6\x43\x4c\xbd\xc0\xd4\x75\x69\x7c\x94\xdf\x11\x66\x2d\x08\xa4\xc1\x5a\x47\x7f\x92\x5b\xa7\x35\xe4\x3f\x96\xc4\x76\x6b\xeb\xa2\xeb\x01\x18\x8a\x50\xb5\x4b\x68\xde\xd7\xf1\x8c\x49\x08\xd4\x5b\x7e\xd3\x16\xbb\xbd\xbd\x4f\x27\x03\x93\xae\xb2\xec\x2f\x50\xa3\x8b\x5d\x0c\x30\xab\x53\x71\x58\x9b\x40\x23\x74\x9c\x6c\x4d\x22\x2f\xbf\x13\x8f\xa9\xcb\x2f\x9d\x84\xd7\xa4\x19\x4b\x96\x69\x83\xd5\x90\x2c\x25\xcf\x5f\xa0\xe5\x42\xa2\x7e\xf8\x60\xe8\x18\x85\xa3\x25\x6d\xb1\x86\x39\x60\xb7\x4f\x4b\xbc\xb1\xc3\xd2\x73\x5e\xc9\xca\x9a\x6e\xd1\xb2\x4a\x98\x37\x67\x45\x4f\xbc\xaa\x10\x8f\x57\xf8\xd2\x7a\x6a\x56\x11\xe8\x15\x5c\xb6\xf3\xa6\x95\xef\x99\x2f\xb5\x36\xbd\xc8\x2b\xe8\xc6\x27\x3e\x1e\xf9\x47\x48\x14\xf6\xb5\xd2\xac\xf0\x50\x92\x5c\x1b\x20\x31\x77\xdc\xc7\x26\xe9\x37\xa4\xdb\xeb\x6e\xc7\x35\x71\x5a\x9f\x7e\x3c\x5c\x79\x9c\x74\x5f\x05\x5e\x80\x9b\xe8\x33\x70\x6a\x31\x82\xfa\x49\xf2\x5f\x95\x55\x6e\x0d\xca\xfb\xd2\x4c\x29\x86\xbb\x7f\xc8\xe7\x85\xf9\xa8\x89\x74\xc1\x35\x3a\xef\x3e\x1c\xa1\x0f\x36\x24\x73\x55\x84\x89\x2c\x20\xff\xd2\x2f\xaf\x6b\x8c\xc9\x04\xfd\xcc\xa6\x50\xbe\x4f\x39\x45\x7e\x37\xf5\xc7\x23\x1b\x42\x90\xb6\x94\xa2\x6a\x77\x1a\x5b\x96\xf1\x97\x39\x39\xfe\xc0\xa9\x71\x89\x59\xf7\x13\xfb\xcc\x49\x46\xb6\x75\xfe\xe2\xc7\xc2\xcf\x8d\x96\xe0\xf0\xc0\xf1\xbb\x67\x39\xb5\xe5\xe6\x85\x42\xc0\x1c\xa5\x51\x16\x7d\x65\x38\xea\x2d\x04\x2b\xec\xdb\xca\x57\x86\x06\xf6\x4f\x1a\x0f\x12\x79\x67\xe0\x0c\xdb\x7d\xb4\x44\xc1\x45\x54\x51\x78\x87\x39\x54\x7d\x2b\x1d\x03\x6c\x6e\xfe\x9d\xe4\x75\xa7\x70\x3e\x19\x58\xf5\x38\x38\xd5\x71\xff\xee\x8e\x08\xf7\xc7\x5e\xab\xf2\x10\x52\xc1\x9e\xdc\x9b\xba\x28\x22\xa9\xab\xcd\xc8\x66\xfb\x51\x14\x73\x1a\x24\x87\xbd\x75\x5b\xd0\x69\xd8\x9b\xab\xef\xed\x6f\x24\xa8\x89\xba\x3b\x0e\xdb\x80\xe1\x55\xce\x3b\xa5\xf0\x78\xec\x35\x35\xfb\xe4\xdd\x4b\xfa\x8f\xcb\x1f\xde\x6d\x03\x84\xa7\xfa\xcf\xdd\x18\x80\xa8\x8a\x4b\xec\x28\x0f\x72\x20\xfc\xfe\xf4\x44\x86\x07\x01\x30\x21\x60\xe9\x08\x73\xb2\xab\x04\x52\x75\xe9\x8e\xd8\xc1\xe7\x0e\xc1\xb4\x7d\x10\x3b\x15\x52\x66\x97\x36\xa8\xe4\xf7\x54\x2f\xd4\xad\x23\x73\x15\x97\x00\xaf\xf2\x7c\x8a\x10\x71\x0f\x81\x0e\x14\x9a\xf0\x82\x21\xe1\x0b\xbc\x5a\x78\x11\x30\xea\x80\x22\xfe\xf6\x89\xe1\x7e\xbb\xb8\x6c\x5f\x1a\x51\x92\xd6\xe9\x76\x83\x89\xd8\xc6\xf8\xc0\xb5\x89\x5b\xad\xd6\xfa\x91\xd0\x72\x52\x61\xb8\x35\xe1\x0b\x62\x90\x78\xa3\x7d\xab\x8f\x36\x31\x13\x09\xef\xef\x2a\x27\x12\xb0\x25\xd8\x73\xb9\xa8\xcd\x21\x2b\xf0\xdf\xfd\x9e\xb2\x6b\x98\x37\x19\x52\x77\x83\x44\x51\xb7\x23\x91\xf3\x23\x98\xf1\x2f\xc2\xfa\xfe\xea\xef\xe4\xf3\x3b\x90\x6c\xdd\x63\x8c\xd1\xbb\xdf\x86\x25\xe8\xde\xd6\x83\x69\xde\x2e\xa7\xce\x49\x54\x77\x18\x04\x47\x49\x04\x5f\xe0\x16\x73\xdc\x35\xbb\xf1\xbb\x44\x6d\xa2\xb9\x4a\x79\xd0\x81\x56\xb7\x2a\xee\x50\xbf\x70\x9f\x07\x0f\xcf\x67\x8d\x2d\xd2\xca\xcb\xfe\xe6\xbc\xd1\xeb\x71\x67\x59\xca\x91\x84\x61\xe1\x6c\x16\xb3\x60\x96\x01\xe9\x48\x0f\x5a\x08\x1c\xe4\x1a\x65\xd8\x92\xd1\x75\x82\xaa\xf2\x87\x33\x39\x48\xb9\x3c\x40\x17\x21\x8c\xcf\x90\xd4\x60\x11\x85\xf3\x5d\xdf\xa6\xf9\x04\xd0\xb4\xb4\x3f\x65\x8b\xbb\xae\x59\x16\xa7\x6f\xcb\x54\x14\x43\x00\xe7\x18\x07\x8a\x2e\x4f\xea\x60\x5d\xfe\x10\xec\x76\xb2\x4c\x42\x30\xf6\xe6\x77\x4c\x97\x36\x99\x16\xc9\x7e\x03\x4d\x2a\x91\x34\x76\xa3\xf0\x49\xd6\x63\x14\x78\x08\x83\x38\x1c\x38\xff\x64\xf6\x62\x6f\x8c\xf6\x38\x7f\x43\xc1\x19\x2d\x9d\x67\x80\x39\x69\xb8\x2e\x73\x98\x5b\x43\xae\xa0\x3d\xc7\x7e\xd5\xa2\x44\x7d\xf2\x97\xce\x4f\x88\x94\xdf\x0d\xed\x3e\xaf\xdb\x76\xf0\x97\xf2\xf1\xec\x36\x9d\x49\x4f\x29\x41\x10\x18\x23\x2a\x68\x14\xb4\x6b\x77\x5c\x0b\x7a\xb5\x9a\x52\xb3\xfc\x66\x9b\x2c\x77\xc1\x12\x36\x74\x6b\x98\x77\xd8\xed\x06\xec\x5b\xe3\x97\xfd\x3e\xca\xd3\x07\x6d\x7b\xb3\x81\xb1\xed\xbd\x51\x91\x77\x7b\xc6\x4a\x7e\xdb\x53\x4b\x96\xa4\x3f\x51\x3d\x23\x3f\x3a\xc4\xb4\xdb\x67\x4c\xdc\x13\xb7\xfc\xee\x65\x40\x64\x77\x2a\x33\x63\x63\x20\x93\xe1\x36\xc8\x46\xce\xeb\x0f\xf1\x93\xc5\x82\x5a\xfb\xf5\x27\xfa\x48\xc1\xd7\xe3\x63\x58\xfc\x8e\xe2\x74\x2f\xb9\x45\x7d\xda\x55\xc7\x56\xed\xe0\x86\xe4\x86\x0a\xfc\xa7\x5a\x95\x43\xf1\x97\xd9\x51\xd9\xbd\x08\x16\x0e\x4b\x51\xa2\x7f\x2e\x45\xe5\x4d\x78\x36\x8f\xe0\x30\x1d\x95\x97\x3d\x44\xef\x07\x41\x85\xf1\x10\xd4\x89\x05\x6f\xff\x71\x49\x43\x54\x50\xf6\x1e\xd5\x67\x5a\x78\xe3\xb5\xb1\x8a\xbd\xd5\x9d\x5f\x65\x79\xf8\xd7\x91\x43\x02\x61\x7c\xea\x66\x39\xf8\x4e\xac\x05\x4f\xc9\xec\xad\x76\xe9\x25\x16\xb1\x3b\x53\x54\xd2\x2b\x2b\x30\xc9\x2e\x52\x87\x11\xfa\xda\xe4\xbe\xfd\x72\x33\x1f\x3b\x9d\xfa\xc6\xb4\xdf\xe1\xfc\xb5\x09\x05\xea\x13\x0c\x57\x65\xf6\x71\xea\x28\x3b\x82\x19\xdb\xd5\xe3\x4f\xca\xa6\xf0\x50\xdc\xf8\xe4\xe4\x74\xca\xfb\xa6\xe7\x2f\xfa\x26\x77\x4a\xd9\x65\xd3\x16\x3e\xa7\x91\x1c\x5d\x42\x71\xee\x37\x06\x1b\xb1\x49\x26\x78\x57\x8e\x3c\x10\x78\x6f\xe8\x50\xf9\x88\x1c\xe7\x59\x07\x7c\xe4\xc9\xe4\xb2\x6b\x9e\x55\x35\x6e\x89\x2b\x0f\x0d\x4f\x94\x31\xa3\xed\xdc\xee\x82\xf1\xf0\x21\x7d\x9c\x59\x82\x57\xc1\x96\xa6\xcb\x50\x84\xc7\xc2\x03\x24\xd2\xf9\xa8\x70\x55\xcb\x7c\xd0\xec\xd6\x9a\x03\xe5\x31\xef\x20\xac\x8a\x89\x7a\x2f\xa5\x72\xc5\x40\xb2\x3d\x32\xb5\x41\x4a\x55\xfb\xef\x36\xac\xb8\x48\xc8\x08\x4c\xda\x9a\x80\x90\x13\xa9\xaa\x34\xcb\x80\x56\x3b\x87\x5b\x55\xec\x32\xec\xd6\x38\xf5\xbc\xb7\x60\x6b\xff\x94\x20\xd0\x4a\xf1\xb4\xeb\xef\xae\xd3\x08\x14\x58\x96\x68\xfb\x87\x8e\xb6\x97\x4c\x20\x31\x91\xba\xc8\x05\x38\xe0\x42\xa5\x62\x72\xd5\x6c\xf3\xd6\xa6\x61\xb7\x10\x3b\x3a\x85\x1b\xce\x59\xd8\x2d\xd2\x1c\x48\x05\xb4\x67\xea\x0e\x38\x53\xd6\x50\x7a\x8a\x50\x84\x29\x8d\x3c\xbb\x06\x3d\x89\x91\xee\x6d\xc8\x3a\x72\xa7\x86\x48\x71\x3e\x5b\x64\xde\xa9\xc1\xa6\xef\x6c\x3c\xcc\x52\x0b\x2b\x7e\x3a\xd0\xf4\x2c\x9c\x27\x3d\x19\xdf\xcb\xdb\x09\xf3\xd4\x80\xd8\x6d\xa3\xdc\x28\x57\xc1\xd6\x27\x02\xc0\x7a\x44\xad\xb9\x84\x87\x05\x68\x11\x9c\x09\x15\x69\x59\x40\xce\xa4\x5c\x20\x0b\x8f\x94\x7d\xf7\xd1\xca\xa9\xbe\x2a\xf5\xbf\xce\x41\x92\x25\x6b\x76\x89\xb4\x0f\x4f\x63\xe2\xf9\x37\x25\x19\x56\x61\xa5\x00\x18\xd1\xd5\x7c\x75\xec\x25\xac\x33\xfc\xd6\x0b\x6b\x40\x0a\xd9\x7f\xce\x19\xf8\x88\x8a\xc2\x23\x3a\xa9\xae\x46\x4c\x4e\x07\x97\x78\x2a\x0a\x69\x16\x82\x0c\x45\x39\xd7\x76\xb0\xe4\xe5\x02\x3f\xf7\xe3\xbe\x59\x10\xbf\x07\x60\xbf\xaa\xd4\x02\x74\x8f\x69\x91\x96\x4c\xa5\x7c\xc7\xfd\x8e\x72\x52\x70\x12\x18\x07\xb4\x95\x78\x15\x1e\x61\x6e\x4b\xed\x37\xca\xbd\xcd\x1b\xed\xfb\x2a\xd1\xaf\x2b\xa9\xde\xba\x30\x2b\x73\xc6\x8c\x1d\x67\xbd\xb4\xad\x8b\xfc\x73\x4f\xf7\x9d\x52\x30\xc0\xba\x87\x91\xc7\xfd\x69\x64\x5b\x44\xaa\x86\x37\xcc\x27\xa8\x09\xdf\xa8\x2a\xd1\x65\xa6\x17\x29\x09\x22\xb8\xe5\x2d\x34\xf8\x2e\x11\x79\x38\x95\x2d\x30\xa1\x43\x41\xbe\xbb\x84\x32\x7b\xdb\xb7\xf7\x2a\xa4\x65\x21\xdc\xbf\xff\x3c\x01\x77\x2b\x0e\xfd\x4b\xe0\x5d\xcf\x13\x07\x76\xe6\x1f\x3f\x68\x9c\xdd\xa0\x62\x10\x0e\x20\x74\x56\x2e\x79\x95\xfa\xca\x8e\x3d\x22\x85\x6b\xa3\x52\xc0\x51\x3b\x29\x55\xa5\xcf\xd4\x60\x64\x99\x63\xe3\xd8\x3b\xb5\xfd\xc1\x91\x21\x4b\xc1\x93\xae\xf3\x16\x2d\x7c\x8d\x3b\x1b\xc0\x26\xe7\x5d\x1e\x31\x44\x5f\x1f\x1f\xd2\x02\x6e\xd2\x18\x21\xbf\x23\x2b\x65\x69\xa2\x34\xb7\x98\xf4\x53\x12\x61\xec\x0f\x2a\x2e\x82\x03\xb7\x0b\x4b\x99\x33\x09\x45\x33\x55\xa0\xb3\x93\x5f\xd8\x55\xe6\xa7\x35\x7a\x3e\xf2\x9a\x3e\x67\x84\x9d\xdd\x67\x06\x50\xcc\xbb\xdf\x6a\x82\x00\x71\x06\x99\x54\xa0\x74\xd5\x00\x2d\x98\x77\xae\x0b\x92\x31\xfb\x92\xbe\x01\x84\xf2\x67\x3c\x8f\xea\x93\xde\xe7\x72\xc7\x5c\xef\x19\xac\xaf\xa7\x70\x9b\xc0\x8a\x20\xf9\xa5\x47\xa2\x95\xce\x32\xc9\x23\xc7\x7e\x80\xea\x86\x75\xa6\xbb\xa5\x52\xe0\x7b\xe6\x9f\x00\x78\xd4\xbd\x2d\x46\x4f\x2f\x8b\x66\xec\x9f\xf6\xb2\x8a\x9f\x6c\x87\xf7\x2d\x4f\x3a\x3b\x2b\x23\x0f\xc5\x27\x49\x9d\xdd\x00\x9a\x10\x2c\x6a\x59\xad\xc3\x3e\x97\x36\x63\x93\x2d\x4a\x07\xdd\x0d\x9d\x0b\xe6\x59\xca\xf1\x60\x3c\x7a\xf0\x3d\xcb\x4d\x8c\x5f\x56\x8a\x31\xac\x05\x1a\xc2\xf0\x54\x3d\x26\xe7\x6d\xbc\x41\x8f\x1c\x34\xa1\x26\x0d\x7d\xc7\x04\x11\x23\x5f\xea\x1f\x5e\xc1\xd8\x45\x51\x99\x5a\x4e\xad\x86\x75\xd5\xee\x3e\xc2\x9d\xaa\xd2\xe0\x20\x5f\x62\x54\x97\x1d\x67\xb7\x73\x15\xdd\x11\x2d\x8f\xe3\x4d\xb4\x13\x98\xc1\x0e\x57\x0c\xe5\xec\x88\x9c\x82\xfa\x06\xf7\x62\x21\xdc\xa0\x12\x78\x9d\x0a\x99\x4f\x58\x67\xc4\x93\x38\x93\xfc\x1c\xe1\x5a\xec\xdd\x20\xf2\x46\x39\x86\x3f\xe4\xbe\xf0\x33\xd5\x3f\xe8\x10\xab\x94\xf9\xa3\xa9\x9f\x8f\xb4\x33\x7f\x05\x93\x67\x19\xa8\xd8\x81\xfb\x24\x6d\xc4\xfe\x0c\xab\x33\xe9\xa4\x4d\xa0\x63\x53\x63\xb6\x95\xb8\xc3\xf5\x79\x14\xfa\x2c\x31\x3f\x93\x22\xa3\xf5\x7a\x5a\x21\xfc\x57\x5e\x62\xa2\x8e\x8b\xbe\xca\x0e\x59\xd9\x10\xad\xe9\xbf\xb8\x25\xfb\x12\x46\xe8\x9b\xd7\x71\x88\x8e\xd1\x30\x9f\x08\x20\x6f\x46\x78\x22\xea\x76\x8c\xf1\xf8\x52\x22\x11\x11\x34\xd6\x34\x2d\xba\x57\x45\xa9\x70\x22\x45\x84\x74\x58\x5d\xfb\x6e\x66\x0b\x1c\x43\xcf\x9b\x68\x2a\x08\x54\xcd\x91\xbe\x35\x67\xb2\x89\x6c\x2b\x79\x09\x98\x95\x3f\xf2\x1f\x36\x66\xd6\xc1\x1f\x3e\x80\x67\xba\x09\x99\x0d\x53\xef\xe5\x27\x38\xc5\x69\x4f\x7b\xef\x85\x79\xd7\xb6\x18\x73\x34\xa6\xa1\xc0\x9f\x42\x28\xe2\x9e\xb6\xfc\x37\x59\x5e\xfd\x54\x4a\x63\x25\x08\x0b\x33\x69\xc4\xbd\x3f\xdc\xba\x61\x54\xde\x51\xba\x11\xf7\x7e\xfb\x92\xd9\x5a\x5e\x09\xc8\xdf\x8c\x5d\xf1\xb3\x7a\xab\xfa\x6c\xee\x02\x3e\x7a\xf4\xaf\x08\xda\xa1\xd5\x00\x14\x5c\xe0\x5d\xd5\xa1\x6e\x7f\xee\xfd\x65\xaf\x6a\x15\x09\x55\xa7\xf7\x15\x0d\x14\xf4\x2f\x9c\xbc\xab\xae\xef\x2b\x77\x07\x58\x7c\xe1\x4a\xd6\x29\x9f\xdf\x41\x0e\xc4\x5c\x47\x83\x91\xab\x9f\xa4\xd6\x73\xd7\x23\x7a\xe1\xdd\x8b\xe0\xd0\x3b\x6f\x47\x0d\x57\x3d\x82\xaf\x8c\x81\x38\x92\x8c\x57\xef\xe5\x4d\xb3\x5a\xec\x28\x64\x71\x75\x25\x9a\xe0\x72\xd0\xae\x08\xe2\xee\x10\x2b\xba\x13\xa3\x6f\x1a\xb7\xb5\x0c\x97\x94\x87\x0b\xaf\x48\xa8\x14\xfc\x33\x9f\x9a\x66\xa2\x44\x65\x81\x5f\x9f\x6f\x0f\x53\xd1\x3d\xf5\x96\x76\x88\x1f\x84\x8e\xf7\x95\x4e\xf1\xda\xa8\x4f\x1c\xc4\x1a\x51\x1c\x1d\xb4\x34\xe2\xd5\x56\xbe\xb5\x57\x1c\xa3\x57\xf1\xf2\x01\x14\x24\xb7\xca\x68\x36\x48\x32\x7a\xdd\x73\xb0\xab\x5c\x00\xad\x3e\x37\xbc\xb1\xad\x72\x27\xd6\x44\x18\xe7\x0c\x9f\xd6\x73\x0b\x67\xa0\x53\x9b\x4d\x78\xec\x63\x90\x76\x35\x4f\x1e\x38\xf0\xe2\x31\xbf\x4a\x10\x04\xc2\xab\xe6\xb4\xf7\xf4\xb5\x45\x01\x71\x45\x05\x51\xcf\x9f\x09\xa3\x27\x3c\x70\x26\x84\x29\xa3\x2c\x0d\x78\x05\x1c\xe1\x59\x77\x20\x5e\x50\x69\x69\xa4\x86\xd8\xe6\x13\x41\x60\x3b\xf9\x24\x56\xda\xfd\x8a\x82\x3d\x38\x6d\xfe\xd4\x59\x63\xef\xc8\xde\xf3\xaf\x04\xe9\x57\x1d\x76\xe2\x1e\x24\x58\x64\xbd\xc9\x07\x5c\x1b\x98\xbd\xc2\x7a\x87\x75\x41\x38\xe7\xdb\x76\xa3\xf7\x09\xb6\x94\x94\x3b\xd8\x13\x73\x2a\xae\xc4\x98\x55\x93\x4f\x2f\x06\xca\xbe\x8b\xda\x38\x6b\x17\x21\x9b\xca\x6a\x37\x2f\x6d\xbd\x0e\xf0\x32\x6e\xce\xad\xea\x87\xe7\x11\xbb\x64\x30\x53\xed\x81\x05\x52\x51\x55\x8d\x6e\x87\xfc\x82\x03\x72\x36\x72\x0c\x28\xf0\x9a\x6a\x9e\x4f\x9a\xd5\x4e\xf9\x56\x5f\xbd\x48\x9c\x3c\xe5\x5f\x7c\x04\xc2\x20\x63\x1f\x21\xdf\x7f\x62\x35\xe3\x15\x02\x6b\x4e\xbb\x97\x7d\x47\xa8\x43\x27\xfb\x4b\xdc\xde\xe4\xd1\xc3\x56\x85\xab\x8e\x5b\x89\x5c\x9a\xc7\xb0\x1d\x1a\x3d\x28\xfb\x11\x9e\xe6\xfe\xe2\xc0\x57\xb9\xd0\xe4\x48\x4c\xca\x24\xad\x6c\x8e\x14\x9e\x2c\x28\x2f\xb7\x14\x65\xa6\x98\x73\xc4\x36\xdc\x3d\x4d\x48\x07\xbd\x8c\x83\x1d\x28\x7c\x51\x3c\x10\xa8\x17\xb1\xac\x05\x62\x82\xc8\xa7\x71\xcd\x7d\x8a\x8e\x70\x34\x8b\x9d\xfe\x28\x1a\x2e\xf5\x07\x3b\xf3\x6a\x07\x95\x3c\x17\x91\xd1\x25\x9b\xb4\x25\xfe\x16\xb4\x51\xca\x01\xee\xe3\x64\xef\x93\x20\xcd\x3e\xb9\x7f\x0d\x3b\x07\x3b\xdd\x7f\xfa\xd0\xf2\x4f\x70\x00\x44\x32\x67\x18\x68\x89\x5b\x4f\x98\x4d\x56\x38\x2d\x8e\x28\x85\xb1\x9f\xed\x53\x21\x53\x61\x5a\x4a\x57\x83\xdb\x8f\x12\x4f\x13\xa2\x2c\x8f\x26\xc9\x67\x7c\x40\x8e\x5d\x89\xc6\x1c\x48\x2a\x0a\x36\xd1\x81\x58\x1d\x02\x84\x80\x11\xa9\x50\x85\x4f\x38\x6f\x9f\x2f\x5a\x36\xa6\x61\xbf\x6d\xab\xd2\xfe\x85\x3e\xa5\xa8\x51\xb1\xba\xad\x70\x4c\x74\x5e\x71\x2b\xdb\xed\x11\x34\x69\x8c\xf9\x14\x8c\x5e\x44\x70\x7b\x01\xbd\x77\xb4\xcb\x56\x4a\xeb\x77\xad\x7d\x63\x30\x79\x4d\x44\x5a\x98\xe0\x6f\xfb\xec\x16\x38\x78\xfc\xc0\x73\x97\x4d\x31\xd8\xc8\xda\x8e\x68\x4f\x9c\x89\x75\x3e\xfe\x9f\x6c\x09\x7d\x91\x0a\x8d\x2c\x6e\x9f\x18\x03\x6c\x38\x78\x4a\x1c\x35\x24\x28\x47\xe1\x18\xd5\x76\x34\x9d\x25\x47\xb4\xac\x18\x39\x04\x17\x3b\x0d\xb4\xbc\x2e\x4a\x1a\xdc\xc3\x6a\x74\xff\xff\x65\xbf\x50\x18\xb8\x67\x6b\x5d\x19\x46\xb3\x63\x97\x20\xf4\xb0\xb9\x76\x0c\xa1\x43\xf4\x23\x73\xb6\x68\x48\xb6\xef\x63\xbc\x0b\xad\xa5\x6a\x78\xdf\xab\x0d\x94\x71\xa1\x32\x7f\xec\x28\x91\x29\xd6\xda\xfb\x8b\xa4\xd9\x71\xf8\x70\xa0\x48\x22\xad\xf4\x66\xc4\xc8\x61\xf5\x11\xa9\xd7\x47\x1f\xf1\x23\xdb\xcf\xa4\x7a\x4d\x1c\xc0\x02\x56\xf5\x9a\xe9\x1e\xb8\x23\x2d\x95\xfa\xdb\x42\x47\x58\x17\xe6\xaa\x3a\x5b\xec\xfe\xd4\xb7\xdb\xd6\xa6\x6c\x7f\xbd\xb6\x0b\x94\x63\x51\x18\xdd\x0b\x03\x2e\x62\xca\x3f\x33\xc8\x4c\x9c\xee\xf3\xfa\xe5\x9a\x7c\x2a\x39\xdb\xcb\x53\xbc\x1b\xf8\x4c\xb2\x67\x51\xd4\xd0\x58\x5b\x1b\x53\x6f\xfb\xfd\xbe\x5d\x2d\x81\x50\x8f\x0a\xcd\xc8\x92\xca\xc2\x1e\x91\xe4\x58\x7b\x73\x7e\x0c\x6e\xb0\x2e\x7c\xf5\x17\xa2\xdf\xe7\xf2\xf1\x3b\x1a\xde\x3d\x92\xcc\x05\x0b\xe2\xc9\x49\x61\x3e\x9b\xeb\x5a\xf6\x9a\xe4\xd0\xc0\xba\x9c\x94\xfe\x4a\x4d\xd7\xfc\x06\xc0\xad\x51\x33\xb4\x84\xfe\xe1\xa5\x46\x76\x48\x41\xef\x8e\xda\x65\x51\x02\x0d\xb9\x54\x42\x35\x5e\x6d\x75\x34\xef\x3d\x37\xf2\x51\x7e\xd9\x19\x29\x80\xae\x0e\x1e\x89\x26\x8a\xc1\x7a\x47\x56\xa7\xbd\x60\x82\x2f\x22\x86\xc7\x97\xd2\x89\x5a\x89\xb3\x09\x8d\x86\x64\xfd\x4c\xb2\x74\x0c\x46\x6b\x67\xad\xe2\x25\x7a\xec\x36\x6b\xa4\x90\xe8\xa5\xe9\xbd\xa9\x26\x68\x18\x2b\x0b\x77\x44\xd5\x47\xac\x23\x66\xab\x88\xbb\xe6\x03\xdf\x4d\xbf\xea\xb6\x7c\x3b\x15\xf6\x85\xa9\x11\x77\x85\x13\xbf\x9e\x5c\xac\x2d\xaa\x9e\x57\x1a\xb6\x44\x4b\xc0\x77\xe4\xcd\xc0\x89\xe9\xe0\x22\x70\x8c\x0b\x73\x7a\x61\x9b\x99\xf4\x8d\x2b\x2d\xbf\x9c\x3e\x50\xcd\xc1\x0c\x24\x7c\xf9\x96\x36\xfe\xdd\xa4\x7f\x17\x1c\x36\x7d\x11\x3e\x0f\x57\xea\x62\xda\x76\xb7\x04\xcc\x88\xd4\x25\xa6\x77\x96\x10\xa1\xc3\xf5\x78\x67\x8d\x54\x9e\x31\x06\x87\xae\x5f\x44\xf3\x60\xb7\x27\xaa\x16\x09\xa3\x70\xf8\x75\x84\x2b\xda\x71\xc7\xeb\x75\x54\x46\x71\x1d\x31\x20\xa3\xdb\x93\x0f\x1b\xf2\x44\x9d\xa0\x02\x7f\xed\x84\xf0\x9f\x86\x82\xe4\x57\x53\xed\xcd\x5e\x6a\x5f\x04\xea\x60\xa6\xa7\x32\x48\x67\x40\xfd\xbf\xbe\x29\xf5\x9f\x64\x12\x2b\x4c\xa8\x4d\x23\x47\x33\x6b\x28\xb0\x05\x5c\x82\xdd\xa9\x85\x53\x55\x34\x78\x8a\xbf\xa9\x03\x8d\xf3\xd7\xf2\x49\x01\x9c\x04\x30\xbb\xe6\x2e\xcc\x15\x41\xc1\x94\x9f\x22\x86\xb1\xdc\xa2\xec\x56\xa2\xfd\xc4\x72\x33\xf6\x6f\xa9\xaf\x48\x82\x6f\xa4\x1a\x05\xc0\x63\x1f\x3a\xc3\x29\x65\x18\xb4\x09\xbd\xb4\x2f\xfd\xb3\x45\xf5\xe1\xf6\xe9\xf6\x13\x41\xf2\xdc\x6b\x51\x72\x39\x50\xde\xd0\x66\x69\x3c\xe7\xa3\xfc\xbb\x2b\x89\xf6\xc2\x48\x3d\xf3\x5d\x2b\x6c\x8e\xe7\xd4\x7f\x23\xbb\x09\x00\x4c\x58\xb1\x48\xaa\x88\x6c\xa8\xb0\xcc\x08\x71\xef\xd8\x58\x35\x57\x88\xae\x50\x62\x4d\x51\x62\x3d\xc3\x93\xe5\xe5\xe6\x42\x4f\x84\x4a\xf9\x23\xcd\x24\xc0\x4a\x73\xfb\x03\x6b\xbd\x65\x5d\xfd\xd4\x3b\xf5\x84\x51\x5f\x6c\x4c\x4f\x7b\xae\xcd\xc2\x93\x43\x6e\x87\x61\xdd\x3a\x63\x95\xa0\x23\x0f\x63\xbb\x2b\x72\xe3\x46\xfe\x42\x7f\x6e\x04\xf8\x90\x09\xfa\xe1\xa0\x71\x79\xe5\xde\xba\x2c\x16\x53\x7e\x3c\x80\xcf\x11\x29\x34\x8d\x0b\x53\xaf\xeb\x88\x41\xff\x99\x5e\x51\x22\xb5\x64\x1a\xdb\xa1\xc2\xc0\x78\x8f\xaa\x69\x0d\x7a\xe8\xf2\x54\x60\x1f\xbd\xea\x90\xbf\x79\xcb\x17\x9f\xd1\xd9\x00\x80\xec\x1d\xf4\xa3\x0b\xf8\xec\xbb\x95\x48\xe9\xd2\x46\x77\xcc\x0d\x0a\xf3\x58\xe2\xc6\xaf\xf9\x63\x5a\x11\xc5\x62\x44\x7e\x76\xdf\xbf\x90\x8c\xe3\xcf\xe3\xa3\xc8\xa0\x8f\x6f\xcc\x4e\xe3\x8f\x17\xd2\xae\x41\xc1\x40\xf6\x94\xac\x5e\xf1\x69\x39\xf3\x74\xdf\xd0\x8c\xcb\xde\x00\x45\xe8\xc6\x6d\x47\x2a\x30\x46\xa6\xf0\xc6\xb0\xdd\xe4\x08\x2a\xff\x1e\x5e\xb4\x4b\x93\xb9\x03\x10\x61\x88\xe7\x14\x57\xd9\x99\xed\x96\x2e\x22\xc4\x9c\xc9\xdb\xee\x63\xfa\xac\x82\x5b\xbd\x9b\xc6\x6c\x90\x33\x90\x85\xc2\x5d\x6b\x6c\x0e\x82\xa6\xe9\x8a\x19\x08\x08\x99\x3a\x60\xf7\x44\x3b\x49\x20\xa6\x21\x0c\x16\x6f\xc6\xae\x2b\x6a\x74\x37\x36\x2d\x6b\x30\xeb\x3c\x88\x2e\x29\xac\xa3\xf7\xa1\xce\xea\x94\x54\x61\xa5\xe1\x4f\x88\xab\x44\xa4\xec\x2e\x07\x25\x5b\x9d\xf2\x2a\x9b\xc5\x55\xa7\xf9\x9a\xac\x6d\x91\xd0\x40\x57\xe5\x72\xef\xd1\x1b\x09\x40\xf1\x27\x2a\x78\x79\xba\xb7\x33\xac\x02\xbc\x3e\x0c\xef\x1f\x40\x26\xdf\x9e\xad\xca\xc4\x6e\x1d\xfc\x57\x5e\x7b\xc8\x35\x8f\x69\x22\xf7\xef\x09\xb6\xfb\x4a\x88\xc9\x63\xf8\x2e\x64\x65\x83\x30\x22\xa6\x0d\xf7\x2f\x8c\xe6\x1d\x06\xb1\xa2\x91\x45\x88\xd5\x50\x72\x05\x07\xe8\xc5\x9b\x6e\x0c\x6b\x1f\xbb\xba\x07\x71\x73\x14\xb1\x37\x36\x44\x62\x94\x73\xe9\xf3\xf8\x24\xc2\xac\xb9\xf5\x77\x4f\x18\x15\xea\xa6\xfe\xef\x3f\x7f\x38\x27\x91\xe5\x90\x3f\xfe\x20\x57\xce\xef\x5d\x18\x2b\x33\x17\xf3\x45\xcc\x28\xab\xb8\xce\xcb\xdc\x6c\x71\x04\x25\x0f\xf7\xa1\xd2\x44\xcc\x64\xfb\x8d\xe7\xcc\x3b\x74\x88\x81\xc4\xe0\x48\xb5\x2f\x14\x54\x31\xe4\x75\xe7\x24\xd4\xfa\x57\x6d\x00\xb6\x47\xf2\x6b\xe8\x95\x30\xb0\xd1\x18\x00\x7f\xbb\x7c\xd9\xe5\xd9\x5d\xe2\xae\x05\x3b\xb2\xb8\xe2\xac\xa7\xda\x22\x09\x47\x7e\xa3\x56\xf5\x08\xfc\x9d\x02\xaf\xc5\x30\x21\x0a\x19\xd6\x34\xdb\x6f\x4d\x56\x9d\x13\x8e\x84\xf2\x6c\x41\x8f\x3d\x22\x44\xbb\xab\xb0\x76\x52\x7b\xb4\xdc\x61\x64\xd9\x2d\xce\x8c\x13\x57\x21\x2b\x11\x32\x7d\xa4\xbb\x00\x51\xfb\xe1\x54\xb9\xfb\x4f\x69\xda\x33\x0f\x8b\xa4\x77\x52\x49\x2f\xdf\xbb\x91\x46\x29\xfa\xe1\x35\xf2\x65\x65\xf8\x3e\x6a\xd7\x98\x29\x60\x05\x34\xb2\xec\x70\xd2\x72\xf5\xed\x6c\xc3\x1f\x5b\x36\x0c\xa9\xce\x6b\xa4\x3b\xee\x5b\xe4\x6a\x40\x41\x8a\x45\x3b\x54\x80\xdb\xdb\x23\x8d\x6a\x2a\xc2\x6f\xaf\x36\xde\x53\x2a\x93\x76\x2a\xab\x5d\xa2\xa1\x97\xd3\x01\x19\x46\xc0\x80\x7d\xe6\xa4\x4a\xc6\x57\x25\x98\x20\xe7\xde\xd4\xa7\x7b\xe2\x9d\x7b\xda\xc9\xed\xe1\x85\xbe\xf6\x5f\xb4\x48\xda\x79\x4e\xc7\xa7\x45\xb2\xc3\xa9\x49\xbf\xcf\x4e\x36\xfd\x3a\x68\x78\xe5\x4c\x08\xc3\xcf\xf3\xd2\xb1\x7c\x04\x60\x73\x4c\x6c\xe4\x31\xb3\x23\x17\xa9\x6c\xf2\x1a\x62\x60\x9f\x1f\x90\x7b\x18\x49\x38\x35\xc2\x6f\xa7\xbd\x31\xdb\x27\x39\xe5\xc2\xa8\xb7\xca\x09\x01\x90\x87\xd7\xc5\x56\x35\x70\x5c\x5c\x23\xcd\x76\x63\x25\x42\x81\xc9\xc3\x85\x79\x8d\xbe\x44\xd6\x8f\xb7\x59\xb4\x55\xb5\x3d\xb7\x4b\xac\x57\x2e\xc1\x5d\xb6\x9a\xd8\x87\xae\xde\xe1\xf2\x73\x8b\x78\x60\x60\xef\xc2\x58\xc6\x83\x00\x6d\x1f\xfc\x64\x1a\xb5\x42\xe7\xa7\xe6\x0a\x83\x12\x6f\x9f\xee\x75\x9f\xa3\xa6\x79\x65\x52\x01\x96\xfa\x94\x35\x11\xe9\x7e\x4b\x89\x7e\xd0\x36\xbf\xbd\x79\x3b\x2e\xf9\x39\xff\xe3\x03\x2e\x89\x6c\xba\x49\xcf\x5b\x22\xc5\x15\x83\xcf\x48\xa7\xbb\x0f\x4f\xb5\xf0\xd2\x87\xcd\x56\xcb\xf4\x0d\x5a\xc4\x8c\x9e\x12\x8b\x3f\xa6\xcc\x72\xb7\x75\x84\x76\x3a\x8b\x4b\xcd\x26\xbd\x0a\xb6\xf1\xea\xd7\x4f\x9c\xc1\x4c\x35\x3f\xb9\xcf\x82\x1e\xf5\x70\x38\x7a\x56\x7a\x68\x0b\x33\x1a\xeb\x02\x98\x77\x21\x78\x64\x87\xb8\x9c\x94\xee\x45\x47\xa3\xb5\x7a\x97\x8c\xbe\x8e\xac\x19\x54\x20\xa2\x4f\x7b\xef\xc9\xc6\xf7\x8b\x65\xe3\x34\xba\x1e\x6d\x90\xf4\xb4\x77\xda\xb7\xbf\xe8\x2d\x7d\x02\xad\x0d\x30\x8b\xf1\x2c\x19\xf1\x70\x6f\x8c\x58\x1b\xea\x96\xc4\x14\x2e\xda\xd0\xca\xbf\xce\xb1\x03\xe0\x4b\xdd\xcf\xbd\xf0\xb6\xde\xaa\x5c\x56\x73\x7d\x8d\x44\x86\xfa\x0f\x93\xa4\x87\x14\xd9\x1f\x1d\xe1\xc0\xbb\xe0\x58\x72\x0f\x4f\xaa\xd8\xc1\x8a\xe6\xd1\xcb\x8f\x0e\xac\x3c\x37\xbc\x5e\x02\x7a\x5a\xe7\x15\x2a\xd9\x8e\x25\x7f\x97\x74\x0b\x76\x1c\xa2\x76\xbf\x3d\x31\xdd\x76\x20\x4e\x9a\x64\x7d\x93\x06\x25\x40\x73\x64\xde\xd4\x71\x17\xf2\x57\x05\x5d\x54\xef\xa3\x61\x41\x37\x3e\x64\x06\x36\x49\xd5\xe2\x47\x50\xd6\xeb\xa8\x21\x96\xd9\x7c\x93\x75\xac\xe6\xcf\x3b\x74\x10\xf9\x03\x16\x71\x6f\x53\xb2\xfb\xc5\x31\x72\x07\xbd\x96\x91\x2c\xa4\x1a\x43\x0e\x6e\x28\x20\x60\xf9\x75\x76\xc2\x0e\x90\xbd\x56\xf0\xdc\x6d\x47\xcc\xf5\x20\xac\x0c\xcd\xb2\x6f\x40\xc7\xef\xfd\x3e\x11\x20\xc9\xef\x69\x1c\x6f\xa4\x52\x65\xec\x84\xbe\x9e\xc3\xed\x1a\x3e\xac\xaf\x98\x67\xdf\xff\x3a\xa1\x1e\xb1\xa8\x6d\xcb\x52\x5f\xe8\xfe\xa2\x04\xa4\xce\xd4\x6a\x3b\x80\x86\x5e\x75\x45\x4a\x6c\x3d\x75\x2e\x21\x0d\xe0\x4a\x02\x41\x8e\x48\xaf\x3c\xf2\x28\x07\x4a\x8d\x60\xa0\x1d\xce\x9b\x26\x99\xb4\x74\x11\x99\x0b\xb9\x4e\xba\xbf\x3d\xf1\x82\x0c\x2f\x28\x9c\x15\xdc\x2d\x39\x4e\x7d\xff\x84\xf4\x5b\xea\xb9\x65\x05\xc3\x7c\x6d\x15\xea\xda\x03\x78\xf1\xc5\xf4\x9b\x96\x41\x52\xb6\x68\x1f\x0a\xc7\x35\xe9\x92\x45\xfb\x45\x13\xa0\xf6\xea\xcb\x71\x36\x3c\x19\x7c\xa3\xa9\x5b\x40\x05\x60\x76\x3c\xe8\x1c\xf8\xe6\xc9\x37\x97\x28\x6a\x67\x64\xc9\x3c\x98\xbc\x04\xfb\x16\xfc\x9d\x1e\xf9\xae\xba\x76\x02\xc9\x89\x44\x2e\x77\x9a\x4f\x6a\xa8\xa7\x7a\xfe\x58\x96\xb5\xa9\xec\x6d\x19\xfc\xcc\xda\xc9\xf0\x6a\x2a\x0b\xcb\xbb\xac\xfe\x6a\x64\x12\xde\x58\x47\xb6\xc0\x90\xc9\x09\xd0\x1b\xd3\xd0\xc9\xed\x05\x9b\x39\x6f\x2d\x1f\x5a\xad\xea\x9a\x7e\x8c\x4e\x34\x4d\xa2\xac\xf8\xae\x96\x8b\x80\x9f\xe1\x43\x8a\xa6\xed\x1b\xba\x25\x90\xf8\x16\x7a\x1f\x58\xfb\xb0\x80\x82\x99\x9e\x3f\xf9\xc1\x36\x1e\xcd\xbb\x72\xa0\x39\xcd\x9a\x99\xd0\xa4\xa7\x30\x93\x02\x3d\x45\x11\xfe\x4b\x1e\x81\x4d\xff\x3f\x36\x2f\x42\x9e\x53\x23\x4a\x87\xce\xdd\x89\xd0\x2d\x02\xb8\xab\x11\x72\x7e\xb4\x68\x8e\xa0\x63\x7a\xb7\x24\x08\x9b\xd9\x81\x3e\xe4\xb6\x3f\xc5\x6d\x51\xbe\x38\x2e\x0e\xca\xf0\xbe\x89\xdb\xe4\x27\xc9\x78\x9a\xb2\x7e\x0e\xc0\x1b\xd5\xe8\x9d\xc3\x23\xcc\xca\xc5\x2b\x52\xd2\x87\x7c\xf3\x7d\xbe\xee\x27\xa7\xd7\xee\xfb\xc6\x05\xf9\x59\x57\x84\xa2\xb9\xdc\x87\xff\x56\xbd\x2a\x01\x34\x63\xbb\xac\xdf\xde\x0d\xe2\x39\xaf\x1c\x42\x35\x0c\xaa\xc2\xa0\xc9\x7e\xbb\xd8\x66\x30\x00\xe2\x2e\x82\x2c\x3d\x3e\x0e\xf9\x9f\x15\x77\x0b\x09\x5b\x3b\xfd\xcb\x56\x79\xc1\x7b\xea\x17\xbf\xa6\x44\xa2\xdd\xc5\x61\x56\x4d\x4c\xfd\x0e\x43\x78\xdb\x3c\x68\x94\x60\xdb\x04\x77\x6b\xaf\x6b\x36\xde\xff\x67\xcc\xab\x16\xe5\xf1\x77\x65\x10\x0f\x14\x09\x69\xdc\x06\x94\x4e\x5b\xfe\x0b\x0a\xe7\x7b\x69\x73\x2a\x5b\xa7\xb0\x72\x72\x5e\xe7\x0b\xdb\x35\x47\xe8\xd9\xdf\xc6\x0a\x87\xb9\x83\xe1\x37\x43\x6b\x3e\xb7\xdb\x07\x0a\x0f\x9a\x78\x28\x72\x91\xdb\x41\x4b\xc8\x05\x4e\xe3\xfb\x43\x58\x75\x94\x05\xc2\xee\x07\xd1\xe4\xe6\xe5\x01\x93\xa7\x1c\x54\xb6\x5f\x18\x89\xcc\x98\x81\x75\xf2\xbb\xf1\xbd\xe2\x82\x36\x52\x4d\x0a\x69\xcb\x9a\xc2\x43\x3c\x61\xef\xcf\x5a\x22\xed\xc0\xd1\x95\xf0\x80\xc5\x60\xbe\x70\x2c\x7f\x37\x16\x5c\x69\x9b\x86\x03\xcc\x82\x9b\x16\xcf\xd0\xe0\xd6\x53\xf7\xaa\xf4\xc7\x74\xde\x02\x74\x5c\xec\xf9\x20\x58\xa3\xfc\x83\x53\x46\x07\x1b\xef\x65\xeb\xd5\x1b\x8c\x85\x24\x6d\xb1\x26\x66\x78\xfb\x71\xb7\x72\x8e\x79\x12\xdf\x76\x8a\x42\xe7\xc6\x50\x99\xdb\x53\xe4\xa9\x84\x3e\xaa\xaa\x3b\xc1\xa2\x71\xc8\xcb\x15\x2b\x9f\x84\x4d\x8d\xb3\x3f\x42\x73\xba\xc9\x94\x2a\x4a\xa3\x65\x10\xfb\xa6\x8a\x49\x64\x57\x77\xf2\x23\x96\x87\x1f\xf7\xad\x4b\x68\x2d\x7c\x50\x45\xb9\x13\xd6\xe7\x76\x93\x21\x9d\xda\xc9\x56\x81\x41\x86\xff\x50\xbb\x52\xc4\x93\xcb\x2e\xe6\x91\xba\x26\x8c\x7a\x90\x14\x46\x8d\xd3\xad\x30\x28\xf8\xa7\x86\x8d\xd5\x1b\xe1\x76\xc4\x7e\x16\xb4\x5f\x25\xa2\xe9\x86\x28\x83\x8e\x86\x73\xf4\xf5\x15\xc0\x8f\x55\xec\xaa\x11\xad\xcb\x2b\xa4\xc3\x4e\x32\xf4\xb9\xe4\x37\x04\xee\x1d\x8e\x71\x61\x41\x5b\x0a\x86\x8f\xb3\x74\x34\xdb\xeb\xbc\xf2\xa3\x6d\x16\x9a\x37\x4d\xe1\xa1\xf8\x5d\x42\x45\xef\x0f\xe1\x63\x95\x0e\x71\x53\x15\x1d\xe5\xbb\xdb\x72\x29\xa7\x0d\x81\x54\x43\x7d\xa9\xb7\x53\x35\x54\x64\xb8\xfb\xc5\xc9\x40\xa2\x0f\x78\xe7\x57\x43\xaf\xe9\x9c\xc5\x31\x3d\xde\x04\x69\xa4\x70\x68\xd3\xe7\xe2\x6d\x1b\x64\x7c\xc1\x3f\x25\xe0\x8b\xe2\xb1\x4b\x89\x37\x90\x08\x87\x52\xe8\xfa\xd1\x69\xf0\x13\x79\x4b\x5c\x22\x44\x83\x66\x1b\x25\xeb\x09\x25\x2e\x91\x20\x3b\x92\x03\xc0\x72\x61\xbe\xe6\x59\xb6\x9d\x7a\x55\x24\xc8\xc0\x8b\x9f\x23\x42\xf8\x30\x02\x26\xf4\x5c\x56\x9a\x0a\xb8\x4b\x96\xec\x86\xa6\xd4\xc0\x25\xbb\xfb\xdd\xdc\xc4\x1d\xb3\xb8\xbb\x25\x58\xe0\x88\x33\xa4\x46\x0d\x42\xdd\x26\x90\xac\xdf\xe0\xe8\xaa\x0a\x9a\xe0\xde\xc7\x46\xee\x9f\xac\x0b\x57\x18\x78\xd1\x13\x4a\x20\x1f\x93\x11\xd9\xdd\xd3\x27\x11\x88\xf2\xdb\xd3\x0a\x42\x96\x1d\xb6\x70\xdb\x85\x87\x3b\x02\xd4\x30\xbd\x81\xcb\x96\xb6\xf0\x2d\xbf\x3b\xee\x00\xb0\xdd\x1e\x69\xb4\xb8\x1e\x49\xc1\xb2\x97\x06\x50\x2b\x72\x4a\x64\x5f\x84\xf9\x74\xf3\xf2\x0c\xc3\x00\x28\x8f\x88\x16\xdf\xde\xbb\xd8\xd6\x73\x25\x46\x7a\xf9\x9f\x84\x49\x96\x88\xbb\xd6\x4d\x2b\x97\x1f\xa4\x34\xa5\x80\x21\x63\x94\xfe\xb3\x1d\xee\xde\x07\xd9\x7c\x78\x5d\xca\xd7\xde\xae\x4c\xd1\x02\x70\x3a\xf2\xf3\xd4\x10\x39\xb5\xe7\xc1\x96\x49\x34\x9d\x4f\x98\xbf\xd9\x2d\x7a\x36\x23\x65\x21\xa8\x58\xb5\x08\x0e\x2f\x76\x94\xfa\x01\xfa\x8c\xf2\xe7\x8e\xa6\xff\x77\x30\x19\x63\xd1\x07\x9d\x8c\xf4\xef\x69\x6b\xb1\x5d\x23\x8a\x68\x59\x48\xfa\x21\xa2\xe0\xe3\x3a\x52\xd3\xe5\x46\x5f\x9a\x31\x8d\x9c\xd6\x3c\x6f\x6d\x3b\xe4\x29\x41\x4a\xab\x7d\x19\x28\x14\xad\x97\x3f\xf4\x5a\x1c\x3e\x49\x0d\x56\xb3\x15\xb0\x43\x5e\x06\x48\x8b\x32\xb3\x7d\x43\x0b\x05\xe5\xa9\x7a\x27\xe8\x51\x7d\xc4\x8c\xf7\x61\x90\x87\xa9\xbd\xea\x9f\xbd\x4d\xde\xfa\x14\x8c\xc9\xee\x73\x28\x15\x33\xba\xa2\x23\x47\x80\x8c\x8f\xea\x1e\x31\x48\x8f\x9a\x48\xd3\x8f\x9f\x83\x8c\xad\x08\x76\x3f\x34\x45\xd7\x3c\x9d\x24\xdb\xae\x6a\x6c\x16\xf6\xcf\x56\xe5\x69\x25\xa7\xa0\xae\x41\x2c\x70\x27\x8f\x9c\xd7\x2e\x97\xd0\x6f\x4a\x35\x43\xd3\xea\x44\x73\xcb\x7e\xd2\x8b\x98\xf4\xf7\xd8\x6e\xa5\x5b\xd9\x7d\x3e\x19\x78\xb6\xc4\xd4\x22\x2d\x14\x09\xa0\x23\x25\xe4\xb4\x28\x4f\xfe\x13\xe5\xdf\x27\xff\xbb\x7d\x2d\x57\xb3\x6b\x2d\x8a\x63\x9f\x8a\x54\xbe\xe0\x4c\xad\x61\x74\x68\x55\x9b\x5d\x80\xa2\x1f\x82\xe0\xa4\x0e\xeb\x4a\xdb\xdc\x52\x4d\x56\xa1\x45\xf0\x4d\x17\x95\xe8\x48\x72\x36\xa0\xb9\xbb\x5d\x75\x94\xa0\x81\x42\xc8\xc6\xa9\x8c\xe2\x1e\x4e\x4a\xbd\x38\x73\x52\x6c\xa0\x15\xc1\xbe\x25\x9c\x50\x8e\x34\xfd\x27\xc9\x66\xf6\x46\x0e\xe4\x03\xad\x85\x93\x7a\x0d\xe5\x29\xec\x13\x17\x51\x47\xe7\x4e\x51\x8a\x15\x05\x2c\x9e\xea\xd4\x02\xd8\x20\x05\xf7\xc3\x05\x24\x37\x15\xd3\xb6\x54\xff\x87\xf7\x99\x07\x78\xb5\x6b\x9e\x4a\x7e\xdb\x7d\x9a\x8d\x53\x0c\x80\xb6\xa2\x6d\xe7\x96\x86\xdc\x95\xf2\x8e\x79\xdf\x11\xd8\x09\x7b\xd8\x32\xf1\x86\x45\x80\x65\x58\xc5\x7a\x2c\x54\x56\xa9\x94\xb7\x01\xc4\x63\x5f\xb6\x3a\xac\xe7\x97\x73\x47\x5a\x5a\xa6\x8a\xec\xd0\x15\xe8\x53\xa2\xc2\x02\x58\xec\xb5\xd1\x9d\x87\x6b\x56\xed\xb4\x9d\x72\xfb\x5a\x60\x7a\x95\x14\xef\x62\xa5\x9a\xc6\xef\xfb\x14\x0a\x83\x67\x8d\x32\xc9\xfd\x35\x2b\xfe\xff\x07\xc0\xc1\xff\x00\x64\xdf\x38\x9f\x3e\xa4\x30\x56\xd9\x8e\xf2\x30\x99\x49\x0a\x98\xee\x90\xe7\xd4\x41\x7c\x14\x28\x77\x02\x52\x4f\x7d\x78\xbf\x9f\x4c\x6f\xb7\x3d\x2b\x2d\xbf\xf8\xf5\x08\xda\xdc\x68\x9b\x8e\x83\x4c\x5f\x16\x74\xa1\x43\x49\x04\xe0\x26\x70\xb1\xae\xb2\x8f\x87\xb3\xed\xd6\xe8\x42\xf4\xb0\xbd\x7b\x89\xe8\x92\x17\x76\xd6\x8b\xb6\xa4\xfe\x71\xe4\xc8\xdd\xda\x11\x27\x04\xdd\x87\x6e\xf0\xe1\xee\x92\xb0\x1f\x0a\xea\xc4\x12\xda\xc1\xb9\x4b\x0a\xea\x46\x30\x6c\xb0\x14\x69\x9b\x80\xec\x4e\xd7\xe5\x0e\x80\xa8\xbd\xdf\xec\x5b\x82\x5a\x5f\xc3\x42\x7e\x09\xcb\x5d\xd8\xb4\xf9\xd5\xdc\xff\x13\xf1\xe3\xaa\x04\x4e\xbc\x60\x68\xa4\x6f\x16\x97\xa3\x47\x09\xc3\xfe\xee\x73\x88\x1d\x74\x8f\x2d\x54\xef\x57\x38\x74\x00\x47\x1d\x04\xe6\x07\xe7\xbf\xde\xf3\x02\x4d\xbb\x5a\xd5\x0a\x6a\xd3\x63\x35\xd7\x2d\x55\x63\x82\x8e\xb7\x46\x47\xd4\xd3\x5d\x2a\xe8\x12\x0e\x98\x8a\x6a\x62\x5f\x52\xc4\x6e\x17\xa1\x5c\x2c\xba\x1f\x49\xc5\x19\x08\x94\xca\x2e\x83\xb6\x2b\xde\xf9\xe0\x3e\x4d\x69\x0d\x75\x79\xe0\xf4\xbe\x29\x71\x47\x92\x79\x68\x26\x1e\x05\x45\x9e\xed\x1f\x7d\x98\x45\xf8\x5f\x78\x8b\xcd\x77\xd1\x52\xf2\xd2\x78\xd8\xf6\x9d\x46\x7e\x3c\x88\x24\x00\xa3\xfe\x05\x83\x5e\x18\x29\x6f\x5c\xf0\xeb\x9a\x87\xfc\x45\x73\xa4\xd3\x7e\x64\xb8\x47\xc4\x76\x01\x4b\x7c\x8f\xc3\x99\x4b\xc7\x3d\x8b\xee\xa3\x53\x46\x6c\x8d\xef\x5d\x65\xa0\xb3\x44\x5f\x03\x4b\xe2\xeb\x70\x7a\x76\xba\x55\x0d\x95\x9b\x97\xa0\xa1\x8d\x37\x08\x7a\x37\x79\x44\x58\x07\x2c\x39\x1f\x7a\xe1\x74\xce\x2d\xdf\x34\xee\x71\xf4\x7e\x3e\x69\xcf\x4d\xca\x20\x2d\xd9\x7a\x6b\x97\x5f\x9d\xcf\xc1\x80\xdc\xaa\xac\x21\xc8\x17\x38\x85\xfb\xd7\xc7\x11\x49\x11\x97\xe4\xb7\xab\xcc\x91\x7a\x0f\x77\x88\x4d\x66\xca\xbf\x5d\x46\xdd\xe4\x0a\x86\x09\x9b\xbc\x03\x88\x2d\xbf\x40\xc6\x8e\x6e\xfc\x15\x3e\x4a\xb3\x70\xa2\x57\x60\xd4\xc0\x73\x0e\x51\xaa\x35\x66\x83\xc6\x17\x8c\x0a\x6f\x02\x17\x40\xec\x41\x13\x8a\xc8\xa9\x85\x39\x1c\xf3\xbd\x7d\xb9\x35\x49\x48\x9f\x77\xdf\xdf\xe6\x30\x22\x9b\xf1\x37\x34\xeb\x74\x8d\x63\xf0\x4e\x9f\x7c\xcc\xc1\x9b\xfe\xb6\x56\x6c\x8b\xf6\xd1\x36\x85\xc0\x7b\xa6\x54\x24\x91\x48\xbc\xdc\x46\x0e\x97\x47\xbc\x5f\x6c\xcb\x40\xc9\x53\x14\x0f\xaa\xa9\xa4\x04\x06\xa6\x63\x3e\xbc\x6f\x63\x12\x1e\x64\xf9\xfa\x42\x3b\x56\x42\x97\x5f\x65\xb0\x0a\x71\x88\x33\x8f\x60\x6d\x58\x48\xa2\x0e\x91\xd1\x08\x49\x7e\x74\xdd\xcf\xfb\xe0\x80\x07\xf8\x37\xe1\x6f\x64\xed\xf9\xa1\xfa\xac\xe2\x2f\x23\xa9\x19\xb3\x28\x2c\x61\x85\xe1\x7b\x5c\x3f\xab\xbd\xa1\x91\xbb\x26\xf9\x29\xdc\xbc\x3b\x25\xb2\x08\x82\x72\x15\x41\x8a\x91\xde\x92\x76\x92\x87\x6c\x63\x2b\xbd\x84\xc4\x22\xef\x0f\xa9\x09\xf7\x0b\x6b\xa1\xfe\x70\x3b\xc7\x21\x46\x79\xd2\x3c\x9e\xaa\xde\xaa\x5d\xfb\x01\x8e\x5f\xdc\x10\xe5\x6c\xd5\xcb\x48\xd6\x23\x80\x72\x90\x97\x60\x16\x2e\x06\x51\x77\xaf\x3b\x5d\x28\x6f\x89\x93\xba\x20\xfd\x77\x1a\xd6\x3b\x40\xdf\x15\x1f\xea\xd3\x9a\xf8\x68\x3b\x14\x83\xfe\xbb\xac\x14\xb1\x2e\x12\x22\xd5\xec\x22\xc3\x18\xb9\x72\xec\xee\x2e\x5d\x95\xc0\xbf\xbf\xfe\x88\x6a\x82\x50\x78\xd6\x89\x4c\xe3\xbe\x32\xc8\xd6\xfe\xa3\x64\x22\xdb\x68\xce\x70\xef\xb3\x96\xef\x5b\xc8\x48\x8a\x9d\xed\xba\xf5\x52\x5c\x53\xbc\x9b\x17\x50\x09\x81\xda\x45\xf0\xb3\x1c\x6a\xc1\x01\x60\xc3\x77\x41\xc0\xb5\xc7\xd2\xf7\xb7\x33\xa8\xe1\x27\xdc\xc9\xa4\xa3\xec\x4b\x28\xc8\x6d\x43\x12\x1c\x95\x97\xdd\x77\xa8\x9c\x22\x5e\xfd\x8e\x21\xf3\x89\x69\x6b\xf3\x92\xba\x34\x1b\xc5\xb2\x99\x4b\x83\x84\x7d\x86\x8c\x4b\x1e\xe5\xde\xf7\x1c\x48\x6c\xf5\x7d\xcb\x8a\x10\x2f\xbf\xf2\xa6\xd6\xda\xda\x3b\x16\x66\x59\x37\x11\x34\x20\x3a\x7b\xec\xec\xf4\x16\xef\xc8\x2b\x29\x8f\x0c\x70\x47\x54\xc5\x45\x1e\x42\x8d\x19\x2d\xe4\xea\xd1\xd0\xa2\xf0\xc4\xc3\x14\xa9\xed\x5e\x7c\x79\xb7\x1d\x6e\xb4\x57\x78\xbf\xc0\x83\x8a\xd2\x65\x64\x44\x64\xc9\x98\x63\x0f\x58\xbd\xb8\x85\xd4\xe4\xe1\xc5\xd6\x57\x54\x23\xfb\xd4\x99\xb4\xfa\x99\xd6\x92\xe9\xb3\xf6\x40\x4d\x44\x4d\x00\x65\xb2\x10\x3b\xdf\x14\xe3\x94\xd0\xc5\x90\xa8\xb7\x46\x4d\xa7\x57\x1b\x3e\xb5\x9c\xde\x21\xc1\xf1\x22\x62\x75\xe8\x4d\x42\x2f\x29\xf1\xa7\x8e\x4d\x48\xa4\x6f\x0a\xc4\xac\x15\xd9\x3a\xca\x3f\x6f\x62\x24\x40\x3d\xd5\x61\xce\x6f\x9f\xb2\xce\x6f\x72\x8e\x8e\x5b\x76\xd0\xf7\x4e\x55\xb5\xdf\x98\xb3\x5d\x32\x92\x8d\xf5\x93\x7c\x3d\xc5\x48\x0a\xf3\xa0\x39\x9c\xf5\xe7\x9f\xa0\x68\xce\x1a\x48\xcf\xf4\x4b\x9c\x1b\x13\xe5\x0f\xf2\x05\x7c\xea\xaf\x2a\xe1\xfe\x2f\xb7\xc9\xcd\x9f\xb8\x1a\xd3\x1d\x76\xca\xb8\x0f\x83\xeb\xb4\xd5\x3f\x51\x35\x9f\x91\x1d\x7a\xc5\x88\x65\x92\x3b\xfc\xf4\x6b\x68\xdc\x4d\x28\xcc\x1e\xb1\x83\xbe\x3f\xbe\x6b\xc2\x6b\x97\x01\x93\x72\x5f\x78\xda\xe6\x23\x5a\xc6\x33\x62\x6c\x9f\x34\xd3\x7e\x46\x50\x2b\xf8\x12\xf4\x6f\x4f\x32\x00\x87\xb7\xa3\x47\xe9\x6f\x2c\xff\xec\x59\x7c\x39\x0d\x8c\xb0\xdf\x9c\x8e\x58\xb0\x73\xbd\x23\x13\x79\x38\x9a\x75\xda\x60\x57\x78\xa0\x63\x47\xa0\xe0\x83\x0b\x09\x38\x24\xe4\x38\xd1\x36\x09\x07\xb5\xb5\x46\xe7\x94\x46\x29\xc5\x39\x3b\xf2\x40\x0d\x51\x1b\x7c\x77\x97\x2f\x5e\x95\x3f\x2f\xd2\xf3\x9a\xf8\xa5\xb6\x99\x42\xaf\xea\x1d\x98\xfc\xbf\x58\x59\xe8\xa3\xd0\x09\x4b\x18\xb7\x5d\x8a\xc5\x6c\x0b\x19\xcc\x28\x76\x41\x27\x84\xcb\x5c\xd4\xf6\xde\x6d\x1b\xae\xde\x57\x59\xa3\x3b\x48\x40\x97\xce\x7f\x69\x12\x98\x09\x70\xe0\xd8\x2c\xc3\x5c\xe9\xe2\x25\x1e\xac\xcd\x13\x6b\x94\x14\x9d\x6c\x68\x5f\x30\x1d\xc4\xe3\x10\x56\xda\xa9\xd3\xe9\xf4\xa5\x81\xcb\xa7\x49\x5e\x34\x49\xc3\x5b\xdd\xc8\xe3\x25\x9c\xa1\x7c\x33\xd6\xc5\x04\xd8\xad\x59\x8b\x45\xf2\x42\xd3\xc3\xb9\xe0\xce\xa3\x75\xdc\x91\x68\xe3\x98\x72\x03\xf1\x88\x35\xbd\x97\x4f\x1d\xcf\xfc\x7b\x1f\xca\xcc\x51\x84\xb2\x87\xaf\xba\xd3\x6f\x13\x61\x11\xac\x19\x25\x6b\x87\x79\x26\xa9\x16\x77\x17\x2d\x32\xa9\x52\x97\x2a\x33\x47\xed\xc4\x51\x4f\x57\x54\x93\x56\x06\x76\x31\x69\x84\xa8\x2f\x26\x18\xe9\x37\xcc\x48\x91\xad\x85\xc0\x62\xf9\xd6\x03\x93\x08\x4c\x86\xa3\x09\xff\x74\x04\xaa\x9f\x2d\xb4\xda\xea\xd3\x4d\x5b\x93\x9b\x51\x68\x1c\xa1\xa3\x20\x2d\x91\xea\x7e\xc8\x66\xfe\x28\xdf\x2f\x73\x8f\x65\xa9\xd4\x8b\x68\x81\x81\x69\x66\xe9\x9a\x78\x59\x1f\x56\x8e\x9f\x62\x95\x21\x9e\xe2\xe1\x7a\x5b\xee\xea\xbe\x3f\xef\xe9\xb5\x14\x8e\x2a\xec\xea\x7c\xb2\x82\xaa\x76\x7e\x90\x8c\x56\x67\xb2\x3b\x37\x4e\x0b\x36\x4e\x0f\x6e\x2a\x29\xd6\xfa\x95\xbf\x92\x27\x42\x91\x0d\xb1\xf6\xaf\x20\x75\x79\x56\xb2\xe2\xb8\xfb\xa7\xfe\x22\xf7\xa0\x68\xbd\xb1\x12\x20\xa5\xcb\xc6\xbb\x4d\xa7\x40\x9c\xb2\x01\xd4\x95\x88\x91\xd2\x69\x89\x9c\xf2\x07\x41\xbd\x4d\x7c\x89\xcf\x2a\x20\xef\xad\x5a\xd5\x5d\x93\x4f\xed\xc2\x1b\x3d\x67\x34\x04\x99\xed\x49\xe8\xa6\x99\x9d\x27\x30\xb7\xb7\x14\x06\x6e\x5a\x41\xe0\xeb\xbb\x68\x92\xca\x70\x8a\xa2\x7d\xa2\x6f\xe8\x74\xff\xa6\x9d\xdc\x48\x27\xf6\xd0\xcf\xb5\x19\x8f\x4e\xf9\x1d\x7e\xe5\xaa\x5d\xff\x68\x60\xd8\x79\x1c\xf1\x48\x12\xe4\x78\x13\x75\x19\xc1\x92\x63\xe1\x79\x64\x5e\xcb\x63\x8c\xd0\x9d\xa5\x16\x2b\x45\xbc\xd7\xb7\x52\x9c\xfd\x96\xe6\xa4\xa1\x8d\xb7\x41\x4e\x0d\x9f\xf3\x63\x23\x7f\x77\xd4\xeb\xee\x0a\x40\xbd\xba\x4f\xea\x63\x9e\x0e\x3c\x91\x19\x8f\xdb\x39\xc2\x02\xa3\x9c\x85\x1f\x35\xeb\xa8\xac\x79\x57\x76\xeb\x3e\xff\xcc\xa6\x11\x1d\x0c\xc5\x1a\x53\xd5\xa5\xd7\xda\xf5\x07\xec\xf2\xaa\x97\x87\xf2\x7f\xba\xf3\xb3\xf2\xfa\xb4\x15\x04\x3d\x03\xf7\xdf\x1c\x3c\xb6\x41\x6e\x70\x50\xb2\xd2\x91\x11\x3d\x11\x79\xe2\xb0\x88\x67\x81\x0a\xa3\x97\xd5\xf5\xfa\xfa\xf0\x57\xcb\x8a\x9d\x26\x6d\x5d\x1f\xfa\xd0\xbe\x6a\xca\x31\xaa\xc9\xb6\x1e\x3f\xac\xda\xa7\xfa\xbf\x5b\x7d\x50\xef\x3d\x86\xb7\xfe\xa0\x22\xc1\x4a\xce\xd7\xcb\xa4\x5e\xfc\x3e\x64\x04\x0a\x6a\xbe\xb2\xb9\xee\x7e\x8a\x3e\xff\x9e\xb8\x4d\x93\xc6\xd1\x45\x60\x5f\x57\x24\x5a\x56\x3a\xba\x55\x97\xb6\xa7\xe2\x85\xfe\x0a\x22\xf8\x7a\x12\x36\xc9\xab\x87\x76\xd0\x0f\xf4\xab\x93\x0a\xe0\x7b\xf1\xb3\xc0\x1d\x51\x05\x12\x96\xb0\x1b\x70\x8b\xc8\x08\x75\xe2\xc5\x62\xbb\xef\x2e\xeb\x54\xb0\x8c\x02\xa5\xb6\xad\x76\x0d\x1b\xc8\xb4\xd0\x1b\xf8\x75\xb4\xfb\x03\x99\x9d\x65\x09\x95\xb3\xd3\x56\x41\xb6\xa2\x6e\x51\x91\xb3\xef\x88\x77\x3b\x01\xa1\x71\xca\x0b\x6b\x2c\x16\xc2\xf0\x84\xb9\x64\xe3\xe8\x29\xca\x1a\x03\x3f\x93\x46\x83\xb6\x5f\x86\x97\xc8\xc5\xf9\xc1\xb9\x23\x4d\x92\x64\x5a\xec\xe0\xfe\x55\x75\xf8\x67\x1e\xa2\x48\xb1\xa9\x2a\x38\xde\x6e\xb3\xc6\x04\xb1\x5e\x91\x17\x11\x2d\xb3\x62\x30\x92\xb6\xc0\x25\x95\x1c\xaf\x1d\x07\x67\x3e\xf7\xd6\xd0\x24\xb6\x5c\xbc\x43\x8e\xcf\x07\x2c\x9f\x1c\x85\xd4\x38\x78\x5f\x48\xa3\x40\xb8\x94\x78\x6a\xf9\xe8\x0b\x07\x06\x7b\xd2\x17\x51\x73\x0c\xbb\x73\xdf\x47\xd1\x30\x11\x96\x94\xab\x0e\x34\x42\x0e\x46\x46\x51\x7a\x37\xdd\xc8\x5a\xe5\xee\x63\xe5\xb6\xcc\x61\x6d\x2d\xba\xa6\x15\xc9\x8a\x72\x76\x8a\x7c\x68\x32\xd7\x9c\x49\x20\xf1\x7c\xd2\x22\xd4\xa0\x0f\xc1\xc8\x9a\xd8\xbb\x81\xbe\x1b\x64\x3c\x1f\xe4\x6a\xa4\x3b\xfd\x4a\x62\xa1\x99\x49\x09\x10\x56\xe9\x8b\x91\x8f\x1d\xc2\xff\x04\xe0\x23\x56\xae\xb2\xa1\xc1\x36\x4c\x18\x80\xc2\x6b\x3b\xe3\xfd\xd1\xed\x6b\x38\x4a\xf1\x5d\xee\x0f\xac\x6c\x2f\x39\xff\x72\xc4\x1a\xfd\xa9\x00\xb7\x46\x2b\x48\x68\xd0\x04\x68\x38\xfb\x0f\x9f\xe4\x08\x7a\xa5\xed\xb2\xb1\x08\xe6\x70\x91\x9c\x75\x92\x22\x73\x22\x20\x35\x35\x8c\x6d\x72\x6a\x67\x58\x10\xed\x6d\x42\x43\xed\x3b\xf6\x4b\x99\xc9\xe6\x41\xbc\x79\x44\xab\x2c\x9c\x82\x20\xa2\x4d\xf4\x93\x1b\xb5\x9b\xb8\xc3\x50\x2a\xc8\x84\xd5\xea\x5d\x09\xab\x0b\x0d\xf0\x1e\x3e\xfb\x9d\x05\x83\x0e\xa2\x4b\xbb\xb1\x33\x05\x03\x02\x9f\x6d\x77\x25\x78\x8a\x19\x27\x47\xa7\x43\x94\xc3\x43\x58\xb9\xd9\x26\xb7\x38\xa1\xd5\xea\xd0\xab\x0d\xe4\x6c\x8f\xbb\x28\x36\x42\x52\x32\xa7\xae\xf5\xe8\x38\x7e\x29\xa9\xb9\xcf\x1e\xa2\xe6\x1f\x9d\xa8\xb8\x5d\x33\xe9\xe8\x14\xe2\xde\x29\x4a\xc4\x0a\x46\x2f\x08\xba\xa2\x69\x2c\x4c\x07\x35\x0b\xb4\xf2\x51\x6c\xb5\x4b\x69\xd9\xe9\xdc\x54\xea\x7a\x66\xbf\xf3\xd5\xfe\x8b\xd0\x16\x1e\x6b\x4e\xbb\x6a\xfe\xfa\xb0\xfe\x92\x2f\x98\xff\xa3\x5b\xf8\x30\x87\x08\xfb\xde\xa7\x84\x0d\x9f\xe0\xc5\xfa\xd7\x17\xeb\xb3\x02\x25\x82\xad\x17\xa9\x0b\xae\x5c\x94\xd9\x0a\xfd\x61\xde\xad\xdf\x4f\xbf\xcd\x6c\xce\xe1\xdb\xa7\xe6\x09\xec\x36\x1f\xd0\x36\x61\xc6\x55\xc3\x41\x29\x3c\xa8\xac\xbc\xa2\x23\x34\x3a\x26\x55\x88\xb8\x3a\xbc\x32\xfb\xb2\xec\xc0\xee\xa6\xcd\x4d\xad\xc3\x59\xb9\x2f\x95\x55\x97\xb5\xed\x50\xda\x98\xd2\x2d\x03\xdb\x97\x7c\x59\x88\xc6\xdb\x63\x7a\x4a\x44\xb4\x84\x89\xe7\x99\x1c\xac\x3c\x3e\x2d\x01\x1e\xd9\xa4\x1c\xd9\xa6\x83\xda\xc6\x66\xae\x34\xb5\x38\x4b\xae\x7b\x2d\x45\xca\x6d\x27\xb8\x6d\x6b\xfa\x96\x42\xa5\x24\x6c\x9e\x09\x5b\x12\x95\xda\x8f\x3a\x7b\xc2\x05\xec\x5b\x48\x6b\x13\x92\x6b\xbd\x30\x1c\x99\x1f\x4e\xd1\x9d\x44\x73\xf4\x70\xd0\x4d\xcc\xb6\x83\x0e\x4c\x5b\x78\x9c\xd9\xe5\x16\xf3\x9a\xa3\xcc\xf8\x8b\x90\x25\x41\x53\x96\x1b\xfe\x6b\xab\xf2\xf7\xac\xe2\x24\x08\xc9\xf9\xca\x83\x2c\x17\xee\x79\x07\xda\x13\xd4\xd6\xfe\xd1\xc6\xc0\xd1\xfe\xa5\x84\x61\xe4\xd1\x28\xb5\xbe\x77\x97\x83\x66\x55\x1d\x49\xcc\xe9\x0c\x45\x64\x50\x58\x24\xfe\x5b\x93\xdf\xbb\xcb\x4d\xcd\xa1\x73\x52\xfc\x51\xe1\xa4\x91\x55\x53\xfa\xf0\x7a\x12\xc9\x05\x94\x79\xcd\x61\xc6\xc0\x47\x13\xc5\x45\xe7\xac\x20\x28\x28\x59\xf9\x0f\xbb\xae\x97\x59\xdd\x07\xa2\x78\x0f\x85\x37\xdb\xb3\x0e\xd9\x91\xb2\x10\xac\xce\xa4\xbb\xd3\x5f\x96\x34\xc3\x36\x7c\xaf\xc7\x81\x41\xcb\x3f\xc7\x1a\xf3\x9b\xb6\x12\x50\x4c\xb4\xcc\xf2\x77\x6c\x94\xd2\xcd\x4d\x6d\x1c\x0c\xec\x74\x62\xba\xfa\x24\xe0\xbc\x11\xd3\x26\x17\x34\xb8\x03\xd2\xc3\xc7\x3b\x31\xa4\xbe\xbe\xcd\x2c\x78\x2b\xe1\xd3\x46\x1e\x0a\x06\x3e\x2d\x01\xb8\xf9\x48\x21\x0c\x78\x90\xf0\xc9\x5a\x7f\x7f\xbc\x07\x0e\x76\x38\xbc\x16\xcb\x00\x1f\x24\xd5\xae\x3c\x4c\x80\xbb\xca\x95\x82\xb3\x0d\xc0\x07\xcd\xbd\xfb\x14\x7e\x0d\x40\x8f\x56\xf9\xba\x87\x9f\x9f\x27\xf1\x84\xbf\x42\x8b\x54\xc9\xa6\x60\x54\xc4\x37\xe6\x59\x17\xba\x16\x7a\x54\xa6\xf8\xc6\x4c\xcd\x54\x63\xfb\xcc\xe2\x7a\x3b\x93\x26\x72\xad\x7e\xf2\x8a\xfd\x0e\x28\xe1\xdf\x4c\xec\x96\x7e\x36\x38\x01\x21\x50\x84\x45\xe8\x87\x0b\x2e\xbc\x3e\xcd\xab\x26\xe3\x51\xee\x92\x5d\xd2\x1f\x4a\x36\x91\x55\xb1\xd3\x03\x6f\xc9\xcd\x79\x41\xf7\x28\x02\x79\x0d\xf6\x2d\x23\xb1\x87\xd8\x50\x4c\x1b\x6b\x63\x45\xbf\xd9\xc0\xa0\xe0\x60\x9d\x7b\xb9\x6d\x88\xec\x72\xec\x95\x53\xed\x79\xd7\xb0\xd8\x79\x0b\x48\x81\x13\x2b\x2b\xd4\x23\x02\x7d\x5c\xa9\x3e\x29\x09\xa1\xab\x92\xfa\x43\x97\xde\x2c\xeb\x36\x1d\x16\x3f\x9c\xe1\xd0\x79\x71\xc7\x16\xd4\x69\xde\x8f\x97\x4b\xa4\x77\x30\xaf\x5f\x42\x5e\x93\x17\x59\xbe\xc8\xe4\x08\x03\xca\xed\x6f\x4e\x9b\x80\xe5\x49\x49\xf4\xfd\x79\x81\xbe\x5b\x34\x57\xd9\xe6\x06\x15\x50\x9f\x8e\x3f\xe8\x45\x0b\xf5\x17\x0c\xfa\xb7\x81\x42\xd3\xcd\xde\xe8\x2c\x77\x8d\xac\x27\xe8\x34\xc6\xc3\x8e\x1a\xa5\x2a\x77\x51\x77\xda\x36\x26\x80\xcf\x8e\x39\x44\x97\xde\xe1\xab\x75\x13\xe7\xb5\x5d\x6e\x0e\xbf\x7f\xed\x83\xbe\xe3\xff\x93\x22\x4e\x46\xf3\xfe\xcb\x73\xd9\x73\x56\x2d\x5c\x9d\xca\x02\x31\x7b\x04\xdb\x5b\x6f\x1a\xcc\xe6\xb5\x71\xa5\xd1\x54\x2e\xad\x1a\xb7\x9d\x79\xa7\x0f\x65\xf4\xfe\x2d\x02\xf3\x44\xc2\x7f\x64\x5b\x02\x7a\x3a\xa3\xc6\x95\xf9\x2c\x38\x3f\xfd\x14\x82\xd4\xf0\xfc\x62\xca\x11\x4e\x96\xc6\x6d\xdc\x74\x44\x0c\x31\x10\x66\x4e\x74\x0b\xdb\x9d\x78\x0c\xd8\x2d\xeb\x08\x32\xd8\xce\x3c\x2f\xee\xcd\x8b\x97\xbd\x2a\x9c\x63\x5f\x58\x87\xef\x61\xc6\x4f\x0f\x75\x96\xa3\x98\x84\x15\xd9\xcd\x92\x2b\x0f\xcd\x03\x43\x4e\xa1\x9b\xe7\x75\xbb\xa7\xe1\x5e\x58\x1e\xd7\x0f\xcb\xe3\x22\x09\x14\x8a\xdc\x4a\xc0\xe0\x3e\x1c\x1c\x87\xe9\xd7\xa5\x47\xd6\xb4\x88\x32\xfb\x23\xe6\xd0\xa2\xd2\x71\x3e\x04\x47\xfa\x28\xcd\x52\x68\xfb\xf2\x54\xd8\x46\xf2\x8d\x30\x06\x53\x41\x3c\x69\x44\x36\x0c\x52\xb9\x8b\xc7\xb2\xc4\x4d\x12\x84\x23\x24\x1a\xf8\x03\x3d\x0d\xdc\xa9\x8e\x71\x67\xf6\x34\x7c\x7b\x3f\x48\x9b\x98\x17\x3a\xc3\xfe\xdd\xf2\xba\x76\x37\x60\xff\x59\x65\x5d\xa2\xe2\x55\xbe\x59\xa1\x8d\x03\x8c\x00\xa5\x30\xad\xef\xc6\x3e\x73\x62\xe2\x1a\xcb\x41\x59\xd7\xd5\x99\x59\xfa\x8a\x30\xb8\x2d\x61\xfa\xce\xdf\x8d\xfd\x4c\xfb\x34\x0a\xd7\x26\x7a\x43\xda\x1f\xc1\x06\x48\x55\x8b\x98\x46\x11\x5b\x83\x17\x8f\xcd\x0d\xcc\x05\xc3\xef\x71\x54\xdc\x9a\x1d\xb8\x57\x08\x6b\x9f\x32\xff\xb6\x47\x6a\xe0\x3c\xba\x55\x1b\xf7\x73\x09\x83\x75\xc4\xbc\xc3\x49\x84\x5d\x3c\x65\x72\xc3\x11\x19\x4b\x70\x77\x1f\x27\x7f\xed\x6c\x2f\xa5\x57\x75\x96\x3e\x1e\x11\x83\xb9\x65\x0c\x9e\xfb\x11\x75\xb1\xf6\xd7\x26\x29\xe8\x6f\x16\x66\xbd\xf3\xa7\x65\x26\x78\xb7\x68\xb1\x1e\xe8\xbe\xef\xaf\x25\x1c\x24\xd5\xf2\xf5\x53\xb8\x34\x23\x9d\x21\xfe\x4d\x34\x20\x68\xbb\x99\xb5\xb6\x68\xec\xd5\xb9\x92\xfb\x0c\x33\xc1\x74\xb7\xf3\x0d\x80\x2c\x39\x38\x0f\xa9\x3e\x1a\x17\xa9\xf9\xc5\xd7\x2e\x0d\x52\x42\x77\xd5\x09\x6e\x6e\x10\xbf\xa8\x32\xe8\xf2\x8f\x22\x69\x37\x8c\x94\x53\x7e\xfe\xc4\xac\x5e\x7b\x2c\xcc\xc0\xe9\x28\x92\x96\x93\xec\xc7\xce\x07\x0c\xe9\xeb\x93\xc9\xf4\xa6\x9a\xff\xbe\x5c\x17\xc9\x62\xfb\xa2\x7d\xfc\x82\x0e\xc6\x93\x21\x3a\xfa\xeb\x7e\xa3\xb9\xf9\x7a\xcc\x04\x82\x78\x67\xf1\x8f\x50\x1c\x9f\x0f\x8a\x68\x05\xe3\xbc\xa1\x5c\x66\xa5\x8d\x23\xd0\x6b\xef\xa9\x5c\x9a\xb0\xbe\x6d\xff\x69\x4e\x48\xce\x0b\x7b\x7b\x95\xf4\xc6\xda\x21\x0a\x9c\x6a\x51\xa9\x6f\x29\x5a\x76\x3b\x39\x31\x8e\xf5\xdd\x5a\xec\x26\xdf\xb5\xd7\x24\x33\x91\x4d\x6c\x0d\xf0\x77\x07\x62\x0f\x45\x20\x84\x9d\x8d\x3e\xee\xb4\xbf\x6a\x97\x3b\xce\x15\x94\x9e\x4b\x3a\x7d\xf2\xa0\xc8\x82\x9a\x53\xcf\xcd\xdb\x4a\xeb\xc0\x6b\x8f\x3b\x48\xb9\x0e\x5c\xc8\x2f\xe0\xa7\x9e\xbb\x88\x6b\x3a\x04\xd1\xb8\x9b\x91\xc7\x7f\xa2\x04\x88\xec\x25\xdc\xd4\xda\x24\xce\x60\x60\xc6\x1c\x18\x91\xa4\x0f\xf7\x4f\xe4\xbd\x00\x2f\xdd\x25\x29\xa5\x54\x00\xcf\x4e\xc9\x8d\x3d\x48\x11\x57\xe2\xf2\xd9\x23\x06\x0c\x45\x77\x54\xd8\x7e\xe3\xd7\xd3\x8d\xa8\x7c\xef\xfc\x84\xae\xe4\xf8\xc7\xc3\x7c\xab\xdd\xc2\x9d\x18\x55\x5d\x41\x21\x8e\x75\xe6\x91\xb5\x09\x95\xdd\x12\x48\x94\x4c\x7e\x5b\x6f\xb2\x51\xd7\x2a\xdb\x89\x55\x5a\x03\x47\x16\x7c\x97\x0d\x9f\x7b\x58\x0c\xa3\x16\xe1\xd6\x3b\xb7\xf9\x5d\x8f\xad\x4f\x1a\x62\xe8\x2b\x58\x99\xd3\x4c\x89\xcb\xad\xc4\xce\x3c\xde\x89\x94\xa8\xe5\x15\xa3\xbc\x24\x35\xdd\xbd\xaa\x79\x5e\x6a\x94\x6f\xb6\xb3\xb0\x5c\x07\x44\xc4\x7d\x3a\xff\x6c\x1e\x3d\xf3\xe9\xe1\xf5\xb9\x86\x76\xc9\x31\xac\x5f\xbc\xde\x11\x0e\xad\x74\xab\x9b\x89\x68\x58\x0b\x84\x77\x62\xde\x34\x6b\x9e\x65\xf4\xc6\xfe\x6d\x4e\x54\x64\xcd\x9a\xb8\xff\xdd\x27\x8b\xb2\x12\xdc\xa8\xfb\x57\x14\x4e\xf7\x28\xfe\x82\x75\xf7\x84\x2f\x04\x2d\xd9\xfd\x48\xc2\x10\x48\xfa\xe2\x81\xfe\x9c\x67\xed\x96\x6f\x76\xef\x1e\x13\xce\xc5\x12\x01\x34\xb6\x8b\x87\x88\x79\xed\x88\x0d\xdf\x8d\x13\x3a\x88\xc5\xe0\x41\xe2\x27\x97\x3d\x5e\x50\x5f\x2f\x59\x66\xd2\xe3\xcf\xdb\x3c\xcb\xc3\xdc\xf6\x1d\xe6\x0b\x3e\x83\xf5\xf2\xd4\xfc\xf1\x99\x1a\x08\x7c\xb0\x1f\x00\x84\x4f\x3d\xf2\x5b\xac\x05\x7b\xdd\x29\xaf\x39\x7b\x70\x65\xdc\xf0\x69\x3b\xd7\xe6\xa9\xe2\x01\xcf\xa4\x32\x2c\x0e\x4e\xba\x2a\xd5\xdb\xcb\x4c\x15\xed\xf0\x39\x55\x79\x23\x40\xd1\x4f\x89\xe2\xf8\x90\x0f\xec\x8a\xc4\x3a\xf9\x3a\xc2\x0c\x2a\xa4\x27\x43\xde\x79\x70\x60\xa3\x10\xcd\x11\xb2\x9d\xd3\xce\x23\x1e\x15\x50\xf5\x3f\xa8\x5c\x86\x45\xb2\xab\x98\x51\x0d\x8b\x6a\x0b\x37\x5a\xd9\xa6\x1f\xf4\xe5\xec\xeb\xe1\xcd\xa3\x5d\xfe\x23\x5f\x30\x17\x51\xe8\x88\xc0\x08\xca\xcb\xdd\xfe\x1f\x7c\xa5\xc6\xa9\x31\x40\x71\x2d\x27\x0d\xe0\x6b\xe2\x90\xc2\x66\x9a\xf6\x5b\xee\xc8\x1e\x96\xd0\x35\x0d\xc1\x99\x10\x87\xb8\x83\xbb\x0d\xb7\xff\x9f\x4b\x0b\x26\x16\x64\x98\x1e\xce\xe6\x73\x22\x80\x26\xef\x88\xc6\x92\x27\x9f\x47\x2e\x73\x5b\x5e\xbb\x12\xd8\x88\xf6\x56\xb9\x1d\xbe\x70\xd6\x39\xac\xf8\xca\xdc\x0d\x5f\x49\x2d\x33\x2c\x9c\x96\x0f\x3d\x5c\x50\x20\x1d\x83\x28\x59\xb6\x0f\x84\x3e\xd3\x0e\x10\xf7\xaa\xb8\x9a\x6d\x08\x1c\x97\x1c\x38\xb8\x92\xf6\x94\x0b\x9e\x53\x72\x8f\x7b\xa7\xcf\x97\x20\x09\x4e\xc3\x7f\x4c\xd8\x45\xa9\xb3\x9f\xbb\xc8\xf3\xb2\x8d\xc8\xae\x30\xca\x3e\x77\x25\x20\xec\x25\xfc\x7a\x7c\xc9\xc2\xee\x5c\x38\xa4\x3a\x71\x6f\x2b\x2a\x94\xb2\x39\x0a\x04\xab\x62\xa0\x4e\xbd\xc2\x56\x78\xe5\x3e\x11\x87\xd1\xdd\xe1\xf2\x9f\x66\x8b\x1b\x7a\x41\x18\xeb\xf9\x9f\x99\xe8\x61\x73\xc2\x9f\xdb\x1f\x97\xa0\x65\x02\x81\x41\xd1\x4d\x03\xdc\x7a\x16\x61\x2b\x9b\x0c\x1c\xac\x20\xd4\x8a\xf4\xfa\xcc\x54\x56\x70\x2b\x38\x02\x52\x40\x8a\x7b\xee\xfb\x0f\x94\xfa\x68\xd7\xc9\xb3\x0b\x6f\xb7\x72\x87\xc0\xfd\x1e\x0a\x78\x98\xe8\xca\x43\xb7\x70\x4a\xb4\x23\xf7\xe1\xe7\x8a\xfd\x8e\x7a\xfb\x2c\x2a\xb8\x7b\x46\xaf\xd4\x8b\x33\x54\x5c\xdd\x5c\xf8\x9c\x90\x0e\x22\x95\xcc\xa6\xda\xe3\x4a\x91\x69\xa4\x1f\x20\x3e\x0b\xd8\x4a\x16\x8e\xb0\x79\xd4\x2d\x95\x49\x22\xf5\x6d\xcd\x3c\x17\x94\x49\x99\x41\xd8\xe5\x27\x86\x47\xef\x2a\x05\x9e\x12\xee\x20\x7a\xd2\x3f\xe2\xa3\x8d\xff\x16\xce\x7c\x89\x74\x4c\x2f\x5e\xad\xd6\xaa\xb9\x33\x4c\xae\xe4\x71\xb5\x30\x8a\x4c\x34\x89\x05\x87\x93\x76\xb3\xa5\xe6\xb7\x4a\xf5\x57\x73\x89\x29\x17\xd9\x66\xcb\x8f\xee\xb3\xe4\xf0\x9e\xb1\xed\x8f\xd8\x0e\xb2\x57\x9c\xf0\x91\x73\xb8\xcb\x30\xfd\x64\x09\x07\xfe\x25\xc8\x8f\x50\x61\x4a\x50\x99\xc2\x8e\x6d\xde\x22\x46\x10\x1e\xc7\x7c\xc4\xef\x9b\xd6\xe2\xcd\x0a\x1c\xd1\xc2\x13\x8b\x25\xd7\xdf\x1d\xf4\x1f\x0f\xfe\x26\x94\xa3\x0b\x69\xaa\x7b\xd8\x57\xd4\xa5\x19\x2d\x4f\xb5\xf9\xfe\x16\x19\xe8\xe7\x12\x74\xb8\x2c\x1f\x9e\x29\x32\xf2\xec\xec\x28\xfc\xc4\x5f\x26\x29\x0e\xde\xa8\xfe\x1e\x8e\x77\xcc\xfe\x51\xe7\x2b\xf9\x09\xd2\x62\x9a\x69\xd5\xa6\x6f\xca\x34\xf8\x83\xf7\x1f\xd5\x98\xb6\x0d\x31\x3b\xce\x7e\xd4\x12\x33\x44\xd6\xfd\x61\x51\xea\x1a\x6d\xdf\xe2\x95\x0e\x99\x45\xa8\x76\x99\x86\x1a\x83\x3c\x68\x1b\xbf\xb3\x1c\x2b\x8e\x30\xf4\x8b\x4c\x7f\xdb\xfe\x6d\xff\x29\xd2\x5e\x0a\x8d\x81\x7b\x45\x8c\x04\xdd\xf6\xcc\x57\x61\x2d\x86\xb4\xcf\x8b\x5f\xaf\xfc\xbf\xfe\x9b\x7b\xed\xf7\xa4\xb7\xd9\xd5\xb7\xd3\x8b\xb8\x8e\x83\xfc\x6c\x96\x70\x93\xec\xcb\x1e\x6c\x1f\x44\x18\x5d\x9c\xce\x41\xe4\xed\x7d\x43\xb6\x1a\x47\x7b\x67\x8f\xfb\xfb\x92\xa9\xb1\x66\x8b\x89\xe0\x06\xcc\x6d\x8a\x02\x37\x26\x9e\x02\x56\xde\x0b\x34\x41\x5b\x45\xb0\xfd\x73\x0a\x62\x79\x91\xd9\x51\xe5\xfb\x27\x3a\xf0\x42\x5b\x63\x20\x8b\xfe\x43\xe1\x7c\xad\x53\x81\x74\xb9\xa5\xf5\x19\x2e\x97\xe2\x27\xdd\x62\x8a\x47\x06\x3a\x19\xf6\x0b\x5f\x11\x90\x11\xb9\xc7\x76\x24\xfd\x13\x97\x23\x56\xef\x03\x3d\x40\xe6\x41\xf9\xf9\x15\xff\x92\x4e\xc3\x04\x43\x28\xcc\xac\x29\xe2\x29\x1b\x96\x77\xdc\xdc\xef\x38\x2b\x5f\xb2\x7f\xc6\x71\xc2\xaf\x81\xe1\x17\x21\xfa\x70\x02\xc1\x38\x4a\x1e\x5f\x6f\x69\xc8\xc3\x53\xf9\x52\x33\x7a\xa5\x7a\xac\xdc\xc1\xc0\xaa\xc8\xed\xd3\x01\xc6\x58\x09\xc7\x62\xfd\xc7\x9f\xb8\x5a\x1e\x81\xd5\xc5\xcd\xd5\x8b\x84\x8a\x22\x5d\xbc\xf7\x57\x52\x4c\x71\x02\x72\xea\x8e\x77\x22\xeb\x2f\x9d\x57\x09\x45\x67\x80\x3a\x69\xe7\xf5\x00\xa9\xb3\x57\xf4\x94\xce\x40\x48\xaf\x90\xb9\xef\xf7\x96\xe7\x85\x8c\xbd\xb2\xc4\x0f\x49\x1f\xfb\xec\xde\xc1\xf2\x3b\x92\xed\xf7\x16\x85\xb4\xdb\x6e\xab\xbb\x7e\x07\xa2\xe1\xb7\xea\xae\xad\x7e\xf1\x89\xbe\xf6\x7f\xd9\x43\xec\x21\x76\xc3\x99\x18\x27\x13\xa8\x45\xb9\xe7\xa8\x6d\x4f\xff\x71\xc7\x42\xa4\x05\xfe\x10\xc9\xad\x9c\x6e\x4c\x36\xdc\x5d\x7e\x81\xf0\x32\x9b\x58\x49\xd1\x5c\x5b\x9c\xcd\xca\x53\x78\x45\x07\x23\xaf\xa0\xa5\x44\x78\xc2\x30\x84\x59\xd0\x1a\xbd\x12\x54\x0f\x39\x47\x46\xd0\x0f\x9c\x4f\xc4\x59\xfa\x92\xff\xc9\x8a\x47\x32\x22\x8d\x32\x28\xd1\xb5\xea\x33\xf6\xdf\x77\x18\x7a\x59\xa9\xa7\x28\xd7\x14\xdd\xcc\x1c\x1d\xe4\xbc\x51\xda\xe5\x71\xd8\xe4\xcd\xa5\x83\x0f\x0b\x4b\x20\x38\x7a\xd1\x9c\xb9\x46\x9e\xab\xc6\x77\x7f\x2d\x15\xe1\x2f\x91\x74\x1a\x16\x4c\x53\x33\x6a\x70\xdd\xfa\x36\x9c\x6d\x5a\x58\x85\xac\x77\x0c\x12\xca\x0a\xcd\x99\xe2\x7a\x99\xd2\x18\x61\xf4\xc3\xe0\x57\x1c\xdc\x86\x4a\xb3\x1b\xb2\xe3\x4e\x6c\x6d\xab\xb0\x4e\x0a\x6f\x3c\x03\x8c\x95\xb9\x1d\x48\x2f\x72\x34\xbe\x2d\xbb\xe1\xe6\x2c\x31\x85\xb5\x36\x26\x60\x7e\x86\x3c\xeb\x16\xf0\x06\x89\x1b\xe2\xd4\xd1\xbe\xff\x09\x27\x5b\xa2\x5a\xcf\xd4\x4a\x77\xbb\x91\x5d\x52\x8a\xb3\xd0\xeb\xf4\xc2\x9d\x68\xa8\x41\x91\x1e\xc0\xc9\xa4\x9c\xe2\x50\xd6\xd4\x10\xcf\xce\x36\x5b\xff\x38\x69\xe8\x30\x28\xb5\xdb\x97\xa2\x92\xd8\xc2\xa9\xc6\x47\xe8\x6b\x7b\x69\xdd\xed\x56\x09\x6e\x05\x36\xf6\xc0\x68\x22\xbe\xa8\xca\x25\xc3\xe5\xaf\x0c\x5b\xa9\x9e\x14\xf4\xf8\x7f\x4c\x9d\x0d\x41\x7d\x8e\x3b\x96\xd6\x42\xa9\x05\x41\x04\xd4\x83\x27\xb9\x68\x33\x1e\x05\x83\x3f\x9f\xb7\xf4\x17\x72\x1e\xb3\xf2\xa5\x89\x2c\x30\x3a\x09\x82\x72\xcb\x2b\xe9\x00\x2c\xf1\x73\x5b\xda\xc5\x7b\xec\xea\xda\x45\x36\x59\x79\x89\x7d\xe7\x86\xaf\x10\x9e\x2d\x94\x9b\x8d\xa1\x2a\x1b\x02\x48\x6f\xa6\x1f\x2d\xcb\x0f\x80\x3b\xcf\x82\x3c\x54\x01\x42\x42\xf1\x61\xb9\x1e\xfe\xcb\xe9\xc3\xa8\x4c\xd4\xb8\x03\xcf\xa6\x64\xa5\x15\x21\x4a\x3b\xe2\x07\xb1\xf3\x00\x6d\xf2\x0b\xe7\xf6\xad\x32\x33\xc2\x17\x7c\x53\xc8\xfe\xed\x92\x97\x70\x63\x23\xb0\xf3\x86\x2c\x81\x1c\x3d\xeb\xa5\x7f\xee\x45\xea\xb4\xde\x4d\x2f\x9b\x08\x2f\xd8\xa3\xca\xad\xd7\x2f\xb8\xdf\x6e\x5e\x16\xcd\xb7\x3c\x8a\x2e\x86\x8d\x5d\xc0\xb0\x1f\x0e\xb3\x6f\x3d\xfd\x09\xae\xa3\xfe\xba\xe4\xcb\xd5\x59\x6e\x30\x92\x6e\x29\x4d\x4e\x67\x58\xfd\x7c\x8f\x44\x96\xc1\x8e\x2f\x99\x5a\x85\x8e\xb7\x31\xf1\x64\x6a\x8f\xb7\xbf\xf9\x23\xe5\x67\x16\xd7\xc4\xae\xb8\xac\xd5\x16\xac\x93\x88\xc0\xb9\x5a\x3e\x06\x22\x47\xa3\xc3\xb8\x0f\xcd\x93\xce\xe6\x49\x74\xee\x39\x72\x9f\x4e\xb4\x99\x7e\xa2\xcc\xb5\x72\xde\xab\x84\xab\x93\xa1\x66\xe7\x74\x47\xf2\x94\x5b\x9d\xaa\x13\xca\x92\x88\x9f\xb6\x7d\x47\xe4\x8e\x22\xd5\xbc\x2c\xf5\xa6\x05\xa1\xe4\xbf\x76\x64\x6b\xae\x26\x25\xd2\x75\x30\x3c\x67\x4f\x82\xd3\xe8\x2b\x45\xef\x19\xb4\xf0\x21\x3f\x6f\x1e\x56\x8e\x6c\xf8\xf9\x74\xdb\x51\xed\xbd\x86\x55\x04\x4a\x52\xe5\x00\x79\x15\x45\xdc\x39\x61\xf8\xb9\xdb\x50\x18\x06\xb0\x94\x16\x03\x40\x9b\xa6\x23\xc5\x67\x80\x7c\xfd\xac\x28\x3d\xb5\x98\xd9\x71\x4d\x38\xb5\xdf\x8a\xa1\xdb\x6b\x90\xe3\xf7\xba\xef\x82\xaf\x24\x96\x29\xca\xf5\xb1\x86\x3e\x18\xe4\x11\xe7\xc3\x75\xd2\x88\xe0\x92\xb7\x9d\xec\xa2\x40\xb2\xf7\x5f\x22\x79\xd9\x0e\x16\xea\x03\x27\xdb\x8a\xb0\xa2\x87\x37\x28\x92\xb3\x7c\x82\xf2\xad\x00\xeb\xb5\xb6\xc6\x42\x56\xf9\x6b\x7d\x3e\x93\x7f\x49\xd1\x49\xb9\x96\xad\xb9\x29\x84\x5a\x70\x45\x21\x5a\x35\x55\x08\x43\x84\xbe\xff\xed\xbd\x6b\xb3\xd9\x5f\x09\xe4\x84\xb8\x2f\xa4\x3c\xa9\xf7\x53\xdf\x13\x5a\xd8\x8a\x60\x44\xd3\x70\x63\x97\x13\xf2\x0a\x58\xf2\x14\x5c\x46\xed\xb0\xb6\xbd\xd9\x6d\xae\x99\xf2\xae\xb6\x63\xe2\x17\x93\x99\x6c\x9d\x7d\x72\x33\xc7\xf9\x8e\xe4\x61\xb0\xc8\x39\x88\xfe\xbb\x9d\x7f\xf4\x27\xe8\x0e\xe1\xe6\xde\xad\xdb\xd9\x57\x4f\x1e\x82\xd4\x30\x2b\x77\x7c\xaa\x1c\x1b\xd4\x21\x8e\x31\x64\x90\x3d\x7c\x80\x3c\xb7\xc9\x71\xe4\x33\xda\x55\xf4\x55\x6c\x81\x08\x9e\x76\x20\xc2\xa3\x40\x33\x88\x77\x90\xc6\xc5\x95\x04\xed\x5c\x8c\x04\x70\x1b\x23\x0b\xd3\x2e\x1d\x8a\xcd\xec\x95\xf3\x20\x2e\x6f\x49\xec\x4f\xd5\x28\x18\x0e\x0a\xfe\xa9\x06\x41\x83\x1d\xeb\x9c\xc9\x54\x02\x1c\x79\x2e\xa0\xce\xfb\x26\xff\xc4\xc8\x77\xd1\x42\x04\xe1\x67\x59\x44\xcb\x78\x5a\x89\x74\x90\xd5\x83\x1c\x4d\x07\xa1\x90\x99\xa5\x61\xb0\xda\x98\x29\x46\xc1\xf9\x59\x82\x40\xae\x4e\x70\xa8\x30\xe5\x89\xc5\xa8\xb9\x05\xd4\x10\xec\x60\x36\xe1\x57\xff\x02\x52\xc1\xb3\x1f\xda\x46\x62\xf7\x2a\x6c\x69\xc9\xf7\xc9\x9e\x4d\x4d\x7f\x2a\x99\xa1\xf6\xf7\x25\x75\x65\x64\x4e\x3f\xfc\x0c\xe5\x80\xac\xe7\x3d\xec\xcd\x88\x63\xcb\x8d\x67\x5e\xdf\x24\x0c\xd5\x96\x0b\x88\xbb\x2f\x3c\xcf\x77\xf2\x1f\x21\x0f\x12\xed\xfc\xfe\x99\xd2\x28\x86\x7a\xed\xc2\x9c\x66\x6d\xe7\x50\x27\xc0\x06\x98\x96\x42\xaa\x49\x34\xbf\xb1\x6d\xd0\xe6\xa1\x71\xbc\x9b\x3b\x34\x30\xe9\xb1\xf2\x94\xf4\x1c\x5c\xc9\x97\xbb\x22\x81\xf7\x3f\xf2\xdf\x0e\x26\xa6\x14\x5c\x17\xda\x41\x58\xdf\xa9\xce\xe5\x68\x0d\x4b\x17\x22\x98\x2e\x49\x2b\x6d\xc7\xa5\x57\x2b\x00\x12\x44\x80\xf1\x28\x08\x3f\x0c\x97\xfc\x9f\xb3\xda\x1f\x3a\x0e\x95\x82\x7d\x87\x4a\x42\xb6\x07\xef\xcf\x36\x13\xc5\x02\x52\xa6\x83\x8f\xca\x91\x17\xc1\xb2\xf2\x45\x3c\xb7\xe3\x65\x71\x93\xbd\x44\x0c\xe4\x6c\xf9\x37\xa6\xb0\x0f\xb4\x59\x5e\x77\xeb\x66\x18\x6e\xe6\x10\x9a\x5d\x6a\xb2\x6c\xbb\xf2\x7b\x8e\xc2\xfd\x4a\x1c\x4d\xe8\xb5\x3f\xdf\x32\x4e\x86\x8d\xb1\x06\x78\x3c\x0a\x85\x8d\xd9\x7a\xd0\x8c\x62\x8d\x63\x2f\xf7\x8d\x9d\x4e\xc8\x6b\x27\xa5\xc0\x2d\x26\x74\x7a\x55\x3f\x0c\xce\x99\xac\x94\xb3\xac\x6a\x8b\x9a\xe9\xaa\xfd\x5a\x5d\x6c\x67\xe6\xae\x7b\x06\x26\xe2\xd3\xe7\x60\x50\xae\x61\x36\x02\x6f\x87\x62\xcd\x1f\x4f\x93\xae\xdd\x90\x58\xf7\x93\xb0\xfc\xc3\x6d\x6e\x98\x2a\x65\x97\xa3\x48\x49\x83\xd4\x2b\xc8\xdd\x89\xd5\x44\x1e\xd2\x01\xf7\x8d\x93\x6d\xd3\x1d\x4d\x18\xd8\xeb\x1c\x18\xec\x37\x5f\x9e\x1d\xe2\x4c\xff\xc4\x4f\x4c\xbb\xd7\xeb\x25\xa6\xa6\x1d\xe1\x67\x21\x1f\xf3\x48\x03\xdd\xbc\x77\xeb\x22\xc2\x87\x10\x85\xd3\x45\x4e\x7b\x7d\x73\xa4\x58\x2f\xbd\x10\xee\xa2\x29\xb0\xab\x9e\x82\x25\xac\x50\x57\x4f\x25\xe9\x1b\x21\xb0\xfb\x94\xcf\x36\xca\x77\xbf\x7c\xb6\xca\x93\x0a\x9c\x6b\x65\x94\x58\x13\xab\x21\x0b\x49\x3f\xd6\x87\x89\x11\x8e\x00\xc7\x38\xa3\x38\x2f\x5a\x5d\x1d\xf6\xf8\x7f\x4c\xac\xf2\xe3\xa4\xef\xd9\x29\xb9\xcf\x05\xe9\x9a\xd7\x79\x33\xf4\xca\x3e\xa1\x73\x74\xf5\xf4\x59\x2e\x66\x21\x67\x08\xc0\x55\xf7\xb5\x49\x1e\xba\x51\x0c\x8d\xa3\xc9\x93\x20\x97\x4f\x17\xc8\xd1\x22\xfb\x64\xb8\xa5\x04\xf1\xc5\x11\xb3\xf1\x0c\x05\x14\xb6\xa1\x87\x0f\x52\xae\xb2\xea\xbc\x0a\x03\xe6\xf9\xd6\x0d\x34\xab\x8c\x42\x98\x8e\x2c\x0a\x17\xb7\x16\xc5\x7c\x48\x34\xa8\x99\xa7\xd4\xfc\x4f\xf7\xe2\xb9\xf6\xe1\x7f\xc0\x0f\xd4\xd6\x79\xb9\xfc\x07\x77\x7d\x3c\x72\xa6\xf9\x97\x9f\x7d\x4d\x04\xc5\x82\xac\x87\x55\x90\x59\xa6\xfc\xab\xb9\x91\xcf\x2c\x87\x66\x5b\x2e\x4a\x8b\xcd\x0a\x2e\x85\xd1\xcf\xff\x4f\x68\xea\xcb\xbc\x89\xe5\xd4\xee\x3d\xb8\x6a\xb1\xc3\x8b\xe2\x75\x52\x12\x37\xea\x97\xb8\xf9\xec\x80\xfb\x51\x70\x47\xb1\x32\xc7\x72\xc8\x32\x67\x2c\xb5\x88\x22\x2a\xe5\x23\x56\xf6\x2b\xa2\xe7\xe3\xf1\x26\xad\xd9\x98\x64\xa6\x32\xb2\x68\x47\x33\xc8\x9d\xc5\x87\xf3\xed\x42\xb4\x63\xc4\x19\x9a\xcf\xd6\xcd\xd9\x4a\x60\x1b\x42\x32\xc9\x98\xb4\xbe\x51\x1c\x82\xe7\xe2\xe9\x1b\x51\x89\x3c\xdd\xf3\x58\x21\xb6\xbc\x99\x9e\x90\xa9\xfa\x23\x47\x6a\x59\xf6\xea\x39\x66\x6d\xd6\x8a\xea\xc8\x1c\x94\x3b\xed\x63\x38\x29\xb1\xce\x33\x5c\xf1\xef\x83\xc1\xe1\x3e\xd9\xd7\xae\x00\xb6\x7f\xbd\x68\xe0\xe8\x9b\x17\xa5\xaa\x47\x04\x88\x1d\x5b\xc4\x04\xca\x46\x1d\xfe\x8c\x6e\xe5\x8e\x86\x90\xae\x74\x3d\x50\x58\xb6\x08\xde\x1b\xae\xe1\x3f\xeb\x00\xa0\x47\x27\x91\x56\x75\xca\xa7\x06\xe3\x1a\x9d\x7d\x68\x5e\xc3\x6f\x76\xe3\x44\xd1\x5d\x8b\xe4\xea\xb8\x84\x22\xab\xcb\xdf\x14\x2b\x61\x7b\xd7\x25\x41\xff\x4d\x27\x25\x9e\x89\xa7\xa2\x2f\xc0\x63\x09\xa2\xd4\x4d\x61\xa8\xe7\xe7\x86\xa5\xc8\x71\xaf\xe2\x47\x45\xb3\xd1\xc9\x75\xb0\xb3\xca\x23\x93\xe1\x82\x2d\x25\x64\x05\xa9\x89\xf9\x35\x72\xc5\xed\xd0\x91\x35\x63\x7f\xe7\x10\xd4\x42\x0c\x0a\x8f\xb0\x77\xfe\x16\x3b\x53\xf1\x15\xdf\x14\xda\x0c\x8c\xf6\xc7\x18\x5f\x7f\x70\x2f\xd1\x88\xf1\x53\xbd\x20\x7f\xdf\xba\x90\x50\x67\x91\x9a\xfa\xae\x7f\x97\xd5\x14\xbd\xd4\xb5\x72\x92\x2c\x8b\xba\x7d\x98\xba\x21\x3d\xc0\x5b\xc9\x7c\xd6\x66\x7e\xe6\x29\x21\xca\x98\x4f\x8b\x6f\x45\xaf\x7a\x31\xeb\x50\xba\x58\x68\x25\xd9\x56\x3b\x23\xcb\x0f\x40\xdb\x98\xcb\x7e\x52\xd4\x7f\x1d\xa5\xf9\xcb\xc5\xd8\xf3\x0a\x6f\xbe\xcb\xfe\x70\xc7\x3d\xd9\xc5\x91\xaf\xfb\x74\xdf\x9f\x0b\x81\x93\xb2\xdf\x3a\x3f\xf4\x07\xb0\xee\x56\x2e\x4c\xde\x30\xf2\x98\x04\x76\xab\xd5\xd6\xd0\x00\x68\xb4\x1e\x24\x6d\x69\x24\x14\xc2\x2a\x6b\xed\xc2\x5a\x60\x72\xd9\xa2\x83\x89\x7a\x94\x84\x17\xf2\x3e\x1d\xd1\xc8\xa9\x57\xf7\x87\x76\xae\x8d\x78\xcf\x20\x0c\xa1\x63\x8b\x5e\x91\xdc\x2c\x6f\xb6\x3c\x40\x09\x1e\xe7\xfe\x81\x54\xf3\x02\x70\x8e\x48\xfe\x3a\xd0\x1e\x72\x94\x34\xea\x6c\x74\xa1\xb4\x98\xb7\xb7\x97\xe5\xfb\x01\x56\xe1\xc3\x3b\x30\x1e\xf8\x7b\x09\xa7\xca\x32\x2a\x07\x7c\xa2\x8d\xd5\xde\x86\xab\xbb\x82\x1c\xad\xe9\xba\x69\xec\x74\x04\xb6\xb3\x27\x50\x10\x1c\x46\x86\x73\x9d\xe0\xcc\x2a\xb6\xdf\x16\x9e\x67\x1b\x25\x66\x1b\x72\x2e\xc5\xd5\x52\xea\xaa\x46\x80\x2b\x03\xe9\xd6\xba\x28\x40\xce\x4e\x11\xa6\x8c\x2f\x3f\x0b\xde\x86\x12\xac\x34\x8b\x59\xfb\x4d\x0a\x4f\x1c\x8a\xc7\xa6\xf3\xb1\x69\x16\x5c\x31\x3f\x6b\xed\x65\xdf\x9b\x87\x9d\xe6\x89\xab\xbb\xa5\xf3\xe4\x04\x46\xcb\x03\x30\x74\x0e\x6e\x14\xad\x7e\x6d\xd9\x39\x09\x06\x5a\xb9\xc9\xac\x62\xf9\xe8\xae\xb2\xe6\x87\x74\xaf\x7b\x5d\x15\x47\x67\x47\xe3\x24\x95\x9a\xad\x11\x2f\xa2\x7c\x15\xf1\x82\xab\xea\x97\xc5\xf7\xbe\xf0\xff\x25\x83\x21\x3f\x45\x9b\x5c\x72\x0e\x61\xf1\xa0\x58\x48\x58\xbd\xc8\x24\x2f\x8d\xda\xb5\xe6\x26\xd5\x9e\x85\x49\xce\x9b\x68\x0b\x41\x7b\xb0\x7b\xf4\x0a\xa9\xf0\xa2\x2a\x6d\x4e\x00\xc5\x7d\xb1\xeb\xaa\xb7\xa3\x34\xef\x93\x9f\x64\x77\xff\xd3\x01\xbb\x9e\x67\xaa\xcf\xdf\x29\x3c\x55\xc2\x7e\x93\x5b\x5d\x87\x82\xc2\x4b\x77\xff\x1e\xda\x8d\x4d\x32\x53\x08\x57\x3a\x6c\xbd\x41\x46\x3b\xec\x0a\x69\xa4\x86\xf0\x56\xbf\x39\x3f\xb5\x47\x9e\x7f\x47\x6a\x4e\xec\xe4\x31\x60\xd1\xe4\x15\x34\x2f\x05\x41\x38\x7a\x12\xac\xdb\x6b\x8d\xb1\x95\xce\xc6\xaa\x36\x64\x2c\x37\x55\xdc\xd6\x56\xaa\x61\x1d\x73\x1d\x27\x05\xd7\x8d\x76\x2d\xe9\x70\x65\xbe\xeb\xf3\x66\x75\x84\x40\xab\x07\x7d\x44\x19\x1c\xf0\xd4\xbc\x98\x15\x9f\x0c\xf8\x02\x1e\x77\xd7\x22\x76\x74\xb6\xdf\xda\x7f\x90\x71\x0f\xf6\x12\xf8\xa7\x0e\x4f\xe1\x78\x90\xe3\x36\x69\xc2\x05\x49\x84\x8e\x42\x0d\xae\xfe\xf9\x94\xd8\xbd\x03\x27\x18\x8a\xb2\x16\xad\x11\xcd\x21\x8a\xc9\x55\x6b\x12\x1b\xbe\xe9\xaf\xf9\xc7\xc2\xad\xbd\x04\xdd\xa1\xf5\x8c\x9a\x2b\xf6\x87\x4c\x71\x11\xbb\xeb\x8f\x3f\xf3\x2d\xe4\x07\x73\x85\xb8\x52\x1e\x76\x1f\x75\xdb\xc8\x74\x50\x37\xdc\xb7\xf8\x4e\x82\x45\x08\xb8\x16\xad\xc6\x27\x5f\x04\x57\xed\xc8\xe3\x97\x77\xc7\xdd\x32\x2a\xd1\xd9\xfc\x43\x95\xe3\x11\x57\x3f\xe1\xb2\xd1\xd5\x78\x66\x5d\xa5\x3d\x1a\xec\x92\xd9\x6b\xb2\xf0\xf5\x16\xd2\x8a\x73\xb1\x2b\x9a\xa7\x47\x17\x5c\xc1\x2e\x5a\xb3\x70\xbc\x21\xf5\x39\x6f\x9e\xf7\xe0\xcb\xa5\x6a\x6a\x96\x25\x7f\x69\x2a\xf2\x2e\x7d\xda\x0e\xdd\xa5\x66\xcc\x83\x4d\x55\x5d\x68\xc4\x0b\xa2\x3e\xe1\x77\xfc\x82\x52\x94\xc7\xe5\xc7\x31\xb6\x61\x35\x18\x08\x0f\x75\xa6\x33\xcc\x2e\x15\x47\x8a\xbd\x8f\x4e\xad\x40\x96\xf0\xb3\xbf\x37\xe1\x6a\x74\xa3\x9b\x46\x6f\x4b\x33\xfd\xb2\xa2\x59\x38\x2d\xa9\x54\x34\x9c\xf7\xc5\x10\x70\xed\x42\xa8\x16\x42\xef\xe3\x12\xcb\x8e\xd5\xce\x4b\xd1\x25\x2f\x22\x1e\xf6\x4a\xf9\xcd\x66\xcd\xeb\x37\x58\x1f\x1b\x5f\x93\xeb\x56\x19\x73\xa1\xa7\x0a\xfb\x67\x62\x67\xf0\x3b\xdc\xb5\x2a\x0e\xef\x5f\x14\xee\x5b\x1b\x7a\x3a\x21\xdd\xcf\x5d\xda\x4d\x5c\x95\xe6\x23\x28\xb6\x73\x04\x9f\x1e\xd3\x4d\x06\x49\x22\x09\xf1\xbc\xd1\xd6\xfa\x62\x8d\xfc\xc2\x2c\x25\xa9\x1f\xc7\x3a\x22\xeb\x42\x1b\x83\x33\xb8\xce\x8b\x48\x82\x67\x0b\x5c\x3c\xa7\x98\x46\x43\x61\xd3\x72\x80\xfc\x42\xe1\x6a\x54\x84\xf4\x99\x05\x9f\xe6\x10\x5f\x43\xd9\x49\x86\x05\xd0\x55\xc5\xaa\x1e\x4c\xf3\x3c\xc8\xc3\x83\xde\x3f\x44\x36\x37\xbd\x9f\xeb\x25\x43\xd8\x5f\x90\x6a\xb1\x4f\x91\x41\x75\x48\x3b\xee\x1e\x12\x2f\x0e\x04\xb7\xb0\xc0\x47\x24\x16\x53\xb1\x0f\x2a\x02\x5c\x90\x4d\xdc\x54\xac\x2a\xb4\xb4\x53\x5d\x57\xd2\x3e\x4a\x18\x5b\xb8\x27\x45\x6c\x7d\xde\xed\xfe\x33\x2d\xf4\xcf\xd5\xe5\xab\xb6\x37\x11\x29\xdf\x9d\xba\x1c\xd3\xc2\x31\x0e\x7c\xcf\xec\xf1\xa6\x18\x47\xe7\x8d\xdd\x75\x0f\x05\xbc\x2d\xd6\x30\xb2\x05\xc0\xe2\xc7\xfb\x57\x04\xd2\x7a\x44\x17\x7c\x0c\xce\x5d\xa5\xb6\xc0\x36\x15\x92\xb7\x93\xd8\x7c\x35\x8c\x7c\xad\x1b\x66\x49\x01\x1a\x37\xe9\x05\xd6\x58\xb9\xd1\xc5\x06\x34\xf3\x41\x1a\xf7\xc3\x0b\x02\x96\x9b\x2b\xf9\xb6\x76\xfc\x6b\xc7\xb7\x55\x27\xa1\x0f\xa8\xcf\xa2\x6b\xf7\x79\x79\x47\x3a\x09\xdd\x97\xa3\x5d\xee\xfd\xd5\xf5\x18\xc7\x68\x93\x8f\x25\xcc\x3f\xac\x25\x7e\x91\x53\xb0\x26\x9f\xce\x2f\x77\xd8\x7a\xdc\xbd\x0e\xf3\x43\x31\x91\xcb\x2f\x68\x68\x08\xa6\x77\xe3\x86\x84\xb6\x77\xf1\x11\x14\xe1\xd9\xe1\xa6\xbf\xd1\xad\x61\xd9\x2c\x4b\x88\xd9\x5e\xa6\xdd\xab\xec\xd9\x03\xdb\xe1\x84\xe4\x33\x4b\x5d\xd2\xb3\xc6\x39\xb3\xed\xc1\x85\xf9\x28\x2a\x6e\xe6\xf0\x16\xfb\x93\x1e\x10\x12\x20\xef\x5a\xd1\x52\x6b\x12\xf9\x56\x58\xca\xc6\x0a\x04\x8a\xc8\x9f\x36\x32\x11\x58\x85\xbf\xb6\xeb\x2a\xdd\x86\xe5\xc7\x1a\x8f\x84\x11\x40\x89\xa1\xa8\x44\x14\xb5\xfe\x35\xc5\xf9\x7d\xce\x2d\x89\xf6\x8a\xc6\x19\x9d\x95\xce\x6f\xec\x51\x91\xdc\x76\x8f\xd6\x86\x33\x6f\x19\xc3\x4e\xce\x02\x9c\x66\x2e\x88\xc4\x7a\x61\xba\x77\x2f\xe2\x4b\x8d\x68\x26\xfc\xd6\xf1\xaa\x9d\xfb\xd6\x98\x06\xd9\x2a\x85\xeb\x77\x10\xe3\x9f\xd6\xd9\x2f\x4d\xf1\x73\xff\x5c\x93\xad\xf9\x1d\xb9\xb3\x3e\x43\xdf\x6d\xfd\xed\xaa\x2a\x05\x31\x2b\x9a\x8f\xe6\xee\x26\xfa\xab\x28\x17\x27\x34\xfa\x01\xff\x12\x57\x65\x8e\xb3\x08\xcd\x6c\xdc\x74\xc3\x47\xa4\x95\x67\xeb\x69\x61\x4c\xe9\x6f\x99\x1d\xf4\xbb\x22\x56\x04\x0a\xfb\x79\x6d\xb7\xc6\x37\xf9\xbf\x47\xe7\x34\x60\x64\x47\x82\x2d\x12\xfa\x38\x71\xcd\x2b\x6f\x4d\xca\xda\x0f\x8d\x56\xef\x2e\x1a\x62\xc2\xbc\x39\xb5\xdc\x15\x59\x8d\x78\xeb\xc9\x3e\x57\xaa\x57\xf4\xbd\x57\x3b\xb6\x8f\x35\x87\x54\x48\xd3\xd6\xf4\x54\x86\x33\x5e\xb3\x49\x90\x2e\x0f\x7e\x9c\xd5\xde\xbb\x1e\xf0\xed\x20\xd7\x1d\x94\xe9\x18\x66\x2e\x4a\x6b\xee\x6a\xe8\xb0\xba\x3a\xc8\x80\x24\x8e\xd7\x4d\xba\x26\xef\x66\x75\xfa\xfe\xe3\x9e\x99\xee\x17\xe3\xde\xb0\xdc\x15\x64\xf9\xe1\x6b\xdf\xb5\x8b\x0c\x31\xfb\xf4\x8f\x4a\xbc\x6a\xad\x89\x61\xcb\x1b\xad\x6f\x7f\x93\xbe\xbe\xcd\xfa\xcc\x88\x97\xc2\xf9\x61\xe2\xc0\x7e\xdf\x25\x2a\xdf\x2f\xe2\xbe\xf0\xf8\xcf\xdc\xf1\x9b\xa9\x33\xfe\x08\x10\x03\x75\x72\xa2\xf6\xd4\xad\xe6\xc6\x90\xcd\x7b\xe4\xaf\xf7\xb9\x99\xa3\x82\x77\xfa\x3f\xae\xc0\xae\x51\x73\x62\x65\xb3\x34\x7f\x85\x9e\xd7\xb1\xe0\x57\xd6\xcc\xeb\x05\x6a\xb5\x3d\xde\x67\x30\x5f\xf4\x78\x2b\x43\xfd\xaa\x82\x0c\xed\x67\xcf\x72\xbb\x0b\xb6\x65\x87\xd9\xb1\xff\xdb\xd4\x32\xba\x2f\xaf\x48\x78\xbc\x26\x46\x08\xb5\x20\x3c\xef\x8b\x3d\xf3\x8c\x47\xec\x48\xce\xcc\xf1\x0f\x42\xfc\x7c\xb2\x61\xdd\x19\x1b\x75\xc2\x3d\xec\xe1\x87\x69\x48\x95\x72\xc8\x87\x7c\xdf\x13\x61\x72\xd5\x7b\x72\xfa\x25\xa7\x7e\x96\x1b\x26\x9c\x8d\x48\x89\x81\x53\x0a\xa1\xa6\x23\xac\xca\xd0\xca\xa7\x50\xa3\x7a\x34\x25\xc7\x8e\x9e\x1d\x11\xc2\xd5\xc8\x99\x39\x52\x59\x4e\x0d\x6e\x6c\x1b\xe7\xc8\x03\x3d\xac\xce\xb7\xb0\x13\xc3\xd1\x47\x38\x18\xef\x2d\x4f\xb7\x5a\x2e\xd2\xb4\xf7\x72\xf6\x25\x42\x86\x76\x2b\xcd\x0f\xd2\x21\xdf\xfe\xff\x23\xeb\xc3\x4d\x70\xef\xce\xf4\x30\x8c\x18\xa7\x70\xee\xb3\x3d\x9d\x57\x31\xb7\xd6\x4a\xc8\xa7\x72\x77\xa3\x75\xbb\xdc\x48\x71\x6f\x10\xdf\xae\x63\xfc\x75\x70\x42\xf1\x33\xe9\xde\x7a\x06\xe2\xd5\x77\x47\x9f\x0d\xd4\x80\x5b\x28\x5d\x35\xfb\xb3\xb3\x95\x23\x48\xbe\xd3\x6b\x91\xe8\x15\xf4\xb4\x42\xa5\xff\xba\xf2\x33\xf6\x9c\xfe\xa1\xe2\xc7\xd5\xb8\xfe\x83\x7b\xae\xbe\xb3\xbb\xdd\xcc\x83\x9d\x33\x4f\x40\xef\xf3\xc2\x41\xb0\x69\x67\xd6\x5e\x64\xb8\xb5\x0f\x38\x1c\x86\xf0\x99\xdd\x70\xc3\x04\xed\xcc\xe4\xce\xb2\x02\xc1\x26\x6b\x27\x7c\x18\x97\x7a\x07\x47\xff\xac\x1f\xe6\x4c\x9c\xae\xa3\xb2\x1d\x90\xd9\x12\xd9\xdd\x4e\x96\xdc\x71\x6a\xa9\xa3\xcc\x16\x41\xdf\x84\x9b\xe9\xc5\x32\xd1\x0e\x51\xba\x64\xb5\xa6\xd7\xb7\xb7\x99\xfb\xa4\xbb\x65\xcd\x3c\x5b\x97\x8a\xbe\xeb\xef\xe1\x78\xb2\x20\xe4\x96\x42\x3f\x2b\x5b\x6b\x0e\xc1\x8e\xf5\x25\x62\x09\xcc\x56\xad\xe0\xcf\xfa\xab\x34\x38\xfe\x0b\xa2\xc3\x1f\x72\xa5\x94\x72\x41\x4b\x24\x6c\x5e\xee\xb7\xce\x53\xca\x2a\xd9\xaf\xd2\x9e\xa7\x5b\x6e\x2f\xf7\xc0\xb3\xf7\x0e\xe1\x1c\xb4\xb7\x71\x0c\xd3\x36\x3a\x7f\xe2\x80\xdd\x2e\x69\x03\xf2\xa0\xf9\xc2\x94\x3e\x3a\x54\x3f\x3d\x84\xe9\xbe\x84\x45\xc3\x8f\xce\x79\x34\xaf\xd5\x68\xb3\x80\x43\x53\x59\xd0\xca\xe5\xa9\xbd\x98\x53\x8a\x0c\xa8\xc9\xc7\x61\xde\xe8\xde\x3f\x53\x69\x82\xe6\x08\x8d\xef\xfd\xa9\x8e\xd5\x43\x5c\x78\x0c\x37\x28\x02\x5e\xe8\x1c\xb4\x46\x58\xb7\x67\xfb\xdc\xca\xf6\x61\x35\x0d\x92\x83\x58\xa0\x76\xcc\x2b\x12\x03\x46\x5e\xfa\xa4\x47\xe1\xf1\x9b\x0b\x4b\xec\x7f\x40\x79\xba\xb0\xf3\x80\x05\x39\xf3\x2a\x74\xbc\x8f\x21\x32\xea\xd7\xa5\x0d\x14\xf1\x91\x7d\x70\x45\x0f\xee\xb7\x55\x2e\x3f\xd7\xc4\x61\x53\x0e\x62\xe6\x53\x56\x64\x5a\x58\xd1\x08\xa0\x96\xb9\x42\x58\x45\x0d\x32\xdc\xc7\xc9\x3c\x32\x45\xa8\x9c\x69\x79\x69\x74\x2b\x4d\xad\x35\xdc\x6b\x34\xe1\x81\xa0\x7a\x56\x22\xcf\x64\xc1\xc7\x87\x4c\xc2\xc2\xc2\xcf\x5a\xed\x40\xae\xd3\x25\x1f\xd9\x1a\x97\x67\x1f\xf1\x26\x7d\x8d\xd8\xa1\xf4\x1f\x8d\x1a\x97\x48\x9f\xb0\x15\x50\x0e\x5e\xbe\x7d\x8b\x7b\xb2\xeb\xcc\xed\x1b\xf9\x81\xc8\x4f\x7f\xc4\xad\xcf\x14\x7e\x0f\xec\x5d\x5d\x47\x9c\x95\x61\xbd\x39\xa3\x1b\x78\xf7\x37\xc2\xac\x31\xa4\x95\x8f\x4d\x34\xc0\xf7\x28\xd9\x14\x3d\x1c\xf9\xaf\x56\x20\xf0\x82\xeb\x0e\x69\xe1\x8e\x38\xb3\x5c\xcb\xd0\x62\x1b\x05\x69\x1f\x79\x26\xf4\x7d\xa8\xef\x82\x42\x8e\xf2\x90\x2e\x64\xeb\xce\xbd\x3a\x7d\x06\xd9\x85\xbf\xed\xd8\x12\x4e\x9a\xb1\xad\xce\x2d\x4f\x7b\x94\x3b\x07\xca\xc9\xe8\xd6\xa3\x59\x2f\x5f\xd6\x14\x11\xe2\x2f\xab\x32\x34\x19\xe1\x6b\x56\xe5\xbd\x0d\x2e\xcd\x46\xab\xdb\x21\xad\xfd\xf7\x83\x27\xf4\xc9\x22\x98\xd8\xc2\xbb\x0e\x98\xed\x8c\xb8\xa9\x1f\x4e\x9e\x92\x79\xd7\xbb\xb2\xe1\x2e\xff\x55\x96\x09\xd8\x6a\x13\x57\x60\x1b\x3a\xba\xed\xde\xdc\x6c\xe2\x33\xdd\x9b\xde\xff\xb7\xfa\x7e\x13\x0b\x79\x63\x83\x6d\x59\xba\xee\xe6\x93\x22\xf1\xca\xfa\x61\xba\x9a\x20\x2d\xfd\xdb\x53\xaf\x61\x0d\xbb\x4e\x18\x74\xac\xa7\x82\xe9\x6f\x3f\x96\x15\x0b\x78\xdd\x47\xaf\xc7\xae\xe5\x40\x6b\x08\xfd\xf0\x52\xe3\x9a\x44\xa0\xb2\xf5\xa4\xe0\xdd\xb6\xd9\x21\x90\x80\x47\xfb\xc7\x5e\x27\xf2\x96\xde\xbf\x50\xb9\x77\x91\xc7\xa6\xad\x82\x4a\x25\x3e\xa6\xbb\x41\xb5\x0a\x23\xba\x79\x00\xf4\xe4\x5e\x11\x6b\x3e\x45\x8b\xb7\x8a\x8f\x1e\x6d\x11\xf3\xc4\x0a\x44\x86\x4e\x40\xd5\xa3\xaf\x0f\x81\x22\x05\xd0\xdf\x58\xdf\x0b\x7f\x4e\x3f\x39\xa7\x46\x94\x5f\xa0\xad\x2c\x4c\x6e\x2b\x23\x22\x6e\x5c\x48\x2f\xd0\x30\x36\xef\x27\xcb\xf0\xa3\xb6\x41\xb6\x6f\xe6\x47\xe1\xc0\x5a\x27\xc6\x91\xd7\x36\xa4\x0e\xcf\xcc\xbe\xd0\x9f\xec\x20\xd5\xf1\x48\xf4\x54\xde\xe1\x38\x25\xc6\xd3\xe7\x9a\x44\x32\xd9\x69\x7d\xb1\xd7\xb9\x92\x49\x0e\x51\xb4\xc8\xba\xaa\xf5\x6d\x11\xaa\x8d\x2d\xac\x33\x3e\x11\xeb\x09\x17\x2a\x5f\xec\x28\x48\x68\x57\x58\xef\x4b\xb3\x15\xe4\xa5\x05\xaa\x86\xd8\x18\x62\xd3\xdb\x1d\xb2\x69\xf9\x8d\x6e\x38\x12\x1f\xa8\x45\x8e\x8b\xf2\xa5\xf5\x17\xb9\xba\x22\xb6\x44\xf3\x67\xe6\xfd\x7a\x39\x41\xaa\xc0\xaa\xf4\xa7\xb5\x44\x67\x1e\xe5\xf7\x0a\x33\x0e\x75\xdd\x91\xbe\x62\x45\x05\x72\x94\xd4\x8a\x1f\x3f\x1e\x70\x33\xc9\x00\x5d\xba\xb2\xf5\xae\x74\x8d\xc3\xfd\x1c\xfd\x96\x5b\x63\xa9\xb5\xae\x9d\xd2\xc9\x85\x3d\x2e\x0d\x28\xf7\x90\x06\x18\x0e\xf1\xc3\x29\x1c\x3a\x26\xb6\xe4\xd4\x08\x5b\x41\xab\x16\xdd\xca\x79\x19\x18\x2c\x29\x1c\xe2\x86\x77\xa1\x43\x9c\xf0\xdc\xf9\xfe\xae\xf4\xe3\x44\x6b\xa0\xc1\x75\x65\xce\x0c\x45\x04\xb3\xa3\x1c\x33\x58\xe3\x00\x30\xfe\xa6\xc6\x27\x96\xf1\x0f\x1c\xb0\x38\x18\xbe\xbd\xf2\xc1\xb4\x48\x55\x81\x74\x7e\xf5\x19\x1e\x9b\x41\x80\xa7\x60\x3b\x54\x38\x76\xc1\xd3\xbb\x08\x3b\x5a\x6b\xb8\xe3\x90\x3f\x2e\x05\xf1\x85\x78\x3c\x2d\x31\x90\x56\x1a\x07\xbd\x89\xf8\xf4\x01\xab\x7b\x23\x7d\xb7\x19\xe3\xe8\x54\x0d\x5f\x64\x59\x24\x7b\x50\xf1\xe2\x17\x04\xdd\x90\xc3\x53\xce\xff\xaf\xac\x85\xb1\x6e\xcc\x3d\x1c\x79\xc8\x81\x2a\xa9\xb6\x70\x0c\x15\xd0\xd8\xb2\xe7\x47\x98\x20\x06\x77\x79\x95\x5f\xf2\xe2\x2f\xe5\x98\x7e\x55\xc4\x52\xc0\x87\x7b\x78\x0e\xa0\xbf\x7c\x98\x59\xb3\xb0\x80\xe6\x26\x45\x80\x97\xfd\xf1\x7e\xb9\xa0\x49\x67\xc5\xe0\xd9\xaa\x2a\x0e\xec\x06\x52\x36\xea\x66\x05\x8c\xf7\xf0\xf6\x2e\x28\xf6\x98\xbe\xa4\xaa\xa0\x70\xfc\xeb\x9e\xf9\x49\x99\x87\xdb\x9a\x6b\x97\x8c\x1c\xf5\x4b\xe3\x8e\xb3\xaa\x39\xa7\x17\xef\x80\x33\xcc\x8b\x83\xfc\xc7\xfd\x61\xc0\x70\x71\xe5\xd7\x3c\x05\xda\x7b\x6a\x8f\xaf\xba\xa5\x0a\xaa\x67\x0f\xdb\xdf\x8e\x63\x78\x02\x8a\x2a\x85\x4a\xfb\xc9\x3e\x4c\x18\xbc\x8f\xe7\xe2\x18\xd8\x1f\xf4\xc8\x61\x51\x25\x87\xc8\x94\xf1\xe0\x6b\x65\xeb\x38\x65\xed\x8e\xfa\xd5\x02\xc8\x3b\xfd\x85\xc8\xdb\x66\x59\xda\x88\xfb\xd2\xe3\xf0\x1b\x7f\xc7\x96\xd8\xd3\x69\x0d\xc4\x2f\x6b\x91\xc9\x3f\xeb\x69\x27\xec\x97\x49\x77\xcb\x27\xe4\x8e\x88\x9e\x26\xd9\xb7\xf3\x3e\x0c\xd2\xec\xb8\xff\x82\x04\x46\x7e\xd6\xd1\x22\xe2\xbb\x43\xdc\x90\x4e\xe6\xd2\x76\xbe\xff\x4f\xf1\x1b\x04\x1a\xc2\x09\xdb\x03\x3a\x34\x04\x98\xc2\xb6\xf4\x9b\xe5\x3f\x15\x35\x47\x0e\x2e\x77\xfe\xc9\xe9\x33\xa2\x2b\x00\xf1\xe0\x03\x8f\x58\xb8\x82\x32\x26\x46\x75\xf5\x6b\x9b\x19\xb4\x94\xbc\xdc\xa4\x99\xd9\xfb\x6e\xef\x80\x97\xda\xf0\x3c\x55\xbc\xd0\x11\x4a\x7c\x37\x57\xd9\x7c\xb3\x45\x25\xe8\xef\x04\x34\x67\x62\x90\xa1\x74\xf2\xba\xf9\x53\x45\xd3\x7d\x7f\xfc\x96\x7a\x7f\x7a\x96\xa2\x6e\x7f\xca\x29\x80\x1d\x9d\x51\xee\xe2\x14\x25\x2a\x0d\x80\x62\x15\xc6\x9f\x9b\x2d\xcd\xbb\xc5\x07\x4a\x3c\x3f\x51\xbf\xf2\x76\xf7\x46\xf2\xd2\x14\x72\x63\x0b\xfb\xf9\x01\x44\x2c\x1a\x6d\xd2\x2b\xf5\x95\xbd\xa9\x7f\x31\xf7\xfe\xc5\x69\x26\x94\xab\xf2\x81\xbb\x28\x49\xbe\xea\x51\x3a\x7f\xe2\x5e\x11\x68\xc2\x1e\x06\xaa\xd8\x34\xdb\xf1\x09\xd3\x54\x2f\x22\xb2\xba\x7e\x2b\x2d\x49\x34\xba\xd8\xd0\x5d\x2e\x87\x25\xc4\xef\x4f\xe5\xbc\xee\x86\x36\xd4\x66\xee\x57\x83\x59\x63\xef\xd4\x14\xe4\xeb\x4d\xbd\x3e\x5c\x53\x97\xfe\xa6\xfd\xdf\xcd\x33\x7c\xcf\x41\xcc\x26\xd3\xf8\xac\xdc\xeb\xce\x55\x3e\x7c\x30\xd5\x7e\xa8\x84\x38\x36\xe6\x5d\x9c\x11\x2d\x74\xc2\xdc\x81\x0b\xd5\x31\xb9\x6f\xc3\x80\x24\x97\x16\x4f\x81\xbb\xb4\xa4\x7b\x23\x42\x4c\x5c\x81\x26\xd8\x83\xa3\x4a\x2c\xd2\x8b\xcf\x52\x6b\xae\xd2\x21\x3f\x41\x85\xad\x9d\x2d\x44\x2d\xfa\x08\xb1\xde\xbd\x6a\x80\xb9\x89\x30\xcb\xa3\x91\x8e\x0e\x76\x14\x56\x10\x6c\x74\xb7\xb6\x36\x87\x44\x94\x23\x8f\x32\xfd\x3c\x22\x77\x00\x1e\x17\x7c\x3f\x44\xe7\xdf\x0f\x51\x3b\xf7\xf8\x44\xfd\xc8\x2b\x40\x26\x33\x04\x46\xb0\x70\xdb\x3e\x22\x24\x02\xec\x77\xb7\x7d\xb0\xf7\xb5\xa9\x48\x37\x29\xe6\xf6\x4c\xe3\x1c\xf6\xa4\x3b\xb2\xd5\x12\xab\x11\x6b\x3e\x12\xbb\xde\x5d\xf4\x0e\xeb\x73\x7d\x63\xab\x83\xdf\x36\x5b\x7d\x55\x67\x01\xd4\x2a\xef\xd8\xb7\xee\x87\x0d\x44\x6f\x3c\xea\xe0\x5c\x23\xc1\x62\x05\x21\x45\xab\x25\x18\x71\xae\xcf\x23\x40\x22\x81\x51\x09\x75\xce\x8a\x20\x7c\x32\x04\xf0\x7a\x63\xd1\x0b\x60\x91\x23\x41\x22\x6f\x7b\x0b\x13\x6d\x00\x20\x0b\x9d\xf4\xd6\xbe\x44\x71\xbb\xf6\x69\xa8\xac\x54\x5c\x73\xca\x85\xed\x64\x0a\x36\xff\x06\x47\x40\x66\x06\x10\x59\x90\x1f\xf0\x97\x43\xc9\x64\xd5\x2e\x73\x5c\x2a\xd1\x0e\xf5\x1e\xcb\x9d\x3b\xc6\xba\xdc\xf4\x1b\x83\x8f\x4b\xf2\xad\x76\xa9\xbe\x4f\x2e\x4e\xdf\x15\x04\x52\xf8\x8a\x78\x35\xfb\x60\xc9\xb3\x05\x2b\x80\x26\xee\x4b\xe3\x83\xce\x2c\x99\xe6\x60\x80\x88\xc2\x3a\xcb\xc9\x6f\x5e\x0a\x2b\x9a\xf2\x0f\xb9\x0e\x30\xb4\x33\x42\xe6\xb2\x8a\xcb\x34\x07\xd5\x70\x2e\x5d\x47\x36\x9e\xed\xe6\xce\x19\x08\xd9\xcf\xcc\x43\xf2\x2f\xeb\x05\x70\x83\x07\x56\x3a\xc7\xd2\xdd\x74\xb0\xd9\xce\xb8\xdf\x41\x27\x48\x14\x73\x4c\xf5\xbf\xc2\xc7\x38\x95\xdd\xb1\x71\x0b\x64\x6a\xaa\xe1\x7a\x31\x05\x42\x3e\xc1\x91\xc8\xaf\x54\x94\xf1\xff\x30\xf2\x58\xf3\x78\x9e\x16\xab\x9e\xbb\x93\x40\x74\x8a\x93\x10\x93\xc0\x12\x25\x51\x09\xe6\x5e\xfb\xd5\x69\x6c\x2e\x0a\x8a\x7a\xbf\x1b\x43\xef\x10\x08\xe0\x35\x51\x04\x44\xd4\x88\x23\x85\xd9\xb9\x80\x92\xe5\x47\x4c\xff\x0d\x30\xb0\x53\x2c\x98\x5f\xc6\x87\xcd\xfe\xd1\x1f\x3b\x61\x10\x63\x73\xd8\xb1\xfb\x67\x91\x80\x56\xf0\xe9\xf3\x08\x33\xa2\xa7\x40\xbc\xe7\x02\xfd\x16\xbd\x22\x19\x8c\xe3\x9f\xb5\x1e\xea\xe9\x96\x2a\x10\xd4\x0b\xf7\x58\x22\x29\x5e\xe4\x5b\x5c\x12\x72\x5c\xe8\x39\xcd\xb4\xca\x24\xc2\x01\x63\x14\x71\x87\xdb\xd9\xf1\x09\x4f\x6d\x64\xc7\x27\x49\x72\x39\x86\xa8\xaa\x83\xb4\xa1\x0e\xe5\x5c\xe5\x93\x6f\x17\x89\x5d\x7a\x4a\x16\xb2\x0f\xe4\xc8\xf3\xce\xb2\xe8\xb1\xee\x48\xb6\x0d\xb8\x5c\xc4\x64\x68\x26\xcb\x30\x69\xd8\x14\xd4\xb3\xc8\xce\xf7\x81\x7a\x69\xf3\x9a\x8a\xb1\xf3\x2a\xd8\xc0\x76\xbf\x54\x33\x9d\xa7\x5b\x88\xfb\x07\x19\xf3\x8d\x36\x1c\x11\xb5\xe1\xba\x82\x34\x78\x89\x5e\xdb\xfb\x93\x92\xf3\xef\xd9\xe4\x66\x0c\xa9\x70\x2f\xe0\x20\x1c\x76\x5d\x98\x05\x89\xfa\x62\x47\x03\x6b\xa4\xc9\xde\x5b\x37\x00\x86\x19\xbe\x94\x68\xf0\x03\x24\x19\x62\x5f\x52\x8c\x57\x84\xb8\x74\xdc\xbb\x41\x8a\x08\xb7\x5f\xc4\x66\xcb\x55\x08\xa4\x83\x98\xb9\x9c\x92\x03\x59\x49\x75\x37\xf2\xb4\xe3\x29\xc2\x47\x38\xff\x84\x1b\x9b\x10\x93\x23\xa2\x62\x2b\xb1\xf8\x4e\xc1\xa7\xe4\xd8\x8b\x4e\x51\x8e\xe1\x8c\x60\xc5\x41\x31\xbb\x5d\x8a\xf2\xe8\xaa\x62\x30\x1c\x9c\xc2\xdb\x6a\xd3\x63\x9f\x37\xd1\x1b\xb6\x20\x1f\xf6\xac\x65\xed\x1a\x54\xe6\x61\x8a\x69\x61\x0b\xe7\x08\xd2\x62\x83\x22\xbd\x27\x39\xb9\x08\xc5\x15\xc2\x84\xf4\x88\x0a\xcd\x7f\x40\x4b\x70\xf8\x56\x71\xf1\xcf\xaa\x48\x8f\xf0\xd9\x7f\xe3\x86\xf2\x9a\xc9\xde\xf9\x12\x8b\x90\x04\xdb\xba\x0f\x3f\xf9\xcf\x0a\xaa\xbb\x2f\xe9\x23\xf5\x26\x2d\xdf\x1e\x72\x84\xef\xf3\xb5\x82\x11\x86\x26\xef\x2f\x9a\x82\x60\x5c\x53\x8f\x7f\xec\xe2\xa6\x5a\xdd\x2d\x6e\x93\x8d\xc3\x1d\xd3\x93\x8b\x66\x89\x30\x59\x0f\x3b\x6e\x5b\x8f\xcc\x34\xaa\x76\xcf\x2f\x11\x90\xad\xe1\x25\xd0\x11\x0e\x72\x42\x55\xfc\xd6\x71\x6d\x8b\x48\x90\x39\xdf\x00\x43\x88\xb5\x80\xee\xf9\xf8\x7f\xf4\x52\xfe\x49\xe1\xee\x35\xaa\xa8\x9b\xe8\x37\xba\xe6\x6f\x09\x04\x66\x54\x8a\xe4\x55\x64\x06\xe0\x2e\xf5\x64\x4f\x5c\x41\x73\x06\xcb\x82\x1e\xf7\x4b\x92\xcf\xdf\xe9\xe2\x59\xbf\x53\xdc\xbb\xc8\xc7\x3b\x93\xdd\x9e\x87\x16\x68\xa3\x02\x88\x06\xd9\x42\xf2\xe9\x2e\x7d\xfd\x4b\x33\x8b\x20\xa4\x8c\xa8\x5a\x7a\xa7\x2d\x70\x99\x23\xdb\xf5\x34\x52\x90\x8c\xea\x0a\x95\x45\x88\xac\x8b\x22\xea\x50\x2d\xc5\x90\xf5\xb8\xbf\xf6\xe7\x7b\xd9\x53\xd9\x02\x1c\x76\x07\x24\xd6\x30\x28\x4a\x84\xe1\x40\x0e\xc9\x08\x39\x38\x54\x05\xfd\xc9\xaa\x2c\x5d\xff\xc0\x76\x0b\xc9\x17\x25\xe0\xb5\x23\x0f\x2a\xe9\x6d\xbb\xe0\x9c\xe9\xbd\x04\xa1\xed\x88\x7c\xfb\xb0\x68\xfc\xdf\xad\x67\x61\x95\xe8\x4e\x6b\x13\xb8\xdf\x31\x36\x6d\x3f\x6c\xf3\x95\x29\x13\x06\x38\xc2\xf6\xc1\x8e\x1c\x48\xaf\xb4\xb3\x8b\x0b\x7b\x5e\x2a\xb2\xbc\xf2\x70\xd6\xc3\xfe\xa4\xc8\xc5\xca\x2b\x47\x9b\xf6\x9c\xce\xa0\x5d\xf8\xb7\x41\xb9\x40\xc7\x68\xbb\xc1\x46\xb2\x2a\x46\x5a\xb2\x01\x1e\x65\x5d\x85\xc3\xb1\x65\x6c\x8a\x0b\xb4\x15\xbf\xe9\xe0\xce\x21\xef\x54\x95\x58\x87\x32\xe9\x6a\x04\x39\xad\x21\x07\xaf\x85\x55\xd5\xf7\x48\x8e\x73\x2a\x10\x1b\x83\xa7\x0f\xf3\x58\x5a\x6e\xc7\x5a\x66\x72\x8e\x31\x5f\x5a\x55\x7a\x15\x72\xb3\xd7\x1e\x2a\x4a\x71\x2e\xfa\x11\x58\xba\x3e\x9f\xdf\x8d\x9b\x71\x6a\x47\xc7\xba\x65\x98\xc3\x9f\x5b\xac\x4d\x0a\x76\x54\x6e\x5d\xee\x1b\xce\x25\x9c\x2a\x42\xea\xd0\xec\x41\xc2\x58\x61\xf5\x7c\x53\xf6\xb7\xa8\x0e\x38\xb7\xda\xe4\x5f\x95\x02\x6c\x81\xab\x35\x0b\xaf\x90\xe6\x83\x79\x21\x7f\xeb\x12\x0a\x07\x2f\xb2\xca\xfe\xab\xc8\xa2\x77\x5b\xb2\x60\x4c\x92\x0a\xb8\xc8\xfa\x76\xab\xaa\xba\xe0\x4b\x2e\xe9\x3d\x09\x66\xba\xae\x12\x18\x54\x0b\x2b\x06\xab\x33\xd8\x23\x76\xc8\x5d\x4c\x24\x5d\x99\xcc\xb9\x24\xa2\xb1\xf3\x91\x9a\x4c\x7e\x5e\xaa\x44\xee\xff\x04\xbf\x9c\xd7\x2f\x0d\x46\x85\x1c\x32\x67\x1e\x98\x68\x7d\xdf\xd4\x7b\xfc\xa5\xf9\xee\xe2\xde\xc0\xb4\x12\x3f\xd9\xca\x3d\xaf\x19\x8a\x0f\xb2\x59\xc5\x0d\x8d\xfe\x79\x9f\x2d\x9c\xdd\xad\x26\xe0\x37\x18\xd5\xa3\xf3\x40\xbd\x9a\x2b\xe3\xf4\x54\x98\x69\x11\x50\x95\x1b\x47\x24\x13\x94\x9d\xf2\x10\x01\x5d\x9f\x1f\x9c\xd5\x92\x09\xbc\x66\xf3\x47\x19\x1b\xda\x2b\x20\x97\xd9\x99\x53\x22\x3b\x5f\x4f\x96\xea\xb0\x6b\x57\x12\x4d\x3f\x77\x72\xf9\x18\xef\x56\xc1\xf5\x92\x26\x3a\xd6\x15\x44\x14\xa7\x9c\x88\xf9\x03\xa3\xd9\x23\x9c\x66\xe1\x6d\x44\x2e\xe9\xd0\xd1\x6e\x67\x5c\xd4\xca\x8c\xf2\x72\x1e\x4b\xcb\xca\x19\x1d\x4d\xe1\x88\x76\x74\x69\x02\x0d\x50\x96\xc8\x3e\xf2\x18\x05\x3e\x26\x32\xb1\xac\x92\x53\x8e\xf5\xd3\x7a\x22\x0e\xbe\xbe\x1a\x80\x35\xdb\x75\x64\x1e\x76\x51\xd6\xda\x07\xac\xfc\x34\x35\x02\x91\xd1\xe7\x58\xb6\x0d\x58\x8b\x88\xbf\x3b\xa3\x6b\xd3\xbf\xa2\x05\xf7\x4d\x3c\x33\x4e\x33\xf7\x2d\xf0\x46\x41\x88\x07\xd5\x02\x83\xa0\x7f\xa7\x9a\x28\x5f\xc1\x33\x8a\xc2\x5c\x71\xe5\x35\x81\x62\x8c\xb1\x4d\xb6\x6a\x38\xcd\x90\xee\x9d\x59\xd9\x83\x13\x48\x0a\x0b\x33\xa2\x52\x07\x3d\xc1\xfb\xfa\x4d\x44\xa9\x9c\x8e\xc9\x4f\xad\x32\x43\xe9\x17\x41\x40\x76\x27\x0e\xcd\xa0\xae\xb7\x67\x95\x07\x55\x4e\x9f\x20\xa6\x9c\xff\x86\x49\x37\xb3\xdb\x45\xf5\x55\x65\xd4\x09\x36\x0d\x6a\xe5\xef\xaf\x0a\xa5\xfb\x54\xf9\x64\xad\x88\xde\x32\xcf\xc9\x09\x2b\x14\x3f\x58\x9e\xa2\x4a\xe3\x6f\x08\x1b\x14\xa0\x1b\x41\x47\xad\xdb\xd3\xdf\x66\x5f\xd3\x87\x08\x19\xb1\xfe\x58\xa0\x39\xf1\xc5\xc2\x1b\xa9\x0b\x8f\xe6\x2e\x47\x42\x35\x4b\x55\x56\x52\x8a\x27\xe9\x72\x4c\x72\xbd\xca\xca\x62\x65\x58\x55\xc5\x9a\x6a\x51\xba\x19\x6e\xaf\x83\x38\x69\x97\x26\x7e\xae\xd7\x21\x9b\x74\x40\xa2\x28\x23\x12\x55\x94\x7d\xdd\x2c\xec\xbe\x10\x72\x33\x80\x27\x7c\xfa\x68\xda\xf8\x50\x52\x44\xa2\x1a\x23\x38\x8b\x0e\x4b\xb1\xa8\x92\xae\x1f\x97\xfa\x25\x44\xaa\xaf\xff\x69\x34\x35\xad\x31\xb4\x4a\xa4\xb3\xb2\x9a\x22\xc6\x25\xac\x0a\x46\x59\x5e\x68\xb8\x3c\x92\x90\xdb\x2b\x32\x96\x59\x43\xd9\x8b\xd6\x8c\x5f\xfc\xcd\x7f\xb5\xdd\xd8\xee\x10\x4a\x3e\x3e\xaa\x91\xc8\x60\xba\x00\xbb\x84\x23\x3b\x15\x68\x58\xe6\xff\xac\x5c\xa3\x1b\x8c\x13\xd4\xaf\xb4\x87\x9d\x93\x95\x43\x1a\x18\x5d\x52\x31\xdb\x82\x2d\x0a\x4e\x51\x2f\x36\x70\x03\x13\xec\x41\xe3\x19\x02\xfc\xb0\x12\xb3\xab\x54\xa0\x0e\xe7\x50\xac\x4a\x0a\x60\x0a\x16\x2e\xbf\x0c\x89\x49\xb6\xaf\x18\x4e\xc5\xe7\x30\x97\x10\xb8\x14\xc8\x84\xff\x6d\x02\x87\xd8\x41\xd0\x6c\xac\x4d\xb1\x0e\x25\x08\xa3\x26\xaa\x4b\x5c\x2a\xac\x90\x1a\x66\x0d\x14\x2a\xd1\x7a\x07\x41\x40\xf1\x87\xa5\xb5\xa9\x46\x96\x22\xb7\x78\x19\x8e\x7d\xd8\x0f\x1d\xbc\x1b\x59\x12\x61\xce\x7d\xd3\x84\x52\x46\x34\xa4\x6b\x1d\x19\xb8\xad\xd4\x24\x6d\xda\xb5\x49\xab\xd0\xb8\x42\xf0\xf9\xfd\x93\xc6\xb2\x3e\x83\x65\x73\x69\x72\x87\xe9\x16\xef\xcd\x1d\x73\x86\x91\x0a\xcb\xc6\x99\xab\x74\x59\xaf\x07\x3d\x12\x20\x45\xd6\x61\x82\x25\xfc\xe4\x9d\x51\xb3\x55\x99\x4e\x56\x6f\x05\x79\xa6\xd6\x49\x43\x80\x2a\x4b\xa9\x9a\x23\x53\xae\xfb\xc8\xeb\xf2\xfe\xba\xa8\xcc\xf9\xa5\x04\x99\x88\x35\x6f\x01\xee\x6d\x6e\x9a\xa0\xdc\xdf\xa4\x12\xca\xfa\x52\x5a\x5c\xd6\xc8\xfe\x5e\x6b\x40\x51\x63\x84\xb4\xaf\xda\xb3\xad\x1c\x42\xf4\x07\x2b\x21\x6c\x12\xac\x8e\x40\x45\xf0\xda\x04\x0a\x04\xff\x3a\xc8\x53\xb4\xf0\xdc\xd1\x15\xd1\xb1\x2c\x76\xc0\x42\x12\xfd\x16\xd6\x01\x0b\xfd\x9d\xd6\x08\x7e\x71\xb6\x6a\xd8\x0d\x80\xa4\xda\xfc\x71\x8e\xfe\xb7\xf3\xae\xc8\x64\xdd\xd2\x20\x4f\x81\xdc\x08\x38\xe2\xdd\x6c\x63\x51\x54\xdd\x29\x2f\xfb\xed\xb2\xde\xc8\xd1\xd2\xc5\xbd\xf1\x7c\x2c\x96\x75\x36\xd9\x22\x09\x51\x92\x83\x24\x82\x3b\x53\x04\xa4\x8b\x6e\xb2\x90\x6b\xb8\x24\x45\xb7\x22\x52\xe9\x94\xf9\xbd\xae\x94\xf9\x0e\x73\xa2\x79\xf3\x56\xac\x8b\x50\x8e\x99\x84\x72\x94\x58\x9a\xdf\x42\xa3\x12\x50\x14\x3c\xaf\x55\xcd\x58\xab\x47\xce\x3f\x21\x27\x15\x36\xc1\xd4\x11\x7b\x60\x4e\x0a\x7f\x56\x86\x88\x3f\x6d\x3a\x8c\xf2\xb3\xb9\x45\x8b\xa0\xa7\xf7\x9d\xf2\x2f\x2f\x5e\x41\xc2\x4e\xbf\x0f\x4e\x0f\x8e\xcc\x12\x3e\x65\xd3\x3d\xaa\xb1\xb6\xd5\x28\x5f\x83\xfa\x0e\xe3\x65\xd6\x3b\x35\x0c\x33\x81\x63\xb1\x02\x52\xa6\x10\xae\x60\xbd\x68\x53\x08\x73\x7c\xc1\x1a\x07\xc9\x92\xc4\xad\xae\x2b\x45\x5e\x9e\xed\x94\x44\xad\xe0\x48\xc7\xb4\x64\x7f\x12\x51\x07\x0d\x21\x26\x0d\x21\x0b\x5a\x7f\x55\x35\xb6\x64\x89\xed\x4a\x18\xce\xe9\xca\x4f\x42\x2a\xd9\x28\x0d\x9a\x7d\x09\x5b\x75\xf9\x07\x75\x1a\xe7\x25\xb8\xa7\xfa\x3f\x3f\x3f\x4f\x59\xe9\x1f\xfc\x59\xcf\x7b\xc1\x66\xf5\xf4\x19\xdb\x83\xa5\x8c\x4a\x9a\xa0\x50\x3c\x59\x33\xd9\x03\x5f\xda\xa7\x33\x18\x7d\xa1\x11\xaf\x87\x52\x73\xc1\xea\xa7\x76\x6e\x55\x8a\x92\x87\x5c\x71\xd4\x3b\xbc\x9e\x9e\x40\xfb\xca\xc1\xae\xe9\x99\x29\xa1\x78\xb6\x91\xe5\xb3\xed\xa8\x08\x7e\xf7\x5d\xdb\xdd\xa0\xf5\xb9\x5e\x3a\x93\x1c\xe1\x3c\xc3\xbd\x11\x81\x19\xee\x30\x92\x3b\x32\x99\x96\x83\x50\xb5\xa1\x68\x8e\x3f\x14\xbd\x39\x43\x69\xda\xd3\x5c\x22\x42\xba\x5f\x54\x03\xbd\xfd\xff\x38\x3f\xe8\xcf\xb0\xcd\x2c\x83\x6c\x0b\x19\x54\x11\xf5\x54\x53\xf7\x62\xd0\xc2\x52\x34\x6c\xe6\x8e\x9d\x0f\x94\xa3\xd6\x3d\x3e\xbf\x9d\x65\x88\x28\x80\x2d\x6a\x0f\x5b\x76\x95\x28\x56\xaf\x60\xc8\x5e\xc6\x58\xfd\x92\xdf\x8c\xac\x0a\xb6\x3b\x7d\xea\x52\x54\xff\x3d\xca\x08\x3a\x60\x5b\xcb\x2d\xb2\x0f\xcd\x6f\x44\x0f\x6a\x85\x56\x09\x7a\x10\xf2\x35\xf6\x49\x14\xa2\x63\x8d\x37\x12\x7a\x1f\xa1\x87\x30\xc0\x66\xb9\x74\x43\x8a\x46\xaa\x8f\x4c\x1e\xd2\x97\x51\x44\xee\xa5\x14\xb0\x95\x5c\x4e\x8f\x34\xc8\xde\x08\x16\x10\x99\x5a\x1f\xcf\xa5\x28\x5c\x76\xb4\xc0\xae\xd7\x24\x74\x6b\xd2\x24\x90\xdf\x84\xfa\xc3\x17\xb2\xb1\x13\x55\xbe\x6b\x52\xba\xce\x4e\x1d\xc1\x5b\x25\x6b\x26\x99\xdd\x13\xbb\x52\x13\x24\x05\x90\x52\xaf\x95\x38\xd0\x85\x12\xa3\x0b\xc4\xb4\x4b\xdf\x80\xc4\x84\x8f\xb6\x72\x2d\x10\xb2\x10\xfb\xf0\x4d\xee\x52\x0b\x37\xb3\x42\x3a\xea\xb4\x2b\xe0\x30\xf1\x2d\x1c\x0f\x7b\x38\xdf\xc8\x3f\xbf\x80\x46\x24\xec\x8b\x39\x92\x8e\x81\x25\x0d\x18\x21\x05\x72\x2a\x52\xe7\x9f\xf8\xde\x59\xe2\xae\x6f\x8d\x9a\xe1\x53\xe7\xfa\x61\x9d\xf8\xa9\xdc\x36\xde\x9f\x85\x0c\x38\x2b\xea\x38\x14\x7b\x53\xbb\x6f\x0f\x21\xbd\x2d\x4b\x2b\xf3\xd6\x86\xa1\x2d\x89\x35\xda\xdb\x8f\xfd\x57\xd6\x88\x11\x69\x21\x84\xd4\x30\xd1\x51\x0f\x69\x6b\x75\x2c\x2f\x6b\x91\x79\xd9\x05\x3e\xe6\x5b\xec\x4b\x7e\xfe\xf7\xa8\x34\xe3\x0b\x8a\x19\x86\x3e\xdb\x2d\x42\x3c\xe3\x6a\x96\xc3\x57\x19\xf8\x00\x4e\xb3\x17\x7c\xb8\x70\x65\x7b\x46\x2d\xaf\xaa\xbf\xe4\xc1\x89\x14\x0d\xb8\xa9\x2c\x2b\x41\x0f\xe1\x75\xe0\xe9\x9d\x9d\xc3\x55\x1a\x66\x26\x94\xe2\x84\x59\x16\x37\x2b\xf8\x7a\xaf\x7c\x8c\x11\xa3\x9d\xf9\x1c\x3b\x42\x1e\x21\xf3\x6f\xbb\xed\x45\x79\xc7\x2d\xb1\x89\xb6\xc4\x3b\xdd\x17\x25\x4b\x02\x6d\x1f\x71\x67\xc4\xc2\x27\x85\xfb\x11\xb3\x46\x64\xe0\xb0\x42\x5b\xe9\xb0\xc4\x52\x10\x46\xb5\xaa\x28\x37\x47\x24\xe8\x16\xee\x8b\xfc\x14\x93\x0a\xdd\xf8\xff\x6e\x5a\xd7\xde\xe1\x1d\xee\x32\x32\xff\x63\xed\x82\x93\xa8\x58\x9c\xb2\x96\x04\x11\x38\x5b\x95\xff\x02\x38\xda\x6d\xf0\x8a\x78\x6a\x9a\xd4\x92\x63\x01\x39\x1e\xd3\xcc\x6a\x23\xb9\x3a\x98\xe6\x9b\x3f\x92\x21\xd5\xe3\xd8\xd9\xc3\x6d\xfe\x98\x14\xe7\x79\xe4\x7d\xd1\xe1\x67\x4d\xa6\xc4\x39\xb6\xe3\x88\x55\x05\x87\x26\xfe\x9b\xdf\xc1\xff\xbb\x13\x3d\x08\x0f\x9f\x96\x84\x99\xed\x10\x3a\xe2\xea\x03\x47\xeb\xca\xbc\x5e\xb4\x43\x01\xa3\x53\xce\x24\x47\x5d\x28\x7b\x4c\x5a\xad\x9c\xfc\x8d\x1a\x8f\x7f\xb5\xc8\x76\xfb\xd8\x4f\x62\x91\x41\x2f\x0f\x9e\x1a\xf5\xfe\xfa\x0f\xab\xbf\x30\x41\x24\x64\x91\xaa\xad\x5b\x0d\xb8\x86\x17\x97\xb3\xfd\xc0\x8b\x03\x4b\x72\xfe\x36\x6a\x03\xb6\x92\x65\xe1\x89\x0c\x13\xb9\xdf\xaa\x78\xb1\x05\x47\x64\x5b\xe4\xad\xd9\x56\x10\x45\xdb\x51\x59\x49\x7e\x02\x71\xb3\xae\x84\xf8\x13\x1d\xb1\x34\xd7\x6c\x30\x1c\x30\x05\x31\xc0\x99\xe1\x66\xf7\x15\x65\xd3\xf9\xd2\xdc\xdc\xde\x02\x19\x2e\x82\x9d\xf1\xf8\x7f\x2d\xfa\x98\xd6\x8c\x99\xe1\x4a\x98\xce\x16\xd5\xa2\x31\x19\x41\xe2\xe6\x30\x04\x21\xeb\x0e\x23\x65\x56\xa1\xc1\x71\x03\x3f\xab\x36\xa2\x56\x11\xbc\x76\x0b\x34\xd3\x6c\x36\x1d\x41\xa6\x87\xc4\x20\x4c\x1d\x97\x18\x89\xaa\x44\x1d\x03\x29\x84\x0f\xa2\x6c\xe0\x53\x27\x89\x55\x48\xad\x94\xc8\xb3\xdc\x9a\x72\xd6\x2e\x29\xcb\xf3\xa5\xf4\xb8\x5f\xf4\x16\xd2\x96\x64\xe1\xb3\x84\x1d\xc6\x82\xc3\x4a\x0b\x79\x60\xb9\xa3\x05\x8f\x2a\x7c\x80\x89\xf5\x43\x00\xdb\x11\x0c\xaf\x18\x27\xcd\x76\x51\x32\x88\x29\x88\x94\x33\x62\xf7\x7d\xeb\x9d\x97\x24\x82\x83\x15\xa8\x51\x9d\x6e\x9f\x58\x00\xbd\xaa\x2c\x46\xdf\x71\xdd\x60\xa9\x50\x2b\x27\x91\x7f\x7c\x91\x36\xc7\x80\xf1\xb5\x91\x2f\x51\x4e\x1f\xec\x17\xb6\xe9\xb0\x92\x0c\xbf\x5f\x8c\x7d\x88\xbf\x85\xb6\x06\x0e\x5c\xbf\x9a\xb0\x54\x19\xff\x36\x21\x88\xbd\x82\x4b\x99\x48\x21\xdb\xa2\x5a\xb3\x9e\xf4\x15\xf5\xe6\x67\xba\xe9\x91\x35\x25\xb7\xe9\xe3\x2a\x87\xb1\xb0\xcf\x69\x02\x9f\x6b\x7e\xc0\x56\xd4\xa4\x57\x18\x74\xd9\x09\xab\xa9\x25\xe2\x0a\x78\xd6\x83\x24\x16\x45\xa9\x46\xea\x23\xe7\x36\xa3\x9d\xd9\xba\xa4\x47\x9c\xda\xf2\x9f\x97\x9b\xd3\x88\xe2\x4d\x26\x29\xa5\x59\x1f\x8f\x3e\x84\x7e\x38\xbd\xdc\x93\x50\xed\xaf\x56\x75\x9b\x02\x71\x93\x17\x71\x6a\x59\xc2\xb0\xcd\x7a\x90\x60\x7e\x8a\x3f\x16\x11\xfb\xe7\xa5\x47\x09\xbd\xe2\x1e\x7f\xd6\x16\x6d\x03\xa3\x4c\xff\x29\x1a\x83\xc0\x02\xcc\x91\x34\x5e\xed\x39\x62\x2a\xf3\xae\x72\x20\xdb\x35\x44\x86\x99\x15\x5b\x4d\xe5\x31\xdc\x17\x75\x5f\xf6\x6d\x99\x9f\x58\x29\x6d\x1a\x0e\xda\xb2\x0d\xf5\xad\x5a\x03\x3b\xe9\xe4\x44\x9c\xa1\x56\x95\xa9\xb5\xab\x9a\xa6\x72\x2c\x5a\xd4\x4d\x5a\x4d\xda\x55\x45\x48\xd9\x31\x91\x2f\x16\xa3\xd6\x8c\xc9\x3c\x65\x77\xe1\x25\x72\x4f\x36\x25\xed\x0e\x3c\xb3\xfb\xcf\xde\x0c\xc1\x14\xd4\x7f\xd4\x9e\x73\xd2\x12\xae\x28\x87\x64\xcf\x3d\x0e\x41\x45\x9f\x72\xbe\x59\xd7\xbd\x6a\x1c\xba\xa2\x2c\x66\x39\x4a\x26\x57\x0f\xe5\xd5\x2b\x48\xe5\xf0\x47\x69\x5c\x32\xe9\xc9\x1d\xc5\xe2\x6e\x0d\x4e\x92\x68\x63\xf5\x7e\x6b\xca\x89\x72\x2e\xa8\x60\x31\x95\x3c\x52\x4c\xbe\x50\x23\xfe\xef\x6e\x51\xd6\x7c\x84\x11\x9e\x57\x72\x56\xf8\x8a\x68\xb6\x24\x15\x81\x22\xf0\x77\x53\x9a\x2f\x62\x6e\x3a\x61\x03\x2e\xea\x22\xfd\xa3\x4b\x56\x77\xb8\xa8\x01\x09\x10\x5e\x62\xed\x92\x11\xa5\x35\x6a\x33\x5a\xe2\x61\x42\x2c\x7f\xb2\x34\xd3\x75\xf3\x1b\x56\x21\xdf\x70\xff\x7d\x7f\xc2\xf7\xe4\xa3\x44\xd5\xda\x92\x57\x3d\xe5\x04\x77\xa2\xb8\xac\xef\xa9\xaa\x56\x7e\x03\x30\xe7\xf8\xd1\x2b\x2e\xf1\x11\xde\xb6\x83\xab\x0e\x2b\x7a\x02\xef\xe6\x40\x07\x76\xb8\xd7\x28\xbe\x9e\xc2\x84\xf3\xfa\xe9\x7d\x90\x6e\xd8\x1c\x56\x08\x45\xbd\x0a\xa6\xfd\x61\x54\xb6\x30\x9a\x0f\x90\x1c\x7e\xcb\x2d\xb6\xc4\x1d\xe9\xf6\x3e\x62\x97\x11\xe7\x3b\x3b\x68\x7f\xdd\xd5\x37\x15\xb8\xcd\x44\xca\x8a\xe7\x9d\x3f\x94\x95\xf5\x90\x04\x9c\xdf\x55\x85\xd9\x51\xba\x84\xd3\x77\x13\x72\x77\x30\x83\xcb\x16\x49\xbe\xce\xf9\x8a\x0a\xd0\xae\x2f\x4a\x29\xad\xd6\xba\x02\x5b\xc1\xab\x36\x71\x6a\x89\x98\x06\x0d\x2b\x61\xfe\x15\xea\x6b\x7c\x34\x04\x91\xdc\x2e\xb6\xbe\xec\x53\xcc\x34\xa3\xdd\x90\x74\x9c\xab\xa0\x92\x59\xc9\x28\xf0\x6f\x3f\x5a\xa6\xd6\xfe\xfb\x61\x7b\x60\x71\xb8\x51\xa3\x86\xf4\x6e\xc5\xcb\x3a\x28\x98\x68\x9a\xe6\x55\xd2\x59\x8e\x90\xc3\x15\x08\xa3\x93\xff\xb6\xd2\xc6\xb8\x25\x54\xa4\xe7\xa4\x88\x09\xcc\x50\xc5\x63\x8f\x29\x6c\xef\x24\xb0\x07\xeb\xb8\xd2\xa6\xa5\xef\xf0\x59\x83\xbd\x1f\x56\xe9\xb3\x54\x05\x81\xbb\xba\x55\x8e\x9f\xfe\xe5\xd6\x36\xf0\x39\x27\x58\x36\xf8\xe8\xb2\x4a\xb2\x5e\x65\x8f\xc6\x01\xb7\x15\xa8\xa4\xe2\x1f\x68\x95\xf8\xa8\x48\xc9\xd2\x28\x8d\xc7\xcf\xc8\xe2\x40\xac\xa7\x78\x66\x7b\x14\x7a\xab\xa8\x30\x21\x7d\xd9\x3f\x87\x9c\xd8\xa2\x43\xdf\x8f\xef\xa7\xfb\xa8\x80\xdc\xad\x82\x6c\xc5\x9e\x6c\x27\x76\x9d\x0a\x3b\x93\x5f\xf9\xed\x59\xf1\xe5\x3b\x84\x3a\xab\x2f\x7a\xaf\x61\xf6\x8c\xa3\xc6\x57\x24\x41\x87\x17\xa8\x34\x7f\xd4\xdf\x15\xa1\x86\xb4\x61\x8c\x58\xd8\x0a\x63\x1e\x0e\x46\x3f\x8c\xc8\xb3\x27\x64\x0b\x67\x9d\x65\x9e\x39\xa0\xc2\x2b\xe0\xe6\xcd\xdb\x94\xaa\x3c\xad\x46\xe7\xd5\xcb\x9e\xed\x08\xdb\x1a\xfb\xab\x6f\x96\x6f\xcf\xa7\x6f\xe9\x6b\xf9\x13\xdf\x1c\x6a\x79\x2a\x3c\x1e\xac\xcf\x0a\x6d\x45\x56\x48\x91\x06\xe5\x22\xe4\xbf\xaa\xa6\x0f\x4c\xb4\xeb\x6a\x7a\xf6\xf0\xad\xc1\x38\x2f\x56\xcb\x8b\xab\xfc\xe3\xa9\xf5\x55\xe5\x16\xce\xe6\x1c\x13\x4f\x39\x77\x63\xb0\xc3\xc5\xe5\x2e\x83\xbe\x3c\xc3\xfc\x26\xe2\x2f\x8f\x6f\xd8\xdc\x1c\x11\x8b\xe6\x81\x5d\xc1\x71\x1b\x15\xc6\x1e\x70\xa2\xcf\x4f\xbd\x4c\xbb\x39\x3c\x3d\x39\xa7\x5b\x30\x4b\xd7\x3c\xb5\x0b\x15\x60\xd9\x83\xad\x76\xca\x73\x6e\xf1\x18\x67\x8e\x4d\xe9\x5a\x8a\x11\x80\x1c\x4d\x8f\xa8\xd8\x76\xe5\x22\x4b\x85\xea\x52\xc0\x5e\x2b\x8e\xfe\xe6\x3b\x36\xc1\x19\xc3\x5e\x2f\xd1\xed\x86\x44\xc3\x42\x21\xe0\xc4\xa2\x6d\x3b\xc3\x47\x2e\x7c\x6e\x7c\x42\x2a\x22\x5b\x2e\x2a\xee\x24\x70\xf9\xbb\x1d\x44\xc4\x14\x37\x73\x62\x6a\x3b\x18\x3b\xca\x72\xa6\x70\x3c\xfd\xec\x82\x0a\x5b\x38\xe6\xbd\xb0\x5c\x3b\xfc\x39\x4e\x4a\x2d\xe6\xe4\x08\xb4\x35\xcd\x38\x33\x84\x3c\x82\x09\x25\xc0\x17\x71\x2e\x3a\x89\xc9\x55\x69\x41\xf0\xd7\x60\x62\x8a\xc1\xcf\xe4\x87\xd4\x45\x51\xd9\xa4\x63\x6f\x24\x8e\xe5\xba\xfb\x1a\xc3\x4e\x98\x30\x38\xe0\x77\x88\x84\x86\xf1\xa7\x98\x47\xa3\x4c\x7d\xc6\x66\x33\x6e\x25\xc6\x2f\x9c\x62\xac\x52\x7f\xf8\x40\x94\xc4\xb7\xb2\xd0\xbd\xd4\xd7\x22\xb9\x75\xb4\xb0\xcb\xe4\xc8\x00\x6b\x9c\xc2\xa0\xb5\x29\x87\xc6\x1c\xc6\x74\x63\xa4\xf1\xc3\x67\x27\x87\xe3\x4e\x4e\x0a\x1c\x2a\x34\x26\x27\x6f\xd9\xc1\xc1\x16\xbd\xf1\x0b\x8b\xf3\xcf\x3b\x3c\xe0\xe7\xd5\x33\x2f\x4d\x14\x20\x26\xbf\xe8\x6f\x31\x18\x45\x77\xe4\x15\x93\x75\xc0\xcd\xb3\x7d\x20\xf3\x72\xb0\x83\x6c\x8a\xf6\x4b\x35\x19\x8b\x32\x99\xeb\x94\xff\x8a\x8a\x31\xbf\x2f\x39\x3f\x4d\x8b\x2a\xb0\xbe\x5e\xcd\xb5\x6e\x67\x20\xd4\x10\x16\xcd\x43\x5e\x6f\x25\x4f\xd8\xdd\x2e\xf9\x00\xa4\x6e\x03\x67\xae\x4f\xe9\x6c\xe1\xe0\xed\x3f\x2e\x2d\xe1\x9f\x5e\xc6\x66\x1c\xde\x7f\xba\x5b\xbb\x27\xb8\x6b\x12\x16\xd6\x43\x52\xc1\x43\x49\xf0\x56\xb1\xd1\x10\xc0\xde\xd4\xce\x1f\xb9\xcd\xba\x22\xf0\xc3\x05\x76\xf5\x20\xb0\xd1\x3b\xb7\x4f\x97\x5b\x84\x73\xae\x8a\x4d\x61\xbc\x29\x35\x60\x45\x26\x69\x40\xc4\x4c\x59\x99\x07\x52\xc5\xd5\x8c\xf0\xfc\xf1\xaf\xc8\xf9\xe6\xc3\x87\xfb\x4b\x96\x67\xa7\xe3\xc6\x67\xb0\x0a\x20\x7d\xca\x1a\xe0\xf8\xe6\x6f\x40\x0d\xa0\xbb\xf9\x83\x5d\xe6\x5b\x14\x84\x5d\x00\x85\x7a\x6b\xba\x66\x60\x61\x65\x07\xdf\x06\xaf\xf8\xf4\x39\x78\x8a\x71\x2e\xab\x8a\xef\x1b\x06\xd8\xae\x74\x4b\xfd\xff\x6e\x95\x84\x8e\xdc\xba\xc3\x9e\x06\xb2\x6d\xc6\x82\x11\x70\xd4\x9e\xe9\x5e\x9b\x69\x8e\x7d\x30\xd4\x10\x13\x14\xe2\x82\x76\xcc\x0e\xb7\xa8\x71\x91\xa9\xb1\x09\x77\xe9\x52\x04\xf7\xf7\xa1\x4a\xc4\xd6\x54\x64\x03\xe4\xde\x05\xb0\x9a\x75\xbd\x01\x9d\x3c\xac\x99\xe8\x03\xf3\x7b\x38\xfd\x0d\x3f\xf2\x8b\x00\xf7\x77\x28\x0a\xe6\xca\x70\xff\x1a\x5e\x2c\x56\x93\x68\xe4\xfc\xc6\x6c\xfd\xe1\x70\xde\x45\x47\xbe\xf1\x57\x0f\x3a\x29\x8e\xf2\x5b\x44\x74\x84\x39\x50\xb1\x66\x57\x39\xc3\x6f\x17\xd2\xf9\x22\xd8\x19\x56\x52\xca\x57\x28\xa1\xe1\x08\xf7\x3e\x2b\x8e\xfe\x29\x34\x83\x1f\xe2\xf1\x51\x7a\x11\x5f\x56\x1f\xc2\xf2\x49\x4b\x62\x60\x2f\xbc\xd9\x3e\x07\x86\x27\x0f\x6b\xd2\xb4\x4d\x0e\x2e\x78\x4a\x6b\xd1\x5e\x63\x1f\xe0\x6a\xc0\xab\x78\xef\xd6\xce\x1c\xb4\xf9\xba\x3e\x1c\xa6\x21\xdf\x8e\x13\x3d\x19\x24\xd0\xa2\x28\x2c\xde\xaf\xa2\x9a\x03\xfe\x36\x42\x0b\x3d\x2d\x4c\xd6\x7b\x77\x98\x31\x80\x41\x27\xa6\x9c\x15\xa4\xa1\x3c\x38\x7e\x7c\x53\xf0\xe1\x0e\xd5\x86\x4a\xa3\x71\xa5\x81\xc2\xfe\xc2\x02\x70\x4d\x2d\x1d\xd0\x75\x06\x84\xf1\xe8\xcc\x74\xda\xad\xfa\x7c\x86\x17\x91\xf2\x9e\xdd\x7e\x48\xc5\x5c\x0a\x9f\x04\xa4\x1e\x79\x35\x75\xc3\x6e\x9e\xe0\xdb\x5b\x56\x42\xf2\x50\x70\xf3\x3f\x66\x1c\x1d\x95\x1c\x7c\x2b\x4a\xfe\x77\x8b\x99\x7f\xd4\xb1\x71\xdd\xf2\x7f\x61\xd3\x9e\xe5\x57\x67\x5b\xc6\x97\xff\x14\xf5\x5b\x9e\x74\x43\xc3\x5f\x9a\x15\xdd\xf3\xc9\x82\xce\xfd\x90\x7d\x95\x3c\xf8\x1b\xc6\x2d\xa7\x4a\x37\x4f\x38\xd9\xeb\x1d\x62\x95\x5d\x2e\x0b\xab\x07\xd3\xee\x0b\x15\x33\x52\x13\xe8\xda\xf0\x4c\x70\x1e\xc6\x7b\x58\x27\x62\xa3\x3c\xf5\xe8\x3f\x1a\xef\x52\x08\x1b\xad\x2d\x2d\x72\x71\xdf\x46\x05\xc1\x6e\x7d\x15\x70\x68\x37\xc8\xf7\x4b\x4b\x6d\xbc\x46\x1c\x23\xbf\xe0\xf1\xcc\x81\x32\x19\xf8\xf5\x68\x86\x93\x4a\x02\x61\x42\x15\x41\xba\x81\x8e\xf0\x89\xa3\x8f\x2d\xfd\x71\x3e\xfb\x39\x97\x02\xd1\x8d\xaf\x55\xbc\xdd\x92\x5b\xaf\x6e\xff\xaf\x29\x71\x70\x59\x57\xbb\x8a\xf8\x99\x05\x6d\xbd\x4a\x44\xda\x52\xac\x7a\x07\x51\xec\xfe\x69\x96\x5c\x07\xf9\x3d\x88\x1d\xba\x96\x19\xd3\x4c\x8d\x95\x85\xc0\xe5\xeb\xfb\x33\x38\x5c\x54\xdf\xfd\xef\x96\x7c\x61\xcf\x99\x85\xe1\x96\xd5\x3c\xac\xfd\x68\xc7\xfd\xa4\x2f\x1c\x27\xfe\x8a\x7e\x08\x0b\x53\xc0\x7b\x6b\x17\x78\x9e\x87\xcd\xf8\xb2\xcb\xf2\xa6\xff\x4c\x2c\x07\x56\xb1\x4b\xe1\x82\x48\xd1\x17\x8a\x3d\x0e\x87\x3f\x0c\x28\x5a\x6e\xf5\xbb\x0b\xb1\x68\xa8\x18\x54\xff\x2f\xee\x61\xb4\xd4\xa7\x88\x6f\xb5\xaf\x52\x33\x70\x72\x4c\x00\x0f\x64\x7e\x7f\xb4\xfb\x8c\x85\x5d\x86\x6e\xed\xc3\xda\xb0\x04\x7d\x18\x66\x10\x6f\x3d\xde\x99\xb1\xba\x3a\x23\xed\xa8\xff\xf2\x81\xe6\x4b\x18\x64\xc2\xbd\x4c\xa3\xe7\xe6\xbc\x36\xcb\xa5\xc4\xea\x43\xb1\x6d\xe7\x43\x7e\x88\x47\xcd\x31\x87\xbe\xb3\xda\xea\x59\x20\x82\xeb\x1f\xe2\xb4\x9a\xcb\x12\x75\xf7\x2c\x67\x87\xf9\x67\x41\x0c\x96\x1f\x2b\xca\x10\x9a\x3b\xf8\x47\x4a\xe8\x2c\x27\x7a\x8c\x12\xfc\xef\x26\x05\x62\xfa\xf1\xe8\x6c\xd5\x71\xbc\x7c\x84\x25\xdf\x74\xc7\x9c\xf9\x1f\x77\x62\xdb\xb8\x5b\x3b\x3e\xa9\xb1\x06\xfb\xee\x97\x3d\x13\x33\x6f\x2b\x1e\x17\xd9\xee\x0b\xf4\x87\xeb\x68\xe5\x3c\x3a\x25\xc6\x7d\x5d\x71\x5f\xd0\xf5\xc1\x4b\xb8\xd6\xb8\x03\xc6\x13\x33\xee\xa0\x37\xac\xea\xc2\x98\xe4\x8f\x4b\xf8\x35\x5a\x71\x97\xc8\x78\x83\x43\x17\x89\xc5\xcf\xc3\xa3\xb9\x34\xfd\x05\x27\xe6\x41\xd9\x26\x2b\x94\x27\x90\x5f\xff\x94\xa8\x80\x4f\x95\xd4\x59\xba\x0a\x6c\x0f\x4f\x79\x38\xc8\x67\x38\x23\x0f\x45\xb3\x5c\x84\x75\x3c\x5c\x52\x50\xac\xae\x65\xb8\x2d\x7c\x93\x56\x6c\x6b\x72\x4e\xe2\x16\x8c\x32\xeb\x95\x47\x55\x59\x25\xb2\x2b\xdd\x7e\xc6\x47\xbc\x24\x0b\x0d\x76\xea\x32\xfc\xae\xbf\x77\x99\xc5\x42\xfc\x57\x7d\x56\x88\x98\x60\x15\x4b\x04\x74\x5d\x90\xf9\xf3\x20\xe6\x35\xd2\x07\x56\xec\x8e\x0e\x17\xbf\xb1\x36\x3a\x0b\xe1\x74\x8e\x58\xeb\x38\x2d\x4d\x50\x50\x54\xbe\x29\xdd\xbd\x36\xeb\xb0\xde\xef\x66\xfe\xde\xb2\xd7\x30\x72\xb2\xfd\xa1\x9d\xc2\x80\xf3\x07\xcd\x79\x71\x39\x5e\x21\x3c\xd8\x77\x29\x75\x29\x42\x70\x61\x42\x0e\xd7\xfe\xb3\x79\x0d\xf6\x71\xc1\x7a\xba\x3c\xf1\xbd\xa4\x49\x7f\xef\x06\x93\xa2\xd9\x15\x69\x3f\x8f\x5f\xfe\x71\x8d\x62\xa9\x57\x6c\xae\x3d\x22\xfc\xd2\x57\x6b\x47\x7d\xe5\x27\x48\x78\xe0\x88\x45\x0c\xbc\x62\xe4\xef\x9e\x25\x61\x3f\xe3\x5d\x67\xb1\xc6\x8a\xb5\x3b\x3e\x1c\x16\x97\xc6\x19\x44\x90\x32\xd3\x73\x8e\x9f\x8f\x44\xfd\x85\x21\x57\x77\xec\x17\x0a\xb8\x85\xf1\x63\x11\x9d\xdb\x6a\x41\xa6\x11\x00\x07\xf4\xdf\x9a\xc3\x3a\xd2\xb6\xd1\x78\x8c\x38\x4d\xaf\xfd\x58\xbe\xc1\x7b\x4a\xd3\xdd\x41\x04\xec\x46\x24\x4e\x88\x07\xd6\xcb\x81\x17\xc6\x5f\x04\x7b\x2d\x6e\xca\xc2\xd2\xd0\xc4\x99\x49\xba\x8a\x4f\x84\x98\x7d\xfc\x6a\x47\x64\x32\xa9\x76\x42\xe2\x31\xa6\x7d\xc5\xbb\x88\x0f\xec\x15\x18\x27\x0e\x6c\x9d\x65\x2b\xed\x02\xad\x3d\xa4\x10\xf4\xaa\x6e\xa1\x22\x14\x35\x08\xab\x5f\x3b\x73\xbc\xfc\x03\xce\xf9\x52\x69\x17\x86\x57\x6f\xf9\x84\xbd\xf1\x0e\xfb\xa1\xff\xaa\xf5\x10\x20\xf0\x72\xd7\xde\x07\x85\xa2\xc2\x63\x62\x5b\x7d\x65\x8a\x41\x5e\x09\xde\x60\x27\xe9\x7a\xdb\xfb\xa3\x60\x03\x4f\x7b\x96\xc3\xaf\x17\x75\x9c\x4d\xde\x6b\x58\x9e\x5f\xef\x90\x8e\x22\x19\x97\xb9\x3f\x79\xa4\xbc\x74\x8d\x60\xa0\x56\xd7\x4d\x35\x58\x7e\xdc\xb9\xae\x14\x16\xcf\x91\xb0\x43\x73\x7b\xbc\x0d\x81\xfa\x85\x76\x00\x1e\x8a\x2d\x9b\xc2\x9a\x99\x59\x9a\x86\xcb\x0f\x75\x40\x7f\xaa\xee\xf6\xa0\xe2\x58\x51\xd7\x10\x3a\xeb\xa8\x13\xb3\xe1\xe6\x9f\x5f\xb5\xab\x20\x54\x20\xce\xcd\xfa\x79\x8e\x81\xe8\x59\x22\xb6\x5f\x96\x7c\xf6\x0c\xad\x9f\x68\xda\x8c\x12\x91\xff\x82\x24\xa7\xb8\xcf\xec\x5a\x15\x17\xe9\x6c\xf6\x9e\x30\xb0\xf3\x3f\x20\x17\xa1\xfd\xa7\x9c\x12\x00\x0c\x36\x6b\x4a\xce\xd0\x81\x06\x36\x0a\xa1\x7b\x6e\x11\x0f\xbc\x5b\xe8\xdb\xe9\x1b\x34\x60\x41\x5d\xae\xb6\x94\x83\xa5\x95\x92\xd0\x22\x3d\x58\x4d\xf2\x71\xa3\xaa\x82\x9c\x9c\x03\x1b\x92\x30\x41\x57\xff\x41\xec\x42\x17\x3d\x41\xf2\xfb\x91\x6f\x19\x59\x58\x13\x42\xa1\xab\x27\xd4\x71\xb5\xd4\x9b\x1c\xa2\xdd\x36\x91\x9b\x8f\xb0\x54\x15\xf3\x17\x66\x17\x1f\x29\xe7\x77\x51\x12\x77\x3b\x52\x16\xe2\x8a\xf0\x9b\xcc\x84\x48\x76\x68\xd4\xb9\xf0\xd2\xef\xc1\x7a\x4f\xf7\x58\x1d\xed\xcc\xc5\xa3\xbb\xf6\xd1\xe4\x02\xde\xa0\x7e\x99\x6d\x75\x10\xc6\x27\xc4\x66\x0b\x6b\x3d\x5b\xb8\x5b\x84\xd3\x00\x0f\x4d\x6a\xf9\xc6\x58\x79\xe7\x90\x1c\xa4\x80\x2c\xe8\x36\xff\xa5\xee\xa9\x15\xfa\xd2\x2b\x6e\x97\x35\xc7\x76\x89\xda\xec\x8a\x29\xea\x8c\x99\x5e\x83\xf0\xb2\x6a\xb3\x9b\x11\x7a\x3d\xa9\x48\x18\xc1\xca\x26\xc8\x7d\x2b\xf5\x49\x98\x48\x46\x36\x76\x55\xa6\xb0\x67\x3b\xfc\x72\x85\x3e\xe2\x63\xb8\x14\x22\xb0\xba\x4b\xe1\x66\x20\x07\x56\x65\xa2\x06\x41\xd7\xb5\xaa\x81\x0a\x2e\x9a\xd0\xb2\xd0\x4d\xe5\x6a\x6a\x89\xc9\x5f\x13\xeb\x24\x11\x09\xcd\x42\xec\x23\x91\x2a\xcf\xd5\x05\x45\x6d\xcb\x27\xaa\x27\x4b\x3e\x24\xcd\xb2\x22\x07\xd9\x30\xf5\x72\xbc\x0e\xbb\x8e\xf0\xff\x4a\xe5\x4b\xff\x2f\x99\xac\x2e\xd0\x95\x12\x00\xf4\x44\x7b\x0a\x5b\x9f\x32\xd4\x5b\x12\x0f\x0f\xf1\x0e\xef\xa3\x28\x2d\x42\x85\x9a\xe7\xff\xb1\xc2\x4c\x47\x4b\x9b\xd8\xce\x66\x1a\xb6\xf5\x8b\x0a\xc6\x95\x49\x82\xc9\x89\x84\xd6\x70\x34\x1e\xe5\xec\x17\xb7\x7f\xfa\xc7\x7b\xf0\x88\x56\x61\x85\x4b\x10\xf1\x67\x04\x22\x68\x59\x9a\xc4\xa2\x84\xe2\x13\x2b\x89\x2d\x72\xd8\xcf\xda\xdb\xce\xf9\xc8\x1c\x71\xe8\x33\x47\x65\x7f\xd5\xdf\x81\xbf\xb2\x6a\xef\x28\xfa\xc9\x98\xcc\x92\x71\x78\x58\x99\xe2\x52\x07\xda\x3b\x4c\x7e\x03\x4d\xf5\x54\xf0\xf5\xa4\x0e\x70\x52\xc6\xd9\x04\xe7\x50\xfd\x0c\xa7\x4f\x72\x01\xe7\x2e\xaf\x16\x8b\x0a\x45\x3c\x99\x70\x1a\xa1\x2c\x13\x87\xe7\xb7\xb2\x66\xdc\x84\x44\x6e\x7a\x02\x93\xc6\x1f\x53\x1e\x89\x43\x9e\x11\x4b\x7e\xec\x2c\x29\x0f\xc9\x31\x08\x58\x8e\x76\x21\x04\x43\x71\x15\x4d\x74\x14\xaa\x6d\xdd\xa9\x2c\x43\xde\xe1\xc6\x5d\x9b\x59\x77\x38\x75\xe7\x98\x13\x5b\x91\x29\x39\x6c\xa3\x3a\x16\xcf\xdb\xf5\xef\x00\xa5\x84\xb0\xe1\xb1\x05\x9b\x31\x78\xa2\x10\x5b\xb8\x69\xc8\x1d\xc4\xfa\x27\xda\x49\x87\x1e\x90\x31\x2c\x53\x24\xe4\x61\x88\x47\x78\x7b\x94\x08\x63\x2e\x60\xa7\xe5\xc5\x67\x8b\x09\xce\x07\x99\xec\x59\x29\x15\xf6\xe2\x94\xd1\xff\x81\x15\x86\xe3\x86\xfa\x52\x08\xcb\xbd\xc1\x84\x55\x04\x87\xc5\x4a\xed\xc9\xf2\x54\x1a\xac\x71\x66\xb0\xd3\xbd\xf5\x01\x4f\x0d\xc0\x31\x18\x95\x78\xf7\xf4\xf8\xae\x88\x5a\xe2\xd5\x38\xe8\x36\x02\x17\x31\x86\xc2\x3e\xac\x0f\x79\xc6\xaf\xe0\x85\x48\xe7\x64\x36\xd2\x90\xff\xd8\xdd\x01\x41\xa1\xa5\xdb\x90\x7b\xcd\x85\x73\x0a\xbf\x5e\x98\x9c\x88\xea\x98\x5a\xf5\x1b\xf6\xd9\xf0\x43\x08\xed\xec\xbb\x99\x96\x6d\x4d\xcc\x71\x74\xac\x89\x35\x36\xb5\xa2\x57\xc1\xe9\xd0\x45\xf0\x4b\xa4\x3e\xe9\xb3\xb8\x22\x3d\x0c\x5c\x06\xc1\x8b\xf0\xa3\x50\xd9\x28\xcf\xed\x96\xe7\xd3\x35\xf9\xb5\x4b\x62\x05\x18\xda\x5b\xfa\x8f\xcd\x58\xe0\x84\x35\x1c\xc4\xf8\xc3\xbc\x4e\xa4\x2d\x78\xbd\xce\x36\x48\x3e\x24\x88\xfd\x31\x0d\x23\x5a\xcd\x0e\x5a\x89\x66\xa3\xc9\xf2\x8c\x05\xc1\x23\x56\xa6\x87\xa8\xb6\x84\x2b\x49\x3e\x94\xc4\x7e\xfc\x32\xaa\x8e\xa8\x2a\x2f\x3d\x0e\x81\x27\x0e\x24\x39\x62\x57\x67\xd2\x64\x38\xbf\x83\xdb\xe2\xdf\x0c\xa4\x5f\x30\x63\x5c\x9f\x9e\x6d\x55\xe8\x88\x06\x6d\x11\x1f\xc1\x15\xf6\x55\xe3\x28\x16\x4d\x4c\x52\x40\x3e\x68\x07\xe4\xc1\x68\x5f\x3f\x53\xe4\x61\xaf\x3a\xac\x09\x89\xda\x82\x11\xf3\xfd\x45\xad\x26\x79\x38\xe3\x71\xe0\x48\x2c\x0d\xcc\x7e\x4a\x1d\x63\xe5\xbf\x99\x26\x2c\x30\x47\x8d\xb1\xf7\xea\x2f\xb8\x2d\x3f\xc0\x3a\x69\x99\x3a\x2a\x77\x9e\xf4\x40\x17\x8d\x9c\x3f\x00\x92\x7b\x07\xb1\x48\x8a\x85\xdf\xf9\xa3\x29\x75\xf6\xf0\xc5\x4a\x93\x33\xc5\x0d\xbf\xb9\x0b\x13\xaa\xcc\x6d\xf8\x9d\x39\xeb\x78\x67\x96\x6f\x72\x43\x09\x7a\x22\x88\x9e\x5e\x86\xf2\xaa\xf0\x92\x7d\xf1\xa7\xfd\x2a\x7a\xb9\x5f\xbe\x3f\xbc\xec\xd3\xa0\xe1\xe0\x9f\x3c\x64\xc4\x51\x15\x58\x9d\xd3\xf3\xec\xa8\x7f\x3f\xf5\xa8\x55\x95\x3b\xdb\xc4\xab\xde\x1a\x6c\xdb\x16\xe8\x5f\x58\x57\x0a\xa8\xac\xe2\xb0\x7b\xc8\x17\xc1\x53\x14\x69\xe9\xca\xe2\x63\x5f\x9c\x0e\x5c\x34\x4d\xb8\x1c\x49\xf7\xaa\x0c\x66\x6a\x78\x74\xd7\x34\x95\x95\x10\xfd\xca\xb6\x8c\x00\x32\xd4\x2c\x21\xf3\x2d\x0a\xbc\xcc\x41\x49\xcc\x63\xd8\xac\x25\xe1\xa8\xe7\xbe\xa4\xb7\x17\xa6\x56\xea\xb2\x32\xf4\x29\xf6\xcf\x3e\xfd\xe3\x9f\x5c\x15\x09\xb6\xf8\xbe\x61\xbf\x7c\x0f\x58\xc1\x2a\xda\xaa\x69\xf6\xda\x38\x8b\x65\x70\x4b\x10\xe7\x22\x06\xb2\xe9\x94\x79\x01\xac\x13\x0c\xb4\x94\x62\x79\xc8\xcd\xd0\x6a\xd8\x68\xf8\x4f\xeb\x68\x8b\xe4\x2f\xef\x44\x2c\xc8\x45\x2f\xed\xa7\x41\xfd\xab\x2f\xc8\x51\xf1\x82\x82\xe5\x1c\xcb\xb4\xf2\x2a\x3a\xee\x41\x83\xc5\x03\x89\xd9\xfe\x78\xff\x13\x30\x76\xa9\xd6\x81\x97\x1b\x49\xa8\x47\x5d\x83\xd9\x72\x48\xbf\x11\x51\xc1\x18\x3a\xa0\xcd\xc3\x72\xaa\x52\x09\x4f\x9e\x48\x75\xb8\xa2\xce\x27\xe7\xd6\x12\xfa\xc3\xdd\x84\xc4\x69\x67\x39\x0c\x5d\x70\x94\x66\x47\xe2\x65\x89\x12\x99\x67\xfe\x0e\x75\x3f\xcb\x60\xd6\xae\x7b\xd9\xa8\x9a\xf7\x90\x4b\x2e\xc0\xd9\xd3\x14\x1b\xfa\x65\x89\x62\xe0\x3c\xeb\x78\x6b\x06\x45\x98\xfe\x2b\x12\xd7\x40\x48\xa3\x34\xcd\x9f\x0d\x2b\x48\x90\x2c\x45\xf7\xc4\x70\x18\x54\xcc\x4f\xbf\x97\xeb\x25\xfb\xa0\x7a\x5e\x52\xde\x70\xf0\xa8\x54\xee\x0a\xf7\x2a\xbe\x7c\x35\xfa\xad\xad\xaa\x9e\xc6\x88\xdc\x17\xf9\xad\xc2\x13\x60\x6a\xd1\x4a\xae\x68\x9b\x93\x12\x2f\x95\xd9\x5d\x4b\x92\x3e\x84\x52\xde\x34\x75\x43\xb8\x99\x8a\xd7\xaa\xa8\x95\xfa\x4f\xbf\x0f\xbf\x77\xee\x64\xb8\x78\x04\x8c\xda\x6f\xf0\x6f\x28\xa7\x0c\xea\xd7\x12\x5a\xe0\xdc\x24\xa0\xc0\x48\x8b\x6c\x8c\xd6\x5f\x01\x6b\x55\xf7\x41\xef\x1f\xf7\x9d\x53\x5f\x6d\x15\xe1\x3f\xd5\x34\xfc\x89\xf8\xd9\xfb\xe4\xa3\x8f\xc9\x63\x3e\xee\x1a\xe3\xac\xda\xba\xfd\x09\x84\x21\xad\x8c\x8e\xa3\x62\x75\xda\x8d\x2f\x86\xe3\x1e\x59\x2e\x93\x94\x87\xb2\x78\x0b\xdd\xd4\x52\x5b\x60\x1a\xfa\x79\xcd\xc7\x59\xef\x2d\xd8\x45\x6e\x55\xc7\xb6\xb7\xb7\x5e\x76\xc9\xaf\x43\x03\x74\x7b\xbf\xe3\x16\x05\x33\xc9\x1f\x9e\xcc\xb5\x5d\x32\x0f\x57\x38\xd2\x8b\xdb\x48\x65\x8c\xd4\xd9\xf3\xed\x66\xcb\xaa\x7d\xeb\x1a\x63\xf3\xa4\xa9\xf9\x06\x9b\x4a\xc2\x9d\x95\xf9\xd5\xb3\x95\x1f\x2c\x70\x65\x11\x39\x17\x82\xc4\x1e\xd6\xc6\x7f\x82\x47\xbc\x3f\x96\x6b\xe2\x9b\x6d\xcb\xa7\xc6\xe8\x83\x4b\x5a\xfe\xc0\x88\xf1\x8d\xfb\x0f\xb7\x94\x24\x3a\x56\x01\x69\x90\x7e\x6f\x57\x73\x94\x9a\x64\xca\x72\xb3\x53\x9b\xdc\x37\x90\x55\xee\xd9\xd4\x36\xc8\x75\x25\x9b\xca\x6b\x60\xff\x21\x55\x41\x63\xb6\x83\x9c\x01\xa6\xc1\xe0\x3e\x0a\x63\x7b\x3d\xe5\x43\x53\x3a\x7d\x2e\x7c\x10\x26\x52\xdd\x29\xd0\x09\xef\xdd\x1c\xf1\x70\x01\xa5\xda\x4f\x0a\x83\xdd\x08\x1c\xc0\xb5\xac\x8a\x66\xe4\x6b\xec\xe3\xf7\x44\x11\x6c\x78\xec\x79\x05\x0c\x8f\x80\x77\x62\xb4\x8d\x57\x59\xbe\x80\x80\x90\xb2\xe5\x83\xd0\xcd\x08\x2a\x9c\x72\x6f\xb6\xa1\x89\x8d\x37\x11\x48\x46\x7f\x25\xfd\x0b\xe9\xf1\xcc\x29\x29\x3e\xd0\x4a\x16\x7e\xc1\xe2\x1c\xed\x5d\x02\x5c\x46\xf6\x64\x5c\xbe\xb0\x71\xcd\xbb\xff\xd9\xa0\x31\x86\x74\x99\x75\x08\xe6\xf1\x11\xac\xf9\xbc\x35\x7a\x78\x1e\xaa\x44\x6d\x91\x17\x9e\x40\x1e\x32\x47\xe4\xb7\x56\xa2\xbe\x6b\x47\x81\x0f\x19\xbc\xcf\xe5\x73\x51\x03\x54\xfe\x87\x3d\x8c\x1a\x1f\x0d\xeb\x1c\x97\xf5\x47\x78\x22\x70\xa6\xcf\x8c\x39\xb7\xe9\xc5\x02\x09\xf9\x3c\x05\x9f\xe1\xf2\xfe\x14\xb5\xd7\xd9\x54\xf8\xa6\xac\xed\x01\x1c\x2a\xa7\x6a\xda\xdf\xa6\xe4\xb9\x70\xf8\xd3\x86\x36\x04\xff\xdd\x4b\xee\x93\x35\x37\xfc\x77\x55\x68\xdb\x0b\xdb\xcb\xd3\x66\x09\x8a\xe6\x70\x70\x9f\x43\x7c\xab\x1c\x3b\xe1\x55\xe3\x0f\xcb\x33\x62\x5c\x97\xbe\x90\x9b\x89\xf8\xb9\xac\x15\x77\xb4\x21\x67\xd9\x03\x2f\x2e\xb6\xec\x63\xa2\x04\xd2\x75\x20\xc3\xb7\x6d\x19\x6c\x94\xa0\x9f\x16\xf3\xc9\x96\x00\x2e\x20\x02\x7b\xb0\x32\xff\xd9\xde\x90\xa3\x69\xbb\x83\x78\x9b\x76\x52\xb1\x15\xea\xed\x94\xd7\x63\x44\xfa\x10\x92\xfe\xc9\xc4\xfb\x96\x62\x0f\x39\x91\x44\x1c\x3d\xf3\x9e\x91\x25\xd9\x09\xc0\xb3\xb5\x86\x39\x7d\x6b\x6f\xad\xc5\x79\x5b\x09\x70\x04\x9f\xa0\xea\x4f\xb5\x3b\x49\x90\x35\x88\x79\x2c\xf0\xc3\x3c\x14\x4c\x02\xc9\x92\x52\xb8\xec\x00\x38\xcd\xb2\x0e\x8c\xe4\xd6\x23\x6c\x05\xeb\xff\x47\xd6\x9b\xa5\x3b\xcb\xf3\x4c\xa3\x73\xc9\xf1\x3f\x29\x03\x0e\xb0\x68\xcc\x0b\x38\x79\x92\xd1\x6f\x95\xaa\xe4\xdc\xdf\xb5\x8f\xf0\x4a\xb7\xd2\x80\x6d\x95\xaa\xf9\x2f\x6e\xb1\xaa\x9c\x8e\xff\x30\x14\x8e\xcd\xbf\x1c\x09\x61\x1a\xcc\x01\xa4\x44\x2d\x64\x1d\x84\xc9\xb0\xc1\xd9\x25\x30\x22\xd5\xdf\x77\xfa\x0a\x09\x0a\x42\x98\xed\xfa\x03\x83\x5e\xa5\x31\xa2\x12\xad\x5b\x45\x23\xee\x20\x8e\x75\xc3\x97\x2e\xf3\xbd\xa0\xe6\x73\x0a\x01\xb4\xe9\xa7\x60\xb2\x8e\xed\x49\xb7\xd0\x59\x69\xc1\x06\x69\x90\x5d\x0f\x31\xf2\xa3\xfb\x03\x77\x69\x95\x76\x68\xf1\xd3\x3e\x31\x23\x39\xdd\xbb\x5f\x0f\xb6\x3f\xf4\xcf\xfb\xa0\x6e\xc8\x0f\x9d\xc8\xaa\x88\x85\x21\x15\xd5\xa1\x7e\x0c\xd6\x21\x89\x39\xc0\x44\xe6\x7f\xb2\xa0\x52\x97\xb8\xf9\xf8\x7e\x70\x1b\x3e\xd7\x97\xf3\xd6\xa7\x68\x3e\x79\x73\xff\xf4\xae\xbb\x28\xa7\xc1\x16\x79\x2b\x34\xec\x05\x5f\x4a\xba\x0a\xfb\x6e\x9a\xbe\x82\xf3\x40\x86\xdd\x2b\xbd\x28\xef\x4e\x57\x17\x8b\xf2\x2b\xed\x30\xe6\x10\x4c\x3c\xb0\x26\xae\xa3\x2c\x27\xdd\x7a\xb8\x61\x59\x77\xf5\xb3\xc0\xde\xef\x38\xc8\x1b\xa7\x52\x0a\x77\xcb\x1e\xce\x63\xf9\x7e\x18\x31\x27\xb9\x5b\xe6\xb3\xa1\x77\xb3\xf2\x42\x89\x07\x9c\xac\xef\xa4\x6e\x2c\xa2\xfc\xf8\x72\x8a\x22\x42\x93\xc0\xb1\xd1\xb7\xac\xd5\xaf\x7a\xf7\x00\x62\x39\xde\x9b\xa9\x05\xbe\xc3\xd6\xdb\xc7\xf7\x29\x9f\x40\x18\xf9\x3c\xc4\x34\x75\x19\x0e\xf7\xdd\xf0\xa5\xd3\x80\xdc\x52\xd0\xde\x7d\xe0\xdb\x63\xa1\xd0\x63\xbc\x36\x3a\xdb\x18\x80\xfa\xa8\x30\x86\xa3\x91\x4d\x25\x1b\x2a\xff\xc7\xe4\x87\x5d\x6c\xc0\xa7\xfe\xef\xe7\xf0\x20\xb4\xf5\x91\x8b\x97\x8d\x08\x34\xcb\x9f\x47\x26\x54\x61\xd4\xd3\xb4\xe3\x53\x18\xfd\x30\x68\xee\xca\x49\x0b\x1e\x29\xa7\x3f\xa7\x64\x6d\xc8\xd3\xfa\x25\x76\x7c\x29\x62\x5e\xdb\x53\xe0\xca\x34\xcc\x40\xd4\x7c\x83\x9c\x69\x94\x81\x7d\x37\xb7\xd0\x11\x78\x79\x7e\x3a\x29\x6d\xc1\x72\x98\x83\xe6\x80\x82\x2d\xa8\x08\xe0\x38\x04\x16\x73\x16\x5b\x30\x44\x14\x3d\x7f\x3d\xb4\xb3\x0c\x84\x13\xdd\xb3\xda\x8f\xc3\x2a\x63\x9f\xc0\xab\xfb\x5e\xb2\xd7\x33\xcf\x61\xd1\xac\xfa\xe8\xcc\x0a\x94\xf8\x70\xe7\xee\x50\xb5\xcd\xbc\x2d\x2a\xf4\x7f\xd5\x5f\xcc\xb7\x92\x0f\xa7\x3c\x44\x3e\xf3\xe1\xbb\xc0\x07\x71\xec\x33\xb2\x21\x62\xc3\x9d\x43\x2a\x61\x85\xa2\x6d\xa8\xb8\xb5\x76\x5d\x89\x53\x10\x3e\xc1\x8e\xdd\xcb\x0f\xa5\x56\x38\x62\x52\xe3\x71\x4f\x12\xa6\xc3\x55\x6f\x16\xaf\x00\xf3\x6e\xf8\x9a\x39\x05\x61\xe7\x80\xd6\xcb\x1e\x0d\xe5\xfc\x72\x1f\x12\x3d\xc2\x50\x02\xa3\xc0\xc7\x00\xf7\x50\xff\x43\xd7\xc4\x87\x6f\xa1\x1b\x41\x35\x5e\xc3\x65\x2c\x0e\x81\xff\x08\x3f\xa2\x28\x70\x2f\x6c\x97\xc9\x1a\x69\x4c\xc2\x76\xb6\x4c\x2d\x4f\x96\xa3\xe2\x29\xbd\xd0\xe1\x2d\x3a\x3e\xcd\xb9\x0a\x3e\xb0\x2a\x80\xb7\x78\xe8\xbe\xff\xab\x7e\x88\x06\x2a\x36\xe8\xa5\x05\x35\xaa\xe6\x80\xf2\xa8\x92\x3d\xe2\x22\xa4\xb3\x59\x06\x6d\x47\x17\x5b\x71\x90\x5e\xe7\x06\x7f\xd7\x2f\x01\xee\xaa\x40\x27\xc5\x2c\x93\xb8\x48\xf6\x84\xbd\xb5\xa4\xbd\xba\x2b\xe9\xf9\xf6\x12\x8d\x47\xd7\xda\xab\x2b\x0c\x26\x1d\x2f\xb3\xb5\x10\x27\x5e\x35\xf1\xac\xb3\x58\x69\xee\xc1\x4b\x98\x59\xb6\x59\xab\x67\x61\x3e\x88\x46\xc7\xa6\x76\x0d\x49\xfd\xb3\xc8\x66\x74\x05\xbc\x42\xc0\x65\x61\x2c\xe6\xb2\x57\xe5\x3f\xe9\x22\x07\x11\x38\x16\x6d\xdb\x77\xf7\x12\x56\xda\x42\xc8\x1d\xcf\x32\xff\x92\x6b\x6c\xdc\x8c\x54\x96\xdc\x3c\x80\x8e\xd8\x90\x6f\x81\x45\xf3\xfa\x5c\xb4\x77\xa7\x93\x93\x93\x15\x14\xa7\xbc\xbb\xda\x81\xfa\xa5\x8d\xb6\x41\x6a\x07\xfe\xa1\x25\x44\x27\x21\x5b\x71\x98\x95\xa4\x2e\xbd\x6d\xc2\x47\xf6\x3a\x27\x9a\x57\x4e\xb3\x90\x6c\x86\xe4\x4f\x2d\x69\x71\xca\x32\x8f\xb6\x19\xe6\xdb\x76\xda\x7b\x78\x57\xda\xa6\x5b\xf3\x85\x47\x4a\xf9\x31\x94\x4b\xb2\xf2\x1c\x2b\xb1\x1b\x19\x56\xe7\x9d\x7e\x89\x67\x73\x9c\x2e\x59\x99\xb8\xe4\xad\xfa\x86\xdb\xdd\x6f\x39\x52\x14\xc4\x88\x22\x20\xa0\xe5\x9e\x3f\xc4\xf8\x4f\x00\x85\xad\x57\xdf\xe0\xa9\xd2\xfc\x3a\xad\xcd\xe4\x47\xbe\xd9\x29\x9f\xfa\xa6\x9f\x55\x0b\x10\xa2\x2e\xb8\x21\x3e\xa9\x14\x7e\xce\x25\xec\x53\x9f\x6a\x83\x3e\x49\x21\xdf\xc2\x28\xe1\x99\xe5\xa0\xff\x04\x37\xd4\x8f\x9d\x16\x36\xe4\x6b\xfb\x26\xb7\x8a\x0e\x01\x84\xd0\x07\xb0\xde\x26\x2f\x82\xe9\xd9\xa2\x44\x02\x7b\x8e\x90\xe5\x33\x44\xd1\x43\x95\x47\xf2\x10\x26\xec\x03\x88\xc1\xf4\x78\xcc\x6f\x65\x52\xb1\x56\x1d\xca\xe5\x33\x3b\xc7\x91\xff\x39\xcc\xa7\xbc\xb5\x87\xf9\x29\xab\x0b\xdb\x5a\x9c\x0b\xef\xc4\xbe\x5a\x7b\xec\x30\x0e\xda\x23\x0c\x2b\x83\x4f\xa4\x3d\xf1\xa6\x4c\x3a\xec\x98\x1d\xb3\x7f\x38\x17\x63\x8d\x38\x4b\xf6\xc3\x07\x5d\x88\xbd\x9d\xcf\x14\x2e\x60\xaf\xfc\xd1\x31\x18\x18\x95\x5e\xc6\x8e\x58\x6b\x9b\xda\xa6\x8f\x1e\xeb\xf5\x49\xaa\xa6\xbb\x39\x93\x6b\xf1\x12\x52\x5d\x95\x7f\x61\x9b\x62\xca\xef\x4b\xb0\x3a\x40\x58\xe6\xb6\x19\x00\xfd\x1e\xbc\x0d\x6e\x5a\x01\xb6\xfb\xd1\x49\x17\x1d\xb3\x2e\xfa\x19\xd6\x49\x3e\x9a\x6a\x38\x13\xf6\x48\x7e\xf9\x6d\x93\x3d\x28\x97\x9f\x1c\x05\x38\x36\xa6\xdc\xac\x7b\x07\xc3\xf7\xd5\xdc\xcf\x71\x93\xbc\x1d\x24\xdc\x01\x23\x9f\x15\x63\xee\x61\x1c\x1f\x29\xa9\x7a\x99\x70\x75\x9e\x41\x18\x2e\x91\x57\x20\xe0\xb6\x97\xca\x1a\x69\xbb\x0b\xd5\x39\x31\xf6\x53\xc2\xd4\xae\xbc\xb9\xff\xa5\xe7\x91\x00\xe5\xb2\xcb\x5c\x72\x8d\xc4\x4c\xce\xc2\xdd\xda\x78\xb1\xb8\x8e\xe4\x24\x29\x69\x2f\x93\x24\x7c\x40\x05\x63\x17\xf6\x66\x5d\x22\x5e\xd7\xb9\x0f\x39\xd1\xef\x73\x4f\x54\xf6\xa3\x0b\xa1\xa8\xaf\xb5\xab\x59\x36\x93\x11\xfd\xdf\xa5\x9f\x60\x2a\xd5\x4f\xa6\x31\x75\x0a\x57\x49\xd7\x38\x68\x6f\xcc\x9d\x9d\x4d\xb6\xb4\x03\x4e\xc1\x77\x48\x08\x3e\x91\x44\x14\x3e\xec\xfe\x3d\xd9\xb4\x3f\x3b\x71\x28\x59\xa1\xbe\xcb\x5a\x2a\x21\x91\x09\xa7\xc8\x17\x6d\x46\xdf\x26\xbb\x86\x1a\x83\x14\x06\xaf\x9f\x7a\xfb\xc2\xf2\x09\xcb\xc3\xf7\x67\xe4\xbf\x7e\xd7\xd3\x35\x5c\x95\x33\xfb\x7b\xf6\xec\x1a\x42\xd2\x90\x6d\x89\x3a\x6b\xcb\x38\x69\x1f\x13\x04\xb9\x82\xaf\xe7\xeb\xab\x63\xb3\x02\x07\x0d\x2e\x25\x0e\x7d\x0f\xf9\x4e\xff\x05\x27\xf7\x5f\x7e\xbe\xfd\x25\xe7\xef\x71\x94\x63\x85\x82\xc7\x1e\xdc\xac\x13\x8e\xb2\x3a\x59\xd3\x00\x33\xc7\x9c\xd9\x01\x8b\x91\x4f\xe9\x39\x1c\x3e\x61\xc1\x94\x77\x6f\xd1\xf2\xa2\xab\xc2\x38\xea\x4e\xb9\x5f\x75\xf6\xe9\x5d\x37\xed\xa8\x49\x2f\xb8\x4f\x8a\x60\x99\x0e\xea\x83\x00\x6e\x6f\x39\x0e\xdf\xf3\x11\x7e\x97\x6b\x23\xea\xd2\xcd\xc9\xc7\x68\x9b\x09\x77\xcf\x77\x10\x7e\xee\xcc\xa8\xcb\xdb\x49\xfd\x3d\x87\xae\x8d\x79\x00\x32\x5f\xb4\xf5\x7c\xff\xe8\xbb\x6f\x24\x94\x11\xde\xae\x8d\x5b\x51\xb5\x0b\x0f\xff\x4a\x7b\x9b\x1d\x8f\xe9\xa3\x76\x1d\xb6\xf4\x5b\x90\x7e\x5f\xaa\x35\xae\x3b\x24\xd5\xbe\x23\x6d\x00\xf6\x21\x78\xfa\x08\x77\x89\xeb\x20\x7e\x03\x76\x15\xb9\xc1\xfe\x15\x62\x1b\xaf\x6c\x1d\x1b\x32\xe7\xcb\x4e\x85\x21\x9e\xb5\x0a\x21\xbb\xb4\x88\x13\x69\xf7\xd2\xdd\xce\x84\x59\x06\x04\x6e\x40\xe5\x83\x71\x6f\xbd\x2b\xfb\x63\x6c\x9b\xff\x88\x41\x9d\x90\x6a\x1d\x9b\x70\xa7\x83\xb0\x18\x98\x3d\x2f\xcb\x36\xfd\x47\x0b\x45\x3d\xb1\xe1\xe4\x93\x52\xe0\x58\x57\x13\xa7\x45\x68\xee\x95\x37\x39\x0b\x6c\x9b\x82\x53\x15\xac\x71\xe5\xf8\xf7\x40\x08\xb8\x53\xba\xfa\x19\x4a\xfa\x5d\xd0\xbd\xed\x02\x03\xce\x0f\x7f\x85\xe6\x60\xa5\x3f\x1a\x9b\x25\xcf\xa1\x72\xcb\x59\x89\xab\x77\x18\x5a\x21\x71\x75\xe6\xe8\x24\x2f\xf1\x42\x42\x8f\x2c\x3c\xaf\x5f\x10\xdb\x95\x9a\x5c\xff\x92\x50\xfd\x94\xf7\xe6\x59\x23\xa8\x85\xec\x6a\xdf\xf9\x57\x0a\xa3\xdd\x83\x57\x78\x7e\xe9\xa2\x0b\x30\x33\x91\xef\xcc\xff\xc1\x6d\xd7\x47\x11\xe7\x9a\x77\xd6\x13\xfb\xed\xd9\xed\xbc\x2d\xbe\x44\x48\xe5\x34\x48\xcd\x11\x61\x63\xa5\x11\x9e\x59\xe1\xd6\x7c\x7c\x04\xbc\x1c\xa7\xac\xb3\xd0\x6e\x65\x0f\x00\xa3\x08\xb2\x63\x59\x62\x0b\x02\xbf\xe7\x83\x79\xe8\xf0\xd4\x4a\xea\x11\x7c\xc5\xa7\x19\x4e\x12\x79\x8e\xf4\x33\x3e\x98\x05\xbc\x1c\x49\xf5\xb6\x9d\x44\x6e\xac\x75\x76\x2a\xa8\xa8\x96\xf3\x27\x20\xe5\x8b\x26\x59\x36\xd5\xb7\x82\xc5\xdd\xd9\x3f\x3e\x6a\x6b\xef\x9e\xde\x60\x5c\x79\x7d\x20\x9a\xed\x56\x37\x06\xac\x96\xf3\x98\x58\x12\xb8\xca\x3a\x52\xbf\xb7\xf9\x93\x62\x63\xb9\xe1\x6c\xa6\x99\x80\x5b\xd2\x06\xce\x8f\xb0\x69\x92\x52\xe4\xf7\xb3\x29\x36\x0b\xd8\x7e\x4e\xf2\x02\xdd\x23\x78\xc6\xca\x8a\x39\xd2\x65\xd6\xbc\x36\x07\x51\xb7\xd9\x3c\x03\xfc\xcf\xf9\x15\x05\xc5\x1e\x49\x33\xf7\x1d\x22\xb8\xe6\x5c\x20\xa5\x07\xea\x01\xf9\x37\x42\xcc\xa9\xf2\x29\xa1\x56\x92\x52\xcf\x16\xab\x70\x6e\xde\x1a\x53\x27\x31\x5c\x7b\xfd\xec\xe4\x21\x7f\xd8\xa5\x74\xda\x0c\xcb\x87\x65\x11\x0b\x46\x47\xdb\xc3\x7b\x5d\x30\xaf\xc1\x8c\x06\xf8\x0a\xa3\x95\x87\xa3\xfd\x22\xc6\x8c\x51\x65\xe4\x81\x39\x38\x20\x46\xb3\x73\xb3\x7a\xd9\x23\x02\x8c\x6c\xd5\xbd\xf6\xe0\x72\x03\xdf\xc1\x3d\x58\x31\xb6\x3e\x3c\x89\x23\xc0\x64\x54\x7b\x3a\x30\x68\x95\x39\x8f\xbd\x98\x5a\x23\x56\xa9\xa4\x60\x53\x0f\x36\x73\xe5\xca\xd7\xb0\x9d\xc2\x4e\xb9\x5e\xc2\x1e\xa0\xe7\x48\xba\xea\xe5\xe3\xaf\xb3\x9c\x64\x23\x2d\xa7\x0e\x3a\xed\x97\x52\x9d\x6b\x66\x45\x0c\x69\x20\x70\x4c\x50\xd9\xb2\x05\x3b\x3b\x3e\xeb\x92\xc9\xf9\x59\x52\x44\x20\x2c\x11\x3d\xb9\x24\x01\x97\x7f\xde\x93\x54\xcc\x4e\xab\xbd\x6d\xb5\x67\x51\x62\xe5\xc9\x4b\xbf\xec\xc4\x96\x8e\x1d\xd4\x69\xb8\x44\xba\xde\x20\x12\xe6\xf0\xb9\xa7\x51\x41\x3c\x3b\xf9\xd3\xb6\xff\x61\xf9\x52\x82\xc6\x34\x51\x84\x3c\x15\xba\xed\x4f\x0e\x76\xad\x9a\x11\x11\x03\x91\x3b\x6d\x44\xa6\xbc\x89\x5a\xb3\x86\x13\xd8\x8e\x85\xa9\x39\xd6\xb7\xde\x41\x56\x10\xe4\x94\xec\x6e\x19\x9a\x56\x76\x15\x2e\x9c\x64\xa1\xf9\x8b\x34\x1f\x09\xef\x30\x83\x5f\xc1\xef\x8e\x44\xb0\x09\xb6\xb6\x61\xa6\xea\xcb\xf5\x58\xef\xa9\x45\xe2\xd7\xb5\x3b\x83\x70\x32\x0a\xdc\xa0\x2b\x2a\x4d\xc0\x4e\x36\x5d\x50\xcb\xda\x2e\xc1\xb1\x82\x30\x39\x1c\xcf\xc8\x06\x64\xcd\x88\xbe\x44\x94\xb5\x63\x91\xb3\xcd\x38\xdb\xd9\x91\x1e\xcd\xc5\x41\xf1\xfa\xab\xba\x17\x88\x34\xf1\xb5\x90\x85\xd8\x83\xb2\x41\xde\x09\x22\xa0\x3a\x16\xf4\x7a\xf8\x75\x23\x54\x1e\x55\x75\x78\x40\xe0\xf1\xb6\x80\xad\x05\x4a\xe4\xff\x4f\x0d\xed\xe7\x3f\xe2\x01\x28\x06\xc3\x3e\x35\xd4\x36\xcf\xf6\x51\x9f\xaa\x80\x9f\xc0\xe5\x6f\x95\x5b\xf6\xe6\xed\xe4\x73\xe8\x22\x8b\x00\x9f\x2f\x6f\x8f\xd0\x8b\xd2\xdd\xe7\xa2\xc0\x52\x25\x96\xae\x9b\x60\xe4\x50\x9d\x00\xed\x95\x4b\xf5\x95\xc3\x7e\x61\xd5\x0e\x43\x79\xb3\xcb\x10\x05\xd8\x3f\x61\xb3\xc3\xec\xde\x34\x3e\x7a\x06\xaa\x0d\x75\xb0\xce\x0f\x7b\xe7\x3c\xed\x59\x42\xb1\x34\x12\x29\x12\xfd\x85\x93\x09\xad\x18\xee\xac\xb9\xfa\x6c\x0b\x25\xef\x6e\x4e\x07\x03\x08\xfb\x72\x75\x85\x16\x81\x44\xcd\x21\xf1\x7d\x25\x2d\x1a\x43\x3a\x43\x79\xb8\x6a\x13\xe5\x55\x18\x2b\x2d\xda\xf1\x80\x23\xef\x75\x54\xb5\x0b\xce\x5f\xa5\xa7\xfb\x8e\x8b\xd6\x55\xbc\x9c\x11\x38\xec\x49\xe4\xe1\x25\x51\x69\x3a\x0d\xf3\x4b\x16\x5c\x9b\xf3\xf1\xfb\xf5\x13\x9d\x06\xc5\x9a\xf5\x39\xde\x88\x0b\x13\x67\xc9\x0f\xe9\xd7\xe5\x48\x0d\x49\x31\xb6\x43\x8d\xbc\xe2\xf0\xc2\xb1\x65\xea\x90\xea\x70\x15\x38\xd5\xd5\xf9\x3e\xc5\x23\x1a\x68\x0f\xdb\xad\x9c\x3d\x3b\x99\x61\x80\x73\x1e\xc5\x92\xf7\x8f\x83\x77\x5e\x14\x62\x54\x4a\x10\xc4\xc5\x90\xb5\x12\xea\xc7\x3f\x3f\xa1\x21\xe6\xbd\x60\xd9\x6c\x1a\x0d\x72\xb2\x88\x67\xda\xb2\xdf\xc8\xeb\x9f\xa8\xac\x7e\x2e\x0b\x1d\xdc\x25\xfd\xe8\x62\xfb\x87\x97\x59\x55\xfe\x5b\x5e\x71\x45\xf5\x35\x7b\x9d\xcd\xf2\x2b\xaf\xca\xe8\xec\x24\xc1\x75\xa3\x33\x02\x1e\x36\x6c\xbc\xf6\x95\x65\x2f\xce\x88\xb2\x89\x05\xcf\xb5\xb2\x93\x6f\x73\x87\x28\x33\xd6\x67\x39\x28\x58\x9e\x24\x61\x05\xdc\x35\x45\xe1\x76\xb2\x9b\x22\x6f\x8f\x54\xff\x23\x0a\x02\x9d\x20\x7f\xbc\x24\xde\x51\xa1\xc1\x76\x02\xda\x4a\xe6\xb8\x4d\x3d\x07\x67\x75\x80\x28\x44\x31\x51\x92\xd1\x13\xcd\xe5\x2f\xfe\x54\x7e\x1d\x29\x84\x9e\xa9\x1b\xd0\x5f\xc5\xf3\xbe\xa2\x95\x7c\x23\x38\xf8\xeb\xb8\xde\xdb\x47\x7f\x73\x9f\xd9\xd5\x58\xfc\x27\xf8\x04\xf3\xec\x0d\xc9\xae\xbc\x32\x6c\x57\xd8\xdc\xea\xdf\x10\xf6\x68\x20\x03\x0e\xab\xce\xc2\x8a\x23\xd4\xdc\x1e\xba\x24\xee\xbc\x0d\xc3\xec\x36\x47\xe0\x21\x7e\x52\xc5\x9a\xbe\x73\x0b\xec\x79\x4b\xd2\x6d\xe5\x59\x78\xac\x59\xd9\x66\x67\x17\x26\xf8\xd7\x29\xdf\xd6\x17\x34\x01\x5e\x8a\x15\xbd\x15\x08\x44\x75\x15\xbd\x50\x5a\x53\xdb\xec\x74\xfc\x9e\x5c\xab\xd7\x1c\x62\x2b\xe4\x3f\x4a\x3a\xb9\xc7\x6e\x19\x32\xca\x7f\x54\x94\x36\x78\xb1\xf7\xe7\x7f\xa0\xd3\xac\x3f\x92\x15\xf7\x9f\x9f\xe9\x6e\x2f\x74\xaa\x5e\xbc\xa2\xec\x3e\xf2\x97\x70\x3d\x71\x20\xac\xd3\x26\x26\xed\x83\xef\xf2\xde\x9b\xe2\x52\x71\x55\x50\x26\xdb\x47\xf1\xd3\xcf\x4b\x3a\x9e\xf0\xb0\x71\x63\x94\x54\x8a\x4e\x1f\x4a\x3a\x36\x67\x4e\x7a\xe6\xbe\x4b\x47\xa6\xf6\xf5\x9e\xa5\xf6\xb9\x60\x39\xc4\x5a\xfc\x12\x13\xc0\x8a\x38\x15\x0d\xb7\x3a\xa4\x97\x67\x63\xb3\xb7\xd2\x74\xe9\xd0\xe8\x04\x19\x6a\xde\xa3\x93\x76\x15\xc2\x64\xb6\xb1\x66\x12\x14\x24\x68\x0f\xef\xab\xb0\xe8\x00\x13\xd8\x9f\x6e\x5b\x83\x44\x62\xd2\x14\x14\xa1\x6b\x2a\x6f\x15\x99\x53\xd6\xa3\x72\x64\x75\x5c\xf4\xaa\x45\x80\x94\x5c\x81\x5b\x7c\xab\x73\xf5\xef\x89\x10\x39\x43\xb2\x95\x91\x1d\xb9\x44\x50\x81\xea\x8a\xbb\x40\x45\xa7\x7b\x6f\x0d\x99\x02\xa9\xfb\x52\x13\x83\x07\x35\x37\x87\x5f\xee\x34\xaf\x14\xce\x21\xa8\x8b\x54\xff\x28\x89\xdb\x4a\x22\xef\x82\x7c\xe2\x72\x82\x0b\xb0\xf7\x4c\xb8\xb3\x38\x29\x27\xd1\x52\x8e\x37\xef\xbb\x5d\x26\x72\xcb\xe3\x6d\x97\x0d\xf0\x47\xa5\x4e\x25\x6a\x88\x85\x58\xb5\x4f\x13\xd7\xda\xf8\xdf\x3f\x3a\x9d\xcb\x1e\x4f\xcf\xda\xe7\x79\x73\xc7\x65\xd7\x00\xbd\x90\xce\x94\x88\xd4\x82\x2f\x85\x54\x2b\xaf\x64\xd0\x31\xf2\x8a\xa8\xfe\x32\x51\x0f\x04\xdd\xed\x7d\x52\x53\x26\x5c\x0d\x50\x2a\x85\xbb\xdf\xd1\x64\x53\x47\xa1\x1c\xb5\xa1\x58\x68\xdc\xab\xec\x82\x87\xda\xaf\x19\x76\xcc\x0a\x77\x3e\xb0\xec\xd2\xce\xc5\xd5\x08\xfe\xd8\xbc\xa7\xe7\x2a\xcf\x91\x95\xfe\x91\x18\xc8\x8e\x24\x49\x92\x6c\x03\xee\x91\x61\x3c\xc7\xc2\xcb\x63\xb9\xc3\x61\xa4\x5c\x61\x5e\x54\xce\x6f\x46\x03\x9d\x1b\xf4\x66\x74\xec\x6f\x00\x5e\x81\xf4\x9d\xf3\xb0\x5e\xee\x36\x19\xd7\xa9\xbc\xce\x33\x42\xa1\x11\x9c\xb5\x84\x8e\x7f\xe7\x7c\xbf\xcf\x5c\x59\xf7\x39\x98\x57\x7b\xae\x08\x45\xf2\x91\xae\xda\x3d\x89\x94\xb6\x7d\xe8\x75\xb8\x55\x5a\x32\x6d\xee\xec\x7e\x8a\x8d\x45\x28\x0e\x80\x25\x82\x24\x63\x38\xf2\xd6\xf9\xab\x6d\x2d\xba\x45\xfe\x5a\xce\xab\x61\x57\x06\xe7\xaa\x6e\x53\xd1\xb7\xc6\x67\xdf\xe6\x85\xf3\xdd\x06\x63\x57\x0e\x82\xd5\x89\xad\x3c\x83\x11\xb6\x1c\x6d\xa1\x3c\x8f\xea\x2b\x85\xca\xf5\x4c\x11\xd5\xd5\x2e\x75\xd4\x7a\xbd\x34\x75\x88\x2d\xcf\x11\x3b\xea\xdb\x3d\x0e\x87\xa2\xb4\x09\x10\x12\xe2\xb5\xac\x50\x60\x00\xf8\x96\xbe\x73\x3a\x59\xd8\x55\x49\x2a\x22\xe8\x1c\xff\xe4\x8a\xaa\x30\xd8\x60\x67\x78\xfe\x63\x19\x66\x07\x89\xe0\x14\x0a\x43\x3d\x66\xdc\x9b\x6a\x38\xfd\xfb\x0e\x13\x57\xa9\xb5\xf2\xdb\x5f\xab\x17\x51\x04\x62\xd7\xe2\xfd\x45\xaf\xb5\xca\x2e\x7a\xd8\x25\x7d\x33\xc2\x48\x22\x62\x62\xa7\x79\x0a\x1c\x84\x59\xc4\x01\xb2\xfc\xaa\xf3\x74\x93\xb7\xb8\xfe\x43\x21\xc0\x52\xdf\x52\x25\xdc\x75\x40\xc3\x9d\x7e\x04\x6e\x91\x73\x4a\x72\x31\x46\x93\x73\x11\x22\xee\x16\xcd\xf2\x6a\x5b\x38\xbd\x59\xc9\x76\xa8\xfd\xe4\x00\xdd\x32\xab\x6c\x3b\xa5\x9b\x84\x64\x36\x85\xaf\x8a\x7d\xe5\x4e\x7f\x41\x33\x49\x35\x1c\x55\xb3\x7f\xf9\x08\x1a\xd8\x19\xdd\x9f\x58\x5e\x66\x49\x47\x27\xf7\xd5\x98\x00\x40\xb2\xb9\x84\xdc\x1b\x3a\xa8\xd8\xef\x37\xf2\x27\x06\x41\x4c\x75\xe6\x74\xd2\xd2\x03\xab\x8f\x6a\xac\x22\x68\x7b\x0a\xb3\x21\x54\x70\xa2\x86\x9d\x2c\x35\x3c\x75\x95\xcd\x2a\xb1\xa9\xa6\xac\x84\xe9\xf0\xd0\x63\x01\x96\x23\xc2\x12\xa5\xdd\x5b\x4a\xdb\x88\x29\x4b\x57\x96\x14\x69\x92\x4e\x6d\xfa\xa7\xaa\xb6\xba\xfe\x29\x61\xcc\x64\x93\x0a\x1b\x4f\x75\x8e\x7a\x6c\x97\x6e\xa2\xee\x3f\x86\x18\x89\x53\xe3\x29\x9b\x95\x33\x54\x24\xce\x0b\x63\xd1\x96\x44\xc2\x1c\x11\xdb\x4c\x4b\xbe\x12\xd0\xd1\x58\x5a\x3f\x2c\x5c\x78\x6d\xe4\x1b\x33\x18\xbb\xc8\xa1\xa5\x74\xf2\x72\xd9\xd5\x9f\x1b\xb1\x33\xba\x38\x18\x64\xe8\x12\x2a\x60\xd8\x49\x91\x47\x96\xc3\xb7\x1b\x96\xd2\xd1\x0c\x0b\xe1\xc0\xa8\xb2\xd6\x4a\xb8\xaa\x7f\x88\x5d\x5c\xb4\xd5\xd6\xc1\xce\x00\x6a\x34\xa2\x2a\x7c\x42\xdc\x13\x66\xd1\xef\x55\xb5\x9d\x26\x27\x9c\x55\x51\xd8\x31\x34\x55\x36\xd0\xe9\x11\x75\x5d\x69\x23\xda\xc1\xec\x73\xbc\x70\x56\x3b\xc1\x06\xb2\xf9\xa3\xff\xd3\x33\x35\x27\xe9\x14\x7a\x97\x27\x5d\xff\x9f\x20\x3c\x68\x34\x9f\x22\x98\x3f\x94\x48\xaf\xec\xb4\x5f\x7c\xf4\xf0\x81\x03\x09\x06\xa8\x8e\xee\x34\xb0\x0c\xdc\xf7\x28\x0d\x97\x30\xa0\x66\xbb\xad\x46\xec\xcf\x50\x3b\xbf\xfe\x87\xf2\x9f\x02\xd5\xf6\x4d\xa8\xe9\x50\x86\x51\xbd\xb6\x4b\x22\xdb\xa1\x39\xa5\x0f\x33\xf0\x2b\x9a\x0d\xda\x4f\xc4\x5c\x8f\xf9\x1f\xdb\xbf\xd9\xf1\x48\xba\xce\xfc\xd4\x1c\x43\xf6\xde\x32\x4a\xc9\x8b\x24\x36\xb7\xd6\xf0\x8c\x61\x52\xd7\x52\xb4\xfa\x32\x25\xc9\x43\x7a\x29\xe3\x63\x1e\xd5\xa8\x1b\x86\xc4\xbd\x5c\xff\x45\xc4\x85\x90\x26\x77\x0f\xa5\x9a\xb9\x76\x1d\x1b\xdd\x36\x5b\x47\x76\x01\x38\x50\x2c\x5e\x91\x58\xcb\xc9\x13\x52\xe8\x39\xe2\x6a\x3f\x3e\x55\xf9\xf3\xdd\xc3\x1a\x4b\x34\x81\xc8\x1e\x34\x5c\xca\x9f\xa5\x5d\x45\x99\x52\x98\xa0\xd4\xc3\x3f\xeb\x0e\x62\xd9\x27\x78\x65\x25\x22\xd7\x6c\x03\x3a\xb2\x01\x98\x90\xa3\x1d\xcd\xb5\x30\xd7\x44\xb4\xa3\xba\x7e\x14\x42\x76\x1f\x76\x9b\x90\x21\xe0\xb5\x9d\x0b\x02\x23\x09\x7f\xc9\xea\xc2\x11\x50\xe9\x20\x1a\x18\xa3\x1b\x37\x45\xe0\x9a\x9c\x4b\x70\x1c\xa5\x68\xf3\x94\x5c\x49\x4d\xd0\xae\xcb\x54\x3b\x75\x44\xa3\x7d\x54\xd2\x10\xa6\x9c\x98\x30\xb4\xa0\x78\x1d\xc9\xc7\x96\xba\xec\x9a\x48\xba\x9f\xd8\xd2\x87\x5b\x84\xbf\x5d\x49\x16\x87\xa5\x15\x95\x9b\x5b\xd3\x44\x85\xa9\x94\xdc\x35\xd2\xf1\xd7\xcc\x32\xad\x9b\xc5\xac\xb4\xc1\xd2\x0a\xc3\x1b\xef\x42\x32\x97\xa8\x23\xa3\x8c\xf4\x44\x68\x1f\xa6\x08\xd8\x17\x75\xcf\x21\xde\x87\x68\x70\xe4\xc8\x85\x88\x65\x9f\xe4\xb3\x6e\x63\xba\xee\x59\x25\xb9\xbe\x33\xad\xb5\xe7\x2b\xda\x7e\x3c\x09\xbb\xc4\xd6\x17\x08\x6c\xe4\x47\x41\x09\x48\xfe\x5d\x6a\x25\x2a\xba\x68\x4a\x90\xab\x5f\x54\xe2\x0f\x6f\x11\x7a\xe9\x78\x51\x06\x97\x04\x83\x00\xd5\xb4\xb9\x15\xa3\x41\x55\x26\xe6\x21\x96\x94\x65\x6d\x92\xc0\xaf\x1c\x2a\xbe\xe9\x5b\x69\xf7\xf1\x4d\xee\xf3\x86\x8f\x81\x28\x15\x99\xe2\x80\x9a\xc1\x34\x3a\x4d\x4e\xb8\x1c\x78\xa9\xbd\x5d\xca\xec\x2a\x95\xb9\xb9\xe9\x58\x79\xa9\x62\x90\xc2\x3c\xd6\x8f\x2e\xdc\x66\x51\x29\x7e\x1e\x06\xe2\x79\xa0\xfb\xa7\x44\xdf\x51\x48\xc2\xab\xd0\xde\xe4\x05\xa3\x24\xaa\x68\x5e\x2d\x22\xec\x25\x0e\x93\x12\x56\xd4\x07\x74\x97\x36\x4a\x54\xaa\xb6\x7f\x6e\xdd\xc8\xde\x5d\x5d\x59\x0b\xd8\x28\x64\x2b\x5a\x43\xd1\x7b\xed\x56\x6a\x5c\xea\x8f\xaf\x87\xc8\x44\xef\x99\xde\xf6\x31\xc8\x6e\xbc\xe7\x9f\x88\x7b\x24\x76\x78\x43\xc1\x38\x71\x90\x25\x7d\xc6\xee\x9c\x3e\xe0\xf9\xed\xba\x18\xc4\xff\x8b\x9b\x47\x8f\x9f\x14\xf6\xd4\x9f\x57\xac\x39\xd0\xc6\xe0\xab\x21\x3b\x0f\x5b\x88\x08\xb3\x43\xe7\xbb\xf9\x3f\x2a\xdd\x0f\xdf\x61\x44\x0b\x9f\x29\x40\x13\xe8\xc0\x1b\x03\x6f\xde\xf5\xed\xca\xdc\x3b\x58\x71\xc7\x1c\x12\x1a\x4f\x98\xf5\x42\x6a\x07\xac\xe5\xcf\x73\x58\x88\x8d\xb8\x3d\xca\x3e\x0f\xb4\xa6\xe2\x7b\x2b\x2c\xd0\x82\x14\x74\xcd\x6a\x1d\xca\x37\x14\x1a\x99\x25\x64\xe0\x4d\x4d\xde\x4c\xc7\x00\x27\xdd\x6a\xc8\x89\x75\x07\x6b\x3f\x8a\xd8\x6d\x83\x91\xd4\x40\x3b\x25\xe9\x07\x29\x7a\x0b\xed\x0c\x04\x8c\x91\x2d\x33\x51\x94\x60\x95\x64\x11\x1b\xcf\x2b\x49\xe9\xc2\x63\xe0\x67\xd0\x09\x29\xbe\x1f\x37\xf1\x07\xcf\x3a\x05\x55\xaf\x7c\x7d\x9b\x73\xa2\x74\x89\x66\x87\xad\xe9\x82\xd9\x4f\x45\x7f\xda\x91\x5f\xe5\x59\xd8\xfe\x08\x19\xee\x39\x2b\xc2\x19\x9d\x34\xaf\xf3\x26\x91\xfa\x00\xad\x88\x74\x97\xc3\x88\xea\x74\xcb\x3b\x1f\xd9\x2c\xee\xef\x8d\xee\x1c\x27\x98\xe9\xbe\x53\xb0\xe2\xe4\x9a\x5b\xa5\x7a\xb8\xed\x96\x55\x84\x7d\xa1\x98\xc8\x0b\x42\x0d\x28\x62\x3d\xce\x30\x87\x3d\x4e\x32\xd3\x8e\x93\xb1\x80\x07\x64\x8a\xfe\x2a\x2b\x63\x1c\x8f\x95\x6c\xbd\x03\x84\xdf\x3b\x7b\x25\x39\xef\xa4\xfe\x80\xc8\x35\x2b\xae\x0f\x8a\x43\x7f\x1e\xec\x8c\x5e\x5c\x60\xe1\x4e\xe8\x87\xe9\x0c\xd7\x4a\x0a\x00\xdd\xa3\xdc\x8f\xf4\x57\xb7\xc2\xb0\x6f\xbe\x8c\x47\x52\xef\x2e\x81\x8d\x47\xfb\xa3\xf0\x20\xd0\x0e\xc0\xdb\x17\x82\x22\xe1\xdd\xc9\xca\xb0\xea\x78\x02\x71\xc6\x60\x40\x72\x0f\x19\x1a\x85\xae\x35\x0f\x54\x84\x57\xa2\x6c\x87\x4e\xa2\x3b\x9c\xd1\x9a\xe8\xfd\x24\xd5\xf0\x9e\xa2\x1b\xb0\x55\xc2\x04\x5b\xf9\xb2\xd7\x66\x6b\x1e\x45\xec\xe5\xfe\x2c\xad\x24\x64\xad\x67\x85\x60\x93\xe7\x38\x2e\xf5\x88\x3e\xdf\xc3\x85\x3a\x6a\xa2\x29\xcd\x7f\x9b\x7f\x11\x9f\x1b\x3a\x11\xd2\xf8\xb8\x2b\x2f\x1b\x77\xee\x81\x19\x3c\x42\x39\x98\xcf\xc3\xcf\xff\x28\xed\xd1\xf4\x53\x48\x0e\x62\xc2\xfd\x2e\xab\x02\x97\xf0\x3c\xd2\x44\x80\x1a\x8f\x25\x59\xfd\x97\x0e\x38\xac\xe1\x7e\xf9\x95\xd5\xa5\xf6\x4f\x36\xb0\x39\x85\x7e\x3d\xb6\x2d\x22\x44\xec\x9e\x47\xac\x54\x93\x4e\x11\x1b\xcc\x5f\x3d\x63\xda\x94\xdd\x93\x5a\x98\xfe\x06\x23\x75\x14\x2a\x48\x7e\x9b\xb2\x6f\xaf\xe0\x7a\xa4\xee\x1b\xfc\x20\x58\x39\xd9\xce\x83\x9d\x3b\xa4\x37\xb7\x56\x1f\xfa\x8c\xec\xd8\x65\x7d\x6f\xab\x2c\xd6\x91\xbb\xa3\x1b\xdc\x65\xd5\xbb\x62\xf4\x5c\x70\x19\xbb\x1f\xc3\xb8\xf2\xa4\x2f\xff\x52\xc2\x9f\x88\xe0\xdf\x52\xa6\x75\x93\x90\x7b\x29\x21\xb3\x5b\x5a\x7c\x84\x6d\x2c\x9c\x06\x6c\xcb\x89\x5e\x79\x0d\xfa\x86\x8b\xda\x59\xe1\xc9\xcb\x68\x26\xef\x74\x99\x57\x87\x6f\x96\x38\xe5\x96\xdc\x08\xba\x0b\x1d\x57\x96\xe4\xcd\x9c\xbf\x22\x5f\x90\x3f\x44\x7a\xfb\xc8\x6a\x1d\xab\x39\x7c\x37\x35\x2b\x67\x61\xaa\x57\x78\x22\x39\x63\x52\xba\x9b\x4a\xfb\xdb\x49\xbd\x7a\xdb\x3f\x50\xa0\x8e\x7d\xc4\x02\xa9\x86\xdf\x6b\xd5\x01\xef\x1d\xb5\xfc\x4e\xd8\xd6\xf9\x4d\xde\x77\x7b\x38\xe7\xf0\x9a\xa3\x84\x13\xbd\x64\x82\x21\x25\xc5\xf4\xf6\x6b\xab\x86\x83\xda\x9f\x0f\x03\x4d\x4e\xd0\x93\x87\x8d\xad\xf1\xd8\xd4\xfa\x6d\xdf\x36\xc8\xab\xc4\x32\x53\xc4\xd6\x21\xda\x90\x37\xbc\x17\x1e\xaf\xd6\xc4\x7b\xeb\x43\x87\x11\x88\x47\xb5\x84\xe9\x67\xcc\x03\x53\x1a\x76\x2f\xa6\xbd\x38\xa7\x7e\x88\x09\x0a\xae\xa4\xf7\x02\xad\x34\x57\x9e\xb1\x28\x4f\x6b\x8c\x5c\x43\x20\xc5\x7c\xd4\xa4\xec\x1f\x30\x06\x58\xe1\xb5\x16\xc2\xc8\x84\xfe\x31\x5c\x38\xe3\x53\x7a\x03\x78\xd7\xda\x35\xc2\x44\x42\x75\xdd\x18\x64\xc7\x73\x54\x3f\xf5\x59\xd1\x76\xf4\x13\xe7\x59\xff\xe6\x37\x2d\x01\x30\x64\x60\xcf\x29\x06\xf6\x53\x11\x60\x30\x61\x97\x2d\x54\x51\xa1\xf9\x8c\x55\xf3\x09\x97\xe8\x55\x05\x5e\xa7\x9b\xec\x1d\x11\xe1\x7a\x12\x9f\x91\xcd\x07\x95\x40\x33\x94\xbb\xcc\x47\xd4\x2e\x11\x11\x82\xde\xb6\xbb\xa6\x70\x76\xcf\xe4\x91\xc2\x46\x98\x7c\xc9\x33\xcc\x26\xf0\x5f\x1e\x0c\xc9\xf6\xe7\x12\x69\xfb\x25\x0b\x01\x7f\x89\x27\x4d\xfa\xce\x50\x3f\xc6\xf3\xad\xe4\x03\x54\xc9\x36\x5b\x5d\xdd\x80\x71\xa8\x30\x04\xc5\xe0\x94\x51\xd6\x50\xae\x50\x15\xf5\xa4\x4d\xbe\x66\xd5\x74\x98\xa8\x28\x20\x3a\x9b\x96\x1c\x56\xa1\xbc\x8d\x08\x14\x8b\x35\x65\xb6\x0f\xe1\x75\xeb\x46\xef\x7e\xf4\xce\x21\x96\x01\xfe\xc5\x64\xa5\xc1\x76\x5a\x61\x4a\xda\xb1\x14\xed\x3f\x92\xb2\xf6\x08\x81\xf2\x0a\xa8\x5e\x08\xa3\x67\x6b\xef\xe2\xc7\xe8\xcf\xc2\x0d\x94\x9b\x5f\x15\xde\x86\x3d\xdf\x2e\x72\x8f\xdb\x5d\x91\xf8\x58\x4e\x01\x43\xb6\x0e\x4f\x7a\xd2\x1e\x06\x57\x5e\xf7\xd2\x1f\x6b\x94\x56\xb7\x0f\x9c\x05\x46\x55\xe8\x5a\x4a\x3b\x84\x25\xe2\x8f\xd6\xa5\x90\xc2\xcb\xf7\xbb\x47\x2d\xa1\x4a\x0e\x64\xac\x4b\x71\x44\x87\x2a\x50\x6f\x1f\xb1\xbc\x5b\x95\xa0\xd5\x7d\x42\x2d\x61\x67\xac\xfc\x01\x6c\x1b\xaa\x3b\xc1\x9e\x8f\x9e\xde\xbb\xb9\x07\x74\x51\x76\xc5\x2d\xf3\x10\x65\xd9\x1c\xe9\x99\x4e\x9f\x94\x5a\x29\x69\x8d\xeb\xc4\x47\xea\x3c\x16\x38\x42\x8e\x9a\x43\x29\xfe\x83\x1f\xb9\xbd\xb6\x6d\x54\x25\x68\x63\x23\x61\x2f\x60\x81\xee\x4f\x42\xdd\x5d\xd1\x4d\xcd\x10\xbf\x34\xa8\xbf\x13\xd6\x8d\x3e\x20\x4a\xf4\xc9\x99\x02\x9d\x32\x0a\xed\xa8\x2a\xee\x96\x5e\xbc\x9b\x2f\x17\xb4\xb2\x8f\x29\x9f\x8f\x6e\x8e\x78\x4b\xd8\x49\x0d\x51\xd9\x31\x6b\x12\x33\x6e\xf4\x08\xcf\x06\xf7\x74\xed\x43\xa3\x83\xc8\xed\x3f\xda\x83\x11\x94\x94\x68\xc4\x6c\x83\x41\x9e\x5a\xdc\x48\x79\x64\x92\xcf\x6c\xc9\xea\x25\xac\x02\xe8\x8e\x7b\x0d\x56\xb7\xb8\xd6\x5d\x44\x42\xfa\x26\xe5\x3e\x76\x59\xbd\x79\x3e\xa4\x73\x13\xa2\x0f\x1f\xc2\x9b\x47\x5d\x86\xce\xd6\xf7\xbb\x76\x95\x77\xee\x94\xc1\x53\x33\x79\xd4\x9d\x0f\x9c\x35\x6a\x97\x73\xd4\x9c\x29\x9e\x3f\x52\xdf\xf1\x9d\x73\xc4\xc5\xda\xec\x9d\x49\x68\xfd\xa6\xe5\xfc\x86\xee\xe1\x53\x27\x3f\x25\x3f\x9e\xfe\x8b\x01\x5a\x1d\xb4\x36\x28\x9b\x2e\x81\xf7\x1c\xa9\xf5\xef\x86\xcf\xd0\xf8\x20\x47\xd1\x07\xe8\xd8\x75\x55\xb6\x34\x3c\x68\xd4\xcf\xce\x64\xb2\x2f\x7f\x27\x8c\xfd\xe2\x16\xee\x55\xb0\xf1\x60\x0c\xdd\xab\xd8\x05\xee\x9f\xf0\x35\xbf\x44\x0d\xb0\x9f\xe8\x96\xfa\x6a\x75\xe2\x1d\xef\x0e\x83\x55\x16\x83\xbb\x1a\x7b\xbb\x15\x8d\x65\x8f\x66\xa0\xfd\x91\xf7\x30\xe8\x5a\x73\x7d\xc5\x38\x55\xf2\x91\xec\x6b\x12\x09\xbb\x12\x55\xf5\x1a\x51\xdc\xad\x5b\x17\x0e\x0c\xf8\x07\x5d\x6b\x77\x04\x8c\xdf\xe5\x60\x61\xb8\xf5\xec\x9f\xdc\x65\x6b\x7b\x51\x1b\xa7\x6b\x96\x75\xc2\xaa\xce\xc4\x1d\x8e\xbe\x56\x42\x36\x13\xc3\x7b\x0e\x61\xcc\x2d\x52\xd7\x1d\xc9\x0c\x48\x5e\x6a\x56\x0c\x36\x5f\x55\x5a\x15\xb8\xdb\x03\x37\x3d\x17\xac\x82\xd8\x2a\x0c\x17\xda\x0b\xf1\xa1\x57\x0c\xfc\xc8\x8d\x8e\xc7\xa0\xab\xd0\xb1\x79\x65\xfb\xc7\x2e\x4c\xd8\x20\x54\x7d\x8a\x09\xbd\x7f\x54\x17\x1b\x4f\xaa\x14\x77\x31\x40\xa3\x71\x77\xc4\x72\x65\x23\xb2\xab\xed\x0a\x0a\x2f\xb1\xbd\x55\x79\x5b\x63\x26\x5f\x76\x7d\xcc\x4c\x1a\x2d\x30\xe7\xf4\x11\xd9\x1c\xb6\xbd\x20\x63\x73\x65\xa6\xd7\xc5\x66\xf2\x35\x33\x99\xd2\x8e\xa1\x8a\xba\x40\x41\x92\xa9\xac\xcd\x09\x61\xc0\xf0\x0f\x9d\x74\x0a\x8b\x50\xd4\x95\x7a\x87\x53\x6c\x56\x9d\xe8\x29\x7f\x86\x57\xe8\x98\x20\xc0\x6a\x5a\xa8\x4b\x61\x00\xb6\x3a\x86\x6d\x84\xeb\xca\xd5\xcc\x04\xdd\x49\xdd\x4c\x60\xeb\x2a\x4c\x73\x84\x9f\x82\xce\xf9\x93\x90\x31\xca\x81\x99\x5d\xde\xd5\x0c\xdb\x10\x11\x14\xed\xf0\x57\x59\xc5\x02\x16\xe0\xbb\x4e\x6a\x23\x5d\xe8\x99\x53\x24\x97\x00\x30\xb2\xf8\xfc\x24\x39\x40\xdc\x42\x60\x3c\x3a\xa1\x63\xb0\xff\x19\x7b\x4b\xcc\xe2\x59\x81\x3d\x67\x04\xe0\xdb\x49\xd2\xa2\xdf\xe7\x95\x8c\x4e\x85\x21\x79\xbb\xb2\x65\x57\xd1\xfa\x61\x4f\xdc\x66\xb1\x4b\xe9\x15\x1f\xe9\xe8\x87\xa8\x82\x56\x8b\x32\xb0\xca\xe6\x22\x68\xc2\xbc\x7b\xc8\xd0\x6d\xba\xa4\xb1\xc7\x08\x1a\x29\x5b\x9c\x00\xb9\xbd\x98\x2c\x68\x5c\x3f\xd8\x88\x64\xe2\xbb\x36\x32\x68\x48\x72\xdf\x70\xb8\xba\xc2\xdf\xf7\xc1\x8a\x0b\x30\xfc\x29\x8b\x88\x9b\x97\xe3\x0f\xe1\x3c\x94\x39\x6b\x47\x45\xd2\xc3\xc1\xf4\x08\x6c\x05\x7f\xd9\xdc\x17\x7f\x04\x17\xed\x48\x9c\x8a\x8e\x5f\x10\x37\x12\xe7\x07\x99\xf3\x8a\x8d\x9a\x02\x6f\x3d\x12\xbd\xaf\xed\xa8\x58\xfa\x1b\x8e\x6c\x7e\x31\x16\x69\x22\xc1\x2c\xf5\x4f\x6b\x15\x88\xb8\xa6\xc8\x05\x18\x29\x53\x2c\xbd\xbb\x5a\x78\x19\x1b\x97\xd8\x5e\x82\x46\x64\x0f\xd3\x9d\x7b\x7e\xff\x43\x45\x75\x2c\xd9\x87\xb3\x60\x9c\xbd\xa5\x0b\xed\x99\x32\x3a\xdb\xae\xf3\xd3\x6d\x95\x1e\x4d\x9b\xe3\xd3\x94\xb8\xb9\x3f\xf0\x2f\xd4\xe1\x0e\x03\x0a\x15\x8b\x76\x65\xc5\x16\x62\xc3\x62\x12\x37\x87\xc5\xdb\x4c\x34\x1e\xc5\xac\x5a\x89\x73\x2f\xc3\x5d\x58\x2c\x2b\xef\x61\x78\x39\x8c\xb0\xd9\x62\xa9\x0b\x1e\x6d\x4c\x16\xb2\x57\xb4\x28\xff\x57\x93\x03\x88\xae\x8e\xa3\x76\xce\x76\xef\x03\x7b\x95\xe0\xc8\xb0\x3f\x69\x43\x45\x6a\xf5\x03\x3d\x77\xb7\xf4\xf9\x35\x25\xa8\x6e\xf3\xee\xb5\xfc\x29\x1a\x8f\x55\x9d\x03\xfb\xe9\xe6\xcb\x77\x4b\xfe\xc7\xfc\x65\xc9\x3a\x6d\x91\xc7\x35\x0c\x2d\x4d\x9f\xdd\x04\xd0\x5a\x59\xec\xfa\x0c\xb6\xd6\xa0\xae\x7a\x07\x61\x0d\xef\x6b\xf7\x6f\x22\x75\x95\x55\xad\xcb\x1e\x34\xb3\xc2\xc8\xa2\xd1\xbd\xad\xee\xf5\x34\x87\x1c\xc0\x27\xed\x05\x58\xf3\x6e\xea\x27\xaf\x0c\x86\x59\x73\x5f\x3f\x7a\x50\xd7\xaa\xe1\x70\x7e\x3b\x75\xba\xfa\xb6\x7b\xac\xec\x5f\xee\xc8\xf8\x24\xaa\xb5\x2a\x73\xdd\x96\xc7\x1c\xd9\xb5\x5d\x92\xdc\x4e\x5a\x68\xab\x94\xc7\x48\xf7\x9a\x58\x33\xef\xcc\xd8\x87\xf0\x8e\x76\x19\xab\x4c\x2f\xe0\xcf\x11\x61\x5f\x30\x95\x50\xea\xe0\x42\x46\x27\x47\x4d\x27\xb4\xcc\xd1\x9d\x04\xa7\x7f\xe4\x2c\x0d\xbf\xe0\x10\xe3\x29\xd5\x67\x49\x84\x75\x97\x74\x70\xb7\xfe\x57\xa6\x66\x85\xf1\x97\x7f\x91\xaf\x7f\xd1\xaf\x9f\x61\x57\xe6\xe7\x6a\x6b\x04\x4f\x1f\x5b\x3b\x9c\x32\x8a\xf2\x98\xc6\xb8\x6e\x85\x71\x8a\xae\x9a\xfd\x23\x4d\xd0\x0a\xf2\x68\xeb\xff\x92\x7c\x6d\x99\xc2\xca\x6a\x9a\xc7\xb0\xcc\x08\x9b\x2d\xfb\x81\x0a\xbb\xae\x59\x90\xa5\x4d\x07\x4f\x35\x43\xe7\x65\x69\x15\x32\xfe\x6b\x52\x9a\x45\x50\x61\xa6\xfc\x4f\xb0\xed\xe7\x97\x75\x1b\xd5\x6d\x0d\x9f\x63\xd4\xbe\xe4\xbb\xda\xd2\x4e\x07\x0e\xd7\xef\x28\x82\x4c\x4e\x62\x48\xb9\x90\x09\x08\x02\xad\x6b\x23\xc2\xe6\x67\xfc\x93\x41\xbe\x04\xb0\x37\xce\x8d\xdf\xfa\xd9\xd5\x57\xfd\x8a\xb1\xaa\x38\x7f\x9b\x9e\xdd\x39\x43\xce\x27\xa3\xcc\x75\x47\x45\x9f\x8f\xf2\x96\xc6\xb1\xa7\x34\xf0\x25\xb2\xaa\xc8\x19\xd8\x1c\xb3\x14\x96\xb8\x60\x84\x30\x81\x53\xf0\x98\xba\xa2\xea\x58\x3e\x21\xb0\x9e\xf3\xea\xf4\x84\x96\xc2\x9d\x2d\x4e\x72\xe4\x9e\x45\x41\x15\x4f\x60\x61\xfb\x8f\xa3\x0a\x00\xfd\xc1\x36\x25\xeb\xeb\xf4\x52\x82\x06\xea\x5f\xe6\xea\x82\x68\xf0\x80\x69\x32\xbd\xea\x22\xbe\x09\x57\x97\x40\x18\x86\x49\x91\xbe\x7a\xbf\x67\xb5\x42\x68\x04\xdb\x76\x5c\x5e\xde\xc6\x2e\x38\x0f\x71\xa2\x67\xad\x91\xd8\x0c\xc9\xc4\x0f\xed\xcc\x2c\x9d\xd9\x80\x75\xd7\x8f\x1e\x30\x1b\xa4\x56\x76\x0a\xe7\x6e\x66\x2c\x30\x72\x31\xa6\x1c\x91\xb9\xe7\x16\x76\x75\x23\x7c\x5f\x59\xc0\x0d\x50\x82\x89\x68\x4a\xee\x2c\xf8\xf6\xfa\xb0\xc8\xb3\x96\x74\x11\x36\x59\xf4\xdb\x48\xd4\xa1\xd8\x36\xf3\xdc\xc5\x7c\xb4\xb9\x62\x8d\x5a\xf6\xe6\xe9\x63\xfb\xa9\xad\xd9\xa2\xf4\xd0\x3b\x66\x0d\xa8\xf9\xab\xd2\x7f\xd2\x73\xe3\xe1\x94\x55\x6d\xdd\xfb\x33\x87\x43\x46\xfd\x59\x35\x9f\xa1\x1a\x3c\xef\xe8\xe6\xf7\xb0\x1d\x96\x5f\x07\xbe\x07\xe5\x6f\xec\x10\x7d\xb2\xbd\xb9\x0f\x72\x5d\x2e\x6b\xb9\x28\x38\xb3\x21\x82\xbf\x7d\xf7\xd2\x17\x82\x20\x7d\xb0\x49\xb0\x8a\xa8\xbf\xd9\x33\x47\x38\x7b\x36\x3e\xab\x62\x99\x96\x62\xb0\x47\x9d\x2c\x42\x0e\xca\xe4\xa0\xd9\xe2\xaa\xfa\x7e\x45\x99\x3d\x09\xc5\xa0\x60\xe6\x71\x53\x3c\x48\xa4\x65\xf7\x29\xdc\x47\xa0\xa7\xe1\xba\xde\x7d\x76\x4a\xfa\x6a\x70\x77\xc1\xaa\x25\xe3\xf6\x24\x8e\xe0\x91\x40\x6c\x8a\x36\xfa\x6a\x8d\xa6\x66\xcd\x72\xc3\xb0\x72\x37\x3a\x9e\x5b\xab\xba\x61\x59\xa0\xe2\x79\xce\xb2\xed\xcb\xb3\xaa\xe8\x25\x8b\xcc\xd0\x85\x1f\x51\x57\xb4\x85\xef\xf0\xad\x45\xd1\x6c\x9f\x51\x83\xf0\xca\x73\xa3\x7b\x5a\xf9\xc5\xa3\x56\x6d\x70\x6c\x60\x25\x39\x87\xff\x98\x4a\xcf\x61\xbf\xdd\x4d\xaa\xe2\xed\xc8\x14\x5f\xbb\x1e\xd5\xd3\xb4\x4f\x37\xf1\x98\x9b\x8f\x60\xc0\x10\x1d\x35\x07\x0d\x6e\xf0\x2b\xe1\x2e\x4a\x15\x9e\xe2\x15\x7e\xa3\x40\x0b\x51\x85\x37\xef\x99\x4e\x56\x36\x1d\xe6\xf9\x30\x2d\x81\x45\x31\xab\xe9\xb5\xb0\x37\xea\xaf\x4d\xc2\x66\xfa\x2f\x2e\xd3\x74\x90\x8a\x92\x8a\x2c\xfe\xec\x92\x17\x9b\x36\xff\xd1\x55\x04\x92\x47\x16\xdb\xab\xa8\xab\x09\x25\x0b\xeb\xe6\x5e\x2d\xca\x2f\x16\x0c\x86\x64\x7d\x03\x5c\xfa\x12\x54\xfb\x26\x30\xaf\x59\x05\x97\x0a\x1a\x90\xaf\xe6\x9f\x42\xd8\xe0\x63\x35\x85\x6f\x3a\xde\x1f\x5e\x48\x3e\xb1\x44\x30\x49\x58\xda\xa3\x51\xba\xa9\x30\xc6\xfe\xe0\x17\x1e\x02\x95\xe3\xf9\xeb\x97\x46\x17\xd5\x7e\x4a\x2b\x7d\x2e\x8d\xf5\x4c\x8a\x05\x1f\xb2\x27\x69\x97\xb7\x4b\x2a\x99\xcf\xfb\xb6\x05\x32\x2c\x06\xb3\xf4\x6d\x0c\xd5\xd3\xdb\x7e\xbb\xe8\x92\x6d\xd7\xb1\x45\x9c\xfc\x0c\x36\x10\x73\x12\x0a\xcc\x74\xd2\x4f\xeb\x0d\x8e\xd7\xa6\x73\x09\x81\xc7\x22\xfb\x32\xe8\xca\xea\x75\x2f\xdb\xe7\xaf\x5f\x79\xdc\x6c\xbe\xe0\xca\x4d\xb2\xee\xba\x72\x03\xfe\x92\x08\xc8\x96\xc6\x4a\x4e\x6f\xe6\x14\x54\x57\x32\x6e\xeb\x44\xdb\xe7\xbb\x9e\x36\x21\x78\x6f\xd4\x56\x8c\x43\xe5\xb5\x62\x6a\x6e\xc0\x6d\xac\x9f\x27\x38\x9a\x2d\x73\xa3\xd7\x2a\xc1\xff\x86\x40\x6f\x8d\x60\x64\xd9\x0e\xd9\x74\xcf\x02\xfd\x42\x6a\x05\xc5\x74\x77\xbd\x55\xde\xba\xd9\x36\x87\x27\xed\x6f\x30\xa0\x55\x00\x58\xb6\x39\x24\x90\x67\x6e\xd5\xee\x5d\xe4\x13\x79\xb9\x0b\x8b\x9a\xc0\x94\x4e\x72\x70\xa8\xd0\x6e\x95\xef\x9d\x2a\x35\x7e\x28\xe5\xe3\xa6\x4d\x71\x75\x77\x04\xf4\xf5\x8b\xb2\x0a\x90\xc1\x17\xfd\xd2\x23\xf7\x73\xd2\x50\x05\x78\x79\x87\xf7\x09\xc3\xa1\xaf\x02\x46\x9d\x0f\x86\x96\xa1\x08\x49\x78\xc4\x38\xff\x15\x51\xc5\xae\x19\x5f\x26\x05\x8b\xb3\xad\x9f\x8a\x58\xee\x45\x4d\xbc\x58\x5e\x5d\x93\x9b\xd5\xf8\x08\x19\xbd\xac\xa5\xe7\x97\x3a\xb9\x92\x8a\x8a\x6b\x4a\x65\x25\x8b\xec\xac\xcd\xd7\x25\x34\xcd\xe6\x1b\x16\xd5\xa3\x2a\x11\x6f\xe6\x92\x04\x78\x41\x3b\xc1\x77\xdd\x4f\xf5\xd7\xc1\xad\xb2\xbf\x44\x55\x2d\x37\x5a\x28\x0d\x53\x0b\x71\x0e\x8e\x1c\x86\xf0\x55\xec\x72\x50\x8d\x69\x2e\x84\x82\x9a\x75\x74\x47\x8b\x8b\xb3\x32\x90\xc4\x8e\x76\x8b\x0f\xb2\xb7\x57\xcb\xbb\x85\x01\x16\x56\xd2\x3e\x3b\x88\x04\x7c\x51\xa1\x0c\x3d\x07\x1f\x65\x57\x87\xa0\xf8\x73\xd6\x6f\x7d\xfe\x5a\x75\xa7\x73\x19\x5a\xf0\xcc\xe6\xa7\xc0\xa9\x84\x49\x52\x7f\x1f\x4a\x99\xe1\x0c\xe4\xc5\xb4\xd7\x92\x6a\x91\xd6\x93\x12\xb7\x43\xd1\x30\xb0\xae\x53\x64\x20\x2b\x0f\x74\x77\xfb\xf9\x48\x2a\xb5\x95\x98\x86\xbc\x46\xb1\x7d\xd1\x48\x63\x55\xcd\xc2\x19\x7c\x48\x1c\xc1\x8d\x3d\xd5\xd8\xdd\xa9\x06\x38\x9e\xdc\xf2\xdb\x11\x1b\x63\x38\xb0\xb2\x93\x6b\x67\x47\x14\xbb\x75\x0d\x4b\x17\x77\x52\x7e\xb0\x8d\x3b\xc9\x59\xf1\x5c\x94\x64\xc3\x9f\xb6\x54\x3b\x31\xbc\xfc\x0d\x38\xc2\x6a\x62\x9d\x8b\xe5\xdc\x66\xf5\x7f\x4a\x0f\xaf\xf6\x99\xdc\xfe\xbd\x84\xb6\xdc\x6d\x61\x9c\xc7\x5b\xb8\xcd\xb2\x9a\x4d\x39\x9b\xfb\xac\xc8\x02\xd8\x30\x22\x50\x8c\x45\xae\x7f\xb2\xbd\xb1\x63\x3f\x11\xf5\xbb\x55\x92\x83\xe0\xb7\xc8\x96\x65\xb9\xdb\xc4\xe6\x96\x8b\xa2\xf4\x46\xdc\x20\xda\xfa\xba\x13\x6a\x9c\xca\x32\x79\xf8\xe6\x7f\x2c\x60\xd4\x22\xb5\x92\x8d\x74\xe1\x19\xc2\x37\xd5\xc6\xb3\x2b\xcb\xfc\xf2\xa6\x82\xd3\x81\xad\x0d\x04\xf1\x97\x0a\x63\x74\x3c\xd8\xda\x5d\xb9\x29\x41\x3f\xf7\x62\xc7\x36\xaf\x53\xd4\x4f\xee\xff\x22\xad\xe6\x49\x0e\x1a\xac\x5d\x9a\x6f\x79\x5d\xa3\x7b\x2b\xaa\x32\x8a\x60\x71\x70\xef\x24\x41\x67\x2f\x76\x18\x98\xba\xfb\xcf\x11\x7d\xac\x52\x6f\xee\xef\x14\x01\xdb\x29\x9a\x3b\x68\xf9\x46\xf6\xe1\xe8\x08\xf2\xaa\x8c\xba\xb5\xf2\xbc\x5d\x09\x23\x5b\x29\x6c\xab\x04\x39\xbc\xb3\xd7\xbc\x75\x60\xc0\xfe\x5a\x85\x7e\xba\x43\x7a\xf4\x76\x1b\xfb\x0e\x51\x6c\xd1\x00\xc5\xd8\xbf\x7a\xc0\xd5\xcd\xc9\x11\x32\x43\x66\x5d\xd3\xfb\x61\xe5\x17\x84\xe0\xc4\x45\x14\x60\x56\xbe\xb6\x16\xde\xf4\x64\x27\x6c\xe7\x05\x76\x13\x0c\xaf\x59\xd6\xce\x36\xf0\x2a\xc1\xc1\x6d\xda\xd1\x00\x34\x60\x8a\x4f\xaa\x4f\x15\xc7\xbb\xfb\xf4\x3c\x54\x46\x47\x11\xbd\xfd\x6e\xf5\xc6\x33\xbf\x8b\xf4\xd4\x31\xb2\x76\xc0\x2e\x7c\x40\xfc\xf9\x8d\x16\xb4\xb7\xa4\xf5\xa6\xc2\x24\x69\x41\xd8\x14\x2f\x2f\x38\x23\xd9\xb5\xc9\xb3\x61\x39\xa5\xf3\x2c\x84\x89\x16\xbb\x60\x16\xf9\xe0\x0c\x11\xb1\xbd\x27\x5e\x0f\x0b\x5d\xe3\xbd\x5a\x5f\xd3\xa4\x8a\x5c\xfd\x19\x2b\xbc\xbf\xb2\xb9\x09\x80\xc0\xb3\x1d\x23\xe0\x3b\xe7\x96\xcf\x23\x5c\x1a\xe6\xbe\xe8\x22\xdb\xd0\x2e\x5b\xbc\x9b\xb9\xcf\x60\xa8\x79\x55\xf9\x89\x30\xc7\xa1\x88\x44\x5c\x0f\x76\x96\x57\x65\x1f\xd8\x28\x72\x1a\x0b\x1a\x30\x1c\x0d\xe9\x50\x79\x2d\x47\x4a\x64\x5b\xab\x87\x6c\xef\x85\xcc\xe2\x5d\xe5\x9a\x4d\xaf\xaf\xe8\x3a\xb3\xcf\x0d\xf3\xc9\x10\x89\x0e\xcd\xde\x32\x0f\xaa\xcb\xbb\x10\x8b\x7e\x5a\xb6\x8f\x3a\xca\x03\xa9\x42\x13\x84\x3d\x99\x25\xf4\xa4\x7e\xf4\x18\x26\x0b\x63\xfd\xce\x0c\x00\xa2\x89\xce\x59\xf2\xa5\xad\xd3\x08\x78\x9f\x95\xb3\x62\x39\xc6\x13\xb4\xf8\x5d\x2e\x94\xd7\x1d\xb4\x63\xe5\x7a\x57\x59\xb9\x5f\x57\x92\x87\x7b\x98\xe2\x8e\x45\xfa\x18\x8f\xfa\xf6\xda\x5a\xa7\xcb\x38\x97\x73\xa4\x2a\xd4\x7b\x36\xb4\x72\xc7\xef\xc5\x57\xc7\xc8\xcf\xf8\x51\x76\x99\xf9\xd7\x8d\xae\x5c\x12\xc7\x96\x5b\x32\xa6\x96\x14\x9e\x24\xc1\x1d\xed\x57\x18\x55\x92\x8f\x9a\xd1\x9e\xcd\x1f\xd1\x2a\x70\xac\xb6\xbd\x3c\x6c\xd0\x33\xb5\x5f\xf2\xe1\x5d\x68\xda\x34\xb1\x25\xed\x5e\xf0\xfe\xd4\xb5\x2a\xb2\x08\xb2\x2e\x94\xd8\xfe\x00\x78\xf9\xf8\xd7\xf2\x9c\xf7\xa6\x59\xb4\x1d\x64\xbf\xf0\xee\x3e\x5a\xda\xbd\x62\xe4\x9e\xbe\x3d\x7b\x44\xdf\xda\x07\x81\x96\x64\x61\x08\x19\xdc\xa0\x9e\x69\x45\x7e\x02\x7b\x75\x7f\xea\x41\xe4\x07\xe6\xb0\x21\x77\x57\x8a\xe8\x45\xaf\x17\xb3\x10\x9c\x7e\x21\x6a\x32\x3e\xb1\x1e\x2a\xc0\x6b\xa8\xa2\xde\xc3\x21\xc0\x2b\x6d\xcc\x91\x2c\x44\x31\x14\xdf\x14\x21\xe4\x2a\xe7\x21\x11\x93\x7c\xf5\x97\xad\x34\xdf\xee\xca\xce\xe1\x4d\x16\xce\x30\x4b\xb8\x31\xcc\x48\xcb\xd4\xbd\x0b\x21\x80\x57\x78\x20\x23\xb2\x9c\x5d\x69\xec\x52\x36\xf2\x90\xcf\x1f\xb1\x1e\x6d\x8c\xad\xc8\xc7\x7e\xbe\xc5\x5d\x06\x9b\x4d\xb8\x40\x66\x66\xd3\xb4\x85\x1e\xb5\x67\xf1\x3f\xfc\x15\x92\x8d\xc3\x31\xb2\x07\x7c\x1f\x99\xe6\x3a\x5f\xb1\x96\xa8\xaa\x7f\xb7\x9e\x74\xb3\x71\xee\xdd\xb6\x82\xa2\xd4\x93\xbe\x8e\x18\xf8\xe1\x08\xbf\xcd\xb2\xbf\xa2\xc6\x9f\x18\xa5\xbe\xd6\x10\xae\x46\xa4\x8d\xed\x4c\xce\x08\x93\x82\xa3\x94\x28\x69\xb6\xa3\x63\x1a\x27\x0a\x17\x5f\x2a\xb0\x97\x10\x54\x31\x01\x09\x6c\x80\x0c\xff\xec\xd4\x74\xc7\x17\x15\xe6\x9a\x69\xa3\xea\xb7\x47\xc8\xc2\x47\x65\x7f\xcb\xe9\x87\xdd\x5d\xf3\x0e\x42\xe2\x1f\x47\xfb\x3f\x69\xec\xf6\x05\xa8\xa7\xda\x7d\xa2\x96\xad\xd8\x15\xb1\x90\x17\x25\x03\x2d\xf2\x20\x35\xc3\x2a\x86\xaf\xd9\x9d\xdf\xf2\x8d\xfe\x5b\x77\x7e\xa2\x51\x5e\xb7\xb9\x29\x64\x05\xd8\xe1\xba\x6e\x9d\xf5\x66\xa1\x7f\xce\xff\xa9\x8d\x3e\xef\xaa\xfe\x47\x25\xb7\x5a\xfd\xbf\xb5\xc0\xcf\xb7\xfa\xea\xbb\x2d\xe2\x5b\x30\xa0\x43\x1a\x02\x5f\x7f\x11\x49\xbb\xf2\xcd\x6c\xaa\xd7\x55\x4e\xff\x4d\x14\x0b\xd0\xbe\xd0\x34\xb3\x73\xa9\xb5\x0f\xa2\x0c\x2f\x91\xcf\x59\xdc\x99\x22\x88\xd0\x8a\x10\x98\x5f\x85\x26\x44\xa8\x41\x5d\xc4\xdc\xcd\x5d\x14\xf0\xfb\x33\x06\x36\x93\x88\xce\x9d\xd7\xca\x0e\xf8\xba\xa6\x96\x04\xb0\x36\xac\x40\x2e\xff\x3f\xbe\x08\x6a\x7b\x89\xab\xbb\xd6\x0b\xec\x90\x23\xca\x36\x12\xc8\xcf\x12\x07\x3b\x47\x8a\x0d\x7b\x1b\x8a\x5c\xcd\x99\xd4\xf6\x3f\xd1\x1f\xbf\xb8\x1b\x4c\x17\x59\xd6\xe0\x8b\x24\xea\x6d\x91\x66\xa6\x4a\x10\xaa\x41\xfa\x21\xf1\x9a\x6d\x05\x2d\x1a\xe4\x95\x09\xf7\x56\x7f\xea\x25\x57\x96\x56\x0a\x66\x4b\x02\x19\x70\xce\x2a\x8a\x25\x41\xd6\x1c\x1e\x14\x68\xc7\xf9\xc3\xd3\xa5\xbc\xd2\x49\x7c\xbf\x0f\xf7\xec\x1f\xa1\xfb\x1f\x10\xb5\xe9\x88\xf4\xd1\x67\xc4\x87\x70\x8f\x8d\xac\x3f\xa4\xb4\x2d\x32\x4e\xda\xc3\x87\x16\x38\xc0\x25\x39\x2f\x02\xe2\xf8\xfd\xbe\x83\xa8\xe1\xf6\x88\x81\x0d\xa0\x96\x92\x8f\x69\x92\x70\xd7\xca\x84\x7f\xac\x95\xf6\x26\xd2\x05\x43\xff\x6e\x99\xfa\x21\xe9\x4d\x08\xc7\x3f\x1e\x24\x5d\xf3\x96\xe0\x64\x59\x69\xef\xa1\xf4\x4c\xd1\x77\x33\xd4\x17\x53\x41\xfc\x0f\xcc\x24\x2c\xfc\x47\xa9\x75\xe1\x13\xf9\xe1\x88\xab\x06\x68\x7f\xf3\x16\x0c\x17\xe7\x69\xdb\xa7\x64\x57\xe0\x65\xaf\x56\x78\x4c\x5f\x41\x5b\xf5\xe6\xe7\xf6\x84\x02\xc6\x66\xd7\x3d\x78\xe9\x4e\xd0\x0e\x6a\xf7\x69\xb3\xed\x97\x94\xee\x1c\x26\x64\x18\x8a\x63\x73\x9f\x6e\x02\xe0\x0f\x28\x74\x7d\xbc\x35\xdb\xdf\x73\xe3\xee\x59\x11\x74\xff\xb1\xfb\x0f\x0f\x0e\x82\xe6\x37\x50\x7b\x3f\x6a\xf7\x78\x83\xc2\xc6\x9f\xf0\x46\x5b\x99\x9d\xe1\x0f\xa5\x0a\xd7\x7b\x16\xec\xa0\x49\x17\x28\x82\x68\xde\x34\x49\x6d\x1e\x40\xce\xc5\x16\xc3\x00\x7f\x84\xd7\x92\xfd\x54\x12\x41\x79\x23\xfe\xd7\xeb\xf2\x7e\x83\x0a\x65\x5b\xbd\xd5\x71\x87\x03\x6f\x74\xe4\xad\x12\x7c\xca\x17\x6a\x9a\x9f\x94\xaa\xda\xa8\x63\xf2\x85\x4d\x1f\x2f\xbd\x93\xa9\x6d\x14\x2f\xdb\x3a\x57\xbe\x65\x2b\x58\xb8\x01\xbe\x9a\x4f\x96\x9d\x9c\xcd\x0e\x29\x2b\x22\xc1\x76\xc6\x4f\x6e\x7c\x61\x9d\x1a\xd2\x15\xf0\x70\xb3\x3a\xe3\x6f\x69\x9d\xdc\x08\x69\xe3\x60\x83\x99\xff\xbf\x4d\x72\xff\xb8\x89\x76\x28\x57\x00\x51\x3e\x3e\xb5\x75\xb2\x4a\x3e\x3c\xb7\x5d\xfa\xcb\x81\x4b\xf7\x88\x53\xd0\xfe\xc8\x47\xdd\xcc\x52\xff\xba\xc5\xea\x16\x79\xea\xac\xe1\x7d\xa4\x44\xc8\x33\xf8\xa1\xee\xb6\xfa\x45\xf0\xaf\xff\x41\xef\xd4\x12\xf1\xff\x7a\xcc\xcc\x3a\x13\x36\xdf\x7e\x18\x74\x3f\xca\x64\x39\x1d\xb9\x11\x0b\x47\xba\x0f\xb1\xde\x0f\xb6\xd6\xc3\x7e\x75\x88\x86\xba\x2d\x34\xfe\x4a\xa9\x09\x2e\x20\x62\xc3\x3b\xb5\x53\x5e\xad\xa3\x03\xfd\x3e\x0a\x7d\x23\x38\xcf\x4d\x92\x58\xed\xc7\x5e\x1e\x29\xb4\x3d\xab\x7d\x89\x1a\x31\xe0\x44\x78\x34\x87\x6b\x9b\x06\xc9\xb5\x8e\x66\xe5\xe1\x60\xe3\x87\x23\xc9\xf9\x8e\xe8\x87\x1d\x53\x78\x93\x53\x04\xcc\x16\xfb\x89\x3e\x38\x6f\xc4\xe4\x36\x9e\x91\x44\x7b\x27\xf6\xc2\x3d\x88\x83\xda\x61\x58\x5d\x87\x4f\x97\xfd\xb1\xf0\x01\xe7\xa5\xcc\x83\x43\x21\xa6\x76\x6c\x64\x70\x2b\xfd\x3a\xf5\xd4\xd5\x6f\xb6\x25\xde\x49\x01\x58\x55\x57\x96\x20\x9e\x70\xcb\xed\xba\xff\x80\x6a\xa8\x07\x67\x86\x6a\x7b\xff\x80\xe5\x50\xb0\xc3\x22\x9a\x64\xe9\x04\x51\xec\x65\xa4\x2b\x15\x76\x74\xd7\xcc\xee\xfa\xed\x45\xe7\x0e\x7f\x00\xbc\xe2\x6e\x1f\xca\xdf\x3c\x6c\x68\xf5\x36\x76\x9b\x09\xfd\x41\x0a\xb7\xb0\x45\x67\x4e\x1c\x9c\x72\x47\xc7\x28\xd1\x92\x56\x3e\xd2\x5b\xb8\x28\x9d\x5a\xad\x21\x6e\x23\xad\xfc\x7d\x0a\x6f\x38\xe5\x13\x75\x26\x0d\xca\x19\x84\x2d\x44\xe4\xf6\xc2\x27\x06\x51\xcf\x7b\xba\xf6\x6e\x73\xcc\x22\x7c\x19\xfb\xc9\x3c\xa8\xd8\x06\x61\x2a\x05\x45\x32\x39\xdf\x33\x8c\xdc\xf9\x2c\x3b\x49\x92\x14\xc8\x54\x25\x6c\x50\xb5\x5f\xa1\x3b\x9e\xfb\x35\xe0\x0a\xd9\xca\xfa\xfc\xc4\x95\x7b\x6b\xf1\x3d\xb0\x9a\x0a\x94\xc2\xce\x04\x0d\xe0\x1b\xc4\xaf\x04\xf4\x62\x72\x71\xb7\x44\x4a\x25\x61\x8a\x70\x9e\xc2\x46\xb7\xf0\xe6\x06\x54\xf4\x44\x47\x30\xd0\x8b\x90\x59\x83\x4d\x8d\xb8\x3c\x9b\xad\x4b\x7a\xd5\x15\x12\x72\x1f\xcd\xa1\x4b\xda\x58\x11\xc3\xc0\x96\x6f\xd2\xc9\xe9\x3e\x68\x06\xb4\x98\x1a\xd8\xce\xcf\x2a\x4f\x1d\x7f\x50\xfe\x44\x81\x45\xd4\x2f\xa1\xe2\x19\x6d\xfc\x62\x1b\x4d\x06\x8d\xac\xb1\x9b\xf7\x81\xd0\x06\xf4\xc3\x28\x4b\x7e\xe9\x85\xf2\x4b\x09\x14\xbb\xca\xe2\x48\xc9\x5d\xf3\x44\x7c\x03\xcc\x3b\x01\x09\x7b\x7f\x17\x36\xe7\x37\xf2\xdd\xa5\xf7\x80\x46\xa4\xe8\x31\x92\xb1\x3d\xc0\x75\xff\x4b\x2d\xb8\x4d\x9e\x9c\xb6\xc2\xd6\x30\x87\xc2\xd9\x13\xa9\x15\x3c\xe3\x97\x36\x0f\x2c\x65\xd2\x71\x8c\x96\xbf\x6f\x9d\x96\xf9\xe5\xaf\xe7\x9d\xfe\x87\x62\x2d\xd8\xfb\xb7\x19\x77\xd4\x40\x77\x29\xc3\x68\x91\xdd\xca\xa2\x2d\xc6\x92\xc3\x82\x86\xe1\xc0\x1a\x1e\xad\xed\x1f\x46\x46\x08\x02\x24\x7f\xc0\x7e\xb6\x81\x14\x00\xff\xe9\xff\x40\x36\xc4\x07\xff\x2b\x92\xad\xfc\x15\x38\x7f\xd2\x57\xe0\x8f\x82\x51\x89\x03\xec\x84\xf0\x84\x08\x67\x03\x6c\x89\x1e\x57\xb6\xef\x09\xb9\xa5\x9d\xa6\x51\x0b\x4e\x35\xa8\x60\x53\x55\xbb\x60\xaa\xf3\x17\xd1\xe8\x3e\x1c\x43\x11\x7d\xee\x9f\x44\xa0\x43\x13\xbc\xa3\xcc\x8f\x80\x32\x3a\x35\xab\x27\xb1\x40\xa7\x79\xac\x56\xcf\x3c\xfe\x1f\xe3\xe3\xa2\xf7\x7f\x0e\xc2\x3a\x5a\x16\x1d\x35\xa7\x53\x76\x8d\x1c\xef\x43\xd6\x0e\x3b\xfa\xf6\x3c\xed\x63\xa7\xf4\xe1\xda\x69\x83\x4c\xcf\xab\xf7\x22\xab\xab\xfa\xf3\x03\x8e\x58\xba\x14\xd6\xab\xcc\xbb\x7d\x50\x69\xbd\x7e\x62\x90\x83\x26\x10\xaa\xb9\xb1\x7e\xbf\x4c\x3c\x6e\xa2\x1a\x68\xae\x43\xf1\x6c\xe7\x92\xe3\x0c\xe7\xfc\xcb\xe4\x10\xf4\x40\x5a\xd7\x58\xae\x80\x3e\xd6\x38\x0e\x5d\x50\xed\xd7\x3c\x48\xcb\x3a\xce\x67\xc4\xd6\x45\xea\x88\x53\x88\x88\x59\x84\xd3\x8c\x0d\x9e\xff\xb8\x60\x71\x47\x62\x57\x5f\x3c\xc3\x9b\x86\xb7\x46\x0f\x87\x3d\x6e\xc5\x72\x48\xa8\x09\x20\x84\x91\x79\xe9\x0c\xc9\xb5\x40\x62\x44\x77\xd0\x2c\xe6\x59\x6d\xd3\xe7\x80\x03\x2d\x30\x3d\xab\x43\xdf\xe5\xb3\x79\x81\xf9\x88\x98\x88\x55\x53\x6e\x7f\x08\x48\x84\x4b\xf9\xb3\xc4\xe3\x57\x77\x03\xb2\x03\x1b\x1b\xcf\xf9\x94\x58\x18\x9f\x64\x16\x0a\x02\xca\x16\x91\x4d\x67\x32\xd0\x97\x8b\x56\xc7\x1c\x49\x0a\x00\x67\x23\xbf\xc5\x36\x52\x04\x2a\x30\x37\x39\x06\x91\x0f\xd9\x54\x06\xcc\x11\x43\x87\x14\xb2\x70\x8c\xbc\xba\x77\x1e\x44\xf8\x3c\x81\xbc\xd1\x44\x0c\x27\x93\x24\x91\x27\xba\x15\xb5\x78\xf2\x21\x56\xa8\xa1\x1e\xa7\x32\xf8\xba\xfa\xbf\x2a\xaa\xbe\x95\x3f\x0f\x47\x3e\x56\xe1\x1e\xab\xb4\x6d\xc3\x1c\xdc\xc3\xa1\x61\x33\x43\xde\x96\x46\xd1\x7f\x38\x95\xe1\xd7\xd7\xec\xbf\xe9\x60\xd9\x8d\xad\x61\xf0\x0a\x48\x5a\x04\x26\x51\x4e\x0d\x74\x57\x68\xf8\x7b\x49\xbf\xfa\xb0\x9a\xb1\xc1\x44\x62\x39\x7c\x92\xb8\xb4\x79\x02\xb5\x4a\xfd\x72\x45\x38\xf5\x45\xf4\xbb\xf7\x1d\x9d\xa0\x8c\x60\xf1\xa3\xcc\x8c\xf8\xe9\x00\x09\xd6\x16\x6a\xd7\xd3\x8c\x2c\xfe\x48\x6a\x70\xda\x76\x95\x90\x7f\x0f\x0b\x11\x49\xb1\x53\x1d\xa6\x33\xe8\xfb\x91\x06\x22\xa2\x4c\xcf\x2e\xe4\xc3\x39\x0a\xa2\x9e\xc0\x6f\x63\x09\xbe\x02\x5f\x36\x6d\x47\xb4\x5b\x9d\x8f\x10\x8d\x7b\xe7\x24\x88\xb1\x91\x86\x12\x1c\xde\xae\xde\x4b\x48\xed\x10\xdc\x1d\x18\x85\x24\xcd\xf5\x6c\x36\x5f\x7b\x0b\x9c\x46\x2f\x8f\xe9\x1c\xd0\x65\x07\xbb\xa0\x84\x11\x57\xb6\xd5\xcc\x6b\xfc\x33\xac\x89\xcb\xa7\x59\x1d\x93\xfa\x50\xf6\xb2\x11\x3f\xa0\x79\x3f\x58\x05\xca\x72\xed\xd6\x1f\xaa\x61\x97\x46\x33\xe5\x02\xbe\x12\x3e\xcc\x4e\xa9\x22\xbd\x7e\xbf\x57\xf6\xfc\x27\x08\x08\x78\x9b\xe2\x80\xbb\x3c\x10\xc8\x01\xa3\xfe\x2e\xa4\xd9\x5b\xa5\x15\x41\x80\x1f\x2a\x0b\x51\xc2\xab\x17\x89\x21\x22\x39\x84\x0f\x84\x1f\x6a\xe7\x73\x81\xd8\x04\xa1\x3e\x48\x10\xa7\x8b\xb4\x0a\x7c\x81\x2e\x9a\x9d\x8a\x41\xbb\x6f\x24\xc3\x40\x0a\x0a\x9b\x7e\x25\x4a\xb2\x0d\xba\x84\xe8\x20\xe8\x0f\x61\xeb\x75\xe3\x56\x1f\xa1\x22\xa0\xb7\x17\x4b\x5b\x1c\xc7\x2a\x06\x7f\x38\x31\xab\xc7\x9b\xce\xf9\xeb\xdd\x1f\x8c\x77\x61\x0e\x1b\xd5\xd8\xb8\x1d\xc7\xf5\x98\x64\x06\xf6\x0b\xbd\x4e\xda\xbc\x7d\xeb\x91\x78\xfc\x99\xe6\x7c\xb3\x38\x5b\x5f\xf7\x3b\xfc\xfa\x68\x3a\xd3\xb0\xcf\xa4\x2c\x08\xea\x01\x61\xc1\x9f\x6c\xb5\x08\xbf\x32\xb7\x4b\xc7\x33\x3f\xff\x5e\xad\x9f\xd0\xef\xd8\x4c\x22\x9a\x42\x0b\xff\xb1\xd1\xb3\x21\x07\x25\xeb\x53\xbd\xad\x36\x22\xf7\x5f\xd0\xe7\x1b\x3c\x2a\xdd\x85\x47\x0b\xdd\x70\x2f\x39\x0e\x02\xd9\xf8\xc7\xf3\xf8\x1d\x72\x47\x04\x19\x2e\x91\xcf\xfd\xf9\x05\x7f\xdb\x5b\xd0\xde\xcc\x8a\x61\x5d\x46\x28\x8b\x19\x92\xf8\x2a\x5e\x97\xbd\x8a\x9f\xdf\xaf\x39\xd2\xb7\x6d\x0b\x7c\xce\xc1\x3e\x70\x37\x97\x87\x67\xb3\x10\x98\x48\x7a\xc7\xaf\x14\x6e\x3f\xb0\x2d\x4c\x91\xed\x43\xdd\x38\x99\x9b\xed\xcf\x7f\x7c\xc3\x7a\x49\x03\xdc\x27\xda\x5f\xd1\xe3\x52\x06\x0a\x6b\xef\x8f\x4e\xd4\xdb\xbe\x06\xa5\x7c\xbf\x43\xc3\x72\x57\x47\xf3\x65\xff\x05\x1c\xd9\x77\x5f\x77\xed\x42\x74\x1e\x95\x1e\x48\x07\xd5\x8f\xb6\x30\x55\x2a\x0b\xea\xa5\xf0\x16\xb7\x36\xe0\x72\x75\xc7\xe4\x7a\x13\x2b\x84\xd2\xc0\x0f\x2c\x3b\xee\x19\x79\x47\xfe\x3f\x62\x47\x77\xcf\x61\x5c\x1d\xc1\x59\x7e\xa2\xdf\xf3\x20\x42\xfd\x9d\x1d\xd6\xbb\x1b\x29\xfa\x4e\x7d\x64\xc5\x34\xd4\xa2\xca\x77\xab\xf1\x9a\xa8\x4a\x0f\xa9\xb9\xfd\x41\x6a\xc4\x19\xa1\x53\x1e\x1f\x37\x34\xd0\xc3\x6a\x54\xc5\xc7\x74\x0d\xf9\x90\x33\x75\xfa\x34\xb6\x44\xdc\x97\xc2\xca\xec\x28\x3b\xb6\x42\xe4\x41\x94\x96\x58\x0e\xf4\x23\xb0\x8f\x71\x17\x2d\xc3\xd3\xcb\x15\x23\xb9\x27\xea\xd7\x05\xf7\x5b\x41\xfa\x86\xd5\xb9\xa2\xcb\x59\x50\x82\xd3\xb0\x54\x29\x06\xa8\xa3\xb7\x85\x87\xf7\xa4\xb0\x32\xb0\xe1\x34\x33\x91\xdc\xfd\x74\xaf\xdc\xe4\xef\xe8\x5b\xed\x31\x08\x9d\xc0\xb9\x0a\x21\x89\x33\xda\x71\x91\x55\x68\x48\x95\x0b\xf4\xdc\xc8\x0e\x73\xc3\x46\xf8\x9e\xd2\xfb\x16\x74\xc8\x9c\x19\x8d\x88\xb5\xd8\x17\x1a\xa4\x70\x37\x42\x13\x32\x22\x71\x45\x4a\xe1\xa0\x70\x7e\x22\x5a\x06\xf4\x40\x07\x1e\x6a\xec\xed\xce\x3a\xec\x2d\x90\x86\x5a\x1a\xb0\xe7\x98\x4a\xf3\x56\xa8\xe4\x05\xbd\xe8\x83\xc0\x08\x09\x0f\xe2\xf2\x9f\xc1\x9c\x05\x93\xed\xd2\xd1\x9f\x33\x15\xee\xd6\x90\x97\xae\xbe\x10\x62\x07\x57\x0d\x1a\x25\xdc\xb6\x4a\x91\x49\xd3\x31\x5c\xf0\x4c\x61\xb7\x06\x8b\x7a\xce\x9b\x20\xfe\x3e\x18\x51\xf3\x70\x8c\x84\xd5\xdc\xff\xea\x4f\x1f\x0e\xbe\x84\xcc\xc4\xa1\x89\x9f\x76\xdf\x1a\x1e\xa7\x78\x12\x25\xd2\x15\x6c\x34\x9c\x61\x90\x06\xed\xb6\x72\x51\xec\x8f\x49\xb4\x02\x70\x28\xd8\x15\x3d\xca\x7c\xe9\xaa\x3b\xa0\x20\xe6\xac\x75\xac\xe5\x0e\xbf\xb4\x9b\x93\xf4\x41\xa1\x27\x60\x15\x09\xee\xe7\xbc\x44\xc6\x20\x24\x32\xfc\xdf\x4f\xda\xb5\x81\xa6\xce\x78\xf8\x7c\x37\x19\xea\x91\x01\x10\xea\x19\xc1\x19\x02\xef\x67\x2f\x2f\x11\x3a\x60\xb7\x49\xda\xc5\xdd\x74\x0e\x56\x4b\x93\xb7\x76\xa0\x2f\xc8\x27\xb9\x62\x4c\x9a\x85\x88\x00\x3c\xf8\xe3\x1e\xf4\x1d\x28\x81\xf9\x96\x30\xbd\x16\x48\xb5\x97\xb4\x88\x67\xe1\x97\x8a\xa7\x5e\x16\xef\xc5\xfb\xd0\x2f\xa4\x3d\xbf\xc9\x82\x74\x7d\x1d\x5e\x66\x67\x07\xce\xc3\xe1\x14\xe3\xb3\x10\x6e\xdc\x7f\x96\xe4\x36\xc1\xa8\x0a\x00\xd8\x31\x86\xbd\x9a\xa4\x1e\x50\x1a\x44\x4e\xcf\x3a\xdf\x0a\xea\x99\x04\x19\x30\xc6\x9b\x50\x07\x00\x0b\x9d\xda\x9b\x82\xf7\x40\xa5\xe0\x0d\xfd\x86\xb4\x78\x99\x9d\x8d\xb2\x15\xc3\xc8\x63\x7d\x42\x4c\x70\x36\x61\x41\x1f\x57\x26\xac\xb1\xcf\x57\x8b\xdd\x41\xdf\x88\x43\xd1\x13\x9d\x84\x41\xcb\xb3\xbb\x8a\x8b\x81\x73\x27\xa8\x54\x5b\x72\x84\x3d\x89\x9e\xd1\xe8\x15\x0d\x52\xa1\xfa\x6f\x6b\x3c\x8f\x24\xad\xcb\xd6\xfc\xe8\x20\xb1\xe1\xbf\x8a\x83\x1c\xd3\xec\xf4\xe1\x03\x86\x53\x20\x49\x6f\x53\x18\xa1\xf0\x4d\x54\xd9\x0d\x00\xf0\xad\x30\xfa\x1a\x70\x47\xff\xfd\x84\xae\xbe\xf6\x0a\xb1\xef\x1b\x36\x87\x9e\x8f\xdf\xe6\xde\x06\x1c\xc1\x36\x7a\x27\x31\x63\x22\xdd\x43\x70\xe8\x3a\x1f\x8c\x96\x58\xff\xf5\x10\xf5\xac\x4e\xa9\x28\xd6\xb9\xb9\x91\xe0\xb2\x74\x16\x85\xed\x43\x9d\x4c\xb3\x66\x27\xe7\xc3\xc2\x9b\xcf\xcb\x49\x09\xf5\x8a\x47\x5e\xd3\x5b\x72\x7f\xdb\x3a\x0f\x0a\x0d\x58\x53\x73\xa6\x5f\x93\xbc\x61\x16\x5b\x80\xc5\xb0\x20\xf1\x02\x2d\x73\x6e\x73\x96\xd3\xe5\x42\x91\xe8\x99\xbb\xab\x0b\x76\x85\xb2\x5c\x96\x5d\x11\x46\x80\x3e\x3c\x46\x48\xcd\xf4\xc5\xed\x08\x7c\x90\xc0\xd6\x14\xfc\x71\xcb\xdb\x1c\x34\x0b\x8f\x86\x16\x3c\xb2\x04\x4e\x32\x9e\x22\x5f\x34\x8f\x3f\x30\xf0\x5b\x1e\x91\x13\x30\x7c\xff\xbb\xc0\xc7\xe3\x01\x94\x03\xe8\xb4\xfa\x27\x7f\xfa\x2c\x7f\xe1\xa8\xf3\x57\x09\x1f\xc0\x32\x80\x3b\x0a\x44\x98\x33\x78\x88\x9a\x6f\x0c\xe7\x77\x5c\x53\x8d\x20\xe5\xaa\x0b\x3f\xd2\x43\x8e\xd6\x23\xd3\x87\x66\x6b\x7c\x67\x13\x73\xa7\xe0\x1a\x17\x4e\x03\xcf\x27\x18\xb3\xc1\xf4\x90\x6a\x6d\xaa\x91\x0c\x6a\xfb\x11\x62\x23\x4a\x04\x06\x1b\xef\xe2\x31\x52\xca\x6d\xa8\xe0\xd1\x71\xe4\x66\xdc\xd6\xb3\x44\xd5\xfc\x44\x9f\xfe\x49\x7a\x4c\x78\x0c\x34\x42\x07\x8c\x33\x9a\xa5\xdc\x6c\x55\xf1\xdc\xa0\x91\x5b\xc6\xf5\xc4\x49\x98\x97\x04\x79\x2d\xc9\x1c\xf5\xb8\x9b\x92\x62\x9c\xe4\x3e\x70\x87\xa0\x42\x0e\x05\xe9\x6c\x16\x02\xdb\x26\xd0\xc7\xb6\xdb\xbc\x65\x0d\x75\xd8\x44\xf1\xd1\x94\xc6\x86\xc1\x8c\xf1\x0e\xc7\xea\xad\xe3\x8b\x43\x30\x16\x9d\x97\x51\xd1\x98\x50\x4e\x12\x62\x97\x4a\x0c\x22\x59\xa9\xf0\x42\x02\x38\x22\x37\x02\x9d\x71\x23\x29\x4d\x0c\x2c\xbd\x62\x24\x02\x88\x14\xe8\x23\x5c\x27\x08\x77\xd4\x16\xc0\xe4\x66\x8b\x1c\xc2\x35\x4a\x8c\x8f\x96\x5d\xfe\xb4\x3d\x3e\x1d\xdf\xea\x3f\xe5\xc3\xb3\xca\x12\x1c\xbe\x88\x72\x16\x80\x09\x51\x34\xad\x9e\x72\x84\x79\xb6\xc0\x0a\x1b\x31\xcd\xea\x69\x57\x3e\xd9\x1f\x79\x8b\x52\xeb\x39\x13\xd0\xb6\x6d\x03\xe5\x17\x11\xde\xb4\x08\xd6\xb0\x4f\xab\xcc\xba\x67\x3a\x27\x17\x1b\x3d\x13\x82\x0a\xe5\x21\xf8\x4c\x23\x03\x4c\x79\xf9\xe7\xff\x56\x96\x61\xf6\x2f\x7c\xc2\x40\xfd\xe4\xd4\x0f\x59\x45\x35\x35\x0d\x1c\xc6\x15\x12\x31\xd4\x5d\x9b\x54\xa0\x16\xb3\xb4\x42\x36\x9e\x45\x79\x1c\xce\x14\xde\x71\x68\x58\x1d\xe2\x60\x94\xda\x45\x26\xf0\xa0\x7d\xc9\x10\xfa\x3c\xbb\xa4\x83\xe4\x31\xc5\x52\x3c\xcc\x17\xb1\x8e\x19\x69\xb4\x64\x73\xc0\xa6\x86\xb7\x49\xcf\x31\x5b\xed\x2b\x0f\x39\x94\x48\x3e\xb8\xd4\xd0\x47\x36\x6a\x9e\x48\xfa\x08\x83\x8d\x21\xcb\xe1\x78\xc8\xca\xd9\x82\xb5\x9c\x40\x15\x9f\xe6\x42\x82\xeb\xd1\xd7\xdc\xf5\xc1\x90\x9c\xe7\xd5\x90\x18\x95\x00\x96\x93\x64\x5e\x7d\x5d\xc3\x49\xfc\xac\xdf\x16\x9c\x3a\x78\x37\x1b\xb4\xb4\x66\x3c\x8e\x19\x95\x0b\xd3\x2f\x12\x00\xf9\x4f\xc4\x4b\xa2\x7b\x49\xaa\x87\x0f\xca\x1a\x13\xb9\x2d\x06\x81\xc8\xec\xa2\x5f\x00\xe6\x5f\x67\xf6\x98\xfa\xe2\x79\xd4\x64\x85\x74\x81\x79\xb8\xdf\x8d\xca\x9f\x1e\x93\x81\x84\x3f\xbd\x15\xf6\x76\x62\x8e\x14\x74\x4c\xe5\x6f\x17\xf3\x13\x7b\xe0\x30\x32\x00\xe5\x43\x9c\x15\xef\x23\x89\xe8\x91\x42\xd3\x71\xe9\x93\xda\x2a\xf6\xe6\xb1\x0b\x87\x84\xd4\xa5\xbf\x44\x11\xc8\xda\x83\x00\xe5\xc3\x99\x0a\x0e\xd1\x9b\x20\xa0\x22\xdf\xe3\x6c\xa2\xe7\xae\xee\x71\x54\x76\x49\x57\x83\x2d\xe1\x31\x53\xe1\x6b\x17\x1e\xe9\xb2\xa6\x9b\xe5\x92\x8e\x5e\x77\xcf\x91\xbe\x02\x7f\xe9\xe6\x7b\x2e\xf3\x70\xdb\xbf\x92\xdd\xd5\x95\x4f\xab\x03\xbb\x72\xd2\xf6\xa1\x2b\x41\xde\x98\x0a\x43\x7f\x9c\xb2\xc1\xdb\x60\x46\x42\xdf\xb7\x02\x6c\x47\xaf\xac\xb5\xcb\xf5\x1d\xa2\x48\x75\xb3\x14\xe9\x1d\x2d\x9b\xba\x68\x58\x38\x83\x51\x4e\x4b\x18\x87\xd3\x81\x48\x1c\xa4\x5d\x76\x9c\xd0\xe0\x6e\xa7\xf8\x0b\x1b\x86\x19\x7b\x68\xa2\x6c\xe0\xc8\x26\x86\xe9\x0b\xe2\x06\x9d\xe9\x3e\x52\x6c\x04\x0a\x65\x33\x97\xac\xea\xa4\xd3\x45\xcb\x43\x47\x3e\x63\x95\x60\xc6\x66\x91\x10\xda\x80\x72\x21\x92\x8d\xed\xf6\x57\x40\x24\x7c\x87\xf6\x11\xe5\xe4\x8b\xcb\xc6\x31\x8f\x54\xc9\xa1\x04\x17\x36\x3a\x3c\x49\xf8\xbb\x5d\x2e\xf1\xce\x52\x30\x60\xd3\x26\xf0\x5c\x7e\x09\xb4\x4b\xb8\x9b\x3d\x82\xd0\x63\x3a\xb1\xcf\x31\x12\xfc\x33\xff\x84\x65\x0c\xcd\xf2\x0d\x2c\x8c\xd8\x39\x69\x20\x52\x16\xc6\x23\x17\x45\x24\xce\xab\xfe\xb2\x8c\xfb\xa6\x53\x4b\xd6\x97\xee\x35\x5f\xa4\x1e\xda\xa7\x74\x4e\x48\x99\x88\xd0\xe0\xcb\x98\xe8\x66\x07\xb8\x46\xc0\x4c\xc8\xc3\x3e\x89\x0e\xdd\x36\xd7\x28\x48\x6b\xfe\x4f\xc0\x4b\x33\x58\x87\x09\xb9\x23\x24\xd3\x7c\x5f\xac\xcb\xdf\x50\xbf\xbf\x1b\x9e\x92\x3f\x22\x29\xbf\x43\x1b\x82\x8d\x8a\xc3\x3c\x24\x18\xc4\xb9\xfe\x76\x87\x8f\x9f\x53\x7c\x5a\x4f\xd2\xc8\x6d\x24\x7d\x82\xfb\xb9\x3b\x49\x04\x96\x0d\x2e\xed\x98\xed\x4b\xdf\x89\xc5\x90\x54\xf5\xca\xa7\x7c\x19\xf6\xfc\x0d\xce\x48\x8e\x44\x8c\x17\xca\xdb\xf3\x21\xcf\x3e\x5f\x13\xdd\xa5\x21\xfc\xda\x0b\x51\x03\xff\xc3\x73\x61\x32\x87\x83\xa4\x24\x75\x3a\xa5\x18\xd9\x83\xbb\x51\xd1\x68\x70\x27\x05\xb0\xfc\x68\xd6\x87\x95\x4e\x4c\x0d\x5b\x1f\xe4\xa0\x7f\x97\x8f\x00\x13\x3d\xb3\x30\x07\xa7\xb4\xb1\x3f\x0a\x00\x0a\xf1\x91\xdd\x56\x5c\xbf\xa2\x6e\x42\x41\xb7\xbd\x21\xdf\x79\x61\xb7\xf2\x43\x75\x26\x38\xf3\x73\x20\xaf\x91\x7b\x4a\xcb\xe2\x08\xf9\x1d\x67\xf9\x1d\x62\x52\x0f\xee\xba\x82\x22\x92\xee\xe6\xd5\x87\xac\x84\x16\xaa\x4b\x74\xe0\x9e\x7f\x7e\x80\x77\x6e\x26\x0a\x07\x65\x62\x82\x3e\x28\x00\xa1\x07\xa6\x9d\xec\x52\x60\xac\x3f\x37\x83\x59\x9f\xf7\x9a\x18\xb3\x49\x71\xc7\x97\xa3\x3b\x54\x1e\x27\x71\x24\x20\x21\x4d\xd6\x21\xa3\xa6\xcb\x79\x1b\xf2\x53\x78\x7b\x69\x84\x70\x04\x17\xc4\xf9\xfb\x0d\x4f\xee\x2b\x8f\x61\xfe\x03\xda\xc8\x4c\xb0\x63\xf6\xd4\x3f\xb7\x5e\x00\x14\x72\xde\xdf\xa5\x1c\xcf\xf8\xb3\x6b\xa2\x8f\x60\x91\x04\xf7\xdc\x83\xa6\xfa\xc0\x50\x9c\x69\x34\xc7\x58\x3e\xb1\x8e\x9f\xfc\x02\xb5\xde\x7a\xad\xdc\xc7\x2b\xa4\xf3\x88\xf0\xb0\xfe\x67\x5c\x76\xa5\x7a\xff\x8c\xe6\xe3\x01\x88\x8d\x7a\x50\x3f\xe2\xcb\x8d\x82\x32\xce\x4f\x80\x58\xe7\xa7\x13\xd9\x64\x0a\xbd\x47\x75\xc1\x98\xad\xc0\x11\x80\x85\x5d\x33\x9f\xcd\xb5\xcd\xa1\x94\xc0\xfe\xc1\x3d\x16\xf6\xe1\x7a\x08\x7f\xdc\xac\x36\xae\x0b\x4e\xa8\x3c\xd9\x84\xb9\x88\x2d\x03\xe2\x74\xc4\x00\xcf\x5d\x27\x44\xe5\x23\x07\x74\x6c\xf1\xfc\xe0\x93\x0a\xd0\x71\xe2\x27\x61\x3e\x7f\xed\x74\xf5\x3f\xd3\x71\xe8\x19\xe2\x45\x40\x09\x01\xc9\x0e\x45\x23\x75\x65\x2b\xea\xf0\x40\x61\x79\x08\xc6\xbf\x3b\xca\x87\x0d\x9c\x63\x85\x0a\x49\x00\xc8\x37\x06\xf7\x15\xd4\x12\x7d\xaf\x87\x07\x9f\xbe\x35\x52\x34\xca\x81\x74\xab\x9d\xd6\x0c\xe4\x00\x20\x3a\x8e\x20\x05\x61\xd9\x83\x6c\xa8\x03\xdc\x7d\x62\x17\x6f\x38\x86\xf4\xb4\x12\xbc\x99\x5e\x79\x44\x5f\xf0\x08\x56\x3b\xaa\x54\x45\x56\x01\x09\x19\x32\x1f\x4f\x40\xc7\xce\x9a\x27\xdb\x57\x3a\xd9\x4b\xe4\x67\x94\x0b\x76\xd9\xb4\x71\x68\x8a\x15\xe7\x8a\x15\xed\x19\xe1\x37\xcf\x23\x39\x4a\x85\x45\xe7\x2f\x96\x19\x16\x0f\x59\x83\xa8\x00\xcb\x60\x5f\xd1\x03\xe8\x89\xed\x74\x3d\xd6\x6b\xcf\x21\x00\xdf\xf3\xd6\xc9\x48\x68\xcf\xba\x54\x76\xce\xc3\x0e\xb3\x20\x03\x59\x64\x8e\x1f\x47\xa3\x12\x4b\xa9\x22\x47\x54\x72\x05\xb6\xca\x2d\x03\x8e\x7e\xf8\x93\x2d\x61\x65\x3b\x77\xb3\xad\x8b\x4c\xee\x4f\xd5\xcd\x5b\x09\x34\x06\x18\x3e\x29\x23\x21\x82\xc9\xf7\x97\xa4\xa0\x8d\x73\xde\x16\xa6\x7c\x5b\x26\xc0\xb7\xf5\x98\xba\x88\xad\x20\x8d\x3d\xc7\x48\xc9\xc6\x87\xad\x3b\x62\x8f\x6d\xfd\x12\x70\xd6\xd6\xcf\xb1\x8e\x80\x2e\x22\x6c\x06\xfb\x60\x3e\xb0\xaf\x7a\x49\xec\x20\x6f\xc1\x24\xff\x71\xf7\xe4\x36\x85\x4a\x29\x0b\x9f\xaa\x0d\x54\x61\xd9\x29\x02\x28\xe7\x6d\xbb\x98\x70\x8e\x9f\xd0\xdd\xe1\x8f\x16\x8e\x49\x55\xcc\x96\x26\x49\x7c\xd2\x70\x36\x64\x85\x64\x93\xb0\xbb\xc2\xc8\x21\x88\x8f\xae\xe6\xd5\xa7\x09\x51\x3e\xea\x21\x03\x1c\x9c\x2a\x2c\xd4\x57\x04\xab\x8a\x40\xba\x16\xd5\xf1\xa0\x94\xa8\x66\x59\x21\x54\x23\xf4\xf1\xca\x6c\xb9\xae\x4e\x7a\xd7\x3a\xb1\x46\x63\x77\xf5\xf4\x5a\x55\xa4\x6b\x7a\x87\x85\xc3\x5b\x86\xf9\x38\xf5\xe9\xf9\x40\x66\xd5\x9a\x84\xf1\x2d\x75\x3d\x88\x90\x34\x5e\x99\x0d\x19\xae\x5c\xbb\x72\x6b\x40\x41\xdc\x62\x1f\x58\xa0\x89\x7f\x72\x3b\x2c\xa1\xb2\x5c\x30\x71\xdf\xbc\x95\x4c\x75\x7b\x41\x2b\x20\xf4\x9a\x7b\xe9\xb4\xca\x2e\x6b\xb9\xda\x97\xa2\x3f\x7c\x04\xf5\x23\x11\x94\x53\xb0\xca\xec\x22\xd2\x36\x64\x22\x32\xf8\x18\x89\x5e\x12\x9e\x88\x4c\x22\xc9\x15\x9c\x91\xdc\x52\xd1\x04\xe9\x2d\x42\xd4\x17\x24\xbc\x11\xd0\x49\x41\x19\x58\x68\x60\xfd\x67\x9b\x81\xe2\xfb\xc4\x3f\x77\xe1\xf9\x10\x3b\x41\x76\x9e\xbb\x2d\x12\xdc\x06\x6e\xe2\xc7\x93\x7d\xfb\xf9\x29\x90\xa0\x48\x24\x37\x45\x1e\xf7\x84\x84\x0a\x62\x1e\x87\xe8\x18\x65\x09\xe2\xc0\xc4\xc0\x96\xa9\xf4\x55\xae\x8b\x58\x57\xfc\x9e\x99\xea\x52\xf8\xeb\x3b\x47\x64\x56\xf6\xec\xa4\xe0\x3e\x9b\x09\x1d\x82\xc4\xfa\xe5\x07\x51\x4e\x7a\xf9\x4d\x04\xe9\x5a\x5a\x19\x7f\xad\xbc\x21\xf2\x2c\x11\x11\x59\x45\x39\x04\x94\x12\x28\x09\x69\xa7\x53\x23\xf2\xda\x0a\x1d\x2e\x37\x36\xd1\xa0\xa2\x66\x94\xa3\xfd\x41\xcc\x60\x0a\xf0\x11\x83\xf4\xc3\x4c\x66\x21\x25\x37\xd1\x1a\xdb\x83\xea\x3e\x8f\x4d\x9b\x29\x4d\x76\xaa\x83\x98\x24\x08\x90\x72\xbc\x02\x6b\x5c\x2f\x32\x39\xf4\x35\xbb\x1f\x67\x39\x74\x3b\x54\x12\x71\x6c\xae\x83\xa4\x9b\x63\x15\x9a\x84\xeb\xc7\x6a\x10\x6e\x56\x88\xa1\x34\xef\xdd\xb1\x9d\x5f\x23\x75\xe6\x1c\xa9\x3f\x8b\x91\x2a\x95\x91\x44\xfe\xd1\xc5\x98\xfe\x46\x5d\xd1\x22\x8a\x89\x42\x83\x46\x78\x1d\xf9\xc3\x84\x19\x8c\xe9\xa5\xa3\xcd\xad\xc2\x5b\xee\x40\x75\x30\xe7\xf8\x86\x1f\xb6\xfe\x95\x9f\xf9\xa9\x28\x2c\x87\x58\x78\x43\x56\x26\xf9\x13\x32\x1f\xd9\xe7\xaf\x0a\xee\x79\x3a\x04\x1d\x1b\xb1\xa7\x00\x25\x17\xd3\xf8\x94\xfe\x54\xfe\x01\x8e\x61\xdc\x3f\x23\x1d\x3a\x18\x26\xb2\xff\x47\x33\xac\x38\xb7\xa5\xd9\x95\x3c\x73\x8b\xd0\x6e\xee\x02\x4f\x2f\x72\x1e\x61\x10\x39\x3b\x82\x22\xc5\x2a\xa6\x9d\x95\x34\xff\x2c\x52\xb9\xfb\x60\xc4\x97\xe4\xad\x7a\xed\x73\xb2\xd5\x00\xab\xf8\x21\x3b\xe1\x14\x85\xb8\x85\x2f\x34\x01\x10\xbf\x2b\x87\xec\x13\x62\x97\x41\x31\xa3\x2e\x78\x79\x08\x15\xe1\x9d\x3b\x93\xdd\x80\x8e\x3b\x98\x62\xef\x82\xd9\xae\xfe\x07\xb2\x30\x74\x5e\x0d\x39\xeb\x46\xe1\x42\x43\x72\xdb\xec\x21\x55\xf4\xcc\x09\x84\x0c\x34\x2c\x19\x92\x9c\xe4\x06\x57\xb3\xea\xfd\x5b\x11\xd9\xd1\xe9\xe2\x0c\x90\xbb\xaf\x6b\x40\x23\x55\x19\x9b\x80\x4b\x42\x3c\x53\xae\x8b\x26\x8f\x67\xf8\xca\x23\xd3\x88\x62\x9b\x33\x49\x1b\xf3\x09\xcc\x64\x97\x7f\x46\x59\x0f\xb1\x73\x01\xef\x50\x1e\x33\xfb\xe7\xec\x7d\x1f\x1e\xe9\xd9\xf9\x07\x86\x20\x86\x97\x8f\xb0\x69\x48\x3a\x99\x59\xec\x1a\xcf\xcb\x0e\xaa\x4a\x3e\x68\xfa\xde\x5b\xe5\x2d\xbf\x0b\xaf\x88\x4e\x72\x4d\x02\x06\xed\x93\x6d\xef\xbd\x80\xb4\x55\xe5\x67\x87\xb1\xca\xdf\x02\x89\xdb\x42\x6d\x12\x26\x78\x09\x64\xee\x48\x9a\x5b\xd7\x66\x40\x39\x06\x00\x63\x97\x88\x2f\x94\x48\x07\xd8\xb9\x6f\x80\x50\x26\x78\x26\x67\xb0\x4c\x58\x90\x75\x75\xf8\xb6\xf2\xbd\x62\x26\x93\xc9\x7f\xa8\x38\xce\x10\x61\x01\x4b\x19\x9b\x2c\x0f\x39\x73\xdf\x96\x2f\xc7\xff\x02\xae\xf3\xac\x9b\xe6\x4d\x82\x9c\x53\x3e\x7f\x6e\x4b\xd9\xd8\x2c\x41\xc4\x74\x1f\x8d\xdf\x59\xec\x84\xbd\x30\xac\x8c\x08\xf7\xae\x7c\x86\xcb\x0a\x46\x1f\x12\x3d\xeb\x90\x97\x4e\x41\x8c\xf0\x09\xbb\x7a\x9b\x94\xe6\x1c\xf4\xde\x6d\xdb\xf7\x4c\x64\x81\x76\x21\x4a\x77\xab\xca\x48\x14\x08\xca\xac\x2d\x8e\x65\xb8\xfc\x44\xe9\xfe\xc2\x5d\x72\x86\xe9\xb0\x0f\x7a\xb5\x08\x7d\x44\xe9\x51\xfe\x39\x4b\x9e\x12\xe9\x3b\xb3\x97\xb8\xcd\xfe\x0d\x00\x66\x8d\xd0\xf9\x2e\xcf\xa7\x32\xeb\xf0\x22\xfe\x72\xb9\xa3\x54\xc1\x29\x32\x22\xcb\xd8\x45\xe4\xaf\x61\xd3\x57\x43\x62\xb2\xe2\xc6\xcf\x3e\x8b\x1a\x43\x03\x58\x17\xe3\x28\xdc\x2e\xd2\xee\xe8\x0b\x6a\x05\x12\x71\x8f\x8b\x8b\x7a\xba\x84\x18\xa6\xf3\xcb\x48\x1a\xe0\x04\x44\x90\x12\xf5\x7d\x76\x82\xd1\x91\x83\xab\x5f\x3b\xcb\x6c\x66\x1b\x32\xb1\x18\x7d\xc3\xc9\x63\x33\x42\xfd\x85\x5c\x14\x17\xcd\x27\x82\x8a\x56\x11\x2a\x8a\xfc\x9d\x67\x16\x40\xdf\x2c\x43\x3c\x8f\x24\xf0\x23\x5e\x81\x7e\x95\x5f\x60\x33\xcc\xf1\xf9\x00\xd6\x41\x65\xf9\x89\x6c\xec\xf7\x47\x2c\x96\xb2\xca\x65\xf3\x6d\x3b\x75\x3b\x0b\xe9\x9b\xff\x76\x85\x94\xc3\x22\x91\x09\x46\xc2\xca\x3e\x22\x77\xcb\x87\xdb\x95\xe4\x74\xb9\x86\x4d\x96\xa7\xe8\x69\x3f\x00\x9a\x4b\x68\x74\x86\xd8\x17\xc1\x0b\xb3\xb5\xe1\xde\x73\x38\x7f\x4c\x45\x19\x8f\xb8\x52\xe9\x27\xf8\x56\xb3\xdf\x3e\xab\xf4\xb1\xef\x9f\x1c\xd6\x87\x7e\x24\x65\xe3\x0d\xe1\xd3\x4e\xd3\x8e\x53\x1e\x45\xef\x90\x2c\x02\x9c\x69\xb1\x7b\xbd\x80\x9b\xf8\x40\x29\x82\xd2\xdf\x54\xc6\x3e\x90\xc8\x37\x67\x5f\xc3\x5e\x50\x6b\xfb\x2d\x85\xce\xa6\x2f\xf0\xd1\x19\xb7\x50\x40\x74\x99\xf4\x36\x5e\xf3\xc9\x1d\x95\x95\x8c\xdc\x4b\xc0\x49\xd1\xef\xc9\x36\xff\xfd\x8f\xf1\x56\x2f\x9c\x3b\x95\x18\xcf\xe9\x51\x96\x04\x7e\x4e\xae\x3e\x2f\x30\xa2\x1a\xa1\x06\xea\x8e\xfc\x08\xce\xcd\xc6\x04\x2a\xc8\x20\x7c\x8f\x4e\x9a\x0d\x8b\x06\x20\x3f\xfe\xa9\xea\xa4\x65\xf1\xb6\x33\x88\x90\x8d\x7e\xda\xfb\xdd\x2c\x8c\x6d\x98\xb9\xd6\xdf\x55\xcd\x8e\xbb\x9e\x61\xb9\x76\x53\x9a\x78\xc3\x38\xd1\xd9\x06\xf7\x29\xa4\x0a\x7a\x22\xf7\x88\xe7\x98\x95\x0f\xe0\x24\xc5\x3b\xd8\xa8\xa7\xc4\x28\x51\xab\x72\x97\x43\xea\x20\xdb\xf7\xfc\x51\x60\x84\x42\x9e\xeb\xc2\x2d\x4e\xcf\x54\xb6\x4a\xaa\xcd\x94\x28\xf3\xbc\x7f\x89\x00\xb7\xb7\xd4\x05\x26\x65\x89\xf3\x6e\xab\xd6\xf9\x2e\x5a\x5c\xe4\xcd\x7e\xca\xf5\xed\xbf\xf9\x08\xef\xf4\xeb\xa3\xfe\x97\x95\x42\x89\x16\x9c\x35\x92\xf1\xea\x78\x56\xde\x32\x86\x93\xe1\x55\x95\x80\x7e\x7f\xe4\x67\x79\x0b\x7c\xb3\x19\xf2\x58\x44\xe1\x51\x66\xc4\x29\x05\x94\xe3\x54\x1c\x14\x24\xe1\xf0\xe1\x56\x49\xfe\x63\x21\xfa\x27\x93\x2a\xcc\xc4\x9b\x6c\x54\xf2\x3f\x9a\x27\x14\x02\x92\x36\xfd\xcc\x51\x26\x86\x4c\xdc\x21\x1b\x3a\xea\xa9\xfc\xc0\x43\xc8\xd3\x51\x22\xa4\xc8\x26\x22\x1a\xb6\x1c\x69\x0e\xc1\xfa\x25\x03\x98\x6b\x9b\x09\x63\xd9\x0f\x4c\xe7\x9f\xcb\x4a\x33\xa6\x47\xac\xa9\x05\x58\xd8\xa6\xe6\x0e\x53\x53\x5b\x35\x75\xf3\x90\x99\x27\xe3\x7f\x74\x2a\x87\x3c\xa3\x62\x8a\xe8\x2e\xfc\x85\x86\x94\x7f\x2c\x20\x5f\xf4\x34\x39\x68\x73\x73\xe5\x48\xbd\xe8\x4b\xc4\x1f\xce\x0a\x49\x43\x6b\x9a\x1d\x64\x4a\xa1\x7e\x4a\xa8\xca\x63\x0a\xc1\xf4\x15\x51\xba\x17\xfa\x67\x7c\xe1\x74\xb7\x88\xc4\x7d\x28\x1c\x58\x3d\xc0\x99\xf8\x54\x3c\x45\x7d\xe6\xc0\x94\xfe\x4d\x35\xb4\x8b\xda\xbf\x42\x0c\xd4\x12\x3f\x9b\x2a\xe0\x44\x82\x02\x0b\x52\x0c\xb3\x5c\x22\x6c\xbc\xc8\x19\xc5\xdf\x80\x34\xdf\xe0\xfc\xc8\x68\x14\xf9\xef\x1c\x78\xd2\xab\x4d\x13\x11\x94\x48\x32\x10\xa2\x45\x02\x64\x0a\xcb\x90\xd3\x85\x5d\x3e\xe8\x6d\xa7\x83\xcf\xf8\x3f\x2f\x29\x1c\xba\x69\x5b\x0b\xf8\x86\x9e\x2c\x22\x0e\x65\x7f\x79\x20\x3c\x81\xa5\x33\xbb\x31\xf7\x83\x04\x1f\x4a\xa2\x50\x1b\x38\x5c\x84\x7a\x8d\x32\xa3\x08\xf9\x39\xbc\x4d\xef\xaf\x35\x03\x63\x72\x6a\x8c\xed\xcb\xdd\xd6\x24\x33\x56\x05\x47\xf8\x2a\x3f\xc4\xca\x59\x84\x4c\x2d\x61\x23\x3a\x2a\x6b\x12\xe0\x14\x71\x22\xd8\xa4\x50\xbc\x54\x57\xee\xcf\x0e\xcc\x7b\xa9\xa5\x2e\x1c\x29\xf2\xe9\xed\x8a\x43\x1f\x43\xf4\x9c\x48\x7c\x29\xaf\x99\xab\x49\x18\x87\x0e\xf1\xc7\x2e\x86\x63\xc1\x14\xff\x70\xbe\x8e\xec\x54\x4e\x31\xb2\x0b\xc4\x90\x38\xee\xe5\xc9\x6d\x76\x59\x5f\x3c\x53\x4a\xb4\xf7\x8b\x55\xd0\x4f\xdf\x98\x17\x65\xa7\xee\x15\x7b\x25\x16\x84\x7b\x79\x91\xf1\xf3\x7c\x36\xbe\x82\x0c\x49\xac\x42\x13\xd1\xa7\x61\x51\x79\x23\x41\x6f\xc7\xf4\x4f\xf4\x0a\xfd\x19\x3f\x12\x45\xaa\x57\x5b\xe4\xa0\x7f\x6a\xb0\xc0\x66\xdf\x8e\xfa\xed\x1b\x9a\xcd\xaa\x6d\x30\x26\x88\x63\xdb\xe1\x2c\xf3\x6a\xc6\x2d\xd2\x6e\x90\xe3\x4e\xda\x9e\x42\x0b\x89\x4d\x1c\xe6\x4d\x45\xc8\x36\xef\xa4\xd5\xd8\x29\x24\xf6\xee\x36\x07\x36\xee\x6a\xa7\xc8\xd5\xcf\x6f\xd1\xba\xb7\x1c\x1c\x43\xfb\x4d\x84\x07\xd9\x4e\xc8\x31\x9f\x3c\x46\xde\xe2\x10\xe0\xd5\x15\xcb\xf4\xd6\xdb\xe3\x45\xe2\x80\xfe\xc9\x0b\x69\x64\x2f\x56\x67\xb3\xf9\x1f\x63\x15\x36\x8e\x61\xdf\x92\x39\x9c\xc6\x12\x8f\x69\x66\x08\x9b\x6d\xe6\xef\x8f\xa0\xb3\xfe\x94\xb0\xaa\x4f\xef\xf8\x7f\xa0\x2a\x63\x90\x3e\x74\x8b\x45\x76\x87\x7c\x4d\xef\x40\xc7\x4e\x32\x78\x08\x8a\x71\xd0\x50\xaf\x73\x91\x0e\xea\x47\xb2\x4a\xfb\x93\xff\x30\x2d\x55\x50\xd8\x10\x30\x60\x02\x57\x9d\xe2\xa6\xaa\x26\xe2\x6a\x3b\x23\xde\xf0\xe4\x87\x59\xab\x2a\x10\x20\x5c\xbc\xa5\xdc\x13\x6d\x2c\xd7\x42\xd1\xf1\x5a\xa4\xa6\x4a\x03\xda\x49\x0f\xa7\x0e\x09\x6d\x5e\xe1\x09\x11\xb2\x29\x6f\x49\xfa\x28\x2d\x85\x6c\xa1\xb7\xc8\x88\xc0\xc8\xe8\x19\xe3\x26\xa9\x04\xcb\x3c\x13\x74\xcd\xba\x96\xd7\xf4\x9e\xf8\x23\xac\x0a\x10\xb0\xa3\xc8\x45\x69\x8f\xb0\xc7\x5d\x46\xa9\xb2\x88\x49\x4c\x2b\x5d\xce\xd2\xf9\x61\x0e\x01\x55\x98\x7c\x2d\x67\xfe\xeb\x29\xae\x0a\x72\xf2\x52\xe4\x72\x5a\x82\xf6\x03\xa7\x0f\xff\xcf\x4b\xc9\xa1\xb5\xea\xaf\x39\x08\x46\xfa\x42\x17\x98\xf0\xfa\xe3\xd7\x72\x3c\x03\x18\x73\x18\x2b\x22\xeb\x3c\xc0\xd4\x9f\x9f\xcf\xce\x9f\x9e\xb7\x63\x09\xcc\x2b\x7c\xe4\x96\xc4\x50\x9a\x25\x55\x02\x5d\x2d\x43\x32\xd1\x2a\xc6\xf7\xd0\x9a\xd7\xff\x94\x3a\xf4\x97\x3e\x7d\xf9\xcf\x07\x9a\x71\xff\x12\x7b\x6c\xf3\x2b\x5a\x34\xd3\xe7\xf0\x50\x58\x52\x85\xa8\x1f\x45\x5f\x48\xfe\xa4\x55\x50\x56\xed\x9a\x44\xea\x6a\x5a\x29\x49\xa5\xd6\xef\x5b\xe6\x99\x36\xde\x82\x24\xf4\x6b\x38\xc1\x19\x86\xce\xa0\x93\xd8\xa3\x53\xe1\x53\x67\x4f\x64\x15\x04\x16\x41\x92\xa8\x83\x7e\x42\xab\x71\x8a\x66\xc9\x94\xc3\xe8\x15\x09\x1e\x04\xdd\x6c\x96\x3c\x3f\x34\x69\x5d\xd7\x1a\xc8\x97\x4c\x64\x22\x06\x1f\xdc\xa2\xb0\x60\xfd\x5c\xeb\x4c\xbf\xd5\x4f\x43\xba\x2e\xa6\xdc\xc2\x03\x29\x76\xf9\xb6\xe1\xf3\xd9\x7c\xb2\x12\x86\xe8\x17\x4b\x47\xa6\x91\x38\x32\xe4\x7b\x51\x99\xa1\x56\xd9\x22\x5b\xe1\x31\x9c\xc5\x9d\x53\x6b\xb8\xf4\x8c\xbe\x66\xf1\x39\x67\xfa\x0c\xf2\x97\x49\x5b\xb8\xba\x9c\xd4\x2c\x8e\xa5\x1e\xde\xec\x80\x5f\x6e\xd8\xbb\x14\x2c\xc6\x5e\x7b\x62\xf8\x0f\x28\x46\xa3\xd5\x22\x6c\x4b\xc9\x4d\xe3\x4f\xef\xe9\x46\xad\x34\x8b\x99\x51\x67\x05\x67\x28\xea\x20\xdb\xfe\x5f\x11\x5c\xf9\x1d\x84\x6a\xcd\x90\x48\x38\x41\x49\x92\xc5\x67\x55\x80\x1a\x5d\x5d\xea\xc2\x64\xa0\x67\x1d\x85\x67\x55\xd9\xc0\x3e\xdb\xea\x84\x5c\x13\xd5\xaf\x4f\xd8\x7d\xf9\x72\xfa\x14\x0c\xf2\x0c\x7f\x1d\x24\x6d\x79\xf2\xa5\xbd\x47\x02\x69\xfc\xd5\x9e\x84\x9d\x84\x8b\xa5\x33\xe2\x27\xed\xed\x93\xaa\x94\xb4\x13\x78\x26\x36\xfc\x32\x75\xe3\x19\x3a\xf8\x55\x43\x9a\xc0\x3a\x85\x1f\xcf\xf6\xce\xc3\x27\x06\x8e\x7d\x2d\x01\x6c\x8d\xde\xe9\x63\xc8\x0d\x99\x39\x1f\xd9\x46\x0d\x55\xf4\x1b\x12\x3d\x87\x3a\xf1\x2f\x99\xa6\x0e\x9e\xce\x79\x71\x24\x16\xd1\x89\x94\x2e\xde\xc9\x88\xc9\x52\xf4\x1b\x0f\x92\x54\x80\xfb\xa1\x81\x5f\xae\xe4\x06\x0c\x40\x9e\x31\x3d\x3e\xa8\xb2\x3a\x77\x49\x75\xad\x8e\x2c\x44\xbe\x3c\xfc\x5c\xd4\x21\xa9\xc7\x86\xc8\xae\x1f\xf2\x73\x8e\x4b\x6d\xc8\xee\x68\x87\x2d\xac\xfb\xd5\xca\x55\x60\x48\x84\x39\x06\x8f\x8d\x18\x59\xf4\x0f\xc9\xaa\x63\xfa\xca\xd8\xe2\x27\x2b\x5a\xe7\x26\xa0\x9b\x21\x25\x54\x55\x47\xad\xaf\x6c\x82\xf7\x41\xa2\x46\x9f\xa6\x17\x6c\x76\x88\x6d\xe4\x67\x49\x1f\xfa\xf7\x5e\xf5\x47\x2f\x9a\x45\x5f\xce\xaf\x7c\x5c\x8a\xdc\xcb\xfb\x12\x0a\xaf\x35\x64\x5d\x2b\xdb\xce\xd4\x6b\x05\x27\x0f\x7e\x6f\xac\xe8\xfb\xc2\x96\x4c\x5f\x84\x8d\xb7\xd8\x4c\x8c\xe7\xbd\x0f\x3a\xd4\x0c\xd2\x15\x51\x34\x45\x69\xfa\x78\xbe\x64\x3d\x83\x1f\x60\x23\xef\x08\xce\x06\xfe\x9a\x4c\x20\xf7\x21\x32\xe3\x15\xca\x02\x86\x9b\x0f\x9e\x69\xc5\x95\x68\x4b\x24\x7b\xa0\x7d\xf8\x31\xf4\x49\x4e\x33\x67\x88\xbc\xfa\xb4\xe9\x96\x4e\x6e\x34\x90\x63\x10\xb6\x3b\x7e\x16\x35\x81\xcf\xed\x7a\xab\x09\x0a\x5f\x9a\x21\xf6\xb6\x07\xe2\x11\x06\x28\x0d\x75\x6b\x5e\xb4\xc4\x8f\x6a\x03\xb5\x29\x02\xf3\x41\x38\xcf\xd8\xc5\x2b\x20\x09\x6e\xb4\xe2\x32\x21\xfa\x9c\x19\x2d\xf5\xa2\xa9\x0d\x12\xec\x1b\x5c\x16\xd1\x94\xb6\xe1\xa7\x60\x6c\xbe\x3a\xdd\x05\x02\xc9\x3f\x78\x1b\x31\x38\x47\xdb\x74\xbd\xda\xa4\xfd\x0d\x57\x97\x53\xeb\x15\x3c\x52\xde\xed\xb6\x4d\xea\x7f\xf7\xb0\x41\x39\x4d\xc8\xed\x13\x34\xa8\x77\xa4\x6e\x96\x08\x7e\xef\x3c\xbc\x97\x0f\xdb\x29\xc5\x83\xcd\xad\xdb\xe4\x72\x9c\x64\x19\x53\xb2\x88\x50\x9f\x4b\x1a\xc1\x0e\x29\x5d\x29\x94\x69\xc9\xff\xf1\x3c\x0c\xa4\x48\x89\x09\x96\x95\xc8\xd2\xd9\x36\x37\x32\x60\xee\xd8\x30\xe2\x52\x0c\xe2\xd4\xf8\x0c\x87\x5b\xb0\x53\xf8\x48\x71\x58\x5c\x17\x49\x63\x9a\x5f\xe1\xee\x90\x1a\x77\xe5\x9d\x7b\xc7\xf9\x60\x1c\x74\x67\xa4\x12\xa1\xe1\xc0\xb9\xd4\xae\xe0\xab\x31\x28\x12\x3b\x47\x60\x01\x12\x5b\xb3\x3d\x7e\x38\xcd\x9c\xcc\xb3\x4a\xb6\x98\x90\xda\x84\xeb\xd9\x6f\x01\x0e\xed\x13\x74\x92\xfd\xba\x5b\x8b\xfa\x0b\xac\xae\x2b\xb7\x43\xc8\x45\x12\x79\xad\x69\x46\x91\xed\x68\x9c\xb7\x75\x82\xdc\x34\x70\x8e\xb0\x2b\x98\x90\x1e\x4c\x78\xf1\xf8\xaf\xcd\x3f\x59\x84\xa6\xbc\x75\x14\xa0\xf5\x6e\x8f\xfb\x20\xde\x46\xc0\xed\x2d\x74\xe7\x7d\x32\xea\xf2\x5d\x34\xf3\x03\x79\xbb\x62\xb8\x6a\x9b\xf1\x6e\x85\xa8\x4d\xe7\xbd\x60\x36\x50\x09\x9b\xd9\x8d\x2a\x06\x8a\xc9\x6e\x62\x6e\x8b\xd2\x41\x67\xf1\xc9\xdf\x73\x00\xa1\x74\xc2\x51\x34\x4d\x8e\x08\x6c\x3b\x0f\x6f\xa2\x67\xca\xe9\x7b\xd3\xf9\x3b\x0c\x14\xde\x79\x0e\x98\xec\xa7\xd1\x7a\x27\x05\xab\x02\x15\x5b\x35\x3a\x89\x7e\x8d\xb4\xbc\x69\x06\x6d\xaf\xb9\x87\x4b\xad\x10\x30\x84\x13\xfa\x60\xef\x67\xc9\xca\xbe\xaa\xab\x5f\x2e\x35\xf3\xc1\xfe\x65\x06\xac\x8d\x5e\xc2\x5e\x51\xf7\x83\xb0\xa4\x9b\xff\x0f\x07\x0a\xab\xda\x2b\x8b\x31\xa5\x3f\x84\x9c\xd1\x3c\xa1\x7e\x58\x01\xd6\xed\x98\x9a\xa9\x2e\x51\x34\x9e\x84\x77\xbd\x83\x28\x75\x9e\x6d\x67\xed\x52\x34\xdd\x3f\x36\x05\x5a\xa5\xe5\x04\x9c\x6b\x98\x80\x71\x6b\x21\x63\x9c\xcd\xe3\xc7\x99\xe2\xb8\xe9\x5d\xee\x58\xe8\x6e\xe4\xaf\x11\xfa\x9a\xc0\x2f\xa3\x6d\xef\xbf\xc2\x43\x3b\xd3\xc5\x8c\x42\x2b\xdc\x31\x37\xfb\xec\x03\xb9\xaa\xb7\x5d\x08\xb4\xda\xd9\x9b\xd4\xfe\xf2\x4c\x43\x1f\x0c\x81\x1c\xd9\x67\x0a\x91\x59\xb3\x90\xbd\xc5\xcd\xc4\x44\x43\x92\xa1\xbb\xf7\x4a\x84\x65\x5f\xe9\xbb\x19\xf3\x84\x5f\x2a\x86\x13\xed\x77\x4a\x55\x68\x4e\x21\x9a\x76\xbb\xe2\x21\x72\x56\x61\xc4\x14\x34\xac\x10\xab\x85\x4a\xeb\x46\xc1\xbd\x5f\x91\x35\x78\x35\xbf\x20\xdf\xa3\xac\xba\x22\xaf\x43\x7a\x29\x48\xd7\x48\xa1\x42\x76\xab\x0a\xd8\x2b\x92\x81\xe0\xe4\xeb\xff\x67\xaf\xac\x4b\x3d\x46\x27\xb6\xa9\xd7\x16\xd9\x3e\x9b\x26\xb6\x0b\x3d\x3d\x25\xbf\x2e\x32\x13\x90\xd6\x0d\x23\xf8\x8f\xfa\x4d\x00\x7b\x66\xb6\x3a\xae\x59\xaf\x61\x2f\xa1\x4c\xd9\xa9\x28\xd1\x66\x6a\x69\x4e\xc8\xd3\x11\xe5\x6b\xee\x7e\x84\x30\xbd\x5d\x5b\x97\x76\xb6\xbf\x6d\x18\xaa\xc1\x0b\x5b\xeb\x2c\x45\xdc\x99\x95\xab\x13\x42\xb7\x42\xe2\xe6\x25\x26\xb4\x3b\xfe\xde\x77\x8c\xae\x9f\xb9\xef\x89\xfe\xc6\x3e\xd2\xb1\x8f\x71\x3b\x91\xb6\x43\x5b\x85\x0b\x09\x93\xf3\xf0\x4f\xfa\x6b\x73\x21\x73\x3e\x18\x7f\x96\x16\x10\xab\xc7\xc0\xb0\x41\xa3\x68\x95\xd3\x90\x88\x03\xc9\xd2\xdd\xa7\xaf\x6b\xe4\xb1\x66\x48\xf4\xca\xec\xf9\x21\x58\x56\x8c\x99\x2b\xac\x89\xe5\x67\x72\xa1\xfb\x1a\xa1\x3e\x2b\xc0\x0b\x7f\x1f\x09\x22\x11\x59\x12\x55\x72\xc6\x94\xa4\x46\x49\x9e\x13\xb1\xea\x20\xc7\x4d\x57\xe0\x11\xcc\xab\x21\x4f\x75\x0a\x59\x33\x43\x38\xcb\xd6\xac\x87\xff\x11\xb9\xc3\xc5\x5a\xd0\x5e\x8e\x57\xf8\x05\x91\x9c\x20\x6a\x0f\x44\xee\x86\x51\x2f\x6b\xd5\x59\x25\x68\xf7\x11\xb5\xf5\xcc\xff\x9d\xf4\xe7\x38\xdd\xd7\x84\xa3\x4d\xb4\x34\xf0\xf6\x49\x59\xb3\x79\x34\xb4\x7c\x73\x53\xf5\x91\x3d\x62\xab\x94\x9f\x65\xe8\x36\xee\x97\x6d\x12\x9d\x39\xe9\x7f\xe9\xdf\x02\x71\x10\xb3\xe9\x74\x23\xb7\x36\x5e\x78\x20\x66\x38\xfa\xad\xe8\x29\x50\x96\xf5\xbf\x8a\x5c\x3c\x87\xe3\xaa\x13\xf4\x0f\xd0\x04\xe3\x12\x3d\x6e\xda\x10\xc9\xe8\xf1\xc0\x3e\xe6\x14\x72\xe8\xe6\xc9\x82\x15\x89\x0e\x3b\x84\xe8\xb7\xc0\x4b\x49\x81\x44\x51\xd1\x1c\x10\xa8\x15\xc9\x02\x91\xbb\xbc\x47\x4c\x2e\x8d\x68\x0f\x6f\xfe\x48\x5a\x08\x9b\x1d\x09\xf8\xa6\x88\xdc\xc7\x22\x57\x7d\xf7\x7c\x48\x2e\x6c\x5f\x60\xef\x07\xa9\x6d\x8e\xac\x14\xdd\xa4\xab\xed\xb0\xef\x67\x25\xfe\x98\x5e\x32\x57\x8a\xb7\x93\xae\x10\x18\x26\x37\x97\xe0\xa3\x70\x6a\x52\xef\x77\xb8\x65\xa9\x0f\x65\x30\x77\xa4\xa0\xc5\xe9\x0d\x25\xfb\x6d\x08\xc6\x78\x1c\x92\x5e\xcd\xce\x7e\x72\xdf\xe0\x97\xf6\x70\xee\x9b\xf0\x32\x2b\xeb\xe9\x67\x61\x33\xbc\x0c\x11\x8a\x3a\x70\xc5\xde\xb1\x68\xf5\x45\x3e\x3f\x7b\x0d\x4f\xfd\x3d\x3c\xb6\x76\xab\xb5\x3f\x7e\xe1\x7b\xa0\xd1\xcc\x44\xa3\x19\x7a\xe2\x41\xa8\x63\x23\xc4\x51\x32\x63\x3f\x72\xf1\x7a\x7e\x4f\xa2\x74\xec\x29\xa1\xb6\xd9\xaa\xe0\xbe\x0a\xce\xcb\xa2\x08\xa3\x2a\x6f\x24\x9a\x5d\xb8\x97\x33\x31\x42\xad\xde\x9b\xad\x5f\x91\x7a\xb0\x95\xfe\xfb\x19\xb5\x7b\xb1\x3f\xee\xfc\xad\x5e\x74\x6c\x73\x40\xd4\x1b\x99\xf3\x5b\x98\x0e\xcd\x6b\xa1\xaf\xf3\xea\xcc\x2c\x0e\x25\x51\xda\xf0\x4d\xf0\xe9\x99\x1f\x7b\x6b\x81\x89\x36\xa2\xe7\x53\xc6\xf2\x50\x09\x2c\x9e\x81\x38\x9e\x9c\xfa\x6c\xd0\xb3\x1b\xb4\x81\x9d\x40\x58\x52\x70\xf8\xf6\xb3\x60\xe2\x1b\xeb\xb5\x88\xf8\xd8\x7e\x8b\x9b\x8c\xb0\xad\x07\x8f\xca\xe1\x11\x0c\x51\x43\xf2\x21\x90\xac\x69\x3e\xb6\x3f\xd2\xa6\x47\xcf\xeb\x4b\x26\x08\x44\x2c\x75\xb3\xfb\x37\x85\x72\x32\x85\x95\x55\xff\xcc\x4d\x99\x02\xc4\x52\x7e\xa2\x5b\x4f\xab\x3b\x90\xf6\xee\x3e\xe2\x9c\xfa\x24\x49\xd3\xd6\x23\x58\xfe\xe1\xe0\x65\x1f\xf8\xe2\xa7\x13\x56\x69\x3f\x45\x93\x4c\xea\x28\x3e\xdf\xf5\x4b\x2c\x3e\xa3\xe0\xb1\xe1\xa6\x9b\x96\x2b\x5a\x1a\xf8\xa3\xdd\xdd\xd3\x69\x7a\x83\x55\x1c\xb9\x8d\xee\x65\x9d\x64\x2d\x45\x07\xb0\x2d\xe4\x06\x5b\xc2\xcf\x47\xcb\xeb\xf1\x43\x9a\x23\xf0\x5e\x3e\x38\x48\x44\x18\xa1\xb1\x4c\xd8\xb4\x7f\x36\x5c\x75\x95\x3e\x79\xad\xa4\x48\x42\x58\x49\x62\x5e\xed\x7b\x42\xa3\x4a\x2a\x59\x21\xbc\xd1\x57\xb7\x32\x4f\x68\x2d\x32\xba\xbe\x28\xb1\x04\x63\x28\x09\x50\x0d\x0b\x5a\xc0\x87\xc2\x61\x0b\x7e\x35\xda\x4d\x85\xbb\xd2\x3a\x37\xfc\x54\x0e\xd8\xb3\x60\x46\xc7\x56\xff\xd9\xd2\x82\xc2\x4b\xc4\x14\x6f\xa3\x97\x2c\x13\x4b\x87\x8f\x2e\xe5\x6f\xac\x5c\x9c\x57\xcc\x58\x72\xbc\x5b\x31\x37\xe1\xab\x02\xb2\x4a\x94\x37\xd5\x9d\x6e\x05\x6b\x0a\x5d\xd1\x9a\xae\x48\xa4\xba\xc8\x29\x84\xb1\x39\xc1\x3e\x8c\x82\xf7\x88\xd2\x84\x0e\xf8\x98\x35\xc3\xf4\x2a\x8c\xb1\x3c\x8d\xe3\x41\x63\x6d\x29\x42\xb1\x3e\xb7\xb4\x66\xb4\x12\xfc\x28\x7c\x96\xa6\x47\x40\xaf\x83\xcf\xe8\xd0\x68\xa1\xd6\x64\x09\xb6\xde\x82\xec\x0d\x3f\x46\x2c\xe1\x52\x74\x9a\x2e\x7b\xf3\xb9\x52\xee\xbf\x8b\x3f\x79\xe4\x75\xb1\xc8\x7f\x77\x09\x2f\x23\xd7\x7f\x92\xd0\xc8\x15\x00\xd2\x4f\xcd\x01\xf4\xc6\xa2\x1e\x74\x6b\x72\x50\xe5\x94\xd9\xa8\x8f\xfd\xfc\xe2\x84\xad\x71\x0a\x71\xa9\xe8\xd4\xf6\xc2\x2f\x05\x48\x1f\xeb\x4f\x39\x5a\x7c\x2d\xc3\x49\x5e\x48\x8b\xa4\x2b\xc1\x12\x6e\xf7\x4b\xfa\xda\x05\x7d\xca\x71\x7d\x09\xbf\x11\xa0\xc3\xfe\x5e\x30\xef\x13\x1d\xfe\xb1\x0f\xfe\xe8\x7b\xfd\x17\xdb\xa5\x3f\xdb\x44\x45\xca\xd6\xdb\x11\xed\x3f\x59\xbb\xff\xa5\xff\xb9\x78\xe6\x0f\x60\xe8\x97\x03\xdf\xa0\x83\xdf\x43\x2d\xaf\xa4\x80\x2d\x9b\x78\xfa\xec\x22\x69\x4d\x1f\x56\x0a\x53\xe5\x7e\x77\x72\x79\xab\x63\xa8\x55\x1b\x2a\x4a\x4f\xeb\x3f\xd2\x53\x35\x0f\x27\x31\x67\xed\xe8\x74\xe9\xa9\xbc\xc2\xfb\xaa\x54\xa6\x78\x91\xe7\x62\x87\xe6\x8a\x45\x09\x01\x54\xa9\xee\xf9\xca\xb1\x90\x13\xcf\x03\x0b\x98\x02\xba\xf1\x9f\x81\xcc\x44\x7d\xef\x18\x44\x4d\x3f\xa3\x9a\x88\x60\x8a\xa0\x44\x68\x09\x1c\xa7\x86\xec\x29\x60\xe5\x73\x0b\xcf\x28\xec\x84\x77\xd2\xcc\xa7\xac\xa0\x31\xf7\xb6\x6c\xc0\xe2\x84\x75\x43\xd3\x20\x2c\xbf\x22\xce\xeb\x9b\x57\xb4\x53\x7d\xfc\x69\xf7\x9f\x04\x6e\xe0\x6c\x1e\x96\xe6\x2d\x79\xdb\xe6\xba\x5f\x5e\xb6\xbe\xf6\xb4\xaf\x11\xbc\xbd\x0b\xe9\x6e\x9d\x5f\x76\xad\x5b\x5a\xf7\x86\x7a\x98\xff\xe5\x6f\xa8\x1c\xd8\xa5\xd9\xfe\xb5\x9f\xb2\x53\x8b\x37\x9d\x92\x9c\xc3\xd6\xb0\xf9\xb2\xf5\xa7\x53\x76\x38\xf0\x6e\xe5\x36\x8d\x60\x78\x91\xfd\x19\xaa\xcc\xb1\xc5\x63\xc0\x7f\x85\x2e\x0c\x36\x0a\x5c\x5c\x56\xc9\x63\x61\xa3\x75\x5c\xab\x5c\xd8\xe7\xd6\x20\x06\x8a\x2d\x94\xda\xe9\x9b\x44\xae\x45\x70\x18\xb3\xd0\xef\xc4\x4c\xb3\xa4\x5e\xc5\x68\x1b\x24\x32\x96\xa1\x96\xfd\xd9\x82\x45\x84\x99\xc7\x08\x91\xd1\xc9\xcb\xe9\xe9\xb1\x88\x7a\x0e\xfe\xf0\x55\xcb\x6d\xc2\x82\x76\xfb\xb4\x8d\x2d\xe9\x98\x20\xaf\x2a\xc8\x3b\x63\x3f\x5d\x7d\x3f\xfd\x84\x98\x42\x5e\xeb\xe5\x2d\xef\xf3\xc2\x26\xd5\x73\xcd\x55\x86\x40\x36\xf4\x1e\x87\x1d\xc5\x66\x86\xad\x3a\x62\xb1\xe4\x21\x76\xb9\xd2\x82\xbe\xea\x5c\x18\x7c\x08\x44\x4f\xcc\x4f\x00\xc5\xbc\xdf\x83\x21\xfd\x69\xf1\x25\x3d\xa1\x59\xf3\xd7\xcf\xf2\x2e\x00\xce\xae\x92\xc7\x86\x07\x1f\xbd\xca\x44\xfb\x19\x3e\x04\xcf\x84\x20\x0b\xff\x57\xc9\xbe\x7c\x8a\x86\x6d\xed\x23\xc2\x7e\x5d\x6d\x46\x82\x72\x25\x86\x6e\xb9\xae\xe1\xd6\xba\xd5\xcc\xbf\xf7\x5b\xc1\xca\x20\xe3\x74\xd2\x54\x93\x15\x9b\x9e\x07\x17\x15\xfb\x4d\x83\x84\x16\xb9\xfb\x07\x82\x67\xda\x31\x76\x8c\x62\x7c\xd6\x38\xfb\x07\xac\x05\xba\xcd\x6a\xec\x90\x02\xd3\x80\x65\x10\xda\x7d\xe6\x50\xa6\x0f\xe5\xe3\xdf\xc3\x50\xc4\x1b\x80\x8e\x24\xcc\xdd\x3d\xb8\x6f\xd0\xe3\xba\x8f\xff\x04\x48\xe8\xe0\x91\xf6\x69\xc3\x3c\x04\xee\x7e\x41\x2f\x18\x63\x65\x54\x0c\x8a\xf8\x01\x5c\x76\x11\x80\xf7\xda\xd3\x47\xb0\x94\x23\xc9\xb5\x23\xb8\x2e\x04\x06\x8c\x99\x4c\xb6\x2a\x36\x73\x04\xe6\x77\x41\x57\x03\xbb\x41\xfd\x67\x14\x00\x7f\xcd\xbd\x1f\xcf\x67\xd8\xb9\xdb\xaa\x10\x23\xa2\xda\xd1\xc2\xec\x61\x7e\xdc\x38\xac\xc9\x69\xef\x3d\x4a\x2d\x12\x58\x93\xe8\xe7\xfd\x49\x3d\x6c\x8f\xa2\x4a\x47\xb5\x51\xfb\x02\x17\x77\x76\x9c\x7a\x30\xb2\x03\x9f\x47\x83\x97\xa3\x33\xcc\xd4\x6d\xab\x18\x98\xbd\xa0\xf8\x12\xf4\xb2\xbe\xa8\xf4\xe9\xad\x26\xd8\x63\xc4\x7f\x1e\xc2\xe0\x07\xb1\xfb\xe0\xa8\xae\x2a\xf0\xfa\xf9\xa9\x26\x94\xd5\xf7\x2e\x46\x21\x34\xef\xd8\x9e\xe4\xc4\x13\xbb\x4a\xb0\x03\xd9\x35\x13\xd9\xba\xfe\x4a\xdc\xa7\xf4\xb0\x02\x88\x91\xf6\x5c\x18\xad\x54\x4c\x03\x6e\x52\x70\x3a\x30\xcc\xef\x43\xf4\xd9\xb0\x90\xbf\x63\x87\xdf\xdb\x8a\xdd\xb1\x79\xdd\x47\x66\x81\xc7\xc9\x3d\x44\xa9\xa5\xf4\xf8\x88\xf0\xf5\x5d\xaf\xb5\x85\x2f\x9d\x0b\x16\x25\x54\x8e\x14\xb0\xee\xb3\x5e\x5e\x6b\xb8\x8d\x1b\x3d\xdb\xae\xf8\x9a\x81\xe1\xff\x78\xb5\x63\x73\x4b\xb7\x71\xdc\x5a\xf6\xd2\x8b\xff\x59\xf7\x9f\xeb\x5b\xbb\xbf\x6d\xf6\xbb\xba\xa9\xe0\xed\x2a\x75\x5c\x9d\x2d\xb0\x8b\xb0\x7c\x88\x9c\x45\xa7\xb5\xcb\xa0\x01\xf4\x14\x42\x38\xe7\x89\xe8\xbf\x4d\x71\xca\x40\x07\x46\x16\x36\x6f\x70\xa3\xe7\x72\xe1\x38\x7c\x0b\x7f\x03\xc5\x96\xe0\x74\x07\x1d\xb6\x02\xdd\xdf\x43\x91\xfb\xbc\xf2\x4c\x3b\x3b\x9b\x08\xde\x2b\xc0\x6e\x47\xae\x1f\xa1\xfd\x95\x22\xc1\x6e\x8d\x8c\x4b\x90\x6a\x25\x70\x66\x05\xd4\x45\xdd\xdd\x85\xd9\x57\x37\x7b\xdd\xef\x74\x55\xa7\x59\xeb\x99\x39\xb6\x16\x9d\x13\xea\x04\xf3\x07\x85\xaa\x63\xd1\xe6\x78\xbe\x48\xb6\xe3\x15\xcf\xdc\xa9\xa1\xeb\x10\xb7\xee\xc7\xe1\x2a\x91\xfb\x1e\x6a\x64\x38\xe1\x92\x59\xeb\xaf\x4e\xe9\xb5\x1c\xc6\x90\x26\xb9\xa9\x6b\x03\x09\x41\xd6\xa0\x59\xb6\x74\x80\x09\x82\x97\xab\x2e\x81\x0b\x99\xf4\xec\x67\x29\xa4\xe1\xc2\x5c\x8a\x2f\xb3\x22\x8e\xc2\x4f\xa7\xf4\xed\x89\xae\x3b\x45\xcc\x61\xfc\xea\xf8\xa3\x8f\x14\xd3\x9e\x18\xcc\x60\xdf\x8b\x48\xb6\x75\xf0\x29\xde\xdf\x6d\xc4\xe0\x01\x52\xa2\xed\x9c\x03\x2f\x99\xc3\x49\x9b\x89\x74\xc9\x92\x11\x7d\x88\x2f\xa9\xbd\x7b\xa1\xb3\x9d\x0c\x30\xec\xbc\x93\xff\x1d\xfe\x6d\xf2\xf3\x15\x06\xd3\x77\x92\xb6\x7a\xbb\xf8\x23\x61\xdf\xc1\xb3\x3c\xad\x4c\x78\xfa\x17\x65\x4f\xa0\x7d\xf0\x7f\xae\x3d\xf7\xac\x7e\xc9\x90\x08\x9f\xa6\x55\x2d\xe5\x34\x56\xda\xec\x8f\xa8\x32\xfc\xad\x01\x18\xf4\xc7\x0f\x65\x3d\x26\x7d\x84\x5e\xcc\xe1\x7a\xaa\x7d\x21\xba\xf0\x3b\x0a\xa5\x2f\xa1\xc3\x6f\xe6\x56\xfe\xd3\xa9\x53\xf7\xf1\xb6\x8d\x7f\x39\x30\x7d\x16\xe4\x8c\xa1\x4b\x62\x6d\xfc\xae\x04\x0e\x7f\xf6\x61\xef\x12\x61\x29\xef\x52\x84\xe5\xbd\xcb\x3e\x7a\x35\xf2\x0e\x35\x35\x53\xb9\xc8\xff\xbd\xbf\x0b\xbb\x19\xf7\xa4\x0e\xc7\x95\x6d\x4a\x79\xa9\x8d\xd1\x52\xfd\xec\x2b\x69\xbe\x7b\x34\xe9\x56\xe3\xc2\xca\x0d\xf0\x2e\x7c\xb8\xea\x1f\x45\x34\xeb\x5b\x6e\x66\xef\x39\xe6\x82\xb7\x17\x1d\xa4\x81\x79\x6e\xe0\x8f\xd8\x9c\x2f\xba\x29\xbf\x5b\xb3\xc5\xe5\xe0\xd4\x87\xc7\xa2\xfe\xce\x33\xfd\x3d\xd1\x21\x61\x27\x05\xb3\xb1\x97\xd4\xef\x74\x9f\x04\xc7\xde\x49\x3f\xb5\xfd\x30\x11\x4d\x90\xe6\xfd\x67\xe4\x37\x35\xeb\x97\x37\x18\x47\x98\x3e\x5f\xa7\x83\x30\xaf\x02\x00\xf1\xe1\x19\xff\x92\x91\xbf\x98\x14\xd8\xe2\xb5\x9c\x1e\x7f\xf5\xba\x75\x85\x01\x6b\x8f\xce\x4a\xdc\x87\xac\x5c\xfa\xfd\xa5\x35\xa2\xc8\x5e\x20\xf4\x49\x70\xbe\x47\xc3\xe5\x67\xf2\x17\xf7\x25\x7b\x8f\x47\xb4\x54\x40\xcf\xf1\xcf\x88\xf6\x4a\xfd\xfc\x43\x46\x3e\x8a\x3a\x36\x76\xcd\xd9\xd7\xe5\xaa\x77\xa0\x03\x5f\x32\x04\xaa\x0a\xc0\xbb\x9e\x7b\x34\xd9\x6e\x16\x80\xf7\xd9\x18\xff\xf6\x86\x36\x96\x7c\x08\x6f\x64\x3a\x81\xb7\xba\xc4\x0e\xf6\x73\xc5\x15\xe4\x0f\x8f\x34\xec\x25\x38\xcf\xe1\xdd\x97\xf7\xa4\xd4\x84\xfb\xa7\x69\xb7\xa9\x43\xcd\x94\x34\x8b\x1a\xdc\x11\xf0\x8f\x7e\xc2\x3b\xf9\xcf\x7c\xd5\x0f\x31\x19\x34\x51\x98\x05\x50\x83\x08\x6c\xfb\x3d\x7a\xde\xdd\x55\x84\xd6\xdb\xa6\x8c\x20\xa1\x7a\x1a\xe2\xe3\xff\x45\x02\xa2\x8f\x4a\x19\xd4\x09\xb8\x4b\x58\x66\x7b\x6f\xe4\xad\xc5\x1c\x6e\xb6\x4b\x74\x45\xd0\xe2\x6b\xd1\x89\xd9\x36\x9f\x0c\xfe\xbf\x73\x6e\xaf\x02\x1f\x0f\xa9\xdf\xed\xcc\x91\x91\xa8\x07\x22\x06\xe5\x77\xe6\x91\x02\xd2\xab\xb8\xe3\x20\x57\x1f\x9b\xa0\x6f\xa6\xce\xd8\xc8\xc1\x98\xab\x50\xf3\x79\x15\x09\x1f\x6d\x30\x4b\xc0\x68\x43\x55\xcd\x17\x53\xd1\x31\x5a\x55\x5f\x5f\x2b\x52\x8d\xa3\x8b\x62\x55\xa4\xfa\x19\x8b\x6d\x6b\x14\xaa\x38\x53\x93\x75\xfd\xfa\x23\x54\x03\xf8\xeb\x4c\x67\x51\x03\xa4\xa8\x27\x32\x13\x49\xf3\xd0\x44\xde\xe3\xea\x48\xf5\x4e\xa0\x0b\x61\x8f\x25\xe7\x18\xa1\x89\x10\x5d\x94\x68\x6c\xd8\x26\x26\xf9\xba\x64\x7b\xd9\xa7\xa2\x08\x6c\x28\x82\xed\xe5\x84\x10\x3e\x3d\x3b\xc9\xc9\x0e\xbf\x87\x89\x2f\x9c\x83\xeb\x67\x9b\x1b\x09\x9f\xae\xcc\x7d\xe0\x25\x05\xe3\xd5\x83\x07\x4f\x36\x78\x3f\x27\x22\x5a\xe8\xca\xac\xd4\xb8\x79\xe7\xa5\x7d\x3f\x60\x16\xc8\x75\xcf\x3b\x2f\x41\x7d\x9e\xd6\x1f\x95\xb9\x87\x6c\x51\xad\x1a\xef\xd4\x3c\xd8\x4e\x81\xda\x06\x43\x79\xe6\x80\xd5\x3c\x39\x0f\xda\xb6\x4e\x7e\x96\x26\xa6\x39\x7c\xda\x27\x3b\x3f\x32\x02\x3a\xeb\x3d\xb7\x0c\x92\xb3\x16\x3a\xd9\x9f\x55\xb5\xdd\x59\x07\xb1\x64\x4f\xfe\x06\xde\x34\x51\xb5\xc6\x71\x56\x83\x65\x6b\x68\x99\xbb\xe3\xaa\x99\x79\x96\xa9\xbd\xc0\xb4\x86\x55\x22\xe8\xee\x3a\x3e\x5c\xaa\x9f\xf4\x7f\x67\x65\x0c\x9c\x9a\x7c\xcf\x39\x30\x70\xbf\xf6\xfd\x5c\xe6\xff\xc8\xd7\x91\x82\x1b\x1d\xe2\x7f\x3a\x24\x72\x34\x6a\x07\x88\xb0\x38\xb2\x32\xce\xac\x66\xcc\x30\xb8\x5b\xdc\x09\x7a\x68\xf4\x54\xfc\xf9\x29\x90\xc1\xf3\xb7\x7d\x85\xc8\x5a\x1d\x20\x5b\x84\xe3\x93\xa7\x39\x6c\x00\x86\x30\x14\x86\x25\x0d\x8b\x0d\x24\xf1\x3b\x6b\xda\xf6\xa6\xcc\x83\xb0\xb5\x2e\xab\x53\x62\x27\xcb\x2a\xe6\xb5\x5d\xd6\xfc\x1f\x1c\x6b\x70\xf1\xee\xc2\x66\x4c\xf1\x74\x5a\xb6\x1f\x40\xf9\x6d\xa3\xc4\x63\x1f\xd9\x10\x70\x1c\x92\x52\xf9\x50\x7c\xf6\x81\xc6\x5e\x38\xdc\x1c\x45\xd0\x04\xb8\xdc\x9e\x7e\xb9\xfe\x3a\x30\x44\xd7\x0f\xae\xcc\x08\xb5\x14\xed\x7b\xde\x9b\xfc\xf9\xd0\xa4\x7a\xd8\x5e\x82\x1e\x02\xd3\xbc\xea\xc7\x07\x03\xdc\x93\x36\x41\x35\x95\xff\x00\x3b\x08\x87\x36\x06\x87\x78\xc2\x36\xe3\xac\x6a\xaa\x20\xe3\x82\x1d\x99\xc3\x4e\x76\x19\x6d\x00\xcc\xd8\xf8\x50\x0f\xab\xe0\x59\x18\x05\x63\x39\xc9\x6d\x2c\x64\xf8\x16\xc5\xaf\x17\x85\xe8\x95\xc3\xe7\xab\xd2\x4f\x3a\x21\x0a\xfc\xcf\x1c\xd5\xd8\x3f\xda\xda\xef\xa5\x39\x42\xed\x10\x4a\x71\xd3\xba\xcf\x2f\xb5\x4f\xfa\x30\xb1\xda\xf3\x5b\x69\x8e\x3b\x0c\x55\x33\xf9\xd9\x4c\xc9\x4c\xe1\x14\x80\xf6\x00\x5b\x21\x60\xbb\xac\x42\xc9\x91\xa2\x21\xf3\xc2\x72\x06\x1b\xdb\x8a\x81\x70\x4a\xb4\xcf\x1a\x59\x99\x56\x83\xfc\x93\x50\x31\x36\xc8\xbe\x68\x21\xda\xe6\xf3\xcb\x9e\x48\x58\x1c\xa2\x65\x7e\xa8\x3b\x87\xac\x4c\xb6\x47\x82\xa8\x3c\x47\x2e\x65\xbb\x6e\x3c\x43\x93\x0a\x7d\xe9\xca\xb6\xbc\xd6\x31\xba\x22\xb3\x6e\x6a\xde\xa2\x5b\x9e\xd8\x39\x49\x9c\x9a\xb7\x7e\xb7\x95\x5c\xbd\x91\x14\xad\x0e\x00\xd6\x62\x5e\xc3\xa4\x5e\x83\x55\xa9\x66\xe8\x64\x34\x9f\x82\xbe\xbc\xc3\x8a\x80\xf4\x32\x78\x12\x20\xb0\xb4\x7f\x44\x9f\x43\x04\xec\xef\x57\xac\x33\x1b\xf2\xf0\xe1\x37\x93\x44\xc6\xd8\xd2\x1d\x29\x8b\x5b\xba\xc3\x5c\xe0\xbc\x3f\x7c\xfe\x19\xe6\x8f\xe7\xde\xfa\x19\x6b\xcb\xe6\xac\xed\xc3\x42\x8b\xcd\xd6\x86\x7e\xeb\x2d\x4d\x6c\x9e\x3c\x9f\x91\x32\xe2\x25\x98\x0f\x38\xcb\xac\x9f\x9b\xe5\xc7\xfa\x51\xeb\x82\x9b\x34\x26\x78\x66\x79\x69\xac\xd5\xfd\xe1\xfd\x09\xe5\x97\xa6\x69\xc3\xd4\x62\x31\x6e\x71\xbd\x3b\xfa\x16\x14\x6d\x21\xd7\x99\x32\x21\x47\xb5\x3b\xe6\xdb\x7b\x1b\xc2\x07\xe8\x3b\x90\xc3\x8d\x18\x19\x7a\x47\xe6\x5f\x0e\xeb\x9a\x0f\x86\x85\xe6\xed\x9f\xb8\x4e\xa5\x7a\x92\xef\xb4\x2a\xc7\x0d\x56\x6b\x77\x50\xbb\x47\xde\xb2\x0f\x91\xf6\x69\x55\xf7\x29\x75\x06\x0c\xa3\xd8\x7f\x10\xe8\x5f\xd5\x25\xb0\xf3\xea\x4b\xdb\x83\xbc\xd3\xd8\x20\xcb\x44\xc2\x47\x3a\x06\x1b\x3c\x41\x88\xa2\x3c\xce\x9b\x6d\x96\xa5\x5c\x6a\x23\x9c\x7b\xec\x82\x96\x72\xfc\xb0\xf5\xc5\x66\x98\xde\x7d\x3a\xc5\x4d\x5a\x0a\xa3\x0b\x96\xd2\xcb\x56\x61\x4f\xd5\x69\xe7\x9b\xcc\x15\xec\x9b\xd7\xd2\xb6\x00\x84\x54\x0b\x22\x87\x4d\xc2\xfd\xdd\x22\xfc\x7b\x99\xcf\x8b\x0d\x89\x88\xf2\x98\x57\x36\xe0\x96\x19\x69\xd7\x97\x7f\xb6\xdc\xd8\x6b\x4b\xfe\xc7\x83\x72\xe2\xc1\xb9\x59\x4b\xaa\xdf\x35\xa9\x1d\x84\x14\x0a\x35\x0d\x26\xc7\x15\xfe\x0a\x09\x7f\x7f\x73\x00\xf6\x7f\x82\xe5\x61\xa6\x20\x5d\x0f\x5a\x03\xec\xe7\xfc\xa5\xf0\xf7\xfe\xb3\x2a\x0b\x34\x35\x7e\x15\x70\x57\x58\xac\x46\xc3\x90\x15\xa2\xbf\x19\x9e\xb7\xde\x2d\x99\x95\xc0\x8b\x0e\xc1\xb7\xc1\xe4\xb6\x73\x0e\x63\xca\x2c\x3f\x85\x77\x18\x2d\x54\x42\xe1\x45\x26\xf4\x13\x13\xae\xa6\x12\x5c\x50\x77\xae\x92\x13\xe5\x7a\x5f\xfd\xea\x82\xc8\x29\xa8\xa4\x8d\xa3\x2e\x4e\x7b\x9c\xc1\x36\x08\xa6\xfa\x2c\x83\xbe\x09\x41\x48\x20\x35\xfb\x78\x1c\x91\x4e\x26\x16\x8f\x55\x6c\x82\xfc\x7f\x81\x1f\x62\x73\xb9\xc9\xe5\x45\x35\x86\x53\xd3\xc9\x2b\xa7\x08\x91\xcf\x61\x32\x49\x16\x49\x79\x4a\x41\x37\xe6\x88\x03\xe2\xf8\xaf\x55\x28\x3d\x01\xc9\x29\xfd\x96\x15\x99\xa0\xd9\x34\x2f\x0d\x82\x13\xaa\x22\xeb\x24\x9d\x7f\x95\xc7\x21\x74\x12\xde\x02\x08\x07\xcc\x66\x06\xb1\x06\x6f\x76\x6a\xba\xd0\xb1\x1e\xb7\x22\x3c\xec\x57\xe1\x6a\x45\xa6\x7b\x04\x88\xe8\x64\x1d\x6d\xa3\x75\x2a\x40\xc4\xa6\x2d\x5d\xda\xe3\x49\xdd\xc7\x78\x8a\xce\x8c\xff\xbf\xd2\xf4\x01\x84\x77\xfa\x67\x16\xf5\x52\x6c\xf0\xfb\xe1\xc7\x88\xbd\x03\xfc\xef\xbc\x98\x31\xcc\x52\xc6\xb9\x59\xb0\x8d\x40\xfc\x14\x8b\x1a\x1f\x69\xcc\xe1\xb4\x3b\x46\x7c\xca\x98\xa4\x4c\x19\x45\x8c\x97\x42\x6c\x4c\x57\x2f\xae\x3b\xef\xb5\x4f\xe3\x9f\x21\xc9\x3a\x15\x79\xaa\xea\xe3\xd8\x30\xb1\xb3\xe1\x05\x17\x19\xd9\xcf\xca\x1e\x3b\xa8\xf0\xd8\xcc\x3b\x66\x8e\x2d\xb6\xa3\xfb\x27\xaf\xe9\xa7\xe6\x17\xf4\x0a\xf4\xbd\x3e\xb1\x55\xa3\x2b\x84\x7d\xaf\xea\xbc\xdb\xf9\xc5\x68\x55\x59\xa1\x3f\x23\x33\xf2\xe9\x20\xbf\x23\xf3\xab\xfb\x85\xf1\xe3\x3d\x3d\xa0\x55\x0d\x07\x32\xc6\xf9\x3a\x98\x5b\x05\xfb\xaf\x8d\x5e\xaf\x8e\x40\x58\xe6\x3f\xc3\x99\xf3\x95\x65\x09\x51\xd7\x3e\x02\x59\x5b\x0c\x89\x38\xed\x4f\xc4\xe6\xba\xa2\xd3\xff\xe8\xf3\xa6\xee\x47\xf2\xfa\x5b\x94\xb7\xd0\xe7\xe0\x94\xf7\x9b\xb1\xa5\x67\x27\x19\xe5\xb6\x53\xee\xed\xe7\x72\xc2\x19\xb3\x4b\xf8\x39\x40\x20\x12\x1f\x7f\x86\x73\x9a\x23\xe8\xad\x08\xb2\x02\x45\x0f\x1b\x04\x22\x23\xb1\x84\x3f\xf5\x50\x01\x93\xcb\xac\x13\x8e\xe0\x5e\x25\x0c\x60\x40\x25\x0e\xe0\x1d\x40\x1f\xd0\xf2\x4f\x13\xa0\xe3\x94\x36\x44\x59\x03\x1a\xd7\xcd\x9d\xce\x30\x87\xd8\x71\x98\x49\x55\x05\xdb\xfe\x55\x34\x58\x3b\x3a\x1e\xd8\xd8\xbe\x30\x1f\x34\x55\xdb\x90\xaf\x26\xac\xb1\xf1\x94\x28\x4d\xb0\xa9\x4d\x9b\x60\x74\x05\xce\x20\xeb\xc7\x73\x56\x66\x23\x7b\xd4\xab\x18\x63\x43\x0e\xf6\x0b\xae\x58\xc5\xad\x00\xa8\x4a\x8c\x7b\x75\x81\x0e\x5b\x08\x3b\x0f\x70\xfb\xe4\x20\xd1\xd8\xbe\x07\x37\xbc\xb5\xfc\x70\x37\x91\xfe\x72\x75\x33\x47\x59\x0d\x05\x47\xf8\xc5\xc7\x3f\x93\x06\x81\xd1\x97\xa5\x81\x4f\x76\x72\x28\xe9\xd5\xcf\xbf\x5f\x38\x6b\x59\x45\x2b\xef\x6d\xa5\xd0\x6b\x52\x0e\xec\x21\xb0\x0e\xb2\x3b\xe7\xfe\x9f\xf7\x33\x6d\xa4\x6c\x62\x4b\x47\x98\x7c\xf2\x75\x87\x0f\x4e\x94\x16\x00\x99\xf7\x97\x69\x71\xad\x91\xf0\x0a\xd4\x63\xd0\x98\x01\xf4\xbd\x73\x64\x57\xf1\xf0\x85\xfd\x20\x4a\x65\x8e\xf4\x95\x75\xfe\x4f\xc0\xfc\xdc\x93\xbc\xd4\x7d\x02\xe4\xea\xdc\xc7\x89\xa3\x73\x20\x1c\x7f\xf6\x0a\x2f\xea\xaa\x52\x7f\x30\x10\x2e\x9f\xc5\x6f\xeb\x6a\xaf\xc8\xd5\xda\x2f\x42\xe0\x60\x0f\x1a\x8c\xfb\x46\xb3\xaf\x9d\x98\xf2\x44\x90\x80\xb8\x2f\xd0\x4e\x11\x56\xaf\xdb\xa5\x20\xd8\x1a\x5e\x18\x60\xe1\x0b\x69\x2f\xc3\xee\x29\x43\xdd\x99\x7f\x56\x1a\x08\xa2\x26\x8c\xec\x55\x5f\xf3\x15\xdd\x25\x6b\xeb\x68\x66\x08\xe6\xbc\x50\x71\x89\x85\xc0\xa0\x57\x77\xc0\x16\x4e\xc6\xc5\xf2\x97\x74\x8f\x8b\x1c\x98\x3c\xeb\x98\x0e\x19\x2a\x84\xca\xd7\x26\xd8\x05\xe4\xbe\x3f\x02\x83\xdf\xc3\x4e\xc8\x2e\x8d\x3e\x0b\x8c\xea\xa8\xb8\xbc\xd6\xcc\xbf\xec\xe2\xf2\x7f\x85\xfd\x9f\xc2\x67\xf3\x15\x18\x91\x9d\x16\x81\x90\x75\x79\x87\xeb\x0b\x47\x20\x05\xd2\x4e\xd5\x76\x07\x5f\x19\x48\x77\xad\x4c\xee\x5a\x23\x11\x76\x59\x00\xe4\x65\x40\xfa\x11\x0f\x1f\xd3\xbf\x50\xf8\x8b\x86\xa1\xd7\x2e\xa3\x0d\xdb\x3c\xae\x82\xd9\x85\x52\x76\x89\x6c\x63\x40\xec\xe7\x9f\x72\x61\x58\x93\x76\x30\x3f\x91\x17\xa9\xef\x67\xf1\x8d\x8b\x3c\x96\xce\x6f\xf5\x03\x89\xa1\x6a\x3f\x01\xca\x58\xb9\xd7\x4f\x8d\x83\x98\xc4\x26\xc0\xa9\xea\x13\x55\xda\x60\x9d\x10\x68\x78\xe0\xdd\x87\x82\x66\xd7\xa7\x90\x74\xcd\xcb\xb6\x28\xd3\xeb\x94\x5e\xa4\x0e\x6d\xb9\xed\x28\x5d\x88\x12\xe5\x83\x70\xb5\x4a\x80\x4b\x7d\xec\x14\x55\x1b\x7d\x3f\xa3\x2c\x66\xbe\x1f\x5f\x74\xbf\x25\x2c\x42\xbf\xf2\xa2\xfe\x2a\x47\xff\x0b\x76\x22\xf9\x37\xdf\x84\x8e\xe0\x45\x52\xff\xca\x5b\x56\x40\x80\x78\xde\x27\x27\xb2\x32\xde\x9f\x20\xde\x97\xfa\x6f\x42\x0c\x77\x0b\x70\xd0\x68\xc1\xb4\x57\xcb\x85\x59\x7f\x38\xb7\x7b\x13\xbf\xdd\x8b\x3f\x28\x19\xef\xd9\xb6\x6b\x73\x83\xa7\x57\xf9\x33\x39\x8d\x9f\x40\xb1\x0f\xe3\x75\xb3\x80\xf2\x0c\x8e\xb7\x3c\x32\x82\xad\xf9\x0e\xa4\xf7\xdd\x02\xe6\x41\xf3\xc7\x55\xe5\x43\xab\x00\xdd\x90\xfc\xed\x3e\x49\x02\x93\xc2\xf9\x94\x4d\xd0\xb7\xb8\x3a\xef\xe6\x25\x0e\xbc\x3a\xd3\xa4\xfa\x25\x3c\xff\x45\x53\x3d\x41\xcf\x8f\xf0\xc0\x20\xd8\x7c\x6e\xb9\xae\xe2\xe5\x7f\x9b\x0d\x06\xad\xda\xec\xdb\x84\x59\x4f\xb0\xfb\x41\x71\x90\x13\xea\xfe\x6c\xc6\x1b\x76\x4e\xd2\x22\x51\xd0\xf3\x5a\xf2\xc8\xbf\x7a\xf1\x94\x00\x3d\x9f\xa4\x63\xd5\x0f\xda\x54\x8e\x41\xff\x5c\x54\x00\x51\x73\x25\xbc\xdb\xf2\x79\x8b\xa2\x21\x17\x3d\xf0\xfb\x15\x95\x6b\x8b\xc2\x90\xc2\x2a\x75\x8f\x7c\xdb\x13\x27\xb2\x54\x03\x05\x01\x38\xcd\x28\x55\xdb\x13\x67\xfc\xfb\x91\xb1\xab\xee\x74\xa1\xb0\x19\x46\x52\xdc\xd3\xec\xf3\xac\xbd\x24\xda\xed\x62\xfc\x9f\xaa\xac\x00\x6b\xfb\xbd\x1e\x9c\xe0\x03\x5a\xc3\x5c\x88\x63\x95\xb1\x44\xc5\x4f\xa3\xb8\xda\xba\xe9\xa3\x5c\xb4\x09\xbc\x6e\x66\xba\xd9\x89\xf0\xb5\x73\x8c\xc2\x61\x60\xd5\xd7\x3e\x37\x76\x7f\x66\x2e\x84\xfd\x77\x9c\x5a\x5b\xf0\xf5\xcb\x29\x9e\x01\x86\x42\x8c\xa1\x1c\x8a\x0c\x11\xfb\x63\xbc\x06\xae\x09\x58\x81\x08\xa5\xd8\x68\xd3\xbf\x86\x23\x04\x19\x0e\xd0\x4f\x0d\xba\xb7\x5f\xe4\x63\x0f\xe2\xff\x2d\x18\x3c\xed\x11\x59\x03\x84\x2e\x6c\x5b\xd9\xff\xbc\x8e\xd0\x24\x34\xcc\xcb\x46\xb4\xee\x88\x98\x54\x24\xfa\x16\x81\xdb\x35\x2c\xcd\xae\x88\xb9\xe9\xbc\x33\x71\x6d\x14\x92\x03\xbd\xfe\x79\xbd\xda\xbb\x96\x56\xc0\x2d\xb8\x09\x5a\x6f\xad\xf1\x76\x39\xf6\x01\xbf\x0c\x3e\xdc\x7e\x35\x92\x4e\x80\x5c\xf1\x73\x4e\xed\x5d\xd9\x59\x76\xb4\x10\x9c\x73\xf6\x2f\xf5\xc7\xd4\x87\x2a\x57\x78\xb2\xc0\x23\x1b\xa4\x27\x27\xae\x2b\x87\xbf\x46\x5e\xc9\x47\xb0\x32\x49\xed\x25\xac\x0b\xfa\x0f\x39\x49\xf1\x67\x73\x33\x1b\x16\xfd\x0c\x63\xd4\x5b\x3c\xfa\x3e\xbe\xf0\xde\x0d\xb2\x05\x2e\xef\xf3\x2f\x51\x78\xcd\xf5\xda\x7f\x68\xb4\x26\x18\xea\x00\x38\xc8\x9a\x70\x41\xed\x6f\xcc\x7e\xa2\xb7\xf0\x81\xdd\x83\xc4\x7f\xab\x2d\xee\x96\xb0\x67\xe4\xee\x0c\xe4\x63\x5d\x90\xe7\x25\x0d\x44\xd9\xb1\x61\xa8\x50\x82\x6d\x00\x52\xa4\x06\x59\x8a\x04\x7b\x4b\x74\xf5\xf0\x2b\xe0\xac\xd2\x10\x9e\xe0\xbd\x6f\x3e\x10\xec\x8c\xad\x81\x43\xca\xb5\xf9\x91\x20\x42\x56\x2c\xfc\xf2\xbe\xc5\xf3\xaf\x31\xb8\x19\xb4\x0f\xca\x3b\x23\x7e\x0a\x08\x0c\x61\x9d\x77\x96\x33\x2c\x69\xc9\xe2\x43\xd4\x31\x51\x6f\x34\x5a\xf9\xa2\x1d\x77\x60\x11\x32\x7c\x36\x97\x59\xd2\x5c\x4e\xb1\x90\xcf\x9f\x34\xf3\x6c\x64\x46\x0f\xfe\xe1\x20\xd4\x6d\x27\xfd\xad\xf8\x1a\x19\xbe\x03\xee\x40\x92\x5b\x76\x39\x70\x17\x96\xc2\x67\x56\xf7\x04\x97\xab\x5f\x46\x1c\x0f\x9a\x94\xcf\x3c\x3c\x33\xcb\x36\x00\xe1\x44\x47\xcf\xf8\x3f\x29\xfc\x6b\x9b\x46\x07\xd0\xaa\x9f\x41\x36\x70\x7a\xdd\x71\x16\xdf\xd5\xe3\xa8\x73\x9c\xc3\x30\xb9\x1d\x46\xc6\x8b\xda\x25\xfa\xe1\xa2\x73\x20\x8b\xcb\x8f\x21\x47\x3c\x5a\x6a\x0e\x54\x01\x4e\x94\x70\x16\x7d\x99\xcf\x96\x28\x34\x33\xf7\xf4\x80\xd1\x8c\x70\xe9\xff\xc4\xea\x47\x3a\x0b\x07\x32\x86\x07\x67\xec\x52\x22\x32\x4f\xd0\x83\x66\xbb\x04\xaa\x8b\x3b\xd8\x4e\xb2\xc8\xb3\x01\x17\x95\xc3\x23\x4e\xfc\x21\xb9\xfd\xdf\x9f\xab\xf0\x91\x15\xd7\x73\xe4\x2e\x14\x08\x89\x14\xff\x77\xe4\x61\x61\x38\xd3\x0e\xf7\x25\xb1\xf9\xa1\x12\x55\x6e\xd2\x07\x30\x4b\x3e\xeb\xea\x85\x2e\x62\xe8\x42\x05\xfa\xaf\x36\x8b\x93\xbc\xf0\x56\xb8\x75\x64\xde\x06\x6a\x59\xe6\x68\xe1\x97\x69\x73\xa0\xe4\x04\x47\x1a\x93\xc4\x0a\xd1\x06\xb0\xad\x31\x0f\x52\x19\x15\xa8\xe7\x5c\x71\x80\xeb\xdc\x41\xf2\x75\x56\xe9\x6a\x8b\x0e\x4d\x4e\xb8\x4f\x2a\x70\xf8\xb8\x09\x74\xe0\x54\xe6\x37\xbb\x7f\x04\x96\xec\xa4\x83\xef\x25\x20\xd5\x3d\x30\xea\xdd\x56\x2d\xc5\x40\xf3\x02\x86\xf5\xc9\xac\x54\x15\x2b\x83\xd8\x84\xdd\xb3\x56\x4d\x9a\xf6\xca\x24\xc5\x5b\x5e\x04\xd9\xd9\x7e\xdf\x43\xba\xe1\xba\x04\xd1\xcd\xdb\x66\x1c\xd0\x3a\xd5\x06\xb6\xf3\xcd\x36\x79\xf9\xb8\xdc\x04\xba\x43\x35\x6b\x55\x36\x97\x6c\x80\x99\x9d\x40\xdf\x79\xd7\x9e\xce\x15\x07\x6b\x03\xcc\x19\x54\xb6\xcd\x7f\x40\x43\x03\x30\x8f\x7c\x24\x60\xe7\x6b\x28\x0f\xa6\x97\x40\x73\x44\x1e\x3d\x88\xa7\xf3\x61\xf6\x70\xc2\x33\x4e\xb5\xa6\x3a\x61\x8a\xd8\xa2\x2c\x18\xdd\xb6\x5e\x02\xca\xdf\x32\x23\xe9\x8f\x29\x49\xd8\x81\xd4\x25\x78\x75\x73\xe8\x19\x16\x3e\x04\x3a\x44\x44\xdd\x6a\x69\x3e\x70\x9c\x77\xd1\x71\xa1\x2d\xb0\x47\xf2\x7e\x8f\x48\xe5\xcb\x3e\x59\x46\xd2\xfb\x77\x17\x20\xaf\x1d\x26\x00\x77\x31\xa6\xa4\x31\x10\x8c\xaf\x20\x45\x84\x4b\xcf\xf2\x79\x49\xe7\xcf\x1a\x45\xe1\xd9\xd8\xaf\x13\x1f\x57\x52\xd3\x1e\xe6\x9c\xf0\x3c\x39\x53\x66\x22\xf4\xc1\x98\xa4\x9d\x7b\xeb\xf5\x67\xa2\xbb\xd6\x5e\x1a\xa0\xb5\xf4\xb3\xba\xf2\x6b\xe1\xea\x42\x66\x7e\xb8\xf5\x8a\xf8\x3f\xcb\x07\x6c\x9d\x25\xd8\x07\xb2\x44\xe6\x3b\xa6\xcc\x60\xba\xc7\xa4\xb9\x02\x56\x1c\x5a\xf0\xb4\x20\xb2\x15\x4c\x43\x31\xf4\xbf\x04\xcf\xf7\x24\x40\x7d\xfe\x07\x45\x8f\xc2\xc8\x26\xd6\xdc\x55\x71\xee\xbf\x11\xaf\x14\xbc\xe2\x35\x85\x8f\xb0\x4e\x69\x06\x2a\x91\x2d\x8f\x71\x7b\x41\x7c\xd5\x1c\x48\x61\x03\xe8\x29\xc0\xf7\x63\xca\x8d\xd5\xaf\x3b\xb7\x23\x12\x9a\x20\xca\x78\x00\x6d\x77\x13\xea\xa5\xb6\xdc\x69\xdb\xa0\x6d\x51\xcd\x2e\x70\x21\x0f\x28\x9d\x77\x17\xd5\xb1\x0b\x1c\xb4\x79\x94\xab\x4a\x84\x35\x81\xc0\x42\x08\x7d\x0e\x6f\x15\xef\x72\x2f\x3b\xd2\x8f\x7f\x9a\x87\x05\x7d\x42\xbf\x03\x70\x44\x84\x58\xdf\x21\x5c\x5a\xe6\xe6\x32\x0c\x40\xbd\x85\x5c\x87\x9d\x71\x8b\x84\x5d\x66\x2d\xc0\x70\x68\x09\x13\x62\x51\x05\x90\xad\xda\xa2\xac\x27\xde\x92\xce\x20\xe5\xdb\x2e\x2f\x18\xf9\xdb\x41\xc4\x7d\x8b\x34\xec\xc4\x8d\xc1\x22\xed\xc3\x92\xec\xc5\x83\xb5\xaf\x78\xed\xc4\x4f\xfc\xa7\x44\x92\xbf\x1a\xe4\x91\xbf\xf2\xd9\x79\x0c\xe0\xf7\x2f\xd2\xd7\xfe\xb2\xd2\xdb\xe8\x78\x3c\x13\xaf\x77\x8f\x62\x3f\x7f\x6c\x96\xc8\x6c\x96\xfe\x25\x7b\x00\x6e\xb2\x69\x87\x27\x08\x4c\x48\xfd\x06\x08\x3a\x75\x16\xcf\x07\x4f\x19\xf8\x96\x29\x34\x7a\xfa\xfc\x8c\x62\xea\x26\xd6\xc5\x54\x7c\xb1\x98\x6c\xab\x21\x50\x7d\x4f\x93\x5f\x62\xee\x0b\xf3\xc3\xdc\x87\x50\xc1\x60\xdc\xec\x60\x56\x55\xb1\x30\x51\xa6\x23\xcc\x1d\x64\xc8\x69\x8e\x08\xe4\xa9\xe5\xb6\x4d\xe1\x12\x36\xcd\x71\x57\x17\x59\xdb\x2f\xf1\xf3\xf9\x0f\xb3\xdc\x76\x1c\x92\x0f\xbe\xfe\x16\x24\x78\x26\xf2\x5c\xbf\xa1\x1e\x1b\x2c\x4d\x8e\xbc\x37\x60\x1f\x4b\x74\x7e\xed\x87\xa7\x90\x06\xe8\x62\x9a\x52\x15\x65\x3e\x44\x31\x13\xe8\x72\x57\x80\xf1\x77\x1b\x5d\x53\x3b\x47\x01\xd8\x7f\x22\xc2\xea\x94\xa7\xc9\x94\x44\xe1\xdf\x24\x9e\x9e\xd2\x38\xaa\x09\x02\x97\x46\xc9\x61\xa6\x14\xb3\xc4\x94\x06\x7d\x7a\x6c\x64\x17\x2e\xae\x63\x0d\x03\x5e\x8c\x66\xec\x5c\x69\x48\x73\x4f\xad\x95\xe4\x52\xff\xdc\xd8\xfc\x22\xe4\xa3\xb9\x4a\xd0\xbe\x82\xa3\x44\xe2\xbe\x5d\x75\xc4\xef\x73\xeb\xde\x38\x9b\x1f\x47\x06\xf7\x8e\xa5\x85\x68\x8f\x56\x60\x94\xa0\xe1\x17\xa4\xc1\x73\x40\xc6\xdc\x08\xba\x90\xe6\x53\x97\x6d\xf0\x39\xf3\x7a\xa9\x10\xf0\x8c\xf0\x91\xfd\x82\x79\x5d\xf4\x1d\x8e\xb3\xe2\xc9\x67\x24\x25\x73\x8f\x0b\x7b\x67\xf6\x03\x9c\x66\xe0\x6f\x35\x5f\xd1\x0f\x38\x15\xef\x3a\x26\xc1\x6b\x28\x25\x55\x38\x8e\x58\x13\x06\x82\xfe\x6e\xe8\xcc\x07\x62\xfe\xfc\x70\xb4\xce\xea\x19\xfc\x93\xd4\x3a\xda\x05\x4c\xc3\x9b\x33\x12\x44\x9f\x60\xa2\x13\x40\xaf\xea\x49\x3c\x4f\x6f\x75\x3f\x4f\xb5\x19\x40\x00\x8f\xec\x7a\xf8\xe2\xf0\x24\x8e\x80\x98\xe7\x1a\xad\x60\x1b\x69\xf3\xf0\xa4\x3c\xfb\x39\x87\x55\xcd\xb3\x31\xc7\x9e\x12\x2b\x38\xb5\xdf\xbf\x23\x1b\xf6\x22\xf9\xd3\x2f\xa7\x29\xaf\x6d\x11\x90\x67\x74\xfa\xe6\x25\x9c\x73\xe4\x2d\x9d\xe6\x80\xf9\xf3\x9b\xb4\x7c\x4f\x8a\x21\x5c\x7f\x7b\xa9\xed\x80\xfc\xda\xb0\x04\xec\xd1\x9e\x64\xf7\xe7\x8e\xc8\xfd\x70\xf2\xed\xb8\x37\xe9\xc3\xc1\xfa\xdc\x97\xad\xf3\xa1\x0b\x8b\x91\x0f\xe8\x5e\x34\xf6\x2a\xa4\x1d\x0f\xf5\xfa\x41\xc2\x1e\x43\xce\xbd\xb7\x0d\xcb\x11\x3c\xff\xa7\x20\xff\x7d\xd4\x71\x50\xc2\xd7\x2f\xcf\x7e\xa8\x5d\x1c\x23\x6e\x4a\xae\x4b\x03\x0a\x94\x88\x37\x1b\xce\xe8\xcb\x0d\xf8\xc9\x68\xf2\x34\x94\x4b\x36\xeb\x43\x69\x5d\x85\x42\xbd\xd0\x50\x14\xe7\xe0\x44\x5b\x1a\xe2\xfc\x92\x1d\x86\xe2\x3d\x96\xa1\x65\xa9\xc1\xcc\x67\x8f\x51\xb4\x1a\xac\x88\xe1\x13\x63\x87\x3f\x80\xcf\xde\x47\x3b\x61\xd7\x40\x6d\x88\x0c\x49\x81\x77\x2e\x40\x78\x61\x7f\xa0\xa5\x8c\xe5\xdd\x4d\xf9\x87\xfc\xb3\x03\xda\x0a\x9f\xb6\x25\x35\x15\xc6\xb9\x0e\x64\x77\x23\x41\xc1\x0f\x48\xa6\xe0\x3e\x68\xd0\x36\x74\x08\x8b\x6c\xa5\x22\xf6\xf5\x06\x95\x9b\x68\x7e\xbd\x66\x05\xcf\xf5\xf5\x9f\xec\x76\x68\xb4\xd8\x37\xf8\x48\x6b\x50\xaf\xa2\x96\x82\xf2\x3e\xfa\x93\xd6\x4d\x3d\xbe\xe7\xd0\x26\xa4\x83\x1d\x85\x37\x3f\x61\x5f\xea\x41\x8d\x40\x0d\x17\x8c\xbe\xdc\x6c\x2b\xdc\x7b\xa1\x51\x35\x7e\x88\x59\x0e\xda\x87\x3a\x0b\xfb\x05\x76\x17\x5f\xcb\xde\x0a\x5f\x4b\x6a\x69\xec\x66\xce\x78\x31\xca\x16\x6c\xda\x08\xdd\x03\x82\x5b\x7d\x30\xe5\x4b\x9e\x04\x3d\xe7\xd8\x93\xc3\x41\xa0\x5f\x0f\x21\x94\xe0\xeb\xde\x76\x4d\x6b\x34\x1b\xce\x4a\x6a\x24\xc6\xf3\xda\x6e\x0e\x59\x02\x64\x01\x74\xe0\x40\x10\xd9\x18\xb4\x83\x5e\xa9\xda\x2e\x11\xe0\xec\x09\x43\xa0\x70\xd6\x56\x26\x55\x9f\x0e\xf9\xf4\xda\xe8\x8c\x9b\x8e\xf9\xe7\x09\xc4\x6d\x7f\x1f\xa6\xfc\xbd\x1b\x58\xab\xbb\x31\x5b\xa5\x22\x73\x20\x3b\xad\xe4\x19\xb4\x22\x49\x8a\x0f\x98\x41\x45\xf1\x51\x18\xed\xd4\xab\xa7\xcd\x11\xa8\xd0\xd1\xa5\x38\x47\x4d\xb8\xe8\x7e\x38\x06\x6e\x4b\x58\x5a\x99\xfa\x5e\x3d\x9e\x98\x7c\xfe\xb7\x3a\x12\x55\xd4\x7b\x78\x77\x97\xb0\x0f\xda\x18\x68\x56\x42\x46\xa0\xfd\x31\x86\x6c\xec\x33\xe0\x2a\x06\xea\x73\x60\xef\xdb\xf4\x06\x59\xc6\x68\x5d\x63\x62\xb8\x71\x90\x8c\xc2\x13\x13\xd7\xd2\xe7\xd7\xec\x18\x66\xa9\x0b\xa2\x6d\x62\x7b\x26\x75\x3b\x3e\x8e\xae\xa2\xdb\x41\x3b\xa0\x4b\x2c\x28\x74\x3b\xd8\x38\xf1\xd0\x16\xfa\x5d\x17\x84\xc9\xcb\x1d\xb9\x53\x1b\xa7\xb8\x44\x30\x9a\x26\x91\x4e\x8c\x51\x98\x12\x79\x7d\x45\x31\x02\x9d\xb3\xba\xb5\x28\x9a\xa4\x8b\xec\xf9\x55\xf1\x6e\xc8\x63\x8b\x99\xa8\xc3\xee\x4c\x2f\x22\xd3\x8d\xce\x4d\x6b\xf4\xc1\x82\x24\x8b\xb6\x49\xba\xbe\xb1\x46\xba\x27\xb8\x1f\xa3\x4b\x94\x7f\xa4\xba\x0e\x93\x9b\x1f\xcf\xe8\x71\x00\x76\xfe\x63\x2b\x45\xc8\xa6\xdb\x85\x87\x6f\x51\xa4\x29\x76\xe9\x3f\xc4\x56\x49\x93\x70\xc7\xa9\xe0\xdb\x7f\x0e\x26\x29\x4c\xd0\x21\xd9\xba\xd0\x2e\xac\x0d\x5b\x81\x78\x81\x47\xb7\x33\x89\x30\xfd\x49\x1d\x13\x76\x2f\xea\x2d\x61\x41\x1c\xe5\xe6\x1d\x53\xa5\xaf\xbe\xd4\x14\x74\x21\x3a\x06\xd2\xe6\x2d\x0f\xa7\x8a\x3c\x3c\xa5\x8d\x17\x2b\xea\x8a\xe6\x65\xf4\x9a\x07\x6e\x6a\x90\xdc\xa6\x40\x38\x58\x04\x29\x49\xff\x29\x36\x42\xf2\xd8\x3a\xbe\xf0\x12\xad\xbf\xb4\x70\xf3\xe2\xd9\xfa\xfe\x4c\xe2\xc4\xc9\xa6\x00\xb6\x09\xd9\x45\xa1\x6c\x80\xea\xac\xd4\xc9\x4a\x0e\x3b\x73\x1e\xbb\xe2\x1c\x85\xaf\x67\xe4\xe3\x65\xbe\x48\x5f\xe5\x1e\x9f\x81\x70\x0f\x6f\xad\xf8\x72\xf9\x0d\x04\xf5\x9b\xe3\xe1\x1f\xac\x43\xaa\x48\x3e\x85\x22\x0e\x44\xbe\xf9\x91\x94\x6b\x88\x0e\x76\xba\x3b\xbe\x03\xcc\x78\x57\xf7\x2b\xf5\xee\x44\xa4\x93\xd8\x60\x20\xd3\x05\xbd\x97\x87\xf7\x56\xae\x35\xcb\xa3\xfc\x67\x61\xbe\x6e\x5c\xb2\xe1\xa1\x24\xa6\xef\x7b\x0e\xb3\x73\x79\xb6\x41\x29\xf0\x9e\x65\xb5\x14\x3b\x71\xef\xc9\xa8\x11\x32\xcd\x03\x17\x86\xb7\x1b\x48\x8a\x9c\xf8\x8e\xdc\x1a\x5c\xd9\xf2\x15\x87\xff\x22\x82\x5a\x39\xde\x43\x53\x90\xd5\x44\x4a\x9f\x70\x65\x72\xc1\x7f\x9c\xf3\xf0\xd6\xe2\xfd\x6b\xec\x3e\x64\xc7\xd4\x24\x05\x34\x90\x79\xa7\x1c\xf4\xe2\xd7\xfc\x9a\x59\xd6\xbf\x04\xe4\xb4\xd0\x7f\x2a\x02\xd8\x53\x41\xd6\xec\x83\x39\x74\xce\xdb\x78\x81\x6e\x77\x69\x60\x67\x2d\xbb\x2a\x67\xcb\xfc\xf7\x7c\x29\x8d\xcb\xef\x66\x3b\x5d\x68\x6d\xe6\xe3\xa0\x14\xfb\x1f\xdc\xdf\xbd\x64\xad\x85\xa3\xd6\x04\x06\xd6\xd9\xac\xa5\x3f\x92\xaf\x18\xe1\x54\x54\xe5\x4f\x78\x57\x6f\xbd\xdd\x95\xe1\x72\x30\x5d\x5a\x65\x46\xbe\x1d\xec\xcd\x60\x37\xe8\x0f\xb5\xef\x86\xec\xa7\x1b\xab\x27\x5b\x2e\xf0\x5e\x65\x1b\x86\x26\x2b\xf7\x5f\xe2\xbb\xbe\x23\x1a\x2f\x7c\x30\xef\xa9\x9e\x9b\xc2\xea\xe8\xef\x82\xc8\x9b\xca\x46\xec\x6d\xdb\xb2\x53\x36\xe8\x76\xdd\xf8\x07\xb8\x53\x78\x83\xdd\x12\xae\x5e\x9f\x9b\x42\xb6\xeb\x23\xa3\x6f\x88\x52\xe4\x1f\x64\xe7\x4e\x56\x0c\x12\x14\x08\x02\x12\x2f\xdb\xcc\x85\x02\xe4\xaa\xdb\x2e\x18\x3e\x1c\x05\x21\x37\xb8\xee\xe8\xb7\x9c\xc5\x89\x36\xde\x91\x09\x26\xfc\x0d\x1f\x4b\xf6\x69\x10\x85\x24\xe8\x16\x1d\x99\x8d\xc7\x79\x6f\x61\xb3\xfe\x57\x96\x35\x39\x1d\x99\xa2\x6d\x03\xe9\x41\x92\xb2\xe0\x0c\x89\x41\x38\x71\x1f\xf3\xa0\x4e\x0d\x1d\xe6\xae\xf2\x0e\xd4\xe2\x2a\x57\xa3\xb7\x5d\x45\x96\x02\xd0\x20\xb0\x0b\xb3\xca\x31\xd9\x46\x5a\x59\xae\xf2\xc7\xbb\xe0\x14\x1a\x1f\x5c\x51\xda\xd7\x4f\x77\x77\x15\x36\x7a\xaf\x55\x9f\xd9\x36\xb1\x31\x6d\x5f\x00\x21\xd8\x9b\x80\xd0\x87\xb8\xd3\x45\x44\xfb\xf2\xab\x96\x1d\x9d\x3c\x2a\x08\xe0\x9a\xbc\x0d\x7b\x81\x01\xc7\xce\xc3\xb4\xc0\x4f\xd4\x47\x79\x5e\x28\x43\x70\xc2\x78\x34\x72\x64\x8e\x85\x7e\x76\xb4\x8d\xa6\xa4\x47\x66\x71\x44\xd4\xca\x91\x85\x93\xf4\x1a\xe1\x78\x95\xd9\x5a\xc9\x43\x6c\xee\x2f\xab\x05\x28\x6e\xe8\x27\xca\xf7\x30\x88\x4e\x4c\x51\x77\xc6\xd6\xdd\xcc\xd1\x9e\x35\xd8\xc2\xcb\x8d\xb2\x82\xd6\xbb\xd9\x22\x1f\x30\xb3\x63\x44\xa3\x3d\xdb\xa8\xc8\xe2\x2b\x58\xbd\x57\xb2\x5a\xe3\x92\x65\xbb\xbb\x86\xca\xaf\x69\xff\x86\xfd\xd2\x4a\x65\x11\x2c\x99\xe2\x96\x79\xa0\x0a\x61\xe6\x4f\x9b\x26\x35\x64\x5a\x67\x26\x33\xd4\x2f\xf2\xf8\x2a\x01\x9a\xb3\xdc\xd3\x93\x84\x17\x0c\xff\x81\xa0\x60\x41\xf2\x8f\x57\x53\x90\x1d\xbc\x21\x23\xce\x1d\x6c\x9b\xee\xa2\x81\x3c\xd3\xcb\x2a\xc7\x26\x49\x05\x4a\x56\xba\x25\x2e\x80\x49\x36\xea\x85\x7a\x8c\xb3\x74\x55\x4a\x03\xbe\x03\xfb\xac\x2b\xbb\x20\xe4\x2b\xca\xe2\x3d\x43\xe2\x26\x4b\xf6\xd6\x6b\xca\xf0\x0d\xe0\x6d\xbb\x1e\xb6\xc9\xfa\x69\xe3\x65\x72\x46\x5e\x9b\x0d\xbc\x1b\xd5\xb8\xe4\x36\x8a\x57\x99\xa4\xc9\xb0\xdf\x4c\xef\x38\x29\x2c\x0e\x79\xb7\x4e\x79\x80\xb8\xc0\xaf\x52\xfb\x0e\x98\x2c\xf3\xbf\x1a\x2e\x44\x90\xb5\x5e\x6a\xb9\x90\x86\x7f\xda\xaa\x2a\xe5\xe3\xa1\x8b\xfe\xf0\xf6\x94\x3c\x9c\xf6\xdb\xc9\x03\x70\x86\x67\xd3\x03\x5e\x0c\x2f\x45\x05\xda\x67\x49\x4a\x29\x4c\x37\x61\x5f\x4c\xa0\x6c\x58\x94\x61\x29\x6f\x1a\x2a\xc1\x83\x98\x2a\x04\x38\x1a\xec\xd1\xac\xe1\x76\xca\x06\xd8\x47\xc8\xcc\xe9\xbe\x37\x8d\x50\x9e\x8d\xd1\xc4\x61\x8b\x63\x86\x24\x6c\xa7\x58\xa0\xd9\x29\x49\x6b\x80\x8d\x1a\x31\xae\xa3\x69\x4f\x61\x2f\x1f\xdd\x17\xf8\xe9\xf8\xa7\xcb\x6a\xe2\xa2\x27\xa9\x3d\xbb\x0d\xd7\x2d\xf2\x28\xed\xdf\xe6\x23\xeb\xbf\xe4\x17\x5f\x11\x46\xa5\x14\x3e\x64\xcd\xf0\x47\xfa\xfa\xb6\xf2\x48\xec\x4a\xa2\x51\xd3\x22\xfe\x61\x3d\xcf\xc3\xdc\x3a\x36\x4f\x72\xae\x50\x6c\xaa\x7b\x79\xc0\xa3\xac\xe3\x93\x57\x28\xeb\x38\x1c\xd3\x50\xe9\x24\xff\x9f\xb4\x09\xf6\x7d\xc7\xec\x84\x71\xcf\x28\x12\x70\x41\xd4\xb7\xf2\x3c\x45\x3a\xd4\x5f\x6e\xf2\x53\xb0\x79\xc3\xcf\x80\x2d\x36\x57\xfd\x42\xc7\xcc\x42\xf4\x60\xff\x48\xdf\xb9\x23\x7b\xcd\xdb\x2f\x58\xfc\x95\x73\xb1\x17\x85\x82\xec\x60\xe5\x7a\xb3\x25\xab\x26\xd8\x49\x86\xd8\x73\x6d\x62\xc5\xdd\x36\x1e\xab\x9a\x34\x62\xe7\x58\x01\xdd\xcf\x4e\x22\xdf\x69\x6f\x61\x27\x3b\xbf\x1e\xf5\x64\xce\x7f\xbc\xa1\xce\x63\xf2\x2e\x25\xbc\x05\xe4\x21\xb5\xdf\x21\xbd\xc0\xb8\x3e\xe9\x17\x14\x9e\xf5\x57\xfc\x71\x9e\xb4\xf4\x81\x20\x82\xa7\xc3\x66\x0b\xc0\x29\x6d\x85\x5d\xed\xbc\x17\xf6\x16\x6a\x46\xcc\x91\xbc\x09\xaf\x5a\x12\x26\xe0\xc4\x40\x26\x3f\x69\x3e\xdb\x3c\x7c\xb8\x97\x43\x53\x87\x56\x44\xb9\x46\x12\xe3\x75\x25\xdd\xb4\x7f\x69\xba\x44\xea\x29\x0c\x19\xe6\xc8\x40\xcc\x9a\xe9\xdc\x54\xea\x92\xd9\xbd\x9a\x55\x9a\xc2\xa1\xa3\x60\x33\x2a\x43\xab\xe5\x83\x14\x42\x88\x37\xe3\xde\x1e\x6a\x06\xa9\x47\xe3\x7d\xd5\x14\xfd\x20\x3c\xe4\x60\x6f\xe7\xf8\x65\xa6\x41\x83\xa1\x4e\xf8\xd6\x6f\xa9\xb9\xe1\xbb\x19\xbe\xc6\x88\x02\x64\x57\x67\xb1\x39\x26\x5c\xa4\x10\xe1\x43\xcd\x85\x9b\x5a\xbf\xce\xc4\xc7\x00\xb4\xd3\x80\x09\x6f\xe8\x1a\xd5\x55\x83\x41\xaf\x99\x5b\x88\x64\x95\x35\x2b\x44\x1c\xbb\x7a\x41\xde\x53\x8a\x07\xc4\x93\x3d\xfb\xaa\x75\x97\xc2\x1d\x66\x4b\x5f\x1d\x3f\xa1\xb8\xf8\xe8\x2d\x7a\x3a\xff\xdc\x46\x3e\xb0\x2b\xe9\x3f\x0d\xf2\x9b\x5d\x29\x5b\xd4\xb5\x65\x88\x40\x61\xb4\xa7\x66\x3e\x3e\x9c\xc0\x12\xba\x82\x72\xad\x3a\xa3\x75\x15\xdb\x03\x0c\x65\x5a\x85\x49\xfe\x8c\x7e\xd6\xbc\xeb\xe5\x1c\x10\xa4\xcc\x44\xed\x89\x2d\xfd\xe5\xcc\x00\x80\x49\xbe\x61\x36\x21\x77\xfa\xaf\x23\xb5\x37\x89\x4e\x28\x3e\x1c\xb2\x22\x01\x40\xa6\xf0\x56\xd1\x27\x2c\xd8\xd7\xaa\xa0\xca\xea\x9a\x63\x6f\x69\xd5\xac\x6c\x04\xb4\xc5\xd8\x78\x62\x02\xbf\xb7\xa8\xca\xdb\x9b\x42\x85\xf6\x51\x36\x75\xaa\x0f\x15\xd6\x84\x68\x84\x59\x7d\xcc\xdb\xc6\xe9\xee\x93\x47\x07\x58\xb5\x7b\xb3\xfd\xb9\x06\x40\xb6\xe6\x12\xdd\xcf\x96\x06\x6a\x83\x91\xa6\x1e\x6b\x5b\x93\x7c\xab\xc0\xae\xd8\xaf\xc5\xd5\x45\xa5\x09\xd1\x64\x95\x37\x55\x0d\x31\x09\x6c\x7c\x9a\x39\xd5\x2f\xd4\x13\x7c\x4a\x1e\xa9\xa7\xc0\x72\x50\x83\x66\xb0\x26\xe7\x17\x6b\x44\xb8\x7d\x75\x7b\xc8\x9b\x4f\x92\x27\xd6\xb3\x8a\xc7\x68\xc3\xdc\xe2\xb6\xd6\xd4\x17\xde\xbc\x7c\xd4\xa9\xaa\x07\xf3\x60\x97\xba\x7f\x23\xbf\x33\x4f\xb4\x9f\x52\x8e\x01\xc2\x3a\xdd\xfc\xea\x94\x19\xd4\xd9\xec\x2a\x97\x33\xbd\xf5\xfc\x33\x31\xbf\xca\x06\xf7\x42\xfd\xc9\x7d\xcb\x30\x78\x29\x8e\xc3\x2e\xc5\x67\x83\xa5\x44\x43\x0e\x01\xcb\xd2\xb7\x64\xed\x6c\xd8\x4a\x63\x13\x0d\xa5\x73\x14\x8f\xcb\x1f\x83\x36\xdb\xe3\xc0\xeb\x56\x1f\x8c\xff\xc3\x66\x8b\x32\xd1\x6a\x4a\x89\x09\xa1\x6a\x5a\x12\x3b\x50\x4b\xda\xce\x16\x49\x6a\xe7\x9e\x4b\x43\xfe\xca\x64\x13\x28\x5e\xe9\x6f\x5e\xd5\x9e\x92\xe7\x31\x66\x4e\xe9\x4a\xe4\xce\xca\x04\xcf\x4d\x41\x06\x91\x6c\xd0\x17\x4f\xbd\x9d\xa1\x53\xf3\x6f\x17\xdc\x94\x70\xe6\x9f\xed\x67\xe2\x0a\x09\x5b\x3b\x62\xad\x53\xfd\x70\xfa\x9c\xe0\x9e\x2d\xa3\x29\x02\x1a\x90\xa2\x94\xb0\x9e\x8a\xec\xcf\x8f\x7c\x97\xca\x19\xca\x94\xd2\x1a\x07\xa0\x23\xb5\x74\xcd\x72\xce\xf2\x0b\x98\xca\x11\x39\xdf\xce\x53\xd2\x40\x5c\x5b\x6c\x7c\x5b\xcf\xa9\x88\x6c\x3c\xd9\xf4\x39\xfd\xda\x5d\xd1\x03\x5b\x7d\x56\x86\x04\x05\x41\x3a\xa2\x01\xc1\x9e\xea\xe1\x4a\x14\x36\x8c\x64\xd1\xc3\x61\x68\x52\x00\xd8\xb0\x57\x66\xeb\xb5\xa2\x0e\x64\x18\xc4\x3c\xd1\x25\xac\xab\xd8\x21\xd3\x98\xa5\xe8\xe4\xa2\xa4\xd0\x2f\xa3\x73\x16\x6e\xdd\x68\x88\xa9\x89\x16\x6e\xcb\x53\x8e\x46\x86\xdb\x59\xb1\x05\xf6\x55\x73\xeb\x03\xe3\x04\x86\x35\x58\x69\x16\x91\xa4\xe8\x8a\x65\x8d\x28\x84\x81\x0b\x86\x5a\x5d\x67\xf8\xd9\x80\x6f\x36\xab\x47\x36\xd8\x94\xfc\xd1\x50\x8e\x58\x2d\x4d\xd6\x87\x8c\x47\xa5\x89\x93\x2c\xaf\xc4\x6a\x43\x96\x69\x68\x63\xd6\x2b\xde\xe0\x2f\x9c\xcd\xdb\x6c\x0f\x76\xd1\x28\x7d\x09\xd3\x29\x68\x3c\x16\x45\x3c\x9c\xbc\x45\x40\x07\xfc\xb0\x94\xd1\x00\x33\x15\x45\x9c\x16\xce\xe7\x9e\x70\x2a\x60\xc0\xc6\x1d\x0f\x91\x2d\x7a\x4a\x93\x72\xa6\x3f\xe1\xc4\xa3\x4d\x31\x91\xe8\x70\xd3\x26\x2b\x12\x67\x50\x45\xdb\x66\xee\x66\x4f\x7f\x2c\x83\x7a\x61\xab\x9d\x6c\xdc\x4f\xd8\xd0\x0b\x2a\x48\x1b\xd5\xe7\x1f\x95\x70\x3b\xce\x27\x21\xf6\x71\x6e\x4c\x65\xd8\x64\x85\x36\xa6\xb6\xe6\x98\x6e\x40\x47\x84\x3a\x19\x59\xb4\x61\x89\x88\x8e\x1c\x41\x0b\x2b\x78\x5a\xb3\xcb\xbb\xec\x60\x2d\xb3\x77\x75\xba\x8c\x41\x72\x17\x14\x5c\x33\x87\x23\xb1\xc6\x67\xc4\x6b\xa2\xf7\x30\xf3\x28\x42\xc8\xb3\xf0\x3c\xb7\x23\x70\x54\x1a\x50\x15\x7e\xd4\xe7\xea\xe7\xfc\x53\x88\x16\x2c\xb4\x6e\x76\xb4\x6c\xea\xf5\x7b\xb8\xcd\x71\x97\xac\x9d\x83\x9e\x45\x30\x45\x32\xda\x05\x3f\xc3\xca\xed\x99\x2b\x17\x8b\x67\xa4\x08\x3e\x33\x12\x23\xbd\x8a\x78\xe6\x34\x4a\x30\x93\x42\x15\x53\xe1\xef\x1a\xa5\xad\x6d\xfe\x5a\xb0\xc9\x33\xc2\x25\x9f\xda\x2b\xd9\xae\xfa\x25\xa1\x8c\x44\x6f\x4f\x59\x91\x64\xed\x9e\x7d\x65\xa3\xf3\x95\xdc\x76\xe0\x4d\xe8\xc7\x43\x18\x5b\x06\xb9\x96\x83\xe9\x64\x15\x65\x4b\x5e\x24\x56\xa8\xb7\x93\xff\x8d\x47\x70\x1b\x73\x5d\xc2\xb9\xc1\x76\x0a\x81\xc9\x83\x08\x66\x43\x3d\x63\xa0\xc6\x3a\xe5\x34\x3e\xd8\x56\x2f\xf3\x87\xaa\xa9\x62\x08\x4f\xd0\xa1\x86\x1b\xe6\xa0\x36\xf5\x50\xaa\x42\x2d\xce\xc0\x6b\xd1\x30\x9b\x0a\x1b\x66\x5b\x6c\xf1\x07\xba\x11\xfb\x48\xed\xe4\x61\x3e\xd0\xa2\xf0\xf6\x96\x95\x70\x6c\x94\x65\x66\x4e\xcc\x60\x7a\xb6\xf6\xd8\x51\xa4\x87\xb9\x40\xd3\xe5\xf2\x0b\x08\x8d\xb1\x16\x39\xfa\xc0\x68\x85\x85\xe6\xe6\x9c\x23\x3c\x76\x2d\xee\xcf\xc5\x3b\x18\x37\xcc\x8e\x9a\xad\x68\x61\xaa\x44\x7b\xae\x5e\x96\xe3\xf6\xd7\x0f\xfc\x1f\x32\x1d\xcb\xe1\xdb\xb5\x2b\x9c\x36\xb1\x69\x69\xf3\x1b\x8f\xe7\xc8\x6f\x87\x3b\x02\xbe\x7c\x62\xc6\xc0\xa0\x68\x12\x25\x99\xf7\x27\x59\x45\x1e\x2a\xab\x2e\x99\xfd\x46\xb2\x8f\x3a\x15\x03\xde\x23\x51\x58\x1d\x33\x25\xd4\xda\xd7\x2b\x1d\x0e\xf8\xc3\x6c\xb5\x15\x39\xb6\xb9\xe7\x16\x3b\x46\x85\xe2\x99\x12\x41\xc0\x9e\x8c\x41\xf1\xba\x0d\xc3\x7b\xeb\x64\x9b\x2c\xfe\x09\x4e\x9e\xa4\x76\xd9\x76\x90\xb1\x64\xc3\x4c\xcb\xb0\xb9\xaa\xeb\x05\xa2\xb0\xbf\x77\x6f\xbd\x3f\x42\xd8\xc3\xb7\x30\x95\xc4\xe6\xda\xec\x34\x45\x34\x47\xe4\x2b\x36\xa5\x17\x7b\x41\x7d\xba\xd5\xcd\xba\xd3\xfa\x8c\x4c\x8c\xeb\xd7\x64\xee\x9d\xf8\xad\x2b\xb4\xf7\x70\x51\x35\xce\xec\x97\x4e\xea\x9c\xad\x52\xfc\xc0\x41\x34\xee\xd7\x46\xc4\xb6\xea\x6a\x82\x85\x1d\x57\x18\x8f\x81\xe5\x42\x0a\x5a\xf7\x61\xd4\xeb\x87\x8d\x9a\x7a\xb7\x3e\x18\x55\x30\xf0\x38\xd8\xd5\x94\xf3\x00\x06\x79\x6e\xb5\xce\x89\xcd\xbd\x6c\x77\x54\x36\x55\x6a\x84\xab\xd9\xa8\xf0\x59\x72\x22\xed\xe8\x98\x16\x4d\xb3\x68\x6e\xd5\xfc\xff\x8b\xbc\xf5\x3f\xe6\x3b\xfa\x64\x8a\x99\xb0\x3d\x69\x4b\xc8\x98\xe1\x55\xe2\x50\x0f\xfa\x64\x6b\xeb\x8e\x45\x2f\x2c\xfa\xd8\x36\xd4\x01\xe8\x6a\xf0\x81\xba\xf2\x65\xcf\xab\xc4\xcc\xd6\x45\x08\x75\x67\x13\x6a\x24\xcc\xfe\x10\x10\xc8\x7d\x66\x1e\xc3\x55\xeb\x97\x75\xdf\x49\xaf\x0f\xa7\x2d\x7a\x89\xb5\x4e\x1a\xfe\xa1\x37\xb4\x3c\xf8\x42\x1d\xa9\x33\x52\x33\xf6\xa4\xce\x54\x17\xf6\xb3\x1d\xbe\xeb\x52\x9e\x1c\x22\x57\xff\x6a\x21\x1a\x76\x11\xd6\x96\x82\x3b\xec\xe1\xa4\xdd\x65\x9f\x82\xfe\xed\x64\xe5\x9f\x10\x28\x3c\xbb\xe0\xff\x46\x3d\x0f\x12\x25\x69\xa3\x75\x7d\xd4\xc7\x8a\xe4\x5f\x60\xd1\x6b\x69\x2e\x5b\x77\xe3\xf7\xc1\x86\x4b\xee\xa6\x1d\x38\x6f\x52\x0d\x59\x15\xf0\x95\x5f\xd7\xc6\x97\xfa\xb9\x85\x74\xb6\x99\x08\xbd\xd1\xba\x86\x49\x97\xc2\xcb\xba\x34\xb0\xb9\xd3\x14\xbe\x20\x15\x9f\x3c\xe6\x5f\xd6\xed\x7f\xea\x4a\xfd\x97\x57\x2a\x54\xdc\x24\x90\x92\xa2\x78\x22\x52\xfa\x71\x3c\xe6\x50\xc6\xd9\x8e\x58\x5d\xb7\xb4\x2f\xc4\x95\xd1\x32\x7b\xc5\x6d\xc3\x99\x65\xcb\x09\xcb\x00\x3f\x34\xef\x05\xd8\x23\xc5\x68\x53\x5c\xc8\xea\xaa\x57\x7f\x77\x6b\x96\x29\x05\xf3\x40\x38\x71\xa4\xf1\x54\x30\x08\xcd\x90\x93\xad\x7c\x89\x86\x32\xee\x6b\xa2\x0f\x61\x27\xea\xcb\x8f\x83\x7e\x81\x84\x6a\x96\xbf\xef\xf7\xb3\xfb\xff\xfa\x56\xce\xf2\xdf\x59\x06\x5c\x37\xb5\x9b\x5f\x02\x17\x5f\xf8\x91\x29\xc8\x17\xeb\x0c\xcf\xd3\x4f\xd1\x8a\xfe\xb1\x89\x58\x5f\xfa\x07\x5a\x34\x57\x09\xd9\x22\x68\xab\x96\xf7\x92\xca\xb4\xc2\xb6\xca\x87\x79\x65\x58\xf0\x1b\xc5\x3c\x8f\xd1\xe4\xda\xbf\x31\x58\x34\x68\x6c\xa3\x37\xd0\x53\xde\x06\xc2\x97\x63\x30\x6f\x70\xd1\xbc\x4f\x06\xc5\x91\x4f\x4b\x6f\x29\xb8\xdf\x3c\x27\xdf\x79\xee\x14\xdb\x2b\x1b\x28\xd7\x17\x71\x94\xde\xa7\x7d\x7a\xb6\x1c\xde\x52\x01\xbd\x71\xfd\xee\x11\x31\xc2\xe9\xfa\x9d\xb8\x0b\x7a\xd3\xa1\x94\xef\x82\x94\x5b\x98\x67\xa9\x2f\x66\xf3\xae\x3c\xe4\x5e\x25\xec\xb1\x61\x93\xc5\xfc\xdd\x59\xd1\x24\xab\x57\xa1\x2c\x88\xac\x9e\xfa\x9c\xf2\xc6\xc2\x4c\xfd\xb2\xf7\x1e\x42\x25\xd1\x22\x5e\x10\x3f\xb1\x79\x55\xaf\xd6\xdc\xb2\x33\x70\xfd\xa7\xed\x15\xfa\xc5\x97\x4d\xba\x73\xeb\x70\xf1\x18\x61\x9c\x2f\x21\x93\xf5\xfb\xf5\xef\x03\x1b\x0b\xff\x3d\x42\x4b\x59\xa3\x13\x6e\x5b\x5a\x52\xf6\x6e\x25\x0e\xde\x1e\x28\x43\xf1\x52\x73\x89\xbd\x91\x7f\xc0\xc7\x17\xcd\xba\x77\x21\xb6\x72\xcf\xfc\x09\xec\xe8\x93\xd3\x1d\x93\xd3\x3d\xcd\x08\x65\xf1\x3d\xfd\x8d\x70\x3e\x99\x03\xde\x61\xba\x7a\x2b\xb3\x37\x6c\xe1\xd0\x72\xef\xbf\x1f\xef\x53\xbc\x21\x32\x50\x6a\x6b\xe5\xb7\x89\xdd\x77\x6b\x41\x81\x73\xf4\x60\x83\x6a\x4f\xe1\x83\x55\x23\x0d\xd7\x8a\xf6\x2d\x9e\x84\x98\xa2\x48\xbb\xcd\xf4\x39\xb3\xc1\xdf\xb5\x24\x29\x85\x22\x1f\x24\x4b\xc2\x94\xb5\x41\xb5\x51\xb3\x7c\xb2\xe1\xd2\xdc\xb1\xf6\x60\xed\x60\x2c\x3a\xcd\x75\x2a\xfa\x16\x09\xb9\x7e\xc3\x91\x95\x74\x5b\xac\xc4\x27\x0e\xeb\x4d\x27\xbd\xe2\x2e\xdf\xdd\xab\xb9\x4c\x5c\x00\x4b\x9a\x60\x28\x52\xd8\xd1\x79\x8a\xde\x12\xdf\x31\xbc\x7e\x67\x0e\xc2\xf3\x6a\x68\xc7\x3d\x46\xc3\xfc\x3f\x36\x9b\xec\x7b\x08\xdd\x10\x85\xf2\xa8\x6f\x4b\x28\x89\x86\xa1\xfe\x7f\x54\x5d\xe9\x92\xb3\x3c\xaf\xbc\x97\xf9\x7d\x6e\xca\x80\x03\x0c\x8b\x79\x01\x27\x4f\x72\xf5\x47\xad\x6e\x39\xf3\x55\x4d\x15\x0a\x01\x86\xb0\x78\x91\x7a\x91\x0c\xd5\x9b\x47\x47\xca\x64\x55\xa4\x9e\xd3\xa2\x45\x15\xa7\x80\x53\x41\xd9\x4a\xd5\xa6\xac\x46\xfd\xca\x6d\x40\x7e\x61\x18\xc5\x32\x5f\x3f\xa1\xea\x7c\xc5\x1d\x00\xa8\xe5\xbc\x3f\xdf\x8f\x9c\xcf\x51\xd5\x8a\x41\xb8\x96\x40\xdd\x4a\x60\x64\xaf\x48\xdd\x31\x6f\x47\x4d\x6a\x0e\x05\x33\x4a\x5d\x29\x4c\xb1\x27\x49\x3d\xd6\x6d\x3f\x2b\x91\x38\xc8\x33\x1f\x2c\x41\x61\xf4\xd7\xd4\xae\x46\x45\x83\x0d\x95\x48\x32\x72\x1f\x5f\x46\x1b\x0b\x54\x84\x1c\xda\xe8\xfd\xd3\x5c\x44\xde\x89\xae\x1d\x5e\xc6\xf2\xe5\x3c\xb0\x66\xc5\xe4\xde\x95\x12\x39\x44\xfb\x4c\xae\x17\x26\xa7\xdf\xf2\x13\x2d\x44\xb2\xc7\x77\xdd\x77\xd1\x85\x64\x06\xbc\xed\xf2\xfa\x9d\xc2\x3f\x58\xfa\x57\xfd\x22\x6a\x34\xa0\x3d\x1b\xeb\xce\xe7\x2c\x4a\x1b\xca\x4d\x64\x0f\x39\x8c\xe5\xc1\x32\xd2\xbf\x93\xa3\xc3\x53\x0a\xd0\x67\x56\xa1\x2c\x53\x2d\x06\x2c\xc3\x07\x4b\x45\x48\x28\x90\x55\x94\x25\x6d\x6a\x01\xa6\xe7\x1e\x85\xfd\xc7\x2b\x7c\x45\x40\x12\xee\xcf\xd4\x6c\x44\xc8\x79\x82\x3b\xb6\x2f\xf7\xc1\xaf\x27\x34\xaf\xe6\x6f\x4d\x8a\x6e\xc6\xc9\x1e\xc4\x39\x02\x5f\xca\xcd\xef\xd4\x2c\xcd\x9a\x1d\x66\xf5\x30\xc7\x13\x73\xeb\x3f\x38\x39\x06\xa1\xe9\xa8\xbf\x85\x0a\x59\x20\x58\xa8\x98\x73\xba\x3a\x2e\x23\x9b\x35\xa9\x56\x35\x4a\x21\xab\x91\xa1\x0e\xbb\x16\x2c\x4a\x9d\xb7\x26\xfe\xd0\xc1\xe2\xaa\x03\x6a\x5c\x8c\x58\xd9\xb1\xe5\xaf\x1b\xd2\x1e\x65\x3b\xbc\x8a\x72\xac\x75\x50\x89\x2a\xaa\x56\x36\xcf\xaf\xd4\xad\x9a\x3f\x5a\x13\xe6\x67\x47\x60\x7d\x51\xa7\x3a\x25\x84\x35\x89\x61\xa4\xc4\x8d\x4d\xc6\x2e\x71\x26\x8f\x89\x3e\x47\xc8\xe4\xb3\x67\x3e\xb2\x9c\x54\xe0\xad\x28\x7c\x1e\xe5\xb1\x58\x8c\x3a\x1f\x51\x38\xca\x2e\xe6\xe5\xd1\x3e\x15\x8d\xc4\xed\x2d\x95\xa2\xd6\xba\x86\xc1\xc8\x93\x82\x06\x30\x4b\x66\x19\x0a\xcc\xcb\x59\xb6\xc9\xa7\x32\x33\xc7\x17\x3f\x07\x66\xd1\x2f\xcb\x50\xed\x5f\x84\x0d\xfa\x91\x7e\xfd\x60\xe5\x55\x2f\x74\x6a\x61\xb8\x80\xdc\x1c\x2b\x4c\x8e\xf6\x42\x10\xe8\x55\x97\x27\xd6\x64\xb6\x64\xcd\x42\xfc\xc3\xf0\x92\x74\x57\x0f\x31\x08\x92\x8b\x00\xa7\x8a\x6b\xb8\x7f\x05\xe8\xf6\xba\x1e\xae\xa5\x85\x51\xa4\xdf\x62\x2f\x55\xf9\x6b\xb7\x97\xb3\xa9\x75\x0d\xde\xaa\xed\x24\x75\x51\x9e\xeb\x27\xc4\xb9\x7c\x0b\x37\x2c\xf5\x40\x6e\x28\x98\x18\xb3\xf6\x85\x49\x91\x97\xb2\x00\xca\x20\xf3\x6a\x77\x1b\xe4\x81\xc9\xf6\xad\x5e\x3e\xd1\xda\x50\x41\xe5\x32\x95\x85\xd1\xc6\xfc\xed\x56\x6d\x3c\x29\x0e\xd2\x7e\xff\x2a\x94\x08\xb6\xdb\xa4\xb0\xcc\x60\x11\x6b\x60\x60\xa6\xa9\x78\x65\x03\xfa\x21\x97\x3e\xd6\xa3\x10\x34\x9e\x51\xfd\x4a\xfb\xfb\x1b\x0e\x3a\xc8\xcc\x89\xed\x46\xfc\xd1\xe6\x15\x56\x16\xb3\x6e\x39\xa3\x68\x14\x68\xc1\xaf\x44\x97\xa1\x01\x56\xe4\xa1\xee\x7c\xa5\xaf\x4d\x33\x6a\xe9\x3c\xd1\x2c\x6a\xc2\xd6\xc4\x3c\x36\x38\x25\xb0\x52\x85\x7c\x0f\x7f\x7f\x5e\x47\x3c\x2a\x52\x04\x6b\xbc\x18\x54\xb5\x5a\xdc\x3b\x1a\x8f\xa5\x28\x7b\xfe\x55\x7c\x82\x4a\x8f\xea\x48\x76\x63\x54\x82\xeb\x47\x78\x74\xa8\x94\xd2\x8f\x73\xd7\x85\x64\x98\xb5\xd6\xb2\x52\x41\x82\x44\x3b\xda\xb4\xfa\x8c\xca\x56\x8f\x24\x67\x14\xbf\x80\x23\x53\x0d\xa7\x87\xb7\x63\xf3\x50\x01\x4c\x53\x3c\xa4\xb7\x0a\x36\xff\x82\xb2\xf4\x8a\x42\x93\xfd\x03\x55\xbd\x5c\xcf\x3a\x56\x5b\xac\x62\xcf\x7d\x55\xf9\x34\x6d\xe9\x62\xbd\xd6\xcd\xa0\xb9\x24\x31\x03\x81\xf8\x51\x71\x8e\x98\xde\x68\x9b\x7e\x66\x07\xcb\xd0\x83\xbd\x95\x3a\xad\x9b\x7a\x87\x63\x74\x78\xb3\xec\x32\x5e\xf1\xec\xb0\x6b\x39\xfe\xb0\xec\x94\x54\x0a\x5b\x51\x9c\x66\x24\x38\x38\x6a\x51\x34\xe6\xd8\x52\x0f\x35\x38\x86\xcc\x4c\xac\xe1\xc2\xbb\x72\x32\xbe\x56\xb4\x26\x3e\x38\x5d\xab\xf2\x58\xa8\x36\x51\x11\x0c\x6d\xa4\x17\xa7\x00\xf2\x94\x42\x99\x3d\xf7\xd1\xfb\x43\xa4\x4c\xd6\x23\x45\xbe\xcd\x6b\xf9\x22\xa4\x31\x16\x3a\x09\xf1\x5b\x9b\xe2\x13\x74\x26\x58\x81\x77\x7a\xa1\xd7\x76\x9c\xcd\x75\xf0\xe5\x5e\x23\xab\xb8\xce\x9a\xc3\xc3\x6b\xe5\x12\xed\x2b\x77\x41\xbb\x0a\x55\x35\x14\xb1\x52\x44\x2a\x77\xe5\xa7\x9c\xb4\x91\xd8\xe2\x32\x8a\x8d\x2b\x11\x9d\xfe\xff\x9d\x49\x2d\xd2\xd7\xe5\xb0\x0f\x3b\x8b\xf0\xbd\x16\x45\x7c\x95\x00\xaf\xbd\x91\xb4\xde\x5a\xe9\x5d\x1b\x76\x2c\x4e\xfe\xe1\x86\x8f\x1c\xbf\x27\x4b\x6c\x77\xcd\x29\x4a\x68\xd1\x9a\x59\xb4\x85\x2d\xf6\x47\x95\xad\xe7\x5c\xa2\x92\xbf\xe2\x21\x54\x0d\x2d\xc4\xd8\x6c\x12\xc0\xc2\x98\x2e\x42\x0a\x77\x98\x10\x77\x5c\xc3\x76\x6a\xa5\x26\xb4\xb7\xbd\x78\x27\x58\x23\x93\x25\x30\xea\x66\x57\x69\x15\xb4\x1f\x71\xc7\xe2\xbb\x50\x75\x4b\x23\x9d\x71\xec\x21\xaa\xbb\x20\xaf\xb0\x89\x41\xeb\x73\x33\x96\x27\x4e\xea\x08\x22\x59\x53\x5a\x3c\x31\x0e\x85\x26\x5f\x64\xc1\x5e\x60\x18\xc3\x82\xd7\xe9\xbe\x17\x0b\xec\x85\xf9\xb9\xb0\x78\xf6\xad\xac\xe5\xca\x0e\x75\x29\x4f\x82\x32\x97\x72\x7c\xcb\x57\x45\xea\x8c\xa0\xa2\x91\x40\xb9\x48\x30\x64\x89\x14\x1b\x1c\x61\xd4\x13\x2d\xf2\xe6\x5b\xbc\x4e\xf1\xe3\x22\x6d\x7d\xb0\xc7\xce\x2b\xd4\x63\x16\xc7\x55\xb0\xaa\x26\xf9\xa4\x25\xcc\x7e\x97\x1c\xf5\xb6\xed\x58\x65\x14\x83\xbe\x29\x34\x18\xed\x8d\x6e\xac\xb6\x9c\x48\x30\x8b\x0d\x31\x55\x67\x21\x6e\x23\xba\xfe\xb7\xde\xac\x03\x39\xc3\xec\x24\x55\x2c\xb4\x5e\x7e\x53\xc3\xb8\xfd\x26\x9a\x2e\xcf\xd7\xe2\xad\x38\x50\x88\x27\xa1\xdd\xf3\x42\xf1\x5a\x1b\xc7\x7a\xe5\xe4\xdd\x48\x56\x6f\x56\xa5\xa7\x7a\x25\x39\x87\x07\xcd\x02\x23\xed\x18\x8a\x4e\x35\x46\x05\x93\x84\x32\x26\xcf\x7b\x90\x0b\xf6\x26\xc9\x0c\xf9\xd2\x39\xaa\x6c\x61\x51\x8b\x2a\x9b\x2f\xc4\x38\x44\x01\xed\xe2\xb2\xa9\xac\x95\xb5\x15\xef\xd6\x21\xb7\xb0\x93\x34\x5c\xbc\x23\x10\xe3\xf5\x13\x83\x34\x65\xf3\x74\x19\x44\x00\x5b\x55\xac\xfb\x3a\xc5\x64\xa1\x8e\x5c\xc2\x36\x28\x58\x79\x18\x8f\xe0\x9c\x59\xeb\x2e\x65\xe2\x49\x32\xe3\x28\x8d\xbd\xa8\x1c\x3f\x49\x49\x74\x6a\xa4\xc4\x09\x98\x68\x1a\xb9\x5c\x61\x49\x8a\x82\x98\x0d\x62\x1f\xaa\x84\x85\x4c\xdc\x79\x8a\x21\x76\x1e\x5a\x0e\x73\xe8\xc5\xad\x34\x28\x5f\x57\x49\xbd\x01\xf1\xa0\xba\x56\x98\x48\x4d\xae\x0a\x19\x94\xb6\x14\x6c\xba\x94\x0e\x9a\x36\x8d\x55\x86\x56\xa3\x9b\x07\x8b\x77\x55\x49\xa0\x1f\x6b\x64\xcc\xc6\x3a\x48\xac\xed\x94\x71\xf3\x78\x42\xbd\x47\x91\x7e\x33\xa8\x62\x45\x72\x70\x59\xcf\xed\x78\x46\xb1\xc9\xba\x7c\x2f\x60\x95\x53\x2c\xb1\x73\xe4\x80\x75\x2c\xe5\x0a\xe6\x18\xd1\x33\xa3\xa4\x56\x00\xa6\x69\x59\x37\x74\xcd\x90\x37\xf3\x33\x03\x6a\x4b\x1d\x88\xc5\xc3\x4b\xa6\x31\xe8\x39\xfd\x90\xf3\x6a\xf7\x43\x6f\xe1\x88\x5b\x4b\xa2\x98\x3a\x07\x97\x8b\x63\x95\x4b\x39\x77\x15\xc7\xa8\x25\x77\x4b\xb4\x66\x4c\x41\x6f\x01\x77\xac\x44\xa5\x2c\x82\xf0\x92\xb1\x57\x49\xa4\xcc\x31\xb2\xd1\x16\xb8\x90\xf6\x08\x86\x46\x94\xa1\xea\x1f\xd9\xfb\x50\xed\x94\x76\x8e\x2b\xc9\xb1\x86\x75\xfe\x29\xa5\xb1\x44\xa1\x72\x05\x2b\x69\x2f\x55\xd4\xaa\xda\x91\x07\xf0\x87\xe7\x38\xab\x72\x76\xaa\x24\x6d\xed\xe4\xa0\x60\xbe\xc8\x3d\xe3\x5c\xfe\x61\x43\x16\x96\xb3\xc0\xb4\x56\x8d\x13\x5e\x34\x28\x0d\xfb\xfa\xf9\x0a\xf9\xe1\x47\xe4\xa9\x1e\x73\xd8\xf0\xa2\xb0\xe6\x17\xec\x91\xd9\x79\x3e\x9c\x30\xa9\x3c\xcb\x03\x4f\x78\x50\xc1\x1f\x3e\x34\x61\x85\x0e\x30\x97\x29\xae\xa1\x97\xc8\x9c\x28\x76\x35\x73\xb9\x46\x24\x42\x81\x5a\xba\x39\x20\x68\xfa\x0d\xcc\x0b\x7f\x54\x5e\x06\x52\x0d\x72\x48\x45\x5a\x67\x18\xdc\x30\xa6\x8a\xb9\x5d\x22\xab\x22\x27\x9a\xb4\x0d\x95\xf2\x3c\x43\xdd\x91\x32\x24\xbd\x0c\x30\x45\x96\xb9\x64\x69\x3d\x54\xde\x01\x5b\xb2\xb2\x84\xe4\x3f\x8b\x64\xa0\xab\x88\x4e\xe6\x4d\x97\x8d\x7e\xd7\xc6\x17\x13\x72\x69\x28\x9b\x37\xa3\x43\x81\xa4\x57\xd1\x14\xd1\xcf\xc9\x57\xc3\x96\x9c\x3b\x07\xbb\x78\x98\xd7\xba\xae\x51\xf8\x8a\x4a\x97\x8f\x10\x3c\xba\x38\xa0\xb7\x60\x2f\x72\x7b\x85\xff\x4c\xbd\x59\xaa\x05\x87\xac\x4a\x82\xee\xec\xde\x9e\x76\xf1\x0f\x3b\xdb\x07\x6b\xff\x74\x0e\x39\xcc\xe9\x50\x2c\x0b\x26\xda\x2a\x99\xa8\x21\x10\x61\x43\xfe\xad\x32\x83\xf7\x9c\x26\xd7\x11\x93\x32\x40\x67\x88\x5f\xc9\xc9\x67\x80\x90\x07\xbf\xfa\xaa\xe2\xf5\x75\xe6\x77\x21\xeb\x62\x33\xe0\xeb\xad\x25\x37\x96\xbb\xea\x90\x5e\xbc\x0f\x78\x5a\x06\x71\xba\x86\xc6\x0c\x19\x42\x79\x78\x80\x06\x16\x03\x96\xf0\xfc\x94\x6d\x64\x21\x06\x55\x25\xc8\xce\x96\x60\x7c\x65\x86\x49\x7a\x28\xfd\x59\xe7\xe5\x9a\xe8\xc5\xe3\x55\xb8\xf0\x9c\x39\xa3\xc5\xe9\x31\x12\x78\x33\x78\x84\x7f\xce\x4c\x51\x91\xfe\xcc\xd6\xc7\x73\x96\xda\x17\x8d\xb3\x51\x88\xe3\xa4\xd2\x46\xb9\x36\xdf\x29\x32\xa7\x07\x1f\xc5\x9d\x01\xdc\xd1\x7e\xe7\xa6\xd1\x95\x48\x49\x4f\xc7\x2f\x5d\xd7\x3c\x72\xc8\xe8\xe8\x57\x11\x41\x7a\x52\xb1\x7a\xf8\x41\xb3\x32\x87\x4e\xcc\xbf\x41\xfd\xcd\x8f\x3f\x41\x96\x99\xc5\x39\x74\x32\x2c\x15\x42\x2b\x85\x92\x78\x13\x9b\x25\xd0\xdd\x7c\x09\xa3\x68\x52\xec\x6c\x30\xae\x72\x1b\xd2\x22\xfe\x0b\xf3\x10\x5c\xb2\x77\xbe\x23\x7c\x41\x9a\x51\x45\xba\x27\xac\x6c\x64\x4b\x6f\x5d\x01\x01\xb0\x20\xbc\xad\x73\x78\xe5\x9c\x7f\xab\x73\x5f\x42\xdf\xb7\xac\x62\xe1\x18\x72\x7d\xf8\x7f\x1f\x71\xda\x82\x8d\x97\xd6\x10\xc2\xf5\xe4\x8f\xbc\x7c\x6c\x1a\x91\x46\x9d\x11\x8d\x91\xc2\x97\xaa\x7b\x4f\xad\xa0\x17\x52\x7e\x6d\x49\x8f\x3b\xf8\xe9\xcc\x61\x94\xcf\xf1\xb2\x17\xf8\xa2\xfe\xd7\x26\x95\x80\x52\xc3\x82\x04\xe1\xf9\x6e\xb5\xba\xad\x15\xf0\xec\x14\xa8\x0c\x67\x61\x54\xef\xca\x15\x06\x86\x16\xeb\xd4\x41\x87\x53\x16\x17\x8a\x63\xd1\x95\xba\x8d\x7e\x44\xfb\xf5\x35\xcc\x91\x7f\x9e\x33\xe1\x32\x83\xf1\x8f\xb4\x5f\x14\xf8\x36\x11\x91\x3a\x38\x37\x35\x1b\x9e\x02\x99\x76\x0f\xae\x28\xfa\x9d\x55\xe5\xa7\xa6\x53\x23\x01\xa0\x8b\xe1\x18\x76\x3e\x45\xa6\xc5\x9d\x30\xbf\xce\x7e\xd3\x6f\x28\xaa\x6d\x58\x20\xf9\xbf\xf2\xf6\x7f\xa8\x6a\x57\xa3\xa0\xcd\x50\x90\xfd\x61\x59\x90\xdf\xc0\xad\x59\xba\x7e\x1f\x5e\xef\x4c\x51\x99\xae\x65\x8e\x9c\xa6\xc6\xaf\xc0\x43\x5c\xf5\x6d\xaf\xf3\x09\x9d\x2d\x0b\x9a\x7b\xcf\xba\x3b\x42\xb0\x73\xd0\x03\x2b\x82\x84\xb6\x41\x11\x90\xd5\x01\xd6\x0b\x95\xc4\xef\xb2\xa6\xc1\xac\xf7\x69\x1f\x8f\x19\x9c\x5f\xa3\x9d\x2e\xab\x6a\x68\xbd\x97\xa2\xfd\x29\x43\xfd\x0e\x25\x26\xd5\xf5\x00\x3b\x0c\x91\xc0\x60\xb8\x5d\x04\xcd\x27\xcc\xc8\xfd\x19\xb5\x48\xd2\x42\x4e\x73\xdb\xed\x76\xea\x26\xda\xb1\x59\x0e\x3c\xb7\xb0\x14\x77\xf3\x2f\xb6\xc3\xee\x58\x18\x08\x13\x7d\xf0\x4a\x9e\x2b\xe2\x7b\xef\x15\x80\x06\x2f\xee\x09\x77\xee\x56\x9a\x7e\xd4\x0d\x49\x3a\xb2\x56\x41\x8f\xe3\x41\x21\x81\x8c\xe1\x35\xeb\x7a\xf2\xf9\x59\xd9\x3f\x24\x70\xc4\x3c\x6d\x9b\x5c\xca\x17\x41\xf6\x04\xb7\x4c\x7a\xfa\x5e\xd7\x28\x75\x83\xe0\x00\x89\xa5\x8f\xcf\x8b\xed\xef\xa7\x62\x1c\x86\x60\x3e\x9b\xa4\xe0\xc8\x8b\xf8\x99\xdd\x34\xc3\xa5\x08\x91\xd8\xf7\x13\xfa\x10\xc7\xfe\xc9\xec\x22\x3f\xe9\x9d\x7a\x5f\x9e\x01\xc5\x26\x2b\x8e\x02\x3c\x28\xf5\x71\x96\xf5\x92\xe9\x3c\xac\x74\x82\xf2\xc6\x5f\x83\xa1\xf5\xc9\x1a\xe0\x3a\x90\xd0\xc6\xd9\x17\x96\xe2\xa1\x79\xb3\x44\x0d\xc1\x79\x97\x1d\x8a\x45\xb1\x2a\xa0\x6f\xa2\xbb\x79\x38\xcd\x41\x51\xa5\x02\x21\xc9\x75\x6e\xce\xe1\x49\xec\xd7\x14\xf3\xf7\x97\xad\x08\xbe\xdb\xfe\x91\xec\x20\xeb\x80\xae\x28\x28\xae\x1c\x35\x9d\x5f\x8d\x75\xf3\x92\x97\x95\x93\xd9\x54\xf2\x1b\x64\x3b\x53\xf6\x53\x43\x10\xba\xe2\x78\x35\xae\x50\x64\x08\x39\x4e\x1b\xe8\xb4\x12\xdf\x2a\xcb\x1b\x0b\xfb\x59\xe4\xb6\xbb\xaa\x5f\x50\xcc\xa8\x69\x0c\xae\xac\xc0\x58\x34\x15\xc9\x99\xbb\xd3\xcd\xa7\x85\x52\x57\x64\xcd\x8f\x26\x4b\xaa\xff\x45\x96\xe3\x09\x73\xc9\xbc\x44\xd4\x75\xda\x01\xa5\xbd\x9e\xd5\xc3\x55\xcc\x3a\x62\x90\xaa\xbd\x5c\x7e\xc3\xea\x71\x4d\x5e\xae\xaa\xdb\x63\x25\xa0\xf0\xbe\xea\x2f\x59\x6e\x6f\xd2\xa0\x6e\x78\x4b\x15\x06\x4d\xb7\xe7\xb6\xbe\xca\x5f\x2c\xe8\x13\x0a\x86\x7c\x17\x15\x10\x61\xa8\x3e\xee\xe2\xc5\x9d\xb1\x4c\x92\x28\x6c\x8d\xde\x5d\x36\x19\xee\x5c\xa1\xd3\x7a\xcf\xfb\xd2\xa2\x41\x41\xbf\xec\x85\x51\x27\xdc\x12\x22\xea\x18\xbb\x0f\x5e\x7b\x55\xd1\x45\x6e\x51\x9a\xbd\xa7\x50\xf1\xf5\x88\x23\x39\x7b\x08\x2a\x59\xa1\x37\xa6\xee\xfc\xc5\x79\x94\xcd\xcb\x0d\x8c\x99\x5a\xe2\x3b\x55\x65\x93\xee\x3f\x6e\x53\x77\x6a\xbc\x3b\x4f\xb2\xf5\x5c\xd9\x15\x56\xee\xaf\xf7\xa1\x7a\xd4\x5b\xff\xfb\x7a\x69\x90\x78\xd9\x93\x1f\x25\x0a\x1b\xf1\x0c\x51\xfa\x0a\x12\xd0\x55\x4f\xa7\xcc\x50\x02\xb1\x79\xe0\x54\xca\x82\x5d\x75\x1c\xb4\x42\x35\xbe\x2a\xeb\x5c\xf0\xe3\x5b\x09\xb4\x1c\x8a\x40\x95\x09\x4d\x28\x62\x45\xc9\xbc\x73\x09\x49\xed\x96\x42\xbc\xfa\xba\x09\xe5\xf5\xd3\xbc\xed\x26\x53\x52\x0f\x51\xcf\xe0\x11\x47\xb2\x2b\x25\x01\x3d\xb2\xfb\x82\xd0\x37\xad\xe1\x1e\xe4\xd4\x3e\x11\x08\xb3\x38\x58\xfc\xe4\x16\xa8\x2a\x9d\xae\xc1\xf6\x3a\xce\x34\xba\x5e\xc8\x75\xb0\x9d\xb9\x8e\xf9\xab\xba\xc8\x3a\xdb\x91\x50\x32\xe6\x19\x1c\xaa\x71\x5b\x80\x41\x80\x7f\x5f\x9a\xd3\x8f\x18\x5b\x2e\xc1\xc8\x13\xda\xf3\x3a\x9e\x52\x5c\xdc\xb3\xc6\x2a\xd7\x46\x08\xe4\xb5\x8a\xe8\x8c\x1c\xf1\x22\x6b\xa6\xf9\xf4\x6a\xb4\xbd\x18\x71\xfd\xec\x15\xb9\x55\xb3\xd0\xeb\x82\xc7\x81\x68\x07\x9b\x8c\xbc\x36\x51\x13\xa1\x14\xc3\x65\x38\x28\xb9\x22\x0c\x9e\xbb\x6b\x3c\x45\xdb\x7b\xd0\x07\xe2\xca\x87\x26\xfb\x57\x16\xf8\x1a\x81\x7e\x5c\x4e\x8d\xba\x67\xc3\x65\xf1\x31\xad\x49\x71\x2a\x21\x4b\xa9\x3f\xdf\x2a\xaa\x7e\x3c\x3e\x09\x00\xe8\x7a\x8c\x51\x0d\x2d\x50\xcb\x0f\x99\x46\xe4\x0e\xd4\xae\x82\xc8\xd7\xd4\x22\xfb\xf6\x62\xb8\x24\xe3\xac\xa3\x20\xb5\x32\x86\x52\x62\xd5\xab\x61\x91\xf8\x06\x57\x9b\x8b\x5f\x40\xea\xdb\x88\x5a\x64\x3e\xbc\xbc\x0f\x5e\x2a\x60\x7c\x19\x70\xde\x77\x25\xe5\x30\xaf\x44\x52\xc4\x95\xbe\x44\xc5\x44\x9d\xe6\xf3\xed\xed\x96\x35\x41\x89\x54\x3f\x4d\x74\xa1\x72\x20\x22\x1f\xe6\x83\x51\x05\xd5\x15\x38\x69\x2b\x75\x16\xa9\x97\x82\xdf\xd7\x58\x7f\x5c\x6e\x7a\xed\xce\xf2\x2b\x66\x5c\xe9\x27\x6d\xdc\x79\x69\xf0\x47\xba\x8b\x34\xed\x29\xcc\x1f\x41\x30\x81\x5c\xbe\x9d\x7e\x4a\x08\x34\xed\x05\x64\x83\x15\xd8\xe8\xbb\xce\xb9\x4b\x2c\xae\x3e\xc3\x3b\xc8\xcd\xe2\x7e\x58\x5d\x95\x9c\xc3\x99\xc3\x0f\x28\x13\xb5\x0a\x87\x50\x99\x01\xdd\x4c\xfe\x41\xbe\xe3\xc3\x7a\x6a\x28\x7a\x9d\xcd\x30\xe0\x4c\xa4\xa1\x9c\x32\x65\x12\xdb\xe6\x4c\x54\x93\x4c\xfd\xc2\x01\xf9\x29\xc7\xa8\x13\xe2\xe4\xe1\xa6\x94\x3a\x07\xe1\xfd\x57\x9d\xc6\xef\x35\x3d\xe0\x3f\xbc\xca\x57\xf7\x41\x8c\xbf\x5b\x37\xf7\x80\xf2\x35\xe1\xcd\x70\x16\xaa\x77\x33\x19\x1a\x51\xf2\x65\xe9\xf4\x3d\x30\x8b\xe9\x9a\x8c\x2a\x95\xa2\xb2\x9a\x6e\x99\x08\xe9\xd9\x3c\xe0\xc1\xc1\x52\x28\xa0\x91\x94\x56\x64\x75\x1a\x96\x42\x49\x93\x37\x6b\x9c\xe7\x10\x65\x94\x1f\xbb\x3d\x95\x7d\x39\x58\x5f\x45\x77\xc2\x28\x7e\x13\x2a\xac\x89\x81\x3c\x57\xa0\xdd\xc8\xfd\xfa\x9e\xf3\x05\x94\x53\x43\xb2\xf1\xce\x8d\x11\x48\x12\xc9\x01\x2f\x32\x7e\x79\x42\x7b\x49\xc5\xd4\x18\x0c\x1d\xe8\x1a\x28\x4e\x99\x99\x03\x80\xb6\x6e\x33\x55\xca\x5f\x41\x9c\xa3\xbd\x15\x87\x3b\x47\xb3\xda\xba\x6b\x00\x77\x04\x3a\xcd\x02\x32\x20\xd9\xa2\x1e\x61\x24\x77\xa4\x41\x8f\x3b\xdc\x0b\x59\x84\xd3\xd0\xa0\x9c\xf1\xf2\xba\xda\x80\x73\xfe\xd0\x3d\x73\x29\x26\x1f\xb7\x5c\x60\xde\x8e\x60\x4a\x3e\xfd\x0f\xda\x26\x96\x34\xe6\xf0\xf2\x69\x79\x7d\x75\x19\x7d\x08\xe1\xdc\x7a\x91\xff\x9c\x6a\xba\x97\x51\x36\x47\x50\x0b\xf1\xd2\xe8\xdc\xb3\x7d\xb3\xa0\x57\xd1\xf4\xeb\x92\xb8\x43\x1e\x23\x92\xb4\xf6\x61\xcc\xd1\x78\xef\x9e\xf9\x8f\xff\x97\x45\x48\x01\x41\xf0\xd2\x92\x0b\x55\x76\x33\x67\x65\x40\xb1\x52\xb2\xb0\xba\x0d\x1d\x23\x5d\x60\x8b\x84\xc5\xdd\xc2\xa1\xd4\x02\x89\x3c\xd6\xfd\xad\x35\xd0\x47\x22\x89\xf0\x8e\x42\xab\x3d\x4a\x62\x07\xa2\x99\x6b\xd4\x43\xd7\x2d\xc2\xe5\x5f\x45\x24\x04\x16\xc1\x03\x91\xf6\xfc\x31\x4e\x7b\xab\xcd\x6e\xf5\x6c\x85\xda\x14\xdc\x43\x25\x1a\xb7\xd2\xea\xd4\xdb\x9a\xfb\x0f\x8b\x7b\xf3\x9b\xfd\xc5\x36\xdf\x91\xe5\x6f\x9a\x67\x5b\x7b\x9c\x11\x91\xd8\x88\x02\x60\xe8\x48\x4e\x59\x0c\x5a\x67\x66\x6f\x2c\xe6\x92\x51\x97\x75\x4b\x95\xc7\x72\x79\x49\x11\x02\x33\x69\xf5\x5b\xfe\x52\xd3\x32\xec\x68\x83\x8f\x98\x59\xe2\xdb\x90\xf5\xe6\x21\x42\x6e\x65\x8b\x77\x75\xcb\x83\x4d\xfe\x9d\xac\x99\x99\x1e\x01\x23\x51\x1b\x61\xf0\x10\x25\x62\x88\x51\x8a\xc3\xb7\x85\x90\x8a\x85\x59\xd5\xdb\x2d\x11\x25\xb4\xd9\x23\x24\x41\xcb\xb1\xbc\x9a\xe0\xa4\x3d\x1d\x8a\xe1\xfc\x4c\x9e\x65\x0f\xde\xa9\x8a\xc6\x48\xf4\x30\x08\xb3\xc5\xad\xef\xc4\x45\x14\x58\x6d\x4b\x6f\xbb\x69\x64\xea\xbd\x73\x15\x01\xf0\xaa\x2c\xac\x5e\x95\x95\xd3\xf6\x00\xa5\xf3\x13\x5c\xd3\xe4\xc8\xe3\xd0\xac\x54\x41\x04\xf5\x59\x6b\xe5\x1e\x3f\xdf\x0a\x6d\x23\x10\xda\x60\x18\x73\x52\x56\x50\xad\x2d\x50\x51\x96\x86\x25\x9b\x63\xc2\x3c\x08\x33\x65\x2f\x9f\xa9\xd0\x0c\xfd\x68\x56\x66\xa5\x69\x8d\x80\x2b\x6c\xa2\x16\x46\x50\xf6\xe1\x7f\x08\x97\xa9\x1f\x4a\xe3\x21\x72\x36\x03\x22\x60\xd0\xf7\xca\xf3\x29\x1a\x5c\x79\x4a\x87\x6d\x75\x70\xc1\x8f\x97\x4e\x3f\x3f\xaa\xa0\xb2\x3a\x69\x4f\xd8\xb7\xee\xea\x68\xe5\xe1\xfe\x09\x3e\x60\x29\x54\xcb\xdc\x9a\xaf\x54\xee\x58\x05\xb5\xbb\x7a\xe7\x08\xa7\xaf\x79\xe9\xea\x8a\xeb\x08\xf2\xeb\x5b\x6b\x95\x08\xbb\x47\xbe\x14\xa3\x0d\x0a\x9a\x2a\xbf\x7e\xfd\x6c\x90\x58\x3b\xf9\xed\xac\x3a\x6f\x34\x07\x00\x3d\x84\xa3\x54\x58\x01\xad\x10\xd4\xad\x1e\xa4\x8b\x75\xd8\xd4\xb4\x35\x85\xd2\x5a\x61\x4c\xab\x92\xa8\xea\xbd\x09\x4e\x75\x51\x1a\xfd\x51\x61\x94\xe2\xa0\x10\x6f\x65\x89\xd7\x27\xf6\xb4\xec\x4a\x22\x14\xad\x5f\x47\xab\x72\xaa\x20\x3b\x9f\x97\x34\x37\x67\xa9\xbe\xac\x09\x25\x60\x0f\x6c\xe6\xa2\x62\x68\x9f\x3e\xdc\xbe\xab\x03\xff\x73\x47\x9c\x03\x5c\xb1\xf8\x4a\x42\x1c\xdb\xeb\x8e\x6f\x55\x47\xdf\xa2\xfe\xd5\x06\xc1\x45\xe8\x35\xc5\x3a\x49\x4b\x63\xf1\x8a\x83\x17\x31\x6b\x37\x13\xeb\xb9\x20\xeb\x14\x58\x47\x7c\x98\x88\xc1\x43\x3d\x55\x45\xd4\x5b\x5e\x59\xe7\x2e\xdd\xc8\xa5\x9c\x92\xf7\x2c\x92\xbe\x5b\x98\x0a\x5a\x58\x2d\x5b\x8a\x88\xab\xd0\x03\x65\xcd\xf5\x51\x32\xf7\x6c\x86\x38\x8b\x50\x03\x8b\x9c\x01\x97\xb5\x1c\x98\x0d\xa8\x54\xb8\x90\xfd\xf3\x13\x6c\x46\x0f\xf8\x92\xd9\x52\x7b\xb0\x13\x58\xe4\x70\xb1\x34\xf8\x23\x68\xc9\x11\x8c\x57\x8c\x17\xe1\xbd\x55\xb8\x76\x5d\x8f\xa4\xf2\x2e\xa0\x39\x7e\xf4\xf9\xb7\x95\x88\xc9\x95\x59\x20\xb0\x73\x53\xc1\x7a\x71\x6c\x7e\x14\x69\x81\xc4\xd3\x7f\xca\xee\xe1\xc1\x7e\xc2\x3e\x04\xc1\x02\xa6\x5d\x2a\x0c\x5b\xe3\xc0\xe5\x2a\x8a\xe5\xa5\x65\x92\xf0\xff\x22\x08\xf1\x92\xa2\xe8\x4b\x54\xf5\x6f\x25\x81\xee\xb7\xee\x10\xff\x67\x28\x83\x3c\xa8\x89\x2a\x60\x8e\xee\xb7\x78\x17\xf4\x3b\xbb\xea\x24\xcb\xc2\x02\xdb\x58\x60\xcf\x8d\xf3\x33\x71\xb6\x7c\xd9\x7e\x93\x77\x68\xbf\xc9\xdf\x73\x1b\x34\xf9\xa5\x85\x86\x32\x34\xa4\x70\x15\xa0\x1e\x2a\x20\xfa\xf4\x26\x53\x67\xaa\x42\xfb\x21\x33\xe5\x55\x4e\xd8\x7a\xed\x1e\x9c\xcf\xc4\x35\xe7\x75\xb7\x5a\xee\x41\x71\x3e\x0c\x21\x16\xb1\xfb\xca\x7a\xdd\xda\x65\xca\x7f\x2a\xc3\xf9\xa1\x4d\xe5\x1c\x3b\x05\x55\x71\x76\x02\xa3\x93\x10\xb3\xac\x18\x41\x90\x54\x05\xf7\x4b\x3d\xb4\x66\x21\x48\x91\xe7\xf0\xad\x08\xc7\x76\x9d\xf6\x5c\x1b\xdb\x72\x8d\x55\x73\x3b\xb9\x3c\xbb\xef\xc4\xa5\x58\xee\x84\x13\xb8\x66\x71\x44\x58\x1d\x91\x42\x99\x9e\xa7\x38\x9a\xa9\xd9\x77\xbd\xbf\x0e\x5d\xf5\xcf\xaf\x73\x56\xbd\x78\x8a\x54\x05\x71\x87\xaf\xfd\x6b\xe2\xb5\x2f\xda\x72\xd3\x2c\x13\xaa\xa1\xfb\xa5\x80\xa5\xd9\xa6\x35\x3d\xba\xa3\x67\x04\x5e\xfc\x3c\x83\xd5\x3b\x9e\xe2\x80\x8c\x85\x88\x8b\xb1\xe8\x22\xa0\x14\xab\x1a\x6d\x70\x3e\x47\x37\x66\x3e\xc8\x37\x5c\x81\x71\x62\xe9\x95\xff\x70\x0a\xd2\x9f\xab\x72\xaa\x8c\xfa\x07\xa2\x35\x52\x6f\x5a\xf1\x90\xb5\x6d\x48\x92\xa6\x7f\xf2\x19\xb7\x29\x6b\xf3\xdb\x1e\xad\xdf\x0d\x57\x69\x8b\xfb\xa9\x29\x7b\x8e\x33\x91\x85\x08\x7f\x68\xe1\xa5\x62\xee\xa0\x67\xf6\xf1\x96\xa9\x55\xb5\xc1\x35\xb9\x87\x95\x22\x5d\x8f\x1a\xfd\xd4\xe3\x9c\x3f\x11\xc1\x92\x4f\x51\x0e\xeb\x2d\xeb\x16\x16\x07\x5e\x9c\xfa\xc4\x14\xd5\xa3\xd4\x75\x54\xb5\xf5\xdc\x78\xcc\xa2\x59\xfb\x43\xcc\xef\x47\xb8\x74\x82\xe9\xa8\x61\xc0\x03\xfd\x04\xff\x9d\x7b\x7c\xfb\xd7\x33\x2d\xc0\xfc\xb8\xe0\x21\x78\xe7\xcc\x88\x75\x57\x3a\xcd\xf9\xb1\x81\x05\x92\xc7\x57\x9e\xa4\xf1\xf9\xf9\x88\x15\x69\xfd\x40\x63\x28\x3f\xa2\xce\xfd\x40\x59\xe6\x97\x41\xfc\x68\x0c\x40\xb8\xd1\xa9\x8e\xfe\x61\xf3\x85\x68\xcf\x1e\x89\x43\xb6\x66\x7a\x67\x43\xeb\xd6\x68\xe5\x3f\x8c\xae\xa8\x57\x66\x29\xfe\xe5\xf3\x1f\xb2\xd9\xbe\xd9\xee\x5d\x7f\xde\xc2\xe0\x6b\x6d\x75\x5f\x8c\x38\x83\xcc\xb8\x3e\x50\x16\x41\xb4\x4c\x44\x20\xa3\x60\xef\xcf\x43\x53\x5d\xcf\xae\x75\xbe\xd2\x4b\x31\x8f\xcc\xd7\x21\x71\x60\xbd\x1c\xc9\x9d\x6e\x23\xe6\xcb\x60\x4e\x92\xa0\x21\xf5\x5e\x7b\xdf\x82\x03\xf9\x62\xfd\x97\x93\x25\x5b\x9e\x59\x0e\xdd\x03\xe0\xd2\xa2\xcd\x0e\x55\xb3\x07\xaf\x1e\x13\x85\x3f\x54\x61\xfd\x87\xba\xe8\xdd\x1e\xea\x43\x95\xcd\xaa\xad\x75\x28\x7b\x7c\x58\xfa\x2c\x9f\xa4\x1a\x72\x00\xed\x86\xf9\xd6\xf4\x0b\x1c\x67\x19\x95\x6d\xf5\x23\x1d\xd1\x55\xe2\x27\xc3\x0c\xe7\x31\x0e\xc6\x87\xf9\x5b\x5b\x9d\x07\x15\x1a\x87\x29\x34\xba\x6c\x3c\x48\x80\xa3\xe7\x72\xf3\x9f\x92\xb2\x07\xd4\x7a\xb5\x65\x8a\xff\x9b\x4f\x91\xc1\xa1\x03\xb1\xa9\xb2\x7b\x8a\x59\xb9\x5f\xab\x58\x97\xaa\x19\x33\xef\xc2\xb0\xd3\x57\x14\xc1\x02\xfb\x21\xea\xd6\x2b\x2b\x80\x10\xaf\x7c\x0d\x3a\xe4\x9a\xda\xba\x09\xf0\x42\x8f\x7f\x0b\xfb\xe6\xe1\x0f\x5a\x73\xc8\xc3\x2c\xfe\x26\x4a\x81\xe4\x93\xa2\x0e\x2b\x1e\x69\x66\xaa\xd8\x96\x67\x7d\xf3\xc4\x3b\xb4\x51\x1e\xc9\x35\xad\xa2\x52\x5c\x55\x67\xd6\xa8\x69\xc0\xa8\xd9\xb7\x4a\x61\xc8\x96\x24\x4e\xdb\x98\x83\x9f\xe4\x98\xe3\xfe\xdd\x31\xdb\xd8\xd7\x5b\x29\x1b\xd4\x99\xff\x48\xa4\xa2\xea\xc1\x0a\x71\xc3\x61\xf4\x78\x74\x39\x2c\xeb\x4f\x49\x15\xf4\xb0\x67\x66\x71\x39\x35\x8f\x06\x20\xd8\x55\xc7\xeb\xcb\x4b\x3b\xf3\x99\x98\x55\x1f\xae\xc8\xde\xeb\x0b\xf5\x55\x7d\xf9\x8a\xa1\xaa\x1e\x04\x7a\x68\x94\xb8\x30\x59\x71\xdc\x85\x8e\xb0\x13\x9b\x86\xba\x73\x21\x95\x34\xc4\x84\xfb\x36\x2c\xee\x5d\x32\x43\x97\xbd\x97\x13\x30\x96\xbc\x2c\x3d\x74\x15\x58\xbf\xb5\x6e\x42\xac\xd0\x9e\xf2\xca\xc0\x75\xb0\x55\x60\x84\x60\x7a\xdb\x0c\x9f\x78\xa8\x7e\x3a\x3f\x5f\x30\x19\x99\xa3\x73\x50\x47\x6d\xc8\x4e\x3e\xe9\x7c\xe8\xb2\xdb\xd3\x2b\xbd\x9f\x3e\x84\x0d\x20\xe1\x2a\xb7\x72\x97\xde\x94\x97\x6c\xef\x9a\x65\x8a\xc6\x22\xae\xea\x94\xba\x08\x91\xc3\x88\x5a\xf7\x2d\xc1\x54\x19\xc4\x55\xb2\x46\x21\x17\x96\x7f\x82\x7f\xaa\x80\x6f\x28\x44\x5d\x45\x5e\x85\x34\xd8\x8f\x0a\xdd\xb9\x15\xba\x07\x28\x44\x29\x16\x1a\x00\xf6\x5f\xfb\xce\x64\x1e\x3f\x68\x3f\x1f\x6c\xb3\x7a\x7d\x94\xcf\xa7\xe8\x78\x47\x73\xb8\xdb\xf7\x24\xd5\xd8\xed\x00\x31\x47\x52\xb2\xdb\x11\x07\xc3\xb4\x59\x41\x66\xda\xa8\x4f\x61\x57\x6c\x11\x3b\x6c\x0b\x36\x29\xce\xae\xc1\x7f\x5d\xd7\xb6\xd1\xac\x1f\xd6\xf7\x73\x89\xeb\x61\x71\xba\xa5\xf3\xe9\x89\xe7\x26\xee\x69\xbd\x5c\x54\xca\xd3\xa6\x82\xba\x04\x5b\x2b\xe7\x23\x5d\xdd\xba\x14\x3a\xd8\x5d\xd4\xda\xf3\x5f\x1b\xbc\x24\xa2\x32\x68\xb0\x5c\x16\x79\xdf\x95\x14\x12\x5f\x4e\x80\x55\xb1\x3b\x32\x97\x16\x0d\xaa\x74\xab\x0e\x6c\x13\xd1\xae\x90\x1d\x9b\xae\x28\x5a\xbf\x69\x33\x57\xfe\xb9\x4f\x1e\x13\x2b\xb6\x60\xc9\xb9\x9c\x54\x64\x47\x8b\xc0\xcd\x60\xf6\xf0\x94\xb4\x0b\x2a\xdd\xe7\x2f\x07\x88\x5d\x69\xd2\x65\xdd\x4a\xae\xa8\x4d\x25\x62\xc8\x85\x38\xc7\x84\xa5\xc3\x3c\xd6\x97\x8d\x91\xe5\xec\x59\xed\xcc\x9f\xf1\x0b\xa0\x22\x7f\xb7\x0d\x71\x30\xf7\x66\x79\x3c\xb4\x22\xba\xd9\x1a\x4f\x2a\xc8\x42\x82\x4f\x22\xaf\x6e\xe1\xf6\xc3\x1a\xb9\x96\x8d\xb3\xd6\xfd\x49\xf9\x75\xe8\xf4\xbf\x2c\x58\xd4\x79\xc9\xbc\x5d\xbf\x14\x5a\x59\xed\xd9\xe8\x48\xe7\x98\xb3\x63\x5a\x3c\x4c\x75\x38\x25\xae\x9b\xde\xbb\x2e\x78\xaa\x9c\x9c\x59\xa0\xb2\x7f\x8a\x25\x1e\x7b\x1d\x1a\x3a\x1d\x19\xe6\x59\xfc\x20\x4e\x6c\x30\x93\x3a\x57\x4c\x3a\x09\x11\xe9\xd2\x1c\x42\xb3\x76\x05\x64\xa3\xe7\x82\x85\xf6\x1f\x6e\x95\xce\x47\x0b\xbd\xe1\x4e\x8e\x5b\x65\x8d\x1a\x0a\x68\xd0\x78\xeb\x3a\xa7\xae\x9e\xbf\xaa\x6e\x9f\xb9\x23\xcf\xdb\x69\xdf\xba\x32\xae\x11\x7b\x2b\x58\x05\xa4\xc3\x24\xfa\xcd\xa5\x8d\x37\x79\xee\xe8\xe5\x64\xbf\x07\x2f\xdd\x9e\x45\x72\x55\x82\xf1\x2e\xf1\xd0\x16\xb0\x0c\xbe\xd6\xa6\x83\x08\x9f\xed\x18\x5f\xdb\x2f\x19\x45\xd9\x73\x34\x80\xbf\x09\xc9\x85\xd0\x3d\x5a\xe6\x37\xf5\x3d\xd3\xb4\x06\xcc\x35\x0d\x65\x3d\x26\x9d\xc6\x30\x28\x35\x91\x7a\x0e\x6b\x52\xbb\x73\x09\xea\xbb\x64\xc7\x02\x72\xfd\xe3\x35\x75\x20\x88\x11\x65\xb6\x1a\x1f\x8c\x9b\x7a\x4f\xe0\x7e\xd2\x6b\xbe\xc8\xa5\xf9\x40\x3c\x9a\xeb\x22\xd5\xf6\xf6\x27\x43\xbd\x14\x34\x65\xd9\xd1\xbd\xf5\xfc\xbf\x4e\xde\x0c\x3b\x84\x40\xf4\x2f\xd4\x43\xc3\x5d\xe0\x35\x13\xc5\x0d\x15\xd8\xfd\x87\xba\xb1\xa5\x36\xe1\xd8\x39\x0a\xe8\x68\x5e\x6e\x45\xa9\x85\x2c\xc2\xdb\x93\x72\x44\x7d\xdc\x21\x01\x94\x7e\x05\x4b\x30\x0c\xff\x5c\x37\x5e\xe5\x76\x96\xca\xc3\xbe\x2f\x2d\xa1\x75\x0b\xe8\x6c\x51\xa4\xc9\x06\x39\x1c\x62\xcd\x6e\x71\xb0\x10\xef\x44\xa1\x83\x65\xfd\x94\x5c\x94\xb5\x9c\x07\x6b\x26\xcf\xb2\x2e\xfa\x77\xcf\x59\xb8\x30\x7b\x16\xe6\x1b\xc3\x5a\xae\xb5\x91\x71\x8c\xc8\x9f\xa0\xb4\x85\xab\x1f\x3b\xb3\xe7\x3c\x48\x4d\x96\xbf\xf5\x89\x32\x23\x2b\xee\xe7\x40\xe6\x09\x5c\xa5\x78\x2c\x8c\x73\x1c\xed\x8e\x64\x94\xca\xed\xa7\x2a\xf8\xe4\xd5\x7e\xed\x01\xf7\xc1\x13\x41\x4f\x60\xad\x83\x79\x2b\xf8\x7b\xfd\xba\x23\x03\xba\x68\xcd\xd2\xe8\xbe\x7d\xf5\x68\xaf\xcc\xfd\xe2\x24\xe6\xae\x5b\x93\xd7\x42\x92\x97\x53\x72\x18\xfc\x69\x78\x0f\x8b\x3f\xbf\xd9\x08\xac\x0d\x8b\x66\xc4\x3e\xfe\x8a\xb2\x0b\x87\x84\x42\x5b\x3e\x1b\xa8\x70\x14\x78\x63\x64\x23\xd7\x3e\x58\x34\xa9\x37\x03\x6d\xcb\xaf\xc6\x6d\x2d\x39\x29\xb5\xc5\x7b\xf9\xbb\x84\xf1\x06\xac\x00\x7d\xa4\xe5\x15\xf3\x2b\xc4\x66\xd9\x4d\xdd\x50\xa5\xf4\x03\xe5\x7f\x2c\x64\xdf\x00\xcf\xfa\xf3\x79\x03\x04\xaa\x8a\x39\x6a\x21\x0c\x56\x49\xda\xa0\x8a\xae\x75\x1b\x92\x90\x2c\xd4\x07\x90\xf7\xb6\x17\xc3\xbf\x54\x13\x76\x27\xfd\xbf\xb4\x6a\x43\x98\x26\xfa\x70\xc6\xe5\x6a\x1b\x29\xf6\x95\x73\x68\xd6\x5d\xaf\xe0\x75\xd6\x28\x24\x7a\x71\xdc\xeb\x8c\x95\x3e\x87\x60\x04\x8f\x62\xab\xda\xa5\x3f\xe4\x2f\x58\x31\xb1\xb7\x66\x96\x6a\xb4\xf5\xeb\x46\x38\x35\x0a\xa9\x5d\xe4\x4e\x24\x5f\x2f\x8d\x47\x49\xdd\xfa\xa3\x2e\x6c\x03\x1b\x39\x05\x72\x0e\x1f\x2e\xd7\x28\x88\xdb\x46\x51\x4e\x45\xac\xde\x09\xe4\x61\x95\xf5\xed\x32\x86\x87\x1e\xae\xa8\xb5\x13\x21\x59\x7b\x47\x6d\xc0\xa6\x68\x9f\x59\x15\xe9\x42\x67\xb7\x2b\xdc\x05\xbb\x72\x7b\x1b\x73\x6d\x44\x95\x5e\x84\x95\x63\x36\x27\x00\xd7\xf5\x1b\xc6\xe9\xb0\x8d\x98\x19\x60\x48\xc4\x3a\x02\x62\x5f\x60\x94\x32\xff\x09\x13\x43\x92\xb5\x51\x4a\x0d\x9e\xb1\xcd\xb1\x5b\xfe\xf9\xb2\x47\xa4\x70\xa9\xfa\x77\x09\x6a\x31\xd2\x4a\xbe\xcc\x32\x89\xb0\x48\x96\x29\x57\xfe\x27\x08\x40\x0e\xcb\x45\xa0\xa1\x7d\xb9\xba\x68\xe6\xe5\x69\x5d\x16\xc2\xf3\xd8\x88\x7d\xd0\x63\xe5\xef\xcb\xc9\x86\x39\x2a\x80\x97\x51\x04\x70\x1b\x42\xbf\x9b\x59\xa0\xb5\x2e\x1d\xa3\xda\x48\xc4\x6b\x4b\x46\xfb\x27\x49\xde\x9e\x02\x34\x80\xaa\xaf\x25\x0f\x37\xed\x55\x15\xef\x3d\xf0\xb6\x4e\x31\x1e\xee\x45\x3b\xb4\x21\x85\x3b\x16\x46\xe1\x1a\xa3\xdf\xa5\xf9\x17\xe6\xb6\x67\xb2\xc9\xab\x88\x08\x97\x3b\x2a\x7f\x14\xe1\x61\xd0\xea\xf4\xf0\x43\xa7\x77\xe6\x33\x65\x7d\xe0\x20\x0b\x43\xd5\xcb\x4f\x49\x01\xbb\x76\xee\x57\x3c\x77\x91\x71\xe1\xd9\x87\x50\xee\x58\x39\xdc\xf7\x8a\xba\xbc\x11\x63\xea\x70\x25\x3d\x80\xe7\x9b\x4f\xcc\x59\x9f\xf2\x23\x8c\x5e\xff\xac\x4c\xe5\x9d\x35\x3c\x35\x4e\x3a\xfa\x63\xbc\xc6\x2d\xc9\x50\xb5\x65\x50\x54\xcf\xd0\x61\xb3\x80\x2c\xe3\xd0\xc7\x80\x17\x62\x57\x64\x8b\xf8\x96\xa9\xaf\x45\x81\x41\x02\x2b\x17\x93\x0a\x39\x21\x92\x46\x5c\xae\x8c\x59\x98\x17\xcb\x8b\x37\xd1\x60\x37\x47\xb1\xbf\x74\x22\x9e\x53\x73\xd6\xbf\x9e\x65\x72\x7e\x36\xfd\xdb\xb9\x39\x1a\xce\xbd\x88\x11\x67\x54\x80\xcf\xfc\x71\x08\x0b\x50\x89\x82\x02\xe4\xf9\x6e\xc6\x86\xfb\xc0\x55\x2e\x09\x06\x1b\xc3\xb9\x57\x10\x1b\x87\xa8\x6f\x4e\xaa\x9b\x5f\x2a\xc7\xdf\x93\x17\xd0\xc1\x6b\xd6\x4f\x4d\x9b\xd0\x03\x09\x63\x0c\x0f\x46\x55\xe2\xf1\x18\x40\xc6\xe3\xd6\x94\x41\xb1\x22\x76\xa5\xae\xdf\xe9\xf7\x03\x95\x78\x49\x10\x1f\x00\x8f\xa9\xa8\x5c\xcf\x81\xaa\xbc\x75\xdb\x58\x31\x3a\x6a\x54\x8c\xab\x28\xbd\x77\x08\xd1\x9e\x9f\x77\x47\xb6\xa0\xd3\xa4\xfc\xb0\x80\x82\xbe\xa4\xbf\x6b\x27\xe5\x69\x99\xa3\x54\x32\x3a\x8f\x36\x67\x3e\x7c\x76\xeb\xbb\x16\xaf\x3c\xb0\x94\xcf\x77\xc8\x35\x7a\xfd\xcc\x66\xcd\xaf\x0e\xf8\x16\x73\x14\x72\xcc\x1a\x3f\x1d\x73\xa4\x64\x8f\x39\x0c\xef\x2d\x62\x71\x9e\x08\xbb\x63\x1e\xa9\xa7\x64\xbd\x92\x18\x94\xa8\xdb\x13\x40\x2e\xd6\x73\x54\xec\x27\x78\x60\x23\x7e\xac\x55\xb6\x9d\xc7\xc3\x06\x19\x2a\xcb\xb9\xba\x6f\x27\x9a\x75\xd0\xa1\x51\xd3\x17\x42\xc0\x9e\x0f\x9d\x8c\x5b\xdb\x69\x5d\x69\x6c\x69\xe1\x37\x0e\x0e\x97\x6d\x41\x52\x22\xc8\x55\xc1\x99\xde\xf7\xf7\xab\x71\xaa\x77\xda\x32\xa2\xc5\x90\x1e\xca\xd1\x20\x02\x83\x34\x67\x9d\x53\x7d\x29\x10\x85\xe5\x48\x02\x40\x48\x78\xf4\xb0\x71\xfb\xc6\x8d\x8b\x80\xa7\x30\x65\xb4\x4e\xa2\x13\x78\x60\x67\xe5\xee\xb0\x31\xb0\xdf\xb6\xf2\x49\xde\x75\x94\xd7\x4e\xfc\xbd\x8b\xff\x12\xf5\x69\x37\x92\xcf\x75\x51\x26\xc1\x75\xaa\x1c\x21\xa0\x9e\xb4\x2c\xac\x3d\xc1\xff\xc9\x7f\x42\xc9\xd4\xee\xdf\x09\x26\xe0\xfd\x44\xfd\xdf\xbb\x04\x04\x1c\xad\xed\x25\x5a\xb5\xbd\x74\x9c\xd2\x58\x47\xf6\x2a\x6a\x6a\xdc\xa6\x91\x7c\x67\xbd\xaf\x7b\x56\xf2\x66\xcf\x71\xd4\xa4\x67\x0a\x22\x1d\xd2\x0a\x4e\x2c\x97\xd7\x4b\x15\xed\x2a\x9d\x0f\x57\xf8\x3c\x19\xec\xc1\x90\xb6\x7e\x44\x25\x7a\x87\xb5\x4f\x94\x53\x2d\x52\xef\xb0\xa0\x0b\x2a\x35\x73\x2f\x5e\xc2\xcf\xdf\x7a\x7c\x55\x8d\x3e\xbf\x8f\xf0\x32\x2c\x54\xc0\xd9\x8a\x44\xb7\xb7\xa2\x1b\xb4\xd1\xc5\x66\x43\xeb\x1b\xe9\x3e\xfb\xf0\x2d\xca\xce\x67\xab\xda\x41\x29\x58\x72\xc0\x3b\x0d\x0d\xec\xe5\xf4\xf7\x74\x03\x0a\x99\x95\xfc\x25\x26\x16\x20\x50\x8b\x77\xb6\xe1\x2e\x90\x38\x6d\x4f\xa5\x34\x8e\x6d\x60\x55\xb4\x4e\xc5\xef\xbc\xee\x6f\xd6\xee\x07\x11\xa0\xa5\xc8\xbe\xf5\x4f\x52\xc5\x31\x5b\x3d\xa9\xc3\xef\x71\x68\xfa\xd6\x3e\x45\xa1\xbd\x95\xca\x97\x39\xe8\x57\xce\xb5\xde\xc5\xa3\x76\x27\x48\x8f\xc6\xb3\x10\x3d\xd0\xbb\x5d\x43\x93\xff\x5d\x53\xc0\x0a\xfa\x71\x7e\x46\xa9\x7f\xb4\x91\x44\x28\x01\xf7\x35\x0a\x65\x1e\x2b\x38\xdf\x00\xfb\x31\x2e\x5f\x45\x5f\xeb\x31\x1b\x43\xdb\x7e\x56\xec\x96\x36\x6d\x60\x17\x4e\xf7\x04\xae\x89\x73\x96\xa3\xa6\xcd\x92\x55\x5a\xb7\x97\x97\xd3\xb0\x2d\x51\xfa\x45\x9e\x9c\xe9\x0a\x17\x49\x2f\xeb\x33\x6a\x0c\x70\x8c\xfa\x57\x56\x02\x11\x0b\xb5\xbc\x01\xa3\x24\x0d\x72\xc0\x13\x78\xad\xd2\x2c\xbc\xce\x06\xe7\x0a\x21\x0b\xb2\xd8\xdc\x83\x1a\x35\x28\xf5\xca\x41\x06\xda\x4d\xc4\xee\xa3\x80\x1f\xec\x70\x66\xda\xd7\x37\xe7\xf4\x28\xd5\x3b\x09\xcf\x63\xa7\x63\xaf\x75\x91\x69\x65\x15\x95\xd8\xda\xf2\x25\xc7\x00\x75\xad\x6e\xab\xa1\x61\xe5\x5a\x9d\x9e\x63\x0b\x15\xa4\xad\x77\x22\x95\x98\x72\xbf\xe4\x5a\xbf\x72\xd4\xfd\x43\xe0\x57\xa6\x8e\x6b\x71\xc7\x5b\x8f\x68\xe7\x0c\x14\x26\x39\xd6\x4f\x95\xb1\x67\xf9\xc2\xac\x52\xf1\x41\x02\x40\x45\x6c\xf8\x65\xbe\x7e\x1a\x3e\x40\xf0\x00\xd1\x95\x67\x9c\xa7\x28\xd4\xfe\x73\xf2\xb5\xcf\xe1\x22\x02\x99\x71\x12\xa8\xf1\xd2\x91\x04\x4d\x02\xdc\x1a\x45\xd5\x15\x9c\xa6\x9d\xc1\xb6\xd4\x89\xf4\xe9\x38\x56\x5e\xb8\x53\xe0\x84\x6d\x58\x7f\xfd\xf1\xd0\x64\x21\x1d\x52\x33\xd2\x81\xe1\xe7\x71\x8a\x82\xc6\xea\x88\x45\x95\x21\xfd\xc3\x7e\x85\x5e\xcc\xea\xd9\x47\x15\xf6\xcf\x22\x75\x65\xb4\xcd\x39\xa2\xfe\x2b\x20\x7c\xe4\xf7\x29\x92\x2f\xa4\xfa\xce\xa0\x4c\x8b\xdb\x2d\x54\x9a\x1d\x5b\x87\x79\x00\x73\x58\xe6\x20\x4a\x27\x51\xb2\x21\x2b\x48\xe8\x81\xeb\x47\x79\xb3\xb2\xbc\xa5\xff\x0b\x15\x61\x31\x8f\xc1\xf7\xf6\x5a\x73\xcd\x7c\x87\x9d\x24\xdd\x74\x80\x91\xc3\x0d\xc8\x0a\x3f\x10\x00\x20\xec\xc7\xe2\xb5\x44\xdf\x9f\x12\x70\xb6\xe8\x3a\x7e\x93\xe5\xd9\xb4\x9c\xe2\x11\x2c\x25\x30\x31\x16\xa5\xe5\x4b\xae\xbe\xe8\x9d\x59\x0e\x0e\x64\x96\xb2\x2f\x85\xd0\x80\x7c\x08\x60\xb9\x34\x89\x1e\x44\x3f\xce\xbf\x76\x1c\x07\x14\x8c\x1d\x88\xeb\x44\x6c\xdf\x1d\x19\x64\xd5\xfe\x77\x7e\x03\x39\x3e\x0f\x12\x7d\x42\xe7\x56\x43\x5c\xc8\xa1\xc0\x38\x38\x4a\xfa\xe7\x12\x35\x4d\x8b\xfb\x49\xf3\x92\x25\x06\x54\x78\x31\xf9\x8b\x71\x0d\xf4\xe2\x2f\x21\x16\x60\x81\xd0\x0d\xa8\xcd\xc8\xea\x34\x2c\x5f\x17\x48\xc8\x24\x05\x3e\xb2\x70\x88\x00\x4b\xfd\x67\xe6\xb8\x65\xc9\x8d\xf0\x1d\x2f\x06\x1a\x52\xcc\x5b\x5e\x3f\xc2\x0b\x08\x2e\xb0\x46\x4a\x76\xc9\x1a\x34\x81\x0b\x2e\x11\xe6\xca\xe1\xcd\x22\x09\x80\x25\xd8\x45\x8b\x94\x1d\x17\x66\xea\xac\x71\xf8\x94\x3f\x3a\xcd\xfd\x67\x0b\x19\x3e\x00\x07\xfc\xc6\xfd\x96\x33\xca\xa9\x36\x15\xf4\x44\xd7\xaf\x4d\x28\x73\x6c\x97\x01\x9f\x3e\x29\xdd\x7c\x4a\x4d\xee\xd7\xc6\xa6\xc3\x27\x70\x25\xb0\x06\x72\x77\x51\xf9\x7f\xd9\x3c\xd6\x7d\xa4\x9c\x5a\xbe\x39\x59\xcb\x09\xe7\x12\x39\x95\x46\xf0\xbb\x09\xfa\xbe\xd5\xd0\x4c\xef\xe0\xd8\x4f\x50\xd0\xf5\xe5\x1e\x92\xce\x91\xfa\x98\xaa\x2b\x74\x6b\x8f\x02\x00\x9f\x9c\x4b\x6f\xc1\x05\xc4\xb2\x26\xfc\x61\x2a\x02\x1e\x4c\x2b\xc1\x08\x83\xe4\x9b\x6d\x1c\xc1\x3c\xd8\x34\xff\xfb\x8a\x85\x4e\x36\xc3\x76\xd7\x16\x0b\xbc\xee\x03\x59\x37\x02\x8d\x26\xd8\x15\x84\x2d\x01\xca\x1b\x61\x62\x3a\x46\x59\x3e\x9f\x5f\xde\xf9\x99\x04\x50\x80\x6e\x80\xa6\xb3\xfc\xb0\x70\x5b\xc9\x01\xca\xb1\x54\x0e\xaa\xf9\xaf\x7b\xe9\x18\x0e\xa5\xf3\x25\x7c\xc1\xdc\x38\xf1\x74\xa9\x9d\x32\xf5\x14\x26\x9f\x5a\xfa\x9a\xf4\xb2\x19\x1b\xcd\x57\xd1\xb4\x49\x64\xb9\x86\x02\xb3\xcd\xff\xc9\x2f\x0f\x9b\xb1\x89\xb6\x8e\x13\xdf\x1d\x64\x9a\x88\x7c\xb7\x48\xe7\x94\xc8\x1b\xb7\xa5\x68\xe8\xdb\xe9\xf3\x1c\xa8\x32\x37\x68\x03\x21\xa9\x8e\x50\xe8\xaa\x58\xee\x1d\x29\x30\x76\xc7\x3f\x03\x3d\x4b\x09\x59\x1b\x6b\x02\x29\x94\xe9\xd5\xf1\x6c\x62\x65\xa3\xcd\xce\xfc\x30\x6e\x53\xaa\x4c\x9d\x13\xd1\x7d\x19\x12\xdc\x22\xa4\x4b\x9a\x39\x7d\x98\xe8\xb4\x48\xb5\x60\x8b\x82\xa2\x3c\x86\x71\x61\xe8\x2e\x0b\xf5\x60\xcd\xb5\x9f\x59\x99\xf8\xf9\xf1\xd8\x25\xcf\x2c\x3b\xac\x71\xbe\x45\x5e\x0f\xf7\x09\xe0\x22\xde\xe1\x5c\x6a\xaf\x66\x09\x5f\xd3\xc6\x91\x03\x5c\xc2\xff\xe9\x0c\x90\x2a\x4f\x6f\xce\x5d\xec\x2e\xe8\x02\x0a\xe9\xbe\x3c\xed\xb7\xfa\xf4\x1b\x79\xef\x3d\xd0\x13\x9a\xf7\x8c\x59\xed\xf5\xc8\xe2\xd5\x88\x11\x4b\x90\xd5\x6f\x4a\x6e\x00\x37\x11\x66\xa9\x1c\x60\x80\xda\xae\x23\x21\xfb\x28\xcc\x05\x06\x9b\x52\x1a\x1a\xd3\xa6\x63\x6c\x9a\x4a\x8e\x2e\x44\xe4\x01\xe4\x7b\x44\xa4\x4f\x0e\x21\xa8\x85\x4c\x75\xcf\x97\xbd\x04\xfe\x7a\xd8\x24\x80\x1c\x71\xeb\x2f\x58\x2f\x0b\xe5\xdd\x49\x00\x87\x72\x6a\x68\x4c\x5d\x0f\x79\x2e\x3e\x30\xa2\x78\x47\xe0\xcb\xcc\x09\xeb\x23\x54\x66\x1e\x71\xb1\x1f\x48\x61\x2b\x1d\xfc\x98\xed\x66\xdf\xfc\x7a\xa4\x08\xe7\x63\x6e\x10\x89\x39\xf0\x6b\x0f\x55\x5b\x1e\xe9\x25\x17\xd6\xf4\xea\x28\x19\x02\x02\xbb\xd4\xa6\xc3\x23\x0c\xa8\x88\x91\x80\x0a\xeb\x05\x9a\x07\x6c\x9a\x66\x22\x25\x3a\x39\x90\xe5\x67\x78\xe1\xe6\x7a\xf3\x2d\xcc\xd7\x14\x0f\x6c\x96\x15\x61\x3e\x94\x1f\xcf\x10\x51\x0b\x49\x62\xa4\x52\x56\xc9\x43\xe5\xed\x7a\xa9\x8c\xd2\xe0\x46\x8e\x96\xe5\x30\x36\xab\xa3\xc9\x0f\x6f\x73\x72\xf3\xd5\x42\x99\x92\xb7\x2c\xf7\x02\x67\xf4\xf0\x46\xa6\x04\x58\xee\x02\x37\x93\xd3\x39\x65\xf1\xa8\x05\x03\x1b\xde\x2a\xa8\x0c\x6f\x14\x5e\x11\x40\xb4\x91\xb5\xf9\x3a\x11\xde\x60\xef\x30\x39\xf0\xb5\x3b\x03\xe1\xc0\x11\x39\xdc\x58\x45\x98\x7f\x73\xf1\x12\xc1\xfd\xcc\xcd\x71\xf5\x99\x08\x7e\x38\x75\x01\xa1\x21\x4d\x85\xe5\xb2\xf3\xfd\x71\x2e\xbd\x52\x89\x43\xa1\x34\x74\xc9\x37\x9b\xe8\xa1\x10\x84\x66\xdd\x4f\x27\x29\xe8\x66\x8f\x0f\x54\x6b\x42\xf3\xff\xfe\xfb\xc1\x63\xb1\xe6\x75\x16\x73\x8e\x52\x00\x1e\xf2\x31\x8b\x7b\x2f\x2c\xfe\x80\xe7\x32\x09\x72\xe1\x3a\xd3\x24\xcf\xef\x41\x78\xdf\xde\xe2\xb4\x37\xe6\x3c\xdc\x6d\x08\x65\x58\xe7\x60\xf2\xdb\x10\xb2\x12\x19\x31\x33\xdf\x3b\x64\xb9\x62\x0e\xd9\xa5\x76\x15\x52\x90\xf6\xc7\xf1\x0a\xa8\xf5\x1d\x6c\x02\x07\x3c\x77\x42\x2e\xc8\x00\xd7\x1a\x5a\xc9\xe2\xc3\xe3\x95\x6c\x34\x9b\x01\x84\xed\xbc\xbd\x64\xd0\xd6\x66\xd4\xb0\x0d\x60\x28\xb0\x7e\x5c\x9d\xb0\xce\x70\x3b\xae\xaf\xcd\x2b\x89\xf3\xa2\xc1\xf6\x67\xfd\x48\xa3\xda\x46\x5d\xf2\x7a\xe9\xcf\x39\xee\x88\x85\x1b\x97\x59\x48\x25\x8b\xb4\x4c\xef\x90\xe5\x23\xd0\x41\x06\xad\x6f\xca\x53\xd7\xd3\x0d\x59\x33\x3f\x3c\x12\xbf\x3c\x9d\x45\x52\x18\x1f\x1c\xd2\xd8\xbc\x2d\xa0\x31\x7d\xa1\x58\x6c\xcf\xd9\x03\x64\xab\xfd\x39\xe8\x51\x09\xdb\x03\xb2\xf0\x54\xd9\xc6\xc2\xf0\xcb\x06\x6c\x01\xb9\xaa\x3d\x90\x0b\x30\xc5\xfd\x83\x43\xe0\xa4\x15\x67\x44\x06\x73\x3f\x85\x8d\x54\xaf\x17\xd0\xf1\xde\x3b\x8b\xd1\xee\xfe\xba\x33\x4b\xe3\x40\x01\xe1\x03\xce\xca\x9a\x50\xef\x77\x4b\x65\xfe\xa3\xa9\x59\x7b\x96\x86\xe5\x79\xdb\x99\xb5\xf8\xbd\xd7\x76\x4c\x41\x73\xc3\x35\x76\x66\xb9\xda\x86\x3f\xe1\x5d\x5a\xcf\x4e\x33\x8a\xae\xae\x0f\x55\xd7\xe9\x81\x5a\x87\xef\x7c\xc7\xc5\xa6\x59\x23\x57\x51\xde\xc5\xc6\x55\x51\x2f\x83\x35\xde\x8d\x94\xde\x2f\x4d\xa1\x7a\x1e\x9b\x9b\xab\x3c\x4a\xec\xa5\x6e\x52\xd5\x7c\x12\xbb\xb3\xd9\xb1\xd6\x7b\x1e\x49\xb9\x3f\xa3\x44\x7c\xd2\x03\xb1\x49\x22\x43\xec\xdf\x8f\x5d\x84\xa0\xeb\x6c\x28\x29\x8e\x7d\xa1\x88\x76\xd1\xe0\xae\x53\xeb\x8e\x1c\x6e\x24\xdc\x1c\x45\x11\x37\xdf\x3e\xf0\xbf\x95\x66\x9e\xaa\x79\x4d\x57\x68\xfb\xd4\xc1\x62\x5c\xff\xb9\xf8\x58\xca\x23\x6b\x3f\x68\xdd\x0a\x49\x2f\xd6\xec\xa3\xd3\xb7\x48\x06\x37\xac\xd5\x33\x61\x05\xa9\xeb\xa8\xda\xfb\xb5\x9d\x9b\x02\x34\x87\xa0\xd7\x4a\x7a\x7b\x1a\xe7\x22\x02\xba\x06\x8f\x18\x59\xaa\xf6\xec\x0a\xd8\xca\xab\x39\xc9\x5d\xb5\x7c\x49\x65\x50\x04\xfb\x87\x25\xfd\x28\xce\xef\x03\xc6\x92\x1e\xae\xb7\x0d\x70\x78\x9c\x20\x2b\x76\x5f\xdb\xd8\x3f\x30\xc9\x2e\x8f\x84\x06\xa4\x37\xeb\xe3\x9d\x75\xf0\xce\x86\x0f\x30\x0b\x04\xaf\xf5\x4e\xa8\x81\x11\xe3\xbe\xb5\x36\x5e\xcf\x2f\x52\x2f\x4f\xe7\x92\x54\xe4\x97\x79\x6d\x0a\xae\xbe\x8c\x50\x3b\x97\x69\xf0\x6b\xea\xb8\x92\x60\xd4\x87\xce\x36\x2d\x9e\xba\x06\x8c\x00\x83\x86\x47\xb4\x3e\x9e\x5d\x75\x87\x2e\xf2\x74\xd3\xd6\x37\x2d\x50\x43\xf2\x0e\xda\xd7\x58\xbc\x44\x8b\x87\x0c\xf2\x8f\x83\x05\x1a\x99\x25\xb9\x17\x9f\x98\xe9\x55\x7a\x30\x90\x5c\xf1\x05\xc6\x11\xaa\xa3\x87\xef\xa9\x5d\x00\x8e\x85\x5d\x48\x3e\xe6\x0d\x18\x43\xfa\x7f\x3e\x77\xb9\xe9\x41\x67\x77\x24\x32\x25\xf1\x71\x44\xb9\x83\xdb\xf4\x60\xf1\x72\x76\x9e\x1c\x3d\x4d\xfa\x7d\x58\x42\x03\x6a\xc0\xa3\x6d\xef\x7f\xbe\x98\x03\x6f\xc0\xd7\x19\xe8\x08\x19\xd6\x1e\x0d\x36\xc0\xe5\x4c\xea\x69\x9a\xf5\x6c\xa4\xf1\xb6\x3e\xe4\xf0\xc8\x6e\x2b\x87\x12\xc8\xef\xf8\x12\x8e\x89\x7e\x60\xf8\x5a\xc9\xa2\x56\x4b\x20\x72\xfc\xda\x27\x3e\x5b\x42\x6e\x42\x64\x3b\x88\xf8\x23\xd9\xfd\x7a\x01\x3e\xae\xd2\xb4\x2a\x22\x70\x60\xfb\xf8\x73\xf0\x61\xf2\xf5\x5d\x4f\xa7\x0d\xd9\x92\xd7\xd9\x9e\xb2\x85\x3d\xe8\x3b\xab\x9c\xfd\xce\x29\x40\x05\xe7\x17\x5d\xe0\x8b\x89\x0b\x76\x5a\xb6\x74\x5b\x09\xf4\x51\x4d\xfd\xd0\x55\x71\x14\x7c\xeb\x67\xaf\xf2\x7b\xf7\xd4\x5a\x7f\xed\x2e\xcf\x46\xe6\xfe\x2c\xed\xee\x5d\xb4\x65\x8b\xe4\x1b\x3b\x87\xbe\xb6\x17\x5f\x9c\x45\xef\x0f\x1b\x01\x0a\x28\x93\xf9\x95\x79\x21\x23\x41\x2c\x02\x26\x66\x12\xe7\xde\x6f\x3d\x01\x2f\xa7\x65\xff\xd0\xb0\x96\xae\x2d\xfc\x3f\x6d\x68\xfd\xca\xb1\x26\xf9\x4c\xec\xe5\xaf\x19\xc5\xbc\x1b\xd2\xe3\x95\x54\xa7\x7a\xa5\xc6\x14\x02\x0a\xc1\x2b\xfa\xd6\x2a\x90\xa8\xbf\xb2\x5a\x42\x79\xee\x70\xa7\x85\xcf\x79\xd8\xd6\xf2\x3f\x41\x2f\x50\xd6\xb4\x73\x62\xfe\xea\x89\x5f\xb1\x08\x80\x00\xa2\xf3\xc8\x90\xc0\x83\x73\x2a\xd2\x16\x7c\xa2\xf0\xa4\xa3\x39\x0c\xc1\x37\x88\xa2\xe2\x13\x5a\x52\x00\x3a\x30\xeb\x0b\xe3\x5b\x5f\xd8\xcc\x4d\x4f\xa2\xc5\xcf\x52\xce\x49\xfa\xde\xfb\x24\xfc\xba\x6b\x04\xbc\x03\xb2\x60\x73\x91\x52\xa4\xf7\xed\x48\x1b\xc9\x41\x3d\xc3\x54\x13\x58\x53\x29\x8b\x43\xb1\xc4\x96\x35\x14\x8d\xea\x79\x39\xda\xa9\xa2\x46\xe6\xc1\xa1\x9c\xca\x5d\x05\x7f\xbd\x83\x5a\x67\xc1\xde\x69\xa8\x68\xb1\xdf\xf7\x1b\xf2\x35\x8e\x1d\xe0\xb4\xf1\x46\xd5\x90\xdd\xa5\x8d\x81\x8f\x4c\x91\x80\x12\x39\x68\xd8\xe8\x36\xf3\xdc\x46\xa0\x77\xbc\x19\x64\x46\x7f\xa4\x3b\xee\x4f\x08\x64\xc7\x6b\xfe\x09\xfd\x71\x04\xe5\x22\xac\x21\x39\xac\x20\x6a\x67\xb7\x8b\x1f\x13\xe6\xb0\x95\xdb\x1b\xd7\x7b\x16\x0d\xc7\x66\x5b\xfc\x6a\x0a\x87\xe6\xdb\x39\x06\x42\x12\xdf\x53\x16\x80\x21\xd2\x5f\x77\x5e\xea\xea\x1d\xda\x9d\x7f\x39\x0a\xb9\x95\x36\x93\x40\x80\xaf\x4a\xe7\xc1\x7f\xee\xe3\x3b\xbe\x4b\x30\xe8\x95\x5e\xc6\xf5\x71\x50\xdd\xf5\xb6\x43\x5d\x54\x02\x40\x02\x55\x86\xbc\x39\xb5\xfe\xe3\x72\xd6\xf6\xa2\x28\x56\x59\x13\xaa\xca\x79\xf5\x9f\x7c\x55\xaf\xf7\x7b\xe1\xb7\x52\xfd\x84\x58\x88\x61\xc8\x12\x21\xaf\x40\x34\x29\x54\x5e\x18\xf8\x06\x91\xf9\xad\x71\xfc\xf2\xfd\x0b\x07\xfe\x16\x08\xd0\x60\x8f\xc9\x24\x9c\xc4\x1c\x76\xb2\xb7\x3a\xfe\x0b\x4a\xee\xea\x05\xae\xdb\x26\x7b\x55\xd0\x07\x29\x86\xc3\x96\x42\x58\x87\x3e\xc6\xb7\x97\x74\x8b\xae\x5b\x19\x06\x0b\x94\xbb\xbd\x5c\xe7\x9d\x05\x7d\xf4\x5c\xf6\x12\xb0\xc4\xfd\x9f\x1b\x1c\xd0\x43\xf8\x38\x9f\xd2\x53\x87\x09\x69\x44\x3e\xf2\xb9\x8e\xa2\x5a\xfa\xc1\x79\xe8\x75\xb8\x42\xa8\x90\x14\xb9\xa9\x07\x90\x49\x86\x25\x53\x77\xd0\x11\x18\xb9\x1c\xf7\x1a\xda\x01\xd7\xd7\x4e\xf8\xe4\x8d\x2b\x9a\xd4\x21\x2b\xec\xb8\xa5\x0b\x0d\x23\x61\x07\x85\x33\xe6\x6b\xd7\xc1\xb7\x33\x2f\x64\xb5\x6f\x85\xed\x81\x8d\x4d\x42\x53\x00\x1c\x3c\x26\xe5\xed\x85\x24\xc5\x1f\x72\x9e\x0b\x83\x00\x16\x2c\xb3\x04\xe0\x97\xec\xa9\x1d\x94\xb4\x88\xcd\xb0\xe6\xf1\x62\x10\x2c\xfd\x39\x7e\xa7\x84\x62\xaf\x79\x13\x26\x66\xce\xe3\x1f\x11\x78\x39\x0d\xdb\x00\xbe\x51\xa5\xe0\xf2\x71\x84\x00\x7c\x49\x42\x73\xa0\x04\x1e\x70\x8e\x8d\xf8\xe8\x4b\xe2\xe2\xd7\x17\xe4\x30\xe5\x2d\xbc\x91\xa7\xac\xde\xef\xca\x1a\xa1\x5f\x98\x79\xf1\x44\x51\xe6\x22\x8c\xc3\xde\x20\x5d\x55\x81\xa4\xae\xdc\xf2\x2c\x2e\x60\x70\x46\xa0\x2c\x81\xc3\x38\x7e\x84\xbf\xc8\x57\xd3\x7b\x5f\x9b\x0a\x7c\x13\x44\x02\xe6\xa2\xfb\xca\x16\xa4\x80\x5b\x1c\x94\xe8\x00\x8e\x42\xcb\xd8\x21\x55\x21\x40\xfc\xa2\xd3\xbe\xd9\x3a\xf8\x59\x9a\xed\xc8\x37\x49\xd1\xfd\xf0\xd6\x9c\xd7\x21\xed\x5b\x58\x71\x59\xbc\xd6\x39\xa4\x0d\x6e\x2d\xc3\x84\x00\xee\x66\x5c\x47\x5d\xfd\xb4\x72\xf5\xc2\x6c\x3f\x54\x33\xfd\x12\xa4\xbe\x51\xf0\x60\x7c\x58\x37\x05\xb3\x96\x9e\x3b\x38\x4b\x50\x82\x4e\x6a\x72\xc1\x47\x40\x6f\x3e\x30\x14\x4d\xc0\x20\xf4\xeb\xe5\x62\xdc\xcb\xc5\x38\xe9\x71\xf6\x70\x6e\x2b\xb9\x6a\x0e\x3f\x64\xd9\x18\xd3\xea\x00\xca\x58\x7f\xcd\x92\xc1\x07\xf8\xa1\x34\x82\x30\xf1\xee\x32\xf4\x62\x20\x17\x74\x69\xc2\xa1\xc2\x10\x81\x6c\x98\x21\xbb\x42\x14\x46\x97\x2a\x2d\x90\x69\x64\x04\x55\x2d\xbb\x25\x0c\x25\xa5\x7b\x5a\x37\xaf\x94\x2c\x42\xb9\x1f\x4b\x79\xc5\xda\x2c\xf9\x20\xa7\x4b\x82\x08\x3b\xaf\x9a\x80\x64\x2e\xc5\x25\xf4\x85\xf6\xf8\x8d\x49\x18\x10\xfd\x42\xd5\x9d\x54\x5c\x75\xf3\x63\xff\x07\x89\xf2\xb9\x48\x86\xef\x9e\x31\x3a\x44\xb6\x3c\xea\xad\xde\xef\x60\x42\xe3\xc0\x45\xf2\x7a\xbf\xfd\x9c\x37\x83\xdc\xf4\x0f\xee\x00\x56\x74\x04\x49\xbc\x85\xa0\x78\x45\xc1\xd7\xc1\x14\x34\x5f\x3a\x50\x5a\xba\x25\x77\x20\x3e\xff\x51\x34\x25\x3d\xa0\xa1\xec\x4b\x02\xf1\xc1\x50\x65\x95\xe3\x98\x05\xa9\xd8\x35\xd0\x3a\xe0\x2c\x2d\x0c\xc5\x4a\xdc\xfd\xa1\x96\xda\x96\x49\xfa\xf3\x23\xd5\xb1\x80\xae\x68\xe5\x03\x48\xcf\x6f\x21\x53\x07\xb4\x85\xee\x2e\xf4\x11\x84\xe0\xb0\x77\xde\x2d\x53\x8f\x4c\x2d\x9f\xe3\xef\xee\x70\x49\xc6\x50\x85\x40\x0b\x81\x18\x60\x02\x16\x50\x8a\x43\x46\x66\x88\x74\xc0\xbc\x3f\xc2\x8a\xd9\xc6\x09\xf7\xac\xef\x63\x22\x75\x64\x2f\x7f\xfd\x10\x3b\xd1\xac\x8f\x6b\x08\xce\x23\x0b\x4a\x08\xc4\x45\x29\x87\x44\x3d\x2f\x17\x51\x60\x4d\x0e\x32\x2a\x0e\x44\xb1\x9e\x86\x57\x21\xf5\xed\x40\xb0\x73\x70\xcc\x83\x20\xfa\x58\xf2\xce\x94\xaa\xb6\xb4\x5c\x5f\x91\xf9\x2f\x92\x13\x4a\xb5\xbb\x38\x84\x65\x62\x6e\xbe\x50\x1d\x1a\xd1\x50\x5d\xea\x05\xf2\x09\xd2\x4a\x78\xb1\xb8\x08\xd4\xc4\x5a\xa5\xa8\xd0\x69\xfa\x63\x91\x57\x6a\xf6\x39\x66\x4d\x3b\xf2\x9e\x7a\x46\xf6\xb9\x13\xab\x62\xcf\xaf\x2e\x52\x71\x7b\xde\x88\x36\xdc\x33\x4a\xff\x81\x99\x78\x12\x7e\x81\x0c\x88\xb7\x1b\x16\xc5\xbf\x73\x38\x89\xf7\x88\x7b\x5a\x88\x7f\xb2\x20\x39\x3c\xc3\xe3\x66\x7e\x6c\xd3\xb7\x93\xa9\xd5\xad\x52\x43\xa0\x2a\xe7\xb1\x41\x32\xbf\xb1\x62\x70\x38\xd1\xe4\x8b\xf4\x9b\xb6\xa2\x0a\x52\xb3\x58\x26\x86\x62\xbf\xac\x35\x9d\x85\xb7\x50\xfb\x62\xd1\x6f\xe6\x52\x84\xed\xcd\xde\x2d\x61\x2e\x24\xcb\xb7\x15\x8e\xac\x80\xaf\xf0\xd9\xc6\x26\x19\x52\x2c\x57\x29\xd3\x53\xe0\x70\x0b\xc8\xd1\x36\xaf\xc2\x2b\x00\x4c\x44\xa1\x7d\xbf\x9e\x3c\x31\x4c\x3a\xbe\x2e\xbf\xf9\x82\x8c\x3f\x41\x15\x6e\x6e\x46\xa5\x83\xb0\xea\x71\x18\x06\x71\x15\x02\x98\x84\xb1\x2d\x3c\x9b\x2f\x2d\xfd\x57\xe4\x6d\x2b\x01\xca\xa0\xfe\xe4\x96\x03\x20\xb1\xff\x91\x3a\x40\x16\x4d\x18\x8c\x2f\xc4\x02\x05\x6f\x1a\x1f\xaf\xca\x66\x4a\xed\xfe\xad\x50\xba\xf4\x0b\xb8\x02\xda\x7d\xbe\x92\xa3\xd7\x2c\xe2\x0e\x63\x9d\x25\x7f\xe0\xa2\x00\x84\x6c\x3c\x52\xd3\x6b\xa5\x82\x42\x88\x32\xe4\xf5\x4c\x4f\x1e\x1e\x59\x5c\x3a\xcc\xcb\x83\x99\x91\xf8\x49\xef\xff\xf9\x14\x18\x8d\xaf\xb5\xdc\xd6\x77\xb9\x69\x2b\x10\x1c\x71\xbf\x09\x2e\xb1\x0e\x75\x9a\x73\x68\x26\xdc\x57\x65\x82\x7f\x83\xe8\x4b\x40\x35\xa6\xb7\x36\xb5\x07\x94\x2e\x2c\x5b\x12\x1b\xd1\x02\x69\x75\x24\x79\x20\x79\x97\x2b\x80\x06\x40\xcd\xfc\xd2\x22\x65\x75\x80\xdb\xc8\x94\xe7\xdd\xe0\x1a\x3d\x72\x27\x4c\x47\x19\xb4\x23\xef\xa5\x8c\xf2\x67\x08\x6b\x2a\xf4\x83\xb1\xc3\x1c\x9b\x49\xe9\x65\xb3\x01\x6e\xc0\x3b\x56\xaa\x01\x6c\x89\xe9\xe3\x0d\x09\x95\x4f\x6e\xb2\x0f\x33\x94\x51\x18\x82\xef\xfd\xeb\xd1\x28\x5c\xfd\x26\x99\xa3\x0d\xa0\x4c\x21\x50\xfa\xad\xa9\x55\x58\x2b\xd1\x84\x1c\x9a\x10\xc3\x3b\xa4\xe1\x2b\x51\xd5\x6b\x60\xb9\x56\xd0\x64\x7c\xb9\x7f\x88\xdb\x40\xf3\x24\x48\xf3\x5a\x1e\x77\x08\x8e\xaf\x25\x6b\xfa\xb4\x12\x47\xb9\x12\xff\x81\x68\xfe\x70\x5c\xb2\xba\xde\x88\xb0\x1c\x57\xbc\x20\xf0\x09\x6f\x01\x4f\xd8\x22\x8e\x80\x21\x19\x21\x34\x48\x08\x8a\xaf\xd0\xc9\x15\x52\x65\x26\x85\x7c\x9d\x25\xcd\xdf\x54\x1c\x6c\x28\xc0\x46\x7f\x9d\x9b\x19\xb3\xb3\xc5\x42\x14\x22\x4b\x46\xff\xaa\x9c\x4c\x00\xcf\x2d\x60\x87\x2c\xc0\xd6\x2c\x21\xeb\x95\xc6\x90\x74\x4d\x58\xf3\x10\xd2\xfa\x36\x13\xeb\xa1\xba\xea\x71\x55\x39\x91\x51\x13\x54\xb0\x2e\x73\x94\x72\xfd\x4e\x68\xba\x63\x36\x44\x49\x75\x2f\xe9\x5d\xb9\xe7\x35\x35\xfb\x69\x64\x5c\xf5\x3d\x99\x4e\xae\x84\x1f\xb8\x10\xbb\x73\xed\xdf\x86\x6b\x80\xdd\x72\x5a\x1a\xa4\xbe\x09\x43\xc8\x6e\x61\x79\x7b\xf6\xd0\x6b\xfc\x6f\xfe\xb4\xa5\xba\xe2\x8c\x47\x42\xe7\x2f\x62\x72\x2d\xb5\xff\x6a\x3d\x00\xae\xe2\x91\x0d\x41\x24\xbe\x80\x53\xc7\xb2\x7c\xc8\xe7\x86\x1c\x7e\x3f\x6b\x1d\xb4\x6e\x67\x45\x5c\x10\x0d\x02\xa6\xc2\xca\xa1\xa0\xc5\xd6\x7f\xf3\xa8\x7b\x61\x27\xbb\xec\x89\xf8\x8f\x0d\xb0\x13\x22\x32\xac\x09\x11\x14\x04\x9a\xb7\xc8\xf5\x71\x53\x18\x1a\xc4\x17\x59\xab\xd2\xdc\x09\x52\x71\xdf\x81\xda\x68\x06\xc8\xcb\x97\x5a\xbe\x34\x24\xd1\x02\x97\xfe\x29\xa0\x1d\xc2\x93\x83\xc2\xcd\xd3\x8f\xc7\xc8\xda\xc4\x99\x2b\xe6\x93\x9f\xb3\x4c\x00\x52\x75\x9c\x48\x88\x3c\xc3\xe3\x9a\xeb\x4f\x79\x96\x2c\xe9\xa8\x5c\x13\x53\xee\x25\xc9\xf7\x79\x49\x13\x87\x09\xbf\xf5\x0a\x75\x25\x10\x9b\x02\x40\x31\xed\xd7\x59\x07\x0f\x9b\x21\xcd\x2f\x44\xc2\xf0\xca\xfd\x3a\x9d\x5a\x3b\x65\x26\x48\x7f\xc9\xfd\xf6\x68\x08\x4a\xd0\x6f\x5a\x0a\x6e\xff\x7c\x69\x60\x0a\x79\x24\x02\x5e\xdd\xc8\x7b\xa6\x6c\x3f\xea\xe8\xec\x76\xa6\x37\xd1\x04\xf5\x9f\x4f\x8f\x3d\x7c\x71\x71\x4a\xe6\x72\xaa\x9b\x8d\x75\x3c\x18\xa7\xe6\x94\x1d\xb5\x09\x8b\xc6\x90\xf0\x67\x0b\x34\x35\xa7\x05\x1b\x63\x0d\xef\xe8\xf1\xe0\x95\x00\x00\x3b\xc1\x15\xd6\x7c\x34\x40\x07\x9e\x0c\x22\x30\xd6\xab\x11\xea\xdd\x11\x9b\x08\x8c\x06\x99\x01\x18\x43\x5f\xe6\x47\x44\xc3\x35\x08\xd2\xd1\xec\xb2\x7f\x8b\x84\xfd\x01\x49\x6d\x91\x2f\xc3\x60\xdd\x49\xd2\x52\x87\x08\xcd\xfd\xfc\xd6\xa2\x7d\x96\x5b\xf6\x18\x06\xd7\x3b\x50\x18\x01\xc9\x00\xf2\xa8\x79\x67\x0b\x1d\x92\xd7\x51\xf6\xd8\xae\x59\xe4\xca\x10\xd2\x88\x00\x1e\x24\x50\x1e\xb2\xca\x9a\x98\x24\x99\x32\x4d\xcc\x27\x32\xa0\x1a\x69\x0b\x73\x4c\xff\x3e\x52\xe4\x5e\x9d\xb2\x3b\xd0\x37\x98\xc6\x4a\x84\xc5\x1d\x86\xda\x17\xec\x96\x76\x85\x3f\x94\x8b\xf8\x08\xc5\x37\x25\x0d\x39\x26\x64\x26\x14\x8c\x9c\x6e\xa0\x3f\xe1\x9a\xc0\xcd\x00\xa4\xc1\x63\x6e\x49\xa9\xa5\x29\x32\xd8\x13\x14\x01\x7c\xd9\xe3\x65\x28\x42\x90\x74\x70\x80\xf4\x88\x42\x53\x70\x11\x28\x0a\x16\x59\x6a\xaf\xec\xc0\x31\xa2\x20\x72\xa2\xce\x6b\xc7\xe1\x95\x85\x52\x97\xa8\xa8\xc9\x7b\x55\xd5\xad\x06\xb8\x27\xaa\x12\x9e\xb5\x1b\x1d\xc6\xbf\x47\xa4\x89\xa9\xc5\x8e\x44\xb1\x25\x9d\xe0\x47\xa0\xf7\x7d\x49\xa4\x8c\x30\x1e\x39\xbc\x34\xe0\x45\xf0\xb5\x13\x40\xa6\xaf\x89\x6c\x00\xfe\x71\x12\xfe\x61\x57\x5b\xc2\xe9\x16\x0b\x31\x52\x30\x6f\xa5\xb2\x3f\xfa\xc7\x30\xef\x5e\xe7\x41\xe6\xdd\x51\x15\xb2\x48\x28\x12\x21\x7c\xc7\xf5\xbd\xb9\x6d\xd4\xb8\x6a\x44\xed\xde\x05\xfc\x59\x6b\x1a\x1e\x41\xf0\x19\x21\xe2\x23\x20\xc9\xad\x97\x66\x9c\xcf\x71\x66\x20\xf2\x93\x0b\x6d\x08\xee\xf2\xbd\x8c\xa8\xef\x72\xcf\xaf\xec\xca\x68\x6f\x51\x22\x54\xc4\xf1\x23\x8c\x54\x4e\x1f\xdd\xa0\xd5\x2f\x77\x3e\x02\x85\x60\x8d\x05\x4f\x8b\x73\xf5\x11\x2c\x05\x02\x3f\x28\x05\x92\x7c\xfe\xa5\x48\xf3\xcb\x31\x1d\x73\x13\xe7\xd8\x03\x88\xa2\x2e\x16\xd6\x08\xfa\x66\xcc\x1b\x23\x54\xd5\x08\x49\x59\x07\xae\x99\x75\x35\x53\x28\x90\x8f\x69\x68\x77\xc0\x99\xcb\xde\x85\x3f\xbc\x2f\xa3\x6f\xee\xa3\x9e\xf7\x1c\x6a\x1e\x0f\xb9\x92\xd7\x28\x7e\x3f\xa0\x63\x79\x31\x00\xa4\xd5\x61\x22\xa0\xf6\xf8\x61\xce\xfc\xbe\x13\xd5\x3c\x32\xd0\x99\xd6\xb2\x4b\xe6\x83\x8e\x26\x72\x30\x8f\x70\x91\x3f\x03\x68\xee\xff\x8b\x60\xf9\x71\xfc\x8a\x8f\x38\x21\x85\xcf\x93\x28\xab\x2a\x26\x8f\xb5\xfa\x3f\x59\x67\x65\xdf\x1e\x0e\x49\x25\x12\x45\xfa\x69\x8f\xf9\x74\x8d\xc1\x87\x8d\x0b\x29\xfa\x00\xf5\x0f\x65\x8b\x81\x5c\xf9\x21\x6c\x45\x9d\xd9\xc3\x65\x84\x28\x95\xf7\x70\x82\x81\x44\x47\xf2\x4c\x1d\x0f\x72\xe7\x1f\x9a\x7b\x3d\x92\xee\x5f\xe6\x50\x38\x7f\xe4\x00\x68\x8d\x1e\xf1\x21\x92\x3d\x03\x5e\x45\x80\x93\xca\x86\x1b\xde\xd8\x4f\x16\x9a\x32\x95\xe0\x33\x9a\x41\xc1\x5b\xac\x49\xb4\xf7\x15\x43\xee\xbc\x1d\x5a\x07\xee\x45\x68\x82\xb8\x27\x79\xa4\x8d\xf3\x3c\x7c\x65\x3b\xda\xcb\x67\x4f\x58\xb8\x96\x0f\x73\x98\x36\x58\xd3\xf6\x92\x94\x48\xea\xcf\x4c\xf1\x8d\x8f\xd4\x35\xfe\x28\x25\x0d\xb5\x17\x63\x72\xa8\x1d\x47\x27\xc3\x59\xf8\x72\x0d\xa7\xb0\xb6\x83\xa8\x58\xd6\x53\x30\xdd\xec\xf0\x12\x5f\xb6\x99\xf7\x50\x34\x79\x1d\x4a\x3e\x64\xde\x10\xa3\xbe\xa1\x60\x00\x2b\x48\x89\x4f\x81\x29\xca\xc1\x6c\x9c\x87\xbb\xd7\x5e\x87\x39\x1e\xf3\x61\x1e\xe6\x50\xe1\xf8\x48\x7e\x60\xc8\x77\xa8\x6a\x5c\x93\xbe\x6c\x26\x07\x4d\xe8\x1c\x90\x92\x2a\x81\x8c\x4d\x70\x2e\x44\x82\xe6\x03\x68\xf2\x2e\x0a\xce\x25\x02\x21\x49\x56\x25\xf1\x2c\x12\x16\x61\x70\x25\xda\xeb\x62\xfc\xdb\x00\x7c\x43\x76\x63\x66\xa1\x66\xdc\x6a\x94\x58\x92\x6b\xda\x3d\x23\x08\x9e\x32\xd7\x50\x6a\x0e\xcb\x00\x9e\x28\xe9\x3b\xa0\x74\x19\xd2\x28\xe9\xe1\xaf\xcc\xc0\x31\x69\x5f\x79\xd3\x7a\x87\x5d\x36\xdd\x84\xba\x2e\x61\xb5\xf0\x12\x72\xe3\x74\x39\x0a\x8f\xd2\x4b\x06\xdc\x16\x56\x6e\x96\xf6\xef\x2a\x19\x07\xd8\xd5\x61\x93\xd2\xfb\x10\x93\x12\x0a\xd0\x14\xd3\x80\xa2\x47\x26\x5d\xb0\x93\x82\x71\x93\xea\xbe\x36\xd3\xfc\x58\xcb\x23\x0b\x87\x70\x17\xf5\x48\x02\x19\x30\xa2\xd6\xba\x21\x14\x1b\xca\x16\xfe\x0c\x53\x91\xa0\x06\xdb\xf9\xde\x5e\xea\x00\xd0\xac\xf8\x35\xc2\xa6\x44\x0e\x0a\x30\x15\xb7\xdb\xf9\x7e\xa4\x38\xc3\xda\xd2\x50\x36\x29\x3f\xf8\x40\xf6\xce\x57\xe3\x11\x52\xd4\xba\x30\xc4\x7e\x73\x89\xd4\x9b\xff\xf8\xa9\x4a\x30\xe3\x56\xa3\x07\x35\x5d\xca\x7a\x00\x83\x1a\x22\x1a\x10\x23\x0a\x45\x8c\x0c\x44\x81\xef\x8c\xa7\x4d\x7a\x21\x39\xf8\x7c\xbd\x44\x32\x92\x10\x44\x7d\x7a\x6a\x5c\x09\xbb\xf6\x1d\x3c\x08\xc2\x6a\xd2\x95\x04\x83\x39\x25\x54\x64\x91\x27\x40\x92\x3e\xc4\xca\x81\xea\xb1\x7d\x78\x4f\xf5\x6e\x59\xc8\x80\x08\x1e\x1b\x5d\xf0\xc2\xa1\x0b\xd0\x1c\xd5\xe3\x31\x84\x2c\xf4\x98\x24\x8c\xd3\xaa\xbc\xd8\x3d\x43\xed\x90\x03\x3a\xed\x76\xd5\x8b\x45\x92\xa9\x20\xcc\xce\x2b\xb7\x52\x2b\xa8\x3e\x22\xe8\x6a\x08\x23\xa8\x48\xdb\x01\xdd\xce\x6d\xa1\x8d\x19\xe0\x99\x0a\xee\x2d\x0f\xcb\x9c\x40\xe7\x04\xc4\x70\x5f\x70\x85\x4e\x57\x01\x08\x54\xce\xc9\x81\x38\xc1\x34\x22\x4e\x74\x67\xb0\x62\x5d\xd6\x22\xab\xbd\xa1\xf3\x03\xe1\x11\xc8\x9a\x6c\x52\xc5\x68\x7b\xe5\x41\xb8\x9b\xb4\x7c\x6d\x21\xec\x83\xe0\x3c\xf6\x36\x04\xb2\x26\xe6\x96\x04\xdd\xbc\xe6\xac\x98\xea\x98\x5d\x34\x79\x1d\xc4\xbb\x08\x89\x79\x06\x06\x07\x49\x66\x3f\xf3\x12\x83\x48\x8b\x84\x96\xb9\xc2\x8e\xde\x75\x49\x09\xab\xb1\xd7\xe9\x25\xc5\x0a\x78\x80\xc4\x06\xa7\x8e\x7b\x52\xc2\x02\xe3\xad\x13\x25\x1d\xa1\x75\xa8\xae\x81\xe1\x23\x67\x1b\x36\x27\x8f\x3d\x91\x65\x26\xc0\xc8\xae\x45\x60\x78\x26\xb2\xc1\xba\x42\xcf\x12\xc0\xe2\x26\x2d\x69\xc4\xbe\xda\x65\xb8\x9a\xd6\x46\xbf\x68\xe0\xce\x58\x5e\x14\xf1\x36\x00\xb3\x23\xec\x0e\x15\xca\x3a\xa0\xf5\x79\xc2\x10\xe8\xa3\x10\x87\x36\xa5\x99\xbd\xe7\x07\x02\xb9\xd3\x70\x3b\x77\x58\x4c\x84\x77\x07\x73\xb1\x1d\x20\x54\x76\x24\x81\x7e\x46\x54\x3a\xaf\x2b\x00\x3d\x82\xeb\x40\xa2\x86\x84\x97\x2e\x4b\x93\xc0\x81\x3d\x01\xe6\x21\xb7\xd9\xad\xee\x4f\xa6\xb5\x3b\xeb\xb5\x79\x15\x6c\x4a\x10\x9e\xf6\x7a\x1a\x73\x8a\x43\x48\x48\x12\x79\x98\x40\xe8\xbc\xf5\x24\x7d\xfd\xef\xed\x95\x18\xe4\x42\xcf\x76\xa1\x13\xf8\x5f\x42\x1e\x8c\x4a\x98\x61\x14\x3d\xeb\xde\x2f\x30\xb0\x96\x8a\x4a\x21\x5f\x17\xc8\x2e\xc1\xd2\xe6\xe3\xb9\x0c\xc7\xfe\x7c\x84\xf8\x59\x7a\xfd\x0f\xa5\x4f\x81\xf9\xe1\x23\x99\x88\xaf\x4a\xe3\x58\x04\x22\xa2\xbe\x1f\x0a\x6f\x7a\x98\x53\xd7\xba\xf1\x2e\xb1\x8a\x93\x2e\x4e\x3b\xbc\x8d\x71\x6c\x8b\x4d\x5a\x46\xca\x7f\x00\x29\x60\x0d\x73\xd1\x87\x14\xab\x51\x8c\xa1\x0c\xc7\xd9\x4a\x1d\xf8\x85\x92\xd7\x50\xb1\x1f\x09\xbc\xfd\x96\x7f\x4d\x42\xe5\x7f\x6d\x08\x1f\xa5\x8d\x6c\xf6\xce\xd1\x91\x0d\x5e\x05\x42\x41\x9f\xb7\x53\x4a\x64\xd4\x88\xc9\x23\x3e\x1d\x48\x59\xef\x5f\xb8\x8f\x2f\x12\x8a\x15\x44\x04\xad\x77\x08\x85\xdc\x84\x94\xfc\xc8\x82\xbf\xa7\xaa\x08\x93\xd8\x76\x39\xaf\xaf\xba\x48\xfe\x57\x8e\x22\x12\x67\x5a\x59\x9a\x75\x79\x11\xca\x94\x38\x85\x81\x90\xa6\x25\x1e\xcd\xa4\xde\x38\xe4\xdf\x21\x31\xe2\x65\x82\xd4\x17\xc7\xf6\x24\xef\x0c\xfc\xdc\xbb\xc3\x3a\x1a\x9b\xc7\xfd\x50\x77\x44\x86\x1e\x7c\x29\x3f\xaf\xd2\x24\x3f\x3f\x30\x29\xea\x8b\x98\xe7\x1f\xa2\xa6\x3f\x14\xa3\xff\x04\x0a\xf6\x13\xa5\xd1\x4f\x5e\x55\x25\xb2\x08\xf5\x0b\x8f\x04\x1f\xfe\xa4\x4a\xec\x97\x05\x2c\x31\x7f\x40\x37\xf5\xfb\xf0\x49\x63\x39\x9b\xcf\xbf\x90\xd2\xef\xc4\xd1\x0a\x60\xf3\x99\xcb\xe8\x11\xad\x8f\x5a\x65\x4c\x81\xee\x0a\x82\xfa\xeb\x4f\x78\xff\xaf\xf4\xfe\xa7\x16\xe3\x2b\xc8\x13\xf0\x00\x79\x09\x33\x74\x02\xbf\xc9\x95\x7b\x7c\x8b\xe1\x9f\xb4\x4c\x96\x60\x13\x59\x6c\x53\x77\xbf\x86\xf0\xff\xff\x74\x32\x31\x01\x43\x6a\x0a\x85\x92\xb7\xf2\x91\x2f\x17\xf1\x14\x9e\xa8\xad\xdb\xe3\x50\x99\xee\x75\x2f\x09\x42\x32\x94\xb4\x49\x16\x36\x19\xad\xa2\x36\xc7\x8b\xe6\x4b\x01\x86\x5f\x7f\x74\x64\x9e\x04\xfa\x3d\x9d\x40\xeb\x7a\x26\xf3\x2d\x24\xd1\x7e\x71\xc2\xec\x02\x26\xbb\xe4\x4b\x38\xe5\x7b\xce\xda\xb6\x27\xe0\xee\x89\xb4\x9a\x14\x4e\x90\xf3\xf2\xa5\xee\xe8\x33\x03\x22\x89\x20\xbd\xbd\xb3\x7f\x26\x0d\xbf\x9e\xe9\x94\x77\xc8\x19\x5e\x8a\x72\x09\xa1\x45\x37\x2c\x40\xd0\x11\xb2\xc7\x7f\x42\xfc\x3d\xbc\x3a\x2a\xd8\x3f\x14\x27\xae\x24\x8c\xc2\x08\xc4\x2f\x45\x65\x6e\xaa\x86\x61\x4c\xdd\x48\x78\xb7\x2e\x9b\x60\x9f\x3b\xe0\xef\x8e\x01\x4a\x81\x01\xda\x28\x58\x4d\xfc\x0f\xc7\x27\x77\x0d\x2d\x85\xfb\xb4\xf7\x87\x40\x9a\xb3\x4c\x04\x02\xcd\x72\xc3\xb1\xe8\x1a\xa8\x79\x41\x48\xd0\x4d\xc4\xd0\xdc\x75\x11\xe6\x83\x35\x67\x00\x82\x64\x1e\xe2\x06\xe3\x21\xe0\x0a\xc5\x8e\x5b\x56\x08\x1e\x6b\xf2\x72\xf3\xb7\xd8\x42\x48\xb1\xbb\x89\x61\x20\x89\xe0\xd5\x46\x0b\xf8\x0c\x58\x90\xae\x2a\x15\x15\x0b\x75\x76\x45\x2a\x2a\x03\x1e\x0c\x1d\x04\x50\xd9\x1f\xd9\x95\x08\x6c\x74\x1e\xde\x38\x59\xd0\x57\x37\x1a\xb7\xde\x8a\xd3\xb8\x7b\x16\x4f\xfc\xd6\x68\xf3\x9e\x37\x42\x88\x22\xcd\x75\xcf\x1c\x6b\xdc\x93\x5d\xc5\x1f\x0a\xb3\x8c\x10\x16\x0e\x6d\x96\xd3\x06\x6b\x4b\x8e\xd8\x61\xc8\xfa\x20\x7f\x93\x12\x3f\x78\xca\x61\xea\x69\x9d\x43\xe5\xc2\xfa\xfd\x27\xc7\x45\x77\x0e\xd2\x2f\x30\x4e\xb3\x54\xc6\x2c\x16\x94\xf8\xce\xe1\xa2\x6f\x17\x56\x25\xe1\xdb\xd5\xa7\xb8\x52\xa2\x7d\xf6\xca\x32\x51\x0c\x4d\x7f\xef\x38\x81\xed\xa9\xf2\x83\x49\xba\xf9\x09\x6c\x85\x9f\xff\xa3\x84\x0b\x01\x4c\x5f\x4d\x0c\x77\xab\xb0\xb7\x22\x1c\x4b\x5e\x01\xab\xbf\x9a\x2b\xe9\x55\x9b\xf2\xd9\x55\x69\x22\x7f\xd9\xcc\x85\x10\x96\xca\x61\xf8\x65\x8f\x63\x83\x25\xdb\x07\x02\x32\xc0\xb8\x10\xc0\xe8\x64\xe6\x09\x63\x82\x5d\x80\xa7\x3d\xd3\x06\x85\x9f\x62\xbc\x72\xdd\x2c\x1c\x7a\xa8\x1a\x25\x46\xc1\xa8\x99\x52\x58\x26\x47\x3a\x38\x0c\x4f\xf4\xcf\xec\x83\xe8\xa4\x17\xaf\x9f\xff\x54\x98\xc6\xe8\xac\x92\xea\x99\x16\x9d\xb4\xc1\x02\x26\x6a\x14\x28\xca\xfd\x31\x02\x0e\xe5\x14\x50\x6e\x7c\x38\x75\x53\x17\xee\x38\x93\x58\x4c\x08\x71\xce\x8c\x0b\x28\x8e\x01\x78\x42\x6b\xa9\x08\x3e\x36\xcd\x3a\x05\x50\xaa\x37\xc3\x59\x18\xa1\xc3\xda\x14\x22\x41\x2c\x0c\xe9\x99\x14\xca\x95\x57\x61\x59\xed\x2a\x07\x7f\x7b\x51\x89\xf1\x6a\xb8\x50\xee\xe2\xf0\x49\xee\xb1\xc2\x84\xd5\xa3\x05\x28\x52\xff\x7f\x4a\xe9\x5c\xdb\x5b\xff\x76\x9b\xa5\x16\x75\xad\x85\xf6\x20\x3e\x21\x23\xe6\x89\x36\x5c\xd6\xf3\x10\x90\xb4\xb0\x07\xbc\x80\x89\x1a\x14\xac\x04\x41\xb1\xd0\x6b\x33\xfe\x73\x90\x76\x0d\x0a\x35\x02\x0a\xcd\x5b\xe0\xa1\xb8\xbb\x64\xa1\xaf\x70\x02\x03\x3e\x2a\x80\x52\x1a\x64\x5c\x53\x5d\x08\xb4\x9a\x6c\x10\x42\x00\xd3\x54\x7c\xb6\x6b\x4b\x31\x83\x90\x1e\x58\xa2\xe9\x03\x6e\x8a\x27\x03\xb0\x94\xa0\x51\x73\x5b\xfa\x33\x0b\x59\x62\x1b\x1b\x49\x0f\x67\x8f\x6b\x3b\x09\x53\x84\x54\x72\x89\x88\x4b\x42\x51\x60\x88\x38\xc9\x60\xd5\xe2\xc7\x19\xdf\x0a\xa8\x95\x42\x2a\x12\x4e\x32\x04\x54\xbd\xd8\xe7\x3a\x10\x8b\x9a\x3a\xf7\xc4\x6f\xa8\x47\x7d\xe5\xff\xaa\x10\x5a\x47\x5d\x9f\xb4\x4f\xbc\xe4\x5d\x71\x35\x1b\x30\xc7\xe4\xfc\x32\xb2\x5f\x45\x61\xa5\x3c\xfb\x94\xed\x6a\xa8\xb2\x9c\xc7\xd0\xeb\x19\x34\x17\xb1\x48\x00\xbc\xc6\xcb\xbe\xb2\x8f\x7b\x75\xcd\x7b\x09\x59\x5f\x7d\xd8\x2e\xc0\xbf\x23\x74\x73\x5e\x74\x8a\x93\x89\x4d\x03\x7c\xd5\xaf\xe0\x8e\xe4\x36\x5d\xaf\xe7\x52\xb0\x36\x83\x9b\x3d\x0c\x0f\x42\xbe\x87\xe1\x56\x43\x75\x87\xea\xf4\x01\x13\x0b\xd6\x16\x90\x62\xdb\x15\x81\xff\xc8\x3e\x89\x0a\x70\xf5\x49\x78\x9c\xcb\x65\x1a\x67\x46\x8f\xc7\x3c\x10\xc0\xf5\x8f\x62\x49\xe9\x45\x70\xfa\x95\xea\xd3\x46\xd3\x84\x25\xa6\x70\x66\x4a\x4d\x99\x29\xb1\x6a\x8b\x21\xc1\xdc\x22\x0d\xf6\x10\x36\x01\xa8\xf0\x0c\xf0\x80\x42\x3e\x9a\x98\x5f\xb0\xcf\xe1\x9d\x4b\xab\x40\x6c\x23\x1f\xd2\xf4\xe0\x49\xc5\x31\x7a\xcf\xc4\x72\x9d\x14\x10\xaf\x94\xbc\x8f\x81\xf0\xd8\x2c\x89\x1f\x95\x00\x4e\x71\x8d\xce\x2a\x7b\x41\x0b\x3c\xb7\x09\xf5\x78\xe9\x02\xd9\xf5\x23\x36\xad\xe3\x63\x01\xaa\xa7\x30\x67\x9f\x77\x2f\x98\x59\x3d\x08\x4d\xab\x0f\xdf\x04\x35\x01\xa2\xd7\xae\x4d\x5e\xe4\x98\x5b\x9d\x01\x55\x6b\xf6\x37\x65\xa7\x2d\x8d\x4d\xc2\xb8\xe3\x2a\xd4\x59\x00\xbd\x11\x49\xec\xe2\x2c\x01\x89\xcb\x13\x15\x86\xec\xb7\xaa\xbd\x46\xec\x8b\x0e\x15\x50\xff\x16\x3c\x93\xe8\x2f\xcf\x59\x8f\x9c\x9b\xf9\x72\xca\xec\xc6\xe2\x7e\x66\x33\x8d\x7a\x26\x0a\x2b\xd8\x5d\xdd\xc3\xb1\x47\x8f\xe1\x89\x8a\xdf\x25\xc8\xda\x41\x7a\x8e\x45\x74\x03\xb2\xde\x65\xa6\x52\x92\xbd\xde\x8b\xce\xda\x7b\x03\xcf\xc4\x59\x7f\x43\x38\x1b\x34\x7a\x89\x63\x43\xe3\xb3\xf2\x7e\xda\x88\x85\x58\xb4\x3b\xfd\x6a\x92\x73\x26\xf1\x10\xa1\xbd\x11\x4e\x3d\x4c\x19\x9d\x89\x59\xc7\xd3\x26\x17\x9c\x4f\x9d\xf2\x16\x05\x7f\x9f\xdf\xfd\x57\x13\x95\x84\x38\x04\x3d\xea\x05\xd5\x15\x07\x42\x55\x80\xa1\x5b\x13\x7e\x58\x8f\x7e\x4b\x1c\xc8\x2e\x15\x67\x9e\x16\xf3\xe6\x1e\x18\xa4\x85\x04\xd0\x19\x29\xe3\x03\x1d\xf4\x8b\x3e\x8f\x36\x31\xba\x02\xdf\x16\x90\xae\x72\xea\x2b\x6b\x39\x99\x17\x38\x94\x06\x74\x0c\x1c\xf5\x71\x10\x11\x00\x77\xaa\x88\x7e\x94\x10\xe3\x3c\xbe\x93\x1e\x0b\x1f\x81\x8f\x4b\xdf\x75\x90\xb4\xf2\x2d\xd7\xca\xb3\x5f\xe5\x5e\x6d\x73\xa9\xca\xb4\xcb\x31\x2b\x2d\x0f\xd8\xdc\xbd\x7c\x91\x6f\xee\xd0\xff\x43\x0c\x5c\xe0\xd5\x38\x1f\x3d\xe6\x14\x23\xf5\x03\x0c\x58\x3a\x7f\xc2\xc5\x04\x8d\xc3\xf1\x20\x1d\xe5\x20\xf6\x4b\xf0\x35\xd8\xfe\xfd\x08\x11\x47\x41\x25\x29\xf5\x00\x7b\x2f\xe0\xdc\x79\x25\x22\xdc\xce\x35\xea\x59\x16\x2f\xda\x8c\x18\xba\x5d\x22\x68\x87\x2b\x69\x7b\xc0\x73\x0a\x12\xec\xc1\x1c\x0c\xb0\xcc\x1c\x6d\x40\x34\x68\xe0\x37\x74\x8f\x07\xa8\x19\xbe\x95\x21\x19\x34\xd8\xb5\xe3\x21\x84\xfd\x3f\x20\x46\x7b\xde\xd4\x55\x3b\xe4\x12\x05\x47\x95\xb7\x96\x78\x65\x0a\x06\x4d\xbc\x56\x7f\xcc\xdd\xcb\xb9\x49\x19\x03\x62\x42\x4c\x1f\xe0\xb5\xf5\xe7\xae\xac\x3e\x30\xf7\xe7\xab\x84\x56\xb0\x0c\xd8\x8a\x30\x67\x85\x32\x16\x65\x28\x82\xba\x14\x22\x91\x7e\xdc\x87\xc8\x27\x97\xb6\x9c\x59\xcd\x68\x12\xf6\x7b\x55\x26\x67\x2f\xcf\xc2\x85\xe6\x7d\xfb\xd7\x32\x07\xbe\x0c\xec\x74\xf6\x79\x61\x93\xb6\x4b\x39\x1f\xd8\x9e\x46\x64\xd9\x95\xc5\xb3\xe5\xf0\xc1\xbc\x51\x07\x02\xed\x53\x81\x76\x8e\x39\xd3\x9e\xdf\xca\x2c\xee\xf9\x75\xc9\xdf\xe8\x29\x97\x86\xdd\xda\xfb\xc2\x49\x9b\x85\xee\x37\xa5\x1e\x67\x83\xc5\x71\x52\x20\x61\xec\xcd\xfd\xdb\x57\xaf\x67\x6f\x75\x3b\xc4\xab\xdb\xd0\xd4\x3a\xd4\x28\xda\x5a\x0b\x26\x01\x50\xb6\x52\x57\xcc\x05\x0e\x8f\x6f\xc9\x1b\x2d\x61\x47\x14\xba\x88\x80\x99\x09\xe9\x65\xb7\x89\x89\x30\x57\x56\x65\x8d\x18\xe1\x42\x5f\xb9\xcd\x3d\xdd\x19\x80\xf6\x4a\x79\xa4\x1d\x36\x8d\x8a\xb8\x90\x59\x50\xdc\x2a\xf8\x14\x5d\x84\x93\x2a\xcb\x65\x73\xbd\x4b\x42\x45\x9a\xcc\x6c\xf3\x1a\xa0\xbb\xa6\x45\xba\xcd\x13\xe5\x8f\x06\xc0\x16\xc9\xe0\xdb\x34\x24\xd8\xf2\x25\xf9\x21\xf7\x81\xfa\x21\xba\xce\x1e\x2e\x21\xef\xa8\xf9\x93\xd7\x50\xa8\xdc\x5a\xb7\xbd\x65\xbc\xfd\x7e\xe0\xfe\x9e\x47\xa2\xbd\xfa\x3d\x07\x0a\x0e\xf6\x4f\x67\x0e\x30\x9d\x5a\x27\x87\xd8\xfd\x11\x3c\x5a\x9f\x02\xd2\xfd\xd6\x3d\x14\x7c\xfa\xb1\x29\x1e\xcd\x8e\xe9\xb7\x20\x2b\xb5\xb1\xf5\x0d\x09\xd9\xe7\x75\xc2\x94\x4e\xe0\xb8\x56\xfa\x06\x6e\x4e\x5d\x35\x04\x8c\x02\xef\x97\xd0\x3f\x7a\xf0\x92\xdc\x53\xaa\x72\xed\xb9\xab\xdc\x86\x1c\x39\xf7\x43\xec\xdb\xc4\x79\x27\x64\x8b\x02\xf2\x86\xc4\x27\x37\xf4\x0a\xaf\xc2\x6d\xd6\x3f\x38\x97\x10\x33\xf5\x6e\x36\x7d\xe1\x71\xe5\x8f\xc4\x51\x0e\x21\x22\x4a\x04\x63\x29\x93\x21\x6b\x4f\x56\x41\xe6\xde\xa8\x8b\x73\x8f\xbd\xa1\xe7\xb8\xf9\x2e\xc4\xf4\x46\x5e\x91\x0e\xc6\x61\xaa\x2d\xb7\xc8\x88\x58\x9c\xfa\x24\xec\xdf\x6f\x33\x54\x1a\x03\xc0\x07\x52\x15\x6d\xe8\x60\x73\xb4\x2b\x88\x1d\x7a\x4a\xd9\x6e\x3c\x07\xba\x49\x31\xc4\x80\xcc\xdf\xc0\xf5\x4d\x85\x9e\x37\x6b\x3e\xd6\x03\x04\x0a\xad\x3a\x8b\x71\x85\x7d\x1d\xbf\x81\x44\x37\xa9\x80\x6b\x9d\xce\x58\xfe\xb8\x34\x12\xde\x0f\xc2\xbc\xca\x4b\x50\x74\x74\x22\xaa\xb1\x43\x47\x80\xa2\x3f\x90\x40\x70\x8c\x57\xd9\x3d\xb5\x4c\x1d\xa2\x42\xdc\x58\x79\xc4\xcf\x5e\x4b\x7e\x7d\xe1\x0a\xab\x0d\x41\x02\x71\xc7\x72\x1e\xc4\xe3\x5b\xaf\xbb\xda\xff\x5e\xb9\x76\xfd\xcd\x7b\x3b\xc6\x3c\xd6\x42\xdf\x24\x34\x4a\xbe\xec\xd8\xaf\xad\xb9\x2e\x31\xe5\x5c\xb3\x8d\x21\x89\x3b\xcb\x8d\xb3\xb2\xc2\xa9\x91\x8a\x4e\x79\xff\x30\x17\xba\x7a\xa9\x57\x6d\x83\x7d\x38\x04\xc5\x13\xeb\xdf\x3b\x42\xc2\xfc\xe0\x49\x48\x1c\x1e\xaa\x5f\xc2\xbc\x7d\x84\x93\xfb\x30\xad\x0b\x9c\x1d\x31\x6e\xc2\xbf\x61\x94\x6b\x6f\xbb\x84\x94\x24\xa8\x64\x13\x0e\x0e\xc0\xd7\x14\x32\xcf\x70\x47\x8d\x48\xe0\x45\x98\xe2\xf0\x58\x68\x15\x2f\x46\x23\xdd\xc2\xd1\xaa\x29\xf7\x80\x0a\x1c\xdb\x26\x47\xe8\x29\xf8\x6a\xc6\xac\xd1\xb3\xb9\xfb\x92\x56\x35\x33\xd2\x35\x8d\x67\x96\xbb\x53\xcf\x27\x0d\x66\x4b\x51\x97\x81\xcb\xd2\x4d\xa8\x1d\x50\x38\x4a\x7f\x2d\x75\x3e\x78\x46\x4b\xf5\xc9\x8c\x47\x3e\x3e\x86\x98\x12\x67\xb6\xcb\x99\x84\x89\x5a\x5a\x6a\x69\x09\x21\xc5\x05\x0c\xeb\x39\x24\x93\x3e\x14\x72\x2a\xb0\x9e\x22\xee\xee\x0e\x57\xa5\x5b\x3d\x90\xa0\x78\x6f\x86\x42\xf3\x39\x66\x6c\x81\x8b\x66\x83\x01\x96\xf9\x53\x37\x46\x53\x38\x14\x95\x86\xc2\x83\xbf\xbe\x2f\xf9\x54\x2f\x3b\xe7\x8b\x8e\xe5\xfb\x71\x74\x9e\xe7\x96\x96\xc6\x90\x5a\xe6\x06\xc2\x43\x01\xc5\xff\xfd\x7c\x04\x2c\x6f\x68\xea\x48\x8d\xfa\xb2\x7c\x4d\x64\xac\x6d\x88\x92\xc1\xd2\x04\x35\x97\x3c\xf8\x78\x64\xf1\xaa\x48\x56\x18\xc3\x20\x87\xe4\x49\x10\xc9\xde\x76\xb6\xd6\x0b\x58\xf9\x0a\x64\x7a\xb6\x34\x91\x04\x44\x3e\x1e\xb5\x60\x26\x60\x8f\x73\x80\x5f\xb8\xc7\x87\x04\xdf\x2f\x34\xa2\xd2\x52\x3d\x5c\x55\x57\xfc\xcd\xd5\x9f\x0b\xe0\xdc\x89\xa3\xf9\x45\x51\xc1\x93\x88\xbf\x36\xa2\x76\x89\x23\xa9\xb4\x23\x85\xe1\xcb\x2b\xc7\x93\x63\x4d\x70\x1f\x83\x61\x8b\x5d\xf1\x68\x9b\x0a\xae\x27\x3c\x17\xbc\x81\x06\x4c\x8f\x58\x3c\xa7\x39\x8f\xdf\xd0\xa3\x35\xf4\x83\x2c\x9a\x39\x3b\x9d\x6c\x7e\x15\x58\x3d\xf4\x88\x82\xad\x9d\x54\xce\xb0\x93\xf3\xc7\xdf\xe1\x76\x0a\xf6\x2f\x52\x4f\xbd\xe5\x44\xdf\x47\x46\x0b\x37\x3b\x59\xe7\x9b\x4a\x69\x5f\xd9\xd5\x7f\xc5\x9e\x16\x83\x72\xe9\x03\x00\x1a\x34\x31\x98\x03\xcb\xe7\x95\x0e\x62\x00\xed\x69\x52\xfd\x73\x2a\x1c\x41\x41\xe5\x97\x9e\x46\xf6\x86\xf5\x53\x00\xd7\x3c\x75\xe9\xf5\x4e\xff\x34\xea\xb7\x80\x36\x4d\x25\xa5\x2e\x60\x7e\x9e\xc5\xf5\xa3\xe7\xd7\x2a\x4b\xa5\x2b\x5c\x96\xac\x3f\x5b\x85\xe8\xdb\x04\xb0\x3b\xa4\x43\xd4\x6c\x67\x80\xd8\x5b\xbf\x90\xbd\x86\xd8\x9b\x87\xbb\x93\x1f\xcd\x04\x2c\x03\x61\x70\x6c\xa3\x26\xc0\xf6\x42\xf4\xc8\x5a\x0b\xa4\x4d\x05\xbe\xe3\x14\x70\x4a\x2a\x06\x4c\x3e\xcf\xde\x42\x0f\x29\x39\x26\x3f\x3e\x10\xa3\x67\xef\xe0\xc7\x83\x79\x8c\x53\x02\xc6\x5b\xfe\x4d\xfd\xa2\x74\xfc\xa8\x4a\x95\xcd\xc9\x07\xe6\xcf\x02\x49\xb7\x12\x37\x67\x3d\x5f\x65\xfa\xdd\x63\xfb\xaf\x0e\xa1\x42\x33\x2a\x4d\x9f\xb3\x36\x61\xa4\x2a\x38\x9b\x05\xe2\x2f\x5b\x18\x10\xbb\xfb\xb3\x08\x4f\x77\x5d\x8d\x6f\x40\x98\xdd\xc5\x68\xd0\x1a\x3c\xf3\x82\x6a\x9d\x45\xe2\x4b\x04\xb1\xd9\xf2\xf1\x23\xf8\x9d\xf2\x47\x1e\x57\x42\xf6\xac\x21\xe7\x2a\x40\xa7\x2f\x45\x43\x0c\x82\xc6\xa0\x5d\x01\xa5\x17\xc7\x67\x4e\x78\xb4\x41\xeb\xd0\xb8\x86\xa3\x24\xbc\x80\xd0\x0b\x41\x24\x80\xf5\x4e\x90\x73\x7f\x08\xd7\x4b\x42\xe6\xad\xb9\x9b\xdb\xd9\xda\x73\x21\x91\x24\xdb\x91\xa5\x83\x71\xfd\x56\x3f\xc7\x18\x6e\x8e\x9e\xf5\xd4\xa6\x36\xda\x69\x1a\x4f\x90\x60\x5c\x7d\xd2\x30\xe2\x9d\xdd\xd8\x25\x7a\x4c\x0a\xce\x38\x85\x66\x13\xab\xa0\xa8\x45\x7e\xb8\x0c\x49\x2a\x1b\x7e\x9e\x1b\xc7\x63\x16\x4b\x93\x2a\xcf\x4d\xe3\x69\xde\x84\xa3\xab\x36\x4c\x97\xaf\xf8\x88\xfb\x2d\x24\x65\x3a\x39\xcc\x44\xef\x4a\x24\x60\x42\x99\xc5\xff\x4b\x12\x10\xd3\xfa\xbd\x57\xa0\xf1\x06\x56\x2a\xfd\xc3\xfa\xe6\x59\x91\x6d\x0b\x60\x5e\x3c\x5f\x29\xd8\xe3\xa3\x80\x05\x23\x90\x64\x3c\x98\xce\xd1\x96\x6a\xca\xc6\x94\xce\x90\x7b\xba\x66\x51\xbf\xe1\xb1\xc5\xe9\x1a\x3c\xb6\x68\x29\x55\xc7\x4a\xfc\x1c\xa5\xd4\x1e\xd0\x46\x17\x5c\x6f\x26\xe5\xce\x02\x92\xcc\x2c\x18\xe2\xbb\x7c\x51\x5c\xf4\x11\x5a\x42\x8f\x53\xb2\xa6\x0e\xd4\x63\x23\xe2\x40\x3d\x9f\x87\xf9\x43\xf1\x10\x83\xe8\x21\xf1\x67\xc0\xf3\xd4\x5c\x5a\xd8\x31\xc9\xf2\x58\x59\x7f\x7d\xc0\x18\x98\x2b\x72\x00\xf5\xb2\xbe\x08\xd5\x29\x9b\x94\x74\x95\x6f\x38\xf4\xa6\x92\x6a\xc1\x8f\xb9\xc1\xfe\x1f\xb1\x66\x9d\x0f\x26\xd8\x21\x41\x95\x67\x89\x50\x09\x1d\x28\xdb\xc4\xc7\x9c\xae\x96\x41\x03\x92\xcf\xef\x84\xcb\x52\xb1\xd6\xfd\x08\x60\xba\x05\x63\x24\x40\x1e\xd6\xe7\x51\xe6\x2a\xcf\x01\x08\xf4\x96\xf3\x01\xe1\x5f\xff\x05\x18\x08\x31\xa0\xea\x3d\x7c\xbc\x1c\x4f\xf7\x92\xfa\x17\x66\x1b\x6a\x1c\x11\x4a\x2e\x38\xdf\xa1\x33\xa5\xa9\x86\x0b\xfa\x79\xb0\x37\x79\xa9\xdd\x2d\xb6\x54\x89\xce\x33\xd5\x0a\x91\x81\xfa\x03\xea\x13\x8a\xf0\x6b\xdf\x35\x7c\xa1\xcd\x79\xd8\x4a\x30\xcd\x73\xc0\x61\x32\x07\xc6\xd9\xf1\x62\x04\xf0\xbd\x66\xcd\x0a\x87\x7a\x64\x82\xfc\xe0\xd4\xaf\x68\x0c\x2b\xae\x44\x05\xdf\xa1\x62\x12\xab\x70\x24\x1a\x7d\xb0\x76\xcc\x73\x9c\x43\x1d\x3e\x5e\x83\x1b\x00\xf4\x04\x82\x9c\xa9\x8f\xa1\xf6\x52\xaa\x2a\x4e\x04\xf7\xb1\x20\xc4\xaa\x3a\x80\xb7\x2f\x7e\x08\x18\x61\x8e\x47\x67\x70\xd9\x7e\x62\xf8\x80\xfd\x62\x80\xf7\xd7\x8f\x55\x36\x89\xd8\x0d\x01\x7e\x19\x4a\x90\x87\x07\x1b\x14\x01\x4d\xa2\x0f\x6a\xd0\x1d\x4c\x48\x94\xe0\xfc\x75\xd6\x9a\x03\xaf\x38\xab\x65\x18\x9a\xc4\xf5\x30\x07\xfa\x94\xeb\x7b\xd5\x43\x87\xe8\x0d\x01\x32\x14\x74\x64\x80\xd4\xa4\x10\x82\xc8\x8a\xb3\x7d\xb0\x37\xb5\xbe\x03\x5f\xa8\x81\xfb\x90\x43\xab\x75\x50\x72\x6a\xc8\x9b\x4c\xb6\xc0\xba\x2a\x11\x9e\x17\xd3\x58\xd6\x9f\x55\x19\x6e\x2d\x85\x68\xc4\x4e\xc0\x1f\x98\x71\xf1\x02\xe6\xe6\xae\xf5\x5e\x65\xc0\xf5\x0a\x27\xae\x4a\x4b\x80\x21\x69\x98\x0d\x31\x01\x7e\x63\x0d\xad\x70\x88\x67\xa2\x4c\x18\x98\x57\x17\xf4\xe6\xfc\x54\x31\xf6\x7f\x72\x5f\x6b\x2e\xfd\xd6\x5a\xdb\xf4\xf3\x7f\xb4\xea\x22\xa6\x8c\x6e\x17\x7d\x0d\x34\x5f\x4d\x83\xec\x93\xce\x2a\x55\x2b\x6c\x2c\xdc\x1c\x68\xc6\xd2\xa1\xb2\xd0\xde\x5e\x45\x54\x9f\x3a\xf3\x53\x46\x5c\xf6\x1c\x2c\x5b\x65\x28\x9d\xf9\x5e\x7e\x2a\x7d\x00\xb0\xfa\xf2\x21\xd6\xad\x50\x29\xac\x2f\xff\x04\x1f\x7c\xb2\x95\xed\xff\x3c\x6f\x40\x32\x06\xcc\x10\x98\xb6\x42\x05\x2c\x9b\xdf\xcc\xf4\xba\x2a\xe7\xb3\x09\x64\xfd\x91\xb4\x82\x56\xf6\xa9\xa8\x29\xab\x20\xd6\xbf\x2c\x3c\x13\xe5\xde\x7b\x08\x16\xf3\x9f\x40\x66\x88\x08\x3b\xd0\x2b\x0e\xad\x1c\x63\x55\xd6\x52\xde\xc6\x7d\x99\xf5\x5f\xc0\x6d\xf6\xa0\x9f\x38\xec\xf0\x0e\x4e\x66\x62\xa5\x99\x89\x61\x26\xe9\x87\x70\xf6\xfc\x2e\x90\xa4\x24\xe9\x10\x64\x3e\xeb\xbd\xcd\xe5\xbc\xdc\x01\xa5\x2e\xa9\x74\x11\x8e\x38\x41\x29\x8c\xaf\x8e\x7b\x82\xd5\xf0\x04\x93\x01\x1f\x40\x6a\xca\xbb\x03\x81\x78\x0b\x02\x09\xd1\xb8\x50\xf5\xb2\x96\xf9\xc1\x79\x9c\xbd\x25\x7e\xd0\x6c\x93\x75\xa2\x53\xe0\x09\xa6\x47\xc2\x1d\x2d\xb4\xae\x0b\x4c\x64\x1f\xaa\x84\x08\xd3\xd9\xc4\xbc\x5e\x41\x77\x80\x95\x58\x13\xec\xba\xd4\x49\x23\xd2\xb5\x43\x3d\x2a\xbc\xc5\xec\xe5\x8d\x0d\xad\x8d\x70\x02\x00\xcc\xc4\x24\xa7\xef\x61\x03\x54\x6a\x43\xc0\x82\x75\x48\x15\x0b\x90\xe6\x78\x36\xc3\xb0\xe3\xd0\xca\x43\xff\x6e\xbf\x65\xf8\xd5\x04\xca\xec\xb5\x55\x70\xd8\x24\x24\xf4\xc6\xba\x53\x48\xcc\xf5\x93\xb4\xa1\xbd\x46\xbf\x8a\xe6\x71\xae\x52\x23\x7b\xc4\x2e\x83\xb2\x40\x7d\xea\x09\xed\xed\xde\x62\x67\x74\x55\xf2\xe7\x76\xb7\xa5\x83\x85\x82\xfa\xc5\xa0\x19\x24\xa2\x24\x22\xcd\xfc\xae\x86\x1a\x72\x57\x77\x61\x38\xc9\x31\xeb\xaa\x90\x66\x95\xa2\xdb\x5d\x1d\x56\xe1\x2b\x6d\xb6\x3f\x25\x11\x23\xec\x83\xf3\xec\x6e\x01\x34\x25\x81\xd0\x85\xd7\x17\x6a\x46\x12\x2c\x2b\x55\x4b\xb2\x5e\xa0\x85\xb6\x10\x4d\x59\x02\x4c\x89\x77\x9c\xdf\xcd\x9b\x60\x9a\xeb\xda\xe0\x9d\xf6\x3a\x35\xf4\xe6\x10\xf2\x67\x40\xca\x50\x0b\x07\x96\x21\x02\x6f\x86\x0e\xa3\xe3\x38\x2f\xfd\x3b\xb7\x61\x7e\x47\xc8\xd4\x52\x47\x6d\x85\xae\xbc\xa9\xdd\x55\x5e\x64\xe2\x22\x10\xa4\xaf\x54\x69\x8f\x76\xf0\x01\x14\xd4\xb2\x92\x30\xd4\x15\xd5\x1b\x3a\xdc\x93\xc6\x97\x06\x9e\x73\x0e\xf4\xe6\xa5\x2d\x35\x36\x25\x9e\x93\xbf\xa8\x9c\x25\x1c\xd1\xd4\x1e\x76\x45\xec\x0c\x0b\xbe\x47\x93\xee\xda\x3a\x54\x06\x23\x47\x91\x5d\x91\x29\x64\xb7\x5a\x5b\xe6\xe7\xbf\x52\x74\xe9\xe6\xf4\xbf\x5b\x9d\xea\x2c\x00\xea\x9a\x21\xa2\x4e\xd3\x34\x16\x9b\x51\x1d\xc4\x50\xe7\x47\xe0\xcd\x90\x84\x03\x44\x53\x67\x3b\x07\x6e\xaa\xfb\xe3\x78\xde\xcd\xcc\xfc\x75\x18\x12\xfa\xab\x6a\x11\x94\x84\x89\xfd\x1c\x05\x94\x14\xb6\xcf\x96\xcc\xa4\x74\xb0\xc6\xe6\xc3\x00\x6d\x73\x62\x28\x5d\xc6\x3f\x22\xe2\x62\xf9\x16\x3b\x1a\xbe\x27\xac\x04\xba\x6d\x60\xce\xf1\xee\xc3\x16\x73\x9a\x85\xde\xdc\xad\x05\xa9\xc2\x76\xee\x57\x40\x35\x85\x35\xec\x30\x8f\x87\x8d\x22\x35\xdf\xe2\xdb\x55\x0a\x6b\x8e\xfb\x26\xe6\x74\x7d\xac\x21\x76\x97\x57\x8a\xe8\xe5\x25\xce\xf1\x37\x71\x39\x33\x3f\xd3\x61\x60\x15\xea\x71\x54\x10\xb4\x89\x1e\x7f\x44\xda\x3b\x48\x38\x08\x84\xf9\x22\x22\x97\xda\xaf\x9d\xdb\xab\x79\x60\x83\xcb\xac\xc0\x4d\x0c\xe4\xc6\x76\x37\x5b\xb7\x8b\x34\x53\x0b\x94\x0c\x73\x8d\x38\xc2\x59\xd1\x16\x85\x0c\xdc\x42\xac\x28\x85\x03\xd3\xd6\x36\x5e\x01\xa6\x62\xa4\x23\x42\xf8\xe9\xa5\x88\x97\x31\xd9\xf3\xe4\xa8\xc4\xb7\x46\x30\x68\xce\xd8\xe8\xa7\x6b\xd2\x5c\xd4\x22\xbd\x4b\xf0\xea\x14\xf1\x1e\xad\xe2\x5b\x60\x4d\x24\xee\x81\x2c\xf3\x0f\xe4\x72\xba\xa9\x16\xb5\xdb\xdc\x8b\xe7\xd6\xda\xde\xbb\x99\x1f\x87\x73\x96\xc8\x54\x83\xb2\x4d\xa9\xb4\x9d\x0e\x01\x49\x6e\xc7\xe9\xeb\x03\x95\x36\x41\xd2\x93\x35\xdc\xbe\xd3\x26\x25\x33\xf7\x5c\x74\x79\x4d\x78\x74\xa8\x0a\x65\xa1\x10\x51\x0e\xf4\xb4\xe1\x2e\x01\x9a\xa1\xde\x63\x01\x9f\x50\x5c\x0a\xe6\x09\xac\xeb\xf0\xdf\xbd\xf6\x52\xe4\x40\xc4\xda\x68\x5a\xa6\x9b\x10\xd8\xa9\xd2\xf7\x0e\xf3\x5f\x19\x07\x83\xe4\xed\x17\x67\xf8\xa2\x3f\xa1\x0b\xe7\xeb\x3a\xcf\xfd\x26\x60\x71\x7f\x20\xfe\xe6\xfd\xd4\x07\x25\x6c\xc1\x35\x67\xa7\x8b\x7c\x98\xca\xff\xa8\xaf\xf9\x40\xea\xce\x97\x2c\xcc\x7f\x92\x70\x3b\x1f\x89\xca\x7f\xec\x3f\x78\x23\xf5\x2e\x8e\x48\x82\xdc\x20\x0e\xf0\xde\x83\xf9\xf3\xce\xcc\xab\xbd\x73\x90\x2a\xdf\x6e\xe5\xfb\x43\xe3\xb9\x9b\xdf\x35\x89\x80\xb7\x0d\xf5\xa8\x2d\xe7\x75\x0b\xfc\xae\x97\x9c\xbb\x90\xf2\xf8\x23\x10\xf7\xe0\x74\xc3\xa2\x14\xa0\x4f\x98\x5b\xec\x1e\xfd\xee\x89\xab\x7e\x7b\x4e\xb2\x80\xf4\x0c\x33\x39\x07\x84\xd3\xad\xee\x7a\x85\x40\x9c\xca\x7b\x2f\x17\x6d\x87\x7a\x1a\x37\xdd\xa3\xf9\x46\x39\x40\x8f\xf4\xcb\x7a\x42\x51\x21\x2d\x8c\xa6\xf1\xd5\xb8\xe6\x2f\x2a\x9d\xbd\xe6\x24\x91\xb7\x69\xbe\xf9\xb6\x22\x02\x74\x5f\xf2\x73\x02\x4c\xbd\x90\x97\x52\xbe\xfe\xd5\x08\xbe\x2f\x8d\xb1\x5f\x4a\x7b\x41\x85\x8e\x9f\xd7\xc0\x8c\x36\x7d\x3a\x1b\x0f\xf8\xb0\xf1\x85\xd6\x20\x30\xa8\x43\x73\x6c\x78\xb9\x7b\x10\x82\xf4\xd6\x63\x6f\xd1\x1f\x11\x3a\x18\xae\x27\x8f\xee\x4f\x04\xfa\x81\xcd\xfd\xd9\x23\xf6\x6e\x2f\x10\x82\x88\x65\x8d\x39\xfd\x4b\x22\x74\x40\x52\x3c\xcb\xa8\xff\xb6\x7e\x6f\x58\x9a\xf8\x35\xf2\x55\xda\x63\x18\x38\xc8\x79\x92\xf7\xf9\x04\x8e\x97\x50\x56\xbe\xa5\xcf\x22\xc6\xdf\x73\x3e\x47\x0a\xe1\x09\x89\x8a\xdc\x0b\x47\x3b\xae\x93\x17\xa6\xa8\xfe\x41\x82\xac\x40\xb6\x72\x1d\x1c\x7c\xde\x8c\x22\x95\xfa\x04\x75\xca\xbf\xf5\xc2\x01\xad\x42\x41\x99\xf5\x3e\xd9\x02\x01\xb2\x01\xd5\xf7\xc4\x02\x63\xee\x2a\x38\x06\x82\x76\xb8\x35\xfd\xc7\xc7\xfd\x99\x7d\x26\x2c\x78\xac\x27\x8b\x9f\xc8\x3e\x64\x06\x2f\x01\x68\x77\x0d\x00\x9f\x42\xe6\x26\xb8\x44\x14\xd6\xe7\xdc\x85\x54\x5a\x79\x2e\xf7\x12\x36\x80\x4a\x0a\x84\x9e\x1e\x1d\x52\xf9\xe9\x28\x79\x6d\x1f\x60\x86\xc1\xdd\x5d\x61\xcf\x2f\x61\x0d\x05\xa7\x6a\x4b\x57\xf0\xa8\x67\x62\x5f\x54\x0f\xe9\x0d\xd4\x63\x78\xfb\xfd\xad\x1c\x5c\x55\x40\xe2\xbd\xd0\xe3\xf5\x2b\xee\xde\x8c\x2f\x11\x69\x3e\x5f\xd7\x37\xf3\x27\x64\x56\xee\x8c\x92\x50\xba\x0b\x91\xb8\xa7\xfd\x9d\x0a\x77\xb9\x62\x23\x94\x5c\x9e\x0d\xe9\x59\xae\xbf\x61\xb6\x2e\x69\xe0\x1b\x27\xc9\x7d\xfe\x82\x7a\x61\xbe\x1d\x46\x86\xc5\xe1\xa2\x67\xbd\x62\xf7\x33\x28\x3d\xb0\x31\xd4\xd8\x1b\x76\x2c\xfe\xff\xdc\x7b\x39\xe0\xb9\x59\x80\x39\x8b\x06\x36\xbd\x16\x91\xc2\x6a\x77\xf0\xad\xe9\xb5\x85\x8e\xf8\x2d\x74\x68\xbe\x0b\xc5\x23\x6c\x69\x53\x7f\x97\xbc\xe2\x27\x9f\xe0\x5a\xbb\xaf\x22\x2e\x7a\x00\x01\x77\xe5\xa6\x72\xcf\x67\x28\x03\x86\xaa\xdf\xcc\x57\xda\x2e\xb3\x75\x0b\x81\x69\xd5\x35\xbf\xe7\xa1\x4b\x02\xd0\xbe\x00\x65\xf5\xa3\x4e\xca\x61\xb8\x65\x62\xd8\xcd\x3b\xfe\x56\x9b\x96\x53\xd3\x2b\x94\x72\x1b\x18\x77\xce\x4d\x66\x50\x3a\x66\x9a\x1f\x41\x2f\x87\xf9\x77\x9b\x1c\x3d\xd8\x3b\xdc\xe9\xdd\x11\x11\x78\x27\xa5\x94\x6e\xc1\xee\x6f\x75\x0c\x8e\x95\x97\xcb\xea\x6d\x2f\x32\xe5\x0d\x53\xc7\xf9\x8f\x05\xb4\xe6\xbe\x3e\x79\x21\x7f\xee\xfa\xa4\x2f\xf4\xc5\x05\x08\xb1\x44\xfb\xaa\x46\x95\x40\xdc\x47\xfa\x23\x40\x28\xa8\x2e\x56\xdd\xc4\xda\x22\x01\x46\x04\x69\xd5\x83\xee\xf1\xf6\x0d\x39\x5e\x83\xee\xe0\x2c\xd9\xc1\x2e\x94\xca\xdc\x86\x51\x01\xc5\x81\xdd\x80\x31\x0b\x61\x7b\xbe\x03\x12\x6c\x8f\x90\xbe\x86\x02\x9a\x02\xa6\x6a\x91\xe4\x0a\xe3\x45\x28\x9f\x35\x9f\xc5\x33\x4d\x02\xd9\xb6\x87\xce\xc2\xb2\x5c\x61\x19\x88\x11\x53\x7b\x61\xec\xd3\x22\xb0\x6f\xd0\x28\x6c\x94\x1e\xf8\x4d\x3c\x0e\xbe\x04\xe3\x9a\x28\x43\xf7\xb4\xe4\x66\xa0\x81\xef\x47\x99\x56\x7d\xd2\x7c\xc7\x3b\x10\x9d\x42\xe3\x09\x59\xf8\x78\x84\xc4\x61\x0e\xd9\xc5\x66\x0c\x6f\x63\x73\x41\x1f\xed\x7e\x22\x53\xfe\x56\x9c\xc2\xe8\xd2\x15\x12\xb5\x76\xd4\x44\x51\xe8\x60\xdd\xca\xff\xea\xdc\xb9\xe7\xe1\x71\xd6\x10\x80\x74\x7d\xc4\xcc\x28\x4f\x11\x08\x29\x7c\x36\x1b\xca\xa3\x08\xcb\x71\x1d\x73\xe0\x45\xed\xea\x09\xd1\x7b\x68\xab\x02\x48\x2d\xaa\x3d\x7e\x9b\xda\xe5\xda\xcb\xeb\x0b\xff\xdd\x13\x6f\xec\xf6\x26\xc1\xc8\x02\x7e\xb1\xa6\x37\x07\x67\x2e\x6e\x18\x11\xbb\x19\x1b\x67\x3c\x67\x41\x7d\xb3\xae\xf3\x6f\x91\x72\x95\x45\x44\x25\x5d\xb6\x89\x0d\x21\x89\xee\x05\xbb\xe7\x0e\x14\x2f\x81\xc8\xc0\xea\xec\x29\xc0\xb8\xb5\xe9\xbb\x5d\x13\x25\x06\x30\x3b\x10\xca\x73\x9a\xb7\xd4\xd5\x45\x52\x80\x93\x4d\x5c\x08\xdc\x75\xd5\xe7\x9b\xa1\x80\xf8\x00\xe7\x4a\xdb\x70\xd0\xb0\xc9\x71\xba\xfc\x2e\xd5\x8e\x4b\xe4\x24\x78\xb0\x40\xe9\x01\xb3\x3b\xf0\xb0\x69\xd2\x25\x07\x60\x57\x8f\x24\x18\xfe\x36\xac\x70\x5c\xa7\xaa\x0c\x97\x2a\xa4\x97\xb4\xaa\xae\x3c\x7f\x4d\x65\xe9\x89\xe9\xc1\xc4\x05\xd1\xe2\x79\x0c\xa0\xaf\x83\x6b\xf9\x7f\xfa\x79\x63\x95\x9b\x48\xda\x10\x49\x84\x6a\xae\xc0\xad\x2f\x92\x92\xe5\x94\x99\x19\xd6\xaf\x3d\x25\x00\x98\x5a\x7b\x26\x21\x63\xf1\x44\xec\x0a\x65\x44\xda\x83\x66\xd0\x76\x0a\xdd\x4b\x57\x69\x14\x7c\x77\x4b\x4d\x97\xd1\x21\xb7\x0a\xe3\x98\x71\x8f\x00\xf8\x13\x2e\x78\x52\x93\x80\x87\xb3\x0b\xcd\x52\xd8\x67\x86\xac\x35\x3f\x04\x12\xf7\x3c\x42\x9e\x11\xb9\x37\x5f\x09\xc4\x81\xbe\x4f\x47\x51\x9e\xf3\xfa\x56\x8a\x2e\x0a\x43\xcf\x0a\x13\xc5\x7d\xaf\xb4\x7e\xa2\x15\x49\x01\x95\xc7\xb0\x5e\xf0\xef\x06\xbb\x4e\xbd\x48\xb9\x30\xac\x77\x40\x26\x20\x69\x04\x60\x56\xd1\x8a\x4f\xef\x1a\xf9\x25\xd0\x95\x04\xc8\xe2\x75\xfd\x71\x80\x6c\xde\x08\x67\xfd\x47\x88\x29\x58\x55\x44\xe0\x96\x7a\x52\x96\x51\x43\x30\x6b\xdb\x2a\xa5\x77\x91\x22\x39\x37\xbe\x14\x8e\x9f\xe5\xf6\xda\xbc\x50\x02\x51\xae\x65\x67\x11\x12\x36\x50\x01\x27\x9b\x29\x48\xed\x6a\xc3\xe0\x5d\x38\x15\x56\xcb\x3d\xbc\x32\x69\x64\x39\x93\x2a\x79\xce\xcc\xf6\x9d\xf3\x78\x71\x8a\x74\xba\x1b\xa5\x9f\xf9\x1c\xda\xbd\xa7\x6c\x0e\x4e\x70\x4c\x03\x97\xe2\x98\xd9\x4a\x58\xec\x5b\xdd\xe1\x99\x5f\x33\xe1\xae\x4e\x6c\xda\xb9\xae\x86\x63\x27\x75\xed\x4e\xe9\xaa\xb9\xee\x70\x78\x73\x4a\x01\xde\xbd\x39\x39\x69\x73\x3c\x6d\xfb\x5f\xd3\x49\xe5\xca\xb0\x0d\xb3\x06\x2e\x0b\x3b\x0d\x47\x2b\x62\x67\x2b\xcf\x92\xb9\x0e\x20\x01\xe8\x07\x71\xa6\xab\x63\x53\x7b\xda\x33\xc3\xdf\x2d\x2a\xfb\x99\xe4\x47\xe2\x12\x91\x52\x92\xec\x39\x3c\x07\xc2\x23\xeb\x88\xf1\xfb\x52\x77\xca\xf4\xb3\x2b\x7e\x37\x6c\x44\x7a\x69\xec\xee\x16\x7c\xb7\xb2\xd1\x07\x64\xcb\x82\x7d\x84\x56\x5b\x58\x5a\xc9\x76\x1d\x70\xa9\x8c\x48\xad\xed\x81\xfa\x6d\xe2\xff\xb6\xb8\x13\xfb\xf6\x40\xd6\x5b\xea\x91\xa7\x84\x96\x1c\x46\x2b\xa0\xec\x51\x7a\xe2\x69\x37\x8e\xc0\x2d\x10\xbe\x36\x1c\x3c\x57\x50\x07\x9e\x3c\xc2\x3a\x0b\xbb\x7f\xd8\x3c\x2f\x51\x52\x71\x7d\x6f\x2c\xca\x5a\xf3\x26\x67\x18\x8b\xa8\xad\xe8\x72\xb5\x08\xe4\xfb\x0c\xd7\xcf\x49\xc2\x94\xbd\x34\x28\x9b\x28\x88\x85\xc9\x8b\x96\xee\xe3\xa9\xf6\xd6\xba\x98\x8e\x3a\x98\x0f\x3e\xa8\x47\x8e\x5f\x91\x39\xde\xb1\x65\x48\x3a\x5a\xd3\x39\x13\x17\x0b\x90\xa3\xa2\x06\xac\x5d\x22\xb0\x06\xd3\xcf\x32\xef\x49\xfb\xad\xb2\xdf\xf4\xe9\xde\x2c\x4c\x2e\xba\x65\xee\x01\x87\x57\x69\x5e\x66\x25\xb8\x8f\xac\x1f\x9d\xde\xa1\xce\x99\xfe\x6d\x42\xd3\xbe\xd6\xf9\x8b\x21\xa6\x98\xde\x91\x08\x58\xb2\x25\xb3\xe8\x16\x78\xf7\x71\x68\x06\x6a\xcb\x44\xa4\xae\xf5\xd7\xd4\xaa\xbc\x04\x4e\x46\x45\x85\xf7\xd5\x7a\x77\xa1\x78\xcf\x90\x96\x38\x84\x30\x3d\x84\x1d\x3b\x12\x48\x4b\x97\x54\x2f\x0b\xcb\xc0\xc8\x20\x6f\x59\x5e\xa1\x91\x61\x39\x92\x73\xcf\xa0\x3e\xfa\x9c\x59\xbb\x6b\x5e\x6e\xc5\x7b\x42\x04\xe7\xbd\xd2\x89\xa9\x9c\x74\x74\x2b\x9a\x0e\xd8\xc4\xd6\x1e\x19\x3a\x84\xb2\x85\x2e\x13\x69\x39\x25\xae\x5c\x71\xf6\x54\xd0\xc4\x00\xe2\x95\x30\x5d\x19\x38\xb4\x2d\x43\x56\x46\x44\x0e\x64\x05\xf9\xed\x5d\x91\x04\xd7\x5c\xc3\x8f\x80\xde\x97\x26\xde\x16\x0d\x12\xd0\x7c\xea\x2d\xd9\x09\xb8\xde\xed\x34\x55\xe5\x84\xa6\xa6\xbc\xb4\xf6\x28\x6d\xec\x65\x0d\xf4\xef\xf5\xc7\x88\x74\x11\xaf\x74\xb7\x6e\x72\xa2\x62\x2f\x42\x55\xc8\xf7\x5c\xc1\x3d\xa5\xbc\x66\x8d\x19\xfb\x9e\x39\x03\xa4\xfa\xa1\xaf\x49\x73\xe8\x6d\x8e\x69\x93\x5c\x63\xa8\xa1\x6f\x15\xa3\xf8\x3b\xa0\xbe\x83\xa6\x68\xd6\x6c\x53\xf7\xaf\x4e\x6b\xa7\xe9\x85\xbd\x8a\x7f\x84\x0d\x36\xa8\x70\xf9\xd2\xad\x68\x36\xb4\x01\x44\xf7\xda\xe4\x8f\x15\x0b\xff\x64\xef\xbb\x70\xf6\x1e\xff\x10\xeb\xab\x65\xbe\x78\x28\xd9\x1f\x6d\xc5\x5e\x73\x1e\xcd\x66\xcf\xe5\xad\x88\x45\x09\x44\x72\xe1\x72\x13\x54\x8d\x29\x01\xf5\xd5\xb5\xde\x9c\xe3\x25\x70\xf0\x1a\x83\x77\x0b\x07\xdd\xdf\xad\x4c\xfc\x55\xf2\xe4\xf3\xaf\xe7\x6b\x22\x70\xd3\xc1\x53\x81\x87\x70\x74\x70\x12\x74\x18\xcf\xeb\xcc\xc8\xae\x7f\x43\xd1\xc2\xcb\x97\xca\x99\x5e\x3b\xd3\xe3\x60\x1f\xac\x07\xf0\xa0\x09\x61\xe2\xde\x04\xf2\x57\x6a\x09\x5b\xf3\x31\xcd\xca\xa9\x83\xff\xf5\xa2\x58\x97\x7f\xda\xaf\xd8\x65\xbf\x12\xa1\xc4\x3b\x71\xd6\x70\xf6\xe8\x84\xc9\xb6\x46\x82\xef\xe3\x16\xb2\x78\xa8\xfa\xf0\x8a\x79\x11\x9f\xff\x6c\x3a\x55\x2f\xdf\xf2\xa0\x2f\x81\xb9\xf1\xff\xd4\xdf\x32\x78\xdc\x7a\x1b\x4f\x9f\xfe\xfa\x59\x38\x35\x47\xd6\xf2\xda\x15\x85\xb5\x39\x84\x3f\xcf\xc0\x0f\x2f\x73\x8b\xf2\x77\xed\x58\xdf\x01\x3b\x4e\x01\x8f\xb6\x70\x78\x0b\x69\x4c\xa3\xa1\x08\xf9\xec\xf4\x7d\x0d\xc1\x4c\xa0\x92\x43\x3a\x14\x56\x3e\x82\x2a\xaf\x55\x72\xa3\x3d\xdf\x47\xc2\x94\x53\x44\xc3\x1a\xc2\xa4\x69\x2d\xc2\xf7\xbe\x75\x1b\x95\xec\xdb\x92\x0e\x61\x3d\xaa\xd4\x3d\xaf\x2a\x2b\x62\x8b\x25\x8a\x8a\xdb\x40\x69\xcb\x3b\xcb\x11\xf5\x2a\x61\xa6\x7a\x7d\xf1\xcd\x35\x44\x35\x4f\x82\x88\xcf\xab\xac\x59\xe0\x64\x58\xd9\xca\xa9\xd5\xa1\x18\x82\x2a\x07\x84\x64\x83\xe9\x52\x18\xbc\x42\xf2\x93\x67\xc0\x4a\x22\xa4\x3c\x4f\xe9\x76\xee\x63\x60\x9b\x99\x1d\x03\x7c\x59\x50\x76\xe4\x91\xe2\x6e\x43\x13\x90\xbf\x78\x0d\x4c\xf2\xda\xfe\xeb\x2a\xa0\xe6\x96\x7e\x97\x2a\x65\x4f\xe1\xaa\xbd\x35\xf4\xa8\xb7\x59\xe3\xcc\xff\xc0\x37\x35\xf5\xd6\x9c\xe8\xea\xc1\x40\x88\xd8\x65\x71\x41\x57\x6a\x41\xad\x55\x3a\x72\x2b\xd2\x41\x04\x31\x03\xef\x75\x32\xb4\xa1\x48\xc7\x43\x40\xfe\x93\x57\x6b\x85\x66\x88\xa4\x40\xa1\x5b\xe8\xbd\xf2\x2a\xee\xd5\x2a\x42\xcb\x5a\xdc\xe3\x9b\xdb\xef\x41\xaf\x76\x08\x73\x94\x00\xd7\x32\xc9\xf1\xb5\x8c\x4c\x26\x5b\x10\xa9\x8b\xb5\xa8\xd6\xb8\x16\x59\xf1\xd9\x9b\xe2\xfe\xba\x08\x81\x9c\x1c\x09\x6f\xfe\xce\x59\x20\xa4\xc5\x75\xca\x23\xa2\x5d\xe7\x3d\x84\xcc\x4e\x38\xae\xda\x68\x6e\x42\x7b\xee\x31\x7f\x1a\x21\xa5\xab\xb3\x2e\x6e\x1d\xab\x6b\x0a\xa2\xc0\xc6\x04\xc4\x19\x89\xb6\xa6\x56\x6a\xad\x8d\x30\xbb\x6b\x70\x66\x2c\x18\x40\x0c\x64\x48\xd7\xda\xb0\xf9\xf2\xc0\xff\x91\xbd\xcf\x8b\x82\x7d\xa2\x39\xe9\xca\x09\x16\x94\x2c\xf9\x8d\x0c\x68\x07\xae\xd5\x7f\xe9\x56\xb2\xbe\x6c\x28\x34\x09\x0a\xfd\xf9\xb0\xe0\xb0\xa6\x57\xc0\x0e\x56\x8c\x15\x08\x69\x7e\x05\xee\xd0\x42\x5e\x6b\x9b\xb7\x8c\x7b\xa0\xa9\x25\x5f\x5a\xe5\x00\xe3\xbe\xb5\x0a\xe2\x3e\xd8\xfb\x35\x71\x73\x90\x34\xd4\x2a\xe3\x83\x0e\x22\xa4\x99\x3d\xc5\x0b\x57\x08\xc4\x62\x41\x53\x31\xd5\xaf\x05\x52\x43\x27\x78\xc4\x3f\x74\x2d\x21\xfe\xa3\x6d\xd3\x91\x36\x6d\xbe\x81\x4a\x40\x50\x37\x44\x6b\xeb\xd5\x42\xed\xdc\xe7\xa6\xc0\xda\x71\x32\xb8\xa6\x44\x4f\xd9\x7a\x0b\x4c\x2d\x3c\x31\xcb\x26\x4b\x25\x7a\x67\x39\x21\xfa\x24\xab\xda\xda\x04\xea\x16\xf0\xea\xf8\x7d\xfe\x82\xaa\xf7\x08\xc2\xb8\x15\x7d\x24\xdd\x67\xa9\xf4\xbb\x14\x60\x3a\xfd\xf8\x28\xff\x30\x58\x65\x61\xb2\xa8\x45\x59\x8a\x4c\x85\x97\x12\xfa\x2f\x88\x2e\x09\xa6\x42\x1a\xcb\x37\xdb\x39\xb5\x5a\x6c\x04\x40\xf8\xb4\xf5\xfb\x34\xd0\xb5\x91\x03\x16\x6b\x65\x4b\xb8\x48\xfd\x7c\x11\x8e\x76\x59\x93\x4f\xd5\xe1\x53\x3b\x92\x6d\xe3\xe2\xa7\x42\x51\x37\x2f\x81\x25\x64\x01\x10\x34\xaf\x58\x8b\xe5\xe7\xb8\xb8\xf9\x82\xff\xc7\x79\x1d\x89\x95\xb0\xa8\x2f\x6f\xb9\xde\x46\xd7\x67\x91\x4f\xfb\x16\xd7\xba\x50\x0f\x09\x77\xda\xeb\x96\x3d\x2d\x80\x9b\xf2\x94\xcd\x7e\x7c\x02\xc3\xf3\x1f\x8b\xda\x75\xf8\x4a\xac\xce\x61\x70\xfb\x48\xf1\x1b\x13\x38\xfa\x2d\xdf\xb3\x10\x49\xbd\xa4\x4b\x0b\x61\xd5\x53\x5c\x75\x9b\x48\x07\x8a\x3e\xcd\x21\xd0\x3a\xbf\x66\x2e\x77\x47\x6b\xd7\xb3\x27\x07\xfe\xb7\xda\x0f\x8e\x49\xfa\x6f\x05\x67\x08\x01\x78\x7c\xcc\x8b\x43\x80\x75\xa0\x16\xe6\x2f\x7a\xb3\x3d\x14\x58\x11\x37\xb9\xd6\xc7\xe3\x9c\xc3\xf0\xd6\x7f\xf7\xaf\xaa\x12\xbf\x48\xb4\xf0\xfe\xfe\x42\x34\x77\xe7\x97\x52\x87\xfb\xf5\x69\x41\x80\xc5\x31\xdf\xf2\xf4\xcd\x6f\xaa\x7e\x91\x7e\x13\x38\x19\xbe\xaf\x3d\x80\xcc\x52\xff\x72\x9c\x35\xbf\xd2\x95\xc2\x2b\x57\x8a\xae\x17\xe7\x4d\xf3\xce\x7b\x38\xef\xac\x2e\xdb\xcc\x88\x7d\x37\xd0\xd2\x0f\x30\x99\x10\x67\x8e\x87\x20\x05\xc9\x25\xc8\xd1\xd4\x4d\x9c\xde\xab\x8c\xf6\xa7\xfa\x4f\x65\xa6\x29\xd4\x57\xeb\x86\xdc\xdc\x9b\x98\xf3\x48\x8f\x4c\x04\x17\x4f\x6e\x04\x33\x68\xc3\x15\xe0\x0f\x8f\xfa\xc5\x5e\x4d\xa2\xc4\x5f\x59\xd2\xae\x3e\x11\x97\xbf\xee\x53\x18\xf0\xda\x90\xe3\xf5\x14\x62\x72\x2a\x97\x70\xe9\xc7\x28\xd4\x73\xd9\x04\x8c\x75\x18\x79\xa0\xce\xed\x25\x5a\xe9\xaf\x5b\x16\xca\x4b\x63\xb4\x74\xa4\xea\x59\xed\xa9\x44\x16\x0c\x6a\xb0\xf1\x16\x30\x0e\xe3\x13\x7c\x12\x47\x6f\xb2\x1b\xe3\xae\xb6\x40\x78\xb9\x02\xeb\x1c\x9e\x6c\x53\x53\x9e\x46\xb4\xea\xdf\xcf\x7b\x48\xc6\x76\xce\x85\x9e\xbc\xbf\xf0\xe0\xfc\x04\x6a\xfc\xbc\x3f\x71\x7c\x17\x79\x6f\xa7\x01\xa0\x51\x62\xf0\x47\xe3\x75\x3f\xa5\x05\xbb\x07\xd6\x1c\xd4\x1f\x0f\x34\x4c\x80\x14\xcd\xc2\x6d\xd6\x31\x9e\x23\xa0\xd3\xaf\x22\x37\x5f\x1b\xd5\xfa\x72\x54\x1e\x03\x0a\xb3\xda\x75\x94\xc4\xec\xc3\xbb\x6a\x97\x98\xed\x43\x40\xf6\xbd\x86\x97\x6f\x0d\xa1\x5c\x6b\x89\x42\x4b\xf6\xa6\x58\x0f\xbc\x7f\x67\x7a\xfc\xba\x7e\xd4\xa5\xd0\x25\xf6\xa7\x90\x4d\x07\xd6\xbd\x84\xcc\xec\x76\x85\xbc\xac\xde\x50\xc8\xca\x6a\xd5\x57\xb9\x71\x8a\x61\x10\xcc\x44\x43\x04\x0e\x23\xf9\x98\x7f\xb9\xa2\xec\xc5\x89\x1e\xe2\x51\x00\xe4\x1a\x93\x4c\x80\xdf\x1d\xfa\x5c\x5d\x57\x33\xd3\x2c\xf8\x2b\xfd\x0c\x48\xfc\xa3\xbc\x03\xb0\x5e\x57\x87\x4c\x9f\xf3\x25\x24\x35\x52\x4c\x3a\x43\x1b\xc2\xbd\xb8\x59\xa0\xd3\xe5\xa1\xef\x08\x73\x45\xa7\x44\x8e\x46\xf2\xa6\xec\x49\x95\x46\xab\xe3\xca\x1d\x16\x60\x21\x07\xd3\x6e\x16\xcc\x60\x3d\x26\x6d\xa6\x31\xf9\x58\x1a\x0c\xdc\xc1\x1b\x8a\xfc\xab\x55\x4c\xd9\x71\x3e\x87\xaf\x83\xb0\xab\x5d\x78\x90\xa4\x05\x8b\xb1\xe4\x41\x1c\x36\x66\x37\xcd\x56\x78\x10\x38\xdd\x3a\xfe\xde\x83\x66\x24\xdc\x75\xb3\xf6\xc5\x4c\x7f\x17\x58\x7d\xa3\x55\x07\x3e\xe4\x5b\x2f\xe6\xf8\x47\x4f\x14\x31\x99\xb3\x23\x2a\x30\x82\xaa\xc3\xbd\xd1\xab\x72\x0c\x3d\x00\x5a\x25\xf6\x57\x5b\x05\xbc\xb9\x5f\xcd\x24\x03\x59\x97\x7c\xd5\x57\x42\x08\x20\x48\x9c\xe2\x5a\x98\x89\x47\xb7\xd3\xf3\x7f\xce\x6e\x0e\xb8\x71\x59\xf2\x86\xfd\xe5\xa3\x36\xd1\xd0\xc7\xd9\x54\x55\xcf\x79\x26\x3c\x7c\xce\xc3\x4a\xf0\xb7\xcb\xba\xb6\x5e\xc5\x3e\x0b\x84\xf8\x38\x13\x47\x19\xc8\xbd\xfa\xd2\x6e\x34\x91\xe7\x01\x9d\x7a\x14\xe8\x89\x31\xc2\x34\xd6\x83\x55\xc3\x90\x47\x89\xd2\xfe\xa3\xb0\xfc\xfd\x50\x9f\xe0\x3e\xc5\xc4\x8c\x0b\x80\xbd\x66\xd9\x2b\xc3\xba\xd8\xbb\x31\xa8\xbe\x8a\x4f\xff\x10\xdc\xe2\x31\x9f\x34\x42\x7a\x40\x4a\x4d\x0d\xde\x63\xde\x1f\xf2\xd8\x79\x60\x5c\xcb\x76\xe5\x31\xb7\xc3\x38\x79\xd8\xd7\xb9\x44\x78\x03\x8a\xef\x89\xd9\xc9\x47\x30\x09\x1e\x36\x82\xd5\x3b\xf6\x80\xa2\x1c\x45\x62\x9f\x74\x54\x46\x2e\xc1\x77\xb4\x6b\x42\xd3\x65\x9f\x43\xfd\x48\x3f\x96\x5f\xb5\x25\x9f\x9d\x07\xb0\x30\xef\x1f\xe1\xca\x83\xf6\x6c\x1f\x62\x65\x40\xda\x13\xfb\x82\x07\x6c\x88\x42\x51\xd6\xe7\x0f\xf9\x5a\x08\x73\xce\x51\xd8\xcd\xf4\x22\xca\xa7\x8f\xcc\x90\x71\x3b\x7d\x49\x14\xea\x17\xf0\x96\xb7\x47\x3c\x9f\x79\x53\xf5\x0d\xee\x6d\x92\xfe\x41\xcb\x5d\x09\x0d\xc8\xab\x3c\x0e\xa0\x22\x90\x62\x9f\x15\x43\x70\xef\x66\x90\x5c\x6a\x87\x62\x5b\x89\x6b\x2b\x5b\xe5\x41\xd2\xe6\x39\xfc\x04\x81\xe1\xf6\xff\x60\xc3\x12\x99\xa6\x0e\x35\xe0\xd4\xf0\x9e\xd7\x2a\xbf\xac\x43\xdd\x57\x26\xef\x1c\xab\xce\x55\xe1\xc8\x39\xd4\x31\xfc\x92\x65\x67\x6a\x11\x21\xd1\x57\xa9\xde\xc3\x0f\x27\x79\x8e\xc3\x29\x96\xe3\x50\xaa\x8c\x8f\x85\x15\x1a\x90\x88\xd5\x92\x1b\x48\x82\x77\x28\x2b\xc7\xea\x83\x3d\x3c\x82\x78\x37\xe2\xfa\x00\xdd\x2b\x07\xd5\xe3\xc7\x73\x38\x05\xfc\xf8\xd9\x11\xb5\x0d\xc3\x38\x02\xc8\x5f\x84\xae\xe7\x60\xd8\x0d\xe0\xa3\x8f\xd4\x89\x85\x50\xb0\x12\x73\x03\xa4\x82\x7d\x79\x07\x9c\xfc\xe2\x36\xe7\xb7\xa7\xb3\x0f\xc5\xc9\x94\x8c\xb9\xea\x28\x01\x32\xdf\x6d\x3e\xa8\xff\xf6\x15\xa5\x15\x0c\xc3\xf1\xe6\xef\x08\xe4\x14\x9d\xd7\xda\xeb\x4c\x56\x0a\xcf\x66\xa8\xef\x34\x54\x3a\x65\x54\x10\x68\x05\x94\x82\x3d\x9a\x27\x9e\xec\x14\x62\xbc\xae\x23\xcb\x68\x62\x0b\xef\x36\xcd\x95\xdf\x76\x76\x1b\xf8\xad\x14\x7c\x86\xf0\xce\x1c\x32\xf9\xcb\x43\x92\xc5\x34\x06\x72\xe1\x0f\x34\x00\x6b\x4b\xdf\xc0\x21\x85\xb6\xae\xc8\x09\x69\x0a\x67\xe6\x89\xbe\xfa\x43\x92\x6b\xe0\xe0\x34\x64\xc7\x02\xd7\x5b\xaf\x4b\x5f\x65\xb9\x85\x9c\x8b\x80\xc6\x5e\x26\xbf\x18\x91\xbc\xd5\xd7\x50\x33\xeb\x21\x8f\x76\x31\x5b\x0d\xd7\x15\xbe\x00\x16\x59\xef\x8b\x33\xeb\x4f\x72\xc2\x9d\x4d\x1e\x6a\xbc\xc7\x25\x08\x7c\x91\x56\x2c\x0a\x03\xcc\x59\x3b\x02\x5e\xc6\x75\x88\x13\xd4\xb5\x1d\x24\x7c\x72\x26\x0b\x3c\xfc\x20\xc8\xf8\xb3\xe9\xe6\x3e\x85\x39\x3f\x29\x5c\x0b\x2c\x05\xad\x95\xed\xa8\xfa\x15\xd0\x54\x52\x74\x04\xe6\xfc\xd0\xb8\xab\x47\x16\x91\x10\x6c\xb7\xfc\x21\xde\x19\x9c\x7d\x12\xad\xa0\xd1\xcb\x69\x53\x5f\x36\x15\x92\x01\x66\x97\xad\x5d\x2f\x49\x88\xbe\x4c\xa1\x05\x6c\x23\x2b\xc1\xc1\xcb\x1f\x04\x3d\x19\x03\xf6\x9a\x48\x31\xbb\x27\xf1\x1b\x92\xbe\xc4\x2b\x22\x81\xc6\x84\x3f\x45\x7a\x19\x58\xf7\x2c\x15\x60\xe1\xfe\xe7\x9b\x0d\xa4\x05\x81\x64\xb7\x6e\x48\x17\x03\x45\x8a\x2f\x8a\x7c\x3a\x21\xc0\xfa\xfa\xeb\x44\x1d\xc2\xbd\x8d\x6c\x10\xae\x75\x54\xf5\x3d\x19\xd9\xdc\x81\x5f\x4a\x88\x1b\xc1\xdc\xc7\xaa\x59\x68\xf9\x3c\xf3\x86\xdb\x60\x6e\xd2\x2a\x7b\x16\x25\xc5\x2b\xbb\xfb\x1e\x7a\x4c\x84\xbf\xaf\x6b\x20\xdd\x91\x82\xe0\x46\xbf\x04\xc9\xa7\x67\x43\x04\xf4\x98\xa3\xea\xce\x40\x17\x58\x72\xc4\x48\xd3\x48\x82\xd7\x63\x37\x2d\xe6\x87\x4b\xf6\x04\x3d\x6c\x32\xb2\x20\xec\x72\x8b\x81\x14\x21\xf7\x77\x6e\x07\x7f\x1f\xe8\x92\x4d\xa1\x13\xda\xc2\x65\x7f\x2b\x8a\x0d\x56\xe5\x77\x01\x86\x1f\x02\x5f\x7f\x1c\x25\x50\xf1\xb9\xd7\x2a\x09\xca\x23\xf7\x18\xff\x7b\x97\xf2\x71\x72\x55\x0d\x7d\x9b\x05\x6d\x5f\x7b\x94\x51\x78\x69\xd2\xd0\x64\x88\x3b\xbd\xe9\xdd\x9b\xea\xaf\xef\x3f\x72\xc1\x77\x3f\x11\x0e\x5b\x03\x6a\x5d\xc5\xe5\xe9\xaa\x97\xa7\x89\x92\xad\x9c\x55\x76\xc4\xd5\x63\x26\x25\x58\x70\x85\x9c\x5a\xd3\x0d\xae\x0d\xf8\xcc\x91\x8d\x47\x83\x06\x9c\x80\xc0\x87\x86\x31\xc0\xf0\x9a\xd5\xc3\xef\xfb\x97\x70\xfb\xb3\x6e\xab\xdc\xb0\xd1\x6b\xe8\x00\x36\xe6\x9d\x9a\xfd\x77\x6d\x68\xf6\x12\x23\x6c\x0b\x63\xcc\xe0\xe2\x8d\x3c\x94\x32\xf3\xe0\xbb\xea\x94\x2c\x1a\xd8\x9e\x42\xe3\x40\xbd\xac\x85\xb1\x9c\x83\x33\x06\x2c\xfc\xa0\xb5\x78\x02\xc8\x52\x04\x75\x37\xc5\xbf\x49\xa1\x7d\x9c\xa8\x92\x21\x5f\x73\xb1\x64\xba\xf2\x4f\x92\xbe\xa5\x86\x6a\x30\x72\xd9\x9c\x76\x03\xf6\xae\x7f\xa4\xdc\x23\x00\xef\x01\xd8\x2f\xa7\xd3\x49\x5d\xab\xf8\x64\x00\xd9\x97\x33\x80\xee\x36\x26\x2e\x52\x1f\x46\x2b\x42\x4d\xe4\xe0\x15\x94\x5f\xde\x4c\xa4\x6e\xb8\x0c\x98\x5b\x57\x46\xfd\xa4\x22\x0c\xbf\xb5\x75\x40\x0a\x10\x93\x6e\x97\x4d\x33\xdb\xae\x74\xba\xd7\x48\xdd\x91\x58\x80\x21\xa0\x4c\xb4\xe1\x57\xc4\x75\x48\x4b\xcf\x8c\x9c\xa9\x28\x4f\xed\xdf\x72\xc6\x8d\x43\x8b\x20\x41\x65\x3f\x80\x07\xf6\x6b\xfc\xe8\x33\x44\x70\xd7\x10\xbe\x6e\x96\xf6\x9d\xd0\x90\xdd\x3c\x0c\x6e\xa6\xe7\x41\xa0\xf1\x67\x40\xef\x43\xd3\xf8\x29\x86\x01\x5e\x04\xfa\x8a\xa3\x70\xec\x6d\x23\x60\xf0\x36\x2e\x8b\x9e\xdc\x89\x6a\xb7\x02\x00\x41\x3f\x8c\xd7\xb9\xd9\x99\x37\x6f\xf2\x73\x69\x45\x99\x0e\x4a\x38\xdc\x6d\x97\x47\xbc\x0d\x21\x22\x5a\x55\xde\xed\x32\xce\xaf\xf1\x0e\xb2\x3d\x80\xf1\x60\x22\x09\xae\x20\xa8\x01\x50\x62\x51\x98\x02\xe9\xd8\x25\x2f\x54\x3a\x5a\x1d\x40\x34\xc6\xfa\x3f\x29\xc4\x1d\x21\x6e\x2c\x49\x64\x0b\x3a\xed\x11\xe9\x78\x0b\x3b\xf1\x2c\x00\xea\x1e\xd8\x31\x74\x54\xef\x3d\xb9\x71\x53\x41\x9e\xf9\xab\xd4\xbc\x60\xd9\x04\xa2\x3d\x66\x4e\x02\xb1\xb5\x97\x8c\xfa\x44\x59\x06\x0b\xbd\xc7\xe8\x92\x6c\xda\x67\x32\xd1\xd2\xc7\x7f\xa9\x7b\xbb\x24\x06\x5f\x88\x6b\xaa\x97\x8a\xff\x09\x43\x0b\x5f\x02\xed\xee\xe8\x71\x88\xa3\x3a\x84\xdd\x26\xe1\x2c\x32\x41\x2d\xb9\x95\x2d\x92\x46\x06\xf8\xd1\x75\x50\xa0\x1d\xf2\x4e\x04\xfd\x50\xa5\x64\x0c\x61\x2c\x1e\xff\x4c\x12\xf0\x49\xf0\x55\x14\x22\x5e\x4a\xee\x8e\xd8\x0b\xed\xe3\x8b\x94\x23\xaf\x7a\xf0\x4b\x71\xeb\xd2\xf6\x72\x63\x6a\xe0\xe8\x29\x52\x94\x02\x2a\x0f\xd0\x0e\x91\xef\x92\x08\x4b\x6b\xe1\x62\x0d\x4b\x56\xcd\x20\xa0\xf6\xa9\x67\xdc\xae\x94\xde\x71\x9b\x0f\x66\x0e\x4e\x5d\x09\x43\x28\x7d\xd8\x3b\x10\x2a\x3f\x70\xa0\x05\xb4\x22\x3b\x1f\x46\x4d\x16\xd9\xb3\x44\x10\x3e\x26\xc2\xbe\xeb\xbe\xc8\xfa\x2e\xf9\x2d\xfd\x28\x39\xfb\xa9\x92\xc4\xfb\x40\xbb\xd6\xef\xea\xa7\x66\xce\x10\x3f\x1c\x97\x7f\x8a\xf7\xfc\x1f\x96\xd4\x3f\xd9\xc7\x82\x1f\xe6\xef\x3f\x99\xb2\x33\x1f\xa7\x89\xdd\x0c\x3d\x6d\xfd\x2e\xf5\x72\x32\xfc\xbb\x10\x34\x5f\x98\xe2\x7c\x67\x80\x42\x1c\x67\x9f\xf6\x58\xfa\x33\xf0\x4e\x32\x2d\x04\x4a\xde\x11\xd6\x6f\x19\xa7\x07\xb9\x14\x91\x98\x84\x40\xd0\xd3\xf0\xbc\x08\xdd\xf6\xf2\x4c\x04\xbd\xcf\xcb\xa6\x6a\xe4\xcb\x86\x73\xd7\xe7\xcd\xef\xc5\xd0\x78\xed\x39\x60\xf4\x3e\x04\x74\xe7\x75\x06\x91\x71\x79\xcd\xca\xc7\x00\x43\x4f\xbf\x74\x1b\xec\x2c\xde\x72\xbc\xa8\xde\x41\xd0\xfd\xba\x4e\x25\x3c\xdb\x57\x0d\xf7\x5e\xb3\x7e\x06\xf4\xb2\xb8\x42\x08\x7c\x41\xce\xe7\x74\xf3\xe2\x03\x43\x9f\x55\xd4\x7d\x4d\x76\x61\x35\x1d\x76\x3b\x77\x1f\x94\x41\x7e\x39\x55\xc9\x29\xbf\x39\xc2\x7d\x79\xb6\xfa\x0b\xad\x1f\x70\xbb\xfc\x1f\x64\x31\x20\x5c\x84\xd9\xc1\x08\x0e\xad\x8f\xd6\xca\x3e\xac\x78\xf8\xe2\x83\x67\xfa\x5f\x01\x8b\x6b\x3a\xb2\x2f\x81\xfa\xc3\x6e\xc9\x82\xa5\xe9\x48\x27\x25\x95\x2c\xf8\xca\x85\xd8\x87\x59\x10\x7a\xbb\xb6\x99\x11\xaf\xbf\xcf\x45\x79\x7f\x30\x38\xe3\x77\x71\xbe\x02\xbe\xbd\xdc\x5a\xd4\x6f\x9c\x4d\x14\x04\x45\x40\x18\x66\xf9\xa1\xfc\xfd\x02\xfc\x0b\x3f\xeb\x09\xcf\x76\xe2\xe9\xc1\xec\x42\xc6\x0c\xfb\xc0\xdb\x65\xa6\xaa\xf1\x93\x22\x16\x0e\xa3\x3f\xcf\x2a\x69\xe8\xd5\x5f\xb6\x16\x4a\x37\x7a\x85\xe4\xcd\x93\x1e\xf1\x20\xe1\x73\x6d\x7f\x87\xc1\xcd\xd3\x26\xf2\x42\xd5\x43\xe7\xed\x62\x68\x0f\xcb\xbc\x09\x32\xaf\x84\x12\x3d\xf3\xe4\x09\x9f\x89\xe6\x7a\x7a\x66\x21\x33\xa2\x0a\x75\xda\x9f\x39\x80\xf0\x37\x00\xef\x45\x80\xf7\x1c\xa0\xf9\xa1\xc1\xe7\x7b\x4e\x9a\x2d\xb2\x26\x92\x65\xfc\xa7\x2b\x9b\x4f\x3a\x82\xb5\xd0\xcf\x39\x3b\x7a\x25\x7c\xe4\x2b\xc1\xd9\xf5\x18\x72\x40\x92\xea\x7e\x7a\x41\xbd\x42\x6d\x86\x10\xee\x77\xcb\x1f\x5a\xfb\x4a\x91\x99\xbb\xee\x81\x37\xaf\x19\x18\x4d\xa2\xd0\x35\x66\xb9\x25\x18\x0a\x14\x39\xd5\x02\x6e\x98\x00\x4b\xd1\x58\x23\xd6\x1b\xa2\xee\x44\x5f\xdd\x85\xed\xf7\xad\x69\x27\xae\xe7\xc7\x97\xac\x07\xb5\x26\xf6\x2e\x84\x11\xdc\xa5\xa1\x9f\x6f\x7b\xe5\x67\xae\xa3\x28\x32\xe6\xf2\xfe\x85\x9d\x03\xa1\xe8\x32\x0d\xb9\x27\x02\x9b\xef\xe9\x14\x2c\x9c\x6a\xce\xfc\x4e\x58\xf9\x29\xd7\x7d\x16\xcf\x1f\x7c\xb8\x4d\x22\xd0\x59\xa8\xf4\xfc\xef\xf6\x44\xdc\x0d\xb0\x90\x1f\x2d\x53\x98\x5b\x9a\x69\x77\x5e\x12\x5b\x78\x7b\x5f\x4f\x8a\xfc\xde\xd9\xad\x75\x6e\xb9\x97\xc1\xbb\x5e\xea\xe2\xb7\x5d\x38\x97\xe4\xe2\x3f\x0f\x89\xc5\x3b\x51\xf4\x03\x3a\xc5\xf4\x85\xbd\xdd\x23\x8a\xa7\xad\xc6\xf0\x8e\x6c\xb1\x05\x60\x99\xce\x2d\x0c\xca\x40\x5a\x2f\xed\xbc\x12\x21\x0c\x9d\xe8\x81\x6b\x88\x01\xbe\xd3\x94\xb5\xa3\x35\xe9\x3c\xaa\xf5\x0f\x5c\x03\xdf\x4c\x0b\xac\x51\xdc\x24\x8b\x79\x7d\xfa\x4f\x3e\x00\x7e\xe0\x27\x87\x69\x0a\x12\xfd\x7a\xcb\x14\xee\x7a\xd1\x3d\xdd\xa1\xed\x6b\x53\x56\xad\xa1\x3d\x8c\xcc\x3a\xfd\x74\x1c\xcf\x2e\xb1\xe9\xd5\xb5\x8c\x7d\xff\xda\xaa\x62\x16\x06\x92\xbc\xaa\x99\x00\x8c\x5d\x1a\xb1\x18\x19\x35\x79\xe9\x50\xd3\xb5\x50\x62\xd0\xd6\xac\xf1\x4b\x58\xea\xeb\x41\xb3\x0f\x94\x2c\xbe\x0b\x91\xbd\x36\xba\x19\xc3\x66\x1d\x54\x85\xe6\xae\x1f\x66\xed\xf7\x57\xe3\x01\x31\x0f\x02\xcd\xe9\x2f\xa2\xfb\x96\xf3\xf9\x0d\x75\x51\x9e\x63\xda\x8f\x76\x54\xdc\xcb\xe6\x59\xea\x38\xf3\xb3\xa1\xcc\xa7\xca\xff\x46\xe5\x69\x6f\x21\xaf\x13\x46\xfc\xf6\x8c\xf8\x79\x1e\x45\x4e\xf9\x21\xa9\x0d\x04\x2e\x71\xd9\xc7\x1c\x12\xb5\x87\xfc\xdf\xcb\x4b\x87\xa6\xf1\xdb\x55\x4a\xc0\xca\x77\x76\x64\x57\x09\x88\x7b\x41\xa5\x4f\xf0\xe8\x22\x6d\xd7\xab\xb8\x1f\x89\x4e\x74\xa7\xe2\x9f\xff\x9e\x8d\xd3\x49\x6b\xd0\x6f\xe1\x77\x37\x5a\xdc\x40\x59\xd6\x77\x5d\x09\x72\xbc\xe0\x57\xe3\x2b\x16\x10\x85\x42\x96\x78\x49\xa1\x49\x3d\x8b\x99\x79\xcd\x67\xe8\x44\xcb\xe3\x7f\x46\x5e\x32\xb8\xe4\xd0\x8d\xe6\x13\x30\x2f\x0b\xdb\x67\x4e\x56\x28\xaf\x78\x59\x2b\x24\x7d\xe4\xa9\x6e\x3a\xf4\x14\x96\xee\x10\x8f\x5e\x69\xf8\x0e\xd1\x68\x2e\x1b\x74\xda\x9d\x0f\xb9\xc3\xbc\xd1\xbf\xc7\x8d\xf6\xed\xb7\x06\xe6\x79\x9a\x01\xb7\x23\x36\x7d\x96\xea\xf5\x94\x8f\x49\xbe\x45\x16\xab\xa3\x02\x50\xbd\x41\xd7\x81\x49\x12\x06\x1d\xb8\xb4\x90\x8b\x3e\xbf\x18\x75\x24\x19\x89\x6f\xc7\x2b\xfc\x20\x7b\x0d\xc3\x07\x59\xb0\x5b\x98\x05\xf4\x9f\xec\x35\x0c\x04\x3c\x25\x1c\xc0\x43\xf5\x24\xa8\xcb\x4c\x0b\xc2\x6c\x13\xa1\x4f\x08\x3e\x1f\x6c\xad\x2f\x99\xae\x5c\xc0\x62\x86\x2c\xb4\xab\x0b\x08\x85\x9d\x57\x16\x54\x2d\x28\x4f\xed\x1b\xd2\xaf\x57\x86\xc8\x92\x70\xe0\xf9\x21\xd4\x7f\x06\xa4\xd0\x7f\x5a\x86\xd4\x04\xd7\xa5\x90\xcd\xb3\x30\xc0\xfa\x19\x70\xdc\xfc\xf1\xff\xd9\x9f\xca\x3b\x5d\xbd\xf4\x33\x80\x7a\xd7\x53\x0c\x56\xea\xc2\xcd\xa6\xf3\x1d\xdb\x4d\xa7\xe6\x50\x8e\x84\xdf\xb2\x50\xf3\x45\x8a\xd5\xa8\xe9\x3c\xbe\x20\xf6\x3f\x82\x7e\xc0\xc3\xcf\x79\xf8\xc6\x7f\x70\xf0\x4d\x84\x3a\xd0\x69\xc0\xbf\x9f\x7f\xc0\xfe\x78\x8d\x03\xe1\x3e\x85\xeb\x2d\xc2\xef\xc9\xe4\xb9\x0b\x55\x6b\x32\x89\x11\x2c\xa1\x9f\x9d\x7c\x10\x74\xa5\x7f\xbe\x09\x26\x2b\x6f\x06\x4c\xd1\x5e\x5e\x5c\xa2\xde\x3a\x10\xf0\x91\xf4\xba\x9c\xfe\x96\x46\x3d\x4a\xd6\x64\x64\x16\xc7\xa1\x3d\xad\x07\x02\xd1\x18\xeb\x34\xdc\xb9\xa8\x59\x2f\x02\x11\x46\xc4\x64\xc5\xa4\xf5\x03\xfa\x63\xc4\x7c\x0d\xd3\xfa\x0c\xc8\xfe\xfa\x4c\x6d\xfe\x06\xd0\xbd\x84\xb6\x2c\x8c\x8e\xf2\x4a\x31\x8e\xba\xd2\xd4\xc4\xad\x33\xd5\x65\x2e\xf9\xd1\x9c\xef\x1d\xaa\x72\x04\xaf\xcb\x48\xf7\xac\x47\x33\xf3\x3d\x6b\x13\x54\x3c\xeb\x76\xb2\x15\x3c\xeb\xb4\x0b\x0b\x2f\xf6\x89\x2b\x69\x46\x8d\xc4\x26\x49\x92\x52\x2e\x17\xf3\x4f\x08\x9a\x03\x3b\x8c\x2c\x99\x6c\x3d\x61\x5f\xe6\xcb\x4d\x60\x7e\x01\xff\xad\x39\x17\xc4\x09\xe8\x7b\x09\x60\x8f\xcd\x89\xef\x2c\x92\xc2\x1e\xb0\x6a\xe6\x2a\x64\xf3\xa5\x80\x1d\xfb\xce\x14\x5d\x14\xbd\xdb\xed\x30\xfc\xdf\xcd\xfa\xf7\xf2\x2f\xd3\x63\x07\x68\xfe\xe5\x30\x27\x68\x53\x48\xda\x5a\x1c\x80\xd9\x75\x0f\xb8\x4e\x52\x09\xa7\x46\xf5\x8e\xda\xef\x88\x93\x3a\xa7\x10\x28\x83\xff\x8e\x9f\x43\x0e\xc6\x2d\xb0\xf7\xe1\xd4\x76\x8a\xe3\xea\xc7\xce\x23\x6b\x52\x67\x1e\x9a\x59\x1f\xa8\x7b\x85\x4b\x24\xaa\xa9\x50\x4d\xa9\xeb\x44\xd7\x2f\xd4\x8c\xe2\x08\x30\x47\x92\xed\xc1\x29\x33\x24\x87\xe2\x53\xe8\x7a\x17\x5e\x7f\xd7\x11\x09\x54\xb3\x37\x72\x4f\x54\xa7\x3a\xed\xf1\xf0\x9f\x86\x19\xa4\x6f\xfc\x5f\x05\xba\xbf\x48\x2d\x00\xc2\xd7\xb8\xaf\x47\x95\x73\x81\x05\x69\x17\x7a\x9e\xfa\xa1\x07\x20\x92\x97\xb0\xf5\x73\xc8\xd2\x1e\x1c\xf7\x01\x62\x4f\xb4\x0b\x1f\x2b\x42\xec\xe5\x21\x7a\x40\xbe\x82\x40\x79\xe0\xef\x2f\x06\x0d\x1c\x5e\x30\x47\xbf\xa5\x89\xbd\x87\x1b\x1a\x80\xf6\x92\xc5\xb6\x80\x1b\x4a\x87\x7a\x2d\x84\x2d\x1e\x40\x71\x31\x33\x65\x61\xcf\xdc\x09\x60\xf6\x55\x22\xd5\x00\x9b\xf9\xb1\x66\x58\xa4\x0b\xf1\xed\xa3\x4d\x3f\x87\x39\x94\x6c\x2d\x92\x8c\xd8\xc1\x51\xab\x2d\xc6\x70\xfb\x00\xf6\x8b\xf2\x4a\xc0\xe9\x17\x6d\xe6\x88\xfd\x39\x42\x5d\x0b\xeb\x95\xbc\xea\xe7\x81\x96\xf1\x85\x10\xef\xc0\x5d\x50\xd0\xfa\xb1\x86\xb1\xc2\x01\x7b\x45\xfd\xea\x0c\x32\x5f\x44\x99\x28\xfb\x7b\x96\xea\x36\xab\x90\x47\x86\xc0\xc0\x92\xb8\x2a\x0c\xb1\x21\xc2\x29\x55\x6e\x8f\x42\x8e\xcb\x4d\x97\x43\x24\xd7\x49\x01\xc1\x09\xf0\xb9\xd4\x11\xd9\x77\x0b\x46\xfd\xb8\x3f\x40\xa8\x23\xa3\x02\xe4\x2f\x01\xba\x42\x81\xfb\x33\xbc\x26\xfc\x62\xe7\x90\x11\x3d\x72\x8a\xab\x94\x45\x33\x3b\xd2\x73\x15\x17\xf8\x48\x97\x60\xac\x84\xf6\xc7\x80\xf7\x80\x0d\xa5\xef\x0e\xa7\x8f\x5e\x7a\xdd\x9f\x39\x78\x05\xe4\x53\x1f\xc8\x85\xcf\x11\x0d\x69\xe1\x4f\x48\x71\xc4\x9e\x37\xad\x10\xec\x0b\x29\x2b\xc7\xf1\xbf\x6c\x0c\x7c\x72\x18\x5c\x62\x2c\x5b\x50\x53\x65\xf5\x12\xc6\x0a\x9c\x35\xb4\x8c\xac\x4d\x66\x5e\xce\xbc\xf5\x58\x14\xf4\xe6\xb7\x6d\xa3\x38\x0a\x50\x15\x5d\x3b\x1b\xdc\x40\xbc\xc8\x0f\x71\xe6\x07\xa1\xf0\xf0\x79\xe6\x33\x2e\xc7\x67\x5b\x4c\x2c\xd4\x4a\x4d\xbf\xac\x07\x25\xc2\xbd\xce\xe3\xbf\xab\x2c\x7e\x15\xec\x42\x9f\x22\xf6\x95\x25\x09\x26\x5c\xa6\x5b\x84\x82\xe8\xf5\xf6\x37\x41\xf7\xf5\xe6\x14\x67\x47\xff\x4f\xf9\xef\x72\x92\x7d\xb2\x53\x36\xc9\xfa\x58\x21\xb1\xd9\xdb\x4e\x21\xc3\x8a\xa4\x7c\x11\x01\xd9\x66\x2c\xbe\x6f\x7e\xb3\xee\x01\xe9\xee\xa0\x0f\xb8\x57\x8c\x07\xfe\x2e\xee\xc4\xce\x95\x81\x12\xdf\x94\x34\xdc\x31\xd3\xf2\x23\xa4\xca\x5b\x60\x7d\x27\x48\x76\x1c\x44\x78\xca\x95\x6f\xd7\x2e\x08\xd7\xf6\x66\xc7\xb8\x41\x20\x29\xd2\x0f\x5b\xd8\x05\x81\xc5\xc5\x8e\xdd\x3f\xfc\x4a\xce\x9f\x82\xdf\x01\xd4\xaf\xa4\x77\x6c\x45\x1e\x9d\x5b\x91\x66\xdc\x56\x6e\xb9\x18\x6d\x21\xfd\x8c\xb2\xdd\x8f\x70\xfe\xb9\x12\x73\x5c\xc4\xdb\xf5\xdc\xd9\x2a\xab\x13\xfb\xb0\x47\xf3\x6c\xf1\x54\x84\xef\x70\xd8\x7f\x6c\x0e\x60\xc3\xa6\xe3\x61\x0e\xce\xc8\xfa\x8e\x59\xbb\xf5\x2a\x19\x68\x0c\xbe\x95\x91\x8b\x70\xe6\xda\x4a\xcf\x9b\x84\x0a\x67\xd1\x32\x73\xc9\xe2\x8b\xf5\xf4\x37\x47\x6d\x90\x70\x09\xd8\xf6\xdc\xc4\xf0\x37\xb5\x56\x10\x13\x26\x25\xa0\x9f\x44\x02\x98\x72\x80\x16\xf0\x81\x69\x0a\x48\x87\xfb\xe6\x4d\x86\x5a\xa5\x48\xbb\x45\xf3\xc3\xfb\xcb\x0d\x39\xa9\xf2\x23\x3c\x3f\x97\x21\x37\x1e\x2c\xb9\xcd\x61\x7f\x44\xf8\x0f\x14\x01\xda\x72\xef\x95\xc6\x2d\x6b\xb0\x6e\x01\xcf\xc4\x5a\xe3\xc4\xe0\x45\xc5\x16\x8f\xa1\x29\xe7\x9b\xf5\x28\x73\x0b\x69\xde\x2f\x4a\x51\x6c\x3d\x34\x33\x0b\x37\x18\x73\x0a\x71\x71\x5e\x93\x1e\x6e\xf7\x5c\xe3\x30\x4c\xc5\x43\x38\x61\x02\xcf\x6f\xcd\xd6\x1c\x82\xe2\x67\xd5\x48\x5f\x9a\xe3\xb3\xe2\x22\xcc\x3e\xb4\xc2\x02\xf2\xdf\x80\xfc\x10\xfb\x4a\x8d\x09\xc0\x9c\x22\xb0\xfe\xe7\x1d\xf8\xff\x48\xc8\x6f\x7d\x97\x04\xa7\x7f\x6b\xca\x8b\x48\xa0\xf8\x00\x5c\x59\xd4\x73\xbe\xbe\x25\x2a\x0c\x50\xbc\x5c\x41\x26\xfd\x00\x6e\xfc\xdc\xe6\xaa\x21\x46\x6e\x27\x4c\x1e\x06\xea\x02\x92\x17\x40\x4c\x25\x40\x6a\x0c\xdb\x7b\xd5\xd3\x88\x65\xf3\x8a\x01\x9f\xa2\x84\x21\x9b\xa4\xc7\xff\xe8\xfe\x36\xad\x73\x1d\x69\xca\x0f\x81\xff\xcf\x9e\x3a\x68\x5b\x90\xd9\x31\xe8\x08\x8c\x8c\xc5\x92\x13\x05\x25\x60\x0a\x96\x80\xa8\x75\x5b\x5a\x41\x59\x63\xb4\xa2\xd0\xc2\x2d\xd7\x50\x7e\xb6\x70\x2a\xb7\xc4\xca\x75\x95\x93\x44\x81\xa0\x3c\x10\x80\xd6\x2d\x61\x12\x26\x16\xc4\x38\x93\xc9\x90\x4f\xa9\xa5\x0f\xdc\x1f\x52\x6b\xe3\x24\xd9\xfc\x90\xa8\xb6\x80\xf2\xa8\x24\x1a\xfc\xb5\x63\x25\x8f\x60\x1f\x07\x0e\x6e\xb6\x24\x7c\xf6\x7b\xe7\x62\x70\x31\xc5\xb5\xbe\x25\x53\xb9\xd6\x9b\x58\x6e\x60\xac\x25\xb6\x63\xed\x31\x45\xd2\xad\x51\x22\x00\x70\xb5\x26\x69\xe7\xe6\x13\x3f\x4b\x6f\xc4\x02\xd2\xef\xd7\x3a\x00\x31\xe7\x51\x14\x32\xd7\xe0\x0f\x7b\xd0\x68\x0a\xfc\x20\x58\x7e\xed\x67\x9e\x47\x58\xf1\xae\x41\x67\x02\x9d\x61\x24\x0c\x04\xa2\xeb\x5a\x2e\x5c\x0c\x6f\x2d\x73\x0c\xa9\xd7\x12\x12\xef\x70\x3c\x0b\x75\x73\xc4\xec\xf1\x3c\xf4\xdf\x5e\xb6\x7a\xf5\x3a\x2e\xdc\xeb\xd9\x89\x61\x7a\xb8\x07\x8d\x61\x91\x3a\x38\xf4\xf2\x54\xea\xb4\x11\x99\x5e\x78\x70\xa0\x5e\x5c\x75\xd8\x6d\x3e\x3c\x82\x1c\x11\xd7\x41\x20\x9a\x40\xfe\xd9\x45\xca\x23\xcc\xfb\xc6\x81\xa9\x7d\x80\x62\x39\xe9\x0d\x0e\xb2\x06\xd5\xae\xfd\x6c\x94\xf9\x04\x73\x5a\x81\xb5\x7a\xba\x46\xe2\xaa\x32\xdc\x9a\x8b\x74\xdb\x77\xe5\x68\xd6\x3c\xea\xbc\xa1\x90\x11\x01\x17\x43\x93\xc3\x82\x44\xbb\x2c\x1b\xd7\xf4\x56\x86\x65\x85\x8c\x23\x19\x20\xf6\xfa\x56\x2e\xc7\x29\xe8\x01\x16\xea\x46\x92\xeb\x46\xec\x3f\xdd\xd8\x00\xfe\xb3\xc6\x5e\x24\x06\xa0\x06\xc4\x24\x90\x5a\x0f\xd2\xd4\x3e\x62\x58\x93\xf0\xb3\x6b\x3a\x84\xd2\x05\xd6\x86\xc2\x53\xab\xeb\x3a\x05\xd1\x60\x6c\x5c\x01\xf7\xea\x8c\xd5\x43\x5c\x77\xe4\x20\xb8\x14\xc7\xa2\xe1\x23\x10\xcd\xfc\xff\x1a\xdf\xda\xa9\x61\x8c\xed\x91\x4d\xb1\x38\x13\x5b\x3d\x17\xd8\x17\x9d\xf5\xe3\x31\x07\x59\x42\x3e\x01\xf6\x28\xf1\x6a\xf4\x4c\x6d\xad\xc9\x2b\xb0\x24\x26\xc8\x77\x7f\xa9\xec\xba\x96\x2a\xf2\xd7\x52\x3b\x1f\x0b\x2c\xd5\x4e\x0c\xbb\x2f\x2e\x70\xe7\xb8\xf7\x93\xf9\xee\xc5\x9e\x3d\x92\x07\xce\xf0\x57\x73\x7d\xf8\x0f\x03\x4e\x31\x2c\x68\x38\x85\x05\x3e\xc0\x7e\x84\xf2\x91\x26\xfc\x87\x5c\x85\x86\x40\x71\x49\x78\x87\xe8\x17\x19\x52\x2d\xe5\x97\xec\xcd\xa5\x68\x84\x0c\x46\xc2\x2f\x01\x26\xcb\x5a\x95\xe5\xb4\xc8\x67\xac\xc0\x20\x2e\x53\xe3\x4c\xe0\x59\x54\x94\x83\xbf\xa0\x2c\xe6\xb2\x8a\xcc\x64\x41\x22\xef\xe0\xf3\x21\x18\x7f\x21\xd5\xcf\x23\x24\xab\xe8\x27\xb2\xb8\x10\x78\x60\xa3\xe3\x93\x54\x49\xc0\x64\xe0\xab\x8a\x88\x0b\xd1\x15\xf6\x81\x24\x8d\x39\x48\xde\x16\xf5\x49\x7a\xf2\xb3\x06\x6f\x8b\x27\xc2\x78\x1a\xe3\x74\xb7\xd9\xa5\xb5\xfb\xfb\x87\x62\xfc\xec\x47\x96\x69\x26\xfb\xc1\x75\x45\xaf\x26\x4b\x4f\x0a\x83\x1d\x8d\x9f\x65\x89\xb7\xe4\xe0\x23\x64\x1f\xd6\xa0\x9c\xea\x6d\x9e\xea\xaa\xcb\x57\xb1\x3e\x5d\x87\x66\x03\x4b\x3a\x5a\x83\xb5\xe0\xb1\xfe\xfb\x81\x0b\x0e\x46\x97\x38\x16\x3a\x0a\xb2\x1d\x56\x6e\xa0\x3a\xa3\x05\x8d\x18\x81\xb7\x51\xdb\xa4\xf8\x92\xd7\x3d\xcd\xaa\x1d\x2d\x49\x97\xfd\xb7\x72\xcc\xfd\x5b\x5d\xec\xe3\xb7\x28\x39\xe4\x81\x2f\x31\xe6\xe6\x73\x6e\x31\xf9\x0f\x74\xd6\xfb\x9d\x41\x00\xf6\x9d\x6d\x9c\x53\x49\x7e\xb0\xf3\x26\x93\xe1\x7c\xce\x5c\x12\x46\xf1\x0b\xb9\x04\x1e\xd9\x7e\x0a\x47\x71\x8c\xb8\xd9\xdf\x04\xb2\x7f\x0a\x66\x84\xeb\xe8\xbf\x22\x05\x3f\xd7\xc0\x70\xcd\xa7\xdf\x2b\xbb\x7b\x92\x1c\x9a\x35\x52\x9a\x7f\x25\x1c\x3e\xcb\xe4\x63\x16\x8f\x1f\xb8\x47\xdd\x8c\xe9\xbd\xfb\xb3\x34\x85\x4c\x00\x9c\xe0\x48\x7b\x90\xec\xb1\x05\x3e\x0f\x9a\x6c\x54\x39\x48\x51\x7f\xbf\x5b\x91\x88\x8a\x73\xd9\xa3\xc0\x80\x4d\x75\xac\x79\xd7\xde\x23\xa9\x13\x04\x80\x4e\x15\x70\x0d\x8e\x3b\xa6\x2a\x7e\xc3\x4b\xc4\x08\xaf\x74\x79\x14\xd2\xfd\xa8\x10\x85\x85\x02\x98\x6c\x8f\x24\x9d\x7d\xf0\xb8\x79\x1d\x6c\xa0\xfd\x99\x44\xfc\xc5\xa0\x7b\x96\xb6\x7d\xf9\x43\xd2\xb0\x51\xf4\x29\x42\x86\x0d\xf8\x1a\xe8\x68\x9a\xdd\x12\x92\xd1\x95\x45\x85\xe0\x55\x98\xcf\xf4\x16\xc1\xc2\x5e\x2a\x70\xeb\x44\xac\x90\xf0\x94\x5b\xcc\xc3\x29\xfa\xc1\x4f\xeb\xfd\x15\xe8\x5f\xbf\x17\x67\xfe\x03\xe7\x9f\x83\x5a\xe1\xdd\x36\xa6\x90\x9b\x3e\x12\xe2\x3f\x77\xa1\xd4\xff\x0e\x2e\xc5\x2b\xc8\x0e\x61\x3f\x84\xd7\x8f\x57\x0d\x93\xf0\x60\x5c\x0c\xa4\x55\xec\xba\x83\xb9\x31\x82\xa1\xa0\xa0\x23\xac\x0f\x31\x22\xe6\x18\x32\x58\xb8\x2c\x04\x3d\x80\x27\x41\x1e\x07\x86\xe9\xda\xa3\x63\xb7\x28\xce\x04\x6f\x31\x54\xec\xb8\xec\xa2\x24\x37\x29\x4d\x34\xb9\x77\xe9\x2c\x12\x84\xf7\x7e\x6f\x86\xe2\x40\xd8\x0f\xf6\xd1\x2c\x18\x15\xfa\xea\xbc\x0f\xf1\xe4\x30\x82\xa3\x0b\x24\x7a\xfd\x38\xeb\x04\x06\x3a\x47\x90\x93\x4f\x05\x3d\xd8\xaf\x96\x2c\x74\x29\x98\xa9\x64\x85\x2b\x0f\x6b\xf3\x91\x85\xdc\x8d\x35\xd6\x84\xa9\x41\x5a\x1f\xaa\xd5\x20\x94\xea\xd2\x94\xac\x55\x89\x7f\xc9\x6c\xa6\x2d\xcf\xef\xbf\x56\x4f\x3e\x11\xeb\x38\xa5\x07\xa1\x46\x53\x0a\x15\xa1\xb1\x02\x34\x10\x14\x8c\x7b\xd9\x95\x1f\x1d\x2b\x46\x17\xa2\x38\xd4\x5d\xa9\xf3\x11\xdd\x1a\x84\x28\x43\xd3\x1e\x52\x62\x7c\x89\xc0\xe5\x10\xa7\x63\x0d\x9b\xe2\xb1\xfa\xbc\x08\xef\x54\x5b\xf3\xe5\x30\xd8\xfc\x64\xe2\x93\x30\x86\xe2\xc8\x78\xd2\x47\x72\x74\x6c\xe2\x1d\x91\xf3\x14\x6c\x16\x1b\x34\x06\x28\x82\x34\x9e\x83\xac\x09\x06\x6e\x2d\xab\x75\xb7\x26\x08\x47\x84\x14\x09\x5c\x0b\x85\x60\x40\xf4\x78\x44\xc0\x65\x27\x2f\x85\xd4\x51\x85\xbf\xdc\x2c\xc8\x8e\xe5\x7a\x05\x7f\xc4\xe7\xdf\x23\xe0\xaf\x3b\x45\x64\x2d\xee\x3f\xef\x9e\xab\xcb\x10\xcf\xd1\x58\x56\xb2\x4a\xec\xe4\x27\x2f\x54\xc3\xab\xe0\xc5\x66\x0e\x61\xd0\x57\x40\x4d\x23\x81\x74\xc4\xc8\x49\x98\x21\x8b\xe3\x44\xf1\xf3\x89\x88\x1d\x81\x6e\xe4\x55\x9c\xa9\x90\x37\x46\x32\xcd\xe6\x0e\x36\x27\x75\xe7\x86\x19\xe8\x00\x0a\x64\x8c\x60\x8f\x29\x8d\x3f\x66\xe5\x25\xad\x1b\xaf\x42\x41\x8d\x39\xa6\x4f\x76\x94\x97\x37\xb0\x23\x44\x88\x2e\xae\xfa\xb2\xe6\xdc\x80\x1d\x42\x97\x59\x1f\x58\xa2\x18\x95\x0b\xb1\x65\xd7\xf0\x1b\xee\xb6\xce\xb5\xb3\x9c\x12\xb2\xd4\x7a\xc7\x3c\xc8\xf2\x20\x87\xe2\x81\x4d\x73\xf9\xd6\x8e\xe9\x39\x93\x42\x52\x9b\x2f\x42\x15\x2b\x6a\x04\x46\x83\x1b\x9d\x54\x46\x85\xaf\x06\x4f\x3c\xa8\x01\x23\x4a\x08\xfc\x6a\x6d\xe3\x01\x8f\x7b\x39\x38\xa4\x35\xb8\xda\x63\xa2\x93\xf2\x98\x06\x9d\x58\xea\xf8\x1f\x3b\x20\x7f\x2f\xfd\xaf\xce\xde\x7a\x65\xbd\x1f\x55\xfc\x7a\x0b\x1a\x93\xeb\x51\x7f\xe7\xe2\xaf\xeb\xa3\x8a\x6f\xf0\xa8\x21\x34\x63\x97\x6e\x97\x0b\xc2\x28\xde\x8a\x17\xc4\x3c\x4a\x3e\x92\x9c\x19\x2f\xda\x3e\x0d\x7a\x47\x48\x68\x21\xb5\xe5\xbc\x94\x1a\x7b\x80\xc4\xf4\x43\x46\x4b\x7b\x9b\x1e\x65\xd7\x76\xfe\xb4\xd9\x82\xaf\xa5\x05\x6b\x38\x25\xac\x9a\x8a\x3d\x56\x2f\xa5\x3a\xc7\x03\x59\x8e\x46\x6c\x01\x93\x74\x14\xdd\x05\x56\xd5\x49\x53\xb6\x47\x2b\x8a\x5b\xa4\xb4\xa0\x0d\x97\xa7\x59\x56\x09\x4d\x8b\x58\xe1\xac\x30\x3d\xa5\x87\xff\x98\xb3\x08\x30\x9c\x29\x3e\x66\x90\xd3\x2f\x46\xbd\xcf\xa4\x1f\x59\x3c\x9d\xbf\x84\x03\xb0\x60\x26\xfd\x22\xa5\x0a\xdd\x41\x21\x2e\x7b\xe6\xcb\xf8\xc8\x82\x44\x3d\xd2\x73\x16\xf9\xc5\x2e\x5c\x9b\xef\x3c\x92\xe8\x2b\xe7\xae\xcf\x82\x8c\x3e\xd2\xe2\x0c\x46\x0f\xe7\xd3\x86\x07\xde\x70\x3e\xa8\x82\x99\x05\x86\xf6\x50\x7e\x3a\xd9\x25\xd2\x3c\xd0\xc4\x03\x9a\x49\x6a\xeb\xed\x25\xaa\xfc\x0e\x50\x64\xa7\xc9\x9c\xb9\xf3\xd3\xce\x47\x93\xa1\xc9\x87\x6c\x15\xf6\x37\x67\x96\x50\x9a\x58\xa5\x75\x93\xbf\x66\x69\x79\xf3\x76\x21\xbb\xcc\x86\xb7\x0b\xad\xd0\x92\x75\x27\xf5\xfb\xff\x94\x5a\x20\x73\xc4\xdd\x26\xd1\x5c\x06\xd4\xd8\x75\xc4\x41\x67\xd0\x20\x04\x2a\xbf\x81\x0b\x43\xe3\x06\x67\x6b\x37\x83\x1f\xc7\xb3\x69\xdf\x34\x8a\x36\x43\xab\x00\x52\xf2\x06\xeb\x27\x5a\x86\x65\x40\x47\xc1\x9c\x92\x85\xbd\x27\x1a\x87\x1a\x5e\x07\x36\x0f\x1a\x0b\x75\xa9\x07\xa0\x86\x9c\x0c\x72\xe6\x37\xc7\x9a\xc0\xff\xc9\x64\xe1\x45\xef\x80\xd2\xa8\x29\xf6\xbc\xeb\xab\x33\x8c\x0c\x4a\x89\xad\xf7\xe4\xaa\x59\x1e\x88\x2e\xb3\x75\x6d\xea\x34\x14\x09\xc1\x0d\x12\xc4\x1f\x4a\x27\x75\xa7\x01\xfe\xd0\xdc\x03\x33\x3f\xb1\x9d\x87\x59\x33\xbb\x61\x96\xa0\x32\x44\xbd\x39\x1e\x1b\xe6\xf8\x0a\xd9\x05\xb1\x74\xe6\xc3\x0b\x34\x7e\x0e\xf3\x16\x32\x35\xc3\xbc\xca\x6f\xc2\x35\x23\x9b\x65\xf7\xf0\xb5\x85\x70\x0c\x31\xb7\xed\xc2\xf7\x21\x3f\xc5\x9f\xb9\xef\x20\xb6\x5c\xa1\x1b\x6d\xa1\x4d\x6b\x77\x71\x6f\x2a\x69\xfe\x36\x62\xd7\x1c\x77\x00\x29\xae\xb3\x9e\x91\x07\xd8\x50\xef\xfd\x11\xc7\x86\x0d\x8c\x85\xf6\xec\x8a\x25\xb3\x16\x92\x71\x56\x2f\x2d\x0e\x41\x8f\xb5\xc0\x73\x18\x43\x9e\x83\x06\x34\xcb\x89\x6f\xc8\xf4\xc5\xe1\x89\x5a\xc3\x79\x73\xe8\x3e\xe4\x47\x95\x81\x45\xee\x4a\xb0\x7d\xec\xa9\x27\x23\x2a\xa7\x48\x71\x59\x38\x84\x48\xf0\x80\xa6\xc1\x81\x5d\x2e\x82\x73\x37\xdb\x08\x7d\x2b\x49\xf3\x01\x78\x54\x3d\x70\xca\x51\x0d\x50\x5a\xd5\x97\xeb\x87\x16\xda\x16\xf1\xe6\x26\x11\x70\xa8\xb0\x82\x8a\x58\x4c\x35\xfa\x7a\xbf\xce\x99\xaa\x69\x16\xaf\x34\x0d\xef\x2b\xe7\x1d\x7d\x95\x48\x52\x4f\x0c\x3f\xcf\xc7\x3f\xa8\x09\xe9\x6b\xb4\x8d\x3d\x2a\x77\xda\xe0\x9c\xd5\x95\xba\xed\x84\xa8\x3e\x00\xdf\xdb\x06\x9b\x68\x35\x3e\x33\xc6\xd2\x9f\x9d\xfe\x4c\xb3\xce\x0e\xee\xbb\x24\xc4\x88\x10\x51\x68\xf6\xd4\x17\xaf\xcb\xf7\xf6\x6f\xb2\x9c\x23\x9e\x8d\x85\x22\x58\x90\x2d\xc5\x88\xb9\xef\xa0\xdf\x5c\x04\x66\xad\x22\xe8\xfc\x3f\x55\x5f\x96\xe0\x2c\xcf\xf4\xba\x97\x77\x67\x06\x9c\xe0\x66\x30\xbf\x81\xe4\x4b\x56\x7f\x4a\x25\x95\xf3\x9c\x9b\xb6\xa0\x99\xc2\xe0\xa1\x5c\x92\x82\xa8\x73\x44\xdc\xdd\xf0\x46\xed\x72\x43\x62\x01\x1b\x5a\x98\x5f\xe8\x0c\x1d\x1a\x45\xec\xe2\x1d\x21\x03\x9e\x6c\x24\xfb\xb8\x2e\xae\x5a\xab\xf7\x2d\xc0\xd2\xb9\x75\x06\xb8\x12\xcb\xb4\x42\x43\x71\x0f\x2d\x5f\x5a\xa5\xfa\x03\x48\xde\x11\xd0\x86\x62\x97\x73\x8c\xa9\x80\x11\xfe\x89\xb3\xba\xb2\xe3\x1a\x42\x11\xe3\x9a\xc3\x6f\xdf\x20\x12\x15\xb4\x1f\x74\x2b\xc8\xca\xb1\xb7\xcb\x4f\x19\x0c\x96\xf2\x08\x8a\x4e\xb1\xce\x86\x87\x08\x49\xcf\x11\x25\x02\x79\x4b\x71\x43\x5c\xb4\xd0\x7b\x78\x80\x5a\x67\xbd\x36\xd1\x4d\xe6\x7f\x9b\x22\xc4\x2c\xd4\xd6\xc2\xb7\xe2\x15\x9b\xa4\xce\xd4\x89\xfc\x97\x11\xc9\x09\x7c\xd8\x39\x1c\x31\x92\x24\x3b\x5c\xcc\x79\xfd\x4f\xe4\x9a\x35\xd2\xbc\x9d\x5f\x43\x03\x8b\x24\x33\x4a\xf7\x8f\x10\xe3\x66\x63\xfc\x00\x3e\x12\xf1\x1e\x24\xb8\x86\x74\x4b\x8b\xd6\xed\x25\x50\xff\x68\x8b\xa3\xe8\x0b\x1d\x99\xf2\x2d\x94\x7c\x3c\x30\x86\x28\x32\x02\xe8\x9d\xfd\x83\xf1\x26\x8f\x84\x19\x06\xad\x4b\x9b\xec\x26\x98\x49\x3c\x6a\x7e\x00\xe5\x1a\x1c\x9b\x14\x13\xc8\xc0\x64\xdb\xbc\x25\x6a\x36\x7c\xd8\x33\x19\x3e\xf8\xc9\x38\xc2\x80\xa0\x59\x23\x98\xbd\xbb\x65\x20\x2c\x25\x44\x46\x47\x7e\x20\x5f\x65\xb0\x6f\x62\x73\xeb\xf8\x24\xfd\x57\xc3\x10\x43\xa2\xc4\xdc\xf4\x29\x85\x09\x05\x77\x13\x1d\x6f\xb8\x73\xa7\xe5\xa8\xd3\x39\xd8\x70\x2e\x34\xe3\x1d\x07\x83\xa4\x51\x0f\xd5\x4a\x45\x56\xac\x25\xfc\x5f\x50\x69\x38\xb4\x03\xf5\xc6\xa9\x09\x48\x92\x95\x37\x44\x61\x4e\x05\x38\x36\x4c\x3d\x71\x9f\xb9\xce\x0b\x6a\x65\x5b\x63\xcb\x50\xa9\x1a\x64\x0c\x3a\x84\x31\xd1\xa0\xec\x5b\x0c\xc1\x69\x7a\xa1\xee\x20\xfc\x26\x7c\x45\x7d\x73\x86\x6f\x80\xeb\xc0\xa9\x9f\x6f\xf5\x41\xe7\xd8\x9c\xb3\x7c\x23\xc4\x6a\x69\x93\x3e\xa3\xa1\xfe\x63\xc4\x80\xcc\xd4\x2c\xf0\x20\x9b\xc1\x27\xf5\x72\x16\x9b\x46\xb4\x97\x3a\x77\x02\x39\x98\x34\xd1\x03\x1c\xba\x36\xe4\x50\x47\x3a\x6e\x01\xe8\x6a\x06\xc9\x11\x0c\xdd\x52\x66\x60\x78\x09\x2d\x83\x2e\x74\xd5\x78\xc6\x1a\xc0\x6f\xfe\x8b\x30\xd1\x00\x1b\x19\xcd\xef\x39\xe6\x1d\x43\x16\x06\x9a\x05\xe2\xf2\x15\xe8\x5c\x2a\x40\xa9\xe0\x39\x16\x19\x46\x2d\xb5\xdb\x52\xe8\x3a\xf4\x82\x0e\xd0\xd6\xf0\xcd\x4b\x18\x38\xa1\x59\x85\x25\x04\x61\xb7\x12\xb7\x26\x4c\xec\x92\x02\x8d\x47\xd2\x6e\x3e\xa2\x6d\xe5\x8f\xdf\x2d\xb7\xf6\xe6\x7f\xc2\xaf\x68\x70\xd3\x2d\x12\x67\x90\x4d\x97\x88\xc4\x9b\x69\x41\xb4\xe9\xd2\x49\x8e\x45\xb2\xca\x9a\x4e\x1f\x82\xdc\xb3\xe7\x09\xc9\xda\xc4\x0a\x83\x5a\x6f\x41\x31\x2a\x47\x32\xb8\x58\xd7\x68\x67\x87\x1c\xbf\x3e\x2b\x7e\x31\xe4\x7f\x28\x38\xe3\x42\xdf\x12\x68\xb5\x34\x02\xde\x5e\x28\xc4\x4e\xa4\xbe\x38\xe1\x49\x2b\xf5\xea\x3a\x3d\x67\x0e\xb4\xfe\x8c\x25\x12\xeb\x6e\x2e\x05\xd9\x0d\x1a\x42\xe1\x37\x61\x5d\x2f\x31\x78\xfa\xfb\xe4\x55\x97\x38\x3c\x83\x6c\x4f\xa0\x34\x41\x3e\x58\xff\x34\xc3\x0b\x1b\x5c\x1c\x11\x7a\xd2\x79\x83\x7f\xc6\x34\xe5\x21\xf9\x48\x75\x48\x33\x37\xb7\x5e\x70\x0e\x1a\x90\x55\x37\xbc\x12\x11\x84\x98\x0f\x98\x3e\x9c\xe6\x85\x1c\x2c\xaf\xa5\x1b\xf2\x80\xa6\x13\xfd\x5e\x39\x2e\x5b\xd7\x44\xf5\x6d\xba\x16\xb5\x63\x40\x61\xdb\x80\xc1\xaf\x88\x29\x92\xd8\x82\xb8\xac\xd3\x74\xce\x3c\x70\x2c\xef\xd5\x38\x37\x97\x65\xa5\x95\x91\x14\x88\xf9\x49\xae\x72\x7e\xa7\xac\x32\x50\x5b\x67\xe5\x21\xd9\xa0\x56\x34\x39\xe8\xf1\x50\x42\x28\xc9\x9b\x10\x6e\x0f\xe4\x15\x6d\xac\xe8\xd3\x7a\x87\xaf\xc6\x6a\x2d\x30\x6f\x45\xfa\x31\xe5\xd5\x4d\x02\xb3\xc9\xc3\x82\x60\xc0\xa2\x98\x25\x7e\x97\x62\x14\x61\x1d\x28\x3a\x0b\xa5\x27\x7c\x69\xf6\x7f\xa0\xda\x9c\x14\x75\x4b\x9a\x4e\xd7\xb0\xc3\x14\x45\x7c\xbf\x69\x64\x25\x9e\xc6\x48\xd4\x43\x80\xda\x2f\x9d\x5d\x1e\x2b\xd8\xb3\xf8\xba\x6c\x38\x2b\x86\xef\x9d\x43\x93\xf4\x5b\x98\xc9\xf5\xed\x91\xd3\x2f\x63\x34\xce\xc5\xf9\x92\x8a\xc3\xa8\xec\xd7\x33\x67\xfc\x83\xfd\xa6\xe3\x50\xed\xff\xb5\x1b\xc2\xdb\x06\xeb\x0b\x1d\x3f\xe8\x21\x9f\x9b\xfc\xa3\xcf\xc9\xef\xfb\x63\x35\xbb\x78\x3c\x4c\x24\xfb\x60\xd4\xc3\x96\xe6\x23\x49\x5c\x78\x5f\xd0\x5a\xeb\x83\xb7\xc2\x0f\x83\xdb\x8e\xff\xfd\x8f\xd3\xab\xd6\xb7\x25\xaf\xa6\xa1\x1a\x64\x1d\xf2\xb6\xc1\xc6\x38\x87\x21\x05\x3c\x2d\xc9\xc6\xa9\x2b\xeb\x37\x18\x64\x20\x98\xa9\xfc\xbc\x77\xc5\xa8\x4d\x29\x9b\xef\xee\xbc\x0b\x94\x77\x89\x65\xdb\xc2\xe2\x0e\xef\xef\xae\x27\x04\x26\xcf\x97\xe5\x92\xd7\xee\x9f\xb1\x4f\x3a\xce\xae\xf7\xe4\x5d\x36\xae\x58\x5d\x74\x9f\x70\xd5\xd4\xb1\x1b\x69\x9f\xe1\x97\x11\x9d\x35\x43\x9e\x41\xeb\x57\x5d\xf2\xf4\x21\xbd\x68\xea\x27\xb1\xfe\x59\x38\x6f\x8c\x0c\x55\xbc\x4b\xb8\x15\xc9\x51\x83\x14\x20\x28\x3e\x6a\xcb\xb9\x4c\xde\x60\xbe\x99\x55\x03\xd2\xcf\xcf\x03\x03\xb9\x3c\x3e\x55\xf3\xf6\xfa\x99\x7e\x19\xec\xa6\xbf\xc9\x4f\x14\xf3\x28\xab\xa5\x72\xe1\xea\xdc\x7f\x63\xee\x32\x72\x80\xf2\x9f\x7d\x4b\x31\x00\x1e\x1c\xf3\x15\xd6\x1b\x45\xd3\x26\x6f\x28\x36\xc6\x49\x9f\x4d\x9c\xaa\xfc\x8c\x1f\x99\x4e\x36\xc1\x6f\x6b\x9a\xbd\xf2\x44\xd2\xfd\x4c\x22\xfa\xdb\x3b\x0f\x9a\xb5\xb0\x05\x05\xaa\xdc\x54\x43\x64\x9f\x18\xdb\x1b\x4a\xef\x08\xe8\x83\x03\xc4\x78\x0e\x50\x6c\x30\x8b\xe9\xff\xe6\x68\xe1\x65\xc3\xe8\x60\x0a\xbf\x60\x4c\xe5\x44\x53\xff\x0f\xf3\xc4\x5f\x1e\xde\x69\x8e\x20\x9a\xe3\x95\xee\x6b\xb5\x31\x31\x19\x3f\x90\xc0\xf6\x00\xdf\xab\x34\x79\x74\x1c\x5d\x63\xe4\x85\xc1\x02\xc3\x88\xaf\x32\x05\x1d\xe8\x94\xb9\xc6\x49\x7e\xc2\x4b\xb1\x74\x2b\x9f\x24\x00\xc2\x77\x43\x6c\x9e\x8c\x3c\x9d\x22\xc3\x8d\x15\x7d\xdb\xe7\xcd\x4d\x9e\x6c\x93\x5f\xea\x9a\xc2\x53\x83\xc7\x4d\xfb\x8b\xe6\x9e\x5a\xa0\xf2\xc8\xcd\x8d\xa1\xdc\x3a\x31\xf9\x0d\x0b\x5e\xd3\x00\x8c\xf3\xd5\xdd\x35\x74\xdc\x3d\x4b\x8b\xfe\x95\xc2\xa2\x63\x52\x72\x97\x9c\x37\xae\x4e\x44\x12\x67\x03\x28\x09\x29\xa6\xec\x60\x17\xa0\x33\x08\xc0\xca\x03\x43\xbd\xc2\x2b\xb2\x9b\xca\x71\x38\xbe\xb3\x8f\xe4\xc8\xb1\x2a\x56\x80\xe4\x45\xb7\x58\xf8\x6c\xd1\x79\xb8\xde\x55\x95\xae\xdd\x21\xa7\x5d\xc3\x24\x43\x44\x24\x0d\x8e\xae\x76\xff\x4f\x5d\x6f\xd8\x61\xb0\x0f\x65\x5f\xe6\x8b\x7a\x93\x86\x8a\x5c\x2e\x8a\xcf\x75\xbb\x2d\xc6\x49\x60\x55\xff\xaa\x75\x62\x16\x5e\x56\xf3\xc7\xf6\xf9\x41\x8e\x90\xd4\xfc\xc1\x2c\x41\xd0\x56\x27\xb0\xc6\x2f\xd3\x26\xc2\x2d\xc8\x7b\x52\xf3\x55\x6f\x86\x50\x0c\x50\x21\x04\x2e\x1a\x35\xda\x6a\x43\x9b\xfe\x1d\x23\x0f\x43\xf6\xd9\x71\x5f\x51\x94\x2a\xb3\xe0\xe1\xab\x71\xf2\x77\xd7\x9f\x72\x9a\x61\xce\x31\x82\xa3\xeb\xc5\xc0\xf5\x50\xf1\x8a\xc1\xdd\x55\x2e\x46\x79\x2e\x68\x74\xf1\x87\x94\x4c\xb1\xaa\x6b\x0e\x12\x88\x21\xbf\xe5\x73\x63\x82\x35\xb9\x51\x31\xa7\x72\xcd\x65\x80\xdf\xbc\x37\xa8\x17\x03\x99\xbc\xfb\xf6\xcb\x69\x8d\x81\xc1\xdd\x25\xc4\xea\xff\xca\xa2\x8f\xe5\x51\x97\x9b\x35\x86\x31\x80\x3a\x45\xe4\x25\x3d\xf5\x0b\xae\xe4\xe2\x2d\x1d\x4a\x39\xbe\xfa\x04\xc3\x45\xfb\x74\x78\x68\x90\x62\x63\x5f\xbe\xa7\x76\x19\x98\xc2\xbd\xe0\xbe\x1e\x32\xc4\x60\x92\xbb\x1a\x26\x94\xe1\x99\xd1\x93\xd6\x0c\xc3\xf6\xe7\x76\xe7\xf2\xd3\xde\xbd\x1c\x9d\x1d\x5b\x28\x2f\xd1\x8f\xc2\xa1\x1f\x16\x1b\xdd\xf5\xc2\xed\xcf\x85\x9e\x59\x5e\x19\x90\x87\x23\xc8\x94\x26\x83\x7d\xc6\x18\x4e\xaf\x98\xf1\x13\x01\x09\x79\xe7\x8d\xc8\xad\xa3\xf7\x8e\x09\x72\x19\x02\xb0\x84\xc3\x62\xec\x91\x2e\x11\x8c\x5a\x9a\x49\x49\xaa\x4c\x6a\x3a\xdd\x99\xa5\x09\x29\xe5\xff\xaa\x73\xd8\x60\x84\x73\x46\xd5\xeb\x8d\xbe\xc7\xde\x2d\x42\xc4\xaa\xb9\x4a\xa7\x56\x61\xd6\xcf\x5a\xce\xa7\x2e\x2f\x3f\xac\xda\x08\x82\xd2\x95\x95\xc4\x70\xfa\x83\x0c\x9a\xd3\x75\xf3\x8a\xba\x29\xc3\x15\x53\xd5\x3e\xa7\x5a\x82\xb1\x80\x05\x1d\xd6\x3a\x61\xe2\x4b\xcd\x6b\xee\x46\x24\x69\x52\x43\x7d\x1e\x2d\x05\x6b\xec\x88\x01\x1c\x0c\x34\x4a\x18\x68\xc4\x08\xc5\x6a\x57\xca\x23\x1b\x20\x09\x07\x19\xc4\x72\xa0\x38\x42\x85\xd6\xd0\xaa\xae\xf6\x59\xef\x35\xc8\x52\x22\x4f\x1d\x24\x24\xb1\x9a\x71\xca\x94\x5f\x64\xe5\x84\x21\xb4\x71\xa5\xc8\x6f\x50\x94\xf8\xb3\x52\xa0\xc8\x4a\xc9\x2a\x9e\x36\xc4\xc8\xa2\x40\x19\x94\x0d\xc7\x56\xfb\x30\xc8\xb1\x6f\x69\x55\x26\x29\x53\xe9\xa5\x87\xbf\x40\xaf\x41\x9b\x2d\x55\x92\xc8\xb6\x0c\xa7\x53\x47\x59\x64\x24\xc8\x39\x0a\xb0\xa3\x6c\x80\xe7\x2c\xd6\xab\x18\x1d\xbc\xc4\x70\x3e\x83\x86\x53\xc8\x2f\x38\xe9\x79\x76\x86\x99\xd7\x29\x65\x31\x2b\x47\xd1\x93\x60\x9b\xde\x15\x33\xcf\x92\x7b\x35\x8c\x3c\x8f\x3e\x07\x74\x5a\xe5\x21\xde\xcc\xec\x73\x9a\x9e\x18\xe2\xbe\x80\xfc\x77\x99\xc2\x20\xa4\x3b\xd5\xcc\x1e\xb8\xd7\x17\x38\x63\xcc\xa6\x03\xdb\xd3\xe3\xeb\x83\x19\x60\x4d\x9b\x83\x31\x15\x8c\xab\xb4\xa7\x7f\xf9\x52\x2c\x83\xee\xe5\x6c\xf0\xe0\x2a\xc9\x03\xc5\xda\xd9\x85\x6c\x29\x29\x1d\xc0\xef\x57\x16\x28\x59\x09\x90\xd6\xcd\x79\x42\xf8\xd7\xe1\xfa\x8f\xfb\x87\xf8\x4f\xfd\x07\xe4\x0c\x19\x48\x1e\x3f\xbb\x96\x1a\x20\xa5\x7d\x88\xda\x37\x58\x3d\x63\x45\xa3\x2a\x92\x10\x7a\x8d\x81\xa2\x6d\xd0\x72\x50\xc8\xdc\x35\x24\xb8\x50\x6f\xfc\xa6\xd8\xe4\x0e\xfd\x52\xe0\x10\x5f\x74\x12\x95\xb4\x09\x9d\x46\xe5\x69\x9f\x3a\x5d\xab\xba\x1e\x43\xf9\x78\xc4\xce\xad\x4a\x8c\xc8\x29\x56\xdb\xf1\x20\x64\xb8\xc1\x41\xac\xf9\xc7\xf6\xa3\xe6\xbd\xfb\xcf\xf8\x52\x1c\x4d\xc9\xe0\xee\x3c\x12\x6e\x27\x6b\x56\x00\x06\xb3\x6f\xe8\x20\xe8\xf7\x94\x7e\x00\x43\x7d\x0a\x1c\x53\x11\x61\xfb\x03\x1d\xb1\x47\x6f\x33\x4f\x8f\x24\xd5\x40\x3a\x4a\x8a\x53\x93\x68\x35\x3a\x39\xc0\x51\x9f\xf3\x3e\xd3\x9b\x8f\x3b\x75\xbd\xe2\x33\xbd\xe8\xc4\x00\x4a\x96\x98\x58\xb7\xdc\x67\x52\x3b\x44\xcd\x2a\x5a\x76\x63\x69\xc2\xf4\x08\x46\xd6\x22\x12\xd5\xfe\x77\xb7\xbf\xa0\x61\xc5\xe4\x83\x61\x78\xe4\x5c\xda\x78\xbb\xa7\xc2\x4d\x36\xa6\xd3\x6a\x41\xc4\x2f\x9f\x75\x03\xed\x2a\x48\x57\x8b\x88\x6c\x69\x95\xfe\xcb\x99\x16\x6b\xb7\x78\xe5\x0b\x1b\xf4\x33\x49\xf6\xff\x14\x51\xd1\x3a\x18\xde\x8c\x80\x44\xb3\x7b\x19\xcc\x25\xcc\x4c\xbf\x05\xe4\x85\xf2\x0f\x25\x6b\x63\xbe\x1e\xfd\x51\x9c\xe4\x03\xef\x6f\xdd\x28\xc3\x24\x2a\x45\x8a\x33\x92\x1c\x1a\xe9\x56\x60\x3a\x30\x1c\x0d\xa7\x8c\x53\x86\x27\x37\x8d\xcf\xdc\x3c\xa3\x11\x3c\xc5\x71\xb2\xca\x79\x24\xbf\x6b\x13\x33\x0b\xd1\x05\x8d\xfb\xed\xfd\x0c\x6a\x56\xf0\xbd\x9e\xb4\xff\x00\x31\xeb\xff\x6e\xf1\xb2\x5a\xfe\xbf\xa0\x6d\x4d\x3a\xe3\x28\xe7\x90\x2a\x0a\x15\x98\xec\x4d\x48\xcd\x58\xf8\xe4\x37\x17\xc3\xaf\xe2\x36\x42\xa8\x47\xf3\xaf\x5c\xb2\x7e\x0c\xa9\x5c\x1b\xeb\xee\x56\xfc\xb9\xa3\x72\xf0\x9b\x51\x94\xd6\x63\x40\x73\x6d\x4d\x99\x5c\x8d\xf9\x06\x2d\x7f\xea\x26\x60\x9d\x6a\x4d\x06\xb6\x7c\xeb\x14\x5d\xfc\xbe\x85\xd2\x8b\x5b\xe4\xd2\xb8\xc4\xc7\x2b\x95\xb0\x74\x76\x40\x73\xae\xa1\xd6\x8a\x49\x16\x62\x6c\x2d\x3f\x8b\x00\x6f\x59\xd6\xdc\x7a\x73\x09\x01\xf2\xc0\xd2\xad\x2b\x4a\x4f\x12\xd8\xa8\xdd\x09\xcb\x15\x29\x37\x45\x26\xa4\x95\x73\xa6\xf5\xca\x7e\x71\xc5\x2e\xb6\xd8\x3e\x29\xdc\xd8\xd2\x56\x78\xff\x53\x24\xf0\xb7\xa4\x08\x4a\x4b\x7f\x3a\x5e\x39\x35\x6e\x31\xb8\x69\x4a\xd5\xe0\x10\x3e\x2e\x61\xec\x02\x41\x46\xe6\x44\xfd\xdf\x1d\x9e\xd6\x44\x4f\x47\x7c\xd5\x60\xd6\xe2\x1b\x1d\x94\xf2\x38\xee\x06\xc3\x7a\x86\xae\x0e\x74\xfa\x1f\x8c\x22\x19\x0e\x96\xd6\xad\xfc\xb9\xe3\xe6\xec\xb7\x7b\xbc\x90\x51\x86\xcc\x31\xfa\xbe\xb4\x30\xaa\x38\x1a\xf3\xe3\xe1\xce\xe5\x7b\x35\x26\x00\x1e\x60\xc0\x2d\x04\x7a\x1e\x07\xb4\xb4\x88\xbc\xcb\x2e\x20\xf3\x92\xda\xe4\xfe\x72\x70\xbe\xcc\x00\xa6\xaa\x1d\x6d\x69\x15\x23\x6d\xad\x6f\x6e\xbd\xea\xae\x92\x79\x76\x06\x62\xa9\x23\xaa\x9f\xe6\x9c\x34\xd2\xd5\x26\x1b\x4c\xfa\x45\x55\xb7\x6f\x82\x27\x0c\x4f\xb6\xd6\xe0\x79\xad\xca\x27\x3c\xec\xc5\x67\x8f\xf7\x28\xa1\x20\xe1\x88\xa5\x8c\x58\x22\x85\xfe\x70\x3d\x3e\x07\xe8\x71\x71\xe2\x9a\x5c\xb4\xba\x05\x5f\x6d\xe4\x54\xfa\x51\x40\xbd\xf1\xcb\x98\xd9\xfb\x75\x46\xd9\x37\x1a\x3b\x5b\x62\xe2\x0e\x1a\xf5\x60\x6e\xc1\x3c\xfc\xd2\xca\x9f\x67\x4b\x8e\x74\x23\x43\x63\x89\x88\x1d\x98\xeb\x4c\x04\x39\xb2\x24\x18\x8f\xac\x5c\x45\x78\xc8\x5c\xe1\x26\x13\xee\x3a\xb9\xfc\xaf\xca\x4c\x46\xde\x35\x09\x5d\x6b\x92\xd0\x52\xeb\x31\xb3\x23\x47\x78\xea\x48\xaa\x2b\x0d\x90\xf4\xf5\xce\xab\x68\x64\x9c\x1b\x3a\xac\x4a\xe0\x7f\xae\x59\x86\x31\x2d\x24\xdc\x0e\xe8\x94\xf0\xf0\x76\x74\xef\xfe\x1d\x89\x63\xc5\x03\x39\x40\x83\x7a\xa5\xd6\xb3\xac\x8c\x1c\x00\xb1\xd8\xd4\xa8\x1d\x98\x8b\x8f\x3b\x96\x1e\x0f\x89\x77\x1e\xc9\xbd\x3d\xb8\xf1\x14\xd7\xe8\xce\x60\x4e\xd4\x7a\x69\x8a\x96\x86\x7b\x00\x67\xdc\xcd\xd0\x63\xb5\xca\xd6\x3f\x6a\x1b\xe7\x2b\xbf\xc9\xc9\x64\x7c\xd0\xb5\x49\x13\x15\x1f\x80\xdf\xe3\xaa\x2e\x41\x0d\xcb\xcb\x2a\xa7\x24\xe4\xb1\xfa\x17\x54\x97\x7b\xe3\xab\x54\x17\x0e\xec\x2a\x87\xae\x14\x6b\x5f\x93\xde\x3d\x8d\x61\xac\x7d\x65\xe7\x0a\x26\x33\xe4\x9c\x49\x8a\xbe\x52\xea\x62\xff\xcc\x3e\xf6\xdc\x3f\x3f\x17\x98\xdb\x53\xa7\x48\x30\xbb\xa1\x82\xc6\x3b\xb8\x83\xbb\xe0\x95\xe4\x4e\x0f\x1c\x78\xd3\x90\xa0\x66\xb7\x62\x09\x12\xca\x5e\xaf\x3c\xd4\x70\xa3\x79\xf1\x0b\xdc\x35\x0a\xda\x31\xa6\xde\x65\x5a\xa3\xf1\xef\x4e\xa2\x2d\xc2\x1f\x7e\x45\x45\x33\x50\x7b\xb9\xfc\xde\xed\x2e\x13\xff\x21\x9a\x8b\x52\x3c\xf7\x12\xbb\x23\x1f\xc3\x9e\xd4\xc6\x3b\x6f\x8b\x31\x4e\x44\xab\x16\xdb\x8c\x8b\x8e\x30\x42\x90\x9b\xac\xb5\x7c\x3f\x75\x2d\x99\xcc\x35\x7c\x19\xfc\x4f\x59\xd8\x09\xdf\x11\x3f\xf3\x52\x4a\xeb\x7b\xe6\x7c\xe2\x9e\xbe\x89\x31\xb0\x1d\x34\xf2\x2a\x40\x55\x03\xbb\xe5\xce\xd1\x27\x49\x8e\xd2\x49\xbb\xd5\x3b\x07\xff\xb9\xa4\xaa\xd2\x2f\x38\x41\xf9\xd4\x89\x30\x1f\x24\x9d\xd3\x17\x7a\xbb\xa5\x1e\x6f\x4f\x9b\x07\xc2\x63\x17\x45\xd5\xe1\x7f\x64\xce\x91\x5b\x74\x43\x9b\x41\x39\x2e\xdb\x6d\xa3\xc5\x50\x68\xdb\xee\xac\x24\x61\xeb\xfe\x90\x96\x73\x87\x44\xec\xd6\x6a\xef\x62\x80\x58\x47\xda\x9a\x93\x23\xfd\xfe\x6d\x35\xf8\x63\xb5\x49\x80\x1d\x68\x97\xb9\x4f\x70\x21\xb7\x8a\xf8\x08\x6f\xb4\x61\x71\xbf\xea\x7e\x45\x29\x3e\x9b\xa3\x49\xfc\x39\xcc\xe2\x0b\x16\xfd\x97\x3f\x09\xea\x77\xf4\x0e\xa9\x72\x3f\xf1\xfa\x99\x20\x91\x5e\xba\xd5\x85\x04\xac\xda\x15\x95\xe1\xbe\x33\x88\x91\xf7\x4c\xaf\x38\xb8\x8e\x14\x9c\xac\xf2\x01\xbb\xd3\xd1\xf5\x95\xe1\x4a\x39\xe5\xd0\xd3\xb8\xa8\x21\x31\xd2\x1f\x32\xcb\xee\x65\x53\x56\xd1\x11\x83\xc4\x54\x22\xee\xbd\xe1\x6d\x94\xe1\x50\x11\xc9\x6f\xf6\xde\xbb\x95\x89\xe3\x49\x6b\xb2\xff\xb5\x38\xca\xae\x36\x29\xb8\xe8\xd1\x41\xb6\xdf\x27\x53\x7d\x41\x1a\x40\x1b\x66\xcd\xff\x35\xef\x69\x0b\x37\x56\xd6\xc8\x16\x62\x35\x9b\x38\x94\x59\xe3\x77\x03\x36\x40\xf3\x56\xd6\xda\xa6\x1e\xd7\xde\xf2\x42\x67\x21\xab\x89\xbf\xda\x31\x18\x7b\x57\x09\xb7\x9e\xff\x83\x42\x39\x89\x76\x90\x2a\x15\xcd\x0e\x36\x4e\x7c\x60\x48\x50\x10\x27\x0f\x6c\x12\xe5\x32\xb8\x61\xcf\x37\xd0\x30\x88\x85\x67\x1d\x82\x60\xd9\xc1\xc9\x9a\x07\x78\xde\x8d\xcc\x3a\x34\x05\x4d\xff\x9e\xea\x5b\x96\x3a\x4e\xf3\x2a\x41\xc4\xbb\x39\xf7\x05\x72\x9f\x0c\xe5\x9d\xdb\xb7\x04\x17\xd0\x3a\x18\x4b\x40\x3b\x85\xc8\x8c\x20\xf8\x51\xf6\xd3\x1d\x7c\x94\x05\xb2\xa5\xef\xf7\x1e\x45\x68\xfb\x7e\x6b\x87\xf7\xff\xc7\x9f\x83\xf7\x07\xd5\x62\xb7\xf4\x91\xee\xc9\x96\xfe\x37\x92\xb4\xf6\x62\xd2\xef\x96\xee\xaf\x68\x6c\x37\x02\xf4\x24\x9e\x5d\xf7\x8f\x10\xb0\xc1\x4e\x5c\x1f\x92\x41\x91\xf6\xae\xf3\x0e\xa2\xb1\x2f\x88\x7c\x27\x9b\xf1\xcd\x75\xba\x08\x66\x0f\x16\xd3\x57\x44\xcc\xcc\x14\x0a\x8d\x40\xec\x09\x10\x89\x4b\x38\x93\x76\x9b\xdc\xfd\x4e\xa4\x3f\x51\x70\x53\x7b\xd6\xee\x16\xc4\x46\x02\x8c\x40\x06\xfc\x21\x55\xac\xad\xac\x7f\x95\x48\x64\x4d\xfb\xfb\xb7\x77\x70\x76\x93\xd3\x68\x79\x16\xfa\x36\x80\x2e\xd8\x0d\x87\x3c\xb3\x77\x2f\x22\x0a\x06\x37\xd2\x5e\xc1\xec\x12\x83\x1b\x32\x29\x74\xf4\x25\x75\xb6\xa0\xee\x51\x39\x83\xfe\xc8\x5c\x13\x2b\xd7\xb9\x54\x19\x0b\xe9\x37\x4e\x7a\x23\x51\x7b\xf2\xa4\xe3\x12\x5e\x4c\xa3\x54\x76\xc1\x07\x6c\xe1\x00\xf3\xa1\x01\xe9\x0a\x65\xe2\xec\x20\xc4\x61\xdd\x31\x88\xe5\x73\xde\xc2\x85\x8a\x19\x3a\xde\x13\xb7\x6e\xce\x79\x28\x58\x2a\x86\x9d\x23\x6b\xe5\x09\x58\x55\xa0\x74\xe1\x2f\xed\xbf\x67\x11\xf7\xe6\x98\xed\xb1\xae\xa1\x4f\xe6\xad\xb0\x7e\x63\x3f\xc8\x60\x30\xef\x64\x24\x54\x42\xd3\x1e\xac\x3b\xb9\xa7\xac\x85\x1e\xa3\x78\xb5\xc9\xa9\xeb\x89\x04\x10\xf4\xe1\xaa\xac\x79\x17\xa2\x70\xc8\x81\x55\x10\x27\x9a\xd7\xfc\x1d\xc5\x64\xcc\x2f\x3b\x10\x25\x22\xf0\x4d\x78\x07\x1a\x73\x80\xf9\x26\x0a\x65\xd7\x35\xcb\x16\x6a\xcd\xdb\x21\x53\x20\x0f\xee\x40\x65\x91\x9b\x5a\x4d\xaa\x7f\x94\xfd\x1d\x66\x48\x20\x4a\xf3\x2e\xd3\xdd\x77\x95\xf6\xcb\x9a\xde\x68\x8b\xc9\x64\xd3\x5d\x4f\x9e\x67\xe2\x34\xbb\x24\x9a\xdd\xd9\xc9\x72\xe7\xfc\x16\x3b\xad\x61\x20\x99\x09\x19\xf5\x5c\x93\x68\x77\x7b\xbd\xbb\xf3\x0f\x83\x13\x78\xbd\x54\x49\x3b\xa1\x8e\x9b\x87\x70\xe2\x9a\x82\x39\xa7\xc1\x90\x73\xe3\xe4\xca\x94\x1e\x1a\x3e\x58\x6b\x73\xe7\x53\x2b\x47\x5d\xfe\x10\xa6\x41\x43\x55\xc9\x61\xf5\xf2\x4e\x27\x7a\x22\xa2\xa7\x51\x28\x97\x04\xb0\x9b\xbe\x37\x77\xa4\x24\x2c\x36\x6e\xd2\xbf\x1a\xe9\xa0\xec\x85\x2e\xad\x2a\x45\xc1\x50\x16\x31\xad\x91\xda\x60\xe5\x33\x18\x64\x8d\xb2\x7c\xce\xa6\x8b\xe3\xe4\x50\x5c\x36\xf8\xe0\x0e\xe9\xa4\x94\xe6\xc2\x19\xa9\x85\xce\xb5\x4b\xbd\x3f\x9c\x8d\x59\x34\x75\xb0\x54\xb9\x05\x21\x5a\x4e\x02\x9d\xa6\x1c\x00\x06\x4a\x4b\x2f\x9e\xeb\x1f\x3e\x44\xd6\x5f\xe5\x86\x87\x82\xaa\x4b\xdd\x79\x8c\xed\xa7\xf3\xb1\x04\x9b\x7e\xa9\x3d\x99\x66\xa9\xf9\x08\xfa\x5b\xcd\x94\xad\x05\x5f\x8f\xae\x47\xca\x22\x5b\x76\x9f\xb3\xe3\xaa\x94\x29\x6a\xb3\xac\xa4\x47\x80\xb7\x07\x09\x56\xde\x95\xb5\x6c\x71\x05\xa2\x4c\x5a\x53\xad\x0e\xe6\xb2\xa6\x03\x1a\x40\xff\x39\x3b\x2f\x7c\x86\xec\xd3\xe5\x1a\xce\x5f\x38\xeb\x8e\xbc\xb6\xa2\x10\x0c\x0c\x86\x58\xe8\xcc\x25\x38\x72\x98\x1a\xf6\x46\x00\x0d\x1b\x77\x12\x8b\xc3\x59\x76\x3c\x30\x24\xe9\xe9\x1d\x64\x8d\xf2\xcf\x52\x08\x46\x08\xfc\xdd\xc0\xe2\xb8\x00\x4f\x02\x7d\xd3\x6d\x17\x89\x2e\x6f\xba\x68\xbc\x0b\xdc\x6a\xdd\xe7\xfa\xd0\xca\x1f\x4b\x69\x89\xe4\x09\x00\xb2\xc6\x96\xc8\x67\x05\x9f\x0f\xb3\x00\x93\xe3\xbc\xf3\x38\xf2\x54\x36\xf0\xf3\x32\xca\xda\x13\xe2\x78\x7a\xad\x38\x2f\xbf\xd8\x28\x5c\x9d\xee\x25\x8c\xd7\x01\xc8\x2f\x74\x3a\xa0\x58\x96\x4c\x81\xb5\x0a\xfd\x2d\x66\xdc\x92\x0e\xd0\x8d\xe3\xbd\x01\x21\x4e\x44\xc0\x4e\x9a\x00\x29\x70\x12\xcd\x6f\x09\xba\x9f\x5f\x90\xb5\x0c\xa3\x78\x86\xe3\xd7\xdb\x28\xf9\x22\x35\x06\xb0\xfe\x94\xc5\x40\xa1\x34\xaf\xfa\xff\x40\x3a\x61\x28\x03\xee\x48\x8c\xb3\xfd\x95\x9d\x3d\xdf\x3f\x68\x54\xb8\xc9\x52\x50\x02\x7d\xd2\x37\x4c\x8e\x1a\xc9\xd8\x7f\x79\x6f\xfd\xff\x3b\x05\xa6\xff\xa8\x90\xfa\x97\x3e\xcd\x3f\x7b\x03\xa4\x00\x4a\x95\xf8\x2f\x59\xb3\x7d\x39\x60\xec\x08\xfe\x48\x99\x2b\x30\x2d\xe3\x8d\xeb\x9f\x8f\xcd\xf8\x5f\x4d\xf2\x94\xef\xbd\x39\x31\xd0\x3b\xd0\x00\xfb\xf7\xa6\x74\x4e\xb0\x49\x0b\x15\xf4\x40\x7d\x94\xa0\x6c\xf1\x19\xf2\x2c\x94\x64\xbf\x3c\xdf\x4a\x35\x46\x54\x3a\x31\x4c\x30\xf7\xb4\x41\xa0\xe1\xa6\x73\xce\x7d\x84\x4b\x11\xa6\xc4\xfc\xcd\x9a\xef\xf5\xec\x1f\xa9\xf3\xfd\x64\xec\x83\xc0\xa3\x48\x56\x06\xf9\x38\x66\xaa\x4b\xcc\x2d\x7b\x5c\x6e\xae\xc1\xa8\x9e\xeb\x9b\x86\x48\xd6\xb3\xa9\x6b\xf0\xf8\xee\x73\x0a\x13\x25\x6f\x94\xe7\x2a\x57\x5a\xfb\x76\x64\xa4\xc4\x9f\x08\x63\xba\x6e\x43\x84\x49\x9d\x88\x41\x38\x45\x90\xc9\xc8\xa4\x08\x0e\x32\x12\xb5\x1e\x76\xb8\x34\xcf\xf5\x69\x35\x1f\x0f\xf3\xec\xd7\x43\xf2\x59\x9d\x9e\x4b\x77\x55\xea\xc9\x8f\xf3\x9f\x4c\x3a\x67\x18\xf3\xf1\x20\x6e\xa5\xdc\x3d\x94\x20\x4e\x16\x5c\x41\x5e\x61\x59\x83\x85\xb8\x0e\xe4\x05\x0e\x91\x93\x32\xe7\x8f\x47\xd2\xe7\xc8\xe5\x35\x10\x64\xbc\xeb\xf6\xa2\x33\x17\x61\xca\xe9\x6c\x4a\xcc\xc9\x4e\x72\x3b\x52\xa5\x0b\x90\xc4\x57\xf4\x6b\xa1\x7e\x35\xf1\xa8\xd5\x72\x75\x98\x73\x18\x32\x5d\x61\xa4\x67\xb8\xc4\x4a\x1f\x66\xce\x98\x1c\x22\xe7\x70\xdd\x82\xc5\x69\x57\xd8\xfd\x9e\x70\x01\x6d\x09\xa2\xa1\x32\x44\x66\x06\x6f\x66\x7b\x63\x99\x54\x03\xf5\xbc\xf4\xcf\x59\xc2\x63\x65\x4e\x1f\xb6\x54\x06\x94\x1e\x39\xff\x74\x80\x90\xd9\xb3\x26\x3d\x7f\xab\x1d\x74\xab\x12\xd4\xf1\xb4\xad\x8d\x71\xc8\xcf\x6b\x74\xa5\x4a\x3a\x43\x8a\x0e\x0c\xb8\x85\x2c\x31\xdc\x21\x53\x71\x57\x30\x16\x33\x10\xf1\x9b\xd2\xd6\xc8\x1f\xdc\x82\xa9\xb8\xe5\x60\x3b\xba\xcf\x8a\x23\xab\xd6\xc9\x67\x7c\x8a\x0d\xf8\xd4\x26\x0c\x39\x5a\x29\xa3\x29\x0c\xfa\xe2\x72\x13\x63\xda\x10\xf5\xda\xbd\x2c\x2d\x28\x84\x12\xb1\x7e\xde\xcf\x67\xe6\x5c\xa9\x8d\x9f\xa0\x2e\x48\xbb\x25\x60\xab\x81\xab\x30\x7d\xe8\x9f\xf7\xc4\xa8\xc8\xf3\xee\x46\xd0\xcf\x3b\x4c\x8f\xda\x4d\x52\x9f\x63\xf1\xc8\x5a\xe9\xe4\xbd\x2c\xcf\xa7\xcc\x2c\x99\xa7\xe7\xd3\x8a\xb7\xa5\x2f\xe0\xd9\x72\x90\x05\x39\xb2\x71\x6e\xa0\x58\x88\xcd\x95\x46\x88\xc0\x35\xda\x04\x75\x78\xcc\x03\x13\xcc\x41\x21\xec\x8e\x92\xc0\x22\xa8\xc1\xf2\xfb\x43\x5e\xe0\x1d\x22\x06\x18\x57\x60\x0a\x88\x66\x54\xb5\xc5\x5d\x83\xc8\xa5\xc0\xb4\xec\x9a\xe2\x7b\xba\xd4\x33\x57\xc3\x89\x8a\x26\x4a\xee\x9a\x21\xee\x62\x45\xc4\x84\x4c\x42\x6f\x90\x9f\x35\x1e\x08\x48\x84\x97\x1d\x75\x16\x3e\x15\x61\x00\xe6\xe5\xc9\x48\xe3\x59\xe5\x82\x95\x7f\x2e\x56\xbc\xb8\x1c\xd7\x36\x65\xfe\x0a\x6e\x2f\xf1\x8f\xe7\xca\x00\x97\x95\xbf\x1f\xdf\x27\x88\x9f\xab\x7c\xb7\xec\xb9\x4e\x2c\xd5\x87\x78\x16\xdd\xbd\xd2\x2b\xac\x67\x97\x92\x7e\x96\x20\x2c\xe6\xb3\xfb\x3c\x63\xe6\x80\x57\xa2\x7b\x58\x06\x51\x85\x9e\x05\xfa\x8d\x94\x54\x72\x36\x63\xb2\xee\x16\x04\x79\xb9\x4c\xb9\xe2\x67\x37\x06\x06\x4a\x9a\x3a\x7f\x66\xc5\x8e\xec\x84\x90\x49\x22\xf2\x20\x9b\x95\xb2\xcd\x33\x94\x98\x5f\xfd\x8c\x3a\xf4\x89\x29\xc4\xec\x99\xb9\xc8\x03\x4d\x17\x0d\xba\x62\xc2\xe3\x19\x96\xf2\x4f\x70\xad\xbc\x84\x95\x20\x0f\x21\x36\xd3\x13\xb1\xdb\xff\xc8\x69\xdc\x45\x6a\x3c\xc9\x4d\xbc\xde\x9c\xb8\x7f\xa6\xab\x5b\x6d\x49\xb7\x05\xe2\x95\xe2\x34\xb6\x46\x59\xb9\x27\x2c\xd9\x58\x96\xa0\x3d\x2a\xa4\xf5\x84\x6a\x03\x5f\x32\xfb\xb0\x99\x3d\xe5\xc8\x4b\x90\xc9\x49\xd6\x4c\x13\x87\x0e\x06\x2a\xd3\x6a\x1e\xb7\x52\x30\x1e\x91\xc5\x85\x29\x0b\xd6\xd2\x8f\x7b\xb9\x49\x4b\xfc\xb8\x4b\x18\x26\x91\xc3\x02\xcb\xbd\xb9\x4a\x47\x01\xc2\x3f\xaa\x61\x74\x27\x7d\x13\x5b\x90\x25\x16\xd2\xd7\x68\xbb\xd5\x92\xa7\x71\x3f\x7a\x1e\xd8\x83\xef\xee\xa3\x8a\xca\xd8\x94\x54\x0d\xa6\xa3\x7f\x08\x0f\xa7\xae\xd0\x91\xab\xca\x52\xca\xc0\xb3\x93\x1f\x45\xc9\xac\xa1\x7c\xf3\xa8\x24\xae\xf9\xf5\xac\xf2\xfc\x7b\x90\x57\xc2\x53\xda\xe3\x0c\x50\x68\xc8\x75\xf1\x15\x70\x7c\x86\x71\x3f\x2c\xbd\xc4\x72\xdc\x95\xda\xf7\x88\x2c\x4b\xe2\x7e\x4a\x3e\xe0\x87\xdb\x2e\x28\x8b\xc6\xc9\x8c\xe1\xd8\x45\x9f\xa7\x07\xfa\xbb\xe7\xe9\xb7\x3f\xaf\xf2\x2f\x33\x40\xfe\xa2\x8d\x19\x75\x60\xf0\x40\x58\xf2\x51\xe1\x4d\xe0\xed\x4b\x1c\xb9\x3c\x5c\x32\x33\x85\x91\x17\x7f\x61\x8f\x23\x88\xd9\xc8\x5d\x0b\x18\x7d\x8a\x96\x3d\x42\xa2\xde\xc0\x93\x49\x19\x8f\x34\x8a\x06\x23\xd1\x8f\xfc\x1e\x48\x42\xc8\x2f\xb9\x7b\xbd\x34\x9b\x9e\x31\x7d\x2c\x6e\xe4\x3b\x18\x91\xa2\x3a\x52\x91\x2c\xbb\xe0\x6f\x78\x82\xdd\x57\x11\xea\x04\x45\x98\xaf\x2a\x2e\x04\x9f\x8a\xae\x4d\xd9\x7b\xc0\x99\xc9\xac\x3e\xd2\x9e\x83\x21\x39\x50\xa1\x3f\x6b\x06\x3f\xff\xf4\x09\x5c\xf5\x57\xdf\x92\x14\x80\x49\x54\x04\xe1\x57\x9e\x64\xe0\x82\xd2\x2a\xec\xb7\x1b\x26\x5d\x91\x2a\xff\xe5\xc2\x48\xd1\xf1\xa0\xb3\x83\xf6\x26\x60\x7d\x24\x19\x10\xe7\x99\x99\x52\x19\x2f\x97\x7c\xca\x9e\xe1\x2f\x66\xdf\x50\x18\x8e\x85\x20\x6d\x8e\x09\x82\xcc\xe1\x51\xfe\x71\xa3\x9d\x59\x29\xda\xdb\xbb\xc4\x93\x98\xde\x6c\x6e\x27\xd2\xd0\x4e\xc1\x24\xa1\xe9\xe9\xd6\x10\x68\x92\xb1\xca\x74\x33\x3a\x39\x59\x5b\xba\xf0\x67\x4f\xe8\x97\xd2\x72\xcc\x7e\x95\xb8\xe5\xd6\xdf\xa7\x81\x3c\x40\xf4\x16\x0d\x8b\xf4\x67\x2f\xd4\xb3\x92\x45\xf9\x26\x6b\x4f\xce\x4f\x53\xfd\x91\xf3\xea\x3d\x91\x7a\x89\x04\x7c\x17\xc4\x81\x85\x19\x8b\x33\xee\x10\xb8\x9a\xac\xb9\xa7\xda\x19\x97\x7e\xfd\x8e\x10\x4d\x5e\x02\x3d\xbd\x35\x9b\xa2\x67\x3c\xc9\x99\xab\x0e\x54\xbf\x9f\x8a\xc4\x3b\xa6\x88\x7f\x4d\x45\x29\x78\x53\x81\xf2\x27\x57\xc5\xbc\xe1\x64\xf5\x1c\x7f\x77\x59\xc5\xef\x5c\x11\x95\xd0\x6f\x2d\x41\xf5\x5c\x74\xf0\xe7\x33\x40\x06\xd1\x88\xb4\xc6\xd2\x3d\xd5\xf4\xd9\x41\x0f\x8a\x7d\x86\xa9\x88\xf8\xb0\x65\x2e\x26\xb1\xb2\x60\xb6\x46\xea\xa8\x7d\x2d\x22\x51\x5a\x7b\xa3\xa8\x97\xfd\xb6\x3e\x7f\x80\x89\x74\x9f\xc6\x10\x1d\xb2\x91\xa0\x79\x24\x37\xf5\x07\x10\x0b\x14\x2e\xd3\xba\x29\x39\x42\x65\x40\x34\x79\x84\x95\x85\xec\x95\xad\x46\xa5\x0b\xc0\x7f\xe2\x74\x66\x81\xb3\x95\xaa\x0d\xd0\xeb\xe1\x6e\x1e\x28\x12\x52\x18\x6b\xca\x7f\x56\x49\xfa\x1d\xca\x9d\xf9\x9a\x9f\xc5\xcd\x21\x85\x27\x21\x18\x2f\x8a\xd3\xf9\x90\x5b\xdb\x08\x83\x34\xf2\x50\x9d\xab\xa2\x59\x11\x30\x3d\xb3\x12\x04\x27\x5a\xdd\x4e\xe9\xfe\xfa\x84\x86\xf3\x3d\x7f\x43\x16\x79\xab\x4f\x89\x6e\x73\x36\x54\xe6\x74\xc3\x64\x37\xf7\xae\x7c\xec\x21\xcb\x36\xb9\xe7\x34\xef\x06\x3c\x47\x78\xdc\x95\xcf\x83\xb2\x16\x53\x1a\xe5\x99\x46\x97\xba\xf1\x26\xe1\x11\x53\x78\x74\xad\xe2\xcc\x50\xd0\x28\xef\xd1\x19\x0d\xce\x5c\xbb\x07\x9f\xe3\x86\x18\xdc\xc6\x72\x22\x85\xb3\xbe\xbb\x8b\x1a\xb3\xe6\x47\xd7\x02\x26\x71\x10\x73\xb9\x31\x30\x1b\x9b\xe4\xff\x47\x06\x22\x46\xf5\x57\x41\x09\xbd\xc2\xce\x0a\xf7\x45\x4d\xb2\x61\xcd\x08\x8c\xd6\x4c\x66\x71\xef\x5a\xb8\x98\x41\xac\x96\x36\x25\x63\x45\x54\xa2\x33\x3d\xaf\x8b\x9c\x54\xa8\xfa\x91\x15\x2a\xe9\x38\xb8\xb1\x05\x3a\xe4\xe2\x55\x8f\x24\xaa\x27\xdf\x4e\x2b\x27\xd1\x3b\x2f\x8a\x5f\xc1\x91\x4d\xac\xd1\xdf\x4c\x27\x30\x7b\x02\x86\x7a\x5d\x05\x4e\x68\x13\x13\xf4\xd2\x76\xd0\x33\x13\x63\xb2\xae\xa1\x37\x62\xf0\xa1\xab\x05\x67\xa7\xf1\x56\xba\x14\x15\x79\xab\xf1\xc3\xd7\x5f\x87\x19\x73\x16\x27\x4b\x0d\x85\xc7\xb5\x7c\x5d\x61\x0c\xba\x84\xec\xe0\x8f\xab\xeb\x0d\x76\x58\x3b\xbe\xcf\x20\x8d\x26\xf2\xf1\xe0\xeb\x26\x3b\x3d\x28\x4d\x86\x59\x5b\x01\xab\x33\xc6\x19\xf6\xfc\x49\xf3\x1e\x3b\xb5\x65\x2c\x1b\x88\xb4\x7e\x43\x4a\x0a\xa3\x02\x91\x48\x49\x3c\xe2\x42\x30\x5b\x67\x0c\xe9\x48\x34\x2d\x5f\x86\x81\x91\x54\xb6\x97\x91\xdb\x96\x4e\x77\xb2\x9f\xff\x92\xd3\x04\x60\xa7\x99\xca\xfe\x0f\xe3\x57\x92\x50\x23\x3b\x70\x74\xb7\x5d\x82\x8d\xc5\x5a\x9e\xf5\x0f\x30\xaf\x39\xb8\x39\x63\xfa\xc8\x35\x2d\xc8\xa3\xaf\x14\x49\x0d\x23\xbe\x34\xf9\xda\xa5\x6b\x13\x6f\x38\x79\xce\x32\xf7\x95\xea\xe6\x98\xda\xdd\xd9\xa5\x37\x74\x0b\x09\xe1\x34\x21\xf4\x23\x9c\xb6\x7b\x10\x5d\xb5\x31\xad\xc9\x50\xa5\xaf\xcb\xe8\x59\x0d\xfa\x02\x12\x74\xbf\xb5\xe5\x8f\xbb\x3a\x24\xd1\x5e\x8f\x10\x5e\x1a\xa9\x4f\xf2\x9f\x98\xa9\x41\x26\xdd\x82\x54\xed\x39\x6a\x55\x3f\x68\x2b\x3a\xd0\x96\xff\x04\x92\x72\x63\xc6\x54\x4e\xd9\xd2\xd9\x23\x3e\x0e\xfe\x7b\x18\xa0\x59\x66\x9f\xe0\xc2\xc5\xe4\x11\x08\xe7\xad\x92\x1e\x26\x57\x9e\xe1\xfe\x9f\xa2\xca\xc3\x1d\x72\x45\xfe\x02\x04\x0b\x18\x6f\xde\x99\xb5\x7a\xef\x02\x13\xe0\xa3\xfe\xbb\xf0\x24\xcb\xb4\x5c\x8d\x1e\xe0\xc3\x9d\x49\x6d\x83\x28\x48\x27\xa3\x26\x71\x51\x17\xfd\x72\x50\x51\x87\x12\x3c\xcb\x7b\x14\x67\xf4\x3e\x3b\x3b\x75\x3f\xaf\x4e\x46\x2d\x9a\x06\x76\x87\xca\x7a\x93\x3b\x5a\xeb\x26\x16\xa9\x12\xd1\x00\x26\x1e\xa7\x8e\xdd\x48\x2e\xaa\x7a\xa0\xa0\x2d\xe2\xbd\x0c\x9a\x6a\xfe\xb2\x33\x6b\xe8\x0c\xcf\xb8\x1f\x27\xd0\x30\xc5\xe6\x86\x16\x33\xab\x30\x90\xd3\x61\x32\xb7\x8f\x38\x08\x4c\xe4\xee\xe0\xbc\x42\x40\x9e\x04\x72\x60\x5d\x60\x8a\x90\xb3\xc1\x60\x29\x3a\x31\x41\x80\xd3\x14\xe2\xc6\x0e\xe2\x7d\xca\xde\x7e\xa8\xff\x0b\x8a\xeb\x9b\x41\xe1\xa1\x86\x21\x1a\xc8\xdd\x62\x44\xd6\x2e\xf0\x45\xfb\x39\x12\x61\x2f\x49\x27\x0c\xd2\x41\xb6\x92\xd9\x58\x00\xa1\xff\x09\xe9\x17\xde\x2b\xa8\x4f\x88\x6a\x6b\xd5\xd9\x47\x20\xac\xee\xd0\x35\xe1\xf3\xa8\x0a\x75\x0e\x35\xec\xf8\xea\x1a\x6e\x76\x85\x3d\x7f\x03\x6b\x5c\xe5\xbc\xeb\xe4\x73\xf8\xd9\x75\xbe\x72\xb0\xe3\x01\x82\x30\x49\xcf\x98\x61\xfd\x90\x3e\x5c\x5e\x52\x50\x03\xa1\x8e\x25\xc7\xba\x70\x8a\xbe\x44\xcb\x55\x70\x1f\x14\x58\x8d\x46\x86\x22\x1d\x78\x03\xb3\xec\x3d\xc1\x7d\x4d\xc1\xc6\xfd\x35\x52\xe4\xb8\x0a\x90\x9c\xc6\x0b\xce\x8a\x7d\x1b\x08\x2f\x38\x4d\xd0\x83\xd6\x5e\xc9\x7b\x6d\xfb\x15\x5b\x85\x81\x1b\xec\x85\xd4\xa0\x0e\x68\x8a\xdf\x04\x4f\x5a\xbf\x58\x3f\xe2\x23\xbe\xeb\x27\x9c\xed\x38\x4b\x35\x60\x16\x4e\xc7\xda\xe9\xf4\x97\xe5\xd2\x01\xfa\x6b\x8a\x04\x3a\x58\x83\x51\x90\xc2\x4d\xc2\xc8\x1c\xed\xa9\xd1\xc3\xef\x0b\xcc\x4f\x99\xaa\x19\xe2\xa9\x1f\xec\xd1\x0e\xb4\x00\x02\x83\x53\xb7\x60\x9a\xe2\x5a\x7e\x5f\x2b\xcc\x35\x4e\xf1\xbd\x81\x83\x9d\xab\xa1\xff\x90\x3e\x2b\x99\xb3\xb4\x02\x1e\xe4\xb2\x63\x65\x50\xb6\x53\xf4\xe7\x07\x6a\x04\xcb\x84\x0e\xb7\xb9\x3b\xea\x59\xe3\x1d\x37\x2b\xb1\x66\x1b\x10\x38\xd4\x85\x59\x45\x1d\x46\x79\x56\x4d\xaf\xb4\xab\x0b\xa2\x75\x6a\x32\xab\x83\x8e\x15\x59\xb0\xa8\xa3\xf8\x13\x13\x85\x74\x87\xb4\x9e\xac\xb5\x9c\x6c\xab\xb7\x03\x7e\xde\xa2\xf4\xae\x52\x35\xb0\x1a\x54\x84\xac\xc1\xdd\x3e\x89\x46\xd6\x3b\x70\x83\x61\x39\xfa\xc1\x92\x52\x96\x90\x78\x12\xb6\x6f\x9c\x56\x01\xc9\x5b\x8e\x77\x77\x37\xb9\x43\x2e\x84\xd3\x42\xaf\x51\x39\x16\x98\x62\x41\x61\x75\x76\x63\x52\x00\x1e\xe9\xca\xfe\x27\x6c\x7a\x78\x30\x1b\x13\x87\xdf\x80\x4f\x82\x0e\x91\x31\x8f\x9c\x99\x91\xf4\xdb\xb4\x7b\x1b\xe1\x4e\x78\x7a\xa3\xe0\x6b\x02\xa1\x39\xde\xfc\x84\x04\x43\xb2\x5d\x3d\x37\x47\x74\xdb\x5d\x1c\xd6\x9d\xaf\x2d\x14\x49\xe5\x9f\x37\x35\xfd\x67\x6a\x1c\xaa\x00\x65\xa9\x78\x28\x07\x0e\x71\x43\xfd\xcb\xda\xc7\x27\xad\xf4\x3e\x3e\x27\x02\xfa\x6e\x7d\x39\xc8\x2b\x55\x27\x3c\x34\xeb\xbb\x6d\x49\x77\xce\x3a\xf6\x34\xb8\x73\x0d\xc0\xda\x1e\x8e\xed\x3c\x8c\x8f\xdb\x80\xbf\xbc\xb4\x01\xd3\x04\xad\x3c\x3c\x81\x2a\x95\x5f\x7b\x95\x58\x8f\xa7\x42\x6b\xfa\x34\x33\xaa\x0c\xa2\xaf\xf7\x46\xd3\xb3\x69\x4a\x17\x6e\x57\x9a\x09\x48\xd9\x7d\x48\x82\x0b\xac\x18\x27\xba\xf4\x8a\x95\x25\xeb\x66\x7b\xda\x50\x1a\x17\xa6\xf2\xcb\x69\x3f\x0d\x13\xc6\xec\x9b\xeb\x17\xdb\x4b\xe7\x47\xe3\x2c\xd8\xb7\x36\xb5\xea\xdf\x48\x94\xfa\x76\x6d\xaa\x2f\x67\x3a\xbf\xe5\x78\xd0\xb0\x0f\xb3\x3c\xe4\x7c\x7e\x0b\xfd\xfa\x38\x34\xfb\xb2\x8f\x6c\xcf\x8e\x93\x64\xdf\x14\xdc\x5e\xa9\xe4\x7c\xed\x49\x36\xfe\x67\x24\xc1\xe6\x8b\x39\xea\xe8\xfc\xd9\x42\x84\x2d\x3f\xdf\xff\xbb\xad\xcd\xf2\xa7\xe5\x69\x50\x5f\xaa\x49\x7e\xa8\xf0\xf7\x29\x3d\x4c\xf1\x89\x7a\xed\xc3\x59\x00\xe7\x02\x53\x6a\xc6\xe0\x12\x8e\x7f\x5b\x22\x81\xe3\xa3\x58\xfa\x27\xc1\x44\x54\x3c\xe0\x0f\x93\x3f\xde\x6c\xb6\xde\x61\x77\xd7\xbe\xf9\x8c\x0b\x7a\x37\x1f\xbe\xbd\x5b\x67\xe1\xda\x10\xfa\x26\x63\x37\x06\xd3\x4e\x21\xe6\x07\x49\x36\xb1\x03\xe5\x3d\xc1\x1a\xb0\x5b\xe0\xd9\xbd\xf5\xfc\xc7\x67\x5f\xd4\x01\x56\x65\xe8\xbf\xa3\x87\xfe\x56\x8f\xe9\x5d\x82\xab\x5b\x9a\x12\xc2\xdf\x1e\xf4\xda\xb5\x83\x2d\x74\x04\x41\xaf\x22\x18\x5a\xc2\x6f\xa5\x88\xbd\xd1\xde\x64\x91\x8a\x83\x7c\x09\x16\xb2\xbe\x77\x30\x8d\xf5\x25\x02\xe6\xed\x94\x87\xe0\xba\xd4\x93\x3c\x66\xe8\x90\x2c\xdc\x76\x91\x47\x61\x90\xa8\x8b\xc8\x27\x00\x39\xd0\xef\xdd\x7c\x97\xf0\xf8\x7e\x43\xcd\x99\x74\x65\x64\x15\x74\xed\x7f\xb0\x92\x65\xc8\x0f\x56\xf2\x1e\x2b\x25\xaf\xfe\xee\xa4\x7e\x43\x13\x09\x54\x86\x12\x33\xb7\xdf\xca\xc9\x78\x5b\xeb\xd7\x6d\x0a\x7d\x4c\xef\xcf\x29\xff\x04\xf4\xc1\xf4\x6d\x0c\x6c\x3a\xe9\xd7\xcb\x6e\xf1\x98\x8b\xc6\xc7\x20\x29\x2f\x34\x1a\x05\x0d\x39\xa8\xc9\x59\xbe\x88\x9e\xe4\x26\x1a\x17\x2c\x08\xc7\xb0\x20\x9c\x28\x9a\xec\x8c\x63\xf6\xb5\xe1\x3d\x18\xef\xb9\xe1\x91\xd3\x9b\xef\xa4\x2a\xf1\x9d\x94\x65\x61\x40\xc3\xa2\x77\x9a\x74\x57\x5f\xf5\xbd\xca\x73\xb0\x6d\x9a\x6d\x79\x61\xac\x47\xa2\x70\x9d\xc9\x1d\xf6\xbd\x5e\x48\xc3\x71\xca\xaf\x98\xd8\x2f\x99\x05\xb9\x00\x85\xd7\x37\x1e\x94\xd8\xf3\xfd\xea\x0b\xae\xb5\xfc\x5b\x62\x75\x04\xb1\x36\xff\x8c\x5e\xc5\x46\xae\xce\xb9\x2d\x49\x07\x90\xe9\x60\x0b\xf5\xaa\x97\x8c\x80\x5e\x56\x73\xfb\x3d\xc0\x54\xb3\xc0\x2a\xca\x32\x59\x81\xaf\xac\xe4\x9a\x57\xd2\x06\x68\x3b\x76\xb1\x7b\xe1\x7d\x2f\xc6\x6f\x1b\x82\x69\xfc\x66\xa2\x10\xc2\x6c\xe1\x57\x68\xbb\xd4\xe0\x30\xef\x08\xbd\x68\xd3\x2d\xa5\x3d\x78\xc5\x73\x37\x30\xb4\xe7\xa4\x83\xee\xa4\xc8\xbf\xd8\x3a\x04\xed\xb8\xb6\x43\x28\x87\x2e\x0e\x59\xca\xaf\xac\x6c\xb0\x4e\x5a\x5e\xaf\xbe\x34\x57\x17\xa4\xe4\xc2\xd0\x1d\x14\x07\xa4\x5b\xe8\x10\x78\xfc\x25\x08\xd0\x49\xba\x8c\x70\x4e\x64\x1c\xd6\x17\x8a\x38\xcf\x9a\x9b\x73\x25\x75\xf5\x8b\x40\x53\xf0\xde\xf0\x2d\x61\xee\x1b\x59\x45\x2c\x33\xf3\xa8\x7c\x52\x9c\x79\x82\x12\xe7\xbf\xc3\x4c\xf7\x92\x1a\x0a\x5c\x43\xfc\x82\x2e\x7b\xe7\xb8\x06\x13\xe5\xce\xf0\xbd\xd3\x97\x6b\xc0\x66\x16\x63\xd9\x0d\x6f\x2e\x62\xf2\x8c\xbd\xb9\xd6\xaa\x3e\xe9\x7a\x49\x0e\xf3\x6a\x91\x66\x77\xd5\xaf\xca\xff\x05\x13\x19\xe4\xd1\x51\x5c\x64\x0e\xa3\xaf\x7a\x54\xf9\x29\x1b\x2c\xe4\x19\x33\x55\xdf\x4a\x38\xa9\xf8\xf5\x54\xba\x8e\x21\x07\x97\x26\x87\x55\x2c\xe7\xcc\xc4\x2e\x6b\xfe\x55\x75\x5d\x4e\xa3\xcf\xb4\x66\x74\x9a\x71\x95\x9e\xb9\x2d\x6d\x4a\xd3\xbb\x66\x48\xbe\xf9\x8f\x99\xb3\x4c\x39\xf0\xed\x16\x19\x33\x26\x89\x12\x80\x8c\xcc\x2a\x1a\xce\x8c\x02\xed\x4b\x22\xf2\x0e\xef\x19\xd2\x94\x6d\xe4\xcb\x86\xf9\xca\x59\xee\x8c\xc9\xe7\x14\xae\xae\x58\x72\x61\x2e\xa9\x90\x6c\x1c\xf7\x3d\x29\xb3\xe7\xf2\x14\x45\xef\x0f\x5f\x49\x29\xaa\x20\x2c\xeb\x61\xa4\xee\x33\x74\x61\xe0\xfd\x21\x90\xa8\xce\x15\x19\x62\x34\x67\xe4\x56\x83\x68\xa8\x5f\xfb\x66\x9f\x1f\x27\x7d\x7d\x90\x07\x4b\x6e\x33\xe2\x5b\x0b\x11\x7c\x1e\xc2\x92\x0f\x72\x0b\xe1\xb1\x98\x3e\x7c\x76\x86\x68\xf6\xf7\xb2\xd6\x94\xac\xe7\x4b\x8e\x9f\x27\x0c\xd9\xbd\xa4\x61\xe0\x4d\x53\x51\x2b\xc9\x22\x75\xd1\xf2\x08\x01\xfa\x92\x76\x23\x3d\xe2\x44\xa0\xc3\x83\x39\x27\x0c\x08\x50\x5e\x37\xa7\xcd\x0c\x1c\xf2\x3c\x14\xe9\xb7\x1b\x13\xa0\xfa\x14\x9b\xb8\xd5\xb9\xaf\x63\xa6\x23\x4d\x19\x83\xe9\x8c\xfb\xcd\x73\x5f\x6e\x8d\xce\x53\x1c\xe9\x16\x55\x99\x31\x47\x67\x36\xb3\xdc\x36\x59\x40\x6e\x72\x56\xbb\xfe\x6e\x65\x30\xda\x67\x4b\xfe\xdf\x85\x50\x34\x6f\xe3\xd5\x2d\x18\x73\x30\x6c\xfb\xfc\xaf\xa1\x43\x53\x60\x06\xb7\xa0\x49\xc7\x44\x14\x51\xec\x83\x26\x85\x9c\x53\x77\x7e\x94\xd9\xdd\x35\xda\x37\xf8\x3f\xa2\x19\xe4\x10\x51\x99\xef\x6e\x31\xee\x8d\xbd\xa8\xd0\xd6\xa2\x75\x63\x3d\x2c\x91\xd6\xa7\x86\xf3\x3c\x10\xda\xe4\x3e\x07\x19\x53\x7e\x15\x56\xe7\xdc\xec\x07\x1b\x0c\xab\xcc\x23\x7f\x44\x11\x3d\x7a\x35\x66\xd0\x86\xfd\x8c\x15\x1a\xee\x0f\x03\x9e\x47\x37\xb7\xf5\xb7\x30\x68\x96\xd6\xb5\x25\xcb\xf9\xcd\x67\x55\x6f\x25\xb8\x9d\xd5\xd5\x88\xe8\x39\x07\x57\x7c\xfe\xbb\x89\xe6\xbc\xc7\x56\x5b\xd5\x5b\x0b\x5f\x4a\xf2\xa7\x29\x2a\x74\x56\x76\x1e\xfc\xb5\xd8\xad\xd2\x3f\x05\x16\x01\x52\x5d\xf7\xda\x0d\xa9\x4f\xba\x7c\xf8\xc8\x43\xa3\x9b\x13\x69\xb2\xe4\xd8\x6f\xf4\x2a\xdc\x52\x74\x6e\xad\x9f\xf0\xa3\x78\xae\x9a\xdd\x32\x40\x93\xc4\xe8\xa1\x9d\x4b\x15\x77\x7d\xf1\x04\x90\x13\x44\xf1\x44\x00\x91\x56\x32\xa3\xdf\x7c\x01\xca\x6f\xb8\x78\x22\x2a\xc9\x52\x2f\xa4\x55\xfb\x07\x47\x6a\x67\xb1\xcb\x0a\xd2\xf4\x46\x65\xd4\x13\x49\x5f\xb1\xab\x3b\x58\x2a\x73\xc0\x96\xc8\x6d\xef\xb3\x51\x27\xdc\xe8\xfd\xda\xca\x40\x8b\x8a\xb3\x68\xd8\x08\x2a\x75\xb8\x44\xde\x9c\x7f\x30\x90\xc7\x96\x1e\xa4\x3c\xb7\x90\xc8\x3b\x95\xa2\xd4\x9d\x0f\xe7\x2a\xff\x49\x90\x57\xf8\x04\xe0\x70\x79\x0a\x68\x27\xeb\x52\xc8\x79\x32\xb7\x6e\xa1\x38\x33\xd1\xc0\xfd\x2a\xd9\x80\x38\xfc\x51\xae\xe3\x2d\xb2\xe6\x8a\x9f\xb9\x35\xb0\xe2\x1a\x7b\x53\xbb\x92\x44\xdd\xe8\xf2\x71\x4a\x75\xfc\xec\x9f\x13\x72\x25\x65\x59\x29\xc3\xb2\x33\x26\x8c\x4f\xf5\x32\x40\xb2\x16\xb3\x58\xc2\x07\x79\x7e\x26\xbf\xd4\x9c\x43\xb5\xff\xcc\x53\x79\x71\xeb\x41\x1e\x88\xd6\x2b\xf5\x22\x6e\x60\x4e\x1e\x2a\x3f\x03\x6b\xab\x34\x30\x54\x4b\xc2\xf5\xd5\x39\xcc\x6f\x51\xa3\x9c\x72\xdd\xbe\xb1\xba\xdd\xbb\x08\xcd\x30\xf0\xec\x6b\x7f\xce\x92\x52\x93\x03\x21\x9a\xb5\x2e\x6c\x28\x1f\x3f\x4b\xca\x6c\x7d\x9f\xeb\x8a\xad\xe3\xa6\x03\xfd\x93\x89\xab\x65\xa2\xed\xee\x0e\x9e\x20\x54\xff\xd8\xdf\x36\xea\x7b\xf6\xfd\xd7\x5b\x67\x5b\x23\x75\x97\xde\x96\xc1\xa6\xee\xe2\x14\xc0\x0f\xb1\xb9\x73\xbc\x29\x5c\x4c\xc1\x37\x4f\x79\xea\x67\x94\xa9\xa3\xb5\xc8\x0a\x8e\x9d\xc9\x87\x4d\x67\xba\x29\x7d\x75\xba\xcc\xe0\x4e\xb4\xeb\x35\x01\xbf\x99\xa5\xdc\x24\xe5\x92\x01\x7f\xcb\xfa\x11\x80\xf5\xbf\x38\xd3\x56\xbf\x8c\x5a\x3d\x05\x8d\x5a\xf5\x25\x44\x64\x5c\x82\x43\x09\x56\x60\x4c\x8b\x88\xbd\x96\x6e\x62\xe9\x61\x10\xe4\x1d\x4a\x50\xc1\x9a\x7f\x35\x1d\x29\x5f\x59\x46\x95\xd3\x2d\x27\xd8\xd4\xeb\x3f\xc4\xa6\xb5\x1d\xfd\x22\xef\x6b\xa6\x8e\x79\xbb\xcf\x1f\x5b\xa6\x81\xbb\x9b\xff\x23\x53\xda\x49\xb6\xf7\xcc\xfd\x0c\xe4\xa8\xfd\xdb\xfd\x70\x8e\xeb\x2d\x42\xf4\x3d\x71\xc4\xd8\x50\x8b\x0a\x30\xc8\xdd\x7e\xb3\x30\x4e\x8d\xf6\x40\x45\x83\x71\xd1\x26\x1f\xca\x8b\x24\xda\x2a\x13\x20\x04\x9d\x83\x22\x5d\xa5\x69\x61\x68\xe2\x51\xf7\xa7\x72\x25\xc0\xef\x2f\x5c\x27\x8b\xd3\x56\x99\x42\xd8\xaa\x3d\x1a\x91\x89\xab\x06\x6a\x08\x51\x8b\x46\x6d\x0f\xda\x2f\xa1\xbc\x38\x09\x0c\x8f\x61\x44\x58\xe5\xc5\x19\x43\x64\x88\x30\x92\x1c\x8d\xae\x41\xe7\xeb\xb7\x42\xea\xaf\xdb\x5d\xca\x10\x33\xcb\xf9\xb3\x64\x0e\xcf\x91\xb1\x42\x3a\xb5\xab\x1e\x64\xc1\x4d\xc7\xb5\xb7\x8b\x36\x8a\x80\xea\x2d\x23\xd1\x36\xb4\x94\xdb\xec\x6e\x3d\x2d\xbf\x82\xec\xbc\x9d\x61\x0e\x9a\xb7\x7f\xfc\x2f\x6c\x49\x03\xd2\x98\x05\x02\x79\x9a\x89\x2f\x86\x34\xcb\xd0\x60\x55\x4f\x1a\xb5\xcf\x3e\xfb\xaf\xc8\xb3\x0c\x36\x95\xb9\x63\x60\xa7\xea\x94\xa1\x22\x37\xcc\x3c\x49\x4e\x88\xfa\x50\x9a\x57\xb5\x05\xcd\x92\x59\xbf\x7e\x92\xad\xe6\x67\xb8\xc5\x7f\xbe\x67\x26\x9f\x36\x31\x49\x9b\x44\x00\xc1\xf4\xfc\x23\x38\xa4\x8a\x82\xf8\x3c\x77\xdf\x42\xab\xc2\xe1\x1d\x68\x4a\x22\x50\x6f\x24\x54\xc3\x68\x8b\x5c\xec\x22\x5b\xce\xe0\xb2\xc3\xb1\x50\x1c\xeb\x99\x7b\xdb\x57\xc1\xd3\x3f\x92\xba\xec\xcd\xae\x76\xa7\x41\x67\x16\x1b\xcb\xd0\x5f\x62\x99\x45\xaf\xfe\xf8\x17\x74\x58\x55\x24\xd6\x33\xdc\x12\xc8\xa8\xfe\x67\xb6\xe6\xa0\xb4\xf7\x71\x93\x3e\x7c\x6b\xa6\xfc\x68\x9c\xfd\x3d\x14\x08\x86\x9d\x27\x23\xd8\xb0\xf1\xd4\x44\x81\xc1\x3b\x87\xa3\x27\xa4\x75\x7d\x25\x8c\xa9\xc8\x3f\x36\x94\x84\xae\x4b\xe9\x3e\x07\x3e\x18\x99\x76\x92\x31\xab\x21\xe4\x61\x9f\xcd\x4c\x5f\xf4\x43\x93\x0d\x47\x6d\x32\x6d\x3d\xea\xc1\x77\xfc\xa8\x55\x12\x81\x68\xbf\x27\xd2\x59\x0d\x8e\x1f\xae\x5b\x18\xd9\x3a\x2a\x8f\xb9\xde\xaf\x42\x8d\x9e\x43\x21\x21\x7b\x62\x3e\xe2\x3e\x56\xe5\x1a\x1e\x45\xcc\xdf\xf2\x9b\xc2\x3d\x90\xc8\x2b\x11\x06\x78\x7b\x86\x4f\x26\x08\xd5\x62\x62\xff\xd3\x85\x77\x57\x70\x92\x8e\xe7\x42\xf1\xbe\x63\x4e\x5c\x56\xa0\xfb\x78\x50\xcd\xe8\xd0\xdb\x71\x78\x83\xa2\x5f\x19\x8d\x8b\xd3\xb0\xc7\x1f\x0b\xbb\x31\x79\xef\xd4\x52\x12\xf0\xee\xe9\x11\x71\x68\xa7\x58\xb7\x30\xdd\x0c\xa3\x20\x43\x0c\xd7\x3a\xdf\x9a\xa5\x4c\x3d\xa5\x1a\x62\xfd\xc9\x59\xdc\xee\xe4\x8f\x28\x7d\xb7\x30\xcb\x04\x31\xc1\xff\x95\xac\x7b\xd3\x86\xff\x48\x9e\xe6\x29\x52\x84\x28\xa1\xe2\x42\xa2\x75\x1b\x15\xda\x39\x92\xbf\xad\x42\x93\x88\xd5\x87\x8e\xc5\xf9\x08\x74\x59\x6d\x88\x55\x02\x23\xdf\x56\x47\xde\x27\x71\xb9\xf7\x51\xc1\xf3\x43\x73\x8f\xe0\x5d\x6b\x56\x06\x6a\x3f\x62\x7b\x62\x9c\xba\x2f\xb1\x81\xd8\xdf\x3e\x6e\xe7\xc1\xc7\x85\x93\x8d\x70\xff\xe4\x03\xac\xfa\x14\x20\x23\x11\xb5\x80\x55\x16\x41\xbc\xbe\xcb\xf6\x33\xfe\xd4\xcc\xb5\xf5\x75\x6f\xd2\xb1\x35\xc7\x5b\x4f\x37\x9f\x24\x6e\xf5\xeb\xc5\x93\x83\x12\xce\x70\x51\xa8\xb4\x36\xf2\x1f\xac\x4f\xe1\xc4\xed\x43\xea\x79\xd5\x86\x90\xce\xdb\x5e\x41\xd9\xf2\x4e\x64\x0d\x45\x3c\xeb\xa5\x3f\x74\x64\x58\xe7\xeb\x62\xd7\xfc\x67\x8f\x55\x2e\xa5\x4b\x30\xb9\x6f\x0f\x02\xd5\xd9\xab\xc1\x3a\xab\xd5\xae\x70\x0f\x21\xc3\x5c\xe9\xa1\x61\x0a\xea\x47\x0d\x62\x6f\xb5\xa7\x7f\xd2\xc3\x74\xaa\xa1\x29\x6d\xbd\x77\xbf\x49\x48\xcb\x11\x39\x1d\x81\xa5\x0a\xeb\x11\x6f\x41\xea\xd0\x3e\x22\x84\xa3\x2a\x27\x77\xfa\x23\x01\xb5\xfd\x23\xc5\x2e\x03\x5a\xa1\x11\xc3\x7e\x93\x9b\x7d\x4b\x00\x6c\xc7\x67\xed\xaf\x29\xbc\xdf\xb5\x46\x03\x21\x43\xd2\x33\xdb\x91\x8b\xd1\x1c\x88\xbd\xbe\x73\x0c\xba\x87\x40\xda\x6e\x37\x2b\x46\x65\x7b\x1d\xa9\x1f\x05\x13\x53\x68\xa0\x12\xa2\xb5\x91\x01\x6a\xf1\x2c\x0c\xbf\xe4\x2c\x41\xec\x3d\xdf\xc3\xad\x3e\x37\x9c\x4a\xad\xdd\x65\x67\x03\x0b\xcc\x46\x07\x67\x5b\x61\x0d\x7b\x15\xaf\x56\x04\xbc\x78\x56\x45\x75\x61\x56\x8a\x02\x22\x0a\xe4\x5d\x5f\x67\x50\xb7\x90\xe4\x29\x60\x1d\xee\x4c\xeb\x46\x78\x50\x25\x5a\x2b\xde\x68\x14\x48\x94\x36\x38\xa9\xa4\x37\xe3\xed\xaf\x87\x15\xe4\x36\xde\xfb\x88\x2e\xac\x43\xfb\x88\xc8\x35\x0e\x67\xc1\x4d\x71\x9f\xad\x7e\x44\x7d\x56\xb8\xd2\x3d\x4e\x49\x44\xad\x9a\x55\x33\x30\x52\xed\x7a\x83\xae\x18\x77\x67\xe2\xd3\x06\x4b\x0a\x57\x9b\x02\x22\x3f\x7b\xd7\x71\xf6\x91\xb4\x52\xe7\x5b\x3b\xdf\xb5\xae\x5f\x0a\xcb\xda\xd0\x91\xe9\x20\xe0\x4f\xf3\xe2\x99\x42\x63\x45\x09\xe2\x69\xb9\x54\x3d\x61\x54\x28\x5d\xaa\xad\x78\x6d\xc3\x4b\xb7\x2e\x0b\xe9\xc1\x88\x9a\xca\x05\x60\xb3\xee\xcc\x50\xc4\x9d\xde\x5d\xe5\x5d\x98\x94\xe9\xbd\x33\xad\xf7\xae\x40\x01\x0c\x72\x95\xd8\xe0\x3d\xc0\xbe\x21\x0a\xcb\xd8\x16\x46\x7d\x59\x3b\xae\xeb\x9b\xf4\x62\xb7\x71\xfa\xf9\xa7\x32\x0a\xb1\x95\xa5\xdd\xbc\xfe\x39\xad\xbc\xbc\x18\xfe\xb9\x81\xaa\x77\xec\xb6\xec\xf1\x29\xab\x40\x82\x24\x9e\x4f\xd0\xa1\xfd\x27\x20\xc5\xd5\xc6\x10\x3f\x2e\x36\x0b\x8d\x31\x36\x88\x67\x68\x95\x9b\x51\xd2\x92\x16\x86\x85\x2c\x27\xeb\x33\x53\x32\x7c\x0b\x69\x4c\x37\x63\x25\x79\x39\xaf\x61\xcd\xee\xba\x2e\x64\xcb\x6b\x54\x8a\x72\x67\xbe\xf5\x96\x17\xca\x57\x6f\xb9\xd0\x05\x6a\xcb\xfe\x33\xc4\x17\x17\xf9\x19\xa1\x7d\xf1\x75\xc7\xb7\xb2\xac\xb6\x11\x31\x07\xd1\x79\x47\x06\x41\xb7\x71\xa7\x74\x0d\x40\x12\x5d\x7a\xf3\x9e\x85\xc3\x25\x27\x72\xaf\x67\xe4\xb2\xf9\xe9\xc6\xe7\x5d\xa4\xbb\x61\x38\x46\xdd\xb0\x6a\x6d\x99\xea\x19\xc0\xb3\x08\xc1\x80\x59\x71\x37\xb7\x73\x0d\xc3\x4b\x10\xbb\xdb\x95\xc2\xab\xf5\xe6\xa7\x47\x62\x77\x13\x6c\x41\xf6\x6e\x9b\xfb\x77\x92\xe1\xad\x0d\x57\xe9\x31\xb8\x7b\x2b\x72\x3b\xb4\x71\x6a\xfd\x04\xe0\x8d\x38\x4a\x61\xef\x9b\xbe\x5f\x59\xb2\x7e\x45\xb2\xfe\xca\xc6\x6c\xb3\xc1\x95\x5c\x84\x35\x7d\xbd\x91\x9e\x0a\xe6\x36\x3d\x74\x9d\x90\xdd\xb9\xd9\x20\x66\x10\xbb\xe9\x92\x60\xf0\xb0\x8b\x76\xc1\x5c\x6e\x15\x0a\xbb\x5e\x83\xe9\x19\x3c\xed\x2f\xe7\xb2\x0d\xc9\x06\x0b\xdc\x6d\xdd\x96\xd4\xce\xaf\x9a\x44\xe4\x04\xc5\x86\x9b\x8e\xdd\x38\xb7\x00\xef\x57\x65\x05\xbb\xf3\xab\x14\x10\x92\xd2\xaf\x00\xc2\x23\x76\xac\x9b\x40\x89\xf7\x13\x82\xcc\xc1\x2d\x6f\xb2\x0d\xda\x90\xb7\xa4\x7d\xf6\x6f\xa7\x76\x5f\x62\xbb\x63\xe6\x47\xfc\x70\x7c\x36\x64\x67\xef\xa9\xca\xe2\x76\xdd\x9e\xc1\x19\x77\x49\xbf\x2c\x58\x62\x9d\xc4\x03\xd2\xda\x6f\xf8\xd2\x5f\xe0\x30\xb2\x74\x76\xf8\x8f\x90\x5f\xc0\x44\x0f\x8a\x7d\x61\x52\x2e\x18\xe1\xbc\xda\x67\xbd\x3f\xfc\x1a\x23\x0d\x6e\x4b\x39\x18\xee\xd3\x47\x8f\x71\xba\xb3\x2e\x3b\x58\xe9\x93\x06\x59\x08\x27\xc6\x69\xc5\xcf\x73\xd3\x59\xd5\x98\x49\x26\xce\x69\x7c\x62\x14\xf9\x1f\x28\xe5\xcc\x6e\x01\x29\x6c\x25\x48\xec\x3c\xad\xb7\xba\x81\xeb\xad\xb7\x7e\xbd\x17\xef\xf9\xaf\xf7\x94\xbb\x41\x6c\xf1\x36\x7a\xd5\x34\xc3\x5a\xdf\x93\xdc\x5a\xd5\x5b\x70\x0a\x7a\xf7\x60\xad\x67\x10\xd0\x79\x97\xc8\x44\x17\xa1\xbb\xb6\xd8\x57\x23\xfd\xb5\x1e\x1a\xc5\x81\xa7\x1e\xc7\xab\x9b\x80\x8d\x58\x35\xc9\x0e\x8c\x6c\x3b\x8f\x48\xd9\xc2\x48\x5e\x77\x0d\x16\xfb\x53\x6f\xd5\x5a\x21\x39\xb9\xca\x9e\x08\x3d\xf0\x1f\x55\xbe\xbc\x2a\x19\xe6\x65\xd7\x04\x1b\xbe\xd0\x5f\x10\x0c\x29\x93\x2b\xc7\x0c\x74\x83\x55\xd6\x19\xc8\x1a\x4f\xf9\xc5\x8a\xf1\x8d\xd9\x3b\x85\x85\x1d\x77\xd5\x0a\xab\xc1\x4f\x11\xcd\xc9\xa1\xcf\x3e\xd1\x24\x12\x7c\xe6\x48\x6f\xcd\x07\xd3\xf3\x60\x15\xab\x61\xe5\x2a\xaa\x14\xfc\x9e\xb8\xa3\xc2\x5f\x2b\xd3\xe3\x89\x30\x52\xe3\x56\x33\x26\x98\x04\xf9\xa4\x72\xbe\xe4\x3f\x1b\x64\xba\xd5\xc6\xd2\xe1\x40\x3b\xbd\x99\x91\xb1\xe6\x7f\x1c\x67\xf3\xb8\xc6\x85\xe8\xc2\x82\x9c\x9f\x93\x52\x4a\xd7\xe4\x32\x4d\x8e\x3e\x24\xad\x7b\x64\x67\x4d\xff\x13\x5f\x3d\x74\x45\x41\x38\x6a\xca\xf6\x59\xd3\xab\x72\x6f\xc4\x32\xef\x40\x13\xff\x77\xd5\x9b\x71\x12\x83\xe1\x64\x7b\xcd\x3a\x9c\xf2\xcb\x41\xaa\x8f\x0e\x33\x32\x87\xd8\xc1\x72\xcf\x5a\xa6\x86\xae\x29\xdc\x84\xad\xe7\x5f\xf8\x4f\x1b\x7d\x6d\xfc\xdf\xfe\x2d\x6b\x0d\xae\xbc\x75\x66\x68\xb0\x8b\xd9\xbf\xa7\xfc\x72\xf7\x89\x8a\x3e\xce\x28\xf5\x26\x62\x4d\x5b\xb7\xa6\x5d\x75\xba\x95\x67\x58\xe2\x73\xb0\x4f\xfd\xaa\xdc\xc4\xe3\x8c\x6b\x9a\xc5\xfc\x77\xfa\x1a\x51\x6e\xd1\x3e\x82\xa7\xcf\x7f\x3f\xec\x16\xeb\x37\x87\xc8\xc0\xd0\xc4\x29\x86\xd8\x66\xa7\x1f\xdf\xba\x25\x60\xe7\x2b\xf8\xb3\xdc\xeb\x3f\xbe\xb3\xf7\x9f\xf7\xcb\x97\x3b\xcf\x3b\xb9\xe0\xf7\x60\xaf\x08\x57\xb6\xef\x4f\xed\x18\x14\x7e\xa7\xaa\x37\x56\x77\x8b\x0d\x6d\xcb\x52\x05\x69\xde\x8a\x99\x30\x9e\xa3\x85\x27\xe4\x02\xf7\x3e\xa7\x86\xb4\x58\x62\x79\x86\x51\x6e\xb0\xb6\x1b\x19\x1a\xc2\x22\xa2\x37\x66\x0d\x59\x19\xdc\xe9\x96\x90\x5a\x4e\xab\xc1\xa5\xb2\x87\xb9\x54\x65\xa0\x2d\x55\x8a\x83\x4b\x3d\x10\x4e\x72\xb4\x33\xbd\x60\x89\xdc\x17\x03\x64\xe3\xcb\x60\x70\xa9\x73\x90\xff\x31\x18\xe5\x71\xf2\x5e\x9e\x3c\xb4\xa8\xfb\x48\xd3\x0d\x96\xff\x40\x92\x38\xc4\xa0\x74\x55\xbb\x98\xbe\x06\xb2\x42\xb7\xe4\xf4\x93\xc8\x5f\x69\xfb\xe0\x3f\x7d\x75\x5d\x3d\xd1\xf5\xd5\x42\xb9\xcf\x2e\x5b\xd5\xa5\x9c\x29\x88\xf1\x45\xd4\xfb\xc6\x7e\xdb\xa2\x18\x7a\x6f\x34\xe0\xa7\x9b\xc3\x73\x37\x22\x22\x0b\x3b\x0a\x20\xf3\x6b\x76\x7a\x91\x2c\xc4\x52\x86\x3a\x69\x78\x87\xb1\xe5\x0b\x55\xa2\xdf\xa3\xfc\x61\x26\xf9\x12\x4e\xc0\xe2\x5e\x2e\xb2\x27\x5f\x5c\xb6\xff\x95\xfc\x68\x48\x7a\xf0\x41\x3c\x10\x0f\x9c\xb7\xe3\x52\xa9\x15\x99\x44\x74\xeb\x46\x49\xa1\x6e\xc1\x00\x3d\xb7\xa0\xc5\x7f\x45\x80\xff\xfe\x98\xf4\xef\x04\x43\x61\xae\x0e\xef\xe5\x74\xde\xfc\xe7\xa9\x24\x0e\xa0\x1c\x2c\xfc\xdf\xe1\xfa\x40\xca\xa0\x6c\xb1\x16\x37\xe8\x74\xb0\x6b\xe2\x77\x61\xe6\x01\xf8\xf7\xdc\x6d\x8d\xb0\xce\xa2\x6f\x14\x4c\xfc\x9d\xff\x9b\x29\xc7\x90\x66\x4d\xc9\x2d\x31\xa9\x0b\x07\x5e\x8a\xf3\xfd\xdd\x08\x00\x9c\x8e\x48\x3a\xf9\xbb\x33\xd5\x24\xff\x6e\xf9\x8c\xff\x31\xfa\xf6\x57\x31\x77\xe3\x51\x9e\xbf\xba\x2b\xad\xd2\x10\x69\xf2\x55\x9c\xfa\x3a\x04\x33\xff\x49\xd3\x42\xf8\xf3\xfe\xa5\xd1\x2a\x29\xff\x7f\x7a\xff\xf2\x9c\xfe\x78\x03\x1c\xed\x32\x3d\xff\x4b\x92\x45\xfa\x43\xb8\xa2\x93\xf0\x77\x15\xb1\x3c\x2e\xbf\x83\xc4\xbc\xde\x5f\x1a\x06\x06\x1e\x0b\x63\x3c\xe5\xa5\x10\x42\xe4\xcf\xd8\xa0\x44\x12\x98\x05\xd6\xdd\x6a\x92\x0d\xcb\xc6\xd7\xde\xb7\xfa\xa4\xd5\x2f\xdf\xb7\xb2\x64\x99\xa3\xfc\x63\x4d\x39\x7f\x82\x5c\xff\x3f\xb5\x9b\x90\xb1\xa5\x35\xeb\x2d\x42\x74\x58\x17\xfa\x0c\x14\xd7\x74\xb2\xd4\x7c\x6f\xdd\x4b\x61\x16\x3b\x19\x2a\x6e\x85\xa4\x38\xef\xae\x8b\xf4\xff\x64\x2b\x30\xdf\x53\xc8\x04\x0c\xbc\x03\x30\xd0\xf3\x68\xce\x8c\x48\x8a\xc2\xdd\x33\xc6\x99\x24\xcf\x9f\x1c\xdb\x22\x6b\x56\xde\xbf\x9d\x99\x6d\x97\x4c\xf2\x7a\xdd\xd5\x92\xfd\x04\x6a\xc1\xe6\xd7\xa1\xd6\xa0\xf7\x5b\x9f\x44\xde\x35\xa4\xf4\xf7\x09\x57\x5f\xfc\xb1\xfa\x3b\x39\xbd\xce\xfd\x54\xf6\x52\x28\xf1\x63\xae\x53\x9c\x6c\x92\xaf\xaf\x0e\x5a\x1a\x7f\x48\xd9\xbf\xb1\x5f\xd9\x51\xab\xf0\x85\x98\x7f\x16\xbf\xd2\x75\xb0\x8e\xc6\x97\x85\x94\x3d\x66\xeb\x72\x84\xe5\xef\x33\x51\x2b\xcc\x9a\x0a\x72\x52\xe9\x02\x0c\x90\x43\xbb\x79\xce\xdd\xda\x57\x16\x97\x48\x11\x98\x97\x70\xc2\x06\xc3\x3f\x33\xda\xa7\x39\x20\xc1\x27\xf9\xe8\xd9\x2e\xef\x79\x8b\xe1\x2f\xc6\xc7\x1c\x9a\x3b\x60\xec\x77\xd1\x63\x2c\x14\xf1\xf8\xa7\x90\x1c\x90\x69\x37\x0c\x82\xe3\x7c\xe5\x11\x3a\x02\x88\xa8\x72\xb3\xa7\x78\xf0\xd6\x81\xd3\xc3\xcf\x43\x6c\xd5\xd9\xb8\x06\xcf\xb5\x90\x4a\xff\x0d\xf0\xe1\x84\xbe\x01\x0e\x0b\xe7\xf4\x66\xa5\x38\xa3\xd3\xb1\x25\x91\xe8\x5f\xfc\x85\x9e\xe2\xea\xe0\xa4\xfb\x38\x38\xff\x7b\x18\x3d\x83\xe1\xb9\x12\x5c\x7b\x37\x13\x8e\x55\xf4\xf7\x33\x70\x94\x10\x00\x58\x9a\xe6\x50\xe6\xf0\x8d\x81\x16\x80\x56\xa0\x7f\xc5\xe9\x17\xab\x93\xbe\x59\x9e\xc1\x3b\x75\x2f\x52\x37\x66\x9c\x9d\x52\x41\xb0\xb9\x11\xf3\x56\xa8\xd3\x90\xd8\x0a\x23\x0b\x9d\x49\x87\x73\x8c\x4e\x30\x11\xb7\xc6\x55\x14\x2a\x0e\x3c\x9f\xec\x4c\xc2\x47\x98\xdb\xe8\x42\xa6\x22\x86\xb2\xc1\xc4\x6d\xc7\x25\x3e\xe6\x34\xe4\xec\xd6\xb4\xf7\x87\x81\xee\xa7\x0f\x0c\x9c\x95\x7c\xef\x9a\xac\x7b\x92\xda\x10\x56\xc2\x61\x11\x0e\x38\xa8\x81\x32\x2c\xdf\xd9\x1b\xf6\x84\x8d\xda\x03\x4a\x2f\x7c\xde\xb4\x74\xbd\x47\xd1\xaa\x6f\x5c\x94\x23\xeb\xb3\x0c\x3f\xf6\x3e\xb2\x48\x9d\xed\xee\x12\xc4\x91\x64\x6b\x4b\x9b\xbf\x8c\xae\x3c\x10\x8a\xf2\xcf\x7f\xf5\x87\x3d\x68\xa8\x2f\xca\x30\xf7\xd2\x4c\x14\x80\x5c\x4f\x0d\x3e\x1e\x85\x56\xe4\x2e\x59\xa0\x5e\xfe\x33\x26\x82\x20\x56\xa0\x89\x2c\xef\xd3\xe9\x26\xbb\xea\x80\x22\x20\x54\x20\x88\xa4\x64\x5b\x12\xf7\x5f\xa6\x6a\x36\xf4\x92\xd7\x6e\xbd\x99\xe4\xf3\x8c\x38\xd8\x93\xb9\xec\x88\xe3\xc5\x71\x6b\x8b\x59\x16\xc8\x0d\x44\x34\x08\x98\x32\x2e\x40\x6b\x5f\x07\x51\x8b\x90\x26\x98\x03\xe2\xd5\x92\x0a\xc1\xfe\x13\x3a\x58\xa7\x9f\xc0\x23\x96\x68\xd9\xf8\xc4\x14\x5f\x08\x0c\xb4\x55\xda\x0d\xd4\xf9\xe6\xd1\xb2\x3a\x57\xcf\x3a\x48\x99\x60\xc8\x6a\x1f\xec\x1b\xf5\xa6\xfc\xb9\x4a\x68\xcc\x4d\x91\x79\xaf\x3c\xbf\x9f\x1b\x75\x1f\xa2\x67\xb9\x4f\x89\x03\xb4\xae\x30\x70\xb0\xc7\xf1\x8c\x81\x19\xb4\x06\x74\xbf\x8a\xdd\xc9\x4a\x4a\x3e\x6a\x70\x09\x16\x64\x4d\xc0\x3c\x73\x37\xab\x7a\xa2\x72\x12\xf3\x1f\x63\x49\x5d\x4d\x3e\x74\x12\xb6\xce\x56\xe8\x66\x64\xaa\xb7\x3c\xff\xa1\x28\x43\x32\x40\x0a\x01\xc3\x20\x6f\xe3\x8f\x76\x4f\xca\xaa\x7c\x26\x37\x9b\xfd\x8f\x32\x00\x65\xe7\x84\xd4\x13\xb3\x14\xf1\xc2\xe2\x57\x17\xca\x4f\x43\x18\xa0\xb2\x94\x6d\xf1\x2e\xff\x6c\xf1\xbf\x9f\x69\x3d\xf4\x9f\x75\x95\x51\xf2\x5a\xbe\x3a\xf9\xdf\xc4\xd2\x2d\x19\x9e\xf1\x8a\x27\x7b\x5b\x9f\xe1\x6d\x2c\x39\x80\xc6\xbc\x65\x98\x1d\x2b\x6f\xf2\xd1\x6c\x4c\xcc\x80\xfd\xa3\x75\x0b\x22\x97\x07\x38\x05\xda\xc4\x9b\xe4\x8c\x51\x89\x51\x3c\x42\xbe\xd9\x69\xff\x21\x8e\x0a\x5b\x63\x16\x2d\x77\x80\xfb\x82\x0c\x51\x66\x87\x3c\x38\xb9\xf3\x08\x0d\x95\x87\x3c\x0a\xad\x64\xde\xc5\xa3\x87\x49\x9d\x99\xbf\x77\x0a\x95\x2d\xe6\x87\x12\x96\x1e\x65\x75\x2e\x98\x95\xe4\x90\x3c\x4a\xee\xcc\xfe\xde\x82\x80\xaf\x9f\x3f\x8d\x3c\x7e\xeb\x67\x48\x6c\x06\x9e\xc3\x39\x2c\x87\xf5\x5f\xf9\xdb\x3e\xa4\xbd\xff\xc8\x4a\xb3\x7d\x64\xa7\xbe\x96\x80\xbc\x12\xcc\x4b\x4b\x3c\x21\xf8\x21\x8f\x74\x9f\xbb\x9a\xf8\x87\xb7\x14\xbe\x3b\x69\x6c\x8f\x20\x71\x3c\x3c\x76\xb5\xca\xd4\xd8\xee\xa0\xd2\xab\x0c\xb3\xf7\x84\x89\x53\x49\x00\x40\xbf\xd0\xdf\x9a\x47\x82\x67\x2b\x37\x1b\xfc\x3d\xc9\xff\x53\x48\x3a\xbf\xc5\x5b\x27\x51\x10\x0d\x77\x66\x0d\x65\x3d\x78\xe6\xaf\x79\x2c\xb7\x8f\x18\xdc\x04\x59\x29\x53\xf9\x47\xfe\x4f\x3f\x8f\x60\xe5\x20\xe6\xf3\x60\xdd\x01\x11\x29\xe8\x88\xd3\x74\xc0\x6e\xe3\x97\xcc\xfa\x83\xb9\x3d\x56\xb2\xc2\xce\xfb\xf5\x2e\x9c\xa8\xc9\x91\x45\x49\xb3\x63\x07\xe8\x06\x28\x32\x9c\x43\xd2\x1d\x09\x36\xe2\xeb\xcb\x43\x59\x4a\xe7\xa8\x23\x82\xa4\xdf\xed\xa7\x34\xd1\x9f\x9f\x32\x73\x44\x48\x38\x54\x08\x28\x8c\x92\x7f\xd3\x41\x18\x33\xaf\x3f\x31\x02\x4e\x75\x66\xe8\x20\x00\x58\xdd\x4f\x3b\xdd\x0f\x87\xd6\x13\xf9\x96\x93\x24\xd4\xa7\x5b\x92\xce\x53\xa4\x45\x4d\x90\xa4\xe5\x26\xbf\x6e\xdd\x74\x53\x3f\x60\x52\xc2\xe2\xc4\x91\xea\x04\xd7\x96\xdd\xc1\x43\x2d\xe5\x74\xf7\x33\xde\x63\xcb\x87\xfe\x3d\xd0\x7b\xda\x01\xcb\xa2\xd2\x3b\x1c\x93\xa7\x67\x38\x28\xd4\xcd\x9c\x6c\xac\xad\x9e\xfd\x54\xff\x77\x25\x4a\x83\xc3\x63\x99\x47\xac\xef\xdd\x9b\x24\xb0\xfa\x33\x09\xfc\x72\xb4\x9d\x22\x48\x36\x49\x22\x76\xfa\x51\xfc\xcf\x1c\x5c\xff\x21\x6e\x00\x1a\x06\x96\x14\x23\x9b\x6a\xb7\xca\x00\x7c\x32\xa8\x32\xd5\x59\xfa\x02\x21\xef\x04\xa4\x4e\xd8\x54\x07\x9d\x79\x08\x4f\xe3\x42\xf7\x83\xa9\x58\xed\xbe\x8a\xf0\xff\x8f\xf3\x70\x89\x29\xbf\xa9\x28\xb3\x65\x0a\x37\x24\xfb\x70\x93\xf7\xf6\xc0\xca\xff\xa8\xe4\x23\xca\x2f\xcd\xf2\x4e\xfe\xf6\x3b\xb8\x38\x58\x9a\xf2\x09\x9f\x2b\xb6\xad\x13\xec\x1b\xb9\xeb\xc9\x18\xa9\x2b\xe1\xf3\x5f\x47\x9e\x44\xc6\x0f\x52\xc4\xe4\xa4\x2c\xde\xa2\xee\x26\x0d\xc0\x3d\xb7\xd2\xfe\x8a\x8c\x94\x31\x17\x32\x87\x7a\x00\x22\xe9\xd4\x79\x77\x9c\xc5\xd5\x7f\x2a\x5a\x69\xf0\x11\xfa\xbd\xc8\xa9\xbe\x5d\x70\xf8\xd4\xd2\x16\xd4\xff\x34\xf2\x1a\xca\xa5\x06\xca\xe0\x29\xff\xec\x0c\x79\x22\xb2\xe5\x01\xd3\xe3\x3f\xd2\xf9\xa5\xb3\x90\x51\x27\x1e\x87\x8e\x39\x62\xce\x58\x3f\x68\x68\x37\x5f\x13\xb7\x73\x2e\x44\x3a\x63\xd8\x21\x19\xf2\xc6\x71\x82\x24\xac\x0f\x97\x27\x68\xdd\x90\x93\x2f\x1f\x98\xc9\x4d\x10\x9d\x64\x6c\x70\xf8\xb8\xe5\x8a\x2f\x40\xd2\x87\x9b\x1e\x8d\xf3\x60\x53\xda\xc5\xff\x4f\x33\x8f\xbb\x7a\x92\x16\x21\x58\x7e\x92\x4f\x48\x52\x30\xb0\x6e\x26\xc5\x1b\x74\x0b\xd2\x78\xd3\x18\x63\xb2\xda\x83\x7d\xa2\xf1\xfb\x71\x1a\xfe\x7d\xf5\x26\x79\x8c\x61\xe4\x78\x23\xc7\x20\xb8\xc7\xf7\x1e\x12\x67\xa3\x0d\x25\xf9\x7f\x0c\xd3\x04\x30\x9d\xcf\x7f\xca\x10\x74\xbc\xa7\xe0\xf2\x73\x28\x3f\xde\xe3\x2d\x1b\xe7\x5b\x86\xcf\x71\xa0\x6e\x3e\xe1\xb6\xd1\xe4\x54\x3b\xff\x56\x84\xfb\x96\xd5\x21\x01\x0a\xd7\x68\x79\xed\x36\x69\x0b\x8f\x4d\xd4\x46\x03\x72\x9b\xb6\xa1\xb9\x9f\x1f\x0e\xd6\xab\xe8\xe0\x91\x0b\x30\x56\x75\x33\x20\x20\xe0\x93\x7e\x5a\xf8\xe9\x4a\xc1\x49\xfa\x9a\x83\xe9\x7f\x83\xb4\xe0\x8c\x79\xab\x07\xc8\xe0\xae\x4c\x4e\xb7\x72\xbf\xe5\x06\xdd\x96\xa6\x7d\x99\x40\x39\x22\xbd\x9e\x34\xf5\xce\xdc\xaf\xfb\x29\x23\xe2\xba\x33\x59\x1e\x20\xfe\xb7\x07\xa5\x0a\x6e\xd3\x3f\x63\x6e\xcf\xc5\xe7\xea\x6d\xa5\xba\x80\xb5\x0c\x8b\x74\x06\xc8\x3d\x0f\xf9\x6b\xd0\x01\xc3\x14\x7b\x55\x56\x31\xa6\x55\xdd\x58\xc4\x71\x89\xdf\x1e\xf4\x77\x64\xfa\xf2\x5e\x0d\x72\x9d\xe6\x04\xdb\xb8\xba\xd7\xb6\x23\xbc\x20\xfb\xc1\xd9\x44\x57\x1d\x08\xf7\xe9\x7d\x72\x5b\x10\x2e\xf4\x1c\x5a\xe8\x29\xeb\x18\x39\x74\xb1\x5d\x97\x40\x2d\x3b\xc4\x08\xb8\x61\xe9\xec\xfa\x02\x0b\x01\xa2\xca\x86\xc0\xbe\xce\xed\xf8\x09\x0b\x54\x4f\xac\xf7\xa3\xce\x50\xd5\xf7\xa9\x38\x64\x70\x92\x49\x3f\x7b\x6e\x3b\x1a\x58\x4a\x02\x58\xa5\x13\x8f\x66\xce\xbf\x8c\x71\x0a\x0b\xd0\xe7\xdc\x07\xdb\x94\x28\xc8\xeb\xcf\xc6\x1a\x3a\xd4\xd4\xc9\xf0\x81\x66\x12\xaa\x2a\x9f\xd2\x87\xc0\xa0\x31\x8e\x49\x3e\x22\x7f\xe7\x0c\xe3\x19\xdf\xc2\xfa\x4d\xb7\x7f\xa3\xd6\xcd\xa0\x42\x80\x35\xfa\xe1\x34\x6d\x9f\xac\x7a\x2d\x23\x34\x6e\xa5\x26\x70\x53\x85\x22\x75\x09\x83\xee\x56\x0d\xe1\xe6\x1f\x8a\x7f\xb7\x16\xff\x6f\x61\x94\x9e\xf4\x62\x25\xcc\x84\x32\x90\x0b\xf1\x81\x4f\xe8\x15\xac\x59\xff\x9e\x58\x7f\x8f\xe9\x60\x4e\xdf\x18\x96\x5f\x06\xa0\xc2\xec\x68\x3f\x29\x94\x32\xd2\x30\x30\x04\x08\xf4\x9e\x1a\xaa\x67\x5c\x01\x86\x13\x1e\xdd\x76\xf8\x97\x02\xc9\x21\x71\x44\xc6\xb6\x56\x62\x7a\x51\x48\x76\xde\xbf\xef\x30\xd1\x9f\x65\x4c\x2e\xf9\xe2\xa3\x65\xc7\x72\xf3\x1e\xd8\xeb\x1a\x6e\x7a\xd3\x0f\x1a\xe0\x58\x19\x83\xcf\x01\x5c\x6c\x78\xec\x3a\x6e\x5d\x91\x76\xf0\xbc\x9f\x8f\x50\xa8\x0b\x90\x50\x69\xe5\x42\xcd\x94\x81\xc6\x24\x5a\x29\x01\x3b\xf8\x67\xcb\x31\xf9\x2e\x98\x8c\x70\xe4\x0f\x73\x97\x20\xae\x2d\x3e\xb9\x53\x16\x53\x67\xb0\x7a\x43\x1c\xf0\x7b\x9a\x65\x49\x0c\x61\x03\x22\x12\x1b\xa1\x64\x30\x6b\xf2\x6c\x40\xad\x98\x42\x45\xe0\x0e\xdf\x0c\x6f\x70\x42\x6a\x01\x2e\x3f\xec\x3e\xd3\xd6\x2f\x60\x77\xcf\x35\xac\x0b\x69\x3e\x5a\xd5\x3a\xbc\x09\x61\xc8\x5d\xd5\x02\x0c\xad\x7c\x6f\x32\x92\x06\x89\xb2\x0c\x6e\xbb\x23\xd1\xbd\x21\x32\xbf\xc0\x20\x7e\x06\xcf\x1f\x43\x99\xb8\x18\xcc\x3a\x06\x11\xdb\xc6\x08\x2e\x30\x46\xfc\xa2\x09\x71\xcb\x77\xe7\xfe\x0d\x31\x85\x01\xf0\x93\x4d\x58\xcf\xdf\x11\xca\xa5\xc9\x64\x48\x25\x74\xfd\x03\x66\x19\x85\x50\x82\xa0\x86\xb3\x83\x2c\xf4\xa0\x82\x50\xb5\xfd\x30\x48\xe0\xe0\x1b\xd2\x04\x1f\xc9\x1c\x84\xeb\x7a\xfd\x2c\xd2\x17\xe8\x66\xe0\xef\x30\x0c\xbf\xa4\x53\xc0\x74\x48\xaa\x24\x04\xf0\xf2\xea\xea\x10\xf5\x54\x78\x17\xdc\xa7\x38\x50\x93\x3a\x81\x54\xef\x0c\x74\x89\x89\xba\x87\x50\xc3\x1e\x3a\x0a\xa2\xff\x5b\x69\x5f\x2b\x57\x45\x6e\x18\x90\xce\x23\xe9\xde\x21\x26\x60\x06\xb1\xda\xc3\x03\xbe\x5a\x37\x81\x6f\x5a\x9d\xd3\xe8\xe5\x53\x06\x24\x43\xd5\x14\xfb\x10\x8e\x33\x43\xb5\x6e\x74\xdd\x29\xb9\x40\x21\x80\xda\x15\x1b\x94\x03\xe9\x52\x0a\xdc\x7a\x05\xb5\x94\x28\x85\x02\xc6\xca\x40\x9f\x95\x5b\xfc\x0b\xef\x35\xef\x00\x30\x9c\x84\x80\xf5\x56\x89\x13\x39\xfc\xac\x57\x6d\x3c\xca\xff\x28\x29\x04\x32\x0c\xf1\xbe\x3b\x19\xf2\xce\x32\x38\x2f\xcf\x78\x3f\x3c\x49\x99\xc7\x11\xd7\x6f\x98\x91\x78\x4e\xda\x3d\x12\x2d\x63\xba\x7a\xc8\xaf\x50\xb9\x70\x7d\x86\xbe\x1a\x75\xa7\x34\x16\x2e\x25\x8b\x43\x83\x41\x65\x8f\xa3\xba\x1c\x83\xbc\xc9\x35\x99\x01\xc1\x85\x10\x6d\x30\x24\xb5\x87\x5d\xd3\xa5\x86\xf8\xf6\x59\xc9\xa9\x47\x43\xfa\xf1\x19\x93\xe7\x7c\x29\x40\xa0\x90\x78\x02\x75\x8c\x07\x28\xa3\xb3\xb6\x88\x69\x3d\x07\x5c\x23\x62\x3a\xda\x71\x6e\x0c\x56\x92\xae\x81\x5d\x1f\x94\x3c\x5e\x92\xc6\x49\x86\xbc\xd7\x25\xc4\x03\xa6\xaf\x12\x00\x06\x3c\x40\x59\x90\x5b\x97\x4c\x8e\xe7\x4d\x9a\x07\x67\x7c\x0b\xe9\xe4\x1c\xeb\x90\xba\x30\x09\x94\x14\xa8\xd7\xd0\xe2\xed\xa4\xbb\x4e\x98\xb4\x93\x7c\x52\x03\x52\x1f\xc5\x9a\xa2\x5d\x7b\x2d\xf3\xcd\x91\x92\xbb\xa0\xb3\x9c\x52\x38\x99\x87\xb5\x00\x90\x76\x48\xf2\x55\xdf\x1f\x45\x57\x85\x04\x11\x6e\xb4\x6e\xe1\x80\x4e\xc5\x0b\x1c\xe7\x0a\x39\x55\xa8\x33\xe8\xeb\x02\xe3\x73\x95\x3c\x83\x3e\xf8\x54\xa4\x3b\xa1\x20\xdb\x90\x74\xcc\x89\x53\x39\x06\xc2\xdb\x7d\xe2\x33\xe3\xdb\x4c\xa4\xaf\x0f\x8a\x0e\xff\xc1\x37\xfd\x1c\xbd\xad\x4a\xaa\x57\xd2\x7d\x46\x0a\x5a\xba\x7b\xac\x2c\x85\xfe\x6b\x02\x13\x4c\xc6\x15\xe9\x5c\xde\xa1\xd1\x00\x73\x2f\x07\xad\xae\x01\xa9\x48\xa0\x4e\x0b\xa5\x92\x74\x0e\x1b\xb6\xb0\xe1\x4e\xfb\xa5\x14\x7d\xc8\x82\x69\x15\x38\x3a\x54\x5c\x60\x7a\x82\x12\x6e\x6b\x87\x04\x48\x11\xe2\x0e\x53\x4b\x7e\x08\xa4\xed\x51\x6c\x21\xcb\x0f\x3d\x0e\x0e\x3e\x14\xff\xb5\x52\x6b\xcd\xca\x3a\xc4\xef\x84\xe5\xaa\x87\xd2\x12\xb2\xd2\x46\x66\xc9\xd8\x6f\x3c\x98\x51\x8c\x0e\xc0\xc6\x6c\x7e\x0c\x54\x5c\x07\x03\x66\x02\x3c\xe0\x72\xf0\xf7\xf5\x80\x43\x2a\x7c\x63\xd2\xf3\xa3\xf6\x06\x2c\x20\xf9\x74\x62\x50\xe3\x69\x73\x00\x7a\x63\xd2\x48\x52\x9b\xdd\x94\x97\xf4\x2a\xac\x1d\x51\x99\xe6\x24\x1a\x3d\x12\x0a\x71\x0d\x5f\xa7\xbd\x37\x47\xd9\x9b\xa8\xef\xad\xa8\xdb\xf7\xde\x24\xfe\xf4\xbd\xd7\x9b\xb6\x16\xdf\x7b\xf0\xd7\xe3\x5b\xe5\x86\xfb\xb5\x16\x4e\xdd\x8c\x6f\xe9\x33\xfd\x5f\x97\x81\x97\xe8\x02\x66\x3f\xa5\xca\xe0\x71\x85\x6f\xfe\x79\xad\xdf\xa1\xc7\xb0\x85\x34\xf2\x17\xf1\x45\x3f\xeb\xe7\x3e\x9d\xf0\xfe\xb9\xee\xc4\xaa\xef\xc3\x2e\xc7\x07\x06\x5c\xba\xc8\x4f\x96\x30\xe0\x27\x9d\x1c\x5b\x7d\x48\x1c\xfd\x28\x53\xe9\xe3\x9a\xc4\xd4\x5e\x18\xbb\x5e\xcf\xfb\xc3\xdc\x94\x37\xd3\x56\xdf\x61\x33\xe8\x31\x18\x11\xf6\xc1\x71\x67\x3f\x04\x30\x49\x4e\x21\xd2\x74\xdf\x1e\x0f\xf7\xa8\xfe\xdb\x55\x79\x9f\x5d\x8e\x61\x9a\x53\xe8\x31\x4c\x7d\xeb\x55\xea\x3e\xef\xfa\xf7\xcb\x9b\xb7\x85\x51\xc6\x0e\xef\xca\x80\xdf\x7b\xad\x53\x57\x6d\x7f\x97\xff\x5d\x99\x2a\x05\x7e\x59\xe1\xbb\x6e\x4d\x91\x73\xf9\x23\xc0\xf5\xee\x3a\x01\xf0\x89\x69\x5d\xad\xbb\x33\x0a\xdf\x65\x97\x39\xfb\x9e\x7b\x02\xd2\xdb\x93\xbd\x1d\xac\xd7\xa3\x4a\xcb\x01\x73\x8a\x2d\xcc\xda\xd7\x55\x66\xed\x2b\xf3\x34\xdc\xe8\x9d\xd7\xb0\x30\x4a\xf4\xee\xc4\x54\x20\x2f\x7e\x96\xe8\x85\x26\x79\x0e\x35\x3b\x09\x5d\x85\x30\xac\x9f\xdd\xb1\x5e\x3f\xca\x16\x42\x2a\x01\x50\xb1\x3c\x60\x0c\x73\x8e\xda\xb7\xd2\xd9\x80\x7c\xfc\xd9\xd7\x0f\x85\xaa\x09\x73\x0e\xf5\x05\x8f\x51\xf2\x01\x64\xa7\xd7\x2e\x82\x49\xce\xf2\xed\xfa\x27\xdf\xea\x6d\xd7\x12\x36\xf5\x98\x38\x95\x60\x42\x34\xf7\x5d\x15\xf6\x2d\x15\xab\x37\x9a\xdf\xa2\x88\xed\x3b\x4f\x59\xfa\xa1\x6f\x24\x1e\xf9\x35\x06\xfd\xf7\x6d\x15\x96\xd4\xd0\xdf\x64\xf0\x4b\xaa\x61\xbd\x64\xa0\xef\x4f\xec\xc4\xf4\x23\x97\x86\x48\x60\x7b\x5b\x5d\xe0\x83\x5c\x00\xa6\x49\xbd\x15\x99\x7f\xa7\x42\xc7\x71\x03\x30\xb0\xe5\x1b\x1d\xea\x58\x06\x7e\x6f\x4c\x7a\x8a\x2c\x01\x27\x56\xe7\xf9\xdf\x9f\xf8\x84\x5e\x37\x87\xe0\xaf\x7b\x8d\x15\xfd\xf3\x7a\x61\x1a\xba\x11\xac\x32\x78\x03\xec\x52\xcc\xaf\x6a\x75\xe8\x33\xdb\x98\xe7\xe9\x4b\x21\x97\xf3\x5a\xe5\x4d\x2f\xfd\x99\x57\xb9\x34\xb0\x85\x30\x04\xe9\x93\xaf\xa2\x7c\x55\x03\x89\xcd\xd2\xab\x50\x8d\xe8\x55\xc2\x4b\xe5\xe5\xd2\x21\xae\x34\x81\x6e\xd0\x21\xaa\x9d\x2f\x84\x41\xbd\x0e\xa2\x13\xc9\xbc\x1d\xb3\xf2\x0d\x34\x3a\x2e\xd8\x5b\xef\xdc\x0a\x64\x7d\x51\x84\x21\xef\x2c\x34\xe3\xfe\x12\x3f\x04\xde\x75\xaf\x10\x5b\xa8\x2d\x44\x22\xf6\xd5\x5b\x36\xe8\x39\xe4\x2e\xd8\x90\xdb\xbb\x72\x1e\x51\x52\x0c\x88\x34\xc7\x92\x6d\x78\xbf\x7e\x9b\xee\x43\x3d\x03\xeb\x5b\xa0\xd5\x3c\xc1\xb0\x46\x8a\x29\x24\x1a\xba\xf3\x7d\x52\xed\x8c\x80\x96\xd4\x2e\xd2\x1a\x52\x0e\x2b\x3d\x3b\x5e\x29\x56\x48\xda\x22\x69\x2c\x80\x69\x53\x5a\xcf\x43\xe8\xd3\xef\xc4\xdd\xac\x07\xe1\x6d\xc6\xbd\xeb\x79\x42\x3a\x56\x0e\xf5\x4e\x8f\xab\x8a\xb4\xde\x91\x7a\x71\x89\x98\x7d\x41\x52\x31\x8c\xeb\x93\x62\xa9\x36\xda\xdb\x95\x62\x60\x6d\xae\xdf\x41\x7f\xd2\x61\x53\xef\x95\x31\x64\x1d\xe4\x60\x1f\xa2\x72\x86\x24\xa5\x60\x63\x29\xfd\x6b\x70\x0d\x69\x00\xd6\xd8\x17\xdc\x77\xf3\x3b\xb0\x07\x55\x31\xff\xc5\xdd\x72\xa8\xde\xc3\xc9\x3e\x2b\x5f\xef\xf2\x71\x52\x23\xfa\x1f\x8b\x9b\x8a\x11\x6a\x86\xa0\xb6\x17\x1b\xa8\x9a\xbd\xac\x3e\x5e\x43\x2a\xc2\xde\x6c\xbc\x5b\x27\x97\xf6\x70\x8f\xb3\x82\x9b\xc2\xa3\xb5\x0a\xa9\xcd\xbf\x20\xbc\xc3\x1d\x38\xad\x07\xb2\xb9\xa7\x45\x5d\x52\xe4\xb9\x68\xd9\x7b\x39\x25\xbb\x7f\x96\x57\x39\x10\xf5\x77\xc1\x07\x9f\x9e\xea\xb6\xf0\x98\xc0\xfb\x10\x70\x96\xe2\x9a\x3f\xcf\xee\x8f\x3f\x93\xb3\x27\x8f\xab\xcb\xe7\x34\xd2\xf4\x5f\xe8\x4e\xe8\x18\x33\x02\xcd\xd2\x95\x80\xcf\xbe\xce\x39\xc7\x25\x79\x62\x86\x03\x48\xa2\xf0\x48\x79\x08\x33\x7c\xf5\x63\x61\x1d\xc9\xff\xe5\x37\x27\x8b\xae\x7c\x53\x7e\xc9\xc6\x85\xba\x69\x98\x0f\x1b\x42\x29\x23\x47\x08\xe6\x82\x88\xb3\xbe\xe2\x4b\x0f\x8d\x5d\x8c\xeb\x37\xfb\x72\xd9\x18\x2c\x32\xa8\xae\x4c\x83\xe5\x2b\x5d\xfe\x29\x5f\xd6\xe5\x55\x34\xfc\x52\x0f\xe0\x0a\x95\x57\x98\xb0\x8b\x34\x72\x59\x27\xc8\xbb\x78\x97\x5c\x89\xaf\xa4\xae\xc7\x95\xfc\xeb\x3a\xbf\x9f\x69\xed\x6a\x13\xdf\xda\x55\x28\xaa\x34\x22\xac\xba\x9e\x18\x65\x30\x18\x9e\xd2\x56\xa1\x3b\x5f\xf7\x9d\x64\x63\xfd\x0e\xab\x8f\xf3\x96\xb1\xcb\x79\x37\xa5\x1d\x9c\xe4\x10\x42\xc2\x94\x9c\x5e\xb8\x14\xef\x0c\xde\xbb\x04\x05\xc1\xd6\xdd\xe9\x4e\xda\x83\x42\x94\xa2\x88\xd4\x7b\x3f\x1e\x51\xe9\x9f\xf7\x40\x7d\x85\xcf\x28\xf7\xfd\x89\x26\x34\x70\xdf\x27\x43\xdb\x6d\xf8\xbb\x0e\x05\x39\x31\xee\xb7\x1f\x4d\x98\xcf\xc8\x8d\xe4\x1c\xe3\x63\xa1\x64\x44\x50\x75\x4f\x11\x9a\x2f\x1b\x1b\xd9\xfd\xa3\x1e\xc2\x05\x36\xd7\xbd\x08\x4e\x29\xcc\xf5\x8f\x30\xea\xaf\x21\xf0\x60\xe8\x51\x08\x72\x88\x42\x54\xb0\xcd\xc2\x4f\xdc\x25\x2c\x74\x75\x05\x42\x39\x55\x38\xec\xd9\x2f\x10\x0c\x3b\x67\xff\x2a\xcf\xd0\xaa\xc0\xa0\xb6\xc8\xfc\x1f\x33\xed\xaa\xdc\xac\xfa\xba\xb5\x45\xbe\xbb\x9d\xff\x2d\x61\x85\x2b\x1f\x57\xac\x3b\xf6\xfe\xac\x5d\x0d\x23\x2e\x23\x44\xbb\x69\xfb\x1f\xbe\xe6\x57\x24\xf5\xc0\xef\x47\x02\x1b\x99\x29\xa3\xf6\x9e\x7c\xe2\x7f\xe9\xa6\x12\xad\x21\x5d\x5b\x3a\xe9\x63\x7f\x71\x06\x09\x65\x1c\x1f\xc9\x65\xbc\x75\xc8\xfb\x95\x24\xca\xf5\xcf\x84\xb6\x2d\x6c\x1c\x5e\x19\xa2\x3e\xc0\x85\x86\x39\x9e\xa7\x1a\x69\x03\xe3\xcc\x68\xda\xf9\x7f\x77\x9a\x1a\x09\x5e\xa7\x53\x52\xc3\x9f\x08\xca\x1a\x4f\xaa\x5f\xc0\x72\x60\xd3\x3b\x7d\x74\x59\x86\x23\xf1\x4c\xf5\x55\xc7\x4a\xc1\x93\x7a\x23\x4a\x90\x08\xc9\x5a\x3a\x91\x7e\xda\xf4\xc6\x56\x19\x91\xd7\x9d\xa3\xf9\xd3\xfa\xb4\x94\xc5\x60\x24\xe9\xdc\x31\xff\xe1\xff\xd9\x14\x17\x82\xce\x05\xe7\x04\x5d\xf1\x42\xda\x17\x59\x9c\x6d\x48\x81\xfe\xd4\x2d\xea\x4b\x1e\x45\xa7\x7b\xf3\x6a\xb5\xf5\x8a\x9b\x46\xb4\x86\x17\xde\x8a\x45\xa3\x3c\xb7\xfb\xbf\x42\x91\x22\x44\x1f\x4f\xb0\x1f\x59\xc6\x0a\x58\x63\xee\x1d\x25\xc1\xcd\x9e\x02\x0f\xb3\x4a\x41\xe8\x2c\x91\x2f\x67\x43\xd4\x07\xdb\xdb\xb3\x4c\x22\xe2\xcf\x37\x7e\xcc\x4f\xda\x64\x8e\xc7\x6f\x40\xd2\x24\x33\x0d\x4a\x50\x26\x99\xfd\x17\x59\x32\xbb\x30\x05\x4b\x79\xfb\x43\x9f\xec\x24\x9a\xe2\xb9\xcc\xd1\xf5\x35\xb4\xbe\x24\x93\x81\xd7\x92\x0f\x79\x06\x6b\x80\xf1\x7d\x48\x5a\x8c\xad\x4a\x34\x23\x5d\xda\xc0\x9d\x48\x42\x5f\x65\x86\x00\xaa\x84\x02\xe6\xf0\xdd\x3d\xb3\xf4\x55\x0d\x3c\x92\x7e\x8b\x55\xdb\x92\x67\x41\x55\xcd\xc8\x06\xa0\x17\x87\x0d\xf5\x54\xf1\x59\xfd\x45\x71\x8a\xf0\xb4\xc7\x00\x94\x1b\xaf\x8c\x66\x9e\x90\xcc\x6f\x8b\x10\x8b\xf2\x3c\x43\x12\x83\xda\xb2\x67\x2e\xcc\xaf\x39\xd1\x6d\x56\xf5\x90\xbb\x0b\xf9\xe9\x93\xf3\xe7\x15\xc3\xd0\xae\x89\x7e\xe2\x73\x94\xca\x45\xe5\x2c\x27\x08\x41\x92\x46\x33\xf8\xe4\x80\xc9\x10\xc9\xfb\x90\x65\x95\x67\x15\xe0\x3a\xd5\x30\xda\x7f\xbb\x50\x60\xe0\xa8\xb0\x20\x97\xd1\x11\x33\xab\x0d\xdd\x76\x43\xbb\x5f\x18\x96\x31\x7b\x4c\xd8\x6a\xb8\xfe\x5b\x7d\xfb\x8a\x0d\x5a\x19\x3a\xa4\xcb\x9f\x23\xe8\x61\xd7\x33\xb6\x4f\x3f\xad\x8d\xfa\x8f\x76\x45\xa5\x08\xbd\xa3\x55\x67\x41\x3a\xd4\x0f\x7b\x72\xf6\xfe\x5b\x22\x82\xc9\x6f\x1c\x6f\x63\x7a\x80\xe7\xe8\xf1\x01\x43\x4e\x03\xfd\x8c\x78\x53\x31\x77\x88\xac\xf4\x90\x1d\xc1\xb2\x0e\x14\x13\xe1\x80\x43\x21\xc8\x21\xa8\xa1\xce\xac\xa3\xe1\x87\x08\xd2\xbd\xfd\xa3\xc1\x61\xdd\xe4\x2e\xc3\x81\xd6\xd7\xa1\x55\x26\x12\xfc\x71\x98\x45\x6b\x3d\xd1\x43\xf3\xd2\x6a\x0e\xe9\x66\xdc\xd2\x07\xf1\xe4\x2d\xfe\xb3\x61\x3a\x9a\x8d\x2b\x72\xdc\xbd\xe4\x43\x42\x82\x8b\xe6\xa1\x1c\x6b\x23\xa0\xe8\x91\x9d\xae\x61\x4a\x30\xbd\x58\x51\xbb\xc0\x5a\x5a\x03\x0e\x1d\x82\x68\x39\x6a\x13\xef\x5f\x14\x1e\xc2\xde\x72\x2a\x47\x1b\x3c\x43\x96\xf0\x84\xa6\xfc\x49\x90\xf4\xed\xc1\x14\x9e\x25\x7c\x23\x75\xfd\x6a\x02\x92\x64\x5f\x30\x12\x61\x43\x91\xb2\xc6\xda\x67\x9a\xca\xff\x79\x39\x50\x4d\x12\xba\x1e\x2b\xe9\xee\xed\xf3\xe4\x34\x22\xa6\x43\xd8\x37\x69\xf7\x3e\x52\xa8\x83\x4d\x17\x4a\x3f\x7f\xb3\x9a\x7b\x64\xd6\x6a\xbb\xd9\x4b\xb6\x72\xb8\x3d\x60\xd8\xee\x69\xe5\xe9\xda\xcd\x0f\xd2\x85\x3e\xe8\xca\x6f\xdd\x8a\x93\xe3\x63\x9f\x46\x61\xf3\xd3\x14\x28\x6f\x77\x27\x81\xb4\x5b\x8d\x64\x43\x3d\x28\x69\x0b\xa4\x42\xef\xd4\xf6\xf8\xf6\x26\xd7\x70\x64\x74\x20\xcd\x9c\x5b\x56\x1a\x86\x34\x70\x2d\xd2\x4b\xa9\x7b\xb6\x34\xa5\xb8\xc8\x6a\x63\x07\x8a\x67\xc0\x81\x64\x95\x98\x88\x75\x10\xaa\x34\x43\x4e\x85\x0c\x0d\x49\xee\xa2\x9e\x4a\x77\x04\xda\x31\xd7\x4c\x4d\x90\xa6\x73\xad\xeb\x27\x4e\x2f\xc1\xc8\x56\xff\x32\x77\x2d\xf2\x0a\x6d\x95\x29\xfa\xad\x3e\x25\x60\x42\xa3\x28\xfb\xd2\x6d\x54\xa2\x13\x4e\x55\x35\x92\xc1\xde\x07\x37\x9c\xa2\x94\x28\x09\x69\x40\x10\x25\x11\xdb\xab\xd5\x01\xfd\x5c\xef\x50\x37\x97\xb2\x8f\x7d\x93\x34\x45\xec\x17\x2a\xc6\xef\x72\x77\x11\x20\xc5\x42\xbe\x2a\xd7\xbb\x4a\x0a\x65\x38\xca\x3f\x5a\x57\x2d\x9a\xbc\x16\x5d\x27\x9f\x1f\x57\x57\xae\x05\xc3\x12\x8a\x26\x5e\x4c\xfa\x39\x76\x45\x7a\x94\x86\xfa\xb1\x34\xcb\x61\xdd\x59\xbf\x0d\xb3\xfa\x3d\x36\xa0\xe5\x5e\x9a\xa8\x6a\x99\x3c\xec\xe6\xb4\x0d\xdd\x43\xb9\xa3\x34\xf7\x4a\x51\xda\x32\xc4\x4b\x7e\x59\xc3\x58\x9a\xc9\x6e\x02\xd4\x75\xe7\xf2\x38\xf7\x8f\xf4\x5e\xf2\x2c\x2a\xb0\xfc\xf1\x60\xd0\xa5\x90\x85\x8d\xee\x1e\xcc\x7e\x6c\xa1\xf0\x03\x61\x13\xd2\xda\x9a\x4b\x2d\x37\xa1\x50\x44\xc1\x04\x51\xa5\xe4\x8b\xe3\xc4\x0d\x30\xc9\x5e\x5f\x39\x16\xf6\x8e\x02\xe8\xc7\x51\xd5\x18\xfe\x25\x7e\x37\x5c\x76\x59\x3f\x36\x5d\x4a\x7e\x6c\x52\xe0\x69\xe9\x74\x11\x1d\xf4\x53\x78\xaf\x9c\xc9\x45\xd9\x94\xad\xf0\x00\xdb\x44\x99\x9e\x14\x75\x66\x4b\xe0\x52\xe4\x8d\x5a\x26\x4f\xda\x68\x34\xd5\x19\x90\x90\xe0\x97\xca\x0c\x59\xd0\xb2\xf4\x06\x52\xae\x9e\x7b\x0d\x10\x08\x66\x7f\x12\x81\x66\xce\x6c\xff\x9f\x4f\x13\xb5\x8d\x52\xef\xb6\xe4\x3f\xe1\xff\xd0\x4f\x16\x61\xd2\xb0\xc6\x31\x86\x28\x4c\xa1\x68\x3d\x84\x52\xfc\x02\x0e\x5a\x4c\x5b\x5f\xa0\x70\x46\xfe\xb8\x5d\x54\x82\x5b\x59\x8d\xe4\xaf\xbc\x01\xf1\x12\x0e\x17\xfe\xa9\x44\x24\x18\x41\x2d\x45\xea\x21\x4d\xfe\xb8\x47\x88\x08\x1f\x78\x55\x62\xcf\xf4\x5e\x59\x6a\x30\x79\x54\xce\x63\x1f\x4e\xde\xf7\x43\xd5\x97\xfe\x63\x1d\x9f\x26\x05\x95\xfc\x1f\xf5\x52\x62\xa7\x26\x3d\x8d\x1a\x59\xf2\x47\xa5\xdf\xf0\x01\x03\x8b\x26\xdf\x74\x5f\x50\xc9\x62\x84\xdf\x54\xee\x72\x2a\x5b\xde\xb9\x13\xf4\x89\x6f\x9e\x9d\x04\x91\xc3\xda\x65\x3e\x84\x03\x41\x2e\xcd\x65\x1d\x56\x25\x44\x4c\xe4\x40\xab\xeb\xbb\xac\x32\xc0\x3e\xdc\x9e\x97\x3b\xad\xe0\x00\xc7\xc7\x6b\x4b\x45\x6b\x23\x56\x7a\xe0\x56\x8b\x64\x74\x94\x9f\x9d\xbc\x61\xe4\x46\x50\x58\x06\xf4\xb6\x90\x6c\xb1\xc3\x51\x9c\x65\xe7\x68\xd9\x00\x95\x2d\x01\x3c\xe0\x6f\x40\xb7\xa7\x88\x1b\x71\x78\x96\x28\xff\x07\xc3\x57\x9e\x2c\xfa\x54\x47\xd1\x0f\x2c\x5d\x6b\xa5\x30\x6d\xc5\xf5\x5d\xf8\x5c\x91\x50\xcb\xad\x1e\x1c\x1f\x1e\xf9\xfb\x65\xbe\x04\xd5\x5b\xfe\x95\x6f\x89\x93\x65\xc8\x53\x3a\xb0\xae\x80\x02\x2a\xd6\x55\x56\xbe\x07\x10\xeb\x17\x43\x22\x49\x02\xed\x02\x4c\xa2\x02\x45\x75\x0d\x95\x97\x36\x96\xc7\xcd\xb3\x1f\x52\x57\x81\xf2\xcb\xff\x02\xf0\x65\xb4\xea\x48\x71\x98\x23\x6f\x1c\xb9\x1c\xd9\xab\x66\x2b\xd4\x71\x36\x04\xe5\xd2\xcf\x7f\x52\x8a\xd1\x46\x34\xf0\x05\xc8\x50\x00\xe1\x31\xd6\xb2\xe8\xfc\x7a\xfa\x79\x88\x11\xc2\xa1\x98\xf3\x61\xef\xb3\x22\xfa\x87\xe7\xea\xfb\xf7\x79\x84\x67\x9b\x01\x7c\x8b\x39\x04\x64\xe4\xc4\x6e\x40\xdf\x48\x3a\x95\x2c\x71\x58\xef\x97\xed\x3e\x84\x07\x02\xf4\x35\xca\xbe\x70\xc4\x1d\x1b\x5f\x39\x65\x92\x1c\xe9\x40\x8e\x83\x24\x64\x90\x1a\x7a\x49\x6f\x06\x59\x7a\xbb\xb6\xd9\xa5\x5f\xb3\x4f\xba\x8c\x0d\x4f\x3a\x13\xda\x2e\xb7\x74\x69\x36\x9d\x63\xbd\x4f\xee\xc8\xd4\x90\x43\xd5\xd2\x11\xd4\xf1\x23\xfd\xe3\xd5\x5f\xbf\xd2\x96\xb2\x5a\x2a\x22\x5e\xa8\x7d\x43\x9a\xb3\xc2\xf0\xc1\x5f\x0b\xc4\x26\x9b\xb4\x53\xe0\x0e\xee\x5b\x9e\x19\x5c\x0d\x57\x74\x39\x39\xc0\x82\x9e\xaa\x57\x29\xb5\x6d\x12\xec\xaa\xcd\x9e\x49\x3f\x61\xb3\xaa\xb9\xb0\x8e\xb1\x77\x8c\xf5\xb4\x81\xae\x73\x63\x75\xa6\x78\xec\x15\xc9\xc7\x34\x34\xb1\x0f\x09\x63\x4b\xca\xd8\x48\x38\x66\xab\xf3\xbd\x33\x75\x13\x2d\xc9\xf6\xdf\x4f\x8e\xc6\xdf\x5d\xab\x29\x5e\xc8\xed\xf6\x43\xf1\x1b\xb3\x2f\x37\x12\x91\xeb\xc2\xf7\x0f\xba\x33\xbf\xd9\x85\xea\x33\x10\x14\xa1\x51\x87\xa2\x32\x4d\xb2\xda\x6d\x3c\x25\x10\xf3\xbd\xa9\x17\xc3\xf3\xec\xbf\x51\xb3\xd5\xf5\x95\x93\x09\x7b\xed\x74\x5e\xc4\xa7\xa9\x9c\xb6\xd7\xda\x18\x9f\xdb\xab\x33\x3a\x95\x92\xb1\x87\x71\xd6\xfe\x57\x17\x74\x44\xf6\xf2\x65\xfc\x77\x2f\x6f\x4a\xc4\x78\x25\xbb\xff\x78\xa0\x7b\xd9\xfc\xed\x46\xfb\xa4\x00\xe9\x5e\x34\x7e\x71\x0d\x99\x4a\x30\xb3\xa7\xba\x17\x4f\x70\x00\x42\xda\xf8\x7b\x27\x62\xb7\xd2\x00\x83\xda\x3b\x06\x4c\xfa\x91\xf9\x16\x51\xc4\x90\xe7\x80\xbf\x65\xdd\x6a\xcd\x90\xa6\x86\x76\x75\x34\xf6\xfc\xa7\x8b\xca\x88\x38\xf0\x5f\x1c\x3b\x6a\x41\xa2\x2b\xfb\x8f\x06\xba\xa7\x97\xcf\x4c\xed\xfc\x22\x91\x01\xff\xd1\x3f\x76\xa6\xe3\x40\x78\x66\xe3\x5e\xcc\x6a\xb0\x92\x52\x37\x53\x68\x02\x5b\xe5\x3f\xa6\xd0\xa4\x89\x0a\xc2\xa0\xe2\x19\x86\x64\x5d\x0d\xa9\x9a\x4b\xd4\x4f\xc8\xd4\x50\xc8\xc1\xde\x9e\x77\x4c\xb3\x41\xb4\x46\xbb\x93\x8c\x0e\x77\x9d\x3e\x1a\xb3\x05\xcc\x57\xed\x84\x63\x92\x16\xc7\xed\xcc\x2b\x6a\xe1\x8c\x74\xbf\xd8\x90\x90\xa9\x0e\xf1\x86\x1c\x4c\x8a\xcb\x30\x85\x7b\xab\xed\x95\xb8\x02\xd2\x42\xfe\x1e\x6e\x54\x98\x85\xbb\xf8\xc9\x32\xb4\x36\xaa\xbc\xe0\x91\x7c\x21\xe7\x86\x2d\xb4\x10\x00\x42\xab\x9d\x52\x38\xfa\xb7\x4c\x4e\x37\xbc\x69\xa2\x4a\xb9\xe7\xca\x5f\x0d\xf4\xa4\x48\x4c\xdd\xaf\xf8\x6f\x24\xe5\x1a\xec\x57\xbe\xd3\x0e\x62\x43\x1e\x6a\x12\xd2\x39\x66\x6e\x91\x67\x26\xa1\x39\x92\x72\x45\x9d\xc0\x29\x8a\xcb\x9a\x12\xde\x06\x62\x26\x8d\x6f\x95\xae\xe5\x5b\xf9\xa4\x59\xd2\x14\x98\x69\xf2\x6d\x4a\xd4\xaa\x6e\x28\x77\x12\xa8\x12\xde\xca\xa6\x35\x9a\xec\x34\x30\xb4\xd0\xeb\x89\x2c\x83\xad\xc0\x90\xfd\x4f\xdf\x83\x2d\x25\xef\xbb\x6d\x59\xbd\xaa\x2d\x5f\xa1\x37\x13\x52\x8c\x86\xa8\x27\x64\xdd\x18\x65\xb9\x00\xfe\x4b\xa7\xb3\x65\x0c\x12\x78\xb7\xb2\xab\x8f\x52\xd0\xa6\x9d\xec\xb8\x6d\x9a\x33\xdf\xa4\xc6\xb0\x41\x5c\x8b\x2b\x56\xc6\xb1\xb6\xb0\xe2\x32\xf0\xe0\x95\x94\xd0\x70\xd8\xf2\x13\x55\x1b\x77\x7c\x86\xc2\x4c\x8e\x8e\xf5\x96\xbb\x46\x8e\x2a\x4b\x7b\xe3\x18\x8a\xdf\xa2\xa7\xbd\xe5\x98\x3e\xdf\xfa\xfe\x4a\xc6\xd8\x6c\xc4\xc3\x29\xdf\x6d\x3c\x22\xe2\xb4\x45\xb6\x2c\xf4\x6f\xac\xca\x3c\x4e\xe1\xa2\x09\x9a\x6d\x7c\xba\xb8\x82\xf4\x69\x9e\x5d\x29\x64\x7c\x32\x8b\x79\x1b\x11\xb8\xf1\x1f\x3f\x7a\x5a\xf5\x46\xd8\x34\x29\xe6\x70\x5c\x42\xfc\xc6\x7a\x09\x64\x94\x41\xcb\xa6\x66\x01\x77\xb3\x8a\xb5\xe9\xb1\xc6\xd6\x3f\x0d\x9f\x91\x86\x9e\xdb\x98\xee\x95\x1f\xce\x88\x77\xca\x0f\x90\xac\x47\x33\x52\xb6\xe4\x73\xdd\xc3\x40\xc9\x15\x8d\x89\x0c\xf0\xd1\xdb\xb0\xa0\xeb\x2b\x19\x9e\x25\xe1\x72\x5d\x1a\x34\x39\x4c\xda\xd4\xba\x10\xa1\xd2\x82\x89\x65\xeb\xf0\xbf\xba\xee\xcd\x15\x93\xa6\x1b\x4c\xb6\x46\x49\xd6\xc4\x8b\x05\x3f\xc1\x96\xf6\x90\xb7\xb1\xce\xd0\x57\x50\xfb\xb8\xe1\x56\x0a\xe1\x9a\x7f\x8f\xd6\x9a\xae\x09\xea\xb7\x3a\x40\x0d\xf1\x1c\x10\xf0\x84\xe8\x5d\x08\xb1\x9b\x8b\x97\x64\x3d\x75\xa9\xde\x64\x0e\x55\xa5\x6f\x23\x35\x9b\x36\xf0\x43\x87\x6d\x4a\xc8\xdf\x24\xf2\xb6\xb7\xc4\xfe\xbf\xd5\x34\x76\x76\x65\x03\xba\xec\xcd\x19\x80\xe5\xb3\xeb\xe0\x3c\x7b\x30\xde\xbd\xba\x75\xa1\x9b\xee\xd6\x5a\x25\xa6\x63\x77\x9a\xdd\xc5\x2d\xf5\x1f\xf8\x37\xce\x8d\x69\x2f\x1b\x06\x54\xbc\x80\xdf\x97\x9d\x9c\xd2\xea\xc8\x67\xfa\x79\x09\x93\x8e\x3c\x7a\x04\x8b\xb0\x54\xd6\xcc\x88\xb7\x3f\x93\x50\xa8\xee\x20\x9d\x99\xeb\x68\x63\xb8\x7e\x86\x90\x25\xb9\x5f\x01\xd8\xf5\x47\xd9\x68\x9e\xb6\xde\x87\xff\xf8\xf5\x5e\xc2\x83\x1e\x32\x36\x6f\x7f\xed\x56\xab\xd4\x3b\xcb\x00\x02\xd7\xa3\xe4\x83\xd6\x6a\x4d\x3b\x14\x61\xaf\xff\xa4\x64\x23\x25\x9c\xea\xc2\xe3\x8e\x34\x85\x04\x5e\xb8\x54\x40\xa0\x5a\xc3\xbd\x77\x89\xd7\x6c\x4a\x0b\x5e\xad\x33\x92\x39\x52\x58\x6b\x59\xf8\xcf\xb9\xd1\xd1\xdf\x90\xf6\x7f\x5c\xa4\x79\x20\x32\xbc\x4a\xca\xc6\x86\xd3\x03\x4f\xdd\x7b\x8c\x48\xba\xf2\x12\xcc\x7e\x29\xcf\x5c\xaa\x4d\x56\x8d\xc8\xdd\xf1\x99\xff\xda\x25\x41\xb3\x4f\x0a\x45\x5a\x77\xf8\x56\x2e\xad\x55\x2a\xb7\x5f\x20\xa4\x51\xff\xa3\xf4\x8c\x5e\x03\x6b\x1c\x7d\x08\x88\x92\xff\xda\x79\x73\xad\x12\x49\xfc\x47\x99\x22\x4c\x6c\x58\xc2\xa9\x2b\x78\xa2\x5e\x4a\x52\x25\x3f\xa4\x80\x92\xb3\xd7\x10\x6b\x9e\xa8\xd4\x92\x9d\xdb\x40\x94\x79\x11\x91\xe5\x06\x79\x19\x7e\x2b\x86\x46\xfd\x5a\xeb\x5b\xac\x92\x8a\x79\x15\x16\x50\x68\x4c\x01\xbd\x94\xaa\x0c\x9d\x89\x56\xf6\x1d\x56\xcf\x47\x67\xea\xd4\x9a\x8e\x42\x89\x55\x43\x1a\x7b\xc1\x61\xb3\x2b\x15\x21\x1d\xed\xc5\x20\x48\x77\xde\x74\x59\x18\x75\x6f\x81\x95\xba\x0a\xe8\x66\xca\x8e\xbd\x26\xda\x79\xbc\xc8\x1a\xc7\x00\x53\x8d\x0e\x24\x61\x78\x8b\xed\x42\x78\x63\x53\x88\xce\xd0\xa2\x13\x35\xe4\xad\xdd\x1e\x48\x61\x25\xf2\x2e\x9b\xc3\x89\x07\x1f\xab\x74\x69\xc6\x78\x2b\x91\x5b\x26\xd1\x1b\x4f\x09\xe1\x9e\x83\x57\xa8\xcb\x3b\x9d\xec\x6a\x2e\x37\x9b\xcd\xe5\x0e\x69\xb8\xe5\x3e\xe7\xbd\x08\x51\x1b\xe3\x6e\x97\xd2\x93\x97\x3b\x04\x3d\xac\x6f\x14\xd2\x19\xf7\xb2\xfe\x24\x69\x38\x19\xba\xdc\x63\xcf\x65\x87\xe6\x8c\x74\x61\xee\x18\x24\x2f\x8d\x51\x10\x2b\x45\x67\x5f\x5a\x6c\x54\x42\x66\xc4\x23\x65\x0e\x42\x48\xd6\x65\x64\xbc\x4c\xd7\x57\x07\x22\xa1\x67\x91\xe2\xa0\x95\xa1\x2e\x53\xbf\xf7\xc0\x92\xb2\x23\x95\x13\xc1\x0b\xd2\x42\x98\xd1\xba\xd4\x48\x8f\x36\xe4\xfd\x9d\xa5\x62\xba\x83\x80\xea\x31\x27\xa5\x6d\xea\xe1\x1f\x28\x4a\xee\xe9\x73\xb4\x4b\x85\x90\x8c\x22\x07\x0b\x94\x07\x43\x44\x46\xb9\x39\x4b\x9d\xd7\x18\x54\x2d\x95\x44\x9f\xc5\x06\x04\x07\xcb\x68\xca\x0d\x72\xc2\xdf\x65\x65\xd6\x8e\x7a\x54\x62\x81\x36\x61\xcb\x9e\x3e\xbe\xec\x59\x16\x71\xcb\x4a\x2f\xf2\x05\xbe\x9b\x7a\x7a\x6b\x58\x30\x59\x65\xf1\x0e\xf5\x1d\xe4\x40\xfb\x53\xf3\x89\x40\xdf\x05\x55\x19\xc5\x6f\x4a\x8b\x79\x69\x83\x6e\xa3\xac\xbe\xa8\x2d\x8e\x8b\xa7\xd1\x2d\xe5\x50\x3d\x09\x62\x9f\xba\x53\x06\x8b\x34\x69\xd6\x10\xa7\x09\xc9\x7c\xab\xd9\xa8\xe1\xc3\xd9\xef\x85\x7d\x36\x1b\x4b\x85\xa4\x8e\xa4\xaf\x16\x17\xe8\xf0\xca\x7c\xc9\xf1\xcb\xa1\x12\xed\x33\xe9\x50\x9c\x91\x16\x4e\x8e\xd7\x44\xf7\x20\x2b\x95\x6a\xc9\x99\x9c\x24\x03\x13\x35\x69\xd4\x00\x2c\x99\x4a\x98\x56\xb6\x41\x22\x35\xef\xf4\xbc\xe9\x46\xb3\xa4\xfb\xb8\x59\x32\xfa\xb0\x24\xcc\x2e\xa9\xe7\xbf\xa4\xfe\x62\xa0\x0d\x3f\x09\x8e\x2a\xe1\x36\x60\xea\xca\x20\x65\xc7\xc1\x2e\x49\x75\x88\xd0\x34\x29\xca\x6c\x87\x56\xe9\x9e\x80\xe8\xfb\x26\x48\x0f\x6f\xa6\x97\x14\x52\x3c\xc9\x35\x78\x04\x2b\x0b\xb9\x57\xfd\xdd\x5d\x31\xee\xef\x5e\x43\x5b\xe6\x2b\xf7\xee\xbf\x10\xe8\xfe\xab\xf6\xd9\xb2\xf2\x30\xe8\xed\xdc\x9f\x35\xd0\x3e\x68\xfd\xcb\x6f\x29\xd8\xa0\x83\x29\xe0\x2f\xf2\x5f\x6e\x2e\xe8\xf0\x17\xea\xeb\x7f\xa9\xc9\x19\xca\x5a\x6d\x3a\xfa\xa1\xf9\xe6\x8c\xfa\x5f\xf7\x4e\xfb\x4b\x9b\x84\x65\x5c\x08\xfa\xcf\x2a\x20\xfc\x20\x8c\xbd\xf1\xef\x72\x85\xba\x0c\x66\xec\x38\xc7\x50\xaa\x68\x85\xe8\xac\x9c\x23\xee\xbe\xfd\xc0\xe6\x17\x58\x42\x6a\xa7\x6c\xcd\x7f\x4d\xd9\xd8\xf5\x2b\xf6\x9c\x43\xee\xbe\xcc\x5e\xd3\x97\xa7\xe7\x22\x15\x3d\xab\xf9\xfe\x84\x24\x8c\x7d\x30\x5e\xae\x57\xe8\xad\x60\x3e\x26\x74\x62\x9e\xae\xa4\x71\x67\x8f\x93\xa0\x94\x4c\xc8\x59\xbc\xe5\x9a\x63\x86\x7b\xae\x2f\xca\x70\x60\xfa\xbc\x53\xdb\x6c\x09\xb5\xf5\x4e\x28\x55\xb4\xd9\xd5\xc9\xb8\x2e\x3e\x8b\xb9\x9e\x21\x09\xa3\xd4\x3b\x64\xfe\x94\x45\x80\xf2\x23\x95\x59\xca\x73\xdd\x3f\xf7\x76\x20\x81\x87\x4b\xf9\xa3\x8b\x92\xbc\xec\x8c\xac\xa5\xa6\x17\x61\xae\xeb\xff\x27\x30\x53\xff\x11\x98\x41\x0d\x2c\x06\x0d\x96\x24\xf9\x4d\x48\x20\xcd\x58\xb8\x6c\x31\x54\x3b\xd7\x45\x17\x13\x1a\x16\x73\xb5\x0f\xd4\x75\x47\xea\xd4\x65\xa8\x0c\x3f\xe3\xa2\x26\x89\x25\xcc\xf6\x62\xd9\xaf\x0c\xe5\x1d\xcc\xab\x84\x39\xd7\x8c\xd9\x14\xde\x3e\xa6\xfb\xcf\x7b\xa2\xd6\x8c\x02\x6a\xb3\x57\x32\x44\xbb\x77\x9d\x3c\xe3\xd0\x16\x16\x16\xfe\x53\x51\x93\xf0\x78\x25\xb2\xeb\x5c\xc8\x5a\xc1\x7e\x1b\xe0\x5f\xec\xf9\x41\xc2\xc2\x3b\x58\xb3\x67\xb4\x6a\x6f\x0c\x42\x9e\x43\x50\x20\x6d\xe0\xee\x57\x02\x45\xdd\x90\xb7\x41\xfa\x27\xbd\x18\xfc\x9e\x41\x04\xb5\x4a\xee\x26\x54\x6b\x9a\x0d\x05\xd3\x7f\x21\x74\xe3\xbf\x1b\xdd\x1d\x8d\x57\x67\x5a\x85\x9d\x21\x71\x23\x2f\x33\x88\xf7\xb3\xf8\x47\xe8\xe6\x52\x0e\x9b\x0b\xe0\x64\x81\x22\x5e\x37\x30\x1f\x44\x8e\x4c\x64\x20\x48\xf3\x12\xea\xb8\xe5\x8a\x96\xc4\xb0\xae\xba\xec\x3a\x1c\x34\x65\x63\xbb\x3d\x49\xf6\x00\xa2\xce\x67\xd5\x61\xca\xa0\xcb\xa6\x8d\x8a\x95\x12\x94\xc9\x0f\xfd\xc3\x6a\xd2\x95\x19\x9a\x73\x9e\x7e\xa9\x70\xf6\x5a\x8d\x15\xe1\x5b\xc8\xe8\xe4\xf0\x87\xb6\x85\xac\x48\x27\x54\x75\xd8\x9f\x81\x88\xce\x2e\xb1\x43\x7b\x23\xe2\x11\xb9\x26\x9f\x64\x71\xd8\xa5\x44\x6b\xa2\xbc\x68\xc0\x78\x6e\xa9\x75\x39\x1c\x49\x43\xb9\x2b\x64\x4b\x21\x9b\x83\x97\xfc\x4d\x14\x02\x39\x8b\xce\xb1\x4b\xa4\x7e\x46\x87\x98\x97\xbb\x85\x68\x12\x26\x77\xd4\x46\xd9\x80\x21\x04\xa9\xd0\x23\x3b\xa5\xdb\xb3\x4a\xd6\x10\x48\xda\x3f\x25\x1e\x9a\xf5\xd7\x78\xf6\x12\x2a\x3f\x22\xa6\x1a\x58\xc3\xa3\x75\xf6\x71\x8c\xcb\x7f\xdc\x5f\xff\xd2\x9e\x51\x31\x3d\xc3\x00\xd8\x80\xb2\xc2\x9f\x77\x93\xa0\x92\x21\xaf\x88\x9f\x37\xf8\xb6\x14\xfa\xb8\x83\xa6\x6c\x88\x63\xf7\x27\x66\x79\xaa\x34\x64\xee\x4c\x56\x36\x80\x94\xb5\x3d\x1e\x2b\x15\x9d\x29\x15\xf2\xcb\xa1\x9b\x93\x6d\xa0\xe2\xb5\xe2\xd3\x13\x2c\xbc\x99\xb7\x3a\x97\xab\x9c\xc3\x47\x35\x14\x48\xe5\x50\x90\x06\x48\xd5\xe7\x93\x69\xd6\x56\x4c\x5d\x37\x47\xd7\xd3\xca\x97\x13\x52\xcf\xe6\x99\xe2\x44\xa7\x9c\xe7\x00\x67\x51\x7a\x9e\x98\x0e\x7d\xf2\x7c\x25\xd2\xf6\x01\x79\xb6\xf2\x78\x48\x3f\x07\x5a\x3b\xba\x04\x70\xa6\xb8\x12\x2e\x7d\x54\x76\x69\xb1\xc6\xf3\xbf\xb3\x14\x7e\x72\x5a\x19\x27\x74\xfd\x1d\xde\x6e\xa4\x4a\x7d\x05\x22\x8d\x0d\x38\x44\x6d\x42\x70\x06\x72\x82\x14\xe3\x69\xd2\xea\xa9\x2d\xc4\x78\xea\xc4\x19\x1b\x20\x74\xe7\x79\xe3\xe0\x8f\xb1\x71\x22\xe2\x59\xad\xfe\x65\xb9\x4a\x38\x1a\x30\xd1\x14\x1a\x1a\x3a\x6f\xd7\x83\x73\x6d\x9d\x81\x56\x00\x8e\x55\xb6\xd8\x67\xee\xe7\x9c\xb9\x3d\x18\xbd\x7c\x28\x15\x02\x7d\xd2\xd5\xe1\xe4\xc8\x13\x74\x86\x99\xc7\x62\x95\xf4\x5c\xef\xcd\x69\x74\x48\x78\x57\x27\xd0\x20\xf7\x5a\xbb\xb2\xde\x13\x3a\x97\x81\x38\xd6\x7a\xfe\xe5\x35\xc1\x88\xfc\x59\x5e\x6c\xd8\x9e\x85\x5a\xeb\x56\x32\x9e\x60\xe0\x99\xa5\x85\x54\x20\x24\xaf\x20\xc1\xb3\xac\x47\xba\x98\xfa\x01\x6d\x9e\x12\xfb\x6b\xd6\xc0\x00\xe3\xe7\x90\x79\xbf\x2f\x81\xd0\x20\x2a\xea\xa1\xe1\x70\xf1\x4e\xbb\x86\xdc\x25\xfd\x1f\xfb\x5c\x35\xaa\x85\xdb\xad\x6e\x4f\xbe\xa9\x6e\x82\xf9\x8c\x12\x80\xaf\x20\x45\x1b\x3c\x23\x91\x97\x87\x26\x93\x9b\x34\x8d\x3d\x9e\xee\x44\xc0\xcd\xba\xda\x9c\x4b\xfd\xf8\x65\x22\x6d\x6a\x27\x58\x63\x33\xf5\x30\x9f\x79\x9a\xfa\xf6\xa9\x49\x5d\x48\x9f\x8d\x0d\x3f\x43\xee\x28\x7d\xba\xde\x52\xba\xf9\xce\xa5\x9b\x29\x3c\x4f\xe7\xc2\x39\x08\x0a\xcb\x13\xb3\x4d\xdc\xcf\x7a\xc0\xac\x01\x92\xb8\x07\xd0\x06\xea\xca\x43\x76\xc6\x87\xf4\xb3\x52\x28\x06\xed\xac\xb5\x40\x56\x0e\xe5\x1f\x48\x1f\x9f\x44\x03\x8f\xb1\xd7\x3b\x04\x85\xfa\x47\x60\xdf\x00\x8d\x48\x9e\x98\x37\xe2\xd1\x56\x09\x34\x3f\xe1\x44\xa8\x73\xae\x6b\x4c\x52\x40\x74\x28\x44\xb3\x0c\x6e\x01\x16\x96\x39\x31\xf0\xf3\x4c\xf4\xe2\x42\x29\x76\x1f\x14\x43\xa2\x64\x88\xe9\x89\x24\x1c\x6e\x95\xe1\xc5\xc5\x7b\x35\xd9\x90\x1b\x57\xfc\xb8\xe3\x5d\x7d\xdc\xed\x5e\xe8\xe5\xfa\xb8\xdd\xb8\xb2\x33\x2c\x01\xce\xdf\x64\xed\xa3\x7d\x1a\x83\xae\x8f\x56\x39\x58\x7c\xf4\x5b\xe7\xfa\x18\x52\x3c\xf2\x9c\x8b\x99\x6a\xf0\x58\x5a\xfb\x16\x13\x77\xb2\x8e\x17\xdb\x5b\x87\x52\x44\xca\xc8\xed\xed\xa7\xca\x7d\xb5\x7f\xbc\x1c\x51\x3d\x5a\x96\x52\x92\x12\xf5\x3d\x51\xd3\xfb\xb4\xae\x93\x54\x76\x21\x0f\x5a\x3e\x64\x27\xff\x68\xdd\x8c\xf9\x51\x6f\xd9\x8d\x3f\xaa\x44\x42\x1f\x10\x0b\xbf\xb8\x4a\x2a\x2b\x0f\x18\x8b\xf8\x74\x29\x50\x11\x8f\xfd\x21\x05\x9f\x07\x33\x28\x1f\x21\x1f\xf1\x50\x00\xfa\xb1\x4a\xcd\x0f\x92\x4b\x3c\x0e\x34\x83\xb5\xf5\x8a\xf0\x07\xaf\x6f\x4d\x5b\xec\x99\xc4\x80\x7b\xb8\x3d\x1c\xab\xf3\x07\xd4\x8e\xf9\xde\x3e\xca\x4f\x15\xeb\xe1\x36\xb0\x6f\xa1\xdf\x5a\xf0\x4f\x08\x35\x27\xf7\x08\x62\x07\x3a\xf2\xb2\x36\x7a\xe0\xcd\xf1\x53\xa6\x17\x15\xaa\xec\xab\x19\xd5\xed\x7d\xa0\x63\xbb\x87\xca\x12\x3b\x2e\x8f\x14\x8d\xa7\x21\xee\xd8\x38\xf7\xf3\xf0\x20\x6a\x26\xda\xa3\x87\x6c\x58\xc3\xda\x07\x1a\x70\xaf\xcd\x1f\xf1\xb5\x3e\x52\xf8\x4a\x50\x6a\x89\xca\x4d\xc3\x2d\x99\xa6\x61\xf0\x50\x41\xfe\xac\x65\xf4\x8b\xc4\xb0\xc9\xbb\x3d\xc8\x93\x58\x29\xa5\x84\xe9\xef\xd1\x1e\x1d\x97\xc6\xf4\xc7\xe4\xcc\xfc\x7f\xb7\xff\x9e\xfc\x4f\x94\x35\xef\x55\x19\xf1\x36\xb8\xa6\x3c\xd2\xfe\x8c\xf4\x41\xaf\x84\x24\x9a\xa4\x7c\xce\x10\x74\xce\xc1\xaf\xce\x70\x01\xa0\x38\x13\x2a\xa8\xae\xb5\xc4\xe7\x6c\x20\x04\x66\xf3\xda\xc5\x93\x30\xf6\x1a\x18\x2f\x89\x80\x41\x2e\xf4\x04\xf3\xf8\x3b\x32\xfd\x95\x0e\x65\x83\x6a\x9e\xef\x97\x45\x85\x88\x91\x4b\x82\x02\x0f\xe1\xa8\xab\xf4\xeb\xe9\x5b\x6e\xaa\x29\x2d\xb3\x92\x8c\x27\xbb\xef\xd2\x3b\xf2\x6b\x9a\xee\x83\x92\x46\x37\x1b\x63\xc8\x28\xcd\x12\x3f\xda\x11\x61\xe7\x46\x7b\xd4\x48\x93\x67\xe0\xeb\x23\x9c\xee\xb8\x8c\xe9\xb6\x81\xa5\x04\x99\xe4\x09\x03\x90\x4f\xe9\xab\x4d\x8a\xc5\x4f\xf7\x10\xc2\x4b\xf1\xfb\x20\xaa\x44\x25\x1d\xeb\xe7\x80\xe4\xed\x97\x13\x92\x03\x93\x58\xd3\x53\xcb\xff\xa3\x0e\x4d\xd3\xc7\x02\xd0\xf7\xcc\x92\x5c\x9d\x1a\x4d\x49\x1c\x5b\x0f\xc2\x2f\xa4\x4a\x14\x7d\xaa\xa7\x02\x53\x86\xb4\xa6\x69\x64\x31\xd5\x26\xa5\x26\x1f\x74\x4d\x75\xcb\x21\xcb\xb4\xf6\x92\x35\x8b\xa1\xc1\x5f\x53\x00\xed\x34\x34\x9a\x29\x01\x25\x45\x6f\x27\x04\x92\x7a\xdc\x64\xb2\x1e\x1e\x85\x76\x4a\x3d\x27\xf2\x4a\xd1\x60\xe9\xed\x9a\x22\xc1\xd6\x40\x50\x2c\x09\x5d\x62\xc7\x1d\x7f\xa5\x70\x6a\x0b\x89\x29\xed\x13\xcc\xb6\xb8\x37\x99\x03\x0e\xa1\x55\x10\x48\xff\x4d\x9b\x04\xf7\x11\x3d\x67\x20\x16\x06\xb9\xfa\xe9\xf9\x15\x52\x46\xaf\xd0\x61\x31\x48\xf6\xca\x94\x7f\x89\x34\x93\xcf\xb5\x65\xb6\xef\x93\x93\xed\x36\x21\xed\x2f\x0f\x79\x57\x66\x93\xc9\xe9\x84\xcc\x09\xae\xd4\x68\xda\x00\xa2\xdf\x45\x82\x4d\x11\x92\x31\x74\xb9\x34\x0f\xe5\x9a\xf6\x50\xa9\xca\xdb\x39\x4b\x0b\x49\x12\x00\x10\x79\x0a\x51\x27\xf7\xb0\xd5\x76\x12\xa4\x5a\xbf\x3a\xde\xca\xec\x33\x74\xae\xd9\xda\x06\x75\xdb\xca\xce\x0e\x84\xa6\xd3\x2e\xe5\x2a\x43\x63\xa0\xb9\x7e\x78\x7d\x8b\x0e\x5f\x62\x24\x34\x85\x8a\xd4\x2c\x09\x69\x57\x7b\xd2\xed\x7d\x84\x5e\xfa\x24\x3b\x59\x2b\xfd\xa1\xe5\x31\x02\x0e\x06\x43\xe6\x0a\x84\x07\xfe\x12\x4f\x73\xba\x28\xac\xc4\x0f\x13\x39\x2b\x8c\x1b\x4c\xd1\x27\xa4\x32\x4e\xa4\xac\x4d\x50\xaf\x14\xcf\x74\x42\xcb\xa5\x2f\x9c\xa6\xd1\x56\x78\x57\x93\x5b\xc6\x20\xc9\x5e\x3c\x69\x2b\x1b\x9a\x98\x1f\x04\xc4\x07\x93\x46\xd1\x95\xc7\xcf\xa1\x00\xf2\x78\x87\x81\xed\x78\x37\x8a\x3b\x49\x6c\x6a\x24\x3f\xbc\xcf\x01\xf5\x99\xc6\xf1\x9e\xa2\x72\x1f\x25\x98\x36\xb6\x8f\x3e\x4a\x43\x3d\x4d\x16\x92\x4d\x9b\x34\x99\xec\x28\xab\xd4\x9b\xac\xb1\x9c\x25\x07\x37\xa2\xbb\xe0\xa5\x8d\x1a\x35\x79\x36\x36\x58\x2e\x0b\x8c\x02\x29\x14\x9f\x52\xc8\x1d\xbd\xa5\x93\xf4\x9e\xd8\xfa\x8c\xf5\x8e\x60\xe1\x58\xaf\x7f\x64\x99\x10\x61\xe8\xd8\x87\x37\x0e\xc3\x13\xd2\x90\xac\x9b\x0d\x1d\xb5\x0b\x32\x85\x46\x11\x90\x34\x91\xda\x44\x8d\x9f\xda\x49\x5b\x50\x60\x8a\xff\xee\x98\xde\x21\xca\x21\xb1\xb4\x91\xa9\x30\x86\x66\x31\x45\x97\xfc\x1b\x32\x38\x89\xf9\x69\x10\xf2\x46\xd2\x50\x42\x36\xdd\x75\x57\x09\x50\xad\x49\x09\x86\xc8\xe6\x87\x90\x1a\xd5\xaa\x6a\x30\x9b\x80\xa2\x5f\x39\x56\x37\x35\x10\x62\x61\x6f\x19\xb2\x90\xfd\xba\xad\x97\x40\x75\x23\xc8\x22\x7c\x04\x28\xae\xb5\x6a\x8a\xdf\xd5\x97\x74\x63\xd6\x2c\xf9\x20\xc8\x30\x85\x5b\xc2\x88\x09\x9e\x9d\x20\x3e\x31\xcc\x1f\x3f\x78\xc0\x42\xa7\xc4\xd1\x87\x40\x44\x47\x75\x9f\x0e\xc7\x08\x3c\x53\xa7\x29\xff\x79\x6f\x17\xf2\x08\x4a\xc2\x32\x38\xce\x4a\x58\x06\x4f\xe1\x11\x7b\xcd\x98\xaf\xd0\xd3\x70\x59\x27\x25\xee\xba\x6b\x26\x58\x33\x92\x75\x2a\x21\x71\xe4\xb1\x2a\xff\x35\xd6\xb0\xde\xdc\x34\x53\x4a\xd8\x80\x0d\x88\x1d\xa0\xbf\xa3\xed\xd3\x4b\xf5\xb0\x41\x09\x55\x23\x63\xdf\x09\x7b\x94\x83\x0a\xef\x7e\x97\x70\xaa\x5e\x73\x3a\xd4\x4e\x6b\x79\x68\xa5\x74\x0f\xc6\x6c\xad\x92\xd7\x4e\x23\x3b\xa6\x63\x0c\x8b\x01\xf6\x89\xdf\x2d\xf2\x67\x98\x8d\x3c\xfa\x9c\x37\x32\x98\xb4\x80\xfc\x3a\x36\xa9\x5a\x92\x42\x13\x48\x52\x7c\x3c\x49\xf2\x5c\xce\xa0\x3e\x85\xf4\x80\x5d\xf0\x89\x20\x64\xa2\x10\xe8\x91\x3a\x18\x6a\x9e\x53\x00\xbc\x62\xef\x1b\xf9\xc2\x53\x80\x19\x2b\x30\xbb\x29\x91\xac\xe8\xce\x37\x3a\x7a\x5b\x69\xd8\x6e\x48\x83\x49\x77\x76\x7c\x25\x21\x89\xc0\xf9\x8c\x38\x81\x87\x69\x47\xc8\xd4\x49\x93\x49\x3c\x20\x03\xf1\x7e\xa7\xa8\x9b\x30\x04\x95\xa6\x15\xcc\xbb\x79\xa2\x35\x5c\x67\x47\xb7\x7d\x11\x90\x6a\x96\xcf\xe9\x75\x24\xc3\x7e\x88\x47\xfd\x4f\xa5\xb6\xd7\xb7\x8f\xa9\xca\x16\xd2\x58\x6b\xd8\xb4\x8c\x29\x8c\xe6\x0d\x31\xb3\x15\x80\x5f\x19\x84\x11\x36\xfe\xe8\xc1\xa5\x96\x43\x94\xe5\xbe\x12\xe5\xa1\x40\x58\xcb\xbb\x44\xa0\x4e\xca\x3b\x59\xed\xaf\x36\x01\x12\x51\x92\x91\xb9\xdb\xcc\xde\x1b\x6d\xc5\xa8\x10\xa5\x83\x35\xf2\x0f\xa0\x1d\x25\x1d\xa2\x7b\xd5\x9a\xbc\xee\xd2\x8c\x0a\x19\x92\x3b\x36\xa6\x08\xd0\x8d\x2e\xc2\x2e\x95\xa5\x0f\x89\x7a\xd6\x6d\xb9\x42\x49\xe9\xd6\x8a\x8d\x99\xe2\x03\x23\xfe\x56\xc4\xff\x95\xcd\x35\xb4\xfa\x51\xec\x10\x90\xc5\x1b\x7a\xe2\x94\x67\xaa\x78\xb7\x78\x84\x8a\x3c\xbe\x27\x8f\xab\x88\x94\x74\xa3\xba\x74\x4b\xf3\x4c\x3e\xc2\x22\xdd\xad\x16\x31\xe8\xa1\x95\x3d\xe4\x9f\xf8\x00\x5d\xf0\x29\x54\xa3\xd2\xfe\xe9\x68\xe2\x7f\xd3\x26\x41\x1d\x08\x38\x4b\x7b\xa6\xf5\x29\xdd\xa1\x7e\x43\xec\xe8\xc3\x9e\xb6\x75\xe4\xc0\xf2\xf5\x38\xdb\xe0\xec\x39\x02\xde\xb9\x8a\xc6\x2f\x76\x95\x8b\x22\x80\xa4\x6d\x07\xb4\xcf\x7a\x7e\x08\x90\x40\x4a\x99\x7a\x31\xd5\x6a\x55\xff\xfa\x5c\xc5\x09\xaa\xa3\x3c\x81\xc4\x77\x6a\x5b\xe4\x1f\x63\x10\xce\x56\xfa\x2f\x42\x66\x59\xa7\x6e\x12\x8f\xaa\x57\xe8\x3b\x39\x61\x5f\xff\xdd\xd9\x24\x0d\x35\xb2\x91\x91\xa3\xcf\x63\x97\x6b\xe7\x70\xc3\x20\x65\x71\x60\xad\x71\x05\x08\xcf\x5a\x5b\x90\xd0\x52\xcd\x21\x21\x95\x15\x1c\x87\x43\x05\xb5\x9b\x90\x54\x21\x59\xa9\xa1\x9b\x1e\x0c\x60\x65\xa0\x5c\xef\xdc\x2f\x18\x1e\x3f\xf6\xb4\x26\x4a\xb3\xdb\x22\x5f\x87\xd5\x3a\x9c\xbc\x9a\xd5\x27\x2c\x89\x24\x08\x95\x4e\x69\xf4\xac\xc9\x05\x85\xb3\x52\xf0\x87\x55\x1a\x05\x00\x3f\x8e\xab\x2f\xe9\x25\x5c\xd3\x1a\xb2\x52\xc8\x6a\x02\x73\x90\x0b\xa3\xc6\xe4\x43\x81\x34\x8e\x5f\x43\x69\x6a\xb2\x06\xcc\x94\x86\x80\x59\x7f\xb5\x42\x03\x7a\x70\xc1\x38\x7f\x2b\x40\x1e\xf7\x29\xdb\x41\xaf\x5d\xd8\x2f\x0f\xb3\x12\x15\x5d\x1b\x6a\xd5\x6f\xcf\x57\x96\xb4\x93\x7a\x39\xd6\x23\xfa\x16\x09\x2d\x35\x8c\x44\xb9\x59\xfb\xa9\x3c\x31\xd7\xd8\xad\x05\x29\xe5\x30\x64\x65\xf8\x0c\xd1\x07\x1f\x5c\x36\x43\xc2\x4f\x7f\xa8\x3d\x08\x8b\xdd\x84\x53\xbb\x3c\xab\x52\xab\x87\xb0\x01\x19\x5c\x40\x51\xab\x46\xf1\xc2\x0d\xfa\xd7\xe8\x70\x3d\xd9\xeb\x00\x62\x02\xef\x90\x7b\xca\xc9\x20\xad\x76\x1b\x91\x46\xe5\x83\x6c\xd1\x50\x6a\xcb\xb3\xae\xe2\xc1\xea\x22\x4b\x56\x0a\x7a\xb4\x3c\xbb\xf5\xfb\x2f\x75\x4a\x07\xcf\x30\xd1\x55\xe9\xb9\x59\x3f\x57\x04\x2b\x9f\x15\xe3\x51\x41\x79\xe1\x66\x49\x41\x43\x03\x2a\x43\xd7\x7a\x40\x3b\xc6\xd6\x7f\x40\xab\xe5\xb7\x59\x8a\x55\xa0\x66\x84\x90\x53\x83\x60\x40\x6c\xc7\x29\x27\x2b\xf7\x28\xcb\xa8\x13\xb5\x95\xd1\x6e\x88\x47\xf1\xb7\x18\x98\x6e\x09\x43\xb9\x1d\xa9\x14\xab\xda\x10\x03\x32\x68\x48\x85\xf2\x1f\x20\xbb\x76\xd0\x2e\xd6\xad\xa2\xeb\x28\x37\x85\xf3\x8b\xfe\x1f\x9c\x15\x47\x5d\x71\xea\x9a\x9b\x27\x18\x40\x7c\x2a\x8d\x8c\x4a\x0c\xdd\xcd\x7e\x40\xc4\xfc\x5f\x05\xaa\xae\x9b\x05\xfd\x18\xad\x1b\x58\x3e\x43\x78\xea\xc9\xd1\xc4\x90\xa6\xc4\xae\xf1\xa0\x09\x5f\x0c\x94\xf9\x6b\x87\x12\xf7\x53\x1f\x31\xe2\xff\xfc\xa1\xd4\x62\x86\x50\x7a\x98\x25\x26\xe5\xaf\xa0\x4f\xe2\x1a\x4a\x2f\x8d\x6e\x6c\xac\xc1\x0e\x0f\x62\xa7\xcd\x4b\x12\x74\xd2\xcd\xcc\x36\x24\x28\x32\x27\xd7\xe7\xe8\x59\xc3\xe0\x61\xea\x56\xa6\xf3\x50\xba\x7a\x3a\xd7\x60\x98\x27\x98\xf1\xbb\x9c\xd4\x69\x95\x53\xe2\x7f\x3d\x83\xca\x5e\x78\x5f\x8f\x94\x3d\x91\x20\x61\x54\xb7\xb2\x23\x92\xda\xff\x29\xc0\xe3\x88\x8a\x52\xae\xd1\xfc\xbc\xb9\x9b\x74\x67\x31\xde\xa2\x5e\x55\x53\x96\x3b\x8c\x39\x39\x6b\x25\x9d\x30\x3c\x6e\xe9\x50\x1d\x74\x29\x74\x87\xe6\x3d\xc0\x53\x24\xe0\xa4\xfc\x0d\xa7\x3b\x86\x72\x15\x3c\x6e\xa8\x51\xb5\x5f\xdd\xfa\x05\x99\x7a\xa7\xca\x2a\x71\xad\x67\x57\xa7\x72\x05\xad\x55\x22\x5a\xd3\xcd\xdf\xb3\xc7\xbc\x83\x13\x8d\xf4\xf6\x58\x07\x83\x2c\x49\x1b\xcd\xaf\x8f\x22\xbe\x10\x38\x96\xa7\x80\x77\xd4\xec\xc5\xa2\xe9\x0d\x04\x71\xfc\xbc\xeb\x26\xab\x4d\xfb\x61\x6c\x4d\x60\x17\xd7\xd1\x53\xd3\x95\x2e\xac\x19\x36\xc5\xf6\xf6\x31\xe9\xca\x86\x91\x9c\x0b\x4a\xc1\xf6\x4e\x98\x34\xd0\xf1\xe0\x92\x3a\xe9\x21\x2c\xde\x49\x49\xe5\x62\x34\x15\x2a\x3a\x27\xcb\xd8\xf1\xd9\x6f\x14\xe4\xd4\x98\x6c\xeb\x0a\x5c\xbe\x1d\xda\x6c\xff\x36\xd2\x40\xa6\x9b\xbd\x85\x17\x89\x97\x5f\x1b\xe7\xaa\xf1\xf9\xde\x0f\x8e\x71\xbe\xf7\xe0\x8d\xd5\xb7\x90\xee\xf4\x75\xee\xb8\xff\x92\x6f\x51\x38\xc8\x80\x7f\x56\xdf\xc8\x24\xff\xb2\xe3\xf2\x85\x8d\x12\xbf\xef\x6f\xb6\x4e\xb1\x1f\x38\x4b\x40\xdd\xfe\x6a\xec\x07\x73\x99\x90\xe6\xfa\x55\x91\xdf\x41\x24\xd8\x2f\x98\x22\xfe\x40\xbf\x90\x37\xf5\xe9\x1d\xe4\xb9\xb1\xfa\xfd\x26\xce\xdb\x7f\x45\xf1\x80\xc9\xa9\x44\x0b\xbf\x1e\xb6\xe7\x21\x06\x46\xd0\x01\xf6\xec\x7a\x5c\x36\x94\xf2\x00\x9c\x01\xb6\x08\x9f\xca\x18\xe8\xa7\xf2\xe3\xfb\xf0\x0d\x87\x88\x17\x65\xb9\xd8\x9e\x7e\xec\x83\xe3\x5c\xf1\x27\x51\x13\xf9\x03\x3f\x14\x55\x58\x1f\xab\x7b\xb0\xd7\xdb\x3e\xc0\x9d\xa5\x75\x5e\xd4\x97\x7a\x47\x46\x24\x00\x3f\x6c\x43\xa1\xe4\x54\xeb\x1a\x03\x7a\xe0\x47\xd3\x06\x5d\x0c\xf4\x6d\xcf\xeb\xcf\x7f\x99\xa1\x07\x3e\x28\x1e\x6b\xed\x00\x55\xc0\xc2\xbd\xfe\xa4\xb3\x65\xdd\x0e\x4d\x24\xbc\x5d\xd3\xe5\x24\x0a\x65\xcb\x77\x39\xbb\x34\xd7\xb9\x97\x1c\x2a\x5c\xe7\xbf\x82\x5c\xec\xe0\x18\xfa\xe9\x81\xc1\x9a\x60\xe5\xb1\xc0\xf5\xec\x2a\x5e\x6a\xc1\x80\x20\xf9\x1d\x67\x5e\xbb\x4a\x54\x59\x15\x7b\x7a\x33\x95\xe1\xec\x50\x82\x6f\xb6\x30\x93\xcf\x0d\x94\xd7\x7f\x56\x4b\x21\x0f\xb1\xb5\x2e\x23\x16\x3f\x3e\x9c\xe7\xdf\xe2\x86\x41\xe4\xeb\x1f\x61\x04\x1b\x9e\x46\xb6\xc3\x1b\xe2\x09\x62\xfc\xbe\x4b\xd2\xc5\x48\xe8\x81\x52\x5f\x97\x50\x96\x00\x81\x63\x7f\x49\xde\xb3\x9c\x0c\x21\xce\x65\x0d\x4b\x16\x0c\x92\x19\xb0\x7f\x97\xef\xde\x83\x06\x8a\xd8\x9e\xe1\x08\x74\xbf\xa5\xea\x0a\x6d\xaf\x39\x24\x3f\xde\x9e\xf6\x45\x44\x35\x17\x2b\x9f\x7d\xcd\x24\xb0\x1e\x5e\x94\xc8\x52\x34\x78\x46\xe2\xdd\x9b\xa1\x6e\xd2\xac\x6d\x41\x13\x7d\xef\x90\x6f\x31\x30\xf5\x4b\x98\x1b\xdd\x0e\x80\xfa\xe4\xce\x3b\x67\x86\x21\x00\xb8\x4f\xe4\x94\xbf\x43\x9d\xc7\x80\x0c\x2c\xde\x49\xda\xae\x6f\x69\x79\xbf\x21\x7e\xc8\x9b\x6e\xb5\x7c\x17\x07\x87\x72\x58\x1c\x04\x61\xd6\xe8\xd2\x62\x92\xbc\x4a\x11\xcc\x3e\x6a\xaa\x90\xad\x92\x0d\xe3\x7b\x90\x7e\x3c\x1a\xc3\x12\xad\x7b\x85\x4c\x57\xad\x90\xb3\xf2\x55\x75\x77\xbf\xac\xdd\xb1\xb2\x47\xa0\x02\x86\xec\x9c\x4b\x58\x5a\x5c\x4c\xc5\x85\x2a\xd8\x7f\x2e\xf5\x75\x29\x6c\xfa\x2a\x55\x89\x1c\x2f\x25\x38\x58\x39\x16\xb7\xe3\xa1\x16\xd8\xee\xd7\xe8\xc3\x84\x2b\x05\x6a\x72\x3f\x7a\xe1\x3d\xe4\x10\xfc\x85\xee\x6d\xa2\x7c\x0e\xbc\x90\x37\xaa\x7a\x7d\x76\x96\x88\x17\xac\x12\xfa\xb2\xeb\xcb\x1e\x83\x74\xab\x47\x59\x7c\xbe\xc2\x83\xc5\x23\x15\x6c\x2f\x5e\x39\xcc\x19\x5f\xf9\x2f\x49\xbf\xe8\xd5\x99\x7f\x44\x00\x29\xec\xb4\x0c\xc9\x81\xea\xd5\xe9\x7c\xd6\xbd\xf0\xb6\x1d\x99\xfd\x69\x26\x98\x3f\xa1\x63\x66\x98\x89\x94\x40\xec\xd8\x3a\x52\xbc\x07\x5a\x60\xe5\x45\x37\x1e\xd7\x08\x7b\xc5\x7b\x49\x69\x31\x7a\x4b\x11\x2f\xb5\x96\x58\xc0\x28\x73\xe1\x82\x94\x4d\x5c\x2a\x4c\xc7\x54\x9e\x89\x83\xfd\x67\xb4\x09\x0d\x31\x74\x3a\x28\x8e\x86\x39\xd4\xcc\x63\x90\x7d\xf4\x4a\x4f\x1e\xea\x86\xe8\xe4\x75\x62\x7c\x41\xe1\x30\x07\xfe\xa4\x7b\x56\xc7\x45\x21\xed\xeb\xe3\x0f\xe2\x7a\x7f\x44\xf4\xb9\xde\x75\x0b\x1d\xaf\x77\x9d\x29\xfc\xe4\xd1\x05\x4e\x93\x41\x38\x8c\xa2\x59\x77\xfb\x59\x0f\x5e\xb7\xc2\x2a\xd6\x27\x5e\xf8\x5f\x06\x59\x2f\x9c\xd0\xdb\xf4\xeb\x46\x7a\x28\x95\xc9\xe0\x4c\x1f\x32\x50\xa7\x07\xd8\xfc\x96\x5d\x4e\x28\xa5\xda\xd7\x3d\x48\x3f\xac\xba\xb6\x3d\xcf\xd2\x98\xb0\x74\x79\x37\x8b\xdb\xe9\x1f\x52\x94\xb9\x64\x0a\x6e\x65\x6a\x2e\xde\x0a\x31\x32\x3f\x4f\x93\xc7\xb1\x0b\x89\x9d\x6c\x13\xaf\x5a\x25\x39\x65\x4d\x8c\x54\xba\xea\x2e\xc2\xc2\x55\xb7\xa5\x44\x76\xe5\x05\x29\x2e\xef\xf2\x44\x6f\xeb\xf2\x46\xc9\x4f\x56\x25\xd2\x6b\xc3\x07\x1f\x22\x5c\xa5\x51\x05\x6c\x3f\xa5\x58\x70\xf9\x4c\x8b\x2a\x1a\x88\xa6\xf0\x6b\xbc\x0a\xb4\xb9\xa9\x4b\x36\xdf\x3f\x09\xb0\x56\xf7\x2e\xfb\x85\x34\xd7\xed\x3f\xe9\x7d\x79\x29\x73\xeb\x8b\x46\x5d\xfe\xd0\x30\x3d\xa5\x43\x76\xcf\x8a\x0b\xf3\xba\x04\xf1\x9d\x5f\xdd\x67\xdb\x50\x76\x89\xb7\xac\x34\x81\x2b\xcb\x3f\xc4\x80\x77\x57\xae\xf4\x71\x23\xec\xcb\xfa\xe6\xfe\x44\x9d\x4f\x7f\xc6\x3f\xa1\xf8\x41\xf5\xae\x76\xce\xda\x40\x9c\x5e\x00\xbf\xc0\xd4\x2f\x25\x29\x6e\x6a\x20\xde\xb3\x54\xd4\x4e\x5e\xc9\x53\xf2\xaf\x9e\x7f\x0b\xf9\x24\xa6\x8a\xdb\x98\x80\x9a\x5f\xdf\x4f\x70\x1a\xcf\xef\x3b\xb9\x26\xfb\xf9\xad\x47\x17\x21\xfa\xb8\xcc\x90\x14\xc0\x10\x94\x6e\x8e\x4a\x44\xdf\x0d\x52\xd4\xc5\x5a\xbe\x36\x32\x07\x0b\x98\xca\x2a\x48\x97\x95\x3e\x8d\x35\x7d\x97\xfe\x9b\x69\x89\x6f\x40\x89\xc6\x50\x19\xfb\x72\x55\xa2\xa8\x03\x71\xd8\xaf\x19\x94\xdc\xc5\xf9\x66\x3e\xd1\xf9\xca\x1e\xd0\x3a\x5f\x4a\x2c\xe1\x2e\xb4\xa9\x3f\x6f\x30\x91\x1c\x1c\xd4\x28\xb9\x69\xef\x44\xc1\x31\x85\xbb\xb0\x20\x81\xab\x7b\x2d\x54\xcd\xfa\xf8\xa2\x7d\x95\x91\xa7\x6a\xf8\xe0\x8d\xb2\xef\xcd\xad\x90\xce\x2b\x64\x46\x0c\x65\xeb\x04\xfc\xdd\x99\x3e\xf9\xb6\x1c\xe1\x0a\xc2\x55\x68\x5e\xa5\x8c\x75\xeb\x5e\xd8\x47\x78\x85\xec\x17\x47\x8d\x2e\xae\x19\x22\x5d\xad\x2a\x9b\x9e\x3a\x65\x14\x62\xc3\x67\x46\xf1\xa3\x4b\xf5\xb1\x83\x90\x1f\x93\x84\xcc\x85\x94\x05\x82\x83\x8e\x4c\x86\xea\xc5\x9f\x55\xd9\x01\x85\x58\xd9\xd5\xe7\x1f\x6d\x29\x04\x7b\xae\x9a\x55\x4b\x58\xad\x1e\x3a\x4a\x57\x91\x80\x59\x89\x04\x03\xab\x21\xf8\x1d\x1b\x78\xe7\xae\x37\x16\x37\xc5\x9a\xdb\xa5\x71\xf6\x12\x43\xb6\xae\xd7\x63\x6d\xcf\xa1\x87\x68\xf0\x77\x7a\x90\xee\xf8\x23\x22\x80\x04\xb4\xf0\x57\xd8\x28\x3e\x94\xd2\xd2\xae\xe4\x6b\x57\x0e\xcb\x02\x45\xc2\x44\x57\x30\x44\x20\x20\x86\xe2\xff\xee\xc2\x5e\xa8\xeb\x81\x49\x77\x07\x90\x91\x1c\xc0\x2e\x61\x03\x05\x03\xd5\xa0\xe7\x51\xa8\xe6\x60\x80\x3e\x90\xe7\xa1\xf4\x05\x03\x92\x21\x3b\x72\x88\x8a\x65\xf1\xc7\xdc\xbc\xc9\xef\xc4\x91\xe8\xef\x0a\x10\x67\x4d\xae\x53\x41\xa8\xf7\xea\x48\xa5\xe7\x68\x9f\xf5\xd6\xa5\x7a\x66\x33\x15\xc7\x44\xe8\x3e\xd9\xc1\xb2\xa2\x48\x82\xac\x79\xc7\xff\xac\xff\xe7\x83\x61\xd8\x85\x70\x03\x29\xda\xc1\xad\x43\x69\x7b\x67\x65\x52\xf0\xb9\xdd\xa1\x21\xb5\x9d\xd2\x44\xda\x44\xd3\x76\x10\x3a\x59\xc2\x45\x58\x12\x4d\x9b\xcb\xc6\xfa\xf5\xad\x37\x67\x1a\xc0\xc4\xe7\xee\x6b\xed\x2a\x66\x3d\xc9\xe5\xb4\x1e\x8b\x74\xd2\x0c\x65\xad\xd2\xab\xba\xa6\xa7\x5e\xa3\x35\x51\x61\xfc\x84\xa5\x32\xbf\x10\xd8\x23\x1f\x52\x3c\x2b\x24\x6e\x9c\x7f\x35\x94\x67\x0d\x06\xd1\xfb\x2c\xaf\xc6\x1b\x65\x03\x54\xbf\x1f\x50\x8e\xf7\x32\x0c\x11\x4f\x44\x02\xf9\x63\x5d\xfa\x8c\x80\x97\x6f\x25\x77\xb2\x51\xf6\x49\xcd\x6a\xe8\xfe\xa8\x1b\x6a\x90\x5a\x49\x65\x55\x72\x24\xc5\xd1\x66\x3d\x0b\xeb\x7b\x71\xb2\xc6\x3a\xb5\x2d\xae\x27\xff\xc3\xf4\xe7\x12\x15\xcf\x18\xec\xb7\xd2\x73\x3e\xac\x44\xae\xa7\x23\x19\x4f\x9e\x73\x7d\xe9\x45\xb1\x13\x5c\x0c\x6d\x60\x22\x47\x07\x28\x1f\xcf\xbc\x77\x5d\xb5\x42\x53\x29\xc4\x47\xd5\x7b\x3c\xe7\xcc\xff\xe6\x50\xdb\x9b\xb3\x06\x2d\xc8\xfc\xf0\x2e\x03\x26\x60\xf9\x4e\xce\x69\x29\xdc\xc8\x7a\x36\xce\x96\x82\x36\x5a\xe5\xaf\x86\x0b\xa5\x56\x75\xef\x49\x24\x94\x7a\xc8\xe9\xcc\xb7\xe4\xc9\x6e\xf9\x10\x22\x7e\xf7\x51\xa9\xd7\x23\x37\xb6\x68\x50\x4f\xcb\x1d\xf0\x07\xe5\xc6\xd4\x14\xab\xa9\x4f\x38\x41\x13\x52\xc2\x0d\xc6\x30\xac\xb9\xf3\xa6\x8d\xb6\xc4\x8b\x82\x12\x1c\x3f\x4c\xb4\xb5\xf1\xdd\x61\xd0\xe7\x65\xc8\x8e\x59\x85\xc2\xd7\x2b\x43\x71\x2d\xd6\xc1\x66\x53\x30\xb4\xbe\xb2\xb2\x28\xce\x9c\x94\x2b\x72\x4a\xa9\x02\xe5\xaa\x92\x6a\x93\x98\x03\x96\xe2\xd6\x58\x63\x36\xe0\x74\xb7\x1c\xae\x84\x78\x9a\xd2\x2a\x99\xd5\xde\xa5\xd1\xde\x9a\xb7\x83\x60\xda\x1d\xe0\xf8\x09\x8e\x21\x7d\xb4\x2b\x96\xf1\x2b\xb0\x72\x0a\xed\xb1\x7b\x08\x7d\x31\x68\x23\xc5\x76\x5d\xab\xd2\xe5\xd1\xfa\xcd\x70\x21\xb4\x59\x82\x75\x58\x08\x7f\x56\x5f\xe8\x7b\x43\x43\x41\xa8\x76\x14\x23\x2f\x60\xf2\xc5\x1d\x95\x21\x14\xd7\x36\xd5\xe4\xa1\xa1\x46\x5c\xf6\xd8\x16\x52\x82\xfb\x33\x70\x96\xbe\x5a\x59\xaa\x74\xe7\xec\xf5\x64\xb8\xcd\x8d\xc8\x8f\xbe\x6d\x7f\x5d\x01\x25\xa1\x96\xb7\xae\x1c\x67\x0f\x7b\xa6\x85\x04\x16\xa6\xfe\x7b\xac\x53\xaf\x53\xa4\xc7\xa3\xd3\x1f\xb8\xd8\x1f\x44\xea\xdb\x87\x8a\x3d\xd0\xa3\x06\x78\x10\xec\x91\x01\x7f\x8e\xd4\x93\x3a\xd3\x27\xde\x09\x38\xd5\x7a\xf9\xbf\x2e\xd2\xf6\x92\x7e\xd9\xcb\x67\x65\xfd\x60\x1a\x75\x9d\xb0\x48\xf0\x12\xd3\x7e\x0e\x76\xef\x10\xee\xc4\x53\x64\x1f\x9d\xf0\x2b\x62\x35\x85\xf8\x9e\x3a\x2d\x08\xf1\xf1\x64\x36\xd2\xe4\xbb\xe0\x93\x9d\x94\x44\x5b\x59\xed\xdb\x98\xe4\x0a\xf5\x37\x0d\x08\x01\x36\x5e\x9b\x73\x22\x05\xd7\x38\xd7\x80\xb0\x3b\xeb\x3d\xeb\xed\x5d\x21\xf0\x99\x42\xe8\x0d\x96\x06\x38\x6f\xfb\x4c\xdf\x70\xcb\x6c\x9f\xc1\xab\x1d\x2b\xd5\x2d\xc4\x74\x3c\x6b\xcf\x66\xbd\x29\x4d\x2a\xb7\x5b\x9a\xf4\x90\x5a\x63\x86\x0a\xd4\xd4\xa4\xd6\x05\xc4\xd2\x0f\x75\x0f\x1f\xef\xff\xb6\xfa\xf1\x08\x6c\xab\xff\x8b\x96\xb7\xd5\x9b\xdd\x0c\x03\x9b\x67\xd6\xf9\x9d\xf8\xc7\x28\xb6\x49\xcf\xc1\x45\xcd\x72\x80\x61\x65\xca\x1a\x16\x14\x90\x31\xa8\xc0\x40\x0b\xc7\x21\x00\xaa\x98\x59\x5b\x2f\xd6\x8e\xb5\x24\x85\x87\xd9\xf8\x15\xb7\x6e\xa7\x02\x89\x34\x0a\xcb\x21\x3d\x7c\xe4\xd6\xcf\x99\xca\x44\x86\x18\x2d\xb0\xce\xd9\xc5\x6b\xa4\x9e\x58\xb5\x66\x2f\x36\x96\x51\xb9\x81\x10\x48\xb3\x57\x57\xa5\xf4\xd4\xa6\x3c\xe7\x24\xc9\x2d\xa8\xe1\xef\xbf\x5b\x81\xb9\x16\x5d\x88\x86\xd7\xd0\x42\x68\x13\x0f\xa9\x7a\xcb\x00\x26\x03\x6a\x48\xbd\x0d\x89\xf9\x58\xa0\x06\x54\xa6\x72\x03\x52\x3f\xab\xf7\xd2\x61\xb3\x2b\xc1\xae\x72\x4a\xd0\xb7\x95\x83\x3b\x52\x83\xcd\x06\x0d\x90\xb7\xde\x28\xc4\xb6\xbb\x3c\x3b\x77\xdd\x25\x85\xa6\x57\x12\x56\x67\x67\x90\xc1\x99\xe3\xdb\x65\xd3\xdc\xe1\x0b\xd5\x4a\xa1\x12\x5b\x7f\x38\xee\x79\xdd\x9f\x81\x96\x78\xd7\xe6\x4a\xf1\x37\x77\x64\xf1\xdf\x9a\xef\x2b\x94\xce\xce\x43\x32\xd7\x56\xb0\x8f\xd0\x22\x5d\xb3\xfd\xc3\xcd\x01\xee\xe2\x6b\xb1\x6f\xe9\xb1\x1f\xe0\xaa\x72\xc9\xff\xec\xf4\xd0\xc5\xc6\x72\x57\xb3\x43\x9a\x26\x55\xf9\x90\xa5\x59\xf4\xff\x99\xe7\xcd\x7c\x24\xcc\x62\x6e\x79\x94\x9a\xda\x90\xa9\x80\xda\x94\x40\xe3\xf0\x4d\x01\xb3\xfb\x92\xa2\xd9\x0d\x5e\x0a\x11\x1e\xbe\xe4\xfe\x30\xdf\x22\x3d\x3f\x1b\x0c\x4a\x4f\xed\xb8\xf5\x1a\xa7\xa3\x1e\x0c\x84\xb8\x1b\x2c\x7d\x3b\x30\x77\xd5\xb9\x56\x4d\xcd\x8d\x3d\x3f\x70\x4c\xe9\x0d\x00\x75\xb5\x2a\x36\xb1\x75\x1d\x78\xa8\x12\xba\x23\x2e\xa2\x16\xc9\x67\xe8\x0b\xef\x61\x05\x6a\x7d\x2c\x4d\x14\xa1\xb7\xe5\x03\x4e\x37\x1c\xcc\x5a\xb5\x96\xd0\x4d\xbb\x2e\x51\x16\x80\xf5\x6f\x4d\x29\x19\xa0\x6e\xd2\xdd\xc2\x36\xc6\xe0\xc1\x66\xe1\xb0\x36\x21\x80\xde\xd0\xc3\x13\x1a\x58\xff\xdb\xa0\x4d\xe5\xcd\x01\xb9\x01\x1f\xa0\x1d\x50\x65\xdc\xd9\x95\x3e\x30\x81\xcd\x32\x78\xd2\x87\x8b\x25\x36\xfd\xd7\x53\x85\x03\x26\x8a\xaa\x95\x17\xe3\x38\x07\x3f\x0d\x41\xcf\x7b\x3c\xe4\x42\x79\xa8\xc3\x62\xa5\x2e\x22\xf3\x12\xf2\x44\x71\xa8\xc6\xb9\xbd\x03\x72\x78\x92\x6f\x43\xb0\xd0\x2f\xa0\x5e\xa1\x31\x05\x4a\x33\xf7\x47\x44\xc5\x43\x41\x70\x42\xe3\xb4\x9a\xdd\x06\x6b\xeb\xb8\xce\x1a\x04\x0a\x38\x42\x83\x8d\xbb\x6e\x4d\x41\xd9\x03\x95\x14\x5d\x9f\x3c\xaf\x8a\x9b\xad\x88\x0e\xa9\x2f\x7a\x44\xf6\xf9\xc1\x08\xf2\xb1\x4a\x86\x4f\x4a\x6a\x40\x45\x72\xd5\xd6\xf8\x7e\xf9\xb8\x0e\x17\x57\xe7\x08\xf4\xf8\xd9\x86\x3b\xf4\x07\x6f\x28\x1d\x85\x0a\x69\xcf\x3d\x76\x7a\xee\xbd\x15\x39\xfc\x53\xe1\x06\xf9\x70\x6e\x8c\xfd\x90\x38\x22\x58\xd3\xfc\x5f\xc4\xff\x8f\xa2\x2a\xed\x88\x30\xc0\x21\xc7\xbc\x03\x9d\x53\xa4\xb2\xdc\x2f\xee\xcd\x14\x55\x8e\xd1\xb9\xc0\xc9\x66\xe8\xa7\xd9\xfb\x4a\x45\x39\x1b\x92\x30\x4e\x75\x64\xf9\x44\x50\x9e\x0c\x21\x13\xaf\xa5\x0e\xf4\x3c\xbf\x02\x89\xe5\x93\x89\x49\x98\x57\x92\x5c\x59\x93\x2e\x9d\xf3\x80\x79\xe0\xbd\x2b\xc2\x11\x72\xdf\x9d\xea\x42\x50\x50\x93\x5c\x9a\x18\x50\x47\x46\x47\x82\xff\x63\x3a\xfc\x91\x3e\x67\x95\x78\xd9\xab\xa7\x77\x1a\x66\xaf\xdc\x55\xd0\xbc\x49\x3b\xac\xfb\x72\x15\x29\x8a\x85\xfa\x9a\xdd\x1d\x3e\x0b\x7b\xb7\xe8\x2f\x64\xdd\xe6\xef\x2f\x5c\x76\xb0\x57\x04\x5d\x34\xc9\x9e\x02\x7a\x93\xf0\x9f\xa4\xd1\xf4\x30\xad\x32\xff\xe3\x1d\x4d\x52\xc3\x38\xdc\x2d\x82\xd3\xa0\x47\xd2\x53\x45\x8d\x12\x82\x7f\x29\x4c\x26\xa0\x12\x3e\x8e\x3a\xfd\x9e\xba\x6e\x1d\x8c\x95\x42\xb8\x4d\xfd\x9b\xc3\x1d\x94\xa9\x96\xd6\xab\xca\x23\x4d\x4f\x7e\x5d\x52\xee\xb6\x26\xbf\x2a\xce\x59\x5f\x9a\x3f\xae\xf7\xf5\xd6\xdb\x8a\x60\x33\x33\xd2\xeb\xc5\x6e\xa8\xa7\xd7\x76\x65\xb4\x73\x53\x19\x71\x29\xd8\xec\x8e\x12\x39\xab\x89\x1a\x68\xbb\xb4\x7a\xa0\x86\xe6\x05\xc7\xa0\xe8\xc4\xeb\xd8\x07\xb5\xca\x6d\x94\x2a\xde\x35\x22\x22\xfe\x5a\xd6\x18\x35\xd4\xe5\xf6\xf1\x75\x5d\xaa\xd3\x57\x21\x25\x20\x91\xb2\x70\x19\x36\xc0\xda\x16\x7a\x66\xa1\x0a\x5f\x3d\xf7\xcb\xab\xbc\xaa\x94\xf6\x3a\x21\xa3\xd0\xff\x39\x65\xae\xc8\x48\x5f\xd2\x2f\xe0\xd8\x1c\x19\xd8\x71\xd7\x80\xbb\x62\x3c\xbc\xdd\xcf\x99\x19\x42\xd5\x93\x3f\x88\xf7\xdb\x1f\xef\x6e\x5d\x4f\x57\xf3\xaa\xed\x47\x1a\xdd\xab\x42\x0e\x7b\x95\x5c\x5a\x0b\x0a\x09\xa0\xa2\xec\xdd\xc4\x03\x20\x69\xf3\xe4\x4d\xef\x8e\x5e\x4e\x26\x1a\x2a\xe5\xd0\xc2\x06\x6d\x2f\x3d\xce\x6a\x70\x57\x82\x3a\x94\xd0\x9a\xc7\xd1\xfb\xe2\x10\x3f\xd1\xc5\xd1\xf4\x09\x39\xa6\x97\xe3\xee\xda\x9c\xd1\xef\x41\xce\x61\x77\x12\xd8\xf3\x3b\xd2\x83\xf6\x7c\xa3\x1f\x46\x14\x77\x68\xf7\xb1\x66\x28\xe6\xee\x90\x85\x3a\x25\x72\x46\x59\xa7\x5d\x19\x99\x56\xfa\x18\x0e\xa5\x8c\x18\x76\x89\x14\xee\xff\x88\xa5\xec\x39\x85\x06\x9b\xf7\xbc\xf6\xf4\x82\xa2\xe9\x4a\xc8\x1b\x81\xee\xbe\x7f\x73\x86\xbc\x2b\x08\x77\x10\x8a\xa5\x29\x26\x0e\x10\xd3\x02\x12\x73\x95\xc8\x9a\x64\xd6\x0e\x8f\x1c\xee\x69\x73\xe5\x37\x4f\xf9\xe0\x7e\x8b\x01\xeb\x81\x50\x96\x2d\x12\x5c\xb6\x8f\x94\xac\xac\x8f\x1b\x8a\x69\x10\x5f\x0b\x6d\x25\x1b\xc7\x31\xb1\x69\xbb\xc9\x72\xd8\xee\x5a\xf8\x9f\x7d\xd2\x3f\xf6\xf4\xe0\x9a\xc5\xea\xfe\x3f\xaa\x38\xc1\x26\x7b\x15\xdd\x6f\xbb\xc3\x80\xdc\x63\x43\x94\x58\x53\x53\xbc\xb5\x9b\xea\x63\x1f\xaa\x8f\xa9\xf9\x36\xc0\x7c\xd3\xcd\x3e\xdc\x26\x6d\x35\x55\x5b\x5b\x64\xc3\x53\x49\x4d\xb3\x09\x58\xa0\x14\x19\x24\xe1\x3e\x84\xfb\x25\x37\x68\x57\x48\xfb\xde\x5b\xac\xc6\x3c\xc8\xb7\x2f\x6c\x31\xeb\xe4\x4b\xfa\xe5\x06\x07\x64\xb2\x4b\x37\xed\x4a\x6c\x32\x1c\x92\x34\x83\x40\xcf\x93\x73\x6e\x94\x58\xbb\xb8\x76\x55\x3c\x1f\x11\xae\xd0\x4c\x83\xe0\x10\x01\x1f\xfe\x56\xe3\xdd\xdb\x6a\x26\xc5\x60\x8b\xf1\xf3\x86\xcc\xac\xef\xcd\x3d\xcb\x27\x7d\x53\x87\x67\x40\x66\x00\xc3\x79\x97\xc7\x2d\x2e\x2c\xee\x7b\x63\x72\x5b\x3a\x65\x45\xa9\xd2\x5b\x59\x6d\xf0\xf2\xf2\xac\x9d\xcd\xa7\x97\x95\xed\x8d\x34\x67\x56\x20\x5b\x09\x11\x31\xe4\x4d\xab\xe6\x03\x16\x87\x1d\x30\xec\x63\x48\x9d\xd0\xb0\x80\x0b\x3f\xf4\x08\x53\x30\x2c\xea\xf6\x59\x3d\x4e\xe2\xb3\x55\xad\x0b\xc5\xd1\x9a\xf2\xf4\x88\xfc\x51\x64\x06\x8e\x10\x9f\x09\xd5\xb3\x5d\x19\x10\x5b\xd8\xc6\x6d\x88\xb3\x3c\xf8\x4f\x76\x91\xad\xe4\x45\x65\x1b\x44\xbe\x29\xd8\x36\xbe\x23\x46\xb3\xfd\x84\xa6\x46\xeb\x4c\x89\x06\xb2\x8d\x7b\xd6\xca\x5d\xfa\x63\x5b\x61\x02\xa1\xa1\xae\x75\xb6\xba\x6f\x5e\x0e\xfc\x0c\x25\xb3\x88\x2f\x6e\xe3\x72\xeb\xdf\x8b\xdf\xf5\x93\x38\x3d\xf9\x7e\x8c\x73\xd2\xe4\xc0\x36\x5a\x7f\xe0\xe0\x8b\x3a\x3e\xd7\xfa\xd3\x63\x93\xae\xdb\xf8\x08\x7b\x8f\x6d\x9c\xd2\xae\xa4\x23\x88\xb0\x31\x81\x03\x62\x6b\x94\x95\x1b\xc7\xf5\x13\x5c\x27\x2c\x14\x89\x75\x41\x6b\x6d\xd3\xa6\x3d\x3f\xce\x55\xd7\xae\x0e\xa3\xec\x7a\x71\x10\x09\xd5\x05\x02\x4a\x78\x6f\xf4\x2c\x5f\x47\x98\x4d\x5d\x57\x49\xb4\xad\xf9\xd5\x11\x33\x4f\xa1\xd1\x86\xe4\x53\x2a\x74\x7d\x64\x61\x61\x48\x63\x31\x43\xf2\xb2\xd9\x6c\x58\xc2\x5b\xee\x22\x6d\xef\x10\x64\xbb\xe6\xe2\x7c\x7f\xf8\xaa\xb7\x3d\x00\x8f\x27\x0d\xd6\xcd\x93\xf6\x78\xba\xf8\x00\x20\xd1\x56\x09\x70\x01\xbc\x5b\xc8\xf1\xda\x25\x7a\xd6\x1a\x13\xa2\x28\xc4\xa6\x93\x35\xe6\xec\xc3\x8b\x8c\xad\x34\x10\xf5\x19\x01\xa8\xbe\x67\x68\x0b\x61\xb5\x2e\x31\xd7\x86\xa6\xed\x07\xfd\xef\x08\xcd\xb9\xfd\x26\x8d\x68\x73\xbf\x43\x02\xca\xaa\x71\x57\xf4\x82\x74\x7d\xf6\xca\x7f\x25\xbc\xa6\x2a\x02\xd3\x4e\xdc\x6c\xbd\x06\xfe\x0b\x79\xe6\x8b\x90\xe4\xd5\x64\x3a\x05\xd0\xe3\xbe\x5b\xfa\x93\xd8\x1f\x94\xd8\x74\x6b\x8b\x9e\x0a\xbf\x0c\xb8\xf9\x5d\x02\x99\x67\x99\xee\x2c\xa5\x36\x64\x66\x12\x80\xa1\x10\xba\x6b\xaf\xa4\x33\x85\x53\xb6\x21\x37\x03\xd7\x2f\x50\xcf\x7a\x73\x3b\x3f\xb6\x2c\xeb\xc7\x1b\x7d\x2b\xa2\x03\xbe\xde\xd1\xb7\x33\xc4\x0c\x59\x64\xec\x51\x3d\xcb\xbe\x47\x4a\x7c\xf9\x87\x49\x65\x36\xca\x35\xac\xf7\xcf\xc9\x6f\xb5\x96\x82\x73\x9c\x20\x2b\xcc\x0c\x2d\xad\x48\x24\x67\x8d\xb6\xde\x49\x86\x70\x6b\xfd\xea\x14\x22\xed\x41\xd1\x4d\xf2\x6b\xaf\x48\x76\x59\xeb\xad\x12\x62\x80\xdc\xaa\x49\xf3\xad\x29\xf8\xb0\x56\x4e\xad\x59\xa9\x86\x0b\xda\xfd\xf6\xa1\x36\x0a\xb1\x51\x2f\x13\x06\x04\x71\xbe\xb9\x85\x04\x9c\x04\xc3\x30\x20\xf3\x43\xd8\xbd\xe3\x47\x01\xdd\xda\xfe\x9b\x8a\x34\x97\xad\x3b\xaf\x94\x4c\xb8\xfa\x67\xb6\x74\x6b\xf1\xd0\xfb\xea\x02\x92\x13\xd7\xa0\x89\x75\x79\x26\x97\x71\xf3\x4b\xb2\x8b\x0d\x42\xa6\x61\x26\xa2\xae\xe2\x59\x59\x29\xd5\x5f\xeb\x61\x3e\x39\x3f\xb2\x96\xa9\x6b\xc4\x4d\x12\x50\x95\x30\x32\xfc\x12\x9a\xb4\xd2\xf2\xe7\x64\x4d\xb4\x66\x34\xc1\x7a\x7a\x20\x61\x52\xbc\x8d\xb1\x4f\xb0\x8d\x25\xcb\x06\xc5\x38\x76\xfe\x57\x4a\xa6\x10\x15\x8a\xac\x61\x7a\x46\x65\x1c\x6a\xa3\x7a\xc9\x9a\x9f\xcf\xbe\x23\xb8\xa8\x94\x57\xcb\x6a\x33\xd7\x88\xb2\x1b\xd0\x46\xe4\x22\x40\x37\x6e\xd3\x9a\xb1\x8e\xff\xe7\x40\x79\x72\x06\xfc\x66\x42\x86\xd6\xa5\xf5\xd2\xa7\x4a\xec\xed\xdd\xa4\x95\xf6\xe6\x2c\xba\x55\xe3\x94\xb5\x53\x1e\x81\x8b\x55\xfa\x10\x57\xf7\x34\x5d\xb7\x3f\x14\xe2\x4b\x87\xb9\x68\x26\xe4\xb8\xdf\x82\xf0\x1c\x02\x5d\x89\x9b\x85\xc2\x93\x0d\x68\x5b\xd1\xf1\x38\x9b\x0e\xf3\xbc\x50\x9a\xe3\xce\x98\x47\xe6\x1d\x4f\xbb\x46\xcf\x40\xaa\x38\x5d\xdf\x47\x53\x51\x8e\x15\xf6\x72\xec\x99\xd7\xab\xfb\xad\xf0\xff\x50\x8e\xd6\x89\x37\xf8\x0b\xaf\x94\x8c\xf3\x0f\x8c\xbf\x1a\x04\x0e\xea\xd8\xfd\x85\xc2\xde\x93\x43\xa4\x3e\x76\x47\x3a\xa6\x04\x12\x53\x27\xda\xad\xd1\x56\xac\x69\xe4\x5c\x92\x01\xe8\xdb\x09\xce\x9e\xb2\x4b\x51\x3a\x5c\x00\x7c\x64\x51\xbc\x12\xcd\xd8\x00\xfe\x73\xf1\xb9\x33\xd4\xaf\x6e\x8e\x82\x96\x5b\x29\x87\xd6\x86\xf2\xf5\x59\xdc\x02\xcf\x77\xbf\xd7\x3f\xd7\xee\xba\x17\x06\x62\x97\xdb\xeb\x82\x45\x4e\x40\x56\x52\xb2\x0b\x54\x60\x09\xb2\xb5\xcf\x79\x59\xa7\xca\x6b\xcc\x05\x46\x5d\x89\x80\xd2\x73\x77\xaf\x37\x0d\xe7\xa7\x04\xe9\xec\x1d\xee\xda\x6d\x92\xb7\x5e\x9c\x4b\xe2\x27\xc1\xc8\x5d\xff\xa3\x5d\xe1\xd2\xa4\x8b\x60\xe0\xe1\xb3\x49\x0b\x9c\x00\x56\x89\xd1\x15\x89\xe9\xb9\xce\x36\x7f\x5a\x7d\x25\x7a\x9d\x02\x35\xee\x5b\xaf\xee\x87\x66\x6d\xcf\xc6\x48\x2f\x58\x1d\xd4\x9b\x63\xbf\x7f\xa1\x16\xc0\x52\xdb\xc1\x0d\x5b\x8f\x43\x2f\x15\xb2\x71\x0e\xe0\xee\xdc\xb8\xdd\xbc\xce\x99\x92\x6a\x55\x69\x7b\x8b\x0c\x6c\x08\x43\x32\x6f\xfc\xde\x3c\xfe\xc0\xfe\xfc\x82\x18\xef\x5c\x9e\xcc\x25\xc5\x12\x0a\x0c\xfc\xa4\xcb\xb6\xb3\x59\x5c\x82\x55\x4b\xd9\xba\x46\x64\x23\xa0\x2e\x58\xc7\xee\x0b\x14\xeb\x74\x52\xab\x0e\xbd\xb0\xa1\x90\x34\xe1\x56\xa4\x5b\x0a\x40\x94\x28\xc4\xeb\xec\x29\x48\x4e\x6c\x01\x31\xe2\xc8\x5d\xd5\x4e\x93\x2e\x0b\x3e\xc1\x4c\xc0\xf9\x66\x07\xff\x49\xe6\xce\xaf\xa1\xb4\xa5\x4b\xd8\xd9\x87\x18\xc3\x38\xeb\x99\x7d\x23\xd3\x0e\x1e\xa1\xd2\xb8\x73\xb6\x2e\x4a\x5e\x75\xf8\xd9\x2d\xd4\x39\x88\x14\x4b\x5b\x1c\x6f\x35\x34\x8b\xd7\xae\xdc\x3a\x77\xb9\x44\x1b\x9d\xf2\xb6\x60\x6c\xda\x9f\x6b\x99\x24\x5a\x08\x67\x28\x96\x56\x39\xfb\xbf\x7c\x54\xd9\x45\xf2\x10\x19\xa4\xdc\x1d\xe8\xfd\xac\x97\x17\xe6\xd1\xfd\x47\xc5\x3c\x2f\x76\x69\xe4\x45\xbb\x0a\x94\xa4\x86\xb7\xc3\x40\xdd\x7f\x5d\xde\x0e\x4c\xf5\xf3\x6a\xb3\xb4\xb4\xb8\x50\xc8\x1f\x5a\xe0\x36\xa8\x35\x92\xf4\x5e\x32\x05\x97\x96\x9c\x57\xe9\xec\x25\xf7\x61\x59\x22\x97\xc8\xc0\xca\x53\xe9\x94\xd6\x52\x84\xe0\x5d\x97\x0a\x24\x7d\xf0\x24\x3c\xbd\x3e\x86\x88\x1e\xdf\x31\xab\x72\x6e\x95\x08\xbf\xd9\xd8\x96\x1b\x1e\x2a\xd6\x9b\x9b\x1d\x49\x00\x7e\xd1\x21\x8c\x68\x15\x97\x57\xc7\x4b\x0c\xdc\x1d\xfc\x3f\xaa\xde\x2e\xd9\x59\x9e\x07\x16\xbd\x3f\xc3\x78\xe7\x75\x2e\x0c\x18\x70\x02\x98\x8f\x9f\xe4\x49\xaa\xf6\xdc\xb7\x5a\xdd\x72\xd6\xae\x5a\x55\x6e\x58\x04\x0c\x18\x5b\x96\xa5\xee\x85\x80\x9c\x8e\x9a\xfc\x3e\xd3\x4a\xce\xc1\xe4\x31\x27\xc1\xf4\xb7\x2c\x7f\x98\xe0\x9f\x21\xfc\xfc\x4c\xa3\xbe\x73\x2d\xdc\x3e\x53\x17\xf7\x92\xca\xec\x7d\xdd\xe3\x66\x7b\x79\x54\x17\x26\xe5\xeb\x79\xd4\x07\x3b\x58\xf0\xf1\x69\x15\xe5\x51\x07\xb1\xf6\xa5\x9e\x52\xd3\x8f\xb2\xc5\x02\xd6\x03\xd3\x5f\x52\xf9\x79\x08\x87\xb7\x88\x47\xa6\xa7\xe0\x61\x13\x30\x72\xf0\x65\xbb\x6b\xf9\xd3\x80\xa7\xa0\xc4\x7e\xa4\x77\xd0\x17\x3d\x40\x95\xe1\x4d\xdc\x7a\xf1\xe3\xa3\x52\xc3\xa9\x43\x7f\xce\x60\xf8\xbb\x78\xd4\x56\x79\x8a\x4d\xaa\xed\x86\xa4\x55\xfd\x48\x4b\x65\x4d\xcc\x02\x1d\xf8\xbf\x89\xf7\x95\x7a\x0f\x68\x71\xc8\xc9\x53\x79\xd3\xfd\x0c\x35\x41\xf6\x07\x66\x53\xfb\xc1\x88\x4b\x67\x63\x28\x27\x5d\x2e\x56\x9a\xf5\xe8\x68\x73\xde\x79\x47\x63\x7c\x83\xa5\xa3\xcf\x69\xfe\x88\x4e\xee\x23\x02\xbb\x8f\xc7\xb9\xfa\xae\xb7\x3b\x11\x66\x4f\xbb\x0e\x92\x3a\x6c\x84\x0e\xdb\xac\xd0\x90\xf9\x3e\x16\x28\x0c\x9c\x8e\x23\x4e\x6d\x76\xcb\x32\x7e\xb6\x9c\xfc\xc5\xa2\xed\x39\x38\xcb\x6e\xf9\x7d\x0d\xc0\x04\xe0\x39\xc6\x71\x0d\xb9\x88\x19\xce\x0a\xef\x0e\x67\xeb\xe5\xeb\x8b\xaf\x60\xae\xef\x41\x7c\x80\x8d\x54\xdf\x8c\x07\xf7\x14\xc3\x88\xb0\xcf\x88\xbd\x23\x36\x48\xdd\xa7\xbc\x5f\x9b\xc3\x50\xd8\xc3\x40\x4c\xd6\xe7\xba\x93\xd3\xad\x56\x95\x9b\xa8\xf5\x16\xeb\x10\x0b\xd1\x59\x57\x49\x04\xd9\x46\xe5\xc4\xc5\xd0\x1a\x22\x84\x33\x86\x81\xa2\x9a\xcc\x6d\x21\xca\x70\xb0\x82\xcc\x75\x22\x03\x8d\x01\xa6\xae\x19\x68\x4f\xd6\x5e\xa8\xfd\xe6\x0a\x4e\xc3\x58\xd1\x87\x0e\x9b\x17\x79\x0c\xf6\xb6\xaa\x99\xed\x5c\x38\x30\x92\xe9\x2f\x3c\x19\x10\xe5\x03\xbb\x3f\xa1\xf8\x82\x90\x04\x78\xf1\x37\x5b\x63\x21\x2c\x5b\x5a\x1b\xe3\x1f\x6f\xd8\x5b\xbb\x5c\xeb\x33\x5c\x14\x3f\x1e\x40\xf4\x2c\x24\xc3\x8b\x26\x93\x3d\x76\x0e\xb3\x48\x2f\x8e\x20\x66\x74\xf9\xd3\x60\xc6\x13\x57\x64\x0e\x02\x3d\xe4\x09\xfe\xe4\x06\xc1\x7d\x12\xf4\x78\x7f\xe8\xf4\x22\x0a\x90\xf1\x01\x41\xef\xa7\xaa\xd8\xa7\xaa\x1d\x8b\x96\x61\xe7\xfc\xa3\xc5\x81\xef\x23\x18\xef\xe0\x03\xd9\x42\xc9\x1b\x84\x7d\x75\xd3\x55\xcb\x26\x1a\x3a\x30\xb5\xb0\xfa\x25\x18\x73\xe6\x3c\x91\xff\x79\xce\xe3\x78\xe8\x07\xea\x95\x67\x30\xb7\x74\xe2\xb5\xcb\x9e\xa3\xbf\x09\xc6\xb3\x84\xb4\x3b\x6b\x02\xe6\xbe\xc8\x93\x9d\xd3\x5b\x77\x8c\xa5\xe0\xb8\x12\xd6\x93\x38\x7d\x83\x33\x55\xc2\x51\x73\x0a\x82\xbd\xe3\xfd\xa3\xee\x3b\x79\xd4\x11\x4a\x62\x4e\xdd\xc7\xd2\xd9\xe2\xb4\x6f\x50\xc3\x4c\x4e\x66\xd9\xf6\xe6\x55\xa4\x7c\xa1\x88\x37\xd3\x47\x60\x03\xa3\x08\x05\x23\xc5\x0d\x2e\xa9\x68\xe7\xa9\xc4\x47\x43\x02\x3e\xd5\x74\x26\xc5\xe0\x14\xe4\x7c\x41\x5b\x69\xa6\x75\x63\x4e\x4c\xb9\x71\xf0\x21\xb6\x48\x0e\xc5\x99\x74\xda\x73\xb2\x7e\xcc\x03\x4f\xa7\x17\x16\x6d\xc8\x90\x75\xdb\x15\xd4\xb9\x03\x93\xb8\x7a\xba\x49\x60\x6b\x25\x59\x6d\x9a\xd6\xd0\xd4\x3c\x25\xd3\x2d\x6e\x3e\x0a\x2d\x80\xe1\x2f\x18\x21\xc0\xe7\xe7\x95\x98\xee\x01\xbe\x52\x7e\x6b\x13\xa6\xb8\x24\xcd\xba\x91\x5a\x76\x90\x73\xcf\x3a\x2c\xce\xf0\x0d\x92\x48\x0b\x0b\x8d\x2c\xcf\xd3\x0c\xbe\x51\x58\xe7\x36\xd4\xb1\x83\x06\xf7\xde\x15\x68\x09\x22\xbd\x90\x59\x9c\x8e\xfc\x4e\xe4\xf0\xcb\x8d\x98\xb0\x51\x5e\x4c\x8a\x9c\xb4\xb2\x9d\xf8\xf7\xaf\x6d\x8b\x5d\x1b\x67\x86\x58\xd1\x8a\x7f\x76\x4a\x42\x9e\x2a\x17\x4d\x27\x08\x46\xf9\xff\x6c\x04\x0b\x8a\x40\x0c\x66\x71\x62\x28\xc7\x89\x80\x8f\x87\xf9\xf2\x1a\x09\xef\x18\xbe\x35\x55\x67\xc7\x12\x1c\x74\x7b\xc8\x14\x22\x8b\x5a\xdd\x5c\x83\x42\x30\x31\x05\x6b\xaa\x6d\xdd\x0c\x74\x7d\xab\xf8\xfa\x1a\x5b\x9f\x7d\xc5\x25\xc2\x4d\xa6\xca\x14\x65\x1b\xed\xbe\x64\x37\xab\x64\xb0\x03\xb7\x32\xaf\xb6\x78\x02\x92\x6c\x2c\x6d\xc5\x46\x52\x07\x39\x89\xf4\x8c\x32\x51\x01\xf9\xaf\x42\x2f\xef\xc4\xf9\xbd\x5f\xac\xac\x8b\xf6\x41\x5c\x54\x04\x7d\x25\x7c\x3c\x13\x13\x86\x06\x42\xaf\x7d\x28\xca\x4d\xe1\x90\x05\x9b\x9e\x0f\xeb\x93\xf3\xf3\xfc\x47\x2e\xbd\x5b\xf3\x51\xe7\xd5\xc3\xfc\xf4\xe4\xa6\x73\x54\xea\xa1\xe7\x83\xb3\x08\x00\xbe\x92\x1c\x99\x59\x86\x0a\x49\xf7\x40\x06\x9c\xff\x13\x93\x1e\x69\xe8\x48\x50\x6f\x05\x96\xcf\x48\xb7\xc7\x34\x70\x9b\x37\x1d\x37\x7f\x5e\xae\x89\x8d\x0d\x0a\x74\xc1\xa3\x37\x47\x5e\xb3\x4d\x27\x0e\xef\xa3\xa7\xf4\x6a\x32\x1e\xce\x9a\x17\x6c\x76\xd7\x0c\x05\xfd\xcc\x8d\xb5\x0a\x4c\xa2\x91\xe3\x67\x95\x22\xbc\x12\x7c\x75\x65\x6a\x7c\x75\xcb\x0f\xfc\xf6\x89\xba\x77\x6a\xb1\xe9\x13\xc9\xe0\x26\x65\x41\x4d\x49\xa6\xd3\x18\x64\x9d\x60\xa1\xfb\x90\x83\x8e\x52\xaf\xe3\xfd\x28\x92\x5d\x1f\xef\xf9\x28\x41\x07\x77\x67\xf2\xbe\x49\x60\x7c\x64\x1c\x0e\xd9\xd2\xc0\x38\x40\x27\x09\xb8\xe6\xc8\x31\x6e\x7d\x77\x09\xfe\xb9\x0c\xd6\x1d\xfe\x2a\x77\xb1\x4f\x84\x76\xa0\x36\x0d\x90\x1b\x87\xdf\x18\x91\xd6\x4e\x08\xe4\xef\x66\xac\xff\x7c\x46\xe2\x7b\x2b\x32\x51\x17\x31\xc5\x35\x4e\xb6\x7a\x70\x68\x1e\xf1\x45\x9c\xea\x6b\x47\xa4\xfd\x91\x97\x8e\x94\xc1\x8e\x06\xba\xc7\x46\x86\x84\x8e\xf0\x77\x71\x91\xc9\x06\xfe\xfb\x60\x1e\x30\x88\xe5\xe6\xc6\x28\xb7\x51\x4c\x65\x04\x2b\x10\x98\x80\xb5\xa2\x65\xdb\xea\x68\x0c\x69\x7a\x3f\xd2\xba\xb6\xc2\x87\xf2\xb1\xbc\x72\x5f\x9d\x1f\x78\x2c\x3f\x35\xa8\xb1\xd4\x48\x17\x35\xc3\xf0\xee\x39\x5b\x1a\xa3\x07\x1b\x8b\xf5\xac\xbe\x24\x38\x7a\x96\xd2\x40\x38\x0c\xa2\xca\x1d\x41\x15\x49\xf7\xe0\xc8\xf9\x94\xff\x2a\x22\xca\xc7\xbc\x92\x70\xce\x5e\x83\xdf\x72\x9e\x83\xdc\x2e\x4b\x2c\x6b\x04\x3f\xa1\x97\x8d\xca\x2e\xbd\x5f\x02\x60\xbe\xd7\xbb\xf2\x14\x64\xfe\x02\x4c\x9b\x66\xdd\x0b\x33\xfd\xdd\x80\xa8\xeb\x8e\xc3\xec\xc9\x24\x28\x5e\xbb\x43\x54\x00\x63\x23\x33\x19\x29\x7d\x34\xa6\x45\xe3\x92\x21\x27\x66\xb1\xf2\xf9\xcb\x1f\x1b\x45\x2c\x02\x36\xbb\xca\x7a\x14\x11\xf9\x99\x05\xc6\x85\x93\x51\xb6\x18\xe9\xed\x08\x90\x75\x45\x9f\xd1\x98\xf8\xa5\xe5\x8f\xdd\x80\xfc\xdf\xf9\xc3\xfe\x13\x1e\x36\x3a\xa3\xf2\x8b\x49\xc4\x6e\x28\x20\x38\x99\x04\x74\x88\xec\x77\x87\x70\x3e\xf7\xca\xc5\x19\x10\x27\x85\x63\x29\x87\x2b\x27\x6b\xb5\x16\xcd\xe7\x40\x9c\xac\xf0\xc6\xc9\x10\x14\x75\x58\x8a\xde\x3a\xef\xbc\xad\x4c\xb1\x38\x64\x01\x32\xc3\x22\x83\xfd\xc1\x07\xf7\xcc\x00\x30\xc4\x5d\x71\x56\xe3\x76\xd8\x27\x40\xd0\xe2\x5d\x5f\x2d\xfb\x99\x49\x96\x3e\x59\x04\x7a\x5a\x87\xcd\x9e\x8a\xe7\x40\x0e\x69\xac\x4a\x1d\xdc\x63\xa6\x11\x33\xbb\xb3\x66\x2e\x7e\x42\x7c\xae\xf2\x40\x80\x46\xd9\xcb\xf9\x88\x5f\xcf\x47\x8c\x63\x79\xa2\xba\x64\x36\x13\xe4\xed\xa5\x42\xfc\xf3\xc8\x1c\x26\xc4\xc3\xf2\x3b\xcb\xc3\xea\x41\x61\xfe\xa0\x20\x00\x7a\x89\x75\xef\x19\xef\x28\x23\x0a\x89\x57\x68\x31\xd0\x19\xe1\xb6\x7c\x4b\x9a\x27\x65\x17\xec\x59\xc8\xcd\x67\xd3\x6d\x0e\x1c\xc8\x90\x0f\x36\x52\x70\xf4\xdd\x85\x19\xc8\xc3\x47\x9c\x7c\x36\x0c\x47\x27\x64\x1b\x6e\x94\x0f\x58\xed\x97\x0b\x83\x38\x0b\x93\xc4\x71\xc0\x62\xd0\x22\xc0\xe6\x69\xa8\xe8\x5f\xec\x5e\x49\x1b\x56\x1d\x21\x9a\xe9\x14\xc9\xdf\x09\x65\x2a\xc1\x5c\x44\xf1\xb7\x6d\x1e\x61\x6a\x40\xf4\x77\xf7\xa6\x25\xa4\x81\x4b\xb1\xc3\x0d\x55\x16\x02\xa6\x6b\x0f\x77\x51\x73\x1e\x6e\xc6\x5d\x0f\xf7\x98\xc9\x3a\xd8\x57\xde\x9a\x47\x27\x64\xc1\xff\xc8\x0c\xe8\xa4\x7a\x20\x93\xc9\x04\xfe\xdd\x0d\x47\xfd\x99\xe7\xb6\xf1\xe4\x3f\x0b\x12\xae\xf8\xff\xf4\x56\x6c\x93\x41\xf1\x01\xda\x97\xef\x97\x93\x65\x33\xd4\xfb\xc9\x47\x5a\x11\x0b\x40\x20\x0e\xbf\x43\x56\x90\xa1\x8d\xcc\x88\x55\x2e\x61\x46\x63\x88\xc6\xce\xe6\x74\x2f\xd1\xff\xc1\x83\xe1\x0f\x0f\xa2\x18\x5e\x32\xba\x60\xa8\x72\x65\x0f\xc5\x17\x88\x86\xf2\x2a\x36\x18\x92\x4c\x75\x28\x52\x6d\x1c\x8a\x12\xe6\x0c\x60\xd9\x4f\xfb\x3a\x9e\xb2\xec\x12\xda\x1c\x1a\x69\xf9\x50\x96\xfb\xab\x73\x60\xb0\x24\x0f\x63\x21\xd3\x2f\x77\x8f\xb1\x10\x32\xc0\xa9\xa5\x06\xc3\xa8\x4b\x21\x45\x9a\xc0\x22\x63\xe3\x07\x7a\xea\x40\x50\xd3\x25\x2a\xc6\xd8\x46\x3e\xe9\x94\x1b\xf2\xbf\x96\xfe\x3b\x38\x8d\x4b\x16\xe2\x4b\xce\xaf\x7a\x91\x4d\x0f\x89\xa8\xe0\x1f\x3e\xb9\xc5\xe8\xf8\x21\xbb\xbb\x58\x8d\x06\x92\xdc\xf4\x39\x18\x2c\x72\x9b\x0c\x98\x15\x9e\x22\x05\x64\x23\xcc\xc8\x7d\x21\xc9\x1f\xd2\x48\x08\xc2\x6f\x68\xd0\xd9\x57\x79\x1d\x39\xe7\x07\xac\xd2\xb0\xee\x36\x5b\x14\x0d\x64\xde\x29\xb2\x07\x1e\xc1\x8f\x76\x6d\x55\x84\x84\x14\xc6\x1b\x5a\x25\xb6\x70\x16\x03\x3e\xb5\x4f\x17\x59\x83\x06\x70\x0d\xf2\x3f\x03\x3d\x7f\x6f\xf5\x3b\xb8\xde\x33\x60\x72\x19\x74\x82\x2f\xfe\x20\x56\xa2\x86\x90\x17\x1b\xd0\x47\xeb\x66\x97\xb9\x7e\x84\xa6\x43\xda\x7d\xc0\x52\xa6\x37\xd8\x33\x22\x0c\x54\x84\x85\xa0\xfc\xa1\x1b\xbc\x3f\x02\x9c\xe6\x18\xb2\x31\x42\xf7\xa9\x40\x6b\x03\xe3\x2f\x82\x76\xc8\x39\x1e\x4d\x4f\x22\x98\xc1\xe3\xd0\x1c\x74\x95\x27\x71\x82\x1d\x47\xa1\x25\xeb\x14\x85\x24\xf0\x31\x28\x26\x44\x1b\xb3\x0a\xbf\x6a\xc9\x02\x0e\xa2\x9e\x74\xc7\x96\x5e\x38\x03\xa7\x86\x24\x4e\x42\x36\x09\xeb\xea\xc4\x6d\x58\x29\xfe\x33\x90\xef\x63\x48\x4d\xfe\x1a\x4c\x86\xfc\x3c\xa8\x0f\x37\xa4\xc6\xc1\x60\x90\x62\xaa\x03\x88\x27\xbc\x7c\xea\x62\x6a\x0a\x29\x42\x8e\x07\x19\x92\x43\x8c\xab\x06\x26\xd6\x91\xae\x81\xfe\x8b\xb5\x62\x5d\xd3\x36\xf6\xc6\x9f\x0c\x7a\x30\x52\xbc\x99\x79\xc2\x14\xaa\xde\x0d\xaa\xaa\x9d\x9d\x93\x5e\xf5\x9c\x35\x7a\x4c\x5d\xfc\x0b\x29\x3f\xe2\x3d\xf4\xc4\x67\x1d\xd1\x75\x1a\xbb\xfb\x13\x09\x6b\x78\x72\xfd\xf1\xb9\x82\xb2\x30\x42\x62\x7a\x74\x78\xc1\xdb\xef\x1b\x6d\x37\xed\x94\x3e\x74\xc6\xfa\xa3\xb4\xdf\x20\x08\x5a\x64\x83\x98\x1e\x92\x43\x31\xbb\x4f\xd6\x4a\xd1\xa3\x21\x44\xa9\x27\x28\x53\x0d\xc0\xbb\x34\xd4\xb1\x74\x05\xad\x45\xff\xe6\x24\xa5\xaf\x1f\xf8\xa6\x83\x55\xf0\x1d\x64\x86\x11\x50\xd5\x23\x1c\x9f\x24\x6b\xce\xaf\x48\x70\xb6\x5d\x67\x12\x0d\xe3\x9f\x49\xb5\x6d\x78\x12\x04\x69\x18\xc5\x05\xc7\x00\x26\x2b\x98\x5e\x0d\xd6\xc5\x74\x73\x17\x82\x97\x44\x7d\x78\x40\x6c\xf1\x20\x14\xf5\x5e\x3d\x9e\xb7\x7e\x91\xc9\x1d\x67\x63\x30\x17\xe8\x7b\xd0\x7e\xea\xa0\x14\x19\x69\x7d\xdd\xa4\xac\xd9\x23\xb2\x28\x7e\xb3\x9d\x37\xbe\x26\xe1\x4b\xa4\x4c\x86\x2b\x03\x27\x40\xf4\x41\xd2\x39\xd0\x5c\xf1\x37\x2b\x13\xee\xa0\xe7\x79\x16\x01\x56\x65\x41\xd0\x0b\x67\xc4\xa0\x74\x0c\xdd\x05\xa7\x77\x0c\x06\xc9\x85\x61\xf8\x08\x72\x7b\xab\xbc\x8e\x5b\xd4\xdb\x64\x79\x3c\x7e\x50\x92\xfa\x3d\x42\x8f\xbc\x9c\xe2\x26\x86\xe0\xa9\x1c\x86\x20\x9d\xec\x9f\x22\xd4\xab\x58\xe5\x0c\x01\xe5\xbe\xca\x3f\xd1\x2f\x11\xc1\x05\x24\xee\xc7\xaa\x44\x16\x43\x4f\x1e\x04\x6d\x80\x95\x68\xc3\xca\xd3\x42\x3c\x8e\xfc\xb7\xcf\xab\xd9\x84\xac\x79\xc7\x97\x54\x8e\xe0\x03\x2c\x47\x52\x63\x2a\xd6\x6c\xbd\xd2\x90\xd0\xe5\x33\x36\x9b\x83\x2d\xb9\x74\x41\x34\x3a\xdf\xd4\x6c\x82\x7e\x9c\xdf\x86\x73\x39\xea\xd3\x37\x83\x6a\xe5\x3f\x11\x69\xae\xef\x8d\x8c\x8e\x27\xa1\xaa\x32\xbb\x2a\x73\x11\xe4\x4f\xf2\xfd\x3a\x48\xed\x81\x98\xdd\x45\x3b\x4f\x3d\x15\xd0\xaf\x71\xf0\x85\x41\xcc\x93\xd8\x8c\x94\xc4\xf8\x10\x9f\x27\x4d\xb8\x53\x3f\xea\xf9\xcd\x69\x0f\x5a\x4f\x83\xca\x38\x07\xdf\xa3\xb2\xf5\xfb\x7c\xf4\x2c\x17\x2e\xa5\xf7\x79\x09\xf2\x42\x66\xb4\xf4\x08\xee\x0d\xf6\xc3\xeb\x0a\x42\x44\x6b\x77\x49\x74\x90\x57\xb2\x8e\x48\xe4\x82\x8d\xee\xb1\xfe\x36\xb9\x12\x0c\x26\xc7\x70\x9a\xf5\x64\xc8\x4a\x82\x94\x1c\x33\xb4\xeb\xc0\x39\x5a\xa1\xf5\xc9\x72\x3c\x81\x48\x6c\x13\xe3\xe2\xc1\x58\xf8\xd8\x30\x13\x66\x09\xf8\xa2\xeb\xc2\x99\x1f\x15\xba\x01\x9c\x24\x44\x87\x20\x92\xe0\x8c\x70\x4e\xc8\xd8\xbb\x54\x55\xf2\x78\xc2\x29\x4f\x38\xe8\x63\x01\x62\x69\xcf\x61\x08\x1e\xc8\x1f\x8d\xe3\x11\xdf\x60\xf2\xd8\x32\x36\x6d\x7c\x14\xea\x8c\xd2\xb6\x8b\xa5\x92\xf4\xbd\x88\x72\x2a\x90\x9e\xe3\xcf\x25\x7a\x05\xa0\x07\xb1\xa9\x39\x63\xa4\x5e\x4b\x20\x96\xce\x62\xa9\x5e\x26\xc2\x7a\x7a\x9b\xe6\x1d\xfa\x2d\x72\x0a\xf5\x6e\x13\x02\x45\x82\x1c\x12\x5f\x81\x98\x34\xa5\xfa\x06\x9a\x48\xcd\x7a\xfa\x14\x6c\x60\xce\x0f\xf9\xe2\xf8\xd9\x43\xe7\x2d\x08\x36\xbb\x23\x0e\xe8\x24\x30\xd9\xc7\x02\x56\x77\xab\x8f\x77\x42\x49\x96\xc1\x28\x16\x92\x2d\xa0\x95\x2c\xa4\x29\xbb\x35\x5c\x18\x20\xaf\xd7\x7d\xca\x2a\x06\xd2\xbf\x8e\xb6\x2e\x02\xc2\x49\xcd\x71\x3a\x67\x8f\x38\x85\x1a\xe3\xe4\xa4\x20\x23\xc0\x83\xe9\x6e\xe0\xa1\x5c\x58\xaa\x1e\x9c\xab\x75\xf7\xaa\x99\x4f\x77\x2b\x56\xa7\xbb\x1f\x6d\x48\xef\xec\x83\x26\x3b\x5c\x48\x17\x76\x68\xcc\x22\x4a\xbb\xd5\x16\xbb\xe3\x5b\x29\x71\xd0\x1d\x9f\x61\x12\xdd\xe3\xbd\x32\x7c\xcc\x79\x25\xc5\xd3\x47\x8a\x60\xfd\xa8\x3e\x49\x59\xd8\x52\xa8\x9c\xd8\x85\xbc\x7c\xe8\x40\x82\x3e\x92\xdf\x5f\x0b\x06\x75\x7d\xda\xc8\xe5\xe1\xf6\xb9\x89\x4d\x12\xa1\x30\x35\xe0\x46\x06\x97\xae\xf1\x84\xd9\x8b\xfa\xea\xa4\xf6\x95\x15\x51\x4c\x9e\x2d\x40\xc8\x09\xc0\x35\x39\x04\x6e\x3b\xa3\x7a\x56\x01\x91\xc4\x3b\xd6\x3d\x25\x59\x89\x86\x4a\x43\x74\x0e\x74\x07\x27\xd8\x9d\xd8\x30\x6c\xa2\x24\xbe\xcb\xfa\x0e\x0e\xc7\xa0\x02\xe9\x68\x36\x76\x9e\x17\x4e\x0e\x47\x9a\x94\x56\x4a\x4e\xc1\xe3\xea\xc5\x7e\xc9\x4c\x87\xae\x4d\x82\xc0\x37\x39\x1f\x8c\xe3\x35\xcc\x77\x5a\xc9\x85\xd0\x55\xe5\x55\x00\x60\x6e\xc4\x9d\x4b\x7e\x88\x89\xb1\x2e\xa2\x43\xed\xaa\x88\xae\xba\x3a\x71\x8a\x62\x20\xf5\xba\x02\x02\xac\xf9\x74\x6a\x9e\xb7\xe0\x50\x44\x36\x3a\x6f\x72\x48\xa4\xe8\xec\xc8\x10\x5a\x45\x11\x79\x8b\xe0\xbb\x43\x0b\xe3\x7a\x44\xb7\x14\xda\x1c\x06\xb6\xde\x8d\x58\xfb\x78\xd4\x9c\x96\xf4\x19\xf8\x48\x16\x7b\x3b\xa4\xf8\x2b\x92\x22\xb1\x81\xf0\x94\x5a\x59\x57\xb4\x0e\xdd\x95\x08\x86\x75\x22\x48\x71\x68\xba\x92\xb1\x37\xc0\xe2\x8a\x76\x68\xac\x67\xb0\x49\x5a\xaf\xce\x83\x7e\x41\x03\x5d\x89\x98\x3b\xb0\x2a\xfb\x9e\x99\x0e\x97\x6e\xe6\xc1\x59\x46\x54\x97\x25\x1a\x63\xe0\x0a\x16\xaa\x2e\xa8\x0b\x63\xee\xe6\x94\x92\x24\x66\x3c\x83\x5a\x30\x8b\xfd\x11\x54\x87\x3c\xb8\xb1\xcc\x23\x46\xbe\xe4\x1f\x12\x10\x13\x2a\x12\x07\x04\xf2\x36\x89\xd8\x35\x44\x1b\x91\x3d\x20\xc2\x4c\x1b\xd7\x07\x77\xee\x74\x79\xe5\x15\x97\x22\x1a\xc7\xb2\x34\x26\xc8\x7b\xd3\x25\xe7\xf0\xc0\x74\xf6\x33\x31\x10\x66\xfa\xd8\xe0\xf4\x0e\x02\xc8\x1b\x89\x24\x34\xfd\x3a\x10\x9b\x68\xf7\xa4\xfb\x4b\x9f\x9b\xc4\x88\x1f\x31\x16\x7e\xc4\xc7\x8b\x29\x4c\x50\x46\x82\x1e\xf2\x0a\xfa\xc3\x4b\x14\xb5\xa9\x25\x79\x18\x9c\x52\x50\x38\x5e\x30\xc7\xb2\xc8\x1a\xc5\x17\x00\x14\xff\xf6\x20\x16\x00\x2c\xc8\xae\x29\x98\x24\x45\x9f\x01\x38\x89\x83\x12\x6f\xfc\x0c\x18\xf4\x8f\x91\x03\x05\x76\xc8\x60\xdb\x6e\x24\x4f\x5d\x92\x94\x06\xa8\x24\xdb\x7d\x1c\xdd\xcd\xd2\xe6\x2d\x97\x50\x9f\xb6\xe0\x93\xec\x74\x8e\x4d\xc4\x93\x9b\x6a\x18\x3c\x41\x5d\x62\x42\x17\xca\xe9\xe6\xb1\xb4\x4e\xad\x1c\x4a\x90\x42\x8a\x74\x72\xe9\xf9\x5a\xc1\x4d\xc4\x5f\x17\x3e\x2d\x79\x23\xbb\xc4\x06\x9d\xc8\xae\xdf\xa5\x29\xd8\x40\x13\x48\x5b\x74\xde\x81\x6d\xc8\x8c\x09\x3e\xb6\xfe\x79\xf3\xa3\x4a\x5a\x67\xc0\x57\x26\x1d\x93\xf4\xee\x18\xa8\xe7\xb4\x91\xa2\x27\x7c\x25\x34\x2b\x87\x37\x79\x8e\xd2\xad\xf5\xcb\x74\x3f\xfc\xcb\xc0\xfb\x6d\x5e\x53\x84\xa0\xd0\xd0\x01\x45\xa4\x76\xb1\xdf\x49\x71\xce\xe3\x2e\xdf\xfb\xbf\xa0\x80\x74\x10\x7c\x89\xd6\x0d\x86\x13\x9b\x64\x8f\x1b\x11\xfa\xf7\x2b\x76\x43\x86\xd5\x2b\x7c\x3c\x83\x17\x32\x66\xd2\x66\xb5\x9b\xe5\x43\xe6\x43\xf9\x10\xcc\x0e\xb9\x69\xcb\x03\x25\x8a\x3e\x9b\x21\xf2\x26\x67\xa3\xf3\xe3\x6f\x84\xd2\x1a\xf7\x65\x37\xe7\x4c\x44\x88\xbe\x5f\x69\x9b\x38\xaf\x73\x01\xfd\x55\x84\x8b\xee\x3a\xe5\xd9\x26\x0d\x50\xee\xca\x65\x03\xc7\xd8\xf0\xe1\x7f\x7b\xb6\x74\xc4\x19\xb3\x71\xa4\x75\x2d\x07\x79\x0b\xa1\xe3\xd3\xbb\x10\x30\x28\x47\xab\xba\xba\xd4\xe8\x02\x80\xe6\x40\xc1\xeb\xb9\xbc\x8a\xbb\x4c\xdc\xb0\x61\x86\x9a\x41\x5a\x20\x56\xe3\xda\xc9\x8a\x0f\x4c\xd8\xd2\xe7\x11\x9a\x13\x04\x96\x0b\x58\x89\x68\xfc\xa5\xe5\x74\x8e\x2d\x24\x7d\x7d\x78\x63\x2d\xfd\x2b\x2d\x71\x3c\x72\x15\x98\xee\xeb\x51\x3c\xda\x5b\x44\x1f\x96\x3c\xa0\x55\x1c\x94\x20\xdb\x1a\x08\xbb\xd2\x18\x2b\xbb\xe6\x8b\x46\x26\x59\xe1\x0d\xe9\xf1\x95\x20\x9d\x3c\x79\xde\xd9\x49\x95\x2b\x53\xf8\x93\x02\x36\x92\xdd\xb3\x9f\xb5\x0f\x1b\xc8\x1e\x11\xdf\x5c\x2f\xf6\xd0\x3e\x7b\xa4\x6e\xea\x4e\x05\x65\x9a\x81\x76\x93\x68\xd2\x90\x0f\x5f\xa9\x13\x31\x66\xc7\xa9\x28\x32\x62\xb9\x9d\x7d\x02\x03\x79\x1a\xfb\x09\xa7\xe0\x29\x69\x81\xfc\xfb\x71\x15\x80\xef\x2d\xa3\xff\x7b\xaf\xd1\xf4\xbf\x37\x03\x6e\xbf\xf7\xcc\x15\x92\xef\x6d\x83\xe2\x39\xa8\xf6\x5f\x3a\x4a\xad\x50\x7a\xfd\xb7\x1e\xe2\xb4\xfa\x52\x94\x0c\x21\x72\x22\xa4\x34\x34\xa9\xe4\x27\xf2\xe5\x6c\xe8\x8b\x0e\xda\x7d\xa3\x86\xfc\x88\x7c\x90\xfa\xfe\x1b\x91\x12\x5f\x4a\x23\x7e\xf3\xc2\xa0\xdd\x2f\x38\xfc\x58\x0e\x9c\x1f\x7c\xad\x9f\x0f\x52\xcb\x97\x4d\x40\x9d\x15\xd3\x1a\xcf\xd7\x9b\xe1\x17\xd9\x4b\x41\x8b\xb9\xd3\x50\x05\x41\x26\x05\x9b\xbf\xd6\xdf\x89\xc0\xf6\x0b\xba\x5c\x82\x75\x47\x52\x98\xc3\x60\xea\x4c\x36\x89\x7d\x30\x18\x13\x1f\x24\xf7\xd9\x40\xfb\xd5\xe5\xdc\x0e\x28\x82\xb8\xda\x87\x79\xd2\x9f\xdb\xab\x0f\xf6\xcc\x89\x79\x35\x9f\x08\xde\xf9\x38\xd9\xf8\x49\x34\x7b\x77\xe8\x24\x9a\x2c\x19\xeb\xfd\x51\xf7\xfb\xfe\xfc\xb8\x11\x83\x63\xf0\x88\xf8\xc8\xb7\xd5\xa2\xf0\xea\x58\xd2\xfb\xb2\x54\xbc\xdf\xdb\x6c\x28\xd1\x59\x56\x91\x6a\xd6\xa5\x17\x5f\xa3\x35\x19\xb2\x27\xc2\x7e\x92\xd7\xe3\x5d\x17\x8e\x4e\xf0\xb1\x86\x50\xe1\x9b\x4b\xd3\x44\xee\x3d\xb3\x32\x56\x17\xc1\xa6\x65\x36\x39\x09\x22\x1b\xf3\x01\x20\xa9\xec\x0c\x85\x62\xfa\x1b\xcb\xd8\xb7\xb8\x24\x0f\x45\xb0\xbc\x8b\x07\x23\xbc\x0b\x93\xa8\xde\x3c\xe7\xa6\x65\x35\xe8\x0f\x8a\x84\x32\x94\x08\x88\xfa\x80\x24\x61\x2c\xc8\x76\xd0\xf5\xe0\xa4\x0b\x42\xcb\xa0\xed\xb4\x96\xdf\xa0\x59\x86\xa5\xe1\x9f\xbd\xe2\x5b\xdb\x9c\x75\x2b\x39\x88\x1e\xed\xe1\xbe\xe9\x85\x06\x7c\xca\x9c\x04\xd6\x33\x06\x1b\xa6\xe6\xb3\xc0\xa2\xd6\x04\x1b\xe6\xc4\x85\x4a\xe0\xf6\x8c\x7c\xf1\x4c\x84\x9a\x86\x49\x6f\x39\x9b\x8d\x15\x67\xcb\xba\x61\x2c\x9f\x05\x89\xa6\x56\x3c\xdf\xe8\x2c\x82\x1a\x34\x37\x0a\x10\x90\x5e\xa2\xf3\xd0\xee\x9e\x1c\x9b\xe5\x74\x65\xb7\x83\x1b\xdb\x8f\x5d\x53\x89\x49\x06\x94\x6c\x06\xa4\xdf\xf4\x33\xe8\xf1\x79\xa2\xf9\xf0\x7e\xd7\x00\x0f\xa7\x0a\xd2\x5b\x99\xc2\xef\x14\x1a\xd0\xef\xf4\x7b\xed\xe9\xf8\x66\xba\x53\xdf\x18\x08\xff\x09\xe8\xde\x6c\x48\xa4\x7d\xfe\x4e\x62\xd3\x7a\x83\xc8\x24\x4e\xd3\xe8\x2b\x91\xe1\x52\x88\x78\xdf\x50\xb2\x60\xa5\x13\xe8\x5d\x37\x21\x57\xfb\x61\xff\x6d\x9b\x76\x3b\x07\xaf\xbc\xa8\x4f\x76\xa4\x9f\x89\x11\xe4\x9d\x34\xc1\x44\xb4\x40\x10\x77\x16\x5e\xb6\xd0\xb1\xf5\x4e\xf3\x6e\x13\x38\x2e\x45\xda\xc6\x12\x87\xc9\x3c\x7c\x83\xdb\xfa\xb9\xc9\xac\x04\xf1\x26\x0f\x1c\x86\x7a\xef\xa7\xa0\x78\x22\x25\x8e\xf2\xba\x9d\xa0\xc9\xad\xc9\xd7\x3d\x41\x19\x4c\x04\x9c\x27\xe5\x1b\x5e\x9e\xf0\xfb\x24\x62\xde\xd7\xab\x22\x1e\xdf\x01\x95\x1c\x5f\xb0\x9e\x9c\x2a\xb2\x44\x26\x3b\xf8\xb1\x05\xce\x3e\x35\xf2\xcd\x4c\x3a\x4d\xb5\x14\x77\x90\x4e\xe9\xbf\x60\xe1\x74\x4e\x4f\x64\xc6\x93\xe7\xb2\x64\xa9\xbe\xbf\xca\xa0\x3c\x95\x57\xe9\xdd\x8f\xf1\x6a\x81\xc3\x2f\x38\xc9\x5e\x64\xd7\x94\x24\x07\x46\xeb\xe0\xde\xb4\xf7\x3a\x2d\x62\xd7\x3c\xb8\xb0\xfc\x72\x05\xb7\x2c\xd4\x0e\xc4\xa4\x9f\xe4\x5f\x4e\xce\xf9\x9f\x93\x6f\xd2\x12\x78\x71\x92\xf2\x42\x2b\x19\xf8\x3d\xbd\xe0\xf5\xf0\x51\xf0\x05\x17\xcc\x76\x05\xbb\xe6\x79\xaf\xf9\x68\x1b\xfd\x7c\x7f\xb8\xd6\xfe\x82\xfa\x49\xbe\xdf\xf1\x2f\xb0\x94\x05\xaa\xdf\x38\x24\x07\x75\x27\x94\xa7\x96\x67\xec\xc6\x32\x12\xd2\x8b\xdb\x56\xfe\xfd\xe7\xf8\xbe\x53\x9a\xda\xd6\x5b\x73\x75\x6e\xcd\x9f\xdf\x86\x82\xbb\x0d\x9b\x0d\x44\x9a\x38\x60\x46\x8d\x3a\x9b\x27\xff\xbd\x90\xa3\x13\xb1\x10\x34\x97\x0d\xf7\x4e\xf6\xfe\x9f\x58\x3c\xfb\x2a\x34\x24\x22\xd9\x4e\xf7\x61\x0f\xd0\x73\xd1\x6e\xef\x33\xb3\xb4\x65\xef\x0d\x51\xc1\x01\x55\x32\x50\xda\x13\x21\xfa\x16\x89\x79\x8f\x63\x78\xc0\x6d\x2a\xcb\xd5\x83\x9b\xcc\x10\xd7\xe7\xfc\xba\xad\x6f\x80\xdc\x99\x9f\x55\x94\xa0\xbe\xfe\x70\x7d\x12\x43\x48\xcc\xe6\xdc\xdc\x89\x75\xdd\x0c\x52\xb9\xee\x53\x93\xb6\xeb\xd6\xe4\x0e\x64\xa0\x31\x1b\x05\x8e\x9d\x1e\x02\xe1\x27\xbf\x77\x1a\xcb\xd7\xfd\x14\x7d\xe8\xe8\x33\x99\x8b\xe2\x3c\xd7\x2d\xba\x50\xb6\x42\x27\x26\x94\xb1\x77\x9d\xb7\xfd\xb9\xf3\xcc\x4a\x1b\x42\xdd\x3e\xf5\xfc\xdc\xe0\x32\x3d\xca\x8b\xeb\x45\x86\xf6\xbd\x04\x00\x87\x57\xe6\xc6\xfa\x3b\x94\xbe\x3e\x07\xfe\x8c\x0c\x71\x2c\x07\xe8\x48\x3a\x9a\x5f\x85\xb6\xdc\x15\xca\x6f\xd7\x91\x3c\xc7\x97\xd0\x6d\x23\x2b\x9d\xc9\x12\x6b\x0f\xfe\xb3\x7a\xb1\x09\x5f\x2e\xc0\xa1\x10\x2a\x6c\x68\xe9\xe8\x92\x5f\x1f\xd9\x26\x0b\x4b\x4e\xc4\xcc\xde\x6d\x2a\x7d\x57\xa9\x93\x75\x90\xde\x26\xc4\xa5\x74\x81\x2d\xee\x24\x98\xc2\xcd\x73\x05\x03\xe5\xe5\xe1\x15\x0e\x98\x5a\x82\x92\xf7\x5d\xbc\x7f\xb8\x20\x68\xce\x43\x21\x5b\x14\xcc\xa2\x47\x8d\xd8\x42\xa8\x91\x6c\xa7\xd6\xf7\xaf\xa6\x44\x8e\x04\x4b\xed\x2a\xd1\x8a\x00\xff\x13\x19\xa9\x4e\x49\x82\x19\xb3\xd3\x2f\x95\xc1\x4e\xba\xc4\x6c\xc0\xf0\x20\x92\xd1\x3b\x22\x40\xd0\x9e\x6d\xce\xe5\xe6\x4f\x5b\x91\x41\xfe\x26\x1b\x67\xde\x47\x1d\x86\x5b\x67\x2d\xf3\xaa\x80\x3f\x43\x34\xb2\x2e\x0f\xdd\x28\xfc\x85\x72\xab\xc1\x5f\xaa\x9f\x26\xb9\xa3\x6c\xb2\x90\x9e\x74\x5b\x5c\x50\xb1\x3b\x09\xa2\x26\x98\xd1\x4d\xca\x12\xb6\x8d\x9d\x3f\xd9\x82\x3d\x55\xaf\x88\x3c\xcb\x56\x88\xfe\x35\x31\x4c\xef\x4a\xd2\x75\x82\x77\x34\x14\xef\x2e\x9b\x6b\x7f\x18\xb0\x03\xc8\xcf\x02\x74\x65\x5e\x72\x31\xe3\xb2\x67\x72\x9e\x81\xbc\xe8\x62\x55\x0d\xbc\xa7\xce\xab\xf5\xe5\xba\x88\x95\xce\x3b\xf7\xa5\x61\x6b\xa5\x2f\x0b\x9d\x1f\x91\x40\x7e\x16\x11\xcc\x7d\x44\x29\x66\x96\x5e\xe3\x40\x9d\x64\x61\x9d\xd6\x57\x9e\x8d\xc9\x94\x5c\x5e\x36\xd6\x1f\x01\xfc\xb5\x19\x48\xdb\x27\x40\x0e\xb6\xd3\xeb\x5d\x6f\x9e\x43\x5c\x5e\x6f\x11\x30\x9c\x91\xb3\x73\xde\x47\x80\x6d\xe8\x16\xff\x32\x48\x64\x7a\x92\x01\x91\xa4\xa6\x89\xdc\xa5\xe8\xd4\x93\xf8\x4d\xc9\xe1\x76\x4f\x91\x48\x73\xde\x20\xe5\x0f\x79\x86\xd3\x7b\x11\x82\x9d\x1c\xa4\x66\x6b\x07\x43\xe9\xbd\x6a\x9f\xcd\xce\x9f\xcc\x86\x20\x11\xf9\x29\xa4\x59\xaf\xc3\xc6\xca\x78\x89\x14\x09\x29\x50\xdf\xaf\x7e\x94\x6e\x27\x57\xbb\xa0\xad\xc6\x39\x38\xf0\xa3\xce\x41\x0c\x5a\x19\x93\xe2\xae\x20\x9d\x14\xbc\x08\x1f\xf1\xd6\xf8\x56\x8b\xfc\x06\x7b\x29\x23\xb2\x0d\x3d\xc5\x03\x5a\x9f\xba\xa5\x0a\x37\xdc\x22\xd8\x28\x58\x6b\xd0\x02\x3b\x0c\x33\xce\x37\x82\xbf\xd4\xe0\x20\x5e\xd8\xab\x8a\x7d\xcf\x49\x50\x83\x0e\x35\x2f\x24\x29\x2d\xc7\x24\x6e\x53\x30\x86\x10\x59\x33\x88\xf3\x23\x32\x22\x60\xf0\x7f\x42\xe5\x82\xf1\x9b\xa0\x02\xe2\x63\xc5\x12\xd0\x25\x12\xd5\xb2\x35\x2e\xbf\xeb\x8f\x99\xe9\x1b\x0a\x03\x3f\x9d\x4e\xf8\x78\xd3\xff\x80\x2d\xf1\xfa\xd9\x17\x78\x90\x1f\xd2\xbe\xbb\xf1\x4f\x52\x0d\x62\x31\x4e\x5e\xc0\xac\x7a\x55\xb9\x49\x11\x43\xbf\x6a\x8d\xe3\x9e\x99\x8f\x3f\x89\x60\xee\x32\x83\x6d\x0b\x8a\x0c\xdb\x9a\xb6\xc2\xb1\xc6\x70\x56\x1c\x97\xc1\xe4\x8f\xe6\x10\x8b\x1d\xc8\x97\x48\x80\x2a\xed\x28\x50\x77\x6d\x4f\x31\xa7\x3a\xa3\xd1\x22\xd8\xb8\x65\xf7\x43\x5d\x0b\xd0\x16\xe4\xaa\x62\xd9\xdc\xcb\xab\x11\xb1\x26\x96\x66\x6a\x68\x0f\x83\xee\x01\xa4\x54\xed\x54\xac\x6f\x02\xfe\x2b\xfb\x9b\x26\x14\x95\xe0\xce\xe4\x0c\x04\xa5\xe8\x21\x81\xe8\x26\x10\xdf\xfe\x8f\x93\xf5\x9a\x35\xa3\x3b\xeb\xe9\xbd\xe9\x29\x19\xa7\xb3\x56\x2d\xc9\x9e\x1e\x3d\xe4\xcf\xa3\x32\x31\xfc\x24\x67\x89\x15\x3c\x9b\x07\x92\xfa\x53\xad\x43\xcb\x31\x3b\xab\x1c\x14\x67\xed\xd8\x6d\xac\x4c\x7d\xb5\x32\x24\x07\xce\xb5\x5c\xf3\x83\xc0\x2b\xdd\x42\xa2\xa1\xaa\x27\x90\xb7\x86\x74\x43\x0b\x83\xea\xcf\x67\x15\x8f\xcc\xa9\xf4\x39\xc2\xae\x11\x3b\x3f\x33\x3f\xe5\x27\x47\x15\x2b\xc7\x42\x76\xaa\xb3\x90\x95\xe2\x2c\x7f\xb8\x9f\x83\x12\xec\x2c\xe2\xc9\xa5\xea\xd0\x69\xef\xa6\xa7\x00\x1a\x74\x15\x7b\xd1\x9f\xae\x7b\x1c\xbd\x8a\x66\xd6\xec\x04\x9a\xc8\xa4\x52\xd5\xcc\xf0\x2c\x41\xe0\x59\xf2\xf4\xd6\x94\xf3\x2c\x43\xf0\xb0\x0e\x9c\x18\x9c\xe0\x82\x15\xdd\xe9\xbd\xaa\x8b\x9a\x6f\x2e\x1d\x39\x96\xb6\x26\x16\xc9\x3a\x96\xfb\xe5\xee\xcf\x13\x69\x3b\x1f\x02\xe4\xd4\xe8\x2d\xfb\xc2\x73\xa3\x81\x01\x69\x54\xfb\xea\xb0\xd0\x2c\x4a\x03\xc3\xe3\x21\x6a\xd6\xd2\x58\x35\xe7\x88\x1b\x3c\x83\x74\x73\xce\x22\x79\xcd\x20\x81\x62\xed\xf2\xd2\x7a\xc5\x39\xc7\x2f\xd5\x15\xce\xae\x9d\x2c\xb4\x6b\x42\x87\xf5\x79\xdc\x31\xa7\x35\xe7\x6f\xfd\xd9\x65\x20\xff\x7e\xd9\x3f\x82\xcb\x59\x5e\xe6\x73\x14\xcb\xd5\xc9\x34\x9c\x33\xff\x8b\x8e\xc3\x1e\xf0\x47\x25\x59\x4b\xf3\xa5\x96\x4a\x8d\x9d\x33\x8b\x6b\x39\xc7\x97\x8c\x53\x29\xba\xcd\xf0\x40\x79\x66\xb0\x2f\x42\xfa\xd0\xe1\x32\xd4\x35\xd6\x38\xce\x0c\xb6\x5c\xf5\x25\x39\xe8\x98\xa1\x32\xc5\x5c\x82\xb3\x09\xab\x9e\x66\x1e\xfb\x47\x83\x05\x7a\x5e\x49\x7c\x9f\x99\xf1\x7d\x67\x0e\x85\x22\x27\xb7\x4a\x07\xa9\x3e\x8f\xaa\xfb\x66\xa0\x8a\xa3\x02\xc6\xab\x24\x78\x04\xd7\x68\x1b\x74\x9d\x8c\x35\xb8\x58\xef\xb5\x51\x8d\xde\x12\xd1\x01\xec\x23\xa7\xbf\x6d\x10\x1f\x25\x37\x1a\xd2\x83\xce\x33\x47\x76\x6b\x8b\x7e\x5b\x39\x73\xd6\x86\x9d\xf4\x2b\xf8\xe3\x5d\x1d\xa3\xa6\x22\x5d\x72\x02\x56\x09\xda\xf8\x42\x65\x1b\x27\x20\x6c\x79\x05\x9d\xea\x5a\xe8\x22\x70\xbe\x55\x32\x83\x3b\xd5\x62\x3c\x01\xa8\xf0\x9c\x8d\xb2\x75\x09\xba\x7d\x60\x9b\x52\xff\xf8\x59\x39\x3d\x73\x34\xb6\x9d\xa0\xcb\x21\x85\xad\x35\xd8\x6f\xec\xce\xe2\xba\x04\xb4\xf9\x78\x3b\x79\x70\x90\xe3\xd1\xec\x6d\x6f\x6a\x07\xa7\xc4\xea\xc1\x2b\x78\x15\x11\x22\xf7\xd6\x34\xe9\xf1\x3a\xed\x6a\xa1\x17\x71\x42\x45\x94\xe4\xa3\xf1\x82\xcd\x70\x9c\xb8\x00\x7c\xa6\xfb\xc5\xd0\xe7\x33\x18\xce\xd1\x76\xb5\xa8\x7a\x8a\x9c\x37\x41\xda\x59\x88\x5c\x52\x8e\x37\xe5\x21\x9d\x14\x6b\x12\x4a\xcb\xad\xd6\x81\x8d\xfe\xb8\xc5\xa1\xba\x81\x60\xbb\x08\x8b\x5b\xe4\x54\x26\xc4\xe9\x32\x4d\x02\x31\x43\x3a\x13\x38\xe2\x1b\xdd\x2b\x34\x65\x64\xe7\xc1\x15\xae\x3a\xc0\x80\xe7\x19\xac\xcd\x7e\x09\x44\xe8\xfa\x64\x4c\xad\x81\x46\x0d\x9d\x1e\x03\x3f\x3f\x2e\xd8\x9c\x69\x42\x14\x94\x23\xeb\x6b\x48\x27\xab\x78\x9e\x13\xf2\x5e\x2a\xc9\x04\xf9\x91\x96\x52\x38\xaf\x0f\x1b\xa4\x62\xda\x62\x38\x79\x71\x32\xe3\x05\x20\x89\xc1\x95\x14\xaa\xb7\x98\x89\x0c\x04\x7b\xda\xd1\xa6\x0d\xc7\xbd\x93\xc7\xf2\xfe\x65\xd9\x1d\xb7\x48\xde\x0c\x58\xff\x27\x6e\xcc\x3b\xdc\x39\x07\x0c\x0e\x85\xdf\x1f\xb7\x02\x67\xc0\xfe\x2a\x8f\x07\xa0\x17\x6c\x1c\xc7\x6d\x1d\x1a\x0f\xf1\xd5\x4e\x21\xb2\x8b\xda\xb0\xeb\x1d\x3c\xac\x88\x1f\x9d\xd8\x21\xbd\x44\x04\xb3\x4c\xb9\x0b\xa4\x4c\x00\x86\xb8\x34\xf6\xd5\x93\x9e\x70\x4c\x5f\xd9\xda\xb0\x0c\x1e\xe1\x9a\x58\x4a\x21\x7d\x29\x03\x56\x10\xe3\xa2\x78\x7f\x64\x6e\x89\xc0\x54\xc4\x99\x95\x6b\xa1\xf6\x5c\xf3\x29\x07\x04\xf0\xa2\x3a\xb5\x53\xfe\x54\xe1\x1d\x8f\x0d\xd3\x3f\x76\x54\x19\x4b\x47\x15\xad\xed\xcc\x0c\x1f\x80\x2e\x7c\x11\xb6\xd1\x28\x6c\x67\x71\xbc\x86\x60\xa1\x04\x93\xad\x38\xa2\xf6\x79\x96\x81\x00\x95\x00\xef\x36\x8e\x3a\xd8\xa4\xd8\x93\x25\x0d\xfe\x61\xba\x75\x03\x88\x61\x32\x47\x8d\x67\x5f\x3b\x31\xd1\xa6\xa1\xf7\x2f\xd8\x99\x63\x49\xe1\x6b\x03\x7f\x56\xc3\x2a\x2f\x86\xf0\x02\x1c\x62\x88\x3d\x45\x2f\x1b\x69\x6b\xf4\x04\x48\xc1\xc0\x36\xc8\x1c\x4c\x41\x2a\xd4\x37\x04\x55\x98\x11\x13\xec\xb1\x9b\x7c\x5a\x87\x2f\xd5\xfb\xed\x95\xac\xc4\xf7\xc3\x5d\xcb\x9b\x10\x8f\x52\x2e\x14\xba\x65\xb2\xf3\xba\x55\xd0\x12\x93\x8f\xb9\x7a\xa4\x0e\x78\x64\xfd\x21\xda\x74\x59\x59\xa4\xc7\xcc\x20\x9e\x03\xd6\xb5\x5f\x08\x71\xcf\x22\x1c\x86\x66\x18\x9f\x48\x6e\xbb\x7e\xe2\xe8\xee\x9c\xe0\x75\xf3\xff\x7c\x1d\xe4\x50\x0e\xf1\x91\xeb\xae\x76\x83\xb5\xf6\xf8\x14\x14\x7e\x7c\x84\x45\xa6\x91\xe3\x00\x81\x40\xdb\x33\x88\xab\x37\xcb\xd6\x3d\xf2\x4a\xd5\x3c\x92\xda\xf2\x04\xab\x8d\x6d\x5f\xa2\xf4\x54\x93\x03\xf4\xb2\x5c\x9c\x8b\x91\xfc\x36\x78\x69\xcb\x49\x92\x10\xa0\x59\xbf\x28\xca\x92\x3b\x98\xbf\x6b\xc5\xf0\xbb\x39\xb5\x20\x38\xab\x79\xd1\x89\x5d\xd8\x81\x17\xc1\xef\xd0\xcc\x43\xb2\x36\xe7\x4c\x02\x1d\xeb\xa6\x76\x66\x1d\x82\x0a\xb5\xe8\x28\xfb\xfa\xbf\x65\xd2\xdd\xa8\x2b\x80\x0d\x24\x8e\xda\xcf\x56\x3d\xd9\xfc\x48\xff\x44\xcb\x9b\xae\xd6\x17\x1e\xc9\xe6\xa8\xfc\xef\x09\x27\xee\xa9\x1f\x29\x65\x28\x12\x1f\x0f\x57\xea\x73\x36\xc6\x43\x02\x28\x98\x2d\x58\x87\x25\x14\xbc\xfd\x4d\x2f\xf6\xc0\x0a\x94\x7f\xa2\x69\xf8\x36\xea\x4c\xb3\xc7\x8e\x44\x42\x38\xf0\xd9\x5e\x1f\x51\xd7\x16\xcd\x13\x49\x68\xcb\xae\xc3\xf0\xb3\xd1\xf3\xda\x06\xdd\xab\xfb\x47\xa4\xa3\xb7\x16\xd7\x77\x69\x7d\x81\xe5\x96\x81\x06\xfb\xcd\xe8\xf5\xfd\x16\xa7\xc1\x7e\x4f\x2b\xa9\x59\xf6\x3b\x68\x34\x6d\xf0\x7d\xfa\x47\xb3\x1f\x94\x40\x02\xc1\x6d\x16\x33\x6d\x7d\xf1\x44\xf6\x59\xcd\xe2\x02\xb5\x4f\x19\x8a\x03\x1b\xe9\x6c\x69\x57\xed\x70\xb3\xa5\x20\xbe\xd5\x80\x6f\x93\xab\x4b\xf5\xc0\x0a\x39\x09\x3c\x0f\x08\x89\x0b\xf4\xbe\xc6\x09\x29\x44\x91\xdd\x3a\x59\x18\x11\xec\x4a\xa2\xa0\x94\x65\x80\xd2\x8e\xc8\x5e\x35\x1d\xc3\x8c\x3f\x00\x93\x2f\x79\x70\x2b\xde\x4e\x50\xfc\x56\xdd\x7d\x55\x06\xec\x5e\xd7\x35\x78\x70\x23\xdb\x0d\x9c\xb5\x43\x25\x37\xaf\x8d\xe3\xcc\xe1\xdf\x39\xa2\xef\xb5\x50\x0c\x68\x97\x54\xf6\x1e\xd4\x29\x7b\x1d\xea\x12\xc7\x4a\x73\x7a\x5f\x6e\xcd\x7b\xf6\x85\x5e\x6a\x2b\xf9\x74\xac\xe4\x2a\x9c\x21\xbe\x22\x08\xb6\xfb\x25\x96\x26\x55\xb7\x2f\x8c\x4a\x06\x6b\xee\x37\xf6\x90\x79\x17\x1c\xda\x7c\x0a\xc5\xba\x63\x2f\x9b\x40\x14\x18\x75\xf9\xaf\xca\xef\x67\x47\x28\xec\x49\x20\x8f\xc2\xae\x25\x84\xbd\xc0\x39\xde\xa8\x76\x59\x95\xb2\x90\x14\x89\x94\xba\x22\x67\x75\x7a\x4d\xbb\x00\x37\xfa\x78\xf8\x2d\x02\x09\xa8\x55\x20\xc8\x0a\xf6\xb9\x20\x80\x91\x54\xae\xb3\x08\x68\x67\x86\x57\xee\xa3\x0f\x24\x7e\xd8\xe8\xb4\xd8\xc4\xde\xcd\x05\x8f\x6f\xbe\x0e\x31\x60\x89\x5f\xb7\x17\x54\xe8\x92\xf3\xbe\x34\x5a\xd7\x1c\x79\xdf\xbb\xc7\x5f\xc4\x02\xe6\x9e\x65\x73\xec\xf2\xe9\x62\xfa\xc7\x57\x65\x93\x89\x9b\x9e\x20\x40\xb1\x2f\x23\x98\xa9\xa1\x76\x21\xe4\x7e\xeb\xc0\xaa\xf4\xa8\xa6\xaf\xb2\x6b\x10\x72\xee\x5e\x96\x83\x07\x72\x19\x48\x1c\xb2\x76\xb1\x0b\xec\x0c\x74\xdc\x7d\xc6\xc4\xfc\x4c\xd0\xf6\x4e\x7c\x41\xca\x57\x46\xa9\x9a\x96\x5d\xf7\x26\x6a\x90\xdd\x07\x23\x7d\x58\xe8\xe9\x78\x52\x50\x96\xef\x1a\x5a\x6d\x96\xe7\xff\x4d\x9f\xcc\xf2\xb5\x28\xe2\x0e\x90\x0c\xff\x76\xac\x16\x2a\x76\xbc\xd5\x53\x0c\xbb\xe7\x0f\xe4\x8f\x00\xfc\xb9\x1c\x64\x6c\x0b\x5d\x13\xcf\x74\xb2\x5b\x82\xa0\x8c\x28\x84\xed\xb1\xe9\x09\x72\x41\x30\x09\x92\x93\xd8\x23\x64\x78\xce\x83\xf1\x20\x3b\xc2\x99\x83\x61\x18\xcc\xc1\xc7\xc4\x53\x5b\x73\x7d\x7c\x03\xb1\x0c\x9a\xe2\x4d\xb3\xbc\x3d\x2d\x3e\x95\xdc\x53\x08\xfa\xef\xa9\x65\x55\xec\x49\xd4\xc3\x8b\x18\x2c\xc1\xa4\xb5\xf0\xf0\x1e\x79\xa4\x64\x3a\xee\xf9\x99\xa4\xbe\xd5\xd5\x4d\xcc\xfa\xed\x3c\xde\x09\x6c\x1d\x6f\x0f\x5b\x00\x02\xab\x86\xbf\x89\x8a\x25\x1e\x7f\x4b\x48\x42\xa0\xc7\xcb\x93\x0b\x3a\x4e\x09\x14\x5a\xe2\x94\xa3\x52\xba\xa9\x0a\x20\x35\x4b\x8e\xd4\xc2\xbe\x86\xea\x40\xf1\x79\xc8\x3b\x70\xcf\x7f\x75\x27\xa6\x9f\xe0\xa0\xfc\x60\x3d\x9a\x0e\x5a\x05\x13\xae\x37\x47\x24\x8b\xf9\x9e\x95\xd3\x8e\x1a\x0b\xa2\xf5\x19\x4c\x9c\xb5\x31\x14\x99\x05\xa7\x49\x54\x9d\x13\xc3\xa2\xea\x74\xb3\xb2\x5a\xf1\xac\xe3\x95\x83\x2a\x18\x99\x3c\x5e\x86\xb8\x7d\xcd\xb1\x24\x5b\x39\x45\x66\x4c\xe4\x40\x54\x28\xf8\x46\xa6\x60\x11\x22\x23\x68\xa6\x1e\xce\x76\xdc\x25\xc9\xa3\xd6\x4e\x61\x78\x95\x73\xd9\x9a\x9e\x1c\x86\xb7\x0f\xd3\x67\xb6\x0f\xcf\xbe\xdd\xab\x68\x7f\x79\xb6\xa0\xb8\xb1\x72\x8e\xa5\x7c\x30\x84\x44\x84\xbc\x8d\xe1\x3a\xce\x67\xe4\x1b\x94\x81\x50\x82\x3b\x59\xb9\xd9\xc1\xa3\x6c\x7d\x2e\x52\xfd\x1d\x29\x64\x61\xb3\x91\xed\xde\x83\x11\x58\xeb\x25\x06\x66\x11\x06\x0f\xc1\x7a\x84\x69\x9d\x04\xf0\x39\xc3\xfb\xc4\xb1\xd6\x05\xfa\xa0\xe6\x48\xa5\xbe\xa8\xad\xc9\x52\x01\x55\x1f\x16\xb6\xe9\xe3\xed\x6b\xcb\x6f\x25\x3d\x18\x0a\xea\xe2\xfc\xca\x4e\x7e\xb9\xe5\xfb\x4b\xa2\xdf\x7c\x83\x12\xd3\x4f\x91\x63\x25\x7d\xcb\xb2\x46\xb6\xc6\x80\x12\x5d\xe6\xa6\x84\xe7\x0d\x9c\x77\xcc\xdf\xd8\xc0\x72\xe7\xff\xb3\x49\x2f\x49\x7c\x0d\x49\x56\x17\xc8\xcf\x14\x6c\x05\x1b\xc9\x05\xb7\x14\x9b\xd4\x2e\xde\xd2\xf1\x4a\x85\xbf\x38\x86\xb8\x58\x72\x37\x3c\x28\x5c\xe2\x49\xa7\x42\xa6\xe3\xe4\x5e\xd6\x2d\x4d\x3a\xcb\xc4\x59\xea\x96\xc6\x6f\x89\x7d\xe3\x1f\x3c\x44\xf2\xe3\x8a\x0e\xff\x0f\x97\xb0\x4a\x91\x00\x1f\x4c\x99\x5e\x21\x9f\x47\x40\x72\xca\x5b\x8e\xd2\xf5\x5e\x6c\x20\x24\x57\xa9\xf7\x70\xc5\x5d\x70\x86\x15\x15\x60\xc8\x07\xde\xf5\x9e\xb9\x09\xc7\x19\xd9\x82\x3f\x9b\x12\xb9\x56\x84\xf3\xf0\x74\xf5\xba\xe2\xdf\x24\x5e\x5e\xeb\x29\x7b\x0e\xa8\xe3\xbf\xfe\xcc\xa0\xd7\x26\x92\xb4\xe2\xa3\x3e\x0f\x8f\x14\x06\x16\xb1\xae\x7d\xd7\x22\xa6\x6d\xa2\xb7\x4e\x4b\x7c\x04\x00\xdf\xfc\x12\x9b\xbc\x13\xe7\x2b\xd5\x79\xd2\xef\x42\x62\x7a\x06\xf2\x8f\xdf\x01\x4f\x58\xb9\x0d\x71\xe1\x8f\x90\x38\x52\x81\xb2\x80\xa8\x3b\x81\xa6\x80\x27\x8b\x1a\x8f\x22\x18\x15\x0c\x3d\x83\xf3\xd0\x70\x2f\x2a\xd1\xba\xee\x73\x23\x2f\xfe\x6c\xc1\xdd\x5a\xd5\x47\x3a\xd8\xc4\x47\xb2\xd6\x88\x63\x05\xbd\x31\x8b\x35\x6a\xac\x30\xb4\xf5\x27\xd5\x0b\x9e\x63\x1e\xd5\x73\x85\xc0\x00\xa3\x35\xb1\x16\x27\xbe\xe2\xef\x37\x1e\x4d\x09\x9f\x95\x21\x36\x1b\x04\x6c\xdf\x1a\xd2\x7c\x43\x74\xc5\xf0\x49\x5c\x42\xf1\x93\xe0\x29\x06\x79\x35\x1b\x9f\x19\x4b\x62\x4a\x6e\xde\x57\xa7\x47\x2e\x3a\x72\x8b\xa8\xa7\xb5\xfc\x5c\x32\x8e\x05\xa2\x35\x95\x60\x02\x5d\x23\x7a\x13\x60\x6e\x16\xe7\xea\x4c\x46\xed\x1f\xee\x7e\x6e\xff\xa0\xef\xc9\x10\x24\x44\xae\xc0\xd2\xca\x33\x38\xd7\xb8\xc8\xf0\xc7\x09\xbb\x36\xe6\xb9\x15\x5d\x5e\x7a\x88\xc2\x0b\x9c\xc5\x64\xaf\x2d\xcf\x27\x6d\xda\xf5\x8f\x40\xeb\x5a\xc6\xf3\xe6\x95\x33\x89\x2c\x0d\xc4\xea\x23\x98\x9f\xc3\x87\xbe\x96\x81\x27\x07\xf3\xb3\x40\xa9\xcf\x24\x48\xd7\x99\xd3\x39\x37\xa2\x67\x8e\xc9\xae\xd6\xc6\x52\xca\xe7\x6b\xe3\x99\x59\x65\x9e\xad\x5a\x2b\x41\xa9\xe6\x9b\xff\xdf\xef\x22\x73\x3d\x78\xcd\xdb\x1d\xb4\xcf\x21\x25\xb2\x36\x36\x96\x95\x14\x8c\x56\x4c\x62\x83\x05\xd3\x25\x7b\x8d\x2c\xa7\xeb\x8a\x70\x62\x96\x88\xd3\x20\x11\x9b\x93\x65\x88\x86\xba\x81\xf2\x4f\x8d\xd2\x85\x85\x5b\xae\xf2\x8a\xd8\x0c\x36\xdc\x5c\x62\xb5\x65\x75\x1d\x61\xa1\x85\x3c\xe6\x59\xc9\x76\x6b\x1e\xce\x60\xa8\x56\x6a\xb7\x03\x66\xd6\xac\x39\x75\x22\x67\x7e\x07\x19\xdc\xda\xff\x41\x39\xd8\x9f\x0f\x0e\xfc\x2b\x88\xd7\x0e\xf1\x24\xf7\xd0\xa3\x6f\xbb\xe3\x80\x7d\x16\x5f\xf3\x06\xee\x33\x9e\x7c\xcb\x8d\x3b\x7a\xcb\xfa\x6f\x2a\xfa\x01\x28\x86\xd7\x80\x41\x3b\xfd\x14\x57\x2e\x88\xab\x5f\xba\x9c\x7d\x1f\x8b\xc8\xb0\x9f\x39\x89\xed\xbd\x2f\xc7\x2b\xd0\x76\x1d\x1f\x9e\x1d\xea\x2d\x42\xe0\x18\x26\x9c\x0e\xb3\x05\x44\x56\x3d\x89\x4b\xb9\x9f\x70\x7a\xfe\x3e\x6f\x51\xa5\xbc\xcc\x25\x18\xb4\xed\x15\x1e\x5c\x74\x02\xd9\x35\x1c\xf1\xa7\x70\xd7\xa9\x8f\xef\xed\x91\x35\x92\x6b\x58\x6f\x41\x88\x1d\x1a\x80\xe0\xbe\x66\xf2\x8a\xf3\x5d\xcb\x67\xe5\x38\x07\x23\xf6\x12\x0f\xab\x53\x96\xc3\x0a\x66\xec\x99\xa4\xce\x9f\x2a\xd6\xe3\x0f\xf9\x45\xd7\xf4\x2f\x91\x1c\xf9\x3e\x92\x68\x9e\xcd\x1a\xe7\xbf\x2e\x0a\x8f\x62\xfe\xc4\xff\x5c\xfa\xcd\x35\x8b\x8f\xf9\xa2\x27\x1a\x4c\xd6\x59\xff\x4a\x2f\xee\xe1\x84\x13\x25\x7b\x3c\x00\x4e\xde\x56\x4f\x04\x4a\xa2\x92\x76\x39\x31\x47\xc7\xef\x43\x81\x43\x81\x97\x3c\x74\x9a\xe3\x9c\x1b\x57\x75\x78\x82\x57\x27\x20\xd1\xff\xe9\xc2\x75\x40\xbe\xe9\x48\xd8\x32\x34\xdd\xed\x07\x43\x81\xab\x32\xce\x04\x4f\x7a\x9c\x40\x82\x31\x4e\x91\x2f\xfe\x0f\xc7\x04\xdb\xad\x0a\xa9\x33\x43\xa4\x57\x50\xcd\x62\x43\xe5\xa6\x33\x37\xa1\x0f\xe4\xbc\x07\xa7\xb5\x22\x34\x30\x74\x14\x71\x61\x7b\x52\x9d\xa3\x95\x3b\x96\x70\x3c\x1b\xac\x37\x69\xba\xed\x85\x8e\xc1\x37\x8e\xee\x92\x7c\x30\x6b\x72\x62\x5c\x44\x3a\x2f\xb1\x2d\x12\x6d\xac\x5f\xa9\x22\x4f\x0d\xda\xc9\xa3\x3b\x5f\xac\x48\xd9\xaa\x48\xb9\xdb\x7f\x1b\x4d\x77\x8b\xc4\xb3\x6f\x68\xbd\x05\x06\xde\xde\x6c\xd3\x9d\x4b\x94\xe5\x78\x57\x1f\x21\xf1\xd4\xdb\x6c\xd0\x3e\x6a\xd6\x01\xfc\x6e\x1c\x3c\xcc\x84\xba\x54\x7a\x61\x9f\x11\xc1\x60\x33\xac\x1a\x28\xb8\xba\xe9\x86\x61\x60\xfe\x15\x48\xa1\x09\xc2\x44\xb3\xfe\xdb\x47\x13\xec\xff\x34\xf3\xe4\xc3\xf4\xf2\xa1\x78\xc0\x72\x33\xa1\x1c\x25\x17\xf8\x97\x5b\x33\x83\x25\x2c\x26\x03\xa4\x01\xe6\xda\xc2\x72\xab\xf5\x2c\xf7\x2c\x1b\x77\x91\x9c\xe8\x72\x0f\xaf\x22\x69\x5c\xc3\xf4\x47\x81\xdd\xa3\x1d\xf7\x87\xc5\x3b\xb3\xb9\x2c\x77\xa7\x5b\x5c\x44\xe1\xb1\xdc\x9d\xae\x2b\x5f\xbd\xd9\xe2\x22\x90\xae\x2f\xb1\x7b\xbb\x2b\xce\x0a\x91\x75\x33\xee\x6e\x31\x43\xed\x64\x29\x1b\x04\xb4\x46\xdb\x57\x13\x7e\xb0\x8b\x28\xcf\x10\x50\x94\xc6\x86\xac\x02\xa4\xa5\xae\x4f\xbb\xa3\xab\xbe\xfe\x23\x9d\xb7\x17\x39\x2e\x19\xf4\xd7\x95\x6c\xb1\x56\x36\x71\x22\x1b\xc9\x7d\xa0\x04\x89\x8e\xca\xba\x31\xbb\x7b\x71\xd1\xfa\x80\xc1\x1a\x5d\x0e\xf1\x65\x40\x05\x9c\x9e\xa9\xa5\xec\xb2\x61\x60\x0b\x44\x95\xed\x49\x37\x96\xf0\xad\xa9\x67\x2d\x6e\xbf\x04\xa1\xb8\xbd\x26\xd0\xe8\x12\x6b\xa1\x16\x88\x34\xce\x25\xd2\xef\x91\xe3\xe6\x96\x33\x2c\x2d\x25\x23\x3a\xf4\x32\xe2\x1e\x81\x8e\x60\x08\x8f\x50\x3b\x30\xce\xf3\x97\x36\x6a\xcd\x71\xba\x78\x96\xe0\x0c\xe1\xf3\xc3\x42\xe6\x7f\x41\x32\xce\xf0\xe7\xc5\xdd\x49\x1f\xa2\x39\x48\xc8\xd3\x4e\xb2\xec\xcc\x87\x00\x3d\x16\x2f\x45\x07\x67\x20\x9f\x4c\x5e\x04\xd4\x92\xc7\x92\x5f\xad\xde\xf9\xfe\x65\x93\x98\x05\xda\x05\x73\xa5\x59\x5d\x77\x80\xb5\x49\xb3\xd9\x86\xfb\x29\x16\x79\xa4\x96\xbc\xef\x52\x35\x33\x18\x3e\x86\xa5\x89\x5a\x82\x32\x2e\x1e\x02\xd2\x69\x32\x51\xf0\x11\x2e\xca\x68\x40\xee\x61\x94\x53\x12\xc5\x79\xf9\x99\x6c\xbe\xa1\x27\x98\xcb\x93\x5f\x03\xdc\xe2\x3c\x72\xbe\x6a\xd4\x21\x56\xac\x17\xf1\xf0\x2e\x79\x12\x97\x77\x1e\x21\x6e\xe9\xa8\xe7\x2d\xf4\x8a\x5d\x6c\x6c\x5b\x4b\xee\xc2\x13\xbe\xe4\x44\xe7\xd2\x92\xde\x57\x80\x83\xa1\x40\x4b\x7a\x91\x06\xfc\xe6\xfe\x1b\x82\xfc\xf2\x2f\xf9\xd6\x26\x20\x36\xf8\x14\x09\x04\x86\xb8\x9e\xb7\x84\xbc\xe3\x02\x67\x92\xd8\xbf\x0d\x15\xce\x34\x16\xe4\x8a\x93\xf0\x3e\x9d\x3c\xfe\x24\xb1\x27\x7c\xae\xf5\xad\x77\x9b\x48\xa9\x08\xc9\xfb\xad\x63\x8d\xce\x3e\xd8\xca\x61\x34\x09\xf5\x8c\xa5\x5b\xd2\x2e\x12\xf8\xe4\x7e\x3a\x31\xaa\x6f\xf7\x97\xc7\x6d\xad\x96\x6d\xca\x63\xf0\x1c\x38\x88\x1a\xfc\xd1\xa2\x83\x62\xbd\x88\x58\x7d\x92\x87\xc8\x79\xe9\x74\xa4\x8d\x18\xfe\x3a\xd3\xba\x33\x5c\xda\x99\xd4\x09\xca\xf7\xd6\x0d\x97\x4b\x64\x01\x06\x27\x5d\x64\x26\x05\xbb\x35\x59\x9f\x2b\x19\x0a\x65\x01\x43\x18\x96\x8b\x08\xdf\x27\x4d\xf0\x80\xf4\xa8\x46\x46\x7c\x1b\x90\x96\x41\x1a\x31\xa9\x17\x92\x1c\x41\x1a\xee\x5e\x77\x31\x6c\x71\x3f\xe0\xb8\xe1\x39\xfa\xea\x7e\x5d\xe2\x67\xa3\x8f\xef\xf3\xa1\x47\xd7\x31\x7f\xde\x40\x3d\xc4\x45\x2f\x36\x07\x8c\x88\xb7\x0f\x7e\x4f\xd1\x04\x3d\xef\xe6\xba\x35\x18\x44\xde\x37\xd7\x48\x9e\x77\xf0\xb4\x1f\x8c\x20\x32\x30\x7c\x48\x5f\x2e\x06\x86\xe7\xbd\x89\x43\x08\xac\xee\xf1\x73\x6f\x38\x90\x4a\xf9\xb0\x74\x5a\xf0\x5b\xa2\x66\x00\x13\x7f\xbb\x24\x81\x22\x26\xea\x9b\x16\x95\x95\xd4\xa8\x7b\xde\x6e\xea\x2f\xc2\x4f\x5d\x69\x50\x1d\x40\x0f\x47\xd4\x42\x8f\x00\xfb\x40\x89\xac\xef\xdf\xcf\xf7\x47\x1a\x03\xaa\xf8\x42\x6e\x64\x83\xeb\x5b\x4b\x81\xc0\x24\xb0\x3f\xea\x5e\x86\x1f\x63\xfb\x51\xd9\x1f\x3e\x91\x08\xcd\xf3\x95\x46\x13\x5f\x3a\xfe\x2b\x17\xad\x8c\x3c\x7d\x95\x4c\xff\x4d\x9f\x4d\xec\xf4\xe9\xe4\x71\xa9\x3d\x2d\xe8\x27\xa2\xac\xdf\x8f\x08\xdd\xbf\x51\x6f\xb8\x28\xc5\x1c\x8f\x98\xf3\xb9\xe1\x5e\xfe\xd0\x67\xbd\x6e\x91\xc8\x5f\x47\x27\x20\xdf\xb3\x55\xf6\x0f\xd9\xfc\x33\x07\xd9\x7c\xd1\x71\x67\xdf\x9e\x54\xd5\xdb\x85\x80\xa9\x97\x58\x6b\x11\x60\x25\x01\x96\x60\x94\x07\x76\xb0\xbd\x7f\xa7\x58\x1a\x8d\x7d\x38\xa9\x9f\xbe\x40\x1d\x3b\xff\x1c\xa9\x01\x1e\xf3\x56\x51\xdd\x67\x77\x2b\x3c\x49\x46\xfd\x84\xbf\xeb\x95\x8e\x80\x24\x76\xaf\x7c\xc0\x1b\xf3\xb5\xac\xcc\x51\x0d\x32\x39\x90\x92\x9e\x8c\xea\xfa\x56\x9e\x3e\x3b\x22\xc2\x8a\x1e\x4f\xa4\x80\x21\x10\xd1\x5f\x8d\xec\x1d\xe3\xec\x8f\x77\x7c\x91\x18\xa9\x53\xd2\x23\x3b\x99\xd7\x5c\xb2\xc7\x06\x58\xa9\xb5\xd6\xe7\xc3\x2e\x10\x3f\xc2\x9a\x69\x84\xa4\x3f\x0b\x57\x35\xad\xa4\x86\xd6\x93\x5c\x43\xcf\x42\x59\x75\x30\xd3\x8b\x3b\x7e\x9b\x4e\x0d\xa9\xc0\x22\x99\x5f\x77\x11\x94\x97\x55\x3f\x5f\x96\x55\x7b\x82\x40\xd4\xd0\x14\x9e\x5d\x90\xd5\xab\xad\x95\x99\x3b\x82\x9e\xee\x59\x5a\x6d\x75\x04\x0c\x55\x9e\x35\x7f\x4b\x22\xed\x7c\xb0\x89\x90\x96\xde\xcf\x90\xcf\x19\xde\x56\x11\xc3\x1f\xe7\x15\xfc\xf3\x87\x5a\x0b\xd6\xda\x4f\x82\xb8\x78\xde\xf2\xa8\xda\xe5\x75\x9f\x55\xfa\x4b\xcd\xcb\xd9\x26\xdb\x30\x5a\x37\x95\x7f\x09\xda\xf3\x33\xcd\xf7\xc6\xc3\xcb\xd9\x98\xf2\xcb\x21\x92\x77\xfb\x7d\xe1\x2e\xde\x64\xe6\x67\x9d\x18\x58\x6c\xe5\x38\x73\xb2\x03\x38\x06\x03\x3e\xa6\x6d\x3f\x4a\x79\x7b\xb0\x7e\x81\x74\x7e\x3f\xd1\x24\x0d\xdf\x9d\xf6\x9e\x60\xaa\x24\x4b\x3c\x1b\x27\x66\xb6\x59\xa0\x69\x5d\x24\x24\xa3\xf1\xee\x9d\xea\x5e\xcd\xbc\xad\x8d\x3c\xd3\x21\x9e\x7a\x2c\x2f\xfb\x03\x49\xfb\xa1\xea\xea\x9b\x82\x50\x10\x3b\x14\x1b\x14\x66\xae\xcb\x23\xc9\xb9\xd5\x7b\x15\xf9\xfd\xc2\xbb\x5b\xb8\x4a\xef\xac\xf6\x2f\x3e\x87\x98\xdb\x3e\x31\x01\x6c\xea\xca\x4f\x28\x2d\xce\x34\x3a\x9f\xe8\x37\xda\x3c\xf2\xe9\x31\xee\x02\xd6\x9d\xf0\x68\xc9\x13\xd8\xbc\xe5\x9d\x88\x48\xf0\xfa\x00\x51\x88\xf7\x57\x8f\x3f\xe9\x21\x86\x91\x79\x1d\x6b\x04\x0f\xeb\xb2\x5d\x8e\xf8\x51\x77\xbd\xb1\x07\x98\x23\x7d\x0d\xe2\x51\xb9\xf6\xf1\xa8\xe4\xc4\x62\x34\x76\x38\xbd\x1f\x2d\x76\xfa\x91\x5b\xe5\x01\x49\x98\x7f\x8a\x4d\xf8\x01\x36\x49\xaf\x8f\x7d\xf2\xfa\x25\x9c\x43\x64\xfb\x70\x36\x7d\x52\xde\x43\x7a\x46\x68\x64\x95\xcc\xea\x51\x0e\xd3\xc3\x66\xa0\x6c\xb7\x40\xa4\xe4\x17\x3d\xac\x95\xc9\x6c\x00\x3c\xad\xf2\x4e\xe1\x19\xfb\xb3\xea\x50\xce\x3f\x8d\xb4\x9c\x5d\x18\x98\x05\x7a\x22\x3e\xa7\x2b\xa2\x43\x28\xdb\x87\xae\x44\xb7\xe0\x7d\x04\x2b\xdb\x56\x7b\xb1\x0b\xd9\xe3\xd1\xd0\x57\x7c\x02\x1b\xaa\xaa\x08\x56\x79\xd1\x88\x2a\x10\xe8\x43\x89\x85\x19\xff\xcd\x6a\x1d\x90\x0f\x81\x25\x54\x93\x42\x1e\xa0\x80\x11\xcd\x63\x9e\xc0\x04\xac\xf0\xa7\xf9\xa6\x57\x67\xbe\xaf\xe0\xc4\x57\xf4\xde\x7c\x47\xf2\xdf\x7c\x7b\x7f\x6b\xdf\xda\x75\xfe\xb8\xce\x6f\x7b\x90\xc1\x99\x7d\x5b\x63\x73\x3e\x76\x2a\xe2\x5a\x41\x46\x7b\x33\x1c\x83\x5d\x5f\x74\xfc\x4e\x20\x2f\xd2\xed\x3b\xc7\x95\x06\xb1\x48\xce\xf5\x15\x9c\xf9\x0a\x14\xf6\x18\xda\xab\xd1\xca\x9f\x67\xf0\xdb\x2b\xd6\x01\x0e\x26\x75\x88\xa0\xcd\x27\xe3\xfd\xb1\xb5\x38\xa6\xd9\x35\x50\xec\xa2\x1e\x54\x09\x16\xfd\xd2\xd8\xec\xc9\xfd\x03\xd6\x27\xde\x66\x5d\xbe\xbf\xe9\x80\x6d\x7d\x7a\xd1\x43\x1a\xfe\x43\xe1\xbf\x5c\xdf\x25\xe6\x18\xb6\x25\x26\x13\xf0\xec\x2f\x8c\x9b\x41\xaf\x92\x83\xd2\x95\x1b\x8d\xf9\xbe\x2e\xaa\xff\x63\x13\x59\xc9\x5c\xe7\x65\x8c\xff\xce\x7f\x9a\xce\x8c\xc4\xa0\xb8\xa8\xc1\x5e\x8c\xec\x88\x18\x26\x21\x7c\xcd\x4a\x63\x98\x6b\x3c\xbf\x2c\xc1\xf9\xb9\x0e\x7c\x23\xc1\xbb\x5e\x5d\xdd\xfa\xd6\x13\xa2\x7b\xd9\x7a\xec\x33\x1c\xdb\x33\x7a\x50\x3f\x3f\x32\x78\xfd\xf4\x45\x8f\x8e\xca\x00\x45\x62\x32\x90\xd9\xff\xd1\xf3\x33\x4d\xd7\x40\x3f\x07\x07\x05\xd4\xf7\xf5\x13\x1f\xee\x78\xc9\xb2\x0c\x0a\xb6\x72\xa2\x7e\x56\xaa\xe4\x91\x0e\xfd\x19\xb1\xd4\x7c\x8b\x45\x9a\xe2\x73\xfe\x84\xfc\x29\x20\x0b\x11\xe1\xbf\xdc\x67\x31\x3b\xa9\x89\x48\xf2\x79\xd7\x90\xda\xe5\xbf\x30\x08\x0c\xa4\xea\x57\x7e\xda\x9c\x95\x35\x3b\xbb\x1c\x38\xd3\x4b\x67\x4f\x38\xfa\x10\x2d\x2a\x73\xe3\xfb\xcf\x54\x73\x9b\xa1\x74\xea\xe5\x2a\xf5\x2b\x43\x2b\x8b\x50\x09\x68\x3c\xfb\x8b\xf2\x33\x40\xf9\xef\x04\xeb\xdc\x78\x6c\x3c\x53\xd9\x16\x95\x14\x72\xf8\x13\x02\x35\xdb\xc1\x41\xd1\x8f\xe5\xc7\xc6\xe7\xcf\xf5\xc7\x39\x77\x4c\x21\x06\x9f\x6b\xc8\x04\x24\x89\x17\xa4\x89\xa7\x4f\x83\xc8\xc6\x01\xfd\x0e\xc1\xf1\xdf\x49\x1e\x71\xf6\x48\x00\x32\xe7\xc3\x48\xb7\xb7\x72\x71\x83\xf7\xe9\x59\x69\xa3\x82\x79\x66\x9f\x7d\x05\x19\xbf\x99\xf6\x5a\x79\x75\xae\xff\xd0\x8e\x30\xac\x9f\x1e\x57\x7c\xc5\x18\xee\x82\xcc\x7f\xaf\x55\xfb\x56\xf1\xf4\x1f\x43\xfb\xc6\xb0\xa4\xf8\x09\xe0\xde\x21\xd0\xff\xd3\x15\x09\xd4\xbe\x55\xeb\x59\x43\x35\x80\xb9\x19\x36\x30\xb4\xee\x29\x29\x29\x72\x4e\x5b\xc8\x12\x6c\x67\x6b\x78\x49\x39\x1e\x70\x36\xea\xbd\x62\x28\x8d\x5b\xe1\xa8\x09\xf5\x1d\x36\x7a\xcf\x40\xf9\x09\x09\xb4\x59\xc4\x2c\x9d\xaa\xd9\x83\x6f\xb5\xc2\x8f\x50\xbe\x25\x6e\xf5\x8f\x0e\x44\x6a\xc1\xfa\x36\x94\xee\x87\x9e\xd4\x12\x22\x04\x66\x93\xcd\x01\xa5\xff\x33\xa7\xa2\x05\x49\x68\x14\xb0\x26\x13\xb2\x65\x79\xd8\xf0\xd6\x39\xba\xc2\x49\xbc\xf3\x4e\xaf\x14\xb6\x9c\x44\xd7\x3c\xdd\x21\x36\x64\x28\x63\x5e\x75\xfd\x27\xa1\x82\x10\x15\x60\x78\x69\xfe\x8f\xda\x04\x0c\xf6\x70\x95\x02\xee\xda\x1a\xe5\xc6\x74\xaf\x1c\x61\x26\x2c\xa7\x72\x8c\x30\xe8\x6c\x52\x71\xb2\x82\x19\xa0\x13\xc0\xdf\x30\xee\x2a\x11\x35\xa9\xa7\xbb\x7f\xf3\xe7\x9e\xe9\x7b\xd0\x8e\xb0\x2d\xa4\x13\xeb\xd0\x04\xe6\x4c\x87\xc7\xcd\x55\xc0\xe9\xa8\xd4\x00\x01\xf0\xa5\xa6\x49\x42\x2e\x56\x66\x8c\x37\x13\x31\xa2\xdd\x1d\x49\x81\xcd\x40\x53\x39\x81\xaa\x01\x23\x40\x79\x70\xb6\x16\xcd\xfe\xd5\xb1\x1a\xd2\x74\xd0\x0f\x35\x1d\xc9\x66\xb4\x24\xaf\x3f\x12\x4f\x9a\x34\xba\x4e\xce\xbe\xa5\xa3\xb6\xaf\x2e\x69\x4f\xe0\x91\x9b\xe4\x41\xc7\x93\x81\x01\xc5\x51\xfd\x9a\xf1\x44\xb9\x02\x5a\x3c\x53\x65\xa0\xcc\x54\x4f\x71\xda\xdb\x4b\xe5\xa1\x87\x12\xb9\x21\x5e\x30\x31\xd6\x63\xaa\x9b\xe7\xbb\xba\x5e\x41\xbc\x0b\x70\x00\x1f\x3c\x50\x06\x01\xc0\xd4\xa4\x15\x9c\x13\x8b\x47\x16\x29\x17\x20\x7c\xd4\xc1\xa0\xa5\xd9\x09\xa2\x77\x2c\x15\xc9\x08\xe4\xc9\x8f\x53\x1b\xce\xa6\x82\x44\x16\x6a\x5d\x94\x9f\x3c\x00\x3c\x95\x6e\x5d\x18\x5a\x1b\x3c\x5e\xfa\xef\x71\x49\x7e\xe0\x10\x07\xb8\xdd\x0b\xe8\x7a\x79\x1a\x7d\x7e\x13\xe4\x39\x74\x11\x76\xb8\x53\x69\x37\x08\x5f\x20\x05\x1d\x8a\xab\x82\xf0\x02\xf6\xc1\xb2\x79\x30\x9e\x61\xca\x52\x16\x56\x82\xe3\x14\x52\x60\xd3\x4f\xa0\x23\x1f\x8a\x50\xc1\xba\x21\xaf\x92\xc9\x09\x32\xd1\xf0\xcb\x84\xcc\x13\x02\x38\x59\x0e\xa1\x4c\xc0\xb4\x89\x49\xde\x3b\x28\x15\x48\xd0\x60\xfa\xb3\xfc\x37\x79\xf7\xcc\xfd\x59\x33\x9d\x49\xa9\x09\x53\x7a\xc5\x75\x0c\xe9\x81\xd8\x1c\x41\xf5\x4a\xf7\x50\x18\x7d\x3a\x25\xb9\x44\x01\x78\xd4\x75\x9d\xf2\x9c\x4e\x89\xdd\xca\xe4\xbc\xf2\xdc\x83\x6c\xb2\x42\xf4\xe4\xf1\x67\xa9\x8d\x15\x6c\xc2\x7a\x56\x3c\x11\x60\x66\x04\x4e\x29\xb2\xf9\x1d\x51\x4c\x82\x0f\x39\xf6\x62\x49\x44\x87\xb2\x0d\x43\x7d\x8b\x15\xc3\x4a\xce\xc8\xb3\xfb\x78\x37\xa5\x55\x95\x59\xe3\x6e\x63\xaa\xe9\x2a\x0b\xa2\xcb\x70\x99\x85\x8b\xbf\x2b\x5b\x55\x45\x8a\x4b\x1f\x7b\xf3\x4d\xb3\x8c\x81\x09\xe9\xb1\xbc\x68\xee\x42\xae\x61\xf8\xc6\xf4\xdf\xb0\x6c\x96\x29\x75\xba\x79\x37\x78\xc7\x0f\xf9\xfd\x41\xef\xff\x26\xe0\x4d\x18\xe8\x19\x95\x37\xde\x9b\x0a\x4a\x1c\xdc\xcb\x9b\x64\x3a\x86\x5e\xee\xc4\x32\xb0\xa8\xc6\xe3\xfd\xbc\x15\x37\x35\xde\x0c\x32\xb7\xd2\xaf\x3c\x1e\x1f\xc5\xca\x8e\x07\x43\x6f\x47\x44\xc7\xd3\x6c\x82\xc4\x03\x53\x8e\x0c\x05\xa0\x8e\x9d\xdf\x8c\x0b\xfd\x08\xc1\xd4\x72\xe7\x3a\x64\x1f\x36\x95\x14\x72\x00\x3d\x3c\xd7\xf1\xc6\x43\xfc\xcc\xc8\xd1\xf3\x10\x48\x57\x77\xb0\xd9\xc8\xcd\x9f\xda\xdc\x0d\xdf\xf3\x58\xdf\x4c\x63\x1f\x3d\xdf\xa0\xc5\xd4\x8f\x15\xfe\xd4\x8d\x88\x4b\xc0\x23\x39\x7c\xb8\xef\x60\xa7\x6f\x40\xd9\xa7\xa3\x59\xc8\xea\x92\x47\xc6\x86\x30\x92\x6d\x44\x30\x48\xa6\x0a\x41\x95\xd4\xc8\x58\x23\xee\x73\x5c\x6e\x5f\xc1\xb5\x52\xdc\xfe\x86\xfc\x5e\x16\x2e\x55\xc0\x51\x59\xf9\xfc\x16\x8f\x98\x10\xcc\x7c\x02\x4b\xfa\x27\xd1\x0c\xef\x72\xfc\x2a\xf6\xd8\x18\x3c\xe3\x1b\x36\x65\xeb\x6f\x2a\x43\x6c\xcf\x50\x7b\xd8\x64\x14\x21\x91\x29\x94\x12\x6c\x3e\xea\x1c\x00\x63\x79\x24\x57\x4a\x80\xad\xcd\xef\x60\x2c\x41\x9e\x31\xba\xcd\xa9\x4b\xc2\x34\x68\x50\x4f\xc1\xc6\x6e\x8d\x92\x63\xa4\xa7\x8f\xe8\x32\x0e\xee\x52\xe0\x00\x06\x92\x88\x3b\x1d\xb3\xe6\x2f\x23\x46\x15\x1e\x36\x64\x19\xa4\x06\x13\xcb\xce\x5d\x38\x63\x86\x19\xe6\x67\x45\x64\x28\x55\x2c\x12\x75\x1a\x47\x2c\x52\x5c\x04\x07\xc7\x3f\x48\x4b\xa8\xd9\xa4\xbb\xe3\xd0\x30\xa6\x3f\xcd\x2a\x49\x28\xce\xe6\x85\x93\x13\x75\x8f\xce\xcc\x25\xd1\x8c\xb4\xf0\x29\x73\x5a\x3d\xa6\x54\xfc\x95\xe6\x7f\x7c\x79\xf9\x2d\xd9\x03\xe4\x41\xfb\x62\x68\xd6\xaa\x05\x4a\x01\x9b\x08\xbf\x7c\x20\xcb\xd6\xef\x3c\x78\xd0\x5a\xdc\x98\xf3\x75\x17\x3e\x57\x71\xec\x66\x12\x14\x99\xe5\xb4\x2b\xeb\xce\x1e\xdc\xc9\x45\x68\x90\xa8\x4b\x14\xa1\x09\x25\x1c\x1a\x95\xf2\xd1\x27\xc8\x5f\x51\xaa\xe0\xa0\x58\x67\x96\x3f\x11\x5d\xf8\x1a\x77\x8c\x01\xbd\xd0\xd6\xb6\xca\xd3\x69\xda\xe6\xf2\x79\x9b\x22\xaf\x11\x5a\x11\x59\x33\xdf\xbc\xfd\x86\x36\xc4\x8a\x6b\x66\xeb\x61\xe3\xfa\xbf\xec\xed\x4c\x96\x56\xf0\x97\x4b\xdc\x61\x55\x8a\x5c\x5e\xf9\x9f\x45\xdd\x3c\x7c\x51\x3c\x4b\x38\xa3\x7e\x58\x5f\x7a\x66\xc8\x87\x6b\x49\xf8\x65\x16\xb3\x39\xfc\x1f\x50\x74\x90\xe8\x43\x48\x6d\xf8\x88\x7a\x11\x49\x09\x2c\xb6\x54\x35\x38\x22\xf4\xbe\xe6\x63\xa2\xcb\x22\x2b\x80\x33\xc7\x9d\x20\xfb\x64\x0d\xdd\x88\x76\x13\x0e\x75\x64\xff\x8c\xca\xc2\x5f\x2a\xeb\xd8\x9f\x94\x9f\x1a\x8b\xbf\xba\x20\x14\x23\xf8\x6d\x61\x76\xc1\x5d\x3d\x03\x23\x87\x8f\x34\x0e\x6e\xb7\x98\x5c\x08\x42\x72\x0c\x66\xe6\x6d\x0e\x36\x79\x71\x0c\x85\xb8\x91\xcd\x45\x59\xc8\x01\xe5\x20\x11\x50\x6a\xe0\x8e\x14\x8f\xe1\xee\xf8\xe3\x4e\x1c\xfd\x87\xa8\xe4\x41\x99\x2a\xe1\x85\x99\xfa\x0e\x47\x12\x13\xd9\x50\xdf\xcc\x8d\x02\x60\x37\x68\x88\x52\x01\xf5\x3d\x2b\x79\x7a\x08\xfa\xe9\xc1\x1d\xe5\x6e\xe1\x0d\x75\xe7\x22\xfa\x10\x39\x74\x4e\x3a\x4a\xb0\xc6\x28\x34\x78\x72\xff\x4c\x66\x98\xa1\x46\x14\x9a\x21\x25\xac\x0d\xf0\x52\xf3\x9f\xcc\x94\x1c\x22\x76\x6d\xa8\xdd\x53\x55\x03\xe7\x07\x40\x79\x31\x20\x14\xd2\x0d\x5c\xe9\x18\x42\x17\x6a\x08\xea\xa2\xc1\x69\xb6\xa4\x47\xe1\x9f\x8f\x3f\xe4\x72\x70\xb9\x7c\x00\x43\x08\x9f\x24\x8d\x25\x4c\xfa\xde\x49\xa7\x75\x5d\xea\x4a\xb8\x86\x20\x44\x4b\xcb\x00\xad\x5a\xa0\xd2\x24\x1d\xa6\x59\xf2\x04\x25\x02\x23\x87\x92\x6f\x57\xa7\x20\x0e\x3d\x89\x7c\xfc\xea\x65\x5f\xef\x93\xb7\x94\xa3\xc5\xc0\xfb\x74\xa4\x76\xc0\x08\x91\xe1\x83\x5a\x10\xcc\x98\xb2\x32\xad\x0a\xf4\x1c\xc0\xcc\xad\x9a\x76\x74\xb4\x0e\xf9\x0b\x9a\x1f\x47\xef\x50\xa6\x73\xf5\x87\x33\x80\x44\x03\xee\xfd\xe0\x23\x47\x68\x99\x64\x6a\x06\x57\x9f\xa9\x44\xab\xd4\x45\xf2\xf9\x48\xf6\xdc\xa4\x1c\x11\x62\x45\x83\xf2\x4f\xac\xb4\xe1\x35\x74\x25\x8e\x23\x84\x27\xb0\x8a\x18\xda\x0f\xd5\xd9\x02\x75\x04\x92\xa1\x79\x02\x1b\xb5\x79\x29\x25\x16\x0d\x19\x4b\x82\xbb\xb4\x35\xb0\x31\x4a\x8a\xc1\x46\x58\x9d\xd6\xf3\x0d\x1c\x6d\x17\xef\x63\xab\x1b\x74\x18\x78\x9f\x1b\x16\xe6\xa4\xf6\x20\x89\x8d\xbc\x42\xa4\x56\x22\x08\xd9\x23\xee\xf8\x2a\xf2\xca\x88\x71\x00\x89\x69\xac\x49\x5c\xb8\x43\x46\x64\x86\x40\x68\x58\xa0\x31\xa4\x45\x30\x9d\x97\x2a\x02\x4c\x80\xf5\xb5\x4b\x7a\x1b\x92\x1b\xb1\xbe\xeb\xec\x7e\x32\x11\xc7\x1a\x7b\x8f\xe9\x23\x84\x59\x50\xa8\x50\xf8\x42\x65\x88\xae\xe4\xa2\xb7\x47\x5b\x7a\x40\x2e\x83\x6e\x63\x0e\x9d\x0e\x9f\x7e\xf1\x2e\xa6\x90\xf1\xf8\xa3\xbf\x31\x22\x80\x56\x67\xa1\xe5\x00\x6d\x09\x1f\x3a\xa0\x2d\x81\xa4\x46\xee\xec\xee\x99\x75\x54\x27\x37\x20\x17\xef\x08\xc0\x5b\x82\x7c\xd8\x26\x94\x55\x5a\xbf\xc5\x9a\xa4\x8f\x68\x2c\x06\x85\x5d\x0f\x58\x60\xe5\x7b\x4d\xce\xaa\x15\x90\xef\xc7\xc6\xee\x7c\x53\xe6\x05\x10\x19\x89\xc4\xdc\x75\x6c\xfa\x8a\x40\xc4\xfa\x20\xda\xe9\xd5\x1e\xe0\x7d\x95\x28\xdb\x00\x3f\xb3\xce\xbc\x45\x08\xea\x00\x52\x70\xfd\x7b\x51\xee\xd2\x10\xbc\x33\x58\xb3\xe6\xe2\x38\x50\x0c\x40\x03\x63\xb4\xad\xe0\x77\x82\x57\x40\x30\x69\xe9\x7a\x20\x87\x8c\x15\xa4\x18\xff\x7e\x9a\x0f\x1d\xd2\x14\x54\x3c\x80\x46\xc5\x9f\xbd\x0f\x92\xe5\x7f\x26\xd4\x4d\xf9\x6a\x90\xae\xe0\x27\x66\xe8\xe0\x47\xdb\x7b\x76\xef\x49\x94\x22\x24\xbd\xbf\xad\xb1\x93\x9a\xfe\xde\xa8\x6b\x70\xaf\xe5\x94\x2a\xc0\x1d\x12\x07\x77\xf9\x4a\xda\x42\x91\x4d\x00\x59\x25\x5f\x1d\xa4\x2e\xc4\xb9\x0e\x26\x6f\x94\xc7\x87\x5f\x61\x0f\x57\xbc\xff\xfc\x70\xfd\x07\xa2\x55\x3a\x0a\x47\x53\xad\xd0\xc1\x66\xa0\xdd\x42\x7e\xa9\x0a\x7e\x4b\x02\x31\xca\xd7\xb7\x04\x17\xde\x03\xcd\x7f\xd7\x9a\x38\x08\x8e\x8b\xce\x03\xc0\x16\x5c\xd3\xd7\x2b\x44\x27\x4e\xad\xe6\x02\x85\xe8\x44\x28\x09\x40\x6d\x42\x62\x0b\xae\x36\x51\x02\x4a\xee\x82\x5c\xf7\xda\x1b\x3f\xc9\x2a\x3b\xed\xa7\xb5\xd6\xd7\x9d\xcf\xd5\x9d\xdb\x93\x6a\x57\xed\x71\x6b\x86\x63\x1b\x9b\x1b\x64\x00\x94\x17\x71\x21\x8a\x10\x9f\xd8\x24\xd4\x0c\xc5\x09\x55\x73\xbd\x98\x0e\xdc\xbb\xb3\x81\x3f\x59\x7f\x32\x14\xab\xbc\x8a\x06\xf3\xf4\x21\x5a\x3e\xa4\xa5\x97\x04\x03\x24\x94\x34\xc5\x77\xac\xfb\xb2\x8e\x44\xb4\xfd\x22\x22\xb0\xb2\xa3\x5f\xab\xaf\x73\x28\x55\x4c\x5d\x68\x4d\x28\x0f\xa5\xaf\xbd\xd2\xc9\x7b\xc4\x97\xfb\x15\x97\x1a\xe7\x87\xf2\x3e\x4b\x84\x07\x4e\xd1\xd7\xf7\x10\x08\xd7\x0d\x9b\x61\xa1\xd7\xb2\x44\x7e\x53\xbf\x48\x88\x42\xe1\x9e\xfd\x22\xf6\xf3\xbe\x68\xcd\xbf\x47\x0c\x39\x5b\xb7\x99\xcc\x91\xcd\xd4\x3b\xa9\xa5\x03\xa7\x1d\xe5\xbb\x2b\x48\xcd\xa7\x92\x02\x95\x9a\xfb\x42\x5e\x59\x62\xb8\xa8\x42\xb0\xc2\x03\x4c\x25\x3a\x80\x90\x68\x3f\xe9\x2c\x75\x97\xf9\xee\xba\x5b\x4a\x0f\x87\x22\xbc\x29\x4c\x81\x58\x29\xdf\x28\x5c\xe4\xea\xc1\x48\x19\xce\x73\xdb\x30\x9b\x97\x17\xa3\x22\x85\xe0\x32\x70\x60\xf4\xe0\x4c\x89\xb3\x98\xc5\xd7\x14\x03\xe6\x4c\x59\x8c\xd9\x95\xb8\x29\x83\x81\x18\x4f\xab\xd6\xc8\x8d\x7d\x95\xf8\x05\xa4\x10\x3e\x44\xcc\xbf\x42\x18\x6f\x66\xcb\xca\x52\x99\xb1\x6f\x1c\x41\x9d\x27\x71\xf0\xad\xf5\x39\x62\x4b\x7b\xd0\x10\xe6\x21\x0e\xa0\xe2\x4e\x8f\xd8\xa5\x45\x8f\x27\x79\x6a\x95\x34\x0a\x98\x05\xe8\x0f\x06\x21\xaf\x21\x35\x41\x0f\x78\x1f\xf4\xcc\x00\x11\xba\x88\xe5\x38\xbe\x7d\xf8\xa2\x9b\x2e\x82\xbc\x52\xe8\x38\x7e\x1a\x12\xdb\x41\x07\x19\x60\x68\x3c\x20\x57\x5f\xaa\x09\xc7\x22\x35\x0c\x03\x5c\x1f\x33\xc8\x17\x62\x25\x83\x4e\x7a\x77\x9e\xe4\x40\xca\xea\x00\x0e\xb9\x8c\x03\xb6\x8c\x84\x16\xf6\x5b\xe5\x1e\x3a\x15\x88\x43\x68\x4a\x1d\x48\x58\xd5\xb5\x37\x2e\x4b\xbb\xfc\x44\x5e\x84\xd4\xec\xf0\x80\x8f\xf0\x68\x4b\x84\xa2\x0a\xaa\xc6\x58\x1d\x16\x60\xf3\x40\x94\x6c\xa8\x58\x0c\x6c\x10\x69\xdd\x3b\x9d\xda\x53\x1a\xf8\x83\x55\x32\x3c\x69\xa1\xc8\x25\x42\xa0\x4b\x88\xe5\x90\xce\xb0\x4f\x6a\x68\x11\xc4\xdd\x8b\xe1\xcd\x4a\x1b\x11\xa9\x64\x41\x39\x12\xcc\x14\x54\x56\xbd\xc6\xee\xc8\x0f\x21\x51\x27\x1b\x0a\xe9\x10\x58\xa5\x38\x75\xf7\x61\x57\xd0\x31\x53\xad\xbb\x3f\xd2\x78\x88\xe0\x22\x20\x29\x3c\x84\x0d\xd7\xdd\xb1\xd0\xd0\x61\x22\x72\x06\x0c\xa6\xf4\x1b\x42\xff\x9a\xb9\x77\xe2\xd7\xb6\xd2\x4d\x3f\x67\x21\xbf\xd7\x9d\x11\x36\xdd\xfd\xd3\x7f\x03\xe6\x62\x84\xa1\x89\x2e\xc7\xee\x9e\x48\xde\x7e\x73\x5a\x6f\x1f\x6c\x8b\x07\xc0\xc7\xdb\xcc\x5c\xa9\x4e\x70\x7f\x47\x62\x85\xee\xf8\x6c\x91\x6b\xd9\x1d\xb7\x07\xda\xa1\x0c\x47\x02\xf0\x53\x0a\x14\xf7\x26\xaa\x4e\x87\x1c\x48\xa1\x50\xa1\x95\x56\x83\x93\xec\x24\x83\x52\x3b\x40\x0c\xf3\xbd\xe8\xa2\x87\x0d\x69\x8a\x00\x35\xac\x98\x58\x43\x57\xfc\xaa\xf6\x21\x12\x51\xd3\x00\x6e\x34\x77\x3d\x74\xe4\x74\xed\x9a\x0b\xd1\x10\xfd\x66\x06\xd6\x95\xe6\x35\x22\xe2\xa9\x00\x68\x68\xc0\xda\xa0\xa4\x36\x8e\x0c\x85\x26\xd5\x06\x16\x3c\xc1\x8b\x7c\xf8\x87\x18\x6d\x75\x59\x6c\x49\x7c\x02\x84\x61\x11\xfd\xd8\x1d\xb1\xbc\xef\x91\x8a\x5e\xa6\x6f\x93\xc1\xb8\x63\x86\x02\x1c\xff\x6e\x22\x1c\xd0\xb5\x6d\x72\x17\x73\x0a\x14\x8a\x21\x10\x4a\x3d\x04\x9a\xc2\x06\xd9\xe7\x8f\x84\x15\xba\x10\x17\x80\xa8\x9f\x2b\x9b\xd4\xcf\xc5\x22\x74\x27\xde\x1c\x8b\x3b\x7b\xb8\xd2\x9f\xb8\x65\xcd\xba\xfa\x85\x80\x2e\x53\xcf\xff\x89\xc2\x1e\x39\x9f\x89\x80\x0f\x4e\x63\x3b\x46\x40\xac\x5d\xf3\x2a\x47\xa3\x79\xec\x6a\x0c\x3a\x1d\x42\x38\xd7\xbd\x12\x6e\x25\x5a\x40\xdd\x42\x85\x63\x53\x5f\x8b\xee\x86\xdf\x90\x8d\xb0\xac\xed\x5c\x79\xec\x9c\x7c\x96\xd1\xd9\xa8\xca\x73\x7a\xc0\x0e\xeb\xa8\xa4\x47\x03\xf2\xb7\x50\x1f\x43\xff\x6c\x34\x54\x1d\xc2\x2e\xbc\x6d\x54\x77\xfc\x77\x35\xf9\xb9\x17\x33\x35\xce\x88\x88\xf2\xad\x89\xc6\x47\xb7\x90\xfb\xc2\xc9\xb3\x39\xa9\xef\x96\xf2\x8f\x25\x32\x79\x63\x9f\x3d\xda\x98\xe1\xf9\x06\x49\xc2\xba\x07\xd6\xef\x69\xd6\x76\x11\x31\xe7\xaa\x1a\x5b\xd7\xf4\x51\xca\x15\x02\x18\xc8\x3b\xe0\x83\x71\x8f\xa1\xea\x0c\x6a\x72\xa6\x20\xc1\xae\xc8\x4d\x67\x43\x5d\x68\x57\x26\x29\x30\x94\x50\x21\xb0\xe1\xa8\x13\x98\x42\xc0\xe2\xeb\xe6\x42\xa7\x00\x49\x94\x58\xb0\x5a\x42\x10\xe3\x20\xdf\x1b\xd2\xb6\x34\xfb\x45\xb5\xa9\x17\x91\xff\x28\xbc\xd8\xfc\xf0\xc3\xd2\x86\xbd\xcc\x7e\xc4\x3f\x02\x01\x9b\x3a\x4c\x14\x3a\xf1\x64\x27\xfe\x1e\x11\x21\x92\xd1\xc9\x1b\x95\x73\xf2\xb6\x85\xac\xc7\xf6\xf0\x1e\x9c\x38\x7f\x03\xf0\x3e\xb3\x52\x93\xf0\xb8\x18\x90\x0a\x24\xb1\x8d\x6d\x68\xe7\x48\x77\x91\x7a\x49\x6e\x8a\x1b\x8a\x1a\x02\x90\x3a\x09\x66\x82\xae\xf7\xab\x0d\x3d\x93\xe5\x11\xbf\x98\xe8\x55\xe9\xa4\xe6\x89\x7c\x68\x39\xc7\x3b\x74\x70\xba\xcd\x99\x6d\x22\x67\x71\x2d\x19\xfa\x49\x7a\x64\x84\xfc\x53\x16\x64\x78\xc7\xe9\x86\x96\x69\x62\x58\x1f\x96\x35\x4b\xbd\xe1\xac\x65\x11\x03\x34\x6b\xa1\xfe\x81\x4e\x93\xf0\x18\xe4\xf9\x80\x0c\xc8\x9a\x25\x3f\xf1\x65\x1f\x91\xd4\xa8\xd2\xbd\x22\x86\x42\x70\x4a\xf2\x05\xdb\x46\x63\x81\x86\x1c\x88\x5e\x23\x7a\x1b\xce\x45\x3b\x50\x84\xb0\x97\x6e\x5a\x47\xa9\x7d\xf2\xe9\x54\x84\x3f\x50\x28\x3e\x75\xa2\x78\xee\xc0\x00\xf6\x11\x60\xc1\x8c\x3b\x07\xd4\x30\x03\xcc\x52\x12\xd1\xc2\x96\xa3\xf8\xe7\x56\x9b\x40\x08\x9d\x85\x06\x9e\x4d\x51\x24\x44\xc0\x0d\xfe\xd4\x43\x54\xb3\xc3\x49\x89\x63\x5f\x04\x06\x41\x34\x44\x95\x84\x91\xa1\x53\x77\x48\x9e\x4f\xba\x91\x43\xaa\x1d\xb1\x38\x01\xf4\xab\xc6\x7e\xd1\xc5\x00\xa6\xf6\x78\x58\xdb\x53\xb7\x19\xec\x9d\x86\x24\x8f\x82\x00\x1a\xfd\x53\xfe\xc0\x0e\x64\xcd\xda\x23\x19\x1d\x64\xea\xb4\xd1\x3d\x3d\x19\xb7\x6a\x20\x2d\x7a\x97\xe3\x78\xab\x2a\x99\x1a\xc4\x1d\x04\x83\x58\xa1\xfe\x59\x75\x16\xa4\x13\x2c\x42\x47\x48\x9c\xc0\x1c\xe7\x81\x5d\x3c\x0d\x28\xf3\x6c\x85\xa7\xf1\x0b\xa4\xaf\x66\x24\xe9\xeb\xab\xca\xe9\xd3\xd7\x7f\x5e\x26\x09\x51\xbc\x2a\xfd\xbc\xe9\x3e\xff\x58\x67\x3e\x50\x09\x8d\xa0\x90\x16\xa1\xb4\x06\x2d\x0c\x54\x9b\xf4\x48\x93\x7d\xec\x24\x98\x4e\xd1\x2b\xfb\xda\x2c\x35\x2a\xce\x10\x26\xa1\xcb\xcf\xda\x8f\x26\x77\x86\x0e\xb7\xd4\x0d\xb4\x38\xa7\x74\x76\xc1\x7d\x87\xd0\x03\x4e\x2d\xac\x89\x49\x66\xc4\xec\x72\x2e\xff\xa2\x1d\x7d\x55\xfe\xef\x96\x72\x89\xbd\x4b\x77\x02\xc3\x14\xe6\x28\xed\xd1\x1a\x97\x24\xc4\x5c\xda\xa4\x34\x69\x13\x0f\xf3\xc7\x84\x61\x25\x45\x18\x20\x69\xab\x21\x48\xa3\x18\xb5\xa4\x44\x6d\x04\x71\x50\xd1\xe2\x48\x2f\x1e\xc4\x78\x46\xd0\x7e\x2f\xfc\xfd\x76\xdd\x2c\xcc\x38\x67\x8d\xdc\xf0\xbd\x7c\xe8\xf2\xd8\xfd\x7a\xe8\xc0\xf9\xa7\x82\xa2\x00\x36\x08\x61\x71\xdd\xdf\x43\x05\xfd\x01\x6c\xcf\xd0\x32\x81\x1c\xd0\xa9\xdf\x0c\x9a\x3d\x43\xf3\xc4\x79\x16\x1d\xdb\x07\xcc\x9b\xdc\x24\xf1\x90\xd6\x73\xaf\x21\x6b\x72\xb0\x7d\x18\x90\x72\xcc\xaa\xd0\x78\xad\x83\x4a\x0e\x85\x4a\x1f\xcb\xd9\xc9\x59\x9d\x96\xed\xa6\x5c\x0d\x9c\x6b\xfc\x27\x08\x5e\xf8\xda\xb1\x36\x9a\xb3\xbf\x41\x7b\x02\x94\x52\x41\x6b\x27\x4f\x3c\x42\x42\xfc\x0d\x99\x15\xeb\x97\xd0\xf7\x93\x24\x01\x0a\x31\x7c\xff\x89\x07\x0d\x72\xc1\x27\x15\x7e\x3e\x2e\x45\xe2\xb2\x5d\x60\xb7\x47\xe1\x51\x16\x0e\xc8\xa5\x94\x86\x66\xec\xa4\x01\x8c\xc4\x5e\xa3\x41\x41\x11\x09\xae\xa7\x42\x57\x27\xc2\xd3\xf4\xe8\xba\x5b\x9a\x23\xf6\x0c\xa9\xa6\x9d\xba\xc1\x07\x04\x2b\x19\xdf\x63\x76\x3c\xe5\x05\xbe\x9f\x77\x71\x13\xea\xfb\x86\xfb\x77\x99\x2b\x79\x14\xbe\x20\xdc\xf7\x8f\xfd\x7b\x6b\x5d\xdf\xa5\x47\x50\xae\xb7\xd7\xf1\xbb\xca\x7e\xf9\x16\x92\xb3\x7c\x45\x8e\x83\xe5\x60\x9e\x04\xc9\xd9\x59\xe6\x6d\x5b\x0c\x73\x01\x92\xd0\x84\xfc\x16\x24\xf5\x70\x37\xd6\xec\x47\x72\x19\x7d\x41\xd4\xe5\x17\x73\x8e\xc3\x55\xc1\x19\xdf\x2c\xb5\x2e\x48\x94\x78\x3b\x80\x32\x49\xf6\x72\xed\xb4\x70\xf0\x75\x5a\x96\x98\xcd\x7f\xb3\x67\xaa\xfc\x47\xd1\x12\x1e\xca\x5a\x33\xde\xfb\x0b\xd9\x26\xaa\x99\x19\x94\xb6\x08\xc5\x07\xbf\x69\xde\xbc\x9b\x06\xe0\x55\x40\xa0\xe0\x8f\xfb\x9b\x7a\x2e\xba\x7f\x93\xdb\xe8\x3c\xde\xcc\xc1\x84\x87\xf9\xb9\x23\xbf\xf2\x73\x63\x55\x8b\xa3\x25\xf4\x47\x7c\x4a\xf4\x21\x73\xc1\x49\x48\x43\xf1\xc3\xf1\xfb\x83\x55\x60\x7f\xdc\x9f\x7a\x3c\x79\x04\xed\x11\xe8\x93\x64\xe9\x93\x90\x85\xe4\x93\xa5\x28\xf5\xc9\x52\xc3\xf8\xd8\xc8\xc9\x16\x0a\x44\xcb\xe1\x13\x4c\xd1\x9f\x4e\xb1\x22\x1f\x1b\x0f\x2f\xa6\xc7\x7d\x12\x39\x77\x3e\x69\xd3\xf6\xc6\x88\x95\x8f\xba\x7f\xf0\x64\x7f\x19\x1b\x05\xe8\x55\x84\xd7\xda\xca\x7f\xf0\x62\x78\xef\xf4\xfe\x7c\xd9\xe8\xdf\x1f\x59\x7c\xef\x8f\x9b\x69\xef\x8f\x34\x2e\x6e\xc5\x4e\xbc\x95\x19\xf7\xbe\xb5\x04\x69\xa0\x93\x52\x87\xe7\x4f\x33\xd6\xc5\xec\x54\x51\xcc\x19\x62\xbe\x91\x01\x4d\x0f\xde\xa2\x86\x81\x86\xca\x19\x6a\x2a\xc3\x41\x2b\x16\x90\x97\x06\x90\xfc\x44\xdd\xc8\x4f\xf5\x0e\x29\x87\x77\x5d\xcc\x58\x67\x68\xa0\xe1\x85\x2d\xf0\xfd\xcb\x63\x30\xa8\xd5\xc0\x77\x7d\x5c\x7a\x16\x0e\x09\xe6\x65\x0c\x6d\x93\x0a\x0f\x8f\x83\xce\x7a\xa4\x4b\x2a\x29\xbc\x39\x28\x92\x28\x92\xfa\xed\xcc\x06\x5e\x33\xfb\x4e\xf1\x38\x84\xb7\xf0\xe0\xbe\x63\xdd\xf5\x5d\x0e\xc9\xaa\x44\x5a\xc3\xbb\x6c\x3f\x1d\x94\x75\xf7\x09\xdb\xbb\x98\xed\xc7\xab\x2c\xd7\xa9\xb3\x2d\xcc\x63\x77\x90\x0e\x21\x29\xcf\x60\x4d\x69\x38\x25\xf6\xb2\x0c\xb3\x08\x10\x81\x13\x7f\xad\x98\x04\xeb\x09\xde\x7c\xf8\x25\x37\xc1\x99\x7c\x79\x3b\xff\x2f\x54\x5c\x02\xcc\xaa\x32\x98\x5f\x3d\xfa\xe0\x5d\x62\x95\xf3\x5d\x86\x4d\xf5\x1a\x56\x12\xb1\x82\x48\x47\xef\xac\x38\xb3\x20\x6b\x16\x32\xab\xef\xf9\xe2\xcb\x86\xe7\xac\xa1\x36\x19\xc5\x86\x38\x51\x5d\xd7\xc5\xcc\x20\x1f\x4a\x20\xe0\xb2\x37\xdd\x16\x69\x35\x1b\xca\x12\x0a\x71\x74\x36\xc4\xff\xda\x20\x2e\xad\x9d\xfc\x09\xe9\x13\x91\x9f\xba\xe6\x8b\xa7\xa3\x02\xed\x88\xaf\xdf\xb4\xc1\xb6\x05\x10\x3f\x09\x5e\x04\x43\x55\x5e\xd4\x77\xfe\xed\x93\x7c\x89\xcc\x8d\x37\xed\x43\x08\xc8\x88\x92\xd0\xe0\x73\x56\x0e\x2c\xe6\x8c\xe0\x97\x7e\x0a\xc7\xf3\xc9\x4b\x34\xfd\xdc\x16\xc8\xc1\x11\x7f\x4e\xf9\xa7\x2c\x83\x04\x0c\xde\x8e\x84\x55\xb2\x9e\x94\xe7\xf2\xf1\xa0\x26\xcb\xe7\xaa\x32\x7c\x38\x30\xf5\xa5\xc3\x13\xca\x32\x6a\x30\x8d\x49\xf7\x9d\xae\x23\x94\x5c\xce\xd3\xc7\x6a\x89\xcd\x08\xf9\xc2\xca\x3b\x39\x95\x30\x87\x38\xdb\x90\xa9\x13\x8c\xcc\x6f\x0f\x10\x95\x13\xfe\x8d\xf8\x68\x2f\xd7\x35\xa4\x68\x56\xa8\x45\xfa\x1d\xfc\xd1\x12\x83\x2e\xc8\x9f\x5f\x99\xdd\xd9\xe6\xe1\xef\x1f\x95\xd4\x3b\x3d\x9b\x26\x0c\xab\x29\x72\xb7\xd7\xdd\xb7\x0c\xdb\x57\xad\x93\x6b\xae\x54\xe5\xf1\xbc\xea\x53\x0a\x2f\xcc\xf9\xb3\x32\x2f\x41\xe3\xf9\xaa\x83\xd2\xc7\x5e\x0c\xbb\xa6\x90\x4c\xd9\x19\x18\x86\x80\xb9\x42\xb5\x16\xfb\xac\x16\x2e\xac\xbc\xca\x4f\x17\xe3\x15\x43\x95\x01\x2e\xef\xbe\x10\x99\xd1\xfe\x2b\x59\x91\xec\xd3\x88\x42\x78\xba\xd9\xfe\xca\x4c\xf6\x7a\x79\x0c\xc5\x49\x94\x7b\xc9\xba\x80\xf5\x51\x48\x01\x47\xaf\x6c\x1f\xf3\x5d\xa8\x1c\xf9\xb2\x17\xeb\x3f\xc1\x7b\x90\x02\x8a\xbd\x9e\xba\xd7\x9b\xe9\x28\x2f\x64\x66\xf6\xb7\xa3\xe3\x25\x95\x93\x83\xea\x38\xf0\xa3\x9e\x01\x78\x9b\x5a\xd9\x02\x0f\xd1\x49\x65\xae\x57\xda\xde\x1f\x6f\xd4\x40\xf6\x3d\x0d\x3f\xfd\x97\xd2\xd4\x5f\x36\x2d\x5f\x43\x08\xe6\x7e\xc5\x11\x4b\xad\x02\x08\x16\x54\x77\xf3\x02\x8d\xee\xfa\x53\x8a\x71\x36\xbd\x97\x6b\xf3\xee\x4b\x9c\x6f\xaa\xc7\xde\x50\xbb\xa2\x7c\x2f\x2f\xb7\x1c\x4f\xc9\xd8\x40\x96\x4a\x20\x7f\x94\x39\x4f\x8d\x19\x84\x96\xc7\x31\xf9\x75\xc6\x59\x06\xe7\xc4\x5f\xda\x86\xd4\xf0\xb9\x11\xcd\x21\x31\xd2\x9f\x3f\x59\x9e\xbc\x8f\x05\x71\x37\x3e\x04\x02\x87\xa2\xec\x2b\x85\xf6\x0c\xc8\xa2\x93\x10\xca\x9b\xbe\xb6\xbb\x09\x9f\xdf\x10\x55\x3e\x08\x2a\x77\x30\x9c\xfe\xde\xaf\x39\x87\xf2\x3b\x96\x1f\xff\x28\xca\x78\x55\x6f\x39\x17\xee\xb5\x05\xc7\x63\x8d\xce\x0b\x04\xbf\xfa\xc1\x74\x38\xdd\x8b\xb2\x5e\xee\x79\x71\x89\xa5\x7b\xa0\x8c\xdb\xf5\x91\x5f\xe6\xfa\xac\x21\xe3\xf1\x61\x57\x7b\xd9\x68\x34\xd0\xd7\x7d\xbd\xb3\xbe\x26\x20\x92\xa9\x5f\xc1\xf5\x74\xc9\x4f\x8b\x52\xda\x30\x9e\x11\x76\xdd\x92\x7c\x41\xe2\x7f\x48\xc3\xdb\x44\x8b\x3d\x11\x64\x3a\x77\x99\x6b\xc0\x1d\x27\xff\x88\x01\x96\x6e\xc9\x51\x25\xe2\x52\x9b\xc2\x4b\x79\xc1\xc0\xa5\x0e\x08\xa8\xff\x1a\xd0\x2f\xca\x15\x3a\x31\xc8\x04\xff\x10\x82\x79\xa3\x38\x44\xdc\x01\xcd\x66\xc3\xbc\xd7\x23\x3f\xfc\x9b\xb8\x10\x1a\xa0\xc8\x98\xeb\x68\xc1\xa2\xd7\x61\xb3\x48\x84\xf6\x13\xbf\xe2\x4c\x8a\x03\x03\x80\xf6\x12\x5b\x18\x22\x85\x4e\x17\x51\x00\xca\x2a\xfd\x51\xd8\x4b\xf4\xab\x54\xfa\x19\x2e\x36\x65\x48\x59\x44\x14\xd4\xd5\x44\x5d\x2a\x48\x3a\xfc\xce\xaa\xbf\xc2\x4b\xec\xf4\xd6\x01\xaa\x5c\xa1\x6c\xab\x97\x55\x57\x2e\x4e\x41\xce\xa2\x48\x39\xef\x0a\x52\xa7\xab\x3e\xd9\xf1\x5d\x55\x62\x3e\x55\xbc\xb8\xae\x49\xe1\xe5\x2a\x59\xbe\xcb\x75\xb1\xfc\x54\x05\x16\x35\x8f\xea\x16\x0e\x0c\xd7\xfc\xd1\x67\x70\xc1\x03\x48\x15\x9e\xf9\x0e\x3d\x31\x40\xd7\xbc\x99\x8f\x3b\x74\x68\xd0\x47\xe7\x41\x90\x7d\xf3\x05\x92\x5d\x9e\xae\x4a\x9c\xa6\x84\xaa\x4e\x0b\xd5\xc5\x1c\x9b\x7b\xd2\xb6\xa7\xcc\x57\xe2\x41\xfc\xaf\x6a\xa3\x61\xe2\x66\xc8\xdd\xe4\x7f\x85\xde\x24\xa0\x81\x0f\x2c\xbf\x7e\x39\xf0\x36\xf5\xa2\x78\x92\xbd\x27\x7d\x0c\x57\xde\x45\xae\x68\xc8\x6f\x9d\x54\x8f\x17\x06\x96\x85\x63\xeb\xe5\xac\xad\x7c\x76\x08\xf2\xe2\x4c\xcf\x2c\x46\xde\x79\x7e\xe4\xb8\x56\xb9\x9a\x4f\xf5\x02\x11\xae\x86\xd7\x4b\x66\xd1\x95\xa7\x66\x00\x5e\x59\xea\x38\x6e\xc4\x5f\x94\x5a\xb9\xd2\xad\xe0\x37\x43\xf2\xfb\x5c\xe9\x0c\x66\x4e\x17\xbf\x59\xd5\xcb\xd9\x86\xf3\x3a\x56\x62\x68\x80\xb3\x15\x60\x8d\x2a\x16\x34\x6c\xa3\x3c\x78\xf4\xc6\x61\x19\x5a\x39\x69\xa6\x2d\x70\x21\x6f\xc2\xe6\x0c\x54\xb1\x59\xd2\xfc\xb9\xf2\x9b\x47\x3f\xd3\x29\x75\xfc\x2b\x85\x2f\xf9\xf2\x09\x0d\x81\x64\x75\x3a\x55\xf7\xfc\x7e\xd6\x1f\x1f\xf9\x17\x6b\xb7\x6d\x0b\x1a\x60\x92\x01\xf8\x1c\x92\x5c\xf8\x6c\x9b\x74\x30\x3e\x83\xb8\xd2\xcd\x92\x75\xf2\xf2\x77\x0e\x25\x1b\x04\x7a\x4c\xa1\x74\x63\xb7\x2e\xe1\x94\xf7\x4f\x3d\xfb\x7c\x65\x76\x5d\xe7\x7d\x7c\x24\x68\xb3\xe3\x85\x66\xc2\x4d\x6a\x36\xb5\x63\xb6\xb1\xcb\xdd\xf8\xc9\xc1\xcf\x97\x04\xba\xc4\xa3\x16\x8e\x99\xe7\x8d\xac\x6b\x0a\x3c\xdc\x4f\x5f\x0f\x3b\xef\xa9\xd1\xb7\xdf\xd6\x85\xe8\xce\xee\xe1\xad\xb8\x16\x83\xa1\x45\xe1\xbc\xff\x3a\xe0\xba\x2f\x99\x61\x50\xbf\x19\xab\xc4\x60\x9c\xbe\xce\xd1\x71\xbb\xfc\x1d\x00\x09\xff\xbd\x2b\xa4\xb6\xcd\x51\xdf\xcd\x2b\xe4\xe4\x67\x8a\xf0\x03\x66\x3a\x12\xd0\xec\xfd\x7d\xec\x1f\xc7\x70\xe1\x9c\x2e\x90\x15\x97\xc9\x2f\x89\xce\x1c\x9a\x20\x03\x79\x58\x80\xf0\x1c\x47\x26\x26\xaf\x03\xad\x2a\xfb\x50\xc4\xb1\x89\xbe\x62\xa9\xa1\xb6\xc3\x1b\xbf\xaa\x44\x7d\x20\xa8\x63\x06\x78\x28\xbc\x54\xa9\xca\x54\x7e\x5d\x06\xc6\xf8\x4f\xff\x9c\x75\x6e\x83\xa3\x32\x35\xcf\x0b\x19\xa8\x3c\x77\x09\x21\x72\x83\x71\xcf\xe4\xd3\x3c\x03\xa7\x98\xde\xdb\x96\xbc\xd4\xae\x8e\x93\xfa\x80\xbc\x0b\x64\x91\x12\x6c\x3f\x45\xa1\xbc\x35\x69\x9d\x65\x89\x0b\x64\x05\xdd\x38\x8a\x1e\x43\x1b\x7d\xa8\x06\x99\x11\x1d\xcf\x0c\x9e\x41\x3e\xd3\x2c\x05\x2f\x08\xe7\x14\x70\xf0\x09\xeb\x37\xe9\xbc\xf4\xb6\xa0\x32\xce\x6a\x35\xf6\x2a\xc0\x45\x74\xb1\xc4\xac\x8d\x19\x44\x32\xf2\x81\xe3\xdf\xb0\x6b\x02\x85\x08\x03\x70\xfa\x61\x09\x2a\xba\x2a\x49\x04\x56\x9c\xd7\x2f\x71\x07\x7a\x3b\xf1\xb2\x5b\xd0\xbe\xc1\x41\x55\x1c\xae\x96\xd8\x6e\xc6\xcc\x87\x7d\xd0\xb9\xc3\x10\x61\x85\xf7\x83\xf2\xa9\xae\xaf\x13\x92\x37\xd5\x2c\x5e\xb9\xec\x4f\x50\x29\xfb\x4d\xec\x85\xa4\x9e\x66\xe7\x32\x5e\xca\xa3\xeb\x4e\x01\x18\x66\xda\xd9\x6b\x90\xc3\x64\x47\xda\x28\xbb\xe2\xb8\x5c\x43\x87\xd1\x9e\x06\xed\x46\xd5\xba\xcd\x8a\xf7\x53\x83\x01\x81\xfa\x4f\x08\xd5\x39\x04\xe2\x20\x5d\xcd\x4a\xea\x2a\xd4\xa3\x6b\x87\x47\x1b\x40\xd6\x8b\xdf\xbb\x02\x5f\x6d\xda\x56\x25\x68\x54\xa5\x4b\x54\x5b\xd8\xb0\x2b\xee\x60\x89\xcc\x31\x7b\xc1\x73\x2b\x4a\x63\xb6\xc9\xbb\x04\x25\x56\x3a\x3c\xa0\xc1\xb3\x85\xf6\x4e\xad\xee\xa6\x35\xc0\x79\x0d\xde\xce\x57\xa5\x3d\x66\xf6\x18\x6b\x38\xd5\x0d\x71\x79\xe7\x04\x39\x53\x48\xf2\xdc\x3e\x7e\x21\x80\x7a\x63\xf9\xd2\xd9\x97\x2a\x12\xa1\xf3\xa7\xec\xb1\x14\x8f\xc4\xb2\xc9\x67\xa8\x78\x2c\x29\xc4\x7d\x9e\xf7\xc8\xef\x12\xcc\x19\x7e\x99\x67\xf8\xad\xce\xa7\xd3\x23\x9d\xcf\x47\xe6\x66\x51\x92\x9c\x0d\x9e\x94\xc2\x35\x40\x06\x0e\x00\x76\x17\x4f\xaa\xec\x9d\xe5\xdf\xb3\x35\x1f\x99\x15\x67\xd1\xd5\x8b\x54\x61\x4a\x74\xa5\xe5\xa0\xfa\x49\x09\xb6\x58\x20\xfe\x67\x93\x1c\x2e\x50\x6e\x5f\xa3\x0d\x11\x75\xe5\x4f\x40\xa8\x28\x19\xa1\xe5\xc5\x55\x87\xb3\x55\x14\x4b\xab\x7a\x87\xe5\xf9\xa4\x25\x73\xc2\x36\x08\x31\xa1\x2c\x01\xa5\xa2\xb0\x6b\x00\x55\x32\x8f\xcf\x40\x3f\x45\xa1\x4e\x2d\x41\xf4\x47\x67\xe9\xef\x58\xe9\x3d\x9b\x72\x88\xf3\x20\x01\xcc\xf7\xaa\xda\x1b\xb2\xd9\x16\x1f\xcd\x7c\xff\x15\x0b\xba\xc1\xbf\xcf\x0b\xcd\x37\xd7\x1f\xcf\xf9\x88\x43\x0f\xac\xb4\x39\x82\x95\xc8\x53\x55\xd1\xc2\x01\xf1\x77\xe5\x15\x6a\x3e\x65\xb3\xa3\x6e\x41\x4a\x7f\xd8\xf0\x5d\x25\x22\x69\xb8\xb8\x8f\x0e\x1c\x25\x54\xb4\x42\x3a\xed\x4d\x51\xac\x39\xfa\xc8\xd9\x19\x1d\x98\x6c\x07\x81\xa1\x97\x64\x8a\x6c\x16\x7c\xa5\xd8\xb9\xb3\x2c\x71\x94\x26\x76\xd0\x21\x92\x42\xc9\xec\xeb\x5e\x42\x7b\xec\x92\xca\xdb\x6c\xd6\xc9\x47\x40\xe2\x41\x20\x2f\xd0\xe1\x0c\x34\x3c\xf3\x27\x9a\x50\x16\xad\xe0\x09\x5f\x37\x85\x7e\x14\x11\x7f\x62\x1e\xa1\x1e\xc4\x03\x7f\x09\xb8\x2d\x46\x0d\x00\x9d\xa7\xd9\x1b\x19\xa2\x8c\x7a\x3b\x79\xe3\xe3\xce\x5a\x7a\x38\xf3\xba\x8b\xac\xff\x44\xc3\xd0\x3e\x04\x28\x38\x5a\x9c\xdd\xef\x8c\x17\x9f\x97\xce\xdd\x6b\x67\x48\x7d\x42\xab\x88\x05\x3f\x70\x9b\x7c\xb3\x8c\xf4\x62\x43\xf6\x1b\xb9\x6c\xce\x3c\x30\x7c\xfe\x8c\x8c\x87\x33\x27\x24\xa2\x13\xf5\xea\xfe\x73\x12\x6f\xd7\xd9\xdf\x1b\xe3\x83\x5d\xbf\x68\x62\x07\xd8\x1f\xf0\x24\xb6\xd7\x06\x0e\xc5\x5d\x54\x34\xb6\x91\xa2\xd7\xb6\xb3\xf1\x7b\xef\x6b\xc7\xe7\x67\xb3\xf3\x44\x85\x4b\x48\x1b\xdd\x54\x42\x05\xa4\xd8\x86\x23\xcd\x02\x5d\x06\xe9\x88\x43\xc5\x89\x4e\x41\x24\xa7\xdb\xb8\x79\x35\xb3\xfb\x25\x5a\x74\xd3\x94\xc3\x7c\xd7\xff\x3d\x69\x2b\x64\x8b\x6e\xa7\xe6\xd6\xc1\x87\x7a\x7a\x2c\xf1\x35\x4d\xa2\x2a\xe2\x11\xc0\xed\x8f\xaa\x52\x65\x3a\x68\x3b\x2c\x6e\xcf\x50\x47\xb0\x95\xeb\xdb\x64\x90\xa2\xf3\x35\x94\xee\x90\x54\x22\xaf\x08\x40\xfe\x49\x2e\xad\x2e\x5c\xb1\x70\xc3\xba\xdc\xfc\x93\x47\x6a\x5a\x2e\xbe\xd1\xd5\x59\x37\xb7\x48\x80\x0f\x28\x78\xd4\x7c\xa3\xfc\x95\x53\x0a\xd1\x0c\x6e\xc4\x13\x58\x9a\xda\x1e\x16\xcf\x55\xc7\x12\x8f\xe4\x27\x0c\xe6\x12\x4b\x85\x28\xdf\xb1\x0f\x8d\x53\x52\x55\x73\xfe\xa9\x2b\x2d\x7a\x04\x0c\x63\x76\x60\x0f\xcb\x1d\x15\xda\x6e\x62\x51\xbf\x27\x9a\x8e\x5f\xd5\x53\x17\x2a\xa0\x67\x4f\x93\xa6\xc7\x44\x4b\x48\x52\x6a\x06\xc6\xb6\x6f\xd1\x97\x93\x3e\xd2\x4c\xfa\xf8\x34\x0f\xea\x4c\x7c\xdc\xce\x50\x2d\x6a\x05\x6c\x24\xac\x9e\x10\xb3\x27\x42\x28\x3b\x7f\xca\x5e\x2d\x1d\xc8\xcf\xbd\x08\x25\xa7\xe4\xdc\xd5\x7e\xbf\x58\x5c\xfc\x34\x24\x01\x28\x04\xad\x13\xfc\xd1\x44\xda\x46\x9e\xc3\xba\xc3\x77\x80\x2c\x20\x29\xa0\xf3\x8f\x19\x15\xf2\x1e\x0e\x24\xda\x84\x5c\x71\xf7\xcb\x19\x94\xf6\xd3\xca\x81\xde\x7a\x3d\x1d\x9c\x24\xea\x64\x7d\x83\xd4\x91\x0d\x5f\xa2\x8f\x30\x78\x4e\xf2\x82\x9d\xa1\x5b\x0f\x6e\x7e\x49\x3a\x85\x08\x94\x0d\xa3\x2a\xbd\xb0\xde\x7c\xa9\xb7\xf4\x9e\x28\x13\x72\x5a\xcf\x40\x6d\xb5\x34\x4d\xf1\xcc\xa7\x84\x69\x05\x71\x08\x4d\x85\x12\x94\x35\x07\x5e\x24\x2d\xae\x17\x28\xcc\x62\x70\x3d\xc3\xe3\x43\x59\x9d\x8f\xb4\x87\x3e\x54\x8b\xf9\xb8\xcf\xf4\xc0\xfa\x90\x8c\xc9\xe3\xfe\x4a\x10\xe9\xfe\x48\x72\xe5\x7e\x55\x2f\x48\xcb\x74\xdc\x9c\x05\x98\x69\x38\x28\x5e\x07\x30\xab\x4c\x92\x6e\x62\x48\xda\x61\x46\x8c\x52\xb4\x11\x0f\x27\xbb\xf4\xb8\x3d\x53\xf5\xb8\x7d\x69\xf5\xf0\xe8\x3b\xa9\x40\x31\x07\x0f\xd3\x21\xc4\x6a\x51\x7a\x48\xb1\x5a\x2d\x32\x0e\xd3\x23\xb8\xb8\x63\xef\x6c\x83\xd1\x4f\x73\x0a\x29\x09\x1e\x56\x41\xb4\x09\x25\x96\x3c\xbb\x8d\xed\x92\x7a\x62\x60\x2a\xd4\x9c\x36\x70\x77\x9d\xb1\x11\xe7\xca\x5b\x8f\x35\xf7\xef\xdf\xad\x38\x88\xd6\xe5\x51\x15\x4e\xe2\x6a\x82\x17\x17\x59\x91\x5f\xcd\x7f\x82\x5f\x80\x79\xcd\xc0\x52\x5e\x7a\x4a\x09\x6a\x86\x7f\x8d\x57\xca\xd7\x1c\x37\x64\xf3\xdc\xb8\x97\xa1\x69\x4c\x0d\x91\x26\x7c\xd4\xa1\x71\x3d\x00\x8f\x71\x68\x92\xe4\x33\x6c\xbb\x78\x50\x36\xfd\x92\xe2\x57\x24\xe2\x03\xa8\xba\xdd\x22\x99\xaa\x6e\x91\xfa\x13\xe7\x90\x9e\x45\xc3\x43\x7c\x30\x3c\xb4\xc8\x6b\xa5\x77\x4f\x56\xfa\xc5\xcb\x3f\x0a\xfb\x58\xa3\x2f\x3e\x18\x1f\xb4\xcd\x10\x99\x18\x82\x78\x86\x0f\xcc\xb0\xf9\x6f\x4a\x67\x61\xbd\xc2\x4b\x84\xda\x3a\xa0\x83\x0b\x2e\x3b\x35\x4f\x8f\x0a\x8b\xd8\x32\xcf\x63\x2a\x52\xf7\xc1\x24\x91\x8f\xb6\x84\x8e\x56\xa1\x2b\xef\x28\xf9\x19\xa5\x8e\xcd\xfd\x1c\x72\x50\xf0\x5e\xf2\x68\x0d\xb6\x98\x94\xfd\xc4\xae\x4a\xdf\xd6\x42\x80\xb3\x34\xd0\xf2\xc7\x0c\x78\x3f\x69\xfe\xc7\x9e\x13\xc1\x18\x59\x32\x4c\xfb\x1e\xd2\x64\x79\x27\xd1\x21\xc8\x19\x6f\x2e\x6f\x1f\x59\x1a\x36\x47\xf6\x4c\x7c\x4a\x8a\x21\xf4\x4a\x7b\xed\x69\x48\x60\x69\xb4\x69\xc5\x10\x7b\xc7\x00\xdd\x29\x65\xaa\x5c\x64\x33\xd8\xd4\x5d\x9a\x4a\xe1\x6d\x32\xdb\x71\x90\x60\xd3\xa0\x50\xd9\x23\xf7\x9c\xa1\x18\xb8\x65\x77\x19\xd4\x0f\x7b\xc5\x28\x1c\x41\x37\x69\xd3\xf8\xa5\x63\x7c\xce\xa1\x68\xab\x23\xe2\xf1\xe1\x04\x3d\x92\xf7\xad\x06\x7d\x7d\xe0\x48\x6f\xb6\x91\x04\xbd\xfb\xc2\x5e\xf9\xf0\x44\xfa\x2a\xb4\x85\x92\x9b\x9c\xa5\x56\x52\x69\xe9\xba\xc4\x3b\xe3\x50\x02\x4b\xd7\x3c\x4a\x73\xe9\x4a\x0f\x2f\xed\x61\xf4\x0e\x28\xdb\x94\x88\x11\x80\xcd\x8a\x6c\x41\x23\x74\xe8\x19\x78\x2f\x7e\x26\xee\x5a\x29\x95\x96\xc0\x63\x7d\xe8\x2e\xca\x36\x27\x81\xc8\x6b\x3f\x22\xcc\x02\x40\x72\x6b\x50\x30\xe5\xed\x20\xc5\x91\xd5\x1b\xee\x5e\xbf\x1d\x48\x05\x76\x84\x78\x26\xf4\x8b\xd8\x2f\xa4\xfe\xfb\x47\x93\xca\xa6\x0f\xe4\x2a\xfb\x9f\x13\x4d\xbb\x63\x16\xce\x3b\x85\x2f\x82\x01\x9c\x0b\x3a\x20\x00\x6f\xde\xad\x3d\xc8\x9c\xf6\x7b\xf7\x48\xd2\x3d\xb4\xf3\x76\xd9\xda\xfb\x3d\x49\x3c\x8a\xfa\x30\x07\x09\xd5\x76\xeb\x2b\x39\x84\x42\xfa\x49\x7e\x0d\x83\x3e\x0a\xc0\xc2\x7d\xc6\xca\x34\x36\xd4\x3d\xef\xf8\x8c\x78\xa0\x07\x61\xd0\x2a\xdb\xdd\x03\x25\x19\x29\x10\xe5\x52\xdb\xe5\xc8\x14\xd8\x39\x22\x2b\x17\x68\x8b\x13\x21\xb3\x9a\x2a\x36\x58\x86\x39\x03\x78\x19\x52\x30\x1e\xfe\x7b\x0a\x95\x10\xb1\x12\x37\x82\x01\xaf\xaa\xd2\x40\x77\x4f\xe7\xa1\x0e\x0d\xb2\x74\xf2\x3b\xb9\x53\x8d\x1b\x04\xbd\x14\xa4\xa0\x5a\x4e\x24\x09\x9b\xba\x37\x21\xa9\x9d\xd3\x2b\x03\x08\x02\xf1\x1b\x80\x1d\x75\x85\xd0\x4e\x0d\x57\x03\x10\xcf\xbb\xc8\x55\xba\xbb\x0a\x82\x8e\x6a\x3f\x7e\xc2\x51\xcf\x6a\xd9\x98\x3d\xe4\x7f\xa1\x50\x85\x90\x17\xe9\x2a\x99\xf9\xf8\xf5\x56\xbc\x2f\x12\x28\x5a\xb2\xf4\xa4\xf2\xa5\x6a\x23\xf1\x65\x21\xb0\xc9\x32\xff\x99\x3e\x6a\xd2\x06\xff\xb9\x15\x02\x49\x29\xaa\xe0\x2c\x29\xa4\x6f\x77\x68\x0d\x78\x53\x35\xd4\x17\xef\x05\xf7\x72\x86\x07\x72\x2f\xdb\x9d\xb9\x8a\xb7\x97\x46\xa1\xb1\x17\xd9\xc5\x7b\x51\x06\xd1\x8e\xf5\xcb\x10\x8d\xda\xf8\x86\x68\x8d\x5a\x71\xa9\x94\xa0\x0d\xe4\xa7\x20\x4e\x45\xfc\xbc\x79\x30\x48\x5b\x64\xe9\xdb\x86\x6c\x5e\x43\x21\x2a\x55\x32\x52\x7f\x99\xc9\xbe\xa3\x13\x96\xb7\x01\xac\x9c\xad\x12\x08\x21\x3f\xe5\xfa\xdf\xa5\x1e\x04\x12\x80\xc8\xad\xdb\xcd\xcc\x77\x0f\x1a\x34\xaa\x96\xb2\x4b\xf8\x68\xf6\xd8\x60\x7f\xb6\x20\x53\x98\x78\xa8\x58\x42\x77\xcc\x21\xa5\x7f\x94\xaf\x43\x52\x63\x40\x2b\x17\xb4\x1c\xc3\x3f\xe6\xd8\xa7\x39\xbb\xe7\x60\x73\xe4\xda\x99\x56\x7a\x85\x56\xd4\xa1\x06\x91\x0f\xc9\x3b\xa3\x3f\xbd\x58\x86\xc2\x93\x9d\xaf\x48\xd3\x6a\x8b\xd0\x00\x83\xdb\xa7\xe7\x14\x68\xa7\xde\x01\xef\xd3\x70\x92\x03\x0c\x8e\xfb\xd6\x88\x6c\x44\x91\x52\xbc\x19\x59\xf4\x7d\xef\x31\x61\x31\x40\x49\x36\xe6\x8d\xec\x59\xca\x5b\x45\xf4\xe8\x7b\xd6\xd0\xb6\x5b\x87\xcf\x8a\x88\xa2\x6e\x87\xe4\x2e\x4f\x91\x8a\x8f\xe8\x7b\x52\x86\x96\x01\xda\x62\x7b\xb2\x4f\x86\x72\x4b\x2f\x49\xaf\x52\x84\x8a\x72\x4e\xaf\x06\xa4\xc9\x74\x6b\xdd\x10\xfa\x54\x14\x48\x4b\x97\xbc\x81\xbb\x33\x68\x27\x21\xed\x09\xc3\x17\xe9\x1b\x4d\x99\xea\xa4\xd5\x4d\x8d\x2a\xbf\x59\xa7\x41\x91\xd2\x94\x3d\x5a\x5e\xc1\xf5\xff\x1c\xed\x2d\x6a\x0c\x92\x53\xe4\xf4\xdb\xc5\x50\xef\xe2\x53\xda\x31\xdc\x87\x50\x08\x76\x91\xce\x68\x87\xf6\x2a\xcb\x45\xfa\x4f\x2e\x47\x35\x11\x24\xe5\x06\xed\x52\x6f\x4b\x8f\x8b\xdf\x91\x59\xe4\x58\xc5\xa2\x30\x58\x8a\xf6\x8d\x6c\x76\x96\xe8\x43\xde\x29\x36\xa4\xc8\x35\x51\x62\x2c\xe9\xd3\x4f\xda\x8c\xb7\x94\xfa\xc5\xe7\xaf\xd0\xb7\xd2\x2b\x45\x0a\x53\x88\x64\x71\xca\x5e\x15\x78\x5b\xbf\x85\xd3\x90\xfa\x4d\xbe\x5c\x53\xdf\xec\x85\xea\x2d\xaf\xbd\x4d\x1e\x96\x50\x6d\xa9\xb7\x47\x5d\xfb\xf1\x18\x59\x38\x64\x79\x2e\x5e\xf3\xf4\x56\xd1\x6b\x6c\x81\x97\x3a\x07\x14\xfb\x52\x75\x6e\x31\x8e\xb7\x66\x32\x1f\xfe\xb9\x40\x23\xcb\xdf\x55\x0d\xfe\x63\x9f\xb7\x67\x27\xfc\x74\x32\x10\x49\x67\x55\x3a\x0e\x99\x1e\xa1\x03\xf3\xe3\x66\xec\x82\x75\x73\x95\xd3\xc7\xba\x9f\xd2\xb3\xda\xf5\xd5\xd4\xad\x8e\xde\x90\xea\xc6\x60\x58\x33\x98\xe7\xea\xfe\xf4\xba\x9c\xdf\xfa\xf6\x6f\xdc\x20\x57\xd8\xaa\x22\x9e\xaa\xac\x8a\x2a\x27\xa1\xf5\xde\xff\xf8\x9b\x21\x96\x54\x0c\x8e\x49\x86\x97\x75\xe9\x74\x55\x9b\x15\xbe\xb1\x08\x19\xae\x27\x1c\xf9\xbd\x23\x8a\x6f\x31\x14\xbe\x62\xce\x1f\xeb\x02\x20\xba\xcc\x8a\x76\xaf\xc3\x46\xa6\x52\xf0\xc9\xf8\xf7\x05\x97\xf1\x93\xca\x00\x75\xa0\x6b\xbc\xf6\xcc\x77\xa9\x1d\xa2\x5a\xf5\x3d\xd5\xc4\x20\xb0\xed\x96\x8e\x9b\xe7\x19\xd3\x4c\x36\x58\xbf\x2c\x37\x9b\x95\x90\x4b\xd0\x36\xa8\xac\xb3\xc1\x1b\xce\x1e\x72\x73\xc2\x60\x4a\x6a\x41\x79\x2b\xd4\xb6\xcc\xc2\xf1\x40\x9d\xad\x6a\x2d\x6e\xa3\x90\x91\xd7\x1f\x22\x5c\x54\xce\xaa\xc7\x94\x68\x0c\x6e\x48\x5f\x4d\x02\xdc\xd1\x41\xd3\x13\xa8\x7c\x8b\x62\x3d\x37\x0c\x2a\x21\x83\x55\xf2\xcb\xbf\x10\x70\x13\x41\x92\x93\xd0\xbf\xa7\x0d\x7c\xcb\x4d\x6a\x4c\x5b\xa9\x68\x0b\x69\xa6\xfe\xc3\xfc\x6e\xda\x5a\x3d\x0d\x5d\x43\x6d\x1a\xb7\x65\x44\x0e\xf0\xc0\x17\x07\xbd\x4d\x0b\x5b\x10\xdc\x8a\xc6\x1c\xcc\xfa\x5b\x8b\xc5\x42\xce\xa7\x57\xdc\x86\xd9\xcb\x4b\x32\xe9\x62\xdc\x69\x40\x47\x96\xd0\xe8\x2a\x74\x8e\x6d\x61\x7d\x6f\x8c\xaa\x40\x82\x1e\xfb\x08\x43\x21\xad\xb4\x31\x20\xd8\x8a\x21\xce\x83\x5a\x73\x7c\x40\x7b\x70\x33\x66\x03\x8f\x94\x37\x4b\x43\x63\x0b\x80\xdd\x12\xe3\x9d\xb7\x14\x32\x5f\x20\x5c\x63\xf7\x89\x4c\x44\xbd\xc2\x44\x2f\xed\x96\x1a\xa9\xe3\x06\xc3\x96\xcb\x75\x1e\x5f\xe3\x5f\x05\x8c\xb0\xc2\x1f\x3c\xb9\xce\xb3\x29\xfd\x6f\x6b\x91\xf3\x5b\xea\xd0\xd9\xac\x9f\x23\x31\x77\x72\x85\x9a\x9b\xab\x5d\xbc\xd3\xb3\x5c\x6f\xfa\x1c\x20\xea\xf5\xf1\x12\xec\xed\x12\xcb\xb8\x19\xa9\x84\x52\xf2\x0e\x80\x14\xb9\x00\xa0\x40\xc6\xfd\x4b\xf0\x5c\x29\xe5\xef\xb2\x60\x3e\xf6\x1a\x1a\x29\xa5\x62\xc6\x30\xcf\xbf\xe1\x05\x08\x4a\x58\xe3\xde\x44\x60\x03\x39\x5b\x69\x88\xdc\x41\x35\x6b\x28\x49\x64\x0c\xcb\x25\x5b\xfe\xd7\xb0\x9c\x30\xd0\x0e\x9b\x75\x26\x68\x29\xe8\x80\xd0\xfa\xb9\x75\x1a\x30\x43\x52\xb6\xe8\x6e\x6b\x3c\xeb\x3d\xb0\xb7\x76\xc0\x3d\xc8\x11\x54\x2c\xb2\x6d\xcc\xa1\xf4\xf5\xe5\x27\xb2\x56\xad\x40\xac\xf5\x5e\xb8\x20\x8d\xee\x83\x2a\x2a\x35\x46\xb6\x55\x1e\x87\xd5\xdd\x04\x5e\x49\x52\x2c\xad\xf8\x26\xff\xa8\x8f\xcd\x44\xa1\xc5\x75\x14\x1d\x3b\x29\x59\x1e\x6d\x43\x6f\xa1\x1e\xd4\xc0\x01\x0b\x14\xff\x55\xcf\x10\x3a\xb3\x31\xb1\xea\xc2\xb0\xd6\x6a\xa0\x09\x71\x17\x1f\x6d\x51\x19\xc6\x85\xc6\x4a\x6d\x90\x00\x4e\x2d\x5e\x7a\xfb\xfb\x9b\x29\xe9\xff\x43\x88\x6e\xd5\x0d\xce\xe4\x38\x55\x08\x8b\xb9\x7c\x9c\x23\x8a\xd3\xb8\xa8\xd8\x9c\x6e\x9d\x1e\x89\xce\xab\x50\x0d\x55\x97\xaa\xd1\x61\xad\xcf\x78\xc6\xe5\x94\xfa\x4b\x05\x5d\xbc\xa4\xd5\xe6\x50\xee\xaa\x60\x6b\xe4\xf5\x42\x8d\x8d\x53\xa2\x35\xf2\x86\x1d\xa8\xec\x59\xfa\xec\x6d\x45\x62\x3a\xe5\xb5\xdc\xa1\x08\x29\x32\x32\xd4\x03\x49\x9f\xcb\xe9\xdb\x2e\x66\x64\xdb\xc7\x86\xb1\xf0\x22\x94\x3b\xc8\xe9\x3d\xb0\x02\x4b\x2d\x9c\x72\x84\xce\xe4\x5a\x2a\x15\xf8\x0d\x70\xc8\x35\x7b\xe2\xca\x02\x3c\x62\x83\xfd\x13\x0a\x64\x92\x46\x5b\x43\x23\xac\x49\x8b\xd5\x8f\x40\x69\x72\x63\xfc\xa0\x0d\x68\x40\x86\x72\x98\x8d\x24\x84\x60\xda\x97\xda\xd9\x33\x64\xc3\x16\x49\x99\xd9\xdd\xf4\x7c\x0a\x05\xd2\x56\xf2\xbe\xc4\x86\xc3\xd0\xf3\x2a\x03\x17\x8f\x3c\xbf\x5a\x02\x70\xee\x22\xd7\x4e\x49\x18\xe5\xaf\xc4\xbc\xde\x27\x0b\x89\x7c\xc1\xed\xeb\xf5\xc9\x4d\x39\xeb\x54\xb5\x6c\x7a\xa8\x81\x73\x85\x9a\x2a\x9b\xb7\x7d\x98\x7a\xa5\x88\x16\x39\x24\x46\xe6\xaa\xae\x14\xcc\x70\xcc\x45\x9c\xb5\x31\xbd\x80\x3b\x85\x24\x7d\xab\x13\x93\xeb\x04\xc8\xe7\xae\x84\x24\xb2\x43\x3e\x0c\x4d\x68\x20\x3e\x62\x74\x5f\xda\x53\xaf\x38\x8a\xbf\xda\x26\xdd\x1c\x18\xf4\x24\x3e\x16\x9c\x08\xae\x3a\xa6\x6a\xe0\x41\xf3\xbd\x21\x55\x82\x02\x58\x88\x28\x1e\x42\xea\x0c\x3c\xfe\xca\x1d\x5d\x73\x5b\x98\x58\xf3\x7c\xa9\xc1\x60\x89\x28\x54\xc7\x42\xfe\xc7\x06\xc7\x22\xf9\x20\x84\xde\x38\xe8\x2f\x26\x86\x3b\xf0\x72\x6f\x51\x99\x6b\xef\xe4\x23\x44\x39\x94\x89\x5c\x11\xec\x2d\xa5\xaf\x25\x4b\x58\x2b\xa4\xbf\x96\xf4\x0a\xe9\xaf\xa7\x7d\xe5\x4d\x25\x6c\xd3\xeb\xec\x9f\xb1\x2b\xc7\x45\x9e\x7a\xe3\x7d\x59\xde\x36\x2a\x49\xd2\xac\x80\x42\xd9\xd1\x74\xd0\xf0\x81\x2c\xd8\xad\x4f\xbf\x87\xef\xa0\xb4\x8d\x26\xd4\x35\xfa\x92\x34\xef\xcc\x1e\x1d\xe3\xf3\xd6\x7e\x50\x3a\x85\xab\x7e\xfd\x50\xa7\x5b\xef\xb9\x38\xe6\x60\x69\xaa\x61\x55\x9a\xb8\x84\x29\x8e\xa0\x6b\xce\x35\xc3\x42\x49\x0c\x43\x45\x08\x8c\xb9\xe9\x17\xd8\x5a\x61\x53\x10\x13\xfb\x16\x25\xc6\xd8\x40\x00\xd5\xeb\xf5\xbd\x8b\x83\xeb\xd2\x18\x80\x75\x15\xad\xa5\x01\x51\xfc\xaf\x47\x34\x4c\x08\xa5\xa1\xe3\x0a\xf4\xd3\x28\x43\x36\x5c\x08\xa4\x21\x84\x83\x07\x4b\x7b\xd8\x4a\x6d\xde\x8d\x25\xd2\x36\x0a\x19\x74\x21\x66\x16\x12\x53\x1f\x89\x17\xa6\x7f\x91\xc6\xb6\xa6\x7b\x09\x31\x31\x9b\x19\x95\xd4\x94\xcc\x42\xa8\x2c\x6e\xd8\xec\xb4\x10\x0a\x83\x9c\x59\xfb\x3f\xf5\xfe\x92\xbc\x29\x50\x36\xe3\x6c\x7a\x45\xf2\xa4\x14\xb7\x6c\x38\xe3\x39\xce\x10\x0f\xc3\xc2\xa4\xbb\x06\xa1\x61\x56\x34\x2c\x3b\x97\x83\x1e\x2a\x74\x52\x34\xd5\x06\xd6\xd4\x10\xba\x65\xf7\xa0\xbb\x39\x14\x0b\xb0\x46\x42\x27\x72\x05\x42\x0f\x4d\x12\x6a\x47\x0e\xdd\xb2\xdc\xc4\xcc\x3c\xb9\x48\x34\x37\x2e\x68\xc6\x77\x07\x4e\xfe\x68\x80\x69\xfb\xde\xf9\x4a\x82\x09\x19\xd8\xda\x40\x44\xa0\x1a\x4c\xda\xa2\x6f\x49\x1b\x1c\x73\xbc\xd0\x56\x43\xec\x2c\xe4\xcc\x7e\xe2\xa1\x69\x7b\xa0\xa9\xb0\x8a\xdb\xa4\x47\xb8\x85\xf2\xd7\xf6\x1b\xde\x52\x48\x19\x82\x13\x52\xf7\x1b\x7e\xfb\x35\xad\x0c\x57\x59\x11\xef\xce\xbb\x58\xe2\x51\x35\x0d\xb0\xa8\xb1\x9a\x50\xfa\x29\xf2\x00\x4b\xbb\xd2\xd0\xa4\x9e\x1d\x3a\xd0\xf3\xaf\xa6\x5e\x69\xbe\xb4\xa7\x34\x6e\x10\x86\xb0\x67\xc6\x4d\xad\xe9\xf1\xe7\xb6\x1e\xd4\xeb\x4b\x0f\x78\x27\x79\x68\x39\xd5\x6c\x8a\x88\x0b\x5d\x32\xad\x34\xf9\xb4\x29\x94\xd7\xe6\x25\x04\xeb\x38\xd8\xa6\x09\x6b\x67\xdc\x33\xed\x66\x12\xf2\x79\x4c\x5b\x68\x9f\x4d\x21\xa8\x36\x65\x1b\x4c\x79\xfb\xbf\xbc\x30\x60\x44\x29\xf3\xd8\x88\xdf\x5a\xa1\x94\xa3\x87\x37\x0c\xea\x5b\x10\x24\x24\xe6\x21\x9b\xa0\x6d\x3f\xea\x01\xdb\x5a\x83\xc2\x0e\xab\x2e\x71\x2b\xfd\x73\x0b\xa9\x46\xc5\x87\x58\x69\x56\x87\xa7\x6e\x01\xe6\x87\xd6\xc1\xb0\x91\xd8\x34\x30\xd6\xe8\x53\xeb\x67\x91\x26\x1a\x9c\xee\x22\x71\xc0\x9e\x94\x50\xc4\x3d\xe4\xca\x54\x51\xeb\x20\x3a\x1e\xd2\x75\x1a\xce\x68\x8e\x9b\x3d\xc2\xed\xe5\xd3\x4b\x8d\xed\x22\x71\x34\x58\x3a\xc5\xc5\xb7\xc8\xfe\xb6\x12\xfc\x25\x8e\x38\xb9\x59\xee\xe0\xfe\xc4\x6a\x6b\xf8\xc3\xa1\xe8\x76\x7a\xc9\x06\xb1\xdc\x90\xd8\xa2\xf4\xd1\xed\x02\xe4\x22\xf3\x5a\xcc\xd8\x4d\x92\x6b\x1b\xf8\xcb\x7e\x0e\xc7\xd9\x72\x77\xce\xeb\xb7\xd4\x2f\x5b\x32\x74\x18\xa5\x9b\x04\xe2\xa6\xe8\x77\x20\xd7\x36\x1f\xb9\xc1\xa4\xbd\x0a\x4d\x5d\xea\x19\x0a\x6b\x48\x7e\x95\x30\x95\x99\xc3\xd2\x66\xc3\x7a\x32\xe5\xc2\x2a\xd3\xc1\x16\xb0\x22\xd1\xc6\x5e\x14\x3e\x65\xe5\x49\x49\xa6\x5a\xd9\xc4\xa0\xef\x76\x5e\x8c\x3f\x02\xae\x5d\x3c\x19\x08\xbf\xc5\x92\xe1\x52\xb9\x64\x8b\xf2\xdc\x54\xc5\x96\x00\x63\xb0\xcd\x1f\x97\x6a\x13\xb7\x8e\xd5\xc8\xaa\x06\x42\xfc\x16\x47\x83\xc4\xbf\x17\xae\xbe\xb1\x26\xfd\x93\xb6\x2c\xce\xe0\x95\x05\x47\x11\xab\x6d\xb6\x24\x47\x11\xa0\xb8\x5a\x89\xe7\x80\xd8\x74\x96\x9b\x76\xfc\xe6\xd3\x70\x45\x85\xbe\x5b\x5e\xb9\x6e\xe2\x98\x1a\x52\x91\xdc\xb5\x94\x10\xeb\x2b\xf9\x06\xd9\x6c\x26\x3e\xdb\x69\xb2\x2c\x2b\xf8\x42\xf8\xf6\x4a\x08\x0c\xc2\x80\x59\x4a\x48\xa8\x7d\x38\x7f\x37\x10\x22\x6a\x6f\x7f\x4e\xf9\xee\x54\x3d\x4c\xa9\xa9\xf7\x95\xcf\x2d\xe4\xd3\x90\xb1\x59\xc8\xf9\x66\xf7\x4f\x19\x2c\xa4\x27\x53\x4d\x0b\xa4\x79\x89\x80\xdd\xc4\x02\xb2\x11\xfe\x6b\xa3\x99\xb7\xe4\x95\xba\x52\x0b\x98\x5a\x37\x01\x16\x12\x21\xcb\x25\x58\x1a\x16\x04\x6a\x44\x75\x4a\x13\x48\x2b\x9d\x6e\x32\xcf\xab\xd6\x08\x97\x1c\xba\x38\xe0\x14\x1d\x78\x01\x2c\x46\x89\xea\xc2\x36\x34\x59\x01\xbb\xb6\x62\xaf\x16\x1c\x70\x85\x12\xd8\x2b\x49\xb9\xeb\x0e\x9d\x39\x9b\xc3\xfb\xf2\x13\x18\x92\xdd\xd1\x0c\x25\x34\xe9\x72\x9d\x73\xfc\xee\x14\xb5\x24\x84\xcf\xb0\xe4\xe3\x35\xc3\x98\xa8\x16\x83\x01\x8f\xa9\x60\x4b\x62\x38\x8d\x95\x76\x6e\x5d\x6d\x57\x1c\x2b\x44\xd0\xa8\x3b\xb6\x9d\x4a\xba\x70\xb9\x33\x55\x65\xab\xd2\x5e\x8b\x2c\x7d\xe4\xd1\xe8\x03\x45\x66\x8c\x7a\x72\x60\x59\xa7\x80\x11\x2b\xe4\x58\x13\x9a\x45\xc4\xa5\x74\x09\xe9\x49\x7a\xaa\x35\x09\x36\x21\x98\x16\xa5\xb4\xdd\xd6\x90\xa1\xd3\xcc\xd0\xd7\x24\x04\x10\x8d\xc0\x4b\x78\x1e\x81\xb4\xca\xca\xd9\x04\xd6\xf4\xe4\x26\x29\xf9\xa5\xe9\x77\xd1\x20\x75\x5d\xbc\xfb\xf7\xb7\x97\xfa\x7a\x4a\xc1\x0d\xfc\x56\xbb\xa6\xcf\x2e\x75\xb6\x09\x70\x5c\x86\xc0\x59\xf2\xd2\x7b\x52\x2b\x3c\xe8\xfd\x79\x1f\x1f\x37\x5a\x9e\x3f\x5b\xca\xa0\x96\xd4\x9f\xf7\x6e\x63\xa4\x83\x45\x12\x5f\xf7\xc2\xf5\x2a\x07\x5e\xce\x2a\x78\x99\x50\x46\x23\x43\x1e\xc4\xc5\x24\x2d\x56\x9b\xf8\xd0\x51\xd7\xd8\xc7\x78\x8d\xe7\x21\x22\x30\x03\x48\x56\x12\xdc\x38\x5f\x75\x09\x31\x9e\x2c\x5d\x75\x64\xb5\x0f\x4a\xb5\x5b\xd9\x06\xee\x67\xc4\x63\x3f\xeb\x57\xe2\x63\x55\xda\x39\xcf\xca\xe5\x02\x17\x10\xcb\xa1\xc0\x75\x99\x71\xc6\x06\xfa\xac\xe2\x09\x86\x44\x98\x46\x7f\x68\x84\x29\x19\xf7\x59\x19\x6e\x63\x65\x27\x41\x2e\xc4\xd2\xf3\xa8\x06\x28\x62\x54\xb7\x0f\x37\x37\x69\x54\x3f\xab\xbb\x24\xad\xf0\x07\x09\x46\x55\x9e\x62\xe1\x82\x0b\xc0\xf3\x27\x51\xe6\x21\x54\xcf\x3a\xa9\x0e\xf9\x54\x3c\x87\x41\x91\x55\x43\x1f\x8c\xea\x45\xb5\x97\x14\x5a\x3f\xcf\x91\xd9\xfc\xac\x5d\x1c\xd6\xd1\xe5\xf4\x04\x91\x8a\x3c\xa9\x4f\x38\xed\xfc\x01\x6e\xc9\x5e\x2d\xe9\xd9\x9e\xf2\x7a\x3d\x97\x5b\x1c\x4c\x50\xd5\xd6\x65\x97\xf6\x1a\x96\x62\xf3\x53\xc9\x84\xf9\x37\xa8\x54\xc2\xe7\xa2\xb8\x37\x03\xeb\x53\xa0\x6c\xa1\xdf\xc4\x0e\x8a\x22\x51\xa1\x10\x49\x3c\x8e\x71\x8d\xdc\xb7\x73\x25\x29\x84\x9d\x3e\x91\x7f\x82\x2f\x56\x3a\x5f\xa0\x90\xd0\x3a\xda\xb3\xc0\x99\xae\xba\x16\xc6\xdb\xa3\xd4\xf9\x0c\xf1\x6c\x70\x41\xc4\x51\x5b\x24\x57\x19\xdc\x6e\xbd\x63\x48\xba\x7c\x02\x48\x56\xaf\x80\x38\x8c\x3b\x97\x2b\x4a\x5e\x01\x09\xd0\x1f\x5d\xc3\x06\x19\x72\xfd\x02\x26\x1e\x47\x1a\x95\x27\x08\x64\x79\xaa\x1c\x72\x6b\xa5\xe9\xc6\xcd\x69\xf1\x1e\xe0\x99\xad\x71\x7a\x79\x86\x06\x5e\x16\x9f\xdf\x33\x1c\x02\xcf\xc6\x7c\x88\x75\x0a\xc5\xe1\x3c\x3d\x11\x96\x0d\x32\x4b\x48\x0d\x41\xe3\xd2\x2b\xab\xeb\x6d\xdd\x17\xe3\xbe\x9e\x11\x55\xf1\xcc\x5b\xd3\xc8\x7e\x86\x0e\x35\xd8\xbd\xbe\xc8\x47\x66\xd3\xb3\xa1\x46\xcf\x0f\xf9\x0f\x27\x41\x3e\x9a\xfe\xd8\xc2\x49\xcd\x13\x53\xf7\x38\x90\x6a\x7a\x08\xd3\xa0\xde\x57\x2e\x6c\x09\x79\xe2\x6f\x74\x58\xe2\x9c\xea\x99\x3e\x71\x3b\x89\x92\x37\x4f\x9b\x87\x4b\x5e\xea\x69\xf3\xa7\xae\x36\x29\xb2\x0b\x8c\x3e\x52\xc8\xf3\xc5\x30\x82\xfd\xa0\xc1\xf9\x84\x2b\x58\x82\x6e\xc8\xca\x1c\xe3\x87\xea\x2d\x9f\x29\xd4\xd4\xa4\x22\xf9\x6c\xac\x87\x4f\x10\xd9\x35\x8d\xb0\x7d\x9f\x19\x76\xf7\xc4\x04\xc6\x5f\x88\x4d\x37\x98\xf1\xfe\x24\x9d\x1c\x51\x6a\xea\x66\xcb\xcd\xd3\x70\xf9\xd7\xca\xdd\x3e\x60\xbe\x0f\x9b\x0b\x82\x08\x2c\x7e\xe4\x81\xc7\xcf\x54\xfc\xeb\x4a\xb1\xe2\xfb\x4c\xad\xb9\x2b\xb5\x1c\x09\x1e\xd5\x4b\xce\xf2\x51\x52\xa5\x8b\x2a\x63\xde\x2a\x0c\xfb\xe4\xe7\x71\x33\x2a\xf8\x71\xcb\x8c\x7e\x20\x7c\x4c\xe7\x99\x78\x1a\x2d\xfa\x3e\xaa\x56\xf8\x1f\x15\xb6\x2d\xd5\x12\x1f\x35\x7a\xbb\x87\x75\x52\x6e\xd7\x3c\xaa\x77\x28\x8f\x3a\x6f\xbe\x58\x48\x81\x32\xfe\x67\xa8\x85\xc7\x3a\xe9\xb6\x23\x7e\xcd\x8f\xb2\x35\x51\xf7\x07\x3a\x4d\xd6\xae\x44\x86\xe4\xc3\x99\xa4\x2e\x22\x2d\xc5\x3f\x82\x53\xd8\x41\xfe\x8f\x6a\x66\xc1\xeb\xfd\x80\x7f\x88\x15\x32\x03\xc4\xf5\x01\x48\xde\xf9\x48\x5f\x5f\xce\x7b\x24\x90\xe5\x39\x90\xd5\x61\xf3\xcb\x2f\x26\x00\x54\x30\xb3\x47\xcf\x75\x9f\x87\xdd\x2d\x43\x51\x1e\xe9\xe9\x6a\x8e\x8f\x04\x0d\x4b\x52\x78\x3c\x6c\xd8\xec\x28\x1f\xfa\xe0\xdc\xb6\x7c\x13\xcc\x32\x4a\x95\xbd\x13\xa5\xff\x6d\x2c\x62\xd0\x45\xb9\x90\xe4\x01\x70\x1e\x29\x8b\x4b\xa1\x9c\x92\x1f\x43\x44\x21\xbd\x03\x98\x1a\xa1\x22\x25\xfc\x4f\x2e\x88\xa6\x10\x0e\xe4\x22\x4e\x12\x37\x9b\xf2\x24\xb6\x4d\xcf\xbb\x3c\x79\x72\xd4\xdd\xbf\xb5\x02\x07\x31\xe5\xd7\x7a\x9b\xcf\xd3\xe5\x36\x7f\xf8\x30\xad\xa4\xa2\x90\x98\x04\xe7\x9b\x2e\x3a\x94\x14\xef\xb9\x2f\x2e\x7d\x40\xf2\x8c\x2a\x54\xf7\x21\xb1\x9f\x3b\xb8\x21\xe6\x9b\x44\x31\xf3\x2d\x6d\xcb\xf9\xde\xb8\x8c\x07\x90\x75\xb4\xa4\x9c\xee\x26\x98\x36\x5f\xc9\xee\xf1\xe0\xf5\xa4\x00\x75\x8f\xd2\x40\x0b\x49\xa8\xc3\x1e\xae\x7f\x2a\xb3\xd4\x84\xaa\x84\x7c\xe6\xfa\x3a\xf3\x4e\xbf\xae\xa7\xf2\xbb\x53\x79\x46\xc4\x5b\x88\x93\x61\x49\xd6\x01\x33\x24\xa0\x8c\x26\x55\x35\x43\x4d\x4e\x0c\xba\xbb\x3e\xfd\xf2\xd0\xff\x4d\x80\x05\x0f\x56\x06\xf2\x5c\xa3\x0a\x75\x2f\xfc\x81\x84\xc7\xea\xa4\x77\x34\x8b\x52\x76\x46\xca\xac\xce\xbf\x66\xf5\x53\x73\x5d\xa4\xcf\x54\x97\x6b\x3a\xf2\x3b\x0b\xeb\x1e\x9a\x2c\xbb\x43\xd2\x02\x18\xfc\xfd\xc8\xa9\x09\xe6\xac\x73\x2d\xce\x0a\xf8\xd4\x46\x92\xbc\x9b\x87\x68\xa8\x5a\x0a\x49\x9a\xe1\xab\x8f\xfa\x8d\x4a\x32\x98\x6d\xd2\x15\x12\x6a\xba\xab\x34\x85\x36\x5b\x39\x68\xca\x20\xe1\x01\xeb\x89\x4d\x8b\x0a\xf3\xa6\x8d\x20\xb4\xa8\x1c\xc5\x7f\xcd\xd8\xf6\x5a\x43\x63\x73\xb4\xae\x91\x58\x8a\x62\x45\x66\x9f\x07\x95\x48\xe5\x2c\x78\x32\x1c\x51\xf8\x0f\xe4\xac\x4d\xec\xab\x4c\xe1\x35\x30\xa8\xe1\x17\x32\xc4\x88\x6b\xe7\x11\x99\xec\x50\x60\xa0\x90\x48\x1b\x5c\xe1\xd2\x1f\x3b\xbe\xf1\x9a\x0d\xea\xf8\x03\x19\x18\x92\xcc\xc2\x86\x6c\x08\xa9\xa1\x55\x42\x90\xac\x4c\x65\x89\xcd\x76\x3e\x29\x3a\x00\x0d\x02\x9d\x74\xc7\x0e\x26\x33\x02\xf0\x5d\xe4\x9d\x47\xb8\x90\xda\x42\x88\xae\x58\xa2\x7d\x59\x1c\x85\x0e\x7e\xb2\x58\x1e\xd4\x23\xd3\x04\x1b\x2a\x87\x43\x35\xde\x86\x26\x91\x32\xe7\x95\xa4\x84\x00\x2a\x9d\x83\x38\xd4\xd6\xd4\xda\x91\x63\xc2\x7f\x2f\xab\xe4\xdb\x96\xb5\x49\x5d\xcf\x39\xde\x46\x0e\x09\xb5\x65\xa4\x77\x01\xb1\xee\xba\x80\xcd\x26\x0e\xa2\xf2\x0d\xf9\xb5\x98\x5f\x23\x33\xf2\xa3\x32\xfc\x0d\x4e\xe9\xd5\xe4\xde\x1c\x13\xfd\xb9\xd3\x50\x7d\xcb\x8c\x92\x37\xc0\x6a\x64\xd9\x72\x73\xfe\x31\x3b\x38\x8e\x7c\xdb\x39\xa7\x97\xaa\x9a\x86\x10\x0c\x43\x78\x4d\xa4\x05\xdb\x96\x22\x6a\x0c\xa5\x27\xe3\x37\xe6\xf4\x7e\x9e\xa1\x1f\xf6\x72\xf9\xd5\x50\x79\xbb\x58\xe8\xc1\xa5\x9b\x5d\x55\xba\x3b\x7d\xc4\x49\x4b\x55\x0e\xda\x2d\x9a\x29\x11\x9a\x89\x66\x7e\xbb\x6b\xc2\x25\xe0\x82\x2b\x03\x29\x3a\x25\xd0\x1e\x00\x61\xad\xa1\xf2\xb6\x96\xa6\xdd\xa6\xfc\x29\xa7\x3a\x8a\x7d\x85\x9d\x63\x3a\xa8\x6b\xe3\x60\x15\xc0\xbf\x59\xfb\xed\x1b\xda\x6d\x2f\xdd\x9c\x3a\x21\x97\x7a\xcb\x42\x7f\x84\xd7\x36\xb5\xaa\xa4\x9c\xf3\x39\xb5\xdc\x0f\x83\x23\x0b\xad\x20\x52\xb2\x6d\x09\x75\x36\x11\x0f\x1a\x3a\x93\x74\xec\x16\x56\x6d\x59\x22\xf3\x73\x6e\x72\x47\x33\x99\x71\xad\x50\xf2\x83\xa1\xc4\x43\x1e\x74\x44\xcf\x88\x00\xfd\xbd\x35\xdd\xd1\xcc\x9b\x9c\xa2\xc2\x13\x97\x05\xe6\x24\x9d\xc6\x34\xe8\x8e\x87\x21\x5e\xa1\x07\x5e\xf3\x9a\x29\x04\xee\x9c\x00\x6e\xba\xbf\x5f\x79\xec\x0c\x7e\xbc\xb8\xfe\x48\xb8\x85\xb7\xc8\x50\x9b\x39\x41\x0e\x8e\xcb\x9a\xd3\x7d\x70\xf8\x71\x01\xb8\xc3\x81\x75\x1e\xb2\x7e\xa7\xbb\x89\x8e\xdd\xb4\x07\xa7\xbb\x2c\x2b\x1d\x11\x80\x85\xeb\x4f\x06\xf5\x5b\xf6\x76\x28\x25\xc6\x75\x87\xe7\xcd\x90\xe6\x58\xa0\x23\x2b\x49\xe2\x6a\x77\xa8\x8e\x21\xda\x9e\x86\xa1\xc1\x53\xfd\x39\xe0\xcc\xd2\x67\x8c\x13\x32\x95\x55\xc6\x7d\x1d\x35\x6b\x58\x9e\x0e\xb2\x93\x4e\x1e\x56\x3e\x8e\xc2\x3f\x15\x0d\x97\x8a\xd3\x5e\xe6\x15\x18\x50\xda\xed\xe4\x5c\x0e\x3c\x2a\x6f\xbf\x5f\x64\x7a\x19\x26\xb0\x39\xc8\xfa\x07\x8e\xff\x4e\xbc\x8d\xfc\x47\xb3\x13\x72\x06\xdc\x1b\x9f\x95\x6b\xc8\xf1\x22\xd2\xbd\x83\x82\xf7\x87\x60\xd0\xfa\xc1\x54\xf9\xcd\x4f\x88\xbf\xca\x2b\x19\x4b\x6c\x83\x8b\xae\x93\x8d\x58\xfe\x83\x1a\x22\xc7\x56\x1d\xbe\x24\x33\x52\xf4\xea\x6a\x15\xf5\x01\x5c\x53\xef\x24\xa9\x35\x68\x9c\xb2\x9a\x36\xdf\xae\x2c\x25\x1e\x86\x65\xf8\x85\x44\x12\x53\x5d\x5b\x6c\xa6\xe1\x8e\xcf\xbb\x2e\x75\xd3\xa1\x91\xe3\x0c\xa9\xb9\xeb\x48\xbb\x60\x70\x2b\x4f\x35\x2a\xba\xb8\x0d\x39\x55\xdd\xd5\xa4\x5f\xb9\xba\xb2\x23\x4a\x61\xe8\x57\xc3\x53\x77\x3d\x84\x62\xda\x22\xfd\xb0\x85\xa9\xa8\x13\x1c\x5a\x3c\xd8\x65\xeb\x3e\x42\xda\x57\x5e\x45\x92\x7a\xc5\x8c\xab\xa3\x48\x7c\xee\x64\x80\x30\x54\xe8\x9a\x18\xc1\x54\xb6\xca\x37\x53\x36\x29\xcd\xf9\x2a\xdc\xde\xde\x5c\x41\x52\x0f\x1b\xbc\x73\x57\x10\xc4\x3f\x27\x6a\x1c\x4f\x25\x77\x71\xf1\xae\x93\xd8\x5a\x31\x33\xd9\x9d\x16\x8e\x16\x86\xdc\x01\xf7\x7f\xe0\xdc\xb4\xec\x78\x87\x1c\x4b\x25\x75\xa7\x0d\xc0\x31\x02\x89\xb0\xee\xe9\x15\xb5\xb9\x6d\x91\x28\xdd\xa1\x66\x82\x0e\x9e\x2a\x8e\x59\x91\x30\x06\x32\x33\x8c\x26\x2c\x5e\xbb\xca\x9b\x02\x0c\xac\xec\xdb\x32\x08\x04\xed\x24\x9a\xd7\x5c\xd7\x54\xb3\xe3\xb5\xe8\x89\x9b\x72\x34\xa0\xf4\x66\x3c\xa6\xeb\xd6\xf1\x0e\xb0\x02\x97\x08\x0e\xad\x17\x39\x04\xb9\xf2\xc5\x8d\x3a\x52\x13\xc0\x60\xf9\x09\x3e\xa6\x83\x52\x5e\xc4\x79\xf9\x89\xd1\x29\x92\x17\xc2\x73\xa3\xda\x4e\xa2\x5f\xdb\x5a\x90\x1c\x3b\x40\x73\xa0\xc9\x89\x05\xbd\xc7\x80\x58\x06\xfb\x96\x14\x59\xa6\x93\x96\x52\x51\xaa\xf6\xcb\x12\x72\x77\x8b\x19\x6d\x3a\x9c\xd7\x44\xcb\x22\x2a\x13\xeb\x36\x90\x91\x64\x4a\x1d\x0d\x20\x68\xce\xb9\xd8\xd6\x87\x03\x03\xc4\xe6\x28\x48\x76\x73\x32\x07\x6d\x39\xe5\x5a\x18\x94\x8c\xd8\xfd\xbc\x15\x71\x38\xde\x8f\xa2\x81\x7a\x04\x0f\x44\xfe\x8f\xea\x72\xcc\xc6\x1d\xc9\x7e\x38\x1e\x1f\xfd\x10\x04\x0e\x5e\x5a\xb7\xf8\xd3\x75\x3b\x82\x50\x06\xa8\xd7\x64\x89\x4a\x74\xb1\x5b\xe6\xde\x88\x0c\x1b\x3f\xb3\x67\x76\x4a\xe9\xec\x28\x21\xd4\x76\x20\x92\xba\x19\x6b\xbe\x19\xf2\x70\xae\x6e\xc3\x7b\x3c\x42\x9a\xee\x94\xd0\x5d\x0b\x80\x18\xb5\x78\x6a\x25\xfd\x87\xd0\xb1\xd3\xf2\x82\x4b\xda\xc5\x51\x22\x2d\x01\xf2\x07\xea\x80\x39\xc3\x06\x21\x30\x24\x64\x66\xdf\x33\x6a\x93\xb5\x3c\x31\x1e\x4d\x31\xed\x48\x1f\x29\xad\x1d\xa1\x99\x38\x92\xfc\xbb\xfc\x27\xa1\x3c\xed\xdb\x42\x95\x0f\xab\x18\x67\xaf\xe7\xa9\xd5\x35\x03\x53\x3c\x0c\xce\x2e\xc6\xfa\xcf\x7f\x58\xdf\x8b\xa8\x66\xc7\x96\xaa\x89\xc0\x18\x1f\xa8\x0c\x6c\xe9\x92\x3a\x5f\x70\x45\x8d\x5a\x4c\x1a\xa5\x53\x3a\xd6\xe9\x62\xc1\x05\xd7\x11\xc1\x44\x97\xfe\x13\x53\xe1\x71\xf9\x4c\x94\x9e\x19\xed\xc1\xb1\x2c\x72\x82\x8c\xec\x72\xc6\x85\x2e\x15\x94\xda\x9f\x60\xd1\xf1\xe7\xde\xba\xc7\x07\xed\xfe\xb1\x20\x04\x84\x29\xfe\x23\xd4\x22\x78\x7c\xf9\x2d\x8c\x8d\xee\xfe\x53\xf3\x28\xb2\xa5\x46\x84\xee\x27\x21\x1a\x1f\x63\x59\x98\x68\x04\x2d\xbd\x5e\xc1\x8f\x86\xf9\xd2\xe0\xf9\xba\x04\x24\xd4\x07\xbf\xcc\x46\xc4\x4f\x12\xfd\x47\x13\xd2\x43\x22\x1e\x1b\x08\x30\x73\x99\x46\xda\x04\x23\x9c\x87\x0c\xb7\x31\xf8\xd4\x2e\xef\xcf\x38\x3f\x1c\x95\x6a\x3a\x4a\x1f\x09\x25\x8b\xad\x84\x54\x63\xe6\x4a\xc3\x98\x49\x1f\x69\x3d\xa6\x0b\x02\x8d\xe1\x3a\xc4\xbc\x48\xf9\x99\x23\xe6\x77\xb3\xc8\x5a\x6d\xe3\x51\x79\xc9\xe2\x5c\xde\x0e\xe7\xa6\x0a\x48\xb1\xbc\x9c\xa3\xd9\x59\x63\x4d\x21\xe6\xa7\x00\x00\x43\xfa\xcc\x73\x38\xf7\x46\x31\x36\x8c\x29\xbe\x5f\x18\xe8\xfe\x1f\xd7\x08\xfa\x47\x74\x46\x6b\x4d\x5c\xc2\xb0\xb2\xd7\x36\xe7\x90\x23\x1a\xb4\x57\xc9\xfa\xb3\x5b\x3a\x4e\xc0\xf4\x08\x19\x4a\xfa\xc1\xd6\x4e\xb5\x91\xff\xde\x00\x9f\x77\xf2\xa4\x00\x1e\x2e\xa7\xd7\x88\x05\xff\x37\x41\x28\x0a\x3a\xe9\x5d\xe2\xcc\x7f\x4c\x0f\x95\x73\x48\x21\xa6\x4e\xbf\x6c\xb4\x25\xf9\x83\x30\x36\x89\xca\x7d\x34\x63\xce\xff\xe4\x23\xc9\xff\xfc\xf8\xfc\xd2\x88\xe5\xa1\xb5\xec\x89\xb3\x73\xb1\x01\x80\xd6\xcb\xdb\x55\xd6\xfd\xe6\xab\x2f\xa4\xf8\xcd\xd1\x76\xf3\xa9\x46\x94\x7f\x76\x9b\x0d\xd1\x0b\x8d\x4e\x0c\xd6\xdb\x09\x03\x99\x1b\x88\x1b\xf0\x06\x90\x91\xb3\xde\x71\x90\xc9\x9e\xa7\xee\x9f\xe0\xdf\xac\x8b\xe6\x62\x73\xa9\x58\xfe\x77\x09\xf2\x11\x98\xa9\xf2\x23\x1a\x14\x9d\x64\x10\x21\x3a\x63\x76\x48\x10\x36\x73\x3e\x07\x6b\x5a\xe6\x93\xcf\x72\x1e\x90\x9b\x95\x40\x24\x1f\x40\x4d\x90\xcf\x3a\xee\x8d\x61\x1b\x79\xe3\xe2\x84\xf2\x76\xf2\xf2\xf5\x79\x2c\xf8\x02\x19\x2c\x18\xad\x19\xf6\x00\x14\x12\x7d\x42\x8b\x8c\x14\xee\x1c\xe3\x8b\x01\xd1\x8d\xce\xbe\x64\xe5\xda\x01\xf1\x7f\x58\x62\xe6\xd9\x44\x87\x01\x32\xc7\x3d\xb9\x58\x56\xa6\x16\x8a\x75\xd8\x48\xa8\xf7\x33\x94\x48\xf2\x64\x2e\x7b\x0e\x84\x72\xa6\x46\x73\x9e\x6e\xf2\x82\xf9\xda\xa8\x9f\x72\xa8\xb7\x74\x1d\x07\x33\x2b\x98\xdd\x12\x71\x67\x59\xf9\xa0\xb9\xfb\x49\x0d\xbe\xc2\x49\x61\x9f\x0e\x2d\x1a\x10\xb6\x4b\xa7\x50\x69\x10\x59\x13\xa2\xe1\x7b\x73\xf0\x1d\x3e\xb4\x95\x87\x4f\xd4\x71\x78\x73\xde\x3e\x40\x88\xea\x4d\xc0\xb8\xe3\xe1\x3e\xdd\xd8\xb3\x32\x04\xf5\xee\xb3\x09\x15\x7e\xa8\x1b\x77\x1f\xf7\xae\xff\x1d\x97\xb8\x08\x05\xf5\x7f\xbe\xe2\xe1\x66\x5c\x34\x4a\x29\xc3\x0f\xb7\xa6\x97\x03\x79\x0a\x20\x63\xe8\x75\xbc\xf9\x89\xa1\x5c\x54\x25\x05\x58\x1a\x28\x8b\xaf\x11\xba\xd6\x21\xaf\x10\x92\x87\xf4\xdf\x0f\xf7\x4f\xf8\x76\x40\x34\x53\xe1\xde\xfe\x19\xd2\x7e\x58\xf1\x25\x27\xdf\x70\x77\x71\xcf\x64\x5f\x41\x29\x31\xc2\xdb\xed\x9b\xe1\xb8\x29\x9c\x06\x9d\x10\x3d\x84\x23\x9c\x5c\x03\x5c\x74\xbc\xf8\x21\x6e\xd6\xe1\xf8\x85\x17\x0e\x48\xe9\x8c\xdf\x24\xa6\x0e\x0e\x9e\xc0\xa8\x5d\x1d\x4d\xbd\xa1\x7e\xb8\xa7\xbe\x07\x3d\xde\x7a\x77\x5e\x1c\x21\xa7\x88\x21\x48\x92\x7b\xf5\xcf\x17\x39\x44\xe2\xdb\x50\x5b\x1c\xff\xa0\xf5\x43\x2b\x7b\xfe\x6b\xa3\x16\xfa\x50\x23\xbc\xdb\x91\x97\x88\x8f\xf2\xa5\xf0\xa1\x2e\x3c\xc6\xda\x07\x48\x5c\x89\xa5\x7a\x56\xe9\xe7\x1a\x6a\x91\x1e\x5b\x0b\xfc\x35\xa4\x82\x81\x75\x66\x84\x32\x25\x71\xa8\x14\xfd\x47\xf9\x53\x80\xec\x24\x8a\x08\x9e\xce\x2c\x4d\xb6\xc2\xd1\x95\x75\x2f\xf6\xbc\x4f\xee\x3e\x6a\xdf\x13\x85\xb2\xee\x50\xea\xee\xc5\x26\x9e\x41\x84\x16\x37\xc9\xc4\x35\x98\x11\x5d\x4e\x88\x3d\x91\x41\x24\x39\xf9\xe4\xde\xa7\x89\x2f\xe7\x02\x34\x18\x2a\x71\x65\x54\x24\x0f\x34\x1b\x55\x3b\xbc\xa1\x01\x19\x37\x47\x6c\xf2\xb4\x63\xd6\x5a\xa4\xc1\xd4\x49\xf3\x31\x87\x5c\xbc\xcb\x3b\x36\x88\x34\x3c\x31\xf3\xfa\xca\x92\x6c\x43\x17\x6e\xdc\xdd\x66\x1e\x4a\x68\xea\x95\xf4\x35\x6b\x2f\x4b\x3a\x32\xa9\x66\x59\x13\x16\x00\x69\x15\x86\xe6\x25\x00\x4b\x7f\x8e\x97\x30\xeb\x8b\x81\x23\xe4\x22\xf3\x8b\x0e\x96\x21\xe8\x77\x87\x3f\x49\x76\xd0\x7c\xac\x21\x5b\x78\x85\xab\x70\x08\x96\x5c\x17\xf8\x31\xa3\x2d\x24\x1f\x53\x68\x2d\xb6\x17\x03\x2f\x28\x8f\x3c\xa4\x2a\x18\x42\x94\xd0\xa8\x5d\xdb\x3f\x53\xa8\x4d\xfe\xef\xb6\xe1\x39\x84\x1d\x93\xf4\x0c\xf7\x34\xdc\xac\xce\xf6\x91\x60\xe1\x26\xf1\x40\x1f\x36\x78\xf8\xd6\xf8\x94\x86\xac\xcc\x9e\x21\x2b\x70\x1f\xa0\x31\xa9\x62\xc3\x7e\x36\x6d\x9f\xb6\xc1\xdb\x5a\x33\x7b\x33\xd8\x91\xfc\xf9\x02\xf2\x01\x9e\x7e\xd9\xcb\x25\x90\x76\x1d\x56\x7f\x9a\x8f\x52\x48\xcd\x7a\x33\x0b\x52\x20\x02\x4a\x1b\x14\xeb\x7d\x7b\xaa\x8a\x3c\xb2\x4d\x4e\x29\x1d\x34\xb9\x4a\xbc\x64\xcc\x51\x4f\x6d\x29\x76\xc7\x20\xd4\xb2\x6a\x40\x06\x79\x08\x12\xa5\x77\x3c\x13\x04\xad\xf4\xba\x46\x5a\xee\xaf\xd0\x7c\xab\x1d\x20\x9c\x03\xd7\xe0\x21\xcf\x2c\xab\xdf\x20\x45\x62\xf3\x23\xe5\x78\x92\x0f\x88\x3c\x48\x8d\x72\xd6\xbf\xe7\x78\x31\x13\xfb\x2a\xcc\x6c\xb8\xfd\xd3\x27\x8d\x1e\xdc\x85\x48\x08\x86\x23\xee\x05\xd9\xa3\x90\x02\xe1\xc6\x5c\xd4\x58\xfa\x1c\xcd\x06\xba\x63\xbc\x44\xfb\x44\x72\x53\x2e\x85\xf0\x86\xc4\x7c\x29\x3f\xa9\xb7\x6a\x66\x14\x0f\x80\x00\x65\x28\x4f\x62\x0a\x4b\x85\x58\x17\x28\xa1\xef\x62\x48\x5a\x4f\x19\xd2\x4b\x2d\xcf\xe6\xdd\x7e\x42\x30\x26\x7b\x79\x4e\xf7\xce\x5e\x21\x35\xb5\x52\xcc\x80\x45\x3e\x3d\x84\x47\x75\x48\xf5\xe6\xa9\xb6\x53\x1a\xea\x83\x2f\xdd\xf2\x9f\x5b\xd3\x5f\x33\x9c\x67\xfd\xbb\xd7\x45\x57\x49\x7e\x42\xdf\x80\xd7\x5a\xfa\xd8\x35\x2f\x8d\x5c\x73\x48\x43\x30\xd5\x0c\xa9\xbf\x99\xda\x6d\x28\x49\xd2\x7b\x60\xa0\x62\xff\x39\x94\xd6\xd9\x7f\x10\x7a\x84\x7a\xf6\x6f\xee\xb8\xe5\xb6\xea\x6f\xa5\xab\x18\xf0\x06\x6d\xa5\xcf\x3f\x50\x56\x2f\x29\xf0\x8e\xd2\x8d\x0d\x00\xa9\x9f\xd9\x84\x59\x2a\x8b\xb7\x35\x3c\x9f\xcd\xf7\x66\x5e\x6f\x4a\xca\x84\x7e\xa4\x9f\xe2\x94\x2d\xd1\x43\x31\xae\xf0\x2c\x3f\x71\x2d\xc0\x95\x19\xd6\x80\xa1\x21\x59\xef\x36\x83\x80\xb2\x3c\xd5\x05\x1b\xed\x86\x99\x9e\x67\x72\x77\x23\x88\x93\xa8\x52\x07\x53\xb7\x0a\xc4\x60\xd1\x3b\x61\x83\xe4\xf8\x40\xb0\x20\xd5\x4a\x48\xa6\x90\x62\xa1\xaf\xdf\x6f\x96\xde\xe2\xcb\xbb\x09\x2a\x4e\xc6\xda\x31\xb6\x7a\x05\x2e\x19\x8e\xfc\xc6\x1e\x22\x00\xb3\x64\x14\xef\x58\x2d\xb3\xd6\x70\x84\xb4\xe3\x39\x81\x40\xc1\xa1\x8d\xb9\x14\x2d\xe9\xab\xd2\x84\xc0\x5b\x51\x29\x52\x07\x99\x49\x5e\xc8\x97\x9a\x43\x53\xb1\xd6\x2d\x02\xbe\x6c\x42\x1d\xd1\x21\x14\x94\xd4\x15\xa0\xc7\xc1\x3b\xae\x5b\x88\x65\x6e\x87\xa4\x28\xb1\x5c\xa8\x5f\x04\xff\x30\x1c\x63\x12\xd7\xc4\x4a\x36\x91\x52\x95\x0d\x34\x3d\xcd\xc5\x66\xc5\xaa\xe5\x22\x82\x0d\x50\xa5\xbd\xa4\x46\x57\x17\x09\x50\x16\x5d\x60\x9a\xf4\xc3\xbc\x49\x44\x32\x28\xfb\x7b\xd2\x77\xc2\x08\x56\x80\xb9\x43\xbe\x55\x5f\xb2\x0f\xfd\x49\x6a\xf0\x80\xe4\x4a\x34\xb3\xfd\x82\xd5\xd6\x8d\xc8\x5f\xcf\xa2\x47\xb7\x80\x62\x44\x69\x2c\xfd\xd2\x84\x19\x97\x18\x40\x30\xc1\x49\x43\xd3\x93\x0c\x41\x44\xb3\x5a\xd9\x44\x8b\x34\x5d\x9b\x40\x24\xf7\x42\x23\xac\x49\x47\xaa\x73\x05\x18\x14\x37\x0f\x71\x48\xc5\xc3\xf6\x33\x69\x73\xac\xaf\x3a\xa4\xea\x58\xec\x49\xf9\xb4\x08\xa2\x8f\x89\xa9\x5f\x98\xbc\xd1\x42\x75\x62\x7c\x21\x3e\xf7\xd9\x17\x95\x1f\x92\x8c\x4c\x1a\x6d\x81\xd2\xb4\x71\x60\x76\xa9\xc8\xa2\xdd\xfb\x7e\x4b\xa2\x12\xbd\x89\x4e\xb1\xc6\x24\x0d\xe4\x0c\xf7\xce\x75\x05\xe0\x31\xf6\x8e\x63\x9c\x6a\x90\x96\x25\xf4\x47\x42\x1c\x35\x9f\x21\x75\xe8\x4f\xb1\x0a\x49\xfe\x35\xab\x2b\xed\x7d\xf1\x92\xff\xdc\x94\x1d\xd7\x43\x27\x4a\x2a\x89\xd0\xbe\x08\xf9\xc7\x97\x74\x11\x41\xb2\x1c\x4a\x87\x27\x73\x2d\x7b\x10\x46\x95\x3e\x7e\x05\x26\xd2\x1c\xaa\x92\x21\x1a\x09\x22\xcc\x90\x28\x3c\x29\xfb\xa5\x8d\xf3\x8a\xd4\x51\x17\xa8\x44\xba\x2c\xf1\xae\xda\x26\x91\xa7\x01\x24\xa9\x28\xd2\x50\xf3\xd1\xe3\xd4\xe1\x89\xaa\x89\x8d\xcb\x1a\x39\x24\xf1\x49\x23\xe1\x61\xe2\xda\x09\xd2\x49\xf8\x94\x93\xf2\x6e\x7b\xef\xf7\x6b\x20\xc9\x3e\x1e\xbb\x27\x87\xe9\x4e\x8f\x75\x89\x1f\x85\x67\xcb\xe1\x19\xb0\x0c\x43\x11\xea\xeb\xa8\xeb\x4b\x1b\x92\xf2\x20\x28\xef\x26\x82\xd9\x69\x97\x8f\x5b\xbc\xc6\xee\xc9\x54\x25\x70\x12\x10\xc1\xbb\xc1\xa6\x48\x79\xf3\xbc\xdb\x25\x31\xcc\x2d\x64\x72\x95\x71\x6a\xe5\x64\xc6\x63\xe5\x57\x61\xc3\xd1\xae\xe3\x86\xf6\x40\xcc\xae\xd0\xd9\xd6\x9d\x47\x21\xe7\x91\x20\x1e\xc6\xda\xba\x29\x74\xd7\xda\x97\x8e\xa6\x73\x99\xf2\x4c\xb4\xbc\x42\x7f\x93\x92\xb5\x84\xc3\x4f\xef\xd5\x46\xbb\x3b\xf4\x2f\xfb\x38\xb6\x48\x7f\xb2\x17\xc7\x5c\x8f\x40\x7c\x0a\xbf\xa6\xae\x5e\x4c\xda\x31\xc8\x65\xe5\xee\x13\x22\x94\x5f\xea\xca\xfd\x59\x83\x83\x94\xa5\xf4\xeb\xee\x93\x46\x06\x44\x2d\xeb\xab\xf0\xc3\xb1\x8d\x4e\xb2\x93\xa7\xc4\xb3\x6e\x70\x7d\xf5\x9c\xa4\xda\x68\x7e\x35\x85\x4b\xc9\xb3\x00\x29\x2d\x1d\x50\x27\x67\x28\x75\x77\x87\x88\xe5\x31\x85\x24\xd8\xed\x4e\x77\xa1\x12\x87\x83\x57\x57\xd7\xdb\xf8\x25\x18\x08\xe5\xcb\x6d\x90\x0a\xe4\xbd\xea\x8e\x5c\xf3\x84\xa8\x34\x31\xcc\x45\x35\xc3\xa9\xb8\x07\x9c\x38\xfa\xa7\x99\xdb\x7c\x3a\xb7\xce\x4e\xa7\x5b\x67\x33\xdf\xbf\x72\x9a\x12\xc1\x3b\x3c\x84\xcd\x8a\x21\xb4\x33\x3f\x52\x53\x3b\xee\xed\x7c\x71\x01\x1b\x38\x94\xef\x40\x2c\xcb\x7b\x31\x14\xad\x01\xf2\x99\x7a\x27\xc7\xcd\x02\x6a\xcf\x89\xa8\xc9\x8b\x82\x7b\xeb\x43\x50\x9f\xfc\xc0\x0d\x7a\x52\x21\x61\x98\x89\x6e\xf9\xfd\xb4\x3b\x9d\x0d\x8b\x1d\x0b\x54\xb2\xf8\x02\x9d\x21\x27\x50\x9f\x7f\x55\x29\x10\x51\xf0\x8f\xa6\x73\x6a\x8a\x4b\xbf\x63\x07\x04\x30\x68\x8f\x2b\x63\xd2\x8f\xdb\xe1\xca\x71\x8b\x52\xff\x46\xf8\x9c\x6a\x80\x14\xe4\x9f\xa2\xe6\x65\xa3\x1a\x63\x8b\x7d\xab\x93\x32\xe1\xd1\x22\x5d\x00\xb7\xd0\x05\x85\x26\x7b\x3b\x8f\x3c\xf7\x1d\x18\xa1\x36\x01\x4e\x8e\x3d\x13\x6d\x10\x78\x86\x16\x69\xfa\x96\x40\x9f\x96\xfc\x00\x7d\xce\x55\x25\x8b\x50\x5b\x75\x42\x7b\xfd\x6b\x6b\x4a\x61\xd8\xe8\xd3\x15\x50\x29\xbf\xdd\xc1\x74\x8c\xce\x55\xb1\x59\xd7\xd4\x94\x4b\x81\x36\x19\xb5\xee\x1b\x8b\xfd\x5a\x1f\xef\x10\x49\xb5\x11\x78\x27\x0e\x21\xcf\x2d\x54\x3a\xdf\xd2\x38\x84\xd3\xe2\xd2\xf1\xf7\xe5\x0c\x2c\x00\xf3\x8f\xf9\x02\xca\xf7\x67\xf9\xdf\x1d\xff\x3b\x1e\x95\x6e\x08\xe0\xac\x9d\xd0\x69\xe8\x75\x34\xeb\x81\xc8\xfc\x22\x62\x00\x6e\xf0\xdf\x21\x57\x5a\xc1\x02\xed\x7d\x11\x02\x39\x55\x86\xd0\xe8\xf1\x61\xe5\x0e\x15\x12\x03\xb5\x4b\xf3\xb7\xc7\xc4\x4e\xa0\x1e\x89\x55\xaf\xfa\x52\xab\x04\x0f\xeb\xe6\x33\xab\x08\x68\xef\x6a\x48\x43\x75\x10\x55\xe3\xd9\xb6\xa4\x29\xba\x6b\x87\x52\x35\x4f\x64\xfa\x5d\x0d\x51\xbe\x16\x7a\xe5\x88\x65\x61\x6d\x4b\xd0\xe1\x19\x94\x1a\xa9\xe2\x01\xa0\x3d\x7a\x48\xc3\xa2\xab\x13\x62\xd0\x42\x30\x35\x9f\xfb\xb8\xdc\x93\xb0\x2e\xa6\x0e\xa0\x86\xea\xe6\xef\x33\xf3\xe5\x61\x9e\xdb\xb5\x66\xb3\x1e\xde\x10\x42\xa8\x7d\x84\xab\x1b\xec\x79\x6d\x26\x19\x41\xa2\x54\xe5\xcc\xdf\xa4\x81\x91\x66\x1d\xb2\x99\x58\x86\x0a\x29\x65\x11\xe0\xac\x55\xeb\x5a\x62\x7c\x87\xfa\x12\x13\x82\x0d\x35\x39\xd4\x05\xd1\x38\x3c\x57\xd2\xa7\x88\x60\x6c\x8e\x84\x2e\x70\x4a\x85\x4c\x28\x9a\xea\xcb\x7a\xd4\xe3\x19\x11\x24\xdd\x83\x4c\x2a\x5d\xf9\xba\xa7\xac\x43\x48\x4c\x25\xa0\xb3\xcb\x40\x6a\xad\xa7\x78\x9c\x9e\x15\x14\xfa\xea\x8a\xa4\x1c\x6d\xf2\x72\x25\x0f\xf1\x07\x94\x8a\xa1\x3a\x35\xfc\x98\x8f\xb0\xfc\x51\x35\x8e\x6c\x1f\x0a\xa2\x3a\x98\x34\xdb\x34\x44\x67\x0b\x54\x50\xe5\x45\xec\x4a\x04\xa0\x74\x66\x9d\xf2\x8b\x2e\x69\x54\x1b\x9b\x13\x73\x13\x3b\x7a\x26\xba\xfc\x61\x63\x0c\x57\x4e\x07\x56\x0d\xaf\x9d\xf5\x45\xfe\x8b\x1c\x4a\xae\xf6\xa4\x3c\x1c\x49\x1b\xb3\xf4\x50\xaf\x18\x79\x9a\x38\x33\x32\xbb\x6d\x06\x20\xc8\x79\x2b\xd2\xc4\x62\x98\x43\xa2\xd0\x25\x90\x9a\x12\xab\xcd\x38\x0b\xe1\xb3\xc9\xaf\x42\xb1\x87\xad\x1d\x3c\x2a\x92\x26\x85\xe6\x6e\xd6\x01\x64\x6b\x80\x68\xeb\x97\xdd\x5d\x3e\x98\xf2\xdf\x65\x24\xa1\xa9\xae\x1b\x96\x63\x89\xe6\x54\x24\xd3\x6a\x56\x1a\xdf\xbc\xc1\x90\x44\x5d\x99\x87\xd1\x99\x11\x92\x74\xf7\xcb\x22\x5b\x4a\xca\xaa\x01\x43\xf6\xd4\x90\xbb\x65\x5c\x61\xb5\x1c\xf1\x23\x9b\x59\x86\x8c\x69\x7c\x0c\x59\x51\xa7\x5d\xe6\x2c\xa4\xcb\xb3\x9c\xd1\x90\x54\x65\xef\x94\x07\x9d\x0c\xc3\x46\x00\x2f\x43\x1c\x34\x43\x8f\x32\x85\x84\xac\x6d\x68\x6c\xcf\x69\x68\x75\x6a\xfd\x6a\xfa\x4a\x73\xf3\x73\xba\x03\xe3\xff\xff\x3f\xff\xdf\xff\x0d\x00\x00\xff\xff\x9b\xc6\xef\xe7\x7d\x0c\x06\x00") - -func dataSurnamesJsonBytes() ([]byte, error) { - return bindataRead( - _dataSurnamesJson, - "data/Surnames.json", - ) -} - -func dataSurnamesJson() (*asset, error) { - bytes, err := dataSurnamesJsonBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "data/Surnames.json", size: 396413, mode: os.FileMode(420), modTime: time.Unix(1452717629, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -// Asset loads and returns the asset for the given name. -// It returns an error if the asset could not be found or -// could not be loaded. -func Asset(name string) ([]byte, error) { - cannonicalName := strings.Replace(name, "\\", "/", -1) - if f, ok := _bindata[cannonicalName]; ok { - a, err := f() - if err != nil { - return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err) - } - return a.bytes, nil - } - return nil, fmt.Errorf("Asset %s not found", name) -} - -// MustAsset is like Asset but panics when Asset would return an error. -// It simplifies safe initialization of global variables. -func MustAsset(name string) []byte { - a, err := Asset(name) - if err != nil { - panic("asset: Asset(" + name + "): " + err.Error()) - } - - return a -} - -// AssetInfo loads and returns the asset info for the given name. -// It returns an error if the asset could not be found or -// could not be loaded. -func AssetInfo(name string) (os.FileInfo, error) { - cannonicalName := strings.Replace(name, "\\", "/", -1) - if f, ok := _bindata[cannonicalName]; ok { - a, err := f() - if err != nil { - return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err) - } - return a.info, nil - } - return nil, fmt.Errorf("AssetInfo %s not found", name) -} - -// AssetNames returns the names of the assets. -func AssetNames() []string { - names := make([]string, 0, len(_bindata)) - for name := range _bindata { - names = append(names, name) - } - return names -} - -// _bindata is a table, holding each asset generator, mapped to its name. -var _bindata = map[string]func() (*asset, error){ - "data/Dvorak.json": dataDvorakJson, - "data/English.json": dataEnglishJson, - "data/FemaleNames.json": dataFemalenamesJson, - "data/Keypad.json": dataKeypadJson, - "data/L33t.json": dataL33tJson, - "data/MacKeypad.json": dataMackeypadJson, - "data/MaleNames.json": dataMalenamesJson, - "data/Passwords.json": dataPasswordsJson, - "data/Qwerty.json": dataQwertyJson, - "data/Surnames.json": dataSurnamesJson, -} - -// AssetDir returns the file names below a certain -// directory embedded in the file by go-bindata. -// For example if you run go-bindata on data/... and data contains the -// following hierarchy: -// -// data/ -// foo.txt -// img/ -// a.png -// b.png -// -// then AssetDir("data") would return []string{"foo.txt", "img"} -// AssetDir("data/img") would return []string{"a.png", "b.png"} -// AssetDir("foo.txt") and AssetDir("notexist") would return an error -// AssetDir("") will return []string{"data"}. -func AssetDir(name string) ([]string, error) { - node := _bintree - if len(name) != 0 { - cannonicalName := strings.Replace(name, "\\", "/", -1) - pathList := strings.Split(cannonicalName, "/") - for _, p := range pathList { - node = node.Children[p] - if node == nil { - return nil, fmt.Errorf("Asset %s not found", name) - } - } - } - if node.Func != nil { - return nil, fmt.Errorf("Asset %s not found", name) - } - rv := make([]string, 0, len(node.Children)) - for childName := range node.Children { - rv = append(rv, childName) - } - return rv, nil -} - -type bintree struct { - Func func() (*asset, error) - Children map[string]*bintree -} - -var _bintree = &bintree{nil, map[string]*bintree{ - "data": &bintree{nil, map[string]*bintree{ - "Dvorak.json": &bintree{dataDvorakJson, map[string]*bintree{}}, - "English.json": &bintree{dataEnglishJson, map[string]*bintree{}}, - "FemaleNames.json": &bintree{dataFemalenamesJson, map[string]*bintree{}}, - "Keypad.json": &bintree{dataKeypadJson, map[string]*bintree{}}, - "L33t.json": &bintree{dataL33tJson, map[string]*bintree{}}, - "MacKeypad.json": &bintree{dataMackeypadJson, map[string]*bintree{}}, - "MaleNames.json": &bintree{dataMalenamesJson, map[string]*bintree{}}, - "Passwords.json": &bintree{dataPasswordsJson, map[string]*bintree{}}, - "Qwerty.json": &bintree{dataQwertyJson, map[string]*bintree{}}, - "Surnames.json": &bintree{dataSurnamesJson, map[string]*bintree{}}, - }}, -}} - -// RestoreAsset restores an asset under the given directory -func RestoreAsset(dir, name string) error { - data, err := Asset(name) - if err != nil { - return err - } - info, err := AssetInfo(name) - if err != nil { - return err - } - err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755)) - if err != nil { - return err - } - err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode()) - if err != nil { - return err - } - err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime()) - if err != nil { - return err - } - return nil -} - -// RestoreAssets restores an asset under the given directory recursively -func RestoreAssets(dir, name string) error { - children, err := AssetDir(name) - // File - if err != nil { - return RestoreAsset(dir, name) - } - // Dir - for _, child := range children { - err = RestoreAssets(dir, filepath.Join(name, child)) - if err != nil { - return err - } - } - return nil -} - -func _filePath(dir, name string) string { - cannonicalName := strings.Replace(name, "\\", "/", -1) - return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...) -} diff --git a/vendor/github.com/ccojocar/zxcvbn-go/entropy/entropyCalculator.go b/vendor/github.com/ccojocar/zxcvbn-go/entropy/entropyCalculator.go deleted file mode 100644 index 80432572bd..0000000000 --- a/vendor/github.com/ccojocar/zxcvbn-go/entropy/entropyCalculator.go +++ /dev/null @@ -1,217 +0,0 @@ -package entropy - -import ( - "math" - "regexp" - "unicode" - - "github.com/ccojocar/zxcvbn-go/adjacency" - "github.com/ccojocar/zxcvbn-go/match" - zxcvbnmath "github.com/ccojocar/zxcvbn-go/utils/math" -) - -const ( - numYears = float64(119) // years match against 1900 - 2019 - numMonths = float64(12) - numDays = float64(31) -) - -var ( - startUpperRx = regexp.MustCompile(`^[A-Z][^A-Z]+$`) - endUpperRx = regexp.MustCompile(`^[^A-Z]+[A-Z]$'`) - allUpperRx = regexp.MustCompile(`^[A-Z]+$`) - keyPadStartingPositions = len(adjacency.GraphMap["keypad"].Graph) - keyPadAvgDegree = adjacency.GraphMap["keypad"].CalculateAvgDegree() -) - -// DictionaryEntropy calculates the entropy of a dictionary match -func DictionaryEntropy(match match.Match, rank float64) float64 { - baseEntropy := math.Log2(rank) - upperCaseEntropy := extraUpperCaseEntropy(match) - // TODO: L33t - return baseEntropy + upperCaseEntropy -} - -func extraUpperCaseEntropy(match match.Match) float64 { - word := match.Token - - allLower := true - - for _, char := range word { - if unicode.IsUpper(char) { - allLower = false - break - } - } - if allLower { - return float64(0) - } - - // a capitalized word is the most common capitalization scheme, - // so it only doubles the search space (uncapitalized + capitalized): 1 extra bit of entropy. - // allcaps and end-capitalized are common enough too, underestimate as 1 extra bit to be safe. - - for _, matcher := range []*regexp.Regexp{startUpperRx, endUpperRx, allUpperRx} { - if matcher.MatchString(word) { - return float64(1) - } - } - // Otherwise calculate the number of ways to capitalize U+L uppercase+lowercase letters with U uppercase letters or - // less. Or, if there's more uppercase than lower (for e.g. PASSwORD), the number of ways to lowercase U+L letters - // with L lowercase letters or less. - - countUpper, countLower := float64(0), float64(0) - for _, char := range word { - if unicode.IsUpper(char) { - countUpper++ - } else if unicode.IsLower(char) { - countLower++ - } - } - totalLenght := countLower + countUpper - var possibililities float64 - - for i := float64(0); i <= math.Min(countUpper, countLower); i++ { - possibililities += zxcvbnmath.NChoseK(totalLenght, i) - } - - if possibililities < 1 { - return float64(1) - } - - return (math.Log2(possibililities)) -} - -// SpatialEntropy calculates the entropy for spatial matches -func SpatialEntropy(match match.Match, turns int, shiftCount int) float64 { - var s, d float64 - if match.DictionaryName == "qwerty" || match.DictionaryName == "dvorak" { - // todo: verify qwerty and dvorak have the same length and degree - s = float64(len(adjacency.BuildQwerty().Graph)) - d = adjacency.BuildQwerty().CalculateAvgDegree() - } else { - s = float64(keyPadStartingPositions) - d = keyPadAvgDegree - } - - possibilities := float64(0) - - length := float64(len(match.Token)) - - // TODO: Should this be <= or just < ? - // Estimate the number of possible patterns w/ length L or less with t turns or less - for i := float64(2); i <= length+1; i++ { - possibleTurns := math.Min(float64(turns), i-1) - for j := float64(1); j <= possibleTurns+1; j++ { - x := zxcvbnmath.NChoseK(i-1, j-1) * s * math.Pow(d, j) - possibilities += x - } - } - - entropy := math.Log2(possibilities) - // add extra entropu for shifted keys. ( % instead of 5 A instead of a) - // Math is similar to extra entropy for uppercase letters in dictionary matches. - - if S := float64(shiftCount); S > float64(0) { - possibilities = float64(0) - U := length - S - - for i := float64(0); i < math.Min(S, U)+1; i++ { - possibilities += zxcvbnmath.NChoseK(S+U, i) - } - - entropy += math.Log2(possibilities) - } - - return entropy -} - -// RepeatEntropy calculates the entropy for repeating entropy -func RepeatEntropy(match match.Match) float64 { - cardinality := CalcBruteForceCardinality(match.Token) - entropy := math.Log2(cardinality * float64(len(match.Token))) - - return entropy -} - -// CalcBruteForceCardinality calculates the brute force cardinality -// TODO: Validate against python -func CalcBruteForceCardinality(password string) float64 { - lower, upper, digits, symbols := float64(0), float64(0), float64(0), float64(0) - - for _, char := range password { - if unicode.IsLower(char) { - lower = float64(26) - } else if unicode.IsDigit(char) { - digits = float64(10) - } else if unicode.IsUpper(char) { - upper = float64(26) - } else { - symbols = float64(33) - } - } - - cardinality := lower + upper + digits + symbols - return cardinality -} - -// SequenceEntropy calculates the entropy for sequences such as 4567 or cdef -func SequenceEntropy(match match.Match, dictionaryLength int, ascending bool) float64 { - firstChar := match.Token[0] - var baseEntropy float64 - if string(firstChar) == "a" || string(firstChar) == "1" { - baseEntropy = float64(0) - } else { - baseEntropy = math.Log2(float64(dictionaryLength)) - // TODO: should this be just the first or any char? - if unicode.IsUpper(rune(firstChar)) { - baseEntropy++ - } - } - - if !ascending { - baseEntropy++ - } - return baseEntropy + math.Log2(float64(len(match.Token))) -} - -// ExtraLeetEntropy calulates the added entropy provied by l33t substitustions -func ExtraLeetEntropy(match match.Match, password string) float64 { - var subsitutions float64 - var unsub float64 - subPassword := password[match.I:match.J] - for index, char := range subPassword { - if string(char) != string(match.Token[index]) { - subsitutions++ - } else { - // TODO: Make this only true for 1337 chars that are not subs? - unsub++ - } - } - - var possibilities float64 - - for i := float64(0); i <= math.Min(subsitutions, unsub)+1; i++ { - possibilities += zxcvbnmath.NChoseK(subsitutions+unsub, i) - } - - if possibilities <= 1 { - return float64(1) - } - return math.Log2(possibilities) -} - -// DateEntropy calculates the entropy provided by a date -func DateEntropy(dateMatch match.DateMatch) float64 { - var entropy float64 - if dateMatch.Year < 100 { - entropy = math.Log2(numDays * numMonths * 100) - } else { - entropy = math.Log2(numDays * numMonths * numYears) - } - - if dateMatch.Separator != "" { - entropy += 2 // add two bits for separator selection [/,-,.,etc] - } - return entropy -} diff --git a/vendor/github.com/ccojocar/zxcvbn-go/frequency/frequency.go b/vendor/github.com/ccojocar/zxcvbn-go/frequency/frequency.go deleted file mode 100644 index 4f51369e1f..0000000000 --- a/vendor/github.com/ccojocar/zxcvbn-go/frequency/frequency.go +++ /dev/null @@ -1,50 +0,0 @@ -package frequency - -import ( - "encoding/json" - "log" - - "github.com/ccojocar/zxcvbn-go/data" -) - -// List holds a frequency list -type List struct { - Name string - List []string -} - -// Lists holds all the frequency list in a map -var Lists = make(map[string]List) - -func init() { - maleFilePath := getAsset("data/MaleNames.json") - femaleFilePath := getAsset("data/FemaleNames.json") - surnameFilePath := getAsset("data/Surnames.json") - englishFilePath := getAsset("data/English.json") - passwordsFilePath := getAsset("data/Passwords.json") - - Lists["MaleNames"] = getStringListFromAsset(maleFilePath, "MaleNames") - Lists["FemaleNames"] = getStringListFromAsset(femaleFilePath, "FemaleNames") - Lists["Surname"] = getStringListFromAsset(surnameFilePath, "Surname") - Lists["English"] = getStringListFromAsset(englishFilePath, "English") - Lists["Passwords"] = getStringListFromAsset(passwordsFilePath, "Passwords") -} - -func getAsset(name string) []byte { - data, err := data.Asset(name) - if err != nil { - panic("Error getting asset " + name) - } - - return data -} - -func getStringListFromAsset(data []byte, name string) List { - var tempList List - err := json.Unmarshal(data, &tempList) - if err != nil { - log.Fatal(err) - } - tempList.Name = name - return tempList -} diff --git a/vendor/github.com/ccojocar/zxcvbn-go/match/match.go b/vendor/github.com/ccojocar/zxcvbn-go/match/match.go deleted file mode 100644 index da3e894ece..0000000000 --- a/vendor/github.com/ccojocar/zxcvbn-go/match/match.go +++ /dev/null @@ -1,45 +0,0 @@ -package match - -// Matches is an alies for []Match used for sorting -type Matches []Match - -func (s Matches) Len() int { - return len(s) -} - -func (s Matches) Swap(i, j int) { - s[i], s[j] = s[j], s[i] -} - -func (s Matches) Less(i, j int) bool { - if s[i].I < s[j].I { - return true - } else if s[i].I == s[j].I { - return s[i].J < s[j].J - } - return false -} - -// Match represents different matches -type Match struct { - Pattern string - I, J int - Token string - DictionaryName string - Entropy float64 -} - -// DateMatch is specifilly a match for type date -type DateMatch struct { - Pattern string - I, J int - Token string - Separator string - Day, Month, Year int64 -} - -// Matcher are a func and ID that can be used to match different passwords -type Matcher struct { - MatchingFunc func(password string) []Match - ID string -} diff --git a/vendor/github.com/ccojocar/zxcvbn-go/matching/dateMatchers.go b/vendor/github.com/ccojocar/zxcvbn-go/matching/dateMatchers.go deleted file mode 100644 index c3829c925d..0000000000 --- a/vendor/github.com/ccojocar/zxcvbn-go/matching/dateMatchers.go +++ /dev/null @@ -1,207 +0,0 @@ -package matching - -import ( - "regexp" - "strconv" - "strings" - - "github.com/ccojocar/zxcvbn-go/entropy" - "github.com/ccojocar/zxcvbn-go/match" -) - -const ( - dateSepMatcherName = "DATESEP" - dateWithOutSepMatcherName = "DATEWITHOUT" -) - -var ( - dateRxYearSuffix = regexp.MustCompile(`((\d{1,2})(\s|-|\/|\\|_|\.)(\d{1,2})(\s|-|\/|\\|_|\.)(19\d{2}|200\d|201\d|\d{2}))`) - dateRxYearPrefix = regexp.MustCompile(`((19\d{2}|200\d|201\d|\d{2})(\s|-|/|\\|_|\.)(\d{1,2})(\s|-|/|\\|_|\.)(\d{1,2}))`) - dateWithOutSepMatch = regexp.MustCompile(`\d{4,8}`) -) - -// FilterDateSepMatcher can be pass to zxcvbn-go.PasswordStrength to skip that matcher -func FilterDateSepMatcher(m match.Matcher) bool { - return m.ID == dateSepMatcherName -} - -// FilterDateWithoutSepMatcher can be pass to zxcvbn-go.PasswordStrength to skip that matcher -func FilterDateWithoutSepMatcher(m match.Matcher) bool { - return m.ID == dateWithOutSepMatcherName -} - -func checkDate(day, month, year int64) (bool, int64, int64, int64) { - if (12 <= month && month <= 31) && day <= 12 { - day, month = month, day - } - - if day > 31 || month > 12 { - return false, 0, 0, 0 - } - - //nolint:staticcheck // Ignore De Morgan's law optimization - if !((1900 <= year && year <= 2025) || (0 <= year && year <= 99)) { - return false, 0, 0, 0 - } - - return true, day, month, year -} - -func dateSepMatcher(password string) []match.Match { - dateMatches := dateSepMatchHelper(password) - - var matches []match.Match - for _, dateMatch := range dateMatches { - match := match.Match{ - I: dateMatch.I, - J: dateMatch.J, - Entropy: entropy.DateEntropy(dateMatch), - DictionaryName: "date_match", - Token: dateMatch.Token, - } - - matches = append(matches, match) - } - - return matches -} - -func dateSepMatchHelper(password string) []match.DateMatch { - var matches []match.DateMatch - - for _, v := range dateRxYearSuffix.FindAllString(password, len(password)) { - splitV := dateRxYearSuffix.FindAllStringSubmatch(v, len(v)) - i := strings.Index(password, v) - j := i + len(v) - day, _ := strconv.ParseInt(splitV[0][4], 10, 16) - month, _ := strconv.ParseInt(splitV[0][2], 10, 16) - year, _ := strconv.ParseInt(splitV[0][6], 10, 16) - match := match.DateMatch{Day: day, Month: month, Year: year, Separator: splitV[0][5], I: i, J: j, Token: password[i:j]} - matches = append(matches, match) - } - - for _, v := range dateRxYearPrefix.FindAllString(password, len(password)) { - splitV := dateRxYearPrefix.FindAllStringSubmatch(v, len(v)) - i := strings.Index(password, v) - j := i + len(v) - day, _ := strconv.ParseInt(splitV[0][4], 10, 16) - month, _ := strconv.ParseInt(splitV[0][6], 10, 16) - year, _ := strconv.ParseInt(splitV[0][2], 10, 16) - match := match.DateMatch{Day: day, Month: month, Year: year, Separator: splitV[0][5], I: i, J: j, Token: password[i:j]} - matches = append(matches, match) - } - - var out []match.DateMatch - for _, match := range matches { - if valid, day, month, year := checkDate(match.Day, match.Month, match.Year); valid { - match.Pattern = "date" - match.Day = day - match.Month = month - match.Year = year - out = append(out, match) - } - } - return out -} - -type dateMatchCandidate struct { - DayMonth string - Year string - I, J int -} - -type dateMatchCandidateTwo struct { - Day string - Month string - Year string - I, J int -} - -func dateWithoutSepMatch(password string) []match.Match { - dateMatches := dateWithoutSepMatchHelper(password) - - var matches []match.Match - for _, dateMatch := range dateMatches { - match := match.Match{ - I: dateMatch.I, - J: dateMatch.J, - Entropy: entropy.DateEntropy(dateMatch), - DictionaryName: "date_match", - Token: dateMatch.Token, - } - - matches = append(matches, match) - } - - return matches -} - -// TODO Has issues with 6 digit dates -func dateWithoutSepMatchHelper(password string) (matches []match.DateMatch) { - for _, v := range dateWithOutSepMatch.FindAllString(password, len(password)) { - i := strings.Index(password, v) - j := i + len(v) - length := len(v) - lastIndex := length - 1 - var candidatesRoundOne []dateMatchCandidate - - if length <= 6 { - // 2-digit year prefix - candidatesRoundOne = append(candidatesRoundOne, buildDateMatchCandidate(v[2:], v[0:2], i, j)) - - // 2-digityear suffix - candidatesRoundOne = append(candidatesRoundOne, buildDateMatchCandidate(v[0:lastIndex-2], v[lastIndex-2:], i, j)) - } - if length >= 6 { - // 4-digit year prefix - candidatesRoundOne = append(candidatesRoundOne, buildDateMatchCandidate(v[4:], v[0:4], i, j)) - - // 4-digit year sufix - candidatesRoundOne = append(candidatesRoundOne, buildDateMatchCandidate(v[0:lastIndex-3], v[lastIndex-3:], i, j)) - } - - var candidatesRoundTwo []dateMatchCandidateTwo - for _, c := range candidatesRoundOne { - if len(c.DayMonth) == 2 { - candidatesRoundTwo = append(candidatesRoundTwo, buildDateMatchCandidateTwo(c.DayMonth[0:0], c.DayMonth[1:1], c.Year, c.I, c.J)) - } else if len(c.DayMonth) == 3 { - candidatesRoundTwo = append(candidatesRoundTwo, buildDateMatchCandidateTwo(c.DayMonth[0:2], c.DayMonth[2:2], c.Year, c.I, c.J)) - candidatesRoundTwo = append(candidatesRoundTwo, buildDateMatchCandidateTwo(c.DayMonth[0:0], c.DayMonth[1:3], c.Year, c.I, c.J)) - } else if len(c.DayMonth) == 4 { - candidatesRoundTwo = append(candidatesRoundTwo, buildDateMatchCandidateTwo(c.DayMonth[0:2], c.DayMonth[2:4], c.Year, c.I, c.J)) - } - } - - for _, candidate := range candidatesRoundTwo { - intDay, err := strconv.ParseInt(candidate.Day, 10, 16) - if err != nil { - continue - } - - intMonth, err := strconv.ParseInt(candidate.Month, 10, 16) - if err != nil { - continue - } - - intYear, err := strconv.ParseInt(candidate.Year, 10, 16) - if err != nil { - continue - } - - if ok, _, _, _ := checkDate(intDay, intMonth, intYear); ok { - matches = append(matches, match.DateMatch{Token: password, Pattern: "date", Day: intDay, Month: intMonth, Year: intYear, I: i, J: j}) - } - - } - } - - return matches -} - -func buildDateMatchCandidate(dayMonth, year string, i, j int) dateMatchCandidate { - return dateMatchCandidate{DayMonth: dayMonth, Year: year, I: i, J: j} -} - -func buildDateMatchCandidateTwo(day, month string, year string, i, j int) dateMatchCandidateTwo { - return dateMatchCandidateTwo{Day: day, Month: month, Year: year, I: i, J: j} -} diff --git a/vendor/github.com/ccojocar/zxcvbn-go/matching/dictionaryMatch.go b/vendor/github.com/ccojocar/zxcvbn-go/matching/dictionaryMatch.go deleted file mode 100644 index d0d4501880..0000000000 --- a/vendor/github.com/ccojocar/zxcvbn-go/matching/dictionaryMatch.go +++ /dev/null @@ -1,56 +0,0 @@ -package matching - -import ( - "strings" - - "github.com/ccojocar/zxcvbn-go/entropy" - "github.com/ccojocar/zxcvbn-go/match" -) - -func buildDictMatcher(dictName string, rankedDict map[string]int) func(password string) []match.Match { - return func(password string) []match.Match { - matches := dictionaryMatch(password, dictName, rankedDict) - for _, v := range matches { - v.DictionaryName = dictName - } - return matches - } -} - -func dictionaryMatch(password string, dictionaryName string, rankedDict map[string]int) []match.Match { - var results []match.Match - pwLower := strings.ToLower(password) - - pwLowerRunes := []rune(pwLower) - length := len(pwLowerRunes) - - for i := 0; i < length; i++ { - for j := i; j < length; j++ { - word := pwLowerRunes[i : j+1] - if val, ok := rankedDict[string(word)]; ok { - matchDic := match.Match{ - Pattern: "dictionary", - DictionaryName: dictionaryName, - I: i, - J: j, - Token: string([]rune(password)[i : j+1]), - } - matchDic.Entropy = entropy.DictionaryEntropy(matchDic, float64(val)) - - results = append(results, matchDic) - } - } - } - - return results -} - -func buildRankedDict(unrankedList []string) map[string]int { - result := make(map[string]int) - - for i, v := range unrankedList { - result[strings.ToLower(v)] = i + 1 - } - - return result -} diff --git a/vendor/github.com/ccojocar/zxcvbn-go/matching/leet.go b/vendor/github.com/ccojocar/zxcvbn-go/matching/leet.go deleted file mode 100644 index f7fd30420f..0000000000 --- a/vendor/github.com/ccojocar/zxcvbn-go/matching/leet.go +++ /dev/null @@ -1,234 +0,0 @@ -package matching - -import ( - "strings" - - "github.com/ccojocar/zxcvbn-go/entropy" - "github.com/ccojocar/zxcvbn-go/match" -) - -// L33TMatcherName id -const L33TMatcherName = "l33t" - -// FilterL33tMatcher can be pass to zxcvbn-go.PasswordStrength to skip that matcher -func FilterL33tMatcher(m match.Matcher) bool { - return m.ID == L33TMatcherName -} - -func l33tMatch(password string) []match.Match { - permutations := getPermutations(password) - - var matches []match.Match - - for _, permutation := range permutations { - for _, mather := range dictionaryMatchers { - matches = append(matches, mather.MatchingFunc(permutation)...) - } - } - - for _, match := range matches { - match.Entropy += entropy.ExtraLeetEntropy(match, password) - match.DictionaryName = match.DictionaryName + "_3117" - } - - return matches -} - -// This function creates a list of permutations based on a fixed table stored on data. The table -// will be reduced in order to proceed in the function using only relevant values (see -// relevantL33tSubtable). -func getPermutations(password string) []string { - substitutions := relevantL33tSubtable(password) - permutations := getAllPermutationsOfLeetSubstitutions(password, substitutions) - return permutations -} - -// This function loads the table from data but only keep in memory the values that are present -// inside the provided password. -func relevantL33tSubtable(password string) map[string][]string { - relevantSubs := make(map[string][]string) - for key, values := range l33tTable.Graph { - for _, value := range values { - if strings.Contains(password, value) { - relevantSubs[key] = append(relevantSubs[key], value) - } - } - } - - return relevantSubs -} - -// This function creates the list of permutations of a given password using the provided table as -// reference for its operation. -func getAllPermutationsOfLeetSubstitutions(password string, table map[string][]string) []string { - result := []string{} - - // create a list of tables without conflicting keys/values (this happens for "|", "7" and "1") - noConflictsTables := createListOfMapsWithoutConflicts(table) - for _, noConflictsTable := range noConflictsTables { - substitutionsMaps := createSubstitutionsMapsFromTable(noConflictsTable) - for _, substitutionsMap := range substitutionsMaps { - newValue := createWordForSubstitutionMap(password, substitutionsMap) - if !stringSliceContainsValue(result, newValue) { - result = append(result, newValue) - } - } - } - - return result -} - -// Create the possible list of maps removing the conflicts from it. As an example, the value "|" -// may represent "i" and "l". For each representation of the conflicting value, a new map is -// created. This may grow exponencialy according to the number of conflicts. The number of maps -// returned by this function may be reduced if the relevantL33tSubtable function was called to -// identify only relevant items. -func createListOfMapsWithoutConflicts(table map[string][]string) []map[string][]string { - // the resulting list starts with the provided table - result := []map[string][]string{} - result = append(result, table) - - // iterate over the list of conflicts in order to expand the maps for each one - conflicts := retrieveConflictsListFromTable(table) - for _, value := range conflicts { - newMapList := []map[string][]string{} - - // for each conflict a new list of maps will be created for every already known map - for _, currentMap := range result { - newMaps := createDifferentMapsForLeetChar(currentMap, value) - newMapList = append(newMapList, newMaps...) - } - - result = newMapList - } - - return result -} - -// This function retrieves the list of values that appear for one or more keys. This is useful to -// know which l33t chars can represent more than one letter. -func retrieveConflictsListFromTable(table map[string][]string) []string { - result := []string{} - foundValues := []string{} - - for _, values := range table { - for _, value := range values { - if stringSliceContainsValue(foundValues, value) { - // only add on results if it was not identified as conflict before - if !stringSliceContainsValue(result, value) { - result = append(result, value) - } - } else { - foundValues = append(foundValues, value) - } - } - } - - return result -} - -// This function aims to create different maps for a given char if this char represents a conflict. -// If the specified char is not a conflict one, the same map will be returned. In scenarios which -// the provided char can not be found on map, an empty list will be returned. This function was -// designed to be used on conflicts situations. -func createDifferentMapsForLeetChar(table map[string][]string, leetChar string) []map[string][]string { - result := []map[string][]string{} - - keysWithSameValue := retrieveListOfKeysWithSpecificValueFromTable(table, leetChar) - for _, key := range keysWithSameValue { - newMap := copyMapRemovingSameValueFromOtherKeys(table, key, leetChar) - result = append(result, newMap) - } - - return result -} - -// This function retrieves the list of keys that can be represented using the given value. -func retrieveListOfKeysWithSpecificValueFromTable(table map[string][]string, valueToFind string) []string { - result := []string{} - - for key, values := range table { - for _, value := range values { - if value == valueToFind && !stringSliceContainsValue(result, key) { - result = append(result, key) - } - } - } - - return result -} - -// This function returns a list of substitution map from a given table. Each map in the result will -// provide only one representation for each value. As an example, if the provided map contains the -// values "@" and "4" in the possibilities to represent "a", two maps will be created where one -// will contain "a" mapping to "@" and the other one will provide "a" mapping to "4". -func createSubstitutionsMapsFromTable(table map[string][]string) []map[string]string { - result := []map[string]string{{"": ""}} - - for key, values := range table { - newResult := []map[string]string{} - - for _, mapInCurrentResult := range result { - for _, value := range values { - newMapForValue := copyMap(mapInCurrentResult) - newMapForValue[key] = value - newResult = append(newResult, newMapForValue) - } - } - - result = newResult - } - - // verification to make sure that the slice was filled - if len(result) == 1 && len(result[0]) == 1 && result[0][""] == "" { - return []map[string]string{} - } - - return result -} - -// This function replaces the values provided on substitution map over the provided word. -func createWordForSubstitutionMap(word string, substitutionMap map[string]string) string { - result := word - for key, value := range substitutionMap { - result = strings.ReplaceAll(result, value, key) - } - - return result -} - -func stringSliceContainsValue(slice []string, value string) bool { - for _, valueInSlice := range slice { - if valueInSlice == value { - return true - } - } - - return false -} - -func copyMap(table map[string]string) map[string]string { - result := make(map[string]string) - - for key, value := range table { - result[key] = value - } - - return result -} - -// This function creates a new map based on the one provided but excluding possible representations -// of the same value on other keys. -func copyMapRemovingSameValueFromOtherKeys(table map[string][]string, keyToFix string, valueToFix string) map[string][]string { - result := make(map[string][]string) - - for key, values := range table { - for _, value := range values { - if value != valueToFix || key == keyToFix { - result[key] = append(result[key], value) - } - } - } - - return result -} diff --git a/vendor/github.com/ccojocar/zxcvbn-go/matching/matching.go b/vendor/github.com/ccojocar/zxcvbn-go/matching/matching.go deleted file mode 100644 index c6948067bc..0000000000 --- a/vendor/github.com/ccojocar/zxcvbn-go/matching/matching.go +++ /dev/null @@ -1,79 +0,0 @@ -package matching - -import ( - "sort" - - "github.com/ccojocar/zxcvbn-go/adjacency" - "github.com/ccojocar/zxcvbn-go/frequency" - "github.com/ccojocar/zxcvbn-go/match" -) - -var ( - dictionaryMatchers []match.Matcher - matchers []match.Matcher - adjacencyGraphs []adjacency.Graph - l33tTable adjacency.Graph - - sequences map[string]string -) - -func init() { - loadFrequencyList() -} - -// Omnimatch runs all matchers against the password -func Omnimatch(password string, userInputs []string, filters ...func(match.Matcher) bool) (matches []match.Match) { - // Can I run into the issue where nil is not equal to nil? - if dictionaryMatchers == nil || adjacencyGraphs == nil { - loadFrequencyList() - } - - if userInputs != nil { - userInputMatcher := buildDictMatcher("user_inputs", buildRankedDict(userInputs)) - matches = userInputMatcher(password) - } - - for _, matcher := range matchers { - shouldBeFiltered := false - for i := range filters { - if filters[i](matcher) { - shouldBeFiltered = true - break - } - } - if !shouldBeFiltered { - matches = append(matches, matcher.MatchingFunc(password)...) - } - } - sort.Sort(match.Matches(matches)) - return matches -} - -func loadFrequencyList() { - for n, list := range frequency.Lists { - dictionaryMatchers = append(dictionaryMatchers, match.Matcher{MatchingFunc: buildDictMatcher(n, buildRankedDict(list.List)), ID: n}) - } - - l33tTable = adjacency.GraphMap["l33t"] - - adjacencyGraphs = append(adjacencyGraphs, adjacency.GraphMap["qwerty"]) - adjacencyGraphs = append(adjacencyGraphs, adjacency.GraphMap["dvorak"]) - adjacencyGraphs = append(adjacencyGraphs, adjacency.GraphMap["keypad"]) - adjacencyGraphs = append(adjacencyGraphs, adjacency.GraphMap["macKeypad"]) - - // l33tFilePath, _ := filepath.Abs("adjacency/L33t.json") - // L33T_TABLE = adjacency.GetAdjancencyGraphFromFile(l33tFilePath, "l33t") - - sequences = make(map[string]string) - sequences["lower"] = "abcdefghijklmnopqrstuvwxyz" - sequences["upper"] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - sequences["digits"] = "0123456789" - - matchers = append(matchers, dictionaryMatchers...) - matchers = append(matchers, match.Matcher{MatchingFunc: spatialMatch, ID: spatialMatcherName}) - matchers = append(matchers, match.Matcher{MatchingFunc: repeatMatch, ID: repeatMatcherName}) - matchers = append(matchers, match.Matcher{MatchingFunc: sequenceMatch, ID: sequenceMatcherName}) - matchers = append(matchers, match.Matcher{MatchingFunc: l33tMatch, ID: L33TMatcherName}) - matchers = append(matchers, match.Matcher{MatchingFunc: dateSepMatcher, ID: dateSepMatcherName}) - matchers = append(matchers, match.Matcher{MatchingFunc: dateWithoutSepMatch, ID: dateWithOutSepMatcherName}) -} diff --git a/vendor/github.com/ccojocar/zxcvbn-go/matching/repeatMatch.go b/vendor/github.com/ccojocar/zxcvbn-go/matching/repeatMatch.go deleted file mode 100644 index d52ba4254b..0000000000 --- a/vendor/github.com/ccojocar/zxcvbn-go/matching/repeatMatch.go +++ /dev/null @@ -1,68 +0,0 @@ -package matching - -import ( - "strings" - - "github.com/ccojocar/zxcvbn-go/entropy" - "github.com/ccojocar/zxcvbn-go/match" -) - -const repeatMatcherName = "REPEAT" - -// FilterRepeatMatcher can be pass to zxcvbn-go.PasswordStrength to skip that matcher -func FilterRepeatMatcher(m match.Matcher) bool { - return m.ID == repeatMatcherName -} - -func repeatMatch(password string) []match.Match { - var matches []match.Match - - // Loop through password. if current == prev currentStreak++ else if currentStreak > 2 {buildMatch; currentStreak = 1} prev = current - var current, prev string - currentStreak := 1 - var i int - var char rune - for i, char = range password { - current = string(char) - if i == 0 { - prev = current - continue - } - - if strings.EqualFold(current, prev) { - currentStreak++ - } else if currentStreak > 2 { - iPos := i - currentStreak - jPos := i - 1 - matchRepeat := match.Match{ - Pattern: "repeat", - I: iPos, - J: jPos, - Token: password[iPos : jPos+1], - DictionaryName: prev, - } - matchRepeat.Entropy = entropy.RepeatEntropy(matchRepeat) - matches = append(matches, matchRepeat) - currentStreak = 1 - } else { - currentStreak = 1 - } - - prev = current - } - - if currentStreak > 2 { - iPos := i - currentStreak + 1 - jPos := i - matchRepeat := match.Match{ - Pattern: "repeat", - I: iPos, - J: jPos, - Token: password[iPos : jPos+1], - DictionaryName: prev, - } - matchRepeat.Entropy = entropy.RepeatEntropy(matchRepeat) - matches = append(matches, matchRepeat) - } - return matches -} diff --git a/vendor/github.com/ccojocar/zxcvbn-go/matching/sequenceMatch.go b/vendor/github.com/ccojocar/zxcvbn-go/matching/sequenceMatch.go deleted file mode 100644 index 6971945838..0000000000 --- a/vendor/github.com/ccojocar/zxcvbn-go/matching/sequenceMatch.go +++ /dev/null @@ -1,74 +0,0 @@ -package matching - -import ( - "strings" - - "github.com/ccojocar/zxcvbn-go/entropy" - "github.com/ccojocar/zxcvbn-go/match" -) - -const sequenceMatcherName = "SEQ" - -// FilterSequenceMatcher can be pass to zxcvbn-go.PasswordStrength to skip that matcher -func FilterSequenceMatcher(m match.Matcher) bool { - return m.ID == sequenceMatcherName -} - -func sequenceMatch(password string) []match.Match { - var matches []match.Match - for i := 0; i < len(password); { - j := i + 1 - var seq string - var seqName string - seqDirection := 0 - for seqCandidateName, seqCandidate := range sequences { - iN := strings.Index(seqCandidate, string(password[i])) - var jN int - if j < len(password) { - jN = strings.Index(seqCandidate, string(password[j])) - } else { - jN = -1 - } - - if iN > -1 && jN > -1 { - direction := jN - iN - if direction == 1 || direction == -1 { - seq = seqCandidate - seqName = seqCandidateName - seqDirection = direction - break - } - } - - } - - if seq != "" { - for { - var prevN, curN int - if j < len(password) { - prevChar, curChar := password[j-1], password[j] - prevN, curN = strings.Index(seq, string(prevChar)), strings.Index(seq, string(curChar)) - } - - if j == len(password) || curN-prevN != seqDirection { - if j-i > 2 { - matchSequence := match.Match{ - Pattern: "sequence", - I: i, - J: j - 1, - Token: password[i:j], - DictionaryName: seqName, - } - - matchSequence.Entropy = entropy.SequenceEntropy(matchSequence, len(seq), (seqDirection == 1)) - matches = append(matches, matchSequence) - } - break - } - j++ - } - } - i = j - } - return matches -} diff --git a/vendor/github.com/ccojocar/zxcvbn-go/matching/spatialMatch.go b/vendor/github.com/ccojocar/zxcvbn-go/matching/spatialMatch.go deleted file mode 100644 index 101ccea5e5..0000000000 --- a/vendor/github.com/ccojocar/zxcvbn-go/matching/spatialMatch.go +++ /dev/null @@ -1,87 +0,0 @@ -package matching - -import ( - "strings" - - "github.com/ccojocar/zxcvbn-go/adjacency" - "github.com/ccojocar/zxcvbn-go/entropy" - "github.com/ccojocar/zxcvbn-go/match" -) - -const spatialMatcherName = "SPATIAL" - -// FilterSpatialMatcher can be pass to zxcvbn-go.PasswordStrength to skip that matcher -func FilterSpatialMatcher(m match.Matcher) bool { - return m.ID == spatialMatcherName -} - -func spatialMatch(password string) (matches []match.Match) { - for _, graph := range adjacencyGraphs { - if graph.Graph != nil { - matches = append(matches, spatialMatchHelper(password, graph)...) - } - } - return matches -} - -func spatialMatchHelper(password string, graph adjacency.Graph) (matches []match.Match) { - for i := 0; i < len(password)-1; { - j := i + 1 - lastDirection := -99 // an int that it should never be! - turns := 0 - shiftedCount := 0 - - for { - prevChar := password[j-1] - found := false - var foundDirection int - curDirection := -1 - // My graphs seem to be wrong. . . and where the hell is qwerty - adjacents := graph.Graph[string(prevChar)] - // Consider growing pattern by one character if j hasn't gone over the edge - if j < len(password) { - curChar := password[j] - for _, adj := range adjacents { - curDirection++ - - if strings.Contains(adj, string(curChar)) { - found = true - foundDirection = curDirection - - if strings.Index(adj, string(curChar)) == 1 { - // index 1 in the adjacency means the key is shifted, 0 means unshifted: A vs a, % vs 5, etc. - // for example, 'q' is adjacent to the entry '2@'. @ is shifted w/ index 1, 2 is unshifted. - shiftedCount++ - } - - if lastDirection != foundDirection { - // adding a turn is correct even in the initial case when last_direction is null: - // every spatial pattern starts with a turn. - turns++ - lastDirection = foundDirection - } - break - } - } - } - - // if the current pattern continued, extend j and try to grow again - if found { - j++ - } else { - // otherwise push the pattern discovered so far, if any... - // don't consider length 1 or 2 chains. - if j-i > 2 { - matchSpc := match.Match{Pattern: "spatial", I: i, J: j - 1, Token: password[i:j], DictionaryName: graph.Name} - matchSpc.Entropy = entropy.SpatialEntropy(matchSpc, turns, shiftedCount) - matches = append(matches, matchSpc) - } - //. . . and then start a new search from the rest of the password - i = j - break - } - } - - } - return matches -} diff --git a/vendor/github.com/ccojocar/zxcvbn-go/renovate.json b/vendor/github.com/ccojocar/zxcvbn-go/renovate.json deleted file mode 100644 index 58ee1e0ea8..0000000000 --- a/vendor/github.com/ccojocar/zxcvbn-go/renovate.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "dependencyDashboard": true, - "dependencyDashboardTitle" : "Renovate(bot) : dependency dashboard", - "vulnerabilityAlerts": { - "enabled": true - }, - "extends": [ - ":preserveSemverRanges", - "group:all", - "schedule:weekly" - ], - "lockFileMaintenance": { - "commitMessageAction": "Update", - "enabled": true, - "extends": [ - "group:all", - "schedule:weekly" - ] - }, - "postUpdateOptions": [ - "gomodTidy", - "gomodUpdateImportPaths" - ], - "separateMajorMinor": false -} diff --git a/vendor/github.com/ccojocar/zxcvbn-go/scoring/scoring.go b/vendor/github.com/ccojocar/zxcvbn-go/scoring/scoring.go deleted file mode 100644 index 7154025a9d..0000000000 --- a/vendor/github.com/ccojocar/zxcvbn-go/scoring/scoring.go +++ /dev/null @@ -1,180 +0,0 @@ -package scoring - -import ( - "fmt" - "math" - "sort" - - "github.com/ccojocar/zxcvbn-go/entropy" - "github.com/ccojocar/zxcvbn-go/match" - zxcvbnmath "github.com/ccojocar/zxcvbn-go/utils/math" -) - -const ( - //for a hash function like bcrypt/scrypt/PBKDF2, 10ms per guess is a safe lower bound. - //(usually a guess would take longer -- this assumes fast hardware and a small work factor.) - //adjust for your site accordingly if you use another hash function, possibly by - //several orders of magnitude! - singleGuess float64 = 0.010 - numAttackers float64 = 100 // Cores used to make guesses - secondsPerGuess float64 = singleGuess / numAttackers -) - -// MinEntropyMatch is the lowest entropy match found -type MinEntropyMatch struct { - Password string - Entropy float64 - MatchSequence []match.Match - CrackTime float64 - CrackTimeDisplay string - Score int - CalcTime float64 -} - -/* -MinimumEntropyMatchSequence returns the minimum entropy - - Takes a list of overlapping matches, returns the non-overlapping sublist with - minimum entropy. O(nm) dp alg for length-n password with m candidate matches. -*/ -func MinimumEntropyMatchSequence(password string, matches []match.Match) MinEntropyMatch { - bruteforceCardinality := entropy.CalcBruteForceCardinality(password) - upToK := make([]float64, len(password)) - backPointers := make([]match.Match, len(password)) - - for k := 0; k < len(password); k++ { - upToK[k] = get(upToK, k-1) + math.Log2(bruteforceCardinality) - - for _, match := range matches { - if match.J != k { - continue - } - - i, j := match.I, match.J - // see if best entropy up to i-1 + entropy of match is less that current min at j - upTo := get(upToK, i-1) - candidateEntropy := upTo + match.Entropy - - if candidateEntropy < upToK[j] { - upToK[j] = candidateEntropy - match.Entropy = candidateEntropy - backPointers[j] = match - } - } - } - - // walk backwards and decode the best sequence - var matchSequence []match.Match - passwordLen := len(password) - passwordLen-- - for k := passwordLen; k >= 0; { - match := backPointers[k] - if match.Pattern != "" { - matchSequence = append(matchSequence, match) - k = match.I - 1 - - } else { - k-- - } - - } - sort.Sort(match.Matches(matchSequence)) - - makeBruteForceMatch := func(i, j int) match.Match { - return match.Match{ - Pattern: "bruteforce", - I: i, - J: j, - Token: password[i : j+1], - Entropy: math.Log2(math.Pow(bruteforceCardinality, float64(j-i))), - } - } - - k := 0 - var matchSequenceCopy []match.Match - for _, match := range matchSequence { - i, j := match.I, match.J - if i-k > 0 { - matchSequenceCopy = append(matchSequenceCopy, makeBruteForceMatch(k, i-1)) - } - k = j + 1 - matchSequenceCopy = append(matchSequenceCopy, match) - } - - if k < len(password) { - matchSequenceCopy = append(matchSequenceCopy, makeBruteForceMatch(k, len(password)-1)) - } - var minEntropy float64 - if len(password) == 0 { - minEntropy = float64(0) - } else { - minEntropy = upToK[len(password)-1] - } - - crackTime := roundToXDigits(entropyToCrackTime(minEntropy), 3) - return MinEntropyMatch{ - Password: password, - Entropy: roundToXDigits(minEntropy, 3), - MatchSequence: matchSequenceCopy, - CrackTime: crackTime, - CrackTimeDisplay: displayTime(crackTime), - Score: crackTimeToScore(crackTime), - } -} - -func get(a []float64, i int) float64 { - if i < 0 || i >= len(a) { - return float64(0) - } - - return a[i] -} - -func entropyToCrackTime(entropy float64) float64 { - crackTime := (0.5 * math.Pow(float64(2), entropy)) * secondsPerGuess - - return crackTime -} - -func roundToXDigits(number float64, digits int) float64 { - return zxcvbnmath.Round(number, .5, digits) -} - -func displayTime(seconds float64) string { - formater := "%.1f %s" - minute := float64(60) - hour := minute * float64(60) - day := hour * float64(24) - month := day * float64(31) - year := month * float64(12) - century := year * float64(100) - - if seconds < minute { - return "instant" - } else if seconds < hour { - return fmt.Sprintf(formater, (1 + math.Ceil(seconds/minute)), "minutes") - } else if seconds < day { - return fmt.Sprintf(formater, (1 + math.Ceil(seconds/hour)), "hours") - } else if seconds < month { - return fmt.Sprintf(formater, (1 + math.Ceil(seconds/day)), "days") - } else if seconds < year { - return fmt.Sprintf(formater, (1 + math.Ceil(seconds/month)), "months") - } else if seconds < century { - return fmt.Sprintf(formater, (1 + math.Ceil(seconds/century)), "years") - } - return "centuries" -} - -func crackTimeToScore(seconds float64) int { - if seconds < 100 { - return 0 - } else if seconds < math.Pow(10, 4) { - return 1 - } else if seconds < math.Pow(10, 6) { - return 2 - } else if seconds < math.Pow(10, 8) { - return 3 - } - - return 4 -} diff --git a/vendor/github.com/ccojocar/zxcvbn-go/utils/math/mathutils.go b/vendor/github.com/ccojocar/zxcvbn-go/utils/math/mathutils.go deleted file mode 100644 index 1b989d194d..0000000000 --- a/vendor/github.com/ccojocar/zxcvbn-go/utils/math/mathutils.go +++ /dev/null @@ -1,40 +0,0 @@ -package zxcvbnmath - -import "math" - -/* -NChoseK http://blog.plover.com/math/choose.html -I am surprised that I have to define these. . . Maybe i just didn't look hard enough for a lib. -*/ -func NChoseK(n, k float64) float64 { - if k > n { - return 0 - } else if k == 0 { - return 1 - } - - var r float64 = 1 - - for d := float64(1); d <= k; d++ { - r *= n - r /= d - n-- - } - - return r -} - -// Round a number -func Round(val float64, roundOn float64, places int) (newVal float64) { - var round float64 - pow := math.Pow(10, float64(places)) - digit := pow * val - _, div := math.Modf(digit) - if div >= roundOn { - round = math.Ceil(digit) - } else { - round = math.Floor(digit) - } - newVal = round / pow - return -} diff --git a/vendor/github.com/ccojocar/zxcvbn-go/zxcvbn.go b/vendor/github.com/ccojocar/zxcvbn-go/zxcvbn.go deleted file mode 100644 index f3dc19e4c5..0000000000 --- a/vendor/github.com/ccojocar/zxcvbn-go/zxcvbn.go +++ /dev/null @@ -1,22 +0,0 @@ -package zxcvbn - -import ( - "time" - - "github.com/ccojocar/zxcvbn-go/match" - "github.com/ccojocar/zxcvbn-go/matching" - "github.com/ccojocar/zxcvbn-go/scoring" - zxcvbnmath "github.com/ccojocar/zxcvbn-go/utils/math" -) - -// PasswordStrength takes a password, userInputs and optional filters and returns a MinEntropyMatch -func PasswordStrength(password string, userInputs []string, filters ...func(match.Matcher) bool) scoring.MinEntropyMatch { - start := time.Now() - matches := matching.Omnimatch(password, userInputs, filters...) - result := scoring.MinimumEntropyMatchSequence(password, matches) - end := time.Now() - - calcTime := end.Nanosecond() - start.Nanosecond() - result.CalcTime = zxcvbnmath.Round(float64(calcTime)*time.Nanosecond.Seconds(), .5, 3) - return result -} diff --git a/vendor/github.com/cespare/xxhash/v2/LICENSE.txt b/vendor/github.com/cespare/xxhash/v2/LICENSE.txt deleted file mode 100644 index 24b53065f4..0000000000 --- a/vendor/github.com/cespare/xxhash/v2/LICENSE.txt +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2016 Caleb Spare - -MIT License - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/cespare/xxhash/v2/README.md b/vendor/github.com/cespare/xxhash/v2/README.md deleted file mode 100644 index 33c88305c4..0000000000 --- a/vendor/github.com/cespare/xxhash/v2/README.md +++ /dev/null @@ -1,74 +0,0 @@ -# xxhash - -[![Go Reference](https://pkg.go.dev/badge/github.com/cespare/xxhash/v2.svg)](https://pkg.go.dev/github.com/cespare/xxhash/v2) -[![Test](https://github.com/cespare/xxhash/actions/workflows/test.yml/badge.svg)](https://github.com/cespare/xxhash/actions/workflows/test.yml) - -xxhash is a Go implementation of the 64-bit [xxHash] algorithm, XXH64. This is a -high-quality hashing algorithm that is much faster than anything in the Go -standard library. - -This package provides a straightforward API: - -``` -func Sum64(b []byte) uint64 -func Sum64String(s string) uint64 -type Digest struct{ ... } - func New() *Digest -``` - -The `Digest` type implements hash.Hash64. Its key methods are: - -``` -func (*Digest) Write([]byte) (int, error) -func (*Digest) WriteString(string) (int, error) -func (*Digest) Sum64() uint64 -``` - -The package is written with optimized pure Go and also contains even faster -assembly implementations for amd64 and arm64. If desired, the `purego` build tag -opts into using the Go code even on those architectures. - -[xxHash]: http://cyan4973.github.io/xxHash/ - -## Compatibility - -This package is in a module and the latest code is in version 2 of the module. -You need a version of Go with at least "minimal module compatibility" to use -github.com/cespare/xxhash/v2: - -* 1.9.7+ for Go 1.9 -* 1.10.3+ for Go 1.10 -* Go 1.11 or later - -I recommend using the latest release of Go. - -## Benchmarks - -Here are some quick benchmarks comparing the pure-Go and assembly -implementations of Sum64. - -| input size | purego | asm | -| ---------- | --------- | --------- | -| 4 B | 1.3 GB/s | 1.2 GB/s | -| 16 B | 2.9 GB/s | 3.5 GB/s | -| 100 B | 6.9 GB/s | 8.1 GB/s | -| 4 KB | 11.7 GB/s | 16.7 GB/s | -| 10 MB | 12.0 GB/s | 17.3 GB/s | - -These numbers were generated on Ubuntu 20.04 with an Intel Xeon Platinum 8252C -CPU using the following commands under Go 1.19.2: - -``` -benchstat <(go test -tags purego -benchtime 500ms -count 15 -bench 'Sum64$') -benchstat <(go test -benchtime 500ms -count 15 -bench 'Sum64$') -``` - -## Projects using this package - -- [InfluxDB](https://github.com/influxdata/influxdb) -- [Prometheus](https://github.com/prometheus/prometheus) -- [VictoriaMetrics](https://github.com/VictoriaMetrics/VictoriaMetrics) -- [FreeCache](https://github.com/coocood/freecache) -- [FastCache](https://github.com/VictoriaMetrics/fastcache) -- [Ristretto](https://github.com/dgraph-io/ristretto) -- [Badger](https://github.com/dgraph-io/badger) diff --git a/vendor/github.com/cespare/xxhash/v2/testall.sh b/vendor/github.com/cespare/xxhash/v2/testall.sh deleted file mode 100644 index 94b9c44398..0000000000 --- a/vendor/github.com/cespare/xxhash/v2/testall.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash -set -eu -o pipefail - -# Small convenience script for running the tests with various combinations of -# arch/tags. This assumes we're running on amd64 and have qemu available. - -go test ./... -go test -tags purego ./... -GOARCH=arm64 go test -GOARCH=arm64 go test -tags purego diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash.go b/vendor/github.com/cespare/xxhash/v2/xxhash.go deleted file mode 100644 index 78bddf1cee..0000000000 --- a/vendor/github.com/cespare/xxhash/v2/xxhash.go +++ /dev/null @@ -1,243 +0,0 @@ -// Package xxhash implements the 64-bit variant of xxHash (XXH64) as described -// at http://cyan4973.github.io/xxHash/. -package xxhash - -import ( - "encoding/binary" - "errors" - "math/bits" -) - -const ( - prime1 uint64 = 11400714785074694791 - prime2 uint64 = 14029467366897019727 - prime3 uint64 = 1609587929392839161 - prime4 uint64 = 9650029242287828579 - prime5 uint64 = 2870177450012600261 -) - -// Store the primes in an array as well. -// -// The consts are used when possible in Go code to avoid MOVs but we need a -// contiguous array for the assembly code. -var primes = [...]uint64{prime1, prime2, prime3, prime4, prime5} - -// Digest implements hash.Hash64. -// -// Note that a zero-valued Digest is not ready to receive writes. -// Call Reset or create a Digest using New before calling other methods. -type Digest struct { - v1 uint64 - v2 uint64 - v3 uint64 - v4 uint64 - total uint64 - mem [32]byte - n int // how much of mem is used -} - -// New creates a new Digest with a zero seed. -func New() *Digest { - return NewWithSeed(0) -} - -// NewWithSeed creates a new Digest with the given seed. -func NewWithSeed(seed uint64) *Digest { - var d Digest - d.ResetWithSeed(seed) - return &d -} - -// Reset clears the Digest's state so that it can be reused. -// It uses a seed value of zero. -func (d *Digest) Reset() { - d.ResetWithSeed(0) -} - -// ResetWithSeed clears the Digest's state so that it can be reused. -// It uses the given seed to initialize the state. -func (d *Digest) ResetWithSeed(seed uint64) { - d.v1 = seed + prime1 + prime2 - d.v2 = seed + prime2 - d.v3 = seed - d.v4 = seed - prime1 - d.total = 0 - d.n = 0 -} - -// Size always returns 8 bytes. -func (d *Digest) Size() int { return 8 } - -// BlockSize always returns 32 bytes. -func (d *Digest) BlockSize() int { return 32 } - -// Write adds more data to d. It always returns len(b), nil. -func (d *Digest) Write(b []byte) (n int, err error) { - n = len(b) - d.total += uint64(n) - - memleft := d.mem[d.n&(len(d.mem)-1):] - - if d.n+n < 32 { - // This new data doesn't even fill the current block. - copy(memleft, b) - d.n += n - return - } - - if d.n > 0 { - // Finish off the partial block. - c := copy(memleft, b) - d.v1 = round(d.v1, u64(d.mem[0:8])) - d.v2 = round(d.v2, u64(d.mem[8:16])) - d.v3 = round(d.v3, u64(d.mem[16:24])) - d.v4 = round(d.v4, u64(d.mem[24:32])) - b = b[c:] - d.n = 0 - } - - if len(b) >= 32 { - // One or more full blocks left. - nw := writeBlocks(d, b) - b = b[nw:] - } - - // Store any remaining partial block. - copy(d.mem[:], b) - d.n = len(b) - - return -} - -// Sum appends the current hash to b and returns the resulting slice. -func (d *Digest) Sum(b []byte) []byte { - s := d.Sum64() - return append( - b, - byte(s>>56), - byte(s>>48), - byte(s>>40), - byte(s>>32), - byte(s>>24), - byte(s>>16), - byte(s>>8), - byte(s), - ) -} - -// Sum64 returns the current hash. -func (d *Digest) Sum64() uint64 { - var h uint64 - - if d.total >= 32 { - v1, v2, v3, v4 := d.v1, d.v2, d.v3, d.v4 - h = rol1(v1) + rol7(v2) + rol12(v3) + rol18(v4) - h = mergeRound(h, v1) - h = mergeRound(h, v2) - h = mergeRound(h, v3) - h = mergeRound(h, v4) - } else { - h = d.v3 + prime5 - } - - h += d.total - - b := d.mem[:d.n&(len(d.mem)-1)] - for ; len(b) >= 8; b = b[8:] { - k1 := round(0, u64(b[:8])) - h ^= k1 - h = rol27(h)*prime1 + prime4 - } - if len(b) >= 4 { - h ^= uint64(u32(b[:4])) * prime1 - h = rol23(h)*prime2 + prime3 - b = b[4:] - } - for ; len(b) > 0; b = b[1:] { - h ^= uint64(b[0]) * prime5 - h = rol11(h) * prime1 - } - - h ^= h >> 33 - h *= prime2 - h ^= h >> 29 - h *= prime3 - h ^= h >> 32 - - return h -} - -const ( - magic = "xxh\x06" - marshaledSize = len(magic) + 8*5 + 32 -) - -// MarshalBinary implements the encoding.BinaryMarshaler interface. -func (d *Digest) MarshalBinary() ([]byte, error) { - b := make([]byte, 0, marshaledSize) - b = append(b, magic...) - b = appendUint64(b, d.v1) - b = appendUint64(b, d.v2) - b = appendUint64(b, d.v3) - b = appendUint64(b, d.v4) - b = appendUint64(b, d.total) - b = append(b, d.mem[:d.n]...) - b = b[:len(b)+len(d.mem)-d.n] - return b, nil -} - -// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface. -func (d *Digest) UnmarshalBinary(b []byte) error { - if len(b) < len(magic) || string(b[:len(magic)]) != magic { - return errors.New("xxhash: invalid hash state identifier") - } - if len(b) != marshaledSize { - return errors.New("xxhash: invalid hash state size") - } - b = b[len(magic):] - b, d.v1 = consumeUint64(b) - b, d.v2 = consumeUint64(b) - b, d.v3 = consumeUint64(b) - b, d.v4 = consumeUint64(b) - b, d.total = consumeUint64(b) - copy(d.mem[:], b) - d.n = int(d.total % uint64(len(d.mem))) - return nil -} - -func appendUint64(b []byte, x uint64) []byte { - var a [8]byte - binary.LittleEndian.PutUint64(a[:], x) - return append(b, a[:]...) -} - -func consumeUint64(b []byte) ([]byte, uint64) { - x := u64(b) - return b[8:], x -} - -func u64(b []byte) uint64 { return binary.LittleEndian.Uint64(b) } -func u32(b []byte) uint32 { return binary.LittleEndian.Uint32(b) } - -func round(acc, input uint64) uint64 { - acc += input * prime2 - acc = rol31(acc) - acc *= prime1 - return acc -} - -func mergeRound(acc, val uint64) uint64 { - val = round(0, val) - acc ^= val - acc = acc*prime1 + prime4 - return acc -} - -func rol1(x uint64) uint64 { return bits.RotateLeft64(x, 1) } -func rol7(x uint64) uint64 { return bits.RotateLeft64(x, 7) } -func rol11(x uint64) uint64 { return bits.RotateLeft64(x, 11) } -func rol12(x uint64) uint64 { return bits.RotateLeft64(x, 12) } -func rol18(x uint64) uint64 { return bits.RotateLeft64(x, 18) } -func rol23(x uint64) uint64 { return bits.RotateLeft64(x, 23) } -func rol27(x uint64) uint64 { return bits.RotateLeft64(x, 27) } -func rol31(x uint64) uint64 { return bits.RotateLeft64(x, 31) } diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_amd64.s b/vendor/github.com/cespare/xxhash/v2/xxhash_amd64.s deleted file mode 100644 index 3e8b132579..0000000000 --- a/vendor/github.com/cespare/xxhash/v2/xxhash_amd64.s +++ /dev/null @@ -1,209 +0,0 @@ -//go:build !appengine && gc && !purego -// +build !appengine -// +build gc -// +build !purego - -#include "textflag.h" - -// Registers: -#define h AX -#define d AX -#define p SI // pointer to advance through b -#define n DX -#define end BX // loop end -#define v1 R8 -#define v2 R9 -#define v3 R10 -#define v4 R11 -#define x R12 -#define prime1 R13 -#define prime2 R14 -#define prime4 DI - -#define round(acc, x) \ - IMULQ prime2, x \ - ADDQ x, acc \ - ROLQ $31, acc \ - IMULQ prime1, acc - -// round0 performs the operation x = round(0, x). -#define round0(x) \ - IMULQ prime2, x \ - ROLQ $31, x \ - IMULQ prime1, x - -// mergeRound applies a merge round on the two registers acc and x. -// It assumes that prime1, prime2, and prime4 have been loaded. -#define mergeRound(acc, x) \ - round0(x) \ - XORQ x, acc \ - IMULQ prime1, acc \ - ADDQ prime4, acc - -// blockLoop processes as many 32-byte blocks as possible, -// updating v1, v2, v3, and v4. It assumes that there is at least one block -// to process. -#define blockLoop() \ -loop: \ - MOVQ +0(p), x \ - round(v1, x) \ - MOVQ +8(p), x \ - round(v2, x) \ - MOVQ +16(p), x \ - round(v3, x) \ - MOVQ +24(p), x \ - round(v4, x) \ - ADDQ $32, p \ - CMPQ p, end \ - JLE loop - -// func Sum64(b []byte) uint64 -TEXT ·Sum64(SB), NOSPLIT|NOFRAME, $0-32 - // Load fixed primes. - MOVQ ·primes+0(SB), prime1 - MOVQ ·primes+8(SB), prime2 - MOVQ ·primes+24(SB), prime4 - - // Load slice. - MOVQ b_base+0(FP), p - MOVQ b_len+8(FP), n - LEAQ (p)(n*1), end - - // The first loop limit will be len(b)-32. - SUBQ $32, end - - // Check whether we have at least one block. - CMPQ n, $32 - JLT noBlocks - - // Set up initial state (v1, v2, v3, v4). - MOVQ prime1, v1 - ADDQ prime2, v1 - MOVQ prime2, v2 - XORQ v3, v3 - XORQ v4, v4 - SUBQ prime1, v4 - - blockLoop() - - MOVQ v1, h - ROLQ $1, h - MOVQ v2, x - ROLQ $7, x - ADDQ x, h - MOVQ v3, x - ROLQ $12, x - ADDQ x, h - MOVQ v4, x - ROLQ $18, x - ADDQ x, h - - mergeRound(h, v1) - mergeRound(h, v2) - mergeRound(h, v3) - mergeRound(h, v4) - - JMP afterBlocks - -noBlocks: - MOVQ ·primes+32(SB), h - -afterBlocks: - ADDQ n, h - - ADDQ $24, end - CMPQ p, end - JG try4 - -loop8: - MOVQ (p), x - ADDQ $8, p - round0(x) - XORQ x, h - ROLQ $27, h - IMULQ prime1, h - ADDQ prime4, h - - CMPQ p, end - JLE loop8 - -try4: - ADDQ $4, end - CMPQ p, end - JG try1 - - MOVL (p), x - ADDQ $4, p - IMULQ prime1, x - XORQ x, h - - ROLQ $23, h - IMULQ prime2, h - ADDQ ·primes+16(SB), h - -try1: - ADDQ $4, end - CMPQ p, end - JGE finalize - -loop1: - MOVBQZX (p), x - ADDQ $1, p - IMULQ ·primes+32(SB), x - XORQ x, h - ROLQ $11, h - IMULQ prime1, h - - CMPQ p, end - JL loop1 - -finalize: - MOVQ h, x - SHRQ $33, x - XORQ x, h - IMULQ prime2, h - MOVQ h, x - SHRQ $29, x - XORQ x, h - IMULQ ·primes+16(SB), h - MOVQ h, x - SHRQ $32, x - XORQ x, h - - MOVQ h, ret+24(FP) - RET - -// func writeBlocks(d *Digest, b []byte) int -TEXT ·writeBlocks(SB), NOSPLIT|NOFRAME, $0-40 - // Load fixed primes needed for round. - MOVQ ·primes+0(SB), prime1 - MOVQ ·primes+8(SB), prime2 - - // Load slice. - MOVQ b_base+8(FP), p - MOVQ b_len+16(FP), n - LEAQ (p)(n*1), end - SUBQ $32, end - - // Load vN from d. - MOVQ s+0(FP), d - MOVQ 0(d), v1 - MOVQ 8(d), v2 - MOVQ 16(d), v3 - MOVQ 24(d), v4 - - // We don't need to check the loop condition here; this function is - // always called with at least one block of data to process. - blockLoop() - - // Copy vN back to d. - MOVQ v1, 0(d) - MOVQ v2, 8(d) - MOVQ v3, 16(d) - MOVQ v4, 24(d) - - // The number of bytes written is p minus the old base pointer. - SUBQ b_base+8(FP), p - MOVQ p, ret+32(FP) - - RET diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_arm64.s b/vendor/github.com/cespare/xxhash/v2/xxhash_arm64.s deleted file mode 100644 index 7e3145a221..0000000000 --- a/vendor/github.com/cespare/xxhash/v2/xxhash_arm64.s +++ /dev/null @@ -1,183 +0,0 @@ -//go:build !appengine && gc && !purego -// +build !appengine -// +build gc -// +build !purego - -#include "textflag.h" - -// Registers: -#define digest R1 -#define h R2 // return value -#define p R3 // input pointer -#define n R4 // input length -#define nblocks R5 // n / 32 -#define prime1 R7 -#define prime2 R8 -#define prime3 R9 -#define prime4 R10 -#define prime5 R11 -#define v1 R12 -#define v2 R13 -#define v3 R14 -#define v4 R15 -#define x1 R20 -#define x2 R21 -#define x3 R22 -#define x4 R23 - -#define round(acc, x) \ - MADD prime2, acc, x, acc \ - ROR $64-31, acc \ - MUL prime1, acc - -// round0 performs the operation x = round(0, x). -#define round0(x) \ - MUL prime2, x \ - ROR $64-31, x \ - MUL prime1, x - -#define mergeRound(acc, x) \ - round0(x) \ - EOR x, acc \ - MADD acc, prime4, prime1, acc - -// blockLoop processes as many 32-byte blocks as possible, -// updating v1, v2, v3, and v4. It assumes that n >= 32. -#define blockLoop() \ - LSR $5, n, nblocks \ - PCALIGN $16 \ - loop: \ - LDP.P 16(p), (x1, x2) \ - LDP.P 16(p), (x3, x4) \ - round(v1, x1) \ - round(v2, x2) \ - round(v3, x3) \ - round(v4, x4) \ - SUB $1, nblocks \ - CBNZ nblocks, loop - -// func Sum64(b []byte) uint64 -TEXT ·Sum64(SB), NOSPLIT|NOFRAME, $0-32 - LDP b_base+0(FP), (p, n) - - LDP ·primes+0(SB), (prime1, prime2) - LDP ·primes+16(SB), (prime3, prime4) - MOVD ·primes+32(SB), prime5 - - CMP $32, n - CSEL LT, prime5, ZR, h // if n < 32 { h = prime5 } else { h = 0 } - BLT afterLoop - - ADD prime1, prime2, v1 - MOVD prime2, v2 - MOVD $0, v3 - NEG prime1, v4 - - blockLoop() - - ROR $64-1, v1, x1 - ROR $64-7, v2, x2 - ADD x1, x2 - ROR $64-12, v3, x3 - ROR $64-18, v4, x4 - ADD x3, x4 - ADD x2, x4, h - - mergeRound(h, v1) - mergeRound(h, v2) - mergeRound(h, v3) - mergeRound(h, v4) - -afterLoop: - ADD n, h - - TBZ $4, n, try8 - LDP.P 16(p), (x1, x2) - - round0(x1) - - // NOTE: here and below, sequencing the EOR after the ROR (using a - // rotated register) is worth a small but measurable speedup for small - // inputs. - ROR $64-27, h - EOR x1 @> 64-27, h, h - MADD h, prime4, prime1, h - - round0(x2) - ROR $64-27, h - EOR x2 @> 64-27, h, h - MADD h, prime4, prime1, h - -try8: - TBZ $3, n, try4 - MOVD.P 8(p), x1 - - round0(x1) - ROR $64-27, h - EOR x1 @> 64-27, h, h - MADD h, prime4, prime1, h - -try4: - TBZ $2, n, try2 - MOVWU.P 4(p), x2 - - MUL prime1, x2 - ROR $64-23, h - EOR x2 @> 64-23, h, h - MADD h, prime3, prime2, h - -try2: - TBZ $1, n, try1 - MOVHU.P 2(p), x3 - AND $255, x3, x1 - LSR $8, x3, x2 - - MUL prime5, x1 - ROR $64-11, h - EOR x1 @> 64-11, h, h - MUL prime1, h - - MUL prime5, x2 - ROR $64-11, h - EOR x2 @> 64-11, h, h - MUL prime1, h - -try1: - TBZ $0, n, finalize - MOVBU (p), x4 - - MUL prime5, x4 - ROR $64-11, h - EOR x4 @> 64-11, h, h - MUL prime1, h - -finalize: - EOR h >> 33, h - MUL prime2, h - EOR h >> 29, h - MUL prime3, h - EOR h >> 32, h - - MOVD h, ret+24(FP) - RET - -// func writeBlocks(d *Digest, b []byte) int -TEXT ·writeBlocks(SB), NOSPLIT|NOFRAME, $0-40 - LDP ·primes+0(SB), (prime1, prime2) - - // Load state. Assume v[1-4] are stored contiguously. - MOVD d+0(FP), digest - LDP 0(digest), (v1, v2) - LDP 16(digest), (v3, v4) - - LDP b_base+8(FP), (p, n) - - blockLoop() - - // Store updated state. - STP (v1, v2), 0(digest) - STP (v3, v4), 16(digest) - - BIC $31, n - MOVD n, ret+32(FP) - RET diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_asm.go b/vendor/github.com/cespare/xxhash/v2/xxhash_asm.go deleted file mode 100644 index 78f95f2561..0000000000 --- a/vendor/github.com/cespare/xxhash/v2/xxhash_asm.go +++ /dev/null @@ -1,15 +0,0 @@ -//go:build (amd64 || arm64) && !appengine && gc && !purego -// +build amd64 arm64 -// +build !appengine -// +build gc -// +build !purego - -package xxhash - -// Sum64 computes the 64-bit xxHash digest of b with a zero seed. -// -//go:noescape -func Sum64(b []byte) uint64 - -//go:noescape -func writeBlocks(d *Digest, b []byte) int diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_other.go b/vendor/github.com/cespare/xxhash/v2/xxhash_other.go deleted file mode 100644 index 118e49e819..0000000000 --- a/vendor/github.com/cespare/xxhash/v2/xxhash_other.go +++ /dev/null @@ -1,76 +0,0 @@ -//go:build (!amd64 && !arm64) || appengine || !gc || purego -// +build !amd64,!arm64 appengine !gc purego - -package xxhash - -// Sum64 computes the 64-bit xxHash digest of b with a zero seed. -func Sum64(b []byte) uint64 { - // A simpler version would be - // d := New() - // d.Write(b) - // return d.Sum64() - // but this is faster, particularly for small inputs. - - n := len(b) - var h uint64 - - if n >= 32 { - v1 := primes[0] + prime2 - v2 := prime2 - v3 := uint64(0) - v4 := -primes[0] - for len(b) >= 32 { - v1 = round(v1, u64(b[0:8:len(b)])) - v2 = round(v2, u64(b[8:16:len(b)])) - v3 = round(v3, u64(b[16:24:len(b)])) - v4 = round(v4, u64(b[24:32:len(b)])) - b = b[32:len(b):len(b)] - } - h = rol1(v1) + rol7(v2) + rol12(v3) + rol18(v4) - h = mergeRound(h, v1) - h = mergeRound(h, v2) - h = mergeRound(h, v3) - h = mergeRound(h, v4) - } else { - h = prime5 - } - - h += uint64(n) - - for ; len(b) >= 8; b = b[8:] { - k1 := round(0, u64(b[:8])) - h ^= k1 - h = rol27(h)*prime1 + prime4 - } - if len(b) >= 4 { - h ^= uint64(u32(b[:4])) * prime1 - h = rol23(h)*prime2 + prime3 - b = b[4:] - } - for ; len(b) > 0; b = b[1:] { - h ^= uint64(b[0]) * prime5 - h = rol11(h) * prime1 - } - - h ^= h >> 33 - h *= prime2 - h ^= h >> 29 - h *= prime3 - h ^= h >> 32 - - return h -} - -func writeBlocks(d *Digest, b []byte) int { - v1, v2, v3, v4 := d.v1, d.v2, d.v3, d.v4 - n := len(b) - for len(b) >= 32 { - v1 = round(v1, u64(b[0:8:len(b)])) - v2 = round(v2, u64(b[8:16:len(b)])) - v3 = round(v3, u64(b[16:24:len(b)])) - v4 = round(v4, u64(b[24:32:len(b)])) - b = b[32:len(b):len(b)] - } - d.v1, d.v2, d.v3, d.v4 = v1, v2, v3, v4 - return n - len(b) -} diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_safe.go b/vendor/github.com/cespare/xxhash/v2/xxhash_safe.go deleted file mode 100644 index 05f5e7dfe7..0000000000 --- a/vendor/github.com/cespare/xxhash/v2/xxhash_safe.go +++ /dev/null @@ -1,16 +0,0 @@ -//go:build appengine -// +build appengine - -// This file contains the safe implementations of otherwise unsafe-using code. - -package xxhash - -// Sum64String computes the 64-bit xxHash digest of s with a zero seed. -func Sum64String(s string) uint64 { - return Sum64([]byte(s)) -} - -// WriteString adds more data to d. It always returns len(s), nil. -func (d *Digest) WriteString(s string) (n int, err error) { - return d.Write([]byte(s)) -} diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go b/vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go deleted file mode 100644 index cf9d42aed5..0000000000 --- a/vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go +++ /dev/null @@ -1,58 +0,0 @@ -//go:build !appengine -// +build !appengine - -// This file encapsulates usage of unsafe. -// xxhash_safe.go contains the safe implementations. - -package xxhash - -import ( - "unsafe" -) - -// In the future it's possible that compiler optimizations will make these -// XxxString functions unnecessary by realizing that calls such as -// Sum64([]byte(s)) don't need to copy s. See https://go.dev/issue/2205. -// If that happens, even if we keep these functions they can be replaced with -// the trivial safe code. - -// NOTE: The usual way of doing an unsafe string-to-[]byte conversion is: -// -// var b []byte -// bh := (*reflect.SliceHeader)(unsafe.Pointer(&b)) -// bh.Data = (*reflect.StringHeader)(unsafe.Pointer(&s)).Data -// bh.Len = len(s) -// bh.Cap = len(s) -// -// Unfortunately, as of Go 1.15.3 the inliner's cost model assigns a high enough -// weight to this sequence of expressions that any function that uses it will -// not be inlined. Instead, the functions below use a different unsafe -// conversion designed to minimize the inliner weight and allow both to be -// inlined. There is also a test (TestInlining) which verifies that these are -// inlined. -// -// See https://github.com/golang/go/issues/42739 for discussion. - -// Sum64String computes the 64-bit xxHash digest of s with a zero seed. -// It may be faster than Sum64([]byte(s)) by avoiding a copy. -func Sum64String(s string) uint64 { - b := *(*[]byte)(unsafe.Pointer(&sliceHeader{s, len(s)})) - return Sum64(b) -} - -// WriteString adds more data to d. It always returns len(s), nil. -// It may be faster than Write([]byte(s)) by avoiding a copy. -func (d *Digest) WriteString(s string) (n int, err error) { - d.Write(*(*[]byte)(unsafe.Pointer(&sliceHeader{s, len(s)}))) - // d.Write always returns len(s), nil. - // Ignoring the return output and returning these fixed values buys a - // savings of 6 in the inliner's cost model. - return len(s), nil -} - -// sliceHeader is similar to reflect.SliceHeader, but it assumes that the layout -// of the first two words is the same as the layout of a string. -type sliceHeader struct { - s string - cap int -} diff --git a/vendor/github.com/charithe/durationcheck/.gitignore b/vendor/github.com/charithe/durationcheck/.gitignore deleted file mode 100644 index c2b126a846..0000000000 --- a/vendor/github.com/charithe/durationcheck/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/durationcheck diff --git a/vendor/github.com/charithe/durationcheck/LICENSE b/vendor/github.com/charithe/durationcheck/LICENSE deleted file mode 100644 index 261eeb9e9f..0000000000 --- a/vendor/github.com/charithe/durationcheck/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/charithe/durationcheck/Makefile b/vendor/github.com/charithe/durationcheck/Makefile deleted file mode 100644 index 8e2f81ae87..0000000000 --- a/vendor/github.com/charithe/durationcheck/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -build: - @GO111MODULE=on go build -ldflags '-s -w' -o durationcheck ./cmd/durationcheck/main.go - -install: - @GO111MODULE=on go install -ldflags '-s -w' ./cmd/durationcheck diff --git a/vendor/github.com/charithe/durationcheck/README.md b/vendor/github.com/charithe/durationcheck/README.md deleted file mode 100644 index 4aa9558f2b..0000000000 --- a/vendor/github.com/charithe/durationcheck/README.md +++ /dev/null @@ -1,51 +0,0 @@ -[![CircleCI](https://circleci.com/gh/charithe/durationcheck.svg?style=svg)](https://circleci.com/gh/charithe/durationcheck) - - - -Duration Check -=============== - -A Go linter to detect cases where two `time.Duration` values are being multiplied in possibly erroneous ways. - -Consider the following (highly contrived) code: - -```go -func waitForSeconds(someDuration time.Duration) { - timeToWait := someDuration * time.Second - fmt.Printf("Waiting for %s\n", timeToWait) -} - -func main() { - waitForSeconds(5) // waits for 5 seconds - waitForSeconds(5 * time.Second) // waits for 1388888h 53m 20s -} -``` - -Both invocations of the function are syntactically correct but the second one is probably not what most people want. -In this contrived example it is quite easy to spot the mistake. However, if the incorrect `waitForSeconds` invocation is -nested deep within a complex piece of code that runs in the background, the mistake could go unnoticed for months (which -is exactly what happened in a production backend system of fairly well-known software service). - - -See the [test cases](testdata/src/a/a.go) for more examples of the types of errors detected by the linter. - - -Installation -------------- - -Requires Go 1.14 or above. - -``` -go get -u github.com/charithe/durationcheck/cmd/durationcheck -``` - -Usage ------ - -Invoke `durationcheck` with your package name - -``` -durationcheck ./... -# or -durationcheck github.com/you/yourproject/... -``` diff --git a/vendor/github.com/charithe/durationcheck/durationcheck.go b/vendor/github.com/charithe/durationcheck/durationcheck.go deleted file mode 100644 index 5fcb98a890..0000000000 --- a/vendor/github.com/charithe/durationcheck/durationcheck.go +++ /dev/null @@ -1,212 +0,0 @@ -package durationcheck - -import ( - "bytes" - "fmt" - "go/ast" - "go/format" - "go/token" - "go/types" - "log" - "os" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/inspector" -) - -var Analyzer = &analysis.Analyzer{ - Name: "durationcheck", - Doc: "check for two durations multiplied together", - Run: run, - Requires: []*analysis.Analyzer{inspect.Analyzer}, -} - -func run(pass *analysis.Pass) (interface{}, error) { - // if the package does not import time, it can be skipped from analysis - if !hasImport(pass.Pkg, "time") { - return nil, nil - } - - inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - - nodeTypes := []ast.Node{ - (*ast.BinaryExpr)(nil), - (*ast.AssignStmt)(nil), - } - - inspect.Preorder(nodeTypes, check(pass)) - - return nil, nil -} - -func hasImport(pkg *types.Package, importPath string) bool { - for _, imp := range pkg.Imports() { - if imp.Path() == importPath { - return true - } - } - - return false -} - -// check contains the logic for checking that time.Duration is used correctly in the code being analysed -func check(pass *analysis.Pass) func(ast.Node) { - return func(node ast.Node) { - switch expr := node.(type) { - case *ast.BinaryExpr: - checkBinaryExpr(pass, expr) - case *ast.AssignStmt: - if expr.Tok != token.MUL_ASSIGN { - return - } - // '*=' assignment requires single-valued expressions - if len(expr.Lhs) != 1 || len(expr.Rhs) != 1 { - return - } - checkBinaryExpr(pass, &ast.BinaryExpr{ - X: expr.Lhs[0], - OpPos: expr.TokPos, - Op: expr.Tok, - Y: expr.Rhs[0], - }) - } - } -} - -func checkBinaryExpr(pass *analysis.Pass, expr *ast.BinaryExpr) { - // we are only interested in multiplication - if expr.Op != token.MUL && expr.Op != token.MUL_ASSIGN { - return - } - - // get the types of the two operands - x, xOK := pass.TypesInfo.Types[expr.X] - y, yOK := pass.TypesInfo.Types[expr.Y] - - if !xOK || !yOK { - return - } - - if isDuration(x.Type) && isDuration(y.Type) { - // check that both sides are acceptable expressions - if isUnacceptableExpr(pass, expr.X) && isUnacceptableExpr(pass, expr.Y) { - pass.Reportf(expr.Pos(), "Multiplication of durations: `%s`", formatNode(expr)) - } - } -} - -func isDuration(x types.Type) bool { - return x.String() == "time.Duration" || x.String() == "*time.Duration" -} - -// isUnacceptableExpr returns true if the argument is not an acceptable time.Duration expression -func isUnacceptableExpr(pass *analysis.Pass, expr ast.Expr) bool { - switch e := expr.(type) { - case *ast.BasicLit: - return false - case *ast.Ident: - return !isAcceptableNestedExpr(pass, e) - case *ast.CallExpr: - return !isAcceptableCast(pass, e) - case *ast.BinaryExpr: - return !isAcceptableNestedExpr(pass, e) - case *ast.UnaryExpr: - return !isAcceptableNestedExpr(pass, e) - case *ast.SelectorExpr: - return !isAcceptableNestedExpr(pass, e) - case *ast.StarExpr: - return !isAcceptableNestedExpr(pass, e) - case *ast.ParenExpr: - return !isAcceptableNestedExpr(pass, e) - case *ast.IndexExpr: - return !isAcceptableNestedExpr(pass, e) - default: - return true - } -} - -// isAcceptableCast returns true if the argument is an acceptable expression cast to time.Duration -func isAcceptableCast(pass *analysis.Pass, e *ast.CallExpr) bool { - // check that there's a single argument - if len(e.Args) != 1 { - return false - } - - // check that the argument is acceptable - if !isAcceptableNestedExpr(pass, e.Args[0]) { - return false - } - - // check for time.Duration cast - selector, ok := e.Fun.(*ast.SelectorExpr) - if !ok { - return false - } - - return isDurationCast(selector) -} - -func isDurationCast(selector *ast.SelectorExpr) bool { - pkg, ok := selector.X.(*ast.Ident) - if !ok { - return false - } - - if pkg.Name != "time" { - return false - } - - return selector.Sel.Name == "Duration" -} - -func isAcceptableNestedExpr(pass *analysis.Pass, n ast.Expr) bool { - switch e := n.(type) { - case *ast.BasicLit: - return true - case *ast.BinaryExpr: - return isAcceptableNestedExpr(pass, e.X) && isAcceptableNestedExpr(pass, e.Y) - case *ast.UnaryExpr: - return isAcceptableNestedExpr(pass, e.X) - case *ast.Ident: - return isAcceptableIdent(pass, e) - case *ast.CallExpr: - if isAcceptableCast(pass, e) { - return true - } - t := pass.TypesInfo.TypeOf(e) - return !isDuration(t) - case *ast.SelectorExpr: - return isAcceptableNestedExpr(pass, e.X) && isAcceptableIdent(pass, e.Sel) - case *ast.StarExpr: - return isAcceptableNestedExpr(pass, e.X) - case *ast.ParenExpr: - return isAcceptableNestedExpr(pass, e.X) - case *ast.IndexExpr: - t := pass.TypesInfo.TypeOf(e) - return !isDuration(t) - default: - return false - } -} - -func isAcceptableIdent(pass *analysis.Pass, ident *ast.Ident) bool { - obj := pass.TypesInfo.ObjectOf(ident) - return !isDuration(obj.Type()) -} - -func formatNode(node ast.Node) string { - buf := new(bytes.Buffer) - if err := format.Node(buf, token.NewFileSet(), node); err != nil { - log.Printf("Error formatting expression: %v", err) - return "" - } - - return buf.String() -} - -func printAST(msg string, node ast.Node) { - fmt.Printf(">>> %s:\n%s\n\n\n", msg, formatNode(node)) - ast.Fprint(os.Stdout, nil, node, nil) - fmt.Println("--------------") -} diff --git a/vendor/github.com/charmbracelet/colorprofile/.golangci-soft.yml b/vendor/github.com/charmbracelet/colorprofile/.golangci-soft.yml deleted file mode 100644 index d325d4fcc6..0000000000 --- a/vendor/github.com/charmbracelet/colorprofile/.golangci-soft.yml +++ /dev/null @@ -1,40 +0,0 @@ -run: - tests: false - issues-exit-code: 0 - -issues: - include: - - EXC0001 - - EXC0005 - - EXC0011 - - EXC0012 - - EXC0013 - - max-issues-per-linter: 0 - max-same-issues: 0 - -linters: - enable: - - exhaustive - - goconst - - godot - - godox - - mnd - - gomoddirectives - - goprintffuncname - - misspell - - nakedret - - nestif - - noctx - - nolintlint - - prealloc - - wrapcheck - - # disable default linters, they are already enabled in .golangci.yml - disable: - - errcheck - - gosimple - - govet - - ineffassign - - staticcheck - - unused diff --git a/vendor/github.com/charmbracelet/colorprofile/.golangci.yml b/vendor/github.com/charmbracelet/colorprofile/.golangci.yml deleted file mode 100644 index d6789e014c..0000000000 --- a/vendor/github.com/charmbracelet/colorprofile/.golangci.yml +++ /dev/null @@ -1,28 +0,0 @@ -run: - tests: false - -issues: - include: - - EXC0001 - - EXC0005 - - EXC0011 - - EXC0012 - - EXC0013 - - max-issues-per-linter: 0 - max-same-issues: 0 - -linters: - enable: - - bodyclose - - gofumpt - - goimports - - gosec - - nilerr - - revive - - rowserrcheck - - sqlclosecheck - - tparallel - - unconvert - - unparam - - whitespace diff --git a/vendor/github.com/charmbracelet/colorprofile/.goreleaser.yml b/vendor/github.com/charmbracelet/colorprofile/.goreleaser.yml deleted file mode 100644 index 40d9f298db..0000000000 --- a/vendor/github.com/charmbracelet/colorprofile/.goreleaser.yml +++ /dev/null @@ -1,6 +0,0 @@ -includes: - - from_url: - url: charmbracelet/meta/main/goreleaser-lib.yaml - -# yaml-language-server: $schema=https://goreleaser.com/static/schema-pro.json - diff --git a/vendor/github.com/charmbracelet/colorprofile/LICENSE b/vendor/github.com/charmbracelet/colorprofile/LICENSE deleted file mode 100644 index b7974b0765..0000000000 --- a/vendor/github.com/charmbracelet/colorprofile/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2020-2024 Charmbracelet, Inc - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/charmbracelet/colorprofile/README.md b/vendor/github.com/charmbracelet/colorprofile/README.md deleted file mode 100644 index c72b2f4b5a..0000000000 --- a/vendor/github.com/charmbracelet/colorprofile/README.md +++ /dev/null @@ -1,103 +0,0 @@ -# Colorprofile - -

- Latest Release - GoDoc - Build Status -

- -A simple, powerful—and at times magical—package for detecting terminal color -profiles and performing color (and CSI) degradation. - -## Detecting the terminal’s color profile - -Detecting the terminal’s color profile is easy. - -```go -import "github.com/charmbracelet/colorprofile" - -// Detect the color profile. If you’re planning on writing to stderr you'd want -// to use os.Stderr instead. -p := colorprofile.Detect(os.Stdout, os.Environ()) - -// Comment on the profile. -fmt.Printf("You know, your colors are quite %s.", func() string { - switch p { - case colorprofile.TrueColor: - return "fancy" - case colorprofile.ANSI256: - return "1990s fancy" - case colorprofile.ANSI: - return "normcore" - case colorprofile.Ascii: - return "ancient" - case colorprofile.NoTTY: - return "naughty!" - } - return "...IDK" // this should never happen -}()) -``` - -## Downsampling colors - -When necessary, colors can be downsampled to a given profile, or manually -downsampled to a specific profile. - -```go -p := colorprofile.Detect(os.Stdout, os.Environ()) -c := color.RGBA{0x6b, 0x50, 0xff, 0xff} // #6b50ff - -// Downsample to the detected profile, when necessary. -convertedColor := p.Convert(c) - -// Or manually convert to a given profile. -ansi256Color := colorprofile.ANSI256.Convert(c) -ansiColor := colorprofile.ANSI.Convert(c) -noColor := colorprofile.Ascii.Convert(c) -noANSI := colorprofile.NoTTY.Convert(c) -``` - -## Automatic downsampling with a Writer - -You can also magically downsample colors in ANSI output, when necessary. If -output is not a TTY ANSI will be dropped entirely. - -```go -myFancyANSI := "\x1b[38;2;107;80;255mCute \x1b[1;3mpuppy!!\x1b[m" - -// Automatically downsample for the terminal at stdout. -w := colorprofile.NewWriter(os.Stdout, os.Environ()) -fmt.Fprintf(w, myFancyANSI) - -// Downsample to 4-bit ANSI. -w.Profile = colorprofile.ANSI -fmt.Fprintf(w, myFancyANSI) - -// Ascii-fy, no colors. -w.Profile = colorprofile.Ascii -fmt.Fprintf(w, myFancyANSI) - -// Strip ANSI altogether. -w.Profile = colorprofile.NoTTY -fmt.Fprintf(w, myFancyANSI) // not as fancy -``` - -## Feedback - -We’d love to hear your thoughts on this project. Feel free to drop us a note! - -- [Twitter](https://twitter.com/charmcli) -- [The Fediverse](https://mastodon.social/@charmcli) -- [Discord](https://charm.sh/chat) - -## License - -[MIT](https://github.com/charmbracelet/bubbletea/raw/master/LICENSE) - ---- - -Part of [Charm](https://charm.sh). - -The Charm logo - -Charm热爱开源 • Charm loves open source • نحنُ نحب المصادر المفتوحة diff --git a/vendor/github.com/charmbracelet/colorprofile/env.go b/vendor/github.com/charmbracelet/colorprofile/env.go deleted file mode 100644 index 8df3d8f7e7..0000000000 --- a/vendor/github.com/charmbracelet/colorprofile/env.go +++ /dev/null @@ -1,287 +0,0 @@ -package colorprofile - -import ( - "bytes" - "io" - "os/exec" - "runtime" - "strconv" - "strings" - - "github.com/charmbracelet/x/term" - "github.com/xo/terminfo" -) - -// Detect returns the color profile based on the terminal output, and -// environment variables. This respects NO_COLOR, CLICOLOR, and CLICOLOR_FORCE -// environment variables. -// -// The rules as follows: -// - TERM=dumb is always treated as NoTTY unless CLICOLOR_FORCE=1 is set. -// - If COLORTERM=truecolor, and the profile is not NoTTY, it gest upgraded to TrueColor. -// - Using any 256 color terminal (e.g. TERM=xterm-256color) will set the profile to ANSI256. -// - Using any color terminal (e.g. TERM=xterm-color) will set the profile to ANSI. -// - Using CLICOLOR=1 without TERM defined should be treated as ANSI if the -// output is a terminal. -// - NO_COLOR takes precedence over CLICOLOR/CLICOLOR_FORCE, and will disable -// colors but not text decoration, i.e. bold, italic, faint, etc. -// -// See https://no-color.org/ and https://bixense.com/clicolors/ for more information. -func Detect(output io.Writer, env []string) Profile { - out, ok := output.(term.File) - isatty := ok && term.IsTerminal(out.Fd()) - environ := newEnviron(env) - term := environ.get("TERM") - isDumb := term == "dumb" - envp := colorProfile(isatty, environ) - if envp == TrueColor || envNoColor(environ) { - // We already know we have TrueColor, or NO_COLOR is set. - return envp - } - - if isatty && !isDumb { - tip := Terminfo(term) - tmuxp := tmux(environ) - - // Color profile is the maximum of env, terminfo, and tmux. - return max(envp, max(tip, tmuxp)) - } - - return envp -} - -// Env returns the color profile based on the terminal environment variables. -// This respects NO_COLOR, CLICOLOR, and CLICOLOR_FORCE environment variables. -// -// The rules as follows: -// - TERM=dumb is always treated as NoTTY unless CLICOLOR_FORCE=1 is set. -// - If COLORTERM=truecolor, and the profile is not NoTTY, it gest upgraded to TrueColor. -// - Using any 256 color terminal (e.g. TERM=xterm-256color) will set the profile to ANSI256. -// - Using any color terminal (e.g. TERM=xterm-color) will set the profile to ANSI. -// - Using CLICOLOR=1 without TERM defined should be treated as ANSI if the -// output is a terminal. -// - NO_COLOR takes precedence over CLICOLOR/CLICOLOR_FORCE, and will disable -// colors but not text decoration, i.e. bold, italic, faint, etc. -// -// See https://no-color.org/ and https://bixense.com/clicolors/ for more information. -func Env(env []string) (p Profile) { - return colorProfile(true, newEnviron(env)) -} - -func colorProfile(isatty bool, env environ) (p Profile) { - isDumb := env.get("TERM") == "dumb" - envp := envColorProfile(env) - if !isatty || isDumb { - // Check if the output is a terminal. - // Treat dumb terminals as NoTTY - p = NoTTY - } else { - p = envp - } - - if envNoColor(env) && isatty { - if p > Ascii { - p = Ascii - } - return - } - - if cliColorForced(env) { - if p < ANSI { - p = ANSI - } - if envp > p { - p = envp - } - - return - } - - if cliColor(env) { - if isatty && !isDumb && p < ANSI { - p = ANSI - } - } - - return p -} - -// envNoColor returns true if the environment variables explicitly disable color output -// by setting NO_COLOR (https://no-color.org/). -func envNoColor(env environ) bool { - noColor, _ := strconv.ParseBool(env.get("NO_COLOR")) - return noColor -} - -func cliColor(env environ) bool { - cliColor, _ := strconv.ParseBool(env.get("CLICOLOR")) - return cliColor -} - -func cliColorForced(env environ) bool { - cliColorForce, _ := strconv.ParseBool(env.get("CLICOLOR_FORCE")) - return cliColorForce -} - -func colorTerm(env environ) bool { - colorTerm := strings.ToLower(env.get("COLORTERM")) - return colorTerm == "truecolor" || colorTerm == "24bit" || - colorTerm == "yes" || colorTerm == "true" -} - -// envColorProfile returns infers the color profile from the environment. -func envColorProfile(env environ) (p Profile) { - term, ok := env.lookup("TERM") - if !ok || len(term) == 0 || term == "dumb" { - p = NoTTY - if runtime.GOOS == "windows" { - // Use Windows API to detect color profile. Windows Terminal and - // cmd.exe don't define $TERM. - if wcp, ok := windowsColorProfile(env); ok { - p = wcp - } - } - } else { - p = ANSI - } - - parts := strings.Split(term, "-") - switch parts[0] { - case "alacritty", - "contour", - "foot", - "ghostty", - "kitty", - "rio", - "st", - "wezterm": - return TrueColor - case "xterm": - if len(parts) > 1 { - switch parts[1] { - case "ghostty", "kitty": - // These terminals can be defined as xterm-TERMNAME - return TrueColor - } - } - case "tmux", "screen": - if p < ANSI256 { - p = ANSI256 - } - } - - if isCloudShell, _ := strconv.ParseBool(env.get("GOOGLE_CLOUD_SHELL")); isCloudShell { - return TrueColor - } - - // GNU Screen doesn't support TrueColor - // Tmux doesn't support $COLORTERM - if colorTerm(env) && !strings.HasPrefix(term, "screen") && !strings.HasPrefix(term, "tmux") { - return TrueColor - } - - if strings.HasSuffix(term, "256color") && p < ANSI256 { - p = ANSI256 - } - - return -} - -// Terminfo returns the color profile based on the terminal's terminfo -// database. This relies on the Tc and RGB capabilities to determine if the -// terminal supports TrueColor. -// If term is empty or "dumb", it returns NoTTY. -func Terminfo(term string) (p Profile) { - if len(term) == 0 || term == "dumb" { - return NoTTY - } - - p = ANSI - ti, err := terminfo.Load(term) - if err != nil { - return - } - - extbools := ti.ExtBoolCapsShort() - if _, ok := extbools["Tc"]; ok { - return TrueColor - } - - if _, ok := extbools["RGB"]; ok { - return TrueColor - } - - return -} - -// Tmux returns the color profile based on `tmux info` output. Tmux supports -// overriding the terminal's color capabilities, so this function will return -// the color profile based on the tmux configuration. -func Tmux(env []string) Profile { - return tmux(newEnviron(env)) -} - -// tmux returns the color profile based on the tmux environment variables. -func tmux(env environ) (p Profile) { - if tmux, ok := env.lookup("TMUX"); !ok || len(tmux) == 0 { - // Not in tmux - return NoTTY - } - - // Check if tmux has either Tc or RGB capabilities. Otherwise, return - // ANSI256. - p = ANSI256 - cmd := exec.Command("tmux", "info") - out, err := cmd.Output() - if err != nil { - return - } - - for _, line := range bytes.Split(out, []byte("\n")) { - if (bytes.Contains(line, []byte("Tc")) || bytes.Contains(line, []byte("RGB"))) && - bytes.Contains(line, []byte("true")) { - return TrueColor - } - } - - return -} - -// environ is a map of environment variables. -type environ map[string]string - -// newEnviron returns a new environment map from a slice of environment -// variables. -func newEnviron(environ []string) environ { - m := make(map[string]string, len(environ)) - for _, e := range environ { - parts := strings.SplitN(e, "=", 2) - var value string - if len(parts) == 2 { - value = parts[1] - } - m[parts[0]] = value - } - return m -} - -// lookup returns the value of an environment variable and a boolean indicating -// if it exists. -func (e environ) lookup(key string) (string, bool) { - v, ok := e[key] - return v, ok -} - -// get returns the value of an environment variable and empty string if it -// doesn't exist. -func (e environ) get(key string) string { - v, _ := e.lookup(key) - return v -} - -func max[T ~byte | ~int](a, b T) T { - if a > b { - return a - } - return b -} diff --git a/vendor/github.com/charmbracelet/colorprofile/env_other.go b/vendor/github.com/charmbracelet/colorprofile/env_other.go deleted file mode 100644 index 080994bc1f..0000000000 --- a/vendor/github.com/charmbracelet/colorprofile/env_other.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build !windows -// +build !windows - -package colorprofile - -func windowsColorProfile(map[string]string) (Profile, bool) { - return 0, false -} diff --git a/vendor/github.com/charmbracelet/colorprofile/env_windows.go b/vendor/github.com/charmbracelet/colorprofile/env_windows.go deleted file mode 100644 index 3b9c28f96d..0000000000 --- a/vendor/github.com/charmbracelet/colorprofile/env_windows.go +++ /dev/null @@ -1,45 +0,0 @@ -//go:build windows -// +build windows - -package colorprofile - -import ( - "strconv" - - "golang.org/x/sys/windows" -) - -func windowsColorProfile(env map[string]string) (Profile, bool) { - if env["ConEmuANSI"] == "ON" { - return TrueColor, true - } - - if len(env["WT_SESSION"]) > 0 { - // Windows Terminal supports TrueColor - return TrueColor, true - } - - major, _, build := windows.RtlGetNtVersionNumbers() - if build < 10586 || major < 10 { - // No ANSI support before WindowsNT 10 build 10586 - if len(env["ANSICON"]) > 0 { - ansiconVer := env["ANSICON_VER"] - cv, err := strconv.Atoi(ansiconVer) - if err != nil || cv < 181 { - // No 8 bit color support before ANSICON 1.81 - return ANSI, true - } - - return ANSI256, true - } - - return NoTTY, true - } - - if build < 14931 { - // No true color support before build 14931 - return ANSI256, true - } - - return TrueColor, true -} diff --git a/vendor/github.com/charmbracelet/colorprofile/profile.go b/vendor/github.com/charmbracelet/colorprofile/profile.go deleted file mode 100644 index 97e37ac366..0000000000 --- a/vendor/github.com/charmbracelet/colorprofile/profile.go +++ /dev/null @@ -1,399 +0,0 @@ -package colorprofile - -import ( - "image/color" - "math" - - "github.com/charmbracelet/x/ansi" - "github.com/lucasb-eyer/go-colorful" -) - -// Profile is a color profile: NoTTY, Ascii, ANSI, ANSI256, or TrueColor. -type Profile byte - -const ( - // NoTTY, not a terminal profile. - NoTTY Profile = iota - // Ascii, uncolored profile. - Ascii //nolint:revive - // ANSI, 4-bit color profile. - ANSI - // ANSI256, 8-bit color profile. - ANSI256 - // TrueColor, 24-bit color profile. - TrueColor -) - -// String returns the string representation of a Profile. -func (p Profile) String() string { - switch p { - case TrueColor: - return "TrueColor" - case ANSI256: - return "ANSI256" - case ANSI: - return "ANSI" - case Ascii: - return "Ascii" - case NoTTY: - return "NoTTY" - } - return "Unknown" -} - -// Convert transforms a given Color to a Color supported within the Profile. -func (p Profile) Convert(c color.Color) color.Color { - if p <= Ascii { - return nil - } - - switch c := c.(type) { - case ansi.BasicColor: - return c - - case ansi.ExtendedColor: - if p == ANSI { - return ansi256ToANSIColor(c) - } - return c - - case ansi.TrueColor, color.Color: - h, ok := colorful.MakeColor(c) - if !ok { - return nil - } - if p != TrueColor { - ac := hexToANSI256Color(h) - if p == ANSI { - return ansi256ToANSIColor(ac) - } - return ac - } - return c - } - - return c -} - -func hexToANSI256Color(c colorful.Color) ansi.ExtendedColor { - v2ci := func(v float64) int { - if v < 48 { - return 0 - } - if v < 115 { - return 1 - } - return int((v - 35) / 40) - } - - // Calculate the nearest 0-based color index at 16..231 - r := v2ci(c.R * 255.0) // 0..5 each - g := v2ci(c.G * 255.0) - b := v2ci(c.B * 255.0) - ci := 36*r + 6*g + b /* 0..215 */ - - // Calculate the represented colors back from the index - i2cv := [6]int{0, 0x5f, 0x87, 0xaf, 0xd7, 0xff} - cr := i2cv[r] // r/g/b, 0..255 each - cg := i2cv[g] - cb := i2cv[b] - - // Calculate the nearest 0-based gray index at 232..255 - var grayIdx int - average := (cr + cg + cb) / 3 - if average > 238 { - grayIdx = 23 - } else { - grayIdx = (average - 3) / 10 // 0..23 - } - gv := 8 + 10*grayIdx // same value for r/g/b, 0..255 - - // Return the one which is nearer to the original input rgb value - c2 := colorful.Color{R: float64(cr) / 255.0, G: float64(cg) / 255.0, B: float64(cb) / 255.0} - g2 := colorful.Color{R: float64(gv) / 255.0, G: float64(gv) / 255.0, B: float64(gv) / 255.0} - colorDist := c.DistanceHSLuv(c2) - grayDist := c.DistanceHSLuv(g2) - - if colorDist <= grayDist { - return ansi.ExtendedColor(16 + ci) //nolint:gosec - } - return ansi.ExtendedColor(232 + grayIdx) //nolint:gosec -} - -func ansi256ToANSIColor(c ansi.ExtendedColor) ansi.BasicColor { - var r int - md := math.MaxFloat64 - - h, _ := colorful.Hex(ansiHex[c]) - for i := 0; i <= 15; i++ { - hb, _ := colorful.Hex(ansiHex[i]) - d := h.DistanceHSLuv(hb) - - if d < md { - md = d - r = i - } - } - - return ansi.BasicColor(r) //nolint:gosec -} - -// RGB values of ANSI colors (0-255). -var ansiHex = []string{ - "#000000", - "#800000", - "#008000", - "#808000", - "#000080", - "#800080", - "#008080", - "#c0c0c0", - "#808080", - "#ff0000", - "#00ff00", - "#ffff00", - "#0000ff", - "#ff00ff", - "#00ffff", - "#ffffff", - "#000000", - "#00005f", - "#000087", - "#0000af", - "#0000d7", - "#0000ff", - "#005f00", - "#005f5f", - "#005f87", - "#005faf", - "#005fd7", - "#005fff", - "#008700", - "#00875f", - "#008787", - "#0087af", - "#0087d7", - "#0087ff", - "#00af00", - "#00af5f", - "#00af87", - "#00afaf", - "#00afd7", - "#00afff", - "#00d700", - "#00d75f", - "#00d787", - "#00d7af", - "#00d7d7", - "#00d7ff", - "#00ff00", - "#00ff5f", - "#00ff87", - "#00ffaf", - "#00ffd7", - "#00ffff", - "#5f0000", - "#5f005f", - "#5f0087", - "#5f00af", - "#5f00d7", - "#5f00ff", - "#5f5f00", - "#5f5f5f", - "#5f5f87", - "#5f5faf", - "#5f5fd7", - "#5f5fff", - "#5f8700", - "#5f875f", - "#5f8787", - "#5f87af", - "#5f87d7", - "#5f87ff", - "#5faf00", - "#5faf5f", - "#5faf87", - "#5fafaf", - "#5fafd7", - "#5fafff", - "#5fd700", - "#5fd75f", - "#5fd787", - "#5fd7af", - "#5fd7d7", - "#5fd7ff", - "#5fff00", - "#5fff5f", - "#5fff87", - "#5fffaf", - "#5fffd7", - "#5fffff", - "#870000", - "#87005f", - "#870087", - "#8700af", - "#8700d7", - "#8700ff", - "#875f00", - "#875f5f", - "#875f87", - "#875faf", - "#875fd7", - "#875fff", - "#878700", - "#87875f", - "#878787", - "#8787af", - "#8787d7", - "#8787ff", - "#87af00", - "#87af5f", - "#87af87", - "#87afaf", - "#87afd7", - "#87afff", - "#87d700", - "#87d75f", - "#87d787", - "#87d7af", - "#87d7d7", - "#87d7ff", - "#87ff00", - "#87ff5f", - "#87ff87", - "#87ffaf", - "#87ffd7", - "#87ffff", - "#af0000", - "#af005f", - "#af0087", - "#af00af", - "#af00d7", - "#af00ff", - "#af5f00", - "#af5f5f", - "#af5f87", - "#af5faf", - "#af5fd7", - "#af5fff", - "#af8700", - "#af875f", - "#af8787", - "#af87af", - "#af87d7", - "#af87ff", - "#afaf00", - "#afaf5f", - "#afaf87", - "#afafaf", - "#afafd7", - "#afafff", - "#afd700", - "#afd75f", - "#afd787", - "#afd7af", - "#afd7d7", - "#afd7ff", - "#afff00", - "#afff5f", - "#afff87", - "#afffaf", - "#afffd7", - "#afffff", - "#d70000", - "#d7005f", - "#d70087", - "#d700af", - "#d700d7", - "#d700ff", - "#d75f00", - "#d75f5f", - "#d75f87", - "#d75faf", - "#d75fd7", - "#d75fff", - "#d78700", - "#d7875f", - "#d78787", - "#d787af", - "#d787d7", - "#d787ff", - "#d7af00", - "#d7af5f", - "#d7af87", - "#d7afaf", - "#d7afd7", - "#d7afff", - "#d7d700", - "#d7d75f", - "#d7d787", - "#d7d7af", - "#d7d7d7", - "#d7d7ff", - "#d7ff00", - "#d7ff5f", - "#d7ff87", - "#d7ffaf", - "#d7ffd7", - "#d7ffff", - "#ff0000", - "#ff005f", - "#ff0087", - "#ff00af", - "#ff00d7", - "#ff00ff", - "#ff5f00", - "#ff5f5f", - "#ff5f87", - "#ff5faf", - "#ff5fd7", - "#ff5fff", - "#ff8700", - "#ff875f", - "#ff8787", - "#ff87af", - "#ff87d7", - "#ff87ff", - "#ffaf00", - "#ffaf5f", - "#ffaf87", - "#ffafaf", - "#ffafd7", - "#ffafff", - "#ffd700", - "#ffd75f", - "#ffd787", - "#ffd7af", - "#ffd7d7", - "#ffd7ff", - "#ffff00", - "#ffff5f", - "#ffff87", - "#ffffaf", - "#ffffd7", - "#ffffff", - "#080808", - "#121212", - "#1c1c1c", - "#262626", - "#303030", - "#3a3a3a", - "#444444", - "#4e4e4e", - "#585858", - "#626262", - "#6c6c6c", - "#767676", - "#808080", - "#8a8a8a", - "#949494", - "#9e9e9e", - "#a8a8a8", - "#b2b2b2", - "#bcbcbc", - "#c6c6c6", - "#d0d0d0", - "#dadada", - "#e4e4e4", - "#eeeeee", -} diff --git a/vendor/github.com/charmbracelet/colorprofile/writer.go b/vendor/github.com/charmbracelet/colorprofile/writer.go deleted file mode 100644 index d04b3b99d6..0000000000 --- a/vendor/github.com/charmbracelet/colorprofile/writer.go +++ /dev/null @@ -1,166 +0,0 @@ -package colorprofile - -import ( - "bytes" - "image/color" - "io" - "strconv" - - "github.com/charmbracelet/x/ansi" -) - -// NewWriter creates a new color profile writer that downgrades color sequences -// based on the detected color profile. -// -// If environ is nil, it will use os.Environ() to get the environment variables. -// -// It queries the given writer to determine if it supports ANSI escape codes. -// If it does, along with the given environment variables, it will determine -// the appropriate color profile to use for color formatting. -// -// This respects the NO_COLOR, CLICOLOR, and CLICOLOR_FORCE environment variables. -func NewWriter(w io.Writer, environ []string) *Writer { - return &Writer{ - Forward: w, - Profile: Detect(w, environ), - } -} - -// Writer represents a color profile writer that writes ANSI sequences to the -// underlying writer. -type Writer struct { - Forward io.Writer - Profile Profile -} - -// Write writes the given text to the underlying writer. -func (w *Writer) Write(p []byte) (int, error) { - switch w.Profile { - case TrueColor: - return w.Forward.Write(p) - case NoTTY: - return io.WriteString(w.Forward, ansi.Strip(string(p))) - default: - return w.downsample(p) - } -} - -// downsample downgrades the given text to the appropriate color profile. -func (w *Writer) downsample(p []byte) (int, error) { - var buf bytes.Buffer - var state byte - - parser := ansi.GetParser() - defer ansi.PutParser(parser) - - for len(p) > 0 { - parser.Reset() - seq, _, read, newState := ansi.DecodeSequence(p, state, parser) - - switch { - case ansi.HasCsiPrefix(seq) && parser.Command() == 'm': - handleSgr(w, parser, &buf) - default: - // If we're not a style SGR sequence, just write the bytes. - if n, err := buf.Write(seq); err != nil { - return n, err - } - } - - p = p[read:] - state = newState - } - - return w.Forward.Write(buf.Bytes()) -} - -// WriteString writes the given text to the underlying writer. -func (w *Writer) WriteString(s string) (n int, err error) { - return w.Write([]byte(s)) -} - -func handleSgr(w *Writer, p *ansi.Parser, buf *bytes.Buffer) { - var style ansi.Style - params := p.Params() - for i := 0; i < len(params); i++ { - param := params[i] - - switch param := param.Param(0); param { - case 0: - // SGR default parameter is 0. We use an empty string to reduce the - // number of bytes written to the buffer. - style = append(style, "") - case 30, 31, 32, 33, 34, 35, 36, 37: // 8-bit foreground color - if w.Profile < ANSI { - continue - } - style = style.ForegroundColor( - w.Profile.Convert(ansi.BasicColor(param - 30))) //nolint:gosec - case 38: // 16 or 24-bit foreground color - var c color.Color - if n := ansi.ReadStyleColor(params[i:], &c); n > 0 { - i += n - 1 - } - if w.Profile < ANSI { - continue - } - style = style.ForegroundColor(w.Profile.Convert(c)) - case 39: // default foreground color - if w.Profile < ANSI { - continue - } - style = style.DefaultForegroundColor() - case 40, 41, 42, 43, 44, 45, 46, 47: // 8-bit background color - if w.Profile < ANSI { - continue - } - style = style.BackgroundColor( - w.Profile.Convert(ansi.BasicColor(param - 40))) //nolint:gosec - case 48: // 16 or 24-bit background color - var c color.Color - if n := ansi.ReadStyleColor(params[i:], &c); n > 0 { - i += n - 1 - } - if w.Profile < ANSI { - continue - } - style = style.BackgroundColor(w.Profile.Convert(c)) - case 49: // default background color - if w.Profile < ANSI { - continue - } - style = style.DefaultBackgroundColor() - case 58: // 16 or 24-bit underline color - var c color.Color - if n := ansi.ReadStyleColor(params[i:], &c); n > 0 { - i += n - 1 - } - if w.Profile < ANSI { - continue - } - style = style.UnderlineColor(w.Profile.Convert(c)) - case 59: // default underline color - if w.Profile < ANSI { - continue - } - style = style.DefaultUnderlineColor() - case 90, 91, 92, 93, 94, 95, 96, 97: // 8-bit bright foreground color - if w.Profile < ANSI { - continue - } - style = style.ForegroundColor( - w.Profile.Convert(ansi.BasicColor(param - 90 + 8))) //nolint:gosec - case 100, 101, 102, 103, 104, 105, 106, 107: // 8-bit bright background color - if w.Profile < ANSI { - continue - } - style = style.BackgroundColor( - w.Profile.Convert(ansi.BasicColor(param - 100 + 8))) //nolint:gosec - default: - // If this is not a color attribute, just append it to the style. - style = append(style, strconv.Itoa(param)) - } - } - - _, _ = buf.WriteString(style.String()) -} diff --git a/vendor/github.com/charmbracelet/lipgloss/.gitignore b/vendor/github.com/charmbracelet/lipgloss/.gitignore deleted file mode 100644 index db482015dd..0000000000 --- a/vendor/github.com/charmbracelet/lipgloss/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -ssh_example_ed25519* -dist/ diff --git a/vendor/github.com/charmbracelet/lipgloss/.golangci.yml b/vendor/github.com/charmbracelet/lipgloss/.golangci.yml deleted file mode 100644 index 90c5c08bd0..0000000000 --- a/vendor/github.com/charmbracelet/lipgloss/.golangci.yml +++ /dev/null @@ -1,41 +0,0 @@ -run: - tests: false - -issues: - include: - - EXC0001 - - EXC0005 - - EXC0011 - - EXC0012 - - EXC0013 - - max-issues-per-linter: 0 - max-same-issues: 0 - -linters: - enable: - - bodyclose - - exhaustive - - goconst - - godot - - godox - - gofumpt - - goimports - - gomoddirectives - - goprintffuncname - - gosec - - misspell - - nakedret - - nestif - - nilerr - - noctx - - nolintlint - - prealloc - - revive - - rowserrcheck - - sqlclosecheck - - tparallel - - unconvert - - unparam - - whitespace - - wrapcheck diff --git a/vendor/github.com/charmbracelet/lipgloss/.goreleaser.yml b/vendor/github.com/charmbracelet/lipgloss/.goreleaser.yml deleted file mode 100644 index 3353d02029..0000000000 --- a/vendor/github.com/charmbracelet/lipgloss/.goreleaser.yml +++ /dev/null @@ -1,5 +0,0 @@ -# yaml-language-server: $schema=https://goreleaser.com/static/schema-pro.json -version: 2 -includes: - - from_url: - url: charmbracelet/meta/main/goreleaser-lib.yaml diff --git a/vendor/github.com/charmbracelet/lipgloss/LICENSE b/vendor/github.com/charmbracelet/lipgloss/LICENSE deleted file mode 100644 index 6f5b1fa620..0000000000 --- a/vendor/github.com/charmbracelet/lipgloss/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2021-2023 Charmbracelet, Inc - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/charmbracelet/lipgloss/README.md b/vendor/github.com/charmbracelet/lipgloss/README.md deleted file mode 100644 index cee2371ce1..0000000000 --- a/vendor/github.com/charmbracelet/lipgloss/README.md +++ /dev/null @@ -1,815 +0,0 @@ -# Lip Gloss - -

- Lip Gloss title treatment
- Latest Release - GoDoc - Build Status - phorm.ai -

- -Style definitions for nice terminal layouts. Built with TUIs in mind. - -![Lip Gloss example](https://github.com/user-attachments/assets/7950b1c1-e0e3-427e-8e7d-6f7f6ad17ca7) - -Lip Gloss takes an expressive, declarative approach to terminal rendering. -Users familiar with CSS will feel at home with Lip Gloss. - -```go - -import "github.com/charmbracelet/lipgloss" - -var style = lipgloss.NewStyle(). - Bold(true). - Foreground(lipgloss.Color("#FAFAFA")). - Background(lipgloss.Color("#7D56F4")). - PaddingTop(2). - PaddingLeft(4). - Width(22) - -fmt.Println(style.Render("Hello, kitty")) -``` - -## Colors - -Lip Gloss supports the following color profiles: - -### ANSI 16 colors (4-bit) - -```go -lipgloss.Color("5") // magenta -lipgloss.Color("9") // red -lipgloss.Color("12") // light blue -``` - -### ANSI 256 Colors (8-bit) - -```go -lipgloss.Color("86") // aqua -lipgloss.Color("201") // hot pink -lipgloss.Color("202") // orange -``` - -### True Color (16,777,216 colors; 24-bit) - -```go -lipgloss.Color("#0000FF") // good ol' 100% blue -lipgloss.Color("#04B575") // a green -lipgloss.Color("#3C3C3C") // a dark gray -``` - -...as well as a 1-bit ASCII profile, which is black and white only. - -The terminal's color profile will be automatically detected, and colors outside -the gamut of the current palette will be automatically coerced to their closest -available value. - -### Adaptive Colors - -You can also specify color options for light and dark backgrounds: - -```go -lipgloss.AdaptiveColor{Light: "236", Dark: "248"} -``` - -The terminal's background color will automatically be detected and the -appropriate color will be chosen at runtime. - -### Complete Colors - -CompleteColor specifies exact values for True Color, ANSI256, and ANSI color -profiles. - -```go -lipgloss.CompleteColor{TrueColor: "#0000FF", ANSI256: "86", ANSI: "5"} -``` - -Automatic color degradation will not be performed in this case and it will be -based on the color specified. - -### Complete Adaptive Colors - -You can use `CompleteColor` with `AdaptiveColor` to specify the exact values for -light and dark backgrounds without automatic color degradation. - -```go -lipgloss.CompleteAdaptiveColor{ - Light: CompleteColor{TrueColor: "#d7ffae", ANSI256: "193", ANSI: "11"}, - Dark: CompleteColor{TrueColor: "#d75fee", ANSI256: "163", ANSI: "5"}, -} -``` - -## Inline Formatting - -Lip Gloss supports the usual ANSI text formatting options: - -```go -var style = lipgloss.NewStyle(). - Bold(true). - Italic(true). - Faint(true). - Blink(true). - Strikethrough(true). - Underline(true). - Reverse(true) -``` - -## Block-Level Formatting - -Lip Gloss also supports rules for block-level formatting: - -```go -// Padding -var style = lipgloss.NewStyle(). - PaddingTop(2). - PaddingRight(4). - PaddingBottom(2). - PaddingLeft(4) - -// Margins -var style = lipgloss.NewStyle(). - MarginTop(2). - MarginRight(4). - MarginBottom(2). - MarginLeft(4) -``` - -There is also shorthand syntax for margins and padding, which follows the same -format as CSS: - -```go -// 2 cells on all sides -lipgloss.NewStyle().Padding(2) - -// 2 cells on the top and bottom, 4 cells on the left and right -lipgloss.NewStyle().Margin(2, 4) - -// 1 cell on the top, 4 cells on the sides, 2 cells on the bottom -lipgloss.NewStyle().Padding(1, 4, 2) - -// Clockwise, starting from the top: 2 cells on the top, 4 on the right, 3 on -// the bottom, and 1 on the left -lipgloss.NewStyle().Margin(2, 4, 3, 1) -``` - -## Aligning Text - -You can align paragraphs of text to the left, right, or center. - -```go -var style = lipgloss.NewStyle(). - Width(24). - Align(lipgloss.Left). // align it left - Align(lipgloss.Right). // no wait, align it right - Align(lipgloss.Center) // just kidding, align it in the center -``` - -## Width and Height - -Setting a minimum width and height is simple and straightforward. - -```go -var style = lipgloss.NewStyle(). - SetString("What’s for lunch?"). - Width(24). - Height(32). - Foreground(lipgloss.Color("63")) -``` - -## Borders - -Adding borders is easy: - -```go -// Add a purple, rectangular border -var style = lipgloss.NewStyle(). - BorderStyle(lipgloss.NormalBorder()). - BorderForeground(lipgloss.Color("63")) - -// Set a rounded, yellow-on-purple border to the top and left -var anotherStyle = lipgloss.NewStyle(). - BorderStyle(lipgloss.RoundedBorder()). - BorderForeground(lipgloss.Color("228")). - BorderBackground(lipgloss.Color("63")). - BorderTop(true). - BorderLeft(true) - -// Make your own border -var myCuteBorder = lipgloss.Border{ - Top: "._.:*:", - Bottom: "._.:*:", - Left: "|*", - Right: "|*", - TopLeft: "*", - TopRight: "*", - BottomLeft: "*", - BottomRight: "*", -} -``` - -There are also shorthand functions for defining borders, which follow a similar -pattern to the margin and padding shorthand functions. - -```go -// Add a thick border to the top and bottom -lipgloss.NewStyle(). - Border(lipgloss.ThickBorder(), true, false) - -// Add a double border to the top and left sides. Rules are set clockwise -// from top. -lipgloss.NewStyle(). - Border(lipgloss.DoubleBorder(), true, false, false, true) -``` - -For more on borders see [the docs][docs]. - -## Copying Styles - -Just use assignment: - -```go -style := lipgloss.NewStyle().Foreground(lipgloss.Color("219")) - -copiedStyle := style // this is a true copy - -wildStyle := style.Blink(true) // this is also true copy, with blink added - -``` - -Since `Style` data structures contains only primitive types, assigning a style -to another effectively creates a new copy of the style without mutating the -original. - -## Inheritance - -Styles can inherit rules from other styles. When inheriting, only unset rules -on the receiver are inherited. - -```go -var styleA = lipgloss.NewStyle(). - Foreground(lipgloss.Color("229")). - Background(lipgloss.Color("63")) - -// Only the background color will be inherited here, because the foreground -// color will have been already set: -var styleB = lipgloss.NewStyle(). - Foreground(lipgloss.Color("201")). - Inherit(styleA) -``` - -## Unsetting Rules - -All rules can be unset: - -```go -var style = lipgloss.NewStyle(). - Bold(true). // make it bold - UnsetBold(). // jk don't make it bold - Background(lipgloss.Color("227")). // yellow background - UnsetBackground() // never mind -``` - -When a rule is unset, it won't be inherited or copied. - -## Enforcing Rules - -Sometimes, such as when developing a component, you want to make sure style -definitions respect their intended purpose in the UI. This is where `Inline` -and `MaxWidth`, and `MaxHeight` come in: - -```go -// Force rendering onto a single line, ignoring margins, padding, and borders. -someStyle.Inline(true).Render("yadda yadda") - -// Also limit rendering to five cells -someStyle.Inline(true).MaxWidth(5).Render("yadda yadda") - -// Limit rendering to a 5x5 cell block -someStyle.MaxWidth(5).MaxHeight(5).Render("yadda yadda") -``` - -## Tabs - -The tab character (`\t`) is rendered differently in different terminals (often -as 8 spaces, sometimes 4). Because of this inconsistency, Lip Gloss converts -tabs to 4 spaces at render time. This behavior can be changed on a per-style -basis, however: - -```go -style := lipgloss.NewStyle() // tabs will render as 4 spaces, the default -style = style.TabWidth(2) // render tabs as 2 spaces -style = style.TabWidth(0) // remove tabs entirely -style = style.TabWidth(lipgloss.NoTabConversion) // leave tabs intact -``` - -## Rendering - -Generally, you just call the `Render(string...)` method on a `lipgloss.Style`: - -```go -style := lipgloss.NewStyle().Bold(true).SetString("Hello,") -fmt.Println(style.Render("kitty.")) // Hello, kitty. -fmt.Println(style.Render("puppy.")) // Hello, puppy. -``` - -But you could also use the Stringer interface: - -```go -var style = lipgloss.NewStyle().SetString("你好,猫咪。").Bold(true) -fmt.Println(style) // 你好,猫咪。 -``` - -### Custom Renderers - -Custom renderers allow you to render to a specific outputs. This is -particularly important when you want to render to different outputs and -correctly detect the color profile and dark background status for each, such as -in a server-client situation. - -```go -func myLittleHandler(sess ssh.Session) { - // Create a renderer for the client. - renderer := lipgloss.NewRenderer(sess) - - // Create a new style on the renderer. - style := renderer.NewStyle().Background(lipgloss.AdaptiveColor{Light: "63", Dark: "228"}) - - // Render. The color profile and dark background state will be correctly detected. - io.WriteString(sess, style.Render("Heyyyyyyy")) -} -``` - -For an example on using a custom renderer over SSH with [Wish][wish] see the -[SSH example][ssh-example]. - -## Utilities - -In addition to pure styling, Lip Gloss also ships with some utilities to help -assemble your layouts. - -### Joining Paragraphs - -Horizontally and vertically joining paragraphs is a cinch. - -```go -// Horizontally join three paragraphs along their bottom edges -lipgloss.JoinHorizontal(lipgloss.Bottom, paragraphA, paragraphB, paragraphC) - -// Vertically join two paragraphs along their center axes -lipgloss.JoinVertical(lipgloss.Center, paragraphA, paragraphB) - -// Horizontally join three paragraphs, with the shorter ones aligning 20% -// from the top of the tallest -lipgloss.JoinHorizontal(0.2, paragraphA, paragraphB, paragraphC) -``` - -### Measuring Width and Height - -Sometimes you’ll want to know the width and height of text blocks when building -your layouts. - -```go -// Render a block of text. -var style = lipgloss.NewStyle(). - Width(40). - Padding(2) -var block string = style.Render(someLongString) - -// Get the actual, physical dimensions of the text block. -width := lipgloss.Width(block) -height := lipgloss.Height(block) - -// Here's a shorthand function. -w, h := lipgloss.Size(block) -``` - -### Placing Text in Whitespace - -Sometimes you’ll simply want to place a block of text in whitespace. - -```go -// Center a paragraph horizontally in a space 80 cells wide. The height of -// the block returned will be as tall as the input paragraph. -block := lipgloss.PlaceHorizontal(80, lipgloss.Center, fancyStyledParagraph) - -// Place a paragraph at the bottom of a space 30 cells tall. The width of -// the text block returned will be as wide as the input paragraph. -block := lipgloss.PlaceVertical(30, lipgloss.Bottom, fancyStyledParagraph) - -// Place a paragraph in the bottom right corner of a 30x80 cell space. -block := lipgloss.Place(30, 80, lipgloss.Right, lipgloss.Bottom, fancyStyledParagraph) -``` - -You can also style the whitespace. For details, see [the docs][docs]. - -## Rendering Tables - -Lip Gloss ships with a table rendering sub-package. - -```go -import "github.com/charmbracelet/lipgloss/table" -``` - -Define some rows of data. - -```go -rows := [][]string{ - {"Chinese", "您好", "你好"}, - {"Japanese", "こんにちは", "やあ"}, - {"Arabic", "أهلين", "أهلا"}, - {"Russian", "Здравствуйте", "Привет"}, - {"Spanish", "Hola", "¿Qué tal?"}, -} -``` - -Use the table package to style and render the table. - -```go -var ( - purple = lipgloss.Color("99") - gray = lipgloss.Color("245") - lightGray = lipgloss.Color("241") - - headerStyle = lipgloss.NewStyle().Foreground(purple).Bold(true).Align(lipgloss.Center) - cellStyle = lipgloss.NewStyle().Padding(0, 1).Width(14) - oddRowStyle = cellStyle.Foreground(gray) - evenRowStyle = cellStyle.Foreground(lightGray) -) - -t := table.New(). - Border(lipgloss.NormalBorder()). - BorderStyle(lipgloss.NewStyle().Foreground(purple)). - StyleFunc(func(row, col int) lipgloss.Style { - switch { - case row == table.HeaderRow: - return headerStyle - case row%2 == 0: - return evenRowStyle - default: - return oddRowStyle - } - }). - Headers("LANGUAGE", "FORMAL", "INFORMAL"). - Rows(rows...) - -// You can also add tables row-by-row -t.Row("English", "You look absolutely fabulous.", "How's it going?") -``` - -Print the table. - -```go -fmt.Println(t) -``` - -![Table Example](https://github.com/charmbracelet/lipgloss/assets/42545625/6e4b70c4-f494-45da-a467-bdd27df30d5d) - -> [!WARNING] -> Table `Rows` need to be declared before `Offset` otherwise it does nothing. - -### Table Borders - -There are helpers to generate tables in markdown or ASCII style: - -#### Markdown Table - -```go -table.New().Border(lipgloss.MarkdownBorder()).BorderTop(false).BorderBottom(false) -``` - -``` -| LANGUAGE | FORMAL | INFORMAL | -|----------|--------------|-----------| -| Chinese | Nǐn hǎo | Nǐ hǎo | -| French | Bonjour | Salut | -| Russian | Zdravstvuyte | Privet | -| Spanish | Hola | ¿Qué tal? | -``` - -#### ASCII Table - -```go -table.New().Border(lipgloss.ASCIIBorder()) -``` - -``` -+----------+--------------+-----------+ -| LANGUAGE | FORMAL | INFORMAL | -+----------+--------------+-----------+ -| Chinese | Nǐn hǎo | Nǐ hǎo | -| French | Bonjour | Salut | -| Russian | Zdravstvuyte | Privet | -| Spanish | Hola | ¿Qué tal? | -+----------+--------------+-----------+ -``` - -For more on tables see [the docs](https://pkg.go.dev/github.com/charmbracelet/lipgloss?tab=doc) and [examples](https://github.com/charmbracelet/lipgloss/tree/master/examples/table). - -## Rendering Lists - -Lip Gloss ships with a list rendering sub-package. - -```go -import "github.com/charmbracelet/lipgloss/list" -``` - -Define a new list. - -```go -l := list.New("A", "B", "C") -``` - -Print the list. - -```go -fmt.Println(l) - -// • A -// • B -// • C -``` - -Lists have the ability to nest. - -```go -l := list.New( - "A", list.New("Artichoke"), - "B", list.New("Baking Flour", "Bananas", "Barley", "Bean Sprouts"), - "C", list.New("Cashew Apple", "Cashews", "Coconut Milk", "Curry Paste", "Currywurst"), - "D", list.New("Dill", "Dragonfruit", "Dried Shrimp"), - "E", list.New("Eggs"), - "F", list.New("Fish Cake", "Furikake"), - "J", list.New("Jicama"), - "K", list.New("Kohlrabi"), - "L", list.New("Leeks", "Lentils", "Licorice Root"), -) -``` - -Print the list. - -```go -fmt.Println(l) -``` - -

-image -

- -Lists can be customized via their enumeration function as well as using -`lipgloss.Style`s. - -```go -enumeratorStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("99")).MarginRight(1) -itemStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("212")).MarginRight(1) - -l := list.New( - "Glossier", - "Claire’s Boutique", - "Nyx", - "Mac", - "Milk", - ). - Enumerator(list.Roman). - EnumeratorStyle(enumeratorStyle). - ItemStyle(itemStyle) -``` - -Print the list. - -

-List example -

- -In addition to the predefined enumerators (`Arabic`, `Alphabet`, `Roman`, `Bullet`, `Tree`), -you may also define your own custom enumerator: - -```go -l := list.New("Duck", "Duck", "Duck", "Duck", "Goose", "Duck", "Duck") - -func DuckDuckGooseEnumerator(l list.Items, i int) string { - if l.At(i).Value() == "Goose" { - return "Honk →" - } - return "" -} - -l = l.Enumerator(DuckDuckGooseEnumerator) -``` - -Print the list: - -

-image -

- -If you need, you can also build lists incrementally: - -```go -l := list.New() - -for i := 0; i < repeat; i++ { - l.Item("Lip Gloss") -} -``` - -## Rendering Trees - -Lip Gloss ships with a tree rendering sub-package. - -```go -import "github.com/charmbracelet/lipgloss/tree" -``` - -Define a new tree. - -```go -t := tree.Root("."). - Child("A", "B", "C") -``` - -Print the tree. - -```go -fmt.Println(t) - -// . -// ├── A -// ├── B -// └── C -``` - -Trees have the ability to nest. - -```go -t := tree.Root("."). - Child("macOS"). - Child( - tree.New(). - Root("Linux"). - Child("NixOS"). - Child("Arch Linux (btw)"). - Child("Void Linux"), - ). - Child( - tree.New(). - Root("BSD"). - Child("FreeBSD"). - Child("OpenBSD"), - ) -``` - -Print the tree. - -```go -fmt.Println(t) -``` - -

-Tree Example (simple) -

- -Trees can be customized via their enumeration function as well as using -`lipgloss.Style`s. - -```go -enumeratorStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("63")).MarginRight(1) -rootStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("35")) -itemStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("212")) - -t := tree. - Root("⁜ Makeup"). - Child( - "Glossier", - "Fenty Beauty", - tree.New().Child( - "Gloss Bomb Universal Lip Luminizer", - "Hot Cheeks Velour Blushlighter", - ), - "Nyx", - "Mac", - "Milk", - ). - Enumerator(tree.RoundedEnumerator). - EnumeratorStyle(enumeratorStyle). - RootStyle(rootStyle). - ItemStyle(itemStyle) -``` - -Print the tree. - -

-Tree Example (makeup) -

- -The predefined enumerators for trees are `DefaultEnumerator` and `RoundedEnumerator`. - -If you need, you can also build trees incrementally: - -```go -t := tree.New() - -for i := 0; i < repeat; i++ { - t.Child("Lip Gloss") -} -``` - ---- - -## FAQ - -
- -Why are things misaligning? Why are borders at the wrong widths? - -

This is most likely due to your locale and encoding, particularly with -regard to Chinese, Japanese, and Korean (for example, zh_CN.UTF-8 -or ja_JP.UTF-8). The most direct way to fix this is to set -RUNEWIDTH_EASTASIAN=0 in your environment.

- -

For details see https://github.com/charmbracelet/lipgloss/issues/40.

-
- -
- -Why isn't Lip Gloss displaying colors? - -

Lip Gloss automatically degrades colors to the best available option in the -given terminal, and if output's not a TTY it will remove color output entirely. -This is common when running tests, CI, or when piping output elsewhere.

- -

If necessary, you can force a color profile in your tests with -SetColorProfile.

- -```go -import ( - "github.com/charmbracelet/lipgloss" - "github.com/muesli/termenv" -) - -lipgloss.SetColorProfile(termenv.TrueColor) -``` - -_Note:_ this option limits the flexibility of your application and can cause -ANSI escape codes to be output in cases where that might not be desired. Take -careful note of your use case and environment before choosing to force a color -profile. - -
- -## What about [Bubble Tea][tea]? - -Lip Gloss doesn’t replace Bubble Tea. Rather, it is an excellent Bubble Tea -companion. It was designed to make assembling terminal user interface views as -simple and fun as possible so that you can focus on building your application -instead of concerning yourself with low-level layout details. - -In simple terms, you can use Lip Gloss to help build your Bubble Tea views. - -[tea]: https://github.com/charmbracelet/tea - -## Under the Hood - -Lip Gloss is built on the excellent [Termenv][termenv] and [Reflow][reflow] -libraries which deal with color and ANSI-aware text operations, respectively. -For many use cases Termenv and Reflow will be sufficient for your needs. - -[termenv]: https://github.com/muesli/termenv -[reflow]: https://github.com/muesli/reflow - -## Rendering Markdown - -For a more document-centric rendering solution with support for things like -lists, tables, and syntax-highlighted code have a look at [Glamour][glamour], -the stylesheet-based Markdown renderer. - -[glamour]: https://github.com/charmbracelet/glamour - -## Contributing - -See [contributing][contribute]. - -[contribute]: https://github.com/charmbracelet/lipgloss/contribute - -## Feedback - -We’d love to hear your thoughts on this project. Feel free to drop us a note! - -- [Twitter](https://twitter.com/charmcli) -- [The Fediverse](https://mastodon.social/@charmcli) -- [Discord](https://charm.sh/chat) - -## License - -[MIT](https://github.com/charmbracelet/lipgloss/raw/master/LICENSE) - ---- - -Part of [Charm](https://charm.sh). - -The Charm logo - -Charm热爱开源 • Charm loves open source - -[docs]: https://pkg.go.dev/github.com/charmbracelet/lipgloss?tab=doc -[wish]: https://github.com/charmbracelet/wish -[ssh-example]: examples/ssh diff --git a/vendor/github.com/charmbracelet/lipgloss/Taskfile.yaml b/vendor/github.com/charmbracelet/lipgloss/Taskfile.yaml deleted file mode 100644 index 0b4a7711a8..0000000000 --- a/vendor/github.com/charmbracelet/lipgloss/Taskfile.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# https://taskfile.dev - -version: '3' - -tasks: - lint: - desc: Run base linters - cmds: - - golangci-lint run - - test: - desc: Run tests - cmds: - - go test ./... {{.CLI_ARGS}} - - test:table: - desc: Run table tests - cmds: - - go test ./table {{.CLI_ARGS}} diff --git a/vendor/github.com/charmbracelet/lipgloss/align.go b/vendor/github.com/charmbracelet/lipgloss/align.go deleted file mode 100644 index ce654b232a..0000000000 --- a/vendor/github.com/charmbracelet/lipgloss/align.go +++ /dev/null @@ -1,83 +0,0 @@ -package lipgloss - -import ( - "strings" - - "github.com/charmbracelet/x/ansi" - "github.com/muesli/termenv" -) - -// Perform text alignment. If the string is multi-lined, we also make all lines -// the same width by padding them with spaces. If a termenv style is passed, -// use that to style the spaces added. -func alignTextHorizontal(str string, pos Position, width int, style *termenv.Style) string { - lines, widestLine := getLines(str) - var b strings.Builder - - for i, l := range lines { - lineWidth := ansi.StringWidth(l) - - shortAmount := widestLine - lineWidth // difference from the widest line - shortAmount += max(0, width-(shortAmount+lineWidth)) // difference from the total width, if set - - if shortAmount > 0 { - switch pos { //nolint:exhaustive - case Right: - s := strings.Repeat(" ", shortAmount) - if style != nil { - s = style.Styled(s) - } - l = s + l - case Center: - // Note: remainder goes on the right. - left := shortAmount / 2 //nolint:mnd - right := left + shortAmount%2 //nolint:mnd - - leftSpaces := strings.Repeat(" ", left) - rightSpaces := strings.Repeat(" ", right) - - if style != nil { - leftSpaces = style.Styled(leftSpaces) - rightSpaces = style.Styled(rightSpaces) - } - l = leftSpaces + l + rightSpaces - default: // Left - s := strings.Repeat(" ", shortAmount) - if style != nil { - s = style.Styled(s) - } - l += s - } - } - - b.WriteString(l) - if i < len(lines)-1 { - b.WriteRune('\n') - } - } - - return b.String() -} - -func alignTextVertical(str string, pos Position, height int, _ *termenv.Style) string { - strHeight := strings.Count(str, "\n") + 1 - if height < strHeight { - return str - } - - switch pos { - case Top: - return str + strings.Repeat("\n", height-strHeight) - case Center: - topPadding, bottomPadding := (height-strHeight)/2, (height-strHeight)/2 //nolint:mnd - if strHeight+topPadding+bottomPadding > height { - topPadding-- - } else if strHeight+topPadding+bottomPadding < height { - bottomPadding++ - } - return strings.Repeat("\n", topPadding) + str + strings.Repeat("\n", bottomPadding) - case Bottom: - return strings.Repeat("\n", height-strHeight) + str - } - return str -} diff --git a/vendor/github.com/charmbracelet/lipgloss/ansi_unix.go b/vendor/github.com/charmbracelet/lipgloss/ansi_unix.go deleted file mode 100644 index d416b8c99b..0000000000 --- a/vendor/github.com/charmbracelet/lipgloss/ansi_unix.go +++ /dev/null @@ -1,7 +0,0 @@ -//go:build !windows -// +build !windows - -package lipgloss - -// enableLegacyWindowsANSI is only needed on Windows. -func enableLegacyWindowsANSI() {} diff --git a/vendor/github.com/charmbracelet/lipgloss/ansi_windows.go b/vendor/github.com/charmbracelet/lipgloss/ansi_windows.go deleted file mode 100644 index 0cf56e4c70..0000000000 --- a/vendor/github.com/charmbracelet/lipgloss/ansi_windows.go +++ /dev/null @@ -1,22 +0,0 @@ -//go:build windows -// +build windows - -package lipgloss - -import ( - "sync" - - "github.com/muesli/termenv" -) - -var enableANSI sync.Once - -// enableANSIColors enables support for ANSI color sequences in the Windows -// default console (cmd.exe and the PowerShell application). Note that this -// only works with Windows 10. Also note that Windows Terminal supports colors -// by default. -func enableLegacyWindowsANSI() { - enableANSI.Do(func() { - _, _ = termenv.EnableWindowsANSIConsole() - }) -} diff --git a/vendor/github.com/charmbracelet/lipgloss/borders.go b/vendor/github.com/charmbracelet/lipgloss/borders.go deleted file mode 100644 index b36f874388..0000000000 --- a/vendor/github.com/charmbracelet/lipgloss/borders.go +++ /dev/null @@ -1,490 +0,0 @@ -package lipgloss - -import ( - "strings" - - "github.com/charmbracelet/x/ansi" - "github.com/muesli/termenv" - "github.com/rivo/uniseg" -) - -// Border contains a series of values which comprise the various parts of a -// border. -type Border struct { - Top string - Bottom string - Left string - Right string - TopLeft string - TopRight string - BottomLeft string - BottomRight string - MiddleLeft string - MiddleRight string - Middle string - MiddleTop string - MiddleBottom string -} - -// GetTopSize returns the width of the top border. If borders contain runes of -// varying widths, the widest rune is returned. If no border exists on the top -// edge, 0 is returned. -func (b Border) GetTopSize() int { - return getBorderEdgeWidth(b.TopLeft, b.Top, b.TopRight) -} - -// GetRightSize returns the width of the right border. If borders contain -// runes of varying widths, the widest rune is returned. If no border exists on -// the right edge, 0 is returned. -func (b Border) GetRightSize() int { - return getBorderEdgeWidth(b.TopRight, b.Right, b.BottomRight) -} - -// GetBottomSize returns the width of the bottom border. If borders contain -// runes of varying widths, the widest rune is returned. If no border exists on -// the bottom edge, 0 is returned. -func (b Border) GetBottomSize() int { - return getBorderEdgeWidth(b.BottomLeft, b.Bottom, b.BottomRight) -} - -// GetLeftSize returns the width of the left border. If borders contain runes -// of varying widths, the widest rune is returned. If no border exists on the -// left edge, 0 is returned. -func (b Border) GetLeftSize() int { - return getBorderEdgeWidth(b.TopLeft, b.Left, b.BottomLeft) -} - -func getBorderEdgeWidth(borderParts ...string) (maxWidth int) { - for _, piece := range borderParts { - w := maxRuneWidth(piece) - if w > maxWidth { - maxWidth = w - } - } - return maxWidth -} - -var ( - noBorder = Border{} - - normalBorder = Border{ - Top: "─", - Bottom: "─", - Left: "│", - Right: "│", - TopLeft: "┌", - TopRight: "┐", - BottomLeft: "└", - BottomRight: "┘", - MiddleLeft: "├", - MiddleRight: "┤", - Middle: "┼", - MiddleTop: "┬", - MiddleBottom: "┴", - } - - roundedBorder = Border{ - Top: "─", - Bottom: "─", - Left: "│", - Right: "│", - TopLeft: "╭", - TopRight: "╮", - BottomLeft: "╰", - BottomRight: "╯", - MiddleLeft: "├", - MiddleRight: "┤", - Middle: "┼", - MiddleTop: "┬", - MiddleBottom: "┴", - } - - blockBorder = Border{ - Top: "█", - Bottom: "█", - Left: "█", - Right: "█", - TopLeft: "█", - TopRight: "█", - BottomLeft: "█", - BottomRight: "█", - MiddleLeft: "█", - MiddleRight: "█", - Middle: "█", - MiddleTop: "█", - MiddleBottom: "█", - } - - outerHalfBlockBorder = Border{ - Top: "▀", - Bottom: "▄", - Left: "▌", - Right: "▐", - TopLeft: "▛", - TopRight: "▜", - BottomLeft: "▙", - BottomRight: "▟", - } - - innerHalfBlockBorder = Border{ - Top: "▄", - Bottom: "▀", - Left: "▐", - Right: "▌", - TopLeft: "▗", - TopRight: "▖", - BottomLeft: "▝", - BottomRight: "▘", - } - - thickBorder = Border{ - Top: "━", - Bottom: "━", - Left: "┃", - Right: "┃", - TopLeft: "┏", - TopRight: "┓", - BottomLeft: "┗", - BottomRight: "┛", - MiddleLeft: "┣", - MiddleRight: "┫", - Middle: "╋", - MiddleTop: "┳", - MiddleBottom: "┻", - } - - doubleBorder = Border{ - Top: "═", - Bottom: "═", - Left: "║", - Right: "║", - TopLeft: "╔", - TopRight: "╗", - BottomLeft: "╚", - BottomRight: "╝", - MiddleLeft: "╠", - MiddleRight: "╣", - Middle: "╬", - MiddleTop: "╦", - MiddleBottom: "╩", - } - - hiddenBorder = Border{ - Top: " ", - Bottom: " ", - Left: " ", - Right: " ", - TopLeft: " ", - TopRight: " ", - BottomLeft: " ", - BottomRight: " ", - MiddleLeft: " ", - MiddleRight: " ", - Middle: " ", - MiddleTop: " ", - MiddleBottom: " ", - } - - markdownBorder = Border{ - Top: "-", - Bottom: "-", - Left: "|", - Right: "|", - TopLeft: "|", - TopRight: "|", - BottomLeft: "|", - BottomRight: "|", - MiddleLeft: "|", - MiddleRight: "|", - Middle: "|", - MiddleTop: "|", - MiddleBottom: "|", - } - - asciiBorder = Border{ - Top: "-", - Bottom: "-", - Left: "|", - Right: "|", - TopLeft: "+", - TopRight: "+", - BottomLeft: "+", - BottomRight: "+", - MiddleLeft: "+", - MiddleRight: "+", - Middle: "+", - MiddleTop: "+", - MiddleBottom: "+", - } -) - -// NormalBorder returns a standard-type border with a normal weight and 90 -// degree corners. -func NormalBorder() Border { - return normalBorder -} - -// RoundedBorder returns a border with rounded corners. -func RoundedBorder() Border { - return roundedBorder -} - -// BlockBorder returns a border that takes the whole block. -func BlockBorder() Border { - return blockBorder -} - -// OuterHalfBlockBorder returns a half-block border that sits outside the frame. -func OuterHalfBlockBorder() Border { - return outerHalfBlockBorder -} - -// InnerHalfBlockBorder returns a half-block border that sits inside the frame. -func InnerHalfBlockBorder() Border { - return innerHalfBlockBorder -} - -// ThickBorder returns a border that's thicker than the one returned by -// NormalBorder. -func ThickBorder() Border { - return thickBorder -} - -// DoubleBorder returns a border comprised of two thin strokes. -func DoubleBorder() Border { - return doubleBorder -} - -// HiddenBorder returns a border that renders as a series of single-cell -// spaces. It's useful for cases when you want to remove a standard border but -// maintain layout positioning. This said, you can still apply a background -// color to a hidden border. -func HiddenBorder() Border { - return hiddenBorder -} - -// MarkdownBorder return a table border in markdown style. -// -// Make sure to disable top and bottom border for the best result. This will -// ensure that the output is valid markdown. -// -// table.New().Border(lipgloss.MarkdownBorder()).BorderTop(false).BorderBottom(false) -func MarkdownBorder() Border { - return markdownBorder -} - -// ASCIIBorder returns a table border with ASCII characters. -func ASCIIBorder() Border { - return asciiBorder -} - -func (s Style) applyBorder(str string) string { - var ( - border = s.getBorderStyle() - hasTop = s.getAsBool(borderTopKey, false) - hasRight = s.getAsBool(borderRightKey, false) - hasBottom = s.getAsBool(borderBottomKey, false) - hasLeft = s.getAsBool(borderLeftKey, false) - - topFG = s.getAsColor(borderTopForegroundKey) - rightFG = s.getAsColor(borderRightForegroundKey) - bottomFG = s.getAsColor(borderBottomForegroundKey) - leftFG = s.getAsColor(borderLeftForegroundKey) - - topBG = s.getAsColor(borderTopBackgroundKey) - rightBG = s.getAsColor(borderRightBackgroundKey) - bottomBG = s.getAsColor(borderBottomBackgroundKey) - leftBG = s.getAsColor(borderLeftBackgroundKey) - ) - - // If a border is set and no sides have been specifically turned on or off - // render borders on all sides. - if s.implicitBorders() { - hasTop = true - hasRight = true - hasBottom = true - hasLeft = true - } - - // If no border is set or all borders are been disabled, abort. - if border == noBorder || (!hasTop && !hasRight && !hasBottom && !hasLeft) { - return str - } - - lines, width := getLines(str) - - if hasLeft { - if border.Left == "" { - border.Left = " " - } - width += maxRuneWidth(border.Left) - } - - if hasRight && border.Right == "" { - border.Right = " " - } - - // If corners should be rendered but are set with the empty string, fill them - // with a single space. - if hasTop && hasLeft && border.TopLeft == "" { - border.TopLeft = " " - } - if hasTop && hasRight && border.TopRight == "" { - border.TopRight = " " - } - if hasBottom && hasLeft && border.BottomLeft == "" { - border.BottomLeft = " " - } - if hasBottom && hasRight && border.BottomRight == "" { - border.BottomRight = " " - } - - // Figure out which corners we should actually be using based on which - // sides are set to show. - if hasTop { - switch { - case !hasLeft && !hasRight: - border.TopLeft = "" - border.TopRight = "" - case !hasLeft: - border.TopLeft = "" - case !hasRight: - border.TopRight = "" - } - } - if hasBottom { - switch { - case !hasLeft && !hasRight: - border.BottomLeft = "" - border.BottomRight = "" - case !hasLeft: - border.BottomLeft = "" - case !hasRight: - border.BottomRight = "" - } - } - - // For now, limit corners to one rune. - border.TopLeft = getFirstRuneAsString(border.TopLeft) - border.TopRight = getFirstRuneAsString(border.TopRight) - border.BottomRight = getFirstRuneAsString(border.BottomRight) - border.BottomLeft = getFirstRuneAsString(border.BottomLeft) - - var out strings.Builder - - // Render top - if hasTop { - top := renderHorizontalEdge(border.TopLeft, border.Top, border.TopRight, width) - top = s.styleBorder(top, topFG, topBG) - out.WriteString(top) - out.WriteRune('\n') - } - - leftRunes := []rune(border.Left) - leftIndex := 0 - - rightRunes := []rune(border.Right) - rightIndex := 0 - - // Render sides - for i, l := range lines { - if hasLeft { - r := string(leftRunes[leftIndex]) - leftIndex++ - if leftIndex >= len(leftRunes) { - leftIndex = 0 - } - out.WriteString(s.styleBorder(r, leftFG, leftBG)) - } - out.WriteString(l) - if hasRight { - r := string(rightRunes[rightIndex]) - rightIndex++ - if rightIndex >= len(rightRunes) { - rightIndex = 0 - } - out.WriteString(s.styleBorder(r, rightFG, rightBG)) - } - if i < len(lines)-1 { - out.WriteRune('\n') - } - } - - // Render bottom - if hasBottom { - bottom := renderHorizontalEdge(border.BottomLeft, border.Bottom, border.BottomRight, width) - bottom = s.styleBorder(bottom, bottomFG, bottomBG) - out.WriteRune('\n') - out.WriteString(bottom) - } - - return out.String() -} - -// Render the horizontal (top or bottom) portion of a border. -func renderHorizontalEdge(left, middle, right string, width int) string { - if middle == "" { - middle = " " - } - - leftWidth := ansi.StringWidth(left) - rightWidth := ansi.StringWidth(right) - - runes := []rune(middle) - j := 0 - - out := strings.Builder{} - out.WriteString(left) - for i := leftWidth + rightWidth; i < width+rightWidth; { - out.WriteRune(runes[j]) - j++ - if j >= len(runes) { - j = 0 - } - i += ansi.StringWidth(string(runes[j])) - } - out.WriteString(right) - - return out.String() -} - -// Apply foreground and background styling to a border. -func (s Style) styleBorder(border string, fg, bg TerminalColor) string { - if fg == noColor && bg == noColor { - return border - } - - style := termenv.Style{} - - if fg != noColor { - style = style.Foreground(fg.color(s.r)) - } - if bg != noColor { - style = style.Background(bg.color(s.r)) - } - - return style.Styled(border) -} - -func maxRuneWidth(str string) int { - var width int - - state := -1 - for len(str) > 0 { - var w int - _, str, w, state = uniseg.FirstGraphemeClusterInString(str, state) - if w > width { - width = w - } - } - - return width -} - -func getFirstRuneAsString(str string) string { - if str == "" { - return str - } - r := []rune(str) - return string(r[0]) -} diff --git a/vendor/github.com/charmbracelet/lipgloss/color.go b/vendor/github.com/charmbracelet/lipgloss/color.go deleted file mode 100644 index 6caf3a3d5e..0000000000 --- a/vendor/github.com/charmbracelet/lipgloss/color.go +++ /dev/null @@ -1,172 +0,0 @@ -package lipgloss - -import ( - "strconv" - - "github.com/muesli/termenv" -) - -// TerminalColor is a color intended to be rendered in the terminal. -type TerminalColor interface { - color(*Renderer) termenv.Color - RGBA() (r, g, b, a uint32) -} - -var noColor = NoColor{} - -// NoColor is used to specify the absence of color styling. When this is active -// foreground colors will be rendered with the terminal's default text color, -// and background colors will not be drawn at all. -// -// Example usage: -// -// var style = someStyle.Background(lipgloss.NoColor{}) -type NoColor struct{} - -func (NoColor) color(*Renderer) termenv.Color { - return termenv.NoColor{} -} - -// RGBA returns the RGBA value of this color. Because we have to return -// something, despite this color being the absence of color, we're returning -// black with 100% opacity. -// -// Red: 0x0, Green: 0x0, Blue: 0x0, Alpha: 0xFFFF. -// -// Deprecated. -func (n NoColor) RGBA() (r, g, b, a uint32) { - return 0x0, 0x0, 0x0, 0xFFFF //nolint:mnd -} - -// Color specifies a color by hex or ANSI value. For example: -// -// ansiColor := lipgloss.Color("21") -// hexColor := lipgloss.Color("#0000ff") -type Color string - -func (c Color) color(r *Renderer) termenv.Color { - return r.ColorProfile().Color(string(c)) -} - -// RGBA returns the RGBA value of this color. This satisfies the Go Color -// interface. Note that on error we return black with 100% opacity, or: -// -// Red: 0x0, Green: 0x0, Blue: 0x0, Alpha: 0xFFFF. -// -// Deprecated. -func (c Color) RGBA() (r, g, b, a uint32) { - return termenv.ConvertToRGB(c.color(renderer)).RGBA() -} - -// ANSIColor is a color specified by an ANSI color value. It's merely syntactic -// sugar for the more general Color function. Invalid colors will render as -// black. -// -// Example usage: -// -// // These two statements are equivalent. -// colorA := lipgloss.ANSIColor(21) -// colorB := lipgloss.Color("21") -type ANSIColor uint - -func (ac ANSIColor) color(r *Renderer) termenv.Color { - return Color(strconv.FormatUint(uint64(ac), 10)).color(r) -} - -// RGBA returns the RGBA value of this color. This satisfies the Go Color -// interface. Note that on error we return black with 100% opacity, or: -// -// Red: 0x0, Green: 0x0, Blue: 0x0, Alpha: 0xFFFF. -// -// Deprecated. -func (ac ANSIColor) RGBA() (r, g, b, a uint32) { - cf := Color(strconv.FormatUint(uint64(ac), 10)) - return cf.RGBA() -} - -// AdaptiveColor provides color options for light and dark backgrounds. The -// appropriate color will be returned at runtime based on the darkness of the -// terminal background color. -// -// Example usage: -// -// color := lipgloss.AdaptiveColor{Light: "#0000ff", Dark: "#000099"} -type AdaptiveColor struct { - Light string - Dark string -} - -func (ac AdaptiveColor) color(r *Renderer) termenv.Color { - if r.HasDarkBackground() { - return Color(ac.Dark).color(r) - } - return Color(ac.Light).color(r) -} - -// RGBA returns the RGBA value of this color. This satisfies the Go Color -// interface. Note that on error we return black with 100% opacity, or: -// -// Red: 0x0, Green: 0x0, Blue: 0x0, Alpha: 0xFFFF. -// -// Deprecated. -func (ac AdaptiveColor) RGBA() (r, g, b, a uint32) { - return termenv.ConvertToRGB(ac.color(renderer)).RGBA() -} - -// CompleteColor specifies exact values for truecolor, ANSI256, and ANSI color -// profiles. Automatic color degradation will not be performed. -type CompleteColor struct { - TrueColor string - ANSI256 string - ANSI string -} - -func (c CompleteColor) color(r *Renderer) termenv.Color { - p := r.ColorProfile() - switch p { //nolint:exhaustive - case termenv.TrueColor: - return p.Color(c.TrueColor) - case termenv.ANSI256: - return p.Color(c.ANSI256) - case termenv.ANSI: - return p.Color(c.ANSI) - default: - return termenv.NoColor{} - } -} - -// RGBA returns the RGBA value of this color. This satisfies the Go Color -// interface. Note that on error we return black with 100% opacity, or: -// -// Red: 0x0, Green: 0x0, Blue: 0x0, Alpha: 0xFFFF. -// CompleteAdaptiveColor specifies exact values for truecolor, ANSI256, and ANSI color -// -// Deprecated. -func (c CompleteColor) RGBA() (r, g, b, a uint32) { - return termenv.ConvertToRGB(c.color(renderer)).RGBA() -} - -// CompleteAdaptiveColor specifies exact values for truecolor, ANSI256, and ANSI color -// profiles, with separate options for light and dark backgrounds. Automatic -// color degradation will not be performed. -type CompleteAdaptiveColor struct { - Light CompleteColor - Dark CompleteColor -} - -func (cac CompleteAdaptiveColor) color(r *Renderer) termenv.Color { - if r.HasDarkBackground() { - return cac.Dark.color(r) - } - return cac.Light.color(r) -} - -// RGBA returns the RGBA value of this color. This satisfies the Go Color -// interface. Note that on error we return black with 100% opacity, or: -// -// Red: 0x0, Green: 0x0, Blue: 0x0, Alpha: 0xFFFF. -// -// Deprecated. -func (cac CompleteAdaptiveColor) RGBA() (r, g, b, a uint32) { - return termenv.ConvertToRGB(cac.color(renderer)).RGBA() -} diff --git a/vendor/github.com/charmbracelet/lipgloss/get.go b/vendor/github.com/charmbracelet/lipgloss/get.go deleted file mode 100644 index 422b4ce955..0000000000 --- a/vendor/github.com/charmbracelet/lipgloss/get.go +++ /dev/null @@ -1,556 +0,0 @@ -package lipgloss - -import ( - "strings" - - "github.com/charmbracelet/x/ansi" -) - -// GetBold returns the style's bold value. If no value is set false is returned. -func (s Style) GetBold() bool { - return s.getAsBool(boldKey, false) -} - -// GetItalic returns the style's italic value. If no value is set false is -// returned. -func (s Style) GetItalic() bool { - return s.getAsBool(italicKey, false) -} - -// GetUnderline returns the style's underline value. If no value is set false is -// returned. -func (s Style) GetUnderline() bool { - return s.getAsBool(underlineKey, false) -} - -// GetStrikethrough returns the style's strikethrough value. If no value is set false -// is returned. -func (s Style) GetStrikethrough() bool { - return s.getAsBool(strikethroughKey, false) -} - -// GetReverse returns the style's reverse value. If no value is set false is -// returned. -func (s Style) GetReverse() bool { - return s.getAsBool(reverseKey, false) -} - -// GetBlink returns the style's blink value. If no value is set false is -// returned. -func (s Style) GetBlink() bool { - return s.getAsBool(blinkKey, false) -} - -// GetFaint returns the style's faint value. If no value is set false is -// returned. -func (s Style) GetFaint() bool { - return s.getAsBool(faintKey, false) -} - -// GetForeground returns the style's foreground color. If no value is set -// NoColor{} is returned. -func (s Style) GetForeground() TerminalColor { - return s.getAsColor(foregroundKey) -} - -// GetBackground returns the style's background color. If no value is set -// NoColor{} is returned. -func (s Style) GetBackground() TerminalColor { - return s.getAsColor(backgroundKey) -} - -// GetWidth returns the style's width setting. If no width is set 0 is -// returned. -func (s Style) GetWidth() int { - return s.getAsInt(widthKey) -} - -// GetHeight returns the style's height setting. If no height is set 0 is -// returned. -func (s Style) GetHeight() int { - return s.getAsInt(heightKey) -} - -// GetAlign returns the style's implicit horizontal alignment setting. -// If no alignment is set Position.Left is returned. -func (s Style) GetAlign() Position { - v := s.getAsPosition(alignHorizontalKey) - if v == Position(0) { - return Left - } - return v -} - -// GetAlignHorizontal returns the style's implicit horizontal alignment setting. -// If no alignment is set Position.Left is returned. -func (s Style) GetAlignHorizontal() Position { - v := s.getAsPosition(alignHorizontalKey) - if v == Position(0) { - return Left - } - return v -} - -// GetAlignVertical returns the style's implicit vertical alignment setting. -// If no alignment is set Position.Top is returned. -func (s Style) GetAlignVertical() Position { - v := s.getAsPosition(alignVerticalKey) - if v == Position(0) { - return Top - } - return v -} - -// GetPadding returns the style's top, right, bottom, and left padding values, -// in that order. 0 is returned for unset values. -func (s Style) GetPadding() (top, right, bottom, left int) { - return s.getAsInt(paddingTopKey), - s.getAsInt(paddingRightKey), - s.getAsInt(paddingBottomKey), - s.getAsInt(paddingLeftKey) -} - -// GetPaddingTop returns the style's top padding. If no value is set 0 is -// returned. -func (s Style) GetPaddingTop() int { - return s.getAsInt(paddingTopKey) -} - -// GetPaddingRight returns the style's right padding. If no value is set 0 is -// returned. -func (s Style) GetPaddingRight() int { - return s.getAsInt(paddingRightKey) -} - -// GetPaddingBottom returns the style's bottom padding. If no value is set 0 is -// returned. -func (s Style) GetPaddingBottom() int { - return s.getAsInt(paddingBottomKey) -} - -// GetPaddingLeft returns the style's left padding. If no value is set 0 is -// returned. -func (s Style) GetPaddingLeft() int { - return s.getAsInt(paddingLeftKey) -} - -// GetHorizontalPadding returns the style's left and right padding. Unset -// values are measured as 0. -func (s Style) GetHorizontalPadding() int { - return s.getAsInt(paddingLeftKey) + s.getAsInt(paddingRightKey) -} - -// GetVerticalPadding returns the style's top and bottom padding. Unset values -// are measured as 0. -func (s Style) GetVerticalPadding() int { - return s.getAsInt(paddingTopKey) + s.getAsInt(paddingBottomKey) -} - -// GetColorWhitespace returns the style's whitespace coloring setting. If no -// value is set false is returned. -func (s Style) GetColorWhitespace() bool { - return s.getAsBool(colorWhitespaceKey, false) -} - -// GetMargin returns the style's top, right, bottom, and left margins, in that -// order. 0 is returned for unset values. -func (s Style) GetMargin() (top, right, bottom, left int) { - return s.getAsInt(marginTopKey), - s.getAsInt(marginRightKey), - s.getAsInt(marginBottomKey), - s.getAsInt(marginLeftKey) -} - -// GetMarginTop returns the style's top margin. If no value is set 0 is -// returned. -func (s Style) GetMarginTop() int { - return s.getAsInt(marginTopKey) -} - -// GetMarginRight returns the style's right margin. If no value is set 0 is -// returned. -func (s Style) GetMarginRight() int { - return s.getAsInt(marginRightKey) -} - -// GetMarginBottom returns the style's bottom margin. If no value is set 0 is -// returned. -func (s Style) GetMarginBottom() int { - return s.getAsInt(marginBottomKey) -} - -// GetMarginLeft returns the style's left margin. If no value is set 0 is -// returned. -func (s Style) GetMarginLeft() int { - return s.getAsInt(marginLeftKey) -} - -// GetHorizontalMargins returns the style's left and right margins. Unset -// values are measured as 0. -func (s Style) GetHorizontalMargins() int { - return s.getAsInt(marginLeftKey) + s.getAsInt(marginRightKey) -} - -// GetVerticalMargins returns the style's top and bottom margins. Unset values -// are measured as 0. -func (s Style) GetVerticalMargins() int { - return s.getAsInt(marginTopKey) + s.getAsInt(marginBottomKey) -} - -// GetBorder returns the style's border style (type Border) and value for the -// top, right, bottom, and left in that order. If no value is set for the -// border style, Border{} is returned. For all other unset values false is -// returned. -func (s Style) GetBorder() (b Border, top, right, bottom, left bool) { - return s.getBorderStyle(), - s.getAsBool(borderTopKey, false), - s.getAsBool(borderRightKey, false), - s.getAsBool(borderBottomKey, false), - s.getAsBool(borderLeftKey, false) -} - -// GetBorderStyle returns the style's border style (type Border). If no value -// is set Border{} is returned. -func (s Style) GetBorderStyle() Border { - return s.getBorderStyle() -} - -// GetBorderTop returns the style's top border setting. If no value is set -// false is returned. -func (s Style) GetBorderTop() bool { - return s.getAsBool(borderTopKey, false) -} - -// GetBorderRight returns the style's right border setting. If no value is set -// false is returned. -func (s Style) GetBorderRight() bool { - return s.getAsBool(borderRightKey, false) -} - -// GetBorderBottom returns the style's bottom border setting. If no value is -// set false is returned. -func (s Style) GetBorderBottom() bool { - return s.getAsBool(borderBottomKey, false) -} - -// GetBorderLeft returns the style's left border setting. If no value is -// set false is returned. -func (s Style) GetBorderLeft() bool { - return s.getAsBool(borderLeftKey, false) -} - -// GetBorderTopForeground returns the style's border top foreground color. If -// no value is set NoColor{} is returned. -func (s Style) GetBorderTopForeground() TerminalColor { - return s.getAsColor(borderTopForegroundKey) -} - -// GetBorderRightForeground returns the style's border right foreground color. -// If no value is set NoColor{} is returned. -func (s Style) GetBorderRightForeground() TerminalColor { - return s.getAsColor(borderRightForegroundKey) -} - -// GetBorderBottomForeground returns the style's border bottom foreground -// color. If no value is set NoColor{} is returned. -func (s Style) GetBorderBottomForeground() TerminalColor { - return s.getAsColor(borderBottomForegroundKey) -} - -// GetBorderLeftForeground returns the style's border left foreground -// color. If no value is set NoColor{} is returned. -func (s Style) GetBorderLeftForeground() TerminalColor { - return s.getAsColor(borderLeftForegroundKey) -} - -// GetBorderTopBackground returns the style's border top background color. If -// no value is set NoColor{} is returned. -func (s Style) GetBorderTopBackground() TerminalColor { - return s.getAsColor(borderTopBackgroundKey) -} - -// GetBorderRightBackground returns the style's border right background color. -// If no value is set NoColor{} is returned. -func (s Style) GetBorderRightBackground() TerminalColor { - return s.getAsColor(borderRightBackgroundKey) -} - -// GetBorderBottomBackground returns the style's border bottom background -// color. If no value is set NoColor{} is returned. -func (s Style) GetBorderBottomBackground() TerminalColor { - return s.getAsColor(borderBottomBackgroundKey) -} - -// GetBorderLeftBackground returns the style's border left background -// color. If no value is set NoColor{} is returned. -func (s Style) GetBorderLeftBackground() TerminalColor { - return s.getAsColor(borderLeftBackgroundKey) -} - -// GetBorderTopWidth returns the width of the top border. If borders contain -// runes of varying widths, the widest rune is returned. If no border exists on -// the top edge, 0 is returned. -// -// Deprecated: This function simply calls Style.GetBorderTopSize. -func (s Style) GetBorderTopWidth() int { - return s.GetBorderTopSize() -} - -// GetBorderTopSize returns the width of the top border. If borders contain -// runes of varying widths, the widest rune is returned. If no border exists on -// the top edge, 0 is returned. -func (s Style) GetBorderTopSize() int { - if !s.getAsBool(borderTopKey, false) && !s.implicitBorders() { - return 0 - } - return s.getBorderStyle().GetTopSize() -} - -// GetBorderLeftSize returns the width of the left border. If borders contain -// runes of varying widths, the widest rune is returned. If no border exists on -// the left edge, 0 is returned. -func (s Style) GetBorderLeftSize() int { - if !s.getAsBool(borderLeftKey, false) && !s.implicitBorders() { - return 0 - } - return s.getBorderStyle().GetLeftSize() -} - -// GetBorderBottomSize returns the width of the bottom border. If borders -// contain runes of varying widths, the widest rune is returned. If no border -// exists on the left edge, 0 is returned. -func (s Style) GetBorderBottomSize() int { - if !s.getAsBool(borderBottomKey, false) && !s.implicitBorders() { - return 0 - } - return s.getBorderStyle().GetBottomSize() -} - -// GetBorderRightSize returns the width of the right border. If borders -// contain runes of varying widths, the widest rune is returned. If no border -// exists on the right edge, 0 is returned. -func (s Style) GetBorderRightSize() int { - if !s.getAsBool(borderRightKey, false) && !s.implicitBorders() { - return 0 - } - return s.getBorderStyle().GetRightSize() -} - -// GetHorizontalBorderSize returns the width of the horizontal borders. If -// borders contain runes of varying widths, the widest rune is returned. If no -// border exists on the horizontal edges, 0 is returned. -func (s Style) GetHorizontalBorderSize() int { - return s.GetBorderLeftSize() + s.GetBorderRightSize() -} - -// GetVerticalBorderSize returns the width of the vertical borders. If -// borders contain runes of varying widths, the widest rune is returned. If no -// border exists on the vertical edges, 0 is returned. -func (s Style) GetVerticalBorderSize() int { - return s.GetBorderTopSize() + s.GetBorderBottomSize() -} - -// GetInline returns the style's inline setting. If no value is set false is -// returned. -func (s Style) GetInline() bool { - return s.getAsBool(inlineKey, false) -} - -// GetMaxWidth returns the style's max width setting. If no value is set 0 is -// returned. -func (s Style) GetMaxWidth() int { - return s.getAsInt(maxWidthKey) -} - -// GetMaxHeight returns the style's max height setting. If no value is set 0 is -// returned. -func (s Style) GetMaxHeight() int { - return s.getAsInt(maxHeightKey) -} - -// GetTabWidth returns the style's tab width setting. If no value is set 4 is -// returned which is the implicit default. -func (s Style) GetTabWidth() int { - return s.getAsInt(tabWidthKey) -} - -// GetUnderlineSpaces returns whether or not the style is set to underline -// spaces. If not value is set false is returned. -func (s Style) GetUnderlineSpaces() bool { - return s.getAsBool(underlineSpacesKey, false) -} - -// GetStrikethroughSpaces returns whether or not the style is set to strikethrough -// spaces. If not value is set false is returned. -func (s Style) GetStrikethroughSpaces() bool { - return s.getAsBool(strikethroughSpacesKey, false) -} - -// GetHorizontalFrameSize returns the sum of the style's horizontal margins, padding -// and border widths. -// -// Provisional: this method may be renamed. -func (s Style) GetHorizontalFrameSize() int { - return s.GetHorizontalMargins() + s.GetHorizontalPadding() + s.GetHorizontalBorderSize() -} - -// GetVerticalFrameSize returns the sum of the style's vertical margins, padding -// and border widths. -// -// Provisional: this method may be renamed. -func (s Style) GetVerticalFrameSize() int { - return s.GetVerticalMargins() + s.GetVerticalPadding() + s.GetVerticalBorderSize() -} - -// GetFrameSize returns the sum of the margins, padding and border width for -// both the horizontal and vertical margins. -func (s Style) GetFrameSize() (x, y int) { - return s.GetHorizontalFrameSize(), s.GetVerticalFrameSize() -} - -// GetTransform returns the transform set on the style. If no transform is set -// nil is returned. -func (s Style) GetTransform() func(string) string { - return s.getAsTransform(transformKey) -} - -// Returns whether or not the given property is set. -func (s Style) isSet(k propKey) bool { - return s.props.has(k) -} - -func (s Style) getAsBool(k propKey, defaultVal bool) bool { - if !s.isSet(k) { - return defaultVal - } - return s.attrs&int(k) != 0 -} - -func (s Style) getAsColor(k propKey) TerminalColor { - if !s.isSet(k) { - return noColor - } - - var c TerminalColor - switch k { //nolint:exhaustive - case foregroundKey: - c = s.fgColor - case backgroundKey: - c = s.bgColor - case marginBackgroundKey: - c = s.marginBgColor - case borderTopForegroundKey: - c = s.borderTopFgColor - case borderRightForegroundKey: - c = s.borderRightFgColor - case borderBottomForegroundKey: - c = s.borderBottomFgColor - case borderLeftForegroundKey: - c = s.borderLeftFgColor - case borderTopBackgroundKey: - c = s.borderTopBgColor - case borderRightBackgroundKey: - c = s.borderRightBgColor - case borderBottomBackgroundKey: - c = s.borderBottomBgColor - case borderLeftBackgroundKey: - c = s.borderLeftBgColor - } - - if c != nil { - return c - } - - return noColor -} - -func (s Style) getAsInt(k propKey) int { - if !s.isSet(k) { - return 0 - } - switch k { //nolint:exhaustive - case widthKey: - return s.width - case heightKey: - return s.height - case paddingTopKey: - return s.paddingTop - case paddingRightKey: - return s.paddingRight - case paddingBottomKey: - return s.paddingBottom - case paddingLeftKey: - return s.paddingLeft - case marginTopKey: - return s.marginTop - case marginRightKey: - return s.marginRight - case marginBottomKey: - return s.marginBottom - case marginLeftKey: - return s.marginLeft - case maxWidthKey: - return s.maxWidth - case maxHeightKey: - return s.maxHeight - case tabWidthKey: - return s.tabWidth - } - return 0 -} - -func (s Style) getAsPosition(k propKey) Position { - if !s.isSet(k) { - return Position(0) - } - switch k { //nolint:exhaustive - case alignHorizontalKey: - return s.alignHorizontal - case alignVerticalKey: - return s.alignVertical - } - return Position(0) -} - -func (s Style) getBorderStyle() Border { - if !s.isSet(borderStyleKey) { - return noBorder - } - return s.borderStyle -} - -// Returns whether or not the style has implicit borders. This happens when -// a border style has been set but no border sides have been explicitly turned -// on or off. -func (s Style) implicitBorders() bool { - var ( - borderStyle = s.getBorderStyle() - topSet = s.isSet(borderTopKey) - rightSet = s.isSet(borderRightKey) - bottomSet = s.isSet(borderBottomKey) - leftSet = s.isSet(borderLeftKey) - ) - return borderStyle != noBorder && !(topSet || rightSet || bottomSet || leftSet) -} - -func (s Style) getAsTransform(propKey) func(string) string { - if !s.isSet(transformKey) { - return nil - } - return s.transform -} - -// Split a string into lines, additionally returning the size of the widest -// line. -func getLines(s string) (lines []string, widest int) { - lines = strings.Split(s, "\n") - - for _, l := range lines { - w := ansi.StringWidth(l) - if widest < w { - widest = w - } - } - - return lines, widest -} diff --git a/vendor/github.com/charmbracelet/lipgloss/join.go b/vendor/github.com/charmbracelet/lipgloss/join.go deleted file mode 100644 index b0a23a5461..0000000000 --- a/vendor/github.com/charmbracelet/lipgloss/join.go +++ /dev/null @@ -1,175 +0,0 @@ -package lipgloss - -import ( - "math" - "strings" - - "github.com/charmbracelet/x/ansi" -) - -// JoinHorizontal is a utility function for horizontally joining two -// potentially multi-lined strings along a vertical axis. The first argument is -// the position, with 0 being all the way at the top and 1 being all the way -// at the bottom. -// -// If you just want to align to the top, center or bottom you may as well just -// use the helper constants Top, Center, and Bottom. -// -// Example: -// -// blockB := "...\n...\n..." -// blockA := "...\n...\n...\n...\n..." -// -// // Join 20% from the top -// str := lipgloss.JoinHorizontal(0.2, blockA, blockB) -// -// // Join on the top edge -// str := lipgloss.JoinHorizontal(lipgloss.Top, blockA, blockB) -func JoinHorizontal(pos Position, strs ...string) string { - if len(strs) == 0 { - return "" - } - if len(strs) == 1 { - return strs[0] - } - - var ( - // Groups of strings broken into multiple lines - blocks = make([][]string, len(strs)) - - // Max line widths for the above text blocks - maxWidths = make([]int, len(strs)) - - // Height of the tallest block - maxHeight int - ) - - // Break text blocks into lines and get max widths for each text block - for i, str := range strs { - blocks[i], maxWidths[i] = getLines(str) - if len(blocks[i]) > maxHeight { - maxHeight = len(blocks[i]) - } - } - - // Add extra lines to make each side the same height - for i := range blocks { - if len(blocks[i]) >= maxHeight { - continue - } - - extraLines := make([]string, maxHeight-len(blocks[i])) - - switch pos { //nolint:exhaustive - case Top: - blocks[i] = append(blocks[i], extraLines...) - - case Bottom: - blocks[i] = append(extraLines, blocks[i]...) - - default: // Somewhere in the middle - n := len(extraLines) - split := int(math.Round(float64(n) * pos.value())) - top := n - split - bottom := n - top - - blocks[i] = append(extraLines[top:], blocks[i]...) - blocks[i] = append(blocks[i], extraLines[bottom:]...) - } - } - - // Merge lines - var b strings.Builder - for i := range blocks[0] { // remember, all blocks have the same number of members now - for j, block := range blocks { - b.WriteString(block[i]) - - // Also make lines the same length - b.WriteString(strings.Repeat(" ", maxWidths[j]-ansi.StringWidth(block[i]))) - } - if i < len(blocks[0])-1 { - b.WriteRune('\n') - } - } - - return b.String() -} - -// JoinVertical is a utility function for vertically joining two potentially -// multi-lined strings along a horizontal axis. The first argument is the -// position, with 0 being all the way to the left and 1 being all the way to -// the right. -// -// If you just want to align to the left, right or center you may as well just -// use the helper constants Left, Center, and Right. -// -// Example: -// -// blockB := "...\n...\n..." -// blockA := "...\n...\n...\n...\n..." -// -// // Join 20% from the top -// str := lipgloss.JoinVertical(0.2, blockA, blockB) -// -// // Join on the right edge -// str := lipgloss.JoinVertical(lipgloss.Right, blockA, blockB) -func JoinVertical(pos Position, strs ...string) string { - if len(strs) == 0 { - return "" - } - if len(strs) == 1 { - return strs[0] - } - - var ( - blocks = make([][]string, len(strs)) - maxWidth int - ) - - for i := range strs { - var w int - blocks[i], w = getLines(strs[i]) - if w > maxWidth { - maxWidth = w - } - } - - var b strings.Builder - for i, block := range blocks { - for j, line := range block { - w := maxWidth - ansi.StringWidth(line) - - switch pos { //nolint:exhaustive - case Left: - b.WriteString(line) - b.WriteString(strings.Repeat(" ", w)) - - case Right: - b.WriteString(strings.Repeat(" ", w)) - b.WriteString(line) - - default: // Somewhere in the middle - if w < 1 { - b.WriteString(line) - break - } - - split := int(math.Round(float64(w) * pos.value())) - right := w - split - left := w - right - - b.WriteString(strings.Repeat(" ", left)) - b.WriteString(line) - b.WriteString(strings.Repeat(" ", right)) - } - - // Write a newline as long as we're not on the last line of the - // last block. - if !(i == len(blocks)-1 && j == len(block)-1) { - b.WriteRune('\n') - } - } - } - - return b.String() -} diff --git a/vendor/github.com/charmbracelet/lipgloss/position.go b/vendor/github.com/charmbracelet/lipgloss/position.go deleted file mode 100644 index 185f5af3bd..0000000000 --- a/vendor/github.com/charmbracelet/lipgloss/position.go +++ /dev/null @@ -1,154 +0,0 @@ -package lipgloss - -import ( - "math" - "strings" - - "github.com/charmbracelet/x/ansi" -) - -// Position represents a position along a horizontal or vertical axis. It's in -// situations where an axis is involved, like alignment, joining, placement and -// so on. -// -// A value of 0 represents the start (the left or top) and 1 represents the end -// (the right or bottom). 0.5 represents the center. -// -// There are constants Top, Bottom, Center, Left and Right in this package that -// can be used to aid readability. -type Position float64 - -func (p Position) value() float64 { - return math.Min(1, math.Max(0, float64(p))) -} - -// Position aliases. -const ( - Top Position = 0.0 - Bottom Position = 1.0 - Center Position = 0.5 - Left Position = 0.0 - Right Position = 1.0 -) - -// Place places a string or text block vertically in an unstyled box of a given -// width or height. -func Place(width, height int, hPos, vPos Position, str string, opts ...WhitespaceOption) string { - return renderer.Place(width, height, hPos, vPos, str, opts...) -} - -// Place places a string or text block vertically in an unstyled box of a given -// width or height. -func (r *Renderer) Place(width, height int, hPos, vPos Position, str string, opts ...WhitespaceOption) string { - return r.PlaceVertical(height, vPos, r.PlaceHorizontal(width, hPos, str, opts...), opts...) -} - -// PlaceHorizontal places a string or text block horizontally in an unstyled -// block of a given width. If the given width is shorter than the max width of -// the string (measured by its longest line) this will be a noop. -func PlaceHorizontal(width int, pos Position, str string, opts ...WhitespaceOption) string { - return renderer.PlaceHorizontal(width, pos, str, opts...) -} - -// PlaceHorizontal places a string or text block horizontally in an unstyled -// block of a given width. If the given width is shorter than the max width of -// the string (measured by its longest line) this will be a noöp. -func (r *Renderer) PlaceHorizontal(width int, pos Position, str string, opts ...WhitespaceOption) string { - lines, contentWidth := getLines(str) - gap := width - contentWidth - - if gap <= 0 { - return str - } - - ws := newWhitespace(r, opts...) - - var b strings.Builder - for i, l := range lines { - // Is this line shorter than the longest line? - short := max(0, contentWidth-ansi.StringWidth(l)) - - switch pos { //nolint:exhaustive - case Left: - b.WriteString(l) - b.WriteString(ws.render(gap + short)) - - case Right: - b.WriteString(ws.render(gap + short)) - b.WriteString(l) - - default: // somewhere in the middle - totalGap := gap + short - - split := int(math.Round(float64(totalGap) * pos.value())) - left := totalGap - split - right := totalGap - left - - b.WriteString(ws.render(left)) - b.WriteString(l) - b.WriteString(ws.render(right)) - } - - if i < len(lines)-1 { - b.WriteRune('\n') - } - } - - return b.String() -} - -// PlaceVertical places a string or text block vertically in an unstyled block -// of a given height. If the given height is shorter than the height of the -// string (measured by its newlines) then this will be a noop. -func PlaceVertical(height int, pos Position, str string, opts ...WhitespaceOption) string { - return renderer.PlaceVertical(height, pos, str, opts...) -} - -// PlaceVertical places a string or text block vertically in an unstyled block -// of a given height. If the given height is shorter than the height of the -// string (measured by its newlines) then this will be a noöp. -func (r *Renderer) PlaceVertical(height int, pos Position, str string, opts ...WhitespaceOption) string { - contentHeight := strings.Count(str, "\n") + 1 - gap := height - contentHeight - - if gap <= 0 { - return str - } - - ws := newWhitespace(r, opts...) - - _, width := getLines(str) - emptyLine := ws.render(width) - b := strings.Builder{} - - switch pos { //nolint:exhaustive - case Top: - b.WriteString(str) - b.WriteRune('\n') - for i := 0; i < gap; i++ { - b.WriteString(emptyLine) - if i < gap-1 { - b.WriteRune('\n') - } - } - - case Bottom: - b.WriteString(strings.Repeat(emptyLine+"\n", gap)) - b.WriteString(str) - - default: // Somewhere in the middle - split := int(math.Round(float64(gap) * pos.value())) - top := gap - split - bottom := gap - top - - b.WriteString(strings.Repeat(emptyLine+"\n", top)) - b.WriteString(str) - - for i := 0; i < bottom; i++ { - b.WriteRune('\n') - b.WriteString(emptyLine) - } - } - - return b.String() -} diff --git a/vendor/github.com/charmbracelet/lipgloss/ranges.go b/vendor/github.com/charmbracelet/lipgloss/ranges.go deleted file mode 100644 index d171699878..0000000000 --- a/vendor/github.com/charmbracelet/lipgloss/ranges.go +++ /dev/null @@ -1,48 +0,0 @@ -package lipgloss - -import ( - "strings" - - "github.com/charmbracelet/x/ansi" -) - -// StyleRanges allows to, given a string, style ranges of it differently. -// The function will take into account existing styles. -// Ranges should not overlap. -func StyleRanges(s string, ranges ...Range) string { - if len(ranges) == 0 { - return s - } - - var buf strings.Builder - lastIdx := 0 - stripped := ansi.Strip(s) - - // Use Truncate and TruncateLeft to style match.MatchedIndexes without - // losing the original option style: - for _, rng := range ranges { - // Add the text before this match - if rng.Start > lastIdx { - buf.WriteString(ansi.Cut(s, lastIdx, rng.Start)) - } - // Add the matched range with its highlight - buf.WriteString(rng.Style.Render(ansi.Cut(stripped, rng.Start, rng.End))) - lastIdx = rng.End - } - - // Add any remaining text after the last match - buf.WriteString(ansi.TruncateLeft(s, lastIdx, "")) - - return buf.String() -} - -// NewRange returns a range that can be used with [StyleRanges]. -func NewRange(start, end int, style Style) Range { - return Range{start, end, style} -} - -// Range to be used with [StyleRanges]. -type Range struct { - Start, End int - Style Style -} diff --git a/vendor/github.com/charmbracelet/lipgloss/renderer.go b/vendor/github.com/charmbracelet/lipgloss/renderer.go deleted file mode 100644 index 233aa7c004..0000000000 --- a/vendor/github.com/charmbracelet/lipgloss/renderer.go +++ /dev/null @@ -1,181 +0,0 @@ -package lipgloss - -import ( - "io" - "sync" - - "github.com/muesli/termenv" -) - -// We're manually creating the struct here to avoid initializing the output and -// query the terminal multiple times. -var renderer = &Renderer{ - output: termenv.DefaultOutput(), -} - -// Renderer is a lipgloss terminal renderer. -type Renderer struct { - output *termenv.Output - colorProfile termenv.Profile - hasDarkBackground bool - - getColorProfile sync.Once - explicitColorProfile bool - - getBackgroundColor sync.Once - explicitBackgroundColor bool - - mtx sync.RWMutex -} - -// DefaultRenderer returns the default renderer. -func DefaultRenderer() *Renderer { - return renderer -} - -// SetDefaultRenderer sets the default global renderer. -func SetDefaultRenderer(r *Renderer) { - renderer = r -} - -// NewRenderer creates a new Renderer. -// -// w will be used to determine the terminal's color capabilities. -func NewRenderer(w io.Writer, opts ...termenv.OutputOption) *Renderer { - r := &Renderer{ - output: termenv.NewOutput(w, opts...), - } - return r -} - -// Output returns the termenv output. -func (r *Renderer) Output() *termenv.Output { - r.mtx.RLock() - defer r.mtx.RUnlock() - return r.output -} - -// SetOutput sets the termenv output. -func (r *Renderer) SetOutput(o *termenv.Output) { - r.mtx.Lock() - defer r.mtx.Unlock() - r.output = o -} - -// ColorProfile returns the detected termenv color profile. -func (r *Renderer) ColorProfile() termenv.Profile { - r.mtx.RLock() - defer r.mtx.RUnlock() - - if !r.explicitColorProfile { - r.getColorProfile.Do(func() { - // NOTE: we don't need to lock here because sync.Once provides its - // own locking mechanism. - r.colorProfile = r.output.EnvColorProfile() - }) - } - - return r.colorProfile -} - -// ColorProfile returns the detected termenv color profile. -func ColorProfile() termenv.Profile { - return renderer.ColorProfile() -} - -// SetColorProfile sets the color profile on the renderer. This function exists -// mostly for testing purposes so that you can assure you're testing against -// a specific profile. -// -// Outside of testing you likely won't want to use this function as the color -// profile will detect and cache the terminal's color capabilities and choose -// the best available profile. -// -// Available color profiles are: -// -// termenv.Ascii // no color, 1-bit -// termenv.ANSI //16 colors, 4-bit -// termenv.ANSI256 // 256 colors, 8-bit -// termenv.TrueColor // 16,777,216 colors, 24-bit -// -// This function is thread-safe. -func (r *Renderer) SetColorProfile(p termenv.Profile) { - r.mtx.Lock() - defer r.mtx.Unlock() - - r.colorProfile = p - r.explicitColorProfile = true -} - -// SetColorProfile sets the color profile on the default renderer. This -// function exists mostly for testing purposes so that you can assure you're -// testing against a specific profile. -// -// Outside of testing you likely won't want to use this function as the color -// profile will detect and cache the terminal's color capabilities and choose -// the best available profile. -// -// Available color profiles are: -// -// termenv.Ascii // no color, 1-bit -// termenv.ANSI //16 colors, 4-bit -// termenv.ANSI256 // 256 colors, 8-bit -// termenv.TrueColor // 16,777,216 colors, 24-bit -// -// This function is thread-safe. -func SetColorProfile(p termenv.Profile) { - renderer.SetColorProfile(p) -} - -// HasDarkBackground returns whether or not the terminal has a dark background. -func HasDarkBackground() bool { - return renderer.HasDarkBackground() -} - -// HasDarkBackground returns whether or not the renderer will render to a dark -// background. A dark background can either be auto-detected, or set explicitly -// on the renderer. -func (r *Renderer) HasDarkBackground() bool { - r.mtx.RLock() - defer r.mtx.RUnlock() - - if !r.explicitBackgroundColor { - r.getBackgroundColor.Do(func() { - // NOTE: we don't need to lock here because sync.Once provides its - // own locking mechanism. - r.hasDarkBackground = r.output.HasDarkBackground() - }) - } - - return r.hasDarkBackground -} - -// SetHasDarkBackground sets the background color detection value for the -// default renderer. This function exists mostly for testing purposes so that -// you can assure you're testing against a specific background color setting. -// -// Outside of testing you likely won't want to use this function as the -// backgrounds value will be automatically detected and cached against the -// terminal's current background color setting. -// -// This function is thread-safe. -func SetHasDarkBackground(b bool) { - renderer.SetHasDarkBackground(b) -} - -// SetHasDarkBackground sets the background color detection value on the -// renderer. This function exists mostly for testing purposes so that you can -// assure you're testing against a specific background color setting. -// -// Outside of testing you likely won't want to use this function as the -// backgrounds value will be automatically detected and cached against the -// terminal's current background color setting. -// -// This function is thread-safe. -func (r *Renderer) SetHasDarkBackground(b bool) { - r.mtx.Lock() - defer r.mtx.Unlock() - - r.hasDarkBackground = b - r.explicitBackgroundColor = true -} diff --git a/vendor/github.com/charmbracelet/lipgloss/runes.go b/vendor/github.com/charmbracelet/lipgloss/runes.go deleted file mode 100644 index 7a49e326cc..0000000000 --- a/vendor/github.com/charmbracelet/lipgloss/runes.go +++ /dev/null @@ -1,43 +0,0 @@ -package lipgloss - -import ( - "strings" -) - -// StyleRunes apply a given style to runes at the given indices in the string. -// Note that you must provide styling options for both matched and unmatched -// runes. Indices out of bounds will be ignored. -func StyleRunes(str string, indices []int, matched, unmatched Style) string { - // Convert slice of indices to a map for easier lookups - m := make(map[int]struct{}) - for _, i := range indices { - m[i] = struct{}{} - } - - var ( - out strings.Builder - group strings.Builder - style Style - runes = []rune(str) - ) - - for i, r := range runes { - group.WriteRune(r) - - _, matches := m[i] - _, nextMatches := m[i+1] - - if matches != nextMatches || i == len(runes)-1 { - // Flush - if matches { - style = matched - } else { - style = unmatched - } - out.WriteString(style.Render(group.String())) - group.Reset() - } - } - - return out.String() -} diff --git a/vendor/github.com/charmbracelet/lipgloss/set.go b/vendor/github.com/charmbracelet/lipgloss/set.go deleted file mode 100644 index fde38faecc..0000000000 --- a/vendor/github.com/charmbracelet/lipgloss/set.go +++ /dev/null @@ -1,799 +0,0 @@ -package lipgloss - -// Set a value on the underlying rules map. -func (s *Style) set(key propKey, value interface{}) { - // We don't allow negative integers on any of our other values, so just keep - // them at zero or above. We could use uints instead, but the - // conversions are a little tedious, so we're sticking with ints for - // sake of usability. - switch key { //nolint:exhaustive - case foregroundKey: - s.fgColor = colorOrNil(value) - case backgroundKey: - s.bgColor = colorOrNil(value) - case widthKey: - s.width = max(0, value.(int)) - case heightKey: - s.height = max(0, value.(int)) - case alignHorizontalKey: - s.alignHorizontal = value.(Position) - case alignVerticalKey: - s.alignVertical = value.(Position) - case paddingTopKey: - s.paddingTop = max(0, value.(int)) - case paddingRightKey: - s.paddingRight = max(0, value.(int)) - case paddingBottomKey: - s.paddingBottom = max(0, value.(int)) - case paddingLeftKey: - s.paddingLeft = max(0, value.(int)) - case marginTopKey: - s.marginTop = max(0, value.(int)) - case marginRightKey: - s.marginRight = max(0, value.(int)) - case marginBottomKey: - s.marginBottom = max(0, value.(int)) - case marginLeftKey: - s.marginLeft = max(0, value.(int)) - case marginBackgroundKey: - s.marginBgColor = colorOrNil(value) - case borderStyleKey: - s.borderStyle = value.(Border) - case borderTopForegroundKey: - s.borderTopFgColor = colorOrNil(value) - case borderRightForegroundKey: - s.borderRightFgColor = colorOrNil(value) - case borderBottomForegroundKey: - s.borderBottomFgColor = colorOrNil(value) - case borderLeftForegroundKey: - s.borderLeftFgColor = colorOrNil(value) - case borderTopBackgroundKey: - s.borderTopBgColor = colorOrNil(value) - case borderRightBackgroundKey: - s.borderRightBgColor = colorOrNil(value) - case borderBottomBackgroundKey: - s.borderBottomBgColor = colorOrNil(value) - case borderLeftBackgroundKey: - s.borderLeftBgColor = colorOrNil(value) - case maxWidthKey: - s.maxWidth = max(0, value.(int)) - case maxHeightKey: - s.maxHeight = max(0, value.(int)) - case tabWidthKey: - // TabWidth is the only property that may have a negative value (and - // that negative value can be no less than -1). - s.tabWidth = value.(int) - case transformKey: - s.transform = value.(func(string) string) - default: - if v, ok := value.(bool); ok { //nolint:nestif - if v { - s.attrs |= int(key) - } else { - s.attrs &^= int(key) - } - } else if attrs, ok := value.(int); ok { - // bool attrs - if attrs&int(key) != 0 { - s.attrs |= int(key) - } else { - s.attrs &^= int(key) - } - } - } - - // Set the prop on - s.props = s.props.set(key) -} - -// setFrom sets the property from another style. -func (s *Style) setFrom(key propKey, i Style) { - switch key { //nolint:exhaustive - case foregroundKey: - s.set(foregroundKey, i.fgColor) - case backgroundKey: - s.set(backgroundKey, i.bgColor) - case widthKey: - s.set(widthKey, i.width) - case heightKey: - s.set(heightKey, i.height) - case alignHorizontalKey: - s.set(alignHorizontalKey, i.alignHorizontal) - case alignVerticalKey: - s.set(alignVerticalKey, i.alignVertical) - case paddingTopKey: - s.set(paddingTopKey, i.paddingTop) - case paddingRightKey: - s.set(paddingRightKey, i.paddingRight) - case paddingBottomKey: - s.set(paddingBottomKey, i.paddingBottom) - case paddingLeftKey: - s.set(paddingLeftKey, i.paddingLeft) - case marginTopKey: - s.set(marginTopKey, i.marginTop) - case marginRightKey: - s.set(marginRightKey, i.marginRight) - case marginBottomKey: - s.set(marginBottomKey, i.marginBottom) - case marginLeftKey: - s.set(marginLeftKey, i.marginLeft) - case marginBackgroundKey: - s.set(marginBackgroundKey, i.marginBgColor) - case borderStyleKey: - s.set(borderStyleKey, i.borderStyle) - case borderTopForegroundKey: - s.set(borderTopForegroundKey, i.borderTopFgColor) - case borderRightForegroundKey: - s.set(borderRightForegroundKey, i.borderRightFgColor) - case borderBottomForegroundKey: - s.set(borderBottomForegroundKey, i.borderBottomFgColor) - case borderLeftForegroundKey: - s.set(borderLeftForegroundKey, i.borderLeftFgColor) - case borderTopBackgroundKey: - s.set(borderTopBackgroundKey, i.borderTopBgColor) - case borderRightBackgroundKey: - s.set(borderRightBackgroundKey, i.borderRightBgColor) - case borderBottomBackgroundKey: - s.set(borderBottomBackgroundKey, i.borderBottomBgColor) - case borderLeftBackgroundKey: - s.set(borderLeftBackgroundKey, i.borderLeftBgColor) - case maxWidthKey: - s.set(maxWidthKey, i.maxWidth) - case maxHeightKey: - s.set(maxHeightKey, i.maxHeight) - case tabWidthKey: - s.set(tabWidthKey, i.tabWidth) - case transformKey: - s.set(transformKey, i.transform) - default: - // Set attributes for set bool properties - s.set(key, i.attrs) - } -} - -func colorOrNil(c interface{}) TerminalColor { - if c, ok := c.(TerminalColor); ok { - return c - } - return nil -} - -// Bold sets a bold formatting rule. -func (s Style) Bold(v bool) Style { - s.set(boldKey, v) - return s -} - -// Italic sets an italic formatting rule. In some terminal emulators this will -// render with "reverse" coloring if not italic font variant is available. -func (s Style) Italic(v bool) Style { - s.set(italicKey, v) - return s -} - -// Underline sets an underline rule. By default, underlines will not be drawn on -// whitespace like margins and padding. To change this behavior set -// UnderlineSpaces. -func (s Style) Underline(v bool) Style { - s.set(underlineKey, v) - return s -} - -// Strikethrough sets a strikethrough rule. By default, strikes will not be -// drawn on whitespace like margins and padding. To change this behavior set -// StrikethroughSpaces. -func (s Style) Strikethrough(v bool) Style { - s.set(strikethroughKey, v) - return s -} - -// Reverse sets a rule for inverting foreground and background colors. -func (s Style) Reverse(v bool) Style { - s.set(reverseKey, v) - return s -} - -// Blink sets a rule for blinking foreground text. -func (s Style) Blink(v bool) Style { - s.set(blinkKey, v) - return s -} - -// Faint sets a rule for rendering the foreground color in a dimmer shade. -func (s Style) Faint(v bool) Style { - s.set(faintKey, v) - return s -} - -// Foreground sets a foreground color. -// -// // Sets the foreground to blue -// s := lipgloss.NewStyle().Foreground(lipgloss.Color("#0000ff")) -// -// // Removes the foreground color -// s.Foreground(lipgloss.NoColor) -func (s Style) Foreground(c TerminalColor) Style { - s.set(foregroundKey, c) - return s -} - -// Background sets a background color. -func (s Style) Background(c TerminalColor) Style { - s.set(backgroundKey, c) - return s -} - -// Width sets the width of the block before applying margins. The width, if -// set, also determines where text will wrap. -func (s Style) Width(i int) Style { - s.set(widthKey, i) - return s -} - -// Height sets the height of the block before applying margins. If the height of -// the text block is less than this value after applying padding (or not), the -// block will be set to this height. -func (s Style) Height(i int) Style { - s.set(heightKey, i) - return s -} - -// Align is a shorthand method for setting horizontal and vertical alignment. -// -// With one argument, the position value is applied to the horizontal alignment. -// -// With two arguments, the value is applied to the horizontal and vertical -// alignments, in that order. -func (s Style) Align(p ...Position) Style { - if len(p) > 0 { - s.set(alignHorizontalKey, p[0]) - } - if len(p) > 1 { - s.set(alignVerticalKey, p[1]) - } - return s -} - -// AlignHorizontal sets a horizontal text alignment rule. -func (s Style) AlignHorizontal(p Position) Style { - s.set(alignHorizontalKey, p) - return s -} - -// AlignVertical sets a vertical text alignment rule. -func (s Style) AlignVertical(p Position) Style { - s.set(alignVerticalKey, p) - return s -} - -// Padding is a shorthand method for setting padding on all sides at once. -// -// With one argument, the value is applied to all sides. -// -// With two arguments, the value is applied to the vertical and horizontal -// sides, in that order. -// -// With three arguments, the value is applied to the top side, the horizontal -// sides, and the bottom side, in that order. -// -// With four arguments, the value is applied clockwise starting from the top -// side, followed by the right side, then the bottom, and finally the left. -// -// With more than four arguments no padding will be added. -func (s Style) Padding(i ...int) Style { - top, right, bottom, left, ok := whichSidesInt(i...) - if !ok { - return s - } - - s.set(paddingTopKey, top) - s.set(paddingRightKey, right) - s.set(paddingBottomKey, bottom) - s.set(paddingLeftKey, left) - return s -} - -// PaddingLeft adds padding on the left. -func (s Style) PaddingLeft(i int) Style { - s.set(paddingLeftKey, i) - return s -} - -// PaddingRight adds padding on the right. -func (s Style) PaddingRight(i int) Style { - s.set(paddingRightKey, i) - return s -} - -// PaddingTop adds padding to the top of the block. -func (s Style) PaddingTop(i int) Style { - s.set(paddingTopKey, i) - return s -} - -// PaddingBottom adds padding to the bottom of the block. -func (s Style) PaddingBottom(i int) Style { - s.set(paddingBottomKey, i) - return s -} - -// ColorWhitespace determines whether or not the background color should be -// applied to the padding. This is true by default as it's more than likely the -// desired and expected behavior, but it can be disabled for certain graphic -// effects. -// -// Deprecated: Just use margins and padding. -func (s Style) ColorWhitespace(v bool) Style { - s.set(colorWhitespaceKey, v) - return s -} - -// Margin is a shorthand method for setting margins on all sides at once. -// -// With one argument, the value is applied to all sides. -// -// With two arguments, the value is applied to the vertical and horizontal -// sides, in that order. -// -// With three arguments, the value is applied to the top side, the horizontal -// sides, and the bottom side, in that order. -// -// With four arguments, the value is applied clockwise starting from the top -// side, followed by the right side, then the bottom, and finally the left. -// -// With more than four arguments no margin will be added. -func (s Style) Margin(i ...int) Style { - top, right, bottom, left, ok := whichSidesInt(i...) - if !ok { - return s - } - - s.set(marginTopKey, top) - s.set(marginRightKey, right) - s.set(marginBottomKey, bottom) - s.set(marginLeftKey, left) - return s -} - -// MarginLeft sets the value of the left margin. -func (s Style) MarginLeft(i int) Style { - s.set(marginLeftKey, i) - return s -} - -// MarginRight sets the value of the right margin. -func (s Style) MarginRight(i int) Style { - s.set(marginRightKey, i) - return s -} - -// MarginTop sets the value of the top margin. -func (s Style) MarginTop(i int) Style { - s.set(marginTopKey, i) - return s -} - -// MarginBottom sets the value of the bottom margin. -func (s Style) MarginBottom(i int) Style { - s.set(marginBottomKey, i) - return s -} - -// MarginBackground sets the background color of the margin. Note that this is -// also set when inheriting from a style with a background color. In that case -// the background color on that style will set the margin color on this style. -func (s Style) MarginBackground(c TerminalColor) Style { - s.set(marginBackgroundKey, c) - return s -} - -// Border is shorthand for setting the border style and which sides should -// have a border at once. The variadic argument sides works as follows: -// -// With one value, the value is applied to all sides. -// -// With two values, the values are applied to the vertical and horizontal -// sides, in that order. -// -// With three values, the values are applied to the top side, the horizontal -// sides, and the bottom side, in that order. -// -// With four values, the values are applied clockwise starting from the top -// side, followed by the right side, then the bottom, and finally the left. -// -// With more than four arguments the border will be applied to all sides. -// -// Examples: -// -// // Applies borders to the top and bottom only -// lipgloss.NewStyle().Border(lipgloss.NormalBorder(), true, false) -// -// // Applies rounded borders to the right and bottom only -// lipgloss.NewStyle().Border(lipgloss.RoundedBorder(), false, true, true, false) -func (s Style) Border(b Border, sides ...bool) Style { - s.set(borderStyleKey, b) - - top, right, bottom, left, ok := whichSidesBool(sides...) - if !ok { - top = true - right = true - bottom = true - left = true - } - - s.set(borderTopKey, top) - s.set(borderRightKey, right) - s.set(borderBottomKey, bottom) - s.set(borderLeftKey, left) - - return s -} - -// BorderStyle defines the Border on a style. A Border contains a series of -// definitions for the sides and corners of a border. -// -// Note that if border visibility has not been set for any sides when setting -// the border style, the border will be enabled for all sides during rendering. -// -// You can define border characters as you'd like, though several default -// styles are included: NormalBorder(), RoundedBorder(), BlockBorder(), -// OuterHalfBlockBorder(), InnerHalfBlockBorder(), ThickBorder(), -// and DoubleBorder(). -// -// Example: -// -// lipgloss.NewStyle().BorderStyle(lipgloss.ThickBorder()) -func (s Style) BorderStyle(b Border) Style { - s.set(borderStyleKey, b) - return s -} - -// BorderTop determines whether or not to draw a top border. -func (s Style) BorderTop(v bool) Style { - s.set(borderTopKey, v) - return s -} - -// BorderRight determines whether or not to draw a right border. -func (s Style) BorderRight(v bool) Style { - s.set(borderRightKey, v) - return s -} - -// BorderBottom determines whether or not to draw a bottom border. -func (s Style) BorderBottom(v bool) Style { - s.set(borderBottomKey, v) - return s -} - -// BorderLeft determines whether or not to draw a left border. -func (s Style) BorderLeft(v bool) Style { - s.set(borderLeftKey, v) - return s -} - -// BorderForeground is a shorthand function for setting all of the -// foreground colors of the borders at once. The arguments work as follows: -// -// With one argument, the argument is applied to all sides. -// -// With two arguments, the arguments are applied to the vertical and horizontal -// sides, in that order. -// -// With three arguments, the arguments are applied to the top side, the -// horizontal sides, and the bottom side, in that order. -// -// With four arguments, the arguments are applied clockwise starting from the -// top side, followed by the right side, then the bottom, and finally the left. -// -// With more than four arguments nothing will be set. -func (s Style) BorderForeground(c ...TerminalColor) Style { - if len(c) == 0 { - return s - } - - top, right, bottom, left, ok := whichSidesColor(c...) - if !ok { - return s - } - - s.set(borderTopForegroundKey, top) - s.set(borderRightForegroundKey, right) - s.set(borderBottomForegroundKey, bottom) - s.set(borderLeftForegroundKey, left) - - return s -} - -// BorderTopForeground set the foreground color for the top of the border. -func (s Style) BorderTopForeground(c TerminalColor) Style { - s.set(borderTopForegroundKey, c) - return s -} - -// BorderRightForeground sets the foreground color for the right side of the -// border. -func (s Style) BorderRightForeground(c TerminalColor) Style { - s.set(borderRightForegroundKey, c) - return s -} - -// BorderBottomForeground sets the foreground color for the bottom of the -// border. -func (s Style) BorderBottomForeground(c TerminalColor) Style { - s.set(borderBottomForegroundKey, c) - return s -} - -// BorderLeftForeground sets the foreground color for the left side of the -// border. -func (s Style) BorderLeftForeground(c TerminalColor) Style { - s.set(borderLeftForegroundKey, c) - return s -} - -// BorderBackground is a shorthand function for setting all of the -// background colors of the borders at once. The arguments work as follows: -// -// With one argument, the argument is applied to all sides. -// -// With two arguments, the arguments are applied to the vertical and horizontal -// sides, in that order. -// -// With three arguments, the arguments are applied to the top side, the -// horizontal sides, and the bottom side, in that order. -// -// With four arguments, the arguments are applied clockwise starting from the -// top side, followed by the right side, then the bottom, and finally the left. -// -// With more than four arguments nothing will be set. -func (s Style) BorderBackground(c ...TerminalColor) Style { - if len(c) == 0 { - return s - } - - top, right, bottom, left, ok := whichSidesColor(c...) - if !ok { - return s - } - - s.set(borderTopBackgroundKey, top) - s.set(borderRightBackgroundKey, right) - s.set(borderBottomBackgroundKey, bottom) - s.set(borderLeftBackgroundKey, left) - - return s -} - -// BorderTopBackground sets the background color of the top of the border. -func (s Style) BorderTopBackground(c TerminalColor) Style { - s.set(borderTopBackgroundKey, c) - return s -} - -// BorderRightBackground sets the background color of right side the border. -func (s Style) BorderRightBackground(c TerminalColor) Style { - s.set(borderRightBackgroundKey, c) - return s -} - -// BorderBottomBackground sets the background color of the bottom of the -// border. -func (s Style) BorderBottomBackground(c TerminalColor) Style { - s.set(borderBottomBackgroundKey, c) - return s -} - -// BorderLeftBackground set the background color of the left side of the -// border. -func (s Style) BorderLeftBackground(c TerminalColor) Style { - s.set(borderLeftBackgroundKey, c) - return s -} - -// Inline makes rendering output one line and disables the rendering of -// margins, padding and borders. This is useful when you need a style to apply -// only to font rendering and don't want it to change any physical dimensions. -// It works well with Style.MaxWidth. -// -// Because this in intended to be used at the time of render, this method will -// not mutate the style and instead return a copy. -// -// Example: -// -// var userInput string = "..." -// var userStyle = text.Style{ /* ... */ } -// fmt.Println(userStyle.Inline(true).Render(userInput)) -func (s Style) Inline(v bool) Style { - o := s // copy - o.set(inlineKey, v) - return o -} - -// MaxWidth applies a max width to a given style. This is useful in enforcing -// a certain width at render time, particularly with arbitrary strings and -// styles. -// -// Because this in intended to be used at the time of render, this method will -// not mutate the style and instead return a copy. -// -// Example: -// -// var userInput string = "..." -// var userStyle = text.Style{ /* ... */ } -// fmt.Println(userStyle.MaxWidth(16).Render(userInput)) -func (s Style) MaxWidth(n int) Style { - o := s // copy - o.set(maxWidthKey, n) - return o -} - -// MaxHeight applies a max height to a given style. This is useful in enforcing -// a certain height at render time, particularly with arbitrary strings and -// styles. -// -// Because this in intended to be used at the time of render, this method will -// not mutate the style and instead returns a copy. -func (s Style) MaxHeight(n int) Style { - o := s // copy - o.set(maxHeightKey, n) - return o -} - -// NoTabConversion can be passed to [Style.TabWidth] to disable the replacement -// of tabs with spaces at render time. -const NoTabConversion = -1 - -// TabWidth sets the number of spaces that a tab (/t) should be rendered as. -// When set to 0, tabs will be removed. To disable the replacement of tabs with -// spaces entirely, set this to [NoTabConversion]. -// -// By default, tabs will be replaced with 4 spaces. -func (s Style) TabWidth(n int) Style { - if n <= -1 { - n = -1 - } - s.set(tabWidthKey, n) - return s -} - -// UnderlineSpaces determines whether to underline spaces between words. By -// default, this is true. Spaces can also be underlined without underlining the -// text itself. -func (s Style) UnderlineSpaces(v bool) Style { - s.set(underlineSpacesKey, v) - return s -} - -// StrikethroughSpaces determines whether to apply strikethroughs to spaces -// between words. By default, this is true. Spaces can also be struck without -// underlining the text itself. -func (s Style) StrikethroughSpaces(v bool) Style { - s.set(strikethroughSpacesKey, v) - return s -} - -// Transform applies a given function to a string at render time, allowing for -// the string being rendered to be manipuated. -// -// Example: -// -// s := NewStyle().Transform(strings.ToUpper) -// fmt.Println(s.Render("raow!") // "RAOW!" -func (s Style) Transform(fn func(string) string) Style { - s.set(transformKey, fn) - return s -} - -// Renderer sets the renderer for the style. This is useful for changing the -// renderer for a style that is being used in a different context. -func (s Style) Renderer(r *Renderer) Style { - s.r = r - return s -} - -// whichSidesInt is a helper method for setting values on sides of a block based -// on the number of arguments. It follows the CSS shorthand rules for blocks -// like margin, padding. and borders. Here are how the rules work: -// -// 0 args: do nothing -// 1 arg: all sides -// 2 args: top -> bottom -// 3 args: top -> horizontal -> bottom -// 4 args: top -> right -> bottom -> left -// 5+ args: do nothing. -func whichSidesInt(i ...int) (top, right, bottom, left int, ok bool) { - switch len(i) { - case 1: - top = i[0] - bottom = i[0] - left = i[0] - right = i[0] - ok = true - case 2: //nolint:mnd - top = i[0] - bottom = i[0] - left = i[1] - right = i[1] - ok = true - case 3: //nolint:mnd - top = i[0] - left = i[1] - right = i[1] - bottom = i[2] - ok = true - case 4: //nolint:mnd - top = i[0] - right = i[1] - bottom = i[2] - left = i[3] - ok = true - } - return top, right, bottom, left, ok -} - -// whichSidesBool is like whichSidesInt, except it operates on a series of -// boolean values. See the comment on whichSidesInt for details on how this -// works. -func whichSidesBool(i ...bool) (top, right, bottom, left bool, ok bool) { - switch len(i) { - case 1: - top = i[0] - bottom = i[0] - left = i[0] - right = i[0] - ok = true - case 2: //nolint:mnd - top = i[0] - bottom = i[0] - left = i[1] - right = i[1] - ok = true - case 3: //nolint:mnd - top = i[0] - left = i[1] - right = i[1] - bottom = i[2] - ok = true - case 4: //nolint:mnd - top = i[0] - right = i[1] - bottom = i[2] - left = i[3] - ok = true - } - return top, right, bottom, left, ok -} - -// whichSidesColor is like whichSides, except it operates on a series of -// boolean values. See the comment on whichSidesInt for details on how this -// works. -func whichSidesColor(i ...TerminalColor) (top, right, bottom, left TerminalColor, ok bool) { - switch len(i) { - case 1: - top = i[0] - bottom = i[0] - left = i[0] - right = i[0] - ok = true - case 2: //nolint:mnd - top = i[0] - bottom = i[0] - left = i[1] - right = i[1] - ok = true - case 3: //nolint:mnd - top = i[0] - left = i[1] - right = i[1] - bottom = i[2] - ok = true - case 4: //nolint:mnd - top = i[0] - right = i[1] - bottom = i[2] - left = i[3] - ok = true - } - return top, right, bottom, left, ok -} diff --git a/vendor/github.com/charmbracelet/lipgloss/size.go b/vendor/github.com/charmbracelet/lipgloss/size.go deleted file mode 100644 index e169ff5e23..0000000000 --- a/vendor/github.com/charmbracelet/lipgloss/size.go +++ /dev/null @@ -1,41 +0,0 @@ -package lipgloss - -import ( - "strings" - - "github.com/charmbracelet/x/ansi" -) - -// Width returns the cell width of characters in the string. ANSI sequences are -// ignored and characters wider than one cell (such as Chinese characters and -// emojis) are appropriately measured. -// -// You should use this instead of len(string) len([]rune(string) as neither -// will give you accurate results. -func Width(str string) (width int) { - for _, l := range strings.Split(str, "\n") { - w := ansi.StringWidth(l) - if w > width { - width = w - } - } - - return width -} - -// Height returns height of a string in cells. This is done simply by -// counting \n characters. If your strings use \r\n for newlines you should -// convert them to \n first, or simply write a separate function for measuring -// height. -func Height(str string) int { - return strings.Count(str, "\n") + 1 -} - -// Size returns the width and height of the string in cells. ANSI sequences are -// ignored and characters wider than one cell (such as Chinese characters and -// emojis) are appropriately measured. -func Size(str string) (width, height int) { - width = Width(str) - height = Height(str) - return width, height -} diff --git a/vendor/github.com/charmbracelet/lipgloss/style.go b/vendor/github.com/charmbracelet/lipgloss/style.go deleted file mode 100644 index 59fa3ab216..0000000000 --- a/vendor/github.com/charmbracelet/lipgloss/style.go +++ /dev/null @@ -1,588 +0,0 @@ -package lipgloss - -import ( - "strings" - "unicode" - - "github.com/charmbracelet/x/ansi" - "github.com/charmbracelet/x/cellbuf" - "github.com/muesli/termenv" -) - -const tabWidthDefault = 4 - -// Property for a key. -type propKey int64 - -// Available properties. -const ( - // Boolean props come first. - boldKey propKey = 1 << iota - italicKey - underlineKey - strikethroughKey - reverseKey - blinkKey - faintKey - underlineSpacesKey - strikethroughSpacesKey - colorWhitespaceKey - - // Non-boolean props. - foregroundKey - backgroundKey - widthKey - heightKey - alignHorizontalKey - alignVerticalKey - - // Padding. - paddingTopKey - paddingRightKey - paddingBottomKey - paddingLeftKey - - // Margins. - marginTopKey - marginRightKey - marginBottomKey - marginLeftKey - marginBackgroundKey - - // Border runes. - borderStyleKey - - // Border edges. - borderTopKey - borderRightKey - borderBottomKey - borderLeftKey - - // Border foreground colors. - borderTopForegroundKey - borderRightForegroundKey - borderBottomForegroundKey - borderLeftForegroundKey - - // Border background colors. - borderTopBackgroundKey - borderRightBackgroundKey - borderBottomBackgroundKey - borderLeftBackgroundKey - - inlineKey - maxWidthKey - maxHeightKey - tabWidthKey - - transformKey -) - -// props is a set of properties. -type props int64 - -// set sets a property. -func (p props) set(k propKey) props { - return p | props(k) -} - -// unset unsets a property. -func (p props) unset(k propKey) props { - return p &^ props(k) -} - -// has checks if a property is set. -func (p props) has(k propKey) bool { - return p&props(k) != 0 -} - -// NewStyle returns a new, empty Style. While it's syntactic sugar for the -// Style{} primitive, it's recommended to use this function for creating styles -// in case the underlying implementation changes. It takes an optional string -// value to be set as the underlying string value for this style. -func NewStyle() Style { - return renderer.NewStyle() -} - -// NewStyle returns a new, empty Style. While it's syntactic sugar for the -// Style{} primitive, it's recommended to use this function for creating styles -// in case the underlying implementation changes. It takes an optional string -// value to be set as the underlying string value for this style. -func (r *Renderer) NewStyle() Style { - s := Style{r: r} - return s -} - -// Style contains a set of rules that comprise a style as a whole. -type Style struct { - r *Renderer - props props - value string - - // we store bool props values here - attrs int - - // props that have values - fgColor TerminalColor - bgColor TerminalColor - - width int - height int - - alignHorizontal Position - alignVertical Position - - paddingTop int - paddingRight int - paddingBottom int - paddingLeft int - - marginTop int - marginRight int - marginBottom int - marginLeft int - marginBgColor TerminalColor - - borderStyle Border - borderTopFgColor TerminalColor - borderRightFgColor TerminalColor - borderBottomFgColor TerminalColor - borderLeftFgColor TerminalColor - borderTopBgColor TerminalColor - borderRightBgColor TerminalColor - borderBottomBgColor TerminalColor - borderLeftBgColor TerminalColor - - maxWidth int - maxHeight int - tabWidth int - - transform func(string) string -} - -// joinString joins a list of strings into a single string separated with a -// space. -func joinString(strs ...string) string { - return strings.Join(strs, " ") -} - -// SetString sets the underlying string value for this style. To render once -// the underlying string is set, use the Style.String. This method is -// a convenience for cases when having a stringer implementation is handy, such -// as when using fmt.Sprintf. You can also simply define a style and render out -// strings directly with Style.Render. -func (s Style) SetString(strs ...string) Style { - s.value = joinString(strs...) - return s -} - -// Value returns the raw, unformatted, underlying string value for this style. -func (s Style) Value() string { - return s.value -} - -// String implements stringer for a Style, returning the rendered result based -// on the rules in this style. An underlying string value must be set with -// Style.SetString prior to using this method. -func (s Style) String() string { - return s.Render() -} - -// Copy returns a copy of this style, including any underlying string values. -// -// Deprecated: to copy just use assignment (i.e. a := b). All methods also -// return a new style. -func (s Style) Copy() Style { - return s -} - -// Inherit overlays the style in the argument onto this style by copying each explicitly -// set value from the argument style onto this style if it is not already explicitly set. -// Existing set values are kept intact and not overwritten. -// -// Margins, padding, and underlying string values are not inherited. -func (s Style) Inherit(i Style) Style { - for k := boldKey; k <= transformKey; k <<= 1 { - if !i.isSet(k) { - continue - } - - switch k { //nolint:exhaustive - case marginTopKey, marginRightKey, marginBottomKey, marginLeftKey: - // Margins are not inherited - continue - case paddingTopKey, paddingRightKey, paddingBottomKey, paddingLeftKey: - // Padding is not inherited - continue - case backgroundKey: - // The margins also inherit the background color - if !s.isSet(marginBackgroundKey) && !i.isSet(marginBackgroundKey) { - s.set(marginBackgroundKey, i.bgColor) - } - } - - if s.isSet(k) { - continue - } - - s.setFrom(k, i) - } - return s -} - -// Render applies the defined style formatting to a given string. -func (s Style) Render(strs ...string) string { - if s.r == nil { - s.r = renderer - } - if s.value != "" { - strs = append([]string{s.value}, strs...) - } - - var ( - str = joinString(strs...) - - p = s.r.ColorProfile() - te = p.String() - teSpace = p.String() - teWhitespace = p.String() - - bold = s.getAsBool(boldKey, false) - italic = s.getAsBool(italicKey, false) - underline = s.getAsBool(underlineKey, false) - strikethrough = s.getAsBool(strikethroughKey, false) - reverse = s.getAsBool(reverseKey, false) - blink = s.getAsBool(blinkKey, false) - faint = s.getAsBool(faintKey, false) - - fg = s.getAsColor(foregroundKey) - bg = s.getAsColor(backgroundKey) - - width = s.getAsInt(widthKey) - height = s.getAsInt(heightKey) - horizontalAlign = s.getAsPosition(alignHorizontalKey) - verticalAlign = s.getAsPosition(alignVerticalKey) - - topPadding = s.getAsInt(paddingTopKey) - rightPadding = s.getAsInt(paddingRightKey) - bottomPadding = s.getAsInt(paddingBottomKey) - leftPadding = s.getAsInt(paddingLeftKey) - - colorWhitespace = s.getAsBool(colorWhitespaceKey, true) - inline = s.getAsBool(inlineKey, false) - maxWidth = s.getAsInt(maxWidthKey) - maxHeight = s.getAsInt(maxHeightKey) - - underlineSpaces = s.getAsBool(underlineSpacesKey, false) || (underline && s.getAsBool(underlineSpacesKey, true)) - strikethroughSpaces = s.getAsBool(strikethroughSpacesKey, false) || (strikethrough && s.getAsBool(strikethroughSpacesKey, true)) - - // Do we need to style whitespace (padding and space outside - // paragraphs) separately? - styleWhitespace = reverse - - // Do we need to style spaces separately? - useSpaceStyler = (underline && !underlineSpaces) || (strikethrough && !strikethroughSpaces) || underlineSpaces || strikethroughSpaces - - transform = s.getAsTransform(transformKey) - ) - - if transform != nil { - str = transform(str) - } - - if s.props == 0 { - return s.maybeConvertTabs(str) - } - - // Enable support for ANSI on the legacy Windows cmd.exe console. This is a - // no-op on non-Windows systems and on Windows runs only once. - enableLegacyWindowsANSI() - - if bold { - te = te.Bold() - } - if italic { - te = te.Italic() - } - if underline { - te = te.Underline() - } - if reverse { - teWhitespace = teWhitespace.Reverse() - te = te.Reverse() - } - if blink { - te = te.Blink() - } - if faint { - te = te.Faint() - } - - if fg != noColor { - te = te.Foreground(fg.color(s.r)) - if styleWhitespace { - teWhitespace = teWhitespace.Foreground(fg.color(s.r)) - } - if useSpaceStyler { - teSpace = teSpace.Foreground(fg.color(s.r)) - } - } - - if bg != noColor { - te = te.Background(bg.color(s.r)) - if colorWhitespace { - teWhitespace = teWhitespace.Background(bg.color(s.r)) - } - if useSpaceStyler { - teSpace = teSpace.Background(bg.color(s.r)) - } - } - - if underline { - te = te.Underline() - } - if strikethrough { - te = te.CrossOut() - } - - if underlineSpaces { - teSpace = teSpace.Underline() - } - if strikethroughSpaces { - teSpace = teSpace.CrossOut() - } - - // Potentially convert tabs to spaces - str = s.maybeConvertTabs(str) - // carriage returns can cause strange behaviour when rendering. - str = strings.ReplaceAll(str, "\r\n", "\n") - - // Strip newlines in single line mode - if inline { - str = strings.ReplaceAll(str, "\n", "") - } - - // Word wrap - if !inline && width > 0 { - wrapAt := width - leftPadding - rightPadding - str = cellbuf.Wrap(str, wrapAt, "") - } - - // Render core text - { - var b strings.Builder - - l := strings.Split(str, "\n") - for i := range l { - if useSpaceStyler { - // Look for spaces and apply a different styler - for _, r := range l[i] { - if unicode.IsSpace(r) { - b.WriteString(teSpace.Styled(string(r))) - continue - } - b.WriteString(te.Styled(string(r))) - } - } else { - b.WriteString(te.Styled(l[i])) - } - if i != len(l)-1 { - b.WriteRune('\n') - } - } - - str = b.String() - } - - // Padding - if !inline { //nolint:nestif - if leftPadding > 0 { - var st *termenv.Style - if colorWhitespace || styleWhitespace { - st = &teWhitespace - } - str = padLeft(str, leftPadding, st) - } - - if rightPadding > 0 { - var st *termenv.Style - if colorWhitespace || styleWhitespace { - st = &teWhitespace - } - str = padRight(str, rightPadding, st) - } - - if topPadding > 0 { - str = strings.Repeat("\n", topPadding) + str - } - - if bottomPadding > 0 { - str += strings.Repeat("\n", bottomPadding) - } - } - - // Height - if height > 0 { - str = alignTextVertical(str, verticalAlign, height, nil) - } - - // Set alignment. This will also pad short lines with spaces so that all - // lines are the same length, so we run it under a few different conditions - // beyond alignment. - { - numLines := strings.Count(str, "\n") - - if numLines != 0 || width != 0 { - var st *termenv.Style - if colorWhitespace || styleWhitespace { - st = &teWhitespace - } - str = alignTextHorizontal(str, horizontalAlign, width, st) - } - } - - if !inline { - str = s.applyBorder(str) - str = s.applyMargins(str, inline) - } - - // Truncate according to MaxWidth - if maxWidth > 0 { - lines := strings.Split(str, "\n") - - for i := range lines { - lines[i] = ansi.Truncate(lines[i], maxWidth, "") - } - - str = strings.Join(lines, "\n") - } - - // Truncate according to MaxHeight - if maxHeight > 0 { - lines := strings.Split(str, "\n") - height := min(maxHeight, len(lines)) - if len(lines) > 0 { - str = strings.Join(lines[:height], "\n") - } - } - - return str -} - -func (s Style) maybeConvertTabs(str string) string { - tw := tabWidthDefault - if s.isSet(tabWidthKey) { - tw = s.getAsInt(tabWidthKey) - } - switch tw { - case -1: - return str - case 0: - return strings.ReplaceAll(str, "\t", "") - default: - return strings.ReplaceAll(str, "\t", strings.Repeat(" ", tw)) - } -} - -func (s Style) applyMargins(str string, inline bool) string { - var ( - topMargin = s.getAsInt(marginTopKey) - rightMargin = s.getAsInt(marginRightKey) - bottomMargin = s.getAsInt(marginBottomKey) - leftMargin = s.getAsInt(marginLeftKey) - - styler termenv.Style - ) - - bgc := s.getAsColor(marginBackgroundKey) - if bgc != noColor { - styler = styler.Background(bgc.color(s.r)) - } - - // Add left and right margin - str = padLeft(str, leftMargin, &styler) - str = padRight(str, rightMargin, &styler) - - // Top/bottom margin - if !inline { - _, width := getLines(str) - spaces := strings.Repeat(" ", width) - - if topMargin > 0 { - str = styler.Styled(strings.Repeat(spaces+"\n", topMargin)) + str - } - if bottomMargin > 0 { - str += styler.Styled(strings.Repeat("\n"+spaces, bottomMargin)) - } - } - - return str -} - -// Apply left padding. -func padLeft(str string, n int, style *termenv.Style) string { - return pad(str, -n, style) -} - -// Apply right padding. -func padRight(str string, n int, style *termenv.Style) string { - return pad(str, n, style) -} - -// pad adds padding to either the left or right side of a string. -// Positive values add to the right side while negative values -// add to the left side. -func pad(str string, n int, style *termenv.Style) string { - if n == 0 { - return str - } - - sp := strings.Repeat(" ", abs(n)) - if style != nil { - sp = style.Styled(sp) - } - - b := strings.Builder{} - l := strings.Split(str, "\n") - - for i := range l { - switch { - // pad right - case n > 0: - b.WriteString(l[i]) - b.WriteString(sp) - // pad left - default: - b.WriteString(sp) - b.WriteString(l[i]) - } - - if i != len(l)-1 { - b.WriteRune('\n') - } - } - - return b.String() -} - -func max(a, b int) int { //nolint:unparam,predeclared - if a > b { - return a - } - return b -} - -func min(a, b int) int { //nolint:predeclared - if a < b { - return a - } - return b -} - -func abs(a int) int { - if a < 0 { - return -a - } - - return a -} diff --git a/vendor/github.com/charmbracelet/lipgloss/unset.go b/vendor/github.com/charmbracelet/lipgloss/unset.go deleted file mode 100644 index 1086e72268..0000000000 --- a/vendor/github.com/charmbracelet/lipgloss/unset.go +++ /dev/null @@ -1,331 +0,0 @@ -package lipgloss - -// unset unsets a property from a style. -func (s *Style) unset(key propKey) { - s.props = s.props.unset(key) -} - -// UnsetBold removes the bold style rule, if set. -func (s Style) UnsetBold() Style { - s.unset(boldKey) - return s -} - -// UnsetItalic removes the italic style rule, if set. -func (s Style) UnsetItalic() Style { - s.unset(italicKey) - return s -} - -// UnsetUnderline removes the underline style rule, if set. -func (s Style) UnsetUnderline() Style { - s.unset(underlineKey) - return s -} - -// UnsetStrikethrough removes the strikethrough style rule, if set. -func (s Style) UnsetStrikethrough() Style { - s.unset(strikethroughKey) - return s -} - -// UnsetReverse removes the reverse style rule, if set. -func (s Style) UnsetReverse() Style { - s.unset(reverseKey) - return s -} - -// UnsetBlink removes the blink style rule, if set. -func (s Style) UnsetBlink() Style { - s.unset(blinkKey) - return s -} - -// UnsetFaint removes the faint style rule, if set. -func (s Style) UnsetFaint() Style { - s.unset(faintKey) - return s -} - -// UnsetForeground removes the foreground style rule, if set. -func (s Style) UnsetForeground() Style { - s.unset(foregroundKey) - return s -} - -// UnsetBackground removes the background style rule, if set. -func (s Style) UnsetBackground() Style { - s.unset(backgroundKey) - return s -} - -// UnsetWidth removes the width style rule, if set. -func (s Style) UnsetWidth() Style { - s.unset(widthKey) - return s -} - -// UnsetHeight removes the height style rule, if set. -func (s Style) UnsetHeight() Style { - s.unset(heightKey) - return s -} - -// UnsetAlign removes the horizontal and vertical text alignment style rule, if set. -func (s Style) UnsetAlign() Style { - s.unset(alignHorizontalKey) - s.unset(alignVerticalKey) - return s -} - -// UnsetAlignHorizontal removes the horizontal text alignment style rule, if set. -func (s Style) UnsetAlignHorizontal() Style { - s.unset(alignHorizontalKey) - return s -} - -// UnsetAlignVertical removes the vertical text alignment style rule, if set. -func (s Style) UnsetAlignVertical() Style { - s.unset(alignVerticalKey) - return s -} - -// UnsetPadding removes all padding style rules. -func (s Style) UnsetPadding() Style { - s.unset(paddingLeftKey) - s.unset(paddingRightKey) - s.unset(paddingTopKey) - s.unset(paddingBottomKey) - return s -} - -// UnsetPaddingLeft removes the left padding style rule, if set. -func (s Style) UnsetPaddingLeft() Style { - s.unset(paddingLeftKey) - return s -} - -// UnsetPaddingRight removes the right padding style rule, if set. -func (s Style) UnsetPaddingRight() Style { - s.unset(paddingRightKey) - return s -} - -// UnsetPaddingTop removes the top padding style rule, if set. -func (s Style) UnsetPaddingTop() Style { - s.unset(paddingTopKey) - return s -} - -// UnsetPaddingBottom removes the bottom padding style rule, if set. -func (s Style) UnsetPaddingBottom() Style { - s.unset(paddingBottomKey) - return s -} - -// UnsetColorWhitespace removes the rule for coloring padding, if set. -func (s Style) UnsetColorWhitespace() Style { - s.unset(colorWhitespaceKey) - return s -} - -// UnsetMargins removes all margin style rules. -func (s Style) UnsetMargins() Style { - s.unset(marginLeftKey) - s.unset(marginRightKey) - s.unset(marginTopKey) - s.unset(marginBottomKey) - return s -} - -// UnsetMarginLeft removes the left margin style rule, if set. -func (s Style) UnsetMarginLeft() Style { - s.unset(marginLeftKey) - return s -} - -// UnsetMarginRight removes the right margin style rule, if set. -func (s Style) UnsetMarginRight() Style { - s.unset(marginRightKey) - return s -} - -// UnsetMarginTop removes the top margin style rule, if set. -func (s Style) UnsetMarginTop() Style { - s.unset(marginTopKey) - return s -} - -// UnsetMarginBottom removes the bottom margin style rule, if set. -func (s Style) UnsetMarginBottom() Style { - s.unset(marginBottomKey) - return s -} - -// UnsetMarginBackground removes the margin's background color. Note that the -// margin's background color can be set from the background color of another -// style during inheritance. -func (s Style) UnsetMarginBackground() Style { - s.unset(marginBackgroundKey) - return s -} - -// UnsetBorderStyle removes the border style rule, if set. -func (s Style) UnsetBorderStyle() Style { - s.unset(borderStyleKey) - return s -} - -// UnsetBorderTop removes the border top style rule, if set. -func (s Style) UnsetBorderTop() Style { - s.unset(borderTopKey) - return s -} - -// UnsetBorderRight removes the border right style rule, if set. -func (s Style) UnsetBorderRight() Style { - s.unset(borderRightKey) - return s -} - -// UnsetBorderBottom removes the border bottom style rule, if set. -func (s Style) UnsetBorderBottom() Style { - s.unset(borderBottomKey) - return s -} - -// UnsetBorderLeft removes the border left style rule, if set. -func (s Style) UnsetBorderLeft() Style { - s.unset(borderLeftKey) - return s -} - -// UnsetBorderForeground removes all border foreground color styles, if set. -func (s Style) UnsetBorderForeground() Style { - s.unset(borderTopForegroundKey) - s.unset(borderRightForegroundKey) - s.unset(borderBottomForegroundKey) - s.unset(borderLeftForegroundKey) - return s -} - -// UnsetBorderTopForeground removes the top border foreground color rule, -// if set. -func (s Style) UnsetBorderTopForeground() Style { - s.unset(borderTopForegroundKey) - return s -} - -// UnsetBorderRightForeground removes the right border foreground color rule, -// if set. -func (s Style) UnsetBorderRightForeground() Style { - s.unset(borderRightForegroundKey) - return s -} - -// UnsetBorderBottomForeground removes the bottom border foreground color -// rule, if set. -func (s Style) UnsetBorderBottomForeground() Style { - s.unset(borderBottomForegroundKey) - return s -} - -// UnsetBorderLeftForeground removes the left border foreground color rule, -// if set. -func (s Style) UnsetBorderLeftForeground() Style { - s.unset(borderLeftForegroundKey) - return s -} - -// UnsetBorderBackground removes all border background color styles, if -// set. -func (s Style) UnsetBorderBackground() Style { - s.unset(borderTopBackgroundKey) - s.unset(borderRightBackgroundKey) - s.unset(borderBottomBackgroundKey) - s.unset(borderLeftBackgroundKey) - return s -} - -// UnsetBorderTopBackgroundColor removes the top border background color rule, -// if set. -// -// Deprecated: This function simply calls Style.UnsetBorderTopBackground. -func (s Style) UnsetBorderTopBackgroundColor() Style { - return s.UnsetBorderTopBackground() -} - -// UnsetBorderTopBackground removes the top border background color rule, -// if set. -func (s Style) UnsetBorderTopBackground() Style { - s.unset(borderTopBackgroundKey) - return s -} - -// UnsetBorderRightBackground removes the right border background color -// rule, if set. -func (s Style) UnsetBorderRightBackground() Style { - s.unset(borderRightBackgroundKey) - return s -} - -// UnsetBorderBottomBackground removes the bottom border background color -// rule, if set. -func (s Style) UnsetBorderBottomBackground() Style { - s.unset(borderBottomBackgroundKey) - return s -} - -// UnsetBorderLeftBackground removes the left border color rule, if set. -func (s Style) UnsetBorderLeftBackground() Style { - s.unset(borderLeftBackgroundKey) - return s -} - -// UnsetInline removes the inline style rule, if set. -func (s Style) UnsetInline() Style { - s.unset(inlineKey) - return s -} - -// UnsetMaxWidth removes the max width style rule, if set. -func (s Style) UnsetMaxWidth() Style { - s.unset(maxWidthKey) - return s -} - -// UnsetMaxHeight removes the max height style rule, if set. -func (s Style) UnsetMaxHeight() Style { - s.unset(maxHeightKey) - return s -} - -// UnsetTabWidth removes the tab width style rule, if set. -func (s Style) UnsetTabWidth() Style { - s.unset(tabWidthKey) - return s -} - -// UnsetUnderlineSpaces removes the value set by UnderlineSpaces. -func (s Style) UnsetUnderlineSpaces() Style { - s.unset(underlineSpacesKey) - return s -} - -// UnsetStrikethroughSpaces removes the value set by StrikethroughSpaces. -func (s Style) UnsetStrikethroughSpaces() Style { - s.unset(strikethroughSpacesKey) - return s -} - -// UnsetTransform removes the value set by Transform. -func (s Style) UnsetTransform() Style { - s.unset(transformKey) - return s -} - -// UnsetString sets the underlying string value to the empty string. -func (s Style) UnsetString() Style { - s.value = "" - return s -} diff --git a/vendor/github.com/charmbracelet/lipgloss/whitespace.go b/vendor/github.com/charmbracelet/lipgloss/whitespace.go deleted file mode 100644 index 040dc98e65..0000000000 --- a/vendor/github.com/charmbracelet/lipgloss/whitespace.go +++ /dev/null @@ -1,83 +0,0 @@ -package lipgloss - -import ( - "strings" - - "github.com/charmbracelet/x/ansi" - "github.com/muesli/termenv" -) - -// whitespace is a whitespace renderer. -type whitespace struct { - re *Renderer - style termenv.Style - chars string -} - -// newWhitespace creates a new whitespace renderer. The order of the options -// matters, if you're using WithWhitespaceRenderer, make sure it comes first as -// other options might depend on it. -func newWhitespace(r *Renderer, opts ...WhitespaceOption) *whitespace { - w := &whitespace{ - re: r, - style: r.ColorProfile().String(), - } - for _, opt := range opts { - opt(w) - } - return w -} - -// Render whitespaces. -func (w whitespace) render(width int) string { - if w.chars == "" { - w.chars = " " - } - - r := []rune(w.chars) - j := 0 - b := strings.Builder{} - - // Cycle through runes and print them into the whitespace. - for i := 0; i < width; { - b.WriteRune(r[j]) - j++ - if j >= len(r) { - j = 0 - } - i += ansi.StringWidth(string(r[j])) - } - - // Fill any extra gaps white spaces. This might be necessary if any runes - // are more than one cell wide, which could leave a one-rune gap. - short := width - ansi.StringWidth(b.String()) - if short > 0 { - b.WriteString(strings.Repeat(" ", short)) - } - - return w.style.Styled(b.String()) -} - -// WhitespaceOption sets a styling rule for rendering whitespace. -type WhitespaceOption func(*whitespace) - -// WithWhitespaceForeground sets the color of the characters in the whitespace. -func WithWhitespaceForeground(c TerminalColor) WhitespaceOption { - return func(w *whitespace) { - w.style = w.style.Foreground(c.color(w.re)) - } -} - -// WithWhitespaceBackground sets the background color of the whitespace. -func WithWhitespaceBackground(c TerminalColor) WhitespaceOption { - return func(w *whitespace) { - w.style = w.style.Background(c.color(w.re)) - } -} - -// WithWhitespaceChars sets the characters to be rendered in the whitespace. -func WithWhitespaceChars(s string) WhitespaceOption { - return func(w *whitespace) { - w.chars = s - } -} diff --git a/vendor/github.com/charmbracelet/x/ansi/LICENSE b/vendor/github.com/charmbracelet/x/ansi/LICENSE deleted file mode 100644 index 65a5654e20..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 Charmbracelet, Inc. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/charmbracelet/x/ansi/ansi.go b/vendor/github.com/charmbracelet/x/ansi/ansi.go deleted file mode 100644 index 48d873c3f8..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/ansi.go +++ /dev/null @@ -1,11 +0,0 @@ -package ansi - -import "io" - -// Execute is a function that "execute" the given escape sequence by writing it -// to the provided output writter. -// -// This is a syntactic sugar over [io.WriteString]. -func Execute(w io.Writer, s string) (int, error) { - return io.WriteString(w, s) -} diff --git a/vendor/github.com/charmbracelet/x/ansi/ascii.go b/vendor/github.com/charmbracelet/x/ansi/ascii.go deleted file mode 100644 index 188582f7e6..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/ascii.go +++ /dev/null @@ -1,8 +0,0 @@ -package ansi - -const ( - // SP is the space character (Char: \x20). - SP = 0x20 - // DEL is the delete character (Caret: ^?, Char: \x7f). - DEL = 0x7F -) diff --git a/vendor/github.com/charmbracelet/x/ansi/background.go b/vendor/github.com/charmbracelet/x/ansi/background.go deleted file mode 100644 index 2383cf09f6..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/background.go +++ /dev/null @@ -1,169 +0,0 @@ -package ansi - -import ( - "fmt" - "image/color" -) - -// Colorizer is a [color.Color] interface that can be formatted as a string. -type Colorizer interface { - color.Color - fmt.Stringer -} - -// HexColorizer is a [color.Color] that can be formatted as a hex string. -type HexColorizer struct{ color.Color } - -var _ Colorizer = HexColorizer{} - -// String returns the color as a hex string. If the color is nil, an empty -// string is returned. -func (h HexColorizer) String() string { - if h.Color == nil { - return "" - } - r, g, b, _ := h.RGBA() - // Get the lower 8 bits - r &= 0xff - g &= 0xff - b &= 0xff - return fmt.Sprintf("#%02x%02x%02x", uint8(r), uint8(g), uint8(b)) //nolint:gosec -} - -// XRGBColorizer is a [color.Color] that can be formatted as an XParseColor -// rgb: string. -// -// See: https://linux.die.net/man/3/xparsecolor -type XRGBColorizer struct{ color.Color } - -var _ Colorizer = XRGBColorizer{} - -// String returns the color as an XParseColor rgb: string. If the color is nil, -// an empty string is returned. -func (x XRGBColorizer) String() string { - if x.Color == nil { - return "" - } - r, g, b, _ := x.RGBA() - // Get the lower 8 bits - return fmt.Sprintf("rgb:%04x/%04x/%04x", r, g, b) -} - -// XRGBAColorizer is a [color.Color] that can be formatted as an XParseColor -// rgba: string. -// -// See: https://linux.die.net/man/3/xparsecolor -type XRGBAColorizer struct{ color.Color } - -var _ Colorizer = XRGBAColorizer{} - -// String returns the color as an XParseColor rgba: string. If the color is nil, -// an empty string is returned. -func (x XRGBAColorizer) String() string { - if x.Color == nil { - return "" - } - r, g, b, a := x.RGBA() - // Get the lower 8 bits - return fmt.Sprintf("rgba:%04x/%04x/%04x/%04x", r, g, b, a) -} - -// SetForegroundColor returns a sequence that sets the default terminal -// foreground color. -// -// OSC 10 ; color ST -// OSC 10 ; color BEL -// -// Where color is the encoded color number. -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands -func SetForegroundColor(c color.Color) string { - var s string - switch c := c.(type) { - case Colorizer: - s = c.String() - case fmt.Stringer: - s = c.String() - default: - s = HexColorizer{c}.String() - } - return "\x1b]10;" + s + "\x07" -} - -// RequestForegroundColor is a sequence that requests the current default -// terminal foreground color. -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands -const RequestForegroundColor = "\x1b]10;?\x07" - -// ResetForegroundColor is a sequence that resets the default terminal -// foreground color. -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands -const ResetForegroundColor = "\x1b]110\x07" - -// SetBackgroundColor returns a sequence that sets the default terminal -// background color. -// -// OSC 11 ; color ST -// OSC 11 ; color BEL -// -// Where color is the encoded color number. -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands -func SetBackgroundColor(c color.Color) string { - var s string - switch c := c.(type) { - case Colorizer: - s = c.String() - case fmt.Stringer: - s = c.String() - default: - s = HexColorizer{c}.String() - } - return "\x1b]11;" + s + "\x07" -} - -// RequestBackgroundColor is a sequence that requests the current default -// terminal background color. -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands -const RequestBackgroundColor = "\x1b]11;?\x07" - -// ResetBackgroundColor is a sequence that resets the default terminal -// background color. -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands -const ResetBackgroundColor = "\x1b]111\x07" - -// SetCursorColor returns a sequence that sets the terminal cursor color. -// -// OSC 12 ; color ST -// OSC 12 ; color BEL -// -// Where color is the encoded color number. -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands -func SetCursorColor(c color.Color) string { - var s string - switch c := c.(type) { - case Colorizer: - s = c.String() - case fmt.Stringer: - s = c.String() - default: - s = HexColorizer{c}.String() - } - return "\x1b]12;" + s + "\x07" -} - -// RequestCursorColor is a sequence that requests the current terminal cursor -// color. -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands -const RequestCursorColor = "\x1b]12;?\x07" - -// ResetCursorColor is a sequence that resets the terminal cursor color. -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands -const ResetCursorColor = "\x1b]112\x07" diff --git a/vendor/github.com/charmbracelet/x/ansi/c0.go b/vendor/github.com/charmbracelet/x/ansi/c0.go deleted file mode 100644 index 28ff7c2a3a..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/c0.go +++ /dev/null @@ -1,79 +0,0 @@ -package ansi - -// C0 control characters. -// -// These range from (0x00-0x1F) as defined in ISO 646 (ASCII). -// See: https://en.wikipedia.org/wiki/C0_and_C1_control_codes -const ( - // NUL is the null character (Caret: ^@, Char: \0). - NUL = 0x00 - // SOH is the start of heading character (Caret: ^A). - SOH = 0x01 - // STX is the start of text character (Caret: ^B). - STX = 0x02 - // ETX is the end of text character (Caret: ^C). - ETX = 0x03 - // EOT is the end of transmission character (Caret: ^D). - EOT = 0x04 - // ENQ is the enquiry character (Caret: ^E). - ENQ = 0x05 - // ACK is the acknowledge character (Caret: ^F). - ACK = 0x06 - // BEL is the bell character (Caret: ^G, Char: \a). - BEL = 0x07 - // BS is the backspace character (Caret: ^H, Char: \b). - BS = 0x08 - // HT is the horizontal tab character (Caret: ^I, Char: \t). - HT = 0x09 - // LF is the line feed character (Caret: ^J, Char: \n). - LF = 0x0A - // VT is the vertical tab character (Caret: ^K, Char: \v). - VT = 0x0B - // FF is the form feed character (Caret: ^L, Char: \f). - FF = 0x0C - // CR is the carriage return character (Caret: ^M, Char: \r). - CR = 0x0D - // SO is the shift out character (Caret: ^N). - SO = 0x0E - // SI is the shift in character (Caret: ^O). - SI = 0x0F - // DLE is the data link escape character (Caret: ^P). - DLE = 0x10 - // DC1 is the device control 1 character (Caret: ^Q). - DC1 = 0x11 - // DC2 is the device control 2 character (Caret: ^R). - DC2 = 0x12 - // DC3 is the device control 3 character (Caret: ^S). - DC3 = 0x13 - // DC4 is the device control 4 character (Caret: ^T). - DC4 = 0x14 - // NAK is the negative acknowledge character (Caret: ^U). - NAK = 0x15 - // SYN is the synchronous idle character (Caret: ^V). - SYN = 0x16 - // ETB is the end of transmission block character (Caret: ^W). - ETB = 0x17 - // CAN is the cancel character (Caret: ^X). - CAN = 0x18 - // EM is the end of medium character (Caret: ^Y). - EM = 0x19 - // SUB is the substitute character (Caret: ^Z). - SUB = 0x1A - // ESC is the escape character (Caret: ^[, Char: \e). - ESC = 0x1B - // FS is the file separator character (Caret: ^\). - FS = 0x1C - // GS is the group separator character (Caret: ^]). - GS = 0x1D - // RS is the record separator character (Caret: ^^). - RS = 0x1E - // US is the unit separator character (Caret: ^_). - US = 0x1F - - // LS0 is the locking shift 0 character. - // This is an alias for [SI]. - LS0 = SI - // LS1 is the locking shift 1 character. - // This is an alias for [SO]. - LS1 = SO -) diff --git a/vendor/github.com/charmbracelet/x/ansi/c1.go b/vendor/github.com/charmbracelet/x/ansi/c1.go deleted file mode 100644 index 71058f5399..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/c1.go +++ /dev/null @@ -1,72 +0,0 @@ -package ansi - -// C1 control characters. -// -// These range from (0x80-0x9F) as defined in ISO 6429 (ECMA-48). -// See: https://en.wikipedia.org/wiki/C0_and_C1_control_codes -const ( - // PAD is the padding character. - PAD = 0x80 - // HOP is the high octet preset character. - HOP = 0x81 - // BPH is the break permitted here character. - BPH = 0x82 - // NBH is the no break here character. - NBH = 0x83 - // IND is the index character. - IND = 0x84 - // NEL is the next line character. - NEL = 0x85 - // SSA is the start of selected area character. - SSA = 0x86 - // ESA is the end of selected area character. - ESA = 0x87 - // HTS is the horizontal tab set character. - HTS = 0x88 - // HTJ is the horizontal tab with justification character. - HTJ = 0x89 - // VTS is the vertical tab set character. - VTS = 0x8A - // PLD is the partial line forward character. - PLD = 0x8B - // PLU is the partial line backward character. - PLU = 0x8C - // RI is the reverse index character. - RI = 0x8D - // SS2 is the single shift 2 character. - SS2 = 0x8E - // SS3 is the single shift 3 character. - SS3 = 0x8F - // DCS is the device control string character. - DCS = 0x90 - // PU1 is the private use 1 character. - PU1 = 0x91 - // PU2 is the private use 2 character. - PU2 = 0x92 - // STS is the set transmit state character. - STS = 0x93 - // CCH is the cancel character. - CCH = 0x94 - // MW is the message waiting character. - MW = 0x95 - // SPA is the start of guarded area character. - SPA = 0x96 - // EPA is the end of guarded area character. - EPA = 0x97 - // SOS is the start of string character. - SOS = 0x98 - // SGCI is the single graphic character introducer character. - SGCI = 0x99 - // SCI is the single character introducer character. - SCI = 0x9A - // CSI is the control sequence introducer character. - CSI = 0x9B - // ST is the string terminator character. - ST = 0x9C - // OSC is the operating system command character. - OSC = 0x9D - // PM is the privacy message character. - PM = 0x9E - // APC is the application program command character. - APC = 0x9F -) diff --git a/vendor/github.com/charmbracelet/x/ansi/charset.go b/vendor/github.com/charmbracelet/x/ansi/charset.go deleted file mode 100644 index 50fff51fcd..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/charset.go +++ /dev/null @@ -1,55 +0,0 @@ -package ansi - -// SelectCharacterSet sets the G-set character designator to the specified -// character set. -// -// ESC Ps Pd -// -// Where Ps is the G-set character designator, and Pd is the identifier. -// For 94-character sets, the designator can be one of: -// - ( G0 -// - ) G1 -// - * G2 -// - + G3 -// -// For 96-character sets, the designator can be one of: -// - - G1 -// - . G2 -// - / G3 -// -// Some common 94-character sets are: -// - 0 DEC Special Drawing Set -// - A United Kingdom (UK) -// - B United States (USASCII) -// -// Examples: -// -// ESC ( B Select character set G0 = United States (USASCII) -// ESC ( 0 Select character set G0 = Special Character and Line Drawing Set -// ESC ) 0 Select character set G1 = Special Character and Line Drawing Set -// ESC * A Select character set G2 = United Kingdom (UK) -// -// See: https://vt100.net/docs/vt510-rm/SCS.html -func SelectCharacterSet(gset byte, charset byte) string { - return "\x1b" + string(gset) + string(charset) -} - -// SCS is an alias for SelectCharacterSet. -func SCS(gset byte, charset byte) string { - return SelectCharacterSet(gset, charset) -} - -// Locking Shift 1 Right (LS1R) shifts G1 into GR character set. -const LS1R = "\x1b~" - -// Locking Shift 2 (LS2) shifts G2 into GL character set. -const LS2 = "\x1bn" - -// Locking Shift 2 Right (LS2R) shifts G2 into GR character set. -const LS2R = "\x1b}" - -// Locking Shift 3 (LS3) shifts G3 into GL character set. -const LS3 = "\x1bo" - -// Locking Shift 3 Right (LS3R) shifts G3 into GR character set. -const LS3R = "\x1b|" diff --git a/vendor/github.com/charmbracelet/x/ansi/clipboard.go b/vendor/github.com/charmbracelet/x/ansi/clipboard.go deleted file mode 100644 index 94d26c366d..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/clipboard.go +++ /dev/null @@ -1,75 +0,0 @@ -package ansi - -import "encoding/base64" - -// Clipboard names. -const ( - SystemClipboard = 'c' - PrimaryClipboard = 'p' -) - -// SetClipboard returns a sequence for manipulating the clipboard. -// -// OSC 52 ; Pc ; Pd ST -// OSC 52 ; Pc ; Pd BEL -// -// Where Pc is the clipboard name and Pd is the base64 encoded data. -// Empty data or invalid base64 data will reset the clipboard. -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands -func SetClipboard(c byte, d string) string { - if d != "" { - d = base64.StdEncoding.EncodeToString([]byte(d)) - } - return "\x1b]52;" + string(c) + ";" + d + "\x07" -} - -// SetSystemClipboard returns a sequence for setting the system clipboard. -// -// This is equivalent to SetClipboard(SystemClipboard, d). -func SetSystemClipboard(d string) string { - return SetClipboard(SystemClipboard, d) -} - -// SetPrimaryClipboard returns a sequence for setting the primary clipboard. -// -// This is equivalent to SetClipboard(PrimaryClipboard, d). -func SetPrimaryClipboard(d string) string { - return SetClipboard(PrimaryClipboard, d) -} - -// ResetClipboard returns a sequence for resetting the clipboard. -// -// This is equivalent to SetClipboard(c, ""). -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands -func ResetClipboard(c byte) string { - return SetClipboard(c, "") -} - -// ResetSystemClipboard is a sequence for resetting the system clipboard. -// -// This is equivalent to ResetClipboard(SystemClipboard). -const ResetSystemClipboard = "\x1b]52;c;\x07" - -// ResetPrimaryClipboard is a sequence for resetting the primary clipboard. -// -// This is equivalent to ResetClipboard(PrimaryClipboard). -const ResetPrimaryClipboard = "\x1b]52;p;\x07" - -// RequestClipboard returns a sequence for requesting the clipboard. -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands -func RequestClipboard(c byte) string { - return "\x1b]52;" + string(c) + ";?\x07" -} - -// RequestSystemClipboard is a sequence for requesting the system clipboard. -// -// This is equivalent to RequestClipboard(SystemClipboard). -const RequestSystemClipboard = "\x1b]52;c;?\x07" - -// RequestPrimaryClipboard is a sequence for requesting the primary clipboard. -// -// This is equivalent to RequestClipboard(PrimaryClipboard). -const RequestPrimaryClipboard = "\x1b]52;p;?\x07" diff --git a/vendor/github.com/charmbracelet/x/ansi/color.go b/vendor/github.com/charmbracelet/x/ansi/color.go deleted file mode 100644 index 77f8a08d1f..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/color.go +++ /dev/null @@ -1,196 +0,0 @@ -package ansi - -import ( - "image/color" -) - -// Technically speaking, the 16 basic ANSI colors are arbitrary and can be -// customized at the terminal level. Given that, we're returning what we feel -// are good defaults. -// -// This could also be a slice, but we use a map to make the mappings very -// explicit. -// -// See: https://www.ditig.com/publications/256-colors-cheat-sheet -var lowANSI = map[uint32]uint32{ - 0: 0x000000, // black - 1: 0x800000, // red - 2: 0x008000, // green - 3: 0x808000, // yellow - 4: 0x000080, // blue - 5: 0x800080, // magenta - 6: 0x008080, // cyan - 7: 0xc0c0c0, // white - 8: 0x808080, // bright black - 9: 0xff0000, // bright red - 10: 0x00ff00, // bright green - 11: 0xffff00, // bright yellow - 12: 0x0000ff, // bright blue - 13: 0xff00ff, // bright magenta - 14: 0x00ffff, // bright cyan - 15: 0xffffff, // bright white -} - -// Color is a color that can be used in a terminal. ANSI (including -// ANSI256) and 24-bit "true colors" fall under this category. -type Color interface { - color.Color -} - -// BasicColor is an ANSI 3-bit or 4-bit color with a value from 0 to 15. -type BasicColor uint8 - -var _ Color = BasicColor(0) - -const ( - // Black is the ANSI black color. - Black BasicColor = iota - - // Red is the ANSI red color. - Red - - // Green is the ANSI green color. - Green - - // Yellow is the ANSI yellow color. - Yellow - - // Blue is the ANSI blue color. - Blue - - // Magenta is the ANSI magenta color. - Magenta - - // Cyan is the ANSI cyan color. - Cyan - - // White is the ANSI white color. - White - - // BrightBlack is the ANSI bright black color. - BrightBlack - - // BrightRed is the ANSI bright red color. - BrightRed - - // BrightGreen is the ANSI bright green color. - BrightGreen - - // BrightYellow is the ANSI bright yellow color. - BrightYellow - - // BrightBlue is the ANSI bright blue color. - BrightBlue - - // BrightMagenta is the ANSI bright magenta color. - BrightMagenta - - // BrightCyan is the ANSI bright cyan color. - BrightCyan - - // BrightWhite is the ANSI bright white color. - BrightWhite -) - -// RGBA returns the red, green, blue and alpha components of the color. It -// satisfies the color.Color interface. -func (c BasicColor) RGBA() (uint32, uint32, uint32, uint32) { - ansi := uint32(c) - if ansi > 15 { - return 0, 0, 0, 0xffff - } - - r, g, b := ansiToRGB(ansi) - return toRGBA(r, g, b) -} - -// ExtendedColor is an ANSI 256 (8-bit) color with a value from 0 to 255. -type ExtendedColor uint8 - -var _ Color = ExtendedColor(0) - -// RGBA returns the red, green, blue and alpha components of the color. It -// satisfies the color.Color interface. -func (c ExtendedColor) RGBA() (uint32, uint32, uint32, uint32) { - r, g, b := ansiToRGB(uint32(c)) - return toRGBA(r, g, b) -} - -// TrueColor is a 24-bit color that can be used in the terminal. -// This can be used to represent RGB colors. -// -// For example, the color red can be represented as: -// -// TrueColor(0xff0000) -type TrueColor uint32 - -var _ Color = TrueColor(0) - -// RGBA returns the red, green, blue and alpha components of the color. It -// satisfies the color.Color interface. -func (c TrueColor) RGBA() (uint32, uint32, uint32, uint32) { - r, g, b := hexToRGB(uint32(c)) - return toRGBA(r, g, b) -} - -// ansiToRGB converts an ANSI color to a 24-bit RGB color. -// -// r, g, b := ansiToRGB(57) -func ansiToRGB(ansi uint32) (uint32, uint32, uint32) { - // For out-of-range values return black. - if ansi > 255 { - return 0, 0, 0 - } - - // Low ANSI. - if ansi < 16 { - h, ok := lowANSI[ansi] - if !ok { - return 0, 0, 0 - } - r, g, b := hexToRGB(h) - return r, g, b - } - - // Grays. - if ansi > 231 { - s := (ansi-232)*10 + 8 - return s, s, s - } - - // ANSI256. - n := ansi - 16 - b := n % 6 - g := (n - b) / 6 % 6 - r := (n - b - g*6) / 36 % 6 - for _, v := range []*uint32{&r, &g, &b} { - if *v > 0 { - c := *v*40 + 55 - *v = c - } - } - - return r, g, b -} - -// hexToRGB converts a number in hexadecimal format to red, green, and blue -// values. -// -// r, g, b := hexToRGB(0x0000FF) -func hexToRGB(hex uint32) (uint32, uint32, uint32) { - return hex >> 16 & 0xff, hex >> 8 & 0xff, hex & 0xff -} - -// toRGBA converts an RGB 8-bit color values to 32-bit color values suitable -// for color.Color. -// -// color.Color requires 16-bit color values, so we duplicate the 8-bit values -// to fill the 16-bit values. -// -// This always returns 0xffff (opaque) for the alpha channel. -func toRGBA(r, g, b uint32) (uint32, uint32, uint32, uint32) { - r |= r << 8 - g |= g << 8 - b |= b << 8 - return r, g, b, 0xffff -} diff --git a/vendor/github.com/charmbracelet/x/ansi/ctrl.go b/vendor/github.com/charmbracelet/x/ansi/ctrl.go deleted file mode 100644 index 8ca744cf2d..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/ctrl.go +++ /dev/null @@ -1,137 +0,0 @@ -package ansi - -import ( - "strconv" - "strings" -) - -// RequestNameVersion (XTVERSION) is a control sequence that requests the -// terminal's name and version. It responds with a DSR sequence identifying the -// terminal. -// -// CSI > 0 q -// DCS > | text ST -// -// See https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-PC-Style-Function-Keys -const ( - RequestNameVersion = "\x1b[>q" - XTVERSION = RequestNameVersion -) - -// RequestXTVersion is a control sequence that requests the terminal's XTVERSION. It responds with a DSR sequence identifying the version. -// -// CSI > Ps q -// DCS > | text ST -// -// See https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-PC-Style-Function-Keys -// -// Deprecated: use [RequestNameVersion] instead. -const RequestXTVersion = RequestNameVersion - -// PrimaryDeviceAttributes (DA1) is a control sequence that reports the -// terminal's primary device attributes. -// -// CSI c -// CSI 0 c -// CSI ? Ps ; ... c -// -// If no attributes are given, or if the attribute is 0, this function returns -// the request sequence. Otherwise, it returns the response sequence. -// -// See https://vt100.net/docs/vt510-rm/DA1.html -func PrimaryDeviceAttributes(attrs ...int) string { - if len(attrs) == 0 { - return RequestPrimaryDeviceAttributes - } else if len(attrs) == 1 && attrs[0] == 0 { - return "\x1b[0c" - } - - as := make([]string, len(attrs)) - for i, a := range attrs { - as[i] = strconv.Itoa(a) - } - return "\x1b[?" + strings.Join(as, ";") + "c" -} - -// DA1 is an alias for [PrimaryDeviceAttributes]. -func DA1(attrs ...int) string { - return PrimaryDeviceAttributes(attrs...) -} - -// RequestPrimaryDeviceAttributes is a control sequence that requests the -// terminal's primary device attributes (DA1). -// -// CSI c -// -// See https://vt100.net/docs/vt510-rm/DA1.html -const RequestPrimaryDeviceAttributes = "\x1b[c" - -// SecondaryDeviceAttributes (DA2) is a control sequence that reports the -// terminal's secondary device attributes. -// -// CSI > c -// CSI > 0 c -// CSI > Ps ; ... c -// -// See https://vt100.net/docs/vt510-rm/DA2.html -func SecondaryDeviceAttributes(attrs ...int) string { - if len(attrs) == 0 { - return RequestSecondaryDeviceAttributes - } - - as := make([]string, len(attrs)) - for i, a := range attrs { - as[i] = strconv.Itoa(a) - } - return "\x1b[>" + strings.Join(as, ";") + "c" -} - -// DA2 is an alias for [SecondaryDeviceAttributes]. -func DA2(attrs ...int) string { - return SecondaryDeviceAttributes(attrs...) -} - -// RequestSecondaryDeviceAttributes is a control sequence that requests the -// terminal's secondary device attributes (DA2). -// -// CSI > c -// -// See https://vt100.net/docs/vt510-rm/DA2.html -const RequestSecondaryDeviceAttributes = "\x1b[>c" - -// TertiaryDeviceAttributes (DA3) is a control sequence that reports the -// terminal's tertiary device attributes. -// -// CSI = c -// CSI = 0 c -// DCS ! | Text ST -// -// Where Text is the unit ID for the terminal. -// -// If no unit ID is given, or if the unit ID is 0, this function returns the -// request sequence. Otherwise, it returns the response sequence. -// -// See https://vt100.net/docs/vt510-rm/DA3.html -func TertiaryDeviceAttributes(unitID string) string { - switch unitID { - case "": - return RequestTertiaryDeviceAttributes - case "0": - return "\x1b[=0c" - } - - return "\x1bP!|" + unitID + "\x1b\\" -} - -// DA3 is an alias for [TertiaryDeviceAttributes]. -func DA3(unitID string) string { - return TertiaryDeviceAttributes(unitID) -} - -// RequestTertiaryDeviceAttributes is a control sequence that requests the -// terminal's tertiary device attributes (DA3). -// -// CSI = c -// -// See https://vt100.net/docs/vt510-rm/DA3.html -const RequestTertiaryDeviceAttributes = "\x1b[=c" diff --git a/vendor/github.com/charmbracelet/x/ansi/cursor.go b/vendor/github.com/charmbracelet/x/ansi/cursor.go deleted file mode 100644 index 0c364d608a..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/cursor.go +++ /dev/null @@ -1,633 +0,0 @@ -package ansi - -import "strconv" - -// SaveCursor (DECSC) is an escape sequence that saves the current cursor -// position. -// -// ESC 7 -// -// See: https://vt100.net/docs/vt510-rm/DECSC.html -const ( - SaveCursor = "\x1b7" - DECSC = SaveCursor -) - -// RestoreCursor (DECRC) is an escape sequence that restores the cursor -// position. -// -// ESC 8 -// -// See: https://vt100.net/docs/vt510-rm/DECRC.html -const ( - RestoreCursor = "\x1b8" - DECRC = RestoreCursor -) - -// RequestCursorPosition is an escape sequence that requests the current cursor -// position. -// -// CSI 6 n -// -// The terminal will report the cursor position as a CSI sequence in the -// following format: -// -// CSI Pl ; Pc R -// -// Where Pl is the line number and Pc is the column number. -// See: https://vt100.net/docs/vt510-rm/CPR.html -// -// Deprecated: use [RequestCursorPositionReport] instead. -const RequestCursorPosition = "\x1b[6n" - -// RequestExtendedCursorPosition (DECXCPR) is a sequence for requesting the -// cursor position report including the current page number. -// -// CSI ? 6 n -// -// The terminal will report the cursor position as a CSI sequence in the -// following format: -// -// CSI ? Pl ; Pc ; Pp R -// -// Where Pl is the line number, Pc is the column number, and Pp is the page -// number. -// See: https://vt100.net/docs/vt510-rm/DECXCPR.html -// -// Deprecated: use [RequestExtendedCursorPositionReport] instead. -const RequestExtendedCursorPosition = "\x1b[?6n" - -// CursorUp (CUU) returns a sequence for moving the cursor up n cells. -// -// CSI n A -// -// See: https://vt100.net/docs/vt510-rm/CUU.html -func CursorUp(n int) string { - var s string - if n > 1 { - s = strconv.Itoa(n) - } - return "\x1b[" + s + "A" -} - -// CUU is an alias for [CursorUp]. -func CUU(n int) string { - return CursorUp(n) -} - -// CUU1 is a sequence for moving the cursor up one cell. -const CUU1 = "\x1b[A" - -// CursorUp1 is a sequence for moving the cursor up one cell. -// -// This is equivalent to CursorUp(1). -// -// Deprecated: use [CUU1] instead. -const CursorUp1 = "\x1b[A" - -// CursorDown (CUD) returns a sequence for moving the cursor down n cells. -// -// CSI n B -// -// See: https://vt100.net/docs/vt510-rm/CUD.html -func CursorDown(n int) string { - var s string - if n > 1 { - s = strconv.Itoa(n) - } - return "\x1b[" + s + "B" -} - -// CUD is an alias for [CursorDown]. -func CUD(n int) string { - return CursorDown(n) -} - -// CUD1 is a sequence for moving the cursor down one cell. -const CUD1 = "\x1b[B" - -// CursorDown1 is a sequence for moving the cursor down one cell. -// -// This is equivalent to CursorDown(1). -// -// Deprecated: use [CUD1] instead. -const CursorDown1 = "\x1b[B" - -// CursorForward (CUF) returns a sequence for moving the cursor right n cells. -// -// # CSI n C -// -// See: https://vt100.net/docs/vt510-rm/CUF.html -func CursorForward(n int) string { - var s string - if n > 1 { - s = strconv.Itoa(n) - } - return "\x1b[" + s + "C" -} - -// CUF is an alias for [CursorForward]. -func CUF(n int) string { - return CursorForward(n) -} - -// CUF1 is a sequence for moving the cursor right one cell. -const CUF1 = "\x1b[C" - -// CursorRight (CUF) returns a sequence for moving the cursor right n cells. -// -// CSI n C -// -// See: https://vt100.net/docs/vt510-rm/CUF.html -// -// Deprecated: use [CursorForward] instead. -func CursorRight(n int) string { - return CursorForward(n) -} - -// CursorRight1 is a sequence for moving the cursor right one cell. -// -// This is equivalent to CursorRight(1). -// -// Deprecated: use [CUF1] instead. -const CursorRight1 = CUF1 - -// CursorBackward (CUB) returns a sequence for moving the cursor left n cells. -// -// # CSI n D -// -// See: https://vt100.net/docs/vt510-rm/CUB.html -func CursorBackward(n int) string { - var s string - if n > 1 { - s = strconv.Itoa(n) - } - return "\x1b[" + s + "D" -} - -// CUB is an alias for [CursorBackward]. -func CUB(n int) string { - return CursorBackward(n) -} - -// CUB1 is a sequence for moving the cursor left one cell. -const CUB1 = "\x1b[D" - -// CursorLeft (CUB) returns a sequence for moving the cursor left n cells. -// -// CSI n D -// -// See: https://vt100.net/docs/vt510-rm/CUB.html -// -// Deprecated: use [CursorBackward] instead. -func CursorLeft(n int) string { - return CursorBackward(n) -} - -// CursorLeft1 is a sequence for moving the cursor left one cell. -// -// This is equivalent to CursorLeft(1). -// -// Deprecated: use [CUB1] instead. -const CursorLeft1 = CUB1 - -// CursorNextLine (CNL) returns a sequence for moving the cursor to the -// beginning of the next line n times. -// -// CSI n E -// -// See: https://vt100.net/docs/vt510-rm/CNL.html -func CursorNextLine(n int) string { - var s string - if n > 1 { - s = strconv.Itoa(n) - } - return "\x1b[" + s + "E" -} - -// CNL is an alias for [CursorNextLine]. -func CNL(n int) string { - return CursorNextLine(n) -} - -// CursorPreviousLine (CPL) returns a sequence for moving the cursor to the -// beginning of the previous line n times. -// -// CSI n F -// -// See: https://vt100.net/docs/vt510-rm/CPL.html -func CursorPreviousLine(n int) string { - var s string - if n > 1 { - s = strconv.Itoa(n) - } - return "\x1b[" + s + "F" -} - -// CPL is an alias for [CursorPreviousLine]. -func CPL(n int) string { - return CursorPreviousLine(n) -} - -// CursorHorizontalAbsolute (CHA) returns a sequence for moving the cursor to -// the given column. -// -// Default is 1. -// -// CSI n G -// -// See: https://vt100.net/docs/vt510-rm/CHA.html -func CursorHorizontalAbsolute(col int) string { - var s string - if col > 0 { - s = strconv.Itoa(col) - } - return "\x1b[" + s + "G" -} - -// CHA is an alias for [CursorHorizontalAbsolute]. -func CHA(col int) string { - return CursorHorizontalAbsolute(col) -} - -// CursorPosition (CUP) returns a sequence for setting the cursor to the -// given row and column. -// -// Default is 1,1. -// -// CSI n ; m H -// -// See: https://vt100.net/docs/vt510-rm/CUP.html -func CursorPosition(col, row int) string { - if row <= 0 && col <= 0 { - return HomeCursorPosition - } - - var r, c string - if row > 0 { - r = strconv.Itoa(row) - } - if col > 0 { - c = strconv.Itoa(col) - } - return "\x1b[" + r + ";" + c + "H" -} - -// CUP is an alias for [CursorPosition]. -func CUP(col, row int) string { - return CursorPosition(col, row) -} - -// CursorHomePosition is a sequence for moving the cursor to the upper left -// corner of the scrolling region. This is equivalent to `CursorPosition(1, 1)`. -const CursorHomePosition = "\x1b[H" - -// SetCursorPosition (CUP) returns a sequence for setting the cursor to the -// given row and column. -// -// CSI n ; m H -// -// See: https://vt100.net/docs/vt510-rm/CUP.html -// -// Deprecated: use [CursorPosition] instead. -func SetCursorPosition(col, row int) string { - if row <= 0 && col <= 0 { - return HomeCursorPosition - } - - var r, c string - if row > 0 { - r = strconv.Itoa(row) - } - if col > 0 { - c = strconv.Itoa(col) - } - return "\x1b[" + r + ";" + c + "H" -} - -// HomeCursorPosition is a sequence for moving the cursor to the upper left -// corner of the scrolling region. This is equivalent to `SetCursorPosition(1, 1)`. -// -// Deprecated: use [CursorHomePosition] instead. -const HomeCursorPosition = CursorHomePosition - -// MoveCursor (CUP) returns a sequence for setting the cursor to the -// given row and column. -// -// CSI n ; m H -// -// See: https://vt100.net/docs/vt510-rm/CUP.html -// -// Deprecated: use [CursorPosition] instead. -func MoveCursor(col, row int) string { - return SetCursorPosition(col, row) -} - -// CursorOrigin is a sequence for moving the cursor to the upper left corner of -// the display. This is equivalent to `SetCursorPosition(1, 1)`. -// -// Deprecated: use [CursorHomePosition] instead. -const CursorOrigin = "\x1b[1;1H" - -// MoveCursorOrigin is a sequence for moving the cursor to the upper left -// corner of the display. This is equivalent to `SetCursorPosition(1, 1)`. -// -// Deprecated: use [CursorHomePosition] instead. -const MoveCursorOrigin = CursorOrigin - -// CursorHorizontalForwardTab (CHT) returns a sequence for moving the cursor to -// the next tab stop n times. -// -// Default is 1. -// -// CSI n I -// -// See: https://vt100.net/docs/vt510-rm/CHT.html -func CursorHorizontalForwardTab(n int) string { - var s string - if n > 1 { - s = strconv.Itoa(n) - } - return "\x1b[" + s + "I" -} - -// CHT is an alias for [CursorHorizontalForwardTab]. -func CHT(n int) string { - return CursorHorizontalForwardTab(n) -} - -// EraseCharacter (ECH) returns a sequence for erasing n characters and moving -// the cursor to the right. This doesn't affect other cell attributes. -// -// Default is 1. -// -// CSI n X -// -// See: https://vt100.net/docs/vt510-rm/ECH.html -func EraseCharacter(n int) string { - var s string - if n > 1 { - s = strconv.Itoa(n) - } - return "\x1b[" + s + "X" -} - -// ECH is an alias for [EraseCharacter]. -func ECH(n int) string { - return EraseCharacter(n) -} - -// CursorBackwardTab (CBT) returns a sequence for moving the cursor to the -// previous tab stop n times. -// -// Default is 1. -// -// CSI n Z -// -// See: https://vt100.net/docs/vt510-rm/CBT.html -func CursorBackwardTab(n int) string { - var s string - if n > 1 { - s = strconv.Itoa(n) - } - return "\x1b[" + s + "Z" -} - -// CBT is an alias for [CursorBackwardTab]. -func CBT(n int) string { - return CursorBackwardTab(n) -} - -// VerticalPositionAbsolute (VPA) returns a sequence for moving the cursor to -// the given row. -// -// Default is 1. -// -// CSI n d -// -// See: https://vt100.net/docs/vt510-rm/VPA.html -func VerticalPositionAbsolute(row int) string { - var s string - if row > 0 { - s = strconv.Itoa(row) - } - return "\x1b[" + s + "d" -} - -// VPA is an alias for [VerticalPositionAbsolute]. -func VPA(row int) string { - return VerticalPositionAbsolute(row) -} - -// VerticalPositionRelative (VPR) returns a sequence for moving the cursor down -// n rows relative to the current position. -// -// Default is 1. -// -// CSI n e -// -// See: https://vt100.net/docs/vt510-rm/VPR.html -func VerticalPositionRelative(n int) string { - var s string - if n > 1 { - s = strconv.Itoa(n) - } - return "\x1b[" + s + "e" -} - -// VPR is an alias for [VerticalPositionRelative]. -func VPR(n int) string { - return VerticalPositionRelative(n) -} - -// HorizontalVerticalPosition (HVP) returns a sequence for moving the cursor to -// the given row and column. -// -// Default is 1,1. -// -// CSI n ; m f -// -// This has the same effect as [CursorPosition]. -// -// See: https://vt100.net/docs/vt510-rm/HVP.html -func HorizontalVerticalPosition(col, row int) string { - var r, c string - if row > 0 { - r = strconv.Itoa(row) - } - if col > 0 { - c = strconv.Itoa(col) - } - return "\x1b[" + r + ";" + c + "f" -} - -// HVP is an alias for [HorizontalVerticalPosition]. -func HVP(col, row int) string { - return HorizontalVerticalPosition(col, row) -} - -// HorizontalVerticalHomePosition is a sequence for moving the cursor to the -// upper left corner of the scrolling region. This is equivalent to -// `HorizontalVerticalPosition(1, 1)`. -const HorizontalVerticalHomePosition = "\x1b[f" - -// SaveCurrentCursorPosition (SCOSC) is a sequence for saving the current cursor -// position for SCO console mode. -// -// CSI s -// -// This acts like [DECSC], except the page number where the cursor is located -// is not saved. -// -// See: https://vt100.net/docs/vt510-rm/SCOSC.html -const ( - SaveCurrentCursorPosition = "\x1b[s" - SCOSC = SaveCurrentCursorPosition -) - -// SaveCursorPosition (SCP or SCOSC) is a sequence for saving the cursor -// position. -// -// CSI s -// -// This acts like Save, except the page number where the cursor is located is -// not saved. -// -// See: https://vt100.net/docs/vt510-rm/SCOSC.html -// -// Deprecated: use [SaveCurrentCursorPosition] instead. -const SaveCursorPosition = "\x1b[s" - -// RestoreCurrentCursorPosition (SCORC) is a sequence for restoring the current -// cursor position for SCO console mode. -// -// CSI u -// -// This acts like [DECRC], except the page number where the cursor was saved is -// not restored. -// -// See: https://vt100.net/docs/vt510-rm/SCORC.html -const ( - RestoreCurrentCursorPosition = "\x1b[u" - SCORC = RestoreCurrentCursorPosition -) - -// RestoreCursorPosition (RCP or SCORC) is a sequence for restoring the cursor -// position. -// -// CSI u -// -// This acts like Restore, except the cursor stays on the same page where the -// cursor was saved. -// -// See: https://vt100.net/docs/vt510-rm/SCORC.html -// -// Deprecated: use [RestoreCurrentCursorPosition] instead. -const RestoreCursorPosition = "\x1b[u" - -// SetCursorStyle (DECSCUSR) returns a sequence for changing the cursor style. -// -// Default is 1. -// -// CSI Ps SP q -// -// Where Ps is the cursor style: -// -// 0: Blinking block -// 1: Blinking block (default) -// 2: Steady block -// 3: Blinking underline -// 4: Steady underline -// 5: Blinking bar (xterm) -// 6: Steady bar (xterm) -// -// See: https://vt100.net/docs/vt510-rm/DECSCUSR.html -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h4-Functions-using-CSI-_-ordered-by-the-final-character-lparen-s-rparen:CSI-Ps-SP-q.1D81 -func SetCursorStyle(style int) string { - if style < 0 { - style = 0 - } - return "\x1b[" + strconv.Itoa(style) + " q" -} - -// DECSCUSR is an alias for [SetCursorStyle]. -func DECSCUSR(style int) string { - return SetCursorStyle(style) -} - -// SetPointerShape returns a sequence for changing the mouse pointer cursor -// shape. Use "default" for the default pointer shape. -// -// OSC 22 ; Pt ST -// OSC 22 ; Pt BEL -// -// Where Pt is the pointer shape name. The name can be anything that the -// operating system can understand. Some common names are: -// -// - copy -// - crosshair -// - default -// - ew-resize -// - n-resize -// - text -// - wait -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Operating-System-Commands -func SetPointerShape(shape string) string { - return "\x1b]22;" + shape + "\x07" -} - -// ReverseIndex (RI) is an escape sequence for moving the cursor up one line in -// the same column. If the cursor is at the top margin, the screen scrolls -// down. -// -// This has the same effect as [RI]. -const ReverseIndex = "\x1bM" - -// HorizontalPositionAbsolute (HPA) returns a sequence for moving the cursor to -// the given column. This has the same effect as [CUP]. -// -// Default is 1. -// -// CSI n ` -// -// See: https://vt100.net/docs/vt510-rm/HPA.html -func HorizontalPositionAbsolute(col int) string { - var s string - if col > 0 { - s = strconv.Itoa(col) - } - return "\x1b[" + s + "`" -} - -// HPA is an alias for [HorizontalPositionAbsolute]. -func HPA(col int) string { - return HorizontalPositionAbsolute(col) -} - -// HorizontalPositionRelative (HPR) returns a sequence for moving the cursor -// right n columns relative to the current position. This has the same effect -// as [CUP]. -// -// Default is 1. -// -// CSI n a -// -// See: https://vt100.net/docs/vt510-rm/HPR.html -func HorizontalPositionRelative(n int) string { - var s string - if n > 0 { - s = strconv.Itoa(n) - } - return "\x1b[" + s + "a" -} - -// HPR is an alias for [HorizontalPositionRelative]. -func HPR(n int) string { - return HorizontalPositionRelative(n) -} - -// Index (IND) is an escape sequence for moving the cursor down one line in the -// same column. If the cursor is at the bottom margin, the screen scrolls up. -// This has the same effect as [IND]. -const Index = "\x1bD" diff --git a/vendor/github.com/charmbracelet/x/ansi/cwd.go b/vendor/github.com/charmbracelet/x/ansi/cwd.go deleted file mode 100644 index b03ac1bb99..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/cwd.go +++ /dev/null @@ -1,26 +0,0 @@ -package ansi - -import ( - "net/url" - "path" -) - -// NotifyWorkingDirectory returns a sequence that notifies the terminal -// of the current working directory. -// -// OSC 7 ; Pt BEL -// -// Where Pt is a URL in the format "file://[host]/[path]". -// Set host to "localhost" if this is a path on the local computer. -// -// See: https://wezfurlong.org/wezterm/shell-integration.html#osc-7-escape-sequence-to-set-the-working-directory -// See: https://iterm2.com/documentation-escape-codes.html#:~:text=RemoteHost%20and%20CurrentDir%3A-,OSC%207,-%3B%20%5BPs%5D%20ST -func NotifyWorkingDirectory(host string, paths ...string) string { - path := path.Join(paths...) - u := &url.URL{ - Scheme: "file", - Host: host, - Path: path, - } - return "\x1b]7;" + u.String() + "\x07" -} diff --git a/vendor/github.com/charmbracelet/x/ansi/doc.go b/vendor/github.com/charmbracelet/x/ansi/doc.go deleted file mode 100644 index e955e9f1b7..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/doc.go +++ /dev/null @@ -1,7 +0,0 @@ -// Package ansi defines common ANSI escape sequences based on the ECMA-48 -// specs. -// -// All sequences use 7-bit C1 control codes, which are supported by most -// terminal emulators. OSC sequences are terminated by a BEL for wider -// compatibility with terminals. -package ansi diff --git a/vendor/github.com/charmbracelet/x/ansi/focus.go b/vendor/github.com/charmbracelet/x/ansi/focus.go deleted file mode 100644 index 4e0207cebb..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/focus.go +++ /dev/null @@ -1,9 +0,0 @@ -package ansi - -// Focus is an escape sequence to notify the terminal that it has focus. -// This is used with [FocusEventMode]. -const Focus = "\x1b[I" - -// Blur is an escape sequence to notify the terminal that it has lost focus. -// This is used with [FocusEventMode]. -const Blur = "\x1b[O" diff --git a/vendor/github.com/charmbracelet/x/ansi/graphics.go b/vendor/github.com/charmbracelet/x/ansi/graphics.go deleted file mode 100644 index 604fef47cf..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/graphics.go +++ /dev/null @@ -1,199 +0,0 @@ -package ansi - -import ( - "bytes" - "encoding/base64" - "errors" - "fmt" - "image" - "io" - "os" - "strings" - - "github.com/charmbracelet/x/ansi/kitty" -) - -// KittyGraphics returns a sequence that encodes the given image in the Kitty -// graphics protocol. -// -// APC G [comma separated options] ; [base64 encoded payload] ST -// -// See https://sw.kovidgoyal.net/kitty/graphics-protocol/ -func KittyGraphics(payload []byte, opts ...string) string { - var buf bytes.Buffer - buf.WriteString("\x1b_G") - buf.WriteString(strings.Join(opts, ",")) - if len(payload) > 0 { - buf.WriteString(";") - buf.Write(payload) - } - buf.WriteString("\x1b\\") - return buf.String() -} - -var ( - // KittyGraphicsTempDir is the directory where temporary files are stored. - // This is used in [WriteKittyGraphics] along with [os.CreateTemp]. - KittyGraphicsTempDir = "" - - // KittyGraphicsTempPattern is the pattern used to create temporary files. - // This is used in [WriteKittyGraphics] along with [os.CreateTemp]. - // The Kitty Graphics protocol requires the file path to contain the - // substring "tty-graphics-protocol". - KittyGraphicsTempPattern = "tty-graphics-protocol-*" -) - -// WriteKittyGraphics writes an image using the Kitty Graphics protocol with -// the given options to w. It chunks the written data if o.Chunk is true. -// -// You can omit m and use nil when rendering an image from a file. In this -// case, you must provide a file path in o.File and use o.Transmission = -// [kitty.File]. You can also use o.Transmission = [kitty.TempFile] to write -// the image to a temporary file. In that case, the file path is ignored, and -// the image is written to a temporary file that is automatically deleted by -// the terminal. -// -// See https://sw.kovidgoyal.net/kitty/graphics-protocol/ -func WriteKittyGraphics(w io.Writer, m image.Image, o *kitty.Options) error { - if o == nil { - o = &kitty.Options{} - } - - if o.Transmission == 0 && len(o.File) != 0 { - o.Transmission = kitty.File - } - - var data bytes.Buffer // the data to be encoded into base64 - e := &kitty.Encoder{ - Compress: o.Compression == kitty.Zlib, - Format: o.Format, - } - - switch o.Transmission { - case kitty.Direct: - if err := e.Encode(&data, m); err != nil { - return fmt.Errorf("failed to encode direct image: %w", err) - } - - case kitty.SharedMemory: - // TODO: Implement shared memory - return fmt.Errorf("shared memory transmission is not yet implemented") - - case kitty.File: - if len(o.File) == 0 { - return kitty.ErrMissingFile - } - - f, err := os.Open(o.File) - if err != nil { - return fmt.Errorf("failed to open file: %w", err) - } - - defer f.Close() //nolint:errcheck - - stat, err := f.Stat() - if err != nil { - return fmt.Errorf("failed to get file info: %w", err) - } - - mode := stat.Mode() - if !mode.IsRegular() { - return fmt.Errorf("file is not a regular file") - } - - // Write the file path to the buffer - if _, err := data.WriteString(f.Name()); err != nil { - return fmt.Errorf("failed to write file path to buffer: %w", err) - } - - case kitty.TempFile: - f, err := os.CreateTemp(KittyGraphicsTempDir, KittyGraphicsTempPattern) - if err != nil { - return fmt.Errorf("failed to create file: %w", err) - } - - defer f.Close() //nolint:errcheck - - if err := e.Encode(f, m); err != nil { - return fmt.Errorf("failed to encode image to file: %w", err) - } - - // Write the file path to the buffer - if _, err := data.WriteString(f.Name()); err != nil { - return fmt.Errorf("failed to write file path to buffer: %w", err) - } - } - - // Encode image to base64 - var payload bytes.Buffer // the base64 encoded image to be written to w - b64 := base64.NewEncoder(base64.StdEncoding, &payload) - if _, err := data.WriteTo(b64); err != nil { - return fmt.Errorf("failed to write base64 encoded image to payload: %w", err) - } - if err := b64.Close(); err != nil { - return err - } - - // If not chunking, write all at once - if !o.Chunk { - _, err := io.WriteString(w, KittyGraphics(payload.Bytes(), o.Options()...)) - return err - } - - // Write in chunks - var ( - err error - n int - ) - chunk := make([]byte, kitty.MaxChunkSize) - isFirstChunk := true - - for { - // Stop if we read less than the chunk size [kitty.MaxChunkSize]. - n, err = io.ReadFull(&payload, chunk) - if errors.Is(err, io.ErrUnexpectedEOF) || errors.Is(err, io.EOF) { - break - } - if err != nil { - return fmt.Errorf("failed to read chunk: %w", err) - } - - opts := buildChunkOptions(o, isFirstChunk, false) - if _, err := io.WriteString(w, KittyGraphics(chunk[:n], opts...)); err != nil { - return err - } - - isFirstChunk = false - } - - // Write the last chunk - opts := buildChunkOptions(o, isFirstChunk, true) - _, err = io.WriteString(w, KittyGraphics(chunk[:n], opts...)) - return err -} - -// buildChunkOptions creates the options slice for a chunk -func buildChunkOptions(o *kitty.Options, isFirstChunk, isLastChunk bool) []string { - var opts []string - if isFirstChunk { - opts = o.Options() - } else { - // These options are allowed in subsequent chunks - if o.Quite > 0 { - opts = append(opts, fmt.Sprintf("q=%d", o.Quite)) - } - if o.Action == kitty.Frame { - opts = append(opts, "a=f") - } - } - - if !isFirstChunk || !isLastChunk { - // We don't need to encode the (m=) option when we only have one chunk. - if isLastChunk { - opts = append(opts, "m=0") - } else { - opts = append(opts, "m=1") - } - } - return opts -} diff --git a/vendor/github.com/charmbracelet/x/ansi/hyperlink.go b/vendor/github.com/charmbracelet/x/ansi/hyperlink.go deleted file mode 100644 index 323bfe932a..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/hyperlink.go +++ /dev/null @@ -1,28 +0,0 @@ -package ansi - -import "strings" - -// SetHyperlink returns a sequence for starting a hyperlink. -// -// OSC 8 ; Params ; Uri ST -// OSC 8 ; Params ; Uri BEL -// -// To reset the hyperlink, omit the URI. -// -// See: https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda -func SetHyperlink(uri string, params ...string) string { - var p string - if len(params) > 0 { - p = strings.Join(params, ":") - } - return "\x1b]8;" + p + ";" + uri + "\x07" -} - -// ResetHyperlink returns a sequence for resetting the hyperlink. -// -// This is equivalent to SetHyperlink("", params...). -// -// See: https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda -func ResetHyperlink(params ...string) string { - return SetHyperlink("", params...) -} diff --git a/vendor/github.com/charmbracelet/x/ansi/iterm2.go b/vendor/github.com/charmbracelet/x/ansi/iterm2.go deleted file mode 100644 index 0ecb336da1..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/iterm2.go +++ /dev/null @@ -1,18 +0,0 @@ -package ansi - -import "fmt" - -// ITerm2 returns a sequence that uses the iTerm2 proprietary protocol. Use the -// iterm2 package for a more convenient API. -// -// OSC 1337 ; key = value ST -// -// Example: -// -// ITerm2(iterm2.File{...}) -// -// See https://iterm2.com/documentation-escape-codes.html -// See https://iterm2.com/documentation-images.html -func ITerm2(data any) string { - return "\x1b]1337;" + fmt.Sprint(data) + "\x07" -} diff --git a/vendor/github.com/charmbracelet/x/ansi/keypad.go b/vendor/github.com/charmbracelet/x/ansi/keypad.go deleted file mode 100644 index 9183c6a7ec..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/keypad.go +++ /dev/null @@ -1,28 +0,0 @@ -package ansi - -// Keypad Application Mode (DECKPAM) is a mode that determines whether the -// keypad sends application sequences or ANSI sequences. -// -// This works like enabling [DECNKM]. -// Use [NumericKeypadMode] to set the numeric keypad mode. -// -// ESC = -// -// See: https://vt100.net/docs/vt510-rm/DECKPAM.html -const ( - KeypadApplicationMode = "\x1b=" - DECKPAM = KeypadApplicationMode -) - -// Keypad Numeric Mode (DECKPNM) is a mode that determines whether the keypad -// sends application sequences or ANSI sequences. -// -// This works the same as disabling [DECNKM]. -// -// ESC > -// -// See: https://vt100.net/docs/vt510-rm/DECKPNM.html -const ( - KeypadNumericMode = "\x1b>" - DECKPNM = KeypadNumericMode -) diff --git a/vendor/github.com/charmbracelet/x/ansi/kitty.go b/vendor/github.com/charmbracelet/x/ansi/kitty.go deleted file mode 100644 index 124ab839e2..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/kitty.go +++ /dev/null @@ -1,90 +0,0 @@ -package ansi - -import "strconv" - -// Kitty keyboard protocol progressive enhancement flags. -// See: https://sw.kovidgoyal.net/kitty/keyboard-protocol/#progressive-enhancement -const ( - KittyDisambiguateEscapeCodes = 1 << iota - KittyReportEventTypes - KittyReportAlternateKeys - KittyReportAllKeysAsEscapeCodes - KittyReportAssociatedKeys - - KittyAllFlags = KittyDisambiguateEscapeCodes | KittyReportEventTypes | - KittyReportAlternateKeys | KittyReportAllKeysAsEscapeCodes | KittyReportAssociatedKeys -) - -// RequestKittyKeyboard is a sequence to request the terminal Kitty keyboard -// protocol enabled flags. -// -// See: https://sw.kovidgoyal.net/kitty/keyboard-protocol/ -const RequestKittyKeyboard = "\x1b[?u" - -// KittyKeyboard returns a sequence to request keyboard enhancements from the terminal. -// The flags argument is a bitmask of the Kitty keyboard protocol flags. While -// mode specifies how the flags should be interpreted. -// -// Possible values for flags mask: -// -// 1: Disambiguate escape codes -// 2: Report event types -// 4: Report alternate keys -// 8: Report all keys as escape codes -// 16: Report associated text -// -// Possible values for mode: -// -// 1: Set given flags and unset all others -// 2: Set given flags and keep existing flags unchanged -// 3: Unset given flags and keep existing flags unchanged -// -// See https://sw.kovidgoyal.net/kitty/keyboard-protocol/#progressive-enhancement -func KittyKeyboard(flags, mode int) string { - return "\x1b[=" + strconv.Itoa(flags) + ";" + strconv.Itoa(mode) + "u" -} - -// PushKittyKeyboard returns a sequence to push the given flags to the terminal -// Kitty Keyboard stack. -// -// Possible values for flags mask: -// -// 0: Disable all features -// 1: Disambiguate escape codes -// 2: Report event types -// 4: Report alternate keys -// 8: Report all keys as escape codes -// 16: Report associated text -// -// CSI > flags u -// -// See https://sw.kovidgoyal.net/kitty/keyboard-protocol/#progressive-enhancement -func PushKittyKeyboard(flags int) string { - var f string - if flags > 0 { - f = strconv.Itoa(flags) - } - - return "\x1b[>" + f + "u" -} - -// DisableKittyKeyboard is a sequence to push zero into the terminal Kitty -// Keyboard stack to disable the protocol. -// -// This is equivalent to PushKittyKeyboard(0). -const DisableKittyKeyboard = "\x1b[>u" - -// PopKittyKeyboard returns a sequence to pop n number of flags from the -// terminal Kitty Keyboard stack. -// -// CSI < flags u -// -// See https://sw.kovidgoyal.net/kitty/keyboard-protocol/#progressive-enhancement -func PopKittyKeyboard(n int) string { - var num string - if n > 0 { - num = strconv.Itoa(n) - } - - return "\x1b[<" + num + "u" -} diff --git a/vendor/github.com/charmbracelet/x/ansi/kitty/decoder.go b/vendor/github.com/charmbracelet/x/ansi/kitty/decoder.go deleted file mode 100644 index fbd08441f4..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/kitty/decoder.go +++ /dev/null @@ -1,85 +0,0 @@ -package kitty - -import ( - "compress/zlib" - "fmt" - "image" - "image/color" - "image/png" - "io" -) - -// Decoder is a decoder for the Kitty graphics protocol. It supports decoding -// images in the 24-bit [RGB], 32-bit [RGBA], and [PNG] formats. It can also -// decompress data using zlib. -// The default format is 32-bit [RGBA]. -type Decoder struct { - // Uses zlib decompression. - Decompress bool - - // Can be one of [RGB], [RGBA], or [PNG]. - Format int - - // Width of the image in pixels. This can be omitted if the image is [PNG] - // formatted. - Width int - - // Height of the image in pixels. This can be omitted if the image is [PNG] - // formatted. - Height int -} - -// Decode decodes the image data from r in the specified format. -func (d *Decoder) Decode(r io.Reader) (image.Image, error) { - if d.Decompress { - zr, err := zlib.NewReader(r) - if err != nil { - return nil, fmt.Errorf("failed to create zlib reader: %w", err) - } - - defer zr.Close() //nolint:errcheck - r = zr - } - - if d.Format == 0 { - d.Format = RGBA - } - - switch d.Format { - case RGBA, RGB: - return d.decodeRGBA(r, d.Format == RGBA) - - case PNG: - return png.Decode(r) - - default: - return nil, fmt.Errorf("unsupported format: %d", d.Format) - } -} - -// decodeRGBA decodes the image data in 32-bit RGBA or 24-bit RGB formats. -func (d *Decoder) decodeRGBA(r io.Reader, alpha bool) (image.Image, error) { - m := image.NewRGBA(image.Rect(0, 0, d.Width, d.Height)) - - var buf []byte - if alpha { - buf = make([]byte, 4) - } else { - buf = make([]byte, 3) - } - - for y := 0; y < d.Height; y++ { - for x := 0; x < d.Width; x++ { - if _, err := io.ReadFull(r, buf[:]); err != nil { - return nil, fmt.Errorf("failed to read pixel data: %w", err) - } - if alpha { - m.SetRGBA(x, y, color.RGBA{buf[0], buf[1], buf[2], buf[3]}) - } else { - m.SetRGBA(x, y, color.RGBA{buf[0], buf[1], buf[2], 0xff}) - } - } - } - - return m, nil -} diff --git a/vendor/github.com/charmbracelet/x/ansi/kitty/encoder.go b/vendor/github.com/charmbracelet/x/ansi/kitty/encoder.go deleted file mode 100644 index f668b9e310..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/kitty/encoder.go +++ /dev/null @@ -1,64 +0,0 @@ -package kitty - -import ( - "compress/zlib" - "fmt" - "image" - "image/png" - "io" -) - -// Encoder is an encoder for the Kitty graphics protocol. It supports encoding -// images in the 24-bit [RGB], 32-bit [RGBA], and [PNG] formats, and -// compressing the data using zlib. -// The default format is 32-bit [RGBA]. -type Encoder struct { - // Uses zlib compression. - Compress bool - - // Can be one of [RGBA], [RGB], or [PNG]. - Format int -} - -// Encode encodes the image data in the specified format and writes it to w. -func (e *Encoder) Encode(w io.Writer, m image.Image) error { - if m == nil { - return nil - } - - if e.Compress { - zw := zlib.NewWriter(w) - defer zw.Close() //nolint:errcheck - w = zw - } - - if e.Format == 0 { - e.Format = RGBA - } - - switch e.Format { - case RGBA, RGB: - bounds := m.Bounds() - for y := bounds.Min.Y; y < bounds.Max.Y; y++ { - for x := bounds.Min.X; x < bounds.Max.X; x++ { - r, g, b, a := m.At(x, y).RGBA() - switch e.Format { - case RGBA: - w.Write([]byte{byte(r >> 8), byte(g >> 8), byte(b >> 8), byte(a >> 8)}) //nolint:errcheck - case RGB: - w.Write([]byte{byte(r >> 8), byte(g >> 8), byte(b >> 8)}) //nolint:errcheck - } - } - } - - case PNG: - if err := png.Encode(w, m); err != nil { - return fmt.Errorf("failed to encode PNG: %w", err) - } - - default: - return fmt.Errorf("unsupported format: %d", e.Format) - } - - return nil -} diff --git a/vendor/github.com/charmbracelet/x/ansi/kitty/graphics.go b/vendor/github.com/charmbracelet/x/ansi/kitty/graphics.go deleted file mode 100644 index 490e7a8a35..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/kitty/graphics.go +++ /dev/null @@ -1,414 +0,0 @@ -package kitty - -import "errors" - -// ErrMissingFile is returned when the file path is missing. -var ErrMissingFile = errors.New("missing file path") - -// MaxChunkSize is the maximum chunk size for the image data. -const MaxChunkSize = 1024 * 4 - -// Placeholder is a special Unicode character that can be used as a placeholder -// for an image. -const Placeholder = '\U0010EEEE' - -// Graphics image format. -const ( - // 32-bit RGBA format. - RGBA = 32 - - // 24-bit RGB format. - RGB = 24 - - // PNG format. - PNG = 100 -) - -// Compression types. -const ( - Zlib = 'z' -) - -// Transmission types. -const ( - // The data transmitted directly in the escape sequence. - Direct = 'd' - - // The data transmitted in a regular file. - File = 'f' - - // A temporary file is used and deleted after transmission. - TempFile = 't' - - // A shared memory object. - // For POSIX see https://pubs.opengroup.org/onlinepubs/9699919799/functions/shm_open.html - // For Windows see https://docs.microsoft.com/en-us/windows/win32/memory/creating-named-shared-memory - SharedMemory = 's' -) - -// Action types. -const ( - // Transmit image data. - Transmit = 't' - // TransmitAndPut transmit image data and display (put) it. - TransmitAndPut = 'T' - // Query terminal for image info. - Query = 'q' - // Put (display) previously transmitted image. - Put = 'p' - // Delete image. - Delete = 'd' - // Frame transmits data for animation frames. - Frame = 'f' - // Animate controls animation. - Animate = 'a' - // Compose composes animation frames. - Compose = 'c' -) - -// Delete types. -const ( - // Delete all placements visible on screen - DeleteAll = 'a' - // Delete all images with the specified id, specified using the i key. If - // you specify a p key for the placement id as well, then only the - // placement with the specified image id and placement id will be deleted. - DeleteID = 'i' - // Delete newest image with the specified number, specified using the I - // key. If you specify a p key for the placement id as well, then only the - // placement with the specified number and placement id will be deleted. - DeleteNumber = 'n' - // Delete all placements that intersect with the current cursor position. - DeleteCursor = 'c' - // Delete animation frames. - DeleteFrames = 'f' - // Delete all placements that intersect a specific cell, the cell is - // specified using the x and y keys - DeleteCell = 'p' - // Delete all placements that intersect a specific cell having a specific - // z-index. The cell and z-index is specified using the x, y and z keys. - DeleteCellZ = 'q' - // Delete all images whose id is greater than or equal to the value of the x - // key and less than or equal to the value of the y. - DeleteRange = 'r' - // Delete all placements that intersect the specified column, specified using - // the x key. - DeleteColumn = 'x' - // Delete all placements that intersect the specified row, specified using - // the y key. - DeleteRow = 'y' - // Delete all placements that have the specified z-index, specified using the - // z key. - DeleteZ = 'z' -) - -// Diacritic returns the diacritic rune at the specified index. If the index is -// out of bounds, the first diacritic rune is returned. -func Diacritic(i int) rune { - if i < 0 || i >= len(diacritics) { - return diacritics[0] - } - return diacritics[i] -} - -// From https://sw.kovidgoyal.net/kitty/_downloads/f0a0de9ec8d9ff4456206db8e0814937/rowcolumn-diacritics.txt -// See https://sw.kovidgoyal.net/kitty/graphics-protocol/#unicode-placeholders for further explanation. -var diacritics = []rune{ - '\u0305', - '\u030D', - '\u030E', - '\u0310', - '\u0312', - '\u033D', - '\u033E', - '\u033F', - '\u0346', - '\u034A', - '\u034B', - '\u034C', - '\u0350', - '\u0351', - '\u0352', - '\u0357', - '\u035B', - '\u0363', - '\u0364', - '\u0365', - '\u0366', - '\u0367', - '\u0368', - '\u0369', - '\u036A', - '\u036B', - '\u036C', - '\u036D', - '\u036E', - '\u036F', - '\u0483', - '\u0484', - '\u0485', - '\u0486', - '\u0487', - '\u0592', - '\u0593', - '\u0594', - '\u0595', - '\u0597', - '\u0598', - '\u0599', - '\u059C', - '\u059D', - '\u059E', - '\u059F', - '\u05A0', - '\u05A1', - '\u05A8', - '\u05A9', - '\u05AB', - '\u05AC', - '\u05AF', - '\u05C4', - '\u0610', - '\u0611', - '\u0612', - '\u0613', - '\u0614', - '\u0615', - '\u0616', - '\u0617', - '\u0657', - '\u0658', - '\u0659', - '\u065A', - '\u065B', - '\u065D', - '\u065E', - '\u06D6', - '\u06D7', - '\u06D8', - '\u06D9', - '\u06DA', - '\u06DB', - '\u06DC', - '\u06DF', - '\u06E0', - '\u06E1', - '\u06E2', - '\u06E4', - '\u06E7', - '\u06E8', - '\u06EB', - '\u06EC', - '\u0730', - '\u0732', - '\u0733', - '\u0735', - '\u0736', - '\u073A', - '\u073D', - '\u073F', - '\u0740', - '\u0741', - '\u0743', - '\u0745', - '\u0747', - '\u0749', - '\u074A', - '\u07EB', - '\u07EC', - '\u07ED', - '\u07EE', - '\u07EF', - '\u07F0', - '\u07F1', - '\u07F3', - '\u0816', - '\u0817', - '\u0818', - '\u0819', - '\u081B', - '\u081C', - '\u081D', - '\u081E', - '\u081F', - '\u0820', - '\u0821', - '\u0822', - '\u0823', - '\u0825', - '\u0826', - '\u0827', - '\u0829', - '\u082A', - '\u082B', - '\u082C', - '\u082D', - '\u0951', - '\u0953', - '\u0954', - '\u0F82', - '\u0F83', - '\u0F86', - '\u0F87', - '\u135D', - '\u135E', - '\u135F', - '\u17DD', - '\u193A', - '\u1A17', - '\u1A75', - '\u1A76', - '\u1A77', - '\u1A78', - '\u1A79', - '\u1A7A', - '\u1A7B', - '\u1A7C', - '\u1B6B', - '\u1B6D', - '\u1B6E', - '\u1B6F', - '\u1B70', - '\u1B71', - '\u1B72', - '\u1B73', - '\u1CD0', - '\u1CD1', - '\u1CD2', - '\u1CDA', - '\u1CDB', - '\u1CE0', - '\u1DC0', - '\u1DC1', - '\u1DC3', - '\u1DC4', - '\u1DC5', - '\u1DC6', - '\u1DC7', - '\u1DC8', - '\u1DC9', - '\u1DCB', - '\u1DCC', - '\u1DD1', - '\u1DD2', - '\u1DD3', - '\u1DD4', - '\u1DD5', - '\u1DD6', - '\u1DD7', - '\u1DD8', - '\u1DD9', - '\u1DDA', - '\u1DDB', - '\u1DDC', - '\u1DDD', - '\u1DDE', - '\u1DDF', - '\u1DE0', - '\u1DE1', - '\u1DE2', - '\u1DE3', - '\u1DE4', - '\u1DE5', - '\u1DE6', - '\u1DFE', - '\u20D0', - '\u20D1', - '\u20D4', - '\u20D5', - '\u20D6', - '\u20D7', - '\u20DB', - '\u20DC', - '\u20E1', - '\u20E7', - '\u20E9', - '\u20F0', - '\u2CEF', - '\u2CF0', - '\u2CF1', - '\u2DE0', - '\u2DE1', - '\u2DE2', - '\u2DE3', - '\u2DE4', - '\u2DE5', - '\u2DE6', - '\u2DE7', - '\u2DE8', - '\u2DE9', - '\u2DEA', - '\u2DEB', - '\u2DEC', - '\u2DED', - '\u2DEE', - '\u2DEF', - '\u2DF0', - '\u2DF1', - '\u2DF2', - '\u2DF3', - '\u2DF4', - '\u2DF5', - '\u2DF6', - '\u2DF7', - '\u2DF8', - '\u2DF9', - '\u2DFA', - '\u2DFB', - '\u2DFC', - '\u2DFD', - '\u2DFE', - '\u2DFF', - '\uA66F', - '\uA67C', - '\uA67D', - '\uA6F0', - '\uA6F1', - '\uA8E0', - '\uA8E1', - '\uA8E2', - '\uA8E3', - '\uA8E4', - '\uA8E5', - '\uA8E6', - '\uA8E7', - '\uA8E8', - '\uA8E9', - '\uA8EA', - '\uA8EB', - '\uA8EC', - '\uA8ED', - '\uA8EE', - '\uA8EF', - '\uA8F0', - '\uA8F1', - '\uAAB0', - '\uAAB2', - '\uAAB3', - '\uAAB7', - '\uAAB8', - '\uAABE', - '\uAABF', - '\uAAC1', - '\uFE20', - '\uFE21', - '\uFE22', - '\uFE23', - '\uFE24', - '\uFE25', - '\uFE26', - '\U00010A0F', - '\U00010A38', - '\U0001D185', - '\U0001D186', - '\U0001D187', - '\U0001D188', - '\U0001D189', - '\U0001D1AA', - '\U0001D1AB', - '\U0001D1AC', - '\U0001D1AD', - '\U0001D242', - '\U0001D243', - '\U0001D244', -} diff --git a/vendor/github.com/charmbracelet/x/ansi/kitty/options.go b/vendor/github.com/charmbracelet/x/ansi/kitty/options.go deleted file mode 100644 index a8d907bdd2..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/kitty/options.go +++ /dev/null @@ -1,367 +0,0 @@ -package kitty - -import ( - "encoding" - "fmt" - "strconv" - "strings" -) - -var ( - _ encoding.TextMarshaler = Options{} - _ encoding.TextUnmarshaler = &Options{} -) - -// Options represents a Kitty Graphics Protocol options. -type Options struct { - // Common options. - - // Action (a=t) is the action to be performed on the image. Can be one of - // [Transmit], [TransmitDisplay], [Query], [Put], [Delete], [Frame], - // [Animate], [Compose]. - Action byte - - // Quite mode (q=0) is the quiet mode. Can be either zero, one, or two - // where zero is the default, 1 suppresses OK responses, and 2 suppresses - // both OK and error responses. - Quite byte - - // Transmission options. - - // ID (i=) is the image ID. The ID is a unique identifier for the image. - // Must be a positive integer up to [math.MaxUint32]. - ID int - - // PlacementID (p=) is the placement ID. The placement ID is a unique - // identifier for the placement of the image. Must be a positive integer up - // to [math.MaxUint32]. - PlacementID int - - // Number (I=0) is the number of images to be transmitted. - Number int - - // Format (f=32) is the image format. One of [RGBA], [RGB], [PNG]. - Format int - - // ImageWidth (s=0) is the transmitted image width. - ImageWidth int - - // ImageHeight (v=0) is the transmitted image height. - ImageHeight int - - // Compression (o=) is the image compression type. Can be [Zlib] or zero. - Compression byte - - // Transmission (t=d) is the image transmission type. Can be [Direct], [File], - // [TempFile], or[SharedMemory]. - Transmission byte - - // File is the file path to be used when the transmission type is [File]. - // If [Options.Transmission] is omitted i.e. zero and this is non-empty, - // the transmission type is set to [File]. - File string - - // Size (S=0) is the size to be read from the transmission medium. - Size int - - // Offset (O=0) is the offset byte to start reading from the transmission - // medium. - Offset int - - // Chunk (m=) whether the image is transmitted in chunks. Can be either - // zero or one. When true, the image is transmitted in chunks. Each chunk - // must be a multiple of 4, and up to [MaxChunkSize] bytes. Each chunk must - // have the m=1 option except for the last chunk which must have m=0. - Chunk bool - - // Display options. - - // X (x=0) is the pixel X coordinate of the image to start displaying. - X int - - // Y (y=0) is the pixel Y coordinate of the image to start displaying. - Y int - - // Z (z=0) is the Z coordinate of the image to display. - Z int - - // Width (w=0) is the width of the image to display. - Width int - - // Height (h=0) is the height of the image to display. - Height int - - // OffsetX (X=0) is the OffsetX coordinate of the cursor cell to start - // displaying the image. OffsetX=0 is the leftmost cell. This must be - // smaller than the terminal cell width. - OffsetX int - - // OffsetY (Y=0) is the OffsetY coordinate of the cursor cell to start - // displaying the image. OffsetY=0 is the topmost cell. This must be - // smaller than the terminal cell height. - OffsetY int - - // Columns (c=0) is the number of columns to display the image. The image - // will be scaled to fit the number of columns. - Columns int - - // Rows (r=0) is the number of rows to display the image. The image will be - // scaled to fit the number of rows. - Rows int - - // VirtualPlacement (U=0) whether to use virtual placement. This is used - // with Unicode [Placeholder] to display images. - VirtualPlacement bool - - // DoNotMoveCursor (C=0) whether to move the cursor after displaying the - // image. - DoNotMoveCursor bool - - // ParentID (P=0) is the parent image ID. The parent ID is the ID of the - // image that is the parent of the current image. This is used with Unicode - // [Placeholder] to display images relative to the parent image. - ParentID int - - // ParentPlacementID (Q=0) is the parent placement ID. The parent placement - // ID is the ID of the placement of the parent image. This is used with - // Unicode [Placeholder] to display images relative to the parent image. - ParentPlacementID int - - // Delete options. - - // Delete (d=a) is the delete action. Can be one of [DeleteAll], - // [DeleteID], [DeleteNumber], [DeleteCursor], [DeleteFrames], - // [DeleteCell], [DeleteCellZ], [DeleteRange], [DeleteColumn], [DeleteRow], - // [DeleteZ]. - Delete byte - - // DeleteResources indicates whether to delete the resources associated - // with the image. - DeleteResources bool -} - -// Options returns the options as a slice of a key-value pairs. -func (o *Options) Options() (opts []string) { - opts = []string{} - if o.Format == 0 { - o.Format = RGBA - } - - if o.Action == 0 { - o.Action = Transmit - } - - if o.Delete == 0 { - o.Delete = DeleteAll - } - - if o.Transmission == 0 { - if len(o.File) > 0 { - o.Transmission = File - } else { - o.Transmission = Direct - } - } - - if o.Format != RGBA { - opts = append(opts, fmt.Sprintf("f=%d", o.Format)) - } - - if o.Quite > 0 { - opts = append(opts, fmt.Sprintf("q=%d", o.Quite)) - } - - if o.ID > 0 { - opts = append(opts, fmt.Sprintf("i=%d", o.ID)) - } - - if o.PlacementID > 0 { - opts = append(opts, fmt.Sprintf("p=%d", o.PlacementID)) - } - - if o.Number > 0 { - opts = append(opts, fmt.Sprintf("I=%d", o.Number)) - } - - if o.ImageWidth > 0 { - opts = append(opts, fmt.Sprintf("s=%d", o.ImageWidth)) - } - - if o.ImageHeight > 0 { - opts = append(opts, fmt.Sprintf("v=%d", o.ImageHeight)) - } - - if o.Transmission != Direct { - opts = append(opts, fmt.Sprintf("t=%c", o.Transmission)) - } - - if o.Size > 0 { - opts = append(opts, fmt.Sprintf("S=%d", o.Size)) - } - - if o.Offset > 0 { - opts = append(opts, fmt.Sprintf("O=%d", o.Offset)) - } - - if o.Compression == Zlib { - opts = append(opts, fmt.Sprintf("o=%c", o.Compression)) - } - - if o.VirtualPlacement { - opts = append(opts, "U=1") - } - - if o.DoNotMoveCursor { - opts = append(opts, "C=1") - } - - if o.ParentID > 0 { - opts = append(opts, fmt.Sprintf("P=%d", o.ParentID)) - } - - if o.ParentPlacementID > 0 { - opts = append(opts, fmt.Sprintf("Q=%d", o.ParentPlacementID)) - } - - if o.X > 0 { - opts = append(opts, fmt.Sprintf("x=%d", o.X)) - } - - if o.Y > 0 { - opts = append(opts, fmt.Sprintf("y=%d", o.Y)) - } - - if o.Z > 0 { - opts = append(opts, fmt.Sprintf("z=%d", o.Z)) - } - - if o.Width > 0 { - opts = append(opts, fmt.Sprintf("w=%d", o.Width)) - } - - if o.Height > 0 { - opts = append(opts, fmt.Sprintf("h=%d", o.Height)) - } - - if o.OffsetX > 0 { - opts = append(opts, fmt.Sprintf("X=%d", o.OffsetX)) - } - - if o.OffsetY > 0 { - opts = append(opts, fmt.Sprintf("Y=%d", o.OffsetY)) - } - - if o.Columns > 0 { - opts = append(opts, fmt.Sprintf("c=%d", o.Columns)) - } - - if o.Rows > 0 { - opts = append(opts, fmt.Sprintf("r=%d", o.Rows)) - } - - if o.Delete != DeleteAll || o.DeleteResources { - da := o.Delete - if o.DeleteResources { - da = da - ' ' // to uppercase - } - - opts = append(opts, fmt.Sprintf("d=%c", da)) - } - - if o.Action != Transmit { - opts = append(opts, fmt.Sprintf("a=%c", o.Action)) - } - - return -} - -// String returns the string representation of the options. -func (o Options) String() string { - return strings.Join(o.Options(), ",") -} - -// MarshalText returns the string representation of the options. -func (o Options) MarshalText() ([]byte, error) { - return []byte(o.String()), nil -} - -// UnmarshalText parses the options from the given string. -func (o *Options) UnmarshalText(text []byte) error { - opts := strings.Split(string(text), ",") - for _, opt := range opts { - ps := strings.SplitN(opt, "=", 2) - if len(ps) != 2 || len(ps[1]) == 0 { - continue - } - - switch ps[0] { - case "a": - o.Action = ps[1][0] - case "o": - o.Compression = ps[1][0] - case "t": - o.Transmission = ps[1][0] - case "d": - d := ps[1][0] - if d >= 'A' && d <= 'Z' { - o.DeleteResources = true - d = d + ' ' // to lowercase - } - o.Delete = d - case "i", "q", "p", "I", "f", "s", "v", "S", "O", "m", "x", "y", "z", "w", "h", "X", "Y", "c", "r", "U", "P", "Q": - v, err := strconv.Atoi(ps[1]) - if err != nil { - continue - } - - switch ps[0] { - case "i": - o.ID = v - case "q": - o.Quite = byte(v) - case "p": - o.PlacementID = v - case "I": - o.Number = v - case "f": - o.Format = v - case "s": - o.ImageWidth = v - case "v": - o.ImageHeight = v - case "S": - o.Size = v - case "O": - o.Offset = v - case "m": - o.Chunk = v == 0 || v == 1 - case "x": - o.X = v - case "y": - o.Y = v - case "z": - o.Z = v - case "w": - o.Width = v - case "h": - o.Height = v - case "X": - o.OffsetX = v - case "Y": - o.OffsetY = v - case "c": - o.Columns = v - case "r": - o.Rows = v - case "U": - o.VirtualPlacement = v == 1 - case "P": - o.ParentID = v - case "Q": - o.ParentPlacementID = v - } - } - } - - return nil -} diff --git a/vendor/github.com/charmbracelet/x/ansi/method.go b/vendor/github.com/charmbracelet/x/ansi/method.go deleted file mode 100644 index 0218809c9a..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/method.go +++ /dev/null @@ -1,172 +0,0 @@ -package ansi - -// Method is a type that represents the how the renderer should calculate the -// display width of cells. -type Method uint8 - -// Display width modes. -const ( - WcWidth Method = iota - GraphemeWidth -) - -// StringWidth returns the width of a string in cells. This is the number of -// cells that the string will occupy when printed in a terminal. ANSI escape -// codes are ignored and wide characters (such as East Asians and emojis) are -// accounted for. -func (m Method) StringWidth(s string) int { - return stringWidth(m, s) -} - -// Truncate truncates a string to a given length, adding a tail to the end if -// the string is longer than the given length. This function is aware of ANSI -// escape codes and will not break them, and accounts for wide-characters (such -// as East-Asian characters and emojis). -func (m Method) Truncate(s string, length int, tail string) string { - return truncate(m, s, length, tail) -} - -// TruncateLeft truncates a string to a given length, adding a prefix to the -// beginning if the string is longer than the given length. This function is -// aware of ANSI escape codes and will not break them, and accounts for -// wide-characters (such as East-Asian characters and emojis). -func (m Method) TruncateLeft(s string, length int, prefix string) string { - return truncateLeft(m, s, length, prefix) -} - -// Cut the string, without adding any prefix or tail strings. This function is -// aware of ANSI escape codes and will not break them, and accounts for -// wide-characters (such as East-Asian characters and emojis). Note that the -// [left] parameter is inclusive, while [right] isn't. -func (m Method) Cut(s string, left, right int) string { - return cut(m, s, left, right) -} - -// Hardwrap wraps a string or a block of text to a given line length, breaking -// word boundaries. This will preserve ANSI escape codes and will account for -// wide-characters in the string. -// When preserveSpace is true, spaces at the beginning of a line will be -// preserved. -// This treats the text as a sequence of graphemes. -func (m Method) Hardwrap(s string, length int, preserveSpace bool) string { - return hardwrap(m, s, length, preserveSpace) -} - -// Wordwrap wraps a string or a block of text to a given line length, not -// breaking word boundaries. This will preserve ANSI escape codes and will -// account for wide-characters in the string. -// The breakpoints string is a list of characters that are considered -// breakpoints for word wrapping. A hyphen (-) is always considered a -// breakpoint. -// -// Note: breakpoints must be a string of 1-cell wide rune characters. -func (m Method) Wordwrap(s string, length int, breakpoints string) string { - return wordwrap(m, s, length, breakpoints) -} - -// Wrap wraps a string or a block of text to a given line length, breaking word -// boundaries if necessary. This will preserve ANSI escape codes and will -// account for wide-characters in the string. The breakpoints string is a list -// of characters that are considered breakpoints for word wrapping. A hyphen -// (-) is always considered a breakpoint. -// -// Note: breakpoints must be a string of 1-cell wide rune characters. -func (m Method) Wrap(s string, length int, breakpoints string) string { - return wrap(m, s, length, breakpoints) -} - -// DecodeSequence decodes the first ANSI escape sequence or a printable -// grapheme from the given data. It returns the sequence slice, the number of -// bytes read, the cell width for each sequence, and the new state. -// -// The cell width will always be 0 for control and escape sequences, 1 for -// ASCII printable characters, and the number of cells other Unicode characters -// occupy. It uses the uniseg package to calculate the width of Unicode -// graphemes and characters. This means it will always do grapheme clustering -// (mode 2027). -// -// Passing a non-nil [*Parser] as the last argument will allow the decoder to -// collect sequence parameters, data, and commands. The parser cmd will have -// the packed command value that contains intermediate and prefix characters. -// In the case of a OSC sequence, the cmd will be the OSC command number. Use -// [Cmd] and [Param] types to unpack command intermediates and prefixes as well -// as parameters. -// -// Zero [Cmd] means the CSI, DCS, or ESC sequence is invalid. Moreover, checking the -// validity of other data sequences, OSC, DCS, etc, will require checking for -// the returned sequence terminator bytes such as ST (ESC \\) and BEL). -// -// We store the command byte in [Cmd] in the most significant byte, the -// prefix byte in the next byte, and the intermediate byte in the least -// significant byte. This is done to avoid using a struct to store the command -// and its intermediates and prefixes. The command byte is always the least -// significant byte i.e. [Cmd & 0xff]. Use the [Cmd] type to unpack the -// command, intermediate, and prefix bytes. Note that we only collect the last -// prefix character and intermediate byte. -// -// The [p.Params] slice will contain the parameters of the sequence. Any -// sub-parameter will have the [parser.HasMoreFlag] set. Use the [Param] type -// to unpack the parameters. -// -// Example: -// -// var state byte // the initial state is always zero [NormalState] -// p := NewParser(32, 1024) // create a new parser with a 32 params buffer and 1024 data buffer (optional) -// input := []byte("\x1b[31mHello, World!\x1b[0m") -// for len(input) > 0 { -// seq, width, n, newState := DecodeSequence(input, state, p) -// log.Printf("seq: %q, width: %d", seq, width) -// state = newState -// input = input[n:] -// } -func (m Method) DecodeSequence(data []byte, state byte, p *Parser) (seq []byte, width, n int, newState byte) { - return decodeSequence(m, data, state, p) -} - -// DecodeSequenceInString decodes the first ANSI escape sequence or a printable -// grapheme from the given data. It returns the sequence slice, the number of -// bytes read, the cell width for each sequence, and the new state. -// -// The cell width will always be 0 for control and escape sequences, 1 for -// ASCII printable characters, and the number of cells other Unicode characters -// occupy. It uses the uniseg package to calculate the width of Unicode -// graphemes and characters. This means it will always do grapheme clustering -// (mode 2027). -// -// Passing a non-nil [*Parser] as the last argument will allow the decoder to -// collect sequence parameters, data, and commands. The parser cmd will have -// the packed command value that contains intermediate and prefix characters. -// In the case of a OSC sequence, the cmd will be the OSC command number. Use -// [Cmd] and [Param] types to unpack command intermediates and prefixes as well -// as parameters. -// -// Zero [Cmd] means the CSI, DCS, or ESC sequence is invalid. Moreover, checking the -// validity of other data sequences, OSC, DCS, etc, will require checking for -// the returned sequence terminator bytes such as ST (ESC \\) and BEL). -// -// We store the command byte in [Cmd] in the most significant byte, the -// prefix byte in the next byte, and the intermediate byte in the least -// significant byte. This is done to avoid using a struct to store the command -// and its intermediates and prefixes. The command byte is always the least -// significant byte i.e. [Cmd & 0xff]. Use the [Cmd] type to unpack the -// command, intermediate, and prefix bytes. Note that we only collect the last -// prefix character and intermediate byte. -// -// The [p.Params] slice will contain the parameters of the sequence. Any -// sub-parameter will have the [parser.HasMoreFlag] set. Use the [Param] type -// to unpack the parameters. -// -// Example: -// -// var state byte // the initial state is always zero [NormalState] -// p := NewParser(32, 1024) // create a new parser with a 32 params buffer and 1024 data buffer (optional) -// input := []byte("\x1b[31mHello, World!\x1b[0m") -// for len(input) > 0 { -// seq, width, n, newState := DecodeSequenceInString(input, state, p) -// log.Printf("seq: %q, width: %d", seq, width) -// state = newState -// input = input[n:] -// } -func (m Method) DecodeSequenceInString(data string, state byte, p *Parser) (seq string, width, n int, newState byte) { - return decodeSequence(m, data, state, p) -} diff --git a/vendor/github.com/charmbracelet/x/ansi/mode.go b/vendor/github.com/charmbracelet/x/ansi/mode.go deleted file mode 100644 index 57f3f0a8e3..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/mode.go +++ /dev/null @@ -1,763 +0,0 @@ -package ansi - -import ( - "strconv" - "strings" -) - -// ModeSetting represents a mode setting. -type ModeSetting byte - -// ModeSetting constants. -const ( - ModeNotRecognized ModeSetting = iota - ModeSet - ModeReset - ModePermanentlySet - ModePermanentlyReset -) - -// IsNotRecognized returns true if the mode is not recognized. -func (m ModeSetting) IsNotRecognized() bool { - return m == ModeNotRecognized -} - -// IsSet returns true if the mode is set or permanently set. -func (m ModeSetting) IsSet() bool { - return m == ModeSet || m == ModePermanentlySet -} - -// IsReset returns true if the mode is reset or permanently reset. -func (m ModeSetting) IsReset() bool { - return m == ModeReset || m == ModePermanentlyReset -} - -// IsPermanentlySet returns true if the mode is permanently set. -func (m ModeSetting) IsPermanentlySet() bool { - return m == ModePermanentlySet -} - -// IsPermanentlyReset returns true if the mode is permanently reset. -func (m ModeSetting) IsPermanentlyReset() bool { - return m == ModePermanentlyReset -} - -// Mode represents an interface for terminal modes. -// Modes can be set, reset, and requested. -type Mode interface { - Mode() int -} - -// SetMode (SM) returns a sequence to set a mode. -// The mode arguments are a list of modes to set. -// -// If one of the modes is a [DECMode], the function will returns two escape -// sequences. -// -// ANSI format: -// -// CSI Pd ; ... ; Pd h -// -// DEC format: -// -// CSI ? Pd ; ... ; Pd h -// -// See: https://vt100.net/docs/vt510-rm/SM.html -func SetMode(modes ...Mode) string { - return setMode(false, modes...) -} - -// SM is an alias for [SetMode]. -func SM(modes ...Mode) string { - return SetMode(modes...) -} - -// ResetMode (RM) returns a sequence to reset a mode. -// The mode arguments are a list of modes to reset. -// -// If one of the modes is a [DECMode], the function will returns two escape -// sequences. -// -// ANSI format: -// -// CSI Pd ; ... ; Pd l -// -// DEC format: -// -// CSI ? Pd ; ... ; Pd l -// -// See: https://vt100.net/docs/vt510-rm/RM.html -func ResetMode(modes ...Mode) string { - return setMode(true, modes...) -} - -// RM is an alias for [ResetMode]. -func RM(modes ...Mode) string { - return ResetMode(modes...) -} - -func setMode(reset bool, modes ...Mode) (s string) { - if len(modes) == 0 { - return - } - - cmd := "h" - if reset { - cmd = "l" - } - - seq := "\x1b[" - if len(modes) == 1 { - switch modes[0].(type) { - case DECMode: - seq += "?" - } - return seq + strconv.Itoa(modes[0].Mode()) + cmd - } - - dec := make([]string, 0, len(modes)/2) - ansi := make([]string, 0, len(modes)/2) - for _, m := range modes { - switch m.(type) { - case DECMode: - dec = append(dec, strconv.Itoa(m.Mode())) - case ANSIMode: - ansi = append(ansi, strconv.Itoa(m.Mode())) - } - } - - if len(ansi) > 0 { - s += seq + strings.Join(ansi, ";") + cmd - } - if len(dec) > 0 { - s += seq + "?" + strings.Join(dec, ";") + cmd - } - return -} - -// RequestMode (DECRQM) returns a sequence to request a mode from the terminal. -// The terminal responds with a report mode function [DECRPM]. -// -// ANSI format: -// -// CSI Pa $ p -// -// DEC format: -// -// CSI ? Pa $ p -// -// See: https://vt100.net/docs/vt510-rm/DECRQM.html -func RequestMode(m Mode) string { - seq := "\x1b[" - switch m.(type) { - case DECMode: - seq += "?" - } - return seq + strconv.Itoa(m.Mode()) + "$p" -} - -// DECRQM is an alias for [RequestMode]. -func DECRQM(m Mode) string { - return RequestMode(m) -} - -// ReportMode (DECRPM) returns a sequence that the terminal sends to the host -// in response to a mode request [DECRQM]. -// -// ANSI format: -// -// CSI Pa ; Ps ; $ y -// -// DEC format: -// -// CSI ? Pa ; Ps $ y -// -// Where Pa is the mode number, and Ps is the mode value. -// -// 0: Not recognized -// 1: Set -// 2: Reset -// 3: Permanent set -// 4: Permanent reset -// -// See: https://vt100.net/docs/vt510-rm/DECRPM.html -func ReportMode(mode Mode, value ModeSetting) string { - if value > 4 { - value = 0 - } - switch mode.(type) { - case DECMode: - return "\x1b[?" + strconv.Itoa(mode.Mode()) + ";" + strconv.Itoa(int(value)) + "$y" - } - return "\x1b[" + strconv.Itoa(mode.Mode()) + ";" + strconv.Itoa(int(value)) + "$y" -} - -// DECRPM is an alias for [ReportMode]. -func DECRPM(mode Mode, value ModeSetting) string { - return ReportMode(mode, value) -} - -// ANSIMode represents an ANSI terminal mode. -type ANSIMode int //nolint:revive - -// Mode returns the ANSI mode as an integer. -func (m ANSIMode) Mode() int { - return int(m) -} - -// DECMode represents a private DEC terminal mode. -type DECMode int - -// Mode returns the DEC mode as an integer. -func (m DECMode) Mode() int { - return int(m) -} - -// Keyboard Action Mode (KAM) is a mode that controls locking of the keyboard. -// When the keyboard is locked, it cannot send data to the terminal. -// -// See: https://vt100.net/docs/vt510-rm/KAM.html -const ( - KeyboardActionMode = ANSIMode(2) - KAM = KeyboardActionMode - - SetKeyboardActionMode = "\x1b[2h" - ResetKeyboardActionMode = "\x1b[2l" - RequestKeyboardActionMode = "\x1b[2$p" -) - -// Insert/Replace Mode (IRM) is a mode that determines whether characters are -// inserted or replaced when typed. -// -// When enabled, characters are inserted at the cursor position pushing the -// characters to the right. When disabled, characters replace the character at -// the cursor position. -// -// See: https://vt100.net/docs/vt510-rm/IRM.html -const ( - InsertReplaceMode = ANSIMode(4) - IRM = InsertReplaceMode - - SetInsertReplaceMode = "\x1b[4h" - ResetInsertReplaceMode = "\x1b[4l" - RequestInsertReplaceMode = "\x1b[4$p" -) - -// Send Receive Mode (SRM) or Local Echo Mode is a mode that determines whether -// the terminal echoes characters back to the host. When enabled, the terminal -// sends characters to the host as they are typed. -// -// See: https://vt100.net/docs/vt510-rm/SRM.html -const ( - SendReceiveMode = ANSIMode(12) - LocalEchoMode = SendReceiveMode - SRM = SendReceiveMode - - SetSendReceiveMode = "\x1b[12h" - ResetSendReceiveMode = "\x1b[12l" - RequestSendReceiveMode = "\x1b[12$p" - - SetLocalEchoMode = "\x1b[12h" - ResetLocalEchoMode = "\x1b[12l" - RequestLocalEchoMode = "\x1b[12$p" -) - -// Line Feed/New Line Mode (LNM) is a mode that determines whether the terminal -// interprets the line feed character as a new line. -// -// When enabled, the terminal interprets the line feed character as a new line. -// When disabled, the terminal interprets the line feed character as a line feed. -// -// A new line moves the cursor to the first position of the next line. -// A line feed moves the cursor down one line without changing the column -// scrolling the screen if necessary. -// -// See: https://vt100.net/docs/vt510-rm/LNM.html -const ( - LineFeedNewLineMode = ANSIMode(20) - LNM = LineFeedNewLineMode - - SetLineFeedNewLineMode = "\x1b[20h" - ResetLineFeedNewLineMode = "\x1b[20l" - RequestLineFeedNewLineMode = "\x1b[20$p" -) - -// Cursor Keys Mode (DECCKM) is a mode that determines whether the cursor keys -// send ANSI cursor sequences or application sequences. -// -// See: https://vt100.net/docs/vt510-rm/DECCKM.html -const ( - CursorKeysMode = DECMode(1) - DECCKM = CursorKeysMode - - SetCursorKeysMode = "\x1b[?1h" - ResetCursorKeysMode = "\x1b[?1l" - RequestCursorKeysMode = "\x1b[?1$p" -) - -// Deprecated: use [SetCursorKeysMode] and [ResetCursorKeysMode] instead. -const ( - EnableCursorKeys = "\x1b[?1h" - DisableCursorKeys = "\x1b[?1l" -) - -// Origin Mode (DECOM) is a mode that determines whether the cursor moves to the -// home position or the margin position. -// -// See: https://vt100.net/docs/vt510-rm/DECOM.html -const ( - OriginMode = DECMode(6) - DECOM = OriginMode - - SetOriginMode = "\x1b[?6h" - ResetOriginMode = "\x1b[?6l" - RequestOriginMode = "\x1b[?6$p" -) - -// Auto Wrap Mode (DECAWM) is a mode that determines whether the cursor wraps -// to the next line when it reaches the right margin. -// -// See: https://vt100.net/docs/vt510-rm/DECAWM.html -const ( - AutoWrapMode = DECMode(7) - DECAWM = AutoWrapMode - - SetAutoWrapMode = "\x1b[?7h" - ResetAutoWrapMode = "\x1b[?7l" - RequestAutoWrapMode = "\x1b[?7$p" -) - -// X10 Mouse Mode is a mode that determines whether the mouse reports on button -// presses. -// -// The terminal responds with the following encoding: -// -// CSI M CbCxCy -// -// Where Cb is the button-1, where it can be 1, 2, or 3. -// Cx and Cy are the x and y coordinates of the mouse event. -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking -const ( - X10MouseMode = DECMode(9) - - SetX10MouseMode = "\x1b[?9h" - ResetX10MouseMode = "\x1b[?9l" - RequestX10MouseMode = "\x1b[?9$p" -) - -// Text Cursor Enable Mode (DECTCEM) is a mode that shows/hides the cursor. -// -// See: https://vt100.net/docs/vt510-rm/DECTCEM.html -const ( - TextCursorEnableMode = DECMode(25) - DECTCEM = TextCursorEnableMode - - SetTextCursorEnableMode = "\x1b[?25h" - ResetTextCursorEnableMode = "\x1b[?25l" - RequestTextCursorEnableMode = "\x1b[?25$p" -) - -// These are aliases for [SetTextCursorEnableMode] and [ResetTextCursorEnableMode]. -const ( - ShowCursor = SetTextCursorEnableMode - HideCursor = ResetTextCursorEnableMode -) - -// Text Cursor Enable Mode (DECTCEM) is a mode that shows/hides the cursor. -// -// See: https://vt100.net/docs/vt510-rm/DECTCEM.html -// -// Deprecated: use [SetTextCursorEnableMode] and [ResetTextCursorEnableMode] instead. -const ( - CursorEnableMode = DECMode(25) - RequestCursorVisibility = "\x1b[?25$p" -) - -// Numeric Keypad Mode (DECNKM) is a mode that determines whether the keypad -// sends application sequences or numeric sequences. -// -// This works like [DECKPAM] and [DECKPNM], but uses different sequences. -// -// See: https://vt100.net/docs/vt510-rm/DECNKM.html -const ( - NumericKeypadMode = DECMode(66) - DECNKM = NumericKeypadMode - - SetNumericKeypadMode = "\x1b[?66h" - ResetNumericKeypadMode = "\x1b[?66l" - RequestNumericKeypadMode = "\x1b[?66$p" -) - -// Backarrow Key Mode (DECBKM) is a mode that determines whether the backspace -// key sends a backspace or delete character. Disabled by default. -// -// See: https://vt100.net/docs/vt510-rm/DECBKM.html -const ( - BackarrowKeyMode = DECMode(67) - DECBKM = BackarrowKeyMode - - SetBackarrowKeyMode = "\x1b[?67h" - ResetBackarrowKeyMode = "\x1b[?67l" - RequestBackarrowKeyMode = "\x1b[?67$p" -) - -// Left Right Margin Mode (DECLRMM) is a mode that determines whether the left -// and right margins can be set with [DECSLRM]. -// -// See: https://vt100.net/docs/vt510-rm/DECLRMM.html -const ( - LeftRightMarginMode = DECMode(69) - DECLRMM = LeftRightMarginMode - - SetLeftRightMarginMode = "\x1b[?69h" - ResetLeftRightMarginMode = "\x1b[?69l" - RequestLeftRightMarginMode = "\x1b[?69$p" -) - -// Normal Mouse Mode is a mode that determines whether the mouse reports on -// button presses and releases. It will also report modifier keys, wheel -// events, and extra buttons. -// -// It uses the same encoding as [X10MouseMode] with a few differences: -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking -const ( - NormalMouseMode = DECMode(1000) - - SetNormalMouseMode = "\x1b[?1000h" - ResetNormalMouseMode = "\x1b[?1000l" - RequestNormalMouseMode = "\x1b[?1000$p" -) - -// VT Mouse Tracking is a mode that determines whether the mouse reports on -// button press and release. -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking -// -// Deprecated: use [NormalMouseMode] instead. -const ( - MouseMode = DECMode(1000) - - EnableMouse = "\x1b[?1000h" - DisableMouse = "\x1b[?1000l" - RequestMouse = "\x1b[?1000$p" -) - -// Highlight Mouse Tracking is a mode that determines whether the mouse reports -// on button presses, releases, and highlighted cells. -// -// It uses the same encoding as [NormalMouseMode] with a few differences: -// -// On highlight events, the terminal responds with the following encoding: -// -// CSI t CxCy -// CSI T CxCyCxCyCxCy -// -// Where the parameters are startx, starty, endx, endy, mousex, and mousey. -const ( - HighlightMouseMode = DECMode(1001) - - SetHighlightMouseMode = "\x1b[?1001h" - ResetHighlightMouseMode = "\x1b[?1001l" - RequestHighlightMouseMode = "\x1b[?1001$p" -) - -// VT Hilite Mouse Tracking is a mode that determines whether the mouse reports on -// button presses, releases, and highlighted cells. -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking -// -// Deprecated: use [HighlightMouseMode] instead. -const ( - MouseHiliteMode = DECMode(1001) - - EnableMouseHilite = "\x1b[?1001h" - DisableMouseHilite = "\x1b[?1001l" - RequestMouseHilite = "\x1b[?1001$p" -) - -// Button Event Mouse Tracking is essentially the same as [NormalMouseMode], -// but it also reports button-motion events when a button is pressed. -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking -const ( - ButtonEventMouseMode = DECMode(1002) - - SetButtonEventMouseMode = "\x1b[?1002h" - ResetButtonEventMouseMode = "\x1b[?1002l" - RequestButtonEventMouseMode = "\x1b[?1002$p" -) - -// Cell Motion Mouse Tracking is a mode that determines whether the mouse -// reports on button press, release, and motion events. -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking -// -// Deprecated: use [ButtonEventMouseMode] instead. -const ( - MouseCellMotionMode = DECMode(1002) - - EnableMouseCellMotion = "\x1b[?1002h" - DisableMouseCellMotion = "\x1b[?1002l" - RequestMouseCellMotion = "\x1b[?1002$p" -) - -// Any Event Mouse Tracking is the same as [ButtonEventMouseMode], except that -// all motion events are reported even if no mouse buttons are pressed. -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking -const ( - AnyEventMouseMode = DECMode(1003) - - SetAnyEventMouseMode = "\x1b[?1003h" - ResetAnyEventMouseMode = "\x1b[?1003l" - RequestAnyEventMouseMode = "\x1b[?1003$p" -) - -// All Mouse Tracking is a mode that determines whether the mouse reports on -// button press, release, motion, and highlight events. -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking -// -// Deprecated: use [AnyEventMouseMode] instead. -const ( - MouseAllMotionMode = DECMode(1003) - - EnableMouseAllMotion = "\x1b[?1003h" - DisableMouseAllMotion = "\x1b[?1003l" - RequestMouseAllMotion = "\x1b[?1003$p" -) - -// Focus Event Mode is a mode that determines whether the terminal reports focus -// and blur events. -// -// The terminal sends the following encoding: -// -// CSI I // Focus In -// CSI O // Focus Out -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Focus-Tracking -const ( - FocusEventMode = DECMode(1004) - - SetFocusEventMode = "\x1b[?1004h" - ResetFocusEventMode = "\x1b[?1004l" - RequestFocusEventMode = "\x1b[?1004$p" -) - -// Deprecated: use [SetFocusEventMode], [ResetFocusEventMode], and -// [RequestFocusEventMode] instead. -const ( - ReportFocusMode = DECMode(1004) - - EnableReportFocus = "\x1b[?1004h" - DisableReportFocus = "\x1b[?1004l" - RequestReportFocus = "\x1b[?1004$p" -) - -// SGR Extended Mouse Mode is a mode that changes the mouse tracking encoding -// to use SGR parameters. -// -// The terminal responds with the following encoding: -// -// CSI < Cb ; Cx ; Cy M -// -// Where Cb is the same as [NormalMouseMode], and Cx and Cy are the x and y. -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking -const ( - SgrExtMouseMode = DECMode(1006) - - SetSgrExtMouseMode = "\x1b[?1006h" - ResetSgrExtMouseMode = "\x1b[?1006l" - RequestSgrExtMouseMode = "\x1b[?1006$p" -) - -// Deprecated: use [SgrExtMouseMode] [SetSgrExtMouseMode], -// [ResetSgrExtMouseMode], and [RequestSgrExtMouseMode] instead. -const ( - MouseSgrExtMode = DECMode(1006) - EnableMouseSgrExt = "\x1b[?1006h" - DisableMouseSgrExt = "\x1b[?1006l" - RequestMouseSgrExt = "\x1b[?1006$p" -) - -// UTF-8 Extended Mouse Mode is a mode that changes the mouse tracking encoding -// to use UTF-8 parameters. -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking -const ( - Utf8ExtMouseMode = DECMode(1005) - - SetUtf8ExtMouseMode = "\x1b[?1005h" - ResetUtf8ExtMouseMode = "\x1b[?1005l" - RequestUtf8ExtMouseMode = "\x1b[?1005$p" -) - -// URXVT Extended Mouse Mode is a mode that changes the mouse tracking encoding -// to use an alternate encoding. -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking -const ( - UrxvtExtMouseMode = DECMode(1015) - - SetUrxvtExtMouseMode = "\x1b[?1015h" - ResetUrxvtExtMouseMode = "\x1b[?1015l" - RequestUrxvtExtMouseMode = "\x1b[?1015$p" -) - -// SGR Pixel Extended Mouse Mode is a mode that changes the mouse tracking -// encoding to use SGR parameters with pixel coordinates. -// -// This is similar to [SgrExtMouseMode], but also reports pixel coordinates. -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking -const ( - SgrPixelExtMouseMode = DECMode(1016) - - SetSgrPixelExtMouseMode = "\x1b[?1016h" - ResetSgrPixelExtMouseMode = "\x1b[?1016l" - RequestSgrPixelExtMouseMode = "\x1b[?1016$p" -) - -// Alternate Screen Mode is a mode that determines whether the alternate screen -// buffer is active. When this mode is enabled, the alternate screen buffer is -// cleared. -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-The-Alternate-Screen-Buffer -const ( - AltScreenMode = DECMode(1047) - - SetAltScreenMode = "\x1b[?1047h" - ResetAltScreenMode = "\x1b[?1047l" - RequestAltScreenMode = "\x1b[?1047$p" -) - -// Save Cursor Mode is a mode that saves the cursor position. -// This is equivalent to [SaveCursor] and [RestoreCursor]. -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-The-Alternate-Screen-Buffer -const ( - SaveCursorMode = DECMode(1048) - - SetSaveCursorMode = "\x1b[?1048h" - ResetSaveCursorMode = "\x1b[?1048l" - RequestSaveCursorMode = "\x1b[?1048$p" -) - -// Alternate Screen Save Cursor Mode is a mode that saves the cursor position as in -// [SaveCursorMode], switches to the alternate screen buffer as in [AltScreenMode], -// and clears the screen on switch. -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-The-Alternate-Screen-Buffer -const ( - AltScreenSaveCursorMode = DECMode(1049) - - SetAltScreenSaveCursorMode = "\x1b[?1049h" - ResetAltScreenSaveCursorMode = "\x1b[?1049l" - RequestAltScreenSaveCursorMode = "\x1b[?1049$p" -) - -// Alternate Screen Buffer is a mode that determines whether the alternate screen -// buffer is active. -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-The-Alternate-Screen-Buffer -// -// Deprecated: use [AltScreenSaveCursorMode] instead. -const ( - AltScreenBufferMode = DECMode(1049) - - SetAltScreenBufferMode = "\x1b[?1049h" - ResetAltScreenBufferMode = "\x1b[?1049l" - RequestAltScreenBufferMode = "\x1b[?1049$p" - - EnableAltScreenBuffer = "\x1b[?1049h" - DisableAltScreenBuffer = "\x1b[?1049l" - RequestAltScreenBuffer = "\x1b[?1049$p" -) - -// Bracketed Paste Mode is a mode that determines whether pasted text is -// bracketed with escape sequences. -// -// See: https://cirw.in/blog/bracketed-paste -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Bracketed-Paste-Mode -const ( - BracketedPasteMode = DECMode(2004) - - SetBracketedPasteMode = "\x1b[?2004h" - ResetBracketedPasteMode = "\x1b[?2004l" - RequestBracketedPasteMode = "\x1b[?2004$p" -) - -// Deprecated: use [SetBracketedPasteMode], [ResetBracketedPasteMode], and -// [RequestBracketedPasteMode] instead. -const ( - EnableBracketedPaste = "\x1b[?2004h" - DisableBracketedPaste = "\x1b[?2004l" - RequestBracketedPaste = "\x1b[?2004$p" -) - -// Synchronized Output Mode is a mode that determines whether output is -// synchronized with the terminal. -// -// See: https://gist.github.com/christianparpart/d8a62cc1ab659194337d73e399004036 -const ( - SynchronizedOutputMode = DECMode(2026) - - SetSynchronizedOutputMode = "\x1b[?2026h" - ResetSynchronizedOutputMode = "\x1b[?2026l" - RequestSynchronizedOutputMode = "\x1b[?2026$p" -) - -// Deprecated: use [SynchronizedOutputMode], [SetSynchronizedOutputMode], and -// [ResetSynchronizedOutputMode], and [RequestSynchronizedOutputMode] instead. -const ( - SyncdOutputMode = DECMode(2026) - - EnableSyncdOutput = "\x1b[?2026h" - DisableSyncdOutput = "\x1b[?2026l" - RequestSyncdOutput = "\x1b[?2026$p" -) - -// Grapheme Clustering Mode is a mode that determines whether the terminal -// should look for grapheme clusters instead of single runes in the rendered -// text. This makes the terminal properly render combining characters such as -// emojis. -// -// See: https://github.com/contour-terminal/terminal-unicode-core -const ( - GraphemeClusteringMode = DECMode(2027) - - SetGraphemeClusteringMode = "\x1b[?2027h" - ResetGraphemeClusteringMode = "\x1b[?2027l" - RequestGraphemeClusteringMode = "\x1b[?2027$p" -) - -// Deprecated: use [SetGraphemeClusteringMode], [ResetGraphemeClusteringMode], and -// [RequestGraphemeClusteringMode] instead. -const ( - EnableGraphemeClustering = "\x1b[?2027h" - DisableGraphemeClustering = "\x1b[?2027l" - RequestGraphemeClustering = "\x1b[?2027$p" -) - -// Win32Input is a mode that determines whether input is processed by the -// Win32 console and Conpty. -// -// See: https://github.com/microsoft/terminal/blob/main/doc/specs/%234999%20-%20Improved%20keyboard%20handling%20in%20Conpty.md -const ( - Win32InputMode = DECMode(9001) - - SetWin32InputMode = "\x1b[?9001h" - ResetWin32InputMode = "\x1b[?9001l" - RequestWin32InputMode = "\x1b[?9001$p" -) - -// Deprecated: use [SetWin32InputMode], [ResetWin32InputMode], and -// [RequestWin32InputMode] instead. -const ( - EnableWin32Input = "\x1b[?9001h" - DisableWin32Input = "\x1b[?9001l" - RequestWin32Input = "\x1b[?9001$p" -) diff --git a/vendor/github.com/charmbracelet/x/ansi/modes.go b/vendor/github.com/charmbracelet/x/ansi/modes.go deleted file mode 100644 index 1bec5bc807..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/modes.go +++ /dev/null @@ -1,71 +0,0 @@ -package ansi - -// Modes represents the terminal modes that can be set or reset. By default, -// all modes are [ModeNotRecognized]. -type Modes map[Mode]ModeSetting - -// NewModes creates a new Modes map. By default, all modes are -// [ModeNotRecognized]. -func NewModes() Modes { - return make(Modes) -} - -// Get returns the setting of a terminal mode. If the mode is not set, it -// returns [ModeNotRecognized]. -func (m Modes) Get(mode Mode) ModeSetting { - return m[mode] -} - -// Delete deletes a terminal mode. This has the same effect as setting the mode -// to [ModeNotRecognized]. -func (m Modes) Delete(mode Mode) { - delete(m, mode) -} - -// Set sets a terminal mode to [ModeSet]. -func (m Modes) Set(modes ...Mode) { - for _, mode := range modes { - m[mode] = ModeSet - } -} - -// PermanentlySet sets a terminal mode to [ModePermanentlySet]. -func (m Modes) PermanentlySet(modes ...Mode) { - for _, mode := range modes { - m[mode] = ModePermanentlySet - } -} - -// Reset sets a terminal mode to [ModeReset]. -func (m Modes) Reset(modes ...Mode) { - for _, mode := range modes { - m[mode] = ModeReset - } -} - -// PermanentlyReset sets a terminal mode to [ModePermanentlyReset]. -func (m Modes) PermanentlyReset(modes ...Mode) { - for _, mode := range modes { - m[mode] = ModePermanentlyReset - } -} - -// IsSet returns true if the mode is set to [ModeSet] or [ModePermanentlySet]. -func (m Modes) IsSet(mode Mode) bool { - return m[mode].IsSet() -} - -// IsPermanentlySet returns true if the mode is set to [ModePermanentlySet]. -func (m Modes) IsPermanentlySet(mode Mode) bool { - return m[mode].IsPermanentlySet() -} - -// IsReset returns true if the mode is set to [ModeReset] or [ModePermanentlyReset]. -func (m Modes) IsReset(mode Mode) bool { - return m[mode].IsReset() -} - -// IsPermanentlyReset returns true if the mode is set to [ModePermanentlyReset]. -func (m Modes) IsPermanentlyReset(mode Mode) bool { - return m[mode].IsPermanentlyReset() -} diff --git a/vendor/github.com/charmbracelet/x/ansi/mouse.go b/vendor/github.com/charmbracelet/x/ansi/mouse.go deleted file mode 100644 index 95b0127fd9..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/mouse.go +++ /dev/null @@ -1,172 +0,0 @@ -package ansi - -import ( - "fmt" -) - -// MouseButton represents the button that was pressed during a mouse message. -type MouseButton byte - -// Mouse event buttons -// -// This is based on X11 mouse button codes. -// -// 1 = left button -// 2 = middle button (pressing the scroll wheel) -// 3 = right button -// 4 = turn scroll wheel up -// 5 = turn scroll wheel down -// 6 = push scroll wheel left -// 7 = push scroll wheel right -// 8 = 4th button (aka browser backward button) -// 9 = 5th button (aka browser forward button) -// 10 -// 11 -// -// Other buttons are not supported. -const ( - MouseNone MouseButton = iota - MouseButton1 - MouseButton2 - MouseButton3 - MouseButton4 - MouseButton5 - MouseButton6 - MouseButton7 - MouseButton8 - MouseButton9 - MouseButton10 - MouseButton11 - - MouseLeft = MouseButton1 - MouseMiddle = MouseButton2 - MouseRight = MouseButton3 - MouseWheelUp = MouseButton4 - MouseWheelDown = MouseButton5 - MouseWheelLeft = MouseButton6 - MouseWheelRight = MouseButton7 - MouseBackward = MouseButton8 - MouseForward = MouseButton9 - MouseRelease = MouseNone -) - -var mouseButtons = map[MouseButton]string{ - MouseNone: "none", - MouseLeft: "left", - MouseMiddle: "middle", - MouseRight: "right", - MouseWheelUp: "wheelup", - MouseWheelDown: "wheeldown", - MouseWheelLeft: "wheelleft", - MouseWheelRight: "wheelright", - MouseBackward: "backward", - MouseForward: "forward", - MouseButton10: "button10", - MouseButton11: "button11", -} - -// String returns a string representation of the mouse button. -func (b MouseButton) String() string { - return mouseButtons[b] -} - -// EncodeMouseButton returns a byte representing a mouse button. -// The button is a bitmask of the following leftmost values: -// -// - The first two bits are the button number: -// 0 = left button, wheel up, or button no. 8 aka (backwards) -// 1 = middle button, wheel down, or button no. 9 aka (forwards) -// 2 = right button, wheel left, or button no. 10 -// 3 = release event, wheel right, or button no. 11 -// -// - The third bit indicates whether the shift key was pressed. -// -// - The fourth bit indicates the alt key was pressed. -// -// - The fifth bit indicates the control key was pressed. -// -// - The sixth bit indicates motion events. Combined with button number 3, i.e. -// release event, it represents a drag event. -// -// - The seventh bit indicates a wheel event. -// -// - The eighth bit indicates additional buttons. -// -// If button is [MouseNone], and motion is false, this returns a release event. -// If button is undefined, this function returns 0xff. -func EncodeMouseButton(b MouseButton, motion, shift, alt, ctrl bool) (m byte) { - // mouse bit shifts - const ( - bitShift = 0b0000_0100 - bitAlt = 0b0000_1000 - bitCtrl = 0b0001_0000 - bitMotion = 0b0010_0000 - bitWheel = 0b0100_0000 - bitAdd = 0b1000_0000 // additional buttons 8-11 - - bitsMask = 0b0000_0011 - ) - - if b == MouseNone { - m = bitsMask - } else if b >= MouseLeft && b <= MouseRight { - m = byte(b - MouseLeft) - } else if b >= MouseWheelUp && b <= MouseWheelRight { - m = byte(b - MouseWheelUp) - m |= bitWheel - } else if b >= MouseBackward && b <= MouseButton11 { - m = byte(b - MouseBackward) - m |= bitAdd - } else { - m = 0xff // invalid button - } - - if shift { - m |= bitShift - } - if alt { - m |= bitAlt - } - if ctrl { - m |= bitCtrl - } - if motion { - m |= bitMotion - } - - return -} - -// x10Offset is the offset for X10 mouse events. -// See https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking -const x10Offset = 32 - -// MouseX10 returns an escape sequence representing a mouse event in X10 mode. -// Note that this requires the terminal support X10 mouse modes. -// -// CSI M Cb Cx Cy -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking -func MouseX10(b byte, x, y int) string { - return "\x1b[M" + string(b+x10Offset) + string(byte(x)+x10Offset+1) + string(byte(y)+x10Offset+1) -} - -// MouseSgr returns an escape sequence representing a mouse event in SGR mode. -// -// CSI < Cb ; Cx ; Cy M -// CSI < Cb ; Cx ; Cy m (release) -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking -func MouseSgr(b byte, x, y int, release bool) string { - s := 'M' - if release { - s = 'm' - } - if x < 0 { - x = -x - } - if y < 0 { - y = -y - } - return fmt.Sprintf("\x1b[<%d;%d;%d%c", b, x+1, y+1, s) -} diff --git a/vendor/github.com/charmbracelet/x/ansi/notification.go b/vendor/github.com/charmbracelet/x/ansi/notification.go deleted file mode 100644 index c712f34059..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/notification.go +++ /dev/null @@ -1,13 +0,0 @@ -package ansi - -// Notify sends a desktop notification using iTerm's OSC 9. -// -// OSC 9 ; Mc ST -// OSC 9 ; Mc BEL -// -// Where Mc is the notification body. -// -// See: https://iterm2.com/documentation-escape-codes.html -func Notify(s string) string { - return "\x1b]9;" + s + "\x07" -} diff --git a/vendor/github.com/charmbracelet/x/ansi/parser.go b/vendor/github.com/charmbracelet/x/ansi/parser.go deleted file mode 100644 index 882e1ed7a0..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/parser.go +++ /dev/null @@ -1,417 +0,0 @@ -package ansi - -import ( - "unicode/utf8" - "unsafe" - - "github.com/charmbracelet/x/ansi/parser" -) - -// Parser represents a DEC ANSI compatible sequence parser. -// -// It uses a state machine to parse ANSI escape sequences and control -// characters. The parser is designed to be used with a terminal emulator or -// similar application that needs to parse ANSI escape sequences and control -// characters. -// See package [parser] for more information. -// -//go:generate go run ./gen.go -type Parser struct { - handler Handler - - // params contains the raw parameters of the sequence. - // These parameters used when constructing CSI and DCS sequences. - params []int - - // data contains the raw data of the sequence. - // These data used when constructing OSC, DCS, SOS, PM, and APC sequences. - data []byte - - // dataLen keeps track of the length of the data buffer. - // If dataLen is -1, the data buffer is unlimited and will grow as needed. - // Otherwise, dataLen is limited by the size of the data buffer. - dataLen int - - // paramsLen keeps track of the number of parameters. - // This is limited by the size of the params buffer. - // - // This is also used when collecting UTF-8 runes to keep track of the - // number of rune bytes collected. - paramsLen int - - // cmd contains the raw command along with the private prefix and - // intermediate bytes of the sequence. - // The first lower byte contains the command byte, the next byte contains - // the private prefix, and the next byte contains the intermediate byte. - // - // This is also used when collecting UTF-8 runes treating it as a slice of - // 4 bytes. - cmd int - - // state is the current state of the parser. - state byte -} - -// NewParser returns a new parser with the default settings. -// The [Parser] uses a default size of 32 for the parameters and 64KB for the -// data buffer. Use [Parser.SetParamsSize] and [Parser.SetDataSize] to set the -// size of the parameters and data buffer respectively. -func NewParser() *Parser { - p := new(Parser) - p.SetParamsSize(parser.MaxParamsSize) - p.SetDataSize(1024 * 64) // 64KB data buffer - return p -} - -// SetParamsSize sets the size of the parameters buffer. -// This is used when constructing CSI and DCS sequences. -func (p *Parser) SetParamsSize(size int) { - p.params = make([]int, size) -} - -// SetDataSize sets the size of the data buffer. -// This is used when constructing OSC, DCS, SOS, PM, and APC sequences. -// If size is less than or equal to 0, the data buffer is unlimited and will -// grow as needed. -func (p *Parser) SetDataSize(size int) { - if size <= 0 { - size = 0 - p.dataLen = -1 - } - p.data = make([]byte, size) -} - -// Params returns the list of parsed packed parameters. -func (p *Parser) Params() Params { - return unsafe.Slice((*Param)(unsafe.Pointer(&p.params[0])), p.paramsLen) -} - -// Param returns the parameter at the given index and falls back to the default -// value if the parameter is missing. If the index is out of bounds, it returns -// the default value and false. -func (p *Parser) Param(i, def int) (int, bool) { - if i < 0 || i >= p.paramsLen { - return def, false - } - return Param(p.params[i]).Param(def), true -} - -// Command returns the packed command of the last dispatched sequence. Use -// [Cmd] to unpack the command. -func (p *Parser) Command() int { - return p.cmd -} - -// Rune returns the last dispatched sequence as a rune. -func (p *Parser) Rune() rune { - rw := utf8ByteLen(byte(p.cmd & 0xff)) - if rw == -1 { - return utf8.RuneError - } - r, _ := utf8.DecodeRune((*[utf8.UTFMax]byte)(unsafe.Pointer(&p.cmd))[:rw]) - return r -} - -// Control returns the last dispatched sequence as a control code. -func (p *Parser) Control() byte { - return byte(p.cmd & 0xff) -} - -// Data returns the raw data of the last dispatched sequence. -func (p *Parser) Data() []byte { - return p.data[:p.dataLen] -} - -// Reset resets the parser to its initial state. -func (p *Parser) Reset() { - p.clear() - p.state = parser.GroundState -} - -// clear clears the parser parameters and command. -func (p *Parser) clear() { - if len(p.params) > 0 { - p.params[0] = parser.MissingParam - } - p.paramsLen = 0 - p.cmd = 0 -} - -// State returns the current state of the parser. -func (p *Parser) State() parser.State { - return p.state -} - -// StateName returns the name of the current state. -func (p *Parser) StateName() string { - return parser.StateNames[p.state] -} - -// Parse parses the given dispatcher and byte buffer. -// Deprecated: Loop over the buffer and call [Parser.Advance] instead. -func (p *Parser) Parse(b []byte) { - for i := 0; i < len(b); i++ { - p.Advance(b[i]) - } -} - -// Advance advances the parser using the given byte. It returns the action -// performed by the parser. -func (p *Parser) Advance(b byte) parser.Action { - switch p.state { - case parser.Utf8State: - // We handle UTF-8 here. - return p.advanceUtf8(b) - default: - return p.advance(b) - } -} - -func (p *Parser) collectRune(b byte) { - if p.paramsLen >= utf8.UTFMax { - return - } - - shift := p.paramsLen * 8 - p.cmd &^= 0xff << shift - p.cmd |= int(b) << shift - p.paramsLen++ -} - -func (p *Parser) advanceUtf8(b byte) parser.Action { - // Collect UTF-8 rune bytes. - p.collectRune(b) - rw := utf8ByteLen(byte(p.cmd & 0xff)) - if rw == -1 { - // We panic here because the first byte comes from the state machine, - // if this panics, it means there is a bug in the state machine! - panic("invalid rune") // unreachable - } - - if p.paramsLen < rw { - return parser.CollectAction - } - - // We have enough bytes to decode the rune using unsafe - if p.handler.Print != nil { - p.handler.Print(p.Rune()) - } - - p.state = parser.GroundState - p.paramsLen = 0 - - return parser.PrintAction -} - -func (p *Parser) advance(b byte) parser.Action { - state, action := parser.Table.Transition(p.state, b) - - // We need to clear the parser state if the state changes from EscapeState. - // This is because when we enter the EscapeState, we don't get a chance to - // clear the parser state. For example, when a sequence terminates with a - // ST (\x1b\\ or \x9c), we dispatch the current sequence and transition to - // EscapeState. However, the parser state is not cleared in this case and - // we need to clear it here before dispatching the esc sequence. - if p.state != state { - if p.state == parser.EscapeState { - p.performAction(parser.ClearAction, state, b) - } - if action == parser.PutAction && - p.state == parser.DcsEntryState && state == parser.DcsStringState { - // XXX: This is a special case where we need to start collecting - // non-string parameterized data i.e. doesn't follow the ECMA-48 § - // 5.4.1 string parameters format. - p.performAction(parser.StartAction, state, 0) - } - } - - // Handle special cases - switch { - case b == ESC && p.state == parser.EscapeState: - // Two ESCs in a row - p.performAction(parser.ExecuteAction, state, b) - default: - p.performAction(action, state, b) - } - - p.state = state - - return action -} - -func (p *Parser) parseStringCmd() { - // Try to parse the command - datalen := len(p.data) - if p.dataLen >= 0 { - datalen = p.dataLen - } - for i := 0; i < datalen; i++ { - d := p.data[i] - if d < '0' || d > '9' { - break - } - if p.cmd == parser.MissingCommand { - p.cmd = 0 - } - p.cmd *= 10 - p.cmd += int(d - '0') - } -} - -func (p *Parser) performAction(action parser.Action, state parser.State, b byte) { - switch action { - case parser.IgnoreAction: - break - - case parser.ClearAction: - p.clear() - - case parser.PrintAction: - p.cmd = int(b) - if p.handler.Print != nil { - p.handler.Print(rune(b)) - } - - case parser.ExecuteAction: - p.cmd = int(b) - if p.handler.Execute != nil { - p.handler.Execute(b) - } - - case parser.PrefixAction: - // Collect private prefix - // we only store the last prefix - p.cmd &^= 0xff << parser.PrefixShift - p.cmd |= int(b) << parser.PrefixShift - - case parser.CollectAction: - if state == parser.Utf8State { - // Reset the UTF-8 counter - p.paramsLen = 0 - p.collectRune(b) - } else { - // Collect intermediate bytes - // we only store the last intermediate byte - p.cmd &^= 0xff << parser.IntermedShift - p.cmd |= int(b) << parser.IntermedShift - } - - case parser.ParamAction: - // Collect parameters - if p.paramsLen >= len(p.params) { - break - } - - if b >= '0' && b <= '9' { - if p.params[p.paramsLen] == parser.MissingParam { - p.params[p.paramsLen] = 0 - } - - p.params[p.paramsLen] *= 10 - p.params[p.paramsLen] += int(b - '0') - } - - if b == ':' { - p.params[p.paramsLen] |= parser.HasMoreFlag - } - - if b == ';' || b == ':' { - p.paramsLen++ - if p.paramsLen < len(p.params) { - p.params[p.paramsLen] = parser.MissingParam - } - } - - case parser.StartAction: - if p.dataLen < 0 && p.data != nil { - p.data = p.data[:0] - } else { - p.dataLen = 0 - } - if p.state >= parser.DcsEntryState && p.state <= parser.DcsStringState { - // Collect the command byte for DCS - p.cmd |= int(b) - } else { - p.cmd = parser.MissingCommand - } - - case parser.PutAction: - switch p.state { - case parser.OscStringState: - if b == ';' && p.cmd == parser.MissingCommand { - p.parseStringCmd() - } - } - - if p.dataLen < 0 { - p.data = append(p.data, b) - } else { - if p.dataLen < len(p.data) { - p.data[p.dataLen] = b - p.dataLen++ - } - } - - case parser.DispatchAction: - // Increment the last parameter - if p.paramsLen > 0 && p.paramsLen < len(p.params)-1 || - p.paramsLen == 0 && len(p.params) > 0 && p.params[0] != parser.MissingParam { - p.paramsLen++ - } - - if p.state == parser.OscStringState && p.cmd == parser.MissingCommand { - // Ensure we have a command for OSC - p.parseStringCmd() - } - - data := p.data - if p.dataLen >= 0 { - data = data[:p.dataLen] - } - switch p.state { - case parser.CsiEntryState, parser.CsiParamState, parser.CsiIntermediateState: - p.cmd |= int(b) - if p.handler.HandleCsi != nil { - p.handler.HandleCsi(Cmd(p.cmd), p.Params()) - } - case parser.EscapeState, parser.EscapeIntermediateState: - p.cmd |= int(b) - if p.handler.HandleEsc != nil { - p.handler.HandleEsc(Cmd(p.cmd)) - } - case parser.DcsEntryState, parser.DcsParamState, parser.DcsIntermediateState, parser.DcsStringState: - if p.handler.HandleDcs != nil { - p.handler.HandleDcs(Cmd(p.cmd), p.Params(), data) - } - case parser.OscStringState: - if p.handler.HandleOsc != nil { - p.handler.HandleOsc(p.cmd, data) - } - case parser.SosStringState: - if p.handler.HandleSos != nil { - p.handler.HandleSos(data) - } - case parser.PmStringState: - if p.handler.HandlePm != nil { - p.handler.HandlePm(data) - } - case parser.ApcStringState: - if p.handler.HandleApc != nil { - p.handler.HandleApc(data) - } - } - } -} - -func utf8ByteLen(b byte) int { - if b <= 0b0111_1111 { // 0x00-0x7F - return 1 - } else if b >= 0b1100_0000 && b <= 0b1101_1111 { // 0xC0-0xDF - return 2 - } else if b >= 0b1110_0000 && b <= 0b1110_1111 { // 0xE0-0xEF - return 3 - } else if b >= 0b1111_0000 && b <= 0b1111_0111 { // 0xF0-0xF7 - return 4 - } - return -1 -} diff --git a/vendor/github.com/charmbracelet/x/ansi/parser/const.go b/vendor/github.com/charmbracelet/x/ansi/parser/const.go deleted file mode 100644 index d62dbf379e..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/parser/const.go +++ /dev/null @@ -1,78 +0,0 @@ -package parser - -// Action is a DEC ANSI parser action. -type Action = byte - -// These are the actions that the parser can take. -const ( - NoneAction Action = iota - ClearAction - CollectAction - PrefixAction - DispatchAction - ExecuteAction - StartAction // Start of a data string - PutAction // Put into the data string - ParamAction - PrintAction - - IgnoreAction = NoneAction -) - -// nolint: unused -var ActionNames = []string{ - "NoneAction", - "ClearAction", - "CollectAction", - "PrefixAction", - "DispatchAction", - "ExecuteAction", - "StartAction", - "PutAction", - "ParamAction", - "PrintAction", -} - -// State is a DEC ANSI parser state. -type State = byte - -// These are the states that the parser can be in. -const ( - GroundState State = iota - CsiEntryState - CsiIntermediateState - CsiParamState - DcsEntryState - DcsIntermediateState - DcsParamState - DcsStringState - EscapeState - EscapeIntermediateState - OscStringState - SosStringState - PmStringState - ApcStringState - - // Utf8State is not part of the DEC ANSI standard. It is used to handle - // UTF-8 sequences. - Utf8State -) - -// nolint: unused -var StateNames = []string{ - "GroundState", - "CsiEntryState", - "CsiIntermediateState", - "CsiParamState", - "DcsEntryState", - "DcsIntermediateState", - "DcsParamState", - "DcsStringState", - "EscapeState", - "EscapeIntermediateState", - "OscStringState", - "SosStringState", - "PmStringState", - "ApcStringState", - "Utf8State", -} diff --git a/vendor/github.com/charmbracelet/x/ansi/parser/seq.go b/vendor/github.com/charmbracelet/x/ansi/parser/seq.go deleted file mode 100644 index 29f491d1c4..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/parser/seq.go +++ /dev/null @@ -1,136 +0,0 @@ -package parser - -import "math" - -// Shift and masks for sequence parameters and intermediates. -const ( - PrefixShift = 8 - IntermedShift = 16 - FinalMask = 0xff - HasMoreFlag = math.MinInt32 - ParamMask = ^HasMoreFlag - MissingParam = ParamMask - MissingCommand = MissingParam - MaxParam = math.MaxUint16 // the maximum value a parameter can have -) - -const ( - // MaxParamsSize is the maximum number of parameters a sequence can have. - MaxParamsSize = 32 - - // DefaultParamValue is the default value used for missing parameters. - DefaultParamValue = 0 -) - -// Prefix returns the prefix byte of the sequence. -// This is always gonna be one of the following '<' '=' '>' '?' and in the -// range of 0x3C-0x3F. -// Zero is returned if the sequence does not have a prefix. -func Prefix(cmd int) int { - return (cmd >> PrefixShift) & FinalMask -} - -// Intermediate returns the intermediate byte of the sequence. -// An intermediate byte is in the range of 0x20-0x2F. This includes these -// characters from ' ', '!', '"', '#', '$', '%', '&', ”', '(', ')', '*', '+', -// ',', '-', '.', '/'. -// Zero is returned if the sequence does not have an intermediate byte. -func Intermediate(cmd int) int { - return (cmd >> IntermedShift) & FinalMask -} - -// Command returns the command byte of the CSI sequence. -func Command(cmd int) int { - return cmd & FinalMask -} - -// Param returns the parameter at the given index. -// It returns -1 if the parameter does not exist. -func Param(params []int, i int) int { - if len(params) == 0 || i < 0 || i >= len(params) { - return -1 - } - - p := params[i] & ParamMask - if p == MissingParam { - return -1 - } - - return p -} - -// HasMore returns true if the parameter has more sub-parameters. -func HasMore(params []int, i int) bool { - if len(params) == 0 || i >= len(params) { - return false - } - - return params[i]&HasMoreFlag != 0 -} - -// Subparams returns the sub-parameters of the given parameter. -// It returns nil if the parameter does not exist. -func Subparams(params []int, i int) []int { - if len(params) == 0 || i < 0 || i >= len(params) { - return nil - } - - // Count the number of parameters before the given parameter index. - var count int - var j int - for j = 0; j < len(params); j++ { - if count == i { - break - } - if !HasMore(params, j) { - count++ - } - } - - if count > i || j >= len(params) { - return nil - } - - var subs []int - for ; j < len(params); j++ { - if !HasMore(params, j) { - break - } - p := Param(params, j) - if p == -1 { - p = DefaultParamValue - } - subs = append(subs, p) - } - - p := Param(params, j) - if p == -1 { - p = DefaultParamValue - } - - return append(subs, p) -} - -// Len returns the number of parameters in the sequence. -// This will return the number of parameters in the sequence, excluding any -// sub-parameters. -func Len(params []int) int { - var n int - for i := 0; i < len(params); i++ { - if !HasMore(params, i) { - n++ - } - } - return n -} - -// Range iterates over the parameters of the sequence and calls the given -// function for each parameter. -// The function should return false to stop the iteration. -func Range(params []int, fn func(i int, param int, hasMore bool) bool) { - for i := 0; i < len(params); i++ { - if !fn(i, Param(params, i), HasMore(params, i)) { - break - } - } -} diff --git a/vendor/github.com/charmbracelet/x/ansi/parser/transition_table.go b/vendor/github.com/charmbracelet/x/ansi/parser/transition_table.go deleted file mode 100644 index 558a5eacca..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/parser/transition_table.go +++ /dev/null @@ -1,273 +0,0 @@ -package parser - -// Table values are generated like this: -// -// index: currentState << IndexStateShift | charCode -// value: action << TransitionActionShift | nextState -const ( - TransitionActionShift = 4 - TransitionStateMask = 15 - IndexStateShift = 8 - - // DefaultTableSize is the default size of the transition table. - DefaultTableSize = 4096 -) - -// Table is a DEC ANSI transition table. -var Table = GenerateTransitionTable() - -// TransitionTable is a DEC ANSI transition table. -// https://vt100.net/emu/dec_ansi_parser -type TransitionTable []byte - -// NewTransitionTable returns a new DEC ANSI transition table. -func NewTransitionTable(size int) TransitionTable { - if size <= 0 { - size = DefaultTableSize - } - return TransitionTable(make([]byte, size)) -} - -// SetDefault sets default transition. -func (t TransitionTable) SetDefault(action Action, state State) { - for i := 0; i < len(t); i++ { - t[i] = action<> TransitionActionShift -} - -// byte range macro -func r(start, end byte) []byte { - var a []byte - for i := int(start); i <= int(end); i++ { - a = append(a, byte(i)) - } - return a -} - -// GenerateTransitionTable generates a DEC ANSI transition table compatible -// with the VT500-series of terminals. This implementation includes a few -// modifications that include: -// - A new Utf8State is introduced to handle UTF8 sequences. -// - Osc and Dcs data accept UTF8 sequences by extending the printable range -// to 0xFF and 0xFE respectively. -// - We don't ignore 0x3A (':') when building Csi and Dcs parameters and -// instead use it to denote sub-parameters. -// - Support dispatching SosPmApc sequences. -// - The DEL (0x7F) character is executed in the Ground state. -// - The DEL (0x7F) character is collected in the DcsPassthrough string state. -// - The ST C1 control character (0x9C) is executed and not ignored. -func GenerateTransitionTable() TransitionTable { - table := NewTransitionTable(DefaultTableSize) - table.SetDefault(NoneAction, GroundState) - - // Anywhere - for _, state := range r(GroundState, Utf8State) { - // Anywhere -> Ground - table.AddMany([]byte{0x18, 0x1a, 0x99, 0x9a}, state, ExecuteAction, GroundState) - table.AddRange(0x80, 0x8F, state, ExecuteAction, GroundState) - table.AddRange(0x90, 0x97, state, ExecuteAction, GroundState) - table.AddOne(0x9C, state, ExecuteAction, GroundState) - // Anywhere -> Escape - table.AddOne(0x1B, state, ClearAction, EscapeState) - // Anywhere -> SosStringState - table.AddOne(0x98, state, StartAction, SosStringState) - // Anywhere -> PmStringState - table.AddOne(0x9E, state, StartAction, PmStringState) - // Anywhere -> ApcStringState - table.AddOne(0x9F, state, StartAction, ApcStringState) - // Anywhere -> CsiEntry - table.AddOne(0x9B, state, ClearAction, CsiEntryState) - // Anywhere -> DcsEntry - table.AddOne(0x90, state, ClearAction, DcsEntryState) - // Anywhere -> OscString - table.AddOne(0x9D, state, StartAction, OscStringState) - // Anywhere -> Utf8 - table.AddRange(0xC2, 0xDF, state, CollectAction, Utf8State) // UTF8 2 byte sequence - table.AddRange(0xE0, 0xEF, state, CollectAction, Utf8State) // UTF8 3 byte sequence - table.AddRange(0xF0, 0xF4, state, CollectAction, Utf8State) // UTF8 4 byte sequence - } - - // Ground - table.AddRange(0x00, 0x17, GroundState, ExecuteAction, GroundState) - table.AddOne(0x19, GroundState, ExecuteAction, GroundState) - table.AddRange(0x1C, 0x1F, GroundState, ExecuteAction, GroundState) - table.AddRange(0x20, 0x7E, GroundState, PrintAction, GroundState) - table.AddOne(0x7F, GroundState, ExecuteAction, GroundState) - - // EscapeIntermediate - table.AddRange(0x00, 0x17, EscapeIntermediateState, ExecuteAction, EscapeIntermediateState) - table.AddOne(0x19, EscapeIntermediateState, ExecuteAction, EscapeIntermediateState) - table.AddRange(0x1C, 0x1F, EscapeIntermediateState, ExecuteAction, EscapeIntermediateState) - table.AddRange(0x20, 0x2F, EscapeIntermediateState, CollectAction, EscapeIntermediateState) - table.AddOne(0x7F, EscapeIntermediateState, IgnoreAction, EscapeIntermediateState) - // EscapeIntermediate -> Ground - table.AddRange(0x30, 0x7E, EscapeIntermediateState, DispatchAction, GroundState) - - // Escape - table.AddRange(0x00, 0x17, EscapeState, ExecuteAction, EscapeState) - table.AddOne(0x19, EscapeState, ExecuteAction, EscapeState) - table.AddRange(0x1C, 0x1F, EscapeState, ExecuteAction, EscapeState) - table.AddOne(0x7F, EscapeState, IgnoreAction, EscapeState) - // Escape -> Ground - table.AddRange(0x30, 0x4F, EscapeState, DispatchAction, GroundState) - table.AddRange(0x51, 0x57, EscapeState, DispatchAction, GroundState) - table.AddOne(0x59, EscapeState, DispatchAction, GroundState) - table.AddOne(0x5A, EscapeState, DispatchAction, GroundState) - table.AddOne(0x5C, EscapeState, DispatchAction, GroundState) - table.AddRange(0x60, 0x7E, EscapeState, DispatchAction, GroundState) - // Escape -> Escape_intermediate - table.AddRange(0x20, 0x2F, EscapeState, CollectAction, EscapeIntermediateState) - // Escape -> Sos_pm_apc_string - table.AddOne('X', EscapeState, StartAction, SosStringState) // SOS - table.AddOne('^', EscapeState, StartAction, PmStringState) // PM - table.AddOne('_', EscapeState, StartAction, ApcStringState) // APC - // Escape -> Dcs_entry - table.AddOne('P', EscapeState, ClearAction, DcsEntryState) - // Escape -> Csi_entry - table.AddOne('[', EscapeState, ClearAction, CsiEntryState) - // Escape -> Osc_string - table.AddOne(']', EscapeState, StartAction, OscStringState) - - // Sos_pm_apc_string - for _, state := range r(SosStringState, ApcStringState) { - table.AddRange(0x00, 0x17, state, PutAction, state) - table.AddOne(0x19, state, PutAction, state) - table.AddRange(0x1C, 0x1F, state, PutAction, state) - table.AddRange(0x20, 0x7F, state, PutAction, state) - // ESC, ST, CAN, and SUB terminate the sequence - table.AddOne(0x1B, state, DispatchAction, EscapeState) - table.AddOne(0x9C, state, DispatchAction, GroundState) - table.AddMany([]byte{0x18, 0x1A}, state, IgnoreAction, GroundState) - } - - // Dcs_entry - table.AddRange(0x00, 0x07, DcsEntryState, IgnoreAction, DcsEntryState) - table.AddRange(0x0E, 0x17, DcsEntryState, IgnoreAction, DcsEntryState) - table.AddOne(0x19, DcsEntryState, IgnoreAction, DcsEntryState) - table.AddRange(0x1C, 0x1F, DcsEntryState, IgnoreAction, DcsEntryState) - table.AddOne(0x7F, DcsEntryState, IgnoreAction, DcsEntryState) - // Dcs_entry -> Dcs_intermediate - table.AddRange(0x20, 0x2F, DcsEntryState, CollectAction, DcsIntermediateState) - // Dcs_entry -> Dcs_param - table.AddRange(0x30, 0x3B, DcsEntryState, ParamAction, DcsParamState) - table.AddRange(0x3C, 0x3F, DcsEntryState, PrefixAction, DcsParamState) - // Dcs_entry -> Dcs_passthrough - table.AddRange(0x08, 0x0D, DcsEntryState, PutAction, DcsStringState) // Follows ECMA-48 § 8.3.27 - // XXX: allows passing ESC (not a ECMA-48 standard) this to allow for - // passthrough of ANSI sequences like in Screen or Tmux passthrough mode. - table.AddOne(0x1B, DcsEntryState, PutAction, DcsStringState) - table.AddRange(0x40, 0x7E, DcsEntryState, StartAction, DcsStringState) - - // Dcs_intermediate - table.AddRange(0x00, 0x17, DcsIntermediateState, IgnoreAction, DcsIntermediateState) - table.AddOne(0x19, DcsIntermediateState, IgnoreAction, DcsIntermediateState) - table.AddRange(0x1C, 0x1F, DcsIntermediateState, IgnoreAction, DcsIntermediateState) - table.AddRange(0x20, 0x2F, DcsIntermediateState, CollectAction, DcsIntermediateState) - table.AddOne(0x7F, DcsIntermediateState, IgnoreAction, DcsIntermediateState) - // Dcs_intermediate -> Dcs_passthrough - table.AddRange(0x30, 0x3F, DcsIntermediateState, StartAction, DcsStringState) - table.AddRange(0x40, 0x7E, DcsIntermediateState, StartAction, DcsStringState) - - // Dcs_param - table.AddRange(0x00, 0x17, DcsParamState, IgnoreAction, DcsParamState) - table.AddOne(0x19, DcsParamState, IgnoreAction, DcsParamState) - table.AddRange(0x1C, 0x1F, DcsParamState, IgnoreAction, DcsParamState) - table.AddRange(0x30, 0x3B, DcsParamState, ParamAction, DcsParamState) - table.AddOne(0x7F, DcsParamState, IgnoreAction, DcsParamState) - table.AddRange(0x3C, 0x3F, DcsParamState, IgnoreAction, DcsParamState) - // Dcs_param -> Dcs_intermediate - table.AddRange(0x20, 0x2F, DcsParamState, CollectAction, DcsIntermediateState) - // Dcs_param -> Dcs_passthrough - table.AddRange(0x40, 0x7E, DcsParamState, StartAction, DcsStringState) - - // Dcs_passthrough - table.AddRange(0x00, 0x17, DcsStringState, PutAction, DcsStringState) - table.AddOne(0x19, DcsStringState, PutAction, DcsStringState) - table.AddRange(0x1C, 0x1F, DcsStringState, PutAction, DcsStringState) - table.AddRange(0x20, 0x7E, DcsStringState, PutAction, DcsStringState) - table.AddOne(0x7F, DcsStringState, PutAction, DcsStringState) - table.AddRange(0x80, 0xFF, DcsStringState, PutAction, DcsStringState) // Allow Utf8 characters by extending the printable range from 0x7F to 0xFF - // ST, CAN, SUB, and ESC terminate the sequence - table.AddOne(0x1B, DcsStringState, DispatchAction, EscapeState) - table.AddOne(0x9C, DcsStringState, DispatchAction, GroundState) - table.AddMany([]byte{0x18, 0x1A}, DcsStringState, IgnoreAction, GroundState) - - // Csi_param - table.AddRange(0x00, 0x17, CsiParamState, ExecuteAction, CsiParamState) - table.AddOne(0x19, CsiParamState, ExecuteAction, CsiParamState) - table.AddRange(0x1C, 0x1F, CsiParamState, ExecuteAction, CsiParamState) - table.AddRange(0x30, 0x3B, CsiParamState, ParamAction, CsiParamState) - table.AddOne(0x7F, CsiParamState, IgnoreAction, CsiParamState) - table.AddRange(0x3C, 0x3F, CsiParamState, IgnoreAction, CsiParamState) - // Csi_param -> Ground - table.AddRange(0x40, 0x7E, CsiParamState, DispatchAction, GroundState) - // Csi_param -> Csi_intermediate - table.AddRange(0x20, 0x2F, CsiParamState, CollectAction, CsiIntermediateState) - - // Csi_intermediate - table.AddRange(0x00, 0x17, CsiIntermediateState, ExecuteAction, CsiIntermediateState) - table.AddOne(0x19, CsiIntermediateState, ExecuteAction, CsiIntermediateState) - table.AddRange(0x1C, 0x1F, CsiIntermediateState, ExecuteAction, CsiIntermediateState) - table.AddRange(0x20, 0x2F, CsiIntermediateState, CollectAction, CsiIntermediateState) - table.AddOne(0x7F, CsiIntermediateState, IgnoreAction, CsiIntermediateState) - // Csi_intermediate -> Ground - table.AddRange(0x40, 0x7E, CsiIntermediateState, DispatchAction, GroundState) - // Csi_intermediate -> Csi_ignore - table.AddRange(0x30, 0x3F, CsiIntermediateState, IgnoreAction, GroundState) - - // Csi_entry - table.AddRange(0x00, 0x17, CsiEntryState, ExecuteAction, CsiEntryState) - table.AddOne(0x19, CsiEntryState, ExecuteAction, CsiEntryState) - table.AddRange(0x1C, 0x1F, CsiEntryState, ExecuteAction, CsiEntryState) - table.AddOne(0x7F, CsiEntryState, IgnoreAction, CsiEntryState) - // Csi_entry -> Ground - table.AddRange(0x40, 0x7E, CsiEntryState, DispatchAction, GroundState) - // Csi_entry -> Csi_intermediate - table.AddRange(0x20, 0x2F, CsiEntryState, CollectAction, CsiIntermediateState) - // Csi_entry -> Csi_param - table.AddRange(0x30, 0x3B, CsiEntryState, ParamAction, CsiParamState) - table.AddRange(0x3C, 0x3F, CsiEntryState, PrefixAction, CsiParamState) - - // Osc_string - table.AddRange(0x00, 0x06, OscStringState, IgnoreAction, OscStringState) - table.AddRange(0x08, 0x17, OscStringState, IgnoreAction, OscStringState) - table.AddOne(0x19, OscStringState, IgnoreAction, OscStringState) - table.AddRange(0x1C, 0x1F, OscStringState, IgnoreAction, OscStringState) - table.AddRange(0x20, 0xFF, OscStringState, PutAction, OscStringState) // Allow Utf8 characters by extending the printable range from 0x7F to 0xFF - - // ST, CAN, SUB, ESC, and BEL terminate the sequence - table.AddOne(0x1B, OscStringState, DispatchAction, EscapeState) - table.AddOne(0x07, OscStringState, DispatchAction, GroundState) - table.AddOne(0x9C, OscStringState, DispatchAction, GroundState) - table.AddMany([]byte{0x18, 0x1A}, OscStringState, IgnoreAction, GroundState) - - return table -} diff --git a/vendor/github.com/charmbracelet/x/ansi/parser_decode.go b/vendor/github.com/charmbracelet/x/ansi/parser_decode.go deleted file mode 100644 index 3e50473947..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/parser_decode.go +++ /dev/null @@ -1,524 +0,0 @@ -package ansi - -import ( - "unicode/utf8" - - "github.com/charmbracelet/x/ansi/parser" - "github.com/mattn/go-runewidth" - "github.com/rivo/uniseg" -) - -// State represents the state of the ANSI escape sequence parser used by -// [DecodeSequence]. -type State = byte - -// ANSI escape sequence states used by [DecodeSequence]. -const ( - NormalState State = iota - PrefixState - ParamsState - IntermedState - EscapeState - StringState -) - -// DecodeSequence decodes the first ANSI escape sequence or a printable -// grapheme from the given data. It returns the sequence slice, the number of -// bytes read, the cell width for each sequence, and the new state. -// -// The cell width will always be 0 for control and escape sequences, 1 for -// ASCII printable characters, and the number of cells other Unicode characters -// occupy. It uses the uniseg package to calculate the width of Unicode -// graphemes and characters. This means it will always do grapheme clustering -// (mode 2027). -// -// Passing a non-nil [*Parser] as the last argument will allow the decoder to -// collect sequence parameters, data, and commands. The parser cmd will have -// the packed command value that contains intermediate and prefix characters. -// In the case of a OSC sequence, the cmd will be the OSC command number. Use -// [Cmd] and [Param] types to unpack command intermediates and prefixes as well -// as parameters. -// -// Zero [Cmd] means the CSI, DCS, or ESC sequence is invalid. Moreover, checking the -// validity of other data sequences, OSC, DCS, etc, will require checking for -// the returned sequence terminator bytes such as ST (ESC \\) and BEL). -// -// We store the command byte in [Cmd] in the most significant byte, the -// prefix byte in the next byte, and the intermediate byte in the least -// significant byte. This is done to avoid using a struct to store the command -// and its intermediates and prefixes. The command byte is always the least -// significant byte i.e. [Cmd & 0xff]. Use the [Cmd] type to unpack the -// command, intermediate, and prefix bytes. Note that we only collect the last -// prefix character and intermediate byte. -// -// The [p.Params] slice will contain the parameters of the sequence. Any -// sub-parameter will have the [parser.HasMoreFlag] set. Use the [Param] type -// to unpack the parameters. -// -// Example: -// -// var state byte // the initial state is always zero [NormalState] -// p := NewParser(32, 1024) // create a new parser with a 32 params buffer and 1024 data buffer (optional) -// input := []byte("\x1b[31mHello, World!\x1b[0m") -// for len(input) > 0 { -// seq, width, n, newState := DecodeSequence(input, state, p) -// log.Printf("seq: %q, width: %d", seq, width) -// state = newState -// input = input[n:] -// } -// -// This function treats the text as a sequence of grapheme clusters. -func DecodeSequence[T string | []byte](b T, state byte, p *Parser) (seq T, width int, n int, newState byte) { - return decodeSequence(GraphemeWidth, b, state, p) -} - -// DecodeSequenceWc decodes the first ANSI escape sequence or a printable -// grapheme from the given data. It returns the sequence slice, the number of -// bytes read, the cell width for each sequence, and the new state. -// -// The cell width will always be 0 for control and escape sequences, 1 for -// ASCII printable characters, and the number of cells other Unicode characters -// occupy. It uses the uniseg package to calculate the width of Unicode -// graphemes and characters. This means it will always do grapheme clustering -// (mode 2027). -// -// Passing a non-nil [*Parser] as the last argument will allow the decoder to -// collect sequence parameters, data, and commands. The parser cmd will have -// the packed command value that contains intermediate and prefix characters. -// In the case of a OSC sequence, the cmd will be the OSC command number. Use -// [Cmd] and [Param] types to unpack command intermediates and prefixes as well -// as parameters. -// -// Zero [Cmd] means the CSI, DCS, or ESC sequence is invalid. Moreover, checking the -// validity of other data sequences, OSC, DCS, etc, will require checking for -// the returned sequence terminator bytes such as ST (ESC \\) and BEL). -// -// We store the command byte in [Cmd] in the most significant byte, the -// prefix byte in the next byte, and the intermediate byte in the least -// significant byte. This is done to avoid using a struct to store the command -// and its intermediates and prefixes. The command byte is always the least -// significant byte i.e. [Cmd & 0xff]. Use the [Cmd] type to unpack the -// command, intermediate, and prefix bytes. Note that we only collect the last -// prefix character and intermediate byte. -// -// The [p.Params] slice will contain the parameters of the sequence. Any -// sub-parameter will have the [parser.HasMoreFlag] set. Use the [Param] type -// to unpack the parameters. -// -// Example: -// -// var state byte // the initial state is always zero [NormalState] -// p := NewParser(32, 1024) // create a new parser with a 32 params buffer and 1024 data buffer (optional) -// input := []byte("\x1b[31mHello, World!\x1b[0m") -// for len(input) > 0 { -// seq, width, n, newState := DecodeSequenceWc(input, state, p) -// log.Printf("seq: %q, width: %d", seq, width) -// state = newState -// input = input[n:] -// } -// -// This function treats the text as a sequence of wide characters and runes. -func DecodeSequenceWc[T string | []byte](b T, state byte, p *Parser) (seq T, width int, n int, newState byte) { - return decodeSequence(WcWidth, b, state, p) -} - -func decodeSequence[T string | []byte](m Method, b T, state State, p *Parser) (seq T, width int, n int, newState byte) { - for i := 0; i < len(b); i++ { - c := b[i] - - switch state { - case NormalState: - switch c { - case ESC: - if p != nil { - if len(p.params) > 0 { - p.params[0] = parser.MissingParam - } - p.cmd = 0 - p.paramsLen = 0 - p.dataLen = 0 - } - state = EscapeState - continue - case CSI, DCS: - if p != nil { - if len(p.params) > 0 { - p.params[0] = parser.MissingParam - } - p.cmd = 0 - p.paramsLen = 0 - p.dataLen = 0 - } - state = PrefixState - continue - case OSC, APC, SOS, PM: - if p != nil { - p.cmd = parser.MissingCommand - p.dataLen = 0 - } - state = StringState - continue - } - - if p != nil { - p.dataLen = 0 - p.paramsLen = 0 - p.cmd = 0 - } - if c > US && c < DEL { - // ASCII printable characters - return b[i : i+1], 1, 1, NormalState - } - - if c <= US || c == DEL || c < 0xC0 { - // C0 & C1 control characters & DEL - return b[i : i+1], 0, 1, NormalState - } - - if utf8.RuneStart(c) { - seq, _, width, _ = FirstGraphemeCluster(b, -1) - if m == WcWidth { - width = runewidth.StringWidth(string(seq)) - } - i += len(seq) - return b[:i], width, i, NormalState - } - - // Invalid UTF-8 sequence - return b[:i], 0, i, NormalState - case PrefixState: - if c >= '<' && c <= '?' { - if p != nil { - // We only collect the last prefix character. - p.cmd &^= 0xff << parser.PrefixShift - p.cmd |= int(c) << parser.PrefixShift - } - break - } - - state = ParamsState - fallthrough - case ParamsState: - if c >= '0' && c <= '9' { - if p != nil { - if p.params[p.paramsLen] == parser.MissingParam { - p.params[p.paramsLen] = 0 - } - - p.params[p.paramsLen] *= 10 - p.params[p.paramsLen] += int(c - '0') - } - break - } - - if c == ':' { - if p != nil { - p.params[p.paramsLen] |= parser.HasMoreFlag - } - } - - if c == ';' || c == ':' { - if p != nil { - p.paramsLen++ - if p.paramsLen < len(p.params) { - p.params[p.paramsLen] = parser.MissingParam - } - } - break - } - - state = IntermedState - fallthrough - case IntermedState: - if c >= ' ' && c <= '/' { - if p != nil { - p.cmd &^= 0xff << parser.IntermedShift - p.cmd |= int(c) << parser.IntermedShift - } - break - } - - if p != nil { - // Increment the last parameter - if p.paramsLen > 0 && p.paramsLen < len(p.params)-1 || - p.paramsLen == 0 && len(p.params) > 0 && p.params[0] != parser.MissingParam { - p.paramsLen++ - } - } - - if c >= '@' && c <= '~' { - if p != nil { - p.cmd &^= 0xff - p.cmd |= int(c) - } - - if HasDcsPrefix(b) { - // Continue to collect DCS data - if p != nil { - p.dataLen = 0 - } - state = StringState - continue - } - - return b[:i+1], 0, i + 1, NormalState - } - - // Invalid CSI/DCS sequence - return b[:i], 0, i, NormalState - case EscapeState: - switch c { - case '[', 'P': - if p != nil { - if len(p.params) > 0 { - p.params[0] = parser.MissingParam - } - p.paramsLen = 0 - p.cmd = 0 - } - state = PrefixState - continue - case ']', 'X', '^', '_': - if p != nil { - p.cmd = parser.MissingCommand - p.dataLen = 0 - } - state = StringState - continue - } - - if c >= ' ' && c <= '/' { - if p != nil { - p.cmd &^= 0xff << parser.IntermedShift - p.cmd |= int(c) << parser.IntermedShift - } - continue - } else if c >= '0' && c <= '~' { - if p != nil { - p.cmd &^= 0xff - p.cmd |= int(c) - } - return b[:i+1], 0, i + 1, NormalState - } - - // Invalid escape sequence - return b[:i], 0, i, NormalState - case StringState: - switch c { - case BEL: - if HasOscPrefix(b) { - parseOscCmd(p) - return b[:i+1], 0, i + 1, NormalState - } - case CAN, SUB: - if HasOscPrefix(b) { - // Ensure we parse the OSC command number - parseOscCmd(p) - } - - // Cancel the sequence - return b[:i], 0, i, NormalState - case ST: - if HasOscPrefix(b) { - // Ensure we parse the OSC command number - parseOscCmd(p) - } - - return b[:i+1], 0, i + 1, NormalState - case ESC: - if HasStPrefix(b[i:]) { - if HasOscPrefix(b) { - // Ensure we parse the OSC command number - parseOscCmd(p) - } - - // End of string 7-bit (ST) - return b[:i+2], 0, i + 2, NormalState - } - - // Otherwise, cancel the sequence - return b[:i], 0, i, NormalState - } - - if p != nil && p.dataLen < len(p.data) { - p.data[p.dataLen] = c - p.dataLen++ - - // Parse the OSC command number - if c == ';' && HasOscPrefix(b) { - parseOscCmd(p) - } - } - } - } - - return b, 0, len(b), state -} - -func parseOscCmd(p *Parser) { - if p == nil || p.cmd != parser.MissingCommand { - return - } - for j := 0; j < p.dataLen; j++ { - d := p.data[j] - if d < '0' || d > '9' { - break - } - if p.cmd == parser.MissingCommand { - p.cmd = 0 - } - p.cmd *= 10 - p.cmd += int(d - '0') - } -} - -// Equal returns true if the given byte slices are equal. -func Equal[T string | []byte](a, b T) bool { - return string(a) == string(b) -} - -// HasPrefix returns true if the given byte slice has prefix. -func HasPrefix[T string | []byte](b, prefix T) bool { - return len(b) >= len(prefix) && Equal(b[0:len(prefix)], prefix) -} - -// HasSuffix returns true if the given byte slice has suffix. -func HasSuffix[T string | []byte](b, suffix T) bool { - return len(b) >= len(suffix) && Equal(b[len(b)-len(suffix):], suffix) -} - -// HasCsiPrefix returns true if the given byte slice has a CSI prefix. -func HasCsiPrefix[T string | []byte](b T) bool { - return (len(b) > 0 && b[0] == CSI) || - (len(b) > 1 && b[0] == ESC && b[1] == '[') -} - -// HasOscPrefix returns true if the given byte slice has an OSC prefix. -func HasOscPrefix[T string | []byte](b T) bool { - return (len(b) > 0 && b[0] == OSC) || - (len(b) > 1 && b[0] == ESC && b[1] == ']') -} - -// HasApcPrefix returns true if the given byte slice has an APC prefix. -func HasApcPrefix[T string | []byte](b T) bool { - return (len(b) > 0 && b[0] == APC) || - (len(b) > 1 && b[0] == ESC && b[1] == '_') -} - -// HasDcsPrefix returns true if the given byte slice has a DCS prefix. -func HasDcsPrefix[T string | []byte](b T) bool { - return (len(b) > 0 && b[0] == DCS) || - (len(b) > 1 && b[0] == ESC && b[1] == 'P') -} - -// HasSosPrefix returns true if the given byte slice has a SOS prefix. -func HasSosPrefix[T string | []byte](b T) bool { - return (len(b) > 0 && b[0] == SOS) || - (len(b) > 1 && b[0] == ESC && b[1] == 'X') -} - -// HasPmPrefix returns true if the given byte slice has a PM prefix. -func HasPmPrefix[T string | []byte](b T) bool { - return (len(b) > 0 && b[0] == PM) || - (len(b) > 1 && b[0] == ESC && b[1] == '^') -} - -// HasStPrefix returns true if the given byte slice has a ST prefix. -func HasStPrefix[T string | []byte](b T) bool { - return (len(b) > 0 && b[0] == ST) || - (len(b) > 1 && b[0] == ESC && b[1] == '\\') -} - -// HasEscPrefix returns true if the given byte slice has an ESC prefix. -func HasEscPrefix[T string | []byte](b T) bool { - return len(b) > 0 && b[0] == ESC -} - -// FirstGraphemeCluster returns the first grapheme cluster in the given string or byte slice. -// This is a syntactic sugar function that wraps -// uniseg.FirstGraphemeClusterInString and uniseg.FirstGraphemeCluster. -func FirstGraphemeCluster[T string | []byte](b T, state int) (T, T, int, int) { - switch b := any(b).(type) { - case string: - cluster, rest, width, newState := uniseg.FirstGraphemeClusterInString(b, state) - return T(cluster), T(rest), width, newState - case []byte: - cluster, rest, width, newState := uniseg.FirstGraphemeCluster(b, state) - return T(cluster), T(rest), width, newState - } - panic("unreachable") -} - -// Cmd represents a sequence command. This is used to pack/unpack a sequence -// command with its intermediate and prefix characters. Those are commonly -// found in CSI and DCS sequences. -type Cmd int - -// Prefix returns the unpacked prefix byte of the CSI sequence. -// This is always gonna be one of the following '<' '=' '>' '?' and in the -// range of 0x3C-0x3F. -// Zero is returned if the sequence does not have a prefix. -func (c Cmd) Prefix() byte { - return byte(parser.Prefix(int(c))) -} - -// Intermediate returns the unpacked intermediate byte of the CSI sequence. -// An intermediate byte is in the range of 0x20-0x2F. This includes these -// characters from ' ', '!', '"', '#', '$', '%', '&', ”', '(', ')', '*', '+', -// ',', '-', '.', '/'. -// Zero is returned if the sequence does not have an intermediate byte. -func (c Cmd) Intermediate() byte { - return byte(parser.Intermediate(int(c))) -} - -// Final returns the unpacked command byte of the CSI sequence. -func (c Cmd) Final() byte { - return byte(parser.Command(int(c))) -} - -// Command packs a command with the given prefix, intermediate, and final. A -// zero byte means the sequence does not have a prefix or intermediate. -// -// Prefixes are in the range of 0x3C-0x3F that is one of `<=>?`. -// -// Intermediates are in the range of 0x20-0x2F that is anything in -// `!"#$%&'()*+,-./`. -// -// Final bytes are in the range of 0x40-0x7E that is anything in the range -// `@A–Z[\]^_`a–z{|}~`. -func Command(prefix, inter, final byte) (c int) { - c = int(final) - c |= int(prefix) << parser.PrefixShift - c |= int(inter) << parser.IntermedShift - return -} - -// Param represents a sequence parameter. Sequence parameters with -// sub-parameters are packed with the HasMoreFlag set. This is used to unpack -// the parameters from a CSI and DCS sequences. -type Param int - -// Param returns the unpacked parameter at the given index. -// It returns the default value if the parameter is missing. -func (s Param) Param(def int) int { - p := int(s) & parser.ParamMask - if p == parser.MissingParam { - return def - } - return p -} - -// HasMore unpacks the HasMoreFlag from the parameter. -func (s Param) HasMore() bool { - return s&parser.HasMoreFlag != 0 -} - -// Parameter packs an escape code parameter with the given parameter and -// whether this parameter has following sub-parameters. -func Parameter(p int, hasMore bool) (s int) { - s = p & parser.ParamMask - if hasMore { - s |= parser.HasMoreFlag - } - return -} diff --git a/vendor/github.com/charmbracelet/x/ansi/parser_handler.go b/vendor/github.com/charmbracelet/x/ansi/parser_handler.go deleted file mode 100644 index 03f9ed4cbd..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/parser_handler.go +++ /dev/null @@ -1,60 +0,0 @@ -package ansi - -import "unsafe" - -// Params represents a list of packed parameters. -type Params []Param - -// Param returns the parameter at the given index and if it is part of a -// sub-parameters. It falls back to the default value if the parameter is -// missing. If the index is out of bounds, it returns the default value and -// false. -func (p Params) Param(i, def int) (int, bool, bool) { - if i < 0 || i >= len(p) { - return def, false, false - } - return p[i].Param(def), p[i].HasMore(), true -} - -// ForEach iterates over the parameters and calls the given function for each -// parameter. If a parameter is part of a sub-parameter, it will be called with -// hasMore set to true. -// Use def to set a default value for missing parameters. -func (p Params) ForEach(def int, f func(i, param int, hasMore bool)) { - for i := range p { - f(i, p[i].Param(def), p[i].HasMore()) - } -} - -// ToParams converts a list of integers to a list of parameters. -func ToParams(params []int) Params { - return unsafe.Slice((*Param)(unsafe.Pointer(¶ms[0])), len(params)) -} - -// Handler handles actions performed by the parser. -// It is used to handle ANSI escape sequences, control characters, and runes. -type Handler struct { - // Print is called when a printable rune is encountered. - Print func(r rune) - // Execute is called when a control character is encountered. - Execute func(b byte) - // HandleCsi is called when a CSI sequence is encountered. - HandleCsi func(cmd Cmd, params Params) - // HandleEsc is called when an ESC sequence is encountered. - HandleEsc func(cmd Cmd) - // HandleDcs is called when a DCS sequence is encountered. - HandleDcs func(cmd Cmd, params Params, data []byte) - // HandleOsc is called when an OSC sequence is encountered. - HandleOsc func(cmd int, data []byte) - // HandlePm is called when a PM sequence is encountered. - HandlePm func(data []byte) - // HandleApc is called when an APC sequence is encountered. - HandleApc func(data []byte) - // HandleSos is called when a SOS sequence is encountered. - HandleSos func(data []byte) -} - -// SetHandler sets the handler for the parser. -func (p *Parser) SetHandler(h Handler) { - p.handler = h -} diff --git a/vendor/github.com/charmbracelet/x/ansi/parser_sync.go b/vendor/github.com/charmbracelet/x/ansi/parser_sync.go deleted file mode 100644 index 65d25a9a6a..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/parser_sync.go +++ /dev/null @@ -1,29 +0,0 @@ -package ansi - -import ( - "sync" - - "github.com/charmbracelet/x/ansi/parser" -) - -var parserPool = sync.Pool{ - New: func() any { - p := NewParser() - p.SetParamsSize(parser.MaxParamsSize) - p.SetDataSize(1024 * 1024 * 4) // 4MB of data buffer - return p - }, -} - -// GetParser returns a parser from a sync pool. -func GetParser() *Parser { - return parserPool.Get().(*Parser) -} - -// PutParser returns a parser to a sync pool. The parser is reset -// automatically. -func PutParser(p *Parser) { - p.Reset() - p.dataLen = 0 - parserPool.Put(p) -} diff --git a/vendor/github.com/charmbracelet/x/ansi/passthrough.go b/vendor/github.com/charmbracelet/x/ansi/passthrough.go deleted file mode 100644 index 14a7452205..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/passthrough.go +++ /dev/null @@ -1,63 +0,0 @@ -package ansi - -import ( - "bytes" -) - -// ScreenPassthrough wraps the given ANSI sequence in a DCS passthrough -// sequence to be sent to the outer terminal. This is used to send raw escape -// sequences to the outer terminal when running inside GNU Screen. -// -// DCS ST -// -// Note: Screen limits the length of string sequences to 768 bytes (since 2014). -// Use zero to indicate no limit, otherwise, this will chunk the returned -// string into limit sized chunks. -// -// See: https://www.gnu.org/software/screen/manual/screen.html#String-Escapes -// See: https://git.savannah.gnu.org/cgit/screen.git/tree/src/screen.h?id=c184c6ec27683ff1a860c45be5cf520d896fd2ef#n44 -func ScreenPassthrough(seq string, limit int) string { - var b bytes.Buffer - b.WriteString("\x1bP") - if limit > 0 { - for i := 0; i < len(seq); i += limit { - end := i + limit - if end > len(seq) { - end = len(seq) - } - b.WriteString(seq[i:end]) - if end < len(seq) { - b.WriteString("\x1b\\\x1bP") - } - } - } else { - b.WriteString(seq) - } - b.WriteString("\x1b\\") - return b.String() -} - -// TmuxPassthrough wraps the given ANSI sequence in a special DCS passthrough -// sequence to be sent to the outer terminal. This is used to send raw escape -// sequences to the outer terminal when running inside Tmux. -// -// DCS tmux ; ST -// -// Where is the given sequence in which all occurrences of ESC -// (0x1b) are doubled i.e. replaced with ESC ESC (0x1b 0x1b). -// -// Note: this needs the `allow-passthrough` option to be set to `on`. -// -// See: https://github.com/tmux/tmux/wiki/FAQ#what-is-the-passthrough-escape-sequence-and-how-do-i-use-it -func TmuxPassthrough(seq string) string { - var b bytes.Buffer - b.WriteString("\x1bPtmux;") - for i := 0; i < len(seq); i++ { - if seq[i] == ESC { - b.WriteByte(ESC) - } - b.WriteByte(seq[i]) - } - b.WriteString("\x1b\\") - return b.String() -} diff --git a/vendor/github.com/charmbracelet/x/ansi/paste.go b/vendor/github.com/charmbracelet/x/ansi/paste.go deleted file mode 100644 index 2f9ea6f79e..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/paste.go +++ /dev/null @@ -1,7 +0,0 @@ -package ansi - -// BracketedPasteStart is the control sequence to enable bracketed paste mode. -const BracketedPasteStart = "\x1b[200~" - -// BracketedPasteEnd is the control sequence to disable bracketed paste mode. -const BracketedPasteEnd = "\x1b[201~" diff --git a/vendor/github.com/charmbracelet/x/ansi/reset.go b/vendor/github.com/charmbracelet/x/ansi/reset.go deleted file mode 100644 index c1b89ea493..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/reset.go +++ /dev/null @@ -1,11 +0,0 @@ -package ansi - -// ResetInitialState (RIS) resets the terminal to its initial state. -// -// ESC c -// -// See: https://vt100.net/docs/vt510-rm/RIS.html -const ( - ResetInitialState = "\x1bc" - RIS = ResetInitialState -) diff --git a/vendor/github.com/charmbracelet/x/ansi/screen.go b/vendor/github.com/charmbracelet/x/ansi/screen.go deleted file mode 100644 index c76e4f0d68..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/screen.go +++ /dev/null @@ -1,410 +0,0 @@ -package ansi - -import ( - "strconv" - "strings" -) - -// EraseDisplay (ED) clears the display or parts of the display. A screen is -// the shown part of the terminal display excluding the scrollback buffer. -// Possible values: -// -// Default is 0. -// -// 0: Clear from cursor to end of screen. -// 1: Clear from cursor to beginning of the screen. -// 2: Clear entire screen (and moves cursor to upper left on DOS). -// 3: Clear entire display which delete all lines saved in the scrollback buffer (xterm). -// -// CSI J -// -// See: https://vt100.net/docs/vt510-rm/ED.html -func EraseDisplay(n int) string { - var s string - if n > 0 { - s = strconv.Itoa(n) - } - return "\x1b[" + s + "J" -} - -// ED is an alias for [EraseDisplay]. -func ED(n int) string { - return EraseDisplay(n) -} - -// EraseDisplay constants. -// These are the possible values for the EraseDisplay function. -const ( - EraseScreenBelow = "\x1b[J" - EraseScreenAbove = "\x1b[1J" - EraseEntireScreen = "\x1b[2J" - EraseEntireDisplay = "\x1b[3J" -) - -// EraseLine (EL) clears the current line or parts of the line. Possible values: -// -// 0: Clear from cursor to end of line. -// 1: Clear from cursor to beginning of the line. -// 2: Clear entire line. -// -// The cursor position is not affected. -// -// CSI K -// -// See: https://vt100.net/docs/vt510-rm/EL.html -func EraseLine(n int) string { - var s string - if n > 0 { - s = strconv.Itoa(n) - } - return "\x1b[" + s + "K" -} - -// EL is an alias for [EraseLine]. -func EL(n int) string { - return EraseLine(n) -} - -// EraseLine constants. -// These are the possible values for the EraseLine function. -const ( - EraseLineRight = "\x1b[K" - EraseLineLeft = "\x1b[1K" - EraseEntireLine = "\x1b[2K" -) - -// ScrollUp (SU) scrolls the screen up n lines. New lines are added at the -// bottom of the screen. -// -// CSI Pn S -// -// See: https://vt100.net/docs/vt510-rm/SU.html -func ScrollUp(n int) string { - var s string - if n > 1 { - s = strconv.Itoa(n) - } - return "\x1b[" + s + "S" -} - -// PanDown is an alias for [ScrollUp]. -func PanDown(n int) string { - return ScrollUp(n) -} - -// SU is an alias for [ScrollUp]. -func SU(n int) string { - return ScrollUp(n) -} - -// ScrollDown (SD) scrolls the screen down n lines. New lines are added at the -// top of the screen. -// -// CSI Pn T -// -// See: https://vt100.net/docs/vt510-rm/SD.html -func ScrollDown(n int) string { - var s string - if n > 1 { - s = strconv.Itoa(n) - } - return "\x1b[" + s + "T" -} - -// PanUp is an alias for [ScrollDown]. -func PanUp(n int) string { - return ScrollDown(n) -} - -// SD is an alias for [ScrollDown]. -func SD(n int) string { - return ScrollDown(n) -} - -// InsertLine (IL) inserts n blank lines at the current cursor position. -// Existing lines are moved down. -// -// CSI Pn L -// -// See: https://vt100.net/docs/vt510-rm/IL.html -func InsertLine(n int) string { - var s string - if n > 1 { - s = strconv.Itoa(n) - } - return "\x1b[" + s + "L" -} - -// IL is an alias for [InsertLine]. -func IL(n int) string { - return InsertLine(n) -} - -// DeleteLine (DL) deletes n lines at the current cursor position. Existing -// lines are moved up. -// -// CSI Pn M -// -// See: https://vt100.net/docs/vt510-rm/DL.html -func DeleteLine(n int) string { - var s string - if n > 1 { - s = strconv.Itoa(n) - } - return "\x1b[" + s + "M" -} - -// DL is an alias for [DeleteLine]. -func DL(n int) string { - return DeleteLine(n) -} - -// SetTopBottomMargins (DECSTBM) sets the top and bottom margins for the scrolling -// region. The default is the entire screen. -// -// Default is 1 and the bottom of the screen. -// -// CSI Pt ; Pb r -// -// See: https://vt100.net/docs/vt510-rm/DECSTBM.html -func SetTopBottomMargins(top, bot int) string { - var t, b string - if top > 0 { - t = strconv.Itoa(top) - } - if bot > 0 { - b = strconv.Itoa(bot) - } - return "\x1b[" + t + ";" + b + "r" -} - -// DECSTBM is an alias for [SetTopBottomMargins]. -func DECSTBM(top, bot int) string { - return SetTopBottomMargins(top, bot) -} - -// SetLeftRightMargins (DECSLRM) sets the left and right margins for the scrolling -// region. -// -// Default is 1 and the right of the screen. -// -// CSI Pl ; Pr s -// -// See: https://vt100.net/docs/vt510-rm/DECSLRM.html -func SetLeftRightMargins(left, right int) string { - var l, r string - if left > 0 { - l = strconv.Itoa(left) - } - if right > 0 { - r = strconv.Itoa(right) - } - return "\x1b[" + l + ";" + r + "s" -} - -// DECSLRM is an alias for [SetLeftRightMargins]. -func DECSLRM(left, right int) string { - return SetLeftRightMargins(left, right) -} - -// SetScrollingRegion (DECSTBM) sets the top and bottom margins for the scrolling -// region. The default is the entire screen. -// -// CSI ; r -// -// See: https://vt100.net/docs/vt510-rm/DECSTBM.html -// -// Deprecated: use [SetTopBottomMargins] instead. -func SetScrollingRegion(t, b int) string { - if t < 0 { - t = 0 - } - if b < 0 { - b = 0 - } - return "\x1b[" + strconv.Itoa(t) + ";" + strconv.Itoa(b) + "r" -} - -// InsertCharacter (ICH) inserts n blank characters at the current cursor -// position. Existing characters move to the right. Characters moved past the -// right margin are lost. ICH has no effect outside the scrolling margins. -// -// Default is 1. -// -// CSI Pn @ -// -// See: https://vt100.net/docs/vt510-rm/ICH.html -func InsertCharacter(n int) string { - var s string - if n > 1 { - s = strconv.Itoa(n) - } - return "\x1b[" + s + "@" -} - -// ICH is an alias for [InsertCharacter]. -func ICH(n int) string { - return InsertCharacter(n) -} - -// DeleteCharacter (DCH) deletes n characters at the current cursor position. -// As the characters are deleted, the remaining characters move to the left and -// the cursor remains at the same position. -// -// Default is 1. -// -// CSI Pn P -// -// See: https://vt100.net/docs/vt510-rm/DCH.html -func DeleteCharacter(n int) string { - var s string - if n > 1 { - s = strconv.Itoa(n) - } - return "\x1b[" + s + "P" -} - -// DCH is an alias for [DeleteCharacter]. -func DCH(n int) string { - return DeleteCharacter(n) -} - -// SetTabEvery8Columns (DECST8C) sets the tab stops at every 8 columns. -// -// CSI ? 5 W -// -// See: https://vt100.net/docs/vt510-rm/DECST8C.html -const ( - SetTabEvery8Columns = "\x1b[?5W" - DECST8C = SetTabEvery8Columns -) - -// HorizontalTabSet (HTS) sets a horizontal tab stop at the current cursor -// column. -// -// This is equivalent to [HTS]. -// -// ESC H -// -// See: https://vt100.net/docs/vt510-rm/HTS.html -const HorizontalTabSet = "\x1bH" - -// TabClear (TBC) clears tab stops. -// -// Default is 0. -// -// Possible values: -// 0: Clear tab stop at the current column. (default) -// 3: Clear all tab stops. -// -// CSI Pn g -// -// See: https://vt100.net/docs/vt510-rm/TBC.html -func TabClear(n int) string { - var s string - if n > 0 { - s = strconv.Itoa(n) - } - return "\x1b[" + s + "g" -} - -// TBC is an alias for [TabClear]. -func TBC(n int) string { - return TabClear(n) -} - -// RequestPresentationStateReport (DECRQPSR) requests the terminal to send a -// report of the presentation state. This includes the cursor information [DECCIR], -// and tab stop [DECTABSR] reports. -// -// Default is 0. -// -// Possible values: -// 0: Error, request ignored. -// 1: Cursor information report [DECCIR]. -// 2: Tab stop report [DECTABSR]. -// -// CSI Ps $ w -// -// See: https://vt100.net/docs/vt510-rm/DECRQPSR.html -func RequestPresentationStateReport(n int) string { - var s string - if n > 0 { - s = strconv.Itoa(n) - } - return "\x1b[" + s + "$w" -} - -// DECRQPSR is an alias for [RequestPresentationStateReport]. -func DECRQPSR(n int) string { - return RequestPresentationStateReport(n) -} - -// TabStopReport (DECTABSR) is the response to a tab stop report request. -// It reports the tab stops set in the terminal. -// -// The response is a list of tab stops separated by a slash (/) character. -// -// DCS 2 $ u D ... D ST -// -// Where D is a decimal number representing a tab stop. -// -// See: https://vt100.net/docs/vt510-rm/DECTABSR.html -func TabStopReport(stops ...int) string { - var s []string - for _, v := range stops { - s = append(s, strconv.Itoa(v)) - } - return "\x1bP2$u" + strings.Join(s, "/") + "\x1b\\" -} - -// DECTABSR is an alias for [TabStopReport]. -func DECTABSR(stops ...int) string { - return TabStopReport(stops...) -} - -// CursorInformationReport (DECCIR) is the response to a cursor information -// report request. It reports the cursor position, visual attributes, and -// character protection attributes. It also reports the status of origin mode -// [DECOM] and the current active character set. -// -// The response is a list of values separated by a semicolon (;) character. -// -// DCS 1 $ u D ... D ST -// -// Where D is a decimal number representing a value. -// -// See: https://vt100.net/docs/vt510-rm/DECCIR.html -func CursorInformationReport(values ...int) string { - var s []string - for _, v := range values { - s = append(s, strconv.Itoa(v)) - } - return "\x1bP1$u" + strings.Join(s, ";") + "\x1b\\" -} - -// DECCIR is an alias for [CursorInformationReport]. -func DECCIR(values ...int) string { - return CursorInformationReport(values...) -} - -// RepeatPreviousCharacter (REP) repeats the previous character n times. -// This is identical to typing the same character n times. -// -// Default is 1. -// -// CSI Pn b -// -// See: ECMA-48 § 8.3.103 -func RepeatPreviousCharacter(n int) string { - var s string - if n > 1 { - s = strconv.Itoa(n) - } - return "\x1b[" + s + "b" -} - -// REP is an alias for [RepeatPreviousCharacter]. -func REP(n int) string { - return RepeatPreviousCharacter(n) -} diff --git a/vendor/github.com/charmbracelet/x/ansi/sgr.go b/vendor/github.com/charmbracelet/x/ansi/sgr.go deleted file mode 100644 index 1a18c98ef4..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/sgr.go +++ /dev/null @@ -1,95 +0,0 @@ -package ansi - -import "strconv" - -// Select Graphic Rendition (SGR) is a command that sets display attributes. -// -// Default is 0. -// -// CSI Ps ; Ps ... m -// -// See: https://vt100.net/docs/vt510-rm/SGR.html -func SelectGraphicRendition(ps ...Attr) string { - if len(ps) == 0 { - return ResetStyle - } - - var s Style - for _, p := range ps { - attr, ok := attrStrings[p] - if ok { - s = append(s, attr) - } else { - if p < 0 { - p = 0 - } - s = append(s, strconv.Itoa(p)) - } - } - - return s.String() -} - -// SGR is an alias for [SelectGraphicRendition]. -func SGR(ps ...Attr) string { - return SelectGraphicRendition(ps...) -} - -var attrStrings = map[int]string{ - ResetAttr: "0", - BoldAttr: "1", - FaintAttr: "2", - ItalicAttr: "3", - UnderlineAttr: "4", - SlowBlinkAttr: "5", - RapidBlinkAttr: "6", - ReverseAttr: "7", - ConcealAttr: "8", - StrikethroughAttr: "9", - NoBoldAttr: "21", - NormalIntensityAttr: "22", - NoItalicAttr: "23", - NoUnderlineAttr: "24", - NoBlinkAttr: "25", - NoReverseAttr: "27", - NoConcealAttr: "28", - NoStrikethroughAttr: "29", - BlackForegroundColorAttr: "30", - RedForegroundColorAttr: "31", - GreenForegroundColorAttr: "32", - YellowForegroundColorAttr: "33", - BlueForegroundColorAttr: "34", - MagentaForegroundColorAttr: "35", - CyanForegroundColorAttr: "36", - WhiteForegroundColorAttr: "37", - ExtendedForegroundColorAttr: "38", - DefaultForegroundColorAttr: "39", - BlackBackgroundColorAttr: "40", - RedBackgroundColorAttr: "41", - GreenBackgroundColorAttr: "42", - YellowBackgroundColorAttr: "43", - BlueBackgroundColorAttr: "44", - MagentaBackgroundColorAttr: "45", - CyanBackgroundColorAttr: "46", - WhiteBackgroundColorAttr: "47", - ExtendedBackgroundColorAttr: "48", - DefaultBackgroundColorAttr: "49", - ExtendedUnderlineColorAttr: "58", - DefaultUnderlineColorAttr: "59", - BrightBlackForegroundColorAttr: "90", - BrightRedForegroundColorAttr: "91", - BrightGreenForegroundColorAttr: "92", - BrightYellowForegroundColorAttr: "93", - BrightBlueForegroundColorAttr: "94", - BrightMagentaForegroundColorAttr: "95", - BrightCyanForegroundColorAttr: "96", - BrightWhiteForegroundColorAttr: "97", - BrightBlackBackgroundColorAttr: "100", - BrightRedBackgroundColorAttr: "101", - BrightGreenBackgroundColorAttr: "102", - BrightYellowBackgroundColorAttr: "103", - BrightBlueBackgroundColorAttr: "104", - BrightMagentaBackgroundColorAttr: "105", - BrightCyanBackgroundColorAttr: "106", - BrightWhiteBackgroundColorAttr: "107", -} diff --git a/vendor/github.com/charmbracelet/x/ansi/status.go b/vendor/github.com/charmbracelet/x/ansi/status.go deleted file mode 100644 index 4337e189d4..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/status.go +++ /dev/null @@ -1,144 +0,0 @@ -package ansi - -import ( - "strconv" - "strings" -) - -// StatusReport represents a terminal status report. -type StatusReport interface { - // StatusReport returns the status report identifier. - StatusReport() int -} - -// ANSIReport represents an ANSI terminal status report. -type ANSIStatusReport int //nolint:revive - -// Report returns the status report identifier. -func (s ANSIStatusReport) StatusReport() int { - return int(s) -} - -// DECStatusReport represents a DEC terminal status report. -type DECStatusReport int - -// Status returns the status report identifier. -func (s DECStatusReport) StatusReport() int { - return int(s) -} - -// DeviceStatusReport (DSR) is a control sequence that reports the terminal's -// status. -// The terminal responds with a DSR sequence. -// -// CSI Ps n -// CSI ? Ps n -// -// If one of the statuses is a [DECStatus], the sequence will use the DEC -// format. -// -// See also https://vt100.net/docs/vt510-rm/DSR.html -func DeviceStatusReport(statues ...StatusReport) string { - var dec bool - list := make([]string, len(statues)) - seq := "\x1b[" - for i, status := range statues { - list[i] = strconv.Itoa(status.StatusReport()) - switch status.(type) { - case DECStatusReport: - dec = true - } - } - if dec { - seq += "?" - } - return seq + strings.Join(list, ";") + "n" -} - -// DSR is an alias for [DeviceStatusReport]. -func DSR(status StatusReport) string { - return DeviceStatusReport(status) -} - -// RequestCursorPositionReport is an escape sequence that requests the current -// cursor position. -// -// CSI 6 n -// -// The terminal will report the cursor position as a CSI sequence in the -// following format: -// -// CSI Pl ; Pc R -// -// Where Pl is the line number and Pc is the column number. -// See: https://vt100.net/docs/vt510-rm/CPR.html -const RequestCursorPositionReport = "\x1b[6n" - -// RequestExtendedCursorPositionReport (DECXCPR) is a sequence for requesting -// the cursor position report including the current page number. -// -// CSI ? 6 n -// -// The terminal will report the cursor position as a CSI sequence in the -// following format: -// -// CSI ? Pl ; Pc ; Pp R -// -// Where Pl is the line number, Pc is the column number, and Pp is the page -// number. -// See: https://vt100.net/docs/vt510-rm/DECXCPR.html -const RequestExtendedCursorPositionReport = "\x1b[?6n" - -// CursorPositionReport (CPR) is a control sequence that reports the cursor's -// position. -// -// CSI Pl ; Pc R -// -// Where Pl is the line number and Pc is the column number. -// -// See also https://vt100.net/docs/vt510-rm/CPR.html -func CursorPositionReport(line, column int) string { - if line < 1 { - line = 1 - } - if column < 1 { - column = 1 - } - return "\x1b[" + strconv.Itoa(line) + ";" + strconv.Itoa(column) + "R" -} - -// CPR is an alias for [CursorPositionReport]. -func CPR(line, column int) string { - return CursorPositionReport(line, column) -} - -// ExtendedCursorPositionReport (DECXCPR) is a control sequence that reports the -// cursor's position along with the page number (optional). -// -// CSI ? Pl ; Pc R -// CSI ? Pl ; Pc ; Pv R -// -// Where Pl is the line number, Pc is the column number, and Pv is the page -// number. -// -// If the page number is zero or negative, the returned sequence won't include -// the page number. -// -// See also https://vt100.net/docs/vt510-rm/DECXCPR.html -func ExtendedCursorPositionReport(line, column, page int) string { - if line < 1 { - line = 1 - } - if column < 1 { - column = 1 - } - if page < 1 { - return "\x1b[?" + strconv.Itoa(line) + ";" + strconv.Itoa(column) + "R" - } - return "\x1b[?" + strconv.Itoa(line) + ";" + strconv.Itoa(column) + ";" + strconv.Itoa(page) + "R" -} - -// DECXCPR is an alias for [ExtendedCursorPositionReport]. -func DECXCPR(line, column, page int) string { - return ExtendedCursorPositionReport(line, column, page) -} diff --git a/vendor/github.com/charmbracelet/x/ansi/style.go b/vendor/github.com/charmbracelet/x/ansi/style.go deleted file mode 100644 index 46ddcaa99b..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/style.go +++ /dev/null @@ -1,660 +0,0 @@ -package ansi - -import ( - "image/color" - "strconv" - "strings" -) - -// ResetStyle is a SGR (Select Graphic Rendition) style sequence that resets -// all attributes. -// See: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters -const ResetStyle = "\x1b[m" - -// Attr is a SGR (Select Graphic Rendition) style attribute. -type Attr = int - -// Style represents an ANSI SGR (Select Graphic Rendition) style. -type Style []string - -// String returns the ANSI SGR (Select Graphic Rendition) style sequence for -// the given style. -func (s Style) String() string { - if len(s) == 0 { - return ResetStyle - } - return "\x1b[" + strings.Join(s, ";") + "m" -} - -// Styled returns a styled string with the given style applied. -func (s Style) Styled(str string) string { - if len(s) == 0 { - return str - } - return s.String() + str + ResetStyle -} - -// Reset appends the reset style attribute to the style. -func (s Style) Reset() Style { - return append(s, resetAttr) -} - -// Bold appends the bold style attribute to the style. -func (s Style) Bold() Style { - return append(s, boldAttr) -} - -// Faint appends the faint style attribute to the style. -func (s Style) Faint() Style { - return append(s, faintAttr) -} - -// Italic appends the italic style attribute to the style. -func (s Style) Italic() Style { - return append(s, italicAttr) -} - -// Underline appends the underline style attribute to the style. -func (s Style) Underline() Style { - return append(s, underlineAttr) -} - -// UnderlineStyle appends the underline style attribute to the style. -func (s Style) UnderlineStyle(u UnderlineStyle) Style { - switch u { - case NoUnderlineStyle: - return s.NoUnderline() - case SingleUnderlineStyle: - return s.Underline() - case DoubleUnderlineStyle: - return append(s, doubleUnderlineStyle) - case CurlyUnderlineStyle: - return append(s, curlyUnderlineStyle) - case DottedUnderlineStyle: - return append(s, dottedUnderlineStyle) - case DashedUnderlineStyle: - return append(s, dashedUnderlineStyle) - } - return s -} - -// DoubleUnderline appends the double underline style attribute to the style. -// This is a convenience method for UnderlineStyle(DoubleUnderlineStyle). -func (s Style) DoubleUnderline() Style { - return s.UnderlineStyle(DoubleUnderlineStyle) -} - -// CurlyUnderline appends the curly underline style attribute to the style. -// This is a convenience method for UnderlineStyle(CurlyUnderlineStyle). -func (s Style) CurlyUnderline() Style { - return s.UnderlineStyle(CurlyUnderlineStyle) -} - -// DottedUnderline appends the dotted underline style attribute to the style. -// This is a convenience method for UnderlineStyle(DottedUnderlineStyle). -func (s Style) DottedUnderline() Style { - return s.UnderlineStyle(DottedUnderlineStyle) -} - -// DashedUnderline appends the dashed underline style attribute to the style. -// This is a convenience method for UnderlineStyle(DashedUnderlineStyle). -func (s Style) DashedUnderline() Style { - return s.UnderlineStyle(DashedUnderlineStyle) -} - -// SlowBlink appends the slow blink style attribute to the style. -func (s Style) SlowBlink() Style { - return append(s, slowBlinkAttr) -} - -// RapidBlink appends the rapid blink style attribute to the style. -func (s Style) RapidBlink() Style { - return append(s, rapidBlinkAttr) -} - -// Reverse appends the reverse style attribute to the style. -func (s Style) Reverse() Style { - return append(s, reverseAttr) -} - -// Conceal appends the conceal style attribute to the style. -func (s Style) Conceal() Style { - return append(s, concealAttr) -} - -// Strikethrough appends the strikethrough style attribute to the style. -func (s Style) Strikethrough() Style { - return append(s, strikethroughAttr) -} - -// NoBold appends the no bold style attribute to the style. -func (s Style) NoBold() Style { - return append(s, noBoldAttr) -} - -// NormalIntensity appends the normal intensity style attribute to the style. -func (s Style) NormalIntensity() Style { - return append(s, normalIntensityAttr) -} - -// NoItalic appends the no italic style attribute to the style. -func (s Style) NoItalic() Style { - return append(s, noItalicAttr) -} - -// NoUnderline appends the no underline style attribute to the style. -func (s Style) NoUnderline() Style { - return append(s, noUnderlineAttr) -} - -// NoBlink appends the no blink style attribute to the style. -func (s Style) NoBlink() Style { - return append(s, noBlinkAttr) -} - -// NoReverse appends the no reverse style attribute to the style. -func (s Style) NoReverse() Style { - return append(s, noReverseAttr) -} - -// NoConceal appends the no conceal style attribute to the style. -func (s Style) NoConceal() Style { - return append(s, noConcealAttr) -} - -// NoStrikethrough appends the no strikethrough style attribute to the style. -func (s Style) NoStrikethrough() Style { - return append(s, noStrikethroughAttr) -} - -// DefaultForegroundColor appends the default foreground color style attribute to the style. -func (s Style) DefaultForegroundColor() Style { - return append(s, defaultForegroundColorAttr) -} - -// DefaultBackgroundColor appends the default background color style attribute to the style. -func (s Style) DefaultBackgroundColor() Style { - return append(s, defaultBackgroundColorAttr) -} - -// DefaultUnderlineColor appends the default underline color style attribute to the style. -func (s Style) DefaultUnderlineColor() Style { - return append(s, defaultUnderlineColorAttr) -} - -// ForegroundColor appends the foreground color style attribute to the style. -func (s Style) ForegroundColor(c Color) Style { - return append(s, foregroundColorString(c)) -} - -// BackgroundColor appends the background color style attribute to the style. -func (s Style) BackgroundColor(c Color) Style { - return append(s, backgroundColorString(c)) -} - -// UnderlineColor appends the underline color style attribute to the style. -func (s Style) UnderlineColor(c Color) Style { - return append(s, underlineColorString(c)) -} - -// UnderlineStyle represents an ANSI SGR (Select Graphic Rendition) underline -// style. -type UnderlineStyle = byte - -const ( - doubleUnderlineStyle = "4:2" - curlyUnderlineStyle = "4:3" - dottedUnderlineStyle = "4:4" - dashedUnderlineStyle = "4:5" -) - -const ( - // NoUnderlineStyle is the default underline style. - NoUnderlineStyle UnderlineStyle = iota - // SingleUnderlineStyle is a single underline style. - SingleUnderlineStyle - // DoubleUnderlineStyle is a double underline style. - DoubleUnderlineStyle - // CurlyUnderlineStyle is a curly underline style. - CurlyUnderlineStyle - // DottedUnderlineStyle is a dotted underline style. - DottedUnderlineStyle - // DashedUnderlineStyle is a dashed underline style. - DashedUnderlineStyle -) - -// SGR (Select Graphic Rendition) style attributes. -// See: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters -const ( - ResetAttr Attr = 0 - BoldAttr Attr = 1 - FaintAttr Attr = 2 - ItalicAttr Attr = 3 - UnderlineAttr Attr = 4 - SlowBlinkAttr Attr = 5 - RapidBlinkAttr Attr = 6 - ReverseAttr Attr = 7 - ConcealAttr Attr = 8 - StrikethroughAttr Attr = 9 - NoBoldAttr Attr = 21 // Some terminals treat this as double underline. - NormalIntensityAttr Attr = 22 - NoItalicAttr Attr = 23 - NoUnderlineAttr Attr = 24 - NoBlinkAttr Attr = 25 - NoReverseAttr Attr = 27 - NoConcealAttr Attr = 28 - NoStrikethroughAttr Attr = 29 - BlackForegroundColorAttr Attr = 30 - RedForegroundColorAttr Attr = 31 - GreenForegroundColorAttr Attr = 32 - YellowForegroundColorAttr Attr = 33 - BlueForegroundColorAttr Attr = 34 - MagentaForegroundColorAttr Attr = 35 - CyanForegroundColorAttr Attr = 36 - WhiteForegroundColorAttr Attr = 37 - ExtendedForegroundColorAttr Attr = 38 - DefaultForegroundColorAttr Attr = 39 - BlackBackgroundColorAttr Attr = 40 - RedBackgroundColorAttr Attr = 41 - GreenBackgroundColorAttr Attr = 42 - YellowBackgroundColorAttr Attr = 43 - BlueBackgroundColorAttr Attr = 44 - MagentaBackgroundColorAttr Attr = 45 - CyanBackgroundColorAttr Attr = 46 - WhiteBackgroundColorAttr Attr = 47 - ExtendedBackgroundColorAttr Attr = 48 - DefaultBackgroundColorAttr Attr = 49 - ExtendedUnderlineColorAttr Attr = 58 - DefaultUnderlineColorAttr Attr = 59 - BrightBlackForegroundColorAttr Attr = 90 - BrightRedForegroundColorAttr Attr = 91 - BrightGreenForegroundColorAttr Attr = 92 - BrightYellowForegroundColorAttr Attr = 93 - BrightBlueForegroundColorAttr Attr = 94 - BrightMagentaForegroundColorAttr Attr = 95 - BrightCyanForegroundColorAttr Attr = 96 - BrightWhiteForegroundColorAttr Attr = 97 - BrightBlackBackgroundColorAttr Attr = 100 - BrightRedBackgroundColorAttr Attr = 101 - BrightGreenBackgroundColorAttr Attr = 102 - BrightYellowBackgroundColorAttr Attr = 103 - BrightBlueBackgroundColorAttr Attr = 104 - BrightMagentaBackgroundColorAttr Attr = 105 - BrightCyanBackgroundColorAttr Attr = 106 - BrightWhiteBackgroundColorAttr Attr = 107 - - RGBColorIntroducerAttr Attr = 2 - ExtendedColorIntroducerAttr Attr = 5 -) - -const ( - resetAttr = "0" - boldAttr = "1" - faintAttr = "2" - italicAttr = "3" - underlineAttr = "4" - slowBlinkAttr = "5" - rapidBlinkAttr = "6" - reverseAttr = "7" - concealAttr = "8" - strikethroughAttr = "9" - noBoldAttr = "21" - normalIntensityAttr = "22" - noItalicAttr = "23" - noUnderlineAttr = "24" - noBlinkAttr = "25" - noReverseAttr = "27" - noConcealAttr = "28" - noStrikethroughAttr = "29" - blackForegroundColorAttr = "30" - redForegroundColorAttr = "31" - greenForegroundColorAttr = "32" - yellowForegroundColorAttr = "33" - blueForegroundColorAttr = "34" - magentaForegroundColorAttr = "35" - cyanForegroundColorAttr = "36" - whiteForegroundColorAttr = "37" - extendedForegroundColorAttr = "38" - defaultForegroundColorAttr = "39" - blackBackgroundColorAttr = "40" - redBackgroundColorAttr = "41" - greenBackgroundColorAttr = "42" - yellowBackgroundColorAttr = "43" - blueBackgroundColorAttr = "44" - magentaBackgroundColorAttr = "45" - cyanBackgroundColorAttr = "46" - whiteBackgroundColorAttr = "47" - extendedBackgroundColorAttr = "48" - defaultBackgroundColorAttr = "49" - extendedUnderlineColorAttr = "58" - defaultUnderlineColorAttr = "59" - brightBlackForegroundColorAttr = "90" - brightRedForegroundColorAttr = "91" - brightGreenForegroundColorAttr = "92" - brightYellowForegroundColorAttr = "93" - brightBlueForegroundColorAttr = "94" - brightMagentaForegroundColorAttr = "95" - brightCyanForegroundColorAttr = "96" - brightWhiteForegroundColorAttr = "97" - brightBlackBackgroundColorAttr = "100" - brightRedBackgroundColorAttr = "101" - brightGreenBackgroundColorAttr = "102" - brightYellowBackgroundColorAttr = "103" - brightBlueBackgroundColorAttr = "104" - brightMagentaBackgroundColorAttr = "105" - brightCyanBackgroundColorAttr = "106" - brightWhiteBackgroundColorAttr = "107" -) - -// foregroundColorString returns the style SGR attribute for the given -// foreground color. -// See: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters -func foregroundColorString(c Color) string { - switch c := c.(type) { - case BasicColor: - // 3-bit or 4-bit ANSI foreground - // "3" or "9" where n is the color number from 0 to 7 - switch c { - case Black: - return blackForegroundColorAttr - case Red: - return redForegroundColorAttr - case Green: - return greenForegroundColorAttr - case Yellow: - return yellowForegroundColorAttr - case Blue: - return blueForegroundColorAttr - case Magenta: - return magentaForegroundColorAttr - case Cyan: - return cyanForegroundColorAttr - case White: - return whiteForegroundColorAttr - case BrightBlack: - return brightBlackForegroundColorAttr - case BrightRed: - return brightRedForegroundColorAttr - case BrightGreen: - return brightGreenForegroundColorAttr - case BrightYellow: - return brightYellowForegroundColorAttr - case BrightBlue: - return brightBlueForegroundColorAttr - case BrightMagenta: - return brightMagentaForegroundColorAttr - case BrightCyan: - return brightCyanForegroundColorAttr - case BrightWhite: - return brightWhiteForegroundColorAttr - } - case ExtendedColor: - // 256-color ANSI foreground - // "38;5;" - return "38;5;" + strconv.FormatUint(uint64(c), 10) - case TrueColor, color.Color: - // 24-bit "true color" foreground - // "38;2;;;" - r, g, b, _ := c.RGBA() - return "38;2;" + - strconv.FormatUint(uint64(shift(r)), 10) + ";" + - strconv.FormatUint(uint64(shift(g)), 10) + ";" + - strconv.FormatUint(uint64(shift(b)), 10) - } - return defaultForegroundColorAttr -} - -// backgroundColorString returns the style SGR attribute for the given -// background color. -// See: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters -func backgroundColorString(c Color) string { - switch c := c.(type) { - case BasicColor: - // 3-bit or 4-bit ANSI foreground - // "4" or "10" where n is the color number from 0 to 7 - switch c { - case Black: - return blackBackgroundColorAttr - case Red: - return redBackgroundColorAttr - case Green: - return greenBackgroundColorAttr - case Yellow: - return yellowBackgroundColorAttr - case Blue: - return blueBackgroundColorAttr - case Magenta: - return magentaBackgroundColorAttr - case Cyan: - return cyanBackgroundColorAttr - case White: - return whiteBackgroundColorAttr - case BrightBlack: - return brightBlackBackgroundColorAttr - case BrightRed: - return brightRedBackgroundColorAttr - case BrightGreen: - return brightGreenBackgroundColorAttr - case BrightYellow: - return brightYellowBackgroundColorAttr - case BrightBlue: - return brightBlueBackgroundColorAttr - case BrightMagenta: - return brightMagentaBackgroundColorAttr - case BrightCyan: - return brightCyanBackgroundColorAttr - case BrightWhite: - return brightWhiteBackgroundColorAttr - } - case ExtendedColor: - // 256-color ANSI foreground - // "48;5;" - return "48;5;" + strconv.FormatUint(uint64(c), 10) - case TrueColor, color.Color: - // 24-bit "true color" foreground - // "38;2;;;" - r, g, b, _ := c.RGBA() - return "48;2;" + - strconv.FormatUint(uint64(shift(r)), 10) + ";" + - strconv.FormatUint(uint64(shift(g)), 10) + ";" + - strconv.FormatUint(uint64(shift(b)), 10) - } - return defaultBackgroundColorAttr -} - -// underlineColorString returns the style SGR attribute for the given underline -// color. -// See: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters -func underlineColorString(c Color) string { - switch c := c.(type) { - // NOTE: we can't use 3-bit and 4-bit ANSI color codes with underline - // color, use 256-color instead. - // - // 256-color ANSI underline color - // "58;5;" - case BasicColor: - return "58;5;" + strconv.FormatUint(uint64(c), 10) - case ExtendedColor: - return "58;5;" + strconv.FormatUint(uint64(c), 10) - case TrueColor, color.Color: - // 24-bit "true color" foreground - // "38;2;;;" - r, g, b, _ := c.RGBA() - return "58;2;" + - strconv.FormatUint(uint64(shift(r)), 10) + ";" + - strconv.FormatUint(uint64(shift(g)), 10) + ";" + - strconv.FormatUint(uint64(shift(b)), 10) - } - return defaultUnderlineColorAttr -} - -// ReadStyleColor decodes a color from a slice of parameters. It returns the -// number of parameters read and the color. This function is used to read SGR -// color parameters following the ITU T.416 standard. -// -// It supports reading the following color types: -// - 0: implementation defined -// - 1: transparent -// - 2: RGB direct color -// - 3: CMY direct color -// - 4: CMYK direct color -// - 5: indexed color -// - 6: RGBA direct color (WezTerm extension) -// -// The parameters can be separated by semicolons (;) or colons (:). Mixing -// separators is not allowed. -// -// The specs supports defining a color space id, a color tolerance value, and a -// tolerance color space id. However, these values have no effect on the -// returned color and will be ignored. -// -// This implementation includes a few modifications to the specs: -// 1. Support for legacy color values separated by semicolons (;) with respect to RGB, and indexed colors -// 2. Support ignoring and omitting the color space id (second parameter) with respect to RGB colors -// 3. Support ignoring and omitting the 6th parameter with respect to RGB and CMY colors -// 4. Support reading RGBA colors -func ReadStyleColor(params Params, co *color.Color) (n int) { - if len(params) < 2 { // Need at least SGR type and color type - return 0 - } - - // First parameter indicates one of 38, 48, or 58 (foreground, background, or underline) - s := params[0] - p := params[1] - colorType := p.Param(0) - n = 2 - - paramsfn := func() (p1, p2, p3, p4 int) { - // Where should we start reading the color? - switch { - case s.HasMore() && p.HasMore() && len(params) > 8 && params[2].HasMore() && params[3].HasMore() && params[4].HasMore() && params[5].HasMore() && params[6].HasMore() && params[7].HasMore(): - // We have color space id, a 6th parameter, a tolerance value, and a tolerance color space - n += 7 - return params[3].Param(0), params[4].Param(0), params[5].Param(0), params[6].Param(0) - case s.HasMore() && p.HasMore() && len(params) > 7 && params[2].HasMore() && params[3].HasMore() && params[4].HasMore() && params[5].HasMore() && params[6].HasMore(): - // We have color space id, a 6th parameter, and a tolerance value - n += 6 - return params[3].Param(0), params[4].Param(0), params[5].Param(0), params[6].Param(0) - case s.HasMore() && p.HasMore() && len(params) > 6 && params[2].HasMore() && params[3].HasMore() && params[4].HasMore() && params[5].HasMore(): - // We have color space id and a 6th parameter - // 48 : 4 : : 1 : 2 : 3 :4 - n += 5 - return params[3].Param(0), params[4].Param(0), params[5].Param(0), params[6].Param(0) - case s.HasMore() && p.HasMore() && len(params) > 5 && params[2].HasMore() && params[3].HasMore() && params[4].HasMore() && !params[5].HasMore(): - // We have color space - // 48 : 3 : : 1 : 2 : 3 - n += 4 - return params[3].Param(0), params[4].Param(0), params[5].Param(0), -1 - case s.HasMore() && p.HasMore() && p.Param(0) == 2 && params[2].HasMore() && params[3].HasMore() && !params[4].HasMore(): - // We have color values separated by colons (:) - // 48 : 2 : 1 : 2 : 3 - fallthrough - case !s.HasMore() && !p.HasMore() && p.Param(0) == 2 && !params[2].HasMore() && !params[3].HasMore() && !params[4].HasMore(): - // Support legacy color values separated by semicolons (;) - // 48 ; 2 ; 1 ; 2 ; 3 - n += 3 - return params[2].Param(0), params[3].Param(0), params[4].Param(0), -1 - } - // Ambiguous SGR color - return -1, -1, -1, -1 - } - - switch colorType { - case 0: // implementation defined - return 2 - case 1: // transparent - *co = color.Transparent - return 2 - case 2: // RGB direct color - if len(params) < 5 { - return 0 - } - - r, g, b, _ := paramsfn() - if r == -1 || g == -1 || b == -1 { - return 0 - } - - *co = color.RGBA{ - R: uint8(r), //nolint:gosec - G: uint8(g), //nolint:gosec - B: uint8(b), //nolint:gosec - A: 0xff, - } - return - - case 3: // CMY direct color - if len(params) < 5 { - return 0 - } - - c, m, y, _ := paramsfn() - if c == -1 || m == -1 || y == -1 { - return 0 - } - - *co = color.CMYK{ - C: uint8(c), //nolint:gosec - M: uint8(m), //nolint:gosec - Y: uint8(y), //nolint:gosec - K: 0, - } - return - - case 4: // CMYK direct color - if len(params) < 6 { - return 0 - } - - c, m, y, k := paramsfn() - if c == -1 || m == -1 || y == -1 || k == -1 { - return 0 - } - - *co = color.CMYK{ - C: uint8(c), //nolint:gosec - M: uint8(m), //nolint:gosec - Y: uint8(y), //nolint:gosec - K: uint8(k), //nolint:gosec - } - return - - case 5: // indexed color - if len(params) < 3 { - return 0 - } - switch { - case s.HasMore() && p.HasMore() && !params[2].HasMore(): - // Colon separated indexed color - // 38 : 5 : 234 - case !s.HasMore() && !p.HasMore() && !params[2].HasMore(): - // Legacy semicolon indexed color - // 38 ; 5 ; 234 - default: - return 0 - } - *co = ExtendedColor(params[2].Param(0)) //nolint:gosec - return 3 - - case 6: // RGBA direct color - if len(params) < 6 { - return 0 - } - - r, g, b, a := paramsfn() - if r == -1 || g == -1 || b == -1 || a == -1 { - return 0 - } - - *co = color.RGBA{ - R: uint8(r), //nolint:gosec - G: uint8(g), //nolint:gosec - B: uint8(b), //nolint:gosec - A: uint8(a), //nolint:gosec - } - return - - default: - return 0 - } -} diff --git a/vendor/github.com/charmbracelet/x/ansi/termcap.go b/vendor/github.com/charmbracelet/x/ansi/termcap.go deleted file mode 100644 index 3c5c7da92f..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/termcap.go +++ /dev/null @@ -1,41 +0,0 @@ -package ansi - -import ( - "encoding/hex" - "strings" -) - -// RequestTermcap (XTGETTCAP) requests Termcap/Terminfo strings. -// -// DCS + q ST -// -// Where is a list of Termcap/Terminfo capabilities, encoded in 2-digit -// hexadecimals, separated by semicolons. -// -// See: https://man7.org/linux/man-pages/man5/terminfo.5.html -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands -func XTGETTCAP(caps ...string) string { - if len(caps) == 0 { - return "" - } - - s := "\x1bP+q" - for i, c := range caps { - if i > 0 { - s += ";" - } - s += strings.ToUpper(hex.EncodeToString([]byte(c))) - } - - return s + "\x1b\\" -} - -// RequestTermcap is an alias for [XTGETTCAP]. -func RequestTermcap(caps ...string) string { - return XTGETTCAP(caps...) -} - -// RequestTerminfo is an alias for [XTGETTCAP]. -func RequestTerminfo(caps ...string) string { - return XTGETTCAP(caps...) -} diff --git a/vendor/github.com/charmbracelet/x/ansi/title.go b/vendor/github.com/charmbracelet/x/ansi/title.go deleted file mode 100644 index 8fd8bf98da..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/title.go +++ /dev/null @@ -1,32 +0,0 @@ -package ansi - -// SetIconNameWindowTitle returns a sequence for setting the icon name and -// window title. -// -// OSC 0 ; title ST -// OSC 0 ; title BEL -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Operating-System-Commands -func SetIconNameWindowTitle(s string) string { - return "\x1b]0;" + s + "\x07" -} - -// SetIconName returns a sequence for setting the icon name. -// -// OSC 1 ; title ST -// OSC 1 ; title BEL -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Operating-System-Commands -func SetIconName(s string) string { - return "\x1b]1;" + s + "\x07" -} - -// SetWindowTitle returns a sequence for setting the window title. -// -// OSC 2 ; title ST -// OSC 2 ; title BEL -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Operating-System-Commands -func SetWindowTitle(s string) string { - return "\x1b]2;" + s + "\x07" -} diff --git a/vendor/github.com/charmbracelet/x/ansi/truncate.go b/vendor/github.com/charmbracelet/x/ansi/truncate.go deleted file mode 100644 index 1fa3efefeb..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/truncate.go +++ /dev/null @@ -1,282 +0,0 @@ -package ansi - -import ( - "bytes" - - "github.com/charmbracelet/x/ansi/parser" - "github.com/mattn/go-runewidth" - "github.com/rivo/uniseg" -) - -// Cut the string, without adding any prefix or tail strings. This function is -// aware of ANSI escape codes and will not break them, and accounts for -// wide-characters (such as East-Asian characters and emojis). Note that the -// [left] parameter is inclusive, while [right] isn't. -// This treats the text as a sequence of graphemes. -func Cut(s string, left, right int) string { - return cut(GraphemeWidth, s, left, right) -} - -// CutWc the string, without adding any prefix or tail strings. This function is -// aware of ANSI escape codes and will not break them, and accounts for -// wide-characters (such as East-Asian characters and emojis). Note that the -// [left] parameter is inclusive, while [right] isn't. -// This treats the text as a sequence of wide characters and runes. -func CutWc(s string, left, right int) string { - return cut(WcWidth, s, left, right) -} - -func cut(m Method, s string, left, right int) string { - if right <= left { - return "" - } - - truncate := Truncate - truncateLeft := TruncateLeft - if m == WcWidth { - truncate = TruncateWc - truncateLeft = TruncateWc - } - - if left == 0 { - return truncate(s, right, "") - } - return truncateLeft(Truncate(s, right, ""), left, "") -} - -// Truncate truncates a string to a given length, adding a tail to the end if -// the string is longer than the given length. This function is aware of ANSI -// escape codes and will not break them, and accounts for wide-characters (such -// as East-Asian characters and emojis). -// This treats the text as a sequence of graphemes. -func Truncate(s string, length int, tail string) string { - return truncate(GraphemeWidth, s, length, tail) -} - -// TruncateWc truncates a string to a given length, adding a tail to the end if -// the string is longer than the given length. This function is aware of ANSI -// escape codes and will not break them, and accounts for wide-characters (such -// as East-Asian characters and emojis). -// This treats the text as a sequence of wide characters and runes. -func TruncateWc(s string, length int, tail string) string { - return truncate(WcWidth, s, length, tail) -} - -func truncate(m Method, s string, length int, tail string) string { - if sw := StringWidth(s); sw <= length { - return s - } - - tw := StringWidth(tail) - length -= tw - if length < 0 { - return "" - } - - var cluster []byte - var buf bytes.Buffer - curWidth := 0 - ignoring := false - pstate := parser.GroundState // initial state - b := []byte(s) - i := 0 - - // Here we iterate over the bytes of the string and collect printable - // characters and runes. We also keep track of the width of the string - // in cells. - // - // Once we reach the given length, we start ignoring characters and only - // collect ANSI escape codes until we reach the end of string. - for i < len(b) { - state, action := parser.Table.Transition(pstate, b[i]) - if state == parser.Utf8State { - // This action happens when we transition to the Utf8State. - var width int - cluster, _, width, _ = uniseg.FirstGraphemeCluster(b[i:], -1) - if m == WcWidth { - width = runewidth.StringWidth(string(cluster)) - } - - // increment the index by the length of the cluster - i += len(cluster) - - // Are we ignoring? Skip to the next byte - if ignoring { - continue - } - - // Is this gonna be too wide? - // If so write the tail and stop collecting. - if curWidth+width > length && !ignoring { - ignoring = true - buf.WriteString(tail) - } - - if curWidth+width > length { - continue - } - - curWidth += width - buf.Write(cluster) - - // Done collecting, now we're back in the ground state. - pstate = parser.GroundState - continue - } - - switch action { - case parser.PrintAction: - // Is this gonna be too wide? - // If so write the tail and stop collecting. - if curWidth >= length && !ignoring { - ignoring = true - buf.WriteString(tail) - } - - // Skip to the next byte if we're ignoring - if ignoring { - i++ - continue - } - - // collects printable ASCII - curWidth++ - fallthrough - default: - buf.WriteByte(b[i]) - i++ - } - - // Transition to the next state. - pstate = state - - // Once we reach the given length, we start ignoring runes and write - // the tail to the buffer. - if curWidth > length && !ignoring { - ignoring = true - buf.WriteString(tail) - } - } - - return buf.String() -} - -// TruncateLeft truncates a string from the left side by removing n characters, -// adding a prefix to the beginning if the string is longer than n. -// This function is aware of ANSI escape codes and will not break them, and -// accounts for wide-characters (such as East-Asian characters and emojis). -// This treats the text as a sequence of graphemes. -func TruncateLeft(s string, n int, prefix string) string { - return truncateLeft(GraphemeWidth, s, n, prefix) -} - -// TruncateLeftWc truncates a string from the left side by removing n characters, -// adding a prefix to the beginning if the string is longer than n. -// This function is aware of ANSI escape codes and will not break them, and -// accounts for wide-characters (such as East-Asian characters and emojis). -// This treats the text as a sequence of wide characters and runes. -func TruncateLeftWc(s string, n int, prefix string) string { - return truncateLeft(WcWidth, s, n, prefix) -} - -func truncateLeft(m Method, s string, n int, prefix string) string { - if n <= 0 { - return s - } - - var cluster []byte - var buf bytes.Buffer - curWidth := 0 - ignoring := true - pstate := parser.GroundState - b := []byte(s) - i := 0 - - for i < len(b) { - if !ignoring { - buf.Write(b[i:]) - break - } - - state, action := parser.Table.Transition(pstate, b[i]) - if state == parser.Utf8State { - var width int - cluster, _, width, _ = uniseg.FirstGraphemeCluster(b[i:], -1) - if m == WcWidth { - width = runewidth.StringWidth(string(cluster)) - } - - i += len(cluster) - curWidth += width - - if curWidth > n && ignoring { - ignoring = false - buf.WriteString(prefix) - } - - if ignoring { - continue - } - - if curWidth > n { - buf.Write(cluster) - } - - pstate = parser.GroundState - continue - } - - switch action { - case parser.PrintAction: - curWidth++ - - if curWidth > n && ignoring { - ignoring = false - buf.WriteString(prefix) - } - - if ignoring { - i++ - continue - } - - fallthrough - default: - buf.WriteByte(b[i]) - i++ - } - - pstate = state - if curWidth > n && ignoring { - ignoring = false - buf.WriteString(prefix) - } - } - - return buf.String() -} - -// ByteToGraphemeRange takes start and stop byte positions and converts them to -// grapheme-aware char positions. -// You can use this with [Truncate], [TruncateLeft], and [Cut]. -func ByteToGraphemeRange(str string, byteStart, byteStop int) (charStart, charStop int) { - bytePos, charPos := 0, 0 - gr := uniseg.NewGraphemes(str) - for byteStart > bytePos { - if !gr.Next() { - break - } - bytePos += len(gr.Str()) - charPos += max(1, gr.Width()) - } - charStart = charPos - for byteStop > bytePos { - if !gr.Next() { - break - } - bytePos += len(gr.Str()) - charPos += max(1, gr.Width()) - } - charStop = charPos - return -} diff --git a/vendor/github.com/charmbracelet/x/ansi/util.go b/vendor/github.com/charmbracelet/x/ansi/util.go deleted file mode 100644 index 301ef15ff8..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/util.go +++ /dev/null @@ -1,106 +0,0 @@ -package ansi - -import ( - "fmt" - "image/color" - "strconv" - "strings" - - "github.com/lucasb-eyer/go-colorful" -) - -// colorToHexString returns a hex string representation of a color. -func colorToHexString(c color.Color) string { - if c == nil { - return "" - } - shift := func(v uint32) uint32 { - if v > 0xff { - return v >> 8 - } - return v - } - r, g, b, _ := c.RGBA() - r, g, b = shift(r), shift(g), shift(b) - return fmt.Sprintf("#%02x%02x%02x", r, g, b) -} - -// rgbToHex converts red, green, and blue values to a hexadecimal value. -// -// hex := rgbToHex(0, 0, 255) // 0x0000FF -func rgbToHex(r, g, b uint32) uint32 { - return r<<16 + g<<8 + b -} - -type shiftable interface { - ~uint | ~uint16 | ~uint32 | ~uint64 -} - -func shift[T shiftable](x T) T { - if x > 0xff { - x >>= 8 - } - return x -} - -// XParseColor is a helper function that parses a string into a color.Color. It -// provides a similar interface to the XParseColor function in Xlib. It -// supports the following formats: -// -// - #RGB -// - #RRGGBB -// - rgb:RRRR/GGGG/BBBB -// - rgba:RRRR/GGGG/BBBB/AAAA -// -// If the string is not a valid color, nil is returned. -// -// See: https://linux.die.net/man/3/xparsecolor -func XParseColor(s string) color.Color { - switch { - case strings.HasPrefix(s, "#"): - c, err := colorful.Hex(s) - if err != nil { - return nil - } - - return c - case strings.HasPrefix(s, "rgb:"): - parts := strings.Split(s[4:], "/") - if len(parts) != 3 { - return nil - } - - r, _ := strconv.ParseUint(parts[0], 16, 32) - g, _ := strconv.ParseUint(parts[1], 16, 32) - b, _ := strconv.ParseUint(parts[2], 16, 32) - - return color.RGBA{uint8(shift(r)), uint8(shift(g)), uint8(shift(b)), 255} //nolint:gosec - case strings.HasPrefix(s, "rgba:"): - parts := strings.Split(s[5:], "/") - if len(parts) != 4 { - return nil - } - - r, _ := strconv.ParseUint(parts[0], 16, 32) - g, _ := strconv.ParseUint(parts[1], 16, 32) - b, _ := strconv.ParseUint(parts[2], 16, 32) - a, _ := strconv.ParseUint(parts[3], 16, 32) - - return color.RGBA{uint8(shift(r)), uint8(shift(g)), uint8(shift(b)), uint8(shift(a))} //nolint:gosec - } - return nil -} - -type ordered interface { - ~int | ~int8 | ~int16 | ~int32 | ~int64 | - ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr | - ~float32 | ~float64 | - ~string -} - -func max[T ordered](a, b T) T { //nolint:predeclared - if a > b { - return a - } - return b -} diff --git a/vendor/github.com/charmbracelet/x/ansi/width.go b/vendor/github.com/charmbracelet/x/ansi/width.go deleted file mode 100644 index d0487d350b..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/width.go +++ /dev/null @@ -1,113 +0,0 @@ -package ansi - -import ( - "bytes" - - "github.com/charmbracelet/x/ansi/parser" - "github.com/mattn/go-runewidth" - "github.com/rivo/uniseg" -) - -// Strip removes ANSI escape codes from a string. -func Strip(s string) string { - var ( - buf bytes.Buffer // buffer for collecting printable characters - ri int // rune index - rw int // rune width - pstate = parser.GroundState // initial state - ) - - // This implements a subset of the Parser to only collect runes and - // printable characters. - for i := 0; i < len(s); i++ { - if pstate == parser.Utf8State { - // During this state, collect rw bytes to form a valid rune in the - // buffer. After getting all the rune bytes into the buffer, - // transition to GroundState and reset the counters. - buf.WriteByte(s[i]) - ri++ - if ri < rw { - continue - } - pstate = parser.GroundState - ri = 0 - rw = 0 - continue - } - - state, action := parser.Table.Transition(pstate, s[i]) - switch action { - case parser.CollectAction: - if state == parser.Utf8State { - // This action happens when we transition to the Utf8State. - rw = utf8ByteLen(s[i]) - buf.WriteByte(s[i]) - ri++ - } - case parser.PrintAction, parser.ExecuteAction: - // collects printable ASCII and non-printable characters - buf.WriteByte(s[i]) - } - - // Transition to the next state. - // The Utf8State is managed separately above. - if pstate != parser.Utf8State { - pstate = state - } - } - - return buf.String() -} - -// StringWidth returns the width of a string in cells. This is the number of -// cells that the string will occupy when printed in a terminal. ANSI escape -// codes are ignored and wide characters (such as East Asians and emojis) are -// accounted for. -// This treats the text as a sequence of grapheme clusters. -func StringWidth(s string) int { - return stringWidth(GraphemeWidth, s) -} - -// StringWidthWc returns the width of a string in cells. This is the number of -// cells that the string will occupy when printed in a terminal. ANSI escape -// codes are ignored and wide characters (such as East Asians and emojis) are -// accounted for. -// This treats the text as a sequence of wide characters and runes. -func StringWidthWc(s string) int { - return stringWidth(WcWidth, s) -} - -func stringWidth(m Method, s string) int { - if s == "" { - return 0 - } - - var ( - pstate = parser.GroundState // initial state - cluster string - width int - ) - - for i := 0; i < len(s); i++ { - state, action := parser.Table.Transition(pstate, s[i]) - if state == parser.Utf8State { - var w int - cluster, _, w, _ = uniseg.FirstGraphemeClusterInString(s[i:], -1) - if m == WcWidth { - w = runewidth.StringWidth(cluster) - } - width += w - i += len(cluster) - 1 - pstate = parser.GroundState - continue - } - - if action == parser.PrintAction { - width++ - } - - pstate = state - } - - return width -} diff --git a/vendor/github.com/charmbracelet/x/ansi/winop.go b/vendor/github.com/charmbracelet/x/ansi/winop.go deleted file mode 100644 index 0238780d0a..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/winop.go +++ /dev/null @@ -1,53 +0,0 @@ -package ansi - -import ( - "strconv" - "strings" -) - -const ( - // ResizeWindowWinOp is a window operation that resizes the terminal - // window. - ResizeWindowWinOp = 4 - - // RequestWindowSizeWinOp is a window operation that requests a report of - // the size of the terminal window in pixels. The response is in the form: - // CSI 4 ; height ; width t - RequestWindowSizeWinOp = 14 - - // RequestCellSizeWinOp is a window operation that requests a report of - // the size of the terminal cell size in pixels. The response is in the form: - // CSI 6 ; height ; width t - RequestCellSizeWinOp = 16 -) - -// WindowOp (XTWINOPS) is a sequence that manipulates the terminal window. -// -// CSI Ps ; Ps ; Ps t -// -// Ps is a semicolon-separated list of parameters. -// See https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h4-Functions-using-CSI-_-ordered-by-the-final-character-lparen-s-rparen:CSI-Ps;Ps;Ps-t.1EB0 -func WindowOp(p int, ps ...int) string { - if p <= 0 { - return "" - } - - if len(ps) == 0 { - return "\x1b[" + strconv.Itoa(p) + "t" - } - - params := make([]string, 0, len(ps)+1) - params = append(params, strconv.Itoa(p)) - for _, p := range ps { - if p >= 0 { - params = append(params, strconv.Itoa(p)) - } - } - - return "\x1b[" + strings.Join(params, ";") + "t" -} - -// XTWINOPS is an alias for [WindowOp]. -func XTWINOPS(p int, ps ...int) string { - return WindowOp(p, ps...) -} diff --git a/vendor/github.com/charmbracelet/x/ansi/wrap.go b/vendor/github.com/charmbracelet/x/ansi/wrap.go deleted file mode 100644 index 6b99580085..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/wrap.go +++ /dev/null @@ -1,467 +0,0 @@ -package ansi - -import ( - "bytes" - "unicode" - "unicode/utf8" - - "github.com/charmbracelet/x/ansi/parser" - "github.com/mattn/go-runewidth" - "github.com/rivo/uniseg" -) - -// nbsp is a non-breaking space -const nbsp = 0xA0 - -// Hardwrap wraps a string or a block of text to a given line length, breaking -// word boundaries. This will preserve ANSI escape codes and will account for -// wide-characters in the string. -// When preserveSpace is true, spaces at the beginning of a line will be -// preserved. -// This treats the text as a sequence of graphemes. -func Hardwrap(s string, limit int, preserveSpace bool) string { - return hardwrap(GraphemeWidth, s, limit, preserveSpace) -} - -// HardwrapWc wraps a string or a block of text to a given line length, breaking -// word boundaries. This will preserve ANSI escape codes and will account for -// wide-characters in the string. -// When preserveSpace is true, spaces at the beginning of a line will be -// preserved. -// This treats the text as a sequence of wide characters and runes. -func HardwrapWc(s string, limit int, preserveSpace bool) string { - return hardwrap(WcWidth, s, limit, preserveSpace) -} - -func hardwrap(m Method, s string, limit int, preserveSpace bool) string { - if limit < 1 { - return s - } - - var ( - cluster []byte - buf bytes.Buffer - curWidth int - forceNewline bool - pstate = parser.GroundState // initial state - b = []byte(s) - ) - - addNewline := func() { - buf.WriteByte('\n') - curWidth = 0 - } - - i := 0 - for i < len(b) { - state, action := parser.Table.Transition(pstate, b[i]) - if state == parser.Utf8State { - var width int - cluster, _, width, _ = uniseg.FirstGraphemeCluster(b[i:], -1) - if m == WcWidth { - width = runewidth.StringWidth(string(cluster)) - } - i += len(cluster) - - if curWidth+width > limit { - addNewline() - } - if !preserveSpace && curWidth == 0 && len(cluster) <= 4 { - // Skip spaces at the beginning of a line - if r, _ := utf8.DecodeRune(cluster); r != utf8.RuneError && unicode.IsSpace(r) { - pstate = parser.GroundState - continue - } - } - - buf.Write(cluster) - curWidth += width - pstate = parser.GroundState - continue - } - - switch action { - case parser.PrintAction, parser.ExecuteAction: - if b[i] == '\n' { - addNewline() - forceNewline = false - break - } - - if curWidth+1 > limit { - addNewline() - forceNewline = true - } - - // Skip spaces at the beginning of a line - if curWidth == 0 { - if !preserveSpace && forceNewline && unicode.IsSpace(rune(b[i])) { - break - } - forceNewline = false - } - - buf.WriteByte(b[i]) - if action == parser.PrintAction { - curWidth++ - } - default: - buf.WriteByte(b[i]) - } - - // We manage the UTF8 state separately manually above. - if pstate != parser.Utf8State { - pstate = state - } - i++ - } - - return buf.String() -} - -// Wordwrap wraps a string or a block of text to a given line length, not -// breaking word boundaries. This will preserve ANSI escape codes and will -// account for wide-characters in the string. -// The breakpoints string is a list of characters that are considered -// breakpoints for word wrapping. A hyphen (-) is always considered a -// breakpoint. -// -// Note: breakpoints must be a string of 1-cell wide rune characters. -// -// This treats the text as a sequence of graphemes. -func Wordwrap(s string, limit int, breakpoints string) string { - return wordwrap(GraphemeWidth, s, limit, breakpoints) -} - -// WordwrapWc wraps a string or a block of text to a given line length, not -// breaking word boundaries. This will preserve ANSI escape codes and will -// account for wide-characters in the string. -// The breakpoints string is a list of characters that are considered -// breakpoints for word wrapping. A hyphen (-) is always considered a -// breakpoint. -// -// Note: breakpoints must be a string of 1-cell wide rune characters. -// -// This treats the text as a sequence of wide characters and runes. -func WordwrapWc(s string, limit int, breakpoints string) string { - return wordwrap(WcWidth, s, limit, breakpoints) -} - -func wordwrap(m Method, s string, limit int, breakpoints string) string { - if limit < 1 { - return s - } - - var ( - cluster []byte - buf bytes.Buffer - word bytes.Buffer - space bytes.Buffer - curWidth int - wordLen int - pstate = parser.GroundState // initial state - b = []byte(s) - ) - - addSpace := func() { - curWidth += space.Len() - buf.Write(space.Bytes()) - space.Reset() - } - - addWord := func() { - if word.Len() == 0 { - return - } - - addSpace() - curWidth += wordLen - buf.Write(word.Bytes()) - word.Reset() - wordLen = 0 - } - - addNewline := func() { - buf.WriteByte('\n') - curWidth = 0 - space.Reset() - } - - i := 0 - for i < len(b) { - state, action := parser.Table.Transition(pstate, b[i]) - if state == parser.Utf8State { - var width int - cluster, _, width, _ = uniseg.FirstGraphemeCluster(b[i:], -1) - if m == WcWidth { - width = runewidth.StringWidth(string(cluster)) - } - i += len(cluster) - - r, _ := utf8.DecodeRune(cluster) - if r != utf8.RuneError && unicode.IsSpace(r) && r != nbsp { - addWord() - space.WriteRune(r) - } else if bytes.ContainsAny(cluster, breakpoints) { - addSpace() - addWord() - buf.Write(cluster) - curWidth++ - } else { - word.Write(cluster) - wordLen += width - if curWidth+space.Len()+wordLen > limit && - wordLen < limit { - addNewline() - } - } - - pstate = parser.GroundState - continue - } - - switch action { - case parser.PrintAction, parser.ExecuteAction: - r := rune(b[i]) - switch { - case r == '\n': - if wordLen == 0 { - if curWidth+space.Len() > limit { - curWidth = 0 - } else { - buf.Write(space.Bytes()) - } - space.Reset() - } - - addWord() - addNewline() - case unicode.IsSpace(r): - addWord() - space.WriteByte(b[i]) - case r == '-': - fallthrough - case runeContainsAny(r, breakpoints): - addSpace() - addWord() - buf.WriteByte(b[i]) - curWidth++ - default: - word.WriteByte(b[i]) - wordLen++ - if curWidth+space.Len()+wordLen > limit && - wordLen < limit { - addNewline() - } - } - - default: - word.WriteByte(b[i]) - } - - // We manage the UTF8 state separately manually above. - if pstate != parser.Utf8State { - pstate = state - } - i++ - } - - addWord() - - return buf.String() -} - -// Wrap wraps a string or a block of text to a given line length, breaking word -// boundaries if necessary. This will preserve ANSI escape codes and will -// account for wide-characters in the string. The breakpoints string is a list -// of characters that are considered breakpoints for word wrapping. A hyphen -// (-) is always considered a breakpoint. -// -// Note: breakpoints must be a string of 1-cell wide rune characters. -// -// This treats the text as a sequence of graphemes. -func Wrap(s string, limit int, breakpoints string) string { - return wrap(GraphemeWidth, s, limit, breakpoints) -} - -// WrapWc wraps a string or a block of text to a given line length, breaking word -// boundaries if necessary. This will preserve ANSI escape codes and will -// account for wide-characters in the string. The breakpoints string is a list -// of characters that are considered breakpoints for word wrapping. A hyphen -// (-) is always considered a breakpoint. -// -// Note: breakpoints must be a string of 1-cell wide rune characters. -// -// This treats the text as a sequence of wide characters and runes. -func WrapWc(s string, limit int, breakpoints string) string { - return wrap(WcWidth, s, limit, breakpoints) -} - -func wrap(m Method, s string, limit int, breakpoints string) string { - if limit < 1 { - return s - } - - var ( - cluster []byte - buf bytes.Buffer - word bytes.Buffer - space bytes.Buffer - curWidth int // written width of the line - wordLen int // word buffer len without ANSI escape codes - pstate = parser.GroundState // initial state - b = []byte(s) - ) - - addSpace := func() { - curWidth += space.Len() - buf.Write(space.Bytes()) - space.Reset() - } - - addWord := func() { - if word.Len() == 0 { - return - } - - addSpace() - curWidth += wordLen - buf.Write(word.Bytes()) - word.Reset() - wordLen = 0 - } - - addNewline := func() { - buf.WriteByte('\n') - curWidth = 0 - space.Reset() - } - - i := 0 - for i < len(b) { - state, action := parser.Table.Transition(pstate, b[i]) - if state == parser.Utf8State { - var width int - cluster, _, width, _ = uniseg.FirstGraphemeCluster(b[i:], -1) - if m == WcWidth { - width = runewidth.StringWidth(string(cluster)) - } - i += len(cluster) - - r, _ := utf8.DecodeRune(cluster) - switch { - case r != utf8.RuneError && unicode.IsSpace(r) && r != nbsp: // nbsp is a non-breaking space - addWord() - space.WriteRune(r) - case bytes.ContainsAny(cluster, breakpoints): - addSpace() - if curWidth+wordLen+width > limit { - word.Write(cluster) - wordLen += width - } else { - addWord() - buf.Write(cluster) - curWidth += width - } - default: - if wordLen+width > limit { - // Hardwrap the word if it's too long - addWord() - } - - word.Write(cluster) - wordLen += width - - if curWidth+wordLen+space.Len() > limit { - addNewline() - } - } - - pstate = parser.GroundState - continue - } - - switch action { - case parser.PrintAction, parser.ExecuteAction: - switch r := rune(b[i]); { - case r == '\n': - if wordLen == 0 { - if curWidth+space.Len() > limit { - curWidth = 0 - } else { - // preserve whitespaces - buf.Write(space.Bytes()) - } - space.Reset() - } - - addWord() - addNewline() - case unicode.IsSpace(r): - addWord() - space.WriteRune(r) - case r == '-': - fallthrough - case runeContainsAny(r, breakpoints): - addSpace() - if curWidth+wordLen >= limit { - // We can't fit the breakpoint in the current line, treat - // it as part of the word. - word.WriteRune(r) - wordLen++ - } else { - addWord() - buf.WriteRune(r) - curWidth++ - } - default: - if curWidth == limit { - addNewline() - } - word.WriteRune(r) - wordLen++ - - if wordLen == limit { - // Hardwrap the word if it's too long - addWord() - } - - if curWidth+wordLen+space.Len() > limit { - addNewline() - } - } - - default: - word.WriteByte(b[i]) - } - - // We manage the UTF8 state separately manually above. - if pstate != parser.Utf8State { - pstate = state - } - i++ - } - - if wordLen == 0 { - if curWidth+space.Len() > limit { - curWidth = 0 - } else { - // preserve whitespaces - buf.Write(space.Bytes()) - } - space.Reset() - } - - addWord() - - return buf.String() -} - -func runeContainsAny(r rune, s string) bool { - for _, c := range s { - if c == r { - return true - } - } - return false -} diff --git a/vendor/github.com/charmbracelet/x/ansi/xterm.go b/vendor/github.com/charmbracelet/x/ansi/xterm.go deleted file mode 100644 index 83fd4bdc4e..0000000000 --- a/vendor/github.com/charmbracelet/x/ansi/xterm.go +++ /dev/null @@ -1,138 +0,0 @@ -package ansi - -import "strconv" - -// KeyModifierOptions (XTMODKEYS) sets/resets xterm key modifier options. -// -// Default is 0. -// -// CSI > Pp m -// CSI > Pp ; Pv m -// -// If Pv is omitted, the resource is reset to its initial value. -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Functions-using-CSI-_-ordered-by-the-final-character_s_ -func KeyModifierOptions(p int, vs ...int) string { - var pp, pv string - if p > 0 { - pp = strconv.Itoa(p) - } - - if len(vs) == 0 { - return "\x1b[>" + strconv.Itoa(p) + "m" - } - - v := vs[0] - if v > 0 { - pv = strconv.Itoa(v) - return "\x1b[>" + pp + ";" + pv + "m" - } - - return "\x1b[>" + pp + "m" -} - -// XTMODKEYS is an alias for [KeyModifierOptions]. -func XTMODKEYS(p int, vs ...int) string { - return KeyModifierOptions(p, vs...) -} - -// SetKeyModifierOptions sets xterm key modifier options. -// This is an alias for [KeyModifierOptions]. -func SetKeyModifierOptions(pp int, pv int) string { - return KeyModifierOptions(pp, pv) -} - -// ResetKeyModifierOptions resets xterm key modifier options. -// This is an alias for [KeyModifierOptions]. -func ResetKeyModifierOptions(pp int) string { - return KeyModifierOptions(pp) -} - -// QueryKeyModifierOptions (XTQMODKEYS) requests xterm key modifier options. -// -// Default is 0. -// -// CSI ? Pp m -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Functions-using-CSI-_-ordered-by-the-final-character_s_ -func QueryKeyModifierOptions(pp int) string { - var p string - if pp > 0 { - p = strconv.Itoa(pp) - } - return "\x1b[?" + p + "m" -} - -// XTQMODKEYS is an alias for [QueryKeyModifierOptions]. -func XTQMODKEYS(pp int) string { - return QueryKeyModifierOptions(pp) -} - -// Modify Other Keys (modifyOtherKeys) is an xterm feature that allows the -// terminal to modify the behavior of certain keys to send different escape -// sequences when pressed. -// -// See: https://invisible-island.net/xterm/manpage/xterm.html#VT100-Widget-Resources:modifyOtherKeys -const ( - SetModifyOtherKeys1 = "\x1b[>4;1m" - SetModifyOtherKeys2 = "\x1b[>4;2m" - ResetModifyOtherKeys = "\x1b[>4m" - QueryModifyOtherKeys = "\x1b[?4m" -) - -// ModifyOtherKeys returns a sequence that sets XTerm modifyOtherKeys mode. -// The mode argument specifies the mode to set. -// -// 0: Disable modifyOtherKeys mode. -// 1: Enable modifyOtherKeys mode 1. -// 2: Enable modifyOtherKeys mode 2. -// -// CSI > 4 ; mode m -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Functions-using-CSI-_-ordered-by-the-final-character_s_ -// See: https://invisible-island.net/xterm/manpage/xterm.html#VT100-Widget-Resources:modifyOtherKeys -// -// Deprecated: use [SetModifyOtherKeys1] or [SetModifyOtherKeys2] instead. -func ModifyOtherKeys(mode int) string { - return "\x1b[>4;" + strconv.Itoa(mode) + "m" -} - -// DisableModifyOtherKeys disables the modifyOtherKeys mode. -// -// CSI > 4 ; 0 m -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Functions-using-CSI-_-ordered-by-the-final-character_s_ -// See: https://invisible-island.net/xterm/manpage/xterm.html#VT100-Widget-Resources:modifyOtherKeys -// -// Deprecated: use [ResetModifyOtherKeys] instead. -const DisableModifyOtherKeys = "\x1b[>4;0m" - -// EnableModifyOtherKeys1 enables the modifyOtherKeys mode 1. -// -// CSI > 4 ; 1 m -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Functions-using-CSI-_-ordered-by-the-final-character_s_ -// See: https://invisible-island.net/xterm/manpage/xterm.html#VT100-Widget-Resources:modifyOtherKeys -// -// Deprecated: use [SetModifyOtherKeys1] instead. -const EnableModifyOtherKeys1 = "\x1b[>4;1m" - -// EnableModifyOtherKeys2 enables the modifyOtherKeys mode 2. -// -// CSI > 4 ; 2 m -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Functions-using-CSI-_-ordered-by-the-final-character_s_ -// See: https://invisible-island.net/xterm/manpage/xterm.html#VT100-Widget-Resources:modifyOtherKeys -// -// Deprecated: use [SetModifyOtherKeys2] instead. -const EnableModifyOtherKeys2 = "\x1b[>4;2m" - -// RequestModifyOtherKeys requests the modifyOtherKeys mode. -// -// CSI ? 4 m -// -// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Functions-using-CSI-_-ordered-by-the-final-character_s_ -// See: https://invisible-island.net/xterm/manpage/xterm.html#VT100-Widget-Resources:modifyOtherKeys -// -// Deprecated: use [QueryModifyOtherKeys] instead. -const RequestModifyOtherKeys = "\x1b[?4m" diff --git a/vendor/github.com/charmbracelet/x/cellbuf/LICENSE b/vendor/github.com/charmbracelet/x/cellbuf/LICENSE deleted file mode 100644 index 65a5654e20..0000000000 --- a/vendor/github.com/charmbracelet/x/cellbuf/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 Charmbracelet, Inc. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/charmbracelet/x/cellbuf/buffer.go b/vendor/github.com/charmbracelet/x/cellbuf/buffer.go deleted file mode 100644 index 790d1f7c4c..0000000000 --- a/vendor/github.com/charmbracelet/x/cellbuf/buffer.go +++ /dev/null @@ -1,473 +0,0 @@ -package cellbuf - -import ( - "strings" - - "github.com/mattn/go-runewidth" - "github.com/rivo/uniseg" -) - -// NewCell returns a new cell. This is a convenience function that initializes a -// new cell with the given content. The cell's width is determined by the -// content using [runewidth.RuneWidth]. -// This will only account for the first combined rune in the content. If the -// content is empty, it will return an empty cell with a width of 0. -func NewCell(r rune, comb ...rune) (c *Cell) { - c = new(Cell) - c.Rune = r - c.Width = runewidth.RuneWidth(r) - for _, r := range comb { - if runewidth.RuneWidth(r) > 0 { - break - } - c.Comb = append(c.Comb, r) - } - c.Comb = comb - c.Width = runewidth.StringWidth(string(append([]rune{r}, comb...))) - return -} - -// NewCellString returns a new cell with the given string content. This is a -// convenience function that initializes a new cell with the given content. The -// cell's width is determined by the content using [runewidth.StringWidth]. -// This will only use the first combined rune in the string. If the string is -// empty, it will return an empty cell with a width of 0. -func NewCellString(s string) (c *Cell) { - c = new(Cell) - for i, r := range s { - if i == 0 { - c.Rune = r - // We only care about the first rune's width - c.Width = runewidth.RuneWidth(r) - } else { - if runewidth.RuneWidth(r) > 0 { - break - } - c.Comb = append(c.Comb, r) - } - } - return -} - -// NewGraphemeCell returns a new cell. This is a convenience function that -// initializes a new cell with the given content. The cell's width is determined -// by the content using [uniseg.FirstGraphemeClusterInString]. -// This is used when the content is a grapheme cluster i.e. a sequence of runes -// that form a single visual unit. -// This will only return the first grapheme cluster in the string. If the -// string is empty, it will return an empty cell with a width of 0. -func NewGraphemeCell(s string) (c *Cell) { - g, _, w, _ := uniseg.FirstGraphemeClusterInString(s, -1) - return newGraphemeCell(g, w) -} - -func newGraphemeCell(s string, w int) (c *Cell) { - c = new(Cell) - c.Width = w - for i, r := range s { - if i == 0 { - c.Rune = r - } else { - c.Comb = append(c.Comb, r) - } - } - return -} - -// Line represents a line in the terminal. -// A nil cell represents an blank cell, a cell with a space character and a -// width of 1. -// If a cell has no content and a width of 0, it is a placeholder for a wide -// cell. -type Line []*Cell - -// Width returns the width of the line. -func (l Line) Width() int { - return len(l) -} - -// Len returns the length of the line. -func (l Line) Len() int { - return len(l) -} - -// String returns the string representation of the line. Any trailing spaces -// are removed. -func (l Line) String() (s string) { - for _, c := range l { - if c == nil { - s += " " - } else if c.Empty() { - continue - } else { - s += c.String() - } - } - s = strings.TrimRight(s, " ") - return -} - -// At returns the cell at the given x position. -// If the cell does not exist, it returns nil. -func (l Line) At(x int) *Cell { - if x < 0 || x >= len(l) { - return nil - } - - c := l[x] - if c == nil { - newCell := BlankCell - return &newCell - } - - return c -} - -// Set sets the cell at the given x position. If a wide cell is given, it will -// set the cell and the following cells to [EmptyCell]. It returns true if the -// cell was set. -func (l Line) Set(x int, c *Cell) bool { - return l.set(x, c, true) -} - -func (l Line) set(x int, c *Cell, clone bool) bool { - width := l.Width() - if x < 0 || x >= width { - return false - } - - // When a wide cell is partially overwritten, we need - // to fill the rest of the cell with space cells to - // avoid rendering issues. - prev := l.At(x) - if prev != nil && prev.Width > 1 { - // Writing to the first wide cell - for j := 0; j < prev.Width && x+j < l.Width(); j++ { - l[x+j] = prev.Clone().Blank() - } - } else if prev != nil && prev.Width == 0 { - // Writing to wide cell placeholders - for j := 1; j < maxCellWidth && x-j >= 0; j++ { - wide := l.At(x - j) - if wide != nil && wide.Width > 1 && j < wide.Width { - for k := 0; k < wide.Width; k++ { - l[x-j+k] = wide.Clone().Blank() - } - break - } - } - } - - if clone && c != nil { - // Clone the cell if not nil. - c = c.Clone() - } - - if c != nil && x+c.Width > width { - // If the cell is too wide, we write blanks with the same style. - for i := 0; i < c.Width && x+i < width; i++ { - l[x+i] = c.Clone().Blank() - } - } else { - l[x] = c - - // Mark wide cells with an empty cell zero width - // We set the wide cell down below - if c != nil && c.Width > 1 { - for j := 1; j < c.Width && x+j < l.Width(); j++ { - var wide Cell - l[x+j] = &wide - } - } - } - - return true -} - -// Buffer is a 2D grid of cells representing a screen or terminal. -type Buffer struct { - // Lines holds the lines of the buffer. - Lines []Line -} - -// NewBuffer creates a new buffer with the given width and height. -// This is a convenience function that initializes a new buffer and resizes it. -func NewBuffer(width int, height int) *Buffer { - b := new(Buffer) - b.Resize(width, height) - return b -} - -// String returns the string representation of the buffer. -func (b *Buffer) String() (s string) { - for i, l := range b.Lines { - s += l.String() - if i < len(b.Lines)-1 { - s += "\r\n" - } - } - return -} - -// Line returns a pointer to the line at the given y position. -// If the line does not exist, it returns nil. -func (b *Buffer) Line(y int) Line { - if y < 0 || y >= len(b.Lines) { - return nil - } - return b.Lines[y] -} - -// Cell implements Screen. -func (b *Buffer) Cell(x int, y int) *Cell { - if y < 0 || y >= len(b.Lines) { - return nil - } - return b.Lines[y].At(x) -} - -// maxCellWidth is the maximum width a terminal cell can get. -const maxCellWidth = 4 - -// SetCell sets the cell at the given x, y position. -func (b *Buffer) SetCell(x, y int, c *Cell) bool { - return b.setCell(x, y, c, true) -} - -// setCell sets the cell at the given x, y position. This will always clone and -// allocates a new cell if c is not nil. -func (b *Buffer) setCell(x, y int, c *Cell, clone bool) bool { - if y < 0 || y >= len(b.Lines) { - return false - } - return b.Lines[y].set(x, c, clone) -} - -// Height implements Screen. -func (b *Buffer) Height() int { - return len(b.Lines) -} - -// Width implements Screen. -func (b *Buffer) Width() int { - if len(b.Lines) == 0 { - return 0 - } - return b.Lines[0].Width() -} - -// Bounds returns the bounds of the buffer. -func (b *Buffer) Bounds() Rectangle { - return Rect(0, 0, b.Width(), b.Height()) -} - -// Resize resizes the buffer to the given width and height. -func (b *Buffer) Resize(width int, height int) { - if width == 0 || height == 0 { - b.Lines = nil - return - } - - if width > b.Width() { - line := make(Line, width-b.Width()) - for i := range b.Lines { - b.Lines[i] = append(b.Lines[i], line...) - } - } else if width < b.Width() { - for i := range b.Lines { - b.Lines[i] = b.Lines[i][:width] - } - } - - if height > len(b.Lines) { - for i := len(b.Lines); i < height; i++ { - b.Lines = append(b.Lines, make(Line, width)) - } - } else if height < len(b.Lines) { - b.Lines = b.Lines[:height] - } -} - -// FillRect fills the buffer with the given cell and rectangle. -func (b *Buffer) FillRect(c *Cell, rect Rectangle) { - cellWidth := 1 - if c != nil && c.Width > 1 { - cellWidth = c.Width - } - for y := rect.Min.Y; y < rect.Max.Y; y++ { - for x := rect.Min.X; x < rect.Max.X; x += cellWidth { - b.setCell(x, y, c, false) //nolint:errcheck - } - } -} - -// Fill fills the buffer with the given cell and rectangle. -func (b *Buffer) Fill(c *Cell) { - b.FillRect(c, b.Bounds()) -} - -// Clear clears the buffer with space cells and rectangle. -func (b *Buffer) Clear() { - b.ClearRect(b.Bounds()) -} - -// ClearRect clears the buffer with space cells within the specified -// rectangles. Only cells within the rectangle's bounds are affected. -func (b *Buffer) ClearRect(rect Rectangle) { - b.FillRect(nil, rect) -} - -// InsertLine inserts n lines at the given line position, with the given -// optional cell, within the specified rectangles. If no rectangles are -// specified, it inserts lines in the entire buffer. Only cells within the -// rectangle's horizontal bounds are affected. Lines are pushed out of the -// rectangle bounds and lost. This follows terminal [ansi.IL] behavior. -// It returns the pushed out lines. -func (b *Buffer) InsertLine(y, n int, c *Cell) { - b.InsertLineRect(y, n, c, b.Bounds()) -} - -// InsertLineRect inserts new lines at the given line position, with the -// given optional cell, within the rectangle bounds. Only cells within the -// rectangle's horizontal bounds are affected. Lines are pushed out of the -// rectangle bounds and lost. This follows terminal [ansi.IL] behavior. -func (b *Buffer) InsertLineRect(y, n int, c *Cell, rect Rectangle) { - if n <= 0 || y < rect.Min.Y || y >= rect.Max.Y || y >= b.Height() { - return - } - - // Limit number of lines to insert to available space - if y+n > rect.Max.Y { - n = rect.Max.Y - y - } - - // Move existing lines down within the bounds - for i := rect.Max.Y - 1; i >= y+n; i-- { - for x := rect.Min.X; x < rect.Max.X; x++ { - // We don't need to clone c here because we're just moving lines down. - b.setCell(x, i, b.Lines[i-n][x], false) - } - } - - // Clear the newly inserted lines within bounds - for i := y; i < y+n; i++ { - for x := rect.Min.X; x < rect.Max.X; x++ { - b.setCell(x, i, c, true) - } - } -} - -// DeleteLineRect deletes lines at the given line position, with the given -// optional cell, within the rectangle bounds. Only cells within the -// rectangle's bounds are affected. Lines are shifted up within the bounds and -// new blank lines are created at the bottom. This follows terminal [ansi.DL] -// behavior. -func (b *Buffer) DeleteLineRect(y, n int, c *Cell, rect Rectangle) { - if n <= 0 || y < rect.Min.Y || y >= rect.Max.Y || y >= b.Height() { - return - } - - // Limit deletion count to available space in scroll region - if n > rect.Max.Y-y { - n = rect.Max.Y - y - } - - // Shift cells up within the bounds - for dst := y; dst < rect.Max.Y-n; dst++ { - src := dst + n - for x := rect.Min.X; x < rect.Max.X; x++ { - // We don't need to clone c here because we're just moving cells up. - // b.lines[dst][x] = b.lines[src][x] - b.setCell(x, dst, b.Lines[src][x], false) - } - } - - // Fill the bottom n lines with blank cells - for i := rect.Max.Y - n; i < rect.Max.Y; i++ { - for x := rect.Min.X; x < rect.Max.X; x++ { - b.setCell(x, i, c, true) - } - } -} - -// DeleteLine deletes n lines at the given line position, with the given -// optional cell, within the specified rectangles. If no rectangles are -// specified, it deletes lines in the entire buffer. -func (b *Buffer) DeleteLine(y, n int, c *Cell) { - b.DeleteLineRect(y, n, c, b.Bounds()) -} - -// InsertCell inserts new cells at the given position, with the given optional -// cell, within the specified rectangles. If no rectangles are specified, it -// inserts cells in the entire buffer. This follows terminal [ansi.ICH] -// behavior. -func (b *Buffer) InsertCell(x, y, n int, c *Cell) { - b.InsertCellRect(x, y, n, c, b.Bounds()) -} - -// InsertCellRect inserts new cells at the given position, with the given -// optional cell, within the rectangle bounds. Only cells within the -// rectangle's bounds are affected, following terminal [ansi.ICH] behavior. -func (b *Buffer) InsertCellRect(x, y, n int, c *Cell, rect Rectangle) { - if n <= 0 || y < rect.Min.Y || y >= rect.Max.Y || y >= b.Height() || - x < rect.Min.X || x >= rect.Max.X || x >= b.Width() { - return - } - - // Limit number of cells to insert to available space - if x+n > rect.Max.X { - n = rect.Max.X - x - } - - // Move existing cells within rectangle bounds to the right - for i := rect.Max.X - 1; i >= x+n && i-n >= rect.Min.X; i-- { - // We don't need to clone c here because we're just moving cells to the - // right. - // b.lines[y][i] = b.lines[y][i-n] - b.setCell(i, y, b.Lines[y][i-n], false) - } - - // Clear the newly inserted cells within rectangle bounds - for i := x; i < x+n && i < rect.Max.X; i++ { - b.setCell(i, y, c, true) - } -} - -// DeleteCell deletes cells at the given position, with the given optional -// cell, within the specified rectangles. If no rectangles are specified, it -// deletes cells in the entire buffer. This follows terminal [ansi.DCH] -// behavior. -func (b *Buffer) DeleteCell(x, y, n int, c *Cell) { - b.DeleteCellRect(x, y, n, c, b.Bounds()) -} - -// DeleteCellRect deletes cells at the given position, with the given -// optional cell, within the rectangle bounds. Only cells within the -// rectangle's bounds are affected, following terminal [ansi.DCH] behavior. -func (b *Buffer) DeleteCellRect(x, y, n int, c *Cell, rect Rectangle) { - if n <= 0 || y < rect.Min.Y || y >= rect.Max.Y || y >= b.Height() || - x < rect.Min.X || x >= rect.Max.X || x >= b.Width() { - return - } - - // Calculate how many positions we can actually delete - remainingCells := rect.Max.X - x - if n > remainingCells { - n = remainingCells - } - - // Shift the remaining cells to the left - for i := x; i < rect.Max.X-n; i++ { - if i+n < rect.Max.X { - // We don't need to clone c here because we're just moving cells to - // the left. - // b.lines[y][i] = b.lines[y][i+n] - b.setCell(i, y, b.Lines[y][i+n], false) - } - } - - // Fill the vacated positions with the given cell - for i := rect.Max.X - n; i < rect.Max.X; i++ { - b.setCell(i, y, c, true) - } -} diff --git a/vendor/github.com/charmbracelet/x/cellbuf/cell.go b/vendor/github.com/charmbracelet/x/cellbuf/cell.go deleted file mode 100644 index 991c919e75..0000000000 --- a/vendor/github.com/charmbracelet/x/cellbuf/cell.go +++ /dev/null @@ -1,503 +0,0 @@ -package cellbuf - -import ( - "github.com/charmbracelet/x/ansi" -) - -var ( - // BlankCell is a cell with a single space, width of 1, and no style or link. - BlankCell = Cell{Rune: ' ', Width: 1} - - // EmptyCell is just an empty cell used for comparisons and as a placeholder - // for wide cells. - EmptyCell = Cell{} -) - -// Cell represents a single cell in the terminal screen. -type Cell struct { - // The style of the cell. Nil style means no style. Zero value prints a - // reset sequence. - Style Style - - // Link is the hyperlink of the cell. - Link Link - - // Comb is the combining runes of the cell. This is nil if the cell is a - // single rune or if it's a zero width cell that is part of a wider cell. - Comb []rune - - // Width is the mono-space width of the grapheme cluster. - Width int - - // Rune is the main rune of the cell. This is zero if the cell is part of a - // wider cell. - Rune rune -} - -// Append appends runes to the cell without changing the width. This is useful -// when we want to use the cell to store escape sequences or other runes that -// don't affect the width of the cell. -func (c *Cell) Append(r ...rune) { - for i, r := range r { - if i == 0 && c.Rune == 0 { - c.Rune = r - continue - } - c.Comb = append(c.Comb, r) - } -} - -// String returns the string content of the cell excluding any styles, links, -// and escape sequences. -func (c Cell) String() string { - if c.Rune == 0 { - return "" - } - if len(c.Comb) == 0 { - return string(c.Rune) - } - return string(append([]rune{c.Rune}, c.Comb...)) -} - -// Equal returns whether the cell is equal to the other cell. -func (c *Cell) Equal(o *Cell) bool { - return o != nil && - c.Width == o.Width && - c.Rune == o.Rune && - runesEqual(c.Comb, o.Comb) && - c.Style.Equal(&o.Style) && - c.Link.Equal(&o.Link) -} - -// Empty returns whether the cell is an empty cell. An empty cell is a cell -// with a width of 0, a rune of 0, and no combining runes. -func (c Cell) Empty() bool { - return c.Width == 0 && - c.Rune == 0 && - len(c.Comb) == 0 -} - -// Reset resets the cell to the default state zero value. -func (c *Cell) Reset() { - c.Rune = 0 - c.Comb = nil - c.Width = 0 - c.Style.Reset() - c.Link.Reset() -} - -// Clear returns whether the cell consists of only attributes that don't -// affect appearance of a space character. -func (c *Cell) Clear() bool { - return c.Rune == ' ' && len(c.Comb) == 0 && c.Width == 1 && c.Style.Clear() && c.Link.Empty() -} - -// Clone returns a copy of the cell. -func (c *Cell) Clone() (n *Cell) { - n = new(Cell) - *n = *c - return -} - -// Blank makes the cell a blank cell by setting the rune to a space, comb to -// nil, and the width to 1. -func (c *Cell) Blank() *Cell { - c.Rune = ' ' - c.Comb = nil - c.Width = 1 - return c -} - -// Link represents a hyperlink in the terminal screen. -type Link struct { - URL string - Params string -} - -// String returns a string representation of the hyperlink. -func (h Link) String() string { - return h.URL -} - -// Reset resets the hyperlink to the default state zero value. -func (h *Link) Reset() { - h.URL = "" - h.Params = "" -} - -// Equal returns whether the hyperlink is equal to the other hyperlink. -func (h *Link) Equal(o *Link) bool { - return o != nil && h.URL == o.URL && h.Params == o.Params -} - -// Empty returns whether the hyperlink is empty. -func (h Link) Empty() bool { - return h.URL == "" && h.Params == "" -} - -// AttrMask is a bitmask for text attributes that can change the look of text. -// These attributes can be combined to create different styles. -type AttrMask uint8 - -// These are the available text attributes that can be combined to create -// different styles. -const ( - BoldAttr AttrMask = 1 << iota - FaintAttr - ItalicAttr - SlowBlinkAttr - RapidBlinkAttr - ReverseAttr - ConcealAttr - StrikethroughAttr - - ResetAttr AttrMask = 0 -) - -// UnderlineStyle is the style of underline to use for text. -type UnderlineStyle = ansi.UnderlineStyle - -// These are the available underline styles. -const ( - NoUnderline = ansi.NoUnderlineStyle - SingleUnderline = ansi.SingleUnderlineStyle - DoubleUnderline = ansi.DoubleUnderlineStyle - CurlyUnderline = ansi.CurlyUnderlineStyle - DottedUnderline = ansi.DottedUnderlineStyle - DashedUnderline = ansi.DashedUnderlineStyle -) - -// Style represents the Style of a cell. -type Style struct { - Fg ansi.Color - Bg ansi.Color - Ul ansi.Color - Attrs AttrMask - UlStyle UnderlineStyle -} - -// Sequence returns the ANSI sequence that sets the style. -func (s Style) Sequence() string { - if s.Empty() { - return ansi.ResetStyle - } - - var b ansi.Style - - if s.Attrs != 0 { - if s.Attrs&BoldAttr != 0 { - b = b.Bold() - } - if s.Attrs&FaintAttr != 0 { - b = b.Faint() - } - if s.Attrs&ItalicAttr != 0 { - b = b.Italic() - } - if s.Attrs&SlowBlinkAttr != 0 { - b = b.SlowBlink() - } - if s.Attrs&RapidBlinkAttr != 0 { - b = b.RapidBlink() - } - if s.Attrs&ReverseAttr != 0 { - b = b.Reverse() - } - if s.Attrs&ConcealAttr != 0 { - b = b.Conceal() - } - if s.Attrs&StrikethroughAttr != 0 { - b = b.Strikethrough() - } - } - if s.UlStyle != NoUnderline { - switch s.UlStyle { - case SingleUnderline: - b = b.Underline() - case DoubleUnderline: - b = b.DoubleUnderline() - case CurlyUnderline: - b = b.CurlyUnderline() - case DottedUnderline: - b = b.DottedUnderline() - case DashedUnderline: - b = b.DashedUnderline() - } - } - if s.Fg != nil { - b = b.ForegroundColor(s.Fg) - } - if s.Bg != nil { - b = b.BackgroundColor(s.Bg) - } - if s.Ul != nil { - b = b.UnderlineColor(s.Ul) - } - - return b.String() -} - -// DiffSequence returns the ANSI sequence that sets the style as a diff from -// another style. -func (s Style) DiffSequence(o Style) string { - if o.Empty() { - return s.Sequence() - } - - var b ansi.Style - - if !colorEqual(s.Fg, o.Fg) { - b = b.ForegroundColor(s.Fg) - } - - if !colorEqual(s.Bg, o.Bg) { - b = b.BackgroundColor(s.Bg) - } - - if !colorEqual(s.Ul, o.Ul) { - b = b.UnderlineColor(s.Ul) - } - - var ( - noBlink bool - isNormal bool - ) - - if s.Attrs != o.Attrs { - if s.Attrs&BoldAttr != o.Attrs&BoldAttr { - if s.Attrs&BoldAttr != 0 { - b = b.Bold() - } else if !isNormal { - isNormal = true - b = b.NormalIntensity() - } - } - if s.Attrs&FaintAttr != o.Attrs&FaintAttr { - if s.Attrs&FaintAttr != 0 { - b = b.Faint() - } else if !isNormal { - b = b.NormalIntensity() - } - } - if s.Attrs&ItalicAttr != o.Attrs&ItalicAttr { - if s.Attrs&ItalicAttr != 0 { - b = b.Italic() - } else { - b = b.NoItalic() - } - } - if s.Attrs&SlowBlinkAttr != o.Attrs&SlowBlinkAttr { - if s.Attrs&SlowBlinkAttr != 0 { - b = b.SlowBlink() - } else if !noBlink { - noBlink = true - b = b.NoBlink() - } - } - if s.Attrs&RapidBlinkAttr != o.Attrs&RapidBlinkAttr { - if s.Attrs&RapidBlinkAttr != 0 { - b = b.RapidBlink() - } else if !noBlink { - b = b.NoBlink() - } - } - if s.Attrs&ReverseAttr != o.Attrs&ReverseAttr { - if s.Attrs&ReverseAttr != 0 { - b = b.Reverse() - } else { - b = b.NoReverse() - } - } - if s.Attrs&ConcealAttr != o.Attrs&ConcealAttr { - if s.Attrs&ConcealAttr != 0 { - b = b.Conceal() - } else { - b = b.NoConceal() - } - } - if s.Attrs&StrikethroughAttr != o.Attrs&StrikethroughAttr { - if s.Attrs&StrikethroughAttr != 0 { - b = b.Strikethrough() - } else { - b = b.NoStrikethrough() - } - } - } - - if s.UlStyle != o.UlStyle { - b = b.UnderlineStyle(s.UlStyle) - } - - return b.String() -} - -// Equal returns true if the style is equal to the other style. -func (s *Style) Equal(o *Style) bool { - return s.Attrs == o.Attrs && - s.UlStyle == o.UlStyle && - colorEqual(s.Fg, o.Fg) && - colorEqual(s.Bg, o.Bg) && - colorEqual(s.Ul, o.Ul) -} - -func colorEqual(c, o ansi.Color) bool { - if c == nil && o == nil { - return true - } - if c == nil || o == nil { - return false - } - cr, cg, cb, ca := c.RGBA() - or, og, ob, oa := o.RGBA() - return cr == or && cg == og && cb == ob && ca == oa -} - -// Bold sets the bold attribute. -func (s *Style) Bold(v bool) *Style { - if v { - s.Attrs |= BoldAttr - } else { - s.Attrs &^= BoldAttr - } - return s -} - -// Faint sets the faint attribute. -func (s *Style) Faint(v bool) *Style { - if v { - s.Attrs |= FaintAttr - } else { - s.Attrs &^= FaintAttr - } - return s -} - -// Italic sets the italic attribute. -func (s *Style) Italic(v bool) *Style { - if v { - s.Attrs |= ItalicAttr - } else { - s.Attrs &^= ItalicAttr - } - return s -} - -// SlowBlink sets the slow blink attribute. -func (s *Style) SlowBlink(v bool) *Style { - if v { - s.Attrs |= SlowBlinkAttr - } else { - s.Attrs &^= SlowBlinkAttr - } - return s -} - -// RapidBlink sets the rapid blink attribute. -func (s *Style) RapidBlink(v bool) *Style { - if v { - s.Attrs |= RapidBlinkAttr - } else { - s.Attrs &^= RapidBlinkAttr - } - return s -} - -// Reverse sets the reverse attribute. -func (s *Style) Reverse(v bool) *Style { - if v { - s.Attrs |= ReverseAttr - } else { - s.Attrs &^= ReverseAttr - } - return s -} - -// Conceal sets the conceal attribute. -func (s *Style) Conceal(v bool) *Style { - if v { - s.Attrs |= ConcealAttr - } else { - s.Attrs &^= ConcealAttr - } - return s -} - -// Strikethrough sets the strikethrough attribute. -func (s *Style) Strikethrough(v bool) *Style { - if v { - s.Attrs |= StrikethroughAttr - } else { - s.Attrs &^= StrikethroughAttr - } - return s -} - -// UnderlineStyle sets the underline style. -func (s *Style) UnderlineStyle(style UnderlineStyle) *Style { - s.UlStyle = style - return s -} - -// Underline sets the underline attribute. -// This is a syntactic sugar for [UnderlineStyle]. -func (s *Style) Underline(v bool) *Style { - if v { - return s.UnderlineStyle(SingleUnderline) - } - return s.UnderlineStyle(NoUnderline) -} - -// Foreground sets the foreground color. -func (s *Style) Foreground(c ansi.Color) *Style { - s.Fg = c - return s -} - -// Background sets the background color. -func (s *Style) Background(c ansi.Color) *Style { - s.Bg = c - return s -} - -// UnderlineColor sets the underline color. -func (s *Style) UnderlineColor(c ansi.Color) *Style { - s.Ul = c - return s -} - -// Reset resets the style to default. -func (s *Style) Reset() *Style { - s.Fg = nil - s.Bg = nil - s.Ul = nil - s.Attrs = ResetAttr - s.UlStyle = NoUnderline - return s -} - -// Empty returns true if the style is empty. -func (s *Style) Empty() bool { - return s.Fg == nil && s.Bg == nil && s.Ul == nil && s.Attrs == ResetAttr && s.UlStyle == NoUnderline -} - -// Clear returns whether the style consists of only attributes that don't -// affect appearance of a space character. -func (s *Style) Clear() bool { - return s.UlStyle == NoUnderline && - s.Attrs&^(BoldAttr|FaintAttr|ItalicAttr|SlowBlinkAttr|RapidBlinkAttr) == 0 && - s.Fg == nil && - s.Bg == nil && - s.Ul == nil -} - -func runesEqual(a, b []rune) bool { - if len(a) != len(b) { - return false - } - for i, r := range a { - if r != b[i] { - return false - } - } - return true -} diff --git a/vendor/github.com/charmbracelet/x/cellbuf/errors.go b/vendor/github.com/charmbracelet/x/cellbuf/errors.go deleted file mode 100644 index 64258fe330..0000000000 --- a/vendor/github.com/charmbracelet/x/cellbuf/errors.go +++ /dev/null @@ -1,6 +0,0 @@ -package cellbuf - -import "errors" - -// ErrOutOfBounds is returned when the given x, y position is out of bounds. -var ErrOutOfBounds = errors.New("out of bounds") diff --git a/vendor/github.com/charmbracelet/x/cellbuf/geom.go b/vendor/github.com/charmbracelet/x/cellbuf/geom.go deleted file mode 100644 index c12e6fb1dc..0000000000 --- a/vendor/github.com/charmbracelet/x/cellbuf/geom.go +++ /dev/null @@ -1,21 +0,0 @@ -package cellbuf - -import ( - "image" -) - -// Position represents an x, y position. -type Position = image.Point - -// Pos is a shorthand for Position{X: x, Y: y}. -func Pos(x, y int) Position { - return image.Pt(x, y) -} - -// Rectange represents a rectangle. -type Rectangle = image.Rectangle - -// Rect is a shorthand for Rectangle. -func Rect(x, y, w, h int) Rectangle { - return image.Rect(x, y, x+w, y+h) -} diff --git a/vendor/github.com/charmbracelet/x/cellbuf/hardscroll.go b/vendor/github.com/charmbracelet/x/cellbuf/hardscroll.go deleted file mode 100644 index 402ac06a69..0000000000 --- a/vendor/github.com/charmbracelet/x/cellbuf/hardscroll.go +++ /dev/null @@ -1,272 +0,0 @@ -package cellbuf - -import ( - "strings" - - "github.com/charmbracelet/x/ansi" -) - -// scrollOptimize optimizes the screen to transform the old buffer into the new -// buffer. -func (s *Screen) scrollOptimize() { - height := s.newbuf.Height() - if s.oldnum == nil || len(s.oldnum) < height { - s.oldnum = make([]int, height) - } - - // Calculate the indices - s.updateHashmap() - if len(s.hashtab) < height { - return - } - - // Pass 1 - from top to bottom scrolling up - for i := 0; i < height; { - for i < height && (s.oldnum[i] == newIndex || s.oldnum[i] <= i) { - i++ - } - if i >= height { - break - } - - shift := s.oldnum[i] - i // shift > 0 - start := i - - i++ - for i < height && s.oldnum[i] != newIndex && s.oldnum[i]-i == shift { - i++ - } - end := i - 1 + shift - - if !s.scrolln(shift, start, end, height-1) { - continue - } - } - - // Pass 2 - from bottom to top scrolling down - for i := height - 1; i >= 0; { - for i >= 0 && (s.oldnum[i] == newIndex || s.oldnum[i] >= i) { - i-- - } - if i < 0 { - break - } - - shift := s.oldnum[i] - i // shift < 0 - end := i - - i-- - for i >= 0 && s.oldnum[i] != newIndex && s.oldnum[i]-i == shift { - i-- - } - - start := i + 1 - (-shift) - if !s.scrolln(shift, start, end, height-1) { - continue - } - } -} - -// scrolln scrolls the screen up by n lines. -func (s *Screen) scrolln(n, top, bot, maxY int) (v bool) { //nolint:unparam - const ( - nonDestScrollRegion = false - memoryBelow = false - ) - - blank := s.clearBlank() - if n > 0 { - // Scroll up (forward) - v = s.scrollUp(n, top, bot, 0, maxY, blank) - if !v { - s.buf.WriteString(ansi.SetTopBottomMargins(top+1, bot+1)) - - // XXX: How should we handle this in inline mode when not using alternate screen? - s.cur.X, s.cur.Y = -1, -1 - v = s.scrollUp(n, top, bot, top, bot, blank) - s.buf.WriteString(ansi.SetTopBottomMargins(1, maxY+1)) - s.cur.X, s.cur.Y = -1, -1 - } - - if !v { - v = s.scrollIdl(n, top, bot-n+1, blank) - } - - // Clear newly shifted-in lines. - if v && - (nonDestScrollRegion || (memoryBelow && bot == maxY)) { - if bot == maxY { - s.move(0, bot-n+1) - s.clearToBottom(nil) - } else { - for i := 0; i < n; i++ { - s.move(0, bot-i) - s.clearToEnd(nil, false) - } - } - } - } else if n < 0 { - // Scroll down (backward) - v = s.scrollDown(-n, top, bot, 0, maxY, blank) - if !v { - s.buf.WriteString(ansi.SetTopBottomMargins(top+1, bot+1)) - - // XXX: How should we handle this in inline mode when not using alternate screen? - s.cur.X, s.cur.Y = -1, -1 - v = s.scrollDown(-n, top, bot, top, bot, blank) - s.buf.WriteString(ansi.SetTopBottomMargins(1, maxY+1)) - s.cur.X, s.cur.Y = -1, -1 - - if !v { - v = s.scrollIdl(-n, bot+n+1, top, blank) - } - - // Clear newly shifted-in lines. - if v && - (nonDestScrollRegion || (memoryBelow && top == 0)) { - for i := 0; i < -n; i++ { - s.move(0, top+i) - s.clearToEnd(nil, false) - } - } - } - } - - if !v { - return - } - - s.scrollBuffer(s.curbuf, n, top, bot, blank) - - // shift hash values too, they can be reused - s.scrollOldhash(n, top, bot) - - return true -} - -// scrollBuffer scrolls the buffer by n lines. -func (s *Screen) scrollBuffer(b *Buffer, n, top, bot int, blank *Cell) { - if top < 0 || bot < top || bot >= b.Height() { - // Nothing to scroll - return - } - - if n < 0 { - // shift n lines downwards - limit := top - n - for line := bot; line >= limit && line >= 0 && line >= top; line-- { - copy(b.Lines[line], b.Lines[line+n]) - } - for line := top; line < limit && line <= b.Height()-1 && line <= bot; line++ { - b.FillRect(blank, Rect(0, line, b.Width(), 1)) - } - } - - if n > 0 { - // shift n lines upwards - limit := bot - n - for line := top; line <= limit && line <= b.Height()-1 && line <= bot; line++ { - copy(b.Lines[line], b.Lines[line+n]) - } - for line := bot; line > limit && line >= 0 && line >= top; line-- { - b.FillRect(blank, Rect(0, line, b.Width(), 1)) - } - } - - s.touchLine(b.Width(), b.Height(), top, bot-top+1, true) -} - -// touchLine marks the line as touched. -func (s *Screen) touchLine(width, height, y, n int, changed bool) { - if n < 0 || y < 0 || y >= height { - return // Nothing to touch - } - - for i := y; i < y+n && i < height; i++ { - if changed { - s.touch[i] = lineData{firstCell: 0, lastCell: width - 1} - } else { - delete(s.touch, i) - } - } -} - -// scrollUp scrolls the screen up by n lines. -func (s *Screen) scrollUp(n, top, bot, minY, maxY int, blank *Cell) bool { - if n == 1 && top == minY && bot == maxY { - s.move(0, bot) - s.updatePen(blank) - s.buf.WriteByte('\n') - } else if n == 1 && bot == maxY { - s.move(0, top) - s.updatePen(blank) - s.buf.WriteString(ansi.DeleteLine(1)) - } else if top == minY && bot == maxY { - if s.xtermLike { - s.move(0, bot) - } else { - s.move(0, top) - } - s.updatePen(blank) - if s.xtermLike { - s.buf.WriteString(ansi.ScrollUp(n)) - } else { - s.buf.WriteString(strings.Repeat("\n", n)) - } - } else if bot == maxY { - s.move(0, top) - s.updatePen(blank) - s.buf.WriteString(ansi.DeleteLine(n)) - } else { - return false - } - return true -} - -// scrollDown scrolls the screen down by n lines. -func (s *Screen) scrollDown(n, top, bot, minY, maxY int, blank *Cell) bool { - if n == 1 && top == minY && bot == maxY { - s.move(0, top) - s.updatePen(blank) - s.buf.WriteString(ansi.ReverseIndex) - } else if n == 1 && bot == maxY { - s.move(0, top) - s.updatePen(blank) - s.buf.WriteString(ansi.InsertLine(1)) - } else if top == minY && bot == maxY { - s.move(0, top) - s.updatePen(blank) - if s.xtermLike { - s.buf.WriteString(ansi.ScrollDown(n)) - } else { - s.buf.WriteString(strings.Repeat(ansi.ReverseIndex, n)) - } - } else if bot == maxY { - s.move(0, top) - s.updatePen(blank) - s.buf.WriteString(ansi.InsertLine(n)) - } else { - return false - } - return true -} - -// scrollIdl scrolls the screen n lines by using [ansi.DL] at del and using -// [ansi.IL] at ins. -func (s *Screen) scrollIdl(n, del, ins int, blank *Cell) bool { - if n < 0 { - return false - } - - // Delete lines - s.move(0, del) - s.updatePen(blank) - s.buf.WriteString(ansi.DeleteLine(n)) - - // Insert lines - s.move(0, ins) - s.updatePen(blank) - s.buf.WriteString(ansi.InsertLine(n)) - - return true -} diff --git a/vendor/github.com/charmbracelet/x/cellbuf/hashmap.go b/vendor/github.com/charmbracelet/x/cellbuf/hashmap.go deleted file mode 100644 index 0d25b5492c..0000000000 --- a/vendor/github.com/charmbracelet/x/cellbuf/hashmap.go +++ /dev/null @@ -1,301 +0,0 @@ -package cellbuf - -import ( - "github.com/charmbracelet/x/ansi" -) - -// hash returns the hash value of a [Line]. -func hash(l Line) (h uint64) { - for _, c := range l { - var r rune - if c == nil { - r = ansi.SP - } else { - r = c.Rune - } - h += (h << 5) + uint64(r) - } - return -} - -// hashmap represents a single [Line] hash. -type hashmap struct { - value uint64 - oldcount, newcount int - oldindex, newindex int -} - -// The value used to indicate lines created by insertions and scrolls. -const newIndex = -1 - -// updateHashmap updates the hashmap with the new hash value. -func (s *Screen) updateHashmap() { - height := s.newbuf.Height() - if len(s.oldhash) >= height && len(s.newhash) >= height { - // rehash changed lines - for i := 0; i < height; i++ { - _, ok := s.touch[i] - if ok { - s.oldhash[i] = hash(s.curbuf.Line(i)) - s.newhash[i] = hash(s.newbuf.Line(i)) - } - } - } else { - // rehash all - if len(s.oldhash) != height { - s.oldhash = make([]uint64, height) - } - if len(s.newhash) != height { - s.newhash = make([]uint64, height) - } - for i := 0; i < height; i++ { - s.oldhash[i] = hash(s.curbuf.Line(i)) - s.newhash[i] = hash(s.newbuf.Line(i)) - } - } - - s.hashtab = make([]hashmap, height*2) - for i := 0; i < height; i++ { - hashval := s.oldhash[i] - - // Find matching hash or empty slot - idx := 0 - for idx < len(s.hashtab) && s.hashtab[idx].value != 0 { - if s.hashtab[idx].value == hashval { - break - } - idx++ - } - - s.hashtab[idx].value = hashval // in case this is a new hash - s.hashtab[idx].oldcount++ - s.hashtab[idx].oldindex = i - } - for i := 0; i < height; i++ { - hashval := s.newhash[i] - - // Find matching hash or empty slot - idx := 0 - for idx < len(s.hashtab) && s.hashtab[idx].value != 0 { - if s.hashtab[idx].value == hashval { - break - } - idx++ - } - - s.hashtab[idx].value = hashval // in case this is a new hash - s.hashtab[idx].newcount++ - s.hashtab[idx].newindex = i - - s.oldnum[i] = newIndex // init old indices slice - } - - // Mark line pair corresponding to unique hash pairs. - for i := 0; i < len(s.hashtab) && s.hashtab[i].value != 0; i++ { - hsp := &s.hashtab[i] - if hsp.oldcount == 1 && hsp.newcount == 1 && hsp.oldindex != hsp.newindex { - s.oldnum[hsp.newindex] = hsp.oldindex - } - } - - s.growHunks() - - // Eliminate bad or impossible shifts. This includes removing those hunks - // which could not grow because of conflicts, as well those which are to be - // moved too far, they are likely to destroy more than carry. - for i := 0; i < height; { - var start, shift, size int - for i < height && s.oldnum[i] == newIndex { - i++ - } - if i >= height { - break - } - start = i - shift = s.oldnum[i] - i - i++ - for i < height && s.oldnum[i] != newIndex && s.oldnum[i]-i == shift { - i++ - } - size = i - start - if size < 3 || size+min(size/8, 2) < abs(shift) { - for start < i { - s.oldnum[start] = newIndex - start++ - } - } - } - - // After clearing invalid hunks, try grow the rest. - s.growHunks() -} - -// scrollOldhash -func (s *Screen) scrollOldhash(n, top, bot int) { - if len(s.oldhash) == 0 { - return - } - - size := bot - top + 1 - abs(n) - if n > 0 { - // Move existing hashes up - copy(s.oldhash[top:], s.oldhash[top+n:top+n+size]) - // Recalculate hashes for newly shifted-in lines - for i := bot; i > bot-n; i-- { - s.oldhash[i] = hash(s.curbuf.Line(i)) - } - } else { - // Move existing hashes down - copy(s.oldhash[top-n:], s.oldhash[top:top+size]) - // Recalculate hashes for newly shifted-in lines - for i := top; i < top-n; i++ { - s.oldhash[i] = hash(s.curbuf.Line(i)) - } - } -} - -func (s *Screen) growHunks() { - var ( - backLimit int // limits for cells to fill - backRefLimit int // limit for references - i int - nextHunk int - ) - - height := s.newbuf.Height() - for i < height && s.oldnum[i] == newIndex { - i++ - } - for ; i < height; i = nextHunk { - var ( - forwardLimit int - forwardRefLimit int - end int - start = i - shift = s.oldnum[i] - i - ) - - // get forward limit - i = start + 1 - for i < height && - s.oldnum[i] != newIndex && - s.oldnum[i]-i == shift { - i++ - } - - end = i - for i < height && s.oldnum[i] == newIndex { - i++ - } - - nextHunk = i - forwardLimit = i - if i >= height || s.oldnum[i] >= i { - forwardRefLimit = i - } else { - forwardRefLimit = s.oldnum[i] - } - - i = start - 1 - - // grow back - if shift < 0 { - backLimit = backRefLimit + (-shift) - } - for i >= backLimit { - if s.newhash[i] == s.oldhash[i+shift] || - s.costEffective(i+shift, i, shift < 0) { - s.oldnum[i] = i + shift - } else { - break - } - i-- - } - - i = end - // grow forward - if shift > 0 { - forwardLimit = forwardRefLimit - shift - } - for i < forwardLimit { - if s.newhash[i] == s.oldhash[i+shift] || - s.costEffective(i+shift, i, shift > 0) { - s.oldnum[i] = i + shift - } else { - break - } - i++ - } - - backLimit = i - backRefLimit = backLimit - if shift > 0 { - backRefLimit += shift - } - } -} - -// costEffective returns true if the cost of moving line 'from' to line 'to' seems to be -// cost effective. 'blank' indicates whether the line 'to' would become blank. -func (s *Screen) costEffective(from, to int, blank bool) bool { - if from == to { - return false - } - - newFrom := s.oldnum[from] - if newFrom == newIndex { - newFrom = from - } - - // On the left side of >= is the cost before moving. On the right side -- - // cost after moving. - - // Calculate costs before moving. - var costBeforeMove int - if blank { - // Cost of updating blank line at destination. - costBeforeMove = s.updateCostBlank(s.newbuf.Line(to)) - } else { - // Cost of updating exiting line at destination. - costBeforeMove = s.updateCost(s.curbuf.Line(to), s.newbuf.Line(to)) - } - - // Add cost of updating source line - costBeforeMove += s.updateCost(s.curbuf.Line(newFrom), s.newbuf.Line(from)) - - // Calculate costs after moving. - var costAfterMove int - if newFrom == from { - // Source becomes blank after move - costAfterMove = s.updateCostBlank(s.newbuf.Line(from)) - } else { - // Source gets updated from another line - costAfterMove = s.updateCost(s.curbuf.Line(newFrom), s.newbuf.Line(from)) - } - - // Add cost of moving source line to destination - costAfterMove += s.updateCost(s.curbuf.Line(from), s.newbuf.Line(to)) - - // Return true if moving is cost effective (costs less or equal) - return costBeforeMove >= costAfterMove -} - -func (s *Screen) updateCost(from, to Line) (cost int) { - var fidx, tidx int - for i := s.newbuf.Width() - 1; i > 0; i, fidx, tidx = i-1, fidx+1, tidx+1 { - if !cellEqual(from.At(fidx), to.At(tidx)) { - cost++ - } - } - return -} - -func (s *Screen) updateCostBlank(to Line) (cost int) { - var tidx int - for i := s.newbuf.Width() - 1; i > 0; i, tidx = i-1, tidx+1 { - if !cellEqual(nil, to.At(tidx)) { - cost++ - } - } - return -} diff --git a/vendor/github.com/charmbracelet/x/cellbuf/link.go b/vendor/github.com/charmbracelet/x/cellbuf/link.go deleted file mode 100644 index 112f8e8ab6..0000000000 --- a/vendor/github.com/charmbracelet/x/cellbuf/link.go +++ /dev/null @@ -1,14 +0,0 @@ -package cellbuf - -import ( - "github.com/charmbracelet/colorprofile" -) - -// Convert converts a hyperlink to respect the given color profile. -func ConvertLink(h Link, p colorprofile.Profile) Link { - if p == colorprofile.NoTTY { - return Link{} - } - - return h -} diff --git a/vendor/github.com/charmbracelet/x/cellbuf/screen.go b/vendor/github.com/charmbracelet/x/cellbuf/screen.go deleted file mode 100644 index 963b9cac36..0000000000 --- a/vendor/github.com/charmbracelet/x/cellbuf/screen.go +++ /dev/null @@ -1,1457 +0,0 @@ -package cellbuf - -import ( - "bytes" - "errors" - "io" - "os" - "strings" - "sync" - - "github.com/charmbracelet/colorprofile" - "github.com/charmbracelet/x/ansi" - "github.com/charmbracelet/x/term" -) - -// ErrInvalidDimensions is returned when the dimensions of a window are invalid -// for the operation. -var ErrInvalidDimensions = errors.New("invalid dimensions") - -// notLocal returns whether the coordinates are not considered local movement -// using the defined thresholds. -// This takes the number of columns, and the coordinates of the current and -// target positions. -func notLocal(cols, fx, fy, tx, ty int) bool { - // The typical distance for a [ansi.CUP] sequence. Anything less than this - // is considered local movement. - const longDist = 8 - 1 - return (tx > longDist) && - (tx < cols-1-longDist) && - (abs(ty-fy)+abs(tx-fx) > longDist) -} - -// relativeCursorMove returns the relative cursor movement sequence using one or two -// of the following sequences [ansi.CUU], [ansi.CUD], [ansi.CUF], [ansi.CUB], -// [ansi.VPA], [ansi.HPA]. -// When overwrite is true, this will try to optimize the sequence by using the -// screen cells values to move the cursor instead of using escape sequences. -func relativeCursorMove(s *Screen, fx, fy, tx, ty int, overwrite, useTabs, useBackspace bool) string { - var seq strings.Builder - - width, height := s.newbuf.Width(), s.newbuf.Height() - if ty != fy { - var yseq string - if s.xtermLike && !s.opts.RelativeCursor { - yseq = ansi.VerticalPositionAbsolute(ty + 1) - } - - // OPTIM: Use [ansi.LF] and [ansi.ReverseIndex] as optimizations. - - if ty > fy { - n := ty - fy - if cud := ansi.CursorDown(n); yseq == "" || len(cud) < len(yseq) { - yseq = cud - } - shouldScroll := !s.opts.AltScreen && fy+n >= s.scrollHeight - if lf := strings.Repeat("\n", n); shouldScroll || (fy+n < height && len(lf) < len(yseq)) { - // TODO: Ensure we're not unintentionally scrolling the screen down. - yseq = lf - s.scrollHeight = max(s.scrollHeight, fy+n) - } - } else if ty < fy { - n := fy - ty - if cuu := ansi.CursorUp(n); yseq == "" || len(cuu) < len(yseq) { - yseq = cuu - } - if n == 1 && fy-1 > 0 { - // TODO: Ensure we're not unintentionally scrolling the screen up. - yseq = ansi.ReverseIndex - } - } - - seq.WriteString(yseq) - } - - if tx != fx { - var xseq string - if s.xtermLike && !s.opts.RelativeCursor { - xseq = ansi.HorizontalPositionAbsolute(tx + 1) - } - - if tx > fx { - n := tx - fx - if useTabs { - var tabs int - var col int - for col = fx; s.tabs.Next(col) <= tx; col = s.tabs.Next(col) { - tabs++ - if col == s.tabs.Next(col) || col >= width-1 { - break - } - } - - if tabs > 0 { - cht := ansi.CursorHorizontalForwardTab(tabs) - tab := strings.Repeat("\t", tabs) - if false && s.xtermLike && len(cht) < len(tab) { - // TODO: The linux console and some terminals such as - // Alacritty don't support [ansi.CHT]. Enable this when - // we have a way to detect this, or after 5 years when - // we're sure everyone has updated their terminals :P - seq.WriteString(cht) - } else { - seq.WriteString(tab) - } - - n = tx - col - fx = col - } - } - - if cuf := ansi.CursorForward(n); xseq == "" || len(cuf) < len(xseq) { - xseq = cuf - } - - // If we have no attribute and style changes, overwrite is cheaper. - var ovw string - if overwrite && ty >= 0 { - for i := 0; i < n; i++ { - cell := s.newbuf.Cell(fx+i, ty) - if cell != nil && cell.Width > 0 { - i += cell.Width - 1 - if !cell.Style.Equal(&s.cur.Style) || !cell.Link.Equal(&s.cur.Link) { - overwrite = false - break - } - } - } - } - - if overwrite && ty >= 0 { - for i := 0; i < n; i++ { - cell := s.newbuf.Cell(fx+i, ty) - if cell != nil && cell.Width > 0 { - ovw += cell.String() - i += cell.Width - 1 - } else { - ovw += " " - } - } - } - - if overwrite && len(ovw) < len(xseq) { - xseq = ovw - } - } else if tx < fx { - n := fx - tx - if useTabs && s.xtermLike { - // VT100 does not support backward tabs [ansi.CBT]. - - col := fx - - var cbt int // cursor backward tabs count - for s.tabs.Prev(col) >= tx { - col = s.tabs.Prev(col) - cbt++ - if col == s.tabs.Prev(col) || col <= 0 { - break - } - } - - if cbt > 0 { - seq.WriteString(ansi.CursorBackwardTab(cbt)) - n = col - tx - } - } - - if cub := ansi.CursorBackward(n); xseq == "" || len(cub) < len(xseq) { - xseq = cub - } - - if useBackspace && n < len(xseq) { - xseq = strings.Repeat("\b", n) - } - } - - seq.WriteString(xseq) - } - - return seq.String() -} - -// moveCursor moves and returns the cursor movement sequence to move the cursor -// to the specified position. -// When overwrite is true, this will try to optimize the sequence by using the -// screen cells values to move the cursor instead of using escape sequences. -func moveCursor(s *Screen, x, y int, overwrite bool) (seq string) { - fx, fy := s.cur.X, s.cur.Y - - if !s.opts.RelativeCursor { - // Method #0: Use [ansi.CUP] if the distance is long. - seq = ansi.CursorPosition(x+1, y+1) - if fx == -1 || fy == -1 || notLocal(s.newbuf.Width(), fx, fy, x, y) { - return - } - } - - // Optimize based on options. - trials := 0 - if s.opts.HardTabs { - trials |= 2 // 0b10 in binary - } - if s.opts.Backspace { - trials |= 1 // 0b01 in binary - } - - // Try all possible combinations of hard tabs and backspace optimizations. - for i := 0; i <= trials; i++ { - // Skip combinations that are not enabled. - if i & ^trials != 0 { - continue - } - - useHardTabs := i&2 != 0 - useBackspace := i&1 != 0 - - // Method #1: Use local movement sequences. - nseq := relativeCursorMove(s, fx, fy, x, y, overwrite, useHardTabs, useBackspace) - if (i == 0 && len(seq) == 0) || len(nseq) < len(seq) { - seq = nseq - } - - // Method #2: Use [ansi.CR] and local movement sequences. - nseq = "\r" + relativeCursorMove(s, 0, fy, x, y, overwrite, useHardTabs, useBackspace) - if len(nseq) < len(seq) { - seq = nseq - } - - if !s.opts.RelativeCursor { - // Method #3: Use [ansi.CursorHomePosition] and local movement sequences. - nseq = ansi.CursorHomePosition + relativeCursorMove(s, 0, 0, x, y, overwrite, useHardTabs, useBackspace) - if len(nseq) < len(seq) { - seq = nseq - } - } - } - - return -} - -// moveCursor moves the cursor to the specified position. -func (s *Screen) moveCursor(x, y int, overwrite bool) { - if !s.opts.AltScreen && s.cur.X == -1 && s.cur.Y == -1 { - // First cursor movement in inline mode, move the cursor to the first - // column before moving to the target position. - s.buf.WriteByte('\r') //nolint:errcheck - s.cur.X, s.cur.Y = 0, 0 - } - s.buf.WriteString(moveCursor(s, x, y, overwrite)) //nolint:errcheck - s.cur.X, s.cur.Y = x, y -} - -func (s *Screen) move(x, y int) { - // XXX: Make sure we use the max height and width of the buffer in case - // we're in the middle of a resize operation. - width := max(s.newbuf.Width(), s.curbuf.Width()) - height := max(s.newbuf.Height(), s.curbuf.Height()) - - if width > 0 && x >= width { - // Handle autowrap - y += (x / width) - x %= width - } - - // XXX: Disable styles if there's any - // Some move operations such as [ansi.LF] can apply styles to the new - // cursor position, thus, we need to reset the styles before moving the - // cursor. - blank := s.clearBlank() - resetPen := y != s.cur.Y && !blank.Equal(&BlankCell) - if resetPen { - s.updatePen(nil) - } - - // Reset wrap around (phantom cursor) state - if s.atPhantom { - s.cur.X = 0 - s.buf.WriteByte('\r') //nolint:errcheck - s.atPhantom = false // reset phantom cell state - } - - // TODO: Investigate if we need to handle this case and/or if we need the - // following code. - // - // if width > 0 && s.cur.X >= width { - // l := (s.cur.X + 1) / width - // - // s.cur.Y += l - // if height > 0 && s.cur.Y >= height { - // l -= s.cur.Y - height - 1 - // } - // - // if l > 0 { - // s.cur.X = 0 - // s.buf.WriteString("\r" + strings.Repeat("\n", l)) //nolint:errcheck - // } - // } - - if height > 0 { - if s.cur.Y > height-1 { - s.cur.Y = height - 1 - } - if y > height-1 { - y = height - 1 - } - } - - if x == s.cur.X && y == s.cur.Y { - // We give up later because we need to run checks for the phantom cell - // and others before we can determine if we can give up. - return - } - - // We set the new cursor in [Screen.moveCursor]. - s.moveCursor(x, y, true) // Overwrite cells if possible -} - -// Cursor represents a terminal Cursor. -type Cursor struct { - Style - Link - Position -} - -// ScreenOptions are options for the screen. -type ScreenOptions struct { - // Term is the terminal type to use when writing to the screen. When empty, - // `$TERM` is used from [os.Getenv]. - Term string - // Profile is the color profile to use when writing to the screen. - Profile colorprofile.Profile - // RelativeCursor is whether to use relative cursor movements. This is - // useful when alt-screen is not used or when using inline mode. - RelativeCursor bool - // AltScreen is whether to use the alternate screen buffer. - AltScreen bool - // ShowCursor is whether to show the cursor. - ShowCursor bool - // HardTabs is whether to use hard tabs to optimize cursor movements. - HardTabs bool - // Backspace is whether to use backspace characters to move the cursor. - Backspace bool -} - -// lineData represents the metadata for a line. -type lineData struct { - // first and last changed cell indices - firstCell, lastCell int - // old index used for scrolling - oldIndex int //nolint:unused -} - -// Screen represents the terminal screen. -type Screen struct { - w io.Writer - buf *bytes.Buffer // buffer for writing to the screen - curbuf *Buffer // the current buffer - newbuf *Buffer // the new buffer - tabs *TabStops - touch map[int]lineData - queueAbove []string // the queue of strings to write above the screen - oldhash, newhash []uint64 // the old and new hash values for each line - hashtab []hashmap // the hashmap table - oldnum []int // old indices from previous hash - cur, saved Cursor // the current and saved cursors - opts ScreenOptions - mu sync.Mutex - method ansi.Method - scrollHeight int // keeps track of how many lines we've scrolled down (inline mode) - altScreenMode bool // whether alternate screen mode is enabled - cursorHidden bool // whether text cursor mode is enabled - clear bool // whether to force clear the screen - xtermLike bool // whether to use xterm-like optimizations, otherwise, it uses vt100 only - queuedText bool // whether we have queued non-zero width text queued up - atPhantom bool // whether the cursor is out of bounds and at a phantom cell -} - -// SetMethod sets the method used to calculate the width of cells. -func (s *Screen) SetMethod(method ansi.Method) { - s.method = method -} - -// UseBackspaces sets whether to use backspace characters to move the cursor. -func (s *Screen) UseBackspaces(v bool) { - s.opts.Backspace = v -} - -// UseHardTabs sets whether to use hard tabs to optimize cursor movements. -func (s *Screen) UseHardTabs(v bool) { - s.opts.HardTabs = v -} - -// SetColorProfile sets the color profile to use when writing to the screen. -func (s *Screen) SetColorProfile(p colorprofile.Profile) { - s.opts.Profile = p -} - -// SetRelativeCursor sets whether to use relative cursor movements. -func (s *Screen) SetRelativeCursor(v bool) { - s.opts.RelativeCursor = v -} - -// EnterAltScreen enters the alternate screen buffer. -func (s *Screen) EnterAltScreen() { - s.opts.AltScreen = true - s.clear = true - s.saved = s.cur -} - -// ExitAltScreen exits the alternate screen buffer. -func (s *Screen) ExitAltScreen() { - s.opts.AltScreen = false - s.clear = true - s.cur = s.saved -} - -// ShowCursor shows the cursor. -func (s *Screen) ShowCursor() { - s.opts.ShowCursor = true -} - -// HideCursor hides the cursor. -func (s *Screen) HideCursor() { - s.opts.ShowCursor = false -} - -// Bounds implements Window. -func (s *Screen) Bounds() Rectangle { - // Always return the new buffer bounds. - return s.newbuf.Bounds() -} - -// Cell implements Window. -func (s *Screen) Cell(x int, y int) *Cell { - return s.newbuf.Cell(x, y) -} - -// Redraw forces a full redraw of the screen. -func (s *Screen) Redraw() { - s.mu.Lock() - s.clear = true - s.mu.Unlock() -} - -// Clear clears the screen with blank cells. This is a convenience method for -// [Screen.Fill] with a nil cell. -func (s *Screen) Clear() bool { - return s.ClearRect(s.newbuf.Bounds()) -} - -// ClearRect clears the given rectangle with blank cells. This is a convenience -// method for [Screen.FillRect] with a nil cell. -func (s *Screen) ClearRect(r Rectangle) bool { - return s.FillRect(nil, r) -} - -// SetCell implements Window. -func (s *Screen) SetCell(x int, y int, cell *Cell) (v bool) { - s.mu.Lock() - defer s.mu.Unlock() - cellWidth := 1 - if cell != nil { - cellWidth = cell.Width - } - if prev := s.curbuf.Cell(x, y); !cellEqual(prev, cell) { - chg, ok := s.touch[y] - if !ok { - chg = lineData{firstCell: x, lastCell: x + cellWidth} - } else { - chg.firstCell = min(chg.firstCell, x) - chg.lastCell = max(chg.lastCell, x+cellWidth) - } - s.touch[y] = chg - } - - return s.newbuf.SetCell(x, y, cell) -} - -// Fill implements Window. -func (s *Screen) Fill(cell *Cell) bool { - return s.FillRect(cell, s.newbuf.Bounds()) -} - -// FillRect implements Window. -func (s *Screen) FillRect(cell *Cell, r Rectangle) bool { - s.mu.Lock() - defer s.mu.Unlock() - s.newbuf.FillRect(cell, r) - for i := r.Min.Y; i < r.Max.Y; i++ { - s.touch[i] = lineData{firstCell: r.Min.X, lastCell: r.Max.X} - } - return true -} - -// isXtermLike returns whether the terminal is xterm-like. This means that the -// terminal supports ECMA-48 and ANSI X3.64 escape sequences. -// TODO: Should this be a lookup table into each $TERM terminfo database? Like -// we could keep a map of ANSI escape sequence to terminfo capability name and -// check if the database supports the escape sequence. Instead of keeping a -// list of terminal names here. -func isXtermLike(termtype string) (v bool) { - parts := strings.Split(termtype, "-") - if len(parts) == 0 { - return - } - - switch parts[0] { - case - "alacritty", - "contour", - "foot", - "ghostty", - "kitty", - "linux", - "rio", - "screen", - "st", - "tmux", - "wezterm", - "xterm": - v = true - } - - return -} - -// NewScreen creates a new Screen. -func NewScreen(w io.Writer, width, height int, opts *ScreenOptions) (s *Screen) { - s = new(Screen) - s.w = w - if opts != nil { - s.opts = *opts - } - - if s.opts.Term == "" { - s.opts.Term = os.Getenv("TERM") - } - - if width <= 0 || height <= 0 { - if f, ok := w.(term.File); ok { - width, height, _ = term.GetSize(f.Fd()) - } - } - if width < 0 { - width = 0 - } - if height < 0 { - height = 0 - } - - s.buf = new(bytes.Buffer) - s.xtermLike = isXtermLike(s.opts.Term) - s.curbuf = NewBuffer(width, height) - s.newbuf = NewBuffer(width, height) - s.cur = Cursor{Position: Pos(-1, -1)} // start at -1 to force a move - s.saved = s.cur - s.reset() - - return -} - -// Width returns the width of the screen. -func (s *Screen) Width() int { - return s.newbuf.Width() -} - -// Height returns the height of the screen. -func (s *Screen) Height() int { - return s.newbuf.Height() -} - -// cellEqual returns whether the two cells are equal. A nil cell is considered -// a [BlankCell]. -func cellEqual(a, b *Cell) bool { - if a == b { - return true - } - if a == nil { - a = &BlankCell - } - if b == nil { - b = &BlankCell - } - return a.Equal(b) -} - -// putCell draws a cell at the current cursor position. -func (s *Screen) putCell(cell *Cell) { - width, height := s.newbuf.Width(), s.newbuf.Height() - if s.opts.AltScreen && s.cur.X == width-1 && s.cur.Y == height-1 { - s.putCellLR(cell) - } else { - s.putAttrCell(cell) - } -} - -// wrapCursor wraps the cursor to the next line. -// -//nolint:unused -func (s *Screen) wrapCursor() { - const autoRightMargin = true - if autoRightMargin { - // Assume we have auto wrap mode enabled. - s.cur.X = 0 - s.cur.Y++ - } else { - s.cur.X-- - } -} - -func (s *Screen) putAttrCell(cell *Cell) { - if cell != nil && cell.Empty() { - // XXX: Zero width cells are special and should not be written to the - // screen no matter what other attributes they have. - // Zero width cells are used for wide characters that are split into - // multiple cells. - return - } - - if cell == nil { - cell = s.clearBlank() - } - - // We're at pending wrap state (phantom cell), incoming cell should - // wrap. - if s.atPhantom { - s.wrapCursor() - s.atPhantom = false - } - - s.updatePen(cell) - s.buf.WriteRune(cell.Rune) //nolint:errcheck - for _, c := range cell.Comb { - s.buf.WriteRune(c) //nolint:errcheck - } - - s.cur.X += cell.Width - - if cell.Width > 0 { - s.queuedText = true - } - - if s.cur.X >= s.newbuf.Width() { - s.atPhantom = true - } -} - -// putCellLR draws a cell at the lower right corner of the screen. -func (s *Screen) putCellLR(cell *Cell) { - // Optimize for the lower right corner cell. - curX := s.cur.X - if cell == nil || !cell.Empty() { - s.buf.WriteString(ansi.ResetAutoWrapMode) //nolint:errcheck - s.putAttrCell(cell) - // Writing to lower-right corner cell should not wrap. - s.atPhantom = false - s.cur.X = curX - s.buf.WriteString(ansi.SetAutoWrapMode) //nolint:errcheck - } -} - -// updatePen updates the cursor pen styles. -func (s *Screen) updatePen(cell *Cell) { - if cell == nil { - cell = &BlankCell - } - - if s.opts.Profile != 0 { - // Downsample colors to the given color profile. - cell.Style = ConvertStyle(cell.Style, s.opts.Profile) - cell.Link = ConvertLink(cell.Link, s.opts.Profile) - } - - if !cell.Style.Equal(&s.cur.Style) { - seq := cell.Style.DiffSequence(s.cur.Style) - if cell.Style.Empty() && len(seq) > len(ansi.ResetStyle) { - seq = ansi.ResetStyle - } - s.buf.WriteString(seq) //nolint:errcheck - s.cur.Style = cell.Style - } - if !cell.Link.Equal(&s.cur.Link) { - s.buf.WriteString(ansi.SetHyperlink(cell.Link.URL, cell.Link.Params)) //nolint:errcheck - s.cur.Link = cell.Link - } -} - -// emitRange emits a range of cells to the buffer. It it equivalent to calling -// [Screen.putCell] for each cell in the range. This is optimized to use -// [ansi.ECH] and [ansi.REP]. -// Returns whether the cursor is at the end of interval or somewhere in the -// middle. -func (s *Screen) emitRange(line Line, n int) (eoi bool) { - for n > 0 { - var count int - for n > 1 && !cellEqual(line.At(0), line.At(1)) { - s.putCell(line.At(0)) - line = line[1:] - n-- - } - - cell0 := line[0] - if n == 1 { - s.putCell(cell0) - return false - } - - count = 2 - for count < n && cellEqual(line.At(count), cell0) { - count++ - } - - ech := ansi.EraseCharacter(count) - cup := ansi.CursorPosition(s.cur.X+count, s.cur.Y) - rep := ansi.RepeatPreviousCharacter(count) - if s.xtermLike && count > len(ech)+len(cup) && cell0 != nil && cell0.Clear() { - s.updatePen(cell0) - s.buf.WriteString(ech) //nolint:errcheck - - // If this is the last cell, we don't need to move the cursor. - if count < n { - s.move(s.cur.X+count, s.cur.Y) - } else { - return true // cursor in the middle - } - } else if s.xtermLike && count > len(rep) && - (cell0 == nil || (len(cell0.Comb) == 0 && cell0.Rune < 256)) { - // We only support ASCII characters. Most terminals will handle - // non-ASCII characters correctly, but some might not, ahem xterm. - // - // NOTE: [ansi.REP] only repeats the last rune and won't work - // if the last cell contains multiple runes. - - wrapPossible := s.cur.X+count >= s.newbuf.Width() - repCount := count - if wrapPossible { - repCount-- - } - - s.updatePen(cell0) - s.putCell(cell0) - repCount-- // cell0 is a single width cell ASCII character - - s.buf.WriteString(ansi.RepeatPreviousCharacter(repCount)) //nolint:errcheck - s.cur.X += repCount - if wrapPossible { - s.putCell(cell0) - } - } else { - for i := 0; i < count; i++ { - s.putCell(line.At(i)) - } - } - - line = line[clamp(count, 0, len(line)):] - n -= count - } - - return -} - -// putRange puts a range of cells from the old line to the new line. -// Returns whether the cursor is at the end of interval or somewhere in the -// middle. -func (s *Screen) putRange(oldLine, newLine Line, y, start, end int) (eoi bool) { - inline := min(len(ansi.CursorPosition(start+1, y+1)), - min(len(ansi.HorizontalPositionAbsolute(start+1)), - len(ansi.CursorForward(start+1)))) - if (end - start + 1) > inline { - var j, same int - for j, same = start, 0; j <= end; j++ { - oldCell, newCell := oldLine.At(j), newLine.At(j) - if same == 0 && oldCell != nil && oldCell.Empty() { - continue - } - if cellEqual(oldCell, newCell) { - same++ - } else { - if same > end-start { - s.emitRange(newLine[start:], j-same-start) - s.move(j, y) - start = j - } - same = 0 - } - } - - i := s.emitRange(newLine[start:], j-same-start) - - // Always return 1 for the next [Screen.move] after a [Screen.putRange] if - // we found identical characters at end of interval. - if same == 0 { - return i - } - return true - } - - return s.emitRange(newLine[start:], end-start+1) -} - -// clearToEnd clears the screen from the current cursor position to the end of -// line. -func (s *Screen) clearToEnd(blank *Cell, force bool) { //nolint:unparam - if s.cur.Y >= 0 { - curline := s.curbuf.Line(s.cur.Y) - for j := s.cur.X; j < s.curbuf.Width(); j++ { - if j >= 0 { - c := curline.At(j) - if !cellEqual(c, blank) { - curline.Set(j, blank) - force = true - } - } - } - } - - if force { - s.updatePen(blank) - count := s.newbuf.Width() - s.cur.X - if s.el0Cost() <= count { - s.buf.WriteString(ansi.EraseLineRight) //nolint:errcheck - } else { - for i := 0; i < count; i++ { - s.putCell(blank) - } - } - } -} - -// clearBlank returns a blank cell based on the current cursor background color. -func (s *Screen) clearBlank() *Cell { - c := BlankCell - if !s.cur.Style.Empty() || !s.cur.Link.Empty() { - c.Style = s.cur.Style - c.Link = s.cur.Link - } - return &c -} - -// insertCells inserts the count cells pointed by the given line at the current -// cursor position. -func (s *Screen) insertCells(line Line, count int) { - if s.xtermLike { - // Use [ansi.ICH] as an optimization. - s.buf.WriteString(ansi.InsertCharacter(count)) //nolint:errcheck - } else { - // Otherwise, use [ansi.IRM] mode. - s.buf.WriteString(ansi.SetInsertReplaceMode) //nolint:errcheck - } - - for i := 0; count > 0; i++ { - s.putAttrCell(line[i]) - count-- - } - - if !s.xtermLike { - s.buf.WriteString(ansi.ResetInsertReplaceMode) //nolint:errcheck - } -} - -// el0Cost returns the cost of using [ansi.EL] 0 i.e. [ansi.EraseLineRight]. If -// this terminal supports background color erase, it can be cheaper to use -// [ansi.EL] 0 i.e. [ansi.EraseLineRight] to clear -// trailing spaces. -func (s *Screen) el0Cost() int { - if s.xtermLike { - return 0 - } - return len(ansi.EraseLineRight) -} - -// transformLine transforms the given line in the current window to the -// corresponding line in the new window. It uses [ansi.ICH] and [ansi.DCH] to -// insert or delete characters. -func (s *Screen) transformLine(y int) { - var firstCell, oLastCell, nLastCell int // first, old last, new last index - oldLine := s.curbuf.Line(y) - newLine := s.newbuf.Line(y) - - // Find the first changed cell in the line - var lineChanged bool - for i := 0; i < s.newbuf.Width(); i++ { - if !cellEqual(newLine.At(i), oldLine.At(i)) { - lineChanged = true - break - } - } - - const ceolStandoutGlitch = false - if ceolStandoutGlitch && lineChanged { - s.move(0, y) - s.clearToEnd(nil, false) - s.putRange(oldLine, newLine, y, 0, s.newbuf.Width()-1) - } else { - blank := newLine.At(0) - - // It might be cheaper to clear leading spaces with [ansi.EL] 1 i.e. - // [ansi.EraseLineLeft]. - if blank == nil || blank.Clear() { - var oFirstCell, nFirstCell int - for oFirstCell = 0; oFirstCell < s.curbuf.Width(); oFirstCell++ { - if !cellEqual(oldLine.At(oFirstCell), blank) { - break - } - } - for nFirstCell = 0; nFirstCell < s.newbuf.Width(); nFirstCell++ { - if !cellEqual(newLine.At(nFirstCell), blank) { - break - } - } - - if nFirstCell == oFirstCell { - firstCell = nFirstCell - - // Find the first differing cell - for firstCell < s.newbuf.Width() && - cellEqual(oldLine.At(firstCell), newLine.At(firstCell)) { - firstCell++ - } - } else if oFirstCell > nFirstCell { - firstCell = nFirstCell - } else if oFirstCell < nFirstCell { - firstCell = oFirstCell - el1Cost := len(ansi.EraseLineLeft) - if el1Cost < nFirstCell-oFirstCell { - if nFirstCell >= s.newbuf.Width() { - s.move(0, y) - s.updatePen(blank) - s.buf.WriteString(ansi.EraseLineRight) //nolint:errcheck - } else { - s.move(nFirstCell-1, y) - s.updatePen(blank) - s.buf.WriteString(ansi.EraseLineLeft) //nolint:errcheck - } - - for firstCell < nFirstCell { - oldLine.Set(firstCell, blank) - firstCell++ - } - } - } - } else { - // Find the first differing cell - for firstCell < s.newbuf.Width() && cellEqual(newLine.At(firstCell), oldLine.At(firstCell)) { - firstCell++ - } - } - - // If we didn't find one, we're done - if firstCell >= s.newbuf.Width() { - return - } - - blank = newLine.At(s.newbuf.Width() - 1) - if blank != nil && !blank.Clear() { - // Find the last differing cell - nLastCell = s.newbuf.Width() - 1 - for nLastCell > firstCell && cellEqual(newLine.At(nLastCell), oldLine.At(nLastCell)) { - nLastCell-- - } - - if nLastCell >= firstCell { - s.move(firstCell, y) - s.putRange(oldLine, newLine, y, firstCell, nLastCell) - if firstCell < len(oldLine) && firstCell < len(newLine) { - copy(oldLine[firstCell:], newLine[firstCell:]) - } else { - copy(oldLine, newLine) - } - } - - return - } - - // Find last non-blank cell in the old line. - oLastCell = s.curbuf.Width() - 1 - for oLastCell > firstCell && cellEqual(oldLine.At(oLastCell), blank) { - oLastCell-- - } - - // Find last non-blank cell in the new line. - nLastCell = s.newbuf.Width() - 1 - for nLastCell > firstCell && cellEqual(newLine.At(nLastCell), blank) { - nLastCell-- - } - - if nLastCell == firstCell && s.el0Cost() < oLastCell-nLastCell { - s.move(firstCell, y) - if !cellEqual(newLine.At(firstCell), blank) { - s.putCell(newLine.At(firstCell)) - } - s.clearToEnd(blank, false) - } else if nLastCell != oLastCell && - !cellEqual(newLine.At(nLastCell), oldLine.At(oLastCell)) { - s.move(firstCell, y) - if oLastCell-nLastCell > s.el0Cost() { - if s.putRange(oldLine, newLine, y, firstCell, nLastCell) { - s.move(nLastCell+1, y) - } - s.clearToEnd(blank, false) - } else { - n := max(nLastCell, oLastCell) - s.putRange(oldLine, newLine, y, firstCell, n) - } - } else { - nLastNonBlank := nLastCell - oLastNonBlank := oLastCell - - // Find the last cells that really differ. - // Can be -1 if no cells differ. - for cellEqual(newLine.At(nLastCell), oldLine.At(oLastCell)) { - if !cellEqual(newLine.At(nLastCell-1), oldLine.At(oLastCell-1)) { - break - } - nLastCell-- - oLastCell-- - if nLastCell == -1 || oLastCell == -1 { - break - } - } - - n := min(oLastCell, nLastCell) - if n >= firstCell { - s.move(firstCell, y) - s.putRange(oldLine, newLine, y, firstCell, n) - } - - if oLastCell < nLastCell { - m := max(nLastNonBlank, oLastNonBlank) - if n != 0 { - for n > 0 { - wide := newLine.At(n + 1) - if wide == nil || !wide.Empty() { - break - } - n-- - oLastCell-- - } - } else if n >= firstCell && newLine.At(n) != nil && newLine.At(n).Width > 1 { - next := newLine.At(n + 1) - for next != nil && next.Empty() { - n++ - oLastCell++ - } - } - - s.move(n+1, y) - ichCost := 3 + nLastCell - oLastCell - if s.xtermLike && (nLastCell < nLastNonBlank || ichCost > (m-n)) { - s.putRange(oldLine, newLine, y, n+1, m) - } else { - s.insertCells(newLine[n+1:], nLastCell-oLastCell) - } - } else if oLastCell > nLastCell { - s.move(n+1, y) - dchCost := 3 + oLastCell - nLastCell - if dchCost > len(ansi.EraseLineRight)+nLastNonBlank-(n+1) { - if s.putRange(oldLine, newLine, y, n+1, nLastNonBlank) { - s.move(nLastNonBlank+1, y) - } - s.clearToEnd(blank, false) - } else { - s.updatePen(blank) - s.deleteCells(oLastCell - nLastCell) - } - } - } - } - - // Update the old line with the new line - if firstCell < len(oldLine) && firstCell < len(newLine) { - copy(oldLine[firstCell:], newLine[firstCell:]) - } else { - copy(oldLine, newLine) - } -} - -// deleteCells deletes the count cells at the current cursor position and moves -// the rest of the line to the left. This is equivalent to [ansi.DCH]. -func (s *Screen) deleteCells(count int) { - // [ansi.DCH] will shift in cells from the right margin so we need to - // ensure that they are the right style. - s.buf.WriteString(ansi.DeleteCharacter(count)) //nolint:errcheck -} - -// clearToBottom clears the screen from the current cursor position to the end -// of the screen. -func (s *Screen) clearToBottom(blank *Cell) { - row, col := s.cur.Y, s.cur.X - if row < 0 { - row = 0 - } - - s.updatePen(blank) - s.buf.WriteString(ansi.EraseScreenBelow) //nolint:errcheck - // Clear the rest of the current line - s.curbuf.ClearRect(Rect(col, row, s.curbuf.Width()-col, 1)) - // Clear everything below the current line - s.curbuf.ClearRect(Rect(0, row+1, s.curbuf.Width(), s.curbuf.Height()-row-1)) -} - -// clearBottom tests if clearing the end of the screen would satisfy part of -// the screen update. Scan backwards through lines in the screen checking if -// each is blank and one or more are changed. -// It returns the top line. -func (s *Screen) clearBottom(total int) (top int) { - if total <= 0 { - return - } - - top = total - last := s.newbuf.Width() - blank := s.clearBlank() - canClearWithBlank := blank == nil || blank.Clear() - - if canClearWithBlank { - var row int - for row = total - 1; row >= 0; row-- { - oldLine := s.curbuf.Line(row) - newLine := s.newbuf.Line(row) - - var col int - ok := true - for col = 0; ok && col < last; col++ { - ok = cellEqual(newLine.At(col), blank) - } - if !ok { - break - } - - for col = 0; ok && col < last; col++ { - ok = len(oldLine) == last && cellEqual(oldLine.At(col), blank) - } - if !ok { - top = row - } - } - - if top < total { - s.move(0, top-1) // top is 1-based - s.clearToBottom(blank) - if s.oldhash != nil && s.newhash != nil && - row < len(s.oldhash) && row < len(s.newhash) { - for row := top; row < s.newbuf.Height(); row++ { - s.oldhash[row] = s.newhash[row] - } - } - } - } - - return -} - -// clearScreen clears the screen and put cursor at home. -func (s *Screen) clearScreen(blank *Cell) { - s.updatePen(blank) - s.buf.WriteString(ansi.CursorHomePosition) //nolint:errcheck - s.buf.WriteString(ansi.EraseEntireScreen) //nolint:errcheck - s.cur.X, s.cur.Y = 0, 0 - s.curbuf.Fill(blank) -} - -// clearBelow clears everything below and including the row. -func (s *Screen) clearBelow(blank *Cell, row int) { - s.move(0, row) - s.clearToBottom(blank) -} - -// clearUpdate forces a screen redraw. -func (s *Screen) clearUpdate() { - blank := s.clearBlank() - var nonEmpty int - if s.opts.AltScreen { - // XXX: We're using the maximum height of the two buffers to ensure - // we write newly added lines to the screen in [Screen.transformLine]. - nonEmpty = max(s.curbuf.Height(), s.newbuf.Height()) - s.clearScreen(blank) - } else { - nonEmpty = s.newbuf.Height() - s.clearBelow(blank, 0) - } - nonEmpty = s.clearBottom(nonEmpty) - for i := 0; i < nonEmpty; i++ { - s.transformLine(i) - } -} - -// Flush flushes the buffer to the screen. -func (s *Screen) Flush() (err error) { - s.mu.Lock() - defer s.mu.Unlock() - return s.flush() -} - -func (s *Screen) flush() (err error) { - // Write the buffer - if s.buf.Len() > 0 { - _, err = s.w.Write(s.buf.Bytes()) //nolint:errcheck - if err == nil { - s.buf.Reset() - } - } - - return -} - -// Render renders changes of the screen to the internal buffer. Call -// [Screen.Flush] to flush pending changes to the screen. -func (s *Screen) Render() { - s.mu.Lock() - s.render() - s.mu.Unlock() -} - -func (s *Screen) render() { - // Do we need to render anything? - if s.opts.AltScreen == s.altScreenMode && - !s.opts.ShowCursor == s.cursorHidden && - !s.clear && - len(s.touch) == 0 && - len(s.queueAbove) == 0 { - return - } - - // TODO: Investigate whether this is necessary. Theoretically, terminals - // can add/remove tab stops and we should be able to handle that. We could - // use [ansi.DECTABSR] to read the tab stops, but that's not implemented in - // most terminals :/ - // // Are we using hard tabs? If so, ensure tabs are using the - // // default interval using [ansi.DECST8C]. - // if s.opts.HardTabs && !s.initTabs { - // s.buf.WriteString(ansi.SetTabEvery8Columns) - // s.initTabs = true - // } - - // Do we need alt-screen mode? - if s.opts.AltScreen != s.altScreenMode { - if s.opts.AltScreen { - s.buf.WriteString(ansi.SetAltScreenSaveCursorMode) - } else { - s.buf.WriteString(ansi.ResetAltScreenSaveCursorMode) - } - s.altScreenMode = s.opts.AltScreen - } - - // Do we need text cursor mode? - if !s.opts.ShowCursor != s.cursorHidden { - s.cursorHidden = !s.opts.ShowCursor - if s.cursorHidden { - s.buf.WriteString(ansi.HideCursor) - } - } - - // Do we have queued strings to write above the screen? - if len(s.queueAbove) > 0 { - // TODO: Use scrolling region if available. - // TODO: Use [Screen.Write] [io.Writer] interface. - - // We need to scroll the screen up by the number of lines in the queue. - // We can't use [ansi.SU] because we want the cursor to move down until - // it reaches the bottom of the screen. - s.move(0, s.newbuf.Height()-1) - s.buf.WriteString(strings.Repeat("\n", len(s.queueAbove))) - s.cur.Y += len(s.queueAbove) - // XXX: Now go to the top of the screen, insert new lines, and write - // the queued strings. It is important to use [Screen.moveCursor] - // instead of [Screen.move] because we don't want to perform any checks - // on the cursor position. - s.moveCursor(0, 0, false) - s.buf.WriteString(ansi.InsertLine(len(s.queueAbove))) - for _, line := range s.queueAbove { - s.buf.WriteString(line + "\r\n") - } - - // Clear the queue - s.queueAbove = s.queueAbove[:0] - } - - var nonEmpty int - - // XXX: In inline mode, after a screen resize, we need to clear the extra - // lines at the bottom of the screen. This is because in inline mode, we - // don't use the full screen height and the current buffer size might be - // larger than the new buffer size. - partialClear := !s.opts.AltScreen && s.cur.X != -1 && s.cur.Y != -1 && - s.curbuf.Width() == s.newbuf.Width() && - s.curbuf.Height() > 0 && - s.curbuf.Height() > s.newbuf.Height() - - if !s.clear && partialClear { - s.clearBelow(nil, s.newbuf.Height()-1) - } - - if s.clear { - s.clearUpdate() - s.clear = false - } else if len(s.touch) > 0 { - if s.opts.AltScreen { - // Optimize scrolling for the alternate screen buffer. - // TODO: Should we optimize for inline mode as well? If so, we need - // to know the actual cursor position to use [ansi.DECSTBM]. - s.scrollOptimize() - } - - var changedLines int - var i int - - if s.opts.AltScreen { - nonEmpty = min(s.curbuf.Height(), s.newbuf.Height()) - } else { - nonEmpty = s.newbuf.Height() - } - - nonEmpty = s.clearBottom(nonEmpty) - for i = 0; i < nonEmpty; i++ { - _, ok := s.touch[i] - if ok { - s.transformLine(i) - changedLines++ - } - } - } - - // Sync windows and screen - s.touch = make(map[int]lineData, s.newbuf.Height()) - - if s.curbuf.Width() != s.newbuf.Width() || s.curbuf.Height() != s.newbuf.Height() { - // Resize the old buffer to match the new buffer. - _, oldh := s.curbuf.Width(), s.curbuf.Height() - s.curbuf.Resize(s.newbuf.Width(), s.newbuf.Height()) - // Sync new lines to old lines - for i := oldh - 1; i < s.newbuf.Height(); i++ { - copy(s.curbuf.Line(i), s.newbuf.Line(i)) - } - } - - s.updatePen(nil) // nil indicates a blank cell with no styles - - // Do we have enough changes to justify toggling the cursor? - if s.buf.Len() > 1 && s.opts.ShowCursor && !s.cursorHidden && s.queuedText { - nb := new(bytes.Buffer) - nb.Grow(s.buf.Len() + len(ansi.HideCursor) + len(ansi.ShowCursor)) - nb.WriteString(ansi.HideCursor) - nb.Write(s.buf.Bytes()) - nb.WriteString(ansi.ShowCursor) - *s.buf = *nb - } - - s.queuedText = false -} - -// Close writes the final screen update and resets the screen. -func (s *Screen) Close() (err error) { - s.mu.Lock() - defer s.mu.Unlock() - - s.render() - s.updatePen(nil) - // Go to the bottom of the screen - s.move(0, s.newbuf.Height()-1) - - if s.altScreenMode { - s.buf.WriteString(ansi.ResetAltScreenSaveCursorMode) - s.altScreenMode = false - } - - if s.cursorHidden { - s.buf.WriteString(ansi.ShowCursor) - s.cursorHidden = false - } - - // Write the buffer - err = s.flush() - if err != nil { - return - } - - s.reset() - return -} - -// reset resets the screen to its initial state. -func (s *Screen) reset() { - s.scrollHeight = 0 - s.cursorHidden = false - s.altScreenMode = false - s.touch = make(map[int]lineData, s.newbuf.Height()) - if s.curbuf != nil { - s.curbuf.Clear() - } - if s.newbuf != nil { - s.newbuf.Clear() - } - s.buf.Reset() - s.tabs = DefaultTabStops(s.newbuf.Width()) - s.oldhash, s.newhash = nil, nil - - // We always disable HardTabs when termtype is "linux". - if strings.HasPrefix(s.opts.Term, "linux") { - s.opts.HardTabs = false - } -} - -// Resize resizes the screen. -func (s *Screen) Resize(width, height int) bool { - oldw := s.newbuf.Width() - oldh := s.newbuf.Height() - - if s.opts.AltScreen || width != oldw { - // We only clear the whole screen if the width changes. Adding/removing - // rows is handled by the [Screen.render] and [Screen.transformLine] - // methods. - s.clear = true - } - - // Clear new columns and lines - if width > oldh { - s.ClearRect(Rect(max(oldw-1, 0), 0, width-oldw, height)) - } else if width < oldw { - s.ClearRect(Rect(max(width-1, 0), 0, oldw-width, height)) - } - - if height > oldh { - s.ClearRect(Rect(0, max(oldh-1, 0), width, height-oldh)) - } else if height < oldh { - s.ClearRect(Rect(0, max(height-1, 0), width, oldh-height)) - } - - s.mu.Lock() - s.newbuf.Resize(width, height) - s.tabs.Resize(width) - s.oldhash, s.newhash = nil, nil - s.scrollHeight = 0 // reset scroll lines - s.mu.Unlock() - - return true -} - -// MoveTo moves the cursor to the given position. -func (s *Screen) MoveTo(x, y int) { - s.mu.Lock() - s.move(x, y) - s.mu.Unlock() -} - -// InsertAbove inserts string above the screen. The inserted string is not -// managed by the screen. This does nothing when alternate screen mode is -// enabled. -func (s *Screen) InsertAbove(str string) { - if s.opts.AltScreen { - return - } - s.mu.Lock() - for _, line := range strings.Split(str, "\n") { - s.queueAbove = append(s.queueAbove, s.method.Truncate(line, s.Width(), "")) - } - s.mu.Unlock() -} diff --git a/vendor/github.com/charmbracelet/x/cellbuf/sequence.go b/vendor/github.com/charmbracelet/x/cellbuf/sequence.go deleted file mode 100644 index 613eefef8b..0000000000 --- a/vendor/github.com/charmbracelet/x/cellbuf/sequence.go +++ /dev/null @@ -1,131 +0,0 @@ -package cellbuf - -import ( - "bytes" - "image/color" - - "github.com/charmbracelet/x/ansi" -) - -// ReadStyle reads a Select Graphic Rendition (SGR) escape sequences from a -// list of parameters. -func ReadStyle(params ansi.Params, pen *Style) { - if len(params) == 0 { - pen.Reset() - return - } - - for i := 0; i < len(params); i++ { - param, hasMore, _ := params.Param(i, 0) - switch param { - case 0: // Reset - pen.Reset() - case 1: // Bold - pen.Bold(true) - case 2: // Dim/Faint - pen.Faint(true) - case 3: // Italic - pen.Italic(true) - case 4: // Underline - nextParam, _, ok := params.Param(i+1, 0) - if hasMore && ok { // Only accept subparameters i.e. separated by ":" - switch nextParam { - case 0, 1, 2, 3, 4, 5: - i++ - switch nextParam { - case 0: // No Underline - pen.UnderlineStyle(NoUnderline) - case 1: // Single Underline - pen.UnderlineStyle(SingleUnderline) - case 2: // Double Underline - pen.UnderlineStyle(DoubleUnderline) - case 3: // Curly Underline - pen.UnderlineStyle(CurlyUnderline) - case 4: // Dotted Underline - pen.UnderlineStyle(DottedUnderline) - case 5: // Dashed Underline - pen.UnderlineStyle(DashedUnderline) - } - } - } else { - // Single Underline - pen.Underline(true) - } - case 5: // Slow Blink - pen.SlowBlink(true) - case 6: // Rapid Blink - pen.RapidBlink(true) - case 7: // Reverse - pen.Reverse(true) - case 8: // Conceal - pen.Conceal(true) - case 9: // Crossed-out/Strikethrough - pen.Strikethrough(true) - case 22: // Normal Intensity (not bold or faint) - pen.Bold(false).Faint(false) - case 23: // Not italic, not Fraktur - pen.Italic(false) - case 24: // Not underlined - pen.Underline(false) - case 25: // Blink off - pen.SlowBlink(false).RapidBlink(false) - case 27: // Positive (not reverse) - pen.Reverse(false) - case 28: // Reveal - pen.Conceal(false) - case 29: // Not crossed out - pen.Strikethrough(false) - case 30, 31, 32, 33, 34, 35, 36, 37: // Set foreground - pen.Foreground(ansi.Black + ansi.BasicColor(param-30)) //nolint:gosec - case 38: // Set foreground 256 or truecolor - var c color.Color - n := ReadStyleColor(params[i:], &c) - if n > 0 { - pen.Foreground(c) - i += n - 1 - } - case 39: // Default foreground - pen.Foreground(nil) - case 40, 41, 42, 43, 44, 45, 46, 47: // Set background - pen.Background(ansi.Black + ansi.BasicColor(param-40)) //nolint:gosec - case 48: // Set background 256 or truecolor - var c color.Color - n := ReadStyleColor(params[i:], &c) - if n > 0 { - pen.Background(c) - i += n - 1 - } - case 49: // Default Background - pen.Background(nil) - case 58: // Set underline color - var c color.Color - n := ReadStyleColor(params[i:], &c) - if n > 0 { - pen.UnderlineColor(c) - i += n - 1 - } - case 59: // Default underline color - pen.UnderlineColor(nil) - case 90, 91, 92, 93, 94, 95, 96, 97: // Set bright foreground - pen.Foreground(ansi.BrightBlack + ansi.BasicColor(param-90)) //nolint:gosec - case 100, 101, 102, 103, 104, 105, 106, 107: // Set bright background - pen.Background(ansi.BrightBlack + ansi.BasicColor(param-100)) //nolint:gosec - } - } -} - -// ReadLink reads a hyperlink escape sequence from a data buffer. -func ReadLink(p []byte, link *Link) { - params := bytes.Split(p, []byte{';'}) - if len(params) != 3 { - return - } - link.Params = string(params[1]) - link.URL = string(params[2]) -} - -// ReadStyleColor reads a color from a list of parameters. -// See [ansi.ReadStyleColor] for more information. -func ReadStyleColor(params ansi.Params, c *color.Color) int { - return ansi.ReadStyleColor(params, c) -} diff --git a/vendor/github.com/charmbracelet/x/cellbuf/style.go b/vendor/github.com/charmbracelet/x/cellbuf/style.go deleted file mode 100644 index 82c4afb73b..0000000000 --- a/vendor/github.com/charmbracelet/x/cellbuf/style.go +++ /dev/null @@ -1,31 +0,0 @@ -package cellbuf - -import ( - "github.com/charmbracelet/colorprofile" -) - -// Convert converts a style to respect the given color profile. -func ConvertStyle(s Style, p colorprofile.Profile) Style { - switch p { - case colorprofile.TrueColor: - return s - case colorprofile.Ascii: - s.Fg = nil - s.Bg = nil - s.Ul = nil - case colorprofile.NoTTY: - return Style{} - } - - if s.Fg != nil { - s.Fg = p.Convert(s.Fg) - } - if s.Bg != nil { - s.Bg = p.Convert(s.Bg) - } - if s.Ul != nil { - s.Ul = p.Convert(s.Ul) - } - - return s -} diff --git a/vendor/github.com/charmbracelet/x/cellbuf/tabstop.go b/vendor/github.com/charmbracelet/x/cellbuf/tabstop.go deleted file mode 100644 index 24eec449ad..0000000000 --- a/vendor/github.com/charmbracelet/x/cellbuf/tabstop.go +++ /dev/null @@ -1,137 +0,0 @@ -package cellbuf - -// DefaultTabInterval is the default tab interval. -const DefaultTabInterval = 8 - -// TabStops represents horizontal line tab stops. -type TabStops struct { - stops []int - interval int - width int -} - -// NewTabStops creates a new set of tab stops from a number of columns and an -// interval. -func NewTabStops(width, interval int) *TabStops { - ts := new(TabStops) - ts.interval = interval - ts.width = width - ts.stops = make([]int, (width+(interval-1))/interval) - ts.init(0, width) - return ts -} - -// DefaultTabStops creates a new set of tab stops with the default interval. -func DefaultTabStops(cols int) *TabStops { - return NewTabStops(cols, DefaultTabInterval) -} - -// Resize resizes the tab stops to the given width. -func (ts *TabStops) Resize(width int) { - if width == ts.width { - return - } - - if width < ts.width { - size := (width + (ts.interval - 1)) / ts.interval - ts.stops = ts.stops[:size] - } else { - size := (width - ts.width + (ts.interval - 1)) / ts.interval - ts.stops = append(ts.stops, make([]int, size)...) - } - - ts.init(ts.width, width) - ts.width = width -} - -// IsStop returns true if the given column is a tab stop. -func (ts TabStops) IsStop(col int) bool { - mask := ts.mask(col) - i := col >> 3 - if i < 0 || i >= len(ts.stops) { - return false - } - return ts.stops[i]&mask != 0 -} - -// Next returns the next tab stop after the given column. -func (ts TabStops) Next(col int) int { - return ts.Find(col, 1) -} - -// Prev returns the previous tab stop before the given column. -func (ts TabStops) Prev(col int) int { - return ts.Find(col, -1) -} - -// Find returns the prev/next tab stop before/after the given column and delta. -// If delta is positive, it returns the next tab stop after the given column. -// If delta is negative, it returns the previous tab stop before the given column. -// If delta is zero, it returns the given column. -func (ts TabStops) Find(col, delta int) int { - if delta == 0 { - return col - } - - var prev bool - count := delta - if count < 0 { - count = -count - prev = true - } - - for count > 0 { - if !prev { - if col >= ts.width-1 { - return col - } - - col++ - } else { - if col < 1 { - return col - } - - col-- - } - - if ts.IsStop(col) { - count-- - } - } - - return col -} - -// Set adds a tab stop at the given column. -func (ts *TabStops) Set(col int) { - mask := ts.mask(col) - ts.stops[col>>3] |= mask -} - -// Reset removes the tab stop at the given column. -func (ts *TabStops) Reset(col int) { - mask := ts.mask(col) - ts.stops[col>>3] &= ^mask -} - -// Clear removes all tab stops. -func (ts *TabStops) Clear() { - ts.stops = make([]int, len(ts.stops)) -} - -// mask returns the mask for the given column. -func (ts *TabStops) mask(col int) int { - return 1 << (col & (ts.interval - 1)) -} - -// init initializes the tab stops starting from col until width. -func (ts *TabStops) init(col, width int) { - for x := col; x < width; x++ { - if x%ts.interval == 0 { - ts.Set(x) - } else { - ts.Reset(x) - } - } -} diff --git a/vendor/github.com/charmbracelet/x/cellbuf/utils.go b/vendor/github.com/charmbracelet/x/cellbuf/utils.go deleted file mode 100644 index b0452fa9a7..0000000000 --- a/vendor/github.com/charmbracelet/x/cellbuf/utils.go +++ /dev/null @@ -1,38 +0,0 @@ -package cellbuf - -import ( - "strings" -) - -// Height returns the height of a string. -func Height(s string) int { - return strings.Count(s, "\n") + 1 -} - -func min(a, b int) int { //nolint:predeclared - if a > b { - return b - } - return a -} - -func max(a, b int) int { //nolint:predeclared - if a > b { - return a - } - return b -} - -func clamp(v, low, high int) int { - if high < low { - low, high = high, low - } - return min(high, max(low, v)) -} - -func abs(a int) int { - if a < 0 { - return -a - } - return a -} diff --git a/vendor/github.com/charmbracelet/x/cellbuf/wrap.go b/vendor/github.com/charmbracelet/x/cellbuf/wrap.go deleted file mode 100644 index 59a2a33756..0000000000 --- a/vendor/github.com/charmbracelet/x/cellbuf/wrap.go +++ /dev/null @@ -1,178 +0,0 @@ -package cellbuf - -import ( - "bytes" - "unicode" - "unicode/utf8" - - "github.com/charmbracelet/x/ansi" -) - -// Wrap returns a string that is wrapped to the specified limit applying any -// ANSI escape sequences in the string. It tries to wrap the string at word -// boundaries, but will break words if necessary. -// -// The breakpoints string is a list of characters that are considered -// breakpoints for word wrapping. A hyphen (-) is always considered a -// breakpoint. -// -// Note: breakpoints must be a string of 1-cell wide rune characters. -func Wrap(s string, limit int, breakpoints string) string { - if len(s) == 0 { - return "" - } - - if limit < 1 { - return s - } - - p := ansi.GetParser() - defer ansi.PutParser(p) - - var ( - buf bytes.Buffer - word bytes.Buffer - space bytes.Buffer - style, curStyle Style - link, curLink Link - curWidth int - wordLen int - ) - - addSpace := func() { - curWidth += space.Len() - buf.Write(space.Bytes()) - space.Reset() - } - - addWord := func() { - if word.Len() == 0 { - return - } - - curLink = link - curStyle = style - - addSpace() - curWidth += wordLen - buf.Write(word.Bytes()) - word.Reset() - wordLen = 0 - } - - addNewline := func() { - if !curStyle.Empty() { - buf.WriteString(ansi.ResetStyle) - } - if !curLink.Empty() { - buf.WriteString(ansi.ResetHyperlink()) - } - buf.WriteByte('\n') - if !curLink.Empty() { - buf.WriteString(ansi.SetHyperlink(curLink.URL, curLink.Params)) - } - if !curStyle.Empty() { - buf.WriteString(curStyle.Sequence()) - } - curWidth = 0 - space.Reset() - } - - var state byte - for len(s) > 0 { - seq, width, n, newState := ansi.DecodeSequence(s, state, p) - switch width { - case 0: - if ansi.Equal(seq, "\t") { - addWord() - space.WriteString(seq) - break - } else if ansi.Equal(seq, "\n") { - if wordLen == 0 { - if curWidth+space.Len() > limit { - curWidth = 0 - } else { - // preserve whitespaces - buf.Write(space.Bytes()) - } - space.Reset() - } - - addWord() - addNewline() - break - } else if ansi.HasCsiPrefix(seq) && p.Command() == 'm' { - // SGR style sequence [ansi.SGR] - ReadStyle(p.Params(), &style) - } else if ansi.HasOscPrefix(seq) && p.Command() == 8 { - // Hyperlink sequence [ansi.SetHyperlink] - ReadLink(p.Data(), &link) - } - - word.WriteString(seq) - default: - if len(seq) == 1 { - // ASCII - r, _ := utf8.DecodeRuneInString(seq) - if unicode.IsSpace(r) { - addWord() - space.WriteRune(r) - break - } else if r == '-' || runeContainsAny(r, breakpoints) { - addSpace() - if curWidth+wordLen+width <= limit { - addWord() - buf.WriteString(seq) - curWidth += width - break - } - } - } - - if wordLen+width > limit { - // Hardwrap the word if it's too long - addWord() - } - - word.WriteString(seq) - wordLen += width - - if curWidth+wordLen+space.Len() > limit { - addNewline() - } - } - - s = s[n:] - state = newState - } - - if wordLen == 0 { - if curWidth+space.Len() > limit { - curWidth = 0 - } else { - // preserve whitespaces - buf.Write(space.Bytes()) - } - space.Reset() - } - - addWord() - - if !curLink.Empty() { - buf.WriteString(ansi.ResetHyperlink()) - } - if !curStyle.Empty() { - buf.WriteString(ansi.ResetStyle) - } - - return buf.String() -} - -func runeContainsAny[T string | []rune](r rune, s T) bool { - for _, c := range []rune(s) { - if c == r { - return true - } - } - return false -} diff --git a/vendor/github.com/charmbracelet/x/cellbuf/writer.go b/vendor/github.com/charmbracelet/x/cellbuf/writer.go deleted file mode 100644 index ae8b2a8106..0000000000 --- a/vendor/github.com/charmbracelet/x/cellbuf/writer.go +++ /dev/null @@ -1,339 +0,0 @@ -package cellbuf - -import ( - "bytes" - "fmt" - "strings" - - "github.com/charmbracelet/x/ansi" -) - -// CellBuffer is a cell buffer that represents a set of cells in a screen or a -// grid. -type CellBuffer interface { - // Cell returns the cell at the given position. - Cell(x, y int) *Cell - // SetCell sets the cell at the given position to the given cell. It - // returns whether the cell was set successfully. - SetCell(x, y int, c *Cell) bool - // Bounds returns the bounds of the cell buffer. - Bounds() Rectangle -} - -// FillRect fills the rectangle within the cell buffer with the given cell. -// This will not fill cells outside the bounds of the cell buffer. -func FillRect(s CellBuffer, c *Cell, rect Rectangle) { - for y := rect.Min.Y; y < rect.Max.Y; y++ { - for x := rect.Min.X; x < rect.Max.X; x++ { - s.SetCell(x, y, c) //nolint:errcheck - } - } -} - -// Fill fills the cell buffer with the given cell. -func Fill(s CellBuffer, c *Cell) { - FillRect(s, c, s.Bounds()) -} - -// ClearRect clears the rectangle within the cell buffer with blank cells. -func ClearRect(s CellBuffer, rect Rectangle) { - FillRect(s, nil, rect) -} - -// Clear clears the cell buffer with blank cells. -func Clear(s CellBuffer) { - Fill(s, nil) -} - -// SetContentRect clears the rectangle within the cell buffer with blank cells, -// and sets the given string as its content. If the height or width of the -// string exceeds the height or width of the cell buffer, it will be truncated. -func SetContentRect(s CellBuffer, str string, rect Rectangle) { - // Replace all "\n" with "\r\n" to ensure the cursor is reset to the start - // of the line. Make sure we don't replace "\r\n" with "\r\r\n". - str = strings.ReplaceAll(str, "\r\n", "\n") - str = strings.ReplaceAll(str, "\n", "\r\n") - ClearRect(s, rect) - printString(s, ansi.GraphemeWidth, rect.Min.X, rect.Min.Y, rect, str, true, "") -} - -// SetContent clears the cell buffer with blank cells, and sets the given string -// as its content. If the height or width of the string exceeds the height or -// width of the cell buffer, it will be truncated. -func SetContent(s CellBuffer, str string) { - SetContentRect(s, str, s.Bounds()) -} - -// Render returns a string representation of the grid with ANSI escape sequences. -func Render(d CellBuffer) string { - var buf bytes.Buffer - height := d.Bounds().Dy() - for y := 0; y < height; y++ { - _, line := RenderLine(d, y) - buf.WriteString(line) - if y < height-1 { - buf.WriteString("\r\n") - } - } - return buf.String() -} - -// RenderLine returns a string representation of the yth line of the grid along -// with the width of the line. -func RenderLine(d CellBuffer, n int) (w int, line string) { - var pen Style - var link Link - var buf bytes.Buffer - var pendingLine string - var pendingWidth int // this ignores space cells until we hit a non-space cell - - writePending := func() { - // If there's no pending line, we don't need to do anything. - if len(pendingLine) == 0 { - return - } - buf.WriteString(pendingLine) - w += pendingWidth - pendingWidth = 0 - pendingLine = "" - } - - for x := 0; x < d.Bounds().Dx(); x++ { - if cell := d.Cell(x, n); cell != nil && cell.Width > 0 { - // Convert the cell's style and link to the given color profile. - cellStyle := cell.Style - cellLink := cell.Link - if cellStyle.Empty() && !pen.Empty() { - writePending() - buf.WriteString(ansi.ResetStyle) //nolint:errcheck - pen.Reset() - } - if !cellStyle.Equal(&pen) { - writePending() - seq := cellStyle.DiffSequence(pen) - buf.WriteString(seq) // nolint:errcheck - pen = cellStyle - } - - // Write the URL escape sequence - if cellLink != link && link.URL != "" { - writePending() - buf.WriteString(ansi.ResetHyperlink()) //nolint:errcheck - link.Reset() - } - if cellLink != link { - writePending() - buf.WriteString(ansi.SetHyperlink(cellLink.URL, cellLink.Params)) //nolint:errcheck - link = cellLink - } - - // We only write the cell content if it's not empty. If it is, we - // append it to the pending line and width to be evaluated later. - if cell.Equal(&BlankCell) { - pendingLine += cell.String() - pendingWidth += cell.Width - } else { - writePending() - buf.WriteString(cell.String()) - w += cell.Width - } - } - } - if link.URL != "" { - buf.WriteString(ansi.ResetHyperlink()) //nolint:errcheck - } - if !pen.Empty() { - buf.WriteString(ansi.ResetStyle) //nolint:errcheck - } - return w, strings.TrimRight(buf.String(), " ") // Trim trailing spaces -} - -// ScreenWriter represents a writer that writes to a [Screen] parsing ANSI -// escape sequences and Unicode characters and converting them into cells that -// can be written to a cell [Buffer]. -type ScreenWriter struct { - *Screen -} - -// NewScreenWriter creates a new ScreenWriter that writes to the given Screen. -// This is a convenience function for creating a ScreenWriter. -func NewScreenWriter(s *Screen) *ScreenWriter { - return &ScreenWriter{s} -} - -// Write writes the given bytes to the screen. -// This will recognize ANSI [ansi.SGR] style and [ansi.SetHyperlink] escape -// sequences. -func (s *ScreenWriter) Write(p []byte) (n int, err error) { - printString(s.Screen, s.method, - s.cur.X, s.cur.Y, s.Bounds(), - p, false, "") - return len(p), nil -} - -// SetContent clears the screen with blank cells, and sets the given string as -// its content. If the height or width of the string exceeds the height or -// width of the screen, it will be truncated. -// -// This will recognize ANSI [ansi.SGR] style and [ansi.SetHyperlink] escape sequences. -func (s *ScreenWriter) SetContent(str string) { - s.SetContentRect(str, s.Bounds()) -} - -// SetContentRect clears the rectangle within the screen with blank cells, and -// sets the given string as its content. If the height or width of the string -// exceeds the height or width of the screen, it will be truncated. -// -// This will recognize ANSI [ansi.SGR] style and [ansi.SetHyperlink] escape -// sequences. -func (s *ScreenWriter) SetContentRect(str string, rect Rectangle) { - // Replace all "\n" with "\r\n" to ensure the cursor is reset to the start - // of the line. Make sure we don't replace "\r\n" with "\r\r\n". - str = strings.ReplaceAll(str, "\r\n", "\n") - str = strings.ReplaceAll(str, "\n", "\r\n") - s.ClearRect(rect) - printString(s.Screen, s.method, - rect.Min.X, rect.Min.Y, rect, - str, true, "") -} - -// Print prints the string at the current cursor position. It will wrap the -// string to the width of the screen if it exceeds the width of the screen. -// This will recognize ANSI [ansi.SGR] style and [ansi.SetHyperlink] escape -// sequences. -func (s *ScreenWriter) Print(str string, v ...interface{}) { - if len(v) > 0 { - str = fmt.Sprintf(str, v...) - } - printString(s.Screen, s.method, - s.cur.X, s.cur.Y, s.Bounds(), - str, false, "") -} - -// PrintAt prints the string at the given position. It will wrap the string to -// the width of the screen if it exceeds the width of the screen. -// This will recognize ANSI [ansi.SGR] style and [ansi.SetHyperlink] escape -// sequences. -func (s *ScreenWriter) PrintAt(x, y int, str string, v ...interface{}) { - if len(v) > 0 { - str = fmt.Sprintf(str, v...) - } - printString(s.Screen, s.method, - x, y, s.Bounds(), - str, false, "") -} - -// PrintCrop prints the string at the current cursor position and truncates the -// text if it exceeds the width of the screen. Use tail to specify a string to -// append if the string is truncated. -// This will recognize ANSI [ansi.SGR] style and [ansi.SetHyperlink] escape -// sequences. -func (s *ScreenWriter) PrintCrop(str string, tail string) { - printString(s.Screen, s.method, - s.cur.X, s.cur.Y, s.Bounds(), - str, true, tail) -} - -// PrintCropAt prints the string at the given position and truncates the text -// if it exceeds the width of the screen. Use tail to specify a string to append -// if the string is truncated. -// This will recognize ANSI [ansi.SGR] style and [ansi.SetHyperlink] escape -// sequences. -func (s *ScreenWriter) PrintCropAt(x, y int, str string, tail string) { - printString(s.Screen, s.method, - x, y, s.Bounds(), - str, true, tail) -} - -// printString draws a string starting at the given position. -func printString[T []byte | string]( - s CellBuffer, - m ansi.Method, - x, y int, - bounds Rectangle, str T, - truncate bool, tail string, -) { - p := ansi.GetParser() - defer ansi.PutParser(p) - - var tailc Cell - if truncate && len(tail) > 0 { - if m == ansi.WcWidth { - tailc = *NewCellString(tail) - } else { - tailc = *NewGraphemeCell(tail) - } - } - - decoder := ansi.DecodeSequenceWc[T] - if m == ansi.GraphemeWidth { - decoder = ansi.DecodeSequence[T] - } - - var cell Cell - var style Style - var link Link - var state byte - for len(str) > 0 { - seq, width, n, newState := decoder(str, state, p) - - switch width { - case 1, 2, 3, 4: // wide cells can go up to 4 cells wide - cell.Width += width - cell.Append([]rune(string(seq))...) - - if !truncate && x+cell.Width > bounds.Max.X && y+1 < bounds.Max.Y { - // Wrap the string to the width of the window - x = bounds.Min.X - y++ - } - if Pos(x, y).In(bounds) { - if truncate && tailc.Width > 0 && x+cell.Width > bounds.Max.X-tailc.Width { - // Truncate the string and append the tail if any. - cell := tailc - cell.Style = style - cell.Link = link - s.SetCell(x, y, &cell) - x += tailc.Width - } else { - // Print the cell to the screen - cell.Style = style - cell.Link = link - s.SetCell(x, y, &cell) //nolint:errcheck - x += width - } - } - - // String is too long for the line, truncate it. - // Make sure we reset the cell for the next iteration. - cell.Reset() - default: - // Valid sequences always have a non-zero Cmd. - // TODO: Handle cursor movement and other sequences - switch { - case ansi.HasCsiPrefix(seq) && p.Command() == 'm': - // SGR - Select Graphic Rendition - ReadStyle(p.Params(), &style) - case ansi.HasOscPrefix(seq) && p.Command() == 8: - // Hyperlinks - ReadLink(p.Data(), &link) - case ansi.Equal(seq, T("\n")): - y++ - case ansi.Equal(seq, T("\r")): - x = bounds.Min.X - default: - cell.Append([]rune(string(seq))...) - } - } - - // Advance the state and data - state = newState - str = str[n:] - } - - // Make sure to set the last cell if it's not empty. - if !cell.Empty() { - s.SetCell(x, y, &cell) //nolint:errcheck - cell.Reset() - } -} diff --git a/vendor/github.com/charmbracelet/x/term/LICENSE b/vendor/github.com/charmbracelet/x/term/LICENSE deleted file mode 100644 index 65a5654e20..0000000000 --- a/vendor/github.com/charmbracelet/x/term/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 Charmbracelet, Inc. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/charmbracelet/x/term/term.go b/vendor/github.com/charmbracelet/x/term/term.go deleted file mode 100644 index 58d6522cae..0000000000 --- a/vendor/github.com/charmbracelet/x/term/term.go +++ /dev/null @@ -1,49 +0,0 @@ -package term - -// State contains platform-specific state of a terminal. -type State struct { - state -} - -// IsTerminal returns whether the given file descriptor is a terminal. -func IsTerminal(fd uintptr) bool { - return isTerminal(fd) -} - -// MakeRaw puts the terminal connected to the given file descriptor into raw -// mode and returns the previous state of the terminal so that it can be -// restored. -func MakeRaw(fd uintptr) (*State, error) { - return makeRaw(fd) -} - -// GetState returns the current state of a terminal which may be useful to -// restore the terminal after a signal. -func GetState(fd uintptr) (*State, error) { - return getState(fd) -} - -// SetState sets the given state of the terminal. -func SetState(fd uintptr, state *State) error { - return setState(fd, state) -} - -// Restore restores the terminal connected to the given file descriptor to a -// previous state. -func Restore(fd uintptr, oldState *State) error { - return restore(fd, oldState) -} - -// GetSize returns the visible dimensions of the given terminal. -// -// These dimensions don't include any scrollback buffer height. -func GetSize(fd uintptr) (width, height int, err error) { - return getSize(fd) -} - -// ReadPassword reads a line of input from a terminal without local echo. This -// is commonly used for inputting passwords and other sensitive data. The slice -// returned does not include the \n. -func ReadPassword(fd uintptr) ([]byte, error) { - return readPassword(fd) -} diff --git a/vendor/github.com/charmbracelet/x/term/term_other.go b/vendor/github.com/charmbracelet/x/term/term_other.go deleted file mode 100644 index 092c7e9d9b..0000000000 --- a/vendor/github.com/charmbracelet/x/term/term_other.go +++ /dev/null @@ -1,39 +0,0 @@ -//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !zos && !windows && !solaris && !plan9 -// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!zos,!windows,!solaris,!plan9 - -package term - -import ( - "fmt" - "runtime" -) - -type state struct{} - -func isTerminal(fd uintptr) bool { - return false -} - -func makeRaw(fd uintptr) (*State, error) { - return nil, fmt.Errorf("terminal: MakeRaw not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) -} - -func getState(fd uintptr) (*State, error) { - return nil, fmt.Errorf("terminal: GetState not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) -} - -func restore(fd uintptr, state *State) error { - return fmt.Errorf("terminal: Restore not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) -} - -func getSize(fd uintptr) (width, height int, err error) { - return 0, 0, fmt.Errorf("terminal: GetSize not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) -} - -func setState(fd uintptr, state *State) error { - return fmt.Errorf("terminal: SetState not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) -} - -func readPassword(fd uintptr) ([]byte, error) { - return nil, fmt.Errorf("terminal: ReadPassword not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) -} diff --git a/vendor/github.com/charmbracelet/x/term/term_unix.go b/vendor/github.com/charmbracelet/x/term/term_unix.go deleted file mode 100644 index 1459cb1bed..0000000000 --- a/vendor/github.com/charmbracelet/x/term/term_unix.go +++ /dev/null @@ -1,96 +0,0 @@ -//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos -// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos - -package term - -import ( - "golang.org/x/sys/unix" -) - -type state struct { - unix.Termios -} - -func isTerminal(fd uintptr) bool { - _, err := unix.IoctlGetTermios(int(fd), ioctlReadTermios) - return err == nil -} - -func makeRaw(fd uintptr) (*State, error) { - termios, err := unix.IoctlGetTermios(int(fd), ioctlReadTermios) - if err != nil { - return nil, err - } - - oldState := State{state{Termios: *termios}} - - // This attempts to replicate the behaviour documented for cfmakeraw in - // the termios(3) manpage. - termios.Iflag &^= unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON - termios.Oflag &^= unix.OPOST - termios.Lflag &^= unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN - termios.Cflag &^= unix.CSIZE | unix.PARENB - termios.Cflag |= unix.CS8 - termios.Cc[unix.VMIN] = 1 - termios.Cc[unix.VTIME] = 0 - if err := unix.IoctlSetTermios(int(fd), ioctlWriteTermios, termios); err != nil { - return nil, err - } - - return &oldState, nil -} - -func setState(fd uintptr, state *State) error { - var termios *unix.Termios - if state != nil { - termios = &state.Termios - } - return unix.IoctlSetTermios(int(fd), ioctlWriteTermios, termios) -} - -func getState(fd uintptr) (*State, error) { - termios, err := unix.IoctlGetTermios(int(fd), ioctlReadTermios) - if err != nil { - return nil, err - } - - return &State{state{Termios: *termios}}, nil -} - -func restore(fd uintptr, state *State) error { - return unix.IoctlSetTermios(int(fd), ioctlWriteTermios, &state.Termios) -} - -func getSize(fd uintptr) (width, height int, err error) { - ws, err := unix.IoctlGetWinsize(int(fd), unix.TIOCGWINSZ) - if err != nil { - return 0, 0, err - } - return int(ws.Col), int(ws.Row), nil -} - -// passwordReader is an io.Reader that reads from a specific file descriptor. -type passwordReader int - -func (r passwordReader) Read(buf []byte) (int, error) { - return unix.Read(int(r), buf) -} - -func readPassword(fd uintptr) ([]byte, error) { - termios, err := unix.IoctlGetTermios(int(fd), ioctlReadTermios) - if err != nil { - return nil, err - } - - newState := *termios - newState.Lflag &^= unix.ECHO - newState.Lflag |= unix.ICANON | unix.ISIG - newState.Iflag |= unix.ICRNL - if err := unix.IoctlSetTermios(int(fd), ioctlWriteTermios, &newState); err != nil { - return nil, err - } - - defer unix.IoctlSetTermios(int(fd), ioctlWriteTermios, termios) - - return readPasswordLine(passwordReader(fd)) -} diff --git a/vendor/github.com/charmbracelet/x/term/term_unix_bsd.go b/vendor/github.com/charmbracelet/x/term/term_unix_bsd.go deleted file mode 100644 index b435031aa5..0000000000 --- a/vendor/github.com/charmbracelet/x/term/term_unix_bsd.go +++ /dev/null @@ -1,11 +0,0 @@ -//go:build darwin || dragonfly || freebsd || netbsd || openbsd -// +build darwin dragonfly freebsd netbsd openbsd - -package term - -import "golang.org/x/sys/unix" - -const ( - ioctlReadTermios = unix.TIOCGETA - ioctlWriteTermios = unix.TIOCSETA -) diff --git a/vendor/github.com/charmbracelet/x/term/term_unix_other.go b/vendor/github.com/charmbracelet/x/term/term_unix_other.go deleted file mode 100644 index ee2a29eb19..0000000000 --- a/vendor/github.com/charmbracelet/x/term/term_unix_other.go +++ /dev/null @@ -1,11 +0,0 @@ -//go:build aix || linux || solaris || zos -// +build aix linux solaris zos - -package term - -import "golang.org/x/sys/unix" - -const ( - ioctlReadTermios = unix.TCGETS - ioctlWriteTermios = unix.TCSETS -) diff --git a/vendor/github.com/charmbracelet/x/term/term_windows.go b/vendor/github.com/charmbracelet/x/term/term_windows.go deleted file mode 100644 index fe7afdec99..0000000000 --- a/vendor/github.com/charmbracelet/x/term/term_windows.go +++ /dev/null @@ -1,87 +0,0 @@ -//go:build windows -// +build windows - -package term - -import ( - "os" - - "golang.org/x/sys/windows" -) - -type state struct { - Mode uint32 -} - -func isTerminal(fd uintptr) bool { - var st uint32 - err := windows.GetConsoleMode(windows.Handle(fd), &st) - return err == nil -} - -func makeRaw(fd uintptr) (*State, error) { - var st uint32 - if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil { - return nil, err - } - raw := st &^ (windows.ENABLE_ECHO_INPUT | windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_LINE_INPUT | windows.ENABLE_PROCESSED_OUTPUT) - raw |= windows.ENABLE_VIRTUAL_TERMINAL_INPUT - if err := windows.SetConsoleMode(windows.Handle(fd), raw); err != nil { - return nil, err - } - return &State{state{st}}, nil -} - -func setState(fd uintptr, state *State) error { - var mode uint32 - if state != nil { - mode = state.Mode - } - return windows.SetConsoleMode(windows.Handle(fd), mode) -} - -func getState(fd uintptr) (*State, error) { - var st uint32 - if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil { - return nil, err - } - return &State{state{st}}, nil -} - -func restore(fd uintptr, state *State) error { - return windows.SetConsoleMode(windows.Handle(fd), state.Mode) -} - -func getSize(fd uintptr) (width, height int, err error) { - var info windows.ConsoleScreenBufferInfo - if err := windows.GetConsoleScreenBufferInfo(windows.Handle(fd), &info); err != nil { - return 0, 0, err - } - return int(info.Window.Right - info.Window.Left + 1), int(info.Window.Bottom - info.Window.Top + 1), nil -} - -func readPassword(fd uintptr) ([]byte, error) { - var st uint32 - if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil { - return nil, err - } - old := st - - st &^= (windows.ENABLE_ECHO_INPUT | windows.ENABLE_LINE_INPUT) - st |= (windows.ENABLE_PROCESSED_OUTPUT | windows.ENABLE_PROCESSED_INPUT) - if err := windows.SetConsoleMode(windows.Handle(fd), st); err != nil { - return nil, err - } - - defer windows.SetConsoleMode(windows.Handle(fd), old) - - var h windows.Handle - p, _ := windows.GetCurrentProcess() - if err := windows.DuplicateHandle(p, windows.Handle(fd), p, &h, 0, false, windows.DUPLICATE_SAME_ACCESS); err != nil { - return nil, err - } - - f := os.NewFile(uintptr(h), "stdin") - defer f.Close() - return readPasswordLine(f) -} diff --git a/vendor/github.com/charmbracelet/x/term/terminal.go b/vendor/github.com/charmbracelet/x/term/terminal.go deleted file mode 100644 index 8963163f85..0000000000 --- a/vendor/github.com/charmbracelet/x/term/terminal.go +++ /dev/null @@ -1,12 +0,0 @@ -package term - -import ( - "io" -) - -// File represents a file that has a file descriptor and can be read from, -// written to, and closed. -type File interface { - io.ReadWriteCloser - Fd() uintptr -} diff --git a/vendor/github.com/charmbracelet/x/term/util.go b/vendor/github.com/charmbracelet/x/term/util.go deleted file mode 100644 index b7313418ff..0000000000 --- a/vendor/github.com/charmbracelet/x/term/util.go +++ /dev/null @@ -1,47 +0,0 @@ -package term - -import ( - "io" - "runtime" -) - -// readPasswordLine reads from reader until it finds \n or io.EOF. -// The slice returned does not include the \n. -// readPasswordLine also ignores any \r it finds. -// Windows uses \r as end of line. So, on Windows, readPasswordLine -// reads until it finds \r and ignores any \n it finds during processing. -func readPasswordLine(reader io.Reader) ([]byte, error) { - var buf [1]byte - var ret []byte - - for { - n, err := reader.Read(buf[:]) - if n > 0 { - switch buf[0] { - case '\b': - if len(ret) > 0 { - ret = ret[:len(ret)-1] - } - case '\n': - if runtime.GOOS != "windows" { - return ret, nil - } - // otherwise ignore \n - case '\r': - if runtime.GOOS == "windows" { - return ret, nil - } - // otherwise ignore \r - default: - ret = append(ret, buf[0]) - } - continue - } - if err != nil { - if err == io.EOF && len(ret) > 0 { - return ret, nil - } - return ret, err - } - } -} diff --git a/vendor/github.com/ckaznocha/intrange/.gitignore b/vendor/github.com/ckaznocha/intrange/.gitignore deleted file mode 100644 index cfcb676e15..0000000000 --- a/vendor/github.com/ckaznocha/intrange/.gitignore +++ /dev/null @@ -1,191 +0,0 @@ -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib - -# Test binary, built with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -go.work.sum - -.vscode/* -!.vscode/settings.json -!.vscode/tasks.json -!.vscode/launch.json -!.vscode/extensions.json -!.vscode/*.code-snippets - -# Local History for Visual Studio Code -.history/ - -# Built Visual Studio Code Extensions -*.vsix - -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider -# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 - -# User-specific stuff -.idea/**/workspace.xml -.idea/**/tasks.xml -.idea/**/usage.statistics.xml -.idea/**/dictionaries -.idea/**/shelf - -# AWS User-specific -.idea/**/aws.xml - -# Generated files -.idea/**/contentModel.xml - -# Sensitive or high-churn files -.idea/**/dataSources/ -.idea/**/dataSources.ids -.idea/**/dataSources.local.xml -.idea/**/sqlDataSources.xml -.idea/**/dynamic.xml -.idea/**/uiDesigner.xml -.idea/**/dbnavigator.xml - -# Gradle -.idea/**/gradle.xml -.idea/**/libraries - -# Gradle and Maven with auto-import -# When using Gradle or Maven with auto-import, you should exclude module files, -# since they will be recreated, and may cause churn. Uncomment if using -# auto-import. -# .idea/artifacts -# .idea/compiler.xml -# .idea/jarRepositories.xml -# .idea/modules.xml -# .idea/*.iml -# .idea/modules -# *.iml -# *.ipr - -# CMake -cmake-build-*/ - -# Mongo Explorer plugin -.idea/**/mongoSettings.xml - -# File-based project format -*.iws - -# IntelliJ -out/ - -# mpeltonen/sbt-idea plugin -.idea_modules/ - -# JIRA plugin -atlassian-ide-plugin.xml - -# Cursive Clojure plugin -.idea/replstate.xml - -# SonarLint plugin -.idea/sonarlint/ - -# Crashlytics plugin (for Android Studio and IntelliJ) -com_crashlytics_export_strings.xml -crashlytics.properties -crashlytics-build.properties -fabric.properties - -# Editor-based Rest Client -.idea/httpRequests - -# Android studio 3.1+ serialized cache file -.idea/caches/build_file_checksums.ser - -# Swap -[._]*.s[a-v][a-z] -!*.svg # comment out if you don't need vector files -[._]*.sw[a-p] -[._]s[a-rt-v][a-z] -[._]ss[a-gi-z] -[._]sw[a-p] - -# Session -Session.vim -Sessionx.vim - -# Temporary -.netrwhist -*~ -# Auto-generated tag files -tags -# Persistent undo -[._]*.un~ - -# Windows thumbnail cache files -Thumbs.db -Thumbs.db:encryptable -ehthumbs.db -ehthumbs_vista.db - -# Dump file -*.stackdump - -# Folder config file -[Dd]esktop.ini - -# Recycle Bin used on file shares -$RECYCLE.BIN/ - -# Windows Installer files -*.cab -*.msi -*.msix -*.msm -*.msp - -# Windows shortcuts -*.lnk - -# 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 - -*~ - -# 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* diff --git a/vendor/github.com/ckaznocha/intrange/.golangci.yml b/vendor/github.com/ckaznocha/intrange/.golangci.yml deleted file mode 100644 index 74a80105ca..0000000000 --- a/vendor/github.com/ckaznocha/intrange/.golangci.yml +++ /dev/null @@ -1,107 +0,0 @@ -linters-settings: - gci: - sections: - - standard - - default - - localmodule - gocritic: - enabled-tags: - - diagnostic - - experimental - - opinionated - - performance - - style - goimports: - local-prefixes: github.com/ckaznocha/intrange - govet: - enable: - - appends - - asmdecl - - assign - - atomic - - atomicalign - - bools - - buildtag - - cgocall - - composites - - copylocks - - deepequalerrors - - defers - - directive - - errorsas - - fieldalignment - - findcall - - framepointer - - httpresponse - - ifaceassert - - loopclosure - - lostcancel - - nilfunc - - nilness - - printf - - reflectvaluecompare - - shadow - - shift - - sigchanyzer - - slog - - sortslice - - stdmethods - - stdversion - - stringintconv - - structtag - - testinggoroutine - - tests - - timeformat - - unmarshal - - unreachable - - unsafeptr - - unusedresult - - unusedwrite - - waitgroup - misspell: - locale: US -linters: - disable-all: true - enable: - - asciicheck - - dupl - - errcheck - - errorlint - - gci - - gochecknoinits - - goconst - - gocritic - - godot - - godox - - err113 - - gofmt - - gofumpt - - goimports - - goprintffuncname - - gosec - - gosimple - - govet - - ineffassign - - lll - - misspell - - nakedret - - nestif - - nilerr - - nlreturn - - noctx - - nolintlint - - prealloc - - predeclared - - revive - - rowserrcheck - - staticcheck - - stylecheck - - typecheck - - unconvert - - unused - - wastedassign - - whitespace - - wsl -issues: - exclude-dirs: - - testdata/ diff --git a/vendor/github.com/ckaznocha/intrange/CONTRIBUTING.md b/vendor/github.com/ckaznocha/intrange/CONTRIBUTING.md deleted file mode 100644 index 541cf2c54e..0000000000 --- a/vendor/github.com/ckaznocha/intrange/CONTRIBUTING.md +++ /dev/null @@ -1,25 +0,0 @@ -# Contributing -Enhancements or fixes are welcome - -## Issues -Check if a ticket for your issue already exists in GitHub issues. If you don't -find a ticket submit a new one. - -## Pull Requests -1. Fork the repo -1. Make your changes. -1. Commit and push the to your fork. - 1. Extra credit if you squash your commits first. -1. Submit a pull request. - -### Style -- Your code should pass golint. -- Follow the existing conventions. - -### Tests -- If you add any functionality be sure to also add a test for it. -- All regressions need to pass before your pull can be accepted - -## License -By contributing to intrange you agree that your contributions will be -licensed under its MIT license. diff --git a/vendor/github.com/ckaznocha/intrange/LICENSE b/vendor/github.com/ckaznocha/intrange/LICENSE deleted file mode 100644 index b68bde54b5..0000000000 --- a/vendor/github.com/ckaznocha/intrange/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2024 Clifton Kaznocha - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/ckaznocha/intrange/README.md b/vendor/github.com/ckaznocha/intrange/README.md deleted file mode 100644 index 9cac46220b..0000000000 --- a/vendor/github.com/ckaznocha/intrange/README.md +++ /dev/null @@ -1,90 +0,0 @@ -# intrange - -[![Build Status](https://github.com/ckaznocha/intrange/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/ckaznocha/intrange/actions/workflows/ci.yml) -[![Release](http://img.shields.io/github/release/ckaznocha/intrange.svg)](https://github.com/ckaznocha/intrange/releases/latest) -[![GoDoc](https://godoc.org/github.com/ckaznocha/intrange?status.svg)](https://godoc.org/github.com/ckaznocha/intrange) - -intrange is a program for checking for loops that could use the [Go 1.22](https://go.dev/ref/spec#Go_1.22) integer -range feature. - -## Installation - -```bash -go install github.com/ckaznocha/intrange/cmd/intrange@latest -``` - -## Usage - -```bash -go vet -vettool=$(which intrange) ./... -``` - -## Examples - -### A loop that uses the value of the loop variable - -```go -package main - -import "fmt" - -func main() { - for i := 0; i < 10; i++ { - fmt.Println(i) - } -} -``` - -Running `intrange` on the above code will produce the following output: - -```bash -main.go:5:2: for loop can be changed to use an integer range (Go 1.22+) -``` - -The loop can be rewritten as: - -```go -package main - -import "fmt" - -func main() { - for i := range 10 { - fmt.Println(i) - } -} -``` - -### A loop that does not use the value of the loop variable - -```go -package main - -import "fmt" - -func main() { - for i := 0; i < 10; i++ { - fmt.Println("Hello again!") - } -} -``` - -Running `intrange` on the above code will produce the following output: - -```bash -main.go:5:2: for loop can be changed to use an integer range (Go 1.22+) -``` - -The loop can be rewritten as: - -```go -package main - -import "fmt" - -func main() { - for range 10 { - fmt.Println("Hello again!") - } -} -``` diff --git a/vendor/github.com/ckaznocha/intrange/SECURITY.md b/vendor/github.com/ckaznocha/intrange/SECURITY.md deleted file mode 100644 index e2c44c4e21..0000000000 --- a/vendor/github.com/ckaznocha/intrange/SECURITY.md +++ /dev/null @@ -1,5 +0,0 @@ -# Security Policy - -## Reporting a Vulnerability - -Please open a [github issue](https://github.com/ckaznocha/intrange/issues) diff --git a/vendor/github.com/ckaznocha/intrange/go.work b/vendor/github.com/ckaznocha/intrange/go.work deleted file mode 100644 index b7e127dcb6..0000000000 --- a/vendor/github.com/ckaznocha/intrange/go.work +++ /dev/null @@ -1,8 +0,0 @@ -go 1.23.0 - -toolchain go1.23.4 - -use ( - . - ./testdata -) diff --git a/vendor/github.com/ckaznocha/intrange/intrange.go b/vendor/github.com/ckaznocha/intrange/intrange.go deleted file mode 100644 index 79aca7973a..0000000000 --- a/vendor/github.com/ckaznocha/intrange/intrange.go +++ /dev/null @@ -1,666 +0,0 @@ -package intrange - -import ( - "errors" - "fmt" - "go/ast" - "go/token" - "go/types" - "strconv" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/inspector" -) - -var ( - Analyzer = &analysis.Analyzer{ - Name: "intrange", - Doc: "intrange is a linter to find places where for loops could make use of an integer range.", - Run: run, - Requires: []*analysis.Analyzer{inspect.Analyzer}, - } - - errFailedAnalysis = errors.New("failed analysis") -) - -const ( - msg = "for loop can be changed to use an integer range (Go 1.22+)" - msgLenRange = "for loop can be changed to `%s := range %s`" - msgLenRangeNoIdent = "for loop can be changed to `range %s`" -) - -func run(pass *analysis.Pass) (any, error) { - result, ok := pass.ResultOf[inspect.Analyzer] - if !ok { - return nil, fmt.Errorf( - "%w: %s", - errFailedAnalysis, - inspect.Analyzer.Name, - ) - } - - resultInspector, ok := result.(*inspector.Inspector) - if !ok { - return nil, fmt.Errorf( - "%w: %s", - errFailedAnalysis, - inspect.Analyzer.Name, - ) - } - - resultInspector.Preorder([]ast.Node{(*ast.ForStmt)(nil), (*ast.RangeStmt)(nil)}, check(pass)) - - return nil, nil -} - -func check(pass *analysis.Pass) func(node ast.Node) { - return func(node ast.Node) { - switch stmt := node.(type) { - case *ast.ForStmt: - checkForStmt(pass, stmt) - case *ast.RangeStmt: - checkRangeStmt(pass, stmt) - default: - return - } - } -} - -func checkForStmt(pass *analysis.Pass, forStmt *ast.ForStmt) { - // Existing checks for other patterns - if forStmt.Init == nil || forStmt.Cond == nil || forStmt.Post == nil { - return - } - - // i := 0;; - init, ok := forStmt.Init.(*ast.AssignStmt) - if !ok { - return - } - - initAssign := init.Tok == token.ASSIGN - - if len(init.Lhs) != 1 || len(init.Rhs) != 1 { - return - } - - initIdent, ok := init.Lhs[0].(*ast.Ident) - if !ok { - return - } - - if !compareNumberLit(init.Rhs[0], 0) { - return - } - - cond, ok := forStmt.Cond.(*ast.BinaryExpr) - if !ok { - return - } - - var ( - operand ast.Expr - hasEquivalentOperator bool - ) - - switch cond.Op { - case token.LSS, token.LEQ: // ;i < n; || ;i <= n; - x, ok := cond.X.(*ast.Ident) - if !ok { - return - } - - if x.Name != initIdent.Name { - return - } - - hasEquivalentOperator = cond.Op == token.LEQ - operand = cond.Y - case token.GTR, token.GEQ: // ;n > i; || ;n >= i; - y, ok := cond.Y.(*ast.Ident) - if !ok { - return - } - - if y.Name != initIdent.Name { - return - } - - hasEquivalentOperator = cond.Op == token.GEQ - operand = cond.X - default: - return - } - - switch post := forStmt.Post.(type) { - case *ast.IncDecStmt: // ;;i++ - if post.Tok != token.INC { - return - } - - ident, ok := post.X.(*ast.Ident) - if !ok { - return - } - - if ident.Name != initIdent.Name { - return - } - case *ast.AssignStmt: - switch post.Tok { - case token.ADD_ASSIGN: // ;;i += 1 - if len(post.Lhs) != 1 { - return - } - - ident, ok := post.Lhs[0].(*ast.Ident) - if !ok { - return - } - - if ident.Name != initIdent.Name { - return - } - - if len(post.Rhs) != 1 { - return - } - - if !compareNumberLit(post.Rhs[0], 1) { - return - } - case token.ASSIGN: // ;;i = i + 1 && ;;i = 1 + i - if len(post.Lhs) != 1 || len(post.Rhs) != 1 { - return - } - - ident, ok := post.Lhs[0].(*ast.Ident) - if !ok { - return - } - - if ident.Name != initIdent.Name { - return - } - - bin, ok := post.Rhs[0].(*ast.BinaryExpr) - if !ok { - return - } - - if bin.Op != token.ADD { - return - } - - switch x := bin.X.(type) { - case *ast.Ident: // ;;i = i + 1 - if x.Name != initIdent.Name { - return - } - - if !compareNumberLit(bin.Y, 1) { - return - } - case *ast.BasicLit: // ;;i = 1 + i - if !compareNumberLit(x, 1) { - return - } - - ident, ok := bin.Y.(*ast.Ident) - if !ok { - return - } - - if ident.Name != initIdent.Name { - return - } - default: - return - } - default: - return - } - default: - return - } - - bc := &bodyChecker{ - initIdent: initIdent, - nExpr: findNExpr(operand), - } - - ast.Inspect(forStmt.Body, bc.check) - - if bc.modified { - return - } - - if initAssign { - pass.Report(analysis.Diagnostic{ - Pos: forStmt.Pos(), - Message: msg + "\nBecause the key is not part of the loop's scope, take care to consider side effects.", - }) - - return - } - - operandIsNumberLit := isNumberLit(operand) - - if hasEquivalentOperator && !operandIsNumberLit { - return - } - - rangeX := operandToString( - pass, - initIdent, - operand, - hasEquivalentOperator && operandIsNumberLit, - ) - - var replacement string - if bc.accessed { - replacement = fmt.Sprintf("%s := range %s", initIdent.Name, rangeX) - } else { - replacement = fmt.Sprintf("range %s", rangeX) - } - - if isFunctionOrMethodCall(operand) { - pass.Report(analysis.Diagnostic{ - Pos: forStmt.Pos(), - Message: msg + "\nBecause the key is returned by a function or method, take care to consider side effects.", - }) - - return - } - - pass.Report(analysis.Diagnostic{ - Pos: forStmt.Pos(), - Message: msg, - SuggestedFixes: []analysis.SuggestedFix{ - { - Message: fmt.Sprintf("Replace loop with `%s`", replacement), - TextEdits: []analysis.TextEdit{ - { - Pos: forStmt.Init.Pos(), - End: forStmt.Post.End(), - NewText: []byte(replacement), - }, - }, - }, - }, - }) -} - -func checkRangeStmt(pass *analysis.Pass, rangeStmt *ast.RangeStmt) { - if rangeStmt.Value != nil { - return - } - - startPos := rangeStmt.Range - usesKey := rangeStmt.Key != nil - identName := "" - - if usesKey { - ident, ok := rangeStmt.Key.(*ast.Ident) - if !ok { - return - } - - if ident.Name == "_" { - usesKey = false - } - - identName = ident.Name - startPos = ident.Pos() - } - - if rangeStmt.X == nil { - return - } - - x, ok := rangeStmt.X.(*ast.CallExpr) - if !ok { - return - } - - if _, ok = x.Fun.(*ast.Ident); !ok { - return - } - - if !isLen(x) { - return - } - - arg, ok := x.Args[0].(*ast.Ident) - if !ok { - return - } - - // make sure arg is a slice or array - obj := pass.TypesInfo.ObjectOf(arg) - if obj == nil { - return - } - - switch obj.Type().Underlying().(type) { - case *types.Slice, *types.Array: - default: - return - } - - if usesKey { - pass.Report(analysis.Diagnostic{ - Pos: startPos, - End: x.End(), - Message: fmt.Sprintf(msgLenRange, identName, arg.Name), - SuggestedFixes: []analysis.SuggestedFix{ - { - Message: fmt.Sprintf("Replace `len(%s)` with `%s`", arg.Name, arg.Name), - TextEdits: []analysis.TextEdit{ - { - Pos: x.Pos(), - End: x.End(), - NewText: []byte(arg.Name), - }, - }, - }, - }, - }) - - return - } - - pass.Report(analysis.Diagnostic{ - Pos: startPos, - End: x.End(), - Message: fmt.Sprintf(msgLenRangeNoIdent, arg.Name), - SuggestedFixes: []analysis.SuggestedFix{ - { - Message: fmt.Sprintf("Replace `len(%s)` with `%s`", arg.Name, arg.Name), - TextEdits: []analysis.TextEdit{ - { - Pos: startPos, - End: x.End(), - NewText: []byte(fmt.Sprintf("range %s", arg.Name)), - }, - }, - }, - }, - }) -} - -func findNExpr(expr ast.Expr) ast.Expr { - switch e := expr.(type) { - case *ast.CallExpr: - if isLen(e) { - return findNExpr(e.Args[0]) - } - - return nil - case *ast.BasicLit: - return nil - case *ast.Ident: - return e - case *ast.SelectorExpr: - return e - case *ast.IndexExpr: - return e - default: - return nil - } -} - -func recursiveOperandToString( - expr ast.Expr, - incrementInt bool, -) string { - switch e := expr.(type) { - case *ast.CallExpr: - args := "" - - for i, v := range e.Args { - if i > 0 { - args += ", " - } - - args += recursiveOperandToString(v, incrementInt && len(e.Args) == 1) - } - - return recursiveOperandToString(e.Fun, false) + "(" + args + ")" - case *ast.BasicLit: - if incrementInt && e.Kind == token.INT { - v, err := strconv.Atoi(e.Value) - if err == nil { - return strconv.Itoa(v + 1) - } - - return e.Value - } - - return e.Value - case *ast.Ident: - return e.Name - case *ast.SelectorExpr: - return recursiveOperandToString(e.X, false) + "." + recursiveOperandToString(e.Sel, false) - case *ast.IndexExpr: - return recursiveOperandToString(e.X, false) + "[" + recursiveOperandToString(e.Index, false) + "]" - case *ast.BinaryExpr: - return recursiveOperandToString(e.X, false) + " " + e.Op.String() + " " + recursiveOperandToString(e.Y, false) - case *ast.StarExpr: - return "*" + recursiveOperandToString(e.X, false) - default: - return "" - } -} - -func identEqual(a, b ast.Expr) bool { - if a == nil || b == nil { - return false - } - - switch aT := a.(type) { - case *ast.Ident: - identB, ok := b.(*ast.Ident) - if !ok { - return false - } - - return aT.Name == identB.Name - case *ast.SelectorExpr: - selectorB, ok := b.(*ast.SelectorExpr) - if !ok { - return false - } - - return identEqual(aT.Sel, selectorB.Sel) && identEqual(aT.X, selectorB.X) - case *ast.IndexExpr: - indexB, ok := b.(*ast.IndexExpr) - if ok { - return identEqual(aT.X, indexB.X) && identEqual(aT.Index, indexB.Index) - } - - return identEqual(aT.X, b) - case *ast.BasicLit: - litB, ok := b.(*ast.BasicLit) - if !ok { - return false - } - - return aT.Value == litB.Value - default: - return false - } -} - -type bodyChecker struct { - initIdent *ast.Ident - nExpr ast.Expr - modified bool - accessed bool -} - -func (b *bodyChecker) check(n ast.Node) bool { - switch stmt := n.(type) { - case *ast.AssignStmt: - for _, lhs := range stmt.Lhs { - if identEqual(lhs, b.initIdent) || identEqual(lhs, b.nExpr) { - b.modified = true - - return false - } - } - case *ast.IncDecStmt: - if identEqual(stmt.X, b.initIdent) || identEqual(stmt.X, b.nExpr) { - b.modified = true - - return false - } - case *ast.Ident: - if identEqual(stmt, b.initIdent) { - b.accessed = true - } - } - - return true -} - -func isNumberLit(exp ast.Expr) bool { - switch lit := exp.(type) { - case *ast.BasicLit: - if lit.Kind == token.INT { - return true - } - - return false - case *ast.CallExpr: - switch fun := lit.Fun.(type) { - case *ast.Ident: - if !isIntCast(fun) { - return false - } - default: - return false - } - - if len(lit.Args) != 1 { - return false - } - - return isNumberLit(lit.Args[0]) - default: - return false - } -} - -func compareNumberLit(exp ast.Expr, val int) bool { - switch lit := exp.(type) { - case *ast.BasicLit: - if lit.Kind != token.INT { - return false - } - - n := strconv.Itoa(val) - - switch lit.Value { - case n, "0x" + n, "0X" + n: - return true - default: - return false - } - case *ast.CallExpr: - switch fun := lit.Fun.(type) { - case *ast.Ident: - if !isIntCast(fun) { - return false - } - default: - return false - } - - if len(lit.Args) != 1 { - return false - } - - return compareNumberLit(lit.Args[0], val) - default: - return false - } -} - -func operandToString( - pass *analysis.Pass, - i *ast.Ident, - operand ast.Expr, - increment bool, -) string { - s := recursiveOperandToString(operand, increment) - t := pass.TypesInfo.TypeOf(i) - - if t == types.Typ[types.Int] { - if len(s) > 5 && s[:4] == "int(" && s[len(s)-1] == ')' { - s = s[4 : len(s)-1] - } - - return s - } - - if len(s) > 2 && s[len(s)-1] == ')' { - return s - } - - if operandIdent, ok := operand.(*ast.Ident); ok { - if operandType := pass.TypesInfo.TypeOf(operandIdent); operandType != nil && - operandType == t { - return s - } - } - - return t.String() + "(" + s + ")" -} - -func isFunctionOrMethodCall(expr ast.Expr) bool { - e, ok := expr.(*ast.CallExpr) - if !ok { - return false - } - - fun, ok := e.Fun.(*ast.Ident) - if !ok { - return true - } - - if isLen(e) || isIntCast(fun) { - return false - } - - return true -} - -func isIntCast(ident *ast.Ident) bool { - switch ident.Name { - case - "int", - "int8", - "int16", - "int32", - "int64", - "uint", - "uint8", - "uint16", - "uint32", - "uint64": - return true - default: - return false - } -} - -func isLen(exp *ast.CallExpr) bool { - fun, ok := exp.Fun.(*ast.Ident) - if !ok { - return false - } - - return fun.Name == "len" && len(exp.Args) == 1 -} diff --git a/vendor/github.com/client9/misspell/.gitignore b/vendor/github.com/client9/misspell/.gitignore deleted file mode 100644 index b1b707e326..0000000000 --- a/vendor/github.com/client9/misspell/.gitignore +++ /dev/null @@ -1,34 +0,0 @@ -dist/ -bin/ -vendor/ - -# editor turds -*~ -*.gz -*.bz2 -*.csv - -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -*.test -*.prof diff --git a/vendor/github.com/client9/misspell/.travis.yml b/vendor/github.com/client9/misspell/.travis.yml deleted file mode 100644 index e63e6c2bdc..0000000000 --- a/vendor/github.com/client9/misspell/.travis.yml +++ /dev/null @@ -1,20 +0,0 @@ -sudo: required -dist: trusty -group: edge -language: go -go: - - "1.10" -git: - depth: 1 - -script: - - ./scripts/travis.sh - -# calls goreleaser when a new tag is pushed -deploy: -- provider: script - skip_cleanup: true - script: curl -sL http://git.io/goreleaser | bash - on: - tags: true - condition: $TRAVIS_OS_NAME = linux diff --git a/vendor/github.com/client9/misspell/Dockerfile b/vendor/github.com/client9/misspell/Dockerfile deleted file mode 100644 index b8ea37b4c5..0000000000 --- a/vendor/github.com/client9/misspell/Dockerfile +++ /dev/null @@ -1,37 +0,0 @@ -FROM golang:1.10.0-alpine - -# cache buster -RUN echo 4 - -# git is needed for "go get" below -RUN apk add --no-cache git make - -# these are my standard testing / linting tools -RUN /bin/true \ - && go get -u github.com/golang/dep/cmd/dep \ - && go get -u github.com/alecthomas/gometalinter \ - && gometalinter --install \ - && rm -rf /go/src /go/pkg -# -# * SCOWL word list -# -# Downloads -# http://wordlist.aspell.net/dicts/ -# --> http://app.aspell.net/create -# - -# use en_US large size -# use regular size for others -ENV SOURCE_US_BIG http://app.aspell.net/create?max_size=70&spelling=US&max_variant=2&diacritic=both&special=hacker&special=roman-numerals&download=wordlist&encoding=utf-8&format=inline - -# should be able tell difference between English variations using this -ENV SOURCE_US http://app.aspell.net/create?max_size=60&spelling=US&max_variant=1&diacritic=both&download=wordlist&encoding=utf-8&format=inline -ENV SOURCE_GB_ISE http://app.aspell.net/create?max_size=60&spelling=GBs&max_variant=2&diacritic=both&download=wordlist&encoding=utf-8&format=inline -ENV SOURCE_GB_IZE http://app.aspell.net/create?max_size=60&spelling=GBz&max_variant=2&diacritic=both&download=wordlist&encoding=utf-8&format=inline -ENV SOURCE_CA http://app.aspell.net/create?max_size=60&spelling=CA&max_variant=2&diacritic=both&download=wordlist&encoding=utf-8&format=inline - -RUN /bin/true \ - && mkdir /scowl-wl \ - && wget -O /scowl-wl/words-US-60.txt ${SOURCE_US} \ - && wget -O /scowl-wl/words-GB-ise-60.txt ${SOURCE_GB_ISE} - diff --git a/vendor/github.com/client9/misspell/Gopkg.lock b/vendor/github.com/client9/misspell/Gopkg.lock deleted file mode 100644 index 90ed45115f..0000000000 --- a/vendor/github.com/client9/misspell/Gopkg.lock +++ /dev/null @@ -1,24 +0,0 @@ -# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. - - -[[projects]] - name = "github.com/gobwas/glob" - packages = [ - ".", - "compiler", - "match", - "syntax", - "syntax/ast", - "syntax/lexer", - "util/runes", - "util/strings" - ] - revision = "5ccd90ef52e1e632236f7326478d4faa74f99438" - version = "v0.2.3" - -[solve-meta] - analyzer-name = "dep" - analyzer-version = 1 - inputs-digest = "087ea4c49358ea8258ad9edfe514cd5ce9975c889c258e5ec7b5d2b720aae113" - solver-name = "gps-cdcl" - solver-version = 1 diff --git a/vendor/github.com/client9/misspell/Gopkg.toml b/vendor/github.com/client9/misspell/Gopkg.toml deleted file mode 100644 index e9b8e6a45a..0000000000 --- a/vendor/github.com/client9/misspell/Gopkg.toml +++ /dev/null @@ -1,34 +0,0 @@ -# Gopkg.toml example -# -# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html -# for detailed Gopkg.toml documentation. -# -# required = ["github.com/user/thing/cmd/thing"] -# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] -# -# [[constraint]] -# name = "github.com/user/project" -# version = "1.0.0" -# -# [[constraint]] -# name = "github.com/user/project2" -# branch = "dev" -# source = "github.com/myfork/project2" -# -# [[override]] -# name = "github.com/x/y" -# version = "2.4.0" -# -# [prune] -# non-go = false -# go-tests = true -# unused-packages = true - - -[[constraint]] - name = "github.com/gobwas/glob" - version = "0.2.3" - -[prune] - go-tests = true - unused-packages = true diff --git a/vendor/github.com/client9/misspell/LICENSE b/vendor/github.com/client9/misspell/LICENSE deleted file mode 100644 index 423e1f9e0f..0000000000 --- a/vendor/github.com/client9/misspell/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015-2017 Nick Galbreath - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - diff --git a/vendor/github.com/client9/misspell/Makefile b/vendor/github.com/client9/misspell/Makefile deleted file mode 100644 index 862ab77b0d..0000000000 --- a/vendor/github.com/client9/misspell/Makefile +++ /dev/null @@ -1,74 +0,0 @@ -CONTAINER=nickg/misspell - -install: ## install misspell into GOPATH/bin - go install ./cmd/misspell - -build: hooks ## build and lint misspell - ./scripts/build.sh - -test: ## run all tests - go test . - -# real publishing is done only by travis -publish: ## test goreleaser - ./scripts/goreleaser-dryrun.sh - -# the grep in line 2 is to remove misspellings in the spelling dictionary -# that trigger false positives!! -falsepositives: /scowl-wl - cat /scowl-wl/words-US-60.txt | \ - grep -i -v -E "payed|Tyre|Euclidian|nonoccurence|dependancy|reenforced|accidently|surprize|dependance|idealogy|binominal|causalities|conquerer|withing|casette|analyse|analogue|dialogue|paralyse|catalogue|archaeolog|clarinettist|catalyses|cancell|chisell|ageing|cataloguing" | \ - misspell -debug -error - cat /scowl-wl/words-GB-ise-60.txt | \ - grep -v -E "payed|nonoccurence|withing" | \ - misspell -locale=UK -debug -error -# cat /scowl-wl/words-GB-ize-60.txt | \ -# grep -v -E "withing" | \ -# misspell -debug -error -# cat /scowl-wl/words-CA-60.txt | \ -# grep -v -E "withing" | \ -# misspell -debug -error - -bench: ## run benchmarks - go test -bench '.*' - -clean: ## clean up time - rm -rf dist/ bin/ - go clean ./... - git gc --aggressive - -ci: ## run test like travis-ci does, requires docker - docker run --rm \ - -v $(PWD):/go/src/github.com/client9/misspell \ - -w /go/src/github.com/client9/misspell \ - ${CONTAINER} \ - make build falsepositives - -docker-build: ## build a docker test image - docker build -t ${CONTAINER} . - -docker-pull: ## pull latest test image - docker pull ${CONTAINER} - -docker-console: ## log into the test image - docker run --rm -it \ - -v $(PWD):/go/src/github.com/client9/misspell \ - -w /go/src/github.com/client9/misspell \ - ${CONTAINER} sh - -.git/hooks/pre-commit: scripts/pre-commit.sh - cp -f scripts/pre-commit.sh .git/hooks/pre-commit -.git/hooks/commit-msg: scripts/commit-msg.sh - cp -f scripts/commit-msg.sh .git/hooks/commit-msg -hooks: .git/hooks/pre-commit .git/hooks/commit-msg ## install git precommit hooks - -.PHONY: help ci console docker-build bench - -# https://www.client9.com/self-documenting-makefiles/ -help: - @awk -F ':|##' '/^[^\t].+?:.*?##/ {\ - printf "\033[36m%-30s\033[0m %s\n", $$1, $$NF \ - }' $(MAKEFILE_LIST) -.DEFAULT_GOAL=help -.PHONY=help - diff --git a/vendor/github.com/client9/misspell/README.md b/vendor/github.com/client9/misspell/README.md deleted file mode 100644 index 5b68af04da..0000000000 --- a/vendor/github.com/client9/misspell/README.md +++ /dev/null @@ -1,424 +0,0 @@ -[![Build Status](https://travis-ci.org/client9/misspell.svg?branch=master)](https://travis-ci.org/client9/misspell) [![Go Report Card](https://goreportcard.com/badge/github.com/client9/misspell)](https://goreportcard.com/report/github.com/client9/misspell) [![GoDoc](https://godoc.org/github.com/client9/misspell?status.svg)](https://godoc.org/github.com/client9/misspell) [![Coverage](http://gocover.io/_badge/github.com/client9/misspell)](http://gocover.io/github.com/client9/misspell) [![license](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](https://raw.githubusercontent.com/client9/misspell/master/LICENSE) - -Correct commonly misspelled English words... quickly. - -### Install - - -If you just want a binary and to start using `misspell`: - -``` -curl -L -o ./install-misspell.sh https://git.io/misspell -sh ./install-misspell.sh -``` - - -Both will install as `./bin/misspell`. You can adjust the download location using the `-b` flag. File a ticket if you want another platform supported. - - -If you use [Go](https://golang.org/), the best way to run `misspell` is by using [gometalinter](#gometalinter). Otherwise, install `misspell` the old-fashioned way: - -``` -go get -u github.com/client9/misspell/cmd/misspell -``` - -and misspell will be in your `GOPATH` - - -Also if you like to live dangerously, one could do - -```bash -curl -L https://git.io/misspell | bash -``` - -### Usage - - -```bash -$ misspell all.html your.txt important.md files.go -your.txt:42:10 found "langauge" a misspelling of "language" - -# ^ file, line, column -``` - -``` -$ misspell -help -Usage of misspell: - -debug - Debug matching, very slow - -error - Exit with 2 if misspelling found - -f string - 'csv', 'sqlite3' or custom Golang template for output - -i string - ignore the following corrections, comma separated - -j int - Number of workers, 0 = number of CPUs - -legal - Show legal information and exit - -locale string - Correct spellings using locale perferances for US or UK. Default is to use a neutral variety of English. Setting locale to US will correct the British spelling of 'colour' to 'color' - -o string - output file or [stderr|stdout|] (default "stdout") - -q Do not emit misspelling output - -source string - Source mode: auto=guess, go=golang source, text=plain or markdown-like text (default "auto") - -w Overwrite file with corrections (default is just to display) -``` - -## FAQ - -* [Automatic Corrections](#correct) -* [Converting UK spellings to US](#locale) -* [Using pipes and stdin](#stdin) -* [Golang special support](#golang) -* [gometalinter support](#gometalinter) -* [CSV Output](#csv) -* [Using SQLite3](#sqlite) -* [Changing output format](#output) -* [Checking a folder recursively](#recursive) -* [Performance](#performance) -* [Known Issues](#issues) -* [Debugging](#debug) -* [False Negatives and missing words](#missing) -* [Origin of Word Lists](#words) -* [Software License](#license) -* [Problem statement](#problem) -* [Other spelling correctors](#others) -* [Other ideas](#otherideas) - - -### How can I make the corrections automatically? - -Just add the `-w` flag! - -``` -$ misspell -w all.html your.txt important.md files.go -your.txt:9:21:corrected "langauge" to "language" - -# ^ File is rewritten only if a misspelling is found -``` - - -### How do I convert British spellings to American (or vice-versa)? - -Add the `-locale US` flag! - -```bash -$ misspell -locale US important.txt -important.txt:10:20 found "colour" a misspelling of "color" -``` - -Add the `-locale UK` flag! - -```bash -$ echo "My favorite color is blue" | misspell -locale UK -stdin:1:3:found "favorite color" a misspelling of "favourite colour" -``` - -Help is appreciated as I'm neither British nor an -expert in the English language. - - -### How do you check an entire folder recursively? - -Just list a directory you'd like to check - -```bash -misspell . -misspell aDirectory anotherDirectory aFile -``` - -You can also run misspell recursively using the following shell tricks: - -```bash -misspell directory/**/* -``` - -or - -```bash -find . -type f | xargs misspell -``` - -You can select a type of file as well. The following examples selects all `.txt` files that are *not* in the `vendor` directory: - -```bash -find . -type f -name '*.txt' | grep -v vendor/ | xargs misspell -error -``` - - -### Can I use pipes or `stdin` for input? - -Yes! - -Print messages to `stderr` only: - -```bash -$ echo "zeebra" | misspell -stdin:1:0:found "zeebra" a misspelling of "zebra" -``` - -Print messages to `stderr`, and corrected text to `stdout`: - -```bash -$ echo "zeebra" | misspell -w -stdin:1:0:corrected "zeebra" to "zebra" -zebra -``` - -Only print the corrected text to `stdout`: - -```bash -$ echo "zeebra" | misspell -w -q -zebra -``` - - -### Are there special rules for golang source files? - -Yes! If the file ends in `.go`, then misspell will only check spelling in -comments. - -If you want to force a file to be checked as a golang source, use `-source=go` -on the command line. Conversely, you can check a golang source as if it were -pure text by using `-source=text`. You might want to do this since many -variable names have misspellings in them! - -### Can I check only-comments in other other programming languages? - -I'm told the using `-source=go` works well for ruby, javascript, java, c and -c++. - -It doesn't work well for python and bash. - - -### Does this work with gometalinter? - -[gometalinter](https://github.com/alecthomas/gometalinter) runs -multiple golang linters. Starting on [2016-06-12](https://github.com/alecthomas/gometalinter/pull/134) -gometalinter supports `misspell` natively but it is disabled by default. - -```bash -# update your copy of gometalinter -go get -u github.com/alecthomas/gometalinter - -# install updates and misspell -gometalinter --install --update -``` - -To use, just enable `misspell` - -``` -gometalinter --enable misspell ./... -``` - -Note that gometalinter only checks golang files, and uses the default options -of `misspell` - -You may wish to run this on your plaintext (.txt) and/or markdown files too. - - - -### How Can I Get CSV Output? - -Using `-f csv`, the output is standard comma-seprated values with headers in the first row. - -``` -misspell -f csv * -file,line,column,typo,corrected -"README.md",9,22,langauge,language -"README.md",47,25,langauge,language -``` - - -### How can I export to SQLite3? - -Using `-f sqlite`, the output is a [sqlite3](https://www.sqlite.org/index.html) dump-file. - -```bash -$ misspell -f sqlite * > /tmp/misspell.sql -$ cat /tmp/misspell.sql - -PRAGMA foreign_keys=OFF; -BEGIN TRANSACTION; -CREATE TABLE misspell( - "file" TEXT, - "line" INTEGER,i - "column" INTEGER,i - "typo" TEXT, - "corrected" TEXT -); -INSERT INTO misspell VALUES("install.txt",202,31,"immediatly","immediately"); -# etc... -COMMIT; -``` - -```bash -$ sqlite3 -init /tmp/misspell.sql :memory: 'select count(*) from misspell' -1 -``` - -With some tricks you can directly pipe output to sqlite3 by using `-init /dev/stdin`: - -``` -misspell -f sqlite * | sqlite3 -init /dev/stdin -column -cmd '.width 60 15' ':memory' \ - 'select substr(file,35),typo,count(*) as count from misspell group by file, typo order by count desc;' -``` - - -### How can I ignore rules? - -Using the `-i "comma,separated,rules"` flag you can specify corrections to ignore. - -For example, if you were to run `misspell -w -error -source=text` against document that contains the string `Guy Finkelshteyn Braswell`, misspell would change the text to `Guy Finkelstheyn Bras well`. You can then -determine the rules to ignore by reverting the change and running the with the `-debug` flag. You can then see -that the corrections were `htey -> they` and `aswell -> as well`. To ignore these two rules, you add `-i "htey,aswell"` to -your command. With debug mode on, you can see it print the corrections, but it will no longer make them. - - -### How can I change the output format? - -Using the `-f template` flag you can pass in a -[golang text template](https://golang.org/pkg/text/template/) to format the output. - -One can use `printf "%q" VALUE` to safely quote a value. - -The default template is compatible with [gometalinter](https://github.com/alecthomas/gometalinter) -``` -{{ .Filename }}:{{ .Line }}:{{ .Column }}:corrected {{ printf "%q" .Original }} to "{{ printf "%q" .Corrected }}" -``` - -To just print probable misspellings: - -``` --f '{{ .Original }}' -``` - - -### What problem does this solve? - -This corrects commonly misspelled English words in computer source -code, and other text-based formats (`.txt`, `.md`, etc). - -It is designed to run quickly so it can be -used as a [pre-commit hook](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) -with minimal burden on the developer. - -It does not work with binary formats (e.g. Word, etc). - -It is not a complete spell-checking program nor a grammar checker. - - -### What are other misspelling correctors and what's wrong with them? - -Some other misspelling correctors: - -* https://github.com/vlajos/misspell_fixer -* https://github.com/lyda/misspell-check -* https://github.com/lucasdemarchi/codespell - -They all work but had problems that prevented me from using them at scale: - -* slow, all of the above check one misspelling at a time (i.e. linear) using regexps -* not MIT/Apache2 licensed (or equivalent) -* have dependencies that don't work for me (python3, bash, linux sed, etc) -* don't understand American vs. British English and sometimes makes unwelcome "corrections" - -That said, they might be perfect for you and many have more features -than this project! - - -### How fast is it? - -Misspell is easily 100x to 1000x faster than other spelling correctors. You -should be able to check and correct 1000 files in under 250ms. - -This uses the mighty power of golang's -[strings.Replacer](https://golang.org/pkg/strings/#Replacer) which is -a implementation or variation of the -[Aho–Corasick algorithm](https://en.wikipedia.org/wiki/Aho–Corasick_algorithm). -This makes multiple substring matches *simultaneously*. - -In addition this uses multiple CPU cores to work on multiple files. - - -### What problems does it have? - -Unlike the other projects, this doesn't know what a "word" is. There may be -more false positives and false negatives due to this. On the other hand, it -sometimes catches things others don't. - -Either way, please file bugs and we'll fix them! - -Since it operates in parallel to make corrections, it can be non-obvious to -determine exactly what word was corrected. - - -### It's making mistakes. How can I debug? - -Run using `-debug` flag on the file you want. It should then print what word -it is trying to correct. Then [file a -bug](https://github.com/client9/misspell/issues) describing the problem. -Thanks! - - -### Why is it making mistakes or missing items in golang files? - -The matching function is *case-sensitive*, so variable names that are multiple -worlds either in all-upper or all-lower case sometimes can cause false -positives. For instance a variable named `bodyreader` could trigger a false -positive since `yrea` is in the middle that could be corrected to `year`. -Other problems happen if the variable name uses a English contraction that -should use an apostrophe. The best way of fixing this is to use the -[Effective Go naming -conventions](https://golang.org/doc/effective_go.html#mixed-caps) and use -[camelCase](https://en.wikipedia.org/wiki/CamelCase) for variable names. You -can check your code using [golint](https://github.com/golang/lint) - - -### What license is this? - -The main code is [MIT](https://github.com/client9/misspell/blob/master/LICENSE). - -Misspell also makes uses of the Golang standard library and contains a modified version of Golang's [strings.Replacer](https://golang.org/pkg/strings/#Replacer) -which are covered under a [BSD License](https://github.com/golang/go/blob/master/LICENSE). Type `misspell -legal` for more details or see [legal.go](https://github.com/client9/misspell/blob/master/legal.go) - - -### Where do the word lists come from? - -It started with a word list from -[Wikipedia](https://en.wikipedia.org/wiki/Wikipedia:Lists_of_common_misspellings/For_machines). -Unfortunately, this list had to be highly edited as many of the words are -obsolete or based from mistakes on mechanical typewriters (I'm guessing). - -Additional words were added based on actually mistakes seen in -the wild (meaning self-generated). - -Variations of UK and US spellings are based on many sources including: - -* http://www.tysto.com/uk-us-spelling-list.html (with heavy editing, many are incorrect) -* http://www.oxforddictionaries.com/us/words/american-and-british-spelling-american (excellent site but incomplete) -* Diffing US and UK [scowl dictionaries](http://wordlist.aspell.net) - -American English is more accepting of spelling variations than is British -English, so "what is American or not" is subject to opinion. Corrections and help welcome. - - -### What are some other enhancements that could be done? - -Here's some ideas for enhancements: - -*Capitalization of proper nouns* could be done (e.g. weekday and month names, country names, language names) - -*Opinionated US spellings* US English has a number of words with alternate -spellings. Think [adviser vs. -advisor](http://grammarist.com/spelling/adviser-advisor/). While "advisor" is not wrong, the opinionated US -locale would correct "advisor" to "adviser". - -*Versioning* Some type of versioning is needed so reporting mistakes and errors is easier. - -*Feedback* Mistakes would be sent to some server for agregation and feedback review. - -*Contractions and Apostrophes* This would optionally correct "isnt" to -"isn't", etc. diff --git a/vendor/github.com/client9/misspell/RELEASE-HOWTO.md b/vendor/github.com/client9/misspell/RELEASE-HOWTO.md deleted file mode 100644 index 55b52d962e..0000000000 --- a/vendor/github.com/client9/misspell/RELEASE-HOWTO.md +++ /dev/null @@ -1,38 +0,0 @@ -# Release HOWTO - -since I forget. - - -1. Review existing tags and pick new release number - - ```sh - git tag - ``` - -2. Tag locally - - ```sh - git tag -a v0.1.0 -m "First release" - ``` - - If things get screwed up, delete the tag with - - ```sh - git tag -d v0.1.0 - ``` - -3. Test goreleaser - - TODO: how to install goreleaser - - ```sh - ./scripts/goreleaser-dryrun.sh - ``` - -4. Push - - ```bash - git push origin v0.1.0 - ``` - -5. Verify release and edit notes. See https://github.com/client9/misspell/releases diff --git a/vendor/github.com/client9/misspell/ascii.go b/vendor/github.com/client9/misspell/ascii.go deleted file mode 100644 index 1430718d6a..0000000000 --- a/vendor/github.com/client9/misspell/ascii.go +++ /dev/null @@ -1,62 +0,0 @@ -package misspell - -// ByteToUpper converts an ascii byte to upper cases -// Uses a branchless algorithm -func ByteToUpper(x byte) byte { - b := byte(0x80) | x - c := b - byte(0x61) - d := ^(b - byte(0x7b)) - e := (c & d) & (^x & 0x7f) - return x - (e >> 2) -} - -// ByteToLower converts an ascii byte to lower case -// uses a branchless algorithm -func ByteToLower(eax byte) byte { - ebx := eax&byte(0x7f) + byte(0x25) - ebx = ebx&byte(0x7f) + byte(0x1a) - ebx = ((ebx & ^eax) >> 2) & byte(0x20) - return eax + ebx -} - -// ByteEqualFold does ascii compare, case insensitive -func ByteEqualFold(a, b byte) bool { - return a == b || ByteToLower(a) == ByteToLower(b) -} - -// StringEqualFold ASCII case-insensitive comparison -// golang toUpper/toLower for both bytes and strings -// appears to be Unicode based which is super slow -// based from https://codereview.appspot.com/5180044/patch/14007/21002 -func StringEqualFold(s1, s2 string) bool { - if len(s1) != len(s2) { - return false - } - for i := 0; i < len(s1); i++ { - c1 := s1[i] - c2 := s2[i] - // c1 & c2 - if c1 != c2 { - c1 |= 'a' - 'A' - c2 |= 'a' - 'A' - if c1 != c2 || c1 < 'a' || c1 > 'z' { - return false - } - } - } - return true -} - -// StringHasPrefixFold is similar to strings.HasPrefix but comparison -// is done ignoring ASCII case. -// / -func StringHasPrefixFold(s1, s2 string) bool { - // prefix is bigger than input --> false - if len(s1) < len(s2) { - return false - } - if len(s1) == len(s2) { - return StringEqualFold(s1, s2) - } - return StringEqualFold(s1[:len(s2)], s2) -} diff --git a/vendor/github.com/client9/misspell/case.go b/vendor/github.com/client9/misspell/case.go deleted file mode 100644 index 2ea3850dfa..0000000000 --- a/vendor/github.com/client9/misspell/case.go +++ /dev/null @@ -1,59 +0,0 @@ -package misspell - -import ( - "strings" -) - -// WordCase is an enum of various word casing styles -type WordCase int - -// Various WordCase types.. likely to be not correct -const ( - CaseUnknown WordCase = iota - CaseLower - CaseUpper - CaseTitle -) - -// CaseStyle returns what case style a word is in -func CaseStyle(word string) WordCase { - upperCount := 0 - lowerCount := 0 - - // this iterates over RUNES not BYTES - for i := 0; i < len(word); i++ { - ch := word[i] - switch { - case ch >= 'a' && ch <= 'z': - lowerCount++ - case ch >= 'A' && ch <= 'Z': - upperCount++ - } - } - - switch { - case upperCount != 0 && lowerCount == 0: - return CaseUpper - case upperCount == 0 && lowerCount != 0: - return CaseLower - case upperCount == 1 && lowerCount > 0 && word[0] >= 'A' && word[0] <= 'Z': - return CaseTitle - } - return CaseUnknown -} - -// CaseVariations returns -// If AllUpper or First-Letter-Only is upcased: add the all upper case version -// If AllLower, add the original, the title and upcase forms -// If Mixed, return the original, and the all upcase form -// -func CaseVariations(word string, style WordCase) []string { - switch style { - case CaseLower: - return []string{word, strings.ToUpper(word[0:1]) + word[1:], strings.ToUpper(word)} - case CaseUpper: - return []string{strings.ToUpper(word)} - default: - return []string{word, strings.ToUpper(word)} - } -} diff --git a/vendor/github.com/client9/misspell/cmd/misspell/main.go b/vendor/github.com/client9/misspell/cmd/misspell/main.go deleted file mode 100644 index 174d79d882..0000000000 --- a/vendor/github.com/client9/misspell/cmd/misspell/main.go +++ /dev/null @@ -1,326 +0,0 @@ -// The misspell command corrects commonly misspelled English words in source files. -package main - -import ( - "bytes" - "flag" - "fmt" - "io" - "io/ioutil" - "log" - "os" - "path/filepath" - "runtime" - "strings" - "text/template" - "time" - - "github.com/client9/misspell" -) - -var ( - defaultWrite *template.Template - defaultRead *template.Template - - stdout *log.Logger - debug *log.Logger - - version = "dev" -) - -const ( - // Note for gometalinter it must be "File:Line:Column: Msg" - // note space beteen ": Msg" - defaultWriteTmpl = `{{ .Filename }}:{{ .Line }}:{{ .Column }}: corrected "{{ .Original }}" to "{{ .Corrected }}"` - defaultReadTmpl = `{{ .Filename }}:{{ .Line }}:{{ .Column }}: "{{ .Original }}" is a misspelling of "{{ .Corrected }}"` - csvTmpl = `{{ printf "%q" .Filename }},{{ .Line }},{{ .Column }},{{ .Original }},{{ .Corrected }}` - csvHeader = `file,line,column,typo,corrected` - sqliteTmpl = `INSERT INTO misspell VALUES({{ printf "%q" .Filename }},{{ .Line }},{{ .Column }},{{ printf "%q" .Original }},{{ printf "%q" .Corrected }});` - sqliteHeader = `PRAGMA foreign_keys=OFF; -BEGIN TRANSACTION; -CREATE TABLE misspell( - "file" TEXT, "line" INTEGER, "column" INTEGER, "typo" TEXT, "corrected" TEXT -);` - sqliteFooter = "COMMIT;" -) - -func worker(writeit bool, r *misspell.Replacer, mode string, files <-chan string, results chan<- int) { - count := 0 - for filename := range files { - orig, err := misspell.ReadTextFile(filename) - if err != nil { - log.Println(err) - continue - } - if len(orig) == 0 { - continue - } - - debug.Printf("Processing %s", filename) - - var updated string - var changes []misspell.Diff - - if mode == "go" { - updated, changes = r.ReplaceGo(orig) - } else { - updated, changes = r.Replace(orig) - } - - if len(changes) == 0 { - continue - } - count += len(changes) - for _, diff := range changes { - // add in filename - diff.Filename = filename - - // output can be done by doing multiple goroutines - // and can clobber os.Stdout. - // - // the log package can be used simultaneously from multiple goroutines - var output bytes.Buffer - if writeit { - defaultWrite.Execute(&output, diff) - } else { - defaultRead.Execute(&output, diff) - } - - // goroutine-safe print to os.Stdout - stdout.Println(output.String()) - } - - if writeit { - ioutil.WriteFile(filename, []byte(updated), 0) - } - } - results <- count -} - -func main() { - t := time.Now() - var ( - workers = flag.Int("j", 0, "Number of workers, 0 = number of CPUs") - writeit = flag.Bool("w", false, "Overwrite file with corrections (default is just to display)") - quietFlag = flag.Bool("q", false, "Do not emit misspelling output") - outFlag = flag.String("o", "stdout", "output file or [stderr|stdout|]") - format = flag.String("f", "", "'csv', 'sqlite3' or custom Golang template for output") - ignores = flag.String("i", "", "ignore the following corrections, comma separated") - locale = flag.String("locale", "", "Correct spellings using locale perferances for US or UK. Default is to use a neutral variety of English. Setting locale to US will correct the British spelling of 'colour' to 'color'") - mode = flag.String("source", "auto", "Source mode: auto=guess, go=golang source, text=plain or markdown-like text") - debugFlag = flag.Bool("debug", false, "Debug matching, very slow") - exitError = flag.Bool("error", false, "Exit with 2 if misspelling found") - showVersion = flag.Bool("v", false, "Show version and exit") - - showLegal = flag.Bool("legal", false, "Show legal information and exit") - ) - flag.Parse() - - if *showVersion { - fmt.Println(version) - return - } - if *showLegal { - fmt.Println(misspell.Legal) - return - } - if *debugFlag { - debug = log.New(os.Stderr, "DEBUG ", 0) - } else { - debug = log.New(ioutil.Discard, "", 0) - } - - r := misspell.Replacer{ - Replacements: misspell.DictMain, - Debug: *debugFlag, - } - // - // Figure out regional variations - // - switch strings.ToUpper(*locale) { - case "": - // nothing - case "US": - r.AddRuleList(misspell.DictAmerican) - case "UK", "GB": - r.AddRuleList(misspell.DictBritish) - case "NZ", "AU", "CA": - log.Fatalf("Help wanted. https://github.com/client9/misspell/issues/6") - default: - log.Fatalf("Unknown locale: %q", *locale) - } - - // - // Stuff to ignore - // - if len(*ignores) > 0 { - r.RemoveRule(strings.Split(*ignores, ",")) - } - - // - // Source input mode - // - switch *mode { - case "auto": - case "go": - case "text": - default: - log.Fatalf("Mode must be one of auto=guess, go=golang source, text=plain or markdown-like text") - } - - // - // Custom output - // - switch { - case *format == "csv": - tmpl := template.Must(template.New("csv").Parse(csvTmpl)) - defaultWrite = tmpl - defaultRead = tmpl - stdout.Println(csvHeader) - case *format == "sqlite" || *format == "sqlite3": - tmpl := template.Must(template.New("sqlite3").Parse(sqliteTmpl)) - defaultWrite = tmpl - defaultRead = tmpl - stdout.Println(sqliteHeader) - case len(*format) > 0: - t, err := template.New("custom").Parse(*format) - if err != nil { - log.Fatalf("Unable to compile log format: %s", err) - } - defaultWrite = t - defaultRead = t - default: // format == "" - defaultWrite = template.Must(template.New("defaultWrite").Parse(defaultWriteTmpl)) - defaultRead = template.Must(template.New("defaultRead").Parse(defaultReadTmpl)) - } - - // we cant't just write to os.Stdout directly since we have multiple goroutine - // all writing at the same time causing broken output. Log is routine safe. - // we see it so it doesn't use a prefix or include a time stamp. - switch { - case *quietFlag || *outFlag == "/dev/null": - stdout = log.New(ioutil.Discard, "", 0) - case *outFlag == "/dev/stderr" || *outFlag == "stderr": - stdout = log.New(os.Stderr, "", 0) - case *outFlag == "/dev/stdout" || *outFlag == "stdout": - stdout = log.New(os.Stdout, "", 0) - case *outFlag == "" || *outFlag == "-": - stdout = log.New(os.Stdout, "", 0) - default: - fo, err := os.Create(*outFlag) - if err != nil { - log.Fatalf("unable to create outfile %q: %s", *outFlag, err) - } - defer fo.Close() - stdout = log.New(fo, "", 0) - } - - // - // Number of Workers / CPU to use - // - if *workers < 0 { - log.Fatalf("-j must >= 0") - } - if *workers == 0 { - *workers = runtime.NumCPU() - } - if *debugFlag { - *workers = 1 - } - - // - // Done with Flags. - // Compile the Replacer and process files - // - r.Compile() - - args := flag.Args() - debug.Printf("initialization complete in %v", time.Since(t)) - - // stdin/stdout - if len(args) == 0 { - // if we are working with pipes/stdin/stdout - // there is no concurrency, so we can directly - // send data to the writers - var fileout io.Writer - var errout io.Writer - switch *writeit { - case true: - // if we ARE writing the corrected stream - // the corrected stream goes to stdout - // and the misspelling errors goes to stderr - // so we can do something like this: - // curl something | misspell -w | gzip > afile.gz - fileout = os.Stdout - errout = os.Stderr - case false: - // if we are not writing out the corrected stream - // then work just like files. Misspelling errors - // are sent to stdout - fileout = ioutil.Discard - errout = os.Stdout - } - count := 0 - next := func(diff misspell.Diff) { - count++ - - // don't even evaluate the output templates - if *quietFlag { - return - } - diff.Filename = "stdin" - if *writeit { - defaultWrite.Execute(errout, diff) - } else { - defaultRead.Execute(errout, diff) - } - errout.Write([]byte{'\n'}) - - } - err := r.ReplaceReader(os.Stdin, fileout, next) - if err != nil { - os.Exit(1) - } - switch *format { - case "sqlite", "sqlite3": - fileout.Write([]byte(sqliteFooter)) - } - if count != 0 && *exitError { - // error - os.Exit(2) - } - return - } - - c := make(chan string, 64) - results := make(chan int, *workers) - - for i := 0; i < *workers; i++ { - go worker(*writeit, &r, *mode, c, results) - } - - for _, filename := range args { - filepath.Walk(filename, func(path string, info os.FileInfo, err error) error { - if err == nil && !info.IsDir() { - c <- path - } - return nil - }) - } - close(c) - - count := 0 - for i := 0; i < *workers; i++ { - changed := <-results - count += changed - } - - switch *format { - case "sqlite", "sqlite3": - stdout.Println(sqliteFooter) - } - - if count != 0 && *exitError { - os.Exit(2) - } -} diff --git a/vendor/github.com/client9/misspell/goreleaser.yml b/vendor/github.com/client9/misspell/goreleaser.yml deleted file mode 100644 index 560cb3810c..0000000000 --- a/vendor/github.com/client9/misspell/goreleaser.yml +++ /dev/null @@ -1,38 +0,0 @@ -# goreleaser.yml -# https://github.com/goreleaser/goreleaser - -project_name: misspell - -builds: - - - main: cmd/misspell/main.go - binary: misspell - ldflags: -s -w -X main.version={{.Version}} - goos: - - darwin - - linux - - windows - goarch: - - amd64 - env: - - CGO_ENABLED=0 - ignore: - - goos: darwin - goarch: 386 - - goos: windows - goarch: 386 - -archive: - name_template: "{{ .Binary }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}" - replacements: - amd64: 64bit - 386: 32bit - darwin: mac - files: - - none* - -checksum: - name_template: "{{ .ProjectName }}_{{ .Version }}_checksums.txt" - -snapshot: - name_template: "SNAPSHOT-{{.Commit}}" diff --git a/vendor/github.com/client9/misspell/install-misspell.sh b/vendor/github.com/client9/misspell/install-misspell.sh deleted file mode 100644 index 8e0ff5d947..0000000000 --- a/vendor/github.com/client9/misspell/install-misspell.sh +++ /dev/null @@ -1,318 +0,0 @@ -#!/bin/sh -set -e -# Code generated by godownloader. DO NOT EDIT. -# - -usage() { - this=$1 - cat </dev/null -} -uname_os() { - os=$(uname -s | tr '[:upper:]' '[:lower:]') - echo "$os" -} -uname_arch() { - arch=$(uname -m) - case $arch in - x86_64) arch="amd64" ;; - x86) arch="386" ;; - i686) arch="386" ;; - i386) arch="386" ;; - aarch64) arch="arm64" ;; - armv5*) arch="arm5" ;; - armv6*) arch="arm6" ;; - armv7*) arch="arm7" ;; - esac - echo ${arch} -} -uname_os_check() { - os=$(uname_os) - case "$os" in - darwin) return 0 ;; - dragonfly) return 0 ;; - freebsd) return 0 ;; - linux) return 0 ;; - android) return 0 ;; - nacl) return 0 ;; - netbsd) return 0 ;; - openbsd) return 0 ;; - plan9) return 0 ;; - solaris) return 0 ;; - windows) return 0 ;; - esac - echo "$0: uname_os_check: internal error '$(uname -s)' got converted to '$os' which is not a GOOS value. Please file bug at https://github.com/client9/shlib" - return 1 -} -uname_arch_check() { - arch=$(uname_arch) - case "$arch" in - 386) return 0 ;; - amd64) return 0 ;; - arm64) return 0 ;; - armv5) return 0 ;; - armv6) return 0 ;; - armv7) return 0 ;; - ppc64) return 0 ;; - ppc64le) return 0 ;; - mips) return 0 ;; - mipsle) return 0 ;; - mips64) return 0 ;; - mips64le) return 0 ;; - s390x) return 0 ;; - amd64p32) return 0 ;; - esac - echo "$0: uname_arch_check: internal error '$(uname -m)' got converted to '$arch' which is not a GOARCH value. Please file bug report at https://github.com/client9/shlib" - return 1 -} -untar() { - tarball=$1 - case "${tarball}" in - *.tar.gz | *.tgz) tar -xzf "${tarball}" ;; - *.tar) tar -xf "${tarball}" ;; - *.zip) unzip "${tarball}" ;; - *) - echo "Unknown archive format for ${tarball}" - return 1 - ;; - esac -} -mktmpdir() { - test -z "$TMPDIR" && TMPDIR="$(mktemp -d)" - mkdir -p "${TMPDIR}" - echo "${TMPDIR}" -} -http_download() { - local_file=$1 - source_url=$2 - header=$3 - headerflag='' - destflag='' - if is_command curl; then - cmd='curl --fail -sSL' - destflag='-o' - headerflag='-H' - elif is_command wget; then - cmd='wget -q' - destflag='-O' - headerflag='--header' - else - echo "http_download: unable to find wget or curl" - return 1 - fi - if [ -z "$header" ]; then - $cmd $destflag "$local_file" "$source_url" - else - $cmd $headerflag "$header" $destflag "$local_file" "$source_url" - fi -} -github_api() { - local_file=$1 - source_url=$2 - header="" - case "$source_url" in - https://api.github.com*) - test -z "$GITHUB_TOKEN" || header="Authorization: token $GITHUB_TOKEN" - ;; - esac - http_download "$local_file" "$source_url" "$header" -} -github_last_release() { - owner_repo=$1 - giturl="https://api.github.com/repos/${owner_repo}/releases/latest" - html=$(github_api - "$giturl") - version=$(echo "$html" | grep -m 1 "\"tag_name\":" | cut -f4 -d'"') - test -z "$version" && return 1 - echo "$version" -} -hash_sha256() { - TARGET=${1:-/dev/stdin} - if is_command gsha256sum; then - hash=$(gsha256sum "$TARGET") || return 1 - echo "$hash" | cut -d ' ' -f 1 - elif is_command sha256sum; then - hash=$(sha256sum "$TARGET") || return 1 - echo "$hash" | cut -d ' ' -f 1 - elif is_command shasum; then - hash=$(shasum -a 256 "$TARGET" 2>/dev/null) || return 1 - echo "$hash" | cut -d ' ' -f 1 - elif is_command openssl; then - hash=$(openssl -dst openssl dgst -sha256 "$TARGET") || return 1 - echo "$hash" | cut -d ' ' -f a - else - echo "hash_sha256: unable to find command to compute sha-256 hash" - return 1 - fi -} -hash_sha256_verify() { - TARGET=$1 - checksums=$2 - if [ -z "$checksums" ]; then - echo "hash_sha256_verify: checksum file not specified in arg2" - return 1 - fi - BASENAME=${TARGET##*/} - want=$(grep "${BASENAME}" "${checksums}" 2>/dev/null | tr '\t' ' ' | cut -d ' ' -f 1) - if [ -z "$want" ]; then - echo "hash_sha256_verify: unable to find checksum for '${TARGET}' in '${checksums}'" - return 1 - fi - got=$(hash_sha256 "$TARGET") - if [ "$want" != "$got" ]; then - echo "hash_sha256_verify: checksum for '$TARGET' did not verify ${want} vs $got" - return 1 - fi -} -cat /dev/null < 50000 { - fin, err := os.Open(filename) - if err != nil { - return "", fmt.Errorf("Unable to open large file %q: %s", filename, err) - } - defer fin.Close() - buf := make([]byte, 512) - _, err = io.ReadFull(fin, buf) - if err != nil { - return "", fmt.Errorf("Unable to read 512 bytes from %q: %s", filename, err) - } - if !isTextFile(buf) { - return "", nil - } - - // set so we don't double check this file - isText = true - } - - // read in whole file - raw, err := ioutil.ReadFile(filename) - if err != nil { - return "", fmt.Errorf("Unable to read all %q: %s", filename, err) - } - - if !isText && !isTextFile(raw) { - return "", nil - } - return string(raw), nil -} diff --git a/vendor/github.com/client9/misspell/notwords.go b/vendor/github.com/client9/misspell/notwords.go deleted file mode 100644 index 06d0d5a5ad..0000000000 --- a/vendor/github.com/client9/misspell/notwords.go +++ /dev/null @@ -1,85 +0,0 @@ -package misspell - -import ( - "bytes" - "regexp" - "strings" -) - -var ( - reEmail = regexp.MustCompile(`[a-zA-Z0-9_.%+-]+@[a-zA-Z0-9-.]+\.[a-zA-Z]{2,6}[^a-zA-Z]`) - reHost = regexp.MustCompile(`[a-zA-Z0-9-.]+\.[a-zA-Z]+`) - reBackslash = regexp.MustCompile(`\\[a-z]`) -) - -// RemovePath attempts to strip away embedded file system paths, e.g. -// /foo/bar or /static/myimg.png -// -// TODO: windows style -// -func RemovePath(s string) string { - out := bytes.Buffer{} - var idx int - for len(s) > 0 { - if idx = strings.IndexByte(s, '/'); idx == -1 { - out.WriteString(s) - break - } - - if idx > 0 { - idx-- - } - - var chclass string - switch s[idx] { - case '/', ' ', '\n', '\t', '\r': - chclass = " \n\r\t" - case '[': - chclass = "]\n" - case '(': - chclass = ")\n" - default: - out.WriteString(s[:idx+2]) - s = s[idx+2:] - continue - } - - endx := strings.IndexAny(s[idx+1:], chclass) - if endx != -1 { - out.WriteString(s[:idx+1]) - out.Write(bytes.Repeat([]byte{' '}, endx)) - s = s[idx+endx+1:] - } else { - out.WriteString(s) - break - } - } - return out.String() -} - -// replaceWithBlanks returns a string with the same number of spaces as the input -func replaceWithBlanks(s string) string { - return strings.Repeat(" ", len(s)) -} - -// RemoveEmail remove email-like strings, e.g. "nickg+junk@xfoobar.com", "nickg@xyz.abc123.biz" -func RemoveEmail(s string) string { - return reEmail.ReplaceAllStringFunc(s, replaceWithBlanks) -} - -// RemoveHost removes host-like strings "foobar.com" "abc123.fo1231.biz" -func RemoveHost(s string) string { - return reHost.ReplaceAllStringFunc(s, replaceWithBlanks) -} - -// RemoveBackslashEscapes removes characters that are preceeded by a backslash -// commonly found in printf format stringd "\nto" -func removeBackslashEscapes(s string) string { - return reBackslash.ReplaceAllStringFunc(s, replaceWithBlanks) -} - -// RemoveNotWords blanks out all the not words -func RemoveNotWords(s string) string { - // do most selective/specific first - return removeBackslashEscapes(RemoveHost(RemoveEmail(RemovePath(StripURL(s))))) -} diff --git a/vendor/github.com/client9/misspell/replace.go b/vendor/github.com/client9/misspell/replace.go deleted file mode 100644 index a99bbcc582..0000000000 --- a/vendor/github.com/client9/misspell/replace.go +++ /dev/null @@ -1,246 +0,0 @@ -package misspell - -import ( - "bufio" - "bytes" - "io" - "regexp" - "strings" - "text/scanner" -) - -func max(x, y int) int { - if x > y { - return x - } - return y -} - -func inArray(haystack []string, needle string) bool { - for _, word := range haystack { - if needle == word { - return true - } - } - return false -} - -var wordRegexp = regexp.MustCompile(`[a-zA-Z0-9']+`) - -// Diff is datastructure showing what changed in a single line -type Diff struct { - Filename string - FullLine string - Line int - Column int - Original string - Corrected string -} - -// Replacer is the main struct for spelling correction -type Replacer struct { - Replacements []string - Debug bool - engine *StringReplacer - corrected map[string]string -} - -// New creates a new default Replacer using the main rule list -func New() *Replacer { - r := Replacer{ - Replacements: DictMain, - } - r.Compile() - return &r -} - -// RemoveRule deletes existings rules. -// TODO: make inplace to save memory -func (r *Replacer) RemoveRule(ignore []string) { - newwords := make([]string, 0, len(r.Replacements)) - for i := 0; i < len(r.Replacements); i += 2 { - if inArray(ignore, r.Replacements[i]) { - continue - } - newwords = append(newwords, r.Replacements[i:i+2]...) - } - r.engine = nil - r.Replacements = newwords -} - -// AddRuleList appends new rules. -// Input is in the same form as Strings.Replacer: [ old1, new1, old2, new2, ....] -// Note: does not check for duplictes -func (r *Replacer) AddRuleList(additions []string) { - r.engine = nil - r.Replacements = append(r.Replacements, additions...) -} - -// Compile compiles the rules. Required before using the Replace functions -func (r *Replacer) Compile() { - - r.corrected = make(map[string]string, len(r.Replacements)/2) - for i := 0; i < len(r.Replacements); i += 2 { - r.corrected[r.Replacements[i]] = r.Replacements[i+1] - } - r.engine = NewStringReplacer(r.Replacements...) -} - -/* -line1 and line2 are different -extract words from each line1 - -replace word -> newword -if word == new-word - continue -if new-word in list of replacements - continue -new word not original, and not in list of replacements - some substring got mixed up. UNdo -*/ -func (r *Replacer) recheckLine(s string, lineNum int, buf io.Writer, next func(Diff)) { - first := 0 - redacted := RemoveNotWords(s) - - idx := wordRegexp.FindAllStringIndex(redacted, -1) - for _, ab := range idx { - word := s[ab[0]:ab[1]] - newword := r.engine.Replace(word) - if newword == word { - // no replacement done - continue - } - - // ignore camelCase words - // https://github.com/client9/misspell/issues/113 - if CaseStyle(word) == CaseUnknown { - continue - } - - if StringEqualFold(r.corrected[strings.ToLower(word)], newword) { - // word got corrected into something we know - io.WriteString(buf, s[first:ab[0]]) - io.WriteString(buf, newword) - first = ab[1] - next(Diff{ - FullLine: s, - Line: lineNum, - Original: word, - Corrected: newword, - Column: ab[0], - }) - continue - } - // Word got corrected into something unknown. Ignore it - } - io.WriteString(buf, s[first:]) -} - -// ReplaceGo is a specialized routine for correcting Golang source -// files. Currently only checks comments, not identifiers for -// spelling. -func (r *Replacer) ReplaceGo(input string) (string, []Diff) { - var s scanner.Scanner - s.Init(strings.NewReader(input)) - s.Mode = scanner.ScanIdents | scanner.ScanFloats | scanner.ScanChars | scanner.ScanStrings | scanner.ScanRawStrings | scanner.ScanComments - lastPos := 0 - output := "" -Loop: - for { - switch s.Scan() { - case scanner.Comment: - origComment := s.TokenText() - newComment := r.engine.Replace(origComment) - - if origComment != newComment { - // s.Pos().Offset is the end of the current token - // subtract len(origComment) to get the start of the token - offset := s.Pos().Offset - output = output + input[lastPos:offset-len(origComment)] + newComment - lastPos = offset - } - case scanner.EOF: - break Loop - } - } - - if lastPos == 0 { - // no changes, no copies - return input, nil - } - if lastPos < len(input) { - output = output + input[lastPos:] - } - diffs := make([]Diff, 0, 8) - buf := bytes.NewBuffer(make([]byte, 0, max(len(input), len(output))+100)) - // faster that making a bytes.Buffer and bufio.ReadString - outlines := strings.SplitAfter(output, "\n") - inlines := strings.SplitAfter(input, "\n") - for i := 0; i < len(inlines); i++ { - if inlines[i] == outlines[i] { - buf.WriteString(outlines[i]) - continue - } - r.recheckLine(inlines[i], i+1, buf, func(d Diff) { - diffs = append(diffs, d) - }) - } - - return buf.String(), diffs - -} - -// Replace is corrects misspellings in input, returning corrected version -// along with a list of diffs. -func (r *Replacer) Replace(input string) (string, []Diff) { - output := r.engine.Replace(input) - if input == output { - return input, nil - } - diffs := make([]Diff, 0, 8) - buf := bytes.NewBuffer(make([]byte, 0, max(len(input), len(output))+100)) - // faster that making a bytes.Buffer and bufio.ReadString - outlines := strings.SplitAfter(output, "\n") - inlines := strings.SplitAfter(input, "\n") - for i := 0; i < len(inlines); i++ { - if inlines[i] == outlines[i] { - buf.WriteString(outlines[i]) - continue - } - r.recheckLine(inlines[i], i+1, buf, func(d Diff) { - diffs = append(diffs, d) - }) - } - - return buf.String(), diffs -} - -// ReplaceReader applies spelling corrections to a reader stream. Diffs are -// emitted through a callback. -func (r *Replacer) ReplaceReader(raw io.Reader, w io.Writer, next func(Diff)) error { - var ( - err error - line string - lineNum int - ) - reader := bufio.NewReader(raw) - for err == nil { - lineNum++ - line, err = reader.ReadString('\n') - - // if it's EOF, then line has the last line - // don't like the check of err here and - // in for loop - if err != nil && err != io.EOF { - return err - } - // easily 5x faster than regexp+map - if line == r.engine.Replace(line) { - io.WriteString(w, line) - continue - } - // but it can be inaccurate, so we need to double check - r.recheckLine(line, lineNum, w, next) - } - return nil -} diff --git a/vendor/github.com/client9/misspell/stringreplacer.go b/vendor/github.com/client9/misspell/stringreplacer.go deleted file mode 100644 index 3151eceb70..0000000000 --- a/vendor/github.com/client9/misspell/stringreplacer.go +++ /dev/null @@ -1,336 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package misspell - -import ( - "io" - // "log" - "strings" -) - -// StringReplacer replaces a list of strings with replacements. -// It is safe for concurrent use by multiple goroutines. -type StringReplacer struct { - r replacer -} - -// replacer is the interface that a replacement algorithm needs to implement. -type replacer interface { - Replace(s string) string - WriteString(w io.Writer, s string) (n int, err error) -} - -// NewStringReplacer returns a new Replacer from a list of old, new string pairs. -// Replacements are performed in order, without overlapping matches. -func NewStringReplacer(oldnew ...string) *StringReplacer { - if len(oldnew)%2 == 1 { - panic("strings.NewReplacer: odd argument count") - } - - return &StringReplacer{r: makeGenericReplacer(oldnew)} -} - -// Replace returns a copy of s with all replacements performed. -func (r *StringReplacer) Replace(s string) string { - return r.r.Replace(s) -} - -// WriteString writes s to w with all replacements performed. -func (r *StringReplacer) WriteString(w io.Writer, s string) (n int, err error) { - return r.r.WriteString(w, s) -} - -// trieNode is a node in a lookup trie for prioritized key/value pairs. Keys -// and values may be empty. For example, the trie containing keys "ax", "ay", -// "bcbc", "x" and "xy" could have eight nodes: -// -// n0 - -// n1 a- -// n2 .x+ -// n3 .y+ -// n4 b- -// n5 .cbc+ -// n6 x+ -// n7 .y+ -// -// n0 is the root node, and its children are n1, n4 and n6; n1's children are -// n2 and n3; n4's child is n5; n6's child is n7. Nodes n0, n1 and n4 (marked -// with a trailing "-") are partial keys, and nodes n2, n3, n5, n6 and n7 -// (marked with a trailing "+") are complete keys. -type trieNode struct { - // value is the value of the trie node's key/value pair. It is empty if - // this node is not a complete key. - value string - // priority is the priority (higher is more important) of the trie node's - // key/value pair; keys are not necessarily matched shortest- or longest- - // first. Priority is positive if this node is a complete key, and zero - // otherwise. In the example above, positive/zero priorities are marked - // with a trailing "+" or "-". - priority int - - // A trie node may have zero, one or more child nodes: - // * if the remaining fields are zero, there are no children. - // * if prefix and next are non-zero, there is one child in next. - // * if table is non-zero, it defines all the children. - // - // Prefixes are preferred over tables when there is one child, but the - // root node always uses a table for lookup efficiency. - - // prefix is the difference in keys between this trie node and the next. - // In the example above, node n4 has prefix "cbc" and n4's next node is n5. - // Node n5 has no children and so has zero prefix, next and table fields. - prefix string - next *trieNode - - // table is a lookup table indexed by the next byte in the key, after - // remapping that byte through genericReplacer.mapping to create a dense - // index. In the example above, the keys only use 'a', 'b', 'c', 'x' and - // 'y', which remap to 0, 1, 2, 3 and 4. All other bytes remap to 5, and - // genericReplacer.tableSize will be 5. Node n0's table will be - // []*trieNode{ 0:n1, 1:n4, 3:n6 }, where the 0, 1 and 3 are the remapped - // 'a', 'b' and 'x'. - table []*trieNode -} - -func (t *trieNode) add(key, val string, priority int, r *genericReplacer) { - if key == "" { - if t.priority == 0 { - t.value = val - t.priority = priority - } - return - } - - if t.prefix != "" { - // Need to split the prefix among multiple nodes. - var n int // length of the longest common prefix - for ; n < len(t.prefix) && n < len(key); n++ { - if t.prefix[n] != key[n] { - break - } - } - if n == len(t.prefix) { - t.next.add(key[n:], val, priority, r) - } else if n == 0 { - // First byte differs, start a new lookup table here. Looking up - // what is currently t.prefix[0] will lead to prefixNode, and - // looking up key[0] will lead to keyNode. - var prefixNode *trieNode - if len(t.prefix) == 1 { - prefixNode = t.next - } else { - prefixNode = &trieNode{ - prefix: t.prefix[1:], - next: t.next, - } - } - keyNode := new(trieNode) - t.table = make([]*trieNode, r.tableSize) - t.table[r.mapping[t.prefix[0]]] = prefixNode - t.table[r.mapping[key[0]]] = keyNode - t.prefix = "" - t.next = nil - keyNode.add(key[1:], val, priority, r) - } else { - // Insert new node after the common section of the prefix. - next := &trieNode{ - prefix: t.prefix[n:], - next: t.next, - } - t.prefix = t.prefix[:n] - t.next = next - next.add(key[n:], val, priority, r) - } - } else if t.table != nil { - // Insert into existing table. - m := r.mapping[key[0]] - if t.table[m] == nil { - t.table[m] = new(trieNode) - } - t.table[m].add(key[1:], val, priority, r) - } else { - t.prefix = key - t.next = new(trieNode) - t.next.add("", val, priority, r) - } -} - -func (r *genericReplacer) lookup(s string, ignoreRoot bool) (val string, keylen int, found bool) { - // Iterate down the trie to the end, and grab the value and keylen with - // the highest priority. - bestPriority := 0 - node := &r.root - n := 0 - for node != nil { - if node.priority > bestPriority && !(ignoreRoot && node == &r.root) { - bestPriority = node.priority - val = node.value - keylen = n - found = true - } - - if s == "" { - break - } - if node.table != nil { - index := r.mapping[ByteToLower(s[0])] - if int(index) == r.tableSize { - break - } - node = node.table[index] - s = s[1:] - n++ - } else if node.prefix != "" && StringHasPrefixFold(s, node.prefix) { - n += len(node.prefix) - s = s[len(node.prefix):] - node = node.next - } else { - break - } - } - return -} - -// genericReplacer is the fully generic algorithm. -// It's used as a fallback when nothing faster can be used. -type genericReplacer struct { - root trieNode - // tableSize is the size of a trie node's lookup table. It is the number - // of unique key bytes. - tableSize int - // mapping maps from key bytes to a dense index for trieNode.table. - mapping [256]byte -} - -func makeGenericReplacer(oldnew []string) *genericReplacer { - r := new(genericReplacer) - // Find each byte used, then assign them each an index. - for i := 0; i < len(oldnew); i += 2 { - key := strings.ToLower(oldnew[i]) - for j := 0; j < len(key); j++ { - r.mapping[key[j]] = 1 - } - } - - for _, b := range r.mapping { - r.tableSize += int(b) - } - - var index byte - for i, b := range r.mapping { - if b == 0 { - r.mapping[i] = byte(r.tableSize) - } else { - r.mapping[i] = index - index++ - } - } - // Ensure root node uses a lookup table (for performance). - r.root.table = make([]*trieNode, r.tableSize) - - for i := 0; i < len(oldnew); i += 2 { - r.root.add(strings.ToLower(oldnew[i]), oldnew[i+1], len(oldnew)-i, r) - } - return r -} - -type appendSliceWriter []byte - -// Write writes to the buffer to satisfy io.Writer. -func (w *appendSliceWriter) Write(p []byte) (int, error) { - *w = append(*w, p...) - return len(p), nil -} - -// WriteString writes to the buffer without string->[]byte->string allocations. -func (w *appendSliceWriter) WriteString(s string) (int, error) { - *w = append(*w, s...) - return len(s), nil -} - -type stringWriterIface interface { - WriteString(string) (int, error) -} - -type stringWriter struct { - w io.Writer -} - -func (w stringWriter) WriteString(s string) (int, error) { - return w.w.Write([]byte(s)) -} - -func getStringWriter(w io.Writer) stringWriterIface { - sw, ok := w.(stringWriterIface) - if !ok { - sw = stringWriter{w} - } - return sw -} - -func (r *genericReplacer) Replace(s string) string { - buf := make(appendSliceWriter, 0, len(s)) - r.WriteString(&buf, s) - return string(buf) -} - -func (r *genericReplacer) WriteString(w io.Writer, s string) (n int, err error) { - sw := getStringWriter(w) - var last, wn int - var prevMatchEmpty bool - for i := 0; i <= len(s); { - // Fast path: s[i] is not a prefix of any pattern. - if i != len(s) && r.root.priority == 0 { - index := int(r.mapping[ByteToLower(s[i])]) - if index == r.tableSize || r.root.table[index] == nil { - i++ - continue - } - } - - // Ignore the empty match iff the previous loop found the empty match. - val, keylen, match := r.lookup(s[i:], prevMatchEmpty) - prevMatchEmpty = match && keylen == 0 - if match { - orig := s[i : i+keylen] - switch CaseStyle(orig) { - case CaseUnknown: - // pretend we didn't match - // i++ - // continue - case CaseUpper: - val = strings.ToUpper(val) - case CaseLower: - val = strings.ToLower(val) - case CaseTitle: - if len(val) < 2 { - val = strings.ToUpper(val) - } else { - val = strings.ToUpper(val[:1]) + strings.ToLower(val[1:]) - } - } - wn, err = sw.WriteString(s[last:i]) - n += wn - if err != nil { - return - } - //log.Printf("%d: Going to correct %q with %q", i, s[i:i+keylen], val) - wn, err = sw.WriteString(val) - n += wn - if err != nil { - return - } - i += keylen - last = i - continue - } - i++ - } - if last != len(s) { - wn, err = sw.WriteString(s[last:]) - n += wn - } - return -} diff --git a/vendor/github.com/client9/misspell/stringreplacer_test.gox b/vendor/github.com/client9/misspell/stringreplacer_test.gox deleted file mode 100644 index 70da997f6e..0000000000 --- a/vendor/github.com/client9/misspell/stringreplacer_test.gox +++ /dev/null @@ -1,421 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package misspell_test - -import ( - "bytes" - "fmt" - "strings" - "testing" - - . "github.com/client9/misspell" -) - -var htmlEscaper = NewStringReplacer( - "&", "&", - "<", "<", - ">", ">", - `"`, """, - "'", "'", -) - -var htmlUnescaper = NewStringReplacer( - "&", "&", - "<", "<", - ">", ">", - """, `"`, - "'", "'", -) - -// The http package's old HTML escaping function. -func oldHTMLEscape(s string) string { - s = strings.Replace(s, "&", "&", -1) - s = strings.Replace(s, "<", "<", -1) - s = strings.Replace(s, ">", ">", -1) - s = strings.Replace(s, `"`, """, -1) - s = strings.Replace(s, "'", "'", -1) - return s -} - -var capitalLetters = NewStringReplacer("a", "A", "b", "B") - -// TestReplacer tests the replacer implementations. -func TestReplacer(t *testing.T) { - type testCase struct { - r *StringReplacer - in, out string - } - var testCases []testCase - - // str converts 0xff to "\xff". This isn't just string(b) since that converts to UTF-8. - str := func(b byte) string { - return string([]byte{b}) - } - var s []string - - // inc maps "\x00"->"\x01", ..., "a"->"b", "b"->"c", ..., "\xff"->"\x00". - for i := 0; i < 256; i++ { - s = append(s, str(byte(i)), str(byte(i+1))) - } - inc := NewStringReplacer(s...) - - // Test cases with 1-byte old strings, 1-byte new strings. - testCases = append(testCases, - testCase{capitalLetters, "brad", "BrAd"}, - testCase{capitalLetters, strings.Repeat("a", (32<<10)+123), strings.Repeat("A", (32<<10)+123)}, - testCase{capitalLetters, "", ""}, - - testCase{inc, "brad", "csbe"}, - testCase{inc, "\x00\xff", "\x01\x00"}, - testCase{inc, "", ""}, - - testCase{NewStringReplacer("a", "1", "a", "2"), "brad", "br1d"}, - ) - - // repeat maps "a"->"a", "b"->"bb", "c"->"ccc", ... - s = nil - for i := 0; i < 256; i++ { - n := i + 1 - 'a' - if n < 1 { - n = 1 - } - s = append(s, str(byte(i)), strings.Repeat(str(byte(i)), n)) - } - repeat := NewStringReplacer(s...) - - // Test cases with 1-byte old strings, variable length new strings. - testCases = append(testCases, - testCase{htmlEscaper, "No changes", "No changes"}, - testCase{htmlEscaper, "I <3 escaping & stuff", "I <3 escaping & stuff"}, - testCase{htmlEscaper, "&&&", "&&&"}, - testCase{htmlEscaper, "", ""}, - - testCase{repeat, "brad", "bbrrrrrrrrrrrrrrrrrradddd"}, - testCase{repeat, "abba", "abbbba"}, - testCase{repeat, "", ""}, - - testCase{NewStringReplacer("a", "11", "a", "22"), "brad", "br11d"}, - ) - - // The remaining test cases have variable length old strings. - - testCases = append(testCases, - testCase{htmlUnescaper, "&amp;", "&"}, - testCase{htmlUnescaper, "<b>HTML's neat</b>", "HTML's neat"}, - testCase{htmlUnescaper, "", ""}, - - testCase{NewStringReplacer("a", "1", "a", "2", "xxx", "xxx"), "brad", "br1d"}, - - testCase{NewStringReplacer("a", "1", "aa", "2", "aaa", "3"), "aaaa", "1111"}, - - testCase{NewStringReplacer("aaa", "3", "aa", "2", "a", "1"), "aaaa", "31"}, - ) - - // gen1 has multiple old strings of variable length. There is no - // overall non-empty common prefix, but some pairwise common prefixes. - gen1 := NewStringReplacer( - "aaa", "3[aaa]", - "aa", "2[aa]", - "a", "1[a]", - "i", "i", - "longerst", "most long", - "longer", "medium", - "long", "short", - "xx", "xx", - "x", "X", - "X", "Y", - "Y", "Z", - ) - testCases = append(testCases, - testCase{gen1, "fooaaabar", "foo3[aaa]b1[a]r"}, - testCase{gen1, "long, longerst, longer", "short, most long, medium"}, - testCase{gen1, "xxxxx", "xxxxX"}, - testCase{gen1, "XiX", "YiY"}, - testCase{gen1, "", ""}, - ) - - // gen2 has multiple old strings with no pairwise common prefix. - gen2 := NewStringReplacer( - "roses", "red", - "violets", "blue", - "sugar", "sweet", - ) - testCases = append(testCases, - testCase{gen2, "roses are red, violets are blue...", "red are red, blue are blue..."}, - testCase{gen2, "", ""}, - ) - - // gen3 has multiple old strings with an overall common prefix. - gen3 := NewStringReplacer( - "abracadabra", "poof", - "abracadabrakazam", "splat", - "abraham", "lincoln", - "abrasion", "scrape", - "abraham", "isaac", - ) - testCases = append(testCases, - testCase{gen3, "abracadabrakazam abraham", "poofkazam lincoln"}, - testCase{gen3, "abrasion abracad", "scrape abracad"}, - testCase{gen3, "abba abram abrasive", "abba abram abrasive"}, - testCase{gen3, "", ""}, - ) - - // foo{1,2,3,4} have multiple old strings with an overall common prefix - // and 1- or 2- byte extensions from the common prefix. - foo1 := NewStringReplacer( - "foo1", "A", - "foo2", "B", - "foo3", "C", - ) - foo2 := NewStringReplacer( - "foo1", "A", - "foo2", "B", - "foo31", "C", - "foo32", "D", - ) - foo3 := NewStringReplacer( - "foo11", "A", - "foo12", "B", - "foo31", "C", - "foo32", "D", - ) - foo4 := NewStringReplacer( - "foo12", "B", - "foo32", "D", - ) - testCases = append(testCases, - testCase{foo1, "fofoofoo12foo32oo", "fofooA2C2oo"}, - testCase{foo1, "", ""}, - - testCase{foo2, "fofoofoo12foo32oo", "fofooA2Doo"}, - testCase{foo2, "", ""}, - - testCase{foo3, "fofoofoo12foo32oo", "fofooBDoo"}, - testCase{foo3, "", ""}, - - testCase{foo4, "fofoofoo12foo32oo", "fofooBDoo"}, - testCase{foo4, "", ""}, - ) - - // genAll maps "\x00\x01\x02...\xfe\xff" to "[all]", amongst other things. - allBytes := make([]byte, 256) - for i := range allBytes { - allBytes[i] = byte(i) - } - allString := string(allBytes) - genAll := NewStringReplacer( - allString, "[all]", - "\xff", "[ff]", - "\x00", "[00]", - ) - testCases = append(testCases, - testCase{genAll, allString, "[all]"}, - testCase{genAll, "a\xff" + allString + "\x00", "a[ff][all][00]"}, - testCase{genAll, "", ""}, - ) - - // Test cases with empty old strings. - - blankToX1 := NewStringReplacer("", "X") - blankToX2 := NewStringReplacer("", "X", "", "") - blankHighPriority := NewStringReplacer("", "X", "o", "O") - blankLowPriority := NewStringReplacer("o", "O", "", "X") - blankNoOp1 := NewStringReplacer("", "") - blankNoOp2 := NewStringReplacer("", "", "", "A") - blankFoo := NewStringReplacer("", "X", "foobar", "R", "foobaz", "Z") - testCases = append(testCases, - testCase{blankToX1, "foo", "XfXoXoX"}, - testCase{blankToX1, "", "X"}, - - testCase{blankToX2, "foo", "XfXoXoX"}, - testCase{blankToX2, "", "X"}, - - testCase{blankHighPriority, "oo", "XOXOX"}, - testCase{blankHighPriority, "ii", "XiXiX"}, - testCase{blankHighPriority, "oiio", "XOXiXiXOX"}, - testCase{blankHighPriority, "iooi", "XiXOXOXiX"}, - testCase{blankHighPriority, "", "X"}, - - testCase{blankLowPriority, "oo", "OOX"}, - testCase{blankLowPriority, "ii", "XiXiX"}, - testCase{blankLowPriority, "oiio", "OXiXiOX"}, - testCase{blankLowPriority, "iooi", "XiOOXiX"}, - testCase{blankLowPriority, "", "X"}, - - testCase{blankNoOp1, "foo", "foo"}, - testCase{blankNoOp1, "", ""}, - - testCase{blankNoOp2, "foo", "foo"}, - testCase{blankNoOp2, "", ""}, - - testCase{blankFoo, "foobarfoobaz", "XRXZX"}, - testCase{blankFoo, "foobar-foobaz", "XRX-XZX"}, - testCase{blankFoo, "", "X"}, - ) - - // single string replacer - - abcMatcher := NewStringReplacer("abc", "[match]") - - testCases = append(testCases, - testCase{abcMatcher, "", ""}, - testCase{abcMatcher, "ab", "ab"}, - testCase{abcMatcher, "abc", "[match]"}, - testCase{abcMatcher, "abcd", "[match]d"}, - testCase{abcMatcher, "cabcabcdabca", "c[match][match]d[match]a"}, - ) - - // Issue 6659 cases (more single string replacer) - - noHello := NewStringReplacer("Hello", "") - testCases = append(testCases, - testCase{noHello, "Hello", ""}, - testCase{noHello, "Hellox", "x"}, - testCase{noHello, "xHello", "x"}, - testCase{noHello, "xHellox", "xx"}, - ) - - // No-arg test cases. - - nop := NewStringReplacer() - testCases = append(testCases, - testCase{nop, "abc", "abc"}, - testCase{nop, "", ""}, - ) - - // Run the test cases. - - for i, tc := range testCases { - if s := tc.r.Replace(tc.in); s != tc.out { - t.Errorf("%d. strings.Replace(%q) = %q, want %q", i, tc.in, s, tc.out) - } - var buf bytes.Buffer - n, err := tc.r.WriteString(&buf, tc.in) - if err != nil { - t.Errorf("%d. WriteString: %v", i, err) - continue - } - got := buf.String() - if got != tc.out { - t.Errorf("%d. WriteString(%q) wrote %q, want %q", i, tc.in, got, tc.out) - continue - } - if n != len(tc.out) { - t.Errorf("%d. WriteString(%q) wrote correct string but reported %d bytes; want %d (%q)", - i, tc.in, n, len(tc.out), tc.out) - } - } -} - -type errWriter struct{} - -func (errWriter) Write(p []byte) (n int, err error) { - return 0, fmt.Errorf("unwritable") -} - -func BenchmarkGenericNoMatch(b *testing.B) { - str := strings.Repeat("A", 100) + strings.Repeat("B", 100) - generic := NewStringReplacer("a", "A", "b", "B", "12", "123") // varying lengths forces generic - for i := 0; i < b.N; i++ { - generic.Replace(str) - } -} - -func BenchmarkGenericMatch1(b *testing.B) { - str := strings.Repeat("a", 100) + strings.Repeat("b", 100) - generic := NewStringReplacer("a", "A", "b", "B", "12", "123") - for i := 0; i < b.N; i++ { - generic.Replace(str) - } -} - -func BenchmarkGenericMatch2(b *testing.B) { - str := strings.Repeat("It's <b>HTML</b>!", 100) - for i := 0; i < b.N; i++ { - htmlUnescaper.Replace(str) - } -} - -func benchmarkSingleString(b *testing.B, pattern, text string) { - r := NewStringReplacer(pattern, "[match]") - b.SetBytes(int64(len(text))) - b.ResetTimer() - for i := 0; i < b.N; i++ { - r.Replace(text) - } -} - -func BenchmarkSingleMaxSkipping(b *testing.B) { - benchmarkSingleString(b, strings.Repeat("b", 25), strings.Repeat("a", 10000)) -} - -func BenchmarkSingleLongSuffixFail(b *testing.B) { - benchmarkSingleString(b, "b"+strings.Repeat("a", 500), strings.Repeat("a", 1002)) -} - -func BenchmarkSingleMatch(b *testing.B) { - benchmarkSingleString(b, "abcdef", strings.Repeat("abcdefghijklmno", 1000)) -} - -func BenchmarkByteByteNoMatch(b *testing.B) { - str := strings.Repeat("A", 100) + strings.Repeat("B", 100) - for i := 0; i < b.N; i++ { - capitalLetters.Replace(str) - } -} - -func BenchmarkByteByteMatch(b *testing.B) { - str := strings.Repeat("a", 100) + strings.Repeat("b", 100) - for i := 0; i < b.N; i++ { - capitalLetters.Replace(str) - } -} - -func BenchmarkByteStringMatch(b *testing.B) { - str := "<" + strings.Repeat("a", 99) + strings.Repeat("b", 99) + ">" - for i := 0; i < b.N; i++ { - htmlEscaper.Replace(str) - } -} - -func BenchmarkHTMLEscapeNew(b *testing.B) { - str := "I <3 to escape HTML & other text too." - for i := 0; i < b.N; i++ { - htmlEscaper.Replace(str) - } -} - -func BenchmarkHTMLEscapeOld(b *testing.B) { - str := "I <3 to escape HTML & other text too." - for i := 0; i < b.N; i++ { - oldHTMLEscape(str) - } -} - -func BenchmarkByteStringReplacerWriteString(b *testing.B) { - str := strings.Repeat("I <3 to escape HTML & other text too.", 100) - buf := new(bytes.Buffer) - for i := 0; i < b.N; i++ { - htmlEscaper.WriteString(buf, str) - buf.Reset() - } -} - -func BenchmarkByteReplacerWriteString(b *testing.B) { - str := strings.Repeat("abcdefghijklmnopqrstuvwxyz", 100) - buf := new(bytes.Buffer) - for i := 0; i < b.N; i++ { - capitalLetters.WriteString(buf, str) - buf.Reset() - } -} - -// BenchmarkByteByteReplaces compares byteByteImpl against multiple Replaces. -func BenchmarkByteByteReplaces(b *testing.B) { - str := strings.Repeat("a", 100) + strings.Repeat("b", 100) - for i := 0; i < b.N; i++ { - strings.Replace(strings.Replace(str, "a", "A", -1), "b", "B", -1) - } -} diff --git a/vendor/github.com/client9/misspell/url.go b/vendor/github.com/client9/misspell/url.go deleted file mode 100644 index 1a259f5f99..0000000000 --- a/vendor/github.com/client9/misspell/url.go +++ /dev/null @@ -1,17 +0,0 @@ -package misspell - -import ( - "regexp" -) - -// Regexp for URL https://mathiasbynens.be/demo/url-regex -// -// original @imme_emosol (54 chars) has trouble with dashes in hostname -// @(https?|ftp)://(-\.)?([^\s/?\.#-]+\.?)+(/[^\s]*)?$@iS -var reURL = regexp.MustCompile(`(?i)(https?|ftp)://(-\.)?([^\s/?\.#]+\.?)+(/[^\s]*)?`) - -// StripURL attemps to replace URLs with blank spaces, e.g. -// "xxx http://foo.com/ yyy -> "xxx yyyy" -func StripURL(s string) string { - return reURL.ReplaceAllStringFunc(s, replaceWithBlanks) -} diff --git a/vendor/github.com/client9/misspell/words.go b/vendor/github.com/client9/misspell/words.go deleted file mode 100644 index c92dd19d04..0000000000 --- a/vendor/github.com/client9/misspell/words.go +++ /dev/null @@ -1,31158 +0,0 @@ -package misspell - -// Code generated automatically. DO NOT EDIT. - -// DictMain is the main rule set, not including locale-specific spellings -var DictMain = []string{ - "differentiatiations", "differentiations", - "disproportionaltely", "disproportionately", - "oversimplificiation", "oversimplification", - "transcendentational", "transcendental", - "anthromorphization", "anthropomorphization", - "disporportionately", "disproportionately", - "dispraportionately", "disproportionately", - "disproportianately", "disproportionately", - "disproportionatley", "disproportionately", - "disproprotionately", "disproportionately", - "fundamentalistisch", "fundamentalists", - "fundamentalistiska", "fundamentalists", - "fundamentalistiske", "fundamentalists", - "fundamentalistiskt", "fundamentalists", - "histocompatability", "histocompatibility", - "microtransacations", "microtransactions", - "microtransacciones", "microtransactions", - "microtransactional", "microtransactions", - "microtransactioned", "microtransactions", - "misunderstandingly", "misunderstandings", - "oversemplification", "oversimplification", - "oversimplifacation", "oversimplification", - "oversimplificaiton", "oversimplification", - "oversimplificating", "oversimplification", - "oversimplyfication", "oversimplification", - "cardiovasculaires", "cardiovascular", - "certificationkits", "certifications", - "counterporductive", "counterproductive", - "coutnerproductive", "counterproductive", - "disporportionatly", "disproportionately", - "disproportiantely", "disproportionately", - "disproportionatly", "disproportionately", - "disproportionnate", "disproportionate", - "disrepresentation", "misrepresentation", - "fundamentalistisk", "fundamentalists", - "incompatabilities", "incompatibilities", - "inconsequentional", "inconsequential", - "indistinguishible", "indistinguishable", - "indistingusihable", "indistinguishable", - "indistinquishable", "indistinguishable", - "indistuingishable", "indistinguishable", - "instatutionalized", "institutionalized", - "institucionalized", "institutionalized", - "institutionilized", "institutionalized", - "instutitionalized", "institutionalized", - "instututionalized", "institutionalized", - "interchangeablely", "interchangeably", - "interchangeablity", "interchangeably", - "intercontinential", "intercontinental", - "micortransactions", "microtransactions", - "microstansactions", "microtransactions", - "microtramsactions", "microtransactions", - "microtranasctions", "microtransactions", - "microtransacitons", "microtransactions", - "microtransacrions", "microtransactions", - "microtransactioms", "microtransactions", - "microtransactiosn", "microtransactions", - "microtranscations", "microtransactions", - "microtrasnactions", "microtransactions", - "mircotransactions", "microtransactions", - "misinterpretating", "misinterpreting", - "misrepresantation", "misrepresentation", - "misrepresentaiton", "misrepresentation", - "misrepresentating", "misrepresenting", - "misunderstantings", "misunderstandings", - "mocrotransactions", "microtransactions", - "oversimplifaction", "oversimplification", - "oversimplificaton", "oversimplification", - "oversimplifiction", "oversimplification", - "responsibillities", "responsibilities", - "unconstitutionnal", "unconstitutional", - "accomplishements", "accomplishments", - "admininistrative", "administrative", - "antidepresssants", "antidepressants", - "architechturally", "architecturally", - "cardiovasculaire", "cardiovascular", - "charactarization", "characterization", - "characterazation", "characterization", - "characterisitics", "characteristics", - "characteristsics", "characteristic", - "characterizarion", "characterization", - "charecterization", "characterization", - "charicterization", "characterization", - "circumstantional", "circumstantial", - "conversationable", "conversational", - "counterprodutive", "counterproductive", - "demonstrationens", "demonstrations", - "deterministische", "deterministic", - "differenciations", "differentiation", - "differentiantion", "differentiation", - "differentiatiors", "differentiation", - "differentitation", "differentiation", - "disperportionate", "disproportionate", - "disporportionate", "disproportionate", - "dispraportionate", "disproportionate", - "disproportianate", "disproportionate", - "disproportionaly", "disproportionately", - "disproprotionate", "disproportionate", - "electromagnectic", "electromagnetic", - "enviornmentalist", "environmentalist", - "environmentality", "environmentally", - "extraordinairily", "extraordinarily", - "extraordinarilly", "extraordinary", - "extraterrestials", "extraterrestrials", - "fundamentalismos", "fundamentalists", - "fundamentalismus", "fundamentalists", - "fundamentalistas", "fundamentalists", - "fundamentalisten", "fundamentalists", - "fundamentalister", "fundamentalists", - "imcomprehensible", "incomprehensible", - "immunosupressant", "immunosuppressant", - "imperfectionists", "imperfections", - "implementaciones", "implementations", - "implementationen", "implementations", - "implementationer", "implementations", - "inappropriatelly", "inappropriately", - "incompatablities", "incompatibilities", - "incompatiblities", "incompatibilities", - "incomprehencible", "incomprehensible", - "incomprehendible", "incomprehensible", - "incomprehenisble", "incomprehensible", - "incomprehensable", "incomprehensible", - "incomprehinsible", "incomprehensible", - "incomprihensible", "incomprehensible", - "inconprehensible", "incomprehensible", - "inconsistentcies", "inconsistencies", - "inconstitutional", "unconstitutional", - "incrompehensible", "incomprehensible", - "indistinguisable", "indistinguishable", - "institutionlized", "institutionalized", - "intellectualiser", "intellectuals", - "intellectualisme", "intellectuals", - "interchangeabley", "interchangeably", - "internationnally", "internationally", - "interpretaciones", "interpretations", - "interpretationen", "interpretations", - "manoeuverability", "maneuverability", - "massachusettians", "massachusetts", - "microtransacions", "microtransactions", - "microtransacting", "microtransactions", - "microtransactios", "microtransactions", - "microtransactons", "microtransactions", - "microtransations", "microtransactions", - "microtranscation", "microtransactions", - "mircotransaction", "microtransactions", - "miscommunciation", "miscommunication", - "miscommunicaiton", "miscommunication", - "miscomunnication", "miscommunication", - "miscummunication", "miscommunication", - "misinterpretated", "misinterpreted", - "misinterpretions", "misinterpreting", - "misinterpretting", "misinterpreting", - "misproportionate", "disproportionate", - "misrepresenation", "misrepresentation", - "misrepresentaion", "misrepresentation", - "misrepresentated", "misrepresented", - "misrepresentatie", "misrepresentation", - "misrepresentativ", "misrepresentation", - "misubderstanding", "misunderstandings", - "misudnerstanding", "misunderstandings", - "misundarstanding", "misunderstandings", - "misunderatanding", "misunderstandings", - "misunderdtanding", "misunderstandings", - "misundersatnding", "misunderstandings", - "misundersranding", "misunderstandings", - "misunderstadings", "misunderstandings", - "misunderstadning", "misunderstandings", - "misunderstamding", "misunderstandings", - "misunderstandigs", "misunderstandings", - "misunderstandimg", "misunderstandings", - "misunderstandind", "misunderstandings", - "misunderstanging", "misunderstandings", - "misunderstanidng", "misunderstandings", - "misunderstanings", "misunderstandings", - "misunderstansing", "misunderstandings", - "misunderstanting", "misunderstandings", - "misunderstending", "misunderstandings", - "misunderstnading", "misunderstandings", - "misunderstsnding", "misunderstandings", - "misunderstunding", "misunderstandings", - "misundertsanding", "misunderstandings", - "misundrestanding", "misunderstandings", - "misunterstanding", "misunderstandings", - "nationalistische", "nationalistic", - "nationalististic", "nationalistic", - "neconstitutional", "unconstitutional", - "notwhithstanding", "notwithstanding", - "objectificiation", "objectification", - "organisationnels", "organisations", - "perpendiculaires", "perpendicular", - "phillosophically", "philosophically", - "preinitalization", "preinitialization", - "prescriptionists", "prescriptions", - "procrastinarting", "procrastinating", - "procrastinationg", "procrastinating", - "procrastinazione", "procrastination", - "professionalisim", "professionalism", - "professionalisme", "professionals", - "professionallism", "professionalism", - "professionnalism", "professionalism", - "programattically", "programmatically", - "proportionallity", "proportionally", - "reaponsibilities", "responsibilities", - "reinitalizations", "reinitializations", - "representaciones", "representations", - "representationen", "representations", - "representationer", "representations", - "repsonsibilities", "responsibilities", - "responcibilities", "responsibilities", - "responisbilities", "responsibilities", - "responsabilities", "responsibilities", - "responsebilities", "responsibilities", - "straightforeward", "straightforward", - "surrepetitiously", "surreptitiously", - "technologicially", "technologically", - "unconditionnally", "unconditionally", - "unconfortability", "discomfort", - "unconstititional", "unconstitutional", - "uncontrollablely", "uncontrollably", - "underestimateing", "underestimating", - "understandablely", "understandably", - "unintentionnally", "unintentionally", - "unsubstantianted", "unsubstantiated", - "unsubstantiative", "unsubstantiated", - "acclimitization", "acclimatization", - "accomplishemnts", "accomplishments", - "accountabillity", "accountability", - "acknolwedgement", "acknowledgement", - "acknoweldgement", "acknowledgement", - "acknowldegement", "acknowledgement", - "acknowlegdement", "acknowledgement", - "administratieve", "administrative", - "administratiors", "administrators", - "administrativne", "administrative", - "aforementionned", "aforementioned", - "anitdepressants", "antidepressants", - "antidepressents", "antidepressants", - "archetecturally", "architecturally", - "associationthis", "associations", - "authobiographic", "autobiographic", - "awknowledgement", "acknowledgement", - "bureaucratische", "bureaucratic", - "cardiovascualar", "cardiovascular", - "carnagie-mellon", "carnegie-mellon", - "carnigie-mellon", "carnegie-mellon", - "celebrationists", "celebrations", - "charactaristics", "characteristics", - "characterisitcs", "characteristics", - "characterisitic", "characteristic", - "characterizaton", "characterization", - "charactersistic", "characteristic", - "charactersitics", "characteristics", - "charactoristics", "characteristics", - "charecteristics", "characteristics", - "comfrontational", "confrontational", - "commuinications", "communications", - "compatabilities", "compatibilities", - "complimentarity", "complimentary", - "compositionwise", "compositions", - "confidenciality", "confidential", - "confidentuality", "confidential", - "confrentational", "confrontational", - "confrontacional", "confrontational", - "conglaturations", "congratulations", - "congradulations", "congratulations", - "congragulations", "congratulations", - "congratualtions", "congratulations", - "congraturations", "congratulations", - "consequentually", "consequently", - "constitutionnal", "constitutional", - "deinitalization", "deinitialization", - "denominationals", "denominations", - "destinationhash", "destinations", - "deterministisch", "deterministic", - "developmentwise", "developments", - "differantiation", "differentiation", - "differenciation", "differentiation", - "differientation", "differentiation", - "discriminatoire", "discriminate", - "discriminatorie", "discriminate", - "disproportiante", "disproportionate", - "disproportinate", "disproportionate", - "elecrtomagnetic", "electromagnetic", - "electormagnetic", "electromagnetic", - "electromagentic", "electromagnetic", - "electromagnatic", "electromagnetic", - "electromangetic", "electromagnetic", - "electromegnetic", "electromagnetic", - "electronagnetic", "electromagnetic", - "enivronmentally", "environmentally", - "entrepreneurers", "entrepreneurs", - "enviornmentally", "environmentally", - "enviromentalist", "environmentalist", - "environemntally", "environmentally", - "envrionmentally", "environmentally", - "evolutionarilly", "evolutionary", - "experementation", "experimentation", - "experimantation", "experimentation", - "experimentacion", "experimentation", - "experimentating", "experimentation", - "experimenterade", "experimented", - "experimintation", "experimentation", - "expirementation", "experimentation", - "extraodrinarily", "extraordinarily", - "extraordinairly", "extraordinarily", - "extraordinarely", "extraordinarily", - "extraordinaryly", "extraordinarily", - "extraterrestial", "extraterrestrial", - "extroardinarily", "extraordinarily", - "fondamentalists", "fundamentalists", - "fundamendalists", "fundamentalists", - "fundamentalisme", "fundamentals", - "fundamentalismo", "fundamentals", - "fundamentalista", "fundamentals", - "fundamentalisti", "fundamentals", - "fundamnetalists", "fundamentalists", - "fundemantalists", "fundamentalists", - "fundimentalists", "fundamentalists", - "fundumentalists", "fundamentalists", - "gongratulations", "congratulations", - "grammaticallity", "grammatically", - "gundamentalists", "fundamentalists", - "idiosynchracies", "idiosyncrasies", - "implementaitons", "implementations", - "implimentations", "implementations", - "inapporpriately", "inappropriately", - "inappropraitely", "inappropriately", - "inappropriatley", "inappropriately", - "incompatability", "incompatibility", - "incompetentence", "incompetence", - "incomprehensibe", "incomprehensible", - "incomprehesible", "incomprehensible", - "inconcequential", "inconsequential", - "inconcistencies", "inconsistencies", - "inconditionally", "unconditionally", - "inconsecuential", "inconsequential", - "inconsequantial", "inconsequential", - "inconsequencial", "inconsequential", - "inconsequentual", "inconsequential", - "inconsiquential", "inconsequential", - "inconsistancies", "inconsistencies", - "inconsistencias", "inconsistencies", - "inconsistensies", "inconsistencies", - "inconsistenties", "inconsistencies", - "independentisme", "independents", - "independentiste", "independents", - "independentness", "independents", - "inexperiencable", "inexperience", - "inplementations", "implementations", - "instantaneoulsy", "instantaneous", - "institutionella", "institutional", - "institutionnels", "institutions", - "instutionalized", "institutionalized", - "insubstantiated", "unsubstantiated", - "interchangabley", "interchangeably", - "interchangebale", "interchangeable", - "intercontinetal", "intercontinental", - "interpertations", "interpretations", - "interpratations", "interpretations", - "interpritations", "interpretations", - "intersectionals", "intersections", - "intrepretations", "interpretations", - "investigationes", "investigations", - "journalistische", "journalistic", - "libertarianisim", "libertarianism", - "libertarianisme", "libertarians", - "libertarianismo", "libertarians", - "libertarianists", "libertarians", - "libertariansism", "libertarianism", - "manisfestations", "manifestations", - "manouverability", "maneuverability", - "manufacturerers", "manufacturers", - "marshmallowiest", "marshmallows", - "marshmallowness", "marshmallows", - "microtransacton", "microtransactions", - "mininterpreting", "misinterpreting", - "miscommuniation", "miscommunication", - "miscommunicatie", "miscommunication", - "miscommuniction", "miscommunication", - "misinterperting", "misinterpreting", - "misinterprating", "misinterpreting", - "misinterprented", "misinterpret", - "misinterprested", "misinterpret", - "misinterpretion", "misinterpreting", - "misinterpretted", "misinterpreted", - "misinterpriting", "misinterpreting", - "misintrepreting", "misinterpreting", - "misrepresention", "misrepresenting", - "misunderstading", "misunderstanding", - "misunderstandig", "misunderstandings", - "misunderstandng", "misunderstandings", - "misunderstaning", "misunderstanding", - "multicultralism", "multiculturalism", - "multinationella", "multinational", - "nationalistisch", "nationalists", - "nationalistisen", "nationalists", - "nationalistiska", "nationalists", - "nationalistiske", "nationalists", - "nationalistiskt", "nationalists", - "nationalistista", "nationalists", - "objectificaiton", "objectification", - "objectivication", "objectification", - "organisationens", "organisations", - "organisationers", "organisations", - "overestimateing", "overestimating", - "paychologically", "psychologically", - "performancetest", "performances", - "performancewise", "performances", - "perpendiculaire", "perpendicular", - "pharamceuticals", "pharmaceutical", - "pharmacueticals", "pharmaceutical", - "philoshopically", "philosophically", - "philosohpically", "philosophically", - "philosophycally", "philosophically", - "phsycologically", "psychologically", - "phychologically", "psychologically", - "phylosophically", "philosophically", - "physcologically", "psychologically", - "precrastination", "procrastination", - "prefessionalism", "professionalism", - "premonasterians", "premonstratensians", - "procastrinating", "procrastinating", - "procastrination", "procrastination", - "procrascinating", "procrastinating", - "procrastenating", "procrastinating", - "procrastiantion", "procrastination", - "procrastibating", "procrastinating", - "procrastibation", "procrastination", - "procrastonating", "procrastinating", - "procrestinating", "procrastinating", - "procrestination", "procrastination", - "professionalsim", "professionalism", - "prograstination", "procrastination", - "progressionists", "progressions", - "progressionwise", "progressions", - "prokrastination", "procrastination", - "proportionallly", "proportionally", - "proscratination", "procrastination", - "pscyhologically", "psychologically", - "pshycologically", "psychologically", - "psichologically", "psychologically", - "psychedelicious", "psychedelics", - "psychedelicness", "psychedelics", - "psycholigically", "psychologically", - "psychopathische", "psychopathic", - "pyschologically", "psychologically", - "racionalization", "rationalization", - "rationalizaiton", "rationalization", - "rationalizating", "rationalization", - "reccomendations", "recommendations", - "recommandations", "recommendations", - "recommondations", "recommendations", - "reinitalization", "reinitialization", - "repersentations", "representations", - "represantations", "representations", - "represantatives", "representatives", - "representatieve", "representative", - "representativas", "representatives", - "representetives", "representatives", - "representitives", "representatives", - "responibilities", "responsibilities", - "responsibilites", "responsibilities", - "responsibilitys", "responsibilities", - "responsibillity", "responsibility", - "responsibilties", "responsibilities", - "responsiblities", "responsibilities", - "ridiculoussness", "ridiculousness", - "saskatchewinian", "saskatchewan", - "satisfactorally", "satisfactory", - "satisfactorilly", "satisfactory", - "schizophreniiic", "schizophrenic", - "sensationalisim", "sensationalism", - "spreadsheeticus", "spreadsheets", - "starightforward", "straightforward", - "straigthforward", "straightforward", - "striaghtforward", "straightforward", - "sustainabillity", "sustainability", - "technoligically", "technologically", - "troubelshooting", "troubleshooting", - "troublehsooting", "troubleshooting", - "troubleshotting", "troubleshooting", - "trustworthyness", "trustworthiness", - "ubsubstantiated", "unsubstantiated", - "unappropriately", "inappropriately", - "uncomfortablely", "uncomfortably", - "uncomfortablity", "uncomfortably", - "unconditionable", "unconditional", - "unconstituional", "unconstitutional", - "uncontitutional", "unconstitutional", - "uncontrollabley", "uncontrollably", - "uncontrollablly", "uncontrollably", - "unconventionnal", "unconventional", - "underastimating", "underestimating", - "underestemating", "underestimating", - "understandabley", "understandably", - "unintensionally", "unintentionally", - "unprofessionnal", "unprofessional", - "unresponsivness", "unresponsive", - "unsibstantiated", "unsubstantiated", - "unsubstanciated", "unsubstantiated", - "unsubstansiated", "unsubstantiated", - "unsusbtantiated", "unsubstantiated", - "untranslateable", "untranslatable", - "vulernabilities", "vulnerabilities", - "vulnarabilities", "vulnerabilities", - "vulnurabilities", "vulnerabilities", - "vunlerabilities", "vulnerabilities", - "vurnerabilities", "vulnerabilities", - "accomplishemnt", "accomplishment", - "accomplishents", "accomplishes", - "acconplishment", "accomplishment", - "acknowledgeing", "acknowledging", - "acknowledgemnt", "acknowledgement", - "acomplishments", "accomplishments", - "administartion", "administration", - "administartors", "administrators", - "administraters", "administrators", - "administratief", "administrative", - "administratiei", "administrative", - "administratior", "administrator", - "administrativo", "administration", - "adminsitration", "administration", - "adminsitrative", "administrative", - "adminsitrators", "administrators", - "affectionatley", "affectionate", - "aforememtioned", "aforementioned", - "aforementioend", "aforementioned", - "alternativelly", "alternatively", - "amministrative", "administrative", - "anitdepressant", "antidepressants", - "approproximate", "approximate", - "approximatelly", "approximately", - "archeaologists", "archeologists", - "architechtures", "architectures", - "architectureal", "architectural", - "architecturial", "architectural", - "assassintation", "assassination", - "authenitcation", "authentication", - "authenticaiton", "authentication", - "authobiography", "autobiography", - "breakthroughts", "breakthroughs", - "bureaucratisch", "bureaucratic", - "calssification", "classification", - "capatilization", "capitalization", - "capitalizacion", "capitalization", - "capitalizaiton", "capitalization", - "capitalizating", "capitalization", - "capitilazation", "capitalization", - "capitolization", "capitalization", - "captialization", "capitalization", - "cardiocascular", "cardiovascular", - "cardiovascualr", "cardiovascular", - "cardiovasuclar", "cardiovascular", - "caridovascular", "cardiovascular", - "cessationalism", "sensationalism", - "cessationalist", "sensationalist", - "charactaristic", "characteristic", - "characterisics", "characteristics", - "characterisitc", "characteristics", - "characteristcs", "characteristics", - "characteritics", "characteristic", - "charactersitic", "characteristics", - "charasteristic", "characteristics", - "charecteristic", "characteristic", - "cheeseburguers", "cheeseburgers", - "cinematagraphy", "cinematography", - "cinematagrophy", "cinematography", - "cinematograhpy", "cinematography", - "cinematogrophy", "cinematography", - "cinematogrpahy", "cinematography", - "cinemetography", "cinematography", - "cinimatography", "cinematography", - "circumstansial", "circumstantial", - "circumstantual", "circumstantial", - "circumstential", "circumstantial", - "circunstantial", "circumstantial", - "classificaiton", "classification", - "coincedentally", "coincidentally", - "coinsidentally", "coincidentally", - "commemmorating", "commemorating", - "communciations", "communications", - "compatablities", "compatibilities", - "compatibillity", "compatibility", - "compatiblities", "compatibilities", - "competitioners", "competitions", - "comphrehensive", "comprehensive", - "computationnal", "computational", - "conciderations", "considerations", - "condescenscion", "condescension", - "condradictions", "contradictions", - "configuartions", "configurations", - "confugurations", "configurations", - "conglaturation", "congratulations", - "congratulatons", "congratulations", - "conicidentally", "coincidentally", - "conifgurations", "configurations", - "conscioussness", "consciousness", - "consentrations", "concentrations", - "consiciousness", "consciousness", - "considerablely", "considerably", - "considerstions", "considerations", - "constititional", "constitutional", - "constitucional", "constitutional", - "contamporaries", "contemporaries", - "contemporaneus", "contemporaneous", - "contraceptivos", "contraceptives", - "contradicitons", "contradictions", - "contradictiong", "contradicting", - "contriceptives", "contraceptives", - "controceptives", "contraceptives", - "controdictions", "contradictions", - "conversacional", "conversational", - "converstaional", "conversational", - "correpsondence", "correspondence", - "correspondants", "correspondents", - "correspondense", "correspondence", - "correspondente", "correspondence", - "corrispondants", "correspondents", - "corrispondence", "correspondence", - "corrospondence", "correspondence", - "costumizations", "customization", - "councidentally", "coincidentally", - "crystalisation", "crystallisation", - "curcumstantial", "circumstantial", - "demenstrations", "demonstrations", - "deminstrations", "demonstrations", - "demonstartions", "demonstrations", - "demonstrativno", "demonstrations", - "demonstrativos", "demonstrations", - "demosntrations", "demonstrations", - "desintegration", "disintegration", - "deterioriating", "deteriorating", - "determinisitic", "deterministic", - "differentiaton", "differentiation", - "disatisfaction", "dissatisfaction", - "discrimanatory", "discriminatory", - "discriminacion", "discrimination", - "discriminitory", "discriminatory", - "disillusionned", "disillusioned", - "diskrimination", "discrimination", - "disproportiate", "disproportionate", - "distingiushing", "distinguishing", - "distingquished", "distinguished", - "distingusihing", "distinguishing", - "distinquishing", "distinguishing", - "distuingishing", "distinguishing", - "dysfunctionnal", "dysfunctional", - "eldistribution", "redistribution", - "electromagnetc", "electromagnetic", - "electromagntic", "electromagnetic", - "endoctrination", "indoctrination", - "enthusiastisch", "enthusiastic", - "entrepreneuers", "entrepreneurs", - "entrepreneures", "entrepreneurs", - "enviormentally", "environmentally", - "enviromentally", "environmentally", - "environmentals", "environments", - "environmentaly", "environmentally", - "experimentaion", "experimentation", - "experimentella", "experimental", - "extraordinairy", "extraordinary", - "extraordinarly", "extraordinary", - "extrordinarily", "extraordinarily", - "fondamentalist", "fundamentalist", - "foreshadowning", "foreshadowing", - "functionallity", "functionality", - "fundamendalist", "fundamentalist", - "fundamentalits", "fundamentalists", - "fundamnetalist", "fundamentalist", - "fundemantalist", "fundamentalist", - "fundimentalist", "fundamentalist", - "fundumentalist", "fundamentalist", - "generalizacion", "generalization", - "generalizating", "generalization", - "generelization", "generalization", - "geographacilly", "geographically", - "geographycally", "geographically", - "geogrpahically", "geographically", - "geopraphically", "geographically", - "goegraphically", "geographically", - "grandchilderen", "grandchildren", - "gravitationnal", "gravitational", - "groubdbreaking", "groundbreaking", - "groudnbreaking", "groundbreaking", - "hallcuinations", "hallucination", - "hallicunations", "hallucinations", - "hallucenations", "hallucinations", - "halluciantions", "hallucinations", - "hallucinaitons", "hallucination", - "hallunications", "hallucinations", - "hallusinations", "hallucinations", - "halluzinations", "hallucinations", - "hellucinations", "hallucinations", - "heterosexuella", "heterosexual", - "hipothetically", "hypothetically", - "homosexuallity", "homosexuality", - "hullucinations", "hallucinations", - "hyopthetically", "hypothetically", - "hypathetically", "hypothetically", - "hypethetically", "hypothetically", - "hypotehtically", "hypothetically", - "hypotethically", "hypothetically", - "identificacion", "identification", - "identificaiton", "identification", - "identificativo", "identification", - "identifikation", "identification", - "imlpementation", "implementations", - "impelmentation", "implementations", - "impersonationg", "impersonating", - "implementacion", "implementation", - "implementaiton", "implementation", - "implementating", "implementation", - "implementatino", "implementations", - "implemetnation", "implementations", - "implimentation", "implementation", - "impossibillity", "impossibility", - "inadvertantely", "inadvertently", - "inappropriatly", "inappropriately", - "inapproprietly", "inappropriately", - "incompatablity", "incompatibility", - "incompatiblity", "incompatibility", - "inconsequental", "inconsequential", - "inconsistentcy", "inconsistency", - "incontrollably", "uncontrollably", - "inconventional", "unconventional", - "inconvienenced", "inconvenience", - "indestrictible", "indestructible", - "indestructuble", "indestructible", - "indetification", "identification", - "indistructible", "indestructible", - "individuallity", "individuality", - "indocrtination", "indoctrination", - "indoctrication", "indoctrination", - "indoktrination", "indoctrination", - "industiralized", "industrialized", - "industrailized", "industrialized", - "industrualized", "industrialized", - "industructible", "indestructible", - "inexplicablely", "inexplicably", - "infrastracture", "infrastructure", - "infrastructuur", "infrastructure", - "infrastrucutre", "infrastructure", - "infrastrukture", "infrastructure", - "infrastrutture", "infrastructure", - "infrasturcture", "infrastructure", - "initalisations", "initialisations", - "initalizations", "initializations", - "inplementation", "implementation", - "inspirationnal", "inspirational", - "instinctivelly", "instinctively", - "institutionale", "institutionalized", - "institutionals", "institutions", - "institutionnal", "institutional", - "intellectualis", "intellectuals", - "intellectualls", "intellectuals", - "intellecutally", "intellectually", - "intercepticons", "interceptions", - "interchangable", "interchangeable", - "interchangably", "interchangeably", - "interchangeble", "interchangeable", - "interchangebly", "interchangeably", - "interlectually", "intellectually", - "internationaal", "international", - "internationaly", "internationally", - "internationnal", "international", - "interpersonnal", "interpersonal", - "interpertation", "interpretation", - "interpratation", "interpretation", - "interpretacion", "interpretation", - "interpretaiton", "interpretations", - "interpretating", "interpretation", - "interpritation", "interpretation", - "interstellaire", "interstellar", - "intillectually", "intellectually", - "intrepretation", "interpretation", - "invesitgations", "investigations", - "investiagtions", "investigations", - "investigatiors", "investigations", - "investigativos", "investigations", - "investigstions", "investigations", - "irrationallity", "irrationally", - "irresponsibile", "irresponsible", - "journalistisch", "journalistic", - "justificativos", "justifications", - "koncentrations", "concentrations", - "liberatrianism", "libertarianism", - "libertarainism", "libertarianism", - "libertariansim", "libertarianism", - "libertarinaism", "libertarianism", - "libertaryanism", "libertarianism", - "libertatianism", "libertarianism", - "liberterianism", "libertarianism", - "libretarianism", "libertarianism", - "manufactureers", "manufactures", - "manufactureras", "manufactures", - "manufacturered", "manufactured", - "manufactureres", "manufacturers", - "manufactureros", "manufactures", - "massachusettes", "massachusetts", - "massachussetts", "massachusetts", - "mataphorically", "metaphorically", - "mathameticians", "mathematicians", - "mathemagically", "mathematically", - "mathematitians", "mathematicians", - "mathemetically", "mathematically", - "mathemeticians", "mathematicians", - "mathimatically", "mathematically", - "mediterainnean", "mediterranean", - "mediterrannean", "mediterranean", - "metaphotically", "metaphorically", - "metephorically", "metaphorically", - "methaporically", "metaphorically", - "metiphorically", "metaphorically", - "metophorically", "metaphorically", - "metropolitaine", "metropolitan", - "misconseptions", "misconceptions", - "misinterperted", "misinterpreted", - "misintrepreted", "misinterpreted", - "mulitnationals", "multinational", - "mulitplication", "multiplication", - "multiplicacion", "multiplication", - "multiplicaiton", "multiplication", - "multiplicativo", "multiplication", - "multiplikation", "multiplication", - "mutlinationals", "multinational", - "mutliplication", "multiplication", - "nationalisitic", "nationalistic", - "nationalistics", "nationalists", - "nationalisties", "nationalists", - "nationalistisk", "nationalists", - "neighbourhoood", "neighbourhood", - "nieghbourhoods", "neighbourhood", - "northereastern", "northeastern", - "objectificaton", "objectification", - "opthalmologist", "ophthalmologist", - "organizacional", "organizational", - "organizaitonal", "organizational", - "organziational", "organizational", - "orginazational", "organizational", - "overestemating", "overestimating", - "overextimating", "overestimating", - "overhwelmingly", "overwhelmingly", - "overhwlemingly", "overwhelmingly", - "overpolulation", "overpopulation", - "overpopluation", "overpopulation", - "oversetimating", "overestimating", - "overshadowered", "overshadowed", - "overwhemlingly", "overwhelmingly", - "overwhlemingly", "overwhelmingly", - "paliamentarian", "parliamentarian", - "parliamentiary", "parliamentary", - "performancepcs", "performances", - "personalitites", "personalities", - "pharamceutical", "pharmaceutical", - "pharmaceudical", "pharmaceutical", - "pharmacuetical", "pharmaceutical", - "pharmaseutical", "pharmaceutical", - "pharmeceutical", "pharmaceutical", - "philosophicaly", "philosophically", - "phramaceutical", "pharmaceutical", - "playthroughers", "playthroughs", - "porportionally", "proportionally", - "practitionners", "practitioners", - "predeterminded", "predetermined", - "predominantely", "predominantly", - "predominantley", "predominantly", - "preinitalizing", "preinitializing", - "prerequisities", "prerequisite", - "procrastinatin", "procrastination", - "procrastinaton", "procrastination", - "professionials", "professionalism", - "professionnals", "professionals", - "profitabillity", "profitability", - "progressivelly", "progressively", - "progressivisme", "progressives", - "pronounciation", "pronunciation", - "proportianally", "proportionally", - "proportionalty", "proportionally", - "proportionella", "proportionally", - "proprotionally", "proportionally", - "protruberances", "protuberances", - "pseudononymous", "pseudonymous", - "psychologicaly", "psychologically", - "qaulifications", "qualification", - "qualifiactions", "qualification", - "qualificaitons", "qualifications", - "quarterbackers", "quarterbacks", - "rationalizaton", "rationalization", - "reaponsibility", "responsibility", - "recommandation", "recommendation", - "recommedations", "recommendations", - "recommondation", "recommendation", - "reconnaissence", "reconnaissance", - "reconstruccion", "reconstruction", - "reconsturction", "reconstruction", - "redistirbution", "redistribution", - "redistribucion", "redistribution", - "redistributivo", "redistribution", - "redistrubition", "redistribution", - "refridgeration", "refrigeration", - "rehabilitacion", "rehabilitation", - "rehabilitaiton", "rehabilitation", - "reinforcemnets", "reinforcements", - "rekommendation", "recommendation", - "rektifications", "certifications", - "reniforcements", "reinforcements", - "repersentation", "representation", - "represantation", "representation", - "represantative", "representative", - "representacion", "representation", - "representaiton", "representations", - "representatief", "representative", - "representating", "representation", - "representativo", "representation", - "representetive", "representative", - "representitive", "representative", - "representstion", "representations", - "representstive", "representatives", - "represetnation", "representations", - "represnetation", "representations", - "reprezentative", "representative", - "repsonsibility", "responsibility", - "resistribution", "redistribution", - "responcibility", "responsibility", - "responisbility", "responsibility", - "responnsibilty", "responsibility", - "responsability", "responsibility", - "responsibilies", "responsibilities", - "responsibities", "responsibilities", - "restaraunteurs", "restaurateurs", - "retroactivelly", "retroactively", - "revolutionairy", "revolutionary", - "revolutionnary", "revolutionary", - "ridicilousness", "ridiculousness", - "ridicoulusness", "ridiculousness", - "rienforcements", "reinforcements", - "righteoussness", "righteousness", - "satisfactoraly", "satisfactory", - "satisfactority", "satisfactorily", - "sceintifically", "scientifically", - "schizophrentic", "schizophrenic", - "screenwrighter", "screenwriter", - "sensacionalism", "sensationalism", - "sensacionalist", "sensationalist", - "sensasionalism", "sensationalism", - "sensasionalist", "sensationalist", - "sensationality", "sensationalist", - "sensationalizm", "sensationalism", - "sensationalsim", "sensationalism", - "sensationilism", "sensationalism", - "sensationilist", "sensationalist", - "sensationslism", "sensationalism", - "sensetionalism", "sensationalism", - "sensibilisiert", "sensibilities", - "sentationalism", "sensationalism", - "sentationalist", "sensationalist", - "senzationalism", "sensationalism", - "senzationalist", "sensationalist", - "sepcifications", "specification", - "simaltaneously", "simultaneously", - "simeltaneously", "simultaneously", - "similtaneously", "simultaneously", - "simlutaneously", "simultaneously", - "simplificacion", "simplification", - "simplificaiton", "simplification", - "simplificating", "simplification", - "simulatenously", "simultaneously", - "simulatneously", "simultaneously", - "simultaenously", "simultaneously", - "simultainously", "simultaneously", - "simultaneoulsy", "simultaneously", - "simultaniously", "simultaneously", - "simulteanously", "simultaneously", - "sistematically", "systematically", - "slaugterhouses", "slaughterhouses", - "specailization", "specialization", - "specialication", "specialization", - "specializaiton", "specialization", - "specificaitons", "specification", - "speciliazation", "specialization", - "spectacularely", "spectacularly", - "spectacularily", "spectacularly", - "spesifications", "specifications", - "spezialisation", "specialization", - "sportsmansship", "sportsmanship", - "spreadsheeters", "spreadsheets", - "straightforwad", "straightforward", - "subconcsiously", "subconsciously", - "subconsicously", "subconsciously", - "subsconciously", "subconsciously", - "sunconsciously", "subconsciously", - "superintendant", "superintendent", - "suppliementing", "supplementing", - "surrepetitious", "surreptitious", - "survivabililty", "survivability", - "survivabillity", "survivability", - "sustainabiltiy", "sustainability", - "syncronization", "synchronization", - "systemetically", "systematically", - "systimatically", "systematically", - "technologicaly", "technologically", - "thermodinamics", "thermodynamics", - "thermodyanmics", "thermodynamics", - "thermodymamics", "thermodynamics", - "thermodymanics", "thermodynamics", - "thermodynamcis", "thermodynamics", - "thermodynanics", "thermodynamics", - "thermodynmaics", "thermodynamics", - "thernodynamics", "thermodynamics", - "theromdynamics", "thermodynamics", - "transformacion", "transformation", - "transfromation", "transformation", - "transitionable", "transitional", - "transitionning", "transitioning", - "transofrmation", "transformation", - "trasnformation", "transformation", - "trasnportation", "transportation", - "unbelievablely", "unbelievably", - "unchallengable", "unchallengeable", - "uncomfortabley", "uncomfortably", - "uncomfortablly", "uncomfortably", - "unconciousness", "unconsciousness", - "unconditionaly", "unconditionally", - "unconditionnal", "unconditional", - "unconsciouslly", "unconsciously", - "uncontrallable", "uncontrollable", - "uncontrallably", "uncontrollably", - "uncontrolablly", "uncontrollably", - "unconvectional", "unconventional", - "unconvencional", "unconventional", - "unconvensional", "unconventional", - "unconventianal", "unconventional", - "underastimated", "underestimated", - "underestamated", "underestimated", - "underestemated", "underestimated", - "underestimeted", "underestimated", - "undersetimated", "underestimated", - "understandebly", "understandably", - "understandible", "understandable", - "understandibly", "understandably", - "undestructible", "indestructible", - "unforetunately", "unfortunately", - "unfortunatelly", "unfortunately", - "unfourtunately", "unfortunately", - "uninitalizable", "uninitializable", - "unintelligient", "unintelligent", - "unintentionaly", "unintentionally", - "unintentionnal", "unintentional", - "unmanouverable", "unmaneuverable", - "unneccessarily", "unnecessarily", - "unnecessarilly", "unnecessarily", - "unprecendented", "unprecedented", - "unprofessionel", "unprofessional", - "unreasonablely", "unreasonably", - "unsubstantiaed", "unsubstantiated", - "unsurprizingly", "unsurprisingly", - "vizualisations", "visualization", - "vulnerabilites", "vulnerabilities", - "vulnerabillity", "vulnerability", - "vulnerablility", "vulnerability", - "wholeheartadly", "wholeheartedly", - "wholeheartidly", "wholeheartedly", - "abbrievations", "abbreviation", - "accelleration", "acceleration", - "accomadations", "accommodations", - "accommadating", "accommodating", - "accommadation", "accommodation", - "accommidation", "accommodation", - "accomodations", "accommodations", - "accomondating", "accommodating", - "accomondation", "accommodation", - "accomplishent", "accomplishment", - "accountabilty", "accountability", - "accredidation", "accreditation", - "acknolwedging", "acknowledging", - "acknowlegding", "acknowledging", - "acomplishment", "accomplishment", - "acquaintaince", "acquaintance", - "acquaintences", "acquaintances", - "acquaintinces", "acquaintances", - "acquanitances", "acquaintance", - "acquantainces", "acquaintances", - "acquantiances", "acquaintances", - "acquiantances", "acquaintances", - "acquiantences", "acquaintances", - "adminastrator", "administrator", - "administartor", "administrator", - "administraion", "administration", - "administraron", "administrator", - "administrater", "administrator", - "administratio", "administrator", - "administraton", "administration", - "adminsitrator", "administrator", - "adminstration", "administration", - "adminstrative", "administrative", - "admissability", "admissibility", - "adnimistrator", "administrators", - "adverticement", "advertisement", - "advertisiment", "advertisement", - "advertisments", "advertisements", - "advirtisement", "advertisement", - "aestethically", "aesthetically", - "aesthatically", "aesthetically", - "aesthitically", "aesthetically", - "affectionnate", "affectionate", - "aforementiond", "aforementioned", - "agriculturual", "agricultural", - "agrumentative", "argumentative", - "alterantively", "alternatively", - "alternativets", "alternatives", - "alternativley", "alternatively", - "alternitavely", "alternatively", - "alternitively", "alternatively", - "aninteresting", "uninteresting", - "annoucnements", "announcements", - "antagonisitic", "antagonistic", - "anthropolgist", "anthropologist", - "apporpriately", "appropriately", - "apporpriation", "appropriation", - "apporximately", "approximately", - "appreciateing", "appreciating", - "appreciateive", "appreciative", - "appreciationg", "appreciating", - "appropirately", "appropriately", - "appropiration", "appropriation", - "appropraitely", "appropriately", - "appropreation", "appropriation", - "appropriatley", "appropriately", - "appropropiate", "appropriate", - "approrpiation", "appropriation", - "approxamately", "approximately", - "approxiamtely", "approximately", - "approximatley", "approximately", - "approximitely", "approximately", - "aqcuaintances", "acquaintances", - "aqquaintances", "acquaintances", - "archaelogical", "archaeological", - "archaelogists", "archaeologists", - "archeaologist", "archeologist", - "archetectural", "architectural", - "architechture", "architecture", - "architechural", "architectural", - "architectrual", "architectural", - "architecutral", "architectural", - "argumentitive", "argumentative", - "arugmentative", "argumentative", - "asethetically", "aesthetically", - "assasinations", "assassinations", - "audomoderator", "automoderator", - "australianess", "australians", - "authenticaion", "authentication", - "authenticaton", "authentication", - "autherization", "authorization", - "authoratitive", "authoritative", - "authoritatian", "authoritarian", - "authoritation", "authorization", - "authorititive", "authoritative", - "authoritorian", "authoritarian", - "authorotative", "authoritative", - "authroization", "authorization", - "automoderador", "automoderator", - "automoderater", "automoderator", - "automodorator", "automoderator", - "automoterator", "automoderator", - "autoritharian", "authoritarian", - "availabillity", "availability", - "awknowledging", "acknowledging", - "billingualism", "bilingualism", - "billionairres", "billionaire", - "borderlanders", "borderlands", - "breadtfeeding", "breastfeeding", - "breastfeading", "breastfeeding", - "breatsfeeding", "breastfeeding", - "broadacasting", "broadcasting", - "bureaucractic", "bureaucratic", - "bureaucratics", "bureaucrats", - "bureaucratius", "bureaucrats", - "californiaman", "californian", - "calrification", "clarification", - "capitalizaton", "capitalization", - "carbohdyrates", "carbohydrates", - "carbohidrates", "carbohydrates", - "carbohyrdates", "carbohydrates", - "carboyhdrates", "carbohydrates", - "carthographer", "cartographer", - "catagorically", "categorically", - "catastrophies", "catastrophe", - "catastrophize", "catastrophe", - "catigorically", "categorically", - "catterpillars", "caterpillars", - "celebrationis", "celebrations", - "ceritfication", "certifications", - "certificaiton", "certification", - "championchips", "championship", - "championshiop", "championships", - "championsship", "championships", - "chanpionships", "championships", - "charactarized", "characterized", - "characterisic", "characteristic", - "characteristc", "characteristics", - "characterists", "characteristics", - "charicterized", "characterized", - "charismatisch", "charismatic", - "checkpointusa", "checkpoints", - "cheeseburgare", "cheeseburger", - "cheeseburgler", "cheeseburger", - "cheeseburguer", "cheeseburger", - "cheezeburgers", "cheeseburgers", - "chornological", "chronological", - "chronoligical", "chronological", - "chronologicly", "chronological", - "cinematograhy", "cinematography", - "cinematograpy", "cinematography", - "circomference", "circumference", - "circumcission", "circumcision", - "circumferance", "circumference", - "circumsicions", "circumcision", - "circumstanial", "circumstantial", - "circumstantal", "circumstantial", - "circumstnaces", "circumstance", - "circunference", "circumference", - "circunstances", "circumstances", - "cirucmference", "circumference", - "cirucmstances", "circumstances", - "civilications", "civilizations", - "civilizaitons", "civilizations", - "clarificaiton", "clarification", - "clasification", "clarification", - "clerification", "clarification", - "coincidentaly", "coincidentally", - "coincidential", "coincidental", - "colaborations", "collaborations", - "collabaration", "collaboration", - "collaberation", "collaboration", - "collaberative", "collaborative", - "collaboratore", "collaborate", - "collectioners", "collections", - "collectivelly", "collectively", - "collobaration", "collaboration", - "combatibility", "compatibility", - "comeptitively", "competitively", - "comfortablely", "comfortably", - "comfortablity", "comfortably", - "comfrontation", "confrontation", - "commemerative", "commemorative", - "commericially", "commercially", - "commerorative", "commemorative", - "comminication", "communication", - "comminucation", "communications", - "commissionees", "commissions", - "commissionned", "commissioned", - "commissionner", "commissioner", - "commmemorated", "commemorated", - "commuications", "communications", - "commuincation", "communications", - "communciation", "communication", - "communiaction", "communications", - "communicaiton", "communication", - "communicatoin", "communications", - "communicatons", "communications", - "compadibility", "compatibility", - "comparativley", "comparatively", - "comparetively", "comparatively", - "comparitavely", "comparatively", - "comparitively", "comparatively", - "compatability", "compatibility", - "compatibiltiy", "compatibility", - "compeditively", "competitively", - "compensantion", "compensation", - "compensationg", "compensating", - "comperatively", "comparatively", - "comperhension", "comprehension", - "competatively", "competitively", - "competitavely", "competitively", - "competitevely", "competitively", - "competitivley", "competitively", - "competiveness", "competitiveness", - "compilcations", "complication", - "compitability", "compatibility", - "complciations", "complication", - "complecations", "complications", - "compliactions", "complication", - "complicaitons", "complication", - "complilations", "complications", - "complimentery", "complimentary", - "complimentoni", "complimenting", - "complimentory", "complimentary", - "comprehention", "comprehension", - "computacional", "computational", - "comtamination", "contamination", - "comtemplating", "contemplating", - "concatination", "contamination", - "conceivablely", "conceivably", - "concencration", "concentration", - "concenrtation", "concentrations", - "concentartion", "concentrations", - "concentracion", "concentration", - "concentraited", "concentrated", - "concentraiton", "concentrations", - "concentratons", "concentrations", - "concervatives", "conservatives", - "concideration", "consideration", - "concioussness", "consciousness", - "concnetration", "concentrations", - "concsiousness", "consciousness", - "condascending", "condescending", - "condescencion", "condescension", - "condescendion", "condescension", - "condescensing", "condescension", - "condiscending", "condescending", - "conditionning", "conditioning", - "condradicting", "contradicting", - "condradiction", "contradiction", - "condradictory", "contradictory", - "conecntration", "concentrations", - "conenctration", "concentrations", - "confidentally", "confidentially", - "configruation", "configurations", - "configuartion", "configuration", - "configuracion", "configuration", - "configuraiton", "configuration", - "configuratoin", "configurations", - "configureable", "configurable", - "confrentation", "confrontation", - "confrontacion", "confrontation", - "confrontating", "confrontation", - "confrontativo", "confrontation", - "congratualted", "congratulate", - "conifguration", "configurations", - "conisderation", "considerations", - "connecticunts", "connecticut", - "connectivitiy", "connectivity", - "conpassionate", "compassionate", - "conplications", "complications", - "conplimentary", "complimentary", - "conplimenting", "complimenting", - "conprehension", "comprehension", - "consdieration", "considerations", - "consenquently", "consequently", - "consentrating", "concentrating", - "consentration", "concentration", - "consequencies", "consequence", - "consequentely", "consequently", - "consequeseces", "consequences", - "conservatisim", "conservatism", - "conservativsm", "conservatism", - "conservitives", "conservatives", - "consicousness", "consciousness", - "considerabely", "considerable", - "considerabile", "considerable", - "considerabley", "considerably", - "considerablly", "considerably", - "consideracion", "consideration", - "consideratoin", "considerations", - "considerstion", "considerations", - "considertaion", "considerations", - "consituencies", "constituencies", - "consitutional", "constitutional", - "constallation", "constellation", - "constarnation", "consternation", - "constillation", "constellation", - "constituintes", "constituents", - "constituional", "constitutional", - "constitutents", "constitutes", - "constitutinal", "constitutional", - "constructicon", "construction", - "constructieve", "constructive", - "constructiong", "constructing", - "consttruction", "construction", - "contaminacion", "contamination", - "contaminanted", "contaminated", - "contanimation", "contamination", - "contenplating", "contemplating", - "contimplating", "contemplating", - "contraceptivo", "contraception", - "contradiccion", "contradiction", - "contradicitng", "contradicting", - "contradiciton", "contradiction", - "contradictary", "contradictory", - "contradictons", "contradicts", - "contraticting", "contradicting", - "contravercial", "controversial", - "contraversial", "controversial", - "contreception", "contraception", - "contreversial", "controversial", - "contributeurs", "contributes", - "contributiors", "contributors", - "contriception", "contraception", - "contridictory", "contradictory", - "contritutions", "contributions", - "contriversial", "controversial", - "controception", "contraception", - "controdicting", "contradicting", - "controdiction", "contradiction", - "controvercial", "controversial", - "controverisal", "controversial", - "controversary", "controversy", - "controversity", "controversy", - "controvertial", "controversial", - "contstruction", "construction", - "conventionnal", "conventional", - "converastions", "conservation", - "conversationa", "conservation", - "conversationg", "conservation", - "conversationy", "conservation", - "conversatiosn", "conservation", - "conversatives", "conservatives", - "converstaions", "conversations", - "convorsations", "conversations", - "cooresponding", "corresponding", - "coorperations", "corporations", - "correctionals", "corrections", - "correpsonding", "corresponding", - "correspondant", "correspondent", - "correspondece", "correspondence", - "corresponders", "corresponds", - "corresponsing", "corresponding", - "corrispondant", "correspondent", - "corrisponding", "corresponding", - "corrosponding", "corresponding", - "costomization", "customization", - "costumization", "customization", - "counterfeight", "counterfeit", - "creationistas", "creationists", - "cricumference", "circumference", - "cringeworthey", "cringeworthy", - "cringeworthly", "cringeworthy", - "crytopgraphic", "cryptographic", - "curcumference", "circumference", - "curcumstances", "circumstances", - "custumization", "customization", - "cuztomization", "customization", - "decentraliced", "decentralized", - "decentrilized", "decentralized", - "decomissioned", "decommissioned", - "decompositing", "decomposing", - "definitivelly", "definitively", - "deinitalizing", "deinitializing", - "demenstration", "demonstration", - "democraticaly", "democratically", - "democraticlly", "democratically", - "demoninations", "denominations", - "demonstarting", "demonstrating", - "demonstartion", "demonstration", - "demonstraiton", "demonstrations", - "demonstratbly", "demonstrably", - "demonstraties", "demonstrate", - "demonstrativo", "demonstration", - "demosntrating", "demonstrating", - "demosntration", "demonstrations", - "denomenations", "denominations", - "denomonations", "denominations", - "deomnstration", "demonstrations", - "dermatalogist", "dermatologist", - "dermatolagist", "dermatologist", - "dermatoligist", "dermatologist", - "dermatologyst", "dermatologist", - "dermetologist", "dermatologist", - "dermitologist", "dermatologist", - "derpatologist", "dermatologist", - "desentralized", "decentralized", - "desillusioned", "disillusioned", - "desintegrated", "disintegrated", - "desinterested", "disinterested", - "determenation", "determination", - "determinacion", "determination", - "determinining", "determining", - "determinisitc", "deterministic", - "determinsitic", "deterministic", - "detmatologist", "dermatologist", - "developmently", "developmental", - "dezentralized", "decentralized", - "differantiate", "differentiate", - "differenciate", "differentiate", - "differintiate", "differentiate", - "diffirentiate", "differentiate", - "disadvandages", "disadvantaged", - "disadvantadge", "disadvantaged", - "disadvanteged", "disadvantaged", - "disadvanteges", "disadvantages", - "disadvatanges", "disadvantages", - "disadventaged", "disadvantaged", - "disadventages", "disadvantages", - "disallusioned", "disillusioned", - "disappearence", "disappearance", - "disappearnace", "disappearance", - "disappearring", "disappearing", - "disatvantaged", "disadvantaged", - "disatvantages", "disadvantages", - "disciplinairy", "disciplinary", - "disciplinerad", "disciplined", - "discipliniary", "disciplinary", - "disconnecters", "disconnects", - "discontinuted", "discontinued", - "discrimianted", "discriminated", - "discriminante", "discriminate", - "discriminatie", "discriminate", - "discriminatin", "discrimination", - "disillisioned", "disillusioned", - "disillutioned", "disillusioned", - "disingenuious", "disingenuous", - "disollusioned", "disillusioned", - "disrecpectful", "disrespectful", - "disrecpecting", "disrespecting", - "disrepsectful", "disrespectful", - "disrepsecting", "disrespecting", - "disresepctful", "disrespectful", - "disresepcting", "disrespecting", - "disrespection", "disrespecting", - "disrespekting", "disrespecting", - "disrispectful", "disrespectful", - "disrispecting", "disrespecting", - "dissagreement", "disagreement", - "dissapearance", "disappearance", - "dissapointted", "dissapointed", - "dissappointed", "disappointed", - "dissobediance", "disobedience", - "dissobedience", "disobedience", - "distingishing", "distinguishing", - "distinguising", "distinguishing", - "distinquished", "distinguished", - "distirbutions", "distributions", - "distiungished", "distinguished", - "distribustion", "distributions", - "distributiors", "distributors", - "distributivos", "distributions", - "distrobutions", "distributions", - "distrubitions", "distributions", - "distuingished", "distinguished", - "documantaries", "documentaries", - "documenatries", "documentaries", - "documentacion", "documentation", - "documentaires", "documentaries", - "documentaiton", "documentation", - "documentarios", "documentaries", - "documentaties", "documentaries", - "documentating", "documentation", - "documenteries", "documentaries", - "documentories", "documentaries", - "drammatically", "grammatically", - "dsyfunctional", "dysfunctional", - "dumbfoundeads", "dumbfounded", - "dusfunctional", "dysfunctional", - "dustification", "justification", - "dysfonctional", "dysfunctional", - "dysfucntional", "dysfunctional", - "dysfuncitonal", "dysfunctional", - "dysfunktional", "dysfunctional", - "easthetically", "aesthetically", - "effectiviness", "effectiveness", - "effictiveness", "effectiveness", - "effortlessely", "effortlessly", - "effortlessley", "effortlessly", - "embarrasement", "embarrassment", - "embarrasments", "embarrassment", - "embarressment", "embarrassment", - "emberrassment", "embarrassment", - "encarceration", "incarceration", - "encorporating", "incorporating", - "encyclopeadia", "encyclopedia", - "encyclopeadic", "encyclopedia", - "encyclopeedia", "encyclopedia", - "encycolpedias", "encyclopedia", - "endoctrinated", "indoctrinated", - "enlightenting", "enlightening", - "enlightnement", "enlightenment", - "enligthenment", "enlightenment", - "enteratinment", "entertainment", - "enterpreneurs", "entrepreneurs", - "enterprenuers", "entrepreneurs", - "enterpreuners", "entrepreneurs", - "entertianment", "entertainment", - "enthusiasists", "enthusiasts", - "enthusiastics", "enthusiasts", - "entrepraneurs", "entrepreneurs", - "entreprenaurs", "entrepreneurs", - "entrepreneuer", "entrepreneurs", - "entreprenours", "entrepreneurs", - "entreprenuers", "entrepreneurs", - "entreprenures", "entrepreneurs", - "entrepreuners", "entrepreneurs", - "entretainment", "entertainment", - "enviornmental", "environmental", - "environemntal", "environmental", - "environmently", "environmental", - "envolutionary", "evolutionary", - "envrionmental", "environmental", - "estabilshment", "establishments", - "establishemnt", "establishments", - "establishmnet", "establishments", - "establsihment", "establishments", - "estbalishment", "establishments", - "ethnocentricm", "ethnocentrism", - "evolutionairy", "evolutionary", - "evolutionarly", "evolutionary", - "evolutionnary", "evolutionary", - "exaggeratting", "exaggerating", - "excpetionally", "exceptionally", - "executioneers", "executioner", - "existentiella", "existential", - "expectionally", "exceptionally", - "experementing", "experimenting", - "experienceing", "experiencing", - "experimentais", "experiments", - "experimention", "experimenting", - "experimentors", "experiments", - "expirementing", "experimenting", - "expodentially", "exponentially", - "exponantially", "exponentially", - "exponencially", "exponentially", - "exponentiella", "exponential", - "extraodrinary", "extraordinary", - "extraordianry", "extraordinary", - "extraordinair", "extraordinary", - "extraordinaly", "extraordinary", - "extraoridnary", "extraordinary", - "extremeophile", "extremophile", - "extroardinary", "extraordinary", - "familiarizate", "familiarize", - "fantasitcally", "fantastically", - "fantasmically", "fantastically", - "fantistically", "fantastically", - "faptastically", "fantastically", - "figurativeley", "figuratively", - "figurativelly", "figuratively", - "frankenstiens", "frankenstein", - "frankenstined", "frankenstein", - "frankenstiner", "frankenstein", - "frankenstines", "frankenstein", - "friendzoneado", "friendzoned", - "fucntionality", "functionality", - "funcitonality", "functionality", - "functionailty", "functionality", - "fundamentalis", "fundamentals", - "fundamnetally", "fundamentally", - "fundementally", "fundamentally", - "fundimentally", "fundamentally", - "gamifications", "ramifications", - "generalizaing", "generalizing", - "generalizaton", "generalization", - "generationals", "generations", - "generationens", "generations", - "generationers", "generations", - "generationnal", "generational", - "geographicaly", "geographically", - "geographicial", "geographical", - "geometricians", "geometers", - "goreshadowing", "foreshadowing", - "governmential", "governmental", - "gradification", "gratification", - "grammarically", "grammatically", - "grandchildern", "grandchildren", - "gratificacion", "gratification", - "gratificaiton", "gratification", - "grativational", "gravitational", - "gravitacional", "gravitational", - "gravitaitonal", "gravitational", - "hallcuination", "hallucination", - "hallicunation", "hallucination", - "hallucenation", "hallucination", - "halluciantion", "hallucinations", - "hallukination", "hallucination", - "hallunication", "hallucination", - "hallusination", "hallucination", - "halluzination", "hallucination", - "heiroglyphics", "hieroglyphics", - "hellucination", "hallucination", - "highlightning", "highlighting", - "homesexuality", "homosexuality", - "homosexualtiy", "homosexuality", - "homosexulaity", "homosexuality", - "horizontallly", "horizontally", - "hullucination", "hallucination", - "hypocriticial", "hypocritical", - "hypotheticaly", "hypothetically", - "hystericallly", "hysterically", - "identificaton", "identification", - "ideoligically", "ideologically", - "ideosyncratic", "idiosyncratic", - "idiologically", "ideologically", - "illistrations", "illustrations", - "illustartions", "illustrations", - "imperfactions", "imperfections", - "impersinating", "impersonating", - "implementaion", "implementation", - "implementatin", "implementations", - "implimenation", "implementation", - "imprefections", "imperfections", - "impresonating", "impersonating", - "inaccessibile", "inaccessible", - "inadventently", "inadvertently", - "inadverdently", "inadvertently", - "inadvertantly", "inadvertently", - "inadvertendly", "inadvertently", - "inapporpriate", "inappropriate", - "inappropirate", "inappropriate", - "inappropraite", "inappropriate", - "inaproppriate", "inappropriate", - "incarcaration", "incarceration", - "incarciration", "incarceration", - "incarseration", "incarceration", - "incerceration", "incarceration", - "incidentially", "incidentally", - "incomfortable", "uncomfortable", - "incomfortably", "uncomfortably", - "incompatabile", "incompatible", - "incompatiable", "incompatible", - "incompatibile", "incompatible", - "inconciderate", "inconsiderate", - "inconcistency", "inconsistency", - "inconditional", "unconditional", - "inconsciously", "unconsciously", - "inconsiderant", "inconsiderate", - "inconsistance", "inconsistency", - "inconsistancy", "inconsistency", - "inconsistenly", "inconsistency", - "inconsistensy", "inconsistency", - "inconsistenty", "inconsistency", - "inconveinence", "inconvenience", - "inconveniance", "inconvenience", - "inconveniente", "inconvenience", - "inconvienence", "inconvenience", - "incoroporated", "incorporated", - "incorparating", "incorporating", - "incorperating", "incorporating", - "incorperation", "incorporation", - "incorruptable", "incorruptible", - "incramentally", "incrementally", - "incrementarla", "incremental", - "incrementarlo", "incremental", - "indavertently", "inadvertently", - "indefinitelly", "indefinitely", - "independantes", "independents", - "independantly", "independently", - "independendet", "independent", - "independendly", "independently", - "indepentently", "independently", - "indespensable", "indispensable", - "indespensible", "indispensable", - "indestructble", "indestructible", - "indestructibe", "indestructible", - "indictrinated", "indoctrinated", - "indipendently", "independently", - "indispensible", "indispensable", - "indivuduality", "individuality", - "indocrtinated", "indoctrinated", - "indocternated", "indoctrinated", - "indoctornated", "indoctrinated", - "indoctrinatie", "indoctrinated", - "indoctrinatin", "indoctrination", - "indoctronated", "indoctrinated", - "industrialied", "industrialized", - "industrialzed", "industrialized", - "inexeprienced", "inexperience", - "inexpeirenced", "inexperience", - "inexpereinced", "inexperienced", - "inexperianced", "inexperienced", - "inexperiecned", "inexperience", - "inexperineced", "inexperience", - "inexpierenced", "inexperienced", - "inexplicabley", "inexplicably", - "inexplicablly", "inexplicably", - "infilitration", "infiltration", - "infrastructre", "infrastructure", - "infrastrucure", "infrastructure", - "inintelligent", "unintelligent", - "ininteresting", "uninteresting", - "initalisation", "initialisation", - "initalization", "initialization", - "inperfections", "imperfections", - "inpersonating", "impersonating", - "inpossibility", "impossibility", - "inpredictable", "unpredictable", - "inresponsible", "irresponsible", - "insectiverous", "insectivorous", - "insecuritites", "insecurities", - "insiginficant", "insignificant", - "insiginifcant", "insignificant", - "insignificent", "insignificant", - "insignificunt", "insignificant", - "insignifigant", "insignificant", - "insiprational", "inspirational", - "insperational", "inspirational", - "inspiritional", "inspirational", - "inspriational", "inspirational", - "instantaenous", "instantaneous", - "instantanious", "instantaneous", - "instanteneous", "instantaneous", - "instantenious", "instantaneous", - "instincitvely", "instinctively", - "instinctivley", "instinctively", - "instititional", "institutional", - "institutionel", "institutional", - "insturmentals", "instrumental", - "instutitional", "institutional", - "insustainable", "unsustainable", - "intelelctuals", "intellectuals", - "intellectualy", "intellectually", - "intellectuels", "intellectuals", - "intellecutals", "intellectuals", - "intellegently", "intelligently", - "intelluctuals", "intellectuals", - "intepretation", "interpretation", - "intereactions", "intersections", - "interesctions", "intersections", - "interlectuals", "intellectuals", - "intermittient", "intermittent", - "intermittment", "intermittent", - "internacional", "international", - "interpersonel", "interpersonal", - "interpresonal", "interpersonal", - "interpretaion", "interpretation", - "interpretarea", "interpreter", - "interpretarem", "interpreter", - "interpretares", "interpreter", - "interpretarse", "interpreter", - "interpretarte", "interpreter", - "interpretatin", "interpretations", - "interpreteert", "interpreter", - "interragation", "interrogation", - "interregation", "interrogation", - "interrigation", "interrogation", - "interrogacion", "interrogation", - "interrogativo", "interrogation", - "intertainment", "entertainment", - "intillectuals", "intellectuals", - "intraspection", "introspection", - "intrensically", "intrinsically", - "intriniscally", "intrinsically", - "intrinsecally", "intrinsically", - "intrisincally", "intrinsically", - "intristically", "intrinsically", - "introductiory", "introductory", - "introspeccion", "introspection", - "introspectivo", "introspection", - "introspektion", "introspection", - "invertibrates", "invertebrates", - "invesitgation", "investigation", - "invesitgative", "investigative", - "invesitgators", "investigators", - "investagators", "investigators", - "investegating", "investigating", - "investegators", "investigators", - "investiagtion", "investigation", - "investiagtive", "investigative", - "investigacion", "investigation", - "investigaiton", "investigations", - "investigaters", "investigators", - "investigativo", "investigation", - "investigatons", "investigations", - "investigsting", "investigating", - "investigstion", "investigations", - "investogators", "investigators", - "invisibillity", "invisibility", - "involuntarely", "involuntary", - "involuntarity", "involuntary", - "invulnerabile", "invulnerable", - "irrationallly", "irrationally", - "irresponcible", "irresponsible", - "irresponisble", "irresponsible", - "irresponsable", "irresponsible", - "irresponsbile", "irresponsible", - "irreversiable", "irreversible", - "irreversibelt", "irreversible", - "irreversibile", "irreversible", - "irrisponsible", "irresponsible", - "jacksonvillle", "jacksonville", - "journalisitic", "journalistic", - "journalistens", "journalists", - "journalisters", "journalists", - "journalistisk", "journalists", - "jsutification", "justifications", - "jurisdicitons", "jurisdictions", - "jurisidctions", "jurisdictions", - "juristictions", "jurisdictions", - "jursidictions", "jurisdictions", - "jusitfication", "justifications", - "justifiaction", "justifications", - "justificacion", "justification", - "justificaiton", "justification", - "justificativo", "justification", - "justificatons", "justifications", - "justificstion", "justifications", - "justiifcation", "justifications", - "karbohydrates", "carbohydrates", - "knoweldgeable", "knowledgeable", - "knowledegable", "knowledgeable", - "knowledgebale", "knowledgable", - "knowlegdeable", "knowledgeable", - "kollaboration", "collaboration", - "koncentration", "concentration", - "konfiguration", "configuration", - "konfrontation", "confrontation", - "konservatives", "conservatives", - "konstellation", "constellation", - "kontamination", "contamination", - "legitimatelly", "legitimately", - "libertariaism", "libertarianism", - "libertariansm", "libertarianism", - "libitarianisn", "libertarianism", - "lighthearthed", "lighthearted", - "mainfestation", "manifestation", - "manafacturers", "manufacturers", - "manafacturing", "manufacturing", - "manafestation", "manifestation", - "manefestation", "manifestation", - "manfuacturers", "manufactures", - "manifacturers", "manufacturers", - "manifacturing", "manufacturing", - "manifastation", "manifestation", - "manifestacion", "manifestation", - "manifestating", "manifestation", - "manifistation", "manifestation", - "manipulationg", "manipulating", - "manufacterers", "manufacturers", - "manufactering", "manufacturing", - "manufacterurs", "manufactures", - "manufactorers", "manufacturers", - "manufactoring", "manufacturing", - "manufactuered", "manufactured", - "manufactuerer", "manufacturer", - "manufactueres", "manufactures", - "manufacturedd", "manufactured", - "manufactureds", "manufactures", - "manufacturerd", "manufactured", - "manufacturier", "manufacturer", - "manufacturors", "manufacturers", - "manufactuters", "manufactures", - "manufacutrers", "manufactures", - "manufcaturers", "manufactures", - "marshmalllows", "marshmallows", - "massachsuetts", "massachusetts", - "massachucetts", "massachusetts", - "massachuestts", "massachusetts", - "massachusents", "massachusetts", - "massachusites", "massachusetts", - "massachussets", "massachusetts", - "massechusetts", "massachusetts", - "masturbateing", "masturbating", - "materialisimo", "materialism", - "mathamatician", "mathematician", - "mathametician", "mathematician", - "mathematicals", "mathematics", - "mathematicaly", "mathematically", - "mathematicans", "mathematics", - "mathematicion", "mathematician", - "mathematitian", "mathematician", - "mathemetician", "mathematician", - "mathmatically", "mathematically", - "mathmaticians", "mathematicians", - "mechanicallly", "mechanically", - "medeterranean", "mediterranean", - "meditarrenean", "mediterranean", - "meditereanean", "mediterranean", - "membranaphone", "membranophone", - "metamorphysis", "metamorphosis", - "metaphoricaly", "metaphorically", - "metaphoricial", "metaphorical", - "metaphysicals", "metaphysics", - "metaphysicans", "metaphysics", - "methamatician", "mathematician", - "methematician", "mathematician", - "metropolitain", "metropolitan", - "metropolitcan", "metropolitan", - "metropolitian", "metropolitan", - "millionairres", "millionaire", - "minneapolites", "minneapolis", - "misanderstood", "misunderstood", - "miscellanious", "miscellaneous", - "misconcpetion", "misconceptions", - "misconecption", "misconceptions", - "misinterperet", "misinterpret", - "misinterprate", "misinterpret", - "misinterprent", "misinterpret", - "misinterprted", "misinterpret", - "misogynisitic", "misogynistic", - "misrepreseted", "misrepresented", - "misunterstood", "misunderstood", - "modificaitons", "modifications", - "motivationals", "motivations", - "motivationnal", "motivational", - "mulitnational", "multinational", - "multimational", "multinational", - "multiplicaton", "multiplication", - "muncipalities", "municipalities", - "munnicipality", "municipality", - "mutlinational", "multinational", - "nacionalistic", "nationalistic", - "narcissisitic", "narcissistic", - "narcississtic", "narcissistic", - "natioanlistic", "nationalistic", - "nationalisitc", "nationalistic", - "nationalistes", "nationalists", - "nationalsitic", "nationalistic", - "neigbhourhood", "neighbourhood", - "neighboorhoud", "neighbourhood", - "neighborehood", "neighbourhood", - "neighborhoood", "neighborhoods", - "neighbourbood", "neighbourhood", - "neighbourgood", "neighbourhood", - "neighbourhoud", "neighbourhood", - "neighourhoods", "neighborhoods", - "nieghborhoods", "neighborhoods", - "nieghbourhood", "neighbourhood", - "noncombatents", "noncombatants", - "noninitalized", "noninitialized", - "northwestener", "northwestern", - "notificaitons", "notifications", - "occassionally", "occasionally", - "operationable", "operational", - "oppertunities", "opportunities", - "opprotunities", "opportunities", - "oppurtunities", "opportunities", - "opthamologist", "ophthalmologist", - "organistaions", "organisations", - "organizatinal", "organizational", - "organizativos", "organizations", - "organsiations", "organisations", - "organziations", "organizations", - "orginasations", "organisations", - "orginazations", "organizations", - "overpopulaton", "overpopulation", - "overreactiong", "overreacting", - "overshaddowed", "overshadowed", - "overwheliming", "overwhelming", - "overwhelmigly", "overwhelmingly", - "overwhelmingy", "overwhelmingly", - "overwhelminly", "overwhelmingly", - "palestininans", "palestinians", - "paraphraseing", "paraphrasing", - "paraphrashing", "paraphrasing", - "parilamentary", "parliamentary", - "parlaimentary", "parliamentary", - "parliamantary", "parliamentary", - "parliamentery", "parliamentary", - "parliamnetary", "parliamentary", - "parliementary", "parliamentary", - "particiaption", "participation", - "participacion", "participation", - "participantes", "participants", - "participativo", "participation", - "particularely", "particularly", - "particularily", "particularly", - "particularlly", "particularly", - "partizipation", "participation", - "passionatelly", "passionately", - "paychiatrists", "psychiatrists", - "paychologists", "psychologists", - "pennsylvainia", "pennsylvania", - "pennsylvanica", "pennsylvania", - "pennsylvannia", "pennsylvania", - "perdominantly", "predominantly", - "perpandicular", "perpendicular", - "perpendicualr", "perpendicular", - "perpenticular", "perpendicular", - "perpetuationg", "perpetuating", - "perpindicular", "perpendicular", - "personalitits", "personalities", - "pessimistisch", "pessimistic", - "pharmaceutial", "pharmaceutical", - "philisophical", "philosophical", - "philosiphical", "philosophical", - "philosohpical", "philosophical", - "philosophycal", "philosophically", - "philospohical", "philosophical", - "phisiological", "physiological", - "photagraphers", "photographers", - "photographics", "photographs", - "photographied", "photographed", - "photographier", "photographer", - "photograpphed", "photographed", - "photogrophers", "photographers", - "photogrpahers", "photographers", - "photoshoppade", "photoshopped", - "photoshoppped", "photoshopped", - "phsyiological", "physiological", - "phychiatrists", "psychiatrists", - "phychological", "psychological", - "phychologists", "psychologists", - "phylosophical", "philosophical", - "physciatrists", "psychiatrists", - "physcological", "psychological", - "physcologists", "psychologists", - "physioligical", "physiological", - "planeswlakers", "planeswalker", - "plansewalkers", "planeswalker", - "playthroughts", "playthroughs", - "polysaccaride", "polysaccharide", - "practicallity", "practically", - "practicioners", "practitioners", - "practisioners", "practitioners", - "practitioneer", "practitioners", - "practitionner", "practitioner", - "pratictioners", "practitioners", - "preconceieved", "preconceived", - "predecessores", "predecessors", - "predetermiend", "predetermined", - "predetirmined", "predetermined", - "preditermined", "predetermined", - "predomenantly", "predominantly", - "predominently", "predominantly", - "pregressively", "progressively", - "preinitalized", "preinitialized", - "preinitalizes", "preinitializes", - "preliferation", "proliferation", - "prependicular", "perpendicular", - "preposterious", "preposterous", - "prerequisties", "prerequisite", - "prerequistite", "prerequisite", - "prescribtions", "prescriptions", - "presumptuious", "presumptuous", - "pretedermined", "predetermined", - "problematisch", "problematic", - "proclaimation", "proclamation", - "prodominantly", "predominantly", - "professionnal", "professional", - "profitiablity", "profitability", - "profitibality", "profitability", - "progressivily", "progressively", - "progressivley", "progressively", - "prononciation", "pronunciation", - "pronouciation", "pronunciation", - "pronunciacion", "pronunciation", - "pronunciating", "pronunciation", - "pronuncuation", "pronunciation", - "pronunication", "pronunciation", - "pronuntiation", "pronunciation", - "propabilities", "probabilities", - "proportionaly", "proportionally", - "proportionnal", "proportional", - "proseletyzing", "proselytizing", - "protagonistas", "protagonists", - "protagonistes", "protagonists", - "protestantisk", "protestants", - "protruberance", "protuberance", - "provocativley", "provocative", - "pscyhiatrists", "psychiatrists", - "pscyhological", "psychological", - "pscyhologists", "psychologists", - "pshycological", "psychological", - "pshycologists", "psychologists", - "psichological", "psychological", - "psychaitrists", "psychiatrists", - "psychedellics", "psychedelics", - "psychiatrisch", "psychiatric", - "psycholigical", "psychological", - "psycholigists", "psychologists", - "psychologycal", "psychologically", - "psychologysts", "psychologists", - "psychyatrists", "psychiatrists", - "psysiological", "physiological", - "purpendicular", "perpendicular", - "pyschiatrists", "psychiatrists", - "pyschological", "psychological", - "pyschologists", "psychologists", - "qaulification", "qualification", - "qualifiaction", "qualification", - "qualificaiton", "qualifications", - "qualificatons", "qualifications", - "qualifikation", "qualification", - "questionalble", "questionable", - "quinessential", "quintessential", - "ramificaitons", "ramifications", - "realisitcally", "realistically", - "realtionships", "relationships", - "reccommending", "recommending", - "receptionnist", "receptionist", - "receptionsist", "receptionist", - "reconaissance", "reconnaissance", - "reconcilation", "reconciliation", - "reconnaisance", "reconnaissance", - "reconstrucion", "reconstruction", - "recreationnal", "recreational", - "rectangulaire", "rectangular", - "redistribuito", "redistribution", - "redistributin", "redistribution", - "reencarnation", "reincarnation", - "refridgerator", "refrigerator", - "rehabilitaion", "rehabilitation", - "rehabilitatin", "rehabilitation", - "rehabilitaton", "rehabilitation", - "reincarantion", "reincarnation", - "reincatnation", "reincarnation", - "reinforcemens", "reinforcements", - "reinforcemnts", "reinforcements", - "reinitalising", "reinitialising", - "reinitalizing", "reinitializing", - "reinkarnation", "reincarnation", - "reinstallling", "reinstalling", - "reintarnation", "reincarnation", - "relationshits", "relationships", - "relationsship", "relationships", - "relatiopnship", "relationship", - "relentlessely", "relentlessly", - "relentlessley", "relentlessly", - "relinqushment", "relinquishment", - "remifications", "ramifications", - "reprehenisble", "reprehensible", - "reprehensable", "reprehensible", - "reprehinsible", "reprehensible", - "represenation", "representation", - "represensible", "reprehensible", - "representaion", "representation", - "representatie", "representatives", - "representatin", "representations", - "representerad", "represented", - "representitve", "representative", - "representives", "representatives", - "repricussions", "repercussions", - "reprihensible", "reprehensible", - "resolutionary", "revolutionary", - "respectivelly", "respectively", - "responsibiliy", "responsibility", - "responsibilty", "responsibility", - "responsiblity", "responsibility", - "respositories", "repositories", - "resssurecting", "resurrecting", - "ressurrection", "resurrection", - "restaraunteur", "restaurateur", - "retoractively", "retroactively", - "retroactivily", "retroactively", - "retroactivley", "retroactively", - "retrocatively", "retroactively", - "revelutionary", "revolutionary", - "revolutionair", "revolutionary", - "revolutionens", "revolutions", - "revolutioners", "revolutions", - "revoultionary", "revolutionary", - "ridiculouness", "ridiculousness", - "rienforcement", "reinforcements", - "righetousness", "righteousness", - "rightiousness", "righteousness", - "rigtheousness", "righteousness", - "rollarcoaster", "rollercoaster", - "rollercaoster", "rollercoaster", - "rollercoaters", "rollercoaster", - "rollercoatser", "rollercoaster", - "rollerocaster", "rollercoaster", - "rollertoaster", "rollercoaster", - "rollorcoaster", "rollercoaster", - "sacrastically", "sarcastically", - "sarcasitcally", "sarcastically", - "satisfactorly", "satisfactory", - "scandianvians", "scandinavian", - "scateboarding", "skateboarding", - "schisophrenic", "schizophrenic", - "schiziphrenic", "schizophrenic", - "schizophernia", "schizophrenia", - "schizophernic", "schizophrenic", - "schizophrania", "schizophrenia", - "schizoprhenia", "schizophrenia", - "schizoprhenic", "schizophrenic", - "schozophrenia", "schizophrenia", - "schozophrenic", "schizophrenic", - "schyzophrenia", "schizophrenia", - "schyzophrenic", "schizophrenic", - "schziophrenia", "schizophrenia", - "schziophrenic", "schizophrenic", - "scientificaly", "scientifically", - "scientificlly", "scientifically", - "segementation", "segmentation", - "sensationable", "sensational", - "sensationails", "sensationalism", - "sensationaism", "sensationalism", - "sensationalim", "sensationalism", - "sensationella", "sensational", - "shcizophrenic", "schizophrenic", - "significanlty", "significantly", - "significently", "significantly", - "signifigantly", "significantly", - "simultaneosly", "simultaneously", - "simultaneuous", "simultaneous", - "simultanously", "simultaneously", - "singificantly", "significantly", - "skatebaording", "skateboarding", - "skateborading", "skateboarding", - "socioecenomic", "socioeconomic", - "socioecomonic", "socioeconomic", - "socioeconimic", "socioeconomic", - "sohpisticated", "sophisticated", - "sophisitcated", "sophisticated", - "sophistacated", "sophisticated", - "sophistocated", "sophisticated", - "sophosticated", "sophisticated", - "spacification", "specification", - "specializaton", "specialization", - "specificaiton", "specifications", - "specificatons", "specifications", - "specifikation", "specification", - "spectaculaire", "spectacular", - "spectaculalry", "spectacularly", - "spectatularly", "spectacularly", - "spesification", "specification", - "spirituallity", "spiritually", - "sponatenously", "spontaneously", - "spontaenously", "spontaneously", - "spontainously", "spontaneously", - "spontaneoulsy", "spontaneously", - "spontaneuosly", "spontaneously", - "spontaniously", "spontaneously", - "spontanuously", "spontaneously", - "sponteanously", "spontaneously", - "sponteneously", "spontaneously", - "sporstmanship", "sportsmanship", - "sportmansship", "sportsmanship", - "sportsmamship", "sportsmanship", - "sportsmenship", "sportsmanship", - "sprotsmanship", "sportsmanship", - "stakeboarding", "skateboarding", - "startegically", "strategically", - "statisitcally", "statistically", - "statistacally", "statistically", - "stereotipical", "stereotypical", - "stereotpyical", "stereotypical", - "stereotypcial", "stereotypical", - "stereotypeing", "stereotyping", - "stereotypying", "stereotyping", - "steriotypical", "stereotypical", - "steroetypical", "stereotypical", - "steryotypical", "stereotypical", - "storytellling", "storytelling", - "stragegically", "strategically", - "stragetically", "strategically", - "straightenend", "straightened", - "straitforward", "straightforward", - "stratagically", "strategically", - "stratigically", "strategically", - "strawberrries", "strawberries", - "stregnthening", "strengthening", - "strenghtening", "strengthening", - "strengthining", "strengthening", - "stretegically", "strategically", - "subcatagories", "subcategories", - "subconsciosly", "subconsciously", - "subconsciouly", "subconsciously", - "subconsiously", "subconsciously", - "subjectivelly", "subjectively", - "subscribtions", "subscriptions", - "substancially", "substantially", - "substanitally", "substantially", - "substansially", "substantially", - "substantiable", "substantial", - "substantually", "substantially", - "substitutents", "substitutes", - "successfullly", "successfully", - "supermarkedet", "supermarket", - "supermarkerts", "supermarkets", - "superpowereds", "superpowers", - "supersticious", "superstitious", - "superstisious", "superstitious", - "superstitiosi", "superstitious", - "superstitiuos", "superstitious", - "superstituous", "superstitious", - "suphisticated", "sophisticated", - "supscriptions", "subscriptions", - "surreptiously", "surreptitiously", - "survavibility", "survivability", - "survibability", "survivability", - "survivabiltiy", "survivability", - "survivalibity", "survivability", - "survivavility", "survivability", - "survivebility", "survivability", - "susbtantially", "substantially", - "sustainabilty", "sustainability", - "synchornously", "synchronously", - "systematicaly", "systematically", - "systematiclly", "systematically", - "techmological", "technological", - "technicallity", "technically", - "technoligical", "technological", - "technologicly", "technological", - "techonlogical", "technological", - "telaportation", "teleportation", - "teleportating", "teleportation", - "teleprotation", "teleportation", - "teliportation", "teleportation", - "teloportation", "teleportation", - "territoriella", "territorial", - "theoratically", "theoretically", - "theoritically", "theoretically", - "therapeutisch", "therapeutic", - "thereotically", "theoretically", - "thermodynaics", "thermodynamics", - "thermodynamcs", "thermodynamics", - "theroetically", "theoretically", - "thoeretically", "theoretically", - "tranistioning", "transitioning", - "transcendance", "transcendence", - "transcribtion", "transcription", - "transcripcion", "transcription", - "transferrring", "transferring", - "transformarea", "transformer", - "transformarem", "transformer", - "transformarse", "transformers", - "transformaton", "transformation", - "transformered", "transformed", - "transgengered", "transgendered", - "transisioning", "transitioning", - "transitionals", "transitions", - "transitionnal", "transitional", - "transitionned", "transitioned", - "transkription", "transcription", - "translyvanian", "transylvania", - "transmisisons", "transmissions", - "transmissable", "transmissible", - "transmisssion", "transmissions", - "transparantie", "transparent", - "transparentcy", "transparency", - "transplantees", "transplants", - "transporation", "transportation", - "transportaion", "transportation", - "transportarme", "transporter", - "transportarse", "transporter", - "transportarte", "transporter", - "transporteurs", "transporter", - "transsexuella", "transsexual", - "transylvannia", "transylvania", - "trasngendered", "transgendered", - "troubleshooot", "troubleshoot", - "udnerestimate", "underestimated", - "umcomfortable", "uncomfortable", - "umcomfortably", "uncomfortably", - "umpredictable", "unpredictable", - "unappropriate", "inappropriate", - "unbelievabley", "unbelievably", - "unbelievablly", "unbelievably", - "uncertaintity", "uncertainty", - "uncomfertable", "uncomfortable", - "uncomfertably", "uncomfortably", - "uncomfortabel", "uncomfortably", - "uncomforyable", "uncomfortably", - "uncomfrotable", "uncomfortable", - "uncomfrotably", "uncomfortably", - "uncomftorable", "uncomfortable", - "uncomftorably", "uncomfortably", - "unconcsiously", "unconsciously", - "unconfortable", "uncomfortable", - "unconfortably", "uncomfortably", - "unconscioulsy", "unconsciously", - "unconsicously", "unconsciously", - "unconsiderate", "inconsiderate", - "uncontrollabe", "uncontrollable", - "uncontrollaby", "uncontrollably", - "unconventinal", "unconventional", - "uncounciously", "unconsciously", - "uncousciously", "unconsciously", - "underastimate", "underestimate", - "underesitmate", "underestimated", - "underestamate", "underestimate", - "underestemate", "underestimate", - "underestiamte", "underestimated", - "undergratuate", "undergraduate", - "underhwelming", "underwhelming", - "underhwleming", "underwhelming", - "underminining", "undermining", - "underpowererd", "underpowered", - "undersetimate", "underestimate", - "understandble", "understandable", - "understandbly", "understandably", - "underwealming", "underwhelming", - "underwhemling", "underwhelming", - "underwhleming", "underwhelming", - "undoctrinated", "indoctrinated", - "unexpectadely", "unexpectedly", - "unfomfortable", "uncomfortable", - "unforgiveable", "unforgivable", - "unfortuantely", "unfortunately", - "unfortunantly", "unfortunately", - "unfortunatley", "unfortunately", - "unfortuneatly", "unfortunately", - "unfortunetely", "unfortunately", - "unilaterallly", "unilaterally", - "uninstallling", "uninstalling", - "unintellegent", "unintelligent", - "unintelligant", "unintelligent", - "unintensional", "unintentional", - "uninteristing", "uninteresting", - "universitites", "universities", - "unnecassarily", "unnecessarily", - "unneccesarily", "unnecessarily", - "unnecessairly", "unnecessarily", - "unnecessarely", "unnecessarily", - "unnecessarity", "unnecessarily", - "unnecesserily", "unnecessarily", - "unnecissarily", "unnecessarily", - "unnessecarily", "unnecessarily", - "unoperational", "nonoperational", - "unprecendeted", "unprecedented", - "unprecidented", "unprecedented", - "unpredecented", "unprecedented", - "unpredicatble", "unpredictable", - "unpredictible", "unpredictable", - "unpresedented", "unprecedented", - "unpridictable", "unpredictable", - "unprofessinal", "unprofessional", - "unrealistisch", "unrealistic", - "unreasonabley", "unreasonably", - "unreasonablly", "unreasonably", - "unrestrictred", "unrestricted", - "unsistainable", "unsustainable", - "unsubscribade", "unsubscribed", - "unsubscribbed", "unsubscribe", - "unsuccesfully", "unsuccessfully", - "unsuccessfull", "unsuccessful", - "unsucessfully", "unsuccessfully", - "unsuprisingly", "unsurprisingly", - "unsuprizingly", "unsurprisingly", - "unsustainible", "unsustainable", - "unsustianable", "unsustainable", - "vertification", "certification", - "villification", "vilification", - "virualization", "visualization", - "visualizacion", "visualization", - "visualizaiton", "visualization", - "visualizating", "visualization", - "vitualization", "visualization", - "vizualization", "visualization", - "volounteering", "volunteering", - "vulberability", "vulnerability", - "vulernability", "vulnerability", - "vulnarability", "vulnerability", - "vulnerabiltiy", "vulnerability", - "vulnurability", "vulnerability", - "vunlerability", "vulnerability", - "vurnerability", "vulnerability", - "weightlfiting", "weightlifting", - "weightlifitng", "weightlifting", - "weightligting", "weightlifting", - "weigthlifting", "weightlifting", - "wholeheartdly", "wholeheartedly", - "wholeheartedy", "wholeheartedly", - "wholeheartely", "wholeheartedly", - "wieghtlifting", "weightlifting", - "abberivation", "abbreviation", - "abberviation", "abbreviation", - "abbreivation", "abbreviation", - "abbreveation", "abbreviation", - "abbrievation", "abbreviation", - "abortificant", "abortifacient", - "abrreviation", "abbreviation", - "academcially", "academically", - "accedentally", "accidentally", - "accelarating", "accelerating", - "accelaration", "acceleration", - "acceleartion", "acceleration", - "acceleraptor", "accelerator", - "accelorating", "accelerating", - "accessibilty", "accessibility", - "accidentlaly", "accidently", - "accomadating", "accommodating", - "accomadation", "accommodation", - "accomodating", "accommodating", - "accomodation", "accommodation", - "accrediation", "accreditation", - "acculumation", "accumulation", - "accumalation", "accumulation", - "accumilation", "accumulation", - "acedemically", "academically", - "acheivements", "achievements", - "acknolwedged", "acknowledged", - "acknolwedges", "acknowledges", - "acknoweldged", "acknowledged", - "acknoweldges", "acknowledges", - "acknowiedged", "acknowledged", - "acknowladges", "acknowledges", - "acknowldeged", "acknowledged", - "acknowledget", "acknowledgement", - "acknowleding", "acknowledging", - "acknowlegded", "acknowledged", - "acknowlegdes", "acknowledges", - "ackumulation", "accumulation", - "acquaintaces", "acquaintances", - "acquaintence", "acquaintance", - "acquantaince", "acquaintance", - "acquantiance", "acquaintances", - "acquiantance", "acquaintances", - "acquiantence", "acquaintance", - "adknowledged", "acknowledged", - "adknowledges", "acknowledges", - "administored", "administer", - "adminsitered", "administered", - "adminstrator", "administrator", - "advantagious", "advantageous", - "advantegeous", "advantageous", - "adventageous", "advantageous", - "adventureous", "adventures", - "adventureres", "adventures", - "adventurious", "adventurous", - "adventuruous", "adventurous", - "advertisiers", "advertisers", - "advertisment", "advertisement", - "advertisters", "advertisers", - "advertisting", "advertising", - "aestheticaly", "aesthetically", - "aestheticlly", "aesthetically", - "afficianados", "aficionados", - "afficionados", "aficionados", - "afghanisthan", "afghanistan", - "afterhtought", "afterthought", - "afterthougth", "afterthought", - "aggressivley", "aggressively", - "agircultural", "agricultural", - "agknowledged", "acknowledged", - "agnosticisim", "agnosticism", - "agracultural", "agricultural", - "agriculteral", "agricultural", - "agriculteurs", "agriculture", - "agricultrual", "agricultural", - "agriculutral", "agricultural", - "agrigultural", "agricultural", - "agrocultural", "agricultural", - "allegiancies", "allegiance", - "alterantives", "alternatives", - "alternatevly", "alternately", - "alternatiely", "alternately", - "alternatieve", "alternative", - "alternativly", "alternatively", - "alternativos", "alternatives", - "alternatvely", "alternately", - "alternitives", "alternatives", - "altruistisch", "altruistic", - "amendmenters", "amendments", - "amohetamines", "amphetamines", - "ampehtamines", "amphetamines", - "ampethamines", "amphetamines", - "amphatamines", "amphetamines", - "amphedamines", "amphetamines", - "amphetamenes", "amphetamines", - "amphetemines", "amphetamines", - "amphetimines", "amphetamines", - "amphetmaines", "amphetamines", - "anecdotallly", "anecdotally", - "annhiliation", "annihilation", - "annihalition", "annihilation", - "annihilatron", "annihilation", - "annihliation", "annihilation", - "annilihation", "annihilation", - "anniversairy", "anniversary", - "anniversarry", "anniversary", - "anniversiary", "anniversary", - "annoucenment", "announcements", - "annoucnement", "announcement", - "announcemnet", "announcements", - "announcemnts", "announcements", - "anphetamines", "amphetamines", - "ansalisation", "nasalisation", - "ansalization", "nasalization", - "antaganistic", "antagonistic", - "antagonisitc", "antagonistic", - "antagonostic", "antagonist", - "antibioticos", "antibiotics", - "anticiaption", "anticipation", - "anticipacion", "anticipation", - "antisipation", "anticipation", - "antogonistic", "antagonistic", - "antrhopology", "anthropology", - "antrophology", "anthropology", - "apllications", "applications", - "apocalypitic", "apocalyptic", - "apologistics", "apologists", - "apologizeing", "apologizing", - "apostrophied", "apostrophe", - "apostrophies", "apostrophe", - "apperciation", "appreciation", - "applicaitons", "applications", - "appoitnments", "appointments", - "apporachable", "approachable", - "appraochable", "approachable", - "appreceating", "appreciating", - "appreciaters", "appreciates", - "appreciatied", "appreciative", - "appreicating", "appreciating", - "appreication", "appreciation", - "appretiation", "appreciation", - "appropriatin", "appropriation", - "appropriatly", "appropriately", - "appropriaton", "appropriation", - "approprietly", "appropriately", - "approstraphe", "apostrophe", - "approxiately", "approximately", - "approximatly", "approximately", - "approximetly", "approximately", - "aproximately", "approximately", - "aqcuaintance", "acquaintance", - "aqquaintance", "acquaintance", - "arbitrariliy", "arbitrarily", - "arbitrarilly", "arbitrarily", - "archetecture", "architecture", - "architechure", "architecture", - "architectual", "architectural", - "architectuur", "architecture", - "architecutre", "architecture", - "architexture", "architecture", - "arcitechture", "architecture", - "areodynamics", "aerodynamics", - "argicultural", "agricultural", - "argumentatie", "argumentative", - "arithmetisch", "arithmetic", - "armageddomon", "armageddon", - "arrengements", "arrangements", - "articifially", "artificially", - "artificailly", "artificially", - "artificiella", "artificial", - "artificually", "artificially", - "artifiically", "artificially", - "assasination", "assassination", - "assassinatin", "assassination", - "assissinated", "assassinated", - "associationg", "associating", - "assoications", "associations", - "assosiations", "associations", - "assosication", "assassination", - "assotiations", "associations", - "assymetrical", "asymmetrical", - "asthetically", "aesthetically", - "astranomical", "astronomical", - "astromonical", "astronomical", - "astronautlis", "astronauts", - "astronimical", "astronomical", - "astronomicly", "astronomical", - "athleticisim", "athleticism", - "atmosphereic", "atmospheric", - "audiobookmrs", "audiobooks", - "auhtenticate", "authenticate", - "australianas", "australians", - "australianos", "australians", - "authentisity", "authenticity", - "authorithies", "authorities", - "authoritiers", "authorities", - "authorizaton", "authorization", - "authrorities", "authorities", - "autochtonous", "autochthonous", - "autocorrrect", "autocorrect", - "automobilies", "automobile", - "automodertor", "automoderator", - "automonomous", "autonomous", - "auxilliaries", "auxiliaries", - "avaliability", "availability", - "avialability", "availability", - "awknowledged", "acknowledged", - "awknowledges", "acknowledges", - "awkwardsness", "awkwardness", - "babysittting", "babysitting", - "beaurocratic", "bureaucratic", - "beautifullly", "beautifully", - "belligerante", "belligerent", - "beuraucratic", "bureaucratic", - "billionairre", "billionaire", - "billionaries", "billionaires", - "billioniares", "billionaires", - "bioligically", "biologically", - "birmingharam", "birmingham", - "bittersweeet", "bittersweet", - "blamethrower", "flamethrower", - "blueberrries", "blueberries", - "blueprintcss", "blueprints", - "boardcasting", "broadcasting", - "bobybuilding", "bodybuilding", - "bodybuidling", "bodybuilding", - "bodybuilidng", "bodybuilding", - "bodybuliding", "bodybuilding", - "bodydbuilder", "bodybuilder", - "bombardement", "bombardment", - "boradcasting", "broadcasting", - "botivational", "motivational", - "brainwahsing", "brainwashing", - "brakethrough", "breakthrough", - "braodcasting", "broadcasting", - "brazilianese", "brazilians", - "brazilianess", "brazilians", - "breakthorugh", "breakthrough", - "breaktrhough", "breakthrough", - "breastfeedig", "breastfeeding", - "breastfeeing", "breastfeeding", - "breasttaking", "breathtaking", - "brianwashing", "brainwashing", - "broadcastors", "broadcasts", - "brotherhoood", "brotherhood", - "buearucratic", "bureaucratic", - "bueraucratic", "bureaucratic", - "bulletprooof", "bulletproof", - "bureaocratic", "bureaucratic", - "bureaucracie", "bureaucratic", - "bureaucracts", "bureaucrats", - "bureaucrates", "bureaucrats", - "bureuacratic", "bureaucratic", - "businessemen", "businessmen", - "cababilities", "capabilities", - "caclulations", "calculations", - "calcluations", "calculation", - "calcualtions", "calculations", - "calculationg", "calculating", - "calculatoare", "calculator", - "californains", "californian", - "californican", "californian", - "californinan", "californian", - "caluclations", "calculations", - "camouflagued", "camouflage", - "canceltation", "cancellation", - "cannibalisim", "cannibalism", - "canniballism", "cannibalism", - "cannotations", "connotations", - "capitalistes", "capitalists", - "caracterized", "characterized", - "carbohydrats", "carbohydrates", - "carbohyrdate", "carbohydrates", - "caricaturale", "caricature", - "caricaturile", "caricature", - "caricaturise", "caricature", - "caricaturize", "caricature", - "catastraphic", "catastrophic", - "catastrohpic", "catastrophic", - "catastrophie", "catastrophe", - "categoricaly", "categorically", - "categoriezed", "categorized", - "catergorized", "categorized", - "caterpillers", "caterpillars", - "catestrophic", "catastrophic", - "catholicisim", "catholicism", - "catholocisim", "catholicism", - "catistrophic", "catastrophic", - "catostraphic", "catastrophic", - "catostrophic", "catastrophic", - "catterpilars", "caterpillars", - "catterpillar", "caterpillar", - "celebratings", "celebrations", - "celebritites", "celebrities", - "celibrations", "celebrations", - "cententenial", "centennial", - "cercumstance", "circumstance", - "cerification", "verification", - "certificiate", "certificate", - "challengeing", "challenging", - "chamiponship", "championships", - "champinoship", "championships", - "championchip", "championship", - "championsihp", "championships", - "championsips", "championships", - "champiosnhip", "championships", - "champoinship", "championship", - "chanpionship", "championship", - "charactarize", "characterize", - "charaterized", "characterized", - "charismastic", "charismatic", - "cheerlearder", "cheerleader", - "cheerleeders", "cheerleaders", - "cheeseberger", "cheeseburger", - "cheeseborger", "cheeseburger", - "cheesebruger", "cheeseburgers", - "cheeseburges", "cheeseburgers", - "cheeseburgie", "cheeseburger", - "cheezeburger", "cheeseburger", - "chirstianity", "christianity", - "chocolateers", "chocolates", - "chrisitanity", "christianity", - "christainity", "christianity", - "christiantiy", "christianity", - "christinaity", "christianity", - "chromosomers", "chromosomes", - "chronologial", "chronological", - "chrsitianity", "christianity", - "cilivization", "civilizations", - "circulatiing", "circulating", - "circulationg", "circulating", - "circumcisied", "circumcised", - "circumcition", "circumcision", - "circumsicion", "circumcision", - "circumsision", "circumcision", - "circumsition", "circumcision", - "circumsizion", "circumcision", - "circumstanes", "circumstance", - "circumstanta", "circumstantial", - "circumstante", "circumstance", - "circuncision", "circumcision", - "circunstance", "circumstance", - "civiliaztion", "civilizations", - "civilizacion", "civilization", - "civilizaiton", "civilization", - "civilizatoin", "civilizations", - "civilizatons", "civilizations", - "civilziation", "civilizations", - "civizilation", "civilizations", - "claculations", "calculations", - "classificato", "classification", - "cockroachers", "cockroaches", - "coefficienct", "coefficient", - "coencidental", "coincidental", - "coincedental", "coincidental", - "coincidencal", "coincidental", - "coincidentia", "coincidental", - "coindidental", "coincidental", - "coinsidental", "coincidental", - "cointerpoint", "counterpoint", - "collaberator", "collaborate", - "collaboratie", "collaborate", - "collaboratin", "collaboration", - "collectivily", "collectively", - "collectivley", "collectively", - "colonialisim", "colonialism", - "colonizacion", "colonization", - "colonizators", "colonizers", - "colonozation", "colonization", - "combanations", "combinations", - "combonations", "combinations", - "comdemnation", "condemnation", - "comemmorates", "commemorates", - "comemoretion", "commemoration", - "comeptitions", "competitions", - "comfirmation", "confirmation", - "comfortabley", "comfortably", - "comfortablly", "comfortably", - "comissioning", "commissioning", - "commandemnts", "commandment", - "commandmants", "commandments", - "commandmends", "commandments", - "commemmorate", "commemorate", - "commendments", "commandments", - "commenteries", "commenters", - "commenwealth", "commonwealth", - "commerciales", "commercials", - "commerically", "commercially", - "comminicated", "communicated", - "commishioned", "commissioned", - "commishioner", "commissioner", - "commisioning", "commissioning", - "commissionar", "commissioner", - "commissionor", "commissioner", - "committments", "commitments", - "commoditites", "commodities", - "commomwealth", "commonwealth", - "commonhealth", "commonwealth", - "commonweatlh", "commonwealth", - "commonwelath", "commonwealth", - "communciated", "communicated", - "communiation", "communication", - "communicatie", "communicate", - "communicatin", "communications", - "communicaton", "communication", - "communitites", "communities", - "compansating", "compensating", - "compansation", "compensation", - "comparativly", "comparatively", - "comparisions", "comparisons", - "comparission", "comparisons", - "comparissons", "comparisons", - "compatablity", "compatibility", - "compatibiliy", "compatibility", - "compatibilty", "compatibility", - "compatiblity", "compatibility", - "compensacion", "compensation", - "compensative", "compensate", - "compesitions", "compositions", - "competetions", "competitions", - "competitevly", "competitively", - "competitiion", "competition", - "competitiors", "competitors", - "competitivly", "competitively", - "competitivos", "competitions", - "compinsating", "compensating", - "compinsation", "compensation", - "complainging", "complaining", - "completetion", "completion", - "compliations", "compilation", - "complicacion", "complication", - "complicatied", "complicate", - "complicaties", "complicate", - "complicatred", "complicate", - "complicatted", "complicate", - "complilation", "complication", - "complimation", "complication", - "complimenary", "complimentary", - "complimentje", "complimented", - "complimentry", "complimentary", - "complination", "complication", - "complitation", "complication", - "composistion", "compositions", - "compramising", "compromising", - "compremising", "compromising", - "compresssion", "compression", - "compromissen", "compromise", - "compromisses", "compromises", - "compromizing", "compromising", - "compromosing", "compromising", - "comptability", "compatibility", - "compulsivley", "compulsive", - "compulsorary", "compulsory", - "computarized", "computerized", - "comrpomising", "compromising", - "comtaminated", "contaminated", - "comtemporary", "contemporary", - "conbinations", "combinations", - "concatinated", "contaminated", - "conceivabley", "conceivably", - "concellation", "cancellation", - "concentraded", "concentrated", - "concentraing", "concentrating", - "concentraion", "concentration", - "concentrarte", "concentrate", - "concentratie", "concentrate", - "concentratin", "concentration", - "concequences", "consequences", - "concequently", "consequently", - "concersation", "conservation", - "concervation", "conservation", - "concervatism", "conservatism", - "concervative", "conservative", - "conciderable", "considerable", - "conciderably", "considerably", - "conciousness", "consciousness", - "conclusiones", "conclusions", - "conclusivley", "conclusive", - "condamnation", "condemnation", - "condemantion", "condemnation", - "condenmation", "condemnation", - "condescening", "condescending", - "condescenion", "condescension", - "conditionnal", "conditional", - "conditionned", "conditioned", - "conditionner", "conditioner", - "condmenation", "condemnation", - "condolencies", "condolences", - "condolensces", "condolences", - "condomnation", "condemnation", - "condradicted", "contradicted", - "conenctivity", "connectivity", - "confedential", "confidential", - "confederancy", "confederacy", - "confederatie", "confederate", - "confermation", "confirmation", - "confersation", "conservation", - "confessionis", "confessions", - "confidencial", "confidential", - "confidentail", "confidential", - "confidentaly", "confidently", - "confidentely", "confidently", - "confidentiel", "confidential", - "configuratin", "configurations", - "configuraton", "configuration", - "confirmacion", "confirmation", - "confrimation", "confirmation", - "confrontaion", "confrontation", - "congegration", "congregation", - "congergation", "congregation", - "congradulate", "congratulate", - "congragation", "congregation", - "congragulate", "congratulate", - "congratualte", "congratulate", - "congregacion", "congregation", - "congresional", "congressional", - "congresssman", "congressman", - "congresssmen", "congressmen", - "congretation", "congregation", - "congrigation", "congregation", - "conicidental", "coincidental", - "connatations", "connotations", - "connecticuit", "connecticut", - "connectivety", "connectivity", - "connetations", "connotations", - "connitations", "connotations", - "connonations", "connotations", - "conolization", "colonization", - "conpensating", "compensating", - "conpensation", "compensation", - "conpetitions", "competitions", - "conplimented", "complimented", - "conpromising", "compromising", - "consciouness", "consciousness", - "consciouslly", "consciously", - "consectutive", "consecutive", - "consecuences", "consequences", - "consecuentes", "consequences", - "consecuently", "consequently", - "consensuarlo", "consensual", - "consentrated", "concentrated", - "consentrates", "concentrates", - "conseqeunces", "consequence", - "consequenses", "consequences", - "consequental", "consequently", - "consequneces", "consequence", - "conservacion", "conservation", - "conservaties", "conservatives", - "conservativo", "conservation", - "conservativs", "conservatism", - "conservitave", "conservatives", - "conservitism", "conservatism", - "conservitive", "conservative", - "considerarle", "considerable", - "considerarte", "considerate", - "consideraste", "considerate", - "consideratie", "considerate", - "consideratin", "considerations", - "consideribly", "considerably", - "consilidated", "consolidated", - "consipracies", "conspiracies", - "consiquently", "consequently", - "consistantly", "consistently", - "consistencey", "consistency", - "consistentcy", "consistently", - "consitutents", "constituents", - "consoldiated", "consolidated", - "consolitated", "consolidate", - "consolodated", "consolidated", - "consoltation", "consultation", - "conspericies", "conspiracies", - "conspiracize", "conspiracies", - "conspiriator", "conspirator", - "conspiricies", "conspiracies", - "conspriacies", "conspiracies", - "consqeuences", "consequence", - "constinually", "continually", - "constitition", "constitution", - "constituante", "constituents", - "constituants", "constituents", - "constituates", "constitutes", - "constitucion", "constitution", - "constituient", "constitute", - "constituinte", "constituents", - "constitutiei", "constitute", - "constitutues", "constitute", - "constiutents", "constituents", - "constracting", "constructing", - "constraction", "construction", - "constrainsts", "constraints", - "construccion", "construction", - "construciton", "construction", - "constructeds", "constructs", - "constructief", "constructive", - "constructies", "constructs", - "constructifs", "constructs", - "constructiin", "constructing", - "constructivo", "construction", - "consturction", "construction", - "consultating", "consultation", - "consumerisim", "consumerism", - "contaiminate", "contaminate", - "contaminatie", "contaminated", - "contaminaton", "contamination", - "contaminents", "containment", - "contamporary", "contemporary", - "contanimated", "contaminated", - "contaniments", "containment", - "contemperary", "contemporary", - "contemporany", "contemporary", - "continentais", "continents", - "continential", "continental", - "contineously", "continuously", - "continiously", "continuously", - "continuacion", "continuation", - "continuating", "continuation", - "continuativo", "continuation", - "continuining", "continuing", - "contirbution", "contribution", - "contirbutors", "contributors", - "contiunation", "continuation", - "contrabution", "contribution", - "contraceptie", "contraceptives", - "contradicing", "contradicting", - "contradicion", "contradiction", - "contradicory", "contradictory", - "contradictie", "contradicted", - "contradictin", "contradiction", - "contradicton", "contradiction", - "contraticted", "contradicted", - "contribucion", "contribution", - "contribuitor", "contributor", - "contributers", "contributors", - "contributivo", "contribution", - "contributons", "contributors", - "contrictions", "contractions", - "contridicted", "contradicted", - "controlleras", "controllers", - "controlllers", "controllers", - "controverial", "controversial", - "controveries", "controversies", - "controversal", "controversial", - "controversey", "controversy", - "contructions", "contractions", - "conveinently", "conveniently", - "convencional", "conventional", - "conveniantly", "conveniently", - "converastion", "conversations", - "converdation", "conservation", - "conversacion", "conversation", - "conversaiton", "conversations", - "conversatino", "conservation", - "conversatism", "conservatism", - "conversatoin", "conversations", - "conversiones", "conversions", - "converstaion", "conversation", - "convertables", "convertibles", - "convertiable", "convertible", - "convertibile", "convertible", - "convervation", "conservation", - "convervatism", "conservatism", - "converzation", "conservation", - "convesration", "conservation", - "convienently", "conveniently", - "convorsation", "conversation", - "convseration", "conservation", - "coordenation", "coordination", - "coordiantion", "coordination", - "coordinacion", "coordination", - "coordinaters", "coordinates", - "coordinatior", "coordinator", - "coordinatore", "coordinate", - "coordonation", "coordination", - "cooridnation", "coordination", - "coorperation", "cooperation", - "coprorations", "corporations", - "corinthianos", "corinthians", - "corinthinans", "corinthians", - "corparations", "corporations", - "corperations", "corporations", - "corporativos", "corporations", - "corproations", "corporations", - "corrdination", "coordination", - "correponding", "corresponding", - "correposding", "corresponding", - "correspondes", "corresponds", - "correspondig", "corresponding", - "corresponing", "corresponding", - "corrisponded", "corresponded", - "costomizable", "customizable", - "costumizable", "customizable", - "councidental", "coincidental", - "counsellling", "counselling", - "counterfiets", "counterfeit", - "counterfited", "counterfeit", - "counterracts", "counterparts", - "countertraps", "counterparts", - "countrywides", "countryside", - "coutnerparts", "counterparts", - "coutnerpoint", "counterpoint", - "covnersation", "conservation", - "crankenstein", "frankenstein", - "creationisim", "creationism", - "creationnism", "creationism", - "creationnist", "creationist", - "creationsism", "creationism", - "creationsist", "creationist", - "creationsits", "creationists", - "credibillity", "credibility", - "crigneworthy", "cringeworthy", - "cringewhorty", "cringeworthy", - "cringeworhty", "cringeworthy", - "cringewrothy", "cringeworthy", - "cringyworthy", "cringeworthy", - "criticallity", "critically", - "criticiszing", "criticising", - "croporations", "corporations", - "crucifiction", "crucifixion", - "cuestionable", "questionable", - "culiminating", "culminating", - "cumulatative", "cumulative", - "cuntaminated", "contaminated", - "curcumcision", "circumcision", - "curcumstance", "circumstance", - "custamizable", "customizable", - "custimizable", "customizable", - "customizaton", "customization", - "customizeble", "customizable", - "customizible", "customizable", - "custumizable", "customizable", - "cuztomizable", "customizable", - "dabilitating", "debilitating", - "dangerousely", "dangerously", - "decensitized", "desensitized", - "deceptionist", "receptionist", - "declareation", "declaration", - "decomposeion", "decomposition", - "decomposited", "decomposed", - "decscription", "description", - "deffensively", "defensively", - "deficiancies", "deficiencies", - "deficiencias", "deficiencies", - "deficiensies", "deficiencies", - "definatively", "definitively", - "defininitely", "definitively", - "definitavely", "definitively", - "definitevely", "definitively", - "definitifely", "definitively", - "definitinely", "definitively", - "definititely", "definitively", - "definitivley", "definitively", - "deinitalized", "deinitialized", - "deinitalizes", "deinitializes", - "delibaretely", "deliberately", - "deliberatley", "deliberately", - "delibirately", "deliberately", - "delibitating", "debilitating", - "deliverately", "deliberately", - "delusionally", "delusively", - "demesticated", "domesticated", - "democracries", "democracies", - "democraphics", "demographics", - "democratisch", "democratic", - "demograhpics", "demographics", - "demogrpahics", "demographics", - "demonination", "denominations", - "demonstarted", "demonstrated", - "demonstartes", "demonstrates", - "demonstrabil", "demonstrably", - "demonstraion", "demonstration", - "demonstraits", "demonstrates", - "demonstrants", "demonstrates", - "demonstratie", "demonstrate", - "demonstratin", "demonstration", - "demonstrerat", "demonstrate", - "demosntrably", "demonstrably", - "demosntrated", "demonstrated", - "demosntrates", "demonstrates", - "demostration", "demonstration", - "denomenation", "denomination", - "denominacion", "denomination", - "denominatior", "denominator", - "denominatons", "denominations", - "denomonation", "denomination", - "deomgraphics", "demographics", - "depencencies", "dependencies", - "dependancies", "dependencies", - "dependencias", "dependencies", - "dependenices", "dependencies", - "dependensies", "dependencies", - "deperecation", "deprecation", - "deplacements", "replacements", - "deregualtion", "deregulation", - "deregulaiton", "deregulation", - "derugulation", "deregulation", - "describtions", "descriptions", - "descriminant", "discriminant", - "descriptivos", "descriptions", - "desctiptions", "descriptions", - "desctruction", "destruction", - "desencitized", "desensitized", - "desensatized", "desensitized", - "desensitived", "desensitized", - "desentisized", "desensitized", - "desentitized", "desensitized", - "desentizised", "desensitized", - "desginations", "destinations", - "desgustingly", "disgustingly", - "desitnations", "destinations", - "despectively", "respectively", - "despensaries", "dispensaries", - "desperatedly", "desperately", - "desperatelly", "desperately", - "desqualified", "disqualified", - "desregarding", "disregarding", - "dessertation", "dissertation", - "destiantions", "destinations", - "destinctions", "destinations", - "destractions", "distractions", - "destributors", "distributors", - "determinanti", "determination", - "determinaton", "determination", - "determinging", "determining", - "determinisic", "deterministic", - "determinisim", "determinism", - "deterministc", "deterministic", - "determinitic", "deterministic", - "detrimential", "detrimental", - "developement", "development", - "developmenet", "developments", - "develpoments", "developments", - "devolopement", "development", - "devolopments", "developments", - "diasspointed", "dissapointed", - "dicitonaries", "dictionaries", - "dictadorship", "dictatorship", - "dictarorship", "dictatorship", - "dictatorshop", "dictatorship", - "dictionaires", "dictionaries", - "didsapointed", "dissapointed", - "differencial", "differential", - "differencies", "differences", - "differentate", "differentiate", - "differnetial", "differential", - "difficulites", "difficulties", - "difficutlies", "difficulties", - "diffuculties", "difficulties", - "dimensionals", "dimensions", - "dimensionnal", "dimensional", - "dimensionsal", "dimensional", - "diplomatisch", "diplomatic", - "directionnal", "directional", - "disaapointed", "dissapointed", - "disadvandage", "disadvantaged", - "disadvantged", "disadvantaged", - "disadvantges", "disadvantages", - "disadvatange", "disadvantage", - "disadventage", "disadvantage", - "disagremeent", "disagreements", - "disapointing", "disappointing", - "disappearnce", "disappearance", - "disappearred", "disappeared", - "disapperaing", "disappearing", - "disaspointed", "dissapointed", - "disastisfied", "dissatisfied", - "disatissfied", "dissatisfied", - "disatvantage", "disadvantage", - "discertation", "dissertation", - "disciniplary", "disciplinary", - "disciplanary", "disciplinary", - "disciplenary", "disciplinary", - "disciplinare", "discipline", - "disciplinera", "disciplinary", - "disciplinery", "disciplinary", - "disclipinary", "disciplinary", - "disconencted", "disconnected", - "disconnectes", "disconnects", - "disconnectme", "disconnected", - "disconnectus", "disconnects", - "discontiuned", "discontinued", - "discountined", "discontinued", - "discreditied", "discredited", - "discreditted", "discredited", - "discriminare", "discriminate", - "discriminted", "discriminated", - "disctinction", "distinction", - "disctinctive", "distinctive", - "disctintions", "distinctions", - "discualified", "disqualified", - "discustingly", "disgustingly", - "disemination", "dissemination", - "disenchanged", "disenchanted", - "disengenuous", "disingenuous", - "disenginuous", "disingenuous", - "disensitized", "desensitized", - "disgareement", "disagreements", - "disgruntaled", "disgruntled", - "disgrunteled", "disgruntled", - "disguntingly", "disgustingly", - "disingeneous", "disingenuous", - "disingenious", "disingenuous", - "disinteresed", "disinterested", - "disintereted", "disinterested", - "dismantleing", "dismantling", - "disobediance", "disobedience", - "disobeidence", "disobedience", - "dispalcement", "displacement", - "dispapointed", "dissapointed", - "dispencaries", "dispensaries", - "dispensaires", "dispensaries", - "dispensarios", "dispensaries", - "dispensiries", "dispensaries", - "dispensories", "dispensaries", - "disqaulified", "disqualified", - "disqualifyed", "disqualified", - "disqustingly", "disgustingly", - "disrecpected", "disrespected", - "disrepsected", "disrespected", - "disresepcted", "disrespected", - "disrespecful", "disrespectful", - "disrespecing", "disrespecting", - "disrespectul", "disrespectful", - "disrespekted", "disrespected", - "disrtibution", "distributions", - "dissapearing", "disappearing", - "dissapionted", "dissapointed", - "dissapoimted", "dissapointed", - "dissapoitned", "dissapointed", - "dissaponited", "dissapointed", - "dissapoonted", "dissapointed", - "dissapounted", "dissapointed", - "dissappinted", "dissapointed", - "dissapponted", "dissapointed", - "dissastified", "dissatisfied", - "dissatisifed", "dissatisfied", - "dissatsified", "dissatisfied", - "dissepointed", "dissapointed", - "dissipointed", "dissapointed", - "dissobediant", "disobedient", - "dissobedient", "disobedient", - "dissopointed", "dissapointed", - "disspaointed", "dissapointed", - "dissppointed", "dissapointed", - "dissspointed", "dissapointed", - "distinations", "distinctions", - "distincitons", "distinctions", - "distingished", "distinguished", - "distingishes", "distinguishes", - "distinguised", "distinguished", - "distirbuting", "distributing", - "distirbution", "distribution", - "distrabution", "distribution", - "distribitors", "distributors", - "distribtuion", "distributions", - "distribucion", "distribution", - "distribuited", "distributed", - "distribuiton", "distributions", - "distribuitor", "distributor", - "distribusion", "distributions", - "distributino", "distributions", - "distributior", "distributor", - "distributons", "distributors", - "distributore", "distribute", - "distriubtion", "distributions", - "distrobution", "distribution", - "distrubances", "disturbance", - "distrubiting", "distributing", - "distrubition", "distribution", - "distrubitors", "distributors", - "distrubution", "distribution", - "distrubutors", "distributors", - "distructions", "distractions", - "distustingly", "disgustingly", - "ditactorship", "dictatorship", - "documenation", "documentation", - "documentaion", "documentation", - "documentaire", "documentaries", - "documentarse", "documentaries", - "documentarsi", "documentaries", - "domesitcated", "domesticated", - "domisticated", "domesticated", - "donesticated", "domesticated", - "donwloadable", "downloadable", - "dossapointed", "dissapointed", - "downlaodable", "downloadable", - "downloadbale", "downloadable", - "downloadeble", "downloadable", - "drankenstein", "frankenstein", - "dublications", "publications", - "dusgustingly", "disgustingly", - "dynamicallly", "dynamically", - "dyregulation", "deregulation", - "earthquackes", "earthquakes", - "earthquakers", "earthquakes", - "econimically", "economically", - "economisesti", "economists", - "educationnal", "educational", - "effectionate", "affectionate", - "effectivelly", "effectively", - "effectivenss", "effectiveness", - "efficienctly", "efficiency", - "effordlessly", "effortlessly", - "ejacualtions", "ejaculation", - "electorlytes", "electrolytes", - "electricrain", "electrician", - "electrictian", "electrician", - "electrobytes", "electrolytes", - "electrocytes", "electrolytes", - "electrolites", "electrolytes", - "electroltyes", "electrolytes", - "electronicas", "electronics", - "electronicos", "electronics", - "electroyltes", "electrolytes", - "elektrolytes", "electrolytes", - "eloctrolytes", "electrolytes", - "embarassment", "embarrassment", - "embarasssing", "embarassing", - "embarrasment", "embarrassment", - "embarressing", "embarrassing", - "embarrissing", "embarrassing", - "emberrassing", "embarrassing", - "emphetamines", "amphetamines", - "emprisonment", "imprisonment", - "encarcerated", "incarcerated", - "enceclopedia", "encyclopedia", - "enchancement", "enhancement", - "enchancments", "enchantments", - "enchantmants", "enchantments", - "enchentments", "enchantments", - "enciclopedia", "encyclopedia", - "enclycopedia", "encyclopedia", - "encorporated", "incorporated", - "encourageing", "encouraging", - "encyclapedia", "encyclopedia", - "encyclepedia", "encyclopedia", - "encyclopadia", "encyclopedia", - "encyclopeida", "encyclopedia", - "encyclopidia", "encyclopedia", - "encycolpedia", "encyclopedia", - "encyklopedia", "encyclopedia", - "encylcopedia", "encyclopedia", - "encyplopedia", "encyclopedia", - "endoresments", "endorsement", - "enemployment", "unemployment", - "enfringement", "infringement", - "enlightended", "enlightened", - "enlightenend", "enlightened", - "enlightented", "enlightened", - "enlightining", "enlightening", - "enligthening", "enlightening", - "entaglements", "entanglements", - "entartaining", "entertaining", - "enterpreneur", "entrepreneurs", - "enterprenuer", "entrepreneur", - "entertainted", "entertained", - "enthusiaists", "enthusiasts", - "enthusuastic", "enthusiastic", - "entoxication", "intoxication", - "entrepeneurs", "entrepreneurs", - "entreperneur", "entrepreneurs", - "entreprenaur", "entrepreneur", - "entrepreners", "entrepreneurs", - "entrepreneus", "entrepreneurs", - "entreprenour", "entrepreneur", - "entreprenure", "entrepreneurs", - "entreprenurs", "entrepreneurs", - "entrepreuner", "entrepreneurs", - "entretaining", "entertaining", - "enviormental", "environmental", - "enviornments", "environments", - "enviromental", "environmental", - "environemnts", "environments", - "environmentl", "environmentally", - "environmetal", "environmental", - "envrionments", "environments", - "establishmet", "establishments", - "evelutionary", "evolutionary", - "exagerrating", "exaggerating", - "exaggarating", "exaggerating", - "exaggaration", "exaggeration", - "exaggeratted", "exaggerated", - "exaggurating", "exaggerating", - "exagguration", "exaggeration", - "exceptionaly", "exceptionally", - "exceptionnal", "exceptional", - "exclusiveity", "exclusivity", - "exclusivelly", "exclusively", - "exclusivitiy", "exclusivity", - "excorciating", "excruciating", - "excrusiating", "excruciating", - "excurciating", "excruciating", - "exectuioners", "executioner", - "executioneer", "executioner", - "executionees", "executions", - "executioness", "executions", - "executionier", "executioner", - "executionner", "executioner", - "exeggerating", "exaggerating", - "exeggeration", "exaggeration", - "expeditonary", "expeditionary", - "expendatures", "expenditures", - "expendetures", "expenditures", - "expentitures", "expenditures", - "experamental", "experimental", - "expereincing", "experiencing", - "experemental", "experimental", - "experiancing", "experiencing", - "experiemntal", "experimental", - "experiemnted", "experimented", - "experimantal", "experimental", - "experimentan", "experimentation", - "experimentes", "experiments", - "experimentle", "experimented", - "experimentos", "experiments", - "experimentul", "experimental", - "expidentures", "expenditures", - "expierencing", "experiencing", - "expiremental", "experimental", - "expiremented", "experimented", - "explaination", "explanation", - "explenations", "explanations", - "expliotation", "exploitation", - "exploitaiton", "exploitation", - "exploitating", "exploitation", - "exploititive", "exploitative", - "explortation", "exploitation", - "explotiation", "exploitation", - "explotiative", "exploitative", - "expolitation", "exploitation", - "expolitative", "exploitative", - "exponentialy", "exponentially", - "expropiation", "expropriation", - "extensivelly", "extensively", - "extradiction", "extradition", - "extraordiary", "extraordinary", - "extraordinay", "extraordinary", - "extrapolerat", "extrapolate", - "extrapoloate", "extrapolate", - "extremistisk", "extremists", - "extrordinary", "extraordinary", - "extruciating", "excruciating", - "facilitatile", "facilitate", - "fahrenheight", "fahrenheit", - "falmethrower", "flamethrower", - "familiarlize", "familiarize", - "fanslaughter", "manslaughter", - "fantasticaly", "fantastically", - "fantasticlly", "fantastically", - "fashionalble", "fashionable", - "fermantation", "fermentation", - "fermentacion", "fermentation", - "fermentaiton", "fermentation", - "fermentating", "fermentation", - "fermintation", "fermentation", - "fictionaries", "dictionaries", - "figuartively", "figuratively", - "figuratevely", "figuratively", - "figurativley", "figuratively", - "figuretively", "figuratively", - "figuritively", "figuratively", - "fingerpoints", "fingerprints", - "firefigthers", "firefighters", - "flamethorwer", "flamethrower", - "flametrhower", "flamethrower", - "flanethrower", "flamethrower", - "flexibillity", "flexibility", - "flourishment", "flourishing", - "fluctiations", "fluctuations", - "flucutations", "fluctuations", - "fluxtuations", "fluctuations", - "forgivenness", "forgiveness", - "fortunatelly", "fortunately", - "framethrower", "flamethrower", - "frankenstain", "frankenstein", - "frankensteen", "frankenstein", - "frankenstine", "frankenstein", - "frankinstein", "frankenstein", - "frementation", "fermentation", - "friendzonded", "friendzoned", - "friendzonned", "friendzoned", - "friendzowned", "friendzoned", - "fringeworthy", "cringeworthy", - "fronkenstein", "frankenstein", - "fruitsations", "frustrations", - "frustrastion", "frustrations", - "fucntionally", "functionally", - "funcitonally", "functionally", - "functionable", "functional", - "functionaliy", "functionally", - "functionalty", "functionality", - "functionlity", "functionality", - "functionning", "functioning", - "fundamentais", "fundamentals", - "fundamentalt", "fundamentalist", - "fundamentaly", "fundamentally", - "fundemantals", "fundamentals", - "fundementals", "fundamentals", - "fundimentals", "fundamentals", - "furstrations", "frustrations", - "futuristisch", "futuristic", - "fwankenstein", "frankenstein", - "geneological", "genealogical", - "generacional", "generational", - "generalizare", "generalize", - "generalizate", "generalize", - "generelizing", "generalizing", - "geograhpical", "geographical", - "geographicly", "geographical", - "geographisch", "geographic", - "geogrpahical", "geographical", - "goegraphical", "geographical", - "governemntal", "governmental", - "governmently", "governmental", - "grammaticaal", "grammatical", - "grammaticaly", "grammatically", - "grandchilden", "grandchildren", - "grandchilder", "grandchildren", - "grandchilren", "grandchildren", - "grassrooters", "grassroots", - "gringeworthy", "cringeworthy", - "guantanameow", "guantanamo", - "guantanamero", "guantanamo", - "hallucinatin", "hallucinations", - "hallucinaton", "hallucination", - "handwritting", "handwriting", - "harrassments", "harassments", - "headqaurters", "headquarters", - "headquatered", "headquartered", - "healthercare", "healthcare", - "heavywieghts", "heavyweight", - "helicopteros", "helicopters", - "hererosexual", "heterosexual", - "heretosexual", "heterosexual", - "heteresexual", "heterosexual", - "hetreosexual", "heterosexual", - "highligthing", "highlighting", - "hipocritical", "hypocritical", - "hipothetical", "hypothetical", - "histarically", "historically", - "histerically", "historically", - "historicians", "historians", - "homogeneized", "homogenized", - "homogenenous", "homogeneous", - "homosexuales", "homosexuals", - "homosexualiy", "homosexuality", - "homosexualls", "homosexuals", - "homosexualty", "homosexuality", - "homosexuella", "homosexual", - "hopsitalized", "hospitalized", - "horisontally", "horizontally", - "horizantally", "horizontally", - "horiztonally", "horizontally", - "horozontally", "horizontally", - "hospitallity", "hospitality", - "hospitilized", "hospitalized", - "hospitolized", "hospitalized", - "hosptialized", "hospitalized", - "humanitarien", "humanitarian", - "humanitarion", "humanitarian", - "humanitatian", "humanitarian", - "humaniterian", "humanitarian", - "humantiarian", "humanitarian", - "huminatarian", "humanitarian", - "hurricanefps", "hurricanes", - "hyopthetical", "hypothetical", - "hypathetical", "hypothetical", - "hypertrophey", "hypertrophy", - "hypethetical", "hypothetical", - "hypocrticial", "hypocritical", - "hypocrytical", "hypocritical", - "hypotehtical", "hypothetical", - "hypotethical", "hypothetical", - "hypotherical", "hypothetical", - "hypotheticly", "hypothetical", - "hystarically", "hysterically", - "hystorically", "hysterically", - "idealistisch", "idealistic", - "identificato", "identification", - "identifierad", "identified", - "identifieras", "identifies", - "identifyable", "identifiable", - "ideologicaly", "ideologically", - "idiosyncracy", "idiosyncrasy", - "illegetimate", "illegitimate", - "illegitamate", "illegitimate", - "illegitamite", "illegitimate", - "illegitemate", "illegitimate", - "illegitimite", "illegitimate", - "illigetimate", "illegitimate", - "illigitemate", "illegitimate", - "illistration", "illustration", - "illsutration", "illustrations", - "illustartion", "illustration", - "illustraitor", "illustrator", - "illustraties", "illustrate", - "illustratior", "illustrator", - "imcompatible", "incompatible", - "imcompetence", "incompetence", - "imexperience", "inexperience", - "immediatelly", "immediately", - "immortallity", "immortality", - "imperialfist", "imperialist", - "imperialisim", "imperialism", - "imperialstic", "imperialist", - "implamenting", "implementing", - "implausibile", "implausible", - "implecations", "implications", - "implementase", "implements", - "implementasi", "implements", - "implementato", "implementation", - "implentation", "implementation", - "implimenting", "implementing", - "imporvements", "improvements", - "impossibilty", "impossibility", - "impossiblely", "impossibly", - "impossiblity", "impossibly", - "impovershied", "impoverished", - "impoversihed", "impoverished", - "imprefection", "imperfections", - "improsonment", "imprisonment", - "improviserad", "improvised", - "imrpovements", "improvements", - "imtimidating", "intimidating", - "imtimidation", "intimidation", - "inaccesibles", "inaccessible", - "inaccessable", "inaccessible", - "inaccessbile", "inaccessible", - "inaccurasies", "inaccuracies", - "inaccuraties", "inaccuracies", - "inaccuricies", "inaccuracies", - "inacuraccies", "inaccuracies", - "inadvertenly", "inadvertently", - "inappropiate", "inappropriate", - "inapproprate", "inappropriate", - "inappropriae", "inappropriately", - "inappropriet", "inappropriately", - "inattractive", "unattractive", - "inbelievable", "unbelievable", - "incarcelated", "incarcerated", - "incarcirated", "incarcerated", - "incarserated", "incarcerated", - "incedentally", "incidentally", - "incentiveise", "incentives", - "incestigator", "investigator", - "incomaptible", "incompatible", - "incomparible", "incompatible", - "incompatable", "incompatible", - "incompatibil", "incompatible", - "incompetance", "incompetence", - "incompetente", "incompetence", - "incompitable", "incompatible", - "incomptetent", "incompetent", - "inconcistent", "inconsistent", - "inconsistant", "inconsistent", - "inconsistecy", "inconsistency", - "inconsisteny", "inconsistency", - "inconveinent", "inconvenient", - "inconveniant", "inconvenient", - "inconveniece", "inconvenience", - "inconvenince", "inconvenience", - "inconvienent", "inconvenient", - "incorparated", "incorporated", - "incorperated", "incorporated", - "incorportaed", "incorporated", - "incorportate", "incorporate", - "incrediblely", "incredibly", - "incrementers", "increments", - "incremential", "incremental", - "indefinately", "indefinitely", - "indefineable", "undefinable", - "indefinetely", "indefinitely", - "indefinitive", "indefinite", - "indefinitley", "indefinitely", - "indefintiely", "indefinitely", - "indepedantly", "independently", - "indepencence", "independence", - "independance", "independence", - "independante", "independents", - "independenet", "independents", - "independenly", "independently", - "independense", "independents", - "independente", "independence", - "independetly", "independently", - "indepentents", "independents", - "indetifiable", "identifiable", - "indianaoplis", "indianapolis", - "indianopolis", "indianapolis", - "indicentally", "incidentally", - "indifferance", "indifference", - "indifferente", "indifference", - "indiffernece", "indifference", - "indimidating", "intimidating", - "indimidation", "intimidation", - "indipendence", "independence", - "indisputible", "indisputable", - "indisputibly", "indisputably", - "individuales", "individuals", - "individualty", "individuality", - "individuella", "individual", - "indiviudally", "individually", - "indivudually", "individually", - "indpendently", "independently", - "indroduction", "introduction", - "indroductory", "introductory", - "industriella", "industrial", - "industrijske", "industries", - "inefficienct", "inefficient", - "inefficienty", "inefficiently", - "inevitablely", "inevitably", - "inevitablity", "inevitably", - "inevititably", "inevitably", - "inexblicably", "inexplicably", - "inexpectedly", "unexpectedly", - "inexpereince", "inexperience", - "inexperiance", "inexperience", - "inexperieced", "inexperienced", - "inexperiened", "inexperienced", - "inexperiente", "inexperience", - "inexpierence", "inexperienced", - "inexplicabil", "inexplicably", - "inexplicibly", "inexplicably", - "infalability", "infallibility", - "infilitrated", "infiltrated", - "infiltraitor", "infiltrator", - "infiltratior", "infiltrator", - "infiltratred", "infiltrate", - "influenceing", "influencing", - "infogrpahics", "infographic", - "inforgivable", "unforgivable", - "infrantryman", "infantryman", - "infridgement", "infringement", - "infrignement", "infringement", - "ingestigator", "investigator", - "ingredientes", "ingredients", - "ingreediants", "ingredients", - "ininterested", "uninterested", - "initalizable", "initializable", - "inkompatible", "incompatible", - "inkompetence", "incompetence", - "inkonsistent", "inconsistent", - "inlightening", "enlightening", - "innersection", "intersection", - "innerstellar", "interstellar", - "inpenetrable", "impenetrable", - "inplementing", "implementing", - "inplications", "implications", - "inpoverished", "impoverished", - "inprisonment", "imprisonment", - "inproductive", "unproductive", - "inprovements", "improvements", - "inresponsive", "unresponsive", - "insentivised", "insensitive", - "insentivises", "insensitive", - "insignifiant", "insignificant", - "insignificat", "insignificant", - "insinuationg", "insinuating", - "instabillity", "instability", - "instalaltion", "installations", - "installatons", "installations", - "installatron", "installation", - "instantaneos", "instantaneous", - "instantaneus", "instantaneous", - "instantanous", "instantaneous", - "instinctivly", "instinctively", - "institutuion", "institution", - "instramental", "instrumental", - "instrcutions", "instruction", - "instrucitons", "instruction", - "instructiosn", "instruction", - "instructores", "instructors", - "instrumentos", "instruments", - "instrumentul", "instrumental", - "insturmental", "instrumental", - "instutitions", "institutions", - "insuccessful", "unsuccessful", - "insufficiant", "insufficient", - "insuffucient", "insufficient", - "insuspecting", "unsuspecting", - "intaxication", "intoxication", - "intelelctual", "intellectuals", - "intellectals", "intellectuals", - "intellectaul", "intellectuals", - "intellectuel", "intellectual", - "intellecutal", "intellectual", - "intelligance", "intelligence", - "intelligenly", "intelligently", - "intelligente", "intelligence", - "intelligenty", "intelligently", - "intelligient", "intelligent", - "intenational", "international", - "intentionnal", "intentional", - "intepretator", "interpretor", - "interatellar", "interstellar", - "interational", "international", - "intercection", "interception", - "intercepcion", "interception", - "interceptons", "interceptions", - "intereaction", "intersection", - "interections", "interactions", - "interersting", "interpreting", - "interesction", "intersection", - "interestigly", "interestingly", - "interestinly", "interestingly", - "interferance", "interference", - "interfereing", "interfering", - "interferisce", "interferes", - "interferisse", "interferes", - "interferring", "interfering", - "intergration", "integration", - "interlectual", "intellectual", - "intermediare", "intermediate", - "intermediete", "intermediate", - "intermettent", "intermittent", - "intermideate", "intermediate", - "intermidiate", "intermediate", - "internatinal", "international", - "internationl", "international", - "internations", "interactions", - "internediate", "intermediate", - "internelized", "internalized", - "internilized", "internalized", - "interperters", "interpreter", - "interperting", "interpreting", - "interprating", "interpreting", - "interpretare", "interpreter", - "interpretato", "interpretation", - "interpreteer", "interpreter", - "interpretier", "interpreter", - "interpretion", "interpreting", - "interpretter", "interpreter", - "interpriting", "interpreting", - "interraccial", "interracial", - "interractial", "interracial", - "interrogatin", "interrogation", - "interrumping", "interrupting", - "interrupteds", "interrupts", - "interruptors", "interrupts", - "interseccion", "intersection", - "interseciton", "intersections", - "interseption", "interception", - "intersetllar", "interstellar", - "interstallar", "interstellar", - "interstaller", "interstellar", - "intersteller", "interstellar", - "interstellor", "interstellar", - "intertaining", "entertaining", - "intertwinded", "intertwined", - "intertwinned", "intertwined", - "interveiwing", "interviewing", - "intervencion", "intervention", - "interveneing", "intervening", - "intervension", "intervention", - "interviening", "interviewing", - "intidimation", "intimidation", - "intillectual", "intellectual", - "intimidacion", "intimidation", - "intimidative", "intimidate", - "intimitading", "intimidating", - "intimitating", "intimidating", - "intimitation", "intimidation", - "intorduction", "introduction", - "intorductory", "introductory", - "intoxicacion", "intoxication", - "intoxination", "intoxication", - "intrepreting", "interpreting", - "intrinsicaly", "intrinsically", - "introdiction", "introduction", - "introduccion", "introduction", - "introduceras", "introduces", - "introduceres", "introduces", - "introduciton", "introduction", - "introductary", "introductory", - "introducting", "introduction", - "introductury", "introductory", - "introduktion", "introduction", - "introspectin", "introspection", - "intruduction", "introduction", - "intruductory", "introductory", - "intsrumental", "instrumental", - "intuitivelly", "intuitively", - "inturrupting", "interrupting", - "invervention", "intervention", - "investagated", "investigated", - "investagator", "investigator", - "investegated", "investigated", - "investegator", "investigator", - "investigaron", "investigator", - "investigater", "investigator", - "investigatie", "investigative", - "investigatin", "investigation", - "investigatio", "investigator", - "investigaton", "investigation", - "investingate", "investigate", - "investogator", "investigator", - "invicibility", "invisibility", - "invididually", "individually", - "invisibiltiy", "invisibility", - "invisilibity", "invisibility", - "invisivility", "invisibility", - "invlunerable", "invulnerable", - "involnerable", "invulnerable", - "involuntairy", "involuntary", - "involuntarly", "involuntary", - "invonvenient", "inconvenient", - "invulenrable", "invulnerable", - "invulernable", "invulnerable", - "invulnarable", "invulnerable", - "invulnerbale", "invulnerable", - "invulnurable", "invulnerable", - "invulverable", "invulnerable", - "invunlerable", "invulnerable", - "invurnerable", "invulnerable", - "irrationably", "irrationally", - "irrationatly", "irrationally", - "irrationella", "irrational", - "irreplacable", "irreplaceable", - "irresistable", "irresistible", - "irresistably", "irresistibly", - "irrespecitve", "irrespective", - "irresponsble", "irresponsible", - "irresponsibe", "irresponsible", - "irreverisble", "irreversible", - "irreversebly", "irreversible", - "irreversibel", "irreversible", - "irrevirsible", "irreversible", - "irrispective", "irrespective", - "irriversible", "irreversible", - "isdefinitely", "indefinitely", - "isntallation", "installation", - "isntrumental", "instrumental", - "jackonsville", "jacksonville", - "jounralistic", "journalistic", - "jouranlistic", "journalistic", - "journalisitc", "journalistic", - "journalistes", "journalists", - "judgementals", "judgements", - "juggernaunts", "juggernaut", - "juridisction", "jurisdictions", - "jurisdiccion", "jurisdiction", - "jurisdiciton", "jurisdiction", - "jurisdiktion", "jurisdiction", - "jurisfiction", "jurisdiction", - "jurisidction", "jurisdiction", - "juristiction", "jurisdiction", - "jursidiction", "jurisdiction", - "jusridiction", "jurisdiction", - "justificatin", "justifications", - "katastrophic", "catastrophic", - "kidnergarten", "kindergarten", - "kindergarden", "kindergarten", - "kingergarten", "kindergarten", - "kintergarten", "kindergarten", - "knolwedgable", "knowledgable", - "knoweldgable", "knowledgable", - "knowladgable", "knowledgable", - "knowldegable", "knowledgable", - "knowldgeable", "knowledgable", - "knowleagable", "knowledgable", - "knowledagble", "knowledgable", - "knowledeable", "knowledgable", - "knowledgabel", "knowledgable", - "knowledgeble", "knowledgeable", - "knowledgebly", "knowledgable", - "knowledgible", "knowledgable", - "knowlegdable", "knowledgable", - "knowlegeable", "knowledgeable", - "knwoledgable", "knowledgable", - "kolonization", "colonization", - "kombinations", "combinations", - "kommissioner", "commissioner", - "kompensation", "compensation", - "konfidential", "confidential", - "konfirmation", "confirmation", - "kongregation", "congregation", - "konservatism", "conservatism", - "konservative", "conservative", - "konsultation", "consultation", - "konversation", "conversation", - "koordination", "coordination", - "krankenstein", "frankenstein", - "leaglization", "legalization", - "legalizacion", "legalization", - "legalizaiton", "legalization", - "legendariske", "legendaries", - "legimitately", "legitimately", - "legislatiors", "legislators", - "legistration", "registration", - "legitamately", "legitimately", - "legitamitely", "legitimately", - "legitemately", "legitimately", - "legitimatley", "legitimately", - "legitimitely", "legitimately", - "liberatrians", "libertarians", - "libertarains", "libertarians", - "libertariens", "libertarians", - "libertaryans", "libertarians", - "libertatians", "libertarians", - "liberterians", "libertarians", - "libretarians", "libertarians", - "lighthearded", "lighthearted", - "linguisticas", "linguistics", - "linguisticos", "linguistics", - "linguistisch", "linguistics", - "litllefinger", "littlefinger", - "littelfinger", "littlefinger", - "litterfinger", "littlefinger", - "littiefinger", "littlefinger", - "littlefigner", "littlefinger", - "littlefinder", "littlefinger", - "littlepinger", "littlefinger", - "lnowledgable", "knowledgable", - "longitudonal", "longitudinal", - "madturbating", "masturbating", - "madturbation", "masturbation", - "magnificient", "magnificent", - "maintainance", "maintenance", - "maintainence", "maintenance", - "maintenaince", "maintenance", - "malfucntions", "malfunction", - "manafactured", "manufactured", - "manafacturer", "manufacturer", - "manafactures", "manufactures", - "manifactured", "manufactured", - "manifacturer", "manufacturer", - "manifactures", "manufactures", - "manifestaion", "manifestation", - "manifestanti", "manifestation", - "manipluating", "manipulating", - "manipluation", "manipulation", - "manipualting", "manipulating", - "manipualtion", "manipulation", - "manipualtive", "manipulative", - "manipulacion", "manipulation", - "manipulitive", "manipulative", - "maniuplating", "manipulating", - "maniuplation", "manipulation", - "maniuplative", "manipulative", - "manouverable", "maneuverable", - "mansalughter", "manslaughter", - "manslaugther", "manslaughter", - "mansluaghter", "manslaughter", - "manufactered", "manufactured", - "manufacterer", "manufacturer", - "manufacteres", "manufactures", - "manufacteurs", "manufactures", - "manufactored", "manufactured", - "manufactorer", "manufacturer", - "manufactores", "manufactures", - "manufactuers", "manufacturers", - "manufactuing", "manufacturing", - "manufacturas", "manufactures", - "manufacturor", "manufacturer", - "manufactuter", "manufacture", - "manufacuters", "manufactures", - "manufacutred", "manufacture", - "manufacutres", "manufactures", - "manufaturing", "manufacturing", - "manupilating", "manipulating", - "manupulating", "manipulating", - "manupulation", "manipulation", - "manupulative", "manipulative", - "marchmallows", "marshmallows", - "marganilized", "marginalized", - "margenalized", "marginalized", - "marginilized", "marginalized", - "marhsmallows", "marshmallows", - "marshamllows", "marshmallows", - "marshmallons", "marshmallows", - "masoginistic", "misogynistic", - "masogynistic", "misogynistic", - "massachusets", "massachusetts", - "massachustts", "massachusetts", - "masterbation", "masturbation", - "masterpeices", "masterpiece", - "mastrubating", "masturbating", - "mastrubation", "masturbation", - "mastubration", "masturbation", - "masturabting", "masturbating", - "masturabtion", "masturbation", - "masturbacion", "masturbation", - "masturbaited", "masturbated", - "masturbathon", "masturbation", - "masturbsting", "masturbating", - "masturdating", "masturbating", - "mastutbation", "masturbation", - "mataphorical", "metaphorical", - "mataphysical", "metaphysical", - "matchmakeing", "matchmaking", - "mathemathics", "mathematics", - "mathematican", "mathematician", - "mathematicas", "mathematics", - "mathematicks", "mathematics", - "mathematicly", "mathematical", - "mathematisch", "mathematics", - "mathemetical", "mathematical", - "matheticians", "mathematicians", - "mathimatical", "mathematical", - "mathmatician", "mathematician", - "mecahnically", "mechanically", - "mechancially", "mechanically", - "meditaciones", "medications", - "mediteranean", "mediterranean", - "mediterraean", "mediterranean", - "mediterranen", "mediterranean", - "memerization", "memorization", - "memorizacion", "memorization", - "memorozation", "memorization", - "metalurgical", "metallurgical", - "metaphisical", "metaphysical", - "metaphoricly", "metaphorical", - "metaphsyical", "metaphysical", - "metaphyiscal", "metaphysical", - "metaphyscial", "metaphysical", - "metaphysisch", "metaphysics", - "metephorical", "metaphorical", - "metephysical", "metaphysical", - "meterologist", "meteorologist", - "meterosexual", "heterosexual", - "methaporical", "metaphorical", - "methematical", "mathematical", - "metiphorical", "metaphorical", - "metophorical", "metaphorical", - "metorpolitan", "metropolitan", - "metrololitan", "metropolitan", - "metropilitan", "metropolitan", - "metroploitan", "metropolitan", - "metropolians", "metropolis", - "metropoliten", "metropolitan", - "metropolitin", "metropolitan", - "metropoliton", "metropolitan", - "microcentres", "microcenter", - "microphonies", "microphones", - "microscophic", "microscopic", - "microscopice", "microscope", - "microscoptic", "microscopic", - "midfieldiers", "midfielders", - "millenialism", "millennialism", - "millionairre", "millionaire", - "millionaries", "millionaires", - "millioniares", "millionaires", - "minimalisitc", "minimalist", - "minimalisity", "minimalist", - "mininterpret", "misinterpret", - "minipulating", "manipulating", - "minipulation", "manipulation", - "minipulative", "manipulative", - "miracilously", "miraculously", - "miracurously", "miraculous", - "miscarraiges", "miscarriage", - "miscelaneous", "miscellaneous", - "miscellanous", "miscellaneous", - "mischievious", "mischievous", - "misdameanors", "misdemeanors", - "misdeamenors", "misdemeanor", - "misfourtunes", "misfortunes", - "misgoynistic", "misogynistic", - "misinterpert", "misinterpret", - "misinterpred", "misinterpreted", - "misinterprit", "misinterpreting", - "misinterpted", "misinterpret", - "misintrepret", "misinterpret", - "misisonaries", "missionaries", - "misoganistic", "misogynistic", - "misogenistic", "misogynistic", - "misoginystic", "misogynistic", - "misognyistic", "misogynistic", - "misogonistic", "misogynistic", - "misogynisitc", "misogynistic", - "misogynsitic", "misogynistic", - "misogynystic", "misogynistic", - "missionaires", "missionaries", - "mississipppi", "mississippi", - "misspellling", "misspelling", - "misteriously", "mysteriously", - "misundersood", "misunderstood", - "misunderstod", "misunderstood", - "misygonistic", "misogynistic", - "modificacion", "modification", - "modificaiton", "modification", - "modificatons", "modifications", - "modifikation", "modification", - "modivational", "motivational", - "moisterizing", "moisturizing", - "moistorizing", "moisturizing", - "moisutrizing", "moisturizing", - "momentarilly", "momentarily", - "monolithisch", "monolithic", - "mositurizing", "moisturizing", - "motherbaords", "motherboards", - "motherborads", "motherboards", - "motivacional", "motivational", - "motovational", "motivational", - "mousturizing", "moisturizing", - "muktitasking", "multitasking", - "mulittasking", "multitasking", - "multinatinal", "multinational", - "multitaksing", "multitasking", - "munipulative", "manipulative", - "mutlitasking", "multitasking", - "mysoganistic", "misogynistic", - "mysogenistic", "misogynistic", - "mysogonistic", "misogynistic", - "mysterioulsy", "mysteriously", - "nacionalists", "nationalists", - "narcisisstic", "narcissistic", - "narcissictic", "narcissistic", - "narcissisism", "narcissism", - "narcissisist", "narcissist", - "narcissisitc", "narcissist", - "narcississts", "narcissist", - "narssicistic", "narcissistic", - "natioanlists", "nationalists", - "nationalisic", "nationalistic", - "nationalisim", "nationalism", - "nationalistc", "nationalistic", - "nationalites", "nationalist", - "nationalitic", "nationalistic", - "nationalitys", "nationalist", - "nationallity", "nationally", - "nationalsits", "nationalists", - "nationalties", "nationalist", - "nazionalists", "nationalists", - "neccessarily", "necessarily", - "neccessities", "necessities", - "necessarilly", "necessarily", - "necessitites", "necessities", - "neckbearders", "neckbeards", - "neckbeardese", "neckbeards", - "neckbeardest", "neckbeards", - "neckbeardies", "neckbeards", - "neckbeardius", "neckbeards", - "negociations", "negotiations", - "negoitations", "negotiations", - "negotiatians", "negotiations", - "negotiatiing", "negotiating", - "negotiationg", "negotiating", - "negotiatiors", "negotiations", - "neigbhorhood", "neighborhoods", - "neigbourhood", "neighbourhood", - "neighboorhod", "neighbourhood", - "neighborhing", "neighboring", - "neighborhods", "neighborhoods", - "neighbourghs", "neighbours", - "neighbourhod", "neighbourhood", - "neighbourood", "neighbourhood", - "neighbrohood", "neighborhoods", - "neighourhood", "neighborhood", - "neoroscience", "neuroscience", - "neruological", "neurological", - "neruoscience", "neuroscience", - "netropolitan", "metropolitan", - "neuorscience", "neuroscience", - "neuralogical", "neurological", - "neuroligical", "neurological", - "neurosceince", "neuroscience", - "neuroscienze", "neuroscience", - "neurosicence", "neuroscience", - "neverhteless", "nevertheless", - "nieghborhood", "neighborhood", - "norhtwestern", "northwestern", - "nothingsness", "nothingness", - "noticeablely", "noticeably", - "notificacion", "notification", - "notificaiton", "notification", - "notificatons", "notifications", - "nuerological", "neurological", - "nueroscience", "neuroscience", - "nutritionnal", "nutritional", - "obersvations", "observations", - "objectivelly", "objectively", - "objectiviser", "objectives", - "objectivitiy", "objectivity", - "obversations", "observations", - "ocassionally", "occasionally", - "occaisonally", "occasionally", - "occasioanlly", "occasionally", - "occassionaly", "occasionally", - "occationally", "occasionally", - "occurrencies", "occurrences", - "offensivelly", "offensively", - "ogranisation", "organisation", - "omniverously", "omnivorously", - "operationnal", "operational", - "opportuniste", "opportunities", - "opportunites", "opportunities", - "oppositition", "opposition", - "opthalmology", "ophthalmology", - "optimistisch", "optimistic", - "optimizacion", "optimization", - "optimizating", "optimization", - "optimziation", "optimization", - "optmizations", "optimizations", - "oragnisation", "organisation", - "orchastrated", "orchestrated", - "orchestarted", "orchestrated", - "orchestraded", "orchestrated", - "orchistrated", "orchestrated", - "orgainsation", "organisation", - "orgainzation", "organizations", - "organisaiton", "organisation", - "organisatons", "organisations", - "organistaion", "organisation", - "organizacion", "organization", - "organizaiton", "organization", - "organizativo", "organization", - "organizatons", "organizations", - "organsiation", "organisation", - "organziation", "organization", - "orginasation", "organisation", - "orginazation", "organization", - "orgnaisation", "organisations", - "originallity", "originality", - "outraegously", "outrageously", - "outrageoulsy", "outrageously", - "outragesouly", "outrageously", - "outrageuosly", "outrageously", - "outragiously", "outrageously", - "outsourceing", "outsourcing", - "overbearring", "overbearing", - "overblocking", "overclocking", - "overclcoking", "overclocking", - "overclicking", "overclocking", - "overcloaking", "overclocking", - "overclockign", "overclocking", - "overclokcing", "overclocking", - "overhearting", "overreacting", - "overheathing", "overheating", - "overhtinking", "overthinking", - "overhwelming", "overwhelming", - "overlappping", "overlapping", - "overlcocking", "overclocking", - "overreaktion", "overreaction", - "overwealming", "overwhelming", - "overwhelemed", "overwhelmed", - "overwhemling", "overwhelming", - "overwhleming", "overwhelming", - "owerpowering", "overpowering", - "painkilllers", "painkillers", - "palastinians", "palestinians", - "palesitnians", "palestinians", - "palestenians", "palestinians", - "palestinains", "palestinians", - "palestiniens", "palestinians", - "palestininan", "palestinian", - "palestininas", "palestinians", - "palistinians", "palestinians", - "palythroughs", "playthroughs", - "parapharsing", "paraphrasing", - "paraphenalia", "paraphernalia", - "paraphrashed", "paraphrase", - "paraphrazing", "paraphrasing", - "paraprashing", "paraphrasing", - "paraprhasing", "paraphrasing", - "parenthesees", "parentheses", - "parenthesies", "parenthesis", - "parliamentry", "parliamentary", - "partecipants", "participants", - "partecipated", "participated", - "parternships", "partnership", - "particapated", "participated", - "particiapnts", "participant", - "particiapted", "participated", - "participante", "participate", - "participaste", "participants", - "participatie", "participated", - "participatin", "participation", - "participatns", "participant", - "participaton", "participant", - "participents", "participants", - "particualrly", "particularly", - "particulalry", "particularly", - "particullary", "particularly", - "passionatley", "passionately", - "pathalogical", "pathological", - "pathelogical", "pathological", - "patholigical", "pathological", - "paychedelics", "psychedelics", - "paychiatrist", "psychiatrist", - "paychologist", "psychologist", - "paychopathic", "psychopathic", - "penetratiing", "penetrating", - "penisylvania", "pennsylvania", - "pennsilvania", "pennsylvania", - "pennslyvania", "pennsylvania", - "pennsylvaina", "pennsylvania", - "pennsyvlania", "pennsylvania", - "pennyslvania", "pennsylvania", - "penssylvania", "pennsylvania", - "pentsylvania", "pennsylvania", - "percentagens", "percentages", - "perferential", "preferential", - "performantes", "performances", - "performences", "performances", - "perfromances", "performances", - "peridoically", "periodically", - "peripathetic", "peripatetic", - "periphereals", "peripherals", - "peripherials", "peripherals", - "permanantely", "permanently", - "permanentely", "permanently", - "permissiable", "permissible", - "peroidically", "periodically", - "perpatrators", "perpetrators", - "perpatuating", "perpetuating", - "perpertators", "perpetrators", - "perpertrated", "perpetrated", - "perpetraitor", "perpetrator", - "perpetraters", "perpetrators", - "perpetuaters", "perpetuates", - "perpitrators", "perpetrators", - "perposefully", "purposefully", - "perposterous", "preposterous", - "perpretators", "perpetrators", - "perpsectives", "perspectives", - "perputrators", "perpetrators", - "perputuating", "perpetuating", - "persepctives", "perspectives", - "perservation", "preservation", - "perseverence", "perseverance", - "personalites", "personalities", - "personallity", "personally", - "personilized", "personalized", - "perspecitves", "perspectives", - "perspectivas", "perspectives", - "persumptuous", "presumptuous", - "perticularly", "particularly", - "pertubations", "perturbations", - "pessimisitic", "pessimistic", - "pessimisstic", "pessimistic", - "phenomenonal", "phenomenal", - "phenomenonly", "phenomenally", - "phenomonenon", "phenomenon", - "phialdelphia", "philadelphia", - "philadalphia", "philadelphia", - "philadelhpia", "philadelphia", - "philadeplhia", "philadelphia", - "philadlephia", "philadelphia", - "philedalphia", "philadelphia", - "philedelphia", "philadelphia", - "philidalphia", "philadelphia", - "philippinnes", "philippines", - "philippinoes", "philippines", - "philisophers", "philosophers", - "philisophies", "philosophies", - "phillippines", "philippines", - "philosiphers", "philosophers", - "philosiphies", "philosophies", - "philosohpers", "philosopher", - "philosohpies", "philosophies", - "philosophiae", "philosophies", - "philosophics", "philosophies", - "philosophios", "philosophies", - "philospohers", "philosophers", - "philospohies", "philosophies", - "photagrapher", "photographer", - "photochopped", "photoshopped", - "photograhper", "photographer", - "photograpers", "photographers", - "photographes", "photographs", - "photographyi", "photographic", - "photogropher", "photographer", - "photogrpahed", "photographed", - "photogrpaher", "photographer", - "photoshipped", "photoshopped", - "photoshooped", "photoshopped", - "photoshoppad", "photoshopped", - "phychedelics", "psychedelics", - "phychiatrist", "psychiatrist", - "phychologist", "psychologist", - "phychopathic", "psychopathic", - "physcedelics", "psychedelics", - "physciatrist", "psychiatrist", - "physcologist", "psychologist", - "physcopathic", "psychopathic", - "physicallity", "physically", - "physiologial", "physiological", - "pilgrimmages", "pilgrimages", - "pitchforkers", "pitchforks", - "pkaythroughs", "playthroughs", - "plabeswalker", "planeswalker", - "plaestinians", "palestinians", - "planeswaller", "planeswalker", - "planeswlaker", "planeswalker", - "planetwalker", "planeswalker", - "plansewalker", "planeswalker", - "plauthroughs", "playthroughs", - "playhtroughs", "playthroughs", - "playtgroughs", "playthroughs", - "playthorughs", "playthroughs", - "playthourghs", "playthroughs", - "playthrougth", "playthroughs", - "playthrouhgs", "playthroughs", - "playthtoughs", "playthroughs", - "playtrhoughs", "playthroughs", - "populationes", "populations", - "pornograpghy", "pornography", - "porportional", "proportional", - "portabillity", "portability", - "portagonists", "protagonists", - "positionning", "positioning", - "positivitely", "positivity", - "possessivize", "possessive", - "possibillity", "possibility", - "possiblility", "possibility", - "possiblities", "possibilities", - "powerfisting", "powerlifting", - "powerlfiting", "powerlifting", - "powerlifitng", "powerlifting", - "powerlisting", "powerlifting", - "powetlifting", "powerlifting", - "powrrlifting", "powerlifting", - "practicioner", "practitioner", - "practisioner", "practitioner", - "pratictioner", "practitioners", - "precedessors", "predecessors", - "preconveived", "preconceived", - "predacessors", "predecessors", - "predeccesors", "predecessor", - "predecesores", "predecessor", - "predescesors", "predecessors", - "predessecors", "predecessors", - "predetermind", "predetermined", - "predicessors", "predecessors", - "predocessors", "predecessors", - "predomiantly", "predominately", - "predominanty", "predominantly", - "predominatly", "predominantly", - "preferantial", "preferential", - "preferentail", "preferential", - "preformances", "performances", - "preinitalize", "preinitialize", - "preliminarly", "preliminary", - "prematurelly", "prematurely", - "premillenial", "premillennial", - "preocupation", "preoccupation", - "preperations", "preparations", - "prepetrators", "perpetrators", - "prepetuating", "perpetuating", - "prepostorous", "preposterous", - "preposturous", "preposterous", - "prerequisets", "prerequisite", - "prescirption", "prescriptions", - "prescribtion", "prescription", - "prescripcion", "prescription", - "prescriptons", "prescriptions", - "prescritpion", "prescriptions", - "presedential", "presidential", - "presentacion", "presentation", - "presentaiton", "presentations", - "preservacion", "preservation", - "preservating", "preservation", - "preservativo", "preservation", - "presidencial", "presidential", - "presidenital", "presidential", - "presidentail", "presidential", - "presnetation", "presentations", - "presonalized", "personalized", - "prespectives", "perspectives", - "presrciption", "prescriptions", - "presumpteous", "presumptuous", - "presumputous", "presumptuous", - "prevantative", "preventative", - "preventation", "presentation", - "preventetive", "preventative", - "preventitive", "preventative", - "prezidential", "presidential", - "principlaity", "principality", - "probabiliste", "probabilities", - "probabilites", "probabilities", - "probabillity", "probability", - "probablistic", "probabilistic", - "proclomation", "proclamation", - "proconceived", "preconceived", - "profesisonal", "professionals", - "professiinal", "professionalism", - "professioanl", "professionals", - "professiomal", "professionalism", - "professionel", "professional", - "professionsl", "professionalism", - "professoinal", "professionals", - "professonial", "professionals", - "proffesional", "professional", - "proficientcy", "proficiency", - "profissional", "professional", - "profitabiliy", "profitability", - "profitabilty", "profitability", - "profressions", "progressions", - "progatonists", "protagonists", - "programmeurs", "programmer", - "progressieve", "progressive", - "progressioin", "progressions", - "progressiong", "progressing", - "progressisme", "progresses", - "progressiste", "progresses", - "progressivas", "progressives", - "progressivey", "progressively", - "progressivly", "progressively", - "progressivsm", "progressives", - "progresssing", "progressing", - "progresssion", "progressions", - "progresssive", "progressives", - "prohibitting", "prohibiting", - "projecticles", "projectiles", - "proletariaat", "proletariat", - "proletariant", "proletariat", - "proletaricat", "proletariat", - "prominantely", "prominently", - "promiscuious", "promiscuous", - "promisculous", "promiscuous", - "promotionnal", "promotional", - "pronounceing", "pronouncing", - "pronunciaton", "pronunciation", - "propertional", "proportional", - "propesterous", "preposterous", - "proportianal", "proportional", - "proportionel", "proportional", - "proposterous", "preposterous", - "proprotional", "proportional", - "prostetution", "prostitution", - "prostitition", "prostitution", - "prostitucion", "prostitution", - "prostituiton", "prostitution", - "prostitutiei", "prostitute", - "protaganists", "protagonists", - "protaginists", "protagonists", - "protagnoists", "protagonists", - "protestantes", "protestants", - "protoganists", "protagonists", - "prouncements", "pronouncements", - "pruposefully", "purposefully", - "pscyhologist", "psychologist", - "pscyhopathic", "psychopathic", - "pshyciatrist", "psychiatrist", - "pshycologist", "psychologist", - "pshycopathic", "psychopathic", - "psichologist", "psychologist", - "psychaitrist", "psychiatrist", - "psychedellic", "psychedelic", - "psychedilics", "psychedelics", - "psychemedics", "psychedelics", - "psychiatirst", "psychiatrists", - "psychiatrics", "psychiatrist", - "psychiatrict", "psychiatrist", - "psychiatrits", "psychiatrists", - "psychistrist", "psychiatrist", - "psychodelics", "psychedelics", - "psycholigist", "psychologist", - "psychologial", "psychological", - "psychologits", "psychologists", - "psychologyst", "psychologist", - "psychopathes", "psychopaths", - "psychyatrist", "psychiatrist", - "puplications", "publications", - "puritannical", "puritanical", - "purpetrators", "perpetrators", - "purpetuating", "perpetuating", - "purpusefully", "purposefully", - "pyschedelics", "psychedelics", - "pyschiatrist", "psychiatrist", - "pyschologist", "psychologist", - "pyschopathic", "psychopathic", - "qualificaton", "qualification", - "qualifierais", "qualifiers", - "qualtitative", "quantitative", - "quantatitive", "quantitative", - "quantititive", "quantitative", - "quarterblack", "quarterback", - "quesitonable", "questionable", - "questionalbe", "questionable", - "questionning", "questioning", - "questionsign", "questioning", - "radioactieve", "radioactive", - "rationallity", "rationally", - "reactionairy", "reactionary", - "reactionnary", "reactionary", - "realisticaly", "realistically", - "realisticlly", "realistically", - "reasonablely", "reasonably", - "recallection", "recollection", - "reccomending", "recommending", - "reccommended", "recommended", - "recepcionist", "receptionist", - "receptionest", "receptionist", - "recgonizable", "recognizable", - "reciporcated", "reciprocate", - "reciprociate", "reciprocate", - "reciprocrate", "reciprocate", - "recognizible", "recognizable", - "recolleciton", "recollection", - "recommanding", "recommending", - "recommendeds", "recommends", - "recommendors", "recommends", - "recommeneded", "recommended", - "recommenting", "recommending", - "recongizable", "recognizable", - "recontructed", "reconstructed", - "recpetionist", "receptionist", - "recreacional", "recreational", - "recriational", "recreational", - "referenceing", "referencing", - "refirgerator", "refrigerator", - "refriderator", "refrigerator", - "refrigarator", "refrigerator", - "refrigerador", "refrigerator", - "refrigerater", "refrigerator", - "refrigirator", "refrigerator", - "regenaration", "regeneration", - "regeneracion", "regeneration", - "regestration", "registration", - "registartion", "registration", - "registrating", "registration", - "regrigerator", "refrigerator", - "regulatorias", "regulators", - "regulatories", "regulators", - "regulatorios", "regulators", - "reicarnation", "reincarnation", - "reinforcemnt", "reinforcement", - "reinitalised", "reinitialised", - "reinitalises", "reinitialises", - "reinitalized", "reinitialized", - "reinitalizes", "reinitializes", - "reinstallled", "reinstalled", - "reisntalling", "reinstalling", - "relaitonship", "relationships", - "relatinoship", "relationships", - "reliabillity", "reliability", - "reluctanctly", "reluctantly", - "remarkablely", "remarkably", - "rememberance", "remembrance", - "reminiscient", "reminiscent", - "renaissaince", "renaissance", - "renegeration", "regeneration", - "reorganision", "reorganisation", - "repalcements", "replacements", - "repersenting", "representing", - "reporduction", "reproduction", - "reporductive", "reproductive", - "reprecussion", "repercussions", - "representate", "representative", - "represention", "representing", - "representive", "representative", - "reproducable", "reproducible", - "reproduccion", "reproduction", - "reproduciton", "reproduction", - "reproducting", "reproduction", - "reproductivo", "reproduction", - "reproduktion", "reproduction", - "repsectfully", "respectfully", - "repsectively", "respectively", - "republicanas", "republicans", - "republicanos", "republicans", - "republicants", "republicans", - "republicians", "republicans", - "requerimento", "requirement", - "requeriments", "requirements", - "requierments", "requirements", - "requriements", "requirements", - "resembelance", "resemblance", - "reseptionist", "receptionist", - "reserrection", "resurrection", - "resintalling", "reinstalling", - "resistancies", "resistances", - "resistencias", "resistances", - "respecitvely", "respectively", - "respectabile", "respectable", - "respectivily", "respectively", - "respectivley", "respectively", - "respectuflly", "respectfully", - "respiratiory", "respiratory", - "responsabile", "responsible", - "responsaveis", "responsive", - "responsbilty", "responsibly", - "responsibile", "responsible", - "responsibily", "responsibility", - "responsibley", "responsibly", - "responsibliy", "responsibly", - "responsiblty", "responsibly", - "ressemblance", "resemblance", - "ressemblence", "resemblance", - "ressurection", "resurrection", - "restaurantes", "restaurants", - "restauration", "restoration", - "restauraunts", "restaurants", - "restirctions", "restrictions", - "restrainting", "restraining", - "restrcitions", "restriction", - "restricitons", "restrictions", - "resurreccion", "resurrection", - "resurrektion", "resurrection", - "retalitation", "retaliation", - "retributioon", "retribution", - "retroactivly", "retroactively", - "revolutionay", "revolutionary", - "revolutionos", "revolutions", - "rezurrection", "resurrection", - "rictatorship", "dictatorship", - "ridicilously", "ridiculously", - "ridicoulusly", "ridiculously", - "righteouness", "righteousness", - "rockerfeller", "rockefeller", - "rollercoaser", "rollercoaster", - "rollercoater", "rollercoaster", - "romanitcally", "romantically", - "roundabounts", "roundabout", - "rudimentatry", "rudimentary", - "rysurrection", "resurrection", - "sacksonville", "jacksonville", - "sacreligious", "sacrilegious", - "sacrificeing", "sacrificing", - "saksatchewan", "saskatchewan", - "salughtering", "slaughtering", - "sanctionning", "sanctioning", - "sarcasticaly", "sarcastically", - "sarcasticlly", "sarcastically", - "sascatchewan", "saskatchewan", - "saskatcehwan", "saskatchewan", - "saskatchawan", "saskatchewan", - "saskatechwan", "saskatchewan", - "sasketchawan", "saskatchewan", - "sasketchewan", "saskatchewan", - "sasktachewan", "saskatchewan", - "satasfaction", "satisfaction", - "satasfactory", "satisfactory", - "satisfaccion", "satisfaction", - "satisfacting", "satisfaction", - "satisfcation", "satisfaction", - "satisfiction", "satisfaction", - "satistactory", "satisfactory", - "satsifaction", "satisfaction", - "satsifactory", "satisfactory", - "scandanivian", "scandinavian", - "scandenavian", "scandinavian", - "scandianvian", "scandinavian", - "scandinacian", "scandinavian", - "scandinaivan", "scandinavia", - "scandinavica", "scandinavian", - "scandinavien", "scandinavian", - "scandinavion", "scandinavian", - "scandivanian", "scandinavian", - "scandonavian", "scandinavian", - "schizophrena", "schizophrenia", - "scholarhsips", "scholarships", - "scholerships", "scholarships", - "scholorships", "scholarships", - "scnadinavian", "scandinavian", - "screenshoots", "screenshot", - "sensationail", "sensational", - "sensationnal", "sensational", - "sensibilites", "sensibilities", - "sensitivitiy", "sensitivity", - "sentimentals", "sentiments", - "sertificates", "certificates", - "serveillance", "surveillance", - "seskatchewan", "saskatchewan", - "shakesperean", "shakespeare", - "shamelessely", "shamelessly", - "shamelessley", "shamelessly", - "shampionship", "championship", - "shardholders", "shareholders", - "shenanigains", "shenanigans", - "shenanigangs", "shenanigans", - "shenaniganns", "shenanigans", - "shenanighans", "shenanigans", - "shopkeeepers", "shopkeepers", - "showboarding", "snowboarding", - "siginificant", "significant", - "significanly", "significantly", - "significante", "significance", - "significanty", "significantly", - "significatly", "significantly", - "signleplayer", "singleplayer", - "simaltaneous", "simultaneous", - "simeltaneous", "simultaneous", - "similaraties", "similarities", - "similiarites", "similarities", - "similiarties", "similarities", - "similiraties", "similarities", - "similtaneous", "simultaneous", - "simliarities", "similarities", - "simlutaneous", "simultaneous", - "simpathizers", "sympathizers", - "simplistisch", "simplistic", - "simulatenous", "simultaneous", - "simulatneous", "simultaneous", - "simultaenous", "simultaneous", - "simultaneuos", "simultaneous", - "simultanious", "simultaneous", - "simulteneous", "simultaneous", - "singelplayer", "singleplayer", - "singlepalyer", "singleplayer", - "sinlgeplayer", "singleplayer", - "situationals", "situations", - "situationnal", "situational", - "skandinavian", "scandinavian", - "skateboaring", "skateboarding", - "skrawberries", "strawberries", - "slaugthering", "slaughtering", - "sloughtering", "slaughtering", - "sluaghtering", "slaughtering", - "snowballling", "snowballing", - "snowbaording", "snowboarding", - "socialistisk", "socialists", - "socialogical", "sociological", - "socioeconimc", "socioeconomic", - "socioeconmic", "socioeconomic", - "socioligical", "sociological", - "sociopolical", "sociological", - "somethingest", "somethings", - "sophisticaed", "sophisticated", - "sophisticted", "sophisticated", - "southamption", "southampton", - "southernerns", "southerners", - "sovereighnty", "sovereignty", - "sovereignety", "sovereignty", - "sovereignity", "sovereignty", - "specialistes", "specialists", - "specializare", "specialize", - "specializate", "specialize", - "specializeds", "specializes", - "specializied", "specialize", - "speciallized", "specialised", - "specifcation", "specification", - "spectacuarly", "spectacular", - "spectaculair", "spectacular", - "spectaculary", "spectacularly", - "spectacullar", "spectacularly", - "specualtions", "speculation", - "spermatozoan", "spermatozoon", - "spesifically", "specifically", - "spirituallly", "spiritually", - "spirtiuality", "spirituality", - "spirutuality", "spirituality", - "spontaneosly", "spontaneously", - "spontaneouly", "spontaneously", - "spreadhseets", "spreadsheets", - "spreadsheats", "spreadsheets", - "spreadsheeds", "spreadsheets", - "spreadsheeet", "spreadsheets", - "standartized", "standardized", - "standerdized", "standardized", - "stardardized", "standardized", - "starightened", "straightened", - "starwberries", "strawberries", - "statisticaly", "statistically", - "stereotpying", "stereotyping", - "stereotypers", "stereotypes", - "stereotypian", "stereotyping", - "steriotyping", "stereotyping", - "steroetyping", "stereotyping", - "steryotyping", "stereotyping", - "straigntened", "straightened", - "straigthened", "straightened", - "strategicaly", "strategically", - "strategiclly", "strategically", - "strawburries", "strawberries", - "streemlining", "streamlining", - "streightened", "straightened", - "strenghening", "strengthening", - "strenghtened", "strengthened", - "strengtheing", "strengthening", - "stroytelling", "storytelling", - "subconcsious", "subconscious", - "subconsicous", "subconscious", - "subcouncious", "subconscious", - "subcsription", "subscriptions", - "subesquently", "subsequently", - "subjectivety", "subjectively", - "subjectivily", "subjectively", - "subjectivley", "subjectively", - "subjudgation", "subjugation", - "subredditors", "subreddits", - "subscirption", "subscriptions", - "subsconcious", "subconscious", - "subscribbers", "subscribers", - "subscribbing", "subscribing", - "subscribirse", "subscriber", - "subscribtion", "subscription", - "subscriptons", "subscriptions", - "subscritpion", "subscriptions", - "subscrpition", "subscriptions", - "subsiquently", "subsequently", - "subsrciption", "subscriptions", - "subsricption", "subscriptions", - "substantialy", "substantially", - "substantitve", "substantive", - "substitition", "substitution", - "substituters", "substitutes", - "substitutivo", "substitution", - "substitutues", "substitutes", - "substracting", "subtracting", - "substraction", "subtraction", - "subterranian", "subterranean", - "succsessfull", "successful", - "sunconscious", "subconscious", - "supermarkeds", "supermarkets", - "supermarkers", "supermarkets", - "supermarkert", "supermarkets", - "supermarkten", "supermarket", - "supermarktes", "supermarkets", - "supernarkets", "supermarkets", - "supernatrual", "supernatural", - "supersticion", "superstition", - "superstision", "superstition", - "superstitios", "superstitious", - "superstitous", "superstitious", - "supervisiors", "supervisors", - "supervisoras", "supervisors", - "supervisores", "supervisors", - "supllemental", "supplemental", - "supplamental", "supplemental", - "supplamented", "supplemented", - "supplimental", "supplemental", - "suppresssion", "suppression", - "supscription", "subscription", - "supsiciously", "suspiciously", - "surprizingly", "surprisingly", - "surrenderred", "surrendered", - "surrundering", "surrendering", - "survaillance", "surveillance", - "survaillence", "surveillance", - "survallience", "surveillance", - "surveillence", "surveillance", - "survelliance", "surveillance", - "surviellance", "surveillance", - "survivabiity", "survivability", - "survivabiliy", "survivability", - "survivabilty", "survivability", - "susceptiable", "susceptible", - "susceptibile", "susceptible", - "suspeciously", "suspiciously", - "suspicioulsy", "suspiciously", - "suspiciuosly", "suspiciously", - "suspisiously", "suspiciously", - "sustainabily", "sustainability", - "symapthizers", "sympathizers", - "symetrically", "symmetrically", - "symmetricaly", "symmetrically", - "sympathethic", "sympathetic", - "sympathsizer", "sympathizers", - "sympathyzers", "sympathizers", - "sympethizers", "sympathizers", - "symphatizers", "sympathizers", - "sympithizers", "sympathizers", - "syncronously", "synchronously", - "sysmatically", "systematically", - "systematisch", "systematic", - "tablespooons", "tablespoon", - "tacticallity", "tactically", - "tangencially", "tangentially", - "tangenitally", "tangentially", - "tangientally", "tangentially", - "teamfighters", "teamfights", - "teansylvania", "transylvania", - "techanically", "mechanically", - "techincality", "technicality", - "technologial", "technological", - "telelevision", "television", - "teleportaion", "teleportation", - "teleportaton", "teleportation", - "temepratures", "temperatures", - "temparatures", "temperatures", - "temperaturas", "temperatures", - "temporarilly", "temporarily", - "tempreatures", "temperatures", - "tempuratures", "temperatures", - "tengentially", "tangentially", - "termendously", "tremendously", - "territorrial", "territorial", - "territorries", "territories", - "testasterone", "testosterone", - "testestorone", "testosterone", - "thanskgiving", "thanksgiving", - "theologicial", "theological", - "theoreticaly", "theoretically", - "thermomenter", "thermometer", - "thermomether", "thermometer", - "thumbnailers", "thumbnails", - "thunderboldt", "thunderbolt", - "tindergarten", "kindergarten", - "torubleshoot", "troubleshoot", - "totalitarion", "totalitarian", - "totalitatian", "totalitarian", - "touchscreeen", "touchscreen", - "traditionaly", "traditionally", - "traditionnal", "traditional", - "tradtionally", "traditionally", - "tramendously", "tremendously", - "tramsformers", "transformers", - "tramsforming", "transforming", - "tranditional", "transitional", - "tranistional", "transitional", - "tranistioned", "transitioned", - "tranlsations", "translations", - "tranmsission", "transmissions", - "transaltions", "translations", - "transaprency", "transparency", - "transational", "transitional", - "transcations", "transactions", - "transcendant", "transcendent", - "transcripton", "transcription", - "transcriptus", "transcripts", - "transesxuals", "transsexuals", - "transfarmers", "transformers", - "transfarring", "transferring", - "transferrred", "transferred", - "transformare", "transformers", - "transformase", "transforms", - "transformees", "transforms", - "transforners", "transformers", - "transfromers", "transformers", - "transfroming", "transforming", - "transgenderd", "transgendered", - "transgendred", "transgendered", - "transgenered", "transgender", - "transicional", "transitional", - "transilvania", "transylvania", - "transimssion", "transmissions", - "transisioned", "transitioned", - "translastion", "translations", - "translateing", "translating", - "translationg", "translating", - "translucient", "translucent", - "translyvania", "transylvania", - "transmisions", "transmission", - "transmisison", "transmission", - "transmissons", "transmissions", - "transmitirte", "transmitter", - "transmittted", "transmitted", - "transmorfers", "transformer", - "transofrmers", "transformers", - "transofrming", "transforming", - "transparancy", "transparency", - "transparenty", "transparency", - "transparrent", "transparent", - "transperancy", "transparency", - "transperency", "transparency", - "transplantes", "transplants", - "transporteur", "transporter", - "transportion", "transporting", - "transpotting", "transporting", - "transsmision", "transmissions", - "transylmania", "transylvania", - "transylvanai", "transylvania", - "trasnferring", "transferring", - "trasnformers", "transformers", - "trasnforming", "transforming", - "trasnmission", "transmissions", - "trasnparency", "transparency", - "trasnporting", "transporting", - "trememdously", "tremendously", - "tremendoulsy", "tremendously", - "tremondously", "tremendously", - "troubelshoot", "troubleshoot", - "troublehsoot", "troubleshoot", - "trumendously", "tremendously", - "trustworthly", "trustworthy", - "ubsubscribed", "unsubscribed", - "udnerpowered", "underpowered", - "umbelievable", "unbelievable", - "umemployment", "unemployment", - "unaccaptable", "unacceptable", - "unacceptible", "unacceptable", - "unaccpetable", "unacceptable", - "unacompanied", "unaccompanied", - "unappealling", "unappealing", - "unattractice", "unattractive", - "unautherized", "unauthorized", - "unauthroized", "unauthorized", - "unbeleivable", "unbelievable", - "unbeleivably", "unbelievably", - "unbeliavable", "unbelievable", - "unbeliavably", "unbelievably", - "unbeliebable", "unbelievable", - "unbelieveble", "unbelievable", - "unbelievibly", "unbelievably", - "unbeliveable", "unbelievable", - "unbeliveably", "unbelievably", - "unbelizeable", "unbelievable", - "unbolievable", "unbelievable", - "uncertainity", "uncertainty", - "uncertaintly", "uncertainty", - "uncompatible", "incompatible", - "unconditinal", "unconditional", - "unconsciosly", "unconsciously", - "unconsciouly", "unconsciously", - "unconsistent", "inconsistent", - "unconvenient", "inconvenient", - "unconvential", "unconventional", - "undecideable", "undecidable", - "undefinitely", "indefinitely", - "undeniablely", "undeniably", - "undergradate", "undergraduate", - "undergradute", "undergraduate", - "underminding", "undermining", - "undermineing", "undermining", - "undermineras", "undermines", - "undermineres", "undermines", - "underminging", "undermining", - "underminning", "undermining", - "undertakeing", "undertaking", - "underwhelimg", "underwhelming", - "underwheling", "underwhelming", - "undesireable", "undesirable", - "undoubtedbly", "undoubtedly", - "unemployemnt", "unemployment", - "unemplyoment", "unemployment", - "unempolyment", "unemployment", - "unenployment", "unemployment", - "unequalities", "inequalities", - "unexpectadly", "unexpectedly", - "unexpectetly", "unexpectedly", - "unexpectidly", "unexpectedly", - "unexperience", "inexperience", - "unexpextedly", "unexpectedly", - "unexplicably", "inexplicably", - "unforgetable", "unforgettable", - "unforgiveble", "unforgivable", - "unforgivible", "unforgivable", - "unfortunatly", "unfortunately", - "unfortunetly", "unfortunately", - "unilatreally", "unilaterally", - "uniliterally", "unilaterally", - "unimpresssed", "unimpressed", - "uninitalised", "uninitialised", - "uninitalized", "uninitialized", - "uninstallimg", "uninstalling", - "uninstallled", "uninstalled", - "unintentinal", "unintentional", - "uninteresing", "uninteresting", - "uninterneted", "uninterested", - "uninterruped", "uninterrupted", - "uninterupted", "uninterrupted", - "unisntalling", "uninstalling", - "unitesstates", "unitedstates", - "univerisites", "universities", - "univeristies", "universities", - "universitets", "universities", - "unliaterally", "unilaterally", - "unneccessary", "unnecessary", - "unnecesarily", "unnecessarily", - "unnecessairy", "unnecessarily", - "unnecessarly", "unnecessarily", - "unnistalling", "uninstalling", - "unpredictabe", "unpredictable", - "unpreductive", "unproductive", - "unproduktive", "unproductive", - "unrealisitic", "unrealistic", - "unreaponsive", "unresponsive", - "unreasonalby", "unreasonably", - "unrepsonsive", "unresponsive", - "unresponcive", "unresponsive", - "unresponisve", "unresponsive", - "unresponsibe", "unresponsive", - "unrestircted", "unrestricted", - "unrestrcited", "unrestricted", - "unristricted", "unrestricted", - "unseccessful", "unsuccessful", - "unsespecting", "unsuspecting", - "unsibscribed", "unsubscribed", - "unsoliciated", "unsolicited", - "unsolicitied", "unsolicited", - "unsubscirbed", "unsubscribed", - "unsubscrible", "unsubscribed", - "unsubscrided", "unsubscribed", - "unsubscriped", "unsubscribed", - "unsubscrubed", "unsubscribed", - "unsubsrcibed", "unsubscribed", - "unsucessfull", "unsuccessful", - "unsunscribed", "unsubscribed", - "unsurprizing", "unsurprising", - "unsusbcribed", "unsubscribed", - "unsustainble", "unsustainable", - "unvelievable", "unbelievable", - "unvelievably", "unbelievably", - "unviersities", "universities", - "unvulnerable", "invulnerable", - "varification", "verification", - "vegetarianas", "vegetarians", - "vegetarianos", "vegetarians", - "verficiation", "verification", - "verificacion", "verification", - "verificaiton", "verification", - "verifikation", "verification", - "vernaculaire", "vernacular", - "versatillity", "versatility", - "verticallity", "vertically", - "videogamemes", "videogames", - "visualizaton", "visualization", - "vocabularily", "vocabulary", - "vocabularity", "vocabulary", - "volonteering", "volunteering", - "volounteered", "volunteered", - "voluntarilly", "voluntarily", - "volunterring", "volunteering", - "vulnerabilty", "vulnerability", - "weightlifing", "weightlifting", - "withdrawalls", "withdrawals", - "withdrawling", "withdrawing", - "withdrawning", "withdrawing", - "wonderfullly", "wonderfully", - "worshippping", "worshipping", - "xenophobical", "xenophobia", - "abandenment", "abandonment", - "abandomnent", "abandonment", - "abandonding", "abandoning", - "abandonnent", "abandonment", - "abandonning", "abandoning", - "abbreviatin", "abbreviation", - "abbreviaton", "abbreviation", - "abdominable", "abdominal", - "abomanation", "abomination", - "abominacion", "abomination", - "abomonation", "abomination", - "abonimation", "abomination", - "aboriginial", "aboriginal", - "aborigional", "aboriginal", - "abreviation", "abbreviation", - "abritrarily", "arbitrarily", - "abritration", "arbitration", - "absolutelly", "absolutely", - "absolutelys", "absolutes", - "absolutisme", "absolutes", - "absolutiste", "absolutes", - "abstraccion", "abstraction", - "abstraktion", "abstraction", - "abstruction", "abstraction", - "abundancies", "abundances", - "academicaly", "academically", - "academicese", "academics", - "accelarated", "accelerated", - "accelarator", "accelerator", - "accelerater", "accelerator", - "acceleratie", "accelerate", - "acceleratio", "accelerator", - "acceleraton", "acceleration", - "accelorated", "accelerated", - "accelorator", "accelerator", - "acceptabelt", "acceptable", - "accesseries", "accessories", - "accessibile", "accessible", - "accessibily", "accessibility", - "accessoires", "accessories", - "accidantely", "accidently", - "accidentaly", "accidentally", - "accidentely", "accidently", - "accidential", "accidental", - "accidentily", "accidently", - "accidentlay", "accidently", - "accidentley", "accidently", - "accidentlly", "accidently", - "accomadated", "accommodated", - "accomadates", "accommodates", - "accommadate", "accommodate", - "accommidate", "accommodate", - "accomodated", "accommodated", - "accomodates", "accommodates", - "accomondate", "accommodate", - "accompained", "accompanied", - "accompanyed", "accompanied", - "accompianed", "accompanied", - "accompinied", "accompanied", - "accomplises", "accomplishes", - "accomplishs", "accomplishes", - "accomponied", "accompanied", - "accountatns", "accountants", - "accountents", "accountants", - "accquainted", "acquainted", - "accrediated", "accredited", - "accreditied", "accredited", - "accreditted", "accredited", - "acculumated", "accumulated", - "accumalated", "accumulated", - "accumelated", "accumulated", - "accumilated", "accumulated", - "accumulatin", "accumulation", - "accumulaton", "accumulation", - "accuratelly", "accurately", - "accustommed", "accustomed", - "acheivement", "achievement", - "acheivments", "achievements", - "achievemint", "achievement", - "achievemnts", "achievements", - "achievments", "achievements", - "achivements", "achievements", - "acknolwedge", "acknowledge", - "acknoweldge", "acknowledge", - "acknowleded", "acknowledged", - "acknowlegde", "acknowledge", - "acknowleged", "acknowledge", - "acknowleges", "acknowledges", - "acknwoledge", "acknowledges", - "acomplished", "accomplished", - "acopalyptic", "apocalyptic", - "acquaintace", "acquaintance", - "acquisation", "acquisition", - "activateing", "activating", - "activationg", "activating", - "activistion", "activision", - "additinally", "additionally", - "additionaly", "additionally", - "additonally", "additionally", - "adequatedly", "adequately", - "adjectiveus", "adjectives", - "administerd", "administered", - "administrar", "administrator", - "administren", "administer", - "administrer", "administer", - "administres", "administer", - "administrez", "administer", - "adminstered", "administered", - "adminstrate", "administrate", - "admittadely", "admittedly", - "adolencence", "adolescence", - "adolescance", "adolescence", - "adolescense", "adolescence", - "advantadges", "advantages", - "advantageos", "advantageous", - "advantageus", "advantageous", - "advantagous", "advantageous", - "adventerous", "adventures", - "adventourus", "adventurous", - "adversiting", "advertising", - "advertisors", "advertisers", - "advertisted", "advertised", - "aesthethics", "aesthetics", - "afficionado", "aficionado", - "affiliction", "affiliation", - "affirmitave", "affirmative", - "affirmitive", "affirmative", - "affixiation", "affiliation", - "affrimative", "affirmative", - "afgahnistan", "afghanistan", - "afganhistan", "afghanistan", - "afghanastan", "afghanistan", - "afghansitan", "afghanistan", - "afhganistan", "afghanistan", - "afternarket", "aftermarket", - "afterthougt", "afterthought", - "aggaravates", "aggravates", - "aggragating", "aggravating", - "aggregatore", "aggregate", - "aggressivly", "aggressively", - "aggresssion", "aggression", - "aggrovating", "aggravating", - "agnostacism", "agnosticism", - "agnostisicm", "agnosticism", - "agnostisism", "agnosticism", - "agnostocism", "agnosticism", - "agnsoticism", "agnosticism", - "agonsticism", "agnosticism", - "agressively", "aggressively", - "agressivley", "agressive", - "agressivnes", "agressive", - "agricolture", "agriculture", - "agriculteur", "agriculture", - "agricultral", "agricultural", - "agricultual", "agricultural", - "agricutlure", "agriculture", - "ahtleticism", "athleticism", - "alcoholicas", "alcoholics", - "alcoholicos", "alcoholics", - "alcoholisim", "alcoholism", - "algorithems", "algorithm", - "algorithims", "algorithm", - "algorithmes", "algorithms", - "algorithmns", "algorithms", - "algorithmus", "algorithms", - "algorithyms", "algorithm", - "algorythims", "algorithms", - "alientating", "alienating", - "alleigances", "allegiance", - "alltogether", "altogether", - "alterantive", "alternative", - "alternatley", "alternately", - "alternitive", "alternative", - "altheticism", "athleticism", - "altnerately", "alternately", - "altruisitic", "altruistic", - "altruistric", "altruistic", - "amalgomated", "amalgamated", - "ambulancier", "ambulance", - "amerliorate", "ameliorate", - "ammendments", "amendments", - "ampehtamine", "amphetamine", - "ampethamine", "amphetamine", - "amphetamies", "amphetamines", - "amphetamins", "amphetamines", - "amphetemine", "amphetamine", - "amphetimine", "amphetamine", - "amphetmaine", "amphetamines", - "analyticals", "analytics", - "anarchistes", "anarchists", - "ancedotally", "anecdotally", - "androgenous", "androgynous", - "anecdatally", "anecdotally", - "anecdotelly", "anecdotally", - "anecodtally", "anecdotally", - "anectodally", "anecdotally", - "anectotally", "anecdotally", - "anedoctally", "anecdotally", - "angosticism", "agnosticism", - "anihilation", "annihilation", - "anitbiotics", "antibiotics", - "annihalated", "annihilated", - "annihilaton", "annihilation", - "annihilited", "annihilated", - "annihliated", "annihilated", - "annilihated", "annihilated", - "anniversery", "anniversary", - "annonymouse", "anonymous", - "announceing", "announcing", - "announcemet", "announcements", - "announcemnt", "announcement", - "announcents", "announces", - "annoymously", "anonymously", - "anonamously", "anonymously", - "anonimously", "anonymously", - "anonmyously", "anonymously", - "anonomously", "anonymously", - "anonymousny", "anonymously", - "anouncement", "announcement", - "antagonisic", "antagonistic", - "antagonistc", "antagonistic", - "antagonstic", "antagonist", - "anthropolgy", "anthropology", - "anthropoloy", "anthropology", - "antibiodics", "antibiotics", - "antibioitcs", "antibiotic", - "antibioitic", "antibiotic", - "antibitoics", "antibiotics", - "antiboitics", "antibiotics", - "anticapated", "anticipated", - "anticiapted", "anticipated", - "anticipatin", "anticipation", - "antiobitics", "antibiotic", - "antiquaited", "antiquated", - "antisipated", "anticipated", - "apacolyptic", "apocalyptic", - "apocaliptic", "apocalyptic", - "apocalpytic", "apocalyptic", - "apocalytpic", "apocalyptic", - "apolagizing", "apologizing", - "apolegetics", "apologetics", - "apologistas", "apologists", - "apologistes", "apologists", - "apostrophie", "apostrophe", - "apparantely", "apparently", - "appareances", "appearances", - "apparentely", "apparently", - "appartments", "apartments", - "appeareance", "appearance", - "appearences", "appearances", - "apperciated", "appreciated", - "apperciates", "appreciates", - "appereances", "appearances", - "applicabile", "applicable", - "applicaiton", "application", - "applicatins", "applicants", - "applicatons", "applications", - "appoitnment", "appointments", - "apporaching", "approaching", - "apporpriate", "appropriate", - "apporximate", "approximate", - "appraoching", "approaching", - "apprearance", "appearance", - "apprecaited", "appreciated", - "apprecaites", "appreciates", - "appreciaite", "appreciative", - "appreciatie", "appreciative", - "appreciatin", "appreciation", - "appreciaton", "appreciation", - "appreciatve", "appreciative", - "appreicated", "appreciated", - "appreicates", "appreciates", - "apprentince", "apprentice", - "appriciated", "appreciated", - "appriciates", "appreciates", - "apprieciate", "appreciate", - "appropirate", "appropriate", - "appropraite", "appropriate", - "appropriato", "appropriation", - "approxamate", "approximate", - "approxiamte", "approximate", - "approxmiate", "approximate", - "aprehensive", "apprehensive", - "apsirations", "aspirations", - "aqcuisition", "acquisition", - "aquaintance", "acquaintance", - "aquiantance", "acquaintance", - "arbitrairly", "arbitrarily", - "arbitralily", "arbitrarily", - "arbitrarely", "arbitrarily", - "arbitrarion", "arbitration", - "arbitratily", "arbitrarily", - "arbritarily", "arbitrarily", - "arbritation", "arbitration", - "arcaheology", "archaeology", - "archaoelogy", "archeology", - "archeaology", "archaeology", - "archimedian", "archimedean", - "architechts", "architect", - "architectes", "architects", - "architecure", "architecture", - "argiculture", "agriculture", - "argumentate", "argumentative", - "aribtrarily", "arbitrarily", - "aribtration", "arbitration", - "arithmentic", "arithmetic", - "arithmethic", "arithmetic", - "arithmetric", "arithmetic", - "armagedddon", "armageddon", - "armageddeon", "armageddon", - "arrangments", "arrangements", - "arrengement", "arrangement", - "articluated", "articulated", - "articualted", "articulated", - "artifically", "artificially", - "artificialy", "artificially", - "aspergerers", "aspergers", - "asphyxation", "asphyxiation", - "aspriations", "aspirations", - "assasinated", "assassinated", - "assasinates", "assassinates", - "assassiante", "assassinate", - "assassinare", "assassinate", - "assassinatd", "assassinated", - "assassinato", "assassination", - "assassinats", "assassins", - "assassinted", "assassinated", - "assembleing", "assembling", - "assemblying", "assembling", - "assertation", "assertion", - "assignemnts", "assignments", - "assimialted", "assimilate", - "assimilatie", "assimilate", - "assimilerat", "assimilate", - "assimiliate", "assimilate", - "assimliated", "assimilate", - "assingments", "assignments", - "assistantes", "assistants", - "assocaition", "associations", - "associaiton", "associations", - "associaties", "associates", - "associatons", "associations", - "assoication", "association", - "assosiating", "associating", - "assosiation", "association", - "assoziation", "association", - "assumptious", "assumptions", - "astonashing", "astonishing", - "astonoshing", "astonishing", - "astronaught", "astronaut", - "astronaunts", "astronaut", - "astronautas", "astronauts", - "astronautes", "astronauts", - "asychronous", "asynchronous", - "asyncronous", "asynchronous", - "atatchments", "attachments", - "atheistisch", "atheistic", - "athelticism", "athleticism", - "athletecism", "athleticism", - "athleticsim", "athleticism", - "athletisicm", "athleticism", - "athletisism", "athleticism", - "atmopsheric", "atmospheric", - "atmoshperic", "atmospheric", - "atmosoheric", "atmospheric", - "atomspheric", "atmospheric", - "atrocitites", "atrocities", - "attachemnts", "attachments", - "attackerasu", "attackers", - "attackerats", "attackers", - "attactments", "attachments", - "attributred", "attributed", - "attributted", "attribute", - "attrocities", "atrocities", - "audiobookas", "audiobooks", - "audioboooks", "audiobook", - "auotcorrect", "autocorrect", - "austrailans", "australians", - "austrailian", "australian", - "australiaan", "australians", - "australiams", "australians", - "australiens", "australians", - "australlian", "australian", - "authenticiy", "authenticity", - "authenticor", "authenticator", - "authenticty", "authenticity", - "authorative", "authoritative", - "authoritate", "authoritative", - "authoroties", "authorities", - "autoatttack", "autoattack", - "autocoreect", "autocorrect", - "autocorrekt", "autocorrect", - "autocorrent", "autocorrect", - "autocorrext", "autocorrect", - "autoctonous", "autochthonous", - "autokorrect", "autocorrect", - "automaticly", "automatically", - "automatonic", "automation", - "automoblies", "automobile", - "auxillaries", "auxiliaries", - "availabiliy", "availability", - "availabilty", "availability", - "availablity", "availability", - "awesoneness", "awesomeness", - "babysittter", "babysitter", - "backbacking", "backpacking", - "backgorunds", "backgrounds", - "backhacking", "backpacking", - "backjacking", "backpacking", - "backtacking", "backpacking", - "bangaldeshi", "bangladesh", - "bangladesch", "bangladesh", - "barceloneta", "barcelona", - "bargainning", "bargaining", - "battelfield", "battlefield", - "battelfront", "battlefront", - "battelships", "battleship", - "battlefeild", "battlefield", - "battlefiend", "battlefield", - "battlefiled", "battlefield", - "battlefornt", "battlefront", - "battlehsips", "battleship", - "beastiality", "bestiality", - "beaurocracy", "bureaucracy", - "beautyfully", "beautifully", - "behaviorial", "behavioral", - "belittleing", "belittling", - "belittlling", "belittling", - "belligerant", "belligerent", - "belligirent", "belligerent", - "bellweather", "bellwether", - "benefitical", "beneficial", - "bestiallity", "bestiality", - "beuatifully", "beautifully", - "beuraucracy", "bureaucracy", - "beuraucrats", "bureaucrats", - "billegerent", "belligerent", - "billionairs", "billionaires", - "billionarie", "billionaire", - "billioniare", "billionaire", - "biologicaly", "biologically", - "birthdayers", "birthdays", - "birthdaymas", "birthdays", - "bittersweat", "bittersweet", - "bitterwseet", "bittersweet", - "blackberrry", "blackberry", - "blacksmitch", "blacksmith", - "bloodboorne", "bloodborne", - "bluebarries", "blueberries", - "blueburries", "blueberries", - "blueprients", "blueprints", - "bodybuildig", "bodybuilding", - "bodybuildng", "bodybuilding", - "bodybuiling", "bodybuilding", - "bombardeada", "bombarded", - "bombardeado", "bombarded", - "bombarderad", "bombarded", - "bordelrands", "borderlands", - "bordlerands", "borderlands", - "bortherhood", "brotherhood", - "bourgeousie", "bourgeois", - "boycottting", "boycotting", - "bracelettes", "bracelets", - "brainwahsed", "brainwashed", - "brainwasing", "brainwashing", - "braziliians", "brazilians", - "breakthough", "breakthrough", - "breakthrouh", "breakthrough", - "breathtakng", "breathtaking", - "brianwashed", "brainwashed", - "brillaintly", "brilliantly", - "broadcasing", "broadcasting", - "broadcastes", "broadcasts", - "broderlands", "borderlands", - "brotherwood", "brotherhood", - "buddhistisk", "buddhists", - "buearucrats", "bureaucrats", - "bueraucracy", "bureaucracy", - "bueraucrats", "bureaucrats", - "buisnessman", "businessman", - "buisnessmen", "businessmen", - "bullerproof", "bulletproof", - "bulletbroof", "bulletproof", - "bulletproff", "bulletproof", - "bulletprrof", "bulletproof", - "bullitproof", "bulletproof", - "bureacuracy", "bureaucracy", - "bureaocracy", "bureaucracy", - "bureaocrats", "bureaucrats", - "bureaucraps", "bureaucrats", - "bureaucrash", "bureaucrats", - "bureaucrasy", "bureaucrats", - "bureaucrazy", "bureaucracy", - "bureuacracy", "bureaucracy", - "bureuacrats", "bureaucrats", - "burueacrats", "bureaucrats", - "businessnes", "businessmen", - "busniessmen", "businessmen", - "butterfiles", "butterflies", - "butterfleye", "butterfly", - "butterflyes", "butterflies", - "butterfries", "butterflies", - "butterlfies", "butterflies", - "caclulating", "calculating", - "caclulation", "calculation", - "caclulators", "calculators", - "cailbration", "calibration", - "calbiration", "calibration", - "calcualting", "calculating", - "calcualtion", "calculations", - "calcualtors", "calculators", - "calculaters", "calculators", - "calculatios", "calculators", - "calculatons", "calculations", - "calibartion", "calibration", - "calibraiton", "calibration", - "califorinan", "californian", - "californain", "californian", - "californica", "california", - "californien", "californian", - "californiia", "californian", - "californina", "californian", - "californnia", "californian", - "califronian", "californian", - "caluclating", "calculating", - "caluclation", "calculation", - "caluclators", "calculators", - "caluculated", "calculated", - "caluiflower", "cauliflower", - "camouflague", "camouflage", - "camouflauge", "camouflage", - "campagining", "campaigning", - "campainging", "campaigning", - "canadianese", "canadians", - "cannabilism", "cannibalism", - "cannabolism", "cannibalism", - "canniablism", "cannibalism", - "cannibalizm", "cannibalism", - "cannibaljim", "cannibalism", - "cannibalsim", "cannibalism", - "cannibilism", "cannibalism", - "cannobalism", "cannibalism", - "cannotation", "connotation", - "capabilites", "capabilities", - "capabilitiy", "capability", - "capabillity", "capability", - "capacitaron", "capacitor", - "capacitores", "capacitors", - "capatilists", "capitalists", - "capatilized", "capitalized", - "caperbility", "capability", - "capitalisim", "capitalism", - "capitilists", "capitalists", - "capitilized", "capitalized", - "capitolists", "capitalists", - "capitolized", "capitalized", - "captialists", "capitalists", - "captialized", "capitalized", - "cariactures", "caricature", - "carniverous", "carnivorous", - "castatrophe", "catastrophe", - "catagorized", "categorized", - "catapillars", "caterpillars", - "catapillers", "caterpillars", - "catasthrope", "catastrophe", - "catastraphe", "catastrophe", - "catastrohpe", "catastrophe", - "catastropic", "catastrophic", - "categroized", "categorized", - "catepillars", "caterpillars", - "catergorize", "categorize", - "caterogized", "categorized", - "caterpilars", "caterpillars", - "caterpiller", "caterpillar", - "catholacism", "catholicism", - "catholicsim", "catholicism", - "catholisicm", "catholicism", - "catholisism", "catholicism", - "catholizism", "catholicism", - "catholocism", "catholicism", - "catogerized", "categorized", - "catterpilar", "caterpillar", - "cauilflower", "cauliflower", - "caulfilower", "cauliflower", - "celebartion", "celebrations", - "celebirties", "celebrities", - "celebracion", "celebration", - "celebrasion", "celebrations", - "celebratons", "celebrations", - "centipeddle", "centipede", - "cerimonious", "ceremonious", - "certaintity", "certainty", - "certificaat", "certificate", - "certificare", "certificate", - "certificato", "certification", - "certificats", "certificates", - "challanging", "challenging", - "challeneged", "challenged", - "challeneger", "challenger", - "challeneges", "challenges", - "chameleooon", "chameleon", - "championshp", "championship", - "championsip", "championship", - "chancellour", "chancellor", - "charachters", "characters", - "charasmatic", "charismatic", - "charimastic", "charismatic", - "charsimatic", "charismatic", - "cheerleadra", "cheerleader", - "cheerleards", "cheerleaders", - "cheerleeder", "cheerleader", - "cheesebuger", "cheeseburger", - "cheeseburgs", "cheeseburgers", - "chihuahuita", "chihuahua", - "childrenmrs", "childrens", - "chloesterol", "cholesterol", - "cholesteral", "cholesterol", - "cholestoral", "cholesterol", - "cholestorol", "cholesterol", - "cholosterol", "cholesterol", - "chormosomes", "chromosomes", - "christianty", "christianity", - "chromasomes", "chromosomes", - "chromesomes", "chromosomes", - "chromisomes", "chromosomes", - "chromosones", "chromosomes", - "chromossome", "chromosomes", - "chromozomes", "chromosomes", - "chronicales", "chronicles", - "chronichles", "chronicles", - "cicrulating", "circulating", - "cincinnasti", "cincinnati", - "cincinnatti", "cincinnati", - "cincinnnati", "cincinnati", - "circimcised", "circumcised", - "circluating", "circulating", - "circualtion", "circulation", - "circulacion", "circulation", - "circumcison", "circumcision", - "circumsiced", "circumcised", - "circumsised", "circumcised", - "circumstace", "circumstance", - "circumvrent", "circumvent", - "circuncised", "circumcised", - "cirticising", "criticising", - "ciruclating", "circulating", - "ciruclation", "circulation", - "citicenship", "citizenship", - "citisenship", "citizenship", - "citizinship", "citizenship", - "civilizatin", "civilizations", - "civilizaton", "civilization", - "claculators", "calculators", - "classifides", "classified", - "cleanilness", "cleanliness", - "cleanleness", "cleanliness", - "cleanlyness", "cleanliness", - "cleansiness", "cleanliness", - "cliffbanger", "cliffhanger", - "cliffhander", "cliffhanger", - "cliffhangar", "cliffhanger", - "clifthanger", "cliffhanger", - "cockaroches", "cockroaches", - "cockraoches", "cockroaches", - "cockroackes", "cockroaches", - "cocktailers", "cocktails", - "coefficeint", "coefficient", - "coefficiant", "coefficient", - "coincedince", "coincidence", - "coincidance", "coincidence", - "coincidense", "coincidence", - "coincidente", "coincidence", - "coincidince", "coincidence", - "coinsidence", "coincidence", - "collabarate", "collaborate", - "collaberate", "collaborate", - "collaborant", "collaborate", - "collaborare", "collaborate", - "collaborato", "collaboration", - "collapseing", "collapsing", - "collaterial", "collateral", - "collectieve", "collective", - "collectivly", "collectively", - "collectivos", "collections", - "collobarate", "collaborate", - "colloborate", "collaborate", - "colonializm", "colonialism", - "colonialsim", "colonialism", - "colonianism", "colonialism", - "colonizaton", "colonization", - "comaprisons", "comparisons", - "combiantion", "combinations", - "combinacion", "combination", - "combinaison", "combinations", - "combinaiton", "combinations", - "combinatino", "combinations", - "combinatins", "combinations", - "combinatios", "combinations", - "combinining", "combining", - "combonation", "combination", - "comediantes", "comedians", - "comeptition", "competition", - "comeptitive", "competitive", - "comeptitors", "competitors", - "comfertable", "comfortable", - "comfertably", "comfortably", - "comfortabel", "comfortably", - "comfortabil", "comfortably", - "comfrotable", "comfortable", - "comftorable", "comfortable", - "comftorably", "comfortably", - "comisioning", "commissioning", - "comissioned", "commissioned", - "comissioner", "commissioner", - "commandered", "commanded", - "commandmant", "commandment", - "commantator", "commentator", - "commendment", "commandment", - "commentarea", "commenter", - "commentaren", "commenter", - "commentater", "commentator", - "commenteers", "commenter", - "commentries", "commenters", - "commercialy", "commercially", - "commericals", "commercials", - "commericial", "commercial", - "comminicate", "communicate", - "comminucate", "communicate", - "commisioned", "commissioned", - "commisioner", "commissioner", - "commisssion", "commissions", - "committment", "commitment", - "commodoties", "commodities", - "commomplace", "commonplace", - "commonspace", "commonplace", - "commonweath", "commonwealth", - "commonwelth", "commonwealth", - "commuincate", "communicated", - "communciate", "communicate", - "communicted", "communicated", - "communistas", "communists", - "communistes", "communists", - "compability", "compatibility", - "compalation", "compilation", - "compansated", "compensated", - "comparabile", "comparable", - "comparasion", "comparison", - "comparasons", "comparisons", - "comparement", "compartment", - "comparetive", "comparative", - "comparision", "comparison", - "comparisson", "comparisons", - "comparitave", "comparative", - "comparitive", "comparative", - "comparsions", "comparisons", - "compassione", "compassionate", - "compasssion", "compassion", - "compatabile", "compatible", - "compatative", "comparative", - "compatiable", "compatible", - "compatibile", "compatible", - "compatibily", "compatibility", - "compeditive", "competitive", - "compeditors", "competitors", - "compeitions", "competitions", - "compeittion", "competitions", - "compelation", "compilation", - "compensante", "compensate", - "compensatie", "compensate", - "compensatin", "compensation", - "compenstate", "compensate", - "comperative", "comparative", - "compesition", "composition", - "competation", "computation", - "competative", "competitive", - "competators", "competitors", - "competetion", "competition", - "competetors", "competitors", - "competiters", "competitors", - "competiting", "competition", - "competitior", "competitor", - "competitivo", "competition", - "competitoin", "competitions", - "competitons", "competitors", - "competution", "computation", - "compilacion", "compilation", - "compilcated", "complicate", - "compination", "compilation", - "compinsated", "compensated", - "compitation", "computation", - "compitetion", "competitions", - "complacient", "complacent", - "complciated", "complicate", - "compleation", "compilation", - "complecated", "complicated", - "completaste", "completes", - "completeing", "completing", - "completeion", "completion", - "completelly", "completely", - "completelyl", "completely", - "completelys", "completes", - "completenes", "completes", - "complexitiy", "complexity", - "compliacted", "complicate", - "compliation", "compilation", - "complicarte", "complicate", - "complicatie", "complicit", - "complicatii", "complicit", - "complicatin", "complicit", - "complictaed", "complicate", - "complimente", "complement", - "complimenty", "complimentary", - "complusions", "compulsion", - "compolation", "compilation", - "componenets", "components", - "componentes", "components", - "composicion", "composition", - "composiiton", "compositions", - "composision", "compositions", - "compositied", "composite", - "composities", "composite", - "compositoin", "compositions", - "compositons", "compositions", - "compositore", "composite", - "compostiion", "compositions", - "compotition", "composition", - "compramised", "compromised", - "compramises", "compromises", - "compremised", "compromised", - "compremises", "compromises", - "comprension", "compression", - "compresores", "compressor", - "compresssed", "compressed", - "compresssor", "compressor", - "comprimised", "compromised", - "comprimises", "compromises", - "compromessi", "compromises", - "compromisng", "compromising", - "compromisse", "compromises", - "compromisso", "compromises", - "compromized", "compromised", - "compulstion", "compulsion", - "compunation", "computation", - "computacion", "computation", - "computating", "computation", - "computition", "computation", - "conceivibly", "conceivably", - "concencrate", "concentrate", - "concentrace", "concentrate", - "concentrade", "concentrated", - "concentrait", "concentrate", - "concentrant", "concentrate", - "concentrare", "concentrate", - "concentrato", "concentration", - "concertmate", "concentrate", - "conceviable", "conceivable", - "conceviably", "conceivably", - "concidering", "considering", - "conciveable", "conceivable", - "conciveably", "conceivably", - "conclsuions", "concussions", - "concludendo", "concluded", - "conclussion", "conclusions", - "conclussive", "conclusive", - "conclutions", "conclusions", - "concsiously", "consciously", - "conculsions", "conclusions", - "concusssion", "concussions", - "condeferacy", "confederacy", - "condicional", "conditional", - "condidtions", "conditions", - "conditionar", "conditioner", - "conditionel", "conditional", - "condolances", "condolences", - "condolenses", "condolences", - "condolonces", "condolences", - "conductiong", "conducting", - "condulences", "condolences", - "conenctions", "connections", - "conescutive", "consecutive", - "confedaracy", "confederacy", - "confedarate", "confederate", - "confederecy", "confederacy", - "conferances", "conferences", - "conferedate", "confederate", - "confererate", "confederate", - "confescated", "confiscated", - "confesssion", "confessions", - "confidantly", "confidently", - "configurare", "configure", - "configurate", "configure", - "configurato", "configuration", - "confilcting", "conflicting", - "confisgated", "confiscated", - "conflciting", "conflicting", - "confortable", "comfortable", - "confrontato", "confrontation", - "confussions", "confessions", - "congrassman", "congressman", - "congratuate", "congratulate", - "conicidence", "coincidence", - "conjonction", "conjunction", - "conjucntion", "conjunction", - "conjuncting", "conjunction", - "conlcusions", "conclusions", - "connatation", "connotation", - "connecitcut", "connecticut", - "connecticon", "connection", - "connectiong", "connecting", - "connectivty", "connectivity", - "connetation", "connotation", - "connonation", "connotation", - "connotacion", "connotation", - "conontation", "connotation", - "conotations", "connotations", - "conquerring", "conquering", - "consdidered", "considered", - "consectuive", "consecutive", - "consecuence", "consequence", - "conseguence", "consequence", - "conselation", "consolation", - "consentrate", "concentrate", - "consequenes", "consequence", - "consequense", "consequences", - "consequente", "consequence", - "consequenty", "consequently", - "consequtive", "consecutive", - "conservanti", "conservation", - "conservatie", "conservatives", - "conservaton", "conservation", - "consficated", "confiscated", - "considerabe", "considerate", - "considerais", "considers", - "considerant", "considerate", - "considerato", "consideration", - "considerble", "considerable", - "considerbly", "considerably", - "considereis", "considers", - "consilation", "consolation", - "consilidate", "consolidate", - "consistance", "consistency", - "consistenly", "consistently", - "consistensy", "consistency", - "consistenty", "consistently", - "consitution", "constitution", - "conslutants", "consultant", - "consolacion", "consolation", - "consoldiate", "consolidate", - "consolidare", "consolidate", - "consolodate", "consolidate", - "consomation", "consolation", - "conspiraces", "conspiracies", - "conspiracys", "conspiracies", - "conspirancy", "conspiracy", - "constantins", "constants", - "constantivs", "constants", - "constarints", "constraint", - "constituant", "constituent", - "constituion", "constitution", - "constituite", "constitute", - "constitutie", "constitutes", - "constrating", "constraint", - "constriants", "constraints", - "construcing", "constructing", - "construcion", "construction", - "construcive", "constructive", - "constructie", "constructive", - "constructos", "constructs", - "constructur", "constructor", - "constructus", "constructs", - "constuction", "construction", - "consturcted", "constructed", - "consuelling", "counselling", - "consulation", "consolation", - "consultaion", "consultation", - "consultanti", "consultation", - "consumation", "consumption", - "consumbales", "consumables", - "consumersim", "consumerism", - "consumibles", "consumables", - "contagiosum", "contagious", - "containered", "contained", - "containmemt", "containment", - "containters", "containers", - "containting", "containing", - "contaminato", "contamination", - "contaminent", "containment", - "contaminted", "contaminated", - "contancting", "contracting", - "contanimate", "contaminated", - "contemplare", "contemplate", - "contempoary", "contemporary", - "contemporay", "contemporary", - "contencious", "contentious", - "contenental", "continental", - "contengency", "contingency", - "contenintal", "continental", - "contenplate", "contemplate", - "contensious", "contentious", - "contentants", "contestants", - "contentuous", "contentious", - "contestaste", "contestants", - "contestents", "contestants", - "contianment", "containment", - "contientous", "contentious", - "contimplate", "contemplate", - "continenets", "continents", - "continentes", "continents", - "continentul", "continental", - "contingancy", "contingency", - "contingient", "contingent", - "contingincy", "contingency", - "continously", "continuously", - "continuarla", "continual", - "continuarlo", "continual", - "continuasse", "continues", - "continueing", "continuing", - "continuemos", "continues", - "continueous", "continuous", - "continuious", "continuous", - "continuning", "continuing", - "continunity", "continuity", - "continuosly", "continuously", - "continuting", "continuing", - "continutity", "continuity", - "continuuing", "continuing", - "continuuity", "continuity", - "contirbuted", "contributed", - "contiunally", "continually", - "contraccion", "contraction", - "contraddice", "contradicted", - "contradices", "contradicts", - "contradtion", "contraction", - "contraversy", "controversy", - "contreversy", "controversy", - "contribuent", "contribute", - "contribuito", "contribution", - "contributer", "contributor", - "contributie", "contribute", - "contributin", "contribution", - "contributos", "contributors", - "contribuyes", "contributes", - "contricting", "contracting", - "contriction", "contraction", - "contridicts", "contradicts", - "contriversy", "controversy", - "controleurs", "controllers", - "controllore", "controllers", - "controvercy", "controversy", - "controversa", "controversial", - "contrubutes", "contributes", - "contructing", "contracting", - "contruction", "construction", - "contructors", "contractors", - "conveinence", "convenience", - "conveneince", "convenience", - "conveniance", "convenience", - "conveniente", "convenience", - "convenietly", "conveniently", - "conventinal", "conventional", - "converitble", "convertible", - "conversaion", "conversion", - "conversatin", "conversations", - "converseley", "conversely", - "converstion", "conversion", - "convertirea", "converter", - "convertirle", "convertible", - "convertirme", "converter", - "convertirte", "converter", - "convicitons", "convictions", - "convienence", "convenience", - "convienient", "convenient", - "convinceing", "convincing", - "convincente", "convenient", - "convincersi", "convinces", - "convirtible", "convertible", - "cooperacion", "cooperation", - "cooperativo", "cooperation", - "cooporation", "cooperation", - "cooporative", "cooperative", - "coordenated", "coordinated", - "coordenates", "coordinates", - "coordianted", "coordinated", - "coordiantes", "coordinates", - "coordiantor", "coordinator", - "coordinador", "coordinator", - "coordinants", "coordinates", - "coordinater", "coordinator", - "coordinaton", "coordination", - "coordonated", "coordinated", - "coordonates", "coordinates", - "coordonator", "coordinator", - "cooridnated", "coordinated", - "cooridnates", "coordinates", - "cooridnator", "coordinator", - "copenhaagen", "copenhagen", - "copenhaegen", "copenhagen", - "copenhaguen", "copenhagen", - "copenhangen", "copenhagen", - "copmetitors", "competitors", - "coproration", "corporation", - "copyrigthed", "copyrighted", - "corinthains", "corinthians", - "corintheans", "corinthians", - "corinthiens", "corinthians", - "corinthinas", "corinthians", - "cornithians", "corinthians", - "corparation", "corporation", - "corperation", "corporation", - "corporacion", "corporation", - "corporativo", "corporation", - "corralation", "correlation", - "correctings", "corrections", - "correctivos", "corrections", - "correktions", "corrections", - "correktness", "correctness", - "correlacion", "correlation", - "correlaties", "correlates", - "corrilation", "correlation", - "corrisponds", "corresponds", - "corrolation", "correlation", - "corrosponds", "corresponds", - "costitution", "constitution", - "councellors", "councillors", - "counrtyside", "countryside", - "counsilling", "counselling", - "countercoat", "counteract", - "counteredit", "counterfeit", - "counterfact", "counteract", - "counterfait", "counterfeit", - "counterfest", "counterfeit", - "counterfiet", "counterfeit", - "counterpaly", "counterplay", - "counterpary", "counterplay", - "counterpath", "counterpart", - "counterpats", "counterparts", - "counterpont", "counterpoint", - "counterract", "counterpart", - "counterside", "countryside", - "countertrap", "counterpart", - "countriside", "countryside", - "countrycide", "countryside", - "countrywise", "countryside", - "courthourse", "courthouse", - "coutnerfeit", "counterfeit", - "coutnerpart", "counterpart", - "coutnerplay", "counterplay", - "creacionism", "creationism", - "creationkit", "creationist", - "creationsim", "creationism", - "creationsit", "creationist", - "creationsts", "creationists", - "creativelly", "creatively", - "credencials", "credentials", - "credentails", "credentials", - "credentaisl", "credentials", - "credientals", "credentials", - "credintials", "credentials", - "cricitising", "criticising", - "criculating", "circulating", - "cringeworhy", "cringeworthy", - "cringeworty", "cringeworthy", - "cringewothy", "cringeworthy", - "criticicing", "criticising", - "criticisied", "criticise", - "criticisims", "criticisms", - "criticisize", "criticise", - "criticiszed", "criticise", - "critisicing", "criticizing", - "critisising", "criticising", - "critizicing", "criticizing", - "critizising", "criticizing", - "critizizing", "criticizing", - "crockodiles", "crocodiles", - "crocodiller", "crocodile", - "crocodilule", "crocodile", - "croporation", "corporation", - "crossfiters", "crossfire", - "cultivative", "cultivate", - "curricullum", "curriculum", - "customizabe", "customizable", - "customizble", "customizable", - "dangeroulsy", "dangerously", - "dardenelles", "dardanelles", - "deadlifters", "deadlifts", - "dealershits", "dealerships", - "deceptivley", "deceptive", - "declaracion", "declaration", - "decleration", "declaration", - "declinining", "declining", - "decloration", "declaration", - "decoartions", "decoration", - "decomposits", "decomposes", - "decoratieve", "decorative", - "decorativos", "decorations", - "decotations", "decorations", - "decsendants", "descendants", - "deductiable", "deductible", - "defenderlas", "defenders", - "defenderlos", "defenders", - "defendernos", "defenders", - "defenesless", "defenseless", - "defenisvely", "defensively", - "defensivley", "defensively", - "deficiencey", "deficiency", - "deficienies", "deficiencies", - "deficientcy", "deficiency", - "definantley", "definately", - "definatedly", "definately", - "definateley", "definately", - "definatelly", "definately", - "definatelty", "definately", - "definatetly", "definately", - "definations", "definitions", - "definatlely", "definately", - "definetally", "definately", - "definetlely", "definetly", - "definitaley", "definately", - "definitelly", "definitely", - "definitevly", "definitively", - "definitiely", "definitively", - "definitieve", "definitive", - "definitiley", "definitively", - "definitivly", "definitively", - "definitivno", "definition", - "definitivos", "definitions", - "definitlely", "definitly", - "definitlety", "definitly", - "deflecticon", "deflection", - "degenererat", "degenerate", - "degradacion", "degradation", - "degradating", "degradation", - "degragation", "degradation", - "degridation", "degradation", - "dehyrdation", "dehydration", - "deinitalize", "deinitialize", - "delaerships", "dealerships", - "delapidated", "dilapidated", - "delcaration", "declaration", - "delearships", "dealerships", - "delevopment", "development", - "deliberante", "deliberate", - "deliberatly", "deliberately", - "deliberetly", "deliberately", - "delightlful", "delightful", - "deliverying", "delivering", - "delusionnal", "delusional", - "deminsional", "dimensional", - "democarcies", "democracies", - "democracize", "democracies", - "democractic", "democratic", - "democraphic", "demographic", - "democrasies", "democracies", - "democrazies", "democracies", - "democrocies", "democracies", - "demograhpic", "demographic", - "demographis", "demographics", - "demograpics", "demographics", - "demogrpahic", "demographic", - "demoninator", "denominator", - "demonstarte", "demonstrate", - "demonstates", "demonstrates", - "demonstraby", "demonstrably", - "demonstrant", "demonstrate", - "demonstrats", "demonstrates", - "demosntrate", "demonstrate", - "denegrating", "denigrating", - "denomenator", "denominator", - "denominador", "denominator", - "denominaron", "denominator", - "denominater", "denominator", - "denominaton", "denomination", - "denomitator", "denominator", - "denomonator", "denominator", - "denonimator", "denominator", - "deocrations", "decorations", - "deomcracies", "democracies", - "deparmental", "departmental", - "depedencies", "dependencies", - "dependancey", "dependency", - "dependencey", "dependency", - "dependencie", "dependence", - "dependenies", "dependencies", - "deplorabile", "deplorable", - "depressieve", "depressive", - "depresssion", "depression", - "deprevation", "deprivation", - "deprication", "deprivation", - "deprivating", "deprivation", - "deprivition", "deprivation", - "deprovation", "deprivation", - "depserately", "desperately", - "depseration", "desperation", - "deregulatin", "deregulation", - "derivativos", "derivatives", - "derivitaves", "derivatives", - "derivitives", "derivatives", - "derpivation", "deprivation", - "derviatives", "derivatives", - "descandants", "descendants", - "descendands", "descendants", - "descendends", "descended", - "descendenta", "descendants", - "descentants", "descendants", - "descirption", "descriptions", - "descprition", "descriptions", - "describiste", "describes", - "describtion", "description", - "descripcion", "description", - "descripiton", "descriptions", - "descripters", "descriptors", - "descriptoin", "descriptions", - "descriptons", "descriptions", - "descritpion", "descriptions", - "descrpition", "descriptions", - "desensitied", "desensitized", - "desensitzed", "desensitized", - "desentisize", "desensitized", - "desgination", "designation", - "designacion", "designation", - "designstion", "designation", - "desinations", "destinations", - "desingation", "designation", - "desitnation", "destination", - "desoriented", "disoriented", - "desparately", "desperately", - "desparation", "desperation", - "desperating", "desperation", - "desperatley", "desperately", - "despirately", "desperately", - "despiration", "desperation", - "destablized", "destabilized", - "destiantion", "destinations", - "destinaiton", "destinations", - "destinatons", "destinations", - "destinction", "destination", - "destraction", "destruction", - "destruccion", "destruction", - "destruciton", "destruction", - "destructivo", "destruction", - "destruktion", "destruction", - "destruktive", "destructive", - "deteoriated", "deteriorated", - "determanism", "determinism", - "determening", "determining", - "determenism", "determinism", - "determinare", "determine", - "determinato", "determination", - "determinded", "determine", - "determinsim", "determinism", - "detramental", "detrimental", - "detremental", "detrimental", - "detrimentul", "detrimental", - "detuschland", "deutschland", - "deustchland", "deutschland", - "deutchsland", "deutschland", - "deutcshland", "deutschland", - "deutschalnd", "deutschland", - "deutshcland", "deutschland", - "develepmont", "developments", - "develompent", "developments", - "developemnt", "developments", - "developmant", "developmental", - "developmetn", "developments", - "developmnet", "developments", - "developpers", "developers", - "develpoment", "developments", - "deveolpment", "developments", - "deveploment", "developments", - "devestating", "devastating", - "devistating", "devastating", - "deyhdration", "dehydration", - "diagnositcs", "diagnostic", - "diagnositic", "diagnostic", - "diagonstics", "diagnostic", - "dictatorhip", "dictatorship", - "dictionaire", "dictionaries", - "dictionairy", "dictionary", - "dictionarys", "dictionaries", - "dictionnary", "dictionary", - "differances", "differences", - "differantly", "differently", - "differental", "differential", - "differentes", "differences", - "differneces", "differences", - "differnetly", "differently", - "difficulity", "difficulty", - "difficultes", "difficulties", - "dificulties", "difficulties", - "dimensiones", "dimensions", - "dimentional", "dimensional", - "dimesnional", "dimensional", - "diminisheds", "diminishes", - "diminsihing", "diminishing", - "diminuitive", "diminutive", - "diminushing", "diminishing", - "dinosaurios", "dinosaurs", - "direccional", "directional", - "direcitonal", "directional", - "directorguy", "directory", - "directorios", "directors", - "direktional", "directional", - "disadvantge", "disadvantage", - "disagreemet", "disagreements", - "disagreemtn", "disagreements", - "disapperead", "disappeared", - "disapporval", "disapproval", - "disapprovel", "disapproval", - "disasterous", "disastrous", - "disastreous", "disastrous", - "disastrious", "disastrous", - "disastruous", "disastrous", - "disatisfied", "dissatisfied", - "disciplened", "disciplined", - "disciplinas", "disciplines", - "disciplince", "disciplines", - "disclipined", "disciplined", - "disclipines", "disciplines", - "discogrophy", "discography", - "discogrpahy", "discography", - "disconencts", "disconnects", - "disconneted", "disconnected", - "disconnnect", "disconnect", - "discontined", "discontinued", - "discontiued", "discontinued", - "discrapency", "discrepancy", - "discretited", "discredited", - "discrimante", "discriminate", - "discrimiate", "discriminate", - "discussiong", "discussing", - "discusssion", "discussions", - "disgraseful", "disgraceful", - "disgrateful", "disgraceful", - "disgrunteld", "disgruntled", - "disgustigly", "disgustingly", - "disgustingy", "disgustingly", - "disgustinly", "disgustingly", - "disicplined", "disciplined", - "disicplines", "disciplines", - "disingenuos", "disingenuous", - "dismanlting", "dismantling", - "dismantaled", "dismantled", - "dismanteled", "dismantled", - "disobediant", "disobedient", - "disocgraphy", "discography", - "disparingly", "disparagingly", - "dispensaire", "dispensaries", - "dispensarie", "dispenser", - "dispensiary", "dispensary", - "displacemnt", "displacement", - "disposicion", "disposition", - "disputandem", "disputandum", - "disqualifed", "disqualified", - "disregaring", "disregarding", - "dissapeared", "disappeared", - "dissapoined", "dissapointed", - "dissapointd", "dissapointed", - "dissapoited", "dissapointed", - "dissappears", "disappears", - "dissatisfed", "dissatisfied", - "disscusions", "discussions", - "dissertaion", "dissertation", - "dissipatore", "dissipate", - "distatesful", "distasteful", - "distatseful", "distasteful", - "disterbance", "disturbance", - "disticntion", "distinctions", - "distinciton", "distinction", - "distincitve", "distinctive", - "distinctily", "distinctly", - "distingiush", "distinguish", - "distinguise", "distinguished", - "distinktion", "distinction", - "distinquish", "distinguish", - "distirbance", "disturbance", - "distirbuted", "distribute", - "distirbutor", "distributor", - "distraccion", "distraction", - "distractons", "distracts", - "distraktion", "distraction", - "distribitor", "distributor", - "distribuent", "distribute", - "distribuite", "distribute", - "distribuito", "distribution", - "distributie", "distributed", - "distributin", "distribution", - "distributio", "distributor", - "distrobuted", "distributed", - "distrubance", "disturbance", - "distrubited", "distributed", - "distrubitor", "distributor", - "distrubuted", "distributed", - "distrubutor", "distributor", - "distructive", "destructive", - "distuingish", "distinguish", - "distunguish", "distinguish", - "disturbante", "disturbance", - "disturbence", "disturbance", - "disucssions", "discussions", - "divisionals", "divisions", - "doccumented", "documented", - "documantary", "documentary", - "documenatry", "documentary", - "documentare", "documentaries", - "documentato", "documentation", - "documentery", "documentary", - "documentory", "documentary", - "domesticted", "domesticated", - "dominateurs", "dominates", - "dominationg", "dominating", - "donwloading", "downloading", - "doublellift", "doublelift", - "downlaoding", "downloading", - "downloadbel", "downloadable", - "downloadbig", "downloading", - "downloadble", "downloadable", - "downvoteers", "downvoters", - "downvoteing", "downvoting", - "downvoteres", "downvoters", - "downvoteros", "downvoters", - "downvoteurs", "downvoters", - "downvotters", "downvoters", - "downvotting", "downvoting", - "dramaticaly", "dramatically", - "dramaticlly", "dramatically", - "drasitcally", "drastically", - "dsyfunction", "dysfunction", - "duetschland", "deutschland", - "durabillity", "durability", - "dyanmically", "dynamically", - "dymanically", "dynamically", - "dysfonction", "dysfunction", - "dysfucntion", "dysfunction", - "dysfunciton", "dysfunction", - "dysfunktion", "dysfunction", - "earhtquakes", "earthquakes", - "earthqaukes", "earthquakes", - "earthquacks", "earthquakes", - "economicaly", "economically", - "economiclly", "economically", - "economisiti", "economist", - "economistes", "economists", - "educacional", "educational", - "effeciently", "efficiently", - "effecitvely", "effectively", - "effectivley", "effectively", - "efficeintly", "efficiently", - "efficiantly", "efficiently", - "efficientcy", "efficiently", - "effortlesly", "effortlessly", - "effortlessy", "effortlessly", - "egaletarian", "egalitarian", - "egalitatian", "egalitarian", - "egaliterian", "egalitarian", - "egostitical", "egotistical", - "egotastical", "egotistical", - "egotestical", "egotistical", - "egotisitcal", "egotistical", - "egotisticle", "egotistical", - "egotystical", "egotistical", - "ehtnicities", "ethnicities", - "ejacluation", "ejaculation", - "ejacualtion", "ejaculation", - "electoratul", "electoral", - "electornics", "electronics", - "electricain", "electrician", - "electricial", "electrical", - "electricien", "electrician", - "electricion", "electrician", - "electricman", "electrician", - "electrisity", "electricity", - "electritian", "electrician", - "electrocity", "electricity", - "electrolyes", "electrolytes", - "electrolyts", "electrolytes", - "electroncis", "electrons", - "electroylte", "electrolytes", - "elementrary", "elementary", - "eleminating", "eliminating", - "elimanation", "elimination", - "eliminacion", "elimination", - "elimintates", "eliminates", - "ellipitcals", "elliptical", - "eloquentely", "eloquently", - "emabrassing", "embarassing", - "embaraasing", "embarassing", - "embarasaing", "embarassing", - "embarassign", "embarassing", - "embarassimg", "embarassing", - "embarassing", "embarrassing", - "embarissing", "embarassing", - "embarrasing", "embarrassing", - "embarressed", "embarrassed", - "embarrssing", "embarassing", - "emergancies", "emergencies", - "emergencias", "emergencies", - "emergenices", "emergencies", - "emmediately", "immediately", - "emmisarries", "emissaries", - "emotionella", "emotionally", - "empahsizing", "emphasizing", - "empathethic", "empathetic", - "emphacizing", "emphasizing", - "emphatising", "emphasizing", - "emphatizing", "emphasizing", - "emphazising", "emphasizing", - "emphesizing", "emphasizing", - "empiracally", "empirically", - "empirialism", "imperialism", - "empirialist", "imperialist", - "enchamtment", "enchantment", - "enchancment", "enchantment", - "enchanement", "enchantment", - "enchanthing", "enchanting", - "enchantmant", "enchantment", - "enchantmens", "enchantments", - "enchantmets", "enchantments", - "encomapsses", "encompasses", - "encompasess", "encompasses", - "encompesses", "encompasses", - "encounteres", "encounters", - "encoutnered", "encountered", - "encryptiion", "encryption", - "encyclopdia", "encyclopedia", - "encylopedia", "encyclopedia", - "endagnering", "endangering", - "endandering", "endangering", - "endorcement", "endorsement", - "endoresment", "endorsement", - "engagaments", "engagements", - "engeneering", "engineering", - "enginerring", "engineering", - "enginnering", "engineering", - "enlargments", "enlargements", - "enligthened", "enlightened", - "enourmously", "enormously", - "enterpirses", "enterprises", - "enterprices", "enterprises", - "enterprishe", "enterprises", - "entertainig", "entertaining", - "entertwined", "entertained", - "enthicities", "ethnicities", - "enthisiasts", "enthusiasts", - "enthuasists", "enthusiasts", - "enthuisasts", "enthusiasts", - "enthusaists", "enthusiasts", - "enthusiants", "enthusiast", - "enthusiasic", "enthusiastic", - "enthusiasim", "enthusiasm", - "enthusiasum", "enthusiasm", - "enthusiatic", "enthusiastic", - "enthusiests", "enthusiasts", - "enthusigasm", "enthusiasm", - "enthusisast", "enthusiasts", - "entrepeneur", "entrepreneur", - "entreperure", "entrepreneur", - "entrepeuner", "entrepreneur", - "entreprener", "entrepreneurs", - "entreprenur", "entrepreneur", - "entretained", "entertained", - "envinroment", "environments", - "enviorments", "environments", - "enviornment", "environment", - "envirnoment", "environment", - "enviroments", "environments", - "enviromnent", "environments", - "environemnt", "environment", - "environmnet", "environments", - "envrionment", "environment", - "equilavents", "equivalents", - "equilbirium", "equilibrium", - "equilevants", "equivalents", - "equilibirum", "equilibrium", - "equilibriam", "equilibrium", - "equilibruim", "equilibrium", - "equivalance", "equivalence", - "equivalants", "equivalents", - "equivalenet", "equivalents", - "equivallent", "equivalent", - "equivelance", "equivalence", - "equivelants", "equivalents", - "equivelents", "equivalents", - "equivilants", "equivalents", - "equivilence", "equivalence", - "equivilents", "equivalents", - "equivlalent", "equivalent", - "equivlanets", "equivalents", - "equivolence", "equivalence", - "equivolents", "equivalents", - "essencially", "essentially", - "essentailly", "essentially", - "essentialls", "essentials", - "essentually", "essentially", - "establising", "establishing", - "ethicallity", "ethically", - "ethincities", "ethnicities", - "ethniticies", "ethnicities", - "europeaners", "europeans", - "europeaness", "europeans", - "evaluatiing", "evaluating", - "evaluationg", "evaluating", - "evangalical", "evangelical", - "evangelikal", "evangelical", - "evengalical", "evangelical", - "evenhtually", "eventually", - "everyonehas", "everyones", - "everyonelse", "everyones", - "evidentally", "evidently", - "exacarbated", "exacerbated", - "exacberated", "exacerbated", - "exagerating", "exaggerating", - "exagerrated", "exaggerated", - "exagerrates", "exaggerates", - "exaggarated", "exaggerated", - "exaggareted", "exaggerate", - "exaggeratin", "exaggeration", - "exaggerrate", "exaggerate", - "exaggurated", "exaggerated", - "exarcebated", "exacerbated", - "excalmation", "exclamation", - "excepcional", "exceptional", - "exceptionel", "exceptional", - "excessivley", "excessively", - "exceutioner", "executioner", - "exchanching", "exchanging", - "exclamacion", "exclamation", - "exclamating", "exclamation", - "exclamativo", "exclamation", - "exclemation", "exclamation", - "exclimation", "exclamation", - "exclucivity", "exclusivity", - "exclusivety", "exclusivity", - "exclusivily", "exclusivity", - "exclusivley", "exclusively", - "excpetional", "exceptional", - "exculsively", "exclusively", - "exculsivity", "exclusivity", - "execitioner", "executioner", - "execptional", "exceptional", - "exectuables", "executable", - "exectuioner", "executioner", - "executionar", "executioner", - "executionor", "executioner", - "exerciseing", "exercising", - "exeuctioner", "executioner", - "existantial", "existential", - "existencial", "existential", - "existensial", "existential", - "existentiel", "existential", - "exlcamation", "exclamation", - "exlcusively", "exclusively", - "exlcusivity", "exclusivity", - "exoskelaton", "exoskeleton", - "expansiones", "expansions", - "expectantcy", "expectancy", - "expectating", "expectation", - "expectional", "exceptional", - "expendature", "expenditure", - "expendeture", "expenditure", - "expentiture", "expenditure", - "expereinced", "experienced", - "expereinces", "experiences", - "experements", "experiments", - "experianced", "experienced", - "experiances", "experiences", - "experiemnts", "experiments", - "experiening", "experiencing", - "experimetal", "experimental", - "experimeted", "experimented", - "experssions", "expressions", - "expiditions", "expeditions", - "expierenced", "experienced", - "expierences", "experiences", - "expirements", "experiments", - "explainging", "explaining", - "explaintory", "explanatory", - "explanaiton", "explanations", - "explanetary", "explanatory", - "explanetory", "explanatory", - "explanitary", "explanatory", - "explanotory", "explanatory", - "explenation", "explanation", - "explenatory", "explanatory", - "explicitely", "explicitly", - "explicitily", "explicitly", - "explination", "explanation", - "explinatory", "explanatory", - "exploitaion", "exploitation", - "exploitatie", "exploitative", - "explonation", "exploration", - "exploracion", "exploration", - "explorating", "exploration", - "explorerers", "explorers", - "explosiones", "explosions", - "explotacion", "exploration", - "expodential", "exponential", - "exponantial", "exponential", - "exponencial", "exponential", - "exponentiel", "exponential", - "expresscoin", "expression", - "expressivos", "expressions", - "expresssive", "expressive", - "expressview", "expressive", - "exprimental", "experimental", - "expropiated", "expropriated", - "extensiones", "extensions", - "extensivley", "extensively", - "extragavant", "extravagant", - "extrapalate", "extrapolate", - "extraploate", "extrapolate", - "extrapolant", "extrapolate", - "extrapolare", "extrapolate", - "extrapolite", "extrapolate", - "extrapulate", "extrapolate", - "extravagent", "extravagant", - "extravagina", "extravagant", - "extravegant", "extravagant", - "extravigant", "extravagant", - "extravogant", "extravagant", - "extremistas", "extremists", - "extremistes", "extremists", - "extropolate", "extrapolate", - "fabircation", "fabrication", - "fabricacion", "fabrication", - "fabrikation", "fabrication", - "facilitarte", "facilitate", - "facilitiate", "facilitate", - "facillitate", "facilitate", - "facisnation", "fascination", - "facsination", "fascination", - "factuallity", "factually", - "familairity", "familiarity", - "familairize", "familiarize", - "familiaries", "familiarize", - "familierize", "familiarize", - "fanatsizing", "fantasizing", - "fanficitons", "fanfiction", - "fantacising", "fantasizing", - "fantacizing", "fantasizing", - "fantasazing", "fantasizing", - "fantasiaing", "fantasizing", - "fantasyzing", "fantasizing", - "fantazising", "fantasizing", - "fascinacion", "fascination", - "fascinatinf", "fascination", - "fascisation", "fascination", - "fascization", "fascination", - "fashionalbe", "fashionable", - "fashoinable", "fashionable", - "fatalitites", "fatalities", - "favoritisme", "favorites", - "favoutrable", "favourable", - "felxibility", "flexibility", - "feministers", "feminists", - "feministisk", "feminists", - "fermentaion", "fermentation", - "fermenterad", "fermented", - "fertilizier", "fertilizer", - "fertizilers", "fertilizer", - "festivalens", "festivals", - "fignernails", "fingernails", - "fignerprint", "fingerprint", - "figurativly", "figuratively", - "finanically", "financially", - "finantially", "financially", - "fingerpints", "fingertips", - "fingerpoint", "fingerprint", - "fingertrips", "fingertips", - "firefighers", "firefighters", - "firefigther", "firefighters", - "firendzoned", "friendzoned", - "firghtening", "frightening", - "flatterende", "flattered", - "flawlessely", "flawlessly", - "flawlessley", "flawlessly", - "flexibiltiy", "flexibility", - "flourescent", "fluorescent", - "fluctuaties", "fluctuate", - "fluctuative", "fluctuate", - "flutteryshy", "fluttershy", - "forcefullly", "forcefully", - "foreseaable", "foreseeable", - "foresseable", "foreseeable", - "forgettting", "forgetting", - "forgiviness", "forgiveness", - "formallized", "formalized", - "formattting", "formatting", - "formidabble", "formidable", - "formidabelt", "formidable", - "formidabile", "formidable", - "fortitudine", "fortitude", - "fortuantely", "fortunately", - "fortunantly", "fortunately", - "fortunatley", "fortunately", - "fortunetely", "fortunately", - "franchieses", "franchises", - "frankensite", "frankenstein", - "frankensten", "frankenstein", - "fransiscans", "franciscans", - "freindships", "friendships", - "freindzoned", "friendzoned", - "frequenices", "frequencies", - "frequensies", "frequencies", - "frequenties", "frequencies", - "frequentily", "frequently", - "frequenzies", "frequencies", - "friendboned", "friendzoned", - "friendlines", "friendlies", - "friendzonie", "friendzoned", - "frientships", "friendships", - "frientzoned", "friendzoned", - "frightenend", "frightened", - "frightining", "frightening", - "frigthening", "frightening", - "frinedzoned", "friendzoned", - "frontlinies", "frontline", - "frontlinjen", "frontline", - "frustartion", "frustrations", - "frustracion", "frustration", - "frustraited", "frustrated", - "frustrantes", "frustrates", - "frustrasion", "frustrations", - "frustrasted", "frustrates", - "frustraties", "frustrates", - "fucntioning", "functioning", - "fulfillling", "fulfilling", - "fulfullment", "fulfillment", - "fullfilment", "fulfillment", - "fullscreeen", "fullscreen", - "funcitoning", "functioning", - "functionaly", "functionally", - "functionnal", "functional", - "fundamentas", "fundamentals", - "fundamently", "fundamental", - "fundametals", "fundamentals", - "fundamnetal", "fundamentals", - "fundemantal", "fundamental", - "fundemental", "fundamental", - "fundimental", "fundamental", - "furhtermore", "furthermore", - "furstration", "frustration", - "furthremore", "furthermore", - "furthurmore", "furthermore", - "futurisitic", "futuristic", - "gangsterest", "gangsters", - "gangsterous", "gangsters", - "gauntlettes", "gauntlets", - "geneologies", "genealogies", - "generalizng", "generalizing", - "generatting", "generating", - "genitaliban", "genitalia", - "gentlemanne", "gentlemen", - "girlfirends", "girlfriends", - "girlfreinds", "girlfriends", - "girlfrients", "girlfriends", - "glorifierad", "glorified", - "glorifindel", "glorified", - "goosebumbps", "goosebumps", - "govenrments", "governments", - "govermental", "governmental", - "governemnts", "governments", - "governmanet", "governmental", - "governmeant", "governmental", - "govormental", "governmental", - "gracefullly", "gracefully", - "grahpically", "graphically", - "grammarical", "grammatical", - "grammaticly", "grammatical", - "grammitical", "grammatical", - "graphcially", "graphically", - "grassrooots", "grassroots", - "gratuitious", "gratuitous", - "gratuituous", "gratuitous", - "gravitatiei", "gravitate", - "grilfriends", "girlfriends", - "grpahically", "graphically", - "guaranteeds", "guarantees", - "guerrillera", "guerrilla", - "gunslingner", "gunslinger", - "hamburgaren", "hamburger", - "hamburgeres", "hamburgers", - "hamburglers", "hamburgers", - "hamburguers", "hamburgers", - "handlebards", "handlebars", - "handrwiting", "handwriting", - "handycapped", "handicapped", - "hanidcapped", "handicapped", - "harassement", "harassment", - "harrasments", "harassments", - "harrassment", "harassment", - "harvestgain", "harvesting", - "headquartes", "headquarters", - "headquaters", "headquarters", - "hearhtstone", "hearthstone", - "heartborken", "heartbroken", - "heartbraker", "heartbreak", - "heartbrakes", "heartbreak", - "heartsthone", "hearthstone", - "heaviweight", "heavyweight", - "heavyweigth", "heavyweight", - "heavywieght", "heavyweight", - "helicoptors", "helicopters", - "helicotpers", "helicopters", - "helicpoters", "helicopters", - "helictopers", "helicopters", - "helikopters", "helicopters", - "hemipsheres", "hemisphere", - "hemishperes", "hemisphere", - "herathstone", "hearthstone", - "heterosexal", "heterosexual", - "hexidecimal", "hexadecimal", - "hierachical", "hierarchical", - "hierarcical", "hierarchical", - "highlighing", "highlighting", - "highschoool", "highschool", - "hipopotamus", "hippopotamus", - "historicaly", "historically", - "historicans", "historians", - "historietas", "histories", - "historinhas", "historians", - "homecomeing", "homecoming", - "homecomming", "homecoming", - "homelesness", "homelessness", - "homelessess", "homelessness", - "homeowneris", "homeowners", - "homoegenous", "homogeneous", - "homogeneize", "homogenize", - "homogenious", "homogeneous", - "homogenuous", "homogeneous", - "homophoboes", "homophobe", - "homosexuais", "homosexuals", - "homosexuels", "homosexuals", - "hopelessely", "hopelessly", - "hopelessley", "hopelessly", - "hopsitality", "hospitality", - "horizonatal", "horizontal", - "horizontaal", "horizontal", - "horizontaly", "horizontally", - "horrendeous", "horrendous", - "horrendious", "horrendous", - "horrenduous", "horrendous", - "hospitalzed", "hospitalized", - "hospotality", "hospitality", - "househoulds", "households", - "humanitarna", "humanitarian", - "humanitites", "humanities", - "humilitaing", "humiliating", - "humilitaion", "humiliation", - "humillating", "humiliating", - "humillation", "humiliation", - "hurricaines", "hurricanes", - "hurricances", "hurricanes", - "hurricanger", "hurricane", - "hyperbollic", "hyperbolic", - "hyperbrophy", "hypertrophy", - "hyperthropy", "hypertrophy", - "hypertorphy", "hypertrophy", - "hypertrohpy", "hypertrophy", - "hypocritcal", "hypocritical", - "hypocritial", "hypocritical", - "hypocrities", "hypocrite", - "hypothesees", "hypotheses", - "hypothesies", "hypothesis", - "hystericaly", "hysterically", - "hystericlly", "hysterically", - "iconclastic", "iconoclastic", - "idealisitic", "idealistic", - "identifible", "identifiable", - "identitites", "identities", - "identitties", "identities", - "ideologiers", "ideologies", - "ideologisen", "ideologies", - "ideologiset", "ideologies", - "ideologiske", "ideologies", - "illegallity", "illegally", - "illegitamte", "illegitimate", - "illegitmate", "illegitimate", - "illsutrator", "illustrator", - "illuminanti", "illuminati", - "illuminarti", "illuminati", - "illuminatti", "illuminati", - "illuminauti", "illuminati", - "illuminiati", "illuminati", - "illuminista", "illuminati", - "illumintati", "illuminati", - "illustarted", "illustrated", - "illustartor", "illustrator", - "illustraded", "illustrated", - "illustraion", "illustration", - "illustrater", "illustrator", - "illustratie", "illustrate", - "illustratin", "illustrations", - "illustraton", "illustration", - "imaganative", "imaginative", - "imaganitive", "imaginative", - "imaginacion", "imagination", - "imaginatiei", "imaginative", - "imaginating", "imagination", - "imaginativo", "imagination", - "imaginitave", "imaginative", - "imbalanaced", "imbalanced", - "imbalanaces", "imbalances", - "imbalancers", "imbalances", - "immatureity", "immaturity", - "immedeately", "immediately", - "immediantly", "immediately", - "immediatley", "immediately", - "immedietely", "immediately", - "immideately", "immediately", - "immidiately", "immediately", - "immigraiton", "immigration", - "immigrantes", "immigrants", - "immoratlity", "immortality", - "immortailty", "immortality", - "immortalisy", "immortals", - "impeccabile", "impeccable", - "imperailist", "imperialist", - "imperealist", "imperialist", - "imperialims", "imperialism", - "imperialsim", "imperialism", - "imperiarist", "imperialist", - "imperically", "empirically", - "imperislist", "imperialist", - "implausable", "implausible", - "implausbile", "implausible", - "implementas", "implements", - "implementes", "implements", - "implementig", "implementing", - "implementos", "implements", - "implicacion", "implication", - "implicatons", "implications", - "implicitely", "implicitly", - "implicitily", "implicitly", - "implikation", "implication", - "implimented", "implemented", - "importantce", "importance", - "importently", "importantly", - "imporvement", "improvement", - "impossibile", "impossible", - "impossibily", "impossibly", - "impossibley", "impossibly", - "impossiblly", "impossibly", - "impoverised", "impoverished", - "impracticle", "impractical", - "impressario", "impresario", - "impresssion", "impressions", - "imprisonent", "imprisonment", - "imprisonned", "imprisoned", - "improbabile", "improbable", - "improtantly", "importantly", - "improvemnts", "improvements", - "improvished", "improvised", - "improvision", "improvisation", - "improvments", "improvements", - "impulsivley", "impulsive", - "imrpovement", "improvement", - "inaccessble", "inaccessible", - "inaccuraces", "inaccuracies", - "inaccurrate", "inaccurate", - "inadvertant", "inadvertent", - "inaguration", "inauguration", - "inahbitants", "inhabitants", - "incarantion", "incarnation", - "incarcerato", "incarceration", - "incarnacion", "incarnation", - "incentivare", "incentive", - "incentivate", "incentive", - "incentivice", "incentive", - "incentivies", "incentives", - "incidencies", "incidence", - "incidentaly", "incidentally", - "incidential", "incidental", - "inclanation", "inclination", - "inclenation", "inclination", - "inclinacion", "inclination", - "inclinaison", "inclination", - "incognition", "incognito", - "incoherrent", "incoherent", - "incompatble", "incompatible", - "incompatent", "incompetent", - "incompetant", "incompetent", - "incompitent", "incompetent", - "incompotent", "incompetent", - "incomptable", "incompatible", - "inconsisent", "inconsistent", - "inconveniet", "inconvenient", - "incoroprate", "incorporate", - "incorparate", "incorporate", - "incorperate", "incorporate", - "incorporare", "incorporate", - "incorported", "incorporated", - "incorprates", "incorporates", - "incorproate", "incorporated", - "incramental", "incremental", - "increadible", "incredible", - "incrediable", "incredible", - "incrediably", "incredibly", - "incredibile", "incredible", - "incredibily", "incredibly", - "incredibley", "incredibly", - "incrememnts", "increments", - "incremenets", "increments", - "incrementas", "increments", - "incremently", "incremental", - "incrementos", "increments", - "incrimental", "incremental", - "inctroduced", "introduced", - "indefinetly", "indefinitely", - "indefininte", "indefinite", - "indefinitly", "indefinitely", - "indepdenent", "independents", - "indepedence", "independence", - "indepednent", "independents", - "independant", "independent", - "independece", "independence", - "independens", "independents", - "independetn", "independents", - "independets", "independents", - "independnet", "independents", - "indepentend", "independents", - "indepentent", "independent", - "indianapols", "indianapolis", - "indicateurs", "indicates", - "indicatiors", "indicators", - "indictement", "indictment", - "indifferant", "indifferent", - "indiffernce", "indifference", - "indigeneous", "indigenous", - "indigenious", "indigenous", - "indigenuous", "indigenous", - "indigineous", "indigenous", - "indipendent", "independent", - "indirectely", "indirectly", - "individiual", "individual", - "individuais", "individuals", - "individualy", "individually", - "individuati", "individuality", - "individuels", "individuals", - "indivuduals", "individuals", - "industriels", "industries", - "ineffecitve", "ineffective", - "ineffektive", "ineffective", - "inefficeint", "inefficient", - "inefficiant", "inefficient", - "ineffictive", "ineffective", - "ineffizient", "inefficient", - "inequallity", "inequality", - "inevitabile", "inevitable", - "inevitabily", "inevitably", - "inevitabley", "inevitably", - "inevitablly", "inevitably", - "inexpencive", "inexpensive", - "inexpenisve", "inexpensive", - "inexperiece", "inexperience", - "inexperince", "inexperience", - "inexplicaby", "inexplicably", - "infallibale", "infallible", - "infallibile", "infallible", - "infectation", "infestation", - "inferioirty", "inferiority", - "infestating", "infestation", - "infilitrate", "infiltrate", - "infiltartor", "infiltrator", - "infiltraron", "infiltrator", - "infiltrarte", "infiltrate", - "infiltrater", "infiltrator", - "infiltratie", "infiltrate", - "infiltrerat", "infiltrate", - "infinitelly", "infinitely", - "infintrator", "infiltrator", - "inflamation", "inflammation", - "inflatabale", "inflatable", - "inflitrator", "infiltrator", - "influancing", "influencing", - "influencial", "influential", - "influencian", "influencing", - "influenting", "influencing", - "influentual", "influential", - "influincing", "influencing", - "infograhpic", "infographic", - "infograpgic", "infographic", - "infogrpahic", "infographic", - "informacion", "information", - "informatice", "informative", - "informatief", "informative", - "informatiei", "informative", - "informatike", "informative", - "informativo", "information", - "informitive", "informative", - "infrigement", "infringement", - "infringeing", "infringing", - "infromation", "information", - "infromative", "informative", - "infulential", "influential", - "ingerdients", "ingredients", - "ingrediants", "ingredients", - "ingreidents", "ingredient", - "ingriedents", "ingredient", - "inhabitents", "inhabitants", - "inheirtance", "inheritance", - "inheratance", "inheritance", - "inheretance", "inheritance", - "inheritence", "inheritance", - "inhertiance", "inheritance", - "initaitives", "initiatives", - "initalisers", "initialisers", - "initalising", "initialising", - "initalizers", "initializers", - "initalizing", "initializing", - "initiaitive", "initiative", - "inititiaves", "initiatives", - "innocenters", "innocents", - "innocentius", "innocents", - "innoculated", "inoculated", - "inpsiration", "inspiration", - "inquisicion", "inquisition", - "inquisistor", "inquisitor", - "inquisiting", "inquisition", - "inquisitior", "inquisitor", - "inquisitivo", "inquisition", - "inquizition", "inquisition", - "insecurites", "insecurities", - "insensative", "insensitive", - "insensetive", "insensitive", - "insentitive", "insensitive", - "insepctions", "inspections", - "inseperable", "inseparable", - "insipration", "inspiration", - "insitutions", "institutions", - "insparation", "inspiration", - "inspecticon", "inspection", - "inspectoras", "inspectors", - "insperation", "inspiration", - "inspiracion", "inspiration", - "inspirating", "inspiration", - "inspriation", "inspiration", - "instalation", "installation", - "instalement", "installment", - "installatin", "installations", - "installeert", "installer", - "installemnt", "installment", - "installling", "installing", - "installmant", "installment", - "instanciate", "instantiate", - "instantaneu", "instantaneous", - "institucion", "institution", - "institutiei", "institute", - "instituttet", "institute", - "instraments", "instruments", - "instruccion", "instruction", - "instruciton", "instruction", - "instructers", "instructors", - "instructior", "instructor", - "instructios", "instructors", - "instructivo", "instruction", - "instructons", "instructors", - "instruktion", "instruction", - "instrumenal", "instrumental", - "instrumetal", "instrumental", - "insturction", "instruction", - "insturctors", "instructors", - "insturments", "instruments", - "instutition", "institution", - "instutution", "institution", - "insufficent", "insufficient", - "insuinating", "insinuating", - "insuniating", "insinuating", - "insurgencey", "insurgency", - "intangiable", "intangible", - "intangibile", "intangible", - "inteferring", "interfering", - "integracion", "integration", - "integratron", "integration", - "integrering", "interfering", - "intelectual", "intellectual", - "inteligence", "intelligence", - "intellectul", "intellectuals", - "intellectus", "intellectuals", - "intellecual", "intellectual", - "intellegent", "intelligent", - "intelligant", "intelligent", - "intencional", "intentional", - "intentionly", "intentional", - "interaccion", "interaction", - "interactice", "interactive", - "interacties", "interacts", - "interactifs", "interacts", - "interactins", "interacts", - "interactios", "interacts", - "interactivo", "interaction", - "interactons", "interacts", - "interaktion", "interaction", - "interaktive", "interactive", - "interasting", "interacting", - "intercation", "integration", - "interceptin", "interception", - "intercoarse", "intercourse", - "intercource", "intercourse", - "interecting", "interacting", - "interection", "interaction", - "interelated", "interrelated", - "interersted", "interpreted", - "interesring", "interfering", - "interessted", "interested", - "interferece", "interference", - "interferens", "interferes", - "interferire", "interfere", - "interfernce", "interference", - "interferred", "interfere", - "interferres", "interferes", - "intergation", "integration", - "intergrated", "integrated", - "intermedate", "intermediate", - "intermedite", "intermediate", - "intermitent", "intermittent", - "internation", "international", - "interneters", "internets", - "internetese", "internets", - "internetest", "internets", - "interneting", "interesting", - "internetors", "internets", - "internettes", "internets", - "interperted", "interpreted", - "interperter", "interpreter", - "interprered", "interpreter", - "interpretor", "interpreter", - "interratial", "interracial", - "interresing", "interfering", - "interrogato", "interrogation", - "interrputed", "interrupted", - "interruping", "interrupting", - "interruptes", "interrupts", - "interruptis", "interrupts", - "intersecton", "intersection", - "interstelar", "interstellar", - "intertained", "intertwined", - "intertvined", "intertwined", - "intertwyned", "intertwined", - "intervalles", "intervals", - "intervation", "integration", - "interveiwed", "interviewed", - "interveiwer", "interviewer", - "intervenion", "intervening", - "intervenire", "intervene", - "interventie", "intervene", - "intervewing", "intervening", - "interviened", "interviewed", - "interviewes", "interviews", - "interviewie", "interviewer", - "intervining", "intervening", - "interwebers", "interwebs", - "interwiever", "interviewer", - "intestinces", "intestines", - "inticracies", "intricacies", - "intimadated", "intimidated", - "intimidades", "intimidated", - "intimidante", "intimidate", - "intimidatie", "intimidated", - "intimidatin", "intimidation", - "intimidaton", "intimidation", - "intimidiate", "intimidate", - "intiminated", "intimidated", - "intimitaded", "intimidated", - "intimitated", "intimidated", - "intiutively", "intuitively", - "intoleranse", "intolerance", - "intolerante", "intolerance", - "intolerence", "intolerance", - "intolernace", "intolerance", - "intolorance", "intolerance", - "intolorence", "intolerance", - "intorducing", "introducing", - "intorverted", "introverted", - "intoxicatin", "intoxication", - "intoxicaton", "intoxication", - "intoxinated", "intoxicated", - "intoxocated", "intoxicated", - "intracacies", "intricacies", - "intracicies", "intricacies", - "intraverted", "introverted", - "intrecacies", "intricacies", - "intrepreted", "interpreted", - "intrepreter", "interpreter", - "intrerupted", "interrupted", - "intricasies", "intricacies", - "intricicies", "intricacies", - "intrigueing", "intriguing", - "intrinsisch", "intrinsic", - "introducion", "introduction", - "introducted", "introduced", - "introductie", "introduce", - "introvertie", "introverted", - "introvertis", "introverts", - "intruducing", "introducing", - "intrumental", "instrumental", - "intuatively", "intuitively", - "intuitevely", "intuitively", - "intuitivley", "intuitively", - "intuituvely", "intuitively", - "inutitively", "intuitively", - "invaldiates", "invalidates", - "invalidades", "invalidates", - "invalidante", "invalidate", - "invariabley", "invariably", - "invariablly", "invariably", - "inventiones", "inventions", - "invesitgate", "investigate", - "investagate", "investigate", - "investiagte", "investigate", - "investigare", "investigate", - "invincibile", "invincible", - "invincinble", "invincible", - "invisibiity", "invisibility", - "invisibiliy", "invisibility", - "involantary", "involuntary", - "involentary", "involuntary", - "involintary", "involuntary", - "involontary", "involuntary", - "involunatry", "involuntary", - "invulnerabe", "invulnerable", - "invulnerble", "invulnerable", - "iresistable", "irresistible", - "iresistably", "irresistibly", - "iresistible", "irresistible", - "iresistibly", "irresistibly", - "irrationaly", "irrationally", - "irrationnal", "irrational", - "islamisists", "islamists", - "islamisters", "islamists", - "islamistisk", "islamists", - "isntruments", "instruments", - "jacksonvile", "jacksonville", - "jailbroaken", "jailbroken", - "jailbrocken", "jailbroken", - "jounralists", "journalists", - "jouranlists", "journalists", - "journalisim", "journalism", - "journalistc", "journalistic", - "journolists", "journalists", - "judegmental", "judgemental", - "judgamental", "judgemental", - "judgementle", "judgemental", - "judgementsl", "judgemental", - "judgenental", "judgemental", - "jugdemental", "judgemental", - "juggernaugt", "juggernaut", - "juggernault", "juggernaut", - "juggernaunt", "juggernaut", - "justifyable", "justifiable", - "kidnappning", "kidnapping", - "kidnappping", "kidnapping", - "kilometeres", "kilometers", - "kindergaten", "kindergarten", - "knowledgabe", "knowledgable", - "knowledgble", "knowledgable", - "kryptoninte", "kryptonite", - "lacklusture", "lackluster", - "laughablely", "laughably", - "legalizaing", "legalizing", - "legalizaton", "legalization", - "legalizeing", "legalizing", - "legenadries", "legendaries", - "legendaires", "legendaries", - "legendarios", "legendaries", - "legendarisk", "legendaries", - "legendaryes", "legendaries", - "legenderies", "legendaries", - "legilsation", "legislation", - "legislacion", "legislation", - "legislativo", "legislation", - "legistation", "legislation", - "legistative", "legislative", - "legistators", "legislators", - "legitematly", "legitimately", - "legitimancy", "legitimacy", - "legitimatcy", "legitimacy", - "legitimatly", "legitimately", - "legitimetly", "legitimately", - "legnedaries", "legendaries", - "lengedaries", "legendaries", - "liberalisim", "liberalism", - "liberatrian", "libertarians", - "libertairan", "libertarians", - "libertarain", "libertarian", - "libertarias", "libertarians", - "libertarien", "libertarian", - "libertaryan", "libertarian", - "libertatian", "libertarian", - "liberterian", "libertarian", - "libguistics", "linguistics", - "libretarian", "libertarian", - "lieutennant", "lieutenant", - "lieutentant", "lieutenant", - "lightenning", "lightening", - "lightenting", "lightening", - "lightheared", "lighthearted", - "lightheated", "lighthearted", - "lightweigth", "lightweight", - "lightwieght", "lightweight", - "lightwright", "lightweight", - "ligthweight", "lightweight", - "limitaitons", "limitation", - "linguisitcs", "linguistics", - "linguisitic", "linguistic", - "lingusitics", "linguistics", - "lithuaninan", "lithuania", - "littlefiger", "littlefinger", - "littlefiner", "littlefinger", - "lockscreeen", "lockscreen", - "longevitity", "longevity", - "lotharingen", "lothringen", - "louisvillle", "louisville", - "maginficent", "magnificent", - "magneficent", "magnificent", - "magnicifent", "magnificent", - "magnifacent", "magnificent", - "magnifecent", "magnificent", - "magnificant", "magnificent", - "magnitudine", "magnitude", - "maintainted", "maintained", - "maintanance", "maintenance", - "maintanence", "maintenance", - "maintenence", "maintenance", - "maintianing", "maintaining", - "maintinaing", "maintaining", - "maintinance", "maintenance", - "maintinence", "maintenance", - "malfonction", "malfunction", - "malfucntion", "malfunction", - "malfunciton", "malfunction", - "malfuncting", "malfunction", - "malfunktion", "malfunction", - "malpractise", "malpractice", - "malpractive", "malpractice", - "maneouvring", "manoeuvring", - "manifestado", "manifesto", - "manifestano", "manifesto", - "manifestato", "manifesto", - "manifestion", "manifesto", - "manifestior", "manifesto", - "manifestons", "manifests", - "manifestors", "manifests", - "manipluated", "manipulated", - "manipualted", "manipulated", - "manipulatie", "manipulative", - "manipulatin", "manipulation", - "manipulaton", "manipulation", - "maniuplated", "manipulated", - "mannerisims", "mannerisms", - "manslaugher", "manslaughter", - "manslaugter", "manslaughter", - "manufacters", "manufactures", - "manufacteur", "manufactures", - "manufactued", "manufactured", - "manufactuer", "manufacture", - "manufacturs", "manufactures", - "manufacuter", "manufacture", - "manufacutre", "manufactures", - "manufatured", "manufactured", - "manupilated", "manipulated", - "marganilize", "marginalized", - "marhsmallow", "marshmallow", - "marijuannas", "marijuana", - "markerplace", "marketplace", - "marketpalce", "marketplace", - "marshamllow", "marshmallow", - "marshmalows", "marshmallows", - "masculanity", "masculinity", - "masculenity", "masculinity", - "masrhmallow", "marshmallow", - "mastermined", "mastermind", - "masterpeace", "masterpiece", - "masterpeice", "masterpiece", - "mastrubated", "masturbated", - "mastrubates", "masturbate", - "masturabted", "masturbated", - "masturbaing", "masturbating", - "masturbarte", "masturbate", - "masturbathe", "masturbated", - "masturbatie", "masturbated", - "masturbatin", "masturbation", - "masturbaton", "masturbation", - "masturbsted", "masturbated", - "masturpiece", "masterpiece", - "masuclinity", "masculinity", - "matchamking", "matchmaking", - "materalists", "materialist", - "materialsim", "materialism", - "mathamatics", "mathematics", - "mathcmaking", "matchmaking", - "mathemagics", "mathematics", - "mathemetics", "mathematics", - "mathimatics", "mathematics", - "matieralism", "materialism", - "maybelleine", "maybelline", - "maybelliene", "maybelline", - "maybellinne", "maybelline", - "maybellline", "maybelline", - "mdifielders", "midfielders", - "meatballers", "meatballs", - "mecernaries", "mercenaries", - "mechanicaly", "mechanically", - "mechanichal", "mechanical", - "mechaniclly", "mechanically", - "mechanicsms", "mechanisms", - "mechanisims", "mechanism", - "mechanismus", "mechanisms", - "medicaitons", "medications", - "medicineras", "medicines", - "meditatiing", "meditating", - "meditationg", "meditating", - "mentionning", "mentioning", - "mercanaries", "mercenaries", - "mercaneries", "mercenaries", - "mercenaires", "mercenaries", - "mercenarias", "mercenaries", - "mercenarios", "mercenaries", - "merceneries", "mercenaries", - "merchandice", "merchandise", - "merchandies", "merchandise", - "merchanidse", "merchandise", - "merchanters", "merchants", - "merchendise", "merchandise", - "merchindise", "merchandise", - "mercinaries", "mercenaries", - "mercineries", "mercenaries", - "metabolisim", "metabolism", - "metabolitic", "metabolic", - "metaphisics", "metaphysics", - "metaphorial", "metaphorical", - "metaphorics", "metaphors", - "metaphsyics", "metaphysics", - "metaphyiscs", "metaphysics", - "methodoligy", "methodology", - "metholodogy", "methodology", - "metropolian", "metropolitan", - "metropolies", "metropolis", - "metropollis", "metropolis", - "metropolois", "metropolis", - "micorcenter", "microcenter", - "micorphones", "microphones", - "microcender", "microcenter", - "microcentre", "microcenter", - "microcentro", "microcenter", - "microhpones", "microphones", - "microscrope", "microscope", - "microwavees", "microwaves", - "microwavers", "microwaves", - "midfeilders", "midfielders", - "midfiedlers", "midfielders", - "midfileders", "midfielders", - "midifelders", "midfielders", - "millienaire", "millionaire", - "millionairs", "millionaires", - "millionarie", "millionaire", - "millioniare", "millionaire", - "mindlessely", "mindlessly", - "mindlessley", "mindlessly", - "minimalstic", "minimalist", - "ministerens", "ministers", - "ministerios", "ministers", - "minneaoplis", "minneapolis", - "minneaplois", "minneapolis", - "minniapolis", "minneapolis", - "miraculaous", "miraculous", - "miraculosly", "miraculously", - "miraculousy", "miraculously", - "mircocenter", "microcenter", - "mircophones", "microphones", - "mircoscopic", "microscopic", - "miscairrage", "miscarriage", - "miscarraige", "miscarriage", - "miscarridge", "miscarriage", - "miscarriege", "miscarriage", - "mischeivous", "mischievous", - "mischevious", "mischievous", - "misdameanor", "misdemeanor", - "misdeamenor", "misdemeanor", - "misdemeaner", "misdemeanor", - "misdemenaor", "misdemeanor", - "misdemenors", "misdemeanors", - "misdimeanor", "misdemeanor", - "misdomeanor", "misdemeanor", - "miserablely", "miserably", - "misfortunte", "misfortune", - "misimformed", "misinformed", - "misinterept", "misinterpret", - "misinterpet", "misinterpret", - "misoginysts", "misogynist", - "misognyists", "misogynist", - "misogyinsts", "misogynist", - "misogynisic", "misogynistic", - "misogynistc", "misogynistic", - "misogynstic", "misogynist", - "missionaire", "missionaries", - "missionairy", "missionary", - "missionares", "missionaries", - "missionaris", "missionaries", - "missionarry", "missionary", - "missionnary", "missionary", - "mississipis", "mississippi", - "misspeeling", "misspelling", - "misspellled", "misspelled", - "mistakengly", "mistakenly", - "mistakently", "mistakenly", - "moderatedly", "moderately", - "moderateurs", "moderates", - "moderatorin", "moderation", - "modificaton", "modification", - "moisterizer", "moisturizer", - "moistruizer", "moisturizer", - "moisturizng", "moisturizing", - "moisturizor", "moisturizer", - "moistutizer", "moisturizer", - "moisutrizer", "moisturizer", - "moleculaire", "molecular", - "molestating", "molestation", - "moleststion", "molestation", - "momemtarily", "momentarily", - "momentairly", "momentarily", - "momentaraly", "momentarily", - "momentarely", "momentarily", - "momenterily", "momentarily", - "monestaries", "monasteries", - "monitoreada", "monitored", - "monitoreado", "monitored", - "monogameous", "monogamous", - "monolitihic", "monolithic", - "monopollies", "monopolies", - "monstorsity", "monstrosity", - "monstrasity", "monstrosity", - "monstrisity", "monstrosity", - "monstrocity", "monstrosity", - "monstrosoty", "monstrosity", - "monstrostiy", "monstrosity", - "monumentaal", "monumental", - "monumentais", "monuments", - "monumentals", "monuments", - "monumentous", "monuments", - "mositurizer", "moisturizer", - "mosntrosity", "monstrosity", - "motehrboard", "motherboard", - "mothebroard", "motherboards", - "motherbaord", "motherboard", - "motherboads", "motherboards", - "motherboars", "motherboards", - "motherborad", "motherboard", - "motherbords", "motherboards", - "motherobard", "motherboards", - "mothreboard", "motherboards", - "motivatinal", "motivational", - "motorcicles", "motorcycles", - "motorcylces", "motorcycles", - "mouthpeices", "mouthpiece", - "mulitplayer", "multiplayer", - "mulitplying", "multiplying", - "multipalyer", "multiplayer", - "multiplater", "multiplayer", - "multiplebgs", "multiples", - "multipleies", "multiples", - "multitaskng", "multitasking", - "multitudine", "multitude", - "multiverese", "multiverse", - "multyplayer", "multiplayer", - "multyplying", "multiplying", - "muncipality", "municipality", - "murdererous", "murderers", - "musicallity", "musically", - "mutliplayer", "multiplayer", - "mutliplying", "multiplying", - "mysterieuse", "mysteries", - "mysteriosly", "mysteriously", - "mysteriouly", "mysteriously", - "mysteriousy", "mysteriously", - "napoleonian", "napoleonic", - "narcisissim", "narcissism", - "narcisissts", "narcissist", - "narcisscism", "narcissism", - "narcisscist", "narcissist", - "narcissisim", "narcissism", - "narcississm", "narcissism", - "narcississt", "narcissist", - "narcissistc", "narcissistic", - "narcissitic", "narcissistic", - "narcisssism", "narcissism", - "narcisssist", "narcissist", - "narcissstic", "narcissist", - "natioanlist", "nationalist", - "nationailty", "nationality", - "nationalesl", "nationals", - "nationalisn", "nationals", - "nationalite", "nationalist", - "nationalits", "nationalist", - "nationalizm", "nationalism", - "nationalsim", "nationalism", - "neccesarily", "necessarily", - "necessairly", "necessarily", - "necessaties", "necessities", - "necesseraly", "necessarily", - "necesserily", "necessarily", - "necessiates", "necessities", - "necessitive", "necessities", - "neckbeardos", "neckbeards", - "neckbeardus", "neckbeards", - "necormancer", "necromancer", - "necromamcer", "necromancer", - "necromanser", "necromancer", - "necromencer", "necromancer", - "needlessley", "needlessly", - "negativeity", "negativity", - "negativelly", "negatively", - "negativitiy", "negativity", - "negiotating", "negotiating", - "negligiable", "negligible", - "negociating", "negotiating", - "negociation", "negotiation", - "negoitating", "negotiating", - "negoitation", "negotiation", - "negotiatied", "negotiate", - "negotiative", "negotiate", - "negotiatons", "negotiations", - "neigborhood", "neighborhood", - "neigbouring", "neighbouring", - "neighborhod", "neighborhood", - "neighbourgs", "neighbours", - "neighouring", "neighboring", - "nercomancer", "necromancer", - "nessasarily", "necessarily", - "neurologial", "neurological", - "neurosciene", "neuroscience", - "neutrallity", "neutrality", - "neverthelss", "nevertheless", - "neverthless", "nevertheless", - "newspapaers", "newspapers", - "newspappers", "newspapers", - "nieghboring", "neighboring", - "nightmarket", "nightmare", - "nonsencical", "nonsensical", - "nonsenscial", "nonsensical", - "nonsensicle", "nonsensical", - "normallized", "normalized", - "northwesten", "northwestern", - "nostalgisch", "nostalgic", - "noteworthly", "noteworthy", - "noticeabley", "noticeably", - "notificaton", "notification", - "notoriuosly", "notoriously", - "numericable", "numerical", - "nurtitional", "nutritional", - "nutricional", "nutritional", - "nutrutional", "nutritional", - "obamination", "abomination", - "obersvation", "observation", - "obilterated", "obliterated", - "objectivety", "objectivity", - "objectivify", "objectivity", - "objectivily", "objectivity", - "objectivley", "objectively", - "obliberated", "obliterated", - "obliderated", "obliterated", - "obligerated", "obliterated", - "oblitarated", "obliterated", - "obliteraded", "obliterated", - "obliterared", "obliterated", - "oblitirated", "obliterated", - "oblitorated", "obliterated", - "obliverated", "obliterated", - "observacion", "observation", - "observaiton", "observant", - "observasion", "observations", - "observating", "observation", - "observerats", "observers", - "obsessivley", "obsessive", - "obstruccion", "obstruction", - "obstruktion", "obstruction", - "obsturction", "obstruction", - "obversation", "observation", - "ocasionally", "occasionally", - "ocassionaly", "occasionally", - "occasionals", "occasions", - "occasionaly", "occasionally", - "occasionnal", "occasional", - "occassional", "occasional", - "occassioned", "occasioned", - "occurrances", "occurrences", - "offensivley", "offensively", - "offesnively", "offensively", - "officiallly", "officially", - "olbiterated", "obliterated", - "omniscienct", "omniscient", - "operacional", "operational", - "operasional", "operational", - "operationel", "operational", - "oppresssing", "oppressing", - "oppresssion", "oppression", - "opprotunity", "opportunity", - "optimisitic", "optimistic", - "optimizaton", "optimization", - "orchestraed", "orchestrated", - "orchestrial", "orchestra", - "oreintation", "orientation", - "organisaton", "organisation", - "organiserad", "organised", - "organistion", "organisation", - "organizarea", "organizer", - "organizarem", "organizer", - "organizarme", "organizer", - "organizarte", "organizer", - "organiztion", "organization", - "oridinarily", "ordinarily", - "orientacion", "orientation", - "originially", "originally", - "originnally", "originally", - "origniality", "originality", - "ostensiably", "ostensibly", - "ostensibily", "ostensibly", - "outclasssed", "outclassed", - "outnunbered", "outnumbered", - "outperfroms", "outperform", - "outpreforms", "outperform", - "outrageosly", "outrageously", - "outrageouly", "outrageously", - "outragerous", "outrageous", - "outskirters", "outskirts", - "outsorucing", "outsourcing", - "outsourcade", "outsourced", - "outsoursing", "outsourcing", - "overbraking", "overbearing", - "overcapping", "overlapping", - "overcharing", "overarching", - "overclcoked", "overclocked", - "overclicked", "overclocked", - "overcloaked", "overclocked", - "overclocing", "overclocking", - "overclockig", "overclocking", - "overclocled", "overclocked", - "overcomeing", "overcoming", - "overcomming", "overcoming", - "overeaching", "overarching", - "overfapping", "overlapping", - "overheading", "overheating", - "overhooking", "overlooking", - "overhwelmed", "overwhelmed", - "overkapping", "overlapping", - "overklocked", "overclocked", - "overlapsing", "overlapping", - "overlcocked", "overclocked", - "overlcoking", "overlooking", - "overlooming", "overlooking", - "overloooked", "overlooked", - "overlordess", "overlords", - "overmapping", "overlapping", - "overpooling", "overlooking", - "overpovered", "overpowered", - "overpoweing", "overpowering", - "overreacing", "overreacting", - "overreactin", "overreaction", - "overreacton", "overreaction", - "overshaddow", "overshadowed", - "overshadowd", "overshadowed", - "overtapping", "overlapping", - "overthining", "overthinking", - "overthinkig", "overthinking", - "overvlocked", "overclocked", - "overwealmed", "overwhelmed", - "overwelming", "overwhelming", - "overwhelemd", "overwhelmed", - "overwhelimg", "overwhelm", - "overwheling", "overwhelming", - "overwhemled", "overwhelmed", - "overwhlemed", "overwhelmed", - "overwritted", "overwrite", - "pakistanais", "pakistani", - "pakistanezi", "pakistani", - "palceholder", "placeholder", - "palesitnian", "palestinians", - "palestenian", "palestinian", - "palestinain", "palestinians", - "palestinans", "palestinians", - "palestinier", "palestine", - "palistinian", "palestinian", - "palythrough", "playthrough", - "papanicalou", "papanicolaou", - "parachutage", "parachute", - "paragraphes", "paragraphs", - "paramedicks", "paramedics", - "paramedicos", "paramedics", - "parameteres", "parameters", - "paranthesis", "parenthesis", - "parapharsed", "paraphrase", - "paraprhased", "paraphrase", - "parasitisme", "parasites", - "parenthasis", "parenthesis", - "parenthesys", "parentheses", - "parenthises", "parenthesis", - "parenthisis", "parenthesis", - "parliamenty", "parliamentary", - "parntership", "partnership", - "parrallelly", "parallelly", - "partecipant", "participant", - "partecipate", "participate", - "parternship", "partnership", - "partiarchal", "patriarchal", - "particapate", "participate", - "particiapte", "participate", - "participait", "participant", - "participans", "participants", - "participare", "participate", - "participatd", "participant", - "participati", "participant", - "participats", "participant", - "participent", "participant", - "particpiate", "participated", - "particually", "particularly", - "particulaly", "particularly", - "particulary", "particularly", - "partnetship", "partnership", - "partonizing", "patronizing", - "passionatly", "passionately", - "passionetly", "passionately", - "passionnate", "passionate", - "passporters", "passports", - "pathologial", "pathological", - "patriarchia", "patriarchal", - "patriarcial", "patriarchal", - "patriarical", "patriarchal", - "patriotisch", "patriotic", - "patriotisim", "patriotism", - "patriottism", "patriotism", - "patronozing", "patronizing", - "peacefullly", "peacefully", - "pedestirans", "pedestrians", - "pedestrains", "pedestrians", - "pedophilies", "pedophile", - "pedophilles", "pedophile", - "penetracion", "penetration", - "penetrading", "penetrating", - "penetrarion", "penetration", - "penninsular", "peninsular", - "pennsylvnia", "pennsylvania", - "pepperocini", "pepperoni", - "percantages", "percentages", - "percautions", "precautions", - "percentille", "percentile", - "percpetions", "perceptions", - "percusssion", "percussion", - "perdicament", "predicament", - "perdictable", "predictable", - "perdictions", "predictions", - "perephirals", "peripherals", - "pereptually", "perpetually", - "perferences", "preferences", - "perfomrance", "performances", - "perforamnce", "performances", - "performaces", "performances", - "performacne", "performances", - "performanes", "performances", - "performanse", "performances", - "performence", "performance", - "performnace", "performances", - "perfromance", "performance", - "perhiperals", "peripherals", - "perihperals", "peripherals", - "periodicaly", "periodically", - "periperhals", "peripherals", - "periphereal", "peripheral", - "peripherial", "peripheral", - "periphirals", "peripherals", - "periphreals", "peripherals", - "periphrials", "peripherals", - "perjorative", "pejorative", - "perliminary", "preliminary", - "permamently", "permanently", - "permanantly", "permanently", - "permaturely", "prematurely", - "permenantly", "permanently", - "permenently", "permanently", - "perminantly", "permanently", - "perminently", "permanently", - "permisisons", "permissions", - "permissable", "permissible", - "permisssion", "permissions", - "pernamently", "permanently", - "perosnality", "personality", - "perparation", "preparation", - "perpatrated", "perpetrated", - "perpatrator", "perpetrator", - "perpatuated", "perpetuated", - "perpatuates", "perpetuates", - "perpertated", "perpetuated", - "perpertator", "perpetrators", - "perpetraded", "perpetrated", - "perpetrador", "perpetrator", - "perpetraron", "perpetrator", - "perpetrater", "perpetrator", - "perpetuaded", "perpetuated", - "perpetutate", "perpetuate", - "perpetuties", "perpetuates", - "perpitrated", "perpetrated", - "perpitrator", "perpetrator", - "perpretated", "perpetrated", - "perpretator", "perpetrators", - "perpsective", "perspective", - "perputrator", "perpetrator", - "perputually", "perpetually", - "perputuated", "perpetuated", - "perputuates", "perpetuates", - "perrogative", "prerogative", - "persceptive", "perspectives", - "persectuion", "persecution", - "persecucion", "persecution", - "persecusion", "persecution", - "persecutted", "persecuted", - "persepctive", "perspective", - "persicution", "persecution", - "persistance", "persistence", - "persistante", "persistent", - "persistense", "persistence", - "persistente", "persistence", - "personhoood", "personhood", - "perspecitve", "perspective", - "perspectief", "perspective", - "perspektive", "perspective", - "persuassion", "persuasion", - "persuassive", "persuasive", - "persucution", "persecution", - "persumption", "presumption", - "pertubation", "perturbation", - "pessimestic", "pessimistic", - "pharamcists", "pharmacist", - "phenomenona", "phenomena", - "philadelpha", "philadelphia", - "philadelpia", "philadelphia", - "philiphines", "philippines", - "philippenes", "philippines", - "philippenis", "philippines", - "philippides", "philippines", - "philippinas", "philippines", - "philippinos", "philippines", - "philisopher", "philosopher", - "phillipines", "philippines", - "philosipher", "philosopher", - "philosopers", "philosophers", - "philosophae", "philosopher", - "philosophia", "philosophical", - "philosopies", "philosophies", - "philosphies", "philosophies", - "philospoher", "philosopher", - "photograhed", "photographed", - "photograher", "photographer", - "photograhic", "photographic", - "photograhpy", "photography", - "photograped", "photographed", - "photograper", "photographer", - "photograpgh", "photographs", - "photograpic", "photographic", - "photogrpahs", "photographs", - "photogrpahy", "photography", - "physcedelic", "psychedelic", - "physciatric", "psychiatric", - "physcopaths", "psychopaths", - "piankillers", "painkillers", - "pilgrimmage", "pilgrimage", - "pitchforcks", "pitchforks", - "pitchforkes", "pitchforks", - "plaestinian", "palestinian", - "plagiariasm", "plagiarism", - "planeswaker", "planeswalker", - "planeswaler", "planeswalker", - "planeswalkr", "planeswalker", - "platfromers", "platformer", - "playhtrough", "playthrough", - "playthorugh", "playthrough", - "playthourgh", "playthrough", - "playthroguh", "playthroughs", - "playthrougs", "playthroughs", - "playthrouhg", "playthroughs", - "playthtough", "playthrough", - "playtrhough", "playthrough", - "ploretariat", "proletariat", - "policitally", "politically", - "policitians", "politicians", - "politicains", "politicians", - "politicanti", "politician", - "politiciens", "politicians", - "politiicans", "politician", - "polititians", "politicians", - "polyphonyic", "polyphonic", - "pomegranite", "pomegranate", - "popluations", "populations", - "poportional", "proportional", - "popoulation", "population", - "porjectiles", "projectiles", - "porletariat", "proletariat", - "pornagraphy", "pornography", - "pornograghy", "pornography", - "pornograhpy", "pornography", - "pornograpgy", "pornography", - "pornogrophy", "pornography", - "pornogrpahy", "pornography", - "porportions", "proportions", - "portestants", "protestants", - "portuguease", "portuguese", - "portuguesse", "portuguese", - "positionial", "positional", - "positionnal", "positional", - "positionned", "positioned", - "positiveity", "positivity", - "positiviely", "positively", - "positivisme", "positives", - "positivisty", "positivity", - "positivitey", "positivity", - "positivitiy", "positivity", - "possesseurs", "possesses", - "possesssion", "possessions", - "possestions", "possessions", - "possiblilty", "possibility", - "potencially", "potentially", - "potentailly", "potentially", - "powerhourse", "powerhouse", - "powerlifing", "powerlifting", - "powerliftng", "powerlifting", - "pracitcally", "practically", - "practicarlo", "practical", - "practioners", "practitioners", - "practitions", "practitioners", - "pragmatisch", "pragmatic", - "precausions", "precautions", - "precedessor", "predecessor", - "precendence", "precedence", - "precentages", "percentages", - "preconceved", "preconceived", - "preconcieve", "preconceived", - "precuations", "precautions", - "predacessor", "predecessor", - "predecesser", "predecessor", - "predections", "predictions", - "predescesor", "predecessors", - "predesessor", "predecessors", - "predesposed", "predisposed", - "predessecor", "predecessor", - "predicatble", "predictable", - "predicement", "predicament", - "predicessor", "predecessor", - "prediciment", "predicament", - "predicitons", "predictions", - "predictible", "predictable", - "predictious", "predictions", - "predictment", "predicament", - "predisposte", "predisposed", - "predocessor", "predecessor", - "preferabbly", "preferably", - "preferabely", "preferable", - "preferabley", "preferably", - "preferablly", "preferably", - "preferances", "preferences", - "preferenser", "preferences", - "preferental", "preferential", - "preferentes", "preferences", - "preferrably", "preferably", - "preferrring", "preferring", - "preformance", "performance", - "pregnanices", "pregnancies", - "pregnencies", "pregnancies", - "pregorative", "prerogative", - "preipherals", "peripherals", - "prejudicies", "prejudice", - "preleminary", "preliminary", - "prelimanary", "preliminary", - "prelimenary", "preliminary", - "premanently", "permanently", - "prematuraly", "prematurely", - "prematurily", "prematurely", - "prematurley", "prematurely", - "premilinary", "preliminary", - "premissible", "permissible", - "premissions", "permissions", - "preorderded", "preordered", - "preorderers", "preorders", - "preparacion", "preparation", - "preperation", "preparation", - "prepetrated", "perpetrated", - "prepetrator", "perpetrator", - "prepetually", "perpetually", - "prepetuated", "perpetuated", - "prepetuates", "perpetuates", - "preporation", "preparation", - "preposterus", "preposterous", - "prerequesit", "prerequisite", - "prerequiste", "prerequisite", - "prerequites", "prerequisite", - "prerogitive", "prerogative", - "prerogotive", "prerogative", - "prescripton", "prescription", - "presecution", "persecution", - "presedintia", "presidential", - "presentaion", "presentation", - "presentatin", "presentations", - "preservaton", "preservation", - "preservered", "preserved", - "presidencey", "presidency", - "presidental", "presidential", - "presidentcy", "presidency", - "presistence", "persistence", - "presitgious", "prestigious", - "presitigous", "prestigious", - "presomption", "presumption", - "prespective", "perspective", - "pressureing", "pressuring", - "prestegious", "prestigious", - "prestigeous", "prestigious", - "prestigieus", "prestigious", - "prestigiosa", "prestigious", - "prestigiose", "prestigious", - "prestigiosi", "prestigious", - "prestigioso", "prestigious", - "prestiguous", "prestigious", - "presumabely", "presumably", - "presumabley", "presumably", - "presumptous", "presumptuous", - "presumptuos", "presumptuous", - "pretencious", "pretentious", - "pretendendo", "pretended", - "pretensious", "pretentious", - "pretentieus", "pretentious", - "prevailaing", "prevailing", - "prevailling", "prevailing", - "preventitve", "preventative", - "preventivno", "prevention", - "primatively", "primitively", - "princessses", "princesses", - "principales", "principles", - "principalis", "principals", - "principielt", "principle", - "privatizied", "privatized", - "priveledges", "privileges", - "privelleges", "privileges", - "privilegeds", "privileges", - "privilegied", "privileged", - "privilegien", "privilege", - "privilegier", "privilege", - "privilegies", "privilege", - "proactivley", "proactive", - "probabilaty", "probability", - "probabilite", "probabilities", - "probalibity", "probability", - "probelmatic", "problematic", - "problamatic", "problematic", - "problimatic", "problematic", - "problomatic", "problematic", - "proccedings", "proceedings", - "proccessing", "processing", - "proceddings", "proceedings", - "procedureal", "procedural", - "procedurial", "procedural", - "procedurile", "procedure", - "processesor", "processors", - "processeurs", "processes", - "processsors", "processors", - "procrastion", "procreation", - "procriation", "procreation", - "prodcutions", "productions", - "prodictions", "productions", - "producerats", "producers", - "producitons", "productions", - "productioin", "productions", - "productivos", "productions", - "productivty", "productivity", - "produktions", "productions", - "professinal", "professional", - "professionl", "professionals", - "professoras", "professors", - "professores", "professors", - "professorin", "profession", - "professsion", "professions", - "proficiancy", "proficiency", - "proficienct", "proficient", - "proficienty", "proficiency", - "proficinecy", "proficiency", - "profitabile", "profitable", - "progerssion", "progressions", - "progerssive", "progressives", - "programable", "programmable", - "programmare", "programmer", - "programmars", "programmers", - "programmate", "programme", - "programmets", "programmers", - "programmeur", "programmer", - "programmier", "programmer", - "programmmed", "programme", - "programmmer", "programme", - "progresison", "progressions", - "progressers", "progresses", - "progressief", "progressive", - "progressino", "progressions", - "progressivo", "progression", - "progressoin", "progressions", - "progressvie", "progressives", - "prohabition", "prohibition", - "prohibation", "prohibition", - "prohibicion", "prohibition", - "prohibiteds", "prohibits", - "prohibitied", "prohibited", - "prohibitifs", "prohibits", - "prohibitivo", "prohibition", - "prohibitons", "prohibits", - "prohibitted", "prohibited", - "projecticle", "projectile", - "projectives", "projectiles", - "projectlies", "projectiles", - "prolateriat", "proletariat", - "proletariet", "proletariat", - "proletariot", "proletariat", - "proletaryat", "proletariat", - "proleteriat", "proletariat", - "prolitariat", "proletariat", - "prologomena", "prolegomena", - "promenantly", "prominently", - "promenently", "prominently", - "prometheius", "prometheus", - "prometheous", "prometheus", - "promethesus", "prometheus", - "prometheyus", "prometheus", - "promimently", "prominently", - "prominantly", "prominently", - "prominately", "prominently", - "promiscious", "promiscuous", - "promocional", "promotional", - "promsicuous", "promiscuous", - "pronography", "pornography", - "pronoucning", "pronouncing", - "pronounched", "pronounced", - "pronunciato", "pronunciation", - "propaganada", "propaganda", - "properitary", "proprietary", - "propertiary", "proprietary", - "propertions", "proportions", - "prophechies", "prophecies", - "propiertary", "proprietary", - "propogation", "propagation", - "proponenets", "proponents", - "proponentes", "proponents", - "proporition", "proposition", - "proportians", "proportions", - "proportinal", "proportional", - "proposicion", "proposition", - "propositivo", "proposition", - "propostions", "proportions", - "propreitary", "proprietary", - "propriatary", "proprietary", - "propriatery", "proprietary", - "propriatory", "proprietary", - "proprietery", "proprietary", - "proprietory", "proprietary", - "propriotary", "proprietary", - "proprotions", "proportions", - "propsective", "prospective", - "propulstion", "propulsion", - "prosectuion", "prosecution", - "prosectuors", "prosecutors", - "prosecuters", "prosecutors", - "prosicution", "prosecution", - "prosocution", "prosecution", - "prosperious", "prosperous", - "prospertity", "prosperity", - "prospettive", "prospective", - "prostethics", "prosthetic", - "prosthethic", "prosthetic", - "prostitites", "prostitutes", - "prostitiute", "prostitute", - "prostituate", "prostitute", - "prostitudes", "prostitutes", - "prostituees", "prostitutes", - "prostituion", "prostitution", - "prostitures", "prostitutes", - "prostitutas", "prostitutes", - "prostitutie", "prostitute", - "prostitutin", "prostitution", - "prostitutke", "prostitutes", - "prostituton", "prostitution", - "prostitutos", "prostitutes", - "protability", "portability", - "protaganist", "protagonist", - "protaginist", "protagonist", - "protagnoist", "protagonist", - "protagoinst", "protagonists", - "protagonits", "protagonists", - "protagonsit", "protagonists", - "protectings", "protections", - "protectoras", "protectors", - "protectores", "protectors", - "protectrons", "protections", - "protelariat", "proletariat", - "protestents", "protestants", - "protistants", "protestants", - "protoganist", "protagonist", - "protogonist", "protagonist", - "protostants", "protestants", - "protototype", "prototype", - "provacative", "provocative", - "provacotive", "provocative", - "provicative", "provocative", - "providencie", "providence", - "provinciaal", "provincial", - "provinicial", "provincial", - "provisiones", "provisions", - "provoactive", "provocative", - "provocatief", "provocative", - "provocitive", "provocative", - "provocotive", "provocative", - "provokative", "provocative", - "pscyhedelic", "psychedelic", - "pscyhiatric", "psychiatric", - "pscyhopaths", "psychopaths", - "pshyciatric", "psychiatric", - "pshycopaths", "psychopaths", - "psychaitric", "psychiatric", - "psychedilic", "psychedelic", - "psychedleic", "psychedelics", - "psychiatist", "psychiatrist", - "psychidelic", "psychedelic", - "psychodelic", "psychedelic", - "psychopants", "psychopaths", - "psychopatch", "psychopath", - "psychopatic", "psychopathic", - "psychotisch", "psychotic", - "psychriatic", "psychiatric", - "publikation", "publication", - "punctiation", "punctuation", - "puncutation", "punctuation", - "punshiments", "punishments", - "punsihments", "punishments", - "purchaseing", "purchasing", - "purchashing", "purchasing", - "purposefuly", "purposefully", - "pyschedelic", "psychedelic", - "pyschiatric", "psychiatric", - "pyschopaths", "psychopaths", - "qaurterback", "quarterback", - "qualificato", "qualification", - "qualifieres", "qualifiers", - "quantitaive", "quantitative", - "quantitatve", "quantitative", - "quantitites", "quantities", - "quantitties", "quantities", - "quarantaine", "quarantine", - "quarantenni", "quarantine", - "quartercask", "quarterbacks", - "quesitoning", "questioning", - "questionned", "questioned", - "questonable", "questionable", - "radiaoctive", "radioactive", - "radioactice", "radioactive", - "radioactief", "radioactive", - "radioaktive", "radioactive", - "radiocative", "radioactive", - "raidoactive", "radioactive", - "reaccurring", "recurring", - "reactionair", "reactionary", - "realibility", "reliability", - "realistisch", "realistic", - "reaserchers", "researchers", - "reaserching", "researching", - "reasonabley", "reasonably", - "reasonablly", "reasonably", - "reassureing", "reassuring", - "reassurring", "reassuring", - "rebuildling", "rebuilding", - "rebuplicans", "republicans", - "reccomended", "recommended", - "receptionst", "receptionist", - "recgonition", "recognition", - "recgonizing", "recognizing", - "rechargable", "rechargeable", - "recipientes", "recipients", - "reciporcate", "reciprocate", - "recipricate", "reciprocate", - "reciprocant", "reciprocate", - "reciprocite", "reciprocate", - "recivership", "receivership", - "reclutantly", "reluctantly", - "recognicing", "recognizing", - "recognision", "recognition", - "recomending", "recommending", - "recommandes", "recommends", - "recommendes", "recommends", - "recommented", "recommended", - "reconcilled", "reconcile", - "recongition", "recognition", - "recongizing", "recognizing", - "reconsidder", "reconsider", - "recrational", "recreational", - "recrutiment", "recruitment", - "rectangluar", "rectangular", - "rectangualr", "rectangular", - "rectengular", "rectangular", - "recuritment", "recruitment", - "redundantcy", "redundancy", - "reevalulate", "reevaluate", - "reevalutate", "reevaluate", - "reevaulated", "reevaluate", - "refelctions", "reflections", - "referancing", "referencing", - "refereneced", "referenced", - "refereneces", "references", - "referincing", "referencing", - "referrences", "references", - "reflectivos", "reflections", - "refreshener", "refresher", - "refrubished", "refurbished", - "refubrished", "refurbished", - "refurbushed", "refurbished", - "regeneratin", "regeneration", - "regeneraton", "regeneration", - "registerdns", "registers", - "registeries", "registers", - "registerred", "registered", - "registraion", "registration", - "regocnition", "recognition", - "regresssion", "regression", - "regresssive", "regressive", - "regualtions", "regulations", - "regulationg", "regulating", - "regulatiors", "regulators", - "reinassance", "renaissance", - "reinforcemt", "reinforcement", - "reinfornced", "reinforced", - "reinitalise", "reinitialise", - "reinitalize", "reinitialize", - "reinstaling", "reinstalling", - "reinstallng", "reinstalling", - "reisntalled", "reinstalled", - "relaibility", "reliability", - "relatiation", "retaliation", - "relationshp", "relationships", - "relativiser", "relatives", - "relativisme", "relatives", - "relativitiy", "relativity", - "relativitly", "relativity", - "relcutantly", "reluctantly", - "relentlesly", "relentlessly", - "relentlessy", "relentlessly", - "relevations", "revelations", - "relfections", "reflections", - "religeously", "religiously", - "religionens", "religions", - "religioners", "religions", - "relpacement", "replacement", - "reluctently", "reluctantly", - "remarkabley", "remarkably", - "remarkablly", "remarkably", - "remasterred", "remastered", - "remembrence", "remembrance", - "reminescent", "reminiscent", - "reminicient", "reminiscent", - "reminiscant", "reminiscent", - "reminiscint", "reminiscent", - "reminscient", "reminiscent", - "reminsicent", "reminiscent", - "renaiisance", "renaissance", - "renaiscance", "renaissance", - "renaissanse", "renaissance", - "renaissence", "renaissance", - "renassaince", "renaissance", - "renassiance", "renaissance", - "reniassance", "renaissance", - "rennovating", "renovating", - "rennovation", "renovation", - "repalcement", "replacement", - "repbulicans", "republicans", - "repeateadly", "repeatedly", - "repectively", "respectively", - "repersented", "represented", - "replacemnet", "replacements", - "replacemnts", "replacements", - "repleacable", "replaceable", - "repositiory", "repository", - "representas", "represents", - "representes", "represents", - "represssion", "repression", - "reproducion", "reproduction", - "reproducive", "reproductive", - "repsectable", "respectable", - "repsonsible", "responsible", - "repsonsibly", "responsibly", - "republcians", "republicans", - "republician", "republican", - "republicons", "republicans", - "repuglicans", "republicans", - "requeriment", "requirement", - "requierment", "requirements", - "resemblence", "resemblance", - "resemblense", "resembles", - "reserachers", "researchers", - "reseraching", "researching", - "resgination", "resignation", - "residencial", "residential", - "residentail", "residential", - "residentual", "residential", - "resignacion", "resignation", - "resignating", "resignation", - "resignement", "resignment", - "resignition", "resignation", - "resintalled", "reinstalled", - "resistansen", "resistances", - "resistanses", "resistances", - "resistences", "resistances", - "resistnaces", "resistances", - "resoltuions", "resolutions", - "resotration", "restoration", - "resoultions", "resolutions", - "respecatble", "respectable", - "respectabil", "respectable", - "respectfuly", "respectfully", - "respectible", "respectable", - "respectivly", "respectively", - "respectuful", "respectful", - "respektable", "respectable", - "resperatory", "respiratory", - "resperitory", "respiratory", - "respiritory", "respiratory", - "respitatory", "respiratory", - "responcible", "responsible", - "responcibly", "responsibly", - "respondendo", "responded", - "responisble", "responsible", - "responisbly", "responsibly", - "responsable", "responsible", - "responsably", "responsibly", - "responsbile", "responsible", - "responsbily", "responsibly", - "responsibel", "responsibly", - "responsibil", "responsibly", - "responsivle", "responsive", - "resporatory", "respiratory", - "respository", "repository", - "respriatory", "respiratory", - "ressembling", "resembling", - "ressurected", "resurrected", - "restaraunts", "restaurants", - "restaruants", "restaurants", - "restauraunt", "restaurant", - "restaurents", "restaurants", - "resteraunts", "restaurants", - "restirction", "restriction", - "restorarion", "restoration", - "restorating", "restoration", - "restrainted", "restrained", - "restrective", "restrictive", - "restriccion", "restriction", - "restricitng", "restricting", - "restriciton", "restrictions", - "restricitve", "restrictive", - "restricteds", "restricts", - "restricters", "restricts", - "restrictied", "restrictive", - "restrictifs", "restricts", - "restrictins", "restricts", - "restrictios", "restricts", - "restrictivo", "restriction", - "restrictons", "restricts", - "restriktion", "restriction", - "restriktive", "restrictive", - "restrittive", "restrictive", - "restructing", "restricting", - "restruction", "restriction", - "restuarants", "restaurants", - "resturaunts", "restaurants", - "resurecting", "resurrecting", - "resurrecion", "resurrection", - "retailation", "retaliation", - "retalitated", "retaliated", - "retardathon", "retardation", - "retardating", "retardation", - "retardatron", "retardation", - "retartation", "retardation", - "retirbution", "retribution", - "retrebution", "retribution", - "retribucion", "retribution", - "retribuiton", "retribution", - "retributivo", "retribution", - "retribvtion", "retribution", - "retrobution", "retribution", - "retrubution", "retribution", - "revealtions", "revelations", - "revelaitons", "revelations", - "revolations", "revolutions", - "revoultions", "revolutions", - "ridiculious", "ridiculous", - "ridiculosly", "ridiculously", - "ridiculouly", "ridiculously", - "ridiculousy", "ridiculously", - "rightfullly", "rightfully", - "rolepalying", "roleplaying", - "romanticaly", "romantically", - "roundabaout", "roundabout", - "roundabount", "roundabout", - "rudimentery", "rudimentary", - "rudimentory", "rudimentary", - "ruidmentary", "rudimentary", - "sacrifacing", "sacrificing", - "sacrificare", "sacrifice", - "sacrificied", "sacrifice", - "sacrificies", "sacrifice", - "sacrifieced", "sacrificed", - "sacrifising", "sacrificing", - "sacrifizing", "sacrificing", - "salughtered", "slaughtered", - "sanctionned", "sanctioned", - "sarcastisch", "sarcastic", - "saskatchewn", "saskatchewan", - "saskatchwan", "saskatchewan", - "satisfacion", "satisfaction", - "satisfacory", "satisfactory", - "scandanavia", "scandinavia", - "scandanivia", "scandinavian", - "scandenavia", "scandinavia", - "scandianvia", "scandinavian", - "scandimania", "scandinavia", - "scandinaiva", "scandinavian", - "scandinavan", "scandinavian", - "scandivania", "scandinavian", - "scandonavia", "scandinavia", - "scarificing", "sacrificing", - "scheduleing", "scheduling", - "schedulling", "scheduling", - "schoalrship", "scholarships", - "scholarhips", "scholarship", - "scholarstic", "scholastic", - "scholership", "scholarship", - "scholorship", "scholarship", - "scientiests", "scientists", - "scnadinavia", "scandinavia", - "scrambleing", "scrambling", - "screenshoot", "screenshot", - "seamlessley", "seamlessly", - "sedentarity", "sedentary", - "seflishness", "selfishness", - "segergation", "segregation", - "segragation", "segregation", - "segregacion", "segregation", - "segretation", "segregation", - "segrigation", "segregation", - "selectivley", "selectively", - "selfeshness", "selfishness", - "senitmental", "sentimental", - "sensacional", "sensational", - "sensasional", "sensational", - "sensationel", "sensational", - "sensetional", "sensational", - "sensitivety", "sensitivity", - "sentamental", "sentimental", - "sentemental", "sentimental", - "sentenceing", "sentencing", - "sentimentos", "sentiments", - "sentimentul", "sentimental", - "separatedly", "separately", - "separatelly", "separately", - "separatisme", "separates", - "separatiste", "separates", - "sepculating", "speculating", - "serivceable", "serviceable", - "serviciable", "serviceable", - "settelement", "settlement", - "settelments", "settlements", - "settlemetns", "settlements", - "sexualizied", "sexualized", - "shakeapeare", "shakespeare", - "shakepseare", "shakespeare", - "shakesphere", "shakespeare", - "shanenigans", "shenanigans", - "shareholdes", "shareholders", - "sharpeneing", "sharpening", - "sharpenning", "sharpening", - "shatterling", "shattering", - "shatterring", "shattering", - "sheakspeare", "shakespeare", - "shenadigans", "shenanigans", - "shenanagans", "shenanigans", - "shenanagins", "shenanigans", - "shenanegans", "shenanigans", - "shenanegins", "shenanigans", - "shenangians", "shenanigans", - "shenanigens", "shenanigans", - "shenanigins", "shenanigans", - "shenenigans", "shenanigans", - "sheninigans", "shenanigans", - "shennaigans", "shenanigans", - "shortenning", "shortening", - "shortenting", "shortening", - "signficiant", "significant", - "signifantly", "significantly", - "significane", "significance", - "significato", "significant", - "signifigant", "significant", - "signifikant", "significant", - "signitories", "signatories", - "signularity", "singularity", - "similarites", "similarities", - "similarlity", "similarity", - "similiarity", "similarity", - "simluations", "simulations", - "simplefying", "simplifying", - "simplicitly", "simplicity", - "simplifiing", "simplifying", - "simplisitic", "simplistic", - "simplyifing", "simplifying", - "simualtions", "simulations", - "simulatious", "simulations", - "simultaneos", "simultaneous", - "simultaneus", "simultaneous", - "simultanous", "simultaneous", - "singluarity", "singularity", - "singualrity", "singularity", - "singulairty", "singularity", - "singularily", "singularity", - "sitautional", "situational", - "situacional", "situational", - "situationly", "situational", - "siutational", "situational", - "skatebaords", "skateboard", - "skateboader", "skateboard", - "skepticisim", "skepticism", - "skillshoots", "skillshots", - "skillshosts", "skillshots", - "slaugthered", "slaughtered", - "slefishness", "selfishness", - "sluaghtered", "slaughtered", - "smarthpones", "smartphones", - "snowboaring", "snowboarding", - "snowbolling", "snowballing", - "snowfalling", "snowballing", - "socailizing", "socializing", - "socialicing", "socializing", - "socialistes", "socialists", - "socialistos", "socialists", - "socializare", "socialize", - "sociapathic", "sociopathic", - "sociologial", "sociological", - "sociopathes", "sociopaths", - "sociopathis", "sociopaths", - "sociophatic", "sociopathic", - "solidariety", "solidarity", - "somethingis", "somethings", - "sorrounding", "surrounding", - "soundtrakcs", "soundtracks", - "southamtpon", "southampton", - "southanpton", "southampton", - "southapmton", "southampton", - "southernese", "southerners", - "southerness", "southerners", - "southernest", "southerners", - "southernors", "southerners", - "southmapton", "southampton", - "southtampon", "southampton", - "soveregnity", "sovereignty", - "sovereighty", "sovereignty", - "sovereingty", "sovereignty", - "sovereinity", "sovereignty", - "soveriegnty", "sovereignty", - "soveriengty", "sovereignty", - "soverignity", "sovereignty", - "specailists", "specialists", - "specailized", "specialized", - "specailizes", "specializes", - "specatcular", "spectacular", - "specialiced", "specialized", - "specialices", "specializes", - "specialites", "specializes", - "speciallist", "specialist", - "speciallity", "specially", - "speciallize", "specialize", - "specialzied", "specialized", - "specifcally", "specifically", - "specificaly", "specifically", - "specificato", "specification", - "specificies", "specifics", - "specifiying", "specifying", - "specilaized", "specialize", - "speciliazed", "specialize", - "spectatores", "spectators", - "spectatular", "spectacular", - "spectauclar", "spectacular", - "spectaulars", "spectaculars", - "spectecular", "spectacular", - "specualting", "speculating", - "specualtion", "speculation", - "specualtive", "speculative", - "specularite", "speculative", - "speculaties", "speculative", - "spiritualiy", "spiritually", - "spiritualty", "spirituality", - "spirituella", "spiritually", - "spirtiually", "spiritually", - "spirutually", "spiritually", - "spitirually", "spiritually", - "sponatenous", "spontaneous", - "sponatneous", "spontaneous", - "sponsership", "sponsorship", - "sponsorhips", "sponsorship", - "sponsorhsip", "sponsorship", - "sponsorshop", "sponsorship", - "spontaenous", "spontaneous", - "spontainous", "spontaneous", - "spontaneuos", "spontaneous", - "spontanious", "spontaneous", - "sponteanous", "spontaneous", - "sponteneous", "spontaneous", - "spreadhseet", "spreadsheet", - "spreadsheat", "spreadsheet", - "spreadshets", "spreadsheets", - "spreedsheet", "spreadsheet", - "springfeild", "springfield", - "springfiled", "springfield", - "sprinklered", "sprinkled", - "squirrelies", "squirrels", - "squirrelius", "squirrels", - "stabilizare", "stabilize", - "stabilizied", "stabilize", - "stabilizier", "stabilize", - "stabilizies", "stabilize", - "staggerring", "staggering", - "staggerwing", "staggering", - "stationairy", "stationary", - "stationerad", "stationed", - "stationnary", "stationary", - "statisitcal", "statistical", - "statisticly", "statistical", - "statistisch", "statistics", - "statsitical", "statistical", - "stereotpyes", "stereotypes", - "stereotying", "stereotyping", - "steriotypes", "stereotypes", - "steroetypes", "stereotypes", - "steryotypes", "stereotypes", - "stimluating", "stimulating", - "stimualting", "stimulating", - "stimualtion", "stimulation", - "stimulantes", "stimulants", - "stockpilled", "stockpile", - "stormfrount", "stormfront", - "storyteling", "storytelling", - "straightden", "straightened", - "straightend", "straightened", - "straightmen", "straighten", - "straightned", "straightened", - "straightner", "straighten", - "strangeshit", "strangest", - "strategisch", "strategic", - "strategiske", "strategies", - "strawberies", "strawberries", - "strawberrry", "strawberry", - "strawbrerry", "strawberry", - "strenghened", "strengthened", - "strenghtend", "strengthen", - "strenghtens", "strengthen", - "strengtened", "strengthened", - "structurels", "structures", - "strugglebus", "struggles", - "struggleing", "struggling", - "stubborness", "stubbornness", - "stutterring", "stuttering", - "subcatagory", "subcategory", - "subconscius", "subconscious", - "subconscous", "subconscious", - "subisdizing", "subsidizing", - "subjectivly", "subjectively", - "submergered", "submerged", - "submisisons", "submissions", - "subredddits", "subreddits", - "subscirbers", "subscribers", - "subscribbed", "subscribe", - "subscribber", "subscriber", - "subscriping", "subscribing", - "subscriptin", "subscriptions", - "subscripton", "subscription", - "subsequenty", "subsequently", - "subsidiezed", "subsidized", - "subsidizied", "subsidized", - "subsidizies", "subsidize", - "subsiziding", "subsidizing", - "subsquently", "subsequently", - "subsrcibers", "subscribers", - "substancial", "substantial", - "substansial", "substantial", - "substansive", "substantive", - "substantied", "substantive", - "substanties", "substantive", - "substential", "substantial", - "substitiute", "substitute", - "substituded", "substituted", - "substitudes", "substitutes", - "substituion", "substitution", - "substitures", "substitutes", - "substitutie", "substitutes", - "substitutos", "substitutes", - "substitutue", "substitutes", - "substracted", "subtracted", - "suburburban", "suburban", - "succesfully", "successfully", - "successeurs", "successes", - "successfull", "successful", - "successfuly", "successfully", - "successsion", "succession", - "successully", "successfully", - "succsesfull", "successfully", - "sucessfully", "successfully", - "sucseptible", "susceptible", - "sufficently", "sufficiently", - "suggestieve", "suggestive", - "sumbissions", "submissions", - "sunglassses", "sunglasses", - "superceeded", "superseded", - "superficiel", "superficial", - "superfulous", "superfluous", - "superhereos", "superhero", - "superifical", "superficial", - "superiorest", "superiors", - "supermacist", "supremacist", - "supermakert", "supermarkets", - "supermakret", "supermarkets", - "supermakter", "supermarkets", - "supermarkts", "supermarkets", - "supermaster", "supermarkets", - "supernatual", "supernatural", - "supersition", "supervision", - "superstiton", "superstition", - "supervisers", "supervisors", - "supervisior", "supervisor", - "suplimented", "supplemented", - "supplaments", "supplements", - "supplemetal", "supplemental", - "supporteurs", "supporters", - "supposedely", "supposedly", - "supposidely", "supposedly", - "supposingly", "supposedly", - "suppresions", "suppression", - "suppresssor", "suppressor", - "supramacist", "supremacist", - "supremacits", "supremacist", - "supremasist", "supremacist", - "supremicist", "supremacist", - "suprimacist", "supremacist", - "suprisingly", "surprisingly", - "suprizingly", "surprisingly", - "suroundings", "surroundings", - "surpemacist", "supremacist", - "surprisinly", "surprisingly", - "surreptious", "surreptitious", - "surroundign", "surroundings", - "surroundigs", "surrounds", - "surroundins", "surrounds", - "surroundngs", "surrounds", - "surveilence", "surveillance", - "survivabily", "survivability", - "susbtantial", "substantial", - "susbtantive", "substantive", - "suscepitble", "susceptible", - "susceptable", "susceptible", - "suscpetible", "susceptible", - "susecptible", "susceptible", - "suspectible", "susceptible", - "suspiciosly", "suspiciously", - "suspiciouly", "suspiciously", - "suspiciouns", "suspicion", - "suspicision", "suspicions", - "suspicisons", "suspicions", - "sustainible", "sustainable", - "switerzland", "switzerland", - "switserland", "switzerland", - "switzlerand", "switzerland", - "swizterland", "switzerland", - "swtizerland", "switzerland", - "symapthetic", "sympathetic", - "symmertical", "symmetrical", - "sympathatic", "sympathetic", - "sympathiers", "sympathizers", - "sympathsize", "sympathize", - "sympethetic", "sympathetic", - "symphatetic", "sympathetic", - "symphatized", "sympathize", - "symphatizer", "sympathizers", - "symphatizes", "sympathize", - "sympothetic", "sympathetic", - "synthesasia", "synthesis", - "synthesesia", "synthesis", - "sypmathetic", "sympathetic", - "tabelspoons", "tablespoons", - "tablepsoons", "tablespoons", - "tablespooon", "tablespoon", - "tablesppons", "tablespoons", - "tailgateing", "tailgating", - "tailgatting", "tailgating", - "tangentialy", "tangentially", - "techincally", "technically", - "techincians", "technicians", - "techiniques", "techniques", - "techncially", "technically", - "technicalty", "technicality", - "technichian", "technician", - "technicials", "technicians", - "techniciens", "technicians", - "technitians", "technicians", - "technnology", "technology", - "technologia", "technological", - "techticians", "technicians", - "teleportato", "teleportation", - "teleportion", "teleporting", - "teleproting", "teleporting", - "temeprature", "temperature", - "temparament", "temperament", - "temparature", "temperature", - "temparement", "temperament", - "tempearture", "temperatures", - "temperamant", "temperament", - "temperarily", "temporarily", - "temperatues", "temperatures", - "temperaturs", "temperatures", - "temperatuur", "temperature", - "temperement", "temperament", - "tempermeant", "temperament", - "tempertaure", "temperature", - "temporairly", "temporarily", - "temporaraly", "temporarily", - "temporarity", "temporarily", - "tempreature", "temperature", - "temproarily", "temporarily", - "tempurature", "temperature", - "tepmorarily", "temporarily", - "termanology", "terminology", - "terminacion", "termination", - "terminaison", "termination", - "terminalogy", "terminology", - "terminatior", "terminator", - "terminatorn", "termination", - "terminilogy", "terminology", - "terminoligy", "terminology", - "terratorial", "territorial", - "terratories", "territories", - "terretorial", "territorial", - "terretories", "territories", - "terrirorial", "territorial", - "terrirories", "territories", - "terriroties", "territories", - "terristrial", "territorial", - "territoires", "territories", - "territorist", "terrorist", - "territority", "territory", - "terroristas", "terrorists", - "terroristes", "terrorists", - "terrorities", "territories", - "terrotorial", "territorial", - "terrotories", "territories", - "testiclular", "testicular", - "thankfullly", "thankfully", - "thanksgivng", "thanksgiving", - "theoligical", "theological", - "theoratical", "theoretical", - "theoreticly", "theoretical", - "theoritical", "theoretical", - "therapautic", "therapeutic", - "therapeudic", "therapeutic", - "therapeutuc", "therapeutic", - "therapuetic", "therapeutic", - "theraupetic", "therapeutic", - "thereaputic", "therapeutic", - "thereotical", "theoretical", - "therepeutic", "therapeutic", - "thermometor", "thermometer", - "thermometre", "thermometer", - "thermomiter", "thermometer", - "thermomoter", "thermometer", - "thermoneter", "thermometer", - "thermostaat", "thermostat", - "theroetical", "theoretical", - "thoeretical", "theoretical", - "threataning", "threatening", - "threatended", "threatened", - "threatining", "threatening", - "throttleing", "throttling", - "throughoput", "throughput", - "throughtout", "throughout", - "throughtput", "throughput", - "thudnerbolt", "thunderbolt", - "thunberbolt", "thunderbolt", - "thunderblot", "thunderbolt", - "thunderboat", "thunderbolt", - "thunderbots", "thunderbolt", - "thunderbowl", "thunderbolt", - "thunderjolt", "thunderbolt", - "thundervolt", "thunderbolt", - "tightenting", "tightening", - "tocuhscreen", "touchscreen", - "torrentking", "torrenting", - "torrentting", "torrenting", - "torublesome", "troublesome", - "torunaments", "tournaments", - "totalitaran", "totalitarian", - "totalitarni", "totalitarian", - "touranments", "tournaments", - "tournamnets", "tournaments", - "tournemants", "tournaments", - "tournements", "tournaments", - "tournmanets", "tournaments", - "tradicional", "traditional", - "tradionally", "traditionally", - "tradisional", "traditional", - "traditionel", "traditional", - "traditition", "tradition", - "tragicallly", "tragically", - "tramautized", "traumatized", - "tramuatized", "traumatized", - "trancendent", "transcendent", - "trancending", "transcending", - "tranclucent", "translucent", - "trandgender", "transgender", - "tranditions", "transitions", - "tranistions", "transitions", - "tranlastion", "translations", - "tranlsating", "translating", - "tranlsation", "translation", - "tranluscent", "translucent", - "trannsexual", "transsexual", - "tranpshobic", "transphobic", - "transaccion", "transaction", - "transaciton", "transactions", - "transalting", "translating", - "transaltion", "translation", - "transations", "transitions", - "transcluent", "translucent", - "transcripto", "transcription", - "transctions", "transitions", - "transculent", "translucent", - "transending", "transcending", - "transfender", "transgender", - "transferers", "transfers", - "transfering", "transferring", - "transfersom", "transforms", - "transfomers", "transforms", - "transformas", "transforms", - "transformes", "transformers", - "transformis", "transforms", - "transformus", "transforms", - "transforums", "transforms", - "transfromed", "transformed", - "transfromer", "transformers", - "transgemder", "transgender", - "transgended", "transgendered", - "transgenger", "transgender", - "transgenres", "transgender", - "transhpobic", "transphobic", - "transisions", "transitions", - "transisitor", "transistor", - "transistion", "transition", - "transistior", "transistor", - "transitiond", "transitioned", - "transitiong", "transitioning", - "translatron", "translation", - "translusent", "translucent", - "transmatter", "transmitter", - "transmision", "transmission", - "transmissin", "transmissions", - "transmisson", "transmission", - "transmittor", "transmitter", - "transmorged", "transformed", - "transmutter", "transmitter", - "transofrmed", "transformed", - "transohobic", "transphobic", - "transparant", "transparent", - "transparecy", "transparency", - "transpareny", "transparency", - "transperant", "transparent", - "transperent", "transparent", - "transphonic", "transphobic", - "transphopic", "transphobic", - "transplanet", "transplant", - "transporder", "transporter", - "transporing", "transporting", - "transportar", "transporter", - "transportng", "transporting", - "transportor", "transporter", - "transseuxal", "transsexual", - "transsexaul", "transsexual", - "transsexuel", "transsexual", - "transulcent", "translucent", - "transylvnia", "transylvania", - "tranzformer", "transformer", - "tranzitions", "transitions", - "tranzporter", "transporter", - "trasncripts", "transcripts", - "trasnferred", "transferred", - "trasnformed", "transformed", - "trasnformer", "transformer", - "trasngender", "transgender", - "trasnmitted", "transmitted", - "trasnmitter", "transmitter", - "trasnparent", "transparent", - "trasnphobic", "transphobic", - "trasnported", "transported", - "trasnporter", "transporter", - "traumatisch", "traumatic", - "traumetized", "traumatized", - "traumitized", "traumatized", - "travellerhd", "travelled", - "travellodge", "travelled", - "tremendeous", "tremendous", - "tremendious", "tremendous", - "tremenduous", "tremendous", - "trespessing", "trespassing", - "tresspasing", "trespassing", - "triggereing", "triggering", - "triggerring", "triggering", - "troubelsome", "troublesome", - "truamatized", "traumatized", - "trushworthy", "trustworthy", - "trustowrthy", "trustworthy", - "trustwhorty", "trustworthy", - "trustworhty", "trustworthy", - "truthfullly", "truthfully", - "tupperwears", "tupperware", - "turstworthy", "trustworthy", - "ubiquitious", "ubiquitous", - "ubiquituous", "ubiquitous", - "ukraininans", "ukrainians", - "ultimatelly", "ultimately", - "unanimoulsy", "unanimous", - "unappeasing", "unappealing", - "unappeeling", "unappealing", - "unathorised", "unauthorised", - "unattendend", "unattended", - "unatteneded", "unattended", - "unattracive", "unattractive", - "unauthoried", "unauthorized", - "unavailible", "unavailable", - "unavaliable", "unavailable", - "unaviodable", "unavoidable", - "unbalanaced", "unbalanced", - "unbraikable", "unbreakable", - "unbrakeable", "unbreakable", - "unbreakabie", "unbreakable", - "unbreakabke", "unbreakable", - "unbreakbale", "unbreakable", - "unbreakeble", "unbreakable", - "unbrearable", "unbreakable", - "uncensorred", "uncensored", - "uncertaincy", "uncertainty", - "uncertanity", "uncertainty", - "uncertianty", "uncertainty", - "unchangable", "unchangeable", - "uncompetive", "uncompetitive", - "unconcsious", "unconscious", - "unconsicous", "unconscious", - "uncouncious", "unconscious", - "undeniabely", "undeniably", - "undeniabley", "undeniably", - "undeniablly", "undeniably", - "undenialbly", "undeniably", - "underestime", "underestimate", - "undergating", "undertaking", - "undergorund", "underground", - "underheight", "underweight", - "undermiming", "undermining", - "undermindes", "undermines", - "undernearth", "underneath", - "underneight", "underweight", - "underpining", "undermining", - "underpowerd", "underpowered", - "underpowred", "underpowered", - "underratted", "underrated", - "understannd", "understands", - "understsand", "understands", - "undertacker", "undertaker", - "underwarter", "underwater", - "underwieght", "underweight", - "underwright", "underweight", - "undesireble", "undesirable", - "undesriable", "undesirable", - "undetecable", "undetectable", - "undiserable", "undesirable", - "undoubedtly", "undoubtedly", - "undoubetdly", "undoubtedly", - "undoubtadly", "undoubtedly", - "undoubtebly", "undoubtedly", - "undoubtetly", "undoubtedly", - "undreground", "underground", - "unemployeed", "unemployed", - "unemployent", "unemployment", - "unemploymed", "unemployed", - "unexpectdly", "unexpectedly", - "unexpectely", "unexpectedly", - "unfamilliar", "unfamiliar", - "unfortuante", "unfortunate", - "ungreatfull", "ungrateful", - "unilateraly", "unilaterally", - "unilaterlly", "unilaterally", - "unimportent", "unimportant", - "uninspiried", "uninspired", - "uninstaling", "uninstalling", - "uninstallng", "uninstalling", - "uninteresed", "uninterested", - "uniquesness", "uniqueness", - "unisntalled", "uninstalled", - "universella", "universally", - "universites", "universities", - "univesities", "universities", - "unjustifyed", "unjustified", - "unknowinlgy", "unknowingly", - "unkowningly", "unknowingly", - "unnecassary", "unnecessary", - "unneccesary", "unnecessary", - "unnecessery", "unnecessary", - "unnecissary", "unnecessary", - "unnessecary", "unnecessary", - "unnistalled", "uninstalled", - "unoriginial", "unoriginal", - "unorigional", "unoriginal", - "unoticeable", "unnoticeable", - "unpleaseant", "unpleasant", - "unportected", "unprotected", - "unprepaired", "unprepared", - "unpreparred", "unprepared", - "unproducive", "unproductive", - "unprotexted", "unprotected", - "unqaulified", "unqualified", - "unrealisitc", "unrealistic", - "unrealsitic", "unrealistic", - "unreasonbly", "unreasonably", - "unregluated", "unregulated", - "unregualted", "unregulated", - "unregulared", "unregulated", - "unrepentent", "unrepentant", - "unresponive", "unresponsive", - "unrestriced", "unrestricted", - "unsettleing", "unsettling", - "unsintalled", "uninstalled", - "unsolicated", "unsolicited", - "unsoliticed", "unsolicited", - "unsolocited", "unsolicited", - "unsubscirbe", "unsubscribe", - "unsubscrbed", "unsubscribed", - "unsubscried", "unsubscribed", - "unsubscripe", "unsubscribe", - "unsubscrive", "unsubscribe", - "unsubscrube", "unsubscribe", - "unsubsrcibe", "unsubscribe", - "unsuccesful", "unsuccessful", - "unsuccessul", "unsuccessful", - "unsucesfuly", "unsuccessfully", - "unsucessful", "unsuccessful", - "unsunscribe", "unsubscribe", - "unsuprising", "unsurprising", - "unsuprizing", "unsurprising", - "unsurprized", "unsurprised", - "unsusbcribe", "unsubscribe", - "unviersally", "universally", - "unwarrented", "unwarranted", - "utiliatrian", "utilitarian", - "utilitatian", "utilitarian", - "utiliterian", "utilitarian", - "utilizacion", "utilization", - "utilizaiton", "utilization", - "utilizating", "utilization", - "utiltiarian", "utilitarian", - "vacciantion", "vaccination", - "vaccinaties", "vaccinate", - "vegaterians", "vegetarians", - "vegetariens", "vegetarians", - "vegetatians", "vegetarians", - "vegeterians", "vegetarians", - "vehementely", "vehemently", - "venezuelean", "venezuela", - "venezuelian", "venezuela", - "ventalation", "ventilation", - "ventelation", "ventilation", - "ventialtion", "ventilation", - "ventilacion", "ventilation", - "verastility", "versatility", - "verfication", "verification", - "versatality", "versatility", - "versitality", "versatility", - "versitilaty", "versatility", - "victorieuse", "victories", - "victoriuous", "victorious", - "vietnameese", "vietnamese", - "vietnamesse", "vietnamese", - "vietnamiese", "vietnamese", - "vietnamnese", "vietnamese", - "vigilanties", "vigilante", - "visibillity", "visibility", - "vocabularly", "vocabulary", - "volatillity", "volatility", - "volonteered", "volunteered", - "volounteers", "volunteers", - "volunatrily", "voluntarily", - "voluntairly", "voluntarily", - "volunteeers", "volunteers", - "volunteraly", "voluntarily", - "voluntereed", "volunteered", - "volunterily", "voluntarily", - "vulnerabile", "vulnerable", - "wallpapaers", "wallpapers", - "wallpappers", "wallpapers", - "washingtion", "washington", - "watermeleon", "watermelon", - "waterprooof", "waterproof", - "wavelegnths", "wavelength", - "wavelenghth", "wavelength", - "wavelenghts", "wavelength", - "weaknessses", "weaknesses", - "wellingston", "wellington", - "wellingtion", "wellington", - "westernerns", "westerners", - "westmisnter", "westminster", - "westmnister", "westminster", - "westmonster", "westminster", - "whisperered", "whispered", - "whitholding", "withholding", - "wikileakers", "wikileaks", - "willingless", "willingness", - "wincheseter", "winchester", - "windsheilds", "windshield", - "withdrawels", "withdrawals", - "withdrawles", "withdrawals", - "withhelding", "withholding", - "withrdawing", "withdrawing", - "witnesssing", "witnessing", - "woodowrking", "woodworking", - "woodworkign", "woodworking", - "worhsipping", "worshipping", - "workstaiton", "workstation", - "workststion", "workstation", - "worshopping", "worshipping", - "xenophoblic", "xenophobic", - "abandining", "abandoning", - "abandonned", "abandoned", - "abbreviato", "abbreviation", - "abnoramlly", "abnormally", - "abnormalty", "abnormally", - "abnornally", "abnormally", - "abominaton", "abomination", - "abondoning", "abandoning", - "aborginial", "aboriginal", - "aboriganal", "aboriginal", - "aborigenal", "aboriginal", - "aborignial", "aboriginal", - "aborigonal", "aboriginal", - "aboroginal", "aboriginal", - "aboslutely", "absolutely", - "abosrption", "absorption", - "abreviated", "abbreviated", - "absintence", "abstinence", - "absitnence", "abstinence", - "absolument", "absolute", - "absolutley", "absolutely", - "absoprtion", "absorption", - "absorbsion", "absorption", - "absorbtion", "absorption", - "absorpsion", "absorption", - "absoultely", "absolutely", - "abstanence", "abstinence", - "abstenance", "abstinence", - "abstenince", "abstinence", - "abstinense", "abstinence", - "abstinince", "abstinence", - "absurditiy", "absurdity", - "abundacies", "abundances", - "academicas", "academics", - "academicos", "academics", - "academicus", "academics", - "accdiently", "accidently", - "accelarate", "accelerate", - "accelerade", "accelerated", - "accelerare", "accelerate", - "accelerato", "acceleration", - "acceleread", "accelerated", - "accelertor", "accelerator", - "accelorate", "accelerate", - "acceptabel", "acceptable", - "acceptabil", "acceptable", - "acceptence", "acceptance", - "accepterad", "accepted", - "acceptible", "acceptable", - "accerelate", "accelerated", - "accesories", "accessories", - "accessable", "accessible", - "accessbile", "accessible", - "accessoire", "accessories", - "accessoirs", "accessories", - "accicently", "accidently", - "accidantly", "accidently", - "accidebtly", "accidently", - "accidenlty", "accidently", - "accidentes", "accidents", - "accidentky", "accidently", - "accidently", "accidentally", - "accidnetly", "accidently", - "accomadate", "accommodate", - "accomodate", "accommodate", - "accompined", "accompanied", - "accomplise", "accomplishes", - "accompliss", "accomplishes", - "accostumed", "accustomed", - "accountent", "accountant", - "accpetable", "acceptable", - "accpetance", "acceptance", - "accuastion", "accusation", - "acculumate", "accumulate", - "accumalate", "accumulate", - "accumelate", "accumulate", - "accumilate", "accumulate", - "accumulare", "accumulate", - "accumulato", "accumulation", - "accumulted", "accumulated", - "accuratley", "accurately", - "accusating", "accusation", - "accusition", "accusation", - "accustumed", "accustomed", - "acheivable", "achievable", - "acheivment", "achievement", - "acheviable", "achievable", - "achiavable", "achievable", - "achieveble", "achievable", - "achievemnt", "achievement", - "achievemts", "achieves", - "achievents", "achieves", - "achievment", "achievement", - "achilleous", "achilles", - "achiveable", "achievable", - "achivement", "achievement", - "acitvating", "activating", - "acitvision", "activision", - "acknowldge", "acknowledge", - "acknowlede", "acknowledge", - "acknowlege", "acknowledge", - "acommodate", "accommodate", - "acopalypse", "apocalypse", - "acordingly", "accordingly", - "acqauinted", "acquainted", - "acquanited", "acquainted", - "acquianted", "acquainted", - "acquinated", "acquainted", - "acquisiton", "acquisition", - "acticating", "activating", - "actication", "activation", - "activacion", "activation", - "activaters", "activates", - "activiates", "activist", - "activiites", "activist", - "activisiom", "activism", - "activisits", "activist", - "activistas", "activists", - "activistes", "activists", - "activiting", "activating", - "activizion", "activision", - "acustommed", "accustomed", - "adaptacion", "adaptation", - "adaptating", "adaptation", - "adaquetely", "adequately", - "addicitons", "addictions", - "addionally", "additionally", - "additivies", "additive", - "additivley", "additive", - "addittions", "addictions", - "addmission", "admission", - "addresable", "addressable", - "addressess", "addresses", - "adequatley", "adequately", - "adequetely", "adequately", - "adequitely", "adequately", - "adernaline", "adrenaline", - "adjectivos", "adjectives", - "adjustible", "adjustable", - "admendment", "amendment", - "administed", "administered", - "administor", "administer", - "administre", "administer", - "administro", "administer", - "adminsiter", "administer", - "admissable", "admissible", - "admittadly", "admittedly", - "admittetly", "admittedly", - "admittidly", "admittedly", - "adolencent", "adolescent", - "adolescant", "adolescent", - "adolescene", "adolescence", - "adoloscent", "adolescent", - "adolsecent", "adolescent", - "adpatation", "adaptation", - "adreanline", "adrenaline", - "adrelanine", "adrenaline", - "adreneline", "adrenaline", - "adreniline", "adrenaline", - "adressable", "addressable", - "advanteges", "advantages", - "advatanges", "advantages", - "adventrous", "adventurous", - "adventrues", "adventures", - "adventuers", "adventures", - "adventuous", "adventurous", - "adventuros", "adventurous", - "adventurus", "adventurous", - "adverticed", "advertised", - "aestethics", "aesthetics", - "aesthatics", "aesthetics", - "aesthestic", "aesthetics", - "affiliaton", "affiliation", - "affilliate", "affiliate", - "affirmitve", "affirmative", - "afflcition", "affliction", - "afflection", "affliction", - "affliation", "affliction", - "affliciton", "affliction", - "afforadble", "affordable", - "affordible", "affordable", - "affortable", "affordable", - "africaners", "africans", - "africaness", "africans", - "aftermaket", "aftermarket", - "afternooon", "afternoon", - "aggravanti", "aggravating", - "aggraveted", "aggravated", - "aggreement", "agreement", - "aggregious", "egregious", - "aggresions", "aggression", - "aggressivo", "aggression", - "aggrovated", "aggravated", - "agnosticim", "agnosticism", - "agnosticsm", "agnosticism", - "agnostisch", "agnostic", - "agnostiscm", "agnosticism", - "agnostisim", "agnosticism", - "agreeement", "agreement", - "agricultre", "agriculture", - "agricultue", "agriculture", - "agriculure", "agriculture", - "agricuture", "agriculture", - "ailenating", "alienating", - "ajdectives", "adjectives", - "alchoholic", "alcoholic", - "alchoolism", "alcoholism", - "alcohalics", "alcoholics", - "alcohalism", "alcoholism", - "alcoholsim", "alcoholism", - "aleinating", "alienating", - "algorhitms", "algorithms", - "algorithem", "algorithm", - "algorithim", "algorithm", - "algorithsm", "algorithms", - "algorithum", "algorithm", - "algorithym", "algorithm", - "algoritmes", "algorithms", - "algoritmos", "algorithms", - "algorthims", "algorithms", - "algortihms", "algorithms", - "algorythms", "algorithms", - "alievating", "alienating", - "alledgedly", "allegedly", - "allegeance", "allegiance", - "allegedely", "allegedly", - "allegedley", "allegedly", - "allegience", "allegiance", - "alleigance", "allegiance", - "allergisch", "allergic", - "alliegance", "allegiance", - "alligeance", "allegiance", - "alocholics", "alcoholics", - "alocholism", "alcoholism", - "alogrithms", "algorithms", - "alphabeast", "alphabet", - "alteracion", "alteration", - "alterarion", "alteration", - "alterating", "alteration", - "alternador", "alternator", - "alternater", "alternator", - "alternatie", "alternatives", - "alternatly", "alternately", - "alternatve", "alternate", - "alternetly", "alternately", - "altogehter", "altogether", - "altogheter", "altogether", - "altriustic", "altruistic", - "altruisitc", "altruistic", - "altrusitic", "altruistic", - "alturistic", "altruistic", - "aluminimum", "aluminum", - "amargeddon", "armageddon", - "amateurest", "amateurs", - "ambassabor", "ambassador", - "ambassader", "ambassador", - "ambassator", "ambassador", - "ambassedor", "ambassador", - "ambassidor", "ambassador", - "ambassodor", "ambassador", - "ambiguitiy", "ambiguity", - "amendmants", "amendments", - "amendmends", "amendments", - "americains", "americas", - "americanas", "americans", - "americanis", "americas", - "americanss", "americas", - "americants", "americas", - "americanus", "americans", - "americares", "americas", - "ammendment", "amendment", - "amrageddon", "armageddon", - "analitical", "analytical", - "analitycal", "analytical", - "analogeous", "analogous", - "analyitcal", "analytical", - "analyseles", "analyses", - "analyseras", "analyses", - "analyseres", "analyses", - "analysised", "analyses", - "analysises", "analyses", - "analysisto", "analysts", - "analystics", "analysts", - "anarchisim", "anarchism", - "anarchistm", "anarchism", - "anarchiszm", "anarchism", - "anarchsits", "anarchists", - "anayltical", "analytical", - "ancilliary", "ancillary", - "androiders", "androids", - "androidtvs", "androids", - "anecdotale", "anecdote", - "anecdotice", "anecdote", - "anestheisa", "anesthesia", - "anesthetia", "anesthesia", - "anesthisia", "anesthesia", - "anitbiotic", "antibiotic", - "anitquated", "antiquated", - "anitsocial", "antisocial", - "aniversary", "anniversary", - "annilihate", "annihilated", - "anniverary", "anniversary", - "anniversay", "anniversary", - "anniversry", "anniversary", - "annointing", "anointing", - "annonceurs", "announcers", - "annoucners", "announcers", - "annoucning", "announcing", - "announched", "announce", - "annyoingly", "annoyingly", - "anonymosly", "anonymously", - "anonymousy", "anonymously", - "antaganist", "antagonist", - "antagnoist", "antagonist", - "antarcitca", "antarctica", - "antarctida", "antarctica", - "anthropoly", "anthropology", - "antibiodic", "antibiotic", - "antibiotcs", "antibiotics", - "antibitoic", "antibiotic", - "antiboitic", "antibiotics", - "anticapate", "anticipate", - "anticiapte", "anticipate", - "anticipare", "anticipate", - "anticipato", "anticipation", - "anticuated", "antiquated", - "antiquited", "antiquated", - "antiqvated", "antiquated", - "antisipate", "anticipate", - "antisocail", "antisocial", - "antisosial", "antisocial", - "antoganist", "antagonist", - "antractica", "antarctica", - "apacolypse", "apocalypse", - "apartheied", "apartheid", - "aplication", "application", - "apocalipse", "apocalypse", - "apocalpyse", "apocalypse", - "apocalypes", "apocalypse", - "apocalypic", "apocalyptic", - "apocalyspe", "apocalypse", - "apocalytic", "apocalyptic", - "apocaplyse", "apocalypse", - "apocolapse", "apocalypse", - "apolagetic", "apologetic", - "apolagized", "apologized", - "apolegetic", "apologetic", - "apoligetic", "apologetic", - "apoligists", "apologists", - "apoligized", "apologized", - "apologisms", "apologists", - "apologiste", "apologise", - "apologitic", "apologetic", - "apostraphe", "apostrophe", - "apostrephe", "apostrophe", - "apostrohpe", "apostrophe", - "apostropes", "apostrophe", - "apparantly", "apparently", - "appareance", "appearance", - "apparenlty", "apparently", - "appartment", "apartment", - "appealling", "appealing", - "appearence", "appearance", - "appearnace", "appearances", - "apperances", "appearances", - "apperantly", "apparently", - "apperciate", "appreciate", - "appereance", "appearance", - "appetities", "appetite", - "appetitite", "appetite", - "appication", "application", - "applainces", "appliances", - "applicaple", "applicable", - "applicates", "applicants", - "applicaton", "application", - "applicible", "applicable", - "appliences", "appliances", - "appointmet", "appointments", - "appologies", "apologies", - "apporached", "approached", - "apporaches", "approaches", - "appraoched", "approached", - "appraoches", "approaches", - "apprecaite", "appreciate", - "appreciato", "appreciation", - "appreciste", "appreciates", - "apprecitae", "appreciates", - "apprecited", "appreciated", - "apprectice", "apprentice", - "appreicate", "appreciate", - "apprendice", "apprentice", - "apprentace", "apprentice", - "apprentise", "apprentice", - "appretiate", "appreciate", - "appretince", "apprentice", - "appriceate", "appreciates", - "appriciate", "appreciate", - "appriecate", "appreciates", - "approacing", "approaching", - "appropiate", "appropriate", - "approprate", "appropriate", - "apropriate", "appropriate", - "aproximate", "approximate", - "apsotrophe", "apostrophe", - "aptitudine", "aptitude", - "aqcuainted", "acquainted", - "aquisition", "acquisition", - "aramgeddon", "armageddon", - "arangement", "arrangement", - "arbitarily", "arbitrarily", - "arbitraily", "arbitrarily", - "arbitraion", "arbitration", - "arbitrairy", "arbitrarily", - "arbitrarly", "arbitrary", - "arbitraton", "arbitration", - "arcehtypes", "archetypes", - "archaelogy", "archaeology", - "archaeolgy", "archaeology", - "archaology", "archeology", - "archatypes", "archetypes", - "archetects", "architects", - "archetipes", "archetypes", - "archetpyes", "archetypes", - "archetypus", "archetypes", - "archeytpes", "archetypes", - "archictect", "architect", - "architechs", "architects", - "architecht", "architect", - "architecte", "architecture", - "architexts", "architects", - "architypes", "archetypes", - "archtiects", "architects", - "archytypes", "archetypes", - "argentinia", "argentina", - "arguements", "arguments", - "argumentas", "arguments", - "argumentos", "arguments", - "arithemtic", "arithmetic", - "arithmitic", "arithmetic", - "aritmethic", "arithmetic", - "armagaddon", "armageddon", - "armageddan", "armageddon", - "armagedden", "armageddon", - "armageddin", "armageddon", - "armagedeon", "armageddon", - "armageedon", "armageddon", - "armagideon", "armageddon", - "armegaddon", "armageddon", - "arrangerad", "arranged", - "arrangment", "arrangement", - "arthimetic", "arithmetic", - "articifial", "artificial", - "articluate", "articulate", - "articualte", "articulate", - "articulted", "articulated", - "artifactos", "artifacts", - "artificiel", "artificial", - "artihmetic", "arithmetic", - "artillerly", "artillery", - "asbestoast", "asbestos", - "asethetics", "aesthetics", - "asisstants", "assistants", - "aspiratons", "aspirations", - "assasinate", "assassinate", - "assassians", "assassin", - "assassinas", "assassins", - "assassines", "assassins", - "assassinos", "assassins", - "assemblare", "assemble", - "assempling", "assembling", - "assersions", "assertions", - "assesement", "assessment", - "assestment", "assessment", - "assignemnt", "assignment", - "assimalate", "assimilate", - "assimilant", "assimilate", - "assimilare", "assimilate", - "assimliate", "assimilate", - "assimulate", "assimilate", - "assingment", "assignment", - "assistanat", "assistants", - "assistanse", "assistants", - "assistante", "assistance", - "assistence", "assistance", - "assistendo", "assisted", - "assistents", "assistants", - "assmebling", "assembling", - "assocaited", "associated", - "assocaites", "associates", - "assocation", "association", - "associatie", "associated", - "associatin", "associations", - "associaton", "association", - "associsted", "associates", - "assoicated", "associated", - "assoicates", "associates", - "assosiated", "associated", - "assosiates", "associates", - "asssassans", "assassins", - "assupmtion", "assumptions", - "assymetric", "asymmetric", - "asteroides", "asteroids", - "asthetical", "aesthetical", - "astonising", "astonishing", - "astornauts", "astronauts", - "astranauts", "astronauts", - "astronatus", "astronauts", - "astronaunt", "astronaut", - "astronomia", "astronomical", - "astronouts", "astronauts", - "astronuats", "astronauts", - "asutralian", "australian", - "atatchment", "attachment", - "athleticos", "athletics", - "athleticsm", "athleticism", - "athletiscm", "athleticism", - "athletisim", "athleticism", - "atmopshere", "atmosphere", - "atmoshpere", "atmosphere", - "atomsphere", "atmosphere", - "atriculate", "articulate", - "atrocoties", "atrocities", - "atrosities", "atrocities", - "attachemnt", "attachment", - "attackeras", "attackers", - "attactment", "attachment", - "attemtping", "attempting", - "attendence", "attendance", - "attendents", "attendants", - "attirbutes", "attributes", - "attmepting", "attempting", - "attracters", "attracts", - "attractice", "attractive", - "attracties", "attracts", - "attractifs", "attracts", - "attraktion", "attraction", - "attraktive", "attractive", - "attribuito", "attribution", - "attritubes", "attributes", - "auctioners", "auctions", - "audioboook", "audiobook", - "audioboost", "audiobooks", - "auidobooks", "audiobooks", - "auotattack", "autoattack", - "austrailan", "australian", - "austrailia", "australia", - "australain", "australians", - "australien", "australian", - "australina", "australians", - "austrlaian", "australians", - "authenticy", "authenticity", - "autherized", "authorized", - "authoritay", "authority", - "authorites", "authorities", - "authorithy", "authority", - "authroized", "authorized", - "autistisch", "autistic", - "autoattaks", "autoattack", - "autocorect", "autocorrect", - "autocorrct", "autocorrect", - "autocorret", "autocorrect", - "autograpgh", "autograph", - "automatice", "automate", - "automatico", "automation", - "automatied", "automate", - "automatiek", "automate", - "automatron", "automation", - "automatted", "automate", - "automibile", "automobile", - "automitive", "automotive", - "automoblie", "automobile", - "automomous", "autonomous", - "automonous", "autonomous", - "automotice", "automotive", - "automotion", "automation", - "automotize", "automotive", - "automotove", "automotive", - "autonamous", "autonomous", - "autonation", "automation", - "autonimous", "autonomous", - "autonomity", "autonomy", - "autononous", "autonomous", - "auttoatack", "autoattack", - "auxilliary", "auxiliary", - "availabale", "available", - "availaible", "available", - "availiable", "available", - "averageadi", "averaged", - "averageifs", "averages", - "awesomeley", "awesomely", - "awesomelly", "awesomely", - "awesomenss", "awesomeness", - "awkwardess", "awkwardness", - "babysister", "babysitter", - "babysiting", "babysitting", - "babysittng", "babysitting", - "bachelores", "bachelors", - "backgorund", "background", - "backgroudn", "backgrounds", - "backgrouds", "backgrounds", - "backgrouns", "backgrounds", - "backgruond", "backgrounds", - "backpacing", "backpacking", - "backpackng", "backpacking", - "backrgound", "backgrounds", - "backrounds", "backgrounds", - "baksetball", "basketball", - "balanceada", "balanced", - "balanceado", "balanced", - "balckberry", "blackberry", - "balckhawks", "blackhawks", - "balcksmith", "blacksmith", - "bandwagoon", "bandwagon", - "bangaldesh", "bangladesh", - "bangladash", "bangladesh", - "bangledash", "bangladesh", - "bangledesh", "bangladesh", - "banglidesh", "bangladesh", - "bankrupcty", "bankruptcy", - "bankruptsy", "bankruptcy", - "bankrutpcy", "bankruptcy", - "barabrians", "barbarians", - "barbariens", "barbarians", - "barbarions", "barbarians", - "barbarisch", "barbaric", - "barberians", "barbarians", - "bargianing", "bargaining", - "bartendars", "bartenders", - "basektball", "basketball", - "baskteball", "basketball", - "bastardous", "bastards", - "battelship", "battleship", - "battelstar", "battlestar", - "battlearts", "battlestar", - "battlechip", "battleship", - "battlefied", "battlefield", - "battlefont", "battlefront", - "battlehips", "battleship", - "battlesaur", "battlestar", - "battlescar", "battlestar", - "battleshop", "battleship", - "battlestsr", "battlestar", - "beahviours", "behaviours", - "beautifuly", "beautifully", - "beautilful", "beautifully", - "beautyfull", "beautiful", - "becnhmarks", "benchmarks", - "beethoveen", "beethoven", - "begginings", "beginnings", - "begininngs", "beginnings", - "beginninng", "beginnings", - "behaivours", "behaviours", - "behaviorly", "behavioral", - "behavoiral", "behavioral", - "behavoiurs", "behaviours", - "behavorial", "behavioral", - "behavoural", "behavioral", - "behvaiours", "behaviours", - "beleagured", "beleaguered", - "beleivable", "believable", - "beliavable", "believable", - "beliebable", "believable", - "believeble", "believable", - "beliveable", "believable", - "benchamrks", "benchmarks", - "benchmakrs", "benchmarks", - "benckmarks", "benchmarks", - "benefecial", "beneficial", - "beneficary", "beneficiary", - "beneficiul", "beneficial", - "benefitial", "beneficial", - "beneifical", "beneficial", - "benelovent", "benevolent", - "benevalent", "benevolent", - "benevelant", "benevolent", - "benevelent", "benevolent", - "benevelont", "benevolent", - "benevloent", "benevolent", - "benevolant", "benevolent", - "benificial", "beneficial", - "benovelent", "benevolent", - "bernouilli", "bernoulli", - "besitality", "bestiality", - "bestaility", "bestiality", - "besteality", "bestiality", - "betrayeado", "betrayed", - "bilateraly", "bilaterally", - "billborads", "billboards", - "bioligical", "biological", - "biologiset", "biologist", - "biologiskt", "biologist", - "birghtness", "brightness", - "birmignham", "birmingham", - "birmimgham", "birmingham", - "bisexuella", "bisexual", - "bitterseet", "bittersweet", - "bitterswet", "bittersweet", - "blackahwks", "blackhawks", - "blackbarry", "blackberry", - "blackbeary", "blackberry", - "blackbeery", "blackberry", - "blackcawks", "blackhawks", - "blackhakws", "blackhawks", - "blackhwaks", "blackhawks", - "blackmsith", "blacksmith", - "blackshits", "blacksmith", - "blasphemey", "blasphemy", - "blitzkreig", "blitzkrieg", - "blochchain", "blockchain", - "blockcahin", "blockchain", - "blockchian", "blockchain", - "bloodboner", "bloodborne", - "bloodbonre", "bloodborne", - "bloodborbe", "bloodborne", - "bloodbrone", "bloodborne", - "bloodporne", "bloodborne", - "bloorborne", "bloodborne", - "blueberies", "blueberries", - "blueberris", "blueberries", - "blueberrry", "blueberry", - "bluebrints", "blueprints", - "boardcasts", "broadcasts", - "bodyheight", "bodyweight", - "bodyweigth", "bodyweight", - "bodywieght", "bodyweight", - "bombarment", "bombardment", - "bookmakred", "bookmarked", - "bootlaoder", "bootloader", - "bootleader", "bootloader", - "boradcasts", "broadcasts", - "borderlads", "borderlands", - "borderlans", "borderlands", - "bottelneck", "bottleneck", - "bottlebeck", "bottleneck", - "boundaires", "boundaries", - "bounderies", "boundaries", - "bourgeoius", "bourgeois", - "boycutting", "boycotting", - "boyfirends", "boyfriends", - "boyfreinds", "boyfriends", - "boyfrients", "boyfriends", - "braceletes", "bracelets", - "braceletts", "bracelets", - "brainwased", "brainwashed", - "brakedowns", "breakdowns", - "braodcasts", "broadcasts", - "brasillian", "brazilian", - "bratenders", "bartenders", - "brazilains", "brazilians", - "brazileans", "brazilians", - "braziliaan", "brazilians", - "brazilions", "brazilians", - "brazillans", "brazilians", - "brightoner", "brighten", - "brigthness", "brightness", - "brillaince", "brilliance", - "brilliante", "brilliance", - "brillianty", "brilliantly", - "brimestone", "brimstone", - "brimingham", "birmingham", - "broacasted", "broadcast", - "brotherhod", "brotherhood", - "brotherood", "brotherhood", - "brusselers", "brussels", - "brutallity", "brutally", - "buisnesses", "businesses", - "bulgariska", "bulgaria", - "bulletpoof", "bulletproof", - "bulletprof", "bulletproof", - "bureaucats", "bureaucrats", - "businesman", "businessman", - "businesmen", "businessmen", - "businessen", "businessmen", - "butterfies", "butterflies", - "cabinettas", "cabinets", - "caclulated", "calculated", - "caclulator", "calculator", - "cahracters", "characters", - "calcluator", "calculators", - "calcualted", "calculated", - "calcualtor", "calculator", - "calculador", "calculator", - "calcularon", "calculator", - "calculater", "calculator", - "calculatin", "calculations", - "calibratin", "calibration", - "calibraton", "calibration", - "califnoria", "californian", - "califonria", "californian", - "califorian", "californian", - "califorina", "california", - "californai", "californian", - "califronia", "california", - "caligraphy", "calligraphy", - "caliofrnia", "californian", - "calrifying", "clarifying", - "calssified", "classified", - "caluclated", "calculated", - "caluclator", "calculator", - "caluculate", "calculate", - "cambodican", "cambodia", - "camofluage", "camouflage", - "camoufalge", "camouflage", - "camouglage", "camouflage", - "campaiging", "campaigning", - "campaignes", "campaigns", - "cancellato", "cancellation", - "candidatas", "candidates", - "candidatxs", "candidates", - "candidiate", "candidate", - "canditates", "candidates", - "cannibalsm", "cannibalism", - "cannisters", "canisters", - "cannonical", "canonical", - "capabality", "capability", - "capabiltiy", "capability", - "capacators", "capacitors", - "capaciters", "capacitors", - "capactiors", "capacitors", - "capasitors", "capacitors", - "capatilism", "capitalism", - "capatilist", "capitalist", - "capatilize", "capitalize", - "capialized", "capitalized", - "capicators", "capacitors", - "capitalisn", "capitals", - "capitalits", "capitalists", - "capitalsim", "capitalism", - "capitalsit", "capitalists", - "capitarist", "capitalist", - "capitilism", "capitalism", - "capitilist", "capitalist", - "capitilize", "capitalize", - "capitlaism", "capitalism", - "capitlaist", "capitalist", - "capitlaize", "capitalized", - "capitolism", "capitalism", - "capitolist", "capitalist", - "capitolize", "capitalize", - "captainers", "captains", - "captialism", "capitalism", - "captialist", "capitalist", - "captialize", "capitalize", - "captivitiy", "captivity", - "caraciture", "caricature", - "carciature", "caricature", - "cardinales", "cardinals", - "cardinalis", "cardinals", - "carefullly", "carefully", - "cariacture", "caricature", - "caricatore", "caricature", - "cariciture", "caricature", - "caricuture", "caricature", - "carismatic", "charismatic", - "carribbean", "caribbean", - "cartdridge", "cartridge", - "cartdriges", "cartridges", - "carthagian", "carthaginian", - "cartilidge", "cartilage", - "cartirdges", "cartridges", - "cartrdiges", "cartridges", - "cartriages", "cartridges", - "cartrigdes", "cartridges", - "casaulties", "casualties", - "cassowarry", "cassowary", - "casualites", "casualties", - "casualries", "casualties", - "casulaties", "casualties", - "cataclysim", "cataclysm", - "cataclysym", "cataclysm", - "catagories", "categories", - "catapillar", "caterpillar", - "catapiller", "caterpillar", - "catastrope", "catastrophe", - "catastrphe", "catastrophe", - "categorice", "categorize", - "categoried", "categorized", - "categoriei", "categorize", - "cateogrize", "categorized", - "catepillar", "caterpillar", - "caterpilar", "caterpillar", - "catholicsm", "catholicism", - "catholicus", "catholics", - "catholisim", "catholicism", - "cativating", "activating", - "cattleship", "battleship", - "causalties", "casualties", - "cautionsly", "cautiously", - "celebratin", "celebration", - "celebrites", "celebrities", - "celebritiy", "celebrity", - "cellpading", "cellpadding", - "cellulaire", "cellular", - "cemetaries", "cemeteries", - "censorhsip", "censorship", - "censurship", "censorship", - "centipedle", "centipede", - "ceremonias", "ceremonies", - "ceremoniis", "ceremonies", - "ceremonije", "ceremonies", - "cerimonial", "ceremonial", - "cerimonies", "ceremonies", - "certainity", "certainty", - "certainlyt", "certainty", - "chairtable", "charitable", - "chalenging", "challenging", - "challanged", "challenged", - "challanges", "challenges", - "challegner", "challenger", - "challender", "challenger", - "challengue", "challenger", - "challengur", "challenger", - "challening", "challenging", - "challneger", "challenger", - "chanceller", "chancellor", - "chancillor", "chancellor", - "chansellor", "chancellor", - "charachter", "character", - "charactere", "characterize", - "characterz", "characterize", - "charactors", "characters", - "charakters", "characters", - "charatable", "charitable", - "charecters", "characters", - "charistics", "characteristics", - "charitible", "charitable", - "chartiable", "charitable", - "chechpoint", "checkpoint", - "checkpiont", "checkpoint", - "checkpoins", "checkpoints", - "checkponts", "checkpoints", - "cheesecase", "cheesecake", - "cheesecave", "cheesecake", - "cheeseface", "cheesecake", - "cheezecake", "cheesecake", - "chemcially", "chemically", - "chidlbirth", "childbirth", - "chihuahuha", "chihuahua", - "childbrith", "childbirth", - "childrends", "childrens", - "childrenis", "childrens", - "childrents", "childrens", - "chirstians", "christians", - "chocalates", "chocolates", - "chocloates", "chocolates", - "chocoaltes", "chocolates", - "chocolatie", "chocolates", - "chocolatos", "chocolates", - "chocolatte", "chocolates", - "chocolotes", "chocolates", - "cholestrol", "cholesterol", - "chormosome", "chromosome", - "chornicles", "chronicles", - "chrisitans", "christians", - "christains", "christians", - "christiaan", "christian", - "christimas", "christians", - "christinas", "christians", - "christines", "christians", - "christmans", "christians", - "chromasome", "chromosome", - "chromesome", "chromosome", - "chromisome", "chromosome", - "chromosmes", "chromosomes", - "chromosoms", "chromosomes", - "chromosone", "chromosome", - "chromosoom", "chromosome", - "chromozome", "chromosome", - "chronciles", "chronicles", - "chronicals", "chronicles", - "chronicels", "chronicles", - "chronocles", "chronicles", - "chronosome", "chromosome", - "chrsitians", "christians", - "cigarattes", "cigarettes", - "cigerattes", "cigarettes", - "cincinatti", "cincinnati", - "cinncinati", "cincinnati", - "circulaire", "circular", - "circulaton", "circulation", - "circumsice", "circumcised", - "circumsied", "circumcised", - "circumwent", "circumvent", - "circunvent", "circumvent", - "cirruculum", "curriculum", - "claculator", "calculator", - "clairfying", "clarifying", - "clasically", "classically", - "classicals", "classics", - "classrooom", "classroom", - "cleanliess", "cleanliness", - "cleareance", "clearance", - "cleverleys", "cleverly", - "cliffhager", "cliffhanger", - "climateers", "climates", - "climatiser", "climates", - "clincially", "clinically", - "clitoridis", "clitoris", - "clitorious", "clitoris", - "co-incided", "coincided", - "cockroachs", "cockroaches", - "cockroahes", "cockroaches", - "coefficent", "coefficient", - "cognatious", "contagious", - "cognitivie", "cognitive", - "coincidnce", "coincide", - "colelctive", "collective", - "colelctors", "collectors", - "collapsers", "collapses", - "collaquial", "colloquial", - "collasping", "collapsing", - "collataral", "collateral", - "collaterol", "collateral", - "collatoral", "collateral", - "collcetion", "collections", - "colleauges", "colleagues", - "colleciton", "collection", - "collectems", "collects", - "collectief", "collective", - "collecties", "collects", - "collectifs", "collects", - "collectivo", "collection", - "collectoin", "collections", - "collectons", "collections", - "collectros", "collects", - "collegaues", "colleagues", - "collequial", "colloquial", - "colleteral", "collateral", - "colliquial", "colloquial", - "collission", "collisions", - "collitions", "collisions", - "colloqiual", "colloquial", - "colloquail", "colloquial", - "colloqueal", "colloquial", - "collpasing", "collapsing", - "colonialsm", "colonialism", - "colorblend", "colorblind", - "coloublind", "colorblind", - "columbidae", "columbia", - "comapnions", "companions", - "comaprable", "comparable", - "comaprison", "comparison", - "comaptible", "compatible", - "combatabts", "combatants", - "combatents", "combatants", - "combinatin", "combinations", - "combinaton", "combination", - "comediants", "comedians", - "comepndium", "compendium", - "comferting", "comforting", - "comforming", "comforting", - "comfortbly", "comfortably", - "comisioned", "commissioned", - "comisioner", "commissioner", - "comissions", "commissions", - "commandbox", "commando", - "commandent", "commandment", - "commandeur", "commanders", - "commandore", "commanders", - "commandpod", "commando", - "commanists", "communists", - "commemters", "commenters", - "commencera", "commerce", - "commenciez", "commence", - "commentaar", "commentary", - "commentare", "commenter", - "commentars", "commenters", - "commentart", "commentator", - "commentery", "commentary", - "commentsry", "commenters", - "commercail", "commercials", - "commercent", "commence", - "commerical", "commercial", - "comminists", "communists", - "commisison", "commissions", - "commissons", "commissions", - "commiteted", "commited", - "commodites", "commodities", - "commtiment", "commitments", - "communicae", "communicated", - "communisim", "communism", - "communiste", "communities", - "communites", "communities", - "communters", "commenters", - "compadible", "compatible", - "compagnons", "companions", - "compainons", "companions", - "compairson", "comparison", - "compalined", "complained", - "compandium", "compendium", - "companians", "companions", - "companines", "companions", - "compansate", "compensate", - "comparabil", "comparable", - "comparason", "comparison", - "comparaste", "compares", - "comparatie", "comparative", - "compareble", "comparable", - "comparemos", "compares", - "comparions", "comparison", - "compariosn", "comparisons", - "comparisen", "compares", - "comparitve", "comparative", - "comparsion", "comparison", - "compartent", "compartment", - "compartmet", "compartment", - "compatibel", "compatible", - "compatibil", "compatible", - "compeating", "completing", - "compeditor", "competitor", - "compednium", "compendium", - "compeeting", "completing", - "compeltely", "completely", - "compelting", "completing", - "compeltion", "completion", - "compemdium", "compendium", - "compenduim", "compendium", - "compenents", "components", - "compenidum", "compendium", - "compensare", "compensate", - "comperable", "comparable", - "comperhend", "comprehend", - "compession", "compassion", - "competance", "competence", - "competator", "competitor", - "competenet", "competence", - "competense", "competence", - "competenze", "competence", - "competeted", "competed", - "competetor", "competitor", - "competidor", "competitor", - "competiors", "competitors", - "competitie", "competitive", - "competitin", "competitions", - "competitio", "competitor", - "competiton", "competition", - "competitve", "competitive", - "compilance", "compliance", - "compilaton", "compilation", - "compinsate", "compensate", - "compitable", "compatible", - "compitance", "compliance", - "complacant", "complacent", - "complaince", "compliance", - "complaines", "complaints", - "complainig", "complaining", - "complainte", "complained", - "complation", "completion", - "compleatly", "completely", - "complecate", "complicate", - "completeds", "completes", - "completent", "complement", - "completily", "complexity", - "completito", "completion", - "completley", "completely", - "complexers", "complexes", - "complexety", "complexity", - "complianed", "compliance", - "compliants", "complaints", - "complicaed", "complicate", - "complicare", "complicate", - "complicati", "complicit", - "complicato", "complication", - "complicite", "complicate", - "complicted", "complicated", - "complience", "compliance", - "complimate", "complicate", - "complition", "completion", - "complusion", "compulsion", - "complusive", "compulsive", - "complusory", "compulsory", - "compolsive", "compulsive", - "compolsory", "compulsory", - "compolsury", "compulsory", - "componants", "components", - "componenet", "components", - "componsate", "compensate", - "comporable", "comparable", - "compositae", "composite", - "compositie", "composite", - "compositon", "composition", - "compraison", "comparisons", - "compramise", "compromise", - "comprassem", "compress", - "comprehand", "comprehend", - "compresion", "compression", - "compresors", "compressor", - "compresser", "compressor", - "compressio", "compressor", - "compresson", "compression", - "comprihend", "comprehend", - "comprimise", "compromise", - "compromiss", "compromises", - "compromize", "compromise", - "compromsie", "compromises", - "comprossor", "compressor", - "compteting", "completing", - "comptetion", "completion", - "compulisve", "compulsive", - "compulosry", "compulsory", - "compulsary", "compulsory", - "compulsery", "compulsory", - "compulsing", "compulsion", - "compulsivo", "compulsion", - "compulsury", "compulsory", - "compuslion", "compulsion", - "compuslive", "compulsive", - "compuslory", "compulsory", - "compustion", "compulsion", - "computanti", "computation", - "conatiners", "containers", - "concedendo", "conceded", - "concedered", "conceded", - "conceitual", "conceptual", - "concentate", "concentrate", - "concenting", "connecting", - "conceptial", "conceptual", - "conceptuel", "conceptual", - "concersion", "concession", - "concesions", "concession", - "concidered", "considered", - "conciously", "consciously", - "concission", "concession", - "conclsuion", "concussion", - "conclusies", "conclusive", - "conclution", "conclusion", - "concorrent", "concurrent", - "concsience", "conscience", - "conculsion", "conclusion", - "conculsive", "conclusive", - "concurment", "concurrent", - "concurrant", "concurrent", - "concurrect", "concurrent", - "concusions", "concussion", - "concusison", "concussions", - "condamning", "condemning", - "condemming", "condemning", - "condencing", "condemning", - "condenming", "condemning", - "condensend", "condensed", - "condidtion", "condition", - "conditinal", "conditional", - "conditiner", "conditioner", - "conditiond", "conditioned", - "conditiong", "conditioning", - "condmening", "condemning", - "conduiting", "conducting", - "conencting", "connecting", - "conenction", "connection", - "conenctors", "connectors", - "conesencus", "consensus", - "confedarcy", "confederacy", - "confedence", "conference", - "confedercy", "confederacy", - "conferance", "conference", - "conferenze", "conference", - "conferming", "confirming", - "confernece", "conferences", - "confessino", "confessions", - "confidance", "confidence", - "confidenly", "confidently", - "confidense", "confidence", - "confidenty", "confidently", - "conflcting", "conflating", - "conflicing", "conflicting", - "conflictos", "conflicts", - "confliting", "conflating", - "confriming", "confirming", - "confussion", "confession", - "congratule", "congratulate", - "congresman", "congressman", - "congresmen", "congressmen", - "congressen", "congressmen", - "conjecutre", "conjecture", - "conjuction", "conjunction", - "conjuncion", "conjunction", - "conlcusion", "conclusion", - "conncetion", "connections", - "conneciton", "connection", - "connecties", "connects", - "connectins", "connects", - "connectivy", "connectivity", - "connectpro", "connector", - "conneticut", "connecticut", - "connotaion", "connotation", - "conpsiracy", "conspiracy", - "conqeuring", "conquering", - "conqouring", "conquering", - "conquerers", "conquerors", - "conquoring", "conquering", - "consciense", "conscience", - "consciouly", "consciously", - "consdiered", "considered", - "consending", "consenting", - "consensuel", "consensual", - "consenusal", "consensual", - "consequece", "consequence", - "consequnce", "consequence", - "conservare", "conserve", - "conservato", "conservation", - "conservice", "conserve", - "conservies", "conserve", - "conservite", "conserve", - "consicence", "conscience", - "consideras", "considers", - "consideret", "considerate", - "consipracy", "conspiracy", - "consistant", "consistent", - "consistens", "consists", - "consisteny", "consistency", - "consitency", "consistency", - "consituted", "constituted", - "conslutant", "consultant", - "consluting", "consulting", - "consolidad", "consolidated", - "consonents", "consonants", - "consorcium", "consortium", - "conspirace", "conspiracies", - "conspiricy", "conspiracy", - "conspriacy", "conspiracy", - "constaints", "constraints", - "constatnly", "constantly", - "constently", "constantly", - "constitude", "constitute", - "constitued", "constitute", - "constituem", "constitute", - "constituer", "constitute", - "constitues", "constitutes", - "constituie", "constitute", - "constituit", "constitute", - "constitutn", "constituents", - "constituye", "constitute", - "constnatly", "constantly", - "constracts", "constructs", - "constraits", "constraints", - "constransi", "constraints", - "constrants", "constraints", - "construced", "constructed", - "constructo", "construction", - "construint", "constraint", - "construits", "constructs", - "construted", "constructed", - "consueling", "consulting", - "consultata", "consultant", - "consultate", "consultant", - "consultati", "consultant", - "consultato", "consultation", - "consultent", "consultant", - "consumated", "consummated", - "consumbale", "consumables", - "consuments", "consumes", - "consumirem", "consumerism", - "consumires", "consumerism", - "consumirse", "consumerism", - "consumiste", "consumes", - "consumpion", "consumption", - "contaction", "contacting", - "contageous", "contagious", - "contagiosa", "contagious", - "contagioso", "contagious", - "contaigous", "contagious", - "containors", "containers", - "contaminen", "containment", - "contanting", "contacting", - "contection", "contention", - "contectual", "contextual", - "conteiners", "contenders", - "contempate", "contemplate", - "contemplat", "contempt", - "contempory", "contemporary", - "contenants", "continents", - "contencion", "contention", - "contendors", "contenders", - "contenents", "continents", - "conteneurs", "contenders", - "contengent", "contingent", - "contension", "contention", - "contentino", "contention", - "contentios", "contentious", - "contentous", "contentious", - "contestais", "contests", - "contestans", "contests", - "contestase", "contests", - "contestion", "contention", - "contestors", "contests", - "contextful", "contextual", - "contextuel", "contextual", - "contextura", "contextual", - "contianers", "containers", - "contianing", "containing", - "contibuted", "contributed", - "contibutes", "contributes", - "contigents", "continents", - "contigious", "contagious", - "contignent", "contingent", - "continants", "continents", - "continenal", "continental", - "continenet", "continents", - "contineous", "continuous", - "continetal", "continental", - "contingecy", "contingency", - "contingeny", "contingency", - "continient", "contingent", - "continious", "continuous", - "continiuty", "continuity", - "contintent", "contingent", - "continualy", "continually", - "continuare", "continue", - "continuati", "continuity", - "continuato", "continuation", - "continuent", "contingent", - "continuety", "continuity", - "continunes", "continents", - "continuons", "continuous", - "continutiy", "continuity", - "continuuum", "continuum", - "contitnent", "contingent", - "contiuning", "containing", - "contiunity", "continuity", - "contorller", "controllers", - "contracing", "contracting", - "contractar", "contractor", - "contracter", "contractor", - "contractin", "contraction", - "contractos", "contracts", - "contradice", "contradicted", - "contradics", "contradicts", - "contredict", "contradict", - "contribued", "contributed", - "contribuem", "contribute", - "contribuer", "contribute", - "contribues", "contributes", - "contribuie", "contribute", - "contribuit", "contribute", - "contributo", "contribution", - "contributs", "contributes", - "contribuye", "contribute", - "contricted", "contracted", - "contridict", "contradict", - "contriubte", "contributes", - "controlelr", "controllers", - "controlers", "controls", - "controling", "controlling", - "controlles", "controls", - "controvery", "controversy", - "controvesy", "controversy", - "contrubite", "contributes", - "contrubute", "contribute", - "contuining", "continuing", - "contuinity", "continuity", - "convaluted", "convoluted", - "convcition", "convictions", - "conveinent", "convenient", - "conveluted", "convoluted", - "convencion", "convention", - "conveniant", "convenient", - "conveniece", "convenience", - "convenince", "convenience", - "convential", "conventional", - "converesly", "conversely", - "convergens", "converse", - "converison", "conversions", - "converning", "converting", - "conversare", "converse", - "conversino", "conversions", - "conversley", "conversely", - "conversoin", "conversions", - "conversons", "conversions", - "convertion", "conversion", - "convertire", "converter", - "converying", "converting", - "conveyered", "conveyed", - "conviccion", "conviction", - "conviciton", "conviction", - "convienent", "convenient", - "conviluted", "convoluted", - "convincted", "convince", - "convinsing", "convincing", - "convinving", "convincing", - "convoluded", "convoluted", - "convoulted", "convoluted", - "convulated", "convoluted", - "convuluted", "convoluted", - "cooperatve", "cooperative", - "coordenate", "coordinate", - "coordiante", "coordinate", - "coordinare", "coordinate", - "coordinato", "coordination", - "coordinats", "coordinates", - "coordonate", "coordinate", - "cooridnate", "coordinate", - "copehnagen", "copenhagen", - "copenaghen", "copenhagen", - "copenahgen", "copenhagen", - "copengagen", "copenhagen", - "copengahen", "copenhagen", - "copenhagan", "copenhagen", - "copenhague", "copenhagen", - "copenhagun", "copenhagen", - "copenhaven", "copenhagen", - "copenhegan", "copenhagen", - "copyrighed", "copyrighted", - "copyrigted", "copyrighted", - "corinthans", "corinthians", - "corinthias", "corinthians", - "corinthins", "corinthians", - "cornmitted", "committed", - "corporatie", "corporate", - "corralated", "correlated", - "corralates", "correlates", - "correccion", "correction", - "correciton", "corrections", - "correcters", "correctors", - "correctess", "correctness", - "correctivo", "correction", - "correctons", "corrections", - "corregated", "correlated", - "correkting", "correcting", - "correlatas", "correlates", - "correlatie", "correlated", - "correlatos", "correlates", - "correspend", "correspond", - "corrilated", "correlated", - "corrilates", "correlates", - "corrispond", "correspond", - "corrolated", "correlated", - "corrolates", "correlates", - "corrospond", "correspond", - "corrpution", "corruption", - "corrulates", "correlates", - "corrupcion", "corruption", - "cosmeticas", "cosmetics", - "cosmeticos", "cosmetics", - "costumized", "customized", - "counceling", "counseling", - "councellor", "councillor", - "councelors", "counselors", - "councilers", "councils", - "counselers", "counselors", - "counsellng", "counselling", - "counsilers", "counselors", - "counsiling", "counseling", - "counsilors", "counselors", - "counsolers", "counselors", - "counsoling", "counseling", - "countepart", "counteract", - "counteratk", "counteract", - "counterbat", "counteract", - "countercat", "counteract", - "countercut", "counteract", - "counteries", "counters", - "countoring", "countering", - "countryies", "countryside", - "countrying", "countering", - "courcework", "coursework", - "coursefork", "coursework", - "courthosue", "courthouse", - "courtrooom", "courtroom", - "cousnelors", "counselors", - "coutneract", "counteract", - "coutnering", "countering", - "covenental", "covenant", - "cranberrry", "cranberry", - "creationis", "creations", - "creationsm", "creationism", - "creationst", "creationist", - "creativily", "creatively", - "creativley", "creatively", - "credibilty", "credibility", - "creeperest", "creepers", - "crimanally", "criminally", - "criminalty", "criminally", - "criminalul", "criminally", - "criticable", "critical", - "criticarlo", "critical", - "criticiing", "criticising", - "criticisim", "criticism", - "criticisme", "criticise", - "criticisng", "criticising", - "criticists", "critics", - "criticisze", "criticise", - "criticizms", "criticisms", - "criticizng", "criticizing", - "critisiced", "criticized", - "critisicms", "criticisms", - "critisicsm", "criticisms", - "critisiscm", "criticisms", - "critisisms", "criticisms", - "critisizes", "criticises", - "critisizms", "criticisms", - "critiziced", "criticized", - "critizised", "criticized", - "critizisms", "criticisms", - "critizized", "criticized", - "crocodille", "crocodile", - "crossfiter", "crossfire", - "crutchetts", "crutches", - "crystalens", "crystals", - "crystalisk", "crystals", - "crystallis", "crystals", - "cuatiously", "cautiously", - "culterally", "culturally", - "cultrually", "culturally", - "culumative", "cumulative", - "culutrally", "culturally", - "cumbersone", "cumbersome", - "cumbursome", "cumbersome", - "cumpolsory", "compulsory", - "cumulitive", "cumulative", - "currancies", "currencies", - "currenctly", "currency", - "currenices", "currencies", - "currentfps", "currents", - "currentlys", "currents", - "currentpos", "currents", - "currentusa", "currents", - "curriculem", "curriculum", - "curriculim", "curriculum", - "curriences", "currencies", - "curroption", "corruption", - "custimized", "customized", - "customzied", "customized", - "custumized", "customized", - "cutscences", "cutscene", - "cutscenses", "cutscene", - "dangerouly", "dangerously", - "dealerhsip", "dealerships", - "deathamtch", "deathmatch", - "deathmacth", "deathmatch", - "debateable", "debatable", - "decembeard", "december", - "decendants", "descendants", - "decendents", "descendants", - "decideable", "decidable", - "deciptions", "depictions", - "decisiones", "decisions", - "declarasen", "declares", - "declaraste", "declares", - "declaremos", "declares", - "decomposit", "decompose", - "decoracion", "decoration", - "decorativo", "decoration", - "decoritive", "decorative", - "decroative", "decorative", - "decsending", "descending", - "dedicacion", "dedication", - "dedikation", "dedication", - "deducatble", "deductible", - "deducitble", "deductible", - "defacation", "defamation", - "defamating", "defamation", - "defanitely", "definately", - "defelction", "deflection", - "defendeers", "defender", - "defendents", "defendants", - "defenderes", "defenders", - "defenesman", "defenseman", - "defenselss", "defenseless", - "defensivly", "defensively", - "defianetly", "definately", - "defiantely", "definately", - "defiantley", "definately", - "defibately", "definately", - "deficately", "definately", - "deficiancy", "deficiency", - "deficience", "deficiencies", - "deficienct", "deficient", - "deficienty", "deficiency", - "defiintely", "definately", - "definaetly", "definately", - "definaitly", "definately", - "definaltey", "definately", - "definataly", "definately", - "definateky", "definately", - "definately", "definitely", - "definatily", "definately", - "defination", "definition", - "definative", "definitive", - "definatlly", "definately", - "definatrly", "definately", - "definayely", "definately", - "defineatly", "definately", - "definetaly", "definately", - "definetely", "definitely", - "definetily", "definately", - "definetlly", "definetly", - "definettly", "definately", - "definicion", "definition", - "definietly", "definitely", - "definining", "defining", - "definitaly", "definately", - "definiteyl", "definitly", - "definitivo", "definition", - "definitley", "definitely", - "definitlly", "definitly", - "definitlry", "definitly", - "definitlty", "definitly", - "definjtely", "definately", - "definltely", "definately", - "definotely", "definately", - "definstely", "definately", - "defintaley", "definately", - "defintiely", "definitely", - "defintiion", "definitions", - "definutely", "definately", - "deflaction", "deflection", - "defleciton", "deflection", - "deflektion", "deflection", - "defniately", "definately", - "degenarate", "degenerate", - "degenerare", "degenerate", - "degenerite", "degenerate", - "degoratory", "derogatory", - "degraderad", "degraded", - "dehydraded", "dehydrated", - "dehyrdated", "dehydrated", - "deifnately", "definately", - "deisgnated", "designated", - "delaership", "dealership", - "delearship", "dealership", - "delegaties", "delegate", - "delegative", "delegate", - "delfection", "deflection", - "delibarate", "deliberate", - "deliberant", "deliberate", - "delibirate", "deliberate", - "deligthful", "delightful", - "deliverate", "deliberate", - "deliverees", "deliveries", - "deliviered", "delivered", - "deliviring", "delivering", - "delporable", "deplorable", - "delpoyment", "deployment", - "delutional", "delusional", - "dementieva", "dementia", - "deminsions", "dimensions", - "democracis", "democracies", - "democracts", "democrat", - "democratas", "democrats", - "democrates", "democrats", - "demograhic", "demographic", - "demographs", "demographics", - "demograpic", "demographic", - "demolation", "demolition", - "demolicion", "demolition", - "demolision", "demolition", - "demolitian", "demolition", - "demoliting", "demolition", - "demoloshed", "demolished", - "demolution", "demolition", - "demonished", "demolished", - "demonstate", "demonstrate", - "demonstras", "demonstrates", - "demorcracy", "democracy", - "denegerate", "degenerate", - "denominato", "denomination", - "denomintor", "denominator", - "deocrative", "decorative", - "deomcratic", "democratic", - "deparments", "departments", - "departmens", "departments", - "departmnet", "departments", - "depcitions", "depictions", - "depdending", "depending", - "depencency", "dependency", - "dependance", "dependence", - "dependancy", "dependency", - "dependandt", "dependant", - "dependends", "depended", - "dependened", "depended", - "dependenta", "dependant", - "dependente", "dependence", - "depicitons", "depictions", - "deplorabel", "deplorable", - "deplorabil", "deplorable", - "deplorible", "deplorable", - "deplyoment", "deployment", - "depolyment", "deployment", - "depositers", "deposits", - "depressief", "depressive", - "depressies", "depressive", - "deprivaton", "deprivation", - "deragotory", "derogatory", - "derivaties", "derivatives", - "deriviated", "derived", - "derivitave", "derivative", - "derivitive", "derivative", - "derogatary", "derogatory", - "derogatery", "derogatory", - "derogetory", "derogatory", - "derogitory", "derogatory", - "derogotary", "derogatory", - "derogotory", "derogatory", - "derviative", "derivative", - "descendats", "descendants", - "descendend", "descended", - "descenting", "descending", - "descerning", "descending", - "descipable", "despicable", - "descisions", "decisions", - "descriibes", "describes", - "descripton", "description", - "desginated", "designated", - "desigining", "designing", - "desireable", "desirable", - "desktopbsd", "desktops", - "despciable", "despicable", - "desperatly", "desperately", - "desperetly", "desperately", - "despicaple", "despicable", - "despicible", "despicable", - "dessicated", "desiccated", - "destinatin", "destinations", - "destinaton", "destination", - "destoryers", "destroyers", - "destorying", "destroying", - "destroyeds", "destroyers", - "destroyeer", "destroyers", - "destrucion", "destruction", - "destrucive", "destructive", - "destryoing", "destroying", - "detectarlo", "detector", - "detectaron", "detector", - "detectoare", "detector", - "determinas", "determines", - "determinig", "determining", - "determinsm", "determinism", - "deutschand", "deutschland", - "devastaded", "devastated", - "devastaing", "devastating", - "devastanti", "devastating", - "devasteted", "devastated", - "develepors", "developers", - "develoeprs", "developers", - "developmet", "developments", - "developors", "develops", - "developped", "developed", - "developres", "develops", - "develpment", "development", - "devestated", "devastated", - "devolvendo", "devolved", - "deyhdrated", "dehydrated", - "diagnosied", "diagnose", - "diagnosies", "diagnosis", - "diagnositc", "diagnostic", - "diagnossed", "diagnose", - "diagnosted", "diagnose", - "diagnotics", "diagnostic", - "diagonstic", "diagnostic", - "dichotomoy", "dichotomy", - "dicitonary", "dictionary", - "diconnects", "disconnects", - "dicovering", "discovering", - "dictateurs", "dictates", - "dictionare", "dictionaries", - "differance", "difference", - "differenly", "differently", - "differense", "differences", - "differente", "difference", - "differentl", "differential", - "differenty", "differently", - "differnece", "difference", - "difficulte", "difficulties", - "difficults", "difficulties", - "difficutly", "difficulty", - "diffuculty", "difficulty", - "diganostic", "diagnostic", - "dimensinal", "dimensional", - "dimentions", "dimensions", - "dimesnions", "dimensions", - "dimineshes", "diminishes", - "diminising", "diminishing", - "dimunitive", "diminutive", - "dinosaures", "dinosaurs", - "dinosaurus", "dinosaurs", - "dipections", "depictions", - "diplimatic", "diplomatic", - "diplomacia", "diplomatic", - "diplomancy", "diplomacy", - "dipolmatic", "diplomatic", - "directinla", "directional", - "directionl", "directional", - "directivos", "directions", - "directores", "directors", - "directorys", "directors", - "directsong", "directions", - "disaapoint", "disappoint", - "disagreeed", "disagreed", - "disapeared", "disappeared", - "disappeard", "disappeared", - "disappered", "disappeared", - "disappiont", "disappoint", - "disaproval", "disapproval", - "disastorus", "disastrous", - "disastrosa", "disastrous", - "disastrose", "disastrous", - "disastrosi", "disastrous", - "disastroso", "disastrous", - "disaterous", "disastrous", - "discalimer", "disclaimer", - "discapline", "discipline", - "discepline", "discipline", - "disception", "discretion", - "discharded", "discharged", - "disciplers", "disciples", - "disciplies", "disciplines", - "disciplins", "disciplines", - "disciprine", "discipline", - "disclamier", "disclaimer", - "discliamer", "disclaimer", - "disclipine", "discipline", - "disclousre", "disclosure", - "disclsoure", "disclosure", - "discograhy", "discography", - "discograpy", "discography", - "discolsure", "disclosure", - "disconenct", "disconnect", - "disconncet", "disconnects", - "disconnets", "disconnects", - "discontued", "discounted", - "discoruage", "discourages", - "discources", "discourse", - "discourgae", "discourages", - "discourges", "discourages", - "discoveres", "discovers", - "discoveryd", "discovered", - "discoverys", "discovers", - "discrecion", "discretion", - "discreddit", "discredited", - "discrepany", "discrepancy", - "discresion", "discretion", - "discreting", "discretion", - "discribing", "describing", - "discrimine", "discriminate", - "discrouage", "discourages", - "discrption", "discretion", - "discusison", "discussions", - "discusting", "discussing", - "disgracful", "disgraceful", - "disgrunted", "disgruntled", - "disgruntld", "disgruntled", - "disguisted", "disguise", - "disgustiny", "disgustingly", - "disgustosa", "disgusts", - "disgustose", "disgusts", - "disgustosi", "disgusts", - "disgustoso", "disgusts", - "dishcarged", "discharged", - "dishinored", "dishonored", - "disicpline", "discipline", - "disiplined", "disciplined", - "dislcaimer", "disclaimer", - "dismanteld", "dismantled", - "dismanting", "dismantling", - "dismentled", "dismantled", - "dispecable", "despicable", - "dispencary", "dispensary", - "dispencers", "dispenser", - "dispencing", "dispensing", - "dispensare", "dispenser", - "dispensory", "dispensary", - "dispesnary", "dispensary", - "dispicable", "despicable", - "displayfps", "displays", - "dispositon", "disposition", - "dispostion", "disposition", - "disputerad", "disputed", - "disrecpect", "disrespect", - "disrection", "discretion", - "disrepsect", "disrespect", - "disresepct", "disrespect", - "disrespekt", "disrespect", - "disription", "disruption", - "disrispect", "disrespect", - "disrputing", "disrupting", - "disruptivo", "disruption", - "disruptron", "disruption", - "dissapears", "disappears", - "dissappear", "disappear", - "disscusion", "discussion", - "dissmisive", "dismissive", - "dissodance", "dissonance", - "dissonante", "dissonance", - "dissonence", "dissonance", - "distastful", "distasteful", - "disticntly", "distinctly", - "distiction", "distinction", - "distincion", "distinction", - "distincive", "distinctive", - "distinclty", "distinctly", - "distinctie", "distinctive", - "distinctin", "distinctions", - "distingish", "distinguish", - "distingush", "distinguish", - "distintcly", "distinctly", - "distoriton", "distortion", - "distorsion", "distortion", - "distortian", "distortion", - "distortron", "distortion", - "distractes", "distracts", - "distractia", "district", - "distractin", "district", - "distractiv", "district", - "distration", "distortion", - "distribuem", "distribute", - "distribuer", "distribute", - "distribuie", "distribute", - "distribuit", "distribute", - "distributs", "distributors", - "distribuye", "distribute", - "distrotion", "distortion", - "distrubing", "disturbing", - "distrubtes", "distrust", - "distrubute", "distribute", - "distubring", "disturbing", - "disturbace", "disturbance", - "disturping", "disrupting", - "disucssing", "discussing", - "disucssion", "discussion", - "disurption", "disruption", - "ditributed", "distributed", - "diversifiy", "diversify", - "dividendes", "dividends", - "dividendos", "dividends", - "divideneds", "dividend", - "divinition", "divination", - "divinitory", "divinity", - "divisiones", "divisions", - "dobulelift", "doublelift", - "doccuments", "documents", - "documentry", "documentary", - "dogmatisch", "dogmatic", - "dolphinese", "dolphins", - "domianting", "dominating", - "domimation", "domination", - "dominacion", "domination", - "dominaters", "dominates", - "donwgraded", "downgraded", - "donwloaded", "downloaded", - "donwvoters", "downvoters", - "donwvoting", "downvoting", - "doomsdaily", "doomsday", - "doubellift", "doublelift", - "doubleiift", "doublelift", - "doubleleft", "doublelift", - "doublelfit", "doublelift", - "doublerift", "doublelift", - "doulbelift", "doublelift", - "downgarded", "downgraded", - "downgrated", "downgrade", - "downlaoded", "downloaded", - "downloadas", "downloads", - "downloades", "downloads", - "downovting", "downvoting", - "downroaded", "downgraded", - "downsiders", "downsides", - "downstaris", "downstairs", - "downstiars", "downstairs", - "downtokers", "downvoters", - "downtoking", "downvoting", - "downtraded", "downgraded", - "downviting", "downvoting", - "downvotear", "downvoters", - "downvoteas", "downvoters", - "downvoteds", "downvoters", - "downvotees", "downvoters", - "downvotesd", "downvoters", - "downvotess", "downvoters", - "downvotest", "downvoters", - "downvoteur", "downvoters", - "downvoties", "downvoters", - "downvotres", "downvoters", - "downvotted", "downvote", - "downvottes", "downvoters", - "downwoters", "downvoters", - "downwoting", "downvoting", - "drasticaly", "drastically", - "drasticlly", "drastically", - "draughtman", "draughtsman", - "dumbbellls", "dumbbells", - "dumbfouded", "dumbfounded", - "dumbfouned", "dumbfounded", - "dungeoness", "dungeons", - "dupilcates", "duplicates", - "duplicants", "duplicates", - "duplicatas", "duplicates", - "duplicitas", "duplicates", - "duplifaces", "duplicates", - "durabiltiy", "durability", - "dyamically", "dynamically", - "dynamicaly", "dynamically", - "dynamicdns", "dynamics", - "dynamiclly", "dynamically", - "dynamicpsf", "dynamics", - "dynamitage", "dynamite", - "dysfuncion", "dysfunction", - "earhtbound", "earthbound", - "earthqauke", "earthquake", - "earthquack", "earthquake", - "earthquaks", "earthquakes", - "earthquate", "earthquake", - "earthqukes", "earthquakes", - "easthetics", "aesthetics", - "ecoligical", "ecological", - "ecomonical", "economical", - "econimical", "economical", - "econimists", "economists", - "economicas", "economics", - "economicos", "economics", - "economicus", "economics", - "economisch", "economic", - "economisit", "economists", - "effeciency", "efficiency", - "effectivly", "effectively", - "efficeincy", "efficiency", - "efficently", "efficiently", - "efficiancy", "efficiency", - "efficienct", "efficient", - "efficienty", "efficiently", - "egotistcal", "egotistical", - "ehtnically", "ethnically", - "ejaculaion", "ejaculation", - "ejaculatie", "ejaculate", - "ejaculatin", "ejaculation", - "ejaculaton", "ejaculation", - "ejaculatte", "ejaculate", - "electircal", "electrical", - "electivite", "elective", - "electoraat", "electorate", - "electorale", "electorate", - "electorite", "electorate", - "electornic", "electronic", - "electrican", "electrician", - "electriciy", "electricity", - "electricty", "electricity", - "electrinic", "electrician", - "electroate", "electorate", - "electrodan", "electron", - "electroinc", "electron", - "electrolye", "electrolytes", - "electroman", "electron", - "electroncs", "electrons", - "electrones", "electrons", - "electronik", "election", - "electronis", "electronics", - "electronix", "election", - "elemantary", "elementary", - "elementery", "elementary", - "elementray", "elementary", - "eleminated", "eliminated", - "elephantes", "elephants", - "elephantis", "elephants", - "elephantos", "elephants", - "elephantus", "elephants", - "eletricity", "electricity", - "elimanates", "eliminates", - "elimenates", "eliminates", - "elimentary", "elementary", - "elimimates", "eliminates", - "eliminaste", "eliminates", - "eliminatin", "elimination", - "eliminaton", "elimination", - "eliminster", "eliminates", - "ellipitcal", "elliptical", - "ellipsical", "elliptical", - "ellipticle", "elliptical", - "ellitpical", "elliptical", - "ellpitical", "elliptical", - "eloquantly", "eloquently", - "eloquintly", "eloquently", - "emapthetic", "empathetic", - "embarassed", "embarrassed", - "embarassig", "embarassing", - "embarrased", "embarrassed", - "embarrases", "embarrassed", - "embezelled", "embezzled", - "emblamatic", "emblematic", - "embodyment", "embodiment", - "emergenies", "emergencies", - "emmigrated", "emigrated", - "emminently", "eminently", - "emmisaries", "emissaries", - "emobdiment", "embodiment", - "emotionaly", "emotionally", - "empahsized", "emphasized", - "empahsizes", "emphasizes", - "empathatic", "empathetic", - "emphacized", "emphasized", - "emphatetic", "empathetic", - "emphatised", "emphasized", - "emphatized", "emphasized", - "emphatizes", "emphasizes", - "emphazised", "emphasized", - "emphazises", "emphasizes", - "emphesized", "emphasized", - "emphesizes", "emphasizes", - "emphisized", "emphasized", - "emphisizes", "emphasizes", - "empiricaly", "empirically", - "employeers", "employees", - "employeurs", "employer", - "emprisoned", "imprisoned", - "encahnting", "enchanting", - "enchancing", "enchanting", - "enchanging", "enchanting", - "enchantent", "enchantment", - "enchantmet", "enchantments", - "encompases", "encompasses", - "encounterd", "encountered", - "encountred", "encountered", - "encouraing", "encouraging", - "encoutners", "encounters", - "encription", "encryption", - "encrpytion", "encryption", - "encyrption", "encryption", - "endlessley", "endlessly", - "endolithes", "endoliths", - "enforceing", "enforcing", - "engagemnet", "engagements", - "engagemnts", "engagements", - "engieneers", "engineers", - "enginereed", "engineered", - "enivitable", "inevitable", - "enlargment", "enlargement", - "enlighment", "enlighten", - "enlightend", "enlightened", - "enlightned", "enlightened", - "enrolement", "enrollment", - "enrollemnt", "enrollment", - "enterpirse", "enterprise", - "enterprice", "enterprise", - "enterpries", "enterprises", - "enterprize", "enterprise", - "enterprsie", "enterprises", - "enterrpise", "enterprises", - "entertaing", "entertaining", - "enthically", "ethnically", - "enthisiast", "enthusiast", - "enthuiasts", "enthusiast", - "enthuisast", "enthusiasts", - "enthusiams", "enthusiasm", - "enthusiant", "enthusiast", - "enthusiats", "enthusiast", - "enthusiest", "enthusiast", - "enthusists", "enthusiasts", - "envelopped", "envelope", - "enveloppen", "envelope", - "enveloppes", "envelope", - "enviorment", "environment", - "enviroment", "environment", - "environmet", "environments", - "equiavlent", "equivalents", - "equilavent", "equivalent", - "equilibium", "equilibrium", - "equilibrim", "equilibrium", - "equilibrum", "equilibrium", - "equippment", "equipment", - "equitorial", "equatorial", - "equivalant", "equivalent", - "equivalnce", "equivalence", - "equivalnet", "equivalents", - "equivelant", "equivalent", - "equivelent", "equivalent", - "equivilant", "equivalent", - "equivilent", "equivalent", - "equivlaent", "equivalents", - "equivolent", "equivalent", - "eratically", "erratically", - "escalative", "escalate", - "escavation", "escalation", - "esitmation", "estimation", - "esoterisch", "esoteric", - "especailly", "especially", - "espeically", "especially", - "espressino", "espresso", - "espression", "espresso", - "essencials", "essentials", - "essensials", "essentials", - "essentails", "essentials", - "essentialy", "essentially", - "essentiels", "essentials", - "essentuals", "essentials", - "estabishes", "establishes", - "estimacion", "estimation", - "estimativo", "estimation", - "estination", "estimation", - "ethicallly", "ethically", - "ethincally", "ethnically", - "ethnicites", "ethnicities", - "ethnicitiy", "ethnicity", - "euphorical", "euphoria", - "euphorisch", "euphoric", - "euthanaisa", "euthanasia", - "euthanazia", "euthanasia", - "euthanesia", "euthanasia", - "evaluacion", "evaluation", - "evalutaion", "evaluation", - "evaulating", "evaluating", - "evaulation", "evaluation", - "eventaully", "eventually", - "eventially", "eventually", - "everyoneis", "everyones", - "exacberate", "exacerbated", - "exagerated", "exaggerated", - "exagerates", "exaggerates", - "exagerrate", "exaggerate", - "exaggarate", "exaggerate", - "exaggurate", "exaggerate", - "exahusting", "exhausting", - "exahustion", "exhaustion", - "examinated", "examined", - "examinerad", "examined", - "exapansion", "expansion", - "exapnsions", "expansions", - "exauhsting", "exhausting", - "exauhstion", "exhaustion", - "excecuting", "executing", - "excecution", "execution", - "exceedigly", "exceedingly", - "exceedinly", "exceedingly", - "excellance", "excellence", - "excellenet", "excellence", - "excellenze", "excellence", - "excerising", "exercising", - "excessivly", "excessively", - "exchangees", "exchanges", - "excitiment", "excitement", - "exclsuives", "exclusives", - "exclusivas", "exclusives", - "exclusivly", "exclusively", - "exclusivos", "exclusives", - "exclusivty", "exclusivity", - "exclussive", "exclusives", - "exclusvies", "exclusives", - "excpetions", "exceptions", - "exculsives", "exclusives", - "exculsivly", "exclusively", - "execptions", "exceptions", - "exectuable", "executable", - "exectuions", "executions", - "exectuives", "executives", - "execusions", "executions", - "executabil", "executable", - "executible", "executable", - "executiner", "executioner", - "executings", "executions", - "executivas", "executives", - "exeedingly", "exceedingly", - "exepmtions", "exemptions", - "exeptional", "exceptional", - "exercicing", "exercising", - "exercizing", "exercising", - "exersicing", "exercising", - "exersising", "exercising", - "exersizing", "exercising", - "exerternal", "external", - "exeuctions", "executions", - "exhasuting", "exhausting", - "exhasution", "exhaustion", - "exhaustivo", "exhaustion", - "exhibicion", "exhibition", - "exhibitons", "exhibits", - "exhuasting", "exhausting", - "exhuastion", "exhaustion", - "exibitions", "exhibitions", - "exictement", "excitement", - "exipration", "expiration", - "existantes", "existent", - "existenial", "existential", - "existental", "existential", - "exlcusives", "exclusives", - "exorbatant", "exorbitant", - "exorbatent", "exorbitant", - "exorbidant", "exorbitant", - "exorbirant", "exorbitant", - "exorbitent", "exorbitant", - "expalining", "explaining", - "expanisons", "expansions", - "expansivos", "expansions", - "expanssion", "expansions", - "expantions", "expansions", - "expecially", "especially", - "expectaion", "expectation", - "expectansy", "expectancy", - "expectency", "expectancy", - "expections", "exceptions", - "expedetion", "expedition", - "expedicion", "expedition", - "expeditivo", "expedition", - "expeiments", "experiments", - "expemtions", "exemptions", - "expendeble", "expendable", - "expendible", "expendable", - "expensable", "expendable", - "expentancy", "expectancy", - "expereince", "experience", - "experement", "experiment", - "experiance", "experience", - "experieced", "experienced", - "experieces", "experiences", - "experiemnt", "experiment", - "experiened", "experienced", - "experiense", "experiences", - "expermient", "experiments", - "experssion", "expression", - "expextancy", "expectancy", - "expidetion", "expedition", - "expierence", "experience", - "expination", "expiration", - "expirement", "experiment", - "explanatin", "explanations", - "explicatia", "explicit", - "explicatie", "explicit", - "explicatif", "explicit", - "explicatii", "explicit", - "explicetly", "explicitly", - "explicilty", "explicitly", - "explioting", "exploiting", - "exploiding", "exploiting", - "exploition", "exploiting", - "explorarea", "explorer", - "exploreres", "explorers", - "explosivas", "explosives", - "explossion", "explosions", - "explossive", "explosives", - "explosvies", "explosives", - "explotions", "explosions", - "explusions", "explosions", - "expodition", "exposition", - "expoliting", "exploiting", - "expolsions", "explosions", - "expolsives", "explosives", - "exponental", "exponential", - "exposicion", "exposition", - "expositivo", "exposition", - "expotition", "exposition", - "exprensive", "expressive", - "expresions", "expression", - "expresison", "expressions", - "expressens", "expresses", - "expressief", "expressive", - "expressley", "expressly", - "expriation", "expiration", - "extensivly", "extensively", - "extentions", "extensions", - "exterioara", "exterior", - "exterioare", "exterior", - "extermally", "externally", - "extermists", "extremists", - "extraccion", "extraction", - "extractivo", "extraction", - "extractnow", "extraction", - "extradtion", "extraction", - "extremaste", "extremes", - "extremeley", "extremely", - "extremelly", "extremely", - "extrememly", "extremely", - "extremests", "extremists", - "extremised", "extremes", - "extremisim", "extremism", - "extremisme", "extremes", - "extremiste", "extremes", - "extrenally", "externally", - "extrimists", "extremists", - "eyeballers", "eyeballs", - "fabriacted", "fabricated", - "fabricatie", "fabricated", - "faciliated", "facilitated", - "facilitait", "facilitate", - "facilitant", "facilitate", - "facilitare", "facilitate", - "facisnated", "fascinated", - "facitilies", "facilities", - "facsinated", "fascinated", - "fahernheit", "fahrenheit", - "fahrenhiet", "fahrenheit", - "fallatious", "fallacious", - "fallicious", "fallacious", - "falshbacks", "flashbacks", - "familiarty", "familiarity", - "familiarze", "familiarize", - "fanaticals", "fanatics", - "fanfaction", "fanfiction", - "fanfcition", "fanfiction", - "fanficiton", "fanfiction", - "fanserivce", "fanservice", - "fanservise", "fanservice", - "fanservive", "fanservice", - "fantasiose", "fantasies", - "farehnheit", "fahrenheit", - "farhenheit", "fahrenheit", - "fascianted", "fascinated", - "fascinatie", "fascinated", - "fascinatin", "fascination", - "fascistisk", "fascists", - "fatalaties", "fatalities", - "favoruites", "favourites", - "favourates", "favourites", - "favouritsm", "favourites", - "favourties", "favourites", - "federacion", "federation", - "federativo", "federation", - "fellowhsip", "fellowship", - "fellowshop", "fellowship", - "feminimity", "femininity", - "feministas", "feminists", - "feminitity", "femininity", - "fermentato", "fermentation", - "fertalizer", "fertilizer", - "fertelizer", "fertilizer", - "fertilizar", "fertilizer", - "fertilzier", "fertilizer", - "fertiziler", "fertilizer", - "festivales", "festivals", - "fetishiste", "fetishes", - "ficticious", "fictitious", - "filessytem", "filesystem", - "filesytems", "filesystem", - "filmamkers", "filmmakers", - "filmmakare", "filmmakers", - "finallizes", "finalizes", - "financialy", "financially", - "fingernals", "fingernails", - "fingerpies", "fingertips", - "fingerpint", "fingerprint", - "fingertaps", "fingertips", - "fingertits", "fingertips", - "fingertops", "fingertips", - "fireballls", "fireballs", - "firefigher", "firefighter", - "firefigter", "firefighter", - "firendlies", "friendlies", - "firghtened", "frightened", - "fisionable", "fissionable", - "flashligth", "flashlight", - "flaskbacks", "flashbacks", - "flawleslly", "flawlessly", - "flexibiliy", "flexibility", - "flexibilty", "flexibility", - "flimmakers", "filmmakers", - "fluctuatie", "fluctuate", - "fluctuatin", "fluctuations", - "flutterhsy", "fluttershy", - "fluttersky", "fluttershy", - "flutterspy", "fluttershy", - "forcifully", "forcefully", - "forecfully", "forcefully", - "foreginers", "foreigners", - "foregorund", "foreground", - "foreignese", "foreigners", - "foreigness", "foreigners", - "foreignors", "foreigners", - "foreingers", "foreigners", - "forensisch", "forensic", - "foreseeble", "foreseeable", - "forgeiners", "foreigners", - "forgieners", "foreigners", - "forgivance", "forgiven", - "forgivenss", "forgiveness", - "forgotting", "forgetting", - "foriegners", "foreigners", - "formadible", "formidable", - "formalhaut", "fomalhaut", - "formallity", "formally", - "formallize", "formalize", - "formatiing", "formatting", - "formatings", "formations", - "formativos", "formations", - "formidabel", "formidable", - "formidabil", "formidable", - "formidible", "formidable", - "forminable", "formidable", - "formitable", "formidable", - "formuladas", "formulas", - "formulados", "formulas", - "forseeable", "foreseeable", - "fortelling", "foretelling", - "fortunatly", "fortunately", - "fortunetly", "fortunately", - "foundaiton", "foundations", - "foundaries", "foundries", - "foundatoin", "foundations", - "fractalers", "fractals", - "fractalius", "fractals", - "fractalpus", "fractals", - "fracturare", "fracture", - "fragmanted", "fragment", - "francaises", "franchises", - "franchices", "franchises", - "franchines", "franchises", - "franchizes", "franchises", - "franchsies", "franchises", - "fransiscan", "franciscan", - "franticaly", "frantically", - "franticlly", "frantically", - "fraternaty", "fraternity", - "fraternety", "fraternity", - "fraterntiy", "fraternity", - "fraturnity", "fraternity", - "fraudalent", "fraudulent", - "fraudelant", "fraudulent", - "fraudelent", "fraudulent", - "fraudolent", "fraudulent", - "fraudulant", "fraudulent", - "freedomers", "freedoms", - "freedomest", "freedoms", - "freindlies", "friendlies", - "freindship", "friendship", - "frequencey", "frequency", - "friednship", "friendships", - "friednzone", "friendzoned", - "friendhsip", "friendship", - "friendsies", "friendlies", - "friendzies", "friendlies", - "friendzond", "friendzoned", - "frientship", "friendship", - "frigthened", "frightened", - "fromatting", "formatting", - "fromidable", "formidable", - "frontlinie", "frontline", - "fruadulent", "fraudulent", - "frustraded", "frustrated", - "frustradet", "frustrates", - "frustraits", "frustrates", - "frustrants", "frustrates", - "frustratin", "frustration", - "frustrsted", "frustrates", - "fucntional", "functional", - "fulfulling", "fulfilling", - "fullfiling", "fulfilling", - "fullfilled", "fulfilled", - "fullscrean", "fullscreen", - "fulttershy", "fluttershy", - "funcitonal", "functional", - "fundametal", "fundamental", - "furstrated", "frustrated", - "furstrates", "frustrates", - "furutistic", "futuristic", - "futhermore", "furthermore", - "futurestic", "futuristic", - "futurisitc", "futuristic", - "futurustic", "futuristic", - "galvinized", "galvanized", - "garuanteed", "guaranteed", - "garuantees", "guarantees", - "gauntanamo", "guantanamo", - "gauntlents", "gauntlet", - "gauranteed", "guaranteed", - "gaurantees", "guarantees", - "gaurenteed", "guaranteed", - "gaurentees", "guarantees", - "generalice", "generalize", - "generalife", "generalize", - "generalnie", "generalize", - "generaters", "generates", - "generaties", "generate", - "generatios", "generators", - "generatons", "generators", - "generatore", "generate", - "generelize", "generalize", - "generocity", "generosity", - "generoisty", "generosity", - "generostiy", "generosity", - "geneticaly", "genetically", - "geneticlly", "genetically", - "genitalias", "genitals", - "genuinelly", "genuinely", - "geographia", "geographical", - "geogrpahic", "geographic", - "germanisch", "germanic", - "gigantisch", "gigantic", - "gimmickers", "gimmicks", - "girlfirend", "girlfriend", - "girlfreind", "girlfriend", - "girlfriens", "girlfriends", - "girlfrinds", "girlfriends", - "girlfrined", "girlfriends", - "goalkeaper", "goalkeeper", - "goalkeeprs", "goalkeeper", - "goalkepeer", "goalkeeper", - "goegraphic", "geographic", - "golakeeper", "goalkeeper", - "goldburger", "goldberg", - "goosebumbs", "goosebumps", - "goosegumps", "goosebumps", - "goosepumps", "goosebumps", - "gothenberg", "gothenburg", - "govenrment", "government", - "govermenet", "goverment", - "govermnent", "governments", - "governemnt", "government", - "governened", "governed", - "governered", "governed", - "governmant", "governmental", - "governmetn", "governments", - "governmnet", "government", - "govnerment", "government", - "govornment", "government", - "gradiating", "graduating", - "gradiation", "graduation", - "graduacion", "graduation", - "grapefriut", "grapefruit", - "grapefrukt", "grapefruit", - "graphicaly", "graphically", - "graphiclly", "graphically", - "gratituous", "gratuitous", - "gratiutous", "gratuitous", - "gratuidous", "gratuitous", - "gratuituos", "gratuitous", - "gratutious", "gratuitous", - "graudating", "graduating", - "graudation", "graduation", - "gravitatie", "gravitate", - "greatfully", "gratefully", - "greenhosue", "greenhouse", - "greviances", "grievances", - "grievences", "grievances", - "grilfriend", "girlfriend", - "guaduloupe", "guadalupe", - "guanatanmo", "guantanamo", - "guantamamo", "guantanamo", - "guantamano", "guantanamo", - "guantanano", "guantanamo", - "guantanemo", "guantanamo", - "guantanoma", "guantanamo", - "guantanomo", "guantanamo", - "guantonamo", "guantanamo", - "guarantess", "guarantees", - "guardiands", "guardians", - "guardianes", "guardians", - "guardianis", "guardians", - "guarenteed", "guaranteed", - "guarentees", "guarantees", - "guarnateed", "guaranteed", - "guarnatees", "guarantees", - "guarunteed", "guaranteed", - "guaruntees", "guarantees", - "guatamalan", "guatemalan", - "gunatanamo", "guantanamo", - "gunlsinger", "gunslinger", - "gunsiinger", "gunslinger", - "gunslanger", "gunslinger", - "gunsligner", "gunslinger", - "gunstinger", "gunslinger", - "gymanstics", "gymnastics", - "gymnasitcs", "gymnastics", - "gynmastics", "gymnastics", - "haemorrage", "haemorrhage", - "halloweeen", "halloween", - "hambergers", "hamburgers", - "hamburgare", "hamburger", - "hamburgesa", "hamburgers", - "hamburgles", "hamburgers", - "hamburgurs", "hamburgers", - "handcuffes", "handcuffs", - "handelbars", "handlebars", - "handicaped", "handicapped", - "handwritng", "handwriting", - "harasments", "harassments", - "hardlinked", "hardline", - "harmoniacs", "harmonic", - "harmonisch", "harmonic", - "harrasment", "harassment", - "harrassing", "harassing", - "harvasting", "harvesting", - "haversting", "harvesting", - "headhpones", "headphones", - "headphoens", "headphones", - "headquarer", "headquarter", - "headquater", "headquarter", - "headshoots", "headshot", - "healtchare", "healthcare", - "healtheast", "healthiest", - "healthyest", "healthiest", - "heapdhones", "headphones", - "heartbeart", "heartbeat", - "heartbeast", "heartbeat", - "heartborne", "heartbroken", - "heartbrake", "heartbreak", - "hearthsone", "hearthstone", - "heatlhcare", "healthcare", - "heavyweght", "heavyweight", - "heavyweigt", "heavyweight", - "hedgehodge", "hedgehog", - "heidelburg", "heidelberg", - "heigthened", "heightened", - "heistation", "hesitation", - "helathcare", "healthcare", - "helicopers", "helicopters", - "helicoptor", "helicopter", - "helicotper", "helicopters", - "helicpoter", "helicopter", - "helictoper", "helicopters", - "helikopter", "helicopter", - "hemingwary", "hemingway", - "hemingwavy", "hemingway", - "hemipshere", "hemisphere", - "hemishpere", "hemisphere", - "hemmorhage", "hemorrhage", - "hempishere", "hemisphere", - "herculeans", "hercules", - "herculeasy", "hercules", - "herculeees", "hercules", - "hesitstion", "hesitation", - "hestiation", "hesitation", - "hieghtened", "heightened", - "hierachies", "hierarchies", - "hieroglphs", "hieroglyphs", - "highalnder", "highlander", - "highlighed", "highlighted", - "highligted", "highlighted", - "highloader", "highlander", - "highpander", "highlander", - "highscholl", "highschool", - "highshcool", "highschool", - "hillarious", "hilarious", - "hinderance", "hindrance", - "hinderence", "hindrance", - "hipsterest", "hipsters", - "hispanicos", "hispanics", - "hispanicus", "hispanics", - "histarical", "historical", - "histerical", "historical", - "historiaan", "historians", - "historicas", "historians", - "historicly", "historical", - "historiens", "histories", - "historisch", "historic", - "hoemopathy", "homeopathy", - "hollywoood", "hollywood", - "homecuming", "homecoming", - "homeoapthy", "homeopathy", - "homeonwers", "homeowners", - "homeopahty", "homeopathy", - "homeophaty", "homeopathy", - "homeopothy", "homeopathy", - "homeothapy", "homeopathy", - "homepoathy", "homeopathy", - "homewoners", "homeowners", - "homoepathy", "homeopathy", - "homogeneos", "homogeneous", - "homogeneus", "homogeneous", - "homophibia", "homophobia", - "homophibic", "homophobic", - "homophobie", "homophobe", - "homophonia", "homophobia", - "homophopia", "homophobia", - "homophopic", "homophobic", - "homosexaul", "homosexual", - "homosexuel", "homosexual", - "honeymooon", "honeymoon", - "hopefullly", "hopefully", - "hopeleslly", "hopelessly", - "horisontal", "horizontal", - "horizantal", "horizontal", - "horizontes", "horizons", - "horiztonal", "horizontal", - "horrendeus", "horrendous", - "horriblely", "horribly", - "hospitales", "hospitals", - "hospitalty", "hospitality", - "hospitible", "hospitable", - "hsitorians", "historians", - "humanaties", "humanities", - "humanitary", "humanity", - "humiliatin", "humiliation", - "humiliaton", "humiliation", - "humilitied", "humiliated", - "humillated", "humiliated", - "hurricance", "hurricane", - "hurriganes", "hurricanes", - "hurrikanes", "hurricanes", - "hurrycanes", "hurricanes", - "hydropilic", "hydrophilic", - "hydropobic", "hydrophobic", - "hyperbolie", "hyperbole", - "hyperlobic", "hyperbolic", - "hyperlogic", "hyperbolic", - "hypertrohy", "hypertrophy", - "hypertropy", "hypertrophy", - "hyphotesis", "hypothesis", - "hypocrates", "hypocrites", - "hypocriscy", "hypocrisy", - "hypocrises", "hypocrites", - "hypocritus", "hypocrites", - "hypocrties", "hypocrites", - "hypocrytes", "hypocrites", - "hypokrites", "hypocrites", - "hypothecis", "hypothesis", - "hypotheiss", "hypotheses", - "hypothesus", "hypotheses", - "hypothises", "hypotheses", - "hypothisis", "hypothesis", - "hypothosis", "hypothesis", - "hyprocites", "hypocrites", - "hystarical", "hysterical", - "hystericly", "hysterical", - "hysteriska", "hysteria", - "ibuprofein", "ibuprofen", - "ibuprofine", "ibuprofen", - "icelandinc", "icelandic", - "idealisitc", "idealistic", - "idealogies", "ideologies", - "identicial", "identical", - "identifyed", "identified", - "identitets", "identities", - "ideolagies", "ideologies", - "ideoligies", "ideologies", - "ideologias", "ideologies", - "ideologice", "ideologies", - "ideologije", "ideologies", - "ideologins", "ideologies", - "ideologisk", "ideologies", - "ideolouges", "ideologies", - "illegalest", "illegals", - "illegallly", "illegally", - "illegimacy", "illegitimacy", - "illegitime", "illegitimate", - "illegitimt", "illegitimate", - "illimunati", "illuminati", - "illinoians", "illinois", - "illistrate", "illiterate", - "illitarate", "illiterate", - "illitirate", "illiterate", - "illumanati", "illuminati", - "illumaniti", "illuminati", - "illumianti", "illuminati", - "illumimati", "illuminati", - "illuminaci", "illuminati", - "illuminadi", "illuminati", - "illuminami", "illuminati", - "illuminazi", "illuminati", - "illuminite", "illuminati", - "illuminiti", "illuminati", - "illuminoti", "illuminati", - "illuminuti", "illuminati", - "illumniati", "illuminati", - "illumunati", "illuminati", - "illuninati", "illuminati", - "illusiones", "illusions", - "illustrant", "illustrate", - "illustrare", "illustrate", - "illustrato", "illustration", - "imablanced", "imbalanced", - "imablances", "imbalances", - "imaginatie", "imaginative", - "imaginaton", "imagination", - "imaginitve", "imaginative", - "imbalenced", "imbalanced", - "imbalences", "imbalances", - "imcomplete", "incomplete", - "imediately", "immediately", - "imigration", "emigration", - "immaturaty", "immaturity", - "immaturety", "immaturity", - "immedeatly", "immediately", - "immediatly", "immediately", - "immedietly", "immediately", - "immenseley", "immensely", - "immidately", "immediately", - "immigranti", "immigration", - "immigrents", "immigrants", - "immitating", "imitating", - "immobilien", "immobile", - "immobilier", "immobile", - "immobilzed", "immobile", - "immobilzer", "immobile", - "immobilzes", "immobile", - "immortales", "immortals", - "immortalis", "immortals", - "immortaliy", "immortality", - "immortalls", "immortals", - "immortalty", "immortality", - "impartirla", "impartial", - "impecabbly", "impeccably", - "impeccible", "impeccable", - "impeckable", "impeccable", - "impelments", "implements", - "imperetive", "imperative", - "imperialsm", "imperialism", - "imperialst", "imperialist", - "imperitave", "imperative", - "imperitive", "imperative", - "implaments", "implements", - "implantase", "implants", - "implausble", "implausible", - "implausibe", "implausible", - "implemenet", "implements", - "implicatia", "implicit", - "implicatie", "implicit", - "implicatii", "implicit", - "implicetly", "implicitly", - "impliciete", "implicit", - "implicilty", "implicitly", - "impliments", "implements", - "imporbable", "improbable", - "importanly", "importantly", - "importanty", "importantly", - "importence", "importance", - "importerad", "imported", - "imporvised", "improvised", - "impossable", "impossible", - "impossbily", "impossibly", - "impossibal", "impossibly", - "impossibel", "impossibly", - "impossibry", "impossibly", - "impossibul", "impossibly", - "impractial", "impractical", - "impreative", "imperative", - "impresison", "impressions", - "impressoin", "impressions", - "impressons", "impressions", - "improbabil", "improbable", - "improbible", "improbable", - "impropable", "improbable", - "improsined", "imprisoned", - "improsoned", "imprisoned", - "improvemnt", "improvement", - "improvents", "improves", - "improvized", "improvised", - "imprsioned", "imprisoned", - "impulsemos", "impulses", - "imrpovised", "improvised", - "inablility", "inability", - "inaccruate", "inaccurate", - "inadaquate", "inadequate", - "inadaquete", "inadequate", - "inadecuate", "inadequate", - "inadeguate", "inadequate", - "inadeqaute", "inadequate", - "inadequete", "inadequate", - "inadequite", "inadequate", - "inadiquate", "inadequate", - "inagurated", "inaugurated", - "inbalanced", "imbalanced", - "inbetweeen", "inbetween", - "incarnaton", "incarnation", - "incentivos", "incentives", - "inchoerent", "incoherent", - "incidentes", "incidents", - "incidently", "incidentally", - "incidentul", "incidental", - "inclreased", "increased", - "incognitio", "incognito", - "incoherant", "incoherent", - "incohorent", "incoherent", - "incorectly", "incorrectly", - "incorrecly", "incorrectly", - "incorrecty", "incorrectly", - "incorretly", "incorrectly", - "incraments", "increments", - "incredable", "incredible", - "incredably", "incredibly", - "incremetal", "incremental", - "incriments", "increments", - "inctroduce", "introduce", - "indefenite", "indefinite", - "indefinate", "indefinite", - "indefinete", "indefinite", - "indefinity", "indefinitely", - "indeginous", "indigenous", - "indentical", "identical", - "independet", "independent", - "indepenent", "independent", - "inderictly", "indirectly", - "indicaters", "indicates", - "indicativo", "indication", - "indicatore", "indicate", - "indicitave", "indicative", - "indicitive", "indicative", - "indiffernt", "indifferent", - "indigenius", "indigenous", - "indiginous", "indigenous", - "indigneous", "indigenous", - "indikation", "indication", - "indireclty", "indirectly", - "indirektly", "indirectly", - "individuel", "individual", - "indiviudal", "individuals", - "indivudual", "individual", - "indoensian", "indonesian", - "indonasian", "indonesian", - "indoneisan", "indonesian", - "indonesean", "indonesian", - "indonesien", "indonesian", - "indonesion", "indonesian", - "indonisian", "indonesian", - "indonistan", "indonesian", - "indpendent", "independent", - "industiral", "industrial", - "industires", "industries", - "industrail", "industrial", - "industrees", "industries", - "industrias", "industries", - "industriel", "industrial", - "industrija", "industrial", - "industrije", "industries", - "indviduals", "individuals", - "inefficent", "inefficient", - "ineqaulity", "inequality", - "inequailty", "inequality", - "inevatible", "inevitable", - "inevetable", "inevitable", - "inevetably", "inevitably", - "inevetible", "inevitable", - "inevidable", "inevitable", - "inevidably", "inevitably", - "inevitible", "inevitable", - "inevitibly", "inevitably", - "inevtiable", "inevitable", - "inevtiably", "inevitably", - "infallable", "infallible", - "infaltable", "inflatable", - "infeccious", "infectious", - "infecteous", "infectious", - "infectuous", "infectious", - "infedility", "infidelity", - "infektious", "infectious", - "inferioara", "inferior", - "inferioare", "inferior", - "inferiorty", "inferiority", - "inferrence", "inference", - "infestaion", "infestation", - "infestaton", "infestation", - "infestions", "infections", - "infideltiy", "infidelity", - "infidility", "infidelity", - "infiltrade", "infiltrate", - "infiltrait", "infiltrate", - "infiltrare", "infiltrate", - "infiltrase", "infiltrate", - "infinately", "infinitely", - "infinetely", "infinitely", - "infiniment", "infinite", - "infinitley", "infinitely", - "infintiely", "infinitely", - "inflamable", "inflatable", - "inflateble", "inflatable", - "inflatible", "inflatable", - "infleunced", "influenced", - "inflitrate", "infiltrate", - "influanced", "influenced", - "influances", "influences", - "influencie", "influences", - "influening", "influencing", - "influensed", "influences", - "influenser", "influences", - "influenses", "influences", - "influental", "influential", - "influented", "influenced", - "influentes", "influences", - "influneced", "influenced", - "infograhic", "infographic", - "infograpic", "infographic", - "infomation", "information", - "informable", "informal", - "informarla", "informal", - "informarle", "informal", - "informarlo", "informal", - "informatie", "informative", - "informella", "informal", - "informerad", "informed", - "informtion", "information", - "infridging", "infringing", - "infrigning", "infringing", - "infulenced", "influenced", - "infulences", "influences", - "ingenuitiy", "ingenuity", - "ingrediant", "ingredient", - "ingrediens", "ingredients", - "ingrediets", "ingredient", - "inhabitans", "inhabitants", - "inhabitats", "inhabitants", - "inherantly", "inherently", - "inherintly", "inherently", - "inheritage", "heritage", - "inhernetly", "inherently", - "inifnitely", "infinitely", - "initaition", "initiation", - "initalised", "initialised", - "initaliser", "initialiser", - "initalises", "initialises", - "initalisms", "initialisms", - "initalized", "initialized", - "initalizer", "initializer", - "initalizes", "initializes", - "initalling", "initialling", - "initalness", "initialness", - "initiaitve", "initiatives", - "initiaties", "initiatives", - "initiativs", "initiatives", - "initiatves", "initiatives", - "initiavite", "initiatives", - "inititaive", "initiatives", - "inititiave", "initiatives", - "initmately", "intimately", - "initmidate", "intimidate", - "inituition", "initiation", - "injustaces", "injustices", - "injusticas", "injustices", - "inmigrants", "immigrants", - "innoavtion", "innovations", - "innocentes", "innocents", - "innotation", "innovation", - "innovacion", "innovation", - "innovaiton", "innovations", - "innovatief", "innovate", - "innovaties", "innovate", - "innovativo", "innovation", - "innvoation", "innovation", - "inofficial", "unofficial", - "inpsection", "inspection", - "inquisator", "inquisitor", - "inquisidor", "inquisitor", - "inquisiter", "inquisitor", - "inquisitio", "inquisitor", - "inquisitir", "inquisitor", - "inquisiton", "inquisition", - "inquistior", "inquisitor", - "inquizitor", "inquisitor", - "inqusitior", "inquisitor", - "insensitve", "insensitive", - "insepction", "inspection", - "insistance", "insistence", - "insistente", "insistence", - "insistenze", "insistence", - "insistince", "insistence", - "insitution", "institution", - "inspeccion", "inspection", - "inspeciton", "inspections", - "inspectons", "inspections", - "inspectres", "inspectors", - "inspektion", "inspection", - "inspektors", "inspectors", - "inspiraste", "inspires", - "inspiraton", "inspiration", - "inspirerad", "inspired", - "inspireras", "inspires", - "insrugency", "insurgency", - "instabiliy", "instability", - "instabilty", "instability", - "installeer", "installer", - "installent", "installment", - "installesd", "installs", - "installion", "installing", - "instatance", "instance", - "instelling", "installing", - "instituded", "instituted", - "instituion", "institution", - "institutie", "institute", - "institutue", "instituted", - "instrament", "instrument", - "instrcutor", "instructors", - "instrucion", "instruction", - "instructer", "instructor", - "instructie", "instructed", - "instruktor", "instructor", - "instuction", "instruction", - "instuments", "instruments", - "insturcted", "instructed", - "insturctor", "instructor", - "insturment", "instrument", - "instutions", "intuitions", - "instututed", "instituted", - "insurgance", "insurgency", - "insurgancy", "insurgency", - "intangable", "intangible", - "intangeble", "intangible", - "intangibil", "intangible", - "intanjible", "intangible", - "integraded", "integrated", - "integrarla", "integral", - "integrarlo", "integral", - "integratie", "integrated", - "integreres", "interferes", - "integreted", "integrated", - "inteligent", "intelligent", - "intenseley", "intensely", - "intensitiy", "intensity", - "intentinal", "intentional", - "intentines", "intestines", - "interacive", "interactive", - "interactes", "interacts", - "interactie", "interactive", - "interactue", "interacted", - "interasted", "interacted", - "interbread", "interbreed", - "intercepto", "interception", - "intercorse", "intercourse", - "intercouse", "intercourse", - "intereacts", "interfaces", - "interected", "interacted", - "interefers", "interferes", - "interesant", "interest", - "interesing", "interesting", - "interestes", "interests", - "interfacce", "interfaces", - "interfears", "interferes", - "interfeers", "interferes", - "interferce", "interferes", - "interferre", "interfere", - "intergated", "integrated", - "interioara", "interior", - "interioare", "interior", - "intermedie", "intermediate", - "internetbs", "internets", - "internetes", "internets", - "internetis", "internets", - "internetts", "internets", - "internetus", "internets", - "interprate", "interpret", - "interrugum", "interregnum", - "interruped", "interrupted", - "interstela", "interstellar", - "intervalls", "intervals", - "intervalos", "intervals", - "interveign", "intervening", - "interveing", "intervening", - "interveiws", "interviews", - "intervento", "intervention", - "intervenue", "intervene", - "interveres", "interferes", - "intervieni", "interviewing", - "intervieuw", "interviews", - "interviewd", "interviewed", - "interviewr", "interviewer", - "intervines", "intervenes", - "interviwed", "interviewed", - "interviwer", "interviewer", - "interwebbs", "interwebs", - "intestents", "intestines", - "intestinas", "intestines", - "intestinos", "intestines", - "intestions", "intestines", - "intidimate", "intimidate", - "intimadate", "intimidate", - "intimatley", "intimately", - "intimiated", "intimidate", - "intimidade", "intimidated", - "intimidant", "intimidate", - "intimidare", "intimidate", - "intimitade", "intimidated", - "intimitaly", "intimately", - "intimitate", "intimidate", - "intimitely", "intimately", - "intolarant", "intolerant", - "intolerace", "intolerance", - "intolerate", "intolerant", - "intolerent", "intolerant", - "intolorant", "intolerant", - "intolorent", "intolerant", - "intorduced", "introduced", - "intorduces", "introduces", - "intorverts", "introverts", - "intoxicted", "intoxicated", - "intraverts", "introverts", - "intreguing", "intriguing", - "intricaces", "intricacies", - "intriguied", "intrigue", - "intrigured", "intrigue", - "intrinseci", "intrinsic", - "intrinsinc", "intrinsic", - "intriquing", "intriguing", - "intriuging", "intriguing", - "introdecks", "introduces", - "introdused", "introduces", - "introvents", "introverts", - "introvered", "introverted", - "introversa", "introverts", - "introverse", "introverts", - "introversi", "introverts", - "introverso", "introverts", - "introversy", "introverts", - "introveted", "introverted", - "intruduced", "introduced", - "intruduces", "introduces", - "intruiging", "intriguing", - "intruments", "instruments", - "intuitevly", "intuitively", - "intuitivly", "intuitively", - "intuitivno", "intuition", - "intutively", "intuitively", - "inumerable", "enumerable", - "inusrgency", "insurgency", - "invaderats", "invaders", - "invaildate", "invalidates", - "invairably", "invariably", - "invaldiate", "invalidates", - "invalidade", "invalidate", - "invalidare", "invalidate", - "invalubale", "invaluable", - "invalueble", "invaluable", - "invaraibly", "invariably", - "invariabil", "invariably", - "invaribaly", "invariably", - "invaulable", "invaluable", - "inveitable", "inevitable", - "inveitably", "inevitably", - "invensions", "inventions", - "inventario", "inventor", - "inventarlo", "inventor", - "inventaron", "inventor", - "inventings", "inventions", - "inventivos", "inventions", - "invertendo", "inverted", - "inverterad", "inverted", - "invertions", "inventions", - "investemnt", "investments", - "investiage", "investigate", - "investions", "inventions", - "investirat", "investigator", - "investmens", "investments", - "invicinble", "invincible", - "invididual", "individual", - "invincable", "invincible", - "invinceble", "invincible", - "invinicble", "invincible", - "invinsible", "invincible", - "invinvible", "invincible", - "invisibily", "invisibility", - "invitacion", "invitation", - "invitating", "invitation", - "involunary", "involuntary", - "involvment", "involvement", - "ironcially", "ironically", - "irracional", "irrational", - "irrationel", "irrational", - "irrelavant", "irrelevant", - "irrelavent", "irrelevant", - "irrelevent", "irrelevant", - "irrelivant", "irrelevant", - "irrelivent", "irrelevant", - "irrevelant", "irrelevant", - "irreverant", "irrelevant", - "irridation", "irritation", - "irriration", "irritation", - "irritacion", "irritation", - "irritaties", "irritate", - "islamisist", "islamist", - "islamistas", "islamists", - "isntalling", "installing", - "isntructed", "instructed", - "isntrument", "instrument", - "israeliens", "israelis", - "israelitas", "israelis", - "italianess", "italians", - "itnroduced", "introduced", - "jailborken", "jailbroken", - "jalibroken", "jailbroken", - "jamaicains", "jamaican", - "jamaicaman", "jamaican", - "jerusaleum", "jerusalem", - "jounralism", "journalism", - "jounralist", "journalist", - "jouranlism", "journalism", - "jouranlist", "journalist", - "journalims", "journals", - "journalits", "journals", - "journalizm", "journalism", - "journalsim", "journalism", - "journolist", "journalist", - "judegments", "judgements", - "judgemenal", "judgemental", - "judgemetal", "judgemental", - "jugdements", "judgements", - "juggarnaut", "juggernaut", - "juggeranut", "juggernaut", - "juggernath", "juggernaut", - "juggernout", "juggernaut", - "juggernuat", "juggernaut", - "juggetnaut", "juggernaut", - "jugglenaut", "juggernaut", - "juggurnaut", "juggernaut", - "justifible", "justifiable", - "juvenilles", "juvenile", - "kickstarer", "kickstarter", - "kickstartr", "kickstarter", - "kickstater", "kickstarter", - "kidnapning", "kidnapping", - "kidnappade", "kidnapped", - "killingest", "killings", - "kilometros", "kilometers", - "kilomiters", "kilometers", - "kilomoters", "kilometers", - "kilomteres", "kilometers", - "kindapping", "kidnapping", - "kingdomers", "kingdoms", - "krpytonite", "kryptonite", - "krypotnite", "kryptonite", - "krypronite", "kryptonite", - "kryptinite", "kryptonite", - "kryptolite", "kryptonite", - "kryptonyte", "kryptonite", - "krypyonite", "kryptonite", - "krytponite", "kryptonite", - "kyrptonite", "kryptonite", - "labarotory", "laboratory", - "laboratroy", "laboratory", - "laborerers", "laborers", - "laboritory", "laboratory", - "laborotory", "laboratory", - "lackbuster", "lackluster", - "lacklaster", "lackluster", - "landacapes", "landscapes", - "landingers", "landings", - "landshapes", "landscapes", - "landspaces", "landscapes", - "lannasters", "lannisters", - "lannesters", "lannisters", - "lannistars", "lannisters", - "lannsiters", "lannisters", - "lateration", "alteration", - "latitudine", "latitude", - "laughabley", "laughably", - "laughablly", "laughably", - "launchered", "launched", - "leaglizing", "legalizing", - "lectureres", "lectures", - "legalazing", "legalizing", - "legalizare", "legalize", - "legalizate", "legalize", - "legendaies", "legendaries", - "legendaris", "legendaries", - "legimitacy", "legitimacy", - "legimitate", "legitimate", - "legislatie", "legislative", - "legitamacy", "legitimacy", - "legitamate", "legitimate", - "legitamicy", "legitimacy", - "legitamite", "legitimate", - "legitemacy", "legitimacy", - "legitemate", "legitimate", - "legitimaly", "legitimacy", - "legitimicy", "legitimacy", - "legitimite", "legitimate", - "leiutenant", "lieutenant", - "lesbianese", "lesbians", - "lesbianest", "lesbians", - "leuitenant", "lieutenant", - "levetating", "levitating", - "liberacion", "liberation", - "liberalest", "liberate", - "liberalizm", "liberalism", - "liberalnim", "liberalism", - "liberalsim", "liberalism", - "liberarion", "liberation", - "liberaties", "liberate", - "liberatore", "liberate", - "libertania", "libertarians", - "libguistic", "linguistic", - "lietuenant", "lieutenant", - "lieutanant", "lieutenant", - "lieutanent", "lieutenant", - "lieutenent", "lieutenant", - "lifestiles", "lifestyles", - "lifestlyes", "lifestyles", - "lifesystem", "filesystem", - "lifesytles", "lifestyles", - "lifetimers", "lifetimes", - "lifetsyles", "lifestyles", - "lighhtning", "lightening", - "lightergas", "lighters", - "lighthning", "lightening", - "lighthorse", "lighthouse", - "lighthosue", "lighthouse", - "lighthours", "lighthouse", - "lightining", "lighting", - "lightneing", "lightening", - "lightnting", "lightening", - "lightrooom", "lightroom", - "lightweigt", "lightweight", - "ligitation", "litigation", - "ligthening", "lightening", - "ligthhouse", "lighthouse", - "likelyhood", "likelihood", - "limination", "limitation", - "limitacion", "limitation", - "limitaiton", "limitation", - "limitating", "limitation", - "limitativo", "limitation", - "linguisics", "linguistics", - "linguisitc", "linguistics", - "linguistcs", "linguistics", - "linguistis", "linguistics", - "linguitics", "linguistic", - "lingusitic", "linguistics", - "lingvistic", "linguistic", - "liousville", "louisville", - "listeneres", "listeners", - "literallly", "literally", - "literarely", "literary", - "literarlly", "literary", - "literatire", "literate", - "literative", "literate", - "literatute", "literate", - "lithuanina", "lithuania", - "litterally", "literally", - "liuetenant", "lieutenant", - "liveatream", "livestream", - "livelehood", "livelihood", - "liverpoool", "liverpool", - "livescream", "livestream", - "livestreem", "livestream", - "livestrems", "livestream", - "livilehood", "livelihood", - "livliehood", "livelihood", - "lobbyistes", "lobbyists", - "lockacreen", "lockscreen", - "logictical", "logistical", - "logisitcal", "logistical", - "logisticas", "logistics", - "logisticly", "logistical", - "loiusville", "louisville", - "lollipoopy", "lollipop", - "lonelyness", "loneliness", - "longevitiy", "longevity", - "lonileness", "loneliness", - "lonlieness", "loneliness", - "louieville", "louisville", - "louisiania", "louisiana", - "louisianna", "louisiana", - "louisivlle", "louisville", - "louisviile", "louisville", - "lousiville", "louisville", - "luietenant", "lieutenant", - "mabyelline", "maybelline", - "magnifient", "magnificent", - "mainpulate", "manipulate", - "mainstreem", "mainstream", - "maintaince", "maintained", - "maintaines", "maintains", - "maintainig", "maintaining", - "maintenace", "maintenance", - "maintianed", "maintained", - "maintioned", "mentioned", - "malfuncion", "malfunction", - "malpractce", "malpractice", - "managebale", "manageable", - "maneagable", "manageable", - "maneouvred", "manoeuvred", - "maneouvres", "manoeuvres", - "maneuveres", "maneuvers", - "maneuveurs", "maneuver", - "manifestas", "manifests", - "manifestes", "manifests", - "manifestus", "manifests", - "manipluate", "manipulate", - "manipualte", "manipulate", - "manipulant", "manipulate", - "manipulare", "manipulate", - "manipulted", "manipulated", - "maniuplate", "manipulate", - "mannarisms", "mannerisms", - "mannersims", "mannerisms", - "mannorisms", "mannerisms", - "manufacter", "manufacture", - "manufacure", "manufacture", - "manufature", "manufacture", - "maraudeurs", "marauder", - "margaritte", "margaret", - "margianlly", "marginally", - "marginaali", "marginal", - "marginable", "marginal", - "marignally", "marginally", - "marijuanna", "marijuana", - "marketting", "marketing", - "marshmalow", "marshmallow", - "masculinty", "masculinity", - "massacrare", "massacre", - "massivelly", "massively", - "masteriers", "masteries", - "masternind", "mastermind", - "masterpice", "masterpiece", - "mastrubate", "masturbate", - "mastubrate", "masturbated", - "masturabte", "masturbate", - "masturbait", "masturbate", - "masturbare", "masturbate", - "masturbeta", "masturbated", - "masturdate", "masturbate", - "materiales", "materials", - "materialsm", "materialism", - "maximazing", "maximizing", - "maximixing", "maximizing", - "mayballine", "maybelline", - "maybellene", "maybelline", - "maybellibe", "maybelline", - "maybilline", "maybelline", - "mccarthyst", "mccarthyist", - "mdifielder", "midfielder", - "meagthread", "megathread", - "meaningess", "meanings", - "meaningles", "meanings", - "meatballls", "meatballs", - "mecahnical", "mechanical", - "mecahnisms", "mechanisms", - "mechancial", "mechanical", - "mechandise", "merchandise", - "mechanichs", "mechanics", - "mechanicle", "mechanical", - "mechanicly", "mechanical", - "mechanicus", "mechanics", - "mechanincs", "mechanic", - "mechanisim", "mechanism", - "mechansims", "mechanisms", - "mechinical", "mechanical", - "mechinisms", "mechanisms", - "mediaction", "medications", - "medicacion", "medication", - "medicaiton", "medication", - "medicalert", "medicare", - "medicallly", "medically", - "medicatons", "medications", - "medicinens", "medicines", - "medicinske", "medicine", - "medicority", "mediocrity", - "medidating", "meditating", - "mediocirty", "mediocrity", - "mediocraty", "mediocrity", - "mediocrety", "mediocrity", - "mediocricy", "mediocrity", - "mediocrily", "mediocrity", - "mediocrisy", "mediocrity", - "meditacion", "medications", - "meditaiton", "meditation", - "melatonian", "melatonin", - "melatonion", "melatonin", - "mellinnium", "millennium", - "melodieuse", "melodies", - "membrances", "membrane", - "mentallity", "mentally", - "mentionnes", "mentions", - "mercenaire", "mercenaries", - "mercenares", "mercenaries", - "mercentile", "mercantile", - "merchanise", "merchandise", - "merchantos", "merchants", - "messagease", "messages", - "messagepad", "messaged", - "messenging", "messaging", - "metabalism", "metabolism", - "metabilism", "metabolism", - "metabloism", "metabolism", - "metablosim", "metabolism", - "metabolics", "metabolism", - "metabolizm", "metabolism", - "metabolsim", "metabolism", - "metalurgic", "metallurgic", - "metaphoras", "metaphors", - "metaphores", "metaphors", - "metaphyics", "metaphysics", - "meterology", "meteorology", - "methaphors", "metaphors", - "methodolgy", "methodology", - "methodoloy", "methodology", - "metrapolis", "metropolis", - "metrolopis", "metropolis", - "metropilis", "metropolis", - "metroplois", "metropolis", - "metropolin", "metropolitan", - "metropolos", "metropolis", - "metropolys", "metropolis", - "mexicanese", "mexicans", - "mexicaness", "mexicans", - "michelline", "michelle", - "micorwaves", "microwaves", - "microhpone", "microphone", - "microscoop", "microscope", - "microvaves", "microwaves", - "microvaxes", "microwaves", - "micrpohone", "microphones", - "midfeilder", "midfielder", - "midfiedler", "midfielder", - "midfieldes", "midfielders", - "midfielers", "midfielders", - "midfileder", "midfielder", - "midifelder", "midfielder", - "midnlessly", "mindlessly", - "migitation", "mitigation", - "migrainers", "migraines", - "miletsones", "milestones", - "milisecond", "millisecond", - "militiades", "militias", - "militiants", "militias", - "millinnium", "millennium", - "miminalist", "minimalist", - "minamilist", "minimalist", - "mindleslly", "mindlessly", - "minimazing", "minimizing", - "minimilast", "minimalist", - "minimilist", "minimalist", - "mininalist", "minimalist", - "ministeres", "ministers", - "ministerns", "ministers", - "minneaplis", "minneapolis", - "minneapols", "minneapolis", - "minnesotta", "minnesota", - "minoritets", "minorities", - "minoroties", "minorities", - "miracalous", "miraculous", - "miracluous", "miraculous", - "miracoulus", "miraculous", - "mircophone", "microphone", - "mircoscope", "microscope", - "mircowaves", "microwaves", - "misandrony", "misandry", - "miscarrage", "miscarriage", - "miscarrige", "miscarriage", - "misdemenor", "misdemeanor", - "miserabley", "miserably", - "miserablly", "miserably", - "misforture", "misfortune", - "misgoynist", "misogynist", - "misinfomed", "misinformed", - "misinterpt", "misinterpret", - "misisonary", "missionary", - "misoganist", "misogynist", - "misogenist", "misogynist", - "misoginist", "misogynist", - "misoginyst", "misogynist", - "misognyist", "misogynist", - "misogonist", "misogynist", - "misogonyst", "misogynist", - "misogyinst", "misogynist", - "misogynyst", "misogynist", - "misoygnist", "misogynist", - "mispelling", "misspelling", - "missionare", "missionaries", - "missionera", "missionary", - "missisippi", "mississippi", - "mississipi", "mississippi", - "mississppi", "mississippi", - "misspeling", "misspelling", - "misspellng", "misspelling", - "mistakedly", "mistakenly", - "mistakinly", "mistakenly", - "mistankely", "mistakenly", - "misterious", "mysterious", - "misteryous", "mysterious", - "mistreaded", "mistreated", - "misygonist", "misogynist", - "mitigaiton", "mitigation", - "moderacion", "moderation", - "moderaters", "moderates", - "moderatley", "moderately", - "moderatore", "moderate", - "moderatorn", "moderation", - "modificato", "modification", - "modifieras", "modifiers", - "modifieres", "modifiers", - "moisturier", "moisturizer", - "moleculair", "molecular", - "molestaion", "molestation", - "molestarle", "molester", - "molestarme", "molester", - "molestarse", "molester", - "molestarte", "molester", - "molestered", "molested", - "momentarly", "momentarily", - "monagomous", "monogamous", - "monetizare", "monetize", - "monitering", "monitoring", - "monogymous", "monogamous", - "monolistic", "monolithic", - "monolitich", "monolithic", - "monolopies", "monopolies", - "monolothic", "monolithic", - "monolythic", "monolithic", - "monopilies", "monopolies", - "monoploies", "monopolies", - "monopolets", "monopolies", - "monopolice", "monopolies", - "monopolios", "monopolies", - "monothilic", "monolithic", - "monsterous", "monsters", - "montioring", "monitoring", - "monumentos", "monuments", - "monumentul", "monumental", - "monumentus", "monuments", - "mormonisim", "mormonism", - "morphinate", "morphine", - "morrisette", "morissette", - "morrisound", "morrison", - "mosquitero", "mosquito", - "mosquiters", "mosquitoes", - "motherbard", "motherboard", - "motherboad", "motherboard", - "motherbord", "motherboard", - "motivaiton", "motivations", - "motiviated", "motivated", - "motorcicle", "motorcycle", - "motorcylce", "motorcycle", - "motorcyles", "motorcycles", - "motorollas", "motorola", - "mouthpeace", "mouthpiece", - "mouthpeice", "mouthpiece", - "movespeeed", "movespeed", - "mozzaralla", "mozzarella", - "mozzeralla", "mozzarella", - "mozzorella", "mozzarella", - "mulitation", "mutilation", - "mulitplied", "multiplied", - "mulitplier", "multiplier", - "mulitverse", "multiverse", - "multilpier", "multiplier", - "multiplaer", "multiplier", - "multiplaye", "multiply", - "multiplayr", "multiply", - "multiplays", "multiply", - "multipleye", "multiply", - "multipling", "multiplying", - "multiplyed", "multiplied", - "multiplyer", "multiple", - "multiplyng", "multiplying", - "murderered", "murdered", - "murdereres", "murderers", - "muscicians", "musicians", - "musculaire", "muscular", - "mushroooms", "mushroom", - "mutialtion", "mutilation", - "mutiliated", "mutilated", - "mutliation", "mutilation", - "mutliplied", "multiplied", - "mutliplier", "multiplier", - "mutliverse", "multiverse", - "mysogynist", "misogynist", - "mysterieus", "mysteries", - "nagivating", "navigating", - "nagivation", "navigation", - "narcassism", "narcissism", - "narcassist", "narcissist", - "narcessist", "narcissist", - "narciscism", "narcissism", - "narciscist", "narcissist", - "narcisissm", "narcissism", - "narcisisst", "narcissist", - "narcisists", "narcissist", - "narcissicm", "narcissism", - "narcissict", "narcissist", - "narcissitc", "narcissist", - "narcissits", "narcissist", - "narcoticos", "narcotics", - "narrativas", "narratives", - "narrativos", "narratives", - "narritives", "narratives", - "nashvillle", "nashville", - "nationales", "nationals", - "nationalis", "nationals", - "nationalit", "nationalist", - "nationaliy", "nationality", - "nationalty", "nationality", - "nationella", "national", - "naturually", "naturally", - "naviagting", "navigating", - "naviagtion", "navigation", - "navigatore", "navigate", - "neccessary", "necessary", - "necesarily", "necessarily", - "necessairy", "necessarily", - "necessarly", "necessary", - "necessarry", "necessary", - "necessiate", "necessitate", - "necessites", "necessities", - "neckbeared", "neckbeard", - "neckboards", "neckbeards", - "neckbreads", "neckbeards", - "neckneards", "neckbeards", - "necromacer", "necromancer", - "necromaner", "necromancer", - "needleslly", "needlessly", - "negativaty", "negativity", - "negativley", "negatively", - "negelcting", "neglecting", - "negilgence", "negligence", - "negiotated", "negotiated", - "neglacting", "neglecting", - "neglagence", "negligence", - "neglegance", "negligence", - "neglegible", "negligible", - "neglegting", "neglecting", - "neglibible", "negligible", - "neglicence", "negligence", - "neglicible", "negligible", - "neglicting", "neglecting", - "negligable", "negligible", - "negligance", "negligence", - "negligeble", "negligible", - "negligente", "negligence", - "negociated", "negotiated", - "negogiated", "negotiated", - "negoitated", "negotiated", - "negotaited", "negotiated", - "negotation", "negotiation", - "negotiaion", "negotiation", - "negotiatie", "negotiated", - "negotiatin", "negotiations", - "negotiaton", "negotiation", - "neigbhours", "neighbours", - "neighbhors", "neighbours", - "neighbords", "neighbours", - "neighbores", "neighbours", - "netowrking", "networking", - "netruality", "neutrality", - "neturality", "neutrality", - "netwroking", "networking", - "neurologia", "neurological", - "neutrailty", "neutrality", - "newletters", "newsletters", - "newlsetter", "newsletter", - "newsettler", "newsletter", - "newslatter", "newsletter", - "nieghbours", "neighbours", - "nightmates", "nightmares", - "nightmears", "nightmares", - "nightmeres", "nightmares", - "nigthmares", "nightmares", - "nipticking", "nitpicking", - "nitpciking", "nitpicking", - "nominacion", "nomination", - "nominatino", "nominations", - "nominativo", "nomination", - "nominatons", "nominations", - "nonsencial", "nonsensical", - "nontheless", "nonetheless", - "northerend", "northern", - "nostalgica", "nostalgia", - "nostalgija", "nostalgia", - "noteworhty", "noteworthy", - "nothingess", "nothingness", - "noticabely", "noticeably", - "noticabley", "noticeably", - "noticiably", "noticeably", - "notoriosly", "notoriously", - "novembeard", "november", - "nuetrality", "neutrality", - "nutricious", "nutritious", - "nutrientes", "nutrients", - "nutritents", "nutrients", - "nutritinal", "nutritional", - "nutritiuos", "nutritious", - "nutritivos", "nutritious", - "nutrituous", "nutritious", - "nutrutious", "nutritious", - "obatinable", "obtainable", - "obejctives", "objectives", - "obilgatory", "obligatory", - "objecitves", "objectives", - "objectivas", "objectives", - "objectivly", "objectively", - "objectivst", "objectives", - "objectivty", "objectivity", - "objektives", "objectives", - "obligitary", "obligatory", - "obligitory", "obligatory", - "observabil", "observable", - "observarse", "observers", - "observaton", "observation", - "observeras", "observers", - "observered", "observed", - "observeres", "observers", - "observible", "observable", - "obstancles", "obstacles", - "obstrucion", "obstruction", - "obstructin", "obstruction", - "obtainabie", "obtainable", - "obtaineble", "obtainable", - "obtainible", "obtainable", - "obtianable", "obtainable", - "ocasionaly", "occasionally", - "ocassional", "occasional", - "ocassioned", "occasioned", - "occaisonal", "occasional", - "occasionly", "occasional", - "occassions", "occasions", - "occational", "occasional", - "occulation", "occupation", - "occupaiton", "occupation", - "occurances", "occurrences", - "occurences", "occurrences", - "occurrance", "occurrence", - "octohedral", "octahedral", - "octohedron", "octahedron", - "offensivly", "offensively", - "offereings", "offerings", - "officailly", "officially", - "olbigatory", "obligatory", - "ominpotent", "omnipotent", - "ominscient", "omniscient", - "omnipetent", "omnipotent", - "omnipitent", "omnipotent", - "omnipotant", "omnipotent", - "omnisicent", "omniscient", - "omniverous", "omnivorous", - "omnsicient", "omniscient", - "onmipotent", "omnipotent", - "onmiscient", "omniscient", - "operatings", "operations", - "operativne", "operative", - "operativos", "operations", - "oportunity", "opportunity", - "opponenets", "opponent", - "oppononent", "opponent", - "oppressiun", "oppressing", - "optimisitc", "optimistic", - "optimizare", "optimize", - "optimizate", "optimize", - "optimizied", "optimize", - "organicaly", "organically", - "organiclly", "organically", - "organisate", "organise", - "organische", "organise", - "organisera", "organizers", - "organisere", "organizers", - "organisert", "organizers", - "organisier", "organise", - "organisims", "organism", - "organismed", "organise", - "organismen", "organise", - "organismer", "organise", - "organismes", "organisms", - "organismus", "organisms", - "organisten", "organise", - "organiszed", "organise", - "organizaed", "organize", - "organizare", "organizer", - "organizate", "organize", - "organizors", "organizers", - "organizuje", "organize", - "organziers", "organizers", - "orientaion", "orientation", - "orientarla", "oriental", - "orientarlo", "oriental", - "origianlly", "originally", - "originales", "originals", - "originalet", "originated", - "originalis", "originals", - "originalty", "originality", - "orignially", "originally", - "origniated", "originated", - "origonally", "originally", - "origonated", "originated", - "ostencibly", "ostensibly", - "ostenisbly", "ostensibly", - "ostensably", "ostensibly", - "ostentibly", "ostensibly", - "ostrasiced", "ostracized", - "ostrasized", "ostracized", - "ostraziced", "ostracized", - "ostrazised", "ostracized", - "ostrecized", "ostracized", - "ostricized", "ostracized", - "ostrocized", "ostracized", - "oustanding", "outstanding", - "outcalssed", "outclassed", - "outlcassed", "outclassed", - "outnumberd", "outnumbered", - "outnumbred", "outnumbered", - "outperfoms", "outperform", - "outperfrom", "outperform", - "outpreform", "outperform", - "outrageuos", "outrageous", - "outragious", "outrageous", - "outragoues", "outrageous", - "outreagous", "outrageous", - "outsourcad", "outsourced", - "outsouring", "outsourcing", - "outsoursed", "outsourced", - "outweighes", "outweighs", - "overarcing", "overarching", - "overclockd", "overclocked", - "overcloked", "overclocked", - "overcoding", "overcoming", - "overheards", "overhead", - "overheared", "overhead", - "overhooked", "overlooked", - "overlanded", "overloaded", - "overlaoded", "overloaded", - "overlaping", "overlapping", - "overlauded", "overloaded", - "overloards", "overload", - "overlorded", "overloaded", - "overlordes", "overlords", - "overnurfed", "overturned", - "overpirced", "overpriced", - "overpowerd", "overpowered", - "overpowred", "overpowered", - "overprised", "overpriced", - "overtunned", "overturned", - "overtunred", "overturned", - "overturing", "overturn", - "overweigth", "overweight", - "overwhemed", "overwhelmed", - "overwieght", "overweight", - "overwritte", "overwrite", - "pahtfinder", "pathfinder", - "painfullly", "painfully", - "painkilers", "painkillers", - "pairlament", "parliament", - "pakistanti", "pakistani", - "paladinlst", "paladins", - "palcements", "placements", - "paleolitic", "paleolithic", - "palestinan", "palestinian", - "paltformer", "platformer", - "palyerbase", "playerbase", - "parachutte", "parachute", - "parademics", "paramedics", - "paradiggum", "paradigm", - "paragraghs", "paragraphs", - "paragrahps", "paragraphs", - "paragrapgh", "paragraphs", - "paragrpahs", "paragraphs", - "parahprase", "paraphrase", - "paralleles", "parallels", - "parallells", "parallels", - "paramadics", "paramedics", - "paramaters", "parameters", - "paramecias", "paramedics", - "parametics", "paramedics", - "parametros", "parameters", - "paramiters", "parameters", - "paramormal", "paranormal", - "paranoicas", "paranoia", - "paranomral", "paranormal", - "paranornal", "paranormal", - "parapharse", "paraphrase", - "paraphraze", "paraphrase", - "paraprhase", "paraphrase", - "parasitter", "parasite", - "parilament", "parliament", - "parituclar", "particular", - "parlaiment", "parliament", - "parliamant", "parliament", - "parliamone", "parliament", - "parliement", "parliament", - "parrallell", "parallel", - "parrallely", "parallelly", - "partiarchy", "patriarchy", - "participas", "participants", - "participat", "participants", - "participte", "participate", - "particualr", "particular", - "partiotism", "patriotism", - "passionais", "passions", - "passionale", "passionately", - "passionant", "passionate", - "passionite", "passionate", - "passivedns", "passives", - "passivelly", "passively", - "patenterad", "patented", - "pathfidner", "pathfinder", - "pathfindir", "pathfinder", - "pathifnder", "pathfinder", - "patientens", "patients", - "patrairchy", "patriarchy", - "patriachry", "patriarchy", - "patriarcal", "patriarchal", - "patriarhal", "patriarchal", - "patriatchy", "patriarchy", - "patriatism", "patriotism", - "patrionism", "patriotism", - "patriotics", "patriotism", - "patriotisk", "patriots", - "patroitism", "patriotism", - "patryarchy", "patriarchy", - "pedantisch", "pedantic", - "pedestiran", "pedestrian", - "pedestrain", "pedestrian", - "pedictions", "depictions", - "pedohpiles", "pedophiles", - "pedohpilia", "pedophilia", - "pedophilac", "pedophilia", - "pedophilea", "pedophilia", - "pedophilie", "pedophile", - "pedophilla", "pedophilia", - "pedophille", "pedophile", - "pedopholia", "pedophilia", - "penetraion", "penetration", - "penetratin", "penetration", - "penetraton", "penetration", - "penguinese", "penguins", - "penguiness", "penguins", - "peninsulla", "peninsula", - "penninsula", "peninsula", - "peodphiles", "pedophiles", - "peodphilia", "pedophilia", - "pepperment", "peppermint", - "pepperonni", "pepperoni", - "percantage", "percentage", - "percantile", "percentile", - "percaution", "precaution", - "percenatge", "percentages", - "percential", "percentile", - "percentige", "percentile", - "perceptoin", "perceptions", - "percession", "percussion", - "percetange", "percentages", - "percetnage", "percentages", - "percintile", "percentile", - "percission", "percussion", - "percpetion", "perceptions", - "percusions", "percussion", - "perdicting", "predicting", - "perdiction", "prediction", - "perdictive", "predictive", - "perenially", "perennially", - "perfeccion", "perfection", - "perfecxion", "perfection", - "perfektion", "perfection", - "perferable", "preferable", - "perferably", "preferably", - "perference", "preference", - "perferring", "preferring", - "perfexcion", "perfection", - "perfomance", "performance", - "performace", "performance", - "performane", "performances", - "performans", "performances", - "performens", "performers", - "performous", "performs", - "perfromers", "performers", - "perhiperal", "peripheral", - "peridinkle", "periwinkle", - "perihperal", "peripheral", - "periodisch", "periodic", - "periperhal", "peripheral", - "peripheals", "peripherals", - "peripheria", "peripheral", - "periphiral", "peripheral", - "periphreal", "peripheral", - "periphrial", "peripheral", - "peritinkle", "periwinkle", - "periwankle", "periwinkle", - "periwinkel", "periwinkle", - "periwinkie", "periwinkle", - "periwinlke", "periwinkle", - "permanenty", "permanently", - "permanetly", "permanently", - "permisions", "permission", - "permisison", "permissions", - "permissble", "permissible", - "permissibe", "permissible", - "permissons", "permissions", - "perogative", "prerogative", - "perordered", "preordered", - "perpatuate", "perpetuate", - "perpetualy", "perpetually", - "perpetuare", "perpetuate", - "persausion", "persuasion", - "persausive", "persuasive", - "persective", "respective", - "persectued", "persecuted", - "persecutie", "persecuted", - "persecutin", "persecution", - "perserving", "preserving", - "persicuted", "persecuted", - "persistant", "persistent", - "persistens", "persists", - "persoanlly", "personally", - "persocuted", "persecuted", - "personalie", "personalized", - "personalis", "personas", - "personarse", "personas", - "personatus", "personas", - "personnell", "personnel", - "perspecive", "perspective", - "perspectie", "perspectives", - "persuasian", "persuasion", - "persuasing", "persuasion", - "persuasivo", "persuasion", - "persuation", "persuasion", - "persucuted", "persecuted", - "persumably", "presumably", - "persussion", "persuasion", - "persvasive", "persuasive", - "perswasion", "persuasion", - "pertinante", "pertinent", - "pervailing", "prevailing", - "pervalence", "prevalence", - "pervention", "prevention", - "perversley", "perverse", - "pesitcides", "pesticides", - "pessimistc", "pessimistic", - "pessimitic", "pessimistic", - "pestacides", "pesticides", - "pestecides", "pesticides", - "pesticedes", "pesticides", - "pesticidas", "pesticides", - "pestisides", "pesticides", - "pestizides", "pesticides", - "pharamcist", "pharmacist", - "pharmacias", "pharmacist", - "pharmacyst", "pharmacist", - "pharmasist", "pharmacist", - "pharmicist", "pharmacist", - "phemonenon", "phenomenon", - "phenemenon", "phenomenon", - "phenemonal", "phenomenal", - "phenomanal", "phenomenal", - "phenomanon", "phenomenon", - "phenomemon", "phenomenon", - "phenomenen", "phenomenon", - "phenomenol", "phenomenal", - "phenomenom", "phenomenon", - "phenominon", "phenomenon", - "phenomonal", "phenomenal", - "phenomonen", "phenomenon", - "phenomonon", "phenomenon", - "phenonemal", "phenomenal", - "phenonemon", "phenomenon", - "phenonmena", "phenomena", - "philipines", "philippines", - "philippins", "philippines", - "philisophy", "philosophy", - "phillipine", "philippine", - "phillipses", "phillies", - "philosiphy", "philosophy", - "philosohpy", "philosophy", - "philosoper", "philosopher", - "philospher", "philosopher", - "philospohy", "philosophy", - "photogragh", "photograph", - "photograhs", "photographs", - "photograhy", "photography", - "photograps", "photographs", - "photograpy", "photography", - "photogrpah", "photographs", - "photoshopd", "photoshopped", - "photoshope", "photoshopped", - "phramacist", "pharmacist", - "phsyically", "physically", - "phsyicians", "physicians", - "phsyicists", "physicists", - "phsyiology", "physiology", - "phycisians", "physicians", - "phycisists", "physicists", - "phyiscally", "physically", - "phyisology", "physiology", - "physcially", "physically", - "physcology", "psychology", - "physcopath", "psychopath", - "physicials", "physicians", - "physiciens", "physicians", - "physioligy", "physiology", - "picthforks", "pitchforks", - "pinoneered", "pioneered", - "pitchferks", "pitchforks", - "pitchfolks", "pitchforks", - "pitchfords", "pitchforks", - "pitchworks", "pitchforks", - "pitckforks", "pitchforks", - "pittaburgh", "pittsburgh", - "pittsbrugh", "pittsburgh", - "placehoder", "placeholder", - "placeholdr", "placeholder", - "placeholer", "placeholder", - "placemenet", "placements", - "plagairism", "plagiarism", - "plagarisim", "plagiarism", - "plagiariam", "plagiarism", - "plagiarios", "plagiarism", - "plagiarius", "plagiarism", - "plagiarizm", "plagiarism", - "plagierism", "plagiarism", - "plaguarism", "plagiarism", - "plaigarism", "plagiarism", - "plasticosa", "plastics", - "platfarmer", "platformer", - "platformar", "platformer", - "platformie", "platformer", - "platfotmer", "platformer", - "platfromer", "platformer", - "platofrmer", "platformer", - "playaround", "playground", - "playersare", "playerbase", - "playgorund", "playground", - "playthrogh", "playthrough", - "playthrouh", "playthrough", - "playwrites", "playwrights", - "plethorian", "plethora", - "policitian", "politician", - "polinators", "pollinators", - "polishuset", "polishes", - "politessen", "politeness", - "politicain", "politician", - "politicaly", "politically", - "politicien", "politician", - "politicing", "politician", - "politicion", "politician", - "politickin", "politician", - "politiikan", "politician", - "politiness", "politeness", - "polititian", "politician", - "popualtion", "populations", - "populairty", "popularity", - "populaiton", "populations", - "popularaty", "popularity", - "popularest", "populate", - "popularily", "popularity", - "populaties", "populate", - "populatiry", "popularity", - "populative", "populate", - "populatoin", "populations", - "popultaion", "populations", - "pormetheus", "prometheus", - "pornograhy", "pornography", - "pornograpy", "pornography", - "pornogrphy", "pornography", - "porportion", "proportion", - "portabilty", "portability", - "portarying", "portraying", - "portoguese", "portuguese", - "portraiing", "portraying", - "portrating", "portraying", - "portrayels", "portrays", - "portugeuse", "portuguese", - "portuguise", "portuguese", - "posessions", "possessions", - "posicional", "positional", - "positevely", "positively", - "positioing", "positioning", - "positionly", "positional", - "positionne", "positioned", - "positivley", "positively", - "possesives", "possessive", - "possessers", "possesses", - "possessess", "possesses", - "possibiliy", "possibility", - "possibilty", "possibility", - "possissive", "possessive", - "posthomous", "posthumous", - "potentialy", "potentially", - "poulations", "populations", - "powerhorse", "powerhouse", - "powerhosue", "powerhouse", - "powerhours", "powerhouse", - "powerhsell", "powershell", - "powerprint", "powerpoint", - "powersehll", "powershell", - "ppublisher", "publisher", - "practially", "practically", - "practicaly", "practically", - "practicess", "practise", - "practiclly", "practically", - "practioner", "practitioner", - "precaucion", "precaution", - "precausion", "precaution", - "precautios", "precautions", - "precedance", "precedence", - "precedense", "precedence", - "preceeding", "preceding", - "precendece", "precedence", - "precentage", "percentage", - "precentile", "percentile", - "preciselly", "precisely", - "precuation", "precautions", - "precussion", "percussion", - "predecated", "predicated", - "predecence", "precedence", - "predecesor", "predecessor", - "predection", "prediction", - "predective", "predictive", - "prediccion", "prediction", - "prediceted", "predicated", - "predicited", "predicated", - "predicitng", "predicting", - "prediciton", "prediction", - "predicitve", "predictive", - "predickted", "predicated", - "predictave", "predictive", - "predictivo", "prediction", - "predictons", "predictions", - "predjuiced", "prejudiced", - "predjuices", "prejudices", - "preduction", "prediction", - "preductive", "predictive", - "predujiced", "prejudiced", - "predujices", "prejudices", - "prefarable", "preferable", - "prefarably", "preferably", - "prefection", "perfection", - "preferance", "preference", - "prefereble", "preferable", - "preferente", "preference", - "preferenze", "preference", - "preferible", "preferable", - "preferibly", "preferably", - "prefernece", "preferences", - "preformers", "performers", - "pregancies", "pregnancies", - "pregnanies", "pregnancies", - "preipheral", "peripheral", - "preisdents", "presidents", - "preisthood", "priesthood", - "prejeduced", "prejudiced", - "prejeduces", "prejudices", - "prejiduced", "prejudiced", - "prejiduces", "prejudices", - "prejucided", "prejudiced", - "prejucides", "prejudices", - "prejuduced", "prejudiced", - "prejuduces", "prejudices", - "prelimiary", "preliminary", - "prematurly", "prematurely", - "preminence", "preeminence", - "premission", "permission", - "preorderes", "preorders", - "prepartion", "preparation", - "prepetuate", "perpetuate", - "preposters", "preposterous", - "prescients", "presidents", - "prescirbed", "prescribed", - "prescriped", "prescribed", - "presearing", "preserving", - "presecuted", "persecuted", - "presedency", "presidency", - "presedents", "presidents", - "presenning", "presenting", - "presentase", "presents", - "presentato", "presentation", - "presention", "presenting", - "presentors", "presents", - "preservare", "preserve", - "preservato", "preservation", - "preserverd", "preserved", - "presidancy", "presidency", - "presidante", "presidents", - "presidenta", "presidential", - "presidenty", "presidency", - "presidunce", "presidency", - "presistent", "persistent", - "presonally", "personally", - "presonhood", "personhood", - "pressuming", "pressuring", - "prestigios", "prestigious", - "prestigous", "prestigious", - "presuambly", "presumably", - "presuasion", "persuasion", - "presuasive", "persuasive", - "presumebly", "presumably", - "presumendo", "presumed", - "presumibly", "presumably", - "presumpton", "presumption", - "pretaining", "pertaining", - "pretection", "protection", - "pretendias", "pretends", - "pretensive", "pretense", - "pretentios", "pretentious", - "pretentous", "pretentious", - "prevalecen", "prevalence", - "prevalente", "prevalence", - "prevencion", "prevention", - "preventivo", "prevention", - "preventors", "prevents", - "previaling", "prevailing", - "previosuly", "previously", - "previoulsy", "previously", - "prevolence", "prevalence", - "pricinpals", "principals", - "primarilly", "primarily", - "primatives", "primitives", - "princepals", "principals", - "princesess", "princesses", - "princibles", "principles", - "principaly", "principality", - "principels", "principals", - "principial", "principal", - "principias", "principals", - "principlas", "principals", - "prinicipal", "principal", - "prinicpals", "principals", - "prinicples", "principles", - "printerest", "printers", - "prioratize", "prioritize", - "prioretize", "prioritize", - "prioritice", "prioritize", - "prioritied", "prioritize", - "prioroties", "priorities", - "priorotize", "prioritize", - "priotities", "priorities", - "priotitize", "prioritize", - "privaleged", "privileged", - "privaleges", "privileges", - "privaticed", "privatized", - "privelaged", "privileged", - "privelages", "privileges", - "priveldges", "privileges", - "priveleged", "privileged", - "priveleges", "privileges", - "privelidge", "privileged", - "priveliged", "privileged", - "priveliges", "privileges", - "privetized", "privatized", - "privilaged", "privileged", - "privilages", "privileges", - "priviledge", "privilege", - "privilegde", "privileges", - "privilegie", "privilege", - "priviliged", "privileged", - "priviliges", "privileges", - "privitazed", "privatized", - "privitized", "privatized", - "probabiliy", "probability", - "probabilty", "probability", - "probablies", "probable", - "probablybe", "probable", - "problemita", "problematic", - "procalimed", "proclaimed", - "procceding", "proceeding", - "procedding", "proceeding", - "procederal", "procedural", - "procedings", "proceedings", - "procedrual", "procedural", - "proceededs", "proceeds", - "proceedure", "procedure", - "proceesing", "proceeding", - "processsor", "processors", - "proclamied", "proclaimed", - "proclaming", "proclaiming", - "procliamed", "proclaimed", - "procreatin", "procreation", - "procudures", "procedures", - "prodcution", "production", - "prodecural", "procedural", - "prodecures", "procedures", - "produccion", "production", - "produceras", "produces", - "produceres", "produces", - "producirse", "producers", - "produciton", "production", - "producting", "production", - "productino", "productions", - "productivo", "production", - "productivy", "productivity", - "productoin", "productions", - "produktion", "production", - "produktive", "productive", - "produtcion", "productions", - "profesions", "profession", - "professers", "professors", - "professorn", "profession", - "professsor", "professors", - "proffesion", "profession", - "proficeint", "proficient", - "proficiant", "proficient", - "proficieny", "proficiency", - "proficincy", "proficiency", - "profitabel", "profitable", - "profitabil", "profitable", - "profitible", "profitable", - "proftiable", "profitable", - "programmar", "programmer", - "programmme", "programme", - "progresing", "progressing", - "progresion", "progression", - "progresive", "progressive", - "progressie", "progressives", - "progressin", "progression", - "progresson", "progression", - "progressos", "progresses", - "progressus", "progresses", - "prohibirte", "prohibit", - "prohibites", "prohibits", - "prohibitng", "prohibiting", - "prohibiton", "prohibition", - "prohibitus", "prohibits", - "prohibitve", "prohibited", - "prohobited", "prohibited", - "prohpecies", "prophecies", - "projecitle", "projectiles", - "projectiel", "projectiles", - "projecties", "projectiles", - "projectils", "projectiles", - "projectles", "projectiles", - "projectlie", "projectiles", - "projectyle", "projectile", - "projektile", "projectile", - "projektion", "projection", - "prometheas", "prometheus", - "promethese", "prometheus", - "promethius", "prometheus", - "promethous", "prometheus", - "promethues", "prometheus", - "prominance", "prominence", - "prominenty", "prominently", - "prominetly", "prominently", - "promiscous", "promiscuous", - "promiscuos", "promiscuous", - "promoteurs", "promotes", - "promotheus", "prometheus", - "promotinal", "promotional", - "pronoucned", "pronounced", - "pronouning", "pronouncing", - "propechies", "prophecies", - "propencity", "propensity", - "propenents", "proponents", - "properites", "properties", - "propersity", "propensity", - "propertion", "proportion", - "propertius", "properties", - "prophacies", "prophecies", - "prophocies", "prophecies", - "propietary", "proprietary", - "proplusion", "propulsion", - "propoganda", "propaganda", - "propogates", "propagates", - "propolsion", "propulsion", - "proponants", "proponents", - "proponenet", "proponent", - "proporcion", "proportion", - "proporties", "properties", - "proporting", "proportion", - "propositon", "proposition", - "propotions", "proportions", - "proprietry", "proprietary", - "proprotion", "proportion", - "propserity", "prosperity", - "propserous", "prosperous", - "propulaios", "propulsion", - "propulsing", "propulsion", - "propultion", "propulsion", - "propuslion", "propulsion", - "prosectued", "prosecuted", - "prosectuor", "prosecutor", - "prosecuter", "prosecutor", - "prosecutie", "prosecuted", - "prosicuted", "prosecuted", - "prosicutor", "prosecutor", - "prosocuted", "prosecuted", - "prosparity", "prosperity", - "prospectos", "prospects", - "prosperety", "prosperity", - "prospertiy", "prosperity", - "prosphetic", "prosthetic", - "prosporous", "prosperous", - "prostehtic", "prosthetic", - "prosterity", "prosperity", - "prostethic", "prosthetic", - "prostitite", "prostitute", - "prostitude", "prostitute", - "prostituee", "prostitute", - "prostituer", "prostitute", - "prostitues", "prostitutes", - "prostiture", "prostitute", - "prostituto", "prostitution", - "prostituye", "prostitute", - "protaginst", "protagonist", - "protastant", "protestant", - "proteccion", "protection", - "proteciton", "protections", - "protectice", "protective", - "protectiei", "protective", - "protectoin", "protections", - "protectons", "protectors", - "protectron", "protection", - "protestans", "protests", - "protestare", "protesters", - "protestato", "protestant", - "protestent", "protestant", - "protestina", "protestant", - "prothsetic", "prosthetic", - "protistant", "protestant", - "protocoles", "protocols", - "protocolls", "protocols", - "protocolos", "protocols", - "protohypes", "prototypes", - "protostant", "protestant", - "prototipes", "prototypes", - "prototpyes", "prototypes", - "protraying", "portraying", - "protuguese", "portuguese", - "provencial", "provincial", - "proveribal", "proverbial", - "provervial", "proverbial", - "providance", "providence", - "providince", "providence", - "provinciae", "province", - "provincies", "province", - "provincija", "provincial", - "provinence", "providence", - "provinical", "provincial", - "provintial", "provincial", - "provinvial", "provincial", - "provisiosn", "provision", - "provisonal", "provisional", - "provocatie", "provocative", - "pscyhology", "psychology", - "pscyhopath", "psychopath", - "pshycology", "psychology", - "pshycopath", "psychopath", - "psychedlic", "psychedelic", - "psychiatic", "psychiatric", - "psycholoog", "psychology", - "psychopaat", "psychopath", - "psychopats", "psychopaths", - "ptichforks", "pitchforks", - "publicitan", "publication", - "publisheed", "published", - "publisherr", "publisher", - "publishher", "publisher", - "publissher", "publisher", - "publlisher", "publisher", - "punihsment", "punishments", - "punishemnt", "punishments", - "punishible", "punishable", - "punishmnet", "punishments", - "punissable", "punishable", - "punsihable", "punishable", - "purchacing", "purchasing", - "purpolsion", "propulsion", - "purposedly", "purposely", - "purposelly", "purposely", - "purpotedly", "purportedly", - "pususading", "persuading", - "pyschology", "psychology", - "pyschopath", "psychopath", - "qaulifiers", "qualifiers", - "quailfiers", "qualifiers", - "qualfiiers", "qualifiers", - "qualifieds", "qualifies", - "qualifiies", "qualifiers", - "qualifiing", "qualifying", - "qualifires", "qualifiers", - "qualifyers", "qualifiers", - "qualitying", "qualifying", - "quanitites", "quantities", - "quantaties", "quantities", - "quantitize", "quantities", - "quarantena", "quarantine", - "quarantene", "quarantine", - "quarantied", "quarantine", - "quarintine", "quarantine", - "quaruntine", "quarantine", - "quesitoned", "questioned", - "questional", "questionable", - "questionne", "questioned", - "rabinnical", "rabbinical", - "radiactive", "radioactive", - "radioacive", "radioactive", - "rainbowers", "rainbows", - "randmoness", "randomness", - "randomzied", "randomized", - "randonmess", "randomness", - "randumness", "randomness", - "raspberrry", "raspberry", - "rationalle", "rationale", - "readmition", "readmission", - "realitvely", "relatively", - "realtively", "relatively", - "realtivity", "relativity", - "reaserched", "researched", - "reasercher", "researcher", - "rebiulding", "rebuilding", - "reboudning", "rebounding", - "rebouncing", "rebounding", - "rebuidling", "rebuilding", - "rebuliding", "rebuilding", - "rebuplican", "republican", - "reccommend", "recommend", - "recepients", "recipients", - "receptoras", "receptors", - "receptores", "receptors", - "recgonised", "recognised", - "recgonized", "recognized", - "recgonizes", "recognizes", - "reciepents", "recipients", - "recipeints", "recipients", - "recipiants", "recipients", - "recocnised", "recognised", - "recoginsed", "recognised", - "recoginzed", "recognized", - "recognices", "recognizes", - "recogniton", "recognition", - "recognzied", "recognised", - "recomended", "recommended", - "recommande", "recommend", - "recommands", "recommends", - "recommeded", "recommended", - "recommened", "recommend", - "recommennd", "recommends", - "recomments", "recommends", - "recompence", "recompense", - "reconcider", "reconsider", - "reconcille", "reconcile", - "recongised", "recognised", - "recongized", "recognized", - "recongizes", "recognizes", - "reconisder", "reconsider", - "reconsiled", "reconsider", - "recordarle", "recorder", - "recordarme", "recorder", - "recordarse", "recorder", - "recordarte", "recorder", - "recreacion", "recreation", - "recreatief", "recreate", - "recreativo", "recreation", - "recrutiers", "recruiters", - "rectanglar", "rectangular", - "rectangual", "rectangular", - "rectanguar", "rectangular", - "recuriters", "recruiters", - "recurrance", "recurrence", - "recursivly", "recursively", - "redefinied", "redefine", - "redefinine", "redefine", - "redemtpion", "redemption", - "redepmtion", "redemption", - "redesiging", "redesign", - "rediculous", "ridiculous", - "redmeption", "redemption", - "redneckers", "rednecks", - "redneckese", "rednecks", - "redneckest", "rednecks", - "reduncancy", "redundancy", - "redundency", "redundancy", - "redundnacy", "redundancy", - "redunduncy", "redundancy", - "reenforced", "reinforced", - "reevaulate", "reevaluate", - "refedendum", "referendum", - "refelcting", "reflecting", - "refelction", "reflection", - "refelctive", "reflective", - "referances", "references", - "referandum", "referendum", - "referemces", "references", - "referemdum", "referendum", - "referendim", "referendum", - "referendom", "referendum", - "referenece", "reference", - "referening", "referencing", - "referenses", "referees", - "referentes", "references", - "referneces", "references", - "referrence", "reference", - "referundum", "referendum", - "refference", "reference", - "refleciton", "reflections", - "reflecters", "reflects", - "reflektion", "reflection", - "reflextion", "reflection", - "reformerad", "reformed", - "refrigerar", "refrigerator", - "refurbised", "refurbished", - "regenarate", "regenerate", - "registeres", "registers", - "registrato", "registration", - "regresives", "regressive", - "regressivo", "regression", - "regualting", "regulating", - "regualtion", "regulations", - "regualtors", "regulators", - "regulacion", "regulation", - "regulament", "regulate", - "regulaotrs", "regulators", - "regularily", "regularly", - "regularing", "regulating", - "regularlas", "regulars", - "regularlos", "regulars", - "regulaters", "regulators", - "regulatios", "regulators", - "regulatons", "regulations", - "rehtorical", "rhetorical", - "reinstaled", "reinstalled", - "reitrement", "retirement", - "relagation", "relaxation", - "relatation", "relaxation", - "relativety", "relativity", - "relativily", "relativity", - "relativley", "relatively", - "relavation", "relaxation", - "relaxating", "relaxation", - "relazation", "relaxation", - "releagtion", "relegation", - "relegetion", "relegation", - "relentness", "relentless", - "reletnless", "relentless", - "relevation", "revelation", - "relexation", "relegation", - "relfecting", "reflecting", - "relfection", "reflection", - "relfective", "reflective", - "reliabilty", "reliability", - "reliablely", "reliably", - "religiones", "religions", - "religiosly", "religiously", - "religiousy", "religiously", - "religously", "religiously", - "relitavely", "relatively", - "reluctanct", "reluctant", - "reluctanly", "reluctantly", - "reluctanty", "reluctantly", - "remarcably", "remarkably", - "remarkibly", "remarkably", - "rememberes", "remembers", - "remenicent", "reminiscent", - "reminisent", "reminiscent", - "reminscent", "reminiscent", - "remmebered", "remembered", - "renaissace", "renaissance", - "renderered", "rendered", - "renegerate", "regenerate", - "renewabels", "renewables", - "renewebles", "renewables", - "rennovated", "renovated", - "renweables", "renewables", - "repatition", "repetition", - "repblicans", "republicans", - "repbulican", "republican", - "repeadedly", "repeatedly", - "repeadetly", "repeatedly", - "repearable", "repeatable", - "repearedly", "repealed", - "repeatadly", "repeatedly", - "repeatedlt", "repealed", - "repeatetly", "repeatedly", - "repeatible", "repeatable", - "repeatidly", "repeatedly", - "repectable", "repeatable", - "repentable", "repeatable", - "repentence", "repentance", - "repersents", "represents", - "repetation", "repetition", - "repeteadly", "repeatedly", - "repetetion", "repetition", - "repeticion", "repetition", - "repetitivo", "repetition", - "replacated", "replicated", - "replaceble", "replaceable", - "replacemet", "replacements", - "replacemnt", "replacement", - "replacemtn", "replacements", - "replecated", "replicated", - "repoistory", "repository", - "reponsible", "responsible", - "reportadly", "reportedly", - "reporteros", "reporters", - "reportidly", "reportedly", - "repositary", "repository", - "reposotory", "repository", - "repostiory", "repository", - "representn", "representing", - "repressent", "represents", - "repressivo", "repression", - "repsectful", "respectful", - "repsecting", "respecting", - "repsective", "respective", - "repsonding", "responding", - "repsonsive", "responsive", - "reptuation", "reputation", - "repubicans", "republicans", - "republcian", "republican", - "republians", "republicans", - "republicon", "republican", - "repuglican", "republican", - "repulicans", "republicans", - "reputacion", "reputation", - "requirment", "requirement", - "requrement", "requirement", - "resemblace", "resemble", - "reserached", "researched", - "reseracher", "researchers", - "reserverad", "reserved", - "reservered", "reserved", - "residental", "residential", - "resistable", "resistible", - "resistanes", "resistances", - "resistanse", "resistances", - "resistence", "resistance", - "resistendo", "resisted", - "resistered", "resisted", - "resistnace", "resistances", - "resitsance", "resistances", - "resoltuion", "resolutions", - "resolucion", "resolution", - "resolutino", "resolutions", - "resolutoin", "resolutions", - "resolutons", "resolutions", - "resolvemos", "resolves", - "resolvendo", "resolved", - "resolveres", "resolves", - "resolverse", "resolves", - "resolviste", "resolves", - "resonabelt", "resonate", - "resoultion", "resolution", - "respecitve", "respective", - "respectifs", "respects", - "respection", "respecting", - "respectons", "respects", - "respectuos", "respects", - "respektive", "respective", - "respiratoy", "respiratory", - "responcive", "responsive", - "responisve", "responsive", - "responsibe", "responsive", - "responsiby", "responsibly", - "responsile", "responsive", - "responsing", "responding", - "ressembled", "resembled", - "restarants", "restaurants", - "restaraunt", "restaurant", - "restaruant", "restaurant", - "restatting", "restarting", - "restaurent", "restaurant", - "restauring", "restarting", - "resteraunt", "restaurant", - "restircted", "restricted", - "restorting", "restarting", - "restrainig", "restraining", - "restrcited", "restricted", - "restrcting", "restarting", - "restricing", "restricting", - "restricion", "restriction", - "restricive", "restrictive", - "restrictes", "restricts", - "restrictie", "restrictive", - "restricton", "restriction", - "restructed", "restricted", - "restuarant", "restaurant", - "resturants", "restaurants", - "resturaunt", "restaurant", - "retaliaton", "retaliation", - "rethorical", "rhetorical", - "retierment", "retirement", - "retribuito", "retribution", - "retrosepct", "retrospect", - "retrospekt", "retrospect", - "revaluated", "reevaluated", - "revealtion", "revelations", - "revelaiton", "revelations", - "revelatons", "revelations", - "revelution", "revelation", - "reversable", "reversible", - "reversably", "reversal", - "reviewtrue", "reviewer", - "revisiones", "revisions", - "revisionis", "revisions", - "revoltuion", "revolution", - "revoluiton", "revolutions", - "revolutoin", "revolutions", - "revoultion", "revolution", - "rewarching", "rewatching", - "rewatchibg", "rewatching", - "rewatchign", "rewatching", - "rewatchimg", "rewatching", - "rhapsodomy", "rhapsody", - "rhetorisch", "rhetoric", - "ridicilous", "ridiculous", - "ridicoulus", "ridiculous", - "ridiculise", "ridicule", - "ridiculize", "ridicule", - "ridiculled", "ridicule", - "ridiculose", "ridicule", - "ridiculued", "ridicule", - "rienforced", "reinforced", - "rigthfully", "rightfully", - "roleplaing", "roleplaying", - "romanmania", "romanian", - "roundaboot", "roundabout", - "rucuperate", "recuperate", - "rudimentry", "rudimentary", - "sacarmento", "sacramento", - "sacntioned", "sanctioned", - "sacraficed", "sacrificed", - "sacrafices", "sacrifices", - "sacramenno", "sacramento", - "sacreficed", "sacrificed", - "sacrefices", "sacrifices", - "sacremento", "sacramento", - "sacrifaced", "sacrificed", - "sacrifaces", "sacrifices", - "sacrifical", "sacrificial", - "sacrificas", "sacrifices", - "sacrificie", "sacrificed", - "sacrificng", "sacrificing", - "sacrifises", "sacrifices", - "sacrifized", "sacrificed", - "sacrifizes", "sacrifices", - "sacromento", "sacramento", - "sadistisch", "sadistic", - "sanctionne", "sanctioned", - "sandiwches", "sandwiches", - "sandviches", "sandwiches", - "sandwishes", "sandwiches", - "sanitazion", "sanitation", - "santiation", "sanitation", - "sastifying", "satisfying", - "satellitte", "satellites", - "satifsying", "satisfying", - "satrically", "satirically", - "satsifying", "satisfying", - "sattelites", "satellites", - "saturacion", "saturation", - "scandalosa", "scandals", - "scandalose", "scandals", - "scandalosi", "scandals", - "scandaloso", "scandals", - "scandaniva", "scandinavia", - "scandinava", "scandinavian", - "scandinvia", "scandinavia", - "scaramento", "sacramento", - "scarificed", "sacrificed", - "scarifices", "sacrifices", - "scarmbling", "scrambling", - "scartching", "scratching", - "sceintific", "scientific", - "sceintists", "scientists", - "scenarioes", "scenarios", - "scenarions", "scenarios", - "scenarious", "scenarios", - "scheudling", "scheduling", - "scholarhip", "scholarship", - "scholarley", "scholarly", - "sciencists", "scientists", - "scientests", "scientists", - "scirptures", "scriptures", - "scooterers", "scooters", - "scorebaord", "scoreboard", - "scoreborad", "scoreboard", - "scorebored", "scoreboard", - "scorpiomon", "scorpion", - "scracthing", "scratching", - "scramblies", "scramble", - "screenshat", "screenshot", - "screenshit", "screenshot", - "scriptores", "scriptures", - "scripturae", "scriptures", - "scriputres", "scriptures", - "scritpures", "scriptures", - "scrutinity", "scrutiny", - "seahawkers", "seahawks", - "sebastiaan", "sebastian", - "segegrated", "segregated", - "segragated", "segregated", - "segregaded", "segregated", - "segregatie", "segregated", - "segretated", "segregated", - "segrigated", "segregated", - "selectiose", "selections", - "selectivly", "selectively", - "selectivos", "selections", - "selfishess", "selfishness", - "senitments", "sentiments", - "sensitiviy", "sensitivity", - "sensitivty", "sensitivity", - "sentaments", "sentiments", - "sentancing", "sentencing", - "sentements", "sentiments", - "sentencian", "sentencing", - "sentensing", "sentencing", - "sentimenal", "sentimental", - "sentimetal", "sentimental", - "sentincing", "sentencing", - "sentinents", "sentiments", - "separacion", "separation", - "separaters", "separates", - "separatley", "separately", - "separatron", "separation", - "separetely", "separately", - "seperately", "separately", - "seperating", "separating", - "seperation", "separation", - "seperatism", "separatism", - "seperatist", "separatist", - "seperatley", "seperate", - "sepulchure", "sepulchre", - "serenitary", "serenity", - "serviceble", "serviceable", - "settelment", "settlement", - "settlemens", "settlements", - "settlemets", "settlements", - "settlemnts", "settlements", - "seuxalized", "sexualized", - "seventeeen", "seventeen", - "sexaulized", "sexualized", - "sexualixed", "sexualized", - "sexuallity", "sexually", - "sexualzied", "sexualized", - "sexulaized", "sexualized", - "shakespare", "shakespeare", - "shakespeer", "shakespeare", - "shakespere", "shakespeare", - "shamelesly", "shamelessly", - "shamelessy", "shamelessly", - "shaprening", "sharpening", - "shareholds", "shareholders", - "sharkening", "sharpening", - "sharpining", "sharpening", - "shartening", "sharpening", - "shatnering", "shattering", - "shattening", "shattering", - "shepharded", "shepherd", - "shilouette", "silhouette", - "shitlasses", "shitless", - "shortenend", "shortened", - "shortining", "shortening", - "sidelinien", "sideline", - "sidelinjen", "sideline", - "sidelinked", "sideline", - "sigantures", "signatures", - "sightstine", "sightstone", - "signficant", "significant", - "signifiant", "significant", - "significat", "significant", - "signitures", "signatures", - "sigthstone", "sightstone", - "sihlouette", "silhouette", - "silohuette", "silhouette", - "silouhette", "silhouette", - "similairty", "similarity", - "similarily", "similarly", - "similarlly", "similarly", - "similiarly", "similarly", - "similiarty", "similarity", - "simliarity", "similarity", - "simluation", "simulation", - "simplictic", "simplistic", - "simplifing", "simplifying", - "simplifyed", "simplified", - "simplifyng", "simplifying", - "simplisitc", "simplistic", - "simplisity", "simplicity", - "simplistes", "simplest", - "simplivity", "simplicity", - "simplyfied", "simplified", - "simualtion", "simulation", - "simulacion", "simulation", - "simulaiton", "simulations", - "simulaties", "simulate", - "simulative", "simulate", - "simulatons", "simulations", - "simulatore", "simulate", - "sincereley", "sincerely", - "sincerelly", "sincerely", - "singatures", "signatures", - "singulaire", "singular", - "singulariy", "singularity", - "singularty", "singularity", - "singulator", "singular", - "sitautions", "situations", - "situatinal", "situational", - "skatebaord", "skateboard", - "skateborad", "skateboard", - "skatebored", "skateboard", - "skatebrand", "skateboard", - "skeletones", "skeletons", - "skeptecism", "skepticism", - "skepticals", "skeptics", - "skepticles", "skeptics", - "skepticons", "skeptics", - "skeptisicm", "skepticism", - "skeptisism", "skepticism", - "sketchysex", "sketches", - "sketpicism", "skepticism", - "skillhosts", "skillshots", - "skillshits", "skillshots", - "skillshoot", "skillshots", - "skillslots", "skillshots", - "skillsofts", "skillshots", - "skillsshot", "skillshots", - "skirmiches", "skirmish", - "skpeticism", "skepticism", - "slaughterd", "slaughtered", - "slipperies", "slippers", - "smarpthone", "smartphones", - "smarthpone", "smartphone", - "snadwiches", "sandwiches", - "snowbaling", "snowballing", - "snowballes", "snowballs", - "snowballls", "snowballs", - "socailists", "socialists", - "socailized", "socialized", - "socialisim", "socialism", - "socializng", "socializing", - "socialsits", "socialists", - "sociapaths", "sociopaths", - "socilaists", "socialists", - "socilaized", "socialized", - "sociologia", "sociological", - "sociopatas", "sociopaths", - "sociopatch", "sociopaths", - "sociopatic", "sociopathic", - "socratease", "socrates", - "socreboard", "scoreboard", - "soemthings", "somethings", - "soldiarity", "solidarity", - "solidairty", "solidarity", - "soliditary", "solidarity", - "solitudine", "solitude", - "somehtings", "somethings", - "someonelse", "someones", - "somethibng", "somethin", - "somethigng", "somethin", - "somethigns", "somethings", - "somethihng", "somethin", - "somethiing", "somethin", - "somethijng", "somethin", - "somethikng", "somethin", - "somethimng", "somethin", - "somethinbg", "somethings", - "somethines", "somethings", - "somethinfg", "somethings", - "somethinhg", "somethings", - "somethinig", "somethings", - "somethinkg", "somethings", - "somethinks", "somethings", - "somethinmg", "somethings", - "somethinng", "somethings", - "somethintg", "somethings", - "somethiong", "somethin", - "somethiung", "somethin", - "sophicated", "sophisticated", - "sotrmfront", "stormfront", - "sotrylines", "storylines", - "soudntrack", "soundtrack", - "soundrtack", "soundtracks", - "soundtracs", "soundtracks", - "soundtrakc", "soundtracks", - "soundtrakk", "soundtrack", - "soundtraks", "soundtracks", - "southampon", "southampton", - "southamton", "southampton", - "southerers", "southerners", - "southernes", "southerners", - "southerton", "southern", - "souveniers", "souvenirs", - "sovereigny", "sovereignty", - "sovereinty", "sovereignty", - "soverignty", "sovereignty", - "spartaniis", "spartans", - "spartanops", "spartans", - "specailist", "specialist", - "specailize", "specializes", - "specialice", "specialize", - "specialied", "specialized", - "specialies", "specializes", - "specialits", "specials", - "speciallly", "specially", - "speciallty", "specially", - "specialops", "specials", - "specialsts", "specialists", - "specialtys", "specials", - "specialzed", "specialized", - "specialzes", "specializes", - "specifices", "specifics", - "specifiing", "specifying", - "specifiyng", "specifying", - "speciliast", "specialists", - "specimines", "specimen", - "spectarors", "spectators", - "spectaters", "spectators", - "spectracal", "spectral", - "spectraply", "spectral", - "spectrolab", "spectral", - "speculatie", "speculative", - "speculatin", "speculation", - "speecheasy", "speeches", - "speicalist", "specialist", - "spiritualy", "spiritually", - "sponsorees", "sponsors", - "sponsorhip", "sponsorship", - "sponsorise", "sponsors", - "spontaneos", "spontaneous", - "spontaneus", "spontaneous", - "spontanous", "spontaneous", - "spoonfulls", "spoonfuls", - "spreadshet", "spreadsheet", - "springfeld", "springfield", - "springfied", "springfield", - "spriritual", "spiritual", - "squirrells", "squirrels", - "squirrelus", "squirrels", - "stabelized", "stabilized", - "stabilzied", "stabilized", - "stablility", "stability", - "stablizied", "stabilized", - "staggaring", "staggering", - "stakeboard", "skateboard", - "starighten", "straighten", - "starnation", "starvation", - "startegies", "strategies", - "startupbus", "startups", - "starwberry", "strawberry", - "statememts", "statements", - "statictics", "statistics", - "stationair", "stationary", - "statisitcs", "statistics", - "statistcal", "statistical", - "statistisk", "statistics", - "stauration", "saturation", - "stealthboy", "stealthy", - "stealthely", "stealthy", - "stealthify", "stealthy", - "stealthray", "stealthy", - "steeleries", "steelers", - "stereotipe", "stereotype", - "stereotpye", "stereotypes", - "steriotype", "stereotype", - "steroetype", "stereotype", - "sterotypes", "stereotypes", - "steryotype", "stereotype", - "stimilants", "stimulants", - "stimilated", "stimulated", - "stimualted", "stimulated", - "stimulatie", "stimulated", - "stimulatin", "stimulation", - "stimulaton", "stimulation", - "stimulents", "stimulants", - "stomrfront", "stormfront", - "storelines", "storylines", - "stormfornt", "stormfront", - "stormfromt", "stormfront", - "stornfront", "stormfront", - "stornghold", "stronghold", - "stradegies", "strategies", - "strageties", "strategies", - "straighted", "straightened", - "straightie", "straighten", - "straightin", "straighten", - "straigthen", "straighten", - "stranglove", "strangle", - "strangreal", "strangle", - "stratagies", "strategies", - "strategems", "strategies", - "strategice", "strategies", - "strategisk", "strategies", - "stravation", "starvation", - "strawbarry", "strawberry", - "strawbeary", "strawberry", - "strawbeery", "strawberry", - "strawbrary", "strawberry", - "strawburry", "strawberry", - "streaching", "stretching", - "streamtrue", "streamer", - "strechting", "stretching", - "strecthing", "stretching", - "stregnthen", "strengthen", - "streichung", "stretching", - "strenghten", "strengthen", - "strengsten", "strengthen", - "strengthes", "strengths", - "strengthin", "strengthen", - "stressende", "stressed", - "striaghten", "straighten", - "stromfront", "stormfront", - "stronkhold", "stronghold", - "stroylines", "storylines", - "structered", "structured", - "structrual", "structural", - "structurel", "structural", - "strucutral", "structural", - "strucutred", "structured", - "strucutres", "structures", - "strugglign", "struggling", - "strwaberry", "strawberry", - "sttutering", "stuttering", - "stupidfree", "stupider", - "stupiditiy", "stupidity", - "sturctural", "structural", - "sturctures", "structures", - "sturggling", "struggling", - "subarmines", "submarines", - "subcultuur", "subculture", - "subesquent", "subsequent", - "subisdized", "subsidized", - "subjectief", "subjective", - "subjectifs", "subjects", - "subjectivy", "subjectively", - "subjektive", "subjective", - "submariens", "submarines", - "submarinas", "submarines", - "submergerd", "submerged", - "submerines", "submarines", - "submisison", "submissions", - "submissies", "submissive", - "submissons", "submissions", - "submittion", "submitting", - "subsadized", "subsidized", - "subscirbed", "subscribed", - "subscirber", "subscribers", - "subscribar", "subscriber", - "subscribir", "subscriber", - "subscrible", "subscriber", - "subscriped", "subscribed", - "subscrubed", "subscribed", - "subscryber", "subscriber", - "subsedized", "subsidized", - "subsequant", "subsequent", - "subsidezed", "subsidized", - "subsidiced", "subsidized", - "subsidizng", "subsidizing", - "subsiduary", "subsidiary", - "subsiquent", "subsequent", - "subsittute", "substitutes", - "subsizided", "subsidized", - "subsrcibed", "subscribed", - "substanial", "substantial", - "substansen", "substances", - "substanser", "substances", - "substanses", "substances", - "substantie", "substantive", - "substatial", "substantial", - "substences", "substances", - "substitite", "substitute", - "substittue", "substitutes", - "substitude", "substitute", - "substitued", "substitute", - "substituer", "substitute", - "substitues", "substitutes", - "substiture", "substitute", - "substituto", "substitution", - "substituts", "substitutes", - "substracts", "subtracts", - "substutite", "substitutes", - "subsudized", "subsidized", - "subtitltes", "subtitle", - "succceeded", "succeeded", - "succcesses", "successes", - "succesfuly", "successfully", - "succesions", "succession", - "successing", "succession", - "successivo", "succession", - "sucesfully", "successfully", - "sucessfull", "successful", - "sucessfuly", "successfully", - "sudnerland", "sunderland", - "sufferered", "suffered", - "sufferring", "suffering", - "sufficiant", "sufficient", - "suggestied", "suggestive", - "suggestief", "suggestive", - "suggestons", "suggests", - "sumbarines", "submarines", - "sumbissive", "submissive", - "sumbitting", "submitting", - "summerized", "summarized", - "summorized", "summarized", - "summurized", "summarized", - "sunderlona", "sunderland", - "sunderlund", "sunderland", - "sungalsses", "sunglasses", - "sunglesses", "sunglasses", - "sunglinger", "gunslinger", - "sunscreeen", "sunscreen", - "superfical", "superficial", - "superfluos", "superfluous", - "superioara", "superior", - "superioare", "superior", - "superioris", "superiors", - "superivsor", "supervisors", - "supermaket", "supermarket", - "supermarkt", "supermarket", - "superouman", "superhuman", - "superposer", "superpowers", - "superviors", "supervisors", - "superviosr", "supervisors", - "supervisar", "supervisor", - "superviser", "supervisor", - "supervisin", "supervision", - "supervison", "supervision", - "supervsior", "supervisors", - "supperssor", "suppressor", - "supplament", "supplement", - "supplemant", "supplemental", - "supplemets", "supplements", - "supportare", "supporters", - "supporteur", "supporter", - "supportied", "supported", - "supportors", "supporters", - "supposdely", "supposedly", - "supposebly", "supposedly", - "supposidly", "supposedly", - "suppresion", "suppression", - "suppresors", "suppressor", - "suppressin", "suppression", - "suppressio", "suppressor", - "suppresson", "suppression", - "suprassing", "surpassing", - "supressing", "suppressing", - "supression", "suppression", - "supsension", "suspension", - "supsicions", "suspicions", - "supsicious", "suspicious", - "surounding", "surrounding", - "surplanted", "supplanted", - "surpressed", "suppressed", - "surprizing", "surprising", - "surrenderd", "surrendered", - "surrouding", "surrounding", - "surroundes", "surrounds", - "surroundig", "surroundings", - "survivours", "survivor", - "suseptable", "susceptible", - "suseptible", "susceptible", - "suspecions", "suspicions", - "suspecious", "suspicious", - "suspencion", "suspension", - "suspendeds", "suspense", - "suspention", "suspension", - "suspicians", "suspicions", - "suspiciois", "suspicions", - "suspicioso", "suspicions", - "suspicioun", "suspicion", - "suspicison", "suspicions", - "suspiciuos", "suspicions", - "suspicsion", "suspicions", - "suspisions", "suspicions", - "suspisious", "suspicious", - "suspitions", "suspicions", - "sustainble", "sustainable", - "swaetshirt", "sweatshirt", - "swearengin", "swearing", - "swearshirt", "sweatshirt", - "sweathsirt", "sweatshirt", - "sweatshits", "sweatshirt", - "sweatshort", "sweatshirt", - "sweatshrit", "sweatshirt", - "sweerheart", "sweetheart", - "sweetshart", "sweetheart", - "switcheasy", "switches", - "switzerand", "switzerland", - "symapthize", "sympathize", - "symbolisch", "symbolic", - "symbolisim", "symbolism", - "symetrical", "symmetrical", - "sympatheic", "sympathetic", - "sympathiek", "sympathize", - "sympathien", "sympathize", - "sympathtic", "sympathetic", - "sympathyze", "sympathize", - "sympethize", "sympathize", - "symphatize", "sympathize", - "symphonity", "symphony", - "sympothize", "sympathize", - "syncronous", "synchronous", - "synomymous", "synonymous", - "synomynous", "synonymous", - "synonamous", "synonymous", - "synonimous", "synonymous", - "synonmyous", "synonymous", - "synonomous", "synonymous", - "synonumous", "synonymous", - "synonynous", "synonymous", - "sypmathize", "sympathize", - "systamatic", "systematic", - "systemetic", "systematic", - "systemisch", "systemic", - "systimatic", "systematic", - "tabelspoon", "tablespoon", - "tablespons", "tablespoons", - "tablesppon", "tablespoon", - "tacitcally", "tactically", - "taiwanesse", "taiwanese", - "taligating", "tailgating", - "tantrumers", "tantrums", - "targetting", "targeting", - "teamfigths", "teamfights", - "teamifghts", "teamfights", - "teamspeack", "teamspeak", - "techicians", "technicians", - "techincian", "technician", - "techinican", "technician", - "techinques", "techniques", - "technicain", "technician", - "technicaly", "technically", - "technicans", "technicians", - "technichan", "technician", - "technicien", "technician", - "technicion", "technician", - "technitian", "technician", - "technqiues", "techniques", - "techtician", "technician", - "tehnically", "ethnically", - "telegrapgh", "telegraph", - "teleporing", "teleporting", - "televesion", "television", - "televisivo", "television", - "temafights", "teamfights", - "temerature", "temperature", - "temperatue", "temperature", - "temperment", "temperament", - "temperture", "temperature", - "templarios", "templars", - "templarius", "templars", - "temporaily", "temporarily", - "temporarly", "temporary", - "temptating", "temptation", - "temptetion", "temptation", - "tendancies", "tendencies", - "tendencias", "tendencies", - "tendencije", "tendencies", - "tendensies", "tendencies", - "tendincies", "tendencies", - "tensionors", "tensions", - "tentacreul", "tentacle", - "termanator", "terminator", - "termendous", "tremendous", - "termiantor", "terminator", - "termigator", "terminator", - "terminales", "terminals", - "terminalis", "terminals", - "terminarla", "terminal", - "terminarlo", "terminal", - "terminaron", "terminator", - "terminater", "terminator", - "terminolgy", "terminology", - "terorrists", "terrorists", - "terrerists", "terrorists", - "terrestial", "terrestrial", - "terriblely", "terribly", - "terriories", "territories", - "territoral", "territorial", - "territores", "territories", - "territoris", "territories", - "territorry", "territory", - "terrorisim", "terrorism", - "terrorsits", "terrorists", - "terrurists", "terrorists", - "testiclees", "testicles", - "testiclies", "testicle", - "testimoney", "testimony", - "thankyooou", "thankyou", - "themselfes", "themselves", - "themsevles", "themselves", - "themsleves", "themselves", - "theocracry", "theocracy", - "theologial", "theological", - "therapetic", "therapeutic", - "therepists", "therapists", - "theripists", "therapists", - "thermastat", "thermostat", - "thermistat", "thermostat", - "thermomter", "thermometer", - "theromstat", "thermostat", - "thorttling", "throttling", - "thorughout", "throughout", - "thouroghly", "thoroughly", - "threadened", "threaded", - "threatenes", "threatens", - "threatning", "threatening", - "threshhold", "threshold", - "throthling", "throttling", - "throtlling", "throttling", - "throughiut", "throughput", - "thubmnails", "thumbnails", - "thumbmails", "thumbnails", - "thunderbot", "thunderbolt", - "thunderolt", "thunderbolt", - "tighetning", "tightening", - "tightining", "tightening", - "tigthening", "tightening", - "tjpanishad", "upanishad", - "toothbruch", "toothbrush", - "toothbruth", "toothbrush", - "toothbursh", "toothbrush", - "toothrbush", "toothbrush", - "toppingest", "toppings", - "torchilght", "torchlight", - "torchlgiht", "torchlight", - "torchligth", "torchlight", - "torhclight", "torchlight", - "torrentbig", "torrenting", - "torrenters", "torrents", - "torrentors", "torrents", - "tortillera", "tortilla", - "tortillias", "tortilla", - "tortillita", "tortilla", - "tortilllas", "tortilla", - "torunament", "tournament", - "totalitara", "totalitarian", - "touchsceen", "touchscreen", - "touchscren", "touchscreen", - "touranment", "tournaments", - "tourmanent", "tournaments", - "tournamets", "tournaments", - "tournamnet", "tournament", - "tournemant", "tournament", - "tournement", "tournament", - "toxicitity", "toxicity", - "trafficing", "trafficking", - "trainwreak", "trainwreck", - "traitorise", "traitors", - "tramboline", "trampoline", - "tramploine", "trampoline", - "trampolene", "trampoline", - "tranformed", "transformed", - "tranistion", "transition", - "tranlsated", "translated", - "transalted", "translated", - "transaltes", "translates", - "transaltor", "translator", - "transation", "transition", - "transciprt", "transcripts", - "transcirpt", "transcripts", - "transcrips", "transcripts", - "transcrito", "transcript", - "transcrits", "transcripts", - "transcrpit", "transcript", - "transfered", "transferred", - "transferer", "transferred", - "transferes", "transfers", - "transferrs", "transfers", - "transferts", "transfers", - "transfomed", "transformed", - "transfored", "transformed", - "transforme", "transfer", - "transfroms", "transforms", - "transgeder", "transgender", - "transgener", "transgender", - "transicion", "transition", - "transision", "transition", - "transister", "transistor", - "transitons", "transitions", - "transitors", "transistor", - "transkript", "transcript", - "translater", "translator", - "translatin", "translations", - "translatio", "translator", - "translpant", "transplants", - "transluent", "translucent", - "transmited", "transmitted", - "transmiter", "transmitter", - "transmitor", "transistor", - "transmorgs", "transforms", - "transpalnt", "transplants", - "transphoic", "transphobic", - "transplain", "transplant", - "transplate", "transplant", - "transplats", "transplants", - "transpoder", "transported", - "transportr", "transporter", - "transsexal", "transsexual", - "transtator", "translator", - "tranzistor", "transistor", - "trasncript", "transcript", - "trasnforms", "transforms", - "trasnlated", "translated", - "trasnlator", "translator", - "trasnplant", "transplant", - "traveleres", "travelers", - "travelodge", "traveled", - "traverlers", "traverse", - "traversare", "traverse", - "traversier", "traverse", - "treasurery", "treasury", - "trememdous", "tremendous", - "tremondous", "tremendous", - "trespasing", "trespassing", - "trianwreck", "trainwreck", - "trochlight", "torchlight", - "trustworhy", "trustworthy", - "trustworty", "trustworthy", - "trustwothy", "trustworthy", - "tryannical", "tyrannical", - "tunraround", "turnaround", - "tupparware", "tupperware", - "turnapound", "turnaround", - "turthfully", "truthfully", - "tutoriales", "tutorials", - "tyrantical", "tyrannical", - "ubiqituous", "ubiquitous", - "ubiquotous", "ubiquitous", - "ubiqutious", "ubiquitous", - "ukrainains", "ukrainians", - "ukraineans", "ukrainians", - "ukrainiens", "ukrainians", - "ukraininas", "ukrainians", - "ukrianians", "ukrainians", - "ulitmately", "ultimately", - "ulterioara", "ulterior", - "ulterioare", "ulterior", - "ultimative", "ultimate", - "ultimatley", "ultimately", - "ultimatuum", "ultimatum", - "unanwsered", "unanswered", - "unasnwered", "unanswered", - "unattanded", "unattended", - "unattented", "unattended", - "unavailabe", "unavailable", - "unavailble", "unavailable", - "unavoidble", "unavoidable", - "unawnsered", "unanswered", - "unbalenced", "unbalanced", - "unballance", "unbalance", - "unbalnaced", "unbalanced", - "unbareable", "unbearable", - "unbeakable", "unbeatable", - "unbeareble", "unbearable", - "unbeatbale", "unbeatable", - "unbeateble", "unbeatable", - "unbeerable", "unbearable", - "unbeetable", "unbeatable", - "unbeknowst", "unbeknownst", - "unbreakble", "unbreakable", - "uncencored", "uncensored", - "uncensered", "uncensored", - "uncersored", "uncensored", - "uncertainy", "uncertainty", - "uncertanty", "uncertainty", - "uncesnored", "uncensored", - "uncomitted", "uncommitted", - "uncommited", "uncommitted", - "unconcious", "unconscious", - "unconscous", "unconscious", - "undebiably", "undeniably", - "undeinable", "undeniable", - "undeinably", "undeniably", - "undenaible", "undeniable", - "undenaibly", "undeniably", - "undenyable", "undeniable", - "undenyably", "undeniably", - "underbaker", "undertaker", - "undercling", "underlying", - "underfaker", "undertaker", - "undergated", "underrated", - "undergrand", "undergrad", - "undergroud", "underground", - "undergrund", "underground", - "undermimes", "undermines", - "underminde", "undermines", - "underminig", "undermining", - "underneeth", "underneath", - "underneith", "underneath", - "undernieth", "underneath", - "underpowed", "underpowered", - "underraged", "underrated", - "underraker", "undertaker", - "underrater", "undertaker", - "undersatnd", "understands", - "understadn", "understands", - "understans", "understands", - "understnad", "understands", - "understoon", "understood", - "understsnd", "understands", - "undertoker", "undertaker", - "undertsand", "understands", - "undertunes", "undertones", - "underwager", "underwater", - "underwares", "underwater", - "underwolrd", "underworld", - "underwoord", "underworld", - "underwrold", "underworld", - "underyling", "underlying", - "undesrtand", "understands", - "undoubtedy", "undoubtedly", - "undoubtely", "undoubtedly", - "undoubtley", "undoubtedly", - "uneccesary", "unnecessary", - "unecessary", "unnecessary", - "unedcuated", "uneducated", - "unedicated", "uneducated", - "unempolyed", "unemployed", - "unexplaind", "unexplained", - "unexplaned", "unexplained", - "unfamilair", "unfamiliar", - "unfamilier", "unfamiliar", - "unfinsihed", "unfinished", - "unfirendly", "unfriendly", - "unfortuate", "unfortunate", - "unfreindly", "unfriendly", - "unfriednly", "unfriendly", - "unfriently", "unfriendly", - "ungrapeful", "ungrateful", - "ungreatful", "ungrateful", - "unhealthly", "unhealthy", - "unicornios", "unicorns", - "unifnished", "unfinished", - "unihabited", "uninhabited", - "unilatreal", "unilateral", - "unimporant", "unimportant", - "unimpresed", "unimpressed", - "unimpressd", "unimpressed", - "uninsipred", "uninspired", - "uninspried", "uninspired", - "uninstaled", "uninstalled", - "uniquiness", "uniqueness", - "univercity", "university", - "univeristy", "university", - "universale", "universe", - "universaly", "universally", - "universels", "universes", - "universets", "universes", - "universite", "universities", - "universtiy", "university", - "unjustifed", "unjustified", - "unknowingy", "unknowingly", - "unknowinly", "unknowingly", - "unnecesary", "unnecessary", - "unofficail", "unofficial", - "unoffocial", "unofficial", - "unorginial", "unoriginal", - "unorignial", "unoriginal", - "unorigonal", "unoriginal", - "unplacable", "unplayable", - "unplaybale", "unplayable", - "unplayeble", "unplayable", - "unpleasent", "unpleasant", - "unpopulair", "unpopular", - "unproteced", "unprotected", - "unqiueness", "uniqueness", - "unqualifed", "unqualified", - "unrealesed", "unreleased", - "unrealible", "unreliable", - "unrealistc", "unrealistic", - "unrealitic", "unrealistic", - "unreasonal", "unreasonably", - "unrelaible", "unreliable", - "unreleated", "unreleased", - "unrelyable", "unreliable", - "unrepetant", "unrepentant", - "unrepetent", "unrepentant", - "unresponse", "unresponsive", - "unsencored", "uncensored", - "unsetlling", "unsettling", - "unsolicted", "unsolicited", - "unsubscibe", "unsubscribe", - "unsubscrbe", "unsubscribe", - "unsucesful", "unsuccessful", - "unsuprised", "unsurprised", - "unsuprized", "unsurprised", - "unviersity", "university", - "unwrittern", "unwritten", - "urkainians", "ukrainians", - "utlimately", "ultimately", - "utlrasound", "ultrasound", - "vaccinatie", "vaccinated", - "vaccineras", "vaccines", - "valentians", "valentines", - "valentiens", "valentines", - "valentimes", "valentines", - "valentinas", "valentines", - "valentinos", "valentines", - "valentones", "valentines", - "validitity", "validity", - "valnetines", "valentines", - "vandalisim", "vandalism", - "vasectomey", "vasectomy", - "vegatarian", "vegetarian", - "vegaterian", "vegetarian", - "vegeratian", "vegetarians", - "vegetairan", "vegetarians", - "vegetarain", "vegetarians", - "vegetarien", "vegetarian", - "vegetarion", "vegetarian", - "vegetatian", "vegetarian", - "vegeterian", "vegetarian", - "vegitables", "vegetables", - "vehemantly", "vehemently", - "vehemontly", "vehemently", - "veitnamese", "vietnamese", - "veiwership", "viewership", - "veiwpoints", "viewpoints", - "venezuella", "venezuela", - "verificato", "verification", - "verifyable", "verifiable", - "veritcally", "vertically", - "veritiable", "verifiable", - "vernecular", "vernacular", - "vernicular", "vernacular", - "versatiliy", "versatility", - "versatille", "versatile", - "versatilty", "versatility", - "versitlity", "versatility", - "vewiership", "viewership", - "vibratoare", "vibrator", - "vicitmized", "victimized", - "vicotrious", "victorious", - "victemized", "victimized", - "victomized", "victimized", - "victorinos", "victorious", - "victorinus", "victorious", - "victoriosa", "victorious", - "victorioso", "victorious", - "victoriuos", "victorious", - "victumized", "victimized", - "videogaems", "videogames", - "videojames", "videogames", - "vidoegames", "videogames", - "vientamese", "vietnamese", - "vietmanese", "vietnamese", - "vietnamees", "vietnamese", - "vietnamise", "vietnamese", - "viewpionts", "viewpoints", - "vigilantie", "vigilante", - "vigoruosly", "vigorously", - "vigourosly", "vigorously", - "villageois", "villages", - "vindicitve", "vindictive", - "vindictave", "vindictive", - "visibiltiy", "visibility", - "vitenamese", "vietnamese", - "vocabluary", "vocabulary", - "volatiltiy", "volatility", - "volativity", "volatility", - "volitality", "volatility", - "volleyboll", "volleyball", - "vollyeball", "volleyball", - "volonteers", "volunteers", - "volounteer", "volunteer", - "voluntairy", "voluntarily", - "voluntarly", "voluntary", - "voluntears", "volunteers", - "volunteeer", "volunteers", - "volunteerd", "volunteered", - "voluntered", "volunteered", - "vulernable", "vulnerable", - "vulnarable", "vulnerable", - "vulnerabil", "vulnerable", - "vulnurable", "vulnerable", - "vunlerable", "vulnerable", - "warrandyte", "warranty", - "warrantles", "warranties", - "warrenties", "warranties", - "washignton", "washington", - "waterlemon", "watermelon", - "watermalon", "watermelon", - "waterproff", "waterproof", - "wavelegnth", "wavelength", - "wavelenghs", "wavelength", - "wavelenght", "wavelength", - "weakensses", "weaknesses", - "weaknesess", "weaknesses", - "weathliest", "wealthiest", - "wedensdays", "wednesdays", - "wednesdsay", "wednesdays", - "wednessday", "wednesdays", - "wednsedays", "wednesdays", - "weightened", "weighted", - "welathiest", "wealthiest", - "wellignton", "wellington", - "wellingotn", "wellington", - "wendesdays", "wednesdays", - "wereabouts", "whereabouts", - "westbroook", "westbrook", - "westernese", "westerners", - "westerness", "westerners", - "westminser", "westminster", - "westminter", "westminster", - "whatosever", "whatsoever", - "whatseover", "whatsoever", - "whipsering", "whispering", - "whsipering", "whispering", - "widepsread", "widespread", - "wikileakes", "wikileaks", - "wilderniss", "wilderness", - "wildreness", "wilderness", - "willfullly", "willfully", - "winchestor", "winchester", - "windhsield", "windshield", - "windsheild", "windshield", - "windshiled", "windshield", - "wisconsion", "wisconsin", - "wishpering", "whispering", - "withdrawan", "withdrawn", - "withdrawel", "withdrawal", - "withdrawin", "withdrawn", - "withholdng", "withholding", - "withrdawal", "withdrawals", - "witnissing", "witnessing", - "wonderfull", "wonderful", - "wonderfuly", "wonderfully", - "wonderwand", "wonderland", - "worhsiping", "worshiping", - "workingest", "workings", - "workstaion", "workstation", - "workstaton", "workstation", - "worshippig", "worshipping", - "worshoping", "worshiping", - "wrestlewar", "wrestler", - "xenohpobic", "xenophobic", - "xenophibia", "xenophobia", - "xenophibic", "xenophobic", - "xenophonic", "xenophobic", - "xenophopia", "xenophobia", - "xenophopic", "xenophobic", - "xeonphobia", "xenophobia", - "xeonphobic", "xenophobic", - "yourselfes", "yourselves", - "yoursleves", "yourselves", - "zimbabwaen", "zimbabwe", - "zionistisk", "zionists", - "abandonig", "abandoning", - "abandonne", "abandonment", - "abanonded", "abandoned", - "abdomnial", "abdominal", - "abdonimal", "abdominal", - "aberation", "aberration", - "abnormaly", "abnormally", - "abodminal", "abdominal", - "abondoned", "abandoned", - "aborigene", "aborigine", - "aboslutes", "absolutes", - "abosrbing", "absorbing", - "abreviate", "abbreviate", - "abritrary", "arbitrary", - "abruptley", "abruptly", - "absailing", "abseiling", - "absloutes", "absolutes", - "absolutey", "absolutely", - "absolutly", "absolutely", - "absoultes", "absolutes", - "abstracto", "abstraction", - "absurdley", "absurdly", - "absuridty", "absurdity", - "abusrdity", "absurdity", - "academica", "academia", - "accademic", "academic", - "accalimed", "acclaimed", - "accelerar", "accelerator", - "accending", "ascending", - "accension", "accession", - "accidenty", "accidently", - "acclamied", "acclaimed", - "accliamed", "acclaimed", - "accomdate", "accommodate", - "accordeon", "accordion", - "accordian", "accordion", - "accoridng", "according", - "accountas", "accountants", - "accountat", "accountants", - "accoustic", "acoustic", - "accroding", "according", - "accuraccy", "accuracy", - "acftually", "factually", - "acheiving", "achieving", - "achieveds", "achieves", - "achillees", "achilles", - "achilleos", "achilles", - "achilleus", "achilles", - "achiveing", "achieving", - "acitvates", "activates", - "aclhemist", "alchemist", - "acomplish", "accomplish", - "acquisito", "acquisition", - "acronymes", "acronyms", - "acronymns", "acronyms", - "acsending", "ascending", - "acsension", "ascension", - "activaste", "activates", - "activatin", "activation", - "activelly", "actively", - "activisim", "activism", - "activisit", "activist", - "activites", "activities", - "actresess", "actresses", - "acusation", "causation", - "acutality", "actuality", - "adavanced", "advanced", - "adbominal", "abdominal", - "additonal", "additional", - "addoptive", "adoptive", - "addresing", "addressing", - "addtional", "additional", - "adhearing", "adhering", - "adherance", "adherence", - "adjectivs", "adjectives", - "adjustabe", "adjustable", - "administr", "administer", - "admitedly", "admittedly", - "adolecent", "adolescent", - "adovcated", "advocated", - "adovcates", "advocates", - "adquiring", "acquiring", - "adresable", "addressable", - "adressing", "addressing", - "aduiobook", "audiobook", - "advatange", "advantage", - "adventurs", "adventures", - "adveristy", "adversity", - "advertisy", "adversity", - "advisorys", "advisors", - "aeorspace", "aerospace", - "aeropsace", "aerospace", - "aerosapce", "aerospace", - "aersopace", "aerospace", - "aestethic", "aesthetic", - "aethistic", "atheistic", - "affiliato", "affiliation", - "affinitiy", "affinity", - "affirmate", "affirmative", - "affliated", "affiliated", - "africanas", "africans", - "africanos", "africans", - "aggegrate", "aggregate", - "aggresive", "aggressive", - "agnosticm", "agnosticism", - "agregates", "aggregates", - "agreggate", "aggregate", - "agrentina", "argentina", - "agression", "aggression", - "agressive", "aggressive", - "agressvie", "agressive", - "agruement", "arguement", - "agruments", "arguments", - "agurement", "arguement", - "ailenated", "alienated", - "airbourne", "airborne", - "aircrafts", "aircraft", - "airplance", "airplane", - "airrcraft", "aircraft", - "aksreddit", "askreddit", - "alcehmist", "alchemist", - "alchemsit", "alchemist", - "alchimest", "alchemist", - "alchmeist", "alchemist", - "alchoolic", "alcoholic", - "alcoholis", "alcoholics", - "alechmist", "alchemist", - "alegience", "allegiance", - "aleinated", "alienated", - "algoriths", "algorithms", - "algoritms", "algorithms", - "algorthim", "algorithm", - "algortihm", "algorithm", - "alignemnt", "alignment", - "alimunium", "aluminium", - "alingment", "alignment", - "allainces", "alliances", - "alledgely", "allegedly", - "allegence", "allegiance", - "alleivate", "alleviate", - "allievate", "alleviate", - "alliviate", "alleviate", - "allopones", "allophones", - "allthough", "although", - "almightly", "almighty", - "alocholic", "alcoholic", - "alogrithm", "algorithm", - "alphabeat", "alphabet", - "alrightey", "alrighty", - "alrightly", "alrighty", - "alrightty", "alrighty", - "alrington", "arlington", - "alrorythm", "algorithm", - "alterante", "alternate", - "alternatr", "alternator", - "althetics", "athletics", - "althought", "although", - "altruisim", "altruism", - "amateures", "amateurs", - "ambluance", "ambulance", - "ambuigity", "ambiguity", - "amendmant", "amendment", - "amercians", "americans", - "americain", "american", - "americams", "americas", - "americaps", "americas", - "americats", "americas", - "amibguity", "ambiguity", - "aminosity", "animosity", - "amrstrong", "armstrong", - "amublance", "ambulance", - "amunition", "ammunition", - "anachrist", "anarchist", - "analagous", "analogous", - "analitycs", "analytics", - "analtyics", "analytics", - "analyitcs", "analytics", - "analyseas", "analyses", - "analysees", "analyses", - "analysens", "analyses", - "analysise", "analyses", - "analystes", "analysts", - "analzying", "analyzing", - "anarchsim", "anarchism", - "anayltics", "analytics", - "anaylzing", "analyzing", - "ancedotal", "anecdotal", - "ancedotes", "anecdotes", - "ancestory", "ancestry", - "androgeny", "androgyny", - "androides", "androids", - "androidos", "androids", - "anecdotle", "anecdote", - "anecodtal", "anecdotal", - "anecodtes", "anecdotes", - "anectodal", "anecdotal", - "anectodes", "anecdotes", - "anedoctal", "anecdotal", - "anedoctes", "anecdotes", - "animostiy", "animosity", - "anitvirus", "antivirus", - "anlaytics", "analytics", - "anniversy", "anniversary", - "annointed", "anointed", - "annoucnes", "announces", - "annoyingy", "annoyingly", - "annoymous", "anonymous", - "annoynace", "annoyance", - "annyoance", "annoyance", - "anomisity", "animosity", - "anomolies", "anomalies", - "anomolous", "anomalous", - "anomynity", "anonymity", - "anomynous", "anonymous", - "anonimity", "anonymity", - "anonmyous", "anonymous", - "anonymoys", "anonymously", - "anorexiac", "anorexic", - "anorexica", "anorexia", - "anrachist", "anarchist", - "ansestors", "ancestors", - "antarctia", "antarctica", - "antennaes", "antennas", - "antiviurs", "antivirus", - "antivrius", "antivirus", - "antivuris", "antivirus", - "anwsering", "answering", - "anynomity", "anonymity", - "anynomous", "anonymous", - "aparthide", "apartheid", - "aparthied", "apartheid", - "apartmens", "apartments", - "apocalype", "apocalypse", - "apostrope", "apostrophe", - "apparenty", "apparently", - "appearane", "appearances", - "appenines", "apennines", - "apperance", "appearance", - "appetitie", "appetite", - "applaudes", "applause", - "applicato", "application", - "appreciae", "appreciates", - "apprentie", "apprentice", - "approachs", "approaches", - "apratheid", "apartheid", - "apsaragus", "asparagus", - "apsergers", "aspergers", - "aquainted", "acquainted", - "arbirtary", "arbitrary", - "arbritary", "arbitrary", - "arcehtype", "archetype", - "archetect", "architect", - "archetpye", "archetype", - "archetyps", "archetypes", - "architecs", "architects", - "archtypes", "archetypes", - "aregument", "arguement", - "areospace", "aerospace", - "argessive", "agressive", - "argeument", "arguement", - "arguabley", "arguably", - "arguablly", "arguably", - "arguement", "argument", - "arguemnet", "arguement", - "arguemnts", "arguments", - "argumeent", "arguement", - "arhtritis", "arthritis", - "aribtrary", "arbitrary", - "ariplanes", "airplanes", - "aristolte", "aristotle", - "aristotel", "aristotle", - "aritfacts", "artifacts", - "arlignton", "arlington", - "arlingotn", "arlington", - "armistace", "armistice", - "armstorng", "armstrong", - "arpatheid", "apartheid", - "arthirtis", "arthritis", - "artifcats", "artifacts", - "artifical", "artificial", - "artillary", "artillery", - "arugement", "arguement", - "arugments", "arguments", - "asapragus", "asparagus", - "asbestoes", "asbestos", - "asborbing", "absorbing", - "asburdity", "absurdity", - "ascendend", "ascended", - "ascneding", "ascending", - "ascnesion", "ascension", - "asethetic", "aesthetic", - "asnwering", "answering", - "asociated", "associated", - "assasined", "assassinated", - "assassian", "assassin", - "assassine", "assassinate", - "assasssin", "assassins", - "assaultes", "assaults", - "assembeld", "assembled", - "assembley", "assembly", - "assemblie", "assemble", - "assisnate", "assassinate", - "assistans", "assistants", - "assistsnt", "assistants", - "assmebled", "assembled", - "associato", "association", - "assoicate", "associate", - "asssasins", "assassins", - "assualted", "assaulted", - "assulated", "assaulted", - "asteorids", "asteroids", - "astericks", "asterisk", - "asteriods", "asteroids", - "astroanut", "astronaut", - "astronuat", "astronaut", - "astrounat", "astronaut", - "asuterity", "austerity", - "atempting", "attempting", - "atheltics", "athletics", - "atheneans", "athenians", - "athesitic", "atheistic", - "athetlics", "athletics", - "athiestic", "atheistic", - "athleticm", "athleticism", - "atmosphir", "atmospheric", - "atributed", "attributed", - "atributes", "attributes", - "atrifacts", "artifacts", - "atrillery", "artillery", - "atrittion", "attrition", - "attachmet", "attachments", - "attaindre", "attainder", - "attemting", "attempting", - "attemtped", "attempted", - "attendent", "attendant", - "attension", "attention", - "attirbute", "attribute", - "attirtion", "attrition", - "attmepted", "attempted", - "attractes", "attracts", - "attractin", "attraction", - "attributo", "attribution", - "attributs", "attributes", - "attritube", "attribute", - "auctionrs", "auctions", - "auidobook", "audiobook", - "auromated", "automated", - "australin", "australians", - "authroity", "authority", - "autoattak", "autoattack", - "autogrpah", "autograph", - "autonomos", "autonomous", - "auxillary", "auxiliary", - "avaialble", "available", - "availible", "available", - "avalaible", "available", - "avaliable", "available", - "averageed", "averaged", - "avialable", "available", - "awakenend", "awakened", - "awesomley", "awesomely", - "awkawrdly", "awkwardly", - "awnsering", "answering", - "bacehlors", "bachelors", - "bachelour", "bachelor", - "bachleors", "bachelors", - "bacholers", "bachelors", - "backdooor", "backdoor", - "backfeild", "backfield", - "backfiled", "backfield", - "backgroud", "background", - "backpakcs", "backpacks", - "badnwagon", "bandwagon", - "badnwidth", "bandwidth", - "balckjack", "blackjack", - "balcklist", "blacklist", - "balitmore", "baltimore", - "ballisitc", "ballistic", - "ballsitic", "ballistic", - "balsphemy", "blasphemy", - "bandiwdth", "bandwidth", - "bandwdith", "bandwidth", - "bandwidht", "bandwidth", - "bandwitdh", "bandwidth", - "bankrupcy", "bankruptcy", - "bankrupty", "bankruptcy", - "banruptcy", "bankruptcy", - "baordwalk", "boardwalk", - "barabrian", "barbarian", - "barbarain", "barbarian", - "barbarina", "barbarian", - "barcelets", "bracelets", - "barcleona", "barcelona", - "bareclona", "barcelona", - "barrackus", "barracks", - "bascially", "basically", - "bastardes", "bastards", - "bastardos", "bastards", - "bastardus", "bastards", - "bathrooom", "bathroom", - "batlimore", "baltimore", - "battailon", "battalion", - "battlaion", "battalion", - "beahviour", "behaviour", - "beauitful", "beautiful", - "beautifyl", "beautifully", - "becnhmark", "benchmark", - "becomeing", "becoming", - "becomming", "becoming", - "beehtoven", "beethoven", - "begginers", "beginners", - "beggining", "beginning", - "begininng", "beginning", - "beginnins", "beginnings", - "behaivors", "behaviors", - "behaivour", "behaviour", - "behavoirs", "behaviors", - "behavoiur", "behaviour", - "behvaiour", "behaviour", - "beleiving", "believing", - "beliveing", "believing", - "belssings", "blessings", - "bemusemnt", "bemusement", - "benchamrk", "benchmark", - "benchmars", "benchmarks", - "benedicat", "benedict", - "benedickt", "benedict", - "benghazhi", "benghazi", - "benghazzi", "benghazi", - "bergamont", "bergamot", - "berkelely", "berkeley", - "bersekrer", "berserker", - "berskerer", "berserker", - "beseiging", "besieging", - "bestialiy", "bestiality", - "beuatiful", "beautiful", - "biginning", "beginning", - "bigrading", "brigading", - "billbaord", "billboard", - "billboars", "billboards", - "binominal", "binomial", - "birgading", "brigading", - "birghtest", "brightest", - "birhtdays", "birthdays", - "bitcoints", "bitcoins", - "blackbery", "blackberry", - "blackhaws", "blackhawks", - "blackshit", "blacksmith", - "blanketts", "blankets", - "blapshemy", "blasphemy", - "blashpemy", "blasphemy", - "blaspehmy", "blasphemy", - "blasphmey", "blasphemy", - "blatanlty", "blatantly", - "blatimore", "baltimore", - "bleuberry", "blueberry", - "bleutooth", "bluetooth", - "blisteres", "blisters", - "blizzcoin", "blizzcon", - "blockchan", "blockchain", - "blockeras", "blockers", - "bloodbore", "bloodborne", - "boardband", "broadband", - "boardcast", "broadcast", - "bodyweigt", "bodyweight", - "bookamrks", "bookmarks", - "bookmakrs", "bookmarks", - "bookmarkd", "bookmarked", - "boradband", "broadband", - "boradcast", "broadcast", - "boradwalk", "boardwalk", - "bouregois", "bourgeois", - "bourgeios", "bourgeois", - "bourgoeis", "bourgeois", - "boyfirend", "boyfriend", - "boyfreind", "boyfriend", - "boyfriens", "boyfriends", - "brabarian", "barbarian", - "bracelona", "barcelona", - "braodband", "broadband", - "braodcast", "broadcast", - "brazilias", "brazilians", - "breakdows", "breakdowns", - "breserker", "berserker", - "bretheren", "brethren", - "bridaging", "brigading", - "brightern", "brighten", - "brigthest", "brightest", - "brilliany", "brilliantly", - "brithdays", "birthdays", - "broadwalk", "boardwalk", - "bruiseres", "bruisers", - "brunettte", "brunette", - "brusseles", "brussels", - "brussells", "brussels", - "brutailty", "brutality", - "brutallly", "brutally", - "buddhisim", "buddhism", - "buddihsts", "buddhists", - "buddishts", "buddhists", - "buhddists", "buddhists", - "buidlings", "buildings", - "bulidings", "buildings", - "burgunday", "burgundy", - "burgundry", "burgundy", - "burritoes", "burritos", - "burtality", "brutality", - "busineses", "business", - "businessa", "businessman", - "businesse", "businessmen", - "businesss", "businesses", - "bussiness", "business", - "buthcered", "butchered", - "butterlfy", "butterfly", - "cacausian", "caucasian", - "caclulate", "calculate", - "cacuasian", "caucasian", - "caculater", "calculator", - "cafeteira", "cafeteria", - "cafetiera", "cafeteria", - "caffeinne", "caffeine", - "calcualte", "calculate", - "californa", "california", - "caluclate", "calculate", - "calulated", "calculated", - "calulater", "calculator", - "cambirdge", "cambridge", - "cambrdige", "cambridge", - "cambrigde", "cambridge", - "camoflage", "camouflage", - "campagins", "campaigns", - "campaings", "campaigns", - "campiagns", "campaigns", - "campusers", "campuses", - "camrbidge", "cambridge", - "canadains", "canadians", - "candadate", "candidate", - "candidats", "candidates", - "cannister", "canister", - "cannoical", "canonical", - "canoncial", "canonical", - "capactior", "capacitor", - "capicator", "capacitor", - "capitalis", "capitals", - "caprenter", "carpenter", - "capsulers", "capsules", - "capsulets", "capsules", - "carachter", "character", - "cardbaord", "cardboard", - "cardborad", "cardboard", - "cardianls", "cardinals", - "cardnials", "cardinals", - "caridnals", "cardinals", - "carmalite", "carmelite", - "carnberry", "cranberry", - "carolinia", "carolina", - "carpetner", "carpenter", - "carptener", "carpenter", - "carribean", "caribbean", - "cartdrige", "cartridge", - "cartilege", "cartilage", - "cartirdge", "cartridge", - "cartrdige", "cartridge", - "cartrigde", "cartridge", - "casaulity", "causality", - "cashieres", "cashiers", - "cassawory", "cassowary", - "cassettte", "cassette", - "casuation", "causation", - "cataclsym", "cataclysm", - "cataclyms", "cataclysm", - "catacylsm", "cataclysm", - "catacyslm", "cataclysm", - "catalcysm", "cataclysm", - "catalgoue", "catalogue", - "cathderal", "cathedral", - "catherdal", "cathedral", - "cathloics", "catholics", - "cathredal", "cathedral", - "caucaisan", "caucasian", - "caucasain", "caucasian", - "causacian", "caucasian", - "causailty", "causality", - "celebirty", "celebrity", - "celebrato", "celebration", - "celebrite", "celebrities", - "celesital", "celestial", - "celestail", "celestial", - "cementary", "cemetery", - "cemetarey", "cemetery", - "cenitpede", "centipede", - "centepide", "centipede", - "centipeed", "centipede", - "centruies", "centuries", - "centuties", "centuries", - "cerebrawl", "cerebral", - "certanity", "certainty", - "certianty", "certainty", - "cesspoool", "cesspool", - "chairmain", "chairman", - "challange", "challenge", - "challengr", "challenger", - "challengs", "challenges", - "chameloen", "chameleon", - "champagen", "champagne", - "champange", "champagne", - "chandlure", "chandler", - "changable", "changeable", - "charactor", "character", - "chatedral", "cathedral", - "chatolics", "catholics", - "checkmeat", "checkmate", - "checkpoit", "checkpoints", - "chekcmate", "checkmate", - "chemestry", "chemistry", - "chemicaly", "chemically", - "chemsitry", "chemistry", - "chernboyl", "chernobyl", - "chernobly", "chernobyl", - "chernoybl", "chernobyl", - "chernyobl", "chernobyl", - "cheronbyl", "chernobyl", - "chidlfree", "childfree", - "chidlrens", "childrens", - "chihauhua", "chihuahua", - "chihuahau", "chihuahua", - "childbird", "childbirth", - "childerns", "childrens", - "childisch", "childish", - "childresn", "childrens", - "chirstian", "christian", - "chirstmas", "christmas", - "chiuhahua", "chihuahua", - "chlidfree", "childfree", - "chlidrens", "childrens", - "chocloate", "chocolate", - "chocoalte", "chocolate", - "chocolats", "chocolates", - "chocolste", "chocolates", - "cholocate", "chocolate", - "chrenobyl", "chernobyl", - "chrisitan", "christian", - "christain", "christian", - "christams", "christmas", - "chrsitian", "christian", - "chrsitmas", "christmas", - "churchers", "churches", - "cigaretts", "cigarettes", - "cigeratte", "cigarette", - "cilivians", "civilians", - "cilpboard", "clipboard", - "cilynders", "cylinders", - "circuitos", "circuits", - "ciriculum", "curriculum", - "cirticise", "criticise", - "civilains", "civilians", - "civillian", "civilian", - "classicos", "classics", - "classicus", "classics", - "classifiy", "classify", - "cleanisng", "cleansing", - "cleasning", "cleansing", - "clikcbait", "clickbait", - "clinicaly", "clinically", - "clipbaord", "clipboard", - "clitories", "clitoris", - "clitorios", "clitoris", - "clitorius", "clitoris", - "clucthing", "clutching", - "clutchign", "clutching", - "cluthcing", "clutching", - "coca cola", "coca-cola", - "cockatils", "cocktails", - "cocktials", "cocktails", - "cognizent", "cognizant", - "colateral", "collateral", - "collabore", "collaborate", - "collasped", "collapsed", - "collaspes", "collapses", - "colleauge", "colleague", - "collectes", "collects", - "collectie", "collective", - "collecton", "collection", - "collectos", "collectors", - "collegaue", "colleague", - "collegues", "colleagues", - "collisson", "collisions", - "collonade", "colonnade", - "collonies", "colonies", - "collpased", "collapsed", - "collpases", "collapses", - "colombina", "colombia", - "columbina", "columbia", - "comapnies", "companies", - "combatans", "combatants", - "combinato", "combination", - "combusion", "combustion", - "comestics", "cosmetics", - "comisions", "commissions", - "comission", "commission", - "comitting", "committing", - "commandes", "commands", - "commentar", "commentator", - "commentes", "commenters", - "commercie", "commerce", - "commision", "commission", - "commiteed", "commited", - "commiting", "committing", - "commitmet", "commitments", - "commongly", "commonly", - "communiss", "communists", - "communite", "communities", - "communits", "communist", - "communsim", "communism", - "compaines", "companies", - "compalins", "complains", - "compalint", "compliant", - "comparisn", "comparisons", - "compeltes", "completes", - "competant", "competent", - "competend", "competed", - "competion", "competition", - "competive", "competitive", - "compilant", "compliant", - "compilare", "compiler", - "compilato", "compilation", - "compitent", "competent", - "complaind", "complained", - "complaing", "complaining", - "completen", "complement", - "completey", "completely", - "completin", "completion", - "complians", "complains", - "componant", "component", - "comprable", "comparable", - "compresas", "compress", - "compreses", "compress", - "compteurs", "computers", - "comptuers", "computers", - "computato", "computation", - "comradets", "comrades", - "comsetics", "cosmetics", - "conanical", "canonical", - "conatiner", "container", - "concelaed", "concealed", - "concelaer", "concealer", - "concelear", "concealer", - "concensus", "consensus", - "conceptos", "concepts", - "conceptul", "conceptual", - "concernig", "concerning", - "concertas", "concerts", - "concevied", "conceived", - "conciders", "considers", - "concieted", "conceited", - "concieved", "conceived", - "conclusie", "conclusive", - "concsious", "conscious", - "concurret", "concurrent", - "condamned", "condemned", - "condemend", "condemned", - "condemmed", "condemned", - "condemnig", "condemning", - "condenmed", "condemned", - "condesend", "condensed", - "condesned", "condensed", - "condmened", "condemned", - "conection", "connection", - "conenctor", "connector", - "conferene", "conferences", - "confessin", "confession", - "confideny", "confidently", - "confilcts", "conflicts", - "confimred", "confirmed", - "confirmas", "confirms", - "conflcits", "conflicts", - "confrimed", "confirmed", - "congitive", "cognitive", - "conlcuded", "concluded", - "connectes", "connects", - "connectit", "connecticut", - "connectos", "connectors", - "conquerer", "conqueror", - "consdider", "consider", - "consensul", "consensual", - "conserned", "concerned", - "consicous", "conscious", - "considerd", "considered", - "considert", "considerate", - "consisent", "consistent", - "consistes", "consists", - "consolato", "consolation", - "consolide", "consolidate", - "consonent", "consonant", - "constanly", "constantly", - "constanst", "constants", - "constanty", "constantly", - "constasnt", "constants", - "constitue", "constitutes", - "constrait", "constraints", - "construcs", "constructs", - "construde", "construed", - "construst", "constructs", - "constured", "construed", - "consulant", "consultant", - "consultat", "consultant", - "consumate", "consummate", - "contactes", "contacts", - "contactos", "contacts", - "contagios", "contagious", - "containes", "contains", - "containig", "containing", - "containts", "contains", - "contemple", "contemplate", - "contendor", "contender", - "contentas", "contents", - "contentes", "contents", - "contentos", "contents", - "contestas", "contests", - "contestat", "contestants", - "contestes", "contests", - "contextes", "contexts", - "contextos", "contexts", - "contianer", "container", - "contibute", "contribute", - "contigent", "contingent", - "continant", "continental", - "continens", "continents", - "continous", "continuous", - "continuos", "continuous", - "continute", "continue", - "contiunal", "continual", - "contracto", "contraction", - "contribue", "contribute", - "contribuo", "contributor", - "controlas", "controls", - "controled", "controlled", - "controles", "controls", - "controlls", "controls", - "convenant", "covenant", - "convencen", "convenience", - "conveniet", "convenient", - "conversie", "converse", - "conversin", "conversions", - "convertie", "convertible", - "convertis", "converts", - "cooldwons", "cooldowns", - "coordinar", "coordinator", - "copenhagn", "copenhagen", - "coprorate", "corporate", - "copywrite", "copyright", - "corcodile", "crocodile", - "corparate", "corporate", - "corproate", "corporate", - "correclty", "correctly", - "correctin", "correction", - "correlato", "correlation", - "corridoor", "corridor", - "corruptin", "corruption", - "corssfire", "crossfire", - "corsshair", "crosshair", - "corsspost", "crosspost", - "coruching", "crouching", - "cosemtics", "cosmetics", - "costumise", "costumes", - "counciles", "councils", - "councills", "councils", - "councilos", "councils", - "countains", "contains", - "counteres", "counters", - "countires", "countries", - "courching", "crouching", - "courtesey", "courtesy", - "courtesty", "courtesy", - "coururier", "courier", - "coutnered", "countered", - "crapenter", "carpenter", - "creativey", "creatively", - "creedence", "credence", - "crhistmas", "christmas", - "cricketts", "crickets", - "criminaly", "criminally", - "critereon", "criterion", - "criterias", "criteria", - "criticaly", "critically", - "criticies", "criticise", - "criticisn", "criticising", - "critisice", "criticise", - "critisicm", "criticism", - "critising", "criticising", - "critisism", "criticism", - "critisize", "criticise", - "critizing", "criticizing", - "crosshiar", "crosshair", - "crossifre", "crossfire", - "crticised", "criticised", - "crusdaers", "crusaders", - "crutchers", "crutches", - "crystalls", "crystals", - "crystalus", "crystals", - "crystalys", "crystals", - "cuacasian", "caucasian", - "cuasality", "causality", - "culitvate", "cultivate", - "culturaly", "culturally", - "culturels", "cultures", - "curiostiy", "curiosity", - "curisoity", "curiosity", - "currenlty", "currently", - "curriculm", "curriculum", - "cursaders", "crusaders", - "custcenes", "cutscenes", - "cutsceens", "cutscenes", - "cutscence", "cutscene", - "cutsences", "cutscenes", - "cyclinder", "cylinder", - "cyclistes", "cyclists", - "cylindres", "cylinders", - "cynicisim", "cynicism", - "dahsboard", "dashboard", - "dalmation", "dalmatian", - "dangeroys", "dangerously", - "dashbaord", "dashboard", - "daugthers", "daughters", - "davantage", "advantage", - "deadlfits", "deadlifts", - "deadpoool", "deadpool", - "dealershp", "dealerships", - "deathmath", "deathmatch", - "decalring", "declaring", - "decendant", "descendant", - "decendent", "descendant", - "decipting", "depicting", - "deciption", "depiction", - "decisivie", "decisive", - "declarase", "declares", - "declarees", "declares", - "decoratie", "decorative", - "decoratin", "decorations", - "decpetion", "deception", - "decpetive", "deceptive", - "decribing", "describing", - "decsended", "descended", - "deductibe", "deductible", - "defaintly", "defiantly", - "defaltion", "deflation", - "defanitly", "defiantly", - "defeintly", "definetly", - "defendent", "defendant", - "defensese", "defenseless", - "defianlty", "defiantly", - "deficeint", "deficient", - "deficieny", "deficiency", - "deficites", "deficits", - "definance", "defiance", - "definatey", "definately", - "definatly", "definitely", - "definetly", "definitely", - "definetyl", "definetly", - "definilty", "definitly", - "definitie", "definitive", - "definitin", "definitions", - "definitly", "definitely", - "definiton", "definition", - "definitve", "definite", - "definityl", "definitly", - "definltey", "definetly", - "defintaly", "defiantly", - "defintily", "definitly", - "defintion", "definition", - "defintley", "definetly", - "defitenly", "definetly", - "defitinly", "definitly", - "defitnaly", "defiantly", - "defitnely", "definetly", - "deflectin", "deflection", - "defnietly", "definetly", - "degeneret", "degenerate", - "degradato", "degradation", - "degradead", "degraded", - "degrassie", "degrasse", - "degrassse", "degrasse", - "deifnetly", "definetly", - "deifnitly", "definitly", - "deisgners", "designers", - "delagates", "delegates", - "delcaring", "declaring", - "delcining", "declining", - "delegatie", "delegate", - "delerious", "delirious", - "delfation", "deflation", - "deliveres", "delivers", - "deliverys", "delivers", - "delpoying", "deploying", - "demcorats", "democrats", - "deminsion", "dimension", - "democarcy", "democracy", - "democract", "democrat", - "demonstre", "demonstrate", - "denominar", "denominator", - "dentistas", "dentists", - "dentistes", "dentists", - "deomcrats", "democrats", - "deopsited", "deposited", - "deparment", "department", - "departmet", "departments", - "depciting", "depicting", - "depcition", "depiction", - "depection", "deception", - "depedency", "dependency", - "depicitng", "depicting", - "depiciton", "depiction", - "deplyoing", "deploying", - "depoisted", "deposited", - "depolying", "deploying", - "depositas", "deposits", - "deposites", "deposits", - "depositis", "deposits", - "depositos", "deposits", - "depostied", "deposited", - "depressie", "depressive", - "depressin", "depression", - "depserate", "desperate", - "depsoited", "deposited", - "descirbes", "describes", - "descision", "decision", - "desginers", "designers", - "desgining", "designing", - "desicions", "decisions", - "designade", "designated", - "designato", "designation", - "desingage", "disengage", - "desingers", "designers", - "desinging", "designing", - "desktopos", "desktops", - "desparate", "desperate", - "desperato", "desperation", - "despoited", "deposited", - "desriable", "desirable", - "dessigned", "designed", - "destinato", "destination", - "destoryed", "destroyed", - "destoryer", "destroyer", - "destroyes", "destroys", - "destructo", "destruction", - "destryoed", "destroyed", - "destryoer", "destroyer", - "desuction", "seduction", - "detailled", "detailed", - "detatched", "detached", - "detectivs", "detectives", - "deteriate", "deteriorate", - "determing", "determining", - "determins", "determines", - "developrs", "develops", - "diabetees", "diabetes", - "diablical", "diabolical", - "diagonaal", "diagonal", - "diagonsed", "diagnosed", - "diagonsis", "diagnosis", - "diagramas", "diagrams", - "diagramms", "diagrams", - "dialectes", "dialects", - "dialectos", "dialects", - "diarrheoa", "diarrhea", - "diasbling", "disabling", - "dichomoty", "dichotomy", - "dicovered", "discovered", - "dictaters", "dictates", - "dictionay", "dictionary", - "difenitly", "definitly", - "diferrent", "different", - "differene", "differences", - "differens", "differences", - "differeny", "differently", - "difficuly", "difficulty", - "diffucult", "difficult", - "dificulty", "difficulty", - "diganosed", "diagnosed", - "diganosis", "diagnosis", - "dimenions", "dimensions", - "dimention", "dimension", - "dimesnion", "dimension", - "diminishs", "diminishes", - "dinasours", "dinosaurs", - "dinosuars", "dinosaurs", - "dinsoaurs", "dinosaurs", - "dionsaurs", "dinosaurs", - "diphtongs", "diphthongs", - "dipthongs", "diphthongs", - "direcotry", "directory", - "directoty", "directory", - "directroy", "directory", - "disaprity", "disparity", - "disastros", "disastrous", - "disatrous", "disastrous", - "disbaling", "disabling", - "disbeleif", "disbelief", - "disbelife", "disbelief", - "disciplen", "disciplines", - "disclamer", "disclaimer", - "disclosue", "disclosure", - "disconnet", "disconnect", - "discosure", "discourse", - "discoverd", "discovered", - "discovere", "discoveries", - "discredid", "discredited", - "discribed", "described", - "discribes", "describes", - "discussin", "discussion", - "diserable", "desirable", - "disgarees", "disagrees", - "disgiused", "disguised", - "disgusied", "disguised", - "disgustes", "disgusts", - "disgustos", "disgusts", - "disgustus", "disgusts", - "dishonesy", "dishonesty", - "dishonord", "dishonored", - "disicples", "disciples", - "dismantel", "dismantle", - "dismisals", "dismissal", - "disnegage", "disengage", - "dispairty", "disparity", - "dispalyed", "displayed", - "dispartiy", "disparity", - "dispenced", "dispensed", - "dispeners", "dispenser", - "displayes", "displays", - "disruptin", "disruption", - "dissapear", "disappear", - "dissarray", "disarray", - "dissmisal", "dismissal", - "disspiate", "dissipate", - "distincte", "distinctive", - "distrcits", "districts", - "distribue", "distributed", - "distrubed", "disturbed", - "distrupts", "distrust", - "disturben", "disturbance", - "diverisfy", "diversify", - "diveristy", "diversity", - "diverstiy", "diversity", - "dividened", "dividend", - "divinitiy", "divinity", - "doccument", "document", - "docrtines", "doctrines", - "docuhebag", "douchebag", - "dogdammit", "goddammit", - "dogfather", "godfather", - "dolphines", "dolphins", - "domecracy", "democracy", - "domecrats", "democrats", - "domiantes", "dominates", - "dominatin", "domination", - "dominaton", "domination", - "dominiant", "dominant", - "donwgrade", "downgrade", - "donwloads", "downloads", - "donwsides", "downsides", - "donwvoted", "downvoted", - "donwvotes", "downvotes", - "doublelit", "doublelift", - "doucehbag", "douchebag", - "downgarde", "downgrade", - "downlaods", "downloads", - "downloaad", "download", - "downovted", "downvoted", - "dravadian", "dravidian", - "drummless", "drumless", - "dsyphoria", "dysphoria", - "dsytopian", "dystopian", - "duaghters", "daughters", - "duplicats", "duplicates", - "durabiliy", "durability", - "dynamicus", "dynamics", - "dypshoria", "dysphoria", - "dyshporia", "dysphoria", - "dysoptian", "dystopian", - "dysphoira", "dysphoria", - "dysphroia", "dysphoria", - "dyspohria", "dysphoria", - "dyspotian", "dystopian", - "dystopain", "dystopian", - "dystpoian", "dystopian", - "eachohter", "eachother", - "eachotehr", "eachother", - "eachtoher", "eachother", - "earpluggs", "earplugs", - "earthboud", "earthbound", - "eastwoood", "eastwood", - "eastwoord", "eastwood", - "ecclectic", "eclectic", - "ecomonics", "economics", - "edficient", "deficient", - "effecient", "efficient", - "efficeint", "efficient", - "efficency", "efficiency", - "efficieny", "efficiency", - "effulence", "effluence", - "egalitara", "egalitarian", - "egpytians", "egyptians", - "egyptains", "egyptians", - "egytpians", "egyptians", - "ehtically", "ethically", - "ehtnicity", "ethnicity", - "eighteeen", "eighteen", - "eitquette", "etiquette", - "ejacualte", "ejaculate", - "electivre", "elective", - "electorns", "electrons", - "electrial", "electrical", - "electricy", "electricity", - "electroal", "electoral", - "elementay", "elementary", - "elepahnts", "elephants", - "eliminase", "eliminates", - "eliminato", "elimination", - "ellignton", "ellington", - "ellingotn", "ellington", - "eloquenty", "eloquently", - "elsehwere", "elsewhere", - "emapthize", "empathize", - "embarress", "embarrassed", - "emmisarry", "emissary", - "emmisions", "emissions", - "emmitting", "emitting", - "empahsize", "emphasize", - "emperical", "empirical", - "emphaised", "emphasised", - "emphatize", "empathize", - "emphazise", "emphasize", - "emphysyma", "emphysema", - "empitness", "emptiness", - "employeer", "employer", - "employeur", "employer", - "empolyees", "employees", - "emtpiness", "emptiness", - "emualtion", "emulation", - "enahncing", "enhancing", - "enchantig", "enchanting", - "enclousre", "enclosure", - "enclsoure", "enclosure", - "encolsure", "enclosure", - "encompase", "encompass", - "encounted", "encountered", - "encrpyted", "encrypted", - "encrytped", "encrypted", - "encyrpted", "encrypted", - "endangerd", "endangered", - "enevlopes", "envelopes", - "enforcees", "enforces", - "engagemet", "engagements", - "engagment", "engagement", - "engieneer", "engineer", - "engineeer", "engineer", - "engineerd", "engineered", - "enhacning", "enhancing", - "enhanceds", "enhances", - "enligthen", "enlighten", - "enourmous", "enormous", - "ensconsed", "ensconced", - "enthicity", "ethnicity", - "enthusiam", "enthusiasm", - "enthusiat", "enthusiast", - "entirelly", "entirely", - "entitlied", "entitled", - "enveloppe", "envelope", - "epidsodes", "episodes", - "epilepsey", "epilepsy", - "epiphanny", "epiphany", - "episonage", "espionage", - "epscially", "specially", - "epsionage", "espionage", - "eqautions", "equations", - "equialent", "equivalent", - "equivalet", "equivalents", - "ermington", "remington", - "erroenous", "erroneous", - "escalatie", "escalate", - "escalatin", "escalation", - "esitmated", "estimated", - "esitmates", "estimates", - "eslewhere", "elsewhere", - "especialy", "especially", - "espianoge", "espionage", - "espinoage", "espionage", - "espoinage", "espionage", - "esponiage", "espionage", - "espressso", "espresso", - "essencial", "essential", - "essentail", "essential", - "essentias", "essentials", - "essentual", "essential", - "essesital", "essential", - "estiamted", "estimated", - "estiamtes", "estimates", - "estimatin", "estimation", - "ethcially", "ethically", - "ethincity", "ethnicity", - "ethnicaly", "ethnically", - "ethniticy", "ethnicity", - "etmyology", "etymology", - "euclidian", "euclidean", - "euorpeans", "europeans", - "euphoriac", "euphoric", - "euphorica", "euphoria", - "europenas", "europeans", - "europians", "europeans", - "eurpoeans", "europeans", - "evangelia", "evangelical", - "evelation", "elevation", - "evenlopes", "envelopes", - "eventally", "eventually", - "eventualy", "eventually", - "everthing", "everything", - "evertyime", "everytime", - "everwhere", "everywhere", - "everyoens", "everyones", - "everyteim", "everytime", - "everytiem", "everytime", - "everyting", "everything", - "eveyrones", "everyones", - "evreyones", "everyones", - "evreytime", "everytime", - "exagerate", "exaggerate", - "exahusted", "exhausted", - "exapnsive", "expansive", - "exauhsted", "exhausted", - "excahnges", "exchanges", - "excecuted", "executed", - "excecutes", "executes", - "excellant", "excellent", - "excercise", "exercise", - "excerised", "exercised", - "excerises", "exercises", - "exceuting", "executing", - "exchnages", "exchanges", - "exclsuive", "exclusive", - "excludeds", "excludes", - "exclusivs", "exclusives", - "exclusivy", "exclusivity", - "excpetion", "exception", - "exculding", "excluding", - "exculsion", "exclusion", - "exculsive", "exclusive", - "execising", "exercising", - "execption", "exception", - "exectuing", "executing", - "exectuion", "execution", - "exectuive", "executive", - "executabe", "executable", - "exepmtion", "exemption", - "exerbated", "exacerbated", - "exercices", "exercise", - "exerciese", "exercises", - "exercizes", "exercise", - "exersices", "exercises", - "exhasuted", "exhausted", - "exhaustin", "exhaustion", - "exhibites", "exhibits", - "exhibitin", "exhibition", - "exhibtion", "exhibition", - "exhuasted", "exhausted", - "exibition", "exhibition", - "existance", "existence", - "existenta", "existential", - "existince", "existence", - "existnace", "existance", - "exlcuding", "excluding", - "exlcusion", "exclusion", - "exlcusive", "exclusive", - "exlpoding", "exploding", - "exlporers", "explorers", - "exlposion", "explosion", - "exonorate", "exonerate", - "expalined", "explained", - "expanisve", "expansive", - "expatriot", "expatriate", - "expectany", "expectancy", - "expection", "exception", - "expemtion", "exemption", - "experimet", "experiments", - "explaines", "explains", - "explainig", "explaining", - "explaning", "explaining", - "expliciet", "explicit", - "explicity", "explicitly", - "explictly", "explicitly", - "explioted", "exploited", - "explodeds", "explodes", - "exploites", "exploits", - "explorare", "explorer", - "explotied", "exploited", - "expolding", "exploding", - "expolited", "exploited", - "expolsion", "explosion", - "expolsive", "explosive", - "expressie", "expressive", - "expressin", "expression", - "exsitance", "existance", - "extention", "extension", - "exteriour", "exterior", - "extermely", "extremely", - "extermism", "extremism", - "extermist", "extremist", - "externaly", "externally", - "extractin", "extraction", - "extrapole", "extrapolate", - "extreemly", "extremely", - "extremers", "extremes", - "extremley", "extremely", - "extrotion", "extortion", - "eyeballls", "eyeballs", - "eyebrowes", "eyebrows", - "eyebrowns", "eyebrows", - "eyesahdow", "eyeshadow", - "eyeshdaow", "eyeshadow", - "eygptians", "egyptians", - "eytmology", "etymology", - "faceboook", "facebook", - "faciliate", "facilitate", - "facilites", "facilities", - "facilitiy", "facility", - "facinated", "fascinated", - "facutally", "factually", - "familiair", "familiar", - "familiare", "familiarize", - "familiary", "familiarity", - "familliar", "familiar", - "fanaticas", "fanatics", - "fanaticos", "fanatics", - "fanaticus", "fanatics", - "fanatsies", "fantasies", - "fanatsize", "fantasize", - "fandation", "foundation", - "fanservie", "fanservice", - "fantazise", "fantasize", - "farenheit", "fahrenheit", - "fascistes", "fascists", - "fashoined", "fashioned", - "favorties", "favorites", - "favoruite", "favourite", - "favourits", "favourites", - "favourtie", "favourite", - "fedreally", "federally", - "feminisim", "feminism", - "feminsits", "feminists", - "femminist", "feminist", - "fesitvals", "festivals", - "fetishers", "fetishes", - "fightings", "fighting", - "filetimes", "lifetimes", - "filiament", "filament", - "filmmakes", "filmmakers", - "fingernal", "fingernails", - "flashligt", "flashlight", - "flavorade", "flavored", - "flavoures", "flavours", - "flavourus", "flavours", - "flawlessy", "flawlessly", - "flexibily", "flexibility", - "fluctaute", "fluctuate", - "flucutate", "fluctuate", - "fluttersy", "fluttershy", - "follwoing", "following", - "foootball", "football", - "forcefuly", "forcefully", - "forcibley", "forcibly", - "forciblly", "forcibly", - "forearmes", "forearms", - "foreginer", "foreigner", - "foregroud", "foreground", - "foreinger", "foreigner", - "forgeiner", "foreigner", - "forgiener", "foreigner", - "forgivens", "forgiveness", - "foriegner", "foreigner", - "forigener", "foreigner", - "formerlly", "formerly", - "formualte", "formulate", - "formulaes", "formulas", - "formulars", "formulas", - "forntline", "frontline", - "forntpage", "frontpage", - "fortuante", "fortunate", - "forumlate", "formulate", - "foundatin", "foundations", - "fourteeen", "fourteen", - "fractales", "fractals", - "fractalis", "fractals", - "fractalus", "fractals", - "fragement", "fragment", - "fragmenot", "fragment", - "franchies", "franchise", - "francsico", "francisco", - "franscico", "francisco", - "frecklers", "freckles", - "freedomes", "freedoms", - "freestlye", "freestyle", - "freesytle", "freestyle", - "fremented", "fermented", - "freqeuncy", "frequency", - "frequence", "frequencies", - "friendlis", "friendlies", - "frightend", "frightened", - "fromation", "formation", - "frontapge", "frontpage", - "frontilne", "frontline", - "frustrato", "frustration", - "frustrats", "frustrates", - "fucntions", "functions", - "fullscren", "fullscreen", - "funcitons", "functions", - "functiong", "functioning", - "functtion", "function", - "furiosuly", "furiously", - "furiuosly", "furiously", - "futuristc", "futuristic", - "gagnsters", "gangsters", - "galations", "galatians", - "galdiator", "gladiator", - "gallaxies", "galaxies", - "garanteed", "guaranteed", - "garantees", "guarantees", - "garuantee", "guarantee", - "gatherins", "gatherings", - "gauntelts", "gauntlets", - "gauntlent", "gauntlet", - "gaurantee", "guarantee", - "gaurentee", "guarantee", - "genatilia", "genitalia", - "geneology", "genealogy", - "generalbs", "generals", - "generalis", "generals", - "generaste", "generates", - "generatie", "generate", - "generatin", "generations", - "generatos", "generators", - "genitaila", "genitalia", - "genitales", "genitals", - "genitalis", "genitals", - "geniunely", "genuinely", - "gentailia", "genitalia", - "gentelmen", "gentlemen", - "gentialia", "genitalia", - "genuienly", "genuinely", - "genuinley", "genuinely", - "geogrpahy", "geography", - "germaniac", "germanic", - "geurrilla", "guerrilla", - "gimmickey", "gimmicky", - "gimmickly", "gimmicky", - "girlfried", "girlfriend", - "goalkeepr", "goalkeeper", - "godafther", "godfather", - "godspeeed", "godspeed", - "goegraphy", "geography", - "goldfisch", "goldfish", - "goosebums", "goosebumps", - "gorvement", "goverment", - "govemrent", "goverment", - "govenment", "government", - "goverance", "governance", - "goveremnt", "goverment", - "goverment", "government", - "govermetn", "goverment", - "govermnet", "goverment", - "governmet", "governments", - "govorment", "government", - "govrement", "goverment", - "gracefull", "graceful", - "gracefuly", "gracefully", - "graduaste", "graduates", - "graduatin", "graduation", - "grahpical", "graphical", - "grativate", "gravitate", - "graudally", "gradually", - "graudates", "graduates", - "greenalnd", "greenland", - "grenaders", "grenades", - "grpahical", "graphical", - "guadulupe", "guadalupe", - "guaranted", "guaranteed", - "guarantes", "guarantees", - "guardains", "guardians", - "guarentee", "guarantee", - "guaridans", "guardians", - "guatamala", "guatemala", - "guerrilas", "guerrillas", - "guradians", "guardians", - "guranteed", "guaranteed", - "gurantees", "guarantees", - "gutiarist", "guitarist", - "habsbourg", "habsburg", - "hairstlye", "hairstyle", - "hairsytle", "hairstyle", - "halarious", "hilarious", - "hambruger", "hamburger", - "hamburges", "hamburgers", - "hamphsire", "hampshire", - "hamsphire", "hampshire", - "handboook", "handbook", - "handedley", "handedly", - "handedlly", "handedly", - "handicape", "handicapped", - "hapmshire", "hampshire", - "happended", "happened", - "happenend", "happened", - "happenned", "happened", - "harasment", "harassment", - "hardenend", "hardened", - "hardwoord", "hardwood", - "haristyle", "hairstyle", - "harrasing", "harassing", - "harrassed", "harassed", - "harrasses", "harassed", - "hdinsight", "hindsight", - "headahces", "headaches", - "headhpone", "headphone", - "headshoot", "headshot", - "healither", "healthier", - "healtheir", "healthier", - "healthiet", "healthiest", - "healthire", "healthier", - "heapdhone", "headphone", - "hedgehoog", "hedgehog", - "hedgehorg", "hedgehog", - "heightend", "heightened", - "heirarchy", "hierarchy", - "herculase", "hercules", - "herculeas", "hercules", - "herculees", "hercules", - "herculeus", "hercules", - "heriarchy", "hierarchy", - "hesistant", "hesitant", - "hesistate", "hesitate", - "hesitatin", "hesitation", - "hieroglph", "hieroglyph", - "highschol", "highschool", - "hindisght", "hindsight", - "hindrence", "hindrance", - "hinduisim", "hinduism", - "hinduisum", "hinduism", - "hipsanics", "hispanics", - "hirearchy", "hierarchy", - "hirsohima", "hiroshima", - "hispancis", "hispanics", - "hitboxers", "hitboxes", - "hoepfully", "hopefully", - "holocasut", "holocaust", - "holocuast", "holocaust", - "homeonwer", "homeowner", - "homeopaty", "homeopathy", - "homewolrd", "homeworld", - "homewoner", "homeowner", - "homewrold", "homeworld", - "homogenes", "homogeneous", - "homosexul", "homosexuals", - "hopelessy", "hopelessly", - "hopsitals", "hospitals", - "horishima", "hiroshima", - "horizones", "horizons", - "horizonts", "horizons", - "horrendos", "horrendous", - "horribley", "horribly", - "horriblly", "horribly", - "horrifing", "horrifying", - "hositlity", "hostility", - "hospitaly", "hospitality", - "hosptials", "hospitals", - "hourgalss", "hourglass", - "hourlgass", "hourglass", - "househols", "households", - "humanitis", "humanities", - "humanoind", "humanoid", - "humiditiy", "humidity", - "hunagrian", "hungarian", - "hurriance", "hurricane", - "hurricans", "hurricanes", - "husbandos", "husbands", - "hydraluic", "hydraulic", - "hydropile", "hydrophile", - "hydropobe", "hydrophobe", - "hydrualic", "hydraulic", - "hyopcrite", "hypocrite", - "hypcorite", "hypocrite", - "hyperoble", "hyperbole", - "hypocracy", "hypocrisy", - "hypocrasy", "hypocrisy", - "hypocricy", "hypocrisy", - "hypocriet", "hypocrite", - "hypocrits", "hypocrites", - "hyporcite", "hypocrite", - "hypothess", "hypotheses", - "hyprocisy", "hypocrisy", - "hyprocite", "hypocrite", - "hyrdation", "hydration", - "hyrdaulic", "hydraulic", - "hysterica", "hysteria", - "hysteriia", "hysteria", - "iburpofen", "ibuprofen", - "icleandic", "icelandic", - "icongnito", "incognito", - "idealisim", "idealism", - "idealistc", "idealistic", - "identifiy", "identify", - "ideologis", "ideologies", - "ignornace", "ignorance", - "illegales", "illegals", - "illegalis", "illegals", - "illegalls", "illegals", - "illnesess", "illnesses", - "illsuions", "illusions", - "illuminai", "illuminati", - "imagenary", "imaginary", - "imaginery", "imaginary", - "imaptient", "impatient", - "imigrated", "emigrated", - "immensley", "immensely", - "immerisve", "immersive", - "immesnely", "immensely", - "immidiate", "immediate", - "immigrato", "immigration", - "immitated", "imitated", - "immitator", "imitator", - "immobilie", "immobile", - "immobille", "immobile", - "immobilze", "immobile", - "immortaly", "immortality", - "immserive", "immersive", - "impaitent", "impatient", - "imparital", "impartial", - "impedence", "impedance", - "implantes", "implants", - "implicati", "implicit", - "impliciet", "implicit", - "implicity", "implicitly", - "impliment", "implement", - "implusive", "impulsive", - "importamt", "important", - "importend", "imported", - "imporving", "improving", - "impossibe", "impossible", - "imprefect", "imperfect", - "impressin", "impressions", - "imprioned", "imprisoned", - "improbabe", "improbable", - "impulisve", "impulsive", - "impuslive", "impulsive", - "imrpoving", "improving", - "inadequet", "inadequate", - "inadquate", "inadequate", - "inaugures", "inaugurates", - "inbalance", "imbalance", - "inbeetwen", "inbetween", - "inbetween", "between", - "inbewteen", "inbetween", - "incarnato", "incarnation", - "incgonito", "incognito", - "inclinato", "inclination", - "includeds", "includes", - "incoginto", "incognito", - "incongito", "incognito", - "incorpore", "incorporate", - "incpetion", "inception", - "incredibe", "incredible", - "incrediby", "incredibly", - "inculding", "including", - "incunabla", "incunabula", - "indicaste", "indicates", - "indicatie", "indicative", - "indicence", "incidence", - "indicents", "incidents", - "indigenos", "indigenous", - "indirecty", "indirectly", - "indisious", "insidious", - "individul", "individual", - "individus", "individuals", - "indoensia", "indonesia", - "indoneisa", "indonesia", - "indutrial", "industrial", - "inersting", "inserting", - "inexpense", "inexpensive", - "infallibe", "infallible", - "inferioir", "inferior", - "inferiour", "inferior", - "infestato", "infestation", - "infiltrar", "infiltrator", - "infinitey", "infinity", - "infinitie", "infinite", - "infinitiy", "infinity", - "infinitly", "infinity", - "inflatabe", "inflatable", - "influense", "influences", - "influenta", "influential", - "informate", "informative", - "infraread", "infrared", - "ingeniuty", "ingenuity", - "ingeunity", "ingenuity", - "ingocnito", "incognito", - "ingorance", "ignorance", - "inguenity", "ingenuity", - "inhabitat", "inhabitants", - "inheirted", "inherited", - "inhertied", "inherited", - "initailly", "initially", - "initalese", "initialese", - "initaling", "initialing", - "initalise", "initialise", - "initalism", "initialism", - "initalize", "initialize", - "initalled", "initialled", - "initation", "initiation", - "initiales", "initials", - "initiatie", "initiatives", - "initiatin", "initiation", - "initiatve", "initiate", - "injustics", "injustices", - "inlcuding", "including", - "inmigrant", "immigrant", - "innoucous", "innocuous", - "innovatin", "innovations", - "innovatve", "innovate", - "inpection", "inception", - "inpending", "impending", - "inproving", "improving", - "inpsector", "inspector", - "inpsiring", "inspiring", - "inquisito", "inquisition", - "inquisitr", "inquisitor", - "inresting", "inserting", - "insanelly", "insanely", - "insepctor", "inspector", - "insidiuos", "insidious", - "insipring", "inspiring", - "insluated", "insulated", - "inspectin", "inspection", - "instabilt", "instability", - "installes", "installs", - "installus", "installs", - "instering", "inserting", - "insticnts", "instincts", - "institude", "instituted", - "instituto", "institution", - "insualted", "insulated", - "insurence", "insurance", - "insurgeny", "insurgency", - "integirty", "integrity", - "integraal", "integral", - "integrade", "integrated", - "integrato", "integration", - "intenisty", "intensity", - "intensley", "intensely", - "interacte", "interactive", - "interents", "internets", - "interesat", "interest", - "interesst", "interests", - "interewbs", "interwebs", - "interfase", "interfaces", - "interfeer", "interfere", - "interfers", "interferes", - "intergate", "integrate", - "intergity", "integrity", - "interiour", "interior", - "internest", "internets", - "interpert", "interpret", - "interprut", "interrupt", - "interrups", "interrupts", - "interstae", "interstate", - "interveen", "intervene", - "intervied", "interviewed", - "intervier", "interviewer", - "intervies", "interviews", - "intesnely", "intensely", - "intesnity", "intensity", - "intestins", "intestines", - "inticrate", "intricate", - "intimidad", "intimidated", - "intircate", "intricate", - "intiution", "intuition", - "intiutive", "intuitive", - "intorduce", "introduce", - "intorvert", "introvert", - "intracite", "intricate", - "intrduced", "introduced", - "intregity", "integrity", - "intrenets", "internets", - "intrepret", "interpret", - "intrerupt", "interrupt", - "intrewebs", "interwebs", - "intrinisc", "intrinsic", - "intrisinc", "intrinsic", - "intrisnic", "intrinsic", - "intriuged", "intrigued", - "introdued", "introduced", - "introduse", "introduces", - "introvers", "introverts", - "intruiged", "intrigued", - "intrument", "instrument", - "inutition", "intuition", - "inutitive", "intuitive", - "invaderas", "invaders", - "invalidas", "invalidates", - "inventios", "inventions", - "investige", "investigate", - "investmet", "investments", - "invincibe", "invincible", - "invloving", "involving", - "invovling", "involving", - "ipubrofen", "ibuprofen", - "iranianos", "iranians", - "irelevent", "irrelevant", - "ironicaly", "ironically", - "irritatie", "irritate", - "irritatin", "irritation", - "isalmists", "islamists", - "isalnders", "islanders", - "islamiskt", "islamist", - "islamsits", "islamists", - "islmaists", "islamists", - "isntaller", "installer", - "isntances", "instances", - "isntantly", "instantly", - "israelies", "israelis", - "israelits", "israelis", - "italianas", "italians", - "italianos", "italians", - "jailbrake", "jailbreak", - "jalibreak", "jailbreak", - "jamaicain", "jamaican", - "jersualem", "jerusalem", - "jeruselam", "jerusalem", - "jeruslaem", "jerusalem", - "journalis", "journals", - "judegment", "judgement", - "judgemant", "judgemental", - "judisuary", "judiciary", - "jugdement", "judgement", - "juggernat", "juggernaut", - "juvenille", "juvenile", - "keneysian", "keynesian", - "kentuckey", "kentucky", - "kenyesian", "keynesian", - "keybaords", "keyboards", - "keyensian", "keynesian", - "keyesnian", "keynesian", - "keynseian", "keynesian", - "keysenian", "keynesian", - "kilometes", "kilometers", - "kindapped", "kidnapped", - "kncokback", "knockback", - "knoweldge", "knowledge", - "knowlegde", "knowledge", - "konckback", "knockback", - "kryptonie", "kryptonite", - "labirynth", "labyrinth", - "laboratoy", "laboratory", - "laboreres", "laborers", - "labratory", "laboratory", - "labriynth", "labyrinth", - "labryinth", "labyrinth", - "labyrnith", "labyrinth", - "landscaps", "landscapes", - "landscspe", "landscapes", - "langauges", "languages", - "languague", "language", - "lanuchers", "launchers", - "lanugages", "languages", - "larington", "arlington", - "latitudie", "latitude", - "lattitude", "latitude", - "laucnhers", "launchers", - "laucnhing", "launching", - "launchign", "launching", - "laybrinth", "labyrinth", - "lebanesse", "lebanese", - "leceister", "leicester", - "leciester", "leicester", - "legitmate", "legitimate", - "legnedary", "legendary", - "lesbianas", "lesbians", - "lesbianus", "lesbians", - "letivicus", "leviticus", - "leutenant", "lieutenant", - "levaithan", "leviathan", - "levellign", "levelling", - "levetated", "levitated", - "levetates", "levitates", - "levicitus", "leviticus", - "levleling", "levelling", - "lfiesteal", "lifesteal", - "liberales", "liberals", - "liberalim", "liberalism", - "liberalis", "liberals", - "liberatin", "liberation", - "libraires", "libraries", - "liecester", "leicester", - "lieuenant", "lieutenant", - "lieutenat", "lieutenant", - "lifespawn", "lifespan", - "lifestlye", "lifestyle", - "lighnting", "lightning", - "lightnign", "lightning", - "ligthning", "lightning", - "ligthroom", "lightroom", - "lingerine", "lingerie", - "lispticks", "lipsticks", - "listenend", "listened", - "literarly", "literary", - "literarry", "literary", - "literatre", "literate", - "literatue", "literate", - "literture", "literature", - "lithaunia", "lithuania", - "lithuaina", "lithuania", - "lithuiana", "lithuania", - "lithunaia", "lithuania", - "litigatin", "litigation", - "lituhania", "lithuania", - "liveprool", "liverpool", - "livestrem", "livestream", - "lobbysits", "lobbyists", - "lockscren", "lockscreen", - "logisitcs", "logistics", - "logsitics", "logistics", - "loiusiana", "louisiana", - "lollipoop", "lollipop", - "louisvile", "louisville", - "luanchers", "launchers", - "luanching", "launching", - "lubicrant", "lubricant", - "lubircant", "lubricant", - "ludcrious", "ludicrous", - "ludricous", "ludicrous", - "lunaticos", "lunatics", - "lunaticus", "lunatics", - "macaronni", "macaroni", - "maestries", "masteries", - "magainzes", "magazines", - "magensium", "magnesium", - "magincian", "magician", - "magintude", "magnitude", - "magneisum", "magnesium", - "magnesuim", "magnesium", - "magnifine", "magnificent", - "mainfesto", "manifesto", - "mainfests", "manifests", - "mainstrem", "mainstream", - "maintaing", "maintaining", - "maintance", "maintenance", - "maintians", "maintains", - "mairjuana", "marijuana", - "malasyian", "malaysian", - "malayisan", "malaysian", - "malaysain", "malaysian", - "maletonin", "melatonin", - "maltesian", "maltese", - "malyasian", "malaysian", - "managable", "manageable", - "managment", "management", - "mandarian", "mandarin", - "mandarijn", "mandarin", - "mandarion", "mandarin", - "maneouvre", "manoeuvre", - "maneuveur", "maneuver", - "maneveurs", "maneuvers", - "manfiesto", "manifesto", - "manfiests", "manifests", - "mangesium", "magnesium", - "mangitude", "magnitude", - "manouvers", "maneuvers", - "mantained", "maintained", - "manuevers", "maneuvers", - "maraudeur", "marauder", - "marevlous", "marvelous", - "margarent", "margaret", - "margarite", "margaret", - "marginaal", "marginal", - "marginaly", "marginally", - "marijauna", "marijuana", - "marineras", "mariners", - "marineris", "mariners", - "marineros", "mariners", - "marjiuana", "marijuana", - "marjority", "majority", - "marmelade", "marmalade", - "marrtyred", "martyred", - "massagens", "massages", - "massivley", "massively", - "masteires", "masteries", - "mastereis", "masteries", - "masterise", "masteries", - "mastermid", "mastermind", - "mastieres", "masteries", - "masturbae", "masturbated", - "materiaal", "material", - "matierals", "materials", - "mattreses", "mattress", - "mayalsian", "malaysian", - "maylasian", "malaysian", - "mccarthey", "mccarthy", - "mecahnics", "mechanics", - "mecernary", "mercenary", - "mechancis", "mechanics", - "mechanims", "mechanism", - "mechaninc", "mechanic", - "mechansim", "mechanism", - "medicince", "medicine", - "mediciney", "mediciny", - "meditatie", "meditate", - "meditatin", "meditation", - "megathred", "megathread", - "melanotin", "melatonin", - "melborune", "melbourne", - "melbounre", "melbourne", - "membrance", "membrane", - "menstraul", "menstrual", - "menstural", "menstrual", - "mensutral", "menstrual", - "mentiones", "mentions", - "mercanery", "mercenary", - "merhcants", "merchants", - "messagers", "messages", - "messanger", "messenger", - "metabloic", "metabolic", - "metalurgy", "metallurgy", - "methaphor", "metaphor", - "methapors", "metaphors", - "methodoly", "methodology", - "metropols", "metropolis", - "mexicanas", "mexicans", - "mexicants", "mexicans", - "mexicanus", "mexicans", - "michellle", "michelle", - "micorwave", "microwave", - "micoscopy", "microscopy", - "microphen", "microphone", - "migrantes", "migrants", - "migrianes", "migraines", - "milawukee", "milwaukee", - "milennium", "millennium", - "milestons", "milestones", - "militians", "militias", - "millenial", "millennial", - "millenian", "millennia", - "millenium", "millennium", - "millionar", "millionaire", - "millitary", "military", - "miluwakee", "milwaukee", - "milwakuee", "milwaukee", - "milwuakee", "milwaukee", - "mindcarck", "mindcrack", - "mindlessy", "mindlessly", - "minerales", "minerals", - "minisclue", "miniscule", - "miniscuel", "miniscule", - "ministery", "ministry", - "minisucle", "miniscule", - "minitaure", "miniature", - "minituare", "miniature", - "minneosta", "minnesota", - "minnestoa", "minnesota", - "minsicule", "miniscule", - "minsiters", "ministers", - "minstries", "ministries", - "miraculos", "miraculous", - "mircowave", "microwave", - "mirrorred", "mirrored", - "miserabel", "miserable", - "mispelled", "misspelled", - "misreable", "miserable", - "misreably", "miserably", - "missisipi", "mississippi", - "missonary", "missionary", - "missourri", "missouri", - "misspelld", "misspelled", - "mobilitiy", "mobility", - "moderatey", "moderately", - "moderatin", "moderation", - "modifires", "modifiers", - "moelcules", "molecules", - "moleclues", "molecules", - "molestare", "molester", - "molestato", "molestation", - "molesterd", "molested", - "monestary", "monastery", - "monitores", "monitors", - "monolgoue", "monologue", - "monolight", "moonlight", - "monolouge", "monologue", - "monopolis", "monopolies", - "monopolly", "monopoly", - "monopoloy", "monopoly", - "monserrat", "montserrat", - "monstorus", "monstrous", - "monstruos", "monstrous", - "montanous", "mountainous", - "monumnets", "monuments", - "moratlity", "mortality", - "morbidley", "morbidly", - "morgatges", "mortgages", - "morgtages", "mortgages", - "morisette", "morissette", - "mormonsim", "mormonism", - "morroccan", "moroccan", - "mortailty", "mortality", - "mosquitto", "mosquito", - "motivatie", "motivate", - "motivatin", "motivations", - "motorcyce", "motorcycles", - "motorolja", "motorola", - "motoroloa", "motorola", - "moustahce", "moustache", - "movepseed", "movespeed", - "mozzarela", "mozzarella", - "mucisians", "musicians", - "mulitated", "mutilated", - "mulitples", "multiples", - "multipled", "multiplied", - "multplies", "multiples", - "murdererd", "murdered", - "muscially", "musically", - "muscician", "musician", - "musculair", "muscular", - "mushrooom", "mushroom", - "musicains", "musicians", - "mutatiohn", "mutation", - "mutialted", "mutilated", - "mutilatin", "mutilation", - "mutliated", "mutilated", - "mutliples", "multiples", - "mutlitude", "multitude", - "mysterise", "mysteries", - "mysterous", "mysterious", - "nacrotics", "narcotics", - "naferious", "nefarious", - "nahsville", "nashville", - "narcissim", "narcissism", - "narcissit", "narcissist", - "narcissts", "narcissist", - "narctoics", "narcotics", - "nasvhille", "nashville", - "nationaal", "national", - "nationaly", "nationally", - "nativelly", "natively", - "natrually", "naturally", - "navigatie", "navigate", - "navigatin", "navigation", - "neccesary", "necessary", - "necessite", "necessities", - "neckbears", "neckbeards", - "neckbread", "neckbeard", - "nedlessly", "endlessly", - "needlessy", "needlessly", - "negiotate", "negotiate", - "negociate", "negotiate", - "negoitate", "negotiate", - "neigbhour", "neighbour", - "neigbours", "neighbours", - "neighboor", "neighbor", - "nessecary", "necessary", - "newcaslte", "newcastle", - "newcastel", "newcastle", - "nieghbour", "neighbour", - "nightfa;;", "nightfall", - "nightlcub", "nightclub", - "nigthclub", "nightclub", - "nigthlife", "nightlife", - "nigthmare", "nightmare", - "nihilisim", "nihilism", - "ninteenth", "nineteenth", - "nominatie", "nominate", - "nominatin", "nomination", - "noninital", "noninitial", - "norhteast", "northeast", - "norhtwest", "northwest", - "normanday", "normandy", - "northeren", "northern", - "norwegain", "norwegian", - "norwiegan", "norwegian", - "nostaglia", "nostalgia", - "nostaglic", "nostalgic", - "nostaliga", "nostalgia", - "nostaligc", "nostalgic", - "nostlagia", "nostalgia", - "nostlagic", "nostalgic", - "nostriles", "nostrils", - "nostrills", "nostrils", - "notacible", "noticable", - "notciable", "noticable", - "noteboook", "notebook", - "noteriety", "notoriety", - "noteworty", "noteworthy", - "noticable", "noticeable", - "noticably", "noticeably", - "noticalbe", "noticable", - "noticeing", "noticing", - "noticible", "noticeable", - "notoroius", "notorious", - "novermber", "november", - "nullabour", "nullarbor", - "numberous", "numerous", - "numercial", "numerical", - "numerious", "numerous", - "nuremburg", "nuremberg", - "nurtients", "nutrients", - "nutirents", "nutrients", - "nutreints", "nutrients", - "nutritent", "nutrient", - "nutritian", "nutritional", - "nutritios", "nutritious", - "obediance", "obedience", - "obeidence", "obedience", - "obersvant", "observant", - "obersvers", "observers", - "obesssion", "obsession", - "obiedence", "obedience", - "obivously", "obviously", - "objectivs", "objectives", - "objectivy", "objectivity", - "obscruity", "obscurity", - "obscuirty", "obscurity", - "observare", "observer", - "observerd", "observed", - "obssesion", "obsession", - "obssesive", "obsessive", - "obssessed", "obsessed", - "obstruced", "obstructed", - "obsucrity", "obscurity", - "obtainabe", "obtainable", - "obviosuly", "obviously", - "obvioulsy", "obviously", - "obvisouly", "obviously", - "obvoiusly", "obviously", - "ocasional", "occasional", - "ocasioned", "occasioned", - "ocassions", "occasions", - "occaisons", "occasions", - "occassion", "occasion", - "occurance", "occurrence", - "occurence", "occurrence", - "octohedra", "octahedra", - "ocuntries", "countries", - "ocurrance", "occurrence", - "ocurrence", "occurrence", - "offcially", "officially", - "offically", "officially", - "officialy", "officially", - "offpsring", "offspring", - "offspirng", "offspring", - "offsrping", "offspring", - "ogliarchy", "oligarchy", - "oilgarchy", "oligarchy", - "oligrachy", "oligarchy", - "ommitting", "omitting", - "onlsaught", "onslaught", - "onsalught", "onslaught", - "onslaugth", "onslaught", - "onsluaght", "onslaught", - "onwership", "ownership", - "opiniones", "opinions", - "oposition", "opposition", - "opponenet", "opponent", - "opposiste", "opposites", - "opposties", "opposites", - "oppressin", "oppression", - "opression", "oppression", - "opressive", "oppressive", - "opthalmic", "ophthalmic", - "optimisim", "optimism", - "optimistc", "optimistic", - "optinally", "optimally", - "oragnered", "orangered", - "oragnised", "organised", - "oragnizer", "organizer", - "orcehstra", "orchestra", - "ordinarly", "ordinary", - "orgainsed", "organised", - "orgainzer", "organizer", - "organered", "orangered", - "organices", "organise", - "organisim", "organism", - "organiske", "organise", - "organiste", "organise", - "organites", "organise", - "organizms", "organism", - "organsied", "organised", - "organsims", "organisms", - "organzier", "organizer", - "orginally", "originally", - "orgnaised", "organised", - "orhcestra", "orchestra", - "orientato", "orientation", - "origanaly", "originally", - "originall", "original", - "originalt", "originality", - "originaly", "originally", - "origintea", "originate", - "origional", "original", - "orignally", "originally", - "orignials", "originals", - "oublisher", "publisher", - "oursleves", "ourselves", - "oustiders", "outsiders", - "oustpoken", "outspoken", - "outisders", "outsiders", - "outnumbed", "outnumbered", - "outpalyed", "outplayed", - "outperfom", "outperform", - "outpsoken", "outspoken", - "outrageos", "outrageous", - "outskirst", "outskirts", - "outskrits", "outskirts", - "outwieghs", "outweighs", - "overbaord", "overboard", - "overclcok", "overclock", - "overdirve", "overdrive", - "overhpyed", "overhyped", - "overhwelm", "overwhelm", - "overlcock", "overclock", - "overloard", "overload", - "overpaied", "overpaid", - "overpowed", "overpowered", - "overriden", "overridden", - "overwhlem", "overwhelm", - "overwirte", "overwrite", - "overwtach", "overwatch", - "overyhped", "overhyped", - "owernship", "ownership", - "pacificts", "pacifist", - "packageid", "packaged", - "pactivity", "captivity", - "painkills", "painkillers", - "paitently", "patiently", - "paitience", "patience", - "pakistain", "pakistani", - "pakistian", "pakistani", - "pakistnai", "pakistani", - "paksitani", "pakistani", - "paladines", "paladins", - "paladinos", "paladins", - "palestein", "palestine", - "palestina", "palestinian", - "palistian", "palestinian", - "paltforms", "platforms", - "palystyle", "playstyle", - "pancakers", "pancakes", - "pantomine", "pantomime", - "paradimes", "paradise", - "paragraps", "paragraphs", - "paragrpah", "paragraph", - "paralells", "parallels", - "paralelly", "parallelly", - "paralisys", "paralysis", - "parallely", "parallelly", - "paralzyed", "paralyzed", - "paramedis", "paramedics", - "paramters", "parameters", - "paranoica", "paranoia", - "paranoida", "paranoia", - "parasties", "parasites", - "paraylsis", "paralysis", - "paraylzed", "paralyzed", - "parellels", "parallels", - "paricular", "particular", - "parisitic", "parasitic", - "paritally", "partially", - "parliment", "parliament", - "parmesaen", "parmesan", - "parntered", "partnered", - "parrallel", "parallel", - "partchett", "pratchett", - "parterned", "partnered", - "participe", "participate", - "partiotic", "patriotic", - "partisain", "partisan", - "pasengers", "passengers", - "passagens", "passages", - "passagers", "passages", - "passerbys", "passersby", - "passiones", "passions", - "passivley", "passively", - "passowrds", "passwords", - "pateintly", "patiently", - "paticular", "particular", - "patinetly", "patiently", - "patriarca", "patriarchal", - "patriarcy", "patriarchy", - "patriotas", "patriots", - "patriotes", "patriots", - "patroitic", "patriotic", - "pattented", "patented", - "pavillion", "pavilion", - "pbulisher", "publisher", - "peacefuly", "peacefully", - "pedohpile", "pedophile", - "pedophila", "pedophilia", - "pedophils", "pedophiles", - "peircings", "piercings", - "penalites", "penalties", - "penatlies", "penalties", - "penduluum", "pendulum", - "penerator", "penetrator", - "penguines", "penguins", - "penguings", "penguins", - "penguinos", "penguins", - "peninsual", "peninsula", - "peninusla", "peninsula", - "penisnula", "peninsula", - "penisular", "peninsular", - "pennisula", "peninsula", - "pensinula", "peninsula", - "pentagoon", "pentagon", - "peodphile", "pedophile", - "pepperino", "pepperoni", - "peppermit", "peppermint", - "percepted", "perceived", - "percevied", "perceived", - "percieved", "perceived", - "percisely", "precisely", - "percision", "precision", - "percursor", "precursor", - "perdators", "predators", - "peremiter", "perimeter", - "perfeclty", "perfectly", - "perfomers", "performers", - "performas", "performs", - "perfromer", "performer", - "pericings", "piercings", - "perimetre", "perimeter", - "peristent", "persistent", - "periwinke", "periwinkle", - "permanant", "permanent", - "permature", "premature", - "permenant", "permanent", - "permieter", "perimeter", - "permissie", "permissible", - "permissin", "permissions", - "permisson", "permission", - "pernament", "permanent", - "perorders", "preorders", - "perpetrar", "perpetrator", - "perpetuae", "perpetuate", - "perpetuas", "perpetuates", - "persauded", "persuaded", - "perscribe", "prescribe", - "perserved", "preserved", - "persistes", "persists", - "personaes", "personas", - "personaly", "personally", - "personell", "personnel", - "personhod", "personhood", - "persuated", "persuade", - "pertended", "pretended", - "pertoleum", "petroleum", - "perusaded", "persuaded", - "pervertes", "perverse", - "pesticids", "pesticides", - "petroluem", "petroleum", - "phemonena", "phenomena", - "phenemona", "phenomena", - "phenonema", "phenomena", - "phillipse", "phillies", - "philosopy", "philosophy", - "philosphy", "philosophy", - "phonecian", "phoenecian", - "phonemena", "phenomena", - "phongraph", "phonograph", - "photograh", "photograph", - "phsyician", "physician", - "phsyicist", "physicist", - "phycisian", "physician", - "phycisist", "physicist", - "physicaly", "physically", - "physicits", "physicist", - "physisict", "physicist", - "piblisher", "publisher", - "picthfork", "pitchfork", - "pinetrest", "pinterest", - "placeheld", "placeholder", - "placemens", "placements", - "plaestine", "palestine", - "plagarism", "plagiarism", - "planatery", "planetary", - "planation", "plantation", - "planteary", "planetary", - "plasticas", "plastics", - "plasticos", "plastics", - "plasticus", "plastics", - "platfroms", "platforms", - "platofrms", "platforms", - "plausable", "plausible", - "plausbile", "plausible", - "plausibel", "plausible", - "playgroud", "playground", - "playright", "playwright", - "playstlye", "playstyle", - "playwrite", "playwright", - "plebicite", "plebiscite", - "plethoria", "plethora", - "ploarized", "polarized", - "pointeres", "pointers", - "polinator", "pollinator", - "polishees", "polishes", - "politelly", "politely", - "politican", "politician", - "politicas", "politics", - "politicin", "politician", - "politicus", "politics", - "polygammy", "polygamy", - "populatin", "populations", - "poralized", "polarized", - "porcelian", "porcelain", - "porcelina", "porcelain", - "poreclain", "porcelain", - "porftolio", "portfolio", - "porgramme", "programme", - "portfoilo", "portfolio", - "portoflio", "portfolio", - "portraing", "portraying", - "portrayes", "portrays", - "portrayls", "portrays", - "portriats", "portraits", - "portugese", "portuguese", - "portugues", "portuguese", - "posessing", "possessing", - "posession", "possession", - "positiond", "positioned", - "positiong", "positioning", - "positionl", "positional", - "positiviy", "positivity", - "possesess", "possesses", - "possesing", "possessing", - "possesion", "possession", - "possessin", "possessions", - "possibile", "possible", - "possibily", "possibility", - "possibley", "possibly", - "possiblly", "possibly", - "possition", "position", - "powderade", "powdered", - "powerfull", "powerful", - "pracitcal", "practical", - "practhett", "pratchett", - "practicly", "practically", - "practives", "practise", - "pragamtic", "pragmatic", - "preadtors", "predators", - "precedeed", "preceded", - "preceeded", "preceded", - "preceived", "perceived", - "preciesly", "precisely", - "precisley", "precisely", - "precurors", "precursor", - "precurosr", "precursor", - "precurser", "precursor", - "predatobr", "predator", - "predictie", "predictive", - "predictin", "prediction", - "predjuice", "prejudice", - "predujice", "prejudice", - "prefectly", "perfectly", - "preferens", "preferences", - "prefering", "preferring", - "preformer", "performer", - "pregnance", "pregnancies", - "preimeter", "perimeter", - "prejiduce", "prejudice", - "prejucide", "prejudice", - "premanent", "permanent", - "premeired", "premiered", - "preorderd", "preordered", - "preparato", "preparation", - "prepatory", "preparatory", - "presentas", "presents", - "presentes", "presents", - "presicely", "precisely", - "presicion", "precision", - "presideny", "presidency", - "prestigiu", "prestigious", - "prestigue", "prestige", - "presuaded", "persuaded", - "pretendas", "pretends", - "pretensje", "pretense", - "pretinent", "pertinent", - "prevelant", "prevalent", - "preventin", "prevention", - "previvous", "previous", - "priesthod", "priesthood", - "priestood", "priesthood", - "primaires", "primaries", - "primairly", "primarily", - "primarliy", "primarily", - "primative", "primitive", - "primordal", "primordial", - "princesas", "princess", - "princeses", "princess", - "princesss", "princesses", - "principas", "principals", - "principly", "principally", - "prinicple", "principle", - "prioritie", "prioritize", - "prioritse", "priorities", - "privalege", "privilege", - "privelege", "privilege", - "privelige", "privilege", - "privilage", "privilege", - "privilegs", "privileges", - "privledge", "privilege", - "probabily", "probability", - "probablly", "probably", - "problemas", "problems", - "procative", "proactive", - "procedger", "procedure", - "proceding", "proceeding", - "proceedes", "proceeds", - "procelain", "porcelain", - "procesess", "processes", - "processer", "processor", - "processos", "processors", - "proclamed", "proclaimed", - "procotols", "protocols", - "prodecure", "procedure", - "productie", "productive", - "productin", "productions", - "productos", "products", - "profesion", "profusion", - "professer", "professor", - "professin", "professions", - "proffesed", "professed", - "proffesor", "professor", - "progessed", "progressed", - "programas", "programs", - "programem", "programme", - "programes", "programs", - "programms", "programs", - "progresso", "progression", - "progresss", "progresses", - "projectie", "projectile", - "projectin", "projection", - "prominant", "prominent", - "promiscus", "promiscuous", - "promotted", "promoted", - "pronomial", "pronominal", - "pronouced", "pronounced", - "pronounds", "pronouns", - "pronounes", "pronouns", - "propagana", "propaganda", - "properies", "properties", - "propertly", "property", - "propeties", "properties", - "prophesie", "prophecies", - "prophetes", "prophets", - "propogate", "propagate", - "proposels", "proposes", - "proposito", "proposition", - "propperly", "properly", - "propsects", "prospects", - "prosperos", "prosperous", - "prostitue", "prostitute", - "protectes", "protects", - "protectie", "protective", - "protectos", "protectors", - "proteinas", "proteins", - "proteines", "proteins", - "protestas", "protests", - "protestat", "protestant", - "protestes", "protests", - "protestos", "protests", - "protfolio", "portfolio", - "protocool", "protocol", - "prototpye", "prototype", - "prototyps", "prototypes", - "protraits", "portraits", - "protrayal", "portrayal", - "protrayed", "portrayed", - "provicial", "provincial", - "provincie", "province", - "provisios", "provisions", - "pruchased", "purchased", - "pruchases", "purchases", - "prugatory", "purgatory", - "pruposely", "purposely", - "pscyhotic", "psychotic", - "pseudonyn", "pseudonym", - "pshycosis", "psychosis", - "pshycotic", "psychotic", - "psycology", "psychology", - "psycothic", "psychotic", - "ptichfork", "pitchfork", - "pubilsher", "publisher", - "publiaher", "publisher", - "publicaly", "publicly", - "publicani", "publication", - "publicher", "publisher", - "publiclly", "publicly", - "publihser", "publisher", - "publisehr", "publisher", - "publisger", "publisher", - "publishor", "publisher", - "publishre", "publisher", - "publsiher", "publisher", - "publusher", "publisher", - "puchasing", "purchasing", - "punishmet", "punishments", - "puplisher", "publisher", - "puragtory", "purgatory", - "purcahsed", "purchased", - "purcahses", "purchases", - "purhcased", "purchased", - "purposley", "purposely", - "pursuaded", "persuaded", - "pursuades", "persuades", - "pyramidas", "pyramids", - "pyramides", "pyramids", - "pyschosis", "psychosis", - "pyschotic", "psychotic", - "qaulifies", "qualifies", - "quantifiy", "quantify", - "quantitiy", "quantity", - "quantitty", "quantity", - "quartlery", "quarterly", - "queations", "equations", - "queenland", "queensland", - "questiond", "questioned", - "questiong", "questioning", - "questionn", "questioning", - "radicalis", "radicals", - "rapsberry", "raspberry", - "rasbperry", "raspberry", - "rationaly", "rationally", - "reactiony", "reactionary", - "realisitc", "realistic", - "realoding", "reloading", - "realsitic", "realistic", - "realtable", "relatable", - "realtions", "relations", - "realtives", "relatives", - "reamining", "remaining", - "reaplying", "replaying", - "reasearch", "research", - "reaveling", "revealing", - "rebellios", "rebellious", - "rebllions", "rebellions", - "recations", "creations", - "reccomend", "recommend", - "reccuring", "recurring", - "receeding", "receding", - "recepient", "recipient", - "recgonise", "recognise", - "recgonize", "recognize", - "recidents", "residents", - "recievers", "receivers", - "recieving", "receiving", - "recipiant", "recipient", - "reciproce", "reciprocate", - "reclutant", "reluctant", - "recoginse", "recognise", - "recoginze", "recognize", - "recomends", "recommends", - "recommens", "recommends", - "reconenct", "reconnect", - "recongise", "recognise", - "recongize", "recognize", - "reconicle", "reconcile", - "reconized", "recognized", - "recordare", "recorder", - "recoveres", "recovers", - "recoverys", "recovers", - "recpetive", "receptive", - "recpetors", "receptors", - "recquired", "required", - "recreatie", "recreate", - "recruitcs", "recruits", - "recruites", "recruits", - "recrusion", "recursion", - "recrutied", "recruited", - "recrutier", "recruiter", - "rectangel", "rectangle", - "rectanlge", "rectangle", - "recuiting", "recruiting", - "recurison", "recursion", - "recurited", "recruited", - "recuriter", "recruiter", - "recusrion", "recursion", - "redeemeed", "redeemed", - "redundany", "redundancy", - "redundent", "redundant", - "reedeming", "redeeming", - "refelcted", "reflected", - "refereces", "references", - "refereees", "referees", - "refereers", "referees", - "referemce", "reference", - "referencs", "references", - "referense", "references", - "referiang", "referring", - "referinng", "refering", - "refernces", "references", - "refernece", "reference", - "refershed", "refreshed", - "refersher", "refresher", - "reffering", "referring", - "reflectie", "reflective", - "refrehser", "refresher", - "refrences", "references", - "refromist", "reformist", - "regionaal", "regional", - "registerd", "registered", - "registery", "registry", - "regualrly", "regularly", - "regualtor", "regulator", - "regulaion", "regulation", - "regulalry", "regularly", - "regulares", "regulars", - "regularis", "regulars", - "regulatin", "regulations", - "regurally", "regularly", - "reigining", "reigning", - "reinstale", "reinstalled", - "reisntall", "reinstall", - "reknowned", "renowned", - "relaoding", "reloading", - "relatiate", "retaliate", - "relativiy", "relativity", - "relativly", "relatively", - "relativno", "relation", - "relavence", "relevance", - "relcutant", "reluctant", - "relevence", "relevance", - "relfected", "reflected", - "reliabily", "reliability", - "reliabley", "reliably", - "religeous", "religious", - "remasterd", "remastered", - "rememberd", "remembered", - "rememebrs", "remembers", - "remianing", "remaining", - "remignton", "remington", - "remingotn", "remington", - "remmebers", "remembers", - "remotelly", "remotely", - "rendevous", "rendezvous", - "rendezous", "rendezvous", - "renedered", "rende", - "renegated", "renegade", - "rennovate", "renovate", - "repalying", "replaying", - "repblican", "republican", - "repeatedy", "repeatedly", - "repective", "receptive", - "repeition", "repetition", - "repentent", "repentant", - "rephrasse", "rephrase", - "replusive", "repulsive", - "reportedy", "reportedly", - "represend", "represented", - "repressin", "repression", - "reprtoire", "repertoire", - "repsonded", "responded", - "reptition", "repetition", - "reptuable", "reputable", - "repubican", "republican", - "republian", "republican", - "repulican", "republican", - "repulisve", "repulsive", - "repuslive", "repulsive", - "resaurant", "restaurant", - "researchs", "researchers", - "resembels", "resembles", - "reserverd", "reserved", - "resintall", "reinstall", - "resistane", "resistances", - "resistans", "resistances", - "resistend", "resisted", - "resistent", "resistant", - "resmebles", "resembles", - "resolutin", "resolutions", - "resoruces", "resources", - "respectes", "respects", - "respectos", "respects", - "responces", "response", - "respondas", "responds", - "respondis", "responds", - "respondus", "responds", - "respoting", "reposting", - "ressemble", "resemble", - "ressurect", "resurrect", - "restarant", "restaurant", - "resticted", "restricted", - "restircts", "restricts", - "restorani", "restoration", - "restraind", "restrained", - "restraing", "restraining", - "restraunt", "restraint", - "restriant", "restraint", - "restricte", "restrictive", - "resturant", "restaurant", - "retailate", "retaliate", - "retalaite", "retaliate", - "retaliers", "retailers", - "reteriver", "retriever", - "retirever", "retriever", - "retrevier", "retriever", - "reuptable", "reputable", - "reveiwers", "reviewers", - "revelaing", "revealing", - "revelance", "relevance", - "revolutin", "revolutions", - "rewachted", "rewatched", - "rewatchig", "rewatching", - "rferences", "references", - "ridiculos", "ridiculous", - "ridiculue", "ridicule", - "ridiculus", "ridiculous", - "righetous", "righteous", - "rightfuly", "rightfully", - "rightoues", "righteous", - "rigourous", "rigorous", - "rigtheous", "righteous", - "rilvaries", "rivalries", - "rininging", "ringing", - "rivarlies", "rivalries", - "rivlaries", "rivalries", - "roaylties", "royalties", - "roboticus", "robotics", - "roganisms", "organisms", - "royalites", "royalties", - "roylaties", "royalties", - "ruleboook", "rulebook", - "sacarstic", "sarcastic", - "sacntuary", "sanctuary", - "sacrafice", "sacrifice", - "sacrastic", "sarcastic", - "sacrifise", "sacrifices", - "salughter", "slaughter", - "samckdown", "smackdown", - "sanctiond", "sanctioned", - "sancturay", "sanctuary", - "sancutary", "sanctuary", - "sandstrom", "sandstorm", - "sandwhich", "sandwich", - "sanhedrim", "sanhedrin", - "santcuary", "sanctuary", - "santioned", "sanctioned", - "sapphirre", "sapphire", - "sastified", "satisfied", - "sastifies", "satisfies", - "satelites", "satellites", - "saterdays", "saturdays", - "satisifed", "satisfied", - "satisifes", "satisfies", - "satrudays", "saturdays", - "satsified", "satisfied", - "satsifies", "satisfies", - "sattelite", "satellite", - "saxaphone", "saxophone", - "scaepgoat", "scapegoat", - "scaleable", "scalable", - "scandales", "scandals", - "scandalos", "scandals", - "scantuary", "sanctuary", - "scaricity", "scarcity", - "scarifice", "sacrifice", - "scarmbled", "scrambled", - "scartched", "scratched", - "scartches", "scratches", - "scavanged", "scavenged", - "sceintist", "scientist", - "scholalry", "scholarly", - "sciencers", "sciences", - "scientfic", "scientific", - "scientifc", "scientific", - "scientits", "scientist", - "sclupture", "sculpture", - "scnearios", "scenarios", - "scoreboad", "scoreboard", - "scottisch", "scottish", - "scracthed", "scratched", - "scracthes", "scratches", - "scrambeld", "scrambled", - "scrathces", "scratches", - "scrollade", "scrolled", - "scrutiney", "scrutiny", - "scrutinty", "scrutiny", - "sculpteur", "sculpture", - "sculputre", "sculpture", - "scultpure", "sculpture", - "scuplture", "sculpture", - "scuptures", "sculptures", - "seamlessy", "seamlessly", - "searchign", "searching", - "sebasitan", "sebastian", - "sebastain", "sebastian", - "sebsatian", "sebastian", - "secceeded", "seceded", - "secertary", "secretary", - "secratary", "secretary", - "secratery", "secretary", - "secretery", "secretary", - "secretley", "secretly", - "sednetary", "sedentary", - "seduciton", "seduction", - "semanitcs", "semantics", - "semestres", "semesters", - "semnatics", "semantics", - "semseters", "semesters", - "senatores", "senators", - "sendetary", "sedentary", - "sensitivy", "sensitivity", - "sentimant", "sentimental", - "sepcially", "specially", - "seperated", "separated", - "seperates", "separates", - "seperator", "separator", - "septmeber", "september", - "seraching", "searching", - "seriosuly", "seriously", - "serioulsy", "seriously", - "seriuosly", "seriously", - "servantes", "servants", - "settlment", "settlement", - "sexualizd", "sexualized", - "sexuallly", "sexually", - "shadasloo", "shadaloo", - "shaprness", "sharpness", - "sharpenss", "sharpness", - "shawhsank", "shawshank", - "sheilding", "shielding", - "shephered", "shepherd", - "shileding", "shielding", - "shitstrom", "shitstorm", - "shletered", "sheltered", - "shoudlers", "shoulders", - "shouldnot", "shouldnt", - "shperical", "spherical", - "shwashank", "shawshank", - "sidebaord", "sideboard", - "siganture", "signature", - "signapore", "singapore", - "signitory", "signatory", - "silhouete", "silhouette", - "similiair", "similiar", - "simliarly", "similarly", - "simluated", "simulated", - "simluator", "simulator", - "simplifiy", "simplify", - "simualted", "simulated", - "simualtor", "simulator", - "simulatie", "simulate", - "simulatin", "simulation", - "sinagpore", "singapore", - "sincerley", "sincerely", - "singature", "signature", - "singpaore", "singapore", - "singulair", "singular", - "singulary", "singularity", - "skateboad", "skateboard", - "skeletaal", "skeletal", - "skepitcal", "skeptical", - "skepticim", "skepticism", - "sketpical", "skeptical", - "slaughted", "slaughtered", - "slaugther", "slaughter", - "slipperly", "slippery", - "sluaghter", "slaughter", - "smackdwon", "smackdown", - "smealting", "smelting", - "smeesters", "semesters", - "snadstorm", "sandstorm", - "snippetts", "snippets", - "snowfalke", "snowflake", - "snowflaek", "snowflake", - "snowlfake", "snowflake", - "snwoballs", "snowballs", - "snythesis", "synthesis", - "snythetic", "synthetic", - "socailism", "socialism", - "socailist", "socialist", - "socailize", "socialize", - "soceities", "societies", - "socialini", "socializing", - "socialiss", "socialists", - "socialsim", "socialism", - "socieites", "societies", - "socilaism", "socialism", - "socilaist", "socialist", - "sociopati", "sociopathic", - "sociopats", "sociopaths", - "socratees", "socrates", - "socrateks", "socrates", - "soemthing", "something", - "sohpomore", "sophomore", - "soliliquy", "soliloquy", - "somehting", "something", - "someoneis", "someones", - "somethign", "something", - "somethins", "somethings", - "sopohmore", "sophomore", - "sotryline", "storyline", - "soundtrak", "soundtrack", - "sountrack", "soundtrack", - "sourthern", "southern", - "souvenier", "souvenir", - "soveregin", "sovereign", - "sovereing", "sovereign", - "soveriegn", "sovereign", - "spacegoat", "scapegoat", - "spagehtti", "spaghetti", - "spahgetti", "spaghetti", - "sparlking", "sparkling", - "spartants", "spartans", - "specailly", "specially", - "specailty", "specialty", - "specality", "specialty", - "speciales", "specials", - "specialis", "specials", - "speciatly", "specialty", - "specifing", "specifying", - "specimine", "specimen", - "spectrail", "spectral", - "specualte", "speculate", - "speechers", "speeches", - "spehrical", "spherical", - "speically", "specially", - "spetember", "september", - "sphagetti", "spaghetti", - "splatooon", "splatoon", - "sponosred", "sponsored", - "sponsered", "sponsored", - "sponsores", "sponsors", - "spontanes", "spontaneous", - "sponzored", "sponsored", - "sprakling", "sparkling", - "sprinkeld", "sprinkled", - "squadroon", "squadron", - "squirrles", "squirrels", - "squirrtle", "squirrel", - "squrriels", "squirrels", - "srirachia", "sriracha", - "srirachra", "sriracha", - "stabliize", "stabilize", - "stainlees", "stainless", - "startegic", "strategic", - "startlxde", "startled", - "statisitc", "statistic", - "staurdays", "saturdays", - "steadilly", "steadily", - "stealthly", "stealthy", - "stichting", "stitching", - "sticthing", "stitching", - "stimulans", "stimulants", - "stockplie", "stockpile", - "stornegst", "strongest", - "stragetic", "strategic", - "straightn", "straighten", - "strangets", "strangest", - "strategis", "strategies", - "strawbery", "strawberry", - "streamade", "streamed", - "streamare", "streamer", - "streamear", "streamer", - "strechted", "stretched", - "strechtes", "stretches", - "strecthed", "stretched", - "strecthes", "stretches", - "stregnths", "strengths", - "strenghen", "strengthen", - "strengthn", "strengthen", - "strentghs", "strengths", - "stressade", "stressed", - "stressers", "stresses", - "strictist", "strictest", - "stringnet", "stringent", - "stroyline", "storyline", - "structual", "structural", - "structurs", "structures", - "strucutre", "structure", - "struggeld", "struggled", - "struggels", "struggles", - "stryofoam", "styrofoam", - "stuctured", "structured", - "stuggling", "struggling", - "stupitidy", "stupidity", - "sturcture", "structure", - "sturggled", "struggled", - "sturggles", "struggles", - "styrofaom", "styrofoam", - "subarmine", "submarine", - "subculter", "subculture", - "submachne", "submachine", - "subpecies", "subspecies", - "subscirbe", "subscribe", - "subsidary", "subsidiary", - "subsizide", "subsidize", - "subsquent", "subsequent", - "subsrcibe", "subscribe", - "substanse", "substances", - "substanta", "substantial", - "substante", "substantive", - "substarte", "substrate", - "substitue", "substitute", - "substract", "subtract", - "subtances", "substances", - "subtiltes", "subtitles", - "subtitels", "subtitles", - "subtletly", "subtlety", - "subtlties", "subtitles", - "succedded", "succeeded", - "succeedes", "succeeds", - "succesful", "successful", - "succesion", "succession", - "succesive", "successive", - "suceeding", "succeeding", - "sucesfuly", "successfully", - "sucessful", "successful", - "sucession", "succession", - "sucessive", "successive", - "sufferage", "suffrage", - "sufferred", "suffered", - "sufficent", "sufficient", - "suggestes", "suggests", - "suggestie", "suggestive", - "sumbarine", "submarine", - "sumberged", "submerged", - "summenors", "summoners", - "summoenrs", "summoners", - "sunderlad", "sunderland", - "sunglases", "sunglasses", - "superfluu", "superfluous", - "superiour", "superior", - "superisor", "superiors", - "supermare", "supermarket", - "superviso", "supervision", - "suposedly", "supposedly", - "supportes", "supports", - "suppreses", "suppress", - "supressed", "suppressed", - "supresses", "suppresses", - "suprising", "surprising", - "suprizing", "surprising", - "supsicion", "suspicion", - "surounded", "surrounded", - "surprized", "surprised", - "surronded", "surrounded", - "surrouded", "surrounded", - "surrouned", "surround", - "survivers", "survivors", - "survivied", "survived", - "survivour", "survivor", - "susbcribe", "subscribe", - "susbtrate", "substrate", - "susncreen", "sunscreen", - "suspectes", "suspects", - "suspendes", "suspense", - "suspensie", "suspense", - "swastikka", "swastika", - "sweatshit", "sweatshirt", - "sweetheat", "sweetheart", - "switchign", "switching", - "swithcing", "switching", - "swtiching", "switching", - "sydnicate", "syndicate", - "sykwalker", "skywalker", - "sylablles", "syllables", - "syllabels", "syllables", - "symbolsim", "symbolism", - "symettric", "symmetric", - "symmetral", "symmetric", - "symmetria", "symmetrical", - "symoblism", "symbolism", - "sympathie", "sympathize", - "symphoney", "symphony", - "symptomes", "symptoms", - "symptomps", "symptoms", - "synagouge", "synagogue", - "syndacite", "syndicate", - "syndiacte", "syndicate", - "synidcate", "syndicate", - "synonymes", "synonyms", - "synonymis", "synonyms", - "synonymns", "synonyms", - "synonymos", "synonymous", - "synonymus", "synonyms", - "synopsies", "synopsis", - "syntehsis", "synthesis", - "syntehtic", "synthetic", - "syntethic", "synthetic", - "syphyllis", "syphilis", - "syracusae", "syracuse", - "sytrofoam", "styrofoam", - "tablespon", "tablespoon", - "tacticaly", "tactically", - "tanenhill", "tannehill", - "tannheill", "tannehill", - "targetted", "targeted", - "tawainese", "taiwanese", - "tawianese", "taiwanese", - "taxanomic", "taxonomic", - "teamfighs", "teamfights", - "teamfigth", "teamfight", - "teamifght", "teamfight", - "teampseak", "teamspeak", - "teaspooon", "teaspoon", - "techician", "technician", - "techinque", "technique", - "technolgy", "technology", - "teeangers", "teenagers", - "tehtering", "tethering", - "telegrpah", "telegraph", - "televsion", "television", - "temafight", "teamfight", - "tempaltes", "templates", - "temparate", "temperate", - "templaras", "templars", - "templares", "templars", - "temporali", "temporarily", - "tenacitiy", "tenacity", - "tensiones", "tensions", - "tentacels", "tentacles", - "tentacuel", "tentacle", - "tentalces", "tentacles", - "termianls", "terminals", - "terminato", "termination", - "terorrism", "terrorism", - "terorrist", "terrorist", - "terrabyte", "terabyte", - "terribley", "terribly", - "terriblly", "terribly", - "terriroty", "territory", - "terrorits", "terrorist", - "terrorsim", "terrorism", - "tesitcles", "testicles", - "tesitmony", "testimony", - "testicels", "testicles", - "testomony", "testimony", - "texturers", "textures", - "thankfuly", "thankfully", - "thankyoou", "thankyou", - "themselfs", "themselves", - "themselvs", "themselves", - "themslves", "themselves", - "theologia", "theological", - "therafter", "thereafter", - "therefoer", "therefor", - "therefour", "therefor", - "theroists", "theorists", - "thetering", "tethering", - "thirlling", "thrilling", - "thirteeen", "thirteen", - "thoecracy", "theocracy", - "thoerists", "theorists", - "thoroughy", "thoroughly", - "thoughout", "throughout", - "threatend", "threatened", - "throrough", "thorough", - "throughly", "thoroughly", - "througout", "throughout", - "thrusdays", "thursdays", - "thurdsays", "thursdays", - "thursdsay", "thursdays", - "thursters", "thrusters", - "tiawanese", "taiwanese", - "timestmap", "timestamp", - "tirangles", "triangles", - "tocuhdown", "touchdown", - "toghether", "together", - "tolerence", "tolerance", - "tommorrow", "tomorrow", - "torandoes", "tornadoes", - "torchligt", "torchlight", - "torelable", "tolerable", - "toritllas", "tortillas", - "tornaodes", "tornadoes", - "torpeados", "torpedoes", - "torrentas", "torrents", - "torrentes", "torrents", - "tortialls", "tortillas", - "tortillia", "tortilla", - "tortillla", "tortilla", - "tottehnam", "tottenham", - "tottenahm", "tottenham", - "tottneham", "tottenham", - "toturials", "tutorials", - "touchdwon", "touchdown", - "touristas", "tourists", - "touristes", "tourists", - "touristey", "touristy", - "touristly", "touristy", - "touristsy", "touristy", - "tournamet", "tournament", - "toxicitiy", "toxicity", - "trafficed", "trafficked", - "tragicaly", "tragically", - "traileras", "trailers", - "traingles", "triangles", - "trainwrek", "trainwreck", - "traitoris", "traitors", - "traitorus", "traitors", - "tramautic", "traumatic", - "tranlsate", "translate", - "transalte", "translate", - "transcris", "transcripts", - "transcrit", "transcript", - "transferd", "transferred", - "transfere", "transferred", - "transfors", "transforms", - "transfrom", "transform", - "transiten", "transient", - "transitin", "transitions", - "transofrm", "transform", - "transplat", "transplant", - "trasnfers", "transfers", - "trasnform", "transform", - "trasnport", "transport", - "traversie", "traverse", - "travestry", "travesty", - "treasuers", "treasures", - "treasurey", "treasury", - "treatmens", "treatments", - "treausres", "treasures", - "tremendos", "tremendous", - "trhilling", "thrilling", - "trhusters", "thrusters", - "triangels", "triangles", - "trianlges", "triangles", - "tribunaal", "tribunal", - "triguered", "triggered", - "trinagles", "triangles", - "truamatic", "traumatic", - "truthfuly", "truthfully", - "tunrtable", "turntable", - "turnaroud", "turnaround", - "turntabel", "turntable", - "typcially", "typically", - "tyrranies", "tyrannies", - "ubiquitos", "ubiquitous", - "ugprading", "upgrading", - "ukrainain", "ukrainian", - "ukrainias", "ukrainians", - "ukrainina", "ukrainian", - "ukrainisn", "ukrainians", - "ukrianian", "ukrainian", - "ulitmatum", "ultimatum", - "ulteriour", "ulterior", - "umbrellla", "umbrella", - "unaminous", "unanimous", - "unanmious", "unanimous", - "unanswerd", "unanswered", - "unanymous", "unanimous", - "unbannend", "unbanned", - "uncensord", "uncensored", - "uncomited", "uncommitted", - "undercunt", "undercut", - "underdong", "underdog", - "undergard", "undergrad", - "underming", "undermining", - "understad", "understands", - "underwaer", "underwear", - "underware", "underwear", - "undescore", "underscore", - "unforseen", "unforeseen", - "unfortune", "unfortunate", - "unfriendy", "unfriendly", - "unhealhty", "unhealthy", - "unheathly", "unhealthy", - "unhelathy", "unhealthy", - "unicornis", "unicorns", - "unicornus", "unicorns", - "uniformes", "uniforms", - "uninamous", "unanimous", - "unintuive", "unintuitive", - "uniquelly", "uniquely", - "unisntall", "uninstall", - "univerity", "university", - "universse", "universes", - "univesity", "university", - "unnistall", "uninstall", - "unoffical", "unofficial", - "unopenend", "unopened", - "unplayabe", "unplayable", - "unplesant", "unpleasant", - "unpopluar", "unpopular", - "unrankend", "unranked", - "unreliabe", "unreliable", - "unrwitten", "unwritten", - "untrianed", "untrained", - "unusaully", "unusually", - "unuseable", "unusable", - "unusuable", "unusable", - "unvierses", "universes", - "unweildly", "unwieldy", - "unwieldly", "unwieldy", - "unwirtten", "unwritten", - "unworthly", "unworthy", - "upcomming", "upcoming", - "upgarding", "upgrading", - "upgradded", "upgraded", - "uplfiting", "uplifting", - "uplifitng", "uplifting", - "urkainian", "ukrainian", - "utlimatum", "ultimatum", - "vacciante", "vaccinate", - "vaccinato", "vaccination", - "vacciners", "vaccines", - "vacestomy", "vasectomy", - "vaguaries", "vagaries", - "vaibility", "viability", - "vaildated", "validated", - "vairables", "variables", - "valdiated", "validated", - "valentein", "valentine", - "valentien", "valentine", - "valentins", "valentines", - "validitiy", "validity", - "valueable", "valuable", - "vanadlism", "vandalism", - "vandalsim", "vandalism", - "varaibles", "variables", - "varations", "variations", - "variantes", "variants", - "vascetomy", "vasectomy", - "vastecomy", "vasectomy", - "veganisim", "veganism", - "vegetarin", "vegetarians", - "vegitable", "vegetable", - "vehementy", "vehemently", - "veiwpoint", "viewpoint", - "velantine", "valentine", - "vendettta", "vendetta", - "venegance", "vengeance", - "veneuzela", "venezuela", - "venezeula", "venezuela", - "venezulea", "venezuela", - "vengaence", "vengeance", - "vengenace", "vengeance", - "ventilato", "ventilation", - "verbatium", "verbatim", - "verfiying", "verifying", - "verifiyng", "verifying", - "verisions", "revisions", - "versalite", "versatile", - "versatily", "versatility", - "versiones", "versions", - "versitale", "versatile", - "verstaile", "versatile", - "verticaly", "vertically", - "veryifing", "verifying", - "vicotrian", "victorian", - "vicotries", "victories", - "victoires", "victories", - "victorain", "victorian", - "victorina", "victorian", - "victorios", "victorious", - "videogaem", "videogame", - "videogams", "videogames", - "vidoegame", "videogame", - "viewpiont", "viewpoint", - "vigilence", "vigilance", - "vigliante", "vigilante", - "vigourous", "vigorous", - "viligante", "vigilante", - "viloently", "violently", - "vincinity", "vicinity", - "vioalting", "violating", - "violentce", "violence", - "virbation", "vibration", - "virgintiy", "virginity", - "virignity", "virginity", - "virutally", "virtually", - "visibiliy", "visibility", - "vitaminas", "vitamins", - "vitamines", "vitamins", - "vitrually", "virtually", - "vociemail", "voicemail", - "voilating", "violating", - "voilation", "violation", - "voilently", "violently", - "volatiliy", "volatility", - "voleyball", "volleyball", - "volontary", "voluntary", - "volonteer", "volunteer", - "volunatry", "voluntary", - "volunteed", "volunteered", - "vriginity", "virginity", - "wallpapes", "wallpapers", - "warrantly", "warranty", - "warrriors", "warriors", - "wavelengh", "wavelength", - "weakenend", "weakened", - "weakneses", "weakness", - "weaknesss", "weaknesses", - "wealtheir", "wealthier", - "weaponary", "weaponry", - "wedensday", "wednesday", - "wednesdsy", "wednesdays", - "wednessay", "wednesdays", - "wednseday", "wednesday", - "welathier", "wealthier", - "wendesday", "wednesday", - "wesbtrook", "westbrook", - "westernes", "westerners", - "westrbook", "westbrook", - "whereever", "wherever", - "whietlist", "whitelist", - "whilrwind", "whirlwind", - "whilsting", "whistling", - "whipsered", "whispered", - "whislting", "whistling", - "whisperes", "whispers", - "whitelsit", "whitelist", - "whitleist", "whitelist", - "whitsling", "whistling", - "whrilwind", "whirlwind", - "whsipered", "whispered", - "whtielist", "whitelist", - "widespred", "widespread", - "widesread", "widespread", - "windshied", "windshield", - "wintesses", "witnesses", - "wisconisn", "wisconsin", - "wishlisht", "wishlist", - "wishpered", "whispered", - "withdrawl", "withdrawal", - "withelist", "whitelist", - "witnesess", "witnesses", - "wolrdview", "worldview", - "wolrdwide", "worldwide", - "wonderlad", "wonderland", - "wordlview", "worldview", - "wordlwide", "worldwide", - "worhtless", "worthless", - "workfroce", "workforce", - "worldivew", "worldview", - "worldveiw", "worldview", - "worstened", "worsened", - "worthelss", "worthless", - "xenbolade", "xenoblade", - "xenobalde", "xenoblade", - "xenophoby", "xenophobia", - "xeonblade", "xenoblade", - "yementite", "yemenite", - "yorkshrie", "yorkshire", - "yorskhire", "yorkshire", - "yosemitie", "yosemite", - "youngents", "youngest", - "yourselvs", "yourselves", - "zimbabwae", "zimbabwe", - "zionistas", "zionists", - "zionistes", "zionists", - "abandond", "abandoned", - "abdomine", "abdomen", - "abilitiy", "ability", - "abilties", "abilities", - "abondons", "abandons", - "aboslute", "absolute", - "abosrbed", "absorbed", - "abruplty", "abruptly", - "abrutply", "abruptly", - "abscence", "absence", - "absestos", "asbestos", - "absoluts", "absolutes", - "absolvte", "absolve", - "absorbes", "absorbs", - "absoulte", "absolute", - "abstante", "bastante", - "abudance", "abundance", - "abudcted", "abducted", - "abundunt", "abundant", - "aburptly", "abruptly", - "abuseres", "abusers", - "abusrdly", "absurdly", - "academis", "academics", - "accademy", "academy", - "acccused", "accused", - "acceptes", "accepts", - "accidens", "accidents", - "accideny", "accidently", - "accoring", "according", - "accountt", "accountant", - "accpeted", "accepted", - "accuarcy", "accuracy", - "accumule", "accumulate", - "accusato", "accusation", - "accussed", "accused", - "acedamia", "academia", - "acedemic", "academic", - "acheived", "achieved", - "acheives", "achieves", - "achieval", "achievable", - "acnedote", "anecdote", - "acording", "according", - "acornyms", "acronyms", - "acousitc", "acoustic", - "acoutsic", "acoustic", - "acovados", "avocados", - "acquifer", "acquire", - "acquited", "acquitted", - "acquried", "acquired", - "acronmys", "acronyms", - "acronysm", "acronyms", - "acroynms", "acronyms", - "acrynoms", "acronyms", - "acsended", "ascended", - "actaully", "actually", - "activite", "activities", - "activits", "activities", - "activley", "actively", - "actresss", "actresses", - "actualey", "actualy", - "actualiy", "actuality", - "actualky", "actualy", - "actualmy", "actualy", - "actualoy", "actualy", - "actualpy", "actualy", - "actualty", "actualy", - "acutally", "actually", - "acutions", "auctions", - "adaptare", "adapter", - "adbandon", "abandon", - "adbucted", "abducted", - "addictes", "addicts", - "addictin", "addictions", - "addictis", "addictions", - "addional", "additional", - "addopted", "adopted", - "addresed", "addressed", - "adealide", "adelaide", - "adecuate", "adequate", - "adeilade", "adelaide", - "adeladie", "adelaide", - "adeliade", "adelaide", - "adeqaute", "adequate", - "adheisve", "adhesive", - "adhevise", "adhesive", - "adivsors", "advisors", - "admiraal", "admiral", - "adolence", "adolescent", - "adorbale", "adorable", - "adovcacy", "advocacy", - "adpaters", "adapters", - "adquired", "acquired", - "adquires", "acquires", - "adresing", "addressing", - "adressed", "addressed", - "adroable", "adorable", - "adultrey", "adultery", - "adventue", "adventures", - "adventus", "adventures", - "advertis", "adverts", - "advesary", "adversary", - "adviseer", "adviser", - "adviseur", "adviser", - "advocade", "advocated", - "advocats", "advocates", - "advsiors", "advisors", - "aethists", "atheists", - "affaires", "affairs", - "affilate", "affiliate", - "affintiy", "affinity", - "affleunt", "affluent", - "affulent", "affluent", - "afircans", "africans", - "africain", "african", - "afternon", "afternoon", - "againnst", "against", - "agnositc", "agnostic", - "agonstic", "agnostic", - "agravate", "aggravate", - "agreemnt", "agreement", - "agregate", "aggregate", - "agressie", "agressive", - "agressor", "aggressor", - "agrieved", "aggrieved", - "agruable", "arguable", - "agruably", "arguably", - "agrument", "argument", - "ahtletes", "athletes", - "aincents", "ancients", - "airboner", "airborne", - "airbrone", "airborne", - "aircarft", "aircraft", - "airplans", "airplanes", - "airporta", "airports", - "airpsace", "airspace", - "airscape", "airspace", - "akransas", "arkansas", - "alchemey", "alchemy", - "alchohol", "alcohol", - "alcholic", "alcoholic", - "alcoholc", "alcoholics", - "aldutery", "adultery", - "aleniate", "alienate", - "algoritm", "algorithm", - "alimoney", "alimony", - "alirghty", "alrighty", - "allaince", "alliance", - "alledged", "alleged", - "alledges", "alleges", - "allegedy", "allegedly", - "allegely", "allegedly", - "allegric", "allergic", - "allergey", "allergy", - "allianse", "alliances", - "alligned", "aligned", - "allinace", "alliance", - "allopone", "allophone", - "allready", "already", - "almigthy", "almighty", - "alpahbet", "alphabet", - "alrigthy", "alrighty", - "altantic", "atlantic", - "alterato", "alteration", - "alternar", "alternator", - "althetes", "athletes", - "althetic", "athletic", - "altriusm", "altruism", - "altrusim", "altruism", - "alturism", "altruism", - "aluminim", "aluminium", - "alumnium", "aluminum", - "alunimum", "aluminum", - "amatersu", "amateurs", - "amaterus", "amateurs", - "amendmet", "amendments", - "amercian", "american", - "amercias", "americas", - "amernian", "armenian", - "amethsyt", "amethyst", - "ameythst", "amethyst", - "ammended", "amended", - "amnestry", "amnesty", - "amoungst", "amongst", - "amplifiy", "amplify", - "amplifly", "amplify", - "amrchair", "armchair", - "amrenian", "armenian", - "amtheyst", "amethyst", - "analgoue", "analogue", - "analisys", "analysis", - "analitic", "analytic", - "analouge", "analogue", - "analysie", "analyse", - "analysit", "analyst", - "analyste", "analyse", - "analysze", "analyse", - "analzyed", "analyzed", - "anaolgue", "analogue", - "anarchim", "anarchism", - "anaylses", "analyses", - "anaylsis", "analysis", - "anaylsts", "analysts", - "anaylzed", "analyzed", - "ancedote", "anecdote", - "anceints", "ancients", - "ancinets", "ancients", - "andoirds", "androids", - "andorids", "androids", - "andriods", "androids", - "anecdots", "anecdotes", - "anectode", "anecdote", - "anedocte", "anecdote", - "aneroxia", "anorexia", - "aneroxic", "anorexic", - "angostic", "agnostic", - "angrilly", "angrily", - "anicents", "ancients", - "animatie", "animate", - "animatte", "animate", - "anlayses", "analyses", - "annoints", "anoints", - "annouced", "announced", - "annoucne", "announce", - "anntenas", "antennas", - "anoerxia", "anorexia", - "anoerxic", "anorexic", - "anonymos", "anonymous", - "anoreixa", "anorexia", - "anounced", "announced", - "anoxeria", "anorexia", - "anoxeric", "anorexic", - "answeres", "answers", - "antartic", "antarctic", - "antennea", "antenna", - "antennna", "antenna", - "anticipe", "anticipate", - "antiquae", "antique", - "antivirs", "antivirus", - "anwsered", "answered", - "anyhting", "anything", - "anyhwere", "anywhere", - "anyoneis", "anyones", - "anythign", "anything", - "anytying", "anything", - "aparment", "apartment", - "apartmet", "apartments", - "apenines", "apennines", - "aperutre", "aperture", - "aplhabet", "alphabet", - "apologes", "apologise", - "aposltes", "apostles", - "apostels", "apostles", - "appaluse", "applause", - "apparant", "apparent", - "appareal", "apparel", - "appareil", "apparel", - "apperead", "appeared", - "applaued", "applaud", - "appluase", "applause", - "appology", "apology", - "apporach", "approach", - "appraoch", "approach", - "apreture", "aperture", - "apsotles", "apostles", - "aqaurium", "aquarium", - "aqcuired", "acquired", - "aquaduct", "aqueduct", - "aquairum", "aquarium", - "aquaruim", "aquarium", - "aquiring", "acquiring", - "aquitted", "acquitted", - "arbitary", "arbitrary", - "arbitray", "arbitrary", - "arbiture", "arbiter", - "architet", "architect", - "archtype", "archetype", - "aremnian", "armenian", - "argentia", "argentina", - "argubaly", "arguably", - "arguemet", "arguement", - "arguemtn", "arguement", - "ariborne", "airborne", - "aricraft", "aircraft", - "ariplane", "airplane", - "ariports", "airports", - "arispace", "airspace", - "aristote", "aristotle", - "aritfact", "artifact", - "arizonia", "arizona", - "arkasnas", "arkansas", - "arlighty", "alrighty", - "armamant", "armament", - "armenain", "armenian", - "armenina", "armenian", - "armpitts", "armpits", - "armstrog", "armstrong", - "arpanoid", "paranoid", - "arpeture", "aperture", - "arragned", "arranged", - "arrestes", "arrests", - "arrestos", "arrests", - "arsenaal", "arsenal", - "artemios", "artemis", - "artemius", "artemis", - "arthrits", "arthritis", - "articule", "articulate", - "artifacs", "artifacts", - "artifcat", "artifact", - "artilley", "artillery", - "artisitc", "artistic", - "artistas", "artists", - "arugable", "arguable", - "arugably", "arguably", - "arugment", "argument", - "asborbed", "absorbed", - "asburdly", "absurdly", - "ascneded", "ascended", - "asissted", "assisted", - "askreddt", "askreddit", - "asnwered", "answered", - "aspectos", "aspects", - "asperges", "aspergers", - "assasins", "assassins", - "assemple", "assemble", - "assertin", "assertions", - "asshates", "asshats", - "asshatts", "asshats", - "assimile", "assimilate", - "assistat", "assistants", - "assitant", "assistant", - "assmeble", "assemble", - "assmebly", "assembly", - "asssasin", "assassin", - "assualts", "assaults", - "asteorid", "asteroid", - "asteriks", "asterisk", - "asteriod", "asteroid", - "asterois", "asteroids", - "astersik", "asterisk", - "asthetic", "aesthetic", - "astronat", "astronaut", - "asutrian", "austrian", - "atheisim", "atheism", - "atheistc", "atheistic", - "atheltes", "athletes", - "atheltic", "athletic", - "athenean", "athenian", - "athesits", "atheists", - "athetlic", "athletic", - "athients", "athiest", - "atittude", "attitude", - "atlantia", "atlanta", - "atmoizer", "atomizer", - "atomzier", "atomizer", - "atribute", "attribute", - "atrifact", "artifact", - "attackes", "attackers", - "attemped", "attempted", - "attemted", "attempted", - "attemtps", "attempts", - "attidute", "attitude", - "attitide", "attitude", - "attribue", "attribute", - "aucitons", "auctions", - "audactiy", "audacity", - "audcaity", "audacity", - "audeince", "audience", - "audiobok", "audiobook", - "austeriy", "austerity", - "austiran", "austrian", - "austitic", "autistic", - "austrain", "austrian", - "australa", "australian", - "austrija", "austria", - "austrila", "austria", - "autisitc", "autistic", - "autoattk", "autoattack", - "autograh", "autograph", - "automato", "automation", - "automony", "autonomy", - "autority", "authority", - "autsitic", "autistic", - "auxilary", "auxiliary", - "avacodos", "avocados", - "avaiable", "available", - "availabe", "available", - "availble", "available", - "avaition", "aviation", - "avalable", "available", - "avalance", "avalanche", - "avataras", "avatars", - "avatards", "avatars", - "avatares", "avatars", - "averadge", "averaged", - "avergaed", "averaged", - "avergaes", "averages", - "aviaiton", "aviation", - "avilable", "available", - "avnegers", "avengers", - "avodacos", "avocados", - "awekened", "weakened", - "awesomey", "awesomely", - "awfullly", "awfully", - "awkwardy", "awkwardly", - "awnsered", "answered", - "babysite", "babysitter", - "baceause", "because", - "bacehlor", "bachelor", - "bachleor", "bachelor", - "bacholer", "bachelor", - "backeast", "backseat", - "backerds", "backers", - "backfied", "backfield", - "backpacs", "backpacks", - "balcanes", "balances", - "balconey", "balcony", - "balconny", "balcony", - "ballistc", "ballistic", - "balnaced", "balanced", - "banannas", "bananas", - "banditas", "bandits", - "bandwith", "bandwidth", - "bangkock", "bangkok", - "baptisim", "baptism", - "barabric", "barbaric", - "barbarin", "barbarian", - "barbaris", "barbarians", - "bardford", "bradford", - "bargaing", "bargaining", - "baristia", "barista", - "barrakcs", "barracks", - "barrells", "barrels", - "basicaly", "basically", - "basiclay", "basicly", - "basicley", "basicly", - "basicliy", "basicly", - "batistia", "batista", - "battalin", "battalion", - "bayonent", "bayonet", - "beachead", "beachhead", - "beacuoup", "beaucoup", - "beardude", "bearded", - "beastley", "beastly", - "beatiful", "beautiful", - "beccause", "because", - "becuasse", "becuase", - "befirend", "befriend", - "befreind", "befriend", - "begginer", "beginner", - "begginig", "begging", - "begginng", "begging", - "begining", "beginning", - "beginnig", "beginning", - "behaivor", "behavior", - "behavios", "behaviours", - "behavoir", "behavior", - "behavour", "behavior", - "behngazi", "benghazi", - "behtesda", "bethesda", - "beleived", "believed", - "beleiver", "believer", - "beleives", "believes", - "beliefes", "beliefs", - "benefica", "beneficial", - "bengahzi", "benghazi", - "bengalas", "bengals", - "bengalos", "bengals", - "bengazhi", "benghazi", - "benghzai", "benghazi", - "bengzhai", "benghazi", - "benhgazi", "benghazi", - "benidect", "benedict", - "benifits", "benefits", - "berekley", "berkeley", - "berserkr", "berserker", - "beseiged", "besieged", - "betehsda", "bethesda", - "beteshda", "bethesda", - "bethdesa", "bethesda", - "bethedsa", "bethesda", - "bethseda", "bethesda", - "beyoncye", "beyonce", - "bibilcal", "biblical", - "bicylces", "bicycles", - "bigfooot", "bigfoot", - "bigining", "beginning", - "bilbical", "biblical", - "billboad", "billboard", - "bilsters", "blisters", - "bilzzard", "blizzard", - "bilzzcon", "blizzcon", - "biologia", "biological", - "birhtday", "birthday", - "birsbane", "brisbane", - "birthdsy", "birthdays", - "biseuxal", "bisexual", - "bisexaul", "bisexual", - "bitcions", "bitcoins", - "bitocins", "bitcoins", - "blackade", "blacked", - "blackend", "blacked", - "blackjak", "blackjack", - "blacklit", "blacklist", - "blatanty", "blatantly", - "blessins", "blessings", - "blessure", "blessing", - "bloggare", "blogger", - "bloggeur", "blogger", - "bluebery", "blueberry", - "bluetooh", "bluetooth", - "blugaria", "bulgaria", - "boardway", "broadway", - "bollcoks", "bollocks", - "bomberos", "bombers", - "bookmars", "bookmarks", - "boradway", "broadway", - "boredoom", "boredom", - "bouldore", "boulder", - "bounites", "bounties", - "boutnies", "bounties", - "boutqiue", "boutique", - "bouyancy", "buoyancy", - "boyfried", "boyfriend", - "bradcast", "broadcast", - "bradfrod", "bradford", - "brakeout", "breakout", - "braodway", "broadway", - "braverly", "bravery", - "breathis", "breaths", - "breathos", "breaths", - "brekaout", "breakout", - "brendamn", "brendan", - "breweres", "brewers", - "brewerey", "brewery", - "brewerks", "brewers", - "brewerys", "brewers", - "brigaged", "brigade", - "brigated", "brigade", - "brigthen", "brighten", - "briliant", "brilliant", - "brillant", "brilliant", - "bristool", "bristol", - "brithday", "birthday", - "brittish", "british", - "briusers", "bruisers", - "broadbad", "broadband", - "broadcat", "broadcasts", - "broadley", "broadly", - "brocolli", "broccoli", - "brodaway", "broadway", - "broncoes", "broncos", - "broswing", "browsing", - "browines", "brownies", - "browisng", "browsing", - "brtually", "brutally", - "brugundy", "burgundy", - "bruisend", "bruised", - "brussles", "brussels", - "brusting", "bursting", - "bubblews", "bubbles", - "buddhits", "buddhist", - "buddhsim", "buddhism", - "buddishm", "buddhism", - "buddisht", "buddhist", - "buglaria", "bulgaria", - "buhddism", "buddhism", - "buhddist", "buddhist", - "buidlers", "builders", - "buidling", "building", - "buildins", "buildings", - "buisness", "business", - "bulagria", "bulgaria", - "bulgaira", "bulgaria", - "buliders", "builders", - "buliding", "building", - "bulletts", "bullets", - "burisers", "bruisers", - "burriots", "burritos", - "burritio", "burrito", - "burritto", "burrito", - "burrtios", "burritos", - "burssels", "brussels", - "burtally", "brutally", - "burtsing", "bursting", - "busrting", "bursting", - "butcherd", "butchered", - "butterey", "buttery", - "butterfy", "butterfly", - "butterry", "buttery", - "butthoel", "butthole", - "bycicles", "bicycles", - "cabbagge", "cabbage", - "cabients", "cabinets", - "cabinate", "cabinet", - "cabinent", "cabinet", - "cabniets", "cabinets", - "caclulus", "calculus", - "cafetera", "cafeteria", - "caffinee", "caffeine", - "cahsiers", "cashiers", - "cainster", "canister", - "calander", "calendar", - "calcular", "calculator", - "calgarry", "calgary", - "calibler", "calibre", - "caloires", "calories", - "calrkson", "clarkson", - "calroies", "calories", - "calssify", "classify", - "calulate", "calculate", - "calymore", "claymore", - "camapign", "campaign", - "cambodai", "cambodia", - "camboida", "cambodia", - "cambpell", "campbell", - "cambride", "cambridge", - "cambrige", "cambridge", - "camoufle", "camouflage", - "campagin", "campaign", - "campaing", "campaign", - "campains", "campaigns", - "camperas", "campers", - "camperos", "campers", - "canadias", "canadians", - "cananbis", "cannabis", - "cancelas", "cancels", - "canceles", "cancels", - "cancells", "cancels", - "canceres", "cancers", - "cancerns", "cancers", - "cancerus", "cancers", - "candiate", "candidate", - "candiens", "candies", - "canistre", "canister", - "cannabil", "cannibal", - "cannbial", "cannibal", - "cannibas", "cannabis", - "cansiter", "canister", - "capitans", "captains", - "capitola", "capital", - "capitulo", "capitol", - "capmbell", "campbell", - "capsuels", "capsules", - "capsulse", "capsules", - "capsumel", "capsule", - "capteurs", "captures", - "captials", "capitals", - "captians", "captains", - "capusles", "capsules", - "caputres", "captures", - "cardboad", "cardboard", - "cardianl", "cardinal", - "cardnial", "cardinal", - "careflly", "carefully", - "carefull", "careful", - "carefuly", "carefully", - "caricate", "caricature", - "caridgan", "cardigan", - "caridnal", "cardinal", - "carinval", "carnival", - "carloina", "carolina", - "carnagie", "carnegie", - "carnigie", "carnegie", - "carnvial", "carnival", - "carrotts", "carrots", - "carrotus", "carrots", - "cartells", "cartels", - "cartmaan", "cartman", - "cartride", "cartridge", - "cartrige", "cartridge", - "carvinal", "carnival", - "casaulty", "casualty", - "casheirs", "cashiers", - "cashieer", "cashier", - "cashires", "cashiers", - "castleos", "castles", - "castlers", "castles", - "casulaty", "casualty", - "cataclym", "cataclysm", - "catagory", "category", - "cataline", "catiline", - "cataloge", "catalogue", - "catalsyt", "catalyst", - "cataylst", "catalyst", - "cathloic", "catholic", - "catlayst", "catalyst", - "caucasin", "caucasian", - "causalty", "casualty", - "cellural", "cellular", - "celullar", "cellular", - "celverly", "cleverly", - "cemetary", "cemetery", - "centeres", "centers", - "centerns", "centers", - "centrase", "centres", - "centrers", "centres", - "ceratine", "creatine", - "cerberal", "cerebral", - "cerbreus", "cerberus", - "cerbures", "cerberus", - "ceremone", "ceremonies", - "cerimony", "ceremony", - "ceromony", "ceremony", - "certainy", "certainty", - "challege", "challenge", - "chambear", "chamber", - "chambres", "chambers", - "champage", "champagne", - "chanisaw", "chainsaw", - "chanlder", "chandler", - "charcaol", "charcoal", - "chargehr", "charger", - "chargeur", "charger", - "chariman", "chairman", - "charimsa", "charisma", - "charmisa", "charisma", - "charocal", "charcoal", - "charsima", "charisma", - "chasiers", "cashiers", - "chassids", "chassis", - "chassies", "chassis", - "chatolic", "catholic", - "chcukles", "chuckles", - "checkare", "checker", - "checkear", "checker", - "cheesees", "cheeses", - "cheeseus", "cheeses", - "cheetoos", "cheetos", - "chemcial", "chemical", - "chemisty", "chemistry", - "chernobl", "chernobyl", - "chiansaw", "chainsaw", - "chidlish", "childish", - "chihuaha", "chihuahua", - "childres", "childrens", - "chillade", "chilled", - "chillead", "chilled", - "chillend", "chilled", - "chilvary", "chivalry", - "chinesse", "chinese", - "chivarly", "chivalry", - "chivlary", "chivalry", - "chlidish", "childish", - "chlroine", "chlorine", - "chmabers", "chambers", - "chocolae", "chocolates", - "chocolet", "chocolates", - "choesive", "cohesive", - "choicers", "choices", - "cholrine", "chlorine", - "chorline", "chlorine", - "chracter", "character", - "christin", "christian", - "chroline", "chlorine", - "chromose", "chromosome", - "chronice", "chronicles", - "chruches", "churches", - "chuckels", "chuckles", - "cielings", "ceilings", - "cigarete", "cigarettes", - "cigarets", "cigarettes", - "cilmbers", "climbers", - "cilnatro", "cilantro", - "ciltoris", "clitoris", - "circiuts", "circuits", - "circkets", "crickets", - "circlebs", "circles", - "circluar", "circular", - "ciricuit", "circuit", - "cirlcing", "circling", - "ciruclar", "circular", - "clannand", "clannad", - "clarifiy", "clarify", - "clarskon", "clarkson", - "clasical", "classical", - "classrom", "classroom", - "classsic", "classics", - "clausens", "clauses", - "cleanies", "cleanse", - "cleasner", "cleanser", - "clenaser", "cleanser", - "clevelry", "cleverly", - "clhorine", "chlorine", - "cliamtes", "climates", - "cliantro", "cilantro", - "clickare", "clicker", - "clickbat", "clickbait", - "clickear", "clicker", - "clientes", "clients", - "clincial", "clinical", - "clinicas", "clinics", - "clinicos", "clinics", - "clipboad", "clipboard", - "clitiros", "clitoris", - "closeing", "closing", - "closeley", "closely", - "clyamore", "claymore", - "clyinder", "cylinder", - "cmoputer", "computer", - "coindice", "coincide", - "collapes", "collapse", - "collares", "collars", - "collaris", "collars", - "collaros", "collars", - "collaspe", "collapse", - "colleage", "colleagues", - "collecte", "collective", - "collegue", "colleague", - "collisin", "collisions", - "collosal", "colossal", - "collpase", "collapse", - "coloardo", "colorado", - "colordao", "colorado", - "colubmia", "columbia", - "columnas", "columns", - "comadres", "comrades", - "comander", "commander", - "comandos", "commandos", - "comapany", "company", - "comapres", "compares", - "combiens", "combines", - "combinig", "combining", - "comediac", "comedic", - "comedias", "comedians", - "comestic", "cosmetic", - "comision", "commission", - "comiting", "committing", - "comitted", "committed", - "comittee", "committee", - "commandd", "commanded", - "commecen", "commence", - "commedic", "comedic", - "commense", "commenters", - "commenty", "commentary", - "commiest", "commits", - "commited", "committed", - "commitee", "committee", - "commites", "commits", - "committe", "committee", - "committs", "commits", - "commitus", "commits", - "commmand", "command", - "communit", "communist", - "companis", "companions", - "comparse", "compares", - "comparte", "compare", - "compasso", "compassion", - "compelte", "complete", - "compense", "compensate", - "complais", "complains", - "complane", "complacent", - "complate", "complacent", - "compleet", "complete", - "completi", "complexity", - "complets", "completes", - "complety", "completely", - "complexs", "complexes", - "complext", "complexity", - "complexy", "complexity", - "complict", "complicit", - "complier", "compiler", - "compones", "compose", - "componet", "components", - "componts", "compost", - "composet", "compost", - "composit", "compost", - "composte", "compose", - "comprese", "compressed", - "compreso", "compressor", - "compsers", "compress", - "comptown", "compton", - "compunet", "compute", - "computre", "compute", - "comradre", "comrade", - "comsetic", "cosmetic", - "conatins", "contains", - "conceald", "concealed", - "conceide", "conceived", - "conceled", "concede", - "concened", "concede", - "concepta", "conceptual", - "concered", "concede", - "concernt", "concert", - "concerte", "concrete", - "concesso", "concession", - "conceted", "concede", - "conceved", "concede", - "concibes", "concise", - "concider", "consider", - "concides", "concise", - "concious", "conscious", - "conclued", "conclude", - "concluse", "conclusive", - "concluso", "conclusion", - "concreet", "concrete", - "concrets", "concerts", - "condemnd", "condemned", - "conditon", "condition", - "condomes", "condoms", - "condomns", "condoms", - "conduict", "conduit", - "conected", "connected", - "conencts", "connects", - "confeses", "confess", - "confesos", "confess", - "confesso", "confession", - "configue", "configure", - "confilct", "conflict", - "confirmd", "confirmed", - "conflcit", "conflict", - "conflics", "conflicts", - "confrims", "confirms", - "conicide", "coincide", - "conlcude", "conclude", - "conqueor", "conquer", - "conquerd", "conquered", - "conqured", "conquered", - "conscent", "consent", - "consious", "conscious", - "constans", "constants", - "constast", "constants", - "constatn", "constant", - "constrat", "constraint", - "construt", "constructs", - "containd", "contained", - "containg", "containing", - "contaire", "containers", - "contanti", "contacting", - "contense", "contenders", - "contenst", "contents", - "contexta", "contextual", - "contextl", "contextual", - "contians", "contains", - "contined", "continued", - "contines", "continents", - "continum", "continuum", - "continus", "continues", - "continut", "continuity", - "continuu", "continuous", - "contracr", "contractor", - "contracs", "contracts", - "controll", "control", - "convenit", "convenient", - "convento", "convention", - "converst", "converts", - "convertr", "converter", - "conviced", "convinced", - "convicto", "conviction", - "convingi", "convincing", - "convinse", "convinces", - "cooldows", "cooldowns", - "coordine", "coordinate", - "coralina", "carolina", - "corollla", "corolla", - "corolloa", "corolla", - "corosion", "corrosion", - "corpsers", "corpses", - "corrdior", "corridor", - "correcty", "correctly", - "correnti", "correcting", - "corretly", "correctly", - "corrupto", "corruption", - "cosemtic", "cosmetic", - "cosutmes", "costumes", - "couldnot", "couldnt", - "coulored", "coloured", - "counries", "countries", - "counseil", "counsel", - "counsole", "counsel", - "counterd", "countered", - "countert", "counteract", - "countres", "counters", - "courtrom", "courtroom", - "courtsey", "courtesy", - "cousines", "cousins", - "cousings", "cousins", - "coutners", "counters", - "covanent", "covenant", - "coverted", "converted", - "coyotees", "coyotes", - "cpatains", "captains", - "cranbery", "cranberry", - "crayones", "crayons", - "creaeted", "created", - "createin", "creatine", - "createur", "creature", - "creatien", "creatine", - "creepgin", "creeping", - "cricling", "circling", - "cringely", "cringey", - "cringery", "cringey", - "criticas", "critics", - "critices", "critics", - "criticie", "criticise", - "criticim", "criticisms", - "criticis", "critics", - "criticms", "critics", - "criticos", "critics", - "criticts", "critics", - "criticus", "critics", - "critiera", "criteria", - "critized", "criticized", - "croatioa", "croatia", - "crossfie", "crossfire", - "crosshar", "crosshair", - "crosspot", "crosspost", - "crowbahr", "crowbar", - "cruasder", "crusader", - "cruciaal", "crucial", - "crucibel", "crucible", - "cruicble", "crucible", - "crusdaer", "crusader", - "crusiers", "cruisers", - "crusiing", "cruising", - "cruthces", "crutches", - "cthulhlu", "cthulhu", - "cthulluh", "cthulhu", - "cubpoard", "cupboard", - "cuddleys", "cuddles", - "culprint", "culprit", - "cultrual", "cultural", - "culutral", "cultural", - "cupbaord", "cupboard", - "cupborad", "cupboard", - "curcible", "crucible", - "curisers", "cruisers", - "curising", "cruising", - "currecny", "currency", - "currence", "currencies", - "currenly", "currently", - "currenty", "currently", - "cursader", "crusader", - "custcene", "cutscene", - "cutsceen", "cutscene", - "cutscens", "cutscenes", - "cutsence", "cutscene", - "cylcists", "cyclists", - "cylidner", "cylinder", - "cylindre", "cylinder", - "cynisicm", "cynicism", - "cyrstals", "crystals", - "dacquiri", "daiquiri", - "daimonds", "diamonds", - "dangeros", "dangers", - "dangerus", "dangers", - "darkenss", "darkness", - "darnkess", "darkness", - "dashboad", "dashboard", - "daugther", "daughter", - "deadlfit", "deadlift", - "deadlifs", "deadlifts", - "deafeted", "defeated", - "deafults", "defaults", - "dealying", "delaying", - "deamenor", "demeanor", - "deathcat", "deathmatch", - "debuffes", "debuffs", - "debufffs", "debuffs", - "decalred", "declared", - "decalres", "declares", - "decembre", "december", - "decidely", "decidedly", - "decieved", "deceived", - "decifits", "deficits", - "decipted", "depicted", - "declears", "declares", - "declinig", "declining", - "decmeber", "december", - "decribed", "described", - "decribes", "describes", - "dedicato", "dedication", - "deductie", "deductible", - "defautls", "defaults", - "defectos", "defects", - "defectus", "defects", - "defendas", "defends", - "defendes", "defenders", - "defendis", "defends", - "defendre", "defender", - "defendrs", "defends", - "defensea", "defenseman", - "defensen", "defenseman", - "defensie", "defensive", - "defetead", "defeated", - "deffined", "defined", - "deficiet", "deficient", - "definate", "definite", - "definaty", "definately", - "definety", "definetly", - "definito", "definition", - "definitv", "definitive", - "deflatin", "deflation", - "deflecto", "deflection", - "defualts", "defaults", - "degarded", "degraded", - "degenere", "degenerate", - "degraged", "degrade", - "degrated", "degrade", - "deisgned", "designed", - "deisgner", "designer", - "dekstops", "desktops", - "delcared", "declared", - "delcares", "declares", - "delepted", "depleted", - "delivere", "deliveries", - "delpeted", "depleted", - "delpoyed", "deployed", - "delyaing", "delaying", - "demandas", "demands", - "demandes", "demands", - "demenaor", "demeanor", - "democray", "democracy", - "demolito", "demolition", - "denseley", "densely", - "densitiy", "density", - "deomcrat", "democrat", - "deovtion", "devotion", - "departer", "departure", - "departue", "departure", - "depcited", "depicted", - "depelted", "depleted", - "dependat", "dependant", - "depictes", "depicts", - "depictin", "depictions", - "depolyed", "deployed", - "depositd", "deposited", - "depostis", "deposits", - "depresse", "depressive", - "depresso", "depression", - "derivate", "derivative", - "descened", "descend", - "descibed", "described", - "descirbe", "describe", - "descrise", "describes", - "desgined", "designed", - "desginer", "designer", - "desicive", "decisive", - "designad", "designated", - "designes", "designs", - "designet", "designated", - "desinged", "designed", - "desinger", "designer", - "desitned", "destined", - "desktiop", "desktop", - "desorder", "disorder", - "despides", "despised", - "despiste", "despise", - "destiney", "destiny", - "destinty", "destiny", - "destkops", "desktops", - "destorys", "destroys", - "destrose", "destroyers", - "destroyd", "destroyed", - "destroyr", "destroyers", - "detalied", "detailed", - "detectas", "detects", - "detectes", "detects", - "detectie", "detectives", - "determen", "determines", - "devasted", "devastated", - "develope", "develop", - "devialet", "deviate", - "deviatie", "deviate", - "devilers", "delivers", - "devloved", "devolved", - "devovled", "devolved", - "diaganol", "diagonal", - "diagnoal", "diagonal", - "diagnoes", "diagnose", - "diagnosi", "diagnostic", - "diagonse", "diagnose", - "diahrrea", "diarrhea", - "dialetcs", "dialects", - "dialgoue", "dialogue", - "dialouge", "dialogue", - "diarreah", "diarrhea", - "diarreha", "diarrhea", - "dichtomy", "dichotomy", - "dickisch", "dickish", - "dicovers", "discovers", - "dicovery", "discovery", - "dicussed", "discussed", - "diferent", "different", - "differnt", "different", - "difficut", "difficulty", - "diffrent", "different", - "diganose", "diagnose", - "dignitiy", "dignity", - "dimaonds", "diamonds", - "dinasour", "dinosaur", - "dinosaus", "dinosaurs", - "dinosuar", "dinosaur", - "dinsoaur", "dinosaur", - "dionsaur", "dinosaur", - "diphtong", "diphthong", - "diplomma", "diploma", - "dipthong", "diphthong", - "direclty", "directly", - "directin", "directions", - "directix", "directx", - "directos", "directors", - "directoy", "directory", - "directrx", "directx", - "dirfting", "drifting", - "disabeld", "disabled", - "disabels", "disables", - "disagred", "disagreed", - "disagres", "disagrees", - "disbaled", "disabled", - "disbales", "disables", - "disbelif", "disbelief", - "dischard", "discharged", - "dischare", "discharged", - "discound", "discounted", - "discoure", "discourse", - "discoved", "discovered", - "discreto", "discretion", - "discribe", "describe", - "disentry", "dysentery", - "disgiuse", "disguise", - "dishoner", "dishonored", - "dishonet", "dishonesty", - "dislikse", "dislikes", - "dismante", "dismantle", - "dismisse", "dismissive", - "disolved", "dissolved", - "dispacth", "dispatch", - "dispalys", "displays", - "dispence", "dispense", - "dispersa", "dispensary", - "displayd", "displayed", - "disposle", "dispose", - "disposte", "dispose", - "dispoves", "dispose", - "disptach", "dispatch", - "disricts", "districts", - "dissovle", "dissolve", - "distates", "distaste", - "distatse", "distaste", - "disticnt", "distinct", - "distorto", "distortion", - "distrcit", "district", - "districs", "districts", - "disturbd", "disturbed", - "disupted", "disputed", - "disuptes", "disputes", - "diversed", "diverse", - "diversiy", "diversify", - "dividens", "dividends", - "divintiy", "divinity", - "divisons", "divisions", - "doapmine", "dopamine", - "docrines", "doctrines", - "docrtine", "doctrine", - "doctines", "doctrines", - "doctirne", "doctrine", - "doctrins", "doctrines", - "dogamtic", "dogmatic", - "dolhpins", "dolphins", - "domapine", "dopamine", - "domecrat", "democrat", - "domiante", "dominate", - "dominato", "domination", - "dominats", "dominates", - "dominent", "dominant", - "dominoin", "dominion", - "donwload", "download", - "donwvote", "downvote", - "doomdsay", "doomsday", - "doosmday", "doomsday", - "doplhins", "dolphins", - "dopmaine", "dopamine", - "dormtund", "dortmund", - "dortumnd", "dortmund", - "dotrmund", "dortmund", - "douchely", "douchey", - "doucheus", "douches", - "dowloads", "downloads", - "downlaod", "download", - "downloas", "downloads", - "downstar", "downstairs", - "downvore", "downvoters", - "downvotr", "downvoters", - "downvots", "downvotes", - "draculea", "dracula", - "draculla", "dracula", - "dragones", "dragons", - "dragonus", "dragons", - "drfiting", "drifting", - "driectly", "directly", - "drifitng", "drifting", - "driveris", "drivers", - "drotmund", "dortmund", - "duaghter", "daughter", - "dumbbels", "dumbbells", - "dumptser", "dumpster", - "dumspter", "dumpster", - "dunegons", "dungeons", - "dungeoun", "dungeon", - "dungoens", "dungeons", - "dupicate", "duplicate", - "duplicas", "duplicates", - "dwarvens", "dwarves", - "dyanmics", "dynamics", - "dyanmite", "dynamite", - "dymanics", "dynamics", - "dymanite", "dynamite", - "dynastry", "dynasty", - "dysentry", "dysentery", - "dysphora", "dysphoria", - "earilest", "earliest", - "eatswood", "eastwood", - "eceonomy", "economy", - "ecidious", "deciduous", - "ecologia", "ecological", - "ecomonic", "economic", - "ecstacys", "ecstasy", - "ecstascy", "ecstasy", - "ecstasty", "ecstasy", - "ectastic", "ecstatic", - "editoras", "editors", - "editores", "editors", - "efficent", "efficient", - "egpytian", "egyptian", - "egyptain", "egyptian", - "egytpian", "egyptian", - "ehtereal", "ethereal", - "ehternet", "ethernet", - "eigtheen", "eighteen", - "electhor", "electro", - "electorn", "electron", - "elementy", "elementary", - "elephans", "elephants", - "elevatin", "elevation", - "elicided", "elicited", - "eligable", "eligible", - "elimiate", "eliminate", - "eliminas", "eliminates", - "elitisim", "elitism", - "elitistm", "elitism", - "ellected", "elected", - "embarass", "embarrass", - "embargos", "embargoes", - "embarras", "embarrass", - "embassay", "embassy", - "embassey", "embassy", - "embasssy", "embassy", - "emergend", "emerged", - "emergerd", "emerged", - "eminated", "emanated", - "emminent", "eminent", - "emmisary", "emissary", - "emmision", "emission", - "emmiting", "emitting", - "emmitted", "emitted", - "empathie", "empathize", - "empirial", "empirical", - "emulatin", "emulation", - "enahnces", "enhances", - "enchanct", "enchant", - "encolsed", "enclosed", - "endanged", "endangered", - "endevors", "endeavors", - "endevour", "endeavour", - "endlessy", "endlessly", - "endorces", "endorse", - "engeneer", "engineer", - "engeries", "energies", - "engineed", "engineered", - "engrames", "engrams", - "engramms", "engrams", - "enigneer", "engineer", - "enitrely", "entirely", - "enlcosed", "enclosed", - "enlsaved", "enslaved", - "ensalved", "enslaved", - "enterity", "entirety", - "entierly", "entirely", - "entierty", "entirety", - "entilted", "entitled", - "entirley", "entirely", - "entiteld", "entitled", - "entitity", "entity", - "entropay", "entropy", - "entrophy", "entropy", - "ephipany", "epiphany", - "epihpany", "epiphany", - "epilespy", "epilepsy", - "epilgoue", "epilogue", - "episdoes", "episodes", - "epitomie", "epitome", - "epliepsy", "epilepsy", - "epliogue", "epilogue", - "epsiodes", "episodes", - "epsresso", "espresso", - "eqaulity", "equality", - "eqaution", "equation", - "equailty", "equality", - "eraticly", "erratically", - "erroneos", "erroneous", - "errupted", "erupted", - "escalato", "escalation", - "esctatic", "ecstatic", - "esential", "essential", - "esitmate", "estimate", - "esperate", "seperate", - "esportes", "esports", - "estiamte", "estimate", - "estoeric", "esoteric", - "estonija", "estonia", - "estoniya", "estonia", - "etherael", "ethereal", - "etherent", "ethernet", - "ethicaly", "ethically", - "etiquete", "etiquette", - "etrailer", "retailer", - "eugencis", "eugenics", - "eugneics", "eugenics", - "euhporia", "euphoria", - "euhporic", "euphoric", - "euorpean", "european", - "euphoira", "euphoria", - "euphroia", "euphoria", - "euphroic", "euphoric", - "europian", "european", - "eurpoean", "european", - "evangers", "avengers", - "everyons", "everyones", - "evidencd", "evidenced", - "evidende", "evidenced", - "evloving", "evolving", - "evolveds", "evolves", - "evolveos", "evolves", - "evovling", "evolving", - "excecute", "execute", - "excedded", "exceeded", - "excelent", "excellent", - "exceptin", "exceptions", - "excerise", "exercise", - "excisted", "existed", - "exclusie", "exclusives", - "exculded", "excluded", - "exculdes", "excludes", - "exection", "execution", - "exectued", "executed", - "executie", "executive", - "executin", "execution", - "exellent", "excellent", - "exerbate", "exacerbate", - "exercide", "exercised", - "exercies", "exercise", - "exersice", "exercise", - "exersize", "exercise", - "exhalted", "exalted", - "exhaustn", "exhaustion", - "exhausto", "exhaustion", - "exicting", "exciting", - "exisitng", "existing", - "existane", "existance", - "existant", "existent", - "existend", "existed", - "exlcuded", "excluded", - "exlcudes", "excludes", - "exlporer", "explorer", - "exoticas", "exotics", - "exoticos", "exotics", - "expalins", "explains", - "expandas", "expands", - "expandes", "expands", - "expansie", "expansive", - "expectes", "expects", - "expectus", "expects", - "expedito", "expedition", - "expences", "expense", - "expensie", "expense", - "expensve", "expense", - "expertas", "experts", - "expertis", "experts", - "expertos", "experts", - "expireds", "expires", - "explaind", "explained", - "explaing", "explaining", - "expliots", "exploits", - "explodie", "explode", - "exploint", "exploit", - "explosie", "explosive", - "explosin", "explosions", - "exploted", "explode", - "expoldes", "explodes", - "expolits", "exploits", - "exportas", "exports", - "exportes", "exports", - "exportfs", "exports", - "exposees", "exposes", - "exposito", "exposition", - "expresse", "expressive", - "expresss", "expresses", - "expressy", "expressly", - "exressed", "expressed", - "exsitent", "existent", - "exsiting", "existing", - "extactly", "exactly", - "extemely", "extremely", - "extendes", "extends", - "extendos", "extends", - "extenion", "extension", - "extensie", "extensive", - "extensis", "extensions", - "extortin", "extortion", - "extracto", "extraction", - "extreems", "extremes", - "extremly", "extremely", - "eygptian", "egyptian", - "faboulus", "fabulous", - "fabricas", "fabrics", - "fabrices", "fabrics", - "fabricus", "fabrics", - "faceplam", "facepalm", - "facilisi", "facilities", - "faciltiy", "facility", - "facsists", "fascists", - "factores", "factors", - "factorys", "factors", - "factualy", "factually", - "faggotts", "faggots", - "faggotus", "faggots", - "falcones", "falcons", - "falgship", "flagship", - "faliures", "failures", - "falseley", "falsely", - "falshing", "flashing", - "falvored", "flavored", - "falvours", "flavours", - "familair", "familiar", - "famoulsy", "famously", - "fanatism", "fanaticism", - "fanatsic", "fanatics", - "fanserve", "fanservice", - "fantasty", "fantasy", - "farcking", "fracking", - "fascisim", "fascism", - "fashiond", "fashioned", - "fasicsts", "fascists", - "fatigure", "fatigue", - "favorits", "favorites", - "favourie", "favourites", - "feasable", "feasible", - "feasbile", "feasible", - "febraury", "february", - "februray", "february", - "feburary", "february", - "fedility", "fidelity", - "fedorahs", "fedoras", - "fedorans", "fedoras", - "feilding", "fielding", - "feisable", "feasible", - "feitshes", "fetishes", - "feltcher", "fletcher", - "felxible", "flexible", - "feminint", "femininity", - "feminsim", "feminism", - "feromone", "pheromone", - "fesiable", "feasible", - "festivas", "festivals", - "festivle", "festive", - "fictious", "fictitious", - "fideling", "fielding", - "fideltiy", "fidelity", - "fiedling", "fielding", - "fiedlity", "fidelity", - "fighitng", "fighting", - "figthing", "fighting", - "fileding", "fielding", - "fimilies", "families", - "finacial", "financial", - "fineshes", "finesse", - "fingersi", "fingertips", - "finnisch", "finnish", - "finsihes", "finishes", - "firebals", "fireballs", - "firendly", "friendly", - "firmwear", "firmware", - "firwmare", "firmware", - "flaghsip", "flagship", - "flamable", "flammable", - "flasghip", "flagship", - "flatterd", "flattered", - "flatteur", "flatter", - "flattire", "flatter", - "flavores", "flavors", - "flechter", "fletcher", - "flecther", "fletcher", - "flemmish", "flemish", - "flethcer", "fletcher", - "flexbile", "flexible", - "flexibel", "flexible", - "flippade", "flipped", - "flitered", "filtered", - "florecen", "florence", - "floridia", "florida", - "floruide", "fluoride", - "floruish", "flourish", - "flourine", "fluorine", - "floursih", "flourish", - "fluorish", "flourish", - "fluroide", "fluoride", - "folowing", "following", - "fontrier", "fontier", - "forasken", "forsaken", - "forbiden", "forbidden", - "foreamrs", "forearms", - "foreksin", "foreskin", - "forenics", "forensic", - "forenisc", "forensic", - "foresnic", "forensic", - "foreward", "foreword", - "foricbly", "forcibly", - "forigven", "forgiven", - "formatin", "formation", - "formelly", "formerly", - "formuals", "formulas", - "fornesic", "forensic", - "forresst", "forrest", - "forsekan", "forsaken", - "forsekin", "foreskin", - "forsenic", "forensic", - "forskaen", "forsaken", - "forsting", "frosting", - "fortitue", "fortitude", - "fortunae", "fortune", - "fortunte", "fortune", - "forumlas", "formulas", - "forunner", "forerunner", - "fossiles", "fossils", - "fossilis", "fossils", - "foundary", "foundry", - "fountian", "fountain", - "fourties", "forties", - "fowrards", "forwards", - "frackign", "fracking", - "framgent", "fragment", - "franches", "franchise", - "franchie", "franchises", - "franciso", "francisco", - "frankiln", "franklin", - "franlkin", "franklin", - "freckels", "freckles", - "freindly", "friendly", - "frequeny", "frequency", - "friendle", "friendlies", - "friendsi", "friendlies", - "frimware", "firmware", - "frogiven", "forgiven", - "frointer", "frontier", - "fromerly", "formerly", - "froniter", "frontier", - "fronteir", "frontier", - "frosaken", "forsaken", - "frutcose", "fructose", - "fucntion", "function", - "fufilled", "fulfilled", - "fulfiled", "fulfilled", - "fullfill", "fulfill", - "funciton", "function", - "fundirse", "fundies", - "funniliy", "funnily", - "funnilly", "funnily", - "furctose", "fructose", - "furition", "fruition", - "furuther", "further", - "futurers", "futures", - "futureus", "futures", - "gamemdoe", "gamemode", - "gamepaly", "gameplay", - "gamergat", "gamertag", - "gammeode", "gamemode", - "ganerate", "generate", - "garantee", "guarantee", - "gardient", "gradient", - "garfeild", "garfield", - "garfiled", "garfield", - "garflied", "garfield", - "garnison", "garrison", - "garrions", "garrison", - "garriosn", "garrison", - "garrsion", "garrison", - "gatherig", "gatherings", - "gauarana", "guaraná", - "gauntelt", "gauntlet", - "gauntles", "gauntlets", - "gaurdian", "guardian", - "gaurding", "guarding", - "gautnlet", "gauntlet", - "gemoetry", "geometry", - "generaly", "generally", - "generase", "generates", - "generats", "generates", - "genialia", "genitalia", - "genisues", "geniuses", - "genitala", "genitalia", - "genrates", "generates", - "gentials", "genitals", - "gentlemn", "gentlemen", - "genuises", "geniuses", - "geograpy", "geography", - "geomerty", "geometry", - "geomtery", "geometry", - "germanos", "germans", - "germanus", "germans", - "gernades", "grenades", - "giagbyte", "gigabyte", - "gigabtye", "gigabyte", - "gigaybte", "gigabyte", - "gigbayte", "gigabyte", - "gignatic", "gigantic", - "giltched", "glitched", - "giltches", "glitches", - "girafffe", "giraffe", - "girefing", "griefing", - "girlling", "grilling", - "gladiatr", "gladiator", - "glichted", "glitched", - "glichtes", "glitches", - "glicthed", "glitched", - "glicthes", "glitches", - "glitchey", "glitchy", - "glitchly", "glitchy", - "glitchty", "glitchy", - "glithced", "glitched", - "glithces", "glitches", - "gloablly", "globally", - "glodberg", "goldberg", - "glodfish", "goldfish", - "gloriuos", "glorious", - "gltiched", "glitched", - "gltiches", "glitches", - "gmaertag", "gamertag", - "goblings", "goblins", - "goddammn", "goddamn", - "goddammt", "goddammit", - "godesses", "goddesses", - "godlberg", "goldberg", - "godlfish", "goldfish", - "godounov", "godunov", - "godpseed", "godspeed", - "godspede", "godspeed", - "goldifsh", "goldfish", - "gonewidl", "gonewild", - "goodlcuk", "goodluck", - "goregous", "gorgeous", - "gorgoeus", "gorgeous", - "gorillia", "gorilla", - "gorillla", "gorilla", - "gospells", "gospels", - "gottleib", "gottlieb", - "gourmelt", "gourmet", - "gourment", "gourmet", - "gouvener", "governor", - "govement", "government", - "goverend", "governed", - "govermet", "goverment", - "governer", "governor", - "gradualy", "gradually", - "grafield", "garfield", - "grafitti", "graffiti", - "grahpics", "graphics", - "grahpite", "graphite", - "graident", "gradient", - "granolla", "granola", - "graphcis", "graphics", - "grapichs", "graphics", - "grappnel", "grapple", - "greandes", "grenades", - "greatful", "grateful", - "greeneer", "greener", - "greenhoe", "greenhouse", - "greenlad", "greenland", - "greenore", "greener", - "greusome", "gruesome", - "grieifng", "griefing", - "grifeing", "griefing", - "grizzlay", "grizzly", - "grizzley", "grizzly", - "grpahics", "graphics", - "grpahite", "graphite", - "gruseome", "gruesome", - "guantano", "guantanamo", - "guardain", "guardian", - "guardias", "guardians", - "guaridan", "guardian", - "guerrila", "guerrilla", - "guidence", "guidance", - "guiseppe", "giuseppe", - "guitards", "guitars", - "guitares", "guitars", - "guitarit", "guitarist", - "gullbile", "gullible", - "gunanine", "guanine", - "guniness", "guinness", - "gunniess", "guinness", - "guradian", "guardian", - "gurading", "guarding", - "gurantee", "guarantee", - "guresome", "gruesome", - "guttaral", "guttural", - "gutteral", "guttural", - "hacthing", "hatching", - "hafltime", "halftime", - "haircuit", "haircut", - "halfitme", "halftime", - "hallowen", "halloween", - "hamburgr", "hamburgers", - "hamitlon", "hamilton", - "hamliton", "hamilton", - "handcufs", "handcuffs", - "handeldy", "handedly", - "handlade", "handled", - "handlare", "handler", - "handledy", "handedly", - "hannbial", "hannibal", - "haording", "hoarding", - "hapening", "happening", - "happends", "happens", - "happenes", "happens", - "happilly", "happily", - "harldine", "hardline", - "harrased", "harassed", - "harrases", "harasses", - "hatchign", "hatching", - "hatesink", "heatsink", - "hathcing", "hatching", - "headachs", "headaches", - "headests", "headsets", - "headhsot", "headshot", - "headseat", "headset", - "healthit", "healthiest", - "heastink", "heatsink", - "heathern", "heathen", - "heatskin", "heatsink", - "heaviliy", "heavily", - "heavilly", "heavily", - "heavnely", "heavenly", - "hedeghog", "hedgehog", - "hegdehog", "hedgehog", - "heighest", "heights", - "heighted", "heightened", - "heirachy", "hierarchy", - "heistant", "hesitant", - "heistate", "hesitate", - "hellifre", "hellfire", - "helluvva", "helluva", - "helpfull", "helpful", - "heratige", "heritage", - "herclues", "hercules", - "heridity", "heredity", - "heroicas", "heroics", - "heroices", "heroics", - "heroicos", "heroics", - "heroicus", "heroics", - "hertiage", "heritage", - "herucles", "hercules", - "hestiant", "hesitant", - "hestiate", "hesitate", - "heveanly", "heavenly", - "hierachy", "hierarchy", - "hierarcy", "hierarchy", - "highlane", "highlander", - "hindiusm", "hinduism", - "hindusim", "hinduism", - "hinudism", "hinduism", - "hiptsers", "hipsters", - "hispanis", "hispanics", - "hispters", "hipsters", - "histroic", "historic", - "hodlings", "holdings", - "hoenstly", "honestly", - "hoildays", "holidays", - "holdiays", "holidays", - "hollywod", "hollywood", - "homeword", "homeworld", - "homineim", "hominem", - "homineum", "hominem", - "honeslty", "honestly", - "honeymon", "honeymoon", - "honsetly", "honestly", - "hopefuly", "hopefully", - "hopkings", "hopkins", - "hopsital", "hospital", - "horading", "hoarding", - "horzions", "horizons", - "hosptial", "hospital", - "hosteles", "hostels", - "hostiliy", "hostility", - "hotshoot", "hotshot", - "hotsport", "hotspot", - "hsyteria", "hysteria", - "htaching", "hatching", - "htiboxes", "hitboxes", - "huanting", "haunting", - "humaniod", "humanoid", - "humanite", "humanities", - "humantiy", "humanity", - "humerous", "humorous", - "huminoid", "humanoid", - "humitidy", "humidity", - "humoural", "humoral", - "humouros", "humorous", - "humurous", "humorous", - "hunderds", "hundreds", - "hundread", "hundred", - "hungarin", "hungarian", - "huntmsan", "huntsman", - "hutnsman", "huntsman", - "hybrides", "hybrids", - "hybridus", "hybrids", - "hydorgen", "hydrogen", - "hydratin", "hydration", - "hydregon", "hydrogen", - "hygience", "hygiene", - "hygienne", "hygiene", - "hyperbel", "hyperbole", - "hypocrit", "hypocrite", - "hyponsis", "hypnosis", - "hyrdogen", "hydrogen", - "icefrong", "icefrog", - "icelings", "ceilings", - "idaeidae", "idea", - "idealogy", "ideology", - "idealsim", "idealism", - "idenfity", "identify", - "idenitfy", "identify", - "identite", "identities", - "ideologe", "ideologies", - "illiegal", "illegal", - "illinios", "illinois", - "illionis", "illinois", - "illnesss", "illnesses", - "illumini", "illuminati", - "illustre", "illustrate", - "illution", "illusion", - "ilogical", "illogical", - "ilterate", "literate", - "imapired", "impaired", - "imgrants", "migrants", - "imigrant", "emigrant", - "immboile", "immobile", - "immenint", "imminent", - "immersie", "immerse", - "immersve", "immerse", - "immitate", "imitate", - "immoblie", "immobile", - "immortas", "immortals", - "impactes", "impacts", - "impactos", "impacts", - "imparied", "impaired", - "imperavi", "imperative", - "imperfet", "imperfect", - "implemet", "implements", - "implosed", "implode", - "impluses", "impulses", - "imporper", "improper", - "importas", "imports", - "importen", "importance", - "importes", "imports", - "imporved", "improved", - "imporves", "improves", - "impropre", "improper", - "improted", "imported", - "improvie", "improvised", - "impusles", "impulses", - "imrpoved", "improved", - "imrpoves", "improves", - "inbetwen", "inbetween", - "inclince", "incline", - "inclinde", "incline", - "includng", "including", - "incorect", "incorrect", - "incuding", "including", - "inculded", "included", - "indianas", "indians", - "indiands", "indians", - "indiania", "indiana", - "indianna", "indiana", - "indianos", "indians", - "indicato", "indication", - "indicats", "indicators", - "indonesa", "indonesia", - "indulgue", "indulge", - "infantis", "infants", - "infantus", "infants", - "infarred", "infrared", - "infectin", "infections", - "infermon", "inferno", - "infiltre", "infiltrate", - "infintie", "infinite", - "infintiy", "infinity", - "inflatie", "inflate", - "influens", "influences", - "informas", "informs", - "informis", "informs", - "infromal", "informal", - "infromed", "informed", - "ingenius", "ingenious", - "ingition", "ignition", - "ingorant", "ignorant", - "inheriet", "inherit", - "inherint", "inherit", - "inhumaan", "inhuman", - "inhumain", "inhuman", - "inifnite", "infinite", - "inifnity", "infinity", - "inisghts", "insights", - "initails", "initials", - "initaite", "initiate", - "initaled", "initialed", - "initally", "initially", - "initialy", "initially", - "initmacy", "intimacy", - "initmate", "intimate", - "injustie", "injustices", - "inlcuded", "included", - "inlcudes", "includes", - "innocens", "innocents", - "innocuos", "innocuous", - "innvoate", "innovate", - "inocence", "innocence", - "inpolite", "impolite", - "inpsired", "inspired", - "inquirey", "inquiry", - "inquirie", "inquire", - "inquiriy", "inquiry", - "inrested", "inserted", - "insanley", "insanely", - "insectes", "insects", - "insectos", "insects", - "insertas", "inserts", - "insertes", "inserts", - "insertos", "inserts", - "insidios", "insidious", - "insigths", "insights", - "insipred", "inspired", - "insipres", "inspires", - "insistas", "insists", - "insistes", "insists", - "insistis", "insists", - "insmonia", "insomnia", - "insomina", "insomnia", - "insonmia", "insomnia", - "inspried", "inspired", - "inspries", "inspires", - "instanse", "instances", - "instanty", "instantly", - "instered", "inserted", - "insticnt", "instinct", - "instincs", "instincts", - "institue", "institute", - "insultas", "insults", - "insultes", "insults", - "insultos", "insults", - "intamicy", "intimacy", - "intamite", "intimate", - "intendes", "intends", - "intendos", "intends", - "intentas", "intents", - "intented", "intended", - "interace", "interacted", - "interacs", "interacts", - "interect", "interacted", - "interent", "internet", - "interese", "interested", - "interfce", "interface", - "intergal", "integral", - "internts", "interns", - "internus", "interns", - "interpet", "interpret", - "interrim", "interim", - "interste", "interstate", - "interupt", "interrupt", - "intevene", "intervene", - "intially", "initially", - "intiials", "initials", - "intimaty", "intimately", - "intimide", "intimidate", - "intregal", "integral", - "intriuge", "intrigue", - "introdue", "introduces", - "introdus", "introduces", - "introvet", "introvert", - "intruige", "intrigue", - "intutive", "intuitive", - "inudstry", "industry", - "inventer", "inventor", - "invertes", "inverse", - "invincil", "invincible", - "invitato", "invitation", - "invloved", "involved", - "invloves", "involves", - "invovled", "involved", - "invovles", "involves", - "iranains", "iranians", - "iraninas", "iranians", - "iritable", "irritable", - "iritated", "irritated", - "ironicly", "ironically", - "irritato", "irritation", - "isalmist", "islamist", - "isarelis", "israelis", - "islamits", "islamist", - "islamsit", "islamist", - "islandes", "islanders", - "ismalist", "islamist", - "isntalls", "installs", - "isolatie", "isolate", - "israelli", "israeli", - "israleis", "israelis", - "isralies", "israelis", - "isrealis", "israelis", - "issueing", "issuing", - "italains", "italians", - "jaguards", "jaguars", - "jaguares", "jaguars", - "jailbrek", "jailbreak", - "jaimacan", "jamaican", - "jamacain", "jamaican", - "jamaicia", "jamaica", - "jamiacan", "jamaican", - "januaray", "january", - "janurary", "january", - "jeapardy", "jeopardy", - "jefferry", "jeffery", - "jefferty", "jeffery", - "jennigns", "jennings", - "jeoprady", "jeopardy", - "jepoardy", "jeopardy", - "jerusalm", "jerusalem", - "jewelrey", "jewelry", - "jewllery", "jewellery", - "joanthan", "jonathan", - "joepardy", "jeopardy", - "johanine", "johannine", - "jonatahn", "jonathan", - "journaal", "journal", - "journied", "journeyed", - "journies", "journeys", - "joysitck", "joystick", - "juadaism", "judaism", - "judaisim", "judaism", - "judgemet", "judgements", - "juducial", "judicial", - "jugnling", "jungling", - "junglign", "jungling", - "junlging", "jungling", - "justifiy", "justify", - "juveline", "juvenile", - "juvenlie", "juvenile", - "katemine", "ketamine", - "kennedey", "kennedy", - "ketmaine", "ketamine", - "keybaord", "keyboard", - "keyboars", "keyboards", - "keyborad", "keyboard", - "keychian", "keychain", - "kicthens", "kitchens", - "kindgoms", "kingdoms", - "kittiens", "kitties", - "knockbak", "knockback", - "knowlege", "knowledge", - "knuckels", "knuckles", - "koreanos", "koreans", - "kunckles", "knuckles", - "kurdisch", "kurdish", - "labatory", "lavatory", - "labenese", "lebanese", - "laboraty", "laboratory", - "laguages", "languages", - "landscae", "landscapes", - "langauge", "language", - "lanucher", "launcher", - "lanuches", "launches", - "laodouts", "loadouts", - "larwence", "lawrence", - "lasagnea", "lasagna", - "lasagnia", "lasagna", - "laucnhed", "launched", - "laucnher", "launcher", - "laucnhes", "launches", - "laundrey", "laundry", - "lawernce", "lawrence", - "lazyness", "laziness", - "leaglize", "legalize", - "lecteurs", "lectures", - "lecutres", "lectures", - "lefitsts", "leftists", - "leftsits", "leftists", - "legenday", "legendary", - "legionis", "legions", - "legitimt", "legitimate", - "lengthes", "lengths", - "lengthly", "lengthy", - "lentiles", "lentils", - "lentills", "lentils", - "lesbains", "lesbians", - "lesibans", "lesbians", - "levander", "lavender", - "levelign", "leveling", - "levetate", "levitate", - "leviathn", "leviathan", - "levleing", "leveling", - "liberato", "liberation", - "libertae", "liberate", - "libertea", "liberate", - "librarse", "libraries", - "licencie", "licence", - "licencse", "licence", - "liebrals", "liberals", - "liekable", "likeable", - "lifepsan", "lifespan", - "lifestel", "lifesteal", - "lifestye", "lifestyle", - "lighitng", "lighting", - "lightnig", "lightning", - "lightres", "lighters", - "lightrom", "lightroom", - "ligthers", "lighters", - "ligthing", "lighting", - "likebale", "likeable", - "limitant", "militant", - "limitato", "limitation", - "lincolin", "lincoln", - "lincolon", "lincoln", - "lineupes", "lineups", - "lingeire", "lingerie", - "lingiere", "lingerie", - "linnaena", "linnaean", - "lipstics", "lipsticks", - "liquidas", "liquids", - "liquides", "liquids", - "liquidos", "liquids", - "liscense", "license", - "lisenced", "silenced", - "listenes", "listens", - "listents", "listens", - "listners", "listeners", - "litature", "literature", - "litecion", "litecoin", - "liteicon", "litecoin", - "literaly", "literally", - "lithuana", "lithuania", - "litigato", "litigation", - "liverpol", "liverpool", - "logtiech", "logitech", - "longitme", "longtime", - "longtiem", "longtime", - "looseley", "loosely", - "loreplay", "roleplay", - "luanched", "launched", - "luancher", "launcher", - "luanches", "launches", - "lubricat", "lubricant", - "lucifear", "lucifer", - "luckilly", "luckily", - "macarino", "macaroni", - "machiens", "machines", - "mackeral", "mackerel", - "macthups", "matchups", - "magasine", "magazine", - "magazins", "magazines", - "magentic", "magnetic", - "magicain", "magician", - "magisine", "magazine", - "magizine", "magazine", - "magnetis", "magnets", - "magnited", "magnitude", - "magnitue", "magnitude", - "mainfest", "manifest", - "maintian", "maintain", - "majoroty", "majority", - "makrsman", "marksman", - "malariya", "malaria", - "malasiya", "malaysia", - "malasyia", "malaysia", - "malayisa", "malaysia", - "malyasia", "malaysia", - "mamalian", "mammalian", - "manadrin", "mandarin", - "manaully", "manually", - "mandaste", "mandates", - "mandrain", "mandarin", - "mandrian", "mandarin", - "maneveur", "maneuver", - "manevuer", "maneuver", - "manfiest", "manifest", - "mangetic", "magnetic", - "manglade", "mangled", - "manifeso", "manifesto", - "manipule", "manipulate", - "manouver", "maneuver", - "manuales", "manuals", - "manuever", "maneuver", - "maraconi", "macaroni", - "maradeur", "marauder", - "maraduer", "marauder", - "maragret", "margaret", - "marbleds", "marbles", - "margerat", "margaret", - "margines", "margins", - "margings", "margins", - "marginis", "margins", - "marignal", "marginal", - "marilyin", "marilyn", - "marinens", "marines", - "markedet", "marketed", - "markeras", "markers", - "markerts", "markers", - "marniers", "mariners", - "marraige", "marriage", - "marryied", "married", - "marskman", "marksman", - "maruader", "marauder", - "marvelos", "marvelous", - "marxisim", "marxism", - "mascarra", "mascara", - "massacer", "massacre", - "massarce", "massacre", - "massasge", "massages", - "masscare", "massacre", - "masteris", "masteries", - "masturbe", "masturbate", - "materias", "materials", - "mathcups", "matchups", - "mathewes", "mathews", - "matieral", "material", - "matterss", "mattress", - "mauarder", "marauder", - "maximini", "maximizing", - "mayalsia", "malaysia", - "maybelle", "maybelline", - "maylasia", "malaysia", - "mccarhty", "mccarthy", - "mcgergor", "mcgregor", - "mchanics", "mechanics", - "mclarean", "mclaren", - "mcreggor", "mcgregor", - "meagtron", "megatron", - "meancing", "menacing", - "meaninng", "meaning", - "meatbals", "meatballs", - "mecahnic", "mechanic", - "mechanim", "mechanism", - "mechanis", "mechanics", - "medacine", "medicine", - "medatite", "meditate", - "medeival", "medieval", - "medevial", "medieval", - "mediavel", "medieval", - "medicaly", "medically", - "mediciad", "medicaid", - "medicins", "medicines", - "medicore", "mediocre", - "medievel", "medieval", - "mediocer", "mediocre", - "mediocry", "mediocrity", - "mediorce", "mediocre", - "meditato", "meditation", - "mediveal", "medieval", - "medoicre", "mediocre", - "meerkrat", "meerkat", - "megatorn", "megatron", - "meidcare", "medicare", - "meixcans", "mexicans", - "melboure", "melbourne", - "meltodwn", "meltdown", - "memoriez", "memorize", - "mencaing", "menacing", - "menstrul", "menstrual", - "mentiong", "mentioning", - "meoldies", "melodies", - "merchans", "merchants", - "mercurcy", "mercury", - "mercurey", "mercury", - "merficul", "merciful", - "merhcant", "merchant", - "mericful", "merciful", - "messgaed", "messaged", - "messiach", "messiah", - "metagaem", "metagame", - "metahpor", "metaphor", - "metamage", "metagame", - "methapor", "metaphor", - "metldown", "meltdown", - "metricas", "metrics", - "metrices", "metrics", - "metropos", "metropolis", - "mexcians", "mexicans", - "mexicain", "mexican", - "mhytical", "mythical", - "michagan", "michigan", - "michgian", "michigan", - "microtax", "microatx", - "microwae", "microwaves", - "midfeild", "midfield", - "midfiled", "midfield", - "midifeld", "midfield", - "migrains", "migraines", - "migriane", "migraine", - "milennia", "millennia", - "miligram", "milligram", - "miliitas", "militias", - "miliraty", "military", - "militais", "militias", - "millenia", "millennia", - "millenna", "millennia", - "miltiant", "militant", - "minature", "miniature", - "mindcrak", "mindcrack", - "minerial", "mineral", - "mingiame", "minigame", - "minimage", "minigame", - "minimals", "minimalist", - "minimalt", "minimalist", - "minimini", "minimizing", - "minimium", "minimum", - "miniscue", "miniscule", - "minsiter", "minister", - "minsitry", "ministry", - "miraculu", "miraculous", - "miralces", "miracles", - "mircales", "miracles", - "mircoatx", "microatx", - "mirgaine", "migraine", - "mirorred", "mirrored", - "misnadry", "misandry", - "misogynt", "misogynist", - "missigno", "mission", - "missiony", "missionary", - "misslies", "missiles", - "missorui", "missouri", - "misspeld", "misspelled", - "mistakey", "mistakenly", - "mistread", "mistreated", - "mobiltiy", "mobility", - "moderats", "moderates", - "modulair", "modular", - "moleculs", "molecules", - "momentos", "moments", - "momentus", "moments", - "monagomy", "monogamy", - "mongoles", "mongols", - "mongolos", "mongols", - "monitord", "monitored", - "monogmay", "monogamy", - "monolite", "monolithic", - "monologe", "monologue", - "monolopy", "monopoly", - "monoploy", "monopoly", - "monopols", "monopolies", - "monrachy", "monarchy", - "monstros", "monstrous", - "montaban", "montana", - "montains", "mountains", - "montanha", "montana", - "montania", "montana", - "montanna", "montana", - "montanta", "montana", - "montanya", "montana", - "montaran", "montana", - "monteize", "monetize", - "monteral", "montreal", - "montiors", "monitors", - "montnana", "montana", - "montypic", "monotypic", - "monumnet", "monument", - "moonligt", "moonlight", - "moprhine", "morphine", - "morbildy", "morbidly", - "mordibly", "morbidly", - "morevoer", "moreover", - "morhpine", "morphine", - "moribdly", "morbidly", - "mormones", "mormons", - "mormonts", "mormons", - "moroever", "moreover", - "morotola", "motorola", - "morphein", "morphine", - "morriosn", "morrison", - "morrocco", "morocco", - "morrsion", "morrison", - "mortards", "mortars", - "mortarts", "mortars", - "moruning", "mourning", - "mosnters", "monsters", - "mosqueto", "mosquitoes", - "mosquite", "mosquitoes", - "mosqutio", "mosquito", - "motoroal", "motorola", - "mounment", "monument", - "mounring", "mourning", - "mountian", "mountain", - "moustace", "moustache", - "movesped", "movespeed", - "mozillia", "mozilla", - "mozillla", "mozilla", - "msytical", "mystical", - "mucnhies", "munchies", - "mudering", "murdering", - "muffings", "muffins", - "muffinus", "muffins", - "mulitple", "multiple", - "mulitply", "multiply", - "multiplr", "multiplier", - "multipls", "multiples", - "mundance", "mundane", - "mundande", "mundane", - "muniches", "munchies", - "murderes", "murders", - "murderus", "murders", - "muscluar", "muscular", - "muscualr", "muscular", - "musicaly", "musically", - "musuclar", "muscular", - "mutliple", "multiple", - "mutliply", "multiply", - "myhtical", "mythical", - "mysitcal", "mystical", - "mysogyny", "misogyny", - "mysteris", "mysteries", - "mythraic", "mithraic", - "nagivate", "navigate", - "naopleon", "napoleon", - "napcakes", "pancakes", - "naploeon", "napoleon", - "napoelon", "napoleon", - "napolean", "napoleon", - "napoloen", "napoleon", - "narcissm", "narcissism", - "narcisst", "narcissist", - "narcotis", "narcotics", - "narwharl", "narwhal", - "naseuous", "nauseous", - "nashvile", "nashville", - "nasueous", "nauseous", - "natievly", "natively", - "nationas", "nationals", - "nationsl", "nationals", - "nativley", "natively", - "natuilus", "nautilus", - "naturaly", "naturally", - "naturels", "natures", - "naturely", "naturally", - "naturens", "natures", - "naturual", "natural", - "nauesous", "nauseous", - "naughtly", "naughty", - "nauitlus", "nautilus", - "nauseuos", "nauseous", - "nautiuls", "nautilus", - "nautlius", "nautilus", - "nautulis", "nautilus", - "naviagte", "navigate", - "navigato", "navigation", - "nazereth", "nazareth", - "necesary", "necessary", - "neckbead", "neckbeard", - "needlees", "needles", - "nefarios", "nefarious", - "negativy", "negativity", - "neglectn", "neglecting", - "neglible", "negligible", - "neigbour", "neighbour", - "neolitic", "neolithic", - "netboook", "netbook", - "neuronas", "neurons", - "neutraal", "neutral", - "neutralt", "neutrality", - "neutraly", "neutrality", - "newcaste", "newcastle", - "nickanme", "nickname", - "nickmane", "nickname", - "nieghbor", "neighbor", - "nightime", "nighttime", - "nightley", "nightly", - "nightlie", "nightlife", - "nihilsim", "nihilism", - "nilihism", "nihilism", - "nirtogen", "nitrogen", - "nirvanna", "nirvana", - "nitorgen", "nitrogen", - "niusance", "nuisance", - "noctrune", "nocturne", - "noctunre", "nocturne", - "nocturen", "nocturne", - "nominato", "nomination", - "nonsence", "nonsense", - "nonsesne", "nonsense", - "noramlly", "normally", - "norhtern", "northern", - "normalis", "normals", - "normalls", "normals", - "normalos", "normals", - "northeat", "northeast", - "northren", "northern", - "northwet", "northwest", - "norwegin", "norwegian", - "nostalga", "nostalgia", - "nostirls", "nostrils", - "notabley", "notably", - "notablly", "notably", - "noteable", "notable", - "noteably", "notably", - "noticabe", "noticable", - "notorios", "notorious", - "novmeber", "november", - "nromandy", "normandy", - "nuatilus", "nautilus", - "nuculear", "nuclear", - "nuetered", "neutered", - "nuisanse", "nuisance", - "nullifiy", "nullify", - "nurtient", "nutrient", - "nusaince", "nuisance", - "nusiance", "nuisance", - "nutirent", "nutrient", - "nutriens", "nutrients", - "nuturing", "nurturing", - "obdisian", "obsidian", - "obediant", "obedient", - "obession", "obsession", - "obilvion", "oblivion", - "obisdian", "obsidian", - "obsessie", "obsessive", - "obsessin", "obsession", - "obsidain", "obsidian", - "obstacal", "obstacle", - "obvilion", "oblivion", - "ocasions", "occasions", - "ocassion", "occasion", - "occaison", "occasion", - "occupato", "occupation", - "occuring", "occurring", - "octobear", "october", - "octopuns", "octopus", - "ofcoruse", "ofcourse", - "ofcoures", "ofcourse", - "ofcousre", "ofcourse", - "ofcrouse", "ofcourse", - "officals", "officials", - "officaly", "officially", - "offsited", "offside", - "ofocurse", "ofcourse", - "oligarcy", "oligarchy", - "olmypics", "olympics", - "olymipcs", "olympics", - "olypmics", "olympics", - "ommision", "omission", - "ommiting", "omitting", - "ommitted", "omitted", - "ongewild", "gonewild", - "onslaugt", "onslaught", - "operatie", "operative", - "opinoins", "opinions", - "oppinion", "opinion", - "opponant", "opponent", - "opposits", "opposites", - "oppossed", "opposed", - "oppresso", "oppression", - "optimaal", "optimal", - "optomism", "optimism", - "oragnise", "organise", - "orangerd", "orangered", - "orangers", "oranges", - "orangism", "organism", - "orchesta", "orchestra", - "ordianry", "ordinary", - "oreintal", "oriental", - "orgainse", "organise", - "orgainze", "organize", - "organims", "organism", - "organsie", "organise", - "organsim", "organism", - "organzie", "organize", - "orgasmes", "orgasms", - "orgasmos", "orgasms", - "orgasmus", "orgasms", - "orginize", "organise", - "orhtodox", "orthodox", - "oridnary", "ordinary", - "originas", "origins", - "origines", "origins", - "originsl", "originals", - "orphanes", "orphans", - "osbidian", "obsidian", - "othrodox", "orthodox", - "ourselvs", "ourselves", - "oustider", "outsider", - "outfeild", "outfield", - "outfidel", "outfield", - "outfiled", "outfield", - "outisder", "outsider", - "outplayd", "outplayed", - "outputed", "outputted", - "outsoure", "outsourced", - "overboad", "overboard", - "overclok", "overclock", - "overdrev", "overdrive", - "overhual", "overhaul", - "overlaod", "overload", - "overpiad", "overpaid", - "overules", "overuse", - "overwath", "overwatch", - "overwhem", "overwhelm", - "oximoron", "oxymoron", - "oylmpics", "olympics", - "pacakged", "packaged", - "packadge", "packaged", - "paficist", "pacifist", - "painfuly", "painfully", - "paitence", "patience", - "paitents", "patients", - "palidans", "paladins", - "palstics", "plastics", - "paltform", "platform", - "paltinum", "platinum", - "palyable", "playable", - "palyoffs", "playoffs", - "pancaeks", "pancakes", - "panckaes", "pancakes", - "pandoria", "pandora", - "pandorra", "pandora", - "panedmic", "pandemic", - "panethon", "pantheon", - "pankaces", "pancakes", - "panmedic", "pandemic", - "pantehon", "pantheon", - "panthoen", "pantheon", - "paradies", "paradise", - "paradyse", "parades", - "paragrah", "paragraph", - "paraiste", "parasite", - "paralell", "parallel", - "paralely", "parallelly", - "paralles", "parallels", - "parameds", "paramedics", - "paramter", "parameter", - "paranioa", "paranoia", - "paraniod", "paranoid", - "paraside", "paradise", - "parasits", "parasites", - "parastie", "parasite", - "parctise", "practise", - "paremsan", "parmesan", - "paristan", "partisan", - "parmasen", "parmesan", - "parmenas", "parmesan", - "parmsean", "parmesan", - "parnters", "partners", - "parralel", "parallel", - "parterns", "partners", - "partialy", "partially", - "partians", "partisan", - "partical", "particular", - "particel", "particle", - "partiets", "parties", - "partiots", "patriots", - "partnerd", "partnered", - "partsian", "partisan", - "passabel", "passable", - "passione", "passionate", - "passisve", "passives", - "passpost", "passports", - "passvies", "passives", - "passwors", "passwords", - "pasttime", "pastime", - "pastural", "pastoral", - "pateince", "patience", - "pateints", "patients", - "patethic", "pathetic", - "patheitc", "pathetic", - "patienty", "patiently", - "patirots", "patriots", - "patriarh", "patriarchy", - "patroits", "patriots", - "patrolls", "patrols", - "patronas", "patrons", - "patrones", "patrons", - "patronis", "patrons", - "patronos", "patrons", - "pattened", "patented", - "patterno", "patterson", - "pattersn", "patterson", - "pblisher", "publisher", - "peageant", "pageant", - "pebbleos", "pebbles", - "pebblers", "pebbles", - "pebblets", "pebbles", - "peciluar", "peculiar", - "pecuilar", "peculiar", - "peculair", "peculiar", - "peculure", "peculiar", - "peformed", "performed", - "peircing", "piercing", - "penaltis", "penalties", - "penatgon", "pentagon", - "penciles", "pencils", - "pendatic", "pedantic", - "pengiuns", "penguins", - "penisula", "peninsula", - "pensioen", "pension", - "pepperin", "pepperoni", - "perceded", "preceded", - "percente", "percentile", - "percieve", "perceive", - "percious", "precious", - "perclude", "preclude", - "perfecty", "perfectly", - "perfroms", "performs", - "perheaps", "perhaps", - "pericing", "piercing", - "peridoic", "periodic", - "perimetr", "perimeter", - "periodes", "periods", - "periodos", "periods", - "permanet", "permanent", - "permiere", "premiere", - "permises", "premises", - "permitas", "permits", - "permites", "permits", - "permitis", "permits", - "permitts", "permits", - "permiums", "premiums", - "peroidic", "periodic", - "perosnas", "personas", - "perpetue", "perpetuate", - "persaude", "persuade", - "perserve", "preserve", - "persisit", "persist", - "personel", "personnel", - "persones", "persons", - "personis", "persons", - "personsa", "personas", - "perstige", "prestige", - "persuaso", "persuasion", - "persuded", "persuaded", - "persuing", "pursuing", - "persuits", "pursuits", - "persumed", "presumed", - "pertaing", "pertaining", - "pertians", "pertains", - "pertinet", "pertinent", - "pervents", "prevents", - "perverst", "pervert", - "perviews", "previews", - "pervious", "previous", - "perxoide", "peroxide", - "pessiary", "pessary", - "petetion", "petition", - "petrolem", "petroleum", - "phantoom", "phantom", - "pharamcy", "pharmacy", - "pharmacs", "pharmacist", - "pharmsci", "pharmacist", - "phenomon", "phenomenon", - "phramacy", "pharmacy", - "phsyical", "physical", - "phsyique", "physique", - "phyiscal", "physical", - "phyisque", "physique", - "physcial", "physical", - "physicis", "physicians", - "physicks", "physics", - "physicts", "physicist", - "physqiue", "physique", - "picthers", "pitchers", - "pillards", "pillars", - "pillaris", "pillars", - "pinancle", "pinnacle", - "pinapple", "pineapple", - "pinnalce", "pinnacle", - "pinnaple", "pineapple", - "pinncale", "pinnacle", - "pinpiont", "pinpoint", - "pinteret", "pinterest", - "piolting", "piloting", - "pioneeer", "pioneer", - "pithcers", "pitchers", - "placebro", "placebo", - "placemet", "placements", - "planetas", "planets", - "planetos", "planets", - "plantiff", "plaintiff", - "plantium", "platinum", - "plasitcs", "plastics", - "platfrom", "platform", - "platimun", "platinum", - "platnium", "platinum", - "platnuim", "platinum", - "plausibe", "plausible", - "playbody", "playboy", - "playstye", "playstyle", - "pleasent", "pleasant", - "plehtora", "plethora", - "pleothra", "plethora", - "plethroa", "plethora", - "ploygamy", "polygamy", - "pnatheon", "pantheon", - "poeoples", "peoples", - "poingant", "poignant", - "pointeur", "pointer", - "pointure", "pointer", - "poisones", "poisons", - "poisonis", "poisons", - "poisonos", "poisons", - "poisonus", "poisons", - "polgyamy", "polygamy", - "polietly", "politely", - "politing", "piloting", - "politley", "politely", - "poltical", "political", - "poluting", "polluting", - "polution", "pollution", - "polygoon", "polygon", - "polymore", "polymer", - "pomotion", "promotion", - "popoulus", "populous", - "populair", "popular", - "populare", "popular", - "populary", "popularity", - "porcelan", "porcelain", - "porposes", "proposes", - "portabel", "portable", - "portalis", "portals", - "portalus", "portals", - "portayed", "portrayed", - "portgual", "portugal", - "portrais", "portraits", - "portrary", "portray", - "portrayl", "portrayal", - "portriat", "portrait", - "posessed", "possessed", - "posesses", "possesses", - "posioned", "poisoned", - "positivs", "positives", - "positivy", "positivity", - "possable", "possible", - "possably", "possibly", - "possbily", "possibly", - "posseses", "possesses", - "possesse", "possessive", - "possesss", "possesses", - "potrayed", "portrayed", - "poverful", "powerful", - "powerded", "powdered", - "powerpot", "powerpoint", - "pracitse", "practise", - "practial", "practical", - "practies", "practise", - "pratcise", "practise", - "praticle", "particle", - "prceeded", "preceded", - "preadtor", "predator", - "preample", "preamble", - "preceeds", "precedes", - "precisie", "precise", - "precisly", "precisely", - "precisou", "precious", - "preculde", "preclude", - "predicat", "predict", - "predicte", "predictive", - "preferas", "prefers", - "prefered", "preferred", - "preferes", "prefers", - "preferis", "prefers", - "preferrs", "prefers", - "preimere", "premiere", - "preimums", "premiums", - "preiodic", "periodic", - "preivews", "previews", - "prejudis", "prejudices", - "prelayed", "replayed", - "premeire", "premiere", - "premesis", "premises", - "premiare", "premier", - "premines", "premise", - "premuims", "premiums", - "preorded", "preordered", - "preordes", "preorders", - "preoxide", "peroxide", - "prepaird", "prepaid", - "preqeuls", "prequels", - "prequles", "prequels", - "prescrie", "prescribed", - "presense", "presence", - "presenst", "presets", - "presidet", "presidents", - "presists", "persists", - "presitge", "prestige", - "presonas", "personas", - "presuade", "persuade", - "pretador", "predator", - "pretains", "pertains", - "preveiws", "previews", - "preverse", "perverse", - "previwes", "previews", - "pricipal", "principal", - "priciple", "principle", - "priemere", "premiere", - "priestes", "priests", - "primaris", "primaries", - "primarly", "primarily", - "princila", "principals", - "principl", "principals", - "prisitne", "pristine", - "probelms", "problems", - "probleem", "problem", - "procalim", "proclaim", - "proccess", "process", - "proceded", "proceeded", - "proceder", "procedure", - "procedes", "proceeds", - "procedue", "procedure", - "proceeed", "proceed", - "procesed", "proceeds", - "processs", "processes", - "proclami", "proclaim", - "procliam", "proclaim", - "procotol", "protocol", - "prodcuts", "products", - "producto", "production", - "profesor", "professor", - "proficit", "proficient", - "profilic", "prolific", - "progroms", "pogroms", - "prohibis", "prohibits", - "prohpecy", "prophecy", - "prohpets", "prophets", - "projecte", "projectile", - "projecto", "projection", - "prolouge", "prologue", - "promplty", "promptly", - "promptes", "prompts", - "promptus", "prompts", - "promtply", "promptly", - "pronoune", "pronounced", - "propechy", "prophecy", - "propehcy", "prophecy", - "propehts", "prophets", - "prophacy", "prophecy", - "propmted", "prompted", - "propmtly", "promptly", - "proponet", "proponents", - "proposse", "proposes", - "proposte", "propose", - "proprety", "property", - "propsect", "prospect", - "prosepct", "prospect", - "prostite", "prostitute", - "protable", "portable", - "protecte", "protective", - "protiens", "proteins", - "protines", "proteins", - "protocal", "protocol", - "prototye", "prototype", - "protrait", "portrait", - "protrays", "portrays", - "protugal", "portugal", - "proverai", "proverbial", - "providee", "providence", - "proximty", "proximity", - "pruchase", "purchase", - "pryamids", "pyramids", - "ptichers", "pitchers", - "pubisher", "publisher", - "publiser", "publisher", - "puinsher", "punisher", - "pulisher", "publisher", - "pumkpins", "pumpkins", - "pumpinks", "pumpkins", - "pumpknis", "pumpkins", - "punshier", "punisher", - "punsiher", "punisher", - "punsihes", "punishes", - "purcahse", "purchase", - "pyramind", "pyramid", - "pyrimads", "pyramids", - "pyrmaids", "pyramids", - "qauntity", "quantity", - "qualifiy", "qualify", - "quanitfy", "quantify", - "quantaty", "quantity", - "quantite", "quantities", - "quantuum", "quantum", - "quarante", "quarantine", - "quartery", "quarterly", - "qucikest", "quickest", - "queation", "equation", - "quention", "quentin", - "quickets", "quickest", - "quicklyu", "quickly", - "rabbitos", "rabbits", - "rabbitts", "rabbits", - "racistas", "racists", - "racistes", "racists", - "radaince", "radiance", - "rahpsody", "rhapsody", - "raidance", "radiance", - "railraod", "railroad", - "randomes", "randoms", - "randomez", "randomized", - "randomns", "randoms", - "randomrs", "randoms", - "randomus", "randoms", - "raosting", "roasting", - "raphsody", "rhapsody", - "raptores", "raptors", - "raspbery", "raspberry", - "rationel", "rationale", - "realible", "reliable", - "realibly", "reliably", - "realiest", "earliest", - "realisim", "realism", - "realisme", "realise", - "realistc", "realistic", - "realiste", "realise", - "realoded", "reloaded", - "realsied", "realised", - "realtion", "relation", - "realtive", "relative", - "reamined", "remained", - "reapired", "repaired", - "reaplugs", "earplugs", - "reaserch", "research", - "reasonal", "reasonably", - "reatiler", "retailer", - "reaveled", "revealed", - "rebellis", "rebellious", - "reboudns", "rebounds", - "rebounce", "rebound", - "rebuildt", "rebuilt", - "rebuplic", "republic", - "receeded", "receded", - "recepits", "receipts", - "receptie", "receptive", - "receptos", "receptors", - "receving", "receiving", - "recident", "resident", - "reciding", "residing", - "recieved", "received", - "reciever", "receiver", - "recieves", "receives", - "recipees", "recipes", - "recipets", "recipes", - "recogise", "recognise", - "recogize", "recognize", - "recognie", "recognizes", - "recomend", "recommend", - "recommed", "recommend", - "reconnet", "reconnect", - "rectange", "rectangle", - "rectifiy", "rectify", - "recuring", "recurring", - "recurits", "recruits", - "redeisgn", "redesign", - "redemeed", "redeemed", - "redesgin", "redesign", - "redesing", "redesign", - "reedemed", "redeemed", - "refeeres", "referees", - "refelcts", "reflects", - "refelxes", "reflexes", - "referede", "referee", - "referene", "referee", - "referens", "references", - "referere", "referee", - "referign", "refering", - "refering", "referring", - "refernce", "references", - "reffered", "referred", - "refilles", "refills", - "refillls", "refills", - "reflecte", "reflective", - "reflecto", "reflection", - "reformes", "reforms", - "refreing", "refering", - "refrence", "reference", - "refreshd", "refreshed", - "refreshr", "refresher", - "refromed", "reformed", - "regardes", "regards", - "regenade", "renegade", - "regenere", "regenerate", - "regiones", "regions", - "regisrty", "registry", - "registed", "registered", - "regresas", "regress", - "regreses", "regress", - "regresos", "regress", - "regresse", "regressive", - "regresso", "regression", - "regrests", "regress", - "regretts", "regrets", - "regsitry", "registry", - "regualrs", "regulars", - "regualte", "regulate", - "reguarly", "regularly", - "regulary", "regularly", - "regulatr", "regulator", - "regulats", "regulators", - "rehersal", "rehearsal", - "rehtoric", "rhetoric", - "reiceved", "recieved", - "reigment", "regiment", - "reigonal", "regional", - "rekenton", "renekton", - "relaible", "reliable", - "relaibly", "reliably", - "relaised", "realised", - "relaoded", "reloaded", - "relasped", "relapsed", - "relatabe", "relatable", - "relateds", "relates", - "relativy", "relativity", - "relavent", "relevant", - "relected", "reelected", - "relegato", "relegation", - "releived", "relieved", - "releiver", "reliever", - "relevent", "relevant", - "relfects", "reflects", - "relfexes", "reflexes", - "reliased", "realised", - "religous", "religious", - "relpased", "relapsed", - "remainds", "remains", - "remainig", "remaining", - "remannts", "remnants", - "remarkes", "remarks", - "remembed", "remembered", - "remembee", "remembered", - "rememebr", "remember", - "remenant", "remnant", - "reminent", "remnant", - "remmeber", "remember", - "remotley", "remotely", - "renderes", "renders", - "reneagde", "renegade", - "renetkon", "renekton", - "renewabe", "renewables", - "renketon", "renekton", - "renmants", "remnants", - "renoylds", "reynolds", - "renteris", "renters", - "renyolds", "reynolds", - "reowrked", "reworked", - "repaires", "repairs", - "repalces", "replaces", - "reparied", "repaired", - "repblics", "republics", - "repbulic", "republic", - "repeatae", "repeatable", - "repeates", "repeats", - "repetion", "repetition", - "repharse", "rephrase", - "repitles", "reptiles", - "replased", "relapsed", - "replayes", "replays", - "replicae", "replicated", - "replubic", "republic", - "reportes", "reporters", - "reposity", "repository", - "repostas", "reposts", - "repostes", "reposts", - "repostig", "reposting", - "repostus", "reposts", - "represet", "represents", - "represso", "repression", - "reprhase", "rephrase", - "repsects", "respects", - "repsonds", "responds", - "repsonse", "response", - "repsoted", "reposted", - "repubics", "republics", - "republis", "republics", - "repulics", "republics", - "repulsie", "repulsive", - "requiers", "requires", - "requieum", "requiem", - "requilme", "requiem", - "requried", "required", - "requries", "requires", - "rescuecd", "rescued", - "researce", "researcher", - "resembes", "resembles", - "reserach", "research", - "resevoir", "reservoir", - "resgined", "resigned", - "residude", "residue", - "residule", "residue", - "resinged", "resigned", - "resistas", "resists", - "resisten", "resistance", - "resistes", "resists", - "resloved", "resolved", - "resloves", "resolves", - "resmeble", "resemble", - "resotred", "restored", - "resourse", "resources", - "resovled", "resolved", - "resovles", "resolves", - "respecte", "respective", - "respesct", "respects", - "responce", "response", - "responed", "respond", - "respones", "response", - "responsd", "responds", - "respoted", "reposted", - "restanti", "restarting", - "restrait", "restraint", - "restrics", "restricts", - "resuable", "reusable", - "retailes", "retailers", - "retalier", "retailer", - "rethoric", "rhetoric", - "retirase", "retires", - "retireds", "retires", - "retireus", "retires", - "retireve", "retrieve", - "retreive", "retrieve", - "retrived", "retrieved", - "retunred", "returned", - "reuasble", "reusable", - "reveales", "reveals", - "reveiwed", "reviewed", - "reveiwer", "reviewer", - "revelaed", "revealed", - "revelant", "relevant", - "revelead", "revealed", - "reverals", "reversal", - "reviewes", "reviewers", - "revlover", "revolver", - "revloves", "revolves", - "revovler", "revolver", - "revovles", "revolves", - "rewatchd", "rewatched", - "rewitten", "rewritten", - "rewritte", "rewrite", - "rewtched", "wretched", - "reynlods", "reynolds", - "reyonlds", "reynolds", - "rhaposdy", "rhapsody", - "rhaspody", "rhapsody", - "rheotric", "rhetoric", - "righteos", "righteous", - "rigntone", "ringtone", - "ringotne", "ringtone", - "ritalian", "ritalin", - "rivalrly", "rivalry", - "roachers", "roaches", - "robberts", "robbers", - "robberys", "robbers", - "robocoop", "robocop", - "robocorp", "robocop", - "robocoup", "robocop", - "roelplay", "roleplay", - "roganism", "organism", - "rolepaly", "roleplay", - "romaanin", "romanian", - "romainan", "romanian", - "romanain", "romanian", - "romanica", "romania", - "rosettta", "rosetta", - "rostaing", "roasting", - "routeros", "routers", - "rutgerus", "rutgers", - "ryenolds", "reynolds", - "sacrifie", "sacrifice", - "saddends", "saddens", - "saddenes", "saddens", - "sadisitc", "sadistic", - "salaires", "salaries", - "sandales", "sandals", - "sandalls", "sandals", - "sandstom", "sandstorm", - "sanotrum", "santorum", - "santourm", "santorum", - "santroum", "santorum", - "santurom", "santorum", - "sapcebar", "spacebar", - "sapphrie", "sapphire", - "sarcasam", "sarcasm", - "sarcasim", "sarcasm", - "sarcastc", "sarcastic", - "sargeant", "sergeant", - "sasauges", "sausages", - "sasuages", "sausages", - "satelite", "satellite", - "satellie", "satellites", - "saterday", "saturday", - "satifies", "satisfies", - "satisfiy", "satisfy", - "satrical", "satirical", - "satruday", "saturday", - "saturdsy", "saturdays", - "sawstika", "swastika", - "scandlas", "scandals", - "scannign", "scanning", - "scarmble", "scramble", - "scepture", "scepter", - "schedual", "schedule", - "schoalrs", "scholars", - "scholary", "scholarly", - "schoodle", "schooled", - "scientic", "scientific", - "scientis", "scientist", - "scoprion", "scorpion", - "scorates", "socrates", - "scoripon", "scorpion", - "scorpoin", "scorpion", - "scostman", "scotsman", - "scratchs", "scratches", - "scriptue", "scriptures", - "scriptus", "scripts", - "scritped", "scripted", - "scroates", "socrates", - "scropion", "scorpion", - "scrpited", "scripted", - "scruitny", "scrutiny", - "scrunity", "scrutiny", - "sctosman", "scotsman", - "sculpter", "sculpture", - "scurtiny", "scrutiny", - "seahakws", "seahawks", - "seahwaks", "seahawks", - "seantors", "senators", - "sebastin", "sebastian", - "seceeded", "succeeded", - "secertly", "secretly", - "secrelty", "secretly", - "secretas", "secrets", - "secretos", "secrets", - "secruity", "security", - "secuirty", "security", - "sedereal", "sidereal", - "seldomly", "seldom", - "selectie", "selective", - "selfiers", "selfies", - "semestre", "semester", - "semseter", "semester", - "senarios", "scenarios", - "senerity", "serenity", - "seniores", "seniors", - "senisble", "sensible", - "sensibel", "sensible", - "sensores", "sensors", - "senstive", "sensitive", - "sentaors", "senators", - "sentiers", "sentries", - "sentinet", "sentient", - "sentinte", "sentient", - "sentires", "sentries", - "sentreis", "sentries", - "separato", "separation", - "separete", "seperate", - "sepearte", "seperate", - "seperate", "separate", - "seplling", "spelling", - "sepreate", "seperate", - "sepulcre", "sepulchre", - "serached", "searched", - "seraches", "searches", - "serentiy", "serenity", - "sergaent", "sergeant", - "settigns", "settings", - "seventen", "seventeen", - "severeal", "several", - "severeid", "severed", - "severide", "severed", - "severley", "severely", - "sexaully", "sexually", - "seziures", "seizures", - "sezuires", "seizures", - "shadoloo", "shadaloo", - "shangahi", "shanghai", - "shanghia", "shanghai", - "sharplay", "sharply", - "sharpley", "sharply", - "shawshak", "shawshank", - "shcolars", "scholars", - "shcooled", "schooled", - "sheilded", "shielded", - "shelterd", "sheltered", - "shelvers", "shelves", - "shelveys", "shelves", - "sherlcok", "sherlock", - "shetlers", "shelters", - "shfiting", "shifting", - "shifitng", "shifting", - "shifteer", "shifter", - "shileded", "shielded", - "shineing", "shining", - "shitstom", "shitstorm", - "shittoon", "shitton", - "shittown", "shitton", - "shleters", "shelters", - "shnaghai", "shanghai", - "shortend", "shortened", - "shotuout", "shoutout", - "shoudlnt", "shouldnt", - "shouldes", "shoulders", - "shoulndt", "shouldnt", - "shrapenl", "shrapnel", - "shrelock", "sherlock", - "shrinked", "shrunk", - "shrpanel", "shrapnel", - "shtiless", "shitless", - "shuoldnt", "shouldnt", - "sideboad", "sideboard", - "sidleine", "sideline", - "siezable", "sizeable", - "siezures", "seizures", - "signatue", "signatures", - "signfies", "signifies", - "signifiy", "signify", - "signigns", "signings", - "signular", "singular", - "silbings", "siblings", - "silicoln", "silicon", - "silicoon", "silicon", - "silimiar", "similiar", - "simialir", "similiar", - "simiilar", "similiar", - "similair", "similar", - "similari", "similiar", - "similart", "similarity", - "similary", "similarly", - "similiar", "similar", - "simliiar", "similiar", - "simluate", "simulate", - "simmilar", "similar", - "simpelst", "simplest", - "simplets", "simplest", - "simplicy", "simplicity", - "simplier", "simpler", - "simulato", "simulation", - "singlers", "singles", - "singluar", "singular", - "sinistre", "sinister", - "sinsiter", "sinister", - "sitckers", "stickers", - "sitrring", "stirring", - "sizebale", "sizeable", - "skateing", "skating", - "skecthes", "sketches", - "skelatel", "skeletal", - "skeletos", "skeletons", - "sketchey", "sketchy", - "sketpics", "skeptics", - "skillsto", "skillshots", - "skimrish", "skirmish", - "skpetics", "skeptics", - "skrimish", "skirmish", - "skteches", "sketches", - "skywalkr", "skywalker", - "slaptoon", "splatoon", - "slaverly", "slavery", - "slienced", "silenced", - "sliently", "silently", - "slighlty", "slightly", - "sligthly", "slightly", - "smartare", "smarter", - "snetries", "sentries", - "snippent", "snippet", - "snippert", "snippet", - "snowbals", "snowballs", - "snugglie", "snuggle", - "snydrome", "syndrome", - "snyopsis", "synopsis", - "soberity", "sobriety", - "sobreity", "sobriety", - "socailly", "socially", - "socalism", "socialism", - "socartes", "socrates", - "socialim", "socialism", - "socities", "societies", - "socttish", "scottish", - "soemthin", "somethin", - "soilders", "soldiers", - "solatary", "solitary", - "soldeirs", "soldiers", - "soliders", "soldiers", - "soluable", "soluble", - "solutide", "solitude", - "somalija", "somalia", - "somehtin", "somethin", - "someoens", "someones", - "somethis", "somethings", - "sometihn", "somethin", - "sometinh", "somethin", - "somoenes", "someones", - "somtimes", "sometimes", - "somwhere", "somewhere", - "soparnos", "sopranos", - "sophmore", "sophomore", - "sorcercy", "sorcery", - "sorcerey", "sorcery", - "sorceror", "sorcerer", - "sorcerry", "sorcery", - "sorpanos", "sopranos", - "southren", "southern", - "soverein", "sovereign", - "soverign", "sovereign", - "sovietes", "soviets", - "spagheti", "spaghetti", - "spainish", "spanish", - "spaltoon", "splatoon", - "spammade", "spammed", - "spammare", "spammer", - "spammear", "spammer", - "spammend", "spammed", - "spammeur", "spammer", - "spanisch", "spanish", - "sparklie", "sparkle", - "spawnign", "spawning", - "specemin", "specimen", - "speciaal", "special", - "specialt", "specialist", - "specialy", "specially", - "specialz", "specialize", - "specifed", "specified", - "specifiy", "specify", - "speciman", "specimen", - "specrtal", "spectral", - "speicals", "specials", - "spellign", "spelling", - "spendour", "splendour", - "sphereos", "spheres", - "spilnter", "splinter", - "spiltter", "splitter", - "spindrel", "spindle", - "spirites", "spirits", - "spiritis", "spirits", - "spiritus", "spirits", - "spirtied", "spirited", - "spleling", "spelling", - "splitner", "splinter", - "spoilerd", "spoiled", - "spoliers", "spoilers", - "sponsord", "sponsored", - "sporanos", "sopranos", - "spotifiy", "spotify", - "spotifty", "spotify", - "sppeches", "speeches", - "sprayade", "sprayed", - "spreaded", "spread", - "springst", "sprints", - "sprinkel", "sprinkle", - "sprintas", "sprints", - "spritual", "spiritual", - "sproutes", "sprouts", - "spwaning", "spawning", - "sqaudron", "squadron", - "sqaurely", "squarely", - "sqiurtle", "squirtle", - "squardon", "squadron", - "squareds", "squares", - "squarley", "squarely", - "squeakey", "squeaky", - "squeakly", "squeaky", - "squirlte", "squirtle", - "squirrle", "squirrel", - "squirtel", "squirtle", - "squishey", "squishy", - "squishly", "squishy", - "squritle", "squirtle", - "squrriel", "squirrel", - "squrtile", "squirtle", - "sriarcha", "sriracha", - "srriacha", "sriracha", - "sryacuse", "syracuse", - "staduims", "stadiums", - "staidums", "stadiums", - "staklers", "stalkers", - "stalekrs", "stalkers", - "stalkear", "stalker", - "staminia", "stamina", - "stampade", "stamped", - "stampeed", "stamped", - "stancels", "stances", - "stancers", "stances", - "standars", "standards", - "standbay", "standby", - "standbuy", "standby", - "stangant", "stagnant", - "staright", "straight", - "starined", "strained", - "starlted", "startled", - "startegy", "strategy", - "starteld", "startled", - "startsup", "startups", - "stateman", "statesman", - "staticts", "statist", - "stationd", "stationed", - "stationy", "stationary", - "statiskt", "statist", - "statistc", "statistic", - "statment", "statement", - "stattues", "statutes", - "statuets", "statutes", - "statuser", "stature", - "staurday", "saturday", - "steadliy", "steadily", - "stealhty", "stealthy", - "steathly", "stealthy", - "stelathy", "stealthy", - "sterilze", "sterile", - "steriods", "steroids", - "stichted", "stitched", - "sticthed", "stitched", - "sticthes", "stitches", - "stimulai", "stimuli", - "stimulas", "stimulants", - "stimulat", "stimulants", - "stimulli", "stimuli", - "stingent", "stringent", - "stirkers", "strikers", - "stlakers", "stalkers", - "stomache", "stomach", - "stormade", "stormed", - "stormend", "stormed", - "stradegy", "strategy", - "stragety", "strategy", - "straignt", "straighten", - "straigth", "straight", - "straings", "strains", - "strangel", "strangle", - "stranget", "strangest", - "stratgey", "strategy", - "stratled", "startled", - "streames", "streams", - "streamos", "streams", - "streamus", "streams", - "streamys", "streams", - "stregnth", "strength", - "stremear", "streamer", - "strenght", "strength", - "strengts", "strengths", - "strenous", "strenuous", - "strentgh", "strength", - "stretchs", "stretches", - "striaght", "straight", - "striclty", "strictly", - "striekrs", "strikers", - "strikely", "strikingly", - "stringet", "stringent", - "stubbron", "stubborn", - "stubmled", "stumbled", - "stucture", "structure", - "studioes", "studios", - "stuipder", "stupider", - "stumbeld", "stumbled", - "stupdily", "stupidly", - "stupidiy", "stupidity", - "stylisch", "stylish", - "styrofom", "styrofoam", - "suasages", "sausages", - "subltety", "subtlety", - "submarie", "submarines", - "subruban", "suburban", - "subscrie", "subscriber", - "subsidie", "subsidized", - "subsidiy", "subsidy", - "substace", "substance", - "substans", "substances", - "substite", "substitute", - "subtelty", "subtlety", - "subtetly", "subtlety", - "subtilte", "subtitle", - "subtitel", "subtitle", - "subtitls", "subtitles", - "subtltey", "subtlety", - "succeded", "succeeded", - "succedes", "succeeds", - "succeeed", "succeed", - "succesed", "succeeds", - "successs", "successes", - "succsess", "success", - "suceeded", "succeeded", - "sucesful", "successful", - "sucesion", "succession", - "sucesses", "successes", - "sucessor", "successor", - "sucessot", "successor", - "sucidial", "suicidal", - "suddnely", "suddenly", - "sufficit", "sufficient", - "suggesst", "suggests", - "suggeste", "suggestive", - "summenor", "summoner", - "summones", "summoners", - "sunfiber", "sunfire", - "sunscren", "sunscreen", - "superham", "superhuman", - "superheo", "superhero", - "superios", "superiors", - "supirsed", "suprised", - "suposing", "supposing", - "supporre", "supporters", - "suprised", "surprised", - "suprized", "surprised", - "suprsied", "suprised", - "supsects", "suspects", - "supsense", "suspense", - "surbuban", "suburban", - "surounds", "surrounds", - "surpases", "surpass", - "surpress", "suppress", - "surprize", "surprise", - "surrouns", "surrounds", - "surveill", "surveil", - "surveyer", "surveyor", - "surviver", "survivor", - "suspened", "suspend", - "suspenso", "suspension", - "swaering", "swearing", - "swansoon", "swanson", - "swasitka", "swastika", - "swaskita", "swastika", - "swatiska", "swastika", - "swatsika", "swastika", - "swedisch", "swedish", - "swiftley", "swiftly", - "swithced", "switched", - "swithces", "switches", - "swtiched", "switched", - "swtiches", "switches", - "syarcuse", "syracuse", - "sydnrome", "syndrome", - "sylablle", "syllable", - "syllabel", "syllable", - "symapthy", "sympathy", - "symboles", "symbols", - "symhpony", "symphony", - "symmerty", "symmetry", - "symmtery", "symmetry", - "symoblic", "symbolic", - "symphaty", "sympathy", - "symptoom", "symptom", - "symtpoms", "symptoms", - "synomyns", "synonyms", - "synonmys", "synonyms", - "synonomy", "synonym", - "synoynms", "synonyms", - "synphony", "symphony", - "synposis", "synopsis", - "sypmathy", "sympathy", - "sypmtoms", "symptoms", - "sypnosis", "synopsis", - "syraucse", "syracuse", - "syrcause", "syracuse", - "syringae", "syringe", - "syringue", "syringe", - "sysamdin", "sysadmin", - "sysdamin", "sysadmin", - "tacticas", "tactics", - "tacticts", "tactics", - "tacticus", "tactics", - "tagliate", "tailgate", - "tahnkyou", "thankyou", - "tailsman", "talisman", - "taiwanee", "taiwanese", - "taligate", "tailgate", - "taliored", "tailored", - "tallents", "tallest", - "talsiman", "talisman", - "tanturms", "tantrums", - "tapitude", "aptitude", - "tasliman", "talisman", - "tattooes", "tattoos", - "tattooos", "tattoos", - "taxanomy", "taxonomy", - "teamfigt", "teamfight", - "teamspek", "teamspeak", - "teancity", "tenacity", - "teapsoon", "teaspoon", - "techniqe", "technique", - "teenages", "teenagers", - "telegrah", "telegraph", - "telphony", "telephony", - "tempalrs", "templars", - "tempalte", "template", - "templats", "templates", - "templeos", "temples", - "templers", "temples", - "temporay", "temporary", - "temprary", "temporary", - "tenacles", "tentacles", - "tenactiy", "tenacity", - "tencaity", "tenacity", - "tendancy", "tendency", - "tendence", "tendencies", - "tentacel", "tentacle", - "tentacls", "tentacles", - "tentalce", "tentacle", - "tequilia", "tequila", - "terriory", "territory", - "territoy", "territory", - "terroist", "terrorist", - "tesitcle", "testicle", - "testicel", "testicle", - "testifiy", "testify", - "teusdays", "tuesdays", - "texutres", "textures", - "thaliand", "thailand", - "theather", "theater", - "theathre", "theater", - "theature", "theater", - "theisitc", "theistic", - "themslef", "themself", - "theorits", "theorist", - "theraphy", "therapy", - "thereian", "therein", - "theroies", "theories", - "theroist", "theorist", - "thesitic", "theistic", - "thialand", "thailand", - "thiestic", "theistic", - "thikning", "thinking", - "thirites", "thirties", - "thirstay", "thirsty", - "thnakyou", "thankyou", - "thoeries", "theories", - "thoerist", "theorist", - "thomspon", "thompson", - "thopmson", "thompson", - "thougths", "thoughts", - "thourogh", "thorough", - "threates", "threatens", - "threefor", "therefor", - "thriteen", "thirteen", - "thrities", "thirties", - "throaths", "throats", - "throners", "thrones", - "throough", "thorough", - "throught", "thought", - "thrusday", "thursday", - "thumbnal", "thumbnails", - "thurdsay", "thursday", - "thursdsy", "thursdays", - "tightare", "tighter", - "timestap", "timestamp", - "tirangle", "triangle", - "tirbunal", "tribunal", - "titainum", "titanium", - "titanuim", "titanium", - "tocuhpad", "touchpad", - "togehter", "together", - "togheter", "together", - "toiletts", "toilets", - "tolerabe", "tolerable", - "tommorow", "tomorrow", - "tonguers", "tongues", - "toriodal", "toroidal", - "toritlla", "tortilla", - "tornadoe", "tornado", - "torotise", "tortoise", - "torpedeo", "torpedo", - "torphies", "trophies", - "tortiose", "tortoise", - "toruisty", "touristy", - "toruneys", "tourneys", - "touchapd", "touchpad", - "tounreys", "tourneys", - "tourisim", "tourism", - "touritsy", "touristy", - "tournyes", "tourneys", - "toursits", "tourists", - "toursity", "touristy", - "toxiticy", "toxicity", - "trabajao", "trabajo", - "trabajdo", "trabajo", - "trackres", "trackers", - "trageted", "targeted", - "traingle", "triangle", - "traitour", "traitor", - "trakcers", "trackers", - "traliers", "trailers", - "tranform", "transform", - "transeat", "translates", - "transfom", "transform", - "transfos", "transforms", - "transiet", "transient", - "transito", "transition", - "transpot", "transport", - "trasnfer", "transfer", - "tratiors", "traitors", - "traveles", "travels", - "traveres", "traverse", - "treasurs", "treasures", - "treatmet", "treatments", - "treatsie", "treaties", - "treausre", "treasure", - "tredning", "trending", - "tremelos", "tremolos", - "tresuary", "treasury", - "trialers", "trailers", - "trianers", "trainers", - "triangel", "triangle", - "triangls", "triangles", - "trianing", "training", - "trianlge", "triangle", - "triators", "traitors", - "tribuanl", "tribunal", - "trickyer", "trickery", - "triggern", "triggering", - "trilogoy", "trilogy", - "trinagle", "triangle", - "trinekts", "trinkets", - "tringale", "triangle", - "trinitiy", "trinity", - "triology", "trilogy", - "triumpth", "triumph", - "trohpies", "trophies", - "trollade", "trolled", - "tropcial", "tropical", - "trotilla", "tortilla", - "trpoical", "tropical", - "trubinal", "tribunal", - "trubines", "turbines", - "tsunamai", "tsunami", - "tuesdsay", "tuesdays", - "tunnells", "tunnels", - "turkisch", "turkish", - "turntabe", "turntable", - "turretts", "turrets", - "tusedays", "tuesdays", - "tutorual", "tutorial", - "twilgiht", "twilight", - "tylenool", "tylenol", - "typicaly", "typically", - "tyranies", "tyrannies", - "tyrannia", "tyrannical", - "ublisher", "publisher", - "udnercut", "undercut", - "udnerdog", "underdog", - "ugpraded", "upgraded", - "ugprades", "upgrades", - "ukrainie", "ukraine", - "ukrainin", "ukrainian", - "ukranian", "ukrainian", - "ulitmate", "ultimate", - "ultamite", "ultimate", - "ultiamte", "ultimate", - "ultimely", "ultimately", - "ultrason", "ultrasound", - "umberlla", "umbrella", - "unabnned", "unbanned", - "unbanend", "unbanned", - "uncanney", "uncanny", - "uncannny", "uncanny", - "underbog", "undergo", - "underglo", "undergo", - "undersog", "undergo", - "undertoe", "undertones", - "underwar", "underwater", - "unfailry", "unfairly", - "unfarily", "unfairly", - "ungodley", "ungodly", - "unhapppy", "unhappy", - "unhealty", "unhealthy", - "unicrons", "unicorns", - "unifroms", "uniforms", - "uniquley", "uniquely", - "univeral", "universal", - "unlikley", "unlikely", - "unlockes", "unlocks", - "unluckly", "unlucky", - "unpoened", "unopened", - "unqiuely", "uniquely", - "unrakned", "unranked", - "unrnaked", "unranked", - "unrpoven", "unproven", - "unsuable", "unusable", - "untraind", "untrained", - "unusualy", "unusually", - "unvierse", "universe", - "unworhty", "unworthy", - "upgarded", "upgraded", - "upgardes", "upgrades", - "uploades", "uploads", - "upstaris", "upstairs", - "upstiars", "upstairs", - "urethrea", "urethra", - "uruguary", "uruguay", - "ususally", "usually", - "utilitiy", "utility", - "utlimate", "ultimate", - "vaccinae", "vaccinated", - "vaccinet", "vaccinated", - "vacinity", "vicinity", - "vaguelly", "vaguely", - "vaiation", "aviation", - "vaieties", "varieties", - "vailidty", "validity", - "vairable", "variable", - "vaklyrie", "valkyrie", - "valenica", "valencia", - "valentie", "valentines", - "valentis", "valentines", - "validade", "validated", - "valkirye", "valkyrie", - "valkiyre", "valkyrie", - "valkriye", "valkyrie", - "valkryie", "valkyrie", - "valkyire", "valkyrie", - "valnecia", "valencia", - "valubale", "valuable", - "valykrie", "valkyrie", - "vamipres", "vampires", - "vampiers", "vampires", - "vampries", "vampires", - "vangurad", "vanguard", - "vanillia", "vanilla", - "vanillla", "vanilla", - "vanugard", "vanguard", - "varaible", "variable", - "varaints", "variants", - "variabel", "variable", - "varibale", "variable", - "varities", "varieties", - "vassales", "vassals", - "vassalls", "vassals", - "vassalos", "vassals", - "vaticaan", "vatican", - "vaticina", "vatican", - "vaulable", "valuable", - "vaylkrie", "valkyrie", - "vechiles", "vehicles", - "vectores", "vectors", - "vegansim", "veganism", - "vegtable", "vegetable", - "vehciles", "vehicles", - "vehicels", "vehicles", - "vehicule", "vehicle", - "veichles", "vehicles", - "venelope", "envelope", - "venemous", "venomous", - "vengance", "vengeance", - "vengence", "vengeance", - "verablly", "verbally", - "verbaitm", "verbatim", - "verisons", "versions", - "versatel", "versatile", - "vertabim", "verbatim", - "vertigro", "vertigo", - "vesseles", "vessels", - "vessells", "vessels", - "viabiliy", "viability", - "viatmins", "vitamins", - "vibratie", "vibrate", - "vibratin", "vibration", - "vicintiy", "vicinity", - "vicseral", "visceral", - "victimas", "victims", - "victimes", "victims", - "victorin", "victorian", - "victoris", "victories", - "vieweres", "viewers", - "viewpoit", "viewpoints", - "vigilane", "vigilante", - "vigliant", "vigilant", - "vikingos", "vikings", - "viligant", "vigilant", - "villegas", "villages", - "vindicte", "vindictive", - "vinicity", "vicinity", - "violatin", "violation", - "violenty", "violently", - "violetas", "violates", - "virament", "vraiment", - "virbator", "vibrator", - "virginas", "virgins", - "virgines", "virgins", - "virgings", "virgins", - "virginis", "virgins", - "virginus", "virgins", - "virtualy", "virtually", - "virtuels", "virtues", - "virtuose", "virtues", - "viscreal", "visceral", - "visercal", "visceral", - "visibily", "visibility", - "visibley", "visibly", - "visiblly", "visibly", - "vitailty", "vitality", - "vitimans", "vitamins", - "vitmains", "vitamins", - "vitories", "victories", - "voicemal", "voicemail", - "voilates", "violates", - "volatily", "volatility", - "volcando", "volcano", - "volcanoe", "volcano", - "volcaron", "volcano", - "vriament", "vraiment", - "wahtever", "whatever", - "wallpapr", "wallpapers", - "warantee", "warranty", - "warcarft", "warcraft", - "warrante", "warranties", - "warriros", "warriors", - "watchemn", "watchmen", - "watchign", "watching", - "wathcing", "watching", - "wathcmen", "watchmen", - "wathever", "whatever", - "watkings", "watkins", - "wealthly", "wealthy", - "webistes", "websites", - "websties", "websites", - "wednesdy", "wednesdays", - "weigthed", "weighted", - "weridest", "weirdest", - "werstler", "wrestler", - "wesbites", "websites", - "westbrok", "westbrook", - "westerse", "westerners", - "wherease", "whereas", - "whipsers", "whispers", - "whislist", "wishlist", - "whisltes", "whistles", - "whisperd", "whispered", - "whistels", "whistles", - "whitsles", "whistles", - "whsipers", "whispers", - "widgetas", "widgets", - "wieghted", "weighted", - "willaims", "williams", - "willfuly", "willfully", - "willimas", "williams", - "windsoar", "windsor", - "wininpeg", "winnipeg", - "winnigns", "winnings", - "winnpieg", "winnipeg", - "wiredest", "weirdest", - "wishlsit", "wishlist", - "wishpers", "whispers", - "withdral", "withdrawal", - "witnesss", "witnesses", - "wonderes", "wonders", - "wonderus", "wonders", - "workfore", "workforce", - "wouldnot", "wouldnt", - "wranlger", "wrangler", - "wreckign", "wrecking", - "wrecthed", "wretched", - "wrekcing", "wrecking", - "wreslter", "wrestler", - "wresters", "wrestlers", - "writting", "writing", - "wrnagler", "wrangler", - "wrteched", "wretched", - "yeilding", "yielding", - "yoesmite", "yosemite", - "yorksher", "yorkshire", - "yorkshie", "yorkshire", - "yosemeti", "yosemite", - "yosimete", "yosemite", - "zealotes", "zealots", - "zealoths", "zealots", - "zealotus", "zealots", - "zealouts", "zealous", - "zepplein", "zeppelin", - "zepplien", "zeppelin", - "zimbabew", "zimbabwe", - "zimbawbe", "zimbabwe", - "zinoists", "zionists", - "zionisim", "zionism", - "zionistm", "zionism", - "zionsits", "zionists", - "zoinists", "zionists", - "abiltiy", "ability", - "abodmen", "abdomen", - "abondon", "abandon", - "aboslve", "absolve", - "abosrbs", "absorbs", - "abriter", "arbiter", - "abrupty", "abruptly", - "absense", "absence", - "absolue", "absolute", - "absovle", "absolve", - "absrobs", "absorbs", - "absuers", "abusers", - "absurdy", "absurdly", - "absymal", "abysmal", - "abymsal", "abysmal", - "acadamy", "academy", - "acadmic", "academic", - "accesss", "access", - "accpets", "accepts", - "accross", "across", - "accuray", "accuracy", - "acheive", "achieve", - "achived", "achieved", - "acident", "accident", - "ackward", "awkward", - "acrlyic", "acrylic", - "actauly", "actualy", - "activit", "activist", - "activly", "actively", - "actualy", "actually", - "actulay", "actualy", - "acuracy", "accuracy", - "acusing", "causing", - "acustom", "accustom", - "acutaly", "actualy", - "acyrlic", "acrylic", - "adaptes", "adapters", - "adatper", "adapter", - "adbomen", "abdomen", - "addcits", "addicts", - "adderss", "address", - "addtion", "addition", - "adequet", "adequate", - "adequit", "adequate", - "adivser", "adviser", - "adivsor", "advisor", - "admited", "admitted", - "admrial", "admiral", - "adpater", "adapter", - "adquire", "acquire", - "adultey", "adultery", - "adverst", "adverts", - "adviced", "advised", - "advocay", "advocacy", - "advsior", "advisor", - "aeriels", "aerials", - "affaris", "affairs", - "affiars", "affairs", - "afircan", "african", - "africas", "africans", - "afwully", "awfully", - "againts", "against", - "agaisnt", "against", - "aganist", "against", - "aggreed", "agreed", - "agianst", "against", - "agreing", "agreeing", - "agruing", "arguing", - "ahtiest", "athiest", - "aicraft", "aircraft", - "ailmony", "alimony", - "airbore", "airborne", - "aircaft", "aircraft", - "airlfow", "airflow", - "airosft", "airsoft", - "airpost", "airports", - "airsfot", "airsoft", - "airzona", "arizona", - "alchmey", "alchemy", - "alchool", "alcohol", - "alcohal", "alcohol", - "aledged", "alleged", - "aledges", "alleges", - "alegbra", "algebra", - "algerba", "algebra", - "alienet", "alienate", - "alledge", "allege", - "allegry", "allergy", - "alltime", "all-time", - "almighy", "almighty", - "alochol", "alcohol", - "alotted", "allotted", - "alowing", "allowing", - "alphabt", "alphabet", - "alreayd", "already", - "alrighy", "alrighty", - "altanta", "atlanta", - "alteast", "atleast", - "altough", "although", - "alusion", "allusion", - "amateus", "amateurs", - "amatuer", "amateur", - "amature", "armature", - "amensia", "amnesia", - "amensty", "amnesty", - "amercia", "america", - "americs", "americas", - "ammount", "amount", - "ammused", "amused", - "amneisa", "amnesia", - "amnsety", "amnesty", - "amognst", "amongst", - "amongts", "amongst", - "amonsgt", "amongst", - "ampilfy", "amplify", - "amrpits", "armpits", - "analoge", "analogue", - "analsyt", "analyst", - "analyes", "analyse", - "analyts", "analyst", - "analzye", "analyze", - "anaylse", "analyse", - "anaylst", "analyst", - "anaylze", "analyze", - "anceint", "ancient", - "andorid", "android", - "andriod", "android", - "androis", "androids", - "angirly", "angrily", - "angluar", "angular", - "angualr", "angular", - "anicent", "ancient", - "anitque", "antique", - "anixety", "anxiety", - "anmesia", "amnesia", - "anmesty", "amnesty", - "annoint", "anoint", - "annualy", "annually", - "annuled", "annulled", - "anohter", "another", - "anomoly", "anomaly", - "answerd", "answered", - "anuglar", "angular", - "anulled", "annulled", - "anwsers", "answers", - "anwyays", "anyways", - "anxeity", "anxiety", - "anyoens", "anyones", - "anyonse", "anyones", - "anywyas", "anyways", - "aparent", "apparent", - "appeard", "appeared", - "appluad", "applaud", - "aproval", "approval", - "apsects", "aspects", - "apshalt", "asphalt", - "apsirin", "aspirin", - "aqcuire", "acquire", - "aquarim", "aquarium", - "aquired", "acquired", - "aranged", "arranged", - "arbitre", "arbiter", - "arcahic", "archaic", - "archiac", "archaic", - "arcylic", "acrylic", - "aresnal", "arsenal", - "aretmis", "artemis", - "argubly", "arguably", - "aribter", "arbiter", - "ariflow", "airflow", - "arisoft", "airsoft", - "aritsts", "artists", - "armchar", "armchair", - "arogant", "arrogant", - "arogent", "arrogant", - "arresst", "arrests", - "arround", "around", - "arsneal", "arsenal", - "artcile", "article", - "artical", "article", - "articel", "article", - "artistc", "artistic", - "artmeis", "artemis", - "artsits", "artists", - "aruging", "arguing", - "aseuxal", "asexual", - "asexaul", "asexual", - "ashpalt", "asphalt", - "asiprin", "aspirin", - "asissts", "assists", - "asnwers", "answers", - "asorbed", "absorbed", - "aspahlt", "asphalt", - "asphlat", "asphalt", - "aspriin", "aspirin", - "assagne", "assange", - "assasin", "assassin", - "assembe", "assemble", - "assemby", "assembly", - "assisst", "assists", - "assnage", "assange", - "asssits", "assists", - "assualt", "assault", - "asterik", "asterisk", - "asutria", "austria", - "atcualy", "actualy", - "atelast", "atleast", - "athesim", "atheism", - "athiesm", "atheism", - "athiest", "atheist", - "athiets", "athiest", - "athlets", "athletes", - "atlantc", "atlantic", - "atleats", "atleast", - "atlesat", "atleast", - "atorney", "attorney", - "atremis", "artemis", - "attemps", "attempts", - "attemts", "attempts", - "attened", "attended", - "attracs", "attracts", - "audbile", "audible", - "audibel", "audible", - "austira", "austria", - "austrai", "austria", - "autistc", "autistic", - "avation", "aviation", - "avtaars", "avatars", - "awakend", "awakened", - "bablyon", "babylon", - "backdor", "backdoor", - "backsta", "backseat", - "baclony", "balcony", - "badnits", "bandits", - "baiscly", "basicly", - "bakcers", "backers", - "balanse", "balances", - "balcked", "blacked", - "banhsee", "banshee", - "bankgok", "bangkok", - "baoynet", "bayonet", - "baptims", "baptism", - "baptsim", "baptism", - "baragin", "bargain", - "bargani", "bargain", - "bargian", "bargain", - "bariner", "brainer", - "barlkey", "barkley", - "barracs", "barracks", - "barrles", "barrels", - "barsita", "barista", - "barvery", "bravery", - "bascily", "basicly", - "basicly", "basically", - "basilcy", "basicly", - "basiton", "bastion", - "basnhee", "banshee", - "bastane", "bastante", - "bastars", "bastards", - "bastino", "bastion", - "bathrom", "bathroom", - "batitsa", "batista", - "batsita", "batista", - "bayblon", "babylon", - "baynoet", "bayonet", - "bayoent", "bayonet", - "bceuase", "becuase", - "beacuse", "because", - "bealtes", "beatles", - "beaslty", "beastly", - "beatels", "beatles", - "beaucop", "beaucoup", - "becamae", "became", - "becames", "becomes", - "becasue", "because", - "becouse", "because", - "becuaes", "becuase", - "becuase", "because", - "becusae", "becuase", - "befried", "befriend", - "beggins", "begins", - "beglian", "belgian", - "beglium", "belgium", - "begnals", "bengals", - "bejiing", "beijing", - "beleifs", "beliefs", - "beleive", "believe", - "belgain", "belgian", - "belguim", "belgium", - "believr", "believer", - "believs", "believes", - "belifes", "beliefs", - "beligan", "belgian", - "beligum", "belgium", - "belived", "believed", - "belives", "believes", - "benagls", "bengals", - "benedit", "benedict", - "benghai", "benghazi", - "benglas", "bengals", - "benifit", "benefit", - "beoynce", "beyonce", - "beraded", "bearded", - "bersekr", "berserk", - "beseige", "besiege", - "betales", "beatles", - "bethesa", "bethesda", - "betrayd", "betrayed", - "beucase", "becuase", - "bewteen", "between", - "bicthes", "bitches", - "bidrman", "birdman", - "biejing", "beijing", - "bifgoot", "bigfoot", - "bigorty", "bigotry", - "bigtoed", "bigoted", - "bigtory", "bigotry", - "biogted", "bigoted", - "biogtry", "bigotry", - "bioplar", "bipolar", - "biploar", "bipolar", - "birdamn", "birdman", - "birdges", "bridges", - "birgade", "brigade", - "bitcion", "bitcoin", - "bithced", "bitched", - "bithces", "bitches", - "bitocin", "bitcoin", - "bizzare", "bizarre", - "blacony", "balcony", - "blaimed", "blamed", - "blankes", "blankets", - "blegian", "belgian", - "blegium", "belgium", - "blizzad", "blizzard", - "blockes", "blockers", - "bloster", "bolster", - "blulets", "bullets", - "bobmers", "bombers", - "bollocs", "bollocks", - "bondary", "boundary", - "bonnano", "bonanno", - "bonsues", "bonuses", - "boraden", "broaden", - "borader", "broader", - "boradly", "broadly", - "bordeom", "boredom", - "boslter", "bolster", - "boudler", "boulder", - "boundry", "boundary", - "bounses", "bonuses", - "boutiqe", "boutique", - "bouyant", "buoyant", - "braevry", "bravery", - "braista", "barista", - "brakley", "barkley", - "branier", "brainer", - "braoden", "broaden", - "braoder", "broader", - "braodly", "broadly", - "brednan", "brendan", - "breifly", "briefly", - "breserk", "berserk", - "brethen", "brethren", - "brewrey", "brewery", - "briagde", "brigade", - "brianer", "brainer", - "bridman", "birdman", - "brielfy", "briefly", - "brigdes", "bridges", - "brightn", "brighten", - "brisben", "brisbane", - "britian", "britain", - "britsol", "bristol", - "briused", "bruised", - "briuser", "bruiser", - "briuses", "bruises", - "brocoli", "broccoli", - "bronocs", "broncos", - "browine", "brownie", - "brownei", "brownie", - "brownis", "brownies", - "bruglar", "burglar", - "brunete", "brunette", - "bruning", "burning", - "brusied", "bruised", - "brusies", "bruises", - "brusses", "brussels", - "brutaly", "brutally", - "btiched", "bitched", - "btiches", "bitches", - "bubbels", "bubbles", - "buddhim", "buddhism", - "buddhit", "buddhist", - "buddist", "buddhist", - "budgest", "budgets", - "bugdets", "budgets", - "buildes", "builders", - "bulgara", "bulgaria", - "bullest", "bullets", - "buoancy", "buoyancy", - "burguny", "burgundy", - "buriser", "bruiser", - "burlgar", "burglar", - "burnign", "burning", - "burried", "buried", - "burrtio", "burrito", - "busines", "business", - "busness", "business", - "butthoe", "butthole", - "buttrey", "buttery", - "cababge", "cabbage", - "cabines", "cabinets", - "cabniet", "cabinet", - "caclium", "calcium", - "cacuses", "caucuses", - "caffeen", "caffeine", - "cahched", "cached", - "cahotic", "chaotic", - "cahsier", "cashier", - "cailbre", "calibre", - "calaber", "caliber", - "calagry", "calgary", - "calback", "callback", - "calbire", "calibre", - "calcuim", "calcium", - "calculs", "calculus", - "calicum", "calcium", - "calrify", "clarify", - "calrity", "clarity", - "caluses", "clauses", - "camboda", "cambodia", - "campain", "campaign", - "campuss", "campuses", - "cancles", "cancels", - "cancres", "cancers", - "cancuks", "canucks", - "canides", "candies", - "cannnot", "cannot", - "canrage", "carnage", - "capible", "capable", - "capitas", "capitals", - "capsuls", "capsules", - "captais", "captains", - "captial", "capital", - "captiol", "capitol", - "captued", "captured", - "capturd", "captured", - "capusle", "capsule", - "carange", "carnage", - "carbien", "carbine", - "cardaic", "cardiac", - "cardina", "cardigan", - "careing", "caring", - "caridac", "cardiac", - "carmtan", "cartman", - "carnege", "carnage", - "carnige", "carnage", - "carolan", "carolina", - "carreer", "career", - "carrers", "careers", - "cartles", "cartels", - "caryons", "crayons", - "casette", "cassette", - "casheir", "cashier", - "cashies", "cashiers", - "cashire", "cashier", - "casltes", "castles", - "caspule", "capsule", - "cassete", "cassette", - "castels", "castles", - "casuing", "causing", - "cathlic", "catholic", - "cauncks", "canucks", - "cavarly", "cavalry", - "cavlary", "cavalry", - "celcius", "celsius", - "celisus", "celsius", - "celitcs", "celtics", - "celsuis", "celsius", - "centruy", "century", - "centuty", "century", - "ceratin", "certain", - "cermaic", "ceramic", - "certian", "certain", - "cervial", "cervical", - "cesspol", "cesspool", - "cetlics", "celtics", - "chambre", "chamber", - "charcol", "charcoal", - "charisa", "charisma", - "chasiss", "chassis", - "chatoic", "chaotic", - "cheeots", "cheetos", - "cheesse", "cheeses", - "chekcer", "checker", - "chelsae", "chelsea", - "cheslea", "chelsea", - "chiense", "chinese", - "childen", "children", - "chimeny", "chimney", - "chinees", "chinese", - "chinmey", "chimney", - "chipest", "chipset", - "chispet", "chipset", - "chivaly", "chivalry", - "chlesea", "chelsea", - "choatic", "chaotic", - "chocies", "choices", - "choosen", "chosen", - "chtulhu", "cthulhu", - "churchs", "churches", - "cilanto", "cilantro", - "cilents", "clients", - "circels", "circles", - "circuis", "circuits", - "cirlces", "circles", - "clacium", "calcium", - "claerer", "clearer", - "claerly", "clearly", - "clagary", "calgary", - "claibre", "calibre", - "claimes", "claims", - "clairfy", "clarify", - "clairty", "clarity", - "clanand", "clannad", - "clarfiy", "clarify", - "classis", "classics", - "clasues", "clauses", - "claymer", "claymore", - "claymoe", "claymore", - "cleanes", "cleanse", - "cleasne", "cleanse", - "cleints", "clients", - "clenase", "cleanse", - "clesius", "celsius", - "cletics", "celtics", - "clevery", "cleverly", - "climats", "climates", - "climbes", "climbers", - "clincis", "clinics", - "clitors", "clitoris", - "cloesly", "closely", - "closley", "closely", - "cluases", "clauses", - "cluprit", "culprit", - "coalese", "coalesce", - "coctail", "cocktail", - "cohesie", "cohesive", - "colgone", "cologne", - "collape", "collapse", - "collest", "collects", - "collony", "colony", - "collumn", "column", - "cologen", "cologne", - "colomba", "colombia", - "colonge", "cologne", - "colorao", "colorado", - "colourd", "coloured", - "columsn", "columns", - "comando", "commando", - "comapny", "company", - "comapre", "compare", - "comarde", "comrade", - "comback", "comeback", - "combins", "combines", - "comdeic", "comedic", - "comited", "committed", - "commano", "commando", - "commans", "commands", - "commere", "commerce", - "comming", "coming", - "commitd", "commited", - "compase", "compares", - "compede", "competed", - "compilr", "compiler", - "compnay", "company", - "compots", "compost", - "comrads", "comrades", - "comtpon", "compton", - "conceed", "concede", - "conceps", "concepts", - "conclue", "conclude", - "concret", "concert", - "condenm", "condemn", - "condiut", "conduit", - "condmen", "condemn", - "confids", "confides", - "confins", "confines", - "confise", "confines", - "conflit", "conflict", - "conived", "connived", - "connecs", "connects", - "conqeur", "conquer", - "conqure", "conquer", - "consept", "concept", - "consern", "concern", - "consums", "consumes", - "contacs", "contacts", - "contais", "contains", - "contast", "contacts", - "contemt", "contempt", - "contens", "contents", - "contess", "contests", - "contian", "contain", - "contine", "continue", - "convers", "converts", - "conveyd", "conveyed", - "convine", "convince", - "coprses", "corpses", - "coputer", "computer", - "corasir", "corsair", - "coratia", "croatia", - "coridal", "cordial", - "corsari", "corsair", - "corsiar", "corsair", - "corspes", "corpses", - "corwbar", "crowbar", - "costums", "costumes", - "coudlnt", "couldnt", - "coulmns", "columns", - "coulndt", "couldnt", - "counsle", "counsel", - "countes", "counters", - "courtey", "courtesy", - "covenat", "covenant", - "coytoes", "coyotes", - "crabine", "carbine", - "cralwed", "crawled", - "craotia", "croatia", - "craweld", "crawled", - "creamic", "ceramic", - "createn", "creatine", - "creater", "creature", - "creatie", "creatine", - "creatue", "creature", - "creepes", "creepers", - "creepig", "creeping", - "creulty", "cruelty", - "cricles", "circles", - "critera", "criteria", - "cropses", "corpses", - "crosair", "corsair", - "crpytic", "cryptic", - "crsytal", "crystal", - "crtical", "critical", - "crucibe", "crucible", - "cruetly", "cruelty", - "cruical", "crucial", - "crulety", "cruelty", - "crusdae", "crusade", - "crusier", "cruiser", - "crusies", "cruises", - "crusive", "cursive", - "crutchs", "crutches", - "crypitc", "cryptic", - "crystas", "crystals", - "crystsl", "crystals", - "crytpic", "cryptic", - "crytsal", "crystal", - "cthluhu", "cthulhu", - "cthuhlu", "cthulhu", - "cthuluh", "cthulhu", - "ctuhlhu", "cthulhu", - "cuasing", "causing", - "cubcile", "cubicle", - "cubilce", "cubicle", - "cuddels", "cuddles", - "culrpit", "culprit", - "culturs", "cultures", - "cupboad", "cupboard", - "cuplrit", "culprit", - "curatin", "curtain", - "curcial", "crucial", - "curcuit", "circuit", - "curelty", "cruelty", - "curiser", "cruiser", - "curisve", "cursive", - "currate", "curate", - "currens", "currents", - "curreny", "currency", - "currest", "currents", - "cursade", "crusade", - "curtian", "curtain", - "cyandie", "cyanide", - "cyclits", "cyclist", - "cycloen", "cyclone", - "cycolps", "cyclops", - "cylcist", "cyclist", - "cylcone", "cyclone", - "cylcops", "cyclops", - "cynaide", "cyanide", - "cyrptic", "cryptic", - "cyrstal", "crystal", - "dagners", "dangers", - "daimond", "diamond", - "damenor", "demeanor", - "dammage", "damage", - "darcula", "dracula", - "dargons", "dragons", - "darkets", "darkest", - "datbase", "database", - "daulity", "duality", - "dawrves", "dwarves", - "ddogers", "dodgers", - "ddoging", "dodging", - "deadlit", "deadlift", - "deadpol", "deadpool", - "deafult", "default", - "deahtly", "deathly", - "deatils", "details", - "deatlhy", "deathly", - "decalre", "declare", - "decison", "decision", - "declars", "declares", - "declase", "declares", - "decress", "decrees", - "decribe", "describe", - "decsend", "descend", - "dectect", "detect", - "defaint", "defiant", - "defauls", "defaults", - "defelct", "deflect", - "defensd", "defends", - "deffine", "define", - "definat", "defiant", - "definet", "definite", - "definie", "definite", - "definig", "defining", - "definit", "definite", - "defualt", "default", - "degarde", "degrade", - "degrase", "degrasse", - "degrate", "degrade", - "deiners", "deniers", - "deisgns", "designs", - "deivant", "deviant", - "dekstop", "desktop", - "delcare", "declare", - "delfect", "deflect", - "demenor", "demeanor", - "dementa", "dementia", - "demsond", "desmond", - "deneirs", "deniers", - "denisty", "density", - "densley", "densely", - "depcits", "depicts", - "dependd", "depended", - "depitcs", "depicts", - "deployd", "deployed", - "depsise", "despise", - "descrie", "describe", - "descuss", "discuss", - "desgins", "designs", - "desings", "designs", - "desitny", "destiny", - "desnely", "densely", - "desnity", "density", - "desomnd", "desmond", - "despict", "depict", - "despide", "despised", - "despies", "despise", - "destkop", "desktop", - "destory", "destroy", - "destros", "destroys", - "detaild", "detailed", - "detials", "details", - "detorit", "detroit", - "detriot", "detroit", - "deuling", "dueling", - "devaint", "deviant", - "devaite", "deviate", - "devided", "divided", - "devlove", "devolve", - "devotin", "devotion", - "devovle", "devolve", - "diabets", "diabetes", - "dialecs", "dialects", - "dialoge", "dialogue", - "diamons", "diamonds", - "diasble", "disable", - "dicksih", "dickish", - "dicover", "discover", - "dictats", "dictates", - "dieties", "deities", - "dilpoma", "diploma", - "dimaond", "diamond", - "dingity", "dignity", - "dinosar", "dinosaur", - "diosese", "diocese", - "dipolma", "diploma", - "dirbble", "dribble", - "directy", "directly", - "diretcx", "directx", - "dirived", "derived", - "dirvers", "drivers", - "disbale", "disable", - "disguss", "disgusts", - "disliks", "dislikes", - "disover", "discover", - "dispair", "despair", - "dispath", "dispatch", - "dispite", "despite", - "dispuse", "disputes", - "disputs", "disputes", - "dissole", "dissolve", - "distase", "distaste", - "distint", "distinct", - "divison", "division", - "docuhes", "douches", - "docuhey", "douchey", - "dogders", "dodgers", - "dogding", "dodging", - "dolhpin", "dolphin", - "dolphis", "dolphins", - "dominae", "dominate", - "dominno", "dominion", - "doplhin", "dolphin", - "dortmud", "dortmund", - "draclua", "dracula", - "dracual", "dracula", - "drakest", "darkest", - "dramtic", "dramatic", - "dribbel", "dribble", - "driectx", "directx", - "driftig", "drifting", - "drinkes", "drinkers", - "druming", "drumming", - "duailty", "duality", - "dualtiy", "duality", - "dubsetp", "dubstep", - "dulaity", "duality", - "duleing", "dueling", - "dunegon", "dungeon", - "dungeos", "dungeons", - "dungoen", "dungeon", - "durring", "during", - "dusbtep", "dubstep", - "dyansty", "dynasty", - "dynamis", "dynamics", - "dynsaty", "dynasty", - "earlies", "earliest", - "earliet", "earliest", - "earplus", "earplugs", - "eastwod", "eastwood", - "ebcuase", "becuase", - "ecilpse", "eclipse", - "eclipes", "eclipse", - "eclispe", "eclipse", - "eclpise", "eclipse", - "ectsasy", "ecstasy", - "edbiles", "edibles", - "edibels", "edibles", - "effords", "efforts", - "ehtanol", "ethanol", - "eifnach", "einfach", - "eighten", "eighteen", - "einfahc", "einfach", - "elasped", "elapsed", - "elcipse", "eclipse", - "elction", "election", - "elecrto", "electro", - "electic", "electric", - "electon", "election", - "ellitot", "elliott", - "elloitt", "elliott", - "elphant", "elephant", - "emabrgo", "embargo", - "emabssy", "embassy", - "emapthy", "empathy", - "embeded", "embedded", - "embrago", "embargo", - "eminate", "emanate", - "emipres", "empires", - "emision", "emission", - "emiting", "emitting", - "emition", "emission", - "emmited", "emitted", - "empahty", "empathy", - "emphsis", "emphasis", - "empiers", "empires", - "empited", "emptied", - "emplore", "employer", - "emporer", "emperor", - "empries", "empires", - "emtpied", "emptied", - "enameld", "enameled", - "encahnt", "enchant", - "encalve", "enclave", - "encrpyt", "encrypt", - "encyrpt", "encrypt", - "endores", "endorse", - "endrose", "endorse", - "energis", "energies", - "enforse", "enforces", - "enginer", "engineer", - "englsih", "english", - "enhanse", "enhances", - "enlcave", "enclave", - "enlgish", "english", - "enlsave", "enslave", - "ensalve", "enslave", - "entbook", "netbook", - "entirey", "entirety", - "entorpy", "entropy", - "epiloge", "epilogue", - "episdoe", "episode", - "epsiode", "episode", - "epsorts", "esports", - "eptiome", "epitome", - "equiped", "equipped", - "erested", "arrested", - "escapse", "escapes", - "escpaes", "escapes", - "esctasy", "ecstasy", - "esporst", "esports", - "espreso", "espresso", - "esprots", "esports", - "essense", "essence", - "etherel", "ethereal", - "ethnaol", "ethanol", - "euphora", "euphoria", - "europen", "european", - "eurpean", "european", - "everets", "everest", - "everset", "everest", - "evloved", "evolved", - "evloves", "evolves", - "evovled", "evolved", - "evovles", "evolves", - "exaclty", "exactly", - "exahust", "exhaust", - "examind", "examined", - "exapnds", "expands", - "exatled", "exalted", - "excange", "exchange", - "excatly", "exactly", - "excells", "excels", - "exceprt", "excerpt", - "excluse", "excludes", - "excrept", "excerpt", - "exculde", "exclude", - "exelent", "excellent", - "exemple", "example", - "exerpts", "excerpts", - "exhasut", "exhaust", - "exhuast", "exhaust", - "exising", "existing", - "existet", "existent", - "exlated", "exalted", - "exlcude", "exclude", - "exliled", "exiled", - "exludes", "excludes", - "exmaple", "example", - "exoitcs", "exotics", - "expalin", "explain", - "expeced", "expected", - "expells", "expels", - "expiers", "expires", - "explict", "explicit", - "expliot", "exploit", - "explods", "explodes", - "explose", "explodes", - "expolde", "explode", - "expolit", "exploit", - "exposse", "exposes", - "expries", "expires", - "exsited", "existed", - "extered", "exerted", - "exterme", "extreme", - "extoics", "exotics", - "extreem", "extreme", - "extrems", "extremes", - "eyebals", "eyeballs", - "eyebros", "eyebrows", - "fabulos", "fabulous", - "facebok", "facebook", - "facepam", "facepalm", - "faclons", "falcons", - "facsism", "fascism", - "facsist", "fascist", - "failurs", "failures", - "faincee", "fiancee", - "falesly", "falsely", - "falired", "flaired", - "falshed", "flashed", - "falshes", "flashes", - "falsley", "falsely", - "falvors", "flavors", - "familes", "families", - "famoust", "famous", - "famousy", "famously", - "fanatsy", "fantasy", - "fantaic", "fanatic", - "faoming", "foaming", - "fascits", "fascist", - "fasicsm", "fascism", - "fasicst", "fascist", - "faslely", "falsely", - "fatiuge", "fatigue", - "febuary", "february", - "fecthed", "fetched", - "fecthes", "fetches", - "feminen", "feminine", - "feminie", "feminine", - "feminim", "feminism", - "feodras", "fedoras", - "fertily", "fertility", - "fesitve", "festive", - "fethced", "fetched", - "fethces", "fetches", - "fetishs", "fetishes", - "fianite", "finite", - "fianlly", "finally", - "fiercly", "fiercely", - "filcker", "flicker", - "filpped", "flipped", - "filterd", "filtered", - "finacee", "fiancee", - "fineses", "finesse", - "fininsh", "finnish", - "finishs", "finishes", - "finisse", "finishes", - "finnsih", "finnish", - "firends", "friends", - "firggin", "friggin", - "firsbee", "frisbee", - "firslty", "firstly", - "firtsly", "firstly", - "fitlers", "filters", - "flacons", "falcons", - "flahsed", "flashed", - "flahses", "flashes", - "flaried", "flaired", - "flasely", "falsely", - "flashig", "flashing", - "flavord", "flavored", - "flavous", "flavours", - "flawess", "flawless", - "flciker", "flicker", - "fliters", "filters", - "flordia", "florida", - "florene", "florence", - "fnaatic", "fanatic", - "fomaing", "foaming", - "fonetic", "phonetic", - "forefit", "forfeit", - "foregin", "foreign", - "foreing", "foreign", - "forfiet", "forfeit", - "forhead", "forehead", - "foriegn", "foreign", - "formaly", "formally", - "formery", "formerly", - "formost", "foremost", - "formual", "formula", - "formuls", "formulas", - "forrset", "forrest", - "forsakn", "forsaken", - "forsane", "forsaken", - "forumla", "formula", - "fountan", "fountain", - "fourten", "fourteen", - "fracter", "fracture", - "fragmet", "fragment", - "freedos", "freedoms", - "freinds", "friends", - "frigign", "friggin", - "fristly", "firstly", - "frostig", "frosting", - "frsibee", "frisbee", - "fruitin", "fruition", - "fullets", "fullest", - "fullset", "fullest", - "funides", "fundies", - "funtion", "function", - "furance", "furnace", - "furncae", "furnace", - "futhroc", "futhark", - "gadgest", "gadgets", - "gagdets", "gadgets", - "galatic", "galactic", - "galcier", "glacier", - "galsgow", "glasgow", - "gameply", "gameplay", - "gamerga", "gamertag", - "gankign", "ganking", - "ganster", "gangster", - "garabge", "garbage", - "garfied", "garfield", - "garnola", "granola", - "generas", "generals", - "genersl", "generals", - "geniuss", "geniuses", - "geogria", "georgia", - "geomety", "geometry", - "georiga", "georgia", - "gernade", "grenade", - "gerogia", "georgia", - "gigabye", "gigabyte", - "giltchy", "glitchy", - "gimmics", "gimmicks", - "gimmicy", "gimmicky", - "girzzly", "grizzly", - "glagsow", "glasgow", - "glaicer", "glacier", - "glicthy", "glitchy", - "glimpes", "glimpse", - "glimspe", "glimpse", - "glipmse", "glimpse", - "glitchd", "glitched", - "glitchs", "glitches", - "glithcy", "glitchy", - "globaly", "globally", - "gloiath", "goliath", - "glorios", "glorious", - "gltichy", "glitchy", - "gnaking", "ganking", - "gnawwed", "gnawed", - "goddanm", "goddamn", - "goddman", "goddamn", - "godliek", "godlike", - "godlman", "goldman", - "godsped", "godspeed", - "goergia", "georgia", - "goilath", "goliath", - "golaith", "goliath", - "golbins", "goblins", - "goldamn", "goldman", - "goldbeg", "goldberg", - "goldike", "godlike", - "golitah", "goliath", - "goodluk", "goodluck", - "gorumet", "gourmet", - "gosepls", "gospels", - "gosples", "gospels", - "gpysies", "gypsies", - "grabage", "garbage", - "grahpic", "graphic", - "grainte", "granite", - "grammer", "grammar", - "graniet", "granite", - "grantie", "granite", - "graphie", "graphite", - "graphis", "graphics", - "grappel", "grapple", - "greande", "grenade", - "grenads", "grenades", - "greneer", "greener", - "griaffe", "giraffe", - "gridles", "griddles", - "grillig", "grilling", - "grpahic", "graphic", - "guardin", "guardian", - "guiness", "guinness", - "gullibe", "gullible", - "gutiars", "guitars", - "gypises", "gypsies", - "gyspies", "gypsies", - "habaeus", "habeas", - "haethen", "heathen", - "hailfax", "halifax", - "halfiax", "halifax", - "handbok", "handbook", - "handedy", "handedly", - "handeld", "handled", - "hanlder", "handler", - "hannibl", "hannibal", - "hanuted", "haunted", - "haorder", "hoarder", - "hapened", "happened", - "happend", "happened", - "happliy", "happily", - "harased", "harassed", - "harases", "harasses", - "hardend", "hardened", - "hardwod", "hardwood", - "haricut", "haircut", - "hatchig", "hatching", - "hauntig", "haunting", - "haviest", "heaviest", - "headest", "headset", - "headses", "headsets", - "heaveny", "heavenly", - "heigher", "higher", - "heigths", "heights", - "helemts", "helmets", - "hellfie", "hellfire", - "hellvua", "helluva", - "helment", "helmet", - "helpped", "helped", - "hemlets", "helmets", - "henious", "heinous", - "heorics", "heroics", - "heorine", "heroine", - "heriocs", "heroics", - "herione", "heroine", - "herocis", "heroics", - "heronie", "heroine", - "hesiman", "heisman", - "hieghts", "heights", - "hienous", "heinous", - "hiesman", "heisman", - "himselv", "himself", - "hiptser", "hipster", - "hismelf", "himself", - "hispter", "hipster", - "hitboxs", "hitboxes", - "hoilday", "holiday", - "hokpins", "hopkins", - "holdiay", "holiday", - "holdins", "holdings", - "homniem", "hominem", - "horader", "hoarder", - "hosited", "hoisted", - "hosthot", "hotshot", - "hostles", "hostels", - "hostpot", "hotspot", - "hothsot", "hotshot", - "hotpsot", "hotspot", - "hotsopt", "hotspot", - "hounour", "honour", - "hseldon", "sheldon", - "huanted", "haunted", - "humanit", "humanist", - "humants", "humanist", - "humidiy", "humidity", - "humoros", "humorous", - "hunagry", "hungary", - "hunderd", "hundred", - "hundres", "hundreds", - "hungray", "hungary", - "hurdels", "hurdles", - "hurldes", "hurdles", - "husbans", "husbands", - "hweaton", "wheaton", - "hybirds", "hybrids", - "hydogen", "hydrogen", - "hygeine", "hygiene", - "hypnoss", "hypnosis", - "hyrbids", "hybrids", - "hystera", "hysteria", - "iceforg", "icefrog", - "ierland", "ireland", - "ignitin", "ignition", - "ignorat", "ignorant", - "illegas", "illegals", - "illegsl", "illegals", - "illinos", "illinois", - "imanent", "eminent", - "imapcts", "impacts", - "iminent", "eminent", - "imminet", "imminent", - "implict", "implicit", - "imploed", "implode", - "imploys", "employs", - "impluse", "impulse", - "impolde", "implode", - "importd", "imported", - "imporve", "improve", - "impules", "impulse", - "impusle", "impulse", - "imrpove", "improve", - "incldue", "include", - "incluse", "includes", - "indains", "indians", - "indiaan", "indiana", - "indluge", "indulge", - "indugle", "indulge", - "infalte", "inflate", - "infenro", "inferno", - "infered", "inferred", - "inferir", "inferior", - "infinet", "infinite", - "infinie", "infinite", - "infinit", "infinite", - "infornt", "infront", - "infroms", "informs", - "infrotn", "infront", - "inheirt", "inherit", - "inidans", "indians", - "initals", "initials", - "initisl", "initials", - "inlcine", "incline", - "inovker", "invoker", - "inpeach", "impeach", - "inpsect", "inspect", - "inpsire", "inspire", - "inquier", "inquire", - "inquriy", "inquiry", - "insaney", "insanely", - "inscets", "insects", - "insepct", "inspect", - "insipre", "inspire", - "insluts", "insults", - "instade", "instead", - "instint", "instinct", - "intenst", "intents", - "intered", "interred", - "interet", "interest", - "internt", "internet", - "interro", "interior", - "intrest", "interest", - "intrige", "intrigue", - "invlove", "involve", - "invoekr", "invoker", - "invovle", "involve", - "iornman", "ironman", - "iranain", "iranian", - "iranias", "iranians", - "iranina", "iranian", - "irleand", "ireland", - "ironamn", "ironman", - "isalmic", "islamic", - "isareli", "israeli", - "islamit", "islamist", - "islmaic", "islamic", - "isloate", "isolate", - "isralei", "israeli", - "isreali", "israeli", - "italias", "italians", - "jagaurs", "jaguars", - "jaguras", "jaguars", - "jamacia", "jamaica", - "jamaina", "jamaican", - "jamiaca", "jamaica", - "jamsine", "jasmine", - "janaury", "january", - "januray", "january", - "japanes", "japanese", - "jasmien", "jasmine", - "jaugars", "jaguars", - "jaunary", "january", - "jeircho", "jericho", - "jennins", "jennings", - "jeopary", "jeopardy", - "jeresys", "jerseys", - "jericoh", "jericho", - "jersyes", "jerseys", - "jewerly", "jewelry", - "jorunal", "journal", - "jounral", "journal", - "joystik", "joystick", - "juadism", "judaism", - "judasim", "judaism", - "judical", "judicial", - "juipter", "jupiter", - "junglig", "jungling", - "juptier", "jupiter", - "jusitfy", "justify", - "justfiy", "justify", - "karakoe", "karaoke", - "karoake", "karaoke", - "kenendy", "kennedy", - "kenndey", "kennedy", - "kentucy", "kentucky", - "keyboad", "keyboard", - "keychan", "keychain", - "keynode", "keynote", - "kicthen", "kitchen", - "killins", "killings", - "kineitc", "kinetic", - "kinghts", "knights", - "kinteic", "kinetic", - "kitches", "kitchens", - "kitites", "kitties", - "knietic", "kinetic", - "knigths", "knights", - "knuckel", "knuckle", - "kroeans", "koreans", - "krudish", "kurdish", - "ktichen", "kitchen", - "kubirck", "kubrick", - "kunckle", "knuckle", - "kurbick", "kubrick", - "kuridsh", "kurdish", - "laguage", "language", - "landins", "landings", - "lantren", "lantern", - "laready", "already", - "laregly", "largely", - "largley", "largely", - "lasanga", "lasagna", - "lasgana", "lasagna", - "latitue", "latitude", - "latnern", "lantern", - "launhed", "launched", - "lavendr", "lavender", - "leathal", "lethal", - "lefitst", "leftist", - "leftits", "leftist", - "legnths", "lengths", - "legnthy", "lengthy", - "legoins", "legions", - "leigons", "legions", - "lenghts", "lengths", - "lenoard", "leonard", - "lepoard", "leopard", - "lesbain", "lesbian", - "lesiban", "lesbian", - "lesiure", "leisure", - "liasion", "liaison", - "liasons", "liaisons", - "liberae", "liberate", - "liberas", "liberals", - "lienups", "lineups", - "liesure", "leisure", - "liftime", "lifetime", - "lighlty", "lightly", - "lightes", "lighters", - "ligthly", "lightly", - "linclon", "lincoln", - "linueps", "lineups", - "liqiuds", "liquids", - "lisence", "license", - "lisense", "license", - "listend", "listened", - "litecon", "litecoin", - "literae", "literate", - "lithuim", "lithium", - "litihum", "lithium", - "loadous", "loadouts", - "loenard", "leonard", - "loepard", "leopard", - "logiteh", "logitech", - "loosley", "loosely", - "luandry", "laundry", - "luckliy", "luckily", - "luicfer", "lucifer", - "lunatis", "lunatics", - "maching", "machine", - "machins", "machines", - "maclolm", "malcolm", - "macthup", "matchup", - "madsion", "madison", - "magents", "magnets", - "magicin", "magician", - "magolia", "magnolia", - "maidson", "madison", - "maintan", "maintain", - "mairlyn", "marilyn", - "malaira", "malaria", - "malaysa", "malaysia", - "malclom", "malcolm", - "manauls", "manuals", - "mandase", "mandates", - "mandats", "mandates", - "mangeld", "mangled", - "mangets", "magnets", - "manualy", "manually", - "manuver", "maneuver", - "marbels", "marbles", - "margart", "margaret", - "mariage", "marriage", - "mariens", "marines", - "maritan", "martian", - "marixsm", "marxism", - "mariyln", "marilyn", - "markede", "marketed", - "marlbes", "marbles", - "marliyn", "marilyn", - "marnies", "marines", - "marrage", "marriage", - "martail", "martial", - "martain", "martian", - "masacra", "mascara", - "massace", "massacre", - "mathcup", "matchup", - "mathwes", "mathews", - "matrial", "martial", - "maunals", "manuals", - "mcalren", "mclaren", - "meanins", "meanings", - "medicad", "medicaid", - "medicae", "medicare", - "medioce", "mediocre", - "meixcan", "mexican", - "meldoic", "melodic", - "melieux", "milieux", - "melodis", "melodies", - "memeber", "member", - "memoery", "memory", - "memorie", "memory", - "menally", "mentally", - "mentaly", "mentally", - "meoldic", "melodic", - "meranda", "veranda", - "merchat", "merchant", - "merucry", "mercury", - "messagd", "messaged", - "messaih", "messiah", - "metagem", "metagame", - "metalic", "metallic", - "mexcian", "mexican", - "michina", "michigan", - "midfied", "midfield", - "midotwn", "midtown", - "midtwon", "midtown", - "migrans", "migrants", - "militat", "militant", - "militis", "militias", - "miltary", "military", - "mimimum", "minimum", - "mineras", "minerals", - "mininos", "minions", - "ministr", "minister", - "ministy", "ministry", - "minoins", "minions", - "minstry", "ministry", - "minumum", "minimum", - "mirrord", "mirrored", - "misandy", "misandry", - "misison", "mission", - "misouri", "missouri", - "mispell", "misspell", - "missils", "missiles", - "mistery", "mystery", - "mobiliy", "mobility", - "modualr", "modular", - "momento", "memento", - "momment", "moment", - "monarcy", "monarchy", - "monatge", "montage", - "monglos", "mongols", - "monitos", "monitors", - "monstre", "monster", - "montaeg", "montage", - "montrel", "montreal", - "monumet", "monument", - "morbidy", "morbidly", - "morgage", "mortgage", - "morphen", "morphine", - "morphie", "morphine", - "morroco", "morocco", - "mortage", "mortgage", - "mosnter", "monster", - "mosture", "moisture", - "motivet", "motivate", - "motnage", "montage", - "motoral", "motorola", - "mountan", "mountain", - "movment", "movement", - "mucuous", "mucous", - "muesums", "museums", - "muliple", "multiple", - "mulsims", "muslims", - "multipe", "multiple", - "multipy", "multiply", - "munbers", "numbers", - "munchis", "munchies", - "murderd", "murdered", - "muscial", "musical", - "mushrom", "mushroom", - "musilms", "muslims", - "muslces", "muscles", - "musuems", "museums", - "mutatin", "mutation", - "mypsace", "myspace", - "mysapce", "myspace", - "napolen", "napoleon", - "narhwal", "narwhal", - "natique", "antique", - "nativey", "natively", - "natrual", "natural", - "naugthy", "naughty", - "nauseos", "nauseous", - "nautils", "nautilus", - "nautral", "natural", - "nautres", "natures", - "nectode", "netcode", - "needels", "needles", - "neruons", "neurons", - "neslave", "enslave", - "netocde", "netcode", - "netowrk", "network", - "netural", "neutral", - "neturon", "neutron", - "netwrok", "network", - "neurton", "neutron", - "neuterd", "neutered", - "nighlty", "nightly", - "nigthly", "nightly", - "nihilim", "nihilism", - "ninties", "1990s", - "niverse", "inverse", - "nocture", "nocturne", - "nominae", "nominate", - "nominet", "nominate", - "nonsene", "nonsense", - "noramls", "normals", - "norhern", "northern", - "normaly", "normally", - "normany", "normandy", - "northen", "northern", - "nostris", "nostrils", - "notario", "ontario", - "notebok", "notebook", - "nothern", "northern", - "nowdays", "nowadays", - "nrivana", "nirvana", - "nuaghty", "naughty", - "nubmers", "numbers", - "nucelar", "nuclear", - "nucelus", "nucleus", - "nuclean", "unclean", - "nuclues", "nucleus", - "nucular", "nuclear", - "nuerons", "neurons", - "nuetral", "neutral", - "nuetron", "neutron", - "nulcear", "nuclear", - "nullfiy", "nullify", - "nusance", "nuisance", - "nutriet", "nutrient", - "oarcles", "oracles", - "obivous", "obvious", - "obvoius", "obvious", - "ocarnia", "ocarina", - "ocasion", "occasion", - "occured", "occurred", - "ocotber", "october", - "ocotpus", "octopus", - "ocraina", "ocarina", - "ocuntry", "country", - "ocurred", "occurred", - "ofcoure", "ofcourse", - "offcers", "officers", - "offical", "official", - "offisde", "offside", - "oftenly", "often", - "ogrilla", "gorilla", - "olmypic", "olympic", - "olreans", "orleans", - "olympis", "olympics", - "olypmic", "olympic", - "omision", "omission", - "omiting", "omitting", - "omlette", "omelette", - "ommited", "omitted", - "onatrio", "ontario", - "onbaord", "onboard", - "onborad", "onboard", - "ontairo", "ontario", - "ontraio", "ontario", - "opartor", "operator", - "openess", "openness", - "opitcal", "optical", - "opitmal", "optimal", - "oponent", "opponent", - "oposite", "opposite", - "oppenly", "openly", - "opponet", "opponent", - "oprhans", "orphans", - "optimim", "optimism", - "oracels", "oracles", - "oragnes", "oranges", - "oragsms", "orgasms", - "oralces", "oracles", - "orbtial", "orbital", - "orcales", "oracles", - "orelans", "orleans", - "organes", "organise", - "organie", "organise", - "organim", "organism", - "orginal", "original", - "orhpans", "orphans", - "oribtal", "orbital", - "orlenas", "orleans", - "orpahns", "orphans", - "orthodx", "orthodox", - "outfied", "outfield", - "outsidr", "outsider", - "overhal", "overhaul", - "overpad", "overpaid", - "oversue", "overuse", - "overtun", "overturn", - "ownders", "wonders", - "owuldve", "wouldve", - "oylmpic", "olympic", - "pacakge", "package", - "pacifit", "pacifist", - "packade", "packaged", - "pacthes", "patches", - "pahntom", "phantom", - "paitent", "patient", - "palcebo", "placebo", - "pallete", "palette", - "palster", "plaster", - "palyboy", "playboy", - "pamflet", "pamphlet", - "pamplet", "pamphlet", - "pancaks", "pancakes", - "pandroa", "pandora", - "panthen", "pantheon", - "paradim", "paradigm", - "paradse", "parades", - "paralel", "parallel", - "paranoa", "paranoia", - "parises", "praises", - "parites", "parties", - "partice", "particle", - "partick", "patrick", - "partiel", "particle", - "partiot", "patriot", - "partols", "patrols", - "passabe", "passable", - "passivs", "passives", - "pasuing", "pausing", - "pateint", "patient", - "pathces", "patches", - "patiens", "patients", - "patirot", "patriot", - "patrcik", "patrick", - "patrios", "patriots", - "patroit", "patriot", - "peaples", "peoples", - "pebbels", "pebbles", - "peirced", "pierced", - "penatly", "penalty", - "pendulm", "pendulum", - "penguis", "penguins", - "penicls", "pencils", - "penison", "pension", - "penisse", "penises", - "penitum", "pentium", - "pensies", "penises", - "pensino", "pension", - "pentuim", "pentium", - "peopels", "peoples", - "percise", "precise", - "perdict", "predict", - "perfers", "prefers", - "perhasp", "perhaps", - "perhpas", "perhaps", - "perisan", "persian", - "perjery", "perjury", - "permade", "premade", - "permier", "premier", - "permise", "premise", - "permium", "premium", - "peroids", "periods", - "peronal", "personal", - "perpaid", "prepaid", - "perphas", "perhaps", - "persain", "persian", - "persets", "presets", - "persits", "persist", - "persued", "pursued", - "persuit", "pursuit", - "pervail", "prevail", - "perview", "preview", - "pharoah", "pharaoh", - "phatnom", "phantom", - "phsyics", "physics", - "phyiscs", "physics", - "physcis", "physics", - "physiqe", "physique", - "picthed", "pitched", - "picther", "pitcher", - "picthes", "pitches", - "piegons", "pigeons", - "piglrim", "pilgrim", - "pigoens", "pigeons", - "pilgirm", "pilgrim", - "pilrgim", "pilgrim", - "pinoeer", "pioneer", - "pinpoit", "pinpoint", - "pionere", "pioneer", - "pireced", "pierced", - "pithces", "pitches", - "plantes", "planets", - "plastis", "plastics", - "plastre", "plaster", - "plataeu", "plateau", - "plateua", "plateau", - "playabe", "playable", - "playofs", "playoffs", - "plesant", "pleasant", - "pligrim", "pilgrim", - "ploygon", "polygon", - "ploymer", "polymer", - "podemso", "podemos", - "podmeos", "podemos", - "poeples", "peoples", - "poignat", "poignant", - "poineer", "pioneer", - "pointes", "pointers", - "poisond", "poisoned", - "polgyon", "polygon", - "polical", "political", - "polishs", "polishes", - "polisse", "polishes", - "politey", "politely", - "poluted", "polluted", - "polutes", "pollutes", - "popluar", "popular", - "populer", "popular", - "populos", "populous", - "porpose", "propose", - "porshan", "portion", - "porshon", "portion", - "portait", "portrait", - "portary", "portray", - "portras", "portrays", - "portrat", "portrait", - "posions", "poisons", - "positon", "position", - "positve", "positive", - "possiby", "possibly", - "postdam", "potsdam", - "postion", "position", - "postive", "positive", - "potatos", "potatoes", - "potical", "optical", - "potrait", "portrait", - "powderd", "powdered", - "poweful", "powerful", - "poylgon", "polygon", - "poylmer", "polymer", - "practie", "practise", - "praisse", "praises", - "praries", "prairies", - "prasied", "praised", - "prasies", "praises", - "pratice", "practice", - "preamde", "premade", - "preceed", "precede", - "precice", "precise", - "preests", "presets", - "prehaps", "perhaps", - "preimer", "premier", - "preimum", "premium", - "preists", "priests", - "preivew", "preview", - "premeir", "premier", - "premiee", "premiere", - "premire", "premier", - "premits", "permits", - "premius", "premiums", - "premuim", "premium", - "prepair", "prepare", - "preriod", "period", - "presens", "presents", - "presest", "presets", - "presist", "persist", - "prestes", "presets", - "presude", "presumed", - "pretene", "pretense", - "pretens", "pretends", - "preveiw", "preview", - "prevert", "pervert", - "previal", "prevail", - "previes", "previews", - "previos", "previous", - "priased", "praised", - "priases", "praises", - "printes", "printers", - "pristen", "pristine", - "probabe", "probable", - "probaly", "probably", - "probelm", "problem", - "procede", "proceed", - "procees", "proceeds", - "procesd", "proceeds", - "proclam", "proclaim", - "produly", "proudly", - "produse", "produces", - "progidy", "prodigy", - "progrom", "pogrom", - "prohibt", "prohibit", - "prohpet", "prophet", - "prologe", "prologue", - "promose", "promotes", - "promots", "promotes", - "prompty", "promptly", - "promtps", "prompts", - "pronous", "pronouns", - "prooved", "proved", - "propeht", "prophet", - "prophey", "prophecy", - "propper", "proper", - "protals", "portals", - "protecs", "protects", - "protess", "protests", - "protocl", "protocol", - "protray", "portray", - "prouldy", "proudly", - "provded", "provided", - "provine", "province", - "prusuit", "pursuit", - "pryamid", "pyramid", - "pscyhed", "psyched", - "ptiched", "pitched", - "pticher", "pitcher", - "puasing", "pausing", - "publicy", "publicly", - "publsih", "publish", - "puhsups", "pushups", - "punishs", "punishes", - "punisse", "punishes", - "pursiut", "pursuit", - "pursude", "pursued", - "purused", "pursued", - "pushpus", "pushups", - "pyarmid", "pyramid", - "pyramis", "pyramids", - "pyrmaid", "pyramid", - "pysched", "psyched", - "qaulify", "qualify", - "qaulity", "quality", - "qauntum", "quantum", - "quailfy", "qualify", - "quailty", "quality", - "queires", "queries", - "queitly", "quietly", - "quereis", "queries", - "quicket", "quickest", - "quielty", "quietly", - "quitely", "quietly", - "qunatum", "quantum", - "qunetin", "quentin", - "racisst", "racists", - "racthet", "ratchet", - "radaint", "radiant", - "radiane", "radiance", - "radicas", "radicals", - "radiers", "raiders", - "raelism", "realism", - "raidant", "radiant", - "railrod", "railroad", - "rainbos", "rainbows", - "raoches", "roaches", - "raoming", "roaming", - "raptros", "raptors", - "raputre", "rapture", - "rathcet", "ratchet", - "ratpure", "rapture", - "reacing", "reaching", - "reagrds", "regards", - "realies", "realise", - "realsie", "realise", - "realsim", "realism", - "realtes", "relates", - "reamins", "remains", - "reapirs", "repairs", - "rebouns", "rebounds", - "rebulit", "rebuilt", - "recalim", "reclaim", - "receips", "receipts", - "recided", "resided", - "reciept", "receipt", - "recievd", "recieved", - "recieve", "receive", - "recitfy", "rectify", - "recived", "received", - "reclami", "reclaim", - "recliam", "reclaim", - "recorre", "recorder", - "recoves", "recovers", - "recpies", "recipes", - "redeemd", "redeemed", - "redners", "renders", - "refelct", "reflect", - "referal", "referral", - "refered", "referred", - "referig", "refering", - "referrs", "refers", - "reflexs", "reflexes", - "refrers", "refers", - "refroms", "reforms", - "refusla", "refusal", - "regerts", "regrets", - "regiems", "regimes", - "regimet", "regiment", - "registy", "registry", - "regluar", "regular", - "regrest", "regrets", - "regulae", "regulate", - "regulas", "regulars", - "regulsr", "regulars", - "reigmes", "regimes", - "reigons", "regions", - "reitres", "retires", - "reivews", "reviews", - "reknown", "renown", - "relaise", "realise", - "relapes", "relapse", - "relaspe", "relapse", - "relatie", "relative", - "relatin", "relation", - "relcaim", "reclaim", - "releive", "relieve", - "releses", "releases", - "relfect", "reflect", - "reliabe", "reliable", - "relient", "reliant", - "relized", "realised", - "relpase", "relapse", - "remaind", "remained", - "remaing", "remaining", - "remakrs", "remarks", - "remannt", "remnant", - "remeber", "remember", - "remians", "remains", - "remnans", "remnants", - "renderd", "rendered", - "renegae", "renegade", - "renmant", "remnant", - "rentors", "renters", - "rentres", "renters", - "renuion", "reunion", - "repaird", "repaired", - "repalys", "replays", - "repblic", "republic", - "repeast", "repeats", - "repitle", "reptile", - "replase", "replaces", - "replayd", "replayed", - "reponse", "response", - "repostd", "reposted", - "repsawn", "respawn", - "repsond", "respond", - "repsots", "reposts", - "reptiel", "reptile", - "reptils", "reptiles", - "repubic", "republic", - "republi", "republic", - "repulic", "republic", - "reqiuem", "requiem", - "requeim", "requiem", - "requime", "requiem", - "requred", "required", - "resapwn", "respawn", - "rescuse", "rescues", - "resembe", "resemble", - "reslove", "resolve", - "resolvs", "resolves", - "resonet", "resonate", - "resovle", "resolve", - "respest", "respects", - "respone", "response", - "respwan", "respawn", - "ressits", "resists", - "restord", "restored", - "resuced", "rescued", - "resuces", "rescues", - "returnd", "returned", - "reuinon", "reunion", - "reveald", "revealed", - "reveiws", "reviews", - "revelas", "reveals", - "reveral", "reversal", - "reviere", "reviewer", - "reviewd", "reviewed", - "reviewr", "reviewer", - "revolvr", "revolver", - "revolvs", "revolves", - "rewirte", "rewrite", - "reworkd", "reworked", - "rewriet", "rewrite", - "reynols", "reynolds", - "rhapsoy", "rhapsody", - "rhythem", "rhythm", - "rhythim", "rhythm", - "rhytmic", "rhythmic", - "riaders", "raiders", - "ritlain", "ritalin", - "ritoers", "rioters", - "rivarly", "rivalry", - "rivlary", "rivalry", - "roahces", "roaches", - "robotis", "robotics", - "rococco", "rococo", - "roestta", "rosetta", - "roiters", "rioters", - "roleply", "roleplay", - "romaina", "romania", - "romaing", "roaming", - "romanin", "romanian", - "romanna", "romanian", - "roomate", "roommate", - "rotuers", "routers", - "rugters", "rutgers", - "rulebok", "rulebook", - "rumorus", "rumours", - "rumuors", "rumours", - "runnung", "running", - "ruslted", "rustled", - "russina", "russian", - "russion", "russian", - "rusteld", "rustled", - "rythmic", "rhythmic", - "rythyms", "rhythms", - "sacrasm", "sarcasm", - "saddnes", "saddens", - "sadistc", "sadistic", - "sadning", "sanding", - "salaris", "salaries", - "salavge", "salvage", - "salvery", "slavery", - "salying", "slaying", - "sampels", "samples", - "samruai", "samurai", - "samuari", "samurai", - "samuria", "samurai", - "sandlas", "sandals", - "sandnig", "sanding", - "sanlder", "sandler", - "santorm", "santorum", - "sapphie", "sapphire", - "sarcams", "sarcasm", - "sargant", "sergeant", - "sasuage", "sausage", - "satifsy", "satisfy", - "satsify", "satisfy", - "satsohi", "satoshi", - "savanha", "savannah", - "savannh", "savannah", - "saveing", "saving", - "sawnsea", "swansea", - "sawnson", "swanson", - "scandas", "scandals", - "scannig", "scanning", - "scartch", "scratch", - "scheems", "schemes", - "schoold", "schooled", - "sciense", "sciences", - "scinece", "science", - "scootes", "scooters", - "scorpin", "scorpion", - "scpeter", "scepter", - "scracth", "scratch", - "scrambe", "scramble", - "scritps", "scripts", - "scrolld", "scrolled", - "scrpits", "scripts", - "scyhter", "scyther", - "seached", "searched", - "seaches", "searches", - "seahaws", "seahawks", - "seantor", "senator", - "searchd", "searched", - "searchs", "searches", - "sebrian", "serbian", - "secerts", "secrets", - "secpter", "scepter", - "secrest", "secrets", - "secrety", "secretly", - "seflies", "selfies", - "seguoys", "segues", - "seinors", "seniors", - "selifes", "selfies", - "senoirs", "seniors", - "sensure", "censure", - "sentaor", "senator", - "sentris", "sentries", - "serbain", "serbian", - "sergeat", "sergeant", - "sergent", "sergeant", - "seriban", "serbian", - "servans", "servants", - "sesnors", "sensors", - "settins", "settings", - "severly", "severely", - "sexualy", "sexually", - "seziure", "seizure", - "shaddow", "shadow", - "shanghi", "shanghai", - "shaprie", "sharpie", - "shaprly", "sharply", - "sharipe", "sharpie", - "shcemes", "schemes", - "sheelpe", "sheeple", - "sheepel", "sheeple", - "shephed", "shepherd", - "sherlok", "sherlock", - "shetler", "shelter", - "shevles", "shelves", - "shfiter", "shifter", - "shieldd", "shielded", - "shiping", "shipping", - "shirely", "shirley", - "shitfer", "shifter", - "shledon", "sheldon", - "shleter", "shelter", - "shoudln", "should", - "shouldt", "shouldnt", - "shoutot", "shoutout", - "showede", "showered", - "showerd", "showered", - "shperes", "spheres", - "shriley", "shirley", - "siblins", "siblings", - "sidelen", "sideline", - "sideral", "sidereal", - "siezing", "seizing", - "siezure", "seizure", - "signfiy", "signify", - "signins", "signings", - "signles", "singles", - "silders", "sliders", - "silenty", "silently", - "similir", "similiar", - "simliar", "similar", - "simplet", "simplest", - "simpley", "simply", - "simplfy", "simplify", - "simpliy", "simplify", - "simposn", "simpson", - "simspon", "simpson", - "singals", "signals", - "singels", "singles", - "singify", "signify", - "singsog", "singsong", - "sitmuli", "stimuli", - "skecthy", "sketchy", - "skeletl", "skeletal", - "skeptis", "skeptics", - "sketchs", "sketches", - "sketpic", "skeptic", - "skpetic", "skeptic", - "sktechy", "sketchy", - "skwyard", "skyward", - "slavage", "salvage", - "slayign", "slaying", - "sldiers", "sliders", - "slefies", "selfies", - "slighly", "slightly", - "slighty", "slightly", - "slippes", "slippers", - "slippey", "slippery", - "smaples", "samples", - "smartre", "smarter", - "smaurai", "samurai", - "snadler", "sandler", - "snigles", "singles", - "snippes", "snippets", - "snodwen", "snowden", - "snwoden", "snowden", - "snycing", "syncing", - "snyergy", "synergy", - "socialy", "socially", - "sofware", "software", - "soildly", "solidly", - "soldies", "soldiers", - "soldily", "solidly", - "somaila", "somalia", - "someons", "someones", - "somethn", "somethin", - "southen", "southern", - "soveits", "soviets", - "spacebr", "spacebar", - "spainsh", "spanish", - "spansih", "spanish", - "spanwed", "spawned", - "sparkel", "sparkle", - "spartas", "spartans", - "spartsn", "spartans", - "sparyed", "sprayed", - "spawend", "spawned", - "spawnig", "spawning", - "specail", "special", - "specfic", "specific", - "specias", "specials", - "specisl", "specials", - "spectum", "spectrum", - "speechs", "speeches", - "spehres", "spheres", - "speical", "special", - "speices", "species", - "spellig", "spelling", - "spindel", "spindle", - "spiritd", "spirited", - "splaton", "splatoon", - "splittr", "splitter", - "spoiles", "spoilers", - "spoitfy", "spotify", - "spolied", "spoiled", - "sponser", "sponsor", - "sporles", "sproles", - "sporuts", "sprouts", - "spotfiy", "spotify", - "sprinke", "sprinkle", - "sproels", "sproles", - "spwaned", "spawned", - "sqaures", "squares", - "sqeuaky", "squeaky", - "sqiushy", "squishy", - "squarey", "squarely", - "squirel", "squirtle", - "squirle", "squirrel", - "squirrl", "squirrel", - "squirte", "squirtle", - "squsihy", "squishy", - "sriraca", "sriracha", - "srpouts", "sprouts", - "sryians", "syrians", - "sryinge", "syringe", - "stadius", "stadiums", - "staduim", "stadium", - "stagnat", "stagnant", - "staidum", "stadium", - "stakler", "stalker", - "stalkes", "stalkers", - "stamnia", "stamina", - "staoshi", "satoshi", - "starins", "strains", - "startde", "startled", - "startus", "startups", - "statits", "statist", - "statsit", "statist", - "statuer", "stature", - "statuse", "statutes", - "statuts", "statutes", - "stautes", "statues", - "stealty", "stealthy", - "steeles", "steelers", - "steorid", "steroid", - "steriel", "sterile", - "sterlie", "sterile", - "stickes", "stickers", - "stiring", "stirring", - "stirker", "striker", - "stirrig", "stirring", - "stitchs", "stitches", - "stlaker", "stalker", - "stlyish", "stylish", - "storeis", "stories", - "storise", "stories", - "stormde", "stormed", - "straigt", "straight", - "straind", "strained", - "streamd", "streamed", - "stregth", "strength", - "strengh", "strength", - "streoid", "steroid", - "stresss", "stresses", - "strians", "strains", - "stricty", "strictly", - "striekr", "striker", - "stromed", "stormed", - "stubbon", "stubborn", - "studing", "studying", - "stuidos", "studios", - "stunami", "tsunami", - "stupidr", "stupider", - "stupidy", "stupidly", - "stupire", "stupider", - "suasage", "sausage", - "subisdy", "subsidy", - "subjest", "subjects", - "subtiel", "subtitle", - "succede", "succeed", - "succeds", "succeeds", - "succees", "succeeds", - "succesd", "succeeds", - "suceeds", "succeeds", - "suddeny", "suddenly", - "suefull", "usefull", - "sufferd", "suffered", - "summonr", "summoner", - "summore", "summoner", - "sunggle", "snuggle", - "sunifre", "sunfire", - "superme", "supreme", - "suposed", "supposed", - "suposes", "supposes", - "suppoed", "supposed", - "suppost", "supports", - "suprass", "surpass", - "supress", "suppress", - "suprisd", "suprised", - "suprise", "surprise", - "suprize", "surprise", - "supsend", "suspend", - "suround", "surround", - "surpeme", "supreme", - "surroud", "surround", - "sweidsh", "swedish", - "swiflty", "swiftly", - "swiming", "swimming", - "switchs", "switches", - "switfly", "swiftly", - "swnasea", "swansea", - "sycning", "syncing", - "sycther", "scyther", - "syirans", "syrians", - "sykward", "skyward", - "syllabe", "syllable", - "symetry", "symmetry", - "symmety", "symmetry", - "symobls", "symbols", - "sympaty", "sympathy", - "symtpom", "symptom", - "synegry", "synergy", - "synoynm", "synonym", - "sypmtom", "symptom", - "syracue", "syracuse", - "syrains", "syrians", - "sysadmn", "sysadmin", - "systemc", "systemic", - "sytlish", "stylish", - "tabacco", "tobacco", - "tailban", "taliban", - "tailord", "tailored", - "talbian", "taliban", - "tallets", "tallest", - "tangeld", "tangled", - "tanlged", "tangled", - "targetd", "targeted", - "taryvon", "trayvon", - "teached", "taught", - "teaspon", "teaspoon", - "techeis", "techies", - "tehcies", "techies", - "temepst", "tempest", - "tempels", "temples", - "tempets", "tempest", - "templas", "templars", - "tempset", "tempest", - "tenacle", "tentacle", - "tendacy", "tendency", - "tequlia", "tequila", - "tesitfy", "testify", - "testice", "testicle", - "teusday", "tuesday", - "thankyu", "thankyou", - "thearpy", "therapy", - "theistc", "theistic", - "theives", "thieves", - "themsef", "themself", - "therefo", "thereof", - "therien", "therein", - "theroem", "theorem", - "thesits", "theists", - "thiests", "theists", - "thirldy", "thirdly", - "thirten", "thirteen", - "thirtsy", "thirsty", - "thoerem", "theorem", - "thorats", "throats", - "thornes", "thrones", - "thoruim", "thorium", - "thoughs", "thoughts", - "threadd", "threaded", - "threeof", "thereof", - "thridly", "thirdly", - "thristy", "thirsty", - "throast", "throats", - "throium", "thorium", - "thryoid", "thyroid", - "thyorid", "thyroid", - "thyriod", "thyroid", - "tigther", "tighter", - "tiolets", "toilets", - "tirdent", "trident", - "titanim", "titanium", - "tlaking", "talking", - "tobbaco", "tobacco", - "toliets", "toilets", - "tolkein", "tolkien", - "tomatos", "tomatoes", - "tongiht", "tonight", - "tonuges", "tongues", - "toppins", "toppings", - "torando", "tornado", - "torndao", "tornado", - "torpdeo", "torpedo", - "torrest", "torrents", - "tortila", "tortilla", - "toruney", "tourney", - "toubles", "troubles", - "touchda", "touchpad", - "tounrey", "tourney", - "tourisy", "touristy", - "tourits", "tourist", - "tournes", "tourneys", - "toursim", "tourism", - "toursit", "tourist", - "towords", "towards", - "trackes", "trackers", - "trailes", "trailers", - "traines", "trainers", - "trainig", "training", - "tralier", "trailer", - "tratior", "traitor", - "traveld", "traveled", - "travere", "traverse", - "travesy", "travesty", - "travles", "travels", - "treasue", "treasure", - "treatis", "treaties", - "tremelo", "tremolo", - "trendig", "trending", - "trialer", "trailer", - "triange", "triangle", - "triator", "traitor", - "trickey", "trickery", - "tridnet", "trident", - "trimuph", "triumph", - "trinkes", "trinkets", - "trinkst", "trinkets", - "trintiy", "trinity", - "triolgy", "trilogy", - "troleld", "trolled", - "troling", "trolling", - "tronado", "tornado", - "tropedo", "torpedo", - "trudnle", "trundle", - "truimph", "triumph", - "trukish", "turkish", - "trundel", "trundle", - "trunlde", "trundle", - "tryahrd", "tryhard", - "tryavon", "trayvon", - "tsamina", "stamina", - "tsnuami", "tsunami", - "tsuanmi", "tsunami", - "tsunmai", "tsunami", - "tuesdsy", "tuesdays", - "tunnles", "tunnels", - "turbins", "turbines", - "turksih", "turkish", - "turltes", "turtles", - "turrest", "turrets", - "turtels", "turtles", - "tuseday", "tuesday", - "tusnami", "tsunami", - "tutrles", "turtles", - "twiligt", "twilight", - "tyelnol", "tylenol", - "typcial", "typical", - "tyrhard", "tryhard", - "tyrrany", "tyranny", - "udpated", "updated", - "uesfull", "usefull", - "ugprade", "upgrade", - "ukarine", "ukraine", - "ukranie", "ukraine", - "ukriane", "ukraine", - "ultimae", "ultimate", - "umbrela", "umbrella", - "unahppy", "unhappy", - "unbannd", "unbanned", - "underog", "undergo", - "unfairy", "unfairly", - "ungoldy", "ungodly", - "unicors", "unicorns", - "uniquey", "uniquely", - "unknwon", "unknown", - "unkonwn", "unknown", - "unlcean", "unclean", - "unlcoks", "unlocks", - "unlcuky", "unlucky", - "unlikey", "unlikely", - "unopend", "unopened", - "unprone", "unproven", - "unusabe", "unusable", - "unworty", "unworthy", - "upgarde", "upgrade", - "upgrads", "upgrades", - "uplaods", "uploads", - "upsteam", "upstream", - "urainum", "uranium", - "uranuim", "uranium", - "uretrha", "urethra", - "urkaine", "ukraine", - "urnaium", "uranium", - "urugauy", "uruguay", - "usefull", "useful", - "usefuly", "usefully", - "utiltiy", "utility", - "utopain", "utopian", - "utpoian", "utopian", - "vaccins", "vaccines", - "vaccume", "vacuum", - "vageuly", "vaguely", - "vaguley", "vaguely", - "vairant", "variant", - "valenca", "valencia", - "valetta", "valletta", - "valkyre", "valkyrie", - "valuabe", "valuable", - "valuble", "valuable", - "vampirs", "vampires", - "vanguad", "vanguard", - "varaint", "variant", - "vareity", "variety", - "varians", "variants", - "varient", "variant", - "varisty", "varsity", - "varitey", "variety", - "varstiy", "varsity", - "vasalls", "vassals", - "vasslas", "vassals", - "vaugely", "vaguely", - "vecotrs", "vectors", - "vectros", "vectors", - "veitnam", "vietnam", - "veiwers", "viewers", - "vendeta", "vendetta", - "verbaly", "verbally", - "verical", "vertical", - "verious", "various", - "verison", "version", - "veritgo", "vertigo", - "versoin", "version", - "vertgio", "vertigo", - "vessles", "vessels", - "vetween", "between", - "viatmin", "vitamin", - "vibratr", "vibrator", - "vicitms", "victims", - "vientam", "vietnam", - "vigrins", "virgins", - "vikigns", "vikings", - "villian", "villain", - "villify", "vilify", - "virbate", "vibrate", - "virigns", "virgins", - "virtiol", "vitriol", - "virutal", "virtual", - "virutes", "virtues", - "visable", "visible", - "visably", "visibly", - "visbily", "visibly", - "visting", "visiting", - "vistors", "visitors", - "vitaliy", "vitality", - "vitamis", "vitamins", - "vitenam", "vietnam", - "vitirol", "vitriol", - "vitmain", "vitamin", - "vitroil", "vitriol", - "vitrual", "virtual", - "vitrues", "virtues", - "volatge", "voltage", - "volumne", "volume", - "votlage", "voltage", - "vrigins", "virgins", - "waclott", "walcott", - "wacther", "watcher", - "waitres", "waiters", - "waktins", "watkins", - "warcrat", "warcraft", - "wardobe", "wardrobe", - "wariwck", "warwick", - "warrany", "warranty", - "warrent", "warrant", - "warrios", "warriors", - "warwcik", "warwick", - "wathcer", "watcher", - "watiers", "waiters", - "waviers", "waivers", - "wawrick", "warwick", - "wayword", "wayward", - "webapge", "webpage", - "webiste", "website", - "webstie", "website", - "weigths", "weights", - "weilded", "wielded", - "weirldy", "weirdly", - "weirods", "weirdos", - "welathy", "wealthy", - "wendsay", "wednesday", - "wensday", "wednesday", - "wepbage", "webpage", - "weridly", "weirdly", - "weridos", "weirdos", - "werstle", "wrestle", - "wesbite", "website", - "whaeton", "wheaton", - "whipser", "whisper", - "whislte", "whistle", - "whistel", "whistle", - "whitsle", "whistle", - "whsiper", "whisper", - "wiaters", "waiters", - "wiavers", "waivers", - "widgest", "widgets", - "wieghts", "weights", - "wigdets", "widgets", - "windosr", "windsor", - "winnins", "winnings", - "winsdor", "windsor", - "wintson", "winston", - "wirting", "writing", - "wisnton", "winston", - "withces", "witches", - "witheld", "withheld", - "withing", "within", - "withold", "withhold", - "wlacott", "walcott", - "wokring", "working", - "workins", "workings", - "woudlnt", "wouldnt", - "woudlve", "wouldve", - "woulndt", "wouldnt", - "wreslte", "wrestle", - "wroking", "working", - "wtiches", "witches", - "wupport", "support", - "yaching", "yachting", - "younget", "youngest", - "youseff", "yousef", - "youself", "yourself", - "zaelots", "zealots", - "zealtos", "zealots", - "zelaots", "zealots", - "zelaous", "zealous", - "zimbabe", "zimbabwe", - "zionsim", "zionism", - "zionsit", "zionist", - "zoinism", "zionism", - "zoinist", "zionist", - "abbout", "about", - "abilty", "ability", - "absail", "abseil", - "abutts", "abuts", - "achive", "achieve", - "acused", "accused", - "addopt", "adopt", - "addres", "address", - "adress", "address", - "aeriel", "aerial", - "affort", "afford", - "agains", "against", - "aginst", "against", - "ahppen", "happen", - "aiport", "airport", - "aisian", "asian", - "albiet", "albeit", - "alchol", "alcohol", - "aledge", "allege", - "aleged", "alleged", - "allign", "align", - "almsot", "almost", - "alomst", "almost", - "alowed", "allowed", - "alwasy", "always", - "alwyas", "always", - "amking", "making", - "ammend", "amend", - "amoung", "among", - "aplied", "applied", - "appart", "apart", - "aquire", "acquire", - "aready", "already", - "arised", "arose", - "arival", "arrival", - "arrary", "array", - "artice", "article", - "asetic", "ascetic", - "asside", "aside", - "attemp", "attempt", - "attemt", "attempt", - "auther", "author", - "awared", "awarded", - "bedore", "before", - "beeing", "being", - "befoer", "before", - "beggin", "begin", - "beleif", "belief", - "belive", "believe", - "beteen", "between", - "betwen", "between", - "beween", "between", - "bianry", "binary", - "boyant", "buoyant", - "broady", "broadly", - "buddah", "buddha", - "buring", "burying", - "carcas", "carcass", - "casion", "caisson", - "casued", "caused", - "casues", "causes", - "ceasar", "caesar", - "cencus", "census", - "censur", "censor", - "cheifs", "chiefs", - "circut", "circuit", - "clasic", "classic", - "coform", "conform", - "comany", "company", - "coucil", "council", - "densly", "densely", - "deside", "decide", - "devels", "delves", - "devide", "divide", - "dieing", "dying", - "divice", "device", - "doulbe", "double", - "dreasm", "dreams", - "duting", "during", - "ealier", "earlier", - "eearly", "early", - "efford", "effort", - "emited", "emitted", - "emnity", "enmity", - "enduce", "induce", - "enlish", "english", - "erally", "orally", - "eratic", "erratic", - "ethose", "those", - "exampt", "exempt", - "excact", "exact", - "excell", "excel", - "exerpt", "excerpt", - "exinct", "extinct", - "expell", "expel", - "expoch", "epoch", - "extint", "extinct", - "facist", "fascist", - "faught", "fought", - "finaly", "finally", - "forsaw", "foresaw", - "fougth", "fought", - "fourty", "forty", - "foward", "forward", - "freind", "friend", - "fromed", "formed", - "fufill", "fulfill", - "futher", "further", - "gardai", "gardaí", - "ghandi", "gandhi", - "glight", "flight", - "gloabl", "global", - "godess", "goddess", - "guilia", "giulia", - "guilio", "giulio", - "habeus", "habeas", - "harras", "harass", - "hatian", "haitian", - "heared", "heard", - "hertzs", "hertz", - "hieght", "height", - "higest", "highest", - "higway", "highway", - "honory", "honorary", - "howver", "however", - "hstory", "history", - "hunman", "human", - "husban", "husband", - "hvaing", "having", - "illess", "illness", - "ilness", "illness", - "imagin", "imagine", - "imense", "immense", - "includ", "include", - "inital", "initial", - "interm", "interim", - "intial", "initial", - "iunior", "junior", - "jaques", "jacques", - "jospeh", "joseph", - "jouney", "journey", - "klenex", "kleenex", - "labled", "labelled", - "largst", "largest", - "larrry", "larry", - "lefted", "left", - "lenght", "length", - "lerans", "learns", - "liason", "liaison", - "libary", "library", - "lieing", "lying", - "lieved", "lived", - "littel", "little", - "livley", "lively", - "lonley", "lonely", - "mailny", "mainly", - "markes", "marks", - "mileau", "milieu", - "milion", "million", - "millon", "million", - "misile", "missile", - "missen", "mizzen", - "missle", "missile", - "mkaing", "making", - "moderm", "modem", - "moreso", "more", - "mounth", "month", - "myraid", "myriad", - "naieve", "naive", - "nestin", "nesting", - "nineth", "ninth", - "noveau", "nouveau", - "occour", "occur", - "occurr", "occur", - "offred", "offered", - "omited", "omitted", - "ouevre", "oeuvre", - "oxigen", "oxygen", - "p0enis", "penis", - "packge", "package", - "peaple", "people", - "pensle", "pencil", - "peopel", "people", - "peotry", "poetry", - "perade", "parade", - "persan", "person", - "persue", "pursue", - "plateu", "plateau", - "poenis", "penis", - "poisin", "poison", - "polute", "pollute", - "posess", "possess", - "posion", "poison", - "prairy", "prairie", - "prarie", "prairie", - "preiod", "period", - "privte", "private", - "proces", "process", - "proove", "prove", - "psuedo", "pseudo", - "psyhic", "psychic", - "pucini", "puccini", - "pumkin", "pumpkin", - "puting", "putting", - "pyscic", "psychic", - "quizes", "quizzes", - "quuery", "query", - "racaus", "raucous", - "radify", "ratify", - "raelly", "really", - "reacll", "recall", - "realyl", "really", - "reched", "reached", - "recide", "reside", - "recrod", "record", - "refect", "reflect", - "relaly", "really", - "renewl", "renewal", - "retuns", "returns", - "reveiw", "review", - "rhymme", "rhyme", - "rigeur", "rigueur", - "rocord", "record", - "rougly", "roughly", - "runing", "running", - "rythem", "rhythm", - "rythim", "rhythm", - "saftey", "safety", - "salery", "salary", - "satisy", "satisfy", - "satric", "satiric", - "saught", "sought", - "scince", "science", - "scirpt", "script", - "seceed", "succeed", - "seinor", "senior", - "sepina", "subpoena", - "sevice", "service", - "shamen", "shaman", - "sheild", "shield", - "shiped", "shipped", - "shorly", "shortly", - "shoudl", "should", - "shreak", "shriek", - "siezed", "seized", - "sixtin", "sistine", - "sneeks", "sneaks", - "somene", "someone", - "soudns", "sounds", - "sourth", "south", - "speach", "speech", - "spects", "aspects", - "spoace", "space", - "sqaure", "square", - "staion", "station", - "stange", "strange", - "stilus", "stylus", - "stirrs", "stirs", - "stopry", "story", - "strnad", "strand", - "studdy", "study", - "suceed", "succeed", - "sucess", "success", - "sucide", "suicide", - "sumary", "summary", - "suport", "support", - "supose", "suppose", - "surfce", "surface", - "surley", "surly", - "swaers", "swears", - "swepth", "swept", - "talekd", "talked", - "theese", "these", - "therby", "thereby", - "thigns", "things", - "thigsn", "things", - "thikns", "thinks", - "thiunk", "think", - "thnigs", "things", - "threee", "three", - "tkaing", "taking", - "tounge", "tongue", - "tourch", "torch", - "towrad", "toward", - "trafic", "traffic", - "troups", "troupes", - "truely", "truly", - "twelth", "twelfth", - "tyrany", "tyranny", - "unabel", "unable", - "unkown", "unknown", - "untill", "until", - "usally", "usually", - "useage", "usage", - "useing", "using", - "usualy", "usually", - "vaccum", "vacuum", - "variey", "variety", - "varing", "varying", - "varity", "variety", - "vasall", "vassal", - "vigeur", "vigueur", - "villin", "villain", - "vreity", "variety", - "vriety", "variety", - "whants", "wants", - "wheras", "whereas", - "wheter", "whether", - "wholey", "wholly", - "whther", "whether", - "wnated", "wanted", - "writen", "written", - "yaerly", "yearly", - "yotube", "youtube", - "zeebra", "zebra", - "abotu", "about", - "adres", "address", - "afair", "affair", - "agian", "again", - "agina", "again", - "agred", "agreed", - "alege", "allege", - "alsot", "also", - "altho", "although", - "amung", "among", - "anual", "annual", - "aroud", "around", - "arund", "around", - "asign", "assign", - "assit", "assist", - "asume", "assume", - "atain", "attain", - "autor", "author", - "baout", "about", - "blaim", "blame", - "boaut", "bout", - "boook", "book", - "borke", "broke", - "breif", "brief", - "caost", "coast", - "casue", "cause", - "chasr", "chaser", - "cheif", "chief", - "chuch", "church", - "claer", "clear", - "clera", "clear", - "coudl", "could", - "crowm", "crown", - "deram", "dram", - "diety", "deity", - "doens", "does", - "doign", "doing", - "donig", "doing", - "drnik", "drink", - "durig", "during", - "earnt", "earned", - "eigth", "eighth", - "eiter", "either", - "emtpy", "empty", - "endig", "ending", - "eveyr", "every", - "exept", "except", - "eyars", "years", - "eyasr", "years", - "fiels", "fields", - "firts", "flirts", - "fleed", "fled", - "fomed", "formed", - "foucs", "focus", - "foudn", "found", - "fouth", "fourth", - "frome", "from", - "ganes", "games", - "gaurd", "guard", - "gerat", "great", - "gogin", "going", - "goign", "going", - "gonig", "going", - "graet", "great", - "greif", "grief", - "gropu", "group", - "guage", "gauge", - "hapen", "happen", - "herad", "heard", - "heroe", "hero", - "higer", "higher", - "housr", "hours", - "htere", "there", - "htikn", "think", - "hting", "thing", - "htink", "think", - "hwihc", "which", - "hwile", "while", - "hwole", "whole", - "idaes", "ideas", - "idesa", "ideas", - "ihaca", "ithaca", - "knwos", "knows", - "konws", "knows", - "lastr", "last", - "lavae", "larvae", - "layed", "laid", - "leage", "league", - "leanr", "lean", - "leran", "learn", - "levle", "level", - "lible", "libel", - "liekd", "liked", - "liuke", "like", - "lmits", "limits", - "lonly", "lonely", - "lukid", "likud", - "lybia", "libya", - "maked", "marked", - "makse", "makes", - "mamal", "mammal", - "mileu", "milieu", - "mkaes", "makes", - "modle", "model", - "moent", "moment", - "moeny", "money", - "monts", "months", - "movei", "movie", - "muder", "murder", - "mysef", "myself", - "neice", "niece", - "ninty", "ninety", - "ocurr", "occur", - "oging", "going", - "opose", "oppose", - "orded", "ordered", - "orgin", "origin", - "otehr", "other", - "ouput", "output", - "owudl", "would", - "paide", "paid", - "palce", "place", - "pased", "passed", - "payed", "paid", - "peice", "piece", - "peoms", "poems", - "poety", "poetry", - "pwoer", "power", - "qtuie", "quite", - "qutie", "quite", - "realy", "really", - "repid", "rapid", - "rised", "raised", - "rulle", "rule", - "rwite", "write", - "rythm", "rhythm", - "safty", "safety", - "scoll", "scroll", - "seach", "search", - "seige", "siege", - "seing", "seeing", - "sence", "sense", - "sicne", "since", - "sieze", "seize", - "sinse", "sines", - "slowy", "slowly", - "snese", "sneeze", - "soley", "solely", - "sotry", "story", - "sotyr", "satyr", - "soudn", "sound", - "sould", "could", - "spred", "spread", - "stlye", "style", - "stong", "strong", - "stoyr", "story", - "strat", "start", - "stroy", "story", - "suppy", "supply", - "swaer", "swear", - "syrap", "syrup", - "sytem", "system", - "sytle", "style", - "tatoo", "tattoo", - "thast", "that", - "theif", "thief", - "theri", "their", - "thgat", "that", - "thier", "their", - "thign", "thing", - "thikn", "think", - "thnig", "thing", - "thrid", "third", - "thsoe", "those", - "thyat", "that", - "tihkn", "think", - "timne", "time", - "tiome", "time", - "tkaes", "takes", - "todya", "today", - "tyhat", "that", - "unsed", "used", - "weild", "wield", - "whant", "want", - "whcih", "which", - "whihc", "which", - "whith", "with", - "whlch", "which", - "wholy", "wholly", - "wierd", "weird", - "wille", "will", - "willk", "will", - "withh", "with", - "witht", "with", - "wiull", "will", - "wnats", "wants", - "wohle", "whole", - "worls", "world", - "woudl", "would", - "wriet", "write", - "wroet", "wrote", - "yaers", "years", - "yatch", "yacht", - "yearm", "year", - "yeasr", "years", - "yeild", "yield", - "yeras", "years", - "yersa", "years", - "agin", "again", - "agre", "agree", - "ahev", "have", - "ahve", "have", - "alse", "else", - "amke", "make", - "anbd", "and", - "andd", "and", - "apon", "upon", - "aslo", "also", - "awya", "away", - "bakc", "back", - "bcak", "back", - "clas", "class", - "cpoy", "coy", - "cxan", "cyan", - "daed", "dead", - "dael", "deal", - "diea", "idea", - "doub", "doubt", - "dyas", "dryas", - "eahc", "each", - "efel", "evil", - "eles", "eels", - "ened", "need", - "enxt", "next", - "esle", "else", - "eyar", "year", - "fatc", "fact", - "fidn", "find", - "fomr", "from", - "grwo", "grow", - "haev", "have", - "halp", "help", - "holf", "hold", - "hten", "then", - "htey", "they", - "htis", "this", - "hvae", "have", - "hvea", "have", - "inot", "into", - "iwll", "will", - "iwth", "with", - "jstu", "just", - "jsut", "just", - "knwo", "know", - "konw", "know", - "kwno", "know", - "liek", "like", - "loev", "love", - "lveo", "love", - "lvoe", "love", - "mkae", "make", - "mkea", "make", - "mroe", "more", - "nkow", "know", - "nkwo", "know", - "nmae", "name", - "noth", "north", - "nowe", "now", - "omre", "more", - "onot", "note", - "onyl", "only", - "owrk", "work", - "peom", "poem", - "pich", "pitch", - "rela", "real", - "sasy", "says", - "smae", "same", - "smoe", "some", - "soem", "some", - "sohw", "show", - "stpo", "stop", - "suop", "soup", - "syas", "says", - "tahn", "than", - "taht", "that", - "tast", "taste", - "tath", "that", - "tehy", "they", - "tghe", "the", - "ther", "there", - "thge", "the", - "thna", "than", - "thne", "then", - "thsi", "this", - "thta", "that", - "tiem", "time", - "tihs", "this", - "tjhe", "the", - "tkae", "take", - "tood", "todo", - "tust", "trust", - "twon", "town", - "twpo", "two", - "tyhe", "they", - "uise", "use", - "vell", "well", - "veyr", "very", - "vrey", "very", - "vyer", "very", - "vyre", "very", - "waht", "what", - "wass", "was", - "watn", "want", - "weas", "was", - "wehn", "when", - "whic", "which", - "whta", "what", - "wich", "which", - "wief", "wife", - "wiew", "view", - "wiht", "with", - "witn", "with", - "wnat", "want", - "wokr", "work", - "wrok", "work", - "wtih", "with", - "yaer", "year", - "yera", "year", - "yrea", "year", - "ytou", "you", - "adn", "and", - "ect", "etc", - "nto", "not", - "teh", "the", - "thn", "then", - "tje", "the", - "whn", "when", - "wih", "with", - "yuo", "you", -} - -// DictAmerican converts UK spellings to US spellings -var DictAmerican = []string{ - "institutionalisation", "institutionalization", - "internationalisation", "internationalization", - "professionalisation", "professionalization", - "compartmentalising", "compartmentalizing", - "institutionalising", "institutionalizing", - "internationalising", "internationalizing", - "compartmentalised", "compartmentalized", - "compartmentalises", "compartmentalizes", - "decriminalisation", "decriminalization", - "denationalisation", "denationalization", - "fictionalisations", "fictionalizations", - "institutionalised", "institutionalized", - "institutionalises", "institutionalizes", - "intellectualising", "intellectualizing", - "internationalised", "internationalized", - "internationalises", "internationalizes", - "pedestrianisation", "pedestrianization", - "professionalising", "professionalizing", - "archaeologically", "archeologically", - "compartmentalise", "compartmentalize", - "decentralisation", "decentralization", - "demilitarisation", "demilitarization", - "externalisations", "externalizations", - "fictionalisation", "fictionalization", - "institutionalise", "institutionalize", - "intellectualised", "intellectualized", - "intellectualises", "intellectualizes", - "internationalise", "internationalize", - "nationalisations", "nationalizations", - "palaeontologists", "paleontologists", - "professionalised", "professionalized", - "professionalises", "professionalizes", - "rationalisations", "rationalizations", - "sensationalising", "sensationalizing", - "sentimentalising", "sentimentalizing", - "acclimatisation", "acclimatization", - "bougainvillaeas", "bougainvilleas", - "commercialising", "commercializing", - "conceptualising", "conceptualizing", - "contextualising", "contextualizing", - "crystallisation", "crystallization", - "decriminalising", "decriminalizing", - "democratisation", "democratization", - "denationalising", "denationalizing", - "depersonalising", "depersonalizing", - "desensitisation", "desensitization", - "destabilisation", "destabilization", - "disorganisation", "disorganization", - "extemporisation", "extemporization", - "externalisation", "externalization", - "familiarisation", "familiarization", - "generalisations", "generalizations", - "hospitalisation", "hospitalization", - "individualising", "individualizing", - "industrialising", "industrializing", - "intellectualise", "intellectualize", - "internalisation", "internalization", - "manoeuvrability", "maneuverability", - "marginalisation", "marginalization", - "materialisation", "materialization", - "miniaturisation", "miniaturization", - "nationalisation", "nationalization", - "neighbourliness", "neighborliness", - "overemphasising", "overemphasizing", - "palaeontologist", "paleontologist", - "particularising", "particularizing", - "pedestrianising", "pedestrianizing", - "professionalise", "professionalize", - "psychoanalysing", "psychoanalyzing", - "rationalisation", "rationalization", - "reorganisations", "reorganizations", - "revolutionising", "revolutionizing", - "sensationalised", "sensationalized", - "sensationalises", "sensationalizes", - "sentimentalised", "sentimentalized", - "sentimentalises", "sentimentalizes", - "specialisations", "specializations", - "standardisation", "standardization", - "synchronisation", "synchronization", - "systematisation", "systematization", - "aggrandisement", "aggrandizement", - "anaesthetising", "anesthetizing", - "archaeological", "archeological", - "archaeologists", "archeologists", - "bougainvillaea", "bougainvillea", - "characterising", "characterizing", - "collectivising", "collectivizing", - "commercialised", "commercialized", - "commercialises", "commercializes", - "conceptualised", "conceptualized", - "conceptualises", "conceptualizes", - "contextualised", "contextualized", - "contextualises", "contextualizes", - "decentralising", "decentralizing", - "decriminalised", "decriminalized", - "decriminalises", "decriminalizes", - "dehumanisation", "dehumanization", - "demilitarising", "demilitarizing", - "demobilisation", "demobilization", - "demoralisation", "demoralization", - "denationalised", "denationalized", - "denationalises", "denationalizes", - "depersonalised", "depersonalized", - "depersonalises", "depersonalizes", - "disembowelling", "disemboweling", - "dramatisations", "dramatizations", - "editorialising", "editorializing", - "encyclopaedias", "encyclopedias", - "fictionalising", "fictionalizing", - "fraternisation", "fraternization", - "generalisation", "generalization", - "gynaecological", "gynecological", - "gynaecologists", "gynecologists", - "haematological", "hematological", - "haematologists", "hematologists", - "immobilisation", "immobilization", - "individualised", "individualized", - "individualises", "individualizes", - "industrialised", "industrialized", - "industrialises", "industrializes", - "liberalisation", "liberalization", - "monopolisation", "monopolization", - "naturalisation", "naturalization", - "neighbourhoods", "neighborhoods", - "neutralisation", "neutralization", - "organisational", "organizational", - "outmanoeuvring", "outmaneuvering", - "overemphasised", "overemphasized", - "overemphasises", "overemphasizes", - "paediatricians", "pediatricians", - "particularised", "particularized", - "particularises", "particularizes", - "pasteurisation", "pasteurization", - "pedestrianised", "pedestrianized", - "pedestrianises", "pedestrianizes", - "philosophising", "philosophizing", - "politicisation", "politicization", - "popularisation", "popularization", - "pressurisation", "pressurization", - "prioritisation", "prioritization", - "privatisations", "privatizations", - "propagandising", "propagandizing", - "psychoanalysed", "psychoanalyzed", - "psychoanalyses", "psychoanalyzes", - "regularisation", "regularization", - "reorganisation", "reorganization", - "revolutionised", "revolutionized", - "revolutionises", "revolutionizes", - "secularisation", "secularization", - "sensationalise", "sensationalize", - "sentimentalise", "sentimentalize", - "serialisations", "serializations", - "specialisation", "specialization", - "sterilisations", "sterilizations", - "stigmatisation", "stigmatization", - "transistorised", "transistorized", - "unrecognisable", "unrecognizable", - "visualisations", "visualizations", - "westernisation", "westernization", - "accessorising", "accessorizing", - "acclimatising", "acclimatizing", - "amortisations", "amortizations", - "amphitheatres", "amphitheaters", - "anaesthetised", "anesthetized", - "anaesthetises", "anesthetizes", - "anaesthetists", "anesthetists", - "archaeologist", "archeologist", - "backpedalling", "backpedaling", - "behaviourists", "behaviorists", - "breathalysers", "breathalyzers", - "breathalysing", "breathalyzing", - "callisthenics", "calisthenics", - "cannibalising", "cannibalizing", - "characterised", "characterized", - "characterises", "characterizes", - "circularising", "circularizing", - "clarinettists", "clarinetists", - "collectivised", "collectivized", - "collectivises", "collectivizes", - "commercialise", "commercialize", - "computerising", "computerizing", - "conceptualise", "conceptualize", - "contextualise", "contextualize", - "criminalising", "criminalizing", - "crystallising", "crystallizing", - "decentralised", "decentralized", - "decentralises", "decentralizes", - "decriminalise", "decriminalize", - "demilitarised", "demilitarized", - "demilitarises", "demilitarizes", - "democratising", "democratizing", - "denationalise", "denationalize", - "depersonalise", "depersonalize", - "desensitising", "desensitizing", - "destabilising", "destabilizing", - "disembowelled", "disemboweled", - "dishonourable", "dishonorable", - "dishonourably", "dishonorably", - "dramatisation", "dramatization", - "editorialised", "editorialized", - "editorialises", "editorializes", - "encyclopaedia", "encyclopedia", - "encyclopaedic", "encyclopedic", - "extemporising", "extemporizing", - "externalising", "externalizing", - "familiarising", "familiarizing", - "fertilisation", "fertilization", - "fictionalised", "fictionalized", - "fictionalises", "fictionalizes", - "formalisation", "formalization", - "fossilisation", "fossilization", - "globalisation", "globalization", - "gynaecologist", "gynecologist", - "haematologist", "hematologist", - "haemophiliacs", "hemophiliacs", - "haemorrhaging", "hemorrhaging", - "harmonisation", "harmonization", - "hospitalising", "hospitalizing", - "hypothesising", "hypothesizing", - "immortalising", "immortalizing", - "individualise", "individualize", - "industrialise", "industrialize", - "internalising", "internalizing", - "marginalising", "marginalizing", - "materialising", "materializing", - "mechanisation", "mechanization", - "memorialising", "memorializing", - "miniaturising", "miniaturizing", - "miscatalogued", "miscataloged", - "misdemeanours", "misdemeanors", - "multicoloured", "multicolored", - "nationalising", "nationalizing", - "neighbourhood", "neighborhood", - "normalisation", "normalization", - "organisations", "organizations", - "outmanoeuvred", "outmaneuvered", - "outmanoeuvres", "outmaneuvers", - "overemphasise", "overemphasize", - "paediatrician", "pediatrician", - "palaeontology", "paleontology", - "particularise", "particularize", - "passivisation", "passivization", - "patronisingly", "patronizingly", - "pedestrianise", "pedestrianize", - "personalising", "personalizing", - "philosophised", "philosophized", - "philosophises", "philosophizes", - "privatisation", "privatization", - "propagandised", "propagandized", - "propagandises", "propagandizes", - "proselytisers", "proselytizers", - "proselytising", "proselytizing", - "psychoanalyse", "psychoanalyze", - "pulverisation", "pulverization", - "rationalising", "rationalizing", - "reconnoitring", "reconnoitering", - "revolutionise", "revolutionize", - "romanticising", "romanticizing", - "serialisation", "serialization", - "socialisation", "socialization", - "stabilisation", "stabilization", - "standardising", "standardizing", - "sterilisation", "sterilization", - "subsidisation", "subsidization", - "synchronising", "synchronizing", - "systematising", "systematizing", - "tantalisingly", "tantalizingly", - "underutilised", "underutilized", - "victimisation", "victimization", - "visualisation", "visualization", - "vocalisations", "vocalizations", - "vulgarisation", "vulgarization", - "accessorised", "accessorized", - "accessorises", "accessorizes", - "acclimatised", "acclimatized", - "acclimatises", "acclimatizes", - "amortisation", "amortization", - "amphitheatre", "amphitheater", - "anaesthetics", "anesthetics", - "anaesthetise", "anesthetize", - "anaesthetist", "anesthetist", - "antagonising", "antagonizing", - "appetisingly", "appetizingly", - "backpedalled", "backpedaled", - "bastardising", "bastardizing", - "behaviourism", "behaviorism", - "behaviourist", "behaviorist", - "bowdlerising", "bowdlerizing", - "breathalysed", "breathalyzed", - "breathalyser", "breathalyzer", - "breathalyses", "breathalyzes", - "cannibalised", "cannibalized", - "cannibalises", "cannibalizes", - "capitalising", "capitalizing", - "caramelising", "caramelizing", - "categorising", "categorizing", - "centigrammes", "centigrams", - "centralising", "centralizing", - "centrepieces", "centerpieces", - "characterise", "characterize", - "circularised", "circularized", - "circularises", "circularizes", - "clarinettist", "clarinetist", - "collectivise", "collectivize", - "colonisation", "colonization", - "computerised", "computerized", - "computerises", "computerizes", - "criminalised", "criminalized", - "criminalises", "criminalizes", - "crystallised", "crystallized", - "crystallises", "crystallizes", - "decentralise", "decentralize", - "dehumanising", "dehumanizing", - "demilitarise", "demilitarize", - "demobilising", "demobilizing", - "democratised", "democratized", - "democratises", "democratizes", - "demoralising", "demoralizing", - "desensitised", "desensitized", - "desensitises", "desensitizes", - "destabilised", "destabilized", - "destabilises", "destabilizes", - "discolouring", "discoloring", - "dishonouring", "dishonoring", - "disorganised", "disorganized", - "editorialise", "editorialize", - "endeavouring", "endeavoring", - "equalisation", "equalization", - "evangelising", "evangelizing", - "extemporised", "extemporized", - "extemporises", "extemporizes", - "externalised", "externalized", - "externalises", "externalizes", - "familiarised", "familiarized", - "familiarises", "familiarizes", - "fictionalise", "fictionalize", - "finalisation", "finalization", - "fraternising", "fraternizing", - "generalising", "generalizing", - "haemophiliac", "hemophiliac", - "haemorrhaged", "hemorrhaged", - "haemorrhages", "hemorrhages", - "haemorrhoids", "hemorrhoids", - "homoeopathic", "homeopathic", - "homogenising", "homogenizing", - "hospitalised", "hospitalized", - "hospitalises", "hospitalizes", - "hypothesised", "hypothesized", - "hypothesises", "hypothesizes", - "idealisation", "idealization", - "immobilisers", "immobilizers", - "immobilising", "immobilizing", - "immortalised", "immortalized", - "immortalises", "immortalizes", - "immunisation", "immunization", - "initialising", "initializing", - "internalised", "internalized", - "internalises", "internalizes", - "jeopardising", "jeopardizing", - "legalisation", "legalization", - "legitimising", "legitimizing", - "liberalising", "liberalizing", - "manoeuvrable", "maneuverable", - "manoeuvrings", "maneuverings", - "marginalised", "marginalized", - "marginalises", "marginalizes", - "marvellously", "marvelously", - "materialised", "materialized", - "materialises", "materializes", - "maximisation", "maximization", - "memorialised", "memorialized", - "memorialises", "memorializes", - "metabolising", "metabolizing", - "militarising", "militarizing", - "milligrammes", "milligrams", - "miniaturised", "miniaturized", - "miniaturises", "miniaturizes", - "misbehaviour", "misbehavior", - "misdemeanour", "misdemeanor", - "mobilisation", "mobilization", - "moisturisers", "moisturizers", - "moisturising", "moisturizing", - "monopolising", "monopolizing", - "moustachioed", "mustachioed", - "nationalised", "nationalized", - "nationalises", "nationalizes", - "naturalising", "naturalizing", - "neighbouring", "neighboring", - "neutralising", "neutralizing", - "oesophaguses", "esophaguses", - "organisation", "organization", - "orthopaedics", "orthopedics", - "outmanoeuvre", "outmaneuver", - "palaeolithic", "paleolithic", - "pasteurising", "pasteurizing", - "personalised", "personalized", - "personalises", "personalizes", - "philosophise", "philosophize", - "plagiarising", "plagiarizing", - "ploughshares", "plowshares", - "polarisation", "polarization", - "politicising", "politicizing", - "popularising", "popularizing", - "pressurising", "pressurizing", - "prioritising", "prioritizing", - "propagandise", "propagandize", - "proselytised", "proselytized", - "proselytiser", "proselytizer", - "proselytises", "proselytizes", - "radicalising", "radicalizing", - "rationalised", "rationalized", - "rationalises", "rationalizes", - "realisations", "realizations", - "recognisable", "recognizable", - "recognisably", "recognizably", - "recognisance", "recognizance", - "reconnoitred", "reconnoitered", - "reconnoitres", "reconnoiters", - "regularising", "regularizing", - "reorganising", "reorganizing", - "revitalising", "revitalizing", - "rhapsodising", "rhapsodizing", - "romanticised", "romanticized", - "romanticises", "romanticizes", - "scandalising", "scandalizing", - "scrutinising", "scrutinizing", - "secularising", "secularizing", - "specialising", "specializing", - "squirrelling", "squirreling", - "standardised", "standardized", - "standardises", "standardizes", - "stigmatising", "stigmatizing", - "sympathisers", "sympathizers", - "sympathising", "sympathizing", - "synchronised", "synchronized", - "synchronises", "synchronizes", - "synthesisers", "synthesizers", - "synthesising", "synthesizing", - "systematised", "systematized", - "systematises", "systematizes", - "technicolour", "technicolor", - "theatregoers", "theatergoers", - "traumatising", "traumatizing", - "trivialising", "trivializing", - "unauthorised", "unauthorized", - "uncatalogued", "uncataloged", - "unfavourable", "unfavorable", - "unfavourably", "unfavorably", - "unionisation", "unionization", - "unrecognised", "unrecognized", - "untrammelled", "untrammeled", - "urbanisation", "urbanization", - "vaporisation", "vaporization", - "vocalisation", "vocalization", - "watercolours", "watercolors", - "westernising", "westernizing", - "accessorise", "accessorize", - "acclimatise", "acclimatize", - "agonisingly", "agonizingly", - "amortisable", "amortizable", - "anaesthesia", "anesthesia", - "anaesthetic", "anesthetic", - "anglicising", "anglicizing", - "antagonised", "antagonized", - "antagonises", "antagonizes", - "apologising", "apologizing", - "archaeology", "archeology", - "authorising", "authorizing", - "bastardised", "bastardized", - "bastardises", "bastardizes", - "bedevilling", "bedeviling", - "behavioural", "behavioral", - "belabouring", "belaboring", - "bowdlerised", "bowdlerized", - "bowdlerises", "bowdlerizes", - "breathalyse", "breathalyze", - "brutalising", "brutalizing", - "cannibalise", "cannibalize", - "capitalised", "capitalized", - "capitalises", "capitalizes", - "caramelised", "caramelized", - "caramelises", "caramelizes", - "carbonising", "carbonizing", - "cataloguing", "cataloging", - "categorised", "categorized", - "categorises", "categorizes", - "cauterising", "cauterizing", - "centigramme", "centigram", - "centilitres", "centiliters", - "centimetres", "centimeters", - "centralised", "centralized", - "centralises", "centralizes", - "centrefolds", "centerfolds", - "centrepiece", "centerpiece", - "channelling", "channeling", - "chequebooks", "checkbooks", - "circularise", "circularize", - "colourfully", "colorfully", - "colourizing", "colorizing", - "computerise", "computerize", - "councillors", "councilors", - "counselling", "counseling", - "counsellors", "counselors", - "criminalise", "criminalize", - "criticising", "criticizing", - "crystallise", "crystallize", - "customising", "customizing", - "defenceless", "defenseless", - "dehumanised", "dehumanized", - "dehumanises", "dehumanizes", - "demobilised", "demobilized", - "demobilises", "demobilizes", - "democratise", "democratize", - "demoralised", "demoralized", - "demoralises", "demoralizes", - "deodorising", "deodorizing", - "desensitise", "desensitize", - "destabilise", "destabilize", - "discoloured", "discolored", - "dishevelled", "disheveled", - "dishonoured", "dishonored", - "dramatising", "dramatizing", - "economising", "economizing", - "empathising", "empathizing", - "emphasising", "emphasizing", - "endeavoured", "endeavored", - "epitomising", "epitomizing", - "evangelised", "evangelized", - "evangelises", "evangelizes", - "extemporise", "extemporize", - "externalise", "externalize", - "factorising", "factorizing", - "familiarise", "familiarize", - "fantasising", "fantasizing", - "favouritism", "favoritism", - "fertilisers", "fertilizers", - "fertilising", "fertilizing", - "flavourings", "flavorings", - "flavourless", "flavorless", - "flavoursome", "flavorsome", - "formalising", "formalizing", - "fossilising", "fossilizing", - "fraternised", "fraternized", - "fraternises", "fraternizes", - "galvanising", "galvanizing", - "generalised", "generalized", - "generalises", "generalizes", - "ghettoising", "ghettoizing", - "globalising", "globalizing", - "gruellingly", "gruelingly", - "gynaecology", "gynecology", - "haematology", "hematology", - "haemoglobin", "hemoglobin", - "haemophilia", "hemophilia", - "haemorrhage", "hemorrhage", - "harmonising", "harmonizing", - "homoeopaths", "homeopaths", - "homoeopathy", "homeopathy", - "homogenised", "homogenized", - "homogenises", "homogenizes", - "hospitalise", "hospitalize", - "hybridising", "hybridizing", - "hypnotising", "hypnotizing", - "hypothesise", "hypothesize", - "immobilised", "immobilized", - "immobiliser", "immobilizer", - "immobilises", "immobilizes", - "immortalise", "immortalize", - "impanelling", "impaneling", - "imperilling", "imperiling", - "initialised", "initialized", - "initialises", "initializes", - "initialling", "initialing", - "instalments", "installments", - "internalise", "internalize", - "italicising", "italicizing", - "jeopardised", "jeopardized", - "jeopardises", "jeopardizes", - "kilogrammes", "kilograms", - "legitimised", "legitimized", - "legitimises", "legitimizes", - "liberalised", "liberalized", - "liberalises", "liberalizes", - "lionisation", "lionization", - "liquidisers", "liquidizers", - "liquidising", "liquidizing", - "magnetising", "magnetizing", - "manoeuvring", "maneuvering", - "marginalise", "marginalize", - "marshalling", "marshaling", - "materialise", "materialize", - "mechanising", "mechanizing", - "memorialise", "memorialize", - "mesmerising", "mesmerizing", - "metabolised", "metabolized", - "metabolises", "metabolizes", - "micrometres", "micrometers", - "militarised", "militarized", - "militarises", "militarizes", - "milligramme", "milligram", - "millilitres", "milliliters", - "millimetres", "millimeters", - "miniaturise", "miniaturize", - "modernising", "modernizing", - "moisturised", "moisturized", - "moisturiser", "moisturizer", - "moisturises", "moisturizes", - "monopolised", "monopolized", - "monopolises", "monopolizes", - "nationalise", "nationalize", - "naturalised", "naturalized", - "naturalises", "naturalizes", - "neighbourly", "neighborly", - "neutralised", "neutralized", - "neutralises", "neutralizes", - "normalising", "normalizing", - "orthopaedic", "orthopedic", - "ostracising", "ostracizing", - "oxidisation", "oxidization", - "paediatrics", "pediatrics", - "paedophiles", "pedophiles", - "paedophilia", "pedophilia", - "passivising", "passivizing", - "pasteurised", "pasteurized", - "pasteurises", "pasteurizes", - "patronising", "patronizing", - "personalise", "personalize", - "plagiarised", "plagiarized", - "plagiarises", "plagiarizes", - "ploughshare", "plowshare", - "politicised", "politicized", - "politicises", "politicizes", - "popularised", "popularized", - "popularises", "popularizes", - "praesidiums", "presidiums", - "pressurised", "pressurized", - "pressurises", "pressurizes", - "prioritised", "prioritized", - "prioritises", "prioritizes", - "privatising", "privatizing", - "proselytise", "proselytize", - "publicising", "publicizing", - "pulverising", "pulverizing", - "quarrelling", "quarreling", - "radicalised", "radicalized", - "radicalises", "radicalizes", - "randomising", "randomizing", - "rationalise", "rationalize", - "realisation", "realization", - "recognising", "recognizing", - "reconnoitre", "reconnoiter", - "regularised", "regularized", - "regularises", "regularizes", - "remodelling", "remodeling", - "reorganised", "reorganized", - "reorganises", "reorganizes", - "revitalised", "revitalized", - "revitalises", "revitalizes", - "rhapsodised", "rhapsodized", - "rhapsodises", "rhapsodizes", - "romanticise", "romanticize", - "scandalised", "scandalized", - "scandalises", "scandalizes", - "sceptically", "skeptically", - "scrutinised", "scrutinized", - "scrutinises", "scrutinizes", - "secularised", "secularized", - "secularises", "secularizes", - "sensitising", "sensitizing", - "serialising", "serializing", - "sermonising", "sermonizing", - "shrivelling", "shriveling", - "signalising", "signalizing", - "snorkelling", "snorkeling", - "snowploughs", "snowplow", - "socialising", "socializing", - "solemnising", "solemnizing", - "specialised", "specialized", - "specialises", "specializes", - "squirrelled", "squirreled", - "stabilisers", "stabilizers", - "stabilising", "stabilizing", - "standardise", "standardize", - "stencilling", "stenciling", - "sterilisers", "sterilizers", - "sterilising", "sterilizing", - "stigmatised", "stigmatized", - "stigmatises", "stigmatizes", - "subsidisers", "subsidizers", - "subsidising", "subsidizing", - "summarising", "summarizing", - "symbolising", "symbolizing", - "sympathised", "sympathized", - "sympathiser", "sympathizer", - "sympathises", "sympathizes", - "synchronise", "synchronize", - "synthesised", "synthesized", - "synthesiser", "synthesizer", - "synthesises", "synthesizes", - "systematise", "systematize", - "tantalising", "tantalizing", - "temporising", "temporizing", - "tenderising", "tenderizing", - "terrorising", "terrorizing", - "theatregoer", "theatergoer", - "traumatised", "traumatized", - "traumatises", "traumatizes", - "trivialised", "trivialized", - "trivialises", "trivializes", - "tyrannising", "tyrannizing", - "uncivilised", "uncivilized", - "unorganised", "unorganized", - "unravelling", "unraveling", - "utilisation", "utilization", - "vandalising", "vandalizing", - "verbalising", "verbalizing", - "victimising", "victimizing", - "visualising", "visualizing", - "vulgarising", "vulgarizing", - "watercolour", "watercolor", - "westernised", "westernized", - "westernises", "westernizes", - "worshipping", "worshiping", - "aeroplanes", "airplanes", - "amortising", "amortizing", - "anglicised", "anglicized", - "anglicises", "anglicizes", - "annualised", "annualized", - "antagonise", "antagonize", - "apologised", "apologized", - "apologises", "apologizes", - "appetisers", "appetizers", - "appetising", "appetizing", - "authorised", "authorized", - "authorises", "authorizes", - "bannisters", "banisters", - "bastardise", "bastardize", - "bedevilled", "bedeviled", - "behaviours", "behaviors", - "bejewelled", "bejeweled", - "belaboured", "belabored", - "bowdlerise", "bowdlerize", - "brutalised", "brutalized", - "brutalises", "brutalizes", - "canalising", "canalizing", - "cancelling", "canceling", - "canonising", "canonizing", - "capitalise", "capitalize", - "caramelise", "caramelize", - "carbonised", "carbonized", - "carbonises", "carbonizes", - "catalogued", "cataloged", - "catalogues", "catalogs", - "catalysing", "catalyzing", - "categorise", "categorize", - "cauterised", "cauterized", - "cauterises", "cauterizes", - "centilitre", "centiliter", - "centimetre", "centimeter", - "centralise", "centralize", - "centrefold", "centerfold", - "channelled", "channeled", - "chequebook", "checkbook", - "chiselling", "chiseling", - "civilising", "civilizing", - "clamouring", "clamoring", - "colonisers", "colonizers", - "colonising", "colonizing", - "colourants", "colorants", - "colourized", "colorized", - "colourizes", "colorizes", - "colourless", "colorless", - "connexions", "connections", - "councillor", "councilor", - "counselled", "counseled", - "counsellor", "counselor", - "criticised", "criticized", - "criticises", "criticizes", - "cudgelling", "cudgeling", - "customised", "customized", - "customises", "customizes", - "dehumanise", "dehumanize", - "demobilise", "demobilize", - "demonising", "demonizing", - "demoralise", "demoralize", - "deodorised", "deodorized", - "deodorises", "deodorizes", - "deputising", "deputizing", - "digitising", "digitizing", - "discolours", "discolors", - "dishonours", "dishonors", - "dramatised", "dramatized", - "dramatises", "dramatizes", - "drivelling", "driveling", - "economised", "economized", - "economises", "economizes", - "empathised", "empathized", - "empathises", "empathizes", - "emphasised", "emphasized", - "emphasises", "emphasizes", - "enamelling", "enameling", - "endeavours", "endeavors", - "energising", "energizing", - "epaulettes", "epaulets", - "epicentres", "epicenters", - "epitomised", "epitomized", - "epitomises", "epitomizes", - "equalisers", "equalizers", - "equalising", "equalizing", - "eulogising", "eulogizing", - "evangelise", "evangelize", - "factorised", "factorized", - "factorises", "factorizes", - "fantasised", "fantasized", - "fantasises", "fantasizes", - "favourable", "favorable", - "favourably", "favorably", - "favourites", "favorites", - "feminising", "feminizing", - "fertilised", "fertilized", - "fertiliser", "fertilizer", - "fertilises", "fertilizes", - "fibreglass", "fiberglass", - "finalising", "finalizing", - "flavouring", "flavoring", - "formalised", "formalized", - "formalises", "formalizes", - "fossilised", "fossilized", - "fossilises", "fossilizes", - "fraternise", "fraternize", - "fulfilment", "fulfillment", - "funnelling", "funneling", - "galvanised", "galvanized", - "galvanises", "galvanizes", - "gambolling", "gamboling", - "gaolbreaks", "jailbreaks", - "generalise", "generalize", - "ghettoised", "ghettoized", - "ghettoises", "ghettoizes", - "globalised", "globalized", - "globalises", "globalizes", - "gonorrhoea", "gonorrhea", - "grovelling", "groveling", - "harbouring", "harboring", - "harmonised", "harmonized", - "harmonises", "harmonizes", - "homoeopath", "homeopath", - "homogenise", "homogenize", - "honourable", "honorable", - "honourably", "honorably", - "humanising", "humanizing", - "humourless", "humorless", - "hybridised", "hybridized", - "hybridises", "hybridizes", - "hypnotised", "hypnotized", - "hypnotises", "hypnotizes", - "idealising", "idealizing", - "immobilise", "immobilize", - "immunising", "immunizing", - "impanelled", "impaneled", - "imperilled", "imperiled", - "inflexions", "inflections", - "initialise", "initialize", - "initialled", "initialed", - "instalment", "installment", - "ionisation", "ionization", - "italicised", "italicized", - "italicises", "italicizes", - "jeopardise", "jeopardize", - "kilogramme", "kilogram", - "kilometres", "kilometers", - "lacklustre", "lackluster", - "legalising", "legalizing", - "legitimise", "legitimize", - "liberalise", "liberalize", - "liquidised", "liquidized", - "liquidiser", "liquidizer", - "liquidises", "liquidizes", - "localising", "localizing", - "magnetised", "magnetized", - "magnetises", "magnetizes", - "manoeuvred", "maneuvered", - "manoeuvres", "maneuvers", - "marshalled", "marshaled", - "marvelling", "marveling", - "marvellous", "marvelous", - "maximising", "maximizing", - "mechanised", "mechanized", - "mechanises", "mechanizes", - "memorising", "memorizing", - "mesmerised", "mesmerized", - "mesmerises", "mesmerizes", - "metabolise", "metabolize", - "micrometre", "micrometer", - "militarise", "militarize", - "millilitre", "milliliter", - "millimetre", "millimeter", - "minimising", "minimizing", - "mobilising", "mobilizing", - "modernised", "modernized", - "modernises", "modernizes", - "moisturise", "moisturize", - "monopolise", "monopolize", - "moralising", "moralizing", - "mouldering", "moldering", - "moustached", "mustached", - "moustaches", "mustaches", - "naturalise", "naturalize", - "neighbours", "neighbors", - "neutralise", "neutralize", - "normalised", "normalized", - "normalises", "normalizes", - "oesophagus", "esophagus", - "optimising", "optimizing", - "organisers", "organizers", - "organising", "organizing", - "ostracised", "ostracized", - "ostracises", "ostracizes", - "paederasts", "pederasts", - "paediatric", "pediatric", - "paedophile", "pedophile", - "panellists", "panelists", - "paralysing", "paralyzing", - "parcelling", "parceling", - "passivised", "passivized", - "passivises", "passivizes", - "pasteurise", "pasteurize", - "patronised", "patronized", - "patronises", "patronizes", - "penalising", "penalizing", - "pencilling", "penciling", - "plagiarise", "plagiarize", - "polarising", "polarizing", - "politicise", "politicize", - "popularise", "popularize", - "practising", "practicing", - "praesidium", "presidium", - "pressurise", "pressurize", - "prioritise", "prioritize", - "privatised", "privatized", - "privatises", "privatizes", - "programmes", "programs", - "publicised", "publicized", - "publicises", "publicizes", - "pulverised", "pulverized", - "pulverises", "pulverizes", - "pummelling", "pummeled", - "quarrelled", "quarreled", - "radicalise", "radicalize", - "randomised", "randomized", - "randomises", "randomizes", - "realisable", "realizable", - "recognised", "recognized", - "recognises", "recognizes", - "refuelling", "refueling", - "regularise", "regularize", - "remodelled", "remodeled", - "remoulding", "remolding", - "reorganise", "reorganize", - "revitalise", "revitalize", - "rhapsodise", "rhapsodize", - "ritualised", "ritualized", - "sanitising", "sanitizing", - "satirising", "satirizing", - "scandalise", "scandalize", - "scepticism", "skepticism", - "scrutinise", "scrutinize", - "secularise", "secularize", - "sensitised", "sensitized", - "sensitises", "sensitizes", - "sepulchres", "sepulchers", - "serialised", "serialized", - "serialises", "serializes", - "sermonised", "sermonized", - "sermonises", "sermonizes", - "shovelling", "shoveling", - "shrivelled", "shriveled", - "signalised", "signalized", - "signalises", "signalizes", - "signalling", "signaling", - "snivelling", "sniveling", - "snorkelled", "snorkeled", - "snowplough", "snowplow", - "socialised", "socialized", - "socialises", "socializes", - "sodomising", "sodomizing", - "solemnised", "solemnized", - "solemnises", "solemnizes", - "specialise", "specialize", - "spiralling", "spiraling", - "splendours", "splendors", - "stabilised", "stabilized", - "stabiliser", "stabilizer", - "stabilises", "stabilizes", - "stencilled", "stenciled", - "sterilised", "sterilized", - "steriliser", "sterilizer", - "sterilises", "sterilizes", - "stigmatise", "stigmatize", - "subsidised", "subsidized", - "subsidiser", "subsidizer", - "subsidises", "subsidizes", - "succouring", "succoring", - "sulphurous", "sulfurous", - "summarised", "summarized", - "summarises", "summarizes", - "swivelling", "swiveling", - "symbolised", "symbolized", - "symbolises", "symbolizes", - "sympathise", "sympathize", - "synthesise", "synthesize", - "tantalised", "tantalized", - "tantalises", "tantalizes", - "temporised", "temporized", - "temporises", "temporizes", - "tenderised", "tenderized", - "tenderises", "tenderizes", - "terrorised", "terrorized", - "terrorises", "terrorizes", - "theorising", "theorizing", - "traumatise", "traumatize", - "travellers", "travelers", - "travelling", "traveling", - "tricolours", "tricolors", - "trivialise", "trivialize", - "tunnelling", "tunneling", - "tyrannised", "tyrannized", - "tyrannises", "tyrannizes", - "unequalled", "unequaled", - "unionising", "unionizing", - "unravelled", "unraveled", - "unrivalled", "unrivaled", - "urbanising", "urbanizing", - "utilisable", "utilizable", - "vandalised", "vandalized", - "vandalises", "vandalizes", - "vaporising", "vaporizing", - "verbalised", "verbalized", - "verbalises", "verbalizes", - "victimised", "victimized", - "victimises", "victimizes", - "visualised", "visualized", - "visualises", "visualizes", - "vocalising", "vocalizing", - "vulcanised", "vulcanized", - "vulgarised", "vulgarized", - "vulgarises", "vulgarizes", - "weaselling", "weaseling", - "westernise", "westernize", - "womanisers", "womanizers", - "womanising", "womanizing", - "worshipped", "worshiped", - "worshipper", "worshiper", - "aeroplane", "airplane", - "aetiology", "etiology", - "agonising", "agonizing", - "almanacks", "almanacs", - "aluminium", "aluminum", - "amortised", "amortized", - "amortises", "amortizes", - "analogues", "analogs", - "analysing", "analyzing", - "anglicise", "anglicize", - "apologise", "apologize", - "appetiser", "appetizer", - "armourers", "armorers", - "armouries", "armories", - "artefacts", "artifacts", - "authorise", "authorize", - "baptising", "baptizing", - "behaviour", "behavior", - "belabours", "belabors", - "brutalise", "brutalize", - "callipers", "calipers", - "canalised", "canalized", - "canalises", "canalizes", - "cancelled", "canceled", - "canonised", "canonized", - "canonises", "canonizes", - "carbonise", "carbonize", - "carolling", "caroling", - "catalogue", "catalog", - "catalysed", "catalyzed", - "catalyses", "catalyzes", - "cauterise", "cauterize", - "cavilling", "caviling", - "chequered", "checkered", - "chiselled", "chiseled", - "civilised", "civilized", - "civilises", "civilizes", - "clamoured", "clamored", - "colonised", "colonized", - "coloniser", "colonizer", - "colonises", "colonizes", - "colourant", "colorant", - "coloureds", "coloreds", - "colourful", "colorful", - "colouring", "coloring", - "colourize", "colorize", - "connexion", "connection", - "criticise", "criticize", - "cruellest", "cruelest", - "cudgelled", "cudgeled", - "customise", "customize", - "demeanour", "demeanor", - "demonised", "demonized", - "demonises", "demonizes", - "deodorise", "deodorize", - "deputised", "deputized", - "deputises", "deputizes", - "dialogues", "dialogs", - "diarrhoea", "diarrhea", - "digitised", "digitized", - "digitises", "digitizes", - "discolour", "discolor", - "disfavour", "disfavor", - "dishonour", "dishonor", - "dramatise", "dramatize", - "drivelled", "driveled", - "economise", "economize", - "empathise", "empathize", - "emphasise", "emphasize", - "enamelled", "enameled", - "enamoured", "enamored", - "endeavour", "endeavor", - "energised", "energized", - "energises", "energizes", - "epaulette", "epaulet", - "epicentre", "epicenter", - "epitomise", "epitomize", - "equalised", "equalized", - "equaliser", "equalizer", - "equalises", "equalizes", - "eulogised", "eulogized", - "eulogises", "eulogizes", - "factorise", "factorize", - "fantasise", "fantasize", - "favouring", "favoring", - "favourite", "favorite", - "feminised", "feminized", - "feminises", "feminizes", - "fertilise", "fertilize", - "finalised", "finalized", - "finalises", "finalizes", - "flautists", "flutists", - "flavoured", "flavored", - "formalise", "formalize", - "fossilise", "fossilize", - "funnelled", "funneled", - "galvanise", "galvanize", - "gambolled", "gamboled", - "gaolbirds", "jailbirds", - "gaolbreak", "jailbreak", - "ghettoise", "ghettoize", - "globalise", "globalize", - "gravelled", "graveled", - "grovelled", "groveled", - "gruelling", "grueling", - "harboured", "harbored", - "harmonise", "harmonize", - "honouring", "honoring", - "humanised", "humanized", - "humanises", "humanizes", - "humouring", "humoring", - "hybridise", "hybridize", - "hypnotise", "hypnotize", - "idealised", "idealized", - "idealises", "idealizes", - "idolising", "idolizing", - "immunised", "immunized", - "immunises", "immunizes", - "inflexion", "inflection", - "italicise", "italicize", - "itemising", "itemizing", - "jewellers", "jewelers", - "jewellery", "jewelry", - "kilometre", "kilometer", - "labelling", "labeling", - "labourers", "laborers", - "labouring", "laboring", - "legalised", "legalized", - "legalises", "legalizes", - "leukaemia", "leukemia", - "levellers", "levelers", - "levelling", "leveling", - "libelling", "libeling", - "libellous", "libelous", - "licencing", "licensing", - "lionising", "lionizing", - "liquidise", "liquidize", - "localised", "localized", - "localises", "localizes", - "magnetise", "magnetize", - "manoeuvre", "maneuver", - "marvelled", "marveled", - "maximised", "maximized", - "maximises", "maximizes", - "mechanise", "mechanize", - "mediaeval", "medieval", - "memorised", "memorized", - "memorises", "memorizes", - "mesmerise", "mesmerize", - "minimised", "minimized", - "minimises", "minimizes", - "mobilised", "mobilized", - "mobilises", "mobilizes", - "modellers", "modelers", - "modelling", "modeling", - "modernise", "modernize", - "moralised", "moralized", - "moralises", "moralizes", - "motorised", "motorized", - "mouldered", "moldered", - "mouldiest", "moldiest", - "mouldings", "moldings", - "moustache", "mustache", - "neighbour", "neighbor", - "normalise", "normalize", - "odourless", "odorless", - "oestrogen", "estrogen", - "optimised", "optimized", - "optimises", "optimizes", - "organised", "organized", - "organiser", "organizer", - "organises", "organizes", - "ostracise", "ostracize", - "oxidising", "oxidizing", - "paederast", "pederast", - "panelling", "paneling", - "panellist", "panelist", - "paralysed", "paralyzed", - "paralyses", "paralyzes", - "parcelled", "parceled", - "passivise", "passivize", - "patronise", "patronize", - "pedalling", "pedaling", - "penalised", "penalized", - "penalises", "penalizes", - "pencilled", "penciled", - "ploughing", "plowing", - "ploughman", "plowman", - "ploughmen", "plowmen", - "polarised", "polarized", - "polarises", "polarizes", - "practised", "practiced", - "practises", "practices", - "pretences", "pretenses", - "primaeval", "primeval", - "privatise", "privatize", - "programme", "program", - "publicise", "publicize", - "pulverise", "pulverize", - "pummelled", "pummel", - "randomise", "randomize", - "ravelling", "raveling", - "realising", "realizing", - "recognise", "recognize", - "refuelled", "refueled", - "remoulded", "remolded", - "revellers", "revelers", - "revelling", "reveling", - "rivalling", "rivaling", - "saltpetre", "saltpeter", - "sanitised", "sanitized", - "sanitises", "sanitizes", - "satirised", "satirized", - "satirises", "satirizes", - "savouries", "savories", - "savouring", "savoring", - "sceptical", "skeptical", - "sensitise", "sensitize", - "sepulchre", "sepulcher", - "serialise", "serialize", - "sermonise", "sermonize", - "shovelled", "shoveled", - "signalise", "signalize", - "signalled", "signaled", - "snivelled", "sniveled", - "socialise", "socialize", - "sodomised", "sodomized", - "sodomises", "sodomizes", - "solemnise", "solemnize", - "spiralled", "spiraled", - "splendour", "splendor", - "stabilise", "stabilize", - "sterilise", "sterilize", - "subsidise", "subsidize", - "succoured", "succored", - "sulphates", "sulfates", - "sulphides", "sulfides", - "summarise", "summarize", - "swivelled", "swiveled", - "symbolise", "symbolize", - "syphoning", "siphoning", - "tantalise", "tantalize", - "tasselled", "tasseled", - "temporise", "temporize", - "tenderise", "tenderize", - "terrorise", "terrorize", - "theorised", "theorized", - "theorises", "theorizes", - "towelling", "toweling", - "travelled", "traveled", - "traveller", "traveler", - "trialling", "trialing", - "tricolour", "tricolor", - "tunnelled", "tunneled", - "tyrannise", "tyrannize", - "unionised", "unionized", - "unionises", "unionizes", - "unsavoury", "unsavory", - "urbanised", "urbanized", - "urbanises", "urbanizes", - "utilising", "utilizing", - "vandalise", "vandalize", - "vaporised", "vaporized", - "vaporises", "vaporizes", - "verbalise", "verbalize", - "victimise", "victimize", - "visualise", "visualize", - "vocalised", "vocalized", - "vocalises", "vocalizes", - "vulgarise", "vulgarize", - "weaselled", "weaseled", - "womanised", "womanized", - "womaniser", "womanizer", - "womanises", "womanizes", - "yodelling", "yodeling", - "yoghourts", "yogurts", - "agonised", "agonized", - "agonises", "agonizes", - "almanack", "almanac", - "amortise", "amortize", - "analogue", "analog", - "analysed", "analyzed", - "analyses", "analyzes", - "armoured", "armored", - "armourer", "armorer", - "artefact", "artifact", - "baptised", "baptized", - "baptises", "baptizes", - "baulking", "balking", - "belabour", "belabor", - "bevelled", "beveled", - "calibres", "calibers", - "calliper", "caliper", - "canalise", "canalize", - "canonise", "canonize", - "carolled", "caroled", - "catalyse", "catalyze", - "cavilled", "caviled", - "civilise", "civilize", - "clamours", "clamors", - "clangour", "clangor", - "colonise", "colonize", - "coloured", "colored", - "cosiness", "coziness", - "crueller", "crueler", - "defences", "defenses", - "demonise", "demonize", - "deputise", "deputize", - "dialling", "dialing", - "dialogue", "dialog", - "digitise", "digitize", - "draughty", "drafty", - "duelling", "dueling", - "energise", "energize", - "enthrals", "enthralls", - "equalise", "equalize", - "eulogise", "eulogize", - "favoured", "favored", - "feminise", "feminize", - "finalise", "finalize", - "flautist", "flutist", - "flavours", "flavors", - "foetuses", "fetuses", - "fuelling", "fueling", - "gaolbird", "jailbird", - "gryphons", "griffins", - "harbours", "harbors", - "honoured", "honored", - "humanise", "humanize", - "humoured", "humored", - "idealise", "idealize", - "idolised", "idolized", - "idolises", "idolizes", - "immunise", "immunize", - "ionisers", "ionizers", - "ionising", "ionizing", - "itemised", "itemized", - "itemises", "itemizes", - "jewelled", "jeweled", - "jeweller", "jeweler", - "labelled", "labeled", - "laboured", "labored", - "labourer", "laborer", - "legalise", "legalize", - "levelled", "leveled", - "leveller", "leveler", - "libelled", "libeled", - "licenced", "licensed", - "licences", "licenses", - "lionised", "lionized", - "lionises", "lionizes", - "localise", "localize", - "maximise", "maximize", - "memorise", "memorize", - "minimise", "minimize", - "misspelt", "misspelled", - "mobilise", "mobilize", - "modelled", "modeled", - "modeller", "modeler", - "moralise", "moralize", - "moulders", "molders", - "mouldier", "moldier", - "moulding", "molding", - "moulting", "molting", - "offences", "offenses", - "optimise", "optimize", - "organise", "organize", - "oxidised", "oxidized", - "oxidises", "oxidizes", - "panelled", "paneled", - "paralyse", "paralyze", - "parlours", "parlors", - "pedalled", "pedaled", - "penalise", "penalize", - "philtres", "filters", - "ploughed", "plowed", - "polarise", "polarize", - "practise", "practice", - "pretence", "pretense", - "ravelled", "raveled", - "realised", "realized", - "realises", "realizes", - "remoulds", "remolds", - "revelled", "reveled", - "reveller", "reveler", - "rivalled", "rivaled", - "rumoured", "rumored", - "sanitise", "sanitize", - "satirise", "satirize", - "saviours", "saviors", - "savoured", "savored", - "sceptics", "skeptics", - "sceptres", "scepters", - "sodomise", "sodomize", - "spectres", "specters", - "succours", "succors", - "sulphate", "sulfate", - "sulphide", "sulfide", - "syphoned", "siphoned", - "theatres", "theaters", - "theorise", "theorize", - "towelled", "toweled", - "toxaemia", "toxemia", - "trialled", "trialed", - "unionise", "unionize", - "urbanise", "urbanize", - "utilised", "utilized", - "utilises", "utilizes", - "vaporise", "vaporize", - "vocalise", "vocalize", - "womanise", "womanize", - "yodelled", "yodeled", - "yoghourt", "yogurt", - "yoghurts", "yogurts", - "agonise", "agonize", - "anaemia", "anemia", - "anaemic", "anemic", - "analyse", "analyze", - "arbours", "arbors", - "armoury", "armory", - "baptise", "baptize", - "baulked", "balked", - "behoved", "behooved", - "behoves", "behooves", - "calibre", "caliber", - "candour", "candor", - "centred", "centered", - "centres", "centers", - "cheques", "checks", - "clamour", "clamor", - "colours", "colors", - "cosiest", "coziest", - "defence", "defense", - "dialled", "dialed", - "distils", "distills", - "duelled", "dueled", - "enthral", "enthrall", - "favours", "favors", - "fervour", "fervor", - "flavour", "flavor", - "fuelled", "fueled", - "fulfils", "fulfills", - "gaolers", "jailers", - "gaoling", "jailing", - "gipsies", "gypsies", - "glueing", "gluing", - "goitres", "goiters", - "grammes", "grams", - "groynes", "groins", - "gryphon", "griffin", - "harbour", "harbor", - "honours", "honors", - "humours", "humors", - "idolise", "idolize", - "instals", "installs", - "instils", "instills", - "ionised", "ionized", - "ioniser", "ionizer", - "ionises", "ionizes", - "itemise", "itemize", - "labours", "labors", - "licence", "license", - "lionise", "lionize", - "louvred", "louvered", - "louvres", "louvers", - "moulded", "molded", - "moulder", "molder", - "moulted", "molted", - "offence", "offense", - "oxidise", "oxidize", - "parlour", "parlor", - "philtre", "filter", - "ploughs", "plows", - "pyjamas", "pajamas", - "rancour", "rancor", - "realise", "realize", - "remould", "remold", - "rigours", "rigors", - "rumours", "rumors", - "saviour", "savior", - "savours", "savors", - "savoury", "savory", - "sceptic", "skeptic", - "sceptre", "scepter", - "spectre", "specter", - "storeys", "stories", - "succour", "succor", - "sulphur", "sulfur", - "syphons", "siphons", - "theatre", "theater", - "tumours", "tumors", - "utilise", "utilize", - "vapours", "vapors", - "waggons", "wagons", - "yoghurt", "yogurt", - "ageing", "aging", - "appals", "appalls", - "arbour", "arbor", - "ardour", "ardor", - "baulks", "balks", - "behove", "behoove", - "centre", "center", - "cheque", "check", - "chilli", "chili", - "colour", "color", - "cosier", "cozier", - "cosies", "cozies", - "cosily", "cozily", - "distil", "distill", - "edoema", "edema", - "enrols", "enrolls", - "faecal", "fecal", - "faeces", "feces", - "favour", "favor", - "fibres", "fibers", - "foetal", "fetal", - "foetid", "fetid", - "foetus", "fetus", - "fulfil", "fulfill", - "gaoled", "jailed", - "gaoler", "jailer", - "goitre", "goiter", - "gramme", "gram", - "groyne", "groin", - "honour", "honor", - "humour", "humor", - "instal", "install", - "instil", "instill", - "ionise", "ionize", - "labour", "labor", - "litres", "liters", - "lustre", "luster", - "meagre", "meager", - "metres", "meters", - "mitres", "miters", - "moulds", "molds", - "mouldy", "moldy", - "moults", "molts", - "odours", "odors", - "plough", "plow", - "pyjama", "pajama", - "rigour", "rigor", - "rumour", "rumor", - "savour", "savor", - "storey", "story", - "syphon", "siphon", - "tumour", "tumor", - "valour", "valor", - "vapour", "vapor", - "vigour", "vigor", - "waggon", "wagon", - "appal", "appall", - "baulk", "balk", - "enrol", "enroll", - "fibre", "fiber", - "gaols", "jails", - "litre", "liter", - "metre", "meter", - "mitre", "miter", - "mould", "mold", - "moult", "molt", - "odour", "odor", - "tyres", "tires", - "cosy", "cozy", - "gaol", "jail", - "tyre", "tire", -} - -// DictBritish converts US spellings to UK spellings -var DictBritish = []string{ - "institutionalization", "institutionalisation", - "internationalization", "internationalisation", - "professionalization", "professionalisation", - "compartmentalizing", "compartmentalising", - "institutionalizing", "institutionalising", - "internationalizing", "internationalising", - "compartmentalized", "compartmentalised", - "compartmentalizes", "compartmentalises", - "decriminalization", "decriminalisation", - "denationalization", "denationalisation", - "fictionalizations", "fictionalisations", - "institutionalized", "institutionalised", - "institutionalizes", "institutionalises", - "intellectualizing", "intellectualising", - "internationalized", "internationalised", - "internationalizes", "internationalises", - "pedestrianization", "pedestrianisation", - "professionalizing", "professionalising", - "compartmentalize", "compartmentalise", - "decentralization", "decentralisation", - "demilitarization", "demilitarisation", - "externalizations", "externalisations", - "fictionalization", "fictionalisation", - "institutionalize", "institutionalise", - "intellectualized", "intellectualised", - "intellectualizes", "intellectualises", - "internationalize", "internationalise", - "nationalizations", "nationalisations", - "professionalized", "professionalised", - "professionalizes", "professionalises", - "rationalizations", "rationalisations", - "sensationalizing", "sensationalising", - "sentimentalizing", "sentimentalising", - "acclimatization", "acclimatisation", - "commercializing", "commercialising", - "conceptualizing", "conceptualising", - "contextualizing", "contextualising", - "crystallization", "crystallisation", - "decriminalizing", "decriminalising", - "democratization", "democratisation", - "denationalizing", "denationalising", - "depersonalizing", "depersonalising", - "desensitization", "desensitisation", - "disorganization", "disorganisation", - "extemporization", "extemporisation", - "externalization", "externalisation", - "familiarization", "familiarisation", - "generalizations", "generalisations", - "hospitalization", "hospitalisation", - "individualizing", "individualising", - "industrializing", "industrialising", - "intellectualize", "intellectualise", - "internalization", "internalisation", - "maneuverability", "manoeuvrability", - "materialization", "materialisation", - "miniaturization", "miniaturisation", - "nationalization", "nationalisation", - "overemphasizing", "overemphasising", - "paleontologists", "palaeontologists", - "particularizing", "particularising", - "pedestrianizing", "pedestrianising", - "professionalize", "professionalise", - "psychoanalyzing", "psychoanalysing", - "rationalization", "rationalisation", - "reorganizations", "reorganisations", - "revolutionizing", "revolutionising", - "sensationalized", "sensationalised", - "sensationalizes", "sensationalises", - "sentimentalized", "sentimentalised", - "sentimentalizes", "sentimentalises", - "specializations", "specialisations", - "standardization", "standardisation", - "synchronization", "synchronisation", - "systematization", "systematisation", - "aggrandizement", "aggrandisement", - "characterizing", "characterising", - "collectivizing", "collectivising", - "commercialized", "commercialised", - "commercializes", "commercialises", - "conceptualized", "conceptualised", - "conceptualizes", "conceptualises", - "contextualized", "contextualised", - "contextualizes", "contextualises", - "decentralizing", "decentralising", - "decriminalized", "decriminalised", - "decriminalizes", "decriminalises", - "dehumanization", "dehumanisation", - "demilitarizing", "demilitarising", - "demobilization", "demobilisation", - "demoralization", "demoralisation", - "denationalized", "denationalised", - "denationalizes", "denationalises", - "depersonalized", "depersonalised", - "depersonalizes", "depersonalises", - "dramatizations", "dramatisations", - "editorializing", "editorialising", - "fictionalizing", "fictionalising", - "fraternization", "fraternisation", - "generalization", "generalisation", - "immobilization", "immobilisation", - "individualized", "individualised", - "individualizes", "individualises", - "industrialized", "industrialised", - "industrializes", "industrialises", - "liberalization", "liberalisation", - "monopolization", "monopolisation", - "naturalization", "naturalisation", - "neighborliness", "neighbourliness", - "neutralization", "neutralisation", - "organizational", "organisational", - "outmaneuvering", "outmanoeuvring", - "overemphasized", "overemphasised", - "overemphasizes", "overemphasises", - "paleontologist", "palaeontologist", - "particularized", "particularised", - "particularizes", "particularises", - "pasteurization", "pasteurisation", - "pedestrianized", "pedestrianised", - "pedestrianizes", "pedestrianises", - "philosophizing", "philosophising", - "politicization", "politicisation", - "popularization", "popularisation", - "pressurization", "pressurisation", - "prioritization", "prioritisation", - "privatizations", "privatisations", - "propagandizing", "propagandising", - "psychoanalyzed", "psychoanalysed", - "psychoanalyzes", "psychoanalyses", - "reconnoitering", "reconnoitring", - "regularization", "regularisation", - "reorganization", "reorganisation", - "revolutionized", "revolutionised", - "revolutionizes", "revolutionises", - "secularization", "secularisation", - "sensationalize", "sensationalise", - "sentimentalize", "sentimentalise", - "serializations", "serialisations", - "specialization", "specialisation", - "sterilizations", "sterilisations", - "stigmatization", "stigmatisation", - "transistorized", "transistorised", - "unrecognizable", "unrecognisable", - "visualizations", "visualisations", - "westernization", "westernisation", - "accessorizing", "accessorising", - "acclimatizing", "acclimatising", - "amortizations", "amortisations", - "amphitheaters", "amphitheatres", - "anesthetizing", "anaesthetising", - "archeologists", "archaeologists", - "breathalyzers", "breathalysers", - "breathalyzing", "breathalysing", - "cannibalizing", "cannibalising", - "characterized", "characterised", - "characterizes", "characterises", - "circularizing", "circularising", - "collectivized", "collectivised", - "collectivizes", "collectivises", - "commercialize", "commercialise", - "computerizing", "computerising", - "conceptualize", "conceptualise", - "contextualize", "contextualise", - "criminalizing", "criminalising", - "crystallizing", "crystallising", - "decentralized", "decentralised", - "decentralizes", "decentralises", - "decriminalize", "decriminalise", - "demilitarized", "demilitarised", - "demilitarizes", "demilitarises", - "democratizing", "democratising", - "denationalize", "denationalise", - "depersonalize", "depersonalise", - "desensitizing", "desensitising", - "destabilizing", "destabilising", - "disemboweling", "disembowelling", - "dramatization", "dramatisation", - "editorialized", "editorialised", - "editorializes", "editorialises", - "extemporizing", "extemporising", - "externalizing", "externalising", - "familiarizing", "familiarising", - "fertilization", "fertilisation", - "fictionalized", "fictionalised", - "fictionalizes", "fictionalises", - "formalization", "formalisation", - "fossilization", "fossilisation", - "globalization", "globalisation", - "gynecological", "gynaecological", - "gynecologists", "gynaecologists", - "harmonization", "harmonisation", - "hematological", "haematological", - "hematologists", "haematologists", - "hospitalizing", "hospitalising", - "hypothesizing", "hypothesising", - "immortalizing", "immortalising", - "individualize", "individualise", - "industrialize", "industrialise", - "internalizing", "internalising", - "marginalizing", "marginalising", - "materializing", "materialising", - "mechanization", "mechanisation", - "memorializing", "memorialising", - "miniaturizing", "miniaturising", - "nationalizing", "nationalising", - "neighborhoods", "neighbourhoods", - "normalization", "normalisation", - "organizations", "organisations", - "outmaneuvered", "outmanoeuvred", - "overemphasize", "overemphasise", - "particularize", "particularise", - "passivization", "passivisation", - "patronizingly", "patronisingly", - "pedestrianize", "pedestrianise", - "pediatricians", "paediatricians", - "personalizing", "personalising", - "philosophized", "philosophised", - "philosophizes", "philosophises", - "privatization", "privatisation", - "propagandized", "propagandised", - "propagandizes", "propagandises", - "proselytizers", "proselytisers", - "proselytizing", "proselytising", - "psychoanalyze", "psychoanalyse", - "pulverization", "pulverisation", - "rationalizing", "rationalising", - "reconnoitered", "reconnoitred", - "revolutionize", "revolutionise", - "romanticizing", "romanticising", - "serialization", "serialisation", - "socialization", "socialisation", - "standardizing", "standardising", - "sterilization", "sterilisation", - "subsidization", "subsidisation", - "synchronizing", "synchronising", - "systematizing", "systematising", - "tantalizingly", "tantalisingly", - "underutilized", "underutilised", - "victimization", "victimisation", - "visualization", "visualisation", - "vocalizations", "vocalisations", - "vulgarization", "vulgarisation", - "accessorized", "accessorised", - "accessorizes", "accessorises", - "acclimatized", "acclimatised", - "acclimatizes", "acclimatises", - "amortization", "amortisation", - "amphitheater", "amphitheatre", - "anesthetists", "anaesthetists", - "anesthetized", "anaesthetised", - "anesthetizes", "anaesthetises", - "antagonizing", "antagonising", - "appetizingly", "appetisingly", - "archeologist", "archaeologist", - "backpedaling", "backpedalling", - "bastardizing", "bastardising", - "behaviorists", "behaviourists", - "bowdlerizing", "bowdlerising", - "breathalyzed", "breathalysed", - "breathalyzes", "breathalyses", - "cannibalized", "cannibalised", - "cannibalizes", "cannibalises", - "capitalizing", "capitalising", - "caramelizing", "caramelising", - "categorizing", "categorising", - "centerpieces", "centrepieces", - "centralizing", "centralising", - "characterize", "characterise", - "circularized", "circularised", - "circularizes", "circularises", - "clarinetists", "clarinettists", - "collectivize", "collectivise", - "colonization", "colonisation", - "computerized", "computerised", - "computerizes", "computerises", - "criminalized", "criminalised", - "criminalizes", "criminalises", - "crystallized", "crystallised", - "crystallizes", "crystallises", - "decentralize", "decentralise", - "dehumanizing", "dehumanising", - "demilitarize", "demilitarise", - "demobilizing", "demobilising", - "democratized", "democratised", - "democratizes", "democratises", - "demoralizing", "demoralising", - "desensitized", "desensitised", - "desensitizes", "desensitises", - "destabilized", "destabilised", - "destabilizes", "destabilises", - "disemboweled", "disembowelled", - "dishonorable", "dishonourable", - "dishonorably", "dishonourably", - "disorganized", "disorganised", - "editorialize", "editorialise", - "equalization", "equalisation", - "evangelizing", "evangelising", - "extemporized", "extemporised", - "extemporizes", "extemporises", - "externalized", "externalised", - "externalizes", "externalises", - "familiarized", "familiarised", - "familiarizes", "familiarises", - "fictionalize", "fictionalise", - "finalization", "finalisation", - "fraternizing", "fraternising", - "generalizing", "generalising", - "gynecologist", "gynaecologist", - "hematologist", "haematologist", - "hemophiliacs", "haemophiliacs", - "hemorrhaging", "haemorrhaging", - "homogenizing", "homogenising", - "hospitalized", "hospitalised", - "hospitalizes", "hospitalises", - "hypothesized", "hypothesised", - "hypothesizes", "hypothesises", - "idealization", "idealisation", - "immobilizers", "immobilisers", - "immobilizing", "immobilising", - "immortalized", "immortalised", - "immortalizes", "immortalises", - "immunization", "immunisation", - "initializing", "initialising", - "installments", "instalments", - "internalized", "internalised", - "internalizes", "internalises", - "jeopardizing", "jeopardising", - "legalization", "legalisation", - "legitimizing", "legitimising", - "liberalizing", "liberalising", - "maneuverable", "manoeuvrable", - "maneuverings", "manoeuvrings", - "marginalized", "marginalised", - "marginalizes", "marginalises", - "materialized", "materialised", - "materializes", "materialises", - "maximization", "maximisation", - "memorialized", "memorialised", - "memorializes", "memorialises", - "metabolizing", "metabolising", - "militarizing", "militarising", - "miniaturized", "miniaturised", - "miniaturizes", "miniaturises", - "miscataloged", "miscatalogued", - "misdemeanors", "misdemeanours", - "mobilization", "mobilisation", - "moisturizers", "moisturisers", - "moisturizing", "moisturising", - "monopolizing", "monopolising", - "multicolored", "multicoloured", - "nationalized", "nationalised", - "nationalizes", "nationalises", - "naturalizing", "naturalising", - "neighborhood", "neighbourhood", - "neutralizing", "neutralising", - "organization", "organisation", - "outmaneuvers", "outmanoeuvres", - "paleontology", "palaeontology", - "pasteurizing", "pasteurising", - "pediatrician", "paediatrician", - "personalized", "personalised", - "personalizes", "personalises", - "philosophize", "philosophise", - "plagiarizing", "plagiarising", - "polarization", "polarisation", - "politicizing", "politicising", - "popularizing", "popularising", - "pressurizing", "pressurising", - "prioritizing", "prioritising", - "propagandize", "propagandise", - "proselytized", "proselytised", - "proselytizer", "proselytiser", - "proselytizes", "proselytises", - "radicalizing", "radicalising", - "rationalized", "rationalised", - "rationalizes", "rationalises", - "realizations", "realisations", - "recognizable", "recognisable", - "recognizably", "recognisably", - "recognizance", "recognisance", - "reconnoiters", "reconnoitres", - "regularizing", "regularising", - "reorganizing", "reorganising", - "revitalizing", "revitalising", - "rhapsodizing", "rhapsodising", - "romanticized", "romanticised", - "romanticizes", "romanticises", - "scandalizing", "scandalising", - "scrutinizing", "scrutinising", - "secularizing", "secularising", - "standardized", "standardised", - "standardizes", "standardises", - "stigmatizing", "stigmatising", - "sympathizers", "sympathisers", - "sympathizing", "sympathising", - "synchronized", "synchronised", - "synchronizes", "synchronises", - "synthesizing", "synthesising", - "systematized", "systematised", - "systematizes", "systematises", - "theatergoers", "theatregoers", - "traumatizing", "traumatising", - "trivializing", "trivialising", - "unauthorized", "unauthorised", - "unionization", "unionisation", - "unrecognized", "unrecognised", - "urbanization", "urbanisation", - "vaporization", "vaporisation", - "vocalization", "vocalisation", - "westernizing", "westernising", - "accessorize", "accessorise", - "acclimatize", "acclimatise", - "agonizingly", "agonisingly", - "amortizable", "amortisable", - "anesthetics", "anaesthetics", - "anesthetist", "anaesthetist", - "anesthetize", "anaesthetise", - "anglicizing", "anglicising", - "antagonized", "antagonised", - "antagonizes", "antagonises", - "apologizing", "apologising", - "backpedaled", "backpedalled", - "bastardized", "bastardised", - "bastardizes", "bastardises", - "behaviorism", "behaviourism", - "behaviorist", "behaviourist", - "bowdlerized", "bowdlerised", - "bowdlerizes", "bowdlerises", - "brutalizing", "brutalising", - "cannibalize", "cannibalise", - "capitalized", "capitalised", - "capitalizes", "capitalises", - "caramelized", "caramelised", - "caramelizes", "caramelises", - "carbonizing", "carbonising", - "categorized", "categorised", - "categorizes", "categorises", - "cauterizing", "cauterising", - "centerfolds", "centrefolds", - "centerpiece", "centrepiece", - "centiliters", "centilitres", - "centimeters", "centimetres", - "centralized", "centralised", - "centralizes", "centralises", - "circularize", "circularise", - "clarinetist", "clarinettist", - "computerize", "computerise", - "criminalize", "criminalise", - "criticizing", "criticising", - "crystallize", "crystallise", - "customizing", "customising", - "defenseless", "defenceless", - "dehumanized", "dehumanised", - "dehumanizes", "dehumanises", - "demobilized", "demobilised", - "demobilizes", "demobilises", - "democratize", "democratise", - "demoralized", "demoralised", - "demoralizes", "demoralises", - "deodorizing", "deodorising", - "desensitize", "desensitise", - "destabilize", "destabilise", - "discoloring", "discolouring", - "dishonoring", "dishonouring", - "dramatizing", "dramatising", - "economizing", "economising", - "empathizing", "empathising", - "emphasizing", "emphasising", - "endeavoring", "endeavouring", - "epitomizing", "epitomising", - "esophaguses", "oesophaguses", - "evangelized", "evangelised", - "evangelizes", "evangelises", - "extemporize", "extemporise", - "externalize", "externalise", - "factorizing", "factorising", - "familiarize", "familiarise", - "fantasizing", "fantasising", - "fertilizers", "fertilisers", - "fertilizing", "fertilising", - "formalizing", "formalising", - "fossilizing", "fossilising", - "fraternized", "fraternised", - "fraternizes", "fraternises", - "fulfillment", "fulfilment", - "galvanizing", "galvanising", - "generalized", "generalised", - "generalizes", "generalises", - "ghettoizing", "ghettoising", - "globalizing", "globalising", - "harmonizing", "harmonising", - "hemophiliac", "haemophiliac", - "hemorrhaged", "haemorrhaged", - "hemorrhages", "haemorrhages", - "hemorrhoids", "haemorrhoids", - "homogenized", "homogenised", - "homogenizes", "homogenises", - "hospitalize", "hospitalise", - "hybridizing", "hybridising", - "hypnotizing", "hypnotising", - "hypothesize", "hypothesise", - "immobilized", "immobilised", - "immobilizer", "immobiliser", - "immobilizes", "immobilises", - "immortalize", "immortalise", - "initialized", "initialised", - "initializes", "initialises", - "installment", "instalment", - "internalize", "internalise", - "italicizing", "italicising", - "jeopardized", "jeopardised", - "jeopardizes", "jeopardises", - "legitimized", "legitimised", - "legitimizes", "legitimises", - "liberalized", "liberalised", - "liberalizes", "liberalises", - "lionization", "lionisation", - "liquidizers", "liquidisers", - "liquidizing", "liquidising", - "magnetizing", "magnetising", - "maneuvering", "manoeuvring", - "marginalize", "marginalise", - "marvelously", "marvellously", - "materialize", "materialise", - "mechanizing", "mechanising", - "memorialize", "memorialise", - "mesmerizing", "mesmerising", - "metabolized", "metabolised", - "metabolizes", "metabolises", - "militarized", "militarised", - "militarizes", "militarises", - "milliliters", "millilitres", - "millimeters", "millimetres", - "miniaturize", "miniaturise", - "misbehavior", "misbehaviour", - "misdemeanor", "misdemeanour", - "modernizing", "modernising", - "moisturized", "moisturised", - "moisturizer", "moisturiser", - "moisturizes", "moisturises", - "monopolized", "monopolised", - "monopolizes", "monopolises", - "nationalize", "nationalise", - "naturalized", "naturalised", - "naturalizes", "naturalises", - "neighboring", "neighbouring", - "neutralized", "neutralised", - "neutralizes", "neutralises", - "normalizing", "normalising", - "orthopedics", "orthopaedics", - "ostracizing", "ostracising", - "outmaneuver", "outmanoeuvre", - "oxidization", "oxidisation", - "pasteurized", "pasteurised", - "pasteurizes", "pasteurises", - "patronizing", "patronising", - "personalize", "personalise", - "plagiarized", "plagiarised", - "plagiarizes", "plagiarises", - "politicized", "politicised", - "politicizes", "politicises", - "popularized", "popularised", - "popularizes", "popularises", - "pressurized", "pressurised", - "pressurizes", "pressurises", - "prioritized", "prioritised", - "prioritizes", "prioritises", - "privatizing", "privatising", - "proselytize", "proselytise", - "publicizing", "publicising", - "pulverizing", "pulverising", - "radicalized", "radicalised", - "radicalizes", "radicalises", - "randomizing", "randomising", - "rationalize", "rationalise", - "realization", "realisation", - "recognizing", "recognising", - "reconnoiter", "reconnoitre", - "regularized", "regularised", - "regularizes", "regularises", - "reorganized", "reorganised", - "reorganizes", "reorganises", - "revitalized", "revitalised", - "revitalizes", "revitalises", - "rhapsodized", "rhapsodised", - "rhapsodizes", "rhapsodises", - "romanticize", "romanticise", - "scandalized", "scandalised", - "scandalizes", "scandalises", - "scrutinized", "scrutinised", - "scrutinizes", "scrutinises", - "secularized", "secularised", - "secularizes", "secularises", - "sensitizing", "sensitising", - "serializing", "serialising", - "sermonizing", "sermonising", - "signalizing", "signalising", - "skeptically", "sceptically", - "socializing", "socialising", - "solemnizing", "solemnising", - "specialized", "specialised", - "specializes", "specialises", - "squirreling", "squirrelling", - "stabilizers", "stabilisers", - "stabilizing", "stabilising", - "standardize", "standardise", - "sterilizers", "sterilisers", - "sterilizing", "sterilising", - "stigmatized", "stigmatised", - "stigmatizes", "stigmatises", - "subsidizers", "subsidisers", - "subsidizing", "subsidising", - "summarizing", "summarising", - "symbolizing", "symbolising", - "sympathized", "sympathised", - "sympathizer", "sympathiser", - "sympathizes", "sympathises", - "synchronize", "synchronise", - "synthesized", "synthesised", - "synthesizes", "synthesises", - "systematize", "systematise", - "tantalizing", "tantalising", - "temporizing", "temporising", - "tenderizing", "tenderising", - "terrorizing", "terrorising", - "theatergoer", "theatregoer", - "traumatized", "traumatised", - "traumatizes", "traumatises", - "trivialized", "trivialised", - "trivializes", "trivialises", - "tyrannizing", "tyrannising", - "uncataloged", "uncatalogued", - "uncivilized", "uncivilised", - "unfavorable", "unfavourable", - "unfavorably", "unfavourably", - "unorganized", "unorganised", - "untrammeled", "untrammelled", - "utilization", "utilisation", - "vandalizing", "vandalising", - "verbalizing", "verbalising", - "victimizing", "victimising", - "visualizing", "visualising", - "vulgarizing", "vulgarising", - "watercolors", "watercolours", - "westernized", "westernised", - "westernizes", "westernises", - "amortizing", "amortising", - "anesthesia", "anaesthesia", - "anesthetic", "anaesthetic", - "anglicized", "anglicised", - "anglicizes", "anglicises", - "annualized", "annualised", - "antagonize", "antagonise", - "apologized", "apologised", - "apologizes", "apologises", - "appetizers", "appetisers", - "appetizing", "appetising", - "archeology", "archaeology", - "authorizes", "authorises", - "bastardize", "bastardise", - "bedeviling", "bedevilling", - "behavioral", "behavioural", - "belaboring", "belabouring", - "bowdlerize", "bowdlerise", - "brutalized", "brutalised", - "brutalizes", "brutalises", - "canalizing", "canalising", - "canonizing", "canonising", - "capitalize", "capitalise", - "caramelize", "caramelise", - "carbonized", "carbonised", - "carbonizes", "carbonises", - "cataloging", "cataloguing", - "catalyzing", "catalysing", - "categorize", "categorise", - "cauterized", "cauterised", - "cauterizes", "cauterises", - "centerfold", "centrefold", - "centiliter", "centilitre", - "centimeter", "centimetre", - "centralize", "centralise", - "channeling", "channelling", - "checkbooks", "chequebooks", - "civilizing", "civilising", - "colonizers", "colonisers", - "colonizing", "colonising", - "colorfully", "colourfully", - "colorizing", "colourizing", - "councilors", "councillors", - "counselors", "counsellors", - "criticized", "criticised", - "criticizes", "criticises", - "customized", "customised", - "customizes", "customises", - "dehumanize", "dehumanise", - "demobilize", "demobilise", - "demonizing", "demonising", - "demoralize", "demoralise", - "deodorized", "deodorised", - "deodorizes", "deodorises", - "deputizing", "deputising", - "digitizing", "digitising", - "discolored", "discoloured", - "disheveled", "dishevelled", - "dishonored", "dishonoured", - "dramatized", "dramatised", - "dramatizes", "dramatises", - "economized", "economised", - "economizes", "economises", - "empathized", "empathised", - "empathizes", "empathises", - "emphasized", "emphasised", - "emphasizes", "emphasises", - "endeavored", "endeavoured", - "energizing", "energising", - "epicenters", "epicentres", - "epitomized", "epitomised", - "epitomizes", "epitomises", - "equalizers", "equalisers", - "equalizing", "equalising", - "eulogizing", "eulogising", - "evangelize", "evangelise", - "factorized", "factorised", - "factorizes", "factorises", - "fantasized", "fantasised", - "fantasizes", "fantasises", - "favoritism", "favouritism", - "feminizing", "feminising", - "fertilized", "fertilised", - "fertilizer", "fertiliser", - "fertilizes", "fertilises", - "fiberglass", "fibreglass", - "finalizing", "finalising", - "flavorings", "flavourings", - "flavorless", "flavourless", - "flavorsome", "flavoursome", - "formalized", "formalised", - "formalizes", "formalises", - "fossilized", "fossilised", - "fossilizes", "fossilises", - "fraternize", "fraternise", - "galvanized", "galvanised", - "galvanizes", "galvanises", - "generalize", "generalise", - "ghettoized", "ghettoised", - "ghettoizes", "ghettoises", - "globalized", "globalised", - "globalizes", "globalises", - "gruelingly", "gruellingly", - "gynecology", "gynaecology", - "harmonized", "harmonised", - "harmonizes", "harmonises", - "hematology", "haematology", - "hemoglobin", "haemoglobin", - "hemophilia", "haemophilia", - "hemorrhage", "haemorrhage", - "homogenize", "homogenise", - "humanizing", "humanising", - "hybridized", "hybridised", - "hybridizes", "hybridises", - "hypnotized", "hypnotised", - "hypnotizes", "hypnotises", - "idealizing", "idealising", - "immobilize", "immobilise", - "immunizing", "immunising", - "impaneling", "impanelling", - "imperiling", "imperilling", - "initialing", "initialling", - "initialize", "initialise", - "ionization", "ionisation", - "italicized", "italicised", - "italicizes", "italicises", - "jeopardize", "jeopardise", - "kilometers", "kilometres", - "lackluster", "lacklustre", - "legalizing", "legalising", - "legitimize", "legitimise", - "liberalize", "liberalise", - "liquidized", "liquidised", - "liquidizer", "liquidiser", - "liquidizes", "liquidises", - "localizing", "localising", - "magnetized", "magnetised", - "magnetizes", "magnetises", - "maneuvered", "manoeuvred", - "marshaling", "marshalling", - "maximizing", "maximising", - "mechanized", "mechanised", - "mechanizes", "mechanises", - "memorizing", "memorising", - "mesmerized", "mesmerised", - "mesmerizes", "mesmerises", - "metabolize", "metabolise", - "militarize", "militarise", - "milliliter", "millilitre", - "millimeter", "millimetre", - "minimizing", "minimising", - "mobilizing", "mobilising", - "modernized", "modernised", - "modernizes", "modernises", - "moisturize", "moisturise", - "monopolize", "monopolise", - "moralizing", "moralising", - "naturalize", "naturalise", - "neighborly", "neighbourly", - "neutralize", "neutralise", - "normalized", "normalised", - "normalizes", "normalises", - "optimizing", "optimising", - "organizers", "organisers", - "organizing", "organising", - "orthopedic", "orthopaedic", - "ostracized", "ostracised", - "ostracizes", "ostracises", - "paralyzing", "paralysing", - "pasteurize", "pasteurise", - "patronized", "patronised", - "patronizes", "patronises", - "pedophiles", "paedophiles", - "pedophilia", "paedophilia", - "penalizing", "penalising", - "plagiarize", "plagiarise", - "plowshares", "ploughshares", - "polarizing", "polarising", - "politicize", "politicise", - "popularize", "popularise", - "prioritize", "prioritise", - "privatized", "privatised", - "privatizes", "privatises", - "publicized", "publicised", - "publicizes", "publicises", - "pulverized", "pulverised", - "pulverizes", "pulverises", - "quarreling", "quarrelling", - "radicalize", "radicalise", - "randomized", "randomised", - "randomizes", "randomises", - "realizable", "realisable", - "recognized", "recognised", - "recognizes", "recognises", - "regularize", "regularise", - "remodeling", "remodelling", - "reorganize", "reorganise", - "revitalize", "revitalise", - "rhapsodize", "rhapsodise", - "ritualized", "ritualised", - "sanitizing", "sanitising", - "satirizing", "satirising", - "scandalize", "scandalise", - "scrutinize", "scrutinise", - "secularize", "secularise", - "sensitized", "sensitised", - "sensitizes", "sensitises", - "sepulchers", "sepulchres", - "serialized", "serialised", - "serializes", "serialises", - "sermonized", "sermonised", - "sermonizes", "sermonises", - "shriveling", "shrivelling", - "signalized", "signalised", - "signalizes", "signalises", - "skepticism", "scepticism", - "socialized", "socialised", - "socializes", "socialises", - "sodomizing", "sodomising", - "solemnized", "solemnised", - "solemnizes", "solemnises", - "specialize", "specialise", - "squirreled", "squirrelled", - "stabilized", "stabilised", - "stabilizer", "stabiliser", - "stabilizes", "stabilises", - "stenciling", "stencilling", - "sterilized", "sterilised", - "sterilizer", "steriliser", - "sterilizes", "sterilises", - "stigmatize", "stigmatise", - "subsidized", "subsidised", - "subsidizer", "subsidiser", - "subsidizes", "subsidises", - "summarized", "summarised", - "summarizes", "summarises", - "symbolized", "symbolised", - "symbolizes", "symbolises", - "sympathize", "sympathise", - "tantalized", "tantalised", - "tantalizes", "tantalises", - "temporized", "temporised", - "temporizes", "temporises", - "tenderized", "tenderised", - "tenderizes", "tenderises", - "terrorized", "terrorised", - "terrorizes", "terrorises", - "theorizing", "theorising", - "traumatize", "traumatise", - "trivialize", "trivialise", - "tyrannized", "tyrannised", - "tyrannizes", "tyrannises", - "unionizing", "unionising", - "unraveling", "unravelling", - "urbanizing", "urbanising", - "utilizable", "utilisable", - "vandalized", "vandalised", - "vandalizes", "vandalises", - "vaporizing", "vaporising", - "verbalized", "verbalised", - "verbalizes", "verbalises", - "victimized", "victimised", - "victimizes", "victimises", - "visualized", "visualised", - "visualizes", "visualises", - "vocalizing", "vocalising", - "vulcanized", "vulcanised", - "vulgarized", "vulgarised", - "vulgarizes", "vulgarises", - "watercolor", "watercolour", - "westernize", "westernise", - "womanizers", "womanisers", - "womanizing", "womanising", - "worshiping", "worshipping", - "agonizing", "agonising", - "airplanes", "aeroplanes", - "amortized", "amortised", - "amortizes", "amortises", - "analyzing", "analysing", - "apologize", "apologise", - "appetizer", "appetiser", - "artifacts", "artefacts", - "baptizing", "baptising", - "bedeviled", "bedevilled", - "behaviors", "behaviours", - "bejeweled", "bejewelled", - "belabored", "belaboured", - "brutalize", "brutalise", - "canalized", "canalised", - "canalizes", "canalises", - "canonized", "canonised", - "canonizes", "canonises", - "carbonize", "carbonise", - "cataloged", "catalogued", - "catalyzed", "catalysed", - "catalyzes", "catalyses", - "cauterize", "cauterise", - "channeled", "channelled", - "checkbook", "chequebook", - "checkered", "chequered", - "chiseling", "chiselling", - "civilized", "civilised", - "civilizes", "civilises", - "clamoring", "clamouring", - "colonized", "colonised", - "colonizer", "coloniser", - "colonizes", "colonises", - "colorants", "colourants", - "colorized", "colourized", - "colorizes", "colourizes", - "colorless", "colourless", - "councilor", "councillor", - "counseled", "counselled", - "counselor", "counsellor", - "criticize", "criticise", - "cudgeling", "cudgelling", - "customize", "customise", - "demonized", "demonised", - "demonizes", "demonises", - "deodorize", "deodorise", - "deputized", "deputised", - "deputizes", "deputises", - "digitized", "digitised", - "digitizes", "digitises", - "discolors", "discolours", - "dishonors", "dishonours", - "dramatize", "dramatise", - "driveling", "drivelling", - "economize", "economise", - "empathize", "empathise", - "emphasize", "emphasise", - "enameling", "enamelling", - "endeavors", "endeavours", - "energized", "energised", - "energizes", "energises", - "enthralls", "enthrals", - "epicenter", "epicentre", - "epitomize", "epitomise", - "equalized", "equalised", - "equalizer", "equaliser", - "equalizes", "equalises", - "eulogized", "eulogised", - "eulogizes", "eulogises", - "factorize", "factorise", - "fantasize", "fantasise", - "favorable", "favourable", - "favorably", "favourably", - "favorites", "favourites", - "feminized", "feminised", - "feminizes", "feminises", - "fertilize", "fertilise", - "finalized", "finalised", - "finalizes", "finalises", - "flavoring", "flavouring", - "formalize", "formalise", - "fossilize", "fossilise", - "funneling", "funnelling", - "galvanize", "galvanise", - "gamboling", "gambolling", - "ghettoize", "ghettoise", - "globalize", "globalise", - "gonorrhea", "gonorrhoea", - "groveling", "grovelling", - "harboring", "harbouring", - "harmonize", "harmonise", - "honorably", "honourably", - "humanized", "humanised", - "humanizes", "humanises", - "hybridize", "hybridise", - "hypnotize", "hypnotise", - "idealized", "idealised", - "idealizes", "idealises", - "idolizing", "idolising", - "immunized", "immunised", - "immunizes", "immunises", - "impaneled", "impanelled", - "imperiled", "imperilled", - "initialed", "initialled", - "italicize", "italicise", - "itemizing", "itemising", - "kilometer", "kilometre", - "legalized", "legalised", - "legalizes", "legalises", - "lionizing", "lionising", - "liquidize", "liquidise", - "localized", "localised", - "localizes", "localises", - "magnetize", "magnetise", - "maneuvers", "manoeuvres", - "marshaled", "marshalled", - "marveling", "marvelling", - "marvelous", "marvellous", - "maximized", "maximised", - "maximizes", "maximises", - "mechanize", "mechanise", - "memorized", "memorised", - "memorizes", "memorises", - "mesmerize", "mesmerise", - "minimized", "minimised", - "minimizes", "minimises", - "mobilized", "mobilised", - "mobilizes", "mobilises", - "modernize", "modernise", - "moldering", "mouldering", - "moralized", "moralised", - "moralizes", "moralises", - "motorized", "motorised", - "mustached", "moustached", - "mustaches", "moustaches", - "neighbors", "neighbours", - "normalize", "normalise", - "optimized", "optimised", - "optimizes", "optimises", - "organized", "organised", - "organizer", "organiser", - "organizes", "organises", - "ostracize", "ostracise", - "oxidizing", "oxidising", - "panelists", "panellists", - "paralyzed", "paralysed", - "paralyzes", "paralyses", - "parceling", "parcelling", - "patronize", "patronise", - "pedophile", "paedophile", - "penalized", "penalised", - "penalizes", "penalises", - "penciling", "pencilling", - "plowshare", "ploughshare", - "polarized", "polarised", - "polarizes", "polarises", - "practiced", "practised", - "pretenses", "pretences", - "privatize", "privatise", - "publicize", "publicise", - "pulverize", "pulverise", - "quarreled", "quarrelled", - "randomize", "randomise", - "realizing", "realising", - "recognize", "recognise", - "refueling", "refuelling", - "remodeled", "remodelled", - "remolding", "remoulding", - "saltpeter", "saltpetre", - "sanitized", "sanitised", - "sanitizes", "sanitises", - "satirized", "satirised", - "satirizes", "satirises", - "sensitize", "sensitise", - "sepulcher", "sepulchre", - "serialize", "serialise", - "sermonize", "sermonise", - "shoveling", "shovelling", - "shriveled", "shrivelled", - "signaling", "signalling", - "signalize", "signalise", - "skeptical", "sceptical", - "sniveling", "snivelling", - "snorkeled", "snorkelled", - "socialize", "socialise", - "sodomized", "sodomised", - "sodomizes", "sodomises", - "solemnize", "solemnise", - "spiraling", "spiralling", - "splendors", "splendours", - "stabilize", "stabilise", - "stenciled", "stencilled", - "sterilize", "sterilise", - "subsidize", "subsidise", - "succoring", "succouring", - "sulfurous", "sulphurous", - "summarize", "summarise", - "swiveling", "swivelling", - "symbolize", "symbolise", - "tantalize", "tantalise", - "temporize", "temporise", - "tenderize", "tenderise", - "terrorize", "terrorise", - "theorized", "theorised", - "theorizes", "theorises", - "travelers", "travellers", - "traveling", "travelling", - "tricolors", "tricolours", - "tunneling", "tunnelling", - "tyrannize", "tyrannise", - "unequaled", "unequalled", - "unionized", "unionised", - "unionizes", "unionises", - "unraveled", "unravelled", - "unrivaled", "unrivalled", - "urbanized", "urbanised", - "urbanizes", "urbanises", - "utilizing", "utilising", - "vandalize", "vandalise", - "vaporized", "vaporised", - "vaporizes", "vaporises", - "verbalize", "verbalise", - "victimize", "victimise", - "visualize", "visualise", - "vocalized", "vocalised", - "vocalizes", "vocalises", - "vulgarize", "vulgarise", - "weaseling", "weaselling", - "womanized", "womanised", - "womanizer", "womaniser", - "womanizes", "womanises", - "worshiped", "worshipped", - "worshiper", "worshipper", - "agonized", "agonised", - "agonizes", "agonises", - "airplane", "aeroplane", - "aluminum", "aluminium", - "amortize", "amortise", - "analyzed", "analysed", - "analyzes", "analyses", - "armorers", "armourers", - "armories", "armouries", - "artifact", "artefact", - "baptized", "baptised", - "baptizes", "baptises", - "behavior", "behaviour", - "behooved", "behoved", - "behooves", "behoves", - "belabors", "belabours", - "calibers", "calibres", - "canalize", "canalise", - "canonize", "canonise", - "catalogs", "catalogues", - "catalyze", "catalyse", - "caviling", "cavilling", - "centered", "centred", - "chiseled", "chiselled", - "civilize", "civilise", - "clamored", "clamoured", - "colonize", "colonise", - "colorant", "colourant", - "coloreds", "coloureds", - "colorful", "colourful", - "coloring", "colouring", - "colorize", "colourize", - "coziness", "cosiness", - "cruelest", "cruellest", - "cudgeled", "cudgelled", - "defenses", "defences", - "demeanor", "demeanour", - "demonize", "demonise", - "deputize", "deputise", - "diarrhea", "diarrhoea", - "digitize", "digitise", - "disfavor", "disfavour", - "dishonor", "dishonour", - "distills", "distils", - "driveled", "drivelled", - "enameled", "enamelled", - "enamored", "enamoured", - "endeavor", "endeavour", - "energize", "energise", - "epaulets", "epaulettes", - "equalize", "equalise", - "estrogen", "oestrogen", - "etiology", "aetiology", - "eulogize", "eulogise", - "favoring", "favouring", - "favorite", "favourite", - "feminize", "feminise", - "finalize", "finalise", - "flavored", "flavoured", - "flutists", "flautists", - "fulfills", "fulfils", - "funneled", "funnelled", - "gamboled", "gambolled", - "graveled", "gravelled", - "groveled", "grovelled", - "grueling", "gruelling", - "harbored", "harboured", - "honoring", "honouring", - "humanize", "humanise", - "humoring", "humouring", - "idealize", "idealise", - "idolized", "idolised", - "idolizes", "idolises", - "immunize", "immunise", - "ionizing", "ionising", - "itemized", "itemised", - "itemizes", "itemises", - "jewelers", "jewellers", - "labeling", "labelling", - "laborers", "labourers", - "laboring", "labouring", - "legalize", "legalise", - "leukemia", "leukaemia", - "levelers", "levellers", - "leveling", "levelling", - "libeling", "libelling", - "libelous", "libellous", - "lionized", "lionised", - "lionizes", "lionises", - "localize", "localise", - "louvered", "louvred", - "maneuver", "manoeuvre", - "marveled", "marvelled", - "maximize", "maximise", - "memorize", "memorise", - "minimize", "minimise", - "mobilize", "mobilise", - "modelers", "modellers", - "modeling", "modelling", - "moldered", "mouldered", - "moldiest", "mouldiest", - "moldings", "mouldings", - "moralize", "moralise", - "mustache", "moustache", - "neighbor", "neighbour", - "odorless", "odourless", - "offenses", "offences", - "optimize", "optimise", - "organize", "organise", - "oxidized", "oxidised", - "oxidizes", "oxidises", - "paneling", "panelling", - "panelist", "panellist", - "paralyze", "paralyse", - "parceled", "parcelled", - "pedaling", "pedalling", - "penalize", "penalise", - "penciled", "pencilled", - "polarize", "polarise", - "pretense", "pretence", - "pummeled", "pummelling", - "raveling", "ravelling", - "realized", "realised", - "realizes", "realises", - "refueled", "refuelled", - "remolded", "remoulded", - "revelers", "revellers", - "reveling", "revelling", - "rivaling", "rivalling", - "sanitize", "sanitise", - "satirize", "satirise", - "savories", "savouries", - "savoring", "savouring", - "scepters", "sceptres", - "shoveled", "shovelled", - "signaled", "signalled", - "skeptics", "sceptics", - "sniveled", "snivelled", - "sodomize", "sodomise", - "specters", "spectres", - "spiraled", "spiralled", - "splendor", "splendour", - "succored", "succoured", - "sulfates", "sulphates", - "sulfides", "sulphides", - "swiveled", "swivelled", - "tasseled", "tasselled", - "theaters", "theatres", - "theorize", "theorise", - "toweling", "towelling", - "traveler", "traveller", - "trialing", "trialling", - "tricolor", "tricolour", - "tunneled", "tunnelled", - "unionize", "unionise", - "unsavory", "unsavoury", - "urbanize", "urbanise", - "utilized", "utilised", - "utilizes", "utilises", - "vaporize", "vaporise", - "vocalize", "vocalise", - "weaseled", "weaselled", - "womanize", "womanise", - "yodeling", "yodelling", - "agonize", "agonise", - "analyze", "analyse", - "appalls", "appals", - "armored", "armoured", - "armorer", "armourer", - "baptize", "baptise", - "behoove", "behove", - "belabor", "belabour", - "beveled", "bevelled", - "caliber", "calibre", - "caroled", "carolled", - "caviled", "cavilled", - "centers", "centres", - "clamors", "clamours", - "clangor", "clangour", - "colored", "coloured", - "coziest", "cosiest", - "crueler", "crueller", - "defense", "defence", - "dialing", "dialling", - "dialogs", "dialogues", - "distill", "distil", - "dueling", "duelling", - "enrolls", "enrols", - "epaulet", "epaulette", - "favored", "favoured", - "flavors", "flavours", - "flutist", "flautist", - "fueling", "fuelling", - "fulfill", "fulfil", - "goiters", "goitres", - "harbors", "harbours", - "honored", "honoured", - "humored", "humoured", - "idolize", "idolise", - "ionized", "ionised", - "ionizes", "ionises", - "itemize", "itemise", - "jeweled", "jewelled", - "jeweler", "jeweller", - "jewelry", "jewellery", - "labeled", "labelled", - "labored", "laboured", - "laborer", "labourer", - "leveled", "levelled", - "leveler", "leveller", - "libeled", "libelled", - "lionize", "lionise", - "louvers", "louvres", - "modeled", "modelled", - "modeler", "modeller", - "molders", "moulders", - "moldier", "mouldier", - "molding", "moulding", - "molting", "moulting", - "offense", "offence", - "oxidize", "oxidise", - "pajamas", "pyjamas", - "paneled", "panelled", - "parlors", "parlours", - "pedaled", "pedalled", - "plowing", "ploughing", - "plowman", "ploughman", - "plowmen", "ploughmen", - "realize", "realise", - "remolds", "remoulds", - "reveled", "revelled", - "reveler", "reveller", - "rivaled", "rivalled", - "rumored", "rumoured", - "saviors", "saviours", - "savored", "savoured", - "scepter", "sceptre", - "skeptic", "sceptic", - "specter", "spectre", - "succors", "succours", - "sulfate", "sulphate", - "sulfide", "sulphide", - "theater", "theatre", - "toweled", "towelled", - "toxemia", "toxaemia", - "trialed", "trialled", - "utilize", "utilise", - "yodeled", "yodelled", - "anemia", "anaemia", - "anemic", "anaemic", - "appall", "appal", - "arbors", "arbours", - "armory", "armoury", - "candor", "candour", - "center", "centre", - "clamor", "clamour", - "colors", "colours", - "cozier", "cosier", - "cozies", "cosies", - "cozily", "cosily", - "dialed", "dialled", - "drafty", "draughty", - "dueled", "duelled", - "favors", "favours", - "fervor", "fervour", - "fibers", "fibres", - "flavor", "flavour", - "fueled", "fuelled", - "goiter", "goitre", - "harbor", "harbour", - "honors", "honours", - "humors", "humours", - "labors", "labours", - "liters", "litres", - "louver", "louvre", - "luster", "lustre", - "meager", "meagre", - "miters", "mitres", - "molded", "moulded", - "molder", "moulder", - "molted", "moulted", - "pajama", "pyjama", - "parlor", "parlour", - "plowed", "ploughed", - "rancor", "rancour", - "remold", "remould", - "rigors", "rigours", - "rumors", "rumours", - "savors", "savours", - "savory", "savoury", - "succor", "succour", - "tumors", "tumours", - "vapors", "vapours", - "aging", "ageing", - "arbor", "arbour", - "ardor", "ardour", - "armor", "armour", - "chili", "chilli", - "color", "colour", - "edema", "edoema", - "favor", "favour", - "fecal", "faecal", - "feces", "faeces", - "fiber", "fibre", - "honor", "honour", - "humor", "humour", - "labor", "labour", - "liter", "litre", - "miter", "mitre", - "molds", "moulds", - "moldy", "mouldy", - "molts", "moults", - "odors", "odours", - "plows", "ploughs", - "rigor", "rigour", - "rumor", "rumour", - "savor", "savour", - "valor", "valour", - "vapor", "vapour", - "vigor", "vigour", - "cozy", "cosy", - "mold", "mould", - "molt", "moult", - "odor", "odour", - "plow", "plough", -} diff --git a/vendor/github.com/curioswitch/go-reassign/.gitattributes b/vendor/github.com/curioswitch/go-reassign/.gitattributes deleted file mode 100644 index d020be8ea4..0000000000 --- a/vendor/github.com/curioswitch/go-reassign/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -*.go text eol=lf - diff --git a/vendor/github.com/curioswitch/go-reassign/.gitignore b/vendor/github.com/curioswitch/go-reassign/.gitignore deleted file mode 100644 index 59fa33613b..0000000000 --- a/vendor/github.com/curioswitch/go-reassign/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -.idea -.VSCode -.envrc - -build -dist diff --git a/vendor/github.com/curioswitch/go-reassign/.golangci.yml b/vendor/github.com/curioswitch/go-reassign/.golangci.yml deleted file mode 100644 index fdf0bb2f22..0000000000 --- a/vendor/github.com/curioswitch/go-reassign/.golangci.yml +++ /dev/null @@ -1,35 +0,0 @@ -linters: - enable: - - asasalint - - bidichk - - bodyclose - - decorder - - durationcheck - - err113 - - errchkjson - - errname - - errorlint - - exhaustive - - gocritic - - gofmt - - goimports - - goprintffuncname - - gosec - - importas - - misspell - - nolintlint - - prealloc - - predeclared - - promlinter - - revive - - stylecheck - - tagliatelle - - tenv - - thelper - - unconvert - - usestdlibvars -issues: - exclude-rules: - - path: magefile\.go - linters: - - deadcode diff --git a/vendor/github.com/curioswitch/go-reassign/.goreleaser.yaml b/vendor/github.com/curioswitch/go-reassign/.goreleaser.yaml deleted file mode 100644 index 25f2dc0c17..0000000000 --- a/vendor/github.com/curioswitch/go-reassign/.goreleaser.yaml +++ /dev/null @@ -1,27 +0,0 @@ -builds: - - main: ./cmd - env: - - CGO_ENABLED=0 - targets: - - linux_amd64 - - linux_arm64 - - darwin_amd64 - - darwin_arm64 - - windows_amd64 - - windows_arm64 -archives: - - format_overrides: - - goos: windows - format: zip -release: - mode: append -checksum: - name_template: 'checksums.txt' -snapshot: - name_template: "{{ incpatch .Version }}-next" -changelog: - sort: asc - filters: - exclude: - - '^docs:' - - '^test:' diff --git a/vendor/github.com/curioswitch/go-reassign/LICENSE b/vendor/github.com/curioswitch/go-reassign/LICENSE deleted file mode 100644 index 9f18bde002..0000000000 --- a/vendor/github.com/curioswitch/go-reassign/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) Choko (choko@curioswitch.org) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/curioswitch/go-reassign/README.md b/vendor/github.com/curioswitch/go-reassign/README.md deleted file mode 100644 index 190756f928..0000000000 --- a/vendor/github.com/curioswitch/go-reassign/README.md +++ /dev/null @@ -1,54 +0,0 @@ -# reassign - -A linter that detects when reassigning a top-level variable in another package. - -## Install - -```bash -go install github.com/curioswitch/go-reassign -``` - -## Usage - -```bash -reassign ./... -``` - -Change the pattern to match against variables being reassigned. By default, only `EOF` and `Err*` variables are checked. - -```bash -reassign -pattern ".*" ./... -``` - -## Background - -Package variables are commonly used to define sentinel errors which callers can use with `errors.Is` to determine the -type of a returned `error`. Some examples exist in the standard [os](https://pkg.go.dev/os#pkg-variables) library. - -Unfortunately, as with any variable, these are mutable, and it is possible to write this very dangerous code. - -```go -package main -import "io" -func bad() { - // breaks file reading - io.EOF = nil -} -``` - -This caused a new pattern for [constant errors](https://dave.cheney.net/2016/04/07/constant-errors) -to gain popularity, but they don't work well with improvements to the `errors` package in recent versions of Go and may -be considered to be non-idiomatic compared to normal `errors.New`. If we can catch reassignment of sentinel errors, we -gain much of the safety of constant errors. - -This linter will catch reassignment of variables in other packages. By default it intends to apply to as many codebases -as possible and only checks a restricted set of variable names, `EOF` and `ErrFoo`, to restrict to sentinel errors. -Package variable reassignment is generally confusing, though, and we recommend avoiding it for all variables, not just errors. -The `pattern` flag can be set to a regular expression to define what variables cannot be reassigned, and `.*` is -recommended if it works with your code. - -## Development - -[mage](https://magefile.org/) is used for development. Run `go run mage.go -l` to see available targets. - -For example, to run checks before sending a PR, run `go run mage.go check`. diff --git a/vendor/github.com/curioswitch/go-reassign/analyzer.go b/vendor/github.com/curioswitch/go-reassign/analyzer.go deleted file mode 100644 index 48707adebe..0000000000 --- a/vendor/github.com/curioswitch/go-reassign/analyzer.go +++ /dev/null @@ -1,13 +0,0 @@ -package reassign - -import ( - "github.com/curioswitch/go-reassign/internal/analyzer" - "golang.org/x/tools/go/analysis" -) - -const FlagPattern = analyzer.FlagPattern - -// NewAnalyzer returns an analyzer for checking that package variables are not reassigned. -func NewAnalyzer() *analysis.Analyzer { - return analyzer.New() -} diff --git a/vendor/github.com/curioswitch/go-reassign/internal/analyzer/analyzer.go b/vendor/github.com/curioswitch/go-reassign/internal/analyzer/analyzer.go deleted file mode 100644 index c2a29c5299..0000000000 --- a/vendor/github.com/curioswitch/go-reassign/internal/analyzer/analyzer.go +++ /dev/null @@ -1,96 +0,0 @@ -package analyzer - -import ( - "fmt" - "go/ast" - "go/types" - "regexp" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/inspector" -) - -const FlagPattern = "pattern" - -func New() *analysis.Analyzer { - a := &analysis.Analyzer{ - Name: "reassign", - Doc: "Checks that package variables are not reassigned", - Requires: []*analysis.Analyzer{inspect.Analyzer}, - Run: run, - } - a.Flags.String(FlagPattern, `^(Err.*|EOF)$`, "Pattern to match package variables against to prevent reassignment") - return a -} - -func run(pass *analysis.Pass) (interface{}, error) { - checkRE, err := regexp.Compile(pass.Analyzer.Flags.Lookup(FlagPattern).Value.String()) - if err != nil { - return nil, fmt.Errorf("invalid pattern: %w", err) - } - - inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - inspect.Preorder([]ast.Node{(*ast.AssignStmt)(nil), (*ast.UnaryExpr)(nil)}, func(node ast.Node) { - switch node := node.(type) { - case *ast.AssignStmt: - for _, lhs := range node.Lhs { - reportImported(pass, lhs, checkRE, "reassigning") - } - default: - // TODO(chokoswitch): Consider handling operations other than assignment on globals, for example - // taking their address. - } - }) - return nil, nil -} - -func reportImported(pass *analysis.Pass, expr ast.Expr, checkRE *regexp.Regexp, prefix string) { - switch x := expr.(type) { - case *ast.SelectorExpr: - selectIdent, ok := x.X.(*ast.Ident) - if !ok { - return - } - - var pkgPath string - if selectObj, ok := pass.TypesInfo.Uses[selectIdent]; ok { - pkg, ok := selectObj.(*types.PkgName) - if !ok || pkg.Imported() == pass.Pkg { - return - } - pkgPath = pkg.Imported().Path() - } - - matches := false - if checkRE.MatchString(x.Sel.Name) { - matches = true - } - if !matches { - // Expression may include a package name, so check that too. Support was added later so we check - // just name and qualified name separately for compatibility. - if checkRE.MatchString(pkgPath + "." + x.Sel.Name) { - matches = true - } - } - - if matches { - pass.Reportf(expr.Pos(), "%s variable %s in other package %s", prefix, x.Sel.Name, selectIdent.Name) - } - case *ast.Ident: - use, ok := pass.TypesInfo.Uses[x].(*types.Var) - if !ok { - return - } - - if use.Pkg() == pass.Pkg { - return - } - - if !checkRE.MatchString(x.Name) { - return - } - - pass.Reportf(expr.Pos(), "%s variable %s from other package %s", prefix, x.Name, use.Pkg().Path()) - } -} diff --git a/vendor/github.com/daixiang0/gci/LICENSE b/vendor/github.com/daixiang0/gci/LICENSE deleted file mode 100644 index e1292f7389..0000000000 --- a/vendor/github.com/daixiang0/gci/LICENSE +++ /dev/null @@ -1,29 +0,0 @@ -BSD 3-Clause License - -Copyright (c) 2020, Xiang Dai -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/daixiang0/gci/pkg/config/config.go b/vendor/github.com/daixiang0/gci/pkg/config/config.go deleted file mode 100644 index 643a313f0d..0000000000 --- a/vendor/github.com/daixiang0/gci/pkg/config/config.go +++ /dev/null @@ -1,114 +0,0 @@ -package config - -import ( - "sort" - - "gopkg.in/yaml.v3" - - "github.com/daixiang0/gci/pkg/section" -) - -var defaultOrder = map[string]int{ - section.StandardType: 0, - section.DefaultType: 1, - section.CustomType: 2, - section.BlankType: 3, - section.DotType: 4, - section.AliasType: 5, - section.LocalModuleType: 6, -} - -type BoolConfig struct { - NoInlineComments bool `yaml:"no-inlineComments"` - NoPrefixComments bool `yaml:"no-prefixComments"` - Debug bool `yaml:"-"` - SkipGenerated bool `yaml:"skipGenerated"` - SkipVendor bool `yaml:"skipVendor"` - CustomOrder bool `yaml:"customOrder"` - NoLexOrder bool `yaml:"noLexOrder"` -} - -type Config struct { - BoolConfig - Sections section.SectionList - SectionSeparators section.SectionList -} - -type YamlConfig struct { - Cfg BoolConfig `yaml:",inline"` - SectionStrings []string `yaml:"sections"` - SectionSeparatorStrings []string `yaml:"sectionseparators"` - - // Since history issue, Golangci-lint needs Analyzer to run and GCI add an Analyzer layer to integrate. - // The ModPath param is only from analyzer.go, no need to set it in all other places. - ModPath string `yaml:"-"` -} - -func (g YamlConfig) Parse() (*Config, error) { - var err error - - sections, err := section.Parse(g.SectionStrings) - if err != nil { - return nil, err - } - if sections == nil { - sections = section.DefaultSections() - } - if err := configureSections(sections, g.ModPath); err != nil { - return nil, err - } - - // if default order sorted sections - if !g.Cfg.CustomOrder { - sort.Slice(sections, func(i, j int) bool { - sectionI, sectionJ := sections[i].Type(), sections[j].Type() - - if g.Cfg.NoLexOrder || sectionI != sectionJ { - return defaultOrder[sectionI] < defaultOrder[sectionJ] - } - - return sections[i].String() < sections[j].String() - }) - } - - sectionSeparators, err := section.Parse(g.SectionSeparatorStrings) - if err != nil { - return nil, err - } - if sectionSeparators == nil { - sectionSeparators = section.DefaultSectionSeparators() - } - - return &Config{g.Cfg, sections, sectionSeparators}, nil -} - -func ParseConfig(in string) (*Config, error) { - config := YamlConfig{} - - err := yaml.Unmarshal([]byte(in), &config) - if err != nil { - return nil, err - } - - gciCfg, err := config.Parse() - if err != nil { - return nil, err - } - - return gciCfg, nil -} - -// configureSections now only do golang module path finding. -// Since history issue, Golangci-lint needs Analyzer to run and GCI add an Analyzer layer to integrate. -// The path param is from analyzer.go, in all other places should pass empty string. -func configureSections(sections section.SectionList, path string) error { - for _, sec := range sections { - switch s := sec.(type) { - case *section.LocalModule: - if err := s.Configure(path); err != nil { - return err - } - } - } - return nil -} diff --git a/vendor/github.com/daixiang0/gci/pkg/format/format.go b/vendor/github.com/daixiang0/gci/pkg/format/format.go deleted file mode 100644 index 062701d2e4..0000000000 --- a/vendor/github.com/daixiang0/gci/pkg/format/format.go +++ /dev/null @@ -1,46 +0,0 @@ -package format - -import ( - "fmt" - - "github.com/daixiang0/gci/pkg/config" - "github.com/daixiang0/gci/pkg/log" - "github.com/daixiang0/gci/pkg/parse" - "github.com/daixiang0/gci/pkg/section" - "github.com/daixiang0/gci/pkg/specificity" -) - -type Block struct { - Start, End int -} - -type resultMap map[string][]*Block - -func Format(data []*parse.GciImports, cfg *config.Config) (resultMap, error) { - result := make(resultMap, len(cfg.Sections)) - for _, d := range data { - // determine match specificity for every available section - var bestSection section.Section - var bestSectionSpecificity specificity.MatchSpecificity = specificity.MisMatch{} - for _, section := range cfg.Sections { - sectionSpecificity := section.MatchSpecificity(d) - if sectionSpecificity.IsMoreSpecific(specificity.MisMatch{}) && sectionSpecificity.Equal(bestSectionSpecificity) { - // specificity is identical - // return nil, section.EqualSpecificityMatchError{} - return nil, nil - } - if sectionSpecificity.IsMoreSpecific(bestSectionSpecificity) { - // better match found - bestSectionSpecificity = sectionSpecificity - bestSection = section - } - } - if bestSection == nil { - return nil, section.NoMatchingSectionForImportError{Imports: d} - } - log.L().Debug(fmt.Sprintf("Matched import %v to section %s", d, bestSection)) - result[bestSection.String()] = append(result[bestSection.String()], &Block{d.Start, d.End}) - } - - return result, nil -} diff --git a/vendor/github.com/daixiang0/gci/pkg/gci/gci.go b/vendor/github.com/daixiang0/gci/pkg/gci/gci.go deleted file mode 100644 index 163e95a861..0000000000 --- a/vendor/github.com/daixiang0/gci/pkg/gci/gci.go +++ /dev/null @@ -1,229 +0,0 @@ -package gci - -import ( - "bytes" - "errors" - "fmt" - goFormat "go/format" - "os" - "sync" - - "github.com/hexops/gotextdiff" - "github.com/hexops/gotextdiff/myers" - "github.com/hexops/gotextdiff/span" - "golang.org/x/sync/errgroup" - - "github.com/daixiang0/gci/pkg/config" - "github.com/daixiang0/gci/pkg/format" - "github.com/daixiang0/gci/pkg/io" - "github.com/daixiang0/gci/pkg/log" - "github.com/daixiang0/gci/pkg/parse" - "github.com/daixiang0/gci/pkg/section" - "github.com/daixiang0/gci/pkg/utils" -) - -func LocalFlagsToSections(localFlags []string) section.SectionList { - sections := section.DefaultSections() - // Add all local arguments as ImportPrefix sections - // for _, l := range localFlags { - // sections = append(sections, section.Section{l, nil, nil}) - // } - return sections -} - -func PrintFormattedFiles(paths []string, cfg config.Config) error { - return processStdInAndGoFilesInPaths(paths, cfg, func(filePath string, unmodifiedFile, formattedFile []byte) error { - fmt.Print(string(formattedFile)) - return nil - }) -} - -func WriteFormattedFiles(paths []string, cfg config.Config) error { - return processGoFilesInPaths(paths, cfg, func(filePath string, unmodifiedFile, formattedFile []byte) error { - if bytes.Equal(unmodifiedFile, formattedFile) { - log.L().Debug(fmt.Sprintf("Skipping correctly formatted File: %s", filePath)) - return nil - } - log.L().Info(fmt.Sprintf("Writing formatted File: %s", filePath)) - return os.WriteFile(filePath, formattedFile, 0o644) - }) -} - -func ListUnFormattedFiles(paths []string, cfg config.Config) error { - return processGoFilesInPaths(paths, cfg, func(filePath string, unmodifiedFile, formattedFile []byte) error { - if bytes.Equal(unmodifiedFile, formattedFile) { - return nil - } - fmt.Println(filePath) - return nil - }) -} - -func DiffFormattedFiles(paths []string, cfg config.Config) error { - return processStdInAndGoFilesInPaths(paths, cfg, func(filePath string, unmodifiedFile, formattedFile []byte) error { - fileURI := span.URIFromPath(filePath) - edits := myers.ComputeEdits(fileURI, string(unmodifiedFile), string(formattedFile)) - unifiedEdits := gotextdiff.ToUnified(filePath, filePath, string(unmodifiedFile), edits) - fmt.Printf("%v", unifiedEdits) - return nil - }) -} - -func DiffFormattedFilesToArray(paths []string, cfg config.Config, diffs *[]string, lock *sync.Mutex) error { - log.InitLogger() - defer log.L().Sync() - return processStdInAndGoFilesInPaths(paths, cfg, func(filePath string, unmodifiedFile, formattedFile []byte) error { - fileURI := span.URIFromPath(filePath) - edits := myers.ComputeEdits(fileURI, string(unmodifiedFile), string(formattedFile)) - unifiedEdits := gotextdiff.ToUnified(filePath, filePath, string(unmodifiedFile), edits) - lock.Lock() - *diffs = append(*diffs, fmt.Sprint(unifiedEdits)) - lock.Unlock() - return nil - }) -} - -type fileFormattingFunc func(filePath string, unmodifiedFile, formattedFile []byte) error - -func processStdInAndGoFilesInPaths(paths []string, cfg config.Config, fileFunc fileFormattingFunc) error { - return ProcessFiles(io.StdInGenerator.Combine(io.GoFilesInPathsGenerator(paths, cfg.SkipVendor)), cfg, fileFunc) -} - -func processGoFilesInPaths(paths []string, cfg config.Config, fileFunc fileFormattingFunc) error { - return ProcessFiles(io.GoFilesInPathsGenerator(paths, cfg.SkipVendor), cfg, fileFunc) -} - -func ProcessFiles(fileGenerator io.FileGeneratorFunc, cfg config.Config, fileFunc fileFormattingFunc) error { - var taskGroup errgroup.Group - files, err := fileGenerator() - if err != nil { - return err - } - for _, file := range files { - // run file processing in parallel - taskGroup.Go(processingFunc(file, cfg, fileFunc)) - } - return taskGroup.Wait() -} - -func processingFunc(file io.FileObj, cfg config.Config, formattingFunc fileFormattingFunc) func() error { - return func() error { - unmodifiedFile, formattedFile, err := LoadFormatGoFile(file, cfg) - if err != nil { - // if errors.Is(err, FileParsingError{}) { - // // do not process files that are improperly formatted - // return nil - // } - return err - } - return formattingFunc(file.Path(), unmodifiedFile, formattedFile) - } -} - -func LoadFormatGoFile(file io.FileObj, cfg config.Config) (src, dist []byte, err error) { - src, err = file.Load() - log.L().Debug(fmt.Sprintf("Loaded File: %s", file.Path())) - if err != nil { - return nil, nil, err - } - - return LoadFormat(src, file.Path(), cfg) -} - -func LoadFormat(in []byte, path string, cfg config.Config) (src, dist []byte, err error) { - src = in - - if cfg.SkipGenerated && parse.IsGeneratedFileByComment(string(src)) { - return src, src, nil - } - - imports, headEnd, tailStart, cStart, cEnd, err := parse.ParseFile(src, path) - if err != nil { - if errors.Is(err, parse.NoImportError{}) { - return src, src, nil - } - return nil, nil, err - } - - // do not do format if only one import - if len(imports) <= 1 { - return src, src, nil - } - - result, err := format.Format(imports, &cfg) - if err != nil { - return nil, nil, err - } - - firstWithIndex := true - - var body []byte - - // order by section list - for _, s := range cfg.Sections { - if len(result[s.String()]) > 0 { - if len(body) > 0 { - body = append(body, utils.Linebreak) - } - for _, d := range result[s.String()] { - AddIndent(&body, &firstWithIndex) - body = append(body, src[d.Start:d.End]...) - } - } - } - - head := make([]byte, headEnd) - copy(head, src[:headEnd]) - tail := make([]byte, len(src)-tailStart) - copy(tail, src[tailStart:]) - - // ensure C - if cStart != 0 { - head = append(head, src[cStart:cEnd]...) - head = append(head, utils.Linebreak) - } - - // add beginning of import block - head = append(head, `import (`...) - head = append(head, utils.Linebreak) - // add end of import block - body = append(body, []byte{utils.RightParenthesis, utils.Linebreak}...) - - log.L().Debug(fmt.Sprintf("head:\n%s", head)) - log.L().Debug(fmt.Sprintf("body:\n%s", body)) - if len(tail) > 20 { - log.L().Debug(fmt.Sprintf("tail:\n%s", tail[:20])) - } else { - log.L().Debug(fmt.Sprintf("tail:\n%s", tail)) - } - - var totalLen int - slices := [][]byte{head, body, tail} - for _, s := range slices { - totalLen += len(s) - } - dist = make([]byte, totalLen) - var i int - for _, s := range slices { - i += copy(dist[i:], s) - } - - // remove ^M(\r\n) from Win to Unix - dist = bytes.ReplaceAll(dist, []byte{utils.WinLinebreak}, []byte{utils.Linebreak}) - - log.L().Debug(fmt.Sprintf("raw:\n%s", dist)) - dist, err = goFormat.Source(dist) - if err != nil { - return nil, nil, err - } - - return src, dist, nil -} - -func AddIndent(in *[]byte, first *bool) { - if *first { - *first = false - return - } - *in = append(*in, utils.Indent) -} diff --git a/vendor/github.com/daixiang0/gci/pkg/gci/testdata.go b/vendor/github.com/daixiang0/gci/pkg/gci/testdata.go deleted file mode 100644 index 866ae84c49..0000000000 --- a/vendor/github.com/daixiang0/gci/pkg/gci/testdata.go +++ /dev/null @@ -1,1298 +0,0 @@ -package gci - -type Cases struct { - name, config, in, out string -} - -var commonConfig = `sections: - - Standard - - Default - - Prefix(github.com/daixiang0) -` - -var testCases = []Cases{ - { - "already-good", - - commonConfig, - - `package main - -import ( - "fmt" - - g "github.com/golang" - - "github.com/daixiang0/gci" -) -`, - `package main - -import ( - "fmt" - - g "github.com/golang" - - "github.com/daixiang0/gci" -) -`, - }, - { - "blank-format", - - commonConfig, - - `package main -import ( - "fmt" - - // comment - g "github.com/golang" // comment - - "github.com/daixiang0/gci" -) -`, - `package main - -import ( - "fmt" - - // comment - g "github.com/golang" // comment - - "github.com/daixiang0/gci" -) -`, - }, - { - "cgo-block", - - commonConfig, - - `package main - -import ( - /* - #include "types.h" - */ - "C" -) -`, - `package main - -import ( - /* - #include "types.h" - */ - "C" -) -`, - }, - { - "cgo-block-after-import", - - commonConfig, - - `package main - -import ( - "fmt" - - "github.com/daixiang0/gci" - g "github.com/golang" -) - -// #cgo CFLAGS: -DPNG_DEBUG=1 -// #cgo amd64 386 CFLAGS: -DX86=1 -// #cgo LDFLAGS: -lpng -// #include -import "C" -`, - `package main - -// #cgo CFLAGS: -DPNG_DEBUG=1 -// #cgo amd64 386 CFLAGS: -DX86=1 -// #cgo LDFLAGS: -lpng -// #include -import "C" - -import ( - "fmt" - - g "github.com/golang" - - "github.com/daixiang0/gci" -) -`, - }, - { - "cgo-block-before-import", - - commonConfig, - - `package main - -// #cgo CFLAGS: -DPNG_DEBUG=1 -// #cgo amd64 386 CFLAGS: -DX86=1 -// #cgo LDFLAGS: -lpng -// #include -import "C" - -import ( - "fmt" - - "github.com/daixiang0/gci" - - g "github.com/golang" -) -`, - `package main - -// #cgo CFLAGS: -DPNG_DEBUG=1 -// #cgo amd64 386 CFLAGS: -DX86=1 -// #cgo LDFLAGS: -lpng -// #include -import "C" - -import ( - "fmt" - - g "github.com/golang" - - "github.com/daixiang0/gci" -) -`, - }, - { - "cgo-block-mixed", - - commonConfig, - - `package main - -import ( - /* #include "types.h" - */"C" -) -`, - `package main - -import ( - /* #include "types.h" - */"C" -) -`, - }, - { - "cgo-block-mixed-with-content", - - commonConfig, - - `package main - -import ( - /* #include "types.h" - #include "other.h" */"C" -) -`, - `package main - -import ( - /* #include "types.h" - #include "other.h" */"C" -) -`, - }, - { - "cgo-block-prefix", - - commonConfig, - - `package main - -import ( - /* #include "types.h" */ "C" -) -`, - `package main - -import ( - /* #include "types.h" */ "C" -) -`, - }, - { - "cgo-block-single-line", - - commonConfig, - - `package main - -import ( - /* #include "types.h" */ - "C" -) -`, - `package main - -import ( - /* #include "types.h" */ - "C" -) -`, - }, - { - "cgo-line", - - commonConfig, - - `package main - -import ( - // #include "types.h" - "C" -) -`, - `package main - -import ( - // #include "types.h" - "C" -) -`, - }, - { - "cgo-multiline", - - commonConfig, - - `package main - -import ( - // #include "types.h" - // #include "other.h" - "C" -) -`, - `package main - -import ( - // #include "types.h" - // #include "other.h" - "C" -) -`, - }, - { - "cgo-single", - - commonConfig, - - `package main - -import ( - "fmt" - - "github.com/daixiang0/gci" -) - -import "C" - -import "github.com/golang" - -import ( - "github.com/daixiang0/gci" -) -`, - `package main - -import "C" - -import ( - "fmt" - - "github.com/golang" - - "github.com/daixiang0/gci" -) -`, - }, - { - "comment", - - commonConfig, - - `package main -import ( - //Do not forget to run Gci - "fmt" -) -`, - `package main -import ( - //Do not forget to run Gci - "fmt" -) -`, - }, - { - "comment-before-import", - - commonConfig, - - `package main - -// comment -import ( - "fmt" - "os" - - "github.com/daixiang0/gci" -) -`, - `package main - -// comment -import ( - "fmt" - "os" - - "github.com/daixiang0/gci" -) -`, - }, - { - "comment-in-the-tail", - - `sections: - - Standard - - Default - - Prefix(github.com/daixiang0) -`, - `package main - -import ( - "fmt" - - g "github.com/golang" - - "github.com/daixiang0/gci" -) - -type test int - -// test -`, - `package main - -import ( - "fmt" - - g "github.com/golang" - - "github.com/daixiang0/gci" -) - -type test int - -// test -`, - }, - { - "comment-top", - - commonConfig, - - `package main - -import ( - "os" // https://pkg.go.dev/os - // https://pkg.go.dev/fmt - "fmt" -) -`, - `package main - -import ( - // https://pkg.go.dev/fmt - "fmt" - "os" // https://pkg.go.dev/os -) -`, - }, - { - "comment-without-whitespace", - - commonConfig, - - `package proc - -import ( - "context"// no separating whitespace here //nolint:confusion -) -`, - `package proc - -import ( - "context"// no separating whitespace here //nolint:confusion -) -`, - }, - { - "comment-with-slashslash", - - commonConfig, - - `package main - -import ( - "fmt" // https://pkg.go.dev/fmt -) -`, - `package main - -import ( - "fmt" // https://pkg.go.dev/fmt -) -`, - }, - { - "custom-order", - - `customOrder: true -sections: - - Prefix(github.com/daixiang0) - - Default - - Standard -`, - `package main - -import ( - "fmt" - - g "github.com/golang" - - "github.com/daixiang0/a" -) -`, - `package main - -import ( - "github.com/daixiang0/a" - - g "github.com/golang" - - "fmt" -) -`, - }, - { - "default-order", - - `sections: - - Standard - - Prefix(github.com/daixiang0) - - Default -`, - `package main - -import ( - "fmt" - - g "github.com/golang" - - "github.com/daixiang0/a" -) -`, - `package main - -import ( - "fmt" - - g "github.com/golang" - - "github.com/daixiang0/a" -) -`, - }, - { - "dot-and-blank", - - `sections: - - Standard - - Default - - Prefix(github.com/daixiang0) - - Blank - - Dot -`, - `package main - -import ( - "fmt" - - g "github.com/golang" - . "github.com/golang/dot" - _ "github.com/golang/blank" - - "github.com/daixiang0/a" - "github.com/daixiang0/gci" - "github.com/daixiang0/gci/subtest" - . "github.com/daixiang0/gci/dot" - _ "github.com/daixiang0/gci/blank" -) -`, - `package main - -import ( - "fmt" - - g "github.com/golang" - - "github.com/daixiang0/a" - "github.com/daixiang0/gci" - "github.com/daixiang0/gci/subtest" - - _ "github.com/daixiang0/gci/blank" - _ "github.com/golang/blank" - - . "github.com/daixiang0/gci/dot" - . "github.com/golang/dot" -) -`, - }, - { - "duplicate-imports", - - `sections: - - Standard - - Default - - Prefix(github.com/daixiang0) -`, - `package main - -import ( - "fmt" - - g "github.com/golang" - - a "github.com/daixiang0/gci" - "github.com/daixiang0/gci" -) -`, - `package main - -import ( - "fmt" - - g "github.com/golang" - - "github.com/daixiang0/gci" - a "github.com/daixiang0/gci" -) -`, - }, - { - "grouped-multiple-custom", - - `sections: - - Standard - - Default - - Prefix(github.com/daixiang0,gitlab.com/daixiang0,daixiang0) -`, - `package main - -import ( - "daixiang0/lib1" - "fmt" - "github.com/daixiang0/gci" - "gitlab.com/daixiang0/gci" - g "github.com/golang" - "github.com/daixiang0/gci/subtest" -) -`, - `package main - -import ( - "fmt" - - g "github.com/golang" - - "daixiang0/lib1" - "github.com/daixiang0/gci" - "github.com/daixiang0/gci/subtest" - "gitlab.com/daixiang0/gci" -) -`, - }, - { - "leading-comment", - - commonConfig, - - `package main - -import ( - // foo - "fmt" -) -`, - `package main - -import ( - // foo - "fmt" -) -`, - }, - { - "linebreak", - - `sections: - - Standard - - Default - - Prefix(github.com/daixiang0) -`, - `package main - -import ( - g "github.com/golang" - - "fmt" - - "github.com/daixiang0/gci" - -) -`, - `package main - -import ( - "fmt" - - g "github.com/golang" - - "github.com/daixiang0/gci" -) -`, - }, - { - "linebreak-no-custom", - - `sections: - - Standard - - Default - - Prefix(github.com/daixiang0) -`, - `package main - -import ( - g "github.com/golang" - - "fmt" - -) -`, - `package main - -import ( - "fmt" - - g "github.com/golang" -) -`, - }, - { - "mismatch-section", - - `sections: - - Standard - - Default - - Prefix(github.com/daixiang0) - - Prefix(github.com/daixiang0/gci) -`, - `package main - -import ( - "fmt" - - g "github.com/golang" - - "github.com/daixiang0/gci" -) -`, - `package main - -import ( - "fmt" - - g "github.com/golang" - - "github.com/daixiang0/gci" -) -`, - }, - { - "multiple-custom", - - `sections: - - Standard - - Default - - Prefix(github.com/daixiang0) - - Prefix(github.com/daixiang0/gci) - - Prefix(github.com/daixiang0/gci/subtest) -`, - `package main - -import ( - "fmt" - - g "github.com/golang" - - "github.com/daixiang0/a" - "github.com/daixiang0/gci" - "github.com/daixiang0/gci/subtest" -) -`, - `package main - -import ( - "fmt" - - g "github.com/golang" - - "github.com/daixiang0/a" - - "github.com/daixiang0/gci" - - "github.com/daixiang0/gci/subtest" -) -`, - }, - { - "multiple-imports", - - commonConfig, - - `package main - -import "fmt" - -import "context" - -import ( - "os" - - "github.com/daixiang0/test" -) - -import "math" - - -// main -func main() { -} -`, - `package main - -import ( - "context" - "fmt" - "math" - "os" - - "github.com/daixiang0/test" -) - -// main -func main() { -} -`, - }, - { - "multiple-line-comment", - - commonConfig, - - `package proc - -import ( - "context" // in-line comment - "fmt" - "os" - - //nolint:depguard // A multi-line comment explaining why in - // this one case it's OK to use os/exec even though depguard - // is configured to force us to use dlib/exec instead. - "os/exec" - - "golang.org/x/sys/unix" - "github.com/local/dlib/dexec" -) -`, - `package proc - -import ( - "context" // in-line comment - "fmt" - "os" - //nolint:depguard // A multi-line comment explaining why in - // this one case it's OK to use os/exec even though depguard - // is configured to force us to use dlib/exec instead. - "os/exec" - - "github.com/local/dlib/dexec" - "golang.org/x/sys/unix" -) -`, - }, - { - "nochar-after-import", - - commonConfig, - - `package main - -import ( - "fmt" -) -`, - `package main - -import ( - "fmt" -) -`, - }, - { - "no-format", - - commonConfig, - - `package main - -import( -"fmt" - -g "github.com/golang" - -"github.com/daixiang0/gci" -) -`, - `package main - -import ( - "fmt" - - g "github.com/golang" - - "github.com/daixiang0/gci" -) -`, - }, - { - "nolint", - - commonConfig, - - `package main - -import ( - "fmt" - - "github.com/forbidden/pkg" //nolint:depguard - - _ "github.com/daixiang0/gci" //nolint:depguard -) -`, - `package main - -import ( - "fmt" - - "github.com/forbidden/pkg" //nolint:depguard - - _ "github.com/daixiang0/gci" //nolint:depguard -) -`, - }, - { - "number-in-alias", - - commonConfig, - - `package main - -import ( - "fmt" - - go_V1 "github.com/golang" - - "github.com/daixiang0/gci" -) -`, - `package main - -import ( - "fmt" - - go_V1 "github.com/golang" - - "github.com/daixiang0/gci" -) -`, - }, - { - "one-import", - - commonConfig, - - `package main -import ( - "fmt" -) - -func main() { -} -`, - `package main -import ( - "fmt" -) - -func main() { -} -`, - }, - { - "one-import-one-line", - - commonConfig, - - `package main - -import "fmt" - -func main() { -} -`, - `package main - -import "fmt" - -func main() { -} -`, - }, - { - "one-line-import-after-import", - - `sections: - - Standard - - Default - - Prefix(github.com/daixiang0) -`, - `package main - -import ( - "fmt" - "os" - - "github.com/daixiang0/test" -) - -import "context" -`, - `package main - -import ( - "context" - "fmt" - "os" - - "github.com/daixiang0/test" -) -`, - }, - { - "same-prefix-custom", - - `sections: - - Standard - - Default - - Prefix(github.com/daixiang0/gci) - - Prefix(github.com/daixiang0/gci/subtest) -`, - `package main - -import ( - "fmt" - - g "github.com/golang" - - "github.com/daixiang0/gci" - "github.com/daixiang0/gci/subtest" -) -`, - `package main - -import ( - "fmt" - - g "github.com/golang" - - "github.com/daixiang0/gci" - - "github.com/daixiang0/gci/subtest" -) -`, - }, - { - "simple-case", - - commonConfig, - - `package main - -import ( - "golang.org/x/tools" - - "fmt" - - "github.com/daixiang0/gci" -) -`, - `package main - -import ( - "fmt" - - "golang.org/x/tools" - - "github.com/daixiang0/gci" -) -`, - }, - { - "whitespace-test", - - commonConfig, - - `package main - -import ( - "fmt" - "github.com/golang" // golang - alias "github.com/daixiang0/gci" -) -`, - `package main - -import ( - "fmt" - - "github.com/golang" // golang - - alias "github.com/daixiang0/gci" -) -`, - }, - { - "with-above-comment-and-alias", - - commonConfig, - - `package main - -import ( - "fmt" - // golang - _ "github.com/golang" - "github.com/daixiang0/gci" -) -`, - `package main - -import ( - "fmt" - - // golang - _ "github.com/golang" - - "github.com/daixiang0/gci" -) -`, - }, - { - "with-comment-and-alias", - - commonConfig, - - `package main - -import ( - "fmt" - _ "github.com/golang" // golang - "github.com/daixiang0/gci" -) -`, - `package main - -import ( - "fmt" - - _ "github.com/golang" // golang - - "github.com/daixiang0/gci" -) -`, - }, - { - "same-prefix-custom", - - `sections: - - Standard - - Default - - Prefix(github.com/daixiang0/gci) - - Prefix(github.com/daixiang0/gci/subtest) -`, - `package main - -import ( - "fmt" - - g "github.com/golang" - - "github.com/daixiang0/gci" - "github.com/daixiang0/gci/subtest" -) -`, - `package main - -import ( - "fmt" - - g "github.com/golang" - - "github.com/daixiang0/gci" - - "github.com/daixiang0/gci/subtest" -) -`, - }, - { - "same-prefix-custom", - - `sections: - - Standard - - Default - - Prefix(github.com/daixiang0/gci) - - Prefix(github.com/daixiang0/gci/subtest) -`, - `package main - -import ( - "fmt" - - g "github.com/golang" - - "github.com/daixiang0/gci" - "github.com/daixiang0/gci/subtest" -) -`, - `package main - -import ( - "fmt" - - g "github.com/golang" - - "github.com/daixiang0/gci" - - "github.com/daixiang0/gci/subtest" -) -`, - }, - { - "blank-in-config", - - `sections: - - Standard - - Default - - Prefix( github.com/daixiang0/gci, github.com/daixiang0/gci/subtest ) -`, - `package main - -import ( - "fmt" - - g "github.com/golang" - - "github.com/daixiang0/gci" - "github.com/daixiang0/gci/subtest" -) -`, - `package main - -import ( - "fmt" - - g "github.com/golang" - - "github.com/daixiang0/gci" - "github.com/daixiang0/gci/subtest" -) -`, - }, - { - "alias", - - `sections: - - Standard - - Default - - Alias -`, - `package main - -import ( - testing "github.com/daixiang0/test" - "fmt" - - g "github.com/golang" - - "github.com/daixiang0/gci" - "github.com/daixiang0/gci/subtest" -) -`, - `package main - -import ( - "fmt" - - "github.com/daixiang0/gci" - "github.com/daixiang0/gci/subtest" - - testing "github.com/daixiang0/test" - g "github.com/golang" -) -`, - }, - { - "no-trailing-newline", - - `sections: - - Standard -`, - `package main - -import ( - "net" - "fmt" -)`, - `package main - -import ( - "fmt" - "net" -) -`, - }, -} diff --git a/vendor/github.com/daixiang0/gci/pkg/io/file.go b/vendor/github.com/daixiang0/gci/pkg/io/file.go deleted file mode 100644 index 79950792ca..0000000000 --- a/vendor/github.com/daixiang0/gci/pkg/io/file.go +++ /dev/null @@ -1,64 +0,0 @@ -package io - -import "io/ioutil" - -// FileObj allows mocking the access to files -type FileObj interface { - Load() ([]byte, error) - Path() string -} - -// File represents a file that can be loaded from the file system -type File struct { - FilePath string -} - -func (f File) Path() string { - return f.FilePath -} - -func (f File) Load() ([]byte, error) { - return ioutil.ReadFile(f.FilePath) -} - -// FileGeneratorFunc returns a list of files that can be loaded and processed -type FileGeneratorFunc func() ([]FileObj, error) - -func (a FileGeneratorFunc) Combine(b FileGeneratorFunc) FileGeneratorFunc { - return func() ([]FileObj, error) { - files, err := a() - if err != nil { - return nil, err - } - additionalFiles, err := b() - if err != nil { - return nil, err - } - files = append(files, additionalFiles...) - return files, err - } -} - -func GoFilesInPathsGenerator(paths []string, skipVendor bool) FileGeneratorFunc { - checkFunc := isGoFile - if skipVendor { - checkFunc = checkChains(isGoFile, isOutsideVendorDir) - } - - return FilesInPathsGenerator(paths, checkFunc) -} - -func FilesInPathsGenerator(paths []string, fileCheckFun fileCheckFunction) FileGeneratorFunc { - return func() (foundFiles []FileObj, err error) { - for _, path := range paths { - files, err := FindFilesForPath(path, fileCheckFun) - if err != nil { - return nil, err - } - for _, filePath := range files { - foundFiles = append(foundFiles, File{filePath}) - } - } - return foundFiles, nil - } -} diff --git a/vendor/github.com/daixiang0/gci/pkg/io/search.go b/vendor/github.com/daixiang0/gci/pkg/io/search.go deleted file mode 100644 index cd821582e7..0000000000 --- a/vendor/github.com/daixiang0/gci/pkg/io/search.go +++ /dev/null @@ -1,77 +0,0 @@ -package io - -import ( - "io/fs" - "os" - "path/filepath" -) - -type fileCheckFunction func(path string, file os.FileInfo) bool - -func FindFilesForPath(path string, fileCheckFun fileCheckFunction) ([]string, error) { - switch entry, err := os.Stat(path); { - case err != nil: - return nil, err - case entry.IsDir(): - return findFilesForDirectory(path, fileCheckFun) - case fileCheckFun(path, entry): - return []string{filepath.Clean(path)}, nil - default: - return []string{}, nil - } -} - -func findFilesForDirectory(dirPath string, fileCheckFun fileCheckFunction) ([]string, error) { - var filePaths []string - err := filepath.WalkDir(dirPath, func(path string, entry fs.DirEntry, err error) error { - if err != nil { - return err - } - file, err := entry.Info() - if err != nil { - return err - } - if !entry.IsDir() && fileCheckFun(path, file) { - filePaths = append(filePaths, filepath.Clean(path)) - } - return nil - }) - if err != nil { - return nil, err - } - return filePaths, nil -} - -func isGoFile(_ string, file os.FileInfo) bool { - return !file.IsDir() && filepath.Ext(file.Name()) == ".go" -} - -func isOutsideVendorDir(path string, _ os.FileInfo) bool { - for { - base := filepath.Base(path) - if base == "vendor" { - return false - } - - prevPath := path - path = filepath.Dir(path) - - if prevPath == path { - break - } - } - - return true -} - -func checkChains(funcs ...fileCheckFunction) fileCheckFunction { - return func(path string, file os.FileInfo) bool { - for _, checkFunc := range funcs { - if !checkFunc(path, file) { - return false - } - } - - return true - } -} diff --git a/vendor/github.com/daixiang0/gci/pkg/io/stdin.go b/vendor/github.com/daixiang0/gci/pkg/io/stdin.go deleted file mode 100644 index ccab2844f4..0000000000 --- a/vendor/github.com/daixiang0/gci/pkg/io/stdin.go +++ /dev/null @@ -1,27 +0,0 @@ -package io - -import ( - "io/ioutil" - "os" -) - -type stdInFile struct{} - -func (s stdInFile) Load() ([]byte, error) { - return ioutil.ReadAll(os.Stdin) -} - -func (s stdInFile) Path() string { - return "StdIn" -} - -var StdInGenerator FileGeneratorFunc = func() ([]FileObj, error) { - stat, err := os.Stdin.Stat() - if err != nil { - return nil, err - } - if (stat.Mode() & os.ModeCharDevice) == 0 { - return []FileObj{stdInFile{}}, nil - } - return []FileObj{}, nil -} diff --git a/vendor/github.com/daixiang0/gci/pkg/log/log.go b/vendor/github.com/daixiang0/gci/pkg/log/log.go deleted file mode 100644 index ab33739ca3..0000000000 --- a/vendor/github.com/daixiang0/gci/pkg/log/log.go +++ /dev/null @@ -1,50 +0,0 @@ -package log - -import ( - "sync" - - "go.uber.org/zap" - "go.uber.org/zap/zapcore" -) - -// Use L to log with Zap -var logger *zap.Logger - -// Keep the config to reference the atomicLevel for changing levels -var logConfig zap.Config - -var doOnce sync.Once - -// InitLogger sets up the logger -func InitLogger() { - doOnce.Do(func() { - logConfig = zap.NewDevelopmentConfig() - - logConfig.EncoderConfig.TimeKey = "timestamp" - logConfig.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder - logConfig.Level.SetLevel(zapcore.InfoLevel) - logConfig.OutputPaths = []string{"stderr"} - - var err error - logger, err = logConfig.Build() - if err != nil { - panic(err) - } - }) -} - -// SetLevel allows you to set the level of the default gci logger. -// This will not work if you replace the logger -func SetLevel(level zapcore.Level) { - logConfig.Level.SetLevel(level) -} - -// L returns the logger -func L() *zap.Logger { - return logger -} - -// SetLogger allows you to set the logger to whatever you want -func SetLogger(l *zap.Logger) { - logger = l -} diff --git a/vendor/github.com/daixiang0/gci/pkg/parse/parse.go b/vendor/github.com/daixiang0/gci/pkg/parse/parse.go deleted file mode 100644 index e8532f850d..0000000000 --- a/vendor/github.com/daixiang0/gci/pkg/parse/parse.go +++ /dev/null @@ -1,200 +0,0 @@ -package parse - -import ( - "go/ast" - "go/parser" - "go/token" - "sort" - "strings" -) - -const C = "\"C\"" - -type GciImports struct { - // original index of import group, include doc, name, path and comment - Start, End int - Name, Path string -} -type ImportList []*GciImports - -func (l ImportList) Len() int { - return len(l) -} - -func (l ImportList) Less(i, j int) bool { - if strings.Compare(l[i].Path, l[j].Path) == 0 { - return strings.Compare(l[i].Name, l[j].Name) < 0 - } - - return strings.Compare(l[i].Path, l[j].Path) < 0 -} - -func (l ImportList) Swap(i, j int) { l[i], l[j] = l[j], l[i] } - -/* - * AST considers a import block as below: - * ``` - * Doc - * Name Path Comment - * ``` - * An example is like below: - * ``` - * // test - * test "fmt" // test - * ``` - * getImports return a import block with name, start and end index - */ -func getImports(imp *ast.ImportSpec) (start, end int, name string) { - if imp.Doc != nil { - // doc poc need minus one to get the first index of comment - start = int(imp.Doc.Pos()) - 1 - } else { - if imp.Name != nil { - // name pos need minus one too - start = int(imp.Name.Pos()) - 1 - } else { - // path pos start without quote, need minus one for it - start = int(imp.Path.Pos()) - 1 - } - } - - if imp.Name != nil { - name = imp.Name.Name - } - - if imp.Comment != nil { - end = int(imp.Comment.End()) - } else { - end = int(imp.Path.End()) - } - return -} - -func ParseFile(src []byte, filename string) (ImportList, int, int, int, int, error) { - fileSet := token.NewFileSet() - f, err := parser.ParseFile(fileSet, filename, src, parser.ParseComments) - if err != nil { - return nil, 0, 0, 0, 0, err - } - - if len(f.Imports) == 0 { - return nil, 0, 0, 0, 0, NoImportError{} - } - - var ( - // headEnd means the start of import block - headEnd int - // tailStart means the end + 1 of import block - tailStart int - // cStart means the start of C import block - cStart int - // cEnd means the end of C import block - cEnd int - data ImportList - ) - - for index, decl := range f.Decls { - switch decl.(type) { - // skip BadDecl and FuncDecl - case *ast.GenDecl: - genDecl := decl.(*ast.GenDecl) - - if genDecl.Tok == token.IMPORT { - // there are two cases, both end with linebreak: - // 1. - // import ( - // "xxxx" - // ) - // 2. - // import "xxx" - if headEnd == 0 { - headEnd = int(decl.Pos()) - 1 - } - tailStart = int(decl.End()) - if tailStart > len(src) { - tailStart = len(src) - } - - for _, spec := range genDecl.Specs { - imp := spec.(*ast.ImportSpec) - // there are only one C import block - // ensure C import block is the first import block - if imp.Path.Value == C { - /* - common case: - - // #include - import "C" - - notice that decl.Pos() == genDecl.Pos() > genDecl.Doc.Pos() - */ - if genDecl.Doc != nil { - cStart = int(genDecl.Doc.Pos()) - 1 - // if C import block is the first, update headEnd - if index == 0 { - headEnd = cStart - } - } else { - /* - special case: - - import "C" - */ - cStart = int(decl.Pos()) - 1 - } - - cEnd = int(decl.End()) - - continue - } - - start, end, name := getImports(imp) - - data = append(data, &GciImports{ - Start: start, - End: end, - Name: name, - Path: strings.Trim(imp.Path.Value, `"`), - }) - } - } - } - } - - sort.Sort(data) - return data, headEnd, tailStart, cStart, cEnd, nil -} - -// IsGeneratedFileByComment reports whether the source file is generated code. -// Using a bit laxer rules than https://golang.org/s/generatedcode to -// match more generated code. -// Taken from https://github.com/golangci/golangci-lint. -func IsGeneratedFileByComment(in string) bool { - const ( - genCodeGenerated = "code generated" - genDoNotEdit = "do not edit" - genAutoFile = "autogenerated file" // easyjson - genAutoGenerated = "automatically generated" // genny - ) - - markers := []string{genCodeGenerated, genDoNotEdit, genAutoFile, genAutoGenerated} - in = strings.ToLower(in) - for _, marker := range markers { - if strings.Contains(in, marker) { - return true - } - } - - return false -} - -type NoImportError struct{} - -func (n NoImportError) Error() string { - return "No imports" -} - -func (i NoImportError) Is(err error) bool { - _, ok := err.(NoImportError) - return ok -} diff --git a/vendor/github.com/daixiang0/gci/pkg/section/alias.go b/vendor/github.com/daixiang0/gci/pkg/section/alias.go deleted file mode 100644 index 423e96acf0..0000000000 --- a/vendor/github.com/daixiang0/gci/pkg/section/alias.go +++ /dev/null @@ -1,25 +0,0 @@ -package section - -import ( - "github.com/daixiang0/gci/pkg/parse" - "github.com/daixiang0/gci/pkg/specificity" -) - -type Alias struct{} - -const AliasType = "alias" - -func (b Alias) MatchSpecificity(spec *parse.GciImports) specificity.MatchSpecificity { - if spec.Name != "." && spec.Name != "_" && spec.Name != "" { - return specificity.NameMatch{} - } - return specificity.MisMatch{} -} - -func (b Alias) String() string { - return AliasType -} - -func (b Alias) Type() string { - return AliasType -} diff --git a/vendor/github.com/daixiang0/gci/pkg/section/blank.go b/vendor/github.com/daixiang0/gci/pkg/section/blank.go deleted file mode 100644 index 4a2741773d..0000000000 --- a/vendor/github.com/daixiang0/gci/pkg/section/blank.go +++ /dev/null @@ -1,25 +0,0 @@ -package section - -import ( - "github.com/daixiang0/gci/pkg/parse" - "github.com/daixiang0/gci/pkg/specificity" -) - -type Blank struct{} - -const BlankType = "blank" - -func (b Blank) MatchSpecificity(spec *parse.GciImports) specificity.MatchSpecificity { - if spec.Name == "_" { - return specificity.NameMatch{} - } - return specificity.MisMatch{} -} - -func (b Blank) String() string { - return BlankType -} - -func (b Blank) Type() string { - return BlankType -} diff --git a/vendor/github.com/daixiang0/gci/pkg/section/commentline.go b/vendor/github.com/daixiang0/gci/pkg/section/commentline.go deleted file mode 100644 index c3ddd08249..0000000000 --- a/vendor/github.com/daixiang0/gci/pkg/section/commentline.go +++ /dev/null @@ -1,24 +0,0 @@ -package section - -import ( - "fmt" - - "github.com/daixiang0/gci/pkg/parse" - "github.com/daixiang0/gci/pkg/specificity" -) - -type CommentLine struct { - Comment string -} - -func (c CommentLine) MatchSpecificity(spec *parse.GciImports) specificity.MatchSpecificity { - return specificity.MisMatch{} -} - -func (c CommentLine) String() string { - return fmt.Sprintf("commentline(%s)", c.Comment) -} - -func (c CommentLine) Type() string { - return "commentline" -} diff --git a/vendor/github.com/daixiang0/gci/pkg/section/default.go b/vendor/github.com/daixiang0/gci/pkg/section/default.go deleted file mode 100644 index 3af07a0927..0000000000 --- a/vendor/github.com/daixiang0/gci/pkg/section/default.go +++ /dev/null @@ -1,22 +0,0 @@ -package section - -import ( - "github.com/daixiang0/gci/pkg/parse" - "github.com/daixiang0/gci/pkg/specificity" -) - -const DefaultType = "default" - -type Default struct{} - -func (d Default) MatchSpecificity(spec *parse.GciImports) specificity.MatchSpecificity { - return specificity.Default{} -} - -func (d Default) String() string { - return DefaultType -} - -func (d Default) Type() string { - return DefaultType -} diff --git a/vendor/github.com/daixiang0/gci/pkg/section/dot.go b/vendor/github.com/daixiang0/gci/pkg/section/dot.go deleted file mode 100644 index 8112eeb1dc..0000000000 --- a/vendor/github.com/daixiang0/gci/pkg/section/dot.go +++ /dev/null @@ -1,25 +0,0 @@ -package section - -import ( - "github.com/daixiang0/gci/pkg/parse" - "github.com/daixiang0/gci/pkg/specificity" -) - -type Dot struct{} - -const DotType = "dot" - -func (d Dot) MatchSpecificity(spec *parse.GciImports) specificity.MatchSpecificity { - if spec.Name == "." { - return specificity.NameMatch{} - } - return specificity.MisMatch{} -} - -func (d Dot) String() string { - return DotType -} - -func (d Dot) Type() string { - return DotType -} diff --git a/vendor/github.com/daixiang0/gci/pkg/section/errors.go b/vendor/github.com/daixiang0/gci/pkg/section/errors.go deleted file mode 100644 index 0a12091356..0000000000 --- a/vendor/github.com/daixiang0/gci/pkg/section/errors.go +++ /dev/null @@ -1,107 +0,0 @@ -package section - -import ( - "errors" - "fmt" - - "github.com/daixiang0/gci/pkg/parse" - "github.com/daixiang0/gci/pkg/utils" -) - -type SectionParsingError struct { - error -} - -func (s SectionParsingError) Unwrap() error { - return s.error -} - -func (s SectionParsingError) Wrap(sectionStr string) error { - return fmt.Errorf("failed to parse section %q: %w", sectionStr, s) -} - -func (s SectionParsingError) Is(err error) bool { - _, ok := err.(SectionParsingError) - return ok -} - -var MissingParameterClosingBracketsError = fmt.Errorf("section parameter is missing closing %q", utils.RightParenthesis) - -var MoreThanOneOpeningQuotesError = fmt.Errorf("found more than one %q parameter start sequences", utils.RightParenthesis) - -var SectionTypeDoesNotAcceptParametersError = errors.New("section type does not accept a parameter") - -var SectionTypeDoesNotAcceptPrefixError = errors.New("section may not contain a Prefix") - -var SectionTypeDoesNotAcceptSuffixError = errors.New("section may not contain a Suffix") - -type EqualSpecificityMatchError struct { - Imports *parse.GciImports - SectionA, SectionB Section -} - -func (e EqualSpecificityMatchError) Error() string { - return fmt.Sprintf("Import %v matched section %s and %s equally", e.Imports, e.SectionA, e.SectionB) -} - -func (e EqualSpecificityMatchError) Is(err error) bool { - _, ok := err.(EqualSpecificityMatchError) - return ok -} - -type NoMatchingSectionForImportError struct { - Imports *parse.GciImports -} - -func (n NoMatchingSectionForImportError) Error() string { - return fmt.Sprintf("No section found for Import: %v", n.Imports) -} - -func (n NoMatchingSectionForImportError) Is(err error) bool { - _, ok := err.(NoMatchingSectionForImportError) - return ok -} - -type InvalidImportSplitError struct { - segments []string -} - -func (i InvalidImportSplitError) Error() string { - return fmt.Sprintf("separating the inline comment from the import yielded an invalid number of segments: %v", i.segments) -} - -func (i InvalidImportSplitError) Is(err error) bool { - _, ok := err.(InvalidImportSplitError) - return ok -} - -type InvalidAliasSplitError struct { - segments []string -} - -func (i InvalidAliasSplitError) Error() string { - return fmt.Sprintf("separating the alias from the path yielded an invalid number of segments: %v", i.segments) -} - -func (i InvalidAliasSplitError) Is(err error) bool { - _, ok := err.(InvalidAliasSplitError) - return ok -} - -var ( - MissingImportStatementError = FileParsingError{errors.New("no import statement present in File")} - ImportStatementNotClosedError = FileParsingError{errors.New("import statement not closed")} -) - -type FileParsingError struct { - error -} - -func (f FileParsingError) Unwrap() error { - return f.error -} - -func (f FileParsingError) Is(err error) bool { - _, ok := err.(FileParsingError) - return ok -} diff --git a/vendor/github.com/daixiang0/gci/pkg/section/local_module.go b/vendor/github.com/daixiang0/gci/pkg/section/local_module.go deleted file mode 100644 index 50f41e5017..0000000000 --- a/vendor/github.com/daixiang0/gci/pkg/section/local_module.go +++ /dev/null @@ -1,59 +0,0 @@ -package section - -import ( - "fmt" - "os" - "strings" - - "golang.org/x/mod/modfile" - - "github.com/daixiang0/gci/pkg/parse" - "github.com/daixiang0/gci/pkg/specificity" -) - -const LocalModuleType = "localmodule" - -type LocalModule struct { - Path string -} - -func (m *LocalModule) MatchSpecificity(spec *parse.GciImports) specificity.MatchSpecificity { - if spec.Path == m.Path || strings.HasPrefix(spec.Path, m.Path+"/") { - return specificity.LocalModule{} - } - - return specificity.MisMatch{} -} - -func (m *LocalModule) String() string { - return LocalModuleType -} - -func (m *LocalModule) Type() string { - return LocalModuleType -} - -// Configure configures the module section by finding the module -// for the current path -func (m *LocalModule) Configure(path string) error { - if path != "" { - m.Path = path - } else { - path, err := findLocalModule() - if err != nil { - return fmt.Errorf("finding local modules for `localModule` configuration: %w", err) - } - m.Path = path - } - - return nil -} - -func findLocalModule() (string, error) { - b, err := os.ReadFile("go.mod") - if err != nil { - return "", fmt.Errorf("reading go.mod: %w", err) - } - - return modfile.ModulePath(b), nil -} diff --git a/vendor/github.com/daixiang0/gci/pkg/section/newline.go b/vendor/github.com/daixiang0/gci/pkg/section/newline.go deleted file mode 100644 index 4bff91b9d4..0000000000 --- a/vendor/github.com/daixiang0/gci/pkg/section/newline.go +++ /dev/null @@ -1,22 +0,0 @@ -package section - -import ( - "github.com/daixiang0/gci/pkg/parse" - "github.com/daixiang0/gci/pkg/specificity" -) - -const newLineName = "newline" - -type NewLine struct{} - -func (n NewLine) MatchSpecificity(spec *parse.GciImports) specificity.MatchSpecificity { - return specificity.MisMatch{} -} - -func (n NewLine) String() string { - return newLineName -} - -func (n NewLine) Type() string { - return newLineName -} diff --git a/vendor/github.com/daixiang0/gci/pkg/section/parser.go b/vendor/github.com/daixiang0/gci/pkg/section/parser.go deleted file mode 100644 index 62ed1582af..0000000000 --- a/vendor/github.com/daixiang0/gci/pkg/section/parser.go +++ /dev/null @@ -1,49 +0,0 @@ -package section - -import ( - "errors" - "fmt" - "strings" -) - -func Parse(data []string) (SectionList, error) { - if len(data) == 0 { - return nil, nil - } - - var list SectionList - var errString string - for _, d := range data { - s := strings.ToLower(d) - if len(s) == 0 { - return nil, nil - } - - if s == "default" { - list = append(list, Default{}) - } else if s == "standard" { - list = append(list, Standard{}) - } else if s == "newline" { - list = append(list, NewLine{}) - } else if strings.HasPrefix(s, "prefix(") && len(d) > 8 { - list = append(list, Custom{d[7 : len(d)-1]}) - } else if strings.HasPrefix(s, "commentline(") && len(d) > 13 { - list = append(list, Custom{d[12 : len(d)-1]}) - } else if s == "dot" { - list = append(list, Dot{}) - } else if s == "blank" { - list = append(list, Blank{}) - } else if s == "alias" { - list = append(list, Alias{}) - } else if s == "localmodule" { - // pointer because we need to mutate the section at configuration time - list = append(list, &LocalModule{}) - } else { - errString += fmt.Sprintf(" %s", s) - } - } - if errString != "" { - return nil, errors.New(fmt.Sprintf("invalid params:%s", errString)) - } - return list, nil -} diff --git a/vendor/github.com/daixiang0/gci/pkg/section/prefix.go b/vendor/github.com/daixiang0/gci/pkg/section/prefix.go deleted file mode 100644 index 30bdd8f4ea..0000000000 --- a/vendor/github.com/daixiang0/gci/pkg/section/prefix.go +++ /dev/null @@ -1,38 +0,0 @@ -package section - -import ( - "fmt" - "strings" - - "github.com/daixiang0/gci/pkg/parse" - "github.com/daixiang0/gci/pkg/specificity" -) - -type Custom struct { - Prefix string -} - -// CustomSeparator allows you to group multiple custom prefix together in the same section -// gci diff -s standard -s default -s prefix(github.com/company,gitlab.com/company,companysuffix) -const CustomSeparator = "," - -const CustomType = "custom" - -func (c Custom) MatchSpecificity(spec *parse.GciImports) specificity.MatchSpecificity { - for _, prefix := range strings.Split(c.Prefix, CustomSeparator) { - prefix = strings.TrimSpace(prefix) - if strings.HasPrefix(spec.Path, prefix) { - return specificity.Match{Length: len(prefix)} - } - } - - return specificity.MisMatch{} -} - -func (c Custom) String() string { - return fmt.Sprintf("prefix(%s)", c.Prefix) -} - -func (c Custom) Type() string { - return CustomType -} diff --git a/vendor/github.com/daixiang0/gci/pkg/section/section.go b/vendor/github.com/daixiang0/gci/pkg/section/section.go deleted file mode 100644 index cc0a43f2f1..0000000000 --- a/vendor/github.com/daixiang0/gci/pkg/section/section.go +++ /dev/null @@ -1,36 +0,0 @@ -package section - -import ( - "github.com/daixiang0/gci/pkg/parse" - "github.com/daixiang0/gci/pkg/specificity" -) - -// Section defines a part of the formatted output. -type Section interface { - // MatchSpecificity returns how well an Import matches to this Section - MatchSpecificity(spec *parse.GciImports) specificity.MatchSpecificity - - // String Implements the stringer interface - String() string - - // return section type - Type() string -} - -type SectionList []Section - -func (list SectionList) String() []string { - var output []string - for _, section := range list { - output = append(output, section.String()) - } - return output -} - -func DefaultSections() SectionList { - return SectionList{Standard{}, Default{}} -} - -func DefaultSectionSeparators() SectionList { - return SectionList{NewLine{}} -} diff --git a/vendor/github.com/daixiang0/gci/pkg/section/standard.go b/vendor/github.com/daixiang0/gci/pkg/section/standard.go deleted file mode 100644 index 26c7e9dc7d..0000000000 --- a/vendor/github.com/daixiang0/gci/pkg/section/standard.go +++ /dev/null @@ -1,30 +0,0 @@ -package section - -import ( - "github.com/daixiang0/gci/pkg/parse" - "github.com/daixiang0/gci/pkg/specificity" -) - -const StandardType = "standard" - -type Standard struct{} - -func (s Standard) MatchSpecificity(spec *parse.GciImports) specificity.MatchSpecificity { - if isStandard(spec.Path) { - return specificity.StandardMatch{} - } - return specificity.MisMatch{} -} - -func (s Standard) String() string { - return StandardType -} - -func (s Standard) Type() string { - return StandardType -} - -func isStandard(pkg string) bool { - _, ok := standardPackages[pkg] - return ok -} diff --git a/vendor/github.com/daixiang0/gci/pkg/section/standard_list.go b/vendor/github.com/daixiang0/gci/pkg/section/standard_list.go deleted file mode 100644 index 34cf38cec5..0000000000 --- a/vendor/github.com/daixiang0/gci/pkg/section/standard_list.go +++ /dev/null @@ -1,185 +0,0 @@ -package section - -// Code generated based on go1.25rc1 X:boringcrypto,arenas,synctest,jsonv2. DO NOT EDIT. - -var standardPackages = map[string]struct{}{ - "archive/tar": {}, - "archive/zip": {}, - "arena": {}, - "bufio": {}, - "bytes": {}, - "cmp": {}, - "compress/bzip2": {}, - "compress/flate": {}, - "compress/gzip": {}, - "compress/lzw": {}, - "compress/zlib": {}, - "container/heap": {}, - "container/list": {}, - "container/ring": {}, - "context": {}, - "crypto": {}, - "crypto/aes": {}, - "crypto/boring": {}, - "crypto/cipher": {}, - "crypto/des": {}, - "crypto/dsa": {}, - "crypto/ecdh": {}, - "crypto/ecdsa": {}, - "crypto/ed25519": {}, - "crypto/elliptic": {}, - "crypto/fips140": {}, - "crypto/hkdf": {}, - "crypto/hmac": {}, - "crypto/md5": {}, - "crypto/mlkem": {}, - "crypto/pbkdf2": {}, - "crypto/rand": {}, - "crypto/rc4": {}, - "crypto/rsa": {}, - "crypto/sha1": {}, - "crypto/sha256": {}, - "crypto/sha3": {}, - "crypto/sha512": {}, - "crypto/subtle": {}, - "crypto/tls": {}, - "crypto/tls/fipsonly": {}, - "crypto/x509": {}, - "crypto/x509/pkix": {}, - "database/sql": {}, - "database/sql/driver": {}, - "debug/buildinfo": {}, - "debug/dwarf": {}, - "debug/elf": {}, - "debug/gosym": {}, - "debug/macho": {}, - "debug/pe": {}, - "debug/plan9obj": {}, - "embed": {}, - "encoding": {}, - "encoding/ascii85": {}, - "encoding/asn1": {}, - "encoding/base32": {}, - "encoding/base64": {}, - "encoding/binary": {}, - "encoding/csv": {}, - "encoding/gob": {}, - "encoding/hex": {}, - "encoding/json": {}, - "encoding/json/jsontext": {}, - "encoding/json/v2": {}, - "encoding/pem": {}, - "encoding/xml": {}, - "errors": {}, - "expvar": {}, - "flag": {}, - "fmt": {}, - "go/ast": {}, - "go/build": {}, - "go/build/constraint": {}, - "go/constant": {}, - "go/doc": {}, - "go/doc/comment": {}, - "go/format": {}, - "go/importer": {}, - "go/parser": {}, - "go/printer": {}, - "go/scanner": {}, - "go/token": {}, - "go/types": {}, - "go/version": {}, - "hash": {}, - "hash/adler32": {}, - "hash/crc32": {}, - "hash/crc64": {}, - "hash/fnv": {}, - "hash/maphash": {}, - "html": {}, - "html/template": {}, - "image": {}, - "image/color": {}, - "image/color/palette": {}, - "image/draw": {}, - "image/gif": {}, - "image/jpeg": {}, - "image/png": {}, - "index/suffixarray": {}, - "io": {}, - "io/fs": {}, - "io/ioutil": {}, - "iter": {}, - "log": {}, - "log/slog": {}, - "log/syslog": {}, - "maps": {}, - "math": {}, - "math/big": {}, - "math/bits": {}, - "math/cmplx": {}, - "math/rand": {}, - "math/rand/v2": {}, - "mime": {}, - "mime/multipart": {}, - "mime/quotedprintable": {}, - "net": {}, - "net/http": {}, - "net/http/cgi": {}, - "net/http/cookiejar": {}, - "net/http/fcgi": {}, - "net/http/httptest": {}, - "net/http/httptrace": {}, - "net/http/httputil": {}, - "net/http/pprof": {}, - "net/mail": {}, - "net/netip": {}, - "net/rpc": {}, - "net/rpc/jsonrpc": {}, - "net/smtp": {}, - "net/textproto": {}, - "net/url": {}, - "os": {}, - "os/exec": {}, - "os/signal": {}, - "os/user": {}, - "path": {}, - "path/filepath": {}, - "plugin": {}, - "reflect": {}, - "regexp": {}, - "regexp/syntax": {}, - "runtime": {}, - "runtime/cgo": {}, - "runtime/coverage": {}, - "runtime/debug": {}, - "runtime/metrics": {}, - "runtime/pprof": {}, - "runtime/race": {}, - "runtime/trace": {}, - "slices": {}, - "sort": {}, - "strconv": {}, - "strings": {}, - "structs": {}, - "sync": {}, - "sync/atomic": {}, - "syscall": {}, - "syscall/js": {}, - "testing": {}, - "testing/fstest": {}, - "testing/iotest": {}, - "testing/quick": {}, - "testing/slogtest": {}, - "testing/synctest": {}, - "text/scanner": {}, - "text/tabwriter": {}, - "text/template": {}, - "text/template/parse": {}, - "time": {}, - "time/tzdata": {}, - "unicode": {}, - "unicode/utf16": {}, - "unicode/utf8": {}, - "unique": {}, - "unsafe": {}, - "weak": {}, -} diff --git a/vendor/github.com/daixiang0/gci/pkg/specificity/default.go b/vendor/github.com/daixiang0/gci/pkg/specificity/default.go deleted file mode 100644 index f7ae4b87bc..0000000000 --- a/vendor/github.com/daixiang0/gci/pkg/specificity/default.go +++ /dev/null @@ -1,19 +0,0 @@ -package specificity - -type Default struct{} - -func (d Default) IsMoreSpecific(than MatchSpecificity) bool { - return isMoreSpecific(d, than) -} - -func (d Default) Equal(to MatchSpecificity) bool { - return equalSpecificity(d, to) -} - -func (d Default) class() specificityClass { - return DefaultClass -} - -func (d Default) String() string { - return "Default" -} diff --git a/vendor/github.com/daixiang0/gci/pkg/specificity/local_module.go b/vendor/github.com/daixiang0/gci/pkg/specificity/local_module.go deleted file mode 100644 index ae482fec47..0000000000 --- a/vendor/github.com/daixiang0/gci/pkg/specificity/local_module.go +++ /dev/null @@ -1,15 +0,0 @@ -package specificity - -type LocalModule struct{} - -func (m LocalModule) IsMoreSpecific(than MatchSpecificity) bool { - return isMoreSpecific(m, than) -} - -func (m LocalModule) Equal(to MatchSpecificity) bool { - return equalSpecificity(m, to) -} - -func (LocalModule) class() specificityClass { - return LocalModuleClass -} diff --git a/vendor/github.com/daixiang0/gci/pkg/specificity/match.go b/vendor/github.com/daixiang0/gci/pkg/specificity/match.go deleted file mode 100644 index f08d2b66bb..0000000000 --- a/vendor/github.com/daixiang0/gci/pkg/specificity/match.go +++ /dev/null @@ -1,24 +0,0 @@ -package specificity - -import "fmt" - -type Match struct { - Length int -} - -func (m Match) IsMoreSpecific(than MatchSpecificity) bool { - otherMatch, isMatch := than.(Match) - return isMoreSpecific(m, than) || (isMatch && m.Length > otherMatch.Length) -} - -func (m Match) Equal(to MatchSpecificity) bool { - return equalSpecificity(m, to) -} - -func (m Match) class() specificityClass { - return MatchClass -} - -func (m Match) String() string { - return fmt.Sprintf("Match(length: %d)", m.Length) -} diff --git a/vendor/github.com/daixiang0/gci/pkg/specificity/mismatch.go b/vendor/github.com/daixiang0/gci/pkg/specificity/mismatch.go deleted file mode 100644 index 8e87111461..0000000000 --- a/vendor/github.com/daixiang0/gci/pkg/specificity/mismatch.go +++ /dev/null @@ -1,19 +0,0 @@ -package specificity - -type MisMatch struct{} - -func (m MisMatch) IsMoreSpecific(than MatchSpecificity) bool { - return isMoreSpecific(m, than) -} - -func (m MisMatch) Equal(to MatchSpecificity) bool { - return equalSpecificity(m, to) -} - -func (m MisMatch) class() specificityClass { - return MisMatchClass -} - -func (m MisMatch) String() string { - return "Mismatch" -} diff --git a/vendor/github.com/daixiang0/gci/pkg/specificity/name.go b/vendor/github.com/daixiang0/gci/pkg/specificity/name.go deleted file mode 100644 index 1900a0ac5d..0000000000 --- a/vendor/github.com/daixiang0/gci/pkg/specificity/name.go +++ /dev/null @@ -1,19 +0,0 @@ -package specificity - -type NameMatch struct{} - -func (n NameMatch) IsMoreSpecific(than MatchSpecificity) bool { - return isMoreSpecific(n, than) -} - -func (n NameMatch) Equal(to MatchSpecificity) bool { - return equalSpecificity(n, to) -} - -func (n NameMatch) class() specificityClass { - return NameClass -} - -func (n NameMatch) String() string { - return "Name" -} diff --git a/vendor/github.com/daixiang0/gci/pkg/specificity/specificity.go b/vendor/github.com/daixiang0/gci/pkg/specificity/specificity.go deleted file mode 100644 index 4a188b3bb4..0000000000 --- a/vendor/github.com/daixiang0/gci/pkg/specificity/specificity.go +++ /dev/null @@ -1,28 +0,0 @@ -package specificity - -type specificityClass int - -const ( - MisMatchClass = 0 - DefaultClass = 10 - StandardClass = 20 - MatchClass = 30 - NameClass = 40 - LocalModuleClass = 50 -) - -// MatchSpecificity is used to determine which section matches an import best -type MatchSpecificity interface { - IsMoreSpecific(than MatchSpecificity) bool - Equal(to MatchSpecificity) bool - class() specificityClass -} - -func isMoreSpecific(this, than MatchSpecificity) bool { - return this.class() > than.class() -} - -func equalSpecificity(base, to MatchSpecificity) bool { - // m.class() == to.class() would not work for Match - return !base.IsMoreSpecific(to) && !to.IsMoreSpecific(base) -} diff --git a/vendor/github.com/daixiang0/gci/pkg/specificity/standard.go b/vendor/github.com/daixiang0/gci/pkg/specificity/standard.go deleted file mode 100644 index 72ccaf7e1e..0000000000 --- a/vendor/github.com/daixiang0/gci/pkg/specificity/standard.go +++ /dev/null @@ -1,19 +0,0 @@ -package specificity - -type StandardMatch struct{} - -func (s StandardMatch) IsMoreSpecific(than MatchSpecificity) bool { - return isMoreSpecific(s, than) -} - -func (s StandardMatch) Equal(to MatchSpecificity) bool { - return equalSpecificity(s, to) -} - -func (s StandardMatch) class() specificityClass { - return StandardClass -} - -func (s StandardMatch) String() string { - return "Standard" -} diff --git a/vendor/github.com/daixiang0/gci/pkg/utils/constants.go b/vendor/github.com/daixiang0/gci/pkg/utils/constants.go deleted file mode 100644 index 2fafbc32cc..0000000000 --- a/vendor/github.com/daixiang0/gci/pkg/utils/constants.go +++ /dev/null @@ -1,12 +0,0 @@ -package utils - -const ( - Indent = '\t' - Linebreak = '\n' - WinLinebreak = '\r' - - Colon = ":" - - LeftParenthesis = '(' - RightParenthesis = ')' -) diff --git a/vendor/github.com/dave/dst/.gitignore b/vendor/github.com/dave/dst/.gitignore deleted file mode 100644 index 5a391e10f6..0000000000 --- a/vendor/github.com/dave/dst/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -*.iml -.DS_Store -.idea/ -coverage.out diff --git a/vendor/github.com/dave/dst/.travis.yml b/vendor/github.com/dave/dst/.travis.yml deleted file mode 100644 index f2af053272..0000000000 --- a/vendor/github.com/dave/dst/.travis.yml +++ /dev/null @@ -1,15 +0,0 @@ -language: go -go: - - 1.x -notificaitons: - email: - recipients: dave@brophy.uk - on_failure: always -install: -# - go get -u github.com/dave/courtney - - go get -t -v ./... -script: - - go test ./... -# - courtney -v -timeout 20m -#after_success: -# - bash <(curl -s https://codecov.io/bash) diff --git a/vendor/github.com/dave/dst/LICENSE b/vendor/github.com/dave/dst/LICENSE deleted file mode 100644 index 95bfa5bed1..0000000000 --- a/vendor/github.com/dave/dst/LICENSE +++ /dev/null @@ -1,51 +0,0 @@ -MIT License - -Copyright (c) 2018 David Brophy - -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. - -This package was forked from https://github.com/golang/go/tree/master/src/go/ast - original license: - -Copyright (c) 2009 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/vendor/github.com/dave/dst/README.md b/vendor/github.com/dave/dst/README.md deleted file mode 100644 index 337781b868..0000000000 --- a/vendor/github.com/dave/dst/README.md +++ /dev/null @@ -1,706 +0,0 @@ -[![Build Status](https://travis-ci.org/dave/dst.svg?branch=master)](https://travis-ci.org/dave/dst) -[![Documentation](https://img.shields.io/badge/godoc-documentation-brightgreen.svg)](https://godoc.org/github.com/dave/dst/decorator) -[![codecov](https://img.shields.io/badge/codecov-92%25-brightgreen.svg)](https://codecov.io/gh/dave/dst) -![stability-stable](https://img.shields.io/badge/stability-stable-brightgreen.svg) -[![Sourcegraph](https://sourcegraph.com/github.com/dave/dst/-/badge.svg)](https://sourcegraph.com/github.com/dave/dst?badge) - -# Decorated Syntax Tree - -The `dst` package enables manipulation of a Go syntax tree with high fidelity. Decorations (e.g. -comments and line spacing) remain attached to the correct nodes as the tree is modified. - -## Where does `go/ast` break? - -The `go/ast` package wasn't created with source manipulation as an intended use-case. Comments are -stored by their byte offset instead of attached to nodes, so re-arranging nodes breaks the output. -See [this Go issue](https://github.com/golang/go/issues/20744) for more information. - -Consider this example where we want to reverse the order of the two statements. As you can see the -comments don't remain attached to the correct nodes: - -```go -code := `package a - -func main(){ - var a int // foo - var b string // bar -} -` -fset := token.NewFileSet() -f, err := parser.ParseFile(fset, "", code, parser.ParseComments) -if err != nil { - panic(err) -} - -list := f.Decls[0].(*ast.FuncDecl).Body.List -list[0], list[1] = list[1], list[0] - -if err := format.Node(os.Stdout, fset, f); err != nil { - panic(err) -} - -//Output: -//package a -// -//func main() { -// // foo -// var b string -// var a int -// // bar -//} -``` - -Here's the same example using `dst`: - -```go -code := `package a - -func main(){ - var a int // foo - var b string // bar -} -` -f, err := decorator.Parse(code) -if err != nil { - panic(err) -} - -list := f.Decls[0].(*dst.FuncDecl).Body.List -list[0], list[1] = list[1], list[0] - -if err := decorator.Print(f); err != nil { - panic(err) -} - -//Output: -//package a -// -//func main() { -// var b string // bar -// var a int // foo -//} -``` - -## Usage - -Parsing a source file to `dst` and printing the results after modification can be accomplished with -several `Parse` and `Print` convenience functions in the [decorator](https://godoc.org/github.com/dave/dst/decorator) -package. - -For more fine-grained control you can use [Decorator](https://godoc.org/github.com/dave/dst/decorator#Decorator) -to convert from `ast` to `dst`, and [Restorer](https://godoc.org/github.com/dave/dst/decorator#Restorer) -to convert back again. - -### Comments - -Comments are added at decoration attachment points. [See here](https://github.com/dave/dst/blob/master/decorations-types-generated.go) -for a full list of these points, along with demonstration code of where they are rendered in the -output. - -The decoration attachment points have convenience functions `Append`, `Prepend`, `Replace`, `Clear` -and `All` to accomplish common tasks. Use the full text of your comment including the `//` or `/**/` -markers. When adding a line comment, a newline is automatically rendered. - -```go -code := `package main - -func main() { - println("Hello World!") -}` -f, err := decorator.Parse(code) -if err != nil { - panic(err) -} - -call := f.Decls[0].(*dst.FuncDecl).Body.List[0].(*dst.ExprStmt).X.(*dst.CallExpr) - -call.Decs.Start.Append("// you can add comments at the start...") -call.Decs.Fun.Append("/* ...in the middle... */") -call.Decs.End.Append("// or at the end.") - -if err := decorator.Print(f); err != nil { - panic(err) -} - -//Output: -//package main -// -//func main() { -// // you can add comments at the start... -// println /* ...in the middle... */ ("Hello World!") // or at the end. -//} -``` - -### Spacing - -The `Before` property marks the node as having a line space (new line or empty line) before the node. -These spaces are rendered before any decorations attached to the `Start` decoration point. The `After` -property is similar but rendered after the node (and after any `End` decorations). - -```go -code := `package main - -func main() { - println(a, b, c) -}` -f, err := decorator.Parse(code) -if err != nil { - panic(err) -} - -call := f.Decls[0].(*dst.FuncDecl).Body.List[0].(*dst.ExprStmt).X.(*dst.CallExpr) - -call.Decs.Before = dst.EmptyLine -call.Decs.After = dst.EmptyLine - -for _, v := range call.Args { - v := v.(*dst.Ident) - v.Decs.Before = dst.NewLine - v.Decs.After = dst.NewLine -} - -if err := decorator.Print(f); err != nil { - panic(err) -} - -//Output: -//package main -// -//func main() { -// -// println( -// a, -// b, -// c, -// ) -// -//} -``` - -### Decorations - -The common decoration properties (`Start`, `End`, `Before` and `After`) occur on all nodes, and can be -accessed with the `Decorations()` method on the `Node` interface: - -```go -code := `package main - -func main() { - var i int - i++ - println(i) -}` -f, err := decorator.Parse(code) -if err != nil { - panic(err) -} - -list := f.Decls[0].(*dst.FuncDecl).Body.List - -list[0].Decorations().Before = dst.EmptyLine -list[0].Decorations().End.Append("// the Decorations method allows access to the common") -list[1].Decorations().End.Append("// decoration properties (Before, Start, End and After)") -list[2].Decorations().End.Append("// for all nodes.") -list[2].Decorations().After = dst.EmptyLine - -if err := decorator.Print(f); err != nil { - panic(err) -} - -//Output: -//package main -// -//func main() { -// -// var i int // the Decorations method allows access to the common -// i++ // decoration properties (Before, Start, End and After) -// println(i) // for all nodes. -// -//} -``` - -#### dstutil.Decorations - -While debugging, it is often useful to have a list of all decorations attached to a node. The -[dstutil](https://github.com/dave/dst/tree/master/dstutil) package provides a helper function `Decorations` which -returns a list of the attachment points and all decorations for any node: - -```go -code := `package main - -// main comment -// is multi line -func main() { - - if true { - - // foo - println( /* foo inline */ "foo") - } else if false { - println /* bar inline */ ("bar") - - // bar after - - } else { - // empty block - } -}` - -f, err := decorator.Parse(code) -if err != nil { - panic(err) -} - -dst.Inspect(f, func(node dst.Node) bool { - if node == nil { - return false - } - before, after, points := dstutil.Decorations(node) - var info string - if before != dst.None { - info += fmt.Sprintf("- Before: %s\n", before) - } - for _, point := range points { - if len(point.Decs) == 0 { - continue - } - info += fmt.Sprintf("- %s: [", point.Name) - for i, dec := range point.Decs { - if i > 0 { - info += ", " - } - info += fmt.Sprintf("%q", dec) - } - info += "]\n" - } - if after != dst.None { - info += fmt.Sprintf("- After: %s\n", after) - } - if info != "" { - fmt.Printf("%T\n%s\n", node, info) - } - return true -}) - -//Output: -//*dst.FuncDecl -//- Before: NewLine -//- Start: ["// main comment", "// is multi line"] -// -//*dst.IfStmt -//- Before: NewLine -//- After: NewLine -// -//*dst.ExprStmt -//- Before: NewLine -//- Start: ["// foo"] -//- After: NewLine -// -//*dst.CallExpr -//- Lparen: ["/* foo inline */"] -// -//*dst.ExprStmt -//- Before: NewLine -//- End: ["\n", "\n", "// bar after"] -//- After: NewLine -// -//*dst.CallExpr -//- Fun: ["/* bar inline */"] -// -//*dst.BlockStmt -//- Lbrace: ["\n", "// empty block"] -``` - -### Newlines - -The `Before` and `After` properties cover the majority of cases, but occasionally a newline needs to -be rendered inside a node. Simply add a `\n` decoration to accomplish this. - -### Clone - -Re-using an existing node elsewhere in the tree will panic when the tree is restored to `ast`. Instead, -use the `Clone` function to make a deep copy of the node before re-use: - -```go -code := `package main - -var i /* a */ int` - -f, err := decorator.Parse(code) -if err != nil { - panic(err) -} - -cloned := dst.Clone(f.Decls[0]).(*dst.GenDecl) - -cloned.Decs.Before = dst.NewLine -cloned.Specs[0].(*dst.ValueSpec).Names[0].Name = "j" -cloned.Specs[0].(*dst.ValueSpec).Names[0].Decs.End.Replace("/* b */") - -f.Decls = append(f.Decls, cloned) - -if err := decorator.Print(f); err != nil { - panic(err) -} - -//Output: -//package main -// -//var i /* a */ int -//var j /* b */ int -``` - -### Apply - -The [dstutil](https://github.com/dave/dst/tree/master/dstutil) package is a fork of `golang.org/x/tools/go/ast/astutil`, -and provides the `Apply` function with similar semantics. - -### Imports - -The decorator can automatically manage the `import` block, which is a non-trivial task. - -Use [NewDecoratorWithImports](https://godoc.org/github.com/dave/dst/decorator#NewDecoratorWithImports) -and [NewRestorerWithImports](https://godoc.org/github.com/dave/dst/decorator#NewRestorerWithImports) -to create an import aware decorator / restorer. - -During decoration, remote identifiers are normalised - `*ast.SelectorExpr` nodes that represent -qualified identifiers are replaced with `*dst.Ident` nodes with the `Path` field set to the path of -the imported package. - -When adding a qualified identifier node, there is no need to use `*dst.SelectorExpr` - just add a -`*dst.Ident` and set `Path` to the imported package path. The restorer will wrap it in a -`*ast.SelectorExpr` where appropriate when converting back to ast, and also update the import -block. - -To enable import management, the decorator must be able to resolve the imported package for -selector expressions and identifiers, and the restorer must be able to resolve the name of a -package given it's path. Several implementations for these resolvers are provided, and the best -method will depend on the environment. [See below](#resolvers) for more details. - -### Load - -The [Load](https://godoc.org/github.com/dave/dst/decorator#Load) convenience function uses -`go/packages` to load packages and decorate all loaded ast files, with import management enabled: - -```go -// Create a simple module in a temporary directory -dir, err := tempDir(map[string]string{ - "go.mod": "module root", - "main.go": "package main \n\n func main() {}", -}) -defer os.RemoveAll(dir) -if err != nil { - panic(err) -} - -// Use the Load convenience function that calls go/packages to load the package. All loaded -// ast files are decorated to dst. -pkgs, err := decorator.Load(&packages.Config{Dir: dir, Mode: packages.LoadSyntax}, "root") -if err != nil { - panic(err) -} -p := pkgs[0] -f := p.Syntax[0] - -// Add a call expression. Note we don't have to use a SelectorExpr - just adding an Ident with -// the imported package path will do. The restorer will add SelectorExpr where appropriate when -// converting back to ast. Note the new Path field on *dst.Ident. Set this to the package path -// of the imported package, and the restorer will automatically add the import to the import -// block. -b := f.Decls[0].(*dst.FuncDecl).Body -b.List = append(b.List, &dst.ExprStmt{ - X: &dst.CallExpr{ - Fun: &dst.Ident{Path: "fmt", Name: "Println"}, - Args: []dst.Expr{ - &dst.BasicLit{Kind: token.STRING, Value: strconv.Quote("Hello, World!")}, - }, - }, -}) - -// Create a restorer with the import manager enabled, and print the result. As you can see, the -// import block is automatically managed, and the Println ident is converted to a SelectorExpr: -r := decorator.NewRestorerWithImports("root", gopackages.New(dir)) -if err := r.Print(p.Syntax[0]); err != nil { - panic(err) -} - -//Output: -//package main -// -//import "fmt" -// -//func main() { fmt.Println("Hello, World!") } -``` - -### Mappings - -The decorator exposes `Dst.Nodes` and `Ast.Nodes` which map between `ast.Node` and `dst.Node`. This -enables systems that refer to `ast` nodes (such as `go/types`) to be used: - -```go -code := `package main - -func main() { - var i int - i++ - println(i) -}` - -// Parse the code to AST -fset := token.NewFileSet() -astFile, err := parser.ParseFile(fset, "", code, parser.ParseComments) -if err != nil { - panic(err) -} - -// Invoke the type checker using AST as input -typesInfo := types.Info{ - Defs: make(map[*ast.Ident]types.Object), - Uses: make(map[*ast.Ident]types.Object), -} -conf := &types.Config{} -if _, err := conf.Check("", fset, []*ast.File{astFile}, &typesInfo); err != nil { - panic(err) -} - -// Create a new decorator, which will track the mapping between ast and dst nodes -dec := decorator.NewDecorator(fset) - -// Decorate the *ast.File to give us a *dst.File -f, err := dec.DecorateFile(astFile) -if err != nil { - panic(err) -} - -// Find the *dst.Ident for the definition of "i" -dstDef := f.Decls[0].(*dst.FuncDecl).Body.List[0].(*dst.DeclStmt).Decl.(*dst.GenDecl).Specs[0].(*dst.ValueSpec).Names[0] - -// Find the *ast.Ident using the Ast.Nodes mapping -astDef := dec.Ast.Nodes[dstDef].(*ast.Ident) - -// Find the types.Object corresponding to "i" -obj := typesInfo.Defs[astDef] - -// Find all the uses of that object -var astUses []*ast.Ident -for id, ob := range typesInfo.Uses { - if ob != obj { - continue - } - astUses = append(astUses, id) -} - -// Find each *dst.Ident in the Dst.Nodes mapping -var dstUses []*dst.Ident -for _, id := range astUses { - dstUses = append(dstUses, dec.Dst.Nodes[id].(*dst.Ident)) -} - -// Change the name of the original definition and all uses -dstDef.Name = "foo" -for _, id := range dstUses { - id.Name = "foo" -} - -// Print the DST -if err := decorator.Print(f); err != nil { - panic(err) -} - -//Output: -//package main -// -//func main() { -// var foo int -// foo++ -// println(foo) -//} -``` - -## Resolvers - -There are two separate interfaces defined by the [resolver package](https://github.com/dave/dst/tree/master/decorator/resolver) -which allow the decorator and restorer to automatically manage the imports block. - -The decorator uses a `DecoratorResolver` which resolves the package path of any `*ast.Ident`. This is -complicated by dot-import syntax ([see below](#dot-imports)). - -The restorer uses a `RestorerResolver` which resolves the name of any package given the path. This -is complicated by vendoring and Go modules. - -When `Resolver` is set on `Decorator` or `Restorer`, the `Path` property must be set to the local -package path. - -Several implementations of both interfaces that are suitable for different environments are -provided: - -### DecoratorResolver - -#### gotypes - -The [gotypes](https://github.com/dave/dst/blob/master/decorator/resolver/gotypes/resolver.go) -package provides a `DecoratorResolver` with full dot-import compatibility. However it requires full -export data for all imported packages, so the `Uses` map from `go/types.Info` is required. There -are several methods of generating `go/types.Info`. Using `golang.org/x/tools/go/packages.Load` is -recommended for full Go modules compatibility. See the [decorator.Load](https://godoc.org/github.com/dave/dst/decorator#Load) -convenience function to automate this. - -#### goast - -The [goast](https://github.com/dave/dst/blob/master/decorator/resolver/goast/resolver.go) package -provides a simplified `DecoratorResolver` that only needs to scan a single ast file. This is unable -to resolve identifiers from dot-imported packages, so will panic if a dot-import is encountered in -the import block. It uses the provided `RestorerResolver` to resolve the names of all imported -packages. If no `RestorerResolver` is provided, the [guess](#guess-and-simple) implementation is used. - -### RestorerResolver - -#### gopackages - -The [gopackages](https://github.com/dave/dst/blob/master/decorator/resolver/gopackages/resolver.go) -package provides a `RestorerResolver` with full compatibility with Go modules. It uses -`golang.org/x/tools/go/packages` to load the package data. This may be very slow, and uses the `go` -command line tool to query package data, so may not be compatible with some environments. - -#### gobuild - -The [gobuild](https://github.com/dave/dst/blob/master/decorator/resolver/gobuild/resolver.go) -package provides an alternative `RestorerResolver` that uses the legacy `go/build` system to load -the imported package data. This may be needed in some circumstances and provides better performance -than `go/packages`. However, this is not Go modules aware. - -#### guess and simple - -The [guess](https://github.com/dave/dst/blob/master/decorator/resolver/guess/resolver.go) and -[simple](https://github.com/dave/dst/blob/master/decorator/resolver/simple/resolver.go) packages -provide simple `RestorerResolver` implementations that may be useful in certain circumstances, or -where performance is critical. `simple` resolves paths only if they occur in a provided map. -`guess` guesses the package name based on the last part of the path. - -### Example - -Here's an example of supplying resolvers for the decorator and restorer: - -```go -code := `package main - - import "fmt" - - func main() { - fmt.Println("a") - }` - -dec := decorator.NewDecoratorWithImports(token.NewFileSet(), "main", goast.New()) - -f, err := dec.Parse(code) -if err != nil { - panic(err) -} - -f.Decls[1].(*dst.FuncDecl).Body.List[0].(*dst.ExprStmt).X.(*dst.CallExpr).Args = []dst.Expr{ - &dst.CallExpr{ - Fun: &dst.Ident{Name: "A", Path: "foo.bar/baz"}, - }, -} - -res := decorator.NewRestorerWithImports("main", guess.New()) -if err := res.Print(f); err != nil { - panic(err) -} - -//Output: -//package main -// -//import ( -// "fmt" -// -// "foo.bar/baz" -//) -// -//func main() { -// fmt.Println(baz.A()) -//} -``` - -### Alias - -To control the alias of imports, use a `FileRestorer`: - -```go -code := `package main - - import "fmt" - - func main() { - fmt.Println("a") - }` - -dec := decorator.NewDecoratorWithImports(token.NewFileSet(), "main", goast.New()) - -f, err := dec.Parse(code) -if err != nil { - panic(err) -} - -res := decorator.NewRestorerWithImports("main", guess.New()) - -fr := res.FileRestorer() -fr.Alias["fmt"] = "fmt1" - -if err := fr.Print(f); err != nil { - panic(err) -} - -//Output: -//package main -// -//import fmt1 "fmt" -// -//func main() { -// fmt1.Println("a") -//} -``` - -### Details - -For more information on exactly how the imports block is managed, read through the [test -cases](https://github.com/dave/dst/blob/master/decorator/restorer_resolver_test.go). - -### Dot-imports - -Consider this file... - -```go -package main - -import ( - . "a" -) - -func main() { - B() - C() -} -``` - -`B` and `C` could be local identifiers from a different file in this package, -or from the imported package `a`. If only one is from `a` and it is removed, we should remove the -import when we restore to `ast`. Thus the resolver needs to be able to resolve the package using -the full info from `go/types`. - -## Status - -This package is well tested and used in many projects. The API should be considered stable going forward. - -## Chat? - -Feel free to create an [issue](https://github.com/dave/dst/issues) or chat in the -[#dst](https://gophers.slack.com/messages/CCVL24MTQ) Gophers Slack channel. - -## Contributing - -For further developing or contributing to `dst`, check out [these notes](https://github.com/dave/dst/blob/master/contributing.md). - -## Special thanks - -Thanks very much to [hawkinsw](https://github.com/hawkinsw) for taking on the task of adding generics compatibility to `dst`. \ No newline at end of file diff --git a/vendor/github.com/dave/dst/README.md.tpl b/vendor/github.com/dave/dst/README.md.tpl deleted file mode 100644 index 26691f9bb4..0000000000 --- a/vendor/github.com/dave/dst/README.md.tpl +++ /dev/null @@ -1,239 +0,0 @@ -[![Build Status](https://travis-ci.org/dave/dst.svg?branch=master)](https://travis-ci.org/dave/dst) -[![Documentation](https://img.shields.io/badge/godoc-documentation-brightgreen.svg)](https://godoc.org/github.com/dave/dst/decorator) -[![codecov](https://img.shields.io/badge/codecov-92%25-brightgreen.svg)](https://codecov.io/gh/dave/dst) -![stability-stable](https://img.shields.io/badge/stability-stable-brightgreen.svg) -[![Sourcegraph](https://sourcegraph.com/github.com/dave/dst/-/badge.svg)](https://sourcegraph.com/github.com/dave/dst?badge) - -# Decorated Syntax Tree - -The `dst` package enables manipulation of a Go syntax tree with high fidelity. Decorations (e.g. -comments and line spacing) remain attached to the correct nodes as the tree is modified. - -## Where does `go/ast` break? - -The `go/ast` package wasn't created with source manipulation as an intended use-case. Comments are -stored by their byte offset instead of attached to nodes, so re-arranging nodes breaks the output. -See [this Go issue](https://github.com/golang/go/issues/20744) for more information. - -Consider this example where we want to reverse the order of the two statements. As you can see the -comments don't remain attached to the correct nodes: - -{{ "ExampleAstBroken" | example }} - -Here's the same example using `dst`: - -{{ "ExampleDstFixed" | example }} - -## Usage - -Parsing a source file to `dst` and printing the results after modification can be accomplished with -several `Parse` and `Print` convenience functions in the [decorator](https://godoc.org/github.com/dave/dst/decorator) -package. - -For more fine-grained control you can use [Decorator](https://godoc.org/github.com/dave/dst/decorator#Decorator) -to convert from `ast` to `dst`, and [Restorer](https://godoc.org/github.com/dave/dst/decorator#Restorer) -to convert back again. - -### Comments - -Comments are added at decoration attachment points. [See here](https://github.com/dave/dst/blob/master/decorations-types-generated.go) -for a full list of these points, along with demonstration code of where they are rendered in the -output. - -The decoration attachment points have convenience functions `Append`, `Prepend`, `Replace`, `Clear` -and `All` to accomplish common tasks. Use the full text of your comment including the `//` or `/**/` -markers. When adding a line comment, a newline is automatically rendered. - -{{ "ExampleComment" | example }} - -### Spacing - -The `Before` property marks the node as having a line space (new line or empty line) before the node. -These spaces are rendered before any decorations attached to the `Start` decoration point. The `After` -property is similar but rendered after the node (and after any `End` decorations). - -{{ "ExampleSpace" | example }} - -### Decorations - -The common decoration properties (`Start`, `End`, `Before` and `After`) occur on all nodes, and can be -accessed with the `Decorations()` method on the `Node` interface: - -{{ "ExampleDecorated" | example }} - -#### dstutil.Decorations - -While debugging, it is often useful to have a list of all decorations attached to a node. The -[dstutil](https://github.com/dave/dst/tree/master/dstutil) package provides a helper function `Decorations` which -returns a list of the attachment points and all decorations for any node: - -{{ "ExampleDecorationPoints" | example }} - -### Newlines - -The `Before` and `After` properties cover the majority of cases, but occasionally a newline needs to -be rendered inside a node. Simply add a `\n` decoration to accomplish this. - -### Clone - -Re-using an existing node elsewhere in the tree will panic when the tree is restored to `ast`. Instead, -use the `Clone` function to make a deep copy of the node before re-use: - -{{ "ExampleClone" | example }} - -### Apply - -The [dstutil](https://github.com/dave/dst/tree/master/dstutil) package is a fork of `golang.org/x/tools/go/ast/astutil`, -and provides the `Apply` function with similar semantics. - -### Imports - -The decorator can automatically manage the `import` block, which is a non-trivial task. - -Use [NewDecoratorWithImports](https://godoc.org/github.com/dave/dst/decorator#NewDecoratorWithImports) -and [NewRestorerWithImports](https://godoc.org/github.com/dave/dst/decorator#NewRestorerWithImports) -to create an import aware decorator / restorer. - -During decoration, remote identifiers are normalised - `*ast.SelectorExpr` nodes that represent -qualified identifiers are replaced with `*dst.Ident` nodes with the `Path` field set to the path of -the imported package. - -When adding a qualified identifier node, there is no need to use `*dst.SelectorExpr` - just add a -`*dst.Ident` and set `Path` to the imported package path. The restorer will wrap it in a -`*ast.SelectorExpr` where appropriate when converting back to ast, and also update the import -block. - -To enable import management, the decorator must be able to resolve the imported package for -selector expressions and identifiers, and the restorer must be able to resolve the name of a -package given it's path. Several implementations for these resolvers are provided, and the best -method will depend on the environment. [See below](#resolvers) for more details. - -### Load - -The [Load](https://godoc.org/github.com/dave/dst/decorator#Load) convenience function uses -`go/packages` to load packages and decorate all loaded ast files, with import management enabled: - -{{ "ExampleImports" | example }} - -### Mappings - -The decorator exposes `Dst.Nodes` and `Ast.Nodes` which map between `ast.Node` and `dst.Node`. This -enables systems that refer to `ast` nodes (such as `go/types`) to be used: - -{{ "ExampleTypes" | example }} - -## Resolvers - -There are two separate interfaces defined by the [resolver package](https://github.com/dave/dst/tree/master/decorator/resolver) -which allow the decorator and restorer to automatically manage the imports block. - -The decorator uses a `DecoratorResolver` which resolves the package path of any `*ast.Ident`. This is -complicated by dot-import syntax ([see below](#dot-imports)). - -The restorer uses a `RestorerResolver` which resolves the name of any package given the path. This -is complicated by vendoring and Go modules. - -When `Resolver` is set on `Decorator` or `Restorer`, the `Path` property must be set to the local -package path. - -Several implementations of both interfaces that are suitable for different environments are -provided: - -### DecoratorResolver - -#### gotypes - -The [gotypes](https://github.com/dave/dst/blob/master/decorator/resolver/gotypes/resolver.go) -package provides a `DecoratorResolver` with full dot-import compatibility. However it requires full -export data for all imported packages, so the `Uses` map from `go/types.Info` is required. There -are several methods of generating `go/types.Info`. Using `golang.org/x/tools/go/packages.Load` is -recommended for full Go modules compatibility. See the [decorator.Load](https://godoc.org/github.com/dave/dst/decorator#Load) -convenience function to automate this. - -#### goast - -The [goast](https://github.com/dave/dst/blob/master/decorator/resolver/goast/resolver.go) package -provides a simplified `DecoratorResolver` that only needs to scan a single ast file. This is unable -to resolve identifiers from dot-imported packages, so will panic if a dot-import is encountered in -the import block. It uses the provided `RestorerResolver` to resolve the names of all imported -packages. If no `RestorerResolver` is provided, the [guess](#guess-and-simple) implementation is used. - -### RestorerResolver - -#### gopackages - -The [gopackages](https://github.com/dave/dst/blob/master/decorator/resolver/gopackages/resolver.go) -package provides a `RestorerResolver` with full compatibility with Go modules. It uses -`golang.org/x/tools/go/packages` to load the package data. This may be very slow, and uses the `go` -command line tool to query package data, so may not be compatible with some environments. - -#### gobuild - -The [gobuild](https://github.com/dave/dst/blob/master/decorator/resolver/gobuild/resolver.go) -package provides an alternative `RestorerResolver` that uses the legacy `go/build` system to load -the imported package data. This may be needed in some circumstances and provides better performance -than `go/packages`. However, this is not Go modules aware. - -#### guess and simple - -The [guess](https://github.com/dave/dst/blob/master/decorator/resolver/guess/resolver.go) and -[simple](https://github.com/dave/dst/blob/master/decorator/resolver/simple/resolver.go) packages -provide simple `RestorerResolver` implementations that may be useful in certain circumstances, or -where performance is critical. `simple` resolves paths only if they occur in a provided map. -`guess` guesses the package name based on the last part of the path. - -### Example - -Here's an example of supplying resolvers for the decorator and restorer: - -{{ "ExampleManualImports" | example }} - -### Alias - -To control the alias of imports, use a `FileRestorer`: - -{{ "ExampleAlias" | example }} - -### Details - -For more information on exactly how the imports block is managed, read through the [test -cases](https://github.com/dave/dst/blob/master/decorator/restorer_resolver_test.go). - -### Dot-imports - -Consider this file... - -```go -package main - -import ( - . "a" -) - -func main() { - B() - C() -} -``` - -`B` and `C` could be local identifiers from a different file in this package, -or from the imported package `a`. If only one is from `a` and it is removed, we should remove the -import when we restore to `ast`. Thus the resolver needs to be able to resolve the package using -the full info from `go/types`. - -## Status - -This package is well tested and used in many projects. The API should be considered stable going forward. - -## Chat? - -Feel free to create an [issue](https://github.com/dave/dst/issues) or chat in the -[#dst](https://gophers.slack.com/messages/CCVL24MTQ) Gophers Slack channel. - -## Contributing - -For further developing or contributing to `dst`, check out [these notes](https://github.com/dave/dst/blob/master/contributing.md). - -## Special thanks - -Thanks very much to [hawkinsw](https://github.com/hawkinsw) for taking on the task of adding generics compatibility to `dst`. \ No newline at end of file diff --git a/vendor/github.com/dave/dst/clone-generated.go b/vendor/github.com/dave/dst/clone-generated.go deleted file mode 100644 index ab2287491b..0000000000 --- a/vendor/github.com/dave/dst/clone-generated.go +++ /dev/null @@ -1,1628 +0,0 @@ -package dst - -import "fmt" - -// Clone returns a deep copy of the node, ready to be re-used elsewhere in the tree. -func Clone(n Node) Node { - switch n := n.(type) { - case *ArrayType: - out := &ArrayType{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Decoration: Lbrack - out.Decs.Lbrack = append(out.Decs.Lbrack, n.Decs.Lbrack...) - - // Node: Len - if n.Len != nil { - out.Len = Clone(n.Len).(Expr) - } - - // Decoration: Len - out.Decs.Len = append(out.Decs.Len, n.Decs.Len...) - - // Node: Elt - if n.Elt != nil { - out.Elt = Clone(n.Elt).(Expr) - } - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *AssignStmt: - out := &AssignStmt{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // List: Lhs - for _, v := range n.Lhs { - out.Lhs = append(out.Lhs, Clone(v).(Expr)) - } - - // Token: Tok - out.Tok = n.Tok - - // Decoration: Tok - out.Decs.Tok = append(out.Decs.Tok, n.Decs.Tok...) - - // List: Rhs - for _, v := range n.Rhs { - out.Rhs = append(out.Rhs, Clone(v).(Expr)) - } - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *BadDecl: - out := &BadDecl{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Bad - out.Length = n.Length - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *BadExpr: - out := &BadExpr{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Bad - out.Length = n.Length - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *BadStmt: - out := &BadStmt{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Bad - out.Length = n.Length - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *BasicLit: - out := &BasicLit{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // String: Value - out.Value = n.Value - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - // Value: Kind - out.Kind = n.Kind - - out.Decs.After = n.Decs.After - - return out - case *BinaryExpr: - out := &BinaryExpr{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Node: X - if n.X != nil { - out.X = Clone(n.X).(Expr) - } - - // Decoration: X - out.Decs.X = append(out.Decs.X, n.Decs.X...) - - // Token: Op - out.Op = n.Op - - // Decoration: Op - out.Decs.Op = append(out.Decs.Op, n.Decs.Op...) - - // Node: Y - if n.Y != nil { - out.Y = Clone(n.Y).(Expr) - } - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *BlockStmt: - out := &BlockStmt{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Decoration: Lbrace - out.Decs.Lbrace = append(out.Decs.Lbrace, n.Decs.Lbrace...) - - // List: List - for _, v := range n.List { - out.List = append(out.List, Clone(v).(Stmt)) - } - - // Token: Rbrace - out.RbraceHasNoPos = n.RbraceHasNoPos - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *BranchStmt: - out := &BranchStmt{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Token: Tok - out.Tok = n.Tok - - // Decoration: Tok - out.Decs.Tok = append(out.Decs.Tok, n.Decs.Tok...) - - // Node: Label - if n.Label != nil { - out.Label = Clone(n.Label).(*Ident) - } - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *CallExpr: - out := &CallExpr{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Node: Fun - if n.Fun != nil { - out.Fun = Clone(n.Fun).(Expr) - } - - // Decoration: Fun - out.Decs.Fun = append(out.Decs.Fun, n.Decs.Fun...) - - // Decoration: Lparen - out.Decs.Lparen = append(out.Decs.Lparen, n.Decs.Lparen...) - - // List: Args - for _, v := range n.Args { - out.Args = append(out.Args, Clone(v).(Expr)) - } - - // Token: Ellipsis - out.Ellipsis = n.Ellipsis - - // Decoration: Ellipsis - out.Decs.Ellipsis = append(out.Decs.Ellipsis, n.Decs.Ellipsis...) - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *CaseClause: - out := &CaseClause{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Decoration: Case - out.Decs.Case = append(out.Decs.Case, n.Decs.Case...) - - // List: List - for _, v := range n.List { - out.List = append(out.List, Clone(v).(Expr)) - } - - // Decoration: Colon - out.Decs.Colon = append(out.Decs.Colon, n.Decs.Colon...) - - // List: Body - for _, v := range n.Body { - out.Body = append(out.Body, Clone(v).(Stmt)) - } - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *ChanType: - out := &ChanType{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Decoration: Begin - out.Decs.Begin = append(out.Decs.Begin, n.Decs.Begin...) - - // Decoration: Arrow - out.Decs.Arrow = append(out.Decs.Arrow, n.Decs.Arrow...) - - // Node: Value - if n.Value != nil { - out.Value = Clone(n.Value).(Expr) - } - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - // Value: Dir - out.Dir = n.Dir - - out.Decs.After = n.Decs.After - - return out - case *CommClause: - out := &CommClause{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Decoration: Case - out.Decs.Case = append(out.Decs.Case, n.Decs.Case...) - - // Node: Comm - if n.Comm != nil { - out.Comm = Clone(n.Comm).(Stmt) - } - - // Decoration: Comm - out.Decs.Comm = append(out.Decs.Comm, n.Decs.Comm...) - - // Decoration: Colon - out.Decs.Colon = append(out.Decs.Colon, n.Decs.Colon...) - - // List: Body - for _, v := range n.Body { - out.Body = append(out.Body, Clone(v).(Stmt)) - } - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *CompositeLit: - out := &CompositeLit{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Node: Type - if n.Type != nil { - out.Type = Clone(n.Type).(Expr) - } - - // Decoration: Type - out.Decs.Type = append(out.Decs.Type, n.Decs.Type...) - - // Decoration: Lbrace - out.Decs.Lbrace = append(out.Decs.Lbrace, n.Decs.Lbrace...) - - // List: Elts - for _, v := range n.Elts { - out.Elts = append(out.Elts, Clone(v).(Expr)) - } - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - // Value: Incomplete - out.Incomplete = n.Incomplete - - out.Decs.After = n.Decs.After - - return out - case *DeclStmt: - out := &DeclStmt{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Node: Decl - if n.Decl != nil { - out.Decl = Clone(n.Decl).(Decl) - } - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *DeferStmt: - out := &DeferStmt{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Decoration: Defer - out.Decs.Defer = append(out.Decs.Defer, n.Decs.Defer...) - - // Node: Call - if n.Call != nil { - out.Call = Clone(n.Call).(*CallExpr) - } - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *Ellipsis: - out := &Ellipsis{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Decoration: Ellipsis - out.Decs.Ellipsis = append(out.Decs.Ellipsis, n.Decs.Ellipsis...) - - // Node: Elt - if n.Elt != nil { - out.Elt = Clone(n.Elt).(Expr) - } - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *EmptyStmt: - out := &EmptyStmt{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - // Value: Implicit - out.Implicit = n.Implicit - - out.Decs.After = n.Decs.After - - return out - case *ExprStmt: - out := &ExprStmt{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Node: X - if n.X != nil { - out.X = Clone(n.X).(Expr) - } - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *Field: - out := &Field{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // List: Names - for _, v := range n.Names { - out.Names = append(out.Names, Clone(v).(*Ident)) - } - - // Node: Type - if n.Type != nil { - out.Type = Clone(n.Type).(Expr) - } - - // Decoration: Type - out.Decs.Type = append(out.Decs.Type, n.Decs.Type...) - - // Node: Tag - if n.Tag != nil { - out.Tag = Clone(n.Tag).(*BasicLit) - } - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *FieldList: - out := &FieldList{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Token: Opening - out.Opening = n.Opening - - // Decoration: Opening - out.Decs.Opening = append(out.Decs.Opening, n.Decs.Opening...) - - // List: List - for _, v := range n.List { - out.List = append(out.List, Clone(v).(*Field)) - } - - // Token: Closing - out.Closing = n.Closing - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *File: - out := &File{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Decoration: Package - out.Decs.Package = append(out.Decs.Package, n.Decs.Package...) - - // Node: Name - if n.Name != nil { - out.Name = Clone(n.Name).(*Ident) - } - - // Decoration: Name - out.Decs.Name = append(out.Decs.Name, n.Decs.Name...) - - // List: Decls - for _, v := range n.Decls { - out.Decls = append(out.Decls, Clone(v).(Decl)) - } - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - // Scope: Scope - out.Scope = CloneScope(n.Scope) - - // List: Imports - for _, v := range n.Imports { - out.Imports = append(out.Imports, Clone(v).(*ImportSpec)) - } - - out.Decs.After = n.Decs.After - - return out - case *ForStmt: - out := &ForStmt{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Decoration: For - out.Decs.For = append(out.Decs.For, n.Decs.For...) - - // Node: Init - if n.Init != nil { - out.Init = Clone(n.Init).(Stmt) - } - - // Decoration: Init - out.Decs.Init = append(out.Decs.Init, n.Decs.Init...) - - // Node: Cond - if n.Cond != nil { - out.Cond = Clone(n.Cond).(Expr) - } - - // Decoration: Cond - out.Decs.Cond = append(out.Decs.Cond, n.Decs.Cond...) - - // Node: Post - if n.Post != nil { - out.Post = Clone(n.Post).(Stmt) - } - - // Decoration: Post - out.Decs.Post = append(out.Decs.Post, n.Decs.Post...) - - // Node: Body - if n.Body != nil { - out.Body = Clone(n.Body).(*BlockStmt) - } - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *FuncDecl: - out := &FuncDecl{} - - out.Decs.Before = n.Decs.Before - - // Init: Type - out.Type = &FuncType{} - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Token: Func - out.Type.Func = n.Type.Func - - // Decoration: Func - out.Decs.Func = append(out.Decs.Func, n.Decs.Func...) - - // Node: Recv - if n.Recv != nil { - out.Recv = Clone(n.Recv).(*FieldList) - } - - // Decoration: Recv - out.Decs.Recv = append(out.Decs.Recv, n.Decs.Recv...) - - // Node: Name - if n.Name != nil { - out.Name = Clone(n.Name).(*Ident) - } - - // Decoration: Name - out.Decs.Name = append(out.Decs.Name, n.Decs.Name...) - - // Node: TypeParams - if n.Type.TypeParams != nil { - out.Type.TypeParams = Clone(n.Type.TypeParams).(*FieldList) - } - - // Decoration: TypeParams - out.Decs.TypeParams = append(out.Decs.TypeParams, n.Decs.TypeParams...) - - // Node: Params - if n.Type.Params != nil { - out.Type.Params = Clone(n.Type.Params).(*FieldList) - } - - // Decoration: Params - out.Decs.Params = append(out.Decs.Params, n.Decs.Params...) - - // Node: Results - if n.Type.Results != nil { - out.Type.Results = Clone(n.Type.Results).(*FieldList) - } - - // Decoration: Results - out.Decs.Results = append(out.Decs.Results, n.Decs.Results...) - - // Node: Body - if n.Body != nil { - out.Body = Clone(n.Body).(*BlockStmt) - } - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *FuncLit: - out := &FuncLit{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Node: Type - if n.Type != nil { - out.Type = Clone(n.Type).(*FuncType) - } - - // Decoration: Type - out.Decs.Type = append(out.Decs.Type, n.Decs.Type...) - - // Node: Body - if n.Body != nil { - out.Body = Clone(n.Body).(*BlockStmt) - } - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *FuncType: - out := &FuncType{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Token: Func - out.Func = n.Func - - // Decoration: Func - out.Decs.Func = append(out.Decs.Func, n.Decs.Func...) - - // Node: TypeParams - if n.TypeParams != nil { - out.TypeParams = Clone(n.TypeParams).(*FieldList) - } - - // Decoration: TypeParams - out.Decs.TypeParams = append(out.Decs.TypeParams, n.Decs.TypeParams...) - - // Node: Params - if n.Params != nil { - out.Params = Clone(n.Params).(*FieldList) - } - - // Decoration: Params - out.Decs.Params = append(out.Decs.Params, n.Decs.Params...) - - // Node: Results - if n.Results != nil { - out.Results = Clone(n.Results).(*FieldList) - } - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *GenDecl: - out := &GenDecl{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Token: Tok - out.Tok = n.Tok - - // Decoration: Tok - out.Decs.Tok = append(out.Decs.Tok, n.Decs.Tok...) - - // Token: Lparen - out.Lparen = n.Lparen - - // Decoration: Lparen - out.Decs.Lparen = append(out.Decs.Lparen, n.Decs.Lparen...) - - // List: Specs - for _, v := range n.Specs { - out.Specs = append(out.Specs, Clone(v).(Spec)) - } - - // Token: Rparen - out.Rparen = n.Rparen - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *GoStmt: - out := &GoStmt{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Decoration: Go - out.Decs.Go = append(out.Decs.Go, n.Decs.Go...) - - // Node: Call - if n.Call != nil { - out.Call = Clone(n.Call).(*CallExpr) - } - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *Ident: - out := &Ident{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Decoration: X - out.Decs.X = append(out.Decs.X, n.Decs.X...) - - // String: Name - out.Name = n.Name - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - // Object: Obj - out.Obj = CloneObject(n.Obj) - - // Path: Path - out.Path = n.Path - - out.Decs.After = n.Decs.After - - return out - case *IfStmt: - out := &IfStmt{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Decoration: If - out.Decs.If = append(out.Decs.If, n.Decs.If...) - - // Node: Init - if n.Init != nil { - out.Init = Clone(n.Init).(Stmt) - } - - // Decoration: Init - out.Decs.Init = append(out.Decs.Init, n.Decs.Init...) - - // Node: Cond - if n.Cond != nil { - out.Cond = Clone(n.Cond).(Expr) - } - - // Decoration: Cond - out.Decs.Cond = append(out.Decs.Cond, n.Decs.Cond...) - - // Node: Body - if n.Body != nil { - out.Body = Clone(n.Body).(*BlockStmt) - } - - // Decoration: Else - out.Decs.Else = append(out.Decs.Else, n.Decs.Else...) - - // Node: Else - if n.Else != nil { - out.Else = Clone(n.Else).(Stmt) - } - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *ImportSpec: - out := &ImportSpec{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Node: Name - if n.Name != nil { - out.Name = Clone(n.Name).(*Ident) - } - - // Decoration: Name - out.Decs.Name = append(out.Decs.Name, n.Decs.Name...) - - // Node: Path - if n.Path != nil { - out.Path = Clone(n.Path).(*BasicLit) - } - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *IncDecStmt: - out := &IncDecStmt{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Node: X - if n.X != nil { - out.X = Clone(n.X).(Expr) - } - - // Decoration: X - out.Decs.X = append(out.Decs.X, n.Decs.X...) - - // Token: Tok - out.Tok = n.Tok - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *IndexExpr: - out := &IndexExpr{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Node: X - if n.X != nil { - out.X = Clone(n.X).(Expr) - } - - // Decoration: X - out.Decs.X = append(out.Decs.X, n.Decs.X...) - - // Decoration: Lbrack - out.Decs.Lbrack = append(out.Decs.Lbrack, n.Decs.Lbrack...) - - // Node: Index - if n.Index != nil { - out.Index = Clone(n.Index).(Expr) - } - - // Decoration: Index - out.Decs.Index = append(out.Decs.Index, n.Decs.Index...) - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *IndexListExpr: - out := &IndexListExpr{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Node: X - if n.X != nil { - out.X = Clone(n.X).(Expr) - } - - // Decoration: X - out.Decs.X = append(out.Decs.X, n.Decs.X...) - - // Decoration: Lbrack - out.Decs.Lbrack = append(out.Decs.Lbrack, n.Decs.Lbrack...) - - // List: Indices - for _, v := range n.Indices { - out.Indices = append(out.Indices, Clone(v).(Expr)) - } - - // Decoration: Indices - out.Decs.Indices = append(out.Decs.Indices, n.Decs.Indices...) - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *InterfaceType: - out := &InterfaceType{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Decoration: Interface - out.Decs.Interface = append(out.Decs.Interface, n.Decs.Interface...) - - // Node: Methods - if n.Methods != nil { - out.Methods = Clone(n.Methods).(*FieldList) - } - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - // Value: Incomplete - out.Incomplete = n.Incomplete - - out.Decs.After = n.Decs.After - - return out - case *KeyValueExpr: - out := &KeyValueExpr{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Node: Key - if n.Key != nil { - out.Key = Clone(n.Key).(Expr) - } - - // Decoration: Key - out.Decs.Key = append(out.Decs.Key, n.Decs.Key...) - - // Decoration: Colon - out.Decs.Colon = append(out.Decs.Colon, n.Decs.Colon...) - - // Node: Value - if n.Value != nil { - out.Value = Clone(n.Value).(Expr) - } - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *LabeledStmt: - out := &LabeledStmt{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Node: Label - if n.Label != nil { - out.Label = Clone(n.Label).(*Ident) - } - - // Decoration: Label - out.Decs.Label = append(out.Decs.Label, n.Decs.Label...) - - // Decoration: Colon - out.Decs.Colon = append(out.Decs.Colon, n.Decs.Colon...) - - // Node: Stmt - if n.Stmt != nil { - out.Stmt = Clone(n.Stmt).(Stmt) - } - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *MapType: - out := &MapType{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Decoration: Map - out.Decs.Map = append(out.Decs.Map, n.Decs.Map...) - - // Node: Key - if n.Key != nil { - out.Key = Clone(n.Key).(Expr) - } - - // Decoration: Key - out.Decs.Key = append(out.Decs.Key, n.Decs.Key...) - - // Node: Value - if n.Value != nil { - out.Value = Clone(n.Value).(Expr) - } - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *Package: - out := &Package{} - - // Value: Name - out.Name = n.Name - - // Scope: Scope - out.Scope = CloneScope(n.Scope) - - // Map: Imports - out.Imports = map[string]*Object{} - for k, v := range n.Imports { - out.Imports[k] = CloneObject(v) - } - - // Map: Files - out.Files = map[string]*File{} - for k, v := range n.Files { - out.Files[k] = Clone(v).(*File) - } - - return out - case *ParenExpr: - out := &ParenExpr{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Decoration: Lparen - out.Decs.Lparen = append(out.Decs.Lparen, n.Decs.Lparen...) - - // Node: X - if n.X != nil { - out.X = Clone(n.X).(Expr) - } - - // Decoration: X - out.Decs.X = append(out.Decs.X, n.Decs.X...) - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *RangeStmt: - out := &RangeStmt{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Decoration: For - out.Decs.For = append(out.Decs.For, n.Decs.For...) - - // Node: Key - if n.Key != nil { - out.Key = Clone(n.Key).(Expr) - } - - // Decoration: Key - out.Decs.Key = append(out.Decs.Key, n.Decs.Key...) - - // Node: Value - if n.Value != nil { - out.Value = Clone(n.Value).(Expr) - } - - // Decoration: Value - out.Decs.Value = append(out.Decs.Value, n.Decs.Value...) - - // Token: Tok - out.Tok = n.Tok - - // Decoration: Range - out.Decs.Range = append(out.Decs.Range, n.Decs.Range...) - - // Node: X - if n.X != nil { - out.X = Clone(n.X).(Expr) - } - - // Decoration: X - out.Decs.X = append(out.Decs.X, n.Decs.X...) - - // Node: Body - if n.Body != nil { - out.Body = Clone(n.Body).(*BlockStmt) - } - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *ReturnStmt: - out := &ReturnStmt{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Decoration: Return - out.Decs.Return = append(out.Decs.Return, n.Decs.Return...) - - // List: Results - for _, v := range n.Results { - out.Results = append(out.Results, Clone(v).(Expr)) - } - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *SelectStmt: - out := &SelectStmt{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Decoration: Select - out.Decs.Select = append(out.Decs.Select, n.Decs.Select...) - - // Node: Body - if n.Body != nil { - out.Body = Clone(n.Body).(*BlockStmt) - } - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *SelectorExpr: - out := &SelectorExpr{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Node: X - if n.X != nil { - out.X = Clone(n.X).(Expr) - } - - // Decoration: X - out.Decs.X = append(out.Decs.X, n.Decs.X...) - - // Node: Sel - if n.Sel != nil { - out.Sel = Clone(n.Sel).(*Ident) - } - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *SendStmt: - out := &SendStmt{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Node: Chan - if n.Chan != nil { - out.Chan = Clone(n.Chan).(Expr) - } - - // Decoration: Chan - out.Decs.Chan = append(out.Decs.Chan, n.Decs.Chan...) - - // Decoration: Arrow - out.Decs.Arrow = append(out.Decs.Arrow, n.Decs.Arrow...) - - // Node: Value - if n.Value != nil { - out.Value = Clone(n.Value).(Expr) - } - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *SliceExpr: - out := &SliceExpr{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Node: X - if n.X != nil { - out.X = Clone(n.X).(Expr) - } - - // Decoration: X - out.Decs.X = append(out.Decs.X, n.Decs.X...) - - // Decoration: Lbrack - out.Decs.Lbrack = append(out.Decs.Lbrack, n.Decs.Lbrack...) - - // Node: Low - if n.Low != nil { - out.Low = Clone(n.Low).(Expr) - } - - // Decoration: Low - out.Decs.Low = append(out.Decs.Low, n.Decs.Low...) - - // Node: High - if n.High != nil { - out.High = Clone(n.High).(Expr) - } - - // Decoration: High - out.Decs.High = append(out.Decs.High, n.Decs.High...) - - // Node: Max - if n.Max != nil { - out.Max = Clone(n.Max).(Expr) - } - - // Decoration: Max - out.Decs.Max = append(out.Decs.Max, n.Decs.Max...) - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - // Value: Slice3 - out.Slice3 = n.Slice3 - - out.Decs.After = n.Decs.After - - return out - case *StarExpr: - out := &StarExpr{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Decoration: Star - out.Decs.Star = append(out.Decs.Star, n.Decs.Star...) - - // Node: X - if n.X != nil { - out.X = Clone(n.X).(Expr) - } - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *StructType: - out := &StructType{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Decoration: Struct - out.Decs.Struct = append(out.Decs.Struct, n.Decs.Struct...) - - // Node: Fields - if n.Fields != nil { - out.Fields = Clone(n.Fields).(*FieldList) - } - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - // Value: Incomplete - out.Incomplete = n.Incomplete - - out.Decs.After = n.Decs.After - - return out - case *SwitchStmt: - out := &SwitchStmt{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Decoration: Switch - out.Decs.Switch = append(out.Decs.Switch, n.Decs.Switch...) - - // Node: Init - if n.Init != nil { - out.Init = Clone(n.Init).(Stmt) - } - - // Decoration: Init - out.Decs.Init = append(out.Decs.Init, n.Decs.Init...) - - // Node: Tag - if n.Tag != nil { - out.Tag = Clone(n.Tag).(Expr) - } - - // Decoration: Tag - out.Decs.Tag = append(out.Decs.Tag, n.Decs.Tag...) - - // Node: Body - if n.Body != nil { - out.Body = Clone(n.Body).(*BlockStmt) - } - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *TypeAssertExpr: - out := &TypeAssertExpr{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Node: X - if n.X != nil { - out.X = Clone(n.X).(Expr) - } - - // Decoration: X - out.Decs.X = append(out.Decs.X, n.Decs.X...) - - // Decoration: Lparen - out.Decs.Lparen = append(out.Decs.Lparen, n.Decs.Lparen...) - - // Node: Type - if n.Type != nil { - out.Type = Clone(n.Type).(Expr) - } - - // Decoration: Type - out.Decs.Type = append(out.Decs.Type, n.Decs.Type...) - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *TypeSpec: - out := &TypeSpec{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Node: Name - if n.Name != nil { - out.Name = Clone(n.Name).(*Ident) - } - - // Token: Assign - out.Assign = n.Assign - - // Decoration: Name - out.Decs.Name = append(out.Decs.Name, n.Decs.Name...) - - // Node: TypeParams - if n.TypeParams != nil { - out.TypeParams = Clone(n.TypeParams).(*FieldList) - } - - // Decoration: TypeParams - out.Decs.TypeParams = append(out.Decs.TypeParams, n.Decs.TypeParams...) - - // Node: Type - if n.Type != nil { - out.Type = Clone(n.Type).(Expr) - } - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *TypeSwitchStmt: - out := &TypeSwitchStmt{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Decoration: Switch - out.Decs.Switch = append(out.Decs.Switch, n.Decs.Switch...) - - // Node: Init - if n.Init != nil { - out.Init = Clone(n.Init).(Stmt) - } - - // Decoration: Init - out.Decs.Init = append(out.Decs.Init, n.Decs.Init...) - - // Node: Assign - if n.Assign != nil { - out.Assign = Clone(n.Assign).(Stmt) - } - - // Decoration: Assign - out.Decs.Assign = append(out.Decs.Assign, n.Decs.Assign...) - - // Node: Body - if n.Body != nil { - out.Body = Clone(n.Body).(*BlockStmt) - } - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *UnaryExpr: - out := &UnaryExpr{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // Token: Op - out.Op = n.Op - - // Decoration: Op - out.Decs.Op = append(out.Decs.Op, n.Decs.Op...) - - // Node: X - if n.X != nil { - out.X = Clone(n.X).(Expr) - } - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - case *ValueSpec: - out := &ValueSpec{} - - out.Decs.Before = n.Decs.Before - - // Decoration: Start - out.Decs.Start = append(out.Decs.Start, n.Decs.Start...) - - // List: Names - for _, v := range n.Names { - out.Names = append(out.Names, Clone(v).(*Ident)) - } - - // Node: Type - if n.Type != nil { - out.Type = Clone(n.Type).(Expr) - } - - // Decoration: Assign - out.Decs.Assign = append(out.Decs.Assign, n.Decs.Assign...) - - // List: Values - for _, v := range n.Values { - out.Values = append(out.Values, Clone(v).(Expr)) - } - - // Decoration: End - out.Decs.End = append(out.Decs.End, n.Decs.End...) - - out.Decs.After = n.Decs.After - - return out - default: - panic(fmt.Sprintf("%T", n)) - } -} diff --git a/vendor/github.com/dave/dst/clone.go b/vendor/github.com/dave/dst/clone.go deleted file mode 100644 index 3f1e5f8292..0000000000 --- a/vendor/github.com/dave/dst/clone.go +++ /dev/null @@ -1,11 +0,0 @@ -package dst - -// CloneObject returns nil: After cloning a node, it should not be attached to the same object / scope. -func CloneObject(o *Object) *Object { - return nil -} - -// CloneScope returns nil: After cloning a node, it should not be attached to the same object / scope. -func CloneScope(s *Scope) *Scope { - return nil -} diff --git a/vendor/github.com/dave/dst/contributing.md b/vendor/github.com/dave/dst/contributing.md deleted file mode 100644 index dc0240605f..0000000000 --- a/vendor/github.com/dave/dst/contributing.md +++ /dev/null @@ -1,78 +0,0 @@ -# Building / Developing / Contributing - -The `dst` package relies heavily on code generation. So heavily, in fact, that `README.md` is -itself generated by a preprocessor! Here are a few tips/tricks to get started developing `dst`. - -## Adding Features, Fixing Bugs - -Generally speaking, code handling node annotation is generated from the files in the `gendst` directory. -In order to add/change decorations, edit the `gendst/data.go` file. Once you have made your edits, you can -regenerate the library's source code based on those changes by - -1. `go run github.com/dave/dst/gendst`: This command will build and run a program generated from the - source code in the `gendst` folder that regenerates all the dst source fiels to reflect the changes - that you just made in the `gendst/data.go` file. - -Whenever you make a change to the `gendst/data.go` file, you must perform the aforementioned step. - -If you add a Node to the `gendst/data.go` file, you will need to make corresponding additions to non-generated -files as well. Those files include, but are not limited to,: - -- `dst.go` -- `walk.go` -- `dstutil/rewrite.go` - -Depending on the changes that you have made to the description of the decorated Nodes, you may have to change some, none, -or all of those files listed above (or even others that are not listed!). - -## Adding/Running Tests - -Any changes to the decorations of Nodes (or the addition of new Nodes) should be accompanied -by an entry in `gendst/positions.go`. - -The format of the file is ... - -``` -// -// startLine { - for i := startLine; i < endLine; i++ { - // we avoid the lines that follow the lines in the comment - avoid[i+1] = true - } - } - } - } - } - - // avoid newlines inside multi-line (back-quoted) strings or bad nodes - for _, frag := range f.fragments { - switch frag := frag.(type) { - case *stringFragment: - if !strings.HasPrefix(frag.String, "`") { - continue - } - - startLine := f.Fset.Position(frag.Pos).Line - endLine := f.Fset.Position(frag.Pos + token.Pos(len(frag.String))).Line - - // multi line string - if endLine > startLine { - for i := startLine; i < endLine; i++ { - // we avoid the lines that follow the lines in the string - avoid[i+1] = true - } - } - - case *badFragment: - - // Newlines inside bad nodes are not printed by the formatter, so there is no - // need to reconstruct them in the restorer. - - startLine := f.Fset.Position(frag.Pos).Line - endLine := f.Fset.Position(frag.Pos + token.Pos(frag.Length)).Line - - if endLine > startLine { - for i := startLine; i < endLine; i++ { - // we avoid the lines that follow the lines in the node - avoid[i+1] = true - } - } - } - } - - // Finding the positions of each newline is not easy. We step through the file one byte - // at a time and get the line number from the FileSet. As the line number increments, - // we know where the newlines are. - line := 1 - tokenf := f.Fset.File(astf.Pos()) - max := tokenf.Base() + tokenf.Size() - for i := tokenf.Base(); i < max; i++ { - pos := f.Fset.Position(token.Pos(i)) - if pos.Line != line { - - // if the line number has changed, we're on a new line - - line = pos.Line - - if avoid[line] { - // ignore if it's in the avoid list - e.g. inside a comment or multi-line - // string - continue - } - - // peek ahead to the next position in the fset. If we're on another new line, - // we have an empty line: - nextLine := line - if i < max-1 { - // can't peek forward at the end of the file - nextLine = f.Fset.Position(token.Pos(i + 1)).Line - } - - if nextLine != line { - // add an empty line fragment - f.addNewlineFragment(token.Pos(i-1), true) - - // for empty lines, increment past the second "\n" manually: - line = nextLine - i++ - - } else { - // add a new line fragment - f.addNewlineFragment(token.Pos(i-1), false) - } - - } - } - } - - switch val := node.(type) { - case *ast.File: - processFile(val) - case *ast.Package: - for _, file := range val.Files { - processFile(file) - } - } - - } - - // the comments and newline fragments will be after the node fragments, so we sort the entire - // list by fset position, ensuring that fragments with equal position stay in the original - // order. This ensures that decorations get added to the correct attachment points (which may - // occur at the same fset position). - sort.SliceStable(f.fragments, func(i, j int) bool { - return f.fragments[i].Position() < f.fragments[j].Position() - }) - - // We calculate the indent of the start and end of each node and comment. This is used to - // during the decoration attachment algorithm to correctly attach hanging indent comments. See - // issues 9 and 18 for more info. - currentIndent := 0 - for i, frag := range f.fragments { - if i == 0 || f.fragments[i-1].Newline() { - currentIndent = f.Fset.Position(frag.Position()).Column - } - switch frag := frag.(type) { - case *decorationFragment: - switch frag.Name { - case "Start": - f.startIndents[frag.Node] = currentIndent - case "End": - f.endIndents[frag.Node] = currentIndent - } - case *commentFragment: - frag.Indent = currentIndent - } - } -} - -func (f *fileDecorator) link() { - - // Pass 1: associate comment groups with decorations. Sweep up any other comments / new-lines / - // empty-lines and associate with the same decoration. - for i, frag := range f.fragments { - switch frag := frag.(type) { - case *decorationFragment: - - // Special case for hanging indent (See https://github.com/dave/dst/issues/18) - // - // If we're on the End decoration of a Stmt or Decl, and indents: end == start+1 (OR - // it's a case / comm clause), then search forward over empty lines for all comments - // with the same indent as the End decoration. - // - // These should be attached to the end node. We also search for subsequent comments that - // have the same indent as the Start. If the next decoration node is the start of a Stmt - // or Decl with the same indent as the original node, these are attached there. - - if frag.Name != "End" { - continue - } - _, stmt := frag.Node.(ast.Stmt) - _, decl := frag.Node.(ast.Decl) - if !stmt && !decl { - continue - } - - if _, labeledStmt := frag.Node.(*ast.LabeledStmt); labeledStmt { - // Special case: labeled statements shouldn't be treated in the same way. - continue - } - - start := f.startIndents[frag.Node] - end := f.endIndents[frag.Node] - - _, caseClause := frag.Node.(*ast.CaseClause) - _, commClause := frag.Node.(*ast.CommClause) - if start == end && (caseClause || commClause) { - // special case for case / comm clause with no items... the clause node starts and - // ends on the same line, but comments can still be hanging. We spoof an indented - // end position: - end++ - } - - if end != start+1 { - continue - } - - frags, next := f.findIndentedComments(i+1, [2]int{end, start}) - endFrags := frags[0] - nextFrags := frags[1] - if len(endFrags) > 0 { - // if endFrags ends with a newline, don't attach it because it was in between the - // two groups, so should be left unattached so we can attach it as spacing in the - // second pass - _, nl := endFrags[len(endFrags)-1].(*newlineFragment) - if nl { - f.attachToDecoration(endFrags[0:len(endFrags)-1], f.decorations, frag) - } else { - f.attachToDecoration(endFrags, f.decorations, frag) - } - } - if len(nextFrags) > 0 && next != nil { - _, nextStmt := next.Node.(ast.Stmt) - _, nextDecl := next.Node.(ast.Decl) - nextStart := f.startIndents[next.Node] - if (nextStmt || nextDecl) && nextStart == start { - f.attachToDecoration(nextFrags, f.decorations, next) - } - } - - case *commentFragment: - - if frag.Attached != nil { - continue - } - - // Comments (or comment groups) attach to decoration points in this precedence: - // - // 1) Before the comment on the same line - // 2) After the comment on the same line - // 3) After the comment on subsequent lines (but stopping at empty lines) - // 4) Before the comment on previous lines (but stopping at empty lines) - // 5) After the comment on subsequent lines - // 6) Before the comment on previous lines - // - // We always stop at tokens, strings. If we get to the end without finding a decoration point we panic. - - var frags []fragment // comment / new-line / empty-line - var dec *decorationFragment - var found bool - var try int - for !found { - try++ - switch try { - case 1: - // Before the comment on the same line (search backwards and stop at any newline) - frags, dec, found = f.findDecoration(true, true, i, -1, false) - case 2: - // After the comment on the same line - // After the comment on line+1 (search forwards and stop at any empty line) - frags, dec, found = f.findDecoration(false, true, i, 1, false) - case 3: - // Before the comment on line-1 (search backwards and stop at any empty line) - frags, dec, found = f.findDecoration(false, true, i, -1, false) - case 4: - // After the comment on line+2 (search forwards) - frags, dec, found = f.findDecoration(false, false, i, 1, false) - case 5: - // After the comment on line-2 (search backwards) - frags, dec, found = f.findDecoration(false, false, i, -1, false) - default: - panic("no decoration found for " + frag.Text) - } - } - f.attachToDecoration(frags, f.decorations, dec) - } - } - - // Pass 2: associate any new-lines / empty-lines that have not been added to decorations to node - // spacing. If they can't be attached as node spacing, attach them as decorations. - for i, frag := range f.fragments { - switch frag := frag.(type) { - case *newlineFragment: - - if frag.Attached != nil { - continue - } - - // If the newline is directly before / after a node, we can set the Before / After spacing - // of the node decoration instead of adding the newline as a decoration. - nodeBefore, _, foundBefore := f.findNode(i, 1) - nodeAfter, _, foundAfter := f.findNode(i, -1) - if foundBefore || foundAfter { - spaceType := dst.NewLine - if frag.Empty { - spaceType = dst.EmptyLine - } - if foundBefore { - f.before[nodeBefore] = spaceType - } - if foundAfter { - f.after[nodeAfter] = spaceType - } - continue - } - - // If this newline can't be associated with a node, attach it to the next / previous - // decoration location: - var dec *decorationFragment - var found bool - var try int - for !found { - try++ - switch try { - case 1: - // search backwards but stop at any token - _, dec, found = f.findDecoration(false, false, i, -1, false) - case 2: - // search forwards but stop at any token - _, dec, found = f.findDecoration(false, false, i, 1, false) - default: - panic("no decoration found for newline") - } - } - appendNewLine(f.decorations, dec.Node, dec.Name, frag.Empty) - } - } - - return -} - -func appendDecoration(m map[ast.Node]map[string][]string, n ast.Node, pos, text string) { - if m[n] == nil { - m[n] = map[string][]string{} - } - m[n][pos] = append(m[n][pos], text) -} - -func appendNewLine(m map[ast.Node]map[string][]string, n ast.Node, pos string, empty bool) { - if m[n] == nil { - m[n] = map[string][]string{} - } - num := 1 - if empty { - num = 2 - } - decs := m[n][pos] - if len(decs) > 0 && strings.HasPrefix(decs[len(decs)-1], "//") { - num-- - } - for i := 0; i < num; i++ { - m[n][pos] = append(m[n][pos], "\n") - } -} - -func (f *fileDecorator) attachToDecoration(frags []fragment, decorations map[ast.Node]map[string][]string, dec *decorationFragment) { - for _, fr := range frags { - switch fr := fr.(type) { - case *commentFragment: - appendDecoration(decorations, dec.Node, dec.Name, fr.Text) - fr.Attached = dec - case *newlineFragment: - appendNewLine(decorations, dec.Node, dec.Name, fr.Empty) - fr.Attached = dec - } - } -} - -func (f *fileDecorator) findDecoration(stopAtNewline, stopAtEmptyLine bool, from int, direction int, onlyClause bool) (swept []fragment, dec *decorationFragment, found bool) { - var frags []fragment - for i := from; i < len(f.fragments) && i >= 0; i += direction { - switch current := f.fragments[i].(type) { - case *decorationFragment: - if onlyClause { - switch current.Node.(type) { - case *ast.CommClause, *ast.CaseClause: - if current.Name == "Start" { - return frags, current, true - } - return - default: - return - } - } - return frags, current, true - case *newlineFragment: - if stopAtNewline { - return - } - if stopAtEmptyLine && current.Empty { - return - } - if current.Attached != nil { - continue - } - if direction == 1 { - frags = append(frags, current) - } else { - frags = append([]fragment{current}, frags...) - } - case *commentFragment: - if current.Attached != nil { - continue - } - if direction == 1 { - frags = append(frags, current) - } else { - frags = append([]fragment{current}, frags...) - } - case *tokenFragment, *stringFragment: - return - } - } - return -} - -func (f *fileDecorator) findNode(from int, direction int) (node ast.Node, dec *decorationFragment, found bool) { - - var name string - switch direction { - case 1: - name = "Start" - case -1: - name = "End" - } - - for i := from; i < len(f.fragments) && i >= 0; i += direction { - switch frag := f.fragments[i].(type) { - case *decorationFragment: - if frag.Name == name { - return frag.Node, frag, true - } - return - case *commentFragment: - if frag.Attached != nil && frag.Attached.Name == name { - return frag.Attached.Node, frag.Attached, true - } - case *newlineFragment: - if frag.Attached != nil && frag.Attached.Name == name { - return frag.Attached.Node, frag.Attached, true - } - case *tokenFragment, *stringFragment: - return - } - } - return -} - -func (f *fileDecorator) findIndentedComments(from int, indents [2]int) (frags [2][]fragment, nextDecoration *decorationFragment) { - var stage int - var pastNewline bool // while this is false, we're on the same line that the stmt ended, so we accept all comments regardless of the indent (e.g. empty clauses) - see "hanging-indent-same-line" test case. - for i := from; i < len(f.fragments); i++ { - switch current := f.fragments[i].(type) { - case *decorationFragment: - return frags, current - case *newlineFragment: - pastNewline = true - frags[stage] = append(frags[stage], current) - case *commentFragment: - if !pastNewline { - frags[stage] = append(frags[stage], current) - continue - } - if stage == 0 { - // Check indent matches. If not, move to second stage or exit if that doesn't match. - if current.Indent != indents[0] { - if current.Indent == indents[1] { - stage = 1 - } else { - return - } - } - } else if stage == 1 { - if current.Indent != indents[1] { - return - } - } - frags[stage] = append(frags[stage], current) - case *tokenFragment, *stringFragment: - return - } - } - return -} - -type fragment interface { - Position() token.Pos - Newline() bool // True if the fragment ends in a newline ("\n" or "//...") -} - -type tokenFragment struct { - Node ast.Node - Token token.Token - Pos token.Pos -} - -type stringFragment struct { - Node ast.Node - String string - Pos token.Pos -} - -type badFragment struct { - Node ast.Node - Pos token.Pos - Length int -} - -type commentFragment struct { - Text string - Pos token.Pos - Attached *decorationFragment // where did we attach this comment in pass 1? - Indent int // indent if this comment follows a newline -} - -type newlineFragment struct { - Pos token.Pos - Empty bool // true if this newline is an empty line (e.g. follows a "//" comment or "\n") - Attached *decorationFragment // where did we attach this comment in pass 1? -} - -type decorationFragment struct { - Node ast.Node - Name string - Pos token.Pos -} - -func (v *tokenFragment) Position() token.Pos { return v.Pos } -func (v *stringFragment) Position() token.Pos { return v.Pos } -func (v *commentFragment) Position() token.Pos { return v.Pos } -func (v *newlineFragment) Position() token.Pos { return v.Pos } -func (v *decorationFragment) Position() token.Pos { return v.Pos } -func (v *badFragment) Position() token.Pos { return v.Pos } - -func (v *tokenFragment) Newline() bool { return false } -func (v *stringFragment) Newline() bool { return false } -func (v *commentFragment) Newline() bool { return strings.HasPrefix(v.Text, "//") } -func (v *newlineFragment) Newline() bool { return true } -func (v *decorationFragment) Newline() bool { return false } -func (v *badFragment) Newline() bool { return false } - -func (f fileDecorator) debug(w io.Writer) { - formatPos := func(s token.Position) string { - return s.String()[strings.Index(s.String(), ":")+1:] - } - nodeType := func(n ast.Node) string { - return strings.Replace(fmt.Sprintf("%T", n), "*ast.", "", -1) - } - for _, v := range f.fragments { - switch v := v.(type) { - case *newlineFragment: - if v.Empty { - fmt.Fprintf(w, "Empty line %s\n", formatPos(f.Fset.Position(v.Pos))) - } else { - fmt.Fprintf(w, "New line %s\n", formatPos(f.Fset.Position(v.Pos))) - } - case *tokenFragment: - fmt.Fprintf(w, "%s %q %s\n", nodeType(v.Node), v.Token, formatPos(f.Fset.Position(v.Pos))) - case *stringFragment: - fmt.Fprintf(w, "%s %q %s\n", nodeType(v.Node), v.String, formatPos(f.Fset.Position(v.Pos))) - case *decorationFragment: - fmt.Fprintf(w, "%s %s %s\n", nodeType(v.Node), v.Name, formatPos(f.Fset.Position(v.Pos))) - case *commentFragment: - fmt.Fprintf(w, "%q %s\n", v.Text, formatPos(f.Fset.Position(v.Pos))) - case *badFragment: - fmt.Fprintf(w, "%s %d %s\n", nodeType(v.Node), v.Length, formatPos(f.Fset.Position(v.Pos))) - default: - fmt.Fprintf(w, "%T %s\n", v, formatPos(f.Fset.Position(v.Position()))) - } - } -} diff --git a/vendor/github.com/dave/dst/decorator/decorator-node-generated.go b/vendor/github.com/dave/dst/decorator/decorator-node-generated.go deleted file mode 100644 index 72044ec772..0000000000 --- a/vendor/github.com/dave/dst/decorator/decorator-node-generated.go +++ /dev/null @@ -1,2379 +0,0 @@ -package decorator - -import ( - "github.com/dave/dst" - "go/ast" - "go/token" -) - -func (f *fileDecorator) decorateNode(parent ast.Node, parentName, parentField, parentFieldType string, n ast.Node) (dst.Node, error) { - if dn, ok := f.Dst.Nodes[n]; ok { - return dn, nil - } - switch n := n.(type) { - case *ast.ArrayType: - out := &dst.ArrayType{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Token: Lbrack - - // Node: Len - if n.Len != nil { - child, err := f.decorateNode(n, "ArrayType", "Len", "Expr", n.Len) - if err != nil { - return nil, err - } - out.Len = child.(dst.Expr) - } - - // Token: Rbrack - - // Node: Elt - if n.Elt != nil { - child, err := f.decorateNode(n, "ArrayType", "Elt", "Expr", n.Elt) - if err != nil { - return nil, err - } - out.Elt = child.(dst.Expr) - } - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["Lbrack"]; ok { - out.Decs.Lbrack = decs - } - if decs, ok := nd["Len"]; ok { - out.Decs.Len = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.AssignStmt: - out := &dst.AssignStmt{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // List: Lhs - for _, v := range n.Lhs { - child, err := f.decorateNode(n, "AssignStmt", "Lhs", "Expr", v) - if err != nil { - return nil, err - } - out.Lhs = append(out.Lhs, child.(dst.Expr)) - } - - // Token: Tok - out.Tok = n.Tok - - // List: Rhs - for _, v := range n.Rhs { - child, err := f.decorateNode(n, "AssignStmt", "Rhs", "Expr", v) - if err != nil { - return nil, err - } - out.Rhs = append(out.Rhs, child.(dst.Expr)) - } - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["Tok"]; ok { - out.Decs.Tok = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.BadDecl: - out := &dst.BadDecl{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Bad - out.Length = int(n.To - n.From) - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.BadExpr: - out := &dst.BadExpr{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Bad - out.Length = int(n.To - n.From) - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.BadStmt: - out := &dst.BadStmt{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Bad - out.Length = int(n.To - n.From) - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.BasicLit: - out := &dst.BasicLit{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // String: Value - out.Value = n.Value - - // Value: Kind - out.Kind = n.Kind - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.BinaryExpr: - out := &dst.BinaryExpr{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Node: X - if n.X != nil { - child, err := f.decorateNode(n, "BinaryExpr", "X", "Expr", n.X) - if err != nil { - return nil, err - } - out.X = child.(dst.Expr) - } - - // Token: Op - out.Op = n.Op - - // Node: Y - if n.Y != nil { - child, err := f.decorateNode(n, "BinaryExpr", "Y", "Expr", n.Y) - if err != nil { - return nil, err - } - out.Y = child.(dst.Expr) - } - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["X"]; ok { - out.Decs.X = decs - } - if decs, ok := nd["Op"]; ok { - out.Decs.Op = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.BlockStmt: - out := &dst.BlockStmt{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Token: Lbrace - - // List: List - for _, v := range n.List { - child, err := f.decorateNode(n, "BlockStmt", "List", "Stmt", v) - if err != nil { - return nil, err - } - out.List = append(out.List, child.(dst.Stmt)) - } - - // Token: Rbrace - if n.Rbrace == token.NoPos { - out.RbraceHasNoPos = true - } - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["Lbrace"]; ok { - out.Decs.Lbrace = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.BranchStmt: - out := &dst.BranchStmt{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Token: Tok - out.Tok = n.Tok - - // Node: Label - if n.Label != nil { - child, err := f.decorateNode(n, "BranchStmt", "Label", "Ident", n.Label) - if err != nil { - return nil, err - } - out.Label = child.(*dst.Ident) - } - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["Tok"]; ok { - out.Decs.Tok = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.CallExpr: - out := &dst.CallExpr{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Node: Fun - if n.Fun != nil { - child, err := f.decorateNode(n, "CallExpr", "Fun", "Expr", n.Fun) - if err != nil { - return nil, err - } - out.Fun = child.(dst.Expr) - } - - // Token: Lparen - - // List: Args - for _, v := range n.Args { - child, err := f.decorateNode(n, "CallExpr", "Args", "Expr", v) - if err != nil { - return nil, err - } - out.Args = append(out.Args, child.(dst.Expr)) - } - - // Token: Ellipsis - out.Ellipsis = n.Ellipsis.IsValid() - - // Token: Rparen - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["Fun"]; ok { - out.Decs.Fun = decs - } - if decs, ok := nd["Lparen"]; ok { - out.Decs.Lparen = decs - } - if decs, ok := nd["Ellipsis"]; ok { - out.Decs.Ellipsis = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.CaseClause: - out := &dst.CaseClause{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Token: Case - - // List: List - for _, v := range n.List { - child, err := f.decorateNode(n, "CaseClause", "List", "Expr", v) - if err != nil { - return nil, err - } - out.List = append(out.List, child.(dst.Expr)) - } - - // Token: Colon - - // List: Body - for _, v := range n.Body { - child, err := f.decorateNode(n, "CaseClause", "Body", "Stmt", v) - if err != nil { - return nil, err - } - out.Body = append(out.Body, child.(dst.Stmt)) - } - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["Case"]; ok { - out.Decs.Case = decs - } - if decs, ok := nd["Colon"]; ok { - out.Decs.Colon = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.ChanType: - out := &dst.ChanType{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Token: Begin - - // Token: Chan - - // Token: Arrow - - // Node: Value - if n.Value != nil { - child, err := f.decorateNode(n, "ChanType", "Value", "Expr", n.Value) - if err != nil { - return nil, err - } - out.Value = child.(dst.Expr) - } - - // Value: Dir - out.Dir = dst.ChanDir(n.Dir) - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["Begin"]; ok { - out.Decs.Begin = decs - } - if decs, ok := nd["Arrow"]; ok { - out.Decs.Arrow = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.CommClause: - out := &dst.CommClause{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Token: Case - - // Node: Comm - if n.Comm != nil { - child, err := f.decorateNode(n, "CommClause", "Comm", "Stmt", n.Comm) - if err != nil { - return nil, err - } - out.Comm = child.(dst.Stmt) - } - - // Token: Colon - - // List: Body - for _, v := range n.Body { - child, err := f.decorateNode(n, "CommClause", "Body", "Stmt", v) - if err != nil { - return nil, err - } - out.Body = append(out.Body, child.(dst.Stmt)) - } - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["Case"]; ok { - out.Decs.Case = decs - } - if decs, ok := nd["Comm"]; ok { - out.Decs.Comm = decs - } - if decs, ok := nd["Colon"]; ok { - out.Decs.Colon = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.CompositeLit: - out := &dst.CompositeLit{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Node: Type - if n.Type != nil { - child, err := f.decorateNode(n, "CompositeLit", "Type", "Expr", n.Type) - if err != nil { - return nil, err - } - out.Type = child.(dst.Expr) - } - - // Token: Lbrace - - // List: Elts - for _, v := range n.Elts { - child, err := f.decorateNode(n, "CompositeLit", "Elts", "Expr", v) - if err != nil { - return nil, err - } - out.Elts = append(out.Elts, child.(dst.Expr)) - } - - // Token: Rbrace - - // Value: Incomplete - out.Incomplete = n.Incomplete - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["Type"]; ok { - out.Decs.Type = decs - } - if decs, ok := nd["Lbrace"]; ok { - out.Decs.Lbrace = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.DeclStmt: - out := &dst.DeclStmt{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Node: Decl - if n.Decl != nil { - child, err := f.decorateNode(n, "DeclStmt", "Decl", "Decl", n.Decl) - if err != nil { - return nil, err - } - out.Decl = child.(dst.Decl) - } - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.DeferStmt: - out := &dst.DeferStmt{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Token: Defer - - // Node: Call - if n.Call != nil { - child, err := f.decorateNode(n, "DeferStmt", "Call", "CallExpr", n.Call) - if err != nil { - return nil, err - } - out.Call = child.(*dst.CallExpr) - } - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["Defer"]; ok { - out.Decs.Defer = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.Ellipsis: - out := &dst.Ellipsis{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Token: Ellipsis - - // Node: Elt - if n.Elt != nil { - child, err := f.decorateNode(n, "Ellipsis", "Elt", "Expr", n.Elt) - if err != nil { - return nil, err - } - out.Elt = child.(dst.Expr) - } - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["Ellipsis"]; ok { - out.Decs.Ellipsis = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.EmptyStmt: - out := &dst.EmptyStmt{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Token: Semicolon - - // Value: Implicit - out.Implicit = n.Implicit - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.ExprStmt: - out := &dst.ExprStmt{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Node: X - if n.X != nil { - child, err := f.decorateNode(n, "ExprStmt", "X", "Expr", n.X) - if err != nil { - return nil, err - } - out.X = child.(dst.Expr) - } - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.Field: - out := &dst.Field{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // List: Names - for _, v := range n.Names { - child, err := f.decorateNode(n, "Field", "Names", "Ident", v) - if err != nil { - return nil, err - } - out.Names = append(out.Names, child.(*dst.Ident)) - } - - // Node: Type - if n.Type != nil { - child, err := f.decorateNode(n, "Field", "Type", "Expr", n.Type) - if err != nil { - return nil, err - } - out.Type = child.(dst.Expr) - } - - // Node: Tag - if n.Tag != nil { - child, err := f.decorateNode(n, "Field", "Tag", "BasicLit", n.Tag) - if err != nil { - return nil, err - } - out.Tag = child.(*dst.BasicLit) - } - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["Type"]; ok { - out.Decs.Type = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.FieldList: - out := &dst.FieldList{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Token: Opening - out.Opening = n.Opening.IsValid() - - // List: List - for _, v := range n.List { - child, err := f.decorateNode(n, "FieldList", "List", "Field", v) - if err != nil { - return nil, err - } - out.List = append(out.List, child.(*dst.Field)) - } - - // Token: Closing - out.Closing = n.Closing.IsValid() - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["Opening"]; ok { - out.Decs.Opening = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.File: - out := &dst.File{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Token: Package - - // Node: Name - if n.Name != nil { - child, err := f.decorateNode(n, "File", "Name", "Ident", n.Name) - if err != nil { - return nil, err - } - out.Name = child.(*dst.Ident) - } - - // List: Decls - for _, v := range n.Decls { - child, err := f.decorateNode(n, "File", "Decls", "Decl", v) - if err != nil { - return nil, err - } - out.Decls = append(out.Decls, child.(dst.Decl)) - } - - // Scope: Scope - scope, err := f.decorateScope(n.Scope) - if err != nil { - return nil, err - } - out.Scope = scope - - // List: Imports - for _, v := range n.Imports { - child, err := f.decorateNode(n, "File", "Imports", "ImportSpec", v) - if err != nil { - return nil, err - } - out.Imports = append(out.Imports, child.(*dst.ImportSpec)) - } - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["Package"]; ok { - out.Decs.Package = decs - } - if decs, ok := nd["Name"]; ok { - out.Decs.Name = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.ForStmt: - out := &dst.ForStmt{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Token: For - - // Node: Init - if n.Init != nil { - child, err := f.decorateNode(n, "ForStmt", "Init", "Stmt", n.Init) - if err != nil { - return nil, err - } - out.Init = child.(dst.Stmt) - } - - // Token: InitSemicolon - - // Node: Cond - if n.Cond != nil { - child, err := f.decorateNode(n, "ForStmt", "Cond", "Expr", n.Cond) - if err != nil { - return nil, err - } - out.Cond = child.(dst.Expr) - } - - // Token: CondSemicolon - - // Node: Post - if n.Post != nil { - child, err := f.decorateNode(n, "ForStmt", "Post", "Stmt", n.Post) - if err != nil { - return nil, err - } - out.Post = child.(dst.Stmt) - } - - // Node: Body - if n.Body != nil { - child, err := f.decorateNode(n, "ForStmt", "Body", "BlockStmt", n.Body) - if err != nil { - return nil, err - } - out.Body = child.(*dst.BlockStmt) - } - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["For"]; ok { - out.Decs.For = decs - } - if decs, ok := nd["Init"]; ok { - out.Decs.Init = decs - } - if decs, ok := nd["Cond"]; ok { - out.Decs.Cond = decs - } - if decs, ok := nd["Post"]; ok { - out.Decs.Post = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.FuncDecl: - out := &dst.FuncDecl{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Init: Type - out.Type = &dst.FuncType{} - f.Dst.Nodes[n.Type] = out.Type - f.Ast.Nodes[out.Type] = n.Type - - // Token: Func - out.Type.Func = true - - // Node: Recv - if n.Recv != nil { - child, err := f.decorateNode(n, "FuncDecl", "Recv", "FieldList", n.Recv) - if err != nil { - return nil, err - } - out.Recv = child.(*dst.FieldList) - } - - // Node: Name - if n.Name != nil { - child, err := f.decorateNode(n, "FuncDecl", "Name", "Ident", n.Name) - if err != nil { - return nil, err - } - out.Name = child.(*dst.Ident) - } - - // Node: TypeParams - if n.Type.TypeParams != nil { - child, err := f.decorateNode(n, "FuncDecl", "TypeParams", "FieldList", n.Type.TypeParams) - if err != nil { - return nil, err - } - out.Type.TypeParams = child.(*dst.FieldList) - } - - // Node: Params - if n.Type.Params != nil { - child, err := f.decorateNode(n, "FuncDecl", "Params", "FieldList", n.Type.Params) - if err != nil { - return nil, err - } - out.Type.Params = child.(*dst.FieldList) - } - - // Node: Results - if n.Type.Results != nil { - child, err := f.decorateNode(n, "FuncDecl", "Results", "FieldList", n.Type.Results) - if err != nil { - return nil, err - } - out.Type.Results = child.(*dst.FieldList) - } - - // Node: Body - if n.Body != nil { - child, err := f.decorateNode(n, "FuncDecl", "Body", "BlockStmt", n.Body) - if err != nil { - return nil, err - } - out.Body = child.(*dst.BlockStmt) - } - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["Func"]; ok { - out.Decs.Func = decs - } - if decs, ok := nd["Recv"]; ok { - out.Decs.Recv = decs - } - if decs, ok := nd["Name"]; ok { - out.Decs.Name = decs - } - if decs, ok := nd["TypeParams"]; ok { - out.Decs.TypeParams = decs - } - if decs, ok := nd["Params"]; ok { - out.Decs.Params = decs - } - if decs, ok := nd["Results"]; ok { - out.Decs.Results = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.FuncLit: - out := &dst.FuncLit{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Node: Type - if n.Type != nil { - child, err := f.decorateNode(n, "FuncLit", "Type", "FuncType", n.Type) - if err != nil { - return nil, err - } - out.Type = child.(*dst.FuncType) - } - - // Node: Body - if n.Body != nil { - child, err := f.decorateNode(n, "FuncLit", "Body", "BlockStmt", n.Body) - if err != nil { - return nil, err - } - out.Body = child.(*dst.BlockStmt) - } - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["Type"]; ok { - out.Decs.Type = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.FuncType: - out := &dst.FuncType{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Token: Func - out.Func = n.Func.IsValid() - - // Node: TypeParams - if n.TypeParams != nil { - child, err := f.decorateNode(n, "FuncType", "TypeParams", "FieldList", n.TypeParams) - if err != nil { - return nil, err - } - out.TypeParams = child.(*dst.FieldList) - } - - // Node: Params - if n.Params != nil { - child, err := f.decorateNode(n, "FuncType", "Params", "FieldList", n.Params) - if err != nil { - return nil, err - } - out.Params = child.(*dst.FieldList) - } - - // Node: Results - if n.Results != nil { - child, err := f.decorateNode(n, "FuncType", "Results", "FieldList", n.Results) - if err != nil { - return nil, err - } - out.Results = child.(*dst.FieldList) - } - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["Func"]; ok { - out.Decs.Func = decs - } - if decs, ok := nd["TypeParams"]; ok { - out.Decs.TypeParams = decs - } - if decs, ok := nd["Params"]; ok { - out.Decs.Params = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.GenDecl: - out := &dst.GenDecl{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Token: Tok - out.Tok = n.Tok - - // Token: Lparen - out.Lparen = n.Lparen.IsValid() - - // List: Specs - for _, v := range n.Specs { - child, err := f.decorateNode(n, "GenDecl", "Specs", "Spec", v) - if err != nil { - return nil, err - } - out.Specs = append(out.Specs, child.(dst.Spec)) - } - - // Token: Rparen - out.Rparen = n.Rparen.IsValid() - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["Tok"]; ok { - out.Decs.Tok = decs - } - if decs, ok := nd["Lparen"]; ok { - out.Decs.Lparen = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.GoStmt: - out := &dst.GoStmt{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Token: Go - - // Node: Call - if n.Call != nil { - child, err := f.decorateNode(n, "GoStmt", "Call", "CallExpr", n.Call) - if err != nil { - return nil, err - } - out.Call = child.(*dst.CallExpr) - } - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["Go"]; ok { - out.Decs.Go = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.Ident: - out := &dst.Ident{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // String: Name - out.Name = n.Name - - // Object: Obj - ob, err := f.decorateObject(n.Obj) - if err != nil { - return nil, err - } - out.Obj = ob - - // Path: Path - if f.Resolver != nil { - path, err := f.resolvePath(false, parent, parentName, parentField, parentFieldType, n) - if err != nil { - return nil, err - } - out.Path = path - } - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["X"]; ok { - out.Decs.X = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.IfStmt: - out := &dst.IfStmt{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Token: If - - // Node: Init - if n.Init != nil { - child, err := f.decorateNode(n, "IfStmt", "Init", "Stmt", n.Init) - if err != nil { - return nil, err - } - out.Init = child.(dst.Stmt) - } - - // Node: Cond - if n.Cond != nil { - child, err := f.decorateNode(n, "IfStmt", "Cond", "Expr", n.Cond) - if err != nil { - return nil, err - } - out.Cond = child.(dst.Expr) - } - - // Node: Body - if n.Body != nil { - child, err := f.decorateNode(n, "IfStmt", "Body", "BlockStmt", n.Body) - if err != nil { - return nil, err - } - out.Body = child.(*dst.BlockStmt) - } - - // Token: ElseTok - - // Node: Else - if n.Else != nil { - child, err := f.decorateNode(n, "IfStmt", "Else", "Stmt", n.Else) - if err != nil { - return nil, err - } - out.Else = child.(dst.Stmt) - } - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["If"]; ok { - out.Decs.If = decs - } - if decs, ok := nd["Init"]; ok { - out.Decs.Init = decs - } - if decs, ok := nd["Cond"]; ok { - out.Decs.Cond = decs - } - if decs, ok := nd["Else"]; ok { - out.Decs.Else = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.ImportSpec: - out := &dst.ImportSpec{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Node: Name - if n.Name != nil { - child, err := f.decorateNode(n, "ImportSpec", "Name", "Ident", n.Name) - if err != nil { - return nil, err - } - out.Name = child.(*dst.Ident) - } - - // Node: Path - if n.Path != nil { - child, err := f.decorateNode(n, "ImportSpec", "Path", "BasicLit", n.Path) - if err != nil { - return nil, err - } - out.Path = child.(*dst.BasicLit) - } - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["Name"]; ok { - out.Decs.Name = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.IncDecStmt: - out := &dst.IncDecStmt{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Node: X - if n.X != nil { - child, err := f.decorateNode(n, "IncDecStmt", "X", "Expr", n.X) - if err != nil { - return nil, err - } - out.X = child.(dst.Expr) - } - - // Token: Tok - out.Tok = n.Tok - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["X"]; ok { - out.Decs.X = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.IndexExpr: - out := &dst.IndexExpr{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Node: X - if n.X != nil { - child, err := f.decorateNode(n, "IndexExpr", "X", "Expr", n.X) - if err != nil { - return nil, err - } - out.X = child.(dst.Expr) - } - - // Token: Lbrack - - // Node: Index - if n.Index != nil { - child, err := f.decorateNode(n, "IndexExpr", "Index", "Expr", n.Index) - if err != nil { - return nil, err - } - out.Index = child.(dst.Expr) - } - - // Token: Rbrack - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["X"]; ok { - out.Decs.X = decs - } - if decs, ok := nd["Lbrack"]; ok { - out.Decs.Lbrack = decs - } - if decs, ok := nd["Index"]; ok { - out.Decs.Index = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.IndexListExpr: - out := &dst.IndexListExpr{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Node: X - if n.X != nil { - child, err := f.decorateNode(n, "IndexListExpr", "X", "Expr", n.X) - if err != nil { - return nil, err - } - out.X = child.(dst.Expr) - } - - // Token: Lbrack - - // List: Indices - for _, v := range n.Indices { - child, err := f.decorateNode(n, "IndexListExpr", "Indices", "Expr", v) - if err != nil { - return nil, err - } - out.Indices = append(out.Indices, child.(dst.Expr)) - } - - // Token: Rbrack - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["X"]; ok { - out.Decs.X = decs - } - if decs, ok := nd["Lbrack"]; ok { - out.Decs.Lbrack = decs - } - if decs, ok := nd["Indices"]; ok { - out.Decs.Indices = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.InterfaceType: - out := &dst.InterfaceType{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Token: Interface - - // Node: Methods - if n.Methods != nil { - child, err := f.decorateNode(n, "InterfaceType", "Methods", "FieldList", n.Methods) - if err != nil { - return nil, err - } - out.Methods = child.(*dst.FieldList) - } - - // Value: Incomplete - out.Incomplete = n.Incomplete - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["Interface"]; ok { - out.Decs.Interface = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.KeyValueExpr: - out := &dst.KeyValueExpr{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Node: Key - if n.Key != nil { - child, err := f.decorateNode(n, "KeyValueExpr", "Key", "Expr", n.Key) - if err != nil { - return nil, err - } - out.Key = child.(dst.Expr) - } - - // Token: Colon - - // Node: Value - if n.Value != nil { - child, err := f.decorateNode(n, "KeyValueExpr", "Value", "Expr", n.Value) - if err != nil { - return nil, err - } - out.Value = child.(dst.Expr) - } - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["Key"]; ok { - out.Decs.Key = decs - } - if decs, ok := nd["Colon"]; ok { - out.Decs.Colon = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.LabeledStmt: - out := &dst.LabeledStmt{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Node: Label - if n.Label != nil { - child, err := f.decorateNode(n, "LabeledStmt", "Label", "Ident", n.Label) - if err != nil { - return nil, err - } - out.Label = child.(*dst.Ident) - } - - // Token: Colon - - // Node: Stmt - if n.Stmt != nil { - child, err := f.decorateNode(n, "LabeledStmt", "Stmt", "Stmt", n.Stmt) - if err != nil { - return nil, err - } - out.Stmt = child.(dst.Stmt) - } - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["Label"]; ok { - out.Decs.Label = decs - } - if decs, ok := nd["Colon"]; ok { - out.Decs.Colon = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.MapType: - out := &dst.MapType{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Token: Map - - // Token: Lbrack - - // Node: Key - if n.Key != nil { - child, err := f.decorateNode(n, "MapType", "Key", "Expr", n.Key) - if err != nil { - return nil, err - } - out.Key = child.(dst.Expr) - } - - // Token: Rbrack - - // Node: Value - if n.Value != nil { - child, err := f.decorateNode(n, "MapType", "Value", "Expr", n.Value) - if err != nil { - return nil, err - } - out.Value = child.(dst.Expr) - } - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["Map"]; ok { - out.Decs.Map = decs - } - if decs, ok := nd["Key"]; ok { - out.Decs.Key = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.Package: - out := &dst.Package{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - // Value: Name - out.Name = n.Name - - // Scope: Scope - scope, err := f.decorateScope(n.Scope) - if err != nil { - return nil, err - } - out.Scope = scope - - // Map: Imports - out.Imports = map[string]*dst.Object{} - for k, v := range n.Imports { - ob, err := f.decorateObject(v) - if err != nil { - return nil, err - } - out.Imports[k] = ob - } - - // Map: Files - out.Files = map[string]*dst.File{} - for k, v := range n.Files { - child, err := f.decorateNode(n, "Package", "Files", "File", v) - if err != nil { - return nil, err - } - out.Files[k] = child.(*dst.File) - } - - return out, nil - case *ast.ParenExpr: - out := &dst.ParenExpr{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Token: Lparen - - // Node: X - if n.X != nil { - child, err := f.decorateNode(n, "ParenExpr", "X", "Expr", n.X) - if err != nil { - return nil, err - } - out.X = child.(dst.Expr) - } - - // Token: Rparen - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["Lparen"]; ok { - out.Decs.Lparen = decs - } - if decs, ok := nd["X"]; ok { - out.Decs.X = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.RangeStmt: - out := &dst.RangeStmt{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Token: For - - // Node: Key - if n.Key != nil { - child, err := f.decorateNode(n, "RangeStmt", "Key", "Expr", n.Key) - if err != nil { - return nil, err - } - out.Key = child.(dst.Expr) - } - - // Token: Comma - - // Node: Value - if n.Value != nil { - child, err := f.decorateNode(n, "RangeStmt", "Value", "Expr", n.Value) - if err != nil { - return nil, err - } - out.Value = child.(dst.Expr) - } - - // Token: Tok - out.Tok = n.Tok - - // Token: Range - - // Node: X - if n.X != nil { - child, err := f.decorateNode(n, "RangeStmt", "X", "Expr", n.X) - if err != nil { - return nil, err - } - out.X = child.(dst.Expr) - } - - // Node: Body - if n.Body != nil { - child, err := f.decorateNode(n, "RangeStmt", "Body", "BlockStmt", n.Body) - if err != nil { - return nil, err - } - out.Body = child.(*dst.BlockStmt) - } - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["For"]; ok { - out.Decs.For = decs - } - if decs, ok := nd["Key"]; ok { - out.Decs.Key = decs - } - if decs, ok := nd["Value"]; ok { - out.Decs.Value = decs - } - if decs, ok := nd["Range"]; ok { - out.Decs.Range = decs - } - if decs, ok := nd["X"]; ok { - out.Decs.X = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.ReturnStmt: - out := &dst.ReturnStmt{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Token: Return - - // List: Results - for _, v := range n.Results { - child, err := f.decorateNode(n, "ReturnStmt", "Results", "Expr", v) - if err != nil { - return nil, err - } - out.Results = append(out.Results, child.(dst.Expr)) - } - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["Return"]; ok { - out.Decs.Return = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.SelectStmt: - out := &dst.SelectStmt{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Token: Select - - // Node: Body - if n.Body != nil { - child, err := f.decorateNode(n, "SelectStmt", "Body", "BlockStmt", n.Body) - if err != nil { - return nil, err - } - out.Body = child.(*dst.BlockStmt) - } - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["Select"]; ok { - out.Decs.Select = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.SelectorExpr: - - // Special case for *ast.SelectorExpr - replace with Ident if needed - id, err := f.decorateSelectorExpr(parent, parentName, parentField, parentFieldType, n) - if err != nil { - return nil, err - } - if id != nil { - return id, nil - } - - out := &dst.SelectorExpr{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Node: X - if n.X != nil { - child, err := f.decorateNode(n, "SelectorExpr", "X", "Expr", n.X) - if err != nil { - return nil, err - } - out.X = child.(dst.Expr) - } - - // Token: Period - - // Node: Sel - if n.Sel != nil { - child, err := f.decorateNode(n, "SelectorExpr", "Sel", "Ident", n.Sel) - if err != nil { - return nil, err - } - out.Sel = child.(*dst.Ident) - } - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["X"]; ok { - out.Decs.X = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.SendStmt: - out := &dst.SendStmt{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Node: Chan - if n.Chan != nil { - child, err := f.decorateNode(n, "SendStmt", "Chan", "Expr", n.Chan) - if err != nil { - return nil, err - } - out.Chan = child.(dst.Expr) - } - - // Token: Arrow - - // Node: Value - if n.Value != nil { - child, err := f.decorateNode(n, "SendStmt", "Value", "Expr", n.Value) - if err != nil { - return nil, err - } - out.Value = child.(dst.Expr) - } - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["Chan"]; ok { - out.Decs.Chan = decs - } - if decs, ok := nd["Arrow"]; ok { - out.Decs.Arrow = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.SliceExpr: - out := &dst.SliceExpr{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Node: X - if n.X != nil { - child, err := f.decorateNode(n, "SliceExpr", "X", "Expr", n.X) - if err != nil { - return nil, err - } - out.X = child.(dst.Expr) - } - - // Token: Lbrack - - // Node: Low - if n.Low != nil { - child, err := f.decorateNode(n, "SliceExpr", "Low", "Expr", n.Low) - if err != nil { - return nil, err - } - out.Low = child.(dst.Expr) - } - - // Token: Colon1 - - // Node: High - if n.High != nil { - child, err := f.decorateNode(n, "SliceExpr", "High", "Expr", n.High) - if err != nil { - return nil, err - } - out.High = child.(dst.Expr) - } - - // Token: Colon2 - - // Node: Max - if n.Max != nil { - child, err := f.decorateNode(n, "SliceExpr", "Max", "Expr", n.Max) - if err != nil { - return nil, err - } - out.Max = child.(dst.Expr) - } - - // Token: Rbrack - - // Value: Slice3 - out.Slice3 = n.Slice3 - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["X"]; ok { - out.Decs.X = decs - } - if decs, ok := nd["Lbrack"]; ok { - out.Decs.Lbrack = decs - } - if decs, ok := nd["Low"]; ok { - out.Decs.Low = decs - } - if decs, ok := nd["High"]; ok { - out.Decs.High = decs - } - if decs, ok := nd["Max"]; ok { - out.Decs.Max = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.StarExpr: - out := &dst.StarExpr{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Token: Star - - // Node: X - if n.X != nil { - child, err := f.decorateNode(n, "StarExpr", "X", "Expr", n.X) - if err != nil { - return nil, err - } - out.X = child.(dst.Expr) - } - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["Star"]; ok { - out.Decs.Star = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.StructType: - out := &dst.StructType{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Token: Struct - - // Node: Fields - if n.Fields != nil { - child, err := f.decorateNode(n, "StructType", "Fields", "FieldList", n.Fields) - if err != nil { - return nil, err - } - out.Fields = child.(*dst.FieldList) - } - - // Value: Incomplete - out.Incomplete = n.Incomplete - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["Struct"]; ok { - out.Decs.Struct = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.SwitchStmt: - out := &dst.SwitchStmt{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Token: Switch - - // Node: Init - if n.Init != nil { - child, err := f.decorateNode(n, "SwitchStmt", "Init", "Stmt", n.Init) - if err != nil { - return nil, err - } - out.Init = child.(dst.Stmt) - } - - // Node: Tag - if n.Tag != nil { - child, err := f.decorateNode(n, "SwitchStmt", "Tag", "Expr", n.Tag) - if err != nil { - return nil, err - } - out.Tag = child.(dst.Expr) - } - - // Node: Body - if n.Body != nil { - child, err := f.decorateNode(n, "SwitchStmt", "Body", "BlockStmt", n.Body) - if err != nil { - return nil, err - } - out.Body = child.(*dst.BlockStmt) - } - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["Switch"]; ok { - out.Decs.Switch = decs - } - if decs, ok := nd["Init"]; ok { - out.Decs.Init = decs - } - if decs, ok := nd["Tag"]; ok { - out.Decs.Tag = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.TypeAssertExpr: - out := &dst.TypeAssertExpr{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Node: X - if n.X != nil { - child, err := f.decorateNode(n, "TypeAssertExpr", "X", "Expr", n.X) - if err != nil { - return nil, err - } - out.X = child.(dst.Expr) - } - - // Token: Period - - // Token: Lparen - - // Node: Type - if n.Type != nil { - child, err := f.decorateNode(n, "TypeAssertExpr", "Type", "Expr", n.Type) - if err != nil { - return nil, err - } - out.Type = child.(dst.Expr) - } - - // Token: TypeToken - - // Token: Rparen - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["X"]; ok { - out.Decs.X = decs - } - if decs, ok := nd["Lparen"]; ok { - out.Decs.Lparen = decs - } - if decs, ok := nd["Type"]; ok { - out.Decs.Type = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.TypeSpec: - out := &dst.TypeSpec{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Node: Name - if n.Name != nil { - child, err := f.decorateNode(n, "TypeSpec", "Name", "Ident", n.Name) - if err != nil { - return nil, err - } - out.Name = child.(*dst.Ident) - } - - // Token: Assign - out.Assign = n.Assign.IsValid() - - // Node: TypeParams - if n.TypeParams != nil { - child, err := f.decorateNode(n, "TypeSpec", "TypeParams", "FieldList", n.TypeParams) - if err != nil { - return nil, err - } - out.TypeParams = child.(*dst.FieldList) - } - - // Node: Type - if n.Type != nil { - child, err := f.decorateNode(n, "TypeSpec", "Type", "Expr", n.Type) - if err != nil { - return nil, err - } - out.Type = child.(dst.Expr) - } - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["Name"]; ok { - out.Decs.Name = decs - } - if decs, ok := nd["TypeParams"]; ok { - out.Decs.TypeParams = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.TypeSwitchStmt: - out := &dst.TypeSwitchStmt{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Token: Switch - - // Node: Init - if n.Init != nil { - child, err := f.decorateNode(n, "TypeSwitchStmt", "Init", "Stmt", n.Init) - if err != nil { - return nil, err - } - out.Init = child.(dst.Stmt) - } - - // Node: Assign - if n.Assign != nil { - child, err := f.decorateNode(n, "TypeSwitchStmt", "Assign", "Stmt", n.Assign) - if err != nil { - return nil, err - } - out.Assign = child.(dst.Stmt) - } - - // Node: Body - if n.Body != nil { - child, err := f.decorateNode(n, "TypeSwitchStmt", "Body", "BlockStmt", n.Body) - if err != nil { - return nil, err - } - out.Body = child.(*dst.BlockStmt) - } - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["Switch"]; ok { - out.Decs.Switch = decs - } - if decs, ok := nd["Init"]; ok { - out.Decs.Init = decs - } - if decs, ok := nd["Assign"]; ok { - out.Decs.Assign = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.UnaryExpr: - out := &dst.UnaryExpr{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // Token: Op - out.Op = n.Op - - // Node: X - if n.X != nil { - child, err := f.decorateNode(n, "UnaryExpr", "X", "Expr", n.X) - if err != nil { - return nil, err - } - out.X = child.(dst.Expr) - } - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["Op"]; ok { - out.Decs.Op = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - case *ast.ValueSpec: - out := &dst.ValueSpec{} - f.Dst.Nodes[n] = out - f.Ast.Nodes[out] = n - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - // List: Names - for _, v := range n.Names { - child, err := f.decorateNode(n, "ValueSpec", "Names", "Ident", v) - if err != nil { - return nil, err - } - out.Names = append(out.Names, child.(*dst.Ident)) - } - - // Node: Type - if n.Type != nil { - child, err := f.decorateNode(n, "ValueSpec", "Type", "Expr", n.Type) - if err != nil { - return nil, err - } - out.Type = child.(dst.Expr) - } - - // Token: Assign - - // List: Values - for _, v := range n.Values { - child, err := f.decorateNode(n, "ValueSpec", "Values", "Expr", v) - if err != nil { - return nil, err - } - out.Values = append(out.Values, child.(dst.Expr)) - } - - if nd, ok := f.decorations[n]; ok { - if decs, ok := nd["Start"]; ok { - out.Decs.Start = decs - } - if decs, ok := nd["Assign"]; ok { - out.Decs.Assign = decs - } - if decs, ok := nd["End"]; ok { - out.Decs.End = decs - } - } - - return out, nil - } - return nil, nil -} diff --git a/vendor/github.com/dave/dst/decorator/decorator.go b/vendor/github.com/dave/dst/decorator/decorator.go deleted file mode 100644 index dc9eaef7b9..0000000000 --- a/vendor/github.com/dave/dst/decorator/decorator.go +++ /dev/null @@ -1,560 +0,0 @@ -package decorator - -import ( - "fmt" - "go/ast" - "go/parser" - "go/token" - "io" - "os" - "strings" - - "github.com/dave/dst" - "github.com/dave/dst/decorator/resolver" - "github.com/dave/dst/decorator/resolver/gotypes" - "github.com/dave/dst/dstutil" - "golang.org/x/tools/go/packages" -) - -// NewDecorator returns a new decorator. If fset is nil, a new FileSet is created. -func NewDecorator(fset *token.FileSet) *Decorator { - if fset == nil { - fset = token.NewFileSet() - } - return &Decorator{ - Map: newMap(), - Filenames: map[*dst.File]string{}, - Fset: fset, - } -} - -// NewDecoratorWithImports returns a new decorator with import management enabled. -func NewDecoratorWithImports(fset *token.FileSet, path string, resolver resolver.DecoratorResolver) *Decorator { - dec := NewDecorator(fset) - dec.Path = path - dec.Resolver = resolver - return dec -} - -// NewDecoratorFromPackage returns a new decorator configured to decorate files in pkg. -func NewDecoratorFromPackage(pkg *packages.Package) *Decorator { - return NewDecoratorWithImports(pkg.Fset, pkg.PkgPath, gotypes.New(pkg.TypesInfo.Uses)) -} - -// Decorator converts ast nodes into dst nodes, and converts decoration info from the ast fileset -// to the dst nodes. Create a new Decorator for each package you need to decorate. -type Decorator struct { - Map // Mapping between ast and dst Nodes, Objects and Scopes - Filenames map[*dst.File]string // Source file names - Fset *token.FileSet // The ast FileSet containing ast decoration info for the files - - // If a Resolver is provided, it is used to resolve remote identifiers from *ast.Ident and - // *ast.SelectorExpr nodes. Usually a remote identifier is a SelectorExpr qualified identifier, - // but in the case of dot-imports they can be simply Ident nodes. During decoration, remote - // identifiers are replaced with *dst.Ident with Path set to the path of imported package. - Resolver resolver.DecoratorResolver - // Local package path - required if Resolver is set. - Path string - // By default local idents are left with an empty Path, so they stay local if the local package - // is renamed. Setting ResolveLocalPath to true prevents this, so all idents will have the - // package path added. - ResolveLocalPath bool -} - -// Parse uses parser.ParseFile to parse and decorate a Go source file. The src parameter should -// be string, []byte, or io.Reader. -func (d *Decorator) Parse(src interface{}) (*dst.File, error) { - return d.ParseFile("", src, parser.ParseComments) -} - -// ParseFile uses parser.ParseFile to parse and decorate a Go source file. The ParseComments flag -// is added to mode if it doesn't exist. -func (d *Decorator) ParseFile(filename string, src interface{}, mode parser.Mode) (*dst.File, error) { - - // If ParseFile returns an error and also a non-nil file, the errors were just parse errors so - // we should continue decorating the file and return the error. - f, perr := parser.ParseFile(d.Fset, filename, src, mode|parser.ParseComments) - if perr != nil && f == nil { - return nil, perr - } - - file, err := d.DecorateFile(f) - if err != nil { - return nil, err - } - - return file, perr -} - -// ParseDir uses parser.ParseDir to parse and decorate a directory containing Go source. The -// ParseComments flag is added to mode if it doesn't exist. -func (d *Decorator) ParseDir(dir string, filter func(os.FileInfo) bool, mode parser.Mode) (map[string]*dst.Package, error) { - pkgs, err := parser.ParseDir(d.Fset, dir, filter, mode|parser.ParseComments) - if err != nil { - return nil, err - } - out := map[string]*dst.Package{} - for k, v := range pkgs { - pkg, err := d.DecorateNode(v) - if err != nil { - return nil, err - } - out[k] = pkg.(*dst.Package) - } - return out, nil -} - -// DecorateFile decorates *ast.File and returns *dst.File -func (d *Decorator) DecorateFile(f *ast.File) (*dst.File, error) { - file, err := d.DecorateNode(f) - if err != nil { - return nil, err - } - return file.(*dst.File), nil -} - -// DecorateNode decorates ast.Node and returns dst.Node -func (d *Decorator) DecorateNode(n ast.Node) (dst.Node, error) { - - if d.Resolver == nil && d.Path != "" { - panic("Decorator Path should be empty when Resolver is nil") - } - - if d.Resolver != nil && d.Path == "" { - panic("Decorator Path should be set when Resolver is set") - } - - fd := d.newFileDecorator() - if f, ok := n.(*ast.File); ok { - fd.file = f - } - fd.fragment(n) - fd.link() - - out, err := fd.decorateNode(nil, "", "", "", n) - if err != nil { - return nil, err - } - - //fmt.Println("\nFragments:") - //fd.debug(os.Stdout) - - //fmt.Println("\nDecorator:") - //debug(os.Stdout, out) - - // Populate Info with filenames if we're decorating a File or Package. - switch n := n.(type) { - case *ast.Package: - for k, v := range n.Files { - d.Filenames[d.Dst.Nodes[v].(*dst.File)] = k - } - case *ast.File: - d.Filenames[out.(*dst.File)] = d.Fset.File(n.Pos()).Name() - } - - return out, nil -} - -func (pd *Decorator) newFileDecorator() *fileDecorator { - return &fileDecorator{ - Decorator: pd, - startIndents: map[ast.Node]int{}, - endIndents: map[ast.Node]int{}, - before: map[ast.Node]dst.SpaceType{}, - after: map[ast.Node]dst.SpaceType{}, - decorations: map[ast.Node]map[string][]string{}, - } -} - -type fileDecorator struct { - *Decorator - file *ast.File // file we're decorating in for import name resolution - can be nil if we're just decorating an isolated node - cursor int - fragments []fragment - startIndents map[ast.Node]int - endIndents map[ast.Node]int - before, after map[ast.Node]dst.SpaceType - decorations map[ast.Node]map[string][]string -} - -// We never need to resolve idents that are in these fields (decorateSelectorExpr will override -// this check with the force parameter for SelectorExpr.Sel when needed). -var avoid = map[string]bool{ - "Field.Names": true, - "LabeledStmt.Label": true, - "BranchStmt.Label": true, - "ImportSpec.Name": true, - "ValueSpec.Names": true, - "TypeSpec.Name": true, - "FuncDecl.Name": true, - "File.Name": true, - "SelectorExpr.Sel": true, -} - -// decorateSelectorExpr is a special case for decorating a SelectorExpr, which might return an -// Ident if the resolver determines that the SelectorExpr represents a qualified ident. -func (f *fileDecorator) decorateSelectorExpr(parent ast.Node, parentName, parentField, parentFieldType string, n *ast.SelectorExpr) (dst.Node, error) { - - if f.Resolver == nil { - // continue to default logic in decorateNode - return nil, nil - } - - // resolve the path with force == true, so we skip the tests that would normally prevent the - // Sel field of SelectorExpr from being resolved. - path, err := f.resolvePath(true, n, "SelectorExpr", "Sel", "Ident", n.Sel) - if err != nil { - return nil, err - } - - if path == "" { - // path == "" -> not a qualified ident -> continue to default logic in decorateNode - return nil, nil - } - - // replace *ast.SelectorExpr with *dst.Ident and merge decorations - out := &dst.Ident{} - f.Dst.Nodes[n] = out - f.Dst.Nodes[n.X] = out - f.Dst.Nodes[n.Sel] = out - f.Ast.Nodes[out] = n - - // String: Name - out.Name = n.Sel.Name - - // Object: Obj - ob, err := f.decorateObject(n.Sel.Obj) - if err != nil { - return nil, err - } - out.Obj = ob - - // Path: Path - out.Path = path - - /* - We must merge the SelectorExpr decorations into an Ident. The Ident has an X decoration - attachment point, but we don't have a simple place to store the decorations and line - spacing from the X / Sel child nodes. This is rather an edge case, but we can fix it by - merging the line-spacing with decorations (line spacing becomes "\n" decorations) and - adding these to the Ident decorations. This will mean that decorated / restored code with - no mutations should be byte-perfect, which is essential. - - Here's a list of the decorations / line spacings we're merging: - - {1}{2}{3}{4}[ X ].{5}{6}{7}{8}{9}[ Sel ]{10}{11}{12}{13} - - 1: SelectorExpr Before Space - f.before[n] - - 2: SelectorExpr Start Decoration - f.decorations[n]["Start"] - 3: X Before Space - f.before[n.X] - 4: X Start Decoration - f.decorations[n.X]["Start"] - - 5: X End Decoration - f.decorations[n.X]["End"] - 6: X After Space - f.after[n.X] - 7: SelectorExpr X Decoration - f.decorations[n]["X"] - 8: Sel Before Space - f.before[n.Sel] - 9: Sel Start Decoration - f.decorations[n.Sel]["Start"] - - 10: Sel End decoration - f.decorations[n.Sel]["End"] - 11: Sel After Space - f.after[n.Sel] - 12: SelectorExpr End Decoration - f.decorations[n]["End"] - - 13: SelectorExpr After Space - f.after[n] - - 1: set Ident.Before - 2-4: merge into Ident.Start - 5-9: merge into Ident.X - 10-12: merge into Ident.End - 13: set Ident.After - */ - - out.Decs.Before = f.before[n] - out.Decs.After = f.after[n] - - var nStart, xBefore, xStart, xEnd, xAfter, nX, sBefore, sStart, sEnd, sAfter, nEnd interface{} - - xBefore = f.before[n.X] - xAfter = f.after[n.X] - - sBefore = f.before[n.Sel] - sAfter = f.after[n.Sel] - - if decs, ok := f.decorations[n]; ok { - nStart = decs["Start"] - nX = decs["X"] - nEnd = decs["End"] - } - if decs, ok := f.decorations[n.X]; ok { - xStart = decs["Start"] - xEnd = decs["End"] - } - if decs, ok := f.decorations[n.Sel]; ok { - sStart = decs["Start"] - sEnd = decs["End"] - } - - if iStart := mergeDecorations(nStart, xBefore, xStart); len(iStart) > 0 { - out.Decs.Start.Append(iStart...) - } - - if iX := mergeDecorations(xEnd, xAfter, nX, sBefore, sStart); len(iX) > 0 { - out.Decs.X.Append(iX...) - } - - if iEnd := mergeDecorations(sEnd, sAfter, nEnd); len(iEnd) > 0 { - out.Decs.End.Append(iEnd...) - } - - return out, nil - -} - -func (f *fileDecorator) resolvePath(force bool, parent ast.Node, parentName, parentField, parentFieldType string, id *ast.Ident) (string, error) { - - if f.Resolver == nil { - panic("resolvePath needs a Resolver") - } - - if !force { - if avoid[parentName+"."+parentField] { - return "", nil - } - if parentFieldType != "Expr" { - panic(fmt.Sprintf("decorateIdent: unsupported parentName %s, parentField %s, parentFieldType %s", parentName, parentField, parentFieldType)) - } - } - - path, err := f.Resolver.ResolveIdent(f.file, parent, parentField, id) - if err != nil { - return "", err - } - - path = stripVendor(path) - - if !f.ResolveLocalPath && path == stripVendor(f.Path) { - return "", nil - } - - return path, nil -} - -func stripVendor(path string) string { - findVendor := func(path string) (index int, ok bool) { - // Two cases, depending on internal at start of string or not. - // The order matters: we must return the index of the final element, - // because the final one is where the effective import path starts. - switch { - case strings.Contains(path, "/vendor/"): - return strings.LastIndex(path, "/vendor/") + 1, true - case strings.HasPrefix(path, "vendor/"): - return 0, true - } - return 0, false - } - i, ok := findVendor(path) - if !ok { - return path - } - return path[i+len("vendor/"):] -} - -func (f *fileDecorator) decorateObject(o *ast.Object) (*dst.Object, error) { - - if o == nil { - return nil, nil - } - - if do, ok := f.Dst.Objects[o]; ok { - return do, nil - } - - /* - // An Object describes a named language entity such as a package, - // constant, type, variable, function (incl. methods), or label. - // - // The Data fields contains object-specific data: - // - // Kind Data type Data value - // Pkg *Scope package scope - // Con int iota for the respective declaration - // - type Object struct { - Kind ObjKind - Name string // declared name - Decl interface{} // corresponding Field, XxxSpec, FuncDecl, LabeledStmt, AssignStmt, Scope; or nil - Data interface{} // object-specific data; or nil - Type interface{} // placeholder for type information; may be nil - } - */ - - out := &dst.Object{} - f.Dst.Objects[o] = out - f.Ast.Objects[out] = o - out.Kind = dst.ObjKind(o.Kind) - out.Name = o.Name - - switch decl := o.Decl.(type) { - case *ast.Scope: - s, err := f.decorateScope(decl) - if err != nil { - return nil, err - } - out.Decl = s - case ast.Node: - n, err := f.decorateNode(nil, "", "", "", decl) - if err != nil { - return nil, err - } - out.Decl = n - case nil: - default: - panic(fmt.Sprintf("o.Decl is %T", o.Data)) - } - - switch data := o.Data.(type) { - case int: - out.Data = data - case *ast.Scope: - s, err := f.decorateScope(data) - if err != nil { - return nil, err - } - out.Data = s - case ast.Node: - n, err := f.decorateNode(nil, "", "", "", data) - if err != nil { - return nil, err - } - out.Data = n - case nil: - default: - panic(fmt.Sprintf("o.Data is %T", o.Data)) - } - - return out, nil -} - -func (f *fileDecorator) decorateScope(s *ast.Scope) (*dst.Scope, error) { - - if s == nil { - return nil, nil - } - - if ds, ok := f.Dst.Scopes[s]; ok { - return ds, nil - } - - /* - // A Scope maintains the set of named language entities declared - // in the scope and a link to the immediately surrounding (outer) - // scope. - // - type Scope struct { - Outer *Scope - Objects map[string]*Object - } - */ - - out := &dst.Scope{} - f.Dst.Scopes[s] = out - f.Ast.Scopes[out] = s - - outer, err := f.decorateScope(s.Outer) - if err != nil { - return nil, err - } - out.Outer = outer - out.Objects = map[string]*dst.Object{} - - for k, v := range s.Objects { - ob, err := f.decorateObject(v) - if err != nil { - return nil, err - } - out.Objects[k] = ob - } - - return out, nil -} - -func debug(w io.Writer, file dst.Node) { - var result string - nodeType := func(n dst.Node) string { - return strings.Replace(fmt.Sprintf("%T", n), "*dst.", "", -1) - } - dst.Inspect(file, func(n dst.Node) bool { - if n == nil { - return false - } - var out string - before, after, points := dstutil.Decorations(n) - switch before { - case dst.NewLine: - out += " [New line before]" - case dst.EmptyLine: - out += " [Empty line before]" - } - for _, point := range points { - if len(point.Decs) > 0 { - var values string - for i, dec := range point.Decs { - if i > 0 { - values += " " - } - values += fmt.Sprintf("%q", dec) - } - out += fmt.Sprintf(" [%s %s]", point.Name, values) - } - } - switch after { - case dst.NewLine: - out += " [New line after]" - case dst.EmptyLine: - out += " [Empty line after]" - } - if out != "" { - result += nodeType(n) + out + "\n" - } - return true - }) - fmt.Fprint(w, result) -} - -// mergeDecorations merges several decoration lists and line spaces into a single decoration list -func mergeDecorations(decorationsOrLineSpace ...interface{}) []string { - var endsWithNewLine bool - var out []string - for _, v := range decorationsOrLineSpace { - switch v := v.(type) { - case nil: - // nothing - case []string: - if len(v) == 0 { - continue - } - out = append(out, v...) - endsWithNewLine = v[len(v)-1] == "\n" || strings.HasPrefix(v[len(v)-1], "//") - case dst.SpaceType: - switch v { - case dst.NewLine: - if endsWithNewLine { - // nothing to do - } else { - out = append(out, "\n") - } - endsWithNewLine = true - case dst.EmptyLine: - if endsWithNewLine { - out = append(out, "\n") - } else { - out = append(out, "\n", "\n") - } - endsWithNewLine = true - } - default: - panic(fmt.Sprintf("%T", v)) - } - } - return out -} diff --git a/vendor/github.com/dave/dst/decorator/helpers.go b/vendor/github.com/dave/dst/decorator/helpers.go deleted file mode 100644 index 679b6e701d..0000000000 --- a/vendor/github.com/dave/dst/decorator/helpers.go +++ /dev/null @@ -1,64 +0,0 @@ -package decorator - -import ( - "go/ast" - "go/format" - "go/parser" - "go/token" - "io" - "os" - - "github.com/dave/dst" -) - -// Parse uses parser.ParseFile to parse and decorate a Go source file. The src parameter should -// be string, []byte, or io.Reader. -func Parse(src interface{}) (*dst.File, error) { - return NewDecorator(token.NewFileSet()).Parse(src) -} - -// ParseFile uses parser.ParseFile to parse and decorate a Go source file. The ParseComments flag is -// added to mode if it doesn't exist. -func ParseFile(fset *token.FileSet, filename string, src interface{}, mode parser.Mode) (*dst.File, error) { - return NewDecorator(fset).ParseFile(filename, src, mode) -} - -// ParseDir uses parser.ParseDir to parse and decorate a directory containing Go source. The -// ParseComments flag is added to mode if it doesn't exist. -func ParseDir(fset *token.FileSet, dir string, filter func(os.FileInfo) bool, mode parser.Mode) (map[string]*dst.Package, error) { - return NewDecorator(fset).ParseDir(dir, filter, mode) -} - -// Decorate decorates an ast.Node and returns a dst.Node. -func Decorate(fset *token.FileSet, n ast.Node) (dst.Node, error) { - return NewDecorator(fset).DecorateNode(n) -} - -// Decorate decorates a *ast.File and returns a *dst.File. -func DecorateFile(fset *token.FileSet, f *ast.File) (*dst.File, error) { - return NewDecorator(fset).DecorateFile(f) -} - -// Print uses format.Node to print a *dst.File to stdout -func Print(f *dst.File) error { - return Fprint(os.Stdout, f) -} - -// Fprint uses format.Node to print a *dst.File to a writer -func Fprint(w io.Writer, f *dst.File) error { - fset, af, err := RestoreFile(f) - if err != nil { - return err - } - return format.Node(w, fset, af) -} - -// RestoreFile restores a *dst.File to a *token.FileSet and a *ast.File -func RestoreFile(file *dst.File) (*token.FileSet, *ast.File, error) { - r := NewRestorer() - f, err := r.RestoreFile(file) - if err != nil { - return nil, nil, err - } - return r.Fset, f, nil -} diff --git a/vendor/github.com/dave/dst/decorator/load.go b/vendor/github.com/dave/dst/decorator/load.go deleted file mode 100644 index 3e109f118a..0000000000 --- a/vendor/github.com/dave/dst/decorator/load.go +++ /dev/null @@ -1,119 +0,0 @@ -package decorator - -import ( - "bytes" - "errors" - "io/ioutil" - "os" - "path/filepath" - - "github.com/dave/dst" - "github.com/dave/dst/decorator/resolver" - "github.com/dave/dst/decorator/resolver/gopackages" - "golang.org/x/tools/go/packages" -) - -func Load(cfg *packages.Config, patterns ...string) ([]*Package, error) { - - if cfg == nil { - cfg = &packages.Config{Mode: packages.LoadSyntax} - } - - if cfg.Mode&packages.NeedSyntax == 0 { - return nil, errors.New("config mode should include NeedSyntax") - } - - pkgs, err := packages.Load(cfg, patterns...) - if err != nil { - return nil, err - } - - dpkgs := map[*packages.Package]*Package{} - - var convert func(p *packages.Package) (*Package, error) - convert = func(pkg *packages.Package) (*Package, error) { - if dp, ok := dpkgs[pkg]; ok { - return dp, nil - } - p := &Package{ - Package: pkg, - Imports: map[string]*Package{}, - } - dpkgs[pkg] = p - if len(pkg.Syntax) > 0 { - - // Only decorate files in the GoFiles list. Syntax also has preprocessed cgo files which - // break things. - goFiles := make(map[string]bool, len(pkg.GoFiles)) - for _, fpath := range pkg.GoFiles { - goFiles[fpath] = true - } - - p.Decorator = NewDecoratorFromPackage(pkg) - for _, f := range pkg.Syntax { - fpath := pkg.Fset.File(f.Pos()).Name() - if !goFiles[fpath] { - continue - } - file, err := p.Decorator.DecorateFile(f) - if err != nil { - return nil, err - } - p.Syntax = append(p.Syntax, file) - } - - dir, _ := filepath.Split(pkg.Fset.File(pkg.Syntax[0].Pos()).Name()) - p.Dir = dir - - for path, imp := range pkg.Imports { - dimp, err := convert(imp) - if err != nil { - return nil, err - } - p.Imports[path] = dimp - } - } - return p, nil - } - - var out []*Package - for _, pkg := range pkgs { - p, err := convert(pkg) - if err != nil { - return nil, err - } - out = append(out, p) - } - - return out, nil -} - -type Package struct { - *packages.Package - Dir string - Decorator *Decorator - Imports map[string]*Package - Syntax []*dst.File -} - -func (p *Package) Save() error { - return p.save(gopackages.New(p.Dir), ioutil.WriteFile) -} - -func (p *Package) SaveWithResolver(resolver resolver.RestorerResolver) error { - return p.save(resolver, ioutil.WriteFile) -} - -func (p *Package) save(resolver resolver.RestorerResolver, writeFile func(filename string, data []byte, perm os.FileMode) error) error { - r := NewRestorerWithImports(p.PkgPath, resolver) - for _, file := range p.Syntax { - buf := &bytes.Buffer{} - if err := r.Fprint(buf, file); err != nil { - return err - } - if err := writeFile(p.Decorator.Filenames[file], buf.Bytes(), 0666); err != nil { - return err - } - } - return nil -} diff --git a/vendor/github.com/dave/dst/decorator/map.go b/vendor/github.com/dave/dst/decorator/map.go deleted file mode 100644 index 48d4adfe53..0000000000 --- a/vendor/github.com/dave/dst/decorator/map.go +++ /dev/null @@ -1,42 +0,0 @@ -package decorator - -import ( - "go/ast" - - "github.com/dave/dst" -) - -func newMap() Map { - return Map{ - Ast: AstMap{ - Nodes: map[dst.Node]ast.Node{}, - Scopes: map[*dst.Scope]*ast.Scope{}, - Objects: map[*dst.Object]*ast.Object{}, - }, - Dst: DstMap{ - Nodes: map[ast.Node]dst.Node{}, - Scopes: map[*ast.Scope]*dst.Scope{}, - Objects: map[*ast.Object]*dst.Object{}, - }, - } -} - -// Map holds a record of the mapping between ast and dst nodes, objects and scopes. -type Map struct { - Ast AstMap - Dst DstMap -} - -// AstMap holds a record of the mapping from dst to ast nodes, objects and scopes. -type AstMap struct { - Nodes map[dst.Node]ast.Node // Mapping from dst to ast Nodes - Objects map[*dst.Object]*ast.Object // Mapping from dst to ast Objects - Scopes map[*dst.Scope]*ast.Scope // Mapping from dst to ast Scopes -} - -// DstMap holds a record of the mapping from ast to dst nodes, objects and scopes. -type DstMap struct { - Nodes map[ast.Node]dst.Node // Mapping from ast to dst Nodes - Objects map[*ast.Object]*dst.Object // Mapping from ast to dst Objects - Scopes map[*ast.Scope]*dst.Scope // Mapping from ast to dst Scopes -} diff --git a/vendor/github.com/dave/dst/decorator/resolver/gopackages/resolver.go b/vendor/github.com/dave/dst/decorator/resolver/gopackages/resolver.go deleted file mode 100644 index 7295d7df6c..0000000000 --- a/vendor/github.com/dave/dst/decorator/resolver/gopackages/resolver.go +++ /dev/null @@ -1,61 +0,0 @@ -package gopackages - -import ( - "fmt" - - "github.com/dave/dst/decorator/resolver" - "golang.org/x/tools/go/packages" -) - -func New(dir string) *RestorerResolver { - return &RestorerResolver{Dir: dir} -} - -func WithConfig(dir string, config packages.Config) *RestorerResolver { - return &RestorerResolver{Config: config, Dir: dir} -} - -func WithHints(dir string, hints map[string]string) *RestorerResolver { - return &RestorerResolver{Dir: dir, Hints: hints} -} - -type RestorerResolver struct { - Dir string - Config packages.Config - - // Hints (package path -> name) is first checked before asking the packages package - Hints map[string]string -} - -func (r *RestorerResolver) ResolvePackage(path string) (string, error) { - - if name, ok := r.Hints[path]; ok { - return name, nil - } - - if r.Dir != "" { - r.Config.Dir = r.Dir - } - r.Config.Mode = packages.LoadTypes - r.Config.Tests = false - - pkgs, err := packages.Load(&r.Config, "pattern="+path) - if err != nil { - return "", err - } - - if len(pkgs) > 1 { - return "", fmt.Errorf("%d packages found for %s, %s", len(pkgs), path, r.Config.Dir) - } - if len(pkgs) == 0 { - return "", resolver.ErrPackageNotFound - } - - p := pkgs[0] - - if len(p.Errors) > 0 { - return "", p.Errors[0] - } - - return p.Name, nil -} diff --git a/vendor/github.com/dave/dst/decorator/resolver/gotypes/resolver.go b/vendor/github.com/dave/dst/decorator/resolver/gotypes/resolver.go deleted file mode 100644 index b79e56219c..0000000000 --- a/vendor/github.com/dave/dst/decorator/resolver/gotypes/resolver.go +++ /dev/null @@ -1,64 +0,0 @@ -package gotypes - -import ( - "errors" - "go/ast" - "go/types" -) - -func New(uses map[*ast.Ident]types.Object) *DecoratorResolver { - return &DecoratorResolver{Uses: uses} -} - -type DecoratorResolver struct { - Uses map[*ast.Ident]types.Object // Types info - must include Uses -} - -func (r *DecoratorResolver) ResolveIdent(file *ast.File, parent ast.Node, parentField string, id *ast.Ident) (string, error) { - - if r.Uses == nil { - return "", errors.New("gotypes.DecoratorResolver needs Uses in types info") - } - - if se, ok := parent.(*ast.SelectorExpr); ok && parentField == "Sel" { - - // if the parent is a SelectorExpr and this Ident is in the Sel field, only resolve the path - // if X is a package identifier - - xid, ok := se.X.(*ast.Ident) - if !ok { - // x is not an ident -> not a qualified identifier - return "", nil - } - obj, ok := r.Uses[xid] - if !ok { - // not found in uses -> not a qualified identifier - return "", nil - } - pn, ok := obj.(*types.PkgName) - if !ok { - // not a pkgname -> not a remote identifier - return "", nil - } - return pn.Imported().Path(), nil - } - - obj, ok := r.Uses[id] - if !ok { - // not found in uses -> not a remote identifier - return "", nil - } - - if v, ok := obj.(*types.Var); ok && v.IsField() { - // field ident (e.g. name of a field in a composite literal) -> doesn't need qualified ident - return "", nil - } - - pkg := obj.Pkg() - if pkg == nil { - // pre-defined idents in the universe scope - e.g. "byte" - return "", nil - } - - return pkg.Path(), nil -} diff --git a/vendor/github.com/dave/dst/decorator/resolver/resolver.go b/vendor/github.com/dave/dst/decorator/resolver/resolver.go deleted file mode 100644 index ccda191933..0000000000 --- a/vendor/github.com/dave/dst/decorator/resolver/resolver.go +++ /dev/null @@ -1,26 +0,0 @@ -package resolver - -import ( - "errors" - "go/ast" -) - -// RestorerResolver resolves a package path to a package name. -type RestorerResolver interface { - ResolvePackage(path string) (string, error) -} - -// DecoratorResolver resolves an identifier to a local or remote reference. -// -// Returns path == "" if the node is not a local or remote reference (e.g. a field in a composite -// literal, the selector in a selector expression etc.). -// -// Returns path == "" is the node is a local reference. -// -// Returns path != "" is the node is a remote reference. -type DecoratorResolver interface { - ResolveIdent(file *ast.File, parent ast.Node, parentField string, id *ast.Ident) (path string, err error) -} - -// ErrPackageNotFound means the package is not found -var ErrPackageNotFound = errors.New("package not found") diff --git a/vendor/github.com/dave/dst/decorator/restorer-generated.go b/vendor/github.com/dave/dst/decorator/restorer-generated.go deleted file mode 100644 index 4b5728ff43..0000000000 --- a/vendor/github.com/dave/dst/decorator/restorer-generated.go +++ /dev/null @@ -1,1956 +0,0 @@ -package decorator - -import ( - "fmt" - "go/ast" - "go/token" - - "github.com/dave/dst" -) - -func (r *FileRestorer) restoreNode(n dst.Node, parentName, parentField, parentFieldType string, allowDuplicate bool) ast.Node { - if an, ok := r.Ast.Nodes[n]; ok { - if allowDuplicate { - return an - } else { - panic(fmt.Sprintf("duplicate node: %#v", n)) - } - } - switch n := n.(type) { - case *dst.ArrayType: - out := &ast.ArrayType{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Token: Lbrack - out.Lbrack = r.cursor - r.cursor += token.Pos(len(token.LBRACK.String())) - - // Decoration: Lbrack - r.applyDecorations(out, "Lbrack", n.Decs.Lbrack, false) - - // Node: Len - if n.Len != nil { - out.Len = r.restoreNode(n.Len, "ArrayType", "Len", "Expr", allowDuplicate).(ast.Expr) - } - - // Token: Rbrack - r.cursor += token.Pos(len(token.RBRACK.String())) - - // Decoration: Len - r.applyDecorations(out, "Len", n.Decs.Len, false) - - // Node: Elt - if n.Elt != nil { - out.Elt = r.restoreNode(n.Elt, "ArrayType", "Elt", "Expr", allowDuplicate).(ast.Expr) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.AssignStmt: - out := &ast.AssignStmt{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // List: Lhs - for _, v := range n.Lhs { - out.Lhs = append(out.Lhs, r.restoreNode(v, "AssignStmt", "Lhs", "Expr", allowDuplicate).(ast.Expr)) - } - - // Token: Tok - out.Tok = n.Tok - out.TokPos = r.cursor - r.cursor += token.Pos(len(n.Tok.String())) - - // Decoration: Tok - r.applyDecorations(out, "Tok", n.Decs.Tok, false) - - // List: Rhs - for _, v := range n.Rhs { - out.Rhs = append(out.Rhs, r.restoreNode(v, "AssignStmt", "Rhs", "Expr", allowDuplicate).(ast.Expr)) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.BadDecl: - out := &ast.BadDecl{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Bad - out.From = r.cursor - r.cursor += token.Pos(n.Length) - out.To = r.cursor - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.BadExpr: - out := &ast.BadExpr{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Bad - out.From = r.cursor - r.cursor += token.Pos(n.Length) - out.To = r.cursor - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.BadStmt: - out := &ast.BadStmt{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Bad - out.From = r.cursor - r.cursor += token.Pos(n.Length) - out.To = r.cursor - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.BasicLit: - out := &ast.BasicLit{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // String: Value - r.applyLiteral(n.Value) - out.ValuePos = r.cursor - out.Value = n.Value - r.cursor += token.Pos(len(n.Value)) - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - - // Value: Kind - out.Kind = n.Kind - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.BinaryExpr: - out := &ast.BinaryExpr{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Node: X - if n.X != nil { - out.X = r.restoreNode(n.X, "BinaryExpr", "X", "Expr", allowDuplicate).(ast.Expr) - } - - // Decoration: X - r.applyDecorations(out, "X", n.Decs.X, false) - - // Token: Op - out.Op = n.Op - out.OpPos = r.cursor - r.cursor += token.Pos(len(n.Op.String())) - - // Decoration: Op - r.applyDecorations(out, "Op", n.Decs.Op, false) - - // Node: Y - if n.Y != nil { - out.Y = r.restoreNode(n.Y, "BinaryExpr", "Y", "Expr", allowDuplicate).(ast.Expr) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.BlockStmt: - out := &ast.BlockStmt{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Token: Lbrace - out.Lbrace = r.cursor - r.cursor += token.Pos(len(token.LBRACE.String())) - - // Decoration: Lbrace - r.applyDecorations(out, "Lbrace", n.Decs.Lbrace, false) - - // List: List - for _, v := range n.List { - out.List = append(out.List, r.restoreNode(v, "BlockStmt", "List", "Stmt", allowDuplicate).(ast.Stmt)) - } - - // Token: Rbrace - if n.RbraceHasNoPos { - out.Rbrace = token.NoPos - } else { - out.Rbrace = r.cursor - } - r.cursor += token.Pos(len(token.RBRACE.String())) - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.BranchStmt: - out := &ast.BranchStmt{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Token: Tok - out.Tok = n.Tok - out.TokPos = r.cursor - r.cursor += token.Pos(len(n.Tok.String())) - - // Decoration: Tok - r.applyDecorations(out, "Tok", n.Decs.Tok, false) - - // Node: Label - if n.Label != nil { - out.Label = r.restoreNode(n.Label, "BranchStmt", "Label", "Ident", allowDuplicate).(*ast.Ident) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.CallExpr: - out := &ast.CallExpr{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Node: Fun - if n.Fun != nil { - out.Fun = r.restoreNode(n.Fun, "CallExpr", "Fun", "Expr", allowDuplicate).(ast.Expr) - } - - // Decoration: Fun - r.applyDecorations(out, "Fun", n.Decs.Fun, false) - - // Token: Lparen - out.Lparen = r.cursor - r.cursor += token.Pos(len(token.LPAREN.String())) - - // Decoration: Lparen - r.applyDecorations(out, "Lparen", n.Decs.Lparen, false) - - // List: Args - for _, v := range n.Args { - out.Args = append(out.Args, r.restoreNode(v, "CallExpr", "Args", "Expr", allowDuplicate).(ast.Expr)) - } - - // Token: Ellipsis - if n.Ellipsis { - out.Ellipsis = r.cursor - r.cursor += token.Pos(len(token.ELLIPSIS.String())) - } - - // Decoration: Ellipsis - r.applyDecorations(out, "Ellipsis", n.Decs.Ellipsis, false) - - // Token: Rparen - out.Rparen = r.cursor - r.cursor += token.Pos(len(token.RPAREN.String())) - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.CaseClause: - out := &ast.CaseClause{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Token: Case - out.Case = r.cursor - r.cursor += token.Pos(len(func() token.Token { - if n.List == nil { - return token.DEFAULT - } - return token.CASE - }().String())) - - // Decoration: Case - r.applyDecorations(out, "Case", n.Decs.Case, false) - - // List: List - for _, v := range n.List { - out.List = append(out.List, r.restoreNode(v, "CaseClause", "List", "Expr", allowDuplicate).(ast.Expr)) - } - - // Token: Colon - out.Colon = r.cursor - r.cursor += token.Pos(len(token.COLON.String())) - - // Decoration: Colon - r.applyDecorations(out, "Colon", n.Decs.Colon, false) - - // List: Body - for _, v := range n.Body { - out.Body = append(out.Body, r.restoreNode(v, "CaseClause", "Body", "Stmt", allowDuplicate).(ast.Stmt)) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.ChanType: - out := &ast.ChanType{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Token: Begin - out.Begin = r.cursor - r.cursor += token.Pos(len(func() token.Token { - if n.Dir == dst.RECV { - return token.ARROW - } - return token.CHAN - }().String())) - - // Token: Chan - if n.Dir == dst.RECV { - r.cursor += token.Pos(len(token.CHAN.String())) - } - - // Decoration: Begin - r.applyDecorations(out, "Begin", n.Decs.Begin, false) - - // Token: Arrow - if n.Dir == dst.SEND { - out.Arrow = r.cursor - r.cursor += token.Pos(len(token.ARROW.String())) - } - - // Decoration: Arrow - r.applyDecorations(out, "Arrow", n.Decs.Arrow, false) - - // Node: Value - if n.Value != nil { - out.Value = r.restoreNode(n.Value, "ChanType", "Value", "Expr", allowDuplicate).(ast.Expr) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - - // Value: Dir - out.Dir = ast.ChanDir(n.Dir) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.CommClause: - out := &ast.CommClause{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Token: Case - out.Case = r.cursor - r.cursor += token.Pos(len(func() token.Token { - if n.Comm == nil { - return token.DEFAULT - } - return token.CASE - }().String())) - - // Decoration: Case - r.applyDecorations(out, "Case", n.Decs.Case, false) - - // Node: Comm - if n.Comm != nil { - out.Comm = r.restoreNode(n.Comm, "CommClause", "Comm", "Stmt", allowDuplicate).(ast.Stmt) - } - - // Decoration: Comm - r.applyDecorations(out, "Comm", n.Decs.Comm, false) - - // Token: Colon - out.Colon = r.cursor - r.cursor += token.Pos(len(token.COLON.String())) - - // Decoration: Colon - r.applyDecorations(out, "Colon", n.Decs.Colon, false) - - // List: Body - for _, v := range n.Body { - out.Body = append(out.Body, r.restoreNode(v, "CommClause", "Body", "Stmt", allowDuplicate).(ast.Stmt)) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.CompositeLit: - out := &ast.CompositeLit{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Node: Type - if n.Type != nil { - out.Type = r.restoreNode(n.Type, "CompositeLit", "Type", "Expr", allowDuplicate).(ast.Expr) - } - - // Decoration: Type - r.applyDecorations(out, "Type", n.Decs.Type, false) - - // Token: Lbrace - out.Lbrace = r.cursor - r.cursor += token.Pos(len(token.LBRACE.String())) - - // Decoration: Lbrace - r.applyDecorations(out, "Lbrace", n.Decs.Lbrace, false) - - // List: Elts - for _, v := range n.Elts { - out.Elts = append(out.Elts, r.restoreNode(v, "CompositeLit", "Elts", "Expr", allowDuplicate).(ast.Expr)) - } - - // Token: Rbrace - out.Rbrace = r.cursor - r.cursor += token.Pos(len(token.RBRACE.String())) - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - - // Value: Incomplete - out.Incomplete = n.Incomplete - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.DeclStmt: - out := &ast.DeclStmt{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Node: Decl - if n.Decl != nil { - out.Decl = r.restoreNode(n.Decl, "DeclStmt", "Decl", "Decl", allowDuplicate).(ast.Decl) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.DeferStmt: - out := &ast.DeferStmt{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Token: Defer - out.Defer = r.cursor - r.cursor += token.Pos(len(token.DEFER.String())) - - // Decoration: Defer - r.applyDecorations(out, "Defer", n.Decs.Defer, false) - - // Node: Call - if n.Call != nil { - out.Call = r.restoreNode(n.Call, "DeferStmt", "Call", "CallExpr", allowDuplicate).(*ast.CallExpr) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.Ellipsis: - out := &ast.Ellipsis{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Token: Ellipsis - out.Ellipsis = r.cursor - r.cursor += token.Pos(len(token.ELLIPSIS.String())) - - // Decoration: Ellipsis - r.applyDecorations(out, "Ellipsis", n.Decs.Ellipsis, false) - - // Node: Elt - if n.Elt != nil { - out.Elt = r.restoreNode(n.Elt, "Ellipsis", "Elt", "Expr", allowDuplicate).(ast.Expr) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.EmptyStmt: - out := &ast.EmptyStmt{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Token: Semicolon - if !n.Implicit { - out.Semicolon = r.cursor - r.cursor += token.Pos(len(token.ARROW.String())) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - - // Value: Implicit - out.Implicit = n.Implicit - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.ExprStmt: - out := &ast.ExprStmt{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Node: X - if n.X != nil { - out.X = r.restoreNode(n.X, "ExprStmt", "X", "Expr", allowDuplicate).(ast.Expr) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.Field: - out := &ast.Field{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // List: Names - for _, v := range n.Names { - out.Names = append(out.Names, r.restoreNode(v, "Field", "Names", "Ident", allowDuplicate).(*ast.Ident)) - } - - // Node: Type - if n.Type != nil { - out.Type = r.restoreNode(n.Type, "Field", "Type", "Expr", allowDuplicate).(ast.Expr) - } - - // Decoration: Type - r.applyDecorations(out, "Type", n.Decs.Type, false) - - // Node: Tag - if n.Tag != nil { - out.Tag = r.restoreNode(n.Tag, "Field", "Tag", "BasicLit", allowDuplicate).(*ast.BasicLit) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.FieldList: - out := &ast.FieldList{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Token: Opening - if n.Opening { - out.Opening = r.cursor - r.cursor += token.Pos(len(token.LPAREN.String())) - } - - // Decoration: Opening - r.applyDecorations(out, "Opening", n.Decs.Opening, false) - - // List: List - for _, v := range n.List { - out.List = append(out.List, r.restoreNode(v, "FieldList", "List", "Field", allowDuplicate).(*ast.Field)) - } - - // Token: Closing - if n.Closing { - out.Closing = r.cursor - r.cursor += token.Pos(len(token.RPAREN.String())) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.File: - out := &ast.File{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Token: Package - out.Package = r.cursor - r.cursor += token.Pos(len(token.PACKAGE.String())) - - // Decoration: Package - r.applyDecorations(out, "Package", n.Decs.Package, false) - - // Node: Name - if n.Name != nil { - out.Name = r.restoreNode(n.Name, "File", "Name", "Ident", allowDuplicate).(*ast.Ident) - } - - // Decoration: Name - r.applyDecorations(out, "Name", n.Decs.Name, false) - - // List: Decls - for _, v := range n.Decls { - out.Decls = append(out.Decls, r.restoreNode(v, "File", "Decls", "Decl", allowDuplicate).(ast.Decl)) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - - // Scope: Scope - out.Scope = r.restoreScope(n.Scope) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.ForStmt: - out := &ast.ForStmt{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Token: For - out.For = r.cursor - r.cursor += token.Pos(len(token.FOR.String())) - - // Decoration: For - r.applyDecorations(out, "For", n.Decs.For, false) - - // Node: Init - if n.Init != nil { - out.Init = r.restoreNode(n.Init, "ForStmt", "Init", "Stmt", allowDuplicate).(ast.Stmt) - } - - // Token: InitSemicolon - if n.Init != nil { - r.cursor += token.Pos(len(token.SEMICOLON.String())) - } - - // Decoration: Init - r.applyDecorations(out, "Init", n.Decs.Init, false) - - // Node: Cond - if n.Cond != nil { - out.Cond = r.restoreNode(n.Cond, "ForStmt", "Cond", "Expr", allowDuplicate).(ast.Expr) - } - - // Token: CondSemicolon - if n.Post != nil { - r.cursor += token.Pos(len(token.SEMICOLON.String())) - } - - // Decoration: Cond - r.applyDecorations(out, "Cond", n.Decs.Cond, false) - - // Node: Post - if n.Post != nil { - out.Post = r.restoreNode(n.Post, "ForStmt", "Post", "Stmt", allowDuplicate).(ast.Stmt) - } - - // Decoration: Post - r.applyDecorations(out, "Post", n.Decs.Post, false) - - // Node: Body - if n.Body != nil { - out.Body = r.restoreNode(n.Body, "ForStmt", "Body", "BlockStmt", allowDuplicate).(*ast.BlockStmt) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.FuncDecl: - out := &ast.FuncDecl{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Init: Type - out.Type = &ast.FuncType{} - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Special decoration: Start - r.applyDecorations(out, "Start", n.Type.Decs.Start, false) - - // Token: Func - if true { - out.Type.Func = r.cursor - r.cursor += token.Pos(len(token.FUNC.String())) - } - - // Decoration: Func - r.applyDecorations(out, "Func", n.Decs.Func, false) - - // Special decoration: Func - r.applyDecorations(out, "Func", n.Type.Decs.Func, false) - - // Node: Recv - if n.Recv != nil { - out.Recv = r.restoreNode(n.Recv, "FuncDecl", "Recv", "FieldList", allowDuplicate).(*ast.FieldList) - } - - // Decoration: Recv - r.applyDecorations(out, "Recv", n.Decs.Recv, false) - - // Node: Name - if n.Name != nil { - out.Name = r.restoreNode(n.Name, "FuncDecl", "Name", "Ident", allowDuplicate).(*ast.Ident) - } - - // Decoration: Name - r.applyDecorations(out, "Name", n.Decs.Name, false) - - // Node: TypeParams - if n.Type.TypeParams != nil { - out.Type.TypeParams = r.restoreNode(n.Type.TypeParams, "FuncDecl", "TypeParams", "FieldList", allowDuplicate).(*ast.FieldList) - } - - // Decoration: TypeParams - r.applyDecorations(out, "TypeParams", n.Decs.TypeParams, false) - - // Special decoration: TypeParams - r.applyDecorations(out, "TypeParams", n.Type.Decs.TypeParams, false) - - // Node: Params - if n.Type.Params != nil { - out.Type.Params = r.restoreNode(n.Type.Params, "FuncDecl", "Params", "FieldList", allowDuplicate).(*ast.FieldList) - } - - // Decoration: Params - r.applyDecorations(out, "Params", n.Decs.Params, false) - - // Special decoration: Params - r.applyDecorations(out, "Params", n.Type.Decs.Params, false) - - // Node: Results - if n.Type.Results != nil { - out.Type.Results = r.restoreNode(n.Type.Results, "FuncDecl", "Results", "FieldList", allowDuplicate).(*ast.FieldList) - } - - // Decoration: Results - r.applyDecorations(out, "Results", n.Decs.Results, false) - - // Special decoration: End - r.applyDecorations(out, "End", n.Type.Decs.End, false) - - // Node: Body - if n.Body != nil { - out.Body = r.restoreNode(n.Body, "FuncDecl", "Body", "BlockStmt", allowDuplicate).(*ast.BlockStmt) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.FuncLit: - out := &ast.FuncLit{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Node: Type - if n.Type != nil { - out.Type = r.restoreNode(n.Type, "FuncLit", "Type", "FuncType", allowDuplicate).(*ast.FuncType) - } - - // Decoration: Type - r.applyDecorations(out, "Type", n.Decs.Type, false) - - // Node: Body - if n.Body != nil { - out.Body = r.restoreNode(n.Body, "FuncLit", "Body", "BlockStmt", allowDuplicate).(*ast.BlockStmt) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.FuncType: - out := &ast.FuncType{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Token: Func - if n.Func { - out.Func = r.cursor - r.cursor += token.Pos(len(token.FUNC.String())) - } - - // Decoration: Func - r.applyDecorations(out, "Func", n.Decs.Func, false) - - // Node: TypeParams - if n.TypeParams != nil { - out.TypeParams = r.restoreNode(n.TypeParams, "FuncType", "TypeParams", "FieldList", allowDuplicate).(*ast.FieldList) - } - - // Decoration: TypeParams - r.applyDecorations(out, "TypeParams", n.Decs.TypeParams, false) - - // Node: Params - if n.Params != nil { - out.Params = r.restoreNode(n.Params, "FuncType", "Params", "FieldList", allowDuplicate).(*ast.FieldList) - } - - // Decoration: Params - r.applyDecorations(out, "Params", n.Decs.Params, false) - - // Node: Results - if n.Results != nil { - out.Results = r.restoreNode(n.Results, "FuncType", "Results", "FieldList", allowDuplicate).(*ast.FieldList) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.GenDecl: - out := &ast.GenDecl{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Token: Tok - out.Tok = n.Tok - out.TokPos = r.cursor - r.cursor += token.Pos(len(n.Tok.String())) - - // Decoration: Tok - r.applyDecorations(out, "Tok", n.Decs.Tok, false) - - // Token: Lparen - if n.Lparen { - out.Lparen = r.cursor - r.cursor += token.Pos(len(token.LPAREN.String())) - } - - // Decoration: Lparen - r.applyDecorations(out, "Lparen", n.Decs.Lparen, false) - - // List: Specs - for _, v := range n.Specs { - out.Specs = append(out.Specs, r.restoreNode(v, "GenDecl", "Specs", "Spec", allowDuplicate).(ast.Spec)) - } - - // Token: Rparen - if n.Rparen { - out.Rparen = r.cursor - r.cursor += token.Pos(len(token.RPAREN.String())) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.GoStmt: - out := &ast.GoStmt{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Token: Go - out.Go = r.cursor - r.cursor += token.Pos(len(token.GO.String())) - - // Decoration: Go - r.applyDecorations(out, "Go", n.Decs.Go, false) - - // Node: Call - if n.Call != nil { - out.Call = r.restoreNode(n.Call, "GoStmt", "Call", "CallExpr", allowDuplicate).(*ast.CallExpr) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.Ident: - - // Special case for *dst.Ident - replace with SelectorExpr if needed - sel := r.restoreIdent(n, parentName, parentField, parentFieldType, allowDuplicate) - if sel != nil { - return sel - } - - out := &ast.Ident{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Decoration: X - r.applyDecorations(out, "X", n.Decs.X, false) - - // String: Name - out.NamePos = r.cursor - out.Name = n.Name - r.cursor += token.Pos(len(n.Name)) - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - - // Object: Obj - out.Obj = r.restoreObject(n.Obj) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.IfStmt: - out := &ast.IfStmt{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Token: If - out.If = r.cursor - r.cursor += token.Pos(len(token.IF.String())) - - // Decoration: If - r.applyDecorations(out, "If", n.Decs.If, false) - - // Node: Init - if n.Init != nil { - out.Init = r.restoreNode(n.Init, "IfStmt", "Init", "Stmt", allowDuplicate).(ast.Stmt) - } - - // Decoration: Init - r.applyDecorations(out, "Init", n.Decs.Init, false) - - // Node: Cond - if n.Cond != nil { - out.Cond = r.restoreNode(n.Cond, "IfStmt", "Cond", "Expr", allowDuplicate).(ast.Expr) - } - - // Decoration: Cond - r.applyDecorations(out, "Cond", n.Decs.Cond, false) - - // Node: Body - if n.Body != nil { - out.Body = r.restoreNode(n.Body, "IfStmt", "Body", "BlockStmt", allowDuplicate).(*ast.BlockStmt) - } - - // Token: ElseTok - if n.Else != nil { - r.cursor += token.Pos(len(token.ELSE.String())) - } - - // Decoration: Else - r.applyDecorations(out, "Else", n.Decs.Else, false) - - // Node: Else - if n.Else != nil { - out.Else = r.restoreNode(n.Else, "IfStmt", "Else", "Stmt", allowDuplicate).(ast.Stmt) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.ImportSpec: - out := &ast.ImportSpec{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Node: Name - if n.Name != nil { - out.Name = r.restoreNode(n.Name, "ImportSpec", "Name", "Ident", allowDuplicate).(*ast.Ident) - } - - // Decoration: Name - r.applyDecorations(out, "Name", n.Decs.Name, false) - - // Node: Path - if n.Path != nil { - out.Path = r.restoreNode(n.Path, "ImportSpec", "Path", "BasicLit", allowDuplicate).(*ast.BasicLit) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.IncDecStmt: - out := &ast.IncDecStmt{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Node: X - if n.X != nil { - out.X = r.restoreNode(n.X, "IncDecStmt", "X", "Expr", allowDuplicate).(ast.Expr) - } - - // Decoration: X - r.applyDecorations(out, "X", n.Decs.X, false) - - // Token: Tok - out.Tok = n.Tok - out.TokPos = r.cursor - r.cursor += token.Pos(len(n.Tok.String())) - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.IndexExpr: - out := &ast.IndexExpr{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Node: X - if n.X != nil { - out.X = r.restoreNode(n.X, "IndexExpr", "X", "Expr", allowDuplicate).(ast.Expr) - } - - // Decoration: X - r.applyDecorations(out, "X", n.Decs.X, false) - - // Token: Lbrack - out.Lbrack = r.cursor - r.cursor += token.Pos(len(token.LBRACK.String())) - - // Decoration: Lbrack - r.applyDecorations(out, "Lbrack", n.Decs.Lbrack, false) - - // Node: Index - if n.Index != nil { - out.Index = r.restoreNode(n.Index, "IndexExpr", "Index", "Expr", allowDuplicate).(ast.Expr) - } - - // Decoration: Index - r.applyDecorations(out, "Index", n.Decs.Index, false) - - // Token: Rbrack - out.Rbrack = r.cursor - r.cursor += token.Pos(len(token.RBRACK.String())) - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.IndexListExpr: - out := &ast.IndexListExpr{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Node: X - if n.X != nil { - out.X = r.restoreNode(n.X, "IndexListExpr", "X", "Expr", allowDuplicate).(ast.Expr) - } - - // Decoration: X - r.applyDecorations(out, "X", n.Decs.X, false) - - // Token: Lbrack - out.Lbrack = r.cursor - r.cursor += token.Pos(len(token.LBRACK.String())) - - // Decoration: Lbrack - r.applyDecorations(out, "Lbrack", n.Decs.Lbrack, false) - - // List: Indices - for _, v := range n.Indices { - out.Indices = append(out.Indices, r.restoreNode(v, "IndexListExpr", "Indices", "Expr", allowDuplicate).(ast.Expr)) - } - - // Decoration: Indices - r.applyDecorations(out, "Indices", n.Decs.Indices, false) - - // Token: Rbrack - out.Rbrack = r.cursor - r.cursor += token.Pos(len(token.RBRACK.String())) - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.InterfaceType: - out := &ast.InterfaceType{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Token: Interface - out.Interface = r.cursor - r.cursor += token.Pos(len(token.INTERFACE.String())) - - // Decoration: Interface - r.applyDecorations(out, "Interface", n.Decs.Interface, false) - - // Node: Methods - if n.Methods != nil { - out.Methods = r.restoreNode(n.Methods, "InterfaceType", "Methods", "FieldList", allowDuplicate).(*ast.FieldList) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - - // Value: Incomplete - out.Incomplete = n.Incomplete - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.KeyValueExpr: - out := &ast.KeyValueExpr{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Node: Key - if n.Key != nil { - out.Key = r.restoreNode(n.Key, "KeyValueExpr", "Key", "Expr", allowDuplicate).(ast.Expr) - } - - // Decoration: Key - r.applyDecorations(out, "Key", n.Decs.Key, false) - - // Token: Colon - out.Colon = r.cursor - r.cursor += token.Pos(len(token.COLON.String())) - - // Decoration: Colon - r.applyDecorations(out, "Colon", n.Decs.Colon, false) - - // Node: Value - if n.Value != nil { - out.Value = r.restoreNode(n.Value, "KeyValueExpr", "Value", "Expr", allowDuplicate).(ast.Expr) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.LabeledStmt: - out := &ast.LabeledStmt{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Node: Label - if n.Label != nil { - out.Label = r.restoreNode(n.Label, "LabeledStmt", "Label", "Ident", allowDuplicate).(*ast.Ident) - } - - // Decoration: Label - r.applyDecorations(out, "Label", n.Decs.Label, false) - - // Token: Colon - out.Colon = r.cursor - r.cursor += token.Pos(len(token.COLON.String())) - - // Decoration: Colon - r.applyDecorations(out, "Colon", n.Decs.Colon, false) - - // Node: Stmt - if n.Stmt != nil { - out.Stmt = r.restoreNode(n.Stmt, "LabeledStmt", "Stmt", "Stmt", allowDuplicate).(ast.Stmt) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.MapType: - out := &ast.MapType{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Token: Map - out.Map = r.cursor - r.cursor += token.Pos(len(token.MAP.String())) - - // Token: Lbrack - r.cursor += token.Pos(len(token.LBRACK.String())) - - // Decoration: Map - r.applyDecorations(out, "Map", n.Decs.Map, false) - - // Node: Key - if n.Key != nil { - out.Key = r.restoreNode(n.Key, "MapType", "Key", "Expr", allowDuplicate).(ast.Expr) - } - - // Token: Rbrack - r.cursor += token.Pos(len(token.RBRACK.String())) - - // Decoration: Key - r.applyDecorations(out, "Key", n.Decs.Key, false) - - // Node: Value - if n.Value != nil { - out.Value = r.restoreNode(n.Value, "MapType", "Value", "Expr", allowDuplicate).(ast.Expr) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.Package: - out := &ast.Package{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - - // Value: Name - out.Name = n.Name - - // Scope: Scope - out.Scope = r.restoreScope(n.Scope) - - // Map: Imports - out.Imports = map[string]*ast.Object{} - for k, v := range n.Imports { - out.Imports[k] = r.restoreObject(v) - } - - // Map: Files - out.Files = map[string]*ast.File{} - for k, v := range n.Files { - out.Files[k] = r.restoreNode(v, "Package", "Files", "File", allowDuplicate).(*ast.File) - } - - return out - case *dst.ParenExpr: - out := &ast.ParenExpr{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Token: Lparen - out.Lparen = r.cursor - r.cursor += token.Pos(len(token.LPAREN.String())) - - // Decoration: Lparen - r.applyDecorations(out, "Lparen", n.Decs.Lparen, false) - - // Node: X - if n.X != nil { - out.X = r.restoreNode(n.X, "ParenExpr", "X", "Expr", allowDuplicate).(ast.Expr) - } - - // Decoration: X - r.applyDecorations(out, "X", n.Decs.X, false) - - // Token: Rparen - out.Rparen = r.cursor - r.cursor += token.Pos(len(token.RPAREN.String())) - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.RangeStmt: - out := &ast.RangeStmt{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Token: For - out.For = r.cursor - r.cursor += token.Pos(len(token.FOR.String())) - - // Decoration: For - r.applyDecorations(out, "For", n.Decs.For, false) - - // Node: Key - if n.Key != nil { - out.Key = r.restoreNode(n.Key, "RangeStmt", "Key", "Expr", allowDuplicate).(ast.Expr) - } - - // Token: Comma - if n.Value != nil { - r.cursor += token.Pos(len(token.COMMA.String())) - } - - // Decoration: Key - r.applyDecorations(out, "Key", n.Decs.Key, false) - - // Node: Value - if n.Value != nil { - out.Value = r.restoreNode(n.Value, "RangeStmt", "Value", "Expr", allowDuplicate).(ast.Expr) - } - - // Decoration: Value - r.applyDecorations(out, "Value", n.Decs.Value, false) - - // Token: Tok - if n.Tok != token.ILLEGAL { - out.Tok = n.Tok - out.TokPos = r.cursor - r.cursor += token.Pos(len(n.Tok.String())) - } - - // Token: Range - r.cursor += token.Pos(len(token.RANGE.String())) - - // Decoration: Range - r.applyDecorations(out, "Range", n.Decs.Range, false) - - // Node: X - if n.X != nil { - out.X = r.restoreNode(n.X, "RangeStmt", "X", "Expr", allowDuplicate).(ast.Expr) - } - - // Decoration: X - r.applyDecorations(out, "X", n.Decs.X, false) - - // Node: Body - if n.Body != nil { - out.Body = r.restoreNode(n.Body, "RangeStmt", "Body", "BlockStmt", allowDuplicate).(*ast.BlockStmt) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.ReturnStmt: - out := &ast.ReturnStmt{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Token: Return - out.Return = r.cursor - r.cursor += token.Pos(len(token.RETURN.String())) - - // Decoration: Return - r.applyDecorations(out, "Return", n.Decs.Return, false) - - // List: Results - for _, v := range n.Results { - out.Results = append(out.Results, r.restoreNode(v, "ReturnStmt", "Results", "Expr", allowDuplicate).(ast.Expr)) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.SelectStmt: - out := &ast.SelectStmt{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Token: Select - out.Select = r.cursor - r.cursor += token.Pos(len(token.SELECT.String())) - - // Decoration: Select - r.applyDecorations(out, "Select", n.Decs.Select, false) - - // Node: Body - if n.Body != nil { - out.Body = r.restoreNode(n.Body, "SelectStmt", "Body", "BlockStmt", allowDuplicate).(*ast.BlockStmt) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.SelectorExpr: - out := &ast.SelectorExpr{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Node: X - if n.X != nil { - out.X = r.restoreNode(n.X, "SelectorExpr", "X", "Expr", allowDuplicate).(ast.Expr) - } - - // Token: Period - r.cursor += token.Pos(len(token.PERIOD.String())) - - // Decoration: X - r.applyDecorations(out, "X", n.Decs.X, false) - - // Node: Sel - if n.Sel != nil { - out.Sel = r.restoreNode(n.Sel, "SelectorExpr", "Sel", "Ident", allowDuplicate).(*ast.Ident) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.SendStmt: - out := &ast.SendStmt{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Node: Chan - if n.Chan != nil { - out.Chan = r.restoreNode(n.Chan, "SendStmt", "Chan", "Expr", allowDuplicate).(ast.Expr) - } - - // Decoration: Chan - r.applyDecorations(out, "Chan", n.Decs.Chan, false) - - // Token: Arrow - out.Arrow = r.cursor - r.cursor += token.Pos(len(token.ARROW.String())) - - // Decoration: Arrow - r.applyDecorations(out, "Arrow", n.Decs.Arrow, false) - - // Node: Value - if n.Value != nil { - out.Value = r.restoreNode(n.Value, "SendStmt", "Value", "Expr", allowDuplicate).(ast.Expr) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.SliceExpr: - out := &ast.SliceExpr{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Node: X - if n.X != nil { - out.X = r.restoreNode(n.X, "SliceExpr", "X", "Expr", allowDuplicate).(ast.Expr) - } - - // Decoration: X - r.applyDecorations(out, "X", n.Decs.X, false) - - // Token: Lbrack - out.Lbrack = r.cursor - r.cursor += token.Pos(len(token.LBRACK.String())) - - // Decoration: Lbrack - r.applyDecorations(out, "Lbrack", n.Decs.Lbrack, false) - - // Node: Low - if n.Low != nil { - out.Low = r.restoreNode(n.Low, "SliceExpr", "Low", "Expr", allowDuplicate).(ast.Expr) - } - - // Token: Colon1 - r.cursor += token.Pos(len(token.COLON.String())) - - // Decoration: Low - r.applyDecorations(out, "Low", n.Decs.Low, false) - - // Node: High - if n.High != nil { - out.High = r.restoreNode(n.High, "SliceExpr", "High", "Expr", allowDuplicate).(ast.Expr) - } - - // Token: Colon2 - if n.Slice3 { - r.cursor += token.Pos(len(token.COLON.String())) - } - - // Decoration: High - r.applyDecorations(out, "High", n.Decs.High, false) - - // Node: Max - if n.Max != nil { - out.Max = r.restoreNode(n.Max, "SliceExpr", "Max", "Expr", allowDuplicate).(ast.Expr) - } - - // Decoration: Max - r.applyDecorations(out, "Max", n.Decs.Max, false) - - // Token: Rbrack - out.Rbrack = r.cursor - r.cursor += token.Pos(len(token.RBRACK.String())) - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - - // Value: Slice3 - out.Slice3 = n.Slice3 - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.StarExpr: - out := &ast.StarExpr{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Token: Star - out.Star = r.cursor - r.cursor += token.Pos(len(token.MUL.String())) - - // Decoration: Star - r.applyDecorations(out, "Star", n.Decs.Star, false) - - // Node: X - if n.X != nil { - out.X = r.restoreNode(n.X, "StarExpr", "X", "Expr", allowDuplicate).(ast.Expr) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.StructType: - out := &ast.StructType{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Token: Struct - out.Struct = r.cursor - r.cursor += token.Pos(len(token.STRUCT.String())) - - // Decoration: Struct - r.applyDecorations(out, "Struct", n.Decs.Struct, false) - - // Node: Fields - if n.Fields != nil { - out.Fields = r.restoreNode(n.Fields, "StructType", "Fields", "FieldList", allowDuplicate).(*ast.FieldList) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - - // Value: Incomplete - out.Incomplete = n.Incomplete - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.SwitchStmt: - out := &ast.SwitchStmt{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Token: Switch - out.Switch = r.cursor - r.cursor += token.Pos(len(token.SWITCH.String())) - - // Decoration: Switch - r.applyDecorations(out, "Switch", n.Decs.Switch, false) - - // Node: Init - if n.Init != nil { - out.Init = r.restoreNode(n.Init, "SwitchStmt", "Init", "Stmt", allowDuplicate).(ast.Stmt) - } - - // Decoration: Init - r.applyDecorations(out, "Init", n.Decs.Init, false) - - // Node: Tag - if n.Tag != nil { - out.Tag = r.restoreNode(n.Tag, "SwitchStmt", "Tag", "Expr", allowDuplicate).(ast.Expr) - } - - // Decoration: Tag - r.applyDecorations(out, "Tag", n.Decs.Tag, false) - - // Node: Body - if n.Body != nil { - out.Body = r.restoreNode(n.Body, "SwitchStmt", "Body", "BlockStmt", allowDuplicate).(*ast.BlockStmt) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.TypeAssertExpr: - out := &ast.TypeAssertExpr{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Node: X - if n.X != nil { - out.X = r.restoreNode(n.X, "TypeAssertExpr", "X", "Expr", allowDuplicate).(ast.Expr) - } - - // Token: Period - r.cursor += token.Pos(len(token.PERIOD.String())) - - // Decoration: X - r.applyDecorations(out, "X", n.Decs.X, false) - - // Token: Lparen - out.Lparen = r.cursor - r.cursor += token.Pos(len(token.LPAREN.String())) - - // Decoration: Lparen - r.applyDecorations(out, "Lparen", n.Decs.Lparen, false) - - // Node: Type - if n.Type != nil { - out.Type = r.restoreNode(n.Type, "TypeAssertExpr", "Type", "Expr", allowDuplicate).(ast.Expr) - } - - // Token: TypeToken - if n.Type == nil { - r.cursor += token.Pos(len(token.TYPE.String())) - } - - // Decoration: Type - r.applyDecorations(out, "Type", n.Decs.Type, false) - - // Token: Rparen - out.Rparen = r.cursor - r.cursor += token.Pos(len(token.RPAREN.String())) - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.TypeSpec: - out := &ast.TypeSpec{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Node: Name - if n.Name != nil { - out.Name = r.restoreNode(n.Name, "TypeSpec", "Name", "Ident", allowDuplicate).(*ast.Ident) - } - - // Token: Assign - if n.Assign { - out.Assign = r.cursor - r.cursor += token.Pos(len(token.ASSIGN.String())) - } - - // Decoration: Name - r.applyDecorations(out, "Name", n.Decs.Name, false) - - // Node: TypeParams - if n.TypeParams != nil { - out.TypeParams = r.restoreNode(n.TypeParams, "TypeSpec", "TypeParams", "FieldList", allowDuplicate).(*ast.FieldList) - } - - // Decoration: TypeParams - r.applyDecorations(out, "TypeParams", n.Decs.TypeParams, false) - - // Node: Type - if n.Type != nil { - out.Type = r.restoreNode(n.Type, "TypeSpec", "Type", "Expr", allowDuplicate).(ast.Expr) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.TypeSwitchStmt: - out := &ast.TypeSwitchStmt{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Token: Switch - out.Switch = r.cursor - r.cursor += token.Pos(len(token.SWITCH.String())) - - // Decoration: Switch - r.applyDecorations(out, "Switch", n.Decs.Switch, false) - - // Node: Init - if n.Init != nil { - out.Init = r.restoreNode(n.Init, "TypeSwitchStmt", "Init", "Stmt", allowDuplicate).(ast.Stmt) - } - - // Decoration: Init - r.applyDecorations(out, "Init", n.Decs.Init, false) - - // Node: Assign - if n.Assign != nil { - out.Assign = r.restoreNode(n.Assign, "TypeSwitchStmt", "Assign", "Stmt", allowDuplicate).(ast.Stmt) - } - - // Decoration: Assign - r.applyDecorations(out, "Assign", n.Decs.Assign, false) - - // Node: Body - if n.Body != nil { - out.Body = r.restoreNode(n.Body, "TypeSwitchStmt", "Body", "BlockStmt", allowDuplicate).(*ast.BlockStmt) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.UnaryExpr: - out := &ast.UnaryExpr{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Token: Op - out.Op = n.Op - out.OpPos = r.cursor - r.cursor += token.Pos(len(n.Op.String())) - - // Decoration: Op - r.applyDecorations(out, "Op", n.Decs.Op, false) - - // Node: X - if n.X != nil { - out.X = r.restoreNode(n.X, "UnaryExpr", "X", "Expr", allowDuplicate).(ast.Expr) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - case *dst.ValueSpec: - out := &ast.ValueSpec{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // List: Names - for _, v := range n.Names { - out.Names = append(out.Names, r.restoreNode(v, "ValueSpec", "Names", "Ident", allowDuplicate).(*ast.Ident)) - } - - // Node: Type - if n.Type != nil { - out.Type = r.restoreNode(n.Type, "ValueSpec", "Type", "Expr", allowDuplicate).(ast.Expr) - } - - // Token: Assign - if n.Values != nil { - r.cursor += token.Pos(len(token.ASSIGN.String())) - } - - // Decoration: Assign - r.applyDecorations(out, "Assign", n.Decs.Assign, false) - - // List: Values - for _, v := range n.Values { - out.Values = append(out.Values, r.restoreNode(v, "ValueSpec", "Values", "Expr", allowDuplicate).(ast.Expr)) - } - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - default: - panic(fmt.Sprintf("%T", n)) - } -} diff --git a/vendor/github.com/dave/dst/decorator/restorer.go b/vendor/github.com/dave/dst/decorator/restorer.go deleted file mode 100644 index 57717834f3..0000000000 --- a/vendor/github.com/dave/dst/decorator/restorer.go +++ /dev/null @@ -1,823 +0,0 @@ -package decorator - -import ( - "fmt" - "go/ast" - "go/format" - "go/token" - "io" - "os" - "sort" - "strconv" - "strings" - - "github.com/dave/dst" - "github.com/dave/dst/decorator/resolver" -) - -// NewRestorer returns a restorer. -func NewRestorer() *Restorer { - return &Restorer{ - Map: newMap(), - Fset: token.NewFileSet(), - } -} - -// NewRestorerWithImports returns a restorer with import management attributes set. -func NewRestorerWithImports(path string, resolver resolver.RestorerResolver) *Restorer { - res := NewRestorer() - res.Path = path - res.Resolver = resolver - return res -} - -// Restorer restores dst.Node to ast.Node -type Restorer struct { - Map - Fset *token.FileSet // Fset is the *token.FileSet in use. Set this to use a pre-existing FileSet. - Extras bool // Resore Objects, Scopes etc. Not needed for printing the resultant AST. If set to true, Objects and Scopes must be carefully managed to avoid duplicate nodes. - - // If a Resolver is provided, the names of all imported packages are resolved, and the imports - // block is updated. All remote identifiers are updated (sometimes this involves changing - // SelectorExpr.X.Name, or even swapping between Ident and SelectorExpr). To force specific - // import alias names, use the FileRestorer.Alias map. - Resolver resolver.RestorerResolver - // Local package path - required if Resolver is set. - Path string -} - -// Print uses format.Node to print a *dst.File to stdout -func (pr *Restorer) Print(f *dst.File) error { - return pr.Fprint(os.Stdout, f) -} - -// Fprint uses format.Node to print a *dst.File to a writer -func (pr *Restorer) Fprint(w io.Writer, f *dst.File) error { - af, err := pr.RestoreFile(f) - if err != nil { - return err - } - return format.Node(w, pr.Fset, af) -} - -// RestoreFile restores a *dst.File to an *ast.File -func (pr *Restorer) RestoreFile(file *dst.File) (*ast.File, error) { - return pr.FileRestorer().RestoreFile(file) -} - -// FileRestorer restores a specific file with extra options -func (pr *Restorer) FileRestorer() *FileRestorer { - return &FileRestorer{ - Restorer: pr, - Alias: map[string]string{}, - } -} - -// FileRestorer restores a specific file with extra options -type FileRestorer struct { - *Restorer - Alias map[string]string // Map of package path -> package alias for imports - Name string // The name of the restored file in the FileSet. Can usually be left empty. - file *dst.File - lines []int - comments []*ast.CommentGroup - base int - cursor token.Pos - nodeDecl map[*ast.Object]dst.Node // Objects that have a ast.Node Decl (look up after file has been rendered) - nodeData map[*ast.Object]dst.Node // Objects that have a ast.Node Data (look up after file has been rendered) - cursorAtNewLine token.Pos // The cursor position directly after adding a newline decoration (or a line comment which ends in a "\n"). If we're still at this cursor position when we add a line space, reduce the "\n" by one. - packageNames map[string]string // names in the code of all imported packages ("." for dot-imports) -} - -// Print uses format.Node to print a *dst.File to stdout -func (r *FileRestorer) Print(f *dst.File) error { - return r.Fprint(os.Stdout, f) -} - -// Fprint uses format.Node to print a *dst.File to a writer -func (r *FileRestorer) Fprint(w io.Writer, f *dst.File) error { - af, err := r.RestoreFile(f) - if err != nil { - return err - } - return format.Node(w, r.Fset, af) -} - -// RestoreFile restores a *dst.File to *ast.File -func (r *FileRestorer) RestoreFile(file *dst.File) (*ast.File, error) { - - if r.Resolver == nil && r.Path != "" { - panic("Restorer Path should be empty when Resolver is nil") - } - - if r.Resolver != nil && r.Path == "" { - panic("Restorer Path should be set when Resolver is set") - } - - if r.Fset == nil { - r.Fset = token.NewFileSet() - } - - // reset the FileRestorer, but leave Name and the Alias map unchanged - - r.file = file - r.lines = []int{0} // initialise with the first line at Pos 0 - r.nodeDecl = map[*ast.Object]dst.Node{} - r.nodeData = map[*ast.Object]dst.Node{} - r.packageNames = map[string]string{} - r.comments = []*ast.CommentGroup{} - r.cursorAtNewLine = 0 - r.packageNames = map[string]string{} - - r.base = r.Fset.Base() // base is the pos that the file will start at in the fset - r.cursor = token.Pos(r.base) - - if err := r.updateImports(); err != nil { - return nil, err - } - - // restore the file, populate comments and lines - f := r.restoreNode(r.file, "", "", "", false).(*ast.File) - - for _, cg := range r.comments { - f.Comments = append(f.Comments, cg) - } - - ff := r.Fset.AddFile(r.Name, r.base, r.fileSize()) - if !ff.SetLines(r.lines) { - panic("ff.SetLines failed") - } - - if r.Extras { - // Sometimes new nodes are created here (e.g. in RangeStmt the "Object" is an AssignStmt - // which never occurs in the actual code). These shouldn't have position information but - // perhaps it doesn't matter? - for o, dn := range r.nodeDecl { - o.Decl = r.restoreNode(dn, "", "", "", true) - } - for o, dn := range r.nodeData { - o.Data = r.restoreNode(dn, "", "", "", true) - } - } - - return f, nil -} - -func (r *FileRestorer) updateImports() error { - - if r.Resolver == nil { - return nil - } - - // list of the import block(s) - var blocks []*dst.GenDecl - - // hasCgoBlock is only true if the "C" import is on it's own in a block at the start of the - // file. If so, this is avoided. If there are no more imports in the file, and a new block is - // added, it should be added below this block. - var hasCgoBlock bool - - // map of package path -> alias for all packages currently in the imports block(s). Alias can - // be an alias, an empty string, "_" or "." - importsFound := map[string]string{} - - // a list of all packages that occur in the source (package path -> true) - packagesInUse := map[string]bool{} - - // a list of all the imports that will be in the imports block after the update - importsRequired := map[string]bool{} - - dst.Inspect(r.file, func(n dst.Node) bool { - switch n := n.(type) { - case *dst.Ident: - if n.Path == "" { - return true - } - if n.Path == r.Path { - return true - } - packagesInUse[n.Path] = true - importsRequired[n.Path] = true - - case *dst.GenDecl: - if n.Tok != token.IMPORT { - return true - } - // if this block has 1 spec and it's the "C" import, ignore it. - if len(n.Specs) == 1 && mustUnquote(n.Specs[0].(*dst.ImportSpec).Path.Value) == "C" { - hasCgoBlock = true - return true - } - blocks = append(blocks, n) - - case *dst.ImportSpec: - path := mustUnquote(n.Path.Value) - if n.Name == nil { - importsFound[path] = "" - } else { - importsFound[path] = n.Name.Name - } - if path == "C" { - // never remove the "C" import - importsRequired["C"] = true - } - } - return true - }) - - // resolved names of all packages in use - resolved := map[string]string{} - - // the effective alias requested - the manually supplied alias will override the alias from the - // import block - effectiveAlias := map[string]string{} - for path, alias := range importsFound { - if alias == "" { - continue - } - if a, ok := r.Alias[path]; ok && a == "" { - continue - } - if alias == "_" && packagesInUse[path] { - continue - } - effectiveAlias[path] = alias - } - for path, alias := range r.Alias { - if alias == "" { - continue - } - if alias == "_" && packagesInUse[path] { - continue - } - effectiveAlias[path] = alias - } - - // any anonymous imports - for path, alias := range effectiveAlias { - if alias == "_" { - importsRequired[path] = true - } - } - - for path := range packagesInUse { - if _, ok := effectiveAlias[path]; ok { - // no need to resolve the path of a package that has an alias - continue - } - name, err := r.Resolver.ResolvePackage(path) - if err != nil { - return fmt.Errorf("could not resolve package %s: %w", path, err) - } - resolved[path] = name - } - - // We sort the required imports so that the order going into the alias conflict detection - // routine is determinate. Without this, in a conflict, the package that receives the automatic - // renamed alias would be different every time. - importsRequiredOrdered := make([]string, len(importsRequired)) - i := 0 - for path := range importsRequired { - importsRequiredOrdered[i] = path - i++ - } - sort.Slice(importsRequiredOrdered, func(i, j int) bool { return packagePathOrderLess(importsRequiredOrdered[i], importsRequiredOrdered[j]) }) - - // alias in the imports block (alias, empty string, "_" or "." - aliases := map[string]string{} - - // name in the code (name or empty string for dot imports). This is consumed later by the - // restoreIdent method, so is a field on FileRestorer. - r.packageNames = map[string]string{} - - // conflict returns true if the provided name already exists in the packageNames list - conflict := func(name string) bool { - for _, n := range r.packageNames { - if name == n { - return true - } - } - return false - } - - // findAlias finds a unique alias given a path and a preferred alias - findAlias := func(path, preferred string) (name, alias string) { - - // if we pass in a preferred alias we should always return an alias even when the alias - // matches the package name. If for some reason the source file has aliased an import with - // the package name, we shouldn't remove this. - aliased := preferred != "" - - if !aliased { - // if there is no preferred alias, we look up the name of the package in the resolved - // names map. - preferred = resolved[path] - } - - // if the current name has a conflict, increment a modifier until a non-conflicting name is - // found - modifier := 1 - current := preferred - for conflict(current) { - current = fmt.Sprintf("%s%d", preferred, modifier) - modifier++ - } - - if !aliased && current == resolved[path] { - // if we didn't supply an alias and the resultant name matches the default package name, - // return empty string for alias indicating that no alias is required. - return current, "" - } - - return current, current - } - - for _, path := range importsRequiredOrdered { - - alias := effectiveAlias[path] - - if alias == "." || alias == "_" { - // no conflict checking for dot-imports or anonymous imports - r.packageNames[path], aliases[path] = "", alias - continue - } - - // regular imports have a unique name chosen. - r.packageNames[path], aliases[path] = findAlias(path, alias) - } - - // make any additions - var added bool - for _, path := range importsRequiredOrdered { - - if _, ok := importsFound[path]; ok { - continue - } - - added = true - - // if there's currently no import blocks, we must create one - if len(blocks) == 0 { - gd := &dst.GenDecl{ - Tok: token.IMPORT, - // make sure it has an empty line before and after - Decs: dst.GenDeclDecorations{ - NodeDecs: dst.NodeDecs{Before: dst.EmptyLine, After: dst.EmptyLine}, - }, - } - if hasCgoBlock { - // special case for if we have the "C" import - r.file.Decls = append([]dst.Decl{r.file.Decls[0], gd}, r.file.Decls[1:]...) - } else { - r.file.Decls = append([]dst.Decl{gd}, r.file.Decls...) - } - blocks = append(blocks, gd) - } - - is := &dst.ImportSpec{ - Path: &dst.BasicLit{Kind: token.STRING, Value: fmt.Sprintf("%q", path)}, - } - if aliases[path] != "" { - is.Name = &dst.Ident{ - Name: aliases[path], - } - } - blocks[0].Specs = append(blocks[0].Specs, is) - } - - if added { - // rearrange import block - sort.Slice(blocks[0].Specs, func(i, j int) bool { - return packagePathOrderLess( - mustUnquote(blocks[0].Specs[i].(*dst.ImportSpec).Path.Value), - mustUnquote(blocks[0].Specs[j].(*dst.ImportSpec).Path.Value), - ) - }) - } - - // import blocks that are empty will be removed from the File Decls list later - deleteBlocks := map[dst.Decl]bool{} - - // update / delete any import specs from all blocks - for _, block := range blocks { - specs := make([]dst.Spec, 0, len(block.Specs)) - for _, spec := range block.Specs { - spec := spec.(*dst.ImportSpec) - path := mustUnquote(spec.Path.Value) - if importsRequired[path] { - if spec.Name == nil && aliases[path] != "" { - // missing alias - spec.Name = &dst.Ident{Name: aliases[path]} - } else if spec.Name != nil && aliases[path] == "" { - // alias needs to be removed - spec.Name = nil - } else if spec.Name != nil && aliases[path] != spec.Name.Name { - // alias wrong - spec.Name.Name = aliases[path] - } - specs = append(specs, spec) - } - } - - count := len(specs) - - if count != len(block.Specs) { - - block.Specs = specs - - if count == 0 { - deleteBlocks[block] = true - } else if count == 1 { - block.Lparen = false - block.Rparen = false - } else { - block.Lparen = true - block.Rparen = true - } - } - } - - if added { - // imports with a period in the path are assumed to not be standard library packages, so - // get a newline separating them from standard library packages. We remove any other - // newlines found in this block. We do this after the deletions because the first non-stdlib - // import might be deleted. - var foundDomainImport bool - for _, spec := range blocks[0].Specs { - path := mustUnquote(spec.(*dst.ImportSpec).Path.Value) - if strings.Contains(path, ".") && !foundDomainImport { - // first non-std-lib import -> empty line above - spec.Decorations().Before = dst.EmptyLine - spec.Decorations().After = dst.NewLine - foundDomainImport = true - continue - } - // all other specs, just newlines - spec.Decorations().Before = dst.NewLine - spec.Decorations().After = dst.NewLine - } - - if len(blocks[0].Specs) == 1 { - blocks[0].Lparen = false - blocks[0].Rparen = false - } else { - blocks[0].Lparen = true - blocks[0].Rparen = true - } - } - - // finally remove any deleted blocks from the File Decls list - if len(deleteBlocks) > 0 { - decls := make([]dst.Decl, 0, len(r.file.Decls)) - for _, decl := range r.file.Decls { - if deleteBlocks[decl] { - continue - } - decls = append(decls, decl) - } - r.file.Decls = decls - } - - return nil -} - -// restoreIdent is a special case for restoring an ident. If the ident has a path and the imported -// package is not a dot-import, we restore the Ident to a *ast.SelectorExpr with the correct name -// in the X field. -func (r *FileRestorer) restoreIdent(n *dst.Ident, parentName, parentField, parentFieldType string, allowDuplicate bool) ast.Node { - - if r.Resolver == nil && n.Path != "" { - panic("This syntax has been decorated with import management enabled, but the restorer does not have import management enabled. Use NewRestorerWithImports to create a restorer with import management. See the Imports section of the readme for more information.") - } - - var name string - if r.Resolver != nil && n.Path != "" { - - if avoid[parentName+"."+parentField] { - panic(fmt.Sprintf("Path %s set on illegal Ident %s: parentName %s, parentField %s, parentFieldType %s", n.Path, n.Name, parentName, parentField, parentFieldType)) - } - - if n.Path != r.Path { - name = r.packageNames[n.Path] - } - - if name == "." { - name = "" - } - } - - if name == "" { - // continue to run standard Ident restore - return nil - } - - // restore to a SelectorExpr - out := &ast.SelectorExpr{} - r.Ast.Nodes[n] = out - r.Dst.Nodes[out] = n - r.Dst.Nodes[out.Sel] = n - r.Dst.Nodes[out.X] = n - r.applySpace(n, "Before", n.Decs.Before) - - // Decoration: Start - r.applyDecorations(out, "Start", n.Decs.Start, false) - - // Node: X - out.X = r.restoreNode(dst.NewIdent(name), "SelectorExpr", "X", "Expr", allowDuplicate).(ast.Expr) - - // Token: Period - r.cursor += token.Pos(len(token.PERIOD.String())) - - // Decoration: X - r.applyDecorations(out, "X", n.Decs.X, false) - - // Node: Sel - out.Sel = r.restoreNode(dst.NewIdent(n.Name), "SelectorExpr", "Sel", "Ident", allowDuplicate).(*ast.Ident) - - // Decoration: End - r.applyDecorations(out, "End", n.Decs.End, true) - r.applySpace(n, "After", n.Decs.After) - - return out - -} - -func packagePathOrderLess(pi, pj string) bool { - // package paths with a . should be ordered after those without - idot := strings.Contains(pi, ".") - jdot := strings.Contains(pj, ".") - if idot != jdot { - return jdot - } - return pi < pj -} - -func (r *FileRestorer) fileSize() int { - - // If a comment is at the end of a file, it will extend past the current cursor position... - - // end pos of file - end := int(r.cursor) - - // check that none of the comments or newlines extend past the file end position. If so, increment. - for _, cg := range r.comments { - if int(cg.End()) >= end { - end = int(cg.End()) + 1 - } - } - for _, lineOffset := range r.lines { - pos := lineOffset + r.base // remember lines are relative to the file base - if pos >= end { - end = pos + 1 - } - } - - return end - r.base -} - -func (r *FileRestorer) applyLiteral(text string) { - isMultiLine := strings.HasPrefix(text, "`") && strings.Contains(text, "\n") - if !isMultiLine { - return - } - for charIndex, char := range text { - if char == '\n' { - lineOffset := int(r.cursor) - r.base + charIndex // remember lines are relative to the file base - r.lines = append(r.lines, lineOffset) - } - } -} - -func (r *FileRestorer) hasCommentField(n ast.Node) bool { - switch n.(type) { - case *ast.Field, *ast.ValueSpec, *ast.TypeSpec, *ast.ImportSpec: - return true - } - return false -} - -func (r *FileRestorer) addCommentField(n ast.Node, slash token.Pos, text string) { - c := &ast.Comment{Slash: slash, Text: text} - switch n := n.(type) { - case *ast.Field: - if n.Comment == nil { - n.Comment = &ast.CommentGroup{} - r.comments = append(r.comments, n.Comment) - } - n.Comment.List = append(n.Comment.List, c) - case *ast.ImportSpec: - if n.Comment == nil { - n.Comment = &ast.CommentGroup{} - r.comments = append(r.comments, n.Comment) - } - n.Comment.List = append(n.Comment.List, c) - case *ast.ValueSpec: - if n.Comment == nil { - n.Comment = &ast.CommentGroup{} - r.comments = append(r.comments, n.Comment) - } - n.Comment.List = append(n.Comment.List, c) - case *ast.TypeSpec: - if n.Comment == nil { - n.Comment = &ast.CommentGroup{} - r.comments = append(r.comments, n.Comment) - } - n.Comment.List = append(n.Comment.List, c) - } -} - -func (r *FileRestorer) applyDecorations(node ast.Node, name string, decorations dst.Decorations, end bool) { - firstLine := true - _, isNodeFile := node.(*ast.File) - isPackageComment := isNodeFile && name == "Start" - - for _, d := range decorations { - - isNewline := d == "\n" - isLineComment := strings.HasPrefix(d, "//") - isInlineComment := strings.HasPrefix(d, "/*") - isComment := isLineComment || isInlineComment - isMultiLineComment := isInlineComment && strings.Contains(d, "\n") - - if end && r.cursorAtNewLine == r.cursor { - r.cursor++ // indent all comments in "End" decorations - } - - // for multi-line comments, add a newline for each \n - if isMultiLineComment { - for charIndex, char := range d { - if char == '\n' { - lineOffset := int(r.cursor) - r.base + charIndex // remember lines are relative to the file base - r.lines = append(r.lines, lineOffset) - } - } - } - - // if the decoration is a comment, add it and advance the cursor - if isComment { - if firstLine && end && r.hasCommentField(node) { - // for comments on the same line as the end of a node that has a Comment field, we - // add the comment to the node instead of the file. - r.addCommentField(node, r.cursor, d) - } else { - r.comments = append(r.comments, &ast.CommentGroup{List: []*ast.Comment{{Slash: r.cursor, Text: d}}}) - } - r.cursor += token.Pos(len(d)) - } - - // for newline decorations and also line-comments, add a newline - if isLineComment || isNewline { - lineOffset := int(r.cursor) - r.base // remember lines are relative to the file base - r.lines = append(r.lines, lineOffset) - r.cursor++ - - r.cursorAtNewLine = r.cursor - } - - if isNewline || isLineComment { - firstLine = false - } - } - if isPackageComment { - // This fixes https://github.com/dave/dst/issues/69 - r.cursor++ - } -} - -func (r *FileRestorer) applySpace(node dst.Node, position string, space dst.SpaceType) { - switch node.(type) { - case *dst.BadDecl, *dst.BadExpr, *dst.BadStmt: - if position == "After" { - // BadXXX are always followed by an empty line - space = dst.EmptyLine - } - } - var newlines int - switch space { - case dst.NewLine: - newlines = 1 - case dst.EmptyLine: - newlines = 2 - } - if r.cursor == r.cursorAtNewLine { - newlines-- - } - for i := 0; i < newlines; i++ { - - // Advance the cursor one more byte for all newlines, so we step over any required - // separator char - e.g. comma. See net-hook test - r.cursor++ - - lineOffset := int(r.cursor) - r.base // remember lines are relative to the file base - r.lines = append(r.lines, lineOffset) - r.cursor++ - r.cursorAtNewLine = r.cursor - } -} - -func (r *FileRestorer) restoreObject(o *dst.Object) *ast.Object { - if !r.Extras { - return nil - } - if o == nil { - return nil - } - if ro, ok := r.Ast.Objects[o]; ok { - return ro - } - /* - // An Object describes a named language entity such as a package, - // constant, type, variable, function (incl. methods), or label. - // - // The Data fields contains object-specific data: - // - // Kind Data type Data value - // Pkg *Scope package scope - // Con int iota for the respective declaration - // - type Object struct { - Kind ObjKind - Name string // declared name - Decl interface{} // corresponding Field, XxxSpec, FuncDecl, LabeledStmt, AssignStmt, Scope; or nil - Data interface{} // object-specific data; or nil - Type interface{} // placeholder for type information; may be nil - } - */ - out := &ast.Object{} - - r.Ast.Objects[o] = out - r.Dst.Objects[out] = o - - out.Kind = ast.ObjKind(o.Kind) - out.Name = o.Name - - switch decl := o.Decl.(type) { - case *dst.Scope: - out.Decl = r.restoreScope(decl) - case dst.Node: - // Can't use restoreNode here because we aren't at the right cursor position, so we store a link - // to the Object and Node so we can look the Nodes up in the cache after the file is fully processed. - r.nodeDecl[out] = decl - case nil: - default: - panic(fmt.Sprintf("o.Decl is %T", o.Decl)) - } - - switch data := o.Data.(type) { - case int: - out.Data = data - case *dst.Scope: - out.Data = r.restoreScope(data) - case dst.Node: - // Can't use restoreNode here because we aren't at the right cursor position, so we store a link - // to the Object and Node so we can look the Nodes up in the cache after the file is fully processed. - r.nodeData[out] = data - case nil: - default: - panic(fmt.Sprintf("o.Data is %T", o.Data)) - } - - return out -} - -func (r *FileRestorer) restoreScope(s *dst.Scope) *ast.Scope { - if !r.Extras { - return nil - } - if s == nil { - return nil - } - if rs, ok := r.Ast.Scopes[s]; ok { - return rs - } - /* - // A Scope maintains the set of named language entities declared - // in the scope and a link to the immediately surrounding (outer) - // scope. - // - type Scope struct { - Outer *Scope - Objects map[string]*Object - } - */ - out := &ast.Scope{} - - r.Ast.Scopes[s] = out - r.Dst.Scopes[out] = s - - out.Outer = r.restoreScope(s.Outer) - out.Objects = map[string]*ast.Object{} - for k, v := range s.Objects { - out.Objects[k] = r.restoreObject(v) - } - - return out -} - -func mustUnquote(s string) string { - out, err := strconv.Unquote(s) - if err != nil { - panic(err) - } - return out -} diff --git a/vendor/github.com/dave/dst/dst.go b/vendor/github.com/dave/dst/dst.go deleted file mode 100644 index 803eb9a879..0000000000 --- a/vendor/github.com/dave/dst/dst.go +++ /dev/null @@ -1,664 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package dst declares the types used to represent decorated syntax -// trees for Go packages. -package dst - -import ( - "go/token" -) - -// ---------------------------------------------------------------------------- -// Interfaces -// -// There are 3 main classes of nodes: Expressions and type nodes, -// statement nodes, and declaration nodes. The node names usually -// match the corresponding Go spec production names to which they -// correspond. The node fields correspond to the individual parts -// of the respective productions. -// -// All nodes contain position information marking the beginning of -// the corresponding source text segment; it is accessible via the -// Pos accessor method. Nodes may contain additional position info -// for language constructs where comments may be found between parts -// of the construct (typically any larger, parenthesized subpart). -// That position information is needed to properly position comments -// when printing the construct. - -// Node is satisfied by all nodes types. -type Node interface { - // Decorations returns the common Node decorations (Before, After, Start, End). This returns nil for Package nodes. - Decorations() *NodeDecs -} - -// All expression nodes implement the Expr interface. -type Expr interface { - Node - exprNode() -} - -// All statement nodes implement the Stmt interface. -type Stmt interface { - Node - stmtNode() -} - -// All declaration nodes implement the Decl interface. -type Decl interface { - Node - declNode() -} - -// ---------------------------------------------------------------------------- -// Expressions and types - -// A Field represents a Field declaration list in a struct type, -// a method list in an interface type, or a parameter/result declaration -// in a signature. -// Field.Names is nil for unnamed parameters (parameter lists which only contain types) -// and embedded struct fields. In the latter case, the field name is the type name. -// -type Field struct { - Names []*Ident // field/method/(type) parameter names; or nil - Type Expr // field/method/parameter type; or nil - Tag *BasicLit // field tag; or nil - Decs FieldDecorations -} - -// A FieldList represents a list of Fields, enclosed by parentheses, -// curly braces, or square brackets. -type FieldList struct { - Opening bool - List []*Field // field list; or nil - Closing bool - Decs FieldListDecorations -} - -// NumFields returns the number of parameters or struct fields represented by a FieldList. -func (f *FieldList) NumFields() int { - n := 0 - if f != nil { - for _, g := range f.List { - m := len(g.Names) - if m == 0 { - m = 1 - } - n += m - } - } - return n -} - -// An expression is represented by a tree consisting of one -// or more of the following concrete expression nodes. -type ( - // A BadExpr node is a placeholder for an expression containing - // syntax errors for which a correct expression node cannot be - // created. - BadExpr struct { - Length int // position range of bad expression - Decs BadExprDecorations - } - - // An Ident node represents an identifier. - Ident struct { - Name string // identifier name - Obj *Object // denoted object; or nil - Path string // path of the imported package, if this identifier is not local - Decs IdentDecorations - } - - // An Ellipsis node stands for the "..." type in a - // parameter list or the "..." length in an array type. - // - Ellipsis struct { - Elt Expr // ellipsis element type (parameter lists only); or nil - Decs EllipsisDecorations - } - - // A BasicLit node represents a literal of basic type. - BasicLit struct { - Kind token.Token // token.INT, token.FLOAT, token.IMAG, token.CHAR, or token.STRING - Value string // literal string; e.g. 42, 0x7f, 3.14, 1e-9, 2.4i, 'a', '\x7f', "foo" or `\m\n\o` - Decs BasicLitDecorations - } - - // A FuncLit node represents a function literal. - FuncLit struct { - Type *FuncType // function type - Body *BlockStmt // function body - Decs FuncLitDecorations - } - - // A CompositeLit node represents a composite literal. - CompositeLit struct { - Type Expr // literal type; or nil - Elts []Expr // list of composite elements; or nil - Incomplete bool // true if (source) expressions are missing in the Elts list - Decs CompositeLitDecorations - } - - // A ParenExpr node represents a parenthesized expression. - ParenExpr struct { - X Expr // parenthesized expression - Decs ParenExprDecorations - } - - // A SelectorExpr node represents an expression followed by a selector. - SelectorExpr struct { - X Expr // expression - Sel *Ident // field selector - Decs SelectorExprDecorations - } - - // An IndexExpr node represents an expression followed by an index. - IndexExpr struct { - X Expr // expression - Index Expr // index expression - Decs IndexExprDecorations - } - - // An IndexListExpr node represents an expression followed by multiple - // indices. - IndexListExpr struct { - X Expr // expression - Indices []Expr - Decs IndexListExprDecorations - } - - // An SliceExpr node represents an expression followed by slice indices. - SliceExpr struct { - X Expr // expression - Low Expr // begin of slice range; or nil - High Expr // end of slice range; or nil - Max Expr // maximum capacity of slice; or nil - Slice3 bool // true if 3-index slice (2 colons present) - Decs SliceExprDecorations - } - - // A TypeAssertExpr node represents an expression followed by a - // type assertion. - // - TypeAssertExpr struct { - X Expr // expression - Type Expr // asserted type; nil means type switch X.(type) - Decs TypeAssertExprDecorations - } - - // A CallExpr node represents an expression followed by an argument list. - CallExpr struct { - Fun Expr // function expression - Args []Expr // function arguments; or nil - Ellipsis bool - Decs CallExprDecorations - } - - // A StarExpr node represents an expression of the form "*" Expression. - // Semantically it could be a unary "*" expression, or a pointer type. - // - StarExpr struct { - X Expr // operand - Decs StarExprDecorations - } - - // A UnaryExpr node represents a unary expression. - // Unary "*" expressions are represented via StarExpr nodes. - // - UnaryExpr struct { - Op token.Token // operator - X Expr // operand - Decs UnaryExprDecorations - } - - // A BinaryExpr node represents a binary expression. - BinaryExpr struct { - X Expr // left operand - Op token.Token // operator - Y Expr // right operand - Decs BinaryExprDecorations - } - - // A KeyValueExpr node represents (key : value) pairs - // in composite literals. - // - KeyValueExpr struct { - Key Expr - Value Expr - Decs KeyValueExprDecorations - } -) - -// The direction of a channel type is indicated by a bit -// mask including one or both of the following constants. -type ChanDir int - -const ( - SEND ChanDir = 1 << iota - RECV -) - -// A type is represented by a tree consisting of one -// or more of the following type-specific expression -// nodes. -type ( - // An ArrayType node represents an array or slice type. - ArrayType struct { - Len Expr // Ellipsis node for [...]T array types, nil for slice types - Elt Expr // element type - Decs ArrayTypeDecorations - } - - // A StructType node represents a struct type. - StructType struct { - Fields *FieldList // list of field declarations - Incomplete bool // true if (source) fields are missing in the Fields list - Decs StructTypeDecorations - } - - // Pointer types are represented via StarExpr nodes. - - // A FuncType node represents a function type. - FuncType struct { - Func bool - TypeParams *FieldList // type parameters; or nil - Params *FieldList // (incoming) parameters; non-nil - Results *FieldList // (outgoing) results; or nil - Decs FuncTypeDecorations - } - - // An InterfaceType node represents an interface type. - InterfaceType struct { - Methods *FieldList // list of embedded interfaces, methods, or types - Incomplete bool // true if (source) methods or types are missing in the Methods list - Decs InterfaceTypeDecorations - } - - // A MapType node represents a map type. - MapType struct { - Key Expr - Value Expr - Decs MapTypeDecorations - } - - // A ChanType node represents a channel type. - ChanType struct { - Dir ChanDir // channel direction - Value Expr // value type - Decs ChanTypeDecorations - } -) - -// exprNode() ensures that only expression/type nodes can be -// assigned to an Expr. -func (*BadExpr) exprNode() {} -func (*Ident) exprNode() {} -func (*Ellipsis) exprNode() {} -func (*BasicLit) exprNode() {} -func (*FuncLit) exprNode() {} -func (*CompositeLit) exprNode() {} -func (*ParenExpr) exprNode() {} -func (*SelectorExpr) exprNode() {} -func (*IndexExpr) exprNode() {} -func (*IndexListExpr) exprNode() {} -func (*SliceExpr) exprNode() {} -func (*TypeAssertExpr) exprNode() {} -func (*CallExpr) exprNode() {} -func (*StarExpr) exprNode() {} -func (*UnaryExpr) exprNode() {} -func (*BinaryExpr) exprNode() {} -func (*KeyValueExpr) exprNode() {} - -func (*ArrayType) exprNode() {} -func (*StructType) exprNode() {} -func (*FuncType) exprNode() {} -func (*InterfaceType) exprNode() {} -func (*MapType) exprNode() {} -func (*ChanType) exprNode() {} - -// ---------------------------------------------------------------------------- -// Convenience functions for Idents - -// NewIdent creates a new Ident without position. -// Useful for ASTs generated by code other than the Go parser. -func NewIdent(name string) *Ident { return &Ident{name, nil, "", IdentDecorations{}} } - -// IsExported reports whether name starts with an upper-case letter. -func IsExported(name string) bool { return token.IsExported(name) } - -// IsExported reports whether id starts with an upper-case letter. -func (id *Ident) IsExported() bool { return token.IsExported(id.Name) } - -func (id *Ident) String() string { - if id != nil { - if id.Path != "" { - return id.Path + "." + id.Name - } - return id.Name - } - return "" -} - -// ---------------------------------------------------------------------------- -// Statements - -// A statement is represented by a tree consisting of one -// or more of the following concrete statement nodes. -type ( - // A BadStmt node is a placeholder for statements containing - // syntax errors for which no correct statement nodes can be - // created. - // - BadStmt struct { - Length int // position range of bad statement - Decs BadStmtDecorations - } - - // A DeclStmt node represents a declaration in a statement list. - DeclStmt struct { - Decl Decl // *GenDecl with CONST, TYPE, or VAR token - Decs DeclStmtDecorations - } - - // An EmptyStmt node represents an empty statement. - // The "position" of the empty statement is the position - // of the immediately following (explicit or implicit) semicolon. - // - EmptyStmt struct { - Implicit bool // if set, ";" was omitted in the source - Decs EmptyStmtDecorations - } - - // A LabeledStmt node represents a labeled statement. - LabeledStmt struct { - Label *Ident - Stmt Stmt - Decs LabeledStmtDecorations - } - - // An ExprStmt node represents a (stand-alone) expression - // in a statement list. - // - ExprStmt struct { - X Expr // expression - Decs ExprStmtDecorations - } - - // A SendStmt node represents a send statement. - SendStmt struct { - Chan Expr - Value Expr - Decs SendStmtDecorations - } - - // An IncDecStmt node represents an increment or decrement statement. - IncDecStmt struct { - X Expr - Tok token.Token // INC or DEC - Decs IncDecStmtDecorations - } - - // An AssignStmt node represents an assignment or - // a short variable declaration. - // - AssignStmt struct { - Lhs []Expr - Tok token.Token // assignment token, DEFINE - Rhs []Expr - Decs AssignStmtDecorations - } - - // A GoStmt node represents a go statement. - GoStmt struct { - Call *CallExpr - Decs GoStmtDecorations - } - - // A DeferStmt node represents a defer statement. - DeferStmt struct { - Call *CallExpr - Decs DeferStmtDecorations - } - - // A ReturnStmt node represents a return statement. - ReturnStmt struct { - Results []Expr // result expressions; or nil - Decs ReturnStmtDecorations - } - - // A BranchStmt node represents a break, continue, goto, - // or fallthrough statement. - // - BranchStmt struct { - Tok token.Token // keyword token (BREAK, CONTINUE, GOTO, FALLTHROUGH) - Label *Ident // label name; or nil - Decs BranchStmtDecorations - } - - // A BlockStmt node represents a braced statement list. - BlockStmt struct { - List []Stmt - RbraceHasNoPos bool // Rbrace may be absent due to syntax error, so we duplicate this in the output for compatibility. - Decs BlockStmtDecorations - } - - // An IfStmt node represents an if statement. - IfStmt struct { - Init Stmt // initialization statement; or nil - Cond Expr // condition - Body *BlockStmt - Else Stmt // else branch; or nil - Decs IfStmtDecorations - } - - // A CaseClause represents a case of an expression or type switch statement. - CaseClause struct { - List []Expr // list of expressions or types; nil means default case - Body []Stmt // statement list; or nil - Decs CaseClauseDecorations - } - - // A SwitchStmt node represents an expression switch statement. - SwitchStmt struct { - Init Stmt // initialization statement; or nil - Tag Expr // tag expression; or nil - Body *BlockStmt // CaseClauses only - Decs SwitchStmtDecorations - } - - // A TypeSwitchStmt node represents a type switch statement. - TypeSwitchStmt struct { - Init Stmt // initialization statement; or nil - Assign Stmt // x := y.(type) or y.(type) - Body *BlockStmt // CaseClauses only - Decs TypeSwitchStmtDecorations - } - - // A CommClause node represents a case of a select statement. - CommClause struct { - Comm Stmt // send or receive statement; nil means default case - Body []Stmt // statement list; or nil - Decs CommClauseDecorations - } - - // A SelectStmt node represents a select statement. - SelectStmt struct { - Body *BlockStmt // CommClauses only - Decs SelectStmtDecorations - } - - // A ForStmt represents a for statement. - ForStmt struct { - Init Stmt // initialization statement; or nil - Cond Expr // condition; or nil - Post Stmt // post iteration statement; or nil - Body *BlockStmt - Decs ForStmtDecorations - } - - // A RangeStmt represents a for statement with a range clause. - RangeStmt struct { - Key, Value Expr // Key, Value may be nil - Tok token.Token // ILLEGAL if Key == nil, ASSIGN, DEFINE - X Expr // value to range over - Body *BlockStmt - Decs RangeStmtDecorations - } -) - -// stmtNode() ensures that only statement nodes can be -// assigned to a Stmt. -func (*BadStmt) stmtNode() {} -func (*DeclStmt) stmtNode() {} -func (*EmptyStmt) stmtNode() {} -func (*LabeledStmt) stmtNode() {} -func (*ExprStmt) stmtNode() {} -func (*SendStmt) stmtNode() {} -func (*IncDecStmt) stmtNode() {} -func (*AssignStmt) stmtNode() {} -func (*GoStmt) stmtNode() {} -func (*DeferStmt) stmtNode() {} -func (*ReturnStmt) stmtNode() {} -func (*BranchStmt) stmtNode() {} -func (*BlockStmt) stmtNode() {} -func (*IfStmt) stmtNode() {} -func (*CaseClause) stmtNode() {} -func (*SwitchStmt) stmtNode() {} -func (*TypeSwitchStmt) stmtNode() {} -func (*CommClause) stmtNode() {} -func (*SelectStmt) stmtNode() {} -func (*ForStmt) stmtNode() {} -func (*RangeStmt) stmtNode() {} - -// ---------------------------------------------------------------------------- -// Declarations - -// A Spec node represents a single (non-parenthesized) import, -// constant, type, or variable declaration. -type ( - // The Spec type stands for any of *ImportSpec, *ValueSpec, and *TypeSpec. - Spec interface { - Node - specNode() - } - - // An ImportSpec node represents a single package import. - ImportSpec struct { - Name *Ident // local package name (including "."); or nil - Path *BasicLit // import path - Decs ImportSpecDecorations - } - - // A ValueSpec node represents a constant or variable declaration - // (ConstSpec or VarSpec production). - // - ValueSpec struct { - Names []*Ident // value names (len(Names) > 0) - Type Expr // value type; or nil - Values []Expr // initial values; or nil - Decs ValueSpecDecorations - } - - // A TypeSpec node represents a type declaration (TypeSpec production). - TypeSpec struct { - Name *Ident // type name - TypeParams *FieldList // type parameters; or nil - Assign bool // position of '=', if any - Type Expr // *Ident, *ParenExpr, *SelectorExpr, *StarExpr, or any of the *XxxTypes - Decs TypeSpecDecorations - } -) - -// Pos and End implementations for spec nodes. - -// specNode() ensures that only spec nodes can be -// assigned to a Spec. -func (*ImportSpec) specNode() {} -func (*ValueSpec) specNode() {} -func (*TypeSpec) specNode() {} - -// A declaration is represented by one of the following declaration nodes. -type ( - // A BadDecl node is a placeholder for a declaration containing - // syntax errors for which a correct declaration node cannot be - // created. - // - BadDecl struct { - Length int // position range of bad declaration - Decs BadDeclDecorations - } - - // A GenDecl node (generic declaration node) represents an import, - // constant, type or variable declaration. A valid Lparen position - // (Lparen.IsValid()) indicates a parenthesized declaration. - // - // Relationship between Tok value and Specs element type: - // - // token.IMPORT *ImportSpec - // token.CONST *ValueSpec - // token.TYPE *TypeSpec - // token.VAR *ValueSpec - // - GenDecl struct { - Tok token.Token // IMPORT, CONST, TYPE, or VAR - Lparen bool - Specs []Spec - Rparen bool - Decs GenDeclDecorations - } - - // A FuncDecl node represents a function declaration. - FuncDecl struct { - Recv *FieldList // receiver (methods); or nil (functions) - Name *Ident // function/method name - Type *FuncType // function signature: type and value parameters, results, and position of "func" keyword - Body *BlockStmt // function body; or nil for external (non-Go) function - Decs FuncDeclDecorations - } -) - -// declNode() ensures that only declaration nodes can be -// assigned to a Decl. -func (*BadDecl) declNode() {} -func (*GenDecl) declNode() {} -func (*FuncDecl) declNode() {} - -// ---------------------------------------------------------------------------- -// Files and packages - -// A File node represents a Go source file. -// -// The Comments list contains all comments in the source file in order of -// appearance, including the comments that are pointed to from other nodes -// via Doc and Comment fields. -// -// For correct printing of source code containing comments (using packages -// go/format and go/printer), special care must be taken to update comments -// when a File's syntax tree is modified: For printing, comments are interspersed -// between tokens based on their position. If syntax tree nodes are -// removed or moved, relevant comments in their vicinity must also be removed -// (from the File.Comments list) or moved accordingly (by updating their -// positions). A CommentMap may be used to facilitate some of these operations. -// -// Whether and how a comment is associated with a node depends on the -// interpretation of the syntax tree by the manipulating program: Except for Doc -// and Comment comments directly associated with nodes, the remaining comments -// are "free-floating" (see also issues #18593, #20744). -type File struct { - Name *Ident // package name - Decls []Decl // top-level declarations; or nil - Scope *Scope // package scope (this file only) - Imports []*ImportSpec // imports in this file - Unresolved []*Ident // unresolved identifiers in this file - Decs FileDecorations -} - -// A Package node represents a set of source files -// collectively building a Go package. -type Package struct { - Name string // package name - Scope *Scope // package scope across all files - Imports map[string]*Object // map of package id -> package object - Files map[string]*File // Go source files by filename -} diff --git a/vendor/github.com/dave/dst/dstutil/decorations-generated.go b/vendor/github.com/dave/dst/dstutil/decorations-generated.go deleted file mode 100644 index b3e31579f0..0000000000 --- a/vendor/github.com/dave/dst/dstutil/decorations-generated.go +++ /dev/null @@ -1,369 +0,0 @@ -package dstutil - -import "github.com/dave/dst" - -func decorations(n dst.Node) (before, after dst.SpaceType, points []DecorationPoint) { - switch n := n.(type) { - case *dst.ArrayType: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"Lbrack", n.Decs.Lbrack}) - points = append(points, DecorationPoint{"Len", n.Decs.Len}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.AssignStmt: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"Tok", n.Decs.Tok}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.BadDecl: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.BadExpr: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.BadStmt: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.BasicLit: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.BinaryExpr: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"X", n.Decs.X}) - points = append(points, DecorationPoint{"Op", n.Decs.Op}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.BlockStmt: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"Lbrace", n.Decs.Lbrace}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.BranchStmt: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"Tok", n.Decs.Tok}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.CallExpr: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"Fun", n.Decs.Fun}) - points = append(points, DecorationPoint{"Lparen", n.Decs.Lparen}) - points = append(points, DecorationPoint{"Ellipsis", n.Decs.Ellipsis}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.CaseClause: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"Case", n.Decs.Case}) - points = append(points, DecorationPoint{"Colon", n.Decs.Colon}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.ChanType: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"Begin", n.Decs.Begin}) - points = append(points, DecorationPoint{"Arrow", n.Decs.Arrow}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.CommClause: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"Case", n.Decs.Case}) - points = append(points, DecorationPoint{"Comm", n.Decs.Comm}) - points = append(points, DecorationPoint{"Colon", n.Decs.Colon}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.CompositeLit: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"Type", n.Decs.Type}) - points = append(points, DecorationPoint{"Lbrace", n.Decs.Lbrace}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.DeclStmt: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.DeferStmt: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"Defer", n.Decs.Defer}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.Ellipsis: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"Ellipsis", n.Decs.Ellipsis}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.EmptyStmt: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.ExprStmt: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.Field: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"Type", n.Decs.Type}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.FieldList: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"Opening", n.Decs.Opening}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.File: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"Package", n.Decs.Package}) - points = append(points, DecorationPoint{"Name", n.Decs.Name}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.ForStmt: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"For", n.Decs.For}) - points = append(points, DecorationPoint{"Init", n.Decs.Init}) - points = append(points, DecorationPoint{"Cond", n.Decs.Cond}) - points = append(points, DecorationPoint{"Post", n.Decs.Post}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.FuncDecl: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"Func", n.Decs.Func}) - points = append(points, DecorationPoint{"Recv", n.Decs.Recv}) - points = append(points, DecorationPoint{"Name", n.Decs.Name}) - points = append(points, DecorationPoint{"TypeParams", n.Decs.TypeParams}) - points = append(points, DecorationPoint{"Params", n.Decs.Params}) - points = append(points, DecorationPoint{"Results", n.Decs.Results}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.FuncLit: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"Type", n.Decs.Type}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.FuncType: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"Func", n.Decs.Func}) - points = append(points, DecorationPoint{"TypeParams", n.Decs.TypeParams}) - points = append(points, DecorationPoint{"Params", n.Decs.Params}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.GenDecl: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"Tok", n.Decs.Tok}) - points = append(points, DecorationPoint{"Lparen", n.Decs.Lparen}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.GoStmt: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"Go", n.Decs.Go}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.Ident: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"X", n.Decs.X}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.IfStmt: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"If", n.Decs.If}) - points = append(points, DecorationPoint{"Init", n.Decs.Init}) - points = append(points, DecorationPoint{"Cond", n.Decs.Cond}) - points = append(points, DecorationPoint{"Else", n.Decs.Else}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.ImportSpec: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"Name", n.Decs.Name}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.IncDecStmt: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"X", n.Decs.X}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.IndexExpr: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"X", n.Decs.X}) - points = append(points, DecorationPoint{"Lbrack", n.Decs.Lbrack}) - points = append(points, DecorationPoint{"Index", n.Decs.Index}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.IndexListExpr: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"X", n.Decs.X}) - points = append(points, DecorationPoint{"Lbrack", n.Decs.Lbrack}) - points = append(points, DecorationPoint{"Indices", n.Decs.Indices}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.InterfaceType: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"Interface", n.Decs.Interface}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.KeyValueExpr: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"Key", n.Decs.Key}) - points = append(points, DecorationPoint{"Colon", n.Decs.Colon}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.LabeledStmt: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"Label", n.Decs.Label}) - points = append(points, DecorationPoint{"Colon", n.Decs.Colon}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.MapType: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"Map", n.Decs.Map}) - points = append(points, DecorationPoint{"Key", n.Decs.Key}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.Package: - case *dst.ParenExpr: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"Lparen", n.Decs.Lparen}) - points = append(points, DecorationPoint{"X", n.Decs.X}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.RangeStmt: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"For", n.Decs.For}) - points = append(points, DecorationPoint{"Key", n.Decs.Key}) - points = append(points, DecorationPoint{"Value", n.Decs.Value}) - points = append(points, DecorationPoint{"Range", n.Decs.Range}) - points = append(points, DecorationPoint{"X", n.Decs.X}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.ReturnStmt: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"Return", n.Decs.Return}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.SelectStmt: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"Select", n.Decs.Select}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.SelectorExpr: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"X", n.Decs.X}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.SendStmt: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"Chan", n.Decs.Chan}) - points = append(points, DecorationPoint{"Arrow", n.Decs.Arrow}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.SliceExpr: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"X", n.Decs.X}) - points = append(points, DecorationPoint{"Lbrack", n.Decs.Lbrack}) - points = append(points, DecorationPoint{"Low", n.Decs.Low}) - points = append(points, DecorationPoint{"High", n.Decs.High}) - points = append(points, DecorationPoint{"Max", n.Decs.Max}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.StarExpr: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"Star", n.Decs.Star}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.StructType: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"Struct", n.Decs.Struct}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.SwitchStmt: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"Switch", n.Decs.Switch}) - points = append(points, DecorationPoint{"Init", n.Decs.Init}) - points = append(points, DecorationPoint{"Tag", n.Decs.Tag}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.TypeAssertExpr: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"X", n.Decs.X}) - points = append(points, DecorationPoint{"Lparen", n.Decs.Lparen}) - points = append(points, DecorationPoint{"Type", n.Decs.Type}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.TypeSpec: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"Name", n.Decs.Name}) - points = append(points, DecorationPoint{"TypeParams", n.Decs.TypeParams}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.TypeSwitchStmt: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"Switch", n.Decs.Switch}) - points = append(points, DecorationPoint{"Init", n.Decs.Init}) - points = append(points, DecorationPoint{"Assign", n.Decs.Assign}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.UnaryExpr: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"Op", n.Decs.Op}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - case *dst.ValueSpec: - before = n.Decs.Before - after = n.Decs.After - points = append(points, DecorationPoint{"Start", n.Decs.Start}) - points = append(points, DecorationPoint{"Assign", n.Decs.Assign}) - points = append(points, DecorationPoint{"End", n.Decs.End}) - } - return -} diff --git a/vendor/github.com/dave/dst/dstutil/decorations.go b/vendor/github.com/dave/dst/dstutil/decorations.go deleted file mode 100644 index bb875fcd07..0000000000 --- a/vendor/github.com/dave/dst/dstutil/decorations.go +++ /dev/null @@ -1,14 +0,0 @@ -package dstutil - -import "github.com/dave/dst" - -// Decorations returns information about all the decoration attachment points associated with a node -func Decorations(n dst.Node) (before, after dst.SpaceType, info []DecorationPoint) { - return decorations(n) -} - -// DecorationPoint contains the name of the decoration attachment point and a list of decorations attached there -type DecorationPoint struct { - Name string - Decs []string -} diff --git a/vendor/github.com/dave/dst/dstutil/rewrite.go b/vendor/github.com/dave/dst/dstutil/rewrite.go deleted file mode 100644 index acb82c8a74..0000000000 --- a/vendor/github.com/dave/dst/dstutil/rewrite.go +++ /dev/null @@ -1,465 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package dstutil - -import ( - "fmt" - - "reflect" - "sort" - - "github.com/dave/dst" -) - -// An ApplyFunc is invoked by Apply for each node n, even if n is nil, -// before and/or after the node's children, using a Cursor describing -// the current node and providing operations on it. -// -// The return value of ApplyFunc controls the syntax tree traversal. -// See Apply for details. -type ApplyFunc func(*Cursor) bool - -// Apply traverses a syntax tree recursively, starting with root, -// and calling pre and post for each node as described below. -// Apply returns the syntax tree, possibly modified. -// -// If pre is not nil, it is called for each node before the node's -// children are traversed (pre-order). If pre returns false, no -// children are traversed, and post is not called for that node. -// -// If post is not nil, and a prior call of pre didn't return false, -// post is called for each node after its children are traversed -// (post-order). If post returns false, traversal is terminated and -// Apply returns immediately. -// -// Only fields that refer to AST nodes are considered children; -// i.e., token.Pos, Scopes, Objects, and fields of basic types -// (strings, etc.) are ignored. -// -// Children are traversed in the order in which they appear in the -// respective node's struct definition. A package's files are -// traversed in the filenames' alphabetical order. -// -func Apply(root dst.Node, pre, post ApplyFunc) (result dst.Node) { - parent := &struct{ dst.Node }{root} - defer func() { - if r := recover(); r != nil && r != abort { - panic(r) - } - result = parent.Node - }() - a := &application{pre: pre, post: post} - a.apply(parent, "Node", nil, root) - return -} - -var abort = new(int) // singleton, to signal termination of Apply - -// A Cursor describes a node encountered during Apply. -// Information about the node and its parent is available -// from the Node, Parent, Name, and Index methods. -// -// If p is a variable of type and value of the current parent node -// c.Parent(), and f is the field identifier with name c.Name(), -// the following invariants hold: -// -// p.f == c.Node() if c.Index() < 0 -// p.f[c.Index()] == c.Node() if c.Index() >= 0 -// -// The methods Replace, Delete, InsertBefore, and InsertAfter -// can be used to change the AST without disrupting Apply. -type Cursor struct { - parent dst.Node - name string - iter *iterator // valid if non-nil - node dst.Node -} - -// Node returns the current Node. -func (c *Cursor) Node() dst.Node { return c.node } - -// Parent returns the parent of the current Node. -func (c *Cursor) Parent() dst.Node { return c.parent } - -// Name returns the name of the parent Node field that contains the current Node. -// If the parent is a *dst.Package and the current Node is a *dst.File, Name returns -// the filename for the current Node. -func (c *Cursor) Name() string { return c.name } - -// Index reports the index >= 0 of the current Node in the slice of Nodes that -// contains it, or a value < 0 if the current Node is not part of a slice. -// The index of the current node changes if InsertBefore is called while -// processing the current node. -func (c *Cursor) Index() int { - if c.iter != nil { - return c.iter.index - } - return -1 -} - -// field returns the current node's parent field value. -func (c *Cursor) field() reflect.Value { - return reflect.Indirect(reflect.ValueOf(c.parent)).FieldByName(c.name) -} - -// Replace replaces the current Node with n. -// The replacement node is not walked by Apply. -func (c *Cursor) Replace(n dst.Node) { - if _, ok := c.node.(*dst.File); ok { - file, ok := n.(*dst.File) - if !ok { - panic("attempt to replace *dst.File with non-*dst.File") - } - c.parent.(*dst.Package).Files[c.name] = file - return - } - - v := c.field() - if i := c.Index(); i >= 0 { - v = v.Index(i) - } - v.Set(reflect.ValueOf(n)) -} - -// Delete deletes the current Node from its containing slice. -// If the current Node is not part of a slice, Delete panics. -// As a special case, if the current node is a package file, -// Delete removes it from the package's Files map. -func (c *Cursor) Delete() { - if _, ok := c.node.(*dst.File); ok { - delete(c.parent.(*dst.Package).Files, c.name) - return - } - - i := c.Index() - if i < 0 { - panic("Delete node not contained in slice") - } - v := c.field() - l := v.Len() - reflect.Copy(v.Slice(i, l), v.Slice(i+1, l)) - v.Index(l - 1).Set(reflect.Zero(v.Type().Elem())) - v.SetLen(l - 1) - c.iter.step-- -} - -// InsertAfter inserts n after the current Node in its containing slice. -// If the current Node is not part of a slice, InsertAfter panics. -// Apply does not walk n. -func (c *Cursor) InsertAfter(n dst.Node) { - i := c.Index() - if i < 0 { - panic("InsertAfter node not contained in slice") - } - v := c.field() - v.Set(reflect.Append(v, reflect.Zero(v.Type().Elem()))) - l := v.Len() - reflect.Copy(v.Slice(i+2, l), v.Slice(i+1, l)) - v.Index(i + 1).Set(reflect.ValueOf(n)) - c.iter.step++ -} - -// InsertBefore inserts n before the current Node in its containing slice. -// If the current Node is not part of a slice, InsertBefore panics. -// Apply will not walk n. -func (c *Cursor) InsertBefore(n dst.Node) { - i := c.Index() - if i < 0 { - panic("InsertBefore node not contained in slice") - } - v := c.field() - v.Set(reflect.Append(v, reflect.Zero(v.Type().Elem()))) - l := v.Len() - reflect.Copy(v.Slice(i+1, l), v.Slice(i, l)) - v.Index(i).Set(reflect.ValueOf(n)) - c.iter.index++ -} - -// application carries all the shared data so we can pass it around cheaply. -type application struct { - pre, post ApplyFunc - cursor Cursor - iter iterator -} - -func (a *application) apply(parent dst.Node, name string, iter *iterator, n dst.Node) { - // convert typed nil into untyped nil - if v := reflect.ValueOf(n); v.Kind() == reflect.Ptr && v.IsNil() { - n = nil - } - - // avoid heap-allocating a new cursor for each apply call; reuse a.cursor instead - saved := a.cursor - a.cursor.parent = parent - a.cursor.name = name - a.cursor.iter = iter - a.cursor.node = n - - if a.pre != nil && !a.pre(&a.cursor) { - a.cursor = saved - return - } - - // walk children - // (the order of the cases matches the order of the corresponding node types in go/ast) - switch n := n.(type) { - case nil: - // nothing to do - - case *dst.Field: - a.applyList(n, "Names") - a.apply(n, "Type", nil, n.Type) - a.apply(n, "Tag", nil, n.Tag) - - case *dst.FieldList: - a.applyList(n, "List") - - // Expressions - case *dst.BadExpr, *dst.Ident, *dst.BasicLit: - // nothing to do - - case *dst.Ellipsis: - a.apply(n, "Elt", nil, n.Elt) - - case *dst.FuncLit: - a.apply(n, "Type", nil, n.Type) - a.apply(n, "Body", nil, n.Body) - - case *dst.CompositeLit: - a.apply(n, "Type", nil, n.Type) - a.applyList(n, "Elts") - - case *dst.ParenExpr: - a.apply(n, "X", nil, n.X) - - case *dst.SelectorExpr: - a.apply(n, "X", nil, n.X) - a.apply(n, "Sel", nil, n.Sel) - - case *dst.IndexExpr: - a.apply(n, "X", nil, n.X) - a.apply(n, "Index", nil, n.Index) - - case *dst.IndexListExpr: - a.apply(n, "X", nil, n.X) - a.applyList(n, "Indices") - - case *dst.SliceExpr: - a.apply(n, "X", nil, n.X) - a.apply(n, "Low", nil, n.Low) - a.apply(n, "High", nil, n.High) - a.apply(n, "Max", nil, n.Max) - - case *dst.TypeAssertExpr: - a.apply(n, "X", nil, n.X) - a.apply(n, "Type", nil, n.Type) - - case *dst.CallExpr: - a.apply(n, "Fun", nil, n.Fun) - a.applyList(n, "Args") - - case *dst.StarExpr: - a.apply(n, "X", nil, n.X) - - case *dst.UnaryExpr: - a.apply(n, "X", nil, n.X) - - case *dst.BinaryExpr: - a.apply(n, "X", nil, n.X) - a.apply(n, "Y", nil, n.Y) - - case *dst.KeyValueExpr: - a.apply(n, "Key", nil, n.Key) - a.apply(n, "Value", nil, n.Value) - - // Types - case *dst.ArrayType: - a.apply(n, "Len", nil, n.Len) - a.apply(n, "Elt", nil, n.Elt) - - case *dst.StructType: - a.apply(n, "Fields", nil, n.Fields) - - case *dst.FuncType: - a.apply(n, "TypeParams", nil, n.TypeParams) - a.apply(n, "Params", nil, n.Params) - a.apply(n, "Results", nil, n.Results) - - case *dst.InterfaceType: - a.apply(n, "Methods", nil, n.Methods) - - case *dst.MapType: - a.apply(n, "Key", nil, n.Key) - a.apply(n, "Value", nil, n.Value) - - case *dst.ChanType: - a.apply(n, "Value", nil, n.Value) - - // Statements - case *dst.BadStmt: - // nothing to do - - case *dst.DeclStmt: - a.apply(n, "Decl", nil, n.Decl) - - case *dst.EmptyStmt: - // nothing to do - - case *dst.LabeledStmt: - a.apply(n, "Label", nil, n.Label) - a.apply(n, "Stmt", nil, n.Stmt) - - case *dst.ExprStmt: - a.apply(n, "X", nil, n.X) - - case *dst.SendStmt: - a.apply(n, "Chan", nil, n.Chan) - a.apply(n, "Value", nil, n.Value) - - case *dst.IncDecStmt: - a.apply(n, "X", nil, n.X) - - case *dst.AssignStmt: - a.applyList(n, "Lhs") - a.applyList(n, "Rhs") - - case *dst.GoStmt: - a.apply(n, "Call", nil, n.Call) - - case *dst.DeferStmt: - a.apply(n, "Call", nil, n.Call) - - case *dst.ReturnStmt: - a.applyList(n, "Results") - - case *dst.BranchStmt: - a.apply(n, "Label", nil, n.Label) - - case *dst.BlockStmt: - a.applyList(n, "List") - - case *dst.IfStmt: - a.apply(n, "Init", nil, n.Init) - a.apply(n, "Cond", nil, n.Cond) - a.apply(n, "Body", nil, n.Body) - a.apply(n, "Else", nil, n.Else) - - case *dst.CaseClause: - a.applyList(n, "List") - a.applyList(n, "Body") - - case *dst.SwitchStmt: - a.apply(n, "Init", nil, n.Init) - a.apply(n, "Tag", nil, n.Tag) - a.apply(n, "Body", nil, n.Body) - - case *dst.TypeSwitchStmt: - a.apply(n, "Init", nil, n.Init) - a.apply(n, "Assign", nil, n.Assign) - a.apply(n, "Body", nil, n.Body) - - case *dst.CommClause: - a.apply(n, "Comm", nil, n.Comm) - a.applyList(n, "Body") - - case *dst.SelectStmt: - a.apply(n, "Body", nil, n.Body) - - case *dst.ForStmt: - a.apply(n, "Init", nil, n.Init) - a.apply(n, "Cond", nil, n.Cond) - a.apply(n, "Post", nil, n.Post) - a.apply(n, "Body", nil, n.Body) - - case *dst.RangeStmt: - a.apply(n, "Key", nil, n.Key) - a.apply(n, "Value", nil, n.Value) - a.apply(n, "X", nil, n.X) - a.apply(n, "Body", nil, n.Body) - - // Declarations - case *dst.ImportSpec: - a.apply(n, "Name", nil, n.Name) - a.apply(n, "Path", nil, n.Path) - - case *dst.ValueSpec: - a.applyList(n, "Names") - a.apply(n, "Type", nil, n.Type) - a.applyList(n, "Values") - - case *dst.TypeSpec: - a.apply(n, "Name", nil, n.Name) - a.apply(n, "TypeParams", nil, n.TypeParams) - a.apply(n, "Type", nil, n.Type) - - case *dst.BadDecl: - // nothing to do - - case *dst.GenDecl: - a.applyList(n, "Specs") - - case *dst.FuncDecl: - a.apply(n, "Recv", nil, n.Recv) - a.apply(n, "Name", nil, n.Name) - a.apply(n, "Type", nil, n.Type) - a.apply(n, "Body", nil, n.Body) - - // Files and packages - case *dst.File: - a.apply(n, "Name", nil, n.Name) - a.applyList(n, "Decls") - // Don't walk n.Comments; they have either been walked already if - // they are Doc comments, or they can be easily walked explicitly. - - case *dst.Package: - // collect and sort names for reproducible behavior - var names []string - for name := range n.Files { - names = append(names, name) - } - sort.Strings(names) - for _, name := range names { - a.apply(n, name, nil, n.Files[name]) - } - - default: - panic(fmt.Sprintf("Apply: unexpected node type %T", n)) - } - - if a.post != nil && !a.post(&a.cursor) { - panic(abort) - } - - a.cursor = saved -} - -// An iterator controls iteration over a slice of nodes. -type iterator struct { - index, step int -} - -func (a *application) applyList(parent dst.Node, name string) { - // avoid heap-allocating a new iterator for each applyList call; reuse a.iter instead - saved := a.iter - a.iter.index = 0 - for { - // must reload parent.name each time, since cursor modifications might change it - v := reflect.Indirect(reflect.ValueOf(parent)).FieldByName(name) - if a.iter.index >= v.Len() { - break - } - - // element x may be nil in a bad AST - be cautious - var x dst.Node - if e := v.Index(a.iter.index); e.IsValid() { - x = e.Interface().(dst.Node) - } - - a.iter.step = 1 - a.apply(parent, name, &a.iter, x) - a.iter.index += a.iter.step - } - a.iter = saved -} diff --git a/vendor/github.com/dave/dst/dstutil/util.go b/vendor/github.com/dave/dst/dstutil/util.go deleted file mode 100644 index 984262278c..0000000000 --- a/vendor/github.com/dave/dst/dstutil/util.go +++ /dev/null @@ -1,14 +0,0 @@ -package dstutil - -import "github.com/dave/dst" - -// Unparen returns e with any enclosing parentheses stripped. -func Unparen(e dst.Expr) dst.Expr { - for { - p, ok := e.(*dst.ParenExpr) - if !ok { - return e - } - e = p.X - } -} diff --git a/vendor/github.com/dave/dst/print.go b/vendor/github.com/dave/dst/print.go deleted file mode 100644 index 0a4a35c41c..0000000000 --- a/vendor/github.com/dave/dst/print.go +++ /dev/null @@ -1,245 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file contains printing support for ASTs. - -package dst - -import ( - "fmt" - "io" - "os" - "reflect" -) - -// A FieldFilter may be provided to Fprint to control the output. -type FieldFilter func(name string, value reflect.Value) bool - -// NotNilFilter returns true for field values that are not nil; -// it returns false otherwise. -func NotNilFilter(_ string, v reflect.Value) bool { - switch v.Kind() { - case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: - return !v.IsNil() - } - return true -} - -// Fprint prints the (sub-)tree starting at AST node x to w. -// If fset != nil, position information is interpreted relative -// to that file set. Otherwise positions are printed as integer -// values (file set specific offsets). -// -// A non-nil FieldFilter f may be provided to control the output: -// struct fields for which f(fieldname, fieldvalue) is true are -// printed; all others are filtered from the output. Unexported -// struct fields are never printed. -func Fprint(w io.Writer, x interface{}, f FieldFilter) error { - return fprint(w, x, f) -} - -func fprint(w io.Writer, x interface{}, f FieldFilter) (err error) { - // setup printer - p := printer{ - output: w, - filter: f, - ptrmap: make(map[interface{}]int), - last: '\n', // force printing of line number on first line - } - - // install error handler - defer func() { - if e := recover(); e != nil { - err = e.(localError).err // re-panics if it's not a localError - } - }() - - // print x - if x == nil { - p.printf("nil\n") - return - } - p.print(reflect.ValueOf(x)) - p.printf("\n") - - return -} - -// Print prints x to standard output, skipping nil fields. -// Print(fset, x) is the same as Fprint(os.Stdout, fset, x, NotNilFilter). -func Print(x interface{}) error { - return Fprint(os.Stdout, x, NotNilFilter) -} - -type printer struct { - output io.Writer - filter FieldFilter - ptrmap map[interface{}]int // *T -> line number - indent int // current indentation level - last byte // the last byte processed by Write - line int // current line number -} - -var indent = []byte(". ") - -func (p *printer) Write(data []byte) (n int, err error) { - var m int - for i, b := range data { - // invariant: data[0:n] has been written - if b == '\n' { - m, err = p.output.Write(data[n : i+1]) - n += m - if err != nil { - return - } - p.line++ - } else if p.last == '\n' { - _, err = fmt.Fprintf(p.output, "%6d ", p.line) - if err != nil { - return - } - for j := p.indent; j > 0; j-- { - _, err = p.output.Write(indent) - if err != nil { - return - } - } - } - p.last = b - } - if len(data) > n { - m, err = p.output.Write(data[n:]) - n += m - } - return -} - -// localError wraps locally caught errors so we can distinguish -// them from genuine panics which we don't want to return as errors. -type localError struct { - err error -} - -// printf is a convenience wrapper that takes care of print errors. -func (p *printer) printf(format string, args ...interface{}) { - if _, err := fmt.Fprintf(p, format, args...); err != nil { - panic(localError{err}) - } -} - -// Implementation note: Print is written for AST nodes but could be -// used to print arbitrary data structures; such a version should -// probably be in a different package. -// -// Note: This code detects (some) cycles created via pointers but -// not cycles that are created via slices or maps containing the -// same slice or map. Code for general data structures probably -// should catch those as well. - -func (p *printer) print(x reflect.Value) { - if !NotNilFilter("", x) { - p.printf("nil") - return - } - - switch x.Kind() { - case reflect.Interface: - p.print(x.Elem()) - - case reflect.Map: - p.printf("%s (len = %d) {", x.Type(), x.Len()) - if x.Len() > 0 { - p.indent++ - p.printf("\n") - for _, key := range x.MapKeys() { - p.print(key) - p.printf(": ") - p.print(x.MapIndex(key)) - p.printf("\n") - } - p.indent-- - } - p.printf("}") - - case reflect.Ptr: - p.printf("*") - // type-checked ASTs may contain cycles - use ptrmap - // to keep track of objects that have been printed - // already and print the respective line number instead - ptr := x.Interface() - if line, exists := p.ptrmap[ptr]; exists { - p.printf("(obj @ %d)", line) - } else { - p.ptrmap[ptr] = p.line - p.print(x.Elem()) - } - - case reflect.Array: - p.printf("%s {", x.Type()) - if x.Len() > 0 { - p.indent++ - p.printf("\n") - for i, n := 0, x.Len(); i < n; i++ { - p.printf("%d: ", i) - p.print(x.Index(i)) - p.printf("\n") - } - p.indent-- - } - p.printf("}") - - case reflect.Slice: - if s, ok := x.Interface().([]byte); ok { - p.printf("%#q", s) - return - } - p.printf("%s (len = %d) {", x.Type(), x.Len()) - if x.Len() > 0 { - p.indent++ - p.printf("\n") - for i, n := 0, x.Len(); i < n; i++ { - p.printf("%d: ", i) - p.print(x.Index(i)) - p.printf("\n") - } - p.indent-- - } - p.printf("}") - - case reflect.Struct: - t := x.Type() - p.printf("%s {", t) - p.indent++ - first := true - for i, n := 0, t.NumField(); i < n; i++ { - // exclude non-exported fields because their - // values cannot be accessed via reflection - if name := t.Field(i).Name; IsExported(name) { - value := x.Field(i) - if p.filter == nil || p.filter(name, value) { - if first { - p.printf("\n") - first = false - } - p.printf("%s: ", name) - p.print(value) - p.printf("\n") - } - } - } - p.indent-- - p.printf("}") - - default: - v := x.Interface() - switch v := v.(type) { - case string: - // print strings in quotes - p.printf("%q", v) - return - } - // default - p.printf("%v", v) - } -} diff --git a/vendor/github.com/dave/dst/readme.go b/vendor/github.com/dave/dst/readme.go deleted file mode 100644 index 7bb53bdc1a..0000000000 --- a/vendor/github.com/dave/dst/readme.go +++ /dev/null @@ -1,4 +0,0 @@ -package dst - -//go:generate go get github.com/dave/rebecca/cmd/becca -//go:generate becca -package=github.com/dave/dst diff --git a/vendor/github.com/dave/dst/resolve.go b/vendor/github.com/dave/dst/resolve.go deleted file mode 100644 index e247bafbe2..0000000000 --- a/vendor/github.com/dave/dst/resolve.go +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file implements NewPackage. - -package dst - -import ( - "fmt" - "go/scanner" - "go/token" - "strconv" -) - -type pkgBuilder struct { - fset *token.FileSet - errors scanner.ErrorList -} - -func (p *pkgBuilder) error(msg string) { - p.errors.Add(p.fset.Position(token.NoPos), msg) -} - -func (p *pkgBuilder) errorf(format string, args ...interface{}) { - p.error(fmt.Sprintf(format, args...)) -} - -func (p *pkgBuilder) declare(scope, altScope *Scope, obj *Object) { - alt := scope.Insert(obj) - if alt == nil && altScope != nil { - // see if there is a conflicting declaration in altScope - alt = altScope.Lookup(obj.Name) - } - if alt != nil { - p.error(fmt.Sprintf("%s redeclared in this block", obj.Name)) - } -} - -func resolve(scope *Scope, ident *Ident) bool { - for ; scope != nil; scope = scope.Outer { - if obj := scope.Lookup(ident.Name); obj != nil { - ident.Obj = obj - return true - } - } - return false -} - -// An Importer resolves import paths to package Objects. -// The imports map records the packages already imported, -// indexed by package id (canonical import path). -// An Importer must determine the canonical import path and -// check the map to see if it is already present in the imports map. -// If so, the Importer can return the map entry. Otherwise, the -// Importer should load the package data for the given path into -// a new *Object (pkg), record pkg in the imports map, and then -// return pkg. -type Importer func(imports map[string]*Object, path string) (pkg *Object, err error) - -// NewPackage creates a new Package node from a set of File nodes. It resolves -// unresolved identifiers across files and updates each file's Unresolved list -// accordingly. If a non-nil importer and universe scope are provided, they are -// used to resolve identifiers not declared in any of the package files. Any -// remaining unresolved identifiers are reported as undeclared. If the files -// belong to different packages, one package name is selected and files with -// different package names are reported and then ignored. -// The result is a package node and a scanner.ErrorList if there were errors. -// -func NewPackage(fset *token.FileSet, files map[string]*File, importer Importer, universe *Scope) (*Package, error) { - var p pkgBuilder - p.fset = fset - - // complete package scope - pkgName := "" - pkgScope := NewScope(universe) - for _, file := range files { - // package names must match - switch name := file.Name.Name; { - case pkgName == "": - pkgName = name - case name != pkgName: - p.errorf("package %s; expected %s", name, pkgName) - continue // ignore this file - } - - // collect top-level file objects in package scope - for _, obj := range file.Scope.Objects { - p.declare(pkgScope, nil, obj) - } - } - - // package global mapping of imported package ids to package objects - imports := make(map[string]*Object) - - // complete file scopes with imports and resolve identifiers - for _, file := range files { - // ignore file if it belongs to a different package - // (error has already been reported) - if file.Name.Name != pkgName { - continue - } - - // build file scope by processing all imports - importErrors := false - fileScope := NewScope(pkgScope) - for _, spec := range file.Imports { - if importer == nil { - importErrors = true - continue - } - path, _ := strconv.Unquote(spec.Path.Value) - pkg, err := importer(imports, path) - if err != nil { - p.errorf("could not import %s (%s)", path, err) - importErrors = true - continue - } - // TODO(gri) If a local package name != "." is provided, - // global identifier resolution could proceed even if the - // import failed. Consider adjusting the logic here a bit. - - // local name overrides imported package name - name := pkg.Name - if spec.Name != nil { - name = spec.Name.Name - } - - // add import to file scope - if name == "." { - // merge imported scope with file scope - for _, obj := range pkg.Data.(*Scope).Objects { - p.declare(fileScope, pkgScope, obj) - } - } else if name != "_" { - // declare imported package object in file scope - // (do not re-use pkg in the file scope but create - // a new object instead; the Decl field is different - // for different files) - obj := NewObj(Pkg, name) - obj.Decl = spec - obj.Data = pkg.Data - p.declare(fileScope, pkgScope, obj) - } - } - - // resolve identifiers - if importErrors { - // don't use the universe scope without correct imports - // (objects in the universe may be shadowed by imports; - // with missing imports, identifiers might get resolved - // incorrectly to universe objects) - pkgScope.Outer = nil - } - i := 0 - for _, ident := range file.Unresolved { - if !resolve(fileScope, ident) { - p.errorf("undeclared name: %s", ident.Name) - file.Unresolved[i] = ident - i++ - } - - } - file.Unresolved = file.Unresolved[0:i] - pkgScope.Outer = universe // reset universe scope - } - - p.errors.Sort() - return &Package{pkgName, pkgScope, imports, files}, p.errors.Err() -} diff --git a/vendor/github.com/dave/dst/scope.go b/vendor/github.com/dave/dst/scope.go deleted file mode 100644 index c05ab7006c..0000000000 --- a/vendor/github.com/dave/dst/scope.go +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file implements scopes and the objects they contain. - -package dst - -import ( - "bytes" - "fmt" -) - -// A Scope maintains the set of named language entities declared -// in the scope and a link to the immediately surrounding (outer) -// scope. -// -type Scope struct { - Outer *Scope - Objects map[string]*Object -} - -// NewScope creates a new scope nested in the outer scope. -func NewScope(outer *Scope) *Scope { - const n = 4 // initial scope capacity - return &Scope{outer, make(map[string]*Object, n)} -} - -// Lookup returns the object with the given name if it is -// found in scope s, otherwise it returns nil. Outer scopes -// are ignored. -// -func (s *Scope) Lookup(name string) *Object { - return s.Objects[name] -} - -// Insert attempts to insert a named object obj into the scope s. -// If the scope already contains an object alt with the same name, -// Insert leaves the scope unchanged and returns alt. Otherwise -// it inserts obj and returns nil. -// -func (s *Scope) Insert(obj *Object) (alt *Object) { - if alt = s.Objects[obj.Name]; alt == nil { - s.Objects[obj.Name] = obj - } - return -} - -// Debugging support -func (s *Scope) String() string { - var buf bytes.Buffer - fmt.Fprintf(&buf, "scope %p {", s) - if s != nil && len(s.Objects) > 0 { - fmt.Fprintln(&buf) - for _, obj := range s.Objects { - fmt.Fprintf(&buf, "\t%s %s\n", obj.Kind, obj.Name) - } - } - fmt.Fprintf(&buf, "}\n") - return buf.String() -} - -// ---------------------------------------------------------------------------- -// Objects - -// An Object describes a named language entity such as a package, -// constant, type, variable, function (incl. methods), or label. -// -// The Data fields contains object-specific data: -// -// Kind Data type Data value -// Pkg *Scope package scope -// Con int iota for the respective declaration -// -type Object struct { - Kind ObjKind - Name string // declared name - Decl interface{} // corresponding Field, XxxSpec, FuncDecl, LabeledStmt, AssignStmt, Scope; or nil - Data interface{} // object-specific data; or nil - Type interface{} // placeholder for type information; may be nil -} - -// NewObj creates a new object of a given kind and name. -func NewObj(kind ObjKind, name string) *Object { - return &Object{Kind: kind, Name: name} -} - -// ObjKind describes what an object represents. -type ObjKind int - -// The list of possible Object kinds. -const ( - Bad ObjKind = iota // for error handling - Pkg // package - Con // constant - Typ // type - Var // variable - Fun // function or method - Lbl // label -) - -var objKindStrings = [...]string{ - Bad: "bad", - Pkg: "package", - Con: "const", - Typ: "type", - Var: "var", - Fun: "func", - Lbl: "label", -} - -func (kind ObjKind) String() string { return objKindStrings[kind] } diff --git a/vendor/github.com/dave/dst/walk.go b/vendor/github.com/dave/dst/walk.go deleted file mode 100644 index da7f97b29f..0000000000 --- a/vendor/github.com/dave/dst/walk.go +++ /dev/null @@ -1,354 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package dst - -import "fmt" - -// A Visitor's Visit method is invoked for each node encountered by Walk. -// If the result visitor w is not nil, Walk visits each of the children -// of node with the visitor w, followed by a call of w.Visit(nil). -type Visitor interface { - Visit(node Node) (w Visitor) -} - -// Helper functions for common node lists. They may be empty. - -func walkIdentList(v Visitor, list []*Ident) { - for _, x := range list { - Walk(v, x) - } -} - -func walkExprList(v Visitor, list []Expr) { - for _, x := range list { - Walk(v, x) - } -} - -func walkStmtList(v Visitor, list []Stmt) { - for _, x := range list { - Walk(v, x) - } -} - -func walkDeclList(v Visitor, list []Decl) { - for _, x := range list { - Walk(v, x) - } -} - -// TODO(gri): Investigate if providing a closure to Walk leads to -// simpler use (and may help eliminate Inspect in turn). - -// Walk traverses an AST in depth-first order: It starts by calling -// v.Visit(node); node must not be nil. If the visitor w returned by -// v.Visit(node) is not nil, Walk is invoked recursively with visitor -// w for each of the non-nil children of node, followed by a call of -// w.Visit(nil). -// -func Walk(v Visitor, node Node) { - if v = v.Visit(node); v == nil { - return - } - - // walk children - // (the order of the cases matches the order - // of the corresponding node types in ast.go) - switch n := node.(type) { - case *Field: - walkIdentList(v, n.Names) - Walk(v, n.Type) - if n.Tag != nil { - Walk(v, n.Tag) - } - - case *FieldList: - for _, f := range n.List { - Walk(v, f) - } - - // Expressions - case *BadExpr, *Ident, *BasicLit: - // nothing to do - - case *Ellipsis: - if n.Elt != nil { - Walk(v, n.Elt) - } - - case *FuncLit: - Walk(v, n.Type) - Walk(v, n.Body) - - case *CompositeLit: - if n.Type != nil { - Walk(v, n.Type) - } - walkExprList(v, n.Elts) - - case *ParenExpr: - Walk(v, n.X) - - case *SelectorExpr: - Walk(v, n.X) - Walk(v, n.Sel) - - case *IndexExpr: - Walk(v, n.X) - Walk(v, n.Index) - - case *IndexListExpr: - Walk(v, n.X) - walkExprList(v, n.Indices) - - case *SliceExpr: - Walk(v, n.X) - if n.Low != nil { - Walk(v, n.Low) - } - if n.High != nil { - Walk(v, n.High) - } - if n.Max != nil { - Walk(v, n.Max) - } - - case *TypeAssertExpr: - Walk(v, n.X) - if n.Type != nil { - Walk(v, n.Type) - } - - case *CallExpr: - Walk(v, n.Fun) - walkExprList(v, n.Args) - - case *StarExpr: - Walk(v, n.X) - - case *UnaryExpr: - Walk(v, n.X) - - case *BinaryExpr: - Walk(v, n.X) - Walk(v, n.Y) - - case *KeyValueExpr: - Walk(v, n.Key) - Walk(v, n.Value) - - // Types - case *ArrayType: - if n.Len != nil { - Walk(v, n.Len) - } - Walk(v, n.Elt) - - case *StructType: - Walk(v, n.Fields) - - case *FuncType: - if n.TypeParams != nil { - Walk(v, n.TypeParams) - } - if n.Params != nil { - Walk(v, n.Params) - } - if n.Results != nil { - Walk(v, n.Results) - } - - case *InterfaceType: - Walk(v, n.Methods) - - case *MapType: - Walk(v, n.Key) - Walk(v, n.Value) - - case *ChanType: - Walk(v, n.Value) - - // Statements - case *BadStmt: - // nothing to do - - case *DeclStmt: - Walk(v, n.Decl) - - case *EmptyStmt: - // nothing to do - - case *LabeledStmt: - Walk(v, n.Label) - Walk(v, n.Stmt) - - case *ExprStmt: - Walk(v, n.X) - - case *SendStmt: - Walk(v, n.Chan) - Walk(v, n.Value) - - case *IncDecStmt: - Walk(v, n.X) - - case *AssignStmt: - walkExprList(v, n.Lhs) - walkExprList(v, n.Rhs) - - case *GoStmt: - Walk(v, n.Call) - - case *DeferStmt: - Walk(v, n.Call) - - case *ReturnStmt: - walkExprList(v, n.Results) - - case *BranchStmt: - if n.Label != nil { - Walk(v, n.Label) - } - - case *BlockStmt: - walkStmtList(v, n.List) - - case *IfStmt: - if n.Init != nil { - Walk(v, n.Init) - } - Walk(v, n.Cond) - Walk(v, n.Body) - if n.Else != nil { - Walk(v, n.Else) - } - - case *CaseClause: - walkExprList(v, n.List) - walkStmtList(v, n.Body) - - case *SwitchStmt: - if n.Init != nil { - Walk(v, n.Init) - } - if n.Tag != nil { - Walk(v, n.Tag) - } - Walk(v, n.Body) - - case *TypeSwitchStmt: - if n.Init != nil { - Walk(v, n.Init) - } - Walk(v, n.Assign) - Walk(v, n.Body) - - case *CommClause: - if n.Comm != nil { - Walk(v, n.Comm) - } - walkStmtList(v, n.Body) - - case *SelectStmt: - Walk(v, n.Body) - - case *ForStmt: - if n.Init != nil { - Walk(v, n.Init) - } - if n.Cond != nil { - Walk(v, n.Cond) - } - if n.Post != nil { - Walk(v, n.Post) - } - Walk(v, n.Body) - - case *RangeStmt: - if n.Key != nil { - Walk(v, n.Key) - } - if n.Value != nil { - Walk(v, n.Value) - } - Walk(v, n.X) - Walk(v, n.Body) - - // Declarations - case *ImportSpec: - if n.Name != nil { - Walk(v, n.Name) - } - Walk(v, n.Path) - - case *ValueSpec: - walkIdentList(v, n.Names) - if n.Type != nil { - Walk(v, n.Type) - } - walkExprList(v, n.Values) - - case *TypeSpec: - Walk(v, n.Name) - if n.TypeParams != nil { - Walk(v, n.TypeParams) - } - Walk(v, n.Type) - - case *BadDecl: - // nothing to do - - case *GenDecl: - for _, s := range n.Specs { - Walk(v, s) - } - - case *FuncDecl: - if n.Recv != nil { - Walk(v, n.Recv) - } - Walk(v, n.Name) - Walk(v, n.Type) - if n.Body != nil { - Walk(v, n.Body) - } - - // Files and packages - case *File: - Walk(v, n.Name) - walkDeclList(v, n.Decls) - // don't walk n.Comments - they have been - // visited already through the individual - // nodes - - case *Package: - for _, f := range n.Files { - Walk(v, f) - } - - default: - panic(fmt.Sprintf("ast.Walk: unexpected node type %T", n)) - } - - v.Visit(nil) -} - -type inspector func(Node) bool - -func (f inspector) Visit(node Node) Visitor { - if f(node) { - return f - } - return nil -} - -// Inspect traverses an AST in depth-first order: It starts by calling -// f(node); node must not be nil. If f returns true, Inspect invokes f -// recursively for each of the non-nil children of node, followed by a -// call of f(nil). -// -func Inspect(node Node, f func(Node) bool) { - Walk(inspector(f), node) -} diff --git a/vendor/github.com/denis-tingaikin/go-header/.gitignore b/vendor/github.com/denis-tingaikin/go-header/.gitignore deleted file mode 100644 index 62c893550a..0000000000 --- a/vendor/github.com/denis-tingaikin/go-header/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.idea/ \ No newline at end of file diff --git a/vendor/github.com/denis-tingaikin/go-header/.go-header.yml b/vendor/github.com/denis-tingaikin/go-header/.go-header.yml deleted file mode 100644 index 3aa6d060db..0000000000 --- a/vendor/github.com/denis-tingaikin/go-header/.go-header.yml +++ /dev/null @@ -1,19 +0,0 @@ -values: - regexp: - copyright-holder: Copyright \(c\) {{mod-year-range}} Denis Tingaikin -template: | - {{copyright-holder}} - - SPDX-License-Identifier: Apache-2.0 - - 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. \ No newline at end of file diff --git a/vendor/github.com/denis-tingaikin/go-header/LICENSE b/vendor/github.com/denis-tingaikin/go-header/LICENSE deleted file mode 100644 index a2c9fda21f..0000000000 --- a/vendor/github.com/denis-tingaikin/go-header/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/vendor/github.com/denis-tingaikin/go-header/README.md b/vendor/github.com/denis-tingaikin/go-header/README.md deleted file mode 100644 index fcddad1fa1..0000000000 --- a/vendor/github.com/denis-tingaikin/go-header/README.md +++ /dev/null @@ -1,83 +0,0 @@ -# go-header -[![ci](https://github.com/denis-tingaikin/go-header/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/denis-tingaikin/go-header/actions/workflows/ci.yml) - -Go source code linter providing checks for license headers. - -## Installation - -For installation you can simply use `go get`. - -```bash -go install github.com/denis-tingaikin/go-header/cmd/go-header -``` - -## Configuration - -To configuring `.go-header.yml` linter you simply need to fill the next fields: - -```yaml ---- -template: # expects header template string. -template-path: # expects path to file with license header string. -values: # expects `const` or `regexp` node with values where values is a map string to string. - const: - key1: value1 # const value just checks equality. Note `key1` should be used in template string as {{ key1 }} or {{ KEY1 }}. - regexp: - key2: value2 # regexp value just checks regex match. The value should be a valid regexp pattern. Note `key2` should be used in template string as {{ key2 }} or {{ KEY2 }}. -``` - -Where `values` also can be used recursively. Example: - -```yaml -values: - const: - key1: "value" - regexp: - key2: "{{key1}} value1" # Reads as regex pattern "value value1" -``` - -## Bult-in values - -- **MOD-YEAR** - Returns the year when the file was modified. -- **MOD-YEAR-RANGE** - Returns a year-range where the range starts from the year when the file was modified. -- **YEAR** - Expects current year. Example header value: `2020`. Example of template using: `{{YEAR}}` or `{{year}}`. -- **YEAR-RANGE** - Expects any valid year interval or current year. Example header value: `2020` or `2000-2020`. Example of template using: `{{year-range}}` or `{{YEAR-RANGE}}`. - -## Execution - -`go-header` linter expects file paths on input. If you want to run `go-header` only on diff files, then you can use this command: - -```bash -go-header $(git diff --name-only | grep -E '.*\.go') -``` - -## Setup example - -### Step 1 - -Create configuration file `.go-header.yml` in the root of project. - -```yaml ---- -values: - const: - MY COMPANY: mycompany.com -template: | - {{ MY COMPANY }} - SPDX-License-Identifier: Apache-2.0 - - 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. -``` - -### Step 2 -You are ready! Execute `go-header ${PATH_TO_FILES}` from the root of the project. diff --git a/vendor/github.com/denis-tingaikin/go-header/analyzer.go b/vendor/github.com/denis-tingaikin/go-header/analyzer.go deleted file mode 100644 index c6b361f01d..0000000000 --- a/vendor/github.com/denis-tingaikin/go-header/analyzer.go +++ /dev/null @@ -1,256 +0,0 @@ -// Copyright (c) 2020-2024 Denis Tingaikin -// -// SPDX-License-Identifier: Apache-2.0 -// -// 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. - -package goheader - -import ( - "fmt" - "go/ast" - "os" - "os/exec" - "strings" - "time" -) - -type Target struct { - Path string - File *ast.File -} - -const iso = "2006-01-02 15:04:05 -0700" - -func (t *Target) ModTime() (time.Time, error) { - diff, err := exec.Command("git", "diff", t.Path).CombinedOutput() - if err == nil && len(diff) == 0 { - line, err := exec.Command("git", "log", "-1", "--pretty=format:%cd", "--date=iso", "--", t.Path).CombinedOutput() - if err == nil { - return time.Parse(iso, string(line)) - } - } - info, err := os.Stat(t.Path) - if err != nil { - return time.Time{}, err - } - return info.ModTime(), nil -} - -type Analyzer struct { - values map[string]Value - template string -} - -func (a *Analyzer) processPerTargetValues(target *Target) error { - a.values["mod-year"] = a.values["year"] - a.values["mod-year-range"] = a.values["year-range"] - if t, err := target.ModTime(); err == nil { - a.values["mod-year"] = &ConstValue{RawValue: fmt.Sprint(t.Year())} - a.values["mod-year-range"] = &RegexpValue{RawValue: `((20\d\d\-{{mod-year}})|({{mod-year}}))`} - } - - for _, v := range a.values { - if err := v.Calculate(a.values); err != nil { - return err - } - } - return nil -} - -func (a *Analyzer) Analyze(target *Target) (i Issue) { - if a.template == "" { - return NewIssue("Missed template for check") - } - - if err := a.processPerTargetValues(target); err != nil { - return &issue{msg: err.Error()} - } - - file := target.File - var header string - var offset = Location{ - Position: 1, - } - if len(file.Comments) > 0 && file.Comments[0].Pos() < file.Package { - if strings.HasPrefix(file.Comments[0].List[0].Text, "/*") { - header = (&ast.CommentGroup{List: []*ast.Comment{file.Comments[0].List[0]}}).Text() - } else { - header = file.Comments[0].Text() - offset.Position += 3 - } - } - defer func() { - if i == nil { - return - } - fix, ok := a.generateFix(i, file, header) - if !ok { - return - } - i = NewIssueWithFix(i.Message(), i.Location(), fix) - }() - header = strings.TrimSpace(header) - if header == "" { - return NewIssue("Missed header for check") - } - s := NewReader(header) - s.SetOffset(offset) - t := NewReader(a.template) - for !s.Done() && !t.Done() { - templateCh := t.Peek() - if templateCh == '{' { - name := a.readField(t) - if a.values[name] == nil { - return NewIssue(fmt.Sprintf("Template has unknown value: %v", name)) - } - if i := a.values[name].Read(s); i != nil { - return i - } - continue - } - sourceCh := s.Peek() - if sourceCh != templateCh { - l := s.Location() - notNextLine := func(r rune) bool { - return r != '\n' - } - actual := s.ReadWhile(notNextLine) - expected := t.ReadWhile(notNextLine) - return NewIssueWithLocation(fmt.Sprintf("Actual: %v\nExpected:%v", actual, expected), l) - } - s.Next() - t.Next() - } - if !s.Done() { - l := s.Location() - return NewIssueWithLocation(fmt.Sprintf("Unexpected string: %v", s.Finish()), l) - } - if !t.Done() { - l := s.Location() - return NewIssueWithLocation(fmt.Sprintf("Missed string: %v", t.Finish()), l) - } - return nil -} - -func (a *Analyzer) readField(reader *Reader) string { - _ = reader.Next() - _ = reader.Next() - - r := reader.ReadWhile(func(r rune) bool { - return r != '}' - }) - - _ = reader.Next() - _ = reader.Next() - - return strings.ToLower(strings.TrimSpace(r)) -} - -func New(options ...Option) *Analyzer { - a := &Analyzer{values: make(map[string]Value)} - for _, o := range options { - o.apply(a) - } - return a -} - -func (a *Analyzer) generateFix(i Issue, file *ast.File, header string) (Fix, bool) { - var expect string - t := NewReader(a.template) - for !t.Done() { - ch := t.Peek() - if ch == '{' { - f := a.values[a.readField(t)] - if f == nil { - return Fix{}, false - } - if f.Calculate(a.values) != nil { - return Fix{}, false - } - expect += f.Get() - continue - } - - expect += string(ch) - t.Next() - } - - fix := Fix{Expected: strings.Split(expect, "\n")} - if !(len(file.Comments) > 0 && file.Comments[0].Pos() < file.Package) { - for i := range fix.Expected { - fix.Expected[i] = "// " + fix.Expected[i] - } - return fix, true - } - - actual := file.Comments[0].List[0].Text - if !strings.HasPrefix(actual, "/*") { - for i := range fix.Expected { - fix.Expected[i] = "// " + fix.Expected[i] - } - for _, c := range file.Comments[0].List { - fix.Actual = append(fix.Actual, c.Text) - } - i = NewIssueWithFix(i.Message(), i.Location(), fix) - return fix, true - } - - gets := func(i int, end bool) string { - if i < 0 { - return header - } - if end { - return header[i+1:] - } - return header[:i] - } - start := strings.Index(actual, gets(strings.IndexByte(header, '\n'), false)) - if start < 0 { - return Fix{}, false // Should be impossible - } - nl := strings.LastIndexByte(actual[:start], '\n') - if nl >= 0 { - fix.Actual = strings.Split(actual[:nl], "\n") - fix.Expected = append(fix.Actual, fix.Expected...) - actual = actual[nl+1:] - start -= nl + 1 - } - - prefix := actual[:start] - if nl < 0 { - fix.Expected[0] = prefix + fix.Expected[0] - } else { - n := len(fix.Actual) - for i := range fix.Expected[n:] { - fix.Expected[n+i] = prefix + fix.Expected[n+i] - } - } - - last := gets(strings.LastIndexByte(header, '\n'), true) - end := strings.Index(actual, last) - if end < 0 { - return Fix{}, false // Should be impossible - } - - trailing := actual[end+len(last):] - if i := strings.IndexRune(trailing, '\n'); i < 0 { - fix.Expected[len(fix.Expected)-1] += trailing - } else { - fix.Expected[len(fix.Expected)-1] += trailing[:i] - fix.Expected = append(fix.Expected, strings.Split(trailing[i+1:], "\n")...) - } - - fix.Actual = append(fix.Actual, strings.Split(actual, "\n")...) - return fix, true -} diff --git a/vendor/github.com/denis-tingaikin/go-header/config.go b/vendor/github.com/denis-tingaikin/go-header/config.go deleted file mode 100644 index c881b63acd..0000000000 --- a/vendor/github.com/denis-tingaikin/go-header/config.go +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (c) 2020-2024 Denis Tingaikin -// -// SPDX-License-Identifier: Apache-2.0 -// -// 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. - -package goheader - -import ( - "errors" - "fmt" - "os" - "strings" - "time" - - "gopkg.in/yaml.v3" -) - -// Configuration represents go-header linter setup parameters -type Configuration struct { - // Values is map of values. Supports two types 'const` and `regexp`. Values can be used recursively. - Values map[string]map[string]string `yaml:"values"'` - // Template is template for checking. Uses values. - Template string `yaml:"template"` - // TemplatePath path to the template file. Useful if need to load the template from a specific file. - TemplatePath string `yaml:"template-path"` -} - -func (c *Configuration) builtInValues() map[string]Value { - var result = make(map[string]Value) - year := fmt.Sprint(time.Now().Year()) - result["year-range"] = &RegexpValue{ - RawValue: `((20\d\d\-{{YEAR}})|({{YEAR}}))`, - } - result["year"] = &ConstValue{ - RawValue: year, - } - return result -} - -func (c *Configuration) GetValues() (map[string]Value, error) { - var result = c.builtInValues() - createConst := func(raw string) Value { - return &ConstValue{RawValue: raw} - } - createRegexp := func(raw string) Value { - return &RegexpValue{RawValue: raw} - } - appendValues := func(m map[string]string, create func(string) Value) { - for k, v := range m { - key := strings.ToLower(k) - result[key] = create(v) - } - } - for k, v := range c.Values { - switch k { - case "const": - appendValues(v, createConst) - case "regexp": - appendValues(v, createRegexp) - default: - return nil, fmt.Errorf("unknown value type %v", k) - } - } - return result, nil -} - -func (c *Configuration) GetTemplate() (string, error) { - if c.Template != "" { - return c.Template, nil - } - if c.TemplatePath == "" { - return "", errors.New("template has not passed") - } - if b, err := os.ReadFile(c.TemplatePath); err != nil { - return "", err - } else { - c.Template = strings.TrimSpace(string(b)) - return c.Template, nil - } -} - -func (c *Configuration) Parse(p string) error { - b, err := os.ReadFile(p) - if err != nil { - return err - } - return yaml.Unmarshal(b, c) -} diff --git a/vendor/github.com/denis-tingaikin/go-header/issue.go b/vendor/github.com/denis-tingaikin/go-header/issue.go deleted file mode 100644 index e92279793c..0000000000 --- a/vendor/github.com/denis-tingaikin/go-header/issue.go +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (c) 2020-2024 Denis Tingaikin -// -// SPDX-License-Identifier: Apache-2.0 -// -// 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. - -package goheader - -type Issue interface { - Location() Location - Message() string - Fix() *Fix -} - -type issue struct { - msg string - location Location - fix *Fix -} - -type Fix struct { - Actual []string - Expected []string -} - -func (i *issue) Location() Location { - return i.location -} - -func (i *issue) Message() string { - return i.msg -} - -func (i *issue) Fix() *Fix { - return i.fix -} - -func NewIssueWithLocation(msg string, location Location) Issue { - return &issue{ - msg: msg, - location: location, - } -} - -func NewIssueWithFix(msg string, location Location, fix Fix) Issue { - return &issue{ - msg: msg, - location: location, - fix: &fix, - } -} - -func NewIssue(msg string) Issue { - return &issue{ - msg: msg, - } -} diff --git a/vendor/github.com/denis-tingaikin/go-header/location.go b/vendor/github.com/denis-tingaikin/go-header/location.go deleted file mode 100644 index 9f18394855..0000000000 --- a/vendor/github.com/denis-tingaikin/go-header/location.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2020-2022 Denis Tingaikin -// -// SPDX-License-Identifier: Apache-2.0 -// -// 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. - -package goheader - -import "fmt" - -type Location struct { - Line int - Position int -} - -func (l Location) String() string { - return fmt.Sprintf("%v:%v", l.Line+1, l.Position) -} - -func (l Location) Add(other Location) Location { - return Location{ - Line: l.Line + other.Line, - Position: l.Position + other.Position, - } -} diff --git a/vendor/github.com/denis-tingaikin/go-header/option.go b/vendor/github.com/denis-tingaikin/go-header/option.go deleted file mode 100644 index a9689e811e..0000000000 --- a/vendor/github.com/denis-tingaikin/go-header/option.go +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) 2020-2022 Denis Tingaikin -// -// SPDX-License-Identifier: Apache-2.0 -// -// 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. - -package goheader - -import "strings" - -type Option interface { - apply(*Analyzer) -} - -type applyAnalyzerOptionFunc func(*Analyzer) - -func (f applyAnalyzerOptionFunc) apply(a *Analyzer) { - f(a) -} - -func WithValues(values map[string]Value) Option { - return applyAnalyzerOptionFunc(func(a *Analyzer) { - a.values = make(map[string]Value) - for k, v := range values { - a.values[strings.ToLower(k)] = v - } - }) -} - -func WithTemplate(template string) Option { - return applyAnalyzerOptionFunc(func(a *Analyzer) { - a.template = template - }) -} diff --git a/vendor/github.com/denis-tingaikin/go-header/reader.go b/vendor/github.com/denis-tingaikin/go-header/reader.go deleted file mode 100644 index 9c9e88a177..0000000000 --- a/vendor/github.com/denis-tingaikin/go-header/reader.go +++ /dev/null @@ -1,116 +0,0 @@ -/* -Copyright (c) 2020-2022 Denis Tingaikin - -SPDX-License-Identifier: Apache-2.0 - -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. -*/ -package goheader - -func NewReader(text string) *Reader { - return &Reader{source: text} -} - -type Reader struct { - source string - position int - location Location - offset Location -} - -func (r *Reader) SetOffset(offset Location) { - r.offset = offset -} - -func (r *Reader) Position() int { - return r.position -} - -func (r *Reader) Location() Location { - return r.location.Add(r.offset) -} - -func (r *Reader) Peek() rune { - if r.Done() { - return rune(0) - } - return rune(r.source[r.position]) -} - -func (r *Reader) Done() bool { - return r.position >= len(r.source) -} - -func (r *Reader) Next() rune { - if r.Done() { - return rune(0) - } - reuslt := r.Peek() - if reuslt == '\n' { - r.location.Line++ - r.location.Position = 0 - } else { - r.location.Position++ - } - r.position++ - return reuslt -} - -func (r *Reader) Finish() string { - if r.position >= len(r.source) { - return "" - } - defer r.till() - return r.source[r.position:] -} - -func (r *Reader) SetPosition(pos int) { - if pos < 0 { - r.position = 0 - } - r.position = pos - r.location = r.calculateLocation() -} - -func (r *Reader) ReadWhile(match func(rune) bool) string { - if match == nil { - return "" - } - start := r.position - for !r.Done() && match(r.Peek()) { - r.Next() - } - return r.source[start:r.position] -} - -func (r *Reader) till() { - r.position = len(r.source) - r.location = r.calculateLocation() -} - -func (r *Reader) calculateLocation() Location { - min := len(r.source) - if min > r.position { - min = r.position - } - x, y := 0, 0 - for i := 0; i < min; i++ { - if r.source[i] == '\n' { - y++ - x = 0 - } else { - x++ - } - } - return Location{Line: y, Position: x} -} diff --git a/vendor/github.com/denis-tingaikin/go-header/value.go b/vendor/github.com/denis-tingaikin/go-header/value.go deleted file mode 100644 index 706a84f18a..0000000000 --- a/vendor/github.com/denis-tingaikin/go-header/value.go +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright (c) 2020-2024 Denis Tingaikin -// -// SPDX-License-Identifier: Apache-2.0 -// -// 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. - -package goheader - -import ( - "errors" - "fmt" - "regexp" - "strings" -) - -type Calculable interface { - Calculate(map[string]Value) error - Get() string - Raw() string -} - -type Value interface { - Calculable - Read(*Reader) Issue -} - -func calculateValue(calculable Calculable, values map[string]Value) (string, error) { - sb := strings.Builder{} - r := calculable.Raw() - var endIndex int - var startIndex int - for startIndex = strings.Index(r, "{{"); startIndex >= 0; startIndex = strings.Index(r, "{{") { - _, _ = sb.WriteString(r[:startIndex]) - endIndex = strings.Index(r, "}}") - if endIndex < 0 { - return "", errors.New("missed value ending") - } - subVal := strings.ToLower(strings.TrimSpace(r[startIndex+2 : endIndex])) - if val := values[subVal]; val != nil { - if err := val.Calculate(values); err != nil { - return "", err - } - sb.WriteString(val.Get()) - } else { - return "", fmt.Errorf("unknown value name %v", subVal) - } - endIndex += 2 - r = r[endIndex:] - } - _, _ = sb.WriteString(r) - return sb.String(), nil -} - -type ConstValue struct { - RawValue, Value string -} - -func (c *ConstValue) Calculate(values map[string]Value) error { - v, err := calculateValue(c, values) - if err != nil { - return err - } - c.Value = v - return nil -} - -func (c *ConstValue) Raw() string { - return c.RawValue -} - -func (c *ConstValue) Get() string { - if c.Value != "" { - return c.Value - } - return c.RawValue -} - -func (c *ConstValue) String() string { - return c.Get() -} - -func (c *ConstValue) Read(s *Reader) Issue { - l := s.Location() - p := s.Position() - for _, ch := range c.Get() { - if ch != s.Peek() { - s.SetPosition(p) - f := s.ReadWhile(func(r rune) bool { - return r != '\n' - }) - return NewIssueWithLocation(fmt.Sprintf("Expected:%v, Actual: %v", c.Get(), f), l) - } - s.Next() - } - return nil -} - -type RegexpValue struct { - RawValue, Value string -} - -func (r *RegexpValue) Calculate(values map[string]Value) error { - v, err := calculateValue(r, values) - if err != nil { - return err - } - r.Value = v - return nil -} - -func (r *RegexpValue) Raw() string { - return r.RawValue -} -func (r *RegexpValue) Get() string { - if r.Value != "" { - return r.Value - } - return r.RawValue -} - -func (r *RegexpValue) String() string { - return r.Get() -} - -func (r *RegexpValue) Read(s *Reader) Issue { - l := s.Location() - p := regexp.MustCompile(r.Get()) - pos := s.Position() - str := s.Finish() - s.SetPosition(pos) - indexes := p.FindAllIndex([]byte(str), -1) - if len(indexes) == 0 { - return NewIssueWithLocation(fmt.Sprintf("Pattern %v doesn't match.", p.String()), l) - } - s.SetPosition(pos + indexes[0][1]) - return nil -} - -var _ Value = &ConstValue{} -var _ Value = &RegexpValue{} diff --git a/vendor/github.com/dlclark/regexp2/.gitignore b/vendor/github.com/dlclark/regexp2/.gitignore deleted file mode 100644 index fb844c330c..0000000000 --- a/vendor/github.com/dlclark/regexp2/.gitignore +++ /dev/null @@ -1,27 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -*.test -*.prof -*.out - -.DS_Store diff --git a/vendor/github.com/dlclark/regexp2/.travis.yml b/vendor/github.com/dlclark/regexp2/.travis.yml deleted file mode 100644 index a2da6be473..0000000000 --- a/vendor/github.com/dlclark/regexp2/.travis.yml +++ /dev/null @@ -1,7 +0,0 @@ -language: go -arch: - - AMD64 - - ppc64le -go: - - 1.9 - - tip diff --git a/vendor/github.com/dlclark/regexp2/ATTRIB b/vendor/github.com/dlclark/regexp2/ATTRIB deleted file mode 100644 index cdf4560b9e..0000000000 --- a/vendor/github.com/dlclark/regexp2/ATTRIB +++ /dev/null @@ -1,133 +0,0 @@ -============ -These pieces of code were ported from dotnet/corefx: - -syntax/charclass.go (from RegexCharClass.cs): ported to use the built-in Go unicode classes. Canonicalize is - a direct port, but most of the other code required large changes because the C# implementation - used a string to represent the CharSet data structure and I cleaned that up in my implementation. - -syntax/code.go (from RegexCode.cs): ported literally with various cleanups and layout to make it more Go-ish. - -syntax/escape.go (from RegexParser.cs): ported Escape method and added some optimizations. Unescape is inspired by - the C# implementation but couldn't be directly ported because of the lack of do-while syntax in Go. - -syntax/parser.go (from RegexpParser.cs and RegexOptions.cs): ported parser struct and associated methods as - literally as possible. Several language differences required changes. E.g. lack pre/post-fix increments as - expressions, lack of do-while loops, lack of overloads, etc. - -syntax/prefix.go (from RegexFCD.cs and RegexBoyerMoore.cs): ported as literally as possible and added support - for unicode chars that are longer than the 16-bit char in C# for the 32-bit rune in Go. - -syntax/replacerdata.go (from RegexReplacement.cs): conceptually ported and re-organized to handle differences - in charclass implementation, and fix odd code layout between RegexParser.cs, Regex.cs, and RegexReplacement.cs. - -syntax/tree.go (from RegexTree.cs and RegexNode.cs): ported literally as possible. - -syntax/writer.go (from RegexWriter.cs): ported literally with minor changes to make it more Go-ish. - -match.go (from RegexMatch.cs): ported, simplified, and changed to handle Go's lack of inheritence. - -regexp.go (from Regex.cs and RegexOptions.cs): conceptually serves the same "starting point", but is simplified - and changed to handle differences in C# strings and Go strings/runes. - -replace.go (from RegexReplacement.cs): ported closely and then cleaned up to combine the MatchEvaluator and - simple string replace implementations. - -runner.go (from RegexRunner.cs): ported literally as possible. - -regexp_test.go (from CaptureTests.cs and GroupNamesAndNumbers.cs): conceptually ported, but the code was - manually structured like Go tests. - -replace_test.go (from RegexReplaceStringTest0.cs): conceptually ported - -rtl_test.go (from RightToLeft.cs): conceptually ported ---- -dotnet/corefx was released under this license: - -The MIT License (MIT) - -Copyright (c) Microsoft Corporation - -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. - -============ -These pieces of code are copied from the Go framework: - -- The overall directory structure of regexp2 was inspired by the Go runtime regexp package. -- The optimization in the escape method of syntax/escape.go is from the Go runtime QuoteMeta() func in regexp/regexp.go -- The method signatures in regexp.go are designed to match the Go framework regexp methods closely -- func regexp2.MustCompile and func quote are almost identifical to the regexp package versions -- BenchmarkMatch* and TestProgramTooLong* funcs in regexp_performance_test.go were copied from the framework - regexp/exec_test.go ---- -The Go framework was released under this license: - -Copyright (c) 2012 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -============ -Some test data were gathered from the Mono project. - -regexp_mono_test.go: ported from https://github.com/mono/mono/blob/master/mcs/class/System/Test/System.Text.RegularExpressions/PerlTrials.cs ---- -Mono tests released under this license: - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/vendor/github.com/dlclark/regexp2/LICENSE b/vendor/github.com/dlclark/regexp2/LICENSE deleted file mode 100644 index fe83dfdc92..0000000000 --- a/vendor/github.com/dlclark/regexp2/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) Doug Clark - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/dlclark/regexp2/README.md b/vendor/github.com/dlclark/regexp2/README.md deleted file mode 100644 index 9cbc1d8d0a..0000000000 --- a/vendor/github.com/dlclark/regexp2/README.md +++ /dev/null @@ -1,174 +0,0 @@ -# regexp2 - full featured regular expressions for Go -Regexp2 is a feature-rich RegExp engine for Go. It doesn't have constant time guarantees like the built-in `regexp` package, but it allows backtracking and is compatible with Perl5 and .NET. You'll likely be better off with the RE2 engine from the `regexp` package and should only use this if you need to write very complex patterns or require compatibility with .NET. - -## Basis of the engine -The engine is ported from the .NET framework's System.Text.RegularExpressions.Regex engine. That engine was open sourced in 2015 under the MIT license. There are some fundamental differences between .NET strings and Go strings that required a bit of borrowing from the Go framework regex engine as well. I cleaned up a couple of the dirtier bits during the port (regexcharclass.cs was terrible), but the parse tree, code emmitted, and therefore patterns matched should be identical. - -## New Code Generation -For extra performance use `regexp2` with [`regexp2cg`](https://github.com/dlclark/regexp2cg). It is a code generation utility for `regexp2` and you can likely improve your regexp runtime performance by 3-10x in hot code paths. As always you should benchmark your specifics to confirm the results. Give it a try! - -## Installing -This is a go-gettable library, so install is easy: - - go get github.com/dlclark/regexp2 - -To use the new Code Generation (while it's in beta) you'll need to use the `code_gen` branch: - - go get github.com/dlclark/regexp2@code_gen - -## Usage -Usage is similar to the Go `regexp` package. Just like in `regexp`, you start by converting a regex into a state machine via the `Compile` or `MustCompile` methods. They ultimately do the same thing, but `MustCompile` will panic if the regex is invalid. You can then use the provided `Regexp` struct to find matches repeatedly. A `Regexp` struct is safe to use across goroutines. - -```go -re := regexp2.MustCompile(`Your pattern`, 0) -if isMatch, _ := re.MatchString(`Something to match`); isMatch { - //do something -} -``` - -The only error that the `*Match*` methods *should* return is a Timeout if you set the `re.MatchTimeout` field. Any other error is a bug in the `regexp2` package. If you need more details about capture groups in a match then use the `FindStringMatch` method, like so: - -```go -if m, _ := re.FindStringMatch(`Something to match`); m != nil { - // the whole match is always group 0 - fmt.Printf("Group 0: %v\n", m.String()) - - // you can get all the groups too - gps := m.Groups() - - // a group can be captured multiple times, so each cap is separately addressable - fmt.Printf("Group 1, first capture", gps[1].Captures[0].String()) - fmt.Printf("Group 1, second capture", gps[1].Captures[1].String()) -} -``` - -Group 0 is embedded in the Match. Group 0 is an automatically-assigned group that encompasses the whole pattern. This means that `m.String()` is the same as `m.Group.String()` and `m.Groups()[0].String()` - -The __last__ capture is embedded in each group, so `g.String()` will return the same thing as `g.Capture.String()` and `g.Captures[len(g.Captures)-1].String()`. - -If you want to find multiple matches from a single input string you should use the `FindNextMatch` method. For example, to implement a function similar to `regexp.FindAllString`: - -```go -func regexp2FindAllString(re *regexp2.Regexp, s string) []string { - var matches []string - m, _ := re.FindStringMatch(s) - for m != nil { - matches = append(matches, m.String()) - m, _ = re.FindNextMatch(m) - } - return matches -} -``` - -`FindNextMatch` is optmized so that it re-uses the underlying string/rune slice. - -The internals of `regexp2` always operate on `[]rune` so `Index` and `Length` data in a `Match` always reference a position in `rune`s rather than `byte`s (even if the input was given as a string). This is a dramatic difference between `regexp` and `regexp2`. It's advisable to use the provided `String()` methods to avoid having to work with indices. - -## Compare `regexp` and `regexp2` -| Category | regexp | regexp2 | -| --- | --- | --- | -| Catastrophic backtracking possible | no, constant execution time guarantees | yes, if your pattern is at risk you can use the `re.MatchTimeout` field | -| Python-style capture groups `(?Pre)` | yes | no (yes in RE2 compat mode) | -| .NET-style capture groups `(?re)` or `(?'name're)` | no | yes | -| comments `(?#comment)` | no | yes | -| branch numbering reset `(?\|a\|b)` | no | no | -| possessive match `(?>re)` | no | yes | -| positive lookahead `(?=re)` | no | yes | -| negative lookahead `(?!re)` | no | yes | -| positive lookbehind `(?<=re)` | no | yes | -| negative lookbehind `(?re)`) -* change singleline behavior for `$` to only match end of string (like RE2) (see [#24](https://github.com/dlclark/regexp2/issues/24)) -* change the character classes `\d` `\s` and `\w` to match the same characters as RE2. NOTE: if you also use the `ECMAScript` option then this will change the `\s` character class to match ECMAScript instead of RE2. ECMAScript allows more whitespace characters in `\s` than RE2 (but still fewer than the the default behavior). -* allow character escape sequences to have defaults. For example, by default `\_` isn't a known character escape and will fail to compile, but in RE2 mode it will match the literal character `_` - -```go -re := regexp2.MustCompile(`Your RE2-compatible pattern`, regexp2.RE2) -if isMatch, _ := re.MatchString(`Something to match`); isMatch { - //do something -} -``` - -This feature is a work in progress and I'm open to ideas for more things to put here (maybe more relaxed character escaping rules?). - -## Catastrophic Backtracking and Timeouts - -`regexp2` supports features that can lead to catastrophic backtracking. -`Regexp.MatchTimeout` can be set to to limit the impact of such behavior; the -match will fail with an error after approximately MatchTimeout. No timeout -checks are done by default. - -Timeout checking is not free. The current timeout checking implementation starts -a background worker that updates a clock value approximately once every 100 -milliseconds. The matching code compares this value against the precomputed -deadline for the match. The performance impact is as follows. - -1. A match with a timeout runs almost as fast as a match without a timeout. -2. If any live matches have a timeout, there will be a background CPU load - (`~0.15%` currently on a modern machine). This load will remain constant - regardless of the number of matches done including matches done in parallel. -3. If no live matches are using a timeout, the background load will remain - until the longest deadline (match timeout + the time when the match started) - is reached. E.g., if you set a timeout of one minute the load will persist - for approximately a minute even if the match finishes quickly. - -See [PR #58](https://github.com/dlclark/regexp2/pull/58) for more details and -alternatives considered. - -## Goroutine leak error -If you're using a library during unit tests (e.g. https://github.com/uber-go/goleak) that validates all goroutines are exited then you'll likely get an error if you or any of your dependencies use regex's with a MatchTimeout. -To remedy the problem you'll need to tell the unit test to wait until the backgroup timeout goroutine is exited. - -```go -func TestSomething(t *testing.T) { - defer goleak.VerifyNone(t) - defer regexp2.StopTimeoutClock() - - // ... test -} - -//or - -func TestMain(m *testing.M) { - // setup - // ... - - // run - m.Run() - - //tear down - regexp2.StopTimeoutClock() - goleak.VerifyNone(t) -} -``` - -This will add ~100ms runtime to each test (or TestMain). If that's too much time you can set the clock cycle rate of the timeout goroutine in an init function in a test file. `regexp2.SetTimeoutCheckPeriod` isn't threadsafe so it must be setup before starting any regex's with Timeouts. - -```go -func init() { - //speed up testing by making the timeout clock 1ms - regexp2.SetTimeoutCheckPeriod(time.Millisecond) -} -``` - -## ECMAScript compatibility mode -In this mode the engine provides compatibility with the [regex engine](https://tc39.es/ecma262/multipage/text-processing.html#sec-regexp-regular-expression-objects) described in the ECMAScript specification. - -Additionally a Unicode mode is provided which allows parsing of `\u{CodePoint}` syntax that is only when both are provided. - -## Library features that I'm still working on -- Regex split - -## Potential bugs -I've run a battery of tests against regexp2 from various sources and found the debug output matches the .NET engine, but .NET and Go handle strings very differently. I've attempted to handle these differences, but most of my testing deals with basic ASCII with a little bit of multi-byte Unicode. There's a chance that there are bugs in the string handling related to character sets with supplementary Unicode chars. Right-to-Left support is coded, but not well tested either. - -## Find a bug? -I'm open to new issues and pull requests with tests if you find something odd! diff --git a/vendor/github.com/dlclark/regexp2/fastclock.go b/vendor/github.com/dlclark/regexp2/fastclock.go deleted file mode 100644 index d256e63c74..0000000000 --- a/vendor/github.com/dlclark/regexp2/fastclock.go +++ /dev/null @@ -1,141 +0,0 @@ -package regexp2 - -import ( - "sync" - "sync/atomic" - "time" -) - -// fasttime holds a time value (ticks since clock initialization) -type fasttime int64 - -// fastclock provides a fast clock implementation. -// -// A background goroutine periodically stores the current time -// into an atomic variable. -// -// A deadline can be quickly checked for expiration by comparing -// its value to the clock stored in the atomic variable. -// -// The goroutine automatically stops once clockEnd is reached. -// (clockEnd covers the largest deadline seen so far + some -// extra time). This ensures that if regexp2 with timeouts -// stops being used we will stop background work. -type fastclock struct { - // instances of atomicTime must be at the start of the struct (or at least 64-bit aligned) - // otherwise 32-bit architectures will panic - - current atomicTime // Current time (approximate) - clockEnd atomicTime // When clock updater is supposed to stop (>= any existing deadline) - - // current and clockEnd can be read via atomic loads. - // Reads and writes of other fields require mu to be held. - mu sync.Mutex - start time.Time // Time corresponding to fasttime(0) - running bool // Is a clock updater running? -} - -var fast fastclock - -// reached returns true if current time is at or past t. -func (t fasttime) reached() bool { - return fast.current.read() >= t -} - -// makeDeadline returns a time that is approximately time.Now().Add(d) -func makeDeadline(d time.Duration) fasttime { - // Increase the deadline since the clock we are reading may be - // just about to tick forwards. - end := fast.current.read() + durationToTicks(d+clockPeriod) - - // Start or extend clock if necessary. - if end > fast.clockEnd.read() { - // If time.Since(last use) > timeout, there's a chance that - // fast.current will no longer be updated, which can lead to - // incorrect 'end' calculations that can trigger a false timeout - fast.mu.Lock() - if !fast.running && !fast.start.IsZero() { - // update fast.current - fast.current.write(durationToTicks(time.Since(fast.start))) - // recalculate our end value - end = fast.current.read() + durationToTicks(d+clockPeriod) - } - fast.mu.Unlock() - extendClock(end) - } - - return end -} - -// extendClock ensures that clock is live and will run until at least end. -func extendClock(end fasttime) { - fast.mu.Lock() - defer fast.mu.Unlock() - - if fast.start.IsZero() { - fast.start = time.Now() - } - - // Extend the running time to cover end as well as a bit of slop. - if shutdown := end + durationToTicks(time.Second); shutdown > fast.clockEnd.read() { - fast.clockEnd.write(shutdown) - } - - // Start clock if necessary - if !fast.running { - fast.running = true - go runClock() - } -} - -// stop the timeout clock in the background -// should only used for unit tests to abandon the background goroutine -func stopClock() { - fast.mu.Lock() - if fast.running { - fast.clockEnd.write(fasttime(0)) - } - fast.mu.Unlock() - - // pause until not running - // get and release the lock - isRunning := true - for isRunning { - time.Sleep(clockPeriod / 2) - fast.mu.Lock() - isRunning = fast.running - fast.mu.Unlock() - } -} - -func durationToTicks(d time.Duration) fasttime { - // Downscale nanoseconds to approximately a millisecond so that we can avoid - // overflow even if the caller passes in math.MaxInt64. - return fasttime(d) >> 20 -} - -const DefaultClockPeriod = 100 * time.Millisecond - -// clockPeriod is the approximate interval between updates of approximateClock. -var clockPeriod = DefaultClockPeriod - -func runClock() { - fast.mu.Lock() - defer fast.mu.Unlock() - - for fast.current.read() <= fast.clockEnd.read() { - // Unlock while sleeping. - fast.mu.Unlock() - time.Sleep(clockPeriod) - fast.mu.Lock() - - newTime := durationToTicks(time.Since(fast.start)) - fast.current.write(newTime) - } - fast.running = false -} - -type atomicTime struct{ v int64 } // Should change to atomic.Int64 when we can use go 1.19 - -func (t *atomicTime) read() fasttime { return fasttime(atomic.LoadInt64(&t.v)) } -func (t *atomicTime) write(v fasttime) { atomic.StoreInt64(&t.v, int64(v)) } diff --git a/vendor/github.com/dlclark/regexp2/match.go b/vendor/github.com/dlclark/regexp2/match.go deleted file mode 100644 index 759cf8ccf4..0000000000 --- a/vendor/github.com/dlclark/regexp2/match.go +++ /dev/null @@ -1,349 +0,0 @@ -package regexp2 - -import ( - "bytes" - "fmt" -) - -// Match is a single regex result match that contains groups and repeated captures -// -// -Groups -// -Capture -type Match struct { - Group //embeded group 0 - - regex *Regexp - otherGroups []Group - - // input to the match - textpos int - textstart int - - capcount int - caps []int - sparseCaps map[int]int - - // output from the match - matches [][]int - matchcount []int - - // whether we've done any balancing with this match. If we - // have done balancing, we'll need to do extra work in Tidy(). - balancing bool -} - -// Group is an explicit or implit (group 0) matched group within the pattern -type Group struct { - Capture // the last capture of this group is embeded for ease of use - - Name string // group name - Captures []Capture // captures of this group -} - -// Capture is a single capture of text within the larger original string -type Capture struct { - // the original string - text []rune - // Index is the position in the underlying rune slice where the first character of - // captured substring was found. Even if you pass in a string this will be in Runes. - Index int - // Length is the number of runes in the captured substring. - Length int -} - -// String returns the captured text as a String -func (c *Capture) String() string { - return string(c.text[c.Index : c.Index+c.Length]) -} - -// Runes returns the captured text as a rune slice -func (c *Capture) Runes() []rune { - return c.text[c.Index : c.Index+c.Length] -} - -func newMatch(regex *Regexp, capcount int, text []rune, startpos int) *Match { - m := Match{ - regex: regex, - matchcount: make([]int, capcount), - matches: make([][]int, capcount), - textstart: startpos, - balancing: false, - } - m.Name = "0" - m.text = text - m.matches[0] = make([]int, 2) - return &m -} - -func newMatchSparse(regex *Regexp, caps map[int]int, capcount int, text []rune, startpos int) *Match { - m := newMatch(regex, capcount, text, startpos) - m.sparseCaps = caps - return m -} - -func (m *Match) reset(text []rune, textstart int) { - m.text = text - m.textstart = textstart - for i := 0; i < len(m.matchcount); i++ { - m.matchcount[i] = 0 - } - m.balancing = false -} - -func (m *Match) tidy(textpos int) { - - interval := m.matches[0] - m.Index = interval[0] - m.Length = interval[1] - m.textpos = textpos - m.capcount = m.matchcount[0] - //copy our root capture to the list - m.Group.Captures = []Capture{m.Group.Capture} - - if m.balancing { - // The idea here is that we want to compact all of our unbalanced captures. To do that we - // use j basically as a count of how many unbalanced captures we have at any given time - // (really j is an index, but j/2 is the count). First we skip past all of the real captures - // until we find a balance captures. Then we check each subsequent entry. If it's a balance - // capture (it's negative), we decrement j. If it's a real capture, we increment j and copy - // it down to the last free position. - for cap := 0; cap < len(m.matchcount); cap++ { - limit := m.matchcount[cap] * 2 - matcharray := m.matches[cap] - - var i, j int - - for i = 0; i < limit; i++ { - if matcharray[i] < 0 { - break - } - } - - for j = i; i < limit; i++ { - if matcharray[i] < 0 { - // skip negative values - j-- - } else { - // but if we find something positive (an actual capture), copy it back to the last - // unbalanced position. - if i != j { - matcharray[j] = matcharray[i] - } - j++ - } - } - - m.matchcount[cap] = j / 2 - } - - m.balancing = false - } -} - -// isMatched tells if a group was matched by capnum -func (m *Match) isMatched(cap int) bool { - return cap < len(m.matchcount) && m.matchcount[cap] > 0 && m.matches[cap][m.matchcount[cap]*2-1] != (-3+1) -} - -// matchIndex returns the index of the last specified matched group by capnum -func (m *Match) matchIndex(cap int) int { - i := m.matches[cap][m.matchcount[cap]*2-2] - if i >= 0 { - return i - } - - return m.matches[cap][-3-i] -} - -// matchLength returns the length of the last specified matched group by capnum -func (m *Match) matchLength(cap int) int { - i := m.matches[cap][m.matchcount[cap]*2-1] - if i >= 0 { - return i - } - - return m.matches[cap][-3-i] -} - -// Nonpublic builder: add a capture to the group specified by "c" -func (m *Match) addMatch(c, start, l int) { - - if m.matches[c] == nil { - m.matches[c] = make([]int, 2) - } - - capcount := m.matchcount[c] - - if capcount*2+2 > len(m.matches[c]) { - oldmatches := m.matches[c] - newmatches := make([]int, capcount*8) - copy(newmatches, oldmatches[:capcount*2]) - m.matches[c] = newmatches - } - - m.matches[c][capcount*2] = start - m.matches[c][capcount*2+1] = l - m.matchcount[c] = capcount + 1 - //log.Printf("addMatch: c=%v, i=%v, l=%v ... matches: %v", c, start, l, m.matches) -} - -// Nonpublic builder: Add a capture to balance the specified group. This is used by the -// -// balanced match construct. (?...) -// -// If there were no such thing as backtracking, this would be as simple as calling RemoveMatch(c). -// However, since we have backtracking, we need to keep track of everything. -func (m *Match) balanceMatch(c int) { - m.balancing = true - - // we'll look at the last capture first - capcount := m.matchcount[c] - target := capcount*2 - 2 - - // first see if it is negative, and therefore is a reference to the next available - // capture group for balancing. If it is, we'll reset target to point to that capture. - if m.matches[c][target] < 0 { - target = -3 - m.matches[c][target] - } - - // move back to the previous capture - target -= 2 - - // if the previous capture is a reference, just copy that reference to the end. Otherwise, point to it. - if target >= 0 && m.matches[c][target] < 0 { - m.addMatch(c, m.matches[c][target], m.matches[c][target+1]) - } else { - m.addMatch(c, -3-target, -4-target /* == -3 - (target + 1) */) - } -} - -// Nonpublic builder: removes a group match by capnum -func (m *Match) removeMatch(c int) { - m.matchcount[c]-- -} - -// GroupCount returns the number of groups this match has matched -func (m *Match) GroupCount() int { - return len(m.matchcount) -} - -// GroupByName returns a group based on the name of the group, or nil if the group name does not exist -func (m *Match) GroupByName(name string) *Group { - num := m.regex.GroupNumberFromName(name) - if num < 0 { - return nil - } - return m.GroupByNumber(num) -} - -// GroupByNumber returns a group based on the number of the group, or nil if the group number does not exist -func (m *Match) GroupByNumber(num int) *Group { - // check our sparse map - if m.sparseCaps != nil { - if newNum, ok := m.sparseCaps[num]; ok { - num = newNum - } - } - if num >= len(m.matchcount) || num < 0 { - return nil - } - - if num == 0 { - return &m.Group - } - - m.populateOtherGroups() - - return &m.otherGroups[num-1] -} - -// Groups returns all the capture groups, starting with group 0 (the full match) -func (m *Match) Groups() []Group { - m.populateOtherGroups() - g := make([]Group, len(m.otherGroups)+1) - g[0] = m.Group - copy(g[1:], m.otherGroups) - return g -} - -func (m *Match) populateOtherGroups() { - // Construct all the Group objects first time called - if m.otherGroups == nil { - m.otherGroups = make([]Group, len(m.matchcount)-1) - for i := 0; i < len(m.otherGroups); i++ { - m.otherGroups[i] = newGroup(m.regex.GroupNameFromNumber(i+1), m.text, m.matches[i+1], m.matchcount[i+1]) - } - } -} - -func (m *Match) groupValueAppendToBuf(groupnum int, buf *bytes.Buffer) { - c := m.matchcount[groupnum] - if c == 0 { - return - } - - matches := m.matches[groupnum] - - index := matches[(c-1)*2] - last := index + matches[(c*2)-1] - - for ; index < last; index++ { - buf.WriteRune(m.text[index]) - } -} - -func newGroup(name string, text []rune, caps []int, capcount int) Group { - g := Group{} - g.text = text - if capcount > 0 { - g.Index = caps[(capcount-1)*2] - g.Length = caps[(capcount*2)-1] - } - g.Name = name - g.Captures = make([]Capture, capcount) - for i := 0; i < capcount; i++ { - g.Captures[i] = Capture{ - text: text, - Index: caps[i*2], - Length: caps[i*2+1], - } - } - //log.Printf("newGroup! capcount %v, %+v", capcount, g) - - return g -} - -func (m *Match) dump() string { - buf := &bytes.Buffer{} - buf.WriteRune('\n') - if len(m.sparseCaps) > 0 { - for k, v := range m.sparseCaps { - fmt.Fprintf(buf, "Slot %v -> %v\n", k, v) - } - } - - for i, g := range m.Groups() { - fmt.Fprintf(buf, "Group %v (%v), %v caps:\n", i, g.Name, len(g.Captures)) - - for _, c := range g.Captures { - fmt.Fprintf(buf, " (%v, %v) %v\n", c.Index, c.Length, c.String()) - } - } - /* - for i := 0; i < len(m.matchcount); i++ { - fmt.Fprintf(buf, "\nGroup %v (%v):\n", i, m.regex.GroupNameFromNumber(i)) - - for j := 0; j < m.matchcount[i]; j++ { - text := "" - - if m.matches[i][j*2] >= 0 { - start := m.matches[i][j*2] - text = m.text[start : start+m.matches[i][j*2+1]] - } - - fmt.Fprintf(buf, " (%v, %v) %v\n", m.matches[i][j*2], m.matches[i][j*2+1], text) - } - } - */ - return buf.String() -} diff --git a/vendor/github.com/dlclark/regexp2/regexp.go b/vendor/github.com/dlclark/regexp2/regexp.go deleted file mode 100644 index a7ddbaf358..0000000000 --- a/vendor/github.com/dlclark/regexp2/regexp.go +++ /dev/null @@ -1,395 +0,0 @@ -/* -Package regexp2 is a regexp package that has an interface similar to Go's framework regexp engine but uses a -more feature full regex engine behind the scenes. - -It doesn't have constant time guarantees, but it allows backtracking and is compatible with Perl5 and .NET. -You'll likely be better off with the RE2 engine from the regexp package and should only use this if you -need to write very complex patterns or require compatibility with .NET. -*/ -package regexp2 - -import ( - "errors" - "math" - "strconv" - "sync" - "time" - - "github.com/dlclark/regexp2/syntax" -) - -var ( - // DefaultMatchTimeout used when running regexp matches -- "forever" - DefaultMatchTimeout = time.Duration(math.MaxInt64) - // DefaultUnmarshalOptions used when unmarshaling a regex from text - DefaultUnmarshalOptions = None -) - -// Regexp is the representation of a compiled regular expression. -// A Regexp is safe for concurrent use by multiple goroutines. -type Regexp struct { - // A match will time out if it takes (approximately) more than - // MatchTimeout. This is a safety check in case the match - // encounters catastrophic backtracking. The default value - // (DefaultMatchTimeout) causes all time out checking to be - // suppressed. - MatchTimeout time.Duration - - // read-only after Compile - pattern string // as passed to Compile - options RegexOptions // options - - caps map[int]int // capnum->index - capnames map[string]int //capture group name -> index - capslist []string //sorted list of capture group names - capsize int // size of the capture array - - code *syntax.Code // compiled program - - // cache of machines for running regexp - muRun *sync.Mutex - runner []*runner -} - -// Compile parses a regular expression and returns, if successful, -// a Regexp object that can be used to match against text. -func Compile(expr string, opt RegexOptions) (*Regexp, error) { - // parse it - tree, err := syntax.Parse(expr, syntax.RegexOptions(opt)) - if err != nil { - return nil, err - } - - // translate it to code - code, err := syntax.Write(tree) - if err != nil { - return nil, err - } - - // return it - return &Regexp{ - pattern: expr, - options: opt, - caps: code.Caps, - capnames: tree.Capnames, - capslist: tree.Caplist, - capsize: code.Capsize, - code: code, - MatchTimeout: DefaultMatchTimeout, - muRun: &sync.Mutex{}, - }, nil -} - -// MustCompile is like Compile but panics if the expression cannot be parsed. -// It simplifies safe initialization of global variables holding compiled regular -// expressions. -func MustCompile(str string, opt RegexOptions) *Regexp { - regexp, error := Compile(str, opt) - if error != nil { - panic(`regexp2: Compile(` + quote(str) + `): ` + error.Error()) - } - return regexp -} - -// Escape adds backslashes to any special characters in the input string -func Escape(input string) string { - return syntax.Escape(input) -} - -// Unescape removes any backslashes from previously-escaped special characters in the input string -func Unescape(input string) (string, error) { - return syntax.Unescape(input) -} - -// SetTimeoutPeriod is a debug function that sets the frequency of the timeout goroutine's sleep cycle. -// Defaults to 100ms. The only benefit of setting this lower is that the 1 background goroutine that manages -// timeouts may exit slightly sooner after all the timeouts have expired. See Github issue #63 -func SetTimeoutCheckPeriod(d time.Duration) { - clockPeriod = d -} - -// StopTimeoutClock should only be used in unit tests to prevent the timeout clock goroutine -// from appearing like a leaking goroutine -func StopTimeoutClock() { - stopClock() -} - -// String returns the source text used to compile the regular expression. -func (re *Regexp) String() string { - return re.pattern -} - -func quote(s string) string { - if strconv.CanBackquote(s) { - return "`" + s + "`" - } - return strconv.Quote(s) -} - -// RegexOptions impact the runtime and parsing behavior -// for each specific regex. They are setable in code as well -// as in the regex pattern itself. -type RegexOptions int32 - -const ( - None RegexOptions = 0x0 - IgnoreCase = 0x0001 // "i" - Multiline = 0x0002 // "m" - ExplicitCapture = 0x0004 // "n" - Compiled = 0x0008 // "c" - Singleline = 0x0010 // "s" - IgnorePatternWhitespace = 0x0020 // "x" - RightToLeft = 0x0040 // "r" - Debug = 0x0080 // "d" - ECMAScript = 0x0100 // "e" - RE2 = 0x0200 // RE2 (regexp package) compatibility mode - Unicode = 0x0400 // "u" -) - -func (re *Regexp) RightToLeft() bool { - return re.options&RightToLeft != 0 -} - -func (re *Regexp) Debug() bool { - return re.options&Debug != 0 -} - -// Replace searches the input string and replaces each match found with the replacement text. -// Count will limit the number of matches attempted and startAt will allow -// us to skip past possible matches at the start of the input (left or right depending on RightToLeft option). -// Set startAt and count to -1 to go through the whole string -func (re *Regexp) Replace(input, replacement string, startAt, count int) (string, error) { - data, err := syntax.NewReplacerData(replacement, re.caps, re.capsize, re.capnames, syntax.RegexOptions(re.options)) - if err != nil { - return "", err - } - //TODO: cache ReplacerData - - return replace(re, data, nil, input, startAt, count) -} - -// ReplaceFunc searches the input string and replaces each match found using the string from the evaluator -// Count will limit the number of matches attempted and startAt will allow -// us to skip past possible matches at the start of the input (left or right depending on RightToLeft option). -// Set startAt and count to -1 to go through the whole string. -func (re *Regexp) ReplaceFunc(input string, evaluator MatchEvaluator, startAt, count int) (string, error) { - return replace(re, nil, evaluator, input, startAt, count) -} - -// FindStringMatch searches the input string for a Regexp match -func (re *Regexp) FindStringMatch(s string) (*Match, error) { - // convert string to runes - return re.run(false, -1, getRunes(s)) -} - -// FindRunesMatch searches the input rune slice for a Regexp match -func (re *Regexp) FindRunesMatch(r []rune) (*Match, error) { - return re.run(false, -1, r) -} - -// FindStringMatchStartingAt searches the input string for a Regexp match starting at the startAt index -func (re *Regexp) FindStringMatchStartingAt(s string, startAt int) (*Match, error) { - if startAt > len(s) { - return nil, errors.New("startAt must be less than the length of the input string") - } - r, startAt := re.getRunesAndStart(s, startAt) - if startAt == -1 { - // we didn't find our start index in the string -- that's a problem - return nil, errors.New("startAt must align to the start of a valid rune in the input string") - } - - return re.run(false, startAt, r) -} - -// FindRunesMatchStartingAt searches the input rune slice for a Regexp match starting at the startAt index -func (re *Regexp) FindRunesMatchStartingAt(r []rune, startAt int) (*Match, error) { - return re.run(false, startAt, r) -} - -// FindNextMatch returns the next match in the same input string as the match parameter. -// Will return nil if there is no next match or if given a nil match. -func (re *Regexp) FindNextMatch(m *Match) (*Match, error) { - if m == nil { - return nil, nil - } - - // If previous match was empty, advance by one before matching to prevent - // infinite loop - startAt := m.textpos - if m.Length == 0 { - if m.textpos == len(m.text) { - return nil, nil - } - - if re.RightToLeft() { - startAt-- - } else { - startAt++ - } - } - return re.run(false, startAt, m.text) -} - -// MatchString return true if the string matches the regex -// error will be set if a timeout occurs -func (re *Regexp) MatchString(s string) (bool, error) { - m, err := re.run(true, -1, getRunes(s)) - if err != nil { - return false, err - } - return m != nil, nil -} - -func (re *Regexp) getRunesAndStart(s string, startAt int) ([]rune, int) { - if startAt < 0 { - if re.RightToLeft() { - r := getRunes(s) - return r, len(r) - } - return getRunes(s), 0 - } - ret := make([]rune, len(s)) - i := 0 - runeIdx := -1 - for strIdx, r := range s { - if strIdx == startAt { - runeIdx = i - } - ret[i] = r - i++ - } - if startAt == len(s) { - runeIdx = i - } - return ret[:i], runeIdx -} - -func getRunes(s string) []rune { - return []rune(s) -} - -// MatchRunes return true if the runes matches the regex -// error will be set if a timeout occurs -func (re *Regexp) MatchRunes(r []rune) (bool, error) { - m, err := re.run(true, -1, r) - if err != nil { - return false, err - } - return m != nil, nil -} - -// GetGroupNames Returns the set of strings used to name capturing groups in the expression. -func (re *Regexp) GetGroupNames() []string { - var result []string - - if re.capslist == nil { - result = make([]string, re.capsize) - - for i := 0; i < len(result); i++ { - result[i] = strconv.Itoa(i) - } - } else { - result = make([]string, len(re.capslist)) - copy(result, re.capslist) - } - - return result -} - -// GetGroupNumbers returns the integer group numbers corresponding to a group name. -func (re *Regexp) GetGroupNumbers() []int { - var result []int - - if re.caps == nil { - result = make([]int, re.capsize) - - for i := 0; i < len(result); i++ { - result[i] = i - } - } else { - result = make([]int, len(re.caps)) - - for k, v := range re.caps { - result[v] = k - } - } - - return result -} - -// GroupNameFromNumber retrieves a group name that corresponds to a group number. -// It will return "" for and unknown group number. Unnamed groups automatically -// receive a name that is the decimal string equivalent of its number. -func (re *Regexp) GroupNameFromNumber(i int) string { - if re.capslist == nil { - if i >= 0 && i < re.capsize { - return strconv.Itoa(i) - } - - return "" - } - - if re.caps != nil { - var ok bool - if i, ok = re.caps[i]; !ok { - return "" - } - } - - if i >= 0 && i < len(re.capslist) { - return re.capslist[i] - } - - return "" -} - -// GroupNumberFromName returns a group number that corresponds to a group name. -// Returns -1 if the name is not a recognized group name. Numbered groups -// automatically get a group name that is the decimal string equivalent of its number. -func (re *Regexp) GroupNumberFromName(name string) int { - // look up name if we have a hashtable of names - if re.capnames != nil { - if k, ok := re.capnames[name]; ok { - return k - } - - return -1 - } - - // convert to an int if it looks like a number - result := 0 - for i := 0; i < len(name); i++ { - ch := name[i] - - if ch > '9' || ch < '0' { - return -1 - } - - result *= 10 - result += int(ch - '0') - } - - // return int if it's in range - if result >= 0 && result < re.capsize { - return result - } - - return -1 -} - -// MarshalText implements [encoding.TextMarshaler]. The output -// matches that of calling the [Regexp.String] method. -func (re *Regexp) MarshalText() ([]byte, error) { - return []byte(re.String()), nil -} - -// UnmarshalText implements [encoding.TextUnmarshaler] by calling -// [Compile] on the encoded value. -func (re *Regexp) UnmarshalText(text []byte) error { - newRE, err := Compile(string(text), DefaultUnmarshalOptions) - if err != nil { - return err - } - *re = *newRE - return nil -} diff --git a/vendor/github.com/dlclark/regexp2/replace.go b/vendor/github.com/dlclark/regexp2/replace.go deleted file mode 100644 index 0376bd9d37..0000000000 --- a/vendor/github.com/dlclark/regexp2/replace.go +++ /dev/null @@ -1,177 +0,0 @@ -package regexp2 - -import ( - "bytes" - "errors" - - "github.com/dlclark/regexp2/syntax" -) - -const ( - replaceSpecials = 4 - replaceLeftPortion = -1 - replaceRightPortion = -2 - replaceLastGroup = -3 - replaceWholeString = -4 -) - -// MatchEvaluator is a function that takes a match and returns a replacement string to be used -type MatchEvaluator func(Match) string - -// Three very similar algorithms appear below: replace (pattern), -// replace (evaluator), and split. - -// Replace Replaces all occurrences of the regex in the string with the -// replacement pattern. -// -// Note that the special case of no matches is handled on its own: -// with no matches, the input string is returned unchanged. -// The right-to-left case is split out because StringBuilder -// doesn't handle right-to-left string building directly very well. -func replace(regex *Regexp, data *syntax.ReplacerData, evaluator MatchEvaluator, input string, startAt, count int) (string, error) { - if count < -1 { - return "", errors.New("Count too small") - } - if count == 0 { - return "", nil - } - - m, err := regex.FindStringMatchStartingAt(input, startAt) - - if err != nil { - return "", err - } - if m == nil { - return input, nil - } - - buf := &bytes.Buffer{} - text := m.text - - if !regex.RightToLeft() { - prevat := 0 - for m != nil { - if m.Index != prevat { - buf.WriteString(string(text[prevat:m.Index])) - } - prevat = m.Index + m.Length - if evaluator == nil { - replacementImpl(data, buf, m) - } else { - buf.WriteString(evaluator(*m)) - } - - count-- - if count == 0 { - break - } - m, err = regex.FindNextMatch(m) - if err != nil { - return "", nil - } - } - - if prevat < len(text) { - buf.WriteString(string(text[prevat:])) - } - } else { - prevat := len(text) - var al []string - - for m != nil { - if m.Index+m.Length != prevat { - al = append(al, string(text[m.Index+m.Length:prevat])) - } - prevat = m.Index - if evaluator == nil { - replacementImplRTL(data, &al, m) - } else { - al = append(al, evaluator(*m)) - } - - count-- - if count == 0 { - break - } - m, err = regex.FindNextMatch(m) - if err != nil { - return "", nil - } - } - - if prevat > 0 { - buf.WriteString(string(text[:prevat])) - } - - for i := len(al) - 1; i >= 0; i-- { - buf.WriteString(al[i]) - } - } - - return buf.String(), nil -} - -// Given a Match, emits into the StringBuilder the evaluated -// substitution pattern. -func replacementImpl(data *syntax.ReplacerData, buf *bytes.Buffer, m *Match) { - for _, r := range data.Rules { - - if r >= 0 { // string lookup - buf.WriteString(data.Strings[r]) - } else if r < -replaceSpecials { // group lookup - m.groupValueAppendToBuf(-replaceSpecials-1-r, buf) - } else { - switch -replaceSpecials - 1 - r { // special insertion patterns - case replaceLeftPortion: - for i := 0; i < m.Index; i++ { - buf.WriteRune(m.text[i]) - } - case replaceRightPortion: - for i := m.Index + m.Length; i < len(m.text); i++ { - buf.WriteRune(m.text[i]) - } - case replaceLastGroup: - m.groupValueAppendToBuf(m.GroupCount()-1, buf) - case replaceWholeString: - for i := 0; i < len(m.text); i++ { - buf.WriteRune(m.text[i]) - } - } - } - } -} - -func replacementImplRTL(data *syntax.ReplacerData, al *[]string, m *Match) { - l := *al - buf := &bytes.Buffer{} - - for _, r := range data.Rules { - buf.Reset() - if r >= 0 { // string lookup - l = append(l, data.Strings[r]) - } else if r < -replaceSpecials { // group lookup - m.groupValueAppendToBuf(-replaceSpecials-1-r, buf) - l = append(l, buf.String()) - } else { - switch -replaceSpecials - 1 - r { // special insertion patterns - case replaceLeftPortion: - for i := 0; i < m.Index; i++ { - buf.WriteRune(m.text[i]) - } - case replaceRightPortion: - for i := m.Index + m.Length; i < len(m.text); i++ { - buf.WriteRune(m.text[i]) - } - case replaceLastGroup: - m.groupValueAppendToBuf(m.GroupCount()-1, buf) - case replaceWholeString: - for i := 0; i < len(m.text); i++ { - buf.WriteRune(m.text[i]) - } - } - l = append(l, buf.String()) - } - } - - *al = l -} diff --git a/vendor/github.com/dlclark/regexp2/runner.go b/vendor/github.com/dlclark/regexp2/runner.go deleted file mode 100644 index 56759f1474..0000000000 --- a/vendor/github.com/dlclark/regexp2/runner.go +++ /dev/null @@ -1,1613 +0,0 @@ -package regexp2 - -import ( - "bytes" - "errors" - "fmt" - "math" - "strconv" - "strings" - "time" - "unicode" - - "github.com/dlclark/regexp2/syntax" -) - -type runner struct { - re *Regexp - code *syntax.Code - - runtextstart int // starting point for search - - runtext []rune // text to search - runtextpos int // current position in text - runtextend int - - // The backtracking stack. Opcodes use this to store data regarding - // what they have matched and where to backtrack to. Each "frame" on - // the stack takes the form of [CodePosition Data1 Data2...], where - // CodePosition is the position of the current opcode and - // the data values are all optional. The CodePosition can be negative, and - // these values (also called "back2") are used by the BranchMark family of opcodes - // to indicate whether they are backtracking after a successful or failed - // match. - // When we backtrack, we pop the CodePosition off the stack, set the current - // instruction pointer to that code position, and mark the opcode - // with a backtracking flag ("Back"). Each opcode then knows how to - // handle its own data. - runtrack []int - runtrackpos int - - // This stack is used to track text positions across different opcodes. - // For example, in /(a*b)+/, the parentheses result in a SetMark/CaptureMark - // pair. SetMark records the text position before we match a*b. Then - // CaptureMark uses that position to figure out where the capture starts. - // Opcodes which push onto this stack are always paired with other opcodes - // which will pop the value from it later. A successful match should mean - // that this stack is empty. - runstack []int - runstackpos int - - // The crawl stack is used to keep track of captures. Every time a group - // has a capture, we push its group number onto the runcrawl stack. In - // the case of a balanced match, we push BOTH groups onto the stack. - runcrawl []int - runcrawlpos int - - runtrackcount int // count of states that may do backtracking - - runmatch *Match // result object - - ignoreTimeout bool - timeout time.Duration // timeout in milliseconds (needed for actual) - deadline fasttime - - operator syntax.InstOp - codepos int - rightToLeft bool - caseInsensitive bool -} - -// run searches for matches and can continue from the previous match -// -// quick is usually false, but can be true to not return matches, just put it in caches -// textstart is -1 to start at the "beginning" (depending on Right-To-Left), otherwise an index in input -// input is the string to search for our regex pattern -func (re *Regexp) run(quick bool, textstart int, input []rune) (*Match, error) { - - // get a cached runner - runner := re.getRunner() - defer re.putRunner(runner) - - if textstart < 0 { - if re.RightToLeft() { - textstart = len(input) - } else { - textstart = 0 - } - } - - return runner.scan(input, textstart, quick, re.MatchTimeout) -} - -// Scans the string to find the first match. Uses the Match object -// both to feed text in and as a place to store matches that come out. -// -// All the action is in the Go() method. Our -// responsibility is to load up the class members before -// calling Go. -// -// The optimizer can compute a set of candidate starting characters, -// and we could use a separate method Skip() that will quickly scan past -// any characters that we know can't match. -func (r *runner) scan(rt []rune, textstart int, quick bool, timeout time.Duration) (*Match, error) { - r.timeout = timeout - r.ignoreTimeout = (time.Duration(math.MaxInt64) == timeout) - r.runtextstart = textstart - r.runtext = rt - r.runtextend = len(rt) - - stoppos := r.runtextend - bump := 1 - - if r.re.RightToLeft() { - bump = -1 - stoppos = 0 - } - - r.runtextpos = textstart - initted := false - - r.startTimeoutWatch() - for { - if r.re.Debug() { - //fmt.Printf("\nSearch content: %v\n", string(r.runtext)) - fmt.Printf("\nSearch range: from 0 to %v\n", r.runtextend) - fmt.Printf("Firstchar search starting at %v stopping at %v\n", r.runtextpos, stoppos) - } - - if r.findFirstChar() { - if err := r.checkTimeout(); err != nil { - return nil, err - } - - if !initted { - r.initMatch() - initted = true - } - - if r.re.Debug() { - fmt.Printf("Executing engine starting at %v\n\n", r.runtextpos) - } - - if err := r.execute(); err != nil { - return nil, err - } - - if r.runmatch.matchcount[0] > 0 { - // We'll return a match even if it touches a previous empty match - return r.tidyMatch(quick), nil - } - - // reset state for another go - r.runtrackpos = len(r.runtrack) - r.runstackpos = len(r.runstack) - r.runcrawlpos = len(r.runcrawl) - } - - // failure! - - if r.runtextpos == stoppos { - r.tidyMatch(true) - return nil, nil - } - - // Recognize leading []* and various anchors, and bump on failure accordingly - - // r.bump by one and start again - - r.runtextpos += bump - } - // We never get here -} - -func (r *runner) execute() error { - - r.goTo(0) - - for { - - if r.re.Debug() { - r.dumpState() - } - - if err := r.checkTimeout(); err != nil { - return err - } - - switch r.operator { - case syntax.Stop: - return nil - - case syntax.Nothing: - break - - case syntax.Goto: - r.goTo(r.operand(0)) - continue - - case syntax.Testref: - if !r.runmatch.isMatched(r.operand(0)) { - break - } - r.advance(1) - continue - - case syntax.Lazybranch: - r.trackPush1(r.textPos()) - r.advance(1) - continue - - case syntax.Lazybranch | syntax.Back: - r.trackPop() - r.textto(r.trackPeek()) - r.goTo(r.operand(0)) - continue - - case syntax.Setmark: - r.stackPush(r.textPos()) - r.trackPush() - r.advance(0) - continue - - case syntax.Nullmark: - r.stackPush(-1) - r.trackPush() - r.advance(0) - continue - - case syntax.Setmark | syntax.Back, syntax.Nullmark | syntax.Back: - r.stackPop() - break - - case syntax.Getmark: - r.stackPop() - r.trackPush1(r.stackPeek()) - r.textto(r.stackPeek()) - r.advance(0) - continue - - case syntax.Getmark | syntax.Back: - r.trackPop() - r.stackPush(r.trackPeek()) - break - - case syntax.Capturemark: - if r.operand(1) != -1 && !r.runmatch.isMatched(r.operand(1)) { - break - } - r.stackPop() - if r.operand(1) != -1 { - r.transferCapture(r.operand(0), r.operand(1), r.stackPeek(), r.textPos()) - } else { - r.capture(r.operand(0), r.stackPeek(), r.textPos()) - } - r.trackPush1(r.stackPeek()) - - r.advance(2) - - continue - - case syntax.Capturemark | syntax.Back: - r.trackPop() - r.stackPush(r.trackPeek()) - r.uncapture() - if r.operand(0) != -1 && r.operand(1) != -1 { - r.uncapture() - } - - break - - case syntax.Branchmark: - r.stackPop() - - matched := r.textPos() - r.stackPeek() - - if matched != 0 { // Nonempty match -> loop now - r.trackPush2(r.stackPeek(), r.textPos()) // Save old mark, textpos - r.stackPush(r.textPos()) // Make new mark - r.goTo(r.operand(0)) // Loop - } else { // Empty match -> straight now - r.trackPushNeg1(r.stackPeek()) // Save old mark - r.advance(1) // Straight - } - continue - - case syntax.Branchmark | syntax.Back: - r.trackPopN(2) - r.stackPop() - r.textto(r.trackPeekN(1)) // Recall position - r.trackPushNeg1(r.trackPeek()) // Save old mark - r.advance(1) // Straight - continue - - case syntax.Branchmark | syntax.Back2: - r.trackPop() - r.stackPush(r.trackPeek()) // Recall old mark - break // Backtrack - - case syntax.Lazybranchmark: - { - // We hit this the first time through a lazy loop and after each - // successful match of the inner expression. It simply continues - // on and doesn't loop. - r.stackPop() - - oldMarkPos := r.stackPeek() - - if r.textPos() != oldMarkPos { // Nonempty match -> try to loop again by going to 'back' state - if oldMarkPos != -1 { - r.trackPush2(oldMarkPos, r.textPos()) // Save old mark, textpos - } else { - r.trackPush2(r.textPos(), r.textPos()) - } - } else { - // The inner expression found an empty match, so we'll go directly to 'back2' if we - // backtrack. In this case, we need to push something on the stack, since back2 pops. - // However, in the case of ()+? or similar, this empty match may be legitimate, so push the text - // position associated with that empty match. - r.stackPush(oldMarkPos) - - r.trackPushNeg1(r.stackPeek()) // Save old mark - } - r.advance(1) - continue - } - - case syntax.Lazybranchmark | syntax.Back: - - // After the first time, Lazybranchmark | syntax.Back occurs - // with each iteration of the loop, and therefore with every attempted - // match of the inner expression. We'll try to match the inner expression, - // then go back to Lazybranchmark if successful. If the inner expression - // fails, we go to Lazybranchmark | syntax.Back2 - - r.trackPopN(2) - pos := r.trackPeekN(1) - r.trackPushNeg1(r.trackPeek()) // Save old mark - r.stackPush(pos) // Make new mark - r.textto(pos) // Recall position - r.goTo(r.operand(0)) // Loop - continue - - case syntax.Lazybranchmark | syntax.Back2: - // The lazy loop has failed. We'll do a true backtrack and - // start over before the lazy loop. - r.stackPop() - r.trackPop() - r.stackPush(r.trackPeek()) // Recall old mark - break - - case syntax.Setcount: - r.stackPush2(r.textPos(), r.operand(0)) - r.trackPush() - r.advance(1) - continue - - case syntax.Nullcount: - r.stackPush2(-1, r.operand(0)) - r.trackPush() - r.advance(1) - continue - - case syntax.Setcount | syntax.Back: - r.stackPopN(2) - break - - case syntax.Nullcount | syntax.Back: - r.stackPopN(2) - break - - case syntax.Branchcount: - // r.stackPush: - // 0: Mark - // 1: Count - - r.stackPopN(2) - mark := r.stackPeek() - count := r.stackPeekN(1) - matched := r.textPos() - mark - - if count >= r.operand(1) || (matched == 0 && count >= 0) { // Max loops or empty match -> straight now - r.trackPushNeg2(mark, count) // Save old mark, count - r.advance(2) // Straight - } else { // Nonempty match -> count+loop now - r.trackPush1(mark) // remember mark - r.stackPush2(r.textPos(), count+1) // Make new mark, incr count - r.goTo(r.operand(0)) // Loop - } - continue - - case syntax.Branchcount | syntax.Back: - // r.trackPush: - // 0: Previous mark - // r.stackPush: - // 0: Mark (= current pos, discarded) - // 1: Count - r.trackPop() - r.stackPopN(2) - if r.stackPeekN(1) > 0 { // Positive -> can go straight - r.textto(r.stackPeek()) // Zap to mark - r.trackPushNeg2(r.trackPeek(), r.stackPeekN(1)-1) // Save old mark, old count - r.advance(2) // Straight - continue - } - r.stackPush2(r.trackPeek(), r.stackPeekN(1)-1) // recall old mark, old count - break - - case syntax.Branchcount | syntax.Back2: - // r.trackPush: - // 0: Previous mark - // 1: Previous count - r.trackPopN(2) - r.stackPush2(r.trackPeek(), r.trackPeekN(1)) // Recall old mark, old count - break // Backtrack - - case syntax.Lazybranchcount: - // r.stackPush: - // 0: Mark - // 1: Count - - r.stackPopN(2) - mark := r.stackPeek() - count := r.stackPeekN(1) - - if count < 0 { // Negative count -> loop now - r.trackPushNeg1(mark) // Save old mark - r.stackPush2(r.textPos(), count+1) // Make new mark, incr count - r.goTo(r.operand(0)) // Loop - } else { // Nonneg count -> straight now - r.trackPush3(mark, count, r.textPos()) // Save mark, count, position - r.advance(2) // Straight - } - continue - - case syntax.Lazybranchcount | syntax.Back: - // r.trackPush: - // 0: Mark - // 1: Count - // 2: r.textPos - - r.trackPopN(3) - mark := r.trackPeek() - textpos := r.trackPeekN(2) - - if r.trackPeekN(1) < r.operand(1) && textpos != mark { // Under limit and not empty match -> loop - r.textto(textpos) // Recall position - r.stackPush2(textpos, r.trackPeekN(1)+1) // Make new mark, incr count - r.trackPushNeg1(mark) // Save old mark - r.goTo(r.operand(0)) // Loop - continue - } else { // Max loops or empty match -> backtrack - r.stackPush2(r.trackPeek(), r.trackPeekN(1)) // Recall old mark, count - break // backtrack - } - - case syntax.Lazybranchcount | syntax.Back2: - // r.trackPush: - // 0: Previous mark - // r.stackPush: - // 0: Mark (== current pos, discarded) - // 1: Count - r.trackPop() - r.stackPopN(2) - r.stackPush2(r.trackPeek(), r.stackPeekN(1)-1) // Recall old mark, count - break // Backtrack - - case syntax.Setjump: - r.stackPush2(r.trackpos(), r.crawlpos()) - r.trackPush() - r.advance(0) - continue - - case syntax.Setjump | syntax.Back: - r.stackPopN(2) - break - - case syntax.Backjump: - // r.stackPush: - // 0: Saved trackpos - // 1: r.crawlpos - r.stackPopN(2) - r.trackto(r.stackPeek()) - - for r.crawlpos() != r.stackPeekN(1) { - r.uncapture() - } - - break - - case syntax.Forejump: - // r.stackPush: - // 0: Saved trackpos - // 1: r.crawlpos - r.stackPopN(2) - r.trackto(r.stackPeek()) - r.trackPush1(r.stackPeekN(1)) - r.advance(0) - continue - - case syntax.Forejump | syntax.Back: - // r.trackPush: - // 0: r.crawlpos - r.trackPop() - - for r.crawlpos() != r.trackPeek() { - r.uncapture() - } - - break - - case syntax.Bol: - if r.leftchars() > 0 && r.charAt(r.textPos()-1) != '\n' { - break - } - r.advance(0) - continue - - case syntax.Eol: - if r.rightchars() > 0 && r.charAt(r.textPos()) != '\n' { - break - } - r.advance(0) - continue - - case syntax.Boundary: - if !r.isBoundary(r.textPos(), 0, r.runtextend) { - break - } - r.advance(0) - continue - - case syntax.Nonboundary: - if r.isBoundary(r.textPos(), 0, r.runtextend) { - break - } - r.advance(0) - continue - - case syntax.ECMABoundary: - if !r.isECMABoundary(r.textPos(), 0, r.runtextend) { - break - } - r.advance(0) - continue - - case syntax.NonECMABoundary: - if r.isECMABoundary(r.textPos(), 0, r.runtextend) { - break - } - r.advance(0) - continue - - case syntax.Beginning: - if r.leftchars() > 0 { - break - } - r.advance(0) - continue - - case syntax.Start: - if r.textPos() != r.textstart() { - break - } - r.advance(0) - continue - - case syntax.EndZ: - rchars := r.rightchars() - if rchars > 1 { - break - } - // RE2 and EcmaScript define $ as "asserts position at the end of the string" - // PCRE/.NET adds "or before the line terminator right at the end of the string (if any)" - if (r.re.options & (RE2 | ECMAScript)) != 0 { - // RE2/Ecmascript mode - if rchars > 0 { - break - } - } else if rchars == 1 && r.charAt(r.textPos()) != '\n' { - // "regular" mode - break - } - - r.advance(0) - continue - - case syntax.End: - if r.rightchars() > 0 { - break - } - r.advance(0) - continue - - case syntax.One: - if r.forwardchars() < 1 || r.forwardcharnext() != rune(r.operand(0)) { - break - } - - r.advance(1) - continue - - case syntax.Notone: - if r.forwardchars() < 1 || r.forwardcharnext() == rune(r.operand(0)) { - break - } - - r.advance(1) - continue - - case syntax.Set: - - if r.forwardchars() < 1 || !r.code.Sets[r.operand(0)].CharIn(r.forwardcharnext()) { - break - } - - r.advance(1) - continue - - case syntax.Multi: - if !r.runematch(r.code.Strings[r.operand(0)]) { - break - } - - r.advance(1) - continue - - case syntax.Ref: - - capnum := r.operand(0) - - if r.runmatch.isMatched(capnum) { - if !r.refmatch(r.runmatch.matchIndex(capnum), r.runmatch.matchLength(capnum)) { - break - } - } else { - if (r.re.options & ECMAScript) == 0 { - break - } - } - - r.advance(1) - continue - - case syntax.Onerep: - - c := r.operand(1) - - if r.forwardchars() < c { - break - } - - ch := rune(r.operand(0)) - - for c > 0 { - if r.forwardcharnext() != ch { - goto BreakBackward - } - c-- - } - - r.advance(2) - continue - - case syntax.Notonerep: - - c := r.operand(1) - - if r.forwardchars() < c { - break - } - ch := rune(r.operand(0)) - - for c > 0 { - if r.forwardcharnext() == ch { - goto BreakBackward - } - c-- - } - - r.advance(2) - continue - - case syntax.Setrep: - - c := r.operand(1) - - if r.forwardchars() < c { - break - } - - set := r.code.Sets[r.operand(0)] - - for c > 0 { - if !set.CharIn(r.forwardcharnext()) { - goto BreakBackward - } - c-- - } - - r.advance(2) - continue - - case syntax.Oneloop: - - c := r.operand(1) - - if c > r.forwardchars() { - c = r.forwardchars() - } - - ch := rune(r.operand(0)) - i := c - - for ; i > 0; i-- { - if r.forwardcharnext() != ch { - r.backwardnext() - break - } - } - - if c > i { - r.trackPush2(c-i-1, r.textPos()-r.bump()) - } - - r.advance(2) - continue - - case syntax.Notoneloop: - - c := r.operand(1) - - if c > r.forwardchars() { - c = r.forwardchars() - } - - ch := rune(r.operand(0)) - i := c - - for ; i > 0; i-- { - if r.forwardcharnext() == ch { - r.backwardnext() - break - } - } - - if c > i { - r.trackPush2(c-i-1, r.textPos()-r.bump()) - } - - r.advance(2) - continue - - case syntax.Setloop: - - c := r.operand(1) - - if c > r.forwardchars() { - c = r.forwardchars() - } - - set := r.code.Sets[r.operand(0)] - i := c - - for ; i > 0; i-- { - if !set.CharIn(r.forwardcharnext()) { - r.backwardnext() - break - } - } - - if c > i { - r.trackPush2(c-i-1, r.textPos()-r.bump()) - } - - r.advance(2) - continue - - case syntax.Oneloop | syntax.Back, syntax.Notoneloop | syntax.Back: - - r.trackPopN(2) - i := r.trackPeek() - pos := r.trackPeekN(1) - - r.textto(pos) - - if i > 0 { - r.trackPush2(i-1, pos-r.bump()) - } - - r.advance(2) - continue - - case syntax.Setloop | syntax.Back: - - r.trackPopN(2) - i := r.trackPeek() - pos := r.trackPeekN(1) - - r.textto(pos) - - if i > 0 { - r.trackPush2(i-1, pos-r.bump()) - } - - r.advance(2) - continue - - case syntax.Onelazy, syntax.Notonelazy: - - c := r.operand(1) - - if c > r.forwardchars() { - c = r.forwardchars() - } - - if c > 0 { - r.trackPush2(c-1, r.textPos()) - } - - r.advance(2) - continue - - case syntax.Setlazy: - - c := r.operand(1) - - if c > r.forwardchars() { - c = r.forwardchars() - } - - if c > 0 { - r.trackPush2(c-1, r.textPos()) - } - - r.advance(2) - continue - - case syntax.Onelazy | syntax.Back: - - r.trackPopN(2) - pos := r.trackPeekN(1) - r.textto(pos) - - if r.forwardcharnext() != rune(r.operand(0)) { - break - } - - i := r.trackPeek() - - if i > 0 { - r.trackPush2(i-1, pos+r.bump()) - } - - r.advance(2) - continue - - case syntax.Notonelazy | syntax.Back: - - r.trackPopN(2) - pos := r.trackPeekN(1) - r.textto(pos) - - if r.forwardcharnext() == rune(r.operand(0)) { - break - } - - i := r.trackPeek() - - if i > 0 { - r.trackPush2(i-1, pos+r.bump()) - } - - r.advance(2) - continue - - case syntax.Setlazy | syntax.Back: - - r.trackPopN(2) - pos := r.trackPeekN(1) - r.textto(pos) - - if !r.code.Sets[r.operand(0)].CharIn(r.forwardcharnext()) { - break - } - - i := r.trackPeek() - - if i > 0 { - r.trackPush2(i-1, pos+r.bump()) - } - - r.advance(2) - continue - - default: - return errors.New("unknown state in regex runner") - } - - BreakBackward: - ; - - // "break Backward" comes here: - r.backtrack() - } -} - -// increase the size of stack and track storage -func (r *runner) ensureStorage() { - if r.runstackpos < r.runtrackcount*4 { - doubleIntSlice(&r.runstack, &r.runstackpos) - } - if r.runtrackpos < r.runtrackcount*4 { - doubleIntSlice(&r.runtrack, &r.runtrackpos) - } -} - -func doubleIntSlice(s *[]int, pos *int) { - oldLen := len(*s) - newS := make([]int, oldLen*2) - - copy(newS[oldLen:], *s) - *pos += oldLen - *s = newS -} - -// Save a number on the longjump unrolling stack -func (r *runner) crawl(i int) { - if r.runcrawlpos == 0 { - doubleIntSlice(&r.runcrawl, &r.runcrawlpos) - } - r.runcrawlpos-- - r.runcrawl[r.runcrawlpos] = i -} - -// Remove a number from the longjump unrolling stack -func (r *runner) popcrawl() int { - val := r.runcrawl[r.runcrawlpos] - r.runcrawlpos++ - return val -} - -// Get the height of the stack -func (r *runner) crawlpos() int { - return len(r.runcrawl) - r.runcrawlpos -} - -func (r *runner) advance(i int) { - r.codepos += (i + 1) - r.setOperator(r.code.Codes[r.codepos]) -} - -func (r *runner) goTo(newpos int) { - // when branching backward or in place, ensure storage - if newpos <= r.codepos { - r.ensureStorage() - } - - r.setOperator(r.code.Codes[newpos]) - r.codepos = newpos -} - -func (r *runner) textto(newpos int) { - r.runtextpos = newpos -} - -func (r *runner) trackto(newpos int) { - r.runtrackpos = len(r.runtrack) - newpos -} - -func (r *runner) textstart() int { - return r.runtextstart -} - -func (r *runner) textPos() int { - return r.runtextpos -} - -// push onto the backtracking stack -func (r *runner) trackpos() int { - return len(r.runtrack) - r.runtrackpos -} - -func (r *runner) trackPush() { - r.runtrackpos-- - r.runtrack[r.runtrackpos] = r.codepos -} - -func (r *runner) trackPush1(I1 int) { - r.runtrackpos-- - r.runtrack[r.runtrackpos] = I1 - r.runtrackpos-- - r.runtrack[r.runtrackpos] = r.codepos -} - -func (r *runner) trackPush2(I1, I2 int) { - r.runtrackpos-- - r.runtrack[r.runtrackpos] = I1 - r.runtrackpos-- - r.runtrack[r.runtrackpos] = I2 - r.runtrackpos-- - r.runtrack[r.runtrackpos] = r.codepos -} - -func (r *runner) trackPush3(I1, I2, I3 int) { - r.runtrackpos-- - r.runtrack[r.runtrackpos] = I1 - r.runtrackpos-- - r.runtrack[r.runtrackpos] = I2 - r.runtrackpos-- - r.runtrack[r.runtrackpos] = I3 - r.runtrackpos-- - r.runtrack[r.runtrackpos] = r.codepos -} - -func (r *runner) trackPushNeg1(I1 int) { - r.runtrackpos-- - r.runtrack[r.runtrackpos] = I1 - r.runtrackpos-- - r.runtrack[r.runtrackpos] = -r.codepos -} - -func (r *runner) trackPushNeg2(I1, I2 int) { - r.runtrackpos-- - r.runtrack[r.runtrackpos] = I1 - r.runtrackpos-- - r.runtrack[r.runtrackpos] = I2 - r.runtrackpos-- - r.runtrack[r.runtrackpos] = -r.codepos -} - -func (r *runner) backtrack() { - newpos := r.runtrack[r.runtrackpos] - r.runtrackpos++ - - if r.re.Debug() { - if newpos < 0 { - fmt.Printf(" Backtracking (back2) to code position %v\n", -newpos) - } else { - fmt.Printf(" Backtracking to code position %v\n", newpos) - } - } - - if newpos < 0 { - newpos = -newpos - r.setOperator(r.code.Codes[newpos] | syntax.Back2) - } else { - r.setOperator(r.code.Codes[newpos] | syntax.Back) - } - - // When branching backward, ensure storage - if newpos < r.codepos { - r.ensureStorage() - } - - r.codepos = newpos -} - -func (r *runner) setOperator(op int) { - r.caseInsensitive = (0 != (op & syntax.Ci)) - r.rightToLeft = (0 != (op & syntax.Rtl)) - r.operator = syntax.InstOp(op & ^(syntax.Rtl | syntax.Ci)) -} - -func (r *runner) trackPop() { - r.runtrackpos++ -} - -// pop framesize items from the backtracking stack -func (r *runner) trackPopN(framesize int) { - r.runtrackpos += framesize -} - -// Technically we are actually peeking at items already popped. So if you want to -// get and pop the top item from the stack, you do -// r.trackPop(); -// r.trackPeek(); -func (r *runner) trackPeek() int { - return r.runtrack[r.runtrackpos-1] -} - -// get the ith element down on the backtracking stack -func (r *runner) trackPeekN(i int) int { - return r.runtrack[r.runtrackpos-i-1] -} - -// Push onto the grouping stack -func (r *runner) stackPush(I1 int) { - r.runstackpos-- - r.runstack[r.runstackpos] = I1 -} - -func (r *runner) stackPush2(I1, I2 int) { - r.runstackpos-- - r.runstack[r.runstackpos] = I1 - r.runstackpos-- - r.runstack[r.runstackpos] = I2 -} - -func (r *runner) stackPop() { - r.runstackpos++ -} - -// pop framesize items from the grouping stack -func (r *runner) stackPopN(framesize int) { - r.runstackpos += framesize -} - -// Technically we are actually peeking at items already popped. So if you want to -// get and pop the top item from the stack, you do -// r.stackPop(); -// r.stackPeek(); -func (r *runner) stackPeek() int { - return r.runstack[r.runstackpos-1] -} - -// get the ith element down on the grouping stack -func (r *runner) stackPeekN(i int) int { - return r.runstack[r.runstackpos-i-1] -} - -func (r *runner) operand(i int) int { - return r.code.Codes[r.codepos+i+1] -} - -func (r *runner) leftchars() int { - return r.runtextpos -} - -func (r *runner) rightchars() int { - return r.runtextend - r.runtextpos -} - -func (r *runner) bump() int { - if r.rightToLeft { - return -1 - } - return 1 -} - -func (r *runner) forwardchars() int { - if r.rightToLeft { - return r.runtextpos - } - return r.runtextend - r.runtextpos -} - -func (r *runner) forwardcharnext() rune { - var ch rune - if r.rightToLeft { - r.runtextpos-- - ch = r.runtext[r.runtextpos] - } else { - ch = r.runtext[r.runtextpos] - r.runtextpos++ - } - - if r.caseInsensitive { - return unicode.ToLower(ch) - } - return ch -} - -func (r *runner) runematch(str []rune) bool { - var pos int - - c := len(str) - if !r.rightToLeft { - if r.runtextend-r.runtextpos < c { - return false - } - - pos = r.runtextpos + c - } else { - if r.runtextpos-0 < c { - return false - } - - pos = r.runtextpos - } - - if !r.caseInsensitive { - for c != 0 { - c-- - pos-- - if str[c] != r.runtext[pos] { - return false - } - } - } else { - for c != 0 { - c-- - pos-- - if str[c] != unicode.ToLower(r.runtext[pos]) { - return false - } - } - } - - if !r.rightToLeft { - pos += len(str) - } - - r.runtextpos = pos - - return true -} - -func (r *runner) refmatch(index, len int) bool { - var c, pos, cmpos int - - if !r.rightToLeft { - if r.runtextend-r.runtextpos < len { - return false - } - - pos = r.runtextpos + len - } else { - if r.runtextpos-0 < len { - return false - } - - pos = r.runtextpos - } - cmpos = index + len - - c = len - - if !r.caseInsensitive { - for c != 0 { - c-- - cmpos-- - pos-- - if r.runtext[cmpos] != r.runtext[pos] { - return false - } - - } - } else { - for c != 0 { - c-- - cmpos-- - pos-- - - if unicode.ToLower(r.runtext[cmpos]) != unicode.ToLower(r.runtext[pos]) { - return false - } - } - } - - if !r.rightToLeft { - pos += len - } - - r.runtextpos = pos - - return true -} - -func (r *runner) backwardnext() { - if r.rightToLeft { - r.runtextpos++ - } else { - r.runtextpos-- - } -} - -func (r *runner) charAt(j int) rune { - return r.runtext[j] -} - -func (r *runner) findFirstChar() bool { - - if 0 != (r.code.Anchors & (syntax.AnchorBeginning | syntax.AnchorStart | syntax.AnchorEndZ | syntax.AnchorEnd)) { - if !r.code.RightToLeft { - if (0 != (r.code.Anchors&syntax.AnchorBeginning) && r.runtextpos > 0) || - (0 != (r.code.Anchors&syntax.AnchorStart) && r.runtextpos > r.runtextstart) { - r.runtextpos = r.runtextend - return false - } - if 0 != (r.code.Anchors&syntax.AnchorEndZ) && r.runtextpos < r.runtextend-1 { - r.runtextpos = r.runtextend - 1 - } else if 0 != (r.code.Anchors&syntax.AnchorEnd) && r.runtextpos < r.runtextend { - r.runtextpos = r.runtextend - } - } else { - if (0 != (r.code.Anchors&syntax.AnchorEnd) && r.runtextpos < r.runtextend) || - (0 != (r.code.Anchors&syntax.AnchorEndZ) && (r.runtextpos < r.runtextend-1 || - (r.runtextpos == r.runtextend-1 && r.charAt(r.runtextpos) != '\n'))) || - (0 != (r.code.Anchors&syntax.AnchorStart) && r.runtextpos < r.runtextstart) { - r.runtextpos = 0 - return false - } - if 0 != (r.code.Anchors&syntax.AnchorBeginning) && r.runtextpos > 0 { - r.runtextpos = 0 - } - } - - if r.code.BmPrefix != nil { - return r.code.BmPrefix.IsMatch(r.runtext, r.runtextpos, 0, r.runtextend) - } - - return true // found a valid start or end anchor - } else if r.code.BmPrefix != nil { - r.runtextpos = r.code.BmPrefix.Scan(r.runtext, r.runtextpos, 0, r.runtextend) - - if r.runtextpos == -1 { - if r.code.RightToLeft { - r.runtextpos = 0 - } else { - r.runtextpos = r.runtextend - } - return false - } - - return true - } else if r.code.FcPrefix == nil { - return true - } - - r.rightToLeft = r.code.RightToLeft - r.caseInsensitive = r.code.FcPrefix.CaseInsensitive - - set := r.code.FcPrefix.PrefixSet - if set.IsSingleton() { - ch := set.SingletonChar() - for i := r.forwardchars(); i > 0; i-- { - if ch == r.forwardcharnext() { - r.backwardnext() - return true - } - } - } else { - for i := r.forwardchars(); i > 0; i-- { - n := r.forwardcharnext() - //fmt.Printf("%v in %v: %v\n", string(n), set.String(), set.CharIn(n)) - if set.CharIn(n) { - r.backwardnext() - return true - } - } - } - - return false -} - -func (r *runner) initMatch() { - // Use a hashtable'ed Match object if the capture numbers are sparse - - if r.runmatch == nil { - if r.re.caps != nil { - r.runmatch = newMatchSparse(r.re, r.re.caps, r.re.capsize, r.runtext, r.runtextstart) - } else { - r.runmatch = newMatch(r.re, r.re.capsize, r.runtext, r.runtextstart) - } - } else { - r.runmatch.reset(r.runtext, r.runtextstart) - } - - // note we test runcrawl, because it is the last one to be allocated - // If there is an alloc failure in the middle of the three allocations, - // we may still return to reuse this instance, and we want to behave - // as if the allocations didn't occur. (we used to test _trackcount != 0) - - if r.runcrawl != nil { - r.runtrackpos = len(r.runtrack) - r.runstackpos = len(r.runstack) - r.runcrawlpos = len(r.runcrawl) - return - } - - r.initTrackCount() - - tracksize := r.runtrackcount * 8 - stacksize := r.runtrackcount * 8 - - if tracksize < 32 { - tracksize = 32 - } - if stacksize < 16 { - stacksize = 16 - } - - r.runtrack = make([]int, tracksize) - r.runtrackpos = tracksize - - r.runstack = make([]int, stacksize) - r.runstackpos = stacksize - - r.runcrawl = make([]int, 32) - r.runcrawlpos = 32 -} - -func (r *runner) tidyMatch(quick bool) *Match { - if !quick { - match := r.runmatch - - r.runmatch = nil - - match.tidy(r.runtextpos) - return match - } else { - // send back our match -- it's not leaving the package, so it's safe to not clean it up - // this reduces allocs for frequent calls to the "IsMatch" bool-only functions - return r.runmatch - } -} - -// capture captures a subexpression. Note that the -// capnum used here has already been mapped to a non-sparse -// index (by the code generator RegexWriter). -func (r *runner) capture(capnum, start, end int) { - if end < start { - T := end - end = start - start = T - } - - r.crawl(capnum) - r.runmatch.addMatch(capnum, start, end-start) -} - -// transferCapture captures a subexpression. Note that the -// capnum used here has already been mapped to a non-sparse -// index (by the code generator RegexWriter). -func (r *runner) transferCapture(capnum, uncapnum, start, end int) { - var start2, end2 int - - // these are the two intervals that are cancelling each other - - if end < start { - T := end - end = start - start = T - } - - start2 = r.runmatch.matchIndex(uncapnum) - end2 = start2 + r.runmatch.matchLength(uncapnum) - - // The new capture gets the innermost defined interval - - if start >= end2 { - end = start - start = end2 - } else if end <= start2 { - start = start2 - } else { - if end > end2 { - end = end2 - } - if start2 > start { - start = start2 - } - } - - r.crawl(uncapnum) - r.runmatch.balanceMatch(uncapnum) - - if capnum != -1 { - r.crawl(capnum) - r.runmatch.addMatch(capnum, start, end-start) - } -} - -// revert the last capture -func (r *runner) uncapture() { - capnum := r.popcrawl() - r.runmatch.removeMatch(capnum) -} - -//debug - -func (r *runner) dumpState() { - back := "" - if r.operator&syntax.Back != 0 { - back = " Back" - } - if r.operator&syntax.Back2 != 0 { - back += " Back2" - } - fmt.Printf("Text: %v\nTrack: %v\nStack: %v\n %s%s\n\n", - r.textposDescription(), - r.stackDescription(r.runtrack, r.runtrackpos), - r.stackDescription(r.runstack, r.runstackpos), - r.code.OpcodeDescription(r.codepos), - back) -} - -func (r *runner) stackDescription(a []int, index int) string { - buf := &bytes.Buffer{} - - fmt.Fprintf(buf, "%v/%v", len(a)-index, len(a)) - if buf.Len() < 8 { - buf.WriteString(strings.Repeat(" ", 8-buf.Len())) - } - - buf.WriteRune('(') - for i := index; i < len(a); i++ { - if i > index { - buf.WriteRune(' ') - } - - buf.WriteString(strconv.Itoa(a[i])) - } - - buf.WriteRune(')') - - return buf.String() -} - -func (r *runner) textposDescription() string { - buf := &bytes.Buffer{} - - buf.WriteString(strconv.Itoa(r.runtextpos)) - - if buf.Len() < 8 { - buf.WriteString(strings.Repeat(" ", 8-buf.Len())) - } - - if r.runtextpos > 0 { - buf.WriteString(syntax.CharDescription(r.runtext[r.runtextpos-1])) - } else { - buf.WriteRune('^') - } - - buf.WriteRune('>') - - for i := r.runtextpos; i < r.runtextend; i++ { - buf.WriteString(syntax.CharDescription(r.runtext[i])) - } - if buf.Len() >= 64 { - buf.Truncate(61) - buf.WriteString("...") - } else { - buf.WriteRune('$') - } - - return buf.String() -} - -// decide whether the pos -// at the specified index is a boundary or not. It's just not worth -// emitting inline code for this logic. -func (r *runner) isBoundary(index, startpos, endpos int) bool { - return (index > startpos && syntax.IsWordChar(r.runtext[index-1])) != - (index < endpos && syntax.IsWordChar(r.runtext[index])) -} - -func (r *runner) isECMABoundary(index, startpos, endpos int) bool { - return (index > startpos && syntax.IsECMAWordChar(r.runtext[index-1])) != - (index < endpos && syntax.IsECMAWordChar(r.runtext[index])) -} - -func (r *runner) startTimeoutWatch() { - if r.ignoreTimeout { - return - } - r.deadline = makeDeadline(r.timeout) -} - -func (r *runner) checkTimeout() error { - if r.ignoreTimeout || !r.deadline.reached() { - return nil - } - - if r.re.Debug() { - //Debug.WriteLine("") - //Debug.WriteLine("RegEx match timeout occurred!") - //Debug.WriteLine("Specified timeout: " + TimeSpan.FromMilliseconds(_timeout).ToString()) - //Debug.WriteLine("Timeout check frequency: " + TimeoutCheckFrequency) - //Debug.WriteLine("Search pattern: " + _runregex._pattern) - //Debug.WriteLine("Input: " + r.runtext) - //Debug.WriteLine("About to throw RegexMatchTimeoutException.") - } - - return fmt.Errorf("match timeout after %v on input `%v`", r.timeout, string(r.runtext)) -} - -func (r *runner) initTrackCount() { - r.runtrackcount = r.code.TrackCount -} - -// getRunner returns a run to use for matching re. -// It uses the re's runner cache if possible, to avoid -// unnecessary allocation. -func (re *Regexp) getRunner() *runner { - re.muRun.Lock() - if n := len(re.runner); n > 0 { - z := re.runner[n-1] - re.runner = re.runner[:n-1] - re.muRun.Unlock() - return z - } - re.muRun.Unlock() - z := &runner{ - re: re, - code: re.code, - } - return z -} - -// putRunner returns a runner to the re's cache. -// There is no attempt to limit the size of the cache, so it will -// grow to the maximum number of simultaneous matches -// run using re. (The cache empties when re gets garbage collected.) -func (re *Regexp) putRunner(r *runner) { - re.muRun.Lock() - r.runtext = nil - if r.runmatch != nil { - r.runmatch.text = nil - } - re.runner = append(re.runner, r) - re.muRun.Unlock() -} diff --git a/vendor/github.com/dlclark/regexp2/syntax/charclass.go b/vendor/github.com/dlclark/regexp2/syntax/charclass.go deleted file mode 100644 index 6881a0e297..0000000000 --- a/vendor/github.com/dlclark/regexp2/syntax/charclass.go +++ /dev/null @@ -1,865 +0,0 @@ -package syntax - -import ( - "bytes" - "encoding/binary" - "fmt" - "sort" - "unicode" - "unicode/utf8" -) - -// CharSet combines start-end rune ranges and unicode categories representing a set of characters -type CharSet struct { - ranges []singleRange - categories []category - sub *CharSet //optional subtractor - negate bool - anything bool -} - -type category struct { - negate bool - cat string -} - -type singleRange struct { - first rune - last rune -} - -const ( - spaceCategoryText = " " - wordCategoryText = "W" -) - -var ( - ecmaSpace = []rune{0x0009, 0x000e, 0x0020, 0x0021, 0x00a0, 0x00a1, 0x1680, 0x1681, 0x2000, 0x200b, 0x2028, 0x202a, 0x202f, 0x2030, 0x205f, 0x2060, 0x3000, 0x3001, 0xfeff, 0xff00} - ecmaWord = []rune{0x0030, 0x003a, 0x0041, 0x005b, 0x005f, 0x0060, 0x0061, 0x007b} - ecmaDigit = []rune{0x0030, 0x003a} - - re2Space = []rune{0x0009, 0x000b, 0x000c, 0x000e, 0x0020, 0x0021} -) - -var ( - AnyClass = getCharSetFromOldString([]rune{0}, false) - ECMAAnyClass = getCharSetFromOldString([]rune{0, 0x000a, 0x000b, 0x000d, 0x000e}, false) - NoneClass = getCharSetFromOldString(nil, false) - ECMAWordClass = getCharSetFromOldString(ecmaWord, false) - NotECMAWordClass = getCharSetFromOldString(ecmaWord, true) - ECMASpaceClass = getCharSetFromOldString(ecmaSpace, false) - NotECMASpaceClass = getCharSetFromOldString(ecmaSpace, true) - ECMADigitClass = getCharSetFromOldString(ecmaDigit, false) - NotECMADigitClass = getCharSetFromOldString(ecmaDigit, true) - - WordClass = getCharSetFromCategoryString(false, false, wordCategoryText) - NotWordClass = getCharSetFromCategoryString(true, false, wordCategoryText) - SpaceClass = getCharSetFromCategoryString(false, false, spaceCategoryText) - NotSpaceClass = getCharSetFromCategoryString(true, false, spaceCategoryText) - DigitClass = getCharSetFromCategoryString(false, false, "Nd") - NotDigitClass = getCharSetFromCategoryString(false, true, "Nd") - - RE2SpaceClass = getCharSetFromOldString(re2Space, false) - NotRE2SpaceClass = getCharSetFromOldString(re2Space, true) -) - -var unicodeCategories = func() map[string]*unicode.RangeTable { - retVal := make(map[string]*unicode.RangeTable) - for k, v := range unicode.Scripts { - retVal[k] = v - } - for k, v := range unicode.Categories { - retVal[k] = v - } - for k, v := range unicode.Properties { - retVal[k] = v - } - return retVal -}() - -func getCharSetFromCategoryString(negateSet bool, negateCat bool, cats ...string) func() *CharSet { - if negateCat && negateSet { - panic("BUG! You should only negate the set OR the category in a constant setup, but not both") - } - - c := CharSet{negate: negateSet} - - c.categories = make([]category, len(cats)) - for i, cat := range cats { - c.categories[i] = category{cat: cat, negate: negateCat} - } - return func() *CharSet { - //make a copy each time - local := c - //return that address - return &local - } -} - -func getCharSetFromOldString(setText []rune, negate bool) func() *CharSet { - c := CharSet{} - if len(setText) > 0 { - fillFirst := false - l := len(setText) - if negate { - if setText[0] == 0 { - setText = setText[1:] - } else { - l++ - fillFirst = true - } - } - - if l%2 == 0 { - c.ranges = make([]singleRange, l/2) - } else { - c.ranges = make([]singleRange, l/2+1) - } - - first := true - if fillFirst { - c.ranges[0] = singleRange{first: 0} - first = false - } - - i := 0 - for _, r := range setText { - if first { - // lower bound in a new range - c.ranges[i] = singleRange{first: r} - first = false - } else { - c.ranges[i].last = r - 1 - i++ - first = true - } - } - if !first { - c.ranges[i].last = utf8.MaxRune - } - } - - return func() *CharSet { - local := c - return &local - } -} - -// Copy makes a deep copy to prevent accidental mutation of a set -func (c CharSet) Copy() CharSet { - ret := CharSet{ - anything: c.anything, - negate: c.negate, - } - - ret.ranges = append(ret.ranges, c.ranges...) - ret.categories = append(ret.categories, c.categories...) - - if c.sub != nil { - sub := c.sub.Copy() - ret.sub = &sub - } - - return ret -} - -// gets a human-readable description for a set string -func (c CharSet) String() string { - buf := &bytes.Buffer{} - buf.WriteRune('[') - - if c.IsNegated() { - buf.WriteRune('^') - } - - for _, r := range c.ranges { - - buf.WriteString(CharDescription(r.first)) - if r.first != r.last { - if r.last-r.first != 1 { - //groups that are 1 char apart skip the dash - buf.WriteRune('-') - } - buf.WriteString(CharDescription(r.last)) - } - } - - for _, c := range c.categories { - buf.WriteString(c.String()) - } - - if c.sub != nil { - buf.WriteRune('-') - buf.WriteString(c.sub.String()) - } - - buf.WriteRune(']') - - return buf.String() -} - -// mapHashFill converts a charset into a buffer for use in maps -func (c CharSet) mapHashFill(buf *bytes.Buffer) { - if c.negate { - buf.WriteByte(0) - } else { - buf.WriteByte(1) - } - - binary.Write(buf, binary.LittleEndian, len(c.ranges)) - binary.Write(buf, binary.LittleEndian, len(c.categories)) - for _, r := range c.ranges { - buf.WriteRune(r.first) - buf.WriteRune(r.last) - } - for _, ct := range c.categories { - buf.WriteString(ct.cat) - if ct.negate { - buf.WriteByte(1) - } else { - buf.WriteByte(0) - } - } - - if c.sub != nil { - c.sub.mapHashFill(buf) - } -} - -// CharIn returns true if the rune is in our character set (either ranges or categories). -// It handles negations and subtracted sub-charsets. -func (c CharSet) CharIn(ch rune) bool { - val := false - // in s && !s.subtracted - - //check ranges - for _, r := range c.ranges { - if ch < r.first { - continue - } - if ch <= r.last { - val = true - break - } - } - - //check categories if we haven't already found a range - if !val && len(c.categories) > 0 { - for _, ct := range c.categories { - // special categories...then unicode - if ct.cat == spaceCategoryText { - if unicode.IsSpace(ch) { - // we found a space so we're done - // negate means this is a "bad" thing - val = !ct.negate - break - } else if ct.negate { - val = true - break - } - } else if ct.cat == wordCategoryText { - if IsWordChar(ch) { - val = !ct.negate - break - } else if ct.negate { - val = true - break - } - } else if unicode.Is(unicodeCategories[ct.cat], ch) { - // if we're in this unicode category then we're done - // if negate=true on this category then we "failed" our test - // otherwise we're good that we found it - val = !ct.negate - break - } else if ct.negate { - val = true - break - } - } - } - - // negate the whole char set - if c.negate { - val = !val - } - - // get subtracted recurse - if val && c.sub != nil { - val = !c.sub.CharIn(ch) - } - - //log.Printf("Char '%v' in %v == %v", string(ch), c.String(), val) - return val -} - -func (c category) String() string { - switch c.cat { - case spaceCategoryText: - if c.negate { - return "\\S" - } - return "\\s" - case wordCategoryText: - if c.negate { - return "\\W" - } - return "\\w" - } - if _, ok := unicodeCategories[c.cat]; ok { - - if c.negate { - return "\\P{" + c.cat + "}" - } - return "\\p{" + c.cat + "}" - } - return "Unknown category: " + c.cat -} - -// CharDescription Produces a human-readable description for a single character. -func CharDescription(ch rune) string { - /*if ch == '\\' { - return "\\\\" - } - - if ch > ' ' && ch <= '~' { - return string(ch) - } else if ch == '\n' { - return "\\n" - } else if ch == ' ' { - return "\\ " - }*/ - - b := &bytes.Buffer{} - escape(b, ch, false) //fmt.Sprintf("%U", ch) - return b.String() -} - -// According to UTS#18 Unicode Regular Expressions (http://www.unicode.org/reports/tr18/) -// RL 1.4 Simple Word Boundaries The class of includes all Alphabetic -// values from the Unicode character database, from UnicodeData.txt [UData], plus the U+200C -// ZERO WIDTH NON-JOINER and U+200D ZERO WIDTH JOINER. -func IsWordChar(r rune) bool { - //"L", "Mn", "Nd", "Pc" - return unicode.In(r, - unicode.Categories["L"], unicode.Categories["Mn"], - unicode.Categories["Nd"], unicode.Categories["Pc"]) || r == '\u200D' || r == '\u200C' - //return 'A' <= r && r <= 'Z' || 'a' <= r && r <= 'z' || '0' <= r && r <= '9' || r == '_' -} - -func IsECMAWordChar(r rune) bool { - return unicode.In(r, - unicode.Categories["L"], unicode.Categories["Mn"], - unicode.Categories["Nd"], unicode.Categories["Pc"]) - - //return 'A' <= r && r <= 'Z' || 'a' <= r && r <= 'z' || '0' <= r && r <= '9' || r == '_' -} - -// SingletonChar will return the char from the first range without validation. -// It assumes you have checked for IsSingleton or IsSingletonInverse and will panic given bad input -func (c CharSet) SingletonChar() rune { - return c.ranges[0].first -} - -func (c CharSet) IsSingleton() bool { - return !c.negate && //negated is multiple chars - len(c.categories) == 0 && len(c.ranges) == 1 && // multiple ranges and unicode classes represent multiple chars - c.sub == nil && // subtraction means we've got multiple chars - c.ranges[0].first == c.ranges[0].last // first and last equal means we're just 1 char -} - -func (c CharSet) IsSingletonInverse() bool { - return c.negate && //same as above, but requires negated - len(c.categories) == 0 && len(c.ranges) == 1 && // multiple ranges and unicode classes represent multiple chars - c.sub == nil && // subtraction means we've got multiple chars - c.ranges[0].first == c.ranges[0].last // first and last equal means we're just 1 char -} - -func (c CharSet) IsMergeable() bool { - return !c.IsNegated() && !c.HasSubtraction() -} - -func (c CharSet) IsNegated() bool { - return c.negate -} - -func (c CharSet) HasSubtraction() bool { - return c.sub != nil -} - -func (c CharSet) IsEmpty() bool { - return len(c.ranges) == 0 && len(c.categories) == 0 && c.sub == nil -} - -func (c *CharSet) addDigit(ecma, negate bool, pattern string) { - if ecma { - if negate { - c.addRanges(NotECMADigitClass().ranges) - } else { - c.addRanges(ECMADigitClass().ranges) - } - } else { - c.addCategories(category{cat: "Nd", negate: negate}) - } -} - -func (c *CharSet) addChar(ch rune) { - c.addRange(ch, ch) -} - -func (c *CharSet) addSpace(ecma, re2, negate bool) { - if ecma { - if negate { - c.addRanges(NotECMASpaceClass().ranges) - } else { - c.addRanges(ECMASpaceClass().ranges) - } - } else if re2 { - if negate { - c.addRanges(NotRE2SpaceClass().ranges) - } else { - c.addRanges(RE2SpaceClass().ranges) - } - } else { - c.addCategories(category{cat: spaceCategoryText, negate: negate}) - } -} - -func (c *CharSet) addWord(ecma, negate bool) { - if ecma { - if negate { - c.addRanges(NotECMAWordClass().ranges) - } else { - c.addRanges(ECMAWordClass().ranges) - } - } else { - c.addCategories(category{cat: wordCategoryText, negate: negate}) - } -} - -// Add set ranges and categories into ours -- no deduping or anything -func (c *CharSet) addSet(set CharSet) { - if c.anything { - return - } - if set.anything { - c.makeAnything() - return - } - // just append here to prevent double-canon - c.ranges = append(c.ranges, set.ranges...) - c.addCategories(set.categories...) - c.canonicalize() -} - -func (c *CharSet) makeAnything() { - c.anything = true - c.categories = []category{} - c.ranges = AnyClass().ranges -} - -func (c *CharSet) addCategories(cats ...category) { - // don't add dupes and remove positive+negative - if c.anything { - // if we've had a previous positive+negative group then - // just return, we're as broad as we can get - return - } - - for _, ct := range cats { - found := false - for _, ct2 := range c.categories { - if ct.cat == ct2.cat { - if ct.negate != ct2.negate { - // oposite negations...this mean we just - // take us as anything and move on - c.makeAnything() - return - } - found = true - break - } - } - - if !found { - c.categories = append(c.categories, ct) - } - } -} - -// Merges new ranges to our own -func (c *CharSet) addRanges(ranges []singleRange) { - if c.anything { - return - } - c.ranges = append(c.ranges, ranges...) - c.canonicalize() -} - -// Merges everything but the new ranges into our own -func (c *CharSet) addNegativeRanges(ranges []singleRange) { - if c.anything { - return - } - - var hi rune - - // convert incoming ranges into opposites, assume they are in order - for _, r := range ranges { - if hi < r.first { - c.ranges = append(c.ranges, singleRange{hi, r.first - 1}) - } - hi = r.last + 1 - } - - if hi < utf8.MaxRune { - c.ranges = append(c.ranges, singleRange{hi, utf8.MaxRune}) - } - - c.canonicalize() -} - -func isValidUnicodeCat(catName string) bool { - _, ok := unicodeCategories[catName] - return ok -} - -func (c *CharSet) addCategory(categoryName string, negate, caseInsensitive bool, pattern string) { - if !isValidUnicodeCat(categoryName) { - // unknown unicode category, script, or property "blah" - panic(fmt.Errorf("Unknown unicode category, script, or property '%v'", categoryName)) - - } - - if caseInsensitive && (categoryName == "Ll" || categoryName == "Lu" || categoryName == "Lt") { - // when RegexOptions.IgnoreCase is specified then {Ll} {Lu} and {Lt} cases should all match - c.addCategories( - category{cat: "Ll", negate: negate}, - category{cat: "Lu", negate: negate}, - category{cat: "Lt", negate: negate}) - } - c.addCategories(category{cat: categoryName, negate: negate}) -} - -func (c *CharSet) addSubtraction(sub *CharSet) { - c.sub = sub -} - -func (c *CharSet) addRange(chMin, chMax rune) { - c.ranges = append(c.ranges, singleRange{first: chMin, last: chMax}) - c.canonicalize() -} - -func (c *CharSet) addNamedASCII(name string, negate bool) bool { - var rs []singleRange - - switch name { - case "alnum": - rs = []singleRange{singleRange{'0', '9'}, singleRange{'A', 'Z'}, singleRange{'a', 'z'}} - case "alpha": - rs = []singleRange{singleRange{'A', 'Z'}, singleRange{'a', 'z'}} - case "ascii": - rs = []singleRange{singleRange{0, 0x7f}} - case "blank": - rs = []singleRange{singleRange{'\t', '\t'}, singleRange{' ', ' '}} - case "cntrl": - rs = []singleRange{singleRange{0, 0x1f}, singleRange{0x7f, 0x7f}} - case "digit": - c.addDigit(false, negate, "") - case "graph": - rs = []singleRange{singleRange{'!', '~'}} - case "lower": - rs = []singleRange{singleRange{'a', 'z'}} - case "print": - rs = []singleRange{singleRange{' ', '~'}} - case "punct": //[!-/:-@[-`{-~] - rs = []singleRange{singleRange{'!', '/'}, singleRange{':', '@'}, singleRange{'[', '`'}, singleRange{'{', '~'}} - case "space": - c.addSpace(true, false, negate) - case "upper": - rs = []singleRange{singleRange{'A', 'Z'}} - case "word": - c.addWord(true, negate) - case "xdigit": - rs = []singleRange{singleRange{'0', '9'}, singleRange{'A', 'F'}, singleRange{'a', 'f'}} - default: - return false - } - - if len(rs) > 0 { - if negate { - c.addNegativeRanges(rs) - } else { - c.addRanges(rs) - } - } - - return true -} - -type singleRangeSorter []singleRange - -func (p singleRangeSorter) Len() int { return len(p) } -func (p singleRangeSorter) Less(i, j int) bool { return p[i].first < p[j].first } -func (p singleRangeSorter) Swap(i, j int) { p[i], p[j] = p[j], p[i] } - -// Logic to reduce a character class to a unique, sorted form. -func (c *CharSet) canonicalize() { - var i, j int - var last rune - - // - // Find and eliminate overlapping or abutting ranges - // - - if len(c.ranges) > 1 { - sort.Sort(singleRangeSorter(c.ranges)) - - done := false - - for i, j = 1, 0; ; i++ { - for last = c.ranges[j].last; ; i++ { - if i == len(c.ranges) || last == utf8.MaxRune { - done = true - break - } - - CurrentRange := c.ranges[i] - if CurrentRange.first > last+1 { - break - } - - if last < CurrentRange.last { - last = CurrentRange.last - } - } - - c.ranges[j] = singleRange{first: c.ranges[j].first, last: last} - - j++ - - if done { - break - } - - if j < i { - c.ranges[j] = c.ranges[i] - } - } - - c.ranges = append(c.ranges[:j], c.ranges[len(c.ranges):]...) - } -} - -// Adds to the class any lowercase versions of characters already -// in the class. Used for case-insensitivity. -func (c *CharSet) addLowercase() { - if c.anything { - return - } - toAdd := []singleRange{} - for i := 0; i < len(c.ranges); i++ { - r := c.ranges[i] - if r.first == r.last { - lower := unicode.ToLower(r.first) - c.ranges[i] = singleRange{first: lower, last: lower} - } else { - toAdd = append(toAdd, r) - } - } - - for _, r := range toAdd { - c.addLowercaseRange(r.first, r.last) - } - c.canonicalize() -} - -/************************************************************************** - Let U be the set of Unicode character values and let L be the lowercase - function, mapping from U to U. To perform case insensitive matching of - character sets, we need to be able to map an interval I in U, say - - I = [chMin, chMax] = { ch : chMin <= ch <= chMax } - - to a set A such that A contains L(I) and A is contained in the union of - I and L(I). - - The table below partitions U into intervals on which L is non-decreasing. - Thus, for any interval J = [a, b] contained in one of these intervals, - L(J) is contained in [L(a), L(b)]. - - It is also true that for any such J, [L(a), L(b)] is contained in the - union of J and L(J). This does not follow from L being non-decreasing on - these intervals. It follows from the nature of the L on each interval. - On each interval, L has one of the following forms: - - (1) L(ch) = constant (LowercaseSet) - (2) L(ch) = ch + offset (LowercaseAdd) - (3) L(ch) = ch | 1 (LowercaseBor) - (4) L(ch) = ch + (ch & 1) (LowercaseBad) - - It is easy to verify that for any of these forms [L(a), L(b)] is - contained in the union of [a, b] and L([a, b]). -***************************************************************************/ - -const ( - LowercaseSet = 0 // Set to arg. - LowercaseAdd = 1 // Add arg. - LowercaseBor = 2 // Bitwise or with 1. - LowercaseBad = 3 // Bitwise and with 1 and add original. -) - -type lcMap struct { - chMin, chMax rune - op, data int32 -} - -var lcTable = []lcMap{ - lcMap{'\u0041', '\u005A', LowercaseAdd, 32}, - lcMap{'\u00C0', '\u00DE', LowercaseAdd, 32}, - lcMap{'\u0100', '\u012E', LowercaseBor, 0}, - lcMap{'\u0130', '\u0130', LowercaseSet, 0x0069}, - lcMap{'\u0132', '\u0136', LowercaseBor, 0}, - lcMap{'\u0139', '\u0147', LowercaseBad, 0}, - lcMap{'\u014A', '\u0176', LowercaseBor, 0}, - lcMap{'\u0178', '\u0178', LowercaseSet, 0x00FF}, - lcMap{'\u0179', '\u017D', LowercaseBad, 0}, - lcMap{'\u0181', '\u0181', LowercaseSet, 0x0253}, - lcMap{'\u0182', '\u0184', LowercaseBor, 0}, - lcMap{'\u0186', '\u0186', LowercaseSet, 0x0254}, - lcMap{'\u0187', '\u0187', LowercaseSet, 0x0188}, - lcMap{'\u0189', '\u018A', LowercaseAdd, 205}, - lcMap{'\u018B', '\u018B', LowercaseSet, 0x018C}, - lcMap{'\u018E', '\u018E', LowercaseSet, 0x01DD}, - lcMap{'\u018F', '\u018F', LowercaseSet, 0x0259}, - lcMap{'\u0190', '\u0190', LowercaseSet, 0x025B}, - lcMap{'\u0191', '\u0191', LowercaseSet, 0x0192}, - lcMap{'\u0193', '\u0193', LowercaseSet, 0x0260}, - lcMap{'\u0194', '\u0194', LowercaseSet, 0x0263}, - lcMap{'\u0196', '\u0196', LowercaseSet, 0x0269}, - lcMap{'\u0197', '\u0197', LowercaseSet, 0x0268}, - lcMap{'\u0198', '\u0198', LowercaseSet, 0x0199}, - lcMap{'\u019C', '\u019C', LowercaseSet, 0x026F}, - lcMap{'\u019D', '\u019D', LowercaseSet, 0x0272}, - lcMap{'\u019F', '\u019F', LowercaseSet, 0x0275}, - lcMap{'\u01A0', '\u01A4', LowercaseBor, 0}, - lcMap{'\u01A7', '\u01A7', LowercaseSet, 0x01A8}, - lcMap{'\u01A9', '\u01A9', LowercaseSet, 0x0283}, - lcMap{'\u01AC', '\u01AC', LowercaseSet, 0x01AD}, - lcMap{'\u01AE', '\u01AE', LowercaseSet, 0x0288}, - lcMap{'\u01AF', '\u01AF', LowercaseSet, 0x01B0}, - lcMap{'\u01B1', '\u01B2', LowercaseAdd, 217}, - lcMap{'\u01B3', '\u01B5', LowercaseBad, 0}, - lcMap{'\u01B7', '\u01B7', LowercaseSet, 0x0292}, - lcMap{'\u01B8', '\u01B8', LowercaseSet, 0x01B9}, - lcMap{'\u01BC', '\u01BC', LowercaseSet, 0x01BD}, - lcMap{'\u01C4', '\u01C5', LowercaseSet, 0x01C6}, - lcMap{'\u01C7', '\u01C8', LowercaseSet, 0x01C9}, - lcMap{'\u01CA', '\u01CB', LowercaseSet, 0x01CC}, - lcMap{'\u01CD', '\u01DB', LowercaseBad, 0}, - lcMap{'\u01DE', '\u01EE', LowercaseBor, 0}, - lcMap{'\u01F1', '\u01F2', LowercaseSet, 0x01F3}, - lcMap{'\u01F4', '\u01F4', LowercaseSet, 0x01F5}, - lcMap{'\u01FA', '\u0216', LowercaseBor, 0}, - lcMap{'\u0386', '\u0386', LowercaseSet, 0x03AC}, - lcMap{'\u0388', '\u038A', LowercaseAdd, 37}, - lcMap{'\u038C', '\u038C', LowercaseSet, 0x03CC}, - lcMap{'\u038E', '\u038F', LowercaseAdd, 63}, - lcMap{'\u0391', '\u03AB', LowercaseAdd, 32}, - lcMap{'\u03E2', '\u03EE', LowercaseBor, 0}, - lcMap{'\u0401', '\u040F', LowercaseAdd, 80}, - lcMap{'\u0410', '\u042F', LowercaseAdd, 32}, - lcMap{'\u0460', '\u0480', LowercaseBor, 0}, - lcMap{'\u0490', '\u04BE', LowercaseBor, 0}, - lcMap{'\u04C1', '\u04C3', LowercaseBad, 0}, - lcMap{'\u04C7', '\u04C7', LowercaseSet, 0x04C8}, - lcMap{'\u04CB', '\u04CB', LowercaseSet, 0x04CC}, - lcMap{'\u04D0', '\u04EA', LowercaseBor, 0}, - lcMap{'\u04EE', '\u04F4', LowercaseBor, 0}, - lcMap{'\u04F8', '\u04F8', LowercaseSet, 0x04F9}, - lcMap{'\u0531', '\u0556', LowercaseAdd, 48}, - lcMap{'\u10A0', '\u10C5', LowercaseAdd, 48}, - lcMap{'\u1E00', '\u1EF8', LowercaseBor, 0}, - lcMap{'\u1F08', '\u1F0F', LowercaseAdd, -8}, - lcMap{'\u1F18', '\u1F1F', LowercaseAdd, -8}, - lcMap{'\u1F28', '\u1F2F', LowercaseAdd, -8}, - lcMap{'\u1F38', '\u1F3F', LowercaseAdd, -8}, - lcMap{'\u1F48', '\u1F4D', LowercaseAdd, -8}, - lcMap{'\u1F59', '\u1F59', LowercaseSet, 0x1F51}, - lcMap{'\u1F5B', '\u1F5B', LowercaseSet, 0x1F53}, - lcMap{'\u1F5D', '\u1F5D', LowercaseSet, 0x1F55}, - lcMap{'\u1F5F', '\u1F5F', LowercaseSet, 0x1F57}, - lcMap{'\u1F68', '\u1F6F', LowercaseAdd, -8}, - lcMap{'\u1F88', '\u1F8F', LowercaseAdd, -8}, - lcMap{'\u1F98', '\u1F9F', LowercaseAdd, -8}, - lcMap{'\u1FA8', '\u1FAF', LowercaseAdd, -8}, - lcMap{'\u1FB8', '\u1FB9', LowercaseAdd, -8}, - lcMap{'\u1FBA', '\u1FBB', LowercaseAdd, -74}, - lcMap{'\u1FBC', '\u1FBC', LowercaseSet, 0x1FB3}, - lcMap{'\u1FC8', '\u1FCB', LowercaseAdd, -86}, - lcMap{'\u1FCC', '\u1FCC', LowercaseSet, 0x1FC3}, - lcMap{'\u1FD8', '\u1FD9', LowercaseAdd, -8}, - lcMap{'\u1FDA', '\u1FDB', LowercaseAdd, -100}, - lcMap{'\u1FE8', '\u1FE9', LowercaseAdd, -8}, - lcMap{'\u1FEA', '\u1FEB', LowercaseAdd, -112}, - lcMap{'\u1FEC', '\u1FEC', LowercaseSet, 0x1FE5}, - lcMap{'\u1FF8', '\u1FF9', LowercaseAdd, -128}, - lcMap{'\u1FFA', '\u1FFB', LowercaseAdd, -126}, - lcMap{'\u1FFC', '\u1FFC', LowercaseSet, 0x1FF3}, - lcMap{'\u2160', '\u216F', LowercaseAdd, 16}, - lcMap{'\u24B6', '\u24D0', LowercaseAdd, 26}, - lcMap{'\uFF21', '\uFF3A', LowercaseAdd, 32}, -} - -func (c *CharSet) addLowercaseRange(chMin, chMax rune) { - var i, iMax, iMid int - var chMinT, chMaxT rune - var lc lcMap - - for i, iMax = 0, len(lcTable); i < iMax; { - iMid = (i + iMax) / 2 - if lcTable[iMid].chMax < chMin { - i = iMid + 1 - } else { - iMax = iMid - } - } - - for ; i < len(lcTable); i++ { - lc = lcTable[i] - if lc.chMin > chMax { - return - } - chMinT = lc.chMin - if chMinT < chMin { - chMinT = chMin - } - - chMaxT = lc.chMax - if chMaxT > chMax { - chMaxT = chMax - } - - switch lc.op { - case LowercaseSet: - chMinT = rune(lc.data) - chMaxT = rune(lc.data) - break - case LowercaseAdd: - chMinT += lc.data - chMaxT += lc.data - break - case LowercaseBor: - chMinT |= 1 - chMaxT |= 1 - break - case LowercaseBad: - chMinT += (chMinT & 1) - chMaxT += (chMaxT & 1) - break - } - - if chMinT < chMin || chMaxT > chMax { - c.addRange(chMinT, chMaxT) - } - } -} diff --git a/vendor/github.com/dlclark/regexp2/syntax/code.go b/vendor/github.com/dlclark/regexp2/syntax/code.go deleted file mode 100644 index 686e822af8..0000000000 --- a/vendor/github.com/dlclark/regexp2/syntax/code.go +++ /dev/null @@ -1,274 +0,0 @@ -package syntax - -import ( - "bytes" - "fmt" - "math" -) - -// similar to prog.go in the go regex package...also with comment 'may not belong in this package' - -// File provides operator constants for use by the Builder and the Machine. - -// Implementation notes: -// -// Regexps are built into RegexCodes, which contain an operation array, -// a string table, and some constants. -// -// Each operation is one of the codes below, followed by the integer -// operands specified for each op. -// -// Strings and sets are indices into a string table. - -type InstOp int - -const ( - // lef/back operands description - - Onerep InstOp = 0 // lef,back char,min,max a {n} - Notonerep = 1 // lef,back char,min,max .{n} - Setrep = 2 // lef,back set,min,max [\d]{n} - - Oneloop = 3 // lef,back char,min,max a {,n} - Notoneloop = 4 // lef,back char,min,max .{,n} - Setloop = 5 // lef,back set,min,max [\d]{,n} - - Onelazy = 6 // lef,back char,min,max a {,n}? - Notonelazy = 7 // lef,back char,min,max .{,n}? - Setlazy = 8 // lef,back set,min,max [\d]{,n}? - - One = 9 // lef char a - Notone = 10 // lef char [^a] - Set = 11 // lef set [a-z\s] \w \s \d - - Multi = 12 // lef string abcd - Ref = 13 // lef group \# - - Bol = 14 // ^ - Eol = 15 // $ - Boundary = 16 // \b - Nonboundary = 17 // \B - Beginning = 18 // \A - Start = 19 // \G - EndZ = 20 // \Z - End = 21 // \Z - - Nothing = 22 // Reject! - - // Primitive control structures - - Lazybranch = 23 // back jump straight first - Branchmark = 24 // back jump branch first for loop - Lazybranchmark = 25 // back jump straight first for loop - Nullcount = 26 // back val set counter, null mark - Setcount = 27 // back val set counter, make mark - Branchcount = 28 // back jump,limit branch++ if zero<=c impl group slots - Capsize int // number of impl group slots - FcPrefix *Prefix // the set of candidate first characters (may be null) - BmPrefix *BmPrefix // the fixed prefix string as a Boyer-Moore machine (may be null) - Anchors AnchorLoc // the set of zero-length start anchors (RegexFCD.Bol, etc) - RightToLeft bool // true if right to left -} - -func opcodeBacktracks(op InstOp) bool { - op &= Mask - - switch op { - case Oneloop, Notoneloop, Setloop, Onelazy, Notonelazy, Setlazy, Lazybranch, Branchmark, Lazybranchmark, - Nullcount, Setcount, Branchcount, Lazybranchcount, Setmark, Capturemark, Getmark, Setjump, Backjump, - Forejump, Goto: - return true - - default: - return false - } -} - -func opcodeSize(op InstOp) int { - op &= Mask - - switch op { - case Nothing, Bol, Eol, Boundary, Nonboundary, ECMABoundary, NonECMABoundary, Beginning, Start, EndZ, - End, Nullmark, Setmark, Getmark, Setjump, Backjump, Forejump, Stop: - return 1 - - case One, Notone, Multi, Ref, Testref, Goto, Nullcount, Setcount, Lazybranch, Branchmark, Lazybranchmark, - Prune, Set: - return 2 - - case Capturemark, Branchcount, Lazybranchcount, Onerep, Notonerep, Oneloop, Notoneloop, Onelazy, Notonelazy, - Setlazy, Setrep, Setloop: - return 3 - - default: - panic(fmt.Errorf("Unexpected op code: %v", op)) - } -} - -var codeStr = []string{ - "Onerep", "Notonerep", "Setrep", - "Oneloop", "Notoneloop", "Setloop", - "Onelazy", "Notonelazy", "Setlazy", - "One", "Notone", "Set", - "Multi", "Ref", - "Bol", "Eol", "Boundary", "Nonboundary", "Beginning", "Start", "EndZ", "End", - "Nothing", - "Lazybranch", "Branchmark", "Lazybranchmark", - "Nullcount", "Setcount", "Branchcount", "Lazybranchcount", - "Nullmark", "Setmark", "Capturemark", "Getmark", - "Setjump", "Backjump", "Forejump", "Testref", "Goto", - "Prune", "Stop", - "ECMABoundary", "NonECMABoundary", -} - -func operatorDescription(op InstOp) string { - desc := codeStr[op&Mask] - if (op & Ci) != 0 { - desc += "-Ci" - } - if (op & Rtl) != 0 { - desc += "-Rtl" - } - if (op & Back) != 0 { - desc += "-Back" - } - if (op & Back2) != 0 { - desc += "-Back2" - } - - return desc -} - -// OpcodeDescription is a humman readable string of the specific offset -func (c *Code) OpcodeDescription(offset int) string { - buf := &bytes.Buffer{} - - op := InstOp(c.Codes[offset]) - fmt.Fprintf(buf, "%06d ", offset) - - if opcodeBacktracks(op & Mask) { - buf.WriteString("*") - } else { - buf.WriteString(" ") - } - buf.WriteString(operatorDescription(op)) - buf.WriteString("(") - op &= Mask - - switch op { - case One, Notone, Onerep, Notonerep, Oneloop, Notoneloop, Onelazy, Notonelazy: - buf.WriteString("Ch = ") - buf.WriteString(CharDescription(rune(c.Codes[offset+1]))) - - case Set, Setrep, Setloop, Setlazy: - buf.WriteString("Set = ") - buf.WriteString(c.Sets[c.Codes[offset+1]].String()) - - case Multi: - fmt.Fprintf(buf, "String = %s", string(c.Strings[c.Codes[offset+1]])) - - case Ref, Testref: - fmt.Fprintf(buf, "Index = %d", c.Codes[offset+1]) - - case Capturemark: - fmt.Fprintf(buf, "Index = %d", c.Codes[offset+1]) - if c.Codes[offset+2] != -1 { - fmt.Fprintf(buf, ", Unindex = %d", c.Codes[offset+2]) - } - - case Nullcount, Setcount: - fmt.Fprintf(buf, "Value = %d", c.Codes[offset+1]) - - case Goto, Lazybranch, Branchmark, Lazybranchmark, Branchcount, Lazybranchcount: - fmt.Fprintf(buf, "Addr = %d", c.Codes[offset+1]) - } - - switch op { - case Onerep, Notonerep, Oneloop, Notoneloop, Onelazy, Notonelazy, Setrep, Setloop, Setlazy: - buf.WriteString(", Rep = ") - if c.Codes[offset+2] == math.MaxInt32 { - buf.WriteString("inf") - } else { - fmt.Fprintf(buf, "%d", c.Codes[offset+2]) - } - - case Branchcount, Lazybranchcount: - buf.WriteString(", Limit = ") - if c.Codes[offset+2] == math.MaxInt32 { - buf.WriteString("inf") - } else { - fmt.Fprintf(buf, "%d", c.Codes[offset+2]) - } - - } - - buf.WriteString(")") - - return buf.String() -} - -func (c *Code) Dump() string { - buf := &bytes.Buffer{} - - if c.RightToLeft { - fmt.Fprintln(buf, "Direction: right-to-left") - } else { - fmt.Fprintln(buf, "Direction: left-to-right") - } - if c.FcPrefix == nil { - fmt.Fprintln(buf, "Firstchars: n/a") - } else { - fmt.Fprintf(buf, "Firstchars: %v\n", c.FcPrefix.PrefixSet.String()) - } - - if c.BmPrefix == nil { - fmt.Fprintln(buf, "Prefix: n/a") - } else { - fmt.Fprintf(buf, "Prefix: %v\n", Escape(c.BmPrefix.String())) - } - - fmt.Fprintf(buf, "Anchors: %v\n", c.Anchors) - fmt.Fprintln(buf) - - if c.BmPrefix != nil { - fmt.Fprintln(buf, "BoyerMoore:") - fmt.Fprintln(buf, c.BmPrefix.Dump(" ")) - } - for i := 0; i < len(c.Codes); i += opcodeSize(InstOp(c.Codes[i])) { - fmt.Fprintln(buf, c.OpcodeDescription(i)) - } - - return buf.String() -} diff --git a/vendor/github.com/dlclark/regexp2/syntax/escape.go b/vendor/github.com/dlclark/regexp2/syntax/escape.go deleted file mode 100644 index 609df10731..0000000000 --- a/vendor/github.com/dlclark/regexp2/syntax/escape.go +++ /dev/null @@ -1,94 +0,0 @@ -package syntax - -import ( - "bytes" - "strconv" - "strings" - "unicode" -) - -func Escape(input string) string { - b := &bytes.Buffer{} - for _, r := range input { - escape(b, r, false) - } - return b.String() -} - -const meta = `\.+*?()|[]{}^$# ` - -func escape(b *bytes.Buffer, r rune, force bool) { - if unicode.IsPrint(r) { - if strings.IndexRune(meta, r) >= 0 || force { - b.WriteRune('\\') - } - b.WriteRune(r) - return - } - - switch r { - case '\a': - b.WriteString(`\a`) - case '\f': - b.WriteString(`\f`) - case '\n': - b.WriteString(`\n`) - case '\r': - b.WriteString(`\r`) - case '\t': - b.WriteString(`\t`) - case '\v': - b.WriteString(`\v`) - default: - if r < 0x100 { - b.WriteString(`\x`) - s := strconv.FormatInt(int64(r), 16) - if len(s) == 1 { - b.WriteRune('0') - } - b.WriteString(s) - break - } - b.WriteString(`\u`) - b.WriteString(strconv.FormatInt(int64(r), 16)) - } -} - -func Unescape(input string) (string, error) { - idx := strings.IndexRune(input, '\\') - // no slashes means no unescape needed - if idx == -1 { - return input, nil - } - - buf := bytes.NewBufferString(input[:idx]) - // get the runes for the rest of the string -- we're going full parser scan on this - - p := parser{} - p.setPattern(input[idx+1:]) - for { - if p.rightMost() { - return "", p.getErr(ErrIllegalEndEscape) - } - r, err := p.scanCharEscape() - if err != nil { - return "", err - } - buf.WriteRune(r) - // are we done? - if p.rightMost() { - return buf.String(), nil - } - - r = p.moveRightGetChar() - for r != '\\' { - buf.WriteRune(r) - if p.rightMost() { - // we're done, no more slashes - return buf.String(), nil - } - // keep scanning until we get another slash - r = p.moveRightGetChar() - } - } -} diff --git a/vendor/github.com/dlclark/regexp2/syntax/fuzz.go b/vendor/github.com/dlclark/regexp2/syntax/fuzz.go deleted file mode 100644 index ee863866db..0000000000 --- a/vendor/github.com/dlclark/regexp2/syntax/fuzz.go +++ /dev/null @@ -1,20 +0,0 @@ -// +build gofuzz - -package syntax - -// Fuzz is the input point for go-fuzz -func Fuzz(data []byte) int { - sdata := string(data) - tree, err := Parse(sdata, RegexOptions(0)) - if err != nil { - return 0 - } - - // translate it to code - _, err = Write(tree) - if err != nil { - panic(err) - } - - return 1 -} diff --git a/vendor/github.com/dlclark/regexp2/syntax/parser.go b/vendor/github.com/dlclark/regexp2/syntax/parser.go deleted file mode 100644 index 4ff0aaa836..0000000000 --- a/vendor/github.com/dlclark/regexp2/syntax/parser.go +++ /dev/null @@ -1,2262 +0,0 @@ -package syntax - -import ( - "fmt" - "math" - "os" - "sort" - "strconv" - "unicode" -) - -type RegexOptions int32 - -const ( - IgnoreCase RegexOptions = 0x0001 // "i" - Multiline = 0x0002 // "m" - ExplicitCapture = 0x0004 // "n" - Compiled = 0x0008 // "c" - Singleline = 0x0010 // "s" - IgnorePatternWhitespace = 0x0020 // "x" - RightToLeft = 0x0040 // "r" - Debug = 0x0080 // "d" - ECMAScript = 0x0100 // "e" - RE2 = 0x0200 // RE2 compat mode - Unicode = 0x0400 // "u" -) - -func optionFromCode(ch rune) RegexOptions { - // case-insensitive - switch ch { - case 'i', 'I': - return IgnoreCase - case 'r', 'R': - return RightToLeft - case 'm', 'M': - return Multiline - case 'n', 'N': - return ExplicitCapture - case 's', 'S': - return Singleline - case 'x', 'X': - return IgnorePatternWhitespace - case 'd', 'D': - return Debug - case 'e', 'E': - return ECMAScript - case 'u', 'U': - return Unicode - default: - return 0 - } -} - -// An Error describes a failure to parse a regular expression -// and gives the offending expression. -type Error struct { - Code ErrorCode - Expr string - Args []interface{} -} - -func (e *Error) Error() string { - if len(e.Args) == 0 { - return "error parsing regexp: " + e.Code.String() + " in `" + e.Expr + "`" - } - return "error parsing regexp: " + fmt.Sprintf(e.Code.String(), e.Args...) + " in `" + e.Expr + "`" -} - -// An ErrorCode describes a failure to parse a regular expression. -type ErrorCode string - -const ( - // internal issue - ErrInternalError ErrorCode = "regexp/syntax: internal error" - // Parser errors - ErrUnterminatedComment = "unterminated comment" - ErrInvalidCharRange = "invalid character class range" - ErrInvalidRepeatSize = "invalid repeat count" - ErrInvalidUTF8 = "invalid UTF-8" - ErrCaptureGroupOutOfRange = "capture group number out of range" - ErrUnexpectedParen = "unexpected )" - ErrMissingParen = "missing closing )" - ErrMissingBrace = "missing closing }" - ErrInvalidRepeatOp = "invalid nested repetition operator" - ErrMissingRepeatArgument = "missing argument to repetition operator" - ErrConditionalExpression = "illegal conditional (?(...)) expression" - ErrTooManyAlternates = "too many | in (?()|)" - ErrUnrecognizedGrouping = "unrecognized grouping construct: (%v" - ErrInvalidGroupName = "invalid group name: group names must begin with a word character and have a matching terminator" - ErrCapNumNotZero = "capture number cannot be zero" - ErrUndefinedBackRef = "reference to undefined group number %v" - ErrUndefinedNameRef = "reference to undefined group name %v" - ErrAlternationCantCapture = "alternation conditions do not capture and cannot be named" - ErrAlternationCantHaveComment = "alternation conditions cannot be comments" - ErrMalformedReference = "(?(%v) ) malformed" - ErrUndefinedReference = "(?(%v) ) reference to undefined group" - ErrIllegalEndEscape = "illegal \\ at end of pattern" - ErrMalformedSlashP = "malformed \\p{X} character escape" - ErrIncompleteSlashP = "incomplete \\p{X} character escape" - ErrUnknownSlashP = "unknown unicode category, script, or property '%v'" - ErrUnrecognizedEscape = "unrecognized escape sequence \\%v" - ErrMissingControl = "missing control character" - ErrUnrecognizedControl = "unrecognized control character" - ErrTooFewHex = "insufficient hexadecimal digits" - ErrInvalidHex = "hex values may not be larger than 0x10FFFF" - ErrMalformedNameRef = "malformed \\k<...> named back reference" - ErrBadClassInCharRange = "cannot include class \\%v in character range" - ErrUnterminatedBracket = "unterminated [] set" - ErrSubtractionMustBeLast = "a subtraction must be the last element in a character class" - ErrReversedCharRange = "[%c-%c] range in reverse order" -) - -func (e ErrorCode) String() string { - return string(e) -} - -type parser struct { - stack *regexNode - group *regexNode - alternation *regexNode - concatenation *regexNode - unit *regexNode - - patternRaw string - pattern []rune - - currentPos int - specialCase *unicode.SpecialCase - - autocap int - capcount int - captop int - capsize int - - caps map[int]int - capnames map[string]int - - capnumlist []int - capnamelist []string - - options RegexOptions - optionsStack []RegexOptions - ignoreNextParen bool -} - -const ( - maxValueDiv10 int = math.MaxInt32 / 10 - maxValueMod10 = math.MaxInt32 % 10 -) - -// Parse converts a regex string into a parse tree -func Parse(re string, op RegexOptions) (*RegexTree, error) { - p := parser{ - options: op, - caps: make(map[int]int), - } - p.setPattern(re) - - if err := p.countCaptures(); err != nil { - return nil, err - } - - p.reset(op) - root, err := p.scanRegex() - - if err != nil { - return nil, err - } - tree := &RegexTree{ - root: root, - caps: p.caps, - capnumlist: p.capnumlist, - captop: p.captop, - Capnames: p.capnames, - Caplist: p.capnamelist, - options: op, - } - - if tree.options&Debug > 0 { - os.Stdout.WriteString(tree.Dump()) - } - - return tree, nil -} - -func (p *parser) setPattern(pattern string) { - p.patternRaw = pattern - p.pattern = make([]rune, 0, len(pattern)) - - //populate our rune array to handle utf8 encoding - for _, r := range pattern { - p.pattern = append(p.pattern, r) - } -} -func (p *parser) getErr(code ErrorCode, args ...interface{}) error { - return &Error{Code: code, Expr: p.patternRaw, Args: args} -} - -func (p *parser) noteCaptureSlot(i, pos int) { - if _, ok := p.caps[i]; !ok { - // the rhs of the hashtable isn't used in the parser - p.caps[i] = pos - p.capcount++ - - if p.captop <= i { - if i == math.MaxInt32 { - p.captop = i - } else { - p.captop = i + 1 - } - } - } -} - -func (p *parser) noteCaptureName(name string, pos int) { - if p.capnames == nil { - p.capnames = make(map[string]int) - } - - if _, ok := p.capnames[name]; !ok { - p.capnames[name] = pos - p.capnamelist = append(p.capnamelist, name) - } -} - -func (p *parser) assignNameSlots() { - if p.capnames != nil { - for _, name := range p.capnamelist { - for p.isCaptureSlot(p.autocap) { - p.autocap++ - } - pos := p.capnames[name] - p.capnames[name] = p.autocap - p.noteCaptureSlot(p.autocap, pos) - - p.autocap++ - } - } - - // if the caps array has at least one gap, construct the list of used slots - if p.capcount < p.captop { - p.capnumlist = make([]int, p.capcount) - i := 0 - - for k := range p.caps { - p.capnumlist[i] = k - i++ - } - - sort.Ints(p.capnumlist) - } - - // merge capsnumlist into capnamelist - if p.capnames != nil || p.capnumlist != nil { - var oldcapnamelist []string - var next int - var k int - - if p.capnames == nil { - oldcapnamelist = nil - p.capnames = make(map[string]int) - p.capnamelist = []string{} - next = -1 - } else { - oldcapnamelist = p.capnamelist - p.capnamelist = []string{} - next = p.capnames[oldcapnamelist[0]] - } - - for i := 0; i < p.capcount; i++ { - j := i - if p.capnumlist != nil { - j = p.capnumlist[i] - } - - if next == j { - p.capnamelist = append(p.capnamelist, oldcapnamelist[k]) - k++ - - if k == len(oldcapnamelist) { - next = -1 - } else { - next = p.capnames[oldcapnamelist[k]] - } - - } else { - //feature: culture? - str := strconv.Itoa(j) - p.capnamelist = append(p.capnamelist, str) - p.capnames[str] = j - } - } - } -} - -func (p *parser) consumeAutocap() int { - r := p.autocap - p.autocap++ - return r -} - -// CountCaptures is a prescanner for deducing the slots used for -// captures by doing a partial tokenization of the pattern. -func (p *parser) countCaptures() error { - var ch rune - - p.noteCaptureSlot(0, 0) - - p.autocap = 1 - - for p.charsRight() > 0 { - pos := p.textpos() - ch = p.moveRightGetChar() - switch ch { - case '\\': - if p.charsRight() > 0 { - p.scanBackslash(true) - } - - case '#': - if p.useOptionX() { - p.moveLeft() - p.scanBlank() - } - - case '[': - p.scanCharSet(false, true) - - case ')': - if !p.emptyOptionsStack() { - p.popOptions() - } - - case '(': - if p.charsRight() >= 2 && p.rightChar(1) == '#' && p.rightChar(0) == '?' { - p.moveLeft() - p.scanBlank() - } else { - p.pushOptions() - if p.charsRight() > 0 && p.rightChar(0) == '?' { - // we have (?... - p.moveRight(1) - - if p.charsRight() > 1 && (p.rightChar(0) == '<' || p.rightChar(0) == '\'') { - // named group: (?<... or (?'... - - p.moveRight(1) - ch = p.rightChar(0) - - if ch != '0' && IsWordChar(ch) { - if ch >= '1' && ch <= '9' { - dec, err := p.scanDecimal() - if err != nil { - return err - } - p.noteCaptureSlot(dec, pos) - } else { - p.noteCaptureName(p.scanCapname(), pos) - } - } - } else if p.useRE2() && p.charsRight() > 2 && (p.rightChar(0) == 'P' && p.rightChar(1) == '<') { - // RE2-compat (?P<) - p.moveRight(2) - ch = p.rightChar(0) - if IsWordChar(ch) { - p.noteCaptureName(p.scanCapname(), pos) - } - - } else { - // (?... - - // get the options if it's an option construct (?cimsx-cimsx...) - p.scanOptions() - - if p.charsRight() > 0 { - if p.rightChar(0) == ')' { - // (?cimsx-cimsx) - p.moveRight(1) - p.popKeepOptions() - } else if p.rightChar(0) == '(' { - // alternation construct: (?(foo)yes|no) - // ignore the next paren so we don't capture the condition - p.ignoreNextParen = true - - // break from here so we don't reset ignoreNextParen - continue - } - } - } - } else { - if !p.useOptionN() && !p.ignoreNextParen { - p.noteCaptureSlot(p.consumeAutocap(), pos) - } - } - } - - p.ignoreNextParen = false - - } - } - - p.assignNameSlots() - return nil -} - -func (p *parser) reset(topopts RegexOptions) { - p.currentPos = 0 - p.autocap = 1 - p.ignoreNextParen = false - - if len(p.optionsStack) > 0 { - p.optionsStack = p.optionsStack[:0] - } - - p.options = topopts - p.stack = nil -} - -func (p *parser) scanRegex() (*regexNode, error) { - ch := '@' // nonspecial ch, means at beginning - isQuant := false - - p.startGroup(newRegexNodeMN(ntCapture, p.options, 0, -1)) - - for p.charsRight() > 0 { - wasPrevQuantifier := isQuant - isQuant = false - - if err := p.scanBlank(); err != nil { - return nil, err - } - - startpos := p.textpos() - - // move past all of the normal characters. We'll stop when we hit some kind of control character, - // or if IgnorePatternWhiteSpace is on, we'll stop when we see some whitespace. - if p.useOptionX() { - for p.charsRight() > 0 { - ch = p.rightChar(0) - //UGLY: clean up, this is ugly - if !(!isStopperX(ch) || (ch == '{' && !p.isTrueQuantifier())) { - break - } - p.moveRight(1) - } - } else { - for p.charsRight() > 0 { - ch = p.rightChar(0) - if !(!isSpecial(ch) || ch == '{' && !p.isTrueQuantifier()) { - break - } - p.moveRight(1) - } - } - - endpos := p.textpos() - - p.scanBlank() - - if p.charsRight() == 0 { - ch = '!' // nonspecial, means at end - } else if ch = p.rightChar(0); isSpecial(ch) { - isQuant = isQuantifier(ch) - p.moveRight(1) - } else { - ch = ' ' // nonspecial, means at ordinary char - } - - if startpos < endpos { - cchUnquantified := endpos - startpos - if isQuant { - cchUnquantified-- - } - wasPrevQuantifier = false - - if cchUnquantified > 0 { - p.addToConcatenate(startpos, cchUnquantified, false) - } - - if isQuant { - p.addUnitOne(p.charAt(endpos - 1)) - } - } - - switch ch { - case '!': - goto BreakOuterScan - - case ' ': - goto ContinueOuterScan - - case '[': - cc, err := p.scanCharSet(p.useOptionI(), false) - if err != nil { - return nil, err - } - p.addUnitSet(cc) - - case '(': - p.pushOptions() - - if grouper, err := p.scanGroupOpen(); err != nil { - return nil, err - } else if grouper == nil { - p.popKeepOptions() - } else { - p.pushGroup() - p.startGroup(grouper) - } - - continue - - case '|': - p.addAlternate() - goto ContinueOuterScan - - case ')': - if p.emptyStack() { - return nil, p.getErr(ErrUnexpectedParen) - } - - if err := p.addGroup(); err != nil { - return nil, err - } - if err := p.popGroup(); err != nil { - return nil, err - } - p.popOptions() - - if p.unit == nil { - goto ContinueOuterScan - } - - case '\\': - n, err := p.scanBackslash(false) - if err != nil { - return nil, err - } - p.addUnitNode(n) - - case '^': - if p.useOptionM() { - p.addUnitType(ntBol) - } else { - p.addUnitType(ntBeginning) - } - - case '$': - if p.useOptionM() { - p.addUnitType(ntEol) - } else { - p.addUnitType(ntEndZ) - } - - case '.': - if p.useOptionS() { - p.addUnitSet(AnyClass()) - } else if p.useOptionE() { - p.addUnitSet(ECMAAnyClass()) - } else { - p.addUnitNotone('\n') - } - - case '{', '*', '+', '?': - if p.unit == nil { - if wasPrevQuantifier { - return nil, p.getErr(ErrInvalidRepeatOp) - } else { - return nil, p.getErr(ErrMissingRepeatArgument) - } - } - p.moveLeft() - - default: - return nil, p.getErr(ErrInternalError) - } - - if err := p.scanBlank(); err != nil { - return nil, err - } - - if p.charsRight() > 0 { - isQuant = p.isTrueQuantifier() - } - if p.charsRight() == 0 || !isQuant { - //maintain odd C# assignment order -- not sure if required, could clean up? - p.addConcatenate() - goto ContinueOuterScan - } - - ch = p.moveRightGetChar() - - // Handle quantifiers - for p.unit != nil { - var min, max int - var lazy bool - - switch ch { - case '*': - min = 0 - max = math.MaxInt32 - - case '?': - min = 0 - max = 1 - - case '+': - min = 1 - max = math.MaxInt32 - - case '{': - { - var err error - startpos = p.textpos() - if min, err = p.scanDecimal(); err != nil { - return nil, err - } - max = min - if startpos < p.textpos() { - if p.charsRight() > 0 && p.rightChar(0) == ',' { - p.moveRight(1) - if p.charsRight() == 0 || p.rightChar(0) == '}' { - max = math.MaxInt32 - } else { - if max, err = p.scanDecimal(); err != nil { - return nil, err - } - } - } - } - - if startpos == p.textpos() || p.charsRight() == 0 || p.moveRightGetChar() != '}' { - p.addConcatenate() - p.textto(startpos - 1) - goto ContinueOuterScan - } - } - - default: - return nil, p.getErr(ErrInternalError) - } - - if err := p.scanBlank(); err != nil { - return nil, err - } - - if p.charsRight() == 0 || p.rightChar(0) != '?' { - lazy = false - } else { - p.moveRight(1) - lazy = true - } - - if min > max { - return nil, p.getErr(ErrInvalidRepeatSize) - } - - p.addConcatenate3(lazy, min, max) - } - - ContinueOuterScan: - } - -BreakOuterScan: - ; - - if !p.emptyStack() { - return nil, p.getErr(ErrMissingParen) - } - - if err := p.addGroup(); err != nil { - return nil, err - } - - return p.unit, nil - -} - -/* - * Simple parsing for replacement patterns - */ -func (p *parser) scanReplacement() (*regexNode, error) { - var c, startpos int - - p.concatenation = newRegexNode(ntConcatenate, p.options) - - for { - c = p.charsRight() - if c == 0 { - break - } - - startpos = p.textpos() - - for c > 0 && p.rightChar(0) != '$' { - p.moveRight(1) - c-- - } - - p.addToConcatenate(startpos, p.textpos()-startpos, true) - - if c > 0 { - if p.moveRightGetChar() == '$' { - n, err := p.scanDollar() - if err != nil { - return nil, err - } - p.addUnitNode(n) - } - p.addConcatenate() - } - } - - return p.concatenation, nil -} - -/* - * Scans $ patterns recognized within replacement patterns - */ -func (p *parser) scanDollar() (*regexNode, error) { - if p.charsRight() == 0 { - return newRegexNodeCh(ntOne, p.options, '$'), nil - } - - ch := p.rightChar(0) - angled := false - backpos := p.textpos() - lastEndPos := backpos - - // Note angle - - if ch == '{' && p.charsRight() > 1 { - angled = true - p.moveRight(1) - ch = p.rightChar(0) - } - - // Try to parse backreference: \1 or \{1} or \{cap} - - if ch >= '0' && ch <= '9' { - if !angled && p.useOptionE() { - capnum := -1 - newcapnum := int(ch - '0') - p.moveRight(1) - if p.isCaptureSlot(newcapnum) { - capnum = newcapnum - lastEndPos = p.textpos() - } - - for p.charsRight() > 0 { - ch = p.rightChar(0) - if ch < '0' || ch > '9' { - break - } - digit := int(ch - '0') - if newcapnum > maxValueDiv10 || (newcapnum == maxValueDiv10 && digit > maxValueMod10) { - return nil, p.getErr(ErrCaptureGroupOutOfRange) - } - - newcapnum = newcapnum*10 + digit - - p.moveRight(1) - if p.isCaptureSlot(newcapnum) { - capnum = newcapnum - lastEndPos = p.textpos() - } - } - p.textto(lastEndPos) - if capnum >= 0 { - return newRegexNodeM(ntRef, p.options, capnum), nil - } - } else { - capnum, err := p.scanDecimal() - if err != nil { - return nil, err - } - if !angled || p.charsRight() > 0 && p.moveRightGetChar() == '}' { - if p.isCaptureSlot(capnum) { - return newRegexNodeM(ntRef, p.options, capnum), nil - } - } - } - } else if angled && IsWordChar(ch) { - capname := p.scanCapname() - - if p.charsRight() > 0 && p.moveRightGetChar() == '}' { - if p.isCaptureName(capname) { - return newRegexNodeM(ntRef, p.options, p.captureSlotFromName(capname)), nil - } - } - } else if !angled { - capnum := 1 - - switch ch { - case '$': - p.moveRight(1) - return newRegexNodeCh(ntOne, p.options, '$'), nil - case '&': - capnum = 0 - case '`': - capnum = replaceLeftPortion - case '\'': - capnum = replaceRightPortion - case '+': - capnum = replaceLastGroup - case '_': - capnum = replaceWholeString - } - - if capnum != 1 { - p.moveRight(1) - return newRegexNodeM(ntRef, p.options, capnum), nil - } - } - - // unrecognized $: literalize - - p.textto(backpos) - return newRegexNodeCh(ntOne, p.options, '$'), nil -} - -// scanGroupOpen scans chars following a '(' (not counting the '('), and returns -// a RegexNode for the type of group scanned, or nil if the group -// simply changed options (?cimsx-cimsx) or was a comment (#...). -func (p *parser) scanGroupOpen() (*regexNode, error) { - var ch rune - var nt nodeType - var err error - close := '>' - start := p.textpos() - - // just return a RegexNode if we have: - // 1. "(" followed by nothing - // 2. "(x" where x != ? - // 3. "(?)" - if p.charsRight() == 0 || p.rightChar(0) != '?' || (p.rightChar(0) == '?' && (p.charsRight() > 1 && p.rightChar(1) == ')')) { - if p.useOptionN() || p.ignoreNextParen { - p.ignoreNextParen = false - return newRegexNode(ntGroup, p.options), nil - } - return newRegexNodeMN(ntCapture, p.options, p.consumeAutocap(), -1), nil - } - - p.moveRight(1) - - for { - if p.charsRight() == 0 { - break - } - - switch ch = p.moveRightGetChar(); ch { - case ':': - nt = ntGroup - - case '=': - p.options &= ^RightToLeft - nt = ntRequire - - case '!': - p.options &= ^RightToLeft - nt = ntPrevent - - case '>': - nt = ntGreedy - - case '\'': - close = '\'' - fallthrough - - case '<': - if p.charsRight() == 0 { - goto BreakRecognize - } - - switch ch = p.moveRightGetChar(); ch { - case '=': - if close == '\'' { - goto BreakRecognize - } - - p.options |= RightToLeft - nt = ntRequire - - case '!': - if close == '\'' { - goto BreakRecognize - } - - p.options |= RightToLeft - nt = ntPrevent - - default: - p.moveLeft() - capnum := -1 - uncapnum := -1 - proceed := false - - // grab part before - - - if ch >= '0' && ch <= '9' { - if capnum, err = p.scanDecimal(); err != nil { - return nil, err - } - - if !p.isCaptureSlot(capnum) { - capnum = -1 - } - - // check if we have bogus characters after the number - if p.charsRight() > 0 && !(p.rightChar(0) == close || p.rightChar(0) == '-') { - return nil, p.getErr(ErrInvalidGroupName) - } - if capnum == 0 { - return nil, p.getErr(ErrCapNumNotZero) - } - } else if IsWordChar(ch) { - capname := p.scanCapname() - - if p.isCaptureName(capname) { - capnum = p.captureSlotFromName(capname) - } - - // check if we have bogus character after the name - if p.charsRight() > 0 && !(p.rightChar(0) == close || p.rightChar(0) == '-') { - return nil, p.getErr(ErrInvalidGroupName) - } - } else if ch == '-' { - proceed = true - } else { - // bad group name - starts with something other than a word character and isn't a number - return nil, p.getErr(ErrInvalidGroupName) - } - - // grab part after - if any - - if (capnum != -1 || proceed == true) && p.charsRight() > 0 && p.rightChar(0) == '-' { - p.moveRight(1) - - //no more chars left, no closing char, etc - if p.charsRight() == 0 { - return nil, p.getErr(ErrInvalidGroupName) - } - - ch = p.rightChar(0) - if ch >= '0' && ch <= '9' { - if uncapnum, err = p.scanDecimal(); err != nil { - return nil, err - } - - if !p.isCaptureSlot(uncapnum) { - return nil, p.getErr(ErrUndefinedBackRef, uncapnum) - } - - // check if we have bogus characters after the number - if p.charsRight() > 0 && p.rightChar(0) != close { - return nil, p.getErr(ErrInvalidGroupName) - } - } else if IsWordChar(ch) { - uncapname := p.scanCapname() - - if !p.isCaptureName(uncapname) { - return nil, p.getErr(ErrUndefinedNameRef, uncapname) - } - uncapnum = p.captureSlotFromName(uncapname) - - // check if we have bogus character after the name - if p.charsRight() > 0 && p.rightChar(0) != close { - return nil, p.getErr(ErrInvalidGroupName) - } - } else { - // bad group name - starts with something other than a word character and isn't a number - return nil, p.getErr(ErrInvalidGroupName) - } - } - - // actually make the node - - if (capnum != -1 || uncapnum != -1) && p.charsRight() > 0 && p.moveRightGetChar() == close { - return newRegexNodeMN(ntCapture, p.options, capnum, uncapnum), nil - } - goto BreakRecognize - } - - case '(': - // alternation construct (?(...) | ) - - parenPos := p.textpos() - if p.charsRight() > 0 { - ch = p.rightChar(0) - - // check if the alternation condition is a backref - if ch >= '0' && ch <= '9' { - var capnum int - if capnum, err = p.scanDecimal(); err != nil { - return nil, err - } - if p.charsRight() > 0 && p.moveRightGetChar() == ')' { - if p.isCaptureSlot(capnum) { - return newRegexNodeM(ntTestref, p.options, capnum), nil - } - return nil, p.getErr(ErrUndefinedReference, capnum) - } - - return nil, p.getErr(ErrMalformedReference, capnum) - - } else if IsWordChar(ch) { - capname := p.scanCapname() - - if p.isCaptureName(capname) && p.charsRight() > 0 && p.moveRightGetChar() == ')' { - return newRegexNodeM(ntTestref, p.options, p.captureSlotFromName(capname)), nil - } - } - } - // not a backref - nt = ntTestgroup - p.textto(parenPos - 1) // jump to the start of the parentheses - p.ignoreNextParen = true // but make sure we don't try to capture the insides - - charsRight := p.charsRight() - if charsRight >= 3 && p.rightChar(1) == '?' { - rightchar2 := p.rightChar(2) - // disallow comments in the condition - if rightchar2 == '#' { - return nil, p.getErr(ErrAlternationCantHaveComment) - } - - // disallow named capture group (?<..>..) in the condition - if rightchar2 == '\'' { - return nil, p.getErr(ErrAlternationCantCapture) - } - - if charsRight >= 4 && (rightchar2 == '<' && p.rightChar(3) != '!' && p.rightChar(3) != '=') { - return nil, p.getErr(ErrAlternationCantCapture) - } - } - - case 'P': - if p.useRE2() { - // support for P syntax - if p.charsRight() < 3 { - goto BreakRecognize - } - - ch = p.moveRightGetChar() - if ch != '<' { - goto BreakRecognize - } - - ch = p.moveRightGetChar() - p.moveLeft() - - if IsWordChar(ch) { - capnum := -1 - capname := p.scanCapname() - - if p.isCaptureName(capname) { - capnum = p.captureSlotFromName(capname) - } - - // check if we have bogus character after the name - if p.charsRight() > 0 && p.rightChar(0) != '>' { - return nil, p.getErr(ErrInvalidGroupName) - } - - // actually make the node - - if capnum != -1 && p.charsRight() > 0 && p.moveRightGetChar() == '>' { - return newRegexNodeMN(ntCapture, p.options, capnum, -1), nil - } - goto BreakRecognize - - } else { - // bad group name - starts with something other than a word character and isn't a number - return nil, p.getErr(ErrInvalidGroupName) - } - } - // if we're not using RE2 compat mode then - // we just behave like normal - fallthrough - - default: - p.moveLeft() - - nt = ntGroup - // disallow options in the children of a testgroup node - if p.group.t != ntTestgroup { - p.scanOptions() - } - if p.charsRight() == 0 { - goto BreakRecognize - } - - if ch = p.moveRightGetChar(); ch == ')' { - return nil, nil - } - - if ch != ':' { - goto BreakRecognize - } - - } - - return newRegexNode(nt, p.options), nil - } - -BreakRecognize: - - // break Recognize comes here - - return nil, p.getErr(ErrUnrecognizedGrouping, string(p.pattern[start:p.textpos()])) -} - -// scans backslash specials and basics -func (p *parser) scanBackslash(scanOnly bool) (*regexNode, error) { - - if p.charsRight() == 0 { - return nil, p.getErr(ErrIllegalEndEscape) - } - - switch ch := p.rightChar(0); ch { - case 'b', 'B', 'A', 'G', 'Z', 'z': - p.moveRight(1) - return newRegexNode(p.typeFromCode(ch), p.options), nil - - case 'w': - p.moveRight(1) - if p.useOptionE() || p.useRE2() { - return newRegexNodeSet(ntSet, p.options, ECMAWordClass()), nil - } - return newRegexNodeSet(ntSet, p.options, WordClass()), nil - - case 'W': - p.moveRight(1) - if p.useOptionE() || p.useRE2() { - return newRegexNodeSet(ntSet, p.options, NotECMAWordClass()), nil - } - return newRegexNodeSet(ntSet, p.options, NotWordClass()), nil - - case 's': - p.moveRight(1) - if p.useOptionE() { - return newRegexNodeSet(ntSet, p.options, ECMASpaceClass()), nil - } else if p.useRE2() { - return newRegexNodeSet(ntSet, p.options, RE2SpaceClass()), nil - } - return newRegexNodeSet(ntSet, p.options, SpaceClass()), nil - - case 'S': - p.moveRight(1) - if p.useOptionE() { - return newRegexNodeSet(ntSet, p.options, NotECMASpaceClass()), nil - } else if p.useRE2() { - return newRegexNodeSet(ntSet, p.options, NotRE2SpaceClass()), nil - } - return newRegexNodeSet(ntSet, p.options, NotSpaceClass()), nil - - case 'd': - p.moveRight(1) - if p.useOptionE() || p.useRE2() { - return newRegexNodeSet(ntSet, p.options, ECMADigitClass()), nil - } - return newRegexNodeSet(ntSet, p.options, DigitClass()), nil - - case 'D': - p.moveRight(1) - if p.useOptionE() || p.useRE2() { - return newRegexNodeSet(ntSet, p.options, NotECMADigitClass()), nil - } - return newRegexNodeSet(ntSet, p.options, NotDigitClass()), nil - - case 'p', 'P': - p.moveRight(1) - prop, err := p.parseProperty() - if err != nil { - return nil, err - } - cc := &CharSet{} - cc.addCategory(prop, (ch != 'p'), p.useOptionI(), p.patternRaw) - if p.useOptionI() { - cc.addLowercase() - } - - return newRegexNodeSet(ntSet, p.options, cc), nil - - default: - return p.scanBasicBackslash(scanOnly) - } -} - -// Scans \-style backreferences and character escapes -func (p *parser) scanBasicBackslash(scanOnly bool) (*regexNode, error) { - if p.charsRight() == 0 { - return nil, p.getErr(ErrIllegalEndEscape) - } - angled := false - k := false - close := '\x00' - - backpos := p.textpos() - ch := p.rightChar(0) - - // Allow \k instead of \, which is now deprecated. - - // According to ECMAScript specification, \k is only parsed as a named group reference if - // there is at least one group name in the regexp. - // See https://www.ecma-international.org/ecma-262/#sec-isvalidregularexpressionliteral, step 7. - // Note, during the first (scanOnly) run we may not have all group names scanned, but that's ok. - if ch == 'k' && (!p.useOptionE() || len(p.capnames) > 0) { - if p.charsRight() >= 2 { - p.moveRight(1) - ch = p.moveRightGetChar() - - if ch == '<' || (!p.useOptionE() && ch == '\'') { // No support for \k'name' in ECMAScript - angled = true - if ch == '\'' { - close = '\'' - } else { - close = '>' - } - } - } - - if !angled || p.charsRight() <= 0 { - return nil, p.getErr(ErrMalformedNameRef) - } - - ch = p.rightChar(0) - k = true - - } else if !p.useOptionE() && (ch == '<' || ch == '\'') && p.charsRight() > 1 { // Note angle without \g - angled = true - if ch == '\'' { - close = '\'' - } else { - close = '>' - } - - p.moveRight(1) - ch = p.rightChar(0) - } - - // Try to parse backreference: \<1> or \ - - if angled && ch >= '0' && ch <= '9' { - capnum, err := p.scanDecimal() - if err != nil { - return nil, err - } - - if p.charsRight() > 0 && p.moveRightGetChar() == close { - if p.isCaptureSlot(capnum) { - return newRegexNodeM(ntRef, p.options, capnum), nil - } - return nil, p.getErr(ErrUndefinedBackRef, capnum) - } - } else if !angled && ch >= '1' && ch <= '9' { // Try to parse backreference or octal: \1 - capnum, err := p.scanDecimal() - if err != nil { - return nil, err - } - - if scanOnly { - return nil, nil - } - - if p.isCaptureSlot(capnum) { - return newRegexNodeM(ntRef, p.options, capnum), nil - } - if capnum <= 9 && !p.useOptionE() { - return nil, p.getErr(ErrUndefinedBackRef, capnum) - } - - } else if angled { - capname := p.scanCapname() - - if capname != "" && p.charsRight() > 0 && p.moveRightGetChar() == close { - - if scanOnly { - return nil, nil - } - - if p.isCaptureName(capname) { - return newRegexNodeM(ntRef, p.options, p.captureSlotFromName(capname)), nil - } - return nil, p.getErr(ErrUndefinedNameRef, capname) - } else { - if k { - return nil, p.getErr(ErrMalformedNameRef) - } - } - } - - // Not backreference: must be char code - - p.textto(backpos) - ch, err := p.scanCharEscape() - if err != nil { - return nil, err - } - - if scanOnly { - return nil, nil - } - - if p.useOptionI() { - ch = unicode.ToLower(ch) - } - - return newRegexNodeCh(ntOne, p.options, ch), nil -} - -// Scans X for \p{X} or \P{X} -func (p *parser) parseProperty() (string, error) { - // RE2 and PCRE supports \pX syntax (no {} and only 1 letter unicode cats supported) - // since this is purely additive syntax it's not behind a flag - if p.charsRight() >= 1 && p.rightChar(0) != '{' { - ch := string(p.moveRightGetChar()) - // check if it's a valid cat - if !isValidUnicodeCat(ch) { - return "", p.getErr(ErrUnknownSlashP, ch) - } - return ch, nil - } - - if p.charsRight() < 3 { - return "", p.getErr(ErrIncompleteSlashP) - } - ch := p.moveRightGetChar() - if ch != '{' { - return "", p.getErr(ErrMalformedSlashP) - } - - startpos := p.textpos() - for p.charsRight() > 0 { - ch = p.moveRightGetChar() - if !(IsWordChar(ch) || ch == '-') { - p.moveLeft() - break - } - } - capname := string(p.pattern[startpos:p.textpos()]) - - if p.charsRight() == 0 || p.moveRightGetChar() != '}' { - return "", p.getErr(ErrIncompleteSlashP) - } - - if !isValidUnicodeCat(capname) { - return "", p.getErr(ErrUnknownSlashP, capname) - } - - return capname, nil -} - -// Returns ReNode type for zero-length assertions with a \ code. -func (p *parser) typeFromCode(ch rune) nodeType { - switch ch { - case 'b': - if p.useOptionE() { - return ntECMABoundary - } - return ntBoundary - case 'B': - if p.useOptionE() { - return ntNonECMABoundary - } - return ntNonboundary - case 'A': - return ntBeginning - case 'G': - return ntStart - case 'Z': - return ntEndZ - case 'z': - return ntEnd - default: - return ntNothing - } -} - -// Scans whitespace or x-mode comments. -func (p *parser) scanBlank() error { - if p.useOptionX() { - for { - for p.charsRight() > 0 && isSpace(p.rightChar(0)) { - p.moveRight(1) - } - - if p.charsRight() == 0 { - break - } - - if p.rightChar(0) == '#' { - for p.charsRight() > 0 && p.rightChar(0) != '\n' { - p.moveRight(1) - } - } else if p.charsRight() >= 3 && p.rightChar(2) == '#' && - p.rightChar(1) == '?' && p.rightChar(0) == '(' { - for p.charsRight() > 0 && p.rightChar(0) != ')' { - p.moveRight(1) - } - if p.charsRight() == 0 { - return p.getErr(ErrUnterminatedComment) - } - p.moveRight(1) - } else { - break - } - } - } else { - for { - if p.charsRight() < 3 || p.rightChar(2) != '#' || - p.rightChar(1) != '?' || p.rightChar(0) != '(' { - return nil - } - - for p.charsRight() > 0 && p.rightChar(0) != ')' { - p.moveRight(1) - } - if p.charsRight() == 0 { - return p.getErr(ErrUnterminatedComment) - } - p.moveRight(1) - } - } - return nil -} - -func (p *parser) scanCapname() string { - startpos := p.textpos() - - for p.charsRight() > 0 { - if !IsWordChar(p.moveRightGetChar()) { - p.moveLeft() - break - } - } - - return string(p.pattern[startpos:p.textpos()]) -} - -// Scans contents of [] (not including []'s), and converts to a set. -func (p *parser) scanCharSet(caseInsensitive, scanOnly bool) (*CharSet, error) { - ch := '\x00' - chPrev := '\x00' - inRange := false - firstChar := true - closed := false - - var cc *CharSet - if !scanOnly { - cc = &CharSet{} - } - - if p.charsRight() > 0 && p.rightChar(0) == '^' { - p.moveRight(1) - if !scanOnly { - cc.negate = true - } - } - - for ; p.charsRight() > 0; firstChar = false { - fTranslatedChar := false - ch = p.moveRightGetChar() - if ch == ']' { - if !firstChar { - closed = true - break - } else if p.useOptionE() { - if !scanOnly { - cc.addRanges(NoneClass().ranges) - } - closed = true - break - } - - } else if ch == '\\' && p.charsRight() > 0 { - switch ch = p.moveRightGetChar(); ch { - case 'D', 'd': - if !scanOnly { - if inRange { - return nil, p.getErr(ErrBadClassInCharRange, ch) - } - cc.addDigit(p.useOptionE() || p.useRE2(), ch == 'D', p.patternRaw) - } - continue - - case 'S', 's': - if !scanOnly { - if inRange { - return nil, p.getErr(ErrBadClassInCharRange, ch) - } - cc.addSpace(p.useOptionE(), p.useRE2(), ch == 'S') - } - continue - - case 'W', 'w': - if !scanOnly { - if inRange { - return nil, p.getErr(ErrBadClassInCharRange, ch) - } - - cc.addWord(p.useOptionE() || p.useRE2(), ch == 'W') - } - continue - - case 'p', 'P': - if !scanOnly { - if inRange { - return nil, p.getErr(ErrBadClassInCharRange, ch) - } - prop, err := p.parseProperty() - if err != nil { - return nil, err - } - cc.addCategory(prop, (ch != 'p'), caseInsensitive, p.patternRaw) - } else { - p.parseProperty() - } - - continue - - case '-': - if !scanOnly { - cc.addRange(ch, ch) - } - continue - - default: - p.moveLeft() - var err error - ch, err = p.scanCharEscape() // non-literal character - if err != nil { - return nil, err - } - fTranslatedChar = true - break // this break will only break out of the switch - } - } else if ch == '[' { - // This is code for Posix style properties - [:Ll:] or [:IsTibetan:]. - // It currently doesn't do anything other than skip the whole thing! - if p.charsRight() > 0 && p.rightChar(0) == ':' && !inRange { - savePos := p.textpos() - - p.moveRight(1) - negate := false - if p.charsRight() > 1 && p.rightChar(0) == '^' { - negate = true - p.moveRight(1) - } - - nm := p.scanCapname() // snag the name - if !scanOnly && p.useRE2() { - // look up the name since these are valid for RE2 - // add the group based on the name - if ok := cc.addNamedASCII(nm, negate); !ok { - return nil, p.getErr(ErrInvalidCharRange) - } - } - if p.charsRight() < 2 || p.moveRightGetChar() != ':' || p.moveRightGetChar() != ']' { - p.textto(savePos) - } else if p.useRE2() { - // move on - continue - } - } - } - - if inRange { - inRange = false - if !scanOnly { - if ch == '[' && !fTranslatedChar && !firstChar { - // We thought we were in a range, but we're actually starting a subtraction. - // In that case, we'll add chPrev to our char class, skip the opening [, and - // scan the new character class recursively. - cc.addChar(chPrev) - sub, err := p.scanCharSet(caseInsensitive, false) - if err != nil { - return nil, err - } - cc.addSubtraction(sub) - - if p.charsRight() > 0 && p.rightChar(0) != ']' { - return nil, p.getErr(ErrSubtractionMustBeLast) - } - } else { - // a regular range, like a-z - if chPrev > ch { - return nil, p.getErr(ErrReversedCharRange, chPrev, ch) - } - cc.addRange(chPrev, ch) - } - } - } else if p.charsRight() >= 2 && p.rightChar(0) == '-' && p.rightChar(1) != ']' { - // this could be the start of a range - chPrev = ch - inRange = true - p.moveRight(1) - } else if p.charsRight() >= 1 && ch == '-' && !fTranslatedChar && p.rightChar(0) == '[' && !firstChar { - // we aren't in a range, and now there is a subtraction. Usually this happens - // only when a subtraction follows a range, like [a-z-[b]] - if !scanOnly { - p.moveRight(1) - sub, err := p.scanCharSet(caseInsensitive, false) - if err != nil { - return nil, err - } - cc.addSubtraction(sub) - - if p.charsRight() > 0 && p.rightChar(0) != ']' { - return nil, p.getErr(ErrSubtractionMustBeLast) - } - } else { - p.moveRight(1) - p.scanCharSet(caseInsensitive, true) - } - } else { - if !scanOnly { - cc.addRange(ch, ch) - } - } - } - - if !closed { - return nil, p.getErr(ErrUnterminatedBracket) - } - - if !scanOnly && caseInsensitive { - cc.addLowercase() - } - - return cc, nil -} - -// Scans any number of decimal digits (pegs value at 2^31-1 if too large) -func (p *parser) scanDecimal() (int, error) { - i := 0 - var d int - - for p.charsRight() > 0 { - d = int(p.rightChar(0) - '0') - if d < 0 || d > 9 { - break - } - p.moveRight(1) - - if i > maxValueDiv10 || (i == maxValueDiv10 && d > maxValueMod10) { - return 0, p.getErr(ErrCaptureGroupOutOfRange) - } - - i *= 10 - i += d - } - - return int(i), nil -} - -// Returns true for options allowed only at the top level -func isOnlyTopOption(option RegexOptions) bool { - return option == RightToLeft || option == ECMAScript || option == RE2 -} - -// Scans cimsx-cimsx option string, stops at the first unrecognized char. -func (p *parser) scanOptions() { - - for off := false; p.charsRight() > 0; p.moveRight(1) { - ch := p.rightChar(0) - - if ch == '-' { - off = true - } else if ch == '+' { - off = false - } else { - option := optionFromCode(ch) - if option == 0 || isOnlyTopOption(option) { - return - } - - if off { - p.options &= ^option - } else { - p.options |= option - } - } - } -} - -// Scans \ code for escape codes that map to single unicode chars. -func (p *parser) scanCharEscape() (r rune, err error) { - - ch := p.moveRightGetChar() - - if ch >= '0' && ch <= '7' { - p.moveLeft() - return p.scanOctal(), nil - } - - pos := p.textpos() - - switch ch { - case 'x': - // support for \x{HEX} syntax from Perl and PCRE - if p.charsRight() > 0 && p.rightChar(0) == '{' { - if p.useOptionE() { - return ch, nil - } - p.moveRight(1) - return p.scanHexUntilBrace() - } else { - r, err = p.scanHex(2) - } - case 'u': - // ECMAscript suppot \u{HEX} only if `u` is also set - if p.useOptionE() && p.useOptionU() && p.charsRight() > 0 && p.rightChar(0) == '{' { - p.moveRight(1) - return p.scanHexUntilBrace() - } else { - r, err = p.scanHex(4) - } - case 'a': - return '\u0007', nil - case 'b': - return '\b', nil - case 'e': - return '\u001B', nil - case 'f': - return '\f', nil - case 'n': - return '\n', nil - case 'r': - return '\r', nil - case 't': - return '\t', nil - case 'v': - return '\u000B', nil - case 'c': - r, err = p.scanControl() - default: - if !p.useOptionE() && !p.useRE2() && IsWordChar(ch) { - return 0, p.getErr(ErrUnrecognizedEscape, string(ch)) - } - return ch, nil - } - if err != nil && p.useOptionE() { - p.textto(pos) - return ch, nil - } - return -} - -// Grabs and converts an ascii control character -func (p *parser) scanControl() (rune, error) { - if p.charsRight() <= 0 { - return 0, p.getErr(ErrMissingControl) - } - - ch := p.moveRightGetChar() - - // \ca interpreted as \cA - - if ch >= 'a' && ch <= 'z' { - ch = (ch - ('a' - 'A')) - } - ch = (ch - '@') - if ch >= 0 && ch < ' ' { - return ch, nil - } - - return 0, p.getErr(ErrUnrecognizedControl) - -} - -// Scan hex digits until we hit a closing brace. -// Non-hex digits, hex value too large for UTF-8, or running out of chars are errors -func (p *parser) scanHexUntilBrace() (rune, error) { - // PCRE spec reads like unlimited hex digits are allowed, but unicode has a limit - // so we can enforce that - i := 0 - hasContent := false - - for p.charsRight() > 0 { - ch := p.moveRightGetChar() - if ch == '}' { - // hit our close brace, we're done here - // prevent \x{} - if !hasContent { - return 0, p.getErr(ErrTooFewHex) - } - return rune(i), nil - } - hasContent = true - // no brace needs to be hex digit - d := hexDigit(ch) - if d < 0 { - return 0, p.getErr(ErrMissingBrace) - } - - i *= 0x10 - i += d - - if i > unicode.MaxRune { - return 0, p.getErr(ErrInvalidHex) - } - } - - // we only make it here if we run out of digits without finding the brace - return 0, p.getErr(ErrMissingBrace) -} - -// Scans exactly c hex digits (c=2 for \xFF, c=4 for \uFFFF) -func (p *parser) scanHex(c int) (rune, error) { - - i := 0 - - if p.charsRight() >= c { - for c > 0 { - d := hexDigit(p.moveRightGetChar()) - if d < 0 { - break - } - i *= 0x10 - i += d - c-- - } - } - - if c > 0 { - return 0, p.getErr(ErrTooFewHex) - } - - return rune(i), nil -} - -// Returns n <= 0xF for a hex digit. -func hexDigit(ch rune) int { - - if d := uint(ch - '0'); d <= 9 { - return int(d) - } - - if d := uint(ch - 'a'); d <= 5 { - return int(d + 0xa) - } - - if d := uint(ch - 'A'); d <= 5 { - return int(d + 0xa) - } - - return -1 -} - -// Scans up to three octal digits (stops before exceeding 0377). -func (p *parser) scanOctal() rune { - // Consume octal chars only up to 3 digits and value 0377 - - c := 3 - - if c > p.charsRight() { - c = p.charsRight() - } - - //we know the first char is good because the caller had to check - i := 0 - d := int(p.rightChar(0) - '0') - for c > 0 && d <= 7 && d >= 0 { - if i >= 0x20 && p.useOptionE() { - break - } - i *= 8 - i += d - c-- - - p.moveRight(1) - if !p.rightMost() { - d = int(p.rightChar(0) - '0') - } - } - - // Octal codes only go up to 255. Any larger and the behavior that Perl follows - // is simply to truncate the high bits. - i &= 0xFF - - return rune(i) -} - -// Returns the current parsing position. -func (p *parser) textpos() int { - return p.currentPos -} - -// Zaps to a specific parsing position. -func (p *parser) textto(pos int) { - p.currentPos = pos -} - -// Returns the char at the right of the current parsing position and advances to the right. -func (p *parser) moveRightGetChar() rune { - ch := p.pattern[p.currentPos] - p.currentPos++ - return ch -} - -// Moves the current position to the right. -func (p *parser) moveRight(i int) { - // default would be 1 - p.currentPos += i -} - -// Moves the current parsing position one to the left. -func (p *parser) moveLeft() { - p.currentPos-- -} - -// Returns the char left of the current parsing position. -func (p *parser) charAt(i int) rune { - return p.pattern[i] -} - -// Returns the char i chars right of the current parsing position. -func (p *parser) rightChar(i int) rune { - // default would be 0 - return p.pattern[p.currentPos+i] -} - -// Number of characters to the right of the current parsing position. -func (p *parser) charsRight() int { - return len(p.pattern) - p.currentPos -} - -func (p *parser) rightMost() bool { - return p.currentPos == len(p.pattern) -} - -// Looks up the slot number for a given name -func (p *parser) captureSlotFromName(capname string) int { - return p.capnames[capname] -} - -// True if the capture slot was noted -func (p *parser) isCaptureSlot(i int) bool { - if p.caps != nil { - _, ok := p.caps[i] - return ok - } - - return (i >= 0 && i < p.capsize) -} - -// Looks up the slot number for a given name -func (p *parser) isCaptureName(capname string) bool { - if p.capnames == nil { - return false - } - - _, ok := p.capnames[capname] - return ok -} - -// option shortcuts - -// True if N option disabling '(' autocapture is on. -func (p *parser) useOptionN() bool { - return (p.options & ExplicitCapture) != 0 -} - -// True if I option enabling case-insensitivity is on. -func (p *parser) useOptionI() bool { - return (p.options & IgnoreCase) != 0 -} - -// True if M option altering meaning of $ and ^ is on. -func (p *parser) useOptionM() bool { - return (p.options & Multiline) != 0 -} - -// True if S option altering meaning of . is on. -func (p *parser) useOptionS() bool { - return (p.options & Singleline) != 0 -} - -// True if X option enabling whitespace/comment mode is on. -func (p *parser) useOptionX() bool { - return (p.options & IgnorePatternWhitespace) != 0 -} - -// True if E option enabling ECMAScript behavior on. -func (p *parser) useOptionE() bool { - return (p.options & ECMAScript) != 0 -} - -// true to use RE2 compatibility parsing behavior. -func (p *parser) useRE2() bool { - return (p.options & RE2) != 0 -} - -// True if U option enabling ECMAScript's Unicode behavior on. -func (p *parser) useOptionU() bool { - return (p.options & Unicode) != 0 -} - -// True if options stack is empty. -func (p *parser) emptyOptionsStack() bool { - return len(p.optionsStack) == 0 -} - -// Finish the current quantifiable (when a quantifier is not found or is not possible) -func (p *parser) addConcatenate() { - // The first (| inside a Testgroup group goes directly to the group - p.concatenation.addChild(p.unit) - p.unit = nil -} - -// Finish the current quantifiable (when a quantifier is found) -func (p *parser) addConcatenate3(lazy bool, min, max int) { - p.concatenation.addChild(p.unit.makeQuantifier(lazy, min, max)) - p.unit = nil -} - -// Sets the current unit to a single char node -func (p *parser) addUnitOne(ch rune) { - if p.useOptionI() { - ch = unicode.ToLower(ch) - } - - p.unit = newRegexNodeCh(ntOne, p.options, ch) -} - -// Sets the current unit to a single inverse-char node -func (p *parser) addUnitNotone(ch rune) { - if p.useOptionI() { - ch = unicode.ToLower(ch) - } - - p.unit = newRegexNodeCh(ntNotone, p.options, ch) -} - -// Sets the current unit to a single set node -func (p *parser) addUnitSet(set *CharSet) { - p.unit = newRegexNodeSet(ntSet, p.options, set) -} - -// Sets the current unit to a subtree -func (p *parser) addUnitNode(node *regexNode) { - p.unit = node -} - -// Sets the current unit to an assertion of the specified type -func (p *parser) addUnitType(t nodeType) { - p.unit = newRegexNode(t, p.options) -} - -// Finish the current group (in response to a ')' or end) -func (p *parser) addGroup() error { - if p.group.t == ntTestgroup || p.group.t == ntTestref { - p.group.addChild(p.concatenation.reverseLeft()) - if (p.group.t == ntTestref && len(p.group.children) > 2) || len(p.group.children) > 3 { - return p.getErr(ErrTooManyAlternates) - } - } else { - p.alternation.addChild(p.concatenation.reverseLeft()) - p.group.addChild(p.alternation) - } - - p.unit = p.group - return nil -} - -// Pops the option stack, but keeps the current options unchanged. -func (p *parser) popKeepOptions() { - lastIdx := len(p.optionsStack) - 1 - p.optionsStack = p.optionsStack[:lastIdx] -} - -// Recalls options from the stack. -func (p *parser) popOptions() { - lastIdx := len(p.optionsStack) - 1 - // get the last item on the stack and then remove it by reslicing - p.options = p.optionsStack[lastIdx] - p.optionsStack = p.optionsStack[:lastIdx] -} - -// Saves options on a stack. -func (p *parser) pushOptions() { - p.optionsStack = append(p.optionsStack, p.options) -} - -// Add a string to the last concatenate. -func (p *parser) addToConcatenate(pos, cch int, isReplacement bool) { - var node *regexNode - - if cch == 0 { - return - } - - if cch > 1 { - str := make([]rune, cch) - copy(str, p.pattern[pos:pos+cch]) - - if p.useOptionI() && !isReplacement { - // We do the ToLower character by character for consistency. With surrogate chars, doing - // a ToLower on the entire string could actually change the surrogate pair. This is more correct - // linguistically, but since Regex doesn't support surrogates, it's more important to be - // consistent. - for i := 0; i < len(str); i++ { - str[i] = unicode.ToLower(str[i]) - } - } - - node = newRegexNodeStr(ntMulti, p.options, str) - } else { - ch := p.charAt(pos) - - if p.useOptionI() && !isReplacement { - ch = unicode.ToLower(ch) - } - - node = newRegexNodeCh(ntOne, p.options, ch) - } - - p.concatenation.addChild(node) -} - -// Push the parser state (in response to an open paren) -func (p *parser) pushGroup() { - p.group.next = p.stack - p.alternation.next = p.group - p.concatenation.next = p.alternation - p.stack = p.concatenation -} - -// Remember the pushed state (in response to a ')') -func (p *parser) popGroup() error { - p.concatenation = p.stack - p.alternation = p.concatenation.next - p.group = p.alternation.next - p.stack = p.group.next - - // The first () inside a Testgroup group goes directly to the group - if p.group.t == ntTestgroup && len(p.group.children) == 0 { - if p.unit == nil { - return p.getErr(ErrConditionalExpression) - } - - p.group.addChild(p.unit) - p.unit = nil - } - return nil -} - -// True if the group stack is empty. -func (p *parser) emptyStack() bool { - return p.stack == nil -} - -// Start a new round for the parser state (in response to an open paren or string start) -func (p *parser) startGroup(openGroup *regexNode) { - p.group = openGroup - p.alternation = newRegexNode(ntAlternate, p.options) - p.concatenation = newRegexNode(ntConcatenate, p.options) -} - -// Finish the current concatenation (in response to a |) -func (p *parser) addAlternate() { - // The | parts inside a Testgroup group go directly to the group - - if p.group.t == ntTestgroup || p.group.t == ntTestref { - p.group.addChild(p.concatenation.reverseLeft()) - } else { - p.alternation.addChild(p.concatenation.reverseLeft()) - } - - p.concatenation = newRegexNode(ntConcatenate, p.options) -} - -// For categorizing ascii characters. - -const ( - Q byte = 5 // quantifier - S = 4 // ordinary stopper - Z = 3 // ScanBlank stopper - X = 2 // whitespace - E = 1 // should be escaped -) - -var _category = []byte{ - //01 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F - 0, 0, 0, 0, 0, 0, 0, 0, 0, X, X, X, X, X, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - // ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? - X, 0, 0, Z, S, 0, 0, 0, S, S, Q, Q, 0, 0, S, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Q, - //@A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, S, S, 0, S, 0, - //'a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Q, S, 0, 0, 0, -} - -func isSpace(ch rune) bool { - return (ch <= ' ' && _category[ch] == X) -} - -// Returns true for those characters that terminate a string of ordinary chars. -func isSpecial(ch rune) bool { - return (ch <= '|' && _category[ch] >= S) -} - -// Returns true for those characters that terminate a string of ordinary chars. -func isStopperX(ch rune) bool { - return (ch <= '|' && _category[ch] >= X) -} - -// Returns true for those characters that begin a quantifier. -func isQuantifier(ch rune) bool { - return (ch <= '{' && _category[ch] >= Q) -} - -func (p *parser) isTrueQuantifier() bool { - nChars := p.charsRight() - if nChars == 0 { - return false - } - - startpos := p.textpos() - ch := p.charAt(startpos) - if ch != '{' { - return ch <= '{' && _category[ch] >= Q - } - - //UGLY: this is ugly -- the original code was ugly too - pos := startpos - for { - nChars-- - if nChars <= 0 { - break - } - pos++ - ch = p.charAt(pos) - if ch < '0' || ch > '9' { - break - } - } - - if nChars == 0 || pos-startpos == 1 { - return false - } - if ch == '}' { - return true - } - if ch != ',' { - return false - } - for { - nChars-- - if nChars <= 0 { - break - } - pos++ - ch = p.charAt(pos) - if ch < '0' || ch > '9' { - break - } - } - - return nChars > 0 && ch == '}' -} diff --git a/vendor/github.com/dlclark/regexp2/syntax/prefix.go b/vendor/github.com/dlclark/regexp2/syntax/prefix.go deleted file mode 100644 index f671688629..0000000000 --- a/vendor/github.com/dlclark/regexp2/syntax/prefix.go +++ /dev/null @@ -1,896 +0,0 @@ -package syntax - -import ( - "bytes" - "fmt" - "strconv" - "unicode" - "unicode/utf8" -) - -type Prefix struct { - PrefixStr []rune - PrefixSet CharSet - CaseInsensitive bool -} - -// It takes a RegexTree and computes the set of chars that can start it. -func getFirstCharsPrefix(tree *RegexTree) *Prefix { - s := regexFcd{ - fcStack: make([]regexFc, 32), - intStack: make([]int, 32), - } - fc := s.regexFCFromRegexTree(tree) - - if fc == nil || fc.nullable || fc.cc.IsEmpty() { - return nil - } - fcSet := fc.getFirstChars() - return &Prefix{PrefixSet: fcSet, CaseInsensitive: fc.caseInsensitive} -} - -type regexFcd struct { - intStack []int - intDepth int - fcStack []regexFc - fcDepth int - skipAllChildren bool // don't process any more children at the current level - skipchild bool // don't process the current child. - failed bool -} - -/* - * The main FC computation. It does a shortcutted depth-first walk - * through the tree and calls CalculateFC to emits code before - * and after each child of an interior node, and at each leaf. - */ -func (s *regexFcd) regexFCFromRegexTree(tree *RegexTree) *regexFc { - curNode := tree.root - curChild := 0 - - for { - if len(curNode.children) == 0 { - // This is a leaf node - s.calculateFC(curNode.t, curNode, 0) - } else if curChild < len(curNode.children) && !s.skipAllChildren { - // This is an interior node, and we have more children to analyze - s.calculateFC(curNode.t|beforeChild, curNode, curChild) - - if !s.skipchild { - curNode = curNode.children[curChild] - // this stack is how we get a depth first walk of the tree. - s.pushInt(curChild) - curChild = 0 - } else { - curChild++ - s.skipchild = false - } - continue - } - - // This is an interior node where we've finished analyzing all the children, or - // the end of a leaf node. - s.skipAllChildren = false - - if s.intIsEmpty() { - break - } - - curChild = s.popInt() - curNode = curNode.next - - s.calculateFC(curNode.t|afterChild, curNode, curChild) - if s.failed { - return nil - } - - curChild++ - } - - if s.fcIsEmpty() { - return nil - } - - return s.popFC() -} - -// To avoid recursion, we use a simple integer stack. -// This is the push. -func (s *regexFcd) pushInt(I int) { - if s.intDepth >= len(s.intStack) { - expanded := make([]int, s.intDepth*2) - copy(expanded, s.intStack) - s.intStack = expanded - } - - s.intStack[s.intDepth] = I - s.intDepth++ -} - -// True if the stack is empty. -func (s *regexFcd) intIsEmpty() bool { - return s.intDepth == 0 -} - -// This is the pop. -func (s *regexFcd) popInt() int { - s.intDepth-- - return s.intStack[s.intDepth] -} - -// We also use a stack of RegexFC objects. -// This is the push. -func (s *regexFcd) pushFC(fc regexFc) { - if s.fcDepth >= len(s.fcStack) { - expanded := make([]regexFc, s.fcDepth*2) - copy(expanded, s.fcStack) - s.fcStack = expanded - } - - s.fcStack[s.fcDepth] = fc - s.fcDepth++ -} - -// True if the stack is empty. -func (s *regexFcd) fcIsEmpty() bool { - return s.fcDepth == 0 -} - -// This is the pop. -func (s *regexFcd) popFC() *regexFc { - s.fcDepth-- - return &s.fcStack[s.fcDepth] -} - -// This is the top. -func (s *regexFcd) topFC() *regexFc { - return &s.fcStack[s.fcDepth-1] -} - -// Called in Beforechild to prevent further processing of the current child -func (s *regexFcd) skipChild() { - s.skipchild = true -} - -// FC computation and shortcut cases for each node type -func (s *regexFcd) calculateFC(nt nodeType, node *regexNode, CurIndex int) { - //fmt.Printf("NodeType: %v, CurIndex: %v, Desc: %v\n", nt, CurIndex, node.description()) - ci := false - rtl := false - - if nt <= ntRef { - if (node.options & IgnoreCase) != 0 { - ci = true - } - if (node.options & RightToLeft) != 0 { - rtl = true - } - } - - switch nt { - case ntConcatenate | beforeChild, ntAlternate | beforeChild, ntTestref | beforeChild, ntLoop | beforeChild, ntLazyloop | beforeChild: - break - - case ntTestgroup | beforeChild: - if CurIndex == 0 { - s.skipChild() - } - break - - case ntEmpty: - s.pushFC(regexFc{nullable: true}) - break - - case ntConcatenate | afterChild: - if CurIndex != 0 { - child := s.popFC() - cumul := s.topFC() - - s.failed = !cumul.addFC(*child, true) - } - - fc := s.topFC() - if !fc.nullable { - s.skipAllChildren = true - } - break - - case ntTestgroup | afterChild: - if CurIndex > 1 { - child := s.popFC() - cumul := s.topFC() - - s.failed = !cumul.addFC(*child, false) - } - break - - case ntAlternate | afterChild, ntTestref | afterChild: - if CurIndex != 0 { - child := s.popFC() - cumul := s.topFC() - - s.failed = !cumul.addFC(*child, false) - } - break - - case ntLoop | afterChild, ntLazyloop | afterChild: - if node.m == 0 { - fc := s.topFC() - fc.nullable = true - } - break - - case ntGroup | beforeChild, ntGroup | afterChild, ntCapture | beforeChild, ntCapture | afterChild, ntGreedy | beforeChild, ntGreedy | afterChild: - break - - case ntRequire | beforeChild, ntPrevent | beforeChild: - s.skipChild() - s.pushFC(regexFc{nullable: true}) - break - - case ntRequire | afterChild, ntPrevent | afterChild: - break - - case ntOne, ntNotone: - s.pushFC(newRegexFc(node.ch, nt == ntNotone, false, ci)) - break - - case ntOneloop, ntOnelazy: - s.pushFC(newRegexFc(node.ch, false, node.m == 0, ci)) - break - - case ntNotoneloop, ntNotonelazy: - s.pushFC(newRegexFc(node.ch, true, node.m == 0, ci)) - break - - case ntMulti: - if len(node.str) == 0 { - s.pushFC(regexFc{nullable: true}) - } else if !rtl { - s.pushFC(newRegexFc(node.str[0], false, false, ci)) - } else { - s.pushFC(newRegexFc(node.str[len(node.str)-1], false, false, ci)) - } - break - - case ntSet: - s.pushFC(regexFc{cc: node.set.Copy(), nullable: false, caseInsensitive: ci}) - break - - case ntSetloop, ntSetlazy: - s.pushFC(regexFc{cc: node.set.Copy(), nullable: node.m == 0, caseInsensitive: ci}) - break - - case ntRef: - s.pushFC(regexFc{cc: *AnyClass(), nullable: true, caseInsensitive: false}) - break - - case ntNothing, ntBol, ntEol, ntBoundary, ntNonboundary, ntECMABoundary, ntNonECMABoundary, ntBeginning, ntStart, ntEndZ, ntEnd: - s.pushFC(regexFc{nullable: true}) - break - - default: - panic(fmt.Sprintf("unexpected op code: %v", nt)) - } -} - -type regexFc struct { - cc CharSet - nullable bool - caseInsensitive bool -} - -func newRegexFc(ch rune, not, nullable, caseInsensitive bool) regexFc { - r := regexFc{ - caseInsensitive: caseInsensitive, - nullable: nullable, - } - if not { - if ch > 0 { - r.cc.addRange('\x00', ch-1) - } - if ch < 0xFFFF { - r.cc.addRange(ch+1, utf8.MaxRune) - } - } else { - r.cc.addRange(ch, ch) - } - return r -} - -func (r *regexFc) getFirstChars() CharSet { - if r.caseInsensitive { - r.cc.addLowercase() - } - - return r.cc -} - -func (r *regexFc) addFC(fc regexFc, concatenate bool) bool { - if !r.cc.IsMergeable() || !fc.cc.IsMergeable() { - return false - } - - if concatenate { - if !r.nullable { - return true - } - - if !fc.nullable { - r.nullable = false - } - } else { - if fc.nullable { - r.nullable = true - } - } - - r.caseInsensitive = r.caseInsensitive || fc.caseInsensitive - r.cc.addSet(fc.cc) - - return true -} - -// This is a related computation: it takes a RegexTree and computes the -// leading substring if it sees one. It's quite trivial and gives up easily. -func getPrefix(tree *RegexTree) *Prefix { - var concatNode *regexNode - nextChild := 0 - - curNode := tree.root - - for { - switch curNode.t { - case ntConcatenate: - if len(curNode.children) > 0 { - concatNode = curNode - nextChild = 0 - } - - case ntGreedy, ntCapture: - curNode = curNode.children[0] - concatNode = nil - continue - - case ntOneloop, ntOnelazy: - if curNode.m > 0 { - return &Prefix{ - PrefixStr: repeat(curNode.ch, curNode.m), - CaseInsensitive: (curNode.options & IgnoreCase) != 0, - } - } - return nil - - case ntOne: - return &Prefix{ - PrefixStr: []rune{curNode.ch}, - CaseInsensitive: (curNode.options & IgnoreCase) != 0, - } - - case ntMulti: - return &Prefix{ - PrefixStr: curNode.str, - CaseInsensitive: (curNode.options & IgnoreCase) != 0, - } - - case ntBol, ntEol, ntBoundary, ntECMABoundary, ntBeginning, ntStart, - ntEndZ, ntEnd, ntEmpty, ntRequire, ntPrevent: - - default: - return nil - } - - if concatNode == nil || nextChild >= len(concatNode.children) { - return nil - } - - curNode = concatNode.children[nextChild] - nextChild++ - } -} - -// repeat the rune r, c times... up to the max of MaxPrefixSize -func repeat(r rune, c int) []rune { - if c > MaxPrefixSize { - c = MaxPrefixSize - } - - ret := make([]rune, c) - - // binary growth using copy for speed - ret[0] = r - bp := 1 - for bp < len(ret) { - copy(ret[bp:], ret[:bp]) - bp *= 2 - } - - return ret -} - -// BmPrefix precomputes the Boyer-Moore -// tables for fast string scanning. These tables allow -// you to scan for the first occurrence of a string within -// a large body of text without examining every character. -// The performance of the heuristic depends on the actual -// string and the text being searched, but usually, the longer -// the string that is being searched for, the fewer characters -// need to be examined. -type BmPrefix struct { - positive []int - negativeASCII []int - negativeUnicode [][]int - pattern []rune - lowASCII rune - highASCII rune - rightToLeft bool - caseInsensitive bool -} - -func newBmPrefix(pattern []rune, caseInsensitive, rightToLeft bool) *BmPrefix { - - b := &BmPrefix{ - rightToLeft: rightToLeft, - caseInsensitive: caseInsensitive, - pattern: pattern, - } - - if caseInsensitive { - for i := 0; i < len(b.pattern); i++ { - // We do the ToLower character by character for consistency. With surrogate chars, doing - // a ToLower on the entire string could actually change the surrogate pair. This is more correct - // linguistically, but since Regex doesn't support surrogates, it's more important to be - // consistent. - - b.pattern[i] = unicode.ToLower(b.pattern[i]) - } - } - - var beforefirst, last, bump int - var scan, match int - - if !rightToLeft { - beforefirst = -1 - last = len(b.pattern) - 1 - bump = 1 - } else { - beforefirst = len(b.pattern) - last = 0 - bump = -1 - } - - // PART I - the good-suffix shift table - // - // compute the positive requirement: - // if char "i" is the first one from the right that doesn't match, - // then we know the matcher can advance by _positive[i]. - // - // This algorithm is a simplified variant of the standard - // Boyer-Moore good suffix calculation. - - b.positive = make([]int, len(b.pattern)) - - examine := last - ch := b.pattern[examine] - b.positive[examine] = bump - examine -= bump - -Outerloop: - for { - // find an internal char (examine) that matches the tail - - for { - if examine == beforefirst { - break Outerloop - } - if b.pattern[examine] == ch { - break - } - examine -= bump - } - - match = last - scan = examine - - // find the length of the match - for { - if scan == beforefirst || b.pattern[match] != b.pattern[scan] { - // at the end of the match, note the difference in _positive - // this is not the length of the match, but the distance from the internal match - // to the tail suffix. - if b.positive[match] == 0 { - b.positive[match] = match - scan - } - - // System.Diagnostics.Debug.WriteLine("Set positive[" + match + "] to " + (match - scan)); - - break - } - - scan -= bump - match -= bump - } - - examine -= bump - } - - match = last - bump - - // scan for the chars for which there are no shifts that yield a different candidate - - // The inside of the if statement used to say - // "_positive[match] = last - beforefirst;" - // This is slightly less aggressive in how much we skip, but at worst it - // should mean a little more work rather than skipping a potential match. - for match != beforefirst { - if b.positive[match] == 0 { - b.positive[match] = bump - } - - match -= bump - } - - // PART II - the bad-character shift table - // - // compute the negative requirement: - // if char "ch" is the reject character when testing position "i", - // we can slide up by _negative[ch]; - // (_negative[ch] = str.Length - 1 - str.LastIndexOf(ch)) - // - // the lookup table is divided into ASCII and Unicode portions; - // only those parts of the Unicode 16-bit code set that actually - // appear in the string are in the table. (Maximum size with - // Unicode is 65K; ASCII only case is 512 bytes.) - - b.negativeASCII = make([]int, 128) - - for i := 0; i < len(b.negativeASCII); i++ { - b.negativeASCII[i] = last - beforefirst - } - - b.lowASCII = 127 - b.highASCII = 0 - - for examine = last; examine != beforefirst; examine -= bump { - ch = b.pattern[examine] - - switch { - case ch < 128: - if b.lowASCII > ch { - b.lowASCII = ch - } - - if b.highASCII < ch { - b.highASCII = ch - } - - if b.negativeASCII[ch] == last-beforefirst { - b.negativeASCII[ch] = last - examine - } - case ch <= 0xffff: - i, j := ch>>8, ch&0xFF - - if b.negativeUnicode == nil { - b.negativeUnicode = make([][]int, 256) - } - - if b.negativeUnicode[i] == nil { - newarray := make([]int, 256) - - for k := 0; k < len(newarray); k++ { - newarray[k] = last - beforefirst - } - - if i == 0 { - copy(newarray, b.negativeASCII) - //TODO: this line needed? - b.negativeASCII = newarray - } - - b.negativeUnicode[i] = newarray - } - - if b.negativeUnicode[i][j] == last-beforefirst { - b.negativeUnicode[i][j] = last - examine - } - default: - // we can't do the filter because this algo doesn't support - // unicode chars >0xffff - return nil - } - } - - return b -} - -func (b *BmPrefix) String() string { - return string(b.pattern) -} - -// Dump returns the contents of the filter as a human readable string -func (b *BmPrefix) Dump(indent string) string { - buf := &bytes.Buffer{} - - fmt.Fprintf(buf, "%sBM Pattern: %s\n%sPositive: ", indent, string(b.pattern), indent) - for i := 0; i < len(b.positive); i++ { - buf.WriteString(strconv.Itoa(b.positive[i])) - buf.WriteRune(' ') - } - buf.WriteRune('\n') - - if b.negativeASCII != nil { - buf.WriteString(indent) - buf.WriteString("Negative table\n") - for i := 0; i < len(b.negativeASCII); i++ { - if b.negativeASCII[i] != len(b.pattern) { - fmt.Fprintf(buf, "%s %s %s\n", indent, Escape(string(rune(i))), strconv.Itoa(b.negativeASCII[i])) - } - } - } - - return buf.String() -} - -// Scan uses the Boyer-Moore algorithm to find the first occurrence -// of the specified string within text, beginning at index, and -// constrained within beglimit and endlimit. -// -// The direction and case-sensitivity of the match is determined -// by the arguments to the RegexBoyerMoore constructor. -func (b *BmPrefix) Scan(text []rune, index, beglimit, endlimit int) int { - var ( - defadv, test, test2 int - match, startmatch, endmatch int - bump, advance int - chTest rune - unicodeLookup []int - ) - - if !b.rightToLeft { - defadv = len(b.pattern) - startmatch = len(b.pattern) - 1 - endmatch = 0 - test = index + defadv - 1 - bump = 1 - } else { - defadv = -len(b.pattern) - startmatch = 0 - endmatch = -defadv - 1 - test = index + defadv - bump = -1 - } - - chMatch := b.pattern[startmatch] - - for { - if test >= endlimit || test < beglimit { - return -1 - } - - chTest = text[test] - - if b.caseInsensitive { - chTest = unicode.ToLower(chTest) - } - - if chTest != chMatch { - if chTest < 128 { - advance = b.negativeASCII[chTest] - } else if chTest < 0xffff && len(b.negativeUnicode) > 0 { - unicodeLookup = b.negativeUnicode[chTest>>8] - if len(unicodeLookup) > 0 { - advance = unicodeLookup[chTest&0xFF] - } else { - advance = defadv - } - } else { - advance = defadv - } - - test += advance - } else { // if (chTest == chMatch) - test2 = test - match = startmatch - - for { - if match == endmatch { - if b.rightToLeft { - return test2 + 1 - } else { - return test2 - } - } - - match -= bump - test2 -= bump - - chTest = text[test2] - - if b.caseInsensitive { - chTest = unicode.ToLower(chTest) - } - - if chTest != b.pattern[match] { - advance = b.positive[match] - if chTest < 128 { - test2 = (match - startmatch) + b.negativeASCII[chTest] - } else if chTest < 0xffff && len(b.negativeUnicode) > 0 { - unicodeLookup = b.negativeUnicode[chTest>>8] - if len(unicodeLookup) > 0 { - test2 = (match - startmatch) + unicodeLookup[chTest&0xFF] - } else { - test += advance - break - } - } else { - test += advance - break - } - - if b.rightToLeft { - if test2 < advance { - advance = test2 - } - } else if test2 > advance { - advance = test2 - } - - test += advance - break - } - } - } - } -} - -// When a regex is anchored, we can do a quick IsMatch test instead of a Scan -func (b *BmPrefix) IsMatch(text []rune, index, beglimit, endlimit int) bool { - if !b.rightToLeft { - if index < beglimit || endlimit-index < len(b.pattern) { - return false - } - - return b.matchPattern(text, index) - } else { - if index > endlimit || index-beglimit < len(b.pattern) { - return false - } - - return b.matchPattern(text, index-len(b.pattern)) - } -} - -func (b *BmPrefix) matchPattern(text []rune, index int) bool { - if len(text)-index < len(b.pattern) { - return false - } - - if b.caseInsensitive { - for i := 0; i < len(b.pattern); i++ { - //Debug.Assert(textinfo.ToLower(_pattern[i]) == _pattern[i], "pattern should be converted to lower case in constructor!"); - if unicode.ToLower(text[index+i]) != b.pattern[i] { - return false - } - } - return true - } else { - for i := 0; i < len(b.pattern); i++ { - if text[index+i] != b.pattern[i] { - return false - } - } - return true - } -} - -type AnchorLoc int16 - -// where the regex can be pegged -const ( - AnchorBeginning AnchorLoc = 0x0001 - AnchorBol = 0x0002 - AnchorStart = 0x0004 - AnchorEol = 0x0008 - AnchorEndZ = 0x0010 - AnchorEnd = 0x0020 - AnchorBoundary = 0x0040 - AnchorECMABoundary = 0x0080 -) - -func getAnchors(tree *RegexTree) AnchorLoc { - - var concatNode *regexNode - nextChild, result := 0, AnchorLoc(0) - - curNode := tree.root - - for { - switch curNode.t { - case ntConcatenate: - if len(curNode.children) > 0 { - concatNode = curNode - nextChild = 0 - } - - case ntGreedy, ntCapture: - curNode = curNode.children[0] - concatNode = nil - continue - - case ntBol, ntEol, ntBoundary, ntECMABoundary, ntBeginning, - ntStart, ntEndZ, ntEnd: - return result | anchorFromType(curNode.t) - - case ntEmpty, ntRequire, ntPrevent: - - default: - return result - } - - if concatNode == nil || nextChild >= len(concatNode.children) { - return result - } - - curNode = concatNode.children[nextChild] - nextChild++ - } -} - -func anchorFromType(t nodeType) AnchorLoc { - switch t { - case ntBol: - return AnchorBol - case ntEol: - return AnchorEol - case ntBoundary: - return AnchorBoundary - case ntECMABoundary: - return AnchorECMABoundary - case ntBeginning: - return AnchorBeginning - case ntStart: - return AnchorStart - case ntEndZ: - return AnchorEndZ - case ntEnd: - return AnchorEnd - default: - return 0 - } -} - -// anchorDescription returns a human-readable description of the anchors -func (anchors AnchorLoc) String() string { - buf := &bytes.Buffer{} - - if 0 != (anchors & AnchorBeginning) { - buf.WriteString(", Beginning") - } - if 0 != (anchors & AnchorStart) { - buf.WriteString(", Start") - } - if 0 != (anchors & AnchorBol) { - buf.WriteString(", Bol") - } - if 0 != (anchors & AnchorBoundary) { - buf.WriteString(", Boundary") - } - if 0 != (anchors & AnchorECMABoundary) { - buf.WriteString(", ECMABoundary") - } - if 0 != (anchors & AnchorEol) { - buf.WriteString(", Eol") - } - if 0 != (anchors & AnchorEnd) { - buf.WriteString(", End") - } - if 0 != (anchors & AnchorEndZ) { - buf.WriteString(", EndZ") - } - - // trim off comma - if buf.Len() >= 2 { - return buf.String()[2:] - } - return "None" -} diff --git a/vendor/github.com/dlclark/regexp2/syntax/replacerdata.go b/vendor/github.com/dlclark/regexp2/syntax/replacerdata.go deleted file mode 100644 index bcf4d3f257..0000000000 --- a/vendor/github.com/dlclark/regexp2/syntax/replacerdata.go +++ /dev/null @@ -1,87 +0,0 @@ -package syntax - -import ( - "bytes" - "errors" -) - -type ReplacerData struct { - Rep string - Strings []string - Rules []int -} - -const ( - replaceSpecials = 4 - replaceLeftPortion = -1 - replaceRightPortion = -2 - replaceLastGroup = -3 - replaceWholeString = -4 -) - -//ErrReplacementError is a general error during parsing the replacement text -var ErrReplacementError = errors.New("Replacement pattern error.") - -// NewReplacerData will populate a reusable replacer data struct based on the given replacement string -// and the capture group data from a regexp -func NewReplacerData(rep string, caps map[int]int, capsize int, capnames map[string]int, op RegexOptions) (*ReplacerData, error) { - p := parser{ - options: op, - caps: caps, - capsize: capsize, - capnames: capnames, - } - p.setPattern(rep) - concat, err := p.scanReplacement() - if err != nil { - return nil, err - } - - if concat.t != ntConcatenate { - panic(ErrReplacementError) - } - - sb := &bytes.Buffer{} - var ( - strings []string - rules []int - ) - - for _, child := range concat.children { - switch child.t { - case ntMulti: - child.writeStrToBuf(sb) - - case ntOne: - sb.WriteRune(child.ch) - - case ntRef: - if sb.Len() > 0 { - rules = append(rules, len(strings)) - strings = append(strings, sb.String()) - sb.Reset() - } - slot := child.m - - if len(caps) > 0 && slot >= 0 { - slot = caps[slot] - } - - rules = append(rules, -replaceSpecials-1-slot) - - default: - panic(ErrReplacementError) - } - } - - if sb.Len() > 0 { - rules = append(rules, len(strings)) - strings = append(strings, sb.String()) - } - - return &ReplacerData{ - Rep: rep, - Strings: strings, - Rules: rules, - }, nil -} diff --git a/vendor/github.com/dlclark/regexp2/syntax/tree.go b/vendor/github.com/dlclark/regexp2/syntax/tree.go deleted file mode 100644 index ea28829319..0000000000 --- a/vendor/github.com/dlclark/regexp2/syntax/tree.go +++ /dev/null @@ -1,654 +0,0 @@ -package syntax - -import ( - "bytes" - "fmt" - "math" - "strconv" -) - -type RegexTree struct { - root *regexNode - caps map[int]int - capnumlist []int - captop int - Capnames map[string]int - Caplist []string - options RegexOptions -} - -// It is built into a parsed tree for a regular expression. - -// Implementation notes: -// -// Since the node tree is a temporary data structure only used -// during compilation of the regexp to integer codes, it's -// designed for clarity and convenience rather than -// space efficiency. -// -// RegexNodes are built into a tree, linked by the n.children list. -// Each node also has a n.parent and n.ichild member indicating -// its parent and which child # it is in its parent's list. -// -// RegexNodes come in as many types as there are constructs in -// a regular expression, for example, "concatenate", "alternate", -// "one", "rept", "group". There are also node types for basic -// peephole optimizations, e.g., "onerep", "notsetrep", etc. -// -// Because perl 5 allows "lookback" groups that scan backwards, -// each node also gets a "direction". Normally the value of -// boolean n.backward = false. -// -// During parsing, top-level nodes are also stacked onto a parse -// stack (a stack of trees). For this purpose we have a n.next -// pointer. [Note that to save a few bytes, we could overload the -// n.parent pointer instead.] -// -// On the parse stack, each tree has a "role" - basically, the -// nonterminal in the grammar that the parser has currently -// assigned to the tree. That code is stored in n.role. -// -// Finally, some of the different kinds of nodes have data. -// Two integers (for the looping constructs) are stored in -// n.operands, an an object (either a string or a set) -// is stored in n.data -type regexNode struct { - t nodeType - children []*regexNode - str []rune - set *CharSet - ch rune - m int - n int - options RegexOptions - next *regexNode -} - -type nodeType int32 - -const ( - // The following are leaves, and correspond to primitive operations - - ntOnerep nodeType = 0 // lef,back char,min,max a {n} - ntNotonerep = 1 // lef,back char,min,max .{n} - ntSetrep = 2 // lef,back set,min,max [\d]{n} - ntOneloop = 3 // lef,back char,min,max a {,n} - ntNotoneloop = 4 // lef,back char,min,max .{,n} - ntSetloop = 5 // lef,back set,min,max [\d]{,n} - ntOnelazy = 6 // lef,back char,min,max a {,n}? - ntNotonelazy = 7 // lef,back char,min,max .{,n}? - ntSetlazy = 8 // lef,back set,min,max [\d]{,n}? - ntOne = 9 // lef char a - ntNotone = 10 // lef char [^a] - ntSet = 11 // lef set [a-z\s] \w \s \d - ntMulti = 12 // lef string abcd - ntRef = 13 // lef group \# - ntBol = 14 // ^ - ntEol = 15 // $ - ntBoundary = 16 // \b - ntNonboundary = 17 // \B - ntBeginning = 18 // \A - ntStart = 19 // \G - ntEndZ = 20 // \Z - ntEnd = 21 // \Z - - // Interior nodes do not correspond to primitive operations, but - // control structures compositing other operations - - // Concat and alternate take n children, and can run forward or backwards - - ntNothing = 22 // [] - ntEmpty = 23 // () - ntAlternate = 24 // a|b - ntConcatenate = 25 // ab - ntLoop = 26 // m,x * + ? {,} - ntLazyloop = 27 // m,x *? +? ?? {,}? - ntCapture = 28 // n () - ntGroup = 29 // (?:) - ntRequire = 30 // (?=) (?<=) - ntPrevent = 31 // (?!) (?) (?<) - ntTestref = 33 // (?(n) | ) - ntTestgroup = 34 // (?(...) | ) - - ntECMABoundary = 41 // \b - ntNonECMABoundary = 42 // \B -) - -func newRegexNode(t nodeType, opt RegexOptions) *regexNode { - return ®exNode{ - t: t, - options: opt, - } -} - -func newRegexNodeCh(t nodeType, opt RegexOptions, ch rune) *regexNode { - return ®exNode{ - t: t, - options: opt, - ch: ch, - } -} - -func newRegexNodeStr(t nodeType, opt RegexOptions, str []rune) *regexNode { - return ®exNode{ - t: t, - options: opt, - str: str, - } -} - -func newRegexNodeSet(t nodeType, opt RegexOptions, set *CharSet) *regexNode { - return ®exNode{ - t: t, - options: opt, - set: set, - } -} - -func newRegexNodeM(t nodeType, opt RegexOptions, m int) *regexNode { - return ®exNode{ - t: t, - options: opt, - m: m, - } -} -func newRegexNodeMN(t nodeType, opt RegexOptions, m, n int) *regexNode { - return ®exNode{ - t: t, - options: opt, - m: m, - n: n, - } -} - -func (n *regexNode) writeStrToBuf(buf *bytes.Buffer) { - for i := 0; i < len(n.str); i++ { - buf.WriteRune(n.str[i]) - } -} - -func (n *regexNode) addChild(child *regexNode) { - reduced := child.reduce() - n.children = append(n.children, reduced) - reduced.next = n -} - -func (n *regexNode) insertChildren(afterIndex int, nodes []*regexNode) { - newChildren := make([]*regexNode, 0, len(n.children)+len(nodes)) - n.children = append(append(append(newChildren, n.children[:afterIndex]...), nodes...), n.children[afterIndex:]...) -} - -// removes children including the start but not the end index -func (n *regexNode) removeChildren(startIndex, endIndex int) { - n.children = append(n.children[:startIndex], n.children[endIndex:]...) -} - -// Pass type as OneLazy or OneLoop -func (n *regexNode) makeRep(t nodeType, min, max int) { - n.t += (t - ntOne) - n.m = min - n.n = max -} - -func (n *regexNode) reduce() *regexNode { - switch n.t { - case ntAlternate: - return n.reduceAlternation() - - case ntConcatenate: - return n.reduceConcatenation() - - case ntLoop, ntLazyloop: - return n.reduceRep() - - case ntGroup: - return n.reduceGroup() - - case ntSet, ntSetloop: - return n.reduceSet() - - default: - return n - } -} - -// Basic optimization. Single-letter alternations can be replaced -// by faster set specifications, and nested alternations with no -// intervening operators can be flattened: -// -// a|b|c|def|g|h -> [a-c]|def|[gh] -// apple|(?:orange|pear)|grape -> apple|orange|pear|grape -func (n *regexNode) reduceAlternation() *regexNode { - if len(n.children) == 0 { - return newRegexNode(ntNothing, n.options) - } - - wasLastSet := false - lastNodeCannotMerge := false - var optionsLast RegexOptions - var i, j int - - for i, j = 0, 0; i < len(n.children); i, j = i+1, j+1 { - at := n.children[i] - - if j < i { - n.children[j] = at - } - - for { - if at.t == ntAlternate { - for k := 0; k < len(at.children); k++ { - at.children[k].next = n - } - n.insertChildren(i+1, at.children) - - j-- - } else if at.t == ntSet || at.t == ntOne { - // Cannot merge sets if L or I options differ, or if either are negated. - optionsAt := at.options & (RightToLeft | IgnoreCase) - - if at.t == ntSet { - if !wasLastSet || optionsLast != optionsAt || lastNodeCannotMerge || !at.set.IsMergeable() { - wasLastSet = true - lastNodeCannotMerge = !at.set.IsMergeable() - optionsLast = optionsAt - break - } - } else if !wasLastSet || optionsLast != optionsAt || lastNodeCannotMerge { - wasLastSet = true - lastNodeCannotMerge = false - optionsLast = optionsAt - break - } - - // The last node was a Set or a One, we're a Set or One and our options are the same. - // Merge the two nodes. - j-- - prev := n.children[j] - - var prevCharClass *CharSet - if prev.t == ntOne { - prevCharClass = &CharSet{} - prevCharClass.addChar(prev.ch) - } else { - prevCharClass = prev.set - } - - if at.t == ntOne { - prevCharClass.addChar(at.ch) - } else { - prevCharClass.addSet(*at.set) - } - - prev.t = ntSet - prev.set = prevCharClass - } else if at.t == ntNothing { - j-- - } else { - wasLastSet = false - lastNodeCannotMerge = false - } - break - } - } - - if j < i { - n.removeChildren(j, i) - } - - return n.stripEnation(ntNothing) -} - -// Basic optimization. Adjacent strings can be concatenated. -// -// (?:abc)(?:def) -> abcdef -func (n *regexNode) reduceConcatenation() *regexNode { - // Eliminate empties and concat adjacent strings/chars - - var optionsLast RegexOptions - var optionsAt RegexOptions - var i, j int - - if len(n.children) == 0 { - return newRegexNode(ntEmpty, n.options) - } - - wasLastString := false - - for i, j = 0, 0; i < len(n.children); i, j = i+1, j+1 { - var at, prev *regexNode - - at = n.children[i] - - if j < i { - n.children[j] = at - } - - if at.t == ntConcatenate && - ((at.options & RightToLeft) == (n.options & RightToLeft)) { - for k := 0; k < len(at.children); k++ { - at.children[k].next = n - } - - //insert at.children at i+1 index in n.children - n.insertChildren(i+1, at.children) - - j-- - } else if at.t == ntMulti || at.t == ntOne { - // Cannot merge strings if L or I options differ - optionsAt = at.options & (RightToLeft | IgnoreCase) - - if !wasLastString || optionsLast != optionsAt { - wasLastString = true - optionsLast = optionsAt - continue - } - - j-- - prev = n.children[j] - - if prev.t == ntOne { - prev.t = ntMulti - prev.str = []rune{prev.ch} - } - - if (optionsAt & RightToLeft) == 0 { - if at.t == ntOne { - prev.str = append(prev.str, at.ch) - } else { - prev.str = append(prev.str, at.str...) - } - } else { - if at.t == ntOne { - // insert at the front by expanding our slice, copying the data over, and then setting the value - prev.str = append(prev.str, 0) - copy(prev.str[1:], prev.str) - prev.str[0] = at.ch - } else { - //insert at the front...this one we'll make a new slice and copy both into it - merge := make([]rune, len(prev.str)+len(at.str)) - copy(merge, at.str) - copy(merge[len(at.str):], prev.str) - prev.str = merge - } - } - } else if at.t == ntEmpty { - j-- - } else { - wasLastString = false - } - } - - if j < i { - // remove indices j through i from the children - n.removeChildren(j, i) - } - - return n.stripEnation(ntEmpty) -} - -// Nested repeaters just get multiplied with each other if they're not -// too lumpy -func (n *regexNode) reduceRep() *regexNode { - - u := n - t := n.t - min := n.m - max := n.n - - for { - if len(u.children) == 0 { - break - } - - child := u.children[0] - - // multiply reps of the same type only - if child.t != t { - childType := child.t - - if !(childType >= ntOneloop && childType <= ntSetloop && t == ntLoop || - childType >= ntOnelazy && childType <= ntSetlazy && t == ntLazyloop) { - break - } - } - - // child can be too lumpy to blur, e.g., (a {100,105}) {3} or (a {2,})? - // [but things like (a {2,})+ are not too lumpy...] - if u.m == 0 && child.m > 1 || child.n < child.m*2 { - break - } - - u = child - if u.m > 0 { - if (math.MaxInt32-1)/u.m < min { - u.m = math.MaxInt32 - } else { - u.m = u.m * min - } - } - if u.n > 0 { - if (math.MaxInt32-1)/u.n < max { - u.n = math.MaxInt32 - } else { - u.n = u.n * max - } - } - } - - if math.MaxInt32 == min { - return newRegexNode(ntNothing, n.options) - } - return u - -} - -// Simple optimization. If a concatenation or alternation has only -// one child strip out the intermediate node. If it has zero children, -// turn it into an empty. -func (n *regexNode) stripEnation(emptyType nodeType) *regexNode { - switch len(n.children) { - case 0: - return newRegexNode(emptyType, n.options) - case 1: - return n.children[0] - default: - return n - } -} - -func (n *regexNode) reduceGroup() *regexNode { - u := n - - for u.t == ntGroup { - u = u.children[0] - } - - return u -} - -// Simple optimization. If a set is a singleton, an inverse singleton, -// or empty, it's transformed accordingly. -func (n *regexNode) reduceSet() *regexNode { - // Extract empty-set, one and not-one case as special - - if n.set == nil { - n.t = ntNothing - } else if n.set.IsSingleton() { - n.ch = n.set.SingletonChar() - n.set = nil - n.t += (ntOne - ntSet) - } else if n.set.IsSingletonInverse() { - n.ch = n.set.SingletonChar() - n.set = nil - n.t += (ntNotone - ntSet) - } - - return n -} - -func (n *regexNode) reverseLeft() *regexNode { - if n.options&RightToLeft != 0 && n.t == ntConcatenate && len(n.children) > 0 { - //reverse children order - for left, right := 0, len(n.children)-1; left < right; left, right = left+1, right-1 { - n.children[left], n.children[right] = n.children[right], n.children[left] - } - } - - return n -} - -func (n *regexNode) makeQuantifier(lazy bool, min, max int) *regexNode { - if min == 0 && max == 0 { - return newRegexNode(ntEmpty, n.options) - } - - if min == 1 && max == 1 { - return n - } - - switch n.t { - case ntOne, ntNotone, ntSet: - if lazy { - n.makeRep(Onelazy, min, max) - } else { - n.makeRep(Oneloop, min, max) - } - return n - - default: - var t nodeType - if lazy { - t = ntLazyloop - } else { - t = ntLoop - } - result := newRegexNodeMN(t, n.options, min, max) - result.addChild(n) - return result - } -} - -// debug functions - -var typeStr = []string{ - "Onerep", "Notonerep", "Setrep", - "Oneloop", "Notoneloop", "Setloop", - "Onelazy", "Notonelazy", "Setlazy", - "One", "Notone", "Set", - "Multi", "Ref", - "Bol", "Eol", "Boundary", "Nonboundary", - "Beginning", "Start", "EndZ", "End", - "Nothing", "Empty", - "Alternate", "Concatenate", - "Loop", "Lazyloop", - "Capture", "Group", "Require", "Prevent", "Greedy", - "Testref", "Testgroup", - "Unknown", "Unknown", "Unknown", - "Unknown", "Unknown", "Unknown", - "ECMABoundary", "NonECMABoundary", -} - -func (n *regexNode) description() string { - buf := &bytes.Buffer{} - - buf.WriteString(typeStr[n.t]) - - if (n.options & ExplicitCapture) != 0 { - buf.WriteString("-C") - } - if (n.options & IgnoreCase) != 0 { - buf.WriteString("-I") - } - if (n.options & RightToLeft) != 0 { - buf.WriteString("-L") - } - if (n.options & Multiline) != 0 { - buf.WriteString("-M") - } - if (n.options & Singleline) != 0 { - buf.WriteString("-S") - } - if (n.options & IgnorePatternWhitespace) != 0 { - buf.WriteString("-X") - } - if (n.options & ECMAScript) != 0 { - buf.WriteString("-E") - } - - switch n.t { - case ntOneloop, ntNotoneloop, ntOnelazy, ntNotonelazy, ntOne, ntNotone: - buf.WriteString("(Ch = " + CharDescription(n.ch) + ")") - break - case ntCapture: - buf.WriteString("(index = " + strconv.Itoa(n.m) + ", unindex = " + strconv.Itoa(n.n) + ")") - break - case ntRef, ntTestref: - buf.WriteString("(index = " + strconv.Itoa(n.m) + ")") - break - case ntMulti: - fmt.Fprintf(buf, "(String = %s)", string(n.str)) - break - case ntSet, ntSetloop, ntSetlazy: - buf.WriteString("(Set = " + n.set.String() + ")") - break - } - - switch n.t { - case ntOneloop, ntNotoneloop, ntOnelazy, ntNotonelazy, ntSetloop, ntSetlazy, ntLoop, ntLazyloop: - buf.WriteString("(Min = ") - buf.WriteString(strconv.Itoa(n.m)) - buf.WriteString(", Max = ") - if n.n == math.MaxInt32 { - buf.WriteString("inf") - } else { - buf.WriteString(strconv.Itoa(n.n)) - } - buf.WriteString(")") - - break - } - - return buf.String() -} - -var padSpace = []byte(" ") - -func (t *RegexTree) Dump() string { - return t.root.dump() -} - -func (n *regexNode) dump() string { - var stack []int - CurNode := n - CurChild := 0 - - buf := bytes.NewBufferString(CurNode.description()) - buf.WriteRune('\n') - - for { - if CurNode.children != nil && CurChild < len(CurNode.children) { - stack = append(stack, CurChild+1) - CurNode = CurNode.children[CurChild] - CurChild = 0 - - Depth := len(stack) - if Depth > 32 { - Depth = 32 - } - buf.Write(padSpace[:Depth]) - buf.WriteString(CurNode.description()) - buf.WriteRune('\n') - } else { - if len(stack) == 0 { - break - } - - CurChild = stack[len(stack)-1] - stack = stack[:len(stack)-1] - CurNode = CurNode.next - } - } - return buf.String() -} diff --git a/vendor/github.com/dlclark/regexp2/syntax/writer.go b/vendor/github.com/dlclark/regexp2/syntax/writer.go deleted file mode 100644 index a5aa11ca06..0000000000 --- a/vendor/github.com/dlclark/regexp2/syntax/writer.go +++ /dev/null @@ -1,500 +0,0 @@ -package syntax - -import ( - "bytes" - "fmt" - "math" - "os" -) - -func Write(tree *RegexTree) (*Code, error) { - w := writer{ - intStack: make([]int, 0, 32), - emitted: make([]int, 2), - stringhash: make(map[string]int), - sethash: make(map[string]int), - } - - code, err := w.codeFromTree(tree) - - if tree.options&Debug > 0 && code != nil { - os.Stdout.WriteString(code.Dump()) - os.Stdout.WriteString("\n") - } - - return code, err -} - -type writer struct { - emitted []int - - intStack []int - curpos int - stringhash map[string]int - stringtable [][]rune - sethash map[string]int - settable []*CharSet - counting bool - count int - trackcount int - caps map[int]int -} - -const ( - beforeChild nodeType = 64 - afterChild = 128 - //MaxPrefixSize is the largest number of runes we'll use for a BoyerMoyer prefix - MaxPrefixSize = 50 -) - -// The top level RegexCode generator. It does a depth-first walk -// through the tree and calls EmitFragment to emits code before -// and after each child of an interior node, and at each leaf. -// -// It runs two passes, first to count the size of the generated -// code, and second to generate the code. -// -// We should time it against the alternative, which is -// to just generate the code and grow the array as we go. -func (w *writer) codeFromTree(tree *RegexTree) (*Code, error) { - var ( - curNode *regexNode - curChild int - capsize int - ) - // construct sparse capnum mapping if some numbers are unused - - if tree.capnumlist == nil || tree.captop == len(tree.capnumlist) { - capsize = tree.captop - w.caps = nil - } else { - capsize = len(tree.capnumlist) - w.caps = tree.caps - for i := 0; i < len(tree.capnumlist); i++ { - w.caps[tree.capnumlist[i]] = i - } - } - - w.counting = true - - for { - if !w.counting { - w.emitted = make([]int, w.count) - } - - curNode = tree.root - curChild = 0 - - w.emit1(Lazybranch, 0) - - for { - if len(curNode.children) == 0 { - w.emitFragment(curNode.t, curNode, 0) - } else if curChild < len(curNode.children) { - w.emitFragment(curNode.t|beforeChild, curNode, curChild) - - curNode = curNode.children[curChild] - - w.pushInt(curChild) - curChild = 0 - continue - } - - if w.emptyStack() { - break - } - - curChild = w.popInt() - curNode = curNode.next - - w.emitFragment(curNode.t|afterChild, curNode, curChild) - curChild++ - } - - w.patchJump(0, w.curPos()) - w.emit(Stop) - - if !w.counting { - break - } - - w.counting = false - } - - fcPrefix := getFirstCharsPrefix(tree) - prefix := getPrefix(tree) - rtl := (tree.options & RightToLeft) != 0 - - var bmPrefix *BmPrefix - //TODO: benchmark string prefixes - if prefix != nil && len(prefix.PrefixStr) > 0 && MaxPrefixSize > 0 { - if len(prefix.PrefixStr) > MaxPrefixSize { - // limit prefix changes to 10k - prefix.PrefixStr = prefix.PrefixStr[:MaxPrefixSize] - } - bmPrefix = newBmPrefix(prefix.PrefixStr, prefix.CaseInsensitive, rtl) - } else { - bmPrefix = nil - } - - return &Code{ - Codes: w.emitted, - Strings: w.stringtable, - Sets: w.settable, - TrackCount: w.trackcount, - Caps: w.caps, - Capsize: capsize, - FcPrefix: fcPrefix, - BmPrefix: bmPrefix, - Anchors: getAnchors(tree), - RightToLeft: rtl, - }, nil -} - -// The main RegexCode generator. It does a depth-first walk -// through the tree and calls EmitFragment to emits code before -// and after each child of an interior node, and at each leaf. -func (w *writer) emitFragment(nodetype nodeType, node *regexNode, curIndex int) error { - bits := InstOp(0) - - if nodetype <= ntRef { - if (node.options & RightToLeft) != 0 { - bits |= Rtl - } - if (node.options & IgnoreCase) != 0 { - bits |= Ci - } - } - ntBits := nodeType(bits) - - switch nodetype { - case ntConcatenate | beforeChild, ntConcatenate | afterChild, ntEmpty: - break - - case ntAlternate | beforeChild: - if curIndex < len(node.children)-1 { - w.pushInt(w.curPos()) - w.emit1(Lazybranch, 0) - } - - case ntAlternate | afterChild: - if curIndex < len(node.children)-1 { - lbPos := w.popInt() - w.pushInt(w.curPos()) - w.emit1(Goto, 0) - w.patchJump(lbPos, w.curPos()) - } else { - for i := 0; i < curIndex; i++ { - w.patchJump(w.popInt(), w.curPos()) - } - } - break - - case ntTestref | beforeChild: - if curIndex == 0 { - w.emit(Setjump) - w.pushInt(w.curPos()) - w.emit1(Lazybranch, 0) - w.emit1(Testref, w.mapCapnum(node.m)) - w.emit(Forejump) - } - - case ntTestref | afterChild: - if curIndex == 0 { - branchpos := w.popInt() - w.pushInt(w.curPos()) - w.emit1(Goto, 0) - w.patchJump(branchpos, w.curPos()) - w.emit(Forejump) - if len(node.children) <= 1 { - w.patchJump(w.popInt(), w.curPos()) - } - } else if curIndex == 1 { - w.patchJump(w.popInt(), w.curPos()) - } - - case ntTestgroup | beforeChild: - if curIndex == 0 { - w.emit(Setjump) - w.emit(Setmark) - w.pushInt(w.curPos()) - w.emit1(Lazybranch, 0) - } - - case ntTestgroup | afterChild: - if curIndex == 0 { - w.emit(Getmark) - w.emit(Forejump) - } else if curIndex == 1 { - Branchpos := w.popInt() - w.pushInt(w.curPos()) - w.emit1(Goto, 0) - w.patchJump(Branchpos, w.curPos()) - w.emit(Getmark) - w.emit(Forejump) - if len(node.children) <= 2 { - w.patchJump(w.popInt(), w.curPos()) - } - } else if curIndex == 2 { - w.patchJump(w.popInt(), w.curPos()) - } - - case ntLoop | beforeChild, ntLazyloop | beforeChild: - - if node.n < math.MaxInt32 || node.m > 1 { - if node.m == 0 { - w.emit1(Nullcount, 0) - } else { - w.emit1(Setcount, 1-node.m) - } - } else if node.m == 0 { - w.emit(Nullmark) - } else { - w.emit(Setmark) - } - - if node.m == 0 { - w.pushInt(w.curPos()) - w.emit1(Goto, 0) - } - w.pushInt(w.curPos()) - - case ntLoop | afterChild, ntLazyloop | afterChild: - - startJumpPos := w.curPos() - lazy := (nodetype - (ntLoop | afterChild)) - - if node.n < math.MaxInt32 || node.m > 1 { - if node.n == math.MaxInt32 { - w.emit2(InstOp(Branchcount+lazy), w.popInt(), math.MaxInt32) - } else { - w.emit2(InstOp(Branchcount+lazy), w.popInt(), node.n-node.m) - } - } else { - w.emit1(InstOp(Branchmark+lazy), w.popInt()) - } - - if node.m == 0 { - w.patchJump(w.popInt(), startJumpPos) - } - - case ntGroup | beforeChild, ntGroup | afterChild: - - case ntCapture | beforeChild: - w.emit(Setmark) - - case ntCapture | afterChild: - w.emit2(Capturemark, w.mapCapnum(node.m), w.mapCapnum(node.n)) - - case ntRequire | beforeChild: - // NOTE: the following line causes lookahead/lookbehind to be - // NON-BACKTRACKING. It can be commented out with (*) - w.emit(Setjump) - - w.emit(Setmark) - - case ntRequire | afterChild: - w.emit(Getmark) - - // NOTE: the following line causes lookahead/lookbehind to be - // NON-BACKTRACKING. It can be commented out with (*) - w.emit(Forejump) - - case ntPrevent | beforeChild: - w.emit(Setjump) - w.pushInt(w.curPos()) - w.emit1(Lazybranch, 0) - - case ntPrevent | afterChild: - w.emit(Backjump) - w.patchJump(w.popInt(), w.curPos()) - w.emit(Forejump) - - case ntGreedy | beforeChild: - w.emit(Setjump) - - case ntGreedy | afterChild: - w.emit(Forejump) - - case ntOne, ntNotone: - w.emit1(InstOp(node.t|ntBits), int(node.ch)) - - case ntNotoneloop, ntNotonelazy, ntOneloop, ntOnelazy: - if node.m > 0 { - if node.t == ntOneloop || node.t == ntOnelazy { - w.emit2(Onerep|bits, int(node.ch), node.m) - } else { - w.emit2(Notonerep|bits, int(node.ch), node.m) - } - } - if node.n > node.m { - if node.n == math.MaxInt32 { - w.emit2(InstOp(node.t|ntBits), int(node.ch), math.MaxInt32) - } else { - w.emit2(InstOp(node.t|ntBits), int(node.ch), node.n-node.m) - } - } - - case ntSetloop, ntSetlazy: - if node.m > 0 { - w.emit2(Setrep|bits, w.setCode(node.set), node.m) - } - if node.n > node.m { - if node.n == math.MaxInt32 { - w.emit2(InstOp(node.t|ntBits), w.setCode(node.set), math.MaxInt32) - } else { - w.emit2(InstOp(node.t|ntBits), w.setCode(node.set), node.n-node.m) - } - } - - case ntMulti: - w.emit1(InstOp(node.t|ntBits), w.stringCode(node.str)) - - case ntSet: - w.emit1(InstOp(node.t|ntBits), w.setCode(node.set)) - - case ntRef: - w.emit1(InstOp(node.t|ntBits), w.mapCapnum(node.m)) - - case ntNothing, ntBol, ntEol, ntBoundary, ntNonboundary, ntECMABoundary, ntNonECMABoundary, ntBeginning, ntStart, ntEndZ, ntEnd: - w.emit(InstOp(node.t)) - - default: - return fmt.Errorf("unexpected opcode in regular expression generation: %v", nodetype) - } - - return nil -} - -// To avoid recursion, we use a simple integer stack. -// This is the push. -func (w *writer) pushInt(i int) { - w.intStack = append(w.intStack, i) -} - -// Returns true if the stack is empty. -func (w *writer) emptyStack() bool { - return len(w.intStack) == 0 -} - -// This is the pop. -func (w *writer) popInt() int { - //get our item - idx := len(w.intStack) - 1 - i := w.intStack[idx] - //trim our slice - w.intStack = w.intStack[:idx] - return i -} - -// Returns the current position in the emitted code. -func (w *writer) curPos() int { - return w.curpos -} - -// Fixes up a jump instruction at the specified offset -// so that it jumps to the specified jumpDest. -func (w *writer) patchJump(offset, jumpDest int) { - w.emitted[offset+1] = jumpDest -} - -// Returns an index in the set table for a charset -// uses a map to eliminate duplicates. -func (w *writer) setCode(set *CharSet) int { - if w.counting { - return 0 - } - - buf := &bytes.Buffer{} - - set.mapHashFill(buf) - hash := buf.String() - i, ok := w.sethash[hash] - if !ok { - i = len(w.sethash) - w.sethash[hash] = i - w.settable = append(w.settable, set) - } - return i -} - -// Returns an index in the string table for a string. -// uses a map to eliminate duplicates. -func (w *writer) stringCode(str []rune) int { - if w.counting { - return 0 - } - - hash := string(str) - i, ok := w.stringhash[hash] - if !ok { - i = len(w.stringhash) - w.stringhash[hash] = i - w.stringtable = append(w.stringtable, str) - } - - return i -} - -// When generating code on a regex that uses a sparse set -// of capture slots, we hash them to a dense set of indices -// for an array of capture slots. Instead of doing the hash -// at match time, it's done at compile time, here. -func (w *writer) mapCapnum(capnum int) int { - if capnum == -1 { - return -1 - } - - if w.caps != nil { - return w.caps[capnum] - } - - return capnum -} - -// Emits a zero-argument operation. Note that the emit -// functions all run in two modes: they can emit code, or -// they can just count the size of the code. -func (w *writer) emit(op InstOp) { - if w.counting { - w.count++ - if opcodeBacktracks(op) { - w.trackcount++ - } - return - } - w.emitted[w.curpos] = int(op) - w.curpos++ -} - -// Emits a one-argument operation. -func (w *writer) emit1(op InstOp, opd1 int) { - if w.counting { - w.count += 2 - if opcodeBacktracks(op) { - w.trackcount++ - } - return - } - w.emitted[w.curpos] = int(op) - w.curpos++ - w.emitted[w.curpos] = opd1 - w.curpos++ -} - -// Emits a two-argument operation. -func (w *writer) emit2(op InstOp, opd1, opd2 int) { - if w.counting { - w.count += 3 - if opcodeBacktracks(op) { - w.trackcount++ - } - return - } - w.emitted[w.curpos] = int(op) - w.curpos++ - w.emitted[w.curpos] = opd1 - w.curpos++ - w.emitted[w.curpos] = opd2 - w.curpos++ -} diff --git a/vendor/github.com/dlclark/regexp2/testoutput1 b/vendor/github.com/dlclark/regexp2/testoutput1 deleted file mode 100644 index fbf63fdf2f..0000000000 --- a/vendor/github.com/dlclark/regexp2/testoutput1 +++ /dev/null @@ -1,7061 +0,0 @@ -# This set of tests is for features that are compatible with all versions of -# Perl >= 5.10, in non-UTF mode. It should run clean for the 8-bit, 16-bit, and -# 32-bit PCRE libraries, and also using the perltest.pl script. - -#forbid_utf -#newline_default lf any anycrlf -#perltest - -/the quick brown fox/ - the quick brown fox - 0: the quick brown fox - What do you know about the quick brown fox? - 0: the quick brown fox -\= Expect no match - The quick brown FOX -No match - What do you know about THE QUICK BROWN FOX? -No match - -/The quick brown fox/i - the quick brown fox - 0: the quick brown fox - The quick brown FOX - 0: The quick brown FOX - What do you know about the quick brown fox? - 0: the quick brown fox - What do you know about THE QUICK BROWN FOX? - 0: THE QUICK BROWN FOX - -/abcd\t\n\r\f\a\e\071\x3b\$\\\?caxyz/ - abcd\t\n\r\f\a\e9;\$\\?caxyz - 0: abcd\x09\x0a\x0d\x0c\x07\x1b9;$\?caxyz - -/a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz/ - abxyzpqrrrabbxyyyypqAzz - 0: abxyzpqrrrabbxyyyypqAzz - abxyzpqrrrabbxyyyypqAzz - 0: abxyzpqrrrabbxyyyypqAzz - aabxyzpqrrrabbxyyyypqAzz - 0: aabxyzpqrrrabbxyyyypqAzz - aaabxyzpqrrrabbxyyyypqAzz - 0: aaabxyzpqrrrabbxyyyypqAzz - aaaabxyzpqrrrabbxyyyypqAzz - 0: aaaabxyzpqrrrabbxyyyypqAzz - abcxyzpqrrrabbxyyyypqAzz - 0: abcxyzpqrrrabbxyyyypqAzz - aabcxyzpqrrrabbxyyyypqAzz - 0: aabcxyzpqrrrabbxyyyypqAzz - aaabcxyzpqrrrabbxyyyypAzz - 0: aaabcxyzpqrrrabbxyyyypAzz - aaabcxyzpqrrrabbxyyyypqAzz - 0: aaabcxyzpqrrrabbxyyyypqAzz - aaabcxyzpqrrrabbxyyyypqqAzz - 0: aaabcxyzpqrrrabbxyyyypqqAzz - aaabcxyzpqrrrabbxyyyypqqqAzz - 0: aaabcxyzpqrrrabbxyyyypqqqAzz - aaabcxyzpqrrrabbxyyyypqqqqAzz - 0: aaabcxyzpqrrrabbxyyyypqqqqAzz - aaabcxyzpqrrrabbxyyyypqqqqqAzz - 0: aaabcxyzpqrrrabbxyyyypqqqqqAzz - aaabcxyzpqrrrabbxyyyypqqqqqqAzz - 0: aaabcxyzpqrrrabbxyyyypqqqqqqAzz - aaaabcxyzpqrrrabbxyyyypqAzz - 0: aaaabcxyzpqrrrabbxyyyypqAzz - abxyzzpqrrrabbxyyyypqAzz - 0: abxyzzpqrrrabbxyyyypqAzz - aabxyzzzpqrrrabbxyyyypqAzz - 0: aabxyzzzpqrrrabbxyyyypqAzz - aaabxyzzzzpqrrrabbxyyyypqAzz - 0: aaabxyzzzzpqrrrabbxyyyypqAzz - aaaabxyzzzzpqrrrabbxyyyypqAzz - 0: aaaabxyzzzzpqrrrabbxyyyypqAzz - abcxyzzpqrrrabbxyyyypqAzz - 0: abcxyzzpqrrrabbxyyyypqAzz - aabcxyzzzpqrrrabbxyyyypqAzz - 0: aabcxyzzzpqrrrabbxyyyypqAzz - aaabcxyzzzzpqrrrabbxyyyypqAzz - 0: aaabcxyzzzzpqrrrabbxyyyypqAzz - aaaabcxyzzzzpqrrrabbxyyyypqAzz - 0: aaaabcxyzzzzpqrrrabbxyyyypqAzz - aaaabcxyzzzzpqrrrabbbxyyyypqAzz - 0: aaaabcxyzzzzpqrrrabbbxyyyypqAzz - aaaabcxyzzzzpqrrrabbbxyyyyypqAzz - 0: aaaabcxyzzzzpqrrrabbbxyyyyypqAzz - aaabcxyzpqrrrabbxyyyypABzz - 0: aaabcxyzpqrrrabbxyyyypABzz - aaabcxyzpqrrrabbxyyyypABBzz - 0: aaabcxyzpqrrrabbxyyyypABBzz - >>>aaabxyzpqrrrabbxyyyypqAzz - 0: aaabxyzpqrrrabbxyyyypqAzz - >aaaabxyzpqrrrabbxyyyypqAzz - 0: aaaabxyzpqrrrabbxyyyypqAzz - >>>>abcxyzpqrrrabbxyyyypqAzz - 0: abcxyzpqrrrabbxyyyypqAzz -\= Expect no match - abxyzpqrrabbxyyyypqAzz -No match - abxyzpqrrrrabbxyyyypqAzz -No match - abxyzpqrrrabxyyyypqAzz -No match - aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz -No match - aaaabcxyzzzzpqrrrabbbxyyypqAzz -No match - aaabcxyzpqrrrabbxyyyypqqqqqqqAzz -No match - -/^(abc){1,2}zz/ - abczz - 0: abczz - 1: abc - abcabczz - 0: abcabczz - 1: abc -\= Expect no match - zz -No match - abcabcabczz -No match - >>abczz -No match - -/^(b+?|a){1,2}?c/ - bc - 0: bc - 1: b - bbc - 0: bbc - 1: b - bbbc - 0: bbbc - 1: bb - bac - 0: bac - 1: a - bbac - 0: bbac - 1: a - aac - 0: aac - 1: a - abbbbbbbbbbbc - 0: abbbbbbbbbbbc - 1: bbbbbbbbbbb - bbbbbbbbbbbac - 0: bbbbbbbbbbbac - 1: a -\= Expect no match - aaac -No match - abbbbbbbbbbbac -No match - -/^(b+|a){1,2}c/ - bc - 0: bc - 1: b - bbc - 0: bbc - 1: bb - bbbc - 0: bbbc - 1: bbb - bac - 0: bac - 1: a - bbac - 0: bbac - 1: a - aac - 0: aac - 1: a - abbbbbbbbbbbc - 0: abbbbbbbbbbbc - 1: bbbbbbbbbbb - bbbbbbbbbbbac - 0: bbbbbbbbbbbac - 1: a -\= Expect no match - aaac -No match - abbbbbbbbbbbac -No match - -/^(b+|a){1,2}?bc/ - bbc - 0: bbc - 1: b - -/^(b*|ba){1,2}?bc/ - babc - 0: babc - 1: ba - bbabc - 0: bbabc - 1: ba - bababc - 0: bababc - 1: ba -\= Expect no match - bababbc -No match - babababc -No match - -/^(ba|b*){1,2}?bc/ - babc - 0: babc - 1: ba - bbabc - 0: bbabc - 1: ba - bababc - 0: bababc - 1: ba -\= Expect no match - bababbc -No match - babababc -No match - -#/^\ca\cA\c[;\c:/ -# \x01\x01\e;z -# 0: \x01\x01\x1b;z - -/^[ab\]cde]/ - athing - 0: a - bthing - 0: b - ]thing - 0: ] - cthing - 0: c - dthing - 0: d - ething - 0: e -\= Expect no match - fthing -No match - [thing -No match - \\thing -No match - -/^[]cde]/ - ]thing - 0: ] - cthing - 0: c - dthing - 0: d - ething - 0: e -\= Expect no match - athing -No match - fthing -No match - -/^[^ab\]cde]/ - fthing - 0: f - [thing - 0: [ - \\thing - 0: \ -\= Expect no match - athing -No match - bthing -No match - ]thing -No match - cthing -No match - dthing -No match - ething -No match - -/^[^]cde]/ - athing - 0: a - fthing - 0: f -\= Expect no match - ]thing -No match - cthing -No match - dthing -No match - ething -No match - -# DLC - I don't get this one -#/^\/ -#  -# 0: \x81 - -#updated to handle 16-bits utf8 -/^ÿ/ - ÿ - 0: \xc3\xbf - -/^[0-9]+$/ - 0 - 0: 0 - 1 - 0: 1 - 2 - 0: 2 - 3 - 0: 3 - 4 - 0: 4 - 5 - 0: 5 - 6 - 0: 6 - 7 - 0: 7 - 8 - 0: 8 - 9 - 0: 9 - 10 - 0: 10 - 100 - 0: 100 -\= Expect no match - abc -No match - -/^.*nter/ - enter - 0: enter - inter - 0: inter - uponter - 0: uponter - -/^xxx[0-9]+$/ - xxx0 - 0: xxx0 - xxx1234 - 0: xxx1234 -\= Expect no match - xxx -No match - -/^.+[0-9][0-9][0-9]$/ - x123 - 0: x123 - x1234 - 0: x1234 - xx123 - 0: xx123 - 123456 - 0: 123456 -\= Expect no match - 123 -No match - -/^.+?[0-9][0-9][0-9]$/ - x123 - 0: x123 - x1234 - 0: x1234 - xx123 - 0: xx123 - 123456 - 0: 123456 -\= Expect no match - 123 -No match - -/^([^!]+)!(.+)=apquxz\.ixr\.zzz\.ac\.uk$/ - abc!pqr=apquxz.ixr.zzz.ac.uk - 0: abc!pqr=apquxz.ixr.zzz.ac.uk - 1: abc - 2: pqr -\= Expect no match - !pqr=apquxz.ixr.zzz.ac.uk -No match - abc!=apquxz.ixr.zzz.ac.uk -No match - abc!pqr=apquxz:ixr.zzz.ac.uk -No match - abc!pqr=apquxz.ixr.zzz.ac.ukk -No match - -/:/ - Well, we need a colon: somewhere - 0: : -\= Expect no match - Fail without a colon -No match - -/([\da-f:]+)$/i - 0abc - 0: 0abc - 1: 0abc - abc - 0: abc - 1: abc - fed - 0: fed - 1: fed - E - 0: E - 1: E - :: - 0: :: - 1: :: - 5f03:12C0::932e - 0: 5f03:12C0::932e - 1: 5f03:12C0::932e - fed def - 0: def - 1: def - Any old stuff - 0: ff - 1: ff -\= Expect no match - 0zzz -No match - gzzz -No match - fed\x20 -No match - Any old rubbish -No match - -/^.*\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/ - .1.2.3 - 0: .1.2.3 - 1: 1 - 2: 2 - 3: 3 - A.12.123.0 - 0: A.12.123.0 - 1: 12 - 2: 123 - 3: 0 -\= Expect no match - .1.2.3333 -No match - 1.2.3 -No match - 1234.2.3 -No match - -/^(\d+)\s+IN\s+SOA\s+(\S+)\s+(\S+)\s*\(\s*$/ - 1 IN SOA non-sp1 non-sp2( - 0: 1 IN SOA non-sp1 non-sp2( - 1: 1 - 2: non-sp1 - 3: non-sp2 - 1 IN SOA non-sp1 non-sp2 ( - 0: 1 IN SOA non-sp1 non-sp2 ( - 1: 1 - 2: non-sp1 - 3: non-sp2 -\= Expect no match - 1IN SOA non-sp1 non-sp2( -No match - -/^[a-zA-Z\d][a-zA-Z\d\-]*(\.[a-zA-Z\d][a-zA-z\d\-]*)*\.$/ - a. - 0: a. - Z. - 0: Z. - 2. - 0: 2. - ab-c.pq-r. - 0: ab-c.pq-r. - 1: .pq-r - sxk.zzz.ac.uk. - 0: sxk.zzz.ac.uk. - 1: .uk - x-.y-. - 0: x-.y-. - 1: .y- -\= Expect no match - -abc.peq. -No match - -/^\*\.[a-z]([a-z\-\d]*[a-z\d]+)?(\.[a-z]([a-z\-\d]*[a-z\d]+)?)*$/ - *.a - 0: *.a - *.b0-a - 0: *.b0-a - 1: 0-a - *.c3-b.c - 0: *.c3-b.c - 1: 3-b - 2: .c - *.c-a.b-c - 0: *.c-a.b-c - 1: -a - 2: .b-c - 3: -c -\= Expect no match - *.0 -No match - *.a- -No match - *.a-b.c- -No match - *.c-a.0-c -No match - -/^(?=ab(de))(abd)(e)/ - abde - 0: abde - 1: de - 2: abd - 3: e - -/^(?!(ab)de|x)(abd)(f)/ - abdf - 0: abdf - 1: - 2: abd - 3: f - -/^(?=(ab(cd)))(ab)/ - abcd - 0: ab - 1: abcd - 2: cd - 3: ab - -/^[\da-f](\.[\da-f])*$/i - a.b.c.d - 0: a.b.c.d - 1: .d - A.B.C.D - 0: A.B.C.D - 1: .D - a.b.c.1.2.3.C - 0: a.b.c.1.2.3.C - 1: .C - -/^\".*\"\s*(;.*)?$/ - \"1234\" - 0: "1234" - \"abcd\" ; - 0: "abcd" ; - 1: ; - \"\" ; rhubarb - 0: "" ; rhubarb - 1: ; rhubarb -\= Expect no match - \"1234\" : things -No match - -/^$/ - \ - 0: -\= Expect no match - A non-empty line -No match - -/ ^ a (?# begins with a) b\sc (?# then b c) $ (?# then end)/x - ab c - 0: ab c -\= Expect no match - abc -No match - ab cde -No match - -/(?x) ^ a (?# begins with a) b\sc (?# then b c) $ (?# then end)/ - ab c - 0: ab c -\= Expect no match - abc -No match - ab cde -No match - -/^ a\ b[c ]d $/x - a bcd - 0: a bcd - a b d - 0: a b d -\= Expect no match - abcd -No match - ab d -No match - -/^(a(b(c)))(d(e(f)))(h(i(j)))(k(l(m)))$/ - abcdefhijklm - 0: abcdefhijklm - 1: abc - 2: bc - 3: c - 4: def - 5: ef - 6: f - 7: hij - 8: ij - 9: j -10: klm -11: lm -12: m - -/^(?:a(b(c)))(?:d(e(f)))(?:h(i(j)))(?:k(l(m)))$/ - abcdefhijklm - 0: abcdefhijklm - 1: bc - 2: c - 3: ef - 4: f - 5: ij - 6: j - 7: lm - 8: m - -#/^[\w][\W][\s][\S][\d][\D][\b][\n][\c]][\022]/ -# a+ Z0+\x08\n\x1d\x12 -# 0: a+ Z0+\x08\x0a\x1d\x12 - -/^[.^$|()*+?{,}]+/ - .^\$(*+)|{?,?} - 0: .^$(*+)|{?,?} - -/^a*\w/ - z - 0: z - az - 0: az - aaaz - 0: aaaz - a - 0: a - aa - 0: aa - aaaa - 0: aaaa - a+ - 0: a - aa+ - 0: aa - -/^a*?\w/ - z - 0: z - az - 0: a - aaaz - 0: a - a - 0: a - aa - 0: a - aaaa - 0: a - a+ - 0: a - aa+ - 0: a - -/^a+\w/ - az - 0: az - aaaz - 0: aaaz - aa - 0: aa - aaaa - 0: aaaa - aa+ - 0: aa - -/^a+?\w/ - az - 0: az - aaaz - 0: aa - aa - 0: aa - aaaa - 0: aa - aa+ - 0: aa - -/^\d{8}\w{2,}/ - 1234567890 - 0: 1234567890 - 12345678ab - 0: 12345678ab - 12345678__ - 0: 12345678__ -\= Expect no match - 1234567 -No match - -/^[aeiou\d]{4,5}$/ - uoie - 0: uoie - 1234 - 0: 1234 - 12345 - 0: 12345 - aaaaa - 0: aaaaa -\= Expect no match - 123456 -No match - -/^[aeiou\d]{4,5}?/ - uoie - 0: uoie - 1234 - 0: 1234 - 12345 - 0: 1234 - aaaaa - 0: aaaa - 123456 - 0: 1234 - -/\A(abc|def)=(\1){2,3}\Z/ - abc=abcabc - 0: abc=abcabc - 1: abc - 2: abc - def=defdefdef - 0: def=defdefdef - 1: def - 2: def -\= Expect no match - abc=defdef -No match - -/^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\11*(\3\4)\1(?#)2$/ - abcdefghijkcda2 - 0: abcdefghijkcda2 - 1: a - 2: b - 3: c - 4: d - 5: e - 6: f - 7: g - 8: h - 9: i -10: j -11: k -12: cd - abcdefghijkkkkcda2 - 0: abcdefghijkkkkcda2 - 1: a - 2: b - 3: c - 4: d - 5: e - 6: f - 7: g - 8: h - 9: i -10: j -11: k -12: cd - -/(cat(a(ract|tonic)|erpillar)) \1()2(3)/ - cataract cataract23 - 0: cataract cataract23 - 1: cataract - 2: aract - 3: ract - 4: - 5: 3 - catatonic catatonic23 - 0: catatonic catatonic23 - 1: catatonic - 2: atonic - 3: tonic - 4: - 5: 3 - caterpillar caterpillar23 - 0: caterpillar caterpillar23 - 1: caterpillar - 2: erpillar - 3: - 4: - 5: 3 - - -/^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]/ - From abcd Mon Sep 01 12:33:02 1997 - 0: From abcd Mon Sep 01 12:33 - 1: abcd - -/^From\s+\S+\s+([a-zA-Z]{3}\s+){2}\d{1,2}\s+\d\d:\d\d/ - From abcd Mon Sep 01 12:33:02 1997 - 0: From abcd Mon Sep 01 12:33 - 1: Sep - From abcd Mon Sep 1 12:33:02 1997 - 0: From abcd Mon Sep 1 12:33 - 1: Sep -\= Expect no match - From abcd Sep 01 12:33:02 1997 -No match - -/^12.34/s - 12\n34 - 0: 12\x0a34 - 12\r34 - 0: 12\x0d34 - -/\w+(?=\t)/ - the quick brown\t fox - 0: brown - -/foo(?!bar)(.*)/ - foobar is foolish see? - 0: foolish see? - 1: lish see? - -/(?:(?!foo)...|^.{0,2})bar(.*)/ - foobar crowbar etc - 0: rowbar etc - 1: etc - barrel - 0: barrel - 1: rel - 2barrel - 0: 2barrel - 1: rel - A barrel - 0: A barrel - 1: rel - -/^(\D*)(?=\d)(?!123)/ - abc456 - 0: abc - 1: abc -\= Expect no match - abc123 -No match - -/^1234(?# test newlines - inside)/ - 1234 - 0: 1234 - -/^1234 #comment in extended re - /x - 1234 - 0: 1234 - -/#rhubarb - abcd/x - abcd - 0: abcd - -/^abcd#rhubarb/x - abcd - 0: abcd - -/^(a)\1{2,3}(.)/ - aaab - 0: aaab - 1: a - 2: b - aaaab - 0: aaaab - 1: a - 2: b - aaaaab - 0: aaaaa - 1: a - 2: a - aaaaaab - 0: aaaaa - 1: a - 2: a - -/(?!^)abc/ - the abc - 0: abc -\= Expect no match - abc -No match - -/(?=^)abc/ - abc - 0: abc -\= Expect no match - the abc -No match - -/^[ab]{1,3}(ab*|b)/ - aabbbbb - 0: aabb - 1: b - -/^[ab]{1,3}?(ab*|b)/ - aabbbbb - 0: aabbbbb - 1: abbbbb - -/^[ab]{1,3}?(ab*?|b)/ - aabbbbb - 0: aa - 1: a - -/^[ab]{1,3}(ab*?|b)/ - aabbbbb - 0: aabb - 1: b - -/ (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* # optional leading comment -(?: (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -" (?: # opening quote... -[^\\\x80-\xff\n\015"] # Anything except backslash and quote -| # or -\\ [^\x80-\xff] # Escaped something (something != CR) -)* " # closing quote -) # initial word -(?: (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* \. (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -" (?: # opening quote... -[^\\\x80-\xff\n\015"] # Anything except backslash and quote -| # or -\\ [^\x80-\xff] # Escaped something (something != CR) -)* " # closing quote -) )* # further okay, if led by a period -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* @ (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # initial subdomain -(?: # -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* \. # if led by a period... -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # ...further okay -)* -# address -| # or -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -" (?: # opening quote... -[^\\\x80-\xff\n\015"] # Anything except backslash and quote -| # or -\\ [^\x80-\xff] # Escaped something (something != CR) -)* " # closing quote -) # one word, optionally followed by.... -(?: -[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] | # atom and space parts, or... -\( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) | # comments, or... - -" (?: # opening quote... -[^\\\x80-\xff\n\015"] # Anything except backslash and quote -| # or -\\ [^\x80-\xff] # Escaped something (something != CR) -)* " # closing quote -# quoted strings -)* -< (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* # leading < -(?: @ (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # initial subdomain -(?: # -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* \. # if led by a period... -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # ...further okay -)* - -(?: (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* , (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* @ (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # initial subdomain -(?: # -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* \. # if led by a period... -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # ...further okay -)* -)* # further okay, if led by comma -: # closing colon -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* )? # optional route -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -" (?: # opening quote... -[^\\\x80-\xff\n\015"] # Anything except backslash and quote -| # or -\\ [^\x80-\xff] # Escaped something (something != CR) -)* " # closing quote -) # initial word -(?: (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* \. (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -" (?: # opening quote... -[^\\\x80-\xff\n\015"] # Anything except backslash and quote -| # or -\\ [^\x80-\xff] # Escaped something (something != CR) -)* " # closing quote -) )* # further okay, if led by a period -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* @ (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # initial subdomain -(?: # -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* \. # if led by a period... -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* (?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| \[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) # ...further okay -)* -# address spec -(?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* > # trailing > -# name and address -) (?: [\040\t] | \( -(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* -\) )* # optional trailing comment -/x - Alan Other - 0: Alan Other - - 0: user@dom.ain - user\@dom.ain - 0: user@dom.ain - \"A. Other\" (a comment) - 0: "A. Other" (a comment) - A. Other (a comment) - 0: Other (a comment) - \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay - 0: "/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/"@x400-re.lay - A missing angle @,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -# Atom -| # or -" # " -[^\\\x80-\xff\n\015"] * # normal -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* -" # " -# Quoted string -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -\. -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -# Atom -| # or -" # " -[^\\\x80-\xff\n\015"] * # normal -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* -" # " -# Quoted string -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# additional words -)* -@ -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -\[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -(?: -\. -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -\[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -)* -# address -| # or -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -# Atom -| # or -" # " -[^\\\x80-\xff\n\015"] * # normal -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* -" # " -# Quoted string -) -# leading word -[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] * # "normal" atoms and or spaces -(?: -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -| -" # " -[^\\\x80-\xff\n\015"] * # normal -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* -" # " -) # "special" comment or quoted string -[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] * # more "normal" -)* -< -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# < -(?: -@ -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -\[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -(?: -\. -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -\[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -)* -(?: , -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -@ -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -\[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -(?: -\. -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -\[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -)* -)* # additional domains -: -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -)? # optional route -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -# Atom -| # or -" # " -[^\\\x80-\xff\n\015"] * # normal -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* -" # " -# Quoted string -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -\. -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -# Atom -| # or -" # " -[^\\\x80-\xff\n\015"] * # normal -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* -" # " -# Quoted string -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# additional words -)* -@ -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -\[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -(?: -\. -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -(?: -[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... -(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom -| -\[ # [ -(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff -\] # ] -) -[\040\t]* # Nab whitespace. -(?: -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: # ( -(?: \\ [^\x80-\xff] | -\( # ( -[^\\\x80-\xff\n\015()] * # normal* -(?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* -\) # ) -) # special -[^\\\x80-\xff\n\015()] * # normal* -)* # )* -\) # ) -[\040\t]* )* # If comment found, allow more spaces. -# optional trailing comments -)* -# address spec -> # > -# name and address -) -/x - Alan Other - 0: Alan Other - - 0: user@dom.ain - user\@dom.ain - 0: user@dom.ain - \"A. Other\" (a comment) - 0: "A. Other" - A. Other (a comment) - 0: Other - \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay - 0: "/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/"@x400-re.lay - A missing angle ?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f - -/P[^*]TAIRE[^*]{1,6}?LL/ - xxxxxxxxxxxPSTAIREISLLxxxxxxxxx - 0: PSTAIREISLL - -/P[^*]TAIRE[^*]{1,}?LL/ - xxxxxxxxxxxPSTAIREISLLxxxxxxxxx - 0: PSTAIREISLL - -/(\.\d\d[1-9]?)\d+/ - 1.230003938 - 0: .230003938 - 1: .23 - 1.875000282 - 0: .875000282 - 1: .875 - 1.235 - 0: .235 - 1: .23 - -/(\.\d\d((?=0)|\d(?=\d)))/ - 1.230003938 - 0: .23 - 1: .23 - 2: - 1.875000282 - 0: .875 - 1: .875 - 2: 5 -\= Expect no match - 1.235 -No match - -/\b(foo)\s+(\w+)/i - Food is on the foo table - 0: foo table - 1: foo - 2: table - -/foo(.*)bar/ - The food is under the bar in the barn. - 0: food is under the bar in the bar - 1: d is under the bar in the - -/foo(.*?)bar/ - The food is under the bar in the barn. - 0: food is under the bar - 1: d is under the - -/(.*)(\d*)/ - I have 2 numbers: 53147 - 0: I have 2 numbers: 53147 - 1: I have 2 numbers: 53147 - 2: - -/(.*)(\d+)/ - I have 2 numbers: 53147 - 0: I have 2 numbers: 53147 - 1: I have 2 numbers: 5314 - 2: 7 - -/(.*?)(\d*)/ - I have 2 numbers: 53147 - 0: - 1: - 2: - -/(.*?)(\d+)/ - I have 2 numbers: 53147 - 0: I have 2 - 1: I have - 2: 2 - -/(.*)(\d+)$/ - I have 2 numbers: 53147 - 0: I have 2 numbers: 53147 - 1: I have 2 numbers: 5314 - 2: 7 - -/(.*?)(\d+)$/ - I have 2 numbers: 53147 - 0: I have 2 numbers: 53147 - 1: I have 2 numbers: - 2: 53147 - -/(.*)\b(\d+)$/ - I have 2 numbers: 53147 - 0: I have 2 numbers: 53147 - 1: I have 2 numbers: - 2: 53147 - -/(.*\D)(\d+)$/ - I have 2 numbers: 53147 - 0: I have 2 numbers: 53147 - 1: I have 2 numbers: - 2: 53147 - -/^\D*(?!123)/ - ABC123 - 0: AB - -/^(\D*)(?=\d)(?!123)/ - ABC445 - 0: ABC - 1: ABC -\= Expect no match - ABC123 -No match - -/^[W-]46]/ - W46]789 - 0: W46] - -46]789 - 0: -46] -\= Expect no match - Wall -No match - Zebra -No match - 42 -No match - [abcd] -No match - ]abcd[ -No match - -/^[W-\]46]/ - W46]789 - 0: W - Wall - 0: W - Zebra - 0: Z - Xylophone - 0: X - 42 - 0: 4 - [abcd] - 0: [ - ]abcd[ - 0: ] - \\backslash - 0: \ -\= Expect no match - -46]789 -No match - well -No match - -/\d\d\/\d\d\/\d\d\d\d/ - 01/01/2000 - 0: 01/01/2000 - -/word (?:[a-zA-Z0-9]+ ){0,10}otherword/ - word cat dog elephant mussel cow horse canary baboon snake shark otherword - 0: word cat dog elephant mussel cow horse canary baboon snake shark otherword -\= Expect no match - word cat dog elephant mussel cow horse canary baboon snake shark -No match - -/word (?:[a-zA-Z0-9]+ ){0,300}otherword/ -\= Expect no match - word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope -No match - -/^(a){0,0}/ - bcd - 0: - abc - 0: - aab - 0: - -/^(a){0,1}/ - bcd - 0: - abc - 0: a - 1: a - aab - 0: a - 1: a - -/^(a){0,2}/ - bcd - 0: - abc - 0: a - 1: a - aab - 0: aa - 1: a - -/^(a){0,3}/ - bcd - 0: - abc - 0: a - 1: a - aab - 0: aa - 1: a - aaa - 0: aaa - 1: a - -/^(a){0,}/ - bcd - 0: - abc - 0: a - 1: a - aab - 0: aa - 1: a - aaa - 0: aaa - 1: a - aaaaaaaa - 0: aaaaaaaa - 1: a - -/^(a){1,1}/ - abc - 0: a - 1: a - aab - 0: a - 1: a -\= Expect no match - bcd -No match - -/^(a){1,2}/ - abc - 0: a - 1: a - aab - 0: aa - 1: a -\= Expect no match - bcd -No match - -/^(a){1,3}/ - abc - 0: a - 1: a - aab - 0: aa - 1: a - aaa - 0: aaa - 1: a -\= Expect no match - bcd -No match - -/^(a){1,}/ - abc - 0: a - 1: a - aab - 0: aa - 1: a - aaa - 0: aaa - 1: a - aaaaaaaa - 0: aaaaaaaa - 1: a -\= Expect no match - bcd -No match - -/.*\.gif/ - borfle\nbib.gif\nno - 0: bib.gif - -/.{0,}\.gif/ - borfle\nbib.gif\nno - 0: bib.gif - -/.*\.gif/m - borfle\nbib.gif\nno - 0: bib.gif - -/.*\.gif/s - borfle\nbib.gif\nno - 0: borfle\x0abib.gif - -/.*\.gif/ms - borfle\nbib.gif\nno - 0: borfle\x0abib.gif - -/.*$/ - borfle\nbib.gif\nno - 0: no - -/.*$/m - borfle\nbib.gif\nno - 0: borfle - -/.*$/s - borfle\nbib.gif\nno - 0: borfle\x0abib.gif\x0ano - -/.*$/ms - borfle\nbib.gif\nno - 0: borfle\x0abib.gif\x0ano - -/.*$/ - borfle\nbib.gif\nno\n - 0: no - -/.*$/m - borfle\nbib.gif\nno\n - 0: borfle - -/.*$/s - borfle\nbib.gif\nno\n - 0: borfle\x0abib.gif\x0ano\x0a - -/.*$/ms - borfle\nbib.gif\nno\n - 0: borfle\x0abib.gif\x0ano\x0a - -/(.*X|^B)/ - abcde\n1234Xyz - 0: 1234X - 1: 1234X - BarFoo - 0: B - 1: B -\= Expect no match - abcde\nBar -No match - -/(.*X|^B)/m - abcde\n1234Xyz - 0: 1234X - 1: 1234X - BarFoo - 0: B - 1: B - abcde\nBar - 0: B - 1: B - -/(.*X|^B)/s - abcde\n1234Xyz - 0: abcde\x0a1234X - 1: abcde\x0a1234X - BarFoo - 0: B - 1: B -\= Expect no match - abcde\nBar -No match - -/(.*X|^B)/ms - abcde\n1234Xyz - 0: abcde\x0a1234X - 1: abcde\x0a1234X - BarFoo - 0: B - 1: B - abcde\nBar - 0: B - 1: B - -/(?s)(.*X|^B)/ - abcde\n1234Xyz - 0: abcde\x0a1234X - 1: abcde\x0a1234X - BarFoo - 0: B - 1: B -\= Expect no match - abcde\nBar -No match - -/(?s:.*X|^B)/ - abcde\n1234Xyz - 0: abcde\x0a1234X - BarFoo - 0: B -\= Expect no match - abcde\nBar -No match - -/^.*B/ -\= Expect no match - abc\nB -No match - -/(?s)^.*B/ - abc\nB - 0: abc\x0aB - -/(?m)^.*B/ - abc\nB - 0: B - -/(?ms)^.*B/ - abc\nB - 0: abc\x0aB - -/(?ms)^B/ - abc\nB - 0: B - -/(?s)B$/ - B\n - 0: B - -/^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/ - 123456654321 - 0: 123456654321 - -/^\d\d\d\d\d\d\d\d\d\d\d\d/ - 123456654321 - 0: 123456654321 - -/^[\d][\d][\d][\d][\d][\d][\d][\d][\d][\d][\d][\d]/ - 123456654321 - 0: 123456654321 - -/^[abc]{12}/ - abcabcabcabc - 0: abcabcabcabc - -/^[a-c]{12}/ - abcabcabcabc - 0: abcabcabcabc - -/^(a|b|c){12}/ - abcabcabcabc - 0: abcabcabcabc - 1: c - -/^[abcdefghijklmnopqrstuvwxy0123456789]/ - n - 0: n -\= Expect no match - z -No match - -/abcde{0,0}/ - abcd - 0: abcd -\= Expect no match - abce -No match - -/ab[cd]{0,0}e/ - abe - 0: abe -\= Expect no match - abcde -No match - -/ab(c){0,0}d/ - abd - 0: abd -\= Expect no match - abcd -No match - -/a(b*)/ - a - 0: a - 1: - ab - 0: ab - 1: b - abbbb - 0: abbbb - 1: bbbb -\= Expect no match - bbbbb -No match - -/ab\d{0}e/ - abe - 0: abe -\= Expect no match - ab1e -No match - -/"([^\\"]+|\\.)*"/ - the \"quick\" brown fox - 0: "quick" - 1: quick - \"the \\\"quick\\\" brown fox\" - 0: "the \"quick\" brown fox" - 1: brown fox - -/]{0,})>]{0,})>([\d]{0,}\.)(.*)((
([\w\W\s\d][^<>]{0,})|[\s]{0,}))<\/a><\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><\/TR>/is - 43.Word Processor
(N-1286)
Lega lstaff.comCA - Statewide - 0: 43.Word Processor
(N-1286)
Lega lstaff.comCA - Statewide - 1: BGCOLOR='#DBE9E9' - 2: align=left valign=top - 3: 43. - 4: Word Processor
(N-1286) - 5: - 6: - 7: - 8: align=left valign=top - 9: Lega lstaff.com -10: align=left valign=top -11: CA - Statewide - -/a[^a]b/ - acb - 0: acb - a\nb - 0: a\x0ab - -/a.b/ - acb - 0: acb -\= Expect no match - a\nb -No match - -/a[^a]b/s - acb - 0: acb - a\nb - 0: a\x0ab - -/a.b/s - acb - 0: acb - a\nb - 0: a\x0ab - -/^(b+?|a){1,2}?c/ - bac - 0: bac - 1: a - bbac - 0: bbac - 1: a - bbbac - 0: bbbac - 1: a - bbbbac - 0: bbbbac - 1: a - bbbbbac - 0: bbbbbac - 1: a - -/^(b+|a){1,2}?c/ - bac - 0: bac - 1: a - bbac - 0: bbac - 1: a - bbbac - 0: bbbac - 1: a - bbbbac - 0: bbbbac - 1: a - bbbbbac - 0: bbbbbac - 1: a - -/(?!\A)x/m - a\bx\n - 0: x - a\nx\n - 0: x -\= Expect no match - x\nb\n -No match - -/(A|B)*?CD/ - CD - 0: CD - -/(A|B)*CD/ - CD - 0: CD - -/(AB)*?\1/ - ABABAB - 0: ABAB - 1: AB - -/(AB)*\1/ - ABABAB - 0: ABABAB - 1: AB - -/(?.*/)foo" - /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/and/foo - 0: /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/and/foo -\= Expect no match - /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/it/you/see/ -No match - -/(?>(\.\d\d[1-9]?))\d+/ - 1.230003938 - 0: .230003938 - 1: .23 - 1.875000282 - 0: .875000282 - 1: .875 -\= Expect no match - 1.235 -No match - -/^((?>\w+)|(?>\s+))*$/ - now is the time for all good men to come to the aid of the party - 0: now is the time for all good men to come to the aid of the party - 1: party -\= Expect no match - this is not a line with only words and spaces! -No match - -/(\d+)(\w)/ - 12345a - 0: 12345a - 1: 12345 - 2: a - 12345+ - 0: 12345 - 1: 1234 - 2: 5 - -/((?>\d+))(\w)/ - 12345a - 0: 12345a - 1: 12345 - 2: a -\= Expect no match - 12345+ -No match - -/(?>a+)b/ - aaab - 0: aaab - -/((?>a+)b)/ - aaab - 0: aaab - 1: aaab - -/(?>(a+))b/ - aaab - 0: aaab - 1: aaa - -/(?>b)+/ - aaabbbccc - 0: bbb - -/(?>a+|b+|c+)*c/ - aaabbbbccccd - 0: aaabbbbc - -/((?>[^()]+)|\([^()]*\))+/ - ((abc(ade)ufh()()x - 0: abc(ade)ufh()()x - 1: x - -/\(((?>[^()]+)|\([^()]+\))+\)/ - (abc) - 0: (abc) - 1: abc - (abc(def)xyz) - 0: (abc(def)xyz) - 1: xyz -\= Expect no match - ((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -No match - -/a(?-i)b/i - ab - 0: ab - Ab - 0: Ab -\= Expect no match - aB -No match - AB -No match - -/(a (?x)b c)d e/ - a bcd e - 0: a bcd e - 1: a bc -\= Expect no match - a b cd e -No match - abcd e -No match - a bcde -No match - -/(a b(?x)c d (?-x)e f)/ - a bcde f - 0: a bcde f - 1: a bcde f -\= Expect no match - abcdef -No match - -/(a(?i)b)c/ - abc - 0: abc - 1: ab - aBc - 0: aBc - 1: aB -\= Expect no match - abC -No match - aBC -No match - Abc -No match - ABc -No match - ABC -No match - AbC -No match - -/a(?i:b)c/ - abc - 0: abc - aBc - 0: aBc -\= Expect no match - ABC -No match - abC -No match - aBC -No match - -/a(?i:b)*c/ - aBc - 0: aBc - aBBc - 0: aBBc -\= Expect no match - aBC -No match - aBBC -No match - -/a(?=b(?i)c)\w\wd/ - abcd - 0: abcd - abCd - 0: abCd -\= Expect no match - aBCd -No match - abcD -No match - -/(?s-i:more.*than).*million/i - more than million - 0: more than million - more than MILLION - 0: more than MILLION - more \n than Million - 0: more \x0a than Million -\= Expect no match - MORE THAN MILLION -No match - more \n than \n million -No match - -/(?:(?s-i)more.*than).*million/i - more than million - 0: more than million - more than MILLION - 0: more than MILLION - more \n than Million - 0: more \x0a than Million -\= Expect no match - MORE THAN MILLION -No match - more \n than \n million -No match - -/(?>a(?i)b+)+c/ - abc - 0: abc - aBbc - 0: aBbc - aBBc - 0: aBBc -\= Expect no match - Abc -No match - abAb -No match - abbC -No match - -/(?=a(?i)b)\w\wc/ - abc - 0: abc - aBc - 0: aBc -\= Expect no match - Ab -No match - abC -No match - aBC -No match - -/(?<=a(?i)b)(\w\w)c/ - abxxc - 0: xxc - 1: xx - aBxxc - 0: xxc - 1: xx -\= Expect no match - Abxxc -No match - ABxxc -No match - abxxC -No match - -/(?:(a)|b)(?(1)A|B)/ - aA - 0: aA - 1: a - bB - 0: bB -\= Expect no match - aB -No match - bA -No match - -/^(a)?(?(1)a|b)+$/ - aa - 0: aa - 1: a - b - 0: b - bb - 0: bb -\= Expect no match - ab -No match - -# Perl gets this next one wrong if the pattern ends with $; in that case it -# fails to match "12". - -/^(?(?=abc)\w{3}:|\d\d)/ - abc: - 0: abc: - 12 - 0: 12 - 123 - 0: 12 -\= Expect no match - xyz -No match - -/^(?(?!abc)\d\d|\w{3}:)$/ - abc: - 0: abc: - 12 - 0: 12 -\= Expect no match - 123 -No match - xyz -No match - -/(?(?<=foo)bar|cat)/ - foobar - 0: bar - cat - 0: cat - fcat - 0: cat - focat - 0: cat -\= Expect no match - foocat -No match - -/(?(?a*)*/ - a - 0: a - aa - 0: aa - aaaa - 0: aaaa - -/(abc|)+/ - abc - 0: abc - 1: - abcabc - 0: abcabc - 1: - abcabcabc - 0: abcabcabc - 1: - xyz - 0: - 1: - -/([a]*)*/ - a - 0: a - 1: - aaaaa - 0: aaaaa - 1: - -/([ab]*)*/ - a - 0: a - 1: - b - 0: b - 1: - ababab - 0: ababab - 1: - aaaabcde - 0: aaaab - 1: - bbbb - 0: bbbb - 1: - -/([^a]*)*/ - b - 0: b - 1: - bbbb - 0: bbbb - 1: - aaa - 0: - 1: - -/([^ab]*)*/ - cccc - 0: cccc - 1: - abab - 0: - 1: - -/([a]*?)*/ - a - 0: - 1: - aaaa - 0: - 1: - -/([ab]*?)*/ - a - 0: - 1: - b - 0: - 1: - abab - 0: - 1: - baba - 0: - 1: - -/([^a]*?)*/ - b - 0: - 1: - bbbb - 0: - 1: - aaa - 0: - 1: - -/([^ab]*?)*/ - c - 0: - 1: - cccc - 0: - 1: - baba - 0: - 1: - -/(?>a*)*/ - a - 0: a - aaabcde - 0: aaa - -/((?>a*))*/ - aaaaa - 0: aaaaa - 1: - aabbaa - 0: aa - 1: - -/((?>a*?))*/ - aaaaa - 0: - 1: - aabbaa - 0: - 1: - -/(?(?=[^a-z]+[a-z]) \d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} ) /x - 12-sep-98 - 0: 12-sep-98 - 12-09-98 - 0: 12-09-98 -\= Expect no match - sep-12-98 -No match - -/(?<=(foo))bar\1/ - foobarfoo - 0: barfoo - 1: foo - foobarfootling - 0: barfoo - 1: foo -\= Expect no match - foobar -No match - barfoo -No match - -/(?i:saturday|sunday)/ - saturday - 0: saturday - sunday - 0: sunday - Saturday - 0: Saturday - Sunday - 0: Sunday - SATURDAY - 0: SATURDAY - SUNDAY - 0: SUNDAY - SunDay - 0: SunDay - -/(a(?i)bc|BB)x/ - abcx - 0: abcx - 1: abc - aBCx - 0: aBCx - 1: aBC - bbx - 0: bbx - 1: bb - BBx - 0: BBx - 1: BB -\= Expect no match - abcX -No match - aBCX -No match - bbX -No match - BBX -No match - -/^([ab](?i)[cd]|[ef])/ - ac - 0: ac - 1: ac - aC - 0: aC - 1: aC - bD - 0: bD - 1: bD - elephant - 0: e - 1: e - Europe - 0: E - 1: E - frog - 0: f - 1: f - France - 0: F - 1: F -\= Expect no match - Africa -No match - -/^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)/ - ab - 0: ab - 1: ab - aBd - 0: aBd - 1: aBd - xy - 0: xy - 1: xy - xY - 0: xY - 1: xY - zebra - 0: z - 1: z - Zambesi - 0: Z - 1: Z -\= Expect no match - aCD -No match - XY -No match - -/(?<=foo\n)^bar/m - foo\nbar - 0: bar -\= Expect no match - bar -No match - baz\nbar -No match - -/(?<=(?]&/ - <&OUT - 0: <& - -/^(a\1?){4}$/ - aaaaaaaaaa - 0: aaaaaaaaaa - 1: aaaa -\= Expect no match - AB -No match - aaaaaaaaa -No match - aaaaaaaaaaa -No match - -/^(a(?(1)\1)){4}$/ - aaaaaaaaaa - 0: aaaaaaaaaa - 1: aaaa -\= Expect no match - aaaaaaaaa -No match - aaaaaaaaaaa -No match - -/(?:(f)(o)(o)|(b)(a)(r))*/ - foobar - 0: foobar - 1: f - 2: o - 3: o - 4: b - 5: a - 6: r - -/(?<=a)b/ - ab - 0: b -\= Expect no match - cb -No match - b -No match - -/(? - 2: abcd - xy:z:::abcd - 0: xy:z:::abcd - 1: xy:z::: - 2: abcd - -/^[^bcd]*(c+)/ - aexycd - 0: aexyc - 1: c - -/(a*)b+/ - caab - 0: aab - 1: aa - -/([\w:]+::)?(\w+)$/ - abcd - 0: abcd - 1: - 2: abcd - xy:z:::abcd - 0: xy:z:::abcd - 1: xy:z::: - 2: abcd -\= Expect no match - abcd: -No match - abcd: -No match - -/^[^bcd]*(c+)/ - aexycd - 0: aexyc - 1: c - -/(>a+)ab/ - -/(?>a+)b/ - aaab - 0: aaab - -/([[:]+)/ - a:[b]: - 0: :[ - 1: :[ - -/([[=]+)/ - a=[b]= - 0: =[ - 1: =[ - -/([[.]+)/ - a.[b]. - 0: .[ - 1: .[ - -/((?>a+)b)/ - aaab - 0: aaab - 1: aaab - -/(?>(a+))b/ - aaab - 0: aaab - 1: aaa - -/((?>[^()]+)|\([^()]*\))+/ - ((abc(ade)ufh()()x - 0: abc(ade)ufh()()x - 1: x - -/a\Z/ -\= Expect no match - aaab -No match - a\nb\n -No match - -/b\Z/ - a\nb\n - 0: b - -/b\z/ - -/b\Z/ - a\nb - 0: b - -/b\z/ - a\nb - 0: b - -/^(?>(?(1)\.|())[^\W_](?>[a-z0-9-]*[^\W_])?)+$/ - a - 0: a - 1: - abc - 0: abc - 1: - a-b - 0: a-b - 1: - 0-9 - 0: 0-9 - 1: - a.b - 0: a.b - 1: - 5.6.7 - 0: 5.6.7 - 1: - the.quick.brown.fox - 0: the.quick.brown.fox - 1: - a100.b200.300c - 0: a100.b200.300c - 1: - 12-ab.1245 - 0: 12-ab.1245 - 1: -\= Expect no match - \ -No match - .a -No match - -a -No match - a- -No match - a. -No match - a_b -No match - a.- -No match - a.. -No match - ab..bc -No match - the.quick.brown.fox- -No match - the.quick.brown.fox. -No match - the.quick.brown.fox_ -No match - the.quick.brown.fox+ -No match - -/(?>.*)(?<=(abcd|wxyz))/ - alphabetabcd - 0: alphabetabcd - 1: abcd - endingwxyz - 0: endingwxyz - 1: wxyz -\= Expect no match - a rather long string that doesn't end with one of them -No match - -/word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword/ - word cat dog elephant mussel cow horse canary baboon snake shark otherword - 0: word cat dog elephant mussel cow horse canary baboon snake shark otherword -\= Expect no match - word cat dog elephant mussel cow horse canary baboon snake shark -No match - -/word (?>[a-zA-Z0-9]+ ){0,30}otherword/ -\= Expect no match - word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope -No match - -/(?<=\d{3}(?!999))foo/ - 999foo - 0: foo - 123999foo - 0: foo -\= Expect no match - 123abcfoo -No match - -/(?<=(?!...999)\d{3})foo/ - 999foo - 0: foo - 123999foo - 0: foo -\= Expect no match - 123abcfoo -No match - -/(?<=\d{3}(?!999)...)foo/ - 123abcfoo - 0: foo - 123456foo - 0: foo -\= Expect no match - 123999foo -No match - -/(?<=\d{3}...)(? - 2: - 3: abcd -
- 2: - 3: abcd - \s*)=(?>\s*) # find - 2: - 3: abcd - Z)+|A)*/ - ZABCDEFG - 0: ZA - 1: A - -/((?>)+|A)*/ - ZABCDEFG - 0: - 1: - -/^[\d-a]/ - abcde - 0: a - -things - 0: - - 0digit - 0: 0 -\= Expect no match - bcdef -No match - -/[\s]+/ - > \x09\x0a\x0c\x0d\x0b< - 0: \x09\x0a\x0c\x0d\x0b - -/\s+/ - > \x09\x0a\x0c\x0d\x0b< - 0: \x09\x0a\x0c\x0d\x0b - -/a b/x - ab - 0: ab - -/(?!\A)x/m - a\nxb\n - 0: x - -/(?!^)x/m -\= Expect no match - a\nxb\n -No match - -#/abc\Qabc\Eabc/ -# abcabcabc -# 0: abcabcabc - -#/abc\Q(*+|\Eabc/ -# abc(*+|abc -# 0: abc(*+|abc - -#/ abc\Q abc\Eabc/x -# abc abcabc -# 0: abc abcabc -#\= Expect no match -# abcabcabc -#No match - -#/abc#comment -# \Q#not comment -# literal\E/x -# abc#not comment\n literal -# 0: abc#not comment\x0a literal - -#/abc#comment -# \Q#not comment -# literal/x -# abc#not comment\n literal -# 0: abc#not comment\x0a literal - -#/abc#comment -# \Q#not comment -# literal\E #more comment -# /x -# abc#not comment\n literal -# 0: abc#not comment\x0a literal - -#/abc#comment -# \Q#not comment -# literal\E #more comment/x -# abc#not comment\n literal -# 0: abc#not comment\x0a literal - -#/\Qabc\$xyz\E/ -# abc\\\$xyz -# 0: abc\$xyz - -#/\Qabc\E\$\Qxyz\E/ -# abc\$xyz -# 0: abc$xyz - -/\Gabc/ - abc - 0: abc -\= Expect no match - xyzabc -No match - -/a(?x: b c )d/ - XabcdY - 0: abcd -\= Expect no match - Xa b c d Y -No match - -/((?x)x y z | a b c)/ - XabcY - 0: abc - 1: abc - AxyzB - 0: xyz - 1: xyz - -/(?i)AB(?-i)C/ - XabCY - 0: abC -\= Expect no match - XabcY -No match - -/((?i)AB(?-i)C|D)E/ - abCE - 0: abCE - 1: abC - DE - 0: DE - 1: D -\= Expect no match - abcE -No match - abCe -No match - dE -No match - De -No match - -/(.*)\d+\1/ - abc123abc - 0: abc123abc - 1: abc - abc123bc - 0: bc123bc - 1: bc - -/(.*)\d+\1/s - abc123abc - 0: abc123abc - 1: abc - abc123bc - 0: bc123bc - 1: bc - -/((.*))\d+\1/ - abc123abc - 0: abc123abc - 1: abc - 2: abc - abc123bc - 0: bc123bc - 1: bc - 2: bc - -# This tests for an IPv6 address in the form where it can have up to -# eight components, one and only one of which is empty. This must be -# an internal component. - -/^(?!:) # colon disallowed at start - (?: # start of item - (?: [0-9a-f]{1,4} | # 1-4 hex digits or - (?(1)0 | () ) ) # if null previously matched, fail; else null - : # followed by colon - ){1,7} # end item; 1-7 of them required - [0-9a-f]{1,4} $ # final hex number at end of string - (?(1)|.) # check that there was an empty component - /ix - a123::a123 - 0: a123::a123 - 1: - a123:b342::abcd - 0: a123:b342::abcd - 1: - a123:b342::324e:abcd - 0: a123:b342::324e:abcd - 1: - a123:ddde:b342::324e:abcd - 0: a123:ddde:b342::324e:abcd - 1: - a123:ddde:b342::324e:dcba:abcd - 0: a123:ddde:b342::324e:dcba:abcd - 1: - a123:ddde:9999:b342::324e:dcba:abcd - 0: a123:ddde:9999:b342::324e:dcba:abcd - 1: -\= Expect no match - 1:2:3:4:5:6:7:8 -No match - a123:bce:ddde:9999:b342::324e:dcba:abcd -No match - a123::9999:b342::324e:dcba:abcd -No match - abcde:2:3:4:5:6:7:8 -No match - ::1 -No match - abcd:fee0:123:: -No match - :1 -No match - 1: -No match - -#/[z\Qa-d]\E]/ -# z -# 0: z -# a -# 0: a -# - -# 0: - -# d -# 0: d -# ] -# 0: ] -#\= Expect no match -# b -#No match - -#TODO: PCRE has an optimization to make this workable, .NET does not -#/(a+)*b/ -#\= Expect no match -# aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -#No match - -# All these had to be updated because we understand unicode -# and this looks like it's expecting single byte matches - -# .NET generates \xe4...not sure what's up, might just be different code pages -/(?i)reg(?:ul(?:[aä]|ae)r|ex)/ - REGular - 0: REGular - regulaer - 0: regulaer - Regex - 0: Regex - regulär - 0: regul\xc3\xa4r - -#/Åæåä[à-ÿÀ-ß]+/ -# Åæåäà -# 0: \xc5\xe6\xe5\xe4\xe0 -# Åæåäÿ -# 0: \xc5\xe6\xe5\xe4\xff -# ÅæåäÀ -# 0: \xc5\xe6\xe5\xe4\xc0 -# Åæåäß -# 0: \xc5\xe6\xe5\xe4\xdf - -/(?<=Z)X./ - \x84XAZXB - 0: XB - -/ab cd (?x) de fg/ - ab cd defg - 0: ab cd defg - -/ab cd(?x) de fg/ - ab cddefg - 0: ab cddefg -\= Expect no match - abcddefg -No match - -/(? - 2: - D - 0: D - 1: - 2: - -# this is really long with debug -- removing for now -#/(a|)*\d/ -# aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 -# 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 -# 1: -#\= Expect no match -# aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -#No match - -/(?>a|)*\d/ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 - 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 -\= Expect no match - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -No match - -/(?:a|)*\d/ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 - 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4 -\= Expect no match - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -No match - -/^(?s)(?>.*)(? - 2: a - -/(?>(a))b|(a)c/ - ac - 0: ac - 1: - 2: a - -/(?=(a))ab|(a)c/ - ac - 0: ac - 1: - 2: a - -/((?>(a))b|(a)c)/ - ac - 0: ac - 1: ac - 2: - 3: a - -/(?=(?>(a))b|(a)c)(..)/ - ac - 0: ac - 1: - 2: a - 3: ac - -/(?>(?>(a))b|(a)c)/ - ac - 0: ac - 1: - 2: a - -/((?>(a+)b)+(aabab))/ - aaaabaaabaabab - 0: aaaabaaabaabab - 1: aaaabaaabaabab - 2: aaa - 3: aabab - -/(?>a+|ab)+?c/ -\= Expect no match - aabc -No match - -/(?>a+|ab)+c/ -\= Expect no match - aabc -No match - -/(?:a+|ab)+c/ - aabc - 0: aabc - -/^(?:a|ab)+c/ - aaaabc - 0: aaaabc - -/(?=abc){0}xyz/ - xyz - 0: xyz - -/(?=abc){1}xyz/ -\= Expect no match - xyz -No match - -/(?=(a))?./ - ab - 0: a - 1: a - bc - 0: b - -/(?=(a))??./ - ab - 0: a - bc - 0: b - -/^(?!a){0}\w+/ - aaaaa - 0: aaaaa - -/(?<=(abc))?xyz/ - abcxyz - 0: xyz - 1: abc - pqrxyz - 0: xyz - -/^[g]+/ - ggg<<>> - 0: ggg<<>> -\= Expect no match - \\ga -No match - -/^[ga]+/ - gggagagaxyz - 0: gggagaga - -/[:a]xxx[b:]/ - :xxx: - 0: :xxx: - -/(?<=a{2})b/i - xaabc - 0: b -\= Expect no match - xabc -No match - -/(? -# 4: -# 5: c -# 6: d -# 7: Y - -#/^X(?7)(a)(?|(b|(?|(r)|(t))(s))|(q))(c)(d)(Y)/ -# XYabcdY -# 0: XYabcdY -# 1: a -# 2: b -# 3: -# 4: -# 5: c -# 6: d -# 7: Y - -/(?'abc'\w+):\k{2}/ - a:aaxyz - 0: a:aa - 1: a - ab:ababxyz - 0: ab:abab - 1: ab -\= Expect no match - a:axyz -No match - ab:abxyz -No match - -/^(?a)? (?(ab)b|c) (?(ab)d|e)/x - abd - 0: abd - 1: a - ce - 0: ce - -# .NET has more consistent grouping numbers with these dupe groups for the two options -/(?:a(? (?')|(?")) |b(? (?')|(?")) ) (?(quote)[a-z]+|[0-9]+)/x,dupnames - a\"aaaaa - 0: a"aaaaa - 1: " - 2: - 3: " - b\"aaaaa - 0: b"aaaaa - 1: " - 2: - 3: " -\= Expect no match - b\"11111 -No match - -#/(?P(?P0)(?P>L1)|(?P>L2))/ -# 0 -# 0: 0 -# 1: 0 -# 00 -# 0: 00 -# 1: 00 -# 2: 0 -# 0000 -# 0: 0000 -# 1: 0000 -# 2: 0 - -#/(?P(?P0)|(?P>L2)(?P>L1))/ -# 0 -# 0: 0 -# 1: 0 -# 2: 0 -# 00 -# 0: 0 -# 1: 0 -# 2: 0 -# 0000 -# 0: 0 -# 1: 0 -# 2: 0 - -# Check the use of names for failure - -# Check opening parens in comment when seeking forward reference. - -#/(?P(?P=abn)xxx|)+/ -# xxx -# 0: -# 1: - -#Posses -/^(a)?(\w)/ - aaaaX - 0: aa - 1: a - 2: a - YZ - 0: Y - 1: - 2: Y - -#Posses -/^(?:a)?(\w)/ - aaaaX - 0: aa - 1: a - YZ - 0: Y - 1: Y - -/\A.*?(a|bc)/ - ba - 0: ba - 1: a - -/\A.*?(?:a|bc|d)/ - ba - 0: ba - -# -------------------------- - -/(another)?(\1?)test/ - hello world test - 0: test - 1: - 2: - -/(another)?(\1+)test/ -\= Expect no match - hello world test -No match - -/((?:a?)*)*c/ - aac - 0: aac - 1: - -/((?>a?)*)*c/ - aac - 0: aac - 1: - -/(?>.*?a)(?<=ba)/ - aba - 0: ba - -/(?:.*?a)(?<=ba)/ - aba - 0: aba - -/(?>.*?a)b/s - aab - 0: ab - -/(?>.*?a)b/ - aab - 0: ab - -/(?>^a)b/s -\= Expect no match - aab -No match - -/(?>.*?)(?<=(abcd)|(wxyz))/ - alphabetabcd - 0: - 1: abcd - endingwxyz - 0: - 1: - 2: wxyz - -/(?>.*)(?<=(abcd)|(wxyz))/ - alphabetabcd - 0: alphabetabcd - 1: abcd - endingwxyz - 0: endingwxyz - 1: - 2: wxyz - -"(?>.*)foo" -\= Expect no match - abcdfooxyz -No match - -"(?>.*?)foo" - abcdfooxyz - 0: foo - -# Tests that try to figure out how Perl works. My hypothesis is that the first -# verb that is backtracked onto is the one that acts. This seems to be the case -# almost all the time, but there is one exception that is perhaps a bug. - -/a(?=bc).|abd/ - abd - 0: abd - abc - 0: ab - -/a(?>bc)d|abd/ - abceabd - 0: abd - -# These tests were formerly in test 2, but changes in PCRE and Perl have -# made them compatible. - -/^(a)?(?(1)a|b)+$/ -\= Expect no match - a -No match - -# ---- - -/^\d*\w{4}/ - 1234 - 0: 1234 -\= Expect no match - 123 -No match - -/^[^b]*\w{4}/ - aaaa - 0: aaaa -\= Expect no match - aaa -No match - -/^[^b]*\w{4}/i - aaaa - 0: aaaa -\= Expect no match - aaa -No match - -/^a*\w{4}/ - aaaa - 0: aaaa -\= Expect no match - aaa -No match - -/^a*\w{4}/i - aaaa - 0: aaaa -\= Expect no match - aaa -No match - -/(?:(?foo)|(?bar))\k/dupnames - foofoo - 0: foofoo - 1: foo - barbar - 0: barbar - 1: bar - -# A notable difference between PCRE and .NET. According to -# the PCRE docs: -# If you make a subroutine call to a non-unique named -# subpattern, the one that corresponds to the first -# occurrence of the name is used. In the absence of -# duplicate numbers (see the previous section) this is -# the one with the lowest number. -# .NET takes the most recently captured number according to MSDN: -# A backreference refers to the most recent definition of -# a group (the definition most immediately to the left, -# when matching left to right). When a group makes multiple -# captures, a backreference refers to the most recent capture. - -#/(?A)(?:(?foo)|(?bar))\k/dupnames -# AfooA -# 0: AfooA -# 1: A -# 2: foo -# AbarA -# 0: AbarA -# 1: A -# 2: -# 3: bar -#\= Expect no match -# Afoofoo -#No match -# Abarbar -#No match - -/^(\d+)\s+IN\s+SOA\s+(\S+)\s+(\S+)\s*\(\s*$/ - 1 IN SOA non-sp1 non-sp2( - 0: 1 IN SOA non-sp1 non-sp2( - 1: 1 - 2: non-sp1 - 3: non-sp2 - -# TODO: .NET's group number ordering here in the second example is a bit odd -/^ (?:(?A)|(?'B'B)(?A)) (?(A)x) (?(B)y)$/x,dupnames - Ax - 0: Ax - 1: A - BAxy - 0: BAxy - 1: A - 2: B - -/ ^ a + b $ /x - aaaab - 0: aaaab - -/ ^ a + #comment - b $ /x - aaaab - 0: aaaab - -/ ^ a + #comment - #comment - b $ /x - aaaab - 0: aaaab - -/ ^ (?> a + ) b $ /x - aaaab - 0: aaaab - -/ ^ ( a + ) + \w $ /x - aaaab - 0: aaaab - 1: aaaa - -/(?:x|(?:(xx|yy)+|x|x|x|x|x)|a|a|a)bc/ -\= Expect no match - acb -No match - -#Posses -#/\A(?:[^\"]+|\"(?:[^\"]*|\"\")*\")+/ -# NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED -# 0: NON QUOTED "QUOT""ED" AFTER - -#Posses -#/\A(?:[^\"]+|\"(?:[^\"]+|\"\")*\")+/ -# NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED -# 0: NON QUOTED "QUOT""ED" AFTER - -#Posses -#/\A(?:[^\"]+|\"(?:[^\"]+|\"\")+\")+/ -# NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED -# 0: NON QUOTED "QUOT""ED" AFTER - -#Posses -#/\A([^\"1]+|[\"2]([^\"3]*|[\"4][\"5])*[\"6])+/ -# NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED -# 0: NON QUOTED "QUOT""ED" AFTER -# 1: AFTER -# 2: - -/^\w+(?>\s*)(?<=\w)/ - test test - 0: tes - -#/(?Pa)?(?Pb)?(?()c|d)*l/ -# acl -# 0: acl -# 1: a -# bdl -# 0: bdl -# 1: -# 2: b -# adl -# 0: dl -# bcl -# 0: l - -/\sabc/ - \x0babc - 0: \x0babc - -#/[\Qa]\E]+/ -# aa]] -# 0: aa]] - -#/[\Q]a\E]+/ -# aa]] -# 0: aa]] - -/A((((((((a))))))))\8B/ - AaaB - 0: AaaB - 1: a - 2: a - 3: a - 4: a - 5: a - 6: a - 7: a - 8: a - -/A(((((((((a)))))))))\9B/ - AaaB - 0: AaaB - 1: a - 2: a - 3: a - 4: a - 5: a - 6: a - 7: a - 8: a - 9: a - -/(|ab)*?d/ - abd - 0: abd - 1: ab - xyd - 0: d - -/(\2|a)(\1)/ - aaa - 0: aa - 1: a - 2: a - -/(\2)(\1)/ - -"Z*(|d*){216}" - -/((((((((((((x))))))))))))\12/ - xx - 0: xx - 1: x - 2: x - 3: x - 4: x - 5: x - 6: x - 7: x - 8: x - 9: x -10: x -11: x -12: x - -#"(?|(\k'Pm')|(?'Pm'))" -# abcd -# 0: -# 1: - -#/(?|(aaa)|(b))\g{1}/ -# aaaaaa -# 0: aaaaaa -# 1: aaa -# bb -# 0: bb -# 1: b - -#/(?|(aaa)|(b))(?1)/ -# aaaaaa -# 0: aaaaaa -# 1: aaa -# baaa -# 0: baaa -# 1: b -#\= Expect no match -# bb -#No match - -#/(?|(aaa)|(b))/ -# xaaa -# 0: aaa -# 1: aaa -# xbc -# 0: b -# 1: b - -#/(?|(?'a'aaa)|(?'a'b))\k'a'/ -# aaaaaa -# 0: aaaaaa -# 1: aaa -# bb -# 0: bb -# 1: b - -#/(?|(?'a'aaa)|(?'a'b))(?'a'cccc)\k'a'/dupnames -# aaaccccaaa -# 0: aaaccccaaa -# 1: aaa -# 2: cccc -# bccccb -# 0: bccccb -# 1: b -# 2: cccc - -# End of testinput1 diff --git a/vendor/github.com/ettle/strcase/.gitignore b/vendor/github.com/ettle/strcase/.gitignore deleted file mode 100644 index 54bc1fbff4..0000000000 --- a/vendor/github.com/ettle/strcase/.gitignore +++ /dev/null @@ -1,18 +0,0 @@ -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib - -# Test binary, built with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -# CPU and memory profiles -*.prof - -# Dependency directories -vendor/ diff --git a/vendor/github.com/ettle/strcase/.golangci.yml b/vendor/github.com/ettle/strcase/.golangci.yml deleted file mode 100644 index b7ce85d424..0000000000 --- a/vendor/github.com/ettle/strcase/.golangci.yml +++ /dev/null @@ -1,82 +0,0 @@ -linters-settings: - dupl: - threshold: 100 - gocyclo: - min-complexity: 15 - gocritic: - enabled-tags: - - diagnostic - - experimental - - opinionated - - performance - - style - disabled-checks: - - ifElseChain - - whyNoLint - - wrapperFunc - govet: - check-shadowing: true - lll: - line-length: 140 - maligned: - suggest-new: true - misspell: - locale: US - nolintlint: - allow-leading-space: false - allow-unused: false - require-specific: true - - require-explanation: true - allow-no-explanation: - - gocyclo - -linters: - disable-all: true - enable: - - bodyclose - - depguard - - dogsled - - dupl - - errcheck - - gochecknoinits - - gocritic - - gocyclo - - gofmt - - goimports - - goprintffuncname - - gosec - - gosimple - - govet - - ineffassign - - lll - - misspell - - nakedret - - nolintlint - - revive - - rowserrcheck - - staticcheck - - stylecheck - - typecheck - - unconvert - - unparam - - unused - - whitespace - - # don't enable: - # - asciicheck - # - gochecknoglobals - # - gocognit - # - godot - # - godox - # - goerr113 - # - maligned - # - nestif - # - prealloc - # - testpackage - # - wsl - -issues: - exclude-use-default: false - max-issues-per-linter: 0 - max-same-issues: 0 diff --git a/vendor/github.com/ettle/strcase/.readme.tmpl b/vendor/github.com/ettle/strcase/.readme.tmpl deleted file mode 100644 index 4d7a894f0e..0000000000 --- a/vendor/github.com/ettle/strcase/.readme.tmpl +++ /dev/null @@ -1,80 +0,0 @@ -{{with .PDoc}} -# Go Strcase - -[![Go Report Card](https://goreportcard.com/badge/github.com/ettle/strcase)](https://goreportcard.com/report/github.com/ettle/strcase) -[![Coverage](http://gocover.io/_badge/github.com/ettle/strcase?0)](http://gocover.io/github.com/ettle/strcase) -[![GoDoc](https://godoc.org/github.com/ettle/strcase?status.svg)](https://pkg.go.dev/github.com/ettle/strcase) - -Convert strings to `snake_case`, `camelCase`, `PascalCase`, `kebab-case` and more! Supports Go initialisms, customization, and Unicode. - -`import "{{.ImportPath}}"` - -## Overview -{{comment_md .Doc}} -{{example_html $ ""}} - -## Index{{if .Consts}} -* [Constants](#pkg-constants){{end}}{{if .Vars}} -* [Variables](#pkg-variables){{end}}{{- range .Funcs -}}{{$name_html := html .Name}} -* [{{node_html $ .Decl false | sanitize}}](#func-{{$name_html}}){{- end}}{{- range .Types}}{{$tname_html := html .Name}} -* [type {{$tname_html}}](#type-{{$tname_html}}){{- range .Funcs}}{{$name_html := html .Name}} - * [{{node_html $ .Decl false | sanitize}}](#func-{{$name_html}}){{- end}}{{- range .Methods}}{{$name_html := html .Name}} - * [{{node_html $ .Decl false | sanitize}}](#type-{{$tname_html}}.{{$name_html}}){{- end}}{{- end}}{{- if $.Notes}}{{- range $marker, $item := $.Notes}} -* [{{noteTitle $marker | html}}s](#pkg-note-{{$marker}}){{end}}{{end}} -{{if $.Examples}} -#### Examples{{- range $.Examples}} -* [{{example_name .Name}}](#example_{{.Name}}){{- end}}{{- end}} - -{{with .Consts}}## Constants -{{range .}}{{node $ .Decl | pre}} -{{comment_md .Doc}}{{end}}{{end}} -{{with .Vars}}## Variables -{{range .}}{{node $ .Decl | pre}} -{{comment_md .Doc}}{{end}}{{end}} - -{{range .Funcs}}{{$name_html := html .Name}}## func [{{$name_html}}]({{gh_url $ .Decl}}) -{{node $ .Decl | pre}} -{{comment_md .Doc}} -{{example_html $ .Name}} -{{callgraph_html $ "" .Name}}{{end}} -{{range .Types}}{{$tname := .Name}}{{$tname_html := html .Name}}## type [{{$tname_html}}]({{gh_url $ .Decl}}) -{{node $ .Decl | pre}} -{{comment_md .Doc}}{{range .Consts}} -{{node $ .Decl | pre }} -{{comment_md .Doc}}{{end}}{{range .Vars}} -{{node $ .Decl | pre }} -{{comment_md .Doc}}{{end}} - -{{example_html $ $tname}} -{{implements_html $ $tname}} -{{methodset_html $ $tname}} - -{{range .Funcs}}{{$name_html := html .Name}}### func [{{$name_html}}]({{gh_url $ .Decl}}) -{{node $ .Decl | pre}} -{{comment_md .Doc}} -{{example_html $ .Name}}{{end}} -{{callgraph_html $ "" .Name}} - -{{range .Methods}}{{$name_html := html .Name}}### func ({{md .Recv}}) [{{$name_html}}]({{gh_url $ .Decl}}) -{{node $ .Decl | pre}} -{{comment_md .Doc}} -{{$name := printf "%s_%s" $tname .Name}}{{example_html $ $name}} -{{callgraph_html $ .Recv .Name}} -{{end}}{{end}}{{end}} - -{{with $.Notes}} -{{range $marker, $content := .}} -## {{noteTitle $marker | html}}s - -{{end}} -{{end}} -{{if .Dirs}} -## Subdirectories -{{range $.Dirs.List}} -{{indent .Depth}}* [{{.Name | html}}]({{print "./" .Path}}){{if .Synopsis}} {{ .Synopsis}}{{end -}} -{{end}} -{{end}} diff --git a/vendor/github.com/ettle/strcase/LICENSE b/vendor/github.com/ettle/strcase/LICENSE deleted file mode 100644 index 4f0116be2e..0000000000 --- a/vendor/github.com/ettle/strcase/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2020 Liyan David Chang - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/ettle/strcase/Makefile b/vendor/github.com/ettle/strcase/Makefile deleted file mode 100644 index ac98b4aa54..0000000000 --- a/vendor/github.com/ettle/strcase/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -.PHONY: benchmark docs lint test - -docs: - which godoc2ghmd || go get github.com/DevotedHealth/godoc2ghmd - godoc2ghmd -template .readme.tmpl github.com/ettle/strcase > README.md - go mod tidy - -test: - go test -cover ./... - -lint: - which golangci-lint || go get github.com/golangci/golangci-lint/cmd/golangci-lint@v1.50.1 - golangci-lint run - golangci-lint run benchmark/*.go - go mod tidy - -benchmark: - cd benchmark && go test -bench=. -test.benchmem - go mod tidy diff --git a/vendor/github.com/ettle/strcase/README.md b/vendor/github.com/ettle/strcase/README.md deleted file mode 100644 index a984da80da..0000000000 --- a/vendor/github.com/ettle/strcase/README.md +++ /dev/null @@ -1,553 +0,0 @@ - -# Go Strcase - -[![Go Report Card](https://goreportcard.com/badge/github.com/ettle/strcase)](https://goreportcard.com/report/github.com/ettle/strcase) -[![Coverage](http://gocover.io/_badge/github.com/ettle/strcase?0)](http://gocover.io/github.com/ettle/strcase) -[![GoDoc](https://godoc.org/github.com/ettle/strcase?status.svg)](https://pkg.go.dev/github.com/ettle/strcase) - -Convert strings to `snake_case`, `camelCase`, `PascalCase`, `kebab-case` and more! Supports Go initialisms, customization, and Unicode. - -`import "github.com/ettle/strcase"` - -## Overview -Package strcase is a package for converting strings into various word cases -(e.g. snake_case, camelCase) - - - go get -u github.com/ettle/strcase - -Example usage - - - strcase.ToSnake("Hello World") // hello_world - strcase.ToSNAKE("Hello World") // HELLO_WORLD - - strcase.ToKebab("helloWorld") // hello-world - strcase.ToKEBAB("helloWorld") // HELLO-WORLD - - strcase.ToPascal("hello-world") // HelloWorld - strcase.ToCamel("hello-world") // helloWorld - - // Handle odd cases - strcase.ToSnake("FOOBar") // foo_bar - - // Support Go initialisms - strcase.ToGoPascal("http_response") // HTTPResponse - - // Specify case and delimiter - strcase.ToCase("HelloWorld", strcase.UpperCase, '.') // HELLO.WORLD - -## Why this package - -String strcase is pretty straight forward and there are a number of methods to -do it. This package is fully featured, more customizable, better tested, and -faster than other packages and what you would probably whip up yourself. - -### Unicode support - -We work for with unicode strings and pay very little performance penalty for it -as we optimized for the common use case of ASCII only strings. - -### Customization - -You can create a custom caser that changes the behavior to what you want. This -customization also reduces the pressure for us to change the default behavior -which means that things are more stable for everyone involved. The goal is to -make the common path easy and fast, while making the uncommon path possible. - - - c := NewCaser( - // Use Go's default initialisms e.g. ID, HTML - true, - // Override initialisms (e.g. don't initialize HTML but initialize SSL - map[string]bool{"SSL": true, "HTML": false}, - // Write your own custom SplitFn - // - NewSplitFn( - []rune{'*', '.', ','}, - SplitCase, - SplitAcronym, - PreserveNumberFormatting, - SplitBeforeNumber, - SplitAfterNumber, - )) - assert.Equal(t, "http_200", c.ToSnake("http200")) - -### Initialism support - -By default, we use the golint intialisms list. You can customize and override -the initialisms if you wish to add additional ones, such as "SSL" or "CMS" or -domain specific ones to your industry. - - - ToGoPascal("http_response") // HTTPResponse - ToGoSnake("http_response") // HTTP_response - -### Test coverage - -We have a wide ranging test suite to make sure that we understand our behavior. -Test coverage isn't everything, but we aim for 100% coverage. - -### Fast - -Optimized to reduce memory allocations with Builder. Benchmarked and optimized -around common cases. - -We're on par with the fastest packages (that have less features) and much -faster than others. We also benchmarked against code snippets. Using string -builders to reduce memory allocation and reordering boolean checks for the -common cases have a large performance impact. - -Hopefully I was fair to each library and happy to rerun benchmarks differently -or reword my commentary based on suggestions or updates. - - - // This package - faster then almost all libraries - // Initialisms are more complicated and slightly slower, but still fast - BenchmarkToTitle-96 9617142 125.7 ns/op 16 B/op 1 allocs/op - BenchmarkToSnake-96 10659919 120.7 ns/op 16 B/op 1 allocs/op - BenchmarkToSNAKE-96 9018282 126.4 ns/op 16 B/op 1 allocs/op - BenchmarkToGoSnake-96 4903687 254.5 ns/op 26 B/op 4 allocs/op - BenchmarkToCustomCaser-96 4434489 265.0 ns/op 28 B/op 4 allocs/op - - // Segment has very fast snake case and camel case libraries - // No features or customization, but very very fast - BenchmarkSegment-96 33625734 35.54 ns/op 16 B/op 1 allocs/op - - // Iancoleman has gotten some performance improvements, but remains - // without unicode support and lacks fine-grained customization - BenchmarkToSnakeIan-96 13141522 92.99 ns/op 16 B/op 1 allocs/op - - // Stdlib strings.Title is deprecated; using golang.org/x.text - BenchmarkGolangOrgXTextCases-96 4665676 262.5 ns/op 272 B/op 2 allocs/op - - // Other libraries or code snippets - // - Most are slower, by up to an order of magnitude - // - No support for initialisms or customization - // - Some generate only camelCase or snake_case - // - Many lack unicode support - BenchmarkToSnakeStoewer-96 8095468 148.9 ns/op 64 B/op 2 allocs/op - // Copying small rune arrays is slow - BenchmarkToSnakeSiongui-96 2912593 401.7 ns/op 112 B/op 19 allocs/op - BenchmarkGoValidator-96 3493800 342.6 ns/op 184 B/op 9 allocs/op - // String alloction is slow - BenchmarkToSnakeFatih-96 1282648 945.1 ns/op 616 B/op 26 allocs/op - // Regexp is slow - BenchmarkToSnakeGolangPrograms-96 778674 1495 ns/op 227 B/op 11 allocs/op - - // These results aren't a surprise - my initial version of this library was - // painfully slow. I think most of us, without spending some time with - // profilers and benchmarks, would write also something on the slower side. - -### Zero dependencies - -That's right - zero. We only import the Go standard library. No hassles with -dependencies, licensing, security alerts. - -## Why not this package - -If every nanosecond matters and this is used in a tight loop, use segment.io's -libraries (https://github.com/segmentio/go-snakecase and -https://github.com/segmentio/go-camelcase). They lack features, but make up for -it by being blazing fast. - -## Migrating from other packages - -If you are migrating from from another package, you may find slight differences -in output. To reduce the delta, you may find it helpful to use the following -custom casers to mimic the behavior of the other package. - - - // From https://github.com/iancoleman/strcase - var c = NewCaser(false, nil, NewSplitFn([]rune{'_', '-', '.'}, SplitCase, SplitAcronym, SplitBeforeNumber)) - - // From https://github.com/stoewer/go-strcase - var c = NewCaser(false, nil, NewSplitFn([]rune{'_', '-'}, SplitCase), SplitAcronym) - - - - -## Index -* [func ToCamel(s string) string](#func-ToCamel) -* [func ToCase(s string, wordCase WordCase, delimiter rune) string](#func-ToCase) -* [func ToGoCamel(s string) string](#func-ToGoCamel) -* [func ToGoCase(s string, wordCase WordCase, delimiter rune) string](#func-ToGoCase) -* [func ToGoKebab(s string) string](#func-ToGoKebab) -* [func ToGoPascal(s string) string](#func-ToGoPascal) -* [func ToGoSnake(s string) string](#func-ToGoSnake) -* [func ToKEBAB(s string) string](#func-ToKEBAB) -* [func ToKebab(s string) string](#func-ToKebab) -* [func ToPascal(s string) string](#func-ToPascal) -* [func ToSNAKE(s string) string](#func-ToSNAKE) -* [func ToSnake(s string) string](#func-ToSnake) -* [type Caser](#type-Caser) - * [func NewCaser(goInitialisms bool, initialismOverrides map[string]bool, splitFn SplitFn) *Caser](#func-NewCaser) - * [func (c *Caser) ToCamel(s string) string](#type-Caser.ToCamel) - * [func (c *Caser) ToCase(s string, wordCase WordCase, delimiter rune) string](#type-Caser.ToCase) - * [func (c *Caser) ToKEBAB(s string) string](#type-Caser.ToKEBAB) - * [func (c *Caser) ToKebab(s string) string](#type-Caser.ToKebab) - * [func (c *Caser) ToPascal(s string) string](#type-Caser.ToPascal) - * [func (c *Caser) ToSNAKE(s string) string](#type-Caser.ToSNAKE) - * [func (c *Caser) ToSnake(s string) string](#type-Caser.ToSnake) -* [type SplitAction](#type-SplitAction) -* [type SplitFn](#type-SplitFn) - * [func NewSplitFn(delimiters []rune, splitOptions ...SplitOption) SplitFn](#func-NewSplitFn) -* [type SplitOption](#type-SplitOption) -* [type WordCase](#type-WordCase) - - - - - -## func [ToCamel](./strcase.go#L57) -``` go -func ToCamel(s string) string -``` -ToCamel returns words in camelCase (capitalized words concatenated together, with first word lower case). -Also known as lowerCamelCase or mixedCase. - - - -## func [ToCase](./strcase.go#L72) -``` go -func ToCase(s string, wordCase WordCase, delimiter rune) string -``` -ToCase returns words in given case and delimiter. - - - -## func [ToGoCamel](./strcase.go#L67) -``` go -func ToGoCamel(s string) string -``` -ToGoCamel returns words in camelCase (capitalized words concatenated together, with first word lower case). -Also known as lowerCamelCase or mixedCase. - -Respects Go's common initialisms, but first word remains lowercased which is -important for code generator use cases (e.g. toJson -> toJSON, httpResponse --> httpResponse). - - - -## func [ToGoCase](./strcase.go#L79) -``` go -func ToGoCase(s string, wordCase WordCase, delimiter rune) string -``` -ToGoCase returns words in given case and delimiter. - -Respects Go's common initialisms (e.g. httpResponse -> HTTPResponse). - - - -## func [ToGoKebab](./strcase.go#L31) -``` go -func ToGoKebab(s string) string -``` -ToGoKebab returns words in kebab-case (lower case words with dashes). -Also known as dash-case. - -Respects Go's common initialisms (e.g. http-response -> HTTP-response). - - - -## func [ToGoPascal](./strcase.go#L51) -``` go -func ToGoPascal(s string) string -``` -ToGoPascal returns words in PascalCase (capitalized words concatenated together). -Also known as UpperPascalCase. - -Respects Go's common initialisms (e.g. HttpResponse -> HTTPResponse). - - - -## func [ToGoSnake](./strcase.go#L11) -``` go -func ToGoSnake(s string) string -``` -ToGoSnake returns words in snake_case (lower case words with underscores). - -Respects Go's common initialisms (e.g. http_response -> HTTP_response). - - - -## func [ToKEBAB](./strcase.go#L37) -``` go -func ToKEBAB(s string) string -``` -ToKEBAB returns words in KEBAB-CASE (upper case words with dashes). -Also known as SCREAMING-KEBAB-CASE or SCREAMING-DASH-CASE. - - - -## func [ToKebab](./strcase.go#L23) -``` go -func ToKebab(s string) string -``` -ToKebab returns words in kebab-case (lower case words with dashes). -Also known as dash-case. - - - -## func [ToPascal](./strcase.go#L43) -``` go -func ToPascal(s string) string -``` -ToPascal returns words in PascalCase (capitalized words concatenated together). -Also known as UpperPascalCase. - - - -## func [ToSNAKE](./strcase.go#L17) -``` go -func ToSNAKE(s string) string -``` -ToSNAKE returns words in SNAKE_CASE (upper case words with underscores). -Also known as SCREAMING_SNAKE_CASE or UPPER_CASE. - - - -## func [ToSnake](./strcase.go#L4) -``` go -func ToSnake(s string) string -``` -ToSnake returns words in snake_case (lower case words with underscores). - - - - -## type [Caser](./caser.go#L4-L7) -``` go -type Caser struct { - // contains filtered or unexported fields -} - -``` -Caser allows for customization of parsing and intialisms - - - - - - - -### func [NewCaser](./caser.go#L24) -``` go -func NewCaser(goInitialisms bool, initialismOverrides map[string]bool, splitFn SplitFn) *Caser -``` -NewCaser returns a configured Caser. - -A Caser should be created when you want fine grained control over how the words are split. - - - Notes on function arguments - - goInitialisms: Whether to use Golint's intialisms - - initialismOverrides: A mapping of extra initialisms - Keys must be in ALL CAPS. Merged with Golint's if goInitialisms is set. - Setting a key to false will override Golint's. - - splitFn: How to separate words - Override the default split function. Consider using NewSplitFn to - configure one instead of writing your own. - - - - - -### func (\*Caser) [ToCamel](./caser.go#L80) -``` go -func (c *Caser) ToCamel(s string) string -``` -ToCamel returns words in camelCase (capitalized words concatenated together, with first word lower case). -Also known as lowerCamelCase or mixedCase. - - - - -### func (\*Caser) [ToCase](./caser.go#L85) -``` go -func (c *Caser) ToCase(s string, wordCase WordCase, delimiter rune) string -``` -ToCase returns words with a given case and delimiter. - - - - -### func (\*Caser) [ToKEBAB](./caser.go#L68) -``` go -func (c *Caser) ToKEBAB(s string) string -``` -ToKEBAB returns words in KEBAB-CASE (upper case words with dashes). -Also known as SCREAMING-KEBAB-CASE or SCREAMING-DASH-CASE. - - - - -### func (\*Caser) [ToKebab](./caser.go#L62) -``` go -func (c *Caser) ToKebab(s string) string -``` -ToKebab returns words in kebab-case (lower case words with dashes). -Also known as dash-case. - - - - -### func (\*Caser) [ToPascal](./caser.go#L74) -``` go -func (c *Caser) ToPascal(s string) string -``` -ToPascal returns words in PascalCase (capitalized words concatenated together). -Also known as UpperPascalCase. - - - - -### func (\*Caser) [ToSNAKE](./caser.go#L56) -``` go -func (c *Caser) ToSNAKE(s string) string -``` -ToSNAKE returns words in SNAKE_CASE (upper case words with underscores). -Also known as SCREAMING_SNAKE_CASE or UPPER_CASE. - - - - -### func (\*Caser) [ToSnake](./caser.go#L50) -``` go -func (c *Caser) ToSnake(s string) string -``` -ToSnake returns words in snake_case (lower case words with underscores). - - - - -## type [SplitAction](./split.go#L111) -``` go -type SplitAction int -``` -SplitAction defines if and how to split a string - - -``` go -const ( - // Noop - Continue to next character - Noop SplitAction = iota - // Split - Split between words - // e.g. to split between wordsWithoutDelimiters - Split - // SkipSplit - Split the word and drop the character - // e.g. to split words with delimiters - SkipSplit - // Skip - Remove the character completely - Skip -) -``` - - - - - - - - - -## type [SplitFn](./split.go#L6) -``` go -type SplitFn func(prev, curr, next rune) SplitAction -``` -SplitFn defines how to split a string into words - - - - - - - -### func [NewSplitFn](./split.go#L15-L18) -``` go -func NewSplitFn( - delimiters []rune, - splitOptions ...SplitOption, -) SplitFn -``` -NewSplitFn returns a SplitFn based on the options provided. - -NewSplitFn covers the majority of common options that other strcase -libraries provide and should allow you to simply create a custom caser. -For more complicated use cases, feel free to write your own SplitFn - - - - - -## type [SplitOption](./split.go#L94) -``` go -type SplitOption int -``` -SplitOption are options that allow for configuring NewSplitFn - - -``` go -const ( - // SplitCase - FooBar -> Foo_Bar - SplitCase SplitOption = iota - // SplitAcronym - FOOBar -> Foo_Bar - // It won't preserve FOO's case. If you want, you can set the Caser's initialisms so FOO will be in all caps - SplitAcronym - // SplitBeforeNumber - port80 -> port_80 - SplitBeforeNumber - // SplitAfterNumber - 200status -> 200_status - SplitAfterNumber - // PreserveNumberFormatting - a.b.2,000.3.c -> a_b_2,000.3_c - PreserveNumberFormatting -) -``` - - - - - - - - - -## type [WordCase](./convert.go#L6) -``` go -type WordCase int -``` -WordCase is an enumeration of the ways to format a word. - - -``` go -const ( - // Original - Preserve the original input strcase - Original WordCase = iota - // LowerCase - All letters lower cased (example) - LowerCase - // UpperCase - All letters upper cased (EXAMPLE) - UpperCase - // TitleCase - Only first letter upper cased (Example) - TitleCase - // CamelCase - TitleCase except lower case first word (exampleText) - // Notably, even if the first word is an initialism, it will be lower - // cased. This is important for code generators where capital letters - // mean exported functions. i.e. jsonString(), not JSONString() - CamelCase -) -``` - - - - - - - - - - - - - diff --git a/vendor/github.com/ettle/strcase/assert.go b/vendor/github.com/ettle/strcase/assert.go deleted file mode 100644 index 09344e40f2..0000000000 --- a/vendor/github.com/ettle/strcase/assert.go +++ /dev/null @@ -1,24 +0,0 @@ -package strcase - -// We use a lightweight replacement for testify/assert to reduce dependencies - -// testingT interface allows us to test our assert functions -type testingT interface { - Logf(format string, args ...interface{}) - Fail() -} - -// assertTrue will fail if the value is not true -func assertTrue(t testingT, value bool) { - if !value { - t.Fail() - } -} - -// assertEqual will fail if the two strings are not equal -func assertEqual(t testingT, expected, actual string) { - if expected != actual { - t.Logf("Expected: %s Actual: %s", expected, actual) - t.Fail() - } -} diff --git a/vendor/github.com/ettle/strcase/caser.go b/vendor/github.com/ettle/strcase/caser.go deleted file mode 100644 index 2e7eb955ba..0000000000 --- a/vendor/github.com/ettle/strcase/caser.go +++ /dev/null @@ -1,87 +0,0 @@ -package strcase - -// Caser allows for customization of parsing and intialisms -type Caser struct { - initialisms map[string]bool - splitFn SplitFn -} - -// NewCaser returns a configured Caser. -// -// A Caser should be created when you want fine grained control over how the words are split. -// -// Notes on function arguments -// -// goInitialisms: Whether to use Golint's intialisms -// -// initialismOverrides: A mapping of extra initialisms -// Keys must be in ALL CAPS. Merged with Golint's if goInitialisms is set. -// Setting a key to false will override Golint's. -// -// splitFn: How to separate words -// Override the default split function. Consider using NewSplitFn to -// configure one instead of writing your own. -func NewCaser(goInitialisms bool, initialismOverrides map[string]bool, splitFn SplitFn) *Caser { - c := &Caser{ - initialisms: golintInitialisms, - splitFn: splitFn, - } - - if c.splitFn == nil { - c.splitFn = defaultSplitFn - } - - if goInitialisms && initialismOverrides != nil { - c.initialisms = map[string]bool{} - for k, v := range golintInitialisms { - c.initialisms[k] = v - } - for k, v := range initialismOverrides { - c.initialisms[k] = v - } - } else if !goInitialisms { - c.initialisms = initialismOverrides - } - - return c -} - -// ToSnake returns words in snake_case (lower case words with underscores). -func (c *Caser) ToSnake(s string) string { - return convert(s, c.splitFn, '_', LowerCase, c.initialisms) -} - -// ToSNAKE returns words in SNAKE_CASE (upper case words with underscores). -// Also known as SCREAMING_SNAKE_CASE or UPPER_CASE. -func (c *Caser) ToSNAKE(s string) string { - return convert(s, c.splitFn, '_', UpperCase, c.initialisms) -} - -// ToKebab returns words in kebab-case (lower case words with dashes). -// Also known as dash-case. -func (c *Caser) ToKebab(s string) string { - return convert(s, c.splitFn, '-', LowerCase, c.initialisms) -} - -// ToKEBAB returns words in KEBAB-CASE (upper case words with dashes). -// Also known as SCREAMING-KEBAB-CASE or SCREAMING-DASH-CASE. -func (c *Caser) ToKEBAB(s string) string { - return convert(s, c.splitFn, '-', UpperCase, c.initialisms) -} - -// ToPascal returns words in PascalCase (capitalized words concatenated together). -// Also known as UpperPascalCase. -func (c *Caser) ToPascal(s string) string { - return convert(s, c.splitFn, '\x00', TitleCase, c.initialisms) -} - -// ToCamel returns words in camelCase (capitalized words concatenated together, with first word lower case). -// Also known as lowerCamelCase or mixedCase. -func (c *Caser) ToCamel(s string) string { - return convert(s, c.splitFn, '\x00', CamelCase, c.initialisms) -} - -// ToCase returns words with a given case and delimiter. -func (c *Caser) ToCase(s string, wordCase WordCase, delimiter rune) string { - return convert(s, c.splitFn, delimiter, wordCase, c.initialisms) -} diff --git a/vendor/github.com/ettle/strcase/convert.go b/vendor/github.com/ettle/strcase/convert.go deleted file mode 100644 index cb901d079d..0000000000 --- a/vendor/github.com/ettle/strcase/convert.go +++ /dev/null @@ -1,306 +0,0 @@ -package strcase - -import "strings" - -// WordCase is an enumeration of the ways to format a word. -type WordCase int - -const ( - // Original - Preserve the original input strcase - Original WordCase = iota - // LowerCase - All letters lower cased (example) - LowerCase - // UpperCase - All letters upper cased (EXAMPLE) - UpperCase - // TitleCase - Only first letter upper cased (Example) - TitleCase - // CamelCase - TitleCase except lower case first word (exampleText) - // Notably, even if the first word is an initialism, it will be lower - // cased. This is important for code generators where capital letters - // mean exported functions. i.e. jsonString(), not JSONString() - CamelCase -) - -// We have 3 convert functions for performance reasons -// The general convert could handle everything, but is not optimized -// -// The other two functions are optimized for the general use cases - that is the non-custom caser functions -// Case 1: Any Case and supports Go Initialisms -// Case 2: UpperCase words, which don't need to support initialisms since everything is in upper case - -// convertWithoutInitialims only works for to UpperCase and LowerCase -// -//nolint:gocyclo -func convertWithoutInitialisms(input string, delimiter rune, wordCase WordCase) string { - input = strings.TrimSpace(input) - runes := []rune(input) - if len(runes) == 0 { - return "" - } - - var b strings.Builder - b.Grow(len(input) + 4) // In case we need to write delimiters where they weren't before - - var prev, curr rune - next := runes[0] // 0 length will have already returned so safe to index - inWord := false - firstWord := true - for i := 0; i < len(runes); i++ { - prev = curr - curr = next - if i+1 == len(runes) { - next = 0 - } else { - next = runes[i+1] - } - - switch defaultSplitFn(prev, curr, next) { - case SkipSplit: - if inWord && delimiter != 0 { - b.WriteRune(delimiter) - } - inWord = false - continue - case Split: - if inWord && delimiter != 0 { - b.WriteRune(delimiter) - } - inWord = false - } - switch wordCase { - case UpperCase: - b.WriteRune(toUpper(curr)) - case LowerCase: - b.WriteRune(toLower(curr)) - case TitleCase: - if inWord { - b.WriteRune(toLower(curr)) - } else { - b.WriteRune(toUpper(curr)) - } - case CamelCase: - if inWord { - b.WriteRune(toLower(curr)) - } else if firstWord { - b.WriteRune(toLower(curr)) - firstWord = false - } else { - b.WriteRune(toUpper(curr)) - } - default: - // Must be original case - b.WriteRune(curr) - } - inWord = true - } - return b.String() -} - -// convertWithGoInitialisms changes a input string to a certain case with a -// delimiter, respecting go initialisms but not skip runes -// -//nolint:gocyclo -func convertWithGoInitialisms(input string, delimiter rune, wordCase WordCase) string { - input = strings.TrimSpace(input) - runes := []rune(input) - if len(runes) == 0 { - return "" - } - - var b strings.Builder - b.Grow(len(input) + 4) // In case we need to write delimiters where they weren't before - - firstWord := true - - addWord := func(start, end int) { - if start == end { - return - } - - if !firstWord && delimiter != 0 { - b.WriteRune(delimiter) - } - - // Don't bother with initialisms if the word is longer than 5 - // A quick proxy to avoid the extra memory allocations - if end-start <= 5 { - var word strings.Builder - word.Grow(end - start) - for i := start; i < end; i++ { - word.WriteRune(toUpper(runes[i])) - } - w := word.String() - if golintInitialisms[w] { - if !firstWord || wordCase != CamelCase { - b.WriteString(w) - firstWord = false - return - } - } - } - - for i := start; i < end; i++ { - r := runes[i] - switch wordCase { - case UpperCase: - panic("use convertWithoutInitialisms instead") - case LowerCase: - b.WriteRune(toLower(r)) - case TitleCase: - if i == start { - b.WriteRune(toUpper(r)) - } else { - b.WriteRune(toLower(r)) - } - case CamelCase: - if !firstWord && i == start { - b.WriteRune(toUpper(r)) - } else { - b.WriteRune(toLower(r)) - } - default: - b.WriteRune(r) - } - } - firstWord = false - } - - var prev, curr rune - next := runes[0] // 0 length will have already returned so safe to index - wordStart := 0 - for i := 0; i < len(runes); i++ { - prev = curr - curr = next - if i+1 == len(runes) { - next = 0 - } else { - next = runes[i+1] - } - - switch defaultSplitFn(prev, curr, next) { - case Split: - addWord(wordStart, i) - wordStart = i - case SkipSplit: - addWord(wordStart, i) - wordStart = i + 1 - } - } - - if wordStart != len(runes) { - addWord(wordStart, len(runes)) - } - return b.String() -} - -// convert changes a input string to a certain case with a delimiter, -// respecting arbitrary initialisms and skip characters -// -//nolint:gocyclo -func convert(input string, fn SplitFn, delimiter rune, wordCase WordCase, - initialisms map[string]bool) string { - input = strings.TrimSpace(input) - runes := []rune(input) - if len(runes) == 0 { - return "" - } - - var b strings.Builder - b.Grow(len(input) + 4) // In case we need to write delimiters where they weren't before - - firstWord := true - var skipIndexes []int - - addWord := func(start, end int) { - // If you have nothing good to say, say nothing at all - if start == end || len(skipIndexes) == end-start { - skipIndexes = nil - return - } - - // If you have something to say, start with a delimiter - if !firstWord && delimiter != 0 { - b.WriteRune(delimiter) - } - - // Check if you're an initialism - // Note - we don't check skip characters here since initialisms - // will probably never have junk characters in between - // I'm open to it if there is a use case - if initialisms != nil { - var word strings.Builder - word.Grow(end - start) - for i := start; i < end; i++ { - word.WriteRune(toUpper(runes[i])) - } - w := word.String() - if initialisms[w] { - if !firstWord || wordCase != CamelCase { - b.WriteString(w) - firstWord = false - return - } - } - } - - skipIdx := 0 - for i := start; i < end; i++ { - if len(skipIndexes) > 0 && skipIdx < len(skipIndexes) && i == skipIndexes[skipIdx] { - skipIdx++ - continue - } - r := runes[i] - switch wordCase { - case UpperCase: - b.WriteRune(toUpper(r)) - case LowerCase: - b.WriteRune(toLower(r)) - case TitleCase: - if i == start { - b.WriteRune(toUpper(r)) - } else { - b.WriteRune(toLower(r)) - } - case CamelCase: - if !firstWord && i == start { - b.WriteRune(toUpper(r)) - } else { - b.WriteRune(toLower(r)) - } - default: - b.WriteRune(r) - } - } - firstWord = false - skipIndexes = nil - } - - var prev, curr rune - next := runes[0] // 0 length will have already returned so safe to index - wordStart := 0 - for i := 0; i < len(runes); i++ { - prev = curr - curr = next - if i+1 == len(runes) { - next = 0 - } else { - next = runes[i+1] - } - - switch fn(prev, curr, next) { - case Skip: - skipIndexes = append(skipIndexes, i) - case Split: - addWord(wordStart, i) - wordStart = i - case SkipSplit: - addWord(wordStart, i) - wordStart = i + 1 - } - } - - if wordStart != len(runes) { - addWord(wordStart, len(runes)) - } - return b.String() -} diff --git a/vendor/github.com/ettle/strcase/doc.go b/vendor/github.com/ettle/strcase/doc.go deleted file mode 100644 index c3bf14a8f5..0000000000 --- a/vendor/github.com/ettle/strcase/doc.go +++ /dev/null @@ -1,150 +0,0 @@ -/* -Package strcase is a package for converting strings into various word cases -(e.g. snake_case, camelCase) - - go get -u github.com/ettle/strcase - -Example usage - - strcase.ToSnake("Hello World") // hello_world - strcase.ToSNAKE("Hello World") // HELLO_WORLD - - strcase.ToKebab("helloWorld") // hello-world - strcase.ToKEBAB("helloWorld") // HELLO-WORLD - - strcase.ToPascal("hello-world") // HelloWorld - strcase.ToCamel("hello-world") // helloWorld - - // Handle odd cases - strcase.ToSnake("FOOBar") // foo_bar - - // Support Go initialisms - strcase.ToGoPascal("http_response") // HTTPResponse - - // Specify case and delimiter - strcase.ToCase("HelloWorld", strcase.UpperCase, '.') // HELLO.WORLD - -## Why this package - -String strcase is pretty straight forward and there are a number of methods to -do it. This package is fully featured, more customizable, better tested, and -faster than other packages and what you would probably whip up yourself. - -### Unicode support - -We work for with unicode strings and pay very little performance penalty for it -as we optimized for the common use case of ASCII only strings. - -### Customization - -You can create a custom caser that changes the behavior to what you want. This -customization also reduces the pressure for us to change the default behavior -which means that things are more stable for everyone involved. The goal is to -make the common path easy and fast, while making the uncommon path possible. - - c := NewCaser( - // Use Go's default initialisms e.g. ID, HTML - true, - // Override initialisms (e.g. don't initialize HTML but initialize SSL - map[string]bool{"SSL": true, "HTML": false}, - // Write your own custom SplitFn - // - NewSplitFn( - []rune{'*', '.', ','}, - SplitCase, - SplitAcronym, - PreserveNumberFormatting, - SplitBeforeNumber, - SplitAfterNumber, - )) - assert.Equal(t, "http_200", c.ToSnake("http200")) - -### Initialism support - -By default, we use the golint intialisms list. You can customize and override -the initialisms if you wish to add additional ones, such as "SSL" or "CMS" or -domain specific ones to your industry. - - ToGoPascal("http_response") // HTTPResponse - ToGoSnake("http_response") // HTTP_response - -### Test coverage - -We have a wide ranging test suite to make sure that we understand our behavior. -Test coverage isn't everything, but we aim for 100% coverage. - -### Fast - -Optimized to reduce memory allocations with Builder. Benchmarked and optimized -around common cases. - -We're on par with the fastest packages (that have less features) and much -faster than others. We also benchmarked against code snippets. Using string -builders to reduce memory allocation and reordering boolean checks for the -common cases have a large performance impact. - -Hopefully I was fair to each library and happy to rerun benchmarks differently -or reword my commentary based on suggestions or updates. - - // This package - faster then almost all libraries - // Initialisms are more complicated and slightly slower, but still fast - BenchmarkToTitle-96 9617142 125.7 ns/op 16 B/op 1 allocs/op - BenchmarkToSnake-96 10659919 120.7 ns/op 16 B/op 1 allocs/op - BenchmarkToSNAKE-96 9018282 126.4 ns/op 16 B/op 1 allocs/op - BenchmarkToGoSnake-96 4903687 254.5 ns/op 26 B/op 4 allocs/op - BenchmarkToCustomCaser-96 4434489 265.0 ns/op 28 B/op 4 allocs/op - - // Segment has very fast snake case and camel case libraries - // No features or customization, but very very fast - BenchmarkSegment-96 33625734 35.54 ns/op 16 B/op 1 allocs/op - - // Iancoleman has gotten some performance improvements, but remains - // without unicode support and lacks fine-grained customization - BenchmarkToSnakeIan-96 13141522 92.99 ns/op 16 B/op 1 allocs/op - - // Stdlib strings.Title is deprecated; using golang.org/x.text - BenchmarkGolangOrgXTextCases-96 4665676 262.5 ns/op 272 B/op 2 allocs/op - - // Other libraries or code snippets - // - Most are slower, by up to an order of magnitude - // - No support for initialisms or customization - // - Some generate only camelCase or snake_case - // - Many lack unicode support - BenchmarkToSnakeStoewer-96 8095468 148.9 ns/op 64 B/op 2 allocs/op - // Copying small rune arrays is slow - BenchmarkToSnakeSiongui-96 2912593 401.7 ns/op 112 B/op 19 allocs/op - BenchmarkGoValidator-96 3493800 342.6 ns/op 184 B/op 9 allocs/op - // String alloction is slow - BenchmarkToSnakeFatih-96 1282648 945.1 ns/op 616 B/op 26 allocs/op - // Regexp is slow - BenchmarkToSnakeGolangPrograms-96 778674 1495 ns/op 227 B/op 11 allocs/op - - // These results aren't a surprise - my initial version of this library was - // painfully slow. I think most of us, without spending some time with - // profilers and benchmarks, would write also something on the slower side. - -### Zero dependencies - -That's right - zero. We only import the Go standard library. No hassles with -dependencies, licensing, security alerts. - -## Why not this package - -If every nanosecond matters and this is used in a tight loop, use segment.io's -libraries (https://github.com/segmentio/go-snakecase and -https://github.com/segmentio/go-camelcase). They lack features, but make up for -it by being blazing fast. - -## Migrating from other packages - -If you are migrating from from another package, you may find slight differences -in output. To reduce the delta, you may find it helpful to use the following -custom casers to mimic the behavior of the other package. - - // From https://github.com/iancoleman/strcase - var c = NewCaser(false, nil, NewSplitFn([]rune{'_', '-', '.'}, SplitCase, SplitAcronym, SplitBeforeNumber)) - - // From https://github.com/stoewer/go-strcase - var c = NewCaser(false, nil, NewSplitFn([]rune{'_', '-'}, SplitCase), SplitAcronym) -*/ -package strcase diff --git a/vendor/github.com/ettle/strcase/initialism.go b/vendor/github.com/ettle/strcase/initialism.go deleted file mode 100644 index 3c313d3e9a..0000000000 --- a/vendor/github.com/ettle/strcase/initialism.go +++ /dev/null @@ -1,43 +0,0 @@ -package strcase - -// golintInitialisms are the golint initialisms -var golintInitialisms = map[string]bool{ - "ACL": true, - "API": true, - "ASCII": true, - "CPU": true, - "CSS": true, - "DNS": true, - "EOF": true, - "GUID": true, - "HTML": true, - "HTTP": true, - "HTTPS": true, - "ID": true, - "IP": true, - "JSON": true, - "LHS": true, - "QPS": true, - "RAM": true, - "RHS": true, - "RPC": true, - "SLA": true, - "SMTP": true, - "SQL": true, - "SSH": true, - "TCP": true, - "TLS": true, - "TTL": true, - "UDP": true, - "UI": true, - "UID": true, - "UUID": true, - "URI": true, - "URL": true, - "UTF8": true, - "VM": true, - "XML": true, - "XMPP": true, - "XSRF": true, - "XSS": true, -} diff --git a/vendor/github.com/ettle/strcase/split.go b/vendor/github.com/ettle/strcase/split.go deleted file mode 100644 index 32bc29759a..0000000000 --- a/vendor/github.com/ettle/strcase/split.go +++ /dev/null @@ -1,165 +0,0 @@ -package strcase - -import "unicode" - -// SplitFn defines how to split a string into words -type SplitFn func(prev, curr, next rune) SplitAction - -// NewSplitFn returns a SplitFn based on the options provided. -// -// NewSplitFn covers the majority of common options that other strcase -// libraries provide and should allow you to simply create a custom caser. -// For more complicated use cases, feel free to write your own SplitFn -// -//nolint:gocyclo -func NewSplitFn( - delimiters []rune, - splitOptions ...SplitOption, -) SplitFn { - var splitCase, splitAcronym, splitBeforeNumber, splitAfterNumber, preserveNumberFormatting bool - - for _, option := range splitOptions { - switch option { - case SplitCase: - splitCase = true - case SplitAcronym: - splitAcronym = true - case SplitBeforeNumber: - splitBeforeNumber = true - case SplitAfterNumber: - splitAfterNumber = true - case PreserveNumberFormatting: - preserveNumberFormatting = true - } - } - - return func(prev, curr, next rune) SplitAction { - // The most common case will be that it's just a letter - // There are safe cases to process - if isLower(curr) && !isNumber(prev) { - return Noop - } - if isUpper(prev) && isUpper(curr) && isUpper(next) { - return Noop - } - - if preserveNumberFormatting { - if (curr == '.' || curr == ',') && - isNumber(prev) && isNumber(next) { - return Noop - } - } - - if unicode.IsSpace(curr) { - return SkipSplit - } - for _, d := range delimiters { - if curr == d { - return SkipSplit - } - } - - if splitBeforeNumber { - if isNumber(curr) && !isNumber(prev) { - if preserveNumberFormatting && (prev == '.' || prev == ',') { - return Noop - } - return Split - } - } - - if splitAfterNumber { - if isNumber(prev) && !isNumber(curr) { - return Split - } - } - - if splitCase { - if !isUpper(prev) && isUpper(curr) { - return Split - } - } - - if splitAcronym { - if isUpper(prev) && isUpper(curr) && isLower(next) { - return Split - } - } - - return Noop - } -} - -// SplitOption are options that allow for configuring NewSplitFn -type SplitOption int - -const ( - // SplitCase - FooBar -> Foo_Bar - SplitCase SplitOption = iota - // SplitAcronym - FOOBar -> Foo_Bar - // It won't preserve FOO's case. If you want, you can set the Caser's initialisms so FOO will be in all caps - SplitAcronym - // SplitBeforeNumber - port80 -> port_80 - SplitBeforeNumber - // SplitAfterNumber - 200status -> 200_status - SplitAfterNumber - // PreserveNumberFormatting - a.b.2,000.3.c -> a_b_2,000.3_c - PreserveNumberFormatting -) - -// SplitAction defines if and how to split a string -type SplitAction int - -const ( - // Noop - Continue to next character - Noop SplitAction = iota - // Split - Split between words - // e.g. to split between wordsWithoutDelimiters - Split - // SkipSplit - Split the word and drop the character - // e.g. to split words with delimiters - SkipSplit - // Skip - Remove the character completely - Skip -) - -//nolint:gocyclo -func defaultSplitFn(prev, curr, next rune) SplitAction { - // The most common case will be that it's just a letter so let lowercase letters return early since we know what they should do - if isLower(curr) { - return Noop - } - // Delimiters are _, -, ., and unicode spaces - // Handle . lower down as it needs to happen after number exceptions - if curr == '_' || curr == '-' || isSpace(curr) { - return SkipSplit - } - - if isUpper(curr) { - if isLower(prev) { - // fooBar - return Split - } else if isUpper(prev) && isLower(next) { - // FOOBar - return Split - } - } - - // Do numeric exceptions last to avoid perf penalty - if unicode.IsNumber(prev) { - // v4.3 is not split - if (curr == '.' || curr == ',') && unicode.IsNumber(next) { - return Noop - } - if !unicode.IsNumber(curr) && curr != '.' { - return Split - } - } - // While period is a default delimiter, keep it down here to avoid - // penalty for other delimiters - if curr == '.' { - return SkipSplit - } - - return Noop -} diff --git a/vendor/github.com/ettle/strcase/strcase.go b/vendor/github.com/ettle/strcase/strcase.go deleted file mode 100644 index 46b4f7a684..0000000000 --- a/vendor/github.com/ettle/strcase/strcase.go +++ /dev/null @@ -1,81 +0,0 @@ -package strcase - -// ToSnake returns words in snake_case (lower case words with underscores). -func ToSnake(s string) string { - return convertWithoutInitialisms(s, '_', LowerCase) -} - -// ToGoSnake returns words in snake_case (lower case words with underscores). -// -// Respects Go's common initialisms (e.g. http_response -> HTTP_response). -func ToGoSnake(s string) string { - return convertWithGoInitialisms(s, '_', LowerCase) -} - -// ToSNAKE returns words in SNAKE_CASE (upper case words with underscores). -// Also known as SCREAMING_SNAKE_CASE or UPPER_CASE. -func ToSNAKE(s string) string { - return convertWithoutInitialisms(s, '_', UpperCase) -} - -// ToKebab returns words in kebab-case (lower case words with dashes). -// Also known as dash-case. -func ToKebab(s string) string { - return convertWithoutInitialisms(s, '-', LowerCase) -} - -// ToGoKebab returns words in kebab-case (lower case words with dashes). -// Also known as dash-case. -// -// Respects Go's common initialisms (e.g. http-response -> HTTP-response). -func ToGoKebab(s string) string { - return convertWithGoInitialisms(s, '-', LowerCase) -} - -// ToKEBAB returns words in KEBAB-CASE (upper case words with dashes). -// Also known as SCREAMING-KEBAB-CASE or SCREAMING-DASH-CASE. -func ToKEBAB(s string) string { - return convertWithoutInitialisms(s, '-', UpperCase) -} - -// ToPascal returns words in PascalCase (capitalized words concatenated together). -// Also known as UpperPascalCase. -func ToPascal(s string) string { - return convertWithoutInitialisms(s, 0, TitleCase) -} - -// ToGoPascal returns words in PascalCase (capitalized words concatenated together). -// Also known as UpperPascalCase. -// -// Respects Go's common initialisms (e.g. HttpResponse -> HTTPResponse). -func ToGoPascal(s string) string { - return convertWithGoInitialisms(s, 0, TitleCase) -} - -// ToCamel returns words in camelCase (capitalized words concatenated together, with first word lower case). -// Also known as lowerCamelCase or mixedCase. -func ToCamel(s string) string { - return convertWithoutInitialisms(s, 0, CamelCase) -} - -// ToGoCamel returns words in camelCase (capitalized words concatenated together, with first word lower case). -// Also known as lowerCamelCase or mixedCase. -// -// Respects Go's common initialisms, but first word remains lowercased which is -// important for code generator use cases (e.g. toJson -> toJSON, httpResponse -// -> httpResponse). -func ToGoCamel(s string) string { - return convertWithGoInitialisms(s, 0, CamelCase) -} - -// ToCase returns words in given case and delimiter. -func ToCase(s string, wordCase WordCase, delimiter rune) string { - return convertWithoutInitialisms(s, delimiter, wordCase) -} - -// ToGoCase returns words in given case and delimiter. -// -// Respects Go's common initialisms (e.g. httpResponse -> HTTPResponse). -func ToGoCase(s string, wordCase WordCase, delimiter rune) string { - return convertWithGoInitialisms(s, delimiter, wordCase) -} diff --git a/vendor/github.com/ettle/strcase/unicode.go b/vendor/github.com/ettle/strcase/unicode.go deleted file mode 100644 index b75e25a512..0000000000 --- a/vendor/github.com/ettle/strcase/unicode.go +++ /dev/null @@ -1,48 +0,0 @@ -package strcase - -import "unicode" - -// Unicode functions, optimized for the common case of ascii -// No performance lost by wrapping since these functions get inlined by the compiler - -func isUpper(r rune) bool { - return unicode.IsUpper(r) -} - -func isLower(r rune) bool { - return unicode.IsLower(r) -} - -func isNumber(r rune) bool { - if r >= '0' && r <= '9' { - return true - } - return unicode.IsNumber(r) -} - -func isSpace(r rune) bool { - if r == ' ' || r == '\t' || r == '\n' || r == '\r' { - return true - } else if r < 128 { - return false - } - return unicode.IsSpace(r) -} - -func toUpper(r rune) rune { - if r >= 'a' && r <= 'z' { - return r - 32 - } else if r < 128 { - return r - } - return unicode.ToUpper(r) -} - -func toLower(r rune) rune { - if r >= 'A' && r <= 'Z' { - return r + 32 - } else if r < 128 { - return r - } - return unicode.ToLower(r) -} diff --git a/vendor/github.com/fatih/structtag/LICENSE b/vendor/github.com/fatih/structtag/LICENSE deleted file mode 100644 index 4fd15f9f8f..0000000000 --- a/vendor/github.com/fatih/structtag/LICENSE +++ /dev/null @@ -1,60 +0,0 @@ -Copyright (c) 2017, Fatih Arslan -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of structtag nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -This software includes some portions from Go. Go is used under the terms of the -BSD like license. - -Copyright (c) 2012 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -The Go gopher was designed by Renee French. http://reneefrench.blogspot.com/ The design is licensed under the Creative Commons 3.0 Attributions license. Read this article for more details: https://blog.golang.org/gopher diff --git a/vendor/github.com/fatih/structtag/README.md b/vendor/github.com/fatih/structtag/README.md deleted file mode 100644 index c4e8b1e86e..0000000000 --- a/vendor/github.com/fatih/structtag/README.md +++ /dev/null @@ -1,73 +0,0 @@ -# structtag [![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](http://godoc.org/github.com/fatih/structtag) - -structtag provides an easy way of parsing and manipulating struct tag fields. -Please vendor the library as it might change in future versions. - -# Install - -```bash -go get github.com/fatih/structtag -``` - -# Example - -```go -package main - -import ( - "fmt" - "reflect" - "sort" - - "github.com/fatih/structtag" -) - -func main() { - type t struct { - t string `json:"foo,omitempty,string" xml:"foo"` - } - - // get field tag - tag := reflect.TypeOf(t{}).Field(0).Tag - - // ... and start using structtag by parsing the tag - tags, err := structtag.Parse(string(tag)) - if err != nil { - panic(err) - } - - // iterate over all tags - for _, t := range tags.Tags() { - fmt.Printf("tag: %+v\n", t) - } - - // get a single tag - jsonTag, err := tags.Get("json") - if err != nil { - panic(err) - } - fmt.Println(jsonTag) // Output: json:"foo,omitempty,string" - fmt.Println(jsonTag.Key) // Output: json - fmt.Println(jsonTag.Name) // Output: foo - fmt.Println(jsonTag.Options) // Output: [omitempty string] - - // change existing tag - jsonTag.Name = "foo_bar" - jsonTag.Options = nil - tags.Set(jsonTag) - - // add new tag - tags.Set(&structtag.Tag{ - Key: "hcl", - Name: "foo", - Options: []string{"squash"}, - }) - - // print the tags - fmt.Println(tags) // Output: json:"foo_bar" xml:"foo" hcl:"foo,squash" - - // sort tags according to keys - sort.Sort(tags) - fmt.Println(tags) // Output: hcl:"foo,squash" json:"foo_bar" xml:"foo" -} -``` diff --git a/vendor/github.com/fatih/structtag/tags.go b/vendor/github.com/fatih/structtag/tags.go deleted file mode 100644 index c168fb21c6..0000000000 --- a/vendor/github.com/fatih/structtag/tags.go +++ /dev/null @@ -1,315 +0,0 @@ -package structtag - -import ( - "bytes" - "errors" - "fmt" - "strconv" - "strings" -) - -var ( - errTagSyntax = errors.New("bad syntax for struct tag pair") - errTagKeySyntax = errors.New("bad syntax for struct tag key") - errTagValueSyntax = errors.New("bad syntax for struct tag value") - - errKeyNotSet = errors.New("tag key does not exist") - errTagNotExist = errors.New("tag does not exist") - errTagKeyMismatch = errors.New("mismatch between key and tag.key") -) - -// Tags represent a set of tags from a single struct field -type Tags struct { - tags []*Tag -} - -// Tag defines a single struct's string literal tag -type Tag struct { - // Key is the tag key, such as json, xml, etc.. - // i.e: `json:"foo,omitempty". Here key is: "json" - Key string - - // Name is a part of the value - // i.e: `json:"foo,omitempty". Here name is: "foo" - Name string - - // Options is a part of the value. It contains a slice of tag options i.e: - // `json:"foo,omitempty". Here options is: ["omitempty"] - Options []string -} - -// Parse parses a single struct field tag and returns the set of tags. -func Parse(tag string) (*Tags, error) { - var tags []*Tag - - hasTag := tag != "" - - // NOTE(arslan) following code is from reflect and vet package with some - // modifications to collect all necessary information and extend it with - // usable methods - for tag != "" { - // Skip leading space. - i := 0 - for i < len(tag) && tag[i] == ' ' { - i++ - } - tag = tag[i:] - if tag == "" { - break - } - - // Scan to colon. A space, a quote or a control character is a syntax - // error. Strictly speaking, control chars include the range [0x7f, - // 0x9f], not just [0x00, 0x1f], but in practice, we ignore the - // multi-byte control characters as it is simpler to inspect the tag's - // bytes than the tag's runes. - i = 0 - for i < len(tag) && tag[i] > ' ' && tag[i] != ':' && tag[i] != '"' && tag[i] != 0x7f { - i++ - } - - if i == 0 { - return nil, errTagKeySyntax - } - if i+1 >= len(tag) || tag[i] != ':' { - return nil, errTagSyntax - } - if tag[i+1] != '"' { - return nil, errTagValueSyntax - } - - key := string(tag[:i]) - tag = tag[i+1:] - - // Scan quoted string to find value. - i = 1 - for i < len(tag) && tag[i] != '"' { - if tag[i] == '\\' { - i++ - } - i++ - } - if i >= len(tag) { - return nil, errTagValueSyntax - } - - qvalue := string(tag[:i+1]) - tag = tag[i+1:] - - value, err := strconv.Unquote(qvalue) - if err != nil { - return nil, errTagValueSyntax - } - - res := strings.Split(value, ",") - name := res[0] - options := res[1:] - if len(options) == 0 { - options = nil - } - - tags = append(tags, &Tag{ - Key: key, - Name: name, - Options: options, - }) - } - - if hasTag && len(tags) == 0 { - return nil, nil - } - - return &Tags{ - tags: tags, - }, nil -} - -// Get returns the tag associated with the given key. If the key is present -// in the tag the value (which may be empty) is returned. Otherwise the -// returned value will be the empty string. The ok return value reports whether -// the tag exists or not (which the return value is nil). -func (t *Tags) Get(key string) (*Tag, error) { - for _, tag := range t.tags { - if tag.Key == key { - return tag, nil - } - } - - return nil, errTagNotExist -} - -// Set sets the given tag. If the tag key already exists it'll override it -func (t *Tags) Set(tag *Tag) error { - if tag.Key == "" { - return errKeyNotSet - } - - added := false - for i, tg := range t.tags { - if tg.Key == tag.Key { - added = true - t.tags[i] = tag - } - } - - if !added { - // this means this is a new tag, add it - t.tags = append(t.tags, tag) - } - - return nil -} - -// AddOptions adds the given option for the given key. If the option already -// exists it doesn't add it again. -func (t *Tags) AddOptions(key string, options ...string) { - for i, tag := range t.tags { - if tag.Key != key { - continue - } - - for _, opt := range options { - if !tag.HasOption(opt) { - tag.Options = append(tag.Options, opt) - } - } - - t.tags[i] = tag - } -} - -// DeleteOptions deletes the given options for the given key -func (t *Tags) DeleteOptions(key string, options ...string) { - hasOption := func(option string) bool { - for _, opt := range options { - if opt == option { - return true - } - } - return false - } - - for i, tag := range t.tags { - if tag.Key != key { - continue - } - - var updated []string - for _, opt := range tag.Options { - if !hasOption(opt) { - updated = append(updated, opt) - } - } - - tag.Options = updated - t.tags[i] = tag - } -} - -// Delete deletes the tag for the given keys -func (t *Tags) Delete(keys ...string) { - hasKey := func(key string) bool { - for _, k := range keys { - if k == key { - return true - } - } - return false - } - - var updated []*Tag - for _, tag := range t.tags { - if !hasKey(tag.Key) { - updated = append(updated, tag) - } - } - - t.tags = updated -} - -// Tags returns a slice of tags. The order is the original tag order unless it -// was changed. -func (t *Tags) Tags() []*Tag { - return t.tags -} - -// Tags returns a slice of tags. The order is the original tag order unless it -// was changed. -func (t *Tags) Keys() []string { - var keys []string - for _, tag := range t.tags { - keys = append(keys, tag.Key) - } - return keys -} - -// String reassembles the tags into a valid literal tag field representation -func (t *Tags) String() string { - tags := t.Tags() - if len(tags) == 0 { - return "" - } - - var buf bytes.Buffer - for i, tag := range t.Tags() { - buf.WriteString(tag.String()) - if i != len(tags)-1 { - buf.WriteString(" ") - } - } - return buf.String() -} - -// HasOption returns true if the given option is available in options -func (t *Tag) HasOption(opt string) bool { - for _, tagOpt := range t.Options { - if tagOpt == opt { - return true - } - } - - return false -} - -// Value returns the raw value of the tag, i.e. if the tag is -// `json:"foo,omitempty", the Value is "foo,omitempty" -func (t *Tag) Value() string { - options := strings.Join(t.Options, ",") - if options != "" { - return fmt.Sprintf(`%s,%s`, t.Name, options) - } - return t.Name -} - -// String reassembles the tag into a valid tag field representation -func (t *Tag) String() string { - return fmt.Sprintf(`%s:%q`, t.Key, t.Value()) -} - -// GoString implements the fmt.GoStringer interface -func (t *Tag) GoString() string { - template := `{ - Key: '%s', - Name: '%s', - Option: '%s', - }` - - if t.Options == nil { - return fmt.Sprintf(template, t.Key, t.Name, "nil") - } - - options := strings.Join(t.Options, ",") - return fmt.Sprintf(template, t.Key, t.Name, options) -} - -func (t *Tags) Len() int { - return len(t.tags) -} - -func (t *Tags) Less(i int, j int) bool { - return t.tags[i].Key < t.tags[j].Key -} - -func (t *Tags) Swap(i int, j int) { - t.tags[i], t.tags[j] = t.tags[j], t.tags[i] -} diff --git a/vendor/github.com/firefart/nonamedreturns/LICENSE b/vendor/github.com/firefart/nonamedreturns/LICENSE deleted file mode 100644 index f288702d2f..0000000000 --- a/vendor/github.com/firefart/nonamedreturns/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/vendor/github.com/firefart/nonamedreturns/analyzer/analyzer.go b/vendor/github.com/firefart/nonamedreturns/analyzer/analyzer.go deleted file mode 100644 index a61899f0e9..0000000000 --- a/vendor/github.com/firefart/nonamedreturns/analyzer/analyzer.go +++ /dev/null @@ -1,143 +0,0 @@ -package analyzer - -import ( - "errors" - "flag" - "go/ast" - "go/types" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/inspector" -) - -const FlagReportErrorInDefer = "report-error-in-defer" - -var Analyzer = &analysis.Analyzer{ - Name: "nonamedreturns", - Doc: "Reports all named returns", - Flags: flags(), - Run: run, - Requires: []*analysis.Analyzer{inspect.Analyzer}, -} - -func flags() flag.FlagSet { - fs := flag.FlagSet{} - fs.Bool(FlagReportErrorInDefer, false, "report named error if it is assigned inside defer") - return fs -} - -func run(pass *analysis.Pass) (interface{}, error) { - reportErrorInDefer := pass.Analyzer.Flags.Lookup(FlagReportErrorInDefer).Value.String() == "true" - errorType := types.Universe.Lookup("error").Type() - - inspector, ok := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - if !ok { - return nil, errors.New("failed to get inspector") - } - - // only filter function defintions - nodeFilter := []ast.Node{ - (*ast.FuncDecl)(nil), - (*ast.FuncLit)(nil), - } - - inspector.Preorder(nodeFilter, func(node ast.Node) { - var funcResults *ast.FieldList - var funcBody *ast.BlockStmt - - switch n := node.(type) { - case *ast.FuncLit: - funcResults = n.Type.Results - funcBody = n.Body - case *ast.FuncDecl: - funcResults = n.Type.Results - funcBody = n.Body - default: - return - } - - // Function without body, ex: https://github.com/golang/go/blob/master/src/internal/syscall/unix/net.go - if funcBody == nil { - return - } - - // no return values - if funcResults == nil { - return - } - - resultsList := funcResults.List - - for _, p := range resultsList { - if len(p.Names) == 0 { - // all good, the parameter is not named - continue - } - - for _, n := range p.Names { - if n.Name == "_" { - continue - } - - if !reportErrorInDefer && - types.Identical(pass.TypesInfo.TypeOf(p.Type), errorType) && - findDeferWithVariableAssignment(funcBody, pass.TypesInfo, pass.TypesInfo.ObjectOf(n)) { - continue - } - - pass.Reportf(node.Pos(), "named return %q with type %q found", n.Name, types.ExprString(p.Type)) - } - } - }) - - return nil, nil // nolint:nilnil -} - -func findDeferWithVariableAssignment(body *ast.BlockStmt, info *types.Info, variable types.Object) bool { - found := false - - ast.Inspect(body, func(node ast.Node) bool { - if found { - return false // stop inspection - } - - if d, ok := node.(*ast.DeferStmt); ok { - if fn, ok2 := d.Call.Fun.(*ast.FuncLit); ok2 { - if findVariableAssignment(fn.Body, info, variable) { - found = true - return false - } - } - } - - return true - }) - - return found -} - -func findVariableAssignment(body *ast.BlockStmt, info *types.Info, variable types.Object) bool { - found := false - - ast.Inspect(body, func(node ast.Node) bool { - if found { - return false // stop inspection - } - - if a, ok := node.(*ast.AssignStmt); ok { - for _, lh := range a.Lhs { - if i, ok2 := lh.(*ast.Ident); ok2 { - if info.ObjectOf(i) == variable { - found = true - return false - } - } - } - } - - return true - }) - - return found -} diff --git a/vendor/github.com/fsnotify/fsnotify/.editorconfig b/vendor/github.com/fsnotify/fsnotify/.editorconfig deleted file mode 100644 index fad895851e..0000000000 --- a/vendor/github.com/fsnotify/fsnotify/.editorconfig +++ /dev/null @@ -1,12 +0,0 @@ -root = true - -[*.go] -indent_style = tab -indent_size = 4 -insert_final_newline = true - -[*.{yml,yaml}] -indent_style = space -indent_size = 2 -insert_final_newline = true -trim_trailing_whitespace = true diff --git a/vendor/github.com/fsnotify/fsnotify/.gitattributes b/vendor/github.com/fsnotify/fsnotify/.gitattributes deleted file mode 100644 index 32f1001be0..0000000000 --- a/vendor/github.com/fsnotify/fsnotify/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -go.sum linguist-generated diff --git a/vendor/github.com/fsnotify/fsnotify/.gitignore b/vendor/github.com/fsnotify/fsnotify/.gitignore deleted file mode 100644 index 4cd0cbaf43..0000000000 --- a/vendor/github.com/fsnotify/fsnotify/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -# Setup a Global .gitignore for OS and editor generated files: -# https://help.github.com/articles/ignoring-files -# git config --global core.excludesfile ~/.gitignore_global - -.vagrant -*.sublime-project diff --git a/vendor/github.com/fsnotify/fsnotify/.mailmap b/vendor/github.com/fsnotify/fsnotify/.mailmap deleted file mode 100644 index a04f2907fe..0000000000 --- a/vendor/github.com/fsnotify/fsnotify/.mailmap +++ /dev/null @@ -1,2 +0,0 @@ -Chris Howey -Nathan Youngman <4566+nathany@users.noreply.github.com> diff --git a/vendor/github.com/fsnotify/fsnotify/AUTHORS b/vendor/github.com/fsnotify/fsnotify/AUTHORS deleted file mode 100644 index 6cbabe5ef5..0000000000 --- a/vendor/github.com/fsnotify/fsnotify/AUTHORS +++ /dev/null @@ -1,62 +0,0 @@ -# Names should be added to this file as -# Name or Organization -# The email address is not required for organizations. - -# You can update this list using the following command: -# -# $ (head -n10 AUTHORS && git shortlog -se | sed -E 's/^\s+[0-9]+\t//') | tee AUTHORS - -# Please keep the list sorted. - -Aaron L -Adrien Bustany -Alexey Kazakov -Amit Krishnan -Anmol Sethi -Bjørn Erik Pedersen -Brian Goff -Bruno Bigras -Caleb Spare -Case Nelson -Chris Howey -Christoffer Buchholz -Daniel Wagner-Hall -Dave Cheney -Eric Lin -Evan Phoenix -Francisco Souza -Gautam Dey -Hari haran -Ichinose Shogo -Johannes Ebke -John C Barstow -Kelvin Fo -Ken-ichirou MATSUZAWA -Matt Layher -Matthias Stone -Nathan Youngman -Nickolai Zeldovich -Oliver Bristow -Patrick -Paul Hammond -Pawel Knap -Pieter Droogendijk -Pratik Shinde -Pursuit92 -Riku Voipio -Rob Figueiredo -Rodrigo Chiossi -Slawek Ligus -Soge Zhang -Tiffany Jernigan -Tilak Sharma -Tobias Klauser -Tom Payne -Travis Cline -Tudor Golubenco -Vahe Khachikyan -Yukang -bronze1man -debrando -henrikedwards -铁哥 diff --git a/vendor/github.com/fsnotify/fsnotify/CHANGELOG.md b/vendor/github.com/fsnotify/fsnotify/CHANGELOG.md deleted file mode 100644 index cc01c08f56..0000000000 --- a/vendor/github.com/fsnotify/fsnotify/CHANGELOG.md +++ /dev/null @@ -1,357 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## [Unreleased] - -## [1.5.4] - 2022-04-25 - -* Windows: add missing defer to `Watcher.WatchList` [#447](https://github.com/fsnotify/fsnotify/pull/447) -* go.mod: use latest x/sys [#444](https://github.com/fsnotify/fsnotify/pull/444) -* Fix compilation for OpenBSD [#443](https://github.com/fsnotify/fsnotify/pull/443) - -## [1.5.3] - 2022-04-22 - -* This version is retracted. An incorrect branch is published accidentally [#445](https://github.com/fsnotify/fsnotify/issues/445) - -## [1.5.2] - 2022-04-21 - -* Add a feature to return the directories and files that are being monitored [#374](https://github.com/fsnotify/fsnotify/pull/374) -* Fix potential crash on windows if `raw.FileNameLength` exceeds `syscall.MAX_PATH` [#361](https://github.com/fsnotify/fsnotify/pull/361) -* Allow build on unsupported GOOS [#424](https://github.com/fsnotify/fsnotify/pull/424) -* Don't set `poller.fd` twice in `newFdPoller` [#406](https://github.com/fsnotify/fsnotify/pull/406) -* fix go vet warnings: call to `(*T).Fatalf` from a non-test goroutine [#416](https://github.com/fsnotify/fsnotify/pull/416) - -## [1.5.1] - 2021-08-24 - -* Revert Add AddRaw to not follow symlinks [#394](https://github.com/fsnotify/fsnotify/pull/394) - -## [1.5.0] - 2021-08-20 - -* Go: Increase minimum required version to Go 1.12 [#381](https://github.com/fsnotify/fsnotify/pull/381) -* Feature: Add AddRaw method which does not follow symlinks when adding a watch [#289](https://github.com/fsnotify/fsnotify/pull/298) -* Windows: Follow symlinks by default like on all other systems [#289](https://github.com/fsnotify/fsnotify/pull/289) -* CI: Use GitHub Actions for CI and cover go 1.12-1.17 - [#378](https://github.com/fsnotify/fsnotify/pull/378) - [#381](https://github.com/fsnotify/fsnotify/pull/381) - [#385](https://github.com/fsnotify/fsnotify/pull/385) -* Go 1.14+: Fix unsafe pointer conversion [#325](https://github.com/fsnotify/fsnotify/pull/325) - -## [1.4.7] - 2018-01-09 - -* BSD/macOS: Fix possible deadlock on closing the watcher on kqueue (thanks @nhooyr and @glycerine) -* Tests: Fix missing verb on format string (thanks @rchiossi) -* Linux: Fix deadlock in Remove (thanks @aarondl) -* Linux: Watch.Add improvements (avoid race, fix consistency, reduce garbage) (thanks @twpayne) -* Docs: Moved FAQ into the README (thanks @vahe) -* Linux: Properly handle inotify's IN_Q_OVERFLOW event (thanks @zeldovich) -* Docs: replace references to OS X with macOS - -## [1.4.2] - 2016-10-10 - -* Linux: use InotifyInit1 with IN_CLOEXEC to stop leaking a file descriptor to a child process when using fork/exec [#178](https://github.com/fsnotify/fsnotify/pull/178) (thanks @pattyshack) - -## [1.4.1] - 2016-10-04 - -* Fix flaky inotify stress test on Linux [#177](https://github.com/fsnotify/fsnotify/pull/177) (thanks @pattyshack) - -## [1.4.0] - 2016-10-01 - -* add a String() method to Event.Op [#165](https://github.com/fsnotify/fsnotify/pull/165) (thanks @oozie) - -## [1.3.1] - 2016-06-28 - -* Windows: fix for double backslash when watching the root of a drive [#151](https://github.com/fsnotify/fsnotify/issues/151) (thanks @brunoqc) - -## [1.3.0] - 2016-04-19 - -* Support linux/arm64 by [patching](https://go-review.googlesource.com/#/c/21971/) x/sys/unix and switching to to it from syscall (thanks @suihkulokki) [#135](https://github.com/fsnotify/fsnotify/pull/135) - -## [1.2.10] - 2016-03-02 - -* Fix golint errors in windows.go [#121](https://github.com/fsnotify/fsnotify/pull/121) (thanks @tiffanyfj) - -## [1.2.9] - 2016-01-13 - -kqueue: Fix logic for CREATE after REMOVE [#111](https://github.com/fsnotify/fsnotify/pull/111) (thanks @bep) - -## [1.2.8] - 2015-12-17 - -* kqueue: fix race condition in Close [#105](https://github.com/fsnotify/fsnotify/pull/105) (thanks @djui for reporting the issue and @ppknap for writing a failing test) -* inotify: fix race in test -* enable race detection for continuous integration (Linux, Mac, Windows) - -## [1.2.5] - 2015-10-17 - -* inotify: use epoll_create1 for arm64 support (requires Linux 2.6.27 or later) [#100](https://github.com/fsnotify/fsnotify/pull/100) (thanks @suihkulokki) -* inotify: fix path leaks [#73](https://github.com/fsnotify/fsnotify/pull/73) (thanks @chamaken) -* kqueue: watch for rename events on subdirectories [#83](https://github.com/fsnotify/fsnotify/pull/83) (thanks @guotie) -* kqueue: avoid infinite loops from symlinks cycles [#101](https://github.com/fsnotify/fsnotify/pull/101) (thanks @illicitonion) - -## [1.2.1] - 2015-10-14 - -* kqueue: don't watch named pipes [#98](https://github.com/fsnotify/fsnotify/pull/98) (thanks @evanphx) - -## [1.2.0] - 2015-02-08 - -* inotify: use epoll to wake up readEvents [#66](https://github.com/fsnotify/fsnotify/pull/66) (thanks @PieterD) -* inotify: closing watcher should now always shut down goroutine [#63](https://github.com/fsnotify/fsnotify/pull/63) (thanks @PieterD) -* kqueue: close kqueue after removing watches, fixes [#59](https://github.com/fsnotify/fsnotify/issues/59) - -## [1.1.1] - 2015-02-05 - -* inotify: Retry read on EINTR [#61](https://github.com/fsnotify/fsnotify/issues/61) (thanks @PieterD) - -## [1.1.0] - 2014-12-12 - -* kqueue: rework internals [#43](https://github.com/fsnotify/fsnotify/pull/43) - * add low-level functions - * only need to store flags on directories - * less mutexes [#13](https://github.com/fsnotify/fsnotify/issues/13) - * done can be an unbuffered channel - * remove calls to os.NewSyscallError -* More efficient string concatenation for Event.String() [#52](https://github.com/fsnotify/fsnotify/pull/52) (thanks @mdlayher) -* kqueue: fix regression in rework causing subdirectories to be watched [#48](https://github.com/fsnotify/fsnotify/issues/48) -* kqueue: cleanup internal watch before sending remove event [#51](https://github.com/fsnotify/fsnotify/issues/51) - -## [1.0.4] - 2014-09-07 - -* kqueue: add dragonfly to the build tags. -* Rename source code files, rearrange code so exported APIs are at the top. -* Add done channel to example code. [#37](https://github.com/fsnotify/fsnotify/pull/37) (thanks @chenyukang) - -## [1.0.3] - 2014-08-19 - -* [Fix] Windows MOVED_TO now translates to Create like on BSD and Linux. [#36](https://github.com/fsnotify/fsnotify/issues/36) - -## [1.0.2] - 2014-08-17 - -* [Fix] Missing create events on macOS. [#14](https://github.com/fsnotify/fsnotify/issues/14) (thanks @zhsso) -* [Fix] Make ./path and path equivalent. (thanks @zhsso) - -## [1.0.0] - 2014-08-15 - -* [API] Remove AddWatch on Windows, use Add. -* Improve documentation for exported identifiers. [#30](https://github.com/fsnotify/fsnotify/issues/30) -* Minor updates based on feedback from golint. - -## dev / 2014-07-09 - -* Moved to [github.com/fsnotify/fsnotify](https://github.com/fsnotify/fsnotify). -* Use os.NewSyscallError instead of returning errno (thanks @hariharan-uno) - -## dev / 2014-07-04 - -* kqueue: fix incorrect mutex used in Close() -* Update example to demonstrate usage of Op. - -## dev / 2014-06-28 - -* [API] Don't set the Write Op for attribute notifications [#4](https://github.com/fsnotify/fsnotify/issues/4) -* Fix for String() method on Event (thanks Alex Brainman) -* Don't build on Plan 9 or Solaris (thanks @4ad) - -## dev / 2014-06-21 - -* Events channel of type Event rather than *Event. -* [internal] use syscall constants directly for inotify and kqueue. -* [internal] kqueue: rename events to kevents and fileEvent to event. - -## dev / 2014-06-19 - -* Go 1.3+ required on Windows (uses syscall.ERROR_MORE_DATA internally). -* [internal] remove cookie from Event struct (unused). -* [internal] Event struct has the same definition across every OS. -* [internal] remove internal watch and removeWatch methods. - -## dev / 2014-06-12 - -* [API] Renamed Watch() to Add() and RemoveWatch() to Remove(). -* [API] Pluralized channel names: Events and Errors. -* [API] Renamed FileEvent struct to Event. -* [API] Op constants replace methods like IsCreate(). - -## dev / 2014-06-12 - -* Fix data race on kevent buffer (thanks @tilaks) [#98](https://github.com/howeyc/fsnotify/pull/98) - -## dev / 2014-05-23 - -* [API] Remove current implementation of WatchFlags. - * current implementation doesn't take advantage of OS for efficiency - * provides little benefit over filtering events as they are received, but has extra bookkeeping and mutexes - * no tests for the current implementation - * not fully implemented on Windows [#93](https://github.com/howeyc/fsnotify/issues/93#issuecomment-39285195) - -## [0.9.3] - 2014-12-31 - -* kqueue: cleanup internal watch before sending remove event [#51](https://github.com/fsnotify/fsnotify/issues/51) - -## [0.9.2] - 2014-08-17 - -* [Backport] Fix missing create events on macOS. [#14](https://github.com/fsnotify/fsnotify/issues/14) (thanks @zhsso) - -## [0.9.1] - 2014-06-12 - -* Fix data race on kevent buffer (thanks @tilaks) [#98](https://github.com/howeyc/fsnotify/pull/98) - -## [0.9.0] - 2014-01-17 - -* IsAttrib() for events that only concern a file's metadata [#79][] (thanks @abustany) -* [Fix] kqueue: fix deadlock [#77][] (thanks @cespare) -* [NOTICE] Development has moved to `code.google.com/p/go.exp/fsnotify` in preparation for inclusion in the Go standard library. - -## [0.8.12] - 2013-11-13 - -* [API] Remove FD_SET and friends from Linux adapter - -## [0.8.11] - 2013-11-02 - -* [Doc] Add Changelog [#72][] (thanks @nathany) -* [Doc] Spotlight and double modify events on macOS [#62][] (reported by @paulhammond) - -## [0.8.10] - 2013-10-19 - -* [Fix] kqueue: remove file watches when parent directory is removed [#71][] (reported by @mdwhatcott) -* [Fix] kqueue: race between Close and readEvents [#70][] (reported by @bernerdschaefer) -* [Doc] specify OS-specific limits in README (thanks @debrando) - -## [0.8.9] - 2013-09-08 - -* [Doc] Contributing (thanks @nathany) -* [Doc] update package path in example code [#63][] (thanks @paulhammond) -* [Doc] GoCI badge in README (Linux only) [#60][] -* [Doc] Cross-platform testing with Vagrant [#59][] (thanks @nathany) - -## [0.8.8] - 2013-06-17 - -* [Fix] Windows: handle `ERROR_MORE_DATA` on Windows [#49][] (thanks @jbowtie) - -## [0.8.7] - 2013-06-03 - -* [API] Make syscall flags internal -* [Fix] inotify: ignore event changes -* [Fix] race in symlink test [#45][] (reported by @srid) -* [Fix] tests on Windows -* lower case error messages - -## [0.8.6] - 2013-05-23 - -* kqueue: Use EVT_ONLY flag on Darwin -* [Doc] Update README with full example - -## [0.8.5] - 2013-05-09 - -* [Fix] inotify: allow monitoring of "broken" symlinks (thanks @tsg) - -## [0.8.4] - 2013-04-07 - -* [Fix] kqueue: watch all file events [#40][] (thanks @ChrisBuchholz) - -## [0.8.3] - 2013-03-13 - -* [Fix] inoitfy/kqueue memory leak [#36][] (reported by @nbkolchin) -* [Fix] kqueue: use fsnFlags for watching a directory [#33][] (reported by @nbkolchin) - -## [0.8.2] - 2013-02-07 - -* [Doc] add Authors -* [Fix] fix data races for map access [#29][] (thanks @fsouza) - -## [0.8.1] - 2013-01-09 - -* [Fix] Windows path separators -* [Doc] BSD License - -## [0.8.0] - 2012-11-09 - -* kqueue: directory watching improvements (thanks @vmirage) -* inotify: add `IN_MOVED_TO` [#25][] (requested by @cpisto) -* [Fix] kqueue: deleting watched directory [#24][] (reported by @jakerr) - -## [0.7.4] - 2012-10-09 - -* [Fix] inotify: fixes from https://codereview.appspot.com/5418045/ (ugorji) -* [Fix] kqueue: preserve watch flags when watching for delete [#21][] (reported by @robfig) -* [Fix] kqueue: watch the directory even if it isn't a new watch (thanks @robfig) -* [Fix] kqueue: modify after recreation of file - -## [0.7.3] - 2012-09-27 - -* [Fix] kqueue: watch with an existing folder inside the watched folder (thanks @vmirage) -* [Fix] kqueue: no longer get duplicate CREATE events - -## [0.7.2] - 2012-09-01 - -* kqueue: events for created directories - -## [0.7.1] - 2012-07-14 - -* [Fix] for renaming files - -## [0.7.0] - 2012-07-02 - -* [Feature] FSNotify flags -* [Fix] inotify: Added file name back to event path - -## [0.6.0] - 2012-06-06 - -* kqueue: watch files after directory created (thanks @tmc) - -## [0.5.1] - 2012-05-22 - -* [Fix] inotify: remove all watches before Close() - -## [0.5.0] - 2012-05-03 - -* [API] kqueue: return errors during watch instead of sending over channel -* kqueue: match symlink behavior on Linux -* inotify: add `DELETE_SELF` (requested by @taralx) -* [Fix] kqueue: handle EINTR (reported by @robfig) -* [Doc] Godoc example [#1][] (thanks @davecheney) - -## [0.4.0] - 2012-03-30 - -* Go 1 released: build with go tool -* [Feature] Windows support using winfsnotify -* Windows does not have attribute change notifications -* Roll attribute notifications into IsModify - -## [0.3.0] - 2012-02-19 - -* kqueue: add files when watch directory - -## [0.2.0] - 2011-12-30 - -* update to latest Go weekly code - -## [0.1.0] - 2011-10-19 - -* kqueue: add watch on file creation to match inotify -* kqueue: create file event -* inotify: ignore `IN_IGNORED` events -* event String() -* linux: common FileEvent functions -* initial commit - -[#79]: https://github.com/howeyc/fsnotify/pull/79 -[#77]: https://github.com/howeyc/fsnotify/pull/77 -[#72]: https://github.com/howeyc/fsnotify/issues/72 -[#71]: https://github.com/howeyc/fsnotify/issues/71 -[#70]: https://github.com/howeyc/fsnotify/issues/70 -[#63]: https://github.com/howeyc/fsnotify/issues/63 -[#62]: https://github.com/howeyc/fsnotify/issues/62 -[#60]: https://github.com/howeyc/fsnotify/issues/60 -[#59]: https://github.com/howeyc/fsnotify/issues/59 -[#49]: https://github.com/howeyc/fsnotify/issues/49 -[#45]: https://github.com/howeyc/fsnotify/issues/45 -[#40]: https://github.com/howeyc/fsnotify/issues/40 -[#36]: https://github.com/howeyc/fsnotify/issues/36 -[#33]: https://github.com/howeyc/fsnotify/issues/33 -[#29]: https://github.com/howeyc/fsnotify/issues/29 -[#25]: https://github.com/howeyc/fsnotify/issues/25 -[#24]: https://github.com/howeyc/fsnotify/issues/24 -[#21]: https://github.com/howeyc/fsnotify/issues/21 diff --git a/vendor/github.com/fsnotify/fsnotify/CONTRIBUTING.md b/vendor/github.com/fsnotify/fsnotify/CONTRIBUTING.md deleted file mode 100644 index 8a642563d7..0000000000 --- a/vendor/github.com/fsnotify/fsnotify/CONTRIBUTING.md +++ /dev/null @@ -1,60 +0,0 @@ -# Contributing - -## Issues - -* Request features and report bugs using the [GitHub Issue Tracker](https://github.com/fsnotify/fsnotify/issues). -* Please indicate the platform you are using fsnotify on. -* A code example to reproduce the problem is appreciated. - -## Pull Requests - -### Contributor License Agreement - -fsnotify is derived from code in the [golang.org/x/exp](https://godoc.org/golang.org/x/exp) package and it may be included [in the standard library](https://github.com/fsnotify/fsnotify/issues/1) in the future. Therefore fsnotify carries the same [LICENSE](https://github.com/fsnotify/fsnotify/blob/master/LICENSE) as Go. Contributors retain their copyright, so you need to fill out a short form before we can accept your contribution: [Google Individual Contributor License Agreement](https://developers.google.com/open-source/cla/individual). - -Please indicate that you have signed the CLA in your pull request. - -### How fsnotify is Developed - -* Development is done on feature branches. -* Tests are run on BSD, Linux, macOS and Windows. -* Pull requests are reviewed and [applied to master][am] using [hub][]. - * Maintainers may modify or squash commits rather than asking contributors to. -* To issue a new release, the maintainers will: - * Update the CHANGELOG - * Tag a version, which will become available through gopkg.in. - -### How to Fork - -For smooth sailing, always use the original import path. Installing with `go get` makes this easy. - -1. Install from GitHub (`go get -u github.com/fsnotify/fsnotify`) -2. Create your feature branch (`git checkout -b my-new-feature`) -3. Ensure everything works and the tests pass (see below) -4. Commit your changes (`git commit -am 'Add some feature'`) - -Contribute upstream: - -1. Fork fsnotify on GitHub -2. Add your remote (`git remote add fork git@github.com:mycompany/repo.git`) -3. Push to the branch (`git push fork my-new-feature`) -4. Create a new Pull Request on GitHub - -This workflow is [thoroughly explained by Katrina Owen](https://splice.com/blog/contributing-open-source-git-repositories-go/). - -### Testing - -fsnotify uses build tags to compile different code on Linux, BSD, macOS, and Windows. - -Before doing a pull request, please do your best to test your changes on multiple platforms, and list which platforms you were able/unable to test on. - -### Maintainers - -Help maintaining fsnotify is welcome. To be a maintainer: - -* Submit a pull request and sign the CLA as above. -* You must be able to run the test suite on Mac, Windows, Linux and BSD. - -All code changes should be internal pull requests. - -Releases are tagged using [Semantic Versioning](http://semver.org/). diff --git a/vendor/github.com/fsnotify/fsnotify/LICENSE b/vendor/github.com/fsnotify/fsnotify/LICENSE deleted file mode 100644 index e180c8fb05..0000000000 --- a/vendor/github.com/fsnotify/fsnotify/LICENSE +++ /dev/null @@ -1,28 +0,0 @@ -Copyright (c) 2012 The Go Authors. All rights reserved. -Copyright (c) 2012-2019 fsnotify Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/fsnotify/fsnotify/README.md b/vendor/github.com/fsnotify/fsnotify/README.md deleted file mode 100644 index 0731c5ef8a..0000000000 --- a/vendor/github.com/fsnotify/fsnotify/README.md +++ /dev/null @@ -1,120 +0,0 @@ -# File system notifications for Go - -[![Go Reference](https://pkg.go.dev/badge/github.com/fsnotify/fsnotify.svg)](https://pkg.go.dev/github.com/fsnotify/fsnotify) [![Go Report Card](https://goreportcard.com/badge/github.com/fsnotify/fsnotify)](https://goreportcard.com/report/github.com/fsnotify/fsnotify) [![Maintainers Wanted](https://img.shields.io/badge/maintainers-wanted-red.svg)](https://github.com/fsnotify/fsnotify/issues/413) - -fsnotify utilizes [`golang.org/x/sys`](https://pkg.go.dev/golang.org/x/sys) rather than [`syscall`](https://pkg.go.dev/syscall) from the standard library. - -Cross platform: Windows, Linux, BSD and macOS. - -| Adapter | OS | Status | -| --------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | -| inotify | Linux 2.6.27 or later, Android\* | Supported | -| kqueue | BSD, macOS, iOS\* | Supported | -| ReadDirectoryChangesW | Windows | Supported | -| FSEvents | macOS | [Planned](https://github.com/fsnotify/fsnotify/issues/11) | -| FEN | Solaris 11 | [In Progress](https://github.com/fsnotify/fsnotify/pull/371) | -| fanotify | Linux 2.6.37+ | [Maybe](https://github.com/fsnotify/fsnotify/issues/114) | -| USN Journals | Windows | [Maybe](https://github.com/fsnotify/fsnotify/issues/53) | -| Polling | *All* | [Maybe](https://github.com/fsnotify/fsnotify/issues/9) | - -\* Android and iOS are untested. - -Please see [the documentation](https://pkg.go.dev/github.com/fsnotify/fsnotify) and consult the [FAQ](#faq) for usage information. - -## API stability - -fsnotify is a fork of [howeyc/fsnotify](https://github.com/howeyc/fsnotify) with a new API as of v1.0. The API is based on [this design document](http://goo.gl/MrYxyA). - -All [releases](https://github.com/fsnotify/fsnotify/releases) are tagged based on [Semantic Versioning](http://semver.org/). - -## Usage - -```go -package main - -import ( - "log" - - "github.com/fsnotify/fsnotify" -) - -func main() { - watcher, err := fsnotify.NewWatcher() - if err != nil { - log.Fatal(err) - } - defer watcher.Close() - - done := make(chan bool) - go func() { - for { - select { - case event, ok := <-watcher.Events: - if !ok { - return - } - log.Println("event:", event) - if event.Op&fsnotify.Write == fsnotify.Write { - log.Println("modified file:", event.Name) - } - case err, ok := <-watcher.Errors: - if !ok { - return - } - log.Println("error:", err) - } - } - }() - - err = watcher.Add("/tmp/foo") - if err != nil { - log.Fatal(err) - } - <-done -} -``` - -## Contributing - -Please refer to [CONTRIBUTING][] before opening an issue or pull request. - -## FAQ - -**When a file is moved to another directory is it still being watched?** - -No (it shouldn't be, unless you are watching where it was moved to). - -**When I watch a directory, are all subdirectories watched as well?** - -No, you must add watches for any directory you want to watch (a recursive watcher is on the roadmap [#18][]). - -**Do I have to watch the Error and Event channels in a separate goroutine?** - -As of now, yes. Looking into making this single-thread friendly (see [howeyc #7][#7]) - -**Why am I receiving multiple events for the same file on OS X?** - -Spotlight indexing on OS X can result in multiple events (see [howeyc #62][#62]). A temporary workaround is to add your folder(s) to the *Spotlight Privacy settings* until we have a native FSEvents implementation (see [#11][]). - -**How many files can be watched at once?** - -There are OS-specific limits as to how many watches can be created: -* Linux: /proc/sys/fs/inotify/max_user_watches contains the limit, reaching this limit results in a "no space left on device" error. -* BSD / OSX: sysctl variables "kern.maxfiles" and "kern.maxfilesperproc", reaching these limits results in a "too many open files" error. - -**Why don't notifications work with NFS filesystems or filesystem in userspace (FUSE)?** - -fsnotify requires support from underlying OS to work. The current NFS protocol does not provide network level support for file notifications. - -[#62]: https://github.com/howeyc/fsnotify/issues/62 -[#18]: https://github.com/fsnotify/fsnotify/issues/18 -[#11]: https://github.com/fsnotify/fsnotify/issues/11 -[#7]: https://github.com/howeyc/fsnotify/issues/7 - -[contributing]: https://github.com/fsnotify/fsnotify/blob/master/CONTRIBUTING.md - -## Related Projects - -* [notify](https://github.com/rjeczalik/notify) -* [fsevents](https://github.com/fsnotify/fsevents) - diff --git a/vendor/github.com/fsnotify/fsnotify/fen.go b/vendor/github.com/fsnotify/fsnotify/fen.go deleted file mode 100644 index b3ac3d8f55..0000000000 --- a/vendor/github.com/fsnotify/fsnotify/fen.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build solaris -// +build solaris - -package fsnotify - -import ( - "errors" -) - -// Watcher watches a set of files, delivering events to a channel. -type Watcher struct { - Events chan Event - Errors chan error -} - -// NewWatcher establishes a new watcher with the underlying OS and begins waiting for events. -func NewWatcher() (*Watcher, error) { - return nil, errors.New("FEN based watcher not yet supported for fsnotify\n") -} - -// Close removes all watches and closes the events channel. -func (w *Watcher) Close() error { - return nil -} - -// Add starts watching the named file or directory (non-recursively). -func (w *Watcher) Add(name string) error { - return nil -} - -// Remove stops watching the the named file or directory (non-recursively). -func (w *Watcher) Remove(name string) error { - return nil -} diff --git a/vendor/github.com/fsnotify/fsnotify/fsnotify.go b/vendor/github.com/fsnotify/fsnotify/fsnotify.go deleted file mode 100644 index 0f4ee52e8a..0000000000 --- a/vendor/github.com/fsnotify/fsnotify/fsnotify.go +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !plan9 -// +build !plan9 - -// Package fsnotify provides a platform-independent interface for file system notifications. -package fsnotify - -import ( - "bytes" - "errors" - "fmt" -) - -// Event represents a single file system notification. -type Event struct { - Name string // Relative path to the file or directory. - Op Op // File operation that triggered the event. -} - -// Op describes a set of file operations. -type Op uint32 - -// These are the generalized file operations that can trigger a notification. -const ( - Create Op = 1 << iota - Write - Remove - Rename - Chmod -) - -func (op Op) String() string { - // Use a buffer for efficient string concatenation - var buffer bytes.Buffer - - if op&Create == Create { - buffer.WriteString("|CREATE") - } - if op&Remove == Remove { - buffer.WriteString("|REMOVE") - } - if op&Write == Write { - buffer.WriteString("|WRITE") - } - if op&Rename == Rename { - buffer.WriteString("|RENAME") - } - if op&Chmod == Chmod { - buffer.WriteString("|CHMOD") - } - if buffer.Len() == 0 { - return "" - } - return buffer.String()[1:] // Strip leading pipe -} - -// String returns a string representation of the event in the form -// "file: REMOVE|WRITE|..." -func (e Event) String() string { - return fmt.Sprintf("%q: %s", e.Name, e.Op.String()) -} - -// Common errors that can be reported by a watcher -var ( - ErrEventOverflow = errors.New("fsnotify queue overflow") -) diff --git a/vendor/github.com/fsnotify/fsnotify/fsnotify_unsupported.go b/vendor/github.com/fsnotify/fsnotify/fsnotify_unsupported.go deleted file mode 100644 index 5968855983..0000000000 --- a/vendor/github.com/fsnotify/fsnotify/fsnotify_unsupported.go +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !darwin && !dragonfly && !freebsd && !openbsd && !linux && !netbsd && !solaris && !windows -// +build !darwin,!dragonfly,!freebsd,!openbsd,!linux,!netbsd,!solaris,!windows - -package fsnotify - -import ( - "fmt" - "runtime" -) - -// Watcher watches a set of files, delivering events to a channel. -type Watcher struct{} - -// NewWatcher establishes a new watcher with the underlying OS and begins waiting for events. -func NewWatcher() (*Watcher, error) { - return nil, fmt.Errorf("fsnotify not supported on %s", runtime.GOOS) -} - -// Close removes all watches and closes the events channel. -func (w *Watcher) Close() error { - return nil -} - -// Add starts watching the named file or directory (non-recursively). -func (w *Watcher) Add(name string) error { - return nil -} - -// Remove stops watching the the named file or directory (non-recursively). -func (w *Watcher) Remove(name string) error { - return nil -} diff --git a/vendor/github.com/fsnotify/fsnotify/inotify.go b/vendor/github.com/fsnotify/fsnotify/inotify.go deleted file mode 100644 index a6d0e0ec8c..0000000000 --- a/vendor/github.com/fsnotify/fsnotify/inotify.go +++ /dev/null @@ -1,351 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build linux -// +build linux - -package fsnotify - -import ( - "errors" - "fmt" - "io" - "os" - "path/filepath" - "strings" - "sync" - "unsafe" - - "golang.org/x/sys/unix" -) - -// Watcher watches a set of files, delivering events to a channel. -type Watcher struct { - Events chan Event - Errors chan error - mu sync.Mutex // Map access - fd int - poller *fdPoller - watches map[string]*watch // Map of inotify watches (key: path) - paths map[int]string // Map of watched paths (key: watch descriptor) - done chan struct{} // Channel for sending a "quit message" to the reader goroutine - doneResp chan struct{} // Channel to respond to Close -} - -// NewWatcher establishes a new watcher with the underlying OS and begins waiting for events. -func NewWatcher() (*Watcher, error) { - // Create inotify fd - fd, errno := unix.InotifyInit1(unix.IN_CLOEXEC) - if fd == -1 { - return nil, errno - } - // Create epoll - poller, err := newFdPoller(fd) - if err != nil { - unix.Close(fd) - return nil, err - } - w := &Watcher{ - fd: fd, - poller: poller, - watches: make(map[string]*watch), - paths: make(map[int]string), - Events: make(chan Event), - Errors: make(chan error), - done: make(chan struct{}), - doneResp: make(chan struct{}), - } - - go w.readEvents() - return w, nil -} - -func (w *Watcher) isClosed() bool { - select { - case <-w.done: - return true - default: - return false - } -} - -// Close removes all watches and closes the events channel. -func (w *Watcher) Close() error { - if w.isClosed() { - return nil - } - - // Send 'close' signal to goroutine, and set the Watcher to closed. - close(w.done) - - // Wake up goroutine - w.poller.wake() - - // Wait for goroutine to close - <-w.doneResp - - return nil -} - -// Add starts watching the named file or directory (non-recursively). -func (w *Watcher) Add(name string) error { - name = filepath.Clean(name) - if w.isClosed() { - return errors.New("inotify instance already closed") - } - - const agnosticEvents = unix.IN_MOVED_TO | unix.IN_MOVED_FROM | - unix.IN_CREATE | unix.IN_ATTRIB | unix.IN_MODIFY | - unix.IN_MOVE_SELF | unix.IN_DELETE | unix.IN_DELETE_SELF - - var flags uint32 = agnosticEvents - - w.mu.Lock() - defer w.mu.Unlock() - watchEntry := w.watches[name] - if watchEntry != nil { - flags |= watchEntry.flags | unix.IN_MASK_ADD - } - wd, errno := unix.InotifyAddWatch(w.fd, name, flags) - if wd == -1 { - return errno - } - - if watchEntry == nil { - w.watches[name] = &watch{wd: uint32(wd), flags: flags} - w.paths[wd] = name - } else { - watchEntry.wd = uint32(wd) - watchEntry.flags = flags - } - - return nil -} - -// Remove stops watching the named file or directory (non-recursively). -func (w *Watcher) Remove(name string) error { - name = filepath.Clean(name) - - // Fetch the watch. - w.mu.Lock() - defer w.mu.Unlock() - watch, ok := w.watches[name] - - // Remove it from inotify. - if !ok { - return fmt.Errorf("can't remove non-existent inotify watch for: %s", name) - } - - // We successfully removed the watch if InotifyRmWatch doesn't return an - // error, we need to clean up our internal state to ensure it matches - // inotify's kernel state. - delete(w.paths, int(watch.wd)) - delete(w.watches, name) - - // inotify_rm_watch will return EINVAL if the file has been deleted; - // the inotify will already have been removed. - // watches and pathes are deleted in ignoreLinux() implicitly and asynchronously - // by calling inotify_rm_watch() below. e.g. readEvents() goroutine receives IN_IGNORE - // so that EINVAL means that the wd is being rm_watch()ed or its file removed - // by another thread and we have not received IN_IGNORE event. - success, errno := unix.InotifyRmWatch(w.fd, watch.wd) - if success == -1 { - // TODO: Perhaps it's not helpful to return an error here in every case. - // the only two possible errors are: - // EBADF, which happens when w.fd is not a valid file descriptor of any kind. - // EINVAL, which is when fd is not an inotify descriptor or wd is not a valid watch descriptor. - // Watch descriptors are invalidated when they are removed explicitly or implicitly; - // explicitly by inotify_rm_watch, implicitly when the file they are watching is deleted. - return errno - } - - return nil -} - -// WatchList returns the directories and files that are being monitered. -func (w *Watcher) WatchList() []string { - w.mu.Lock() - defer w.mu.Unlock() - - entries := make([]string, 0, len(w.watches)) - for pathname := range w.watches { - entries = append(entries, pathname) - } - - return entries -} - -type watch struct { - wd uint32 // Watch descriptor (as returned by the inotify_add_watch() syscall) - flags uint32 // inotify flags of this watch (see inotify(7) for the list of valid flags) -} - -// readEvents reads from the inotify file descriptor, converts the -// received events into Event objects and sends them via the Events channel -func (w *Watcher) readEvents() { - var ( - buf [unix.SizeofInotifyEvent * 4096]byte // Buffer for a maximum of 4096 raw events - n int // Number of bytes read with read() - errno error // Syscall errno - ok bool // For poller.wait - ) - - defer close(w.doneResp) - defer close(w.Errors) - defer close(w.Events) - defer unix.Close(w.fd) - defer w.poller.close() - - for { - // See if we have been closed. - if w.isClosed() { - return - } - - ok, errno = w.poller.wait() - if errno != nil { - select { - case w.Errors <- errno: - case <-w.done: - return - } - continue - } - - if !ok { - continue - } - - n, errno = unix.Read(w.fd, buf[:]) - // If a signal interrupted execution, see if we've been asked to close, and try again. - // http://man7.org/linux/man-pages/man7/signal.7.html : - // "Before Linux 3.8, reads from an inotify(7) file descriptor were not restartable" - if errno == unix.EINTR { - continue - } - - // unix.Read might have been woken up by Close. If so, we're done. - if w.isClosed() { - return - } - - if n < unix.SizeofInotifyEvent { - var err error - if n == 0 { - // If EOF is received. This should really never happen. - err = io.EOF - } else if n < 0 { - // If an error occurred while reading. - err = errno - } else { - // Read was too short. - err = errors.New("notify: short read in readEvents()") - } - select { - case w.Errors <- err: - case <-w.done: - return - } - continue - } - - var offset uint32 - // We don't know how many events we just read into the buffer - // While the offset points to at least one whole event... - for offset <= uint32(n-unix.SizeofInotifyEvent) { - // Point "raw" to the event in the buffer - raw := (*unix.InotifyEvent)(unsafe.Pointer(&buf[offset])) - - mask := uint32(raw.Mask) - nameLen := uint32(raw.Len) - - if mask&unix.IN_Q_OVERFLOW != 0 { - select { - case w.Errors <- ErrEventOverflow: - case <-w.done: - return - } - } - - // If the event happened to the watched directory or the watched file, the kernel - // doesn't append the filename to the event, but we would like to always fill the - // the "Name" field with a valid filename. We retrieve the path of the watch from - // the "paths" map. - w.mu.Lock() - name, ok := w.paths[int(raw.Wd)] - // IN_DELETE_SELF occurs when the file/directory being watched is removed. - // This is a sign to clean up the maps, otherwise we are no longer in sync - // with the inotify kernel state which has already deleted the watch - // automatically. - if ok && mask&unix.IN_DELETE_SELF == unix.IN_DELETE_SELF { - delete(w.paths, int(raw.Wd)) - delete(w.watches, name) - } - w.mu.Unlock() - - if nameLen > 0 { - // Point "bytes" at the first byte of the filename - bytes := (*[unix.PathMax]byte)(unsafe.Pointer(&buf[offset+unix.SizeofInotifyEvent]))[:nameLen:nameLen] - // The filename is padded with NULL bytes. TrimRight() gets rid of those. - name += "/" + strings.TrimRight(string(bytes[0:nameLen]), "\000") - } - - event := newEvent(name, mask) - - // Send the events that are not ignored on the events channel - if !event.ignoreLinux(mask) { - select { - case w.Events <- event: - case <-w.done: - return - } - } - - // Move to the next event in the buffer - offset += unix.SizeofInotifyEvent + nameLen - } - } -} - -// Certain types of events can be "ignored" and not sent over the Events -// channel. Such as events marked ignore by the kernel, or MODIFY events -// against files that do not exist. -func (e *Event) ignoreLinux(mask uint32) bool { - // Ignore anything the inotify API says to ignore - if mask&unix.IN_IGNORED == unix.IN_IGNORED { - return true - } - - // If the event is not a DELETE or RENAME, the file must exist. - // Otherwise the event is ignored. - // *Note*: this was put in place because it was seen that a MODIFY - // event was sent after the DELETE. This ignores that MODIFY and - // assumes a DELETE will come or has come if the file doesn't exist. - if !(e.Op&Remove == Remove || e.Op&Rename == Rename) { - _, statErr := os.Lstat(e.Name) - return os.IsNotExist(statErr) - } - return false -} - -// newEvent returns an platform-independent Event based on an inotify mask. -func newEvent(name string, mask uint32) Event { - e := Event{Name: name} - if mask&unix.IN_CREATE == unix.IN_CREATE || mask&unix.IN_MOVED_TO == unix.IN_MOVED_TO { - e.Op |= Create - } - if mask&unix.IN_DELETE_SELF == unix.IN_DELETE_SELF || mask&unix.IN_DELETE == unix.IN_DELETE { - e.Op |= Remove - } - if mask&unix.IN_MODIFY == unix.IN_MODIFY { - e.Op |= Write - } - if mask&unix.IN_MOVE_SELF == unix.IN_MOVE_SELF || mask&unix.IN_MOVED_FROM == unix.IN_MOVED_FROM { - e.Op |= Rename - } - if mask&unix.IN_ATTRIB == unix.IN_ATTRIB { - e.Op |= Chmod - } - return e -} diff --git a/vendor/github.com/fsnotify/fsnotify/inotify_poller.go b/vendor/github.com/fsnotify/fsnotify/inotify_poller.go deleted file mode 100644 index b572a37c3f..0000000000 --- a/vendor/github.com/fsnotify/fsnotify/inotify_poller.go +++ /dev/null @@ -1,187 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build linux -// +build linux - -package fsnotify - -import ( - "errors" - - "golang.org/x/sys/unix" -) - -type fdPoller struct { - fd int // File descriptor (as returned by the inotify_init() syscall) - epfd int // Epoll file descriptor - pipe [2]int // Pipe for waking up -} - -func emptyPoller(fd int) *fdPoller { - poller := new(fdPoller) - poller.fd = fd - poller.epfd = -1 - poller.pipe[0] = -1 - poller.pipe[1] = -1 - return poller -} - -// Create a new inotify poller. -// This creates an inotify handler, and an epoll handler. -func newFdPoller(fd int) (*fdPoller, error) { - var errno error - poller := emptyPoller(fd) - defer func() { - if errno != nil { - poller.close() - } - }() - - // Create epoll fd - poller.epfd, errno = unix.EpollCreate1(unix.EPOLL_CLOEXEC) - if poller.epfd == -1 { - return nil, errno - } - // Create pipe; pipe[0] is the read end, pipe[1] the write end. - errno = unix.Pipe2(poller.pipe[:], unix.O_NONBLOCK|unix.O_CLOEXEC) - if errno != nil { - return nil, errno - } - - // Register inotify fd with epoll - event := unix.EpollEvent{ - Fd: int32(poller.fd), - Events: unix.EPOLLIN, - } - errno = unix.EpollCtl(poller.epfd, unix.EPOLL_CTL_ADD, poller.fd, &event) - if errno != nil { - return nil, errno - } - - // Register pipe fd with epoll - event = unix.EpollEvent{ - Fd: int32(poller.pipe[0]), - Events: unix.EPOLLIN, - } - errno = unix.EpollCtl(poller.epfd, unix.EPOLL_CTL_ADD, poller.pipe[0], &event) - if errno != nil { - return nil, errno - } - - return poller, nil -} - -// Wait using epoll. -// Returns true if something is ready to be read, -// false if there is not. -func (poller *fdPoller) wait() (bool, error) { - // 3 possible events per fd, and 2 fds, makes a maximum of 6 events. - // I don't know whether epoll_wait returns the number of events returned, - // or the total number of events ready. - // I decided to catch both by making the buffer one larger than the maximum. - events := make([]unix.EpollEvent, 7) - for { - n, errno := unix.EpollWait(poller.epfd, events, -1) - if n == -1 { - if errno == unix.EINTR { - continue - } - return false, errno - } - if n == 0 { - // If there are no events, try again. - continue - } - if n > 6 { - // This should never happen. More events were returned than should be possible. - return false, errors.New("epoll_wait returned more events than I know what to do with") - } - ready := events[:n] - epollhup := false - epollerr := false - epollin := false - for _, event := range ready { - if event.Fd == int32(poller.fd) { - if event.Events&unix.EPOLLHUP != 0 { - // This should not happen, but if it does, treat it as a wakeup. - epollhup = true - } - if event.Events&unix.EPOLLERR != 0 { - // If an error is waiting on the file descriptor, we should pretend - // something is ready to read, and let unix.Read pick up the error. - epollerr = true - } - if event.Events&unix.EPOLLIN != 0 { - // There is data to read. - epollin = true - } - } - if event.Fd == int32(poller.pipe[0]) { - if event.Events&unix.EPOLLHUP != 0 { - // Write pipe descriptor was closed, by us. This means we're closing down the - // watcher, and we should wake up. - } - if event.Events&unix.EPOLLERR != 0 { - // If an error is waiting on the pipe file descriptor. - // This is an absolute mystery, and should never ever happen. - return false, errors.New("Error on the pipe descriptor.") - } - if event.Events&unix.EPOLLIN != 0 { - // This is a regular wakeup, so we have to clear the buffer. - err := poller.clearWake() - if err != nil { - return false, err - } - } - } - } - - if epollhup || epollerr || epollin { - return true, nil - } - return false, nil - } -} - -// Close the write end of the poller. -func (poller *fdPoller) wake() error { - buf := make([]byte, 1) - n, errno := unix.Write(poller.pipe[1], buf) - if n == -1 { - if errno == unix.EAGAIN { - // Buffer is full, poller will wake. - return nil - } - return errno - } - return nil -} - -func (poller *fdPoller) clearWake() error { - // You have to be woken up a LOT in order to get to 100! - buf := make([]byte, 100) - n, errno := unix.Read(poller.pipe[0], buf) - if n == -1 { - if errno == unix.EAGAIN { - // Buffer is empty, someone else cleared our wake. - return nil - } - return errno - } - return nil -} - -// Close all poller file descriptors, but not the one passed to it. -func (poller *fdPoller) close() { - if poller.pipe[1] != -1 { - unix.Close(poller.pipe[1]) - } - if poller.pipe[0] != -1 { - unix.Close(poller.pipe[0]) - } - if poller.epfd != -1 { - unix.Close(poller.epfd) - } -} diff --git a/vendor/github.com/fsnotify/fsnotify/kqueue.go b/vendor/github.com/fsnotify/fsnotify/kqueue.go deleted file mode 100644 index 6fb8d8532e..0000000000 --- a/vendor/github.com/fsnotify/fsnotify/kqueue.go +++ /dev/null @@ -1,535 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build freebsd || openbsd || netbsd || dragonfly || darwin -// +build freebsd openbsd netbsd dragonfly darwin - -package fsnotify - -import ( - "errors" - "fmt" - "io/ioutil" - "os" - "path/filepath" - "sync" - "time" - - "golang.org/x/sys/unix" -) - -// Watcher watches a set of files, delivering events to a channel. -type Watcher struct { - Events chan Event - Errors chan error - done chan struct{} // Channel for sending a "quit message" to the reader goroutine - - kq int // File descriptor (as returned by the kqueue() syscall). - - mu sync.Mutex // Protects access to watcher data - watches map[string]int // Map of watched file descriptors (key: path). - externalWatches map[string]bool // Map of watches added by user of the library. - dirFlags map[string]uint32 // Map of watched directories to fflags used in kqueue. - paths map[int]pathInfo // Map file descriptors to path names for processing kqueue events. - fileExists map[string]bool // Keep track of if we know this file exists (to stop duplicate create events). - isClosed bool // Set to true when Close() is first called -} - -type pathInfo struct { - name string - isDir bool -} - -// NewWatcher establishes a new watcher with the underlying OS and begins waiting for events. -func NewWatcher() (*Watcher, error) { - kq, err := kqueue() - if err != nil { - return nil, err - } - - w := &Watcher{ - kq: kq, - watches: make(map[string]int), - dirFlags: make(map[string]uint32), - paths: make(map[int]pathInfo), - fileExists: make(map[string]bool), - externalWatches: make(map[string]bool), - Events: make(chan Event), - Errors: make(chan error), - done: make(chan struct{}), - } - - go w.readEvents() - return w, nil -} - -// Close removes all watches and closes the events channel. -func (w *Watcher) Close() error { - w.mu.Lock() - if w.isClosed { - w.mu.Unlock() - return nil - } - w.isClosed = true - - // copy paths to remove while locked - var pathsToRemove = make([]string, 0, len(w.watches)) - for name := range w.watches { - pathsToRemove = append(pathsToRemove, name) - } - w.mu.Unlock() - // unlock before calling Remove, which also locks - - for _, name := range pathsToRemove { - w.Remove(name) - } - - // send a "quit" message to the reader goroutine - close(w.done) - - return nil -} - -// Add starts watching the named file or directory (non-recursively). -func (w *Watcher) Add(name string) error { - w.mu.Lock() - w.externalWatches[name] = true - w.mu.Unlock() - _, err := w.addWatch(name, noteAllEvents) - return err -} - -// Remove stops watching the the named file or directory (non-recursively). -func (w *Watcher) Remove(name string) error { - name = filepath.Clean(name) - w.mu.Lock() - watchfd, ok := w.watches[name] - w.mu.Unlock() - if !ok { - return fmt.Errorf("can't remove non-existent kevent watch for: %s", name) - } - - const registerRemove = unix.EV_DELETE - if err := register(w.kq, []int{watchfd}, registerRemove, 0); err != nil { - return err - } - - unix.Close(watchfd) - - w.mu.Lock() - isDir := w.paths[watchfd].isDir - delete(w.watches, name) - delete(w.paths, watchfd) - delete(w.dirFlags, name) - w.mu.Unlock() - - // Find all watched paths that are in this directory that are not external. - if isDir { - var pathsToRemove []string - w.mu.Lock() - for _, path := range w.paths { - wdir, _ := filepath.Split(path.name) - if filepath.Clean(wdir) == name { - if !w.externalWatches[path.name] { - pathsToRemove = append(pathsToRemove, path.name) - } - } - } - w.mu.Unlock() - for _, name := range pathsToRemove { - // Since these are internal, not much sense in propagating error - // to the user, as that will just confuse them with an error about - // a path they did not explicitly watch themselves. - w.Remove(name) - } - } - - return nil -} - -// WatchList returns the directories and files that are being monitered. -func (w *Watcher) WatchList() []string { - w.mu.Lock() - defer w.mu.Unlock() - - entries := make([]string, 0, len(w.watches)) - for pathname := range w.watches { - entries = append(entries, pathname) - } - - return entries -} - -// Watch all events (except NOTE_EXTEND, NOTE_LINK, NOTE_REVOKE) -const noteAllEvents = unix.NOTE_DELETE | unix.NOTE_WRITE | unix.NOTE_ATTRIB | unix.NOTE_RENAME - -// keventWaitTime to block on each read from kevent -var keventWaitTime = durationToTimespec(100 * time.Millisecond) - -// addWatch adds name to the watched file set. -// The flags are interpreted as described in kevent(2). -// Returns the real path to the file which was added, if any, which may be different from the one passed in the case of symlinks. -func (w *Watcher) addWatch(name string, flags uint32) (string, error) { - var isDir bool - // Make ./name and name equivalent - name = filepath.Clean(name) - - w.mu.Lock() - if w.isClosed { - w.mu.Unlock() - return "", errors.New("kevent instance already closed") - } - watchfd, alreadyWatching := w.watches[name] - // We already have a watch, but we can still override flags. - if alreadyWatching { - isDir = w.paths[watchfd].isDir - } - w.mu.Unlock() - - if !alreadyWatching { - fi, err := os.Lstat(name) - if err != nil { - return "", err - } - - // Don't watch sockets. - if fi.Mode()&os.ModeSocket == os.ModeSocket { - return "", nil - } - - // Don't watch named pipes. - if fi.Mode()&os.ModeNamedPipe == os.ModeNamedPipe { - return "", nil - } - - // Follow Symlinks - // Unfortunately, Linux can add bogus symlinks to watch list without - // issue, and Windows can't do symlinks period (AFAIK). To maintain - // consistency, we will act like everything is fine. There will simply - // be no file events for broken symlinks. - // Hence the returns of nil on errors. - if fi.Mode()&os.ModeSymlink == os.ModeSymlink { - name, err = filepath.EvalSymlinks(name) - if err != nil { - return "", nil - } - - w.mu.Lock() - _, alreadyWatching = w.watches[name] - w.mu.Unlock() - - if alreadyWatching { - return name, nil - } - - fi, err = os.Lstat(name) - if err != nil { - return "", nil - } - } - - watchfd, err = unix.Open(name, openMode, 0700) - if watchfd == -1 { - return "", err - } - - isDir = fi.IsDir() - } - - const registerAdd = unix.EV_ADD | unix.EV_CLEAR | unix.EV_ENABLE - if err := register(w.kq, []int{watchfd}, registerAdd, flags); err != nil { - unix.Close(watchfd) - return "", err - } - - if !alreadyWatching { - w.mu.Lock() - w.watches[name] = watchfd - w.paths[watchfd] = pathInfo{name: name, isDir: isDir} - w.mu.Unlock() - } - - if isDir { - // Watch the directory if it has not been watched before, - // or if it was watched before, but perhaps only a NOTE_DELETE (watchDirectoryFiles) - w.mu.Lock() - - watchDir := (flags&unix.NOTE_WRITE) == unix.NOTE_WRITE && - (!alreadyWatching || (w.dirFlags[name]&unix.NOTE_WRITE) != unix.NOTE_WRITE) - // Store flags so this watch can be updated later - w.dirFlags[name] = flags - w.mu.Unlock() - - if watchDir { - if err := w.watchDirectoryFiles(name); err != nil { - return "", err - } - } - } - return name, nil -} - -// readEvents reads from kqueue and converts the received kevents into -// Event values that it sends down the Events channel. -func (w *Watcher) readEvents() { - eventBuffer := make([]unix.Kevent_t, 10) - -loop: - for { - // See if there is a message on the "done" channel - select { - case <-w.done: - break loop - default: - } - - // Get new events - kevents, err := read(w.kq, eventBuffer, &keventWaitTime) - // EINTR is okay, the syscall was interrupted before timeout expired. - if err != nil && err != unix.EINTR { - select { - case w.Errors <- err: - case <-w.done: - break loop - } - continue - } - - // Flush the events we received to the Events channel - for len(kevents) > 0 { - kevent := &kevents[0] - watchfd := int(kevent.Ident) - mask := uint32(kevent.Fflags) - w.mu.Lock() - path := w.paths[watchfd] - w.mu.Unlock() - event := newEvent(path.name, mask) - - if path.isDir && !(event.Op&Remove == Remove) { - // Double check to make sure the directory exists. This can happen when - // we do a rm -fr on a recursively watched folders and we receive a - // modification event first but the folder has been deleted and later - // receive the delete event - if _, err := os.Lstat(event.Name); os.IsNotExist(err) { - // mark is as delete event - event.Op |= Remove - } - } - - if event.Op&Rename == Rename || event.Op&Remove == Remove { - w.Remove(event.Name) - w.mu.Lock() - delete(w.fileExists, event.Name) - w.mu.Unlock() - } - - if path.isDir && event.Op&Write == Write && !(event.Op&Remove == Remove) { - w.sendDirectoryChangeEvents(event.Name) - } else { - // Send the event on the Events channel. - select { - case w.Events <- event: - case <-w.done: - break loop - } - } - - if event.Op&Remove == Remove { - // Look for a file that may have overwritten this. - // For example, mv f1 f2 will delete f2, then create f2. - if path.isDir { - fileDir := filepath.Clean(event.Name) - w.mu.Lock() - _, found := w.watches[fileDir] - w.mu.Unlock() - if found { - // make sure the directory exists before we watch for changes. When we - // do a recursive watch and perform rm -fr, the parent directory might - // have gone missing, ignore the missing directory and let the - // upcoming delete event remove the watch from the parent directory. - if _, err := os.Lstat(fileDir); err == nil { - w.sendDirectoryChangeEvents(fileDir) - } - } - } else { - filePath := filepath.Clean(event.Name) - if fileInfo, err := os.Lstat(filePath); err == nil { - w.sendFileCreatedEventIfNew(filePath, fileInfo) - } - } - } - - // Move to next event - kevents = kevents[1:] - } - } - - // cleanup - err := unix.Close(w.kq) - if err != nil { - // only way the previous loop breaks is if w.done was closed so we need to async send to w.Errors. - select { - case w.Errors <- err: - default: - } - } - close(w.Events) - close(w.Errors) -} - -// newEvent returns an platform-independent Event based on kqueue Fflags. -func newEvent(name string, mask uint32) Event { - e := Event{Name: name} - if mask&unix.NOTE_DELETE == unix.NOTE_DELETE { - e.Op |= Remove - } - if mask&unix.NOTE_WRITE == unix.NOTE_WRITE { - e.Op |= Write - } - if mask&unix.NOTE_RENAME == unix.NOTE_RENAME { - e.Op |= Rename - } - if mask&unix.NOTE_ATTRIB == unix.NOTE_ATTRIB { - e.Op |= Chmod - } - return e -} - -func newCreateEvent(name string) Event { - return Event{Name: name, Op: Create} -} - -// watchDirectoryFiles to mimic inotify when adding a watch on a directory -func (w *Watcher) watchDirectoryFiles(dirPath string) error { - // Get all files - files, err := ioutil.ReadDir(dirPath) - if err != nil { - return err - } - - for _, fileInfo := range files { - filePath := filepath.Join(dirPath, fileInfo.Name()) - filePath, err = w.internalWatch(filePath, fileInfo) - if err != nil { - return err - } - - w.mu.Lock() - w.fileExists[filePath] = true - w.mu.Unlock() - } - - return nil -} - -// sendDirectoryEvents searches the directory for newly created files -// and sends them over the event channel. This functionality is to have -// the BSD version of fsnotify match Linux inotify which provides a -// create event for files created in a watched directory. -func (w *Watcher) sendDirectoryChangeEvents(dirPath string) { - // Get all files - files, err := ioutil.ReadDir(dirPath) - if err != nil { - select { - case w.Errors <- err: - case <-w.done: - return - } - } - - // Search for new files - for _, fileInfo := range files { - filePath := filepath.Join(dirPath, fileInfo.Name()) - err := w.sendFileCreatedEventIfNew(filePath, fileInfo) - - if err != nil { - return - } - } -} - -// sendFileCreatedEvent sends a create event if the file isn't already being tracked. -func (w *Watcher) sendFileCreatedEventIfNew(filePath string, fileInfo os.FileInfo) (err error) { - w.mu.Lock() - _, doesExist := w.fileExists[filePath] - w.mu.Unlock() - if !doesExist { - // Send create event - select { - case w.Events <- newCreateEvent(filePath): - case <-w.done: - return - } - } - - // like watchDirectoryFiles (but without doing another ReadDir) - filePath, err = w.internalWatch(filePath, fileInfo) - if err != nil { - return err - } - - w.mu.Lock() - w.fileExists[filePath] = true - w.mu.Unlock() - - return nil -} - -func (w *Watcher) internalWatch(name string, fileInfo os.FileInfo) (string, error) { - if fileInfo.IsDir() { - // mimic Linux providing delete events for subdirectories - // but preserve the flags used if currently watching subdirectory - w.mu.Lock() - flags := w.dirFlags[name] - w.mu.Unlock() - - flags |= unix.NOTE_DELETE | unix.NOTE_RENAME - return w.addWatch(name, flags) - } - - // watch file to mimic Linux inotify - return w.addWatch(name, noteAllEvents) -} - -// kqueue creates a new kernel event queue and returns a descriptor. -func kqueue() (kq int, err error) { - kq, err = unix.Kqueue() - if kq == -1 { - return kq, err - } - return kq, nil -} - -// register events with the queue -func register(kq int, fds []int, flags int, fflags uint32) error { - changes := make([]unix.Kevent_t, len(fds)) - - for i, fd := range fds { - // SetKevent converts int to the platform-specific types: - unix.SetKevent(&changes[i], fd, unix.EVFILT_VNODE, flags) - changes[i].Fflags = fflags - } - - // register the events - success, err := unix.Kevent(kq, changes, nil, nil) - if success == -1 { - return err - } - return nil -} - -// read retrieves pending events, or waits until an event occurs. -// A timeout of nil blocks indefinitely, while 0 polls the queue. -func read(kq int, events []unix.Kevent_t, timeout *unix.Timespec) ([]unix.Kevent_t, error) { - n, err := unix.Kevent(kq, nil, events, timeout) - if err != nil { - return nil, err - } - return events[0:n], nil -} - -// durationToTimespec prepares a timeout value -func durationToTimespec(d time.Duration) unix.Timespec { - return unix.NsecToTimespec(d.Nanoseconds()) -} diff --git a/vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go b/vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go deleted file mode 100644 index 36cc3845b6..0000000000 --- a/vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build freebsd || openbsd || netbsd || dragonfly -// +build freebsd openbsd netbsd dragonfly - -package fsnotify - -import "golang.org/x/sys/unix" - -const openMode = unix.O_NONBLOCK | unix.O_RDONLY | unix.O_CLOEXEC diff --git a/vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go b/vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go deleted file mode 100644 index 98cd8476ff..0000000000 --- a/vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build darwin -// +build darwin - -package fsnotify - -import "golang.org/x/sys/unix" - -// note: this constant is not defined on BSD -const openMode = unix.O_EVTONLY | unix.O_CLOEXEC diff --git a/vendor/github.com/fsnotify/fsnotify/windows.go b/vendor/github.com/fsnotify/fsnotify/windows.go deleted file mode 100644 index 02ce7deb0b..0000000000 --- a/vendor/github.com/fsnotify/fsnotify/windows.go +++ /dev/null @@ -1,586 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build windows -// +build windows - -package fsnotify - -import ( - "errors" - "fmt" - "os" - "path/filepath" - "reflect" - "runtime" - "sync" - "syscall" - "unsafe" -) - -// Watcher watches a set of files, delivering events to a channel. -type Watcher struct { - Events chan Event - Errors chan error - isClosed bool // Set to true when Close() is first called - mu sync.Mutex // Map access - port syscall.Handle // Handle to completion port - watches watchMap // Map of watches (key: i-number) - input chan *input // Inputs to the reader are sent on this channel - quit chan chan<- error -} - -// NewWatcher establishes a new watcher with the underlying OS and begins waiting for events. -func NewWatcher() (*Watcher, error) { - port, e := syscall.CreateIoCompletionPort(syscall.InvalidHandle, 0, 0, 0) - if e != nil { - return nil, os.NewSyscallError("CreateIoCompletionPort", e) - } - w := &Watcher{ - port: port, - watches: make(watchMap), - input: make(chan *input, 1), - Events: make(chan Event, 50), - Errors: make(chan error), - quit: make(chan chan<- error, 1), - } - go w.readEvents() - return w, nil -} - -// Close removes all watches and closes the events channel. -func (w *Watcher) Close() error { - if w.isClosed { - return nil - } - w.isClosed = true - - // Send "quit" message to the reader goroutine - ch := make(chan error) - w.quit <- ch - if err := w.wakeupReader(); err != nil { - return err - } - return <-ch -} - -// Add starts watching the named file or directory (non-recursively). -func (w *Watcher) Add(name string) error { - if w.isClosed { - return errors.New("watcher already closed") - } - in := &input{ - op: opAddWatch, - path: filepath.Clean(name), - flags: sysFSALLEVENTS, - reply: make(chan error), - } - w.input <- in - if err := w.wakeupReader(); err != nil { - return err - } - return <-in.reply -} - -// Remove stops watching the the named file or directory (non-recursively). -func (w *Watcher) Remove(name string) error { - in := &input{ - op: opRemoveWatch, - path: filepath.Clean(name), - reply: make(chan error), - } - w.input <- in - if err := w.wakeupReader(); err != nil { - return err - } - return <-in.reply -} - -// WatchList returns the directories and files that are being monitered. -func (w *Watcher) WatchList() []string { - w.mu.Lock() - defer w.mu.Unlock() - - entries := make([]string, 0, len(w.watches)) - for _, entry := range w.watches { - for _, watchEntry := range entry { - entries = append(entries, watchEntry.path) - } - } - - return entries -} - -const ( - // Options for AddWatch - sysFSONESHOT = 0x80000000 - sysFSONLYDIR = 0x1000000 - - // Events - sysFSACCESS = 0x1 - sysFSALLEVENTS = 0xfff - sysFSATTRIB = 0x4 - sysFSCLOSE = 0x18 - sysFSCREATE = 0x100 - sysFSDELETE = 0x200 - sysFSDELETESELF = 0x400 - sysFSMODIFY = 0x2 - sysFSMOVE = 0xc0 - sysFSMOVEDFROM = 0x40 - sysFSMOVEDTO = 0x80 - sysFSMOVESELF = 0x800 - - // Special events - sysFSIGNORED = 0x8000 - sysFSQOVERFLOW = 0x4000 -) - -func newEvent(name string, mask uint32) Event { - e := Event{Name: name} - if mask&sysFSCREATE == sysFSCREATE || mask&sysFSMOVEDTO == sysFSMOVEDTO { - e.Op |= Create - } - if mask&sysFSDELETE == sysFSDELETE || mask&sysFSDELETESELF == sysFSDELETESELF { - e.Op |= Remove - } - if mask&sysFSMODIFY == sysFSMODIFY { - e.Op |= Write - } - if mask&sysFSMOVE == sysFSMOVE || mask&sysFSMOVESELF == sysFSMOVESELF || mask&sysFSMOVEDFROM == sysFSMOVEDFROM { - e.Op |= Rename - } - if mask&sysFSATTRIB == sysFSATTRIB { - e.Op |= Chmod - } - return e -} - -const ( - opAddWatch = iota - opRemoveWatch -) - -const ( - provisional uint64 = 1 << (32 + iota) -) - -type input struct { - op int - path string - flags uint32 - reply chan error -} - -type inode struct { - handle syscall.Handle - volume uint32 - index uint64 -} - -type watch struct { - ov syscall.Overlapped - ino *inode // i-number - path string // Directory path - mask uint64 // Directory itself is being watched with these notify flags - names map[string]uint64 // Map of names being watched and their notify flags - rename string // Remembers the old name while renaming a file - buf [4096]byte -} - -type indexMap map[uint64]*watch -type watchMap map[uint32]indexMap - -func (w *Watcher) wakeupReader() error { - e := syscall.PostQueuedCompletionStatus(w.port, 0, 0, nil) - if e != nil { - return os.NewSyscallError("PostQueuedCompletionStatus", e) - } - return nil -} - -func getDir(pathname string) (dir string, err error) { - attr, e := syscall.GetFileAttributes(syscall.StringToUTF16Ptr(pathname)) - if e != nil { - return "", os.NewSyscallError("GetFileAttributes", e) - } - if attr&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 { - dir = pathname - } else { - dir, _ = filepath.Split(pathname) - dir = filepath.Clean(dir) - } - return -} - -func getIno(path string) (ino *inode, err error) { - h, e := syscall.CreateFile(syscall.StringToUTF16Ptr(path), - syscall.FILE_LIST_DIRECTORY, - syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE, - nil, syscall.OPEN_EXISTING, - syscall.FILE_FLAG_BACKUP_SEMANTICS|syscall.FILE_FLAG_OVERLAPPED, 0) - if e != nil { - return nil, os.NewSyscallError("CreateFile", e) - } - var fi syscall.ByHandleFileInformation - if e = syscall.GetFileInformationByHandle(h, &fi); e != nil { - syscall.CloseHandle(h) - return nil, os.NewSyscallError("GetFileInformationByHandle", e) - } - ino = &inode{ - handle: h, - volume: fi.VolumeSerialNumber, - index: uint64(fi.FileIndexHigh)<<32 | uint64(fi.FileIndexLow), - } - return ino, nil -} - -// Must run within the I/O thread. -func (m watchMap) get(ino *inode) *watch { - if i := m[ino.volume]; i != nil { - return i[ino.index] - } - return nil -} - -// Must run within the I/O thread. -func (m watchMap) set(ino *inode, watch *watch) { - i := m[ino.volume] - if i == nil { - i = make(indexMap) - m[ino.volume] = i - } - i[ino.index] = watch -} - -// Must run within the I/O thread. -func (w *Watcher) addWatch(pathname string, flags uint64) error { - dir, err := getDir(pathname) - if err != nil { - return err - } - if flags&sysFSONLYDIR != 0 && pathname != dir { - return nil - } - ino, err := getIno(dir) - if err != nil { - return err - } - w.mu.Lock() - watchEntry := w.watches.get(ino) - w.mu.Unlock() - if watchEntry == nil { - if _, e := syscall.CreateIoCompletionPort(ino.handle, w.port, 0, 0); e != nil { - syscall.CloseHandle(ino.handle) - return os.NewSyscallError("CreateIoCompletionPort", e) - } - watchEntry = &watch{ - ino: ino, - path: dir, - names: make(map[string]uint64), - } - w.mu.Lock() - w.watches.set(ino, watchEntry) - w.mu.Unlock() - flags |= provisional - } else { - syscall.CloseHandle(ino.handle) - } - if pathname == dir { - watchEntry.mask |= flags - } else { - watchEntry.names[filepath.Base(pathname)] |= flags - } - if err = w.startRead(watchEntry); err != nil { - return err - } - if pathname == dir { - watchEntry.mask &= ^provisional - } else { - watchEntry.names[filepath.Base(pathname)] &= ^provisional - } - return nil -} - -// Must run within the I/O thread. -func (w *Watcher) remWatch(pathname string) error { - dir, err := getDir(pathname) - if err != nil { - return err - } - ino, err := getIno(dir) - if err != nil { - return err - } - w.mu.Lock() - watch := w.watches.get(ino) - w.mu.Unlock() - if watch == nil { - return fmt.Errorf("can't remove non-existent watch for: %s", pathname) - } - if pathname == dir { - w.sendEvent(watch.path, watch.mask&sysFSIGNORED) - watch.mask = 0 - } else { - name := filepath.Base(pathname) - w.sendEvent(filepath.Join(watch.path, name), watch.names[name]&sysFSIGNORED) - delete(watch.names, name) - } - return w.startRead(watch) -} - -// Must run within the I/O thread. -func (w *Watcher) deleteWatch(watch *watch) { - for name, mask := range watch.names { - if mask&provisional == 0 { - w.sendEvent(filepath.Join(watch.path, name), mask&sysFSIGNORED) - } - delete(watch.names, name) - } - if watch.mask != 0 { - if watch.mask&provisional == 0 { - w.sendEvent(watch.path, watch.mask&sysFSIGNORED) - } - watch.mask = 0 - } -} - -// Must run within the I/O thread. -func (w *Watcher) startRead(watch *watch) error { - if e := syscall.CancelIo(watch.ino.handle); e != nil { - w.Errors <- os.NewSyscallError("CancelIo", e) - w.deleteWatch(watch) - } - mask := toWindowsFlags(watch.mask) - for _, m := range watch.names { - mask |= toWindowsFlags(m) - } - if mask == 0 { - if e := syscall.CloseHandle(watch.ino.handle); e != nil { - w.Errors <- os.NewSyscallError("CloseHandle", e) - } - w.mu.Lock() - delete(w.watches[watch.ino.volume], watch.ino.index) - w.mu.Unlock() - return nil - } - e := syscall.ReadDirectoryChanges(watch.ino.handle, &watch.buf[0], - uint32(unsafe.Sizeof(watch.buf)), false, mask, nil, &watch.ov, 0) - if e != nil { - err := os.NewSyscallError("ReadDirectoryChanges", e) - if e == syscall.ERROR_ACCESS_DENIED && watch.mask&provisional == 0 { - // Watched directory was probably removed - if w.sendEvent(watch.path, watch.mask&sysFSDELETESELF) { - if watch.mask&sysFSONESHOT != 0 { - watch.mask = 0 - } - } - err = nil - } - w.deleteWatch(watch) - w.startRead(watch) - return err - } - return nil -} - -// readEvents reads from the I/O completion port, converts the -// received events into Event objects and sends them via the Events channel. -// Entry point to the I/O thread. -func (w *Watcher) readEvents() { - var ( - n, key uint32 - ov *syscall.Overlapped - ) - runtime.LockOSThread() - - for { - e := syscall.GetQueuedCompletionStatus(w.port, &n, &key, &ov, syscall.INFINITE) - watch := (*watch)(unsafe.Pointer(ov)) - - if watch == nil { - select { - case ch := <-w.quit: - w.mu.Lock() - var indexes []indexMap - for _, index := range w.watches { - indexes = append(indexes, index) - } - w.mu.Unlock() - for _, index := range indexes { - for _, watch := range index { - w.deleteWatch(watch) - w.startRead(watch) - } - } - var err error - if e := syscall.CloseHandle(w.port); e != nil { - err = os.NewSyscallError("CloseHandle", e) - } - close(w.Events) - close(w.Errors) - ch <- err - return - case in := <-w.input: - switch in.op { - case opAddWatch: - in.reply <- w.addWatch(in.path, uint64(in.flags)) - case opRemoveWatch: - in.reply <- w.remWatch(in.path) - } - default: - } - continue - } - - switch e { - case syscall.ERROR_MORE_DATA: - if watch == nil { - w.Errors <- errors.New("ERROR_MORE_DATA has unexpectedly null lpOverlapped buffer") - } else { - // The i/o succeeded but the buffer is full. - // In theory we should be building up a full packet. - // In practice we can get away with just carrying on. - n = uint32(unsafe.Sizeof(watch.buf)) - } - case syscall.ERROR_ACCESS_DENIED: - // Watched directory was probably removed - w.sendEvent(watch.path, watch.mask&sysFSDELETESELF) - w.deleteWatch(watch) - w.startRead(watch) - continue - case syscall.ERROR_OPERATION_ABORTED: - // CancelIo was called on this handle - continue - default: - w.Errors <- os.NewSyscallError("GetQueuedCompletionPort", e) - continue - case nil: - } - - var offset uint32 - for { - if n == 0 { - w.Events <- newEvent("", sysFSQOVERFLOW) - w.Errors <- errors.New("short read in readEvents()") - break - } - - // Point "raw" to the event in the buffer - raw := (*syscall.FileNotifyInformation)(unsafe.Pointer(&watch.buf[offset])) - // TODO: Consider using unsafe.Slice that is available from go1.17 - // https://stackoverflow.com/questions/51187973/how-to-create-an-array-or-a-slice-from-an-array-unsafe-pointer-in-golang - // instead of using a fixed syscall.MAX_PATH buf, we create a buf that is the size of the path name - size := int(raw.FileNameLength / 2) - var buf []uint16 - sh := (*reflect.SliceHeader)(unsafe.Pointer(&buf)) - sh.Data = uintptr(unsafe.Pointer(&raw.FileName)) - sh.Len = size - sh.Cap = size - name := syscall.UTF16ToString(buf) - fullname := filepath.Join(watch.path, name) - - var mask uint64 - switch raw.Action { - case syscall.FILE_ACTION_REMOVED: - mask = sysFSDELETESELF - case syscall.FILE_ACTION_MODIFIED: - mask = sysFSMODIFY - case syscall.FILE_ACTION_RENAMED_OLD_NAME: - watch.rename = name - case syscall.FILE_ACTION_RENAMED_NEW_NAME: - if watch.names[watch.rename] != 0 { - watch.names[name] |= watch.names[watch.rename] - delete(watch.names, watch.rename) - mask = sysFSMOVESELF - } - } - - sendNameEvent := func() { - if w.sendEvent(fullname, watch.names[name]&mask) { - if watch.names[name]&sysFSONESHOT != 0 { - delete(watch.names, name) - } - } - } - if raw.Action != syscall.FILE_ACTION_RENAMED_NEW_NAME { - sendNameEvent() - } - if raw.Action == syscall.FILE_ACTION_REMOVED { - w.sendEvent(fullname, watch.names[name]&sysFSIGNORED) - delete(watch.names, name) - } - if w.sendEvent(fullname, watch.mask&toFSnotifyFlags(raw.Action)) { - if watch.mask&sysFSONESHOT != 0 { - watch.mask = 0 - } - } - if raw.Action == syscall.FILE_ACTION_RENAMED_NEW_NAME { - fullname = filepath.Join(watch.path, watch.rename) - sendNameEvent() - } - - // Move to the next event in the buffer - if raw.NextEntryOffset == 0 { - break - } - offset += raw.NextEntryOffset - - // Error! - if offset >= n { - w.Errors <- errors.New("Windows system assumed buffer larger than it is, events have likely been missed.") - break - } - } - - if err := w.startRead(watch); err != nil { - w.Errors <- err - } - } -} - -func (w *Watcher) sendEvent(name string, mask uint64) bool { - if mask == 0 { - return false - } - event := newEvent(name, uint32(mask)) - select { - case ch := <-w.quit: - w.quit <- ch - case w.Events <- event: - } - return true -} - -func toWindowsFlags(mask uint64) uint32 { - var m uint32 - if mask&sysFSACCESS != 0 { - m |= syscall.FILE_NOTIFY_CHANGE_LAST_ACCESS - } - if mask&sysFSMODIFY != 0 { - m |= syscall.FILE_NOTIFY_CHANGE_LAST_WRITE - } - if mask&sysFSATTRIB != 0 { - m |= syscall.FILE_NOTIFY_CHANGE_ATTRIBUTES - } - if mask&(sysFSMOVE|sysFSCREATE|sysFSDELETE) != 0 { - m |= syscall.FILE_NOTIFY_CHANGE_FILE_NAME | syscall.FILE_NOTIFY_CHANGE_DIR_NAME - } - return m -} - -func toFSnotifyFlags(action uint32) uint64 { - switch action { - case syscall.FILE_ACTION_ADDED: - return sysFSCREATE - case syscall.FILE_ACTION_REMOVED: - return sysFSDELETE - case syscall.FILE_ACTION_MODIFIED: - return sysFSMODIFY - case syscall.FILE_ACTION_RENAMED_OLD_NAME: - return sysFSMOVEDFROM - case syscall.FILE_ACTION_RENAMED_NEW_NAME: - return sysFSMOVEDTO - } - return 0 -} diff --git a/vendor/github.com/fzipp/gocyclo/CHANGELOG.md b/vendor/github.com/fzipp/gocyclo/CHANGELOG.md deleted file mode 100644 index c9bedfb3b0..0000000000 --- a/vendor/github.com/fzipp/gocyclo/CHANGELOG.md +++ /dev/null @@ -1,58 +0,0 @@ -# Changelog -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## [0.6.0] - 2022-06-15 -### Changed -- Breaking: remove meaningless `-total` and `-total-short` options - -## [0.5.1] - 2022-04-06 -### Fixed -- Don't skip directories `.` and `..` - -## [0.5.0] - 2022-03-22 -### Changed -- Ignore `vendor` and `testdata` directories and directories with names - that begin with `.` or `_` - -## [0.4.0] - 2021-12-19 -### Added -- Support method receivers with type parameters introduced in Go 1.18 - -### Changed -- Use more efficient filepath.WalkDir instead of filepath.Walk - -## [0.3.1] - 2020-10-20 -### Added -- Test coverage - -### Fixed -- Fix cyclomatic complexity for function literals (base complexity of 1 was missing) - -## [0.3.0] - 2020-10-17 -### Added -- New `-avg-short` and `-total-short` options for printing average and total cyclomatic complexities without label -- Export the `AnalyzeASTFile` function in package API -- Doc comments for exported functions and types - -### Fixed -- Ignore `default` cases - -## [0.2.0] - 2020-10-17 -### Added -- Support for gocyclo as a package -- Support for ignoring of individual functions via a new `gocyclo:ignore` directive -- New `-total` option to compute total cyclomatic complexity -- New `-ignore` option to ignore files matching a regular expression -- Analysis of function literals at declaration level - -### Changed -- Breaking: installation changed to `go get github.com/fzipp/gocyclo/cmd/gocyclo` - -## [0.1.0] - 2020-10-17 - -### Added -- `go.mod` file; beginning of versioning - diff --git a/vendor/github.com/fzipp/gocyclo/CONTRIBUTORS b/vendor/github.com/fzipp/gocyclo/CONTRIBUTORS deleted file mode 100644 index 1c09f1a06a..0000000000 --- a/vendor/github.com/fzipp/gocyclo/CONTRIBUTORS +++ /dev/null @@ -1,7 +0,0 @@ -# Names should be added to this file like so: -# Name - -# Please keep the list sorted. - -Frederik Zipp -Harshavardhana diff --git a/vendor/github.com/fzipp/gocyclo/LICENSE b/vendor/github.com/fzipp/gocyclo/LICENSE deleted file mode 100644 index 45f88d6cb3..0000000000 --- a/vendor/github.com/fzipp/gocyclo/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2013 Frederik Zipp. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of the copyright owner nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/fzipp/gocyclo/README.md b/vendor/github.com/fzipp/gocyclo/README.md deleted file mode 100644 index d357b8ef71..0000000000 --- a/vendor/github.com/fzipp/gocyclo/README.md +++ /dev/null @@ -1,106 +0,0 @@ -# gocyclo - -[![PkgGoDev](https://pkg.go.dev/badge/github.com/fzipp/gocyclo)](https://pkg.go.dev/github.com/fzipp/gocyclo) -![Build Status](https://github.com/fzipp/gocyclo/workflows/build/badge.svg) -[![Go Report Card](https://goreportcard.com/badge/github.com/fzipp/gocyclo)](https://goreportcard.com/report/github.com/fzipp/gocyclo) - -Gocyclo calculates -[cyclomatic complexities](https://en.wikipedia.org/wiki/Cyclomatic_complexity) -of functions in Go source code. - -Cyclomatic complexity is a -[code quality metric](https://en.wikipedia.org/wiki/Software_metric) -which can be used to identify code that needs refactoring. -It measures the number of linearly independent paths through a function's -source code. - -The cyclomatic complexity of a function is calculated according to the -following rules: - -``` - 1 is the base complexity of a function -+1 for each 'if', 'for', 'case', '&&' or '||' -``` - -A function with a higher cyclomatic complexity requires more test cases to -cover all possible paths and is potentially harder to understand. The -complexity can be reduced by applying common refactoring techniques that lead -to smaller functions. - -## Installation - -To install the `gocyclo` command, run - -``` -$ go install github.com/fzipp/gocyclo/cmd/gocyclo@latest -``` - -and put the resulting binary in one of your PATH directories if -`$GOPATH/bin` isn't already in your PATH. - -## Usage - -``` -Calculate cyclomatic complexities of Go functions. -Usage: - gocyclo [flags] ... - -Flags: - -over N show functions with complexity > N only and - return exit code 1 if the set is non-empty - -top N show the top N most complex functions only - -avg, -avg-short show the average complexity over all functions; - the short option prints the value without a label - -ignore REGEX exclude files matching the given regular expression - -The output fields for each line are: - -``` - -## Examples - -``` -$ gocyclo . -$ gocyclo main.go -$ gocyclo -top 10 src/ -$ gocyclo -over 25 docker -$ gocyclo -avg . -$ gocyclo -top 20 -ignore "_test|Godeps|vendor/" . -$ gocyclo -over 3 -avg gocyclo/ -``` - -Example output: - -``` -9 gocyclo (*complexityVisitor).Visit complexity.go:30:1 -8 main main cmd/gocyclo/main.go:53:1 -7 gocyclo (*fileAnalyzer).analyzeDecl analyze.go:96:1 -4 gocyclo Analyze analyze.go:24:1 -4 gocyclo parseDirectives directives.go:27:1 -4 gocyclo (Stats).SortAndFilter stats.go:52:1 -Average: 2.72 -``` - -Note that the average is calculated over all analyzed functions, -not just the printed ones. - -### Ignoring individual functions - -Individual functions can be ignored with a `gocyclo:ignore` directive: - -``` -//gocyclo:ignore -func f1() { - // ... -} - -//gocyclo:ignore -var f2 = func() { - // ... -} -``` - -## License - -This project is free and open source software licensed under the -[BSD 3-Clause License](LICENSE). diff --git a/vendor/github.com/fzipp/gocyclo/analyze.go b/vendor/github.com/fzipp/gocyclo/analyze.go deleted file mode 100644 index 2d8bcff257..0000000000 --- a/vendor/github.com/fzipp/gocyclo/analyze.go +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright 2020 Frederik Zipp. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package gocyclo - -import ( - "fmt" - "go/ast" - "go/parser" - "go/token" - "io/fs" - "log" - "os" - "path/filepath" - "regexp" - "strings" -) - -// Analyze calculates the cyclomatic complexities of the functions and methods -// in the Go source code files in the given paths. If a path is a directory -// all Go files under that directory are analyzed recursively. -// Files with paths matching the 'ignore' regular expressions are skipped. -// The 'ignore' parameter can be nil, meaning that no files are skipped. -func Analyze(paths []string, ignore *regexp.Regexp) Stats { - var stats Stats - for _, path := range paths { - info, err := os.Stat(path) - if err != nil { - log.Printf("could not get file info for path %q: %s\n", path, err) - continue - } - if info.IsDir() { - stats = analyzeDir(path, ignore, stats) - } else { - stats = analyzeFile(path, ignore, stats) - } - } - return stats -} - -func analyzeDir(dirname string, ignore *regexp.Regexp, stats Stats) Stats { - filepath.WalkDir(dirname, func(path string, entry fs.DirEntry, err error) error { - if isSkipDir(entry) { - return filepath.SkipDir - } - if err == nil && isGoFile(entry) { - stats = analyzeFile(path, ignore, stats) - } - return err - }) - return stats -} - -var skipDirs = map[string]bool{ - "testdata": true, - "vendor": true, -} - -func isSkipDir(entry fs.DirEntry) bool { - return entry.IsDir() && (skipDirs[entry.Name()] || - (strings.HasPrefix(entry.Name(), ".") && entry.Name() != "." && entry.Name() != "..") || - strings.HasPrefix(entry.Name(), "_")) -} - -func isGoFile(entry fs.DirEntry) bool { - return !entry.IsDir() && strings.HasSuffix(entry.Name(), ".go") -} - -func analyzeFile(path string, ignore *regexp.Regexp, stats Stats) Stats { - if isIgnored(path, ignore) { - return stats - } - fset := token.NewFileSet() - f, err := parser.ParseFile(fset, path, nil, parser.ParseComments) - if err != nil { - log.Fatal(err) - } - return AnalyzeASTFile(f, fset, stats) -} - -func isIgnored(path string, ignore *regexp.Regexp) bool { - return ignore != nil && ignore.MatchString(path) -} - -// AnalyzeASTFile calculates the cyclomatic complexities of the functions -// and methods in the abstract syntax tree (AST) of a parsed Go file and -// appends the results to the given Stats slice. -func AnalyzeASTFile(f *ast.File, fs *token.FileSet, s Stats) Stats { - analyzer := &fileAnalyzer{ - file: f, - fileSet: fs, - stats: s, - } - return analyzer.analyze() -} - -type fileAnalyzer struct { - file *ast.File - fileSet *token.FileSet - stats Stats -} - -func (a *fileAnalyzer) analyze() Stats { - for _, decl := range a.file.Decls { - a.analyzeDecl(decl) - } - return a.stats -} - -func (a *fileAnalyzer) analyzeDecl(d ast.Decl) { - switch decl := d.(type) { - case *ast.FuncDecl: - a.addStatIfNotIgnored(decl, funcName(decl), decl.Doc) - case *ast.GenDecl: - for _, spec := range decl.Specs { - valueSpec, ok := spec.(*ast.ValueSpec) - if !ok { - continue - } - for _, value := range valueSpec.Values { - funcLit, ok := value.(*ast.FuncLit) - if !ok { - continue - } - a.addStatIfNotIgnored(funcLit, valueSpec.Names[0].Name, decl.Doc) - } - } - } -} - -func (a *fileAnalyzer) addStatIfNotIgnored(node ast.Node, funcName string, doc *ast.CommentGroup) { - if parseDirectives(doc).HasIgnore() { - return - } - a.stats = append(a.stats, Stat{ - PkgName: a.file.Name.Name, - FuncName: funcName, - Complexity: Complexity(node), - Pos: a.fileSet.Position(node.Pos()), - }) -} - -// funcName returns the name representation of a function or method: -// "(Type).Name" for methods or simply "Name" for functions. -func funcName(fn *ast.FuncDecl) string { - if fn.Recv != nil { - if fn.Recv.NumFields() > 0 { - typ := fn.Recv.List[0].Type - return fmt.Sprintf("(%s).%s", recvString(typ), fn.Name) - } - } - return fn.Name.Name -} diff --git a/vendor/github.com/fzipp/gocyclo/complexity.go b/vendor/github.com/fzipp/gocyclo/complexity.go deleted file mode 100644 index 65f5077e82..0000000000 --- a/vendor/github.com/fzipp/gocyclo/complexity.go +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2020 Frederik Zipp. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package gocyclo calculates the cyclomatic complexities of functions and -// methods in Go source code. -package gocyclo - -import ( - "go/ast" - "go/token" -) - -// Complexity calculates the cyclomatic complexity of a function. -// The 'fn' node is either a *ast.FuncDecl or a *ast.FuncLit. -func Complexity(fn ast.Node) int { - v := complexityVisitor{ - complexity: 1, - } - ast.Walk(&v, fn) - return v.complexity -} - -type complexityVisitor struct { - // complexity is the cyclomatic complexity - complexity int -} - -// Visit implements the ast.Visitor interface. -func (v *complexityVisitor) Visit(n ast.Node) ast.Visitor { - switch n := n.(type) { - case *ast.IfStmt, *ast.ForStmt, *ast.RangeStmt: - v.complexity++ - case *ast.CaseClause: - if n.List != nil { // ignore default case - v.complexity++ - } - case *ast.CommClause: - if n.Comm != nil { // ignore default case - v.complexity++ - } - case *ast.BinaryExpr: - if n.Op == token.LAND || n.Op == token.LOR { - v.complexity++ - } - } - return v -} diff --git a/vendor/github.com/fzipp/gocyclo/directives.go b/vendor/github.com/fzipp/gocyclo/directives.go deleted file mode 100644 index b4ee3c4488..0000000000 --- a/vendor/github.com/fzipp/gocyclo/directives.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2020 Frederik Zipp. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package gocyclo - -import ( - "go/ast" - "strings" -) - -type directives []string - -func (ds directives) HasIgnore() bool { - return ds.isPresent("ignore") -} - -func (ds directives) isPresent(name string) bool { - for _, d := range ds { - if d == name { - return true - } - } - return false -} - -func parseDirectives(doc *ast.CommentGroup) directives { - if doc == nil { - return directives{} - } - const prefix = "//gocyclo:" - var ds directives - for _, comment := range doc.List { - if strings.HasPrefix(comment.Text, prefix) { - ds = append(ds, strings.TrimSpace(strings.TrimPrefix(comment.Text, prefix))) - } - } - return ds -} diff --git a/vendor/github.com/fzipp/gocyclo/recv.go b/vendor/github.com/fzipp/gocyclo/recv.go deleted file mode 100644 index a5c82fef5a..0000000000 --- a/vendor/github.com/fzipp/gocyclo/recv.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2021 Frederik Zipp. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build go1.18 -// +build go1.18 - -package gocyclo - -import "go/ast" - -// recvString returns a string representation of recv of the -// form "T", "*T", or "BADRECV" (if not a proper receiver type). -func recvString(recv ast.Expr) string { - switch t := recv.(type) { - case *ast.Ident: - return t.Name - case *ast.StarExpr: - return "*" + recvString(t.X) - case *ast.IndexExpr: - return recvString(t.X) - case *ast.IndexListExpr: - return recvString(t.X) - } - return "BADRECV" -} diff --git a/vendor/github.com/fzipp/gocyclo/recv_pre118.go b/vendor/github.com/fzipp/gocyclo/recv_pre118.go deleted file mode 100644 index 2fe2d0cdbd..0000000000 --- a/vendor/github.com/fzipp/gocyclo/recv_pre118.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2021 Frederik Zipp. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !go1.18 -// +build !go1.18 - -package gocyclo - -import "go/ast" - -// recvString returns a string representation of recv of the -// form "T", "*T", or "BADRECV" (if not a proper receiver type). -func recvString(recv ast.Expr) string { - switch t := recv.(type) { - case *ast.Ident: - return t.Name - case *ast.StarExpr: - return "*" + recvString(t.X) - case *ast.IndexExpr: - return recvString(t.X) - } - return "BADRECV" -} diff --git a/vendor/github.com/fzipp/gocyclo/stats.go b/vendor/github.com/fzipp/gocyclo/stats.go deleted file mode 100644 index 0a377e4b68..0000000000 --- a/vendor/github.com/fzipp/gocyclo/stats.go +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2020 Frederik Zipp. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package gocyclo - -import ( - "fmt" - "go/token" - "sort" -) - -// Stat holds the cyclomatic complexity of a function, along with its package -// and and function name and its position in the source code. -type Stat struct { - PkgName string - FuncName string - Complexity int - Pos token.Position -} - -// String formats the cyclomatic complexity information of a function in -// the following format: " " -func (s Stat) String() string { - return fmt.Sprintf("%d %s %s %s", s.Complexity, s.PkgName, s.FuncName, s.Pos) -} - -// Stats hold the cyclomatic complexities of many functions. -type Stats []Stat - -// AverageComplexity calculates the average cyclomatic complexity of the -// cyclomatic complexities in s. -func (s Stats) AverageComplexity() float64 { - return float64(s.TotalComplexity()) / float64(len(s)) -} - -// TotalComplexity calculates the total sum of all cyclomatic -// complexities in s. -func (s Stats) TotalComplexity() uint64 { - total := uint64(0) - for _, stat := range s { - total += uint64(stat.Complexity) - } - return total -} - -// SortAndFilter sorts the cyclomatic complexities in s in descending order -// and returns a slice of s limited to the 'top' N entries with a cyclomatic -// complexity greater than 'over'. If 'top' is negative, i.e. -1, it does -// not limit the result. If 'over' is <= 0 it does not limit the result either, -// because a function has a base cyclomatic complexity of at least 1. -func (s Stats) SortAndFilter(top, over int) Stats { - result := make(Stats, len(s)) - copy(result, s) - sort.Stable(byComplexityDesc(result)) - for i, stat := range result { - if i == top { - return result[:i] - } - if stat.Complexity <= over { - return result[:i] - } - } - return result -} - -type byComplexityDesc Stats - -func (s byComplexityDesc) Len() int { return len(s) } -func (s byComplexityDesc) Swap(i, j int) { s[i], s[j] = s[j], s[i] } -func (s byComplexityDesc) Less(i, j int) bool { - return s[i].Complexity >= s[j].Complexity -} diff --git a/vendor/github.com/ghostiam/protogetter/.goreleaser.yaml b/vendor/github.com/ghostiam/protogetter/.goreleaser.yaml deleted file mode 100644 index cc5d4cffb9..0000000000 --- a/vendor/github.com/ghostiam/protogetter/.goreleaser.yaml +++ /dev/null @@ -1,25 +0,0 @@ -version: 2 -before: - hooks: - - go mod tidy -builds: - - id: protogetter - main: ./cmd/protogetter - binary: protogetter - env: - - CGO_ENABLED=0 - goos: - - linux - - windows - - darwin -checksum: - name_template: 'checksums.txt' -snapshot: - name_template: "{{ incpatch .Version }}-next" -changelog: - sort: asc - filters: - exclude: - - '^docs:' - - '^test:' - - '^ci:' diff --git a/vendor/github.com/ghostiam/protogetter/LICENSE b/vendor/github.com/ghostiam/protogetter/LICENSE deleted file mode 100644 index b4449661b7..0000000000 --- a/vendor/github.com/ghostiam/protogetter/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 Vladislav Fursov (GhostIAm) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/vendor/github.com/ghostiam/protogetter/Makefile b/vendor/github.com/ghostiam/protogetter/Makefile deleted file mode 100644 index 4c2a62af18..0000000000 --- a/vendor/github.com/ghostiam/protogetter/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -.PHONY: test -test: - $(MAKE) -C testdata vendor - go test -v ./... - -.PHONY: install -install: - go install ./cmd/protogetter - @echo "Installed in $(shell which protogetter)" diff --git a/vendor/github.com/ghostiam/protogetter/README.md b/vendor/github.com/ghostiam/protogetter/README.md deleted file mode 100644 index c033e9597f..0000000000 --- a/vendor/github.com/ghostiam/protogetter/README.md +++ /dev/null @@ -1,73 +0,0 @@ -# Protogetter -Welcome to the Protogetter project! - -## Overview -Protogetter is a linter developed specifically for Go programmers working with nested `protobuf` types.\ -It's designed to aid developers in preventing `invalid memory address or nil pointer dereference` errors arising from direct access of nested `protobuf` fields. - -When working with `protobuf`, it's quite common to have complex structures where a message field is contained within another message, which itself can be part of another message, and so on. -If these fields are accessed directly and some field in the call chain will not be initialized, it can result in application panic. - -Protogetter addresses this issue by suggesting use of getter methods for field access. - -## How does it work? -Protogetter analyzes your Go code and helps detect direct `protobuf` field accesses that could give rise to panic.\ -The linter suggests using getters: -```go -m.GetFoo().GetBar().GetBaz() -``` -instead of direct field access: -```go -m.Foo.Bar.Baz -``` - -And you will then only need to perform a nil check after the final call: -```go -if m.GetFoo().GetBar().GetBaz() != nil { - // Do something with m.GetFoo().GetBar().GetBaz() -} -``` -instead of: -```go -if m.Foo != nil { - if m.Foo.Bar != nil { - if m.Foo.Bar.Baz != nil { - // Do something with m.Foo.Bar.Baz - } - } -} -``` - -or use zero values: - -```go -// If one of the methods returns `nil` we will receive 0 instead of panic. -v := m.GetFoo().GetBar().GetBaz().GetInt() -``` - -instead of panic: - -```go -// If at least one structure in the chains is not initialized, we will get a panic. -v := m.Foo.Bar.Baz.Int -``` - -which simplifies the code and makes it more reliable. - -## Installation - -```bash -go install github.com/ghostiam/protogetter/cmd/protogetter@latest -``` - -## Usage - -To run the linter: -```bash -protogetter ./... -``` - -Or to apply suggested fixes directly: -```bash -protogetter --fix ./... -``` diff --git a/vendor/github.com/ghostiam/protogetter/flake.lock b/vendor/github.com/ghostiam/protogetter/flake.lock deleted file mode 100644 index 664ccdaa62..0000000000 --- a/vendor/github.com/ghostiam/protogetter/flake.lock +++ /dev/null @@ -1,61 +0,0 @@ -{ - "nodes": { - "flake-utils": { - "inputs": { - "systems": "systems" - }, - "locked": { - "lastModified": 1731533236, - "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1759381078, - "narHash": "sha256-gTrEEp5gEspIcCOx9PD8kMaF1iEmfBcTbO0Jag2QhQs=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "7df7ff7d8e00218376575f0acdcc5d66741351ee", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "root": { - "inputs": { - "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs" - } - }, - "systems": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/vendor/github.com/ghostiam/protogetter/flake.nix b/vendor/github.com/ghostiam/protogetter/flake.nix deleted file mode 100644 index 4bbe48500e..0000000000 --- a/vendor/github.com/ghostiam/protogetter/flake.nix +++ /dev/null @@ -1,70 +0,0 @@ -{ - description = "A flake that builds a repo"; - - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; - flake-utils.url = "github:numtide/flake-utils"; - }; - - outputs = - inputs@{ - nixpkgs, - flake-utils, - ... - }: - flake-utils.lib.eachDefaultSystem ( - system: - let - pkgs = import nixpkgs { inherit system; }; - go = pkgs.go_1_24; - buildInputs = with pkgs; [ - go - coreutils - curl - xmlstarlet - - # Protobuf + gRPC - protobuf - protoc-gen-go - protoc-gen-go-grpc - grpc - ]; - - defaultShellHook = '' - export SHELL="${pkgs.bashInteractive}/bin/bash" - - export FLAKE_ROOT="$(nix flake metadata | grep 'Resolved URL' | awk '{print $3}' | sed 's/^path://' | sed 's/^git+file:\/\///')" - export HISTFILE="$FLAKE_ROOT/.nix_bash_history" - - export GOROOT="${go}/share/go" - ''; - in - { - # run: `nix develop` - devShells = { - default = pkgs.mkShell { - inherit buildInputs; - shellHook = defaultShellHook; - }; - - # Update IDEA paths. Use only if nix installed in whole system. - # run: `nix develop .#idea` - idea = pkgs.mkShell { - inherit buildInputs; - - shellHook = pkgs.lib.concatLines [ - defaultShellHook - '' - cd "$FLAKE_ROOT" - - echo "Replace GOPATH" - xmlstarlet ed -L -u '//project/component[@name="GOROOT"]/@url' -v 'file://${go}/share/go' .idea/workspace.xml - - exit 0 - '' - ]; - }; - }; - } - ); -} diff --git a/vendor/github.com/ghostiam/protogetter/posfilter.go b/vendor/github.com/ghostiam/protogetter/posfilter.go deleted file mode 100644 index 82075ccb16..0000000000 --- a/vendor/github.com/ghostiam/protogetter/posfilter.go +++ /dev/null @@ -1,65 +0,0 @@ -package protogetter - -import ( - "go/token" -) - -type PosFilter struct { - positions map[token.Pos]struct{} - alreadyReplaced map[string]map[int][2]int // map[filename][line][start, end] -} - -func NewPosFilter() *PosFilter { - return &PosFilter{ - positions: make(map[token.Pos]struct{}), - alreadyReplaced: make(map[string]map[int][2]int), - } -} - -func (f *PosFilter) IsFiltered(pos token.Pos) bool { - _, ok := f.positions[pos] - return ok -} - -func (f *PosFilter) AddPos(pos token.Pos) { - f.positions[pos] = struct{}{} -} - -func (f *PosFilter) IsAlreadyReplaced(fset *token.FileSet, pos, end token.Pos) bool { - filePos := fset.Position(pos) - fileEnd := fset.Position(end) - - lines, ok := f.alreadyReplaced[filePos.Filename] - if !ok { - return false - } - - lineRange, ok := lines[filePos.Line] - if !ok { - return false - } - - if lineRange[0] <= filePos.Offset && fileEnd.Offset <= lineRange[1] { - return true - } - - return false -} - -func (f *PosFilter) AddAlreadyReplaced(fset *token.FileSet, pos, end token.Pos) { - filePos := fset.Position(pos) - fileEnd := fset.Position(end) - - lines, ok := f.alreadyReplaced[filePos.Filename] - if !ok { - lines = make(map[int][2]int) - f.alreadyReplaced[filePos.Filename] = lines - } - - lineRange, ok := lines[filePos.Line] - if ok && lineRange[0] <= filePos.Offset && fileEnd.Offset <= lineRange[1] { - return - } - - lines[filePos.Line] = [2]int{filePos.Offset, fileEnd.Offset} -} diff --git a/vendor/github.com/ghostiam/protogetter/processor.go b/vendor/github.com/ghostiam/protogetter/processor.go deleted file mode 100644 index aaa4ab3c65..0000000000 --- a/vendor/github.com/ghostiam/protogetter/processor.go +++ /dev/null @@ -1,428 +0,0 @@ -package protogetter - -import ( - "fmt" - "go/ast" - "go/token" - "go/types" - "reflect" - "strings" -) - -type processor struct { - info *types.Info - filter *PosFilter - cfg *Config - - to strings.Builder - from strings.Builder - err error -} - -func Process(info *types.Info, filter *PosFilter, n ast.Node, cfg *Config) (*Result, error) { - p := &processor{ - info: info, - filter: filter, - cfg: cfg, - } - - return p.process(n) -} - -func (c *processor) process(n ast.Node) (*Result, error) { - switch x := n.(type) { - case *ast.AssignStmt: - // Skip any assignment to the field. - for i, s := range x.Lhs { - c.filter.AddPos(s.Pos()) - - if se, ok := s.(*ast.StarExpr); ok { - c.filter.AddPos(se.X.Pos()) - } - - if len(x.Rhs) > i { - value := x.Rhs[i] - if se, ok := value.(*ast.SelectorExpr); ok { - if hasPointerKeyWithoutPointerGetter(c.info, s, se) { - c.filter.AddPos(se.Sel.Pos()) - } - } - } - } - - case *ast.IncDecStmt: - // Skip any increment/decrement to the field. - c.filter.AddPos(x.X.Pos()) - - case *ast.UnaryExpr: - if x.Op == token.AND { - // Skip all expressions when the field is used as a pointer. - // Because this is not direct reading, but most likely writing by pointer (for example like sql.Scan). - c.filter.AddPos(x.X.Pos()) - } - - case *ast.KeyValueExpr: - if se, ok := x.Value.(*ast.SelectorExpr); ok { - if hasPointerKeyWithoutPointerGetter(c.info, x.Key, se) { - c.filter.AddPos(se.Sel.Pos()) - } - } - - case *ast.CallExpr: - if !c.cfg.ReplaceFirstArgInAppend && len(x.Args) > 0 { - if v, ok := x.Fun.(*ast.Ident); ok && v.Name == "append" { - // Skip first argument of append function. - c.filter.AddPos(x.Args[0].Pos()) - break - } - } - - switch fun := x.Fun.(type) { - case *ast.Ident: - // Allow passing optional parameters to the function without getter. - - if len(x.Args) == 0 { - return &Result{}, nil - } - - if fun.Obj == nil || fun.Obj.Kind != ast.Fun { - return &Result{}, nil - } - - decl, ok := fun.Obj.Decl.(*ast.FuncDecl) - if !ok || decl.Type == nil { - return &Result{}, nil - } - - for _, arg := range x.Args { - a, ok := arg.(*ast.SelectorExpr) - if !ok { - continue - } - - if !isProtoMessage(c.info, a.X) { - continue - } - - // If the argument is not a pointer, - // then we should not skip the check for using the getter. - _, isPtrArg := c.info.TypeOf(a).Underlying().(*types.Pointer) - if !isPtrArg { - continue - } - - // If the getter also have a pointer, - // then we should not skip the check for using the getter. - getterHasPointer, _ := getterResultHasPointer(c.info, a.X, a.Sel.Name) - if getterHasPointer { - continue - } - - c.filter.AddPos(a.Sel.Pos()) - } - - case *ast.SelectorExpr: - if !isProtoMessage(c.info, fun.X) { - return &Result{}, nil - } - - c.processInner(x) - - default: - return &Result{}, nil - } - - case *ast.SelectorExpr: - if !isProtoMessage(c.info, x.X) { - // If the selector is not on a proto message, skip it. - return &Result{}, nil - } - - c.processInner(x) - - case *ast.StarExpr: - f, ok := x.X.(*ast.SelectorExpr) - if !ok { - return &Result{}, nil - } - - if !isProtoMessage(c.info, f.X) { - return &Result{}, nil - } - - // proto2 generates fields as pointers. Hence, the indirection - // must be removed when generating the fix for the case. - // The `*` is retained in `c.from`, but excluded from the fix - // present in the `c.to`. - c.writeFrom("*") - c.processInner(x.X) - - case *ast.BinaryExpr: - // Check if the expression is a comparison. - if x.Op != token.EQL && x.Op != token.NEQ { - return &Result{}, nil - } - - // Check if one of the operands is nil. - - xIdent, xOk := x.X.(*ast.Ident) - yIdent, yOk := x.Y.(*ast.Ident) - - xIsNil := xOk && xIdent.Name == "nil" - yIsNil := yOk && yIdent.Name == "nil" - - if !xIsNil && !yIsNil { - return &Result{}, nil - } - - // Extract the non-nil operand for further checks - - var expr ast.Expr - if xIsNil { - expr = x.Y - } else { - expr = x.X - } - - se, ok := expr.(*ast.SelectorExpr) - if !ok { - return &Result{}, nil - } - - if !isProtoMessage(c.info, se.X) { - return &Result{}, nil - } - - // Check if the Getter function of the protobuf message returns a pointer. - hasPointer, ok := getterResultHasPointer(c.info, se.X, se.Sel.Name) - if !ok || hasPointer { - return &Result{}, nil - } - - c.filter.AddPos(x.X.Pos()) - - default: - return nil, fmt.Errorf("not implemented for type: %s (%s)", reflect.TypeOf(x), formatNode(n)) - } - - if c.err != nil { - return nil, c.err - } - - return &Result{ - From: c.from.String(), - To: c.to.String(), - }, nil -} - -func (c *processor) processInner(expr ast.Expr) { - switch x := expr.(type) { - case *ast.Ident: - c.write(x.Name) - - case *ast.BasicLit: - c.write(x.Value) - - case *ast.UnaryExpr: - if x.Op == token.AND { - c.write(formatNode(x)) - return - } - - c.write(x.Op.String()) - c.processInner(x.X) - - case *ast.SelectorExpr: - c.processInner(x.X) - c.write(".") - - // Skip if the field is filtered. - isFiltered := c.filter.IsFiltered(x.Sel.Pos()) - - // If getter exists, use it. - if methodIsExists(c.info, x.X, "Get"+x.Sel.Name) && !isFiltered { - c.writeFrom(x.Sel.Name) - c.writeTo("Get" + x.Sel.Name + "()") - return - } - - // If the selector is not a proto-message or the method has already been called, we leave it unchanged. - // This approach is significantly more efficient than verifying the presence of methods in all cases. - c.write(x.Sel.Name) - - case *ast.CallExpr: - c.processInner(x.Fun) - c.write("(") - for i, arg := range x.Args { - if i > 0 { - c.write(",") - } - c.processInner(arg) - } - c.write(")") - - case *ast.IndexExpr: - c.processInner(x.X) - c.write("[") - c.processInner(x.Index) - c.write("]") - - case *ast.BinaryExpr: - c.processInner(x.X) - c.write(x.Op.String()) - c.processInner(x.Y) - - case *ast.ParenExpr: - c.write("(") - c.processInner(x.X) - c.write(")") - - case *ast.StarExpr: - c.write("*") - c.processInner(x.X) - - case *ast.CompositeLit, *ast.TypeAssertExpr, *ast.ArrayType, *ast.FuncLit, *ast.SliceExpr, *ast.MapType: - // Process the node as is. - c.write(formatNode(x)) - - default: - c.err = fmt.Errorf("processInner: not implemented for type: %s", reflect.TypeOf(x)) - } -} - -func (c *processor) write(s string) { - c.writeTo(s) - c.writeFrom(s) -} - -func (c *processor) writeTo(s string) { - c.to.WriteString(s) -} - -func (c *processor) writeFrom(s string) { - c.from.WriteString(s) -} - -// Result contains source code (from) and suggested change (to) -type Result struct { - From string - To string -} - -func (r *Result) Skipped() bool { - // If from and to are the same, skip it. - return r.From == r.To -} - -func isProtoMessage(info *types.Info, expr ast.Expr) bool { - // First, we are checking for the presence of the ProtoReflect method which is currently being generated - // and corresponds to v2 version. - // https://pkg.go.dev/google.golang.org/protobuf@v1.31.0/proto#Message - const protoV2Method = "ProtoReflect" - ok := methodIsExists(info, expr, protoV2Method) - if ok { - return true - } - - // Afterwards, we are checking the ProtoMessage method. All the structures that implement the proto.Message interface - // have a ProtoMessage method and are proto-structures. This interface has been generated since version 1.0.0 and - // continues to exist for compatibility. - // https://pkg.go.dev/github.com/golang/protobuf/proto?utm_source=godoc#Message - const protoV1Method = "ProtoMessage" - ok = methodIsExists(info, expr, protoV1Method) - if ok { - // Since there is a protoc-gen-gogo generator that implements the proto.Message interface, but may not generate - // getters or generate from without checking for nil, so even if getters exist, we skip them. - const protocGenGoGoMethod = "MarshalToSizedBuffer" - return !methodIsExists(info, expr, protocGenGoGoMethod) - } - - return false -} - -func typesNamed(info *types.Info, x ast.Expr) (*types.Named, bool) { - if info == nil { - return nil, false - } - - t := info.TypeOf(x) - if t == nil { - return nil, false - } - - ptr, ok := t.Underlying().(*types.Pointer) - if ok { - t = ptr.Elem() - } - - named, ok := t.(*types.Named) - if !ok { - return nil, false - } - - return named, true -} - -func methodIsExists(info *types.Info, x ast.Expr, name string) bool { - named, ok := typesNamed(info, x) - if !ok { - return false - } - - for i := 0; i < named.NumMethods(); i++ { - if named.Method(i).Name() == name { - return true - } - } - - return false -} - -func getterResultHasPointer(info *types.Info, x ast.Expr, name string) (hasPointer, ok bool) { - named, ok := typesNamed(info, x) - if !ok { - return false, false - } - - for i := 0; i < named.NumMethods(); i++ { - method := named.Method(i) - if method.Name() != "Get"+name { - continue - } - - var sig *types.Signature - sig, ok = method.Type().(*types.Signature) - if !ok { - return false, false - } - - results := sig.Results() - if results.Len() == 0 { - return false, false - } - - firstType := results.At(0) - _, ok = firstType.Type().(*types.Pointer) - if !ok { - return false, true - } - - return true, true - } - - return false, false -} - -func hasPointerKeyWithoutPointerGetter(info *types.Info, key ast.Expr, value *ast.SelectorExpr) bool { - _, isPtr := info.TypeOf(key).(*types.Pointer) - if !isPtr { - return false - } - - getterHasPointer, ok := getterResultHasPointer(info, value.X, value.Sel.Name) - if !ok { - return false - } - - return !getterHasPointer -} diff --git a/vendor/github.com/ghostiam/protogetter/protogetter.go b/vendor/github.com/ghostiam/protogetter/protogetter.go deleted file mode 100644 index 0dbcf31c93..0000000000 --- a/vendor/github.com/ghostiam/protogetter/protogetter.go +++ /dev/null @@ -1,237 +0,0 @@ -package protogetter - -import ( - "bytes" - "flag" - "fmt" - "go/ast" - "go/format" - "go/token" - "log" - "path/filepath" - "strings" - - "github.com/gobwas/glob" - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/ast/inspector" -) - -const msgFormat = "avoid direct access to proto field %s, use %s instead" - -func NewAnalyzer(cfg *Config) *analysis.Analyzer { - if cfg == nil { - cfg = &Config{} - } - - return &analysis.Analyzer{ - Name: "protogetter", - Doc: "Reports direct reads from proto message fields when getters should be used", - Flags: flags(cfg), - Run: func(pass *analysis.Pass) (any, error) { - err := Run(pass, cfg) - return nil, err - }, - } -} - -func flags(opts *Config) flag.FlagSet { - fs := flag.NewFlagSet("protogetter", flag.ContinueOnError) - - fs.Func("skip-generated-by", "skip files generated with the given prefixes", func(s string) error { - for _, prefix := range strings.Split(s, ",") { - opts.SkipGeneratedBy = append(opts.SkipGeneratedBy, prefix) - } - return nil - }) - fs.Func("skip-files", "skip files with the given glob patterns", func(s string) error { - for _, pattern := range strings.Split(s, ",") { - opts.SkipFiles = append(opts.SkipFiles, pattern) - } - return nil - }) - fs.BoolVar(&opts.SkipAnyGenerated, "skip-any-generated", false, "skip any generated files") - - return *fs -} - -type Config struct { - SkipGeneratedBy []string - SkipFiles []string - SkipAnyGenerated bool - ReplaceFirstArgInAppend bool -} - -func Run(pass *analysis.Pass, cfg *Config) error { - skipGeneratedBy := make([]string, 0, len(cfg.SkipGeneratedBy)+3) - // Always skip files generated by protoc-gen-go, protoc-gen-go-grpc and protoc-gen-grpc-gateway. - skipGeneratedBy = append(skipGeneratedBy, "protoc-gen-go", "protoc-gen-go-grpc", "protoc-gen-grpc-gateway") - for _, s := range cfg.SkipGeneratedBy { - s = strings.TrimSpace(s) - if s == "" { - continue - } - skipGeneratedBy = append(skipGeneratedBy, s) - } - - skipFilesGlobPatterns := make([]glob.Glob, 0, len(cfg.SkipFiles)) - for _, s := range cfg.SkipFiles { - s = strings.TrimSpace(s) - if s == "" { - continue - } - - compile, err := glob.Compile(s) - if err != nil { - return fmt.Errorf("invalid glob pattern: %w", err) - } - - skipFilesGlobPatterns = append(skipFilesGlobPatterns, compile) - } - - nodeTypes := []ast.Node{ - (*ast.AssignStmt)(nil), - (*ast.BinaryExpr)(nil), - (*ast.CallExpr)(nil), - (*ast.SelectorExpr)(nil), - (*ast.StarExpr)(nil), - (*ast.IncDecStmt)(nil), - (*ast.UnaryExpr)(nil), - (*ast.KeyValueExpr)(nil), - } - - // Skip filtered files. - var files []*ast.File - for _, f := range pass.Files { - if skipGeneratedFile(f, skipGeneratedBy, cfg.SkipAnyGenerated) { - continue - } - - if skipFilesByGlob(pass.Fset.File(f.Pos()).Name(), skipFilesGlobPatterns) { - continue - } - - files = append(files, f) - - // ast.Print(pass.Fset, f) - } - - ins := inspector.New(files) - - filter := NewPosFilter() - ins.Preorder(nodeTypes, func(node ast.Node) { - report := analyse(pass, filter, node, cfg) - if report == nil { - return - } - pass.Report(report.ToDiagReport()) - }) - - return nil -} - -func analyse(pass *analysis.Pass, filter *PosFilter, n ast.Node, cfg *Config) *Report { - // fmt.Printf("\n>>> check: %s\n", formatNode(n)) - // ast.Print(pass.Fset, n) - if filter.IsFiltered(n.Pos()) { - // fmt.Printf(">>> filtered\n") - return nil - } - - result, err := Process(pass.TypesInfo, filter, n, cfg) - if err != nil { - pass.Report(analysis.Diagnostic{ - Pos: n.Pos(), - End: n.End(), - Message: fmt.Sprintf("error: %v", err), - }) - - return nil - } - - // If existing in filter, skip it. - if filter.IsFiltered(n.Pos()) { - return nil - } - - if result.Skipped() { - return nil - } - - // If the expression has already been replaced, skip it. - if filter.IsAlreadyReplaced(pass.Fset, n.Pos(), n.End()) { - return nil - } - // Add the expression to the filter. - filter.AddAlreadyReplaced(pass.Fset, n.Pos(), n.End()) - - return &Report{ - node: n, - result: result, - } -} - -type Report struct { - node ast.Node - result *Result -} - -func (r *Report) ToDiagReport() analysis.Diagnostic { - msg := fmt.Sprintf(msgFormat, r.result.From, r.result.To) - - return analysis.Diagnostic{ - Pos: r.node.Pos(), - End: r.node.End(), - Message: msg, - SuggestedFixes: []analysis.SuggestedFix{ - { - Message: msg, - TextEdits: []analysis.TextEdit{ - { - Pos: r.node.Pos(), - End: r.node.End(), - NewText: []byte(r.result.To), - }, - }, - }, - }, - } -} - -func skipGeneratedFile(f *ast.File, prefixes []string, skipAny bool) bool { - if len(f.Comments) == 0 { - return false - } - firstComment := f.Comments[0].Text() - - if skipAny && ast.IsGenerated(f) { - return true - } - - for _, prefix := range prefixes { - if strings.HasPrefix(firstComment, "Code generated by "+prefix) { - return true - } - } - - return false -} - -func skipFilesByGlob(filename string, patterns []glob.Glob) bool { - for _, pattern := range patterns { - if pattern.Match(filename) || pattern.Match(filepath.Base(filename)) { - return true - } - } - - return false -} - -func formatNode(node ast.Node) string { - buf := new(bytes.Buffer) - if err := format.Node(buf, token.NewFileSet(), node); err != nil { - log.Printf("Error formatting expression: %v", err) - return "" - } - - return buf.String() -} diff --git a/vendor/github.com/go-critic/go-critic/LICENSE b/vendor/github.com/go-critic/go-critic/LICENSE deleted file mode 100644 index 5198a4a942..0000000000 --- a/vendor/github.com/go-critic/go-critic/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2018-2021 go-critic team - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/go-critic/go-critic/checkers/appendAssign_checker.go b/vendor/github.com/go-critic/go-critic/checkers/appendAssign_checker.go deleted file mode 100644 index 2a67dccec8..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/appendAssign_checker.go +++ /dev/null @@ -1,103 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/token" - "go/types" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" - - "github.com/go-toolsmith/astequal" - "github.com/go-toolsmith/astp" - "golang.org/x/tools/go/ast/astutil" -) - -func init() { - var info linter.CheckerInfo - info.Name = "appendAssign" - info.Tags = []string{linter.DiagnosticTag} - info.Summary = "Detects suspicious append result assignments" - info.Before = ` -p.positives = append(p.negatives, x) -p.negatives = append(p.negatives, y)` - info.After = ` -p.positives = append(p.positives, x) -p.negatives = append(p.negatives, y)` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForStmt(&appendAssignChecker{ctx: ctx}), nil - }) -} - -type appendAssignChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext -} - -func (c *appendAssignChecker) VisitStmt(stmt ast.Stmt) { - assign, ok := stmt.(*ast.AssignStmt) - if !ok || (assign.Tok != token.ASSIGN && assign.Tok != token.DEFINE) || len(assign.Lhs) != len(assign.Rhs) { - return - } - for i, rhs := range assign.Rhs { - call, ok := rhs.(*ast.CallExpr) - if !ok || qualifiedName(call.Fun) != "append" { - continue - } - c.checkAppend(assign.Lhs[i], call) - } -} - -func (c *appendAssignChecker) checkAppend(x ast.Expr, call *ast.CallExpr) { - if call.Ellipsis != token.NoPos { - // Try to detect `xs = append(ys, xs...)` idiom. - for _, arg := range call.Args[1:] { - y := arg - if arg, ok := arg.(*ast.SliceExpr); ok { - y = arg.X - } - if astequal.Expr(x, y) { - return - } - } - } - - switch x := x.(type) { - case *ast.Ident: - if x.Name == "_" { - return // Don't check assignments to blank ident - } - case *ast.IndexExpr: - if !astp.IsIndexExpr(call.Args[0]) { - // Most likely `m[k] = append(x, ...)` - // pattern, where x was retrieved by m[k] before. - // - // TODO: it's possible to record such map/slice reads - // and check whether it was done before this call. - // But for now, treat it like x belongs to m[k]. - return - } - } - - switch y := call.Args[0].(type) { - case *ast.SliceExpr: - if _, ok := c.ctx.TypeOf(y.X).(*types.Array); ok { - // Arrays are frequently used as scratch storages. - return - } - c.matchSlices(call, x, y.X) - case *ast.IndexExpr, *ast.Ident, *ast.SelectorExpr: - c.matchSlices(call, x, y) - } -} - -func (c *appendAssignChecker) matchSlices(cause ast.Node, x, y ast.Expr) { - if !astequal.Expr(x, astutil.Unparen(y)) { - c.warn(cause) - } -} - -func (c *appendAssignChecker) warn(cause ast.Node) { - c.ctx.Warn(cause, "append result not assigned to the same slice") -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/appendCombine_checker.go b/vendor/github.com/go-critic/go-critic/checkers/appendCombine_checker.go deleted file mode 100644 index 81a7aa30b3..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/appendCombine_checker.go +++ /dev/null @@ -1,103 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/token" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" - - "github.com/go-toolsmith/astcast" - "github.com/go-toolsmith/astequal" -) - -func init() { - var info linter.CheckerInfo - info.Name = "appendCombine" - info.Tags = []string{linter.PerformanceTag} - info.Summary = "Detects `append` chains to the same slice that can be done in a single `append` call" - info.Before = ` -xs = append(xs, 1) -xs = append(xs, 2)` - info.After = `xs = append(xs, 1, 2)` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForStmtList(&appendCombineChecker{ctx: ctx}), nil - }) -} - -type appendCombineChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext -} - -func (c *appendCombineChecker) VisitStmtList(_ ast.Node, list []ast.Stmt) { - var cause ast.Node // First append - var slice ast.Expr // Slice being appended to - chain := 0 // How much appends in a row we've seen - - // Break the chain. - // If enough appends are in chain, print warning. - flush := func() { - if chain > 1 { - c.warn(cause, chain) - } - chain = 0 - slice = nil - } - - for _, stmt := range list { - call := c.matchAppend(stmt, slice) - if call == nil { - flush() - continue - } - - if chain == 0 { - // First append in a chain. - chain = 1 - slice = call.Args[0] - cause = stmt - } else { - chain++ - } - } - - // Required for printing chains that consist of trailing - // statements from the list. - flush() -} - -func (c *appendCombineChecker) matchAppend(stmt ast.Stmt, slice ast.Expr) *ast.CallExpr { - // Seeking for: - // slice = append(slice, xs...) - // xs are 0-N append arguments, but not variadic argument, - // because it makes append combining impossible. - - assign := astcast.ToAssignStmt(stmt) - if len(assign.Lhs) != 1 || len(assign.Rhs) != 1 { - return nil - } - - call, ok := assign.Rhs[0].(*ast.CallExpr) - { - cond := ok && - qualifiedName(call.Fun) == "append" && - call.Ellipsis == token.NoPos && - astequal.Expr(assign.Lhs[0], call.Args[0]) - if !cond { - return nil - } - } - - // Check that current append slice match previous append slice. - // Otherwise we should break the chain. - if slice == nil || astequal.Expr(slice, call.Args[0]) { - return call - } - return nil -} - -func (c *appendCombineChecker) warn(cause ast.Node, chain int) { - c.ctx.Warn(cause, "can combine chain of %d appends into one", chain) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/badCond_checker.go b/vendor/github.com/go-critic/go-critic/checkers/badCond_checker.go deleted file mode 100644 index 22a6267fd6..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/badCond_checker.go +++ /dev/null @@ -1,162 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/constant" - "go/token" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/checkers/internal/lintutil" - "github.com/go-critic/go-critic/linter" - - "github.com/go-toolsmith/astcast" - "github.com/go-toolsmith/astcopy" - "github.com/go-toolsmith/astequal" - "github.com/go-toolsmith/typep" - "golang.org/x/tools/go/ast/astutil" -) - -func init() { - var info linter.CheckerInfo - info.Name = "badCond" - info.Tags = []string{linter.DiagnosticTag} - info.Summary = "Detects suspicious condition expressions" - info.Before = ` -for i := 0; i > n; i++ { - xs[i] = 0 -}` - info.After = ` -for i := 0; i < n; i++ { - xs[i] = 0 -}` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForFuncDecl(&badCondChecker{ctx: ctx}), nil - }) -} - -type badCondChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext -} - -func (c *badCondChecker) VisitFuncDecl(decl *ast.FuncDecl) { - ast.Inspect(decl.Body, func(n ast.Node) bool { - switch n := n.(type) { - case *ast.ForStmt: - c.checkForStmt(n) - case ast.Expr: - c.checkExpr(n) - } - return true - }) -} - -func (c *badCondChecker) checkExpr(expr ast.Expr) { - // TODO(quasilyte): recognize more patterns. - - cond := astcast.ToBinaryExpr(expr) - lhs := astcast.ToBinaryExpr(astutil.Unparen(cond.X)) - rhs := astcast.ToBinaryExpr(astutil.Unparen(cond.Y)) - - if cond.Op != token.LAND { - return - } - - // Notes: - // `x != a || x != b` handled by go vet. - - // Pattern 1. - // `x < a && x > b`; Where `a` is less than `b`. - if c.lessAndGreater(lhs, rhs) { - c.warnCond(cond, "always false") - return - } - - // Pattern 2. - // `x == a && x == b` - // - // Valid when `b == a` is intended, but still reported. - // We can disable "just suspicious" warnings by default - // is users are upset with the current behavior. - if c.equalToBoth(lhs, rhs) { - c.warnCond(cond, "suspicious") - return - } -} - -func (c *badCondChecker) equalToBoth(lhs, rhs *ast.BinaryExpr) bool { - return lhs.Op == token.EQL && rhs.Op == token.EQL && - astequal.Expr(lhs.X, rhs.X) && - typep.SideEffectFree(c.ctx.TypesInfo, lhs.Y) && typep.SideEffectFree(c.ctx.TypesInfo, rhs.Y) -} - -func (c *badCondChecker) lessAndGreater(lhs, rhs *ast.BinaryExpr) bool { - if lhs.Op != token.LSS || rhs.Op != token.GTR { - return false - } - if !astequal.Expr(lhs.X, rhs.X) { - return false - } - a := c.ctx.TypesInfo.Types[lhs.Y].Value - b := c.ctx.TypesInfo.Types[rhs.Y].Value - return a != nil && b != nil && constant.Compare(a, token.LSS, b) -} - -func (c *badCondChecker) checkForStmt(stmt *ast.ForStmt) { - // TODO(quasilyte): handle other kinds of bad conditionals. - - init := astcast.ToAssignStmt(stmt.Init) - if init.Tok != token.DEFINE || len(init.Lhs) != 1 || len(init.Rhs) != 1 { - return - } - if astcast.ToBasicLit(init.Rhs[0]).Value != "0" { - return - } - - iter := astcast.ToIdent(init.Lhs[0]) - cond := astcast.ToBinaryExpr(stmt.Cond) - - var i, n ast.Expr - var op token.Token - switch { - case cond.Op == token.GTR && astequal.Expr(iter, cond.X): - i = cond.X - n = cond.Y - op = token.LSS - case cond.Op == token.LSS && astequal.Expr(iter, cond.Y): - i = cond.Y - n = cond.X - op = token.GTR - default: - return - } - - if !typep.SideEffectFree(c.ctx.TypesInfo, n) { - return - } - - post := astcast.ToIncDecStmt(stmt.Post) - if post.Tok != token.INC || !astequal.Expr(iter, i) { - return - } - - mutated := lintutil.CouldBeMutated(c.ctx.TypesInfo, stmt.Body, n) || - lintutil.CouldBeMutated(c.ctx.TypesInfo, stmt.Body, iter) - if mutated { - return - } - - c.warnForStmt(stmt, op, cond) -} - -func (c *badCondChecker) warnForStmt(cause ast.Node, op token.Token, cond *ast.BinaryExpr) { - suggest := astcopy.BinaryExpr(cond) - suggest.Op = op - c.ctx.Warn(cause, "`%s` in loop; probably meant `%s`?", - cond, suggest) -} - -func (c *badCondChecker) warnCond(cond *ast.BinaryExpr, tag string) { - c.ctx.Warn(cond, "`%s` condition is %s", cond, tag) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/badRegexp_checker.go b/vendor/github.com/go-critic/go-critic/checkers/badRegexp_checker.go deleted file mode 100644 index 8f5cf97f68..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/badRegexp_checker.go +++ /dev/null @@ -1,446 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/constant" - "sort" - "strconv" - "unicode" - "unicode/utf8" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" - - "github.com/quasilyte/regex/syntax" -) - -func init() { - var info linter.CheckerInfo - info.Name = "badRegexp" - info.Tags = []string{linter.DiagnosticTag, linter.ExperimentalTag} - info.Summary = "Detects suspicious regexp patterns" - info.Before = "regexp.MustCompile(`(?:^aa|bb|cc)foo[aba]`)" - info.After = "regexp.MustCompile(`^(?:aa|bb|cc)foo[ab]`)" - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - opts := &syntax.ParserOptions{} - c := &badRegexpChecker{ - ctx: ctx, - parser: syntax.NewParser(opts), - } - return astwalk.WalkerForExpr(c), nil - }) -} - -type badRegexpChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext - - parser *syntax.Parser - cause ast.Expr - - flagStates []regexpFlagState - goodAnchors []syntax.Position -} - -type regexpFlagState [utf8.RuneSelf]bool - -func (c *badRegexpChecker) VisitExpr(x ast.Expr) { - call, ok := x.(*ast.CallExpr) - if !ok { - return - } - - switch qualifiedName(call.Fun) { - case "regexp.Compile", "regexp.MustCompile": - cv := c.ctx.TypesInfo.Types[call.Args[0]].Value - if cv == nil || cv.Kind() != constant.String { - return - } - pat := constant.StringVal(cv) - c.cause = call.Args[0] - c.checkPattern(pat) - } -} - -func (c *badRegexpChecker) checkPattern(pat string) { - re, err := c.parser.Parse(pat) - if err != nil { - return - } - - c.flagStates = c.flagStates[:0] - c.goodAnchors = c.goodAnchors[:0] - - // In Go all flags (modifiers) are set to false by default, - // so we start from the empty flag set. - c.flagStates = append(c.flagStates, regexpFlagState{}) - - c.markGoodCarets(re.Expr) - c.walk(re.Expr) -} - -func (c *badRegexpChecker) markGoodCarets(e syntax.Expr) { - canSkip := func(e syntax.Expr) bool { - switch e.Op { - case syntax.OpFlagOnlyGroup: - return true - case syntax.OpGroup: - x := e.Args[0] - return x.Op == syntax.OpConcat && len(x.Args) == 0 - } - return false - } - - if e.Op == syntax.OpConcat && len(e.Args) > 1 { - i := 0 - for i < len(e.Args) && canSkip(e.Args[i]) { - i++ - } - if i < len(e.Args) { - c.markGoodCarets(e.Args[i]) - } - return - } - if e.Op == syntax.OpCaret { - c.addGoodAnchor(e.Pos) - } - for _, a := range e.Args { - c.markGoodCarets(a) - } -} - -func (c *badRegexpChecker) walk(e syntax.Expr) { - switch e.Op { - case syntax.OpAlt: - c.checkAltAnchor(e) - c.checkAltDups(e) - for _, a := range e.Args { - c.walk(a) - } - - case syntax.OpCharClass, syntax.OpNegCharClass: - if c.checkCharClassRanges(e) { - c.checkCharClassDups(e) - } - - case syntax.OpStar, syntax.OpPlus: - c.checkNestedQuantifier(e) - c.walk(e.Args[0]) - - case syntax.OpFlagOnlyGroup: - c.updateFlagState(c.currentFlagState(), e, e.Args[0].Value) - case syntax.OpGroupWithFlags: - // Creates a new context using the current context copy. - // New flags are evaluated inside a new context. - // After nested expressions are processed, previous context is restored. - nflags := len(c.flagStates) - c.flagStates = append(c.flagStates, *c.currentFlagState()) - c.updateFlagState(c.currentFlagState(), e, e.Args[1].Value) - c.walk(e.Args[0]) - c.flagStates = c.flagStates[:nflags] - case syntax.OpGroup, syntax.OpCapture, syntax.OpNamedCapture: - // Like with OpGroupWithFlags, but doesn't evaluate any new flags. - nflags := len(c.flagStates) - c.flagStates = append(c.flagStates, *c.currentFlagState()) - c.walk(e.Args[0]) - c.flagStates = c.flagStates[:nflags] - - case syntax.OpCaret: - if !c.isGoodAnchor(e) { - c.warnf("dangling or redundant ^, maybe \\^ is intended?") - } - - default: - for _, a := range e.Args { - c.walk(a) - } - } -} - -func (c *badRegexpChecker) currentFlagState() *regexpFlagState { - return &c.flagStates[len(c.flagStates)-1] -} - -func (c *badRegexpChecker) updateFlagState(state *regexpFlagState, e syntax.Expr, flagString string) { - clearing := false - for i := 0; i < len(flagString); i++ { - ch := flagString[i] - if ch == '-' { - clearing = true - continue - } - if int(ch) >= len(state) { - continue // Should never happen in practice, but we don't want a panic - } - - if clearing { - if !state[ch] { - c.warnf("clearing unset flag %c in %s", ch, e.Value) - } - } else { - if state[ch] { - c.warnf("redundant flag %c in %s", ch, e.Value) - } - } - state[ch] = !clearing - } -} - -func (c *badRegexpChecker) checkNestedQuantifier(e syntax.Expr) { - x := e.Args[0] - switch x.Op { - case syntax.OpGroup, syntax.OpCapture, syntax.OpGroupWithFlags: - if len(e.Args) == 1 { - x = x.Args[0] - } - } - - switch x.Op { - case syntax.OpPlus, syntax.OpStar: - c.warnf("repeated greedy quantifier in %s", e.Value) - } -} - -func (c *badRegexpChecker) checkAltDups(alt syntax.Expr) { - // Seek duplicated alternation expressions. - - set := make(map[string]struct{}, len(alt.Args)) - for _, a := range alt.Args { - if _, ok := set[a.Value]; ok { - c.warnf("`%s` is duplicated in %s", a.Value, alt.Value) - } - set[a.Value] = struct{}{} - } -} - -func (c *badRegexpChecker) isCharOrLit(e syntax.Expr) bool { - return e.Op == syntax.OpChar || e.Op == syntax.OpLiteral -} - -func (c *badRegexpChecker) checkAltAnchor(alt syntax.Expr) { - // Seek suspicious anchors. - - // Case 1: an alternation of literals where 1st expr begins with ^ anchor. - first := alt.Args[0] - if first.Op == syntax.OpConcat && len(first.Args) == 2 && first.Args[0].Op == syntax.OpCaret && c.isCharOrLit(first.Args[1]) { - matched := true - for _, a := range alt.Args[1:] { - if !c.isCharOrLit(a) { - matched = false - break - } - } - if matched { - c.warnf("^ applied only to `%s` in %s", first.Value[len(`^`):], alt.Value) - } - } - - // Case 2: an alternation of literals where last expr ends with $ anchor. - last := alt.Args[len(alt.Args)-1] - if last.Op == syntax.OpConcat && len(last.Args) == 2 && last.Args[1].Op == syntax.OpDollar && c.isCharOrLit(last.Args[0]) { - matched := true - for _, a := range alt.Args[:len(alt.Args)-1] { - if !c.isCharOrLit(a) { - matched = false - break - } - } - if matched { - c.warnf("$ applied only to `%s` in %s", last.Value[:len(last.Value)-len(`$`)], alt.Value) - } - } -} - -func (c *badRegexpChecker) checkCharClassRanges(cc syntax.Expr) bool { - // Seek for suspicious ranges like `!-_`. - // - // We permit numerical ranges (0-9, hex and octal literals) - // and simple ascii letter ranges. - - for _, e := range cc.Args { - if e.Op != syntax.OpCharRange { - continue - } - switch e.Args[0].Op { - case syntax.OpEscapeOctal, syntax.OpEscapeHex: - continue - } - ch := c.charClassBoundRune(e.Args[0]) - if ch == 0 { - return false - } - good := unicode.IsLetter(ch) || (ch >= '0' && ch <= '9') - if !good { - c.warnSloppyCharRange(e.Value, cc.Value) - } - } - - return true -} - -func (c *badRegexpChecker) checkCharClassDups(cc syntax.Expr) { - // Seek for excessive elements inside a character class. - // Report them as intersections. - - if len(cc.Args) == 1 { - return // Can't had duplicates. - } - - type charRange struct { - low rune - high rune - source string - } - ranges := make([]charRange, 0, 8) - addRange := func(source string, low, high rune) { - ranges = append(ranges, charRange{source: source, low: low, high: high}) - } - addRange1 := func(source string, ch rune) { - addRange(source, ch, ch) - } - - // 1. Collect ranges, O(n). - for _, e := range cc.Args { - switch e.Op { - case syntax.OpEscapeOctal: - addRange1(e.Value, c.octalToRune(e)) - case syntax.OpEscapeHex: - addRange1(e.Value, c.hexToRune(e)) - case syntax.OpChar: - addRange1(e.Value, c.stringToRune(e.Value)) - case syntax.OpCharRange: - addRange(e.Value, c.charClassBoundRune(e.Args[0]), c.charClassBoundRune(e.Args[1])) - case syntax.OpEscapeMeta: - addRange1(e.Value, rune(e.Value[1])) - case syntax.OpEscapeChar: - ch := c.stringToRune(e.Value[len(`\`):]) - if unicode.IsPunct(ch) { - addRange1(e.Value, ch) - break - } - switch e.Value { - case `\|`, `\<`, `\>`, `\+`, `\=`: // How to cover all symbols? - addRange1(e.Value, c.stringToRune(e.Value[len(`\`):])) - case `\t`: - addRange1(e.Value, '\t') - case `\n`: - addRange1(e.Value, '\n') - case `\r`: - addRange1(e.Value, '\r') - case `\v`: - addRange1(e.Value, '\v') - case `\d`: - addRange(e.Value, '0', '9') - case `\D`: - addRange(e.Value, 0, '0'-1) - addRange(e.Value, '9'+1, utf8.MaxRune) - case `\s`: - addRange(e.Value, '\t', '\n') // 9-10 - addRange(e.Value, '\f', '\r') // 12-13 - addRange1(e.Value, ' ') // 32 - case `\S`: - addRange(e.Value, 0, '\t'-1) - addRange(e.Value, '\n'+1, '\f'-1) - addRange(e.Value, '\r'+1, ' '-1) - addRange(e.Value, ' '+1, utf8.MaxRune) - case `\w`: - addRange(e.Value, '0', '9') // 48-57 - addRange(e.Value, 'A', 'Z') // 65-90 - addRange1(e.Value, '_') // 95 - addRange(e.Value, 'a', 'z') // 97-122 - case `\W`: - addRange(e.Value, 0, '0'-1) - addRange(e.Value, '9'+1, 'A'-1) - addRange(e.Value, 'Z'+1, '_'-1) - addRange(e.Value, '_'+1, 'a'-1) - addRange(e.Value, 'z'+1, utf8.MaxRune) - default: - // Give up: unknown escape sequence. - return - } - default: - // Give up: unexpected operation inside char class. - return - } - } - - // 2. Sort ranges, O(nlogn). - sort.SliceStable(ranges, func(i, j int) bool { - return ranges[i].low < ranges[j].low - }) - - // 3. Search for duplicates, O(n). - for i := 0; i < len(ranges)-1; i++ { - x := ranges[i+0] - y := ranges[i+1] - if x.high >= y.low { - c.warnCharClassDup(x.source, y.source, cc.Value) - break - } - } -} - -func (c *badRegexpChecker) charClassBoundRune(e syntax.Expr) rune { - switch e.Op { - case syntax.OpChar: - return c.stringToRune(e.Value) - case syntax.OpEscapeHex: - return c.hexToRune(e) - case syntax.OpEscapeOctal: - return c.octalToRune(e) - default: - return 0 - } -} - -func (c *badRegexpChecker) octalToRune(e syntax.Expr) rune { - v, _ := strconv.ParseInt(e.Value[len(`\`):], 8, 32) - return rune(v) -} - -func (c *badRegexpChecker) hexToRune(e syntax.Expr) rune { - var s string - switch e.Form { - case syntax.FormEscapeHexFull: - s = e.Value[len(`\x{`) : len(e.Value)-len(`}`)] - default: - s = e.Value[len(`\x`):] - } - v, _ := strconv.ParseInt(s, 16, 32) - return rune(v) -} - -func (c *badRegexpChecker) stringToRune(s string) rune { - ch, _ := utf8.DecodeRuneInString(s) - return ch -} - -func (c *badRegexpChecker) addGoodAnchor(pos syntax.Position) { - c.goodAnchors = append(c.goodAnchors, pos) -} - -func (c *badRegexpChecker) isGoodAnchor(e syntax.Expr) bool { - for _, pos := range c.goodAnchors { - if e.Pos == pos { - return true - } - } - return false -} - -func (c *badRegexpChecker) warnf(format string, args ...interface{}) { - c.ctx.Warn(c.cause, format, args...) -} - -func (c *badRegexpChecker) warnSloppyCharRange(rng, charClass string) { - c.ctx.Warn(c.cause, "suspicious char range `%s` in %s", rng, charClass) -} - -func (c *badRegexpChecker) warnCharClassDup(x, y, charClass string) { - if x == y { - c.ctx.Warn(c.cause, "`%s` is duplicated in %s", x, charClass) - } else { - c.ctx.Warn(c.cause, "`%s` intersects with `%s` in %s", x, y, charClass) - } -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/boolExprSimplify_checker.go b/vendor/github.com/go-critic/go-critic/checkers/boolExprSimplify_checker.go deleted file mode 100644 index a1c69cb7ab..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/boolExprSimplify_checker.go +++ /dev/null @@ -1,346 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/token" - "strconv" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/checkers/internal/lintutil" - "github.com/go-critic/go-critic/linter" - - "github.com/go-toolsmith/astcast" - "github.com/go-toolsmith/astcopy" - "github.com/go-toolsmith/astequal" - "github.com/go-toolsmith/astp" - "github.com/go-toolsmith/typep" - "golang.org/x/tools/go/ast/astutil" -) - -func init() { - var info linter.CheckerInfo - info.Name = "boolExprSimplify" - info.Tags = []string{linter.StyleTag, linter.ExperimentalTag} - info.Summary = "Detects bool expressions that can be simplified" - info.Before = ` -a := !(elapsed >= expectElapsedMin) -b := !(x) == !(y)` - info.After = ` -a := elapsed < expectElapsedMin -b := (x) == (y)` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForExpr(&boolExprSimplifyChecker{ctx: ctx}), nil - }) -} - -type boolExprSimplifyChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext - hasFloats bool -} - -func (c *boolExprSimplifyChecker) VisitExpr(x ast.Expr) { - if !astp.IsBinaryExpr(x) && !astp.IsUnaryExpr(x) { - return - } - - // Throw away non-bool expressions and avoid redundant - // AST copying below. - if typ := c.ctx.TypeOf(x); typ == nil || !typep.HasBoolKind(typ.Underlying()) { - return - } - - // We'll loose all types info after a copy, - // this is why we record valuable info before doing it. - c.hasFloats = lintutil.ContainsNode(x, func(n ast.Node) bool { - if x, ok := n.(*ast.BinaryExpr); ok { - return typep.HasFloatProp(c.ctx.TypeOf(x.X).Underlying()) || - typep.HasFloatProp(c.ctx.TypeOf(x.Y).Underlying()) - } - return false - }) - - y := c.simplifyBool(astcopy.Expr(x)) - if !astequal.Expr(x, y) { - c.warn(x, y) - } -} - -func (c *boolExprSimplifyChecker) simplifyBool(x ast.Expr) ast.Expr { - return astutil.Apply(x, nil, func(cur *astutil.Cursor) bool { - return c.doubleNegation(cur) || - c.negatedEquals(cur) || - c.invertComparison(cur) || - c.combineChecks(cur) || - c.removeIncDec(cur) || - c.foldRanges(cur) || - true - }).(ast.Expr) -} - -func (c *boolExprSimplifyChecker) doubleNegation(cur *astutil.Cursor) bool { - neg1 := astcast.ToUnaryExpr(cur.Node()) - neg2 := astcast.ToUnaryExpr(astutil.Unparen(neg1.X)) - if neg1.Op == token.NOT && neg2.Op == token.NOT { - cur.Replace(astutil.Unparen(neg2.X)) - return true - } - return false -} - -func (c *boolExprSimplifyChecker) negatedEquals(cur *astutil.Cursor) bool { - x, ok := cur.Node().(*ast.BinaryExpr) - if !ok || x.Op != token.EQL { - return false - } - neg1 := astcast.ToUnaryExpr(x.X) - neg2 := astcast.ToUnaryExpr(x.Y) - if neg1.Op == token.NOT && neg2.Op == token.NOT { - x.X = neg1.X - x.Y = neg2.X - return true - } - return false -} - -func (c *boolExprSimplifyChecker) invertComparison(cur *astutil.Cursor) bool { - if c.hasFloats { // See #673 - return false - } - - neg := astcast.ToUnaryExpr(cur.Node()) - cmp := astcast.ToBinaryExpr(astutil.Unparen(neg.X)) - if neg.Op != token.NOT { - return false - } - - // Replace operator to its negated form. - switch cmp.Op { - case token.EQL: - cmp.Op = token.NEQ - case token.NEQ: - cmp.Op = token.EQL - case token.LSS: - cmp.Op = token.GEQ - case token.GTR: - cmp.Op = token.LEQ - case token.LEQ: - cmp.Op = token.GTR - case token.GEQ: - cmp.Op = token.LSS - - default: - return false - } - cur.Replace(cmp) - return true -} - -func (c *boolExprSimplifyChecker) isSafe(x ast.Expr) bool { - return typep.SideEffectFree(c.ctx.TypesInfo, x) -} - -func (c *boolExprSimplifyChecker) combineChecks(cur *astutil.Cursor) bool { - or, ok := cur.Node().(*ast.BinaryExpr) - if !ok || or.Op != token.LOR { - return false - } - - lhs := astcast.ToBinaryExpr(astutil.Unparen(or.X)) - rhs := astcast.ToBinaryExpr(astutil.Unparen(or.Y)) - - if !astequal.Expr(lhs.X, rhs.X) || !astequal.Expr(lhs.Y, rhs.Y) { - return false - } - if !c.isSafe(lhs.X) || !c.isSafe(lhs.Y) { - return false - } - - combTable := [...]struct { - x token.Token - y token.Token - result token.Token - }{ - {token.GTR, token.EQL, token.GEQ}, - {token.EQL, token.GTR, token.GEQ}, - {token.LSS, token.EQL, token.LEQ}, - {token.EQL, token.LSS, token.LEQ}, - } - for _, comb := range &combTable { - if comb.x == lhs.Op && comb.y == rhs.Op { - lhs.Op = comb.result - cur.Replace(lhs) - return true - } - } - return false -} - -func (c *boolExprSimplifyChecker) removeIncDec(cur *astutil.Cursor) bool { - cmp := astcast.ToBinaryExpr(cur.Node()) - - matchOneWay := func(op token.Token, x, y *ast.BinaryExpr) bool { - if x.Op != op || astcast.ToBasicLit(x.Y).Value != "1" { - return false - } - if y.Op == op && astcast.ToBasicLit(y.Y).Value == "1" { - return false - } - return true - } - replace := func(lhsOp, rhsOp, replacement token.Token) bool { - lhs := astcast.ToBinaryExpr(cmp.X) - rhs := astcast.ToBinaryExpr(cmp.Y) - switch { - case matchOneWay(lhsOp, lhs, rhs): - cmp.X = lhs.X - cmp.Op = replacement - cur.Replace(cmp) - return true - case matchOneWay(rhsOp, rhs, lhs): - cmp.Y = rhs.X - cmp.Op = replacement - cur.Replace(cmp) - return true - default: - return false - } - } - - switch cmp.Op { - case token.GTR: - // `x > y-1` => `x >= y` - // `x+1 > y` => `x >= y` - return replace(token.ADD, token.SUB, token.GEQ) - - case token.GEQ: - // `x >= y+1` => `x > y` - // `x-1 >= y` => `x > y` - return replace(token.SUB, token.ADD, token.GTR) - - case token.LSS: - // `x < y+1` => `x <= y` - // `x-1 < y` => `x <= y` - return replace(token.SUB, token.ADD, token.LEQ) - - case token.LEQ: - // `x <= y-1` => `x < y` - // `x+1 <= y` => `x < y` - return replace(token.ADD, token.SUB, token.LSS) - - default: - return false - } -} - -func (c *boolExprSimplifyChecker) foldRanges(cur *astutil.Cursor) bool { - if c.hasFloats { // See #848 - return false - } - - e, ok := cur.Node().(*ast.BinaryExpr) - if !ok { - return false - } - lhs := astcast.ToBinaryExpr(e.X) - rhs := astcast.ToBinaryExpr(e.Y) - if !c.isSafe(lhs.X) || !c.isSafe(rhs.X) { - return false - } - if !astequal.Expr(lhs.X, rhs.X) { - return false - } - - c1, ok := c.int64val(lhs.Y) - if !ok { - return false - } - c2, ok := c.int64val(rhs.Y) - if !ok { - return false - } - - type combination struct { - lhsOp token.Token - rhsOp token.Token - rhsDiff int64 - resDelta int64 - } - match := func(comb *combination) bool { - if lhs.Op != comb.lhsOp || rhs.Op != comb.rhsOp { - return false - } - if c2-c1 != comb.rhsDiff { - return false - } - return true - } - - switch e.Op { - case token.LAND: - combTable := [...]combination{ - // `x > c && x < c+2` => `x == c+1` - {token.GTR, token.LSS, 2, 1}, - // `x >= c && x < c+1` => `x == c` - {token.GEQ, token.LSS, 1, 0}, - // `x > c && x <= c+1` => `x == c+1` - {token.GTR, token.LEQ, 1, 1}, - // `x >= c && x <= c` => `x == c` - {token.GEQ, token.LEQ, 0, 0}, - } - for i := range combTable { - comb := combTable[i] - if match(&comb) { - lhs.Op = token.EQL - v := c1 + comb.resDelta - lhs.Y.(*ast.BasicLit).Value = strconv.FormatInt(v, 10) - cur.Replace(lhs) - return true - } - } - - case token.LOR: - combTable := [...]combination{ - // `x < c || x > c` => `x != c` - {token.LSS, token.GTR, 0, 0}, - // `x <= c || x > c+1` => `x != c+1` - {token.LEQ, token.GTR, 1, 1}, - // `x < c || x >= c+1` => `x != c` - {token.LSS, token.GEQ, 1, 0}, - // `x <= c || x >= c+2` => `x != c+1` - {token.LEQ, token.GEQ, 2, 1}, - } - for i := range combTable { - comb := combTable[i] - if match(&comb) { - lhs.Op = token.NEQ - v := c1 + comb.resDelta - lhs.Y.(*ast.BasicLit).Value = strconv.FormatInt(v, 10) - cur.Replace(lhs) - return true - } - } - } - - return false -} - -func (c *boolExprSimplifyChecker) int64val(x ast.Expr) (int64, bool) { - // TODO(quasilyte): if we had types info, we could use TypesInfo.Types[x].Value, - // but since copying erases leaves us without it, only basic literals are handled. - lit, ok := x.(*ast.BasicLit) - if !ok { - return 0, false - } - v, err := strconv.ParseInt(lit.Value, 10, 64) - if err != nil { - return 0, false - } - return v, true -} - -func (c *boolExprSimplifyChecker) warn(cause, suggestion ast.Expr) { - c.SkipChilds = true - c.ctx.Warn(cause, "can simplify `%s` to `%s`", cause, suggestion) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/builtinShadowDecl_checker.go b/vendor/github.com/go-critic/go-critic/checkers/builtinShadowDecl_checker.go deleted file mode 100644 index d8be10ce9c..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/builtinShadowDecl_checker.go +++ /dev/null @@ -1,63 +0,0 @@ -package checkers - -import ( - "go/ast" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" -) - -func init() { - var info linter.CheckerInfo - info.Name = "builtinShadowDecl" - info.Tags = []string{linter.DiagnosticTag, linter.ExperimentalTag} - info.Summary = "Detects top-level declarations that shadow the predeclared identifiers" - info.Before = `type int struct {}` - info.After = `type myInt struct {}` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return &builtinShadowDeclChecker{ctx: ctx}, nil - }) -} - -type builtinShadowDeclChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext -} - -func (c *builtinShadowDeclChecker) WalkFile(f *ast.File) { - for _, decl := range f.Decls { - switch decl := decl.(type) { - case *ast.FuncDecl: - // Don't check methods. They can shadow anything safely. - if decl.Recv == nil { - c.checkName(decl.Name) - } - case *ast.GenDecl: - c.visitGenDecl(decl) - } - } -} - -func (c *builtinShadowDeclChecker) visitGenDecl(decl *ast.GenDecl) { - for _, spec := range decl.Specs { - switch spec := spec.(type) { - case *ast.ValueSpec: - for _, name := range spec.Names { - c.checkName(name) - } - case *ast.TypeSpec: - c.checkName(spec.Name) - } - } -} - -func (c *builtinShadowDeclChecker) checkName(name *ast.Ident) { - if isBuiltin(name.Name) { - c.warn(name) - } -} - -func (c *builtinShadowDeclChecker) warn(ident *ast.Ident) { - c.ctx.Warn(ident, "shadowing of predeclared identifier: %s", ident) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/builtinShadow_checker.go b/vendor/github.com/go-critic/go-critic/checkers/builtinShadow_checker.go deleted file mode 100644 index 0b4b7bafb8..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/builtinShadow_checker.go +++ /dev/null @@ -1,36 +0,0 @@ -package checkers - -import ( - "go/ast" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" -) - -func init() { - var info linter.CheckerInfo - info.Name = "builtinShadow" - info.Tags = []string{linter.StyleTag, linter.OpinionatedTag} - info.Summary = "Detects when predeclared identifiers are shadowed in assignments" - info.Before = `len := 10` - info.After = `length := 10` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForLocalDef(&builtinShadowChecker{ctx: ctx}, ctx.TypesInfo), nil - }) -} - -type builtinShadowChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext -} - -func (c *builtinShadowChecker) VisitLocalDef(name astwalk.Name, _ ast.Expr) { - if isBuiltin(name.ID.Name) { - c.warn(name.ID) - } -} - -func (c *builtinShadowChecker) warn(ident *ast.Ident) { - c.ctx.Warn(ident, "shadowing of predeclared identifier: %s", ident) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/captLocal_checker.go b/vendor/github.com/go-critic/go-critic/checkers/captLocal_checker.go deleted file mode 100644 index b31a6f7fd3..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/captLocal_checker.go +++ /dev/null @@ -1,49 +0,0 @@ -package checkers - -import ( - "go/ast" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" -) - -func init() { - var info linter.CheckerInfo - info.Name = "captLocal" - info.Tags = []string{linter.StyleTag} - info.Params = linter.CheckerParams{ - "paramsOnly": { - Value: true, - Usage: "whether to restrict checker to params only", - }, - } - info.Summary = "Detects capitalized names for local variables" - info.Before = `func f(IN int, OUT *int) (ERR error) {}` - info.After = `func f(in int, out *int) (err error) {}` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - c := &captLocalChecker{ctx: ctx} - c.paramsOnly = info.Params.Bool("paramsOnly") - return astwalk.WalkerForLocalDef(c, ctx.TypesInfo), nil - }) -} - -type captLocalChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext - - paramsOnly bool -} - -func (c *captLocalChecker) VisitLocalDef(def astwalk.Name, _ ast.Expr) { - if c.paramsOnly && def.Kind != astwalk.NameParam { - return - } - if ast.IsExported(def.ID.Name) { - c.warn(def.ID) - } -} - -func (c *captLocalChecker) warn(id ast.Node) { - c.ctx.Warn(id, "`%s' should not be capitalized", id) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/caseOrder_checker.go b/vendor/github.com/go-critic/go-critic/checkers/caseOrder_checker.go deleted file mode 100644 index 345274f1c8..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/caseOrder_checker.go +++ /dev/null @@ -1,88 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/types" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" -) - -func init() { - var info linter.CheckerInfo - info.Name = "caseOrder" - info.Tags = []string{linter.DiagnosticTag} - info.Summary = "Detects erroneous case order inside switch statements" - info.Before = ` -switch x.(type) { -case ast.Expr: - fmt.Println("expr") -case *ast.BasicLit: - fmt.Println("basic lit") // Never executed -}` - info.After = ` -switch x.(type) { -case *ast.BasicLit: - fmt.Println("basic lit") // Now reachable -case ast.Expr: - fmt.Println("expr") -}` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForStmt(&caseOrderChecker{ctx: ctx}), nil - }) -} - -type caseOrderChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext -} - -func (c *caseOrderChecker) VisitStmt(stmt ast.Stmt) { - switch stmt := stmt.(type) { - case *ast.TypeSwitchStmt: - c.checkTypeSwitch(stmt) - case *ast.SwitchStmt: - c.checkSwitch(stmt) - } -} - -func (c *caseOrderChecker) checkTypeSwitch(s *ast.TypeSwitchStmt) { - type ifaceType struct { - node ast.Node - typ *types.Interface - } - var ifaces []ifaceType // Interfaces seen so far - for _, cc := range s.Body.List { - cc := cc.(*ast.CaseClause) - for _, x := range cc.List { - typ := c.ctx.TypeOf(x) - if typ == linter.UnknownType { - c.warnUnknownType(cc, x) - return - } - for _, iface := range ifaces { - if types.Implements(typ, iface.typ) { - c.warnTypeSwitch(cc, x, iface.node) - break - } - } - if iface, ok := typ.Underlying().(*types.Interface); ok { - ifaces = append(ifaces, ifaceType{node: x, typ: iface}) - } - } - } -} - -func (c *caseOrderChecker) warnTypeSwitch(cause, concrete, iface ast.Node) { - c.ctx.Warn(cause, "case %s must go before the %s case", concrete, iface) -} - -func (c *caseOrderChecker) warnUnknownType(cause, concrete ast.Node) { - c.ctx.Warn(cause, "type is not defined %s", concrete) -} - -func (c *caseOrderChecker) checkSwitch(_ *ast.SwitchStmt) { - // TODO(quasilyte): can handle expression cases that overlap. - // Cases that have narrower value range should go before wider ones. -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/checkers.go b/vendor/github.com/go-critic/go-critic/checkers/checkers.go deleted file mode 100644 index 751c71501e..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/checkers.go +++ /dev/null @@ -1,19 +0,0 @@ -// Package checkers is a go-critic linter main checkers collection. -package checkers - -import ( - "os" - - "github.com/go-critic/go-critic/linter" -) - -var collection = &linter.CheckerCollection{ - URL: "https://github.com/go-critic/go-critic/checkers", -} - -var debug = func() func() bool { - v := os.Getenv("DEBUG") != "" - return func() bool { - return v - } -}() diff --git a/vendor/github.com/go-critic/go-critic/checkers/codegenComment_checker.go b/vendor/github.com/go-critic/go-critic/checkers/codegenComment_checker.go deleted file mode 100644 index 6eeb0bb5db..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/codegenComment_checker.go +++ /dev/null @@ -1,61 +0,0 @@ -package checkers - -import ( - "go/ast" - "regexp" - "strings" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" -) - -func init() { - var info linter.CheckerInfo - info.Name = "codegenComment" - info.Tags = []string{linter.DiagnosticTag} - info.Summary = "Detects malformed 'code generated' file comments" - info.Before = `// This file was automatically generated by foogen` - info.After = `// Code generated by foogen. DO NOT EDIT.` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - patterns := []string{ - "this (?:file|code) (?:was|is) auto(?:matically)? generated", - "this (?:file|code) (?:was|is) generated automatically", - "this (?:file|code) (?:was|is) generated by", - "this (?:file|code) (?:was|is) (?:auto(?:matically)? )?generated", - "this (?:file|code) (?:was|is) generated", - "code in this file (?:was|is) auto(?:matically)? generated", - "generated (?:file|code) - do not edit", - // TODO(quasilyte): more of these. - } - re := regexp.MustCompile("(?i)" + strings.Join(patterns, "|")) - return &codegenCommentChecker{ - ctx: ctx, - badCommentRE: re, - }, nil - }) -} - -type codegenCommentChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext - - badCommentRE *regexp.Regexp -} - -func (c *codegenCommentChecker) WalkFile(f *ast.File) { - if f.Doc == nil { - return - } - - for _, comment := range f.Doc.List { - if c.badCommentRE.MatchString(comment.Text) { - c.warn(comment) - return - } - } -} - -func (c *codegenCommentChecker) warn(cause ast.Node) { - c.ctx.Warn(cause, "comment should match `Code generated .* DO NOT EDIT.` regexp") -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/commentFormatting_checker.go b/vendor/github.com/go-critic/go-critic/checkers/commentFormatting_checker.go deleted file mode 100644 index b834158eca..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/commentFormatting_checker.go +++ /dev/null @@ -1,123 +0,0 @@ -package checkers - -import ( - "go/ast" - "regexp" - "strings" - "unicode" - "unicode/utf8" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" -) - -func init() { - var info linter.CheckerInfo - info.Name = "commentFormatting" - info.Tags = []string{linter.StyleTag} - info.Summary = "Detects comments with non-idiomatic formatting" - info.Before = `//This is a comment` - info.After = `// This is a comment` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - regexpPatterns := []*regexp.Regexp{ - regexp.MustCompile(`^//[\w-]+:.*$`), // e.g.: key: value - } - equalPatterns := []string{ - "//nolint", - } - parts := []string{ - "//go:generate ", // e.g.: go:generate value - "//line /", // e.g.: line /path/to/file:123 - "//nolint ", // e.g.: nolint - "//noinspection ", // e.g.: noinspection ALL, some GoLand and friends versions - "//region", // e.g.: region awawa, used by GoLand and friends for custom folding - "//endregion", // e.g.: endregion awawa or endregion, closes GoLand regions - "// or , used by VSCode for custom folding - "//", // e.g.: , closes VSCode regions - "//export ", // e.g.: export Foo - "///", // e.g.: vertical breaker ///////////// - "//+", - "//#", - "//-", - "//!", - } - - return astwalk.WalkerForComment(&commentFormattingChecker{ - ctx: ctx, - partPatterns: parts, - equalPatterns: equalPatterns, - regexpPatterns: regexpPatterns, - }), nil - }) -} - -type commentFormattingChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext - - partPatterns []string - equalPatterns []string - regexpPatterns []*regexp.Regexp -} - -func (c *commentFormattingChecker) VisitComment(cg *ast.CommentGroup) { - if strings.HasPrefix(cg.List[0].Text, "/*") { - return - } - -outerLoop: - for _, comment := range cg.List { - commentLen := len(comment.Text) - if commentLen <= len("// ") { - continue - } - - for _, p := range c.partPatterns { - if commentLen < len(p) { - continue - } - - if strings.EqualFold(comment.Text[:len(p)], p) { - continue outerLoop - } - } - - for _, p := range c.equalPatterns { - if strings.EqualFold(comment.Text, p) { - continue outerLoop - } - } - - for _, p := range c.regexpPatterns { - if p.MatchString(comment.Text) { - continue outerLoop - } - } - - // Make a decision based on a first comment text rune. - r, _ := utf8.DecodeRuneInString(comment.Text[len("//"):]) - if !c.specialChar(r) && !unicode.IsSpace(r) { - c.warn(comment) - return - } - } -} - -func (c *commentFormattingChecker) specialChar(r rune) bool { - // Permitted list to avoid false-positives. - switch r { - case '+', '-', '#', '!': - return true - default: - return false - } -} - -func (c *commentFormattingChecker) warn(comment *ast.Comment) { - c.ctx.WarnFixable(comment, linter.QuickFix{ - From: comment.Pos(), - To: comment.End(), - Replacement: []byte(strings.Replace(comment.Text, "//", "// ", 1)), - }, "put a space between `//` and comment text") -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/commentedOutCode_checker.go b/vendor/github.com/go-critic/go-critic/checkers/commentedOutCode_checker.go deleted file mode 100644 index 788355d7fc..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/commentedOutCode_checker.go +++ /dev/null @@ -1,169 +0,0 @@ -package checkers - -import ( - "fmt" - "go/ast" - "go/token" - "regexp" - "strings" - "unicode/utf8" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" - - "github.com/go-toolsmith/strparse" -) - -func init() { - var info linter.CheckerInfo - info.Name = "commentedOutCode" - info.Tags = []string{linter.DiagnosticTag, linter.ExperimentalTag} - info.Summary = "Detects commented-out code inside function bodies" - info.Params = linter.CheckerParams{ - "minLength": { - Value: 15, - Usage: "min length of the comment that triggers a warning", - }, - } - info.Before = ` -// fmt.Println("Debugging hard") -foo(1, 2)` - info.After = `foo(1, 2)` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForLocalComment(&commentedOutCodeChecker{ - ctx: ctx, - notQuiteFuncCall: regexp.MustCompile(`\w+\s+\([^)]*\)\s*$`), - minLength: info.Params.Int("minLength"), - }), nil - }) -} - -type commentedOutCodeChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext - fn *ast.FuncDecl - - notQuiteFuncCall *regexp.Regexp - minLength int -} - -func (c *commentedOutCodeChecker) EnterFunc(fn *ast.FuncDecl) bool { - c.fn = fn // Need to store current function inside checker context - return fn.Body != nil -} - -func (c *commentedOutCodeChecker) VisitLocalComment(cg *ast.CommentGroup) { - s := cg.Text() // Collect text once - - // We do multiple heuristics to avoid false positives. - // Many things can be improved here. - - markers := []string{ - "TODO", // TODO comments with code are permitted. - - // "http://" is interpreted as a label with comment. - // There are other protocols we might want to include. - "http://", - "https://", - - "e.g. ", // Clearly not a "selector expr" (mostly due to extra space) - } - for _, m := range markers { - if strings.Contains(s, m) { - return - } - } - - // Some very short comment that can be skipped. - // Usually triggering on these results in false positive. - // Unless there is a very popular call like print/println. - cond := utf8.RuneCountInString(s) < c.minLength && - !strings.Contains(s, "print") && - !strings.Contains(s, "fmt.") && - !strings.Contains(s, "log.") - if cond { - return - } - - // Almost looks like a commented-out function call, - // but there is a whitespace between function name and - // parameters list. Skip these to avoid false positives. - if c.notQuiteFuncCall.MatchString(s) { - return - } - - if c.isExampleOutputComment(s) { - return - } - - stmt := strparse.Stmt(s) - - if c.isPermittedStmt(stmt) { - return - } - - if stmt != strparse.BadStmt { - c.warn(cg) - return - } - - // Don't try to parse one-liner as block statement - if len(cg.List) == 1 && !strings.Contains(s, "\n") { - return - } - - // Add braces to make block statement from - // multiple statements. - stmt = strparse.Stmt(fmt.Sprintf("{ %s }", s)) - - if stmt, ok := stmt.(*ast.BlockStmt); ok && len(stmt.List) != 0 { - c.warn(cg) - } -} - -// An example output comment can be one of the following: -// -// Output: some output -// -// or -// -// Output: -// some output -// -// See https://go.dev/blog/examples -func (c *commentedOutCodeChecker) isExampleOutputComment(s string) bool { - return isExampleTestFunc(c.fn) && strings.Contains(s, "Output:") -} - -func (c *commentedOutCodeChecker) isPermittedStmt(stmt ast.Stmt) bool { - switch stmt := stmt.(type) { - case *ast.ExprStmt: - return c.isPermittedExpr(stmt.X) - case *ast.LabeledStmt: - return c.isPermittedStmt(stmt.Stmt) - case *ast.DeclStmt: - decl := stmt.Decl.(*ast.GenDecl) - return decl.Tok == token.TYPE - default: - return false - } -} - -func (c *commentedOutCodeChecker) isPermittedExpr(x ast.Expr) bool { - // Permit anything except expressions that can be used - // with complete result discarding. - switch x := x.(type) { - case *ast.CallExpr: - return false - case *ast.UnaryExpr: - // "<-" channel receive is not permitted. - return x.Op != token.ARROW - default: - return true - } -} - -func (c *commentedOutCodeChecker) warn(cause ast.Node) { - c.ctx.Warn(cause, "may want to remove commented-out code") -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/commentedOutImport_checker.go b/vendor/github.com/go-critic/go-critic/checkers/commentedOutImport_checker.go deleted file mode 100644 index e0855da812..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/commentedOutImport_checker.go +++ /dev/null @@ -1,76 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/token" - "regexp" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" -) - -func init() { - var info linter.CheckerInfo - info.Name = "commentedOutImport" - info.Tags = []string{linter.StyleTag, linter.ExperimentalTag} - info.Summary = "Detects commented-out imports" - info.Before = ` -import ( - "fmt" - //"os" -)` - info.After = ` -import ( - "fmt" -)` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - const pattern = `(?m)^(?://|/\*)?\s*"([a-zA-Z0-9_/]+)"\s*(?:\*/)?$` - return &commentedOutImportChecker{ - ctx: ctx, - importStringRE: regexp.MustCompile(pattern), - }, nil - }) -} - -type commentedOutImportChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext - - importStringRE *regexp.Regexp -} - -func (c *commentedOutImportChecker) WalkFile(f *ast.File) { - // TODO(quasilyte): handle commented-out import spec, - // for example: // import "errors". - - for _, decl := range f.Decls { - decl, ok := decl.(*ast.GenDecl) - if !ok || decl.Tok != token.IMPORT { - // Import decls can only be in the beginning of the file. - // If we've met some other decl, there will be no more - // import decls. - break - } - - // Find comments inside this import decl span. - for _, cg := range f.Comments { - if cg.Pos() > decl.Rparen { - break // Below the decl, stop. - } - if cg.Pos() < decl.Lparen { - continue // Before the decl, skip. - } - - for _, comment := range cg.List { - for _, m := range c.importStringRE.FindAllStringSubmatch(comment.Text, -1) { - c.warn(comment, m[1]) - } - } - } - } -} - -func (c *commentedOutImportChecker) warn(cause ast.Node, path string) { - c.ctx.Warn(cause, "remove commented-out %q import", path) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/defaultCaseOrder_checker.go b/vendor/github.com/go-critic/go-critic/checkers/defaultCaseOrder_checker.go deleted file mode 100644 index cdebaef987..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/defaultCaseOrder_checker.go +++ /dev/null @@ -1,65 +0,0 @@ -package checkers - -import ( - "go/ast" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" -) - -func init() { - var info linter.CheckerInfo - info.Name = "defaultCaseOrder" - info.Tags = []string{linter.StyleTag} - info.Summary = "Detects when default case in switch isn't on 1st or last position" - info.Before = ` -switch { -case x > y: - // ... -default: // <- not the best position - // ... -case x == 10: - // ... -}` - info.After = ` -switch { -case x > y: - // ... -case x == 10: - // ... -default: // <- last case (could also be the first one) - // ... -}` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForStmt(&defaultCaseOrderChecker{ctx: ctx}), nil - }) -} - -type defaultCaseOrderChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext -} - -func (c *defaultCaseOrderChecker) VisitStmt(stmt ast.Stmt) { - swtch, ok := stmt.(*ast.SwitchStmt) - if !ok { - return - } - for i, stmt := range swtch.Body.List { - caseStmt, ok := stmt.(*ast.CaseClause) - if !ok { - continue - } - // is `default` case - if caseStmt.List == nil { - if i != 0 && i != len(swtch.Body.List)-1 { - c.warn(caseStmt) - } - } - } -} - -func (c *defaultCaseOrderChecker) warn(cause *ast.CaseClause) { - c.ctx.Warn(cause, "consider to make `default` case as first or as last case") -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/deferInLoop_checker.go b/vendor/github.com/go-critic/go-critic/checkers/deferInLoop_checker.go deleted file mode 100644 index 37c80c864a..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/deferInLoop_checker.go +++ /dev/null @@ -1,70 +0,0 @@ -package checkers - -import ( - "go/ast" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" -) - -func init() { - var info linter.CheckerInfo - info.Name = "deferInLoop" - info.Tags = []string{linter.DiagnosticTag, linter.ExperimentalTag} - info.Summary = "Detects loops inside functions that use defer" - info.Before = ` -for _, filename := range []string{"foo", "bar"} { - f, err := os.Open(filename) - - defer f.Close() -} -` - info.After = ` -func process(filename string) { - f, err := os.Open(filename) - - defer f.Close() -} -/* ... */ -for _, filename := range []string{"foo", "bar"} { - process(filename) -}` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForFuncDecl(&deferInLoopChecker{ctx: ctx}), nil - }) -} - -type deferInLoopChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext - inFor bool -} - -func (c *deferInLoopChecker) VisitFuncDecl(fn *ast.FuncDecl) { - ast.Inspect(fn.Body, c.traversalFunc) -} - -func (c deferInLoopChecker) traversalFunc(cur ast.Node) bool { - switch n := cur.(type) { - case *ast.DeferStmt: - if c.inFor { - c.warn(n) - } - case *ast.RangeStmt, *ast.ForStmt: - if !c.inFor { - ast.Inspect(cur, deferInLoopChecker{ctx: c.ctx, inFor: true}.traversalFunc) - return false - } - case *ast.FuncLit: - ast.Inspect(n.Body, deferInLoopChecker{ctx: c.ctx, inFor: false}.traversalFunc) - return false - case nil: - return false - } - return true -} - -func (c *deferInLoopChecker) warn(cause *ast.DeferStmt) { - c.ctx.Warn(cause, "Possible resource leak, 'defer' is called in the 'for' loop") -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/deprecatedComment_checker.go b/vendor/github.com/go-critic/go-critic/checkers/deprecatedComment_checker.go deleted file mode 100644 index bb41d478ea..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/deprecatedComment_checker.go +++ /dev/null @@ -1,173 +0,0 @@ -package checkers - -import ( - "go/ast" - "strings" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" -) - -const deprecatedPrefix = "Deprecated: " - -func init() { - var info linter.CheckerInfo - info.Name = "deprecatedComment" - info.Tags = []string{linter.DiagnosticTag} - info.Summary = "Detects malformed 'deprecated' doc-comments" - info.Before = ` -// deprecated, use FuncNew instead -func FuncOld() int` - info.After = ` -// Deprecated: use FuncNew instead -func FuncOld() int` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - c := &deprecatedCommentChecker{ctx: ctx} - - c.commonPatterns = []string{ - "this type is deprecated", - "this function is deprecated", - "[[deprecated]]", - "note: deprecated", - "deprecated in", - "deprecated. use", - "deprecated! use", - "deprecated use", - // TODO(quasilyte): more of these? - } - - // TODO(quasilyte): may want to generate this list programmatically. - // - // TODO(quasilyte): currently it only handles a single missing letter. - // Might want to handle other kinds of common misspell/typo kinds. - c.commonTypos = []string{ - "Dprecated: ", - "Derecated: ", - "Depecated: ", - "Depekated: ", - "Deprcated: ", - "Depreated: ", - "Deprected: ", - "Deprecaed: ", - "Deprecatd: ", - "Deprecate: ", - "Derpecate: ", - "Derpecated: ", - "Depreacted: ", - } - for i := range c.commonTypos { - c.commonTypos[i] = strings.ToUpper(c.commonTypos[i]) - } - - return astwalk.WalkerForDocComment(c), nil - }) -} - -type deprecatedCommentChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext - - commonPatterns []string - commonTypos []string -} - -func (c *deprecatedCommentChecker) VisitDocComment(doc *ast.CommentGroup) { - // There are 3 accepted forms of deprecation comments: - // - // 1. inline, that can't be handled with a DocCommentVisitor. - // Note that "Deprecated: " may not even be the comment prefix there. - // Example: "The line number in the input. Deprecated: Kept for compatibility." - // TODO(quasilyte): fix it. - // - // 2. Longer form-1. It's a doc-comment that only contains "deprecation" notice. - // - // 3. Like form-2, but may also include doc-comment text. - // Distinguished by an empty line. - // - // See https://github.com/golang/go/issues/10909#issuecomment-136492606. - // - // It's desirable to see how people make mistakes with the format, - // this is why there is currently no special treatment for these cases. - // TODO(quasilyte): do more audits and grow the negative tests suite. - // - // TODO(quasilyte): there are also multi-line deprecation comments. - - // prev stores the previous line after it was trimmed. - // It's used to check whether the deprecation prefix is at the beginning of a new paragraph. - var prev string - - for _, comment := range doc.List { - if strings.HasPrefix(comment.Text, "/*") { - // TODO(quasilyte): handle multi-line doc comments. - continue - } - rawLine := strings.TrimPrefix(comment.Text, "//") - l := strings.TrimSpace(rawLine) - if len(rawLine) < len(deprecatedPrefix) { - prev = l - continue - } - - // Check whether someone messed up with a prefix casing. - upcase := strings.ToUpper(l) - if strings.HasPrefix(upcase, "DEPRECATED: ") && !strings.HasPrefix(l, deprecatedPrefix) { - c.warnCasing(comment, l) - return - } - - // Check is someone used comma instead of a colon. - if strings.HasPrefix(l, "Deprecated, ") { - c.warnComma(comment) - return - } - - // Check for other commonly used patterns. - for _, pat := range c.commonPatterns { - if len(l) < len(pat) { - continue - } - - if strings.EqualFold(l[:len(pat)], pat) { - c.warnPattern(comment) - return - } - } - - // Detect some simple typos. - for _, prefixWithTypo := range c.commonTypos { - if strings.HasPrefix(upcase, prefixWithTypo) { - c.warnTypo(comment, l) - return - } - } - - if strings.HasPrefix(l, deprecatedPrefix) && prev != "" { - c.warnParagraph(comment) - return - } - prev = l - } -} - -func (c *deprecatedCommentChecker) warnCasing(cause ast.Node, line string) { - prefix := line[:len("DEPRECATED: ")] - c.ctx.Warn(cause, "use `Deprecated: ` (note the casing) instead of `%s`", prefix) -} - -func (c *deprecatedCommentChecker) warnPattern(cause ast.Node) { - c.ctx.Warn(cause, "the proper format is `Deprecated: `") -} - -func (c *deprecatedCommentChecker) warnComma(cause ast.Node) { - c.ctx.Warn(cause, "use `:` instead of `,` in `Deprecated, `") -} - -func (c *deprecatedCommentChecker) warnTypo(cause ast.Node, line string) { - word := strings.Split(line, ":")[0] - c.ctx.Warn(cause, "typo in `%s`; should be `Deprecated`", word) -} - -func (c *deprecatedCommentChecker) warnParagraph(cause ast.Node) { - c.ctx.Warn(cause, "`Deprecated: ` notices should be in a dedicated paragraph, separated from the rest") -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/docStub_checker.go b/vendor/github.com/go-critic/go-critic/checkers/docStub_checker.go deleted file mode 100644 index aa23de42c4..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/docStub_checker.go +++ /dev/null @@ -1,95 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/token" - "regexp" - "strings" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" -) - -func init() { - var info linter.CheckerInfo - info.Name = "docStub" - info.Tags = []string{linter.StyleTag, linter.ExperimentalTag} - info.Summary = "Detects comments that silence go lint complaints about doc-comment" - info.Before = ` -// Foo ... -func Foo() { -}` - info.After = ` -// (A) - remove the doc-comment stub -func Foo() {} -// (B) - replace it with meaningful comment -// Foo is a demonstration-only function. -func Foo() {}` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - re := `(?i)^\.\.\.$|^\.$|^xxx\.?$|^whatever\.?$` - c := &docStubChecker{ - ctx: ctx, - stubCommentRE: regexp.MustCompile(re), - } - return c, nil - }) -} - -type docStubChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext - - stubCommentRE *regexp.Regexp -} - -func (c *docStubChecker) WalkFile(f *ast.File) { - for _, decl := range f.Decls { - switch decl := decl.(type) { - case *ast.FuncDecl: - c.visitDoc(decl, decl.Name, decl.Doc, false) - case *ast.GenDecl: - if decl.Tok != token.TYPE { - continue - } - if len(decl.Specs) == 1 { - spec := decl.Specs[0].(*ast.TypeSpec) - // Only 1 spec, use doc from the decl itself. - c.visitDoc(spec, spec.Name, decl.Doc, true) - } - // N specs, use per-spec doc. - for _, spec := range decl.Specs { - spec := spec.(*ast.TypeSpec) - c.visitDoc(spec, spec.Name, spec.Doc, true) - } - } - } -} - -func (c *docStubChecker) visitDoc(decl ast.Node, sym *ast.Ident, doc *ast.CommentGroup, article bool) { - if !sym.IsExported() || doc == nil { - return - } - line := strings.TrimSpace(doc.List[0].Text[len("//"):]) - if article { - // Skip optional article. - for _, a := range []string{"The ", "An ", "A "} { - if strings.HasPrefix(line, a) { - line = line[len(a):] - break - } - } - } - if !strings.HasPrefix(line, sym.Name) { - return - } - line = strings.TrimSpace(line[len(sym.Name):]) - // Now try to detect the "stub" part. - if c.stubCommentRE.MatchString(line) { - c.warn(decl) - } -} - -func (c *docStubChecker) warn(cause ast.Node) { - c.ctx.Warn(cause, "silencing go lint doc-comment warnings is unadvised") -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/dupBranchBody_checker.go b/vendor/github.com/go-critic/go-critic/checkers/dupBranchBody_checker.go deleted file mode 100644 index c4f0183878..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/dupBranchBody_checker.go +++ /dev/null @@ -1,59 +0,0 @@ -package checkers - -import ( - "go/ast" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" - - "github.com/go-toolsmith/astequal" -) - -func init() { - var info linter.CheckerInfo - info.Name = "dupBranchBody" - info.Tags = []string{linter.DiagnosticTag} - info.Summary = "Detects duplicated branch bodies inside conditional statements" - info.Before = ` -if cond { - println("cond=true") -} else { - println("cond=true") -}` - info.After = ` -if cond { - println("cond=true") -} else { - println("cond=false") -}` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForStmt(&dupBranchBodyChecker{ctx: ctx}), nil - }) -} - -type dupBranchBodyChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext -} - -func (c *dupBranchBodyChecker) VisitStmt(stmt ast.Stmt) { - // TODO(quasilyte): extend to check switch statements as well. - // Should be very careful with type switches. - - if stmt, ok := stmt.(*ast.IfStmt); ok { - c.checkIf(stmt) - } -} - -func (c *dupBranchBodyChecker) checkIf(stmt *ast.IfStmt) { - thenBody := stmt.Body - elseBody, ok := stmt.Else.(*ast.BlockStmt) - if ok && astequal.Stmt(thenBody, elseBody) { - c.warnIf(stmt) - } -} - -func (c *dupBranchBodyChecker) warnIf(cause ast.Node) { - c.ctx.Warn(cause, "both branches in if statement have same body") -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/dupCase_checker.go b/vendor/github.com/go-critic/go-critic/checkers/dupCase_checker.go deleted file mode 100644 index 381bad68b8..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/dupCase_checker.go +++ /dev/null @@ -1,70 +0,0 @@ -package checkers - -import ( - "go/ast" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/checkers/internal/lintutil" - "github.com/go-critic/go-critic/linter" -) - -func init() { - var info linter.CheckerInfo - info.Name = "dupCase" - info.Tags = []string{linter.DiagnosticTag} - info.Summary = "Detects duplicated case clauses inside switch or select statements" - info.Before = ` -switch x { -case ys[0], ys[1], ys[2], ys[0], ys[4]: -}` - info.After = ` -switch x { -case ys[0], ys[1], ys[2], ys[3], ys[4]: -}` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForStmt(&dupCaseChecker{ctx: ctx}), nil - }) -} - -type dupCaseChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext - - astSet lintutil.AstSet -} - -func (c *dupCaseChecker) VisitStmt(stmt ast.Stmt) { - switch stmt := stmt.(type) { - case *ast.SwitchStmt: - c.checkSwitch(stmt) - case *ast.SelectStmt: - c.checkSelect(stmt) - } -} - -func (c *dupCaseChecker) checkSwitch(stmt *ast.SwitchStmt) { - c.astSet.Clear() - for i := range stmt.Body.List { - cc := stmt.Body.List[i].(*ast.CaseClause) - for _, x := range cc.List { - if !c.astSet.Insert(x) { - c.warn(x) - } - } - } -} - -func (c *dupCaseChecker) checkSelect(stmt *ast.SelectStmt) { - c.astSet.Clear() - for i := range stmt.Body.List { - x := stmt.Body.List[i].(*ast.CommClause).Comm - if !c.astSet.Insert(x) { - c.warn(x) - } - } -} - -func (c *dupCaseChecker) warn(cause ast.Node) { - c.ctx.Warn(cause, "'case %s' is duplicated", cause) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/dupImports_checker.go b/vendor/github.com/go-critic/go-critic/checkers/dupImports_checker.go deleted file mode 100644 index ed674eb85c..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/dupImports_checker.go +++ /dev/null @@ -1,63 +0,0 @@ -package checkers - -import ( - "fmt" - "go/ast" - - "github.com/go-critic/go-critic/linter" -) - -func init() { - var info linter.CheckerInfo - info.Name = "dupImport" - info.Tags = []string{linter.StyleTag, linter.ExperimentalTag} - info.Summary = "Detects multiple imports of the same package under different aliases" - info.Before = ` -import ( - "fmt" - printing "fmt" // Imported the second time -)` - info.After = ` -import( - "fmt" -)` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return &dupImportChecker{ctx: ctx}, nil - }) -} - -type dupImportChecker struct { - ctx *linter.CheckerContext -} - -func (c *dupImportChecker) WalkFile(f *ast.File) { - imports := make(map[string][]*ast.ImportSpec) - for _, importDcl := range f.Imports { - pkg := importDcl.Path.Value - imports[pkg] = append(imports[pkg], importDcl) - } - - for _, importList := range imports { - if len(importList) == 1 { - continue - } - c.warn(importList) - } -} - -func (c *dupImportChecker) warn(importList []*ast.ImportSpec) { - msg := fmt.Sprintf("package is imported %d times under different aliases on lines", len(importList)) - for idx, importDcl := range importList { - switch { - case idx == len(importList)-1: - msg += " and" - case idx > 0: - msg += "," - } - msg += fmt.Sprintf(" %d", c.ctx.FileSet.Position(importDcl.Pos()).Line) - } - for _, importDcl := range importList { - c.ctx.Warn(importDcl, msg) - } -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/dupOption_checker.go b/vendor/github.com/go-critic/go-critic/checkers/dupOption_checker.go deleted file mode 100644 index 5e7eeda169..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/dupOption_checker.go +++ /dev/null @@ -1,118 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/token" - "go/types" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" - "github.com/go-toolsmith/astcast" - "github.com/go-toolsmith/astfmt" -) - -func init() { - var info linter.CheckerInfo - info.Name = "dupOption" - info.Tags = []string{linter.DiagnosticTag, linter.ExperimentalTag} - info.Summary = "Detects duplicated option function arguments in variadic function calls" - info.Before = `doSomething(name, - withWidth(w), - withHeight(h), - withWidth(w), -)` - info.After = `doSomething(name, - withWidth(w), - withHeight(h), -)` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - c := &dupOptionChecker{ctx: ctx} - return astwalk.WalkerForExpr(c), nil - }) -} - -type dupOptionChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext -} - -func (c *dupOptionChecker) VisitExpr(expr ast.Expr) { - call := astcast.ToCallExpr(expr) - variadicArgs, argType := c.getVariadicArgs(call) - if len(variadicArgs) == 0 { - return - } - - if !c.isOptionType(argType) { - return - } - - dupArgs := c.findDupArgs(variadicArgs) - for _, arg := range dupArgs { - c.warn(arg) - } -} - -func (c *dupOptionChecker) getVariadicArgs(call *ast.CallExpr) ([]ast.Expr, types.Type) { - if len(call.Args) == 0 { - return nil, nil - } - - // skip for someFunc(a, b ...) - if call.Ellipsis != token.NoPos { - return nil, nil - } - - funType := c.ctx.TypeOf(call.Fun) - sign, ok := funType.(*types.Signature) - if !ok || !sign.Variadic() { - return nil, nil - } - - last := sign.Params().Len() - 1 - sliceType, ok := sign.Params().At(last).Type().(*types.Slice) - if !ok { - return nil, nil - } - - if last > len(call.Args) { - return nil, nil - } - - argType := sliceType.Elem() - return call.Args[last:], argType -} - -func (c *dupOptionChecker) isOptionType(typeInfo types.Type) bool { - typeInfo = typeInfo.Underlying() - - sign, ok := typeInfo.(*types.Signature) - if !ok { - return false - } - - if sign.Params().Len() == 0 { - return false - } - - return true -} - -func (c *dupOptionChecker) findDupArgs(args []ast.Expr) []ast.Expr { - codeMap := make(map[string]bool) - dupArgs := make([]ast.Expr, 0) - for _, arg := range args { - code := astfmt.Sprint(arg) - if codeMap[code] { - dupArgs = append(dupArgs, arg) - continue - } - codeMap[code] = true - } - return dupArgs -} - -func (c *dupOptionChecker) warn(arg ast.Node) { - c.ctx.Warn(arg, "function argument `%s` is duplicated", arg) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/dupSubExpr_checker.go b/vendor/github.com/go-critic/go-critic/checkers/dupSubExpr_checker.go deleted file mode 100644 index 9ab75945cd..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/dupSubExpr_checker.go +++ /dev/null @@ -1,103 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/token" - "go/types" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" - - "github.com/go-toolsmith/astequal" - "github.com/go-toolsmith/typep" -) - -func init() { - var info linter.CheckerInfo - info.Name = "dupSubExpr" - info.Tags = []string{linter.DiagnosticTag} - info.Summary = "Detects suspicious duplicated sub-expressions" - info.Before = ` -sort.Slice(xs, func(i, j int) bool { - return xs[i].v < xs[i].v // Duplicated index -})` - info.After = ` -sort.Slice(xs, func(i, j int) bool { - return xs[i].v < xs[j].v -})` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - c := &dupSubExprChecker{ctx: ctx} - - ops := []struct { - op token.Token - float bool // Whether float args require special care - }{ - {op: token.LOR}, // x || x - {op: token.LAND}, // x && x - {op: token.OR}, // x | x - {op: token.AND}, // x & x - {op: token.XOR}, // x ^ x - {op: token.LSS}, // x < x - {op: token.GTR}, // x > x - {op: token.AND_NOT}, // x &^ x - {op: token.REM}, // x % x - - {op: token.EQL, float: true}, // x == x - {op: token.NEQ, float: true}, // x != x - {op: token.LEQ, float: true}, // x <= x - {op: token.GEQ, float: true}, // x >= x - {op: token.QUO, float: true}, // x / x - {op: token.SUB, float: true}, // x - x - } - - c.opSet = make(map[token.Token]bool) - c.floatOpsSet = make(map[token.Token]bool) - for _, opInfo := range ops { - c.opSet[opInfo.op] = true - if opInfo.float { - c.floatOpsSet[opInfo.op] = true - } - } - - return astwalk.WalkerForExpr(c), nil - }) -} - -type dupSubExprChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext - - // opSet is a set of binary operations that do not make - // sense with duplicated (same) RHS and LHS. - opSet map[token.Token]bool - - floatOpsSet map[token.Token]bool -} - -func (c *dupSubExprChecker) VisitExpr(expr ast.Expr) { - if expr, ok := expr.(*ast.BinaryExpr); ok { - c.checkBinaryExpr(expr) - } -} - -func (c *dupSubExprChecker) checkBinaryExpr(expr *ast.BinaryExpr) { - if !c.opSet[expr.Op] { - return - } - if c.resultIsFloat(expr.X) && c.floatOpsSet[expr.Op] { - return - } - if typep.SideEffectFree(c.ctx.TypesInfo, expr) && c.opSet[expr.Op] && astequal.Expr(expr.X, expr.Y) { - c.warn(expr) - } -} - -func (c *dupSubExprChecker) resultIsFloat(expr ast.Expr) bool { - typ, ok := c.ctx.TypeOf(expr).(*types.Basic) - return ok && typ.Info()&types.IsFloat != 0 -} - -func (c *dupSubExprChecker) warn(cause *ast.BinaryExpr) { - c.ctx.Warn(cause, "suspicious identical LHS and RHS for `%s` operator", cause.Op) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/elseif_checker.go b/vendor/github.com/go-critic/go-critic/checkers/elseif_checker.go deleted file mode 100644 index 857d09fa0e..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/elseif_checker.go +++ /dev/null @@ -1,72 +0,0 @@ -package checkers - -import ( - "go/ast" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" - - "github.com/go-toolsmith/astp" -) - -func init() { - var info linter.CheckerInfo - info.Name = "elseif" - info.Tags = []string{linter.StyleTag} - info.Params = linter.CheckerParams{ - "skipBalanced": { - Value: true, - Usage: "whether to skip balanced if-else pairs", - }, - } - info.Summary = "Detects else with nested if statement that can be replaced with else-if" - info.Before = ` -if cond1 { -} else { - if x := cond2; x { - } -}` - info.After = ` -if cond1 { -} else if x := cond2; x { -}` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - c := &elseifChecker{ctx: ctx} - c.skipBalanced = info.Params.Bool("skipBalanced") - return astwalk.WalkerForStmt(c), nil - }) -} - -type elseifChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext - - skipBalanced bool -} - -func (c *elseifChecker) VisitStmt(stmt ast.Stmt) { - if stmt, ok := stmt.(*ast.IfStmt); ok { - elseBody, ok := stmt.Else.(*ast.BlockStmt) - if !ok || len(elseBody.List) != 1 { - return - } - innerIfStmt, ok := elseBody.List[0].(*ast.IfStmt) - if !ok { - return - } - balanced := len(stmt.Body.List) == 1 && - astp.IsIfStmt(stmt.Body.List[0]) - if balanced && c.skipBalanced { - return // Configured to skip balanced statements - } - if innerIfStmt.Else != nil || innerIfStmt.Init != nil { - return - } - c.warn(stmt.Else) - } -} - -func (c *elseifChecker) warn(cause ast.Node) { - c.ctx.Warn(cause, "can replace 'else {if cond {}}' with 'else if cond {}'") -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/embedded_rules.go b/vendor/github.com/go-critic/go-critic/checkers/embedded_rules.go deleted file mode 100644 index ad507425e6..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/embedded_rules.go +++ /dev/null @@ -1,108 +0,0 @@ -package checkers - -import ( - "fmt" - "go/ast" - "go/build" - "go/token" - "os" - - "github.com/go-critic/go-critic/checkers/rulesdata" - "github.com/go-critic/go-critic/linter" - - "github.com/quasilyte/go-ruleguard/ruleguard" -) - -//go:generate go run ./rules/precompile.go -rules ./rules/rules.go -o ./rulesdata/rulesdata.go - -func InitEmbeddedRules() error { - filename := "rules/rules.go" - - fset := token.NewFileSet() - var groups []ruleguard.GoRuleGroup - - var buildContext *build.Context - - ruleguardDebug := os.Getenv("GOCRITIC_RULEGUARD_DEBUG") != "" - - // First we create an Engine to parse all rules. - // We need it to get the structured info about our rules - // that will be used to generate checkers. - // We introduce an extra scope in hope that rootEngine - // will be garbage-collected after we don't need it. - // LoadedGroups() returns a slice copy and that's all what we need. - { - rootEngine := ruleguard.NewEngine() - rootEngine.InferBuildContext() - buildContext = rootEngine.BuildContext - - loadContext := &ruleguard.LoadContext{ - Fset: fset, - DebugImports: ruleguardDebug, - DebugPrint: func(s string) { - fmt.Println("debug:", s) - }, - } - if err := rootEngine.LoadFromIR(loadContext, filename, rulesdata.PrecompiledRules); err != nil { - return fmt.Errorf("load embedded ruleguard rules: %w", err) - } - groups = rootEngine.LoadedGroups() - } - - // For every rules group we create a new checker and a separate engine. - // That dedicated ruleguard engine will contain rules only from one group. - for i := range groups { - g := groups[i] - info := &linter.CheckerInfo{ - Name: g.Name, - Summary: g.DocSummary, - Before: g.DocBefore, - After: g.DocAfter, - Note: g.DocNote, - Tags: g.DocTags, - - EmbeddedRuleguard: true, - } - collection.AddChecker(info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - parseContext := &ruleguard.LoadContext{ - Fset: fset, - GroupFilter: func(gr *ruleguard.GoRuleGroup) bool { - return gr.Name == g.Name - }, - DebugImports: ruleguardDebug, - DebugPrint: func(s string) { - fmt.Println("debug:", s) - }, - } - engine := ruleguard.NewEngine() - engine.BuildContext = buildContext - err := engine.LoadFromIR(parseContext, filename, rulesdata.PrecompiledRules) - if err != nil { - return nil, err - } - c := &embeddedRuleguardChecker{ - ctx: ctx, - engine: engine, - } - return c, nil - }) - } - - return nil -} - -type embeddedRuleguardChecker struct { - ctx *linter.CheckerContext - engine *ruleguard.Engine -} - -func (c *embeddedRuleguardChecker) WalkFile(f *ast.File) { - runRuleguardEngine(c.ctx, f, c.engine, &ruleguard.RunContext{ - Pkg: c.ctx.Pkg, - Types: c.ctx.TypesInfo, - Sizes: c.ctx.SizesInfo, - GoVersion: ruleguard.GoVersion(c.ctx.GoVersion), - Fset: c.ctx.FileSet, - TruncateLen: 100, - }) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/emptyFallthrough_checker.go b/vendor/github.com/go-critic/go-critic/checkers/emptyFallthrough_checker.go deleted file mode 100644 index a008c61870..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/emptyFallthrough_checker.go +++ /dev/null @@ -1,70 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/token" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" -) - -func init() { - var info linter.CheckerInfo - info.Name = "emptyFallthrough" - info.Tags = []string{linter.StyleTag, linter.ExperimentalTag} - info.Summary = "Detects fallthrough that can be avoided by using multi case values" - info.Before = `switch kind { -case reflect.Int: - fallthrough -case reflect.Int32: - return Int -}` - info.After = `switch kind { -case reflect.Int, reflect.Int32: - return Int -}` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForStmt(&emptyFallthroughChecker{ctx: ctx}), nil - }) -} - -type emptyFallthroughChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext -} - -func (c *emptyFallthroughChecker) VisitStmt(stmt ast.Stmt) { - ss, ok := stmt.(*ast.SwitchStmt) - if !ok { - return - } - - prevCaseDefault := false - for i := len(ss.Body.List) - 1; i >= 0; i-- { - if cc, ok := ss.Body.List[i].(*ast.CaseClause); ok { - warn := false - if len(cc.Body) == 1 { - if bs, ok := cc.Body[0].(*ast.BranchStmt); ok && bs.Tok == token.FALLTHROUGH { - warn = true - if prevCaseDefault { - c.warnDefault(bs) - } else if cc.List != nil { - c.warn(bs) - } - } - } - if !warn { - prevCaseDefault = cc.List == nil - } - } - } -} - -func (c *emptyFallthroughChecker) warnDefault(cause ast.Node) { - c.ctx.Warn(cause, "remove empty case containing only fallthrough to default case") -} - -func (c *emptyFallthroughChecker) warn(cause ast.Node) { - c.ctx.Warn(cause, "replace empty case containing only fallthrough with expression list") -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/evalOrder_checker.go b/vendor/github.com/go-critic/go-critic/checkers/evalOrder_checker.go deleted file mode 100644 index f8c5ae5423..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/evalOrder_checker.go +++ /dev/null @@ -1,88 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/token" - "go/types" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/checkers/internal/lintutil" - "github.com/go-critic/go-critic/linter" - - "github.com/go-toolsmith/astcast" - "github.com/go-toolsmith/astequal" - "github.com/go-toolsmith/typep" -) - -func init() { - var info linter.CheckerInfo - info.Name = "evalOrder" - info.Tags = []string{linter.DiagnosticTag, linter.ExperimentalTag} - info.Summary = "Detects unwanted dependencies on the evaluation order" - info.Before = `return x, f(&x)` - info.After = ` -err := f(&x) -return x, err -` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForStmt(&evalOrderChecker{ctx: ctx}), nil - }) -} - -type evalOrderChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext -} - -func (c *evalOrderChecker) VisitStmt(stmt ast.Stmt) { - ret := astcast.ToReturnStmt(stmt) - if len(ret.Results) < 2 { - return - } - - // TODO(quasilyte): handle selector expressions like o.val in addition - // to bare identifiers. - addrTake := &ast.UnaryExpr{Op: token.AND} - for _, res := range ret.Results { - id, ok := res.(*ast.Ident) - if !ok { - continue - } - addrTake.X = id // addrTake is &id now - for _, res := range ret.Results { - call, ok := res.(*ast.CallExpr) - if !ok { - continue - } - - // 1. Check if there is a call in form of id.method() where - // method takes id by a pointer. - if sel, ok := call.Fun.(*ast.SelectorExpr); ok { - if astequal.Node(sel.X, id) && c.hasPtrRecv(sel.Sel) { - c.warn(call) - } - } - - // 2. Check that there is no call that uses &id as an argument. - dependency := lintutil.ContainsNode(call, func(n ast.Node) bool { - return astequal.Node(addrTake, n) - }) - if dependency { - c.warn(call) - } - } - } -} - -func (c *evalOrderChecker) hasPtrRecv(fn *ast.Ident) bool { - sig, ok := c.ctx.TypeOf(fn).(*types.Signature) - if !ok { - return false - } - return typep.IsPointer(sig.Recv().Type()) -} - -func (c *evalOrderChecker) warn(call *ast.CallExpr) { - c.ctx.Warn(call, "may want to evaluate %s before the return statement", call) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/exitAfterDefer_checker.go b/vendor/github.com/go-critic/go-critic/checkers/exitAfterDefer_checker.go deleted file mode 100644 index 19b20e4259..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/exitAfterDefer_checker.go +++ /dev/null @@ -1,91 +0,0 @@ -package checkers - -import ( - "go/ast" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" - - "github.com/go-toolsmith/astfmt" - "github.com/go-toolsmith/astp" - "golang.org/x/tools/go/ast/astutil" -) - -func init() { - var info linter.CheckerInfo - info.Name = "exitAfterDefer" - info.Tags = []string{linter.DiagnosticTag} - info.Summary = "Detects calls to exit/fatal inside functions that use defer" - info.Before = ` -defer os.Remove(filename) -if bad { - log.Fatalf("something bad happened") -}` - info.After = ` -defer os.Remove(filename) -if bad { - log.Printf("something bad happened") - return -}` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForFuncDecl(&exitAfterDeferChecker{ctx: ctx}), nil - }) -} - -type exitAfterDeferChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext -} - -func (c *exitAfterDeferChecker) VisitFuncDecl(fn *ast.FuncDecl) { - // TODO(quasilyte): handle goto and other kinds of flow that break - // the algorithm below that expects the latter statement to be - // executed after the ones that come before it. - - var deferStmt *ast.DeferStmt - pre := func(cur *astutil.Cursor) bool { - // If we found a defer statement in the function post traversal. - // and are looking at the Else branch during a pre traversal, stop seeking as it could be false positive. - if deferStmt != nil && cur.Name() == "Else" { - return false - } - - // Don't recurse into local anonymous functions. - return !astp.IsFuncLit(cur.Node()) - } - post := func(cur *astutil.Cursor) bool { - switch n := cur.Node().(type) { - case *ast.DeferStmt: - deferStmt = n - case *ast.CallExpr: - // See #995. We allow `defer os.Exit()` calls - // as it's harder to determine whether they're going - // to clutter anything without actually trying to - // simulate the defer stack + understanding the control flow. - // TODO: can we use CFG here? - if _, ok := cur.Parent().(*ast.DeferStmt); ok { - return true - } - if deferStmt != nil { - switch qualifiedName(n.Fun) { - case "log.Fatal", "log.Fatalf", "log.Fatalln", "os.Exit": - c.warn(n, deferStmt) - return false - } - } - } - return true - } - astutil.Apply(fn.Body, pre, post) -} - -func (c *exitAfterDeferChecker) warn(cause *ast.CallExpr, deferStmt *ast.DeferStmt) { - s := astfmt.Sprint(deferStmt) - if fnlit, ok := deferStmt.Call.Fun.(*ast.FuncLit); ok { - // To avoid long and multi-line warning messages, - // collapse the function literals. - s = "defer " + astfmt.Sprint(fnlit.Type) + "{...}(...)" - } - c.ctx.Warn(cause, "%s will exit, and `%s` will not run", cause.Fun, s) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/filepathJoin_checker.go b/vendor/github.com/go-critic/go-critic/checkers/filepathJoin_checker.go deleted file mode 100644 index 17ab0ea83f..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/filepathJoin_checker.go +++ /dev/null @@ -1,51 +0,0 @@ -package checkers - -import ( - "go/ast" - "strings" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" - - "github.com/go-toolsmith/astcast" -) - -func init() { - var info linter.CheckerInfo - info.Name = "filepathJoin" - info.Tags = []string{linter.DiagnosticTag, linter.ExperimentalTag} - info.Summary = "Detects problems in filepath.Join() function calls" - info.Before = `filepath.Join("dir/", filename)` - info.After = `filepath.Join("dir", filename)` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForExpr(&filepathJoinChecker{ctx: ctx}), nil - }) -} - -type filepathJoinChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext -} - -func (c *filepathJoinChecker) VisitExpr(expr ast.Expr) { - call := astcast.ToCallExpr(expr) - if qualifiedName(call.Fun) != "filepath.Join" { - return - } - - for _, arg := range call.Args { - arg, ok := arg.(*ast.BasicLit) - if ok && c.hasSeparator(arg) { - c.warnSeparator(arg) - } - } -} - -func (c *filepathJoinChecker) hasSeparator(v *ast.BasicLit) bool { - return strings.ContainsAny(v.Value, `/\`) -} - -func (c *filepathJoinChecker) warnSeparator(sep ast.Expr) { - c.ctx.Warn(sep, "%s contains a path separator", sep) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/flagName_checker.go b/vendor/github.com/go-critic/go-critic/checkers/flagName_checker.go deleted file mode 100644 index 7010668608..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/flagName_checker.go +++ /dev/null @@ -1,89 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/constant" - "go/types" - "strings" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" - - "github.com/go-toolsmith/astcast" -) - -func init() { - var info linter.CheckerInfo - info.Name = "flagName" - info.Tags = []string{linter.DiagnosticTag} - info.Summary = "Detects suspicious flag names" - info.Before = `b := flag.Bool(" foo ", false, "description")` - info.After = `b := flag.Bool("foo", false, "description")` - info.Note = "https://github.com/golang/go/issues/41792" - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForExpr(&flagNameChecker{ctx: ctx}), nil - }) -} - -type flagNameChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext -} - -func (c *flagNameChecker) VisitExpr(expr ast.Expr) { - call := astcast.ToCallExpr(expr) - calledExpr := astcast.ToSelectorExpr(call.Fun) - obj, ok := c.ctx.TypesInfo.ObjectOf(astcast.ToIdent(calledExpr.X)).(*types.PkgName) - if !ok { - return - } - sym := calledExpr.Sel - pkg := obj.Imported() - if pkg.Path() != "flag" { - return - } - - switch sym.Name { - case "Bool", "Duration", "Float64", "String", - "Int", "Int64", "Uint", "Uint64": - c.checkFlagName(call, call.Args[0]) - case "BoolVar", "DurationVar", "Float64Var", "StringVar", - "IntVar", "Int64Var", "UintVar", "Uint64Var": - c.checkFlagName(call, call.Args[1]) - } -} - -func (c *flagNameChecker) checkFlagName(call *ast.CallExpr, arg ast.Expr) { - cv := c.ctx.TypesInfo.Types[arg].Value - if cv == nil { - return // Non-constant name - } - name := constant.StringVal(cv) - switch { - case name == "": - c.warnEmpty(call) - case strings.HasPrefix(name, "-"): - c.warnHyphenPrefix(call, name) - case strings.Contains(name, "="): - c.warnEq(call, name) - case strings.Contains(name, " "): - c.warnWhitespace(call, name) - } -} - -func (c *flagNameChecker) warnEmpty(cause ast.Node) { - c.ctx.Warn(cause, "empty flag name") -} - -func (c *flagNameChecker) warnHyphenPrefix(cause ast.Node, name string) { - c.ctx.Warn(cause, "flag name %q should not start with a hyphen", name) -} - -func (c *flagNameChecker) warnEq(cause ast.Node, name string) { - c.ctx.Warn(cause, "flag name %q should not contain '='", name) -} - -func (c *flagNameChecker) warnWhitespace(cause ast.Node, name string) { - c.ctx.Warn(cause, "flag name %q contains whitespace", name) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/hexLiteral_checker.go b/vendor/github.com/go-critic/go-critic/checkers/hexLiteral_checker.go deleted file mode 100644 index 7301bd325a..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/hexLiteral_checker.go +++ /dev/null @@ -1,61 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/token" - "strings" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" - - "github.com/go-toolsmith/astcast" -) - -func init() { - var info linter.CheckerInfo - info.Name = "hexLiteral" - info.Tags = []string{linter.StyleTag, linter.ExperimentalTag} - info.Summary = "Detects hex literals that have mixed case letter digits" - info.Before = ` -x := 0X12 -y := 0xfF` - info.After = ` -x := 0x12 -// (A) -y := 0xff -// (B) -y := 0xFF` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForExpr(&hexLiteralChecker{ctx: ctx}), nil - }) -} - -type hexLiteralChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext -} - -func (c *hexLiteralChecker) warn0X(lit *ast.BasicLit) { - suggest := "0x" + lit.Value[len("0X"):] - c.ctx.Warn(lit, "prefer 0x over 0X, s/%s/%s/", lit.Value, suggest) -} - -func (c *hexLiteralChecker) warnMixedDigits(lit *ast.BasicLit) { - c.ctx.Warn(lit, "don't mix hex literal letter digits casing") -} - -func (c *hexLiteralChecker) VisitExpr(expr ast.Expr) { - lit := astcast.ToBasicLit(expr) - if lit.Kind != token.INT || len(lit.Value) < 3 { - return - } - if strings.HasPrefix(lit.Value, "0X") { - c.warn0X(lit) - return - } - digits := lit.Value[len("0x"):] - if strings.ToLower(digits) != digits && strings.ToUpper(digits) != digits { - c.warnMixedDigits(lit) - } -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/hugeParam_checker.go b/vendor/github.com/go-critic/go-critic/checkers/hugeParam_checker.go deleted file mode 100644 index 170c3f4171..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/hugeParam_checker.go +++ /dev/null @@ -1,84 +0,0 @@ -package checkers - -import ( - "go/ast" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" - - "github.com/go-toolsmith/astcast" -) - -func init() { - var info linter.CheckerInfo - info.Name = "hugeParam" - info.Tags = []string{linter.PerformanceTag} - info.Params = linter.CheckerParams{ - "sizeThreshold": { - Value: 80, - Usage: "size in bytes that makes the warning trigger", - }, - } - info.Summary = "Detects params that incur excessive amount of copying" - info.Before = `func f(x [1024]int) {}` - info.After = `func f(x *[1024]int) {}` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForFuncDecl(&hugeParamChecker{ - ctx: ctx, - sizeThreshold: int64(info.Params.Int("sizeThreshold")), - }), nil - }) -} - -type hugeParamChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext - - sizeThreshold int64 -} - -func (c *hugeParamChecker) VisitFuncDecl(decl *ast.FuncDecl) { - // TODO(quasilyte): maybe it's worthwhile to permit skipping - // test files for this checker? - if c.isImplementStringer(decl) { - return - } - - if decl.Recv != nil { - c.checkParams(decl.Recv.List) - } - c.checkParams(decl.Type.Params.List) -} - -// isImplementStringer check method signature is: String() string. -func (*hugeParamChecker) isImplementStringer(decl *ast.FuncDecl) bool { - if decl.Recv != nil && - decl.Name.Name == "String" && - decl.Type != nil && - len(decl.Type.Params.List) == 0 && - decl.Type.Results != nil && - len(decl.Type.Results.List) == 1 && - astcast.ToIdent(decl.Type.Results.List[0].Type).Name == "string" { - return true - } - - return false -} - -func (c *hugeParamChecker) checkParams(params []*ast.Field) { - for _, p := range params { - for _, id := range p.Names { - typ := c.ctx.TypeOf(id) - size, ok := c.ctx.SizeOf(typ) - if ok && size >= c.sizeThreshold { - c.warn(id, size) - } - } - } -} - -func (c *hugeParamChecker) warn(cause *ast.Ident, size int64) { - c.ctx.Warn(cause, "%s is heavy (%d bytes); consider passing it by pointer", - cause, size) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/ifElseChain_checker.go b/vendor/github.com/go-critic/go-critic/checkers/ifElseChain_checker.go deleted file mode 100644 index e73c609d5c..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/ifElseChain_checker.go +++ /dev/null @@ -1,110 +0,0 @@ -package checkers - -import ( - "go/ast" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" -) - -func init() { - var info linter.CheckerInfo - info.Name = "ifElseChain" - info.Tags = []string{linter.StyleTag} - info.Params = linter.CheckerParams{ - "minThreshold": { - Value: 2, - Usage: "min number of if-else blocks that makes the warning trigger", - }, - } - info.Summary = "Detects repeated if-else statements and suggests to replace them with switch statement" - info.Before = ` -if cond1 { - // Code A. -} else if cond2 { - // Code B. -} else { - // Code C. -}` - info.After = ` -switch { -case cond1: - // Code A. -case cond2: - // Code B. -default: - // Code C. -}` - info.Note = ` -Permits single else or else-if; repeated else-if or else + else-if -will trigger suggestion to use switch statement. -See [EffectiveGo#switch](https://golang.org/doc/effective_go.html#switch).` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForStmt(&ifElseChainChecker{ - ctx: ctx, - minThreshold: info.Params.Int("minThreshold"), - }), nil - }) -} - -type ifElseChainChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext - - cause *ast.IfStmt - visited map[*ast.IfStmt]bool - - minThreshold int -} - -func (c *ifElseChainChecker) EnterFunc(fn *ast.FuncDecl) bool { - if fn.Body == nil { - return false - } - c.visited = make(map[*ast.IfStmt]bool) - return true -} - -func (c *ifElseChainChecker) VisitStmt(stmt ast.Stmt) { - if stmt, ok := stmt.(*ast.IfStmt); ok { - if c.visited[stmt] { - return - } - c.cause = stmt - c.checkIfStmt(stmt) - } -} - -func (c *ifElseChainChecker) checkIfStmt(stmt *ast.IfStmt) { - if c.countIfelseLen(stmt) >= c.minThreshold { - c.warn() - } -} - -func (c *ifElseChainChecker) countIfelseLen(stmt *ast.IfStmt) int { - count := 0 - for { - if stmt.Init != nil { - return 0 // Give up - } - - switch e := stmt.Else.(type) { - case *ast.IfStmt: - // Else if. - stmt = e - count++ - c.visited[e] = true - case *ast.BlockStmt: - // Else branch. - return count + 1 - default: - // No else or else if. - return count - } - } -} - -func (c *ifElseChainChecker) warn() { - c.ctx.Warn(c.cause, "rewrite if-else to switch statement") -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/importShadow_checker.go b/vendor/github.com/go-critic/go-critic/checkers/importShadow_checker.go deleted file mode 100644 index b690487b7b..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/importShadow_checker.go +++ /dev/null @@ -1,47 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/types" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" -) - -func init() { - var info linter.CheckerInfo - info.Name = "importShadow" - info.Tags = []string{linter.StyleTag, linter.OpinionatedTag} - info.Summary = "Detects when imported package names shadowed in the assignments" - info.Before = ` -// "path/filepath" is imported. -filepath := "foo.txt"` - info.After = ` -filename := "foo.txt"` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - ctx.Require.PkgObjects = true - return astwalk.WalkerForLocalDef(&importShadowChecker{ctx: ctx}, ctx.TypesInfo), nil - }) -} - -type importShadowChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext -} - -func (c *importShadowChecker) VisitLocalDef(def astwalk.Name, _ ast.Expr) { - for pkgObj, name := range c.ctx.PkgObjects { - if name == def.ID.Name && name != "_" { - c.warn(def.ID, name, pkgObj.Imported()) - } - } -} - -func (c *importShadowChecker) warn(id ast.Node, importedName string, pkg *types.Package) { - if isStdlibPkg(pkg) { - c.ctx.Warn(id, "shadow of imported package '%s'", importedName) - } else { - c.ctx.Warn(id, "shadow of imported from '%s' package '%s'", pkg.Path(), importedName) - } -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/initClause_checker.go b/vendor/github.com/go-critic/go-critic/checkers/initClause_checker.go deleted file mode 100644 index 8612717b27..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/initClause_checker.go +++ /dev/null @@ -1,57 +0,0 @@ -package checkers - -import ( - "go/ast" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" - - "github.com/go-toolsmith/astp" -) - -func init() { - var info linter.CheckerInfo - info.Name = "initClause" - info.Tags = []string{linter.StyleTag, linter.OpinionatedTag, linter.ExperimentalTag} - info.Summary = "Detects non-assignment statements inside if/switch init clause" - info.Before = `if sideEffect(); cond { -}` - info.After = `sideEffect() -if cond { -}` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForStmt(&initClauseChecker{ctx: ctx}), nil - }) -} - -type initClauseChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext -} - -func (c *initClauseChecker) VisitStmt(stmt ast.Stmt) { - initClause := c.getInitClause(stmt) - if initClause != nil && !astp.IsAssignStmt(initClause) { - c.warn(stmt, initClause) - } -} - -func (c *initClauseChecker) getInitClause(x ast.Stmt) ast.Stmt { - switch x := x.(type) { - case *ast.IfStmt: - return x.Init - case *ast.SwitchStmt: - return x.Init - default: - return nil - } -} - -func (c *initClauseChecker) warn(stmt, clause ast.Stmt) { - name := "if" - if astp.IsSwitchStmt(stmt) { - name = "switch" - } - c.ctx.Warn(stmt, "consider to move `%s` before %s", clause, name) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/comment_walker.go b/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/comment_walker.go deleted file mode 100644 index 6c60e3fede..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/comment_walker.go +++ /dev/null @@ -1,41 +0,0 @@ -package astwalk - -import ( - "go/ast" - "strings" -) - -type commentWalker struct { - visitor CommentVisitor -} - -func (w *commentWalker) WalkFile(f *ast.File) { - if !w.visitor.EnterFile(f) { - return - } - - for _, cg := range f.Comments { - visitCommentGroups(cg, w.visitor.VisitComment) - } -} - -func visitCommentGroups(cg *ast.CommentGroup, visit func(*ast.CommentGroup)) { - var group []*ast.Comment - visitGroup := func(list []*ast.Comment) { - if len(list) == 0 { - return - } - cg := &ast.CommentGroup{List: list} - visit(cg) - } - for _, comment := range cg.List { - if strings.HasPrefix(comment.Text, "/*") { - visitGroup(group) - group = group[:0] - visitGroup([]*ast.Comment{comment}) - } else { - group = append(group, comment) - } - } - visitGroup(group) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/doc_comment_walker.go b/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/doc_comment_walker.go deleted file mode 100644 index 39b5365083..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/doc_comment_walker.go +++ /dev/null @@ -1,48 +0,0 @@ -package astwalk - -import ( - "go/ast" -) - -type docCommentWalker struct { - visitor DocCommentVisitor -} - -func (w *docCommentWalker) WalkFile(f *ast.File) { - for _, decl := range f.Decls { - switch decl := decl.(type) { - case *ast.FuncDecl: - if decl.Doc != nil { - w.visitor.VisitDocComment(decl.Doc) - } - case *ast.GenDecl: - if decl.Doc != nil { - w.visitor.VisitDocComment(decl.Doc) - } - for _, spec := range decl.Specs { - switch spec := spec.(type) { - case *ast.ImportSpec: - if spec.Doc != nil { - w.visitor.VisitDocComment(spec.Doc) - } - case *ast.ValueSpec: - if spec.Doc != nil { - w.visitor.VisitDocComment(spec.Doc) - } - case *ast.TypeSpec: - if spec.Doc != nil { - w.visitor.VisitDocComment(spec.Doc) - } - ast.Inspect(spec.Type, func(n ast.Node) bool { - if n, ok := n.(*ast.Field); ok { - if n.Doc != nil { - w.visitor.VisitDocComment(n.Doc) - } - } - return true - }) - } - } - } - } -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/expr_walker.go b/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/expr_walker.go deleted file mode 100644 index de66c1081b..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/expr_walker.go +++ /dev/null @@ -1,31 +0,0 @@ -package astwalk - -import ( - "go/ast" -) - -type exprWalker struct { - visitor ExprVisitor -} - -func (w *exprWalker) WalkFile(f *ast.File) { - if !w.visitor.EnterFile(f) { - return - } - - for _, decl := range f.Decls { - if decl, ok := decl.(*ast.FuncDecl); ok { - if !w.visitor.EnterFunc(decl) { - continue - } - } - - ast.Inspect(decl, func(x ast.Node) bool { - if x, ok := x.(ast.Expr); ok { - w.visitor.VisitExpr(x) - return !w.visitor.skipChilds() - } - return true - }) - } -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/func_decl_walker.go b/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/func_decl_walker.go deleted file mode 100644 index c7e3a4371e..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/func_decl_walker.go +++ /dev/null @@ -1,23 +0,0 @@ -package astwalk - -import ( - "go/ast" -) - -type funcDeclWalker struct { - visitor FuncDeclVisitor -} - -func (w *funcDeclWalker) WalkFile(f *ast.File) { - if !w.visitor.EnterFile(f) { - return - } - - for _, decl := range f.Decls { - decl, ok := decl.(*ast.FuncDecl) - if !ok || !w.visitor.EnterFunc(decl) { - continue - } - w.visitor.VisitFuncDecl(decl) - } -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/local_comment_walker.go b/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/local_comment_walker.go deleted file mode 100644 index e042f0d5ef..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/local_comment_walker.go +++ /dev/null @@ -1,32 +0,0 @@ -package astwalk - -import ( - "go/ast" -) - -type localCommentWalker struct { - visitor LocalCommentVisitor -} - -func (w *localCommentWalker) WalkFile(f *ast.File) { - if !w.visitor.EnterFile(f) { - return - } - - for _, decl := range f.Decls { - decl, ok := decl.(*ast.FuncDecl) - if !ok || !w.visitor.EnterFunc(decl) { - continue - } - - for _, cg := range f.Comments { - // Not sure that decls/comments are sorted - // by positions, so do a naive full scan for now. - if cg.Pos() < decl.Pos() || cg.Pos() > decl.End() { - continue - } - - visitCommentGroups(cg, w.visitor.VisitLocalComment) - } - } -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/local_def_visitor.go b/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/local_def_visitor.go deleted file mode 100644 index 0c9c14955e..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/local_def_visitor.go +++ /dev/null @@ -1,49 +0,0 @@ -package astwalk - -import ( - "go/ast" -) - -// LocalDefVisitor visits every name definitions inside a function. -// -// Next elements are considered as name definitions: -// - Function parameters (input, output, receiver) -// - Every LHS of ":=" assignment that defines a new name -// - Every local var/const declaration. -// -// NOTE: this visitor is experimental. -// This is also why it lives in a separate file. -type LocalDefVisitor interface { - walkerEvents - VisitLocalDef(Name, ast.Expr) -} - -// NameKind describes what kind of name Name object holds. -type NameKind int - -// Name holds ver/const/param definition symbol info. -type Name struct { - ID *ast.Ident - Kind NameKind - - // Index is NameVar-specific field that is used to - // specify nth tuple element being assigned to the name. - Index int -} - -// NOTE: set of name kinds is not stable and may change over time. -// -// TODO(quasilyte): is NameRecv/NameParam/NameResult granularity desired? -// TODO(quasilyte): is NameVar/NameBind (var vs :=) granularity desired? -const ( - // NameParam is function/method receiver/input/output name. - // Initializing expression is always nil. - NameParam NameKind = iota - // NameVar is var or ":=" declared name. - // Initializing expression may be nil for var-declared names - // without explicit initializing expression. - NameVar - // NameConst is const-declared name. - // Initializing expression is never nil. - NameConst -) diff --git a/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/local_def_walker.go b/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/local_def_walker.go deleted file mode 100644 index f6808cbb49..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/local_def_walker.go +++ /dev/null @@ -1,118 +0,0 @@ -package astwalk - -import ( - "go/ast" - "go/token" - "go/types" -) - -type localDefWalker struct { - visitor LocalDefVisitor - info *types.Info -} - -func (w *localDefWalker) WalkFile(f *ast.File) { - for _, decl := range f.Decls { - decl, ok := decl.(*ast.FuncDecl) - if !ok || !w.visitor.EnterFunc(decl) { - continue - } - w.walkFunc(decl) - } -} - -func (w *localDefWalker) walkFunc(decl *ast.FuncDecl) { - w.walkSignature(decl) - w.walkFuncBody(decl) -} - -func (w *localDefWalker) walkFuncBody(decl *ast.FuncDecl) { - ast.Inspect(decl.Body, func(x ast.Node) bool { - switch x := x.(type) { - case *ast.AssignStmt: - if x.Tok != token.DEFINE { - return false - } - if len(x.Lhs) != len(x.Rhs) { - // Multi-value assignment. - // Invariant: there is only 1 RHS. - for i, lhs := range x.Lhs { - id, ok := lhs.(*ast.Ident) - if !ok || w.info.Defs[id] == nil { - continue - } - def := Name{ID: id, Kind: NameVar, Index: i} - w.visitor.VisitLocalDef(def, x.Rhs[0]) - } - } else { - // Simple 1-1 assignments. - for i, lhs := range x.Lhs { - id, ok := lhs.(*ast.Ident) - if !ok || w.info.Defs[id] == nil { - continue - } - def := Name{ID: id, Kind: NameVar} - w.visitor.VisitLocalDef(def, x.Rhs[i]) - } - } - return false - - case *ast.GenDecl: - // Decls always introduce new names. - for _, spec := range x.Specs { - spec, ok := spec.(*ast.ValueSpec) - if !ok { // Ignore type/import specs - return false - } - switch { - case len(spec.Values) == 0: - // var-specific decls without explicit init. - for _, id := range spec.Names { - def := Name{ID: id, Kind: NameVar} - w.visitor.VisitLocalDef(def, nil) - } - case len(spec.Names) != len(spec.Values): - // var-specific decls that assign tuple results. - for i, id := range spec.Names { - def := Name{ID: id, Kind: NameVar, Index: i} - w.visitor.VisitLocalDef(def, spec.Values[0]) - } - default: - // Can be either var or const decl. - kind := NameVar - if x.Tok == token.CONST { - kind = NameConst - } - for i, id := range spec.Names { - def := Name{ID: id, Kind: kind} - w.visitor.VisitLocalDef(def, spec.Values[i]) - } - } - } - return false - } - - return true - }) -} - -func (w *localDefWalker) walkSignature(decl *ast.FuncDecl) { - for _, p := range decl.Type.Params.List { - for _, id := range p.Names { - def := Name{ID: id, Kind: NameParam} - w.visitor.VisitLocalDef(def, nil) - } - } - if decl.Type.Results != nil { - for _, p := range decl.Type.Results.List { - for _, id := range p.Names { - def := Name{ID: id, Kind: NameParam} - w.visitor.VisitLocalDef(def, nil) - } - } - } - if decl.Recv != nil && len(decl.Recv.List[0].Names) != 0 { - def := Name{ID: decl.Recv.List[0].Names[0], Kind: NameParam} - w.visitor.VisitLocalDef(def, nil) - } -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/local_expr_walker.go b/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/local_expr_walker.go deleted file mode 100644 index e455b3f8b6..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/local_expr_walker.go +++ /dev/null @@ -1,29 +0,0 @@ -package astwalk - -import ( - "go/ast" -) - -type localExprWalker struct { - visitor LocalExprVisitor -} - -func (w *localExprWalker) WalkFile(f *ast.File) { - if !w.visitor.EnterFile(f) { - return - } - - for _, decl := range f.Decls { - decl, ok := decl.(*ast.FuncDecl) - if !ok || !w.visitor.EnterFunc(decl) { - continue - } - ast.Inspect(decl.Body, func(x ast.Node) bool { - if x, ok := x.(ast.Expr); ok { - w.visitor.VisitLocalExpr(x) - return !w.visitor.skipChilds() - } - return true - }) - } -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/stmt_list_walker.go b/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/stmt_list_walker.go deleted file mode 100644 index 403292f669..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/stmt_list_walker.go +++ /dev/null @@ -1,33 +0,0 @@ -package astwalk - -import ( - "go/ast" -) - -type stmtListWalker struct { - visitor StmtListVisitor -} - -func (w *stmtListWalker) WalkFile(f *ast.File) { - if !w.visitor.EnterFile(f) { - return - } - - for _, decl := range f.Decls { - decl, ok := decl.(*ast.FuncDecl) - if !ok || !w.visitor.EnterFunc(decl) { - continue - } - ast.Inspect(decl.Body, func(x ast.Node) bool { - switch x := x.(type) { - case *ast.BlockStmt: - w.visitor.VisitStmtList(x, x.List) - case *ast.CaseClause: - w.visitor.VisitStmtList(x, x.Body) - case *ast.CommClause: - w.visitor.VisitStmtList(x, x.Body) - } - return !w.visitor.skipChilds() - }) - } -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/stmt_walker.go b/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/stmt_walker.go deleted file mode 100644 index 912de867dd..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/stmt_walker.go +++ /dev/null @@ -1,29 +0,0 @@ -package astwalk - -import ( - "go/ast" -) - -type stmtWalker struct { - visitor StmtVisitor -} - -func (w *stmtWalker) WalkFile(f *ast.File) { - if !w.visitor.EnterFile(f) { - return - } - - for _, decl := range f.Decls { - decl, ok := decl.(*ast.FuncDecl) - if !ok || !w.visitor.EnterFunc(decl) { - continue - } - ast.Inspect(decl.Body, func(x ast.Node) bool { - if x, ok := x.(ast.Stmt); ok { - w.visitor.VisitStmt(x) - return !w.visitor.skipChilds() - } - return true - }) - } -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/type_expr_walker.go b/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/type_expr_walker.go deleted file mode 100644 index bc9bdef47b..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/type_expr_walker.go +++ /dev/null @@ -1,119 +0,0 @@ -package astwalk - -import ( - "go/ast" - "go/token" - "go/types" - - "github.com/go-toolsmith/astp" - "github.com/go-toolsmith/typep" -) - -type typeExprWalker struct { - visitor TypeExprVisitor - info *types.Info -} - -func (w *typeExprWalker) WalkFile(f *ast.File) { - if !w.visitor.EnterFile(f) { - return - } - - for _, decl := range f.Decls { - if decl, ok := decl.(*ast.FuncDecl); ok { - if !w.visitor.EnterFunc(decl) { - continue - } - } - switch decl := decl.(type) { - case *ast.FuncDecl: - if !w.visitor.EnterFunc(decl) { - continue - } - w.walkSignature(decl.Type) - ast.Inspect(decl.Body, w.walk) - case *ast.GenDecl: - if decl.Tok == token.IMPORT { - continue - } - ast.Inspect(decl, w.walk) - } - } -} - -func (w *typeExprWalker) visit(x ast.Expr) bool { - w.visitor.VisitTypeExpr(x) - return !w.visitor.skipChilds() -} - -func (w *typeExprWalker) walk(x ast.Node) bool { - switch x := x.(type) { - case *ast.ChanType: - return w.visit(x) - case *ast.ParenExpr: - if typep.IsTypeExpr(w.info, x.X) { - return w.visit(x) - } - return true - case *ast.CallExpr: - // Pointer conversions require parenthesis around pointer type. - // These casts are represented as call expressions. - // Because it's impossible for the visitor to distinguish such - // "required" parenthesis, walker skips outmost parenthesis in such cases. - return w.inspectInner(x.Fun) - case *ast.SelectorExpr: - // Like with conversions, method expressions are another special. - return w.inspectInner(x.X) - case *ast.StarExpr: - if typep.IsTypeExpr(w.info, x.X) { - return w.visit(x) - } - return true - case *ast.MapType: - return w.visit(x) - case *ast.FuncType: - return w.visit(x) - case *ast.StructType: - return w.visit(x) - case *ast.InterfaceType: - if !w.visit(x) { - return false - } - for _, method := range x.Methods.List { - switch x := method.Type.(type) { - case *ast.FuncType: - w.walkSignature(x) - default: - // Embedded interface. - w.walk(x) - } - } - return false - case *ast.ArrayType: - return w.visit(x) - } - return true -} - -func (w *typeExprWalker) inspectInner(x ast.Expr) bool { - parens, ok := x.(*ast.ParenExpr) - shouldInspect := ok && - typep.IsTypeExpr(w.info, parens.X) && - (astp.IsStarExpr(parens.X) || astp.IsFuncType(parens.X)) - if shouldInspect { - ast.Inspect(parens.X, w.walk) - return false - } - return true -} - -func (w *typeExprWalker) walkSignature(typ *ast.FuncType) { - for _, p := range typ.Params.List { - ast.Inspect(p.Type, w.walk) - } - if typ.Results != nil { - for _, p := range typ.Results.List { - ast.Inspect(p.Type, w.walk) - } - } -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/visitor.go b/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/visitor.go deleted file mode 100644 index 3486a8e622..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/visitor.go +++ /dev/null @@ -1,77 +0,0 @@ -package astwalk - -import ( - "go/ast" -) - -// DocCommentVisitor visits every doc-comment. -// Does not visit doc-comments for function-local definitions (types, etc). -// Also does not visit package doc-comment (file-level doc-comments). -type DocCommentVisitor interface { - VisitDocComment(*ast.CommentGroup) -} - -// FuncDeclVisitor visits every top-level function declaration. -type FuncDeclVisitor interface { - walkerEvents - VisitFuncDecl(*ast.FuncDecl) -} - -// ExprVisitor visits every expression inside AST file. -type ExprVisitor interface { - walkerEvents - VisitExpr(ast.Expr) -} - -// LocalExprVisitor visits every expression inside function body. -type LocalExprVisitor interface { - walkerEvents - VisitLocalExpr(ast.Expr) -} - -// StmtListVisitor visits every statement list inside function body. -// This includes block statement bodies as well as implicit blocks -// introduced by case clauses and alike. -type StmtListVisitor interface { - walkerEvents - VisitStmtList(ast.Node, []ast.Stmt) -} - -// StmtVisitor visits every statement inside function body. -type StmtVisitor interface { - walkerEvents - VisitStmt(ast.Stmt) -} - -// TypeExprVisitor visits every type describing expression. -// It also traverses struct types and interface types to run -// checker over their fields/method signatures. -type TypeExprVisitor interface { - walkerEvents - VisitTypeExpr(ast.Expr) -} - -// LocalCommentVisitor visits every comment inside function body. -type LocalCommentVisitor interface { - walkerEvents - VisitLocalComment(*ast.CommentGroup) -} - -// CommentVisitor visits every comment. -type CommentVisitor interface { - walkerEvents - VisitComment(*ast.CommentGroup) -} - -// walkerEvents describes common hooks available for most visitor types. -type walkerEvents interface { - // EnterFile is called for every file that is about to be traversed. - // If false is returned, file is not visited. - EnterFile(*ast.File) bool - - // EnterFunc is called for every function declaration that is about - // to be traversed. If false is returned, function is not visited. - EnterFunc(*ast.FuncDecl) bool - - skipChilds() bool -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/walk_handler.go b/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/walk_handler.go deleted file mode 100644 index 96d2dd0e6f..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/walk_handler.go +++ /dev/null @@ -1,34 +0,0 @@ -package astwalk - -import ( - "go/ast" -) - -// WalkHandler is a type to be embedded into every checker -// that uses astwalk walkers. -type WalkHandler struct { - // SkipChilds controls whether currently analyzed - // node childs should be traversed. - // - // Value is reset after each visitor invocation, - // so there is no need to set value back to false. - SkipChilds bool -} - -// EnterFile is a default walkerEvents.EnterFile implementation -// that reports every file as accepted candidate for checking. -func (w *WalkHandler) EnterFile(_ *ast.File) bool { - return true -} - -// EnterFunc is a default walkerEvents.EnterFunc implementation -// that skips extern function (ones that do not have body). -func (w *WalkHandler) EnterFunc(decl *ast.FuncDecl) bool { - return decl.Body != nil -} - -func (w *WalkHandler) skipChilds() bool { - v := w.SkipChilds - w.SkipChilds = false - return v -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/walker.go b/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/walker.go deleted file mode 100644 index f838a64c15..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/internal/astwalk/walker.go +++ /dev/null @@ -1,57 +0,0 @@ -package astwalk - -import ( - "go/types" - - "github.com/go-critic/go-critic/linter" -) - -// WalkerForFuncDecl returns file walker implementation for FuncDeclVisitor. -func WalkerForFuncDecl(v FuncDeclVisitor) linter.FileWalker { - return &funcDeclWalker{visitor: v} -} - -// WalkerForExpr returns file walker implementation for ExprVisitor. -func WalkerForExpr(v ExprVisitor) linter.FileWalker { - return &exprWalker{visitor: v} -} - -// WalkerForLocalExpr returns file walker implementation for LocalExprVisitor. -func WalkerForLocalExpr(v LocalExprVisitor) linter.FileWalker { - return &localExprWalker{visitor: v} -} - -// WalkerForStmtList returns file walker implementation for StmtListVisitor. -func WalkerForStmtList(v StmtListVisitor) linter.FileWalker { - return &stmtListWalker{visitor: v} -} - -// WalkerForStmt returns file walker implementation for StmtVisitor. -func WalkerForStmt(v StmtVisitor) linter.FileWalker { - return &stmtWalker{visitor: v} -} - -// WalkerForTypeExpr returns file walker implementation for TypeExprVisitor. -func WalkerForTypeExpr(v TypeExprVisitor, info *types.Info) linter.FileWalker { - return &typeExprWalker{visitor: v, info: info} -} - -// WalkerForLocalComment returns file walker implementation for LocalCommentVisitor. -func WalkerForLocalComment(v LocalCommentVisitor) linter.FileWalker { - return &localCommentWalker{visitor: v} -} - -// WalkerForComment returns file walker implementation for CommentVisitor. -func WalkerForComment(v CommentVisitor) linter.FileWalker { - return &commentWalker{visitor: v} -} - -// WalkerForDocComment returns file walker implementation for DocCommentVisitor. -func WalkerForDocComment(v DocCommentVisitor) linter.FileWalker { - return &docCommentWalker{visitor: v} -} - -// WalkerForLocalDef returns file walker implementation for LocalDefVisitor. -func WalkerForLocalDef(v LocalDefVisitor, info *types.Info) linter.FileWalker { - return &localDefWalker{visitor: v, info: info} -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/internal/lintutil/astfind.go b/vendor/github.com/go-critic/go-critic/checkers/internal/lintutil/astfind.go deleted file mode 100644 index a6d0ad7c45..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/internal/lintutil/astfind.go +++ /dev/null @@ -1,41 +0,0 @@ -package lintutil - -import ( - "go/ast" - - "golang.org/x/tools/go/ast/astutil" -) - -// FindNode applies pred for root and all it's childs until it returns true. -// If followFunc is defined, it's called before following any node to check whether it needs to be followed. -// followFunc has to return true in order to continuing traversing the node and return false otherwise. -// Matched node is returned. -// If none of the nodes matched predicate, nil is returned. -func FindNode(root ast.Node, followFunc, pred func(ast.Node) bool) ast.Node { - var ( - found ast.Node - preFunc func(*astutil.Cursor) bool - ) - - if followFunc != nil { - preFunc = func(cur *astutil.Cursor) bool { - return followFunc(cur.Node()) - } - } - - astutil.Apply(root, - preFunc, - func(cur *astutil.Cursor) bool { - if pred(cur.Node()) { - found = cur.Node() - return false - } - return true - }) - return found -} - -// ContainsNode reports whether `FindNode(root, pred)!=nil`. -func ContainsNode(root ast.Node, pred func(ast.Node) bool) bool { - return FindNode(root, nil, pred) != nil -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/internal/lintutil/astflow.go b/vendor/github.com/go-critic/go-critic/checkers/internal/lintutil/astflow.go deleted file mode 100644 index f64907d69b..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/internal/lintutil/astflow.go +++ /dev/null @@ -1,86 +0,0 @@ -package lintutil - -import ( - "go/ast" - "go/token" - "go/types" - - "github.com/go-toolsmith/astequal" - "github.com/go-toolsmith/astp" - "github.com/go-toolsmith/typep" -) - -// Different utilities to make simple analysis over typed ast values flow. -// -// It's primitive and can't replace SSA, but the bright side is that -// it does not require building an additional IR eagerly. -// Expected to be used sparingly inside a few checkers. -// -// If proven really useful, can be moved to go-toolsmith library. - -// IsImmutable reports whether n can be modified through any operation. -func IsImmutable(info *types.Info, n ast.Expr) bool { - if astp.IsBasicLit(n) { - return true - } - tv, ok := info.Types[n] - return ok && !tv.Assignable() && !tv.Addressable() -} - -// CouldBeMutated reports whether dst can be modified inside body. -// -// Note that it does not take already existing pointers to dst. -// An example of safe and correct usage is checking of something -// that was just defined, so the dst is a result of that definition. -func CouldBeMutated(info *types.Info, body ast.Node, dst ast.Expr) bool { - if IsImmutable(info, dst) { // Fast path. - return false - } - - // We don't track pass-by-value. - // If it's already a pointer, passing it by value - // means that there can be a potential indirect modification. - // - // It's possible to be less conservative here and find at least - // one such value pass before giving up. - if typep.IsPointer(info.TypeOf(dst)) { - return true - } - - var isDst func(x ast.Expr) bool - if dst, ok := dst.(*ast.Ident); ok { - // Identifier can be shadowed, - // so we need to check the object as well. - obj := info.ObjectOf(dst) - if obj == nil { - return true // Being conservative - } - isDst = func(x ast.Expr) bool { - id, ok := x.(*ast.Ident) - return ok && id.Name == dst.Name && info.ObjectOf(id) == obj - } - } else { - isDst = func(x ast.Expr) bool { - return astequal.Expr(dst, x) - } - } - - return ContainsNode(body, func(n ast.Node) bool { - switch n := n.(type) { - case *ast.UnaryExpr: - if n.Op == token.AND && isDst(n.X) { - return true // Address taken - } - case *ast.AssignStmt: - for _, lhs := range n.Lhs { - if isDst(lhs) { - return true - } - } - case *ast.IncDecStmt: - // Incremented or decremented. - return isDst(n.X) - } - return false - }) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/internal/lintutil/astset.go b/vendor/github.com/go-critic/go-critic/checkers/internal/lintutil/astset.go deleted file mode 100644 index ebe7835e51..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/internal/lintutil/astset.go +++ /dev/null @@ -1,44 +0,0 @@ -package lintutil - -import ( - "go/ast" - - "github.com/go-toolsmith/astequal" -) - -// AstSet is a simple ast.Node set. -// Zero value is ready to use set. -// Can be reused after Clear call. -type AstSet struct { - items []ast.Node -} - -// Contains reports whether s contains x. -func (s *AstSet) Contains(x ast.Node) bool { - for i := range s.items { - if astequal.Node(s.items[i], x) { - return true - } - } - return false -} - -// Insert pushes x in s if it's not already there. -// Returns true if element was inserted. -func (s *AstSet) Insert(x ast.Node) bool { - if s.Contains(x) { - return false - } - s.items = append(s.items, x) - return true -} - -// Clear removes all element from set. -func (s *AstSet) Clear() { - s.items = s.items[:0] -} - -// Len returns the number of elements contained inside s. -func (s *AstSet) Len() int { - return len(s.items) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/internal/lintutil/zero_value.go b/vendor/github.com/go-critic/go-critic/checkers/internal/lintutil/zero_value.go deleted file mode 100644 index 4370f58185..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/internal/lintutil/zero_value.go +++ /dev/null @@ -1,94 +0,0 @@ -package lintutil - -import ( - "go/ast" - "go/constant" - "go/token" - "go/types" -) - -// IsZeroValue reports whether x represents zero value of its type. -// -// The functions is conservative and may return false for zero values -// if some cases are not handled in a comprehensive way -// but is should never return true for something that's not a proper zv. -func IsZeroValue(info *types.Info, x ast.Expr) bool { - switch x := x.(type) { - case *ast.BasicLit: - typ := info.TypeOf(x).Underlying().(*types.Basic) - v := info.Types[x].Value - var z constant.Value - switch { - case typ.Kind() == types.String: - z = constant.MakeString("") - case typ.Info()&types.IsInteger != 0: - z = constant.MakeInt64(0) - case typ.Info()&types.IsUnsigned != 0: - z = constant.MakeUint64(0) - case typ.Info()&types.IsFloat != 0: - z = constant.MakeFloat64(0) - default: - return false - } - return constant.Compare(v, token.EQL, z) - - case *ast.CompositeLit: - return len(x.Elts) == 0 - - default: - // Note that this function is not comprehensive. - return false - } -} - -// ZeroValueOf returns a zero value expression for typeExpr of type typ. -// If function can't find such a value, nil is returned. -func ZeroValueOf(typeExpr ast.Expr, typ types.Type) ast.Expr { - switch utyp := typ.Underlying().(type) { - case *types.Basic: - info := utyp.Info() - var zv ast.Expr - switch { - case info&types.IsInteger != 0: - zv = &ast.BasicLit{Kind: token.INT, Value: "0"} - case info&types.IsFloat != 0: - zv = &ast.BasicLit{Kind: token.FLOAT, Value: "0.0"} - case info&types.IsString != 0: - zv = &ast.BasicLit{Kind: token.STRING, Value: `""`} - case info&types.IsBoolean != 0: - zv = &ast.Ident{Name: "false"} - } - if isDefaultLiteralType(typ) { - return zv - } - return &ast.CallExpr{ - Fun: typeExpr, - Args: []ast.Expr{zv}, - } - - case *types.Slice, *types.Map, *types.Pointer, *types.Interface: - return &ast.CallExpr{ - Fun: typeExpr, - Args: []ast.Expr{&ast.Ident{Name: "nil"}}, - } - - case *types.Array, *types.Struct: - return &ast.CompositeLit{Type: typeExpr} - - default: - return nil - } -} - -func isDefaultLiteralType(typ types.Type) bool { - btyp, ok := typ.(*types.Basic) - if !ok { - return false - } - switch btyp.Kind() { - case types.Bool, types.Int, types.Float64, types.String: - return true - default: - return false - } -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/mapKey_checker.go b/vendor/github.com/go-critic/go-critic/checkers/mapKey_checker.go deleted file mode 100644 index 2885dc7254..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/mapKey_checker.go +++ /dev/null @@ -1,125 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/types" - "strings" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/checkers/internal/lintutil" - "github.com/go-critic/go-critic/linter" - - "github.com/go-toolsmith/astcast" - "github.com/go-toolsmith/astp" - "github.com/go-toolsmith/typep" -) - -func init() { - var info linter.CheckerInfo - info.Name = "mapKey" - info.Tags = []string{linter.DiagnosticTag} - info.Summary = "Detects suspicious map literal keys" - info.Before = ` -_ = map[string]int{ - "foo": 1, - "bar ": 2, -}` - info.After = ` -_ = map[string]int{ - "foo": 1, - "bar": 2, -}` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForExpr(&mapKeyChecker{ctx: ctx}), nil - }) -} - -type mapKeyChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext - - astSet lintutil.AstSet -} - -func (c *mapKeyChecker) VisitExpr(expr ast.Expr) { - lit := astcast.ToCompositeLit(expr) - if len(lit.Elts) < 2 { - return - } - - typ, ok := c.ctx.TypeOf(lit).Underlying().(*types.Map) - if !ok { - return - } - if !typep.HasStringKind(typ.Key().Underlying()) { - return - } - - c.checkWhitespace(lit) - c.checkDuplicates(lit) -} - -func (c *mapKeyChecker) checkDuplicates(lit *ast.CompositeLit) { - c.astSet.Clear() - - for _, elt := range lit.Elts { - kv := astcast.ToKeyValueExpr(elt) - if astp.IsBasicLit(kv.Key) { - // Basic lits are handled by the compiler. - continue - } - if !typep.SideEffectFree(c.ctx.TypesInfo, kv.Key) { - continue - } - if !c.astSet.Insert(kv.Key) { - c.warnDupKey(kv.Key) - } - } -} - -func (c *mapKeyChecker) checkWhitespace(lit *ast.CompositeLit) { - var whitespaceKey ast.Node - for _, elt := range lit.Elts { - key := astcast.ToBasicLit(astcast.ToKeyValueExpr(elt).Key) - if len(key.Value) < len(`" "`) { - continue - } - // s is unquoted string literal value. - s := key.Value[len(`"`) : len(key.Value)-len(`"`)] - if !strings.Contains(s, " ") { - continue - } - if whitespaceKey != nil { - // Already seen something with a whitespace. - // More than one entry => not suspicious. - return - } - if s == " " { - // If space is used as a key, maybe this map - // has something to do with spaces. Give up. - return - } - // Check if it has exactly 1 space prefix or suffix. - bad := strings.HasPrefix(s, " ") && !strings.HasPrefix(s, " ") || - strings.HasSuffix(s, " ") && !strings.HasSuffix(s, " ") - if !bad { - // These spaces can be a padding, - // or a legitimate part of a key. Give up. - return - } - whitespaceKey = key - } - - if whitespaceKey != nil { - c.warnWhitespace(whitespaceKey) - } -} - -func (c *mapKeyChecker) warnWhitespace(key ast.Node) { - c.ctx.Warn(key, "suspicious whitespace in %s key", key) -} - -func (c *mapKeyChecker) warnDupKey(key ast.Node) { - c.ctx.Warn(key, "suspicious duplicate %s key", key) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/methodExprCall_checker.go b/vendor/github.com/go-critic/go-critic/checkers/methodExprCall_checker.go deleted file mode 100644 index 755d3b4722..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/methodExprCall_checker.go +++ /dev/null @@ -1,58 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/token" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" - - "github.com/go-toolsmith/astcast" - "github.com/go-toolsmith/astcopy" - "github.com/go-toolsmith/typep" -) - -func init() { - var info linter.CheckerInfo - info.Name = "methodExprCall" - info.Tags = []string{linter.StyleTag, linter.ExperimentalTag} - info.Summary = "Detects method expression call that can be replaced with a method call" - info.Before = `f := foo{} -foo.bar(f)` - info.After = `f := foo{} -f.bar()` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForExpr(&methodExprCallChecker{ctx: ctx}), nil - }) -} - -type methodExprCallChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext -} - -func (c *methodExprCallChecker) VisitExpr(x ast.Expr) { - call := astcast.ToCallExpr(x) - s := astcast.ToSelectorExpr(call.Fun) - - if len(call.Args) < 1 || astcast.ToIdent(call.Args[0]).Name == "nil" { - return - } - - if typep.IsTypeExpr(c.ctx.TypesInfo, s.X) { - c.warn(call, s) - } -} - -func (c *methodExprCallChecker) warn(cause *ast.CallExpr, s *ast.SelectorExpr) { - selector := astcopy.SelectorExpr(s) - selector.X = cause.Args[0] - - // Remove "&" from the receiver (if any). - if u, ok := selector.X.(*ast.UnaryExpr); ok && u.Op == token.AND { - selector.X = u.X - } - - c.ctx.Warn(cause, "consider to change `%s` to `%s`", cause.Fun, selector) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/nestingReduce_checker.go b/vendor/github.com/go-critic/go-critic/checkers/nestingReduce_checker.go deleted file mode 100644 index dfe73018c8..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/nestingReduce_checker.go +++ /dev/null @@ -1,73 +0,0 @@ -package checkers - -import ( - "go/ast" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" -) - -func init() { - var info linter.CheckerInfo - info.Name = "nestingReduce" - info.Tags = []string{linter.StyleTag, linter.OpinionatedTag, linter.ExperimentalTag} - info.Params = linter.CheckerParams{ - "bodyWidth": { - Value: 5, - Usage: "min number of statements inside a branch to trigger a warning", - }, - } - info.Summary = "Finds where nesting level could be reduced" - info.Before = ` -for _, v := range a { - if v.Bool { - body() - } -}` - info.After = ` -for _, v := range a { - if !v.Bool { - continue - } - body() -}` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - c := &nestingReduceChecker{ctx: ctx} - c.bodyWidth = info.Params.Int("bodyWidth") - return astwalk.WalkerForStmt(c), nil - }) -} - -type nestingReduceChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext - - bodyWidth int -} - -func (c *nestingReduceChecker) VisitStmt(stmt ast.Stmt) { - switch stmt := stmt.(type) { - case *ast.ForStmt: - c.checkLoopBody(stmt.Body.List) - case *ast.RangeStmt: - c.checkLoopBody(stmt.Body.List) - } -} - -func (c *nestingReduceChecker) checkLoopBody(body []ast.Stmt) { - if len(body) != 1 { - return - } - stmt, ok := body[0].(*ast.IfStmt) - if !ok { - return - } - if len(stmt.Body.List) >= c.bodyWidth && stmt.Else == nil { - c.warnLoop(stmt) - } -} - -func (c *nestingReduceChecker) warnLoop(cause ast.Node) { - c.ctx.Warn(cause, "invert if cond, replace body with `continue`, move old body after the statement") -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/newDeref_checker.go b/vendor/github.com/go-critic/go-critic/checkers/newDeref_checker.go deleted file mode 100644 index 1a1b05e0df..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/newDeref_checker.go +++ /dev/null @@ -1,51 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/types" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/checkers/internal/lintutil" - "github.com/go-critic/go-critic/linter" - - "github.com/go-toolsmith/astcast" - "golang.org/x/tools/go/ast/astutil" -) - -func init() { - var info linter.CheckerInfo - info.Name = "newDeref" - info.Tags = []string{linter.StyleTag} - info.Summary = "Detects immediate dereferencing of `new` expressions" - info.Before = `x := *new(bool)` - info.After = `x := false` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForExpr(&newDerefChecker{ctx: ctx}), nil - }) -} - -type newDerefChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext -} - -func (c *newDerefChecker) VisitExpr(expr ast.Expr) { - deref := astcast.ToStarExpr(expr) - call := astcast.ToCallExpr(deref.X) - if astcast.ToIdent(call.Fun).Name == "new" { - typ := c.ctx.TypeOf(call.Args[0]) - // allow *new(T) if T is a type parameter, see #1272 for details - if _, ok := typ.(*types.TypeParam); ok { - return - } - zv := lintutil.ZeroValueOf(astutil.Unparen(call.Args[0]), typ) - if zv != nil { - c.warn(expr, zv) - } - } -} - -func (c *newDerefChecker) warn(cause, suggestion ast.Expr) { - c.ctx.Warn(cause, "replace `%s` with `%s`", cause, suggestion) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/nilValReturn_checker.go b/vendor/github.com/go-critic/go-critic/checkers/nilValReturn_checker.go deleted file mode 100644 index 9a1213f5c2..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/nilValReturn_checker.go +++ /dev/null @@ -1,72 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/token" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" - - "github.com/go-toolsmith/astequal" - "github.com/go-toolsmith/typep" -) - -func init() { - var info linter.CheckerInfo - info.Name = "nilValReturn" - info.Tags = []string{linter.DiagnosticTag, linter.ExperimentalTag} - info.Summary = "Detects return statements those results evaluate to nil" - info.Before = ` -if err == nil { - return err -}` - info.After = ` -// (A) - return nil explicitly -if err == nil { - return nil -} -// (B) - typo in "==", change to "!=" -if err != nil { - return err -}` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForStmt(&nilValReturnChecker{ctx: ctx}), nil - }) -} - -type nilValReturnChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext -} - -func (c *nilValReturnChecker) VisitStmt(stmt ast.Stmt) { - ifStmt, ok := stmt.(*ast.IfStmt) - if !ok || len(ifStmt.Body.List) != 1 { - return - } - ret, ok := ifStmt.Body.List[0].(*ast.ReturnStmt) - if !ok { - return - } - expr, ok := ifStmt.Cond.(*ast.BinaryExpr) - if !ok { - return - } - xIsNil := expr.Op == token.EQL && - typep.SideEffectFree(c.ctx.TypesInfo, expr.X) && - qualifiedName(expr.Y) == "nil" - if !xIsNil { - return - } - for _, res := range ret.Results { - if astequal.Expr(expr.X, res) { - c.warn(ret, expr.X) - break - } - } -} - -func (c *nilValReturnChecker) warn(cause, val ast.Node) { - c.ctx.Warn(cause, "returned expr is always nil; replace %s with nil", val) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/octalLiteral_checker.go b/vendor/github.com/go-critic/go-critic/checkers/octalLiteral_checker.go deleted file mode 100644 index a25fac85cc..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/octalLiteral_checker.go +++ /dev/null @@ -1,51 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/token" - "strings" - "unicode" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" - - "github.com/go-toolsmith/astcast" -) - -func init() { - var info linter.CheckerInfo - info.Name = "octalLiteral" - info.Tags = []string{linter.StyleTag, linter.ExperimentalTag, linter.OpinionatedTag} - info.Summary = "Detects old-style octal literals" - info.Before = `foo(02)` - info.After = `foo(0o2)` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForExpr(&octalLiteralChecker{ctx: ctx}), nil - }) -} - -type octalLiteralChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext -} - -func (c *octalLiteralChecker) VisitExpr(expr ast.Expr) { - if !c.ctx.GoVersion.GreaterOrEqual(linter.GoVersion{Major: 1, Minor: 13}) { - return - } - lit := astcast.ToBasicLit(expr) - if lit.Kind != token.INT { - return - } - if !strings.HasPrefix(lit.Value, "0") || len(lit.Value) == 1 { - return - } - if unicode.IsDigit(rune(lit.Value[1])) { - c.warn(lit) - } -} - -func (c *octalLiteralChecker) warn(lit *ast.BasicLit) { - c.ctx.Warn(lit, "use new octal literal style, 0o%s", lit.Value[len("0"):]) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/paramTypeCombine_checker.go b/vendor/github.com/go-critic/go-critic/checkers/paramTypeCombine_checker.go deleted file mode 100644 index c777fec9e6..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/paramTypeCombine_checker.go +++ /dev/null @@ -1,97 +0,0 @@ -package checkers - -import ( - "go/ast" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" - - "github.com/go-toolsmith/astcopy" - "github.com/go-toolsmith/astequal" -) - -func init() { - var info linter.CheckerInfo - info.Name = "paramTypeCombine" - info.Tags = []string{linter.StyleTag, linter.OpinionatedTag} - info.Summary = "Detects if function parameters could be combined by type and suggest the way to do it" - info.Before = `func foo(a, b int, c, d int, e, f int, g int) {}` - info.After = `func foo(a, b, c, d, e, f, g int) {}` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForFuncDecl(¶mTypeCombineChecker{ctx: ctx}), nil - }) -} - -type paramTypeCombineChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext -} - -func (c *paramTypeCombineChecker) EnterFunc(*ast.FuncDecl) bool { - return true -} - -func (c *paramTypeCombineChecker) VisitFuncDecl(decl *ast.FuncDecl) { - typ := c.optimizeFuncType(decl.Type) - if !astequal.Expr(typ, decl.Type) { - c.warn(decl.Type, typ) - } -} - -func (c *paramTypeCombineChecker) optimizeFuncType(f *ast.FuncType) *ast.FuncType { - optimizedParamFunc := astcopy.FuncType(f) - - optimizedParamFunc.Params = c.optimizeParams(f.Params) - optimizedParamFunc.Results = c.optimizeParams(f.Results) - - return optimizedParamFunc -} - -func (c *paramTypeCombineChecker) optimizeParams(params *ast.FieldList) *ast.FieldList { - // To avoid false positives, skip unnamed param lists. - // - // We're using a property that Go only permits unnamed params - // for the whole list, so it's enough to check whether any of - // ast.Field have empty name list. - skip := params == nil || - len(params.List) < 2 || - len(params.List[0].Names) == 0 || - c.paramsAreMultiLine(params) - if skip { - return params - } - - list := []*ast.Field{} - names := make([]*ast.Ident, len(params.List[0].Names)) - copy(names, params.List[0].Names) - list = append(list, &ast.Field{ - Names: names, - Type: params.List[0].Type, - }) - for i, p := range params.List[1:] { - names = make([]*ast.Ident, len(p.Names)) - copy(names, p.Names) - if astequal.Expr(p.Type, params.List[i].Type) { - list[len(list)-1].Names = append(list[len(list)-1].Names, names...) - } else { - list = append(list, &ast.Field{ - Names: names, - Type: params.List[i+1].Type, - }) - } - } - return &ast.FieldList{ - List: list, - } -} - -func (c *paramTypeCombineChecker) warn(f1, f2 *ast.FuncType) { - c.ctx.Warn(f1, "%s could be replaced with %s", f1, f2) -} - -func (c *paramTypeCombineChecker) paramsAreMultiLine(params *ast.FieldList) bool { - startPos := c.ctx.FileSet.Position(params.Opening) - endPos := c.ctx.FileSet.Position(params.Closing) - return startPos.Line != endPos.Line -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/ptrToRefParam_checker.go b/vendor/github.com/go-critic/go-critic/checkers/ptrToRefParam_checker.go deleted file mode 100644 index 172a4acb58..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/ptrToRefParam_checker.go +++ /dev/null @@ -1,70 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/types" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" -) - -func init() { - var info linter.CheckerInfo - info.Name = "ptrToRefParam" - info.Tags = []string{linter.StyleTag, linter.OpinionatedTag, linter.ExperimentalTag} - info.Summary = "Detects input and output parameters that have a type of pointer to referential type" - info.Before = `func f(m *map[string]int) (*chan *int)` - info.After = `func f(m map[string]int) (chan *int)` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForFuncDecl(&ptrToRefParamChecker{ctx: ctx}), nil - }) -} - -type ptrToRefParamChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext -} - -func (c *ptrToRefParamChecker) VisitFuncDecl(fn *ast.FuncDecl) { - c.checkParams(fn.Type.Params.List) - if fn.Type.Results != nil { - c.checkParams(fn.Type.Results.List) - } -} - -func (c *ptrToRefParamChecker) checkParams(params []*ast.Field) { - for _, param := range params { - ptr, ok := c.ctx.TypeOf(param.Type).(*types.Pointer) - if !ok { - continue - } - - if c.isRefType(ptr.Elem()) { - if len(param.Names) == 0 { - c.ctx.Warn(param, "consider to make non-pointer type for `%s`", param.Type) - } else { - for i := range param.Names { - c.warn(param.Names[i]) - } - } - } - } -} - -func (c *ptrToRefParamChecker) isRefType(x types.Type) bool { - switch typ := x.(type) { - case *types.Map, *types.Chan, *types.Interface: - return true - case *types.Named: - // Handle underlying type only for interfaces. - if _, ok := typ.Underlying().(*types.Interface); ok { - return true - } - } - return false -} - -func (c *ptrToRefParamChecker) warn(id *ast.Ident) { - c.ctx.Warn(id, "consider `%s' to be of non-pointer type", id) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/rangeAppendAll_checker.go b/vendor/github.com/go-critic/go-critic/checkers/rangeAppendAll_checker.go deleted file mode 100644 index f4851d4024..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/rangeAppendAll_checker.go +++ /dev/null @@ -1,100 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/token" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" - "github.com/go-toolsmith/astcast" - "golang.org/x/tools/go/ast/astutil" -) - -func init() { - var info linter.CheckerInfo - info.Name = "rangeAppendAll" - info.Tags = []string{linter.DiagnosticTag, linter.ExperimentalTag} - info.Summary = "Detects append all its data while range it" - info.Before = `for _, n := range ns { - ... - rs = append(rs, ns...) // append all slice data - } -}` - info.After = `for _, n := range ns { - ... - rs = append(rs, n) - } -}` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - c := &rangeAppendAllChecker{ctx: ctx} - return astwalk.WalkerForStmt(c), nil - }) -} - -type rangeAppendAllChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext -} - -func (c *rangeAppendAllChecker) VisitStmt(stmt ast.Stmt) { - rangeStmt, ok := stmt.(*ast.RangeStmt) - if !ok || len(rangeStmt.Body.List) == 0 { - return - } - rangeIdent, ok := rangeStmt.X.(*ast.Ident) - if !ok { - return - } - rangeObj := c.ctx.TypesInfo.ObjectOf(rangeIdent) - - astutil.Apply(rangeStmt.Body, nil, func(cur *astutil.Cursor) bool { - appendFrom := c.getValidAppendFrom(cur.Node()) - if appendFrom != nil { - appendFromObj := c.ctx.TypesInfo.ObjectOf(appendFrom) - if appendFromObj == rangeObj { - c.warn(appendFrom) - } - } - return true - }) -} - -func (c *rangeAppendAllChecker) getValidAppendFrom(expr ast.Node) *ast.Ident { - call := astcast.ToCallExpr(expr) - if len(call.Args) != 2 || call.Ellipsis == token.NoPos { - return nil - } - if qualifiedName(call.Fun) != "append" { - return nil - } - if c.isSliceLiteral(call.Args[0]) { - return nil - } - appendFrom, ok := call.Args[1].(*ast.Ident) - if !ok { - return nil - } - return appendFrom -} - -func (c *rangeAppendAllChecker) isSliceLiteral(arg ast.Expr) bool { - switch v := arg.(type) { - // []T{}, []T{n} - case *ast.CompositeLit: - return true - // []T(nil) - case *ast.CallExpr: - if astcast.ToArrayType(v.Fun) != astcast.NilArrayType && len(v.Args) == 1 { - id := astcast.ToIdent(v.Args[0]) - return id.Name == "nil" && id.Obj == nil - } - return false - default: - return false - } -} - -func (c *rangeAppendAllChecker) warn(appendFrom *ast.Ident) { - c.ctx.Warn(appendFrom, "append all `%s` data while range it", appendFrom) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/rangeExprCopy_checker.go b/vendor/github.com/go-critic/go-critic/checkers/rangeExprCopy_checker.go deleted file mode 100644 index 3f61ee0bda..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/rangeExprCopy_checker.go +++ /dev/null @@ -1,80 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/types" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" -) - -func init() { - var info linter.CheckerInfo - info.Name = "rangeExprCopy" - info.Tags = []string{linter.PerformanceTag} - info.Params = linter.CheckerParams{ - "sizeThreshold": { - Value: 512, - Usage: "size in bytes that makes the warning trigger", - }, - "skipTestFuncs": { - Value: true, - Usage: "whether to check test functions", - }, - } - info.Summary = "Detects expensive copies of `for` loop range expressions" - info.Details = "Suggests to use pointer to array to avoid the copy using `&` on range expression." - info.Before = ` -var xs [2048]byte -for _, x := range xs { // Copies 2048 bytes - // Loop body. -}` - info.After = ` -var xs [2048]byte -for _, x := range &xs { // No copy - // Loop body. -}` - info.Note = "See Go issue for details: https://github.com/golang/go/issues/15812." - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - c := &rangeExprCopyChecker{ctx: ctx} - c.sizeThreshold = int64(info.Params.Int("sizeThreshold")) - c.skipTestFuncs = info.Params.Bool("skipTestFuncs") - return astwalk.WalkerForStmt(c), nil - }) -} - -type rangeExprCopyChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext - - sizeThreshold int64 - skipTestFuncs bool -} - -func (c *rangeExprCopyChecker) EnterFunc(fn *ast.FuncDecl) bool { - return fn.Body != nil && - !(c.skipTestFuncs && isUnitTestFunc(c.ctx, fn)) -} - -func (c *rangeExprCopyChecker) VisitStmt(stmt ast.Stmt) { - rng, ok := stmt.(*ast.RangeStmt) - if !ok || rng.Key == nil || rng.Value == nil { - return - } - tv := c.ctx.TypesInfo.Types[rng.X] - if !tv.Addressable() { - return - } - if _, ok := tv.Type.(*types.Array); !ok { - return - } - if size, ok := c.ctx.SizeOf(tv.Type); ok && size >= c.sizeThreshold { - c.warn(rng, size) - } -} - -func (c *rangeExprCopyChecker) warn(rng *ast.RangeStmt, size int64) { - c.ctx.Warn(rng, "copy of %s (%d bytes) can be avoided with &%s", - rng.X, size, rng.X) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/rangeValCopy_checker.go b/vendor/github.com/go-critic/go-critic/checkers/rangeValCopy_checker.go deleted file mode 100644 index 6d15c30cd1..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/rangeValCopy_checker.go +++ /dev/null @@ -1,76 +0,0 @@ -package checkers - -import ( - "go/ast" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" -) - -func init() { - var info linter.CheckerInfo - info.Name = "rangeValCopy" - info.Tags = []string{linter.PerformanceTag} - info.Params = linter.CheckerParams{ - "sizeThreshold": { - Value: 128, - Usage: "size in bytes that makes the warning trigger", - }, - "skipTestFuncs": { - Value: true, - Usage: "whether to check test functions", - }, - } - info.Summary = "Detects loops that copy big objects during each iteration" - info.Details = "Suggests to use index access or take address and make use pointer instead." - info.Before = ` -xs := make([][1024]byte, length) -for _, x := range xs { - // Loop body. -}` - info.After = ` -xs := make([][1024]byte, length) -for i := range xs { - x := &xs[i] - // Loop body. -}` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - c := &rangeValCopyChecker{ctx: ctx} - c.sizeThreshold = int64(info.Params.Int("sizeThreshold")) - c.skipTestFuncs = info.Params.Bool("skipTestFuncs") - return astwalk.WalkerForStmt(c), nil - }) -} - -type rangeValCopyChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext - - sizeThreshold int64 - skipTestFuncs bool -} - -func (c *rangeValCopyChecker) EnterFunc(fn *ast.FuncDecl) bool { - return fn.Body != nil && - !(c.skipTestFuncs && isUnitTestFunc(c.ctx, fn)) -} - -func (c *rangeValCopyChecker) VisitStmt(stmt ast.Stmt) { - rng, ok := stmt.(*ast.RangeStmt) - if !ok || rng.Value == nil { - return - } - typ := c.ctx.TypeOf(rng.Value) - if typ == nil { - return - } - size, ok := c.ctx.SizeOf(typ) - if ok && size >= c.sizeThreshold { - c.warn(rng, size) - } -} - -func (c *rangeValCopyChecker) warn(n ast.Node, size int64) { - c.ctx.Warn(n, "each iteration copies %d bytes (consider pointers or indexing)", size) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/regexpPattern_checker.go b/vendor/github.com/go-critic/go-critic/checkers/regexpPattern_checker.go deleted file mode 100644 index 45aba261ba..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/regexpPattern_checker.go +++ /dev/null @@ -1,68 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/constant" - "regexp" - "strings" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" -) - -func init() { - var info linter.CheckerInfo - info.Name = "regexpPattern" - info.Tags = []string{linter.DiagnosticTag, linter.ExperimentalTag} - info.Summary = "Detects suspicious regexp patterns" - info.Before = "regexp.MustCompile(`google.com|yandex.ru`)" - info.After = "regexp.MustCompile(`google\\.com|yandex\\.ru`)" - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - domains := []string{ - "com", - "org", - "info", - "net", - "ru", - "de", - } - - allDomains := strings.Join(domains, "|") - domainRE := regexp.MustCompile(`[^\\]\.(` + allDomains + `)\b`) - return astwalk.WalkerForExpr(®expPatternChecker{ - ctx: ctx, - domainRE: domainRE, - }), nil - }) -} - -type regexpPatternChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext - - domainRE *regexp.Regexp -} - -func (c *regexpPatternChecker) VisitExpr(x ast.Expr) { - call, ok := x.(*ast.CallExpr) - if !ok { - return - } - - switch qualifiedName(call.Fun) { - case "regexp.Compile", "regexp.CompilePOSIX", "regexp.MustCompile", "regexp.MustCompilePosix": - cv := c.ctx.TypesInfo.Types[call.Args[0]].Value - if cv == nil || cv.Kind() != constant.String { - return - } - s := constant.StringVal(cv) - if m := c.domainRE.FindStringSubmatch(s); m != nil { - c.warnDomain(call.Args[0], m[1]) - } - } -} - -func (c *regexpPatternChecker) warnDomain(cause ast.Expr, domain string) { - c.ctx.Warn(cause, "'.%s' should probably be '\\.%s'", domain, domain) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/regexpSimplify_checker.go b/vendor/github.com/go-critic/go-critic/checkers/regexpSimplify_checker.go deleted file mode 100644 index f500f43500..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/regexpSimplify_checker.go +++ /dev/null @@ -1,512 +0,0 @@ -package checkers - -import ( - "fmt" - "go/ast" - "go/constant" - "log" - "strings" - "unicode/utf8" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" - - "github.com/quasilyte/regex/syntax" -) - -func init() { - var info linter.CheckerInfo - info.Name = "regexpSimplify" - info.Tags = []string{linter.StyleTag, linter.ExperimentalTag, linter.OpinionatedTag} - info.Summary = "Detects regexp patterns that can be simplified" - info.Before = "regexp.MustCompile(`(?:a|b|c) [a-z][a-z]*`)" - info.After = "regexp.MustCompile(`[abc] {3}[a-z]+`)" - - // TODO(quasilyte): add params to control most opinionated replacements - // like `[0-9] -> \d` - // `[[:digit:]] -> \d` - // `[A-Za-z0-9_]` -> `\w` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - opts := &syntax.ParserOptions{ - NoLiterals: true, - } - c := ®expSimplifyChecker{ - ctx: ctx, - parser: syntax.NewParser(opts), - out: &strings.Builder{}, - } - return astwalk.WalkerForExpr(c), nil - }) -} - -type regexpSimplifyChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext - parser *syntax.Parser - - // out is a tmp buffer where we build a simplified regexp pattern. - out *strings.Builder - // score is a number of applied simplifications - score int -} - -func (c *regexpSimplifyChecker) VisitExpr(x ast.Expr) { - call, ok := x.(*ast.CallExpr) - if !ok { - return - } - - switch qualifiedName(call.Fun) { - case "regexp.Compile", "regexp.MustCompile": - cv := c.ctx.TypesInfo.Types[call.Args[0]].Value - if cv == nil || cv.Kind() != constant.String { - return - } - pat := constant.StringVal(cv) - if len(pat) > 60 { - // Skip scary regexp patterns for now. - break - } - - // Only do 2 passes. - simplified := pat - for pass := 0; pass < 2; pass++ { - candidate := c.simplify(pass, simplified) - if candidate == "" { - break - } - simplified = candidate - } - if simplified != "" && simplified != pat { - c.warn(call.Args[0], pat, simplified) - } - } -} - -func (c *regexpSimplifyChecker) simplify(pass int, pat string) string { - re, err := c.parser.Parse(pat) - if err != nil { - return "" - } - - c.score = 0 - c.out.Reset() - - // TODO(quasilyte): suggest char ranges for things like [012345689]? - // TODO(quasilyte): evaluate char range to suggest better replacements. - // TODO(quasilyte): (?:ab|ac) -> a[bc] - // TODO(quasilyte): suggest "s" and "." flag if things like [\w\W] are used. - // TODO(quasilyte): x{n}x? -> x{n,n+1} - - c.walk(re.Expr) - - if debug() { - // This happens only in one of two cases: - // 1. Parser has a bug and we got invalid AST for the given pattern. - // 2. Simplifier incorrectly built a replacement string from the AST. - if c.score == 0 && c.out.String() != pat { - log.Printf("pass %d: unexpected pattern diff:\n\thave: %q\n\twant: %q", - pass, c.out.String(), pat) - } - } - - if c.score > 0 { - return c.out.String() - } - return "" -} - -func (c *regexpSimplifyChecker) walk(e syntax.Expr) { - out := c.out - - switch e.Op { - case syntax.OpConcat: - c.walkConcat(e) - - case syntax.OpAlt: - c.walkAlt(e) - - case syntax.OpCharRange: - s := c.simplifyCharRange(e) - if s != "" { - out.WriteString(s) - c.score++ - } else { - out.WriteString(e.Value) - } - - case syntax.OpGroupWithFlags: - out.WriteString("(") - out.WriteString(e.Args[1].Value) - out.WriteString(":") - c.walk(e.Args[0]) - out.WriteString(")") - case syntax.OpGroup: - c.walkGroup(e) - case syntax.OpCapture: - out.WriteString("(") - c.walk(e.Args[0]) - out.WriteString(")") - case syntax.OpNamedCapture: - out.WriteString("(?P<") - out.WriteString(e.Args[1].Value) - out.WriteString(">") - c.walk(e.Args[0]) - out.WriteString(")") - - case syntax.OpRepeat: - // TODO(quasilyte): is it worth it to analyze repeat argument - // more closely and handle `{n,n} -> {n}` cases? - rep := e.Args[1].Value - switch rep { - case "{0,1}": - c.walk(e.Args[0]) - out.WriteString("?") - c.score++ - case "{1,}": - c.walk(e.Args[0]) - out.WriteString("+") - c.score++ - case "{0,}": - c.walk(e.Args[0]) - out.WriteString("*") - c.score++ - case "{0}": - // Maybe {0} should be reported by another check, regexpLint? - c.score++ - case "{1}": - c.walk(e.Args[0]) - c.score++ - default: - c.walk(e.Args[0]) - out.WriteString(rep) - } - - case syntax.OpPosixClass: - out.WriteString(e.Value) - - case syntax.OpNegCharClass: - s := c.simplifyNegCharClass(e) - if s != "" { - c.out.WriteString(s) - c.score++ - } else { - out.WriteString("[^") - for _, e := range e.Args { - c.walk(e) - } - out.WriteString("]") - } - - case syntax.OpCharClass: - s := c.simplifyCharClass(e) - if s != "" { - c.out.WriteString(s) - c.score++ - } else { - out.WriteString("[") - for _, e := range e.Args { - c.walk(e) - } - out.WriteString("]") - } - - case syntax.OpEscapeChar: - switch e.Value { - case `\&`, `\#`, `\!`, `\@`, `\%`, `\<`, `\>`, `\:`, `\;`, `\/`, `\,`, `\=`, `\.`: - c.score++ - out.WriteString(e.Value[len(`\`):]) - default: - out.WriteString(e.Value) - } - - case syntax.OpQuestion, syntax.OpNonGreedy: - c.walk(e.Args[0]) - out.WriteString("?") - case syntax.OpStar: - c.walk(e.Args[0]) - out.WriteString("*") - case syntax.OpPlus: - c.walk(e.Args[0]) - out.WriteString("+") - - default: - out.WriteString(e.Value) - } -} - -func (c *regexpSimplifyChecker) walkGroup(g syntax.Expr) { - switch g.Args[0].Op { - case syntax.OpChar, syntax.OpEscapeChar, syntax.OpEscapeMeta, syntax.OpCharClass: - c.walk(g.Args[0]) - c.score++ - return - } - - c.out.WriteString("(?:") - c.walk(g.Args[0]) - c.out.WriteString(")") -} - -func (c *regexpSimplifyChecker) simplifyNegCharClass(e syntax.Expr) string { - switch e.Value { - case `[^0-9]`: - return `\D` - case `[^\s]`: - return `\S` - case `[^\S]`: - return `\s` - case `[^\w]`: - return `\W` - case `[^\W]`: - return `\w` - case `[^\d]`: - return `\D` - case `[^\D]`: - return `\d` - case `[^[:^space:]]`: - return `\s` - case `[^[:space:]]`: - return `\S` - case `[^[:^word:]]`: - return `\w` - case `[^[:word:]]`: - return `\W` - case `[^[:^digit:]]`: - return `\d` - case `[^[:digit:]]`: - return `\D` - } - - return "" -} - -func (c *regexpSimplifyChecker) simplifyCharClass(e syntax.Expr) string { - switch e.Value { - case `[0-9]`: - return `\d` - case `[[:word:]]`: - return `\w` - case `[[:^word:]]`: - return `\W` - case `[[:digit:]]`: - return `\d` - case `[[:^digit:]]`: - return `\D` - case `[[:space:]]`: - return `\s` - case `[[:^space:]]`: - return `\S` - case `[][]`: - return `\]\[` - case `[]]`: - return `\]` - } - - if len(e.Args) == 1 { - switch e.Args[0].Op { - case syntax.OpChar: - switch v := e.Args[0].Value; v { - case "|", "*", "+", "?", ".", "[", "^", "$", "(", ")": - // Can't take outside of the char group without escaping. - default: - return v - } - case syntax.OpEscapeChar: - return e.Args[0].Value - } - } - - return "" -} - -func (c *regexpSimplifyChecker) canMerge(x, y syntax.Expr) bool { - if x.Op != y.Op { - return false - } - switch x.Op { - case syntax.OpChar, syntax.OpCharClass, syntax.OpEscapeMeta, syntax.OpEscapeChar, syntax.OpNegCharClass, syntax.OpGroup: - return x.Value == y.Value - default: - return false - } -} - -func (c *regexpSimplifyChecker) canCombine(x, y syntax.Expr) (threshold int, ok bool) { - if x.Op != y.Op { - return 0, false - } - - switch x.Op { - case syntax.OpDot: - return 3, true - - case syntax.OpChar: - if x.Value != y.Value { - return 0, false - } - if x.Value == " " { - return 1, true - } - return 4, true - - case syntax.OpEscapeMeta, syntax.OpEscapeChar: - if x.Value == y.Value { - return 2, true - } - - case syntax.OpCharClass, syntax.OpNegCharClass, syntax.OpGroup: - if x.Value == y.Value { - return 1, true - } - } - - return 0, false -} - -func (c *regexpSimplifyChecker) concatLiteral(e syntax.Expr) string { - if e.Op == syntax.OpConcat && c.allChars(e) { - return e.Value - } - return "" -} - -func (c *regexpSimplifyChecker) allChars(e syntax.Expr) bool { - for _, a := range e.Args { - if a.Op != syntax.OpChar { - return false - } - } - return true -} - -func (c *regexpSimplifyChecker) factorPrefixSuffix(alt syntax.Expr) bool { - // TODO: more forms of prefixes/suffixes? - // - // A more generalized algorithm could handle `fo|fo1|fo2` -> `fo[12]?`. - // but it's an open question whether the latter form universally better. - // - // Right now it handles only the simplest cases: - // `http|https` -> `https?` - // `xfoo|foo` -> `x?foo` - if len(alt.Args) != 2 { - return false - } - x := c.concatLiteral(alt.Args[0]) - y := c.concatLiteral(alt.Args[1]) - if x == y { - return false // Reject non-literals and identical strings early - } - - // Let x be a shorter string. - if len(x) > len(y) { - x, y = y, x - } - // Do we have a common prefix? - tail := strings.TrimPrefix(y, x) - if len(tail) <= utf8.UTFMax && utf8.RuneCountInString(tail) == 1 { - c.out.WriteString(x + tail + "?") - c.score++ - return true - } - // Do we have a common suffix? - head := strings.TrimSuffix(y, x) - if len(head) <= utf8.UTFMax && utf8.RuneCountInString(head) == 1 { - c.out.WriteString(head + "?" + x) - c.score++ - return true - } - return false -} - -func (c *regexpSimplifyChecker) walkAlt(alt syntax.Expr) { - // `x|y|z` -> `[xyz]`. - if c.allChars(alt) { - c.score++ - c.out.WriteString("[") - for _, e := range alt.Args { - c.out.WriteString(e.Value) - } - c.out.WriteString("]") - return - } - - if c.factorPrefixSuffix(alt) { - return - } - - for i, e := range alt.Args { - c.walk(e) - if i != len(alt.Args)-1 { - c.out.WriteString("|") - } - } -} - -func (c *regexpSimplifyChecker) walkConcat(concat syntax.Expr) { - i := 0 - for i < len(concat.Args) { - x := concat.Args[i] - c.walk(x) - i++ - - if i >= len(concat.Args) { - break - } - - // Try merging `xy*` into `x+` where x=y. - if concat.Args[i].Op == syntax.OpStar { - if c.canMerge(x, concat.Args[i].Args[0]) { - c.out.WriteString("+") - c.score++ - i++ - continue - } - } - - // Try combining `xy` into `x{2}` where x=y. - threshold, ok := c.canCombine(x, concat.Args[i]) - if !ok { - continue - } - n := 1 // Can combine at least 1 pair. - for j := i + 1; j < len(concat.Args); j++ { - _, ok := c.canCombine(x, concat.Args[j]) - if !ok { - break - } - n++ - } - if n >= threshold { - fmt.Fprintf(c.out, "{%d}", n+1) - c.score++ - i += n - } - } -} - -func (c *regexpSimplifyChecker) simplifyCharRange(rng syntax.Expr) string { - if rng.Args[0].Op != syntax.OpChar || rng.Args[1].Op != syntax.OpChar { - return "" - } - - lo := rng.Args[0].Value - hi := rng.Args[1].Value - if len(lo) == 1 && len(hi) == 1 { - switch hi[0] - lo[0] { - case 0: - return lo - case 1: - return lo + hi - case 2: - return lo + string(lo[0]+1) + hi - } - } - - return "" -} - -func (c *regexpSimplifyChecker) warn(cause ast.Expr, orig, suggest string) { - c.ctx.Warn(cause, "can re-write `%s` as `%s`", orig, suggest) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/ruleguard_checker.go b/vendor/github.com/go-critic/go-critic/checkers/ruleguard_checker.go deleted file mode 100644 index 485819842c..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/ruleguard_checker.go +++ /dev/null @@ -1,322 +0,0 @@ -package checkers - -import ( - "bytes" - "errors" - "fmt" - "go/ast" - "go/token" - "log" - "os" - "path/filepath" - "sort" - "strings" - - "github.com/go-critic/go-critic/linter" - - "github.com/quasilyte/go-ruleguard/ruleguard" -) - -func init() { - var info linter.CheckerInfo - info.Name = "ruleguard" - info.Tags = []string{linter.StyleTag, linter.ExperimentalTag} - info.Params = linter.CheckerParams{ - "rules": { - Value: "", - Usage: "comma-separated list of gorule file paths. Glob patterns such as 'rules-*.go' may be specified", - }, - "debug": { - Value: "", - Usage: "enable debug for the specified named rules group", - }, - "failOnError": { - Value: false, - Usage: "deprecated, use failOn param; if set to true, identical to failOn='all', otherwise failOn=''", - }, - "failOn": { - Value: "", - Usage: `Determines the behavior when an error occurs while parsing ruleguard files. -If flag is not set, log error and skip rule files that contain an error. -If flag is set, the value must be a comma-separated list of error conditions. -* 'import': rule refers to a package that cannot be loaded. -* 'dsl': gorule file does not comply with the ruleguard DSL.`, - }, - "enable": { - Value: "", - Usage: "comma-separated list of enabled groups or skip empty to enable everything", - }, - "disable": { - Value: "", - Usage: "comma-separated list of disabled groups or skip empty to enable everything", - }, - } - info.Summary = "Runs user-defined rules using ruleguard linter" - info.Details = "Reads a rules file and turns them into go-critic checkers." - info.Before = `N/A` - info.After = `N/A` - info.Note = "See https://github.com/quasilyte/go-ruleguard." - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return newRuleguardChecker(&info, ctx) - }) -} - -// parseErrorHandler is used to determine whether to ignore or fail ruleguard parsing errors. -type parseErrorHandler struct { - // failureConditions is a map of predicates which are evaluated against a ruleguard parsing error. - // If at least one predicate returns true, then an error is returned. - // Otherwise, the ruleguard file is skipped. - failureConditions map[string]func(err error) bool -} - -// failOnParseError returns true if a parseError occurred and that error should be not be ignored. -func (e parseErrorHandler) failOnParseError(parseError error) bool { - for _, p := range e.failureConditions { - if p(parseError) { - return true - } - } - return false -} - -func newErrorHandler(failOnErrorFlag string) (*parseErrorHandler, error) { - h := parseErrorHandler{ - failureConditions: make(map[string]func(err error) bool), - } - failOnErrorPredicates := map[string]func(error) bool{ - "dsl": func(err error) bool { var e *ruleguard.ImportError; return !errors.As(err, &e) }, - "import": func(err error) bool { var e *ruleguard.ImportError; return errors.As(err, &e) }, - "all": func(_ error) bool { return true }, - } - for _, k := range strings.Split(failOnErrorFlag, ",") { - if k == "" { - continue - } - if p, ok := failOnErrorPredicates[k]; ok { - h.failureConditions[k] = p - } else { - // Wrong flag value. - supportedValues := []string{} - for key := range failOnErrorPredicates { - supportedValues = append(supportedValues, key) - } - return nil, fmt.Errorf("ruleguard init error: 'failOnError' flag '%s' is invalid. It must be a comma-separated list and supported values are '%s'", - k, strings.Join(supportedValues, ",")) - } - } - return &h, nil -} - -func newRuleguardChecker(info *linter.CheckerInfo, ctx *linter.CheckerContext) (*ruleguardChecker, error) { - c := &ruleguardChecker{ - ctx: ctx, - debugGroup: info.Params.String("debug"), - } - rulesFlag := info.Params.String("rules") - if rulesFlag == "" { - return c, nil - } - failOn := info.Params.String("failOn") - if failOn == "" { - if info.Params.Bool("failOnError") { - failOn = "all" - } - } - h, err := newErrorHandler(failOn) - if err != nil { - return nil, err - } - - engine := ruleguard.NewEngine() - engine.InferBuildContext() - fset := token.NewFileSet() - filePatterns := strings.Split(rulesFlag, ",") - - enabledGroups := make(map[string]bool) - disabledGroups := make(map[string]bool) - enabledTags := make(map[string]bool) - disabledTags := make(map[string]bool) - - for _, g := range strings.Split(info.Params.String("disable"), ",") { - g = strings.TrimSpace(g) - if strings.HasPrefix(g, "#") { - disabledTags[strings.TrimPrefix(g, "#")] = true - continue - } - - disabledGroups[g] = true - } - flagEnable := info.Params.String("enable") - if flagEnable != "" { - for _, g := range strings.Split(flagEnable, ",") { - g = strings.TrimSpace(g) - if strings.HasPrefix(g, "#") { - enabledTags[strings.TrimPrefix(g, "#")] = true - continue - } - - enabledGroups[g] = true - } - } - - if !enabledTags[linter.ExperimentalTag] { - disabledTags[linter.ExperimentalTag] = true - } - ruleguardDebug := os.Getenv("GOCRITIC_RULEGUARD_DEBUG") != "" - - inEnabledTags := func(g *ruleguard.GoRuleGroup) bool { - for _, t := range g.DocTags { - if enabledTags[t] { - return true - } - } - return false - } - inDisabledTags := func(g *ruleguard.GoRuleGroup) string { - for _, t := range g.DocTags { - if disabledTags[t] { - return t - } - } - return "" - } - - loadContext := &ruleguard.LoadContext{ - Fset: fset, - DebugImports: ruleguardDebug, - DebugPrint: debugPrint, - GroupFilter: func(g *ruleguard.GoRuleGroup) bool { - enabled := flagEnable == "" || enabledGroups[g.Name] || inEnabledTags(g) - whyDisabled := "" - - switch { - case !enabled: - whyDisabled = "not enabled by name or tag (-enable flag)" - case disabledGroups[g.Name]: - whyDisabled = "disabled by name (-disable flag)" - default: - if tag := inDisabledTags(g); tag != "" { - whyDisabled = fmt.Sprintf("disabled by %s tag (-disable flag)", tag) - } - } - - if ruleguardDebug { - if whyDisabled != "" { - debugPrint(fmt.Sprintf("(-) %s is %s", g.Name, whyDisabled)) - } else { - debugPrint(fmt.Sprintf("(+) %s is enabled", g.Name)) - } - } - return whyDisabled == "" - }, - } - - loaded := 0 - for _, filePattern := range filePatterns { - filenames, err := filepath.Glob(strings.TrimSpace(filePattern)) - if err != nil { - // The only possible returned error is ErrBadPattern, when pattern is malformed. - log.Printf("ruleguard init error: %+v", err) - continue - } - if len(filenames) == 0 { - return nil, fmt.Errorf("ruleguard init error: no file matching '%s'", strings.TrimSpace(filePattern)) - } - for _, filename := range filenames { - data, err := os.ReadFile(filename) - if err != nil { - if h.failOnParseError(err) { - return nil, fmt.Errorf("ruleguard init error: %+v", err) - } - log.Printf("ruleguard init error, skip %s: %+v", filename, err) - } - if err := engine.Load(loadContext, filename, bytes.NewReader(data)); err != nil { - if h.failOnParseError(err) { - return nil, fmt.Errorf("ruleguard init error: %+v", err) - } - log.Printf("ruleguard init error, skip %s: %+v", filename, err) - } - loaded++ - } - } - - if loaded != 0 { - c.engine = engine - } - return c, nil -} - -type ruleguardChecker struct { - ctx *linter.CheckerContext - - debugGroup string - engine *ruleguard.Engine -} - -func (c *ruleguardChecker) WalkFile(f *ast.File) { - if c.engine == nil { - return - } - - runRuleguardEngine(c.ctx, f, c.engine, &ruleguard.RunContext{ - Debug: c.debugGroup, - DebugPrint: func(s string) { - fmt.Fprintln(os.Stderr, s) - }, - Pkg: c.ctx.Pkg, - Types: c.ctx.TypesInfo, - Sizes: c.ctx.SizesInfo, - Fset: c.ctx.FileSet, - TruncateLen: 100, - }) -} - -func runRuleguardEngine(ctx *linter.CheckerContext, f *ast.File, e *ruleguard.Engine, runCtx *ruleguard.RunContext) { - type ruleguardReport struct { - pos token.Pos - message string - fix linter.QuickFix - } - var reports []ruleguardReport - - runCtx.Report = func(data *ruleguard.ReportData) { - // TODO(quasilyte): investigate whether we should add a rule name as - // a message prefix here. - r := ruleguardReport{ - pos: data.Node.Pos(), - message: data.Message, - } - fix := data.Suggestion - if fix != nil { - r.fix = linter.QuickFix{ - From: fix.From, - To: fix.To, - Replacement: fix.Replacement, - } - } - reports = append(reports, r) - } - - if err := e.Run(runCtx, f); err != nil { - // Normally this should never happen, but since - // we don't have a better mechanism to report errors, - // emit a warning. - ctx.Warn(f, "execution error: %v", err) - } - - sort.Slice(reports, func(i, j int) bool { - return reports[i].message < reports[j].message - }) - for _, report := range reports { - if report.fix.Replacement != nil { - ctx.WarnFixableWithPos(report.pos, report.fix, "%s", report.message) - } else { - ctx.WarnWithPos(report.pos, "%s", report.message) - } - } -} - -func debugPrint(s string) { - fmt.Println("debug:", s) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/rulesdata/rulesdata.go b/vendor/github.com/go-critic/go-critic/checkers/rulesdata/rulesdata.go deleted file mode 100644 index 664145858b..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/rulesdata/rulesdata.go +++ /dev/null @@ -1,2581 +0,0 @@ -// Code generated by "precompile.go". DO NOT EDIT. - -package rulesdata - -import "github.com/quasilyte/go-ruleguard/ruleguard/ir" - -var PrecompiledRules = &ir.File{ - PkgPath: "gorules", - CustomDecls: []string{}, - BundleImports: []ir.BundleImport{}, - RuleGroups: []ir.RuleGroup{ - { - Line: 11, - Name: "redundantSprint", - MatcherName: "m", - DocTags: []string{"style", "experimental"}, - DocSummary: "Detects redundant fmt.Sprint calls", - DocBefore: "fmt.Sprint(x)", - DocAfter: "x.String()", - Rules: []ir.Rule{ - { - Line: 12, - SyntaxPatterns: []ir.PatternString{ - {Line: 12, Value: "fmt.Sprint($x)"}, - {Line: 12, Value: "fmt.Sprintf(\"%s\", $x)"}, - {Line: 12, Value: "fmt.Sprintf(\"%v\", $x)"}, - }, - ReportTemplate: "use $x.String() instead", - SuggestTemplate: "$x.String()", - WhereExpr: ir.FilterExpr{ - Line: 13, - Op: ir.FilterAndOp, - Src: "!m[\"x\"].Type.Is(`reflect.Value`) && m[\"x\"].Type.Implements(`fmt.Stringer`)", - Args: []ir.FilterExpr{ - { - Line: 13, - Op: ir.FilterNotOp, - Src: "!m[\"x\"].Type.Is(`reflect.Value`)", - Args: []ir.FilterExpr{{ - Line: 13, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"x\"].Type.Is(`reflect.Value`)", - Value: "x", - Args: []ir.FilterExpr{{Line: 13, Op: ir.FilterStringOp, Src: "`reflect.Value`", Value: "reflect.Value"}}, - }}, - }, - { - Line: 13, - Op: ir.FilterVarTypeImplementsOp, - Src: "m[\"x\"].Type.Implements(`fmt.Stringer`)", - Value: "x", - Args: []ir.FilterExpr{{Line: 13, Op: ir.FilterStringOp, Src: "`fmt.Stringer`", Value: "fmt.Stringer"}}, - }, - }, - }, - }, - { - Line: 17, - SyntaxPatterns: []ir.PatternString{ - {Line: 17, Value: "fmt.Sprint($x)"}, - {Line: 17, Value: "fmt.Sprintf(\"%s\", $x)"}, - {Line: 17, Value: "fmt.Sprintf(\"%v\", $x)"}, - }, - ReportTemplate: "$x is already string", - SuggestTemplate: "$x", - WhereExpr: ir.FilterExpr{ - Line: 18, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"x\"].Type.Is(`string`)", - Value: "x", - Args: []ir.FilterExpr{{Line: 18, Op: ir.FilterStringOp, Src: "`string`", Value: "string"}}, - }, - }, - }, - }, - { - Line: 27, - Name: "deferUnlambda", - MatcherName: "m", - DocTags: []string{"style", "experimental"}, - DocSummary: "Detects deferred function literals that can be simplified", - DocBefore: "defer func() { f() }()", - DocAfter: "defer f()", - Rules: []ir.Rule{ - { - Line: 28, - SyntaxPatterns: []ir.PatternString{{Line: 28, Value: "defer func() { $f($*args) }()"}}, - ReportTemplate: "can rewrite as `defer $f($args)`", - WhereExpr: ir.FilterExpr{ - Line: 29, - Op: ir.FilterAndOp, - Src: "m[\"f\"].Node.Is(`Ident`) && m[\"f\"].Text != \"panic\" && m[\"f\"].Text != \"recover\" && m[\"args\"].Const", - Args: []ir.FilterExpr{ - { - Line: 29, - Op: ir.FilterAndOp, - Src: "m[\"f\"].Node.Is(`Ident`) && m[\"f\"].Text != \"panic\" && m[\"f\"].Text != \"recover\"", - Args: []ir.FilterExpr{ - { - Line: 29, - Op: ir.FilterAndOp, - Src: "m[\"f\"].Node.Is(`Ident`) && m[\"f\"].Text != \"panic\"", - Args: []ir.FilterExpr{ - { - Line: 29, - Op: ir.FilterVarNodeIsOp, - Src: "m[\"f\"].Node.Is(`Ident`)", - Value: "f", - Args: []ir.FilterExpr{{Line: 29, Op: ir.FilterStringOp, Src: "`Ident`", Value: "Ident"}}, - }, - { - Line: 29, - Op: ir.FilterNeqOp, - Src: "m[\"f\"].Text != \"panic\"", - Args: []ir.FilterExpr{ - {Line: 29, Op: ir.FilterVarTextOp, Src: "m[\"f\"].Text", Value: "f"}, - {Line: 29, Op: ir.FilterStringOp, Src: "\"panic\"", Value: "panic"}, - }, - }, - }, - }, - { - Line: 29, - Op: ir.FilterNeqOp, - Src: "m[\"f\"].Text != \"recover\"", - Args: []ir.FilterExpr{ - {Line: 29, Op: ir.FilterVarTextOp, Src: "m[\"f\"].Text", Value: "f"}, - {Line: 29, Op: ir.FilterStringOp, Src: "\"recover\"", Value: "recover"}, - }, - }, - }, - }, - { - Line: 29, - Op: ir.FilterVarConstOp, - Src: "m[\"args\"].Const", - Value: "args", - }, - }, - }, - }, - { - Line: 32, - SyntaxPatterns: []ir.PatternString{{Line: 32, Value: "defer func() { $pkg.$f($*args) }()"}}, - ReportTemplate: "can rewrite as `defer $pkg.$f($args)`", - WhereExpr: ir.FilterExpr{ - Line: 33, - Op: ir.FilterAndOp, - Src: "m[\"f\"].Node.Is(`Ident`) && m[\"args\"].Const && m[\"pkg\"].Object.Is(`PkgName`)", - Args: []ir.FilterExpr{ - { - Line: 33, - Op: ir.FilterAndOp, - Src: "m[\"f\"].Node.Is(`Ident`) && m[\"args\"].Const", - Args: []ir.FilterExpr{ - { - Line: 33, - Op: ir.FilterVarNodeIsOp, - Src: "m[\"f\"].Node.Is(`Ident`)", - Value: "f", - Args: []ir.FilterExpr{{Line: 33, Op: ir.FilterStringOp, Src: "`Ident`", Value: "Ident"}}, - }, - { - Line: 33, - Op: ir.FilterVarConstOp, - Src: "m[\"args\"].Const", - Value: "args", - }, - }, - }, - { - Line: 33, - Op: ir.FilterVarObjectIsOp, - Src: "m[\"pkg\"].Object.Is(`PkgName`)", - Value: "pkg", - Args: []ir.FilterExpr{{Line: 33, Op: ir.FilterStringOp, Src: "`PkgName`", Value: "PkgName"}}, - }, - }, - }, - }, - }, - }, - { - Line: 41, - Name: "badLock", - MatcherName: "m", - DocTags: []string{"diagnostic", "experimental"}, - DocSummary: "Detects suspicious mutex lock/unlock operations", - DocBefore: "mu.Lock(); mu.Unlock()", - DocAfter: "mu.Lock(); defer mu.Unlock()", - Rules: []ir.Rule{ - { - Line: 45, - SyntaxPatterns: []ir.PatternString{{Line: 45, Value: "$mu1.Lock(); $mu2.Unlock()"}}, - ReportTemplate: "defer is missing, mutex is unlocked immediately", - WhereExpr: ir.FilterExpr{ - Line: 46, - Op: ir.FilterEqOp, - Src: "m[\"mu1\"].Text == m[\"mu2\"].Text", - Args: []ir.FilterExpr{ - {Line: 46, Op: ir.FilterVarTextOp, Src: "m[\"mu1\"].Text", Value: "mu1"}, - {Line: 46, Op: ir.FilterVarTextOp, Src: "m[\"mu2\"].Text", Value: "mu2"}, - }, - }, - LocationVar: "mu2", - }, - { - Line: 50, - SyntaxPatterns: []ir.PatternString{{Line: 50, Value: "$mu1.RLock(); $mu2.RUnlock()"}}, - ReportTemplate: "defer is missing, mutex is unlocked immediately", - WhereExpr: ir.FilterExpr{ - Line: 51, - Op: ir.FilterEqOp, - Src: "m[\"mu1\"].Text == m[\"mu2\"].Text", - Args: []ir.FilterExpr{ - {Line: 51, Op: ir.FilterVarTextOp, Src: "m[\"mu1\"].Text", Value: "mu1"}, - {Line: 51, Op: ir.FilterVarTextOp, Src: "m[\"mu2\"].Text", Value: "mu2"}, - }, - }, - LocationVar: "mu2", - }, - { - Line: 56, - SyntaxPatterns: []ir.PatternString{{Line: 56, Value: "$mu1.Lock(); defer $mu2.RUnlock()"}}, - ReportTemplate: "suspicious unlock, maybe Unlock was intended?", - WhereExpr: ir.FilterExpr{ - Line: 57, - Op: ir.FilterEqOp, - Src: "m[\"mu1\"].Text == m[\"mu2\"].Text", - Args: []ir.FilterExpr{ - {Line: 57, Op: ir.FilterVarTextOp, Src: "m[\"mu1\"].Text", Value: "mu1"}, - {Line: 57, Op: ir.FilterVarTextOp, Src: "m[\"mu2\"].Text", Value: "mu2"}, - }, - }, - LocationVar: "mu2", - }, - { - Line: 61, - SyntaxPatterns: []ir.PatternString{{Line: 61, Value: "$mu1.RLock(); defer $mu2.Unlock()"}}, - ReportTemplate: "suspicious unlock, maybe RUnlock was intended?", - WhereExpr: ir.FilterExpr{ - Line: 62, - Op: ir.FilterEqOp, - Src: "m[\"mu1\"].Text == m[\"mu2\"].Text", - Args: []ir.FilterExpr{ - {Line: 62, Op: ir.FilterVarTextOp, Src: "m[\"mu1\"].Text", Value: "mu1"}, - {Line: 62, Op: ir.FilterVarTextOp, Src: "m[\"mu2\"].Text", Value: "mu2"}, - }, - }, - LocationVar: "mu2", - }, - { - Line: 67, - SyntaxPatterns: []ir.PatternString{{Line: 67, Value: "$mu1.Lock(); defer $mu2.Lock()"}}, - ReportTemplate: "maybe defer $mu1.Unlock() was intended?", - WhereExpr: ir.FilterExpr{ - Line: 68, - Op: ir.FilterEqOp, - Src: "m[\"mu1\"].Text == m[\"mu2\"].Text", - Args: []ir.FilterExpr{ - {Line: 68, Op: ir.FilterVarTextOp, Src: "m[\"mu1\"].Text", Value: "mu1"}, - {Line: 68, Op: ir.FilterVarTextOp, Src: "m[\"mu2\"].Text", Value: "mu2"}, - }, - }, - LocationVar: "mu2", - }, - { - Line: 72, - SyntaxPatterns: []ir.PatternString{{Line: 72, Value: "$mu1.RLock(); defer $mu2.RLock()"}}, - ReportTemplate: "maybe defer $mu1.RUnlock() was intended?", - WhereExpr: ir.FilterExpr{ - Line: 73, - Op: ir.FilterEqOp, - Src: "m[\"mu1\"].Text == m[\"mu2\"].Text", - Args: []ir.FilterExpr{ - {Line: 73, Op: ir.FilterVarTextOp, Src: "m[\"mu1\"].Text", Value: "mu1"}, - {Line: 73, Op: ir.FilterVarTextOp, Src: "m[\"mu2\"].Text", Value: "mu2"}, - }, - }, - LocationVar: "mu2", - }, - }, - }, - { - Line: 82, - Name: "httpNoBody", - MatcherName: "m", - DocTags: []string{"style", "experimental"}, - DocSummary: "Detects nil usages in http.NewRequest calls, suggesting http.NoBody as an alternative", - DocBefore: "http.NewRequest(\"GET\", url, nil)", - DocAfter: "http.NewRequest(\"GET\", url, http.NoBody)", - Rules: []ir.Rule{ - { - Line: 83, - SyntaxPatterns: []ir.PatternString{{Line: 83, Value: "http.NewRequest($method, $url, $nil)"}}, - ReportTemplate: "http.NoBody should be preferred to the nil request body", - SuggestTemplate: "http.NewRequest($method, $url, http.NoBody)", - WhereExpr: ir.FilterExpr{ - Line: 84, - Op: ir.FilterEqOp, - Src: "m[\"nil\"].Text == \"nil\"", - Args: []ir.FilterExpr{ - {Line: 84, Op: ir.FilterVarTextOp, Src: "m[\"nil\"].Text", Value: "nil"}, - {Line: 84, Op: ir.FilterStringOp, Src: "\"nil\"", Value: "nil"}, - }, - }, - }, - { - Line: 88, - SyntaxPatterns: []ir.PatternString{{Line: 88, Value: "http.NewRequestWithContext($ctx, $method, $url, $nil)"}}, - ReportTemplate: "http.NoBody should be preferred to the nil request body", - SuggestTemplate: "http.NewRequestWithContext($ctx, $method, $url, http.NoBody)", - WhereExpr: ir.FilterExpr{ - Line: 89, - Op: ir.FilterEqOp, - Src: "m[\"nil\"].Text == \"nil\"", - Args: []ir.FilterExpr{ - {Line: 89, Op: ir.FilterVarTextOp, Src: "m[\"nil\"].Text", Value: "nil"}, - {Line: 89, Op: ir.FilterStringOp, Src: "\"nil\"", Value: "nil"}, - }, - }, - }, - { - Line: 93, - SyntaxPatterns: []ir.PatternString{{Line: 93, Value: "httptest.NewRequest($method, $url, $nil)"}}, - ReportTemplate: "http.NoBody should be preferred to the nil request body", - SuggestTemplate: "httptest.NewRequest($method, $url, http.NoBody)", - WhereExpr: ir.FilterExpr{ - Line: 94, - Op: ir.FilterEqOp, - Src: "m[\"nil\"].Text == \"nil\"", - Args: []ir.FilterExpr{ - {Line: 94, Op: ir.FilterVarTextOp, Src: "m[\"nil\"].Text", Value: "nil"}, - {Line: 94, Op: ir.FilterStringOp, Src: "\"nil\"", Value: "nil"}, - }, - }, - }, - }, - }, - { - Line: 104, - Name: "preferDecodeRune", - MatcherName: "m", - DocTags: []string{"performance", "experimental"}, - DocSummary: "Detects expressions like []rune(s)[0] that may cause unwanted rune slice allocation", - DocBefore: "r := []rune(s)[0]", - DocAfter: "r, _ := utf8.DecodeRuneInString(s)", - DocNote: "See Go issue for details: https://github.com/golang/go/issues/45260", - Rules: []ir.Rule{{ - Line: 105, - SyntaxPatterns: []ir.PatternString{{Line: 105, Value: "[]rune($s)[0]"}}, - ReportTemplate: "consider replacing $$ with utf8.DecodeRuneInString($s)", - WhereExpr: ir.FilterExpr{ - Line: 106, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"s\"].Type.Is(`string`)", - Value: "s", - Args: []ir.FilterExpr{{Line: 106, Op: ir.FilterStringOp, Src: "`string`", Value: "string"}}, - }, - }}, - }, - { - Line: 114, - Name: "sloppyLen", - MatcherName: "m", - DocTags: []string{"diagnostic"}, - DocSummary: "Detects usage of `len` when result is obvious or doesn't make sense", - DocBefore: "len(arr) <= 0", - DocAfter: "len(arr) == 0", - Rules: []ir.Rule{ - { - Line: 115, - SyntaxPatterns: []ir.PatternString{{Line: 115, Value: "len($_) >= 0"}}, - ReportTemplate: "$$ is always true", - }, - { - Line: 116, - SyntaxPatterns: []ir.PatternString{{Line: 116, Value: "len($_) < 0"}}, - ReportTemplate: "$$ is always false", - }, - { - Line: 117, - SyntaxPatterns: []ir.PatternString{{Line: 117, Value: "len($x) <= 0"}}, - ReportTemplate: "$$ can be len($x) == 0", - }, - }, - }, - { - Line: 124, - Name: "valSwap", - MatcherName: "m", - DocTags: []string{"style"}, - DocSummary: "Detects value swapping code that are not using parallel assignment", - DocBefore: "*tmp = *x; *x = *y; *y = *tmp", - DocAfter: "*x, *y = *y, *x", - Rules: []ir.Rule{{ - Line: 125, - SyntaxPatterns: []ir.PatternString{{Line: 125, Value: "$tmp := $y; $y = $x; $x = $tmp"}}, - ReportTemplate: "can re-write as `$y, $x = $x, $y`", - }}, - }, - { - Line: 133, - Name: "switchTrue", - MatcherName: "m", - DocTags: []string{"style"}, - DocSummary: "Detects switch-over-bool statements that use explicit `true` tag value", - DocBefore: "switch true {...}", - DocAfter: "switch {...}", - Rules: []ir.Rule{ - { - Line: 134, - SyntaxPatterns: []ir.PatternString{{Line: 134, Value: "switch true { $*_ }"}}, - ReportTemplate: "replace 'switch true {}' with 'switch {}'", - }, - { - Line: 136, - SyntaxPatterns: []ir.PatternString{{Line: 136, Value: "switch $x; true { $*_ }"}}, - ReportTemplate: "replace 'switch $x; true {}' with 'switch $x; {}'", - }, - }, - }, - { - Line: 144, - Name: "flagDeref", - MatcherName: "m", - DocTags: []string{"diagnostic"}, - DocSummary: "Detects immediate dereferencing of `flag` package pointers", - DocBefore: "b := *flag.Bool(\"b\", false, \"b docs\")", - DocAfter: "var b bool; flag.BoolVar(&b, \"b\", false, \"b docs\")", - Rules: []ir.Rule{ - { - Line: 145, - SyntaxPatterns: []ir.PatternString{{Line: 145, Value: "*flag.Bool($*_)"}}, - ReportTemplate: "immediate deref in $$ is most likely an error; consider using flag.BoolVar", - }, - { - Line: 146, - SyntaxPatterns: []ir.PatternString{{Line: 146, Value: "*flag.Duration($*_)"}}, - ReportTemplate: "immediate deref in $$ is most likely an error; consider using flag.DurationVar", - }, - { - Line: 147, - SyntaxPatterns: []ir.PatternString{{Line: 147, Value: "*flag.Float64($*_)"}}, - ReportTemplate: "immediate deref in $$ is most likely an error; consider using flag.Float64Var", - }, - { - Line: 148, - SyntaxPatterns: []ir.PatternString{{Line: 148, Value: "*flag.Int($*_)"}}, - ReportTemplate: "immediate deref in $$ is most likely an error; consider using flag.IntVar", - }, - { - Line: 149, - SyntaxPatterns: []ir.PatternString{{Line: 149, Value: "*flag.Int64($*_)"}}, - ReportTemplate: "immediate deref in $$ is most likely an error; consider using flag.Int64Var", - }, - { - Line: 150, - SyntaxPatterns: []ir.PatternString{{Line: 150, Value: "*flag.String($*_)"}}, - ReportTemplate: "immediate deref in $$ is most likely an error; consider using flag.StringVar", - }, - { - Line: 151, - SyntaxPatterns: []ir.PatternString{{Line: 151, Value: "*flag.Uint($*_)"}}, - ReportTemplate: "immediate deref in $$ is most likely an error; consider using flag.UintVar", - }, - { - Line: 152, - SyntaxPatterns: []ir.PatternString{{Line: 152, Value: "*flag.Uint64($*_)"}}, - ReportTemplate: "immediate deref in $$ is most likely an error; consider using flag.Uint64Var", - }, - }, - }, - { - Line: 159, - Name: "emptyStringTest", - MatcherName: "m", - DocTags: []string{"style", "experimental"}, - DocSummary: "Detects empty string checks that can be written more idiomatically", - DocBefore: "len(s) == 0", - DocAfter: "s == \"\"", - Rules: []ir.Rule{ - { - Line: 160, - SyntaxPatterns: []ir.PatternString{{Line: 160, Value: "len($s) != 0"}}, - ReportTemplate: "replace `$$` with `$s != \"\"`", - WhereExpr: ir.FilterExpr{ - Line: 161, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"s\"].Type.Is(`string`)", - Value: "s", - Args: []ir.FilterExpr{{Line: 161, Op: ir.FilterStringOp, Src: "`string`", Value: "string"}}, - }, - }, - { - Line: 163, - SyntaxPatterns: []ir.PatternString{{Line: 163, Value: "len($s) > 0"}}, - ReportTemplate: "replace `$$` with `$s != \"\"`", - WhereExpr: ir.FilterExpr{ - Line: 164, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"s\"].Type.Is(`string`)", - Value: "s", - Args: []ir.FilterExpr{{Line: 164, Op: ir.FilterStringOp, Src: "`string`", Value: "string"}}, - }, - }, - { - Line: 167, - SyntaxPatterns: []ir.PatternString{{Line: 167, Value: "len($s) == 0"}}, - ReportTemplate: "replace `$$` with `$s == \"\"`", - WhereExpr: ir.FilterExpr{ - Line: 168, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"s\"].Type.Is(`string`)", - Value: "s", - Args: []ir.FilterExpr{{Line: 168, Op: ir.FilterStringOp, Src: "`string`", Value: "string"}}, - }, - }, - { - Line: 170, - SyntaxPatterns: []ir.PatternString{{Line: 170, Value: "len($s) <= 0"}}, - ReportTemplate: "replace `$$` with `$s == \"\"`", - WhereExpr: ir.FilterExpr{ - Line: 171, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"s\"].Type.Is(`string`)", - Value: "s", - Args: []ir.FilterExpr{{Line: 171, Op: ir.FilterStringOp, Src: "`string`", Value: "string"}}, - }, - }, - }, - }, - { - Line: 179, - Name: "stringXbytes", - MatcherName: "m", - DocTags: []string{"performance"}, - DocSummary: "Detects redundant conversions between string and []byte", - DocBefore: "copy(b, []byte(s))", - DocAfter: "copy(b, s)", - Rules: []ir.Rule{ - { - Line: 180, - SyntaxPatterns: []ir.PatternString{{Line: 180, Value: "copy($_, []byte($s))"}}, - ReportTemplate: "can simplify `[]byte($s)` to `$s`", - }, - { - Line: 182, - SyntaxPatterns: []ir.PatternString{{Line: 182, Value: "string($b) == \"\""}}, - ReportTemplate: "suggestion: len($b) == 0", - SuggestTemplate: "len($b) == 0", - WhereExpr: ir.FilterExpr{ - Line: 182, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"b\"].Type.Is(`[]byte`)", - Value: "b", - Args: []ir.FilterExpr{{Line: 182, Op: ir.FilterStringOp, Src: "`[]byte`", Value: "[]byte"}}, - }, - }, - { - Line: 183, - SyntaxPatterns: []ir.PatternString{{Line: 183, Value: "string($b) != \"\""}}, - ReportTemplate: "suggestion: len($b) != 0", - SuggestTemplate: "len($b) != 0", - WhereExpr: ir.FilterExpr{ - Line: 183, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"b\"].Type.Is(`[]byte`)", - Value: "b", - Args: []ir.FilterExpr{{Line: 183, Op: ir.FilterStringOp, Src: "`[]byte`", Value: "[]byte"}}, - }, - }, - { - Line: 185, - SyntaxPatterns: []ir.PatternString{{Line: 185, Value: "len(string($b))"}}, - ReportTemplate: "suggestion: len($b)", - SuggestTemplate: "len($b)", - WhereExpr: ir.FilterExpr{ - Line: 185, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"b\"].Type.Is(`[]byte`)", - Value: "b", - Args: []ir.FilterExpr{{Line: 185, Op: ir.FilterStringOp, Src: "`[]byte`", Value: "[]byte"}}, - }, - }, - { - Line: 187, - SyntaxPatterns: []ir.PatternString{{Line: 187, Value: "string($x) == string($y)"}}, - ReportTemplate: "suggestion: bytes.Equal($x, $y)", - SuggestTemplate: "bytes.Equal($x, $y)", - WhereExpr: ir.FilterExpr{ - Line: 188, - Op: ir.FilterAndOp, - Src: "m[\"x\"].Type.Is(`[]byte`) && m[\"y\"].Type.Is(`[]byte`)", - Args: []ir.FilterExpr{ - { - Line: 188, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"x\"].Type.Is(`[]byte`)", - Value: "x", - Args: []ir.FilterExpr{{Line: 188, Op: ir.FilterStringOp, Src: "`[]byte`", Value: "[]byte"}}, - }, - { - Line: 188, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"y\"].Type.Is(`[]byte`)", - Value: "y", - Args: []ir.FilterExpr{{Line: 188, Op: ir.FilterStringOp, Src: "`[]byte`", Value: "[]byte"}}, - }, - }, - }, - }, - { - Line: 191, - SyntaxPatterns: []ir.PatternString{{Line: 191, Value: "string($x) != string($y)"}}, - ReportTemplate: "suggestion: !bytes.Equal($x, $y)", - SuggestTemplate: "!bytes.Equal($x, $y)", - WhereExpr: ir.FilterExpr{ - Line: 192, - Op: ir.FilterAndOp, - Src: "m[\"x\"].Type.Is(`[]byte`) && m[\"y\"].Type.Is(`[]byte`)", - Args: []ir.FilterExpr{ - { - Line: 192, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"x\"].Type.Is(`[]byte`)", - Value: "x", - Args: []ir.FilterExpr{{Line: 192, Op: ir.FilterStringOp, Src: "`[]byte`", Value: "[]byte"}}, - }, - { - Line: 192, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"y\"].Type.Is(`[]byte`)", - Value: "y", - Args: []ir.FilterExpr{{Line: 192, Op: ir.FilterStringOp, Src: "`[]byte`", Value: "[]byte"}}, - }, - }, - }, - }, - { - Line: 195, - SyntaxPatterns: []ir.PatternString{{Line: 195, Value: "$re.Match([]byte($s))"}}, - ReportTemplate: "suggestion: $re.MatchString($s)", - SuggestTemplate: "$re.MatchString($s)", - WhereExpr: ir.FilterExpr{ - Line: 196, - Op: ir.FilterAndOp, - Src: "m[\"re\"].Type.Is(`*regexp.Regexp`) && m[\"s\"].Type.Is(`string`)", - Args: []ir.FilterExpr{ - { - Line: 196, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"re\"].Type.Is(`*regexp.Regexp`)", - Value: "re", - Args: []ir.FilterExpr{{Line: 196, Op: ir.FilterStringOp, Src: "`*regexp.Regexp`", Value: "*regexp.Regexp"}}, - }, - { - Line: 196, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"s\"].Type.Is(`string`)", - Value: "s", - Args: []ir.FilterExpr{{Line: 196, Op: ir.FilterStringOp, Src: "`string`", Value: "string"}}, - }, - }, - }, - }, - { - Line: 199, - SyntaxPatterns: []ir.PatternString{{Line: 199, Value: "$re.FindIndex([]byte($s))"}}, - ReportTemplate: "suggestion: $re.FindStringIndex($s)", - SuggestTemplate: "$re.FindStringIndex($s)", - WhereExpr: ir.FilterExpr{ - Line: 200, - Op: ir.FilterAndOp, - Src: "m[\"re\"].Type.Is(`*regexp.Regexp`) && m[\"s\"].Type.Is(`string`)", - Args: []ir.FilterExpr{ - { - Line: 200, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"re\"].Type.Is(`*regexp.Regexp`)", - Value: "re", - Args: []ir.FilterExpr{{Line: 200, Op: ir.FilterStringOp, Src: "`*regexp.Regexp`", Value: "*regexp.Regexp"}}, - }, - { - Line: 200, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"s\"].Type.Is(`string`)", - Value: "s", - Args: []ir.FilterExpr{{Line: 200, Op: ir.FilterStringOp, Src: "`string`", Value: "string"}}, - }, - }, - }, - }, - { - Line: 203, - SyntaxPatterns: []ir.PatternString{{Line: 203, Value: "$re.FindAllIndex([]byte($s), $n)"}}, - ReportTemplate: "suggestion: $re.FindAllStringIndex($s, $n)", - SuggestTemplate: "$re.FindAllStringIndex($s, $n)", - WhereExpr: ir.FilterExpr{ - Line: 204, - Op: ir.FilterAndOp, - Src: "m[\"re\"].Type.Is(`*regexp.Regexp`) && m[\"s\"].Type.Is(`string`)", - Args: []ir.FilterExpr{ - { - Line: 204, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"re\"].Type.Is(`*regexp.Regexp`)", - Value: "re", - Args: []ir.FilterExpr{{Line: 204, Op: ir.FilterStringOp, Src: "`*regexp.Regexp`", Value: "*regexp.Regexp"}}, - }, - { - Line: 204, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"s\"].Type.Is(`string`)", - Value: "s", - Args: []ir.FilterExpr{{Line: 204, Op: ir.FilterStringOp, Src: "`string`", Value: "string"}}, - }, - }, - }, - }, - }, - }, - { - Line: 213, - Name: "indexAlloc", - MatcherName: "m", - DocTags: []string{"performance"}, - DocSummary: "Detects strings.Index calls that may cause unwanted allocs", - DocBefore: "strings.Index(string(x), y)", - DocAfter: "bytes.Index(x, []byte(y))", - DocNote: "See Go issue for details: https://github.com/golang/go/issues/25864", - Rules: []ir.Rule{{ - Line: 214, - SyntaxPatterns: []ir.PatternString{{Line: 214, Value: "strings.Index(string($x), $y)"}}, - ReportTemplate: "consider replacing $$ with bytes.Index($x, []byte($y))", - WhereExpr: ir.FilterExpr{ - Line: 215, - Op: ir.FilterAndOp, - Src: "m[\"x\"].Pure && m[\"y\"].Pure", - Args: []ir.FilterExpr{ - {Line: 215, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, - {Line: 215, Op: ir.FilterVarPureOp, Src: "m[\"y\"].Pure", Value: "y"}, - }, - }, - }}, - }, - { - Line: 223, - Name: "wrapperFunc", - MatcherName: "m", - DocTags: []string{"style"}, - DocSummary: "Detects function calls that can be replaced with convenience wrappers", - DocBefore: "wg.Add(-1)", - DocAfter: "wg.Done()", - Rules: []ir.Rule{ - { - Line: 224, - SyntaxPatterns: []ir.PatternString{{Line: 224, Value: "$wg.Add(-1)"}}, - ReportTemplate: "use WaitGroup.Done method in `$$`", - WhereExpr: ir.FilterExpr{ - Line: 225, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"wg\"].Type.Is(`sync.WaitGroup`)", - Value: "wg", - Args: []ir.FilterExpr{{Line: 225, Op: ir.FilterStringOp, Src: "`sync.WaitGroup`", Value: "sync.WaitGroup"}}, - }, - }, - { - Line: 228, - SyntaxPatterns: []ir.PatternString{{Line: 228, Value: "$buf.Truncate(0)"}}, - ReportTemplate: "use Buffer.Reset method in `$$`", - WhereExpr: ir.FilterExpr{ - Line: 229, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"buf\"].Type.Is(`bytes.Buffer`)", - Value: "buf", - Args: []ir.FilterExpr{{Line: 229, Op: ir.FilterStringOp, Src: "`bytes.Buffer`", Value: "bytes.Buffer"}}, - }, - }, - { - Line: 232, - SyntaxPatterns: []ir.PatternString{{Line: 232, Value: "http.HandlerFunc(http.NotFound)"}}, - ReportTemplate: "use http.NotFoundHandler method in `$$`", - }, - { - Line: 234, - SyntaxPatterns: []ir.PatternString{{Line: 234, Value: "strings.SplitN($_, $_, -1)"}}, - ReportTemplate: "use strings.Split method in `$$`", - }, - { - Line: 235, - SyntaxPatterns: []ir.PatternString{{Line: 235, Value: "strings.Replace($_, $_, $_, -1)"}}, - ReportTemplate: "use strings.ReplaceAll method in `$$`", - }, - { - Line: 236, - SyntaxPatterns: []ir.PatternString{{Line: 236, Value: "strings.Map(unicode.ToTitle, $_)"}}, - ReportTemplate: "use strings.ToTitle method in `$$`", - }, - { - Line: 237, - SyntaxPatterns: []ir.PatternString{ - {Line: 237, Value: "strings.Index($s1, $s2) >= 0"}, - {Line: 237, Value: "strings.Index($s1, $s2) != -1"}, - }, - ReportTemplate: "suggestion: strings.Contains($s1, $s2)", - SuggestTemplate: "strings.Contains($s1, $s2)", - }, - { - Line: 238, - SyntaxPatterns: []ir.PatternString{ - {Line: 238, Value: "strings.IndexAny($s1, $s2) >= 0"}, - {Line: 238, Value: "strings.IndexAny($s1, $s2) != -1"}, - }, - ReportTemplate: "suggestion: strings.ContainsAny($s1, $s2)", - SuggestTemplate: "strings.ContainsAny($s1, $s2)", - }, - { - Line: 239, - SyntaxPatterns: []ir.PatternString{ - {Line: 239, Value: "strings.IndexRune($s1, $s2) >= 0"}, - {Line: 239, Value: "strings.IndexRune($s1, $s2) != -1"}, - }, - ReportTemplate: "suggestion: strings.ContainsRune($s1, $s2)", - SuggestTemplate: "strings.ContainsRune($s1, $s2)", - }, - { - Line: 241, - SyntaxPatterns: []ir.PatternString{ - {Line: 241, Value: "$i := strings.Index($s, $sep); $*_; $x, $y = $s[:$i], $s[$i+1:]"}, - {Line: 242, Value: "$i := strings.Index($s, $sep); $*_; $x = $s[:$i]; $*_; $y = $s[$i+1:]"}, - }, - ReportTemplate: "suggestion: $x, $y, _ = strings.Cut($s, $sep)", - SuggestTemplate: "$x, $y, _ = strings.Cut($s, $sep)", - WhereExpr: ir.FilterExpr{ - Line: 243, - Op: ir.FilterGoVersionGreaterEqThanOp, - Src: "m.GoVersion().GreaterEqThan(\"1.18\")", - Value: "1.18", - }, - }, - { - Line: 246, - SyntaxPatterns: []ir.PatternString{ - {Line: 247, Value: "if $i := strings.Index($s, $sep); $i != -1 { $*_; $x, $y = $s[:$i], $s[$i+1:]; $*_ }"}, - {Line: 248, Value: "if $i := strings.Index($s, $sep); $i != -1 { $*_; $x = $s[:$i]; $*_; $y = $s[$i+1:]; $*_ }"}, - {Line: 249, Value: "if $i := strings.Index($s, $sep); $i >= 0 { $*_; $x, $y = $s[:$i], $s[$i+1:]; $*_ }"}, - {Line: 250, Value: "if $i := strings.Index($s, $sep); $i >= 0 { $*_; $x = $s[:$i]; $*_; $y = $s[$i+1:]; $*_ }"}, - }, - ReportTemplate: "suggestion: if $x, $y, ok = strings.Cut($s, $sep); ok { ... }", - SuggestTemplate: "if $x, $y, ok = strings.Cut($s, $sep); ok { ... }", - WhereExpr: ir.FilterExpr{ - Line: 251, - Op: ir.FilterGoVersionGreaterEqThanOp, - Src: "m.GoVersion().GreaterEqThan(\"1.18\")", - Value: "1.18", - }, - }, - { - Line: 254, - SyntaxPatterns: []ir.PatternString{{Line: 254, Value: "bytes.SplitN(b, []byte(\".\"), -1)"}}, - ReportTemplate: "use bytes.Split method in `$$`", - }, - { - Line: 255, - SyntaxPatterns: []ir.PatternString{{Line: 255, Value: "bytes.Replace($_, $_, $_, -1)"}}, - ReportTemplate: "use bytes.ReplaceAll method in `$$`", - }, - { - Line: 256, - SyntaxPatterns: []ir.PatternString{{Line: 256, Value: "bytes.Map(unicode.ToUpper, $_)"}}, - ReportTemplate: "use bytes.ToUpper method in `$$`", - }, - { - Line: 257, - SyntaxPatterns: []ir.PatternString{{Line: 257, Value: "bytes.Map(unicode.ToLower, $_)"}}, - ReportTemplate: "use bytes.ToLower method in `$$`", - }, - { - Line: 258, - SyntaxPatterns: []ir.PatternString{{Line: 258, Value: "bytes.Map(unicode.ToTitle, $_)"}}, - ReportTemplate: "use bytes.ToTitle method in `$$`", - }, - { - Line: 259, - SyntaxPatterns: []ir.PatternString{ - {Line: 259, Value: "bytes.Index($b1, $b2) >= 0"}, - {Line: 259, Value: "bytes.Index($b1, $b2) != -1"}, - }, - ReportTemplate: "suggestion: bytes.Contains($b1, $b2)", - SuggestTemplate: "bytes.Contains($b1, $b2)", - }, - { - Line: 260, - SyntaxPatterns: []ir.PatternString{ - {Line: 260, Value: "bytes.IndexAny($b1, $b2) >= 0"}, - {Line: 260, Value: "bytes.IndexAny($b1, $b2) != -1"}, - }, - ReportTemplate: "suggestion: bytes.ContainsAny($b1, $b2)", - SuggestTemplate: "bytes.ContainsAny($b1, $b2)", - }, - { - Line: 261, - SyntaxPatterns: []ir.PatternString{ - {Line: 261, Value: "bytes.IndexRune($b1, $b2) >= 0"}, - {Line: 261, Value: "bytes.IndexRune($b1, $b2) != -1"}, - }, - ReportTemplate: "suggestion: bytes.ContainsRune($b1, $b2)", - SuggestTemplate: "bytes.ContainsRune($b1, $b2)", - }, - { - Line: 263, - SyntaxPatterns: []ir.PatternString{{Line: 263, Value: "draw.DrawMask($_, $_, $_, $_, nil, image.Point{}, $_)"}}, - ReportTemplate: "use draw.Draw method in `$$`", - }, - }, - }, - { - Line: 271, - Name: "regexpMust", - MatcherName: "m", - DocTags: []string{"style"}, - DocSummary: "Detects `regexp.Compile*` that can be replaced with `regexp.MustCompile*`", - DocBefore: "re, _ := regexp.Compile(\"const pattern\")", - DocAfter: "re := regexp.MustCompile(\"const pattern\")", - Rules: []ir.Rule{ - { - Line: 272, - SyntaxPatterns: []ir.PatternString{{Line: 272, Value: "regexp.Compile($pat)"}}, - ReportTemplate: "for const patterns like $pat, use regexp.MustCompile", - WhereExpr: ir.FilterExpr{ - Line: 273, - Op: ir.FilterVarConstOp, - Src: "m[\"pat\"].Const", - Value: "pat", - }, - }, - { - Line: 276, - SyntaxPatterns: []ir.PatternString{{Line: 276, Value: "regexp.CompilePOSIX($pat)"}}, - ReportTemplate: "for const patterns like $pat, use regexp.MustCompilePOSIX", - WhereExpr: ir.FilterExpr{ - Line: 277, - Op: ir.FilterVarConstOp, - Src: "m[\"pat\"].Const", - Value: "pat", - }, - }, - }, - }, - { - Line: 285, - Name: "badCall", - MatcherName: "m", - DocTags: []string{"diagnostic"}, - DocSummary: "Detects suspicious function calls", - DocBefore: "strings.Replace(s, from, to, 0)", - DocAfter: "strings.Replace(s, from, to, -1)", - Rules: []ir.Rule{ - { - Line: 286, - SyntaxPatterns: []ir.PatternString{{Line: 286, Value: "strings.Replace($_, $_, $_, $zero)"}}, - ReportTemplate: "suspicious arg 0, probably meant -1", - WhereExpr: ir.FilterExpr{ - Line: 287, - Op: ir.FilterEqOp, - Src: "m[\"zero\"].Value.Int() == 0", - Args: []ir.FilterExpr{ - { - Line: 287, - Op: ir.FilterVarValueIntOp, - Src: "m[\"zero\"].Value.Int()", - Value: "zero", - }, - { - Line: 287, - Op: ir.FilterIntOp, - Src: "0", - Value: int64(0), - }, - }, - }, - LocationVar: "zero", - }, - { - Line: 289, - SyntaxPatterns: []ir.PatternString{{Line: 289, Value: "bytes.Replace($_, $_, $_, $zero)"}}, - ReportTemplate: "suspicious arg 0, probably meant -1", - WhereExpr: ir.FilterExpr{ - Line: 290, - Op: ir.FilterEqOp, - Src: "m[\"zero\"].Value.Int() == 0", - Args: []ir.FilterExpr{ - { - Line: 290, - Op: ir.FilterVarValueIntOp, - Src: "m[\"zero\"].Value.Int()", - Value: "zero", - }, - { - Line: 290, - Op: ir.FilterIntOp, - Src: "0", - Value: int64(0), - }, - }, - }, - LocationVar: "zero", - }, - { - Line: 293, - SyntaxPatterns: []ir.PatternString{{Line: 293, Value: "strings.SplitN($_, $_, $zero)"}}, - ReportTemplate: "suspicious arg 0, probably meant -1", - WhereExpr: ir.FilterExpr{ - Line: 294, - Op: ir.FilterEqOp, - Src: "m[\"zero\"].Value.Int() == 0", - Args: []ir.FilterExpr{ - { - Line: 294, - Op: ir.FilterVarValueIntOp, - Src: "m[\"zero\"].Value.Int()", - Value: "zero", - }, - { - Line: 294, - Op: ir.FilterIntOp, - Src: "0", - Value: int64(0), - }, - }, - }, - LocationVar: "zero", - }, - { - Line: 296, - SyntaxPatterns: []ir.PatternString{{Line: 296, Value: "bytes.SplitN($_, $_, $zero)"}}, - ReportTemplate: "suspicious arg 0, probably meant -1", - WhereExpr: ir.FilterExpr{ - Line: 297, - Op: ir.FilterEqOp, - Src: "m[\"zero\"].Value.Int() == 0", - Args: []ir.FilterExpr{ - { - Line: 297, - Op: ir.FilterVarValueIntOp, - Src: "m[\"zero\"].Value.Int()", - Value: "zero", - }, - { - Line: 297, - Op: ir.FilterIntOp, - Src: "0", - Value: int64(0), - }, - }, - }, - LocationVar: "zero", - }, - { - Line: 300, - SyntaxPatterns: []ir.PatternString{{Line: 300, Value: "append($_)"}}, - ReportTemplate: "no-op append call, probably missing arguments", - }, - { - Line: 302, - SyntaxPatterns: []ir.PatternString{{Line: 302, Value: "filepath.Join($_)"}}, - ReportTemplate: "suspicious Join on 1 argument", - }, - }, - }, - { - Line: 309, - Name: "assignOp", - MatcherName: "m", - DocTags: []string{"style"}, - DocSummary: "Detects assignments that can be simplified by using assignment operators", - DocBefore: "x = x * 2", - DocAfter: "x *= 2", - Rules: []ir.Rule{ - { - Line: 310, - SyntaxPatterns: []ir.PatternString{{Line: 310, Value: "$x = $x + 1"}}, - ReportTemplate: "replace `$$` with `$x++`", - WhereExpr: ir.FilterExpr{Line: 310, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, - }, - { - Line: 311, - SyntaxPatterns: []ir.PatternString{{Line: 311, Value: "$x = $x - 1"}}, - ReportTemplate: "replace `$$` with `$x--`", - WhereExpr: ir.FilterExpr{Line: 311, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, - }, - { - Line: 313, - SyntaxPatterns: []ir.PatternString{{Line: 313, Value: "$x = $x + $y"}}, - ReportTemplate: "replace `$$` with `$x += $y`", - WhereExpr: ir.FilterExpr{Line: 313, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, - }, - { - Line: 314, - SyntaxPatterns: []ir.PatternString{{Line: 314, Value: "$x = $x - $y"}}, - ReportTemplate: "replace `$$` with `$x -= $y`", - WhereExpr: ir.FilterExpr{Line: 314, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, - }, - { - Line: 316, - SyntaxPatterns: []ir.PatternString{{Line: 316, Value: "$x = $x * $y"}}, - ReportTemplate: "replace `$$` with `$x *= $y`", - WhereExpr: ir.FilterExpr{Line: 316, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, - }, - { - Line: 317, - SyntaxPatterns: []ir.PatternString{{Line: 317, Value: "$x = $x / $y"}}, - ReportTemplate: "replace `$$` with `$x /= $y`", - WhereExpr: ir.FilterExpr{Line: 317, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, - }, - { - Line: 318, - SyntaxPatterns: []ir.PatternString{{Line: 318, Value: "$x = $x % $y"}}, - ReportTemplate: "replace `$$` with `$x %= $y`", - WhereExpr: ir.FilterExpr{Line: 318, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, - }, - { - Line: 319, - SyntaxPatterns: []ir.PatternString{{Line: 319, Value: "$x = $x & $y"}}, - ReportTemplate: "replace `$$` with `$x &= $y`", - WhereExpr: ir.FilterExpr{Line: 319, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, - }, - { - Line: 320, - SyntaxPatterns: []ir.PatternString{{Line: 320, Value: "$x = $x | $y"}}, - ReportTemplate: "replace `$$` with `$x |= $y`", - WhereExpr: ir.FilterExpr{Line: 320, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, - }, - { - Line: 321, - SyntaxPatterns: []ir.PatternString{{Line: 321, Value: "$x = $x ^ $y"}}, - ReportTemplate: "replace `$$` with `$x ^= $y`", - WhereExpr: ir.FilterExpr{Line: 321, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, - }, - { - Line: 322, - SyntaxPatterns: []ir.PatternString{{Line: 322, Value: "$x = $x << $y"}}, - ReportTemplate: "replace `$$` with `$x <<= $y`", - WhereExpr: ir.FilterExpr{Line: 322, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, - }, - { - Line: 323, - SyntaxPatterns: []ir.PatternString{{Line: 323, Value: "$x = $x >> $y"}}, - ReportTemplate: "replace `$$` with `$x >>= $y`", - WhereExpr: ir.FilterExpr{Line: 323, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, - }, - { - Line: 324, - SyntaxPatterns: []ir.PatternString{{Line: 324, Value: "$x = $x &^ $y"}}, - ReportTemplate: "replace `$$` with `$x &^= $y`", - WhereExpr: ir.FilterExpr{Line: 324, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, - }, - }, - }, - { - Line: 331, - Name: "preferWriteByte", - MatcherName: "m", - DocTags: []string{"performance", "experimental", "opinionated"}, - DocSummary: "Detects WriteRune calls with rune literal argument that is single byte and reports to use WriteByte instead", - DocBefore: "w.WriteRune('\\n')", - DocAfter: "w.WriteByte('\\n')", - Rules: []ir.Rule{{ - Line: 335, - SyntaxPatterns: []ir.PatternString{{Line: 335, Value: "$w.WriteRune($c)"}}, - ReportTemplate: "consider writing single byte rune $c with $w.WriteByte($c)", - WhereExpr: ir.FilterExpr{ - Line: 336, - Op: ir.FilterAndOp, - Src: "m[\"w\"].Type.Implements(\"io.ByteWriter\") && (m[\"c\"].Const && m[\"c\"].Value.Int() < runeSelf)", - Args: []ir.FilterExpr{ - { - Line: 336, - Op: ir.FilterVarTypeImplementsOp, - Src: "m[\"w\"].Type.Implements(\"io.ByteWriter\")", - Value: "w", - Args: []ir.FilterExpr{{Line: 336, Op: ir.FilterStringOp, Src: "\"io.ByteWriter\"", Value: "io.ByteWriter"}}, - }, - { - Line: 336, - Op: ir.FilterAndOp, - Src: "(m[\"c\"].Const && m[\"c\"].Value.Int() < runeSelf)", - Args: []ir.FilterExpr{ - { - Line: 336, - Op: ir.FilterVarConstOp, - Src: "m[\"c\"].Const", - Value: "c", - }, - { - Line: 336, - Op: ir.FilterLtOp, - Src: "m[\"c\"].Value.Int() < runeSelf", - Args: []ir.FilterExpr{ - { - Line: 336, - Op: ir.FilterVarValueIntOp, - Src: "m[\"c\"].Value.Int()", - Value: "c", - }, - { - Line: 336, - Op: ir.FilterIntOp, - Src: "runeSelf", - Value: int64(128), - }, - }, - }, - }, - }, - }, - }, - }}, - }, - { - Line: 344, - Name: "preferFprint", - MatcherName: "m", - DocTags: []string{"performance", "experimental"}, - DocSummary: "Detects fmt.Sprint(f/ln) calls which can be replaced with fmt.Fprint(f/ln)", - DocBefore: "w.Write([]byte(fmt.Sprintf(\"%x\", 10)))", - DocAfter: "fmt.Fprintf(w, \"%x\", 10)", - Rules: []ir.Rule{ - { - Line: 345, - SyntaxPatterns: []ir.PatternString{{Line: 345, Value: "$w.Write([]byte(fmt.Sprint($*args)))"}}, - ReportTemplate: "fmt.Fprint($w, $args) should be preferred to the $$", - SuggestTemplate: "fmt.Fprint($w, $args)", - WhereExpr: ir.FilterExpr{ - Line: 346, - Op: ir.FilterVarTypeImplementsOp, - Src: "m[\"w\"].Type.Implements(\"io.Writer\")", - Value: "w", - Args: []ir.FilterExpr{{Line: 346, Op: ir.FilterStringOp, Src: "\"io.Writer\"", Value: "io.Writer"}}, - }, - }, - { - Line: 350, - SyntaxPatterns: []ir.PatternString{{Line: 350, Value: "$w.Write([]byte(fmt.Sprintf($*args)))"}}, - ReportTemplate: "fmt.Fprintf($w, $args) should be preferred to the $$", - SuggestTemplate: "fmt.Fprintf($w, $args)", - WhereExpr: ir.FilterExpr{ - Line: 351, - Op: ir.FilterVarTypeImplementsOp, - Src: "m[\"w\"].Type.Implements(\"io.Writer\")", - Value: "w", - Args: []ir.FilterExpr{{Line: 351, Op: ir.FilterStringOp, Src: "\"io.Writer\"", Value: "io.Writer"}}, - }, - }, - { - Line: 355, - SyntaxPatterns: []ir.PatternString{{Line: 355, Value: "$w.Write([]byte(fmt.Sprintln($*args)))"}}, - ReportTemplate: "fmt.Fprintln($w, $args) should be preferred to the $$", - SuggestTemplate: "fmt.Fprintln($w, $args)", - WhereExpr: ir.FilterExpr{ - Line: 356, - Op: ir.FilterVarTypeImplementsOp, - Src: "m[\"w\"].Type.Implements(\"io.Writer\")", - Value: "w", - Args: []ir.FilterExpr{{Line: 356, Op: ir.FilterStringOp, Src: "\"io.Writer\"", Value: "io.Writer"}}, - }, - }, - { - Line: 360, - SyntaxPatterns: []ir.PatternString{{Line: 360, Value: "io.WriteString($w, fmt.Sprint($*args))"}}, - ReportTemplate: "suggestion: fmt.Fprint($w, $args)", - SuggestTemplate: "fmt.Fprint($w, $args)", - }, - { - Line: 361, - SyntaxPatterns: []ir.PatternString{{Line: 361, Value: "io.WriteString($w, fmt.Sprintf($*args))"}}, - ReportTemplate: "suggestion: fmt.Fprintf($w, $args)", - SuggestTemplate: "fmt.Fprintf($w, $args)", - }, - { - Line: 362, - SyntaxPatterns: []ir.PatternString{{Line: 362, Value: "io.WriteString($w, fmt.Sprintln($*args))"}}, - ReportTemplate: "suggestion: fmt.Fprintln($w, $args)", - SuggestTemplate: "fmt.Fprintln($w, $args)", - }, - { - Line: 364, - SyntaxPatterns: []ir.PatternString{{Line: 364, Value: "$w.WriteString(fmt.Sprint($*args))"}}, - ReportTemplate: "suggestion: fmt.Fprint($w, $args)", - SuggestTemplate: "fmt.Fprint($w, $args)", - WhereExpr: ir.FilterExpr{ - Line: 365, - Op: ir.FilterAndOp, - Src: "m[\"w\"].Type.Implements(\"io.Writer\") && m[\"w\"].Type.Implements(\"io.StringWriter\")", - Args: []ir.FilterExpr{ - { - Line: 365, - Op: ir.FilterVarTypeImplementsOp, - Src: "m[\"w\"].Type.Implements(\"io.Writer\")", - Value: "w", - Args: []ir.FilterExpr{{Line: 365, Op: ir.FilterStringOp, Src: "\"io.Writer\"", Value: "io.Writer"}}, - }, - { - Line: 365, - Op: ir.FilterVarTypeImplementsOp, - Src: "m[\"w\"].Type.Implements(\"io.StringWriter\")", - Value: "w", - Args: []ir.FilterExpr{{Line: 365, Op: ir.FilterStringOp, Src: "\"io.StringWriter\"", Value: "io.StringWriter"}}, - }, - }, - }, - }, - { - Line: 367, - SyntaxPatterns: []ir.PatternString{{Line: 367, Value: "$w.WriteString(fmt.Sprintf($*args))"}}, - ReportTemplate: "suggestion: fmt.Fprintf($w, $args)", - SuggestTemplate: "fmt.Fprintf($w, $args)", - WhereExpr: ir.FilterExpr{ - Line: 368, - Op: ir.FilterAndOp, - Src: "m[\"w\"].Type.Implements(\"io.Writer\") && m[\"w\"].Type.Implements(\"io.StringWriter\")", - Args: []ir.FilterExpr{ - { - Line: 368, - Op: ir.FilterVarTypeImplementsOp, - Src: "m[\"w\"].Type.Implements(\"io.Writer\")", - Value: "w", - Args: []ir.FilterExpr{{Line: 368, Op: ir.FilterStringOp, Src: "\"io.Writer\"", Value: "io.Writer"}}, - }, - { - Line: 368, - Op: ir.FilterVarTypeImplementsOp, - Src: "m[\"w\"].Type.Implements(\"io.StringWriter\")", - Value: "w", - Args: []ir.FilterExpr{{Line: 368, Op: ir.FilterStringOp, Src: "\"io.StringWriter\"", Value: "io.StringWriter"}}, - }, - }, - }, - }, - { - Line: 370, - SyntaxPatterns: []ir.PatternString{{Line: 370, Value: "$w.WriteString(fmt.Sprintln($*args))"}}, - ReportTemplate: "suggestion: fmt.Fprintln($w, $args)", - SuggestTemplate: "fmt.Fprintln($w, $args)", - WhereExpr: ir.FilterExpr{ - Line: 371, - Op: ir.FilterAndOp, - Src: "m[\"w\"].Type.Implements(\"io.Writer\") && m[\"w\"].Type.Implements(\"io.StringWriter\")", - Args: []ir.FilterExpr{ - { - Line: 371, - Op: ir.FilterVarTypeImplementsOp, - Src: "m[\"w\"].Type.Implements(\"io.Writer\")", - Value: "w", - Args: []ir.FilterExpr{{Line: 371, Op: ir.FilterStringOp, Src: "\"io.Writer\"", Value: "io.Writer"}}, - }, - { - Line: 371, - Op: ir.FilterVarTypeImplementsOp, - Src: "m[\"w\"].Type.Implements(\"io.StringWriter\")", - Value: "w", - Args: []ir.FilterExpr{{Line: 371, Op: ir.FilterStringOp, Src: "\"io.StringWriter\"", Value: "io.StringWriter"}}, - }, - }, - }, - }, - }, - }, - { - Line: 379, - Name: "dupArg", - MatcherName: "m", - DocTags: []string{"diagnostic"}, - DocSummary: "Detects suspicious duplicated arguments", - DocBefore: "copy(dst, dst)", - DocAfter: "copy(dst, src)", - Rules: []ir.Rule{ - { - Line: 380, - SyntaxPatterns: []ir.PatternString{ - {Line: 380, Value: "$x.Equal($x)"}, - {Line: 380, Value: "$x.Equals($x)"}, - {Line: 380, Value: "$x.Compare($x)"}, - {Line: 380, Value: "$x.Cmp($x)"}, - }, - ReportTemplate: "suspicious method call with the same argument and receiver", - WhereExpr: ir.FilterExpr{Line: 381, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, - }, - { - Line: 384, - SyntaxPatterns: []ir.PatternString{ - {Line: 384, Value: "copy($x, $x)"}, - {Line: 385, Value: "cmp.Compare($x, $x)"}, - {Line: 386, Value: "maps.Equal($x, $x)"}, - {Line: 387, Value: "math.Dim($x, $x)"}, - {Line: 388, Value: "math.Max($x, $x)"}, - {Line: 389, Value: "math.Min($x, $x)"}, - {Line: 390, Value: "reflect.Copy($x, $x)"}, - {Line: 391, Value: "reflect.DeepEqual($x, $x)"}, - {Line: 392, Value: "slices.Compare($x, $x)"}, - {Line: 393, Value: "slices.Equal($x, $x)"}, - {Line: 394, Value: "strings.Contains($x, $x)"}, - {Line: 395, Value: "strings.Compare($x, $x)"}, - {Line: 396, Value: "strings.EqualFold($x, $x)"}, - {Line: 397, Value: "strings.HasPrefix($x, $x)"}, - {Line: 398, Value: "strings.HasSuffix($x, $x)"}, - {Line: 399, Value: "strings.Index($x, $x)"}, - {Line: 400, Value: "strings.LastIndex($x, $x)"}, - {Line: 401, Value: "strings.Split($x, $x)"}, - {Line: 402, Value: "strings.SplitAfter($x, $x)"}, - {Line: 403, Value: "strings.SplitAfterN($x, $x, $_)"}, - {Line: 404, Value: "strings.SplitN($x, $x, $_)"}, - {Line: 405, Value: "strings.Replace($_, $x, $x, $_)"}, - {Line: 406, Value: "strings.ReplaceAll($_, $x, $x)"}, - {Line: 407, Value: "bytes.Contains($x, $x)"}, - {Line: 408, Value: "bytes.Compare($x, $x)"}, - {Line: 409, Value: "bytes.Equal($x, $x)"}, - {Line: 410, Value: "bytes.EqualFold($x, $x)"}, - {Line: 411, Value: "bytes.HasPrefix($x, $x)"}, - {Line: 412, Value: "bytes.HasSuffix($x, $x)"}, - {Line: 413, Value: "bytes.Index($x, $x)"}, - {Line: 414, Value: "bytes.LastIndex($x, $x)"}, - {Line: 415, Value: "bytes.Split($x, $x)"}, - {Line: 416, Value: "bytes.SplitAfter($x, $x)"}, - {Line: 417, Value: "bytes.SplitAfterN($x, $x, $_)"}, - {Line: 418, Value: "bytes.SplitN($x, $x, $_)"}, - {Line: 419, Value: "bytes.Replace($_, $x, $x, $_)"}, - {Line: 420, Value: "bytes.ReplaceAll($_, $x, $x)"}, - {Line: 421, Value: "types.Identical($x, $x)"}, - {Line: 422, Value: "types.IdenticalIgnoreTags($x, $x)"}, - {Line: 423, Value: "draw.Draw($x, $_, $x, $_, $_)"}, - }, - ReportTemplate: "suspicious duplicated args in $$", - WhereExpr: ir.FilterExpr{Line: 424, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, - }, - }, - }, - { - Line: 432, - Name: "returnAfterHttpError", - MatcherName: "m", - DocTags: []string{"diagnostic", "experimental"}, - DocSummary: "Detects suspicious http.Error call without following return", - DocBefore: "if err != nil { http.Error(...); }", - DocAfter: "if err != nil { http.Error(...); return; }", - Rules: []ir.Rule{{ - Line: 433, - SyntaxPatterns: []ir.PatternString{{Line: 433, Value: "if $_ { $*_; http.Error($w, $err, $code) }"}}, - ReportTemplate: "Possibly return is missed after the http.Error call", - LocationVar: "w", - }}, - }, - { - Line: 442, - Name: "preferFilepathJoin", - MatcherName: "m", - DocTags: []string{"style", "experimental"}, - DocSummary: "Detects concatenation with os.PathSeparator which can be replaced with filepath.Join", - DocBefore: "x + string(os.PathSeparator) + y", - DocAfter: "filepath.Join(x, y)", - Rules: []ir.Rule{{ - Line: 443, - SyntaxPatterns: []ir.PatternString{{Line: 443, Value: "$x + string(os.PathSeparator) + $y"}}, - ReportTemplate: "filepath.Join($x, $y) should be preferred to the $$", - SuggestTemplate: "filepath.Join($x, $y)", - WhereExpr: ir.FilterExpr{ - Line: 444, - Op: ir.FilterAndOp, - Src: "m[\"x\"].Type.Is(`string`) && m[\"y\"].Type.Is(`string`)", - Args: []ir.FilterExpr{ - { - Line: 444, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"x\"].Type.Is(`string`)", - Value: "x", - Args: []ir.FilterExpr{{Line: 444, Op: ir.FilterStringOp, Src: "`string`", Value: "string"}}, - }, - { - Line: 444, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"y\"].Type.Is(`string`)", - Value: "y", - Args: []ir.FilterExpr{{Line: 444, Op: ir.FilterStringOp, Src: "`string`", Value: "string"}}, - }, - }, - }, - }}, - }, - { - Line: 453, - Name: "preferStringWriter", - MatcherName: "m", - DocTags: []string{"performance", "experimental"}, - DocSummary: "Detects w.Write or io.WriteString calls which can be replaced with w.WriteString", - DocBefore: "w.Write([]byte(\"foo\"))", - DocAfter: "w.WriteString(\"foo\")", - Rules: []ir.Rule{ - { - Line: 454, - SyntaxPatterns: []ir.PatternString{{Line: 454, Value: "$w.Write([]byte($s))"}}, - ReportTemplate: "$w.WriteString($s) should be preferred to the $$", - SuggestTemplate: "$w.WriteString($s)", - WhereExpr: ir.FilterExpr{ - Line: 455, - Op: ir.FilterVarTypeImplementsOp, - Src: "m[\"w\"].Type.Implements(\"io.StringWriter\")", - Value: "w", - Args: []ir.FilterExpr{{Line: 455, Op: ir.FilterStringOp, Src: "\"io.StringWriter\"", Value: "io.StringWriter"}}, - }, - }, - { - Line: 459, - SyntaxPatterns: []ir.PatternString{{Line: 459, Value: "io.WriteString($w, $s)"}}, - ReportTemplate: "$w.WriteString($s) should be preferred to the $$", - SuggestTemplate: "$w.WriteString($s)", - WhereExpr: ir.FilterExpr{ - Line: 460, - Op: ir.FilterVarTypeImplementsOp, - Src: "m[\"w\"].Type.Implements(\"io.StringWriter\")", - Value: "w", - Args: []ir.FilterExpr{{Line: 460, Op: ir.FilterStringOp, Src: "\"io.StringWriter\"", Value: "io.StringWriter"}}, - }, - }, - }, - }, - { - Line: 469, - Name: "sliceClear", - MatcherName: "m", - DocTags: []string{"performance", "experimental"}, - DocSummary: "Detects slice clear loops, suggests an idiom that is recognized by the Go compiler", - DocBefore: "for i := 0; i < len(buf); i++ { buf[i] = 0 }", - DocAfter: "for i := range buf { buf[i] = 0 }", - Rules: []ir.Rule{{ - Line: 470, - SyntaxPatterns: []ir.PatternString{{Line: 470, Value: "for $i := 0; $i < len($xs); $i++ { $xs[$i] = $zero }"}}, - ReportTemplate: "rewrite as for-range so compiler can recognize this pattern", - WhereExpr: ir.FilterExpr{ - Line: 471, - Op: ir.FilterEqOp, - Src: "m[\"zero\"].Value.Int() == 0", - Args: []ir.FilterExpr{ - { - Line: 471, - Op: ir.FilterVarValueIntOp, - Src: "m[\"zero\"].Value.Int()", - Value: "zero", - }, - { - Line: 471, - Op: ir.FilterIntOp, - Src: "0", - Value: int64(0), - }, - }, - }, - }}, - }, - { - Line: 479, - Name: "syncMapLoadAndDelete", - MatcherName: "m", - DocTags: []string{"diagnostic", "experimental"}, - DocSummary: "Detects sync.Map load+delete operations that can be replaced with LoadAndDelete", - DocBefore: "v, ok := m.Load(k); if ok { m.Delete($k); f(v); }", - DocAfter: "v, deleted := m.LoadAndDelete(k); if deleted { f(v) }", - Rules: []ir.Rule{{ - Line: 480, - SyntaxPatterns: []ir.PatternString{{Line: 480, Value: "$_, $ok := $m.Load($k); if $ok { $m.Delete($k); $*_ }"}}, - ReportTemplate: "use $m.LoadAndDelete to perform load+delete operations atomically", - WhereExpr: ir.FilterExpr{ - Line: 481, - Op: ir.FilterAndOp, - Src: "m.GoVersion().GreaterEqThan(\"1.15\") &&\n\tm[\"m\"].Type.Is(`*sync.Map`)", - Args: []ir.FilterExpr{ - { - Line: 481, - Op: ir.FilterGoVersionGreaterEqThanOp, - Src: "m.GoVersion().GreaterEqThan(\"1.15\")", - Value: "1.15", - }, - { - Line: 482, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"m\"].Type.Is(`*sync.Map`)", - Value: "m", - Args: []ir.FilterExpr{{Line: 482, Op: ir.FilterStringOp, Src: "`*sync.Map`", Value: "*sync.Map"}}, - }, - }, - }, - }}, - }, - { - Line: 490, - Name: "sprintfQuotedString", - MatcherName: "m", - DocTags: []string{"diagnostic", "experimental"}, - DocSummary: "Detects \"%s\" formatting directives that can be replaced with %q", - DocBefore: "fmt.Sprintf(`\"%s\"`, s)", - DocAfter: "fmt.Sprintf(`%q`, s)", - Rules: []ir.Rule{{ - Line: 491, - SyntaxPatterns: []ir.PatternString{{Line: 491, Value: "fmt.Sprintf($s, $*_)"}}, - ReportTemplate: "use %q instead of \"%s\" for quoted strings", - WhereExpr: ir.FilterExpr{ - Line: 492, - Op: ir.FilterOrOp, - Src: "m[\"s\"].Text.Matches(\"^`.*\\\"%s\\\".*`$\") ||\n\tm[\"s\"].Text.Matches(`^\".*\\\\\"%s\\\\\".*\"$`)", - Args: []ir.FilterExpr{ - { - Line: 492, - Op: ir.FilterVarTextMatchesOp, - Src: "m[\"s\"].Text.Matches(\"^`.*\\\"%s\\\".*`$\")", - Value: "s", - Args: []ir.FilterExpr{{Line: 492, Op: ir.FilterStringOp, Src: "\"^`.*\\\"%s\\\".*`$\"", Value: "^`.*\"%s\".*`$"}}, - }, - { - Line: 493, - Op: ir.FilterVarTextMatchesOp, - Src: "m[\"s\"].Text.Matches(`^\".*\\\\\"%s\\\\\".*\"$`)", - Value: "s", - Args: []ir.FilterExpr{{Line: 493, Op: ir.FilterStringOp, Src: "`^\".*\\\\\"%s\\\\\".*\"$`", Value: "^\".*\\\\\"%s\\\\\".*\"$"}}, - }, - }, - }, - }}, - }, - { - Line: 501, - Name: "offBy1", - MatcherName: "m", - DocTags: []string{"diagnostic"}, - DocSummary: "Detects various off-by-one kind of errors", - DocBefore: "xs[len(xs)]", - DocAfter: "xs[len(xs)-1]", - Rules: []ir.Rule{ - { - Line: 502, - SyntaxPatterns: []ir.PatternString{{Line: 502, Value: "$x[len($x)]"}}, - ReportTemplate: "index expr always panics; maybe you wanted $x[len($x)-1]?", - SuggestTemplate: "$x[len($x)-1]", - WhereExpr: ir.FilterExpr{ - Line: 503, - Op: ir.FilterAndOp, - Src: "m[\"x\"].Pure && m[\"x\"].Type.Is(`[]$_`)", - Args: []ir.FilterExpr{ - {Line: 503, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, - { - Line: 503, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"x\"].Type.Is(`[]$_`)", - Value: "x", - Args: []ir.FilterExpr{{Line: 503, Op: ir.FilterStringOp, Src: "`[]$_`", Value: "[]$_"}}, - }, - }, - }, - }, - { - Line: 510, - SyntaxPatterns: []ir.PatternString{ - {Line: 511, Value: "$i := strings.Index($s, $_); $_ := $slicing[$i:]"}, - {Line: 512, Value: "$i := strings.Index($s, $_); $_ = $slicing[$i:]"}, - {Line: 513, Value: "$i := bytes.Index($s, $_); $_ := $slicing[$i:]"}, - {Line: 514, Value: "$i := bytes.Index($s, $_); $_ = $slicing[$i:]"}, - }, - ReportTemplate: "Index() can return -1; maybe you wanted to do $s[$i+1:]", - WhereExpr: ir.FilterExpr{ - Line: 515, - Op: ir.FilterEqOp, - Src: "m[\"s\"].Text == m[\"slicing\"].Text", - Args: []ir.FilterExpr{ - {Line: 515, Op: ir.FilterVarTextOp, Src: "m[\"s\"].Text", Value: "s"}, - {Line: 515, Op: ir.FilterVarTextOp, Src: "m[\"slicing\"].Text", Value: "slicing"}, - }, - }, - LocationVar: "slicing", - }, - { - Line: 519, - SyntaxPatterns: []ir.PatternString{ - {Line: 520, Value: "$i := strings.Index($s, $_); $_ := $slicing[:$i]"}, - {Line: 521, Value: "$i := strings.Index($s, $_); $_ = $slicing[:$i]"}, - {Line: 522, Value: "$i := bytes.Index($s, $_); $_ := $slicing[:$i]"}, - {Line: 523, Value: "$i := bytes.Index($s, $_); $_ = $slicing[:$i]"}, - }, - ReportTemplate: "Index() can return -1; maybe you wanted to do $s[:$i+1]", - WhereExpr: ir.FilterExpr{ - Line: 524, - Op: ir.FilterEqOp, - Src: "m[\"s\"].Text == m[\"slicing\"].Text", - Args: []ir.FilterExpr{ - {Line: 524, Op: ir.FilterVarTextOp, Src: "m[\"s\"].Text", Value: "s"}, - {Line: 524, Op: ir.FilterVarTextOp, Src: "m[\"slicing\"].Text", Value: "slicing"}, - }, - }, - LocationVar: "slicing", - }, - { - Line: 528, - SyntaxPatterns: []ir.PatternString{ - {Line: 529, Value: "$s[strings.Index($s, $_):]"}, - {Line: 530, Value: "$s[:strings.Index($s, $_)]"}, - {Line: 531, Value: "$s[bytes.Index($s, $_):]"}, - {Line: 532, Value: "$s[:bytes.Index($s, $_)]"}, - }, - ReportTemplate: "Index() can return -1; maybe you wanted to do Index()+1", - }, - }, - }, - { - Line: 540, - Name: "unslice", - MatcherName: "m", - DocTags: []string{"style"}, - DocSummary: "Detects slice expressions that can be simplified to sliced expression itself", - DocBefore: "copy(b[:], values...)", - DocAfter: "copy(b, values...)", - Rules: []ir.Rule{{ - Line: 541, - SyntaxPatterns: []ir.PatternString{{Line: 541, Value: "$s[:]"}}, - ReportTemplate: "could simplify $$ to $s", - SuggestTemplate: "$s", - WhereExpr: ir.FilterExpr{ - Line: 542, - Op: ir.FilterOrOp, - Src: "m[\"s\"].Type.Is(`string`) || m[\"s\"].Type.Is(`[]$_`)", - Args: []ir.FilterExpr{ - { - Line: 542, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"s\"].Type.Is(`string`)", - Value: "s", - Args: []ir.FilterExpr{{Line: 542, Op: ir.FilterStringOp, Src: "`string`", Value: "string"}}, - }, - { - Line: 542, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"s\"].Type.Is(`[]$_`)", - Value: "s", - Args: []ir.FilterExpr{{Line: 542, Op: ir.FilterStringOp, Src: "`[]$_`", Value: "[]$_"}}, - }, - }, - }, - }}, - }, - { - Line: 551, - Name: "yodaStyleExpr", - MatcherName: "m", - DocTags: []string{"style", "experimental"}, - DocSummary: "Detects Yoda style expressions and suggests to replace them", - DocBefore: "return nil != ptr", - DocAfter: "return ptr != nil", - Rules: []ir.Rule{ - { - Line: 552, - SyntaxPatterns: []ir.PatternString{{Line: 552, Value: "$constval != $x"}}, - ReportTemplate: "consider to change order in expression to $x != $constval", - WhereExpr: ir.FilterExpr{ - Line: 552, - Op: ir.FilterAndOp, - Src: "m[\"constval\"].Node.Is(`BasicLit`) && !m[\"x\"].Node.Is(`BasicLit`)", - Args: []ir.FilterExpr{ - { - Line: 552, - Op: ir.FilterVarNodeIsOp, - Src: "m[\"constval\"].Node.Is(`BasicLit`)", - Value: "constval", - Args: []ir.FilterExpr{{Line: 552, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"}}, - }, - { - Line: 552, - Op: ir.FilterNotOp, - Src: "!m[\"x\"].Node.Is(`BasicLit`)", - Args: []ir.FilterExpr{{ - Line: 552, - Op: ir.FilterVarNodeIsOp, - Src: "m[\"x\"].Node.Is(`BasicLit`)", - Value: "x", - Args: []ir.FilterExpr{{Line: 552, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"}}, - }}, - }, - }, - }, - }, - { - Line: 554, - SyntaxPatterns: []ir.PatternString{{Line: 554, Value: "$constval == $x"}}, - ReportTemplate: "consider to change order in expression to $x == $constval", - WhereExpr: ir.FilterExpr{ - Line: 554, - Op: ir.FilterAndOp, - Src: "m[\"constval\"].Node.Is(`BasicLit`) && !m[\"x\"].Node.Is(`BasicLit`)", - Args: []ir.FilterExpr{ - { - Line: 554, - Op: ir.FilterVarNodeIsOp, - Src: "m[\"constval\"].Node.Is(`BasicLit`)", - Value: "constval", - Args: []ir.FilterExpr{{Line: 554, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"}}, - }, - { - Line: 554, - Op: ir.FilterNotOp, - Src: "!m[\"x\"].Node.Is(`BasicLit`)", - Args: []ir.FilterExpr{{ - Line: 554, - Op: ir.FilterVarNodeIsOp, - Src: "m[\"x\"].Node.Is(`BasicLit`)", - Value: "x", - Args: []ir.FilterExpr{{Line: 554, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"}}, - }}, - }, - }, - }, - }, - { - Line: 557, - SyntaxPatterns: []ir.PatternString{{Line: 557, Value: "nil != $x"}}, - ReportTemplate: "consider to change order in expression to $x != nil", - WhereExpr: ir.FilterExpr{ - Line: 557, - Op: ir.FilterNotOp, - Src: "!m[\"x\"].Node.Is(`BasicLit`)", - Args: []ir.FilterExpr{{ - Line: 557, - Op: ir.FilterVarNodeIsOp, - Src: "m[\"x\"].Node.Is(`BasicLit`)", - Value: "x", - Args: []ir.FilterExpr{{Line: 557, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"}}, - }}, - }, - }, - { - Line: 559, - SyntaxPatterns: []ir.PatternString{{Line: 559, Value: "nil == $x"}}, - ReportTemplate: "consider to change order in expression to $x == nil", - WhereExpr: ir.FilterExpr{ - Line: 559, - Op: ir.FilterNotOp, - Src: "!m[\"x\"].Node.Is(`BasicLit`)", - Args: []ir.FilterExpr{{ - Line: 559, - Op: ir.FilterVarNodeIsOp, - Src: "m[\"x\"].Node.Is(`BasicLit`)", - Value: "x", - Args: []ir.FilterExpr{{Line: 559, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"}}, - }}, - }, - }, - }, - }, - { - Line: 567, - Name: "equalFold", - MatcherName: "m", - DocTags: []string{"performance", "experimental"}, - DocSummary: "Detects unoptimal strings/bytes case-insensitive comparison", - DocBefore: "strings.ToLower(x) == strings.ToLower(y)", - DocAfter: "strings.EqualFold(x, y)", - Rules: []ir.Rule{ - { - Line: 576, - SyntaxPatterns: []ir.PatternString{ - {Line: 577, Value: "strings.ToLower($x) == $y"}, - {Line: 578, Value: "strings.ToLower($x) == strings.ToLower($y)"}, - {Line: 579, Value: "$x == strings.ToLower($y)"}, - {Line: 580, Value: "strings.ToUpper($x) == $y"}, - {Line: 581, Value: "strings.ToUpper($x) == strings.ToUpper($y)"}, - {Line: 582, Value: "$x == strings.ToUpper($y)"}, - }, - ReportTemplate: "consider replacing with strings.EqualFold($x, $y)", - SuggestTemplate: "strings.EqualFold($x, $y)", - WhereExpr: ir.FilterExpr{ - Line: 583, - Op: ir.FilterAndOp, - Src: "m[\"x\"].Pure && m[\"y\"].Pure && m[\"x\"].Text != m[\"y\"].Text", - Args: []ir.FilterExpr{ - { - Line: 583, - Op: ir.FilterAndOp, - Src: "m[\"x\"].Pure && m[\"y\"].Pure", - Args: []ir.FilterExpr{ - {Line: 583, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, - {Line: 583, Op: ir.FilterVarPureOp, Src: "m[\"y\"].Pure", Value: "y"}, - }, - }, - { - Line: 583, - Op: ir.FilterNeqOp, - Src: "m[\"x\"].Text != m[\"y\"].Text", - Args: []ir.FilterExpr{ - {Line: 583, Op: ir.FilterVarTextOp, Src: "m[\"x\"].Text", Value: "x"}, - {Line: 583, Op: ir.FilterVarTextOp, Src: "m[\"y\"].Text", Value: "y"}, - }, - }, - }, - }, - }, - { - Line: 588, - SyntaxPatterns: []ir.PatternString{ - {Line: 589, Value: "strings.ToLower($x) != $y"}, - {Line: 590, Value: "strings.ToLower($x) != strings.ToLower($y)"}, - {Line: 591, Value: "$x != strings.ToLower($y)"}, - {Line: 592, Value: "strings.ToUpper($x) != $y"}, - {Line: 593, Value: "strings.ToUpper($x) != strings.ToUpper($y)"}, - {Line: 594, Value: "$x != strings.ToUpper($y)"}, - }, - ReportTemplate: "consider replacing with !strings.EqualFold($x, $y)", - SuggestTemplate: "!strings.EqualFold($x, $y)", - WhereExpr: ir.FilterExpr{ - Line: 595, - Op: ir.FilterAndOp, - Src: "m[\"x\"].Pure && m[\"y\"].Pure && m[\"x\"].Text != m[\"y\"].Text", - Args: []ir.FilterExpr{ - { - Line: 595, - Op: ir.FilterAndOp, - Src: "m[\"x\"].Pure && m[\"y\"].Pure", - Args: []ir.FilterExpr{ - {Line: 595, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, - {Line: 595, Op: ir.FilterVarPureOp, Src: "m[\"y\"].Pure", Value: "y"}, - }, - }, - { - Line: 595, - Op: ir.FilterNeqOp, - Src: "m[\"x\"].Text != m[\"y\"].Text", - Args: []ir.FilterExpr{ - {Line: 595, Op: ir.FilterVarTextOp, Src: "m[\"x\"].Text", Value: "x"}, - {Line: 595, Op: ir.FilterVarTextOp, Src: "m[\"y\"].Text", Value: "y"}, - }, - }, - }, - }, - }, - { - Line: 600, - SyntaxPatterns: []ir.PatternString{ - {Line: 601, Value: "bytes.Equal(bytes.ToLower($x), $y)"}, - {Line: 602, Value: "bytes.Equal(bytes.ToLower($x), bytes.ToLower($y))"}, - {Line: 603, Value: "bytes.Equal($x, bytes.ToLower($y))"}, - {Line: 604, Value: "bytes.Equal(bytes.ToUpper($x), $y)"}, - {Line: 605, Value: "bytes.Equal(bytes.ToUpper($x), bytes.ToUpper($y))"}, - {Line: 606, Value: "bytes.Equal($x, bytes.ToUpper($y))"}, - }, - ReportTemplate: "consider replacing with bytes.EqualFold($x, $y)", - SuggestTemplate: "bytes.EqualFold($x, $y)", - WhereExpr: ir.FilterExpr{ - Line: 607, - Op: ir.FilterAndOp, - Src: "m[\"x\"].Pure && m[\"y\"].Pure && m[\"x\"].Text != m[\"y\"].Text", - Args: []ir.FilterExpr{ - { - Line: 607, - Op: ir.FilterAndOp, - Src: "m[\"x\"].Pure && m[\"y\"].Pure", - Args: []ir.FilterExpr{ - {Line: 607, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, - {Line: 607, Op: ir.FilterVarPureOp, Src: "m[\"y\"].Pure", Value: "y"}, - }, - }, - { - Line: 607, - Op: ir.FilterNeqOp, - Src: "m[\"x\"].Text != m[\"y\"].Text", - Args: []ir.FilterExpr{ - {Line: 607, Op: ir.FilterVarTextOp, Src: "m[\"x\"].Text", Value: "x"}, - {Line: 607, Op: ir.FilterVarTextOp, Src: "m[\"y\"].Text", Value: "y"}, - }, - }, - }, - }, - }, - }, - }, - { - Line: 616, - Name: "argOrder", - MatcherName: "m", - DocTags: []string{"diagnostic"}, - DocSummary: "Detects suspicious arguments order", - DocBefore: "strings.HasPrefix(\"#\", userpass)", - DocAfter: "strings.HasPrefix(userpass, \"#\")", - Rules: []ir.Rule{{ - Line: 617, - SyntaxPatterns: []ir.PatternString{ - {Line: 618, Value: "strings.HasPrefix($lit, $s)"}, - {Line: 619, Value: "bytes.HasPrefix($lit, $s)"}, - {Line: 620, Value: "strings.HasSuffix($lit, $s)"}, - {Line: 621, Value: "bytes.HasSuffix($lit, $s)"}, - {Line: 622, Value: "strings.Contains($lit, $s)"}, - {Line: 623, Value: "bytes.Contains($lit, $s)"}, - {Line: 624, Value: "strings.TrimPrefix($lit, $s)"}, - {Line: 625, Value: "bytes.TrimPrefix($lit, $s)"}, - {Line: 626, Value: "strings.TrimSuffix($lit, $s)"}, - {Line: 627, Value: "bytes.TrimSuffix($lit, $s)"}, - {Line: 628, Value: "strings.Split($lit, $s)"}, - {Line: 629, Value: "bytes.Split($lit, $s)"}, - }, - ReportTemplate: "$lit and $s arguments order looks reversed", - WhereExpr: ir.FilterExpr{ - Line: 630, - Op: ir.FilterAndOp, - Src: "(m[\"lit\"].Const || m[\"lit\"].ConstSlice) &&\n\t!(m[\"s\"].Const || m[\"s\"].ConstSlice) &&\n\t!m[\"lit\"].Node.Is(`Ident`)", - Args: []ir.FilterExpr{ - { - Line: 630, - Op: ir.FilterAndOp, - Src: "(m[\"lit\"].Const || m[\"lit\"].ConstSlice) &&\n\t!(m[\"s\"].Const || m[\"s\"].ConstSlice)", - Args: []ir.FilterExpr{ - { - Line: 630, - Op: ir.FilterOrOp, - Src: "(m[\"lit\"].Const || m[\"lit\"].ConstSlice)", - Args: []ir.FilterExpr{ - { - Line: 630, - Op: ir.FilterVarConstOp, - Src: "m[\"lit\"].Const", - Value: "lit", - }, - { - Line: 630, - Op: ir.FilterVarConstSliceOp, - Src: "m[\"lit\"].ConstSlice", - Value: "lit", - }, - }, - }, - { - Line: 631, - Op: ir.FilterNotOp, - Src: "!(m[\"s\"].Const || m[\"s\"].ConstSlice)", - Args: []ir.FilterExpr{{ - Line: 631, - Op: ir.FilterOrOp, - Src: "(m[\"s\"].Const || m[\"s\"].ConstSlice)", - Args: []ir.FilterExpr{ - { - Line: 631, - Op: ir.FilterVarConstOp, - Src: "m[\"s\"].Const", - Value: "s", - }, - { - Line: 631, - Op: ir.FilterVarConstSliceOp, - Src: "m[\"s\"].ConstSlice", - Value: "s", - }, - }, - }}, - }, - }, - }, - { - Line: 632, - Op: ir.FilterNotOp, - Src: "!m[\"lit\"].Node.Is(`Ident`)", - Args: []ir.FilterExpr{{ - Line: 632, - Op: ir.FilterVarNodeIsOp, - Src: "m[\"lit\"].Node.Is(`Ident`)", - Value: "lit", - Args: []ir.FilterExpr{{Line: 632, Op: ir.FilterStringOp, Src: "`Ident`", Value: "Ident"}}, - }}, - }, - }, - }, - }}, - }, - { - Line: 640, - Name: "stringConcatSimplify", - MatcherName: "m", - DocTags: []string{"style", "experimental"}, - DocSummary: "Detects string concat operations that can be simplified", - DocBefore: "strings.Join([]string{x, y}, \"_\")", - DocAfter: "x + \"_\" + y", - Rules: []ir.Rule{ - { - Line: 641, - SyntaxPatterns: []ir.PatternString{{Line: 641, Value: "strings.Join([]string{$x, $y}, \"\")"}}, - ReportTemplate: "suggestion: $x + $y", - SuggestTemplate: "$x + $y", - }, - { - Line: 642, - SyntaxPatterns: []ir.PatternString{{Line: 642, Value: "strings.Join([]string{$x, $y, $z}, \"\")"}}, - ReportTemplate: "suggestion: $x + $y + $z", - SuggestTemplate: "$x + $y + $z", - }, - { - Line: 643, - SyntaxPatterns: []ir.PatternString{{Line: 643, Value: "strings.Join([]string{$x, $y}, $glue)"}}, - ReportTemplate: "suggestion: $x + $glue + $y", - SuggestTemplate: "$x + $glue + $y", - }, - }, - }, - { - Line: 650, - Name: "timeExprSimplify", - MatcherName: "m", - DocTags: []string{"style", "experimental"}, - DocSummary: "Detects manual conversion to milli- or microseconds", - DocBefore: "t.Unix() / 1000", - DocAfter: "t.UnixMilli()", - Rules: []ir.Rule{ - { - Line: 655, - SyntaxPatterns: []ir.PatternString{{Line: 655, Value: "$t.Unix() / 1000"}}, - ReportTemplate: "use $t.UnixMilli() instead of $$", - SuggestTemplate: "$t.UnixMilli()", - WhereExpr: ir.FilterExpr{ - Line: 656, - Op: ir.FilterAndOp, - Src: "m.GoVersion().GreaterEqThan(\"1.17\") && isTime(m[\"t\"])", - Args: []ir.FilterExpr{ - { - Line: 656, - Op: ir.FilterGoVersionGreaterEqThanOp, - Src: "m.GoVersion().GreaterEqThan(\"1.17\")", - Value: "1.17", - }, - { - Line: 656, - Op: ir.FilterOrOp, - Src: "isTime(m[\"t\"])", - Args: []ir.FilterExpr{ - { - Line: 656, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"t\"].Type.Is(`time.Time`)", - Value: "t", - Args: []ir.FilterExpr{{Line: 652, Op: ir.FilterStringOp, Src: "`time.Time`", Value: "time.Time"}}, - }, - { - Line: 656, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"t\"].Type.Is(`*time.Time`)", - Value: "t", - Args: []ir.FilterExpr{{Line: 652, Op: ir.FilterStringOp, Src: "`*time.Time`", Value: "*time.Time"}}, - }, - }, - }, - }, - }, - }, - { - Line: 660, - SyntaxPatterns: []ir.PatternString{{Line: 660, Value: "$t.UnixNano() * 1000"}}, - ReportTemplate: "use $t.UnixMicro() instead of $$", - SuggestTemplate: "$t.UnixMicro()", - WhereExpr: ir.FilterExpr{ - Line: 661, - Op: ir.FilterAndOp, - Src: "m.GoVersion().GreaterEqThan(\"1.17\") && isTime(m[\"t\"])", - Args: []ir.FilterExpr{ - { - Line: 661, - Op: ir.FilterGoVersionGreaterEqThanOp, - Src: "m.GoVersion().GreaterEqThan(\"1.17\")", - Value: "1.17", - }, - { - Line: 661, - Op: ir.FilterOrOp, - Src: "isTime(m[\"t\"])", - Args: []ir.FilterExpr{ - { - Line: 661, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"t\"].Type.Is(`time.Time`)", - Value: "t", - Args: []ir.FilterExpr{{Line: 652, Op: ir.FilterStringOp, Src: "`time.Time`", Value: "time.Time"}}, - }, - { - Line: 661, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"t\"].Type.Is(`*time.Time`)", - Value: "t", - Args: []ir.FilterExpr{{Line: 652, Op: ir.FilterStringOp, Src: "`*time.Time`", Value: "*time.Time"}}, - }, - }, - }, - }, - }, - }, - }, - }, - { - Line: 670, - Name: "exposedSyncMutex", - MatcherName: "m", - DocTags: []string{"style", "experimental"}, - DocSummary: "Detects exposed methods from sync.Mutex and sync.RWMutex", - DocBefore: "type Foo struct{ ...; sync.Mutex; ... }", - DocAfter: "type Foo struct{ ...; mu sync.Mutex; ... }", - Rules: []ir.Rule{ - { - Line: 675, - SyntaxPatterns: []ir.PatternString{{Line: 675, Value: "type $x struct { $*_; sync.Mutex; $*_ }"}}, - ReportTemplate: "don't embed sync.Mutex", - WhereExpr: ir.FilterExpr{ - Line: 676, - Op: ir.FilterVarTextMatchesOp, - Src: "isExported(m[\"x\"])", - Value: "x", - Args: []ir.FilterExpr{{Line: 672, Op: ir.FilterStringOp, Src: "`^\\p{Lu}`", Value: "^\\p{Lu}"}}, - }, - }, - { - Line: 679, - SyntaxPatterns: []ir.PatternString{{Line: 679, Value: "type $x struct { $*_; *sync.Mutex; $*_ }"}}, - ReportTemplate: "don't embed *sync.Mutex", - WhereExpr: ir.FilterExpr{ - Line: 680, - Op: ir.FilterVarTextMatchesOp, - Src: "isExported(m[\"x\"])", - Value: "x", - Args: []ir.FilterExpr{{Line: 672, Op: ir.FilterStringOp, Src: "`^\\p{Lu}`", Value: "^\\p{Lu}"}}, - }, - }, - { - Line: 683, - SyntaxPatterns: []ir.PatternString{{Line: 683, Value: "type $x struct { $*_; sync.RWMutex; $*_ }"}}, - ReportTemplate: "don't embed sync.RWMutex", - WhereExpr: ir.FilterExpr{ - Line: 684, - Op: ir.FilterVarTextMatchesOp, - Src: "isExported(m[\"x\"])", - Value: "x", - Args: []ir.FilterExpr{{Line: 672, Op: ir.FilterStringOp, Src: "`^\\p{Lu}`", Value: "^\\p{Lu}"}}, - }, - }, - { - Line: 687, - SyntaxPatterns: []ir.PatternString{{Line: 687, Value: "type $x struct { $*_; *sync.RWMutex; $*_ }"}}, - ReportTemplate: "don't embed *sync.RWMutex", - WhereExpr: ir.FilterExpr{ - Line: 688, - Op: ir.FilterVarTextMatchesOp, - Src: "isExported(m[\"x\"])", - Value: "x", - Args: []ir.FilterExpr{{Line: 672, Op: ir.FilterStringOp, Src: "`^\\p{Lu}`", Value: "^\\p{Lu}"}}, - }, - }, - }, - }, - { - Line: 696, - Name: "badSorting", - MatcherName: "m", - DocTags: []string{"diagnostic", "experimental"}, - DocSummary: "Detects bad usage of sort package", - DocBefore: "xs = sort.StringSlice(xs)", - DocAfter: "sort.Strings(xs)", - Rules: []ir.Rule{ - { - Line: 697, - SyntaxPatterns: []ir.PatternString{{Line: 697, Value: "$x = sort.IntSlice($x)"}}, - ReportTemplate: "suspicious sort.IntSlice usage, maybe sort.Ints was intended?", - SuggestTemplate: "sort.Ints($x)", - WhereExpr: ir.FilterExpr{ - Line: 698, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"x\"].Type.Is(`[]int`)", - Value: "x", - Args: []ir.FilterExpr{{Line: 698, Op: ir.FilterStringOp, Src: "`[]int`", Value: "[]int"}}, - }, - }, - { - Line: 702, - SyntaxPatterns: []ir.PatternString{{Line: 702, Value: "$x = sort.Float64Slice($x)"}}, - ReportTemplate: "suspicious sort.Float64s usage, maybe sort.Float64s was intended?", - SuggestTemplate: "sort.Float64s($x)", - WhereExpr: ir.FilterExpr{ - Line: 703, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"x\"].Type.Is(`[]float64`)", - Value: "x", - Args: []ir.FilterExpr{{Line: 703, Op: ir.FilterStringOp, Src: "`[]float64`", Value: "[]float64"}}, - }, - }, - { - Line: 707, - SyntaxPatterns: []ir.PatternString{{Line: 707, Value: "$x = sort.StringSlice($x)"}}, - ReportTemplate: "suspicious sort.StringSlice usage, maybe sort.Strings was intended?", - SuggestTemplate: "sort.Strings($x)", - WhereExpr: ir.FilterExpr{ - Line: 708, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"x\"].Type.Is(`[]string`)", - Value: "x", - Args: []ir.FilterExpr{{Line: 708, Op: ir.FilterStringOp, Src: "`[]string`", Value: "[]string"}}, - }, - }, - }, - }, - { - Line: 717, - Name: "externalErrorReassign", - MatcherName: "m", - DocTags: []string{"diagnostic", "experimental"}, - DocSummary: "Detects suspicious reassignment of error from another package", - DocBefore: "io.EOF = nil", - DocAfter: "/* don't do it */", - Rules: []ir.Rule{{ - Line: 718, - SyntaxPatterns: []ir.PatternString{{Line: 718, Value: "$pkg.$err = $x"}}, - ReportTemplate: "suspicious reassignment of error from another package", - WhereExpr: ir.FilterExpr{ - Line: 719, - Op: ir.FilterAndOp, - Src: "m[\"err\"].Type.Is(`error`) && m[\"pkg\"].Object.Is(`PkgName`)", - Args: []ir.FilterExpr{ - { - Line: 719, - Op: ir.FilterVarTypeIsOp, - Src: "m[\"err\"].Type.Is(`error`)", - Value: "err", - Args: []ir.FilterExpr{{Line: 719, Op: ir.FilterStringOp, Src: "`error`", Value: "error"}}, - }, - { - Line: 719, - Op: ir.FilterVarObjectIsOp, - Src: "m[\"pkg\"].Object.Is(`PkgName`)", - Value: "pkg", - Args: []ir.FilterExpr{{Line: 719, Op: ir.FilterStringOp, Src: "`PkgName`", Value: "PkgName"}}, - }, - }, - }, - }}, - }, - { - Line: 727, - Name: "emptyDecl", - MatcherName: "m", - DocTags: []string{"diagnostic", "experimental"}, - DocSummary: "Detects suspicious empty declarations blocks", - DocBefore: "var()", - DocAfter: "/* nothing */", - Rules: []ir.Rule{ - { - Line: 728, - SyntaxPatterns: []ir.PatternString{{Line: 728, Value: "var()"}}, - ReportTemplate: "empty var() block", - }, - { - Line: 729, - SyntaxPatterns: []ir.PatternString{{Line: 729, Value: "const()"}}, - ReportTemplate: "empty const() block", - }, - { - Line: 730, - SyntaxPatterns: []ir.PatternString{{Line: 730, Value: "type()"}}, - ReportTemplate: "empty type() block", - }, - }, - }, - { - Line: 737, - Name: "dynamicFmtString", - MatcherName: "m", - DocTags: []string{"diagnostic", "experimental"}, - DocSummary: "Detects suspicious formatting strings usage", - DocBefore: "fmt.Errorf(msg)", - DocAfter: "errors.New(msg) or fmt.Errorf(\"%s\", msg)", - Rules: []ir.Rule{ - { - Line: 738, - SyntaxPatterns: []ir.PatternString{{Line: 738, Value: "fmt.Errorf($f)"}}, - ReportTemplate: "use errors.New($f) or fmt.Errorf(\"%s\", $f) instead", - SuggestTemplate: "errors.New($f)", - WhereExpr: ir.FilterExpr{ - Line: 739, - Op: ir.FilterNotOp, - Src: "!m[\"f\"].Const", - Args: []ir.FilterExpr{{ - Line: 739, - Op: ir.FilterVarConstOp, - Src: "m[\"f\"].Const", - Value: "f", - }}, - }, - }, - { - Line: 743, - SyntaxPatterns: []ir.PatternString{{Line: 743, Value: "fmt.Errorf($f($*args))"}}, - ReportTemplate: "use errors.New($f($*args)) or fmt.Errorf(\"%s\", $f($*args)) instead", - SuggestTemplate: "errors.New($f($*args))", - }, - }, - }, - { - Line: 752, - Name: "stringsCompare", - MatcherName: "m", - DocTags: []string{"style", "experimental"}, - DocSummary: "Detects strings.Compare usage", - DocBefore: "strings.Compare(x, y)", - DocAfter: "x < y", - Rules: []ir.Rule{ - { - Line: 753, - SyntaxPatterns: []ir.PatternString{{Line: 753, Value: "strings.Compare($s1, $s2) == 0"}}, - ReportTemplate: "suggestion: $s1 == $s2", - SuggestTemplate: "$s1 == $s2", - }, - { - Line: 756, - SyntaxPatterns: []ir.PatternString{ - {Line: 756, Value: "strings.Compare($s1, $s2) == -1"}, - {Line: 757, Value: "strings.Compare($s1, $s2) < 0"}, - }, - ReportTemplate: "suggestion: $s1 < $s2", - SuggestTemplate: "$s1 < $s2", - }, - { - Line: 760, - SyntaxPatterns: []ir.PatternString{ - {Line: 760, Value: "strings.Compare($s1, $s2) == 1"}, - {Line: 761, Value: "strings.Compare($s1, $s2) > 0"}, - }, - ReportTemplate: "suggestion: $s1 > $s2", - SuggestTemplate: "$s1 > $s2", - }, - }, - }, - { - Line: 769, - Name: "uncheckedInlineErr", - MatcherName: "m", - DocTags: []string{"diagnostic", "experimental"}, - DocSummary: "Detects unchecked errors in if statements", - DocBefore: "if err := expr(); err2 != nil { /*...*/ }", - DocAfter: "if err := expr(); err != nil { /*...*/ }", - Rules: []ir.Rule{{ - Line: 770, - SyntaxPatterns: []ir.PatternString{ - {Line: 771, Value: "if $err := $_($*_); $err2 != nil { $*_ }"}, - {Line: 772, Value: "if $err = $_($*_); $err2 != nil { $*_ }"}, - {Line: 773, Value: "if $*_, $err := $_($*_); $err2 != nil { $*_ }"}, - {Line: 774, Value: "if $*_, $err = $_($*_); $err2 != nil { $*_ }"}, - }, - ReportTemplate: "$err error is unchecked, maybe intended to check it instead of $err2", - WhereExpr: ir.FilterExpr{ - Line: 775, - Op: ir.FilterAndOp, - Src: "m[\"err\"].Type.Implements(\"error\") && m[\"err2\"].Type.Implements(\"error\") &&\n\tm[\"err\"].Text != m[\"err2\"].Text", - Args: []ir.FilterExpr{ - { - Line: 775, - Op: ir.FilterAndOp, - Src: "m[\"err\"].Type.Implements(\"error\") && m[\"err2\"].Type.Implements(\"error\")", - Args: []ir.FilterExpr{ - { - Line: 775, - Op: ir.FilterVarTypeImplementsOp, - Src: "m[\"err\"].Type.Implements(\"error\")", - Value: "err", - Args: []ir.FilterExpr{{Line: 775, Op: ir.FilterStringOp, Src: "\"error\"", Value: "error"}}, - }, - { - Line: 775, - Op: ir.FilterVarTypeImplementsOp, - Src: "m[\"err2\"].Type.Implements(\"error\")", - Value: "err2", - Args: []ir.FilterExpr{{Line: 775, Op: ir.FilterStringOp, Src: "\"error\"", Value: "error"}}, - }, - }, - }, - { - Line: 776, - Op: ir.FilterNeqOp, - Src: "m[\"err\"].Text != m[\"err2\"].Text", - Args: []ir.FilterExpr{ - {Line: 776, Op: ir.FilterVarTextOp, Src: "m[\"err\"].Text", Value: "err"}, - {Line: 776, Op: ir.FilterVarTextOp, Src: "m[\"err2\"].Text", Value: "err2"}, - }, - }, - }, - }, - LocationVar: "err", - }}, - }, - { - Line: 785, - Name: "badSyncOnceFunc", - MatcherName: "m", - DocTags: []string{"diagnostic", "experimental"}, - DocSummary: "Detects bad usage of sync.OnceFunc", - DocBefore: "sync.OnceFunc(foo)()", - DocAfter: "fooOnce := sync.OnceFunc(foo); ...; fooOnce()", - Rules: []ir.Rule{ - { - Line: 786, - SyntaxPatterns: []ir.PatternString{{Line: 786, Value: "$*_; sync.OnceFunc($x); $*_;"}}, - ReportTemplate: "possible sync.OnceFunc misuse, sync.OnceFunc($x) result is not used", - WhereExpr: ir.FilterExpr{ - Line: 788, - Op: ir.FilterGoVersionGreaterEqThanOp, - Src: "m.GoVersion().GreaterEqThan(\"1.21\")", - Value: "1.21", - }, - }, - { - Line: 790, - SyntaxPatterns: []ir.PatternString{{Line: 790, Value: "sync.OnceFunc($x)()"}}, - ReportTemplate: "possible sync.OnceFunc misuse, consider to assign sync.OnceFunc($x) to a variable", - WhereExpr: ir.FilterExpr{ - Line: 792, - Op: ir.FilterGoVersionGreaterEqThanOp, - Src: "m.GoVersion().GreaterEqThan(\"1.21\")", - Value: "1.21", - }, - }, - }, - }, - { - Line: 799, - Name: "zeroByteRepeat", - MatcherName: "m", - DocTags: []string{"performance"}, - DocSummary: "Detects bytes.Repeat with 0 value", - DocBefore: "bytes.Repeat([]byte{0}, x)", - DocAfter: "make([]byte, x)", - Rules: []ir.Rule{ - { - Line: 800, - SyntaxPatterns: []ir.PatternString{{Line: 800, Value: "bytes.Repeat([]byte{0}, $x)"}}, - ReportTemplate: "avoid bytes.Repeat([]byte{0}, $x); consider using make([]byte, $x) instead", - SuggestTemplate: "make([]byte, $x)", - }, - { - Line: 805, - SyntaxPatterns: []ir.PatternString{{Line: 805, Value: "bytes.Repeat([]byte{$x}, $n)"}}, - ReportTemplate: "avoid bytes.Repeat with a const 0; use make([]byte, $n) instead", - SuggestTemplate: "make([]byte, $n)", - WhereExpr: ir.FilterExpr{ - Line: 806, - Op: ir.FilterAndOp, - Src: "m[\"x\"].Const && m[\"x\"].Value.Int() == 0", - Args: []ir.FilterExpr{ - { - Line: 806, - Op: ir.FilterVarConstOp, - Src: "m[\"x\"].Const", - Value: "x", - }, - { - Line: 806, - Op: ir.FilterEqOp, - Src: "m[\"x\"].Value.Int() == 0", - Args: []ir.FilterExpr{ - { - Line: 806, - Op: ir.FilterVarValueIntOp, - Src: "m[\"x\"].Value.Int()", - Value: "x", - }, - { - Line: 806, - Op: ir.FilterIntOp, - Src: "0", - Value: int64(0), - }, - }, - }, - }, - }, - }, - }, - }, - }, -} - diff --git a/vendor/github.com/go-critic/go-critic/checkers/singleCaseSwitch_checker.go b/vendor/github.com/go-critic/go-critic/checkers/singleCaseSwitch_checker.go deleted file mode 100644 index a1a399fdaa..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/singleCaseSwitch_checker.go +++ /dev/null @@ -1,85 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/token" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" - - "golang.org/x/tools/go/ast/astutil" -) - -func init() { - var info linter.CheckerInfo - info.Name = "singleCaseSwitch" - info.Tags = []string{linter.StyleTag} - info.Summary = "Detects switch statements that could be better written as if statement" - info.Before = ` -switch x := x.(type) { -case int: - body() -}` - info.After = ` -if x, ok := x.(int); ok { - body() -}` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForStmt(&singleCaseSwitchChecker{ctx: ctx}), nil - }) -} - -type singleCaseSwitchChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext -} - -func (c *singleCaseSwitchChecker) VisitStmt(stmt ast.Stmt) { - switch stmt := stmt.(type) { - case *ast.SwitchStmt: - c.checkSwitchStmt(stmt, stmt.Body) - case *ast.TypeSwitchStmt: - c.checkSwitchStmt(stmt, stmt.Body) - } -} - -func (c *singleCaseSwitchChecker) checkSwitchStmt(stmt ast.Stmt, body *ast.BlockStmt) { - if len(body.List) != 1 { - return - } - cc := body.List[0].(*ast.CaseClause) - if c.hasBreak(cc) { - return - } - switch { - case cc.List == nil: - c.warnDefault(stmt) - case len(cc.List) == 1: - c.warn(stmt) - } -} - -func (c *singleCaseSwitchChecker) hasBreak(stmt ast.Stmt) bool { - found := false - astutil.Apply(stmt, func(cur *astutil.Cursor) bool { - switch n := cur.Node().(type) { - case *ast.BranchStmt: - if n.Tok == token.BREAK { - found = true - } - case *ast.ForStmt, *ast.RangeStmt, *ast.SelectStmt, *ast.SwitchStmt: - return false - } - return true - }, nil) - return found -} - -func (c *singleCaseSwitchChecker) warn(stmt ast.Stmt) { - c.ctx.Warn(stmt, "should rewrite switch statement to if statement") -} - -func (c *singleCaseSwitchChecker) warnDefault(stmt ast.Stmt) { - c.ctx.Warn(stmt, "found switch with default case only") -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/sloppyReassign_checker.go b/vendor/github.com/go-critic/go-critic/checkers/sloppyReassign_checker.go deleted file mode 100644 index d83d7fd5a1..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/sloppyReassign_checker.go +++ /dev/null @@ -1,81 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/token" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" - - "github.com/go-toolsmith/astcast" - "github.com/go-toolsmith/astcopy" - "github.com/go-toolsmith/astequal" -) - -func init() { - var info linter.CheckerInfo - info.Name = "sloppyReassign" - info.Tags = []string{linter.DiagnosticTag, linter.ExperimentalTag} - info.Summary = "Detects suspicious/confusing re-assignments" - info.Before = `if err = f(); err != nil { return err }` - info.After = `if err := f(); err != nil { return err }` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForStmt(&sloppyReassignChecker{ctx: ctx}), nil - }) -} - -type sloppyReassignChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext -} - -func (c *sloppyReassignChecker) VisitStmt(stmt ast.Stmt) { - // Right now only check assignments in if statements init. - ifStmt := astcast.ToIfStmt(stmt) - assign := astcast.ToAssignStmt(ifStmt.Init) - if assign.Tok != token.ASSIGN { - return - } - - // TODO(quasilyte): is handling of multi-value assignments worthwhile? - if len(assign.Lhs) != 1 || len(assign.Rhs) != 1 { - return - } - - // TODO(quasilyte): handle not only the simplest, return-only case. - body := ifStmt.Body.List - if len(body) != 1 { - return - } - - // Variable that is being re-assigned. - reAssigned := astcast.ToIdent(assign.Lhs[0]) - if reAssigned.Name == "" { - return - } - - // TODO(quasilyte): handle not only nil comparisons. - eqToNil := &ast.BinaryExpr{ - Op: token.NEQ, - X: reAssigned, - Y: &ast.Ident{Name: "nil"}, - } - if !astequal.Expr(ifStmt.Cond, eqToNil) { - return - } - - results := astcast.ToReturnStmt(body[0]).Results - for _, res := range results { - if astequal.Expr(reAssigned, res) { - c.warnAssignToDefine(assign, reAssigned.Name) - break - } - } -} - -func (c *sloppyReassignChecker) warnAssignToDefine(assign *ast.AssignStmt, name string) { - suggest := astcopy.AssignStmt(assign) - suggest.Tok = token.DEFINE - c.ctx.Warn(assign, "re-assignment to `%s` can be replaced with `%s`", name, suggest) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/sloppyTypeAssert_checker.go b/vendor/github.com/go-critic/go-critic/checkers/sloppyTypeAssert_checker.go deleted file mode 100644 index 454ab78b19..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/sloppyTypeAssert_checker.go +++ /dev/null @@ -1,56 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/types" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" - - "github.com/go-toolsmith/astcast" -) - -func init() { - var info linter.CheckerInfo - info.Name = "sloppyTypeAssert" - info.Tags = []string{linter.DiagnosticTag} - info.Summary = "Detects redundant type assertions" - info.Before = ` -func f(r io.Reader) interface{} { - return r.(interface{}) -} -` - info.After = ` -func f(r io.Reader) interface{} { - return r -} -` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForExpr(&sloppyTypeAssertChecker{ctx: ctx}), nil - }) -} - -type sloppyTypeAssertChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext -} - -func (c *sloppyTypeAssertChecker) VisitExpr(expr ast.Expr) { - assert := astcast.ToTypeAssertExpr(expr) - if assert.Type == nil { - return - } - - toType := c.ctx.TypeOf(expr) - fromType := c.ctx.TypeOf(assert.X) - - if types.Identical(toType, fromType) { - c.warnIdentical(expr) - return - } -} - -func (c *sloppyTypeAssertChecker) warnIdentical(cause ast.Expr) { - c.ctx.Warn(cause, "type assertion from/to types are identical") -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/sortSlice_checker.go b/vendor/github.com/go-critic/go-critic/checkers/sortSlice_checker.go deleted file mode 100644 index 22ef3b16a7..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/sortSlice_checker.go +++ /dev/null @@ -1,136 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/token" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/checkers/internal/lintutil" - "github.com/go-critic/go-critic/linter" - - "github.com/go-toolsmith/astcast" - "github.com/go-toolsmith/astequal" - "github.com/go-toolsmith/typep" - "golang.org/x/tools/go/ast/astutil" -) - -func init() { - var info linter.CheckerInfo - info.Name = "sortSlice" - info.Tags = []string{linter.DiagnosticTag, linter.ExperimentalTag} - info.Summary = "Detects suspicious sort.Slice calls" - info.Before = `sort.Slice(xs, func(i, j) bool { return keys[i] < keys[j] })` - info.After = `sort.Slice(kv, func(i, j) bool { return kv[i].key < kv[j].key })` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForExpr(&sortSliceChecker{ctx: ctx}), nil - }) -} - -type sortSliceChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext -} - -func (c *sortSliceChecker) VisitExpr(expr ast.Expr) { - call := astcast.ToCallExpr(expr) - if len(call.Args) != 2 { - return - } - switch qualifiedName(call.Fun) { - case "sort.Slice", "sort.SliceStable": - // OK. - default: - return - } - - slice := c.unwrapSlice(call.Args[0]) - lessFunc, ok := call.Args[1].(*ast.FuncLit) - if !ok { - return - } - if !typep.SideEffectFree(c.ctx.TypesInfo, slice) { - return // Don't check unpredictable slice values - } - - ivar, jvar := c.paramIdents(lessFunc.Type) - if ivar == nil || jvar == nil { - return - } - - if len(lessFunc.Body.List) != 1 { - return - } - ret, ok := lessFunc.Body.List[0].(*ast.ReturnStmt) - if !ok { - return - } - cmp := astcast.ToBinaryExpr(astutil.Unparen(ret.Results[0])) - if !typep.SideEffectFree(c.ctx.TypesInfo, cmp) { - return - } - switch cmp.Op { - case token.LSS, token.LEQ, token.GTR, token.GEQ: - // Both cmp.X and cmp.Y are expected to be some expressions - // over the `slice` expression. In the simplest case, - // it's a `slice[i] slice[j]`. - if !c.containsSlice(cmp.X, slice) && !c.containsSlice(cmp.Y, slice) { - c.warnSlice(cmp, slice) - } - - // This one is more about the style, but can reveal potential issue - // or misprint in sorting condition. - // We give a warn if X contains indexing with `i` index and Y - // contains indexing with `j`. - if c.containsIndex(cmp.X, jvar) && c.containsIndex(cmp.Y, ivar) { - c.warnIndex(cmp, ivar, jvar) - } - } -} - -func (c *sortSliceChecker) paramIdents(e *ast.FuncType) (ivar, jvar *ast.Ident) { - // Covers both `i, j int` and `i int, j int`. - idents := make([]*ast.Ident, 0, 2) - for _, field := range e.Params.List { - idents = append(idents, field.Names...) - } - if len(idents) == 2 { - return idents[0], idents[1] - } - return nil, nil -} - -func (c *sortSliceChecker) unwrapSlice(e ast.Expr) ast.Expr { - switch e := e.(type) { - case *ast.ParenExpr: - return c.unwrapSlice(e.X) - case *ast.SliceExpr: - return e.X - default: - return e - } -} - -func (c *sortSliceChecker) containsIndex(e, index ast.Expr) bool { - return lintutil.ContainsNode(e, func(n ast.Node) bool { - indexing, ok := n.(*ast.IndexExpr) - if !ok { - return false - } - return astequal.Expr(indexing.Index, index) - }) -} - -func (c *sortSliceChecker) containsSlice(e, slice ast.Expr) bool { - return lintutil.ContainsNode(e, func(n ast.Node) bool { - return astequal.Node(n, slice) - }) -} - -func (c *sortSliceChecker) warnSlice(cause ast.Node, slice ast.Expr) { - c.ctx.Warn(cause, "cmp func must use %s slice in comparison", slice) -} - -func (c *sortSliceChecker) warnIndex(cause ast.Node, ivar, jvar *ast.Ident) { - c.ctx.Warn(cause, "unusual order of {%s,%s} params in comparison", ivar, jvar) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/sqlQuery_checker.go b/vendor/github.com/go-critic/go-critic/checkers/sqlQuery_checker.go deleted file mode 100644 index 02a2370d30..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/sqlQuery_checker.go +++ /dev/null @@ -1,175 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/types" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" - - "github.com/go-toolsmith/astcast" -) - -func init() { - var info linter.CheckerInfo - info.Name = "sqlQuery" - info.Tags = []string{linter.DiagnosticTag, linter.ExperimentalTag} - info.Summary = "Detects issue in Query() and Exec() calls" - info.Before = `_, err := db.Query("UPDATE ...")` - info.After = `_, err := db.Exec("UPDATE ...")` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForStmt(&sqlQueryChecker{ctx: ctx}), nil - }) -} - -type sqlQueryChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext -} - -func (c *sqlQueryChecker) VisitStmt(stmt ast.Stmt) { - assign := astcast.ToAssignStmt(stmt) - if len(assign.Lhs) != 2 { // Query() has 2 return values. - return - } - if len(assign.Rhs) != 1 { - return - } - - // If Query() is called, but first return value is ignored, - // there is no way to close/read the returned rows. - // This can cause a connection leak. - if id, ok := assign.Lhs[0].(*ast.Ident); ok && id.Name != "_" { - return - } - - call := astcast.ToCallExpr(assign.Rhs[0]) - funcExpr := astcast.ToSelectorExpr(call.Fun) - if !c.funcIsQuery(funcExpr) { - return - } - - if c.typeHasExecMethod(c.ctx.TypeOf(funcExpr.X)) { - c.warnAndSuggestExec(funcExpr) - } else { - c.warnRowsIgnored(funcExpr) - } -} - -func (c *sqlQueryChecker) funcIsQuery(funcExpr *ast.SelectorExpr) bool { - if funcExpr.Sel == nil { - return false - } - switch funcExpr.Sel.Name { - case "Query", "QueryContext": - // Stdlib and friends. - case "Queryx", "QueryxContext": - // sqlx. - default: - return false - } - - // To avoid false positives (unrelated types can have Query method) - // check that the 1st returned type has Row-like name. - typ, ok := c.ctx.TypeOf(funcExpr).Underlying().(*types.Signature) - if !ok || typ.Results() == nil || typ.Results().Len() != 2 { - return false - } - if !c.typeIsRowsLike(typ.Results().At(0).Type()) { - return false - } - - return true -} - -func (c *sqlQueryChecker) typeIsRowsLike(typ types.Type) bool { - switch typ := typ.(type) { - case *types.Pointer: - return c.typeIsRowsLike(typ.Elem()) - case *types.Named: - return typ.Obj().Name() == "Rows" - default: - return false - } -} - -func (c *sqlQueryChecker) funcIsExec(fn *types.Func) bool { - if fn.Name() != "Exec" { - return false - } - - // Expect exactly 2 results. - sig := fn.Type().(*types.Signature) - if sig.Results() == nil || sig.Results().Len() != 2 { - return false - } - - // Expect at least 1 param and it should be a string (query). - params := sig.Params() - if params == nil || params.Len() == 0 { - return false - } - if typ, ok := params.At(0).Type().(*types.Basic); !ok || typ.Kind() != types.String { - return false - } - - return true -} - -func (c *sqlQueryChecker) typeHasExecMethod(typ types.Type) bool { - switch typ := typ.(type) { - case *types.Struct: - for i := 0; i < typ.NumFields(); i++ { - if c.typeHasExecMethod(typ.Field(i).Type()) { - return true - } - } - case *types.Alias: - switch typ := typ.Underlying().(type) { - case *types.Interface: - return c.typeHasExecMethod(typ) - default: - // TODO(cristaloleg): is there something else to handle? - } - case *types.Interface: - for i := 0; i < typ.NumMethods(); i++ { - if c.funcIsExec(typ.Method(i)) { - return true - } - } - case *types.Pointer: - return c.typeHasExecMethod(typ.Elem()) - case *types.Named: - for i := 0; i < typ.NumMethods(); i++ { - if c.funcIsExec(typ.Method(i)) { - return true - } - } - switch ut := typ.Underlying().(type) { - case *types.Interface: - return c.typeHasExecMethod(ut) - case *types.Struct: - // Check embedded types. - for i := 0; i < ut.NumFields(); i++ { - field := ut.Field(i) - if !field.Embedded() { - continue - } - if c.typeHasExecMethod(field.Type()) { - return true - } - } - } - } - - return false -} - -func (c *sqlQueryChecker) warnAndSuggestExec(funcExpr *ast.SelectorExpr) { - c.ctx.Warn(funcExpr, "use %s.Exec() if returned result is not needed", funcExpr.X) -} - -func (c *sqlQueryChecker) warnRowsIgnored(funcExpr *ast.SelectorExpr) { - c.ctx.Warn(funcExpr, "ignoring Query() rows result may lead to a connection leak") -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/todoCommentWithoutDetail_checker.go b/vendor/github.com/go-critic/go-critic/checkers/todoCommentWithoutDetail_checker.go deleted file mode 100644 index f8e4b9b3c0..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/todoCommentWithoutDetail_checker.go +++ /dev/null @@ -1,50 +0,0 @@ -package checkers - -import ( - "go/ast" - "regexp" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" -) - -func init() { - var info linter.CheckerInfo - info.Name = "todoCommentWithoutDetail" - info.Tags = []string{linter.StyleTag, linter.OpinionatedTag, linter.ExperimentalTag} - info.Summary = "Detects TODO comments without detail/assignee" - info.Before = ` -// TODO -fiiWithCtx(nil, a, b) -` - info.After = ` -// TODO(admin): pass context.TODO() instead of nil -fiiWithCtx(nil, a, b) -` - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - visitor := &todoCommentWithoutCodeChecker{ - ctx: ctx, - regex: regexp.MustCompile(`^(//|/\*)?\s*(TODO|FIX|FIXME|BUG)\s*(\*/)?$`), - } - return astwalk.WalkerForComment(visitor), nil - }) -} - -type todoCommentWithoutCodeChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext - regex *regexp.Regexp -} - -func (c *todoCommentWithoutCodeChecker) VisitComment(cg *ast.CommentGroup) { - for _, comment := range cg.List { - if c.regex.MatchString(comment.Text) { - c.warn(cg) - break - } - } -} - -func (c *todoCommentWithoutCodeChecker) warn(cause ast.Node) { - c.ctx.Warn(cause, "may want to add detail/assignee to this TODO/FIXME/BUG comment") -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/tooManyResults_checker.go b/vendor/github.com/go-critic/go-critic/checkers/tooManyResults_checker.go deleted file mode 100644 index 57411ba249..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/tooManyResults_checker.go +++ /dev/null @@ -1,54 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/types" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" -) - -func init() { - var info linter.CheckerInfo - info.Name = "tooManyResultsChecker" - info.Tags = []string{linter.StyleTag, linter.OpinionatedTag, linter.ExperimentalTag} - info.Params = linter.CheckerParams{ - "maxResults": { - Value: 5, - Usage: "maximum number of results", - }, - } - info.Summary = "Detects function with too many results" - info.Before = `func fn() (a, b, c, d float32, _ int, _ bool)` - info.After = `func fn() (resultStruct, bool)` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - c := astwalk.WalkerForFuncDecl(&tooManyResultsChecker{ - ctx: ctx, - maxParams: info.Params.Int("maxResults"), - }) - return c, nil - }) -} - -type tooManyResultsChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext - maxParams int -} - -func (c *tooManyResultsChecker) VisitFuncDecl(decl *ast.FuncDecl) { - typ := c.ctx.TypeOf(decl.Name) - sig, ok := typ.(*types.Signature) - if !ok { - return - } - - if count := sig.Results().Len(); count > c.maxParams { - c.warn(decl) - } -} - -func (c *tooManyResultsChecker) warn(n ast.Node) { - c.ctx.Warn(n, "function has more than %d results, consider to simplify the function", c.maxParams) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/truncateCmp_checker.go b/vendor/github.com/go-critic/go-critic/checkers/truncateCmp_checker.go deleted file mode 100644 index b369025267..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/truncateCmp_checker.go +++ /dev/null @@ -1,124 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/token" - "go/types" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" - - "github.com/go-toolsmith/astcast" - "github.com/go-toolsmith/astp" -) - -func init() { - var info linter.CheckerInfo - info.Name = "truncateCmp" - info.Tags = []string{linter.DiagnosticTag, linter.ExperimentalTag} - info.Params = linter.CheckerParams{ - "skipArchDependent": { - Value: true, - Usage: "whether to skip int/uint/uintptr types", - }, - } - info.Summary = "Detects potential truncation issues when comparing ints of different sizes" - info.Before = ` -func f(x int32, y int16) bool { - return int16(x) < y -}` - info.After = ` -func f(x int32, int16) bool { - return x < int32(y) -}` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - c := &truncateCmpChecker{ctx: ctx} - c.skipArchDependent = info.Params.Bool("skipArchDependent") - return astwalk.WalkerForExpr(c), nil - }) -} - -type truncateCmpChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext - - skipArchDependent bool -} - -func (c *truncateCmpChecker) VisitExpr(expr ast.Expr) { - cmp := astcast.ToBinaryExpr(expr) - switch cmp.Op { - case token.LSS, token.GTR, token.LEQ, token.GEQ, token.EQL, token.NEQ: - if astp.IsBasicLit(cmp.X) || astp.IsBasicLit(cmp.Y) { - return // Don't bother about untyped consts - } - leftCast := c.isTruncCast(cmp.X) - rightCast := c.isTruncCast(cmp.Y) - switch { - case leftCast && rightCast: - return - case leftCast: - c.checkCmp(cmp.X, cmp.Y) - case rightCast: - c.checkCmp(cmp.Y, cmp.X) - } - default: - return - } -} - -func (c *truncateCmpChecker) isTruncCast(x ast.Expr) bool { - switch astcast.ToIdent(astcast.ToCallExpr(x).Fun).Name { - case "int8", "int16", "int32", "uint8", "uint16", "uint32": - return true - default: - return false - } -} - -func (c *truncateCmpChecker) checkCmp(cmpX, cmpY ast.Expr) { - // Check if we have a cast to a type that can truncate. - xcast := astcast.ToCallExpr(cmpX) - if len(xcast.Args) != 1 { - return // Just in case of the shadowed builtin - } - - x := xcast.Args[0] - y := cmpY - - // Check that both x and y are signed or unsigned int-typed. - xtyp, ok := c.ctx.TypeOf(x).Underlying().(*types.Basic) - if !ok || xtyp.Info()&types.IsInteger == 0 { - return - } - ytyp, ok := c.ctx.TypeOf(y).Underlying().(*types.Basic) - if !ok || xtyp.Info() != ytyp.Info() { - return - } - - xsize, ok := c.ctx.SizeOf(xtyp) - if !ok { - return - } - ysize, ok := c.ctx.SizeOf(ytyp) - if !ok { - return - } - if xsize <= ysize { - return - } - - if c.skipArchDependent { - switch xtyp.Kind() { - case types.Int, types.Uint, types.Uintptr: - return - } - } - - c.warn(xcast, xsize*8, ysize*8, xtyp.String()) -} - -func (c *truncateCmpChecker) warn(cause ast.Expr, xsize, ysize int64, suggest string) { - c.ctx.Warn(cause, "truncation in comparison %d->%d bit; cast the other operand to %s instead", xsize, ysize, suggest) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/typeAssertChain_checker.go b/vendor/github.com/go-critic/go-critic/checkers/typeAssertChain_checker.go deleted file mode 100644 index e0d20fd4c5..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/typeAssertChain_checker.go +++ /dev/null @@ -1,133 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/token" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/checkers/internal/lintutil" - "github.com/go-critic/go-critic/linter" - - "github.com/go-toolsmith/astcast" - "github.com/go-toolsmith/astequal" - "github.com/go-toolsmith/astp" -) - -func init() { - var info linter.CheckerInfo - info.Name = "typeAssertChain" - info.Tags = []string{linter.StyleTag, linter.ExperimentalTag} - info.Summary = "Detects repeated type assertions and suggests to replace them with type switch statement" - info.Before = ` -if x, ok := v.(T1); ok { - // Code A, uses x. -} else if x, ok := v.(T2); ok { - // Code B, uses x. -} else if x, ok := v.(T3); ok { - // Code C, uses x. -}` - info.After = ` -switch x := v.(T1) { -case cond1: - // Code A, uses x. -case cond2: - // Code B, uses x. -default: - // Code C, uses x. -}` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForStmt(&typeAssertChainChecker{ctx: ctx}), nil - }) -} - -type typeAssertChainChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext - - cause *ast.IfStmt - visited map[*ast.IfStmt]bool - typeSet lintutil.AstSet -} - -func (c *typeAssertChainChecker) EnterFunc(fn *ast.FuncDecl) bool { - if fn.Body == nil { - return false - } - c.visited = make(map[*ast.IfStmt]bool) - return true -} - -func (c *typeAssertChainChecker) VisitStmt(stmt ast.Stmt) { - ifstmt, ok := stmt.(*ast.IfStmt) - if !ok || c.visited[ifstmt] || ifstmt.Init == nil { - return - } - assertion := c.getTypeAssert(ifstmt) - if assertion == nil { - return - } - c.cause = ifstmt - c.checkIfStmt(ifstmt, assertion) -} - -func (c *typeAssertChainChecker) getTypeAssert(ifstmt *ast.IfStmt) *ast.TypeAssertExpr { - assign := astcast.ToAssignStmt(ifstmt.Init) - if len(assign.Lhs) != 2 || len(assign.Rhs) != 1 { - return nil - } - if !astp.IsIdent(assign.Lhs[0]) || assign.Tok != token.DEFINE { - return nil - } - if !astequal.Expr(assign.Lhs[1], ifstmt.Cond) { - return nil - } - - assertion, ok := assign.Rhs[0].(*ast.TypeAssertExpr) - if !ok { - return nil - } - return assertion -} - -func (c *typeAssertChainChecker) checkIfStmt(stmt *ast.IfStmt, assertion *ast.TypeAssertExpr) { - if c.countTypeAssertions(stmt, assertion) >= 2 { - c.warn() - } -} - -func (c *typeAssertChainChecker) countTypeAssertions(stmt *ast.IfStmt, assertion *ast.TypeAssertExpr) int { - c.typeSet.Clear() - - count := 1 - x := assertion.X - c.typeSet.Insert(assertion.Type) - for { - e, ok := stmt.Else.(*ast.IfStmt) - if !ok { - return count - } - assertion = c.getTypeAssert(e) - if assertion == nil { - return count - } - if !c.typeSet.Insert(assertion.Type) { - // Asserted type is duplicated. - // Type switch does not permit duplicate cases, - // so give up. - return 0 - } - if !astequal.Expr(x, assertion.X) { - // Mixed type asserting chain. - // Can't be easily translated to a type switch. - return 0 - } - stmt = e - count++ - c.visited[e] = true - } -} - -func (c *typeAssertChainChecker) warn() { - c.ctx.Warn(c.cause, "rewrite if-else to type switch statement") -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/typeDefFirst_checker.go b/vendor/github.com/go-critic/go-critic/checkers/typeDefFirst_checker.go deleted file mode 100644 index 11381c4014..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/typeDefFirst_checker.go +++ /dev/null @@ -1,92 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/token" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" -) - -func init() { - var info linter.CheckerInfo - info.Name = "typeDefFirst" - info.Tags = []string{linter.StyleTag, linter.ExperimentalTag} - info.Summary = "Detects method declarations preceding the type definition itself" - info.Before = ` -func (r rec) Method() {} -type rec struct{} -` - info.After = ` -type rec struct{} -func (r rec) Method() {} -` - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return &typeDefFirstChecker{ - ctx: ctx, - }, nil - }) -} - -type typeDefFirstChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext - trackedTypes map[string]bool -} - -func (c *typeDefFirstChecker) WalkFile(f *ast.File) { - if len(f.Decls) == 0 { - return - } - - c.trackedTypes = make(map[string]bool) - for _, decl := range f.Decls { - c.walkDecl(decl) - } -} - -func (c *typeDefFirstChecker) walkDecl(decl ast.Decl) { - switch decl := decl.(type) { - case *ast.FuncDecl: - if decl.Recv == nil { - return - } - receiver := decl.Recv.List[0] - typeName := c.receiverType(receiver.Type) - c.trackedTypes[typeName] = true - - case *ast.GenDecl: - if decl.Tok != token.TYPE { - return - } - for _, spec := range decl.Specs { - spec, ok := spec.(*ast.TypeSpec) - if !ok { - return - } - typeName := spec.Name.Name - if val, ok := c.trackedTypes[typeName]; ok && val { - c.warn(decl, typeName) - } - } - } -} - -func (c *typeDefFirstChecker) receiverType(e ast.Expr) string { - switch e := e.(type) { - case *ast.StarExpr: - return c.receiverType(e.X) - case *ast.Ident: - return e.Name - case *ast.IndexExpr: - return c.receiverType(e.X) - case *ast.IndexListExpr: - return c.receiverType(e.X) - default: - panic("unreachable") - } -} - -func (c *typeDefFirstChecker) warn(cause ast.Node, typeName string) { - c.ctx.Warn(cause, "definition of type '%s' should appear before its methods", typeName) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/typeSwitchVar_checker.go b/vendor/github.com/go-critic/go-critic/checkers/typeSwitchVar_checker.go deleted file mode 100644 index 4b27b17928..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/typeSwitchVar_checker.go +++ /dev/null @@ -1,98 +0,0 @@ -package checkers - -import ( - "go/ast" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/checkers/internal/lintutil" - "github.com/go-critic/go-critic/linter" - - "github.com/go-toolsmith/astequal" - "github.com/go-toolsmith/astp" -) - -func init() { - var info linter.CheckerInfo - info.Name = "typeSwitchVar" - info.Tags = []string{linter.StyleTag} - info.Summary = "Detects type switches that can benefit from type guard clause with variable" - info.Before = ` -switch v.(type) { -case int: - return v.(int) -case point: - return v.(point).x + v.(point).y -default: - return 0 -}` - info.After = ` -switch v := v.(type) { -case int: - return v -case point: - return v.x + v.y -default: - return 0 -}` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForStmt(&typeSwitchVarChecker{ctx: ctx}), nil - }) -} - -type typeSwitchVarChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext - count int -} - -func (c *typeSwitchVarChecker) VisitStmt(stmt ast.Stmt) { - if stmt, ok := stmt.(*ast.TypeSwitchStmt); ok { - c.count = 0 - c.checkTypeSwitch(stmt) - } -} - -func (c *typeSwitchVarChecker) checkTypeSwitch(root *ast.TypeSwitchStmt) { - if astp.IsAssignStmt(root.Assign) { - return // Already with type guard - } - // Must be a *ast.ExprStmt then. - expr := root.Assign.(*ast.ExprStmt).X.(*ast.TypeAssertExpr).X - object := c.ctx.TypesInfo.ObjectOf(identOf(expr)) - if object == nil { - return // Give up: can't handle shadowing without object - } - - for _, clause := range root.Body.List { - clause := clause.(*ast.CaseClause) - // Multiple types in a list mean that assert.X will have - // a type of interface{} inside clause body. - // We are looking for precise type case. - if len(clause.List) != 1 { - continue - } - // Create artificial node just for matching. - assert1 := ast.TypeAssertExpr{X: expr, Type: clause.List[0]} - for _, stmt := range clause.Body { - assert2 := lintutil.FindNode(stmt, nil, func(x ast.Node) bool { - return astequal.Node(&assert1, x) - }) - if object == c.ctx.TypesInfo.ObjectOf(identOf(assert2)) { - c.count++ - break - } - } - } - if c.count > 0 { - c.warn(root) - } -} - -func (c *typeSwitchVarChecker) warn(n ast.Node) { - msg := "case" - if c.count > 1 { - msg = "cases" - } - c.ctx.Warn(n, "%d "+msg+" can benefit from type switch with assignment", c.count) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/typeUnparen_checker.go b/vendor/github.com/go-critic/go-critic/checkers/typeUnparen_checker.go deleted file mode 100644 index e2e225ebf2..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/typeUnparen_checker.go +++ /dev/null @@ -1,96 +0,0 @@ -package checkers - -import ( - "go/ast" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" - - "github.com/go-toolsmith/astcopy" - "github.com/go-toolsmith/astequal" -) - -func init() { - var info linter.CheckerInfo - info.Name = "typeUnparen" - info.Tags = []string{linter.StyleTag, linter.OpinionatedTag} - info.Summary = "Detects unneeded parenthesis inside type expressions and suggests to remove them" - info.Before = `type foo [](func([](func())))` - info.After = `type foo []func([]func())` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForTypeExpr(&typeUnparenChecker{ctx: ctx}, ctx.TypesInfo), nil - }) -} - -type typeUnparenChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext -} - -func (c *typeUnparenChecker) VisitTypeExpr(e ast.Expr) { - switch e := e.(type) { - case *ast.ParenExpr: - switch e.X.(type) { - case *ast.StructType: - c.ctx.Warn(e, "could simplify (struct{...}) to struct{...}") - case *ast.InterfaceType: - c.ctx.Warn(e, "could simplify (interface{...}) to interface{...}") - default: - c.checkType(e) - } - case *ast.StructType, *ast.InterfaceType: - // Only nested fields are to be reported. - default: - c.checkType(e) - } -} - -func (c *typeUnparenChecker) checkType(e ast.Expr) { - noParens := c.removeRedundantParens(astcopy.Expr(e)) - if !astequal.Expr(e, noParens) { - c.warn(e, noParens) - } - c.SkipChilds = true -} - -func (c *typeUnparenChecker) removeRedundantParens(e ast.Expr) ast.Expr { - switch e := e.(type) { - case *ast.ParenExpr: - return c.removeRedundantParens(e.X) - case *ast.ArrayType: - e.Elt = c.removeRedundantParens(e.Elt) - case *ast.StarExpr: - e.X = c.removeRedundantParens(e.X) - case *ast.TypeAssertExpr: - e.Type = c.removeRedundantParens(e.Type) - case *ast.FuncType: - for _, field := range e.Params.List { - field.Type = c.removeRedundantParens(field.Type) - } - if e.Results != nil { - for _, field := range e.Results.List { - field.Type = c.removeRedundantParens(field.Type) - } - } - case *ast.MapType: - e.Key = c.removeRedundantParens(e.Key) - e.Value = c.removeRedundantParens(e.Value) - case *ast.ChanType: - if valueWithParens, ok := e.Value.(*ast.ParenExpr); ok { - if nestedChan, ok := valueWithParens.X.(*ast.ChanType); ok { - const anyDir = ast.SEND | ast.RECV - if nestedChan.Dir != anyDir || e.Dir != anyDir { - valueWithParens.X = c.removeRedundantParens(valueWithParens.X) - return e - } - } - } - e.Value = c.removeRedundantParens(e.Value) - } - return e -} - -func (c *typeUnparenChecker) warn(cause, noParens ast.Expr) { - c.ctx.Warn(cause, "could simplify %s to %s", cause, noParens) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/underef_checker.go b/vendor/github.com/go-critic/go-critic/checkers/underef_checker.go deleted file mode 100644 index 0ce2c89ba7..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/underef_checker.go +++ /dev/null @@ -1,128 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/types" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" - - "github.com/go-toolsmith/astcast" - "github.com/go-toolsmith/astp" -) - -func init() { - var info linter.CheckerInfo - info.Name = "underef" - info.Tags = []string{linter.StyleTag} - info.Params = linter.CheckerParams{ - "skipRecvDeref": { - Value: true, - Usage: "whether to skip (*x).method() calls where x is a pointer receiver", - }, - } - info.Summary = "Detects dereference expressions that can be omitted" - info.Before = ` -(*k).field = 5 -v := (*a)[5] // only if a is array` - info.After = ` -k.field = 5 -v := a[5]` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - c := &underefChecker{ctx: ctx} - c.skipRecvDeref = info.Params.Bool("skipRecvDeref") - return astwalk.WalkerForExpr(c), nil - }) -} - -type underefChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext - - skipRecvDeref bool -} - -func (c *underefChecker) VisitExpr(expr ast.Expr) { - switch n := expr.(type) { - case *ast.SelectorExpr: - expr := astcast.ToParenExpr(n.X) - if c.skipRecvDeref && c.isPtrRecvMethodCall(n.Sel) { - return - } - - if expr, ok := expr.X.(*ast.StarExpr); ok { - if c.checkStarExpr(expr) { - c.warnSelect(n) - } - } - case *ast.IndexExpr: - expr := astcast.ToParenExpr(n.X) - if expr, ok := expr.X.(*ast.StarExpr); ok { - if !c.checkStarExpr(expr) { - return - } - if c.checkArray(expr) { - c.warnArray(n) - } - } - } -} - -func (c *underefChecker) isPtrRecvMethodCall(fn *ast.Ident) bool { - typ, ok := c.ctx.TypeOf(fn).(*types.Signature) - if ok && typ != nil && typ.Recv() != nil { - _, ok := typ.Recv().Type().(*types.Pointer) - return ok - } - return false -} - -func (c *underefChecker) underef(x *ast.ParenExpr) ast.Expr { - // If there is only 1 deref, can remove parenthesis, - // otherwise can remove StarExpr only. - dereferenced := x.X.(*ast.StarExpr).X - if astp.IsStarExpr(dereferenced) { - return &ast.ParenExpr{X: dereferenced} - } - return dereferenced -} - -func (c *underefChecker) warnSelect(expr *ast.SelectorExpr) { - // TODO: add () to function output. - c.ctx.Warn(expr, "could simplify %s to %s.%s", - expr, - c.underef(expr.X.(*ast.ParenExpr)), - expr.Sel.Name) -} - -func (c *underefChecker) warnArray(expr *ast.IndexExpr) { - c.ctx.Warn(expr, "could simplify %s to %s[%s]", - expr, - c.underef(expr.X.(*ast.ParenExpr)), - expr.Index) -} - -// checkStarExpr checks if ast.StarExpr could be simplified. -func (c *underefChecker) checkStarExpr(expr *ast.StarExpr) bool { - typ, ok := c.ctx.TypeOf(expr.X).Underlying().(*types.Pointer) - if !ok { - return false - } - - switch typ.Elem().Underlying().(type) { - case *types.Pointer, *types.Interface: - return false - default: - return true - } -} - -func (c *underefChecker) checkArray(expr *ast.StarExpr) bool { - typ, ok := c.ctx.TypeOf(expr.X).(*types.Pointer) - if !ok { - return false - } - _, ok = typ.Elem().(*types.Array) - return ok -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/unlabelStmt_checker.go b/vendor/github.com/go-critic/go-critic/checkers/unlabelStmt_checker.go deleted file mode 100644 index d0e83f3c2e..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/unlabelStmt_checker.go +++ /dev/null @@ -1,181 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/token" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/checkers/internal/lintutil" - "github.com/go-critic/go-critic/linter" -) - -func init() { - var info linter.CheckerInfo - info.Name = "unlabelStmt" - info.Tags = []string{linter.StyleTag, linter.ExperimentalTag} - info.Summary = "Detects redundant statement labels" - info.Before = ` -derp: -for x := range xs { - if x == 0 { - break derp - } -}` - info.After = ` -for x := range xs { - if x == 0 { - break - } -}` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForStmt(&unlabelStmtChecker{ctx: ctx}), nil - }) -} - -type unlabelStmtChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext -} - -func (c *unlabelStmtChecker) EnterFunc(fn *ast.FuncDecl) bool { - if fn.Body == nil { - return false - } - // TODO(quasilyte): should not do additional traversal here. - // For now, skip all functions that contain goto statement. - return !lintutil.ContainsNode(fn.Body, func(n ast.Node) bool { - br, ok := n.(*ast.BranchStmt) - return ok && br.Tok == token.GOTO - }) -} - -func (c *unlabelStmtChecker) VisitStmt(stmt ast.Stmt) { - labeled, ok := stmt.(*ast.LabeledStmt) - if !ok || !c.canBreakFrom(labeled.Stmt) { - return - } - - // We have a labeled statement from that have labeled continue/break. - // This is an invariant, since unused label is a compile-time error - // and we're currently skipping functions containing goto. - // - // Also note that Go labels are function-scoped and there - // can be no re-definitions. This means that we don't - // need to care about label shadowing or things like that. - // - // The task is to find cases where labeled branch (continue/break) - // is redundant and can be re-written, decreasing the label usages - // and potentially leading to its redundancy, - // or finding the redundant labels right away. - - name := labeled.Label.Name - - // Simplest case that can prove that label is redundant. - // - // If labeled branch is somewhere inside the statement block itself - // and none of the nested break'able statements refer to that label, - // the label can be removed. - matchUsage := func(n ast.Node) bool { - return c.canBreakFrom(n) && c.usesLabel(c.blockStmtOf(n), name) - } - if !lintutil.ContainsNode(c.blockStmtOf(labeled.Stmt), matchUsage) { - c.warnRedundant(labeled) - return - } - - // Only for loops: if last stmt in list is a loop - // that contains labeled "continue" to the outer loop label, - // it can be refactored to use "break" instead. - // Exceptions: select statements with a labeled "continue" are ignored. - if c.isLoop(labeled.Stmt) { - body := c.blockStmtOf(labeled.Stmt) - if len(body.List) == 0 { - return - } - last := body.List[len(body.List)-1] - if !c.isLoop(last) { - return - } - br := lintutil.FindNode(c.blockStmtOf(last), - func(n ast.Node) bool { - switch n.(type) { - case *ast.SelectStmt: - return false - default: - return true - } - }, - func(n ast.Node) bool { - br, ok := n.(*ast.BranchStmt) - return ok && br.Label != nil && - br.Label.Name == name && br.Tok == token.CONTINUE - }) - - if br != nil { - c.warnLabeledContinue(br, name) - } - } -} - -// isLoop reports whether n is a loop of some kind. -// In other words, it tells whether n body can contain "continue" -// associated with n. -func (c *unlabelStmtChecker) isLoop(n ast.Node) bool { - switch n.(type) { - case *ast.ForStmt, *ast.RangeStmt: - return true - default: - return false - } -} - -// canBreakFrom reports whether it is possible to "break" or "continue" from n body. -func (c *unlabelStmtChecker) canBreakFrom(n ast.Node) bool { - switch n.(type) { - case *ast.RangeStmt, *ast.ForStmt, *ast.SwitchStmt, *ast.TypeSwitchStmt, *ast.SelectStmt: - return true - default: - return false - } -} - -// blockStmtOf returns body of specified node. -// -// TODO(quasilyte): handle other statements and see if it can be useful -// in other checkers. -func (c *unlabelStmtChecker) blockStmtOf(n ast.Node) *ast.BlockStmt { - switch n := n.(type) { - case *ast.RangeStmt: - return n.Body - case *ast.ForStmt: - return n.Body - case *ast.SwitchStmt: - return n.Body - case *ast.TypeSwitchStmt: - return n.Body - case *ast.SelectStmt: - return n.Body - - default: - return nil - } -} - -// usesLabel reports whether n contains a usage of label. -func (c *unlabelStmtChecker) usesLabel(n *ast.BlockStmt, label string) bool { - return lintutil.ContainsNode(n, func(n ast.Node) bool { - branch, ok := n.(*ast.BranchStmt) - return ok && branch.Label != nil && - branch.Label.Name == label && - (branch.Tok == token.CONTINUE || branch.Tok == token.BREAK) - }) -} - -func (c *unlabelStmtChecker) warnRedundant(cause *ast.LabeledStmt) { - c.ctx.Warn(cause, "label %s is redundant", cause.Label) -} - -func (c *unlabelStmtChecker) warnLabeledContinue(cause ast.Node, label string) { - c.ctx.Warn(cause, "change `continue %s` to `break`", label) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/unlambda_checker.go b/vendor/github.com/go-critic/go-critic/checkers/unlambda_checker.go deleted file mode 100644 index 0401bf5d37..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/unlambda_checker.go +++ /dev/null @@ -1,118 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/token" - "go/types" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/checkers/internal/lintutil" - "github.com/go-critic/go-critic/linter" - - "github.com/go-toolsmith/astcast" - "github.com/go-toolsmith/astequal" - "github.com/go-toolsmith/typep" -) - -func init() { - var info linter.CheckerInfo - info.Name = "unlambda" - info.Tags = []string{linter.StyleTag} - info.Summary = "Detects function literals that can be simplified" - info.Before = `func(x int) int { return fn(x) }` - info.After = `fn` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForExpr(&unlambdaChecker{ctx: ctx}), nil - }) -} - -type unlambdaChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext -} - -func (c *unlambdaChecker) VisitExpr(x ast.Expr) { - fn, ok := x.(*ast.FuncLit) - if !ok || len(fn.Body.List) != 1 { - return - } - - ret, ok := fn.Body.List[0].(*ast.ReturnStmt) - if !ok || len(ret.Results) != 1 { - return - } - - result := astcast.ToCallExpr(ret.Results[0]) - callable := qualifiedName(result.Fun) - if callable == "" { - return // Skip tricky cases; only handle simple calls - } - if isBuiltin(callable) { - return // See #762 - } - hasVars := lintutil.ContainsNode(result.Fun, func(n ast.Node) bool { - id, ok := n.(*ast.Ident) - if !ok { - return false - } - obj, ok := c.ctx.TypesInfo.ObjectOf(id).(*types.Var) - if !ok { - return false - } - // Permit only non-pointer struct method values. - return !typep.IsStruct(obj.Type().Underlying()) - }) - if hasVars { - return // See #888 #1007 - } - - fnType := c.ctx.TypeOf(fn) - resultType := c.ctx.TypeOf(result.Fun) - if !types.Identical(fnType, resultType) { - return - } - // Now check that all arguments match the parameters. - n := 0 - for _, params := range fn.Type.Params.List { - if _, ok := params.Type.(*ast.Ellipsis); ok { - if result.Ellipsis == token.NoPos { - return - } - n++ - continue - } - - for _, id := range params.Names { - if !astequal.Expr(id, result.Args[n]) { - return - } - n++ - } - } - - if c.lenArgs(result.Args) == n { - c.warn(fn, callable) - } -} - -func (c *unlambdaChecker) warn(cause ast.Node, suggestion string) { - c.ctx.Warn(cause, "replace `%s` with `%s`", cause, suggestion) -} - -func (c *unlambdaChecker) lenArgs(args []ast.Expr) int { - lenArgs := len(args) - - for _, arg := range args { - callExp, ok := arg.(*ast.CallExpr) - if !ok { - continue - } - - // Don't count function call. only args. - lenArgs-- - lenArgs += c.lenArgs(callExp.Args) - } - - return lenArgs -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/unnamedResult_checker.go b/vendor/github.com/go-critic/go-critic/checkers/unnamedResult_checker.go deleted file mode 100644 index 0d40addf75..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/unnamedResult_checker.go +++ /dev/null @@ -1,103 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/types" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" -) - -func init() { - var info linter.CheckerInfo - info.Name = "unnamedResult" - info.Tags = []string{linter.StyleTag, linter.OpinionatedTag, linter.ExperimentalTag} - info.Params = linter.CheckerParams{ - "checkExported": { - Value: false, - Usage: "whether to check exported functions", - }, - } - info.Summary = "Detects unnamed results that may benefit from names" - info.Before = `func f() (float64, float64)` - info.After = `func f() (x, y float64)` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - c := &unnamedResultChecker{ctx: ctx} - c.checkExported = info.Params.Bool("checkExported") - return astwalk.WalkerForFuncDecl(c), nil - }) -} - -type unnamedResultChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext - - checkExported bool -} - -func (c *unnamedResultChecker) VisitFuncDecl(decl *ast.FuncDecl) { - if c.checkExported && !ast.IsExported(decl.Name.Name) { - return - } - results := decl.Type.Results - switch { - case results == nil: - return // Function has no results - case len(results.List) != 0 && results.List[0].Names != nil: - return // Skip named results - } - - typeName := func(x ast.Expr) string { return c.typeName(c.ctx.TypeOf(x)) } - isError := func(x ast.Expr) bool { return qualifiedName(x) == "error" } - isBool := func(x ast.Expr) bool { return qualifiedName(x) == "bool" } - - // Main difference with case of len=2 is that we permit any - // typ1 as long as second type is either error or bool. - if results.NumFields() == 2 { - typ1, typ2 := results.List[0].Type, results.List[1].Type - name1, name2 := typeName(typ1), typeName(typ2) - cond := (name1 != name2 && name2 != "") || - (!isError(typ1) && isError(typ2)) || - (!isBool(typ1) && isBool(typ2)) - if !cond { - c.warn(decl) - } - return - } - - seen := make(map[string]bool, len(results.List)) - for i := range results.List { - typ := results.List[i].Type - name := typeName(typ) - isLast := i == len(results.List)-1 - - cond := !seen[name] || - (isLast && (isError(typ) || isBool(typ))) - if !cond { - c.warn(decl) - return - } - - seen[name] = true - } -} - -func (c *unnamedResultChecker) typeName(typ types.Type) string { - switch typ := typ.(type) { - case *types.Array: - return c.typeName(typ.Elem()) - case *types.Pointer: - return c.typeName(typ.Elem()) - case *types.Slice: - return c.typeName(typ.Elem()) - case *types.Named: - return typ.Obj().Name() - default: - return "" - } -} - -func (c *unnamedResultChecker) warn(n ast.Node) { - c.ctx.Warn(n, "consider giving a name to these results") -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/unnecessaryBlock_checker.go b/vendor/github.com/go-critic/go-critic/checkers/unnecessaryBlock_checker.go deleted file mode 100644 index b577ff4219..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/unnecessaryBlock_checker.go +++ /dev/null @@ -1,78 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/token" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" - - "github.com/go-toolsmith/astp" -) - -func init() { - var info linter.CheckerInfo - info.Name = "unnecessaryBlock" - info.Tags = []string{linter.StyleTag, linter.OpinionatedTag, linter.ExperimentalTag} - info.Summary = "Detects unnecessary braced statement blocks" - info.Before = ` -x := 1 -{ - print(x) -}` - info.After = ` -x := 1 -print(x)` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForStmtList(&unnecessaryBlockChecker{ctx: ctx}), nil - }) -} - -type unnecessaryBlockChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext -} - -func (c *unnecessaryBlockChecker) VisitStmtList(x ast.Node, statements []ast.Stmt) { - // Using StmtListVisitor instead of StmtVisitor makes it easier to avoid - // false positives on IfStmt, RangeStmt, ForStmt and alike. - // We only inspect BlockStmt inside statement lists, so this method is not - // called for IfStmt itself, for example. - - if (astp.IsCaseClause(x) || astp.IsCommClause(x)) && len(statements) == 1 { - if _, ok := statements[0].(*ast.BlockStmt); ok { - c.ctx.Warn(statements[0], "case statement doesn't require a block statement") - return - } - } - - for _, stmt := range statements { - stmt, ok := stmt.(*ast.BlockStmt) - if ok && !c.hasDefinitions(stmt) { - c.warn(stmt) - } - } -} - -func (c *unnecessaryBlockChecker) hasDefinitions(stmt *ast.BlockStmt) bool { - for _, bs := range stmt.List { - switch stmt := bs.(type) { - case *ast.AssignStmt: - if stmt.Tok == token.DEFINE { - return true - } - case *ast.DeclStmt: - decl := stmt.Decl.(*ast.GenDecl) - if len(decl.Specs) != 0 { - return true - } - } - } - - return false -} - -func (c *unnecessaryBlockChecker) warn(expr ast.Stmt) { - c.ctx.Warn(expr, "block doesn't have definitions, can be simply deleted") -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/unnecessaryDefer_checker.go b/vendor/github.com/go-critic/go-critic/checkers/unnecessaryDefer_checker.go deleted file mode 100644 index 4c1ed41f6f..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/unnecessaryDefer_checker.go +++ /dev/null @@ -1,112 +0,0 @@ -package checkers - -import ( - "go/ast" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" - - "github.com/go-toolsmith/astfmt" -) - -func init() { - var info linter.CheckerInfo - info.Name = "unnecessaryDefer" - info.Tags = []string{linter.DiagnosticTag, linter.ExperimentalTag} - info.Summary = "Detects redundantly deferred calls" - info.Before = ` -func() { - defer os.Remove(filename) -}` - info.After = ` -func() { - os.Remove(filename) -}` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForFuncDecl(&unnecessaryDeferChecker{ctx: ctx}), nil - }) -} - -type unnecessaryDeferChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext - isFunc bool -} - -// Visit implements the ast.Visitor. This visitor keeps track of the block -// statement belongs to a function or any other block. If the block is not a -// function and ends with a defer statement that should be OK since it's -// deferring the outer function. -func (c *unnecessaryDeferChecker) Visit(node ast.Node) ast.Visitor { - switch n := node.(type) { - case *ast.FuncDecl, *ast.FuncLit: - c.isFunc = true - case *ast.BlockStmt: - c.checkDeferBeforeReturn(n) - default: - c.isFunc = false - } - - return c -} - -func (c *unnecessaryDeferChecker) VisitFuncDecl(funcDecl *ast.FuncDecl) { - // We always start as a function (*ast.FuncDecl.Body passed) - c.isFunc = true - - ast.Walk(c, funcDecl.Body) -} - -func (c *unnecessaryDeferChecker) checkDeferBeforeReturn(funcDecl *ast.BlockStmt) { - // Check if we have an explicit return or if it's just the end of the scope. - explicitReturn := false - retIndex := len(funcDecl.List) - for i, stmt := range funcDecl.List { - retStmt, ok := stmt.(*ast.ReturnStmt) - if !ok { - continue - } - explicitReturn = true - if !c.isTrivialReturn(retStmt) { - continue - } - retIndex = i - break - } - if retIndex == 0 { - return - } - - if deferStmt, ok := funcDecl.List[retIndex-1].(*ast.DeferStmt); ok { - // If the block is a function and ending with return or if we have an - // explicit return in any other block we should warn about - // unnecessary defer. - if c.isFunc || explicitReturn { - c.warn(deferStmt) - } - } -} - -func (c *unnecessaryDeferChecker) isTrivialReturn(ret *ast.ReturnStmt) bool { - for _, e := range ret.Results { - if !c.isConstExpr(e) { - return false - } - } - return true -} - -func (c *unnecessaryDeferChecker) isConstExpr(e ast.Expr) bool { - return c.ctx.TypesInfo.Types[e].Value != nil -} - -func (c *unnecessaryDeferChecker) warn(deferStmt *ast.DeferStmt) { - s := astfmt.Sprint(deferStmt) - if fnlit, ok := deferStmt.Call.Fun.(*ast.FuncLit); ok { - // To avoid long and multi-line warning messages, - // collapse the function literals. - s = "defer " + astfmt.Sprint(fnlit.Type) + "{...}(...)" - } - c.ctx.Warn(deferStmt, "%s is placed just before return", s) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/utils.go b/vendor/github.com/go-critic/go-critic/checkers/utils.go deleted file mode 100644 index 5740f0d4dd..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/utils.go +++ /dev/null @@ -1,312 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/types" - "strings" - - "github.com/go-critic/go-critic/linter" -) - -// goStdlib contains `go list std` command output list. -// `internal` and `vendor` packages are excluded. -// Used to detect packages that belong to standard Go packages distribution. -var goStdlib = map[string]bool{ - "archive/tar": true, - "archive/zip": true, - "bufio": true, - "bytes": true, - "cmp": true, - "compress/bzip2": true, - "compress/flate": true, - "compress/gzip": true, - "compress/lzw": true, - "compress/zlib": true, - "container/heap": true, - "container/list": true, - "container/ring": true, - "context": true, - "crypto": true, - "crypto/aes": true, - "crypto/cipher": true, - "crypto/des": true, - "crypto/dsa": true, - "crypto/ecdh": true, - "crypto/ecdsa": true, - "crypto/ed25519": true, - "crypto/elliptic": true, - "crypto/hmac": true, - "crypto/md5": true, - "crypto/rand": true, - "crypto/rc4": true, - "crypto/rsa": true, - "crypto/sha1": true, - "crypto/sha256": true, - "crypto/sha512": true, - "crypto/subtle": true, - "crypto/tls": true, - "crypto/x509": true, - "crypto/x509/pkix": true, - "database/sql": true, - "database/sql/driver": true, - "debug/buildinfo": true, - "debug/dwarf": true, - "debug/elf": true, - "debug/gosym": true, - "debug/macho": true, - "debug/pe": true, - "debug/plan9obj": true, - "embed": true, - "encoding": true, - "encoding/ascii85": true, - "encoding/asn1": true, - "encoding/base32": true, - "encoding/base64": true, - "encoding/binary": true, - "encoding/csv": true, - "encoding/gob": true, - "encoding/hex": true, - "encoding/json": true, - "encoding/pem": true, - "encoding/xml": true, - "errors": true, - "expvar": true, - "flag": true, - "fmt": true, - "go/ast": true, - "go/build": true, - "go/build/constraint": true, - "go/constant": true, - "go/doc": true, - "go/doc/comment": true, - "go/format": true, - "go/importer": true, - "go/parser": true, - "go/printer": true, - "go/scanner": true, - "go/token": true, - "go/types": true, - "go/version": true, - "hash": true, - "hash/adler32": true, - "hash/crc32": true, - "hash/crc64": true, - "hash/fnv": true, - "hash/maphash": true, - "html": true, - "html/template": true, - "image": true, - "image/color": true, - "image/color/palette": true, - "image/draw": true, - "image/gif": true, - "image/jpeg": true, - "image/png": true, - "index/suffixarray": true, - "io": true, - "io/fs": true, - "io/ioutil": true, - "iter": true, - "log": true, - "log/slog": true, - "log/syslog": true, - "maps": true, - "math": true, - "math/big": true, - "math/bits": true, - "math/cmplx": true, - "math/rand": true, - "math/rand/v2": true, - "mime": true, - "mime/multipart": true, - "mime/quotedprintable": true, - "net": true, - "net/http": true, - "net/http/cgi": true, - "net/http/cookiejar": true, - "net/http/fcgi": true, - "net/http/httptest": true, - "net/http/httptrace": true, - "net/http/httputil": true, - "net/http/pprof": true, - "net/mail": true, - "net/netip": true, - "net/rpc": true, - "net/rpc/jsonrpc": true, - "net/smtp": true, - "net/textproto": true, - "net/url": true, - "os": true, - "os/exec": true, - "os/signal": true, - "os/user": true, - "path": true, - "path/filepath": true, - "plugin": true, - "reflect": true, - "regexp": true, - "regexp/syntax": true, - "runtime": true, - "runtime/cgo": true, - "runtime/coverage": true, - "runtime/debug": true, - "runtime/metrics": true, - "runtime/pprof": true, - "runtime/race": true, - "runtime/trace": true, - "slices": true, - "sort": true, - "strconv": true, - "strings": true, - "structs": true, - "sync": true, - "sync/atomic": true, - "syscall": true, - "testing": true, - "testing/fstest": true, - "testing/iotest": true, - "testing/quick": true, - "testing/slogtest": true, - "text/scanner": true, - "text/tabwriter": true, - "text/template": true, - "text/template/parse": true, - "time": true, - "time/tzdata": true, - "unicode": true, - "unicode/utf16": true, - "unicode/utf8": true, - "unique": true, - "unsafe": true, -} - -var goBuiltins = map[string]bool{ - // Types - "any": true, - "bool": true, - "byte": true, - "comparable": true, - "complex64": true, - "complex128": true, - "error": true, - "float32": true, - "float64": true, - "int": true, - "int8": true, - "int16": true, - "int32": true, - "int64": true, - "rune": true, - "string": true, - "uint": true, - "uint8": true, - "uint16": true, - "uint32": true, - "uint64": true, - "uintptr": true, - - // Constants - "true": true, - "false": true, - "iota": true, - - // Zero value - "nil": true, - - // Functions - "append": true, - "cap": true, - "clear": true, - "close": true, - "complex": true, - "copy": true, - "delete": true, - "imag": true, - "len": true, - "make": true, - "min": true, - "max": true, - "new": true, - "panic": true, - "print": true, - "println": true, - "real": true, - "recover": true, -} - -// isBuiltin reports whether sym belongs to a predefined identifier set. -func isBuiltin(sym string) bool { - return goBuiltins[sym] -} - -// isStdlibPkg reports whether pkg is a package from the Go standard library. -func isStdlibPkg(pkg *types.Package) bool { - return pkg != nil && goStdlib[pkg.Path()] -} - -// isExampleTestFunc reports whether FuncDecl looks like a testable example function. -func isExampleTestFunc(fn *ast.FuncDecl) bool { - return len(fn.Type.Params.List) == 0 && strings.HasPrefix(fn.Name.String(), "Example") -} - -// isUnitTestFunc reports whether FuncDecl declares testing function. -func isUnitTestFunc(ctx *linter.CheckerContext, fn *ast.FuncDecl) bool { - if !strings.HasPrefix(fn.Name.Name, "Test") { - return false - } - typ := ctx.TypesInfo.TypeOf(fn.Name) - if sig, ok := typ.(*types.Signature); ok { - return sig.Results().Len() == 0 && - sig.Params().Len() == 1 && - sig.Params().At(0).Type().String() == "*testing.T" - } - return false -} - -// qualifiedName returns called expr fully-qualified name. -// -// It works for simple identifiers like f => "f" and identifiers -// from other package like pkg.f => "pkg.f". -// -// For all unexpected expressions returns empty string. -func qualifiedName(x ast.Expr) string { - switch x := x.(type) { - case *ast.SelectorExpr: - pkg, ok := x.X.(*ast.Ident) - if !ok { - return "" - } - return pkg.Name + "." + x.Sel.Name - case *ast.Ident: - return x.Name - default: - return "" - } -} - -// identOf returns identifier for x that can be used to obtain associated types.Object. -// Returns nil for expressions that yield temporary results, like `f().field`. -func identOf(x ast.Node) *ast.Ident { - switch x := x.(type) { - case *ast.Ident: - return x - case *ast.SelectorExpr: - return identOf(x.Sel) - case *ast.TypeAssertExpr: - // x.(type) - x may contain ident. - return identOf(x.X) - case *ast.IndexExpr: - // x[i] - x may contain ident. - return identOf(x.X) - case *ast.StarExpr: - // *x - x may contain ident. - return identOf(x.X) - case *ast.SliceExpr: - // x[:] - x may contain ident. - return identOf(x.X) - - default: - // Note that this function is not comprehensive. - return nil - } -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/weakCond_checker.go b/vendor/github.com/go-critic/go-critic/checkers/weakCond_checker.go deleted file mode 100644 index 3d7c9c1225..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/weakCond_checker.go +++ /dev/null @@ -1,78 +0,0 @@ -package checkers - -import ( - "go/ast" - "go/token" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/checkers/internal/lintutil" - "github.com/go-critic/go-critic/linter" - - "github.com/go-toolsmith/astcast" - "github.com/go-toolsmith/astequal" - "github.com/go-toolsmith/typep" - "golang.org/x/tools/go/ast/astutil" -) - -func init() { - var info linter.CheckerInfo - info.Name = "weakCond" - info.Tags = []string{linter.DiagnosticTag, linter.ExperimentalTag} - info.Summary = "Detects conditions that are unsafe due to not being exhaustive" - info.Before = `xs != nil && xs[0] != nil` - info.After = `len(xs) != 0 && xs[0] != nil` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForExpr(&weakCondChecker{ctx: ctx}), nil - }) -} - -type weakCondChecker struct { - astwalk.WalkHandler - ctx *linter.CheckerContext -} - -func (c *weakCondChecker) VisitExpr(expr ast.Expr) { - // TODO(Quasilyte): more patterns. - // TODO(Quasilyte): analyze and fix false positives. - - cond := astcast.ToBinaryExpr(expr) - lhs := astcast.ToBinaryExpr(astutil.Unparen(cond.X)) - rhs := astutil.Unparen(cond.Y) - - // Pattern 1. - // `x != nil && usageOf(x[i])` - // Pattern 2. - // `x == nil || usageOf(x[i])` - - // lhs is `x nil` - x := lhs.X - if !typep.IsSlice(c.ctx.TypeOf(x)) { - return - } - if astcast.ToIdent(lhs.Y).Name != "nil" { - return - } - - pat1prefix := cond.Op == token.LAND && lhs.Op == token.NEQ - pat2prefix := cond.Op == token.LOR && lhs.Op == token.EQL - if !pat1prefix && !pat2prefix { - return - } - - if c.isIndexed(rhs, x) { - c.warn(expr, "nil check may not be enough, check for len") - } -} - -// isIndexed reports whether x is indexed inside given expr tree. -func (c *weakCondChecker) isIndexed(tree, x ast.Expr) bool { - return lintutil.ContainsNode(tree, func(n ast.Node) bool { - indexing := astcast.ToIndexExpr(n) - return astequal.Expr(x, indexing.X) - }) -} - -func (c *weakCondChecker) warn(cause ast.Node, suggest string) { - c.ctx.Warn(cause, "suspicious `%s`; %s", cause, suggest) -} diff --git a/vendor/github.com/go-critic/go-critic/checkers/whyNoLint_checker.go b/vendor/github.com/go-critic/go-critic/checkers/whyNoLint_checker.go deleted file mode 100644 index eaa53e5d5b..0000000000 --- a/vendor/github.com/go-critic/go-critic/checkers/whyNoLint_checker.go +++ /dev/null @@ -1,50 +0,0 @@ -package checkers - -import ( - "go/ast" - "regexp" - "strings" - - "github.com/go-critic/go-critic/checkers/internal/astwalk" - "github.com/go-critic/go-critic/linter" -) - -func init() { - var info linter.CheckerInfo - info.Name = "whyNoLint" - info.Tags = []string{linter.StyleTag, linter.ExperimentalTag} - info.Summary = "Ensures that `//nolint` comments include an explanation" - info.Before = `//nolint` - info.After = `//nolint // reason` - - collection.AddChecker(&info, func(ctx *linter.CheckerContext) (linter.FileWalker, error) { - return astwalk.WalkerForComment(&whyNoLintChecker{ - ctx: ctx, - re: regexp.MustCompile(`^// *nolint(?::[^ ]+)? *(.*)$`), - }), nil - }) -} - -type whyNoLintChecker struct { - astwalk.WalkHandler - - ctx *linter.CheckerContext - re *regexp.Regexp -} - -func (c whyNoLintChecker) VisitComment(cg *ast.CommentGroup) { - if strings.HasPrefix(cg.List[0].Text, "/*") { - return - } - for _, comment := range cg.List { - sl := c.re.FindStringSubmatch(comment.Text) - if len(sl) < 2 { - continue - } - - if s := sl[1]; !strings.HasPrefix(s, "//") || strings.TrimPrefix(s, "//") == "" { - c.ctx.Warn(cg, "include an explanation for nolint directive") - return - } - } -} diff --git a/vendor/github.com/go-critic/go-critic/linter/go_version.go b/vendor/github.com/go-critic/go-critic/linter/go_version.go deleted file mode 100644 index b5ef2f75ff..0000000000 --- a/vendor/github.com/go-critic/go-critic/linter/go_version.go +++ /dev/null @@ -1,52 +0,0 @@ -package linter - -import ( - "fmt" - "strconv" - "strings" -) - -type GoVersion struct { - Major int - Minor int -} - -// GreaterOrEqual performs $v >= $other operation. -// -// In other words, it reports whether $v version constraint can use -// a feature from the $other Go version. -// -// As a special case, Major=0 covers all versions. -func (v GoVersion) GreaterOrEqual(other GoVersion) bool { - switch { - case v.Major == 0: - return true - case v.Major == other.Major: - return v.Minor >= other.Minor - default: - return v.Major >= other.Major - } -} - -func ParseGoVersion(version string) (GoVersion, error) { - var result GoVersion - version = strings.TrimPrefix(version, "go") - if version == "" { - return result, nil - } - parts := strings.Split(version, ".") - if len(parts) != 2 { - return result, fmt.Errorf("invalid Go version format: %s", version) - } - major, err := strconv.Atoi(parts[0]) - if err != nil { - return result, fmt.Errorf("invalid major version part: %s: %w", parts[0], err) - } - minor, err := strconv.Atoi(parts[1]) - if err != nil { - return result, fmt.Errorf("invalid minor version part: %s: %w", parts[1], err) - } - result.Major = major - result.Minor = minor - return result, nil -} diff --git a/vendor/github.com/go-critic/go-critic/linter/helpers.go b/vendor/github.com/go-critic/go-critic/linter/helpers.go deleted file mode 100644 index d5110df642..0000000000 --- a/vendor/github.com/go-critic/go-critic/linter/helpers.go +++ /dev/null @@ -1,136 +0,0 @@ -package linter - -import ( - "fmt" - "regexp" - "sort" - "strings" - - "github.com/go-toolsmith/astfmt" -) - -type checkerProto struct { - info *CheckerInfo - constructor func(*Context) (*Checker, error) -} - -// prototypes is a set of registered checkers that are not yet instantiated. -// Registration should be done with AddChecker function. -// Initialized checkers can be obtained with NewChecker function. -var prototypes = make(map[string]checkerProto) - -func getCheckersInfo() []*CheckerInfo { - infoList := make([]*CheckerInfo, 0, len(prototypes)) - for _, proto := range prototypes { - infoCopy := *proto.info - infoList = append(infoList, &infoCopy) - } - sort.Slice(infoList, func(i, j int) bool { - return infoList[i].Name < infoList[j].Name - }) - return infoList -} - -func addChecker(info *CheckerInfo, constructor func(*CheckerContext) (FileWalker, error)) { - if _, ok := prototypes[info.Name]; ok { - panic(fmt.Sprintf("checker with name %q already registered", info.Name)) - } - - // Validate param value type. - for pname, param := range info.Params { - switch param.Value.(type) { - case string, int, bool: - // OK. - default: - panic(fmt.Sprintf("unsupported %q param type value: %T", - pname, param.Value)) - } - } - - trimDocumentation := func(info *CheckerInfo) { - fields := []*string{ - &info.Summary, - &info.Details, - &info.Before, - &info.After, - &info.Note, - } - for _, f := range fields { - *f = strings.TrimSpace(*f) - } - } - - trimDocumentation(info) - - if err := validateCheckerInfo(info); err != nil { - panic(err) - } - - proto := checkerProto{ - info: info, - constructor: func(ctx *Context) (*Checker, error) { - var c Checker - c.Info = info - c.ctx = CheckerContext{ - Context: ctx, - printer: astfmt.NewPrinter(ctx.FileSet), - } - var err error - c.fileWalker, err = constructor(&c.ctx) - return &c, err - }, - } - - prototypes[info.Name] = proto -} - -func newChecker(ctx *Context, info *CheckerInfo) (*Checker, error) { - proto, ok := prototypes[info.Name] - if !ok { - panic(fmt.Sprintf("checker with name %q not registered", info.Name)) - } - return proto.constructor(ctx) -} - -func validateCheckerInfo(info *CheckerInfo) error { - steps := []func(*CheckerInfo) error{ - validateCheckerName, - validateCheckerDocumentation, - validateCheckerTags, - } - - for _, step := range steps { - if err := step(info); err != nil { - return fmt.Errorf("%q validation error: %v", info.Name, err) - } - } - return nil -} - -var validIdentRE = regexp.MustCompile(`^\w+$`) - -func validateCheckerName(info *CheckerInfo) error { - if !validIdentRE.MatchString(info.Name) { - return fmt.Errorf("checker name contains illegal chars") - } - return nil -} - -func validateCheckerDocumentation(_ *CheckerInfo) error { - // TODO(quasilyte): validate documentation. - return nil -} - -func validateCheckerTags(info *CheckerInfo) error { - tagSet := make(map[string]bool) - for _, tag := range info.Tags { - if tagSet[tag] { - return fmt.Errorf("duplicated tag %q", tag) - } - if !validIdentRE.MatchString(tag) { - return fmt.Errorf("checker tag %q contains illegal chars", tag) - } - tagSet[tag] = true - } - return nil -} diff --git a/vendor/github.com/go-critic/go-critic/linter/linter.go b/vendor/github.com/go-critic/go-critic/linter/linter.go deleted file mode 100644 index c751d94cce..0000000000 --- a/vendor/github.com/go-critic/go-critic/linter/linter.go +++ /dev/null @@ -1,401 +0,0 @@ -package linter - -import ( - "go/ast" - "go/token" - "go/types" - "strconv" - "strings" - - "github.com/go-toolsmith/astfmt" -) - -const ( - DiagnosticTag = "diagnostic" - ExperimentalTag = "experimental" - OpinionatedTag = "opinionated" - PerformanceTag = "performance" - SecurityTag = "security" - StyleTag = "style" -) - -// UnknownType is a special sentinel value that is returned from the CheckerContext.TypeOf -// method instead of the nil type. -var UnknownType types.Type = types.Typ[types.Invalid] - -// FileWalker is an interface every checker should implement. -// -// The WalkFile method is executed for every Go file inside the -// package that is being checked. -type FileWalker interface { - WalkFile(*ast.File) -} - -// CheckerCollection provides additional information for a group of checkers. -type CheckerCollection struct { - // URL is a link for a main source of information on the collection. - URL string -} - -// AddChecker registers a new checker into a checkers pool. -// Constructor is used to create a new checker instance. -// Checker name (defined in CheckerInfo.Name) must be unique. -// -// CheckerInfo.Collection is automatically set to the coll (the receiver). -// -// If checker is never needed, for example if it is disabled, -// constructor will not be called. -func (coll *CheckerCollection) AddChecker(info *CheckerInfo, constructor func(*CheckerContext) (FileWalker, error)) { - if coll == nil { - panic("adding checker to a nil collection") - } - info.Collection = coll - addChecker(info, constructor) -} - -// CheckerParam describes a single checker customizable parameter. -type CheckerParam struct { - // Value holds parameter bound value. - // It might be overwritten by the integrating linter. - // - // Permitted types include: - // - int - // - bool - // - string - Value interface{} - - // Usage gives an overview about what parameter does. - Usage string -} - -// CheckerParams holds all checker-specific parameters. -// -// Provides convenient access to the loosely typed underlying map. -type CheckerParams map[string]*CheckerParam - -// Int lookups pname key in underlying map and type-asserts it to int. -func (params CheckerParams) Int(pname string) int { return params[pname].Value.(int) } - -// Bool lookups pname key in underlying map and type-asserts it to bool. -func (params CheckerParams) Bool(pname string) bool { return params[pname].Value.(bool) } - -// String lookups pname key in underlying map and type-asserts it to string. -func (params CheckerParams) String(pname string) string { return params[pname].Value.(string) } - -// CheckerInfo holds checker metadata and structured documentation. -type CheckerInfo struct { - // Name is a checker name. - Name string - - // Tags is a list of labels that can be used to enable or disable checker. - // Common tags are "experimental" and "performance". - Tags []string - - // Params declares checker-specific parameters. Optional. - Params CheckerParams - - // Summary is a short one sentence description. - // Should not end with a period. - Summary string - - // Details extends summary with additional info. Optional. - Details string - - // Before is a code snippet of code that will violate rule. - Before string - - // After is a code snippet of fixed code that complies to the rule. - After string - - // Note is an optional caution message or advice. - Note string - - // EmbeddedRuleguard tells whether this checker is auto-generated - // from the embedded ruleguard rules. - EmbeddedRuleguard bool - - // Collection establishes a checker-to-collection relationship. - Collection *CheckerCollection -} - -// GetCheckersInfo returns a checkers info list for all registered checkers. -// The slice is sorted by a checker name. -// -// Info objects can be used to instantiate checkers with NewChecker function. -func GetCheckersInfo() []*CheckerInfo { - return getCheckersInfo() -} - -// HasTag reports whether checker described by the info has specified tag. -func (info *CheckerInfo) HasTag(tag string) bool { - for i := range info.Tags { - if info.Tags[i] == tag { - return true - } - } - return false -} - -// Checker is an implementation of a check that is described by the associated info. -type Checker struct { - // Info is an info object that was used to instantiate this checker. - Info *CheckerInfo - - ctx CheckerContext - - fileWalker FileWalker -} - -// NewChecker returns initialized checker identified by an info. -// info must be non-nil. -// Returns an error if info describes a checker that was not properly registered, -// or if checker fails to initialize. -func NewChecker(ctx *Context, info *CheckerInfo) (*Checker, error) { - return newChecker(ctx, info) -} - -// Check runs rule checker over file f. -func (c *Checker) Check(f *ast.File) []Warning { - c.ctx.warnings = c.ctx.warnings[:0] - c.fileWalker.WalkFile(f) - return c.ctx.warnings -} - -// QuickFix is our analysis.TextEdit; we're using it here to avoid -// direct analysis package dependency for now. -type QuickFix struct { - From token.Pos - To token.Pos - Replacement []byte -} - -// Warning represents issue that is found by checker. -type Warning struct { - Pos token.Pos - - // Text is warning message without source location info. - Text string - - // Suggestion is a quick fix for a given problem. - // QuickFix is analysis.TextEdit and can be used to - // construct an analysis.SuggestedFix object. - // - // For convenience, there is Warning.HasQuickFix() method - // that reports whether Suggestion has something meaningful. - Suggestion QuickFix -} - -// HasQuickFix reports whether this warning has a suggested fix. -func (warn Warning) HasQuickFix() bool { - return warn.Suggestion.Replacement != nil -} - -// Context is a readonly state shared among every checker. -type Context struct { - // TypesInfo carries parsed packages types information. - TypesInfo *types.Info - - // SizesInfo carries alignment and type size information. - // Arch-dependent. - SizesInfo types.Sizes - - // GoVersion is a target Go version. - GoVersion GoVersion - - // FileSet is a file set that was used during the program loading. - FileSet *token.FileSet - - // Pkg describes package that is being checked. - Pkg *types.Package - - // Filename is a currently checked file name. - Filename string - - // Require records what optional resources are required - // by the checkers set that use this context. - // - // Every require fields makes associated context field - // to be properly initialized. - // For example, Context.require.PkgObjects => Context.PkgObjects. - Require struct { - PkgObjects bool - PkgRenames bool - } - - // PkgObjects stores all imported packages and their local names. - PkgObjects map[*types.PkgName]string - - // PkgRenames maps package path to its local renaming. - // Contains no entries for packages that were imported without - // explicit local names. - PkgRenames map[string]string -} - -// NewContext returns new shared context to be used by every checker. -// -// All data carried by the context is readonly for checkers, -// but can be modified by the integrating application. -func NewContext(fset *token.FileSet, sizes types.Sizes) *Context { - return &Context{ - FileSet: fset, - SizesInfo: sizes, - TypesInfo: &types.Info{}, - } -} - -// SetGoVersion adjust the target Go language version. -// -// The format is like "1.5", "1.8", etc. -// It's permitted to have "go" prefix (e.g. "go1.5"). -// -// Empty string (the default) means that we make no -// Go version assumptions and (like go-critic does) behave -// like all features are available. To make go-critic -// more conservative, the upper Go version level should be adjusted. -func (c *Context) SetGoVersion(version string) { - v, err := ParseGoVersion(version) - if err != nil { - panic(err) - } - c.GoVersion = v -} - -// SetPackageInfo sets package-related metadata. -// -// Must be called for every package being checked. -func (c *Context) SetPackageInfo(info *types.Info, pkg *types.Package) { - if info != nil { - // We do this kind of assignment to avoid - // changing c.typesInfo field address after - // every re-assignment. - *c.TypesInfo = *info - } - c.Pkg = pkg -} - -// SetFileInfo sets file-related metadata. -// -// Must be called for every source code file being checked. -func (c *Context) SetFileInfo(name string, f *ast.File) { - c.Filename = name - if c.Require.PkgObjects { - resolvePkgObjects(c, f) - } - if c.Require.PkgRenames { - resolvePkgRenames(c, f) - } -} - -// CheckerContext is checker-local context copy. -// Fields that are not from Context itself are writeable. -type CheckerContext struct { - *Context - - // printer used to format warning text. - printer *astfmt.Printer - - warnings []Warning -} - -// Warn adds a Warning to checker output. -func (ctx *CheckerContext) Warn(node ast.Node, format string, args ...interface{}) { - ctx.WarnWithPos(node.Pos(), format, args...) -} - -// WarnFixable emits a warning with a fix suggestion provided by the caller. -func (ctx *CheckerContext) WarnFixable(node ast.Node, fix QuickFix, format string, args ...interface{}) { - ctx.WarnFixableWithPos(node.Pos(), fix, format, args...) -} - -// WarnWithPos adds a Warning to checker output. Useful for ruleguard's Report func. -func (ctx *CheckerContext) WarnWithPos(pos token.Pos, format string, args ...interface{}) { - ctx.warnings = append(ctx.warnings, Warning{ - Text: ctx.printer.Sprintf(format, args...), - Pos: pos, - }) -} - -// WarnFixableWithPos adds a Warning to checker output. Useful for ruleguard's Report func. -func (ctx *CheckerContext) WarnFixableWithPos(pos token.Pos, fix QuickFix, format string, args ...interface{}) { - ctx.warnings = append(ctx.warnings, Warning{ - Text: ctx.printer.Sprintf(format, args...), - Pos: pos, - Suggestion: fix, - }) -} - -// TypeOf returns the type of expression x. -// -// Unlike TypesInfo.TypeOf, it never returns nil. -// Instead, it returns the Invalid type as a sentinel UnknownType value. -func (ctx *CheckerContext) TypeOf(x ast.Expr) types.Type { - typ := ctx.TypesInfo.TypeOf(x) - if typ != nil { - return typ - } - // Usually it means that some incorrect type info was loaded - // or the analyzed package was only partially (?) correct. - // To avoid nil pointer panics we can return a sentinel value - // that will fail most type assertions as well as kind checks - // (if the call side expects a *types.Basic). - return UnknownType -} - -// SizeOf returns the size of the typ in bytes. -// -// Unlike SizesInfo.SizeOf, it will not panic on generic types. -func (ctx *CheckerContext) SizeOf(typ types.Type) (int64, bool) { - if _, ok := typ.(*types.TypeParam); ok { - return 0, false - } - if named, ok := typ.(*types.Named); ok && named.TypeParams() != nil { - return 0, false - } - return ctx.safeSizesInfoSizeof(typ) -} - -// safeSizesInfoSizeof unlike SizesInfo.Sizeof will not panic on struct with generic fields. -// it will catch a panic and recover from it, see https://github.com/go-critic/go-critic/issues/1354 -func (ctx *CheckerContext) safeSizesInfoSizeof(typ types.Type) (size int64, ok bool) { - ok = true - defer func() { - if r := recover(); r != nil { - if strings.Contains(r.(string), "assertion failed") { - size, ok = 0, false - } else { - panic(r) - } - } - }() - - size = ctx.SizesInfo.Sizeof(typ) - return size, ok -} - -func resolvePkgObjects(ctx *Context, f *ast.File) { - ctx.PkgObjects = make(map[*types.PkgName]string, len(f.Imports)) - - for _, spec := range f.Imports { - if spec.Name != nil { - obj := ctx.TypesInfo.ObjectOf(spec.Name) - ctx.PkgObjects[obj.(*types.PkgName)] = spec.Name.Name - } else { - obj := ctx.TypesInfo.Implicits[spec] - ctx.PkgObjects[obj.(*types.PkgName)] = obj.Name() - } - } -} - -func resolvePkgRenames(ctx *Context, f *ast.File) { - ctx.PkgRenames = make(map[string]string) - - for _, spec := range f.Imports { - if spec.Name != nil { - path, err := strconv.Unquote(spec.Path.Value) - if err != nil { - panic(err) - } - ctx.PkgRenames[path] = spec.Name.Name - } - } -} diff --git a/vendor/github.com/go-toolsmith/astcast/LICENSE b/vendor/github.com/go-toolsmith/astcast/LICENSE deleted file mode 100644 index eef17180f8..0000000000 --- a/vendor/github.com/go-toolsmith/astcast/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2018 go-toolsmith - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/go-toolsmith/astcast/README.md b/vendor/github.com/go-toolsmith/astcast/README.md deleted file mode 100644 index 19ca0e71d2..0000000000 --- a/vendor/github.com/go-toolsmith/astcast/README.md +++ /dev/null @@ -1,103 +0,0 @@ -# astcast - -[![build-img]][build-url] -[![pkg-img]][pkg-url] -[![reportcard-img]][reportcard-url] -[![version-img]][version-url] - -Package `astcast` wraps type assertion operations in such way that you don't have -to worry about nil pointer results anymore. - -## Installation - -Go version 1.16+ - -```bash -go get github.com/go-toolsmith/astcast -``` - -## Example - -```go -package main - -import ( - "fmt" - - "github.com/go-toolsmith/astcast" - "github.com/go-toolsmith/strparse" -) - -func main() { - x := strparse.Expr(`(foo * bar) + 1`) - - // x type is ast.Expr, we want to access bar operand - // that is a RHS of the LHS of the addition. - // Note that addition LHS (X field) is has parenthesis, - // so we have to remove them too. - - add := astcast.ToBinaryExpr(x) - mul := astcast.ToBinaryExpr(astcast.ToParenExpr(add.X).X) - bar := astcast.ToIdent(mul.Y) - fmt.Printf("%T %s\n", bar, bar.Name) // => *ast.Ident bar - - // If argument has different dynamic type, - // non-nil sentinel object of requested type is returned. - // Those sentinel objects are exported so if you need - // to know whether it was a nil interface value of - // failed type assertion, you can compare returned - // object with such a sentinel. - - y := astcast.ToCallExpr(strparse.Expr(`x`)) - if y == astcast.NilCallExpr { - fmt.Println("it is a sentinel, type assertion failed") - } -} -``` - -Without `astcast`, you would have to do a lots of type assertions: - -```go -package main - -import ( - "fmt" - - "github.com/go-toolsmith/strparse" -) - -func main() { - x := strparse.Expr(`(foo * bar) + 1`) - - add, ok := x.(*ast.BinaryExpr) - if !ok || add == nil { - return - } - additionLHS, ok := add.X.(*ast.ParenExpr) - if !ok || additionLHS == nil { - return - } - mul, ok := additionLHS.X.(*ast.BinaryExpr) - if !ok || mul == nil { - return - } - bar, ok := mul.Y.(*ast.Ident) - if !ok || bar == nil { - return - } - fmt.Printf("%T %s\n", bar, bar.Name) -} -``` - -## License - -[MIT License](LICENSE). - -[build-img]: https://github.com/go-toolsmith/astcast/workflows/build/badge.svg -[build-url]: https://github.com/go-toolsmith/astcast/actions -[pkg-img]: https://pkg.go.dev/badge/go-toolsmith/astcast -[pkg-url]: https://pkg.go.dev/github.com/go-toolsmith/astcast -[reportcard-img]: https://goreportcard.com/badge/go-toolsmith/astcast -[reportcard-url]: https://goreportcard.com/report/go-toolsmith/astcast -[version-img]: https://img.shields.io/github/v/release/go-toolsmith/astcast -[version-url]: https://github.com/go-toolsmith/astcast/releases diff --git a/vendor/github.com/go-toolsmith/astcast/astcast.go b/vendor/github.com/go-toolsmith/astcast/astcast.go deleted file mode 100644 index 746d568aa3..0000000000 --- a/vendor/github.com/go-toolsmith/astcast/astcast.go +++ /dev/null @@ -1,590 +0,0 @@ -// Code generated by astcast_generate.go; DO NOT EDIT - -// Package astcast wraps type assertion operations in such way that you don't have -// to worry about nil pointer results anymore. -package astcast - -import ( - "go/ast" -) - -// A set of sentinel nil-like values that are returned -// by all "casting" functions in case of failed type assertion. -var ( - NilArrayType = &ast.ArrayType{} - NilBadExpr = &ast.BadExpr{} - NilBasicLit = &ast.BasicLit{} - NilBinaryExpr = &ast.BinaryExpr{} - NilCallExpr = &ast.CallExpr{} - NilChanType = &ast.ChanType{} - NilCompositeLit = &ast.CompositeLit{} - NilEllipsis = &ast.Ellipsis{} - NilFuncLit = &ast.FuncLit{} - NilFuncType = &ast.FuncType{} - NilIdent = &ast.Ident{} - NilIndexExpr = &ast.IndexExpr{} - NilInterfaceType = &ast.InterfaceType{} - NilKeyValueExpr = &ast.KeyValueExpr{} - NilMapType = &ast.MapType{} - NilParenExpr = &ast.ParenExpr{} - NilSelectorExpr = &ast.SelectorExpr{} - NilSliceExpr = &ast.SliceExpr{} - NilStarExpr = &ast.StarExpr{} - NilStructType = &ast.StructType{} - NilTypeAssertExpr = &ast.TypeAssertExpr{} - NilUnaryExpr = &ast.UnaryExpr{} - NilAssignStmt = &ast.AssignStmt{} - NilBadStmt = &ast.BadStmt{} - NilBlockStmt = &ast.BlockStmt{} - NilBranchStmt = &ast.BranchStmt{} - NilCaseClause = &ast.CaseClause{} - NilCommClause = &ast.CommClause{} - NilDeclStmt = &ast.DeclStmt{} - NilDeferStmt = &ast.DeferStmt{} - NilEmptyStmt = &ast.EmptyStmt{} - NilExprStmt = &ast.ExprStmt{} - NilForStmt = &ast.ForStmt{} - NilGoStmt = &ast.GoStmt{} - NilIfStmt = &ast.IfStmt{} - NilIncDecStmt = &ast.IncDecStmt{} - NilLabeledStmt = &ast.LabeledStmt{} - NilRangeStmt = &ast.RangeStmt{} - NilReturnStmt = &ast.ReturnStmt{} - NilSelectStmt = &ast.SelectStmt{} - NilSendStmt = &ast.SendStmt{} - NilSwitchStmt = &ast.SwitchStmt{} - NilTypeSwitchStmt = &ast.TypeSwitchStmt{} - NilComment = &ast.Comment{} - NilCommentGroup = &ast.CommentGroup{} - NilFieldList = &ast.FieldList{} - NilFile = &ast.File{} - NilPackage = &ast.Package{} -) - -// ToArrayType returns x as a non-nil *ast.ArrayType. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilArrayType. -func ToArrayType(x ast.Node) *ast.ArrayType { - if x, ok := x.(*ast.ArrayType); ok { - return x - } - return NilArrayType -} - -// ToBadExpr returns x as a non-nil *ast.BadExpr. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilBadExpr. -func ToBadExpr(x ast.Node) *ast.BadExpr { - if x, ok := x.(*ast.BadExpr); ok { - return x - } - return NilBadExpr -} - -// ToBasicLit returns x as a non-nil *ast.BasicLit. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilBasicLit. -func ToBasicLit(x ast.Node) *ast.BasicLit { - if x, ok := x.(*ast.BasicLit); ok { - return x - } - return NilBasicLit -} - -// ToBinaryExpr returns x as a non-nil *ast.BinaryExpr. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilBinaryExpr. -func ToBinaryExpr(x ast.Node) *ast.BinaryExpr { - if x, ok := x.(*ast.BinaryExpr); ok { - return x - } - return NilBinaryExpr -} - -// ToCallExpr returns x as a non-nil *ast.CallExpr. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilCallExpr. -func ToCallExpr(x ast.Node) *ast.CallExpr { - if x, ok := x.(*ast.CallExpr); ok { - return x - } - return NilCallExpr -} - -// ToChanType returns x as a non-nil *ast.ChanType. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilChanType. -func ToChanType(x ast.Node) *ast.ChanType { - if x, ok := x.(*ast.ChanType); ok { - return x - } - return NilChanType -} - -// ToCompositeLit returns x as a non-nil *ast.CompositeLit. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilCompositeLit. -func ToCompositeLit(x ast.Node) *ast.CompositeLit { - if x, ok := x.(*ast.CompositeLit); ok { - return x - } - return NilCompositeLit -} - -// ToEllipsis returns x as a non-nil *ast.Ellipsis. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilEllipsis. -func ToEllipsis(x ast.Node) *ast.Ellipsis { - if x, ok := x.(*ast.Ellipsis); ok { - return x - } - return NilEllipsis -} - -// ToFuncLit returns x as a non-nil *ast.FuncLit. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilFuncLit. -func ToFuncLit(x ast.Node) *ast.FuncLit { - if x, ok := x.(*ast.FuncLit); ok { - return x - } - return NilFuncLit -} - -// ToFuncType returns x as a non-nil *ast.FuncType. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilFuncType. -func ToFuncType(x ast.Node) *ast.FuncType { - if x, ok := x.(*ast.FuncType); ok { - return x - } - return NilFuncType -} - -// ToIdent returns x as a non-nil *ast.Ident. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilIdent. -func ToIdent(x ast.Node) *ast.Ident { - if x, ok := x.(*ast.Ident); ok { - return x - } - return NilIdent -} - -// ToIndexExpr returns x as a non-nil *ast.IndexExpr. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilIndexExpr. -func ToIndexExpr(x ast.Node) *ast.IndexExpr { - if x, ok := x.(*ast.IndexExpr); ok { - return x - } - return NilIndexExpr -} - -// ToInterfaceType returns x as a non-nil *ast.InterfaceType. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilInterfaceType. -func ToInterfaceType(x ast.Node) *ast.InterfaceType { - if x, ok := x.(*ast.InterfaceType); ok { - return x - } - return NilInterfaceType -} - -// ToKeyValueExpr returns x as a non-nil *ast.KeyValueExpr. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilKeyValueExpr. -func ToKeyValueExpr(x ast.Node) *ast.KeyValueExpr { - if x, ok := x.(*ast.KeyValueExpr); ok { - return x - } - return NilKeyValueExpr -} - -// ToMapType returns x as a non-nil *ast.MapType. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilMapType. -func ToMapType(x ast.Node) *ast.MapType { - if x, ok := x.(*ast.MapType); ok { - return x - } - return NilMapType -} - -// ToParenExpr returns x as a non-nil *ast.ParenExpr. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilParenExpr. -func ToParenExpr(x ast.Node) *ast.ParenExpr { - if x, ok := x.(*ast.ParenExpr); ok { - return x - } - return NilParenExpr -} - -// ToSelectorExpr returns x as a non-nil *ast.SelectorExpr. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilSelectorExpr. -func ToSelectorExpr(x ast.Node) *ast.SelectorExpr { - if x, ok := x.(*ast.SelectorExpr); ok { - return x - } - return NilSelectorExpr -} - -// ToSliceExpr returns x as a non-nil *ast.SliceExpr. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilSliceExpr. -func ToSliceExpr(x ast.Node) *ast.SliceExpr { - if x, ok := x.(*ast.SliceExpr); ok { - return x - } - return NilSliceExpr -} - -// ToStarExpr returns x as a non-nil *ast.StarExpr. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilStarExpr. -func ToStarExpr(x ast.Node) *ast.StarExpr { - if x, ok := x.(*ast.StarExpr); ok { - return x - } - return NilStarExpr -} - -// ToStructType returns x as a non-nil *ast.StructType. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilStructType. -func ToStructType(x ast.Node) *ast.StructType { - if x, ok := x.(*ast.StructType); ok { - return x - } - return NilStructType -} - -// ToTypeAssertExpr returns x as a non-nil *ast.TypeAssertExpr. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilTypeAssertExpr. -func ToTypeAssertExpr(x ast.Node) *ast.TypeAssertExpr { - if x, ok := x.(*ast.TypeAssertExpr); ok { - return x - } - return NilTypeAssertExpr -} - -// ToUnaryExpr returns x as a non-nil *ast.UnaryExpr. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilUnaryExpr. -func ToUnaryExpr(x ast.Node) *ast.UnaryExpr { - if x, ok := x.(*ast.UnaryExpr); ok { - return x - } - return NilUnaryExpr -} - -// ToAssignStmt returns x as a non-nil *ast.AssignStmt. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilAssignStmt. -func ToAssignStmt(x ast.Node) *ast.AssignStmt { - if x, ok := x.(*ast.AssignStmt); ok { - return x - } - return NilAssignStmt -} - -// ToBadStmt returns x as a non-nil *ast.BadStmt. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilBadStmt. -func ToBadStmt(x ast.Node) *ast.BadStmt { - if x, ok := x.(*ast.BadStmt); ok { - return x - } - return NilBadStmt -} - -// ToBlockStmt returns x as a non-nil *ast.BlockStmt. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilBlockStmt. -func ToBlockStmt(x ast.Node) *ast.BlockStmt { - if x, ok := x.(*ast.BlockStmt); ok { - return x - } - return NilBlockStmt -} - -// ToBranchStmt returns x as a non-nil *ast.BranchStmt. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilBranchStmt. -func ToBranchStmt(x ast.Node) *ast.BranchStmt { - if x, ok := x.(*ast.BranchStmt); ok { - return x - } - return NilBranchStmt -} - -// ToCaseClause returns x as a non-nil *ast.CaseClause. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilCaseClause. -func ToCaseClause(x ast.Node) *ast.CaseClause { - if x, ok := x.(*ast.CaseClause); ok { - return x - } - return NilCaseClause -} - -// ToCommClause returns x as a non-nil *ast.CommClause. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilCommClause. -func ToCommClause(x ast.Node) *ast.CommClause { - if x, ok := x.(*ast.CommClause); ok { - return x - } - return NilCommClause -} - -// ToDeclStmt returns x as a non-nil *ast.DeclStmt. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilDeclStmt. -func ToDeclStmt(x ast.Node) *ast.DeclStmt { - if x, ok := x.(*ast.DeclStmt); ok { - return x - } - return NilDeclStmt -} - -// ToDeferStmt returns x as a non-nil *ast.DeferStmt. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilDeferStmt. -func ToDeferStmt(x ast.Node) *ast.DeferStmt { - if x, ok := x.(*ast.DeferStmt); ok { - return x - } - return NilDeferStmt -} - -// ToEmptyStmt returns x as a non-nil *ast.EmptyStmt. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilEmptyStmt. -func ToEmptyStmt(x ast.Node) *ast.EmptyStmt { - if x, ok := x.(*ast.EmptyStmt); ok { - return x - } - return NilEmptyStmt -} - -// ToExprStmt returns x as a non-nil *ast.ExprStmt. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilExprStmt. -func ToExprStmt(x ast.Node) *ast.ExprStmt { - if x, ok := x.(*ast.ExprStmt); ok { - return x - } - return NilExprStmt -} - -// ToForStmt returns x as a non-nil *ast.ForStmt. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilForStmt. -func ToForStmt(x ast.Node) *ast.ForStmt { - if x, ok := x.(*ast.ForStmt); ok { - return x - } - return NilForStmt -} - -// ToGoStmt returns x as a non-nil *ast.GoStmt. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilGoStmt. -func ToGoStmt(x ast.Node) *ast.GoStmt { - if x, ok := x.(*ast.GoStmt); ok { - return x - } - return NilGoStmt -} - -// ToIfStmt returns x as a non-nil *ast.IfStmt. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilIfStmt. -func ToIfStmt(x ast.Node) *ast.IfStmt { - if x, ok := x.(*ast.IfStmt); ok { - return x - } - return NilIfStmt -} - -// ToIncDecStmt returns x as a non-nil *ast.IncDecStmt. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilIncDecStmt. -func ToIncDecStmt(x ast.Node) *ast.IncDecStmt { - if x, ok := x.(*ast.IncDecStmt); ok { - return x - } - return NilIncDecStmt -} - -// ToLabeledStmt returns x as a non-nil *ast.LabeledStmt. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilLabeledStmt. -func ToLabeledStmt(x ast.Node) *ast.LabeledStmt { - if x, ok := x.(*ast.LabeledStmt); ok { - return x - } - return NilLabeledStmt -} - -// ToRangeStmt returns x as a non-nil *ast.RangeStmt. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilRangeStmt. -func ToRangeStmt(x ast.Node) *ast.RangeStmt { - if x, ok := x.(*ast.RangeStmt); ok { - return x - } - return NilRangeStmt -} - -// ToReturnStmt returns x as a non-nil *ast.ReturnStmt. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilReturnStmt. -func ToReturnStmt(x ast.Node) *ast.ReturnStmt { - if x, ok := x.(*ast.ReturnStmt); ok { - return x - } - return NilReturnStmt -} - -// ToSelectStmt returns x as a non-nil *ast.SelectStmt. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilSelectStmt. -func ToSelectStmt(x ast.Node) *ast.SelectStmt { - if x, ok := x.(*ast.SelectStmt); ok { - return x - } - return NilSelectStmt -} - -// ToSendStmt returns x as a non-nil *ast.SendStmt. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilSendStmt. -func ToSendStmt(x ast.Node) *ast.SendStmt { - if x, ok := x.(*ast.SendStmt); ok { - return x - } - return NilSendStmt -} - -// ToSwitchStmt returns x as a non-nil *ast.SwitchStmt. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilSwitchStmt. -func ToSwitchStmt(x ast.Node) *ast.SwitchStmt { - if x, ok := x.(*ast.SwitchStmt); ok { - return x - } - return NilSwitchStmt -} - -// ToTypeSwitchStmt returns x as a non-nil *ast.TypeSwitchStmt. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilTypeSwitchStmt. -func ToTypeSwitchStmt(x ast.Node) *ast.TypeSwitchStmt { - if x, ok := x.(*ast.TypeSwitchStmt); ok { - return x - } - return NilTypeSwitchStmt -} - -// ToComment returns x as a non-nil *ast.Comment. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilComment. -func ToComment(x ast.Node) *ast.Comment { - if x, ok := x.(*ast.Comment); ok { - return x - } - return NilComment -} - -// ToCommentGroup returns x as a non-nil *ast.CommentGroup. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilCommentGroup. -func ToCommentGroup(x ast.Node) *ast.CommentGroup { - if x, ok := x.(*ast.CommentGroup); ok { - return x - } - return NilCommentGroup -} - -// ToFieldList returns x as a non-nil *ast.FieldList. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilFieldList. -func ToFieldList(x ast.Node) *ast.FieldList { - if x, ok := x.(*ast.FieldList); ok { - return x - } - return NilFieldList -} - -// ToFile returns x as a non-nil *ast.File. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilFile. -func ToFile(x ast.Node) *ast.File { - if x, ok := x.(*ast.File); ok { - return x - } - return NilFile -} - -// ToPackage returns x as a non-nil *ast.Package. -// If ast.Node actually has such dynamic type, the result is -// identical to normal type assertion. In case if it has -// different type, the returned value is NilPackage. -func ToPackage(x ast.Node) *ast.Package { - if x, ok := x.(*ast.Package); ok { - return x - } - return NilPackage -} diff --git a/vendor/github.com/go-toolsmith/astcopy/LICENSE b/vendor/github.com/go-toolsmith/astcopy/LICENSE deleted file mode 100644 index eef17180f8..0000000000 --- a/vendor/github.com/go-toolsmith/astcopy/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2018 go-toolsmith - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/go-toolsmith/astcopy/README.md b/vendor/github.com/go-toolsmith/astcopy/README.md deleted file mode 100644 index 7adc665250..0000000000 --- a/vendor/github.com/go-toolsmith/astcopy/README.md +++ /dev/null @@ -1,57 +0,0 @@ -# astcopy - -[![build-img]][build-url] -[![pkg-img]][pkg-url] -[![reportcard-img]][reportcard-url] -[![version-img]][version-url] - -Package `astcopy` implements Go AST reflection-free deep copy operations. - -## Installation: - -Go version 1.16+ - -```bash -go get github.com/go-toolsmith/astcopy -``` - -## Example - -```go -package main - -import ( - "fmt" - "go/ast" - "go/token" - - "github.com/go-toolsmith/astcopy" - "github.com/go-toolsmith/astequal" - "github.com/go-toolsmith/strparse" -) - -func main() { - x := strparse.Expr(`1 + 2`).(*ast.BinaryExpr) - y := astcopy.BinaryExpr(x) - fmt.Println(astequal.Expr(x, y)) // => true - - // Now modify x and make sure y is not modified. - z := astcopy.BinaryExpr(y) - x.Op = token.SUB - fmt.Println(astequal.Expr(y, z)) // => true - fmt.Println(astequal.Expr(x, y)) // => false -} -``` - -## License - -[MIT License](LICENSE). - -[build-img]: https://github.com/go-toolsmith/astp/workflows/build/badge.svg -[build-url]: https://github.com/go-toolsmith/astp/actions -[pkg-img]: https://pkg.go.dev/badge/go-toolsmith/astp -[pkg-url]: https://pkg.go.dev/github.com/go-toolsmith/astp -[reportcard-img]: https://goreportcard.com/badge/go-toolsmith/astp -[reportcard-url]: https://goreportcard.com/report/go-toolsmith/astp -[version-img]: https://img.shields.io/github/v/release/go-toolsmith/astp -[version-url]: https://github.com/go-toolsmith/astp/releases diff --git a/vendor/github.com/go-toolsmith/astcopy/astcopy.go b/vendor/github.com/go-toolsmith/astcopy/astcopy.go deleted file mode 100644 index 72bc58ce6d..0000000000 --- a/vendor/github.com/go-toolsmith/astcopy/astcopy.go +++ /dev/null @@ -1,945 +0,0 @@ -// Package astcopy implements Go AST reflection-free deep copy operations. -package astcopy - -import ( - "go/ast" - - "golang.org/x/exp/typeparams" -) - -// Node returns x node deep copy. -// Copy of nil argument is nil. -func Node(x ast.Node) ast.Node { - return copyNode(x) -} - -// NodeList returns xs node slice deep copy. -// Copy of nil argument is nil. -func NodeList(xs []ast.Node) []ast.Node { - if xs == nil { - return nil - } - cp := make([]ast.Node, len(xs)) - for i := range xs { - cp[i] = copyNode(xs[i]) - } - return cp -} - -// Expr returns x expression deep copy. -// Copy of nil argument is nil. -func Expr(x ast.Expr) ast.Expr { - return copyExpr(x) -} - -// ExprList returns xs expression slice deep copy. -// Copy of nil argument is nil. -func ExprList(xs []ast.Expr) []ast.Expr { - if xs == nil { - return nil - } - cp := make([]ast.Expr, len(xs)) - for i := range xs { - cp[i] = copyExpr(xs[i]) - } - return cp -} - -// Stmt returns x statement deep copy. -// Copy of nil argument is nil. -func Stmt(x ast.Stmt) ast.Stmt { - return copyStmt(x) -} - -// StmtList returns xs statement slice deep copy. -// Copy of nil argument is nil. -func StmtList(xs []ast.Stmt) []ast.Stmt { - if xs == nil { - return nil - } - cp := make([]ast.Stmt, len(xs)) - for i := range xs { - cp[i] = copyStmt(xs[i]) - } - return cp -} - -// Decl returns x declaration deep copy. -// Copy of nil argument is nil. -func Decl(x ast.Decl) ast.Decl { - return copyDecl(x) -} - -// DeclList returns xs declaration slice deep copy. -// Copy of nil argument is nil. -func DeclList(xs []ast.Decl) []ast.Decl { - if xs == nil { - return nil - } - cp := make([]ast.Decl, len(xs)) - for i := range xs { - cp[i] = copyDecl(xs[i]) - } - return cp -} - -// BadExpr returns x deep copy. -// Copy of nil argument is nil. -func BadExpr(x *ast.BadExpr) *ast.BadExpr { - if x == nil { - return nil - } - cp := *x - return &cp -} - -// Ident returns x deep copy. -// Copy of nil argument is nil. -func Ident(x *ast.Ident) *ast.Ident { - if x == nil { - return nil - } - cp := *x - return &cp -} - -// IdentList returns xs identifier slice deep copy. -// Copy of nil argument is nil. -func IdentList(xs []*ast.Ident) []*ast.Ident { - if xs == nil { - return nil - } - cp := make([]*ast.Ident, len(xs)) - for i := range xs { - cp[i] = Ident(xs[i]) - } - return cp -} - -// Ellipsis returns x deep copy. -// Copy of nil argument is nil. -func Ellipsis(x *ast.Ellipsis) *ast.Ellipsis { - if x == nil { - return nil - } - cp := *x - cp.Elt = copyExpr(x.Elt) - return &cp -} - -// BasicLit returns x deep copy. -// Copy of nil argument is nil. -func BasicLit(x *ast.BasicLit) *ast.BasicLit { - if x == nil { - return nil - } - cp := *x - return &cp -} - -// FuncLit returns x deep copy. -// Copy of nil argument is nil. -func FuncLit(x *ast.FuncLit) *ast.FuncLit { - if x == nil { - return nil - } - cp := *x - cp.Type = FuncType(x.Type) - cp.Body = BlockStmt(x.Body) - return &cp -} - -// CompositeLit returns x deep copy. -// Copy of nil argument is nil. -func CompositeLit(x *ast.CompositeLit) *ast.CompositeLit { - if x == nil { - return nil - } - cp := *x - cp.Type = copyExpr(x.Type) - cp.Elts = ExprList(x.Elts) - return &cp -} - -// ParenExpr returns x deep copy. -// Copy of nil argument is nil. -func ParenExpr(x *ast.ParenExpr) *ast.ParenExpr { - if x == nil { - return nil - } - cp := *x - cp.X = copyExpr(x.X) - return &cp -} - -// SelectorExpr returns x deep copy. -// Copy of nil argument is nil. -func SelectorExpr(x *ast.SelectorExpr) *ast.SelectorExpr { - if x == nil { - return nil - } - cp := *x - cp.X = copyExpr(x.X) - cp.Sel = Ident(x.Sel) - return &cp -} - -// IndexExpr returns x deep copy. -// Copy of nil argument is nil. -func IndexExpr(x *ast.IndexExpr) *ast.IndexExpr { - if x == nil { - return nil - } - cp := *x - cp.X = copyExpr(x.X) - cp.Index = copyExpr(x.Index) - return &cp -} - -// IndexListExpr returns x deep copy. -// Copy of nil argument is nil. -func IndexListExpr(x *typeparams.IndexListExpr) *typeparams.IndexListExpr { - if x == nil { - return nil - } - cp := *x - cp.X = copyExpr(x.X) - cp.Indices = ExprList(x.Indices) - return &cp -} - -// SliceExpr returns x deep copy. -// Copy of nil argument is nil. -func SliceExpr(x *ast.SliceExpr) *ast.SliceExpr { - if x == nil { - return nil - } - cp := *x - cp.X = copyExpr(x.X) - cp.Low = copyExpr(x.Low) - cp.High = copyExpr(x.High) - cp.Max = copyExpr(x.Max) - return &cp -} - -// TypeAssertExpr returns x deep copy. -// Copy of nil argument is nil. -func TypeAssertExpr(x *ast.TypeAssertExpr) *ast.TypeAssertExpr { - if x == nil { - return nil - } - cp := *x - cp.X = copyExpr(x.X) - cp.Type = copyExpr(x.Type) - return &cp -} - -// CallExpr returns x deep copy. -// Copy of nil argument is nil. -func CallExpr(x *ast.CallExpr) *ast.CallExpr { - if x == nil { - return nil - } - cp := *x - cp.Fun = copyExpr(x.Fun) - cp.Args = ExprList(x.Args) - return &cp -} - -// StarExpr returns x deep copy. -// Copy of nil argument is nil. -func StarExpr(x *ast.StarExpr) *ast.StarExpr { - if x == nil { - return nil - } - cp := *x - cp.X = copyExpr(x.X) - return &cp -} - -// UnaryExpr returns x deep copy. -// Copy of nil argument is nil. -func UnaryExpr(x *ast.UnaryExpr) *ast.UnaryExpr { - if x == nil { - return nil - } - cp := *x - cp.X = copyExpr(x.X) - return &cp -} - -// BinaryExpr returns x deep copy. -// Copy of nil argument is nil. -func BinaryExpr(x *ast.BinaryExpr) *ast.BinaryExpr { - if x == nil { - return nil - } - cp := *x - cp.X = copyExpr(x.X) - cp.Y = copyExpr(x.Y) - return &cp -} - -// KeyValueExpr returns x deep copy. -// Copy of nil argument is nil. -func KeyValueExpr(x *ast.KeyValueExpr) *ast.KeyValueExpr { - if x == nil { - return nil - } - cp := *x - cp.Key = copyExpr(x.Key) - cp.Value = copyExpr(x.Value) - return &cp -} - -// ArrayType returns x deep copy. -// Copy of nil argument is nil. -func ArrayType(x *ast.ArrayType) *ast.ArrayType { - if x == nil { - return nil - } - cp := *x - cp.Len = copyExpr(x.Len) - cp.Elt = copyExpr(x.Elt) - return &cp -} - -// StructType returns x deep copy. -// Copy of nil argument is nil. -func StructType(x *ast.StructType) *ast.StructType { - if x == nil { - return nil - } - cp := *x - cp.Fields = FieldList(x.Fields) - return &cp -} - -// Field returns x deep copy. -// Copy of nil argument is nil. -func Field(x *ast.Field) *ast.Field { - if x == nil { - return nil - } - cp := *x - cp.Names = IdentList(x.Names) - cp.Type = copyExpr(x.Type) - cp.Tag = BasicLit(x.Tag) - cp.Doc = CommentGroup(x.Doc) - cp.Comment = CommentGroup(x.Comment) - return &cp -} - -// FieldList returns x deep copy. -// Copy of nil argument is nil. -func FieldList(x *ast.FieldList) *ast.FieldList { - if x == nil { - return nil - } - cp := *x - if x.List != nil { - cp.List = make([]*ast.Field, len(x.List)) - for i := range x.List { - cp.List[i] = Field(x.List[i]) - } - } - return &cp -} - -// InterfaceType returns x deep copy. -// Copy of nil argument is nil. -func InterfaceType(x *ast.InterfaceType) *ast.InterfaceType { - if x == nil { - return nil - } - cp := *x - cp.Methods = FieldList(x.Methods) - return &cp -} - -// MapType returns x deep copy. -// Copy of nil argument is nil. -func MapType(x *ast.MapType) *ast.MapType { - if x == nil { - return nil - } - cp := *x - cp.Key = copyExpr(x.Key) - cp.Value = copyExpr(x.Value) - return &cp -} - -// ChanType returns x deep copy. -// Copy of nil argument is nil. -func ChanType(x *ast.ChanType) *ast.ChanType { - if x == nil { - return nil - } - cp := *x - cp.Value = copyExpr(x.Value) - return &cp -} - -// BlockStmt returns x deep copy. -// Copy of nil argument is nil. -func BlockStmt(x *ast.BlockStmt) *ast.BlockStmt { - if x == nil { - return nil - } - cp := *x - cp.List = StmtList(x.List) - return &cp -} - -// ImportSpec returns x deep copy. -// Copy of nil argument is nil. -func ImportSpec(x *ast.ImportSpec) *ast.ImportSpec { - if x == nil { - return nil - } - cp := *x - cp.Name = Ident(x.Name) - cp.Path = BasicLit(x.Path) - cp.Doc = CommentGroup(x.Doc) - cp.Comment = CommentGroup(x.Comment) - return &cp -} - -// ValueSpec returns x deep copy. -// Copy of nil argument is nil. -func ValueSpec(x *ast.ValueSpec) *ast.ValueSpec { - if x == nil { - return nil - } - cp := *x - cp.Names = IdentList(x.Names) - cp.Values = ExprList(x.Values) - cp.Type = copyExpr(x.Type) - cp.Doc = CommentGroup(x.Doc) - cp.Comment = CommentGroup(x.Comment) - return &cp -} - -// Spec returns x deep copy. -// Copy of nil argument is nil. -func Spec(x ast.Spec) ast.Spec { - if x == nil { - return nil - } - - switch x := x.(type) { - case *ast.ImportSpec: - return ImportSpec(x) - case *ast.ValueSpec: - return ValueSpec(x) - case *ast.TypeSpec: - return TypeSpec(x) - default: - panic("unhandled spec") - } -} - -// SpecList returns xs spec slice deep copy. -// Copy of nil argument is nil. -func SpecList(xs []ast.Spec) []ast.Spec { - if xs == nil { - return nil - } - cp := make([]ast.Spec, len(xs)) - for i := range xs { - cp[i] = Spec(xs[i]) - } - return cp -} - -// BadStmt returns x deep copy. -// Copy of nil argument is nil. -func BadStmt(x *ast.BadStmt) *ast.BadStmt { - if x == nil { - return nil - } - cp := *x - return &cp -} - -// DeclStmt returns x deep copy. -// Copy of nil argument is nil. -func DeclStmt(x *ast.DeclStmt) *ast.DeclStmt { - if x == nil { - return nil - } - cp := *x - cp.Decl = copyDecl(x.Decl) - return &cp -} - -// EmptyStmt returns x deep copy. -// Copy of nil argument is nil. -func EmptyStmt(x *ast.EmptyStmt) *ast.EmptyStmt { - if x == nil { - return nil - } - cp := *x - return &cp -} - -// LabeledStmt returns x deep copy. -// Copy of nil argument is nil. -func LabeledStmt(x *ast.LabeledStmt) *ast.LabeledStmt { - if x == nil { - return nil - } - cp := *x - cp.Label = Ident(x.Label) - cp.Stmt = copyStmt(x.Stmt) - return &cp -} - -// ExprStmt returns x deep copy. -// Copy of nil argument is nil. -func ExprStmt(x *ast.ExprStmt) *ast.ExprStmt { - if x == nil { - return nil - } - cp := *x - cp.X = copyExpr(x.X) - return &cp -} - -// SendStmt returns x deep copy. -// Copy of nil argument is nil. -func SendStmt(x *ast.SendStmt) *ast.SendStmt { - if x == nil { - return nil - } - cp := *x - cp.Chan = copyExpr(x.Chan) - cp.Value = copyExpr(x.Value) - return &cp -} - -// IncDecStmt returns x deep copy. -// Copy of nil argument is nil. -func IncDecStmt(x *ast.IncDecStmt) *ast.IncDecStmt { - if x == nil { - return nil - } - cp := *x - cp.X = copyExpr(x.X) - return &cp -} - -// AssignStmt returns x deep copy. -// Copy of nil argument is nil. -func AssignStmt(x *ast.AssignStmt) *ast.AssignStmt { - if x == nil { - return nil - } - cp := *x - cp.Lhs = ExprList(x.Lhs) - cp.Rhs = ExprList(x.Rhs) - return &cp -} - -// GoStmt returns x deep copy. -// Copy of nil argument is nil. -func GoStmt(x *ast.GoStmt) *ast.GoStmt { - if x == nil { - return nil - } - cp := *x - cp.Call = CallExpr(x.Call) - return &cp -} - -// DeferStmt returns x deep copy. -// Copy of nil argument is nil. -func DeferStmt(x *ast.DeferStmt) *ast.DeferStmt { - if x == nil { - return nil - } - cp := *x - cp.Call = CallExpr(x.Call) - return &cp -} - -// ReturnStmt returns x deep copy. -// Copy of nil argument is nil. -func ReturnStmt(x *ast.ReturnStmt) *ast.ReturnStmt { - if x == nil { - return nil - } - cp := *x - cp.Results = ExprList(x.Results) - return &cp -} - -// BranchStmt returns x deep copy. -// Copy of nil argument is nil. -func BranchStmt(x *ast.BranchStmt) *ast.BranchStmt { - if x == nil { - return nil - } - cp := *x - cp.Label = Ident(x.Label) - return &cp -} - -// IfStmt returns x deep copy. -// Copy of nil argument is nil. -func IfStmt(x *ast.IfStmt) *ast.IfStmt { - if x == nil { - return nil - } - cp := *x - cp.Init = copyStmt(x.Init) - cp.Cond = copyExpr(x.Cond) - cp.Body = BlockStmt(x.Body) - cp.Else = copyStmt(x.Else) - return &cp -} - -// CaseClause returns x deep copy. -// Copy of nil argument is nil. -func CaseClause(x *ast.CaseClause) *ast.CaseClause { - if x == nil { - return nil - } - cp := *x - cp.List = ExprList(x.List) - cp.Body = StmtList(x.Body) - return &cp -} - -// SwitchStmt returns x deep copy. -// Copy of nil argument is nil. -func SwitchStmt(x *ast.SwitchStmt) *ast.SwitchStmt { - if x == nil { - return nil - } - cp := *x - cp.Init = copyStmt(x.Init) - cp.Tag = copyExpr(x.Tag) - cp.Body = BlockStmt(x.Body) - return &cp -} - -// TypeSwitchStmt returns x deep copy. -// Copy of nil argument is nil. -func TypeSwitchStmt(x *ast.TypeSwitchStmt) *ast.TypeSwitchStmt { - if x == nil { - return nil - } - cp := *x - cp.Init = copyStmt(x.Init) - cp.Assign = copyStmt(x.Assign) - cp.Body = BlockStmt(x.Body) - return &cp -} - -// CommClause returns x deep copy. -// Copy of nil argument is nil. -func CommClause(x *ast.CommClause) *ast.CommClause { - if x == nil { - return nil - } - cp := *x - cp.Comm = copyStmt(x.Comm) - cp.Body = StmtList(x.Body) - return &cp -} - -// SelectStmt returns x deep copy. -// Copy of nil argument is nil. -func SelectStmt(x *ast.SelectStmt) *ast.SelectStmt { - if x == nil { - return nil - } - cp := *x - cp.Body = BlockStmt(x.Body) - return &cp -} - -// ForStmt returns x deep copy. -// Copy of nil argument is nil. -func ForStmt(x *ast.ForStmt) *ast.ForStmt { - if x == nil { - return nil - } - cp := *x - cp.Init = copyStmt(x.Init) - cp.Cond = copyExpr(x.Cond) - cp.Post = copyStmt(x.Post) - cp.Body = BlockStmt(x.Body) - return &cp -} - -// RangeStmt returns x deep copy. -// Copy of nil argument is nil. -func RangeStmt(x *ast.RangeStmt) *ast.RangeStmt { - if x == nil { - return nil - } - cp := *x - cp.Key = copyExpr(x.Key) - cp.Value = copyExpr(x.Value) - cp.X = copyExpr(x.X) - cp.Body = BlockStmt(x.Body) - return &cp -} - -// Comment returns x deep copy. -// Copy of nil argument is nil. -func Comment(x *ast.Comment) *ast.Comment { - if x == nil { - return nil - } - cp := *x - return &cp -} - -// CommentGroup returns x deep copy. -// Copy of nil argument is nil. -func CommentGroup(x *ast.CommentGroup) *ast.CommentGroup { - if x == nil { - return nil - } - cp := *x - if x.List != nil { - cp.List = make([]*ast.Comment, len(x.List)) - for i := range x.List { - cp.List[i] = Comment(x.List[i]) - } - } - return &cp -} - -// File returns x deep copy. -// Copy of nil argument is nil. -func File(x *ast.File) *ast.File { - if x == nil { - return nil - } - cp := *x - cp.Doc = CommentGroup(x.Doc) - cp.Name = Ident(x.Name) - cp.Decls = DeclList(x.Decls) - cp.Imports = make([]*ast.ImportSpec, len(x.Imports)) - for i := range x.Imports { - cp.Imports[i] = ImportSpec(x.Imports[i]) - } - cp.Unresolved = IdentList(x.Unresolved) - cp.Comments = make([]*ast.CommentGroup, len(x.Comments)) - for i := range x.Comments { - cp.Comments[i] = CommentGroup(x.Comments[i]) - } - return &cp -} - -// Package returns x deep copy. -// Copy of nil argument is nil. -func Package(x *ast.Package) *ast.Package { - if x == nil { - return nil - } - cp := *x - cp.Files = make(map[string]*ast.File) - for filename, f := range x.Files { - cp.Files[filename] = f - } - return &cp -} - -// BadDecl returns x deep copy. -// Copy of nil argument is nil. -func BadDecl(x *ast.BadDecl) *ast.BadDecl { - if x == nil { - return nil - } - cp := *x - return &cp -} - -// GenDecl returns x deep copy. -// Copy of nil argument is nil. -func GenDecl(x *ast.GenDecl) *ast.GenDecl { - if x == nil { - return nil - } - cp := *x - cp.Specs = SpecList(x.Specs) - cp.Doc = CommentGroup(x.Doc) - return &cp -} - -// FuncDecl returns x deep copy. -// Copy of nil argument is nil. -func FuncDecl(x *ast.FuncDecl) *ast.FuncDecl { - if x == nil { - return nil - } - cp := *x - cp.Recv = FieldList(x.Recv) - cp.Name = Ident(x.Name) - cp.Type = FuncType(x.Type) - cp.Body = BlockStmt(x.Body) - cp.Doc = CommentGroup(x.Doc) - return &cp -} - -func copyNode(x ast.Node) ast.Node { - switch x := x.(type) { - case ast.Expr: - return copyExpr(x) - case ast.Stmt: - return copyStmt(x) - case ast.Decl: - return copyDecl(x) - - case ast.Spec: - return Spec(x) - case *ast.FieldList: - return FieldList(x) - case *ast.Comment: - return Comment(x) - case *ast.CommentGroup: - return CommentGroup(x) - case *ast.File: - return File(x) - case *ast.Package: - return Package(x) - - default: - panic("unhandled node") - } -} - -func copyExpr(x ast.Expr) ast.Expr { - if x == nil { - return nil - } - - switch x := x.(type) { - case *ast.BadExpr: - return BadExpr(x) - case *ast.Ident: - return Ident(x) - case *ast.Ellipsis: - return Ellipsis(x) - case *ast.BasicLit: - return BasicLit(x) - case *ast.FuncLit: - return FuncLit(x) - case *ast.CompositeLit: - return CompositeLit(x) - case *ast.ParenExpr: - return ParenExpr(x) - case *ast.SelectorExpr: - return SelectorExpr(x) - case *ast.IndexExpr: - return IndexExpr(x) - case *typeparams.IndexListExpr: - return IndexListExpr(x) - case *ast.SliceExpr: - return SliceExpr(x) - case *ast.TypeAssertExpr: - return TypeAssertExpr(x) - case *ast.CallExpr: - return CallExpr(x) - case *ast.StarExpr: - return StarExpr(x) - case *ast.UnaryExpr: - return UnaryExpr(x) - case *ast.BinaryExpr: - return BinaryExpr(x) - case *ast.KeyValueExpr: - return KeyValueExpr(x) - case *ast.ArrayType: - return ArrayType(x) - case *ast.StructType: - return StructType(x) - case *ast.FuncType: - return FuncType(x) - case *ast.InterfaceType: - return InterfaceType(x) - case *ast.MapType: - return MapType(x) - case *ast.ChanType: - return ChanType(x) - - default: - panic("unhandled expr") - } -} - -func copyStmt(x ast.Stmt) ast.Stmt { - if x == nil { - return nil - } - - switch x := x.(type) { - case *ast.BadStmt: - return BadStmt(x) - case *ast.DeclStmt: - return DeclStmt(x) - case *ast.EmptyStmt: - return EmptyStmt(x) - case *ast.LabeledStmt: - return LabeledStmt(x) - case *ast.ExprStmt: - return ExprStmt(x) - case *ast.SendStmt: - return SendStmt(x) - case *ast.IncDecStmt: - return IncDecStmt(x) - case *ast.AssignStmt: - return AssignStmt(x) - case *ast.GoStmt: - return GoStmt(x) - case *ast.DeferStmt: - return DeferStmt(x) - case *ast.ReturnStmt: - return ReturnStmt(x) - case *ast.BranchStmt: - return BranchStmt(x) - case *ast.BlockStmt: - return BlockStmt(x) - case *ast.IfStmt: - return IfStmt(x) - case *ast.CaseClause: - return CaseClause(x) - case *ast.SwitchStmt: - return SwitchStmt(x) - case *ast.TypeSwitchStmt: - return TypeSwitchStmt(x) - case *ast.CommClause: - return CommClause(x) - case *ast.SelectStmt: - return SelectStmt(x) - case *ast.ForStmt: - return ForStmt(x) - case *ast.RangeStmt: - return RangeStmt(x) - - default: - panic("unhandled stmt") - } -} - -func copyDecl(x ast.Decl) ast.Decl { - if x == nil { - return nil - } - - switch x := x.(type) { - case *ast.BadDecl: - return BadDecl(x) - case *ast.GenDecl: - return GenDecl(x) - case *ast.FuncDecl: - return FuncDecl(x) - - default: - panic("unhandled decl") - } -} diff --git a/vendor/github.com/go-toolsmith/astcopy/astcopy_go117.go b/vendor/github.com/go-toolsmith/astcopy/astcopy_go117.go deleted file mode 100644 index 1b748bae50..0000000000 --- a/vendor/github.com/go-toolsmith/astcopy/astcopy_go117.go +++ /dev/null @@ -1,30 +0,0 @@ -//go:build !go1.18 -// +build !go1.18 - -package astcopy - -// FuncType returns x deep copy. -// Copy of nil argument is nil. -func FuncType(x *ast.FuncType) *ast.FuncType { - if x == nil { - return nil - } - cp := *x - cp.Params = FieldList(x.Params) - cp.Results = FieldList(x.Results) - return &cp -} - -// TypeSpec returns x deep copy. -// Copy of nil argument is nil. -func TypeSpec(x *ast.TypeSpec) *ast.TypeSpec { - if x == nil { - return nil - } - cp := *x - cp.Name = Ident(x.Name) - cp.Type = copyExpr(x.Type) - cp.Doc = CommentGroup(x.Doc) - cp.Comment = CommentGroup(x.Comment) - return &cp -} diff --git a/vendor/github.com/go-toolsmith/astcopy/astcopy_go118.go b/vendor/github.com/go-toolsmith/astcopy/astcopy_go118.go deleted file mode 100644 index 72f800acc1..0000000000 --- a/vendor/github.com/go-toolsmith/astcopy/astcopy_go118.go +++ /dev/null @@ -1,36 +0,0 @@ -//go:build go1.18 -// +build go1.18 - -package astcopy - -import ( - "go/ast" -) - -// FuncType returns x deep copy. -// Copy of nil argument is nil. -func FuncType(x *ast.FuncType) *ast.FuncType { - if x == nil { - return nil - } - cp := *x - cp.Params = FieldList(x.Params) - cp.Results = FieldList(x.Results) - cp.TypeParams = FieldList(x.TypeParams) - return &cp -} - -// TypeSpec returns x deep copy. -// Copy of nil argument is nil. -func TypeSpec(x *ast.TypeSpec) *ast.TypeSpec { - if x == nil { - return nil - } - cp := *x - cp.Name = Ident(x.Name) - cp.Type = copyExpr(x.Type) - cp.Doc = CommentGroup(x.Doc) - cp.Comment = CommentGroup(x.Comment) - cp.TypeParams = FieldList(x.TypeParams) - return &cp -} diff --git a/vendor/github.com/go-toolsmith/astequal/.gitignore b/vendor/github.com/go-toolsmith/astequal/.gitignore deleted file mode 100644 index f38c2b852f..0000000000 --- a/vendor/github.com/go-toolsmith/astequal/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -bin -pkg -src/main -tmp - diff --git a/vendor/github.com/go-toolsmith/astequal/LICENSE b/vendor/github.com/go-toolsmith/astequal/LICENSE deleted file mode 100644 index 717f894f52..0000000000 --- a/vendor/github.com/go-toolsmith/astequal/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2017 Iskander Sharipov / Quasilyte - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/go-toolsmith/astequal/README.md b/vendor/github.com/go-toolsmith/astequal/README.md deleted file mode 100644 index db5e3a8c97..0000000000 --- a/vendor/github.com/go-toolsmith/astequal/README.md +++ /dev/null @@ -1,82 +0,0 @@ -# astequal - -[![build-img]][build-url] -[![pkg-img]][pkg-url] -[![reportcard-img]][reportcard-url] -[![version-img]][version-url] - -Package `astequal` provides AST (deep) equallity check operations. - -## Installation: - -Go version 1.16+ - -```bash -go get github.com/go-toolsmith/astequal -``` - -## Example - -```go -package main - -import ( - "fmt" - "go/ast" - "go/parser" - "go/token" - "log" - "reflect" - - "github.com/go-toolsmith/astequal" -) - -func main() { - const code = ` - package foo - - func main() { - x := []int{1, 2, 3} - x := []int{1, 2, 3} - }` - - fset := token.NewFileSet() - pkg, err := parser.ParseFile(fset, "string", code, 0) - if err != nil { - log.Fatalf("parse error: %+v", err) - } - - fn := pkg.Decls[0].(*ast.FuncDecl) - x := fn.Body.List[0] - y := fn.Body.List[1] - - // Reflect DeepEqual will fail due to different Pos values. - // astequal only checks whether two nodes describe AST. - fmt.Println(reflect.DeepEqual(x, y)) // => false - fmt.Println(astequal.Node(x, y)) // => true - fmt.Println(astequal.Stmt(x, y)) // => true -} -``` - -## Performance - -`astequal` outperforms reflection-based comparison by a big margin: - -``` -BenchmarkEqualExpr/astequal.Expr-8 5000000 298 ns/op 0 B/op 0 allocs/op -BenchmarkEqualExpr/astequal.Node-8 3000000 409 ns/op 0 B/op 0 allocs/op -BenchmarkEqualExpr/reflect.DeepEqual-8 50000 38898 ns/op 10185 B/op 156 allocs/op -``` - -## License - -[MIT License](LICENSE). - -[build-img]: https://github.com/go-toolsmith/astequal/workflows/build/badge.svg -[build-url]: https://github.com/go-toolsmith/astequal/actions -[pkg-img]: https://pkg.go.dev/badge/go-toolsmith/astequal -[pkg-url]: https://pkg.go.dev/github.com/go-toolsmith/astequal -[reportcard-img]: https://goreportcard.com/badge/go-toolsmith/astequal -[reportcard-url]: https://goreportcard.com/report/go-toolsmith/astequal -[version-img]: https://img.shields.io/github/v/release/go-toolsmith/astequal -[version-url]: https://github.com/go-toolsmith/astequal/releases diff --git a/vendor/github.com/go-toolsmith/astequal/astequal.go b/vendor/github.com/go-toolsmith/astequal/astequal.go deleted file mode 100644 index d1a04e9427..0000000000 --- a/vendor/github.com/go-toolsmith/astequal/astequal.go +++ /dev/null @@ -1,771 +0,0 @@ -// Package astequal provides AST (deep) equallity check operations. -package astequal - -import ( - "go/ast" - "go/token" -) - -// Node reports whether two AST nodes are structurally (deep) equal. -// -// Nil arguments are permitted: true is returned if x and y are both nils. -// -// See also: Expr, Stmt, Decl functions. -func Node(x, y ast.Node) bool { - return astNodeEq(x, y) -} - -// Expr reports whether two AST expressions are structurally (deep) equal. -// -// Nil arguments are permitted: true is returned if x and y are both nils. -// ast.BadExpr comparison always yields false. -func Expr(x, y ast.Expr) bool { - return astExprEq(x, y) -} - -// Stmt reports whether two AST statements are structurally (deep) equal. -// -// Nil arguments are permitted: true is returned if x and y are both nils. -// ast.BadStmt comparison always yields false. -func Stmt(x, y ast.Stmt) bool { - return astStmtEq(x, y) -} - -// Decl reports whether two AST declarations are structurally (deep) equal. -// -// Nil arguments are permitted: true is returned if x and y are both nils. -// ast.BadDecl comparison always yields false. -func Decl(x, y ast.Decl) bool { - return astDeclEq(x, y) -} - -// Functions to perform deep equallity checks between arbitrary AST nodes. - -// Compare interface node types. -// -// Interfaces, as well as their values, can be nil. -// -// Even if AST does expect field X to be mandatory, -// nil checks are required as nodes can be constructed -// manually, or be partially invalid/incomplete. - -func astNodeEq(x, y ast.Node) bool { - switch x := x.(type) { - case ast.Expr: - y, ok := y.(ast.Expr) - return ok && astExprEq(x, y) - case ast.Stmt: - y, ok := y.(ast.Stmt) - return ok && astStmtEq(x, y) - case ast.Decl: - y, ok := y.(ast.Decl) - return ok && astDeclEq(x, y) - - case *ast.Field: - y, ok := y.(*ast.Field) - return ok && astFieldEq(x, y) - case *ast.FieldList: - y, ok := y.(*ast.FieldList) - return ok && astFieldListEq(x, y) - - default: - return false - } -} - -func astExprEq(x, y ast.Expr) bool { - if x == nil || y == nil { - return x == y - } - - switch x := x.(type) { - case *ast.Ident: - y, ok := y.(*ast.Ident) - return ok && astIdentEq(x, y) - - case *ast.BasicLit: - y, ok := y.(*ast.BasicLit) - return ok && astBasicLitEq(x, y) - - case *ast.FuncLit: - y, ok := y.(*ast.FuncLit) - return ok && astFuncLitEq(x, y) - - case *ast.CompositeLit: - y, ok := y.(*ast.CompositeLit) - return ok && astCompositeLitEq(x, y) - - case *ast.ParenExpr: - y, ok := y.(*ast.ParenExpr) - return ok && astParenExprEq(x, y) - - case *ast.SelectorExpr: - y, ok := y.(*ast.SelectorExpr) - return ok && astSelectorExprEq(x, y) - - case *ast.IndexExpr: - y, ok := y.(*ast.IndexExpr) - return ok && astIndexExprEq(x, y) - - case *ast.IndexListExpr: - y, ok := y.(*ast.IndexListExpr) - return ok && astIndexListExprEq(x, y) - - case *ast.SliceExpr: - y, ok := y.(*ast.SliceExpr) - return ok && astSliceExprEq(x, y) - - case *ast.TypeAssertExpr: - y, ok := y.(*ast.TypeAssertExpr) - return ok && astTypeAssertExprEq(x, y) - - case *ast.CallExpr: - y, ok := y.(*ast.CallExpr) - return ok && astCallExprEq(x, y) - - case *ast.StarExpr: - y, ok := y.(*ast.StarExpr) - return ok && astStarExprEq(x, y) - - case *ast.UnaryExpr: - y, ok := y.(*ast.UnaryExpr) - return ok && astUnaryExprEq(x, y) - - case *ast.BinaryExpr: - y, ok := y.(*ast.BinaryExpr) - return ok && astBinaryExprEq(x, y) - - case *ast.KeyValueExpr: - y, ok := y.(*ast.KeyValueExpr) - return ok && astKeyValueExprEq(x, y) - - case *ast.ArrayType: - y, ok := y.(*ast.ArrayType) - return ok && astArrayTypeEq(x, y) - - case *ast.StructType: - y, ok := y.(*ast.StructType) - return ok && astStructTypeEq(x, y) - - case *ast.FuncType: - y, ok := y.(*ast.FuncType) - return ok && astFuncTypeEq(x, y) - - case *ast.InterfaceType: - y, ok := y.(*ast.InterfaceType) - return ok && astInterfaceTypeEq(x, y) - - case *ast.MapType: - y, ok := y.(*ast.MapType) - return ok && astMapTypeEq(x, y) - - case *ast.ChanType: - y, ok := y.(*ast.ChanType) - return ok && astChanTypeEq(x, y) - - case *ast.Ellipsis: - y, ok := y.(*ast.Ellipsis) - return ok && astEllipsisEq(x, y) - - default: - return false - } -} - -func astStmtEq(x, y ast.Stmt) bool { - if x == nil || y == nil { - return x == y - } - - switch x := x.(type) { - case *ast.ExprStmt: - y, ok := y.(*ast.ExprStmt) - return ok && astExprStmtEq(x, y) - - case *ast.SendStmt: - y, ok := y.(*ast.SendStmt) - return ok && astSendStmtEq(x, y) - - case *ast.IncDecStmt: - y, ok := y.(*ast.IncDecStmt) - return ok && astIncDecStmtEq(x, y) - - case *ast.AssignStmt: - y, ok := y.(*ast.AssignStmt) - return ok && astAssignStmtEq(x, y) - - case *ast.GoStmt: - y, ok := y.(*ast.GoStmt) - return ok && astGoStmtEq(x, y) - - case *ast.DeferStmt: - y, ok := y.(*ast.DeferStmt) - return ok && astDeferStmtEq(x, y) - - case *ast.ReturnStmt: - y, ok := y.(*ast.ReturnStmt) - return ok && astReturnStmtEq(x, y) - - case *ast.BranchStmt: - y, ok := y.(*ast.BranchStmt) - return ok && astBranchStmtEq(x, y) - - case *ast.BlockStmt: - y, ok := y.(*ast.BlockStmt) - return ok && astBlockStmtEq(x, y) - - case *ast.IfStmt: - y, ok := y.(*ast.IfStmt) - return ok && astIfStmtEq(x, y) - - case *ast.CaseClause: - y, ok := y.(*ast.CaseClause) - return ok && astCaseClauseEq(x, y) - - case *ast.SwitchStmt: - y, ok := y.(*ast.SwitchStmt) - return ok && astSwitchStmtEq(x, y) - - case *ast.TypeSwitchStmt: - y, ok := y.(*ast.TypeSwitchStmt) - return ok && astTypeSwitchStmtEq(x, y) - - case *ast.CommClause: - y, ok := y.(*ast.CommClause) - return ok && astCommClauseEq(x, y) - - case *ast.SelectStmt: - y, ok := y.(*ast.SelectStmt) - return ok && astSelectStmtEq(x, y) - - case *ast.ForStmt: - y, ok := y.(*ast.ForStmt) - return ok && astForStmtEq(x, y) - - case *ast.RangeStmt: - y, ok := y.(*ast.RangeStmt) - return ok && astRangeStmtEq(x, y) - - case *ast.DeclStmt: - y, ok := y.(*ast.DeclStmt) - return ok && astDeclStmtEq(x, y) - - case *ast.LabeledStmt: - y, ok := y.(*ast.LabeledStmt) - return ok && astLabeledStmtEq(x, y) - - case *ast.EmptyStmt: - y, ok := y.(*ast.EmptyStmt) - return ok && astEmptyStmtEq(x, y) - - default: - return false - } -} - -func astDeclEq(x, y ast.Decl) bool { - if x == nil || y == nil { - return x == y - } - - switch x := x.(type) { - case *ast.GenDecl: - y, ok := y.(*ast.GenDecl) - return ok && astGenDeclEq(x, y) - - case *ast.FuncDecl: - y, ok := y.(*ast.FuncDecl) - return ok && astFuncDeclEq(x, y) - - default: - return false - } -} - -// Compare concrete nodes for equallity. -// -// Any node of pointer type permitted to be nil, -// hence nil checks are mandatory. - -func astIdentEq(x, y *ast.Ident) bool { - if x == nil || y == nil { - return x == y - } - return x.Name == y.Name -} - -func astKeyValueExprEq(x, y *ast.KeyValueExpr) bool { - if x == nil || y == nil { - return x == y - } - return astExprEq(x.Key, y.Key) && astExprEq(x.Value, y.Value) -} - -func astArrayTypeEq(x, y *ast.ArrayType) bool { - if x == nil || y == nil { - return x == y - } - return astExprEq(x.Len, y.Len) && astExprEq(x.Elt, y.Elt) -} - -func astStructTypeEq(x, y *ast.StructType) bool { - if x == nil || y == nil { - return x == y - } - return astFieldListEq(x.Fields, y.Fields) -} - -func astFuncTypeEq(x, y *ast.FuncType) bool { - if x == nil || y == nil { - return x == y - } - return astFieldListEq(x.Params, y.Params) && - astFieldListEq(x.Results, y.Results) && - astFieldListEq(forFuncType(x), forFuncType(y)) -} - -func astBasicLitEq(x, y *ast.BasicLit) bool { - if x == nil || y == nil { - return x == y - } - return x.Kind == y.Kind && x.Value == y.Value -} - -func astBlockStmtEq(x, y *ast.BlockStmt) bool { - if x == nil || y == nil { - return x == y - } - return astStmtSliceEq(x.List, y.List) -} - -func astFieldEq(x, y *ast.Field) bool { - if x == nil || y == nil { - return x == y - } - return astIdentSliceEq(x.Names, y.Names) && - astExprEq(x.Type, y.Type) -} - -func astFuncLitEq(x, y *ast.FuncLit) bool { - if x == nil || y == nil { - return x == y - } - return astFuncTypeEq(x.Type, y.Type) && - astBlockStmtEq(x.Body, y.Body) -} - -func astCompositeLitEq(x, y *ast.CompositeLit) bool { - if x == nil || y == nil { - return x == y - } - return astExprEq(x.Type, y.Type) && - astExprSliceEq(x.Elts, y.Elts) -} - -func astSelectorExprEq(x, y *ast.SelectorExpr) bool { - if x == nil || y == nil { - return x == y - } - return astExprEq(x.X, y.X) && astIdentEq(x.Sel, y.Sel) -} - -func astIndexExprEq(x, y *ast.IndexExpr) bool { - if x == nil || y == nil { - return x == y - } - return astExprEq(x.X, y.X) && astExprEq(x.Index, y.Index) -} - -func astIndexListExprEq(x, y *ast.IndexListExpr) bool { - if x == nil || y == nil { - return x == y - } - return astExprEq(x.X, y.X) && astExprSliceEq(x.Indices, y.Indices) -} - -func astSliceExprEq(x, y *ast.SliceExpr) bool { - if x == nil || y == nil { - return x == y - } - return astExprEq(x.X, y.X) && - astExprEq(x.Low, y.Low) && - astExprEq(x.High, y.High) && - astExprEq(x.Max, y.Max) -} - -func astTypeAssertExprEq(x, y *ast.TypeAssertExpr) bool { - if x == nil || y == nil { - return x == y - } - return astExprEq(x.X, y.X) && astExprEq(x.Type, y.Type) -} - -func astInterfaceTypeEq(x, y *ast.InterfaceType) bool { - if x == nil || y == nil { - return x == y - } - return astFieldListEq(x.Methods, y.Methods) -} - -func astMapTypeEq(x, y *ast.MapType) bool { - if x == nil || y == nil { - return x == y - } - return astExprEq(x.Key, y.Key) && astExprEq(x.Value, y.Value) -} - -func astChanTypeEq(x, y *ast.ChanType) bool { - if x == nil || y == nil { - return x == y - } - return x.Dir == y.Dir && astExprEq(x.Value, y.Value) -} - -func astCallExprEq(x, y *ast.CallExpr) bool { - if x == nil || y == nil { - return x == y - } - return astExprEq(x.Fun, y.Fun) && - astExprSliceEq(x.Args, y.Args) && - (x.Ellipsis == 0) == (y.Ellipsis == 0) -} - -func astEllipsisEq(x, y *ast.Ellipsis) bool { - if x == nil || y == nil { - return x == y - } - return astExprEq(x.Elt, y.Elt) -} - -func astUnaryExprEq(x, y *ast.UnaryExpr) bool { - if x == nil || y == nil { - return x == y - } - return x.Op == y.Op && astExprEq(x.X, y.X) -} - -func astBinaryExprEq(x, y *ast.BinaryExpr) bool { - if x == nil || y == nil { - return x == y - } - return x.Op == y.Op && - astExprEq(x.X, y.X) && - astExprEq(x.Y, y.Y) -} - -func astParenExprEq(x, y *ast.ParenExpr) bool { - if x == nil || y == nil { - return x == y - } - return astExprEq(x.X, y.X) -} - -func astStarExprEq(x, y *ast.StarExpr) bool { - if x == nil || y == nil { - return x == y - } - return astExprEq(x.X, y.X) -} - -func astFieldListEq(x, y *ast.FieldList) bool { - if x == nil || y == nil { - return x == y - } - return astFieldSliceEq(x.List, y.List) -} - -func astEmptyStmtEq(x, y *ast.EmptyStmt) bool { - if x == nil || y == nil { - return x == y - } - return x.Implicit == y.Implicit -} - -func astLabeledStmtEq(x, y *ast.LabeledStmt) bool { - if x == nil || y == nil { - return x == y - } - return astIdentEq(x.Label, y.Label) && astStmtEq(x.Stmt, y.Stmt) -} - -func astExprStmtEq(x, y *ast.ExprStmt) bool { - if x == nil || y == nil { - return x == y - } - return astExprEq(x.X, y.X) -} - -func astSendStmtEq(x, y *ast.SendStmt) bool { - if x == nil || y == nil { - return x == y - } - return astExprEq(x.Chan, y.Chan) && astExprEq(x.Value, y.Value) -} - -func astDeclStmtEq(x, y *ast.DeclStmt) bool { - if x == nil || y == nil { - return x == y - } - return astDeclEq(x.Decl, y.Decl) -} - -func astIncDecStmtEq(x, y *ast.IncDecStmt) bool { - if x == nil || y == nil { - return x == y - } - return x.Tok == y.Tok && astExprEq(x.X, y.X) -} - -func astAssignStmtEq(x, y *ast.AssignStmt) bool { - if x == nil || y == nil { - return x == y - } - return x.Tok == y.Tok && - astExprSliceEq(x.Lhs, y.Lhs) && - astExprSliceEq(x.Rhs, y.Rhs) -} - -func astGoStmtEq(x, y *ast.GoStmt) bool { - if x == nil || y == nil { - return x == y - } - return astCallExprEq(x.Call, y.Call) -} - -func astDeferStmtEq(x, y *ast.DeferStmt) bool { - if x == nil || y == nil { - return x == y - } - return astCallExprEq(x.Call, y.Call) -} - -func astReturnStmtEq(x, y *ast.ReturnStmt) bool { - if x == nil || y == nil { - return x == y - } - return astExprSliceEq(x.Results, y.Results) -} - -func astBranchStmtEq(x, y *ast.BranchStmt) bool { - if x == nil || y == nil { - return x == y - } - return x.Tok == y.Tok && astIdentEq(x.Label, y.Label) -} - -func astIfStmtEq(x, y *ast.IfStmt) bool { - if x == nil || y == nil { - return x == y - } - return astStmtEq(x.Init, y.Init) && - astExprEq(x.Cond, y.Cond) && - astBlockStmtEq(x.Body, y.Body) && - astStmtEq(x.Else, y.Else) -} - -func astCaseClauseEq(x, y *ast.CaseClause) bool { - if x == nil || y == nil { - return x == y - } - return astExprSliceEq(x.List, y.List) && - astStmtSliceEq(x.Body, y.Body) -} - -func astSwitchStmtEq(x, y *ast.SwitchStmt) bool { - if x == nil || y == nil { - return x == y - } - return astStmtEq(x.Init, y.Init) && - astExprEq(x.Tag, y.Tag) && - astBlockStmtEq(x.Body, y.Body) -} - -func astTypeSwitchStmtEq(x, y *ast.TypeSwitchStmt) bool { - if x == nil || y == nil { - return x == y - } - return astStmtEq(x.Init, y.Init) && - astStmtEq(x.Assign, y.Assign) && - astBlockStmtEq(x.Body, y.Body) -} - -func astCommClauseEq(x, y *ast.CommClause) bool { - if x == nil || y == nil { - return x == y - } - return astStmtEq(x.Comm, y.Comm) && astStmtSliceEq(x.Body, y.Body) -} - -func astSelectStmtEq(x, y *ast.SelectStmt) bool { - if x == nil || y == nil { - return x == y - } - return astBlockStmtEq(x.Body, y.Body) -} - -func astForStmtEq(x, y *ast.ForStmt) bool { - if x == nil || y == nil { - return x == y - } - return astStmtEq(x.Init, y.Init) && - astExprEq(x.Cond, y.Cond) && - astStmtEq(x.Post, y.Post) && - astBlockStmtEq(x.Body, y.Body) -} - -func astRangeStmtEq(x, y *ast.RangeStmt) bool { - if x == nil || y == nil { - return x == y - } - return x.Tok == y.Tok && - astExprEq(x.Key, y.Key) && - astExprEq(x.Value, y.Value) && - astExprEq(x.X, y.X) && - astBlockStmtEq(x.Body, y.Body) -} - -func astFuncDeclEq(x, y *ast.FuncDecl) bool { - if x == nil || y == nil { - return x == y - } - return astFieldListEq(x.Recv, y.Recv) && - astIdentEq(x.Name, y.Name) && - astFuncTypeEq(x.Type, y.Type) && - astBlockStmtEq(x.Body, y.Body) -} - -func astGenDeclEq(x, y *ast.GenDecl) bool { - if x == nil || y == nil { - return x == y - } - - if x.Tok != y.Tok { - return false - } - if len(x.Specs) != len(y.Specs) { - return false - } - - switch x.Tok { - case token.IMPORT: - for i := range x.Specs { - xspec := x.Specs[i].(*ast.ImportSpec) - yspec := y.Specs[i].(*ast.ImportSpec) - if !astImportSpecEq(xspec, yspec) { - return false - } - } - case token.TYPE: - for i := range x.Specs { - xspec := x.Specs[i].(*ast.TypeSpec) - yspec := y.Specs[i].(*ast.TypeSpec) - if !astTypeSpecEq(xspec, yspec) { - return false - } - } - default: - for i := range x.Specs { - xspec := x.Specs[i].(*ast.ValueSpec) - yspec := y.Specs[i].(*ast.ValueSpec) - if !astValueSpecEq(xspec, yspec) { - return false - } - } - } - - return true -} - -func astImportSpecEq(x, y *ast.ImportSpec) bool { - if x == nil || y == nil { - return x == y - } - return astIdentEq(x.Name, y.Name) && astBasicLitEq(x.Path, y.Path) -} - -func astTypeSpecEq(x, y *ast.TypeSpec) bool { - if x == nil || y == nil { - return x == y - } - return astIdentEq(x.Name, y.Name) && astExprEq(x.Type, y.Type) && - astFieldListEq(forTypeSpec(x), forTypeSpec(y)) -} - -func astValueSpecEq(x, y *ast.ValueSpec) bool { - if x == nil || y == nil { - return x == y - } - return astIdentSliceEq(x.Names, y.Names) && - astExprEq(x.Type, y.Type) && - astExprSliceEq(x.Values, y.Values) -} - -// Compare slices for equallity. -// -// Each slice element that has pointer type permitted to be nil, -// hence instead of using adhoc comparison of values, -// equallity functions that are defined above are used. - -func astIdentSliceEq(xs, ys []*ast.Ident) bool { - if len(xs) != len(ys) { - return false - } - for i := range xs { - if !astIdentEq(xs[i], ys[i]) { - return false - } - } - return true -} - -func astFieldSliceEq(xs, ys []*ast.Field) bool { - if len(xs) != len(ys) { - return false - } - for i := range xs { - if !astFieldEq(xs[i], ys[i]) { - return false - } - } - return true -} - -func astStmtSliceEq(xs, ys []ast.Stmt) bool { - if len(xs) != len(ys) { - return false - } - for i := range xs { - if !astStmtEq(xs[i], ys[i]) { - return false - } - } - return true -} - -func astExprSliceEq(xs, ys []ast.Expr) bool { - if len(xs) != len(ys) { - return false - } - for i := range xs { - if !astExprEq(xs[i], ys[i]) { - return false - } - } - return true -} - -// forTypeSpec returns n.TypeParams. -func forTypeSpec(n *ast.TypeSpec) *ast.FieldList { - if n == nil { - return nil - } - return n.TypeParams -} - -// forFuncType returns n.TypeParams. -func forFuncType(n *ast.FuncType) *ast.FieldList { - if n == nil { - return nil - } - return n.TypeParams -} diff --git a/vendor/github.com/go-toolsmith/astequal/diff.go b/vendor/github.com/go-toolsmith/astequal/diff.go deleted file mode 100644 index cd69b45250..0000000000 --- a/vendor/github.com/go-toolsmith/astequal/diff.go +++ /dev/null @@ -1,23 +0,0 @@ -package astequal - -import ( - "bytes" - "go/ast" - "go/format" - "go/token" - - "github.com/google/go-cmp/cmp" -) - -func Diff(x, y ast.Node) string { - var buf bytes.Buffer - format.Node(&buf, token.NewFileSet(), x) - s1 := buf.String() - - buf.Reset() - format.Node(&buf, token.NewFileSet(), y) - s2 := buf.String() - - // TODO(cristaloleg): replace with a more lightweight diff impl. - return cmp.Diff(s1, s2) -} diff --git a/vendor/github.com/go-toolsmith/astfmt/LICENSE b/vendor/github.com/go-toolsmith/astfmt/LICENSE deleted file mode 100644 index eef17180f8..0000000000 --- a/vendor/github.com/go-toolsmith/astfmt/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2018 go-toolsmith - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/go-toolsmith/astfmt/README.md b/vendor/github.com/go-toolsmith/astfmt/README.md deleted file mode 100644 index 00f790fd2f..0000000000 --- a/vendor/github.com/go-toolsmith/astfmt/README.md +++ /dev/null @@ -1,55 +0,0 @@ -# astfmt - -[![build-img]][build-url] -[![pkg-img]][pkg-url] -[![reportcard-img]][reportcard-url] -[![version-img]][version-url] - -Package `astfmt` implements ast.Node formatting with fmt-like API. - -## Installation - -Go version 1.16+ - -```bash -go get github.com/go-toolsmith/astfmt -``` - -## Example - -```go -package main - -import ( - "go/token" - "os" - - "github.com/go-toolsmith/astfmt" - "github.com/go-toolsmith/strparse" -) - -func Example() { - x := strparse.Expr(`foo(bar(baz(1+2)))`) - // astfmt functions add %s support for ast.Node arguments. - astfmt.Println(x) // => foo(bar(baz(1 + 2))) - astfmt.Fprintf(os.Stdout, "node=%s\n", x) // => node=foo(bar(baz(1 + 2))) - - // Can use specific file set with printer. - fset := token.NewFileSet() // Suppose this fset is used when parsing - pp := astfmt.NewPrinter(fset) - pp.Println(x) // => foo(bar(baz(1 + 2))) -} -``` - -## License - -[MIT License](LICENSE). - -[build-img]: https://github.com/go-toolsmith/astfmt/workflows/build/badge.svg -[build-url]: https://github.com/go-toolsmith/astfmt/actions -[pkg-img]: https://pkg.go.dev/badge/go-toolsmith/astfmt -[pkg-url]: https://pkg.go.dev/github.com/go-toolsmith/astfmt -[reportcard-img]: https://goreportcard.com/badge/go-toolsmith/astfmt -[reportcard-url]: https://goreportcard.com/report/go-toolsmith/astfmt -[version-img]: https://img.shields.io/github/v/release/go-toolsmith/astfmt -[version-url]: https://github.com/go-toolsmith/astfmt/releases diff --git a/vendor/github.com/go-toolsmith/astfmt/astfmt.go b/vendor/github.com/go-toolsmith/astfmt/astfmt.go deleted file mode 100644 index ca993e033f..0000000000 --- a/vendor/github.com/go-toolsmith/astfmt/astfmt.go +++ /dev/null @@ -1,111 +0,0 @@ -// Package astfmt implements `ast.Node` formatting with fmt-like API. -package astfmt - -import ( - "bytes" - "fmt" - "go/ast" - "go/printer" - "go/token" - "io" -) - -// Println calls fmt.Println with additional support of %s format -// for ast.Node arguments. -// -// Uses empty file set for AST printing. -func Println(args ...interface{}) error { - return defaultPrinter.Println(args...) -} - -// Fprintf calls fmt.Fprintf with additional support of %s format -// for ast.Node arguments. -// -// Uses empty file set for AST printing. -func Fprintf(w io.Writer, format string, args ...interface{}) error { - return defaultPrinter.Fprintf(w, format, args...) -} - -// Sprintf calls fmt.Sprintf with additional support of %s format -// for ast.Node arguments. -// -// Uses empty file set for AST printing. -func Sprintf(format string, args ...interface{}) string { - return defaultPrinter.Sprintf(format, args...) -} - -// Sprint calls fmt.Sprint with additional support of %s format -// for ast.Node arguments. -// -// Uses empty file set for AST printing. -func Sprint(args ...interface{}) string { - return defaultPrinter.Sprint(args...) -} - -// NewPrinter returns printer that uses bound file set when printing AST nodes. -func NewPrinter(fset *token.FileSet) *Printer { - return &Printer{fset: fset} -} - -// Printer provides API close to fmt package for printing AST nodes. -// Unlike freestanding functions from this package, it makes it possible -// to associate appropriate file set for better output. -type Printer struct { - fset *token.FileSet -} - -// Println printer method is like Println function, but uses bound file set when printing. -func (p *Printer) Println(args ...interface{}) error { - _, err := fmt.Println(wrapArgs(p.fset, args)...) - return err -} - -// Fprintf printer method is like Fprintf function, but uses bound file set when printing. -func (p *Printer) Fprintf(w io.Writer, format string, args ...interface{}) error { - _, err := fmt.Fprintf(w, format, wrapArgs(p.fset, args)...) - return err -} - -// Sprintf printer method is like Sprintf function, but uses bound file set when printing. -func (p *Printer) Sprintf(format string, args ...interface{}) string { - return fmt.Sprintf(format, wrapArgs(p.fset, args)...) -} - -// Sprint printer method is like Sprint function, but uses bound file set when printing. -func (p *Printer) Sprint(args ...interface{}) string { - return fmt.Sprint(wrapArgs(p.fset, args)...) -} - -// defaultPrinter is used in printing functions like Println. -// Uses empty file set. -var defaultPrinter = NewPrinter(token.NewFileSet()) - -// wrapArgs returns arguments slice with every ast.Node element -// replaced with fmtNode wrapper that supports additional formatting. -func wrapArgs(fset *token.FileSet, args []interface{}) []interface{} { - for i := range args { - if x, ok := args[i].(ast.Node); ok { - args[i] = fmtNode{fset: fset, node: x} - } - } - return args -} - -type fmtNode struct { - fset *token.FileSet - node ast.Node -} - -func (n fmtNode) String() string { - var buf bytes.Buffer - if err := printer.Fprint(&buf, n.fset, n.node); err != nil { - return fmt.Sprintf("%%!s(ast.Node=%s)", err) - } - return buf.String() -} - -func (n fmtNode) GoString() string { - var buf bytes.Buffer - fmt.Fprintf(&buf, "%#v", n.node) - return buf.String() -} diff --git a/vendor/github.com/go-toolsmith/astp/LICENSE b/vendor/github.com/go-toolsmith/astp/LICENSE deleted file mode 100644 index eef17180f8..0000000000 --- a/vendor/github.com/go-toolsmith/astp/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2018 go-toolsmith - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/go-toolsmith/astp/README.md b/vendor/github.com/go-toolsmith/astp/README.md deleted file mode 100644 index cf5197e811..0000000000 --- a/vendor/github.com/go-toolsmith/astp/README.md +++ /dev/null @@ -1,54 +0,0 @@ -# astp - -[![build-img]][build-url] -[![pkg-img]][pkg-url] -[![reportcard-img]][reportcard-url] -[![version-img]][version-url] - -Package `astp` provides AST predicates. - -## Installation: - -Go version 1.16+ - -```bash -go get github.com/go-toolsmith/astp -``` - -## Example - -```go -package main - -import ( - "fmt" - - "github.com/go-toolsmith/astp" - "github.com/go-toolsmith/strparse" -) - -func main() { - if astp.IsIdent(strparse.Expr(`x`)) { - fmt.Println("ident") - } - if astp.IsBlockStmt(strparse.Stmt(`{f()}`)) { - fmt.Println("block stmt") - } - if astp.IsGenDecl(strparse.Decl(`var x int = 10`)) { - fmt.Println("gen decl") - } -} -``` - -## License - -[MIT License](LICENSE). - -[build-img]: https://github.com/go-toolsmith/astp/workflows/build/badge.svg -[build-url]: https://github.com/go-toolsmith/astp/actions -[pkg-img]: https://pkg.go.dev/badge/go-toolsmith/astp -[pkg-url]: https://pkg.go.dev/github.com/go-toolsmith/astp -[reportcard-img]: https://goreportcard.com/badge/go-toolsmith/astp -[reportcard-url]: https://goreportcard.com/report/go-toolsmith/astp -[version-img]: https://img.shields.io/github/v/release/go-toolsmith/astp -[version-url]: https://github.com/go-toolsmith/astp/releases diff --git a/vendor/github.com/go-toolsmith/astp/decl.go b/vendor/github.com/go-toolsmith/astp/decl.go deleted file mode 100644 index 4654ad95cf..0000000000 --- a/vendor/github.com/go-toolsmith/astp/decl.go +++ /dev/null @@ -1,39 +0,0 @@ -package astp - -import "go/ast" - -// IsDecl reports whether a node is a ast.Decl. -func IsDecl(node ast.Node) bool { - _, ok := node.(ast.Decl) - return ok -} - -// IsFuncDecl reports whether a given ast.Node is a function declaration (*ast.FuncDecl). -func IsFuncDecl(node ast.Node) bool { - _, ok := node.(*ast.FuncDecl) - return ok -} - -// IsGenDecl reports whether a given ast.Node is a generic declaration (*ast.GenDecl). -func IsGenDecl(node ast.Node) bool { - _, ok := node.(*ast.GenDecl) - return ok -} - -// IsImportSpec reports whether a given ast.Node is an import declaration (*ast.ImportSpec). -func IsImportSpec(node ast.Node) bool { - _, ok := node.(*ast.ImportSpec) - return ok -} - -// IsValueSpec reports whether a given ast.Node is a value declaration (*ast.ValueSpec). -func IsValueSpec(node ast.Node) bool { - _, ok := node.(*ast.ValueSpec) - return ok -} - -// IsTypeSpec reports whether a given ast.Node is a type declaration (*ast.TypeSpec). -func IsTypeSpec(node ast.Node) bool { - _, ok := node.(*ast.TypeSpec) - return ok -} diff --git a/vendor/github.com/go-toolsmith/astp/expr.go b/vendor/github.com/go-toolsmith/astp/expr.go deleted file mode 100644 index adf9668ce2..0000000000 --- a/vendor/github.com/go-toolsmith/astp/expr.go +++ /dev/null @@ -1,141 +0,0 @@ -package astp - -import "go/ast" - -// IsExpr reports whether a given ast.Node is an expression(ast.Expr). -func IsExpr(node ast.Node) bool { - _, ok := node.(ast.Expr) - return ok -} - -// IsBadExpr reports whether a given ast.Node is a bad expression (*ast.IsBadExpr). -func IsBadExpr(node ast.Node) bool { - _, ok := node.(*ast.BadExpr) - return ok -} - -// IsIdent reports whether a given ast.Node is an identifier (*ast.IsIdent). -func IsIdent(node ast.Node) bool { - _, ok := node.(*ast.Ident) - return ok -} - -// IsEllipsis reports whether a given ast.Node is an `...` (ellipsis) (*ast.IsEllipsis). -func IsEllipsis(node ast.Node) bool { - _, ok := node.(*ast.Ellipsis) - return ok -} - -// IsBasicLit reports whether a given ast.Node is a literal of basic type (*ast.IsBasicLit). -func IsBasicLit(node ast.Node) bool { - _, ok := node.(*ast.BasicLit) - return ok -} - -// IsFuncLit reports whether a given ast.Node is a function literal (*ast.IsFuncLit). -func IsFuncLit(node ast.Node) bool { - _, ok := node.(*ast.FuncLit) - return ok -} - -// IsCompositeLit reports whether a given ast.Node is a composite literal (*ast.IsCompositeLit). -func IsCompositeLit(node ast.Node) bool { - _, ok := node.(*ast.CompositeLit) - return ok -} - -// IsParenExpr reports whether a given ast.Node is a parenthesized expression (*ast.IsParenExpr). -func IsParenExpr(node ast.Node) bool { - _, ok := node.(*ast.ParenExpr) - return ok -} - -// IsSelectorExpr reports whether a given ast.Node is a selector expression (*ast.IsSelectorExpr). -func IsSelectorExpr(node ast.Node) bool { - _, ok := node.(*ast.SelectorExpr) - return ok -} - -// IsIndexExpr reports whether a given ast.Node is an index expression (*ast.IsIndexExpr). -func IsIndexExpr(node ast.Node) bool { - _, ok := node.(*ast.IndexExpr) - return ok -} - -// IsSliceExpr reports whether a given ast.Node is a slice expression (*ast.IsSliceExpr). -func IsSliceExpr(node ast.Node) bool { - _, ok := node.(*ast.SliceExpr) - return ok -} - -// IsTypeAssertExpr reports whether a given ast.Node is a type assert expression (*ast.IsTypeAssertExpr). -func IsTypeAssertExpr(node ast.Node) bool { - _, ok := node.(*ast.TypeAssertExpr) - return ok -} - -// IsCallExpr reports whether a given ast.Node is an expression followed by an argument list (*ast.IsCallExpr). -func IsCallExpr(node ast.Node) bool { - _, ok := node.(*ast.CallExpr) - return ok -} - -// IsStarExpr reports whether a given ast.Node is a star expression(unary "*" or apointer) (*ast.IsStarExpr) -func IsStarExpr(node ast.Node) bool { - _, ok := node.(*ast.StarExpr) - return ok -} - -// IsUnaryExpr reports whether a given ast.Node is a unary expression (*ast.IsUnaryExpr). -func IsUnaryExpr(node ast.Node) bool { - _, ok := node.(*ast.UnaryExpr) - return ok -} - -// IsBinaryExpr reports whether a given ast.Node is a binary expression (*ast.IsBinaryExpr). -func IsBinaryExpr(node ast.Node) bool { - _, ok := node.(*ast.BinaryExpr) - return ok -} - -// IsKeyValueExpr reports whether a given ast.Node is a (key:value) pair (*ast.IsKeyValueExpr). -func IsKeyValueExpr(node ast.Node) bool { - _, ok := node.(*ast.KeyValueExpr) - return ok -} - -// IsArrayType reports whether a given ast.Node is an array or slice type (*ast.IsArrayType). -func IsArrayType(node ast.Node) bool { - _, ok := node.(*ast.ArrayType) - return ok -} - -// IsStructType reports whether a given ast.Node is a struct type (*ast.IsStructType). -func IsStructType(node ast.Node) bool { - _, ok := node.(*ast.StructType) - return ok -} - -// IsFuncType reports whether a given ast.Node is a function type (*ast.IsFuncType). -func IsFuncType(node ast.Node) bool { - _, ok := node.(*ast.FuncType) - return ok -} - -// IsInterfaceType reports whether a given ast.Node is an interface type (*ast.IsInterfaceType). -func IsInterfaceType(node ast.Node) bool { - _, ok := node.(*ast.InterfaceType) - return ok -} - -// IsMapType reports whether a given ast.Node is a map type (*ast.IsMapType). -func IsMapType(node ast.Node) bool { - _, ok := node.(*ast.MapType) - return ok -} - -// IsChanType reports whether a given ast.Node is a channel type (*ast.IsChanType). -func IsChanType(node ast.Node) bool { - _, ok := node.(*ast.ChanType) - return ok -} diff --git a/vendor/github.com/go-toolsmith/astp/stmt.go b/vendor/github.com/go-toolsmith/astp/stmt.go deleted file mode 100644 index 19645d212e..0000000000 --- a/vendor/github.com/go-toolsmith/astp/stmt.go +++ /dev/null @@ -1,135 +0,0 @@ -package astp - -import "go/ast" - -// IsStmt reports whether a given ast.Node is a statement(ast.Stmt). -func IsStmt(node ast.Node) bool { - _, ok := node.(ast.Stmt) - return ok -} - -// IsBadStmt reports whether a given ast.Node is a bad statement(*ast.BadStmt) -func IsBadStmt(node ast.Node) bool { - _, ok := node.(*ast.BadStmt) - return ok -} - -// IsDeclStmt reports whether a given ast.Node is a declaration statement(*ast.DeclStmt) -func IsDeclStmt(node ast.Node) bool { - _, ok := node.(*ast.DeclStmt) - return ok -} - -// IsEmptyStmt reports whether a given ast.Node is an empty statement(*ast.EmptyStmt) -func IsEmptyStmt(node ast.Node) bool { - _, ok := node.(*ast.EmptyStmt) - return ok -} - -// IsLabeledStmt reports whether a given ast.Node is a label statement(*ast.LabeledStmt) -func IsLabeledStmt(node ast.Node) bool { - _, ok := node.(*ast.LabeledStmt) - return ok -} - -// IsExprStmt reports whether a given ast.Node is an expression statement(*ast.ExprStmt) -func IsExprStmt(node ast.Node) bool { - _, ok := node.(*ast.ExprStmt) - return ok -} - -// IsSendStmt reports whether a given ast.Node is a send to chan statement(*ast.SendStmt) -func IsSendStmt(node ast.Node) bool { - _, ok := node.(*ast.SendStmt) - return ok -} - -// IsIncDecStmt reports whether a given ast.Node is a increment/decrement statement(*ast.IncDecStmt) -func IsIncDecStmt(node ast.Node) bool { - _, ok := node.(*ast.IncDecStmt) - return ok -} - -// IsAssignStmt reports whether a given ast.Node is an assignment statement(*ast.AssignStmt) -func IsAssignStmt(node ast.Node) bool { - _, ok := node.(*ast.AssignStmt) - return ok -} - -// IsGoStmt reports whether a given ast.Node is a go statement(*ast.GoStmt) -func IsGoStmt(node ast.Node) bool { - _, ok := node.(*ast.GoStmt) - return ok -} - -// IsDeferStmt reports whether a given ast.Node is a defer statement(*ast.DeferStmt) -func IsDeferStmt(node ast.Node) bool { - _, ok := node.(*ast.DeferStmt) - return ok -} - -// IsReturnStmt reports whether a given ast.Node is a return statement(*ast.ReturnStmt) -func IsReturnStmt(node ast.Node) bool { - _, ok := node.(*ast.ReturnStmt) - return ok -} - -// IsBranchStmt reports whether a given ast.Node is a branch(goto/continue/break/fallthrough)statement(*ast.BranchStmt) -func IsBranchStmt(node ast.Node) bool { - _, ok := node.(*ast.BranchStmt) - return ok -} - -// IsBlockStmt reports whether a given ast.Node is a block statement(*ast.BlockStmt) -func IsBlockStmt(node ast.Node) bool { - _, ok := node.(*ast.BlockStmt) - return ok -} - -// IsIfStmt reports whether a given ast.Node is an if statement(*ast.IfStmt) -func IsIfStmt(node ast.Node) bool { - _, ok := node.(*ast.IfStmt) - return ok -} - -// IsCaseClause reports whether a given ast.Node is a case statement(*ast.CaseClause) -func IsCaseClause(node ast.Node) bool { - _, ok := node.(*ast.CaseClause) - return ok -} - -// IsSwitchStmt reports whether a given ast.Node is a switch statement(*ast.SwitchStmt) -func IsSwitchStmt(node ast.Node) bool { - _, ok := node.(*ast.SwitchStmt) - return ok -} - -// IsTypeSwitchStmt reports whether a given ast.Node is a type switch statement(*ast.TypeSwitchStmt) -func IsTypeSwitchStmt(node ast.Node) bool { - _, ok := node.(*ast.TypeSwitchStmt) - return ok -} - -// IsCommClause reports whether a given ast.Node is a select statement(*ast.CommClause) -func IsCommClause(node ast.Node) bool { - _, ok := node.(*ast.CommClause) - return ok -} - -// IsSelectStmt reports whether a given ast.Node is a selection statement(*ast.SelectStmt) -func IsSelectStmt(node ast.Node) bool { - _, ok := node.(*ast.SelectStmt) - return ok -} - -// IsForStmt reports whether a given ast.Node is a for statement(*ast.ForStmt) -func IsForStmt(node ast.Node) bool { - _, ok := node.(*ast.ForStmt) - return ok -} - -// IsRangeStmt reports whether a given ast.Node is a range statement(*ast.RangeStmt) -func IsRangeStmt(node ast.Node) bool { - _, ok := node.(*ast.RangeStmt) - return ok -} diff --git a/vendor/github.com/go-toolsmith/strparse/LICENSE b/vendor/github.com/go-toolsmith/strparse/LICENSE deleted file mode 100644 index eef17180f8..0000000000 --- a/vendor/github.com/go-toolsmith/strparse/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2018 go-toolsmith - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/go-toolsmith/strparse/README.md b/vendor/github.com/go-toolsmith/strparse/README.md deleted file mode 100644 index ac04d516fe..0000000000 --- a/vendor/github.com/go-toolsmith/strparse/README.md +++ /dev/null @@ -1,48 +0,0 @@ -# strparse - -[![build-img]][build-url] -[![pkg-img]][pkg-url] -[![reportcard-img]][reportcard-url] -[![version-img]][version-url] - -Package `strparse` provides convenience wrappers around `go/parser` for simple -expression, statement and declaretion parsing from string. - -## Installation - -Go version 1.16+ - -```bash -go get github.com/go-toolsmith/strparse -``` - -## Example - -```go -package main - -import ( - "github.com/go-toolsmith/astequal" - "github.com/go-toolsmith/strparse" -) - -func main() { - // Comparing AST strings for equallity (note different spacing): - x := strparse.Expr(`1 + f(v[0].X)`) - y := strparse.Expr(` 1+f( v[0].X ) `) - fmt.Println(astequal.Expr(x, y)) // => true -} -``` - -## License - -[MIT License](LICENSE). - -[build-img]: https://github.com/go-toolsmith/strparse/workflows/build/badge.svg -[build-url]: https://github.com/go-toolsmith/strparse/actions -[pkg-img]: https://pkg.go.dev/badge/go-toolsmith/strparse -[pkg-url]: https://pkg.go.dev/github.com/go-toolsmith/strparse -[reportcard-img]: https://goreportcard.com/badge/go-toolsmith/strparse -[reportcard-url]: https://goreportcard.com/report/go-toolsmith/strparse -[version-img]: https://img.shields.io/github/v/release/go-toolsmith/strparse -[version-url]: https://github.com/go-toolsmith/strparse/releases diff --git a/vendor/github.com/go-toolsmith/strparse/strparse.go b/vendor/github.com/go-toolsmith/strparse/strparse.go deleted file mode 100644 index 894c7ebac3..0000000000 --- a/vendor/github.com/go-toolsmith/strparse/strparse.go +++ /dev/null @@ -1,59 +0,0 @@ -// Package strparse provides convenience wrappers around `go/parser` for simple -// expression, statement and declaration parsing from string. -// -// Can be used to construct AST nodes using source syntax. -package strparse - -import ( - "go/ast" - "go/parser" - "go/token" -) - -var ( - // BadExpr is returned as a parse result for malformed expressions. - // Should be treated as constant or readonly variable. - BadExpr = &ast.BadExpr{} - - // BadStmt is returned as a parse result for malformed statmenents. - // Should be treated as constant or readonly variable. - BadStmt = &ast.BadStmt{} - - // BadDecl is returned as a parse result for malformed declarations. - // Should be treated as constant or readonly variable. - BadDecl = &ast.BadDecl{} -) - -// Expr parses single expression node from s. -// In case of parse error, BadExpr is returned. -func Expr(s string) ast.Expr { - node, err := parser.ParseExpr(s) - if err != nil { - return BadExpr - } - return node -} - -// Stmt parses single statement node from s. -// In case of parse error, BadStmt is returned. -func Stmt(s string) ast.Stmt { - node, err := parser.ParseFile(token.NewFileSet(), "", "package main;func main() {"+s+"}", 0) - if err != nil { - return BadStmt - } - fn := node.Decls[0].(*ast.FuncDecl) - if len(fn.Body.List) != 1 { - return BadStmt - } - return fn.Body.List[0] -} - -// Decl parses single declaration node from s. -// In case of parse error, BadDecl is returned. -func Decl(s string) ast.Decl { - node, err := parser.ParseFile(token.NewFileSet(), "", "package main;"+s, 0) - if err != nil || len(node.Decls) != 1 { - return BadDecl - } - return node.Decls[0] -} diff --git a/vendor/github.com/go-toolsmith/typep/LICENSE b/vendor/github.com/go-toolsmith/typep/LICENSE deleted file mode 100644 index eef17180f8..0000000000 --- a/vendor/github.com/go-toolsmith/typep/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2018 go-toolsmith - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/go-toolsmith/typep/README.md b/vendor/github.com/go-toolsmith/typep/README.md deleted file mode 100644 index 77478c4434..0000000000 --- a/vendor/github.com/go-toolsmith/typep/README.md +++ /dev/null @@ -1,54 +0,0 @@ -# typep - -[![build-img]][build-url] -[![pkg-img]][pkg-url] -[![reportcard-img]][reportcard-url] -[![version-img]][version-url] - -Package `typep` provides type predicates. - -## Installation: - -Go version 1.16+ - -```bash -go get github.com/go-toolsmith/typep -``` - -## Example - -```go -package main - -import ( - "fmt" - - "github.com/go-toolsmith/typep" - "github.com/go-toolsmith/strparse" -) - -func main() { - floatTyp := types.Typ[types.Float32] - intTyp := types.Typ[types.Int] - ptr := types.NewPointer(intTyp) - arr := types.NewArray(intTyp, 64) - - fmt.Println(typep.HasFloatProp(floatTyp)) // => true - fmt.Println(typep.HasFloatProp(intTyp)) // => false - fmt.Println(typep.IsPointer(ptr)) // => true - fmt.Println(typep.IsArray(arr)) // => true -} -``` - -## License - -[MIT License](LICENSE). - -[build-img]: https://github.com/go-toolsmith/typep/workflows/build/badge.svg -[build-url]: https://github.com/go-toolsmith/typep/actions -[pkg-img]: https://pkg.go.dev/badge/go-toolsmith/typep -[pkg-url]: https://pkg.go.dev/github.com/go-toolsmith/typep -[reportcard-img]: https://goreportcard.com/badge/go-toolsmith/typep -[reportcard-url]: https://goreportcard.com/report/go-toolsmith/typep -[version-img]: https://img.shields.io/github/v/release/go-toolsmith/typep -[version-url]: https://github.com/go-toolsmith/typep/releases diff --git a/vendor/github.com/go-toolsmith/typep/doc.go b/vendor/github.com/go-toolsmith/typep/doc.go deleted file mode 100644 index 990bc402c0..0000000000 --- a/vendor/github.com/go-toolsmith/typep/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package typep provides type predicates. -package typep diff --git a/vendor/github.com/go-toolsmith/typep/predicates.go b/vendor/github.com/go-toolsmith/typep/predicates.go deleted file mode 100644 index b07325a726..0000000000 --- a/vendor/github.com/go-toolsmith/typep/predicates.go +++ /dev/null @@ -1,36 +0,0 @@ -package typep - -import ( - "go/ast" - "go/types" -) - -// IsTypeExpr reports whether x represents a type expression. -// -// Type expression does not evaluate to any run time value, -// but rather describes a type that is used inside Go expression. -// -// For example, (*T)(v) is a CallExpr that "calls" (*T). -// (*T) is a type expression that tells Go compiler type v should be converted to. -func IsTypeExpr(info *types.Info, x ast.Expr) bool { - switch x := x.(type) { - case *ast.StarExpr: - return IsTypeExpr(info, x.X) - case *ast.ParenExpr: - return IsTypeExpr(info, x.X) - case *ast.SelectorExpr: - return IsTypeExpr(info, x.Sel) - - case *ast.Ident: - // Identifier may be a type expression if object - // it reffers to is a type name. - _, ok := info.ObjectOf(x).(*types.TypeName) - return ok - - case *ast.FuncType, *ast.StructType, *ast.InterfaceType, *ast.ArrayType, *ast.MapType, *ast.ChanType: - return true - - default: - return false - } -} diff --git a/vendor/github.com/go-toolsmith/typep/safe_expr.go b/vendor/github.com/go-toolsmith/typep/safe_expr.go deleted file mode 100644 index d5835d97bb..0000000000 --- a/vendor/github.com/go-toolsmith/typep/safe_expr.go +++ /dev/null @@ -1,73 +0,0 @@ -package typep - -import ( - "go/ast" - "go/token" - "go/types" -) - -// SideEffectFree reports whether expr is softly safe expression and contains -// no significant side-effects. As opposed to strictly safe expressions, -// soft safe expressions permit some forms of side-effects, like -// panic possibility during indexing or nil pointer dereference. -// -// Uses types info to determine type conversion expressions that -// are the only permitted kinds of call expressions. -// Note that is does not check whether called function really -// has any side effects. The analysis is very conservative. -func SideEffectFree(info *types.Info, expr ast.Expr) bool { - // This list switch is not comprehensive and uses - // whitelist to be on the conservative side. - // Can be extended as needed. - - if expr == nil { - return true - } - - switch expr := expr.(type) { - case *ast.StarExpr: - return SideEffectFree(info, expr.X) - case *ast.BinaryExpr: - return SideEffectFree(info, expr.X) && - SideEffectFree(info, expr.Y) - case *ast.UnaryExpr: - return expr.Op != token.ARROW && - SideEffectFree(info, expr.X) - case *ast.BasicLit, *ast.Ident: - return true - case *ast.SliceExpr: - return SideEffectFree(info, expr.X) && - SideEffectFree(info, expr.Low) && - SideEffectFree(info, expr.High) && - SideEffectFree(info, expr.Max) - case *ast.IndexExpr: - return SideEffectFree(info, expr.X) && - SideEffectFree(info, expr.Index) - case *ast.SelectorExpr: - return SideEffectFree(info, expr.X) - case *ast.ParenExpr: - return SideEffectFree(info, expr.X) - case *ast.TypeAssertExpr: - return SideEffectFree(info, expr.X) - case *ast.CompositeLit: - return SideEffectFreeList(info, expr.Elts) - case *ast.CallExpr: - return IsTypeExpr(info, expr.Fun) && - SideEffectFreeList(info, expr.Args) - - default: - return false - } -} - -// SideEffectFreeList reports whether every expr in list is safe. -// -// See SideEffectFree. -func SideEffectFreeList(info *types.Info, list []ast.Expr) bool { - for _, expr := range list { - if !SideEffectFree(info, expr) { - return false - } - } - return true -} diff --git a/vendor/github.com/go-toolsmith/typep/simple_predicates.go b/vendor/github.com/go-toolsmith/typep/simple_predicates.go deleted file mode 100644 index 61e7d5b7f7..0000000000 --- a/vendor/github.com/go-toolsmith/typep/simple_predicates.go +++ /dev/null @@ -1,359 +0,0 @@ -// Code generated by simple_predicates_generate.go; DO NOT EDIT - -package typep - -import ( - "go/types" -) - -// Simple 1-to-1 type predicates via type assertion. - -// IsBasic reports whether a given type has *types.Basic type. -func IsBasic(typ types.Type) bool { - _, ok := typ.(*types.Basic) - return ok -} - -// IsArray reports whether a given type has *types.Array type. -func IsArray(typ types.Type) bool { - _, ok := typ.(*types.Array) - return ok -} - -// IsSlice reports whether a given type has *types.Slice type. -func IsSlice(typ types.Type) bool { - _, ok := typ.(*types.Slice) - return ok -} - -// IsStruct reports whether a given type has *types.Struct type. -func IsStruct(typ types.Type) bool { - _, ok := typ.(*types.Struct) - return ok -} - -// IsPointer reports whether a given type has *types.Pointer type. -func IsPointer(typ types.Type) bool { - _, ok := typ.(*types.Pointer) - return ok -} - -// IsTuple reports whether a given type has *types.Tuple type. -func IsTuple(typ types.Type) bool { - _, ok := typ.(*types.Tuple) - return ok -} - -// IsSignature reports whether a given type has *types.Signature type. -func IsSignature(typ types.Type) bool { - _, ok := typ.(*types.Signature) - return ok -} - -// IsInterface reports whether a given type has *types.Interface type. -func IsInterface(typ types.Type) bool { - _, ok := typ.(*types.Interface) - return ok -} - -// IsMap reports whether a given type has *types.Map type. -func IsMap(typ types.Type) bool { - _, ok := typ.(*types.Map) - return ok -} - -// IsChan reports whether a given type has *types.Chan type. -func IsChan(typ types.Type) bool { - _, ok := typ.(*types.Chan) - return ok -} - -// IsNamed reports whether a given type has *types.Named type. -func IsNamed(typ types.Type) bool { - _, ok := typ.(*types.Named) - return ok -} - -// *types.Basic predicates for the info field. - -// HasBooleanProp reports whether typ is a *types.Basic has IsBoolean property. -func HasBooleanProp(typ types.Type) bool { - if typ, ok := typ.(*types.Basic); ok { - return typ.Info()&types.IsBoolean != 0 - } - return false -} - -// HasIntegerProp reports whether typ is a *types.Basic has IsInteger property. -func HasIntegerProp(typ types.Type) bool { - if typ, ok := typ.(*types.Basic); ok { - return typ.Info()&types.IsInteger != 0 - } - return false -} - -// HasUnsignedProp reports whether typ is a *types.Basic has IsUnsigned property. -func HasUnsignedProp(typ types.Type) bool { - if typ, ok := typ.(*types.Basic); ok { - return typ.Info()&types.IsUnsigned != 0 - } - return false -} - -// HasFloatProp reports whether typ is a *types.Basic has IsFloat property. -func HasFloatProp(typ types.Type) bool { - if typ, ok := typ.(*types.Basic); ok { - return typ.Info()&types.IsFloat != 0 - } - return false -} - -// HasComplexProp reports whether typ is a *types.Basic has IsComplex property. -func HasComplexProp(typ types.Type) bool { - if typ, ok := typ.(*types.Basic); ok { - return typ.Info()&types.IsComplex != 0 - } - return false -} - -// HasStringProp reports whether typ is a *types.Basic has IsString property. -func HasStringProp(typ types.Type) bool { - if typ, ok := typ.(*types.Basic); ok { - return typ.Info()&types.IsString != 0 - } - return false -} - -// HasUntypedProp reports whether typ is a *types.Basic has IsUntyped property. -func HasUntypedProp(typ types.Type) bool { - if typ, ok := typ.(*types.Basic); ok { - return typ.Info()&types.IsUntyped != 0 - } - return false -} - -// HasOrderedProp reports whether typ is a *types.Basic has IsOrdered property. -func HasOrderedProp(typ types.Type) bool { - if typ, ok := typ.(*types.Basic); ok { - return typ.Info()&types.IsOrdered != 0 - } - return false -} - -// HasNumericProp reports whether typ is a *types.Basic has IsNumeric property. -func HasNumericProp(typ types.Type) bool { - if typ, ok := typ.(*types.Basic); ok { - return typ.Info()&types.IsNumeric != 0 - } - return false -} - -// HasConstTypeProp reports whether typ is a *types.Basic has IsConstType property. -func HasConstTypeProp(typ types.Type) bool { - if typ, ok := typ.(*types.Basic); ok { - return typ.Info()&types.IsConstType != 0 - } - return false -} - -// *types.Basic predicates for the kind field. - -// HasBoolKind reports whether typ is a *types.Basic with its kind set to types.Bool. -func HasBoolKind(typ types.Type) bool { - if typ, ok := typ.(*types.Basic); ok { - return typ.Kind() == types.Bool - } - return false -} - -// HasIntKind reports whether typ is a *types.Basic with its kind set to types.Int. -func HasIntKind(typ types.Type) bool { - if typ, ok := typ.(*types.Basic); ok { - return typ.Kind() == types.Int - } - return false -} - -// HasInt8Kind reports whether typ is a *types.Basic with its kind set to types.Int8. -func HasInt8Kind(typ types.Type) bool { - if typ, ok := typ.(*types.Basic); ok { - return typ.Kind() == types.Int8 - } - return false -} - -// HasInt16Kind reports whether typ is a *types.Basic with its kind set to types.Int16. -func HasInt16Kind(typ types.Type) bool { - if typ, ok := typ.(*types.Basic); ok { - return typ.Kind() == types.Int16 - } - return false -} - -// HasInt32Kind reports whether typ is a *types.Basic with its kind set to types.Int32. -func HasInt32Kind(typ types.Type) bool { - if typ, ok := typ.(*types.Basic); ok { - return typ.Kind() == types.Int32 - } - return false -} - -// HasInt64Kind reports whether typ is a *types.Basic with its kind set to types.Int64. -func HasInt64Kind(typ types.Type) bool { - if typ, ok := typ.(*types.Basic); ok { - return typ.Kind() == types.Int64 - } - return false -} - -// HasUintKind reports whether typ is a *types.Basic with its kind set to types.Uint. -func HasUintKind(typ types.Type) bool { - if typ, ok := typ.(*types.Basic); ok { - return typ.Kind() == types.Uint - } - return false -} - -// HasUint8Kind reports whether typ is a *types.Basic with its kind set to types.Uint8. -func HasUint8Kind(typ types.Type) bool { - if typ, ok := typ.(*types.Basic); ok { - return typ.Kind() == types.Uint8 - } - return false -} - -// HasUint16Kind reports whether typ is a *types.Basic with its kind set to types.Uint16. -func HasUint16Kind(typ types.Type) bool { - if typ, ok := typ.(*types.Basic); ok { - return typ.Kind() == types.Uint16 - } - return false -} - -// HasUint32Kind reports whether typ is a *types.Basic with its kind set to types.Uint32. -func HasUint32Kind(typ types.Type) bool { - if typ, ok := typ.(*types.Basic); ok { - return typ.Kind() == types.Uint32 - } - return false -} - -// HasUint64Kind reports whether typ is a *types.Basic with its kind set to types.Uint64. -func HasUint64Kind(typ types.Type) bool { - if typ, ok := typ.(*types.Basic); ok { - return typ.Kind() == types.Uint64 - } - return false -} - -// HasUintptrKind reports whether typ is a *types.Basic with its kind set to types.Uintptr. -func HasUintptrKind(typ types.Type) bool { - if typ, ok := typ.(*types.Basic); ok { - return typ.Kind() == types.Uintptr - } - return false -} - -// HasFloat32Kind reports whether typ is a *types.Basic with its kind set to types.Float32. -func HasFloat32Kind(typ types.Type) bool { - if typ, ok := typ.(*types.Basic); ok { - return typ.Kind() == types.Float32 - } - return false -} - -// HasFloat64Kind reports whether typ is a *types.Basic with its kind set to types.Float64. -func HasFloat64Kind(typ types.Type) bool { - if typ, ok := typ.(*types.Basic); ok { - return typ.Kind() == types.Float64 - } - return false -} - -// HasComplex64Kind reports whether typ is a *types.Basic with its kind set to types.Complex64. -func HasComplex64Kind(typ types.Type) bool { - if typ, ok := typ.(*types.Basic); ok { - return typ.Kind() == types.Complex64 - } - return false -} - -// HasComplex128Kind reports whether typ is a *types.Basic with its kind set to types.Complex128. -func HasComplex128Kind(typ types.Type) bool { - if typ, ok := typ.(*types.Basic); ok { - return typ.Kind() == types.Complex128 - } - return false -} - -// HasStringKind reports whether typ is a *types.Basic with its kind set to types.String. -func HasStringKind(typ types.Type) bool { - if typ, ok := typ.(*types.Basic); ok { - return typ.Kind() == types.String - } - return false -} - -// HasUnsafePointerKind reports whether typ is a *types.Basic with its kind set to types.UnsafePointer. -func HasUnsafePointerKind(typ types.Type) bool { - if typ, ok := typ.(*types.Basic); ok { - return typ.Kind() == types.UnsafePointer - } - return false -} - -// HasUntypedBoolKind reports whether typ is a *types.Basic with its kind set to types.UntypedBool. -func HasUntypedBoolKind(typ types.Type) bool { - if typ, ok := typ.(*types.Basic); ok { - return typ.Kind() == types.UntypedBool - } - return false -} - -// HasUntypedIntKind reports whether typ is a *types.Basic with its kind set to types.UntypedInt. -func HasUntypedIntKind(typ types.Type) bool { - if typ, ok := typ.(*types.Basic); ok { - return typ.Kind() == types.UntypedInt - } - return false -} - -// HasUntypedRuneKind reports whether typ is a *types.Basic with its kind set to types.UntypedRune. -func HasUntypedRuneKind(typ types.Type) bool { - if typ, ok := typ.(*types.Basic); ok { - return typ.Kind() == types.UntypedRune - } - return false -} - -// HasUntypedFloatKind reports whether typ is a *types.Basic with its kind set to types.UntypedFloat. -func HasUntypedFloatKind(typ types.Type) bool { - if typ, ok := typ.(*types.Basic); ok { - return typ.Kind() == types.UntypedFloat - } - return false -} - -// HasUntypedComplexKind reports whether typ is a *types.Basic with its kind set to types.UntypedComplex. -func HasUntypedComplexKind(typ types.Type) bool { - if typ, ok := typ.(*types.Basic); ok { - return typ.Kind() == types.UntypedComplex - } - return false -} - -// HasUntypedStringKind reports whether typ is a *types.Basic with its kind set to types.UntypedString. -func HasUntypedStringKind(typ types.Type) bool { - if typ, ok := typ.(*types.Basic); ok { - return typ.Kind() == types.UntypedString - } - return false -} - -// HasUntypedNilKind reports whether typ is a *types.Basic with its kind set to types.UntypedNil. -func HasUntypedNilKind(typ types.Type) bool { - if typ, ok := typ.(*types.Basic); ok { - return typ.Kind() == types.UntypedNil - } - return false -} diff --git a/vendor/github.com/go-viper/mapstructure/v2/.editorconfig b/vendor/github.com/go-viper/mapstructure/v2/.editorconfig deleted file mode 100644 index faef0c91e7..0000000000 --- a/vendor/github.com/go-viper/mapstructure/v2/.editorconfig +++ /dev/null @@ -1,21 +0,0 @@ -root = true - -[*] -charset = utf-8 -end_of_line = lf -indent_size = 4 -indent_style = space -insert_final_newline = true -trim_trailing_whitespace = true - -[*.go] -indent_style = tab - -[{Makefile,*.mk}] -indent_style = tab - -[*.nix] -indent_size = 2 - -[.golangci.yaml] -indent_size = 2 diff --git a/vendor/github.com/go-viper/mapstructure/v2/.envrc b/vendor/github.com/go-viper/mapstructure/v2/.envrc deleted file mode 100644 index 2e0f9f5f71..0000000000 --- a/vendor/github.com/go-viper/mapstructure/v2/.envrc +++ /dev/null @@ -1,4 +0,0 @@ -if ! has nix_direnv_version || ! nix_direnv_version 3.0.4; then - source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/3.0.4/direnvrc" "sha256-DzlYZ33mWF/Gs8DDeyjr8mnVmQGx7ASYqA5WlxwvBG4=" -fi -use flake . --impure diff --git a/vendor/github.com/go-viper/mapstructure/v2/.gitignore b/vendor/github.com/go-viper/mapstructure/v2/.gitignore deleted file mode 100644 index 470e7ca2bd..0000000000 --- a/vendor/github.com/go-viper/mapstructure/v2/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -/.devenv/ -/.direnv/ -/.pre-commit-config.yaml -/bin/ -/build/ -/var/ diff --git a/vendor/github.com/go-viper/mapstructure/v2/.golangci.yaml b/vendor/github.com/go-viper/mapstructure/v2/.golangci.yaml deleted file mode 100644 index bda9625668..0000000000 --- a/vendor/github.com/go-viper/mapstructure/v2/.golangci.yaml +++ /dev/null @@ -1,48 +0,0 @@ -version: "2" - -run: - timeout: 10m - -linters: - enable: - - govet - - ineffassign - # - misspell - - nolintlint - # - revive - - disable: - - errcheck - - staticcheck - - unused - - settings: - misspell: - locale: US - nolintlint: - allow-unused: false # report any unused nolint directives - require-specific: false # don't require nolint directives to be specific about which linter is being skipped - -formatters: - enable: - - gci - - gofmt - - gofumpt - - goimports - # - golines - - settings: - gci: - sections: - - standard - - default - - localmodule - gofmt: - simplify: true - rewrite-rules: - - pattern: interface{} - replacement: any - - exclusions: - paths: - - internal/ diff --git a/vendor/github.com/go-viper/mapstructure/v2/CHANGELOG.md b/vendor/github.com/go-viper/mapstructure/v2/CHANGELOG.md deleted file mode 100644 index afd44e5f5f..0000000000 --- a/vendor/github.com/go-viper/mapstructure/v2/CHANGELOG.md +++ /dev/null @@ -1,104 +0,0 @@ -> [!WARNING] -> As of v2 of this library, change log can be found in GitHub releases. - -## 1.5.1 - -* Wrap errors so they're compatible with `errors.Is` and `errors.As` [GH-282] -* Fix map of slices not decoding properly in certain cases. [GH-266] - -## 1.5.0 - -* New option `IgnoreUntaggedFields` to ignore decoding to any fields - without `mapstructure` (or the configured tag name) set [GH-277] -* New option `ErrorUnset` which makes it an error if any fields - in a target struct are not set by the decoding process. [GH-225] -* New function `OrComposeDecodeHookFunc` to help compose decode hooks. [GH-240] -* Decoding to slice from array no longer crashes [GH-265] -* Decode nested struct pointers to map [GH-271] -* Fix issue where `,squash` was ignored if `Squash` option was set. [GH-280] -* Fix issue where fields with `,omitempty` would sometimes decode - into a map with an empty string key [GH-281] - -## 1.4.3 - -* Fix cases where `json.Number` didn't decode properly [GH-261] - -## 1.4.2 - -* Custom name matchers to support any sort of casing, formatting, etc. for - field names. [GH-250] -* Fix possible panic in ComposeDecodeHookFunc [GH-251] - -## 1.4.1 - -* Fix regression where `*time.Time` value would be set to empty and not be sent - to decode hooks properly [GH-232] - -## 1.4.0 - -* A new decode hook type `DecodeHookFuncValue` has been added that has - access to the full values. [GH-183] -* Squash is now supported with embedded fields that are struct pointers [GH-205] -* Empty strings will convert to 0 for all numeric types when weakly decoding [GH-206] - -## 1.3.3 - -* Decoding maps from maps creates a settable value for decode hooks [GH-203] - -## 1.3.2 - -* Decode into interface type with a struct value is supported [GH-187] - -## 1.3.1 - -* Squash should only squash embedded structs. [GH-194] - -## 1.3.0 - -* Added `",omitempty"` support. This will ignore zero values in the source - structure when encoding. [GH-145] - -## 1.2.3 - -* Fix duplicate entries in Keys list with pointer values. [GH-185] - -## 1.2.2 - -* Do not add unsettable (unexported) values to the unused metadata key - or "remain" value. [GH-150] - -## 1.2.1 - -* Go modules checksum mismatch fix - -## 1.2.0 - -* Added support to capture unused values in a field using the `",remain"` value - in the mapstructure tag. There is an example to showcase usage. -* Added `DecoderConfig` option to always squash embedded structs -* `json.Number` can decode into `uint` types -* Empty slices are preserved and not replaced with nil slices -* Fix panic that can occur in when decoding a map into a nil slice of structs -* Improved package documentation for godoc - -## 1.1.2 - -* Fix error when decode hook decodes interface implementation into interface - type. [GH-140] - -## 1.1.1 - -* Fix panic that can happen in `decodePtr` - -## 1.1.0 - -* Added `StringToIPHookFunc` to convert `string` to `net.IP` and `net.IPNet` [GH-133] -* Support struct to struct decoding [GH-137] -* If source map value is nil, then destination map value is nil (instead of empty) -* If source slice value is nil, then destination slice value is nil (instead of empty) -* If source pointer is nil, then destination pointer is set to nil (instead of - allocated zero value of type) - -## 1.0.0 - -* Initial tagged stable release. diff --git a/vendor/github.com/go-viper/mapstructure/v2/LICENSE b/vendor/github.com/go-viper/mapstructure/v2/LICENSE deleted file mode 100644 index f9c841a51e..0000000000 --- a/vendor/github.com/go-viper/mapstructure/v2/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2013 Mitchell Hashimoto - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/vendor/github.com/go-viper/mapstructure/v2/README.md b/vendor/github.com/go-viper/mapstructure/v2/README.md deleted file mode 100644 index 45db719755..0000000000 --- a/vendor/github.com/go-viper/mapstructure/v2/README.md +++ /dev/null @@ -1,81 +0,0 @@ -# mapstructure - -[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/go-viper/mapstructure/ci.yaml?style=flat-square)](https://github.com/go-viper/mapstructure/actions/workflows/ci.yaml) -[![go.dev reference](https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white&style=flat-square)](https://pkg.go.dev/mod/github.com/go-viper/mapstructure/v2) -![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/go-viper/mapstructure?style=flat-square&color=61CFDD) -[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/go-viper/mapstructure/badge?style=flat-square)](https://deps.dev/go/github.com%252Fgo-viper%252Fmapstructure%252Fv2) - -mapstructure is a Go library for decoding generic map values to structures -and vice versa, while providing helpful error handling. - -This library is most useful when decoding values from some data stream (JSON, -Gob, etc.) where you don't _quite_ know the structure of the underlying data -until you read a part of it. You can therefore read a `map[string]interface{}` -and use this library to decode it into the proper underlying native Go -structure. - -## Installation - -```shell -go get github.com/go-viper/mapstructure/v2 -``` - -## Migrating from `github.com/mitchellh/mapstructure` - -[@mitchehllh](https://github.com/mitchellh) announced his intent to archive some of his unmaintained projects (see [here](https://gist.github.com/mitchellh/90029601268e59a29e64e55bab1c5bdc) and [here](https://github.com/mitchellh/mapstructure/issues/349)). This is a repository achieved the "blessed fork" status. - -You can migrate to this package by changing your import paths in your Go files to `github.com/go-viper/mapstructure/v2`. -The API is the same, so you don't need to change anything else. - -Here is a script that can help you with the migration: - -```shell -sed -i 's|github.com/mitchellh/mapstructure|github.com/go-viper/mapstructure/v2|g' $(find . -type f -name '*.go') -``` - -If you need more time to migrate your code, that is absolutely fine. - -Some of the latest fixes are backported to the v1 release branch of this package, so you can use the Go modules `replace` feature until you are ready to migrate: - -```shell -replace github.com/mitchellh/mapstructure => github.com/go-viper/mapstructure v1.6.0 -``` - -## Usage & Example - -For usage and examples see the [documentation](https://pkg.go.dev/mod/github.com/go-viper/mapstructure/v2). - -The `Decode` function has examples associated with it there. - -## But Why?! - -Go offers fantastic standard libraries for decoding formats such as JSON. -The standard method is to have a struct pre-created, and populate that struct -from the bytes of the encoded format. This is great, but the problem is if -you have configuration or an encoding that changes slightly depending on -specific fields. For example, consider this JSON: - -```json -{ - "type": "person", - "name": "Mitchell" -} -``` - -Perhaps we can't populate a specific structure without first reading -the "type" field from the JSON. We could always do two passes over the -decoding of the JSON (reading the "type" first, and the rest later). -However, it is much simpler to just decode this into a `map[string]interface{}` -structure, read the "type" key, then use something like this library -to decode it into the proper structure. - -## Credits - -Mapstructure was originally created by [@mitchellh](https://github.com/mitchellh). -This is a maintained fork of the original library. - -Read more about the reasons for the fork [here](https://github.com/mitchellh/mapstructure/issues/349). - -## License - -The project is licensed under the [MIT License](LICENSE). diff --git a/vendor/github.com/go-viper/mapstructure/v2/decode_hooks.go b/vendor/github.com/go-viper/mapstructure/v2/decode_hooks.go deleted file mode 100644 index a852a0a04c..0000000000 --- a/vendor/github.com/go-viper/mapstructure/v2/decode_hooks.go +++ /dev/null @@ -1,714 +0,0 @@ -package mapstructure - -import ( - "encoding" - "errors" - "fmt" - "net" - "net/netip" - "net/url" - "reflect" - "strconv" - "strings" - "time" -) - -// typedDecodeHook takes a raw DecodeHookFunc (an any) and turns -// it into the proper DecodeHookFunc type, such as DecodeHookFuncType. -func typedDecodeHook(h DecodeHookFunc) DecodeHookFunc { - // Create variables here so we can reference them with the reflect pkg - var f1 DecodeHookFuncType - var f2 DecodeHookFuncKind - var f3 DecodeHookFuncValue - - // Fill in the variables into this interface and the rest is done - // automatically using the reflect package. - potential := []any{f1, f2, f3} - - v := reflect.ValueOf(h) - vt := v.Type() - for _, raw := range potential { - pt := reflect.ValueOf(raw).Type() - if vt.ConvertibleTo(pt) { - return v.Convert(pt).Interface() - } - } - - return nil -} - -// cachedDecodeHook takes a raw DecodeHookFunc (an any) and turns -// it into a closure to be used directly -// if the type fails to convert we return a closure always erroring to keep the previous behaviour -func cachedDecodeHook(raw DecodeHookFunc) func(from reflect.Value, to reflect.Value) (any, error) { - switch f := typedDecodeHook(raw).(type) { - case DecodeHookFuncType: - return func(from reflect.Value, to reflect.Value) (any, error) { - return f(from.Type(), to.Type(), from.Interface()) - } - case DecodeHookFuncKind: - return func(from reflect.Value, to reflect.Value) (any, error) { - return f(from.Kind(), to.Kind(), from.Interface()) - } - case DecodeHookFuncValue: - return func(from reflect.Value, to reflect.Value) (any, error) { - return f(from, to) - } - default: - return func(from reflect.Value, to reflect.Value) (any, error) { - return nil, errors.New("invalid decode hook signature") - } - } -} - -// DecodeHookExec executes the given decode hook. This should be used -// since it'll naturally degrade to the older backwards compatible DecodeHookFunc -// that took reflect.Kind instead of reflect.Type. -func DecodeHookExec( - raw DecodeHookFunc, - from reflect.Value, to reflect.Value, -) (any, error) { - switch f := typedDecodeHook(raw).(type) { - case DecodeHookFuncType: - return f(from.Type(), to.Type(), from.Interface()) - case DecodeHookFuncKind: - return f(from.Kind(), to.Kind(), from.Interface()) - case DecodeHookFuncValue: - return f(from, to) - default: - return nil, errors.New("invalid decode hook signature") - } -} - -// ComposeDecodeHookFunc creates a single DecodeHookFunc that -// automatically composes multiple DecodeHookFuncs. -// -// The composed funcs are called in order, with the result of the -// previous transformation. -func ComposeDecodeHookFunc(fs ...DecodeHookFunc) DecodeHookFunc { - cached := make([]func(from reflect.Value, to reflect.Value) (any, error), 0, len(fs)) - for _, f := range fs { - cached = append(cached, cachedDecodeHook(f)) - } - return func(f reflect.Value, t reflect.Value) (any, error) { - var err error - data := f.Interface() - - newFrom := f - for _, c := range cached { - data, err = c(newFrom, t) - if err != nil { - return nil, err - } - if v, ok := data.(reflect.Value); ok { - newFrom = v - } else { - newFrom = reflect.ValueOf(data) - } - } - - return data, nil - } -} - -// OrComposeDecodeHookFunc executes all input hook functions until one of them returns no error. In that case its value is returned. -// If all hooks return an error, OrComposeDecodeHookFunc returns an error concatenating all error messages. -func OrComposeDecodeHookFunc(ff ...DecodeHookFunc) DecodeHookFunc { - cached := make([]func(from reflect.Value, to reflect.Value) (any, error), 0, len(ff)) - for _, f := range ff { - cached = append(cached, cachedDecodeHook(f)) - } - return func(a, b reflect.Value) (any, error) { - var allErrs string - var out any - var err error - - for _, c := range cached { - out, err = c(a, b) - if err != nil { - allErrs += err.Error() + "\n" - continue - } - - return out, nil - } - - return nil, errors.New(allErrs) - } -} - -// StringToSliceHookFunc returns a DecodeHookFunc that converts -// string to []string by splitting on the given sep. -func StringToSliceHookFunc(sep string) DecodeHookFunc { - return func( - f reflect.Type, - t reflect.Type, - data any, - ) (any, error) { - if f.Kind() != reflect.String { - return data, nil - } - if t != reflect.SliceOf(f) { - return data, nil - } - - raw := data.(string) - if raw == "" { - return []string{}, nil - } - - return strings.Split(raw, sep), nil - } -} - -// StringToWeakSliceHookFunc brings back the old (pre-v2) behavior of [StringToSliceHookFunc]. -// -// As of mapstructure v2.0.0 [StringToSliceHookFunc] checks if the return type is a string slice. -// This function removes that check. -func StringToWeakSliceHookFunc(sep string) DecodeHookFunc { - return func( - f reflect.Type, - t reflect.Type, - data any, - ) (any, error) { - if f.Kind() != reflect.String || t.Kind() != reflect.Slice { - return data, nil - } - - raw := data.(string) - if raw == "" { - return []string{}, nil - } - - return strings.Split(raw, sep), nil - } -} - -// StringToTimeDurationHookFunc returns a DecodeHookFunc that converts -// strings to time.Duration. -func StringToTimeDurationHookFunc() DecodeHookFunc { - return func( - f reflect.Type, - t reflect.Type, - data any, - ) (any, error) { - if f.Kind() != reflect.String { - return data, nil - } - if t != reflect.TypeOf(time.Duration(5)) { - return data, nil - } - - // Convert it by parsing - d, err := time.ParseDuration(data.(string)) - - return d, wrapTimeParseDurationError(err) - } -} - -// StringToTimeLocationHookFunc returns a DecodeHookFunc that converts -// strings to *time.Location. -func StringToTimeLocationHookFunc() DecodeHookFunc { - return func( - f reflect.Type, - t reflect.Type, - data any, - ) (any, error) { - if f.Kind() != reflect.String { - return data, nil - } - if t != reflect.TypeOf(time.Local) { - return data, nil - } - d, err := time.LoadLocation(data.(string)) - - return d, wrapTimeParseLocationError(err) - } -} - -// StringToURLHookFunc returns a DecodeHookFunc that converts -// strings to *url.URL. -func StringToURLHookFunc() DecodeHookFunc { - return func( - f reflect.Type, - t reflect.Type, - data any, - ) (any, error) { - if f.Kind() != reflect.String { - return data, nil - } - if t != reflect.TypeOf(&url.URL{}) { - return data, nil - } - - // Convert it by parsing - u, err := url.Parse(data.(string)) - - return u, wrapUrlError(err) - } -} - -// StringToIPHookFunc returns a DecodeHookFunc that converts -// strings to net.IP -func StringToIPHookFunc() DecodeHookFunc { - return func( - f reflect.Type, - t reflect.Type, - data any, - ) (any, error) { - if f.Kind() != reflect.String { - return data, nil - } - if t != reflect.TypeOf(net.IP{}) { - return data, nil - } - - // Convert it by parsing - ip := net.ParseIP(data.(string)) - if ip == nil { - return net.IP{}, fmt.Errorf("failed parsing ip") - } - - return ip, nil - } -} - -// StringToIPNetHookFunc returns a DecodeHookFunc that converts -// strings to net.IPNet -func StringToIPNetHookFunc() DecodeHookFunc { - return func( - f reflect.Type, - t reflect.Type, - data any, - ) (any, error) { - if f.Kind() != reflect.String { - return data, nil - } - if t != reflect.TypeOf(net.IPNet{}) { - return data, nil - } - - // Convert it by parsing - _, net, err := net.ParseCIDR(data.(string)) - return net, wrapNetParseError(err) - } -} - -// StringToTimeHookFunc returns a DecodeHookFunc that converts -// strings to time.Time. -func StringToTimeHookFunc(layout string) DecodeHookFunc { - return func( - f reflect.Type, - t reflect.Type, - data any, - ) (any, error) { - if f.Kind() != reflect.String { - return data, nil - } - if t != reflect.TypeOf(time.Time{}) { - return data, nil - } - - // Convert it by parsing - ti, err := time.Parse(layout, data.(string)) - - return ti, wrapTimeParseError(err) - } -} - -// WeaklyTypedHook is a DecodeHookFunc which adds support for weak typing to -// the decoder. -// -// Note that this is significantly different from the WeaklyTypedInput option -// of the DecoderConfig. -func WeaklyTypedHook( - f reflect.Kind, - t reflect.Kind, - data any, -) (any, error) { - dataVal := reflect.ValueOf(data) - switch t { - case reflect.String: - switch f { - case reflect.Bool: - if dataVal.Bool() { - return "1", nil - } - return "0", nil - case reflect.Float32: - return strconv.FormatFloat(dataVal.Float(), 'f', -1, 64), nil - case reflect.Int: - return strconv.FormatInt(dataVal.Int(), 10), nil - case reflect.Slice: - dataType := dataVal.Type() - elemKind := dataType.Elem().Kind() - if elemKind == reflect.Uint8 { - return string(dataVal.Interface().([]uint8)), nil - } - case reflect.Uint: - return strconv.FormatUint(dataVal.Uint(), 10), nil - } - } - - return data, nil -} - -func RecursiveStructToMapHookFunc() DecodeHookFunc { - return func(f reflect.Value, t reflect.Value) (any, error) { - if f.Kind() != reflect.Struct { - return f.Interface(), nil - } - - var i any = struct{}{} - if t.Type() != reflect.TypeOf(&i).Elem() { - return f.Interface(), nil - } - - m := make(map[string]any) - t.Set(reflect.ValueOf(m)) - - return f.Interface(), nil - } -} - -// TextUnmarshallerHookFunc returns a DecodeHookFunc that applies -// strings to the UnmarshalText function, when the target type -// implements the encoding.TextUnmarshaler interface -func TextUnmarshallerHookFunc() DecodeHookFuncType { - return func( - f reflect.Type, - t reflect.Type, - data any, - ) (any, error) { - if f.Kind() != reflect.String { - return data, nil - } - result := reflect.New(t).Interface() - unmarshaller, ok := result.(encoding.TextUnmarshaler) - if !ok { - return data, nil - } - str, ok := data.(string) - if !ok { - str = reflect.Indirect(reflect.ValueOf(&data)).Elem().String() - } - if err := unmarshaller.UnmarshalText([]byte(str)); err != nil { - return nil, err - } - return result, nil - } -} - -// StringToNetIPAddrHookFunc returns a DecodeHookFunc that converts -// strings to netip.Addr. -func StringToNetIPAddrHookFunc() DecodeHookFunc { - return func( - f reflect.Type, - t reflect.Type, - data any, - ) (any, error) { - if f.Kind() != reflect.String { - return data, nil - } - if t != reflect.TypeOf(netip.Addr{}) { - return data, nil - } - - // Convert it by parsing - addr, err := netip.ParseAddr(data.(string)) - - return addr, wrapNetIPParseAddrError(err) - } -} - -// StringToNetIPAddrPortHookFunc returns a DecodeHookFunc that converts -// strings to netip.AddrPort. -func StringToNetIPAddrPortHookFunc() DecodeHookFunc { - return func( - f reflect.Type, - t reflect.Type, - data any, - ) (any, error) { - if f.Kind() != reflect.String { - return data, nil - } - if t != reflect.TypeOf(netip.AddrPort{}) { - return data, nil - } - - // Convert it by parsing - addrPort, err := netip.ParseAddrPort(data.(string)) - - return addrPort, wrapNetIPParseAddrPortError(err) - } -} - -// StringToNetIPPrefixHookFunc returns a DecodeHookFunc that converts -// strings to netip.Prefix. -func StringToNetIPPrefixHookFunc() DecodeHookFunc { - return func( - f reflect.Type, - t reflect.Type, - data any, - ) (any, error) { - if f.Kind() != reflect.String { - return data, nil - } - if t != reflect.TypeOf(netip.Prefix{}) { - return data, nil - } - - // Convert it by parsing - prefix, err := netip.ParsePrefix(data.(string)) - - return prefix, wrapNetIPParsePrefixError(err) - } -} - -// StringToBasicTypeHookFunc returns a DecodeHookFunc that converts -// strings to basic types. -// int8, uint8, int16, uint16, int32, uint32, int64, uint64, int, uint, float32, float64, bool, byte, rune, complex64, complex128 -func StringToBasicTypeHookFunc() DecodeHookFunc { - return ComposeDecodeHookFunc( - StringToInt8HookFunc(), - StringToUint8HookFunc(), - StringToInt16HookFunc(), - StringToUint16HookFunc(), - StringToInt32HookFunc(), - StringToUint32HookFunc(), - StringToInt64HookFunc(), - StringToUint64HookFunc(), - StringToIntHookFunc(), - StringToUintHookFunc(), - StringToFloat32HookFunc(), - StringToFloat64HookFunc(), - StringToBoolHookFunc(), - // byte and rune are aliases for uint8 and int32 respectively - // StringToByteHookFunc(), - // StringToRuneHookFunc(), - StringToComplex64HookFunc(), - StringToComplex128HookFunc(), - ) -} - -// StringToInt8HookFunc returns a DecodeHookFunc that converts -// strings to int8. -func StringToInt8HookFunc() DecodeHookFunc { - return func(f reflect.Type, t reflect.Type, data any) (any, error) { - if f.Kind() != reflect.String || t.Kind() != reflect.Int8 { - return data, nil - } - - // Convert it by parsing - i64, err := strconv.ParseInt(data.(string), 0, 8) - return int8(i64), wrapStrconvNumError(err) - } -} - -// StringToUint8HookFunc returns a DecodeHookFunc that converts -// strings to uint8. -func StringToUint8HookFunc() DecodeHookFunc { - return func(f reflect.Type, t reflect.Type, data any) (any, error) { - if f.Kind() != reflect.String || t.Kind() != reflect.Uint8 { - return data, nil - } - - // Convert it by parsing - u64, err := strconv.ParseUint(data.(string), 0, 8) - return uint8(u64), wrapStrconvNumError(err) - } -} - -// StringToInt16HookFunc returns a DecodeHookFunc that converts -// strings to int16. -func StringToInt16HookFunc() DecodeHookFunc { - return func(f reflect.Type, t reflect.Type, data any) (any, error) { - if f.Kind() != reflect.String || t.Kind() != reflect.Int16 { - return data, nil - } - - // Convert it by parsing - i64, err := strconv.ParseInt(data.(string), 0, 16) - return int16(i64), wrapStrconvNumError(err) - } -} - -// StringToUint16HookFunc returns a DecodeHookFunc that converts -// strings to uint16. -func StringToUint16HookFunc() DecodeHookFunc { - return func(f reflect.Type, t reflect.Type, data any) (any, error) { - if f.Kind() != reflect.String || t.Kind() != reflect.Uint16 { - return data, nil - } - - // Convert it by parsing - u64, err := strconv.ParseUint(data.(string), 0, 16) - return uint16(u64), wrapStrconvNumError(err) - } -} - -// StringToInt32HookFunc returns a DecodeHookFunc that converts -// strings to int32. -func StringToInt32HookFunc() DecodeHookFunc { - return func(f reflect.Type, t reflect.Type, data any) (any, error) { - if f.Kind() != reflect.String || t.Kind() != reflect.Int32 { - return data, nil - } - - // Convert it by parsing - i64, err := strconv.ParseInt(data.(string), 0, 32) - return int32(i64), wrapStrconvNumError(err) - } -} - -// StringToUint32HookFunc returns a DecodeHookFunc that converts -// strings to uint32. -func StringToUint32HookFunc() DecodeHookFunc { - return func(f reflect.Type, t reflect.Type, data any) (any, error) { - if f.Kind() != reflect.String || t.Kind() != reflect.Uint32 { - return data, nil - } - - // Convert it by parsing - u64, err := strconv.ParseUint(data.(string), 0, 32) - return uint32(u64), wrapStrconvNumError(err) - } -} - -// StringToInt64HookFunc returns a DecodeHookFunc that converts -// strings to int64. -func StringToInt64HookFunc() DecodeHookFunc { - return func(f reflect.Type, t reflect.Type, data any) (any, error) { - if f.Kind() != reflect.String || t.Kind() != reflect.Int64 { - return data, nil - } - - // Convert it by parsing - i64, err := strconv.ParseInt(data.(string), 0, 64) - return int64(i64), wrapStrconvNumError(err) - } -} - -// StringToUint64HookFunc returns a DecodeHookFunc that converts -// strings to uint64. -func StringToUint64HookFunc() DecodeHookFunc { - return func(f reflect.Type, t reflect.Type, data any) (any, error) { - if f.Kind() != reflect.String || t.Kind() != reflect.Uint64 { - return data, nil - } - - // Convert it by parsing - u64, err := strconv.ParseUint(data.(string), 0, 64) - return uint64(u64), wrapStrconvNumError(err) - } -} - -// StringToIntHookFunc returns a DecodeHookFunc that converts -// strings to int. -func StringToIntHookFunc() DecodeHookFunc { - return func(f reflect.Type, t reflect.Type, data any) (any, error) { - if f.Kind() != reflect.String || t.Kind() != reflect.Int { - return data, nil - } - - // Convert it by parsing - i64, err := strconv.ParseInt(data.(string), 0, 0) - return int(i64), wrapStrconvNumError(err) - } -} - -// StringToUintHookFunc returns a DecodeHookFunc that converts -// strings to uint. -func StringToUintHookFunc() DecodeHookFunc { - return func(f reflect.Type, t reflect.Type, data any) (any, error) { - if f.Kind() != reflect.String || t.Kind() != reflect.Uint { - return data, nil - } - - // Convert it by parsing - u64, err := strconv.ParseUint(data.(string), 0, 0) - return uint(u64), wrapStrconvNumError(err) - } -} - -// StringToFloat32HookFunc returns a DecodeHookFunc that converts -// strings to float32. -func StringToFloat32HookFunc() DecodeHookFunc { - return func(f reflect.Type, t reflect.Type, data any) (any, error) { - if f.Kind() != reflect.String || t.Kind() != reflect.Float32 { - return data, nil - } - - // Convert it by parsing - f64, err := strconv.ParseFloat(data.(string), 32) - return float32(f64), wrapStrconvNumError(err) - } -} - -// StringToFloat64HookFunc returns a DecodeHookFunc that converts -// strings to float64. -func StringToFloat64HookFunc() DecodeHookFunc { - return func(f reflect.Type, t reflect.Type, data any) (any, error) { - if f.Kind() != reflect.String || t.Kind() != reflect.Float64 { - return data, nil - } - - // Convert it by parsing - f64, err := strconv.ParseFloat(data.(string), 64) - return f64, wrapStrconvNumError(err) - } -} - -// StringToBoolHookFunc returns a DecodeHookFunc that converts -// strings to bool. -func StringToBoolHookFunc() DecodeHookFunc { - return func(f reflect.Type, t reflect.Type, data any) (any, error) { - if f.Kind() != reflect.String || t.Kind() != reflect.Bool { - return data, nil - } - - // Convert it by parsing - b, err := strconv.ParseBool(data.(string)) - return b, wrapStrconvNumError(err) - } -} - -// StringToByteHookFunc returns a DecodeHookFunc that converts -// strings to byte. -func StringToByteHookFunc() DecodeHookFunc { - return StringToUint8HookFunc() -} - -// StringToRuneHookFunc returns a DecodeHookFunc that converts -// strings to rune. -func StringToRuneHookFunc() DecodeHookFunc { - return StringToInt32HookFunc() -} - -// StringToComplex64HookFunc returns a DecodeHookFunc that converts -// strings to complex64. -func StringToComplex64HookFunc() DecodeHookFunc { - return func(f reflect.Type, t reflect.Type, data any) (any, error) { - if f.Kind() != reflect.String || t.Kind() != reflect.Complex64 { - return data, nil - } - - // Convert it by parsing - c128, err := strconv.ParseComplex(data.(string), 64) - return complex64(c128), wrapStrconvNumError(err) - } -} - -// StringToComplex128HookFunc returns a DecodeHookFunc that converts -// strings to complex128. -func StringToComplex128HookFunc() DecodeHookFunc { - return func(f reflect.Type, t reflect.Type, data any) (any, error) { - if f.Kind() != reflect.String || t.Kind() != reflect.Complex128 { - return data, nil - } - - // Convert it by parsing - c128, err := strconv.ParseComplex(data.(string), 128) - return c128, wrapStrconvNumError(err) - } -} diff --git a/vendor/github.com/go-viper/mapstructure/v2/errors.go b/vendor/github.com/go-viper/mapstructure/v2/errors.go deleted file mode 100644 index 07d31c22aa..0000000000 --- a/vendor/github.com/go-viper/mapstructure/v2/errors.go +++ /dev/null @@ -1,244 +0,0 @@ -package mapstructure - -import ( - "errors" - "fmt" - "net" - "net/url" - "reflect" - "strconv" - "strings" - "time" -) - -// Error interface is implemented by all errors emitted by mapstructure. -// -// Use [errors.As] to check if an error implements this interface. -type Error interface { - error - - mapstructure() -} - -// DecodeError is a generic error type that holds information about -// a decoding error together with the name of the field that caused the error. -type DecodeError struct { - name string - err error -} - -func newDecodeError(name string, err error) *DecodeError { - return &DecodeError{ - name: name, - err: err, - } -} - -func (e *DecodeError) Name() string { - return e.name -} - -func (e *DecodeError) Unwrap() error { - return e.err -} - -func (e *DecodeError) Error() string { - return fmt.Sprintf("'%s' %s", e.name, e.err) -} - -func (*DecodeError) mapstructure() {} - -// ParseError is an error type that indicates a value could not be parsed -// into the expected type. -type ParseError struct { - Expected reflect.Value - Value any - Err error -} - -func (e *ParseError) Error() string { - return fmt.Sprintf("cannot parse value as '%s': %s", e.Expected.Type(), e.Err) -} - -func (*ParseError) mapstructure() {} - -// UnconvertibleTypeError is an error type that indicates a value could not be -// converted to the expected type. -type UnconvertibleTypeError struct { - Expected reflect.Value - Value any -} - -func (e *UnconvertibleTypeError) Error() string { - return fmt.Sprintf( - "expected type '%s', got unconvertible type '%s'", - e.Expected.Type(), - reflect.TypeOf(e.Value), - ) -} - -func (*UnconvertibleTypeError) mapstructure() {} - -func wrapStrconvNumError(err error) error { - if err == nil { - return nil - } - - if err, ok := err.(*strconv.NumError); ok { - return &strconvNumError{Err: err} - } - - return err -} - -type strconvNumError struct { - Err *strconv.NumError -} - -func (e *strconvNumError) Error() string { - return "strconv." + e.Err.Func + ": " + e.Err.Err.Error() -} - -func (e *strconvNumError) Unwrap() error { return e.Err } - -func wrapUrlError(err error) error { - if err == nil { - return nil - } - - if err, ok := err.(*url.Error); ok { - return &urlError{Err: err} - } - - return err -} - -type urlError struct { - Err *url.Error -} - -func (e *urlError) Error() string { - return fmt.Sprintf("%s", e.Err.Err) -} - -func (e *urlError) Unwrap() error { return e.Err } - -func wrapNetParseError(err error) error { - if err == nil { - return nil - } - - if err, ok := err.(*net.ParseError); ok { - return &netParseError{Err: err} - } - - return err -} - -type netParseError struct { - Err *net.ParseError -} - -func (e *netParseError) Error() string { - return "invalid " + e.Err.Type -} - -func (e *netParseError) Unwrap() error { return e.Err } - -func wrapTimeParseError(err error) error { - if err == nil { - return nil - } - - if err, ok := err.(*time.ParseError); ok { - return &timeParseError{Err: err} - } - - return err -} - -type timeParseError struct { - Err *time.ParseError -} - -func (e *timeParseError) Error() string { - if e.Err.Message == "" { - return fmt.Sprintf("parsing time as %q: cannot parse as %q", e.Err.Layout, e.Err.LayoutElem) - } - - return "parsing time " + e.Err.Message -} - -func (e *timeParseError) Unwrap() error { return e.Err } - -func wrapNetIPParseAddrError(err error) error { - if err == nil { - return nil - } - - if errMsg := err.Error(); strings.HasPrefix(errMsg, "ParseAddr") { - errPieces := strings.Split(errMsg, ": ") - - return fmt.Errorf("ParseAddr: %s", errPieces[len(errPieces)-1]) - } - - return err -} - -func wrapNetIPParseAddrPortError(err error) error { - if err == nil { - return nil - } - - errMsg := err.Error() - if strings.HasPrefix(errMsg, "invalid port ") { - return errors.New("invalid port") - } else if strings.HasPrefix(errMsg, "invalid ip:port ") { - return errors.New("invalid ip:port") - } - - return err -} - -func wrapNetIPParsePrefixError(err error) error { - if err == nil { - return nil - } - - if errMsg := err.Error(); strings.HasPrefix(errMsg, "netip.ParsePrefix") { - errPieces := strings.Split(errMsg, ": ") - - return fmt.Errorf("netip.ParsePrefix: %s", errPieces[len(errPieces)-1]) - } - - return err -} - -func wrapTimeParseDurationError(err error) error { - if err == nil { - return nil - } - - errMsg := err.Error() - if strings.HasPrefix(errMsg, "time: unknown unit ") { - return errors.New("time: unknown unit") - } else if strings.HasPrefix(errMsg, "time: ") { - idx := strings.LastIndex(errMsg, " ") - - return errors.New(errMsg[:idx]) - } - - return err -} - -func wrapTimeParseLocationError(err error) error { - if err == nil { - return nil - } - errMsg := err.Error() - if strings.Contains(errMsg, "unknown time zone") || strings.HasPrefix(errMsg, "time: unknown format") { - return fmt.Errorf("invalid time zone format: %w", err) - } - - return err -} diff --git a/vendor/github.com/go-viper/mapstructure/v2/flake.lock b/vendor/github.com/go-viper/mapstructure/v2/flake.lock deleted file mode 100644 index 5e67bdd6b4..0000000000 --- a/vendor/github.com/go-viper/mapstructure/v2/flake.lock +++ /dev/null @@ -1,294 +0,0 @@ -{ - "nodes": { - "cachix": { - "inputs": { - "devenv": [ - "devenv" - ], - "flake-compat": [ - "devenv" - ], - "git-hooks": [ - "devenv" - ], - "nixpkgs": "nixpkgs" - }, - "locked": { - "lastModified": 1742042642, - "narHash": "sha256-D0gP8srrX0qj+wNYNPdtVJsQuFzIng3q43thnHXQ/es=", - "owner": "cachix", - "repo": "cachix", - "rev": "a624d3eaf4b1d225f918de8543ed739f2f574203", - "type": "github" - }, - "original": { - "owner": "cachix", - "ref": "latest", - "repo": "cachix", - "type": "github" - } - }, - "devenv": { - "inputs": { - "cachix": "cachix", - "flake-compat": "flake-compat", - "git-hooks": "git-hooks", - "nix": "nix", - "nixpkgs": "nixpkgs_3" - }, - "locked": { - "lastModified": 1744876578, - "narHash": "sha256-8MTBj2REB8t29sIBLpxbR0+AEGJ7f+RkzZPAGsFd40c=", - "owner": "cachix", - "repo": "devenv", - "rev": "7ff7c351bba20d0615be25ecdcbcf79b57b85fe1", - "type": "github" - }, - "original": { - "owner": "cachix", - "repo": "devenv", - "type": "github" - } - }, - "flake-compat": { - "flake": false, - "locked": { - "lastModified": 1733328505, - "narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=", - "owner": "edolstra", - "repo": "flake-compat", - "rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec", - "type": "github" - }, - "original": { - "owner": "edolstra", - "repo": "flake-compat", - "type": "github" - } - }, - "flake-parts": { - "inputs": { - "nixpkgs-lib": [ - "devenv", - "nix", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1712014858, - "narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=", - "owner": "hercules-ci", - "repo": "flake-parts", - "rev": "9126214d0a59633752a136528f5f3b9aa8565b7d", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "flake-parts", - "type": "github" - } - }, - "flake-parts_2": { - "inputs": { - "nixpkgs-lib": "nixpkgs-lib" - }, - "locked": { - "lastModified": 1743550720, - "narHash": "sha256-hIshGgKZCgWh6AYJpJmRgFdR3WUbkY04o82X05xqQiY=", - "owner": "hercules-ci", - "repo": "flake-parts", - "rev": "c621e8422220273271f52058f618c94e405bb0f5", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "flake-parts", - "type": "github" - } - }, - "git-hooks": { - "inputs": { - "flake-compat": [ - "devenv" - ], - "gitignore": "gitignore", - "nixpkgs": [ - "devenv", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1742649964, - "narHash": "sha256-DwOTp7nvfi8mRfuL1escHDXabVXFGT1VlPD1JHrtrco=", - "owner": "cachix", - "repo": "git-hooks.nix", - "rev": "dcf5072734cb576d2b0c59b2ac44f5050b5eac82", - "type": "github" - }, - "original": { - "owner": "cachix", - "repo": "git-hooks.nix", - "type": "github" - } - }, - "gitignore": { - "inputs": { - "nixpkgs": [ - "devenv", - "git-hooks", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1709087332, - "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", - "owner": "hercules-ci", - "repo": "gitignore.nix", - "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "gitignore.nix", - "type": "github" - } - }, - "libgit2": { - "flake": false, - "locked": { - "lastModified": 1697646580, - "narHash": "sha256-oX4Z3S9WtJlwvj0uH9HlYcWv+x1hqp8mhXl7HsLu2f0=", - "owner": "libgit2", - "repo": "libgit2", - "rev": "45fd9ed7ae1a9b74b957ef4f337bc3c8b3df01b5", - "type": "github" - }, - "original": { - "owner": "libgit2", - "repo": "libgit2", - "type": "github" - } - }, - "nix": { - "inputs": { - "flake-compat": [ - "devenv" - ], - "flake-parts": "flake-parts", - "libgit2": "libgit2", - "nixpkgs": "nixpkgs_2", - "nixpkgs-23-11": [ - "devenv" - ], - "nixpkgs-regression": [ - "devenv" - ], - "pre-commit-hooks": [ - "devenv" - ] - }, - "locked": { - "lastModified": 1741798497, - "narHash": "sha256-E3j+3MoY8Y96mG1dUIiLFm2tZmNbRvSiyN7CrSKuAVg=", - "owner": "domenkozar", - "repo": "nix", - "rev": "f3f44b2baaf6c4c6e179de8cbb1cc6db031083cd", - "type": "github" - }, - "original": { - "owner": "domenkozar", - "ref": "devenv-2.24", - "repo": "nix", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1733212471, - "narHash": "sha256-M1+uCoV5igihRfcUKrr1riygbe73/dzNnzPsmaLCmpo=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "55d15ad12a74eb7d4646254e13638ad0c4128776", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs-lib": { - "locked": { - "lastModified": 1743296961, - "narHash": "sha256-b1EdN3cULCqtorQ4QeWgLMrd5ZGOjLSLemfa00heasc=", - "owner": "nix-community", - "repo": "nixpkgs.lib", - "rev": "e4822aea2a6d1cdd36653c134cacfd64c97ff4fa", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "nixpkgs.lib", - "type": "github" - } - }, - "nixpkgs_2": { - "locked": { - "lastModified": 1717432640, - "narHash": "sha256-+f9c4/ZX5MWDOuB1rKoWj+lBNm0z0rs4CK47HBLxy1o=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "88269ab3044128b7c2f4c7d68448b2fb50456870", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "release-24.05", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_3": { - "locked": { - "lastModified": 1733477122, - "narHash": "sha256-qamMCz5mNpQmgBwc8SB5tVMlD5sbwVIToVZtSxMph9s=", - "owner": "cachix", - "repo": "devenv-nixpkgs", - "rev": "7bd9e84d0452f6d2e63b6e6da29fe73fac951857", - "type": "github" - }, - "original": { - "owner": "cachix", - "ref": "rolling", - "repo": "devenv-nixpkgs", - "type": "github" - } - }, - "nixpkgs_4": { - "locked": { - "lastModified": 1744536153, - "narHash": "sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "18dd725c29603f582cf1900e0d25f9f1063dbf11", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "root": { - "inputs": { - "devenv": "devenv", - "flake-parts": "flake-parts_2", - "nixpkgs": "nixpkgs_4" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/vendor/github.com/go-viper/mapstructure/v2/flake.nix b/vendor/github.com/go-viper/mapstructure/v2/flake.nix deleted file mode 100644 index 3b116f426d..0000000000 --- a/vendor/github.com/go-viper/mapstructure/v2/flake.nix +++ /dev/null @@ -1,46 +0,0 @@ -{ - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; - flake-parts.url = "github:hercules-ci/flake-parts"; - devenv.url = "github:cachix/devenv"; - }; - - outputs = - inputs@{ flake-parts, ... }: - flake-parts.lib.mkFlake { inherit inputs; } { - imports = [ - inputs.devenv.flakeModule - ]; - - systems = [ - "x86_64-linux" - "x86_64-darwin" - "aarch64-darwin" - ]; - - perSystem = - { pkgs, ... }: - rec { - devenv.shells = { - default = { - languages = { - go.enable = true; - }; - - pre-commit.hooks = { - nixpkgs-fmt.enable = true; - }; - - packages = with pkgs; [ - golangci-lint - ]; - - # https://github.com/cachix/devenv/issues/528#issuecomment-1556108767 - containers = pkgs.lib.mkForce { }; - }; - - ci = devenv.shells.default; - }; - }; - }; -} diff --git a/vendor/github.com/go-viper/mapstructure/v2/internal/errors/errors.go b/vendor/github.com/go-viper/mapstructure/v2/internal/errors/errors.go deleted file mode 100644 index d1c15e474f..0000000000 --- a/vendor/github.com/go-viper/mapstructure/v2/internal/errors/errors.go +++ /dev/null @@ -1,11 +0,0 @@ -package errors - -import "errors" - -func New(text string) error { - return errors.New(text) -} - -func As(err error, target interface{}) bool { - return errors.As(err, target) -} diff --git a/vendor/github.com/go-viper/mapstructure/v2/internal/errors/join.go b/vendor/github.com/go-viper/mapstructure/v2/internal/errors/join.go deleted file mode 100644 index d74e3a0b5a..0000000000 --- a/vendor/github.com/go-viper/mapstructure/v2/internal/errors/join.go +++ /dev/null @@ -1,9 +0,0 @@ -//go:build go1.20 - -package errors - -import "errors" - -func Join(errs ...error) error { - return errors.Join(errs...) -} diff --git a/vendor/github.com/go-viper/mapstructure/v2/internal/errors/join_go1_19.go b/vendor/github.com/go-viper/mapstructure/v2/internal/errors/join_go1_19.go deleted file mode 100644 index 700b40229c..0000000000 --- a/vendor/github.com/go-viper/mapstructure/v2/internal/errors/join_go1_19.go +++ /dev/null @@ -1,61 +0,0 @@ -//go:build !go1.20 - -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package errors - -// Join returns an error that wraps the given errors. -// Any nil error values are discarded. -// Join returns nil if every value in errs is nil. -// The error formats as the concatenation of the strings obtained -// by calling the Error method of each element of errs, with a newline -// between each string. -// -// A non-nil error returned by Join implements the Unwrap() []error method. -func Join(errs ...error) error { - n := 0 - for _, err := range errs { - if err != nil { - n++ - } - } - if n == 0 { - return nil - } - e := &joinError{ - errs: make([]error, 0, n), - } - for _, err := range errs { - if err != nil { - e.errs = append(e.errs, err) - } - } - return e -} - -type joinError struct { - errs []error -} - -func (e *joinError) Error() string { - // Since Join returns nil if every value in errs is nil, - // e.errs cannot be empty. - if len(e.errs) == 1 { - return e.errs[0].Error() - } - - b := []byte(e.errs[0].Error()) - for _, err := range e.errs[1:] { - b = append(b, '\n') - b = append(b, err.Error()...) - } - // At this point, b has at least one byte '\n'. - // return unsafe.String(&b[0], len(b)) - return string(b) -} - -func (e *joinError) Unwrap() []error { - return e.errs -} diff --git a/vendor/github.com/go-viper/mapstructure/v2/mapstructure.go b/vendor/github.com/go-viper/mapstructure/v2/mapstructure.go deleted file mode 100644 index 7c35bce020..0000000000 --- a/vendor/github.com/go-viper/mapstructure/v2/mapstructure.go +++ /dev/null @@ -1,1712 +0,0 @@ -// Package mapstructure exposes functionality to convert one arbitrary -// Go type into another, typically to convert a map[string]any -// into a native Go structure. -// -// The Go structure can be arbitrarily complex, containing slices, -// other structs, etc. and the decoder will properly decode nested -// maps and so on into the proper structures in the native Go struct. -// See the examples to see what the decoder is capable of. -// -// The simplest function to start with is Decode. -// -// # Field Tags -// -// When decoding to a struct, mapstructure will use the field name by -// default to perform the mapping. For example, if a struct has a field -// "Username" then mapstructure will look for a key in the source value -// of "username" (case insensitive). -// -// type User struct { -// Username string -// } -// -// You can change the behavior of mapstructure by using struct tags. -// The default struct tag that mapstructure looks for is "mapstructure" -// but you can customize it using DecoderConfig. -// -// # Renaming Fields -// -// To rename the key that mapstructure looks for, use the "mapstructure" -// tag and set a value directly. For example, to change the "username" example -// above to "user": -// -// type User struct { -// Username string `mapstructure:"user"` -// } -// -// # Embedded Structs and Squashing -// -// Embedded structs are treated as if they're another field with that name. -// By default, the two structs below are equivalent when decoding with -// mapstructure: -// -// type Person struct { -// Name string -// } -// -// type Friend struct { -// Person -// } -// -// type Friend struct { -// Person Person -// } -// -// This would require an input that looks like below: -// -// map[string]any{ -// "person": map[string]any{"name": "alice"}, -// } -// -// If your "person" value is NOT nested, then you can append ",squash" to -// your tag value and mapstructure will treat it as if the embedded struct -// were part of the struct directly. Example: -// -// type Friend struct { -// Person `mapstructure:",squash"` -// } -// -// Now the following input would be accepted: -// -// map[string]any{ -// "name": "alice", -// } -// -// When decoding from a struct to a map, the squash tag squashes the struct -// fields into a single map. Using the example structs from above: -// -// Friend{Person: Person{Name: "alice"}} -// -// Will be decoded into a map: -// -// map[string]any{ -// "name": "alice", -// } -// -// DecoderConfig has a field that changes the behavior of mapstructure -// to always squash embedded structs. -// -// # Remainder Values -// -// If there are any unmapped keys in the source value, mapstructure by -// default will silently ignore them. You can error by setting ErrorUnused -// in DecoderConfig. If you're using Metadata you can also maintain a slice -// of the unused keys. -// -// You can also use the ",remain" suffix on your tag to collect all unused -// values in a map. The field with this tag MUST be a map type and should -// probably be a "map[string]any" or "map[any]any". -// See example below: -// -// type Friend struct { -// Name string -// Other map[string]any `mapstructure:",remain"` -// } -// -// Given the input below, Other would be populated with the other -// values that weren't used (everything but "name"): -// -// map[string]any{ -// "name": "bob", -// "address": "123 Maple St.", -// } -// -// # Omit Empty Values -// -// When decoding from a struct to any other value, you may use the -// ",omitempty" suffix on your tag to omit that value if it equates to -// the zero value, or a zero-length element. The zero value of all types is -// specified in the Go specification. -// -// For example, the zero type of a numeric type is zero ("0"). If the struct -// field value is zero and a numeric type, the field is empty, and it won't -// be encoded into the destination type. And likewise for the URLs field, if the -// slice is nil or empty, it won't be encoded into the destination type. -// -// type Source struct { -// Age int `mapstructure:",omitempty"` -// URLs []string `mapstructure:",omitempty"` -// } -// -// # Omit Zero Values -// -// When decoding from a struct to any other value, you may use the -// ",omitzero" suffix on your tag to omit that value if it equates to the zero -// value. The zero value of all types is specified in the Go specification. -// -// For example, the zero type of a numeric type is zero ("0"). If the struct -// field value is zero and a numeric type, the field is empty, and it won't -// be encoded into the destination type. And likewise for the URLs field, if the -// slice is nil, it won't be encoded into the destination type. -// -// Note that if the field is a slice, and it is empty but not nil, it will -// still be encoded into the destination type. -// -// type Source struct { -// Age int `mapstructure:",omitzero"` -// URLs []string `mapstructure:",omitzero"` -// } -// -// # Unexported fields -// -// Since unexported (private) struct fields cannot be set outside the package -// where they are defined, the decoder will simply skip them. -// -// For this output type definition: -// -// type Exported struct { -// private string // this unexported field will be skipped -// Public string -// } -// -// Using this map as input: -// -// map[string]any{ -// "private": "I will be ignored", -// "Public": "I made it through!", -// } -// -// The following struct will be decoded: -// -// type Exported struct { -// private: "" // field is left with an empty string (zero value) -// Public: "I made it through!" -// } -// -// # Other Configuration -// -// mapstructure is highly configurable. See the DecoderConfig struct -// for other features and options that are supported. -package mapstructure - -import ( - "encoding/json" - "fmt" - "reflect" - "sort" - "strconv" - "strings" - - "github.com/go-viper/mapstructure/v2/internal/errors" -) - -// DecodeHookFunc is the callback function that can be used for -// data transformations. See "DecodeHook" in the DecoderConfig -// struct. -// -// The type must be one of DecodeHookFuncType, DecodeHookFuncKind, or -// DecodeHookFuncValue. -// Values are a superset of Types (Values can return types), and Types are a -// superset of Kinds (Types can return Kinds) and are generally a richer thing -// to use, but Kinds are simpler if you only need those. -// -// The reason DecodeHookFunc is multi-typed is for backwards compatibility: -// we started with Kinds and then realized Types were the better solution, -// but have a promise to not break backwards compat so we now support -// both. -type DecodeHookFunc any - -// DecodeHookFuncType is a DecodeHookFunc which has complete information about -// the source and target types. -type DecodeHookFuncType func(reflect.Type, reflect.Type, any) (any, error) - -// DecodeHookFuncKind is a DecodeHookFunc which knows only the Kinds of the -// source and target types. -type DecodeHookFuncKind func(reflect.Kind, reflect.Kind, any) (any, error) - -// DecodeHookFuncValue is a DecodeHookFunc which has complete access to both the source and target -// values. -type DecodeHookFuncValue func(from reflect.Value, to reflect.Value) (any, error) - -// DecoderConfig is the configuration that is used to create a new decoder -// and allows customization of various aspects of decoding. -type DecoderConfig struct { - // DecodeHook, if set, will be called before any decoding and any - // type conversion (if WeaklyTypedInput is on). This lets you modify - // the values before they're set down onto the resulting struct. The - // DecodeHook is called for every map and value in the input. This means - // that if a struct has embedded fields with squash tags the decode hook - // is called only once with all of the input data, not once for each - // embedded struct. - // - // If an error is returned, the entire decode will fail with that error. - DecodeHook DecodeHookFunc - - // If ErrorUnused is true, then it is an error for there to exist - // keys in the original map that were unused in the decoding process - // (extra keys). - ErrorUnused bool - - // If ErrorUnset is true, then it is an error for there to exist - // fields in the result that were not set in the decoding process - // (extra fields). This only applies to decoding to a struct. This - // will affect all nested structs as well. - ErrorUnset bool - - // AllowUnsetPointer, if set to true, will prevent fields with pointer types - // from being reported as unset, even if ErrorUnset is true and the field was - // not present in the input data. This allows pointer fields to be optional - // without triggering an error when they are missing. - AllowUnsetPointer bool - - // ZeroFields, if set to true, will zero fields before writing them. - // For example, a map will be emptied before decoded values are put in - // it. If this is false, a map will be merged. - ZeroFields bool - - // If WeaklyTypedInput is true, the decoder will make the following - // "weak" conversions: - // - // - bools to string (true = "1", false = "0") - // - numbers to string (base 10) - // - bools to int/uint (true = 1, false = 0) - // - strings to int/uint (base implied by prefix) - // - int to bool (true if value != 0) - // - string to bool (accepts: 1, t, T, TRUE, true, True, 0, f, F, - // FALSE, false, False. Anything else is an error) - // - empty array = empty map and vice versa - // - negative numbers to overflowed uint values (base 10) - // - slice of maps to a merged map - // - single values are converted to slices if required. Each - // element is weakly decoded. For example: "4" can become []int{4} - // if the target type is an int slice. - // - WeaklyTypedInput bool - - // Squash will squash embedded structs. A squash tag may also be - // added to an individual struct field using a tag. For example: - // - // type Parent struct { - // Child `mapstructure:",squash"` - // } - Squash bool - - // Metadata is the struct that will contain extra metadata about - // the decoding. If this is nil, then no metadata will be tracked. - Metadata *Metadata - - // Result is a pointer to the struct that will contain the decoded - // value. - Result any - - // The tag name that mapstructure reads for field names. This - // defaults to "mapstructure" - TagName string - - // The option of the value in the tag that indicates a field should - // be squashed. This defaults to "squash". - SquashTagOption string - - // IgnoreUntaggedFields ignores all struct fields without explicit - // TagName, comparable to `mapstructure:"-"` as default behaviour. - IgnoreUntaggedFields bool - - // MatchName is the function used to match the map key to the struct - // field name or tag. Defaults to `strings.EqualFold`. This can be used - // to implement case-sensitive tag values, support snake casing, etc. - MatchName func(mapKey, fieldName string) bool - - // DecodeNil, if set to true, will cause the DecodeHook (if present) to run - // even if the input is nil. This can be used to provide default values. - DecodeNil bool -} - -// A Decoder takes a raw interface value and turns it into structured -// data, keeping track of rich error information along the way in case -// anything goes wrong. Unlike the basic top-level Decode method, you can -// more finely control how the Decoder behaves using the DecoderConfig -// structure. The top-level Decode method is just a convenience that sets -// up the most basic Decoder. -type Decoder struct { - config *DecoderConfig - cachedDecodeHook func(from reflect.Value, to reflect.Value) (any, error) -} - -// Metadata contains information about decoding a structure that -// is tedious or difficult to get otherwise. -type Metadata struct { - // Keys are the keys of the structure which were successfully decoded - Keys []string - - // Unused is a slice of keys that were found in the raw value but - // weren't decoded since there was no matching field in the result interface - Unused []string - - // Unset is a slice of field names that were found in the result interface - // but weren't set in the decoding process since there was no matching value - // in the input - Unset []string -} - -// Decode takes an input structure and uses reflection to translate it to -// the output structure. output must be a pointer to a map or struct. -func Decode(input any, output any) error { - config := &DecoderConfig{ - Metadata: nil, - Result: output, - } - - decoder, err := NewDecoder(config) - if err != nil { - return err - } - - return decoder.Decode(input) -} - -// WeakDecode is the same as Decode but is shorthand to enable -// WeaklyTypedInput. See DecoderConfig for more info. -func WeakDecode(input, output any) error { - config := &DecoderConfig{ - Metadata: nil, - Result: output, - WeaklyTypedInput: true, - } - - decoder, err := NewDecoder(config) - if err != nil { - return err - } - - return decoder.Decode(input) -} - -// DecodeMetadata is the same as Decode, but is shorthand to -// enable metadata collection. See DecoderConfig for more info. -func DecodeMetadata(input any, output any, metadata *Metadata) error { - config := &DecoderConfig{ - Metadata: metadata, - Result: output, - } - - decoder, err := NewDecoder(config) - if err != nil { - return err - } - - return decoder.Decode(input) -} - -// WeakDecodeMetadata is the same as Decode, but is shorthand to -// enable both WeaklyTypedInput and metadata collection. See -// DecoderConfig for more info. -func WeakDecodeMetadata(input any, output any, metadata *Metadata) error { - config := &DecoderConfig{ - Metadata: metadata, - Result: output, - WeaklyTypedInput: true, - } - - decoder, err := NewDecoder(config) - if err != nil { - return err - } - - return decoder.Decode(input) -} - -// NewDecoder returns a new decoder for the given configuration. Once -// a decoder has been returned, the same configuration must not be used -// again. -func NewDecoder(config *DecoderConfig) (*Decoder, error) { - val := reflect.ValueOf(config.Result) - if val.Kind() != reflect.Ptr { - return nil, errors.New("result must be a pointer") - } - - val = val.Elem() - if !val.CanAddr() { - return nil, errors.New("result must be addressable (a pointer)") - } - - if config.Metadata != nil { - if config.Metadata.Keys == nil { - config.Metadata.Keys = make([]string, 0) - } - - if config.Metadata.Unused == nil { - config.Metadata.Unused = make([]string, 0) - } - - if config.Metadata.Unset == nil { - config.Metadata.Unset = make([]string, 0) - } - } - - if config.TagName == "" { - config.TagName = "mapstructure" - } - - if config.SquashTagOption == "" { - config.SquashTagOption = "squash" - } - - if config.MatchName == nil { - config.MatchName = strings.EqualFold - } - - result := &Decoder{ - config: config, - } - if config.DecodeHook != nil { - result.cachedDecodeHook = cachedDecodeHook(config.DecodeHook) - } - - return result, nil -} - -// Decode decodes the given raw interface to the target pointer specified -// by the configuration. -func (d *Decoder) Decode(input any) error { - err := d.decode("", input, reflect.ValueOf(d.config.Result).Elem()) - - // Retain some of the original behavior when multiple errors ocurr - var joinedErr interface{ Unwrap() []error } - if errors.As(err, &joinedErr) { - return fmt.Errorf("decoding failed due to the following error(s):\n\n%w", err) - } - - return err -} - -// isNil returns true if the input is nil or a typed nil pointer. -func isNil(input any) bool { - if input == nil { - return true - } - val := reflect.ValueOf(input) - return val.Kind() == reflect.Ptr && val.IsNil() -} - -// Decodes an unknown data type into a specific reflection value. -func (d *Decoder) decode(name string, input any, outVal reflect.Value) error { - var ( - inputVal = reflect.ValueOf(input) - outputKind = getKind(outVal) - decodeNil = d.config.DecodeNil && d.cachedDecodeHook != nil - ) - if isNil(input) { - // Typed nils won't match the "input == nil" below, so reset input. - input = nil - } - if input == nil { - // If the data is nil, then we don't set anything, unless ZeroFields is set - // to true. - if d.config.ZeroFields { - outVal.Set(reflect.Zero(outVal.Type())) - - if d.config.Metadata != nil && name != "" { - d.config.Metadata.Keys = append(d.config.Metadata.Keys, name) - } - } - if !decodeNil { - return nil - } - } - if !inputVal.IsValid() { - if !decodeNil { - // If the input value is invalid, then we just set the value - // to be the zero value. - outVal.Set(reflect.Zero(outVal.Type())) - if d.config.Metadata != nil && name != "" { - d.config.Metadata.Keys = append(d.config.Metadata.Keys, name) - } - return nil - } - // Hooks need a valid inputVal, so reset it to zero value of outVal type. - switch outputKind { - case reflect.Struct, reflect.Map: - var mapVal map[string]any - inputVal = reflect.ValueOf(mapVal) // create nil map pointer - case reflect.Slice, reflect.Array: - var sliceVal []any - inputVal = reflect.ValueOf(sliceVal) // create nil slice pointer - default: - inputVal = reflect.Zero(outVal.Type()) - } - } - - if d.cachedDecodeHook != nil { - // We have a DecodeHook, so let's pre-process the input. - var err error - input, err = d.cachedDecodeHook(inputVal, outVal) - if err != nil { - return newDecodeError(name, err) - } - } - if isNil(input) { - return nil - } - - var err error - addMetaKey := true - switch outputKind { - case reflect.Bool: - err = d.decodeBool(name, input, outVal) - case reflect.Interface: - err = d.decodeBasic(name, input, outVal) - case reflect.String: - err = d.decodeString(name, input, outVal) - case reflect.Int: - err = d.decodeInt(name, input, outVal) - case reflect.Uint: - err = d.decodeUint(name, input, outVal) - case reflect.Float32: - err = d.decodeFloat(name, input, outVal) - case reflect.Complex64: - err = d.decodeComplex(name, input, outVal) - case reflect.Struct: - err = d.decodeStruct(name, input, outVal) - case reflect.Map: - err = d.decodeMap(name, input, outVal) - case reflect.Ptr: - addMetaKey, err = d.decodePtr(name, input, outVal) - case reflect.Slice: - err = d.decodeSlice(name, input, outVal) - case reflect.Array: - err = d.decodeArray(name, input, outVal) - case reflect.Func: - err = d.decodeFunc(name, input, outVal) - default: - // If we reached this point then we weren't able to decode it - return newDecodeError(name, fmt.Errorf("unsupported type: %s", outputKind)) - } - - // If we reached here, then we successfully decoded SOMETHING, so - // mark the key as used if we're tracking metainput. - if addMetaKey && d.config.Metadata != nil && name != "" { - d.config.Metadata.Keys = append(d.config.Metadata.Keys, name) - } - - return err -} - -// This decodes a basic type (bool, int, string, etc.) and sets the -// value to "data" of that type. -func (d *Decoder) decodeBasic(name string, data any, val reflect.Value) error { - if val.IsValid() && val.Elem().IsValid() { - elem := val.Elem() - - // If we can't address this element, then its not writable. Instead, - // we make a copy of the value (which is a pointer and therefore - // writable), decode into that, and replace the whole value. - copied := false - if !elem.CanAddr() { - copied = true - - // Make *T - copy := reflect.New(elem.Type()) - - // *T = elem - copy.Elem().Set(elem) - - // Set elem so we decode into it - elem = copy - } - - // Decode. If we have an error then return. We also return right - // away if we're not a copy because that means we decoded directly. - if err := d.decode(name, data, elem); err != nil || !copied { - return err - } - - // If we're a copy, we need to set te final result - val.Set(elem.Elem()) - return nil - } - - dataVal := reflect.ValueOf(data) - - // If the input data is a pointer, and the assigned type is the dereference - // of that exact pointer, then indirect it so that we can assign it. - // Example: *string to string - if dataVal.Kind() == reflect.Ptr && dataVal.Type().Elem() == val.Type() { - dataVal = reflect.Indirect(dataVal) - } - - if !dataVal.IsValid() { - dataVal = reflect.Zero(val.Type()) - } - - dataValType := dataVal.Type() - if !dataValType.AssignableTo(val.Type()) { - return newDecodeError(name, &UnconvertibleTypeError{ - Expected: val, - Value: data, - }) - } - - val.Set(dataVal) - return nil -} - -func (d *Decoder) decodeString(name string, data any, val reflect.Value) error { - dataVal := reflect.Indirect(reflect.ValueOf(data)) - dataKind := getKind(dataVal) - - converted := true - switch { - case dataKind == reflect.String: - val.SetString(dataVal.String()) - case dataKind == reflect.Bool && d.config.WeaklyTypedInput: - if dataVal.Bool() { - val.SetString("1") - } else { - val.SetString("0") - } - case dataKind == reflect.Int && d.config.WeaklyTypedInput: - val.SetString(strconv.FormatInt(dataVal.Int(), 10)) - case dataKind == reflect.Uint && d.config.WeaklyTypedInput: - val.SetString(strconv.FormatUint(dataVal.Uint(), 10)) - case dataKind == reflect.Float32 && d.config.WeaklyTypedInput: - val.SetString(strconv.FormatFloat(dataVal.Float(), 'f', -1, 64)) - case dataKind == reflect.Slice && d.config.WeaklyTypedInput, - dataKind == reflect.Array && d.config.WeaklyTypedInput: - dataType := dataVal.Type() - elemKind := dataType.Elem().Kind() - switch elemKind { - case reflect.Uint8: - var uints []uint8 - if dataKind == reflect.Array { - uints = make([]uint8, dataVal.Len(), dataVal.Len()) - for i := range uints { - uints[i] = dataVal.Index(i).Interface().(uint8) - } - } else { - uints = dataVal.Interface().([]uint8) - } - val.SetString(string(uints)) - default: - converted = false - } - default: - converted = false - } - - if !converted { - return newDecodeError(name, &UnconvertibleTypeError{ - Expected: val, - Value: data, - }) - } - - return nil -} - -func (d *Decoder) decodeInt(name string, data any, val reflect.Value) error { - dataVal := reflect.Indirect(reflect.ValueOf(data)) - dataKind := getKind(dataVal) - dataType := dataVal.Type() - - switch { - case dataKind == reflect.Int: - val.SetInt(dataVal.Int()) - case dataKind == reflect.Uint: - val.SetInt(int64(dataVal.Uint())) - case dataKind == reflect.Float32: - val.SetInt(int64(dataVal.Float())) - case dataKind == reflect.Bool && d.config.WeaklyTypedInput: - if dataVal.Bool() { - val.SetInt(1) - } else { - val.SetInt(0) - } - case dataKind == reflect.String && d.config.WeaklyTypedInput: - str := dataVal.String() - if str == "" { - str = "0" - } - - i, err := strconv.ParseInt(str, 0, val.Type().Bits()) - if err == nil { - val.SetInt(i) - } else { - return newDecodeError(name, &ParseError{ - Expected: val, - Value: data, - Err: wrapStrconvNumError(err), - }) - } - case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number": - jn := data.(json.Number) - i, err := jn.Int64() - if err != nil { - return newDecodeError(name, &ParseError{ - Expected: val, - Value: data, - Err: err, - }) - } - val.SetInt(i) - default: - return newDecodeError(name, &UnconvertibleTypeError{ - Expected: val, - Value: data, - }) - } - - return nil -} - -func (d *Decoder) decodeUint(name string, data any, val reflect.Value) error { - dataVal := reflect.Indirect(reflect.ValueOf(data)) - dataKind := getKind(dataVal) - dataType := dataVal.Type() - - switch { - case dataKind == reflect.Int: - i := dataVal.Int() - if i < 0 && !d.config.WeaklyTypedInput { - return newDecodeError(name, &ParseError{ - Expected: val, - Value: data, - Err: fmt.Errorf("%d overflows uint", i), - }) - } - val.SetUint(uint64(i)) - case dataKind == reflect.Uint: - val.SetUint(dataVal.Uint()) - case dataKind == reflect.Float32: - f := dataVal.Float() - if f < 0 && !d.config.WeaklyTypedInput { - return newDecodeError(name, &ParseError{ - Expected: val, - Value: data, - Err: fmt.Errorf("%f overflows uint", f), - }) - } - val.SetUint(uint64(f)) - case dataKind == reflect.Bool && d.config.WeaklyTypedInput: - if dataVal.Bool() { - val.SetUint(1) - } else { - val.SetUint(0) - } - case dataKind == reflect.String && d.config.WeaklyTypedInput: - str := dataVal.String() - if str == "" { - str = "0" - } - - i, err := strconv.ParseUint(str, 0, val.Type().Bits()) - if err == nil { - val.SetUint(i) - } else { - return newDecodeError(name, &ParseError{ - Expected: val, - Value: data, - Err: wrapStrconvNumError(err), - }) - } - case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number": - jn := data.(json.Number) - i, err := strconv.ParseUint(string(jn), 0, 64) - if err != nil { - return newDecodeError(name, &ParseError{ - Expected: val, - Value: data, - Err: wrapStrconvNumError(err), - }) - } - val.SetUint(i) - default: - return newDecodeError(name, &UnconvertibleTypeError{ - Expected: val, - Value: data, - }) - } - - return nil -} - -func (d *Decoder) decodeBool(name string, data any, val reflect.Value) error { - dataVal := reflect.Indirect(reflect.ValueOf(data)) - dataKind := getKind(dataVal) - - switch { - case dataKind == reflect.Bool: - val.SetBool(dataVal.Bool()) - case dataKind == reflect.Int && d.config.WeaklyTypedInput: - val.SetBool(dataVal.Int() != 0) - case dataKind == reflect.Uint && d.config.WeaklyTypedInput: - val.SetBool(dataVal.Uint() != 0) - case dataKind == reflect.Float32 && d.config.WeaklyTypedInput: - val.SetBool(dataVal.Float() != 0) - case dataKind == reflect.String && d.config.WeaklyTypedInput: - b, err := strconv.ParseBool(dataVal.String()) - if err == nil { - val.SetBool(b) - } else if dataVal.String() == "" { - val.SetBool(false) - } else { - return newDecodeError(name, &ParseError{ - Expected: val, - Value: data, - Err: wrapStrconvNumError(err), - }) - } - default: - return newDecodeError(name, &UnconvertibleTypeError{ - Expected: val, - Value: data, - }) - } - - return nil -} - -func (d *Decoder) decodeFloat(name string, data any, val reflect.Value) error { - dataVal := reflect.Indirect(reflect.ValueOf(data)) - dataKind := getKind(dataVal) - dataType := dataVal.Type() - - switch { - case dataKind == reflect.Int: - val.SetFloat(float64(dataVal.Int())) - case dataKind == reflect.Uint: - val.SetFloat(float64(dataVal.Uint())) - case dataKind == reflect.Float32: - val.SetFloat(dataVal.Float()) - case dataKind == reflect.Bool && d.config.WeaklyTypedInput: - if dataVal.Bool() { - val.SetFloat(1) - } else { - val.SetFloat(0) - } - case dataKind == reflect.String && d.config.WeaklyTypedInput: - str := dataVal.String() - if str == "" { - str = "0" - } - - f, err := strconv.ParseFloat(str, val.Type().Bits()) - if err == nil { - val.SetFloat(f) - } else { - return newDecodeError(name, &ParseError{ - Expected: val, - Value: data, - Err: wrapStrconvNumError(err), - }) - } - case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number": - jn := data.(json.Number) - i, err := jn.Float64() - if err != nil { - return newDecodeError(name, &ParseError{ - Expected: val, - Value: data, - Err: err, - }) - } - val.SetFloat(i) - default: - return newDecodeError(name, &UnconvertibleTypeError{ - Expected: val, - Value: data, - }) - } - - return nil -} - -func (d *Decoder) decodeComplex(name string, data any, val reflect.Value) error { - dataVal := reflect.Indirect(reflect.ValueOf(data)) - dataKind := getKind(dataVal) - - switch { - case dataKind == reflect.Complex64: - val.SetComplex(dataVal.Complex()) - default: - return newDecodeError(name, &UnconvertibleTypeError{ - Expected: val, - Value: data, - }) - } - - return nil -} - -func (d *Decoder) decodeMap(name string, data any, val reflect.Value) error { - valType := val.Type() - valKeyType := valType.Key() - valElemType := valType.Elem() - - // By default we overwrite keys in the current map - valMap := val - - // If the map is nil or we're purposely zeroing fields, make a new map - if valMap.IsNil() || d.config.ZeroFields { - // Make a new map to hold our result - mapType := reflect.MapOf(valKeyType, valElemType) - valMap = reflect.MakeMap(mapType) - } - - dataVal := reflect.ValueOf(data) - - // Resolve any levels of indirection - for dataVal.Kind() == reflect.Pointer { - dataVal = reflect.Indirect(dataVal) - } - - // Check input type and based on the input type jump to the proper func - switch dataVal.Kind() { - case reflect.Map: - return d.decodeMapFromMap(name, dataVal, val, valMap) - - case reflect.Struct: - return d.decodeMapFromStruct(name, dataVal, val, valMap) - - case reflect.Array, reflect.Slice: - if d.config.WeaklyTypedInput { - return d.decodeMapFromSlice(name, dataVal, val, valMap) - } - - fallthrough - - default: - return newDecodeError(name, &UnconvertibleTypeError{ - Expected: val, - Value: data, - }) - } -} - -func (d *Decoder) decodeMapFromSlice(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error { - // Special case for BC reasons (covered by tests) - if dataVal.Len() == 0 { - val.Set(valMap) - return nil - } - - for i := 0; i < dataVal.Len(); i++ { - err := d.decode( - name+"["+strconv.Itoa(i)+"]", - dataVal.Index(i).Interface(), val) - if err != nil { - return err - } - } - - return nil -} - -func (d *Decoder) decodeMapFromMap(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error { - valType := val.Type() - valKeyType := valType.Key() - valElemType := valType.Elem() - - // Accumulate errors - var errs []error - - // If the input data is empty, then we just match what the input data is. - if dataVal.Len() == 0 { - if dataVal.IsNil() { - if !val.IsNil() { - val.Set(dataVal) - } - } else { - // Set to empty allocated value - val.Set(valMap) - } - - return nil - } - - for _, k := range dataVal.MapKeys() { - fieldName := name + "[" + k.String() + "]" - - // First decode the key into the proper type - currentKey := reflect.Indirect(reflect.New(valKeyType)) - if err := d.decode(fieldName, k.Interface(), currentKey); err != nil { - errs = append(errs, err) - continue - } - - // Next decode the data into the proper type - v := dataVal.MapIndex(k).Interface() - currentVal := reflect.Indirect(reflect.New(valElemType)) - if err := d.decode(fieldName, v, currentVal); err != nil { - errs = append(errs, err) - continue - } - - valMap.SetMapIndex(currentKey, currentVal) - } - - // Set the built up map to the value - val.Set(valMap) - - return errors.Join(errs...) -} - -func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error { - typ := dataVal.Type() - for i := 0; i < typ.NumField(); i++ { - // Get the StructField first since this is a cheap operation. If the - // field is unexported, then ignore it. - f := typ.Field(i) - if f.PkgPath != "" { - continue - } - - // Next get the actual value of this field and verify it is assignable - // to the map value. - v := dataVal.Field(i) - if !v.Type().AssignableTo(valMap.Type().Elem()) { - return newDecodeError( - name+"."+f.Name, - fmt.Errorf("cannot assign type %q to map value field of type %q", v.Type(), valMap.Type().Elem()), - ) - } - - tagValue := f.Tag.Get(d.config.TagName) - keyName := f.Name - - if tagValue == "" && d.config.IgnoreUntaggedFields { - continue - } - - // If Squash is set in the config, we squash the field down. - squash := d.config.Squash && v.Kind() == reflect.Struct && f.Anonymous - - v = dereferencePtrToStructIfNeeded(v, d.config.TagName) - - // Determine the name of the key in the map - if index := strings.Index(tagValue, ","); index != -1 { - if tagValue[:index] == "-" { - continue - } - // If "omitempty" is specified in the tag, it ignores empty values. - if strings.Index(tagValue[index+1:], "omitempty") != -1 && isEmptyValue(v) { - continue - } - - // If "omitzero" is specified in the tag, it ignores zero values. - if strings.Index(tagValue[index+1:], "omitzero") != -1 && v.IsZero() { - continue - } - - // If "squash" is specified in the tag, we squash the field down. - squash = squash || strings.Contains(tagValue[index+1:], d.config.SquashTagOption) - if squash { - // When squashing, the embedded type can be a pointer to a struct. - if v.Kind() == reflect.Ptr && v.Elem().Kind() == reflect.Struct { - v = v.Elem() - } - - // The final type must be a struct - if v.Kind() != reflect.Struct { - return newDecodeError( - name+"."+f.Name, - fmt.Errorf("cannot squash non-struct type %q", v.Type()), - ) - } - } else { - if strings.Index(tagValue[index+1:], "remain") != -1 { - if v.Kind() != reflect.Map { - return newDecodeError( - name+"."+f.Name, - fmt.Errorf("error remain-tag field with invalid type: %q", v.Type()), - ) - } - - ptr := v.MapRange() - for ptr.Next() { - valMap.SetMapIndex(ptr.Key(), ptr.Value()) - } - continue - } - } - if keyNameTagValue := tagValue[:index]; keyNameTagValue != "" { - keyName = keyNameTagValue - } - } else if len(tagValue) > 0 { - if tagValue == "-" { - continue - } - keyName = tagValue - } - - switch v.Kind() { - // this is an embedded struct, so handle it differently - case reflect.Struct: - x := reflect.New(v.Type()) - x.Elem().Set(v) - - vType := valMap.Type() - vKeyType := vType.Key() - vElemType := vType.Elem() - mType := reflect.MapOf(vKeyType, vElemType) - vMap := reflect.MakeMap(mType) - - // Creating a pointer to a map so that other methods can completely - // overwrite the map if need be (looking at you decodeMapFromMap). The - // indirection allows the underlying map to be settable (CanSet() == true) - // where as reflect.MakeMap returns an unsettable map. - addrVal := reflect.New(vMap.Type()) - reflect.Indirect(addrVal).Set(vMap) - - err := d.decode(keyName, x.Interface(), reflect.Indirect(addrVal)) - if err != nil { - return err - } - - // the underlying map may have been completely overwritten so pull - // it indirectly out of the enclosing value. - vMap = reflect.Indirect(addrVal) - - if squash { - for _, k := range vMap.MapKeys() { - valMap.SetMapIndex(k, vMap.MapIndex(k)) - } - } else { - valMap.SetMapIndex(reflect.ValueOf(keyName), vMap) - } - - default: - valMap.SetMapIndex(reflect.ValueOf(keyName), v) - } - } - - if val.CanAddr() { - val.Set(valMap) - } - - return nil -} - -func (d *Decoder) decodePtr(name string, data any, val reflect.Value) (bool, error) { - // If the input data is nil, then we want to just set the output - // pointer to be nil as well. - isNil := data == nil - if !isNil { - switch v := reflect.Indirect(reflect.ValueOf(data)); v.Kind() { - case reflect.Chan, - reflect.Func, - reflect.Interface, - reflect.Map, - reflect.Ptr, - reflect.Slice: - isNil = v.IsNil() - } - } - if isNil { - if !val.IsNil() && val.CanSet() { - nilValue := reflect.New(val.Type()).Elem() - val.Set(nilValue) - } - - return true, nil - } - - // Create an element of the concrete (non pointer) type and decode - // into that. Then set the value of the pointer to this type. - valType := val.Type() - valElemType := valType.Elem() - if val.CanSet() { - realVal := val - if realVal.IsNil() || d.config.ZeroFields { - realVal = reflect.New(valElemType) - } - - if err := d.decode(name, data, reflect.Indirect(realVal)); err != nil { - return false, err - } - - val.Set(realVal) - } else { - if err := d.decode(name, data, reflect.Indirect(val)); err != nil { - return false, err - } - } - return false, nil -} - -func (d *Decoder) decodeFunc(name string, data any, val reflect.Value) error { - // Create an element of the concrete (non pointer) type and decode - // into that. Then set the value of the pointer to this type. - dataVal := reflect.Indirect(reflect.ValueOf(data)) - if val.Type() != dataVal.Type() { - return newDecodeError(name, &UnconvertibleTypeError{ - Expected: val, - Value: data, - }) - } - val.Set(dataVal) - return nil -} - -func (d *Decoder) decodeSlice(name string, data any, val reflect.Value) error { - dataVal := reflect.Indirect(reflect.ValueOf(data)) - dataValKind := dataVal.Kind() - valType := val.Type() - valElemType := valType.Elem() - sliceType := reflect.SliceOf(valElemType) - - // If we have a non array/slice type then we first attempt to convert. - if dataValKind != reflect.Array && dataValKind != reflect.Slice { - if d.config.WeaklyTypedInput { - switch { - // Slice and array we use the normal logic - case dataValKind == reflect.Slice, dataValKind == reflect.Array: - break - - // Empty maps turn into empty slices - case dataValKind == reflect.Map: - if dataVal.Len() == 0 { - val.Set(reflect.MakeSlice(sliceType, 0, 0)) - return nil - } - // Create slice of maps of other sizes - return d.decodeSlice(name, []any{data}, val) - - case dataValKind == reflect.String && valElemType.Kind() == reflect.Uint8: - return d.decodeSlice(name, []byte(dataVal.String()), val) - - // All other types we try to convert to the slice type - // and "lift" it into it. i.e. a string becomes a string slice. - default: - // Just re-try this function with data as a slice. - return d.decodeSlice(name, []any{data}, val) - } - } - - return newDecodeError(name, - fmt.Errorf("source data must be an array or slice, got %s", dataValKind)) - } - - // If the input value is nil, then don't allocate since empty != nil - if dataValKind != reflect.Array && dataVal.IsNil() { - return nil - } - - valSlice := val - if valSlice.IsNil() || d.config.ZeroFields { - // Make a new slice to hold our result, same size as the original data. - valSlice = reflect.MakeSlice(sliceType, dataVal.Len(), dataVal.Len()) - } else if valSlice.Len() > dataVal.Len() { - valSlice = valSlice.Slice(0, dataVal.Len()) - } - - // Accumulate any errors - var errs []error - - for i := 0; i < dataVal.Len(); i++ { - currentData := dataVal.Index(i).Interface() - for valSlice.Len() <= i { - valSlice = reflect.Append(valSlice, reflect.Zero(valElemType)) - } - currentField := valSlice.Index(i) - - fieldName := name + "[" + strconv.Itoa(i) + "]" - if err := d.decode(fieldName, currentData, currentField); err != nil { - errs = append(errs, err) - } - } - - // Finally, set the value to the slice we built up - val.Set(valSlice) - - return errors.Join(errs...) -} - -func (d *Decoder) decodeArray(name string, data any, val reflect.Value) error { - dataVal := reflect.Indirect(reflect.ValueOf(data)) - dataValKind := dataVal.Kind() - valType := val.Type() - valElemType := valType.Elem() - arrayType := reflect.ArrayOf(valType.Len(), valElemType) - - valArray := val - - if isComparable(valArray) && valArray.Interface() == reflect.Zero(valArray.Type()).Interface() || d.config.ZeroFields { - // Check input type - if dataValKind != reflect.Array && dataValKind != reflect.Slice { - if d.config.WeaklyTypedInput { - switch { - // Empty maps turn into empty arrays - case dataValKind == reflect.Map: - if dataVal.Len() == 0 { - val.Set(reflect.Zero(arrayType)) - return nil - } - - // All other types we try to convert to the array type - // and "lift" it into it. i.e. a string becomes a string array. - default: - // Just re-try this function with data as a slice. - return d.decodeArray(name, []any{data}, val) - } - } - - return newDecodeError(name, - fmt.Errorf("source data must be an array or slice, got %s", dataValKind)) - - } - if dataVal.Len() > arrayType.Len() { - return newDecodeError(name, - fmt.Errorf("expected source data to have length less or equal to %d, got %d", arrayType.Len(), dataVal.Len())) - } - - // Make a new array to hold our result, same size as the original data. - valArray = reflect.New(arrayType).Elem() - } - - // Accumulate any errors - var errs []error - - for i := 0; i < dataVal.Len(); i++ { - currentData := dataVal.Index(i).Interface() - currentField := valArray.Index(i) - - fieldName := name + "[" + strconv.Itoa(i) + "]" - if err := d.decode(fieldName, currentData, currentField); err != nil { - errs = append(errs, err) - } - } - - // Finally, set the value to the array we built up - val.Set(valArray) - - return errors.Join(errs...) -} - -func (d *Decoder) decodeStruct(name string, data any, val reflect.Value) error { - dataVal := reflect.Indirect(reflect.ValueOf(data)) - - // If the type of the value to write to and the data match directly, - // then we just set it directly instead of recursing into the structure. - if dataVal.Type() == val.Type() { - val.Set(dataVal) - return nil - } - - dataValKind := dataVal.Kind() - switch dataValKind { - case reflect.Map: - return d.decodeStructFromMap(name, dataVal, val) - - case reflect.Struct: - // Not the most efficient way to do this but we can optimize later if - // we want to. To convert from struct to struct we go to map first - // as an intermediary. - - // Make a new map to hold our result - mapType := reflect.TypeOf((map[string]any)(nil)) - mval := reflect.MakeMap(mapType) - - // Creating a pointer to a map so that other methods can completely - // overwrite the map if need be (looking at you decodeMapFromMap). The - // indirection allows the underlying map to be settable (CanSet() == true) - // where as reflect.MakeMap returns an unsettable map. - addrVal := reflect.New(mval.Type()) - - reflect.Indirect(addrVal).Set(mval) - if err := d.decodeMapFromStruct(name, dataVal, reflect.Indirect(addrVal), mval); err != nil { - return err - } - - result := d.decodeStructFromMap(name, reflect.Indirect(addrVal), val) - return result - - default: - return newDecodeError(name, - fmt.Errorf("expected a map or struct, got %q", dataValKind)) - } -} - -func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) error { - dataValType := dataVal.Type() - if kind := dataValType.Key().Kind(); kind != reflect.String && kind != reflect.Interface { - return newDecodeError(name, - fmt.Errorf("needs a map with string keys, has %q keys", kind)) - } - - dataValKeys := make(map[reflect.Value]struct{}) - dataValKeysUnused := make(map[any]struct{}) - for _, dataValKey := range dataVal.MapKeys() { - dataValKeys[dataValKey] = struct{}{} - dataValKeysUnused[dataValKey.Interface()] = struct{}{} - } - - targetValKeysUnused := make(map[any]struct{}) - - var errs []error - - // This slice will keep track of all the structs we'll be decoding. - // There can be more than one struct if there are embedded structs - // that are squashed. - structs := make([]reflect.Value, 1, 5) - structs[0] = val - - // Compile the list of all the fields that we're going to be decoding - // from all the structs. - type field struct { - field reflect.StructField - val reflect.Value - } - - // remainField is set to a valid field set with the "remain" tag if - // we are keeping track of remaining values. - var remainField *field - - fields := []field{} - for len(structs) > 0 { - structVal := structs[0] - structs = structs[1:] - - structType := structVal.Type() - - for i := 0; i < structType.NumField(); i++ { - fieldType := structType.Field(i) - fieldVal := structVal.Field(i) - if fieldVal.Kind() == reflect.Ptr && fieldVal.Elem().Kind() == reflect.Struct { - // Handle embedded struct pointers as embedded structs. - fieldVal = fieldVal.Elem() - } - - // If "squash" is specified in the tag, we squash the field down. - squash := d.config.Squash && fieldVal.Kind() == reflect.Struct && fieldType.Anonymous - remain := false - - // We always parse the tags cause we're looking for other tags too - tagParts := strings.Split(fieldType.Tag.Get(d.config.TagName), ",") - for _, tag := range tagParts[1:] { - if tag == d.config.SquashTagOption { - squash = true - break - } - - if tag == "remain" { - remain = true - break - } - } - - if squash { - switch fieldVal.Kind() { - case reflect.Struct: - structs = append(structs, fieldVal) - case reflect.Interface: - if !fieldVal.IsNil() { - structs = append(structs, fieldVal.Elem().Elem()) - } - default: - errs = append(errs, newDecodeError( - name+"."+fieldType.Name, - fmt.Errorf("unsupported type for squash: %s", fieldVal.Kind()), - )) - } - continue - } - - // Build our field - if remain { - remainField = &field{fieldType, fieldVal} - } else { - // Normal struct field, store it away - fields = append(fields, field{fieldType, fieldVal}) - } - } - } - - // for fieldType, field := range fields { - for _, f := range fields { - field, fieldValue := f.field, f.val - fieldName := field.Name - - tagValue := field.Tag.Get(d.config.TagName) - if tagValue == "" && d.config.IgnoreUntaggedFields { - continue - } - tagValue = strings.SplitN(tagValue, ",", 2)[0] - if tagValue != "" { - fieldName = tagValue - } - - rawMapKey := reflect.ValueOf(fieldName) - rawMapVal := dataVal.MapIndex(rawMapKey) - if !rawMapVal.IsValid() { - // Do a slower search by iterating over each key and - // doing case-insensitive search. - for dataValKey := range dataValKeys { - mK, ok := dataValKey.Interface().(string) - if !ok { - // Not a string key - continue - } - - if d.config.MatchName(mK, fieldName) { - rawMapKey = dataValKey - rawMapVal = dataVal.MapIndex(dataValKey) - break - } - } - - if !rawMapVal.IsValid() { - // There was no matching key in the map for the value in - // the struct. Remember it for potential errors and metadata. - if !(d.config.AllowUnsetPointer && fieldValue.Kind() == reflect.Ptr) { - targetValKeysUnused[fieldName] = struct{}{} - } - continue - } - } - - if !fieldValue.IsValid() { - // This should never happen - panic("field is not valid") - } - - // If we can't set the field, then it is unexported or something, - // and we just continue onwards. - if !fieldValue.CanSet() { - continue - } - - // Delete the key we're using from the unused map so we stop tracking - delete(dataValKeysUnused, rawMapKey.Interface()) - - // If the name is empty string, then we're at the root, and we - // don't dot-join the fields. - if name != "" { - fieldName = name + "." + fieldName - } - - if err := d.decode(fieldName, rawMapVal.Interface(), fieldValue); err != nil { - errs = append(errs, err) - } - } - - // If we have a "remain"-tagged field and we have unused keys then - // we put the unused keys directly into the remain field. - if remainField != nil && len(dataValKeysUnused) > 0 { - // Build a map of only the unused values - remain := map[any]any{} - for key := range dataValKeysUnused { - remain[key] = dataVal.MapIndex(reflect.ValueOf(key)).Interface() - } - - // Decode it as-if we were just decoding this map onto our map. - if err := d.decodeMap(name, remain, remainField.val); err != nil { - errs = append(errs, err) - } - - // Set the map to nil so we have none so that the next check will - // not error (ErrorUnused) - dataValKeysUnused = nil - } - - if d.config.ErrorUnused && len(dataValKeysUnused) > 0 { - keys := make([]string, 0, len(dataValKeysUnused)) - for rawKey := range dataValKeysUnused { - keys = append(keys, rawKey.(string)) - } - sort.Strings(keys) - - errs = append(errs, newDecodeError( - name, - fmt.Errorf("has invalid keys: %s", strings.Join(keys, ", ")), - )) - } - - if d.config.ErrorUnset && len(targetValKeysUnused) > 0 { - keys := make([]string, 0, len(targetValKeysUnused)) - for rawKey := range targetValKeysUnused { - keys = append(keys, rawKey.(string)) - } - sort.Strings(keys) - - errs = append(errs, newDecodeError( - name, - fmt.Errorf("has unset fields: %s", strings.Join(keys, ", ")), - )) - } - - if err := errors.Join(errs...); err != nil { - return err - } - - // Add the unused keys to the list of unused keys if we're tracking metadata - if d.config.Metadata != nil { - for rawKey := range dataValKeysUnused { - key := rawKey.(string) - if name != "" { - key = name + "." + key - } - - d.config.Metadata.Unused = append(d.config.Metadata.Unused, key) - } - for rawKey := range targetValKeysUnused { - key := rawKey.(string) - if name != "" { - key = name + "." + key - } - - d.config.Metadata.Unset = append(d.config.Metadata.Unset, key) - } - } - - return nil -} - -func isEmptyValue(v reflect.Value) bool { - switch getKind(v) { - case reflect.Array, reflect.Map, reflect.Slice, reflect.String: - return v.Len() == 0 - case reflect.Bool: - return !v.Bool() - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return v.Int() == 0 - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - return v.Uint() == 0 - case reflect.Float32, reflect.Float64: - return v.Float() == 0 - case reflect.Interface, reflect.Ptr: - return v.IsNil() - } - return false -} - -func getKind(val reflect.Value) reflect.Kind { - kind := val.Kind() - - switch { - case kind >= reflect.Int && kind <= reflect.Int64: - return reflect.Int - case kind >= reflect.Uint && kind <= reflect.Uint64: - return reflect.Uint - case kind >= reflect.Float32 && kind <= reflect.Float64: - return reflect.Float32 - case kind >= reflect.Complex64 && kind <= reflect.Complex128: - return reflect.Complex64 - default: - return kind - } -} - -func isStructTypeConvertibleToMap(typ reflect.Type, checkMapstructureTags bool, tagName string) bool { - for i := 0; i < typ.NumField(); i++ { - f := typ.Field(i) - if f.PkgPath == "" && !checkMapstructureTags { // check for unexported fields - return true - } - if checkMapstructureTags && f.Tag.Get(tagName) != "" { // check for mapstructure tags inside - return true - } - } - return false -} - -func dereferencePtrToStructIfNeeded(v reflect.Value, tagName string) reflect.Value { - if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct { - return v - } - deref := v.Elem() - derefT := deref.Type() - if isStructTypeConvertibleToMap(derefT, true, tagName) { - return deref - } - return v -} diff --git a/vendor/github.com/go-viper/mapstructure/v2/reflect_go1_19.go b/vendor/github.com/go-viper/mapstructure/v2/reflect_go1_19.go deleted file mode 100644 index d0913fff6c..0000000000 --- a/vendor/github.com/go-viper/mapstructure/v2/reflect_go1_19.go +++ /dev/null @@ -1,44 +0,0 @@ -//go:build !go1.20 - -package mapstructure - -import "reflect" - -func isComparable(v reflect.Value) bool { - k := v.Kind() - switch k { - case reflect.Invalid: - return false - - case reflect.Array: - switch v.Type().Elem().Kind() { - case reflect.Interface, reflect.Array, reflect.Struct: - for i := 0; i < v.Type().Len(); i++ { - // if !v.Index(i).Comparable() { - if !isComparable(v.Index(i)) { - return false - } - } - return true - } - return v.Type().Comparable() - - case reflect.Interface: - // return v.Elem().Comparable() - return isComparable(v.Elem()) - - case reflect.Struct: - for i := 0; i < v.NumField(); i++ { - return false - - // if !v.Field(i).Comparable() { - if !isComparable(v.Field(i)) { - return false - } - } - return true - - default: - return v.Type().Comparable() - } -} diff --git a/vendor/github.com/go-viper/mapstructure/v2/reflect_go1_20.go b/vendor/github.com/go-viper/mapstructure/v2/reflect_go1_20.go deleted file mode 100644 index f8255a1b17..0000000000 --- a/vendor/github.com/go-viper/mapstructure/v2/reflect_go1_20.go +++ /dev/null @@ -1,10 +0,0 @@ -//go:build go1.20 - -package mapstructure - -import "reflect" - -// TODO: remove once we drop support for Go <1.20 -func isComparable(v reflect.Value) bool { - return v.Comparable() -} diff --git a/vendor/github.com/go-xmlfmt/xmlfmt/LICENSE b/vendor/github.com/go-xmlfmt/xmlfmt/LICENSE deleted file mode 100644 index 890776ab7c..0000000000 --- a/vendor/github.com/go-xmlfmt/xmlfmt/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2016 go-xmlfmt - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/go-xmlfmt/xmlfmt/README.md b/vendor/github.com/go-xmlfmt/xmlfmt/README.md deleted file mode 100644 index 9f661ea2d2..0000000000 --- a/vendor/github.com/go-xmlfmt/xmlfmt/README.md +++ /dev/null @@ -1,245 +0,0 @@ -# Go XML Formatter - -[![MIT License](http://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) -[![Go Doc](https://img.shields.io/badge/godoc-reference-4b68a3.svg)](https://godoc.org/github.com/go-xmlfmt/xmlfmt) -[![Go Report Card](https://goreportcard.com/badge/github.com/go-xmlfmt/xmlfmt)](https://goreportcard.com/report/github.com/go-xmlfmt/xmlfmt) - -## Synopsis - -The Go XML Formatter, xmlfmt, will format the XML string in a readable way. - -```go -package main - -import "github.com/go-xmlfmt/xmlfmt" - -func main() { - xml1 := `aSome org-or-otherWouldnt you like to knowPatCalifia` - x := xmlfmt.FormatXML(xml1, "\t", " ") - print(x) - - // If the XML Comments have nested tags in them - xml1 = ` Fred - - 23456 ` - x = xmlfmt.FormatXML(xml1, "", " ", true) - print(x) -} - -``` - -Output: - -```xml - - - a - - - - - Some org-or-other - Wouldnt you like to know - - - Pat - Califia - - - - - - - - Fred - - 23456 - -``` - -There is no XML decoding and encoding involved, only pure regular expression matching and replacing. So it is much faster than going through decoding and encoding procedures. Moreover, the exact XML source string is preserved, instead of being changed by the encoder. This is why this package exists in the first place. - -Note that - -- the default line ending is handled by the package automatically now. For Windows it's `CRLF`, and standard for anywhere else. No need to change the default line ending now. -- the case of XML comments nested within XML comments is ***not*** supported. Please avoid them or use any other tools to correct them before using this package. -- don't turn on the `nestedTagsInComments` parameter blindly, as the code has become 10+ times more complicated because of it. - -## Command - -To use it on command line, check out [xmlfmt](https://github.com/AntonioSun/xmlfmt): - - -``` -$ xmlfmt -V -xmlfmt - XML Formatter -Copyright (C) 2016-2022, Antonio Sun - -The xmlfmt will format the XML string without rewriting the document - -Built on 2022-02-06 -Version 1.1.1 - -$ xmlfmt -the required flag `-f, --file' was not specified - -Usage: - xmlfmt [OPTIONS] - -Application Options: - -f, --file= The xml file to read from (or "-" for stdin) [$XMLFMT_FILEI] - -p, --prefix= Each element begins on a new line and this prefix [$XMLFMT_PREFIX] - -i, --indent= Indent string for nested elements (default: ) [$XMLFMT_INDENT] - -n, --nested Nested tags in comments [$XMLFMT_NESTED] - -v, --verbose Verbose mode (Multiple -v options increase the verbosity) - -V, --version Show program version and exit - -Help Options: - -h, --help Show this help message - - -$ curl -sL https://pastebin.com/raw/z3euQ5PR | xmlfmt -f - - - - - a - - - - - Some org-or-other - Wouldnt you like to know - - - Pat - Califia - - - - - -$ curl -sL https://pastebin.com/raw/Zs0qy0qz | tee /tmp/xmlfmt.xml | xmlfmt -f - -n - - - Fred - - 23456 - - -$ XMLFMT_NESTED=true XMLFMT_PREFIX='|' xmlfmt -f /tmp/xmlfmt.xml - -| -| -| Fred -| -| 23456 -| -``` - - -## Justification - -### The format - -The Go XML Formatter is not called XML Beautifier because the result is not *exactly* as what people would expect -- most of the closing tags stays on the same line, just as shown above. Having been looking at the result and thinking over it, I now think it is actually a better way to present it, as those closing tags on the same line are better stay that way in my opinion. I.e., - -When it comes to very big XML strings, which is what I’m dealing every day, saving spaces by not allowing those closing tags taking extra lines is plus instead of negative to me. - -### The alternative - -To format it “properly”, i.e., as what people would normally see, is very hard using pure regular expression. In fact, according to Sam Whited from the go-nuts mlist, - -> Regular expression is, well, regular. This means that they can parse regular grammars, but can't parse context free grammars (like XML). It is actually impossible to use a regex to do this task; it will always be fragile, unfortunately. - -So if the output format is so important to you, then unfortunately you have to go through decoding and encoding procedures. But there are some drawbacks as well, as put by James McGill, in http://stackoverflow.com/questions/21117161, besides such method being slow: - -> I like this solution, but am still in search of a Golang XML formatter/prettyprinter that doesn't rewrite the document (other than formatting whitespace). Marshalling or using the Encoder will change namespace declarations. -> -> For example an element like "< ns1:Element />" will be translated to something like '< Element xmlns="http://bla...bla/ns1" >< /Element >' which seems harmless enough except when the intent is to not alter the xml other than formatting. -- James McGill Nov 12 '15 - -Using Sam's code as an example, - -https://play.golang.org/p/JUqQY3WpW5 - -The above code formats the following XML - -```xml - - - - - - 123 - John Brown - - - - -``` - -into this: - -```xml - -
- - - - 123 - John Brown - - - -
-``` - -I know they are syntactically the same, however the problem is that they *look* totally different. - -That's why there is this package, an XML Beautifier that doesn't rewrite the document. - -## Credit - -The credit goes to **diotalevi** from his post at http://www.perlmonks.org/?node_id=261292. - -However, it does not work for all cases. For example, - -```sh -$ echo '
123John Brown
' | perl -pe 's/(?<=>)\s+(?=<)//g; s(<(/?)([^/>]+)(/?)>\s*(?=(".($1&&($4 eq"
-123 -John Brown - - - - -``` - -I simplified the algorithm, and now it should work for all cases: - -```sh -echo '
123John Brown
' | perl -pe 's/(?<=>)\s+(?=<)//g; s(<(/?)([^>]+)(/?)>)($indent+=$3?0:$1?-1:1;"<$1$2$3>"."\n".(" "x$indent))ge' -``` -```xml - -
-
- - - - - 123 - - John Brown - - - -
-``` - -This package is a direct translate from above Perl code into Go, -then further enhanced by @ruandao and @chenbihao. diff --git a/vendor/github.com/go-xmlfmt/xmlfmt/xmlfmt.go b/vendor/github.com/go-xmlfmt/xmlfmt/xmlfmt.go deleted file mode 100644 index 365a1d0477..0000000000 --- a/vendor/github.com/go-xmlfmt/xmlfmt/xmlfmt.go +++ /dev/null @@ -1,94 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// Porgram: xmlfmt.go -// Purpose: Go XML Beautify from XML string using pure string manipulation -// Authors: Antonio Sun (c) 2016-2022, All rights reserved -//////////////////////////////////////////////////////////////////////////// - -package xmlfmt - -import ( - "html" - "regexp" - "runtime" - "strings" -) - -var ( - reg = regexp.MustCompile(`<([/!]?)([^>]+?)(/?)>`) - reXMLComments = regexp.MustCompile(`(?s)()`) - reSpaces = regexp.MustCompile(`(?s)>\s+<`) - reNewlines = regexp.MustCompile(`\r*\n`) - // NL is the newline string used in XML output. - NL = "\n" -) - -func init() { - // define NL for Windows - if runtime.GOOS == "windows" { - NL = "\r\n" - } -} - -// FormatXML will (purly) reformat the XML string in a readable way, without any rewriting/altering the structure. -// If your XML Comments have nested tags in them, or you're not 100% sure otherwise, pass `true` as the third parameter to this function. But don't turn it on blindly, as the code has become ten times more complicated because of it. -func FormatXML(xmls, prefix, indent string, nestedTagsInComments ...bool) string { - nestedTagsInComment := false - if len(nestedTagsInComments) > 0 { - nestedTagsInComment = nestedTagsInComments[0] - } - src := reSpaces.ReplaceAllString(xmls, "><") - if nestedTagsInComment { - src = reXMLComments.ReplaceAllStringFunc(src, func(m string) string { - parts := reXMLComments.FindStringSubmatch(m) - p2 := reNewlines.ReplaceAllString(parts[2], " ") - return parts[1] + html.EscapeString(p2) + parts[3] - }) - } - rf := replaceTag(prefix, indent) - r := prefix + reg.ReplaceAllStringFunc(src, rf) - if nestedTagsInComment { - r = reXMLComments.ReplaceAllStringFunc(r, func(m string) string { - parts := reXMLComments.FindStringSubmatch(m) - return parts[1] + html.UnescapeString(parts[2]) + parts[3] - }) - } - - return r -} - -// replaceTag returns a closure function to do 's/(?<=>)\s+(?=<)//g; s(<(/?)([^>]+?)(/?)>)($indent+=$3?0:$1?-1:1;"<$1$2$3>"."\n".(" "x$indent))ge' as in Perl -// and deal with comments as well -func replaceTag(prefix, indent string) func(string) string { - indentLevel := 0 - lastEndElem := true - return func(m string) string { - // head elem - if strings.HasPrefix(m, "") { - lastEndElem = true - return NL + prefix + strings.Repeat(indent, indentLevel) + m - } - // comment elem - if strings.HasPrefix(m, " "${filename}" -benchmem - echo "OK" - git checkout ${backup} - sleep 5 - fi -} - - -to=$1 -current=`git rev-parse --abbrev-ref HEAD` - -bench ${to} $2 -bench ${current} $2 - -benchcmp $3 "/tmp/${to}-$2.bench" "/tmp/${current}-$2.bench" diff --git a/vendor/github.com/gobwas/glob/compiler/compiler.go b/vendor/github.com/gobwas/glob/compiler/compiler.go deleted file mode 100644 index 02e7de80a0..0000000000 --- a/vendor/github.com/gobwas/glob/compiler/compiler.go +++ /dev/null @@ -1,525 +0,0 @@ -package compiler - -// TODO use constructor with all matchers, and to their structs private -// TODO glue multiple Text nodes (like after QuoteMeta) - -import ( - "fmt" - "reflect" - - "github.com/gobwas/glob/match" - "github.com/gobwas/glob/syntax/ast" - "github.com/gobwas/glob/util/runes" -) - -func optimizeMatcher(matcher match.Matcher) match.Matcher { - switch m := matcher.(type) { - - case match.Any: - if len(m.Separators) == 0 { - return match.NewSuper() - } - - case match.AnyOf: - if len(m.Matchers) == 1 { - return m.Matchers[0] - } - - return m - - case match.List: - if m.Not == false && len(m.List) == 1 { - return match.NewText(string(m.List)) - } - - return m - - case match.BTree: - m.Left = optimizeMatcher(m.Left) - m.Right = optimizeMatcher(m.Right) - - r, ok := m.Value.(match.Text) - if !ok { - return m - } - - var ( - leftNil = m.Left == nil - rightNil = m.Right == nil - ) - if leftNil && rightNil { - return match.NewText(r.Str) - } - - _, leftSuper := m.Left.(match.Super) - lp, leftPrefix := m.Left.(match.Prefix) - la, leftAny := m.Left.(match.Any) - - _, rightSuper := m.Right.(match.Super) - rs, rightSuffix := m.Right.(match.Suffix) - ra, rightAny := m.Right.(match.Any) - - switch { - case leftSuper && rightSuper: - return match.NewContains(r.Str, false) - - case leftSuper && rightNil: - return match.NewSuffix(r.Str) - - case rightSuper && leftNil: - return match.NewPrefix(r.Str) - - case leftNil && rightSuffix: - return match.NewPrefixSuffix(r.Str, rs.Suffix) - - case rightNil && leftPrefix: - return match.NewPrefixSuffix(lp.Prefix, r.Str) - - case rightNil && leftAny: - return match.NewSuffixAny(r.Str, la.Separators) - - case leftNil && rightAny: - return match.NewPrefixAny(r.Str, ra.Separators) - } - - return m - } - - return matcher -} - -func compileMatchers(matchers []match.Matcher) (match.Matcher, error) { - if len(matchers) == 0 { - return nil, fmt.Errorf("compile error: need at least one matcher") - } - if len(matchers) == 1 { - return matchers[0], nil - } - if m := glueMatchers(matchers); m != nil { - return m, nil - } - - idx := -1 - maxLen := -1 - var val match.Matcher - for i, matcher := range matchers { - if l := matcher.Len(); l != -1 && l >= maxLen { - maxLen = l - idx = i - val = matcher - } - } - - if val == nil { // not found matcher with static length - r, err := compileMatchers(matchers[1:]) - if err != nil { - return nil, err - } - return match.NewBTree(matchers[0], nil, r), nil - } - - left := matchers[:idx] - var right []match.Matcher - if len(matchers) > idx+1 { - right = matchers[idx+1:] - } - - var l, r match.Matcher - var err error - if len(left) > 0 { - l, err = compileMatchers(left) - if err != nil { - return nil, err - } - } - - if len(right) > 0 { - r, err = compileMatchers(right) - if err != nil { - return nil, err - } - } - - return match.NewBTree(val, l, r), nil -} - -func glueMatchers(matchers []match.Matcher) match.Matcher { - if m := glueMatchersAsEvery(matchers); m != nil { - return m - } - if m := glueMatchersAsRow(matchers); m != nil { - return m - } - return nil -} - -func glueMatchersAsRow(matchers []match.Matcher) match.Matcher { - if len(matchers) <= 1 { - return nil - } - - var ( - c []match.Matcher - l int - ) - for _, matcher := range matchers { - if ml := matcher.Len(); ml == -1 { - return nil - } else { - c = append(c, matcher) - l += ml - } - } - return match.NewRow(l, c...) -} - -func glueMatchersAsEvery(matchers []match.Matcher) match.Matcher { - if len(matchers) <= 1 { - return nil - } - - var ( - hasAny bool - hasSuper bool - hasSingle bool - min int - separator []rune - ) - - for i, matcher := range matchers { - var sep []rune - - switch m := matcher.(type) { - case match.Super: - sep = []rune{} - hasSuper = true - - case match.Any: - sep = m.Separators - hasAny = true - - case match.Single: - sep = m.Separators - hasSingle = true - min++ - - case match.List: - if !m.Not { - return nil - } - sep = m.List - hasSingle = true - min++ - - default: - return nil - } - - // initialize - if i == 0 { - separator = sep - } - - if runes.Equal(sep, separator) { - continue - } - - return nil - } - - if hasSuper && !hasAny && !hasSingle { - return match.NewSuper() - } - - if hasAny && !hasSuper && !hasSingle { - return match.NewAny(separator) - } - - if (hasAny || hasSuper) && min > 0 && len(separator) == 0 { - return match.NewMin(min) - } - - every := match.NewEveryOf() - - if min > 0 { - every.Add(match.NewMin(min)) - - if !hasAny && !hasSuper { - every.Add(match.NewMax(min)) - } - } - - if len(separator) > 0 { - every.Add(match.NewContains(string(separator), true)) - } - - return every -} - -func minimizeMatchers(matchers []match.Matcher) []match.Matcher { - var done match.Matcher - var left, right, count int - - for l := 0; l < len(matchers); l++ { - for r := len(matchers); r > l; r-- { - if glued := glueMatchers(matchers[l:r]); glued != nil { - var swap bool - - if done == nil { - swap = true - } else { - cl, gl := done.Len(), glued.Len() - swap = cl > -1 && gl > -1 && gl > cl - swap = swap || count < r-l - } - - if swap { - done = glued - left = l - right = r - count = r - l - } - } - } - } - - if done == nil { - return matchers - } - - next := append(append([]match.Matcher{}, matchers[:left]...), done) - if right < len(matchers) { - next = append(next, matchers[right:]...) - } - - if len(next) == len(matchers) { - return next - } - - return minimizeMatchers(next) -} - -// minimizeAnyOf tries to apply some heuristics to minimize number of nodes in given tree -func minimizeTree(tree *ast.Node) *ast.Node { - switch tree.Kind { - case ast.KindAnyOf: - return minimizeTreeAnyOf(tree) - default: - return nil - } -} - -// minimizeAnyOf tries to find common children of given node of AnyOf pattern -// it searches for common children from left and from right -// if any common children are found – then it returns new optimized ast tree -// else it returns nil -func minimizeTreeAnyOf(tree *ast.Node) *ast.Node { - if !areOfSameKind(tree.Children, ast.KindPattern) { - return nil - } - - commonLeft, commonRight := commonChildren(tree.Children) - commonLeftCount, commonRightCount := len(commonLeft), len(commonRight) - if commonLeftCount == 0 && commonRightCount == 0 { // there are no common parts - return nil - } - - var result []*ast.Node - if commonLeftCount > 0 { - result = append(result, ast.NewNode(ast.KindPattern, nil, commonLeft...)) - } - - var anyOf []*ast.Node - for _, child := range tree.Children { - reuse := child.Children[commonLeftCount : len(child.Children)-commonRightCount] - var node *ast.Node - if len(reuse) == 0 { - // this pattern is completely reduced by commonLeft and commonRight patterns - // so it become nothing - node = ast.NewNode(ast.KindNothing, nil) - } else { - node = ast.NewNode(ast.KindPattern, nil, reuse...) - } - anyOf = appendIfUnique(anyOf, node) - } - switch { - case len(anyOf) == 1 && anyOf[0].Kind != ast.KindNothing: - result = append(result, anyOf[0]) - case len(anyOf) > 1: - result = append(result, ast.NewNode(ast.KindAnyOf, nil, anyOf...)) - } - - if commonRightCount > 0 { - result = append(result, ast.NewNode(ast.KindPattern, nil, commonRight...)) - } - - return ast.NewNode(ast.KindPattern, nil, result...) -} - -func commonChildren(nodes []*ast.Node) (commonLeft, commonRight []*ast.Node) { - if len(nodes) <= 1 { - return - } - - // find node that has least number of children - idx := leastChildren(nodes) - if idx == -1 { - return - } - tree := nodes[idx] - treeLength := len(tree.Children) - - // allocate max able size for rightCommon slice - // to get ability insert elements in reverse order (from end to start) - // without sorting - commonRight = make([]*ast.Node, treeLength) - lastRight := treeLength // will use this to get results as commonRight[lastRight:] - - var ( - breakLeft bool - breakRight bool - commonTotal int - ) - for i, j := 0, treeLength-1; commonTotal < treeLength && j >= 0 && !(breakLeft && breakRight); i, j = i+1, j-1 { - treeLeft := tree.Children[i] - treeRight := tree.Children[j] - - for k := 0; k < len(nodes) && !(breakLeft && breakRight); k++ { - // skip least children node - if k == idx { - continue - } - - restLeft := nodes[k].Children[i] - restRight := nodes[k].Children[j+len(nodes[k].Children)-treeLength] - - breakLeft = breakLeft || !treeLeft.Equal(restLeft) - - // disable searching for right common parts, if left part is already overlapping - breakRight = breakRight || (!breakLeft && j <= i) - breakRight = breakRight || !treeRight.Equal(restRight) - } - - if !breakLeft { - commonTotal++ - commonLeft = append(commonLeft, treeLeft) - } - if !breakRight { - commonTotal++ - lastRight = j - commonRight[j] = treeRight - } - } - - commonRight = commonRight[lastRight:] - - return -} - -func appendIfUnique(target []*ast.Node, val *ast.Node) []*ast.Node { - for _, n := range target { - if reflect.DeepEqual(n, val) { - return target - } - } - return append(target, val) -} - -func areOfSameKind(nodes []*ast.Node, kind ast.Kind) bool { - for _, n := range nodes { - if n.Kind != kind { - return false - } - } - return true -} - -func leastChildren(nodes []*ast.Node) int { - min := -1 - idx := -1 - for i, n := range nodes { - if idx == -1 || (len(n.Children) < min) { - min = len(n.Children) - idx = i - } - } - return idx -} - -func compileTreeChildren(tree *ast.Node, sep []rune) ([]match.Matcher, error) { - var matchers []match.Matcher - for _, desc := range tree.Children { - m, err := compile(desc, sep) - if err != nil { - return nil, err - } - matchers = append(matchers, optimizeMatcher(m)) - } - return matchers, nil -} - -func compile(tree *ast.Node, sep []rune) (m match.Matcher, err error) { - switch tree.Kind { - case ast.KindAnyOf: - // todo this could be faster on pattern_alternatives_combine_lite (see glob_test.go) - if n := minimizeTree(tree); n != nil { - return compile(n, sep) - } - matchers, err := compileTreeChildren(tree, sep) - if err != nil { - return nil, err - } - return match.NewAnyOf(matchers...), nil - - case ast.KindPattern: - if len(tree.Children) == 0 { - return match.NewNothing(), nil - } - matchers, err := compileTreeChildren(tree, sep) - if err != nil { - return nil, err - } - m, err = compileMatchers(minimizeMatchers(matchers)) - if err != nil { - return nil, err - } - - case ast.KindAny: - m = match.NewAny(sep) - - case ast.KindSuper: - m = match.NewSuper() - - case ast.KindSingle: - m = match.NewSingle(sep) - - case ast.KindNothing: - m = match.NewNothing() - - case ast.KindList: - l := tree.Value.(ast.List) - m = match.NewList([]rune(l.Chars), l.Not) - - case ast.KindRange: - r := tree.Value.(ast.Range) - m = match.NewRange(r.Lo, r.Hi, r.Not) - - case ast.KindText: - t := tree.Value.(ast.Text) - m = match.NewText(t.Text) - - default: - return nil, fmt.Errorf("could not compile tree: unknown node type") - } - - return optimizeMatcher(m), nil -} - -func Compile(tree *ast.Node, sep []rune) (match.Matcher, error) { - m, err := compile(tree, sep) - if err != nil { - return nil, err - } - - return m, nil -} diff --git a/vendor/github.com/gobwas/glob/glob.go b/vendor/github.com/gobwas/glob/glob.go deleted file mode 100644 index 2afde343af..0000000000 --- a/vendor/github.com/gobwas/glob/glob.go +++ /dev/null @@ -1,80 +0,0 @@ -package glob - -import ( - "github.com/gobwas/glob/compiler" - "github.com/gobwas/glob/syntax" -) - -// Glob represents compiled glob pattern. -type Glob interface { - Match(string) bool -} - -// Compile creates Glob for given pattern and strings (if any present after pattern) as separators. -// The pattern syntax is: -// -// pattern: -// { term } -// -// term: -// `*` matches any sequence of non-separator characters -// `**` matches any sequence of characters -// `?` matches any single non-separator character -// `[` [ `!` ] { character-range } `]` -// character class (must be non-empty) -// `{` pattern-list `}` -// pattern alternatives -// c matches character c (c != `*`, `**`, `?`, `\`, `[`, `{`, `}`) -// `\` c matches character c -// -// character-range: -// c matches character c (c != `\\`, `-`, `]`) -// `\` c matches character c -// lo `-` hi matches character c for lo <= c <= hi -// -// pattern-list: -// pattern { `,` pattern } -// comma-separated (without spaces) patterns -// -func Compile(pattern string, separators ...rune) (Glob, error) { - ast, err := syntax.Parse(pattern) - if err != nil { - return nil, err - } - - matcher, err := compiler.Compile(ast, separators) - if err != nil { - return nil, err - } - - return matcher, nil -} - -// MustCompile is the same as Compile, except that if Compile returns error, this will panic -func MustCompile(pattern string, separators ...rune) Glob { - g, err := Compile(pattern, separators...) - if err != nil { - panic(err) - } - - return g -} - -// QuoteMeta returns a string that quotes all glob pattern meta characters -// inside the argument text; For example, QuoteMeta(`{foo*}`) returns `\[foo\*\]`. -func QuoteMeta(s string) string { - b := make([]byte, 2*len(s)) - - // a byte loop is correct because all meta characters are ASCII - j := 0 - for i := 0; i < len(s); i++ { - if syntax.Special(s[i]) { - b[j] = '\\' - j++ - } - b[j] = s[i] - j++ - } - - return string(b[0:j]) -} diff --git a/vendor/github.com/gobwas/glob/match/any.go b/vendor/github.com/gobwas/glob/match/any.go deleted file mode 100644 index 514a9a5c45..0000000000 --- a/vendor/github.com/gobwas/glob/match/any.go +++ /dev/null @@ -1,45 +0,0 @@ -package match - -import ( - "fmt" - "github.com/gobwas/glob/util/strings" -) - -type Any struct { - Separators []rune -} - -func NewAny(s []rune) Any { - return Any{s} -} - -func (self Any) Match(s string) bool { - return strings.IndexAnyRunes(s, self.Separators) == -1 -} - -func (self Any) Index(s string) (int, []int) { - found := strings.IndexAnyRunes(s, self.Separators) - switch found { - case -1: - case 0: - return 0, segments0 - default: - s = s[:found] - } - - segments := acquireSegments(len(s)) - for i := range s { - segments = append(segments, i) - } - segments = append(segments, len(s)) - - return 0, segments -} - -func (self Any) Len() int { - return lenNo -} - -func (self Any) String() string { - return fmt.Sprintf("", string(self.Separators)) -} diff --git a/vendor/github.com/gobwas/glob/match/any_of.go b/vendor/github.com/gobwas/glob/match/any_of.go deleted file mode 100644 index 8e65356cdc..0000000000 --- a/vendor/github.com/gobwas/glob/match/any_of.go +++ /dev/null @@ -1,82 +0,0 @@ -package match - -import "fmt" - -type AnyOf struct { - Matchers Matchers -} - -func NewAnyOf(m ...Matcher) AnyOf { - return AnyOf{Matchers(m)} -} - -func (self *AnyOf) Add(m Matcher) error { - self.Matchers = append(self.Matchers, m) - return nil -} - -func (self AnyOf) Match(s string) bool { - for _, m := range self.Matchers { - if m.Match(s) { - return true - } - } - - return false -} - -func (self AnyOf) Index(s string) (int, []int) { - index := -1 - - segments := acquireSegments(len(s)) - for _, m := range self.Matchers { - idx, seg := m.Index(s) - if idx == -1 { - continue - } - - if index == -1 || idx < index { - index = idx - segments = append(segments[:0], seg...) - continue - } - - if idx > index { - continue - } - - // here idx == index - segments = appendMerge(segments, seg) - } - - if index == -1 { - releaseSegments(segments) - return -1, nil - } - - return index, segments -} - -func (self AnyOf) Len() (l int) { - l = -1 - for _, m := range self.Matchers { - ml := m.Len() - switch { - case l == -1: - l = ml - continue - - case ml == -1: - return -1 - - case l != ml: - return -1 - } - } - - return -} - -func (self AnyOf) String() string { - return fmt.Sprintf("", self.Matchers) -} diff --git a/vendor/github.com/gobwas/glob/match/btree.go b/vendor/github.com/gobwas/glob/match/btree.go deleted file mode 100644 index a8130e93ea..0000000000 --- a/vendor/github.com/gobwas/glob/match/btree.go +++ /dev/null @@ -1,146 +0,0 @@ -package match - -import ( - "fmt" - "unicode/utf8" -) - -type BTree struct { - Value Matcher - Left Matcher - Right Matcher - ValueLengthRunes int - LeftLengthRunes int - RightLengthRunes int - LengthRunes int -} - -func NewBTree(Value, Left, Right Matcher) (tree BTree) { - tree.Value = Value - tree.Left = Left - tree.Right = Right - - lenOk := true - if tree.ValueLengthRunes = Value.Len(); tree.ValueLengthRunes == -1 { - lenOk = false - } - - if Left != nil { - if tree.LeftLengthRunes = Left.Len(); tree.LeftLengthRunes == -1 { - lenOk = false - } - } - - if Right != nil { - if tree.RightLengthRunes = Right.Len(); tree.RightLengthRunes == -1 { - lenOk = false - } - } - - if lenOk { - tree.LengthRunes = tree.LeftLengthRunes + tree.ValueLengthRunes + tree.RightLengthRunes - } else { - tree.LengthRunes = -1 - } - - return tree -} - -func (self BTree) Len() int { - return self.LengthRunes -} - -// todo? -func (self BTree) Index(s string) (int, []int) { - return -1, nil -} - -func (self BTree) Match(s string) bool { - inputLen := len(s) - - // self.Length, self.RLen and self.LLen are values meaning the length of runes for each part - // here we manipulating byte length for better optimizations - // but these checks still works, cause minLen of 1-rune string is 1 byte. - if self.LengthRunes != -1 && self.LengthRunes > inputLen { - return false - } - - // try to cut unnecessary parts - // by knowledge of length of right and left part - var offset, limit int - if self.LeftLengthRunes >= 0 { - offset = self.LeftLengthRunes - } - if self.RightLengthRunes >= 0 { - limit = inputLen - self.RightLengthRunes - } else { - limit = inputLen - } - - for offset < limit { - // search for matching part in substring - index, segments := self.Value.Index(s[offset:limit]) - if index == -1 { - releaseSegments(segments) - return false - } - - l := s[:offset+index] - var left bool - if self.Left != nil { - left = self.Left.Match(l) - } else { - left = l == "" - } - - if left { - for i := len(segments) - 1; i >= 0; i-- { - length := segments[i] - - var right bool - var r string - // if there is no string for the right branch - if inputLen <= offset+index+length { - r = "" - } else { - r = s[offset+index+length:] - } - - if self.Right != nil { - right = self.Right.Match(r) - } else { - right = r == "" - } - - if right { - releaseSegments(segments) - return true - } - } - } - - _, step := utf8.DecodeRuneInString(s[offset+index:]) - offset += index + step - - releaseSegments(segments) - } - - return false -} - -func (self BTree) String() string { - const n string = "" - var l, r string - if self.Left == nil { - l = n - } else { - l = self.Left.String() - } - if self.Right == nil { - r = n - } else { - r = self.Right.String() - } - - return fmt.Sprintf("%s]>", l, self.Value, r) -} diff --git a/vendor/github.com/gobwas/glob/match/contains.go b/vendor/github.com/gobwas/glob/match/contains.go deleted file mode 100644 index 0998e95b0e..0000000000 --- a/vendor/github.com/gobwas/glob/match/contains.go +++ /dev/null @@ -1,58 +0,0 @@ -package match - -import ( - "fmt" - "strings" -) - -type Contains struct { - Needle string - Not bool -} - -func NewContains(needle string, not bool) Contains { - return Contains{needle, not} -} - -func (self Contains) Match(s string) bool { - return strings.Contains(s, self.Needle) != self.Not -} - -func (self Contains) Index(s string) (int, []int) { - var offset int - - idx := strings.Index(s, self.Needle) - - if !self.Not { - if idx == -1 { - return -1, nil - } - - offset = idx + len(self.Needle) - if len(s) <= offset { - return 0, []int{offset} - } - s = s[offset:] - } else if idx != -1 { - s = s[:idx] - } - - segments := acquireSegments(len(s) + 1) - for i := range s { - segments = append(segments, offset+i) - } - - return 0, append(segments, offset+len(s)) -} - -func (self Contains) Len() int { - return lenNo -} - -func (self Contains) String() string { - var not string - if self.Not { - not = "!" - } - return fmt.Sprintf("", not, self.Needle) -} diff --git a/vendor/github.com/gobwas/glob/match/every_of.go b/vendor/github.com/gobwas/glob/match/every_of.go deleted file mode 100644 index 7c968ee368..0000000000 --- a/vendor/github.com/gobwas/glob/match/every_of.go +++ /dev/null @@ -1,99 +0,0 @@ -package match - -import ( - "fmt" -) - -type EveryOf struct { - Matchers Matchers -} - -func NewEveryOf(m ...Matcher) EveryOf { - return EveryOf{Matchers(m)} -} - -func (self *EveryOf) Add(m Matcher) error { - self.Matchers = append(self.Matchers, m) - return nil -} - -func (self EveryOf) Len() (l int) { - for _, m := range self.Matchers { - if ml := m.Len(); l > 0 { - l += ml - } else { - return -1 - } - } - - return -} - -func (self EveryOf) Index(s string) (int, []int) { - var index int - var offset int - - // make `in` with cap as len(s), - // cause it is the maximum size of output segments values - next := acquireSegments(len(s)) - current := acquireSegments(len(s)) - - sub := s - for i, m := range self.Matchers { - idx, seg := m.Index(sub) - if idx == -1 { - releaseSegments(next) - releaseSegments(current) - return -1, nil - } - - if i == 0 { - // we use copy here instead of `current = seg` - // cause seg is a slice from reusable buffer `in` - // and it could be overwritten in next iteration - current = append(current, seg...) - } else { - // clear the next - next = next[:0] - - delta := index - (idx + offset) - for _, ex := range current { - for _, n := range seg { - if ex+delta == n { - next = append(next, n) - } - } - } - - if len(next) == 0 { - releaseSegments(next) - releaseSegments(current) - return -1, nil - } - - current = append(current[:0], next...) - } - - index = idx + offset - sub = s[index:] - offset += idx - } - - releaseSegments(next) - - return index, current -} - -func (self EveryOf) Match(s string) bool { - for _, m := range self.Matchers { - if !m.Match(s) { - return false - } - } - - return true -} - -func (self EveryOf) String() string { - return fmt.Sprintf("", self.Matchers) -} diff --git a/vendor/github.com/gobwas/glob/match/list.go b/vendor/github.com/gobwas/glob/match/list.go deleted file mode 100644 index 7fd763ecd8..0000000000 --- a/vendor/github.com/gobwas/glob/match/list.go +++ /dev/null @@ -1,49 +0,0 @@ -package match - -import ( - "fmt" - "github.com/gobwas/glob/util/runes" - "unicode/utf8" -) - -type List struct { - List []rune - Not bool -} - -func NewList(list []rune, not bool) List { - return List{list, not} -} - -func (self List) Match(s string) bool { - r, w := utf8.DecodeRuneInString(s) - if len(s) > w { - return false - } - - inList := runes.IndexRune(self.List, r) != -1 - return inList == !self.Not -} - -func (self List) Len() int { - return lenOne -} - -func (self List) Index(s string) (int, []int) { - for i, r := range s { - if self.Not == (runes.IndexRune(self.List, r) == -1) { - return i, segmentsByRuneLength[utf8.RuneLen(r)] - } - } - - return -1, nil -} - -func (self List) String() string { - var not string - if self.Not { - not = "!" - } - - return fmt.Sprintf("", not, string(self.List)) -} diff --git a/vendor/github.com/gobwas/glob/match/match.go b/vendor/github.com/gobwas/glob/match/match.go deleted file mode 100644 index f80e007fb8..0000000000 --- a/vendor/github.com/gobwas/glob/match/match.go +++ /dev/null @@ -1,81 +0,0 @@ -package match - -// todo common table of rune's length - -import ( - "fmt" - "strings" -) - -const lenOne = 1 -const lenZero = 0 -const lenNo = -1 - -type Matcher interface { - Match(string) bool - Index(string) (int, []int) - Len() int - String() string -} - -type Matchers []Matcher - -func (m Matchers) String() string { - var s []string - for _, matcher := range m { - s = append(s, fmt.Sprint(matcher)) - } - - return fmt.Sprintf("%s", strings.Join(s, ",")) -} - -// appendMerge merges and sorts given already SORTED and UNIQUE segments. -func appendMerge(target, sub []int) []int { - lt, ls := len(target), len(sub) - out := make([]int, 0, lt+ls) - - for x, y := 0, 0; x < lt || y < ls; { - if x >= lt { - out = append(out, sub[y:]...) - break - } - - if y >= ls { - out = append(out, target[x:]...) - break - } - - xValue := target[x] - yValue := sub[y] - - switch { - - case xValue == yValue: - out = append(out, xValue) - x++ - y++ - - case xValue < yValue: - out = append(out, xValue) - x++ - - case yValue < xValue: - out = append(out, yValue) - y++ - - } - } - - target = append(target[:0], out...) - - return target -} - -func reverseSegments(input []int) { - l := len(input) - m := l / 2 - - for i := 0; i < m; i++ { - input[i], input[l-i-1] = input[l-i-1], input[i] - } -} diff --git a/vendor/github.com/gobwas/glob/match/max.go b/vendor/github.com/gobwas/glob/match/max.go deleted file mode 100644 index d72f69efff..0000000000 --- a/vendor/github.com/gobwas/glob/match/max.go +++ /dev/null @@ -1,49 +0,0 @@ -package match - -import ( - "fmt" - "unicode/utf8" -) - -type Max struct { - Limit int -} - -func NewMax(l int) Max { - return Max{l} -} - -func (self Max) Match(s string) bool { - var l int - for range s { - l += 1 - if l > self.Limit { - return false - } - } - - return true -} - -func (self Max) Index(s string) (int, []int) { - segments := acquireSegments(self.Limit + 1) - segments = append(segments, 0) - var count int - for i, r := range s { - count++ - if count > self.Limit { - break - } - segments = append(segments, i+utf8.RuneLen(r)) - } - - return 0, segments -} - -func (self Max) Len() int { - return lenNo -} - -func (self Max) String() string { - return fmt.Sprintf("", self.Limit) -} diff --git a/vendor/github.com/gobwas/glob/match/min.go b/vendor/github.com/gobwas/glob/match/min.go deleted file mode 100644 index db57ac8eb4..0000000000 --- a/vendor/github.com/gobwas/glob/match/min.go +++ /dev/null @@ -1,57 +0,0 @@ -package match - -import ( - "fmt" - "unicode/utf8" -) - -type Min struct { - Limit int -} - -func NewMin(l int) Min { - return Min{l} -} - -func (self Min) Match(s string) bool { - var l int - for range s { - l += 1 - if l >= self.Limit { - return true - } - } - - return false -} - -func (self Min) Index(s string) (int, []int) { - var count int - - c := len(s) - self.Limit + 1 - if c <= 0 { - return -1, nil - } - - segments := acquireSegments(c) - for i, r := range s { - count++ - if count >= self.Limit { - segments = append(segments, i+utf8.RuneLen(r)) - } - } - - if len(segments) == 0 { - return -1, nil - } - - return 0, segments -} - -func (self Min) Len() int { - return lenNo -} - -func (self Min) String() string { - return fmt.Sprintf("", self.Limit) -} diff --git a/vendor/github.com/gobwas/glob/match/nothing.go b/vendor/github.com/gobwas/glob/match/nothing.go deleted file mode 100644 index 0d4ecd36b8..0000000000 --- a/vendor/github.com/gobwas/glob/match/nothing.go +++ /dev/null @@ -1,27 +0,0 @@ -package match - -import ( - "fmt" -) - -type Nothing struct{} - -func NewNothing() Nothing { - return Nothing{} -} - -func (self Nothing) Match(s string) bool { - return len(s) == 0 -} - -func (self Nothing) Index(s string) (int, []int) { - return 0, segments0 -} - -func (self Nothing) Len() int { - return lenZero -} - -func (self Nothing) String() string { - return fmt.Sprintf("") -} diff --git a/vendor/github.com/gobwas/glob/match/prefix.go b/vendor/github.com/gobwas/glob/match/prefix.go deleted file mode 100644 index a7347250e8..0000000000 --- a/vendor/github.com/gobwas/glob/match/prefix.go +++ /dev/null @@ -1,50 +0,0 @@ -package match - -import ( - "fmt" - "strings" - "unicode/utf8" -) - -type Prefix struct { - Prefix string -} - -func NewPrefix(p string) Prefix { - return Prefix{p} -} - -func (self Prefix) Index(s string) (int, []int) { - idx := strings.Index(s, self.Prefix) - if idx == -1 { - return -1, nil - } - - length := len(self.Prefix) - var sub string - if len(s) > idx+length { - sub = s[idx+length:] - } else { - sub = "" - } - - segments := acquireSegments(len(sub) + 1) - segments = append(segments, length) - for i, r := range sub { - segments = append(segments, length+i+utf8.RuneLen(r)) - } - - return idx, segments -} - -func (self Prefix) Len() int { - return lenNo -} - -func (self Prefix) Match(s string) bool { - return strings.HasPrefix(s, self.Prefix) -} - -func (self Prefix) String() string { - return fmt.Sprintf("", self.Prefix) -} diff --git a/vendor/github.com/gobwas/glob/match/prefix_any.go b/vendor/github.com/gobwas/glob/match/prefix_any.go deleted file mode 100644 index 8ee58fe1b3..0000000000 --- a/vendor/github.com/gobwas/glob/match/prefix_any.go +++ /dev/null @@ -1,55 +0,0 @@ -package match - -import ( - "fmt" - "strings" - "unicode/utf8" - - sutil "github.com/gobwas/glob/util/strings" -) - -type PrefixAny struct { - Prefix string - Separators []rune -} - -func NewPrefixAny(s string, sep []rune) PrefixAny { - return PrefixAny{s, sep} -} - -func (self PrefixAny) Index(s string) (int, []int) { - idx := strings.Index(s, self.Prefix) - if idx == -1 { - return -1, nil - } - - n := len(self.Prefix) - sub := s[idx+n:] - i := sutil.IndexAnyRunes(sub, self.Separators) - if i > -1 { - sub = sub[:i] - } - - seg := acquireSegments(len(sub) + 1) - seg = append(seg, n) - for i, r := range sub { - seg = append(seg, n+i+utf8.RuneLen(r)) - } - - return idx, seg -} - -func (self PrefixAny) Len() int { - return lenNo -} - -func (self PrefixAny) Match(s string) bool { - if !strings.HasPrefix(s, self.Prefix) { - return false - } - return sutil.IndexAnyRunes(s[len(self.Prefix):], self.Separators) == -1 -} - -func (self PrefixAny) String() string { - return fmt.Sprintf("", self.Prefix, string(self.Separators)) -} diff --git a/vendor/github.com/gobwas/glob/match/prefix_suffix.go b/vendor/github.com/gobwas/glob/match/prefix_suffix.go deleted file mode 100644 index 8208085a19..0000000000 --- a/vendor/github.com/gobwas/glob/match/prefix_suffix.go +++ /dev/null @@ -1,62 +0,0 @@ -package match - -import ( - "fmt" - "strings" -) - -type PrefixSuffix struct { - Prefix, Suffix string -} - -func NewPrefixSuffix(p, s string) PrefixSuffix { - return PrefixSuffix{p, s} -} - -func (self PrefixSuffix) Index(s string) (int, []int) { - prefixIdx := strings.Index(s, self.Prefix) - if prefixIdx == -1 { - return -1, nil - } - - suffixLen := len(self.Suffix) - if suffixLen <= 0 { - return prefixIdx, []int{len(s) - prefixIdx} - } - - if (len(s) - prefixIdx) <= 0 { - return -1, nil - } - - segments := acquireSegments(len(s) - prefixIdx) - for sub := s[prefixIdx:]; ; { - suffixIdx := strings.LastIndex(sub, self.Suffix) - if suffixIdx == -1 { - break - } - - segments = append(segments, suffixIdx+suffixLen) - sub = sub[:suffixIdx] - } - - if len(segments) == 0 { - releaseSegments(segments) - return -1, nil - } - - reverseSegments(segments) - - return prefixIdx, segments -} - -func (self PrefixSuffix) Len() int { - return lenNo -} - -func (self PrefixSuffix) Match(s string) bool { - return strings.HasPrefix(s, self.Prefix) && strings.HasSuffix(s, self.Suffix) -} - -func (self PrefixSuffix) String() string { - return fmt.Sprintf("", self.Prefix, self.Suffix) -} diff --git a/vendor/github.com/gobwas/glob/match/range.go b/vendor/github.com/gobwas/glob/match/range.go deleted file mode 100644 index ce30245a40..0000000000 --- a/vendor/github.com/gobwas/glob/match/range.go +++ /dev/null @@ -1,48 +0,0 @@ -package match - -import ( - "fmt" - "unicode/utf8" -) - -type Range struct { - Lo, Hi rune - Not bool -} - -func NewRange(lo, hi rune, not bool) Range { - return Range{lo, hi, not} -} - -func (self Range) Len() int { - return lenOne -} - -func (self Range) Match(s string) bool { - r, w := utf8.DecodeRuneInString(s) - if len(s) > w { - return false - } - - inRange := r >= self.Lo && r <= self.Hi - - return inRange == !self.Not -} - -func (self Range) Index(s string) (int, []int) { - for i, r := range s { - if self.Not != (r >= self.Lo && r <= self.Hi) { - return i, segmentsByRuneLength[utf8.RuneLen(r)] - } - } - - return -1, nil -} - -func (self Range) String() string { - var not string - if self.Not { - not = "!" - } - return fmt.Sprintf("", not, string(self.Lo), string(self.Hi)) -} diff --git a/vendor/github.com/gobwas/glob/match/row.go b/vendor/github.com/gobwas/glob/match/row.go deleted file mode 100644 index 4379042e42..0000000000 --- a/vendor/github.com/gobwas/glob/match/row.go +++ /dev/null @@ -1,77 +0,0 @@ -package match - -import ( - "fmt" -) - -type Row struct { - Matchers Matchers - RunesLength int - Segments []int -} - -func NewRow(len int, m ...Matcher) Row { - return Row{ - Matchers: Matchers(m), - RunesLength: len, - Segments: []int{len}, - } -} - -func (self Row) matchAll(s string) bool { - var idx int - for _, m := range self.Matchers { - length := m.Len() - - var next, i int - for next = range s[idx:] { - i++ - if i == length { - break - } - } - - if i < length || !m.Match(s[idx:idx+next+1]) { - return false - } - - idx += next + 1 - } - - return true -} - -func (self Row) lenOk(s string) bool { - var i int - for range s { - i++ - if i > self.RunesLength { - return false - } - } - return self.RunesLength == i -} - -func (self Row) Match(s string) bool { - return self.lenOk(s) && self.matchAll(s) -} - -func (self Row) Len() (l int) { - return self.RunesLength -} - -func (self Row) Index(s string) (int, []int) { - for i := range s { - if len(s[i:]) < self.RunesLength { - break - } - if self.matchAll(s[i:]) { - return i, self.Segments - } - } - return -1, nil -} - -func (self Row) String() string { - return fmt.Sprintf("", self.RunesLength, self.Matchers) -} diff --git a/vendor/github.com/gobwas/glob/match/segments.go b/vendor/github.com/gobwas/glob/match/segments.go deleted file mode 100644 index 9ea6f30943..0000000000 --- a/vendor/github.com/gobwas/glob/match/segments.go +++ /dev/null @@ -1,91 +0,0 @@ -package match - -import ( - "sync" -) - -type SomePool interface { - Get() []int - Put([]int) -} - -var segmentsPools [1024]sync.Pool - -func toPowerOfTwo(v int) int { - v-- - v |= v >> 1 - v |= v >> 2 - v |= v >> 4 - v |= v >> 8 - v |= v >> 16 - v++ - - return v -} - -const ( - cacheFrom = 16 - cacheToAndHigher = 1024 - cacheFromIndex = 15 - cacheToAndHigherIndex = 1023 -) - -var ( - segments0 = []int{0} - segments1 = []int{1} - segments2 = []int{2} - segments3 = []int{3} - segments4 = []int{4} -) - -var segmentsByRuneLength [5][]int = [5][]int{ - 0: segments0, - 1: segments1, - 2: segments2, - 3: segments3, - 4: segments4, -} - -func init() { - for i := cacheToAndHigher; i >= cacheFrom; i >>= 1 { - func(i int) { - segmentsPools[i-1] = sync.Pool{New: func() interface{} { - return make([]int, 0, i) - }} - }(i) - } -} - -func getTableIndex(c int) int { - p := toPowerOfTwo(c) - switch { - case p >= cacheToAndHigher: - return cacheToAndHigherIndex - case p <= cacheFrom: - return cacheFromIndex - default: - return p - 1 - } -} - -func acquireSegments(c int) []int { - // make []int with less capacity than cacheFrom - // is faster than acquiring it from pool - if c < cacheFrom { - return make([]int, 0, c) - } - - return segmentsPools[getTableIndex(c)].Get().([]int)[:0] -} - -func releaseSegments(s []int) { - c := cap(s) - - // make []int with less capacity than cacheFrom - // is faster than acquiring it from pool - if c < cacheFrom { - return - } - - segmentsPools[getTableIndex(c)].Put(s) -} diff --git a/vendor/github.com/gobwas/glob/match/single.go b/vendor/github.com/gobwas/glob/match/single.go deleted file mode 100644 index ee6e3954c1..0000000000 --- a/vendor/github.com/gobwas/glob/match/single.go +++ /dev/null @@ -1,43 +0,0 @@ -package match - -import ( - "fmt" - "github.com/gobwas/glob/util/runes" - "unicode/utf8" -) - -// single represents ? -type Single struct { - Separators []rune -} - -func NewSingle(s []rune) Single { - return Single{s} -} - -func (self Single) Match(s string) bool { - r, w := utf8.DecodeRuneInString(s) - if len(s) > w { - return false - } - - return runes.IndexRune(self.Separators, r) == -1 -} - -func (self Single) Len() int { - return lenOne -} - -func (self Single) Index(s string) (int, []int) { - for i, r := range s { - if runes.IndexRune(self.Separators, r) == -1 { - return i, segmentsByRuneLength[utf8.RuneLen(r)] - } - } - - return -1, nil -} - -func (self Single) String() string { - return fmt.Sprintf("", string(self.Separators)) -} diff --git a/vendor/github.com/gobwas/glob/match/suffix.go b/vendor/github.com/gobwas/glob/match/suffix.go deleted file mode 100644 index 85bea8c68e..0000000000 --- a/vendor/github.com/gobwas/glob/match/suffix.go +++ /dev/null @@ -1,35 +0,0 @@ -package match - -import ( - "fmt" - "strings" -) - -type Suffix struct { - Suffix string -} - -func NewSuffix(s string) Suffix { - return Suffix{s} -} - -func (self Suffix) Len() int { - return lenNo -} - -func (self Suffix) Match(s string) bool { - return strings.HasSuffix(s, self.Suffix) -} - -func (self Suffix) Index(s string) (int, []int) { - idx := strings.Index(s, self.Suffix) - if idx == -1 { - return -1, nil - } - - return 0, []int{idx + len(self.Suffix)} -} - -func (self Suffix) String() string { - return fmt.Sprintf("", self.Suffix) -} diff --git a/vendor/github.com/gobwas/glob/match/suffix_any.go b/vendor/github.com/gobwas/glob/match/suffix_any.go deleted file mode 100644 index c5106f8196..0000000000 --- a/vendor/github.com/gobwas/glob/match/suffix_any.go +++ /dev/null @@ -1,43 +0,0 @@ -package match - -import ( - "fmt" - "strings" - - sutil "github.com/gobwas/glob/util/strings" -) - -type SuffixAny struct { - Suffix string - Separators []rune -} - -func NewSuffixAny(s string, sep []rune) SuffixAny { - return SuffixAny{s, sep} -} - -func (self SuffixAny) Index(s string) (int, []int) { - idx := strings.Index(s, self.Suffix) - if idx == -1 { - return -1, nil - } - - i := sutil.LastIndexAnyRunes(s[:idx], self.Separators) + 1 - - return i, []int{idx + len(self.Suffix) - i} -} - -func (self SuffixAny) Len() int { - return lenNo -} - -func (self SuffixAny) Match(s string) bool { - if !strings.HasSuffix(s, self.Suffix) { - return false - } - return sutil.IndexAnyRunes(s[:len(s)-len(self.Suffix)], self.Separators) == -1 -} - -func (self SuffixAny) String() string { - return fmt.Sprintf("", string(self.Separators), self.Suffix) -} diff --git a/vendor/github.com/gobwas/glob/match/super.go b/vendor/github.com/gobwas/glob/match/super.go deleted file mode 100644 index 3875950bb8..0000000000 --- a/vendor/github.com/gobwas/glob/match/super.go +++ /dev/null @@ -1,33 +0,0 @@ -package match - -import ( - "fmt" -) - -type Super struct{} - -func NewSuper() Super { - return Super{} -} - -func (self Super) Match(s string) bool { - return true -} - -func (self Super) Len() int { - return lenNo -} - -func (self Super) Index(s string) (int, []int) { - segments := acquireSegments(len(s) + 1) - for i := range s { - segments = append(segments, i) - } - segments = append(segments, len(s)) - - return 0, segments -} - -func (self Super) String() string { - return fmt.Sprintf("") -} diff --git a/vendor/github.com/gobwas/glob/match/text.go b/vendor/github.com/gobwas/glob/match/text.go deleted file mode 100644 index 0a17616d3c..0000000000 --- a/vendor/github.com/gobwas/glob/match/text.go +++ /dev/null @@ -1,45 +0,0 @@ -package match - -import ( - "fmt" - "strings" - "unicode/utf8" -) - -// raw represents raw string to match -type Text struct { - Str string - RunesLength int - BytesLength int - Segments []int -} - -func NewText(s string) Text { - return Text{ - Str: s, - RunesLength: utf8.RuneCountInString(s), - BytesLength: len(s), - Segments: []int{len(s)}, - } -} - -func (self Text) Match(s string) bool { - return self.Str == s -} - -func (self Text) Len() int { - return self.RunesLength -} - -func (self Text) Index(s string) (int, []int) { - index := strings.Index(s, self.Str) - if index == -1 { - return -1, nil - } - - return index, self.Segments -} - -func (self Text) String() string { - return fmt.Sprintf("", self.Str) -} diff --git a/vendor/github.com/gobwas/glob/readme.md b/vendor/github.com/gobwas/glob/readme.md deleted file mode 100644 index f58144e733..0000000000 --- a/vendor/github.com/gobwas/glob/readme.md +++ /dev/null @@ -1,148 +0,0 @@ -# glob.[go](https://golang.org) - -[![GoDoc][godoc-image]][godoc-url] [![Build Status][travis-image]][travis-url] - -> Go Globbing Library. - -## Install - -```shell - go get github.com/gobwas/glob -``` - -## Example - -```go - -package main - -import "github.com/gobwas/glob" - -func main() { - var g glob.Glob - - // create simple glob - g = glob.MustCompile("*.github.com") - g.Match("api.github.com") // true - - // quote meta characters and then create simple glob - g = glob.MustCompile(glob.QuoteMeta("*.github.com")) - g.Match("*.github.com") // true - - // create new glob with set of delimiters as ["."] - g = glob.MustCompile("api.*.com", '.') - g.Match("api.github.com") // true - g.Match("api.gi.hub.com") // false - - // create new glob with set of delimiters as ["."] - // but now with super wildcard - g = glob.MustCompile("api.**.com", '.') - g.Match("api.github.com") // true - g.Match("api.gi.hub.com") // true - - // create glob with single symbol wildcard - g = glob.MustCompile("?at") - g.Match("cat") // true - g.Match("fat") // true - g.Match("at") // false - - // create glob with single symbol wildcard and delimiters ['f'] - g = glob.MustCompile("?at", 'f') - g.Match("cat") // true - g.Match("fat") // false - g.Match("at") // false - - // create glob with character-list matchers - g = glob.MustCompile("[abc]at") - g.Match("cat") // true - g.Match("bat") // true - g.Match("fat") // false - g.Match("at") // false - - // create glob with character-list matchers - g = glob.MustCompile("[!abc]at") - g.Match("cat") // false - g.Match("bat") // false - g.Match("fat") // true - g.Match("at") // false - - // create glob with character-range matchers - g = glob.MustCompile("[a-c]at") - g.Match("cat") // true - g.Match("bat") // true - g.Match("fat") // false - g.Match("at") // false - - // create glob with character-range matchers - g = glob.MustCompile("[!a-c]at") - g.Match("cat") // false - g.Match("bat") // false - g.Match("fat") // true - g.Match("at") // false - - // create glob with pattern-alternatives list - g = glob.MustCompile("{cat,bat,[fr]at}") - g.Match("cat") // true - g.Match("bat") // true - g.Match("fat") // true - g.Match("rat") // true - g.Match("at") // false - g.Match("zat") // false -} - -``` - -## Performance - -This library is created for compile-once patterns. This means, that compilation could take time, but -strings matching is done faster, than in case when always parsing template. - -If you will not use compiled `glob.Glob` object, and do `g := glob.MustCompile(pattern); g.Match(...)` every time, then your code will be much more slower. - -Run `go test -bench=.` from source root to see the benchmarks: - -Pattern | Fixture | Match | Speed (ns/op) ---------|---------|-------|-------------- -`[a-z][!a-x]*cat*[h][!b]*eyes*` | `my cat has very bright eyes` | `true` | 432 -`[a-z][!a-x]*cat*[h][!b]*eyes*` | `my dog has very bright eyes` | `false` | 199 -`https://*.google.*` | `https://account.google.com` | `true` | 96 -`https://*.google.*` | `https://google.com` | `false` | 66 -`{https://*.google.*,*yandex.*,*yahoo.*,*mail.ru}` | `http://yahoo.com` | `true` | 163 -`{https://*.google.*,*yandex.*,*yahoo.*,*mail.ru}` | `http://google.com` | `false` | 197 -`{https://*gobwas.com,http://exclude.gobwas.com}` | `https://safe.gobwas.com` | `true` | 22 -`{https://*gobwas.com,http://exclude.gobwas.com}` | `http://safe.gobwas.com` | `false` | 24 -`abc*` | `abcdef` | `true` | 8.15 -`abc*` | `af` | `false` | 5.68 -`*def` | `abcdef` | `true` | 8.84 -`*def` | `af` | `false` | 5.74 -`ab*ef` | `abcdef` | `true` | 15.2 -`ab*ef` | `af` | `false` | 10.4 - -The same things with `regexp` package: - -Pattern | Fixture | Match | Speed (ns/op) ---------|---------|-------|-------------- -`^[a-z][^a-x].*cat.*[h][^b].*eyes.*$` | `my cat has very bright eyes` | `true` | 2553 -`^[a-z][^a-x].*cat.*[h][^b].*eyes.*$` | `my dog has very bright eyes` | `false` | 1383 -`^https:\/\/.*\.google\..*$` | `https://account.google.com` | `true` | 1205 -`^https:\/\/.*\.google\..*$` | `https://google.com` | `false` | 767 -`^(https:\/\/.*\.google\..*|.*yandex\..*|.*yahoo\..*|.*mail\.ru)$` | `http://yahoo.com` | `true` | 1435 -`^(https:\/\/.*\.google\..*|.*yandex\..*|.*yahoo\..*|.*mail\.ru)$` | `http://google.com` | `false` | 1674 -`^(https:\/\/.*gobwas\.com|http://exclude.gobwas.com)$` | `https://safe.gobwas.com` | `true` | 1039 -`^(https:\/\/.*gobwas\.com|http://exclude.gobwas.com)$` | `http://safe.gobwas.com` | `false` | 272 -`^abc.*$` | `abcdef` | `true` | 237 -`^abc.*$` | `af` | `false` | 100 -`^.*def$` | `abcdef` | `true` | 464 -`^.*def$` | `af` | `false` | 265 -`^ab.*ef$` | `abcdef` | `true` | 375 -`^ab.*ef$` | `af` | `false` | 145 - -[godoc-image]: https://godoc.org/github.com/gobwas/glob?status.svg -[godoc-url]: https://godoc.org/github.com/gobwas/glob -[travis-image]: https://travis-ci.org/gobwas/glob.svg?branch=master -[travis-url]: https://travis-ci.org/gobwas/glob - -## Syntax - -Syntax is inspired by [standard wildcards](http://tldp.org/LDP/GNU-Linux-Tools-Summary/html/x11655.htm), -except that `**` is aka super-asterisk, that do not sensitive for separators. \ No newline at end of file diff --git a/vendor/github.com/gobwas/glob/syntax/ast/ast.go b/vendor/github.com/gobwas/glob/syntax/ast/ast.go deleted file mode 100644 index 3220a694a9..0000000000 --- a/vendor/github.com/gobwas/glob/syntax/ast/ast.go +++ /dev/null @@ -1,122 +0,0 @@ -package ast - -import ( - "bytes" - "fmt" -) - -type Node struct { - Parent *Node - Children []*Node - Value interface{} - Kind Kind -} - -func NewNode(k Kind, v interface{}, ch ...*Node) *Node { - n := &Node{ - Kind: k, - Value: v, - } - for _, c := range ch { - Insert(n, c) - } - return n -} - -func (a *Node) Equal(b *Node) bool { - if a.Kind != b.Kind { - return false - } - if a.Value != b.Value { - return false - } - if len(a.Children) != len(b.Children) { - return false - } - for i, c := range a.Children { - if !c.Equal(b.Children[i]) { - return false - } - } - return true -} - -func (a *Node) String() string { - var buf bytes.Buffer - buf.WriteString(a.Kind.String()) - if a.Value != nil { - buf.WriteString(" =") - buf.WriteString(fmt.Sprintf("%v", a.Value)) - } - if len(a.Children) > 0 { - buf.WriteString(" [") - for i, c := range a.Children { - if i > 0 { - buf.WriteString(", ") - } - buf.WriteString(c.String()) - } - buf.WriteString("]") - } - return buf.String() -} - -func Insert(parent *Node, children ...*Node) { - parent.Children = append(parent.Children, children...) - for _, ch := range children { - ch.Parent = parent - } -} - -type List struct { - Not bool - Chars string -} - -type Range struct { - Not bool - Lo, Hi rune -} - -type Text struct { - Text string -} - -type Kind int - -const ( - KindNothing Kind = iota - KindPattern - KindList - KindRange - KindText - KindAny - KindSuper - KindSingle - KindAnyOf -) - -func (k Kind) String() string { - switch k { - case KindNothing: - return "Nothing" - case KindPattern: - return "Pattern" - case KindList: - return "List" - case KindRange: - return "Range" - case KindText: - return "Text" - case KindAny: - return "Any" - case KindSuper: - return "Super" - case KindSingle: - return "Single" - case KindAnyOf: - return "AnyOf" - default: - return "" - } -} diff --git a/vendor/github.com/gobwas/glob/syntax/ast/parser.go b/vendor/github.com/gobwas/glob/syntax/ast/parser.go deleted file mode 100644 index 429b409430..0000000000 --- a/vendor/github.com/gobwas/glob/syntax/ast/parser.go +++ /dev/null @@ -1,157 +0,0 @@ -package ast - -import ( - "errors" - "fmt" - "github.com/gobwas/glob/syntax/lexer" - "unicode/utf8" -) - -type Lexer interface { - Next() lexer.Token -} - -type parseFn func(*Node, Lexer) (parseFn, *Node, error) - -func Parse(lexer Lexer) (*Node, error) { - var parser parseFn - - root := NewNode(KindPattern, nil) - - var ( - tree *Node - err error - ) - for parser, tree = parserMain, root; parser != nil; { - parser, tree, err = parser(tree, lexer) - if err != nil { - return nil, err - } - } - - return root, nil -} - -func parserMain(tree *Node, lex Lexer) (parseFn, *Node, error) { - for { - token := lex.Next() - switch token.Type { - case lexer.EOF: - return nil, tree, nil - - case lexer.Error: - return nil, tree, errors.New(token.Raw) - - case lexer.Text: - Insert(tree, NewNode(KindText, Text{token.Raw})) - return parserMain, tree, nil - - case lexer.Any: - Insert(tree, NewNode(KindAny, nil)) - return parserMain, tree, nil - - case lexer.Super: - Insert(tree, NewNode(KindSuper, nil)) - return parserMain, tree, nil - - case lexer.Single: - Insert(tree, NewNode(KindSingle, nil)) - return parserMain, tree, nil - - case lexer.RangeOpen: - return parserRange, tree, nil - - case lexer.TermsOpen: - a := NewNode(KindAnyOf, nil) - Insert(tree, a) - - p := NewNode(KindPattern, nil) - Insert(a, p) - - return parserMain, p, nil - - case lexer.Separator: - p := NewNode(KindPattern, nil) - Insert(tree.Parent, p) - - return parserMain, p, nil - - case lexer.TermsClose: - return parserMain, tree.Parent.Parent, nil - - default: - return nil, tree, fmt.Errorf("unexpected token: %s", token) - } - } - return nil, tree, fmt.Errorf("unknown error") -} - -func parserRange(tree *Node, lex Lexer) (parseFn, *Node, error) { - var ( - not bool - lo rune - hi rune - chars string - ) - for { - token := lex.Next() - switch token.Type { - case lexer.EOF: - return nil, tree, errors.New("unexpected end") - - case lexer.Error: - return nil, tree, errors.New(token.Raw) - - case lexer.Not: - not = true - - case lexer.RangeLo: - r, w := utf8.DecodeRuneInString(token.Raw) - if len(token.Raw) > w { - return nil, tree, fmt.Errorf("unexpected length of lo character") - } - lo = r - - case lexer.RangeBetween: - // - - case lexer.RangeHi: - r, w := utf8.DecodeRuneInString(token.Raw) - if len(token.Raw) > w { - return nil, tree, fmt.Errorf("unexpected length of lo character") - } - - hi = r - - if hi < lo { - return nil, tree, fmt.Errorf("hi character '%s' should be greater than lo '%s'", string(hi), string(lo)) - } - - case lexer.Text: - chars = token.Raw - - case lexer.RangeClose: - isRange := lo != 0 && hi != 0 - isChars := chars != "" - - if isChars == isRange { - return nil, tree, fmt.Errorf("could not parse range") - } - - if isRange { - Insert(tree, NewNode(KindRange, Range{ - Lo: lo, - Hi: hi, - Not: not, - })) - } else { - Insert(tree, NewNode(KindList, List{ - Chars: chars, - Not: not, - })) - } - - return parserMain, tree, nil - } - } -} diff --git a/vendor/github.com/gobwas/glob/syntax/lexer/lexer.go b/vendor/github.com/gobwas/glob/syntax/lexer/lexer.go deleted file mode 100644 index a1c8d1962a..0000000000 --- a/vendor/github.com/gobwas/glob/syntax/lexer/lexer.go +++ /dev/null @@ -1,273 +0,0 @@ -package lexer - -import ( - "bytes" - "fmt" - "github.com/gobwas/glob/util/runes" - "unicode/utf8" -) - -const ( - char_any = '*' - char_comma = ',' - char_single = '?' - char_escape = '\\' - char_range_open = '[' - char_range_close = ']' - char_terms_open = '{' - char_terms_close = '}' - char_range_not = '!' - char_range_between = '-' -) - -var specials = []byte{ - char_any, - char_single, - char_escape, - char_range_open, - char_range_close, - char_terms_open, - char_terms_close, -} - -func Special(c byte) bool { - return bytes.IndexByte(specials, c) != -1 -} - -type tokens []Token - -func (i *tokens) shift() (ret Token) { - ret = (*i)[0] - copy(*i, (*i)[1:]) - *i = (*i)[:len(*i)-1] - return -} - -func (i *tokens) push(v Token) { - *i = append(*i, v) -} - -func (i *tokens) empty() bool { - return len(*i) == 0 -} - -var eof rune = 0 - -type lexer struct { - data string - pos int - err error - - tokens tokens - termsLevel int - - lastRune rune - lastRuneSize int - hasRune bool -} - -func NewLexer(source string) *lexer { - l := &lexer{ - data: source, - tokens: tokens(make([]Token, 0, 4)), - } - return l -} - -func (l *lexer) Next() Token { - if l.err != nil { - return Token{Error, l.err.Error()} - } - if !l.tokens.empty() { - return l.tokens.shift() - } - - l.fetchItem() - return l.Next() -} - -func (l *lexer) peek() (r rune, w int) { - if l.pos == len(l.data) { - return eof, 0 - } - - r, w = utf8.DecodeRuneInString(l.data[l.pos:]) - if r == utf8.RuneError { - l.errorf("could not read rune") - r = eof - w = 0 - } - - return -} - -func (l *lexer) read() rune { - if l.hasRune { - l.hasRune = false - l.seek(l.lastRuneSize) - return l.lastRune - } - - r, s := l.peek() - l.seek(s) - - l.lastRune = r - l.lastRuneSize = s - - return r -} - -func (l *lexer) seek(w int) { - l.pos += w -} - -func (l *lexer) unread() { - if l.hasRune { - l.errorf("could not unread rune") - return - } - l.seek(-l.lastRuneSize) - l.hasRune = true -} - -func (l *lexer) errorf(f string, v ...interface{}) { - l.err = fmt.Errorf(f, v...) -} - -func (l *lexer) inTerms() bool { - return l.termsLevel > 0 -} - -func (l *lexer) termsEnter() { - l.termsLevel++ -} - -func (l *lexer) termsLeave() { - l.termsLevel-- -} - -var inTextBreakers = []rune{char_single, char_any, char_range_open, char_terms_open} -var inTermsBreakers = append(inTextBreakers, char_terms_close, char_comma) - -func (l *lexer) fetchItem() { - r := l.read() - switch { - case r == eof: - l.tokens.push(Token{EOF, ""}) - - case r == char_terms_open: - l.termsEnter() - l.tokens.push(Token{TermsOpen, string(r)}) - - case r == char_comma && l.inTerms(): - l.tokens.push(Token{Separator, string(r)}) - - case r == char_terms_close && l.inTerms(): - l.tokens.push(Token{TermsClose, string(r)}) - l.termsLeave() - - case r == char_range_open: - l.tokens.push(Token{RangeOpen, string(r)}) - l.fetchRange() - - case r == char_single: - l.tokens.push(Token{Single, string(r)}) - - case r == char_any: - if l.read() == char_any { - l.tokens.push(Token{Super, string(r) + string(r)}) - } else { - l.unread() - l.tokens.push(Token{Any, string(r)}) - } - - default: - l.unread() - - var breakers []rune - if l.inTerms() { - breakers = inTermsBreakers - } else { - breakers = inTextBreakers - } - l.fetchText(breakers) - } -} - -func (l *lexer) fetchRange() { - var wantHi bool - var wantClose bool - var seenNot bool - for { - r := l.read() - if r == eof { - l.errorf("unexpected end of input") - return - } - - if wantClose { - if r != char_range_close { - l.errorf("expected close range character") - } else { - l.tokens.push(Token{RangeClose, string(r)}) - } - return - } - - if wantHi { - l.tokens.push(Token{RangeHi, string(r)}) - wantClose = true - continue - } - - if !seenNot && r == char_range_not { - l.tokens.push(Token{Not, string(r)}) - seenNot = true - continue - } - - if n, w := l.peek(); n == char_range_between { - l.seek(w) - l.tokens.push(Token{RangeLo, string(r)}) - l.tokens.push(Token{RangeBetween, string(n)}) - wantHi = true - continue - } - - l.unread() // unread first peek and fetch as text - l.fetchText([]rune{char_range_close}) - wantClose = true - } -} - -func (l *lexer) fetchText(breakers []rune) { - var data []rune - var escaped bool - -reading: - for { - r := l.read() - if r == eof { - break - } - - if !escaped { - if r == char_escape { - escaped = true - continue - } - - if runes.IndexRune(breakers, r) != -1 { - l.unread() - break reading - } - } - - escaped = false - data = append(data, r) - } - - if len(data) > 0 { - l.tokens.push(Token{Text, string(data)}) - } -} diff --git a/vendor/github.com/gobwas/glob/syntax/lexer/token.go b/vendor/github.com/gobwas/glob/syntax/lexer/token.go deleted file mode 100644 index 2797c4e83a..0000000000 --- a/vendor/github.com/gobwas/glob/syntax/lexer/token.go +++ /dev/null @@ -1,88 +0,0 @@ -package lexer - -import "fmt" - -type TokenType int - -const ( - EOF TokenType = iota - Error - Text - Char - Any - Super - Single - Not - Separator - RangeOpen - RangeClose - RangeLo - RangeHi - RangeBetween - TermsOpen - TermsClose -) - -func (tt TokenType) String() string { - switch tt { - case EOF: - return "eof" - - case Error: - return "error" - - case Text: - return "text" - - case Char: - return "char" - - case Any: - return "any" - - case Super: - return "super" - - case Single: - return "single" - - case Not: - return "not" - - case Separator: - return "separator" - - case RangeOpen: - return "range_open" - - case RangeClose: - return "range_close" - - case RangeLo: - return "range_lo" - - case RangeHi: - return "range_hi" - - case RangeBetween: - return "range_between" - - case TermsOpen: - return "terms_open" - - case TermsClose: - return "terms_close" - - default: - return "undef" - } -} - -type Token struct { - Type TokenType - Raw string -} - -func (t Token) String() string { - return fmt.Sprintf("%v<%q>", t.Type, t.Raw) -} diff --git a/vendor/github.com/gobwas/glob/syntax/syntax.go b/vendor/github.com/gobwas/glob/syntax/syntax.go deleted file mode 100644 index 1d168b1482..0000000000 --- a/vendor/github.com/gobwas/glob/syntax/syntax.go +++ /dev/null @@ -1,14 +0,0 @@ -package syntax - -import ( - "github.com/gobwas/glob/syntax/ast" - "github.com/gobwas/glob/syntax/lexer" -) - -func Parse(s string) (*ast.Node, error) { - return ast.Parse(lexer.NewLexer(s)) -} - -func Special(b byte) bool { - return lexer.Special(b) -} diff --git a/vendor/github.com/gobwas/glob/util/runes/runes.go b/vendor/github.com/gobwas/glob/util/runes/runes.go deleted file mode 100644 index a723556410..0000000000 --- a/vendor/github.com/gobwas/glob/util/runes/runes.go +++ /dev/null @@ -1,154 +0,0 @@ -package runes - -func Index(s, needle []rune) int { - ls, ln := len(s), len(needle) - - switch { - case ln == 0: - return 0 - case ln == 1: - return IndexRune(s, needle[0]) - case ln == ls: - if Equal(s, needle) { - return 0 - } - return -1 - case ln > ls: - return -1 - } - -head: - for i := 0; i < ls && ls-i >= ln; i++ { - for y := 0; y < ln; y++ { - if s[i+y] != needle[y] { - continue head - } - } - - return i - } - - return -1 -} - -func LastIndex(s, needle []rune) int { - ls, ln := len(s), len(needle) - - switch { - case ln == 0: - if ls == 0 { - return 0 - } - return ls - case ln == 1: - return IndexLastRune(s, needle[0]) - case ln == ls: - if Equal(s, needle) { - return 0 - } - return -1 - case ln > ls: - return -1 - } - -head: - for i := ls - 1; i >= 0 && i >= ln; i-- { - for y := ln - 1; y >= 0; y-- { - if s[i-(ln-y-1)] != needle[y] { - continue head - } - } - - return i - ln + 1 - } - - return -1 -} - -// IndexAny returns the index of the first instance of any Unicode code point -// from chars in s, or -1 if no Unicode code point from chars is present in s. -func IndexAny(s, chars []rune) int { - if len(chars) > 0 { - for i, c := range s { - for _, m := range chars { - if c == m { - return i - } - } - } - } - return -1 -} - -func Contains(s, needle []rune) bool { - return Index(s, needle) >= 0 -} - -func Max(s []rune) (max rune) { - for _, r := range s { - if r > max { - max = r - } - } - - return -} - -func Min(s []rune) rune { - min := rune(-1) - for _, r := range s { - if min == -1 { - min = r - continue - } - - if r < min { - min = r - } - } - - return min -} - -func IndexRune(s []rune, r rune) int { - for i, c := range s { - if c == r { - return i - } - } - return -1 -} - -func IndexLastRune(s []rune, r rune) int { - for i := len(s) - 1; i >= 0; i-- { - if s[i] == r { - return i - } - } - - return -1 -} - -func Equal(a, b []rune) bool { - if len(a) == len(b) { - for i := 0; i < len(a); i++ { - if a[i] != b[i] { - return false - } - } - - return true - } - - return false -} - -// HasPrefix tests whether the string s begins with prefix. -func HasPrefix(s, prefix []rune) bool { - return len(s) >= len(prefix) && Equal(s[0:len(prefix)], prefix) -} - -// HasSuffix tests whether the string s ends with suffix. -func HasSuffix(s, suffix []rune) bool { - return len(s) >= len(suffix) && Equal(s[len(s)-len(suffix):], suffix) -} diff --git a/vendor/github.com/gobwas/glob/util/strings/strings.go b/vendor/github.com/gobwas/glob/util/strings/strings.go deleted file mode 100644 index e8ee1920b1..0000000000 --- a/vendor/github.com/gobwas/glob/util/strings/strings.go +++ /dev/null @@ -1,39 +0,0 @@ -package strings - -import ( - "strings" - "unicode/utf8" -) - -func IndexAnyRunes(s string, rs []rune) int { - for _, r := range rs { - if i := strings.IndexRune(s, r); i != -1 { - return i - } - } - - return -1 -} - -func LastIndexAnyRunes(s string, rs []rune) int { - for _, r := range rs { - i := -1 - if 0 <= r && r < utf8.RuneSelf { - i = strings.LastIndexByte(s, byte(r)) - } else { - sub := s - for len(sub) > 0 { - j := strings.IndexRune(s, r) - if j == -1 { - break - } - i = j - sub = sub[i+1:] - } - } - if i != -1 { - return i - } - } - return -1 -} diff --git a/vendor/github.com/godoc-lint/godoc-lint/LICENSE b/vendor/github.com/godoc-lint/godoc-lint/LICENSE deleted file mode 100644 index f51a8f9b58..0000000000 --- a/vendor/github.com/godoc-lint/godoc-lint/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2025 Babak K. Shandiz - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/godoc-lint/godoc-lint/pkg/analysis/analyzer.go b/vendor/github.com/godoc-lint/godoc-lint/pkg/analysis/analyzer.go deleted file mode 100644 index 0523900586..0000000000 --- a/vendor/github.com/godoc-lint/godoc-lint/pkg/analysis/analyzer.go +++ /dev/null @@ -1,108 +0,0 @@ -// Package analysis provides the main analyzer implementation. -package analysis - -import ( - "errors" - "fmt" - "path/filepath" - - "golang.org/x/tools/go/analysis" - - "github.com/godoc-lint/godoc-lint/pkg/model" - "github.com/godoc-lint/godoc-lint/pkg/util" -) - -const ( - metaName = "godoclint" - metaDoc = "Checks Golang's documentation practice (godoc)" - metaURL = "https://github.com/godoc-lint/godoc-lint" -) - -// Analyzer implements the godoc-lint analyzer. -type Analyzer struct { - baseDir string - cb model.ConfigBuilder - inspector model.Inspector - reg model.Registry - exitFunc func(int, error) - - analyzer *analysis.Analyzer -} - -// NewAnalyzer returns a new instance of the corresponding analyzer. -func NewAnalyzer(baseDir string, cb model.ConfigBuilder, reg model.Registry, inspector model.Inspector, exitFunc func(int, error)) *Analyzer { - result := &Analyzer{ - baseDir: baseDir, - cb: cb, - reg: reg, - inspector: inspector, - exitFunc: exitFunc, - analyzer: &analysis.Analyzer{ - Name: metaName, - Doc: metaDoc, - URL: metaURL, - Requires: []*analysis.Analyzer{inspector.GetAnalyzer()}, - }, - } - - result.analyzer.Run = result.run - return result -} - -// GetAnalyzer returns the underlying analyzer. -func (a *Analyzer) GetAnalyzer() *analysis.Analyzer { - return a.analyzer -} - -func (a *Analyzer) run(pass *analysis.Pass) (any, error) { - if len(pass.Files) == 0 { - return nil, nil - } - - ft := util.GetPassFileToken(pass.Files[0], pass) - if ft == nil { - err := errors.New("cannot prepare config") - if a.exitFunc != nil { - a.exitFunc(2, err) - } - return nil, err - } - - if !util.IsPathUnderBaseDir(a.baseDir, ft.Name()) { - return nil, nil - } - - pkgDir := filepath.Dir(ft.Name()) - cfg, err := a.cb.GetConfig(pkgDir) - if err != nil { - err := fmt.Errorf("cannot prepare config: %w", err) - if a.exitFunc != nil { - a.exitFunc(2, err) - } - return nil, err - } - - ir := pass.ResultOf[a.inspector.GetAnalyzer()].(*model.InspectorResult) - if ir == nil || ir.Files == nil { - return nil, nil - } - - actx := &model.AnalysisContext{ - Config: cfg, - InspectorResult: ir, - Pass: pass, - } - - for _, checker := range a.reg.List() { - // TODO(babakks): This can be done once to improve performance. - ruleSet := checker.GetCoveredRules() - if !actx.Config.IsAnyRuleApplicable(ruleSet) { - continue - } - - if err := checker.Apply(actx); err != nil { - return nil, fmt.Errorf("checker error: %w", err) - } - } - return nil, nil -} diff --git a/vendor/github.com/godoc-lint/godoc-lint/pkg/check/deprecated/deprecated.go b/vendor/github.com/godoc-lint/godoc-lint/pkg/check/deprecated/deprecated.go deleted file mode 100644 index 08915f6c73..0000000000 --- a/vendor/github.com/godoc-lint/godoc-lint/pkg/check/deprecated/deprecated.go +++ /dev/null @@ -1,114 +0,0 @@ -// Package deprecated provides a checker for correct usage of deprecation -// markers. -package deprecated - -import ( - "go/ast" - "go/doc/comment" - "regexp" - - "github.com/godoc-lint/godoc-lint/pkg/model" - "github.com/godoc-lint/godoc-lint/pkg/util" -) - -const deprecatedRule = model.DeprecatedRule - -var ruleSet = model.RuleSet{}.Add(deprecatedRule) - -// DeprecatedChecker checks correct usage of "Deprecated:" markers. -type DeprecatedChecker struct{} - -// NewDeprecatedChecker returns a new instance of the corresponding checker. -func NewDeprecatedChecker() *DeprecatedChecker { - return &DeprecatedChecker{} -} - -// GetCoveredRules implements the corresponding interface method. -func (r *DeprecatedChecker) GetCoveredRules() model.RuleSet { - return ruleSet -} - -// Apply implements the corresponding interface method. -func (r *DeprecatedChecker) Apply(actx *model.AnalysisContext) error { - docs := make(map[*model.CommentGroup]struct{}, 10*len(actx.InspectorResult.Files)) - - for _, ir := range util.AnalysisApplicableFiles(actx, false, model.RuleSet{}.Add(deprecatedRule)) { - if ir.PackageDoc != nil { - docs[ir.PackageDoc] = struct{}{} - } - - for _, sd := range ir.SymbolDecl { - isExported := ast.IsExported(sd.Name) - if !isExported { - continue - } - - if sd.ParentDoc != nil { - docs[sd.ParentDoc] = struct{}{} - } - if sd.Doc == nil { - continue - } - docs[sd.Doc] = struct{}{} - } - } - - for doc := range docs { - checkDeprecations(actx, doc) - } - return nil -} - -// probableDeprecationRE finds probable deprecation markers, including the -// correct usage. -var probableDeprecationRE = regexp.MustCompile(`(?i)^deprecated:.?`) - -const correctDeprecationMarker = "Deprecated: " - -func checkDeprecations(actx *model.AnalysisContext, doc *model.CommentGroup) { - if doc.DisabledRules.All || doc.DisabledRules.Rules.Has(deprecatedRule) { - return - } - - for _, block := range doc.Parsed.Content { - // The correct usage of deprecation markers is to put them at the beginning - // of a paragraph (i.e. not a heading, code block, etc). Also the syntax is - // strict and must only be "Deprecated: " (case-sensitive and with the - // trailing whitespace). - // - // However, not all wrong usages are reliably discoverable. For example: - // - // // Foo is a symbol. - // // deprecated: use Bar. - // // func Foo() {} - // - // In this cases, the "deprecated: " marker is at the beginning of a new - // line, but as of godoc parser, it's just in the middle of the paragraph - // started at the top line. There might be some smart ways to detect these - // cases, but the problem is there will be false-positives to them. For - // instance, a valid case like this should never be detected as a wrong - // usage: - // - // // Foo is a symbol but here are the reasons why it's - // // deprecated: blah, blah, ... - // // func Foo() {} - // - // Needless to say we don't want to deal with human language complexities. - - par, ok := block.(*comment.Paragraph) - if !ok || len(par.Text) == 0 { - continue - } - text, ok := (par.Text[0]).(comment.Plain) - if !ok { - continue - } - - if match := probableDeprecationRE.FindString(string(text)); match == "" || match == correctDeprecationMarker { - continue - } - - actx.Pass.ReportRangef(&doc.CG, "deprecation note should be formatted as %q", correctDeprecationMarker) - break - } -} diff --git a/vendor/github.com/godoc-lint/godoc-lint/pkg/check/max_len/max_len.go b/vendor/github.com/godoc-lint/godoc-lint/pkg/check/max_len/max_len.go deleted file mode 100644 index 1d647c49ed..0000000000 --- a/vendor/github.com/godoc-lint/godoc-lint/pkg/check/max_len/max_len.go +++ /dev/null @@ -1,96 +0,0 @@ -// Package max_len provides a checker for maximum line length of godocs. -package max_len - -import ( - "fmt" - gdc "go/doc/comment" - "strings" - "unicode/utf8" - - "github.com/godoc-lint/godoc-lint/pkg/model" - "github.com/godoc-lint/godoc-lint/pkg/util" -) - -const maxLenRule = model.MaxLenRule - -var ruleSet = model.RuleSet{}.Add(maxLenRule) - -// MaxLenChecker checks maximum line length of godocs. -type MaxLenChecker struct{} - -// NewMaxLenChecker returns a new instance of the corresponding checker. -func NewMaxLenChecker() *MaxLenChecker { - return &MaxLenChecker{} -} - -// GetCoveredRules implements the corresponding interface method. -func (r *MaxLenChecker) GetCoveredRules() model.RuleSet { - return ruleSet -} - -// Apply implements the corresponding interface method. -func (r *MaxLenChecker) Apply(actx *model.AnalysisContext) error { - includeTests := actx.Config.GetRuleOptions().MaxLenIncludeTests - maxLen := int(actx.Config.GetRuleOptions().MaxLenLength) - - docs := make(map[*model.CommentGroup]struct{}, 10*len(actx.InspectorResult.Files)) - - for _, ir := range util.AnalysisApplicableFiles(actx, includeTests, model.RuleSet{}.Add(maxLenRule)) { - if ir.PackageDoc != nil { - docs[ir.PackageDoc] = struct{}{} - } - - for _, sd := range ir.SymbolDecl { - if sd.ParentDoc != nil { - docs[sd.ParentDoc] = struct{}{} - } - if sd.Doc == nil { - continue - } - docs[sd.Doc] = struct{}{} - } - } - - for doc := range docs { - checkMaxLen(actx, doc, maxLen) - } - return nil -} - -func checkMaxLen(actx *model.AnalysisContext, doc *model.CommentGroup, maxLen int) { - if doc.DisabledRules.All || doc.DisabledRules.Rules.Has(maxLenRule) { - return - } - - linkDefsMap := make(map[string]struct{}, len(doc.Parsed.Links)) - for _, linkDef := range doc.Parsed.Links { - linkDefLine := fmt.Sprintf("[%s]: %s", linkDef.Text, linkDef.URL) - linkDefsMap[linkDefLine] = struct{}{} - } - - nonCodeBlocks := make([]gdc.Block, 0, len(doc.Parsed.Content)) - for _, b := range doc.Parsed.Content { - if _, ok := b.(*gdc.Code); ok { - continue - } - nonCodeBlocks = append(nonCodeBlocks, b) - } - strippedCodeAndLinks := &gdc.Doc{ - Content: nonCodeBlocks, - } - text := string((&gdc.Printer{}).Comment(strippedCodeAndLinks)) - linesIter := strings.SplitSeq(removeCarriageReturn(text), "\n") - - for l := range linesIter { - lineLen := utf8.RuneCountInString(l) - if lineLen <= maxLen { - continue - } - actx.Pass.ReportRangef(&doc.CG, "godoc line is too long (%d > %d)", lineLen, maxLen) - break - } -} - -func removeCarriageReturn(s string) string { - return strings.ReplaceAll(s, "\r", "") -} diff --git a/vendor/github.com/godoc-lint/godoc-lint/pkg/check/no_unused_link/no_unused_link.go b/vendor/github.com/godoc-lint/godoc-lint/pkg/check/no_unused_link/no_unused_link.go deleted file mode 100644 index 8910204bef..0000000000 --- a/vendor/github.com/godoc-lint/godoc-lint/pkg/check/no_unused_link/no_unused_link.go +++ /dev/null @@ -1,69 +0,0 @@ -// Package no_unused_link provides a checker for unused links in godocs. -package no_unused_link - -import ( - "github.com/godoc-lint/godoc-lint/pkg/model" - "github.com/godoc-lint/godoc-lint/pkg/util" -) - -const noUnusedLinkRule = model.NoUnusedLinkRule - -var ruleSet = model.RuleSet{}.Add(noUnusedLinkRule) - -// NoUnusedLinkChecker checks for unused links. -type NoUnusedLinkChecker struct{} - -// NewNoUnusedLinkChecker returns a new instance of the corresponding checker. -func NewNoUnusedLinkChecker() *NoUnusedLinkChecker { - return &NoUnusedLinkChecker{} -} - -// GetCoveredRules implements the corresponding interface method. -func (r *NoUnusedLinkChecker) GetCoveredRules() model.RuleSet { - return ruleSet -} - -// Apply implements the corresponding interface method. -func (r *NoUnusedLinkChecker) Apply(actx *model.AnalysisContext) error { - includeTests := actx.Config.GetRuleOptions().NoUnusedLinkIncludeTests - - docs := make(map[*model.CommentGroup]struct{}, 10*len(actx.InspectorResult.Files)) - - for _, ir := range util.AnalysisApplicableFiles(actx, includeTests, model.RuleSet{}.Add(noUnusedLinkRule)) { - if ir.PackageDoc != nil { - docs[ir.PackageDoc] = struct{}{} - } - - for _, sd := range ir.SymbolDecl { - if sd.ParentDoc != nil { - docs[sd.ParentDoc] = struct{}{} - } - if sd.Doc == nil { - continue - } - docs[sd.Doc] = struct{}{} - } - } - - for doc := range docs { - checkNoUnusedLink(actx, doc) - } - return nil -} - -func checkNoUnusedLink(actx *model.AnalysisContext, doc *model.CommentGroup) { - if doc.DisabledRules.All || doc.DisabledRules.Rules.Has(noUnusedLinkRule) { - return - } - - if doc.Text == "" { - return - } - - for _, linkDef := range doc.Parsed.Links { - if linkDef.Used { - continue - } - actx.Pass.ReportRangef(&doc.CG, "godoc has unused link (%q)", linkDef.Text) - } -} diff --git a/vendor/github.com/godoc-lint/godoc-lint/pkg/check/pkg_doc/pkg_doc.go b/vendor/github.com/godoc-lint/godoc-lint/pkg/check/pkg_doc/pkg_doc.go deleted file mode 100644 index 199b1f54b2..0000000000 --- a/vendor/github.com/godoc-lint/godoc-lint/pkg/check/pkg_doc/pkg_doc.go +++ /dev/null @@ -1,204 +0,0 @@ -// Package pkg_doc provides a checker for package godocs. -package pkg_doc - -import ( - "go/ast" - "strings" - - "github.com/godoc-lint/godoc-lint/pkg/check/shared" - "github.com/godoc-lint/godoc-lint/pkg/model" - "github.com/godoc-lint/godoc-lint/pkg/util" -) - -const ( - pkgDocRule = model.PkgDocRule - singlePkgDocRule = model.SinglePkgDocRule - requirePkgDocRule = model.RequirePkgDocRule -) - -var ruleSet = model.RuleSet{}.Add( - pkgDocRule, - singlePkgDocRule, - requirePkgDocRule, -) - -// PkgDocChecker checks package godocs. -type PkgDocChecker struct{} - -// NewPkgDocChecker returns a new instance of the corresponding checker. -func NewPkgDocChecker() *PkgDocChecker { - return &PkgDocChecker{} -} - -// GetCoveredRules implements the corresponding interface method. -func (r *PkgDocChecker) GetCoveredRules() model.RuleSet { - return ruleSet -} - -// Apply implements the corresponding interface method. -func (r *PkgDocChecker) Apply(actx *model.AnalysisContext) error { - checkPkgDocRule(actx) - checkSinglePkgDocRule(actx) - checkRequirePkgDocRule(actx) - return nil -} - -const commandPkgName = "main" -const commandTestPkgName = "main_test" - -func checkPkgDocRule(actx *model.AnalysisContext) { - if !actx.Config.IsAnyRuleApplicable(model.RuleSet{}.Add(pkgDocRule)) { - return - } - - includeTests := actx.Config.GetRuleOptions().PkgDocIncludeTests - - for f, ir := range util.AnalysisApplicableFiles(actx, includeTests, model.RuleSet{}.Add(pkgDocRule)) { - if ir.PackageDoc == nil { - continue - } - - if ir.PackageDoc.DisabledRules.All || ir.PackageDoc.DisabledRules.Rules.Has(pkgDocRule) { - continue - } - - if f.Name.Name == commandPkgName || f.Name.Name == commandTestPkgName { - // Skip command packages, as they are not required to start with - // "Package main" or "Package main_test". - // - // See for more details: - // - https://github.com/godoc-lint/godoc-lint/issues/10 - // - https://go.dev/doc/comment#cmd - continue - } - - if ir.PackageDoc.Text == "" { - continue - } - - if shared.HasDeprecatedParagraph(ir.PackageDoc.Parsed.Content) { - // If there's a paragraph starting with "Deprecated:", we skip the - // entire godoc. The reason is a deprecated symbol will not appear - // when docs are rendered. - // - // Another reason is that we cannot just skip those paragraphs and - // look for the symbol in the remaining text. To do that, we need - // to iterate over all comment.Block nodes, and check if a block - // is a paragraph AND starts with the deprecation marker. This is - // simple, but the challenge appears when we get to the first block - // that does not have the marker and we want to check if it starts - // with the symbol name. We'd expect that to be a paragraph, but - // that is not always the case. For example, take this decl: - // - // // Deprecated: blah blah - // // - // // Foo is integer - // // - // // Deprecation: blah blah - // type Foo int - // - // The first block is a paragraph which we can easily skip due to - // the "Deprecated:" marker. However, the second block is actually - // parsed as a heading. One can verify this by copy/pasting it in - // a Go file and check the gopls hover. - // - // There might be a workaround for this, but this also means the - // godoc parser behaves in unexpected ways, and until we don't - // really know the extent of its quirks, it's safer to just skip - // further checks on such godocs. - continue - } - - if expectedPrefix, ok := checkPkgDocPrefix(ir.PackageDoc.Text, f.Name.Name); !ok { - actx.Pass.Reportf(ir.PackageDoc.CG.Pos(), "package godoc should start with %q", expectedPrefix+" ") - } - } -} - -func checkPkgDocPrefix(text string, packageName string) (string, bool) { - expectedPrefix := "Package " + packageName - if !strings.HasPrefix(text, expectedPrefix) { - return expectedPrefix, false - } - rest := text[len(expectedPrefix):] - return expectedPrefix, rest == "" || rest[0] == ' ' || rest[0] == '\t' || rest[0] == '\r' || rest[0] == '\n' -} - -func checkSinglePkgDocRule(actx *model.AnalysisContext) { - if !actx.Config.IsAnyRuleApplicable(model.RuleSet{}.Add(singlePkgDocRule)) { - return - } - - includeTests := actx.Config.GetRuleOptions().SinglePkgDocIncludeTests - - documentedPkgs := make(map[string][]*ast.File, 2) - - for f, ir := range util.AnalysisApplicableFiles(actx, includeTests, model.RuleSet{}.Add(singlePkgDocRule)) { - if ir.PackageDoc == nil || ir.PackageDoc.Text == "" { - continue - } - - if ir.PackageDoc.DisabledRules.All || ir.PackageDoc.DisabledRules.Rules.Has(singlePkgDocRule) { - continue - } - - pkg := f.Name.Name - if _, ok := documentedPkgs[pkg]; !ok { - documentedPkgs[pkg] = make([]*ast.File, 0, 2) - } - documentedPkgs[pkg] = append(documentedPkgs[pkg], f) - } - - for pkg, fs := range documentedPkgs { - if len(fs) < 2 { - continue - } - for _, f := range fs { - ir := actx.InspectorResult.Files[f] - actx.Pass.Reportf(ir.PackageDoc.CG.Pos(), "package has more than one godoc (%q)", pkg) - } - } -} - -func checkRequirePkgDocRule(actx *model.AnalysisContext) { - if !actx.Config.IsAnyRuleApplicable(model.RuleSet{}.Add(requirePkgDocRule)) { - return - } - - includeTests := actx.Config.GetRuleOptions().RequirePkgDocIncludeTests - - pkgFiles := make(map[string][]*ast.File, 2) - - for f := range util.AnalysisApplicableFiles(actx, includeTests, model.RuleSet{}.Add(requirePkgDocRule)) { - pkg := f.Name.Name - if _, ok := pkgFiles[pkg]; !ok { - pkgFiles[pkg] = make([]*ast.File, 0, len(actx.Pass.Files)) - } - pkgFiles[pkg] = append(pkgFiles[pkg], f) - } - - for pkg, fs := range pkgFiles { - pkgHasGodoc := false - for _, f := range fs { - ir := actx.InspectorResult.Files[f] - - if ir.PackageDoc == nil || ir.PackageDoc.Text == "" { - continue - } - - if ir.PackageDoc.DisabledRules.All || ir.PackageDoc.DisabledRules.Rules.Has(requirePkgDocRule) { - continue - } - - pkgHasGodoc = true - break - } - - if pkgHasGodoc { - continue - } - - // Add a diagnostic message to the first file of the package. - actx.Pass.Reportf(fs[0].Name.Pos(), "package should have a godoc (%q)", pkg) - } -} diff --git a/vendor/github.com/godoc-lint/godoc-lint/pkg/check/registry.go b/vendor/github.com/godoc-lint/godoc-lint/pkg/check/registry.go deleted file mode 100644 index 8452fa02ca..0000000000 --- a/vendor/github.com/godoc-lint/godoc-lint/pkg/check/registry.go +++ /dev/null @@ -1,64 +0,0 @@ -// Package check provides a registry of checkers. -package check - -import ( - "github.com/godoc-lint/godoc-lint/pkg/check/deprecated" - "github.com/godoc-lint/godoc-lint/pkg/check/max_len" - "github.com/godoc-lint/godoc-lint/pkg/check/no_unused_link" - "github.com/godoc-lint/godoc-lint/pkg/check/pkg_doc" - "github.com/godoc-lint/godoc-lint/pkg/check/require_doc" - "github.com/godoc-lint/godoc-lint/pkg/check/start_with_name" - "github.com/godoc-lint/godoc-lint/pkg/model" -) - -// Registry implements a registry of rules. -type Registry struct { - checkers map[model.Checker]struct{} - coveredRules model.RuleSet -} - -// NewRegistry returns a new rule registry instance. -func NewRegistry(checkers ...model.Checker) *Registry { - registry := Registry{ - checkers: make(map[model.Checker]struct{}, len(checkers)+10), - } - for _, c := range checkers { - registry.Add(c) - } - return ®istry -} - -// NewPopulatedRegistry returns a registry with all supported rules registered. -func NewPopulatedRegistry() *Registry { - return NewRegistry( - max_len.NewMaxLenChecker(), - pkg_doc.NewPkgDocChecker(), - require_doc.NewRequireDocChecker(), - start_with_name.NewStartWithNameChecker(), - no_unused_link.NewNoUnusedLinkChecker(), - deprecated.NewDeprecatedChecker(), - ) -} - -// Add implements the corresponding interface method. -func (r *Registry) Add(checker model.Checker) { - if _, ok := r.checkers[checker]; ok { - return - } - r.coveredRules = r.coveredRules.Merge(checker.GetCoveredRules()) - r.checkers[checker] = struct{}{} -} - -// List implements the corresponding interface method. -func (r *Registry) List() []model.Checker { - all := make([]model.Checker, 0, len(r.checkers)) - for c := range r.checkers { - all = append(all, c) - } - return all -} - -// GetCoveredRules implements the corresponding interface method. -func (r *Registry) GetCoveredRules() model.RuleSet { - return r.coveredRules -} diff --git a/vendor/github.com/godoc-lint/godoc-lint/pkg/check/require_doc/require_doc.go b/vendor/github.com/godoc-lint/godoc-lint/pkg/check/require_doc/require_doc.go deleted file mode 100644 index 9b0ba1affa..0000000000 --- a/vendor/github.com/godoc-lint/godoc-lint/pkg/check/require_doc/require_doc.go +++ /dev/null @@ -1,166 +0,0 @@ -// Package require_doc provides a checker that requires symbols to have godocs. -package require_doc - -import ( - "go/ast" - - "golang.org/x/tools/go/analysis" - - "github.com/godoc-lint/godoc-lint/pkg/model" - "github.com/godoc-lint/godoc-lint/pkg/util" -) - -const requireDocRule = model.RequireDocRule - -var ruleSet = model.RuleSet{}.Add(requireDocRule) - -// RequireDocChecker checks required godocs. -type RequireDocChecker struct{} - -// NewRequireDocChecker returns a new instance of the corresponding checker. -func NewRequireDocChecker() *RequireDocChecker { - return &RequireDocChecker{} -} - -// GetCoveredRules implements the corresponding interface method. -func (r *RequireDocChecker) GetCoveredRules() model.RuleSet { - return ruleSet -} - -// Apply implements the corresponding interface method. -func (r *RequireDocChecker) Apply(actx *model.AnalysisContext) error { - includeTests := actx.Config.GetRuleOptions().RequireDocIncludeTests - requirePublic := !actx.Config.GetRuleOptions().RequireDocIgnoreExported - requirePrivate := !actx.Config.GetRuleOptions().RequireDocIgnoreUnexported - - if !requirePublic && !requirePrivate { - return nil - } - - for _, ir := range util.AnalysisApplicableFiles(actx, includeTests, model.RuleSet{}.Add(requireDocRule)) { - for _, decl := range ir.SymbolDecl { - isExported := ast.IsExported(decl.Name) - if isExported && !requirePublic || !isExported && !requirePrivate { - continue - } - - if decl.Doc != nil && (decl.Doc.DisabledRules.All || decl.Doc.DisabledRules.Rules.Has(requireDocRule)) { - continue - } - - if decl.Kind == model.SymbolDeclKindBad { - continue - } - - if decl.Kind == model.SymbolDeclKindFunc { - if decl.Doc == nil || decl.Doc.Text == "" { - reportRange(actx.Pass, decl.Ident) - } - continue - } - - // Now we only have const/var/type declarations. - - if decl.Doc != nil && decl.Doc.Text != "" { - // cases: - // - // // godoc - // const foo = 0 - // - // // godoc - // const foo, bar = 0, 0 - // - // const ( - // // godoc - // foo = 0 - // ) - // - // const ( - // // godoc - // foo, bar = 0, 0 - // ) - // - // // godoc - // type foo int - // - // type ( - // // godoc - // foo int - // ) - continue - } - - if decl.TrailingDoc != nil && decl.TrailingDoc.Text != "" { - // cases: - // - // const foo = 0 // godoc - // - // const foo, bar = 0, 0 // godoc - // - // const ( - // foo = 0 // godoc - // ) - // - // const ( - // foo, bar = 0, 0 // godoc - // ) - // - // type foo int // godoc - // - // type ( - // foo int // godoc - // ) - continue - } - - if decl.ParentDoc != nil && decl.ParentDoc.Text != "" { - // cases: - // - // // godoc - // const ( - // foo = 0 - // ) - // - // // godoc - // const ( - // foo, bar = 0, 0 - // ) - // - // // godoc - // type ( - // foo int - // ) - continue - } - - // At this point there is no godoc for the symbol. - // - // cases: - // - // const foo = 0 - // - // const foo, bar = 0, 0 - // - // const ( - // foo = 0 - // ) - // - // const ( - // foo, bar = 0, 0 - // ) - // - // type foo int - // - // type ( - // foo int - // ) - - reportRange(actx.Pass, decl.Ident) - } - } - return nil -} - -func reportRange(pass *analysis.Pass, ident *ast.Ident) { - pass.ReportRangef(ident, "symbol should have a godoc (%q)", ident.Name) -} diff --git a/vendor/github.com/godoc-lint/godoc-lint/pkg/check/shared/deprecated.go b/vendor/github.com/godoc-lint/godoc-lint/pkg/check/shared/deprecated.go deleted file mode 100644 index 8ebed0e2b9..0000000000 --- a/vendor/github.com/godoc-lint/godoc-lint/pkg/check/shared/deprecated.go +++ /dev/null @@ -1,29 +0,0 @@ -// Package shared provides shared utilities for checkers. -package shared - -import ( - "go/doc/comment" - "strings" -) - -// HasDeprecatedParagraph reports whether the given comment blocks contain a -// paragraph starting with deprecation marker. -func HasDeprecatedParagraph(blocks []comment.Block) bool { - for _, block := range blocks { - par, ok := block.(*comment.Paragraph) - if !ok || len(par.Text) == 0 { - continue - } - text, ok := (par.Text[0]).(comment.Plain) - if !ok { - continue - } - - // Only an exact match (casing and the trailing whitespace) is considered - // a valid deprecation marker. - if strings.HasPrefix(string(text), "Deprecated: ") { - return true - } - } - return false -} diff --git a/vendor/github.com/godoc-lint/godoc-lint/pkg/check/start_with_name/start_with_name.go b/vendor/github.com/godoc-lint/godoc-lint/pkg/check/start_with_name/start_with_name.go deleted file mode 100644 index af83b99a03..0000000000 --- a/vendor/github.com/godoc-lint/godoc-lint/pkg/check/start_with_name/start_with_name.go +++ /dev/null @@ -1,125 +0,0 @@ -// Package start_with_name provides a checker for godocs starting with the -// symbol name. -package start_with_name - -import ( - "go/ast" - "regexp" - "strings" - - "github.com/godoc-lint/godoc-lint/pkg/check/shared" - "github.com/godoc-lint/godoc-lint/pkg/model" - "github.com/godoc-lint/godoc-lint/pkg/util" -) - -const startWithNameRule = model.StartWithNameRule - -var ruleSet = model.RuleSet{}.Add(startWithNameRule) - -// StartWithNameChecker checks starter of godocs. -type StartWithNameChecker struct{} - -// NewStartWithNameChecker returns a new instance of the corresponding checker. -func NewStartWithNameChecker() *StartWithNameChecker { - return &StartWithNameChecker{} -} - -// GetCoveredRules implements the corresponding interface method. -func (r *StartWithNameChecker) GetCoveredRules() model.RuleSet { - return ruleSet -} - -// Apply implements the corresponding interface method. -func (r *StartWithNameChecker) Apply(actx *model.AnalysisContext) error { - if !actx.Config.IsAnyRuleApplicable(model.RuleSet{}.Add(startWithNameRule)) { - return nil - } - - includeTests := actx.Config.GetRuleOptions().StartWithNameIncludeTests - includePrivate := actx.Config.GetRuleOptions().StartWithNameIncludeUnexported - - for _, ir := range util.AnalysisApplicableFiles(actx, includeTests, model.RuleSet{}.Add(startWithNameRule)) { - for _, decl := range ir.SymbolDecl { - isExported := ast.IsExported(decl.Name) - if !isExported && !includePrivate { - continue - } - - if decl.Kind == model.SymbolDeclKindBad { - continue - } - - if decl.Doc == nil || decl.Doc.Text == "" { - continue - } - - if decl.Doc.DisabledRules.All || decl.Doc.DisabledRules.Rules.Has(startWithNameRule) { - continue - } - - if decl.MultiNameDecl { - continue - } - - if shared.HasDeprecatedParagraph(decl.Doc.Parsed.Content) { - // If there's a paragraph starting with "Deprecated:", we skip the - // entire godoc. The reason is a deprecated symbol will not appear - // when docs are rendered. - // - // Another reason is that we cannot just skip those paragraphs and - // look for the symbol in the remaining text. To do that, we need - // to iterate over all comment.Block nodes, and check if a block - // is a paragraph AND starts with the deprecation marker. This is - // simple, but the challenge appears when we get to the first block - // that does not have the marker and we want to check if it starts - // with the symbol name. We'd expect that to be a paragraph, but - // that is not always the case. For example, take this decl: - // - // // Deprecated: blah blah - // // - // // Foo is integer - // // - // // Deprecation: blah blah - // type Foo int - // - // The first block is a paragraph which we can easily skip due to - // the "Deprecated:" marker. However, the second block is actually - // parsed as a heading. One can verify this by copy/pasting it in - // a Go file and check the gopls hover. - // - // There might be a workaround for this, but this also means the - // godoc parser behaves in unexpected ways, and until we don't - // really know the extent of its quirks, it's safer to just skip - // further checks on such godocs. - continue - } - - if matchSymbolName(decl.Doc.Text, decl.Name) { - continue - } - - actx.Pass.ReportRangef(&decl.Doc.CG, "godoc should start with symbol name (%q)", decl.Name) - } - } - return nil -} - -var startPattern = regexp.MustCompile(`^(?:(A|a|AN|An|an|THE|The|the) )?(?P.+?)\b`) -var startPatternSymbolNameIndex = startPattern.SubexpIndex("symbol_name") - -func matchSymbolName(text string, symbol string) bool { - head := strings.SplitN(text, "\n", 2)[0] - head, _ = strings.CutPrefix(head, "\r") - head = strings.SplitN(head, " ", 2)[0] - head = strings.SplitN(head, "\t", 2)[0] - - if head == symbol { - return true - } - - match := startPattern.FindStringSubmatch(text) - if match == nil { - return false - } - return match[startPatternSymbolNameIndex] == symbol -} diff --git a/vendor/github.com/godoc-lint/godoc-lint/pkg/compose/compose.go b/vendor/github.com/godoc-lint/godoc-lint/pkg/compose/compose.go deleted file mode 100644 index 7ec04e3494..0000000000 --- a/vendor/github.com/godoc-lint/godoc-lint/pkg/compose/compose.go +++ /dev/null @@ -1,53 +0,0 @@ -// Package compose provides composition of the linter components. -package compose - -import ( - "os" - - "github.com/godoc-lint/godoc-lint/pkg/analysis" - "github.com/godoc-lint/godoc-lint/pkg/check" - "github.com/godoc-lint/godoc-lint/pkg/config" - "github.com/godoc-lint/godoc-lint/pkg/inspect" - "github.com/godoc-lint/godoc-lint/pkg/model" -) - -// Composition holds the composed components of the linter. -type Composition struct { - Registry model.Registry - ConfigBuilder model.ConfigBuilder - Inspector model.Inspector - Analyzer model.Analyzer -} - -// CompositionConfig holds the configuration for composing the linter. -type CompositionConfig struct { - BaseDir string - ExitFunc func(int, error) - - // BaseDirPlainConfig holds the plain configuration for the base directory. - // - // This is meant to be used for integrating with umbrella linters (e.g. - // golangci-lint) where the root config comes from a different source/format. - BaseDirPlainConfig *config.PlainConfig -} - -// Compose composes the linter components based on the given configuration. -func Compose(c CompositionConfig) *Composition { - if c.BaseDir == "" { - // It's a best effort to use the current working directory if not set. - c.BaseDir, _ = os.Getwd() - } - - reg := check.NewPopulatedRegistry() - cb := config.NewConfigBuilder(c.BaseDir).WithBaseDirPlainConfig(c.BaseDirPlainConfig) - ocb := config.NewOnceConfigBuilder(cb) - inspector := inspect.NewInspector(ocb, c.ExitFunc) - analyzer := analysis.NewAnalyzer(c.BaseDir, ocb, reg, inspector, c.ExitFunc) - - return &Composition{ - Registry: reg, - ConfigBuilder: cb, - Inspector: inspector, - Analyzer: analyzer, - } -} diff --git a/vendor/github.com/godoc-lint/godoc-lint/pkg/config/builder.go b/vendor/github.com/godoc-lint/godoc-lint/pkg/config/builder.go deleted file mode 100644 index aa25cf186f..0000000000 --- a/vendor/github.com/godoc-lint/godoc-lint/pkg/config/builder.go +++ /dev/null @@ -1,289 +0,0 @@ -package config - -import ( - "errors" - "fmt" - "os" - "path/filepath" - "regexp" - "slices" - - "github.com/godoc-lint/godoc-lint/pkg/model" - "github.com/godoc-lint/godoc-lint/pkg/util" -) - -// ConfigBuilder implements a configuration builder. -type ConfigBuilder struct { - baseDir string - override *model.ConfigOverride - - // baseDirPlainConfig holds the plain config for the base directory. - // - // This is meant to be used for integrating with umbrella linters (e.g. - // golangci-lint) where the root config comes from a different - // source/format. - baseDirPlainConfig *PlainConfig -} - -// NewConfigBuilder crates a new instance of the corresponding struct. -func NewConfigBuilder(baseDir string) *ConfigBuilder { - return &ConfigBuilder{ - baseDir: baseDir, - } -} - -// WithBaseDirPlainConfig sets the plain config for the base directory. This is -// meant to be used for integrating with umbrella linters (e.g. golangci-lint) -// where the root config comes from a different source/format. -func (cb *ConfigBuilder) WithBaseDirPlainConfig(baseDirPlainConfig *PlainConfig) *ConfigBuilder { - cb.baseDirPlainConfig = baseDirPlainConfig - return cb -} - -// GetConfig implements the corresponding interface method. -func (cb *ConfigBuilder) GetConfig(cwd string) (model.Config, error) { - return cb.build(cwd) -} - -func (cb *ConfigBuilder) resolvePlainConfig(cwd string) (*PlainConfig, *PlainConfig, string, string, error) { - def := getDefaultPlainConfig() - - if !util.IsPathUnderBaseDir(cb.baseDir, cwd) { - if pcfg, filePath, err := cb.resolvePlainConfigAtBaseDir(); err != nil { - return nil, nil, "", "", err - } else if pcfg != nil { - return pcfg, def, cb.baseDir, filePath, nil - } - return def, def, cb.baseDir, "", nil - } - - path := cwd - for { - rel, err := filepath.Rel(cb.baseDir, path) - if err != nil { - return nil, nil, "", "", err - } - - if rel == "." { - if pcfg, filePath, err := cb.resolvePlainConfigAtBaseDir(); err != nil { - return nil, nil, "", "", err - } else if pcfg != nil { - return pcfg, def, cb.baseDir, filePath, nil - } - return def, def, cb.baseDir, "", nil - } - - if pcfg, filePath, err := findConventionalConfigFile(path); err != nil { - return nil, nil, "", "", err - } else if pcfg != nil { - return pcfg, def, path, filePath, nil - } - - path = filepath.Dir(path) - } -} - -func (cb *ConfigBuilder) resolvePlainConfigAtBaseDir() (*PlainConfig, string, error) { - // TODO(babakks): refactor this to a sync.OnceValue for performance - - if cb.override != nil && cb.override.ConfigFilePath != nil { - pcfg, err := FromYAMLFile(*cb.override.ConfigFilePath) - if err != nil { - return nil, "", err - } - return pcfg, *cb.override.ConfigFilePath, nil - } - - if pcfg, filePath, err := findConventionalConfigFile(cb.baseDir); err != nil { - return nil, "", err - } else if pcfg != nil { - return pcfg, filePath, nil - } - - if cb.baseDirPlainConfig != nil { - return cb.baseDirPlainConfig, "", nil - } - return nil, "", nil -} - -func findConventionalConfigFile(dir string) (*PlainConfig, string, error) { - for _, dcf := range defaultConfigFiles { - path := filepath.Join(dir, dcf) - if fi, err := os.Stat(path); err != nil || fi.IsDir() { - continue - } - pcfg, err := FromYAMLFile(path) - if err != nil { - return nil, "", err - } - return pcfg, path, nil - } - return nil, "", nil -} - -// build creates the configuration struct. -// -// It checks a sequence of sources: -// 1. Custom config file path -// 2. Default configuration files (e.g., `.godoc-lint.yaml`) -// -// If none was available, the default configuration will be returned. -// -// The method also does the following: -// - Applies override flags (e.g., enable, or disable). -// - Validates the final configuration. -func (cb *ConfigBuilder) build(cwd string) (*config, error) { - pcfg, def, configCWD, configFilePath, err := cb.resolvePlainConfig(cwd) - if err != nil { - return nil, err - } - - if err := pcfg.Validate(); err != nil { - return nil, fmt.Errorf("invalid config at %q: %w", configFilePath, err) - } - - toValidRuleSet := func(s []string) (*model.RuleSet, []string) { - if s == nil { - return nil, nil - } - invalids := make([]string, 0, len(s)) - rules := make([]model.Rule, 0, len(s)) - for _, v := range s { - if !model.AllRules.Has(model.Rule(v)) { - invalids = append(invalids, v) - continue - } - rules = append(rules, model.Rule(v)) - } - set := model.RuleSet{}.Add(rules...) - return &set, invalids - } - - toValidRegexpSlice := func(s []string) ([]*regexp.Regexp, []string) { - if s == nil { - return nil, nil - } - var invalids []string - var regexps []*regexp.Regexp - for _, v := range s { - re, err := regexp.Compile(v) - if err != nil { - invalids = append(invalids, v) - continue - } - regexps = append(regexps, re) - } - return regexps, invalids - } - - var errs []error - - result := &config{ - cwd: configCWD, - configFilePath: configFilePath, - } - - var enabledRules *model.RuleSet - if cb.override != nil && cb.override.Enable != nil { - enabledRules = cb.override.Enable - } else { - raw := pcfg.Enable - if raw == nil { - raw = def.Enable - } - rs, invalids := toValidRuleSet(raw) - if len(invalids) > 0 { - errs = append(errs, fmt.Errorf("invalid rule(s) name to enable: %q", invalids)) - } else { - enabledRules = rs - } - } - - var disabledRules *model.RuleSet - if cb.override != nil && cb.override.Disable != nil { - disabledRules = cb.override.Disable - } else { - raw := pcfg.Disable - if raw == nil { - raw = def.Disable - } - rs, invalids := toValidRuleSet(raw) - if len(invalids) > 0 { - errs = append(errs, fmt.Errorf("invalid rule(s) name to disable: %q", invalids)) - } else { - disabledRules = rs - } - } - - if cb.override != nil && cb.override.Include != nil { - result.includeAsRegexp = cb.override.Include - } else { - raw := pcfg.Include - if raw == nil { - raw = def.Include - } - rs, invalids := toValidRegexpSlice(raw) - if len(invalids) > 0 { - errs = append(errs, fmt.Errorf("invalid path pattern(s) to include: %q", invalids)) - } else { - result.includeAsRegexp = rs - } - } - - if cb.override != nil && cb.override.Exclude != nil { - result.excludeAsRegexp = cb.override.Exclude - } else { - raw := pcfg.Exclude - if raw == nil { - raw = def.Exclude - } - rs, invalids := toValidRegexpSlice(raw) - if len(invalids) > 0 { - errs = append(errs, fmt.Errorf("invalid path pattern(s) to exclude: %q", invalids)) - } else { - result.excludeAsRegexp = rs - } - } - - if cb.override != nil && cb.override.Default != nil { - result.rulesToApply = model.DefaultSetToRules[*cb.override.Default] - } else { - raw := pcfg.Default - if raw == nil { - raw = def.Default // never nil - } - - if !slices.Contains(model.DefaultSetValues, model.DefaultSet(*raw)) { - errs = append(errs, fmt.Errorf("invalid default set %q; must be one of %q", *raw, model.DefaultSetValues)) - } else { - result.rulesToApply = model.DefaultSetToRules[model.DefaultSet(*raw)] - } - } - - if errs != nil { - return nil, errors.Join(errs...) - } - - if enabledRules != nil { - result.rulesToApply = result.rulesToApply.Merge(*enabledRules) - } - if disabledRules != nil { - result.rulesToApply = result.rulesToApply.Remove(disabledRules.List()...) - } - - // To avoid being too strict, we don't complain if a rule is enabled and disabled at the same time. - - resolvedOptions := &model.RuleOptions{} - transferOptions(resolvedOptions, def.Options) // def.Options is never nil - if pcfg.Options != nil { - transferOptions(resolvedOptions, pcfg.Options) - } - result.options = resolvedOptions - - return result, nil -} - -// SetOverride implements the corresponding interface method. -func (cb *ConfigBuilder) SetOverride(override *model.ConfigOverride) { - cb.override = override -} diff --git a/vendor/github.com/godoc-lint/godoc-lint/pkg/config/config.go b/vendor/github.com/godoc-lint/godoc-lint/pkg/config/config.go deleted file mode 100644 index 9a2cdfc603..0000000000 --- a/vendor/github.com/godoc-lint/godoc-lint/pkg/config/config.go +++ /dev/null @@ -1,73 +0,0 @@ -package config - -import ( - "path/filepath" - "regexp" - - "github.com/godoc-lint/godoc-lint/pkg/model" -) - -// config represents the godoc-lint analyzer configuration. -type config struct { - // cwd holds the directory that the configuration is applied to. This is the - // way to find out relative paths to include/exclude based on the config - // file. - cwd string - - // configFilePath holds the path to the configuration file. If there is no - // configuration file, which is the case when the default is used, this will - // be an empty string. - configFilePath string - - includeAsRegexp []*regexp.Regexp - excludeAsRegexp []*regexp.Regexp - rulesToApply model.RuleSet - options *model.RuleOptions -} - -// GetConfigFilePath implements the corresponding interface method. -func (c *config) GetConfigFilePath() string { - return c.configFilePath -} - -// GetCWD implements the corresponding interface method. -func (c *config) GetCWD() string { - return c.cwd -} - -// IsAnyRuleApplicable implements the corresponding interface method. -func (c *config) IsAnyRuleApplicable(rs model.RuleSet) bool { - return c.rulesToApply.HasCommonsWith(rs) -} - -// IsPathApplicable implements the corresponding interface method. -func (c *config) IsPathApplicable(path string) bool { - p, err := filepath.Rel(c.cwd, path) - if err != nil { - p = path - } - - // To ensure a consistent behavior on different platform (with the same - // configuration), we convert the path to a Unix-style path. - asUnixPath := filepath.ToSlash(p) - - for _, re := range c.excludeAsRegexp { - if re.MatchString(asUnixPath) { - return false - } - } - if c.includeAsRegexp == nil { - return true - } - for _, re := range c.includeAsRegexp { - if re.MatchString(asUnixPath) { - return true - } - } - return false -} - -// GetRuleOptions implements the corresponding interface method. -func (c *config) GetRuleOptions() *model.RuleOptions { - return c.options -} diff --git a/vendor/github.com/godoc-lint/godoc-lint/pkg/config/default.go b/vendor/github.com/godoc-lint/godoc-lint/pkg/config/default.go deleted file mode 100644 index 79ba8b670c..0000000000 --- a/vendor/github.com/godoc-lint/godoc-lint/pkg/config/default.go +++ /dev/null @@ -1,28 +0,0 @@ -package config - -import ( - _ "embed" - "sync" -) - -// defaultConfigFiles is the list of default configuration file names. -var defaultConfigFiles = []string{ - ".godoc-lint.yaml", - ".godoc-lint.yml", - ".godoc-lint.json", - ".godoclint.yaml", - ".godoclint.yml", - ".godoclint.json", -} - -// defaultConfigYAML is the default configuration (as YAML). -// -//go:embed default.yaml -var defaultConfigYAML []byte - -// getDefaultPlainConfig returns the parsed default configuration. -var getDefaultPlainConfig = sync.OnceValue(func() *PlainConfig { - // Error is nil due to tests. - pcfg, _ := FromYAML(defaultConfigYAML) - return pcfg -}) diff --git a/vendor/github.com/godoc-lint/godoc-lint/pkg/config/default.yaml b/vendor/github.com/godoc-lint/godoc-lint/pkg/config/default.yaml deleted file mode 100644 index eb244e771c..0000000000 --- a/vendor/github.com/godoc-lint/godoc-lint/pkg/config/default.yaml +++ /dev/null @@ -1,15 +0,0 @@ -# Default configuration -version: "1.0" -default: basic -options: - max-len/length: 77 - max-len/include-tests: false - pkg-doc/include-tests: false - single-pkg-doc/include-tests: false - require-pkg-doc/include-tests: false - require-doc/include-tests: false - require-doc/ignore-exported: false - require-doc/ignore-unexported: true - start-with-name/include-tests: false - start-with-name/include-unexported: false - no-unused-link/include-tests: false \ No newline at end of file diff --git a/vendor/github.com/godoc-lint/godoc-lint/pkg/config/doc.go b/vendor/github.com/godoc-lint/godoc-lint/pkg/config/doc.go deleted file mode 100644 index 3a015d9899..0000000000 --- a/vendor/github.com/godoc-lint/godoc-lint/pkg/config/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package config provides configuration building and management. -package config diff --git a/vendor/github.com/godoc-lint/godoc-lint/pkg/config/once.go b/vendor/github.com/godoc-lint/godoc-lint/pkg/config/once.go deleted file mode 100644 index 2d865d5570..0000000000 --- a/vendor/github.com/godoc-lint/godoc-lint/pkg/config/once.go +++ /dev/null @@ -1,59 +0,0 @@ -package config - -import ( - "sync" - - "github.com/godoc-lint/godoc-lint/pkg/model" -) - -// OnceConfigBuilder wraps a config builder and make it a one-time builder, so -// that further attempts to build will return the same result. -// -// This type is concurrent-safe. -type OnceConfigBuilder struct { - builder model.ConfigBuilder - - mu sync.Mutex - m map[string]built -} - -type built struct { - value model.Config - err error -} - -// NewOnceConfigBuilder crates a new instance of the corresponding struct. -func NewOnceConfigBuilder(builder model.ConfigBuilder) *OnceConfigBuilder { - return &OnceConfigBuilder{ - builder: builder, - } -} - -// GetConfig implements the corresponding interface method. -func (ocb *OnceConfigBuilder) GetConfig(cwd string) (model.Config, error) { - ocb.mu.Lock() - defer ocb.mu.Unlock() - - if b, ok := ocb.m[cwd]; ok { - return b.value, b.err - } - - b := built{} - b.value, b.err = ocb.builder.GetConfig(cwd) - if ocb.m == nil { - ocb.m = make(map[string]built, 10) - } - ocb.m[cwd] = b - return b.value, b.err -} - -// SetOverride implements the corresponding interface method. -func (ocb *OnceConfigBuilder) SetOverride(override *model.ConfigOverride) { - ocb.mu.Lock() - defer ocb.mu.Unlock() - - if len(ocb.m) > 0 { - return - } - ocb.builder.SetOverride(override) -} diff --git a/vendor/github.com/godoc-lint/godoc-lint/pkg/config/parser.go b/vendor/github.com/godoc-lint/godoc-lint/pkg/config/parser.go deleted file mode 100644 index 71a04f0459..0000000000 --- a/vendor/github.com/godoc-lint/godoc-lint/pkg/config/parser.go +++ /dev/null @@ -1,42 +0,0 @@ -package config - -import ( - "fmt" - "os" - "strings" - - "gopkg.in/yaml.v3" -) - -// FromYAML parses configuration from given YAML content. -func FromYAML(in []byte) (*PlainConfig, error) { - raw := PlainConfig{} - if err := yaml.Unmarshal(in, &raw); err != nil { - return nil, fmt.Errorf("cannot parse config from YAML file: %w", err) - } - - if raw.Version != nil && !strings.HasPrefix(*raw.Version, "1.") { - return nil, fmt.Errorf("unsupported config version: %s", *raw.Version) - } - - return &raw, nil -} - -// FromYAMLFile parses configuration from given file path. -func FromYAMLFile(path string) (*PlainConfig, error) { - in, err := os.ReadFile(path) - if err != nil { - return nil, fmt.Errorf("cannot read file (%s): %w", path, err) - } - - raw := PlainConfig{} - if err := yaml.Unmarshal(in, &raw); err != nil { - return nil, fmt.Errorf("cannot parse config from YAML file: %w", err) - } - - if raw.Version != nil && !strings.HasPrefix(*raw.Version, "1.") { - return nil, fmt.Errorf("unsupported config version: %s", *raw.Version) - } - - return &raw, nil -} diff --git a/vendor/github.com/godoc-lint/godoc-lint/pkg/config/plain.go b/vendor/github.com/godoc-lint/godoc-lint/pkg/config/plain.go deleted file mode 100644 index 4cb75d8d04..0000000000 --- a/vendor/github.com/godoc-lint/godoc-lint/pkg/config/plain.go +++ /dev/null @@ -1,128 +0,0 @@ -package config - -import ( - "errors" - "fmt" - "reflect" - "regexp" - "slices" - - "github.com/godoc-lint/godoc-lint/pkg/model" -) - -// PlainConfig represents the plain configuration type as users would provide -// via a config file (e.g., a YAML file). -type PlainConfig struct { - Version *string `yaml:"version" mapstructure:"version"` - Exclude []string `yaml:"exclude" mapstructure:"exclude"` - Include []string `yaml:"include" mapstructure:"include"` - Default *string `yaml:"default" mapstructure:"default"` - Enable []string `yaml:"enable" mapstructure:"enable"` - Disable []string `yaml:"disable" mapstructure:"disable"` - Options *PlainRuleOptions `yaml:"options" mapstructure:"options"` -} - -// PlainRuleOptions represents the plain rule options as users would provide via -// a config file (e.g., a YAML file). -type PlainRuleOptions struct { - MaxLenLength *uint `option:"max-len/length" yaml:"max-len/length" mapstructure:"max-len/length"` - MaxLenIncludeTests *bool `option:"max-len/include-tests" yaml:"max-len/include-tests" mapstructure:"max-len/include-tests"` - PkgDocIncludeTests *bool `option:"pkg-doc/include-tests" yaml:"pkg-doc/include-tests" mapstructure:"pkg-doc/include-tests"` - SinglePkgDocIncludeTests *bool `option:"single-pkg-doc/include-tests" yaml:"single-pkg-doc/include-tests" mapstructure:"single-pkg-doc/include-tests"` - RequirePkgDocIncludeTests *bool `option:"require-pkg-doc/include-tests" yaml:"require-pkg-doc/include-tests" mapstructure:"require-pkg-doc/include-tests"` - RequireDocIncludeTests *bool `option:"require-doc/include-tests" yaml:"require-doc/include-tests" mapstructure:"require-doc/include-tests"` - RequireDocIgnoreExported *bool `option:"require-doc/ignore-exported" yaml:"require-doc/ignore-exported" mapstructure:"require-doc/ignore-exported"` - RequireDocIgnoreUnexported *bool `option:"require-doc/ignore-unexported" yaml:"require-doc/ignore-unexported" mapstructure:"require-doc/ignore-unexported"` - StartWithNameIncludeTests *bool `option:"start-with-name/include-tests" yaml:"start-with-name/include-tests" mapstructure:"start-with-name/include-tests"` - StartWithNameIncludeUnexported *bool `option:"start-with-name/include-unexported" yaml:"start-with-name/include-unexported" mapstructure:"start-with-name/include-unexported"` - NoUnusedLinkIncludeTests *bool `option:"no-unused-link/include-tests" yaml:"no-unused-link/include-tests" mapstructure:"no-unused-link/include-tests"` -} - -func transferOptions(target *model.RuleOptions, source *PlainRuleOptions) { - resV := reflect.ValueOf(target).Elem() - resVT := resV.Type() - - resOptionMap := make(map[string]string, resVT.NumField()) - for i := 0; i < resVT.NumField(); i++ { - ft := resVT.Field(i) - key, ok := ft.Tag.Lookup("option") - if !ok { - continue - } - resOptionMap[key] = ft.Name - } - - v := reflect.ValueOf(source).Elem() - vt := v.Type() - for i := 0; i < vt.NumField(); i++ { - ft := vt.Field(i) - key, ok := ft.Tag.Lookup("option") - if !ok { - continue - } - if ft.Type.Kind() != reflect.Pointer { - continue - } - f := v.Field(i) - if f.IsNil() { - continue - } - resFieldName, ok := resOptionMap[key] - if !ok { - continue - } - resV.FieldByName(resFieldName).Set(f.Elem()) - } -} - -// Validate validates the plain configuration. -func (pcfg *PlainConfig) Validate() error { - var errs []error - - if pcfg.Default != nil && !slices.Contains(model.DefaultSetValues, model.DefaultSet(*pcfg.Default)) { - errs = append(errs, fmt.Errorf("invalid default set %q; must be one of %q", *pcfg.Default, model.DefaultSetValues)) - } - - if invalids := getInvalidRules(pcfg.Enable); len(invalids) > 0 { - errs = append(errs, fmt.Errorf("invalid rule name(s) to enable: %q", invalids)) - } - - if invalids := getInvalidRules(pcfg.Disable); len(invalids) > 0 { - errs = append(errs, fmt.Errorf("invalid rule name(s) to disable: %q", invalids)) - } - - // To avoid being too strict, we don't complain if a rule is enabled and disabled at the same time. - - if invalids := getInvalidRegexps(pcfg.Include); len(invalids) > 0 { - errs = append(errs, fmt.Errorf("invalid inclusion pattern(s): %q", invalids)) - } - - if invalids := getInvalidRegexps(pcfg.Exclude); len(invalids) > 0 { - errs = append(errs, fmt.Errorf("invalid exclusion pattern(s): %q", invalids)) - } - - if len(errs) > 0 { - return errors.Join(errs...) - } - return nil -} - -func getInvalidRules(names []string) []string { - invalids := make([]string, 0, len(names)) - for _, element := range names { - if !model.AllRules.Has(model.Rule(element)) { - invalids = append(invalids, element) - } - } - return invalids -} - -func getInvalidRegexps(values []string) []string { - invalids := make([]string, 0, len(values)) - for _, element := range values { - if _, err := regexp.Compile(element); err != nil { - invalids = append(invalids, element) - } - } - return invalids -} diff --git a/vendor/github.com/godoc-lint/godoc-lint/pkg/inspect/inspector.go b/vendor/github.com/godoc-lint/godoc-lint/pkg/inspect/inspector.go deleted file mode 100644 index 7ea535ee84..0000000000 --- a/vendor/github.com/godoc-lint/godoc-lint/pkg/inspect/inspector.go +++ /dev/null @@ -1,313 +0,0 @@ -// Package inspect provides the pre-run inspection analyzer. -package inspect - -import ( - "errors" - "fmt" - "go/ast" - gdc "go/doc/comment" - "go/token" - "path/filepath" - "reflect" - "regexp" - "strings" - - "golang.org/x/tools/go/analysis" - - "github.com/godoc-lint/godoc-lint/pkg/model" - "github.com/godoc-lint/godoc-lint/pkg/util" -) - -const ( - metaName = "godoclint_inspect" - metaDoc = "Pre-run inspector for godoclint" - metaURL = "https://github.com/godoc-lint/godoc-lint" -) - -// Inspector implements the godoc-lint pre-run inspector. -type Inspector struct { - cb model.ConfigBuilder - exitFunc func(int, error) - - analyzer *analysis.Analyzer - parser gdc.Parser -} - -// NewInspector returns a new instance of the inspector. -func NewInspector(cb model.ConfigBuilder, exitFunc func(int, error)) *Inspector { - result := &Inspector{ - cb: cb, - exitFunc: exitFunc, - analyzer: &analysis.Analyzer{ - Name: metaName, - Doc: metaDoc, - URL: metaURL, - ResultType: reflect.TypeOf(new(model.InspectorResult)), - }, - } - result.analyzer.Run = result.run - return result -} - -// GetAnalyzer returns the underlying analyzer. -func (i *Inspector) GetAnalyzer() *analysis.Analyzer { - return i.analyzer -} - -var topLevelOrphanCommentGroupPattern = regexp.MustCompile(`(?m)(?:^//.*\r?\n)+(?:\r?\n|\z)`) -var disableDirectivePattern = regexp.MustCompile(`(?m)//godoclint:disable(?: *([^\r\n]+))?\r?$`) - -func (i *Inspector) run(pass *analysis.Pass) (any, error) { - if len(pass.Files) == 0 { - return &model.InspectorResult{}, nil - } - - ft := util.GetPassFileToken(pass.Files[0], pass) - if ft == nil { - err := errors.New("cannot prepare config") - if i.exitFunc != nil { - i.exitFunc(2, err) - } - return nil, err - } - - pkgDir := filepath.Dir(ft.Name()) - cfg, err := i.cb.GetConfig(pkgDir) - if err != nil { - if i.exitFunc != nil { - i.exitFunc(2, err) - } - return nil, err - } - - inspect := func(f *ast.File) (*model.FileInspection, error) { - ft := util.GetPassFileToken(f, pass) - if ft == nil { - return nil, nil - } - - raw, err := pass.ReadFile(ft.Name()) - if err != nil { - return nil, fmt.Errorf("cannot read file %q: %v", ft.Name(), err) - } - - // Extract package godoc, if any. - packageDoc := i.extractCommentGroup(f.Doc) - - // Extract top-level //godoclint:disable directives. - disabledRules := model.InspectorResultDisableRules{} - for _, match := range topLevelOrphanCommentGroupPattern.FindAll(raw, -1) { - d := extractDisableDirectivesInComment(string(match)) - disabledRules.All = disabledRules.All || d.All - disabledRules.Rules = disabledRules.Rules.Merge(d.Rules) - } - - // Extract top-level symbol declarations. - decls := make([]model.SymbolDecl, 0, len(f.Decls)) - for _, d := range f.Decls { - switch dt := d.(type) { - case *ast.FuncDecl: - decls = append(decls, model.SymbolDecl{ - Decl: d, - Kind: model.SymbolDeclKindFunc, - Name: dt.Name.Name, - Ident: dt.Name, - Doc: i.extractCommentGroup(dt.Doc), - }) - case *ast.BadDecl: - decls = append(decls, model.SymbolDecl{ - Decl: d, - Kind: model.SymbolDeclKindBad, - }) - case *ast.GenDecl: - switch dt.Tok { - case token.CONST, token.VAR: - kind := model.SymbolDeclKindConst - if dt.Tok == token.VAR { - kind = model.SymbolDeclKindVar - } - if dt.Lparen == token.NoPos { - // cases: - // const ... (single line) - // var ... (single line) - - spec := dt.Specs[0].(*ast.ValueSpec) - if len(spec.Names) == 1 { - // cases: - // const foo = 0 - // var foo = 0 - decls = append(decls, model.SymbolDecl{ - Decl: d, - Kind: kind, - Name: spec.Names[0].Name, - Ident: spec.Names[0], - Doc: i.extractCommentGroup(dt.Doc), - TrailingDoc: i.extractCommentGroup(spec.Comment), - }) - } else { - // cases: - // const foo, bar = 0, 0 - // var foo, bar = 0, 0 - doc := i.extractCommentGroup(dt.Doc) - trailingDoc := i.extractCommentGroup(spec.Comment) - for ix, n := range spec.Names { - decls = append(decls, model.SymbolDecl{ - Decl: d, - Kind: kind, - Name: n.Name, - Ident: n, - Doc: doc, - TrailingDoc: trailingDoc, - MultiNameDecl: true, - MultiNameIndex: ix, - }) - } - } - } else { - // cases: - // const ( - // foo = 0 - // ) - // var ( - // foo = 0 - // ) - // const ( - // foo, bar = 0, 0 - // ) - // var ( - // foo, bar = 0, 0 - // ) - - parentDoc := i.extractCommentGroup(dt.Doc) - for spix, s := range dt.Specs { - spec := s.(*ast.ValueSpec) - doc := i.extractCommentGroup(spec.Doc) - trailingDoc := i.extractCommentGroup(spec.Comment) - for ix, n := range spec.Names { - decls = append(decls, model.SymbolDecl{ - Decl: d, - Kind: kind, - Name: n.Name, - Ident: n, - Doc: doc, - TrailingDoc: trailingDoc, - ParentDoc: parentDoc, - MultiNameDecl: len(spec.Names) > 1, - MultiNameIndex: ix, - MultiSpecDecl: true, - MultiSpecIndex: spix, - }) - } - } - } - case token.TYPE: - if dt.Lparen == token.NoPos { - // case: - // type foo int - - spec := dt.Specs[0].(*ast.TypeSpec) - decls = append(decls, model.SymbolDecl{ - Decl: d, - Kind: model.SymbolDeclKindType, - IsTypeAlias: spec.Assign != token.NoPos, - Name: spec.Name.Name, - Ident: spec.Name, - Doc: i.extractCommentGroup(dt.Doc), - TrailingDoc: i.extractCommentGroup(spec.Comment), - }) - } else { - // case: - // type ( - // foo int - // ) - - parentDoc := i.extractCommentGroup(dt.Doc) - for spix, s := range dt.Specs { - spec := s.(*ast.TypeSpec) - decls = append(decls, model.SymbolDecl{ - Decl: d, - Kind: model.SymbolDeclKindType, - IsTypeAlias: spec.Assign != token.NoPos, - Name: spec.Name.Name, - Ident: spec.Name, - Doc: i.extractCommentGroup(spec.Doc), - TrailingDoc: i.extractCommentGroup(spec.Comment), - ParentDoc: parentDoc, - MultiSpecDecl: true, - MultiSpecIndex: spix, - }) - } - } - default: - continue - } - } - } - - return &model.FileInspection{ - DisabledRules: disabledRules, - PackageDoc: packageDoc, - SymbolDecl: decls, - }, nil - } - - result := &model.InspectorResult{ - Files: make(map[*ast.File]*model.FileInspection, len(pass.Files)), - } - - for _, f := range pass.Files { - ft := util.GetPassFileToken(f, pass) - if ft == nil { - continue - } - if !cfg.IsPathApplicable(ft.Name()) { - continue - } - - if fi, err := inspect(f); err != nil { - return nil, fmt.Errorf("inspector failed: %w", err) - } else { - result.Files[f] = fi - } - } - return result, nil -} - -func (i *Inspector) extractCommentGroup(cg *ast.CommentGroup) *model.CommentGroup { - if cg == nil { - return nil - } - - lines := make([]string, 0, len(cg.List)) - for _, l := range cg.List { - lines = append(lines, l.Text) - } - rawText := strings.Join(lines, "\n") - - text := cg.Text() - return &model.CommentGroup{ - CG: *cg, - Parsed: *i.parser.Parse(text), - Text: text, - DisabledRules: extractDisableDirectivesInComment(rawText), - } -} - -func extractDisableDirectivesInComment(s string) model.InspectorResultDisableRules { - result := model.InspectorResultDisableRules{} - for _, directive := range disableDirectivePattern.FindAllStringSubmatch(s, -1) { - args := string(directive[1]) - if args == "" { - result.All = true - continue - } - - names := strings.Split(strings.TrimSpace(args), " ") - for _, name := range names { - if model.AllRules.Has(model.Rule(name)) { - result.Rules = result.Rules.Add(model.Rule(name)) - } - } - } - return result -} diff --git a/vendor/github.com/godoc-lint/godoc-lint/pkg/model/analyzer.go b/vendor/github.com/godoc-lint/godoc-lint/pkg/model/analyzer.go deleted file mode 100644 index ded44c4e71..0000000000 --- a/vendor/github.com/godoc-lint/godoc-lint/pkg/model/analyzer.go +++ /dev/null @@ -1,11 +0,0 @@ -package model - -import ( - "golang.org/x/tools/go/analysis" -) - -// Analyzer defines an analyzer. -type Analyzer interface { - // GetAnalyzer returns the underlying analyzer. - GetAnalyzer() *analysis.Analyzer -} diff --git a/vendor/github.com/godoc-lint/godoc-lint/pkg/model/checker.go b/vendor/github.com/godoc-lint/godoc-lint/pkg/model/checker.go deleted file mode 100644 index dca42e279c..0000000000 --- a/vendor/github.com/godoc-lint/godoc-lint/pkg/model/checker.go +++ /dev/null @@ -1,24 +0,0 @@ -package model - -import "golang.org/x/tools/go/analysis" - -// AnalysisContext provides contextual information about the running analysis. -type AnalysisContext struct { - // Config provides analyzer configuration. - Config Config - - // InspectorResult is the analysis result of the pre-run inspector. - InspectorResult *InspectorResult - - // Pass is the analysis Pass instance. - Pass *analysis.Pass -} - -// Checker defines a rule checker. -type Checker interface { - // GetCoveredRules returns the set of rules applied by the checker. - GetCoveredRules() RuleSet - - // Apply checks for the rule(s). - Apply(actx *AnalysisContext) error -} diff --git a/vendor/github.com/godoc-lint/godoc-lint/pkg/model/config.go b/vendor/github.com/godoc-lint/godoc-lint/pkg/model/config.go deleted file mode 100644 index 78fa62a27e..0000000000 --- a/vendor/github.com/godoc-lint/godoc-lint/pkg/model/config.go +++ /dev/null @@ -1,123 +0,0 @@ -package model - -import ( - "maps" - "regexp" - "slices" -) - -// ConfigBuilder defines a configuration builder. -type ConfigBuilder interface { - // SetOverride sets the configuration override. - SetOverride(override *ConfigOverride) - - // GetConfig builds and returns the configuration object for the given path. - GetConfig(cwd string) (Config, error) -} - -// DefaultSet defines the default set of rules to enable. -type DefaultSet string - -const ( - // DefaultSetAll enables all rules. - DefaultSetAll DefaultSet = "all" - // DefaultSetNone disables all rules. - DefaultSetNone DefaultSet = "none" - // DefaultSetBasic enables a basic set of rules. - DefaultSetBasic DefaultSet = "basic" - - // DefaultDefaultSet is the default set of rules to enable. - DefaultDefaultSet = DefaultSetBasic -) - -// DefaultSetToRules maps default sets to the corresponding rule sets. -var DefaultSetToRules = map[DefaultSet]RuleSet{ - DefaultSetAll: AllRules, - DefaultSetNone: {}, - DefaultSetBasic: func() RuleSet { - return RuleSet{}.Add( - PkgDocRule, - SinglePkgDocRule, - StartWithNameRule, - DeprecatedRule, - ) - }(), -} - -// DefaultSetValues holds the valid values for DefaultSet. -var DefaultSetValues = func() []DefaultSet { - values := slices.Collect(maps.Keys(DefaultSetToRules)) - slices.Sort(values) - return values -}() - -// ConfigOverride represents a configuration override. -// -// Non-nil values (including empty slices) indicate that the corresponding field -// is overridden. -type ConfigOverride struct { - // ConfigFilePath is the path to config file. - ConfigFilePath *string - - // Include is the overridden list of regexp patterns matching the files that - // the linter should include. - Include []*regexp.Regexp - - // Exclude is the overridden list of regexp patterns matching the files that - // the linter should exclude. - Exclude []*regexp.Regexp - - // Default is the default set of rules to enable. - Default *DefaultSet - - // Enable is the overridden list of rules to enable. - Enable *RuleSet - - // Disable is the overridden list of rules to disable. - Disable *RuleSet -} - -// NewConfigOverride returns a new config override instance. -func NewConfigOverride() *ConfigOverride { - return &ConfigOverride{} -} - -// Config defines an analyzer configuration. -type Config interface { - // GetCWD returns the directory that the configuration is applied to. This - // is the base to compute relative paths to include/exclude files. - GetCWD() string - - // GetConfigFilePath returns the path to the configuration file. If there is - // no configuration file, which is the case when the default is used, this - // will be an empty string. - GetConfigFilePath() string - - // IsAnyRuleEnabled determines if any of the given rule names is among - // enabled rules, or not among disabled rules. - IsAnyRuleApplicable(RuleSet) bool - - // IsPathApplicable determines if the given path matches the included path - // patterns, or does not match the excluded path patterns. - IsPathApplicable(path string) bool - - // Returns the rule-specific options. - // - // It never returns a nil pointer. - GetRuleOptions() *RuleOptions -} - -// RuleOptions represents individual linter rule configurations. -type RuleOptions struct { - MaxLenLength uint `option:"max-len/length"` - MaxLenIncludeTests bool `option:"max-len/include-tests"` - PkgDocIncludeTests bool `option:"pkg-doc/include-tests"` - SinglePkgDocIncludeTests bool `option:"single-pkg-doc/include-tests"` - RequirePkgDocIncludeTests bool `option:"require-pkg-doc/include-tests"` - RequireDocIncludeTests bool `option:"require-doc/include-tests"` - RequireDocIgnoreExported bool `option:"require-doc/ignore-exported"` - RequireDocIgnoreUnexported bool `option:"require-doc/ignore-unexported"` - StartWithNameIncludeTests bool `option:"start-with-name/include-tests"` - StartWithNameIncludeUnexported bool `option:"start-with-name/include-unexported"` - NoUnusedLinkIncludeTests bool `option:"no-unused-link/include-tests"` -} diff --git a/vendor/github.com/godoc-lint/godoc-lint/pkg/model/doc.go b/vendor/github.com/godoc-lint/godoc-lint/pkg/model/doc.go deleted file mode 100644 index b4afa8d46c..0000000000 --- a/vendor/github.com/godoc-lint/godoc-lint/pkg/model/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package model provides data models for the linter. -package model diff --git a/vendor/github.com/godoc-lint/godoc-lint/pkg/model/inspector.go b/vendor/github.com/godoc-lint/godoc-lint/pkg/model/inspector.go deleted file mode 100644 index 3166e17faf..0000000000 --- a/vendor/github.com/godoc-lint/godoc-lint/pkg/model/inspector.go +++ /dev/null @@ -1,189 +0,0 @@ -package model - -import ( - "go/ast" - "go/doc/comment" - - "golang.org/x/tools/go/analysis" -) - -// Inspector defines a pre-run inspector. -type Inspector interface { - // GetAnalyzer returns the underlying analyzer. - GetAnalyzer() *analysis.Analyzer -} - -// InspectorResult represents the result of the inspector analysis. -type InspectorResult struct { - // Files provides extracted information per AST file. - Files map[*ast.File]*FileInspection -} - -// FileInspection represents the inspection result for a single file. -type FileInspection struct { - // DisabledRules contains information about rules disabled at top level. - DisabledRules InspectorResultDisableRules - - // PackageDoc represents the package godoc, if any. - PackageDoc *CommentGroup - - // SymbolDecl represents symbols declared in the package file. - SymbolDecl []SymbolDecl -} - -// InspectorResultDisableRules contains the list of disabled rules. -type InspectorResultDisableRules struct { - // All indicates whether all rules are disabled. - All bool - - // Rules is the set of rules disabled. - Rules RuleSet -} - -// SymbolDeclKind is the enum type for the symbol declarations. -type SymbolDeclKind string - -const ( - // SymbolDeclKindBad represents an unknown declaration kind. - SymbolDeclKindBad SymbolDeclKind = "bad" - // SymbolDeclKindFunc represents a function declaration kind. - SymbolDeclKindFunc SymbolDeclKind = "func" - // SymbolDeclKindConst represents a const declaration kind. - SymbolDeclKindConst SymbolDeclKind = "const" - // SymbolDeclKindType represents a type declaration kind. - SymbolDeclKindType SymbolDeclKind = "type" - // SymbolDeclKindVar represents a var declaration kind. - SymbolDeclKindVar SymbolDeclKind = "var" -) - -// SymbolDecl represents a top level declaration. -type SymbolDecl struct { - // Decl is the underlying declaration node. - Decl ast.Decl - - // Kind is the declaration kind (e.g., func or type). - Kind SymbolDeclKind - - // IsTypeAlias indicates that the type symbol is an alias. For example: - // - // type Foo = int - // - // This is always false for non-type declaration (e.g., const or var). - IsTypeAlias bool - - // Name is the name of the declared symbol. - Name string - - // Ident is the symbol identifier node. - Ident *ast.Ident - - // MultiNameDecl determines whether the symbol is declared as part of a - // multi-name declaration spec; For example: - // - // const foo, bar = 0, 0 - // - // This field is only valid for const, var, or type declarations. - MultiNameDecl bool - - // MultiNameIndex is the index of the declared symbol within the spec. For - // example, in the below declaration, the index of "foo" and "bar" are 0 and - // 1, respectively: - // - // const foo, bar = 0, 0 - // - // In single-name specs, this will be 0. - MultiNameIndex int - - // MultiSpecDecl determines whether the symbol is declared as part of a - // multi-spec declaration. A multi spec declaration is const/var/type - // declaration with a pair of grouping brackets, even if there is only one - // spec between the brackets. For example, these are multi-spec - // declarations: - // - // const ( - // foo = 0 - // ) - // - // const ( - // foo, bar = 0, 0 - // ) - // - // const ( - // foo = 0 - // bar = 0 - // ) - // - // const ( - // foo, bar = 0, 0 - // baz = 0 - // ) - // - MultiSpecDecl bool - - // SpecIndex is the index of the spec where the symbol is declared. For - // example, in the below declaration, the index of "foo" and "bar" are 0 and - // 1, respectively: - // - // const ( - // foo = 0 - // bar = 0 - // ) - // - // In single-spec declarations, this will be 0. - MultiSpecIndex int - - // Doc is the comment group associated to the symbol. For example: - // - // // godoc - // const foo = 0 - // - // const ( - // // godoc - // foo = 0 - // ) - // - // Note that, as in the first example above, for single-spec declarations - // (i.e., single line declarations), the godoc above the const/var/type - // keyword is considered as the declaration doc, and the parent doc will be - // nil. - Doc *CommentGroup - - // TrailingDoc is the comment group that is following the symbol - // declaration. For example, this is a trailing comment group: - // - // const ( - // foo = 0 // trailing comment group. - // ) - // - TrailingDoc *CommentGroup - - // Doc is the comment group associated to the parent declaration. For - // instance: - // - // // parent godoc - // const ( - // // godoc - // Foo = 0 - // ) - // - // Note that for single-spec declarations (i.e., single line declarations), - // the godoc above the const/var/type keyword is considered as the - // declaration doc, and the parent doc will be nil. - ParentDoc *CommentGroup -} - -// CommentGroup represents an ast.CommentGroup and its parsed godoc instance. -type CommentGroup struct { - // CG represents the AST comment group. - CG ast.CommentGroup - - // Parsed represents the comment group parsed into a godoc. - Parsed comment.Doc - - // Test is the comment group text. - Text string - - // DisabledRules contains information about rules disabled in the comment - // group. - DisabledRules InspectorResultDisableRules -} diff --git a/vendor/github.com/godoc-lint/godoc-lint/pkg/model/registry.go b/vendor/github.com/godoc-lint/godoc-lint/pkg/model/registry.go deleted file mode 100644 index 64512291da..0000000000 --- a/vendor/github.com/godoc-lint/godoc-lint/pkg/model/registry.go +++ /dev/null @@ -1,14 +0,0 @@ -package model - -// Registry defines a registry of checkers. -type Registry interface { - // Add registers a new checker. - Add(Checker) - - // List returns a slice of the registered checkers. - List() []Checker - - // GetCoveredRules returns the set of rules covered by the registered - // checkers. - GetCoveredRules() RuleSet -} diff --git a/vendor/github.com/godoc-lint/godoc-lint/pkg/model/rule.go b/vendor/github.com/godoc-lint/godoc-lint/pkg/model/rule.go deleted file mode 100644 index c53fcf61a0..0000000000 --- a/vendor/github.com/godoc-lint/godoc-lint/pkg/model/rule.go +++ /dev/null @@ -1,37 +0,0 @@ -package model - -// Rule represents a rule. -type Rule string - -const ( - // PkgDocRule represents the "pkg-doc" rule. - PkgDocRule Rule = "pkg-doc" - // SinglePkgDocRule represents the "single-pkg-doc" rule. - SinglePkgDocRule Rule = "single-pkg-doc" - // RequirePkgDocRule represents the "require-pkg-doc" rule. - RequirePkgDocRule Rule = "require-pkg-doc" - // StartWithNameRule represents the "start-with-name" rule. - StartWithNameRule Rule = "start-with-name" - // RequireDocRule represents the "require-doc" rule. - RequireDocRule Rule = "require-doc" - // DeprecatedRule represents the "deprecated" rule. - DeprecatedRule Rule = "deprecated" - // MaxLenRule represents the "max-len" rule. - MaxLenRule Rule = "max-len" - // NoUnusedLinkRule represents the "no-unused-link" rule. - NoUnusedLinkRule Rule = "no-unused-link" -) - -// AllRules is the set of all supported rules. -var AllRules = func() RuleSet { - return RuleSet{}.Add( - PkgDocRule, - SinglePkgDocRule, - RequirePkgDocRule, - StartWithNameRule, - RequireDocRule, - DeprecatedRule, - MaxLenRule, - NoUnusedLinkRule, - ) -}() diff --git a/vendor/github.com/godoc-lint/godoc-lint/pkg/model/ruleset.go b/vendor/github.com/godoc-lint/godoc-lint/pkg/model/ruleset.go deleted file mode 100644 index 0cf195447c..0000000000 --- a/vendor/github.com/godoc-lint/godoc-lint/pkg/model/ruleset.go +++ /dev/null @@ -1,97 +0,0 @@ -package model - -import "slices" - -// RuleSet represents an immutable set of rule names. -// -// A zero rule set represents an empty set. -type RuleSet struct { - m map[Rule]struct{} -} - -// Merge combines the rules in the current and the given rule sets into a new -// set. -func (rs RuleSet) Merge(another RuleSet) RuleSet { - result := RuleSet{ - m: make(map[Rule]struct{}, len(rs.m)+len(another.m)), - } - for r := range rs.m { - result.m[r] = struct{}{} - } - for r := range another.m { - result.m[r] = struct{}{} - } - return result -} - -// Add returns a new rule set containing the rules in the current set and the -// rules provided as arguments. -func (rs RuleSet) Add(rules ...Rule) RuleSet { - result := RuleSet{ - m: make(map[Rule]struct{}, len(rs.m)+len(rules)), - } - for r := range rs.m { - result.m[r] = struct{}{} - } - for _, r := range rules { - result.m[r] = struct{}{} - } - return result -} - -// Remove returns a new rule set containing the rules in the current set -// excluding those provided as arguments. -func (rs RuleSet) Remove(rules ...Rule) RuleSet { - result := RuleSet{ - m: make(map[Rule]struct{}, len(rs.m)), - } - for r := range rs.m { - result.m[r] = struct{}{} - } - for _, r := range rules { - delete(result.m, r) - } - return result -} - -// Has determines whether the given rule is in the set. -func (rs RuleSet) Has(rule Rule) bool { - _, ok := rs.m[rule] - return ok -} - -// HasCommonsWith indicates at least one rule is in common with the given rule -// set. -// -// If the given set is empty/zero, the method will return false. -func (rs RuleSet) HasCommonsWith(another RuleSet) bool { - for r := range another.m { - if _, ok := rs.m[r]; ok { - return true - } - } - return false -} - -// IsSupersetOf indicates that all rules in the given set are in the current -// set. -// -// If the given set is empty/zero, the method will return true. -func (rs RuleSet) IsSupersetOf(another RuleSet) bool { - for r := range another.m { - if _, ok := rs.m[r]; !ok { - return false - } - } - return true -} - -// List returns a slice of the rules in the set. -func (rs RuleSet) List() []Rule { - rules := make([]Rule, 0, len(rs.m)) - for r := range rs.m { - rules = append(rules, r) - } - slices.Sort(rules) - return rules -} diff --git a/vendor/github.com/godoc-lint/godoc-lint/pkg/util/ast.go b/vendor/github.com/godoc-lint/godoc-lint/pkg/util/ast.go deleted file mode 100644 index 1441001d01..0000000000 --- a/vendor/github.com/godoc-lint/godoc-lint/pkg/util/ast.go +++ /dev/null @@ -1,66 +0,0 @@ -package util - -import ( - "go/ast" - "go/token" - "iter" - "strings" - - "golang.org/x/tools/go/analysis" - - "github.com/godoc-lint/godoc-lint/pkg/model" -) - -// GetPassFileToken is a helper function to return the file token associated -// with the given AST file. -func GetPassFileToken(f *ast.File, pass *analysis.Pass) *token.File { - if f.Pos() == token.NoPos { - return nil - } - ft := pass.Fset.File(f.Pos()) - if ft == nil { - return nil - } - return ft -} - -// AnalysisApplicableFiles returns an iterator looping over files that are ready -// to be analyzed. -// -// The yield-ed arguments are never nil. -func AnalysisApplicableFiles(actx *model.AnalysisContext, includeTests bool, ruleSet model.RuleSet) iter.Seq2[*ast.File, *model.FileInspection] { - return func(yield func(*ast.File, *model.FileInspection) bool) { - if actx.InspectorResult == nil { - return - } - - for _, f := range actx.Pass.Files { - ir := actx.InspectorResult.Files[f] - - if ir == nil { - continue - } - - ft := GetPassFileToken(f, actx.Pass) - if ft == nil { - continue - } - - if !actx.Config.IsPathApplicable(ft.Name()) { - continue - } - - if !includeTests && strings.HasSuffix(ft.Name(), "_test.go") { - continue - } - - if ir.DisabledRules.All || ir.DisabledRules.Rules.IsSupersetOf(ruleSet) { - continue - } - - if !yield(f, ir) { - return - } - } - } -} diff --git a/vendor/github.com/godoc-lint/godoc-lint/pkg/util/doc.go b/vendor/github.com/godoc-lint/godoc-lint/pkg/util/doc.go deleted file mode 100644 index 1c40b74680..0000000000 --- a/vendor/github.com/godoc-lint/godoc-lint/pkg/util/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package util provides utility functions for the linter. -package util diff --git a/vendor/github.com/godoc-lint/godoc-lint/pkg/util/path.go b/vendor/github.com/godoc-lint/godoc-lint/pkg/util/path.go deleted file mode 100644 index b7dd451e2f..0000000000 --- a/vendor/github.com/godoc-lint/godoc-lint/pkg/util/path.go +++ /dev/null @@ -1,16 +0,0 @@ -package util - -import ( - "path/filepath" - "strings" -) - -// IsPathUnderBaseDir determines whether the given path is a sub-directory of -// the given base, lexicographically. -func IsPathUnderBaseDir(baseDir, path string) bool { - rel, err := filepath.Rel(baseDir, path) - if err != nil { - return false - } - return rel == "." || rel != ".." && !strings.HasPrefix(filepath.ToSlash(rel), "../") -} diff --git a/vendor/github.com/gofrs/flock/.gitignore b/vendor/github.com/gofrs/flock/.gitignore deleted file mode 100644 index daf913b1b3..0000000000 --- a/vendor/github.com/gofrs/flock/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -*.test -*.prof diff --git a/vendor/github.com/gofrs/flock/.golangci.yml b/vendor/github.com/gofrs/flock/.golangci.yml deleted file mode 100644 index bc837b266a..0000000000 --- a/vendor/github.com/gofrs/flock/.golangci.yml +++ /dev/null @@ -1,116 +0,0 @@ -version: "2" - -formatters: - enable: - - gofumpt - - goimports - settings: - gofumpt: - extra-rules: true - -linters: - enable: - - asasalint - - bidichk - - dogsled - - dupword - - durationcheck - - err113 - - errname - - errorlint - - fatcontext - - forbidigo - - gocheckcompilerdirectives - - gochecknoinits - - gocritic - - godot - - godox - - goheader - - gomoddirectives - - goprintffuncname - - gosec - - inamedparam - - interfacebloat - - ireturn - - mirror - - misspell - - nolintlint - - revive - - staticcheck - - testifylint - - thelper - - unconvert - - unparam - - usestdlibvars - - whitespace - - wsl_v5 - settings: - gocritic: - disabled-checks: - - paramTypeCombine # already handle by gofumpt.extra-rules - - whyNoLint # already handle by nonolint - - unnamedResult - - hugeParam - - sloppyReassign - - rangeValCopy - - octalLiteral - - ptrToRefParam - - appendAssign - - ruleguard - - httpNoBody - - exposedSyncMutex - enabled-tags: - - diagnostic - - style - - performance - godox: - keywords: - - FIXME - goheader: - template: |- - Copyright 2015 Tim Heckman. All rights reserved. - Copyright 2018-{{ YEAR }} The Gofrs. All rights reserved. - Use of this source code is governed by the BSD 3-Clause - license that can be found in the LICENSE file. - gosec: - excludes: - - G115 - misspell: - locale: US - revive: - rules: - - name: struct-tag - - name: blank-imports - - name: context-as-argument - - name: context-keys-type - - name: dot-imports - - name: error-return - - name: error-strings - - name: error-naming - - name: exported - - name: if-return - - name: increment-decrement - - name: var-naming - - name: var-declaration - - name: package-comments - - name: range - - name: receiver-naming - - name: time-naming - - name: unexported-return - - name: indent-error-flow - - name: errorf - - name: empty-block - - name: superfluous-else - - name: unused-parameter - - name: unreachable-code - - name: redefines-builtin-id - exclusions: - presets: - - comments - - common-false-positives - - std-error-handling - -issues: - max-issues-per-linter: 0 - max-same-issues: 0 - diff --git a/vendor/github.com/gofrs/flock/LICENSE b/vendor/github.com/gofrs/flock/LICENSE deleted file mode 100644 index c785e5e4b2..0000000000 --- a/vendor/github.com/gofrs/flock/LICENSE +++ /dev/null @@ -1,28 +0,0 @@ -Copyright (c) 2018-2025, The Gofrs -Copyright (c) 2015-2020, Tim Heckman -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of gofrs nor the names of its contributors may be used - to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/gofrs/flock/Makefile b/vendor/github.com/gofrs/flock/Makefile deleted file mode 100644 index 65c139d68c..0000000000 --- a/vendor/github.com/gofrs/flock/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -.PHONY: lint test test_race build_cross_os - -default: lint test build_cross_os - -test: - go test -v -cover ./... - -test_race: - CGO_ENABLED=1 go test -v -race ./... - -lint: - golangci-lint run - -build_cross_os: - ./build.sh diff --git a/vendor/github.com/gofrs/flock/README.md b/vendor/github.com/gofrs/flock/README.md deleted file mode 100644 index f7ca0dd9c2..0000000000 --- a/vendor/github.com/gofrs/flock/README.md +++ /dev/null @@ -1,45 +0,0 @@ -# flock - -[![Go Reference](https://pkg.go.dev/badge/github.com/gofrs/flock.svg)](https://pkg.go.dev/github.com/gofrs/flock) -[![License](https://img.shields.io/badge/license-BSD_3--Clause-brightgreen.svg?style=flat)](https://github.com/gofrs/flock/blob/main/LICENSE) -[![Go Report Card](https://goreportcard.com/badge/github.com/gofrs/flock)](https://goreportcard.com/report/github.com/gofrs/flock) - -`flock` implements a thread-safe file lock. - -It also includes a non-blocking `TryLock()` function to allow locking without blocking execution. - -## Installation - -```bash -go get -u github.com/gofrs/flock -``` - -## Usage - -```go -import "github.com/gofrs/flock" - -fileLock := flock.New("/var/lock/go-lock.lock") - -locked, err := fileLock.TryLock() - -if err != nil { - // handle locking error -} - -if locked { - // do work - fileLock.Unlock() -} -``` - -For more detailed usage information take a look at the package API docs on -[GoDoc](https://pkg.go.dev/github.com/gofrs/flock). - -## License - -`flock` is released under the BSD 3-Clause License. See the [`LICENSE`](./LICENSE) file for more details. - -## Project History - -This project was originally `github.com/theckman/go-flock`, it was transferred to Gofrs by the original author [Tim Heckman ](https://github.com/theckman). diff --git a/vendor/github.com/gofrs/flock/SECURITY.md b/vendor/github.com/gofrs/flock/SECURITY.md deleted file mode 100644 index 01419bd592..0000000000 --- a/vendor/github.com/gofrs/flock/SECURITY.md +++ /dev/null @@ -1,21 +0,0 @@ -# Security Policy - -## Supported Versions - -We support the latest version of this library. -We do not guarantee support of previous versions. - -If a defect is reported, it will generally be fixed on the latest version (provided it exists) irrespective of whether it was introduced in a prior version. - -## Reporting a Vulnerability - -To report a potential security vulnerability, please create a [security advisory](https://github.com/gofrs/flock/security/advisories/new). - -For us to respond to your report most effectively, please include any of the following: - -- Steps to reproduce or a proof-of-concept -- Any relevant information, including the versions used - -## Security Scorecard - -This project submits security [results](https://scorecard.dev/viewer/?uri=github.com/gofrs/flock) to the [OpenSSF Scorecard](https://securityscorecards.dev/). diff --git a/vendor/github.com/gofrs/flock/build.sh b/vendor/github.com/gofrs/flock/build.sh deleted file mode 100644 index 60f7809f06..0000000000 --- a/vendor/github.com/gofrs/flock/build.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -e - -# Not supported by flock: -# - plan9/* -# - js/wasm -# - wasp1/wasm - -for row in $(go tool dist list -json | jq -r '.[] | @base64'); do - _jq() { - echo ${row} | base64 --decode | jq -r ${1} - } - - GOOS=$(_jq '.GOOS') - GOARCH=$(_jq '.GOARCH') - - echo "$GOOS/$GOARCH" - GOOS=$GOOS GOARCH=$GOARCH go build -done diff --git a/vendor/github.com/gofrs/flock/flock.go b/vendor/github.com/gofrs/flock/flock.go deleted file mode 100644 index 4cb0746a71..0000000000 --- a/vendor/github.com/gofrs/flock/flock.go +++ /dev/null @@ -1,222 +0,0 @@ -// Copyright 2015 Tim Heckman. All rights reserved. -// Copyright 2018-2025 The Gofrs. All rights reserved. -// Use of this source code is governed by the BSD 3-Clause -// license that can be found in the LICENSE file. - -// Package flock implements a thread-safe interface for file locking. -// It also includes a non-blocking TryLock() function to allow locking -// without blocking execution. -// -// Package flock is released under the BSD 3-Clause License. See the LICENSE file -// for more details. -// -// While using this library, remember that the locking behaviors are not -// guaranteed to be the same on each platform. For example, some UNIX-like -// operating systems will transparently convert a shared lock to an exclusive -// lock. If you Unlock() the flock from a location where you believe that you -// have the shared lock, you may accidentally drop the exclusive lock. -package flock - -import ( - "context" - "io/fs" - "os" - "runtime" - "sync" - "time" -) - -type Option func(f *Flock) - -// SetFlag sets the flag used to create/open the file. -func SetFlag(flag int) Option { - return func(f *Flock) { - f.flag = flag - } -} - -// SetPermissions sets the OS permissions to set on the file. -func SetPermissions(perm fs.FileMode) Option { - return func(f *Flock) { - f.perm = perm - } -} - -// Flock is the struct type to handle file locking. All fields are unexported, -// with access to some of the fields provided by getter methods (Path() and Locked()). -type Flock struct { - path string - m sync.RWMutex - fh *os.File - l bool - r bool - - // flag is the flag used to create/open the file. - flag int - // perm is the OS permissions to set on the file. - perm fs.FileMode -} - -// New returns a new instance of *Flock. The only parameter -// it takes is the path to the desired lockfile. -func New(path string, opts ...Option) *Flock { - // create it if it doesn't exist, and open the file read-only. - flags := os.O_CREATE - - switch runtime.GOOS { - case "aix", "solaris", "illumos": - // AIX cannot preform write-lock (i.e. exclusive) on a read-only file. - flags |= os.O_RDWR - default: - flags |= os.O_RDONLY - } - - f := &Flock{ - path: path, - flag: flags, - perm: fs.FileMode(0o600), - } - - for _, opt := range opts { - opt(f) - } - - return f -} - -// NewFlock returns a new instance of *Flock. The only parameter -// it takes is the path to the desired lockfile. -// -// Deprecated: Use New instead. -func NewFlock(path string) *Flock { - return New(path) -} - -// Close is equivalent to calling Unlock. -// -// This will release the lock and close the underlying file descriptor. -// It will not remove the file from disk, that's up to your application. -func (f *Flock) Close() error { - return f.Unlock() -} - -// Path returns the path as provided in NewFlock(). -func (f *Flock) Path() string { - return f.path -} - -// Locked returns the lock state (locked: true, unlocked: false). -// -// Warning: by the time you use the returned value, the state may have changed. -func (f *Flock) Locked() bool { - f.m.RLock() - defer f.m.RUnlock() - - return f.l -} - -// RLocked returns the read lock state (locked: true, unlocked: false). -// -// Warning: by the time you use the returned value, the state may have changed. -func (f *Flock) RLocked() bool { - f.m.RLock() - defer f.m.RUnlock() - - return f.r -} - -// Stat returns the FileInfo structure describing the lock file. -// If the lock file does not exist or cannot be accessed, an error is returned. -// -// This can be used to check the modification time of the lock file, -// which is useful for detecting stale locks. -func (f *Flock) Stat() (fs.FileInfo, error) { - f.m.RLock() - defer f.m.RUnlock() - - if f.fh != nil { - return f.fh.Stat() - } - - return os.Stat(f.path) -} - -func (f *Flock) String() string { - return f.path -} - -// TryLockContext repeatedly tries to take an exclusive lock until one of the conditions is met: -// - TryLock succeeds -// - TryLock fails with error -// - Context Done channel is closed. -func (f *Flock) TryLockContext(ctx context.Context, retryDelay time.Duration) (bool, error) { - return tryCtx(ctx, f.TryLock, retryDelay) -} - -// TryRLockContext repeatedly tries to take a shared lock until one of the conditions is met: -// - TryRLock succeeds -// - TryRLock fails with error -// - Context Done channel is closed. -func (f *Flock) TryRLockContext(ctx context.Context, retryDelay time.Duration) (bool, error) { - return tryCtx(ctx, f.TryRLock, retryDelay) -} - -func tryCtx(ctx context.Context, fn func() (bool, error), retryDelay time.Duration) (bool, error) { - if ctx.Err() != nil { - return false, ctx.Err() - } - - for { - if ok, err := fn(); ok || err != nil { - return ok, err - } - - select { - case <-ctx.Done(): - return false, ctx.Err() - case <-time.After(retryDelay): - } - } -} - -func (f *Flock) setFh(flag int) error { - // open a new os.File instance - fh, err := os.OpenFile(f.path, flag, f.perm) - if err != nil { - return err - } - - // set the file handle on the struct - f.fh = fh - - return nil -} - -// resetFh resets file handle: -// - tries to close the file (ignore errors) -// - sets fh to nil. -func (f *Flock) resetFh() { - if f.fh == nil { - return - } - - _ = f.fh.Close() - - f.fh = nil -} - -// ensure the file handle is closed if no lock is held. -func (f *Flock) ensureFhState() { - if f.l || f.r || f.fh == nil { - return - } - - f.resetFh() -} - -func (f *Flock) reset() { - f.l = false - f.r = false - - f.resetFh() -} diff --git a/vendor/github.com/gofrs/flock/flock_others.go b/vendor/github.com/gofrs/flock/flock_others.go deleted file mode 100644 index 92d0f7e95a..0000000000 --- a/vendor/github.com/gofrs/flock/flock_others.go +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2015 Tim Heckman. All rights reserved. -// Copyright 2018-2025 The Gofrs. All rights reserved. -// Use of this source code is governed by the BSD 3-Clause -// license that can be found in the LICENSE file. - -//go:build (!unix && !windows) || plan9 - -package flock - -import ( - "errors" - "io/fs" -) - -func (f *Flock) Lock() error { - return &fs.PathError{ - Op: "Lock", - Path: f.Path(), - Err: errors.ErrUnsupported, - } -} - -func (f *Flock) RLock() error { - return &fs.PathError{ - Op: "RLock", - Path: f.Path(), - Err: errors.ErrUnsupported, - } -} - -func (f *Flock) Unlock() error { - return &fs.PathError{ - Op: "Unlock", - Path: f.Path(), - Err: errors.ErrUnsupported, - } -} - -func (f *Flock) TryLock() (bool, error) { - return false, f.Lock() -} - -func (f *Flock) TryRLock() (bool, error) { - return false, f.RLock() -} diff --git a/vendor/github.com/gofrs/flock/flock_unix.go b/vendor/github.com/gofrs/flock/flock_unix.go deleted file mode 100644 index 77de7a8837..0000000000 --- a/vendor/github.com/gofrs/flock/flock_unix.go +++ /dev/null @@ -1,211 +0,0 @@ -// Copyright 2015 Tim Heckman. All rights reserved. -// Copyright 2018-2025 The Gofrs. All rights reserved. -// Use of this source code is governed by the BSD 3-Clause -// license that can be found in the LICENSE file. - -//go:build darwin || dragonfly || freebsd || illumos || linux || netbsd || openbsd - -package flock - -import ( - "errors" - "os" - - "golang.org/x/sys/unix" -) - -// Lock is a blocking call to try and take an exclusive file lock. -// It will wait until it is able to obtain the exclusive file lock. -// It's recommended that TryLock() be used over this function. -// This function may block the ability to query the current Locked() or RLocked() status due to a RW-mutex lock. -// -// If we are already exclusive-locked, -// this function short-circuits and returns immediately assuming it can take the mutex lock. -// -// If the *Flock has a shared lock (RLock), -// this may transparently replace the shared lock with an exclusive lock on some UNIX-like operating systems. -// Be careful when using exclusive locks in conjunction with shared locks (RLock()), -// because calling Unlock() may accidentally release the exclusive lock that was once a shared lock. -func (f *Flock) Lock() error { - return f.lock(&f.l, unix.LOCK_EX) -} - -// RLock is a blocking call to try and take a shared file lock. -// It will wait until it is able to obtain the shared file lock. -// It's recommended that TryRLock() be used over this function. -// This function may block the ability to query the current Locked() or RLocked() status due to a RW-mutex lock. -// -// If we are already shared-locked, -// this function short-circuits and returns immediately assuming it can take the mutex lock. -func (f *Flock) RLock() error { - return f.lock(&f.r, unix.LOCK_SH) -} - -func (f *Flock) lock(locked *bool, flag int) error { - f.m.Lock() - defer f.m.Unlock() - - if *locked { - return nil - } - - if f.fh == nil { - if err := f.setFh(f.flag); err != nil { - return err - } - - defer f.ensureFhState() - } - - err := unix.Flock(int(f.fh.Fd()), flag) - if err != nil { - shouldRetry, reopenErr := f.reopenFDOnError(err) - if reopenErr != nil { - return reopenErr - } - - if !shouldRetry { - return err - } - - err = unix.Flock(int(f.fh.Fd()), flag) - if err != nil { - return err - } - } - - *locked = true - - return nil -} - -// Unlock is a function to unlock the file. -// This file takes a RW-mutex lock, -// so while it is running the Locked() and RLocked() functions will be blocked. -// -// This function short-circuits if we are unlocked already. -// If not, it calls unix.LOCK_UN on the file and closes the file descriptor. -// It does not remove the file from disk. It's up to your application to do. -// -// Please note, -// if your shared lock became an exclusive lock, -// this may unintentionally drop the exclusive lock if called by the consumer that believes they have a shared lock. -// Please see Lock() for more details. -func (f *Flock) Unlock() error { - f.m.Lock() - defer f.m.Unlock() - - // If we aren't locked or if the lockfile instance is nil - // just return a nil error because we are unlocked. - if (!f.l && !f.r) || f.fh == nil { - return nil - } - - // Mark the file as unlocked. - err := unix.Flock(int(f.fh.Fd()), unix.LOCK_UN) - if err != nil { - return err - } - - f.reset() - - return nil -} - -// TryLock is the preferred function for taking an exclusive file lock. -// This function takes an RW-mutex lock before it tries to lock the file, -// so there is the possibility that this function may block for a short time -// if another goroutine is trying to take any action. -// -// The actual file lock is non-blocking. -// If we are unable to get the exclusive file lock, -// the function will return false instead of waiting for the lock. -// If we get the lock, we also set the *Flock instance as being exclusive-locked. -func (f *Flock) TryLock() (bool, error) { - return f.try(&f.l, unix.LOCK_EX) -} - -// TryRLock is the preferred function for taking a shared file lock. -// This function takes an RW-mutex lock before it tries to lock the file, -// so there is the possibility that this function may block for a short time -// if another goroutine is trying to take any action. -// -// The actual file lock is non-blocking. -// If we are unable to get the shared file lock, -// the function will return false instead of waiting for the lock. -// If we get the lock, we also set the *Flock instance as being share-locked. -func (f *Flock) TryRLock() (bool, error) { - return f.try(&f.r, unix.LOCK_SH) -} - -func (f *Flock) try(locked *bool, flag int) (bool, error) { - f.m.Lock() - defer f.m.Unlock() - - if *locked { - return true, nil - } - - if f.fh == nil { - if err := f.setFh(f.flag); err != nil { - return false, err - } - - defer f.ensureFhState() - } - - var retried bool - -retry: - err := unix.Flock(int(f.fh.Fd()), flag|unix.LOCK_NB) - - switch { - case errors.Is(err, unix.EWOULDBLOCK): - return false, nil - case err == nil: - *locked = true - return true, nil - } - - if !retried { - shouldRetry, reopenErr := f.reopenFDOnError(err) - if reopenErr != nil { - return false, reopenErr - } else if shouldRetry { - retried = true - goto retry - } - } - - return false, err -} - -// reopenFDOnError determines whether we should reopen the file handle in readwrite mode and try again. -// This comes from `util-linux/sys-utils/flock.c`: -// > Since Linux 3.4 (commit 55725513) -// > Probably NFSv4 where flock() is emulated by fcntl(). -// > https://github.com/util-linux/util-linux/blob/198e920aa24743ef6ace4e07cf6237de527f9261/sys-utils/flock.c#L374-L390 -func (f *Flock) reopenFDOnError(err error) (bool, error) { - if !errors.Is(err, unix.EIO) && !errors.Is(err, unix.EBADF) { - return false, nil - } - - st, err := f.fh.Stat() - if err != nil { - return false, nil - } - - if st.Mode()&f.perm != f.perm { - return false, nil - } - - f.resetFh() - - // reopen in read-write mode and set the file handle - err = f.setFh(f.flag | os.O_RDWR) - if err != nil { - return false, err - } - - return true, nil -} diff --git a/vendor/github.com/gofrs/flock/flock_unix_fcntl.go b/vendor/github.com/gofrs/flock/flock_unix_fcntl.go deleted file mode 100644 index 05c2f88c65..0000000000 --- a/vendor/github.com/gofrs/flock/flock_unix_fcntl.go +++ /dev/null @@ -1,393 +0,0 @@ -// Copyright 2015 Tim Heckman. All rights reserved. -// Copyright 2018-2025 The Gofrs. All rights reserved. -// Use of this source code is governed by the BSD 3-Clause -// license that can be found in the LICENSE file. - -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This code implements the filelock API using POSIX 'fcntl' locks, -// which attach to an (inode, process) pair rather than a file descriptor. -// To avoid unlocking files prematurely when the same file is opened through different descriptors, -// we allow only one read-lock at a time. -// -// This code is adapted from the Go package (go.22): -// https://github.com/golang/go/blob/release-branch.go1.22/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go - -//go:build aix || (solaris && !illumos) - -package flock - -import ( - "errors" - "io" - "io/fs" - "math/rand" - "sync" - "syscall" - "time" - - "golang.org/x/sys/unix" -) - -// https://github.com/golang/go/blob/09aeb6e33ab426eff4676a3baf694d5a3019e9fc/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go#L28 -type lockType int16 - -// String returns the name of the function corresponding to lt -// (Lock, RLock, or Unlock). -// https://github.com/golang/go/blob/09aeb6e33ab426eff4676a3baf694d5a3019e9fc/src/cmd/go/internal/lockedfile/internal/filelock/filelock.go#L67 -func (lt lockType) String() string { - switch lt { - case readLock: - return "RLock" - case writeLock: - return "Lock" - default: - return "Unlock" - } -} - -// https://github.com/golang/go/blob/09aeb6e33ab426eff4676a3baf694d5a3019e9fc/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go#L30-L33 -const ( - readLock lockType = unix.F_RDLCK - writeLock lockType = unix.F_WRLCK -) - -// https://github.com/golang/go/blob/09aeb6e33ab426eff4676a3baf694d5a3019e9fc/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go#L35 -type inode = uint64 - -// https://github.com/golang/go/blob/09aeb6e33ab426eff4676a3baf694d5a3019e9fc/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go#L37-L40 -type inodeLock struct { - owner *Flock - queue []<-chan *Flock -} - -type cmdType int - -const ( - tryLock cmdType = unix.F_SETLK - waitLock cmdType = unix.F_SETLKW -) - -var ( - mu sync.Mutex - inodes = map[*Flock]inode{} - locks = map[inode]inodeLock{} -) - -// Lock is a blocking call to try and take an exclusive file lock. -// It will wait until it is able to obtain the exclusive file lock. -// It's recommended that TryLock() be used over this function. -// This function may block the ability to query the current Locked() or RLocked() status due to a RW-mutex lock. -// -// If we are already exclusive-locked, this function short-circuits and -// returns immediately assuming it can take the mutex lock. -// -// If the *Flock has a shared lock (RLock), -// this may transparently replace the shared lock with an exclusive lock on some UNIX-like operating systems. -// Be careful when using exclusive locks in conjunction with shared locks (RLock()), -// because calling Unlock() may accidentally release the exclusive lock that was once a shared lock. -func (f *Flock) Lock() error { - return f.lock(&f.l, writeLock) -} - -// RLock is a blocking call to try and take a shared file lock. -// It will wait until it is able to obtain the shared file lock. -// It's recommended that TryRLock() be used over this function. -// This function may block the ability to query the current Locked() or RLocked() status due to a RW-mutex lock. -// -// If we are already shared-locked, this function short-circuits and -// returns immediately assuming it can take the mutex lock. -func (f *Flock) RLock() error { - return f.lock(&f.r, readLock) -} - -func (f *Flock) lock(locked *bool, flag lockType) error { - f.m.Lock() - defer f.m.Unlock() - - if *locked { - return nil - } - - if f.fh == nil { - if err := f.setFh(f.flag); err != nil { - return err - } - - defer f.ensureFhState() - } - - _, err := f.doLock(waitLock, flag, true) - if err != nil { - return err - } - - *locked = true - - return nil -} - -// https://github.com/golang/go/blob/09aeb6e33ab426eff4676a3baf694d5a3019e9fc/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go#L48 -func (f *Flock) doLock(cmd cmdType, lt lockType, blocking bool) (bool, error) { - // POSIX locks apply per inode and process, - // and the lock for an inode is released when *any* descriptor for that inode is closed. - // So we need to synchronize access to each inode internally, - // and must serialize lock and unlock calls that refer to the same inode through different descriptors. - fi, err := f.fh.Stat() - if err != nil { - return false, err - } - - // Note(ldez): don't replace `syscall.Stat_t` by `unix.Stat_t` because `FileInfo.Sys()` returns `syscall.Stat_t` - ino := fi.Sys().(*syscall.Stat_t).Ino - - mu.Lock() - - if i, dup := inodes[f]; dup && i != ino { - mu.Unlock() - return false, &fs.PathError{ - Op: lt.String(), - Path: f.Path(), - Err: errors.New("inode for file changed since last Lock or RLock"), - } - } - - inodes[f] = ino - - var wait chan *Flock - - l := locks[ino] - - switch { - case l.owner == f: - // This file already owns the lock, but the call may change its lock type. - case l.owner == nil: - // No owner: it's ours now. - l.owner = f - - case !blocking: - // Already owned: cannot take the lock. - mu.Unlock() - return false, nil - - default: - // Already owned: add a channel to wait on. - wait = make(chan *Flock) - l.queue = append(l.queue, wait) - } - - locks[ino] = l - - mu.Unlock() - - if wait != nil { - wait <- f - } - - // Spurious EDEADLK errors arise on platforms that compute deadlock graphs at - // the process, rather than thread, level. Consider processes P and Q, with - // threads P.1, P.2, and Q.3. The following trace is NOT a deadlock, but will be - // reported as a deadlock on systems that consider only process granularity: - // - // P.1 locks file A. - // Q.3 locks file B. - // Q.3 blocks on file A. - // P.2 blocks on file B. (This is erroneously reported as a deadlock.) - // P.1 unlocks file A. - // Q.3 unblocks and locks file A. - // Q.3 unlocks files A and B. - // P.2 unblocks and locks file B. - // P.2 unlocks file B. - // - // These spurious errors were observed in practice on AIX and Solaris in - // cmd/go: see https://golang.org/issue/32817. - // - // We work around this bug by treating EDEADLK as always spurious. If there - // really is a lock-ordering bug between the interacting processes, it will - // become a livelock instead, but that's not appreciably worse than if we had - // a proper flock implementation (which generally does not even attempt to - // diagnose deadlocks). - // - // In the above example, that changes the trace to: - // - // P.1 locks file A. - // Q.3 locks file B. - // Q.3 blocks on file A. - // P.2 spuriously fails to lock file B and goes to sleep. - // P.1 unlocks file A. - // Q.3 unblocks and locks file A. - // Q.3 unlocks files A and B. - // P.2 wakes up and locks file B. - // P.2 unlocks file B. - // - // We know that the retry loop will not introduce a *spurious* livelock - // because, according to the POSIX specification, EDEADLK is only to be - // returned when “the lock is blocked by a lock from another process”. - // If that process is blocked on some lock that we are holding, then the - // resulting livelock is due to a real deadlock (and would manifest as such - // when using, for example, the flock implementation of this package). - // If the other process is *not* blocked on some other lock that we are - // holding, then it will eventually release the requested lock. - - nextSleep := 1 * time.Millisecond - const maxSleep = 500 * time.Millisecond - for { - err = setlkw(f.fh.Fd(), cmd, lt) - if !errors.Is(err, unix.EDEADLK) { - break - } - - time.Sleep(nextSleep) - - nextSleep += nextSleep - if nextSleep > maxSleep { - nextSleep = maxSleep - } - // Apply 10% jitter to avoid synchronizing collisions when we finally unblock. - nextSleep += time.Duration((0.1*rand.Float64() - 0.05) * float64(nextSleep)) - } - - if err != nil { - f.doUnlock() - - if cmd == tryLock && errors.Is(err, unix.EACCES) { - return false, nil - } - - return false, &fs.PathError{ - Op: lt.String(), - Path: f.Path(), - Err: err, - } - } - - return true, nil -} - -func (f *Flock) Unlock() error { - f.m.Lock() - defer f.m.Unlock() - - // If we aren't locked or if the lockfile instance is nil - // just return a nil error because we are unlocked. - if (!f.l && !f.r) || f.fh == nil { - return nil - } - - if err := f.doUnlock(); err != nil { - return err - } - - f.reset() - - return nil -} - -// https://github.com/golang/go/blob/09aeb6e33ab426eff4676a3baf694d5a3019e9fc/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go#L163 -func (f *Flock) doUnlock() (err error) { - var owner *Flock - - mu.Lock() - - ino, ok := inodes[f] - if ok { - owner = locks[ino].owner - } - - mu.Unlock() - - if owner == f { - err = setlkw(f.fh.Fd(), waitLock, unix.F_UNLCK) - } - - mu.Lock() - - l := locks[ino] - - if len(l.queue) == 0 { - // No waiters: remove the map entry. - delete(locks, ino) - } else { - // The first waiter is sending us their file now. - // Receive it and update the queue. - l.owner = <-l.queue[0] - l.queue = l.queue[1:] - locks[ino] = l - } - - delete(inodes, f) - - mu.Unlock() - - return err -} - -// TryLock is the preferred function for taking an exclusive file lock. -// This function takes an RW-mutex lock before it tries to lock the file, -// so there is the possibility that this function may block for a short time -// if another goroutine is trying to take any action. -// -// The actual file lock is non-blocking. -// If we are unable to get the exclusive file lock, -// the function will return false instead of waiting for the lock. -// If we get the lock, we also set the *Flock instance as being exclusive-locked. -func (f *Flock) TryLock() (bool, error) { - return f.try(&f.l, writeLock) -} - -// TryRLock is the preferred function for taking a shared file lock. -// This function takes an RW-mutex lock before it tries to lock the file, -// so there is the possibility that this function may block for a short time -// if another goroutine is trying to take any action. -// -// The actual file lock is non-blocking. -// If we are unable to get the shared file lock, -// the function will return false instead of waiting for the lock. -// If we get the lock, we also set the *Flock instance as being share-locked. -func (f *Flock) TryRLock() (bool, error) { - return f.try(&f.r, readLock) -} - -func (f *Flock) try(locked *bool, flag lockType) (bool, error) { - f.m.Lock() - defer f.m.Unlock() - - if *locked { - return true, nil - } - - if f.fh == nil { - if err := f.setFh(f.flag); err != nil { - return false, err - } - - defer f.ensureFhState() - } - - hasLock, err := f.doLock(tryLock, flag, false) - if err != nil { - return false, err - } - - *locked = hasLock - - return hasLock, nil -} - -// setlkw calls FcntlFlock with cmd for the entire file indicated by fd. -// https://github.com/golang/go/blob/09aeb6e33ab426eff4676a3baf694d5a3019e9fc/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go#L198 -func setlkw(fd uintptr, cmd cmdType, lt lockType) error { - for { - err := unix.FcntlFlock(fd, int(cmd), &unix.Flock_t{ - Type: int16(lt), - Whence: io.SeekStart, - Start: 0, - Len: 0, // All bytes. - }) - if !errors.Is(err, unix.EINTR) { - return err - } - } -} diff --git a/vendor/github.com/gofrs/flock/flock_windows.go b/vendor/github.com/gofrs/flock/flock_windows.go deleted file mode 100644 index aa144f156e..0000000000 --- a/vendor/github.com/gofrs/flock/flock_windows.go +++ /dev/null @@ -1,160 +0,0 @@ -// Copyright 2015 Tim Heckman. All rights reserved. -// Copyright 2018-2025 The Gofrs. All rights reserved. -// Use of this source code is governed by the BSD 3-Clause -// license that can be found in the LICENSE file. - -//go:build windows - -package flock - -import ( - "errors" - - "golang.org/x/sys/windows" -) - -// Use of 0x00000000 for the shared lock is a guess based on some the MS Windows `LockFileEX` docs, -// which document the `LOCKFILE_EXCLUSIVE_LOCK` flag as: -// -// > The function requests an exclusive lock. Otherwise, it requests a shared lock. -// -// https://msdn.microsoft.com/en-us/library/windows/desktop/aa365203(v=vs.85).aspx -const winLockfileSharedLock = 0x00000000 - -// ErrorLockViolation is the error code returned from the Windows syscall when a lock would block, -// and you ask to fail immediately. -// -//nolint:errname // It should be renamed to `ErrLockViolation`. -const ErrorLockViolation windows.Errno = 0x21 // 33 - -// Lock is a blocking call to try and take an exclusive file lock. -// It will wait until it is able to obtain the exclusive file lock. -// It's recommended that TryLock() be used over this function. -// This function may block the ability to query the current Locked() or RLocked() status due to a RW-mutex lock. -// -// If we are already locked, this function short-circuits and -// returns immediately assuming it can take the mutex lock. -func (f *Flock) Lock() error { - return f.lock(&f.l, windows.LOCKFILE_EXCLUSIVE_LOCK) -} - -// RLock is a blocking call to try and take a shared file lock. -// It will wait until it is able to obtain the shared file lock. -// It's recommended that TryRLock() be used over this function. -// This function may block the ability to query the current Locked() or RLocked() status due to a RW-mutex lock. -// -// If we are already locked, this function short-circuits and -// returns immediately assuming it can take the mutex lock. -func (f *Flock) RLock() error { - return f.lock(&f.r, winLockfileSharedLock) -} - -func (f *Flock) lock(locked *bool, flag uint32) error { - f.m.Lock() - defer f.m.Unlock() - - if *locked { - return nil - } - - if f.fh == nil { - if err := f.setFh(f.flag); err != nil { - return err - } - - defer f.ensureFhState() - } - - err := windows.LockFileEx(windows.Handle(f.fh.Fd()), flag, 0, 1, 0, &windows.Overlapped{}) - if err != nil && !errors.Is(err, windows.Errno(0)) { - return err - } - - *locked = true - - return nil -} - -// Unlock is a function to unlock the file. -// This file takes a RW-mutex lock, -// so while it is running the Locked() and RLocked() functions will be blocked. -// -// This function short-circuits if we are unlocked already. -// If not, it calls UnlockFileEx() on the file and closes the file descriptor. -// It does not remove the file from disk. -// It's up to your application to do. -func (f *Flock) Unlock() error { - f.m.Lock() - defer f.m.Unlock() - - // if we aren't locked or if the lockfile instance is nil - // just return a nil error because we are unlocked - if (!f.l && !f.r) || f.fh == nil { - return nil - } - - // mark the file as unlocked - err := windows.UnlockFileEx(windows.Handle(f.fh.Fd()), 0, 1, 0, &windows.Overlapped{}) - if err != nil && !errors.Is(err, windows.Errno(0)) { - return err - } - - f.reset() - - return nil -} - -// TryLock is the preferred function for taking an exclusive file lock. -// This function does take a RW-mutex lock before it tries to lock the file, -// so there is the possibility that this function may block for a short time -// if another goroutine is trying to take any action. -// -// The actual file lock is non-blocking. -// If we are unable to get the exclusive file lock, -// the function will return false instead of waiting for the lock. -// If we get the lock, we also set the *Flock instance as being exclusive-locked. -func (f *Flock) TryLock() (bool, error) { - return f.try(&f.l, windows.LOCKFILE_EXCLUSIVE_LOCK) -} - -// TryRLock is the preferred function for taking a shared file lock. -// This function does take a RW-mutex lock before it tries to lock the file, -// so there is the possibility that this function may block for a short time if another goroutine is trying to take any action. -// -// The actual file lock is non-blocking. -// If we are unable to get the shared file lock, -// the function will return false instead of waiting for the lock. -// If we get the lock, we also set the *Flock instance as being shared-locked. -func (f *Flock) TryRLock() (bool, error) { - return f.try(&f.r, winLockfileSharedLock) -} - -func (f *Flock) try(locked *bool, flag uint32) (bool, error) { - f.m.Lock() - defer f.m.Unlock() - - if *locked { - return true, nil - } - - if f.fh == nil { - if err := f.setFh(f.flag); err != nil { - return false, err - } - - defer f.ensureFhState() - } - - err := windows.LockFileEx(windows.Handle(f.fh.Fd()), flag|windows.LOCKFILE_FAIL_IMMEDIATELY, 0, 1, 0, &windows.Overlapped{}) - if err != nil && !errors.Is(err, windows.Errno(0)) { - if errors.Is(err, ErrorLockViolation) || errors.Is(err, windows.ERROR_IO_PENDING) { - return false, nil - } - - return false, err - } - - *locked = true - - return true, nil -} diff --git a/vendor/github.com/golang/protobuf/ptypes/any.go b/vendor/github.com/golang/protobuf/ptypes/any.go deleted file mode 100644 index fdff3fdb4c..0000000000 --- a/vendor/github.com/golang/protobuf/ptypes/any.go +++ /dev/null @@ -1,180 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ptypes - -import ( - "fmt" - "strings" - - "github.com/golang/protobuf/proto" - "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/reflect/protoregistry" - - anypb "github.com/golang/protobuf/ptypes/any" -) - -const urlPrefix = "type.googleapis.com/" - -// AnyMessageName returns the message name contained in an anypb.Any message. -// Most type assertions should use the Is function instead. -// -// Deprecated: Call the any.MessageName method instead. -func AnyMessageName(any *anypb.Any) (string, error) { - name, err := anyMessageName(any) - return string(name), err -} -func anyMessageName(any *anypb.Any) (protoreflect.FullName, error) { - if any == nil { - return "", fmt.Errorf("message is nil") - } - name := protoreflect.FullName(any.TypeUrl) - if i := strings.LastIndex(any.TypeUrl, "/"); i >= 0 { - name = name[i+len("/"):] - } - if !name.IsValid() { - return "", fmt.Errorf("message type url %q is invalid", any.TypeUrl) - } - return name, nil -} - -// MarshalAny marshals the given message m into an anypb.Any message. -// -// Deprecated: Call the anypb.New function instead. -func MarshalAny(m proto.Message) (*anypb.Any, error) { - switch dm := m.(type) { - case DynamicAny: - m = dm.Message - case *DynamicAny: - if dm == nil { - return nil, proto.ErrNil - } - m = dm.Message - } - b, err := proto.Marshal(m) - if err != nil { - return nil, err - } - return &anypb.Any{TypeUrl: urlPrefix + proto.MessageName(m), Value: b}, nil -} - -// Empty returns a new message of the type specified in an anypb.Any message. -// It returns protoregistry.NotFound if the corresponding message type could not -// be resolved in the global registry. -// -// Deprecated: Use protoregistry.GlobalTypes.FindMessageByName instead -// to resolve the message name and create a new instance of it. -func Empty(any *anypb.Any) (proto.Message, error) { - name, err := anyMessageName(any) - if err != nil { - return nil, err - } - mt, err := protoregistry.GlobalTypes.FindMessageByName(name) - if err != nil { - return nil, err - } - return proto.MessageV1(mt.New().Interface()), nil -} - -// UnmarshalAny unmarshals the encoded value contained in the anypb.Any message -// into the provided message m. It returns an error if the target message -// does not match the type in the Any message or if an unmarshal error occurs. -// -// The target message m may be a *DynamicAny message. If the underlying message -// type could not be resolved, then this returns protoregistry.NotFound. -// -// Deprecated: Call the any.UnmarshalTo method instead. -func UnmarshalAny(any *anypb.Any, m proto.Message) error { - if dm, ok := m.(*DynamicAny); ok { - if dm.Message == nil { - var err error - dm.Message, err = Empty(any) - if err != nil { - return err - } - } - m = dm.Message - } - - anyName, err := AnyMessageName(any) - if err != nil { - return err - } - msgName := proto.MessageName(m) - if anyName != msgName { - return fmt.Errorf("mismatched message type: got %q want %q", anyName, msgName) - } - return proto.Unmarshal(any.Value, m) -} - -// Is reports whether the Any message contains a message of the specified type. -// -// Deprecated: Call the any.MessageIs method instead. -func Is(any *anypb.Any, m proto.Message) bool { - if any == nil || m == nil { - return false - } - name := proto.MessageName(m) - if !strings.HasSuffix(any.TypeUrl, name) { - return false - } - return len(any.TypeUrl) == len(name) || any.TypeUrl[len(any.TypeUrl)-len(name)-1] == '/' -} - -// DynamicAny is a value that can be passed to UnmarshalAny to automatically -// allocate a proto.Message for the type specified in an anypb.Any message. -// The allocated message is stored in the embedded proto.Message. -// -// Example: -// -// var x ptypes.DynamicAny -// if err := ptypes.UnmarshalAny(a, &x); err != nil { ... } -// fmt.Printf("unmarshaled message: %v", x.Message) -// -// Deprecated: Use the any.UnmarshalNew method instead to unmarshal -// the any message contents into a new instance of the underlying message. -type DynamicAny struct{ proto.Message } - -func (m DynamicAny) String() string { - if m.Message == nil { - return "" - } - return m.Message.String() -} -func (m DynamicAny) Reset() { - if m.Message == nil { - return - } - m.Message.Reset() -} -func (m DynamicAny) ProtoMessage() { - return -} -func (m DynamicAny) ProtoReflect() protoreflect.Message { - if m.Message == nil { - return nil - } - return dynamicAny{proto.MessageReflect(m.Message)} -} - -type dynamicAny struct{ protoreflect.Message } - -func (m dynamicAny) Type() protoreflect.MessageType { - return dynamicAnyType{m.Message.Type()} -} -func (m dynamicAny) New() protoreflect.Message { - return dynamicAnyType{m.Message.Type()}.New() -} -func (m dynamicAny) Interface() protoreflect.ProtoMessage { - return DynamicAny{proto.MessageV1(m.Message.Interface())} -} - -type dynamicAnyType struct{ protoreflect.MessageType } - -func (t dynamicAnyType) New() protoreflect.Message { - return dynamicAny{t.MessageType.New()} -} -func (t dynamicAnyType) Zero() protoreflect.Message { - return dynamicAny{t.MessageType.Zero()} -} diff --git a/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go b/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go deleted file mode 100644 index 0ef27d33de..0000000000 --- a/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go +++ /dev/null @@ -1,62 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: github.com/golang/protobuf/ptypes/any/any.proto - -package any - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - anypb "google.golang.org/protobuf/types/known/anypb" - reflect "reflect" -) - -// Symbols defined in public import of google/protobuf/any.proto. - -type Any = anypb.Any - -var File_github_com_golang_protobuf_ptypes_any_any_proto protoreflect.FileDescriptor - -var file_github_com_golang_protobuf_ptypes_any_any_proto_rawDesc = []byte{ - 0x0a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, - 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x2f, 0x61, 0x6e, 0x79, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x2b, 0x5a, 0x29, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, - 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, - 0x73, 0x2f, 0x61, 0x6e, 0x79, 0x3b, 0x61, 0x6e, 0x79, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, -} - -var file_github_com_golang_protobuf_ptypes_any_any_proto_goTypes = []interface{}{} -var file_github_com_golang_protobuf_ptypes_any_any_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_github_com_golang_protobuf_ptypes_any_any_proto_init() } -func file_github_com_golang_protobuf_ptypes_any_any_proto_init() { - if File_github_com_golang_protobuf_ptypes_any_any_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_github_com_golang_protobuf_ptypes_any_any_proto_rawDesc, - NumEnums: 0, - NumMessages: 0, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_github_com_golang_protobuf_ptypes_any_any_proto_goTypes, - DependencyIndexes: file_github_com_golang_protobuf_ptypes_any_any_proto_depIdxs, - }.Build() - File_github_com_golang_protobuf_ptypes_any_any_proto = out.File - file_github_com_golang_protobuf_ptypes_any_any_proto_rawDesc = nil - file_github_com_golang_protobuf_ptypes_any_any_proto_goTypes = nil - file_github_com_golang_protobuf_ptypes_any_any_proto_depIdxs = nil -} diff --git a/vendor/github.com/golang/protobuf/ptypes/doc.go b/vendor/github.com/golang/protobuf/ptypes/doc.go deleted file mode 100644 index d3c33259d2..0000000000 --- a/vendor/github.com/golang/protobuf/ptypes/doc.go +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package ptypes provides functionality for interacting with well-known types. -// -// Deprecated: Well-known types have specialized functionality directly -// injected into the generated packages for each message type. -// See the deprecation notice for each function for the suggested alternative. -package ptypes diff --git a/vendor/github.com/golang/protobuf/ptypes/duration.go b/vendor/github.com/golang/protobuf/ptypes/duration.go deleted file mode 100644 index b2b55dd851..0000000000 --- a/vendor/github.com/golang/protobuf/ptypes/duration.go +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ptypes - -import ( - "errors" - "fmt" - "time" - - durationpb "github.com/golang/protobuf/ptypes/duration" -) - -// Range of google.protobuf.Duration as specified in duration.proto. -// This is about 10,000 years in seconds. -const ( - maxSeconds = int64(10000 * 365.25 * 24 * 60 * 60) - minSeconds = -maxSeconds -) - -// Duration converts a durationpb.Duration to a time.Duration. -// Duration returns an error if dur is invalid or overflows a time.Duration. -// -// Deprecated: Call the dur.AsDuration and dur.CheckValid methods instead. -func Duration(dur *durationpb.Duration) (time.Duration, error) { - if err := validateDuration(dur); err != nil { - return 0, err - } - d := time.Duration(dur.Seconds) * time.Second - if int64(d/time.Second) != dur.Seconds { - return 0, fmt.Errorf("duration: %v is out of range for time.Duration", dur) - } - if dur.Nanos != 0 { - d += time.Duration(dur.Nanos) * time.Nanosecond - if (d < 0) != (dur.Nanos < 0) { - return 0, fmt.Errorf("duration: %v is out of range for time.Duration", dur) - } - } - return d, nil -} - -// DurationProto converts a time.Duration to a durationpb.Duration. -// -// Deprecated: Call the durationpb.New function instead. -func DurationProto(d time.Duration) *durationpb.Duration { - nanos := d.Nanoseconds() - secs := nanos / 1e9 - nanos -= secs * 1e9 - return &durationpb.Duration{ - Seconds: int64(secs), - Nanos: int32(nanos), - } -} - -// validateDuration determines whether the durationpb.Duration is valid -// according to the definition in google/protobuf/duration.proto. -// A valid durpb.Duration may still be too large to fit into a time.Duration -// Note that the range of durationpb.Duration is about 10,000 years, -// while the range of time.Duration is about 290 years. -func validateDuration(dur *durationpb.Duration) error { - if dur == nil { - return errors.New("duration: nil Duration") - } - if dur.Seconds < minSeconds || dur.Seconds > maxSeconds { - return fmt.Errorf("duration: %v: seconds out of range", dur) - } - if dur.Nanos <= -1e9 || dur.Nanos >= 1e9 { - return fmt.Errorf("duration: %v: nanos out of range", dur) - } - // Seconds and Nanos must have the same sign, unless d.Nanos is zero. - if (dur.Seconds < 0 && dur.Nanos > 0) || (dur.Seconds > 0 && dur.Nanos < 0) { - return fmt.Errorf("duration: %v: seconds and nanos have different signs", dur) - } - return nil -} diff --git a/vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go b/vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go deleted file mode 100644 index d0079ee3ef..0000000000 --- a/vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go +++ /dev/null @@ -1,63 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: github.com/golang/protobuf/ptypes/duration/duration.proto - -package duration - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - durationpb "google.golang.org/protobuf/types/known/durationpb" - reflect "reflect" -) - -// Symbols defined in public import of google/protobuf/duration.proto. - -type Duration = durationpb.Duration - -var File_github_com_golang_protobuf_ptypes_duration_duration_proto protoreflect.FileDescriptor - -var file_github_com_golang_protobuf_ptypes_duration_duration_proto_rawDesc = []byte{ - 0x0a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, - 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x64, 0x75, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x35, 0x5a, 0x33, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var file_github_com_golang_protobuf_ptypes_duration_duration_proto_goTypes = []interface{}{} -var file_github_com_golang_protobuf_ptypes_duration_duration_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_github_com_golang_protobuf_ptypes_duration_duration_proto_init() } -func file_github_com_golang_protobuf_ptypes_duration_duration_proto_init() { - if File_github_com_golang_protobuf_ptypes_duration_duration_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_github_com_golang_protobuf_ptypes_duration_duration_proto_rawDesc, - NumEnums: 0, - NumMessages: 0, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_github_com_golang_protobuf_ptypes_duration_duration_proto_goTypes, - DependencyIndexes: file_github_com_golang_protobuf_ptypes_duration_duration_proto_depIdxs, - }.Build() - File_github_com_golang_protobuf_ptypes_duration_duration_proto = out.File - file_github_com_golang_protobuf_ptypes_duration_duration_proto_rawDesc = nil - file_github_com_golang_protobuf_ptypes_duration_duration_proto_goTypes = nil - file_github_com_golang_protobuf_ptypes_duration_duration_proto_depIdxs = nil -} diff --git a/vendor/github.com/golang/protobuf/ptypes/timestamp.go b/vendor/github.com/golang/protobuf/ptypes/timestamp.go deleted file mode 100644 index 8368a3f70d..0000000000 --- a/vendor/github.com/golang/protobuf/ptypes/timestamp.go +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ptypes - -import ( - "errors" - "fmt" - "time" - - timestamppb "github.com/golang/protobuf/ptypes/timestamp" -) - -// Range of google.protobuf.Duration as specified in timestamp.proto. -const ( - // Seconds field of the earliest valid Timestamp. - // This is time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC).Unix(). - minValidSeconds = -62135596800 - // Seconds field just after the latest valid Timestamp. - // This is time.Date(10000, 1, 1, 0, 0, 0, 0, time.UTC).Unix(). - maxValidSeconds = 253402300800 -) - -// Timestamp converts a timestamppb.Timestamp to a time.Time. -// It returns an error if the argument is invalid. -// -// Unlike most Go functions, if Timestamp returns an error, the first return -// value is not the zero time.Time. Instead, it is the value obtained from the -// time.Unix function when passed the contents of the Timestamp, in the UTC -// locale. This may or may not be a meaningful time; many invalid Timestamps -// do map to valid time.Times. -// -// A nil Timestamp returns an error. The first return value in that case is -// undefined. -// -// Deprecated: Call the ts.AsTime and ts.CheckValid methods instead. -func Timestamp(ts *timestamppb.Timestamp) (time.Time, error) { - // Don't return the zero value on error, because corresponds to a valid - // timestamp. Instead return whatever time.Unix gives us. - var t time.Time - if ts == nil { - t = time.Unix(0, 0).UTC() // treat nil like the empty Timestamp - } else { - t = time.Unix(ts.Seconds, int64(ts.Nanos)).UTC() - } - return t, validateTimestamp(ts) -} - -// TimestampNow returns a google.protobuf.Timestamp for the current time. -// -// Deprecated: Call the timestamppb.Now function instead. -func TimestampNow() *timestamppb.Timestamp { - ts, err := TimestampProto(time.Now()) - if err != nil { - panic("ptypes: time.Now() out of Timestamp range") - } - return ts -} - -// TimestampProto converts the time.Time to a google.protobuf.Timestamp proto. -// It returns an error if the resulting Timestamp is invalid. -// -// Deprecated: Call the timestamppb.New function instead. -func TimestampProto(t time.Time) (*timestamppb.Timestamp, error) { - ts := ×tamppb.Timestamp{ - Seconds: t.Unix(), - Nanos: int32(t.Nanosecond()), - } - if err := validateTimestamp(ts); err != nil { - return nil, err - } - return ts, nil -} - -// TimestampString returns the RFC 3339 string for valid Timestamps. -// For invalid Timestamps, it returns an error message in parentheses. -// -// Deprecated: Call the ts.AsTime method instead, -// followed by a call to the Format method on the time.Time value. -func TimestampString(ts *timestamppb.Timestamp) string { - t, err := Timestamp(ts) - if err != nil { - return fmt.Sprintf("(%v)", err) - } - return t.Format(time.RFC3339Nano) -} - -// validateTimestamp determines whether a Timestamp is valid. -// A valid timestamp represents a time in the range [0001-01-01, 10000-01-01) -// and has a Nanos field in the range [0, 1e9). -// -// If the Timestamp is valid, validateTimestamp returns nil. -// Otherwise, it returns an error that describes the problem. -// -// Every valid Timestamp can be represented by a time.Time, -// but the converse is not true. -func validateTimestamp(ts *timestamppb.Timestamp) error { - if ts == nil { - return errors.New("timestamp: nil Timestamp") - } - if ts.Seconds < minValidSeconds { - return fmt.Errorf("timestamp: %v before 0001-01-01", ts) - } - if ts.Seconds >= maxValidSeconds { - return fmt.Errorf("timestamp: %v after 10000-01-01", ts) - } - if ts.Nanos < 0 || ts.Nanos >= 1e9 { - return fmt.Errorf("timestamp: %v: nanos not in range [0, 1e9)", ts) - } - return nil -} diff --git a/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go b/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go deleted file mode 100644 index a76f807600..0000000000 --- a/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go +++ /dev/null @@ -1,64 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: github.com/golang/protobuf/ptypes/timestamp/timestamp.proto - -package timestamp - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - timestamppb "google.golang.org/protobuf/types/known/timestamppb" - reflect "reflect" -) - -// Symbols defined in public import of google/protobuf/timestamp.proto. - -type Timestamp = timestamppb.Timestamp - -var File_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto protoreflect.FileDescriptor - -var file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_rawDesc = []byte{ - 0x0a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, - 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2f, 0x74, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x37, - 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, - 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x3b, 0x74, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, -} - -var file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_goTypes = []interface{}{} -var file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_init() } -func file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_init() { - if File_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_rawDesc, - NumEnums: 0, - NumMessages: 0, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_goTypes, - DependencyIndexes: file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_depIdxs, - }.Build() - File_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto = out.File - file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_rawDesc = nil - file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_goTypes = nil - file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_depIdxs = nil -} diff --git a/vendor/github.com/golangci/asciicheck/.gitignore b/vendor/github.com/golangci/asciicheck/.gitignore deleted file mode 100644 index 26938fd810..0000000000 --- a/vendor/github.com/golangci/asciicheck/.gitignore +++ /dev/null @@ -1,21 +0,0 @@ -# IntelliJ project files -.idea -*.iml -out -gen - -# Go template -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib - -# Test binary, built with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -/asciicheck diff --git a/vendor/github.com/golangci/asciicheck/.golangci.yml b/vendor/github.com/golangci/asciicheck/.golangci.yml deleted file mode 100644 index e28845eb59..0000000000 --- a/vendor/github.com/golangci/asciicheck/.golangci.yml +++ /dev/null @@ -1,87 +0,0 @@ -version: "2" - -formatters: - enable: - - gci - - gofumpt - settings: - gofumpt: - extra-rules: true - -linters: - default: all - disable: - - cyclop # duplicate of gocyclo - - dupl - - errchkjson - - exhaustive - - exhaustruct - - lll - - mnd - - nilnil - - nlreturn - - nonamedreturns - - paralleltest - - prealloc - - rowserrcheck # not relevant (SQL) - - sqlclosecheck # not relevant (SQL) - - testpackage - - tparallel - - varnamelen - - wsl # Deprecated - - forcetypeassert # recheck in the future. - - settings: - depguard: - rules: - main: - deny: - - pkg: github.com/instana/testify - desc: not allowed - - pkg: github.com/pkg/errors - desc: Should be replaced by standard lib errors package - funlen: - lines: -1 - statements: 40 - goconst: - min-len: 5 - min-occurrences: 3 - gocritic: - disabled-checks: - - sloppyReassign - - rangeValCopy - - octalLiteral - - paramTypeCombine # already handle by gofumpt.extra-rules - enabled-tags: - - diagnostic - - style - - performance - settings: - hugeParam: - sizeThreshold: 100 - gocyclo: - min-complexity: 20 - godox: - keywords: - - FIXME - govet: - disable: - - fieldalignment - enable-all: true - misspell: - locale: US - mnd: - ignored-numbers: - - "124" - wsl: - force-case-trailing-whitespace: 1 - allow-trailing-comment: true - exclusions: - presets: - - comments - - std-error-handling - - common-false-positives - -issues: - max-issues-per-linter: 0 - max-same-issues: 0 diff --git a/vendor/github.com/golangci/asciicheck/LICENSE b/vendor/github.com/golangci/asciicheck/LICENSE deleted file mode 100644 index 48a60cf1c4..0000000000 --- a/vendor/github.com/golangci/asciicheck/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2020 tdakkota - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/golangci/asciicheck/Makefile b/vendor/github.com/golangci/asciicheck/Makefile deleted file mode 100644 index cdfc261144..0000000000 --- a/vendor/github.com/golangci/asciicheck/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -.PHONY: clean check test build - -default: clean check test build - -clean: - rm -rf dist/ cover.out - -test: clean - go test -v -cover ./... - -check: - golangci-lint run - -build: - go build -ldflags "-s -w" -trimpath ./cmd/asciicheck/ diff --git a/vendor/github.com/golangci/asciicheck/README.md b/vendor/github.com/golangci/asciicheck/README.md deleted file mode 100644 index 0d1da4b97c..0000000000 --- a/vendor/github.com/golangci/asciicheck/README.md +++ /dev/null @@ -1,82 +0,0 @@ -# asciicheck - -[![Go Report Card](https://goreportcard.com/badge/github.com/golangci/asciicheck)](https://goreportcard.com/report/github.com/golangci/asciicheck) - -Simple linter to check that your code does not contain non-ASCII identifiers - -The project has been moved to the golangci organization because the GitHub account of the original author (@tdakkota) is no longer available. - -## Install - -```bash -go install github.com/golangci/asciicheck/cmd/asciicheck@latest -``` - -## Reason to use - -So, do you see this code? Looks correct, isn't it? - -```go -package main - -import "fmt" - -type TеstStruct struct{} - -func main() { - s := TestStruct{} - fmt.Println(s) -} -``` - -But if you try to run it, you will get an error: - -``` -./prog.go:8:7: undefined: TestStruct -``` -What? `TestStruct` is defined above, but compiler thinks diffrent. Why? - -**Answer**: - -Because `TestStruct` is not `TеstStruct`. -``` -type TеstStruct struct{} - ^ this 'e' (U+0435) is not 'e' (U+0065) -``` - -## Usage - -asciicheck uses [`singlechecker`](https://pkg.go.dev/golang.org/x/tools/go/analysis/singlechecker) package to run: - -``` -asciicheck: checks that all code identifiers does not have non-ASCII symbols in the name - -Usage: asciicheck [-flag] [package] - - -Flags: - -V print version and exit - -all - no effect (deprecated) - -c int - display offending line with this many lines of context (default -1) - -cpuprofile string - write CPU profile to this file - -debug string - debug flags, any subset of "fpstv" - -fix - apply all suggested fixes - -flags - print analyzer flags in JSON - -json - emit JSON output - -memprofile string - write memory profile to this file - -source - no effect (deprecated) - -tags string - no effect (deprecated) - -trace string - write trace log to this file - -v no effect (deprecated) -``` diff --git a/vendor/github.com/golangci/asciicheck/ascii.go b/vendor/github.com/golangci/asciicheck/ascii.go deleted file mode 100644 index 43fe25b59e..0000000000 --- a/vendor/github.com/golangci/asciicheck/ascii.go +++ /dev/null @@ -1,21 +0,0 @@ -package asciicheck - -import ( - "unicode" - "unicode/utf8" -) - -func isASCII(s string) (rune, bool) { - if len(s) == 1 { - r, size := utf8.DecodeRuneInString(s) - return r, size < 2 - } - - for _, r := range s { - if r > unicode.MaxASCII { - return r, false - } - } - - return 0, true -} diff --git a/vendor/github.com/golangci/asciicheck/asciicheck.go b/vendor/github.com/golangci/asciicheck/asciicheck.go deleted file mode 100644 index 0983c7270c..0000000000 --- a/vendor/github.com/golangci/asciicheck/asciicheck.go +++ /dev/null @@ -1,104 +0,0 @@ -package asciicheck - -import ( - "fmt" - "go/ast" - "go/token" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/inspector" -) - -func NewAnalyzer() *analysis.Analyzer { - return &analysis.Analyzer{ - Name: "asciicheck", - Doc: "checks that all code identifiers does not have non-ASCII symbols in the name", - Requires: []*analysis.Analyzer{inspect.Analyzer}, - Run: run, - } -} - -func run(pass *analysis.Pass) (any, error) { - insp := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - - nodeFilter := []ast.Node{ - (*ast.File)(nil), - (*ast.ImportSpec)(nil), - (*ast.TypeSpec)(nil), - (*ast.ValueSpec)(nil), - (*ast.FuncDecl)(nil), - (*ast.StructType)(nil), - (*ast.FuncType)(nil), - (*ast.InterfaceType)(nil), - (*ast.LabeledStmt)(nil), - (*ast.AssignStmt)(nil), - } - - insp.Preorder(nodeFilter, func(n ast.Node) { - switch n := n.(type) { - case *ast.File: - checkIdent(pass, n.Name) - case *ast.ImportSpec: - checkIdent(pass, n.Name) - case *ast.TypeSpec: - checkIdent(pass, n.Name) - checkFieldList(pass, n.TypeParams) - case *ast.ValueSpec: - for _, name := range n.Names { - checkIdent(pass, name) - } - case *ast.FuncDecl: - checkIdent(pass, n.Name) - checkFieldList(pass, n.Recv) - case *ast.StructType: - checkFieldList(pass, n.Fields) - case *ast.FuncType: - checkFieldList(pass, n.TypeParams) - checkFieldList(pass, n.Params) - checkFieldList(pass, n.Results) - case *ast.InterfaceType: - checkFieldList(pass, n.Methods) - case *ast.LabeledStmt: - checkIdent(pass, n.Label) - case *ast.AssignStmt: - if n.Tok == token.DEFINE { - for _, expr := range n.Lhs { - if ident, ok := expr.(*ast.Ident); ok { - checkIdent(pass, ident) - } - } - } - } - }) - - return nil, nil -} - -func checkIdent(pass *analysis.Pass, v *ast.Ident) { - if v == nil { - return - } - - ch, ascii := isASCII(v.Name) - if !ascii { - pass.Report( - analysis.Diagnostic{ - Pos: v.Pos(), - Message: fmt.Sprintf("identifier %q contain non-ASCII character: %#U", v.Name, ch), - }, - ) - } -} - -func checkFieldList(pass *analysis.Pass, f *ast.FieldList) { - if f == nil { - return - } - - for _, f := range f.List { - for _, name := range f.Names { - checkIdent(pass, name) - } - } -} diff --git a/vendor/github.com/golangci/dupl/LICENSE b/vendor/github.com/golangci/dupl/LICENSE deleted file mode 100644 index ab317d8413..0000000000 --- a/vendor/github.com/golangci/dupl/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015 Michal Bohuslávek - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/golangci/dupl/job/buildtree.go b/vendor/github.com/golangci/dupl/job/buildtree.go deleted file mode 100644 index e9aad54c0f..0000000000 --- a/vendor/github.com/golangci/dupl/job/buildtree.go +++ /dev/null @@ -1,22 +0,0 @@ -package job - -import ( - "github.com/golangci/dupl/suffixtree" - "github.com/golangci/dupl/syntax" -) - -func BuildTree(schan chan []*syntax.Node) (t *suffixtree.STree, d *[]*syntax.Node, done chan bool) { - t = suffixtree.New() - data := make([]*syntax.Node, 0, 100) - done = make(chan bool) - go func() { - for seq := range schan { - data = append(data, seq...) - for _, node := range seq { - t.Update(node) - } - } - done <- true - }() - return t, &data, done -} diff --git a/vendor/github.com/golangci/dupl/job/parse.go b/vendor/github.com/golangci/dupl/job/parse.go deleted file mode 100644 index eb9d7c6255..0000000000 --- a/vendor/github.com/golangci/dupl/job/parse.go +++ /dev/null @@ -1,36 +0,0 @@ -package job - -import ( - "log" - - "github.com/golangci/dupl/syntax" - "github.com/golangci/dupl/syntax/golang" -) - -func Parse(fchan chan string) chan []*syntax.Node { - - // parse AST - achan := make(chan *syntax.Node) - go func() { - for file := range fchan { - ast, err := golang.Parse(file) - if err != nil { - log.Println(err) - continue - } - achan <- ast - } - close(achan) - }() - - // serialize - schan := make(chan []*syntax.Node) - go func() { - for ast := range achan { - seq := syntax.Serialize(ast) - schan <- seq - } - close(schan) - }() - return schan -} diff --git a/vendor/github.com/golangci/dupl/lib/lib.go b/vendor/github.com/golangci/dupl/lib/lib.go deleted file mode 100644 index 3000a8f38c..0000000000 --- a/vendor/github.com/golangci/dupl/lib/lib.go +++ /dev/null @@ -1,88 +0,0 @@ -// Package lib Golangci-lint: altered version of main.go -package lib - -import ( - "os" - "sort" - - "github.com/golangci/dupl/job" - "github.com/golangci/dupl/printer" - "github.com/golangci/dupl/syntax" -) - -func Run(files []string, threshold int) ([]printer.Issue, error) { - fchan := make(chan string, 1024) - go func() { - for _, f := range files { - fchan <- f - } - close(fchan) - }() - schan := job.Parse(fchan) - t, data, done := job.BuildTree(schan) - <-done - - // finish stream - t.Update(&syntax.Node{Type: -1}) - - mchan := t.FindDuplOver(threshold) - duplChan := make(chan syntax.Match) - go func() { - for m := range mchan { - match := syntax.FindSyntaxUnits(*data, m, threshold) - if len(match.Frags) > 0 { - duplChan <- match - } - } - close(duplChan) - }() - - return makeIssues(duplChan) -} - -func makeIssues(duplChan <-chan syntax.Match) ([]printer.Issue, error) { - groups := make(map[string][][]*syntax.Node) - for dupl := range duplChan { - groups[dupl.Hash] = append(groups[dupl.Hash], dupl.Frags...) - } - keys := make([]string, 0, len(groups)) - for k := range groups { - keys = append(keys, k) - } - sort.Strings(keys) - - p := printer.NewIssuer(os.ReadFile) - - var issues []printer.Issue - for _, k := range keys { - uniq := unique(groups[k]) - if len(uniq) > 1 { - i, err := p.MakeIssues(uniq) - if err != nil { - return nil, err - } - issues = append(issues, i...) - } - } - - return issues, nil -} - -func unique(group [][]*syntax.Node) [][]*syntax.Node { - fileMap := make(map[string]map[int]struct{}) - - var newGroup [][]*syntax.Node - for _, seq := range group { - node := seq[0] - file, ok := fileMap[node.Filename] - if !ok { - file = make(map[int]struct{}) - fileMap[node.Filename] = file - } - if _, ok := file[node.Pos]; !ok { - file[node.Pos] = struct{}{} - newGroup = append(newGroup, seq) - } - } - return newGroup -} diff --git a/vendor/github.com/golangci/dupl/printer/html.go b/vendor/github.com/golangci/dupl/printer/html.go deleted file mode 100644 index ac14741419..0000000000 --- a/vendor/github.com/golangci/dupl/printer/html.go +++ /dev/null @@ -1,122 +0,0 @@ -package printer - -import ( - "bytes" - "fmt" - "html" - "io" - "regexp" - "sort" - - "github.com/golangci/dupl/syntax" -) - -type htmlprinter struct { - iota int - w io.Writer - ReadFile -} - -func NewHTML(w io.Writer, fread ReadFile) Printer { - return &htmlprinter{w: w, ReadFile: fread} -} - -func (p *htmlprinter) PrintHeader() error { - _, err := fmt.Fprint(p.w, ` - -Duplicates - -`) - return err -} - -func (p *htmlprinter) PrintClones(dups [][]*syntax.Node) error { - p.iota++ - fmt.Fprintf(p.w, "

#%d found %d clones

\n", p.iota, len(dups)) - - clones := make([]clone, len(dups)) - for i, dup := range dups { - cnt := len(dup) - if cnt == 0 { - panic("zero length dup") - } - nstart := dup[0] - nend := dup[cnt-1] - - file, err := p.ReadFile(nstart.Filename) - if err != nil { - return err - } - - lineStart, _ := blockLines(file, nstart.Pos, nend.End) - cl := clone{filename: nstart.Filename, lineStart: lineStart} - start := findLineBeg(file, nstart.Pos) - content := append(toWhitespace(file[start:nstart.Pos]), file[nstart.Pos:nend.End]...) - cl.fragment = deindent(content) - clones[i] = cl - } - - sort.Sort(byNameAndLine(clones)) - for _, cl := range clones { - fmt.Fprintf(p.w, "

%s:%d

\n
%s
\n", cl.filename, cl.lineStart, - html.EscapeString(string(cl.fragment))) - } - return nil -} - -func (*htmlprinter) PrintFooter() error { return nil } - -func findLineBeg(file []byte, index int) int { - for i := index; i >= 0; i-- { - if file[i] == '\n' { - return i + 1 - } - } - return 0 -} - -func toWhitespace(str []byte) []byte { - var out []byte - for _, c := range bytes.Runes(str) { - if c == '\t' { - out = append(out, '\t') - } else { - out = append(out, ' ') - } - } - return out -} - -func deindent(block []byte) []byte { - const maxVal = 99 - min := maxVal - re := regexp.MustCompile(`(^|\n)(\t*)\S`) - for _, line := range re.FindAllSubmatch(block, -1) { - indent := line[2] - if len(indent) < min { - min = len(indent) - } - } - if min == 0 || min == maxVal { - return block - } - block = block[min:] -Loop: - for i := 0; i < len(block); i++ { - if block[i] == '\n' && i != len(block)-1 { - for j := 0; j < min; j++ { - if block[i+j+1] != '\t' { - continue Loop - } - } - block = append(block[:i+1], block[i+1+min:]...) - } - } - return block -} diff --git a/vendor/github.com/golangci/dupl/printer/issuer.go b/vendor/github.com/golangci/dupl/printer/issuer.go deleted file mode 100644 index 9b79f57056..0000000000 --- a/vendor/github.com/golangci/dupl/printer/issuer.go +++ /dev/null @@ -1,56 +0,0 @@ -package printer - -// Golangci-lint: altered version of plumbing.go - -import ( - "sort" - - "github.com/golangci/dupl/syntax" -) - -type Clone clone - -func (c Clone) Filename() string { - return c.filename -} - -func (c Clone) LineStart() int { - return c.lineStart -} - -func (c Clone) LineEnd() int { - return c.lineEnd -} - -type Issue struct { - From, To Clone -} - -type Issuer struct { - ReadFile -} - -func NewIssuer(fread ReadFile) *Issuer { - return &Issuer{fread} -} - -func (p *Issuer) MakeIssues(dups [][]*syntax.Node) ([]Issue, error) { - clones, err := prepareClonesInfo(p.ReadFile, dups) - if err != nil { - return nil, err - } - - sort.Sort(byNameAndLine(clones)) - - var issues []Issue - - for i, cl := range clones { - nextCl := clones[(i+1)%len(clones)] - issues = append(issues, Issue{ - From: Clone(cl), - To: Clone(nextCl), - }) - } - - return issues, nil -} diff --git a/vendor/github.com/golangci/dupl/printer/plumbing.go b/vendor/github.com/golangci/dupl/printer/plumbing.go deleted file mode 100644 index b0577ddd56..0000000000 --- a/vendor/github.com/golangci/dupl/printer/plumbing.go +++ /dev/null @@ -1,36 +0,0 @@ -package printer - -import ( - "fmt" - "io" - "sort" - - "github.com/golangci/dupl/syntax" -) - -type plumbing struct { - w io.Writer - ReadFile -} - -func NewPlumbing(w io.Writer, fread ReadFile) Printer { - return &plumbing{w, fread} -} - -func (p *plumbing) PrintHeader() error { return nil } - -func (p *plumbing) PrintClones(dups [][]*syntax.Node) error { - clones, err := prepareClonesInfo(p.ReadFile, dups) - if err != nil { - return err - } - sort.Sort(byNameAndLine(clones)) - for i, cl := range clones { - nextCl := clones[(i+1)%len(clones)] - fmt.Fprintf(p.w, "%s:%d-%d: duplicate of %s:%d-%d\n", cl.filename, cl.lineStart, cl.lineEnd, - nextCl.filename, nextCl.lineStart, nextCl.lineEnd) - } - return nil -} - -func (p *plumbing) PrintFooter() error { return nil } diff --git a/vendor/github.com/golangci/dupl/printer/printer.go b/vendor/github.com/golangci/dupl/printer/printer.go deleted file mode 100644 index 385217bfc1..0000000000 --- a/vendor/github.com/golangci/dupl/printer/printer.go +++ /dev/null @@ -1,11 +0,0 @@ -package printer - -import "github.com/golangci/dupl/syntax" - -type ReadFile func(filename string) ([]byte, error) - -type Printer interface { - PrintHeader() error - PrintClones(dups [][]*syntax.Node) error - PrintFooter() error -} diff --git a/vendor/github.com/golangci/dupl/printer/text.go b/vendor/github.com/golangci/dupl/printer/text.go deleted file mode 100644 index 8359fa76f4..0000000000 --- a/vendor/github.com/golangci/dupl/printer/text.go +++ /dev/null @@ -1,100 +0,0 @@ -package printer - -import ( - "fmt" - "io" - "sort" - - "github.com/golangci/dupl/syntax" -) - -type text struct { - cnt int - w io.Writer - ReadFile -} - -func NewText(w io.Writer, fread ReadFile) Printer { - return &text{w: w, ReadFile: fread} -} - -func (p *text) PrintHeader() error { return nil } - -func (p *text) PrintClones(dups [][]*syntax.Node) error { - p.cnt++ - fmt.Fprintf(p.w, "found %d clones:\n", len(dups)) - clones, err := prepareClonesInfo(p.ReadFile, dups) - if err != nil { - return err - } - sort.Sort(byNameAndLine(clones)) - for _, cl := range clones { - fmt.Fprintf(p.w, " %s:%d,%d\n", cl.filename, cl.lineStart, cl.lineEnd) - } - return nil -} - -func (p *text) PrintFooter() error { - _, err := fmt.Fprintf(p.w, "\nFound total %d clone groups.\n", p.cnt) - return err -} - -func prepareClonesInfo(fread ReadFile, dups [][]*syntax.Node) ([]clone, error) { - clones := make([]clone, len(dups)) - for i, dup := range dups { - cnt := len(dup) - if cnt == 0 { - panic("zero length dup") - } - nstart := dup[0] - nend := dup[cnt-1] - - file, err := fread(nstart.Filename) - if err != nil { - return nil, err - } - - cl := clone{filename: nstart.Filename} - cl.lineStart, cl.lineEnd = blockLines(file, nstart.Pos, nend.End) - clones[i] = cl - } - return clones, nil -} - -func blockLines(file []byte, from, to int) (int, int) { - line := 1 - lineStart, lineEnd := 0, 0 - for offset, b := range file { - if b == '\n' { - line++ - } - if offset == from { - lineStart = line - } - if offset == to-1 { - lineEnd = line - break - } - } - return lineStart, lineEnd -} - -type clone struct { - filename string - lineStart int - lineEnd int - fragment []byte -} - -type byNameAndLine []clone - -func (c byNameAndLine) Len() int { return len(c) } - -func (c byNameAndLine) Swap(i, j int) { c[i], c[j] = c[j], c[i] } - -func (c byNameAndLine) Less(i, j int) bool { - if c[i].filename == c[j].filename { - return c[i].lineStart < c[j].lineStart - } - return c[i].filename < c[j].filename -} diff --git a/vendor/github.com/golangci/dupl/suffixtree/dupl.go b/vendor/github.com/golangci/dupl/suffixtree/dupl.go deleted file mode 100644 index ab145b4f3b..0000000000 --- a/vendor/github.com/golangci/dupl/suffixtree/dupl.go +++ /dev/null @@ -1,98 +0,0 @@ -package suffixtree - -import "sort" - -type Match struct { - Ps []Pos - Len Pos -} - -type posList struct { - positions []Pos -} - -func newPosList() *posList { - return &posList{make([]Pos, 0)} -} - -func (p *posList) append(p2 *posList) { - p.positions = append(p.positions, p2.positions...) -} - -func (p *posList) add(pos Pos) { - p.positions = append(p.positions, pos) -} - -type contextList struct { - lists map[int]*posList -} - -func newContextList() *contextList { - return &contextList{make(map[int]*posList)} -} - -func (c *contextList) getAll() []Pos { - keys := make([]int, 0, len(c.lists)) - for k := range c.lists { - keys = append(keys, k) - } - sort.Ints(keys) - var ps []Pos - for _, k := range keys { - ps = append(ps, c.lists[k].positions...) - } - return ps -} - -func (c *contextList) append(c2 *contextList) { - for lc, pl := range c2.lists { - if _, ok := c.lists[lc]; ok { - c.lists[lc].append(pl) - } else { - c.lists[lc] = pl - } - } -} - -// FindDuplOver find pairs of maximal duplicities over a threshold -// length. -func (t *STree) FindDuplOver(threshold int) <-chan Match { - auxTran := newTran(0, 0, t.root) - ch := make(chan Match) - go func() { - walkTrans(auxTran, 0, threshold, ch) - close(ch) - }() - return ch -} - -func walkTrans(parent *tran, length, threshold int, ch chan<- Match) *contextList { - s := parent.state - - cl := newContextList() - - if len(s.trans) == 0 { - pl := newPosList() - start := parent.end + 1 - Pos(length) - pl.add(start) - ch := 0 - if start > 0 { - ch = s.tree.data[start-1].Val() - } - cl.lists[ch] = pl - return cl - } - - for _, t := range s.trans { - ln := length + t.len() - cl2 := walkTrans(t, ln, threshold, ch) - if ln >= threshold { - cl.append(cl2) - } - } - if length >= threshold && len(cl.lists) > 1 { - m := Match{cl.getAll(), Pos(length)} - ch <- m - } - return cl -} diff --git a/vendor/github.com/golangci/dupl/suffixtree/suffixtree.go b/vendor/github.com/golangci/dupl/suffixtree/suffixtree.go deleted file mode 100644 index 871469e8d5..0000000000 --- a/vendor/github.com/golangci/dupl/suffixtree/suffixtree.go +++ /dev/null @@ -1,216 +0,0 @@ -package suffixtree - -import ( - "bytes" - "fmt" - "math" - "strings" -) - -const infinity = math.MaxInt32 - -// Pos denotes position in data slice. -type Pos int32 - -type Token interface { - Val() int -} - -// STree is a struct representing a suffix tree. -type STree struct { - data []Token - root *state - auxState *state // auxiliary state - - // active point - s *state - start, end Pos -} - -// New creates new suffix tree. -func New() *STree { - t := new(STree) - t.data = make([]Token, 0, 50) - t.root = newState(t) - t.auxState = newState(t) - t.root.linkState = t.auxState - t.s = t.root - return t -} - -// Update refreshes the suffix tree to by new data. -func (t *STree) Update(data ...Token) { - t.data = append(t.data, data...) - for range data { - t.update() - t.s, t.start = t.canonize(t.s, t.start, t.end) - t.end++ - } -} - -// update transforms suffix tree T(n) to T(n+1). -func (t *STree) update() { - oldr := t.root - - // (s, (start, end)) is the canonical reference pair for the active point - s := t.s - start, end := t.start, t.end - var r *state - for { - var endPoint bool - r, endPoint = t.testAndSplit(s, start, end-1) - if endPoint { - break - } - r.fork(end) - if oldr != t.root { - oldr.linkState = r - } - oldr = r - s, start = t.canonize(s.linkState, start, end-1) - } - if oldr != t.root { - oldr.linkState = r - } - - // update active point - t.s = s - t.start = start -} - -// testAndSplit tests whether a state with canonical ref. pair -// (s, (start, end)) is the end point, that is, a state that have -// a c-transition. If not, then state (exs, (start, end)) is made -// explicit (if not already so). -func (t *STree) testAndSplit(s *state, start, end Pos) (exs *state, endPoint bool) { - c := t.data[t.end] - if start <= end { - tr := s.findTran(t.data[start]) - splitPoint := tr.start + end - start + 1 - if t.data[splitPoint].Val() == c.Val() { - return s, true - } - // make the (s, (start, end)) state explicit - newSt := newState(s.tree) - newSt.addTran(splitPoint, tr.end, tr.state) - tr.end = splitPoint - 1 - tr.state = newSt - return newSt, false - } - if s == t.auxState || s.findTran(c) != nil { - return s, true - } - return s, false -} - -// canonize returns updated state and start position for ref. pair -// (s, (start, end)) of state r so the new ref. pair is canonical, -// that is, referenced from the closest explicit ancestor of r. -func (t *STree) canonize(s *state, start, end Pos) (*state, Pos) { - if s == t.auxState { - s, start = t.root, start+1 - } - if start > end { - return s, start - } - - var tr *tran - for { - if start <= end { - tr = s.findTran(t.data[start]) - if tr == nil { - panic(fmt.Sprintf("there should be some transition for '%d' at %d", - t.data[start].Val(), start)) - } - } - if tr.end-tr.start > end-start { - break - } - start += tr.end - tr.start + 1 - s = tr.state - } - if s == nil { - panic("there should always be some suffix link resolution") - } - return s, start -} - -func (t *STree) At(p Pos) Token { - if p < 0 || p >= Pos(len(t.data)) { - panic("position out of bounds") - } - return t.data[p] -} - -func (t *STree) String() string { - buf := new(bytes.Buffer) - printState(buf, t.root, 0) - return buf.String() -} - -func printState(buf *bytes.Buffer, s *state, ident int) { - for _, tr := range s.trans { - fmt.Fprint(buf, strings.Repeat(" ", ident)) - fmt.Fprintf(buf, "* (%d, %d)\n", tr.start, tr.ActEnd()) - printState(buf, tr.state, ident+1) - } -} - -// state is an explicit state of the suffix tree. -type state struct { - tree *STree - trans []*tran - linkState *state -} - -func newState(t *STree) *state { - return &state{ - tree: t, - trans: make([]*tran, 0), - linkState: nil, - } -} - -func (s *state) addTran(start, end Pos, r *state) { - s.trans = append(s.trans, newTran(start, end, r)) -} - -// fork creates a new branch from the state s. -func (s *state) fork(i Pos) *state { - r := newState(s.tree) - s.addTran(i, infinity, r) - return r -} - -// findTran finds c-transition. -func (s *state) findTran(c Token) *tran { - for _, tran := range s.trans { - if s.tree.data[tran.start].Val() == c.Val() { - return tran - } - } - return nil -} - -// tran represents a state's transition. -type tran struct { - start, end Pos - state *state -} - -func newTran(start, end Pos, s *state) *tran { - return &tran{start, end, s} -} - -func (t *tran) len() int { - return int(t.end - t.start + 1) -} - -// ActEnd returns actual end position as consistent with -// the actual length of the data in the STree. -func (t *tran) ActEnd() Pos { - if t.end == infinity { - return Pos(len(t.state.tree.data)) - 1 - } - return t.end -} diff --git a/vendor/github.com/golangci/dupl/syntax/golang/golang.go b/vendor/github.com/golangci/dupl/syntax/golang/golang.go deleted file mode 100644 index a0b1e77e13..0000000000 --- a/vendor/github.com/golangci/dupl/syntax/golang/golang.go +++ /dev/null @@ -1,392 +0,0 @@ -package golang - -import ( - "go/ast" - "go/parser" - "go/token" - - "github.com/golangci/dupl/syntax" -) - -const ( - BadNode = iota - File - ArrayType - AssignStmt - BasicLit - BinaryExpr - BlockStmt - BranchStmt - CallExpr - CaseClause - ChanType - CommClause - CompositeLit - DeclStmt - DeferStmt - Ellipsis - EmptyStmt - ExprStmt - Field - FieldList - ForStmt - FuncDecl - FuncLit - FuncType - GenDecl - GoStmt - Ident - IfStmt - IncDecStmt - IndexExpr - InterfaceType - KeyValueExpr - LabeledStmt - MapType - ParenExpr - RangeStmt - ReturnStmt - SelectStmt - SelectorExpr - SendStmt - SliceExpr - StarExpr - StructType - SwitchStmt - TypeAssertExpr - TypeSpec - TypeSwitchStmt - UnaryExpr - ValueSpec -) - -// Parse the given file and return uniform syntax tree. -func Parse(filename string) (*syntax.Node, error) { - fset := token.NewFileSet() - file, err := parser.ParseFile(fset, filename, nil, 0) - if err != nil { - return nil, err - } - t := &transformer{ - fileset: fset, - filename: filename, - } - return t.trans(file), nil -} - -type transformer struct { - fileset *token.FileSet - filename string -} - -// trans transforms given golang AST to uniform tree structure. -func (t *transformer) trans(node ast.Node) (o *syntax.Node) { - o = syntax.NewNode() - o.Filename = t.filename - st, end := node.Pos(), node.End() - o.Pos, o.End = t.fileset.File(st).Offset(st), t.fileset.File(end).Offset(end) - - switch n := node.(type) { - case *ast.ArrayType: - o.Type = ArrayType - if n.Len != nil { - o.AddChildren(t.trans(n.Len)) - } - o.AddChildren(t.trans(n.Elt)) - - case *ast.AssignStmt: - o.Type = AssignStmt - for _, e := range n.Rhs { - o.AddChildren(t.trans(e)) - } - - for _, e := range n.Lhs { - o.AddChildren(t.trans(e)) - } - - case *ast.BasicLit: - o.Type = BasicLit - - case *ast.BinaryExpr: - o.Type = BinaryExpr - o.AddChildren(t.trans(n.X), t.trans(n.Y)) - - case *ast.BlockStmt: - o.Type = BlockStmt - for _, stmt := range n.List { - o.AddChildren(t.trans(stmt)) - } - - case *ast.BranchStmt: - o.Type = BranchStmt - if n.Label != nil { - o.AddChildren(t.trans(n.Label)) - } - - case *ast.CallExpr: - o.Type = CallExpr - o.AddChildren(t.trans(n.Fun)) - for _, arg := range n.Args { - o.AddChildren(t.trans(arg)) - } - - case *ast.CaseClause: - o.Type = CaseClause - for _, e := range n.List { - o.AddChildren(t.trans(e)) - } - for _, stmt := range n.Body { - o.AddChildren(t.trans(stmt)) - } - - case *ast.ChanType: - o.Type = ChanType - o.AddChildren(t.trans(n.Value)) - - case *ast.CommClause: - o.Type = CommClause - if n.Comm != nil { - o.AddChildren(t.trans(n.Comm)) - } - for _, stmt := range n.Body { - o.AddChildren(t.trans(stmt)) - } - - case *ast.CompositeLit: - o.Type = CompositeLit - if n.Type != nil { - o.AddChildren(t.trans(n.Type)) - } - for _, e := range n.Elts { - o.AddChildren(t.trans(e)) - } - - case *ast.DeclStmt: - o.Type = DeclStmt - o.AddChildren(t.trans(n.Decl)) - - case *ast.DeferStmt: - o.Type = DeferStmt - o.AddChildren(t.trans(n.Call)) - - case *ast.Ellipsis: - o.Type = Ellipsis - if n.Elt != nil { - o.AddChildren(t.trans(n.Elt)) - } - - case *ast.EmptyStmt: - o.Type = EmptyStmt - - case *ast.ExprStmt: - o.Type = ExprStmt - o.AddChildren(t.trans(n.X)) - - case *ast.Field: - o.Type = Field - for _, name := range n.Names { - o.AddChildren(t.trans(name)) - } - o.AddChildren(t.trans(n.Type)) - - case *ast.FieldList: - o.Type = FieldList - for _, field := range n.List { - o.AddChildren(t.trans(field)) - } - - case *ast.File: - o.Type = File - for _, decl := range n.Decls { - if genDecl, ok := decl.(*ast.GenDecl); ok && genDecl.Tok == token.IMPORT { - // skip import declarations - continue - } - o.AddChildren(t.trans(decl)) - } - - case *ast.ForStmt: - o.Type = ForStmt - if n.Init != nil { - o.AddChildren(t.trans(n.Init)) - } - if n.Cond != nil { - o.AddChildren(t.trans(n.Cond)) - } - if n.Post != nil { - o.AddChildren(t.trans(n.Post)) - } - o.AddChildren(t.trans(n.Body)) - - case *ast.FuncDecl: - o.Type = FuncDecl - if n.Recv != nil { - o.AddChildren(t.trans(n.Recv)) - } - o.AddChildren(t.trans(n.Name), t.trans(n.Type)) - if n.Body != nil { - o.AddChildren(t.trans(n.Body)) - } - - case *ast.FuncLit: - o.Type = FuncLit - o.AddChildren(t.trans(n.Type), t.trans(n.Body)) - - case *ast.FuncType: - o.Type = FuncType - o.AddChildren(t.trans(n.Params)) - if n.Results != nil { - o.AddChildren(t.trans(n.Results)) - } - - case *ast.GenDecl: - o.Type = GenDecl - for _, spec := range n.Specs { - o.AddChildren(t.trans(spec)) - } - - case *ast.GoStmt: - o.Type = GoStmt - o.AddChildren(t.trans(n.Call)) - - case *ast.Ident: - o.Type = Ident - - case *ast.IfStmt: - o.Type = IfStmt - if n.Init != nil { - o.AddChildren(t.trans(n.Init)) - } - o.AddChildren(t.trans(n.Cond), t.trans(n.Body)) - if n.Else != nil { - o.AddChildren(t.trans(n.Else)) - } - - case *ast.IncDecStmt: - o.Type = IncDecStmt - o.AddChildren(t.trans(n.X)) - - case *ast.IndexExpr: - o.Type = IndexExpr - o.AddChildren(t.trans(n.X), t.trans(n.Index)) - - case *ast.InterfaceType: - o.Type = InterfaceType - o.AddChildren(t.trans(n.Methods)) - - case *ast.KeyValueExpr: - o.Type = KeyValueExpr - o.AddChildren(t.trans(n.Key), t.trans(n.Value)) - - case *ast.LabeledStmt: - o.Type = LabeledStmt - o.AddChildren(t.trans(n.Label), t.trans(n.Stmt)) - - case *ast.MapType: - o.Type = MapType - o.AddChildren(t.trans(n.Key), t.trans(n.Value)) - - case *ast.ParenExpr: - o.Type = ParenExpr - o.AddChildren(t.trans(n.X)) - - case *ast.RangeStmt: - o.Type = RangeStmt - if n.Key != nil { - o.AddChildren(t.trans(n.Key)) - } - if n.Value != nil { - o.AddChildren(t.trans(n.Value)) - } - o.AddChildren(t.trans(n.X), t.trans(n.Body)) - - case *ast.ReturnStmt: - o.Type = ReturnStmt - for _, e := range n.Results { - o.AddChildren(t.trans(e)) - } - - case *ast.SelectStmt: - o.Type = SelectStmt - o.AddChildren(t.trans(n.Body)) - - case *ast.SelectorExpr: - o.Type = SelectorExpr - o.AddChildren(t.trans(n.X), t.trans(n.Sel)) - - case *ast.SendStmt: - o.Type = SendStmt - o.AddChildren(t.trans(n.Chan), t.trans(n.Value)) - - case *ast.SliceExpr: - o.Type = SliceExpr - o.AddChildren(t.trans(n.X)) - if n.Low != nil { - o.AddChildren(t.trans(n.Low)) - } - if n.High != nil { - o.AddChildren(t.trans(n.High)) - } - if n.Max != nil { - o.AddChildren(t.trans(n.Max)) - } - - case *ast.StarExpr: - o.Type = StarExpr - o.AddChildren(t.trans(n.X)) - - case *ast.StructType: - o.Type = StructType - o.AddChildren(t.trans(n.Fields)) - - case *ast.SwitchStmt: - o.Type = SwitchStmt - if n.Init != nil { - o.AddChildren(t.trans(n.Init)) - } - if n.Tag != nil { - o.AddChildren(t.trans(n.Tag)) - } - o.AddChildren(t.trans(n.Body)) - - case *ast.TypeAssertExpr: - o.Type = TypeAssertExpr - o.AddChildren(t.trans(n.X)) - if n.Type != nil { - o.AddChildren(t.trans(n.Type)) - } - - case *ast.TypeSpec: - o.Type = TypeSpec - o.AddChildren(t.trans(n.Name), t.trans(n.Type)) - - case *ast.TypeSwitchStmt: - o.Type = TypeSwitchStmt - if n.Init != nil { - o.AddChildren(t.trans(n.Init)) - } - o.AddChildren(t.trans(n.Assign), t.trans(n.Body)) - - case *ast.UnaryExpr: - o.Type = UnaryExpr - o.AddChildren(t.trans(n.X)) - - case *ast.ValueSpec: - o.Type = ValueSpec - for _, name := range n.Names { - o.AddChildren(t.trans(name)) - } - if n.Type != nil { - o.AddChildren(t.trans(n.Type)) - } - for _, val := range n.Values { - o.AddChildren(t.trans(val)) - } - - default: - o.Type = BadNode - - } - - return o -} diff --git a/vendor/github.com/golangci/dupl/syntax/syntax.go b/vendor/github.com/golangci/dupl/syntax/syntax.go deleted file mode 100644 index 9b11d3119b..0000000000 --- a/vendor/github.com/golangci/dupl/syntax/syntax.go +++ /dev/null @@ -1,193 +0,0 @@ -package syntax - -import ( - "crypto/sha1" - - "github.com/golangci/dupl/suffixtree" -) - -// To avoid "goroutine stack exceeds" with gigantic slices (Composite Literals). -// 10_000 => 0.89s -// 20_000 => 1.53s -// 30_000 => 2.57s -// 40_000 => 3.89s -// 50_000 => 5.58s -// 60_000 => 7.95s -// 70_000 => 10.15s -// 80_000 => 13.11s -// 90_000 => 16.62s -// 100_000 => 21.42s -const maxChildrenSerial = 10_000 - -type Node struct { - Type int - Filename string - Pos, End int - Children []*Node - Owns int -} - -func NewNode() *Node { - return &Node{} -} - -func (n *Node) AddChildren(children ...*Node) { - n.Children = append(n.Children, children...) -} - -func (n *Node) Val() int { - return n.Type -} - -type Match struct { - Hash string - Frags [][]*Node -} - -func Serialize(n *Node) []*Node { - stream := make([]*Node, 0, 10) - serial(n, &stream) - return stream -} - -func serial(n *Node, stream *[]*Node) int { - *stream = append(*stream, n) - var count int - for i, child := range n.Children { - // To avoid "goroutine stack exceeds" with gigantic slices (Composite Literals). - if i > maxChildrenSerial { - break - } - - count += serial(child, stream) - } - n.Owns = count - return count + 1 -} - -// FindSyntaxUnits finds all complete syntax units in the match group and returns them -// with the corresponding hash. -func FindSyntaxUnits(data []*Node, m suffixtree.Match, threshold int) Match { - if len(m.Ps) == 0 { - return Match{} - } - firstSeq := data[m.Ps[0] : m.Ps[0]+m.Len] - indexes := getUnitsIndexes(firstSeq, threshold) - - // TODO: is this really working? - indexCnt := len(indexes) - if indexCnt > 0 { - lasti := indexes[indexCnt-1] - firstn := firstSeq[lasti] - for i := 1; i < len(m.Ps); i++ { - n := data[int(m.Ps[i])+lasti] - if firstn.Owns != n.Owns { - indexes = indexes[:indexCnt-1] - break - } - } - } - if len(indexes) == 0 || isCyclic(indexes, firstSeq) || spansMultipleFiles(indexes, firstSeq) { - return Match{} - } - - match := Match{Frags: make([][]*Node, len(m.Ps))} - for i, pos := range m.Ps { - match.Frags[i] = make([]*Node, len(indexes)) - for j, index := range indexes { - match.Frags[i][j] = data[int(pos)+index] - } - } - - lastIndex := indexes[len(indexes)-1] - match.Hash = hashSeq(firstSeq[indexes[0] : lastIndex+firstSeq[lastIndex].Owns]) - return match -} - -func getUnitsIndexes(nodeSeq []*Node, threshold int) []int { - var indexes []int - var split bool - for i := 0; i < len(nodeSeq); { - n := nodeSeq[i] - switch { - case n.Owns >= len(nodeSeq)-i: - // not complete syntax unit - i++ - split = true - continue - case n.Owns+1 < threshold: - split = true - default: - if split { - indexes = indexes[:0] - split = false - } - indexes = append(indexes, i) - } - i += n.Owns + 1 - } - return indexes -} - -// isCyclic finds out whether there is a repetive pattern in the found clone. If positive, -// it return false to point out that the clone would be redundant. -func isCyclic(indexes []int, nodes []*Node) bool { - cnt := len(indexes) - if cnt <= 1 { - return false - } - - alts := make(map[int]bool) - for i := 1; i <= cnt/2; i++ { - if cnt%i == 0 { - alts[i] = true - } - } - - for i := 0; i < indexes[cnt/2]; i++ { - nstart := nodes[i+indexes[0]] - AltLoop: - for alt := range alts { - for j := alt; j < cnt; j += alt { - index := i + indexes[j] - if index < len(nodes) { - nalt := nodes[index] - if nstart.Owns == nalt.Owns && nstart.Type == nalt.Type { - continue - } - } else if i >= indexes[alt] { - return true - } - delete(alts, alt) - continue AltLoop - } - } - if len(alts) == 0 { - return false - } - } - return true -} - -func spansMultipleFiles(indexes []int, nodes []*Node) bool { - if len(indexes) < 2 { - return false - } - f := nodes[indexes[0]].Filename - for i := 1; i < len(indexes); i++ { - if nodes[indexes[i]].Filename != f { - return true - } - } - return false -} - -func hashSeq(nodes []*Node) string { - h := sha1.New() - bytes := make([]byte, len(nodes)) - for i, node := range nodes { - bytes[i] = byte(node.Type) - } - h.Write(bytes) - return string(h.Sum(nil)) -} diff --git a/vendor/github.com/golangci/go-printf-func-name/LICENSE b/vendor/github.com/golangci/go-printf-func-name/LICENSE deleted file mode 100644 index 4585140d18..0000000000 --- a/vendor/github.com/golangci/go-printf-func-name/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -MIT License - -Copyright (c) 2024 Golangci-lint authors -Copyright (c) 2020 Isaev Denis - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/golangci/go-printf-func-name/pkg/analyzer/analyzer.go b/vendor/github.com/golangci/go-printf-func-name/pkg/analyzer/analyzer.go deleted file mode 100644 index 0b41500f24..0000000000 --- a/vendor/github.com/golangci/go-printf-func-name/pkg/analyzer/analyzer.go +++ /dev/null @@ -1,90 +0,0 @@ -package analyzer - -import ( - "go/ast" - "strings" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/inspector" -) - -var Analyzer = &analysis.Analyzer{ - Name: "goprintffuncname", - Doc: "Checks that printf-like functions are named with `f` at the end.", - Run: run, - Requires: []*analysis.Analyzer{inspect.Analyzer}, -} - -func run(pass *analysis.Pass) (any, error) { - insp := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - - nodeFilter := []ast.Node{ - (*ast.FuncDecl)(nil), - } - - insp.Preorder(nodeFilter, func(node ast.Node) { - funcDecl := node.(*ast.FuncDecl) - - if res := funcDecl.Type.Results; res != nil && len(res.List) != 0 { - return - } - - params := funcDecl.Type.Params.List - if len(params) < 2 { // [0] must be format (string), [1] must be args (...interface{}) - return - } - - formatParamType, ok := params[len(params)-2].Type.(*ast.Ident) - if !ok { // first param type isn't identificator so it can't be of type "string" - return - } - - if formatParamType.Name != "string" { // first param (format) type is not string - return - } - - formatParamNames := params[len(params)-2].Names - if len(formatParamNames) == 0 || formatParamNames[len(formatParamNames)-1].Name != "format" { - return - } - - argsParamType, ok := params[len(params)-1].Type.(*ast.Ellipsis) - if !ok { - // args are not ellipsis (...args) - return - } - - if !isAny(argsParamType) { - return - } - - if strings.HasSuffix(funcDecl.Name.Name, "f") { - return - } - - pass.Reportf(node.Pos(), "printf-like formatting function '%s' should be named '%sf'", - funcDecl.Name.Name, funcDecl.Name.Name) - }) - - return nil, nil -} - -func isAny(ell *ast.Ellipsis) bool { - switch elt := ell.Elt.(type) { - case *ast.InterfaceType: - if elt.Methods != nil && len(elt.Methods.List) != 0 { - // has >= 1 method in interface, but we need an empty interface "interface{}" - return false - } - - return true - - case *ast.Ident: - if elt.Name == "any" { - return true - } - } - - return false -} diff --git a/vendor/github.com/golangci/gofmt/gofmt/LICENSE b/vendor/github.com/golangci/gofmt/gofmt/LICENSE deleted file mode 100644 index 6a66aea5ea..0000000000 --- a/vendor/github.com/golangci/gofmt/gofmt/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/golangci/gofmt/gofmt/doc.go b/vendor/github.com/golangci/gofmt/gofmt/doc.go deleted file mode 100644 index d0a4580219..0000000000 --- a/vendor/github.com/golangci/gofmt/gofmt/doc.go +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -/* -Gofmt formats Go programs. -It uses tabs for indentation and blanks for alignment. -Alignment assumes that an editor is using a fixed-width font. - -Without an explicit path, it processes the standard input. Given a file, -it operates on that file; given a directory, it operates on all .go files in -that directory, recursively. (Files starting with a period are ignored.) -By default, gofmt prints the reformatted sources to standard output. - -Usage: - - gofmt [flags] [path ...] - -The flags are: - - -d - Do not print reformatted sources to standard output. - If a file's formatting is different than gofmt's, print diffs - to standard output. - -e - Print all (including spurious) errors. - -l - Do not print reformatted sources to standard output. - If a file's formatting is different from gofmt's, print its name - to standard output. - -r rule - Apply the rewrite rule to the source before reformatting. - -s - Try to simplify code (after applying the rewrite rule, if any). - -w - Do not print reformatted sources to standard output. - If a file's formatting is different from gofmt's, overwrite it - with gofmt's version. If an error occurred during overwriting, - the original file is restored from an automatic backup. - -Debugging support: - - -cpuprofile filename - Write cpu profile to the specified file. - -The rewrite rule specified with the -r flag must be a string of the form: - - pattern -> replacement - -Both pattern and replacement must be valid Go expressions. -In the pattern, single-character lowercase identifiers serve as -wildcards matching arbitrary sub-expressions; those expressions -will be substituted for the same identifiers in the replacement. - -When gofmt reads from standard input, it accepts either a full Go program -or a program fragment. A program fragment must be a syntactically -valid declaration list, statement list, or expression. When formatting -such a fragment, gofmt preserves leading indentation as well as leading -and trailing spaces, so that individual sections of a Go program can be -formatted by piping them through gofmt. - -# Examples - -To check files for unnecessary parentheses: - - gofmt -r '(a) -> a' -l *.go - -To remove the parentheses: - - gofmt -r '(a) -> a' -w *.go - -To convert the package tree from explicit slice upper bounds to implicit ones: - - gofmt -r 'α[β:len(α)] -> α[β:]' -w $GOROOT/src - -# The simplify command - -When invoked with -s gofmt will make the following source transformations where possible. - - An array, slice, or map composite literal of the form: - []T{T{}, T{}} - will be simplified to: - []T{{}, {}} - - A slice expression of the form: - s[a:len(s)] - will be simplified to: - s[a:] - - A range of the form: - for x, _ = range v {...} - will be simplified to: - for x = range v {...} - - A range of the form: - for _ = range v {...} - will be simplified to: - for range v {...} - -This may result in changes that are incompatible with earlier versions of Go. -*/ -package gofmt - -// BUG(rsc): The implementation of -r is a bit slow. -// BUG(gri): If -w fails, the restored original file may not have some of the -// original file attributes. diff --git a/vendor/github.com/golangci/gofmt/gofmt/gofmt.go b/vendor/github.com/golangci/gofmt/gofmt/gofmt.go deleted file mode 100644 index a4f252e86d..0000000000 --- a/vendor/github.com/golangci/gofmt/gofmt/gofmt.go +++ /dev/null @@ -1,570 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package gofmt - -import ( - "bytes" - "context" - "flag" - "fmt" - "go/ast" - "go/parser" - "go/printer" - "go/scanner" - "go/token" - "io" - "io/fs" - "math/rand" - "os" - "path/filepath" - "runtime" - "runtime/pprof" - "strconv" - "strings" - - "github.com/rogpeppe/go-internal/diff" - "golang.org/x/sync/semaphore" -) - -var ( - // main operation modes - list = flag.Bool("gofmt.l", false, "list files whose formatting differs from gofmt's") - write = flag.Bool("gofmt.w", false, "write result to (source) file instead of stdout") - rewriteRule = flag.String("gofmt.r", "", "rewrite rule (e.g., 'a[b:len(a)] -> a[b:]')") - simplifyAST = flag.Bool("gofmt.s", false, "simplify code") - doDiff = flag.Bool("gofmt.d", false, "display diffs instead of rewriting files") - allErrors = flag.Bool("gofmt.e", false, "report all errors (not just the first 10 on different lines)") - - // debugging - cpuprofile = flag.String("gofmt.cpuprofile", "", "write cpu profile to this file") -) - -// Keep these in sync with go/format/format.go. -const ( - tabWidth = 8 - printerMode = printer.UseSpaces | printer.TabIndent | printerNormalizeNumbers - - // printerNormalizeNumbers means to canonicalize number literal prefixes - // and exponents while printing. See https://golang.org/doc/go1.13#gofmt. - // - // This value is defined in go/printer specifically for go/format and cmd/gofmt. - printerNormalizeNumbers = 1 << 30 -) - -// fdSem guards the number of concurrently-open file descriptors. -// -// For now, this is arbitrarily set to 200, based on the observation that many -// platforms default to a kernel limit of 256. Ideally, perhaps we should derive -// it from rlimit on platforms that support that system call. -// -// File descriptors opened from outside of this package are not tracked, -// so this limit may be approximate. -var fdSem = make(chan bool, 200) - -var ( - rewrite func(*token.FileSet, *ast.File) *ast.File - parserMode parser.Mode -) - -func usage() { - fmt.Fprintf(os.Stderr, "usage: gofmt [flags] [path ...]\n") - flag.PrintDefaults() -} - -func initParserMode() { - parserMode = parser.ParseComments - if *allErrors { - parserMode |= parser.AllErrors - } - // It's only -r that makes use of go/ast's object resolution, - // so avoid the unnecessary work if the flag isn't used. - if *rewriteRule == "" { - parserMode |= parser.SkipObjectResolution - } -} - -func isGoFile(f fs.DirEntry) bool { - // ignore non-Go files - name := f.Name() - return !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go") && !f.IsDir() -} - -// A sequencer performs concurrent tasks that may write output, but emits that -// output in a deterministic order. -type sequencer struct { - maxWeight int64 - sem *semaphore.Weighted // weighted by input bytes (an approximate proxy for memory overhead) - prev <-chan *reporterState // 1-buffered -} - -// newSequencer returns a sequencer that allows concurrent tasks up to maxWeight -// and writes tasks' output to out and err. -func newSequencer(maxWeight int64, out, err io.Writer) *sequencer { - sem := semaphore.NewWeighted(maxWeight) - prev := make(chan *reporterState, 1) - prev <- &reporterState{out: out, err: err} - return &sequencer{ - maxWeight: maxWeight, - sem: sem, - prev: prev, - } -} - -// exclusive is a weight that can be passed to a sequencer to cause -// a task to be executed without any other concurrent tasks. -const exclusive = -1 - -// Add blocks until the sequencer has enough weight to spare, then adds f as a -// task to be executed concurrently. -// -// If the weight is either negative or larger than the sequencer's maximum -// weight, Add blocks until all other tasks have completed, then the task -// executes exclusively (blocking all other calls to Add until it completes). -// -// f may run concurrently in a goroutine, but its output to the passed-in -// reporter will be sequential relative to the other tasks in the sequencer. -// -// If f invokes a method on the reporter, execution of that method may block -// until the previous task has finished. (To maximize concurrency, f should -// avoid invoking the reporter until it has finished any parallelizable work.) -// -// If f returns a non-nil error, that error will be reported after f's output -// (if any) and will cause a nonzero final exit code. -func (s *sequencer) Add(weight int64, f func(*reporter) error) { - if weight < 0 || weight > s.maxWeight { - weight = s.maxWeight - } - if err := s.sem.Acquire(context.TODO(), weight); err != nil { - // Change the task from "execute f" to "report err". - weight = 0 - f = func(*reporter) error { return err } - } - - r := &reporter{prev: s.prev} - next := make(chan *reporterState, 1) - s.prev = next - - // Start f in parallel: it can run until it invokes a method on r, at which - // point it will block until the previous task releases the output state. - go func() { - if err := f(r); err != nil { - r.Report(err) - } - next <- r.getState() // Release the next task. - s.sem.Release(weight) - }() -} - -// AddReport prints an error to s after the output of any previously-added -// tasks, causing the final exit code to be nonzero. -func (s *sequencer) AddReport(err error) { - s.Add(0, func(*reporter) error { return err }) -} - -// GetExitCode waits for all previously-added tasks to complete, then returns an -// exit code for the sequence suitable for passing to os.Exit. -func (s *sequencer) GetExitCode() int { - c := make(chan int, 1) - s.Add(0, func(r *reporter) error { - c <- r.ExitCode() - return nil - }) - return <-c -} - -// A reporter reports output, warnings, and errors. -type reporter struct { - prev <-chan *reporterState - state *reporterState -} - -// reporterState carries the state of a reporter instance. -// -// Only one reporter at a time may have access to a reporterState. -type reporterState struct { - out, err io.Writer - exitCode int -} - -// getState blocks until any prior reporters are finished with the reporter -// state, then returns the state for manipulation. -func (r *reporter) getState() *reporterState { - if r.state == nil { - r.state = <-r.prev - } - return r.state -} - -// Warnf emits a warning message to the reporter's error stream, -// without changing its exit code. -func (r *reporter) Warnf(format string, args ...any) { - fmt.Fprintf(r.getState().err, format, args...) -} - -// Write emits a slice to the reporter's output stream. -// -// Any error is returned to the caller, and does not otherwise affect the -// reporter's exit code. -func (r *reporter) Write(p []byte) (int, error) { - return r.getState().out.Write(p) -} - -// Report emits a non-nil error to the reporter's error stream, -// changing its exit code to a nonzero value. -func (r *reporter) Report(err error) { - if err == nil { - panic("Report with nil error") - } - st := r.getState() - scanner.PrintError(st.err, err) - st.exitCode = 2 -} - -func (r *reporter) ExitCode() int { - return r.getState().exitCode -} - -// If info == nil, we are formatting stdin instead of a file. -// If in == nil, the source is the contents of the file with the given filename. -func processFile(filename string, info fs.FileInfo, in io.Reader, r *reporter) error { - src, err := readFile(filename, info, in) - if err != nil { - return err - } - - fileSet := token.NewFileSet() - // If we are formatting stdin, we accept a program fragment in lieu of a - // complete source file. - fragmentOk := info == nil - file, sourceAdj, indentAdj, err := parse(fileSet, filename, src, fragmentOk) - if err != nil { - return err - } - - if rewrite != nil { - if sourceAdj == nil { - file = rewrite(fileSet, file) - } else { - r.Warnf("warning: rewrite ignored for incomplete programs\n") - } - } - - ast.SortImports(fileSet, file) - - if *simplifyAST { - simplify(file) - } - - res, err := format(fileSet, file, sourceAdj, indentAdj, src, printer.Config{Mode: printerMode, Tabwidth: tabWidth}) - if err != nil { - return err - } - - if !bytes.Equal(src, res) { - // formatting has changed - if *list { - fmt.Fprintln(r, filename) - } - if *write { - if info == nil { - panic("-w should not have been allowed with stdin") - } - - perm := info.Mode().Perm() - if err := writeFile(filename, src, res, perm, info.Size()); err != nil { - return err - } - } - if *doDiff { - newName := filepath.ToSlash(filename) - oldName := newName + ".orig" - r.Write(diff.Diff(oldName, src, newName, res)) - } - } - - if !*list && !*write && !*doDiff { - _, err = r.Write(res) - } - - return err -} - -// readFile reads the contents of filename, described by info. -// If in is non-nil, readFile reads directly from it. -// Otherwise, readFile opens and reads the file itself, -// with the number of concurrently-open files limited by fdSem. -func readFile(filename string, info fs.FileInfo, in io.Reader) ([]byte, error) { - if in == nil { - fdSem <- true - var err error - f, err := os.Open(filename) - if err != nil { - return nil, err - } - in = f - defer func() { - f.Close() - <-fdSem - }() - } - - // Compute the file's size and read its contents with minimal allocations. - // - // If we have the FileInfo from filepath.WalkDir, use it to make - // a buffer of the right size and avoid ReadAll's reallocations. - // - // If the size is unknown (or bogus, or overflows an int), fall back to - // a size-independent ReadAll. - size := -1 - if info != nil && info.Mode().IsRegular() && int64(int(info.Size())) == info.Size() { - size = int(info.Size()) - } - if size+1 <= 0 { - // The file is not known to be regular, so we don't have a reliable size for it. - var err error - src, err := io.ReadAll(in) - if err != nil { - return nil, err - } - return src, nil - } - - // We try to read size+1 bytes so that we can detect modifications: if we - // read more than size bytes, then the file was modified concurrently. - // (If that happens, we could, say, append to src to finish the read, or - // proceed with a truncated buffer — but the fact that it changed at all - // indicates a possible race with someone editing the file, so we prefer to - // stop to avoid corrupting it.) - src := make([]byte, size+1) - n, err := io.ReadFull(in, src) - switch err { - case nil, io.EOF, io.ErrUnexpectedEOF: - // io.ReadFull returns io.EOF (for an empty file) or io.ErrUnexpectedEOF - // (for a non-empty file) if the file was changed unexpectedly. Continue - // with comparing file sizes in those cases. - default: - return nil, err - } - if n < size { - return nil, fmt.Errorf("error: size of %s changed during reading (from %d to %d bytes)", filename, size, n) - } else if n > size { - return nil, fmt.Errorf("error: size of %s changed during reading (from %d to >=%d bytes)", filename, size, len(src)) - } - return src[:n], nil -} - -func main() { - // Arbitrarily limit in-flight work to 2MiB times the number of threads. - // - // The actual overhead for the parse tree and output will depend on the - // specifics of the file, but this at least keeps the footprint of the process - // roughly proportional to GOMAXPROCS. - maxWeight := (2 << 20) * int64(runtime.GOMAXPROCS(0)) - s := newSequencer(maxWeight, os.Stdout, os.Stderr) - - // call gofmtMain in a separate function - // so that it can use defer and have them - // run before the exit. - gofmtMain(s) - os.Exit(s.GetExitCode()) -} - -func gofmtMain(s *sequencer) { - flag.Usage = usage - flag.Parse() - - if *cpuprofile != "" { - fdSem <- true - f, err := os.Create(*cpuprofile) - if err != nil { - s.AddReport(fmt.Errorf("creating cpu profile: %s", err)) - return - } - defer func() { - f.Close() - <-fdSem - }() - pprof.StartCPUProfile(f) - defer pprof.StopCPUProfile() - } - - initParserMode() - initRewrite() - - args := flag.Args() - if len(args) == 0 { - if *write { - s.AddReport(fmt.Errorf("error: cannot use -w with standard input")) - return - } - s.Add(0, func(r *reporter) error { - return processFile("", nil, os.Stdin, r) - }) - return - } - - for _, arg := range args { - switch info, err := os.Stat(arg); { - case err != nil: - s.AddReport(err) - case !info.IsDir(): - // Non-directory arguments are always formatted. - arg := arg - s.Add(fileWeight(arg, info), func(r *reporter) error { - return processFile(arg, info, nil, r) - }) - default: - // Directories are walked, ignoring non-Go files. - err := filepath.WalkDir(arg, func(path string, f fs.DirEntry, err error) error { - if err != nil || !isGoFile(f) { - return err - } - info, err := f.Info() - if err != nil { - s.AddReport(err) - return nil - } - s.Add(fileWeight(path, info), func(r *reporter) error { - return processFile(path, info, nil, r) - }) - return nil - }) - if err != nil { - s.AddReport(err) - } - } - } -} - -func fileWeight(path string, info fs.FileInfo) int64 { - if info == nil { - return exclusive - } - if info.Mode().Type() == fs.ModeSymlink { - var err error - info, err = os.Stat(path) - if err != nil { - return exclusive - } - } - if !info.Mode().IsRegular() { - // For non-regular files, FileInfo.Size is system-dependent and thus not a - // reliable indicator of weight. - return exclusive - } - return info.Size() -} - -// writeFile updates a file with the new formatted data. -func writeFile(filename string, orig, formatted []byte, perm fs.FileMode, size int64) error { - // Make a temporary backup file before rewriting the original file. - bakname, err := backupFile(filename, orig, perm) - if err != nil { - return err - } - - fdSem <- true - defer func() { <-fdSem }() - - fout, err := os.OpenFile(filename, os.O_WRONLY, perm) - if err != nil { - // We couldn't even open the file, so it should - // not have changed. - os.Remove(bakname) - return err - } - defer fout.Close() // for error paths - - restoreFail := func(err error) { - fmt.Fprintf(os.Stderr, "gofmt: %s: error restoring file to original: %v; backup in %s\n", filename, err, bakname) - } - - n, err := fout.Write(formatted) - if err == nil && int64(n) < size { - err = fout.Truncate(int64(n)) - } - - if err != nil { - // Rewriting the file failed. - - if n == 0 { - // Original file unchanged. - os.Remove(bakname) - return err - } - - // Try to restore the original contents. - - no, erro := fout.WriteAt(orig, 0) - if erro != nil { - // That failed too. - restoreFail(erro) - return err - } - - if no < n { - // Original file is shorter. Truncate. - if erro = fout.Truncate(int64(no)); erro != nil { - restoreFail(erro) - return err - } - } - - if erro := fout.Close(); erro != nil { - restoreFail(erro) - return err - } - - // Original contents restored. - os.Remove(bakname) - return err - } - - if err := fout.Close(); err != nil { - restoreFail(err) - return err - } - - // File updated. - os.Remove(bakname) - return nil -} - -// backupFile writes data to a new file named filename with permissions perm, -// with randomly chosen such that the file name is unique. backupFile returns -// the chosen file name. -func backupFile(filename string, data []byte, perm fs.FileMode) (string, error) { - fdSem <- true - defer func() { <-fdSem }() - - nextRandom := func() string { - return strconv.Itoa(rand.Int()) - } - - dir, base := filepath.Split(filename) - var ( - bakname string - f *os.File - ) - for { - bakname = filepath.Join(dir, base+"."+nextRandom()) - var err error - f, err = os.OpenFile(bakname, os.O_RDWR|os.O_CREATE|os.O_EXCL, perm) - if err == nil { - break - } - if err != nil && !os.IsExist(err) { - return "", err - } - } - - // write data to backup file - _, err := f.Write(data) - if err1 := f.Close(); err == nil { - err = err1 - } - - return bakname, err -} diff --git a/vendor/github.com/golangci/gofmt/gofmt/golangci.go b/vendor/github.com/golangci/gofmt/gofmt/golangci.go deleted file mode 100644 index a7f3ef6e73..0000000000 --- a/vendor/github.com/golangci/gofmt/gofmt/golangci.go +++ /dev/null @@ -1,133 +0,0 @@ -package gofmt - -import ( - "bytes" - "fmt" - "go/ast" - "go/parser" - "go/printer" - "go/token" - "os" - "path/filepath" - "sync" - - "github.com/rogpeppe/go-internal/diff" -) - -type Options struct { - NeedSimplify bool - RewriteRules []RewriteRule -} - -var parserModeMu sync.RWMutex - -type RewriteRule struct { - Pattern string - Replacement string -} - -// Run runs gofmt. -// Deprecated: use [Source] instead. -func Run(filename string, needSimplify bool) ([]byte, error) { - return RunRewrite(filename, needSimplify, nil) -} - -// RunRewrite runs gofmt. -// Deprecated: use [Source] instead. -func RunRewrite(filename string, needSimplify bool, rewriteRules []RewriteRule) ([]byte, error) { - src, err := os.ReadFile(filename) - if err != nil { - return nil, err - } - - fset := token.NewFileSet() - - parserModeMu.Lock() - initParserMode() - parserModeMu.Unlock() - - file, sourceAdj, indentAdj, err := parse(fset, filename, src, false) - if err != nil { - return nil, err - } - - file, err = rewriteFileContent(fset, file, rewriteRules) - if err != nil { - return nil, err - } - - ast.SortImports(fset, file) - - if needSimplify { - simplify(file) - } - - res, err := format(fset, file, sourceAdj, indentAdj, src, printer.Config{Mode: printerMode, Tabwidth: tabWidth}) - if err != nil { - return nil, err - } - - if bytes.Equal(src, res) { - return nil, nil - } - - // formatting has changed - newName := filepath.ToSlash(filename) - oldName := newName + ".orig" - - return diff.Diff(oldName, src, newName, res), nil -} - -// Source formats the code like gofmt. -// Empty string `rewrite` will be ignored. -func Source(filename string, src []byte, opts Options) ([]byte, error) { - fset := token.NewFileSet() - - parserModeMu.Lock() - initParserMode() - parserModeMu.Unlock() - - file, sourceAdj, indentAdj, err := parse(fset, filename, src, false) - if err != nil { - return nil, err - } - - file, err = rewriteFileContent(fset, file, opts.RewriteRules) - if err != nil { - return nil, err - } - - ast.SortImports(fset, file) - - if opts.NeedSimplify { - simplify(file) - } - - return format(fset, file, sourceAdj, indentAdj, src, printer.Config{Mode: printerMode, Tabwidth: tabWidth}) -} - -func rewriteFileContent(fset *token.FileSet, file *ast.File, rewriteRules []RewriteRule) (*ast.File, error) { - for _, rewriteRule := range rewriteRules { - pattern, err := parseExpression(rewriteRule.Pattern, "pattern") - if err != nil { - return nil, err - } - - replacement, err := parseExpression(rewriteRule.Replacement, "replacement") - if err != nil { - return nil, err - } - - file = rewriteFile(fset, pattern, replacement, file) - } - - return file, nil -} - -func parseExpression(s, what string) (ast.Expr, error) { - x, err := parser.ParseExpr(s) - if err != nil { - return nil, fmt.Errorf("parsing %s %q at %s\n", what, s, err) - } - return x, nil -} diff --git a/vendor/github.com/golangci/gofmt/gofmt/internal.go b/vendor/github.com/golangci/gofmt/gofmt/internal.go deleted file mode 100644 index 231a250915..0000000000 --- a/vendor/github.com/golangci/gofmt/gofmt/internal.go +++ /dev/null @@ -1,183 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// TODO(gri): This file and the file src/go/format/internal.go are -// the same (but for this comment and the package name). Do not modify -// one without the other. Determine if we can factor out functionality -// in a public API. See also #11844 for context. - -package gofmt - -import ( - "bytes" - "go/ast" - "go/parser" - "go/printer" - "go/token" - "strings" -) - -// parse parses src, which was read from the named file, -// as a Go source file, declaration, or statement list. -func parse(fset *token.FileSet, filename string, src []byte, fragmentOk bool) ( - file *ast.File, - sourceAdj func(src []byte, indent int) []byte, - indentAdj int, - err error, -) { - - // START - Change related to usage inside golangci-lint - parserModeMu.Lock() - parserMode := parserMode - parserModeMu.Unlock() - // END - Change related to usage inside golangci-lint - - // Try as whole source file. - file, err = parser.ParseFile(fset, filename, src, parserMode) - // If there's no error, return. If the error is that the source file didn't begin with a - // package line and source fragments are ok, fall through to - // try as a source fragment. Stop and return on any other error. - if err == nil || !fragmentOk || !strings.Contains(err.Error(), "expected 'package'") { - return - } - - // If this is a declaration list, make it a source file - // by inserting a package clause. - // Insert using a ';', not a newline, so that the line numbers - // in psrc match the ones in src. - psrc := append([]byte("package p;"), src...) - file, err = parser.ParseFile(fset, filename, psrc, parserMode) - if err == nil { - sourceAdj = func(src []byte, indent int) []byte { - // Remove the package clause. - // Gofmt has turned the ';' into a '\n'. - src = src[indent+len("package p\n"):] - return bytes.TrimSpace(src) - } - return - } - // If the error is that the source file didn't begin with a - // declaration, fall through to try as a statement list. - // Stop and return on any other error. - if !strings.Contains(err.Error(), "expected declaration") { - return - } - - // If this is a statement list, make it a source file - // by inserting a package clause and turning the list - // into a function body. This handles expressions too. - // Insert using a ';', not a newline, so that the line numbers - // in fsrc match the ones in src. Add an extra '\n' before the '}' - // to make sure comments are flushed before the '}'. - fsrc := append(append([]byte("package p; func _() {"), src...), '\n', '\n', '}') - file, err = parser.ParseFile(fset, filename, fsrc, parserMode) - if err == nil { - sourceAdj = func(src []byte, indent int) []byte { - // Cap adjusted indent to zero. - if indent < 0 { - indent = 0 - } - // Remove the wrapping. - // Gofmt has turned the "; " into a "\n\n". - // There will be two non-blank lines with indent, hence 2*indent. - src = src[2*indent+len("package p\n\nfunc _() {"):] - // Remove only the "}\n" suffix: remaining whitespaces will be trimmed anyway - src = src[:len(src)-len("}\n")] - return bytes.TrimSpace(src) - } - // Gofmt has also indented the function body one level. - // Adjust that with indentAdj. - indentAdj = -1 - } - - // Succeeded, or out of options. - return -} - -// format formats the given package file originally obtained from src -// and adjusts the result based on the original source via sourceAdj -// and indentAdj. -func format( - fset *token.FileSet, - file *ast.File, - sourceAdj func(src []byte, indent int) []byte, - indentAdj int, - src []byte, - cfg printer.Config, -) ([]byte, error) { - if sourceAdj == nil { - // Complete source file. - var buf bytes.Buffer - err := cfg.Fprint(&buf, fset, file) - if err != nil { - return nil, err - } - return buf.Bytes(), nil - } - - // Partial source file. - // Determine and prepend leading space. - i, j := 0, 0 - for j < len(src) && isSpace(src[j]) { - if src[j] == '\n' { - i = j + 1 // byte offset of last line in leading space - } - j++ - } - var res []byte - res = append(res, src[:i]...) - - // Determine and prepend indentation of first code line. - // Spaces are ignored unless there are no tabs, - // in which case spaces count as one tab. - indent := 0 - hasSpace := false - for _, b := range src[i:j] { - switch b { - case ' ': - hasSpace = true - case '\t': - indent++ - } - } - if indent == 0 && hasSpace { - indent = 1 - } - for i := 0; i < indent; i++ { - res = append(res, '\t') - } - - // Format the source. - // Write it without any leading and trailing space. - cfg.Indent = indent + indentAdj - var buf bytes.Buffer - err := cfg.Fprint(&buf, fset, file) - if err != nil { - return nil, err - } - out := sourceAdj(buf.Bytes(), cfg.Indent) - - // If the adjusted output is empty, the source - // was empty but (possibly) for white space. - // The result is the incoming source. - if len(out) == 0 { - return src, nil - } - - // Otherwise, append output to leading space. - res = append(res, out...) - - // Determine and append trailing space. - i = len(src) - for i > 0 && isSpace(src[i-1]) { - i-- - } - return append(res, src[i:]...), nil -} - -// isSpace reports whether the byte is a space character. -// isSpace defines a space as being among the following bytes: ' ', '\t', '\n' and '\r'. -func isSpace(b byte) bool { - return b == ' ' || b == '\t' || b == '\n' || b == '\r' -} diff --git a/vendor/github.com/golangci/gofmt/gofmt/readme.md b/vendor/github.com/golangci/gofmt/gofmt/readme.md deleted file mode 100644 index 907973116f..0000000000 --- a/vendor/github.com/golangci/gofmt/gofmt/readme.md +++ /dev/null @@ -1,15 +0,0 @@ -# Hard Fork of gofmt - -- https://github.com/golang/go/blob/master/src/cmd/gofmt/ -- https://github.com/golang/go/blob/master/src/internal/testenv -- https://github.com/golang/go/blob/master/src/internal/platform -- https://github.com/golang/go/blob/master/src/internal/diff -> replaced by `github.com/rogpeppe/go-internal/diff` -- https://github.com/golang/go/blob/master/src/internal/cfg - -## Updates - -- 2024-08-17: Sync with go1.22.6 -- 2023-02-28: Sync with go1.21.7 -- 2023-10-04: Sync with go1.20.8 -- 2023-10-04: Sync with go1.19.13 -- 2022-08-31: Sync with go1.18.5 diff --git a/vendor/github.com/golangci/gofmt/gofmt/rewrite.go b/vendor/github.com/golangci/gofmt/gofmt/rewrite.go deleted file mode 100644 index c95d44f61b..0000000000 --- a/vendor/github.com/golangci/gofmt/gofmt/rewrite.go +++ /dev/null @@ -1,309 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package gofmt - -import ( - "fmt" - "go/ast" - "go/parser" - "go/token" - "os" - "reflect" - "strings" - "unicode" - "unicode/utf8" -) - -func initRewrite() { - if *rewriteRule == "" { - rewrite = nil // disable any previous rewrite - return - } - f := strings.Split(*rewriteRule, "->") - if len(f) != 2 { - fmt.Fprintf(os.Stderr, "rewrite rule must be of the form 'pattern -> replacement'\n") - os.Exit(2) - } - pattern := parseExpr(f[0], "pattern") - replace := parseExpr(f[1], "replacement") - rewrite = func(fset *token.FileSet, p *ast.File) *ast.File { - return rewriteFile(fset, pattern, replace, p) - } -} - -// parseExpr parses s as an expression. -// It might make sense to expand this to allow statement patterns, -// but there are problems with preserving formatting and also -// with what a wildcard for a statement looks like. -func parseExpr(s, what string) ast.Expr { - x, err := parser.ParseExpr(s) - if err != nil { - fmt.Fprintf(os.Stderr, "parsing %s %s at %s\n", what, s, err) - os.Exit(2) - } - return x -} - -// Keep this function for debugging. -/* -func dump(msg string, val reflect.Value) { - fmt.Printf("%s:\n", msg) - ast.Print(fileSet, val.Interface()) - fmt.Println() -} -*/ - -// rewriteFile applies the rewrite rule 'pattern -> replace' to an entire file. -func rewriteFile(fileSet *token.FileSet, pattern, replace ast.Expr, p *ast.File) *ast.File { - cmap := ast.NewCommentMap(fileSet, p, p.Comments) - m := make(map[string]reflect.Value) - pat := reflect.ValueOf(pattern) - repl := reflect.ValueOf(replace) - - var rewriteVal func(val reflect.Value) reflect.Value - rewriteVal = func(val reflect.Value) reflect.Value { - // don't bother if val is invalid to start with - if !val.IsValid() { - return reflect.Value{} - } - val = apply(rewriteVal, val) - clear(m) - if match(m, pat, val) { - val = subst(m, repl, reflect.ValueOf(val.Interface().(ast.Node).Pos())) - } - return val - } - - r := apply(rewriteVal, reflect.ValueOf(p)).Interface().(*ast.File) - r.Comments = cmap.Filter(r).Comments() // recreate comments list - return r -} - -// set is a wrapper for x.Set(y); it protects the caller from panics if x cannot be changed to y. -func set(x, y reflect.Value) { - // don't bother if x cannot be set or y is invalid - if !x.CanSet() || !y.IsValid() { - return - } - defer func() { - if x := recover(); x != nil { - if s, ok := x.(string); ok && - (strings.Contains(s, "type mismatch") || strings.Contains(s, "not assignable")) { - // x cannot be set to y - ignore this rewrite - return - } - panic(x) - } - }() - x.Set(y) -} - -// Values/types for special cases. -var ( - objectPtrNil = reflect.ValueOf((*ast.Object)(nil)) - scopePtrNil = reflect.ValueOf((*ast.Scope)(nil)) - - identType = reflect.TypeOf((*ast.Ident)(nil)) - objectPtrType = reflect.TypeOf((*ast.Object)(nil)) - positionType = reflect.TypeOf(token.NoPos) - callExprType = reflect.TypeOf((*ast.CallExpr)(nil)) - scopePtrType = reflect.TypeOf((*ast.Scope)(nil)) -) - -// apply replaces each AST field x in val with f(x), returning val. -// To avoid extra conversions, f operates on the reflect.Value form. -func apply(f func(reflect.Value) reflect.Value, val reflect.Value) reflect.Value { - if !val.IsValid() { - return reflect.Value{} - } - - // *ast.Objects introduce cycles and are likely incorrect after - // rewrite; don't follow them but replace with nil instead - if val.Type() == objectPtrType { - return objectPtrNil - } - - // similarly for scopes: they are likely incorrect after a rewrite; - // replace them with nil - if val.Type() == scopePtrType { - return scopePtrNil - } - - switch v := reflect.Indirect(val); v.Kind() { - case reflect.Slice: - for i := 0; i < v.Len(); i++ { - e := v.Index(i) - set(e, f(e)) - } - case reflect.Struct: - for i := 0; i < v.NumField(); i++ { - e := v.Field(i) - set(e, f(e)) - } - case reflect.Interface: - e := v.Elem() - set(v, f(e)) - } - return val -} - -func isWildcard(s string) bool { - rune, size := utf8.DecodeRuneInString(s) - return size == len(s) && unicode.IsLower(rune) -} - -// match reports whether pattern matches val, -// recording wildcard submatches in m. -// If m == nil, match checks whether pattern == val. -func match(m map[string]reflect.Value, pattern, val reflect.Value) bool { - // Wildcard matches any expression. If it appears multiple - // times in the pattern, it must match the same expression - // each time. - if m != nil && pattern.IsValid() && pattern.Type() == identType { - name := pattern.Interface().(*ast.Ident).Name - if isWildcard(name) && val.IsValid() { - // wildcards only match valid (non-nil) expressions. - if _, ok := val.Interface().(ast.Expr); ok && !val.IsNil() { - if old, ok := m[name]; ok { - return match(nil, old, val) - } - m[name] = val - return true - } - } - } - - // Otherwise, pattern and val must match recursively. - if !pattern.IsValid() || !val.IsValid() { - return !pattern.IsValid() && !val.IsValid() - } - if pattern.Type() != val.Type() { - return false - } - - // Special cases. - switch pattern.Type() { - case identType: - // For identifiers, only the names need to match - // (and none of the other *ast.Object information). - // This is a common case, handle it all here instead - // of recursing down any further via reflection. - p := pattern.Interface().(*ast.Ident) - v := val.Interface().(*ast.Ident) - return p == nil && v == nil || p != nil && v != nil && p.Name == v.Name - case objectPtrType, positionType: - // object pointers and token positions always match - return true - case callExprType: - // For calls, the Ellipsis fields (token.Pos) must - // match since that is how f(x) and f(x...) are different. - // Check them here but fall through for the remaining fields. - p := pattern.Interface().(*ast.CallExpr) - v := val.Interface().(*ast.CallExpr) - if p.Ellipsis.IsValid() != v.Ellipsis.IsValid() { - return false - } - } - - p := reflect.Indirect(pattern) - v := reflect.Indirect(val) - if !p.IsValid() || !v.IsValid() { - return !p.IsValid() && !v.IsValid() - } - - switch p.Kind() { - case reflect.Slice: - if p.Len() != v.Len() { - return false - } - for i := 0; i < p.Len(); i++ { - if !match(m, p.Index(i), v.Index(i)) { - return false - } - } - return true - - case reflect.Struct: - for i := 0; i < p.NumField(); i++ { - if !match(m, p.Field(i), v.Field(i)) { - return false - } - } - return true - - case reflect.Interface: - return match(m, p.Elem(), v.Elem()) - } - - // Handle token integers, etc. - return p.Interface() == v.Interface() -} - -// subst returns a copy of pattern with values from m substituted in place -// of wildcards and pos used as the position of tokens from the pattern. -// if m == nil, subst returns a copy of pattern and doesn't change the line -// number information. -func subst(m map[string]reflect.Value, pattern reflect.Value, pos reflect.Value) reflect.Value { - if !pattern.IsValid() { - return reflect.Value{} - } - - // Wildcard gets replaced with map value. - if m != nil && pattern.Type() == identType { - name := pattern.Interface().(*ast.Ident).Name - if isWildcard(name) { - if old, ok := m[name]; ok { - return subst(nil, old, reflect.Value{}) - } - } - } - - if pos.IsValid() && pattern.Type() == positionType { - // use new position only if old position was valid in the first place - if old := pattern.Interface().(token.Pos); !old.IsValid() { - return pattern - } - return pos - } - - // Otherwise copy. - switch p := pattern; p.Kind() { - case reflect.Slice: - if p.IsNil() { - // Do not turn nil slices into empty slices. go/ast - // guarantees that certain lists will be nil if not - // populated. - return reflect.Zero(p.Type()) - } - v := reflect.MakeSlice(p.Type(), p.Len(), p.Len()) - for i := 0; i < p.Len(); i++ { - v.Index(i).Set(subst(m, p.Index(i), pos)) - } - return v - - case reflect.Struct: - v := reflect.New(p.Type()).Elem() - for i := 0; i < p.NumField(); i++ { - v.Field(i).Set(subst(m, p.Field(i), pos)) - } - return v - - case reflect.Pointer: - v := reflect.New(p.Type()).Elem() - if elem := p.Elem(); elem.IsValid() { - v.Set(subst(m, elem, pos).Addr()) - } - return v - - case reflect.Interface: - v := reflect.New(p.Type()).Elem() - if elem := p.Elem(); elem.IsValid() { - v.Set(subst(m, elem, pos)) - } - return v - } - - return pattern -} diff --git a/vendor/github.com/golangci/gofmt/gofmt/simplify.go b/vendor/github.com/golangci/gofmt/gofmt/simplify.go deleted file mode 100644 index 3b34d562ba..0000000000 --- a/vendor/github.com/golangci/gofmt/gofmt/simplify.go +++ /dev/null @@ -1,169 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package gofmt - -import ( - "go/ast" - "go/token" - "reflect" -) - -type simplifier struct{} - -func (s simplifier) Visit(node ast.Node) ast.Visitor { - switch n := node.(type) { - case *ast.CompositeLit: - // array, slice, and map composite literals may be simplified - outer := n - var keyType, eltType ast.Expr - switch typ := outer.Type.(type) { - case *ast.ArrayType: - eltType = typ.Elt - case *ast.MapType: - keyType = typ.Key - eltType = typ.Value - } - - if eltType != nil { - var ktyp reflect.Value - if keyType != nil { - ktyp = reflect.ValueOf(keyType) - } - typ := reflect.ValueOf(eltType) - for i, x := range outer.Elts { - px := &outer.Elts[i] - // look at value of indexed/named elements - if t, ok := x.(*ast.KeyValueExpr); ok { - if keyType != nil { - s.simplifyLiteral(ktyp, keyType, t.Key, &t.Key) - } - x = t.Value - px = &t.Value - } - s.simplifyLiteral(typ, eltType, x, px) - } - // node was simplified - stop walk (there are no subnodes to simplify) - return nil - } - - case *ast.SliceExpr: - // a slice expression of the form: s[a:len(s)] - // can be simplified to: s[a:] - // if s is "simple enough" (for now we only accept identifiers) - // - // Note: This may not be correct because len may have been redeclared in - // the same package. However, this is extremely unlikely and so far - // (April 2022, after years of supporting this rewrite feature) - // has never come up, so let's keep it working as is (see also #15153). - // - // Also note that this code used to use go/ast's object tracking, - // which was removed in exchange for go/parser.Mode.SkipObjectResolution. - // False positives are extremely unlikely as described above, - // and go/ast's object tracking is incomplete in any case. - if n.Max != nil { - // - 3-index slices always require the 2nd and 3rd index - break - } - if s, _ := n.X.(*ast.Ident); s != nil { - // the array/slice object is a single identifier - if call, _ := n.High.(*ast.CallExpr); call != nil && len(call.Args) == 1 && !call.Ellipsis.IsValid() { - // the high expression is a function call with a single argument - if fun, _ := call.Fun.(*ast.Ident); fun != nil && fun.Name == "len" { - // the function called is "len" - if arg, _ := call.Args[0].(*ast.Ident); arg != nil && arg.Name == s.Name { - // the len argument is the array/slice object - n.High = nil - } - } - } - } - // Note: We could also simplify slice expressions of the form s[0:b] to s[:b] - // but we leave them as is since sometimes we want to be very explicit - // about the lower bound. - // An example where the 0 helps: - // x, y, z := b[0:2], b[2:4], b[4:6] - // An example where it does not: - // x, y := b[:n], b[n:] - - case *ast.RangeStmt: - // - a range of the form: for x, _ = range v {...} - // can be simplified to: for x = range v {...} - // - a range of the form: for _ = range v {...} - // can be simplified to: for range v {...} - if isBlank(n.Value) { - n.Value = nil - } - if isBlank(n.Key) && n.Value == nil { - n.Key = nil - } - } - - return s -} - -func (s simplifier) simplifyLiteral(typ reflect.Value, astType, x ast.Expr, px *ast.Expr) { - ast.Walk(s, x) // simplify x - - // if the element is a composite literal and its literal type - // matches the outer literal's element type exactly, the inner - // literal type may be omitted - if inner, ok := x.(*ast.CompositeLit); ok { - if match(nil, typ, reflect.ValueOf(inner.Type)) { - inner.Type = nil - } - } - // if the outer literal's element type is a pointer type *T - // and the element is & of a composite literal of type T, - // the inner &T may be omitted. - if ptr, ok := astType.(*ast.StarExpr); ok { - if addr, ok := x.(*ast.UnaryExpr); ok && addr.Op == token.AND { - if inner, ok := addr.X.(*ast.CompositeLit); ok { - if match(nil, reflect.ValueOf(ptr.X), reflect.ValueOf(inner.Type)) { - inner.Type = nil // drop T - *px = inner // drop & - } - } - } - } -} - -func isBlank(x ast.Expr) bool { - ident, ok := x.(*ast.Ident) - return ok && ident.Name == "_" -} - -func simplify(f *ast.File) { - // remove empty declarations such as "const ()", etc - removeEmptyDeclGroups(f) - - var s simplifier - ast.Walk(s, f) -} - -func removeEmptyDeclGroups(f *ast.File) { - i := 0 - for _, d := range f.Decls { - if g, ok := d.(*ast.GenDecl); !ok || !isEmpty(f, g) { - f.Decls[i] = d - i++ - } - } - f.Decls = f.Decls[:i] -} - -func isEmpty(f *ast.File, g *ast.GenDecl) bool { - if g.Doc != nil || g.Specs != nil { - return false - } - - for _, c := range f.Comments { - // if there is a comment in the declaration, it is not considered empty - if g.Pos() <= c.Pos() && c.End() <= g.End() { - return false - } - } - - return true -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/LICENSE b/vendor/github.com/golangci/golangci-lint/v2/LICENSE deleted file mode 100644 index e72bfddabc..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. \ No newline at end of file diff --git a/vendor/github.com/golangci/golangci-lint/v2/cmd/golangci-lint/main.go b/vendor/github.com/golangci/golangci-lint/v2/cmd/golangci-lint/main.go deleted file mode 100644 index acb09cd8c0..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/cmd/golangci-lint/main.go +++ /dev/null @@ -1,80 +0,0 @@ -package main - -import ( - "cmp" - "fmt" - "os" - "regexp" - "runtime/debug" - "strings" - - "github.com/golangci/golangci-lint/v2/pkg/commands" - "github.com/golangci/golangci-lint/v2/pkg/exitcodes" -) - -var ( - goVersion = "unknown" - - // Populated by goreleaser during build - version = "unknown" - commit = "?" - date = "" -) - -func main() { - info := createBuildInfo() - - if err := commands.Execute(info); err != nil { - _, _ = fmt.Fprintf(os.Stderr, "The command is terminated due to an error: %v\n", err) - os.Exit(exitcodes.Failure) - } -} - -func createBuildInfo() commands.BuildInfo { - info := commands.BuildInfo{ - Commit: commit, - Version: version, - GoVersion: goVersion, - Date: date, - } - - buildInfo, available := debug.ReadBuildInfo() - if !available { - return info - } - - info.GoVersion = buildInfo.GoVersion - - if date != "" { - return info - } - - info.Version = buildInfo.Main.Version - - matched, _ := regexp.MatchString(`v\d+\.\d+\.\d+`, buildInfo.Main.Version) - if matched { - info.Version = strings.TrimPrefix(buildInfo.Main.Version, "v") - } - - var revision string - var modified string - for _, setting := range buildInfo.Settings { - // The `vcs.xxx` information is only available with `go build`. - // This information is not available with `go install` or `go run`. - switch setting.Key { - case "vcs.time": - info.Date = setting.Value - case "vcs.revision": - revision = setting.Value - case "vcs.modified": - modified = setting.Value - } - } - - info.Date = cmp.Or(info.Date, "(unknown)") - - info.Commit = fmt.Sprintf("(%s, modified: %s, mod sum: %q)", - cmp.Or(revision, "unknown"), cmp.Or(modified, "?"), buildInfo.Main.Sum) - - return info -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/cmd/golangci-lint/plugins.go b/vendor/github.com/golangci/golangci-lint/v2/cmd/golangci-lint/plugins.go deleted file mode 100644 index 541ff76242..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/cmd/golangci-lint/plugins.go +++ /dev/null @@ -1,3 +0,0 @@ -package main - -// This file is used to declare module plugins. diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/cache/cache.go b/vendor/github.com/golangci/golangci-lint/v2/internal/cache/cache.go deleted file mode 100644 index 138a36148a..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/cache/cache.go +++ /dev/null @@ -1,296 +0,0 @@ -package cache - -import ( - "bytes" - "encoding/gob" - "encoding/hex" - "errors" - "fmt" - "maps" - "runtime" - "slices" - "strings" - "sync" - - "golang.org/x/tools/go/packages" - - "github.com/golangci/golangci-lint/v2/internal/go/cache" - "github.com/golangci/golangci-lint/v2/pkg/logutils" - "github.com/golangci/golangci-lint/v2/pkg/timeutils" -) - -type HashMode int - -const ( - HashModeNeedOnlySelf HashMode = iota - HashModeNeedDirectDeps - HashModeNeedAllDeps -) - -var ErrMissing = errors.New("missing data") - -type hashResults map[HashMode]string - -// Cache is a per-package data cache. -// A cached data is invalidated when package, -// or it's dependencies change. -type Cache struct { - lowLevelCache cache.Cache - pkgHashes sync.Map - sw *timeutils.Stopwatch - log logutils.Log - ioSem chan struct{} // semaphore limiting parallel IO -} - -func NewCache(sw *timeutils.Stopwatch, log logutils.Log) (*Cache, error) { - return &Cache{ - lowLevelCache: cache.Default(), - sw: sw, - log: log, - ioSem: make(chan struct{}, runtime.GOMAXPROCS(-1)), - }, nil -} - -func (c *Cache) Close() { - err := c.sw.TrackStageErr("close", c.lowLevelCache.Close) - if err != nil { - c.log.Errorf("cache close: %v", err) - } -} - -func (c *Cache) Put(pkg *packages.Package, mode HashMode, key string, data any) error { - buf, err := c.encode(data) - if err != nil { - return err - } - - actionID, err := c.buildKey(pkg, mode, key) - if err != nil { - return fmt.Errorf("failed to calculate package %s action id: %w", pkg.Name, err) - } - - err = c.putBytes(actionID, buf) - if err != nil { - return fmt.Errorf("failed to save data to low-level cache by key %s for package %s: %w", key, pkg.Name, err) - } - - return nil -} - -func (c *Cache) Get(pkg *packages.Package, mode HashMode, key string, data any) error { - actionID, err := c.buildKey(pkg, mode, key) - if err != nil { - return fmt.Errorf("failed to calculate package %s action id: %w", pkg.Name, err) - } - - cachedData, err := c.getBytes(actionID) - if err != nil { - if cache.IsErrMissing(err) { - return ErrMissing - } - return fmt.Errorf("failed to get data from low-level cache by key %s for package %s: %w", key, pkg.Name, err) - } - - return c.decode(cachedData, data) -} - -func (c *Cache) buildKey(pkg *packages.Package, mode HashMode, key string) (cache.ActionID, error) { - return timeutils.TrackStage(c.sw, "key build", func() (cache.ActionID, error) { - actionID, err := c.pkgActionID(pkg, mode) - if err != nil { - return actionID, err - } - - subkey, subkeyErr := cache.Subkey(actionID, key) - if subkeyErr != nil { - return actionID, fmt.Errorf("failed to build subkey: %w", subkeyErr) - } - - return subkey, nil - }) -} - -func (c *Cache) pkgActionID(pkg *packages.Package, mode HashMode) (cache.ActionID, error) { - hash, err := c.packageHash(pkg, mode) - if err != nil { - return cache.ActionID{}, fmt.Errorf("failed to get package hash: %w", err) - } - - key, err := cache.NewHash("action ID") - if err != nil { - return cache.ActionID{}, fmt.Errorf("failed to make a hash: %w", err) - } - - fmt.Fprintf(key, "pkgpath %s\n", pkg.PkgPath) - fmt.Fprintf(key, "pkghash %s\n", hash) - - return key.Sum(), nil -} - -func (c *Cache) packageHash(pkg *packages.Package, mode HashMode) (string, error) { - results, found := c.pkgHashes.Load(pkg) - if found { - hashRes := results.(hashResults) - if result, ok := hashRes[mode]; ok { - return result, nil - } - - return "", fmt.Errorf("no mode %d in hash result", mode) - } - - hashRes, err := c.computePkgHash(pkg) - if err != nil { - return "", err - } - - result, found := hashRes[mode] - if !found { - return "", fmt.Errorf("invalid mode %d", mode) - } - - c.pkgHashes.Store(pkg, hashRes) - - return result, nil -} - -// computePkgHash computes a package's hash. -// The hash is based on all Go files that make up the package, -// as well as the hashes of imported packages. -func (c *Cache) computePkgHash(pkg *packages.Package) (hashResults, error) { - key, err := cache.NewHash("package hash") - if err != nil { - return nil, fmt.Errorf("failed to make a hash: %w", err) - } - - hashRes := hashResults{} - - fmt.Fprintf(key, "pkgpath %s\n", pkg.PkgPath) - - for _, f := range slices.Concat(pkg.CompiledGoFiles, pkg.IgnoredFiles) { - h, fErr := c.fileHash(f) - if fErr != nil { - return nil, fmt.Errorf("failed to calculate file %s hash: %w", f, fErr) - } - - fmt.Fprintf(key, "file %s %x\n", f, h) - } - - curSum := key.Sum() - hashRes[HashModeNeedOnlySelf] = hex.EncodeToString(curSum[:]) - - imps := slices.SortedFunc(maps.Values(pkg.Imports), func(a, b *packages.Package) int { - return strings.Compare(a.PkgPath, b.PkgPath) - }) - - if err := c.computeDepsHash(HashModeNeedOnlySelf, imps, key); err != nil { - return nil, err - } - - curSum = key.Sum() - hashRes[HashModeNeedDirectDeps] = hex.EncodeToString(curSum[:]) - - if err := c.computeDepsHash(HashModeNeedAllDeps, imps, key); err != nil { - return nil, err - } - - curSum = key.Sum() - hashRes[HashModeNeedAllDeps] = hex.EncodeToString(curSum[:]) - - return hashRes, nil -} - -func (c *Cache) computeDepsHash(depMode HashMode, imps []*packages.Package, key *cache.Hash) error { - for _, dep := range imps { - if dep.PkgPath == "unsafe" { - continue - } - - depHash, err := c.packageHash(dep, depMode) - if err != nil { - return fmt.Errorf("failed to calculate hash for dependency %s with mode %d: %w", dep.Name, depMode, err) - } - - fmt.Fprintf(key, "import %s %s\n", dep.PkgPath, depHash) - } - - return nil -} - -func (c *Cache) putBytes(actionID cache.ActionID, buf *bytes.Buffer) error { - c.ioSem <- struct{}{} - - err := c.sw.TrackStageErr("cache io", func() error { - return cache.PutBytes(c.lowLevelCache, actionID, buf.Bytes()) - }) - - <-c.ioSem - - if err != nil { - return err - } - - return nil -} - -func (c *Cache) getBytes(actionID cache.ActionID) ([]byte, error) { - c.ioSem <- struct{}{} - - cachedData, err := timeutils.TrackStage(c.sw, "cache io", func() ([]byte, error) { - b, _, errGB := cache.GetBytes(c.lowLevelCache, actionID) - return b, errGB - }) - - <-c.ioSem - - if err != nil { - return nil, err - } - - return cachedData, nil -} - -func (c *Cache) fileHash(f string) ([cache.HashSize]byte, error) { - c.ioSem <- struct{}{} - - h, err := cache.FileHash(f) - - <-c.ioSem - - if err != nil { - return [cache.HashSize]byte{}, err - } - - return h, nil -} - -func (c *Cache) encode(data any) (*bytes.Buffer, error) { - buf := &bytes.Buffer{} - err := c.sw.TrackStageErr("gob", func() error { - return gob.NewEncoder(buf).Encode(data) - }) - if err != nil { - return nil, fmt.Errorf("failed to gob encode: %w", err) - } - - return buf, nil -} - -func (c *Cache) decode(b []byte, data any) error { - err := c.sw.TrackStageErr("gob", func() error { - return gob.NewDecoder(bytes.NewReader(b)).Decode(data) - }) - if err != nil { - return fmt.Errorf("failed to gob decode: %w", err) - } - - return nil -} - -func SetSalt(b *bytes.Buffer) { - cache.SetSalt(b.Bytes()) -} - -func DefaultDir() string { - cacheDir, _ := cache.DefaultDir() - return cacheDir -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/errorutil/errors.go b/vendor/github.com/golangci/golangci-lint/v2/internal/errorutil/errors.go deleted file mode 100644 index c8a3a0357e..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/errorutil/errors.go +++ /dev/null @@ -1,23 +0,0 @@ -package errorutil - -import ( - "fmt" -) - -// PanicError can be used to not print stacktrace twice -type PanicError struct { - recovered any - stack []byte -} - -func NewPanicError(recovered any, stack []byte) *PanicError { - return &PanicError{recovered: recovered, stack: stack} -} - -func (e PanicError) Error() string { - return fmt.Sprint(e.recovered) -} - -func (e PanicError) Stack() []byte { - return e.stack -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/go/LICENSE b/vendor/github.com/golangci/golangci-lint/v2/internal/go/LICENSE deleted file mode 100644 index 6a66aea5ea..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/go/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/go/base/error_notunix.go b/vendor/github.com/golangci/golangci-lint/v2/internal/go/base/error_notunix.go deleted file mode 100644 index c7780fa300..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/go/base/error_notunix.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !unix - -package base - -func IsETXTBSY(err error) bool { - // syscall.ETXTBSY is only meaningful on Unix platforms. - return false -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/go/base/error_unix.go b/vendor/github.com/golangci/golangci-lint/v2/internal/go/base/error_unix.go deleted file mode 100644 index 2dcd75e5f3..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/go/base/error_unix.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build unix - -package base - -import ( - "errors" - "syscall" -) - -func IsETXTBSY(err error) bool { - return errors.Is(err, syscall.ETXTBSY) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/go/base/readme.md b/vendor/github.com/golangci/golangci-lint/v2/internal/go/base/readme.md deleted file mode 100644 index 93afe9f283..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/go/base/readme.md +++ /dev/null @@ -1,10 +0,0 @@ -# quoted - -Extracted from `go/src/cmd/go/internal/base/` (related to `cache`). - -Only the function `IsETXTBSY` is extracted. - -## History - -- https://github.com/golangci/golangci-lint/pull/5576 - - sync go1.24.1 diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/cache.go b/vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/cache.go deleted file mode 100644 index c514613dce..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/cache.go +++ /dev/null @@ -1,716 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package cache implements a build artifact cache. -// -// This package is a slightly modified fork of Go's -// cmd/go/internal/cache package. -package cache - -import ( - "bytes" - "crypto/sha256" - "encoding/hex" - "errors" - "fmt" - "io" - "io/fs" - "os" - "path/filepath" - "strconv" - "strings" - "time" - - "github.com/rogpeppe/go-internal/lockedfile" - "github.com/rogpeppe/go-internal/robustio" - - "github.com/golangci/golangci-lint/v2/internal/go/base" - "github.com/golangci/golangci-lint/v2/internal/go/mmap" -) - -// An ActionID is a cache action key, the hash of a complete description of a -// repeatable computation (command line, environment variables, -// input file contents, executable contents). -type ActionID [HashSize]byte - -// An OutputID is a cache output key, the hash of an output of a computation. -type OutputID [HashSize]byte - -// Cache is the interface as used by the cmd/go. -type Cache interface { - // Get returns the cache entry for the provided ActionID. - // On miss, the error type should be of type *entryNotFoundError. - // - // After a successful call to Get, OutputFile(Entry.OutputID) must - // exist on disk until Close is called (at the end of the process). - Get(ActionID) (Entry, error) - - // Put adds an item to the cache. - // - // The seeker is only used to seek to the beginning. After a call to Put, - // the seek position is not guaranteed to be in any particular state. - // - // As a special case, if the ReadSeeker is of type noVerifyReadSeeker, - // the verification from GODEBUG=goverifycache=1 is skipped. - // - // After a successful call to Put, OutputFile(OutputID) must - // exist on disk until Close is called (at the end of the process). - Put(ActionID, io.ReadSeeker) (_ OutputID, size int64, _ error) - - // Close is called at the end of the go process. Implementations can do - // cache cleanup work at this phase, or wait for and report any errors from - // background cleanup work started earlier. Any cache trimming in one - // process should not cause the invariants of this interface to be - // violated in another process. Namely, a cache trim from one process should - // not delete an ObjectID from disk that was recently Get or Put from - // another process. As a rule of thumb, don't trim things used in the last - // day. - Close() error - - // OutputFile returns the path on disk where OutputID is stored. - // - // It's only called after a successful get or put call so it doesn't need - // to return an error; it's assumed that if the previous get or put succeeded, - // it's already on disk. - OutputFile(OutputID) string - - // FuzzDir returns where fuzz files are stored. - FuzzDir() string -} - -// A Cache is a package cache, backed by a file system directory tree. -type DiskCache struct { - dir string - now func() time.Time -} - -// Open opens and returns the cache in the given directory. -// -// It is safe for multiple processes on a single machine to use the -// same cache directory in a local file system simultaneously. -// They will coordinate using operating system file locks and may -// duplicate effort but will not corrupt the cache. -// -// However, it is NOT safe for multiple processes on different machines -// to share a cache directory (for example, if the directory were stored -// in a network file system). File locking is notoriously unreliable in -// network file systems and may not suffice to protect the cache. -func Open(dir string) (*DiskCache, error) { - info, err := os.Stat(dir) - if err != nil { - return nil, err - } - if !info.IsDir() { - return nil, &fs.PathError{Op: "open", Path: dir, Err: fmt.Errorf("not a directory")} - } - for i := 0; i < 256; i++ { - name := filepath.Join(dir, fmt.Sprintf("%02x", i)) - if err := os.MkdirAll(name, 0o777); err != nil { - return nil, err - } - } - c := &DiskCache{ - dir: dir, - now: time.Now, - } - return c, nil -} - -// fileName returns the name of the file corresponding to the given id. -func (c *DiskCache) fileName(id [HashSize]byte, key string) string { - return filepath.Join(c.dir, fmt.Sprintf("%02x", id[0]), fmt.Sprintf("%x", id)+"-"+key) -} - -// An entryNotFoundError indicates that a cache entry was not found, with an -// optional underlying reason. -type entryNotFoundError struct { - Err error -} - -func (e *entryNotFoundError) Error() string { - if e.Err == nil { - return "cache entry not found" - } - return fmt.Sprintf("cache entry not found: %v", e.Err) -} - -func (e *entryNotFoundError) Unwrap() error { - return e.Err -} - -const ( - // action entry file is "v1 \n" - hexSize = HashSize * 2 - entrySize = 2 + 1 + hexSize + 1 + hexSize + 1 + 20 + 1 + 20 + 1 -) - -// verify controls whether to run the cache in verify mode. -// In verify mode, the cache always returns errMissing from Get -// but then double-checks in Put that the data being written -// exactly matches any existing entry. This provides an easy -// way to detect program behavior that would have been different -// had the cache entry been returned from Get. -// -// verify is enabled by setting the environment variable -// GODEBUG=gocacheverify=1. -var verify = false - -var errVerifyMode = errors.New("gocacheverify=1") - -// DebugTest is set when GODEBUG=gocachetest=1 is in the environment. -var DebugTest = false - -// func init() { initEnv() } -// -// var ( -// gocacheverify = godebug.New("gocacheverify") -// gocachehash = godebug.New("gocachehash") -// gocachetest = godebug.New("gocachetest") -// ) -// -// func initEnv() { -// if gocacheverify.Value() == "1" { -// gocacheverify.IncNonDefault() -// verify = true -// } -// if gocachehash.Value() == "1" { -// gocachehash.IncNonDefault() -// debugHash = true -// } -// if gocachetest.Value() == "1" { -// gocachetest.IncNonDefault() -// DebugTest = true -// } -// } - -// Get looks up the action ID in the cache, -// returning the corresponding output ID and file size, if any. -// Note that finding an output ID does not guarantee that the -// saved file for that output ID is still available. -func (c *DiskCache) Get(id ActionID) (Entry, error) { - if verify { - return Entry{}, &entryNotFoundError{Err: errVerifyMode} - } - return c.get(id) -} - -type Entry struct { - OutputID OutputID - Size int64 - Time time.Time // when added to cache -} - -// get is Get but does not respect verify mode, so that Put can use it. -func (c *DiskCache) get(id ActionID) (Entry, error) { - missing := func(reason error) (Entry, error) { - return Entry{}, &entryNotFoundError{Err: reason} - } - f, err := os.Open(c.fileName(id, "a")) - if err != nil { - return missing(err) - } - defer f.Close() - entry := make([]byte, entrySize+1) // +1 to detect whether f is too long - if n, err := io.ReadFull(f, entry); n > entrySize { - return missing(errors.New("too long")) - } else if err != io.ErrUnexpectedEOF { - if err == io.EOF { - return missing(errors.New("file is empty")) - } - return missing(err) - } else if n < entrySize { - return missing(errors.New("entry file incomplete")) - } - if entry[0] != 'v' || entry[1] != '1' || entry[2] != ' ' || entry[3+hexSize] != ' ' || entry[3+hexSize+1+hexSize] != ' ' || entry[3+hexSize+1+hexSize+1+20] != ' ' || entry[entrySize-1] != '\n' { - return missing(errors.New("invalid header")) - } - eid, entry := entry[3:3+hexSize], entry[3+hexSize:] - eout, entry := entry[1:1+hexSize], entry[1+hexSize:] - esize, entry := entry[1:1+20], entry[1+20:] - etime, entry := entry[1:1+20], entry[1+20:] - var buf [HashSize]byte - if _, err := hex.Decode(buf[:], eid); err != nil { - return missing(fmt.Errorf("decoding ID: %v", err)) - } else if buf != id { - return missing(errors.New("mismatched ID")) - } - if _, err := hex.Decode(buf[:], eout); err != nil { - return missing(fmt.Errorf("decoding output ID: %v", err)) - } - i := 0 - for i < len(esize) && esize[i] == ' ' { - i++ - } - size, err := strconv.ParseInt(string(esize[i:]), 10, 64) - if err != nil { - return missing(fmt.Errorf("parsing size: %v", err)) - } else if size < 0 { - return missing(errors.New("negative size")) - } - i = 0 - for i < len(etime) && etime[i] == ' ' { - i++ - } - tm, err := strconv.ParseInt(string(etime[i:]), 10, 64) - if err != nil { - return missing(fmt.Errorf("parsing timestamp: %v", err)) - } else if tm < 0 { - return missing(errors.New("negative timestamp")) - } - - c.markUsed(c.fileName(id, "a")) - - return Entry{buf, size, time.Unix(0, tm)}, nil -} - -// GetFile looks up the action ID in the cache and returns -// the name of the corresponding data file. -func GetFile(c Cache, id ActionID) (file string, entry Entry, err error) { - entry, err = c.Get(id) - if err != nil { - return "", Entry{}, err - } - file = c.OutputFile(entry.OutputID) - info, err := os.Stat(file) - if err != nil { - return "", Entry{}, &entryNotFoundError{Err: err} - } - if info.Size() != entry.Size { - return "", Entry{}, &entryNotFoundError{Err: errors.New("file incomplete")} - } - return file, entry, nil -} - -// GetBytes looks up the action ID in the cache and returns -// the corresponding output bytes. -// GetBytes should only be used for data that can be expected to fit in memory. -func GetBytes(c Cache, id ActionID) ([]byte, Entry, error) { - entry, err := c.Get(id) - if err != nil { - return nil, entry, err - } - data, err := robustio.ReadFile(c.OutputFile(entry.OutputID)) - if err != nil { - return nil, entry, &entryNotFoundError{Err: err} - } - if sha256.Sum256(data) != entry.OutputID { - return nil, entry, &entryNotFoundError{Err: errors.New("bad checksum")} - } - return data, entry, nil -} - -// GetMmap looks up the action ID in the cache and returns -// the corresponding output bytes. -// GetMmap should only be used for data that can be expected to fit in memory. -func GetMmap(c Cache, id ActionID) ([]byte, Entry, bool, error) { - entry, err := c.Get(id) - if err != nil { - return nil, entry, false, err - } - md, opened, err := mmap.Mmap(c.OutputFile(entry.OutputID)) - if err != nil { - return nil, Entry{}, opened, err - } - if int64(len(md.Data)) != entry.Size { - return nil, Entry{}, true, &entryNotFoundError{Err: errors.New("file incomplete")} - } - return md.Data, entry, true, nil -} - -// OutputFile returns the name of the cache file storing output with the given OutputID. -func (c *DiskCache) OutputFile(out OutputID) string { - file := c.fileName(out, "d") - isDir := c.markUsed(file) - if isDir { // => cached executable - entries, err := os.ReadDir(file) - if err != nil { - return fmt.Sprintf("DO NOT USE - missing binary cache entry: %v", err) - } - if len(entries) != 1 { - return "DO NOT USE - invalid binary cache entry" - } - return filepath.Join(file, entries[0].Name()) - } - return file -} - -// Time constants for cache expiration. -// -// We set the mtime on a cache file on each use, but at most one per mtimeInterval (1 hour), -// to avoid causing many unnecessary inode updates. The mtimes therefore -// roughly reflect "time of last use" but may in fact be older by at most an hour. -// -// We scan the cache for entries to delete at most once per trimInterval (1 day). -// -// When we do scan the cache, we delete entries that have not been used for -// at least trimLimit (5 days). Statistics gathered from a month of usage by -// Go developers found that essentially all reuse of cached entries happened -// within 5 days of the previous reuse. See golang.org/issue/22990. -const ( - mtimeInterval = 1 * time.Hour - trimInterval = 24 * time.Hour - trimLimit = 5 * 24 * time.Hour -) - -// markUsed makes a best-effort attempt to update mtime on file, -// so that mtime reflects cache access time. -// -// Because the reflection only needs to be approximate, -// and to reduce the amount of disk activity caused by using -// cache entries, used only updates the mtime if the current -// mtime is more than an hour old. This heuristic eliminates -// nearly all of the mtime updates that would otherwise happen, -// while still keeping the mtimes useful for cache trimming. -// -// markUsed reports whether the file is a directory (an executable cache entry). -func (c *DiskCache) markUsed(file string) (isDir bool) { - info, err := os.Stat(file) - if err != nil { - return false - } - if now := c.now(); now.Sub(info.ModTime()) >= mtimeInterval { - os.Chtimes(file, now, now) - } - return info.IsDir() -} - -func (c *DiskCache) Close() error { return c.Trim() } - -// Trim removes old cache entries that are likely not to be reused. -func (c *DiskCache) Trim() error { - now := c.now() - - // We maintain in dir/trim.txt the time of the last completed cache trim. - // If the cache has been trimmed recently enough, do nothing. - // This is the common case. - // If the trim file is corrupt, detected if the file can't be parsed, or the - // trim time is too far in the future, attempt the trim anyway. It's possible that - // the cache was full when the corruption happened. Attempting a trim on - // an empty cache is cheap, so there wouldn't be a big performance hit in that case. - if data, err := lockedfile.Read(filepath.Join(c.dir, "trim.txt")); err == nil { - if t, err := strconv.ParseInt(strings.TrimSpace(string(data)), 10, 64); err == nil { - lastTrim := time.Unix(t, 0) - if d := now.Sub(lastTrim); d < trimInterval && d > -mtimeInterval { - return nil - } - } - } - - // Trim each of the 256 subdirectories. - // We subtract an additional mtimeInterval - // to account for the imprecision of our "last used" mtimes. - cutoff := now.Add(-trimLimit - mtimeInterval) - for i := 0; i < 256; i++ { - subdir := filepath.Join(c.dir, fmt.Sprintf("%02x", i)) - c.trimSubdir(subdir, cutoff) - } - - // Ignore errors from here: if we don't write the complete timestamp, the - // cache will appear older than it is, and we'll trim it again next time. - var b bytes.Buffer - fmt.Fprintf(&b, "%d", now.Unix()) - if err := lockedfile.Write(filepath.Join(c.dir, "trim.txt"), &b, 0o666); err != nil { - return err - } - - return nil -} - -// trimSubdir trims a single cache subdirectory. -func (c *DiskCache) trimSubdir(subdir string, cutoff time.Time) { - // Read all directory entries from subdir before removing - // any files, in case removing files invalidates the file offset - // in the directory scan. Also, ignore error from f.Readdirnames, - // because we don't care about reporting the error and we still - // want to process any entries found before the error. - f, err := os.Open(subdir) - if err != nil { - return - } - names, _ := f.Readdirnames(-1) - f.Close() - - for _, name := range names { - // Remove only cache entries (xxxx-a and xxxx-d). - if !strings.HasSuffix(name, "-a") && !strings.HasSuffix(name, "-d") { - continue - } - entry := filepath.Join(subdir, name) - info, err := os.Stat(entry) - if err == nil && info.ModTime().Before(cutoff) { - if info.IsDir() { // executable cache entry - os.RemoveAll(entry) - continue - } - os.Remove(entry) - } - } -} - -// putIndexEntry adds an entry to the cache recording that executing the action -// with the given id produces an output with the given output id (hash) and size. -func (c *DiskCache) putIndexEntry(id ActionID, out OutputID, size int64, allowVerify bool) error { - // Note: We expect that for one reason or another it may happen - // that repeating an action produces a different output hash - // (for example, if the output contains a time stamp or temp dir name). - // While not ideal, this is also not a correctness problem, so we - // don't make a big deal about it. In particular, we leave the action - // cache entries writable specifically so that they can be overwritten. - // - // Setting GODEBUG=gocacheverify=1 does make a big deal: - // in verify mode we are double-checking that the cache entries - // are entirely reproducible. As just noted, this may be unrealistic - // in some cases but the check is also useful for shaking out real bugs. - entry := fmt.Sprintf("v1 %x %x %20d %20d\n", id, out, size, time.Now().UnixNano()) - if verify && allowVerify { - old, err := c.get(id) - if err == nil && (old.OutputID != out || old.Size != size) { - // panic to show stack trace, so we can see what code is generating this cache entry. - msg := fmt.Sprintf("go: internal cache error: cache verify failed: id=%x changed:<<<\n%s\n>>>\nold: %x %d\nnew: %x %d", id, reverseHash(id), out, size, old.OutputID, old.Size) - panic(msg) - } - } - file := c.fileName(id, "a") - - // Copy file to cache directory. - mode := os.O_WRONLY | os.O_CREATE - f, err := os.OpenFile(file, mode, 0o666) - if err != nil { - return err - } - _, err = f.WriteString(entry) - if err == nil { - // Truncate the file only *after* writing it. - // (This should be a no-op, but truncate just in case of previous corruption.) - // - // This differs from os.WriteFile, which truncates to 0 *before* writing - // via os.O_TRUNC. Truncating only after writing ensures that a second write - // of the same content to the same file is idempotent, and does not — even - // temporarily! — undo the effect of the first write. - err = f.Truncate(int64(len(entry))) - } - if closeErr := f.Close(); err == nil { - err = closeErr - } - if err != nil { - // TODO(bcmills): This Remove potentially races with another go command writing to file. - // Can we eliminate it? - os.Remove(file) - return err - } - err = os.Chtimes(file, c.now(), c.now()) // mainly for tests - if err != nil { - return fmt.Errorf("failed to change time of file %s: %w", file, err) - } - - return nil -} - -// noVerifyReadSeeker is an io.ReadSeeker wrapper sentinel type -// that says that Cache.Put should skip the verify check -// (from GODEBUG=goverifycache=1). -type noVerifyReadSeeker struct { - io.ReadSeeker -} - -// Put stores the given output in the cache as the output for the action ID. -// It may read file twice. The content of file must not change between the two passes. -func (c *DiskCache) Put(id ActionID, file io.ReadSeeker) (OutputID, int64, error) { - wrapper, isNoVerify := file.(noVerifyReadSeeker) - if isNoVerify { - file = wrapper.ReadSeeker - } - return c.put(id, "", file, !isNoVerify) -} - -// PutExecutable is used to store the output as the output for the action ID into a -// file with the given base name, with the executable mode bit set. -// It may read file twice. The content of file must not change between the two passes. -func (c *DiskCache) PutExecutable(id ActionID, name string, file io.ReadSeeker) (OutputID, int64, error) { - if name == "" { - panic("PutExecutable called without a name") - } - wrapper, isNoVerify := file.(noVerifyReadSeeker) - if isNoVerify { - file = wrapper.ReadSeeker - } - return c.put(id, name, file, !isNoVerify) -} - -// PutNoVerify is like Put but disables the verify check -// when GODEBUG=goverifycache=1 is set. -// It is meant for data that is OK to cache but that we expect to vary slightly from run to run, -// like test output containing times and the like. -func PutNoVerify(c Cache, id ActionID, file io.ReadSeeker) (OutputID, int64, error) { - return c.Put(id, noVerifyReadSeeker{file}) -} - -func (c *DiskCache) put(id ActionID, executableName string, file io.ReadSeeker, allowVerify bool) (OutputID, int64, error) { - // Compute output ID. - h := sha256.New() - if _, err := file.Seek(0, 0); err != nil { - return OutputID{}, 0, err - } - size, err := io.Copy(h, file) - if err != nil { - return OutputID{}, 0, err - } - var out OutputID - h.Sum(out[:0]) - - // Copy to cached output file (if not already present). - fileMode := fs.FileMode(0o666) - if executableName != "" { - fileMode = 0o777 - } - if err := c.copyFile(file, executableName, out, size, fileMode); err != nil { - return out, size, err - } - - // Add to cache index. - return out, size, c.putIndexEntry(id, out, size, allowVerify) -} - -// PutBytes stores the given bytes in the cache as the output for the action ID. -func PutBytes(c Cache, id ActionID, data []byte) error { - _, _, err := c.Put(id, bytes.NewReader(data)) - return err -} - -// copyFile copies file into the cache, expecting it to have the given -// output ID and size, if that file is not present already. -func (c *DiskCache) copyFile(file io.ReadSeeker, executableName string, out OutputID, size int64, perm os.FileMode) error { - name := c.fileName(out, "d") // TODO(matloob): use a different suffix for the executable cache? - info, err := os.Stat(name) - if executableName != "" { - // This is an executable file. The file at name won't hold the output itself, but will - // be a directory that holds the output, named according to executableName. Check to see - // if the directory already exists, and if it does not, create it. Then reset name - // to the name we want the output written to. - if err != nil { - if !os.IsNotExist(err) { - return err - } - if err := os.Mkdir(name, 0o777); err != nil { - return err - } - if info, err = os.Stat(name); err != nil { - return err - } - } - if !info.IsDir() { - return errors.New("internal error: invalid binary cache entry: not a directory") - } - - // directory exists. now set name to the inner file - name = filepath.Join(name, executableName) - info, err = os.Stat(name) - } - if err == nil && info.Size() == size { - // Check hash. - if f, err := os.Open(name); err == nil { - h := sha256.New() - _, copyErr := io.Copy(h, f) - if copyErr != nil { - return fmt.Errorf("failed to copy to sha256: %w", copyErr) - } - - f.Close() - var out2 OutputID - h.Sum(out2[:0]) - if out == out2 { - return nil - } - } - // Hash did not match. Fall through and rewrite file. - } - - // Copy file to cache directory. - mode := os.O_RDWR | os.O_CREATE - if err == nil && info.Size() > size { // shouldn't happen but fix in case - mode |= os.O_TRUNC - } - f, err := os.OpenFile(name, mode, perm) - if err != nil { - if base.IsETXTBSY(err) { - // This file is being used by an executable. It must have - // already been written by another go process and then run. - // return without an error. - return nil - } - return err - } - defer f.Close() - if size == 0 { - // File now exists with correct size. - // Only one possible zero-length file, so contents are OK too. - // Early return here makes sure there's a "last byte" for code below. - return nil - } - - // From here on, if any of the I/O writing the file fails, - // we make a best-effort attempt to truncate the file f - // before returning, to avoid leaving bad bytes in the file. - - // Copy file to f, but also into h to double-check hash. - if _, err := file.Seek(0, 0); err != nil { - f.Truncate(0) - return err - } - h := sha256.New() - w := io.MultiWriter(f, h) - if _, err := io.CopyN(w, file, size-1); err != nil { - f.Truncate(0) - return err - } - // Check last byte before writing it; writing it will make the size match - // what other processes expect to find and might cause them to start - // using the file. - buf := make([]byte, 1) - if _, err := file.Read(buf); err != nil { - f.Truncate(0) - return err - } - n, wErr := h.Write(buf) - if n != len(buf) { - return fmt.Errorf("wrote to hash %d/%d bytes with error %w", n, len(buf), wErr) - } - - sum := h.Sum(nil) - if !bytes.Equal(sum, out[:]) { - f.Truncate(0) - return fmt.Errorf("file content changed underfoot") - } - - // Commit cache file entry. - if _, err := f.Write(buf); err != nil { - f.Truncate(0) - return err - } - if err := f.Close(); err != nil { - // Data might not have been written, - // but file may look like it is the right size. - // To be extra careful, remove cached file. - os.Remove(name) - return err - } - err = os.Chtimes(name, c.now(), c.now()) // mainly for tests - if err != nil { - return fmt.Errorf("failed to change time of file %s: %w", name, err) - } - - return nil -} - -// FuzzDir returns a subdirectory within the cache for storing fuzzing data. -// The subdirectory may not exist. -// -// This directory is managed by the internal/fuzz package. Files in this -// directory aren't removed by the 'go clean -cache' command or by Trim. -// They may be removed with 'go clean -fuzzcache'. -// -// TODO(#48526): make Trim remove unused files from this directory. -func (c *DiskCache) FuzzDir() string { - return filepath.Join(c.dir, "fuzz") -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/cache_gcil.go b/vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/cache_gcil.go deleted file mode 100644 index b4f07738e6..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/cache_gcil.go +++ /dev/null @@ -1,12 +0,0 @@ -package cache - -import ( - "errors" -) - -// IsErrMissing allows to access to the internal error. -// TODO(ldez) the handling of this error inside runner_action.go should be refactored. -func IsErrMissing(err error) bool { - var errENF *entryNotFoundError - return errors.As(err, &errENF) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/default.go b/vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/default.go deleted file mode 100644 index cf38ab3d7b..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/default.go +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cache - -import ( - "fmt" - base "log" - "os" - "path/filepath" - "sync" -) - -// Default returns the default cache to use. -// It never returns nil. -func Default() Cache { - return initDefaultCacheOnce() -} - -var initDefaultCacheOnce = sync.OnceValue(initDefaultCache) - -// cacheREADME is a message stored in a README in the cache directory. -// Because the cache lives outside the normal Go trees, we leave the -// README as a courtesy to explain where it came from. -const cacheREADME = `This directory holds cached build artifacts from golangci-lint. -` - -// initDefaultCache does the work of finding the default cache -// the first time Default is called. -func initDefaultCache() Cache { - dir, _ := DefaultDir() - if dir == "off" { - if defaultDirErr != nil { - base.Fatalf("build cache is required, but could not be located: %v", defaultDirErr) - } - base.Fatalf("build cache is disabled by %s=off, but required as of Go 1.12", envGolangciLintCache) - } - if err := os.MkdirAll(dir, 0o777); err != nil { - base.Fatalf("failed to initialize build cache at %s: %s\n", dir, err) - } - if _, err := os.Stat(filepath.Join(dir, "README")); err != nil { - // Best effort. - os.WriteFile(filepath.Join(dir, "README"), []byte(cacheREADME), 0666) - } - - diskCache, err := Open(dir) - if err != nil { - base.Fatalf("failed to initialize build cache at %s: %s\n", dir, err) - } - - if v := os.Getenv(envGolangciLintCacheProg); v != "" { - return startCacheProg(v, diskCache) - } - - return diskCache -} - -var ( - defaultDirOnce sync.Once - defaultDir string - defaultDirChanged bool // effective value differs from $GOLANGCI_LINT_CACHE - defaultDirErr error -) - -// DefaultDir returns the effective GOLANGCI_LINT_CACHE setting. -// It returns "off" if the cache is disabled, -// and reports whether the effective value differs from GOLANGCI_LINT_CACHE. -func DefaultDir() (string, bool) { - // Save the result of the first call to DefaultDir for later use in - // initDefaultCache. cmd/go/main.go explicitly sets GOLANGCI_LINT_CACHE so that - // subprocesses will inherit it, but that means initDefaultCache can't - // otherwise distinguish between an explicit "off" and a UserCacheDir error. - - defaultDirOnce.Do(func() { - defaultDir = os.Getenv(envGolangciLintCache) - if defaultDir != "" { - defaultDirChanged = true - if filepath.IsAbs(defaultDir) || defaultDir == "off" { - return - } - defaultDir = "off" - defaultDirErr = fmt.Errorf("%s is not an absolute path", envGolangciLintCache) - return - } - - // Compute default location. - dir, err := os.UserCacheDir() - if err != nil { - defaultDir = "off" - defaultDirChanged = true - defaultDirErr = fmt.Errorf("%s is not defined and %w", envGolangciLintCache, err) - return - } - defaultDir = filepath.Join(dir, "golangci-lint") - }) - - return defaultDir, defaultDirChanged -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/default_gcil.go b/vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/default_gcil.go deleted file mode 100644 index a801f67f47..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/default_gcil.go +++ /dev/null @@ -1,6 +0,0 @@ -package cache - -const ( - envGolangciLintCache = "GOLANGCI_LINT_CACHE" - envGolangciLintCacheProg = "GOLANGCI_LINT_CACHEPROG" -) diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/hash.go b/vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/hash.go deleted file mode 100644 index 6a53dd8867..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/hash.go +++ /dev/null @@ -1,192 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cache - -import ( - "bytes" - "crypto/sha256" - "fmt" - "hash" - "io" - "os" - "strings" - "sync" -) - -var debugHash = false // set when GODEBUG=gocachehash=1 - -// HashSize is the number of bytes in a hash. -const HashSize = 32 - -// A Hash provides access to the canonical hash function used to index the cache. -// The current implementation uses salted SHA256, but clients must not assume this. -type Hash struct { - h hash.Hash - name string // for debugging - buf *bytes.Buffer // for verify -} - -// hashSalt is a salt string added to the beginning of every hash -// created by NewHash. Using the golangci-lint version makes sure that different -// versions of the command do not address the same cache -// entries, so that a bug in one version does not affect the execution -// of other versions. This salt will result in additional ActionID files -// in the cache, but not additional copies of the large output files, -// which are still addressed by unsalted SHA256. -var hashSalt []byte - -// stripExperiment strips any GOEXPERIMENT configuration from the Go -// version string. -func stripExperiment(version string) string { - if i := strings.Index(version, " X:"); i >= 0 { - return version[:i] - } - return version -} - -// Subkey returns an action ID corresponding to mixing a parent -// action ID with a string description of the subkey. -func Subkey(parent ActionID, desc string) (ActionID, error) { - h := sha256.New() - h.Write([]byte("subkey:")) - n, err := h.Write(parent[:]) - if n != len(parent) { - return ActionID{}, fmt.Errorf("wrote %d/%d bytes of parent with error %s", n, len(parent), err) - } - n, err = h.Write([]byte(desc)) - if n != len(desc) { - return ActionID{}, fmt.Errorf("wrote %d/%d bytes of desc with error %s", n, len(desc), err) - } - - var out ActionID - h.Sum(out[:0]) - if debugHash { - fmt.Fprintf(os.Stderr, "HASH subkey %x %q = %x\n", parent, desc, out) - } - if verify { - hashDebug.Lock() - hashDebug.m[out] = fmt.Sprintf("subkey %x %q", parent, desc) - hashDebug.Unlock() - } - return out, nil -} - -// NewHash returns a new Hash. -// The caller is expected to Write data to it and then call Sum. -func NewHash(name string) (*Hash, error) { - h := &Hash{h: sha256.New(), name: name} - if debugHash { - fmt.Fprintf(os.Stderr, "HASH[%s]\n", h.name) - } - n, err := h.Write(hashSalt) - if n != len(hashSalt) { - return nil, fmt.Errorf("wrote %d/%d bytes of hash salt with error %s", n, len(hashSalt), err) - } - if verify { - h.buf = new(bytes.Buffer) - } - return h, nil -} - -// Write writes data to the running hash. -func (h *Hash) Write(b []byte) (int, error) { - if debugHash { - fmt.Fprintf(os.Stderr, "HASH[%s]: %q\n", h.name, b) - } - if h.buf != nil { - h.buf.Write(b) - } - return h.h.Write(b) -} - -// Sum returns the hash of the data written previously. -func (h *Hash) Sum() [HashSize]byte { - var out [HashSize]byte - h.h.Sum(out[:0]) - if debugHash { - fmt.Fprintf(os.Stderr, "HASH[%s]: %x\n", h.name, out) - } - if h.buf != nil { - hashDebug.Lock() - if hashDebug.m == nil { - hashDebug.m = make(map[[HashSize]byte]string) - } - hashDebug.m[out] = h.buf.String() - hashDebug.Unlock() - } - return out -} - -// In GODEBUG=gocacheverify=1 mode, -// hashDebug holds the input to every computed hash ID, -// so that we can work backward from the ID involved in a -// cache entry mismatch to a description of what should be there. -var hashDebug struct { - sync.Mutex - m map[[HashSize]byte]string -} - -// reverseHash returns the input used to compute the hash id. -func reverseHash(id [HashSize]byte) string { - hashDebug.Lock() - s := hashDebug.m[id] - hashDebug.Unlock() - return s -} - -var hashFileCache struct { - sync.Mutex - m map[string][HashSize]byte -} - -// FileHash returns the hash of the named file. -// It caches repeated lookups for a given file, -// and the cache entry for a file can be initialized -// using SetFileHash. -// The hash used by FileHash is not the same as -// the hash used by NewHash. -func FileHash(file string) ([HashSize]byte, error) { - hashFileCache.Lock() - out, ok := hashFileCache.m[file] - hashFileCache.Unlock() - - if ok { - return out, nil - } - - h := sha256.New() - f, err := os.Open(file) - if err != nil { - if debugHash { - fmt.Fprintf(os.Stderr, "HASH %s: %v\n", file, err) - } - return [HashSize]byte{}, err - } - _, err = io.Copy(h, f) - f.Close() - if err != nil { - if debugHash { - fmt.Fprintf(os.Stderr, "HASH %s: %v\n", file, err) - } - return [HashSize]byte{}, err - } - h.Sum(out[:0]) - if debugHash { - fmt.Fprintf(os.Stderr, "HASH %s: %x\n", file, out) - } - - SetFileHash(file, out) - return out, nil -} - -// SetFileHash sets the hash returned by FileHash for file. -func SetFileHash(file string, sum [HashSize]byte) { - hashFileCache.Lock() - if hashFileCache.m == nil { - hashFileCache.m = make(map[string][HashSize]byte) - } - hashFileCache.m[file] = sum - hashFileCache.Unlock() -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/hash_gcil.go b/vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/hash_gcil.go deleted file mode 100644 index 08749036bd..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/hash_gcil.go +++ /dev/null @@ -1,5 +0,0 @@ -package cache - -func SetSalt(b []byte) { - hashSalt = b -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/prog.go b/vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/prog.go deleted file mode 100644 index dc44e1385b..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/prog.go +++ /dev/null @@ -1,375 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cache - -import ( - "bufio" - "context" - "crypto/sha256" - "encoding/base64" - "encoding/json" - "errors" - "fmt" - "io" - "log" - base "log" - "os" - "os/exec" - "sync" - "sync/atomic" - "time" - - "github.com/golangci/golangci-lint/v2/internal/go/cacheprog" - "github.com/golangci/golangci-lint/v2/internal/go/quoted" -) - -// ProgCache implements Cache via JSON messages over stdin/stdout to a child -// helper process which can then implement whatever caching policy/mechanism it -// wants. -// -// See https://github.com/golang/go/issues/59719 -type ProgCache struct { - cmd *exec.Cmd - stdout io.ReadCloser // from the child process - stdin io.WriteCloser // to the child process - bw *bufio.Writer // to stdin - jenc *json.Encoder // to bw - - // can are the commands that the child process declared that it supports. - // This is effectively the versioning mechanism. - can map[cacheprog.Cmd]bool - - // fuzzDirCache is another Cache implementation to use for the FuzzDir - // method. In practice this is the default GOCACHE disk-based - // implementation. - // - // TODO(bradfitz): maybe this isn't ideal. But we'd need to extend the Cache - // interface and the fuzzing callers to be less disk-y to do more here. - fuzzDirCache Cache - - closing atomic.Bool - ctx context.Context // valid until Close via ctxClose - ctxCancel context.CancelFunc // called on Close - readLoopDone chan struct{} // closed when readLoop returns - - mu sync.Mutex // guards following fields - nextID int64 - inFlight map[int64]chan<- *cacheprog.Response - outputFile map[OutputID]string // object => abs path on disk - - // writeMu serializes writing to the child process. - // It must never be held at the same time as mu. - writeMu sync.Mutex -} - -// startCacheProg starts the prog binary (with optional space-separated flags) -// and returns a Cache implementation that talks to it. -// -// It blocks a few seconds to wait for the child process to successfully start -// and advertise its capabilities. -func startCacheProg(progAndArgs string, fuzzDirCache Cache) Cache { - if fuzzDirCache == nil { - panic("missing fuzzDirCache") - } - args, err := quoted.Split(progAndArgs) - if err != nil { - base.Fatalf("%s args: %v", envGolangciLintCacheProg, err) - } - var prog string - if len(args) > 0 { - prog = args[0] - args = args[1:] - } - - ctx, ctxCancel := context.WithCancel(context.Background()) - - cmd := exec.CommandContext(ctx, prog, args...) - out, err := cmd.StdoutPipe() - if err != nil { - base.Fatalf("StdoutPipe to %s: envGolangciLintCacheProg, %v", envGolangciLintCacheProg, err) - } - in, err := cmd.StdinPipe() - if err != nil { - base.Fatalf("StdinPipe to %s: envGolangciLintCacheProg, %v", envGolangciLintCacheProg, err) - } - cmd.Stderr = os.Stderr - // On close, we cancel the context. Rather than killing the helper, - // close its stdin. - cmd.Cancel = in.Close - - if err := cmd.Start(); err != nil { - base.Fatalf("error starting %s program %q: %v", envGolangciLintCacheProg, prog, err) - } - - pc := &ProgCache{ - ctx: ctx, - ctxCancel: ctxCancel, - fuzzDirCache: fuzzDirCache, - cmd: cmd, - stdout: out, - stdin: in, - bw: bufio.NewWriter(in), - inFlight: make(map[int64]chan<- *cacheprog.Response), - outputFile: make(map[OutputID]string), - readLoopDone: make(chan struct{}), - } - - // Register our interest in the initial protocol message from the child to - // us, saying what it can do. - capResc := make(chan *cacheprog.Response, 1) - pc.inFlight[0] = capResc - - pc.jenc = json.NewEncoder(pc.bw) - go pc.readLoop(pc.readLoopDone) - - // Give the child process a few seconds to report its capabilities. This - // should be instant and not require any slow work by the program. - timer := time.NewTicker(5 * time.Second) - defer timer.Stop() - for { - select { - case <-timer.C: - log.Printf("# still waiting for %s %v ...", envGolangciLintCacheProg, prog) - case capRes := <-capResc: - can := map[cacheprog.Cmd]bool{} - for _, cmd := range capRes.KnownCommands { - can[cmd] = true - } - if len(can) == 0 { - base.Fatalf("%s %v declared no supported commands", envGolangciLintCacheProg, prog) - } - pc.can = can - return pc - } - } -} - -func (c *ProgCache) readLoop(readLoopDone chan<- struct{}) { - defer close(readLoopDone) - jd := json.NewDecoder(c.stdout) - for { - res := new(cacheprog.Response) - if err := jd.Decode(res); err != nil { - if c.closing.Load() { - c.mu.Lock() - for _, ch := range c.inFlight { - close(ch) - } - c.inFlight = nil - c.mu.Unlock() - return // quietly - } - if err == io.EOF { - c.mu.Lock() - inFlight := len(c.inFlight) - c.mu.Unlock() - base.Fatalf("%s exited pre-Close with %v pending requests", envGolangciLintCacheProg, inFlight) - } - base.Fatalf("error reading JSON from %s: %v", envGolangciLintCacheProg, err) - } - c.mu.Lock() - ch, ok := c.inFlight[res.ID] - delete(c.inFlight, res.ID) - c.mu.Unlock() - if ok { - ch <- res - } else { - base.Fatalf("%s sent response for unknown request ID %v", envGolangciLintCacheProg, res.ID) - } - } -} - -var errCacheprogClosed = fmt.Errorf("%s program closed unexpectedly", envGolangciLintCacheProg) - -func (c *ProgCache) send(ctx context.Context, req *cacheprog.Request) (*cacheprog.Response, error) { - resc := make(chan *cacheprog.Response, 1) - if err := c.writeToChild(req, resc); err != nil { - return nil, err - } - select { - case res := <-resc: - if res == nil { - return nil, errCacheprogClosed - } - if res.Err != "" { - return nil, errors.New(res.Err) - } - return res, nil - case <-ctx.Done(): - return nil, ctx.Err() - } -} - -func (c *ProgCache) writeToChild(req *cacheprog.Request, resc chan<- *cacheprog.Response) (err error) { - c.mu.Lock() - if c.inFlight == nil { - return errCacheprogClosed - } - c.nextID++ - req.ID = c.nextID - c.inFlight[req.ID] = resc - c.mu.Unlock() - - defer func() { - if err != nil { - c.mu.Lock() - if c.inFlight != nil { - delete(c.inFlight, req.ID) - } - c.mu.Unlock() - } - }() - - c.writeMu.Lock() - defer c.writeMu.Unlock() - - if err := c.jenc.Encode(req); err != nil { - return err - } - if err := c.bw.WriteByte('\n'); err != nil { - return err - } - if req.Body != nil && req.BodySize > 0 { - if err := c.bw.WriteByte('"'); err != nil { - return err - } - e := base64.NewEncoder(base64.StdEncoding, c.bw) - wrote, err := io.Copy(e, req.Body) - if err != nil { - return err - } - if err := e.Close(); err != nil { - return nil - } - if wrote != req.BodySize { - return fmt.Errorf("short write writing body to %s for action %x, output %x: wrote %v; expected %v", - envGolangciLintCacheProg, req.ActionID, req.OutputID, wrote, req.BodySize) - } - if _, err := c.bw.WriteString("\"\n"); err != nil { - return err - } - } - if err := c.bw.Flush(); err != nil { - return err - } - return nil -} - -func (c *ProgCache) Get(a ActionID) (Entry, error) { - if !c.can[cacheprog.CmdGet] { - // They can't do a "get". Maybe they're a write-only cache. - // - // TODO(bradfitz,bcmills): figure out the proper error type here. Maybe - // errors.ErrUnsupported? Is entryNotFoundError even appropriate? There - // might be places where we rely on the fact that a recent Put can be - // read through a corresponding Get. Audit callers and check, and document - // error types on the Cache interface. - return Entry{}, &entryNotFoundError{} - } - res, err := c.send(c.ctx, &cacheprog.Request{ - Command: cacheprog.CmdGet, - ActionID: a[:], - }) - if err != nil { - return Entry{}, err // TODO(bradfitz): or entryNotFoundError? Audit callers. - } - if res.Miss { - return Entry{}, &entryNotFoundError{} - } - e := Entry{ - Size: res.Size, - } - if res.Time != nil { - e.Time = *res.Time - } else { - e.Time = time.Now() - } - if res.DiskPath == "" { - return Entry{}, &entryNotFoundError{fmt.Errorf("%s didn't populate DiskPath on get hit", envGolangciLintCacheProg)} - } - if copy(e.OutputID[:], res.OutputID) != len(res.OutputID) { - return Entry{}, &entryNotFoundError{errors.New("incomplete ProgResponse OutputID")} - } - c.noteOutputFile(e.OutputID, res.DiskPath) - return e, nil -} - -func (c *ProgCache) noteOutputFile(o OutputID, diskPath string) { - c.mu.Lock() - defer c.mu.Unlock() - c.outputFile[o] = diskPath -} - -func (c *ProgCache) OutputFile(o OutputID) string { - c.mu.Lock() - defer c.mu.Unlock() - return c.outputFile[o] -} - -func (c *ProgCache) Put(a ActionID, file io.ReadSeeker) (_ OutputID, size int64, _ error) { - // Compute output ID. - h := sha256.New() - if _, err := file.Seek(0, 0); err != nil { - return OutputID{}, 0, err - } - size, err := io.Copy(h, file) - if err != nil { - return OutputID{}, 0, err - } - var out OutputID - h.Sum(out[:0]) - - if _, err := file.Seek(0, 0); err != nil { - return OutputID{}, 0, err - } - - if !c.can[cacheprog.CmdPut] { - // Child is a read-only cache. Do nothing. - return out, size, nil - } - - res, err := c.send(c.ctx, &cacheprog.Request{ - Command: cacheprog.CmdPut, - ActionID: a[:], - OutputID: out[:], - Body: file, - BodySize: size, - }) - if err != nil { - return OutputID{}, 0, err - } - if res.DiskPath == "" { - return OutputID{}, 0, fmt.Errorf("%s didn't return DiskPath in put response", envGolangciLintCacheProg) - } - c.noteOutputFile(out, res.DiskPath) - return out, size, err -} - -func (c *ProgCache) Close() error { - c.closing.Store(true) - var err error - - // First write a "close" message to the child so it can exit nicely - // and clean up if it wants. Only after that exchange do we cancel - // the context that kills the process. - if c.can[cacheprog.CmdClose] { - _, err = c.send(c.ctx, &cacheprog.Request{Command: cacheprog.CmdClose}) - if errors.Is(err, errCacheprogClosed) { - // Allow the child to quit without responding to close. - err = nil - } - } - // Cancel the context, which will close the helper's stdin. - c.ctxCancel() - // Wait until the helper closes its stdout. - <-c.readLoopDone - return err -} - -func (c *ProgCache) FuzzDir() string { - // TODO(bradfitz): figure out what to do here. For now just use the - // disk-based default. - return c.fuzzDirCache.FuzzDir() -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/readme.md b/vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/readme.md deleted file mode 100644 index 66341fd4b8..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/go/cache/readme.md +++ /dev/null @@ -1,53 +0,0 @@ -# cache - -Extracted from `go/src/cmd/go/internal/cache/`. - -The main modifications are: -- The errors management - - Some methods return error. - - Some errors are returned instead of being ignored. -- The name of the env vars: - - `GOCACHE` -> `GOLANGCI_LINT_CACHE` - - `GOCACHEPROG` -> `GOLANGCI_LINT_CACHEPROG` - -## History - -- https://github.com/golangci/golangci-lint/pull/5576 - - sync go1.24.1 -- https://github.com/golangci/golangci-lint/pull/5100 - - Move package from `internal/cache` to `internal/go/cache` -- https://github.com/golangci/golangci-lint/pull/5098 - - sync with go1.23.2 - - sync with go1.22.8 - - sync with go1.21.13 - - sync with go1.20.14 - - sync with go1.19.13 - - sync with go1.18.10 - - sync with go1.17.13 - - sync with go1.16.15 - - sync with go1.15.15 - - sync with go1.14.15 - -## Previous History - -Based on the initial PR/commit the based in a mix between go1.12 and go1.13: -- cache.go (go1.13) -- cache_test.go (go1.12?) -- default.go (go1.12?) -- hash.go (go1.13 and go1.12 are identical) -- hash_test.go -> (go1.12?) - -Adapted for golangci-lint: -- https://github.com/golangci/golangci-lint/pull/699: initial code (contains modifications of the files) -- https://github.com/golangci/golangci-lint/pull/779: just a nolint (`cache.go`) -- https://github.com/golangci/golangci-lint/pull/788: only directory permissions changes (0777 -> 0744) (`cache.go`, `cache_test.go`, `default.go`) -- https://github.com/golangci/golangci-lint/pull/808: mainly related to logs and errors (`cache.go`, `default.go`, `hash.go`, `hash_test.go`) -- https://github.com/golangci/golangci-lint/pull/1063: `ioutil` -> `robustio` (`cache.go`) -- https://github.com/golangci/golangci-lint/pull/1070: add `t.Parallel()` inside `cache_test.go` -- https://github.com/golangci/golangci-lint/pull/1162: errors inside `cache.go` -- https://github.com/golangci/golangci-lint/pull/2318: `ioutil` -> `os` (`cache.go`, `cache_test.go`, `default.go`, `hash_test.go`) -- https://github.com/golangci/golangci-lint/pull/2352: Go doc typos -- https://github.com/golangci/golangci-lint/pull/3012: errors inside `cache.go` (`cache.go`, `default.go`) -- https://github.com/golangci/golangci-lint/pull/3196: constant for `GOLANGCI_LINT_CACHE` (`cache.go`) -- https://github.com/golangci/golangci-lint/pull/3204: add this file and `%w` in `fmt.Errorf` (`cache.go`) -- https://github.com/golangci/golangci-lint/pull/3604: remove `github.com/pkg/errors` (`cache.go`) diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/go/cacheprog/cacheprog.go b/vendor/github.com/golangci/golangci-lint/v2/internal/go/cacheprog/cacheprog.go deleted file mode 100644 index a2796592df..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/go/cacheprog/cacheprog.go +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright 2024 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package cacheprog defines the protocol for a GOCACHEPROG program. -// -// By default, the go command manages a build cache stored in the file system -// itself. GOCACHEPROG can be set to the name of a command (with optional -// space-separated flags) that implements the go command build cache externally. -// This permits defining a different cache policy. -// -// The go command will start the GOCACHEPROG as a subprocess and communicate -// with it via JSON messages over stdin/stdout. The subprocess's stderr will be -// connected to the go command's stderr. -// -// The subprocess should immediately send a [Response] with its capabilities. -// After that, the go command will send a stream of [Request] messages and the -// subprocess should reply to each [Request] with a [Response] message. -package cacheprog - -import ( - "io" - "time" -) - -// Cmd is a command that can be issued to a child process. -// -// If the interface needs to grow, the go command can add new commands or new -// versioned commands like "get2" in the future. The initial [Response] from -// the child process indicates which commands it supports. -type Cmd string - -const ( - // CmdPut tells the cache program to store an object in the cache. - // - // [Request.ActionID] is the cache key of this object. The cache should - // store [Request.OutputID] and [Request.Body] under this key for a - // later "get" request. It must also store the Body in a file in the local - // file system and return the path to that file in [Response.DiskPath], - // which must exist at least until a "close" request. - CmdPut = Cmd("put") - - // CmdGet tells the cache program to retrieve an object from the cache. - // - // [Request.ActionID] specifies the key of the object to get. If the - // cache does not contain this object, it should set [Response.Miss] to - // true. Otherwise, it should populate the fields of [Response], - // including setting [Response.OutputID] to the OutputID of the original - // "put" request and [Response.DiskPath] to the path of a local file - // containing the Body of the original "put" request. That file must - // continue to exist at least until a "close" request. - CmdGet = Cmd("get") - - // CmdClose requests that the cache program exit gracefully. - // - // The cache program should reply to this request and then exit - // (thus closing its stdout). - CmdClose = Cmd("close") -) - -// Request is the JSON-encoded message that's sent from the go command to -// the GOCACHEPROG child process over stdin. Each JSON object is on its own -// line. A ProgRequest of Type "put" with BodySize > 0 will be followed by a -// line containing a base64-encoded JSON string literal of the body. -type Request struct { - // ID is a unique number per process across all requests. - // It must be echoed in the Response from the child. - ID int64 - - // Command is the type of request. - // The go command will only send commands that were declared - // as supported by the child. - Command Cmd - - // ActionID is the cache key for "put" and "get" requests. - ActionID []byte `json:",omitempty"` // or nil if not used - - // OutputID is stored with the body for "put" requests. - // - // Prior to Go 1.24, when GOCACHEPROG was still an experiment, this was - // accidentally named ObjectID. It was renamed to OutputID in Go 1.24. - OutputID []byte `json:",omitempty"` // or nil if not used - - // Body is the body for "put" requests. It's sent after the JSON object - // as a base64-encoded JSON string when BodySize is non-zero. - // It's sent as a separate JSON value instead of being a struct field - // send in this JSON object so large values can be streamed in both directions. - // The base64 string body of a Request will always be written - // immediately after the JSON object and a newline. - Body io.Reader `json:"-"` - - // BodySize is the number of bytes of Body. If zero, the body isn't written. - BodySize int64 `json:",omitempty"` - - // ObjectID is the accidental spelling of OutputID that was used prior to Go - // 1.24. - // - // Deprecated: use OutputID. This field is only populated temporarily for - // backwards compatibility with Go 1.23 and earlier when - // GOEXPERIMENT=gocacheprog is set. It will be removed in Go 1.25. - ObjectID []byte `json:",omitempty"` -} - -// Response is the JSON response from the child process to the go command. -// -// With the exception of the first protocol message that the child writes to its -// stdout with ID==0 and KnownCommands populated, these are only sent in -// response to a Request from the go command. -// -// Responses can be sent in any order. The ID must match the request they're -// replying to. -type Response struct { - ID int64 // that corresponds to Request; they can be answered out of order - Err string `json:",omitempty"` // if non-empty, the error - - // KnownCommands is included in the first message that cache helper program - // writes to stdout on startup (with ID==0). It includes the - // Request.Command types that are supported by the program. - // - // This lets the go command extend the protocol gracefully over time (adding - // "get2", etc), or fail gracefully when needed. It also lets the go command - // verify the program wants to be a cache helper. - KnownCommands []Cmd `json:",omitempty"` - - // For "get" requests. - - Miss bool `json:",omitempty"` // cache miss - OutputID []byte `json:",omitempty"` // the ObjectID stored with the body - Size int64 `json:",omitempty"` // body size in bytes - Time *time.Time `json:",omitempty"` // when the object was put in the cache (optional; used for cache expiration) - - // For "get" and "put" requests. - - // DiskPath is the absolute path on disk of the body corresponding to a - // "get" (on cache hit) or "put" request's ActionID. - DiskPath string `json:",omitempty"` -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/go/cacheprog/readme.md b/vendor/github.com/golangci/golangci-lint/v2/internal/go/cacheprog/readme.md deleted file mode 100644 index 1b08c84806..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/go/cacheprog/readme.md +++ /dev/null @@ -1,9 +0,0 @@ -# quoted - -Extracted from `go/src/cmd/go/internal/cacheprog/` (related to `cache`). -This is just a copy of the Go code without any changes. - -## History - -- https://github.com/golangci/golangci-lint/pull/5576 - - sync go1.24.1 diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/go/mmap/mmap.go b/vendor/github.com/golangci/golangci-lint/v2/internal/go/mmap/mmap.go deleted file mode 100644 index fd374df82e..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/go/mmap/mmap.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This package is a lightly modified version of the mmap code -// in github.com/google/codesearch/index. - -// The mmap package provides an abstraction for memory mapping files -// on different platforms. -package mmap - -import ( - "os" -) - -// Data is mmap'ed read-only data from a file. -// The backing file is never closed, so Data -// remains valid for the lifetime of the process. -type Data struct { - f *os.File - Data []byte -} - -// Mmap maps the given file into memory. -func Mmap(file string) (Data, bool, error) { - f, err := os.Open(file) - if err != nil { - return Data{}, false, err - } - data, err := mmapFile(f) - return data, true, err -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/go/mmap/mmap_other.go b/vendor/github.com/golangci/golangci-lint/v2/internal/go/mmap/mmap_other.go deleted file mode 100644 index 4d2844fc37..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/go/mmap/mmap_other.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build (js && wasm) || wasip1 || plan9 - -package mmap - -import ( - "io" - "os" -) - -// mmapFile on other systems doesn't mmap the file. It just reads everything. -func mmapFile(f *os.File) (Data, error) { - b, err := io.ReadAll(f) - if err != nil { - return Data{}, err - } - return Data{f, b}, nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/go/mmap/mmap_unix.go b/vendor/github.com/golangci/golangci-lint/v2/internal/go/mmap/mmap_unix.go deleted file mode 100644 index 5dce872368..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/go/mmap/mmap_unix.go +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build unix - -package mmap - -import ( - "fmt" - "io/fs" - "os" - "syscall" -) - -func mmapFile(f *os.File) (Data, error) { - st, err := f.Stat() - if err != nil { - return Data{}, err - } - size := st.Size() - pagesize := int64(os.Getpagesize()) - if int64(int(size+(pagesize-1))) != size+(pagesize-1) { - return Data{}, fmt.Errorf("%s: too large for mmap", f.Name()) - } - n := int(size) - if n == 0 { - return Data{f, nil}, nil - } - mmapLength := int(((size + pagesize - 1) / pagesize) * pagesize) // round up to page size - data, err := syscall.Mmap(int(f.Fd()), 0, mmapLength, syscall.PROT_READ, syscall.MAP_SHARED) - if err != nil { - return Data{}, &fs.PathError{Op: "mmap", Path: f.Name(), Err: err} - } - return Data{f, data[:n]}, nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/go/mmap/mmap_windows.go b/vendor/github.com/golangci/golangci-lint/v2/internal/go/mmap/mmap_windows.go deleted file mode 100644 index 256fab4b49..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/go/mmap/mmap_windows.go +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package mmap - -import ( - "fmt" - "os" - "syscall" - "unsafe" - - "golang.org/x/sys/windows" -) - -func mmapFile(f *os.File) (Data, error) { - st, err := f.Stat() - if err != nil { - return Data{}, err - } - size := st.Size() - if size == 0 { - return Data{f, nil}, nil - } - h, err := syscall.CreateFileMapping(syscall.Handle(f.Fd()), nil, syscall.PAGE_READONLY, 0, 0, nil) - if err != nil { - return Data{}, fmt.Errorf("CreateFileMapping %s: %w", f.Name(), err) - } - - addr, err := syscall.MapViewOfFile(h, syscall.FILE_MAP_READ, 0, 0, 0) - if err != nil { - return Data{}, fmt.Errorf("MapViewOfFile %s: %w", f.Name(), err) - } - var info windows.MemoryBasicInformation - err = windows.VirtualQuery(addr, &info, unsafe.Sizeof(info)) - if err != nil { - return Data{}, fmt.Errorf("VirtualQuery %s: %w", f.Name(), err) - } - data := unsafe.Slice((*byte)(unsafe.Pointer(addr)), int(info.RegionSize)) - if len(data) < int(size) { - // In some cases, especially on 386, we may not receive a in incomplete mapping: - // one that is shorter than the file itself. Return an error in those cases because - // incomplete mappings are not useful. - return Data{}, fmt.Errorf("mmapFile: received incomplete mapping of file") - } - return Data{f, data[:int(size)]}, nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/go/mmap/readme.md b/vendor/github.com/golangci/golangci-lint/v2/internal/go/mmap/readme.md deleted file mode 100644 index 5cbfdeefe6..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/go/mmap/readme.md +++ /dev/null @@ -1,17 +0,0 @@ -# mmap - -Extracted from `go/src/cmd/go/internal/mmap/` (related to `cache`). -This is just a copy of the Go code without any changes. - -## History - -- https://github.com/golangci/golangci-lint/pull/5576 - - sync go1.24.1 -- https://github.com/golangci/golangci-lint/pull/5100 - - Move package from `internal/mmap` to `internal/go/mmap` -- https://github.com/golangci/golangci-lint/pull/5098 - - sync with go1.23.2 - - sync with go1.22.8 - - sync with go1.21.13 - - sync with go1.20.14 - - sync with go1.19.13 diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/go/quoted/quoted.go b/vendor/github.com/golangci/golangci-lint/v2/internal/go/quoted/quoted.go deleted file mode 100644 index a812275073..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/go/quoted/quoted.go +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package quoted provides string manipulation utilities. -package quoted - -import ( - "flag" - "fmt" - "strings" - "unicode" -) - -func isSpaceByte(c byte) bool { - return c == ' ' || c == '\t' || c == '\n' || c == '\r' -} - -// Split splits s into a list of fields, -// allowing single or double quotes around elements. -// There is no unescaping or other processing within -// quoted fields. -// -// Keep in sync with cmd/dist/quoted.go -func Split(s string) ([]string, error) { - // Split fields allowing '' or "" around elements. - // Quotes further inside the string do not count. - var f []string - for len(s) > 0 { - for len(s) > 0 && isSpaceByte(s[0]) { - s = s[1:] - } - if len(s) == 0 { - break - } - // Accepted quoted string. No unescaping inside. - if s[0] == '"' || s[0] == '\'' { - quote := s[0] - s = s[1:] - i := 0 - for i < len(s) && s[i] != quote { - i++ - } - if i >= len(s) { - return nil, fmt.Errorf("unterminated %c string", quote) - } - f = append(f, s[:i]) - s = s[i+1:] - continue - } - i := 0 - for i < len(s) && !isSpaceByte(s[i]) { - i++ - } - f = append(f, s[:i]) - s = s[i:] - } - return f, nil -} - -// Join joins a list of arguments into a string that can be parsed -// with Split. Arguments are quoted only if necessary; arguments -// without spaces or quotes are kept as-is. No argument may contain both -// single and double quotes. -func Join(args []string) (string, error) { - var buf []byte - for i, arg := range args { - if i > 0 { - buf = append(buf, ' ') - } - var sawSpace, sawSingleQuote, sawDoubleQuote bool - for _, c := range arg { - switch { - case c > unicode.MaxASCII: - continue - case isSpaceByte(byte(c)): - sawSpace = true - case c == '\'': - sawSingleQuote = true - case c == '"': - sawDoubleQuote = true - } - } - switch { - case !sawSpace && !sawSingleQuote && !sawDoubleQuote: - buf = append(buf, arg...) - - case !sawSingleQuote: - buf = append(buf, '\'') - buf = append(buf, arg...) - buf = append(buf, '\'') - - case !sawDoubleQuote: - buf = append(buf, '"') - buf = append(buf, arg...) - buf = append(buf, '"') - - default: - return "", fmt.Errorf("argument %q contains both single and double quotes and cannot be quoted", arg) - } - } - return string(buf), nil -} - -// A Flag parses a list of string arguments encoded with Join. -// It is useful for flags like cmd/link's -extldflags. -type Flag []string - -var _ flag.Value = (*Flag)(nil) - -func (f *Flag) Set(v string) error { - fs, err := Split(v) - if err != nil { - return err - } - *f = fs[:len(fs):len(fs)] - return nil -} - -func (f *Flag) String() string { - if f == nil { - return "" - } - s, err := Join(*f) - if err != nil { - return strings.Join(*f, " ") - } - return s -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/go/quoted/readme.md b/vendor/github.com/golangci/golangci-lint/v2/internal/go/quoted/readme.md deleted file mode 100644 index 97868185c0..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/go/quoted/readme.md +++ /dev/null @@ -1,15 +0,0 @@ -# quoted - -Extracted from `go/src/cmd/internal/quoted/` (related to `cache`). -This is just a copy of the Go code without any changes. - -## History - -- https://github.com/golangci/golangci-lint/pull/5576 - - sync go1.24.1 (no change) -- https://github.com/golangci/golangci-lint/pull/5100 - - Move package from `internal/quoted` to `internal/go/quoted` -- https://github.com/golangci/golangci-lint/pull/5098 - - sync go1.23.2 - - sync go1.22.8 - - sync go1.21.13 diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/x/LICENSE b/vendor/github.com/golangci/golangci-lint/v2/internal/x/LICENSE deleted file mode 100644 index 2a7cf70da6..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/x/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright 2009 The Go Authors. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google LLC nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/analysisflags/readme.md b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/analysisflags/readme.md deleted file mode 100644 index 6035c22265..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/analysisflags/readme.md +++ /dev/null @@ -1,11 +0,0 @@ -# analysisflags - -Extracted from `/go/analysis/internal/analysisflags` (related to `checker`). -This is just a copy of the code without any changes. - -## History - -- https://github.com/golangci/golangci-lint/pull/6076 - - sync with https://github.com/golang/tools/blob/v0.37.0/go/analysis/internal/analysisflags -- https://github.com/golangci/golangci-lint/pull/5576 - - sync with https://github.com/golang/tools/blob/v0.28.0/go/analysis/internal/analysisflags diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/analysisflags/url.go b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/analysisflags/url.go deleted file mode 100644 index 26a917a991..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/analysisflags/url.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package analysisflags - -import ( - "fmt" - "net/url" - - "golang.org/x/tools/go/analysis" -) - -// ResolveURL resolves the URL field for a Diagnostic from an Analyzer -// and returns the URL. See Diagnostic.URL for details. -func ResolveURL(a *analysis.Analyzer, d analysis.Diagnostic) (string, error) { - if d.URL == "" && d.Category == "" && a.URL == "" { - return "", nil // do nothing - } - raw := d.URL - if d.URL == "" && d.Category != "" { - raw = "#" + d.Category - } - u, err := url.Parse(raw) - if err != nil { - return "", fmt.Errorf("invalid Diagnostic.URL %q: %s", raw, err) - } - base, err := url.Parse(a.URL) - if err != nil { - return "", fmt.Errorf("invalid Analyzer.URL %q: %s", a.URL, err) - } - return base.ResolveReference(u).String(), nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/analysisinternal/analysis.go b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/analysisinternal/analysis.go deleted file mode 100644 index b613d16734..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/analysisinternal/analysis.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package analysisinternal provides gopls' internal analyses with a -// number of helper functions that operate on typed syntax trees. -package analysisinternal - -import ( - "fmt" - "slices" - - "golang.org/x/tools/go/analysis" -) - -// A ReadFileFunc is a function that returns the -// contents of a file, such as [os.ReadFile]. -type ReadFileFunc = func(filename string) ([]byte, error) - -// CheckedReadFile returns a wrapper around a Pass.ReadFile -// function that performs the appropriate checks. -func CheckedReadFile(pass *analysis.Pass, readFile ReadFileFunc) ReadFileFunc { - return func(filename string) ([]byte, error) { - if err := CheckReadable(pass, filename); err != nil { - return nil, err - } - return readFile(filename) - } -} - -// CheckReadable enforces the access policy defined by the ReadFile field of [analysis.Pass]. -func CheckReadable(pass *analysis.Pass, filename string) error { - if slices.Contains(pass.OtherFiles, filename) || - slices.Contains(pass.IgnoredFiles, filename) { - return nil - } - for _, f := range pass.Files { - if pass.Fset.File(f.FileStart).Name() == filename { - return nil - } - } - return fmt.Errorf("Pass.ReadFile: %s is not among OtherFiles, IgnoredFiles, or names of Files", filename) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/analysisinternal/readme.md b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/analysisinternal/readme.md deleted file mode 100644 index 6c54592d9e..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/analysisinternal/readme.md +++ /dev/null @@ -1,11 +0,0 @@ -# analysisinternal - -Extracted from `/internal/analysisinternal/` (related to `checker`). -This is just a copy of the code without any changes. - -## History - -- https://github.com/golangci/golangci-lint/pull/6076 - - sync with https://github.com/golang/tools/blob/v0.37.0/internal/analysisinternal/ -- https://github.com/golangci/golangci-lint/pull/5576 - - sync with https://github.com/golang/tools/blob/v0.28.0/internal/analysisinternal/ diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/diff.go b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/diff.go deleted file mode 100644 index c12bdfd2ac..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/diff.go +++ /dev/null @@ -1,177 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package diff computes differences between text files or strings. -package diff - -import ( - "fmt" - "slices" - "sort" - "strings" -) - -// An Edit describes the replacement of a portion of a text file. -type Edit struct { - Start, End int // byte offsets of the region to replace - New string // the replacement -} - -func (e Edit) String() string { - return fmt.Sprintf("{Start:%d,End:%d,New:%q}", e.Start, e.End, e.New) -} - -// Apply applies a sequence of edits to the src buffer and returns the -// result. Edits are applied in order of start offset; edits with the -// same start offset are applied in they order they were provided. -// -// Apply returns an error if any edit is out of bounds, -// or if any pair of edits is overlapping. -func Apply(src string, edits []Edit) (string, error) { - edits, size, err := validate(src, edits) - if err != nil { - return "", err - } - - // Apply edits. - out := make([]byte, 0, size) - lastEnd := 0 - for _, edit := range edits { - if lastEnd < edit.Start { - out = append(out, src[lastEnd:edit.Start]...) - } - out = append(out, edit.New...) - lastEnd = edit.End - } - out = append(out, src[lastEnd:]...) - - if len(out) != size { - panic("wrong size") - } - - return string(out), nil -} - -// ApplyBytes is like Apply, but it accepts a byte slice. -// The result is always a new array. -func ApplyBytes(src []byte, edits []Edit) ([]byte, error) { - res, err := Apply(string(src), edits) - return []byte(res), err -} - -// validate checks that edits are consistent with src, -// and returns the size of the patched output. -// It may return a different slice. -func validate(src string, edits []Edit) ([]Edit, int, error) { - if !sort.IsSorted(editsSort(edits)) { - edits = slices.Clone(edits) - SortEdits(edits) - } - - // Check validity of edits and compute final size. - size := len(src) - lastEnd := 0 - for _, edit := range edits { - if !(0 <= edit.Start && edit.Start <= edit.End && edit.End <= len(src)) { - return nil, 0, fmt.Errorf("diff has out-of-bounds edits") - } - if edit.Start < lastEnd { - return nil, 0, fmt.Errorf("diff has overlapping edits") - } - size += len(edit.New) + edit.Start - edit.End - lastEnd = edit.End - } - - return edits, size, nil -} - -// SortEdits orders a slice of Edits by (start, end) offset. -// This ordering puts insertions (end = start) before deletions -// (end > start) at the same point, but uses a stable sort to preserve -// the order of multiple insertions at the same point. -// (Apply detects multiple deletions at the same point as an error.) -func SortEdits(edits []Edit) { - sort.Stable(editsSort(edits)) -} - -type editsSort []Edit - -func (a editsSort) Len() int { return len(a) } -func (a editsSort) Less(i, j int) bool { - if cmp := a[i].Start - a[j].Start; cmp != 0 { - return cmp < 0 - } - return a[i].End < a[j].End -} -func (a editsSort) Swap(i, j int) { a[i], a[j] = a[j], a[i] } - -// lineEdits expands and merges a sequence of edits so that each -// resulting edit replaces one or more complete lines. -// See ApplyEdits for preconditions. -func lineEdits(src string, edits []Edit) ([]Edit, error) { - edits, _, err := validate(src, edits) - if err != nil { - return nil, err - } - - // Do all deletions begin and end at the start of a line, - // and all insertions end with a newline? - // (This is merely a fast path.) - for _, edit := range edits { - if edit.Start >= len(src) || // insertion at EOF - edit.Start > 0 && src[edit.Start-1] != '\n' || // not at line start - edit.End > 0 && src[edit.End-1] != '\n' || // not at line start - edit.New != "" && edit.New[len(edit.New)-1] != '\n' { // partial insert - goto expand // slow path - } - } - return edits, nil // aligned - -expand: - if len(edits) == 0 { - return edits, nil // no edits (unreachable due to fast path) - } - expanded := make([]Edit, 0, len(edits)) // a guess - prev := edits[0] - // TODO(adonovan): opt: start from the first misaligned edit. - // TODO(adonovan): opt: avoid quadratic cost of string += string. - for _, edit := range edits[1:] { - between := src[prev.End:edit.Start] - if !strings.Contains(between, "\n") { - // overlapping lines: combine with previous edit. - prev.New += between + edit.New - prev.End = edit.End - } else { - // non-overlapping lines: flush previous edit. - expanded = append(expanded, expandEdit(prev, src)) - prev = edit - } - } - return append(expanded, expandEdit(prev, src)), nil // flush final edit -} - -// expandEdit returns edit expanded to complete whole lines. -func expandEdit(edit Edit, src string) Edit { - // Expand start left to start of line. - // (delta is the zero-based column number of start.) - start := edit.Start - if delta := start - 1 - strings.LastIndex(src[:start], "\n"); delta > 0 { - edit.Start -= delta - edit.New = src[start-delta:start] + edit.New - } - - // Expand end right to end of line. - end := edit.End - if end > 0 && src[end-1] != '\n' || - edit.New != "" && edit.New[len(edit.New)-1] != '\n' { - if nl := strings.IndexByte(src[end:], '\n'); nl < 0 { - edit.End = len(src) // extend to EOF - } else { - edit.End = end + nl + 1 // extend beyond \n - } - } - edit.New += src[end:edit.End] - - return edit -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/lcs/common.go b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/lcs/common.go deleted file mode 100644 index 27fa9ecbd5..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/lcs/common.go +++ /dev/null @@ -1,179 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package lcs - -import ( - "log" - "sort" -) - -// lcs is a longest common sequence -type lcs []diag - -// A diag is a piece of the edit graph where A[X+i] == B[Y+i], for 0<=i l[j].Len - }) - return l -} - -// validate that the elements of the lcs do not overlap -// (can only happen when the two-sided algorithm ends early) -// expects the lcs to be sorted -func (l lcs) valid() bool { - for i := 1; i < len(l); i++ { - if l[i-1].X+l[i-1].Len > l[i].X { - return false - } - if l[i-1].Y+l[i-1].Len > l[i].Y { - return false - } - } - return true -} - -// repair overlapping lcs -// only called if two-sided stops early -func (l lcs) fix() lcs { - // from the set of diagonals in l, find a maximal non-conflicting set - // this problem may be NP-complete, but we use a greedy heuristic, - // which is quadratic, but with a better data structure, could be D log D. - // independent is not enough: {0,3,1} and {3,0,2} can't both occur in an lcs - // which has to have monotone x and y - if len(l) == 0 { - return nil - } - sort.Slice(l, func(i, j int) bool { return l[i].Len > l[j].Len }) - tmp := make(lcs, 0, len(l)) - tmp = append(tmp, l[0]) - for i := 1; i < len(l); i++ { - var dir direction - nxt := l[i] - for _, in := range tmp { - if dir, nxt = overlap(in, nxt); dir == empty || dir == bad { - break - } - } - if nxt.Len > 0 && dir != bad { - tmp = append(tmp, nxt) - } - } - tmp.sort() - if false && !tmp.valid() { // debug checking - log.Fatalf("here %d", len(tmp)) - } - return tmp -} - -type direction int - -const ( - empty direction = iota // diag is empty (so not in lcs) - leftdown // proposed acceptably to the left and below - rightup // proposed diag is acceptably to the right and above - bad // proposed diag is inconsistent with the lcs so far -) - -// overlap trims the proposed diag prop so it doesn't overlap with -// the existing diag that has already been added to the lcs. -func overlap(exist, prop diag) (direction, diag) { - if prop.X <= exist.X && exist.X < prop.X+prop.Len { - // remove the end of prop where it overlaps with the X end of exist - delta := prop.X + prop.Len - exist.X - prop.Len -= delta - if prop.Len <= 0 { - return empty, prop - } - } - if exist.X <= prop.X && prop.X < exist.X+exist.Len { - // remove the beginning of prop where overlaps with exist - delta := exist.X + exist.Len - prop.X - prop.Len -= delta - if prop.Len <= 0 { - return empty, prop - } - prop.X += delta - prop.Y += delta - } - if prop.Y <= exist.Y && exist.Y < prop.Y+prop.Len { - // remove the end of prop that overlaps (in Y) with exist - delta := prop.Y + prop.Len - exist.Y - prop.Len -= delta - if prop.Len <= 0 { - return empty, prop - } - } - if exist.Y <= prop.Y && prop.Y < exist.Y+exist.Len { - // remove the beginning of peop that overlaps with exist - delta := exist.Y + exist.Len - prop.Y - prop.Len -= delta - if prop.Len <= 0 { - return empty, prop - } - prop.X += delta // no test reaches this code - prop.Y += delta - } - if prop.X+prop.Len <= exist.X && prop.Y+prop.Len <= exist.Y { - return leftdown, prop - } - if exist.X+exist.Len <= prop.X && exist.Y+exist.Len <= prop.Y { - return rightup, prop - } - // prop can't be in an lcs that contains exist - return bad, prop -} - -// manipulating Diag and lcs - -// prepend a diagonal (x,y)-(x+1,y+1) segment either to an empty lcs -// or to its first Diag. prepend is only called to extend diagonals -// the backward direction. -func (lcs lcs) prepend(x, y int) lcs { - if len(lcs) > 0 { - d := &lcs[0] - if int(d.X) == x+1 && int(d.Y) == y+1 { - // extend the diagonal down and to the left - d.X, d.Y = int(x), int(y) - d.Len++ - return lcs - } - } - - r := diag{X: int(x), Y: int(y), Len: 1} - lcs = append([]diag{r}, lcs...) - return lcs -} - -// append appends a diagonal, or extends the existing one. -// by adding the edge (x,y)-(x+1.y+1). append is only called -// to extend diagonals in the forward direction. -func (lcs lcs) append(x, y int) lcs { - if len(lcs) > 0 { - last := &lcs[len(lcs)-1] - // Expand last element if adjoining. - if last.X+last.Len == x && last.Y+last.Len == y { - last.Len++ - return lcs - } - } - - return append(lcs, diag{X: x, Y: y, Len: 1}) -} - -// enforce constraint on d, k -func ok(d, k int) bool { - return d >= 0 && -d <= k && k <= d -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/lcs/doc.go b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/lcs/doc.go deleted file mode 100644 index aa4b0fb591..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/lcs/doc.go +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// package lcs contains code to find longest-common-subsequences -// (and diffs) -package lcs - -/* -Compute longest-common-subsequences of two slices A, B using -algorithms from Myers' paper. A longest-common-subsequence -(LCS from now on) of A and B is a maximal set of lexically increasing -pairs of subscripts (x,y) with A[x]==B[y]. There may be many LCS, but -they all have the same length. An LCS determines a sequence of edits -that changes A into B. - -The key concept is the edit graph of A and B. -If A has length N and B has length M, then the edit graph has -vertices v[i][j] for 0 <= i <= N, 0 <= j <= M. There is a -horizontal edge from v[i][j] to v[i+1][j] whenever both are in -the graph, and a vertical edge from v[i][j] to f[i][j+1] similarly. -When A[i] == B[j] there is a diagonal edge from v[i][j] to v[i+1][j+1]. - -A path between in the graph between (0,0) and (N,M) determines a sequence -of edits converting A into B: each horizontal edge corresponds to removing -an element of A, and each vertical edge corresponds to inserting an -element of B. - -A vertex (x,y) is on (forward) diagonal k if x-y=k. A path in the graph -is of length D if it has D non-diagonal edges. The algorithms generate -forward paths (in which at least one of x,y increases at each edge), -or backward paths (in which at least one of x,y decreases at each edge), -or a combination. (Note that the orientation is the traditional mathematical one, -with the origin in the lower-left corner.) - -Here is the edit graph for A:"aabbaa", B:"aacaba". (I know the diagonals look weird.) - ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ - a | ___/‾‾‾ | ___/‾‾‾ | | | ___/‾‾‾ | ___/‾‾‾ | - ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ - b | | | ___/‾‾‾ | ___/‾‾‾ | | | - ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ - a | ___/‾‾‾ | ___/‾‾‾ | | | ___/‾‾‾ | ___/‾‾‾ | - ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ - c | | | | | | | - ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ - a | ___/‾‾‾ | ___/‾‾‾ | | | ___/‾‾‾ | ___/‾‾‾ | - ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ - a | ___/‾‾‾ | ___/‾‾‾ | | | ___/‾‾‾ | ___/‾‾‾ | - ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ - a a b b a a - - -The algorithm labels a vertex (x,y) with D,k if it is on diagonal k and at -the end of a maximal path of length D. (Because x-y=k it suffices to remember -only the x coordinate of the vertex.) - -The forward algorithm: Find the longest diagonal starting at (0,0) and -label its end with D=0,k=0. From that vertex take a vertical step and -then follow the longest diagonal (up and to the right), and label that vertex -with D=1,k=-1. From the D=0,k=0 point take a horizontal step and the follow -the longest diagonal (up and to the right) and label that vertex -D=1,k=1. In the same way, having labelled all the D vertices, -from a vertex labelled D,k find two vertices -tentatively labelled D+1,k-1 and D+1,k+1. There may be two on the same -diagonal, in which case take the one with the larger x. - -Eventually the path gets to (N,M), and the diagonals on it are the LCS. - -Here is the edit graph with the ends of D-paths labelled. (So, for instance, -0/2,2 indicates that x=2,y=2 is labelled with 0, as it should be, since the first -step is to go up the longest diagonal from (0,0).) -A:"aabbaa", B:"aacaba" - ⊙ ------- ⊙ ------- ⊙ -------(3/3,6)------- ⊙ -------(3/5,6)-------(4/6,6) - a | ___/‾‾‾ | ___/‾‾‾ | | | ___/‾‾‾ | ___/‾‾‾ | - ⊙ ------- ⊙ ------- ⊙ -------(2/3,5)------- ⊙ ------- ⊙ ------- ⊙ - b | | | ___/‾‾‾ | ___/‾‾‾ | | | - ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ -------(3/5,4)------- ⊙ - a | ___/‾‾‾ | ___/‾‾‾ | | | ___/‾‾‾ | ___/‾‾‾ | - ⊙ ------- ⊙ -------(1/2,3)-------(2/3,3)------- ⊙ ------- ⊙ ------- ⊙ - c | | | | | | | - ⊙ ------- ⊙ -------(0/2,2)-------(1/3,2)-------(2/4,2)-------(3/5,2)-------(4/6,2) - a | ___/‾‾‾ | ___/‾‾‾ | | | ___/‾‾‾ | ___/‾‾‾ | - ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ - a | ___/‾‾‾ | ___/‾‾‾ | | | ___/‾‾‾ | ___/‾‾‾ | - ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ ------- ⊙ - a a b b a a - -The 4-path is reconstructed starting at (4/6,6), horizontal to (3/5,6), diagonal to (3,4), vertical -to (2/3,3), horizontal to (1/2,3), vertical to (0/2,2), and diagonal to (0,0). As expected, -there are 4 non-diagonal steps, and the diagonals form an LCS. - -There is a symmetric backward algorithm, which gives (backwards labels are prefixed with a colon): -A:"aabbaa", B:"aacaba" - ⊙ -------- ⊙ -------- ⊙ -------- ⊙ -------- ⊙ -------- ⊙ -------- ⊙ - a | ____/‾‾‾ | ____/‾‾‾ | | | ____/‾‾‾ | ____/‾‾‾ | - ⊙ -------- ⊙ -------- ⊙ -------- ⊙ -------- ⊙ --------(:0/5,5)-------- ⊙ - b | | | ____/‾‾‾ | ____/‾‾‾ | | | - ⊙ -------- ⊙ -------- ⊙ --------(:1/3,4)-------- ⊙ -------- ⊙ -------- ⊙ - a | ____/‾‾‾ | ____/‾‾‾ | | | ____/‾‾‾ | ____/‾‾‾ | - (:3/0,3)--------(:2/1,3)-------- ⊙ --------(:2/3,3)--------(:1/4,3)-------- ⊙ -------- ⊙ - c | | | | | | | - ⊙ -------- ⊙ -------- ⊙ --------(:3/3,2)--------(:2/4,2)-------- ⊙ -------- ⊙ - a | ____/‾‾‾ | ____/‾‾‾ | | | ____/‾‾‾ | ____/‾‾‾ | - (:3/0,1)-------- ⊙ -------- ⊙ -------- ⊙ --------(:3/4,1)-------- ⊙ -------- ⊙ - a | ____/‾‾‾ | ____/‾‾‾ | | | ____/‾‾‾ | ____/‾‾‾ | - (:4/0,0)-------- ⊙ -------- ⊙ -------- ⊙ --------(:4/4,0)-------- ⊙ -------- ⊙ - a a b b a a - -Neither of these is ideal for use in an editor, where it is undesirable to send very long diffs to the -front end. It's tricky to decide exactly what 'very long diffs' means, as "replace A by B" is very short. -We want to control how big D can be, by stopping when it gets too large. The forward algorithm then -privileges common prefixes, and the backward algorithm privileges common suffixes. Either is an undesirable -asymmetry. - -Fortunately there is a two-sided algorithm, implied by results in Myers' paper. Here's what the labels in -the edit graph look like. -A:"aabbaa", B:"aacaba" - ⊙ --------- ⊙ --------- ⊙ --------- ⊙ --------- ⊙ --------- ⊙ --------- ⊙ - a | ____/‾‾‾‾ | ____/‾‾‾‾ | | | ____/‾‾‾‾ | ____/‾‾‾‾ | - ⊙ --------- ⊙ --------- ⊙ --------- (2/3,5) --------- ⊙ --------- (:0/5,5)--------- ⊙ - b | | | ____/‾‾‾‾ | ____/‾‾‾‾ | | | - ⊙ --------- ⊙ --------- ⊙ --------- (:1/3,4)--------- ⊙ --------- ⊙ --------- ⊙ - a | ____/‾‾‾‾ | ____/‾‾‾‾ | | | ____/‾‾‾‾ | ____/‾‾‾‾ | - ⊙ --------- (:2/1,3)--------- (1/2,3) ---------(2:2/3,3)--------- (:1/4,3)--------- ⊙ --------- ⊙ - c | | | | | | | - ⊙ --------- ⊙ --------- (0/2,2) --------- (1/3,2) ---------(2:2/4,2)--------- ⊙ --------- ⊙ - a | ____/‾‾‾‾ | ____/‾‾‾‾ | | | ____/‾‾‾‾ | ____/‾‾‾‾ | - ⊙ --------- ⊙ --------- ⊙ --------- ⊙ --------- ⊙ --------- ⊙ --------- ⊙ - a | ____/‾‾‾‾ | ____/‾‾‾‾ | | | ____/‾‾‾‾ | ____/‾‾‾‾ | - ⊙ --------- ⊙ --------- ⊙ --------- ⊙ --------- ⊙ --------- ⊙ --------- ⊙ - a a b b a a - -The algorithm stopped when it saw the backwards 2-path ending at (1,3) and the forwards 2-path ending at (3,5). The criterion -is a backwards path ending at (u,v) and a forward path ending at (x,y), where u <= x and the two points are on the same -diagonal. (Here the edgegraph has a diagonal, but the criterion is x-y=u-v.) Myers proves there is a forward -2-path from (0,0) to (1,3), and that together with the backwards 2-path ending at (1,3) gives the expected 4-path. -Unfortunately the forward path has to be constructed by another run of the forward algorithm; it can't be found from the -computed labels. That is the worst case. Had the code noticed (x,y)=(u,v)=(3,3) the whole path could be reconstructed -from the edgegraph. The implementation looks for a number of special cases to try to avoid computing an extra forward path. - -If the two-sided algorithm has stop early (because D has become too large) it will have found a forward LCS and a -backwards LCS. Ideally these go with disjoint prefixes and suffixes of A and B, but disjointedness may fail and the two -computed LCS may conflict. (An easy example is where A is a suffix of B, and shares a short prefix. The backwards LCS -is all of A, and the forward LCS is a prefix of A.) The algorithm combines the two -to form a best-effort LCS. In the worst case the forward partial LCS may have to -be recomputed. -*/ - -/* Eugene Myers paper is titled -"An O(ND) Difference Algorithm and Its Variations" -and can be found at -http://www.xmailserver.org/diff2.pdf - -(There is a generic implementation of the algorithm the repository with git hash -b9ad7e4ade3a686d608e44475390ad428e60e7fc) -*/ diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/lcs/git.sh b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/lcs/git.sh deleted file mode 100644 index b25ba4aac7..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/lcs/git.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash -# -# Copyright 2022 The Go Authors. All rights reserved. -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file. -# -# Creates a zip file containing all numbered versions -# of the commit history of a large source file, for use -# as input data for the tests of the diff algorithm. -# -# Run script from root of the x/tools repo. - -set -eu - -# WARNING: This script will install the latest version of $file -# The largest real source file in the x/tools repo. -# file=internal/golang/completion/completion.go -# file=internal/golang/diagnostics.go -file=internal/protocol/tsprotocol.go - -tmp=$(mktemp -d) -git log $file | - awk '/^commit / {print $2}' | - nl -ba -nrz | - while read n hash; do - git checkout --quiet $hash $file - cp -f $file $tmp/$n - done -(cd $tmp && zip -q - *) > testdata.zip -rm -fr $tmp -git restore --staged $file -git restore $file -echo "Created testdata.zip" diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/lcs/labels.go b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/lcs/labels.go deleted file mode 100644 index 504913d1da..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/lcs/labels.go +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package lcs - -import ( - "fmt" -) - -// For each D, vec[D] has length D+1, -// and the label for (D, k) is stored in vec[D][(D+k)/2]. -type label struct { - vec [][]int -} - -// Temporary checking DO NOT COMMIT true TO PRODUCTION CODE -const debug = false - -// debugging. check that the (d,k) pair is valid -// (that is, -d<=k<=d and d+k even) -func checkDK(D, k int) { - if k >= -D && k <= D && (D+k)%2 == 0 { - return - } - panic(fmt.Sprintf("out of range, d=%d,k=%d", D, k)) -} - -func (t *label) set(D, k, x int) { - if debug { - checkDK(D, k) - } - for len(t.vec) <= D { - t.vec = append(t.vec, nil) - } - if t.vec[D] == nil { - t.vec[D] = make([]int, D+1) - } - t.vec[D][(D+k)/2] = x // known that D+k is even -} - -func (t *label) get(d, k int) int { - if debug { - checkDK(d, k) - } - return int(t.vec[d][(d+k)/2]) -} - -func newtriang(limit int) label { - if limit < 100 { - // Preallocate if limit is not large. - return label{vec: make([][]int, limit)} - } - return label{} -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/lcs/old.go b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/lcs/old.go deleted file mode 100644 index 4c346706a7..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/lcs/old.go +++ /dev/null @@ -1,478 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package lcs - -// TODO(adonovan): remove unclear references to "old" in this package. - -import ( - "fmt" -) - -// A Diff is a replacement of a portion of A by a portion of B. -type Diff struct { - Start, End int // offsets of portion to delete in A - ReplStart, ReplEnd int // offset of replacement text in B -} - -// DiffStrings returns the differences between two strings. -// It does not respect rune boundaries. -func DiffStrings(a, b string) []Diff { return diff(stringSeqs{a, b}) } - -// DiffBytes returns the differences between two byte sequences. -// It does not respect rune boundaries. -func DiffBytes(a, b []byte) []Diff { return diff(bytesSeqs{a, b}) } - -// DiffRunes returns the differences between two rune sequences. -func DiffRunes(a, b []rune) []Diff { return diff(runesSeqs{a, b}) } - -func diff(seqs sequences) []Diff { - // A limit on how deeply the LCS algorithm should search. The value is just a guess. - const maxDiffs = 100 - diff, _ := compute(seqs, twosided, maxDiffs/2) - return diff -} - -// compute computes the list of differences between two sequences, -// along with the LCS. It is exercised directly by tests. -// The algorithm is one of {forward, backward, twosided}. -func compute(seqs sequences, algo func(*editGraph) lcs, limit int) ([]Diff, lcs) { - if limit <= 0 { - limit = 1 << 25 // effectively infinity - } - alen, blen := seqs.lengths() - g := &editGraph{ - seqs: seqs, - vf: newtriang(limit), - vb: newtriang(limit), - limit: limit, - ux: alen, - uy: blen, - delta: alen - blen, - } - lcs := algo(g) - diffs := lcs.toDiffs(alen, blen) - return diffs, lcs -} - -// editGraph carries the information for computing the lcs of two sequences. -type editGraph struct { - seqs sequences - vf, vb label // forward and backward labels - - limit int // maximal value of D - // the bounding rectangle of the current edit graph - lx, ly, ux, uy int - delta int // common subexpression: (ux-lx)-(uy-ly) -} - -// toDiffs converts an LCS to a list of edits. -func (lcs lcs) toDiffs(alen, blen int) []Diff { - var diffs []Diff - var pa, pb int // offsets in a, b - for _, l := range lcs { - if pa < l.X || pb < l.Y { - diffs = append(diffs, Diff{pa, l.X, pb, l.Y}) - } - pa = l.X + l.Len - pb = l.Y + l.Len - } - if pa < alen || pb < blen { - diffs = append(diffs, Diff{pa, alen, pb, blen}) - } - return diffs -} - -// --- FORWARD --- - -// fdone decides if the forward path has reached the upper right -// corner of the rectangle. If so, it also returns the computed lcs. -func (e *editGraph) fdone(D, k int) (bool, lcs) { - // x, y, k are relative to the rectangle - x := e.vf.get(D, k) - y := x - k - if x == e.ux && y == e.uy { - return true, e.forwardlcs(D, k) - } - return false, nil -} - -// run the forward algorithm, until success or up to the limit on D. -func forward(e *editGraph) lcs { - e.setForward(0, 0, e.lx) - if ok, ans := e.fdone(0, 0); ok { - return ans - } - // from D to D+1 - for D := range e.limit { - e.setForward(D+1, -(D + 1), e.getForward(D, -D)) - if ok, ans := e.fdone(D+1, -(D + 1)); ok { - return ans - } - e.setForward(D+1, D+1, e.getForward(D, D)+1) - if ok, ans := e.fdone(D+1, D+1); ok { - return ans - } - for k := -D + 1; k <= D-1; k += 2 { - // these are tricky and easy to get backwards - lookv := e.lookForward(k, e.getForward(D, k-1)+1) - lookh := e.lookForward(k, e.getForward(D, k+1)) - if lookv > lookh { - e.setForward(D+1, k, lookv) - } else { - e.setForward(D+1, k, lookh) - } - if ok, ans := e.fdone(D+1, k); ok { - return ans - } - } - } - // D is too large - // find the D path with maximal x+y inside the rectangle and - // use that to compute the found part of the lcs - kmax := -e.limit - 1 - diagmax := -1 - for k := -e.limit; k <= e.limit; k += 2 { - x := e.getForward(e.limit, k) - y := x - k - if x+y > diagmax && x <= e.ux && y <= e.uy { - diagmax, kmax = x+y, k - } - } - return e.forwardlcs(e.limit, kmax) -} - -// recover the lcs by backtracking from the farthest point reached -func (e *editGraph) forwardlcs(D, k int) lcs { - var ans lcs - for x := e.getForward(D, k); x != 0 || x-k != 0; { - if ok(D-1, k-1) && x-1 == e.getForward(D-1, k-1) { - // if (x-1,y) is labelled D-1, x--,D--,k--,continue - D, k, x = D-1, k-1, x-1 - continue - } else if ok(D-1, k+1) && x == e.getForward(D-1, k+1) { - // if (x,y-1) is labelled D-1, x, D--,k++, continue - D, k = D-1, k+1 - continue - } - // if (x-1,y-1)--(x,y) is a diagonal, prepend,x--,y--, continue - y := x - k - ans = ans.prepend(x+e.lx-1, y+e.ly-1) - x-- - } - return ans -} - -// start at (x,y), go up the diagonal as far as possible, -// and label the result with d -func (e *editGraph) lookForward(k, relx int) int { - rely := relx - k - x, y := relx+e.lx, rely+e.ly - if x < e.ux && y < e.uy { - x += e.seqs.commonPrefixLen(x, e.ux, y, e.uy) - } - return x -} - -func (e *editGraph) setForward(d, k, relx int) { - x := e.lookForward(k, relx) - e.vf.set(d, k, x-e.lx) -} - -func (e *editGraph) getForward(d, k int) int { - x := e.vf.get(d, k) - return x -} - -// --- BACKWARD --- - -// bdone decides if the backward path has reached the lower left corner -func (e *editGraph) bdone(D, k int) (bool, lcs) { - // x, y, k are relative to the rectangle - x := e.vb.get(D, k) - y := x - (k + e.delta) - if x == 0 && y == 0 { - return true, e.backwardlcs(D, k) - } - return false, nil -} - -// run the backward algorithm, until success or up to the limit on D. -// (used only by tests) -func backward(e *editGraph) lcs { - e.setBackward(0, 0, e.ux) - if ok, ans := e.bdone(0, 0); ok { - return ans - } - // from D to D+1 - for D := range e.limit { - e.setBackward(D+1, -(D + 1), e.getBackward(D, -D)-1) - if ok, ans := e.bdone(D+1, -(D + 1)); ok { - return ans - } - e.setBackward(D+1, D+1, e.getBackward(D, D)) - if ok, ans := e.bdone(D+1, D+1); ok { - return ans - } - for k := -D + 1; k <= D-1; k += 2 { - // these are tricky and easy to get wrong - lookv := e.lookBackward(k, e.getBackward(D, k-1)) - lookh := e.lookBackward(k, e.getBackward(D, k+1)-1) - if lookv < lookh { - e.setBackward(D+1, k, lookv) - } else { - e.setBackward(D+1, k, lookh) - } - if ok, ans := e.bdone(D+1, k); ok { - return ans - } - } - } - - // D is too large - // find the D path with minimal x+y inside the rectangle and - // use that to compute the part of the lcs found - kmax := -e.limit - 1 - diagmin := 1 << 25 - for k := -e.limit; k <= e.limit; k += 2 { - x := e.getBackward(e.limit, k) - y := x - (k + e.delta) - if x+y < diagmin && x >= 0 && y >= 0 { - diagmin, kmax = x+y, k - } - } - if kmax < -e.limit { - panic(fmt.Sprintf("no paths when limit=%d?", e.limit)) - } - return e.backwardlcs(e.limit, kmax) -} - -// recover the lcs by backtracking -func (e *editGraph) backwardlcs(D, k int) lcs { - var ans lcs - for x := e.getBackward(D, k); x != e.ux || x-(k+e.delta) != e.uy; { - if ok(D-1, k-1) && x == e.getBackward(D-1, k-1) { - // D--, k--, x unchanged - D, k = D-1, k-1 - continue - } else if ok(D-1, k+1) && x+1 == e.getBackward(D-1, k+1) { - // D--, k++, x++ - D, k, x = D-1, k+1, x+1 - continue - } - y := x - (k + e.delta) - ans = ans.append(x+e.lx, y+e.ly) - x++ - } - return ans -} - -// start at (x,y), go down the diagonal as far as possible, -func (e *editGraph) lookBackward(k, relx int) int { - rely := relx - (k + e.delta) // forward k = k + e.delta - x, y := relx+e.lx, rely+e.ly - if x > 0 && y > 0 { - x -= e.seqs.commonSuffixLen(0, x, 0, y) - } - return x -} - -// convert to rectangle, and label the result with d -func (e *editGraph) setBackward(d, k, relx int) { - x := e.lookBackward(k, relx) - e.vb.set(d, k, x-e.lx) -} - -func (e *editGraph) getBackward(d, k int) int { - x := e.vb.get(d, k) - return x -} - -// -- TWOSIDED --- - -func twosided(e *editGraph) lcs { - // The termination condition could be improved, as either the forward - // or backward pass could succeed before Myers' Lemma applies. - // Aside from questions of efficiency (is the extra testing cost-effective) - // this is more likely to matter when e.limit is reached. - e.setForward(0, 0, e.lx) - e.setBackward(0, 0, e.ux) - - // from D to D+1 - for D := range e.limit { - // just finished a backwards pass, so check - if got, ok := e.twoDone(D, D); ok { - return e.twolcs(D, D, got) - } - // do a forwards pass (D to D+1) - e.setForward(D+1, -(D + 1), e.getForward(D, -D)) - e.setForward(D+1, D+1, e.getForward(D, D)+1) - for k := -D + 1; k <= D-1; k += 2 { - // these are tricky and easy to get backwards - lookv := e.lookForward(k, e.getForward(D, k-1)+1) - lookh := e.lookForward(k, e.getForward(D, k+1)) - if lookv > lookh { - e.setForward(D+1, k, lookv) - } else { - e.setForward(D+1, k, lookh) - } - } - // just did a forward pass, so check - if got, ok := e.twoDone(D+1, D); ok { - return e.twolcs(D+1, D, got) - } - // do a backward pass, D to D+1 - e.setBackward(D+1, -(D + 1), e.getBackward(D, -D)-1) - e.setBackward(D+1, D+1, e.getBackward(D, D)) - for k := -D + 1; k <= D-1; k += 2 { - // these are tricky and easy to get wrong - lookv := e.lookBackward(k, e.getBackward(D, k-1)) - lookh := e.lookBackward(k, e.getBackward(D, k+1)-1) - if lookv < lookh { - e.setBackward(D+1, k, lookv) - } else { - e.setBackward(D+1, k, lookh) - } - } - } - - // D too large. combine a forward and backward partial lcs - // first, a forward one - kmax := -e.limit - 1 - diagmax := -1 - for k := -e.limit; k <= e.limit; k += 2 { - x := e.getForward(e.limit, k) - y := x - k - if x+y > diagmax && x <= e.ux && y <= e.uy { - diagmax, kmax = x+y, k - } - } - if kmax < -e.limit { - panic(fmt.Sprintf("no forward paths when limit=%d?", e.limit)) - } - lcs := e.forwardlcs(e.limit, kmax) - // now a backward one - // find the D path with minimal x+y inside the rectangle and - // use that to compute the lcs - diagmin := 1 << 25 // infinity - for k := -e.limit; k <= e.limit; k += 2 { - x := e.getBackward(e.limit, k) - y := x - (k + e.delta) - if x+y < diagmin && x >= 0 && y >= 0 { - diagmin, kmax = x+y, k - } - } - if kmax < -e.limit { - panic(fmt.Sprintf("no backward paths when limit=%d?", e.limit)) - } - lcs = append(lcs, e.backwardlcs(e.limit, kmax)...) - // These may overlap (e.forwardlcs and e.backwardlcs return sorted lcs) - ans := lcs.fix() - return ans -} - -// Does Myers' Lemma apply? -func (e *editGraph) twoDone(df, db int) (int, bool) { - if (df+db+e.delta)%2 != 0 { - return 0, false // diagonals cannot overlap - } - kmin := max(-df, -db+e.delta) - kmax := db + e.delta - if df < kmax { - kmax = df - } - for k := kmin; k <= kmax; k += 2 { - x := e.vf.get(df, k) - u := e.vb.get(db, k-e.delta) - if u <= x { - // is it worth looking at all the other k? - for l := k; l <= kmax; l += 2 { - x := e.vf.get(df, l) - y := x - l - u := e.vb.get(db, l-e.delta) - v := u - l - if x == u || u == 0 || v == 0 || y == e.uy || x == e.ux { - return l, true - } - } - return k, true - } - } - return 0, false -} - -func (e *editGraph) twolcs(df, db, kf int) lcs { - // db==df || db+1==df - x := e.vf.get(df, kf) - y := x - kf - kb := kf - e.delta - u := e.vb.get(db, kb) - v := u - kf - - // Myers proved there is a df-path from (0,0) to (u,v) - // and a db-path from (x,y) to (N,M). - // In the first case the overall path is the forward path - // to (u,v) followed by the backward path to (N,M). - // In the second case the path is the backward path to (x,y) - // followed by the forward path to (x,y) from (0,0). - - // Look for some special cases to avoid computing either of these paths. - if x == u { - // "babaab" "cccaba" - // already patched together - lcs := e.forwardlcs(df, kf) - lcs = append(lcs, e.backwardlcs(db, kb)...) - return lcs.sort() - } - - // is (u-1,v) or (u,v-1) labelled df-1? - // if so, that forward df-1-path plus a horizontal or vertical edge - // is the df-path to (u,v), then plus the db-path to (N,M) - if u > 0 && ok(df-1, u-1-v) && e.vf.get(df-1, u-1-v) == u-1 { - // "aabbab" "cbcabc" - lcs := e.forwardlcs(df-1, u-1-v) - lcs = append(lcs, e.backwardlcs(db, kb)...) - return lcs.sort() - } - if v > 0 && ok(df-1, (u-(v-1))) && e.vf.get(df-1, u-(v-1)) == u { - // "abaabb" "bcacab" - lcs := e.forwardlcs(df-1, u-(v-1)) - lcs = append(lcs, e.backwardlcs(db, kb)...) - return lcs.sort() - } - - // The path can't possibly contribute to the lcs because it - // is all horizontal or vertical edges - if u == 0 || v == 0 || x == e.ux || y == e.uy { - // "abaabb" "abaaaa" - if u == 0 || v == 0 { - return e.backwardlcs(db, kb) - } - return e.forwardlcs(df, kf) - } - - // is (x+1,y) or (x,y+1) labelled db-1? - if x+1 <= e.ux && ok(db-1, x+1-y-e.delta) && e.vb.get(db-1, x+1-y-e.delta) == x+1 { - // "bababb" "baaabb" - lcs := e.backwardlcs(db-1, kb+1) - lcs = append(lcs, e.forwardlcs(df, kf)...) - return lcs.sort() - } - if y+1 <= e.uy && ok(db-1, x-(y+1)-e.delta) && e.vb.get(db-1, x-(y+1)-e.delta) == x { - // "abbbaa" "cabacc" - lcs := e.backwardlcs(db-1, kb-1) - lcs = append(lcs, e.forwardlcs(df, kf)...) - return lcs.sort() - } - - // need to compute another path - // "aabbaa" "aacaba" - lcs := e.backwardlcs(db, kb) - oldx, oldy := e.ux, e.uy - e.ux = u - e.uy = v - lcs = append(lcs, forward(e)...) - e.ux, e.uy = oldx, oldy - return lcs.sort() -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/lcs/sequence.go b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/lcs/sequence.go deleted file mode 100644 index 2d72d26304..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/lcs/sequence.go +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package lcs - -// This file defines the abstract sequence over which the LCS algorithm operates. - -// sequences abstracts a pair of sequences, A and B. -type sequences interface { - lengths() (int, int) // len(A), len(B) - commonPrefixLen(ai, aj, bi, bj int) int // len(commonPrefix(A[ai:aj], B[bi:bj])) - commonSuffixLen(ai, aj, bi, bj int) int // len(commonSuffix(A[ai:aj], B[bi:bj])) -} - -type stringSeqs struct{ a, b string } - -func (s stringSeqs) lengths() (int, int) { return len(s.a), len(s.b) } -func (s stringSeqs) commonPrefixLen(ai, aj, bi, bj int) int { - return commonPrefixLenString(s.a[ai:aj], s.b[bi:bj]) -} -func (s stringSeqs) commonSuffixLen(ai, aj, bi, bj int) int { - return commonSuffixLenString(s.a[ai:aj], s.b[bi:bj]) -} - -// The explicit capacity in s[i:j:j] leads to more efficient code. - -type bytesSeqs struct{ a, b []byte } - -func (s bytesSeqs) lengths() (int, int) { return len(s.a), len(s.b) } -func (s bytesSeqs) commonPrefixLen(ai, aj, bi, bj int) int { - return commonPrefixLenBytes(s.a[ai:aj:aj], s.b[bi:bj:bj]) -} -func (s bytesSeqs) commonSuffixLen(ai, aj, bi, bj int) int { - return commonSuffixLenBytes(s.a[ai:aj:aj], s.b[bi:bj:bj]) -} - -type runesSeqs struct{ a, b []rune } - -func (s runesSeqs) lengths() (int, int) { return len(s.a), len(s.b) } -func (s runesSeqs) commonPrefixLen(ai, aj, bi, bj int) int { - return commonPrefixLenRunes(s.a[ai:aj:aj], s.b[bi:bj:bj]) -} -func (s runesSeqs) commonSuffixLen(ai, aj, bi, bj int) int { - return commonSuffixLenRunes(s.a[ai:aj:aj], s.b[bi:bj:bj]) -} - -// TODO(adonovan): optimize these functions using ideas from: -// - https://go.dev/cl/408116 common.go -// - https://go.dev/cl/421435 xor_generic.go - -// TODO(adonovan): factor using generics when available, -// but measure performance impact. - -// commonPrefixLen* returns the length of the common prefix of a[ai:aj] and b[bi:bj]. -func commonPrefixLenBytes(a, b []byte) int { - n := min(len(a), len(b)) - i := 0 - for i < n && a[i] == b[i] { - i++ - } - return i -} -func commonPrefixLenRunes(a, b []rune) int { - n := min(len(a), len(b)) - i := 0 - for i < n && a[i] == b[i] { - i++ - } - return i -} -func commonPrefixLenString(a, b string) int { - n := min(len(a), len(b)) - i := 0 - for i < n && a[i] == b[i] { - i++ - } - return i -} - -// commonSuffixLen* returns the length of the common suffix of a[ai:aj] and b[bi:bj]. -func commonSuffixLenBytes(a, b []byte) int { - n := min(len(a), len(b)) - i := 0 - for i < n && a[len(a)-1-i] == b[len(b)-1-i] { - i++ - } - return i -} -func commonSuffixLenRunes(a, b []rune) int { - n := min(len(a), len(b)) - i := 0 - for i < n && a[len(a)-1-i] == b[len(b)-1-i] { - i++ - } - return i -} -func commonSuffixLenString(a, b string) int { - n := min(len(a), len(b)) - i := 0 - for i < n && a[len(a)-1-i] == b[len(b)-1-i] { - i++ - } - return i -} - -func min(x, y int) int { - if x < y { - return x - } else { - return y - } -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/ndiff.go b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/ndiff.go deleted file mode 100644 index 1c64d1ecdf..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/ndiff.go +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package diff - -import ( - "bytes" - "unicode/utf8" - - "github.com/golangci/golangci-lint/v2/internal/x/tools/diff/lcs" -) - -// Strings computes the differences between two strings. -// The resulting edits respect rune boundaries. -func Strings(before, after string) []Edit { - if before == after { - return nil // common case - } - - if isASCII(before) && isASCII(after) { - // TODO(adonovan): opt: specialize diffASCII for strings. - return diffASCII([]byte(before), []byte(after)) - } - return diffRunes([]rune(before), []rune(after)) -} - -// Bytes computes the differences between two byte slices. -// The resulting edits respect rune boundaries. -func Bytes(before, after []byte) []Edit { - if bytes.Equal(before, after) { - return nil // common case - } - - if isASCII(before) && isASCII(after) { - return diffASCII(before, after) - } - return diffRunes(runes(before), runes(after)) -} - -func diffASCII(before, after []byte) []Edit { - diffs := lcs.DiffBytes(before, after) - - // Convert from LCS diffs. - res := make([]Edit, len(diffs)) - for i, d := range diffs { - res[i] = Edit{d.Start, d.End, string(after[d.ReplStart:d.ReplEnd])} - } - return res -} - -func diffRunes(before, after []rune) []Edit { - diffs := lcs.DiffRunes(before, after) - - // The diffs returned by the lcs package use indexes - // into whatever slice was passed in. - // Convert rune offsets to byte offsets. - res := make([]Edit, len(diffs)) - lastEnd := 0 - utf8Len := 0 - for i, d := range diffs { - utf8Len += runesLen(before[lastEnd:d.Start]) // text between edits - start := utf8Len - utf8Len += runesLen(before[d.Start:d.End]) // text deleted by this edit - res[i] = Edit{start, utf8Len, string(after[d.ReplStart:d.ReplEnd])} - lastEnd = d.End - } - return res -} - -// runes is like []rune(string(bytes)) without the duplicate allocation. -func runes(bytes []byte) []rune { - n := utf8.RuneCount(bytes) - runes := make([]rune, n) - for i := range n { - r, sz := utf8.DecodeRune(bytes) - bytes = bytes[sz:] - runes[i] = r - } - return runes -} - -// runesLen returns the length in bytes of the UTF-8 encoding of runes. -func runesLen(runes []rune) (len int) { - for _, r := range runes { - len += utf8.RuneLen(r) - } - return len -} - -// isASCII reports whether s contains only ASCII. -func isASCII[S string | []byte](s S) bool { - for i := 0; i < len(s); i++ { - if s[i] >= utf8.RuneSelf { - return false - } - } - return true -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/readme.md b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/readme.md deleted file mode 100644 index b28e41d9c0..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/readme.md +++ /dev/null @@ -1,11 +0,0 @@ -# diff - -Extracted from `/internal/diff/` (related to `fixer`). -This is just a copy of the code without any changes. - -## History - -- https://github.com/golangci/golangci-lint/pull/6076 - - sync with https://github.com/golang/tools/blob/v0.37.0/internal/diff/ -- https://github.com/golangci/golangci-lint/pull/5576 - - sync with https://github.com/golang/tools/blob/v0.28.0/internal/diff/ diff --git a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/unified.go b/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/unified.go deleted file mode 100644 index 9a786dbbef..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/internal/x/tools/diff/unified.go +++ /dev/null @@ -1,251 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package diff - -import ( - "fmt" - "log" - "strings" -) - -// DefaultContextLines is the number of unchanged lines of surrounding -// context displayed by Unified. Use ToUnified to specify a different value. -const DefaultContextLines = 3 - -// Unified returns a unified diff of the old and new strings. -// The old and new labels are the names of the old and new files. -// If the strings are equal, it returns the empty string. -func Unified(oldLabel, newLabel, old, new string) string { - edits := Strings(old, new) - unified, err := ToUnified(oldLabel, newLabel, old, edits, DefaultContextLines) - if err != nil { - // Can't happen: edits are consistent. - log.Fatalf("internal error in diff.Unified: %v", err) - } - return unified -} - -// ToUnified applies the edits to content and returns a unified diff, -// with contextLines lines of (unchanged) context around each diff hunk. -// The old and new labels are the names of the content and result files. -// It returns an error if the edits are inconsistent; see ApplyEdits. -func ToUnified(oldLabel, newLabel, content string, edits []Edit, contextLines int) (string, error) { - u, err := toUnified(oldLabel, newLabel, content, edits, contextLines) - if err != nil { - return "", err - } - return u.String(), nil -} - -// unified represents a set of edits as a unified diff. -type unified struct { - // from is the name of the original file. - from string - // to is the name of the modified file. - to string - // hunks is the set of edit hunks needed to transform the file content. - hunks []*hunk -} - -// Hunk represents a contiguous set of line edits to apply. -type hunk struct { - // The line in the original source where the hunk starts. - fromLine int - // The line in the original source where the hunk finishes. - toLine int - // The set of line based edits to apply. - lines []line -} - -// Line represents a single line operation to apply as part of a Hunk. -type line struct { - // kind is the type of line this represents, deletion, insertion or copy. - kind opKind - // content is the content of this line. - // For deletion it is the line being removed, for all others it is the line - // to put in the output. - content string -} - -// opKind is used to denote the type of operation a line represents. -type opKind int - -const ( - // opDelete is the operation kind for a line that is present in the input - // but not in the output. - opDelete opKind = iota - // opInsert is the operation kind for a line that is new in the output. - opInsert - // opEqual is the operation kind for a line that is the same in the input and - // output, often used to provide context around edited lines. - opEqual -) - -// String returns a human readable representation of an OpKind. It is not -// intended for machine processing. -func (k opKind) String() string { - switch k { - case opDelete: - return "delete" - case opInsert: - return "insert" - case opEqual: - return "equal" - default: - panic("unknown operation kind") - } -} - -// toUnified takes a file contents and a sequence of edits, and calculates -// a unified diff that represents those edits. -func toUnified(fromName, toName string, content string, edits []Edit, contextLines int) (unified, error) { - gap := contextLines * 2 - u := unified{ - from: fromName, - to: toName, - } - if len(edits) == 0 { - return u, nil - } - var err error - edits, err = lineEdits(content, edits) // expand to whole lines - if err != nil { - return u, err - } - lines := splitLines(content) - var h *hunk - last := 0 - toLine := 0 - for _, edit := range edits { - // Compute the zero-based line numbers of the edit start and end. - // TODO(adonovan): opt: compute incrementally, avoid O(n^2). - start := strings.Count(content[:edit.Start], "\n") - end := strings.Count(content[:edit.End], "\n") - if edit.End == len(content) && len(content) > 0 && content[len(content)-1] != '\n' { - end++ // EOF counts as an implicit newline - } - - switch { - case h != nil && start == last: - // direct extension - case h != nil && start <= last+gap: - // within range of previous lines, add the joiners - addEqualLines(h, lines, last, start) - default: - // need to start a new hunk - if h != nil { - // add the edge to the previous hunk - addEqualLines(h, lines, last, last+contextLines) - u.hunks = append(u.hunks, h) - } - toLine += start - last - h = &hunk{ - fromLine: start + 1, - toLine: toLine + 1, - } - // add the edge to the new hunk - delta := addEqualLines(h, lines, start-contextLines, start) - h.fromLine -= delta - h.toLine -= delta - } - last = start - for i := start; i < end; i++ { - h.lines = append(h.lines, line{kind: opDelete, content: lines[i]}) - last++ - } - if edit.New != "" { - for _, content := range splitLines(edit.New) { - h.lines = append(h.lines, line{kind: opInsert, content: content}) - toLine++ - } - } - } - if h != nil { - // add the edge to the final hunk - addEqualLines(h, lines, last, last+contextLines) - u.hunks = append(u.hunks, h) - } - return u, nil -} - -func splitLines(text string) []string { - lines := strings.SplitAfter(text, "\n") - if lines[len(lines)-1] == "" { - lines = lines[:len(lines)-1] - } - return lines -} - -func addEqualLines(h *hunk, lines []string, start, end int) int { - delta := 0 - for i := start; i < end; i++ { - if i < 0 { - continue - } - if i >= len(lines) { - return delta - } - h.lines = append(h.lines, line{kind: opEqual, content: lines[i]}) - delta++ - } - return delta -} - -// String converts a unified diff to the standard textual form for that diff. -// The output of this function can be passed to tools like patch. -func (u unified) String() string { - if len(u.hunks) == 0 { - return "" - } - b := new(strings.Builder) - fmt.Fprintf(b, "--- %s\n", u.from) - fmt.Fprintf(b, "+++ %s\n", u.to) - for _, hunk := range u.hunks { - fromCount, toCount := 0, 0 - for _, l := range hunk.lines { - switch l.kind { - case opDelete: - fromCount++ - case opInsert: - toCount++ - default: - fromCount++ - toCount++ - } - } - fmt.Fprint(b, "@@") - if fromCount > 1 { - fmt.Fprintf(b, " -%d,%d", hunk.fromLine, fromCount) - } else if hunk.fromLine == 1 && fromCount == 0 { - // Match odd GNU diff -u behavior adding to empty file. - fmt.Fprintf(b, " -0,0") - } else { - fmt.Fprintf(b, " -%d", hunk.fromLine) - } - if toCount > 1 { - fmt.Fprintf(b, " +%d,%d", hunk.toLine, toCount) - } else if hunk.toLine == 1 && toCount == 0 { - // Match odd GNU diff -u behavior adding to empty file. - fmt.Fprintf(b, " +0,0") - } else { - fmt.Fprintf(b, " +%d", hunk.toLine) - } - fmt.Fprint(b, " @@\n") - for _, l := range hunk.lines { - switch l.kind { - case opDelete: - fmt.Fprintf(b, "-%s", l.content) - case opInsert: - fmt.Fprintf(b, "+%s", l.content) - default: - fmt.Fprintf(b, " %s", l.content) - } - if !strings.HasSuffix(l.content, "\n") { - fmt.Fprintf(b, "\n\\ No newline at end of file\n") - } - } - } - return b.String() -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/cache.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/cache.go deleted file mode 100644 index 9772841c94..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/cache.go +++ /dev/null @@ -1,83 +0,0 @@ -package commands - -import ( - "fmt" - "os" - "path/filepath" - - "github.com/spf13/cobra" - - "github.com/golangci/golangci-lint/v2/internal/cache" - "github.com/golangci/golangci-lint/v2/pkg/fsutils" - "github.com/golangci/golangci-lint/v2/pkg/logutils" -) - -type cacheCommand struct { - cmd *cobra.Command -} - -func newCacheCommand() *cacheCommand { - c := &cacheCommand{} - - cacheCmd := &cobra.Command{ - Use: "cache", - Short: "Cache control and information.", - Args: cobra.NoArgs, - RunE: func(cmd *cobra.Command, _ []string) error { - return cmd.Help() - }, - } - - cacheCmd.AddCommand( - &cobra.Command{ - Use: "clean", - Short: "Clean cache", - Args: cobra.NoArgs, - ValidArgsFunction: cobra.NoFileCompletions, - RunE: c.executeClean, - }, - &cobra.Command{ - Use: "status", - Short: "Show cache status", - Args: cobra.NoArgs, - ValidArgsFunction: cobra.NoFileCompletions, - Run: c.executeStatus, - }, - ) - - c.cmd = cacheCmd - - return c -} - -func (*cacheCommand) executeClean(_ *cobra.Command, _ []string) error { - cacheDir := cache.DefaultDir() - - if err := os.RemoveAll(cacheDir); err != nil { - return fmt.Errorf("failed to remove dir %s: %w", cacheDir, err) - } - - return nil -} - -func (*cacheCommand) executeStatus(_ *cobra.Command, _ []string) { - cacheDir := cache.DefaultDir() - - _, _ = fmt.Fprintf(logutils.StdOut, "Dir: %s\n", cacheDir) - - cacheSizeBytes, err := dirSizeBytes(cacheDir) - if err == nil { - _, _ = fmt.Fprintf(logutils.StdOut, "Size: %s\n", fsutils.PrettifyBytesCount(cacheSizeBytes)) - } -} - -func dirSizeBytes(path string) (int64, error) { - var size int64 - err := filepath.Walk(path, func(_ string, info os.FileInfo, err error) error { - if err == nil && !info.IsDir() { - size += info.Size() - } - return err - }) - return size, err -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/config.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/config.go deleted file mode 100644 index b1889fa426..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/config.go +++ /dev/null @@ -1,149 +0,0 @@ -package commands - -import ( - "encoding/json" - "fmt" - "os" - "path/filepath" - - "github.com/fatih/color" - "github.com/spf13/cobra" - "github.com/spf13/viper" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/exitcodes" - "github.com/golangci/golangci-lint/v2/pkg/fsutils" - "github.com/golangci/golangci-lint/v2/pkg/logutils" -) - -type pathOptions struct { - JSON bool -} - -type configCommand struct { - viper *viper.Viper - cmd *cobra.Command - - opts config.LoaderOptions - verifyOpts verifyOptions - pathOpts pathOptions - - buildInfo BuildInfo - - log logutils.Log -} - -func newConfigCommand(log logutils.Log, info BuildInfo) *configCommand { - c := &configCommand{ - viper: viper.New(), - log: log, - buildInfo: info, - } - - configCmd := &cobra.Command{ - Use: "config", - Short: "Configuration file information and verification.", - Args: cobra.NoArgs, - RunE: func(cmd *cobra.Command, _ []string) error { - return cmd.Help() - }, - PersistentPreRunE: c.preRunE, - } - - verifyCommand := &cobra.Command{ - Use: "verify", - Short: "Verify configuration against JSON schema.", - Args: cobra.NoArgs, - ValidArgsFunction: cobra.NoFileCompletions, - RunE: c.executeVerify, - SilenceUsage: true, - SilenceErrors: true, - } - - pathCommand := &cobra.Command{ - Use: "path", - Short: "Print used configuration path.", - Args: cobra.NoArgs, - ValidArgsFunction: cobra.NoFileCompletions, - RunE: c.executePath, - } - - configCmd.AddCommand( - pathCommand, - verifyCommand, - ) - - flagSet := configCmd.PersistentFlags() - flagSet.SortFlags = false // sort them as they are defined here - - setupConfigFileFlagSet(flagSet, &c.opts) - - // ex: --schema jsonschema/golangci.next.jsonschema.json - verifyFlagSet := verifyCommand.Flags() - verifyFlagSet.StringVar(&c.verifyOpts.schemaURL, "schema", "", color.GreenString("JSON schema URL")) - _ = verifyFlagSet.MarkHidden("schema") - - pathFlagSet := pathCommand.Flags() - pathFlagSet.BoolVar(&c.pathOpts.JSON, "json", false, color.GreenString("Display as JSON")) - - c.cmd = configCmd - - return c -} - -func (c *configCommand) preRunE(cmd *cobra.Command, args []string) error { - // The command doesn't depend on the real configuration. - // It only needs to know the path of the configuration file. - cfg := config.NewDefault() - - loader := config.NewLintersLoader(c.log.Child(logutils.DebugKeyConfigReader), c.viper, cmd.Flags(), c.opts, cfg, args) - - err := loader.Load(config.LoadOptions{}) - if err != nil { - return fmt.Errorf("can't load config: %w", err) - } - - return nil -} - -func (c *configCommand) executePath(cmd *cobra.Command, _ []string) error { - usedConfigFile := c.getUsedConfig() - - if c.pathOpts.JSON { - abs, err := filepath.Abs(usedConfigFile) - if err != nil { - return err - } - - return json.NewEncoder(cmd.OutOrStdout()).Encode(map[string]string{ - "path": usedConfigFile, - "absolutePath": abs, - }) - } - - if usedConfigFile == "" { - c.log.Warnf("No config file detected") - os.Exit(exitcodes.NoConfigFileDetected) - } - - cmd.Println(usedConfigFile) - - return nil -} - -// getUsedConfig returns the resolved path to the golangci config file, -// or the empty string if no configuration could be found. -func (c *configCommand) getUsedConfig() string { - usedConfigFile := c.viper.ConfigFileUsed() - if usedConfigFile == "" { - return "" - } - - prettyUsedConfigFile, err := fsutils.ShortestRelPath(usedConfigFile, "") - if err != nil { - c.log.Warnf("Can't pretty print config file path: %s", err) - return usedConfigFile - } - - return prettyUsedConfigFile -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/config_verify.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/config_verify.go deleted file mode 100644 index ef7a4e094d..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/config_verify.go +++ /dev/null @@ -1,239 +0,0 @@ -package commands - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "net/http" - "os" - "path/filepath" - "strconv" - "strings" - "time" - - hcversion "github.com/hashicorp/go-version" - "github.com/pelletier/go-toml/v2" - "github.com/santhosh-tekuri/jsonschema/v6" - "github.com/spf13/cobra" - "github.com/spf13/pflag" - "gopkg.in/yaml.v3" - - "github.com/golangci/golangci-lint/v2/pkg/exitcodes" -) - -type verifyOptions struct { - schemaURL string // For debugging purpose only (Flag only). -} - -func (c *configCommand) executeVerify(cmd *cobra.Command, _ []string) error { - usedConfigFile := c.getUsedConfig() - if usedConfigFile == "" { - c.log.Warnf("No config file detected") - os.Exit(exitcodes.NoConfigFileDetected) - } - - schemaURL, err := createSchemaURL(cmd.Flags(), c.buildInfo) - if err != nil { - return fmt.Errorf("get JSON schema: %w", err) - } - - err = validateConfiguration(schemaURL, usedConfigFile) - if err != nil { - var v *jsonschema.ValidationError - if !errors.As(err, &v) { - return fmt.Errorf("[%s] validate: %w", usedConfigFile, err) - } - - printValidationDetail(cmd, v.DetailedOutput()) - - return errors.New("the configuration contains invalid elements") - } - - return nil -} - -func createSchemaURL(flags *pflag.FlagSet, buildInfo BuildInfo) (string, error) { - schemaURL, err := flags.GetString("schema") - if err != nil { - return "", fmt.Errorf("get schema flag: %w", err) - } - - if schemaURL != "" { - return schemaURL, nil - } - - switch { - case buildInfo.Version != "" && buildInfo.Version != "(devel)": - version, err := hcversion.NewVersion(buildInfo.Version) - if err != nil { - return "", fmt.Errorf("parse version: %w", err) - } - - if version.Core().Equal(hcversion.Must(hcversion.NewVersion("v0.0.0"))) { - commit, err := extractCommitHash(buildInfo) - if err != nil { - return "", err - } - - return fmt.Sprintf("https://raw.githubusercontent.com/golangci/golangci-lint/%s/jsonschema/golangci.next.jsonschema.json", - commit), nil - } - - return fmt.Sprintf("https://golangci-lint.run/jsonschema/golangci.v%d.%d.jsonschema.json", - version.Segments()[0], version.Segments()[1]), nil - - case buildInfo.Commit != "" && buildInfo.Commit != "?": - commit, err := extractCommitHash(buildInfo) - if err != nil { - return "", err - } - - return fmt.Sprintf("https://raw.githubusercontent.com/golangci/golangci-lint/%s/jsonschema/golangci.next.jsonschema.json", - commit), nil - - default: - return "", errors.New("version not found") - } -} - -func extractCommitHash(buildInfo BuildInfo) (string, error) { - if buildInfo.Commit == "" || buildInfo.Commit == "?" { - return "", errors.New("empty commit information") - } - - if buildInfo.Commit == "unknown" { - return "", errors.New("unknown commit information") - } - - commit := buildInfo.Commit - - if strings.HasPrefix(commit, "(") { - c, _, ok := strings.Cut(strings.TrimPrefix(commit, "("), ",") - if !ok { - return "", errors.New("commit information not found") - } - - commit = c - } - - if commit == "unknown" { - return "", errors.New("unknown commit information") - } - - return commit, nil -} - -func validateConfiguration(schemaPath, targetFile string) error { - compiler := jsonschema.NewCompiler() - compiler.UseLoader(jsonschema.SchemeURLLoader{ - "file": jsonschema.FileLoader{}, - "https": newJSONSchemaHTTPLoader(), - }) - compiler.DefaultDraft(jsonschema.Draft7) - - schema, err := compiler.Compile(schemaPath) - if err != nil { - return fmt.Errorf("compile schema: %w", err) - } - - var m any - - switch strings.ToLower(filepath.Ext(targetFile)) { - case ".yaml", ".yml", ".json": - m, err = decodeYamlFile(targetFile) - if err != nil { - return err - } - - case ".toml": - m, err = decodeTomlFile(targetFile) - if err != nil { - return err - } - - default: - // unsupported - return errors.New("unsupported configuration format") - } - - return schema.Validate(m) -} - -func printValidationDetail(cmd *cobra.Command, detail *jsonschema.OutputUnit) { - if detail.Error != nil { - data, _ := json.Marshal(detail.Error) - details, _ := strconv.Unquote(string(data)) - - cmd.PrintErrf("jsonschema: %q does not validate with %q: %s\n", - strings.ReplaceAll(strings.TrimPrefix(detail.InstanceLocation, "/"), "/", "."), detail.KeywordLocation, details) - } - - for _, d := range detail.Errors { - printValidationDetail(cmd, &d) - } -} - -func decodeYamlFile(filename string) (any, error) { - file, err := os.Open(filename) - if err != nil { - return nil, fmt.Errorf("[%s] file open: %w", filename, err) - } - - defer func() { _ = file.Close() }() - - var m any - err = yaml.NewDecoder(file).Decode(&m) - if err != nil { - return nil, fmt.Errorf("[%s] YAML decode: %w", filename, err) - } - - return m, nil -} - -func decodeTomlFile(filename string) (any, error) { - file, err := os.Open(filename) - if err != nil { - return nil, fmt.Errorf("[%s] file open: %w", filename, err) - } - - defer func() { _ = file.Close() }() - - var m any - err = toml.NewDecoder(file).Decode(&m) - if err != nil { - return nil, fmt.Errorf("[%s] TOML decode: %w", filename, err) - } - - return m, nil -} - -type jsonschemaHTTPLoader struct { - *http.Client -} - -func newJSONSchemaHTTPLoader() *jsonschemaHTTPLoader { - return &jsonschemaHTTPLoader{Client: &http.Client{ - Timeout: 2 * time.Second, - }} -} - -func (l jsonschemaHTTPLoader) Load(url string) (any, error) { - req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, url, http.NoBody) - if err != nil { - return nil, err - } - - resp, err := l.Do(req) - if err != nil { - return nil, err - } - - defer resp.Body.Close() - - if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("%s returned status code %d", url, resp.StatusCode) - } - - return jsonschema.UnmarshalJSON(resp.Body) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/custom.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/custom.go deleted file mode 100644 index 227df9bee1..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/custom.go +++ /dev/null @@ -1,79 +0,0 @@ -package commands - -import ( - "fmt" - "log" - "os" - - "github.com/spf13/cobra" - - "github.com/golangci/golangci-lint/v2/pkg/commands/internal" - "github.com/golangci/golangci-lint/v2/pkg/logutils" -) - -const envKeepTempFiles = "CUSTOM_GCL_KEEP_TEMP_FILES" - -type customCommand struct { - cmd *cobra.Command - - cfg *internal.Configuration - - log logutils.Log -} - -func newCustomCommand(logger logutils.Log) *customCommand { - c := &customCommand{log: logger} - - customCmd := &cobra.Command{ - Use: "custom", - Short: "Build a version of golangci-lint with custom linters.", - Args: cobra.NoArgs, - PreRunE: c.preRunE, - RunE: c.runE, - SilenceUsage: true, - } - - c.cmd = customCmd - - return c -} - -func (c *customCommand) preRunE(_ *cobra.Command, _ []string) error { - cfg, err := internal.LoadConfiguration() - if err != nil { - return err - } - - err = cfg.Validate() - if err != nil { - return err - } - - c.cfg = cfg - - return nil -} - -func (c *customCommand) runE(cmd *cobra.Command, _ []string) error { - tmp, err := os.MkdirTemp(os.TempDir(), "custom-gcl") - if err != nil { - return fmt.Errorf("create temporary directory: %w", err) - } - - defer func() { - if os.Getenv(envKeepTempFiles) != "" { - log.Printf("WARN: The env var %s has been detected: the temporary directory is preserved: %s", envKeepTempFiles, tmp) - - return - } - - _ = os.RemoveAll(tmp) - }() - - err = internal.NewBuilder(c.log, c.cfg, tmp).Build(cmd.Context()) - if err != nil { - return fmt.Errorf("build process: %w", err) - } - - return nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/flagsets.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/flagsets.go deleted file mode 100644 index 2b61217c65..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/flagsets.go +++ /dev/null @@ -1,142 +0,0 @@ -package commands - -import ( - "github.com/fatih/color" - "github.com/spf13/pflag" - "github.com/spf13/viper" - - "github.com/golangci/golangci-lint/v2/pkg/commands/internal" - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/exitcodes" -) - -const defaultMaxIssuesPerLinter = 50 - -func setupLintersFlagSet(v *viper.Viper, fs *pflag.FlagSet) { - internal.AddFlagAndBind(v, fs, fs.String, "default", "linters.default", config.GroupStandard, - color.GreenString("Default set of linters to enable")) - - internal.AddHackedStringSliceP(fs, "disable", "D", color.GreenString("Disable specific linter")) - internal.AddHackedStringSliceP(fs, "enable", "E", color.GreenString("Enable specific linter")) - - fs.StringSlice("enable-only", nil, - color.GreenString("Override linters configuration section to only run the specific linter(s)")) // Flags only. - - internal.AddFlagAndBind(v, fs, fs.Bool, "fast-only", "linters.fast-only", false, - color.GreenString("Filter enabled linters to run only fast linters")) -} - -func setupFormattersFlagSet(v *viper.Viper, fs *pflag.FlagSet) { - internal.AddFlagAndBindP(v, fs, fs.StringSliceP, "enable", "E", "formatters.enable", nil, - color.GreenString("Enable specific formatter")) -} - -func setupRunFlagSet(v *viper.Viper, fs *pflag.FlagSet) { - internal.AddFlagAndBindP(v, fs, fs.IntP, "concurrency", "j", "run.concurrency", 0, - color.GreenString("Number of CPUs to use (Default: Automatically set to match Linux container CPU quota"+ - " and fall back to the number of logical CPUs in the machine)")) - - internal.AddFlagAndBind(v, fs, fs.String, "modules-download-mode", "run.modules-download-mode", "", - color.GreenString("Modules download mode. If not empty, passed as -mod= to go tools")) - internal.AddFlagAndBind(v, fs, fs.Int, "issues-exit-code", "run.issues-exit-code", exitcodes.IssuesFound, - color.GreenString("Exit code when issues were found")) - internal.AddHackedStringSlice(fs, "build-tags", color.GreenString("Build tags")) - - internal.AddFlagAndBind(v, fs, fs.Duration, "timeout", "run.timeout", defaultTimeout, - color.GreenString("Timeout for total work. Disabled by default")) - - internal.AddFlagAndBind(v, fs, fs.Bool, "tests", "run.tests", true, color.GreenString("Analyze tests (*_test.go)")) - - internal.AddDeprecatedHackedStringSlice(fs, "skip-files", color.GreenString("Regexps of files to skip")) - internal.AddDeprecatedHackedStringSlice(fs, "skip-dirs", color.GreenString("Regexps of directories to skip")) - - const allowParallelDesc = "Allow multiple parallel golangci-lint instances running.\n" + - "If false (default) - golangci-lint acquires file lock on start." - internal.AddFlagAndBind(v, fs, fs.Bool, "allow-parallel-runners", "run.allow-parallel-runners", false, - color.GreenString(allowParallelDesc)) - const allowSerialDesc = "Allow multiple golangci-lint instances running, but serialize them around a lock.\n" + - "If false (default) - golangci-lint exits with an error if it fails to acquire file lock on start." - internal.AddFlagAndBind(v, fs, fs.Bool, "allow-serial-runners", "run.allow-serial-runners", false, color.GreenString(allowSerialDesc)) -} - -func setupOutputFlagSet(v *viper.Viper, fs *pflag.FlagSet) { - internal.AddFlagAndBind(v, fs, fs.String, "path-prefix", "output.path-prefix", "", - color.GreenString("Path prefix to add to output")) - internal.AddFlagAndBind(v, fs, fs.String, "path-mode", "output.path-mode", "", - color.GreenString("Path mode to use (empty, or 'abs')")) - internal.AddFlagAndBind(v, fs, fs.Bool, "show-stats", "output.show-stats", true, color.GreenString("Show statistics per linter")) - - setupOutputFormatsFlagSet(v, fs) -} - -func setupOutputFormatsFlagSet(v *viper.Viper, fs *pflag.FlagSet) { - outputPathDesc := "Output path can be either `stdout`, `stderr` or path to the file to write to." - printLinterNameDesc := "Print linter name in the end of issue text." - colorsDesc := "Use colors." - - internal.AddFlagAndBind(v, fs, fs.String, "output.text.path", "output.formats.text.path", "", - color.GreenString(outputPathDesc)) - internal.AddFlagAndBind(v, fs, fs.Bool, "output.text.print-linter-name", "output.formats.text.print-linter-name", true, - color.GreenString(printLinterNameDesc)) - internal.AddFlagAndBind(v, fs, fs.Bool, "output.text.print-issued-lines", "output.formats.text.print-issued-lines", true, - color.GreenString("Print lines of code with issue.")) - internal.AddFlagAndBind(v, fs, fs.Bool, "output.text.colors", "output.formats.text.colors", true, - color.GreenString(colorsDesc)) - - internal.AddFlagAndBind(v, fs, fs.String, "output.json.path", "output.formats.json.path", "", - color.GreenString(outputPathDesc)) - - internal.AddFlagAndBind(v, fs, fs.String, "output.tab.path", "output.formats.tab.path", "", - color.GreenString(outputPathDesc)) - internal.AddFlagAndBind(v, fs, fs.Bool, "output.tab.print-linter-name", "output.formats.tab.print-linter-name", - true, color.GreenString(printLinterNameDesc)) - internal.AddFlagAndBind(v, fs, fs.Bool, "output.tab.colors", "output.formats.tab.colors", true, - color.GreenString(colorsDesc)) - - internal.AddFlagAndBind(v, fs, fs.String, "output.html.path", "output.formats.html.path", "", - color.GreenString(outputPathDesc)) - - internal.AddFlagAndBind(v, fs, fs.String, "output.checkstyle.path", "output.formats.checkstyle.path", "", - color.GreenString(outputPathDesc)) - - internal.AddFlagAndBind(v, fs, fs.String, "output.code-climate.path", "output.formats.code-climate.path", "", - color.GreenString(outputPathDesc)) - - internal.AddFlagAndBind(v, fs, fs.String, "output.junit-xml.path", "output.formats.junit-xml.path", "", - color.GreenString(outputPathDesc)) - internal.AddFlagAndBind(v, fs, fs.Bool, "output.junit-xml.extended", "output.formats.junit-xml.extended", false, - color.GreenString("Support extra JUnit XML fields.")) - - internal.AddFlagAndBind(v, fs, fs.String, "output.teamcity.path", "output.formats.teamcity.path", "", - color.GreenString(outputPathDesc)) - - internal.AddFlagAndBind(v, fs, fs.String, "output.sarif.path", "output.formats.sarif.path", "", - color.GreenString(outputPathDesc)) -} - -func setupIssuesFlagSet(v *viper.Viper, fs *pflag.FlagSet) { - internal.AddFlagAndBind(v, fs, fs.Int, "max-issues-per-linter", "issues.max-issues-per-linter", defaultMaxIssuesPerLinter, - color.GreenString("Maximum issues count per one linter. Set to 0 to disable")) - internal.AddFlagAndBind(v, fs, fs.Int, "max-same-issues", "issues.max-same-issues", 3, - color.GreenString("Maximum count of issues with the same text. Set to 0 to disable")) - internal.AddFlagAndBind(v, fs, fs.Bool, "uniq-by-line", "issues.uniq-by-line", true, - color.GreenString("Make issues output unique by line")) - - const newDesc = "Show only new issues: if there are unstaged changes or untracked files, only those changes " + - "are analyzed, else only changes in HEAD~ are analyzed.\nIt's a super-useful option for integration " + - "of golangci-lint into existing large codebase.\nIt's not practical to fix all existing issues at " + - "the moment of integration: much better to not allow issues in new code.\nFor CI setups, prefer " + - "--new-from-rev=HEAD~, as --new can skip linting the current patch if any scripts generate " + - "unstaged files before golangci-lint runs." - internal.AddFlagAndBindP(v, fs, fs.BoolP, "new", "n", "issues.new", false, color.GreenString(newDesc)) - internal.AddFlagAndBind(v, fs, fs.String, "new-from-rev", "issues.new-from-rev", "", - color.GreenString("Show only new issues created after git revision `REV`")) - internal.AddFlagAndBind(v, fs, fs.String, "new-from-patch", "issues.new-from-patch", "", - color.GreenString("Show only new issues created in git patch with file path `PATH`")) - internal.AddFlagAndBind(v, fs, fs.String, "new-from-merge-base", "issues.new-from-merge-base", "", - color.GreenString("Show only new issues created after the best common ancestor (merge-base against HEAD)")) - internal.AddFlagAndBind(v, fs, fs.Bool, "whole-files", "issues.whole-files", false, - color.GreenString("Show issues in any part of update files (requires new-from-rev or new-from-patch)")) - internal.AddFlagAndBind(v, fs, fs.Bool, "fix", "issues.fix", false, - color.GreenString("Apply the fixes detected by the linters and formatters (if it's supported by the linter)")) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/fmt.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/fmt.go deleted file mode 100644 index ab1aef45b6..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/fmt.go +++ /dev/null @@ -1,145 +0,0 @@ -package commands - -import ( - "fmt" - "os" - "path/filepath" - "strings" - - "github.com/fatih/color" - "github.com/spf13/cobra" - "github.com/spf13/viper" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goformat" - "github.com/golangci/golangci-lint/v2/pkg/goformatters" - "github.com/golangci/golangci-lint/v2/pkg/logutils" - "github.com/golangci/golangci-lint/v2/pkg/result/processors" -) - -type fmtOptions struct { - config.LoaderOptions - - diff bool // Flag only. - diffColored bool // Flag only. - stdin bool // Flag only. -} - -type fmtCommand struct { - viper *viper.Viper - cmd *cobra.Command - - opts fmtOptions - - cfg *config.Config - - buildInfo BuildInfo - - runner *goformat.Runner - - log logutils.Log -} - -func newFmtCommand(logger logutils.Log, info BuildInfo) *fmtCommand { - c := &fmtCommand{ - viper: viper.New(), - log: logger, - cfg: config.NewDefault(), - buildInfo: info, - } - - fmtCmd := &cobra.Command{ - Use: "fmt", - Short: "Format Go source files.", - RunE: c.execute, - PreRunE: c.preRunE, - PersistentPreRunE: c.persistentPreRunE, - PersistentPostRun: c.persistentPostRun, - SilenceUsage: true, - } - - fmtCmd.SetOut(logutils.StdOut) // use custom output to properly color it in Windows terminals - fmtCmd.SetErr(logutils.StdErr) - - fs := fmtCmd.Flags() - fs.SortFlags = false // sort them as they are defined here - - setupConfigFileFlagSet(fs, &c.opts.LoaderOptions) - - setupFormattersFlagSet(c.viper, fs) - - fs.BoolVarP(&c.opts.diff, "diff", "d", false, color.GreenString("Display diffs instead of rewriting files")) - fs.BoolVar(&c.opts.diffColored, "diff-colored", false, color.GreenString("Display diffs instead of rewriting files (with colors)")) - fs.BoolVar(&c.opts.stdin, "stdin", false, color.GreenString("Use standard input for piping source files")) - - c.cmd = fmtCmd - - return c -} - -func (c *fmtCommand) persistentPreRunE(cmd *cobra.Command, args []string) error { - c.log.Infof("%s", c.buildInfo.String()) - - loader := config.NewFormattersLoader(c.log.Child(logutils.DebugKeyConfigReader), c.viper, cmd.Flags(), c.opts.LoaderOptions, c.cfg, args) - - err := loader.Load(config.LoadOptions{CheckDeprecation: true, Validation: true}) - if err != nil { - return fmt.Errorf("can't load config: %w", err) - } - - return nil -} - -func (c *fmtCommand) preRunE(_ *cobra.Command, _ []string) error { - if c.cfg.GetConfigDir() != "" && c.cfg.Version != "2" { - return fmt.Errorf("invalid version of the configuration: %q", c.cfg.Version) - } - - metaFormatter, err := goformatters.NewMetaFormatter(c.log, &c.cfg.Formatters, &c.cfg.Run) - if err != nil { - return fmt.Errorf("failed to create meta-formatter: %w", err) - } - - matcher := processors.NewGeneratedFileMatcher(c.cfg.Formatters.Exclusions.Generated) - - opts, err := goformat.NewRunnerOptions(c.cfg, c.opts.diff, c.opts.diffColored, c.opts.stdin) - if err != nil { - return fmt.Errorf("build walk options: %w", err) - } - - c.runner = goformat.NewRunner(c.log, metaFormatter, matcher, opts) - - return nil -} - -func (c *fmtCommand) execute(_ *cobra.Command, args []string) error { - paths := cleanArgs(args) - - c.log.Infof("Formatting Go files...") - - err := c.runner.Run(paths) - if err != nil { - return fmt.Errorf("failed to process files: %w", err) - } - - return nil -} - -func (c *fmtCommand) persistentPostRun(_ *cobra.Command, _ []string) { - if c.runner.ExitCode() != 0 { - os.Exit(c.runner.ExitCode()) - } -} - -func cleanArgs(args []string) []string { - if len(args) == 0 { - return []string{"."} - } - - var expanded []string - for _, arg := range args { - expanded = append(expanded, filepath.Clean(strings.ReplaceAll(arg, "...", ""))) - } - - return expanded -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/formatters.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/formatters.go deleted file mode 100644 index bd6e0e80fc..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/formatters.go +++ /dev/null @@ -1,137 +0,0 @@ -package commands - -import ( - "encoding/json" - "fmt" - - "github.com/fatih/color" - "github.com/spf13/cobra" - "github.com/spf13/viper" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goformatters" - "github.com/golangci/golangci-lint/v2/pkg/lint/linter" - "github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb" - "github.com/golangci/golangci-lint/v2/pkg/logutils" -) - -type formattersHelp struct { - Enabled []formatterHelp - Disabled []formatterHelp -} - -type formattersOptions struct { - config.LoaderOptions - JSON bool -} - -type formattersCommand struct { - viper *viper.Viper - cmd *cobra.Command - - opts formattersOptions - - cfg *config.Config - - log logutils.Log - - dbManager *lintersdb.Manager -} - -func newFormattersCommand(logger logutils.Log) *formattersCommand { - c := &formattersCommand{ - viper: viper.New(), - cfg: config.NewDefault(), - log: logger, - } - - formattersCmd := &cobra.Command{ - Use: "formatters", - Short: "List current formatters configuration.", - Args: cobra.NoArgs, - ValidArgsFunction: cobra.NoFileCompletions, - RunE: c.execute, - PreRunE: c.preRunE, - SilenceUsage: true, - } - - fs := formattersCmd.Flags() - fs.SortFlags = false // sort them as they are defined here - - setupConfigFileFlagSet(fs, &c.opts.LoaderOptions) - - setupFormattersFlagSet(c.viper, fs) - - fs.BoolVar(&c.opts.JSON, "json", false, color.GreenString("Display as JSON")) - - c.cmd = formattersCmd - - return c -} - -func (c *formattersCommand) preRunE(cmd *cobra.Command, args []string) error { - loader := config.NewFormattersLoader(c.log.Child(logutils.DebugKeyConfigReader), c.viper, cmd.Flags(), c.opts.LoaderOptions, c.cfg, args) - - err := loader.Load(config.LoadOptions{Validation: true}) - if err != nil { - return fmt.Errorf("can't load config: %w", err) - } - - dbManager, err := lintersdb.NewManager(c.log.Child(logutils.DebugKeyLintersDB), c.cfg, - lintersdb.NewLinterBuilder(), lintersdb.NewPluginModuleBuilder(c.log), lintersdb.NewPluginGoBuilder(c.log)) - if err != nil { - return err - } - - c.dbManager = dbManager - - return nil -} - -func (c *formattersCommand) execute(_ *cobra.Command, _ []string) error { - enabledLintersMap, err := c.dbManager.GetEnabledLintersMap() - if err != nil { - return fmt.Errorf("can't get enabled formatters: %w", err) - } - - var enabledFormatters []*linter.Config - var disabledFormatters []*linter.Config - - for _, lc := range c.dbManager.GetAllSupportedLinterConfigs() { - if lc.Internal { - continue - } - - if !goformatters.IsFormatter(lc.Name()) { - continue - } - - if enabledLintersMap[lc.Name()] == nil { - disabledFormatters = append(disabledFormatters, lc) - } else { - enabledFormatters = append(enabledFormatters, lc) - } - } - - if c.opts.JSON { - formatters := formattersHelp{} - - for _, lc := range enabledFormatters { - formatters.Enabled = append(formatters.Enabled, newFormatterHelp(lc)) - } - - for _, lc := range disabledFormatters { - formatters.Disabled = append(formatters.Disabled, newFormatterHelp(lc)) - } - - return json.NewEncoder(c.cmd.OutOrStdout()).Encode(formatters) - } - - color.Green("Enabled by your configuration formatters:\n") - printFormatters(enabledFormatters) - - color.Red("\nDisabled by your configuration formatters:\n") - printFormatters(disabledFormatters) - - return nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/help.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/help.go deleted file mode 100644 index 6e9393ddd3..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/help.go +++ /dev/null @@ -1,101 +0,0 @@ -package commands - -import ( - "strings" - "unicode" - "unicode/utf8" - - "github.com/fatih/color" - "github.com/spf13/cobra" - - "github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb" - "github.com/golangci/golangci-lint/v2/pkg/logutils" -) - -type helpOptions struct { - JSON bool -} - -type helpCommand struct { - cmd *cobra.Command - - opts helpOptions - - dbManager *lintersdb.Manager - - log logutils.Log -} - -func newHelpCommand(logger logutils.Log) *helpCommand { - c := &helpCommand{log: logger} - - helpCmd := &cobra.Command{ - Use: "help", - Short: "Display extra help", - Args: cobra.NoArgs, - RunE: func(cmd *cobra.Command, _ []string) error { - return cmd.Help() - }, - } - - lintersCmd := &cobra.Command{ - Use: "linters", - Short: "Display help for linters.", - Args: cobra.NoArgs, - ValidArgsFunction: cobra.NoFileCompletions, - RunE: c.lintersExecute, - PreRunE: c.lintersPreRunE, - } - - fsLinter := lintersCmd.Flags() - fsLinter.SortFlags = false // sort them as they are defined here - - fsLinter.BoolVar(&c.opts.JSON, "json", false, color.GreenString("Display as JSON")) - - helpCmd.AddCommand(lintersCmd) - - formattersCmd := &cobra.Command{ - Use: "formatters", - Short: "Display help for formatters.", - Args: cobra.NoArgs, - ValidArgsFunction: cobra.NoFileCompletions, - RunE: c.formattersExecute, - PreRunE: c.formattersPreRunE, - } - - fsFormatter := formattersCmd.Flags() - fsFormatter.SortFlags = false // sort them as they are defined here - - fsFormatter.BoolVar(&c.opts.JSON, "json", false, color.GreenString("Display as JSON")) - - helpCmd.AddCommand(formattersCmd) - - c.cmd = helpCmd - - return c -} - -func formatDescription(desc string) string { - desc = strings.TrimSpace(desc) - - if desc == "" { - return desc - } - - // If the linter description spans multiple lines, truncate everything following the first newline - endFirstLine := strings.IndexRune(desc, '\n') - if endFirstLine > 0 { - desc = desc[:endFirstLine] - } - - rawDesc := []rune(desc) - - r, _ := utf8.DecodeRuneInString(desc) - rawDesc[0] = unicode.ToUpper(r) - - if rawDesc[len(rawDesc)-1] != '.' { - rawDesc = append(rawDesc, '.') - } - - return string(rawDesc) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/help_formatters.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/help_formatters.go deleted file mode 100644 index e41cea368b..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/help_formatters.go +++ /dev/null @@ -1,123 +0,0 @@ -package commands - -import ( - "encoding/json" - "fmt" - "slices" - "strings" - - "github.com/fatih/color" - "github.com/spf13/cobra" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goformatters" - "github.com/golangci/golangci-lint/v2/pkg/lint/linter" - "github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb" - "github.com/golangci/golangci-lint/v2/pkg/logutils" -) - -type formatterHelp struct { - Name string `json:"name"` - Desc string `json:"description"` - Deprecated bool `json:"deprecated"` - Since string `json:"since"` - OriginalURL string `json:"originalURL,omitempty"` -} - -func newFormatterHelp(lc *linter.Config) formatterHelp { - return formatterHelp{ - Name: lc.Name(), - Desc: formatDescription(lc.Linter.Desc()), - Deprecated: lc.IsDeprecated(), - Since: lc.Since, - OriginalURL: lc.OriginalURL, - } -} - -func (c *helpCommand) formattersPreRunE(_ *cobra.Command, _ []string) error { - // The command doesn't depend on the real configuration. - dbManager, err := lintersdb.NewManager(c.log.Child(logutils.DebugKeyLintersDB), config.NewDefault(), lintersdb.NewLinterBuilder()) - if err != nil { - return err - } - - c.dbManager = dbManager - - return nil -} - -func (c *helpCommand) formattersExecute(_ *cobra.Command, _ []string) error { - if c.opts.JSON { - return c.formattersPrintJSON() - } - - c.formattersPrint() - - return nil -} - -func (c *helpCommand) formattersPrintJSON() error { - var formatters []formatterHelp - - for _, lc := range c.dbManager.GetAllSupportedLinterConfigs() { - if lc.Internal { - continue - } - - if !goformatters.IsFormatter(lc.Name()) { - continue - } - - formatters = append(formatters, newFormatterHelp(lc)) - } - - return json.NewEncoder(c.cmd.OutOrStdout()).Encode(formatters) -} - -func (c *helpCommand) formattersPrint() { - var lcs []*linter.Config - for _, lc := range c.dbManager.GetAllSupportedLinterConfigs() { - if lc.Internal { - continue - } - - if !goformatters.IsFormatter(lc.Name()) { - continue - } - - lcs = append(lcs, lc) - } - - color.Green("Disabled by default formatters:\n") - printFormatters(lcs) -} - -func printFormatters(lcs []*linter.Config) { - slices.SortFunc(lcs, func(a, b *linter.Config) int { - if a.IsDeprecated() && b.IsDeprecated() { - return strings.Compare(a.Name(), b.Name()) - } - - if a.IsDeprecated() { - return 1 - } - - if b.IsDeprecated() { - return -1 - } - - return strings.Compare(a.Name(), b.Name()) - }) - - for _, lc := range lcs { - desc := formatDescription(lc.Linter.Desc()) - - deprecatedMark := "" - if lc.IsDeprecated() { - deprecatedMark = " [" + color.RedString("deprecated") + "]" - } - - _, _ = fmt.Fprintf(logutils.StdOut, "%s%s: %s\n", - color.YellowString(lc.Name()), deprecatedMark, desc) - } -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/help_linters.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/help_linters.go deleted file mode 100644 index b4e647700d..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/help_linters.go +++ /dev/null @@ -1,156 +0,0 @@ -package commands - -import ( - "encoding/json" - "fmt" - "maps" - "slices" - "strings" - - "github.com/fatih/color" - "github.com/spf13/cobra" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goformatters" - "github.com/golangci/golangci-lint/v2/pkg/lint/linter" - "github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb" - "github.com/golangci/golangci-lint/v2/pkg/logutils" -) - -type linterHelp struct { - Name string `json:"name"` - Desc string `json:"description"` - Groups []string `json:"groups"` - Fast bool `json:"fast"` - AutoFix bool `json:"autoFix"` - Deprecated bool `json:"deprecated"` - Since string `json:"since"` - OriginalURL string `json:"originalURL,omitempty"` -} - -func newLinterHelp(lc *linter.Config) linterHelp { - groups := []string{config.GroupAll} - - if !lc.IsSlowLinter() { - groups = append(groups, config.GroupFast) - } - - return linterHelp{ - Name: lc.Name(), - Desc: formatDescription(lc.Linter.Desc()), - Groups: slices.Concat(groups, slices.Collect(maps.Keys(lc.Groups))), - Fast: !lc.IsSlowLinter(), - AutoFix: lc.CanAutoFix, - Deprecated: lc.IsDeprecated(), - Since: lc.Since, - OriginalURL: lc.OriginalURL, - } -} - -func (c *helpCommand) lintersPreRunE(_ *cobra.Command, _ []string) error { - // The command doesn't depend on the real configuration. - dbManager, err := lintersdb.NewManager(c.log.Child(logutils.DebugKeyLintersDB), config.NewDefault(), lintersdb.NewLinterBuilder()) - if err != nil { - return err - } - - c.dbManager = dbManager - - return nil -} - -func (c *helpCommand) lintersExecute(_ *cobra.Command, _ []string) error { - if c.opts.JSON { - return c.lintersPrintJSON() - } - - c.lintersPrint() - - return nil -} - -func (c *helpCommand) lintersPrintJSON() error { - var linters []linterHelp - - for _, lc := range c.dbManager.GetAllSupportedLinterConfigs() { - if lc.Internal { - continue - } - - if goformatters.IsFormatter(lc.Name()) { - continue - } - - linters = append(linters, newLinterHelp(lc)) - } - - return json.NewEncoder(c.cmd.OutOrStdout()).Encode(linters) -} - -func (c *helpCommand) lintersPrint() { - var enabledLCs, disabledLCs []*linter.Config - for _, lc := range c.dbManager.GetAllSupportedLinterConfigs() { - if lc.Internal { - continue - } - - if goformatters.IsFormatter(lc.Name()) { - continue - } - - if lc.FromGroup(config.GroupStandard) { - enabledLCs = append(enabledLCs, lc) - } else { - disabledLCs = append(disabledLCs, lc) - } - } - - color.Green("Enabled by default linters:\n") - printLinters(enabledLCs) - - color.Red("\nDisabled by default linters:\n") - printLinters(disabledLCs) -} - -func printLinters(lcs []*linter.Config) { - slices.SortFunc(lcs, func(a, b *linter.Config) int { - if a.IsDeprecated() && b.IsDeprecated() { - return strings.Compare(a.Name(), b.Name()) - } - - if a.IsDeprecated() { - return 1 - } - - if b.IsDeprecated() { - return -1 - } - - return strings.Compare(a.Name(), b.Name()) - }) - - for _, lc := range lcs { - desc := formatDescription(lc.Linter.Desc()) - - deprecatedMark := "" - if lc.IsDeprecated() { - deprecatedMark = " [" + color.RedString("deprecated") + "]" - } - - var capabilities []string - if !lc.IsSlowLinter() { - capabilities = append(capabilities, color.BlueString("fast")) - } - if lc.CanAutoFix { - capabilities = append(capabilities, color.GreenString("auto-fix")) - } - - var capability string - if capabilities != nil { - capability = " [" + strings.Join(capabilities, ", ") + "]" - } - - _, _ = fmt.Fprintf(logutils.StdOut, "%s%s: %s%s\n", - color.YellowString(lc.Name()), deprecatedMark, desc, capability) - } -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/builder.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/builder.go deleted file mode 100644 index bfd242f159..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/builder.go +++ /dev/null @@ -1,282 +0,0 @@ -package internal - -import ( - "context" - "crypto/sha256" - "encoding/base64" - "fmt" - "io" - "os" - "os/exec" - "path/filepath" - "runtime" - "strings" - "time" - "unicode" - - "golang.org/x/mod/sumdb/dirhash" - - "github.com/golangci/golangci-lint/v2/pkg/logutils" -) - -// Builder runs all the required commands to build a binary. -type Builder struct { - cfg *Configuration - - log logutils.Log - - root string - repo string -} - -// NewBuilder creates a new Builder. -func NewBuilder(logger logutils.Log, cfg *Configuration, root string) *Builder { - return &Builder{ - cfg: cfg, - log: logger, - root: root, - repo: filepath.Join(root, "golangci-lint"), - } -} - -// Build builds the custom binary. -func (b Builder) Build(ctx context.Context) error { - b.log.Infof("Cloning golangci-lint repository") - - err := b.clone(ctx) - if err != nil { - return fmt.Errorf("clone golangci-lint: %w", err) - } - - b.log.Infof("Adding plugin imports") - - err = b.updatePluginsFile() - if err != nil { - return fmt.Errorf("update plugin file: %w", err) - } - - b.log.Infof("Adding replace directives") - - err = b.addToGoMod(ctx) - if err != nil { - return fmt.Errorf("add to go.mod: %w", err) - } - - b.log.Infof("Running go mod tidy") - - err = b.goModTidy(ctx) - if err != nil { - return fmt.Errorf("go mod tidy: %w", err) - } - - b.log.Infof("Building golangci-lint binary") - - binaryName := b.getBinaryName() - - err = b.goBuild(ctx, binaryName) - if err != nil { - return fmt.Errorf("build golangci-lint binary: %w", err) - } - - b.log.Infof("Moving golangci-lint binary") - - err = b.copyBinary(binaryName) - if err != nil { - return fmt.Errorf("move golangci-lint binary: %w", err) - } - - return nil -} - -func (b Builder) clone(ctx context.Context) error { - //nolint:gosec // the variable is sanitized. - cmd := exec.CommandContext(ctx, - "git", "clone", "--branch", sanitizeVersion(b.cfg.Version), - "--single-branch", "--depth", "1", "-c advice.detachedHead=false", "-q", - "https://github.com/golangci/golangci-lint.git", - ) - cmd.Dir = b.root - - output, err := cmd.CombinedOutput() - if err != nil { - b.log.Infof("%s", string(output)) - - return fmt.Errorf("%s: %w", strings.Join(cmd.Args, " "), err) - } - - return nil -} - -func (b Builder) addToGoMod(ctx context.Context) error { - for _, plugin := range b.cfg.Plugins { - if plugin.Path != "" { - err := b.addReplaceDirective(ctx, plugin) - if err != nil { - return err - } - - continue - } - - err := b.goGet(ctx, plugin) - if err != nil { - return err - } - } - - return nil -} - -func (b Builder) goGet(ctx context.Context, plugin *Plugin) error { - //nolint:gosec // the variables are user related. - cmd := exec.CommandContext(ctx, "go", "get", plugin.Module+"@"+plugin.Version) - cmd.Dir = b.repo - - b.log.Infof("run: %s", strings.Join(cmd.Args, " ")) - - output, err := cmd.CombinedOutput() - if err != nil { - b.log.Warnf("%s", string(output)) - - return fmt.Errorf("%s: %w", strings.Join(cmd.Args, " "), err) - } - - return nil -} - -func (b Builder) addReplaceDirective(ctx context.Context, plugin *Plugin) error { - replace := fmt.Sprintf("%s=%s", plugin.Module, plugin.Path) - - cmd := exec.CommandContext(ctx, "go", "mod", "edit", "-replace", replace) - cmd.Dir = b.repo - - b.log.Infof("run: %s", strings.Join(cmd.Args, " ")) - - output, err := cmd.CombinedOutput() - if err != nil { - b.log.Warnf("%s", string(output)) - - return fmt.Errorf("%s: %w", strings.Join(cmd.Args, " "), err) - } - - return nil -} - -func (b Builder) goModTidy(ctx context.Context) error { - cmd := exec.CommandContext(ctx, "go", "mod", "tidy") - cmd.Dir = b.repo - - output, err := cmd.CombinedOutput() - if err != nil { - b.log.Warnf("%s", string(output)) - - return fmt.Errorf("%s: %w", strings.Join(cmd.Args, " "), err) - } - - return nil -} - -func (b Builder) goBuild(ctx context.Context, binaryName string) error { - version, err := b.createVersion(b.cfg.Version) - if err != nil { - return fmt.Errorf("custom version: %w", err) - } - - b.log.Infof("version: %s", version) - - //nolint:gosec // the variable is sanitized. - cmd := exec.CommandContext(ctx, "go", "build", - "-ldflags", - fmt.Sprintf("-s -w -X 'main.version=%s' -X 'main.date=%s'", version, time.Now().UTC().String()), - "-o", binaryName, - "./cmd/golangci-lint", - ) - cmd.Dir = b.repo - - output, err := cmd.CombinedOutput() - if err != nil { - b.log.Warnf("%s", string(output)) - - return fmt.Errorf("%s: %w", strings.Join(cmd.Args, " "), err) - } - - return nil -} - -func (b Builder) copyBinary(binaryName string) error { - src := filepath.Join(b.repo, binaryName) - - source, err := os.Open(filepath.Clean(src)) - if err != nil { - return fmt.Errorf("open source file: %w", err) - } - - defer func() { _ = source.Close() }() - - info, err := source.Stat() - if err != nil { - return fmt.Errorf("stat source file: %w", err) - } - - if b.cfg.Destination != "" { - err = os.MkdirAll(b.cfg.Destination, os.ModePerm) - if err != nil { - return fmt.Errorf("create destination directory: %w", err) - } - } - - dst, err := os.OpenFile(filepath.Join(b.cfg.Destination, binaryName), os.O_RDWR|os.O_CREATE|os.O_TRUNC, info.Mode()) - if err != nil { - return fmt.Errorf("create destination file: %w", err) - } - - defer func() { _ = dst.Close() }() - - _, err = io.Copy(dst, source) - if err != nil { - return fmt.Errorf("copy source to destination: %w", err) - } - - return nil -} - -func (b Builder) getBinaryName() string { - name := b.cfg.Name - if runtime.GOOS == "windows" { - name += ".exe" - } - - return name -} - -func (b Builder) createVersion(orig string) (string, error) { - hash := sha256.New() - - for _, plugin := range b.cfg.Plugins { - if plugin.Path == "" { - continue - } - - dh, err := hashDir(plugin.Path, "", dirhash.DefaultHash) - if err != nil { - return "", fmt.Errorf("hash plugin directory: %w", err) - } - - b.log.Infof("%s: %s", plugin.Path, dh) - - hash.Write([]byte(dh)) - } - - return fmt.Sprintf("%s-custom-gcl-%s", - sanitizeVersion(orig), - sanitizeVersion(base64.URLEncoding.EncodeToString(hash.Sum(nil))), - ), nil -} - -func sanitizeVersion(v string) string { - fn := func(c rune) bool { - return !unicode.IsLetter(c) && !unicode.IsNumber(c) && c != '.' && c != '/' - } - - return strings.Join(strings.FieldsFunc(v, fn), "") -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/configuration.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/configuration.go deleted file mode 100644 index f9de4c47a7..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/configuration.go +++ /dev/null @@ -1,140 +0,0 @@ -package internal - -import ( - "errors" - "fmt" - "os" - "path/filepath" - "strings" - - "gopkg.in/yaml.v3" -) - -const base = ".custom-gcl" - -const defaultBinaryName = "custom-gcl" - -// Configuration represents the configuration file. -type Configuration struct { - // golangci-lint version. - Version string `yaml:"version"` - - // Name of the binary. - Name string `yaml:"name,omitempty"` - - // Destination is the path to a directory to store the binary. - Destination string `yaml:"destination,omitempty"` - - // Plugins information. - Plugins []*Plugin `yaml:"plugins,omitempty"` -} - -// Validate checks and clean the configuration. -func (c *Configuration) Validate() error { - if strings.TrimSpace(c.Version) == "" { - return errors.New("root field 'version' is required") - } - - if strings.TrimSpace(c.Name) == "" { - c.Name = defaultBinaryName - } - - if len(c.Plugins) == 0 { - return errors.New("no plugins defined") - } - - for _, plugin := range c.Plugins { - if strings.TrimSpace(plugin.Module) == "" { - return errors.New("field 'module' is required") - } - - if strings.TrimSpace(plugin.Import) == "" { - plugin.Import = plugin.Module - } - - if strings.TrimSpace(plugin.Path) == "" && strings.TrimSpace(plugin.Version) == "" { - return errors.New("missing information: 'version' or 'path' should be provided") - } - - if strings.TrimSpace(plugin.Path) != "" && strings.TrimSpace(plugin.Version) != "" { - return errors.New("invalid configuration: 'version' and 'path' should not be provided at the same time") - } - - if strings.TrimSpace(plugin.Path) == "" { - continue - } - - abs, err := filepath.Abs(plugin.Path) - if err != nil { - return err - } - - plugin.Path = abs - } - - return nil -} - -// Plugin represents information about a plugin. -type Plugin struct { - // Module name. - Module string `yaml:"module"` - - // Import to use. - Import string `yaml:"import,omitempty"` - - // Version of the module. - // Only for module available through a Go proxy. - Version string `yaml:"version,omitempty"` - - // Path to the local module. - // Only for local module. - Path string `yaml:"path,omitempty"` -} - -func LoadConfiguration() (*Configuration, error) { - configFilePath, err := findConfigurationFile() - if err != nil { - return nil, fmt.Errorf("file %s not found: %w", configFilePath, err) - } - - file, err := os.Open(configFilePath) - if err != nil { - return nil, fmt.Errorf("file %s open: %w", configFilePath, err) - } - - defer func() { _ = file.Close() }() - - var cfg Configuration - - err = yaml.NewDecoder(file).Decode(&cfg) - if err != nil { - return nil, fmt.Errorf("YAML decoding: %w", err) - } - - return &cfg, nil -} - -func findConfigurationFile() (string, error) { - entries, err := os.ReadDir(".") - if err != nil { - return "", fmt.Errorf("read directory: %w", err) - } - - for _, entry := range entries { - ext := filepath.Ext(entry.Name()) - - switch strings.ToLower(strings.TrimPrefix(ext, ".")) { - case "yml", "yaml", "json": - if isConf(ext, entry.Name()) { - return entry.Name(), nil - } - } - } - - return "", errors.New("configuration file not found") -} - -func isConf(ext, name string) bool { - return base+ext == name -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/dirhash.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/dirhash.go deleted file mode 100644 index 16ea6a8561..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/dirhash.go +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package internal - -import ( - "fmt" - "io" - "os" - "path/filepath" - "strings" - - "golang.org/x/mod/sumdb/dirhash" -) - -// Slightly modified copy of [dirhash.HashDir]. -// https://github.com/golang/mod/blob/v0.28.0/sumdb/dirhash/hash.go#L67-L79 -func hashDir(dir, prefix string, hash dirhash.Hash) (string, error) { - files, err := dirFiles(dir, prefix) - if err != nil { - return "", err - } - - osOpen := func(name string) (io.ReadCloser, error) { - return os.Open(filepath.Join(dir, strings.TrimPrefix(name, prefix))) - } - - return hash(files, osOpen) -} - -// Modified copy of [dirhash.DirFiles]. -// https://github.com/golang/mod/blob/v0.28.0/sumdb/dirhash/hash.go#L81-L109 -// And adapted to globally follows the rules from https://github.com/golang/mod/blob/v0.28.0/zip/zip.go -func dirFiles(dir, prefix string) ([]string, error) { - var files []string - - dir = filepath.Clean(dir) - - err := filepath.Walk(dir, func(file string, info os.FileInfo, err error) error { - if err != nil { - return err - } - - if info.IsDir() { - if dir == file { - // Don't skip the top-level directory. - return nil - } - - switch info.Name() { - // Skip vendor and node directories. - case "vendor", "node_modules": - return filepath.SkipDir - - // Skip VCS directories. - case ".bzr", ".git", ".hg", ".svn": - return filepath.SkipDir - } - - // Skip submodules (directories containing go.mod files). - if goModInfo, err := os.Lstat(filepath.Join(dir, "go.mod")); err == nil && !goModInfo.IsDir() { - return filepath.SkipDir - } - - return nil - } - - if file == dir { - return fmt.Errorf("%s is not a directory", dir) - } - - if !info.Mode().IsRegular() { - return nil - } - - rel := file - - if dir != "." { - rel = file[len(dir)+1:] - } - - f := filepath.Join(prefix, rel) - - files = append(files, filepath.ToSlash(f)) - - return nil - }) - if err != nil { - return nil, err - } - return files, nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/imports.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/imports.go deleted file mode 100644 index 3bebf596b1..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/imports.go +++ /dev/null @@ -1,69 +0,0 @@ -package internal - -import ( - "bytes" - "fmt" - "go/format" - "os" - "path/filepath" - "text/template" -) - -const importsTemplate = ` -package main - -import ( -{{range .Imports -}} - _ "{{.}}" -{{end -}} -) -` - -func (b Builder) updatePluginsFile() error { - importsDest := filepath.Join(b.repo, "cmd", "golangci-lint", "plugins.go") - - info, err := os.Stat(importsDest) - if err != nil { - return fmt.Errorf("file %s not found: %w", importsDest, err) - } - - source, err := generateImports(b.cfg) - if err != nil { - return fmt.Errorf("generate imports: %w", err) - } - - b.log.Infof("generated imports info %s:\n%s\n", importsDest, source) - - err = os.WriteFile(filepath.Clean(importsDest), source, info.Mode()) - if err != nil { - return fmt.Errorf("write file %s: %w", importsDest, err) - } - - return nil -} - -func generateImports(cfg *Configuration) ([]byte, error) { - impTmpl, err := template.New("plugins.go").Parse(importsTemplate) - if err != nil { - return nil, fmt.Errorf("parse template: %w", err) - } - - var imps []string - for _, plugin := range cfg.Plugins { - imps = append(imps, plugin.Import) - } - - buf := &bytes.Buffer{} - - err = impTmpl.Execute(buf, map[string]any{"Imports": imps}) - if err != nil { - return nil, fmt.Errorf("execute template: %w", err) - } - - source, err := format.Source(buf.Bytes()) - if err != nil { - return nil, fmt.Errorf("format source: %w", err) - } - - return source, nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/fakeloader/config.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/fakeloader/config.go deleted file mode 100644 index 159f4cba00..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/fakeloader/config.go +++ /dev/null @@ -1,22 +0,0 @@ -package fakeloader - -// Config implements [config.BaseConfig]. -// This only the stub for the real file loader. -type Config struct { - Version string `mapstructure:"version"` - - cfgDir string // Path to the directory containing golangci-lint config file. -} - -func NewConfig() *Config { - return &Config{} -} - -// SetConfigDir sets the path to directory that contains golangci-lint config file. -func (c *Config) SetConfigDir(dir string) { - c.cfgDir = dir -} - -func (*Config) IsInternalTest() bool { - return false -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/fakeloader/fakeloader.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/fakeloader/fakeloader.go deleted file mode 100644 index fd17449b57..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/fakeloader/fakeloader.go +++ /dev/null @@ -1,48 +0,0 @@ -package fakeloader - -import ( - "fmt" - "os" - - "github.com/go-viper/mapstructure/v2" - - "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/parser" - "github.com/golangci/golangci-lint/v2/pkg/config" -) - -// Load is used to keep case of configuration. -// Viper serialize raw map keys in lowercase, this is a problem with the configuration of some linters. -func Load(srcPath string, old any) error { - file, err := os.Open(srcPath) - if err != nil { - return fmt.Errorf("open file: %w", err) - } - - defer func() { _ = file.Close() }() - - raw := map[string]any{} - - err = parser.Decode(file, raw) - if err != nil { - return err - } - - // NOTE: this is inspired by viper internals. - cc := &mapstructure.DecoderConfig{ - Result: old, - WeaklyTypedInput: true, - DecodeHook: config.DecodeHookFunc(), - } - - decoder, err := mapstructure.NewDecoder(cc) - if err != nil { - return fmt.Errorf("constructing mapstructure decoder: %w", err) - } - - err = decoder.Decode(raw) - if err != nil { - return fmt.Errorf("decoding configuration file: %w", err) - } - - return nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate.go deleted file mode 100644 index 69b6c7c425..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate.go +++ /dev/null @@ -1,19 +0,0 @@ -package migrate - -import ( - "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/ptr" - "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone" - "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo" -) - -func ToConfig(old *versionone.Config) *versiontwo.Config { - return &versiontwo.Config{ - Version: ptr.Pointer("2"), - Linters: toLinters(old), - Formatters: toFormatters(old), - Issues: toIssues(old), - Output: toOutput(old), - Severity: toSeverity(old), - Run: toRun(old), - } -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_formatters.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_formatters.go deleted file mode 100644 index 8836e6db88..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_formatters.go +++ /dev/null @@ -1,105 +0,0 @@ -package migrate - -import ( - "slices" - "strings" - - "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/ptr" - "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone" - "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo" -) - -func toFormatters(old *versionone.Config) versiontwo.Formatters { - enable := ProcessEffectiveFormatters(old.Linters) - - var paths []string - if len(enable) > 0 { - paths = slices.Concat(old.Issues.ExcludeFiles, old.Issues.ExcludeDirs) - } - - if old.Issues.UseDefaultExcludeDirs == nil || ptr.Deref(old.Issues.UseDefaultExcludeDirs) { - paths = append(paths, "third_party$", "builtin$", "examples$") - } - - paths = append(paths, toFormattersPathsFromRules(old.Issues)...) - - return versiontwo.Formatters{ - Enable: enable, - Settings: versiontwo.FormatterSettings{ - Gci: toGciSettings(old.LintersSettings.Gci), - GoFmt: toGoFmtSettings(old.LintersSettings.GoFmt), - GoFumpt: toGoFumptSettings(old.LintersSettings.GoFumpt), - GoImports: toGoImportsSettings(old.LintersSettings.GoImports), - }, - Exclusions: versiontwo.FormatterExclusions{ - Generated: toExclusionGenerated(old.Issues.ExcludeGenerated), - Paths: paths, - }, - } -} - -func toFormattersPathsFromRules(old versionone.Issues) []string { - var results []string - - for _, rule := range old.ExcludeRules { - allNames := convertStaticcheckLinterNames(convertAlternativeNames(rule.Linters)) - - names := onlyFormatterNames(allNames) - if len(names) == 0 { - continue - } - - if ptr.Deref(rule.Path) == "" { - continue - } - - results = append(results, ptr.Deref(rule.Path)) - } - - return results -} - -func toGciSettings(old versionone.GciSettings) versiontwo.GciSettings { - return versiontwo.GciSettings{ - Sections: old.Sections, - NoInlineComments: old.NoInlineComments, - NoPrefixComments: old.NoPrefixComments, - CustomOrder: old.CustomOrder, - NoLexOrder: old.NoLexOrder, - } -} - -func toGoFmtSettings(old versionone.GoFmtSettings) versiontwo.GoFmtSettings { - settings := versiontwo.GoFmtSettings{ - Simplify: old.Simplify, - } - - for _, rule := range old.RewriteRules { - settings.RewriteRules = append(settings.RewriteRules, versiontwo.GoFmtRewriteRule{ - Pattern: rule.Pattern, - Replacement: rule.Replacement, - }) - } - - return settings -} - -func toGoFumptSettings(old versionone.GoFumptSettings) versiontwo.GoFumptSettings { - return versiontwo.GoFumptSettings{ - ModulePath: old.ModulePath, - ExtraRules: old.ExtraRules, - } -} - -func toGoImportsSettings(old versionone.GoImportsSettings) versiontwo.GoImportsSettings { - var localPrefixes []string - - prefixes := ptr.Deref(old.LocalPrefixes) - if prefixes != "" { - localPrefixes = strings.Split(prefixes, ",") - } - - return versiontwo.GoImportsSettings{ - LocalPrefixes: localPrefixes, - } -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_issues.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_issues.go deleted file mode 100644 index eab9d17c64..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_issues.go +++ /dev/null @@ -1,20 +0,0 @@ -package migrate - -import ( - "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone" - "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo" -) - -func toIssues(old *versionone.Config) versiontwo.Issues { - return versiontwo.Issues{ - MaxIssuesPerLinter: old.Issues.MaxIssuesPerLinter, - MaxSameIssues: old.Issues.MaxSameIssues, - UniqByLine: old.Issues.UniqByLine, - DiffFromRevision: old.Issues.DiffFromRevision, - DiffFromMergeBase: old.Issues.DiffFromMergeBase, - DiffPatchFilePath: old.Issues.DiffPatchFilePath, - WholeFiles: old.Issues.WholeFiles, - Diff: old.Issues.Diff, - NeedFix: old.Issues.NeedFix, - } -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_linter_names.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_linter_names.go deleted file mode 100644 index bbb178ab38..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_linter_names.go +++ /dev/null @@ -1,966 +0,0 @@ -package migrate - -import ( - "cmp" - "slices" - - "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/ptr" - "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone" -) - -type LinterInfo struct { - Name string `json:"name"` - Presets []string `json:"inPresets"` - Slow bool `json:"isSlow,omitempty"` - Default bool `json:"enabledByDefault,omitempty"` - AlternativeNames []string `json:"alternativeNames,omitempty"` -} - -func (l *LinterInfo) isName(name string) bool { - if name == l.Name { - return true - } - - return slices.Contains(l.AlternativeNames, name) -} - -func (l *LinterInfo) hasPresets(names []string) bool { - for _, name := range names { - if slices.Contains(l.Presets, name) { - return true - } - } - - return false -} - -func ProcessEffectiveLinters(old versionone.Linters) (enable, disable []string) { - switch { - case ptr.Deref(old.DisableAll): - return disableAllFilter(old), nil - - case ptr.Deref(old.EnableAll): - return nil, enableAllFilter(old) - - default: - return defaultLintersFilter(old) - } -} - -func ProcessEffectiveFormatters(old versionone.Linters) []string { - enabled, disabled := ProcessEffectiveLinters(old) - - if ptr.Deref(old.EnableAll) { - var formatterNames []string - - for _, f := range getAllFormatterNames() { - if !slices.Contains(disabled, f) { - formatterNames = append(formatterNames, f) - } - } - - return formatterNames - } - - return onlyFormatterNames(enabled) -} - -// disableAllFilter generates the value of `enable` when `disable-all` is `true`. -func disableAllFilter(old versionone.Linters) []string { - // Note: - // - disable-all + enable-all - // => impossible (https://github.com/golangci/golangci-lint/blob/e1eb4cb2c7fba29b5831b63e454844d83c692874/pkg/config/linters.go#L38) - // - disable-all + disable - // => impossible (https://github.com/golangci/golangci-lint/blob/e1eb4cb2c7fba29b5831b63e454844d83c692874/pkg/config/linters.go#L47) - - // if disable-all -> presets fast enable - // - presets fast enable: (presets - [slow]) + enable => effective enable + none - // - presets fast: presets - slow => effective enable + none - // - presets fast enable: presets + enable => effective enable + none - // - enable => effective enable + none - // - fast => nothing - // - fast enable: enable => effective enable + none - - // (presets - [slow]) + enable => effective enable + none - names := toNames( - slices.Concat( - filter( - allLinters(), onlyPresets(old), keepFast(old), // presets - [slow] - ), - allEnabled(old, allLinters()), // + enable - ), - ) - - return slices.Concat(names, unknownLinterNames(old.Enable, allLinters())) -} - -// enableAllFilter generates the value of `disable` when `enable-all` is `true`. -func enableAllFilter(old versionone.Linters) []string { - // Note: - // - enable-all + disable-all - // => impossible (https://github.com/golangci/golangci-lint/blob/e1eb4cb2c7fba29b5831b63e454844d83c692874/pkg/config/linters.go#L38) - // - enable-all + enable + fast=false - // => impossible (https://github.com/golangci/golangci-lint/blob/e1eb4cb2c7fba29b5831b63e454844d83c692874/pkg/config/linters.go#L52) - // - enable-all + enable + fast=true - // => possible (https://github.com/golangci/golangci-lint/blob/e1eb4cb2c7fba29b5831b63e454844d83c692874/pkg/config/linters.go#L51) - - // if enable-all -> presets fast enable disable - // - presets fast enable disable: all - fast - enable + disable => effective disable + all - // - presets fast disable: all - fast + disable => effective disable + all - // - presets fast: all - fast => effective disable + all - // - presets disable: disable => effective disable + all - // - disable => effective disable + all - // - fast: all - fast => effective disable + all - // - fast disable: all - fast + disable => effective disable + all - - // all - [fast] - enable + disable => effective disable + all - names := toNames( - slices.Concat( - removeLinters( - filter( - allLinters(), keepSlow(old), // all - fast - ), - allEnabled(old, allLinters()), // - enable - ), - allDisabled(old, allLinters()), // + disable - ), - ) - - return slices.Concat(names, unknownLinterNames(old.Disable, allLinters())) -} - -// defaultLintersFilter generates the values of `enable` and `disable` when using default linters. -func defaultLintersFilter(old versionone.Linters) (enable, disable []string) { - // Note: - // - a linter cannot be inside `enable` and `disable` in the same configuration - // => https://github.com/golangci/golangci-lint/blob/e1eb4cb2c7fba29b5831b63e454844d83c692874/pkg/config/linters.go#L66 - - // if default -> presets fast disable - // - presets > fast > disable > enable => effective enable + disable + standard - // - (default - fast) - enable + disable => effective disable - // - presets - slow + enable - default - [effective disable] => effective enable - // - presets + fast + disable => effective enable + disable + standard - // - (default - fast) + disable => effective disable - // - presets - slow - default - [effective disable] => effective enable - // - presets + fast + enable - // - (default - fast) - enable => effective disable - // - presets - slow + enable - default - [effective disable] => effective enable - // - presets + fast - // - (default - fast) => effective disable - // - presets - slow - default - [effective disable] => effective enable - // - presets + disable - // - default + disable => effective disable - // - presets - default - [effective disable] => effective enable - // - presets + enable - // - default - enable => effective disable - // - presets + enable - default - [effective disable] => effective enable - // - disable - // - default + disable => effective disable - // - default - [effective disable] => effective enable - // - enable - // - default - enable => effective disable - // - enable - default - [effective disable] => effective enable - // - fast - // - default - fast => effective disable - // - default - [effective disable] => effective enable - // - fast + disable - // - (default - fast) + disable => effective disable - // - default - [effective disable] => effective enable - // - fast + enable - // - (default - fast) - enable => effective disable - // - enable - default - [effective disable] => effective enable - - disabledLinters := defaultLintersDisableFilter(old) - - enabledLinters := defaultLintersEnableFilter(old, disabledLinters) - - enabled := toNames(enabledLinters) - disabled := toNames(disabledLinters) - - return slices.Concat(enabled, unknownLinterNames(old.Enable, allLinters())), - slices.Concat(disabled, unknownLinterNames(old.Disable, allLinters())) -} - -// defaultLintersEnableFilter generates the value of `enable` when using default linters. -func defaultLintersEnableFilter(old versionone.Linters, effectiveDisabled []LinterInfo) []LinterInfo { - // presets - slow + enable - default - [effective disable] => effective enable - return removeLinters( - filter( - slices.Concat( - filter( - allLinters(), onlyPresets(old), keepFast(old), // presets - slow - ), - allEnabled(old, allLinters()), // + enable - ), - notDefault, // - default - ), - effectiveDisabled, // - [effective disable] - ) -} - -// defaultLintersDisableFilter generates the value of `disable` when using default linters. -func defaultLintersDisableFilter(old versionone.Linters) []LinterInfo { - // (default - fast) - enable + disable => effective disable - return slices.Concat( - removeLinters( - filter(allLinters(), onlyDefault, keepSlow(old)), // (default - fast) - allEnabled(old, allLinters()), // - enable - ), - allDisabled(old, allLinters()), // + disable - ) -} - -func allLinters() []LinterInfo { - return []LinterInfo{ - { - Name: "asasalint", - Presets: []string{"bugs"}, - Slow: true, - }, - { - Name: "asciicheck", - Presets: []string{"bugs", "style"}, - }, - { - Name: "bidichk", - Presets: []string{"bugs"}, - }, - { - Name: "bodyclose", - Presets: []string{"performance", "bugs"}, - Slow: true, - }, - { - Name: "canonicalheader", - Presets: []string{"style"}, - Slow: true, - }, - { - Name: "containedctx", - Presets: []string{"style"}, - Slow: true, - }, - { - Name: "contextcheck", - Presets: []string{"bugs"}, - Slow: true, - }, - { - Name: "copyloopvar", - Presets: []string{"style"}, - }, - { - Name: "cyclop", - Presets: []string{"complexity"}, - }, - { - Name: "decorder", - Presets: []string{"style"}, - }, - { - Name: "depguard", - Presets: []string{"style", "import", "module"}, - }, - { - Name: "dogsled", - Presets: []string{"style"}, - }, - { - Name: "dupl", - Presets: []string{"style"}, - }, - { - Name: "dupword", - Presets: []string{"comment"}, - }, - { - Name: "durationcheck", - Presets: []string{"bugs"}, - Slow: true, - }, - { - Name: "errcheck", - Presets: []string{"bugs", "error"}, - Slow: true, - Default: true, - }, - { - Name: "errchkjson", - Presets: []string{"bugs"}, - Slow: true, - }, - { - Name: "errname", - Presets: []string{"style"}, - Slow: true, - }, - { - Name: "errorlint", - Presets: []string{"bugs", "error"}, - Slow: true, - }, - { - Name: "exhaustive", - Presets: []string{"bugs"}, - Slow: true, - }, - { - Name: "exhaustruct", - Presets: []string{"style", "test"}, - Slow: true, - }, - { - Name: "exptostd", - Presets: []string{"style"}, - Slow: true, - }, - { - Name: "forbidigo", - Presets: []string{"style"}, - Slow: true, - }, - { - Name: "forcetypeassert", - Presets: []string{"style"}, - Slow: true, - }, - { - Name: "fatcontext", - Presets: []string{"performance"}, - Slow: true, - }, - { - Name: "funlen", - Presets: []string{"complexity"}, - }, - { - Name: "gci", - Presets: []string{"format", "import"}, - }, - { - Name: "ginkgolinter", - Presets: []string{"style"}, - Slow: true, - }, - { - Name: "gocheckcompilerdirectives", - Presets: []string{"bugs"}, - }, - { - Name: "gochecknoglobals", - Presets: []string{"style"}, - Slow: true, - }, - { - Name: "gochecknoinits", - Presets: []string{"style"}, - }, - { - Name: "gochecksumtype", - Presets: []string{"bugs"}, - Slow: true, - }, - { - Name: "gocognit", - Presets: []string{"complexity"}, - }, - { - Name: "goconst", - Presets: []string{"style"}, - }, - { - Name: "gocritic", - Presets: []string{"style", "metalinter"}, - Slow: true, - }, - { - Name: "gocyclo", - Presets: []string{"complexity"}, - }, - { - Name: "godot", - Presets: []string{"style", "comment"}, - }, - { - Name: "godox", - Presets: []string{"style", "comment"}, - }, - { - Name: "err113", - Presets: []string{"style", "error"}, - Slow: true, - AlternativeNames: []string{"goerr113"}, - }, - { - Name: "gofmt", - Presets: []string{"format"}, - }, - { - Name: "gofumpt", - Presets: []string{"format"}, - }, - { - Name: "goheader", - Presets: []string{"style"}, - }, - { - Name: "goimports", - Presets: []string{"format", "import"}, - }, - { - Name: "mnd", - Presets: []string{"style"}, - AlternativeNames: []string{"gomnd"}, - }, - { - Name: "gomoddirectives", - Presets: []string{"style", "module"}, - }, - { - Name: "gomodguard", - Presets: []string{"style", "import", "module"}, - }, - { - Name: "goprintffuncname", - Presets: []string{"style"}, - }, - { - Name: "gosec", - Presets: []string{"bugs"}, - Slow: true, - AlternativeNames: []string{"gas"}, - }, - { - Name: "gosimple", - Presets: []string{"style"}, - Slow: true, - Default: true, - AlternativeNames: []string{"megacheck"}, - }, - { - Name: "gosmopolitan", - Presets: []string{"bugs"}, - Slow: true, - }, - { - Name: "govet", - Presets: []string{"bugs", "metalinter"}, - Slow: true, - Default: true, - AlternativeNames: []string{"vet", "vetshadow"}, - }, - { - Name: "grouper", - Presets: []string{"style"}, - }, - { - Name: "iface", - Presets: []string{"style"}, - Slow: true, - }, - { - Name: "importas", - Presets: []string{"style"}, - Slow: true, - }, - { - Name: "inamedparam", - Presets: []string{"style"}, - }, - { - Name: "ineffassign", - Presets: []string{"unused"}, - Default: true, - }, - { - Name: "interfacebloat", - Presets: []string{"style"}, - }, - { - Name: "intrange", - Presets: []string{"style"}, - Slow: true, - }, - { - Name: "ireturn", - Presets: []string{"style"}, - Slow: true, - }, - { - Name: "lll", - Presets: []string{"style"}, - }, - { - Name: "loggercheck", - Presets: []string{"style", "bugs"}, - Slow: true, - AlternativeNames: []string{"logrlint"}, - }, - { - Name: "maintidx", - Presets: []string{"complexity"}, - }, - { - Name: "makezero", - Presets: []string{"style", "bugs"}, - Slow: true, - }, - { - Name: "mirror", - Presets: []string{"style"}, - Slow: true, - }, - { - Name: "misspell", - Presets: []string{"style", "comment"}, - }, - { - Name: "musttag", - Presets: []string{"style", "bugs"}, - Slow: true, - }, - { - Name: "nakedret", - Presets: []string{"style"}, - }, - { - Name: "nestif", - Presets: []string{"complexity"}, - }, - { - Name: "nilerr", - Presets: []string{"bugs"}, - Slow: true, - }, - { - Name: "nilnesserr", - Presets: []string{"bugs"}, - Slow: true, - }, - { - Name: "nilnil", - Presets: []string{"style"}, - Slow: true, - }, - { - Name: "nlreturn", - Presets: []string{"style"}, - }, - { - Name: "noctx", - Presets: []string{"performance", "bugs"}, - Slow: true, - }, - { - Name: "nonamedreturns", - Presets: []string{"style"}, - Slow: true, - }, - { - Name: "nosprintfhostport", - Presets: []string{"style"}, - }, - { - Name: "paralleltest", - Presets: []string{"style", "test"}, - Slow: true, - }, - { - Name: "perfsprint", - Presets: []string{"performance"}, - Slow: true, - }, - { - Name: "prealloc", - Presets: []string{"performance"}, - }, - { - Name: "predeclared", - Presets: []string{"style"}, - }, - { - Name: "promlinter", - Presets: []string{"style"}, - }, - { - Name: "protogetter", - Presets: []string{"bugs"}, - Slow: true, - }, - { - Name: "reassign", - Presets: []string{"bugs"}, - Slow: true, - }, - { - Name: "recvcheck", - Presets: []string{"bugs"}, - Slow: true, - }, - { - Name: "revive", - Presets: []string{"style", "metalinter"}, - Slow: true, - }, - { - Name: "rowserrcheck", - Presets: []string{"bugs", "sql"}, - Slow: true, - }, - { - Name: "sloglint", - Presets: []string{"style"}, - Slow: true, - }, - { - Name: "sqlclosecheck", - Presets: []string{"bugs", "sql"}, - Slow: true, - }, - { - Name: "spancheck", - Presets: []string{"bugs"}, - Slow: true, - }, - { - Name: "staticcheck", - Presets: []string{"bugs", "metalinter"}, - Slow: true, - Default: true, - AlternativeNames: []string{"megacheck"}, - }, - { - Name: "stylecheck", - Presets: []string{"style"}, - Slow: true, - }, - { - Name: "tagalign", - Presets: []string{"style"}, - }, - { - Name: "tagliatelle", - Presets: []string{"style"}, - Slow: true, - }, - { - Name: "testableexamples", - Presets: []string{"test"}, - }, - { - Name: "testifylint", - Presets: []string{"test", "bugs"}, - Slow: true, - }, - { - Name: "testpackage", - Presets: []string{"style", "test"}, - }, - { - Name: "thelper", - Presets: []string{"test"}, - Slow: true, - }, - { - Name: "tparallel", - Presets: []string{"style", "test"}, - Slow: true, - }, - { - Name: "unconvert", - Presets: []string{"style"}, - Slow: true, - }, - { - Name: "unparam", - Presets: []string{"unused"}, - Slow: true, - }, - { - Name: "unused", - Presets: []string{"unused"}, - Slow: true, - Default: true, - AlternativeNames: []string{"megacheck"}, - }, - { - Name: "usestdlibvars", - Presets: []string{"style"}, - }, - { - Name: "usetesting", - Presets: []string{"test"}, - Slow: true, - }, - { - Name: "varnamelen", - Presets: []string{"style"}, - Slow: true, - }, - { - Name: "wastedassign", - Presets: []string{"style"}, - Slow: true, - }, - { - Name: "whitespace", - Presets: []string{"style"}, - }, - { - Name: "wrapcheck", - Presets: []string{"style", "error"}, - Slow: true, - }, - { - Name: "wsl", - Presets: []string{"style"}, - }, - { - Name: "zerologlint", - Presets: []string{"bugs"}, - Slow: true, - }, - { - Name: "nolintlint", - Presets: []string{"style"}, - }, - } -} - -func toNames(linters []LinterInfo) []string { - var results []string - - for _, linter := range linters { - results = append(results, linter.Name) - } - - return Unique(results) -} - -func removeLinters(linters, toRemove []LinterInfo) []LinterInfo { - return slices.DeleteFunc(linters, func(info LinterInfo) bool { - return slices.ContainsFunc(toRemove, func(en LinterInfo) bool { - return info.Name == en.Name - }) - }) -} - -func allEnabled(old versionone.Linters, linters []LinterInfo) []LinterInfo { - var results []LinterInfo - - for _, linter := range linters { - if slices.ContainsFunc(old.Enable, linter.isName) { - results = append(results, linter) - } - } - - return results -} - -func allDisabled(old versionone.Linters, linters []LinterInfo) []LinterInfo { - var results []LinterInfo - - for _, linter := range linters { - if slices.ContainsFunc(old.Disable, linter.isName) { - results = append(results, linter) - } - } - - return results -} - -func filter(linters []LinterInfo, fns ...fnFilter) []LinterInfo { - var results []LinterInfo - - for _, linter := range linters { - if mergeFilters(linter, fns) { - results = append(results, linter) - } - } - - return results -} - -func mergeFilters(linter LinterInfo, fns []fnFilter) bool { - for _, fn := range fns { - if !fn(linter) { - return false - } - } - - return true -} - -type fnFilter func(linter LinterInfo) bool - -func onlyPresets(old versionone.Linters) fnFilter { - return func(linter LinterInfo) bool { - return linter.hasPresets(old.Presets) - } -} - -func onlyDefault(linter LinterInfo) bool { - return linter.Default -} - -func notDefault(linter LinterInfo) bool { - return !linter.Default -} - -func keepFast(old versionone.Linters) fnFilter { - return func(linter LinterInfo) bool { - if !ptr.Deref(old.Fast) { - return true - } - - return !linter.Slow - } -} - -func keepSlow(old versionone.Linters) fnFilter { - return func(linter LinterInfo) bool { - if !ptr.Deref(old.Fast) { - return false - } - - return linter.Slow - } -} - -func unknownLinterNames(names []string, linters []LinterInfo) []string { - deprecatedLinters := []string{ - "deadcode", - "execinquery", - "exhaustivestruct", - "exportloopref", - "golint", - "ifshort", - "interfacer", - "maligned", - "nosnakecase", - "scopelint", - "structcheck", - "tenv", - "typecheck", - "varcheck", - } - - var results []string - - for _, name := range names { - found := slices.ContainsFunc(linters, func(l LinterInfo) bool { - return l.isName(name) - }) - - if !found { - if slices.Contains(deprecatedLinters, name) { - continue - } - - results = append(results, name) - } - } - - return Unique(results) -} - -func convertStaticcheckLinterNames(names []string) []string { - var results []string - - for _, name := range names { - if slices.Contains([]string{"stylecheck", "gosimple"}, name) { - results = append(results, "staticcheck") - continue - } - - results = append(results, name) - } - - return Unique(results) -} - -func convertDisabledStaticcheckLinterNames(names []string) []string { - removeStaticcheck := slices.Contains(names, "staticcheck") && slices.Contains(names, "stylecheck") && slices.Contains(names, "gosimple") - - var results []string - - for _, name := range names { - if removeStaticcheck && slices.Contains([]string{"stylecheck", "gosimple", "staticcheck"}, name) { - results = append(results, "staticcheck") - continue - } - - if slices.Contains([]string{"stylecheck", "gosimple"}, name) { - continue - } - - results = append(results, name) - } - - return Unique(results) -} - -func onlyLinterNames(names []string) []string { - formatters := []string{"gci", "gofmt", "gofumpt", "goimports"} - - var results []string - - for _, name := range names { - if !slices.Contains(formatters, name) { - results = append(results, name) - } - } - - return results -} - -func onlyFormatterNames(names []string) []string { - formatters := getAllFormatterNames() - - var results []string - - for _, name := range names { - if slices.Contains(formatters, name) { - results = append(results, name) - } - } - - return results -} - -func convertAlternativeNames(names []string) []string { - altNames := map[string]string{ - "gas": "gosec", - "goerr113": "err113", - "gomnd": "mnd", - "logrlint": "loggercheck", - "megacheck": "staticcheck", - "vet": "govet", - "vetshadow": "govet", - } - - var results []string - - for _, name := range names { - if name == "typecheck" { - continue - } - - if n, ok := altNames[name]; ok { - results = append(results, n) - continue - } - - results = append(results, name) - } - - return Unique(results) -} - -func Unique[S ~[]E, E cmp.Ordered](s S) S { - return slices.Compact(slices.Sorted(slices.Values(s))) -} - -func getAllFormatterNames() []string { - return []string{"gci", "gofmt", "gofumpt", "goimports"} -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_linters.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_linters.go deleted file mode 100644 index c070119b6a..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_linters.go +++ /dev/null @@ -1,31 +0,0 @@ -package migrate - -import ( - "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/ptr" - "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone" - "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo" -) - -func toLinters(old *versionone.Config) versiontwo.Linters { - enable, disable := ProcessEffectiveLinters(old.Linters) - - return versiontwo.Linters{ - Default: getDefaultName(old.Linters), - Enable: onlyLinterNames(convertStaticcheckLinterNames(enable)), - Disable: onlyLinterNames(convertDisabledStaticcheckLinterNames(disable)), - FastOnly: nil, - Settings: toLinterSettings(old.LintersSettings), - Exclusions: toExclusions(old), - } -} - -func getDefaultName(old versionone.Linters) *string { - switch { - case ptr.Deref(old.DisableAll): - return ptr.Pointer("none") - case ptr.Deref(old.EnableAll): - return ptr.Pointer("all") - default: - return nil // standard is the default - } -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_linters_exclusions.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_linters_exclusions.go deleted file mode 100644 index aac4d381a9..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_linters_exclusions.go +++ /dev/null @@ -1,144 +0,0 @@ -package migrate - -import ( - "slices" - - "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/ptr" - "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone" - "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo" - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/result/processors" -) - -func toExclusions(old *versionone.Config) versiontwo.LinterExclusions { - return versiontwo.LinterExclusions{ - Generated: toExclusionGenerated(old.Issues.ExcludeGenerated), - Presets: toPresets(old.Issues), - Rules: toExclusionRules(old), - Paths: toExclusionPaths(old.Issues), - } -} - -func toExclusionGenerated(excludeGenerated *string) *string { - if excludeGenerated == nil || ptr.Deref(excludeGenerated) == "" { - return ptr.Pointer("lax") - } - - if ptr.Deref(excludeGenerated) == "strict" { - return nil - } - - return excludeGenerated -} - -func toPresets(old versionone.Issues) []string { - if old.UseDefaultExcludes != nil && !ptr.Deref(old.UseDefaultExcludes) { - return nil - } - - if len(old.IncludeDefaultExcludes) != 0 { - var pp []string - for p, rules := range processors.LinterExclusionPresets { - found := slices.ContainsFunc(rules, func(rule config.ExcludeRule) bool { - return slices.Contains(old.IncludeDefaultExcludes, rule.InternalReference) - }) - if !found { - pp = append(pp, p) - } - } - - slices.Sort(pp) - - return pp - } - - return []string{ - config.ExclusionPresetComments, - config.ExclusionPresetCommonFalsePositives, - config.ExclusionPresetLegacy, - config.ExclusionPresetStdErrorHandling, - } -} - -func toExclusionRules(old *versionone.Config) []versiontwo.ExcludeRule { - var results []versiontwo.ExcludeRule - - for _, rule := range old.Issues.ExcludeRules { - names := onlyLinterNames(convertStaticcheckLinterNames(convertAlternativeNames(rule.Linters))) - if len(rule.Linters) > 0 && len(names) == 0 { - continue - } - - results = append(results, versiontwo.ExcludeRule{ - BaseRule: versiontwo.BaseRule{ - Linters: names, - Path: rule.Path, - PathExcept: rule.PathExcept, - Text: addPrefix(old.Issues, rule.Text), - Source: addPrefix(old.Issues, rule.Source), - }, - }) - } - - for _, pattern := range old.Issues.ExcludePatterns { - results = append(results, versiontwo.ExcludeRule{ - BaseRule: versiontwo.BaseRule{ - Path: ptr.Pointer(`(.+)\.go$`), - Text: addPrefix(old.Issues, ptr.Pointer(pattern)), - }, - }) - } - - return slices.Concat(results, linterTestExclusions(old.LintersSettings)) -} - -func addPrefix(old versionone.Issues, s *string) *string { - if s == nil || ptr.Deref(s) == "" { - return s - } - - var prefix string - if ptr.Deref(old.ExcludeCaseSensitive) { - prefix = "(?i)" - } - - return ptr.Pointer(prefix + ptr.Deref(s)) -} - -func linterTestExclusions(old versionone.LintersSettings) []versiontwo.ExcludeRule { - var excludedTestLinters []string - - if ptr.Deref(old.Asasalint.IgnoreTest) { - excludedTestLinters = append(excludedTestLinters, "asasalint") - } - if ptr.Deref(old.Cyclop.SkipTests) { - excludedTestLinters = append(excludedTestLinters, "cyclop") - } - if ptr.Deref(old.Goconst.IgnoreTests) { - excludedTestLinters = append(excludedTestLinters, "goconst") - } - if ptr.Deref(old.Gosmopolitan.IgnoreTests) { - excludedTestLinters = append(excludedTestLinters, "gosmopolitan") - } - - if len(excludedTestLinters) == 0 { - return nil - } - - return []versiontwo.ExcludeRule{{ - BaseRule: versiontwo.BaseRule{ - Linters: excludedTestLinters, - Path: ptr.Pointer(`(.+)_test\.go`), - }, - }} -} - -func toExclusionPaths(old versionone.Issues) []string { - results := slices.Concat(old.ExcludeFiles, old.ExcludeDirs) - - if old.UseDefaultExcludeDirs == nil || ptr.Deref(old.UseDefaultExcludeDirs) { - results = append(results, "third_party$", "builtin$", "examples$") - } - - return results -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_linters_settings.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_linters_settings.go deleted file mode 100644 index 4656842d6b..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_linters_settings.go +++ /dev/null @@ -1,1037 +0,0 @@ -package migrate - -import ( - "slices" - "strings" - - "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/ptr" - "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone" - "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo" -) - -func toLinterSettings(old versionone.LintersSettings) versiontwo.LintersSettings { - return versiontwo.LintersSettings{ - Asasalint: toAsasalintSettings(old.Asasalint), - BiDiChk: toBiDiChkSettings(old.BiDiChk), - CopyLoopVar: toCopyLoopVarSettings(old.CopyLoopVar), - Cyclop: toCyclopSettings(old.Cyclop), - Decorder: toDecorderSettings(old.Decorder), - Depguard: toDepGuardSettings(old.Depguard), - Dogsled: toDogsledSettings(old.Dogsled), - Dupl: toDuplSettings(old.Dupl), - DupWord: toDupWordSettings(old.DupWord), - Errcheck: toErrcheckSettings(old.Errcheck), - ErrChkJSON: toErrChkJSONSettings(old.ErrChkJSON), - ErrorLint: toErrorLintSettings(old.ErrorLint), - Exhaustive: toExhaustiveSettings(old.Exhaustive), - Exhaustruct: toExhaustructSettings(old.Exhaustruct), - Fatcontext: toFatcontextSettings(old.Fatcontext), - Forbidigo: toForbidigoSettings(old.Forbidigo), - Funlen: toFunlenSettings(old.Funlen), - GinkgoLinter: toGinkgoLinterSettings(old.GinkgoLinter), - Gocognit: toGocognitSettings(old.Gocognit), - GoChecksumType: toGoChecksumTypeSettings(old.GoChecksumType), - Goconst: toGoConstSettings(old.Goconst), - Gocritic: toGoCriticSettings(old.Gocritic), - Gocyclo: toGoCycloSettings(old.Gocyclo), - Godot: toGodotSettings(old.Godot), - Godox: toGodoxSettings(old.Godox), - Goheader: toGoHeaderSettings(old.Goheader), - GoModDirectives: toGoModDirectivesSettings(old.GoModDirectives), - Gomodguard: toGoModGuardSettings(old.Gomodguard), - Gosec: toGoSecSettings(old.Gosec), - Gosmopolitan: toGosmopolitanSettings(old.Gosmopolitan), - Govet: toGovetSettings(old.Govet), - Grouper: toGrouperSettings(old.Grouper), - Iface: toIfaceSettings(old.Iface), - ImportAs: toImportAsSettings(old.ImportAs), - Inamedparam: toINamedParamSettings(old.Inamedparam), - InterfaceBloat: toInterfaceBloatSettings(old.InterfaceBloat), - Ireturn: toIreturnSettings(old.Ireturn), - Lll: toLllSettings(old.Lll), - LoggerCheck: toLoggerCheckSettings(old.LoggerCheck), - MaintIdx: toMaintIdxSettings(old.MaintIdx), - Makezero: toMakezeroSettings(old.Makezero), - Misspell: toMisspellSettings(old.Misspell), - Mnd: toMndSettings(old.Mnd), - MustTag: toMustTagSettings(old.MustTag), - Nakedret: toNakedretSettings(old.Nakedret), - Nestif: toNestifSettings(old.Nestif), - NilNil: toNilNilSettings(old.NilNil), - Nlreturn: toNlreturnSettings(old.Nlreturn), - NoLintLint: toNoLintLintSettings(old.NoLintLint), - NoNamedReturns: toNoNamedReturnsSettings(old.NoNamedReturns), - ParallelTest: toParallelTestSettings(old.ParallelTest), - PerfSprint: toPerfSprintSettings(old.PerfSprint), - Prealloc: toPreallocSettings(old.Prealloc), - Predeclared: toPredeclaredSettings(old.Predeclared), - Promlinter: toPromlinterSettings(old.Promlinter), - ProtoGetter: toProtoGetterSettings(old.ProtoGetter), - Reassign: toReassignSettings(old.Reassign), - Recvcheck: toRecvcheckSettings(old.Recvcheck), - Revive: toReviveSettings(old.Revive), - RowsErrCheck: toRowsErrCheckSettings(old.RowsErrCheck), - SlogLint: toSlogLintSettings(old.SlogLint), - Spancheck: toSpancheckSettings(old.Spancheck), - Staticcheck: toStaticCheckSettings(old), - TagAlign: toTagAlignSettings(old.TagAlign), - Tagliatelle: toTagliatelleSettings(old.Tagliatelle), - Testifylint: toTestifylintSettings(old.Testifylint), - Testpackage: toTestpackageSettings(old.Testpackage), - Thelper: toThelperSettings(old.Thelper), - Unconvert: toUnconvertSettings(old.Unconvert), - Unparam: toUnparamSettings(old.Unparam), - Unused: toUnusedSettings(old.Unused), - UseStdlibVars: toUseStdlibVarsSettings(old.UseStdlibVars), - UseTesting: toUseTestingSettings(old.UseTesting), - Varnamelen: toVarnamelenSettings(old.Varnamelen), - Whitespace: toWhitespaceSettings(old.Whitespace), - Wrapcheck: toWrapcheckSettings(old.Wrapcheck), - WSL: toWSLSettings(old.WSL), - Custom: toCustom(old.Custom), - } -} - -func toAsasalintSettings(old versionone.AsasalintSettings) versiontwo.AsasalintSettings { - return versiontwo.AsasalintSettings{ - Exclude: old.Exclude, - UseBuiltinExclusions: old.UseBuiltinExclusions, - } -} - -func toBiDiChkSettings(old versionone.BiDiChkSettings) versiontwo.BiDiChkSettings { - // The values are true be default, but the default are defined after the configuration loading. - // So the serialization doesn't have good results, but it's complex to do better. - return versiontwo.BiDiChkSettings{ - LeftToRightEmbedding: old.LeftToRightEmbedding, - RightToLeftEmbedding: old.RightToLeftEmbedding, - PopDirectionalFormatting: old.PopDirectionalFormatting, - LeftToRightOverride: old.LeftToRightOverride, - RightToLeftOverride: old.RightToLeftOverride, - LeftToRightIsolate: old.LeftToRightIsolate, - RightToLeftIsolate: old.RightToLeftIsolate, - FirstStrongIsolate: old.FirstStrongIsolate, - PopDirectionalIsolate: old.PopDirectionalIsolate, - } -} - -func toCopyLoopVarSettings(old versionone.CopyLoopVarSettings) versiontwo.CopyLoopVarSettings { - return versiontwo.CopyLoopVarSettings{ - CheckAlias: old.CheckAlias, - } -} - -func toCyclopSettings(old versionone.Cyclop) versiontwo.CyclopSettings { - return versiontwo.CyclopSettings{ - MaxComplexity: old.MaxComplexity, - PackageAverage: old.PackageAverage, - } -} - -func toDecorderSettings(old versionone.DecorderSettings) versiontwo.DecorderSettings { - return versiontwo.DecorderSettings{ - DecOrder: old.DecOrder, - IgnoreUnderscoreVars: old.IgnoreUnderscoreVars, - DisableDecNumCheck: old.DisableDecNumCheck, - DisableTypeDecNumCheck: old.DisableTypeDecNumCheck, - DisableConstDecNumCheck: old.DisableConstDecNumCheck, - DisableVarDecNumCheck: old.DisableVarDecNumCheck, - DisableDecOrderCheck: old.DisableDecOrderCheck, - DisableInitFuncFirstCheck: old.DisableInitFuncFirstCheck, - } -} - -func toDepGuardSettings(old versionone.DepGuardSettings) versiontwo.DepGuardSettings { - settings := versiontwo.DepGuardSettings{} - - for k, r := range old.Rules { - if settings.Rules == nil { - settings.Rules = make(map[string]*versiontwo.DepGuardList) - } - - list := &versiontwo.DepGuardList{ - ListMode: r.ListMode, - Files: r.Files, - Allow: r.Allow, - } - - for _, deny := range r.Deny { - list.Deny = append(list.Deny, versiontwo.DepGuardDeny{ - Pkg: deny.Pkg, - Desc: deny.Desc, - }) - } - - settings.Rules[k] = list - } - - return settings -} - -func toDogsledSettings(old versionone.DogsledSettings) versiontwo.DogsledSettings { - return versiontwo.DogsledSettings{ - MaxBlankIdentifiers: old.MaxBlankIdentifiers, - } -} - -func toDuplSettings(old versionone.DuplSettings) versiontwo.DuplSettings { - return versiontwo.DuplSettings{ - Threshold: old.Threshold, - } -} - -func toDupWordSettings(old versionone.DupWordSettings) versiontwo.DupWordSettings { - return versiontwo.DupWordSettings{ - Keywords: old.Keywords, - Ignore: old.Ignore, - } -} - -func toErrcheckSettings(old versionone.ErrcheckSettings) versiontwo.ErrcheckSettings { - return versiontwo.ErrcheckSettings{ - DisableDefaultExclusions: old.DisableDefaultExclusions, - CheckTypeAssertions: old.CheckTypeAssertions, - CheckAssignToBlank: old.CheckAssignToBlank, - ExcludeFunctions: old.ExcludeFunctions, - } -} - -func toErrChkJSONSettings(old versionone.ErrChkJSONSettings) versiontwo.ErrChkJSONSettings { - return versiontwo.ErrChkJSONSettings{ - CheckErrorFreeEncoding: old.CheckErrorFreeEncoding, - ReportNoExported: old.ReportNoExported, - } -} - -func toErrorLintSettings(old versionone.ErrorLintSettings) versiontwo.ErrorLintSettings { - settings := versiontwo.ErrorLintSettings{ - Errorf: old.Errorf, - ErrorfMulti: old.ErrorfMulti, - Asserts: old.Asserts, - Comparison: old.Comparison, - } - - for _, allowedError := range old.AllowedErrors { - settings.AllowedErrors = append(settings.AllowedErrors, versiontwo.ErrorLintAllowPair{ - Err: allowedError.Err, - Fun: allowedError.Fun, - }) - } - for _, allowedError := range old.AllowedErrorsWildcard { - settings.AllowedErrorsWildcard = append(settings.AllowedErrorsWildcard, versiontwo.ErrorLintAllowPair{ - Err: allowedError.Err, - Fun: allowedError.Fun, - }) - } - - return settings -} - -func toExhaustiveSettings(old versionone.ExhaustiveSettings) versiontwo.ExhaustiveSettings { - return versiontwo.ExhaustiveSettings{ - Check: old.Check, - DefaultSignifiesExhaustive: old.DefaultSignifiesExhaustive, - IgnoreEnumMembers: old.IgnoreEnumMembers, - IgnoreEnumTypes: old.IgnoreEnumTypes, - PackageScopeOnly: old.PackageScopeOnly, - ExplicitExhaustiveMap: old.ExplicitExhaustiveMap, - ExplicitExhaustiveSwitch: old.ExplicitExhaustiveSwitch, - DefaultCaseRequired: old.DefaultCaseRequired, - } -} - -func toExhaustructSettings(old versionone.ExhaustructSettings) versiontwo.ExhaustructSettings { - return versiontwo.ExhaustructSettings{ - Include: old.Include, - Exclude: old.Exclude, - } -} - -func toFatcontextSettings(old versionone.FatcontextSettings) versiontwo.FatcontextSettings { - return versiontwo.FatcontextSettings{ - CheckStructPointers: old.CheckStructPointers, - } -} - -func toForbidigoSettings(old versionone.ForbidigoSettings) versiontwo.ForbidigoSettings { - settings := versiontwo.ForbidigoSettings{ - ExcludeGodocExamples: old.ExcludeGodocExamples, - AnalyzeTypes: old.AnalyzeTypes, - } - - for _, pattern := range old.Forbid { - if pattern.Pattern == nil && pattern.Msg == nil && pattern.Package == nil { - buffer, err := pattern.MarshalString() - if err != nil { - // impossible case - panic(err) - } - - settings.Forbid = append(settings.Forbid, versiontwo.ForbidigoPattern{ - Pattern: ptr.Pointer(string(buffer)), - }) - - continue - } - - settings.Forbid = append(settings.Forbid, versiontwo.ForbidigoPattern{ - Pattern: pattern.Pattern, - Package: pattern.Package, - Msg: pattern.Msg, - }) - } - - return settings -} - -func toFunlenSettings(old versionone.FunlenSettings) versiontwo.FunlenSettings { - return versiontwo.FunlenSettings{ - Lines: old.Lines, - Statements: old.Statements, - IgnoreComments: old.IgnoreComments, - } -} - -func toGinkgoLinterSettings(old versionone.GinkgoLinterSettings) versiontwo.GinkgoLinterSettings { - return versiontwo.GinkgoLinterSettings{ - SuppressLenAssertion: old.SuppressLenAssertion, - SuppressNilAssertion: old.SuppressNilAssertion, - SuppressErrAssertion: old.SuppressErrAssertion, - SuppressCompareAssertion: old.SuppressCompareAssertion, - SuppressAsyncAssertion: old.SuppressAsyncAssertion, - SuppressTypeCompareWarning: old.SuppressTypeCompareWarning, - ForbidFocusContainer: old.ForbidFocusContainer, - AllowHaveLenZero: old.AllowHaveLenZero, - ForceExpectTo: old.ForceExpectTo, - ValidateAsyncIntervals: old.ValidateAsyncIntervals, - ForbidSpecPollution: old.ForbidSpecPollution, - ForceSucceedForFuncs: old.ForceSucceedForFuncs, - } -} - -func toGocognitSettings(old versionone.GocognitSettings) versiontwo.GocognitSettings { - return versiontwo.GocognitSettings{ - MinComplexity: old.MinComplexity, - } -} - -func toGoChecksumTypeSettings(old versionone.GoChecksumTypeSettings) versiontwo.GoChecksumTypeSettings { - return versiontwo.GoChecksumTypeSettings{ - DefaultSignifiesExhaustive: old.DefaultSignifiesExhaustive, - IncludeSharedInterfaces: old.IncludeSharedInterfaces, - } -} - -func toGoConstSettings(old versionone.GoConstSettings) versiontwo.GoConstSettings { - return versiontwo.GoConstSettings{ - IgnoreStrings: old.IgnoreStrings, - MatchWithConstants: old.MatchWithConstants, - MinStringLen: old.MinStringLen, - MinOccurrencesCount: old.MinOccurrencesCount, - ParseNumbers: old.ParseNumbers, - NumberMin: old.NumberMin, - NumberMax: old.NumberMax, - IgnoreCalls: old.IgnoreCalls, - } -} - -func toGoCriticSettings(old versionone.GoCriticSettings) versiontwo.GoCriticSettings { - settings := versiontwo.GoCriticSettings{ - Go: old.Go, - DisableAll: old.DisableAll, - EnabledChecks: old.EnabledChecks, - EnableAll: old.EnableAll, - DisabledChecks: old.DisabledChecks, - EnabledTags: old.EnabledTags, - DisabledTags: old.DisabledTags, - } - - for k, checkSettings := range old.SettingsPerCheck { - if settings.SettingsPerCheck == nil { - settings.SettingsPerCheck = make(map[string]versiontwo.GoCriticCheckSettings) - } - - if k != "ruleguard" { - settings.SettingsPerCheck[k] = versiontwo.GoCriticCheckSettings(checkSettings) - - continue - } - - gccs := versiontwo.GoCriticCheckSettings{} - - for sk, value := range checkSettings { - if sk != "rules" { - gccs[sk] = value - - continue - } - - if rules, ok := value.(string); ok { - gccs[sk] = strings.ReplaceAll(rules, "${configDir}", "${base-path}") - } - } - - settings.SettingsPerCheck[k] = gccs - } - - return settings -} - -func toGoCycloSettings(old versionone.GoCycloSettings) versiontwo.GoCycloSettings { - return versiontwo.GoCycloSettings{ - MinComplexity: old.MinComplexity, - } -} - -func toGodotSettings(old versionone.GodotSettings) versiontwo.GodotSettings { - return versiontwo.GodotSettings{ - Scope: old.Scope, - Exclude: old.Exclude, - Capital: old.Capital, - Period: old.Period, - } -} - -func toGodoxSettings(old versionone.GodoxSettings) versiontwo.GodoxSettings { - return versiontwo.GodoxSettings{ - Keywords: old.Keywords, - } -} - -func toGoHeaderSettings(old versionone.GoHeaderSettings) versiontwo.GoHeaderSettings { - return versiontwo.GoHeaderSettings{ - Values: old.Values, - Template: old.Template, - TemplatePath: old.TemplatePath, - } -} - -func toGoModDirectivesSettings(old versionone.GoModDirectivesSettings) versiontwo.GoModDirectivesSettings { - return versiontwo.GoModDirectivesSettings{ - ReplaceAllowList: old.ReplaceAllowList, - ReplaceLocal: old.ReplaceLocal, - ExcludeForbidden: old.ExcludeForbidden, - RetractAllowNoExplanation: old.RetractAllowNoExplanation, - ToolchainForbidden: old.ToolchainForbidden, - ToolchainPattern: old.ToolchainPattern, - ToolForbidden: old.ToolForbidden, - GoDebugForbidden: old.GoDebugForbidden, - GoVersionPattern: old.GoVersionPattern, - } -} - -func toGoModGuardSettings(old versionone.GoModGuardSettings) versiontwo.GoModGuardSettings { - blocked := versiontwo.GoModGuardBlocked{ - LocalReplaceDirectives: old.Blocked.LocalReplaceDirectives, - } - - for _, version := range old.Blocked.Modules { - data := map[string]versiontwo.GoModGuardModule{} - - for k, v := range version { - data[k] = versiontwo.GoModGuardModule{ - Recommendations: v.Recommendations, - Reason: v.Reason, - } - } - - blocked.Modules = append(blocked.Modules, data) - } - - for _, version := range old.Blocked.Versions { - data := map[string]versiontwo.GoModGuardVersion{} - - for k, v := range version { - data[k] = versiontwo.GoModGuardVersion{ - Version: v.Version, - Reason: v.Reason, - } - } - - blocked.Versions = append(blocked.Versions, data) - } - - return versiontwo.GoModGuardSettings{ - Allowed: versiontwo.GoModGuardAllowed{ - Modules: old.Allowed.Modules, - Domains: old.Allowed.Domains, - }, - Blocked: blocked, - } -} - -func toGoSecSettings(old versionone.GoSecSettings) versiontwo.GoSecSettings { - return versiontwo.GoSecSettings{ - Includes: old.Includes, - Excludes: old.Excludes, - Severity: old.Severity, - Confidence: old.Confidence, - Config: old.Config, - Concurrency: old.Concurrency, - } -} - -func toGosmopolitanSettings(old versionone.GosmopolitanSettings) versiontwo.GosmopolitanSettings { - return versiontwo.GosmopolitanSettings{ - AllowTimeLocal: old.AllowTimeLocal, - EscapeHatches: old.EscapeHatches, - WatchForScripts: old.WatchForScripts, - } -} - -func toGovetSettings(old versionone.GovetSettings) versiontwo.GovetSettings { - return versiontwo.GovetSettings{ - Go: old.Go, - Enable: old.Enable, - Disable: old.Disable, - EnableAll: old.EnableAll, - DisableAll: old.DisableAll, - Settings: old.Settings, - } -} - -func toGrouperSettings(old versionone.GrouperSettings) versiontwo.GrouperSettings { - return versiontwo.GrouperSettings{ - ConstRequireSingleConst: old.ConstRequireSingleConst, - ConstRequireGrouping: old.ConstRequireGrouping, - ImportRequireSingleImport: old.ImportRequireSingleImport, - ImportRequireGrouping: old.ImportRequireGrouping, - TypeRequireSingleType: old.TypeRequireSingleType, - TypeRequireGrouping: old.TypeRequireGrouping, - VarRequireSingleVar: old.VarRequireSingleVar, - VarRequireGrouping: old.VarRequireGrouping, - } -} - -func toIfaceSettings(old versionone.IfaceSettings) versiontwo.IfaceSettings { - return versiontwo.IfaceSettings{ - Enable: old.Enable, - Settings: old.Settings, - } -} - -func toImportAsSettings(old versionone.ImportAsSettings) versiontwo.ImportAsSettings { - settings := versiontwo.ImportAsSettings{ - NoUnaliased: old.NoUnaliased, - NoExtraAliases: old.NoExtraAliases, - } - - for _, alias := range old.Alias { - settings.Alias = append(settings.Alias, versiontwo.ImportAsAlias{ - Pkg: alias.Pkg, - Alias: alias.Alias, - }) - } - - return settings -} - -func toINamedParamSettings(old versionone.INamedParamSettings) versiontwo.INamedParamSettings { - return versiontwo.INamedParamSettings{ - SkipSingleParam: old.SkipSingleParam, - } -} - -func toInterfaceBloatSettings(old versionone.InterfaceBloatSettings) versiontwo.InterfaceBloatSettings { - return versiontwo.InterfaceBloatSettings{ - Max: old.Max, - } -} - -func toIreturnSettings(old versionone.IreturnSettings) versiontwo.IreturnSettings { - return versiontwo.IreturnSettings{ - Allow: old.Allow, - Reject: old.Reject, - } -} - -func toLllSettings(old versionone.LllSettings) versiontwo.LllSettings { - return versiontwo.LllSettings{ - LineLength: old.LineLength, - TabWidth: old.TabWidth, - } -} - -func toLoggerCheckSettings(old versionone.LoggerCheckSettings) versiontwo.LoggerCheckSettings { - return versiontwo.LoggerCheckSettings{ - Kitlog: old.Kitlog, - Klog: old.Klog, - Logr: old.Logr, - Slog: old.Slog, - Zap: old.Zap, - RequireStringKey: old.RequireStringKey, - NoPrintfLike: old.NoPrintfLike, - Rules: old.Rules, - } -} - -func toMaintIdxSettings(old versionone.MaintIdxSettings) versiontwo.MaintIdxSettings { - return versiontwo.MaintIdxSettings{ - Under: old.Under, - } -} - -func toMakezeroSettings(old versionone.MakezeroSettings) versiontwo.MakezeroSettings { - return versiontwo.MakezeroSettings{ - Always: old.Always, - } -} - -func toMisspellSettings(old versionone.MisspellSettings) versiontwo.MisspellSettings { - settings := versiontwo.MisspellSettings{ - Mode: old.Mode, - Locale: old.Locale, - IgnoreRules: old.IgnoreWords, - } - - for _, word := range old.ExtraWords { - settings.ExtraWords = append(settings.ExtraWords, versiontwo.MisspellExtraWords{ - Typo: word.Typo, - Correction: word.Correction, - }) - } - - return settings -} - -func toMndSettings(old versionone.MndSettings) versiontwo.MndSettings { - return versiontwo.MndSettings{ - Checks: old.Checks, - IgnoredNumbers: old.IgnoredNumbers, - IgnoredFiles: old.IgnoredFiles, - IgnoredFunctions: old.IgnoredFunctions, - } -} - -func toMustTagSettings(old versionone.MustTagSettings) versiontwo.MustTagSettings { - settings := versiontwo.MustTagSettings{} - - for _, function := range old.Functions { - settings.Functions = append(settings.Functions, versiontwo.MustTagFunction{ - Name: function.Name, - Tag: function.Tag, - ArgPos: function.ArgPos, - }) - } - - return settings -} - -func toNakedretSettings(old versionone.NakedretSettings) versiontwo.NakedretSettings { - return versiontwo.NakedretSettings{ - MaxFuncLines: old.MaxFuncLines, - } -} - -func toNestifSettings(old versionone.NestifSettings) versiontwo.NestifSettings { - return versiontwo.NestifSettings{ - MinComplexity: old.MinComplexity, - } -} - -func toNilNilSettings(old versionone.NilNilSettings) versiontwo.NilNilSettings { - return versiontwo.NilNilSettings{ - DetectOpposite: old.DetectOpposite, - CheckedTypes: old.CheckedTypes, - } -} - -func toNlreturnSettings(old versionone.NlreturnSettings) versiontwo.NlreturnSettings { - return versiontwo.NlreturnSettings{ - BlockSize: old.BlockSize, - } -} - -func toNoLintLintSettings(old versionone.NoLintLintSettings) versiontwo.NoLintLintSettings { - return versiontwo.NoLintLintSettings{ - RequireExplanation: old.RequireExplanation, - RequireSpecific: old.RequireSpecific, - AllowNoExplanation: old.AllowNoExplanation, - AllowUnused: old.AllowUnused, - } -} - -func toNoNamedReturnsSettings(old versionone.NoNamedReturnsSettings) versiontwo.NoNamedReturnsSettings { - return versiontwo.NoNamedReturnsSettings{ - ReportErrorInDefer: old.ReportErrorInDefer, - } -} - -func toParallelTestSettings(old versionone.ParallelTestSettings) versiontwo.ParallelTestSettings { - return versiontwo.ParallelTestSettings{ - Go: nil, - IgnoreMissing: old.IgnoreMissing, - IgnoreMissingSubtests: old.IgnoreMissingSubtests, - } -} - -func toPerfSprintSettings(old versionone.PerfSprintSettings) versiontwo.PerfSprintSettings { - return versiontwo.PerfSprintSettings{ - IntegerFormat: old.IntegerFormat, - IntConversion: old.IntConversion, - ErrorFormat: old.ErrorFormat, - ErrError: old.ErrError, - ErrorF: old.ErrorF, - StringFormat: old.StringFormat, - SprintF1: old.SprintF1, - StrConcat: old.StrConcat, - BoolFormat: old.BoolFormat, - HexFormat: old.HexFormat, - } -} - -func toPreallocSettings(old versionone.PreallocSettings) versiontwo.PreallocSettings { - return versiontwo.PreallocSettings{ - Simple: old.Simple, - RangeLoops: old.RangeLoops, - ForLoops: old.ForLoops, - } -} - -func toPredeclaredSettings(old versionone.PredeclaredSettings) versiontwo.PredeclaredSettings { - var ignore []string - if ptr.Deref(old.Ignore) != "" { - ignore = strings.Split(ptr.Deref(old.Ignore), ",") - } - - return versiontwo.PredeclaredSettings{ - Ignore: ignore, - Qualified: old.Qualified, - } -} - -func toPromlinterSettings(old versionone.PromlinterSettings) versiontwo.PromlinterSettings { - return versiontwo.PromlinterSettings{ - Strict: old.Strict, - DisabledLinters: old.DisabledLinters, - } -} - -func toProtoGetterSettings(old versionone.ProtoGetterSettings) versiontwo.ProtoGetterSettings { - return versiontwo.ProtoGetterSettings{ - SkipGeneratedBy: old.SkipGeneratedBy, - SkipFiles: old.SkipFiles, - SkipAnyGenerated: old.SkipAnyGenerated, - ReplaceFirstArgInAppend: old.ReplaceFirstArgInAppend, - } -} - -func toReassignSettings(old versionone.ReassignSettings) versiontwo.ReassignSettings { - return versiontwo.ReassignSettings{ - Patterns: old.Patterns, - } -} - -func toRecvcheckSettings(old versionone.RecvcheckSettings) versiontwo.RecvcheckSettings { - return versiontwo.RecvcheckSettings{ - DisableBuiltin: old.DisableBuiltin, - Exclusions: old.Exclusions, - } -} - -func toReviveSettings(old versionone.ReviveSettings) versiontwo.ReviveSettings { - settings := versiontwo.ReviveSettings{ - MaxOpenFiles: old.MaxOpenFiles, - Confidence: old.Confidence, - Severity: old.Severity, - EnableAllRules: old.EnableAllRules, - ErrorCode: old.ErrorCode, - WarningCode: old.WarningCode, - } - - for _, rule := range old.Rules { - settings.Rules = append(settings.Rules, versiontwo.ReviveRule{ - Name: rule.Name, - Arguments: rule.Arguments, - Severity: rule.Severity, - Disabled: rule.Disabled, - Exclude: rule.Exclude, - }) - } - - for _, directive := range old.Directives { - settings.Directives = append(settings.Directives, versiontwo.ReviveDirective{ - Name: directive.Name, - Severity: directive.Severity, - }) - } - - return settings -} - -func toRowsErrCheckSettings(old versionone.RowsErrCheckSettings) versiontwo.RowsErrCheckSettings { - return versiontwo.RowsErrCheckSettings{ - Packages: old.Packages, - } -} - -func toSlogLintSettings(old versionone.SlogLintSettings) versiontwo.SlogLintSettings { - return versiontwo.SlogLintSettings{ - NoMixedArgs: old.NoMixedArgs, - KVOnly: old.KVOnly, - AttrOnly: old.AttrOnly, - NoGlobal: old.NoGlobal, - Context: old.Context, - StaticMsg: old.StaticMsg, - NoRawKeys: old.NoRawKeys, - KeyNamingCase: old.KeyNamingCase, - ForbiddenKeys: old.ForbiddenKeys, - ArgsOnSepLines: old.ArgsOnSepLines, - } -} - -func toSpancheckSettings(old versionone.SpancheckSettings) versiontwo.SpancheckSettings { - return versiontwo.SpancheckSettings{ - Checks: old.Checks, - IgnoreCheckSignatures: old.IgnoreCheckSignatures, - ExtraStartSpanSignatures: old.ExtraStartSpanSignatures, - } -} - -func toStaticCheckSettings(old versionone.LintersSettings) versiontwo.StaticCheckSettings { - var checks []string - - for _, check := range slices.Concat(old.Staticcheck.Checks, old.Stylecheck.Checks, old.Gosimple.Checks) { - if check == "*" { - checks = append(checks, "all") - continue - } - checks = append(checks, check) - } - - checks = Unique(checks) - - slices.SortFunc(checks, func(a, b string) int { - if a == "all" { - return -1 - } - - if b == "all" { - return 1 - } - - return strings.Compare(a, b) - }) - - return versiontwo.StaticCheckSettings{ - Checks: checks, - Initialisms: old.Stylecheck.Initialisms, - DotImportWhitelist: old.Stylecheck.DotImportWhitelist, - HTTPStatusCodeWhitelist: old.Stylecheck.HTTPStatusCodeWhitelist, - } -} - -func toTagAlignSettings(old versionone.TagAlignSettings) versiontwo.TagAlignSettings { - return versiontwo.TagAlignSettings{ - Align: old.Align, - Sort: old.Sort, - Order: old.Order, - Strict: old.Strict, - } -} - -func toTagliatelleSettings(old versionone.TagliatelleSettings) versiontwo.TagliatelleSettings { - tcase := versiontwo.TagliatelleCase{ - TagliatelleBase: versiontwo.TagliatelleBase{ - Rules: old.Case.Rules, - UseFieldName: old.Case.UseFieldName, - IgnoredFields: old.Case.IgnoredFields, - }, - Overrides: []versiontwo.TagliatelleOverrides{}, - } - - for k, rule := range old.Case.ExtendedRules { - if tcase.ExtendedRules == nil { - tcase.ExtendedRules = make(map[string]versiontwo.TagliatelleExtendedRule) - } - - tcase.ExtendedRules[k] = versiontwo.TagliatelleExtendedRule{ - Case: rule.Case, - ExtraInitialisms: rule.ExtraInitialisms, - InitialismOverrides: rule.InitialismOverrides, - } - } - - return versiontwo.TagliatelleSettings{Case: tcase} -} - -func toTestifylintSettings(old versionone.TestifylintSettings) versiontwo.TestifylintSettings { - return versiontwo.TestifylintSettings{ - EnableAll: old.EnableAll, - DisableAll: old.DisableAll, - EnabledCheckers: old.EnabledCheckers, - DisabledCheckers: old.DisabledCheckers, - BoolCompare: versiontwo.TestifylintBoolCompare{ - IgnoreCustomTypes: old.BoolCompare.IgnoreCustomTypes, - }, - ExpectedActual: versiontwo.TestifylintExpectedActual{ - ExpVarPattern: old.ExpectedActual.ExpVarPattern, - }, - Formatter: versiontwo.TestifylintFormatter{ - CheckFormatString: old.Formatter.CheckFormatString, - RequireFFuncs: old.Formatter.RequireFFuncs, - }, - GoRequire: versiontwo.TestifylintGoRequire{ - IgnoreHTTPHandlers: old.GoRequire.IgnoreHTTPHandlers, - }, - RequireError: versiontwo.TestifylintRequireError{ - FnPattern: old.RequireError.FnPattern, - }, - SuiteExtraAssertCall: versiontwo.TestifylintSuiteExtraAssertCall{ - Mode: old.SuiteExtraAssertCall.Mode, - }, - } -} - -func toTestpackageSettings(old versionone.TestpackageSettings) versiontwo.TestpackageSettings { - return versiontwo.TestpackageSettings{ - SkipRegexp: old.SkipRegexp, - AllowPackages: old.AllowPackages, - } -} - -func toThelperSettings(old versionone.ThelperSettings) versiontwo.ThelperSettings { - return versiontwo.ThelperSettings{ - Test: versiontwo.ThelperOptions{ - First: old.Test.First, - Name: old.Test.Name, - Begin: old.Test.Begin, - }, - Fuzz: versiontwo.ThelperOptions{ - First: old.Fuzz.First, - Name: old.Fuzz.Name, - Begin: old.Fuzz.Begin, - }, - Benchmark: versiontwo.ThelperOptions{ - First: old.Benchmark.First, - Name: old.Benchmark.Name, - Begin: old.Benchmark.Begin, - }, - TB: versiontwo.ThelperOptions{ - First: old.TB.First, - Name: old.TB.Name, - Begin: old.TB.Begin, - }, - } -} - -func toUnconvertSettings(old versionone.UnconvertSettings) versiontwo.UnconvertSettings { - return versiontwo.UnconvertSettings{ - FastMath: old.FastMath, - Safe: old.Safe, - } -} - -func toUnparamSettings(old versionone.UnparamSettings) versiontwo.UnparamSettings { - return versiontwo.UnparamSettings{ - CheckExported: old.CheckExported, - } -} - -func toUnusedSettings(old versionone.UnusedSettings) versiontwo.UnusedSettings { - return versiontwo.UnusedSettings{ - FieldWritesAreUses: old.FieldWritesAreUses, - PostStatementsAreReads: old.PostStatementsAreReads, - ExportedFieldsAreUsed: old.ExportedFieldsAreUsed, - ParametersAreUsed: old.ParametersAreUsed, - LocalVariablesAreUsed: old.LocalVariablesAreUsed, - GeneratedIsUsed: old.GeneratedIsUsed, - } -} - -func toUseStdlibVarsSettings(old versionone.UseStdlibVarsSettings) versiontwo.UseStdlibVarsSettings { - return versiontwo.UseStdlibVarsSettings{ - HTTPMethod: old.HTTPMethod, - HTTPStatusCode: old.HTTPStatusCode, - TimeWeekday: old.TimeWeekday, - TimeMonth: old.TimeMonth, - TimeLayout: old.TimeLayout, - CryptoHash: old.CryptoHash, - DefaultRPCPath: old.DefaultRPCPath, - SQLIsolationLevel: old.SQLIsolationLevel, - TLSSignatureScheme: old.TLSSignatureScheme, - ConstantKind: old.ConstantKind, - } -} - -func toUseTestingSettings(old versionone.UseTestingSettings) versiontwo.UseTestingSettings { - return versiontwo.UseTestingSettings{ - ContextBackground: old.ContextBackground, - ContextTodo: old.ContextTodo, - OSChdir: old.OSChdir, - OSMkdirTemp: old.OSMkdirTemp, - OSSetenv: old.OSSetenv, - OSTempDir: old.OSTempDir, - OSCreateTemp: old.OSCreateTemp, - } -} - -func toVarnamelenSettings(old versionone.VarnamelenSettings) versiontwo.VarnamelenSettings { - return versiontwo.VarnamelenSettings{ - MaxDistance: old.MaxDistance, - MinNameLength: old.MinNameLength, - CheckReceiver: old.CheckReceiver, - CheckReturn: old.CheckReturn, - CheckTypeParam: old.CheckTypeParam, - IgnoreNames: old.IgnoreNames, - IgnoreTypeAssertOk: old.IgnoreTypeAssertOk, - IgnoreMapIndexOk: old.IgnoreMapIndexOk, - IgnoreChanRecvOk: old.IgnoreChanRecvOk, - IgnoreDecls: old.IgnoreDecls, - } -} - -func toWhitespaceSettings(old versionone.WhitespaceSettings) versiontwo.WhitespaceSettings { - return versiontwo.WhitespaceSettings{ - MultiIf: old.MultiIf, - MultiFunc: old.MultiFunc, - } -} - -func toWrapcheckSettings(old versionone.WrapcheckSettings) versiontwo.WrapcheckSettings { - return versiontwo.WrapcheckSettings{ - ExtraIgnoreSigs: old.ExtraIgnoreSigs, - IgnoreSigs: old.IgnoreSigs, - IgnoreSigRegexps: old.IgnoreSigRegexps, - IgnorePackageGlobs: old.IgnorePackageGlobs, - IgnoreInterfaceRegexps: old.IgnoreInterfaceRegexps, - } -} - -func toWSLSettings(old versionone.WSLSettings) versiontwo.WSLv4Settings { - return versiontwo.WSLv4Settings{ - StrictAppend: old.StrictAppend, - AllowAssignAndCallCuddle: old.AllowAssignAndCallCuddle, - AllowAssignAndAnythingCuddle: old.AllowAssignAndAnythingCuddle, - AllowMultiLineAssignCuddle: old.AllowMultiLineAssignCuddle, - ForceCaseTrailingWhitespaceLimit: old.ForceCaseTrailingWhitespaceLimit, - AllowTrailingComment: old.AllowTrailingComment, - AllowSeparatedLeadingComment: old.AllowSeparatedLeadingComment, - AllowCuddleDeclaration: old.AllowCuddleDeclaration, - AllowCuddleWithCalls: old.AllowCuddleWithCalls, - AllowCuddleWithRHS: old.AllowCuddleWithRHS, - ForceCuddleErrCheckAndAssign: old.ForceCuddleErrCheckAndAssign, - ErrorVariableNames: old.ErrorVariableNames, - ForceExclusiveShortDeclarations: old.ForceExclusiveShortDeclarations, - } -} - -func toCustom(old map[string]versionone.CustomLinterSettings) map[string]versiontwo.CustomLinterSettings { - if old == nil { - return nil - } - - settings := map[string]versiontwo.CustomLinterSettings{} - - for k, s := range old { - settings[k] = versiontwo.CustomLinterSettings{ - Type: s.Type, - Path: s.Path, - Description: s.Description, - OriginalURL: s.OriginalURL, - Settings: s.Settings, - } - } - - return settings -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_output.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_output.go deleted file mode 100644 index e76f8e4471..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_output.go +++ /dev/null @@ -1,103 +0,0 @@ -package migrate - -import ( - "slices" - - "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/ptr" - "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone" - "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo" -) - -func toOutput(old *versionone.Config) versiontwo.Output { - formats := versiontwo.Formats{} - - oldFormats := cleanIncompatibleFormats(old.Output.Formats, "colored-line-number", "line-number") - oldFormats = cleanIncompatibleFormats(oldFormats, "colored-tab", "tab") - oldFormats = cleanIncompatibleFormats(oldFormats, "junit-xml-extended", "junit-xml") - - for _, format := range oldFormats { - switch ptr.Deref(format.Format) { - case "colored-line-number": - formats.Text.PrintLinterName = old.Output.PrintLinterName - formats.Text.PrintIssuedLine = old.Output.PrintIssuedLine - formats.Text.Colors = nil // color is true by default (flags). - formats.Text.Path = ptr.Pointer(defaultFormatPath(ptr.Deref(format.Path))) - - case "line-number": - formats.Text.PrintLinterName = old.Output.PrintLinterName - formats.Text.PrintIssuedLine = old.Output.PrintIssuedLine - formats.Text.Colors = ptr.Pointer(false) - formats.Text.Path = ptr.Pointer(defaultFormatPath(ptr.Deref(format.Path))) - - case "json": - formats.JSON.Path = ptr.Pointer(defaultFormatPath(ptr.Deref(format.Path))) - - case "colored-tab": - formats.Tab.PrintLinterName = old.Output.PrintLinterName - formats.Tab.Colors = nil // Colors is true by default (flags). - formats.Tab.Path = ptr.Pointer(defaultFormatPath(ptr.Deref(format.Path))) - - case "tab": - formats.Tab.PrintLinterName = old.Output.PrintLinterName - formats.Tab.Colors = ptr.Pointer(false) - formats.Tab.Path = ptr.Pointer(defaultFormatPath(ptr.Deref(format.Path))) - - case "html": - formats.HTML.Path = ptr.Pointer(defaultFormatPath(ptr.Deref(format.Path))) - - case "checkstyle": - formats.Checkstyle.Path = ptr.Pointer(defaultFormatPath(ptr.Deref(format.Path))) - - case "code-climate": - formats.CodeClimate.Path = ptr.Pointer(defaultFormatPath(ptr.Deref(format.Path))) - - case "junit-xml": - formats.JUnitXML.Extended = nil // Extended is false by default. - formats.JUnitXML.Path = ptr.Pointer(defaultFormatPath(ptr.Deref(format.Path))) - - case "junit-xml-extended": - formats.JUnitXML.Extended = ptr.Pointer(true) - formats.JUnitXML.Path = ptr.Pointer(defaultFormatPath(ptr.Deref(format.Path))) - - case "github-actions": - // Ignored - - case "teamcity": - formats.TeamCity.Path = ptr.Pointer(defaultFormatPath(ptr.Deref(format.Path))) - - case "sarif": - formats.Sarif.Path = ptr.Pointer(defaultFormatPath(ptr.Deref(format.Path))) - } - } - - return versiontwo.Output{ - Formats: formats, - SortOrder: old.Output.SortOrder, - PathPrefix: old.Output.PathPrefix, - ShowStats: nil, // Enforce the new default. (nil -> omitempty -> true) - } -} - -func defaultFormatPath(p string) string { - if p == "" { - return "stdout" - } - - return p -} - -func cleanIncompatibleFormats(old versionone.OutputFormats, f1, f2 string) versionone.OutputFormats { - index1 := slices.IndexFunc(old, func(format versionone.OutputFormat) bool { - return ptr.Deref(format.Format) == f1 - }) - - index2 := slices.IndexFunc(old, func(format versionone.OutputFormat) bool { - return ptr.Deref(format.Format) == f2 - }) - - if index1 >= 0 && index2 >= 0 { - return slices.Delete(old, index2, index2+1) - } - - return old -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_run.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_run.go deleted file mode 100644 index 88db447095..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_run.go +++ /dev/null @@ -1,34 +0,0 @@ -package migrate - -import ( - "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/ptr" - "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone" - "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo" -) - -func toRun(old *versionone.Config) versiontwo.Run { - var relativePathMode *string - if ptr.Deref(old.Run.RelativePathMode) != "cfg" { - // cfg is the new default. - relativePathMode = old.Run.RelativePathMode - } - - var concurrency *int - if ptr.Deref(old.Run.Concurrency) != 0 { - // 0 is the new default - concurrency = old.Run.Concurrency - } - - return versiontwo.Run{ - Timeout: 0, // Enforce new default. - Concurrency: concurrency, - Go: old.Run.Go, - RelativePathMode: relativePathMode, - BuildTags: old.Run.BuildTags, - ModulesDownloadMode: old.Run.ModulesDownloadMode, - ExitCodeIfIssuesFound: old.Run.ExitCodeIfIssuesFound, - AnalyzeTests: old.Run.AnalyzeTests, - AllowParallelRunners: old.Run.AllowParallelRunners, - AllowSerialRunners: old.Run.AllowSerialRunners, - } -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_severity.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_severity.go deleted file mode 100644 index 6db40bca78..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/migrate_severity.go +++ /dev/null @@ -1,33 +0,0 @@ -package migrate - -import ( - "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone" - "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo" -) - -func toSeverity(old *versionone.Config) versiontwo.Severity { - var rules []versiontwo.SeverityRule - - for _, rule := range old.Severity.Rules { - names := convertStaticcheckLinterNames(convertAlternativeNames(rule.Linters)) - if len(rule.Linters) > 0 && len(names) == 0 { - continue - } - - rules = append(rules, versiontwo.SeverityRule{ - BaseRule: versiontwo.BaseRule{ - Linters: names, - Path: rule.Path, - PathExcept: rule.PathExcept, - Text: rule.Text, - Source: rule.Source, - }, - Severity: rule.Severity, - }) - } - - return versiontwo.Severity{ - Default: old.Severity.Default, - Rules: rules, - } -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/parser/parser.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/parser/parser.go deleted file mode 100644 index ea00b41f5a..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/parser/parser.go +++ /dev/null @@ -1,87 +0,0 @@ -package parser - -import ( - "bytes" - "encoding/json" - "errors" - "fmt" - "io" - "path/filepath" - "strings" - - "github.com/pelletier/go-toml/v2" - "gopkg.in/yaml.v3" -) - -type File interface { - io.ReadWriter - Name() string -} - -// Decode decodes a file into data. -// The choice of the decoder is based on the file extension. -func Decode(file File, data any) error { - ext := filepath.Ext(file.Name()) - - switch strings.ToLower(ext) { - case ".yaml", ".yml", ".json": - err := yaml.NewDecoder(file).Decode(data) - if err != nil && !errors.Is(err, io.EOF) { - return fmt.Errorf("YAML decode file %s: %w", file.Name(), err) - } - - case ".toml": - err := toml.NewDecoder(file).Decode(&data) - if err != nil { - return fmt.Errorf("TOML decode file %s: %w", file.Name(), err) - } - - default: - return fmt.Errorf("unsupported file type: %s", ext) - } - - return nil -} - -// Encode encodes data into a file. -// The choice of the encoder is based on the file extension. -func Encode(data any, dstFile File) error { - ext := filepath.Ext(dstFile.Name()) - - switch strings.ToLower(ext) { - case ".yml", ".yaml": - encoder := yaml.NewEncoder(dstFile) - encoder.SetIndent(2) - - return encoder.Encode(data) - - case ".toml": - encoder := toml.NewEncoder(dstFile) - - return encoder.Encode(data) - - case ".json": - // The JSON encoder converts empty struct to `{}` instead of nothing (even with omitempty JSON struct tags). - // So we need to use the YAML encoder as bridge to create JSON file. - - var buf bytes.Buffer - err := yaml.NewEncoder(&buf).Encode(data) - if err != nil { - return err - } - - raw := map[string]any{} - err = yaml.NewDecoder(&buf).Decode(raw) - if err != nil { - return err - } - - encoder := json.NewEncoder(dstFile) - encoder.SetIndent("", " ") - - return encoder.Encode(raw) - - default: - return fmt.Errorf("unsupported file type: %s", ext) - } -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/ptr/ptr.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/ptr/ptr.go deleted file mode 100644 index b0c7974e0e..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/ptr/ptr.go +++ /dev/null @@ -1,12 +0,0 @@ -package ptr - -func Deref[T any](v *T) T { - if v == nil { - var zero T - return zero - } - - return *v -} - -func Pointer[T any](v T) *T { return &v } diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/base_rule.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/base_rule.go deleted file mode 100644 index 244e25997b..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/base_rule.go +++ /dev/null @@ -1,9 +0,0 @@ -package versionone - -type BaseRule struct { - Linters []string `mapstructure:"linters"` - Path *string `mapstructure:"path"` - PathExcept *string `mapstructure:"path-except"` - Text *string `mapstructure:"text"` - Source *string `mapstructure:"source"` -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/config.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/config.go deleted file mode 100644 index 1e9d0ee151..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/config.go +++ /dev/null @@ -1,18 +0,0 @@ -package versionone - -type Config struct { - Version string `mapstructure:"version"` // From v2, to be able to detect already migrated config file. - - Run Run `mapstructure:"run"` - - Output Output `mapstructure:"output"` - - LintersSettings LintersSettings `mapstructure:"linters-settings"` - Linters Linters `mapstructure:"linters"` - Issues Issues `mapstructure:"issues"` - Severity Severity `mapstructure:"severity"` -} - -func NewConfig() *Config { - return &Config{} -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/doc.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/doc.go deleted file mode 100644 index fb945f3c58..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/doc.go +++ /dev/null @@ -1,4 +0,0 @@ -// Package versionone contains a modified copy of v1 configuration. -// The structures are altered to use pointer on builtin types. -// The field version is added to enforce the detection of already migrated file. -package versionone diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/issues.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/issues.go deleted file mode 100644 index bac6ba9ca2..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/issues.go +++ /dev/null @@ -1,32 +0,0 @@ -package versionone - -type Issues struct { - IncludeDefaultExcludes []string `mapstructure:"include"` - ExcludeCaseSensitive *bool `mapstructure:"exclude-case-sensitive"` - ExcludePatterns []string `mapstructure:"exclude"` - ExcludeRules []ExcludeRule `mapstructure:"exclude-rules"` - UseDefaultExcludes *bool `mapstructure:"exclude-use-default"` - - ExcludeGenerated *string `mapstructure:"exclude-generated"` - - ExcludeFiles []string `mapstructure:"exclude-files"` - ExcludeDirs []string `mapstructure:"exclude-dirs"` - - UseDefaultExcludeDirs *bool `mapstructure:"exclude-dirs-use-default"` - - MaxIssuesPerLinter *int `mapstructure:"max-issues-per-linter"` - MaxSameIssues *int `mapstructure:"max-same-issues"` - UniqByLine *bool `mapstructure:"uniq-by-line"` - - DiffFromRevision *string `mapstructure:"new-from-rev"` - DiffFromMergeBase *string `mapstructure:"new-from-merge-base"` - DiffPatchFilePath *string `mapstructure:"new-from-patch"` - WholeFiles *bool `mapstructure:"whole-files"` - Diff *bool `mapstructure:"new"` - - NeedFix *bool `mapstructure:"fix"` -} - -type ExcludeRule struct { - BaseRule `mapstructure:",squash"` -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/linters.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/linters.go deleted file mode 100644 index d6a490fee0..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/linters.go +++ /dev/null @@ -1,11 +0,0 @@ -package versionone - -type Linters struct { - Enable []string `mapstructure:"enable"` - Disable []string `mapstructure:"disable"` - EnableAll *bool `mapstructure:"enable-all"` - DisableAll *bool `mapstructure:"disable-all"` - Fast *bool `mapstructure:"fast"` - - Presets []string `mapstructure:"presets"` -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/linters_settings.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/linters_settings.go deleted file mode 100644 index 44583b7d34..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/linters_settings.go +++ /dev/null @@ -1,865 +0,0 @@ -package versionone - -import ( - "encoding" - - "gopkg.in/yaml.v3" - - "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/ptr" -) - -type LintersSettings struct { - Asasalint AsasalintSettings `mapstructure:"asasalint"` - BiDiChk BiDiChkSettings `mapstructure:"bidichk"` - CopyLoopVar CopyLoopVarSettings `mapstructure:"copyloopvar"` - Cyclop Cyclop `mapstructure:"cyclop"` - Decorder DecorderSettings `mapstructure:"decorder"` - Depguard DepGuardSettings `mapstructure:"depguard"` - Dogsled DogsledSettings `mapstructure:"dogsled"` - Dupl DuplSettings `mapstructure:"dupl"` - DupWord DupWordSettings `mapstructure:"dupword"` - Errcheck ErrcheckSettings `mapstructure:"errcheck"` - ErrChkJSON ErrChkJSONSettings `mapstructure:"errchkjson"` - ErrorLint ErrorLintSettings `mapstructure:"errorlint"` - Exhaustive ExhaustiveSettings `mapstructure:"exhaustive"` - Exhaustruct ExhaustructSettings `mapstructure:"exhaustruct"` - Fatcontext FatcontextSettings `mapstructure:"fatcontext"` - Forbidigo ForbidigoSettings `mapstructure:"forbidigo"` - Funlen FunlenSettings `mapstructure:"funlen"` - GinkgoLinter GinkgoLinterSettings `mapstructure:"ginkgolinter"` - Gocognit GocognitSettings `mapstructure:"gocognit"` - GoChecksumType GoChecksumTypeSettings `mapstructure:"gochecksumtype"` - Goconst GoConstSettings `mapstructure:"goconst"` - Gocritic GoCriticSettings `mapstructure:"gocritic"` - Gocyclo GoCycloSettings `mapstructure:"gocyclo"` - Godot GodotSettings `mapstructure:"godot"` - Godox GodoxSettings `mapstructure:"godox"` - Goheader GoHeaderSettings `mapstructure:"goheader"` - GoModDirectives GoModDirectivesSettings `mapstructure:"gomoddirectives"` - Gomodguard GoModGuardSettings `mapstructure:"gomodguard"` - Gosec GoSecSettings `mapstructure:"gosec"` - Gosimple StaticCheckSettings `mapstructure:"gosimple"` - Gosmopolitan GosmopolitanSettings `mapstructure:"gosmopolitan"` - Govet GovetSettings `mapstructure:"govet"` - Grouper GrouperSettings `mapstructure:"grouper"` - Iface IfaceSettings `mapstructure:"iface"` - ImportAs ImportAsSettings `mapstructure:"importas"` - Inamedparam INamedParamSettings `mapstructure:"inamedparam"` - InterfaceBloat InterfaceBloatSettings `mapstructure:"interfacebloat"` - Ireturn IreturnSettings `mapstructure:"ireturn"` - Lll LllSettings `mapstructure:"lll"` - LoggerCheck LoggerCheckSettings `mapstructure:"loggercheck"` - MaintIdx MaintIdxSettings `mapstructure:"maintidx"` - Makezero MakezeroSettings `mapstructure:"makezero"` - Misspell MisspellSettings `mapstructure:"misspell"` - Mnd MndSettings `mapstructure:"mnd"` - MustTag MustTagSettings `mapstructure:"musttag"` - Nakedret NakedretSettings `mapstructure:"nakedret"` - Nestif NestifSettings `mapstructure:"nestif"` - NilNil NilNilSettings `mapstructure:"nilnil"` - Nlreturn NlreturnSettings `mapstructure:"nlreturn"` - NoLintLint NoLintLintSettings `mapstructure:"nolintlint"` - NoNamedReturns NoNamedReturnsSettings `mapstructure:"nonamedreturns"` - ParallelTest ParallelTestSettings `mapstructure:"paralleltest"` - PerfSprint PerfSprintSettings `mapstructure:"perfsprint"` - Prealloc PreallocSettings `mapstructure:"prealloc"` - Predeclared PredeclaredSettings `mapstructure:"predeclared"` - Promlinter PromlinterSettings `mapstructure:"promlinter"` - ProtoGetter ProtoGetterSettings `mapstructure:"protogetter"` - Reassign ReassignSettings `mapstructure:"reassign"` - Recvcheck RecvcheckSettings `mapstructure:"recvcheck"` - Revive ReviveSettings `mapstructure:"revive"` - RowsErrCheck RowsErrCheckSettings `mapstructure:"rowserrcheck"` - SlogLint SlogLintSettings `mapstructure:"sloglint"` - Spancheck SpancheckSettings `mapstructure:"spancheck"` - Staticcheck StaticCheckSettings `mapstructure:"staticcheck"` - Stylecheck StaticCheckSettings `mapstructure:"stylecheck"` - TagAlign TagAlignSettings `mapstructure:"tagalign"` - Tagliatelle TagliatelleSettings `mapstructure:"tagliatelle"` - Tenv TenvSettings `mapstructure:"tenv"` - Testifylint TestifylintSettings `mapstructure:"testifylint"` - Testpackage TestpackageSettings `mapstructure:"testpackage"` - Thelper ThelperSettings `mapstructure:"thelper"` - Unconvert UnconvertSettings `mapstructure:"unconvert"` - Unparam UnparamSettings `mapstructure:"unparam"` - Unused UnusedSettings `mapstructure:"unused"` - UseStdlibVars UseStdlibVarsSettings `mapstructure:"usestdlibvars"` - UseTesting UseTestingSettings `mapstructure:"usetesting"` - Varnamelen VarnamelenSettings `mapstructure:"varnamelen"` - Whitespace WhitespaceSettings `mapstructure:"whitespace"` - Wrapcheck WrapcheckSettings `mapstructure:"wrapcheck"` - WSL WSLSettings `mapstructure:"wsl"` - - Custom map[string]CustomLinterSettings `mapstructure:"custom"` - - Gci GciSettings `mapstructure:"gci"` - GoFmt GoFmtSettings `mapstructure:"gofmt"` - GoFumpt GoFumptSettings `mapstructure:"gofumpt"` - GoImports GoImportsSettings `mapstructure:"goimports"` -} - -type AsasalintSettings struct { - Exclude []string `mapstructure:"exclude"` - UseBuiltinExclusions *bool `mapstructure:"use-builtin-exclusions"` - IgnoreTest *bool `mapstructure:"ignore-test"` -} - -type BiDiChkSettings struct { - LeftToRightEmbedding *bool `mapstructure:"left-to-right-embedding"` - RightToLeftEmbedding *bool `mapstructure:"right-to-left-embedding"` - PopDirectionalFormatting *bool `mapstructure:"pop-directional-formatting"` - LeftToRightOverride *bool `mapstructure:"left-to-right-override"` - RightToLeftOverride *bool `mapstructure:"right-to-left-override"` - LeftToRightIsolate *bool `mapstructure:"left-to-right-isolate"` - RightToLeftIsolate *bool `mapstructure:"right-to-left-isolate"` - FirstStrongIsolate *bool `mapstructure:"first-strong-isolate"` - PopDirectionalIsolate *bool `mapstructure:"pop-directional-isolate"` -} - -type CopyLoopVarSettings struct { - CheckAlias *bool `mapstructure:"check-alias"` - - // Deprecated: use CheckAlias - IgnoreAlias *bool `mapstructure:"ignore-alias"` -} - -type Cyclop struct { - MaxComplexity *int `mapstructure:"max-complexity"` - PackageAverage *float64 `mapstructure:"package-average"` - SkipTests *bool `mapstructure:"skip-tests"` -} - -type DepGuardSettings struct { - Rules map[string]*DepGuardList `mapstructure:"rules"` -} - -type DepGuardList struct { - ListMode *string `mapstructure:"list-mode"` - Files []string `mapstructure:"files"` - Allow []string `mapstructure:"allow"` - Deny []DepGuardDeny `mapstructure:"deny"` -} - -type DepGuardDeny struct { - Pkg *string `mapstructure:"pkg"` - Desc *string `mapstructure:"desc"` -} - -type DecorderSettings struct { - DecOrder []string `mapstructure:"dec-order"` - IgnoreUnderscoreVars *bool `mapstructure:"ignore-underscore-vars"` - DisableDecNumCheck *bool `mapstructure:"disable-dec-num-check"` - DisableTypeDecNumCheck *bool `mapstructure:"disable-type-dec-num-check"` - DisableConstDecNumCheck *bool `mapstructure:"disable-const-dec-num-check"` - DisableVarDecNumCheck *bool `mapstructure:"disable-var-dec-num-check"` - DisableDecOrderCheck *bool `mapstructure:"disable-dec-order-check"` - DisableInitFuncFirstCheck *bool `mapstructure:"disable-init-func-first-check"` -} - -type DogsledSettings struct { - MaxBlankIdentifiers *int `mapstructure:"max-blank-identifiers"` -} - -type DuplSettings struct { - Threshold *int `mapstructure:"threshold"` -} - -type DupWordSettings struct { - Keywords []string `mapstructure:"keywords"` - Ignore []string `mapstructure:"ignore"` -} - -type ErrcheckSettings struct { - DisableDefaultExclusions *bool `mapstructure:"disable-default-exclusions"` - CheckTypeAssertions *bool `mapstructure:"check-type-assertions"` - CheckAssignToBlank *bool `mapstructure:"check-blank"` - ExcludeFunctions []string `mapstructure:"exclude-functions"` - - // Deprecated: use ExcludeFunctions instead - Exclude *string `mapstructure:"exclude"` - - // Deprecated: use ExcludeFunctions instead - Ignore *string `mapstructure:"ignore"` -} - -type ErrChkJSONSettings struct { - CheckErrorFreeEncoding *bool `mapstructure:"check-error-free-encoding"` - ReportNoExported *bool `mapstructure:"report-no-exported"` -} - -type ErrorLintSettings struct { - Errorf *bool `mapstructure:"errorf"` - ErrorfMulti *bool `mapstructure:"errorf-multi"` - Asserts *bool `mapstructure:"asserts"` - Comparison *bool `mapstructure:"comparison"` - AllowedErrors []ErrorLintAllowPair `mapstructure:"allowed-errors"` - AllowedErrorsWildcard []ErrorLintAllowPair `mapstructure:"allowed-errors-wildcard"` -} - -type ErrorLintAllowPair struct { - Err *string `mapstructure:"err"` - Fun *string `mapstructure:"fun"` -} - -type ExhaustiveSettings struct { - Check []string `mapstructure:"check"` - CheckGenerated *bool `mapstructure:"check-generated"` - DefaultSignifiesExhaustive *bool `mapstructure:"default-signifies-exhaustive"` - IgnoreEnumMembers *string `mapstructure:"ignore-enum-members"` - IgnoreEnumTypes *string `mapstructure:"ignore-enum-types"` - PackageScopeOnly *bool `mapstructure:"package-scope-only"` - ExplicitExhaustiveMap *bool `mapstructure:"explicit-exhaustive-map"` - ExplicitExhaustiveSwitch *bool `mapstructure:"explicit-exhaustive-switch"` - DefaultCaseRequired *bool `mapstructure:"default-case-required"` -} - -type ExhaustructSettings struct { - Include []string `mapstructure:"include"` - Exclude []string `mapstructure:"exclude"` -} - -type FatcontextSettings struct { - CheckStructPointers *bool `mapstructure:"check-struct-pointers"` -} - -type ForbidigoSettings struct { - Forbid []ForbidigoPattern `mapstructure:"forbid"` - ExcludeGodocExamples *bool `mapstructure:"exclude-godoc-examples"` - AnalyzeTypes *bool `mapstructure:"analyze-types"` -} - -var _ encoding.TextUnmarshaler = &ForbidigoPattern{} - -// ForbidigoPattern corresponds to forbidigo.pattern and adds mapstructure support. -// The YAML field names must match what forbidigo expects. -type ForbidigoPattern struct { - // patternString gets populated when the config contains a *string as entry in ForbidigoSettings.Forbid[] - // because ForbidigoPattern implements encoding.TextUnmarshaler - // and the reader uses the mapstructure.TextUnmarshallerHookFunc as decoder hook. - // - // If the entry is a map, then the other fields are set as usual by mapstructure. - patternString *string - Pattern *string `yaml:"p" mapstructure:"p"` - Package *string `yaml:"pkg,omitempty" mapstructure:"pkg,omitempty"` - Msg *string `yaml:"msg,omitempty" mapstructure:"msg,omitempty"` -} - -func (p *ForbidigoPattern) UnmarshalText(text []byte) error { - // Validation happens when instantiating forbidigo. - p.patternString = ptr.Pointer(string(text)) - return nil -} - -// MarshalString converts the pattern into a *string as needed by forbidigo.NewLinter. -// -// MarshalString is intentionally not called MarshalText, -// although it has the same signature -// because implementing encoding.TextMarshaler led to infinite recursion when yaml.Marshal called MarshalText. -func (p *ForbidigoPattern) MarshalString() ([]byte, error) { - if ptr.Deref(p.patternString) != "" { - return []byte(ptr.Deref(p.patternString)), nil - } - - return yaml.Marshal(p) -} - -type FunlenSettings struct { - Lines *int `mapstructure:"lines"` - Statements *int `mapstructure:"statements"` - IgnoreComments *bool `mapstructure:"ignore-comments"` -} - -type GinkgoLinterSettings struct { - SuppressLenAssertion *bool `mapstructure:"suppress-len-assertion"` - SuppressNilAssertion *bool `mapstructure:"suppress-nil-assertion"` - SuppressErrAssertion *bool `mapstructure:"suppress-err-assertion"` - SuppressCompareAssertion *bool `mapstructure:"suppress-compare-assertion"` - SuppressAsyncAssertion *bool `mapstructure:"suppress-async-assertion"` - SuppressTypeCompareWarning *bool `mapstructure:"suppress-type-compare-assertion"` - ForbidFocusContainer *bool `mapstructure:"forbid-focus-container"` - AllowHaveLenZero *bool `mapstructure:"allow-havelen-zero"` - ForceExpectTo *bool `mapstructure:"force-expect-to"` - ValidateAsyncIntervals *bool `mapstructure:"validate-async-intervals"` - ForbidSpecPollution *bool `mapstructure:"forbid-spec-pollution"` - ForceSucceedForFuncs *bool `mapstructure:"force-succeed"` -} - -type GoChecksumTypeSettings struct { - DefaultSignifiesExhaustive *bool `mapstructure:"default-signifies-exhaustive"` - IncludeSharedInterfaces *bool `mapstructure:"include-shared-interfaces"` -} - -type GocognitSettings struct { - MinComplexity *int `mapstructure:"min-complexity"` -} - -type GoConstSettings struct { - IgnoreStrings *string `mapstructure:"ignore-strings"` - IgnoreTests *bool `mapstructure:"ignore-tests"` - MatchWithConstants *bool `mapstructure:"match-constant"` - MinStringLen *int `mapstructure:"min-len"` - MinOccurrencesCount *int `mapstructure:"min-occurrences"` - ParseNumbers *bool `mapstructure:"numbers"` - NumberMin *int `mapstructure:"min"` - NumberMax *int `mapstructure:"max"` - IgnoreCalls *bool `mapstructure:"ignore-calls"` -} - -type GoCriticSettings struct { - Go *string `mapstructure:"-"` - DisableAll *bool `mapstructure:"disable-all"` - EnabledChecks []string `mapstructure:"enabled-checks"` - EnableAll *bool `mapstructure:"enable-all"` - DisabledChecks []string `mapstructure:"disabled-checks"` - EnabledTags []string `mapstructure:"enabled-tags"` - DisabledTags []string `mapstructure:"disabled-tags"` - SettingsPerCheck map[string]GoCriticCheckSettings `mapstructure:"settings"` -} - -type GoCriticCheckSettings map[string]any - -type GoCycloSettings struct { - MinComplexity *int `mapstructure:"min-complexity"` -} - -type GodotSettings struct { - Scope *string `mapstructure:"scope"` - Exclude []string `mapstructure:"exclude"` - Capital *bool `mapstructure:"capital"` - Period *bool `mapstructure:"period"` - - // Deprecated: use Scope instead - CheckAll *bool `mapstructure:"check-all"` -} - -type GodoxSettings struct { - Keywords []string `mapstructure:"keywords"` -} - -type GoHeaderSettings struct { - Values map[string]map[string]string `mapstructure:"values"` - Template *string `mapstructure:"template"` - TemplatePath *string `mapstructure:"template-path"` -} - -type GoModDirectivesSettings struct { - ReplaceAllowList []string `mapstructure:"replace-allow-list"` - ReplaceLocal *bool `mapstructure:"replace-local"` - ExcludeForbidden *bool `mapstructure:"exclude-forbidden"` - RetractAllowNoExplanation *bool `mapstructure:"retract-allow-no-explanation"` - ToolchainForbidden *bool `mapstructure:"toolchain-forbidden"` - ToolchainPattern *string `mapstructure:"toolchain-pattern"` - ToolForbidden *bool `mapstructure:"tool-forbidden"` - GoDebugForbidden *bool `mapstructure:"go-debug-forbidden"` - GoVersionPattern *string `mapstructure:"go-version-pattern"` -} - -type GoModGuardSettings struct { - Allowed struct { - Modules []string `mapstructure:"modules"` - Domains []string `mapstructure:"domains"` - } `mapstructure:"allowed"` - Blocked struct { - Modules []map[string]struct { - Recommendations []string `mapstructure:"recommendations"` - Reason *string `mapstructure:"reason"` - } `mapstructure:"modules"` - Versions []map[string]struct { - Version *string `mapstructure:"version"` - Reason *string `mapstructure:"reason"` - } `mapstructure:"versions"` - LocalReplaceDirectives *bool `mapstructure:"local_replace_directives"` - } `mapstructure:"blocked"` -} - -type GoSecSettings struct { - Includes []string `mapstructure:"includes"` - Excludes []string `mapstructure:"excludes"` - Severity *string `mapstructure:"severity"` - Confidence *string `mapstructure:"confidence"` - ExcludeGenerated *bool `mapstructure:"exclude-generated"` - Config map[string]any `mapstructure:"config"` - Concurrency *int `mapstructure:"concurrency"` -} - -type GosmopolitanSettings struct { - AllowTimeLocal *bool `mapstructure:"allow-time-local"` - EscapeHatches []string `mapstructure:"escape-hatches"` - IgnoreTests *bool `mapstructure:"ignore-tests"` - WatchForScripts []string `mapstructure:"watch-for-scripts"` -} - -type GovetSettings struct { - Go *string `mapstructure:"-"` - - Enable []string `mapstructure:"enable"` - Disable []string `mapstructure:"disable"` - EnableAll *bool `mapstructure:"enable-all"` - DisableAll *bool `mapstructure:"disable-all"` - - Settings map[string]map[string]any `mapstructure:"settings"` - - // Deprecated: the linter should be enabled inside Enable. - CheckShadowing *bool `mapstructure:"check-shadowing"` -} - -type GrouperSettings struct { - ConstRequireSingleConst *bool `mapstructure:"const-require-single-const"` - ConstRequireGrouping *bool `mapstructure:"const-require-grouping"` - ImportRequireSingleImport *bool `mapstructure:"import-require-single-import"` - ImportRequireGrouping *bool `mapstructure:"import-require-grouping"` - TypeRequireSingleType *bool `mapstructure:"type-require-single-type"` - TypeRequireGrouping *bool `mapstructure:"type-require-grouping"` - VarRequireSingleVar *bool `mapstructure:"var-require-single-var"` - VarRequireGrouping *bool `mapstructure:"var-require-grouping"` -} - -type IfaceSettings struct { - Enable []string `mapstructure:"enable"` - Settings map[string]map[string]any `mapstructure:"settings"` -} - -type ImportAsSettings struct { - Alias []ImportAsAlias `mapstructure:"alias"` - NoUnaliased *bool `mapstructure:"no-unaliased"` - NoExtraAliases *bool `mapstructure:"no-extra-aliases"` -} - -type ImportAsAlias struct { - Pkg *string `mapstructure:"pkg"` - Alias *string `mapstructure:"alias"` -} - -type INamedParamSettings struct { - SkipSingleParam *bool `mapstructure:"skip-single-param"` -} - -type InterfaceBloatSettings struct { - Max *int `mapstructure:"max"` -} - -type IreturnSettings struct { - Allow []string `mapstructure:"allow"` - Reject []string `mapstructure:"reject"` -} - -type LllSettings struct { - LineLength *int `mapstructure:"line-length"` - TabWidth *int `mapstructure:"tab-width"` -} - -type LoggerCheckSettings struct { - Kitlog *bool `mapstructure:"kitlog"` - Klog *bool `mapstructure:"klog"` - Logr *bool `mapstructure:"logr"` - Slog *bool `mapstructure:"slog"` - Zap *bool `mapstructure:"zap"` - RequireStringKey *bool `mapstructure:"require-string-key"` - NoPrintfLike *bool `mapstructure:"no-printf-like"` - Rules []string `mapstructure:"rules"` -} - -type MaintIdxSettings struct { - Under *int `mapstructure:"under"` -} - -type MakezeroSettings struct { - Always *bool `mapstructure:"always"` -} - -type MisspellSettings struct { - Mode *string `mapstructure:"mode"` - Locale *string `mapstructure:"locale"` - ExtraWords []MisspellExtraWords `mapstructure:"extra-words"` - // TODO(ldez): v2 the option must be renamed to `IgnoredRules`. - IgnoreWords []string `mapstructure:"ignore-words"` -} - -type MisspellExtraWords struct { - Typo *string `mapstructure:"typo"` - Correction *string `mapstructure:"correction"` -} - -type MustTagSettings struct { - Functions []struct { - Name *string `mapstructure:"name"` - Tag *string `mapstructure:"tag"` - ArgPos *int `mapstructure:"arg-pos"` - } `mapstructure:"functions"` -} - -type NakedretSettings struct { - MaxFuncLines *uint `mapstructure:"max-func-lines"` -} - -type NestifSettings struct { - MinComplexity *int `mapstructure:"min-complexity"` -} - -type NilNilSettings struct { - DetectOpposite *bool `mapstructure:"detect-opposite"` - CheckedTypes []string `mapstructure:"checked-types"` -} - -type NlreturnSettings struct { - BlockSize *int `mapstructure:"block-size"` -} - -type MndSettings struct { - Checks []string `mapstructure:"checks"` - IgnoredNumbers []string `mapstructure:"ignored-numbers"` - IgnoredFiles []string `mapstructure:"ignored-files"` - IgnoredFunctions []string `mapstructure:"ignored-functions"` -} - -type NoLintLintSettings struct { - RequireExplanation *bool `mapstructure:"require-explanation"` - RequireSpecific *bool `mapstructure:"require-specific"` - AllowNoExplanation []string `mapstructure:"allow-no-explanation"` - AllowUnused *bool `mapstructure:"allow-unused"` -} - -type NoNamedReturnsSettings struct { - ReportErrorInDefer *bool `mapstructure:"report-error-in-defer"` -} - -type ParallelTestSettings struct { - Go *string `mapstructure:"-"` - IgnoreMissing *bool `mapstructure:"ignore-missing"` - IgnoreMissingSubtests *bool `mapstructure:"ignore-missing-subtests"` -} - -type PerfSprintSettings struct { - IntegerFormat *bool `mapstructure:"integer-format"` - IntConversion *bool `mapstructure:"int-conversion"` - - ErrorFormat *bool `mapstructure:"error-format"` - ErrError *bool `mapstructure:"err-error"` - ErrorF *bool `mapstructure:"errorf"` - - StringFormat *bool `mapstructure:"string-format"` - SprintF1 *bool `mapstructure:"sprintf1"` - StrConcat *bool `mapstructure:"strconcat"` - - BoolFormat *bool `mapstructure:"bool-format"` - HexFormat *bool `mapstructure:"hex-format"` -} - -type PreallocSettings struct { - Simple *bool `mapstructure:"simple"` - RangeLoops *bool `mapstructure:"range-loops"` - ForLoops *bool `mapstructure:"for-loops"` -} - -type PredeclaredSettings struct { - Ignore *string `mapstructure:"ignore"` - Qualified *bool `mapstructure:"q"` -} - -type PromlinterSettings struct { - Strict *bool `mapstructure:"strict"` - DisabledLinters []string `mapstructure:"disabled-linters"` -} - -type ProtoGetterSettings struct { - SkipGeneratedBy []string `mapstructure:"skip-generated-by"` - SkipFiles []string `mapstructure:"skip-files"` - SkipAnyGenerated *bool `mapstructure:"skip-any-generated"` - ReplaceFirstArgInAppend *bool `mapstructure:"replace-first-arg-in-append"` -} - -type ReassignSettings struct { - Patterns []string `mapstructure:"patterns"` -} - -type RecvcheckSettings struct { - DisableBuiltin *bool `mapstructure:"disable-builtin"` - Exclusions []string `mapstructure:"exclusions"` -} - -type ReviveSettings struct { - Go *string `mapstructure:"-"` - MaxOpenFiles *int `mapstructure:"max-open-files"` - IgnoreGeneratedHeader *bool `mapstructure:"ignore-generated-header"` - Confidence *float64 `mapstructure:"confidence"` - Severity *string `mapstructure:"severity"` - EnableAllRules *bool `mapstructure:"enable-all-rules"` - Rules []struct { - Name *string `mapstructure:"name"` - Arguments []any `mapstructure:"arguments"` - Severity *string `mapstructure:"severity"` - Disabled *bool `mapstructure:"disabled"` - Exclude []string `mapstructure:"exclude"` - } `mapstructure:"rules"` - ErrorCode *int `mapstructure:"error-code"` - WarningCode *int `mapstructure:"warning-code"` - Directives []struct { - Name *string `mapstructure:"name"` - Severity *string `mapstructure:"severity"` - } `mapstructure:"directives"` -} - -type RowsErrCheckSettings struct { - Packages []string `mapstructure:"packages"` -} - -type SlogLintSettings struct { - NoMixedArgs *bool `mapstructure:"no-mixed-args"` - KVOnly *bool `mapstructure:"kv-only"` - AttrOnly *bool `mapstructure:"attr-only"` - NoGlobal *string `mapstructure:"no-global"` - Context *string `mapstructure:"context"` - StaticMsg *bool `mapstructure:"static-msg"` - NoRawKeys *bool `mapstructure:"no-raw-keys"` - KeyNamingCase *string `mapstructure:"key-naming-case"` - ForbiddenKeys []string `mapstructure:"forbidden-keys"` - ArgsOnSepLines *bool `mapstructure:"args-on-sep-lines"` -} - -type SpancheckSettings struct { - Checks []string `mapstructure:"checks"` - IgnoreCheckSignatures []string `mapstructure:"ignore-check-signatures"` - ExtraStartSpanSignatures []string `mapstructure:"extra-start-span-signatures"` -} - -type StaticCheckSettings struct { - Checks []string `mapstructure:"checks"` - Initialisms []string `mapstructure:"initialisms"` // only for stylecheck - DotImportWhitelist []string `mapstructure:"dot-import-whitelist"` // only for stylecheck - HTTPStatusCodeWhitelist []string `mapstructure:"http-status-code-whitelist"` // only for stylecheck -} - -type TagAlignSettings struct { - Align *bool `mapstructure:"align"` - Sort *bool `mapstructure:"sort"` - Order []string `mapstructure:"order"` - Strict *bool `mapstructure:"strict"` -} - -type TagliatelleSettings struct { - Case TagliatelleCase `mapstructure:"case"` -} - -type TagliatelleCase struct { - TagliatelleBase `mapstructure:",squash"` - Overrides []TagliatelleOverrides `mapstructure:"overrides"` -} - -type TagliatelleOverrides struct { - TagliatelleBase `mapstructure:",squash"` - Package *string `mapstructure:"pkg"` - Ignore *bool `mapstructure:"ignore"` -} - -type TagliatelleBase struct { - Rules map[string]string `mapstructure:"rules"` - ExtendedRules map[string]TagliatelleExtendedRule `mapstructure:"extended-rules"` - UseFieldName *bool `mapstructure:"use-field-name"` - IgnoredFields []string `mapstructure:"ignored-fields"` -} - -type TagliatelleExtendedRule struct { - Case *string `mapstructure:"case"` - ExtraInitialisms *bool `mapstructure:"extra-initialisms"` - InitialismOverrides map[string]bool `mapstructure:"initialism-overrides"` -} - -type TestifylintSettings struct { - EnableAll *bool `mapstructure:"enable-all"` - DisableAll *bool `mapstructure:"disable-all"` - EnabledCheckers []string `mapstructure:"enable"` - DisabledCheckers []string `mapstructure:"disable"` - - BoolCompare struct { - IgnoreCustomTypes *bool `mapstructure:"ignore-custom-types"` - } `mapstructure:"bool-compare"` - - ExpectedActual struct { - ExpVarPattern *string `mapstructure:"pattern"` - } `mapstructure:"expected-actual"` - - Formatter struct { - CheckFormatString *bool `mapstructure:"check-format-string"` - RequireFFuncs *bool `mapstructure:"require-f-funcs"` - } `mapstructure:"formatter"` - - GoRequire struct { - IgnoreHTTPHandlers *bool `mapstructure:"ignore-http-handlers"` - } `mapstructure:"go-require"` - - RequireError struct { - FnPattern *string `mapstructure:"fn-pattern"` - } `mapstructure:"require-error"` - - SuiteExtraAssertCall struct { - Mode *string `mapstructure:"mode"` - } `mapstructure:"suite-extra-assert-call"` -} - -type TestpackageSettings struct { - SkipRegexp *string `mapstructure:"skip-regexp"` - AllowPackages []string `mapstructure:"allow-packages"` -} - -type ThelperSettings struct { - Test ThelperOptions `mapstructure:"test"` - Fuzz ThelperOptions `mapstructure:"fuzz"` - Benchmark ThelperOptions `mapstructure:"benchmark"` - TB ThelperOptions `mapstructure:"tb"` -} - -type ThelperOptions struct { - First *bool `mapstructure:"first"` - Name *bool `mapstructure:"name"` - Begin *bool `mapstructure:"begin"` -} - -type TenvSettings struct { - All *bool `mapstructure:"all"` -} - -type UseStdlibVarsSettings struct { - HTTPMethod *bool `mapstructure:"http-method"` - HTTPStatusCode *bool `mapstructure:"http-status-code"` - TimeWeekday *bool `mapstructure:"time-weekday"` - TimeMonth *bool `mapstructure:"time-month"` - TimeLayout *bool `mapstructure:"time-layout"` - CryptoHash *bool `mapstructure:"crypto-hash"` - DefaultRPCPath *bool `mapstructure:"default-rpc-path"` - SQLIsolationLevel *bool `mapstructure:"sql-isolation-level"` - TLSSignatureScheme *bool `mapstructure:"tls-signature-scheme"` - ConstantKind *bool `mapstructure:"constant-kind"` - - // Deprecated - OSDevNull *bool `mapstructure:"os-dev-null"` - // Deprecated - SyslogPriority *bool `mapstructure:"syslog-priority"` -} - -type UseTestingSettings struct { - ContextBackground *bool `mapstructure:"context-background"` - ContextTodo *bool `mapstructure:"context-todo"` - OSChdir *bool `mapstructure:"os-chdir"` - OSMkdirTemp *bool `mapstructure:"os-mkdir-temp"` - OSSetenv *bool `mapstructure:"os-setenv"` - OSTempDir *bool `mapstructure:"os-temp-dir"` - OSCreateTemp *bool `mapstructure:"os-create-temp"` -} - -type UnconvertSettings struct { - FastMath *bool `mapstructure:"fast-math"` - Safe *bool `mapstructure:"safe"` -} - -type UnparamSettings struct { - CheckExported *bool `mapstructure:"check-exported"` - Algo *string `mapstructure:"algo"` -} - -type UnusedSettings struct { - FieldWritesAreUses *bool `mapstructure:"field-writes-are-uses"` - PostStatementsAreReads *bool `mapstructure:"post-statements-are-reads"` - ExportedFieldsAreUsed *bool `mapstructure:"exported-fields-are-used"` - ParametersAreUsed *bool `mapstructure:"parameters-are-used"` - LocalVariablesAreUsed *bool `mapstructure:"local-variables-are-used"` - GeneratedIsUsed *bool `mapstructure:"generated-is-used"` - - // Deprecated - ExportedIsUsed *bool `mapstructure:"exported-is-used"` -} - -type VarnamelenSettings struct { - MaxDistance *int `mapstructure:"max-distance"` - MinNameLength *int `mapstructure:"min-name-length"` - CheckReceiver *bool `mapstructure:"check-receiver"` - CheckReturn *bool `mapstructure:"check-return"` - CheckTypeParam *bool `mapstructure:"check-type-param"` - IgnoreNames []string `mapstructure:"ignore-names"` - IgnoreTypeAssertOk *bool `mapstructure:"ignore-type-assert-ok"` - IgnoreMapIndexOk *bool `mapstructure:"ignore-map-index-ok"` - IgnoreChanRecvOk *bool `mapstructure:"ignore-chan-recv-ok"` - IgnoreDecls []string `mapstructure:"ignore-decls"` -} - -type WhitespaceSettings struct { - MultiIf *bool `mapstructure:"multi-if"` - MultiFunc *bool `mapstructure:"multi-func"` -} - -type WrapcheckSettings struct { - ExtraIgnoreSigs []string `mapstructure:"extra-ignore-sigs"` - // TODO(ldez): v2 the options must be renamed to use hyphen. - IgnoreSigs []string `mapstructure:"ignoreSigs"` - IgnoreSigRegexps []string `mapstructure:"ignoreSigRegexps"` - IgnorePackageGlobs []string `mapstructure:"ignorePackageGlobs"` - IgnoreInterfaceRegexps []string `mapstructure:"ignoreInterfaceRegexps"` -} - -type WSLSettings struct { - StrictAppend *bool `mapstructure:"strict-append"` - AllowAssignAndCallCuddle *bool `mapstructure:"allow-assign-and-call"` - AllowAssignAndAnythingCuddle *bool `mapstructure:"allow-assign-and-anything"` - AllowMultiLineAssignCuddle *bool `mapstructure:"allow-multiline-assign"` - ForceCaseTrailingWhitespaceLimit *int `mapstructure:"force-case-trailing-whitespace"` - AllowTrailingComment *bool `mapstructure:"allow-trailing-comment"` - AllowSeparatedLeadingComment *bool `mapstructure:"allow-separated-leading-comment"` - AllowCuddleDeclaration *bool `mapstructure:"allow-cuddle-declarations"` - AllowCuddleWithCalls []string `mapstructure:"allow-cuddle-with-calls"` - AllowCuddleWithRHS []string `mapstructure:"allow-cuddle-with-rhs"` - ForceCuddleErrCheckAndAssign *bool `mapstructure:"force-err-cuddling"` - ErrorVariableNames []string `mapstructure:"error-variable-names"` - ForceExclusiveShortDeclarations *bool `mapstructure:"force-short-decl-cuddling"` -} - -// CustomLinterSettings encapsulates the meta-data of a private linter. -type CustomLinterSettings struct { - // Type plugin type. - // It can be `goplugin` or `module`. - Type *string `mapstructure:"type"` - - // Path to a plugin *.so file that implements the private linter. - // Only for Go plugin system. - Path *string `mapstructure:"path"` - - // Description describes the purpose of the private linter. - Description *string `mapstructure:"description"` - // OriginalURL The URL containing the source code for the private linter. - OriginalURL *string `mapstructure:"original-url"` - - // Settings plugin settings only work with linterdb.PluginConstructor symbol. - Settings any `mapstructure:"settings"` -} - -type GciSettings struct { - Sections []string `mapstructure:"sections"` - NoInlineComments *bool `mapstructure:"no-inline-comments"` - NoPrefixComments *bool `mapstructure:"no-prefix-comments"` - SkipGenerated *bool `mapstructure:"skip-generated"` - CustomOrder *bool `mapstructure:"custom-order"` - NoLexOrder *bool `mapstructure:"no-lex-order"` - - // Deprecated: use Sections instead. - LocalPrefixes *string `mapstructure:"local-prefixes"` -} - -type GoFmtSettings struct { - Simplify *bool `mapstructure:"simplify"` - RewriteRules []GoFmtRewriteRule `mapstructure:"rewrite-rules"` -} - -type GoFmtRewriteRule struct { - Pattern *string `mapstructure:"pattern"` - Replacement *string `mapstructure:"replacement"` -} - -type GoFumptSettings struct { - ModulePath *string `mapstructure:"module-path"` - ExtraRules *bool `mapstructure:"extra-rules"` - - // Deprecated: use the global `run.go` instead. - LangVersion *string `mapstructure:"lang-version"` -} - -type GoImportsSettings struct { - LocalPrefixes *string `mapstructure:"local-prefixes"` -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/output.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/output.go deleted file mode 100644 index a3d86fc1d2..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/output.go +++ /dev/null @@ -1,37 +0,0 @@ -package versionone - -import ( - "strings" - - "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/ptr" -) - -type Output struct { - Formats OutputFormats `mapstructure:"formats"` - PrintIssuedLine *bool `mapstructure:"print-issued-lines"` - PrintLinterName *bool `mapstructure:"print-linter-name"` - SortResults *bool `mapstructure:"sort-results"` - SortOrder []string `mapstructure:"sort-order"` - PathPrefix *string `mapstructure:"path-prefix"` - ShowStats *bool `mapstructure:"show-stats"` -} - -type OutputFormat struct { - Format *string `mapstructure:"format"` - Path *string `mapstructure:"path"` -} - -type OutputFormats []OutputFormat - -func (p *OutputFormats) UnmarshalText(text []byte) error { - for item := range strings.SplitSeq(string(text), ",") { - format, path, _ := strings.Cut(item, ":") - - *p = append(*p, OutputFormat{ - Path: ptr.Pointer(path), - Format: ptr.Pointer(format), - }) - } - - return nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/run.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/run.go deleted file mode 100644 index db3e0edc93..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/run.go +++ /dev/null @@ -1,25 +0,0 @@ -package versionone - -import ( - "time" -) - -// Run encapsulates the config options for running the linter analysis. -type Run struct { - Timeout time.Duration `mapstructure:"timeout"` - - Concurrency *int `mapstructure:"concurrency"` - - Go *string `mapstructure:"go"` - - RelativePathMode *string `mapstructure:"relative-path-mode"` - - BuildTags []string `mapstructure:"build-tags"` - ModulesDownloadMode *string `mapstructure:"modules-download-mode"` - - ExitCodeIfIssuesFound *int `mapstructure:"issues-exit-code"` - AnalyzeTests *bool `mapstructure:"tests"` - - AllowParallelRunners *bool `mapstructure:"allow-parallel-runners"` - AllowSerialRunners *bool `mapstructure:"allow-serial-runners"` -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/severity.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/severity.go deleted file mode 100644 index b9d52e692d..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone/severity.go +++ /dev/null @@ -1,12 +0,0 @@ -package versionone - -type Severity struct { - Default *string `mapstructure:"default-severity"` - CaseSensitive *bool `mapstructure:"case-sensitive"` - Rules []SeverityRule `mapstructure:"rules"` -} - -type SeverityRule struct { - BaseRule `mapstructure:",squash"` - Severity *string `mapstructure:"severity"` -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/base_rule.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/base_rule.go deleted file mode 100644 index 469592dcc1..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/base_rule.go +++ /dev/null @@ -1,13 +0,0 @@ -// Code generated by pkg/commands/internal/migrate/cloner/cloner.go. DO NOT EDIT. - -package versiontwo - -type BaseRule struct { - Linters []string `yaml:"linters,omitempty" toml:"linters,multiline,omitempty"` - Path *string `yaml:"path,omitempty" toml:"path,multiline,omitempty"` - PathExcept *string `yaml:"path-except,omitempty" toml:"path-except,multiline,omitempty"` - Text *string `yaml:"text,omitempty" toml:"text,multiline,omitempty"` - Source *string `yaml:"source,omitempty" toml:"source,multiline,omitempty"` - - InternalReference *string `yaml:"-,omitempty" toml:"-,multiline,omitempty"` -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/config.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/config.go deleted file mode 100644 index 341b47b6c7..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/config.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by pkg/commands/internal/migrate/cloner/cloner.go. DO NOT EDIT. - -package versiontwo - -type Config struct { - Version *string `yaml:"version,omitempty" toml:"version,multiline,omitempty"` - - Run Run `yaml:"run,omitempty" toml:"run,multiline,omitempty"` - - Output Output `yaml:"output,omitempty" toml:"output,multiline,omitempty"` - - Linters Linters `yaml:"linters,omitempty" toml:"linters,multiline,omitempty"` - - Issues Issues `yaml:"issues,omitempty" toml:"issues,multiline,omitempty"` - Severity Severity `yaml:"severity,omitempty" toml:"severity,multiline,omitempty"` - - Formatters Formatters `yaml:"formatters,omitempty" toml:"formatters,multiline,omitempty"` -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/formatters.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/formatters.go deleted file mode 100644 index 417714947a..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/formatters.go +++ /dev/null @@ -1,15 +0,0 @@ -// Code generated by pkg/commands/internal/migrate/cloner/cloner.go. DO NOT EDIT. - -package versiontwo - -type Formatters struct { - Enable []string `yaml:"enable,omitempty" toml:"enable,multiline,omitempty"` - Settings FormatterSettings `yaml:"settings,omitempty" toml:"settings,multiline,omitempty"` - Exclusions FormatterExclusions `yaml:"exclusions,omitempty" toml:"exclusions,multiline,omitempty"` -} - -type FormatterExclusions struct { - Generated *string `yaml:"generated,omitempty" toml:"generated,multiline,omitempty"` - Paths []string `yaml:"paths,omitempty" toml:"paths,multiline,omitempty"` - WarnUnused *bool `yaml:"warn-unused,omitempty" toml:"warn-unused,multiline,omitempty"` -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/formatters_settings.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/formatters_settings.go deleted file mode 100644 index 878b2c4171..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/formatters_settings.go +++ /dev/null @@ -1,48 +0,0 @@ -// Code generated by pkg/commands/internal/migrate/cloner/cloner.go. DO NOT EDIT. - -package versiontwo - -type FormatterSettings struct { - Gci GciSettings `yaml:"gci,omitempty" toml:"gci,multiline,omitempty"` - GoFmt GoFmtSettings `yaml:"gofmt,omitempty" toml:"gofmt,multiline,omitempty"` - GoFumpt GoFumptSettings `yaml:"gofumpt,omitempty" toml:"gofumpt,multiline,omitempty"` - GoImports GoImportsSettings `yaml:"goimports,omitempty" toml:"goimports,multiline,omitempty"` - GoLines GoLinesSettings `yaml:"golines,omitempty" toml:"golines,multiline,omitempty"` -} - -type GciSettings struct { - Sections []string `yaml:"sections,omitempty" toml:"sections,multiline,omitempty"` - NoInlineComments *bool `yaml:"no-inline-comments,omitempty" toml:"no-inline-comments,multiline,omitempty"` - NoPrefixComments *bool `yaml:"no-prefix-comments,omitempty" toml:"no-prefix-comments,multiline,omitempty"` - CustomOrder *bool `yaml:"custom-order,omitempty" toml:"custom-order,multiline,omitempty"` - NoLexOrder *bool `yaml:"no-lex-order,omitempty" toml:"no-lex-order,multiline,omitempty"` -} - -type GoFmtSettings struct { - Simplify *bool `yaml:"simplify,omitempty" toml:"simplify,multiline,omitempty"` - RewriteRules []GoFmtRewriteRule `yaml:"rewrite-rules,omitempty" toml:"rewrite-rules,multiline,omitempty"` -} - -type GoFmtRewriteRule struct { - Pattern *string `yaml:"pattern,omitempty" toml:"pattern,multiline,omitempty"` - Replacement *string `yaml:"replacement,omitempty" toml:"replacement,multiline,omitempty"` -} - -type GoFumptSettings struct { - ModulePath *string `yaml:"module-path,omitempty" toml:"module-path,multiline,omitempty"` - ExtraRules *bool `yaml:"extra-rules,omitempty" toml:"extra-rules,multiline,omitempty"` - - LangVersion *string `yaml:"-,omitempty" toml:"-,multiline,omitempty"` -} - -type GoImportsSettings struct { - LocalPrefixes []string `yaml:"local-prefixes,omitempty" toml:"local-prefixes,multiline,omitempty"` -} - -type GoLinesSettings struct { - MaxLen *int `yaml:"max-len,omitempty" toml:"max-len,multiline,omitempty"` - TabLen *int `yaml:"tab-len,omitempty" toml:"tab-len,multiline,omitempty"` - ShortenComments *bool `yaml:"shorten-comments,omitempty" toml:"shorten-comments,multiline,omitempty"` - ReformatTags *bool `yaml:"reformat-tags,omitempty" toml:"reformat-tags,multiline,omitempty"` - ChainSplitDots *bool `yaml:"chain-split-dots,omitempty" toml:"chain-split-dots,multiline,omitempty"` -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/issues.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/issues.go deleted file mode 100644 index fa3b06ac5d..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/issues.go +++ /dev/null @@ -1,17 +0,0 @@ -// Code generated by pkg/commands/internal/migrate/cloner/cloner.go. DO NOT EDIT. - -package versiontwo - -type Issues struct { - MaxIssuesPerLinter *int `yaml:"max-issues-per-linter,omitempty" toml:"max-issues-per-linter,multiline,omitempty"` - MaxSameIssues *int `yaml:"max-same-issues,omitempty" toml:"max-same-issues,multiline,omitempty"` - UniqByLine *bool `yaml:"uniq-by-line,omitempty" toml:"uniq-by-line,multiline,omitempty"` - - DiffFromRevision *string `yaml:"new-from-rev,omitempty" toml:"new-from-rev,multiline,omitempty"` - DiffFromMergeBase *string `yaml:"new-from-merge-base,omitempty" toml:"new-from-merge-base,multiline,omitempty"` - DiffPatchFilePath *string `yaml:"new-from-patch,omitempty" toml:"new-from-patch,multiline,omitempty"` - WholeFiles *bool `yaml:"whole-files,omitempty" toml:"whole-files,multiline,omitempty"` - Diff *bool `yaml:"new,omitempty" toml:"new,multiline,omitempty"` - - NeedFix *bool `yaml:"fix,omitempty" toml:"fix,multiline,omitempty"` -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/linters.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/linters.go deleted file mode 100644 index 797313111d..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/linters.go +++ /dev/null @@ -1,14 +0,0 @@ -// Code generated by pkg/commands/internal/migrate/cloner/cloner.go. DO NOT EDIT. - -package versiontwo - -type Linters struct { - Default *string `yaml:"default,omitempty" toml:"default,multiline,omitempty"` - Enable []string `yaml:"enable,omitempty" toml:"enable,multiline,omitempty"` - Disable []string `yaml:"disable,omitempty" toml:"disable,multiline,omitempty"` - FastOnly *bool `yaml:"fast-only,omitempty" toml:"fast-only,multiline,omitempty"` - - Settings LintersSettings `yaml:"settings,omitempty" toml:"settings,multiline,omitempty"` - - Exclusions LinterExclusions `yaml:"exclusions,omitempty" toml:"exclusions,multiline,omitempty"` -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/linters_exclusions.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/linters_exclusions.go deleted file mode 100644 index d4ecb97204..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/linters_exclusions.go +++ /dev/null @@ -1,16 +0,0 @@ -// Code generated by pkg/commands/internal/migrate/cloner/cloner.go. DO NOT EDIT. - -package versiontwo - -type LinterExclusions struct { - Generated *string `yaml:"generated,omitempty" toml:"generated,multiline,omitempty"` - WarnUnused *bool `yaml:"warn-unused,omitempty" toml:"warn-unused,multiline,omitempty"` - Presets []string `yaml:"presets,omitempty" toml:"presets,multiline,omitempty"` - Rules []ExcludeRule `yaml:"rules,omitempty" toml:"rules,multiline,omitempty"` - Paths []string `yaml:"paths,omitempty" toml:"paths,multiline,omitempty"` - PathsExcept []string `yaml:"paths-except,omitempty" toml:"paths-except,multiline,omitempty"` -} - -type ExcludeRule struct { - BaseRule `yaml:",inline"` -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/linters_settings.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/linters_settings.go deleted file mode 100644 index be35d13903..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/linters_settings.go +++ /dev/null @@ -1,801 +0,0 @@ -// Code generated by pkg/commands/internal/migrate/cloner/cloner.go. DO NOT EDIT. - -package versiontwo - -type LintersSettings struct { - FormatterSettings `yaml:"-,omitempty" toml:"-,multiline,omitempty"` - - Asasalint AsasalintSettings `yaml:"asasalint,omitempty" toml:"asasalint,multiline,omitempty"` - BiDiChk BiDiChkSettings `yaml:"bidichk,omitempty" toml:"bidichk,multiline,omitempty"` - CopyLoopVar CopyLoopVarSettings `yaml:"copyloopvar,omitempty" toml:"copyloopvar,multiline,omitempty"` - Cyclop CyclopSettings `yaml:"cyclop,omitempty" toml:"cyclop,multiline,omitempty"` - Decorder DecorderSettings `yaml:"decorder,omitempty" toml:"decorder,multiline,omitempty"` - Depguard DepGuardSettings `yaml:"depguard,omitempty" toml:"depguard,multiline,omitempty"` - Dogsled DogsledSettings `yaml:"dogsled,omitempty" toml:"dogsled,multiline,omitempty"` - Dupl DuplSettings `yaml:"dupl,omitempty" toml:"dupl,multiline,omitempty"` - DupWord DupWordSettings `yaml:"dupword,omitempty" toml:"dupword,multiline,omitempty"` - EmbeddedStructFieldCheck EmbeddedStructFieldCheckSettings `yaml:"embeddedstructfieldcheck,omitempty" toml:"embeddedstructfieldcheck,multiline,omitempty"` - Errcheck ErrcheckSettings `yaml:"errcheck,omitempty" toml:"errcheck,multiline,omitempty"` - ErrChkJSON ErrChkJSONSettings `yaml:"errchkjson,omitempty" toml:"errchkjson,multiline,omitempty"` - ErrorLint ErrorLintSettings `yaml:"errorlint,omitempty" toml:"errorlint,multiline,omitempty"` - Exhaustive ExhaustiveSettings `yaml:"exhaustive,omitempty" toml:"exhaustive,multiline,omitempty"` - Exhaustruct ExhaustructSettings `yaml:"exhaustruct,omitempty" toml:"exhaustruct,multiline,omitempty"` - Fatcontext FatcontextSettings `yaml:"fatcontext,omitempty" toml:"fatcontext,multiline,omitempty"` - Forbidigo ForbidigoSettings `yaml:"forbidigo,omitempty" toml:"forbidigo,multiline,omitempty"` - FuncOrder FuncOrderSettings `yaml:"funcorder,omitempty" toml:"funcorder,multiline,omitempty"` - Funlen FunlenSettings `yaml:"funlen,omitempty" toml:"funlen,multiline,omitempty"` - GinkgoLinter GinkgoLinterSettings `yaml:"ginkgolinter,omitempty" toml:"ginkgolinter,multiline,omitempty"` - Gocognit GocognitSettings `yaml:"gocognit,omitempty" toml:"gocognit,multiline,omitempty"` - GoChecksumType GoChecksumTypeSettings `yaml:"gochecksumtype,omitempty" toml:"gochecksumtype,multiline,omitempty"` - Goconst GoConstSettings `yaml:"goconst,omitempty" toml:"goconst,multiline,omitempty"` - Gocritic GoCriticSettings `yaml:"gocritic,omitempty" toml:"gocritic,multiline,omitempty"` - Gocyclo GoCycloSettings `yaml:"gocyclo,omitempty" toml:"gocyclo,multiline,omitempty"` - Godot GodotSettings `yaml:"godot,omitempty" toml:"godot,multiline,omitempty"` - Godox GodoxSettings `yaml:"godox,omitempty" toml:"godox,multiline,omitempty"` - Goheader GoHeaderSettings `yaml:"goheader,omitempty" toml:"goheader,multiline,omitempty"` - GoModDirectives GoModDirectivesSettings `yaml:"gomoddirectives,omitempty" toml:"gomoddirectives,multiline,omitempty"` - Gomodguard GoModGuardSettings `yaml:"gomodguard,omitempty" toml:"gomodguard,multiline,omitempty"` - Gosec GoSecSettings `yaml:"gosec,omitempty" toml:"gosec,multiline,omitempty"` - Gosmopolitan GosmopolitanSettings `yaml:"gosmopolitan,omitempty" toml:"gosmopolitan,multiline,omitempty"` - Govet GovetSettings `yaml:"govet,omitempty" toml:"govet,multiline,omitempty"` - Grouper GrouperSettings `yaml:"grouper,omitempty" toml:"grouper,multiline,omitempty"` - Iface IfaceSettings `yaml:"iface,omitempty" toml:"iface,multiline,omitempty"` - ImportAs ImportAsSettings `yaml:"importas,omitempty" toml:"importas,multiline,omitempty"` - Inamedparam INamedParamSettings `yaml:"inamedparam,omitempty" toml:"inamedparam,multiline,omitempty"` - InterfaceBloat InterfaceBloatSettings `yaml:"interfacebloat,omitempty" toml:"interfacebloat,multiline,omitempty"` - Ireturn IreturnSettings `yaml:"ireturn,omitempty" toml:"ireturn,multiline,omitempty"` - Lll LllSettings `yaml:"lll,omitempty" toml:"lll,multiline,omitempty"` - LoggerCheck LoggerCheckSettings `yaml:"loggercheck,omitempty" toml:"loggercheck,multiline,omitempty"` - MaintIdx MaintIdxSettings `yaml:"maintidx,omitempty" toml:"maintidx,multiline,omitempty"` - Makezero MakezeroSettings `yaml:"makezero,omitempty" toml:"makezero,multiline,omitempty"` - Misspell MisspellSettings `yaml:"misspell,omitempty" toml:"misspell,multiline,omitempty"` - Mnd MndSettings `yaml:"mnd,omitempty" toml:"mnd,multiline,omitempty"` - MustTag MustTagSettings `yaml:"musttag,omitempty" toml:"musttag,multiline,omitempty"` - Nakedret NakedretSettings `yaml:"nakedret,omitempty" toml:"nakedret,multiline,omitempty"` - Nestif NestifSettings `yaml:"nestif,omitempty" toml:"nestif,multiline,omitempty"` - NilNil NilNilSettings `yaml:"nilnil,omitempty" toml:"nilnil,multiline,omitempty"` - Nlreturn NlreturnSettings `yaml:"nlreturn,omitempty" toml:"nlreturn,multiline,omitempty"` - NoLintLint NoLintLintSettings `yaml:"nolintlint,omitempty" toml:"nolintlint,multiline,omitempty"` - NoNamedReturns NoNamedReturnsSettings `yaml:"nonamedreturns,omitempty" toml:"nonamedreturns,multiline,omitempty"` - ParallelTest ParallelTestSettings `yaml:"paralleltest,omitempty" toml:"paralleltest,multiline,omitempty"` - PerfSprint PerfSprintSettings `yaml:"perfsprint,omitempty" toml:"perfsprint,multiline,omitempty"` - Prealloc PreallocSettings `yaml:"prealloc,omitempty" toml:"prealloc,multiline,omitempty"` - Predeclared PredeclaredSettings `yaml:"predeclared,omitempty" toml:"predeclared,multiline,omitempty"` - Promlinter PromlinterSettings `yaml:"promlinter,omitempty" toml:"promlinter,multiline,omitempty"` - ProtoGetter ProtoGetterSettings `yaml:"protogetter,omitempty" toml:"protogetter,multiline,omitempty"` - Reassign ReassignSettings `yaml:"reassign,omitempty" toml:"reassign,multiline,omitempty"` - Recvcheck RecvcheckSettings `yaml:"recvcheck,omitempty" toml:"recvcheck,multiline,omitempty"` - Revive ReviveSettings `yaml:"revive,omitempty" toml:"revive,multiline,omitempty"` - RowsErrCheck RowsErrCheckSettings `yaml:"rowserrcheck,omitempty" toml:"rowserrcheck,multiline,omitempty"` - SlogLint SlogLintSettings `yaml:"sloglint,omitempty" toml:"sloglint,multiline,omitempty"` - Spancheck SpancheckSettings `yaml:"spancheck,omitempty" toml:"spancheck,multiline,omitempty"` - Staticcheck StaticCheckSettings `yaml:"staticcheck,omitempty" toml:"staticcheck,multiline,omitempty"` - TagAlign TagAlignSettings `yaml:"tagalign,omitempty" toml:"tagalign,multiline,omitempty"` - Tagliatelle TagliatelleSettings `yaml:"tagliatelle,omitempty" toml:"tagliatelle,multiline,omitempty"` - Testifylint TestifylintSettings `yaml:"testifylint,omitempty" toml:"testifylint,multiline,omitempty"` - Testpackage TestpackageSettings `yaml:"testpackage,omitempty" toml:"testpackage,multiline,omitempty"` - Thelper ThelperSettings `yaml:"thelper,omitempty" toml:"thelper,multiline,omitempty"` - Unconvert UnconvertSettings `yaml:"unconvert,omitempty" toml:"unconvert,multiline,omitempty"` - Unparam UnparamSettings `yaml:"unparam,omitempty" toml:"unparam,multiline,omitempty"` - Unused UnusedSettings `yaml:"unused,omitempty" toml:"unused,multiline,omitempty"` - UseStdlibVars UseStdlibVarsSettings `yaml:"usestdlibvars,omitempty" toml:"usestdlibvars,multiline,omitempty"` - UseTesting UseTestingSettings `yaml:"usetesting,omitempty" toml:"usetesting,multiline,omitempty"` - Varnamelen VarnamelenSettings `yaml:"varnamelen,omitempty" toml:"varnamelen,multiline,omitempty"` - Whitespace WhitespaceSettings `yaml:"whitespace,omitempty" toml:"whitespace,multiline,omitempty"` - Wrapcheck WrapcheckSettings `yaml:"wrapcheck,omitempty" toml:"wrapcheck,multiline,omitempty"` - WSL WSLv4Settings `yaml:"wsl,omitempty" toml:"wsl,multiline,omitempty"` - WSLv5 WSLv5Settings `yaml:"wsl_v5,omitempty" toml:"wsl_v5,multiline,omitempty"` - - Custom map[string]CustomLinterSettings `yaml:"custom,omitempty" toml:"custom,multiline,omitempty"` -} - -type AsasalintSettings struct { - Exclude []string `yaml:"exclude,omitempty" toml:"exclude,multiline,omitempty"` - UseBuiltinExclusions *bool `yaml:"use-builtin-exclusions,omitempty" toml:"use-builtin-exclusions,multiline,omitempty"` -} - -type BiDiChkSettings struct { - LeftToRightEmbedding *bool `yaml:"left-to-right-embedding,omitempty" toml:"left-to-right-embedding,multiline,omitempty"` - RightToLeftEmbedding *bool `yaml:"right-to-left-embedding,omitempty" toml:"right-to-left-embedding,multiline,omitempty"` - PopDirectionalFormatting *bool `yaml:"pop-directional-formatting,omitempty" toml:"pop-directional-formatting,multiline,omitempty"` - LeftToRightOverride *bool `yaml:"left-to-right-override,omitempty" toml:"left-to-right-override,multiline,omitempty"` - RightToLeftOverride *bool `yaml:"right-to-left-override,omitempty" toml:"right-to-left-override,multiline,omitempty"` - LeftToRightIsolate *bool `yaml:"left-to-right-isolate,omitempty" toml:"left-to-right-isolate,multiline,omitempty"` - RightToLeftIsolate *bool `yaml:"right-to-left-isolate,omitempty" toml:"right-to-left-isolate,multiline,omitempty"` - FirstStrongIsolate *bool `yaml:"first-strong-isolate,omitempty" toml:"first-strong-isolate,multiline,omitempty"` - PopDirectionalIsolate *bool `yaml:"pop-directional-isolate,omitempty" toml:"pop-directional-isolate,multiline,omitempty"` -} - -type CopyLoopVarSettings struct { - CheckAlias *bool `yaml:"check-alias,omitempty" toml:"check-alias,multiline,omitempty"` -} - -type CyclopSettings struct { - MaxComplexity *int `yaml:"max-complexity,omitempty" toml:"max-complexity,multiline,omitempty"` - PackageAverage *float64 `yaml:"package-average,omitempty" toml:"package-average,multiline,omitempty"` -} - -type DepGuardSettings struct { - Rules map[string]*DepGuardList `yaml:"rules,omitempty" toml:"rules,multiline,omitempty"` -} - -type DepGuardList struct { - ListMode *string `yaml:"list-mode,omitempty" toml:"list-mode,multiline,omitempty"` - Files []string `yaml:"files,omitempty" toml:"files,multiline,omitempty"` - Allow []string `yaml:"allow,omitempty" toml:"allow,multiline,omitempty"` - Deny []DepGuardDeny `yaml:"deny,omitempty" toml:"deny,multiline,omitempty"` -} - -type DepGuardDeny struct { - Pkg *string `yaml:"pkg,omitempty" toml:"pkg,multiline,omitempty"` - Desc *string `yaml:"desc,omitempty" toml:"desc,multiline,omitempty"` -} - -type DecorderSettings struct { - DecOrder []string `yaml:"dec-order,omitempty" toml:"dec-order,multiline,omitempty"` - IgnoreUnderscoreVars *bool `yaml:"ignore-underscore-vars,omitempty" toml:"ignore-underscore-vars,multiline,omitempty"` - DisableDecNumCheck *bool `yaml:"disable-dec-num-check,omitempty" toml:"disable-dec-num-check,multiline,omitempty"` - DisableTypeDecNumCheck *bool `yaml:"disable-type-dec-num-check,omitempty" toml:"disable-type-dec-num-check,multiline,omitempty"` - DisableConstDecNumCheck *bool `yaml:"disable-const-dec-num-check,omitempty" toml:"disable-const-dec-num-check,multiline,omitempty"` - DisableVarDecNumCheck *bool `yaml:"disable-var-dec-num-check,omitempty" toml:"disable-var-dec-num-check,multiline,omitempty"` - DisableDecOrderCheck *bool `yaml:"disable-dec-order-check,omitempty" toml:"disable-dec-order-check,multiline,omitempty"` - DisableInitFuncFirstCheck *bool `yaml:"disable-init-func-first-check,omitempty" toml:"disable-init-func-first-check,multiline,omitempty"` -} - -type DogsledSettings struct { - MaxBlankIdentifiers *int `yaml:"max-blank-identifiers,omitempty" toml:"max-blank-identifiers,multiline,omitempty"` -} - -type DuplSettings struct { - Threshold *int `yaml:"threshold,omitempty" toml:"threshold,multiline,omitempty"` -} - -type DupWordSettings struct { - Keywords []string `yaml:"keywords,omitempty" toml:"keywords,multiline,omitempty"` - Ignore []string `yaml:"ignore,omitempty" toml:"ignore,multiline,omitempty"` -} - -type EmbeddedStructFieldCheckSettings struct { - ForbidMutex *bool `yaml:"forbid-mutex,omitempty" toml:"forbid-mutex,multiline,omitempty"` -} - -type ErrcheckSettings struct { - DisableDefaultExclusions *bool `yaml:"disable-default-exclusions,omitempty" toml:"disable-default-exclusions,multiline,omitempty"` - CheckTypeAssertions *bool `yaml:"check-type-assertions,omitempty" toml:"check-type-assertions,multiline,omitempty"` - CheckAssignToBlank *bool `yaml:"check-blank,omitempty" toml:"check-blank,multiline,omitempty"` - ExcludeFunctions []string `yaml:"exclude-functions,omitempty" toml:"exclude-functions,multiline,omitempty"` - Verbose *bool `yaml:"verbose,omitempty" toml:"verbose,multiline,omitempty"` -} - -type ErrChkJSONSettings struct { - CheckErrorFreeEncoding *bool `yaml:"check-error-free-encoding,omitempty" toml:"check-error-free-encoding,multiline,omitempty"` - ReportNoExported *bool `yaml:"report-no-exported,omitempty" toml:"report-no-exported,multiline,omitempty"` -} - -type ErrorLintSettings struct { - Errorf *bool `yaml:"errorf,omitempty" toml:"errorf,multiline,omitempty"` - ErrorfMulti *bool `yaml:"errorf-multi,omitempty" toml:"errorf-multi,multiline,omitempty"` - Asserts *bool `yaml:"asserts,omitempty" toml:"asserts,multiline,omitempty"` - Comparison *bool `yaml:"comparison,omitempty" toml:"comparison,multiline,omitempty"` - AllowedErrors []ErrorLintAllowPair `yaml:"allowed-errors,omitempty" toml:"allowed-errors,multiline,omitempty"` - AllowedErrorsWildcard []ErrorLintAllowPair `yaml:"allowed-errors-wildcard,omitempty" toml:"allowed-errors-wildcard,multiline,omitempty"` -} - -type ErrorLintAllowPair struct { - Err *string `yaml:"err,omitempty" toml:"err,multiline,omitempty"` - Fun *string `yaml:"fun,omitempty" toml:"fun,multiline,omitempty"` -} - -type ExhaustiveSettings struct { - Check []string `yaml:"check,omitempty" toml:"check,multiline,omitempty"` - DefaultSignifiesExhaustive *bool `yaml:"default-signifies-exhaustive,omitempty" toml:"default-signifies-exhaustive,multiline,omitempty"` - IgnoreEnumMembers *string `yaml:"ignore-enum-members,omitempty" toml:"ignore-enum-members,multiline,omitempty"` - IgnoreEnumTypes *string `yaml:"ignore-enum-types,omitempty" toml:"ignore-enum-types,multiline,omitempty"` - PackageScopeOnly *bool `yaml:"package-scope-only,omitempty" toml:"package-scope-only,multiline,omitempty"` - ExplicitExhaustiveMap *bool `yaml:"explicit-exhaustive-map,omitempty" toml:"explicit-exhaustive-map,multiline,omitempty"` - ExplicitExhaustiveSwitch *bool `yaml:"explicit-exhaustive-switch,omitempty" toml:"explicit-exhaustive-switch,multiline,omitempty"` - DefaultCaseRequired *bool `yaml:"default-case-required,omitempty" toml:"default-case-required,multiline,omitempty"` -} - -type ExhaustructSettings struct { - Include []string `yaml:"include,omitempty" toml:"include,multiline,omitempty"` - Exclude []string `yaml:"exclude,omitempty" toml:"exclude,multiline,omitempty"` -} - -type FatcontextSettings struct { - CheckStructPointers *bool `yaml:"check-struct-pointers,omitempty" toml:"check-struct-pointers,multiline,omitempty"` -} - -type ForbidigoSettings struct { - Forbid []ForbidigoPattern `yaml:"forbid,omitempty" toml:"forbid,multiline,omitempty"` - ExcludeGodocExamples *bool `yaml:"exclude-godoc-examples,omitempty" toml:"exclude-godoc-examples,multiline,omitempty"` - AnalyzeTypes *bool `yaml:"analyze-types,omitempty" toml:"analyze-types,multiline,omitempty"` -} - -type ForbidigoPattern struct { - Pattern *string `yaml:"pattern,omitempty" toml:"pattern,multiline,omitempty"` - Package *string `yaml:"pkg,omitempty,omitempty" toml:"pkg,omitempty,multiline,omitempty"` - Msg *string `yaml:"msg,omitempty,omitempty" toml:"msg,omitempty,multiline,omitempty"` -} - -type FuncOrderSettings struct { - Constructor *bool `yaml:"constructor,omitempty,omitempty" toml:"constructor,omitempty,multiline,omitempty"` - StructMethod *bool `yaml:"struct-method,omitempty,omitempty" toml:"struct-method,omitempty,multiline,omitempty"` - Alphabetical *bool `yaml:"alphabetical,omitempty,omitempty" toml:"alphabetical,omitempty,multiline,omitempty"` -} - -type FunlenSettings struct { - Lines *int `yaml:"lines,omitempty" toml:"lines,multiline,omitempty"` - Statements *int `yaml:"statements,omitempty" toml:"statements,multiline,omitempty"` - IgnoreComments *bool `yaml:"ignore-comments,omitempty" toml:"ignore-comments,multiline,omitempty"` -} - -type GinkgoLinterSettings struct { - SuppressLenAssertion *bool `yaml:"suppress-len-assertion,omitempty" toml:"suppress-len-assertion,multiline,omitempty"` - SuppressNilAssertion *bool `yaml:"suppress-nil-assertion,omitempty" toml:"suppress-nil-assertion,multiline,omitempty"` - SuppressErrAssertion *bool `yaml:"suppress-err-assertion,omitempty" toml:"suppress-err-assertion,multiline,omitempty"` - SuppressCompareAssertion *bool `yaml:"suppress-compare-assertion,omitempty" toml:"suppress-compare-assertion,multiline,omitempty"` - SuppressAsyncAssertion *bool `yaml:"suppress-async-assertion,omitempty" toml:"suppress-async-assertion,multiline,omitempty"` - SuppressTypeCompareWarning *bool `yaml:"suppress-type-compare-assertion,omitempty" toml:"suppress-type-compare-assertion,multiline,omitempty"` - ForbidFocusContainer *bool `yaml:"forbid-focus-container,omitempty" toml:"forbid-focus-container,multiline,omitempty"` - AllowHaveLenZero *bool `yaml:"allow-havelen-zero,omitempty" toml:"allow-havelen-zero,multiline,omitempty"` - ForceExpectTo *bool `yaml:"force-expect-to,omitempty" toml:"force-expect-to,multiline,omitempty"` - ValidateAsyncIntervals *bool `yaml:"validate-async-intervals,omitempty" toml:"validate-async-intervals,multiline,omitempty"` - ForbidSpecPollution *bool `yaml:"forbid-spec-pollution,omitempty" toml:"forbid-spec-pollution,multiline,omitempty"` - ForceSucceedForFuncs *bool `yaml:"force-succeed,omitempty" toml:"force-succeed,multiline,omitempty"` -} - -type GoChecksumTypeSettings struct { - DefaultSignifiesExhaustive *bool `yaml:"default-signifies-exhaustive,omitempty" toml:"default-signifies-exhaustive,multiline,omitempty"` - IncludeSharedInterfaces *bool `yaml:"include-shared-interfaces,omitempty" toml:"include-shared-interfaces,multiline,omitempty"` -} - -type GocognitSettings struct { - MinComplexity *int `yaml:"min-complexity,omitempty" toml:"min-complexity,multiline,omitempty"` -} - -type GoConstSettings struct { - IgnoreStringValues []string `yaml:"ignore-string-values,omitempty" toml:"ignore-string-values,multiline,omitempty"` - MatchWithConstants *bool `yaml:"match-constant,omitempty" toml:"match-constant,multiline,omitempty"` - MinStringLen *int `yaml:"min-len,omitempty" toml:"min-len,multiline,omitempty"` - MinOccurrencesCount *int `yaml:"min-occurrences,omitempty" toml:"min-occurrences,multiline,omitempty"` - ParseNumbers *bool `yaml:"numbers,omitempty" toml:"numbers,multiline,omitempty"` - NumberMin *int `yaml:"min,omitempty" toml:"min,multiline,omitempty"` - NumberMax *int `yaml:"max,omitempty" toml:"max,multiline,omitempty"` - IgnoreCalls *bool `yaml:"ignore-calls,omitempty" toml:"ignore-calls,multiline,omitempty"` - FindDuplicates *bool `yaml:"find-duplicates,omitempty" toml:"find-duplicates,multiline,omitempty"` - EvalConstExpressions *bool `yaml:"eval-const-expressions,omitempty" toml:"eval-const-expressions,multiline,omitempty"` - - IgnoreStrings *string `yaml:"ignore-strings,omitempty" toml:"ignore-strings,multiline,omitempty"` -} - -type GoCriticSettings struct { - Go *string `yaml:"-,omitempty" toml:"-,multiline,omitempty"` - DisableAll *bool `yaml:"disable-all,omitempty" toml:"disable-all,multiline,omitempty"` - EnabledChecks []string `yaml:"enabled-checks,omitempty" toml:"enabled-checks,multiline,omitempty"` - EnableAll *bool `yaml:"enable-all,omitempty" toml:"enable-all,multiline,omitempty"` - DisabledChecks []string `yaml:"disabled-checks,omitempty" toml:"disabled-checks,multiline,omitempty"` - EnabledTags []string `yaml:"enabled-tags,omitempty" toml:"enabled-tags,multiline,omitempty"` - DisabledTags []string `yaml:"disabled-tags,omitempty" toml:"disabled-tags,multiline,omitempty"` - SettingsPerCheck map[string]GoCriticCheckSettings `yaml:"settings,omitempty" toml:"settings,multiline,omitempty"` -} - -type GoCriticCheckSettings map[string]any - -type GoCycloSettings struct { - MinComplexity *int `yaml:"min-complexity,omitempty" toml:"min-complexity,multiline,omitempty"` -} - -type GodotSettings struct { - Scope *string `yaml:"scope,omitempty" toml:"scope,multiline,omitempty"` - Exclude []string `yaml:"exclude,omitempty" toml:"exclude,multiline,omitempty"` - Capital *bool `yaml:"capital,omitempty" toml:"capital,multiline,omitempty"` - Period *bool `yaml:"period,omitempty" toml:"period,multiline,omitempty"` -} - -type GodoxSettings struct { - Keywords []string `yaml:"keywords,omitempty" toml:"keywords,multiline,omitempty"` -} - -type GoHeaderSettings struct { - Values map[string]map[string]string `yaml:"values,omitempty" toml:"values,multiline,omitempty"` - Template *string `yaml:"template,omitempty" toml:"template,multiline,omitempty"` - TemplatePath *string `yaml:"template-path,omitempty" toml:"template-path,multiline,omitempty"` -} - -type GoModDirectivesSettings struct { - ReplaceAllowList []string `yaml:"replace-allow-list,omitempty" toml:"replace-allow-list,multiline,omitempty"` - ReplaceLocal *bool `yaml:"replace-local,omitempty" toml:"replace-local,multiline,omitempty"` - ExcludeForbidden *bool `yaml:"exclude-forbidden,omitempty" toml:"exclude-forbidden,multiline,omitempty"` - RetractAllowNoExplanation *bool `yaml:"retract-allow-no-explanation,omitempty" toml:"retract-allow-no-explanation,multiline,omitempty"` - ToolchainForbidden *bool `yaml:"toolchain-forbidden,omitempty" toml:"toolchain-forbidden,multiline,omitempty"` - ToolchainPattern *string `yaml:"toolchain-pattern,omitempty" toml:"toolchain-pattern,multiline,omitempty"` - ToolForbidden *bool `yaml:"tool-forbidden,omitempty" toml:"tool-forbidden,multiline,omitempty"` - GoDebugForbidden *bool `yaml:"go-debug-forbidden,omitempty" toml:"go-debug-forbidden,multiline,omitempty"` - GoVersionPattern *string `yaml:"go-version-pattern,omitempty" toml:"go-version-pattern,multiline,omitempty"` -} - -type GoModGuardSettings struct { - Allowed GoModGuardAllowed `yaml:"allowed,omitempty" toml:"allowed,multiline,omitempty"` - Blocked GoModGuardBlocked `yaml:"blocked,omitempty" toml:"blocked,multiline,omitempty"` -} - -type GoModGuardAllowed struct { - Modules []string `yaml:"modules,omitempty" toml:"modules,multiline,omitempty"` - Domains []string `yaml:"domains,omitempty" toml:"domains,multiline,omitempty"` -} - -type GoModGuardBlocked struct { - Modules []map[string]GoModGuardModule `yaml:"modules,omitempty" toml:"modules,multiline,omitempty"` - Versions []map[string]GoModGuardVersion `yaml:"versions,omitempty" toml:"versions,multiline,omitempty"` - LocalReplaceDirectives *bool `yaml:"local-replace-directives,omitempty" toml:"local-replace-directives,multiline,omitempty"` -} - -type GoModGuardModule struct { - Recommendations []string `yaml:"recommendations,omitempty" toml:"recommendations,multiline,omitempty"` - Reason *string `yaml:"reason,omitempty" toml:"reason,multiline,omitempty"` -} - -type GoModGuardVersion struct { - Version *string `yaml:"version,omitempty" toml:"version,multiline,omitempty"` - Reason *string `yaml:"reason,omitempty" toml:"reason,multiline,omitempty"` -} - -type GoSecSettings struct { - Includes []string `yaml:"includes,omitempty" toml:"includes,multiline,omitempty"` - Excludes []string `yaml:"excludes,omitempty" toml:"excludes,multiline,omitempty"` - Severity *string `yaml:"severity,omitempty" toml:"severity,multiline,omitempty"` - Confidence *string `yaml:"confidence,omitempty" toml:"confidence,multiline,omitempty"` - Config map[string]any `yaml:"config,omitempty" toml:"config,multiline,omitempty"` - Concurrency *int `yaml:"concurrency,omitempty" toml:"concurrency,multiline,omitempty"` -} - -type GosmopolitanSettings struct { - AllowTimeLocal *bool `yaml:"allow-time-local,omitempty" toml:"allow-time-local,multiline,omitempty"` - EscapeHatches []string `yaml:"escape-hatches,omitempty" toml:"escape-hatches,multiline,omitempty"` - WatchForScripts []string `yaml:"watch-for-scripts,omitempty" toml:"watch-for-scripts,multiline,omitempty"` -} - -type GovetSettings struct { - Go *string `yaml:"-,omitempty" toml:"-,multiline,omitempty"` - - Enable []string `yaml:"enable,omitempty" toml:"enable,multiline,omitempty"` - Disable []string `yaml:"disable,omitempty" toml:"disable,multiline,omitempty"` - EnableAll *bool `yaml:"enable-all,omitempty" toml:"enable-all,multiline,omitempty"` - DisableAll *bool `yaml:"disable-all,omitempty" toml:"disable-all,multiline,omitempty"` - - Settings map[string]map[string]any `yaml:"settings,omitempty" toml:"settings,multiline,omitempty"` -} - -type GrouperSettings struct { - ConstRequireSingleConst *bool `yaml:"const-require-single-const,omitempty" toml:"const-require-single-const,multiline,omitempty"` - ConstRequireGrouping *bool `yaml:"const-require-grouping,omitempty" toml:"const-require-grouping,multiline,omitempty"` - ImportRequireSingleImport *bool `yaml:"import-require-single-import,omitempty" toml:"import-require-single-import,multiline,omitempty"` - ImportRequireGrouping *bool `yaml:"import-require-grouping,omitempty" toml:"import-require-grouping,multiline,omitempty"` - TypeRequireSingleType *bool `yaml:"type-require-single-type,omitempty" toml:"type-require-single-type,multiline,omitempty"` - TypeRequireGrouping *bool `yaml:"type-require-grouping,omitempty" toml:"type-require-grouping,multiline,omitempty"` - VarRequireSingleVar *bool `yaml:"var-require-single-var,omitempty" toml:"var-require-single-var,multiline,omitempty"` - VarRequireGrouping *bool `yaml:"var-require-grouping,omitempty" toml:"var-require-grouping,multiline,omitempty"` -} - -type IfaceSettings struct { - Enable []string `yaml:"enable,omitempty" toml:"enable,multiline,omitempty"` - Settings map[string]map[string]any `yaml:"settings,omitempty" toml:"settings,multiline,omitempty"` -} - -type ImportAsSettings struct { - Alias []ImportAsAlias `yaml:"alias,omitempty" toml:"alias,multiline,omitempty"` - NoUnaliased *bool `yaml:"no-unaliased,omitempty" toml:"no-unaliased,multiline,omitempty"` - NoExtraAliases *bool `yaml:"no-extra-aliases,omitempty" toml:"no-extra-aliases,multiline,omitempty"` -} - -type ImportAsAlias struct { - Pkg *string `yaml:"pkg,omitempty" toml:"pkg,multiline,omitempty"` - Alias *string `yaml:"alias,omitempty" toml:"alias,multiline,omitempty"` -} - -type INamedParamSettings struct { - SkipSingleParam *bool `yaml:"skip-single-param,omitempty" toml:"skip-single-param,multiline,omitempty"` -} - -type InterfaceBloatSettings struct { - Max *int `yaml:"max,omitempty" toml:"max,multiline,omitempty"` -} - -type IreturnSettings struct { - Allow []string `yaml:"allow,omitempty" toml:"allow,multiline,omitempty"` - Reject []string `yaml:"reject,omitempty" toml:"reject,multiline,omitempty"` -} - -type LllSettings struct { - LineLength *int `yaml:"line-length,omitempty" toml:"line-length,multiline,omitempty"` - TabWidth *int `yaml:"tab-width,omitempty" toml:"tab-width,multiline,omitempty"` -} - -type LoggerCheckSettings struct { - Kitlog *bool `yaml:"kitlog,omitempty" toml:"kitlog,multiline,omitempty"` - Klog *bool `yaml:"klog,omitempty" toml:"klog,multiline,omitempty"` - Logr *bool `yaml:"logr,omitempty" toml:"logr,multiline,omitempty"` - Slog *bool `yaml:"slog,omitempty" toml:"slog,multiline,omitempty"` - Zap *bool `yaml:"zap,omitempty" toml:"zap,multiline,omitempty"` - RequireStringKey *bool `yaml:"require-string-key,omitempty" toml:"require-string-key,multiline,omitempty"` - NoPrintfLike *bool `yaml:"no-printf-like,omitempty" toml:"no-printf-like,multiline,omitempty"` - Rules []string `yaml:"rules,omitempty" toml:"rules,multiline,omitempty"` -} - -type MaintIdxSettings struct { - Under *int `yaml:"under,omitempty" toml:"under,multiline,omitempty"` -} - -type MakezeroSettings struct { - Always *bool `yaml:"always,omitempty" toml:"always,multiline,omitempty"` -} - -type MisspellSettings struct { - Mode *string `yaml:"mode,omitempty" toml:"mode,multiline,omitempty"` - Locale *string `yaml:"locale,omitempty" toml:"locale,multiline,omitempty"` - ExtraWords []MisspellExtraWords `yaml:"extra-words,omitempty" toml:"extra-words,multiline,omitempty"` - IgnoreRules []string `yaml:"ignore-rules,omitempty" toml:"ignore-rules,multiline,omitempty"` -} - -type MisspellExtraWords struct { - Typo *string `yaml:"typo,omitempty" toml:"typo,multiline,omitempty"` - Correction *string `yaml:"correction,omitempty" toml:"correction,multiline,omitempty"` -} - -type MustTagSettings struct { - Functions []MustTagFunction `yaml:"functions,omitempty" toml:"functions,multiline,omitempty"` -} - -type MustTagFunction struct { - Name *string `yaml:"name,omitempty" toml:"name,multiline,omitempty"` - Tag *string `yaml:"tag,omitempty" toml:"tag,multiline,omitempty"` - ArgPos *int `yaml:"arg-pos,omitempty" toml:"arg-pos,multiline,omitempty"` -} - -type NakedretSettings struct { - MaxFuncLines *uint `yaml:"max-func-lines,omitempty" toml:"max-func-lines,multiline,omitempty"` -} - -type NestifSettings struct { - MinComplexity *int `yaml:"min-complexity,omitempty" toml:"min-complexity,multiline,omitempty"` -} - -type NilNilSettings struct { - OnlyTwo *bool `yaml:"only-two,omitempty" toml:"only-two,multiline,omitempty"` - DetectOpposite *bool `yaml:"detect-opposite,omitempty" toml:"detect-opposite,multiline,omitempty"` - CheckedTypes []string `yaml:"checked-types,omitempty" toml:"checked-types,multiline,omitempty"` -} - -type NlreturnSettings struct { - BlockSize *int `yaml:"block-size,omitempty" toml:"block-size,multiline,omitempty"` -} - -type MndSettings struct { - Checks []string `yaml:"checks,omitempty" toml:"checks,multiline,omitempty"` - IgnoredNumbers []string `yaml:"ignored-numbers,omitempty" toml:"ignored-numbers,multiline,omitempty"` - IgnoredFiles []string `yaml:"ignored-files,omitempty" toml:"ignored-files,multiline,omitempty"` - IgnoredFunctions []string `yaml:"ignored-functions,omitempty" toml:"ignored-functions,multiline,omitempty"` -} - -type NoLintLintSettings struct { - RequireExplanation *bool `yaml:"require-explanation,omitempty" toml:"require-explanation,multiline,omitempty"` - RequireSpecific *bool `yaml:"require-specific,omitempty" toml:"require-specific,multiline,omitempty"` - AllowNoExplanation []string `yaml:"allow-no-explanation,omitempty" toml:"allow-no-explanation,multiline,omitempty"` - AllowUnused *bool `yaml:"allow-unused,omitempty" toml:"allow-unused,multiline,omitempty"` -} - -type NoNamedReturnsSettings struct { - ReportErrorInDefer *bool `yaml:"report-error-in-defer,omitempty" toml:"report-error-in-defer,multiline,omitempty"` -} - -type ParallelTestSettings struct { - Go *string `yaml:"-,omitempty" toml:"-,multiline,omitempty"` - IgnoreMissing *bool `yaml:"ignore-missing,omitempty" toml:"ignore-missing,multiline,omitempty"` - IgnoreMissingSubtests *bool `yaml:"ignore-missing-subtests,omitempty" toml:"ignore-missing-subtests,multiline,omitempty"` -} - -type PerfSprintSettings struct { - IntegerFormat *bool `yaml:"integer-format,omitempty" toml:"integer-format,multiline,omitempty"` - IntConversion *bool `yaml:"int-conversion,omitempty" toml:"int-conversion,multiline,omitempty"` - - ErrorFormat *bool `yaml:"error-format,omitempty" toml:"error-format,multiline,omitempty"` - ErrError *bool `yaml:"err-error,omitempty" toml:"err-error,multiline,omitempty"` - ErrorF *bool `yaml:"errorf,omitempty" toml:"errorf,multiline,omitempty"` - - StringFormat *bool `yaml:"string-format,omitempty" toml:"string-format,multiline,omitempty"` - SprintF1 *bool `yaml:"sprintf1,omitempty" toml:"sprintf1,multiline,omitempty"` - StrConcat *bool `yaml:"strconcat,omitempty" toml:"strconcat,multiline,omitempty"` - - BoolFormat *bool `yaml:"bool-format,omitempty" toml:"bool-format,multiline,omitempty"` - HexFormat *bool `yaml:"hex-format,omitempty" toml:"hex-format,multiline,omitempty"` -} - -type PreallocSettings struct { - Simple *bool `yaml:"simple,omitempty" toml:"simple,multiline,omitempty"` - RangeLoops *bool `yaml:"range-loops,omitempty" toml:"range-loops,multiline,omitempty"` - ForLoops *bool `yaml:"for-loops,omitempty" toml:"for-loops,multiline,omitempty"` -} - -type PredeclaredSettings struct { - Ignore []string `yaml:"ignore,omitempty" toml:"ignore,multiline,omitempty"` - Qualified *bool `yaml:"qualified-name,omitempty" toml:"qualified-name,multiline,omitempty"` -} - -type PromlinterSettings struct { - Strict *bool `yaml:"strict,omitempty" toml:"strict,multiline,omitempty"` - DisabledLinters []string `yaml:"disabled-linters,omitempty" toml:"disabled-linters,multiline,omitempty"` -} - -type ProtoGetterSettings struct { - SkipGeneratedBy []string `yaml:"skip-generated-by,omitempty" toml:"skip-generated-by,multiline,omitempty"` - SkipFiles []string `yaml:"skip-files,omitempty" toml:"skip-files,multiline,omitempty"` - SkipAnyGenerated *bool `yaml:"skip-any-generated,omitempty" toml:"skip-any-generated,multiline,omitempty"` - ReplaceFirstArgInAppend *bool `yaml:"replace-first-arg-in-append,omitempty" toml:"replace-first-arg-in-append,multiline,omitempty"` -} - -type ReassignSettings struct { - Patterns []string `yaml:"patterns,omitempty" toml:"patterns,multiline,omitempty"` -} - -type RecvcheckSettings struct { - DisableBuiltin *bool `yaml:"disable-builtin,omitempty" toml:"disable-builtin,multiline,omitempty"` - Exclusions []string `yaml:"exclusions,omitempty" toml:"exclusions,multiline,omitempty"` -} - -type ReviveSettings struct { - Go *string `yaml:"-,omitempty" toml:"-,multiline,omitempty"` - MaxOpenFiles *int `yaml:"max-open-files,omitempty" toml:"max-open-files,multiline,omitempty"` - Confidence *float64 `yaml:"confidence,omitempty" toml:"confidence,multiline,omitempty"` - Severity *string `yaml:"severity,omitempty" toml:"severity,multiline,omitempty"` - EnableAllRules *bool `yaml:"enable-all-rules,omitempty" toml:"enable-all-rules,multiline,omitempty"` - Rules []ReviveRule `yaml:"rules,omitempty" toml:"rules,multiline,omitempty"` - ErrorCode *int `yaml:"error-code,omitempty" toml:"error-code,multiline,omitempty"` - WarningCode *int `yaml:"warning-code,omitempty" toml:"warning-code,multiline,omitempty"` - Directives []ReviveDirective `yaml:"directives,omitempty" toml:"directives,multiline,omitempty"` -} - -type ReviveRule struct { - Name *string `yaml:"name,omitempty" toml:"name,multiline,omitempty"` - Arguments []any `yaml:"arguments,omitempty" toml:"arguments,multiline,omitempty"` - Severity *string `yaml:"severity,omitempty" toml:"severity,multiline,omitempty"` - Disabled *bool `yaml:"disabled,omitempty" toml:"disabled,multiline,omitempty"` - Exclude []string `yaml:"exclude,omitempty" toml:"exclude,multiline,omitempty"` -} - -type ReviveDirective struct { - Name *string `yaml:"name,omitempty" toml:"name,multiline,omitempty"` - Severity *string `yaml:"severity,omitempty" toml:"severity,multiline,omitempty"` -} - -type RowsErrCheckSettings struct { - Packages []string `yaml:"packages,omitempty" toml:"packages,multiline,omitempty"` -} - -type SlogLintSettings struct { - NoMixedArgs *bool `yaml:"no-mixed-args,omitempty" toml:"no-mixed-args,multiline,omitempty"` - KVOnly *bool `yaml:"kv-only,omitempty" toml:"kv-only,multiline,omitempty"` - AttrOnly *bool `yaml:"attr-only,omitempty" toml:"attr-only,multiline,omitempty"` - NoGlobal *string `yaml:"no-global,omitempty" toml:"no-global,multiline,omitempty"` - Context *string `yaml:"context,omitempty" toml:"context,multiline,omitempty"` - StaticMsg *bool `yaml:"static-msg,omitempty" toml:"static-msg,multiline,omitempty"` - MsgStyle *string `yaml:"msg-style,omitempty" toml:"msg-style,multiline,omitempty"` - NoRawKeys *bool `yaml:"no-raw-keys,omitempty" toml:"no-raw-keys,multiline,omitempty"` - KeyNamingCase *string `yaml:"key-naming-case,omitempty" toml:"key-naming-case,multiline,omitempty"` - ForbiddenKeys []string `yaml:"forbidden-keys,omitempty" toml:"forbidden-keys,multiline,omitempty"` - ArgsOnSepLines *bool `yaml:"args-on-sep-lines,omitempty" toml:"args-on-sep-lines,multiline,omitempty"` -} - -type SpancheckSettings struct { - Checks []string `yaml:"checks,omitempty" toml:"checks,multiline,omitempty"` - IgnoreCheckSignatures []string `yaml:"ignore-check-signatures,omitempty" toml:"ignore-check-signatures,multiline,omitempty"` - ExtraStartSpanSignatures []string `yaml:"extra-start-span-signatures,omitempty" toml:"extra-start-span-signatures,multiline,omitempty"` -} - -type StaticCheckSettings struct { - Checks []string `yaml:"checks,omitempty" toml:"checks,multiline,omitempty"` - Initialisms []string `yaml:"initialisms,omitempty" toml:"initialisms,multiline,omitempty"` - DotImportWhitelist []string `yaml:"dot-import-whitelist,omitempty" toml:"dot-import-whitelist,multiline,omitempty"` - HTTPStatusCodeWhitelist []string `yaml:"http-status-code-whitelist,omitempty" toml:"http-status-code-whitelist,multiline,omitempty"` -} - -type TagAlignSettings struct { - Align *bool `yaml:"align,omitempty" toml:"align,multiline,omitempty"` - Sort *bool `yaml:"sort,omitempty" toml:"sort,multiline,omitempty"` - Order []string `yaml:"order,omitempty" toml:"order,multiline,omitempty"` - Strict *bool `yaml:"strict,omitempty" toml:"strict,multiline,omitempty"` -} - -type TagliatelleSettings struct { - Case TagliatelleCase `yaml:"case,omitempty" toml:"case,multiline,omitempty"` -} - -type TagliatelleCase struct { - TagliatelleBase `yaml:",inline"` - Overrides []TagliatelleOverrides `yaml:"overrides,omitempty" toml:"overrides,multiline,omitempty"` -} - -type TagliatelleOverrides struct { - TagliatelleBase `yaml:",inline"` - Package *string `yaml:"pkg,omitempty" toml:"pkg,multiline,omitempty"` - Ignore *bool `yaml:"ignore,omitempty" toml:"ignore,multiline,omitempty"` -} - -type TagliatelleBase struct { - Rules map[string]string `yaml:"rules,omitempty" toml:"rules,multiline,omitempty"` - ExtendedRules map[string]TagliatelleExtendedRule `yaml:"extended-rules,omitempty" toml:"extended-rules,multiline,omitempty"` - UseFieldName *bool `yaml:"use-field-name,omitempty" toml:"use-field-name,multiline,omitempty"` - IgnoredFields []string `yaml:"ignored-fields,omitempty" toml:"ignored-fields,multiline,omitempty"` -} - -type TagliatelleExtendedRule struct { - Case *string `yaml:"case,omitempty" toml:"case,multiline,omitempty"` - ExtraInitialisms *bool `yaml:"extra-initialisms,omitempty" toml:"extra-initialisms,multiline,omitempty"` - InitialismOverrides map[string]bool `yaml:"initialism-overrides,omitempty" toml:"initialism-overrides,multiline,omitempty"` -} - -type TestifylintSettings struct { - EnableAll *bool `yaml:"enable-all,omitempty" toml:"enable-all,multiline,omitempty"` - DisableAll *bool `yaml:"disable-all,omitempty" toml:"disable-all,multiline,omitempty"` - EnabledCheckers []string `yaml:"enable,omitempty" toml:"enable,multiline,omitempty"` - DisabledCheckers []string `yaml:"disable,omitempty" toml:"disable,multiline,omitempty"` - - BoolCompare TestifylintBoolCompare `yaml:"bool-compare,omitempty" toml:"bool-compare,multiline,omitempty"` - ExpectedActual TestifylintExpectedActual `yaml:"expected-actual,omitempty" toml:"expected-actual,multiline,omitempty"` - Formatter TestifylintFormatter `yaml:"formatter,omitempty" toml:"formatter,multiline,omitempty"` - GoRequire TestifylintGoRequire `yaml:"go-require,omitempty" toml:"go-require,multiline,omitempty"` - RequireError TestifylintRequireError `yaml:"require-error,omitempty" toml:"require-error,multiline,omitempty"` - SuiteExtraAssertCall TestifylintSuiteExtraAssertCall `yaml:"suite-extra-assert-call,omitempty" toml:"suite-extra-assert-call,multiline,omitempty"` -} - -type TestifylintBoolCompare struct { - IgnoreCustomTypes *bool `yaml:"ignore-custom-types,omitempty" toml:"ignore-custom-types,multiline,omitempty"` -} - -type TestifylintExpectedActual struct { - ExpVarPattern *string `yaml:"pattern,omitempty" toml:"pattern,multiline,omitempty"` -} - -type TestifylintFormatter struct { - CheckFormatString *bool `yaml:"check-format-string,omitempty" toml:"check-format-string,multiline,omitempty"` - RequireFFuncs *bool `yaml:"require-f-funcs,omitempty" toml:"require-f-funcs,multiline,omitempty"` - RequireStringMsg *bool `yaml:"require-string-msg,omitempty" toml:"require-string-msg,multiline,omitempty"` -} - -type TestifylintGoRequire struct { - IgnoreHTTPHandlers *bool `yaml:"ignore-http-handlers,omitempty" toml:"ignore-http-handlers,multiline,omitempty"` -} - -type TestifylintRequireError struct { - FnPattern *string `yaml:"fn-pattern,omitempty" toml:"fn-pattern,multiline,omitempty"` -} - -type TestifylintSuiteExtraAssertCall struct { - Mode *string `yaml:"mode,omitempty" toml:"mode,multiline,omitempty"` -} - -type TestpackageSettings struct { - SkipRegexp *string `yaml:"skip-regexp,omitempty" toml:"skip-regexp,multiline,omitempty"` - AllowPackages []string `yaml:"allow-packages,omitempty" toml:"allow-packages,multiline,omitempty"` -} - -type ThelperSettings struct { - Test ThelperOptions `yaml:"test,omitempty" toml:"test,multiline,omitempty"` - Fuzz ThelperOptions `yaml:"fuzz,omitempty" toml:"fuzz,multiline,omitempty"` - Benchmark ThelperOptions `yaml:"benchmark,omitempty" toml:"benchmark,multiline,omitempty"` - TB ThelperOptions `yaml:"tb,omitempty" toml:"tb,multiline,omitempty"` -} - -type ThelperOptions struct { - First *bool `yaml:"first,omitempty" toml:"first,multiline,omitempty"` - Name *bool `yaml:"name,omitempty" toml:"name,multiline,omitempty"` - Begin *bool `yaml:"begin,omitempty" toml:"begin,multiline,omitempty"` -} - -type UseStdlibVarsSettings struct { - HTTPMethod *bool `yaml:"http-method,omitempty" toml:"http-method,multiline,omitempty"` - HTTPStatusCode *bool `yaml:"http-status-code,omitempty" toml:"http-status-code,multiline,omitempty"` - TimeWeekday *bool `yaml:"time-weekday,omitempty" toml:"time-weekday,multiline,omitempty"` - TimeMonth *bool `yaml:"time-month,omitempty" toml:"time-month,multiline,omitempty"` - TimeLayout *bool `yaml:"time-layout,omitempty" toml:"time-layout,multiline,omitempty"` - CryptoHash *bool `yaml:"crypto-hash,omitempty" toml:"crypto-hash,multiline,omitempty"` - DefaultRPCPath *bool `yaml:"default-rpc-path,omitempty" toml:"default-rpc-path,multiline,omitempty"` - SQLIsolationLevel *bool `yaml:"sql-isolation-level,omitempty" toml:"sql-isolation-level,multiline,omitempty"` - TLSSignatureScheme *bool `yaml:"tls-signature-scheme,omitempty" toml:"tls-signature-scheme,multiline,omitempty"` - ConstantKind *bool `yaml:"constant-kind,omitempty" toml:"constant-kind,multiline,omitempty"` - TimeDateMonth *bool `yaml:"time-date-month,omitempty" toml:"time-date-month,multiline,omitempty"` -} - -type UseTestingSettings struct { - ContextBackground *bool `yaml:"context-background,omitempty" toml:"context-background,multiline,omitempty"` - ContextTodo *bool `yaml:"context-todo,omitempty" toml:"context-todo,multiline,omitempty"` - OSChdir *bool `yaml:"os-chdir,omitempty" toml:"os-chdir,multiline,omitempty"` - OSMkdirTemp *bool `yaml:"os-mkdir-temp,omitempty" toml:"os-mkdir-temp,multiline,omitempty"` - OSSetenv *bool `yaml:"os-setenv,omitempty" toml:"os-setenv,multiline,omitempty"` - OSTempDir *bool `yaml:"os-temp-dir,omitempty" toml:"os-temp-dir,multiline,omitempty"` - OSCreateTemp *bool `yaml:"os-create-temp,omitempty" toml:"os-create-temp,multiline,omitempty"` -} - -type UnconvertSettings struct { - FastMath *bool `yaml:"fast-math,omitempty" toml:"fast-math,multiline,omitempty"` - Safe *bool `yaml:"safe,omitempty" toml:"safe,multiline,omitempty"` -} - -type UnparamSettings struct { - CheckExported *bool `yaml:"check-exported,omitempty" toml:"check-exported,multiline,omitempty"` -} - -type UnusedSettings struct { - FieldWritesAreUses *bool `yaml:"field-writes-are-uses,omitempty" toml:"field-writes-are-uses,multiline,omitempty"` - PostStatementsAreReads *bool `yaml:"post-statements-are-reads,omitempty" toml:"post-statements-are-reads,multiline,omitempty"` - ExportedFieldsAreUsed *bool `yaml:"exported-fields-are-used,omitempty" toml:"exported-fields-are-used,multiline,omitempty"` - ParametersAreUsed *bool `yaml:"parameters-are-used,omitempty" toml:"parameters-are-used,multiline,omitempty"` - LocalVariablesAreUsed *bool `yaml:"local-variables-are-used,omitempty" toml:"local-variables-are-used,multiline,omitempty"` - GeneratedIsUsed *bool `yaml:"generated-is-used,omitempty" toml:"generated-is-used,multiline,omitempty"` -} - -type VarnamelenSettings struct { - MaxDistance *int `yaml:"max-distance,omitempty" toml:"max-distance,multiline,omitempty"` - MinNameLength *int `yaml:"min-name-length,omitempty" toml:"min-name-length,multiline,omitempty"` - CheckReceiver *bool `yaml:"check-receiver,omitempty" toml:"check-receiver,multiline,omitempty"` - CheckReturn *bool `yaml:"check-return,omitempty" toml:"check-return,multiline,omitempty"` - CheckTypeParam *bool `yaml:"check-type-param,omitempty" toml:"check-type-param,multiline,omitempty"` - IgnoreNames []string `yaml:"ignore-names,omitempty" toml:"ignore-names,multiline,omitempty"` - IgnoreTypeAssertOk *bool `yaml:"ignore-type-assert-ok,omitempty" toml:"ignore-type-assert-ok,multiline,omitempty"` - IgnoreMapIndexOk *bool `yaml:"ignore-map-index-ok,omitempty" toml:"ignore-map-index-ok,multiline,omitempty"` - IgnoreChanRecvOk *bool `yaml:"ignore-chan-recv-ok,omitempty" toml:"ignore-chan-recv-ok,multiline,omitempty"` - IgnoreDecls []string `yaml:"ignore-decls,omitempty" toml:"ignore-decls,multiline,omitempty"` -} - -type WhitespaceSettings struct { - MultiIf *bool `yaml:"multi-if,omitempty" toml:"multi-if,multiline,omitempty"` - MultiFunc *bool `yaml:"multi-func,omitempty" toml:"multi-func,multiline,omitempty"` -} - -type WrapcheckSettings struct { - ExtraIgnoreSigs []string `yaml:"extra-ignore-sigs,omitempty" toml:"extra-ignore-sigs,multiline,omitempty"` - IgnoreSigs []string `yaml:"ignore-sigs,omitempty" toml:"ignore-sigs,multiline,omitempty"` - IgnoreSigRegexps []string `yaml:"ignore-sig-regexps,omitempty" toml:"ignore-sig-regexps,multiline,omitempty"` - IgnorePackageGlobs []string `yaml:"ignore-package-globs,omitempty" toml:"ignore-package-globs,multiline,omitempty"` - IgnoreInterfaceRegexps []string `yaml:"ignore-interface-regexps,omitempty" toml:"ignore-interface-regexps,multiline,omitempty"` - ReportInternalErrors *bool `yaml:"report-internal-errors,omitempty" toml:"report-internal-errors,multiline,omitempty"` -} - -type WSLv4Settings struct { - StrictAppend *bool `yaml:"strict-append,omitempty" toml:"strict-append,multiline,omitempty"` - AllowAssignAndCallCuddle *bool `yaml:"allow-assign-and-call,omitempty" toml:"allow-assign-and-call,multiline,omitempty"` - AllowAssignAndAnythingCuddle *bool `yaml:"allow-assign-and-anything,omitempty" toml:"allow-assign-and-anything,multiline,omitempty"` - AllowMultiLineAssignCuddle *bool `yaml:"allow-multiline-assign,omitempty" toml:"allow-multiline-assign,multiline,omitempty"` - ForceCaseTrailingWhitespaceLimit *int `yaml:"force-case-trailing-whitespace,omitempty" toml:"force-case-trailing-whitespace,multiline,omitempty"` - AllowTrailingComment *bool `yaml:"allow-trailing-comment,omitempty" toml:"allow-trailing-comment,multiline,omitempty"` - AllowSeparatedLeadingComment *bool `yaml:"allow-separated-leading-comment,omitempty" toml:"allow-separated-leading-comment,multiline,omitempty"` - AllowCuddleDeclaration *bool `yaml:"allow-cuddle-declarations,omitempty" toml:"allow-cuddle-declarations,multiline,omitempty"` - AllowCuddleWithCalls []string `yaml:"allow-cuddle-with-calls,omitempty" toml:"allow-cuddle-with-calls,multiline,omitempty"` - AllowCuddleWithRHS []string `yaml:"allow-cuddle-with-rhs,omitempty" toml:"allow-cuddle-with-rhs,multiline,omitempty"` - AllowCuddleUsedInBlock *bool `yaml:"allow-cuddle-used-in-block,omitempty" toml:"allow-cuddle-used-in-block,multiline,omitempty"` - ForceCuddleErrCheckAndAssign *bool `yaml:"force-err-cuddling,omitempty" toml:"force-err-cuddling,multiline,omitempty"` - ErrorVariableNames []string `yaml:"error-variable-names,omitempty" toml:"error-variable-names,multiline,omitempty"` - ForceExclusiveShortDeclarations *bool `yaml:"force-short-decl-cuddling,omitempty" toml:"force-short-decl-cuddling,multiline,omitempty"` -} - -type WSLv5Settings struct { - AllowFirstInBlock *bool `yaml:"allow-first-in-block,omitempty" toml:"allow-first-in-block,multiline,omitempty"` - AllowWholeBlock *bool `yaml:"allow-whole-block,omitempty" toml:"allow-whole-block,multiline,omitempty"` - BranchMaxLines *int `yaml:"branch-max-lines,omitempty" toml:"branch-max-lines,multiline,omitempty"` - CaseMaxLines *int `yaml:"case-max-lines,omitempty" toml:"case-max-lines,multiline,omitempty"` - Default *string `yaml:"default,omitempty" toml:"default,multiline,omitempty"` - Enable []string `yaml:"enable,omitempty" toml:"enable,multiline,omitempty"` - Disable []string `yaml:"disable,omitempty" toml:"disable,multiline,omitempty"` -} - -type CustomLinterSettings struct { - Type *string `yaml:"type,omitempty" toml:"type,multiline,omitempty"` - - Path *string `yaml:"path,omitempty" toml:"path,multiline,omitempty"` - - Description *string `yaml:"description,omitempty" toml:"description,multiline,omitempty"` - - OriginalURL *string `yaml:"original-url,omitempty" toml:"original-url,multiline,omitempty"` - - Settings any `yaml:"settings,omitempty" toml:"settings,multiline,omitempty"` -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/output.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/output.go deleted file mode 100644 index 16afb6701e..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/output.go +++ /dev/null @@ -1,11 +0,0 @@ -// Code generated by pkg/commands/internal/migrate/cloner/cloner.go. DO NOT EDIT. - -package versiontwo - -type Output struct { - Formats Formats `yaml:"formats,omitempty" toml:"formats,multiline,omitempty"` - SortOrder []string `yaml:"sort-order,omitempty" toml:"sort-order,multiline,omitempty"` - ShowStats *bool `yaml:"show-stats,omitempty" toml:"show-stats,multiline,omitempty"` - PathPrefix *string `yaml:"path-prefix,omitempty" toml:"path-prefix,multiline,omitempty"` - PathMode *string `yaml:"path-mode,omitempty" toml:"path-mode,multiline,omitempty"` -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/output_formats.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/output_formats.go deleted file mode 100644 index dbc5665f78..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/output_formats.go +++ /dev/null @@ -1,37 +0,0 @@ -// Code generated by pkg/commands/internal/migrate/cloner/cloner.go. DO NOT EDIT. - -package versiontwo - -type Formats struct { - Text Text `yaml:"text,omitempty" toml:"text,multiline,omitempty"` - JSON SimpleFormat `yaml:"json,omitempty" toml:"json,multiline,omitempty"` - Tab Tab `yaml:"tab,omitempty" toml:"tab,multiline,omitempty"` - HTML SimpleFormat `yaml:"html,omitempty" toml:"html,multiline,omitempty"` - Checkstyle SimpleFormat `yaml:"checkstyle,omitempty" toml:"checkstyle,multiline,omitempty"` - CodeClimate SimpleFormat `yaml:"code-climate,omitempty" toml:"code-climate,multiline,omitempty"` - JUnitXML JUnitXML `yaml:"junit-xml,omitempty" toml:"junit-xml,multiline,omitempty"` - TeamCity SimpleFormat `yaml:"teamcity,omitempty" toml:"teamcity,multiline,omitempty"` - Sarif SimpleFormat `yaml:"sarif,omitempty" toml:"sarif,multiline,omitempty"` -} - -type SimpleFormat struct { - Path *string `yaml:"path,omitempty" toml:"path,multiline,omitempty"` -} - -type Text struct { - SimpleFormat `yaml:",inline"` - PrintLinterName *bool `yaml:"print-linter-name,omitempty" toml:"print-linter-name,multiline,omitempty"` - PrintIssuedLine *bool `yaml:"print-issued-lines,omitempty" toml:"print-issued-lines,multiline,omitempty"` - Colors *bool `yaml:"colors,omitempty" toml:"colors,multiline,omitempty"` -} - -type Tab struct { - SimpleFormat `yaml:",inline"` - PrintLinterName *bool `yaml:"print-linter-name,omitempty" toml:"print-linter-name,multiline,omitempty"` - Colors *bool `yaml:"colors,omitempty" toml:"colors,multiline,omitempty"` -} - -type JUnitXML struct { - SimpleFormat `yaml:",inline"` - Extended *bool `yaml:"extended,omitempty" toml:"extended,multiline,omitempty"` -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/run.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/run.go deleted file mode 100644 index 501d3e9fca..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/run.go +++ /dev/null @@ -1,26 +0,0 @@ -// Code generated by pkg/commands/internal/migrate/cloner/cloner.go. DO NOT EDIT. - -package versiontwo - -import ( - "time" -) - -type Run struct { - Timeout time.Duration `yaml:"timeout,omitempty" toml:"timeout,multiline,omitempty"` - - Concurrency *int `yaml:"concurrency,omitempty" toml:"concurrency,multiline,omitempty"` - - Go *string `yaml:"go,omitempty" toml:"go,multiline,omitempty"` - - RelativePathMode *string `yaml:"relative-path-mode,omitempty" toml:"relative-path-mode,multiline,omitempty"` - - BuildTags []string `yaml:"build-tags,omitempty" toml:"build-tags,multiline,omitempty"` - ModulesDownloadMode *string `yaml:"modules-download-mode,omitempty" toml:"modules-download-mode,multiline,omitempty"` - - ExitCodeIfIssuesFound *int `yaml:"issues-exit-code,omitempty" toml:"issues-exit-code,multiline,omitempty"` - AnalyzeTests *bool `yaml:"tests,omitempty" toml:"tests,multiline,omitempty"` - - AllowParallelRunners *bool `yaml:"allow-parallel-runners,omitempty" toml:"allow-parallel-runners,multiline,omitempty"` - AllowSerialRunners *bool `yaml:"allow-serial-runners,omitempty" toml:"allow-serial-runners,multiline,omitempty"` -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/severity.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/severity.go deleted file mode 100644 index 248ddf1f18..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versiontwo/severity.go +++ /dev/null @@ -1,13 +0,0 @@ -// Code generated by pkg/commands/internal/migrate/cloner/cloner.go. DO NOT EDIT. - -package versiontwo - -type Severity struct { - Default *string `yaml:"default,omitempty" toml:"default,multiline,omitempty"` - Rules []SeverityRule `yaml:"rules,omitempty" toml:"rules,multiline,omitempty"` -} - -type SeverityRule struct { - BaseRule `yaml:",inline"` - Severity *string `yaml:"severity,omitempty" toml:"severity,multiline,omitempty"` -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/vibra.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/vibra.go deleted file mode 100644 index ece2483fe0..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/internal/vibra.go +++ /dev/null @@ -1,59 +0,0 @@ -package internal - -import ( - "fmt" - - "github.com/spf13/pflag" - "github.com/spf13/viper" -) - -type FlagFunc[T any] func(name string, value T, usage string) *T - -type FlagPFunc[T any] func(name, shorthand string, value T, usage string) *T - -// AddFlagAndBind adds a Cobra/pflag flag and binds it with Viper. -func AddFlagAndBind[T any](v *viper.Viper, fs *pflag.FlagSet, pfn FlagFunc[T], name, bind string, value T, usage string) { - pfn(name, value, usage) - - err := v.BindPFlag(bind, fs.Lookup(name)) - if err != nil { - panic(fmt.Sprintf("failed to bind flag %s: %v", name, err)) - } -} - -// AddFlagAndBindP adds a Cobra/pflag flag and binds it with Viper. -func AddFlagAndBindP[T any](v *viper.Viper, fs *pflag.FlagSet, pfn FlagPFunc[T], name, shorthand, bind string, value T, usage string) { - pfn(name, shorthand, value, usage) - - err := v.BindPFlag(bind, fs.Lookup(name)) - if err != nil { - panic(fmt.Sprintf("failed to bind flag %s: %v", name, err)) - } -} - -// AddDeprecatedFlagAndBind similar to AddFlagAndBind but deprecate the flag. -func AddDeprecatedFlagAndBind[T any](v *viper.Viper, fs *pflag.FlagSet, pfn FlagFunc[T], name, bind string, value T, usage string) { - AddFlagAndBind(v, fs, pfn, name, bind, value, usage) - deprecateFlag(fs, name) -} - -// AddHackedStringSliceP Hack for slice, see Loader.applyStringSliceHack. -func AddHackedStringSliceP(fs *pflag.FlagSet, name, shorthand, usage string) { - fs.StringSliceP(name, shorthand, nil, usage) -} - -// AddHackedStringSlice Hack for slice, see Loader.applyStringSliceHack. -func AddHackedStringSlice(fs *pflag.FlagSet, name, usage string) { - AddHackedStringSliceP(fs, name, "", usage) -} - -// AddDeprecatedHackedStringSlice similar to AddHackedStringSlice but deprecate the flag. -func AddDeprecatedHackedStringSlice(fs *pflag.FlagSet, name, usage string) { - AddHackedStringSlice(fs, name, usage) - deprecateFlag(fs, name) -} - -func deprecateFlag(fs *pflag.FlagSet, name string) { - _ = fs.MarkHidden(name) - _ = fs.MarkDeprecated(name, "check the documentation for more information.") -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/linters.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/linters.go deleted file mode 100644 index 4be11ab567..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/linters.go +++ /dev/null @@ -1,136 +0,0 @@ -package commands - -import ( - "encoding/json" - "fmt" - - "github.com/fatih/color" - "github.com/spf13/cobra" - "github.com/spf13/viper" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goformatters" - "github.com/golangci/golangci-lint/v2/pkg/lint/linter" - "github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb" - "github.com/golangci/golangci-lint/v2/pkg/logutils" -) - -type lintersHelp struct { - Enabled []linterHelp - Disabled []linterHelp -} - -type lintersOptions struct { - config.LoaderOptions - JSON bool -} - -type lintersCommand struct { - viper *viper.Viper - cmd *cobra.Command - - opts lintersOptions - - cfg *config.Config - - log logutils.Log - - dbManager *lintersdb.Manager -} - -func newLintersCommand(logger logutils.Log) *lintersCommand { - c := &lintersCommand{ - viper: viper.New(), - cfg: config.NewDefault(), - log: logger, - } - - lintersCmd := &cobra.Command{ - Use: "linters", - Short: "List current linters configuration.", - Args: cobra.NoArgs, - ValidArgsFunction: cobra.NoFileCompletions, - RunE: c.execute, - PreRunE: c.preRunE, - SilenceUsage: true, - } - - fs := lintersCmd.Flags() - fs.SortFlags = false // sort them as they are defined here - - setupConfigFileFlagSet(fs, &c.opts.LoaderOptions) - setupLintersFlagSet(c.viper, fs) - - fs.BoolVar(&c.opts.JSON, "json", false, color.GreenString("Display as JSON")) - - c.cmd = lintersCmd - - return c -} - -func (c *lintersCommand) preRunE(cmd *cobra.Command, args []string) error { - loader := config.NewLintersLoader(c.log.Child(logutils.DebugKeyConfigReader), c.viper, cmd.Flags(), c.opts.LoaderOptions, c.cfg, args) - - err := loader.Load(config.LoadOptions{Validation: true}) - if err != nil { - return fmt.Errorf("can't load config: %w", err) - } - - dbManager, err := lintersdb.NewManager(c.log.Child(logutils.DebugKeyLintersDB), c.cfg, - lintersdb.NewLinterBuilder(), lintersdb.NewPluginModuleBuilder(c.log), lintersdb.NewPluginGoBuilder(c.log)) - if err != nil { - return err - } - - c.dbManager = dbManager - - return nil -} - -func (c *lintersCommand) execute(_ *cobra.Command, _ []string) error { - enabledLintersMap, err := c.dbManager.GetEnabledLintersMap() - if err != nil { - return fmt.Errorf("can't get enabled linters: %w", err) - } - - var enabledLinters []*linter.Config - var disabledLinters []*linter.Config - - for _, lc := range c.dbManager.GetAllSupportedLinterConfigs() { - if lc.Internal { - continue - } - - if goformatters.IsFormatter(lc.Name()) { - continue - } - - if enabledLintersMap[lc.Name()] == nil { - disabledLinters = append(disabledLinters, lc) - } else { - enabledLinters = append(enabledLinters, lc) - } - } - - if c.opts.JSON { - linters := lintersHelp{} - - for _, lc := range enabledLinters { - linters.Enabled = append(linters.Enabled, newLinterHelp(lc)) - } - - for _, lc := range disabledLinters { - linters.Disabled = append(linters.Disabled, newLinterHelp(lc)) - } - - return json.NewEncoder(c.cmd.OutOrStdout()).Encode(linters) - } - - color.Green("Enabled by your configuration linters:\n") - printLinters(enabledLinters) - - color.Red("\nDisabled by your configuration linters:\n") - printLinters(disabledLinters) - - return nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/migrate.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/migrate.go deleted file mode 100644 index 7012e9226e..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/migrate.go +++ /dev/null @@ -1,243 +0,0 @@ -package commands - -import ( - "errors" - "fmt" - "os" - "path/filepath" - "strings" - - "github.com/charmbracelet/lipgloss" - "github.com/fatih/color" - "github.com/santhosh-tekuri/jsonschema/v6" - "github.com/spf13/cobra" - "github.com/spf13/viper" - - "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate" - "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/fakeloader" - "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/parser" - "github.com/golangci/golangci-lint/v2/pkg/commands/internal/migrate/versionone" - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/exitcodes" - "github.com/golangci/golangci-lint/v2/pkg/logutils" -) - -type migrateOptions struct { - config.LoaderOptions - - format string // Flag only. - skipValidation bool // Flag only. -} -type migrateCommand struct { - viper *viper.Viper - cmd *cobra.Command - - opts migrateOptions - - cfg *versionone.Config - - buildInfo BuildInfo - - log logutils.Log -} - -func newMigrateCommand(log logutils.Log, info BuildInfo) *migrateCommand { - c := &migrateCommand{ - viper: viper.New(), - cfg: versionone.NewConfig(), - buildInfo: info, - log: log, - } - - migrateCmd := &cobra.Command{ - Use: "migrate", - Short: "Migrate configuration file from v1 to v2.", - SilenceUsage: true, - SilenceErrors: true, - Args: cobra.NoArgs, - RunE: c.execute, - PreRunE: c.preRunE, - PersistentPreRunE: c.persistentPreRunE, - } - - migrateCmd.SetOut(logutils.StdOut) // use custom output to properly color it in Windows terminals - migrateCmd.SetErr(logutils.StdErr) - - fs := migrateCmd.Flags() - fs.SortFlags = false // sort them as they are defined here - - setupConfigFileFlagSet(fs, &c.opts.LoaderOptions) - - fs.StringVar(&c.opts.format, "format", "", - color.GreenString("Output file format.\nBy default, the format of the input configuration file is used.\n"+ - "It can be 'yml', 'yaml', 'toml', or 'json'.")) - - fs.BoolVar(&c.opts.skipValidation, "skip-validation", false, - color.GreenString("Skip validation of the configuration file against the JSON Schema for v1.")) - - c.cmd = migrateCmd - - return c -} - -func (c *migrateCommand) execute(_ *cobra.Command, _ []string) error { - srcPath := c.viper.ConfigFileUsed() - if srcPath == "" { - c.log.Warnf("No config file detected") - os.Exit(exitcodes.NoConfigFileDetected) - } - - err := c.backupConfigurationFile(srcPath) - if err != nil { - return err - } - - c.log.Warnf("The configuration comments are not migrated.") - c.log.Warnf("Details about the migration: https://golangci-lint.run/docs/product/migration-guide/") - - c.log.Infof("Migrating v1 configuration file: %s", srcPath) - - ext := filepath.Ext(srcPath) - - if c.opts.format != "" { - ext = "." + c.opts.format - } - - if !strings.EqualFold(filepath.Ext(srcPath), ext) { - defer func() { - _ = os.RemoveAll(srcPath) - }() - } - - if c.cfg.Run.Timeout != 0 { - c.log.Warnf("The configuration `run.timeout` is ignored. By default, in v2, the timeout is disabled.") - } - - newCfg := migrate.ToConfig(c.cfg) - - dstPath := strings.TrimSuffix(srcPath, filepath.Ext(srcPath)) + ext - - err = saveNewConfiguration(newCfg, dstPath) - if err != nil { - return fmt.Errorf("saving configuration file: %w", err) - } - - c.log.Infof("Migration done: %s", dstPath) - - callForAction(c.cmd) - - return nil -} - -func (c *migrateCommand) preRunE(cmd *cobra.Command, _ []string) error { - switch strings.ToLower(c.opts.format) { - case "", "yml", "yaml", "toml", "json": - // Valid format. - default: - return fmt.Errorf("unsupported format: %s", c.opts.format) - } - - if c.cfg.Version != "" { - return fmt.Errorf("configuration version is already set: %s", c.cfg.Version) - } - - if c.opts.skipValidation { - return nil - } - - usedConfigFile := c.viper.ConfigFileUsed() - if usedConfigFile == "" { - c.log.Warnf("No config file detected") - os.Exit(exitcodes.NoConfigFileDetected) - } - - c.log.Infof("Validating v1 configuration file: %s", usedConfigFile) - - err := validateConfiguration("https://golangci-lint.run/jsonschema/golangci.v1.jsonschema.json", usedConfigFile) - if err != nil { - var v *jsonschema.ValidationError - if !errors.As(err, &v) { - return fmt.Errorf("[%s] validate: %w", usedConfigFile, err) - } - - printValidationDetail(cmd, v.DetailedOutput()) - - return errors.New("the configuration contains invalid elements") - } - - return nil -} - -func (c *migrateCommand) persistentPreRunE(_ *cobra.Command, args []string) error { - c.log.Infof("%s", c.buildInfo.String()) - - loader := config.NewBaseLoader(c.log.Child(logutils.DebugKeyConfigReader), c.viper, c.opts.LoaderOptions, fakeloader.NewConfig(), args) - - // Loads the configuration just to get the effective path of the configuration. - err := loader.Load() - if err != nil { - return fmt.Errorf("can't load config: %w", err) - } - - srcPath := c.viper.ConfigFileUsed() - if srcPath == "" { - c.log.Warnf("No config file detected") - os.Exit(exitcodes.NoConfigFileDetected) - } - - return fakeloader.Load(srcPath, c.cfg) -} - -func (c *migrateCommand) backupConfigurationFile(srcPath string) error { - filename := strings.TrimSuffix(filepath.Base(srcPath), filepath.Ext(srcPath)) + ".bck" + filepath.Ext(srcPath) - dstPath := filepath.Join(filepath.Dir(srcPath), filename) - - c.log.Infof("Saving the v1 configuration to: %s", dstPath) - - stat, err := os.Stat(srcPath) - if err != nil { - return err - } - - data, err := os.ReadFile(srcPath) - if err != nil { - return err - } - - err = os.WriteFile(dstPath, data, stat.Mode()) - if err != nil { - return err - } - - return nil -} - -func saveNewConfiguration(cfg any, dstPath string) error { - dstFile, err := os.Create(dstPath) - if err != nil { - return err - } - - defer func() { _ = dstFile.Close() }() - - return parser.Encode(cfg, dstFile) -} - -func callForAction(cmd *cobra.Command) { - pStyle := lipgloss.NewStyle(). - Padding(1). - BorderStyle(lipgloss.RoundedBorder()). - BorderForeground(lipgloss.Color("161")). - Align(lipgloss.Center) - - hStyle := lipgloss.NewStyle().Bold(true) - - s := fmt.Sprintln(hStyle.Render("We need you!")) - s += ` -Donations help fund the ongoing development and maintenance of this tool. -If golangci-lint has been useful to you, please consider contributing. - -Donate now: https://donate.golangci.org` - - cmd.Println(pStyle.Render(s)) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/root.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/root.go deleted file mode 100644 index 9fa36f25fd..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/root.go +++ /dev/null @@ -1,173 +0,0 @@ -package commands - -import ( - "errors" - "fmt" - "os" - "slices" - - "github.com/fatih/color" - "github.com/spf13/cobra" - "github.com/spf13/pflag" - - "github.com/golangci/golangci-lint/v2/pkg/logutils" -) - -func Execute(info BuildInfo) error { - return newRootCommand(info).Execute() -} - -type rootOptions struct { - PrintVersion bool // Flag only. - - Verbose bool // Flag only. - Color string // Flag only. -} - -type rootCommand struct { - cmd *cobra.Command - opts rootOptions - - log logutils.Log -} - -func newRootCommand(info BuildInfo) *rootCommand { - c := &rootCommand{} - - rootCmd := &cobra.Command{ - Use: "golangci-lint", - Short: "golangci-lint is a smart linters runner.", - Long: `Smart, fast linters runner.`, - Args: cobra.NoArgs, - RunE: func(cmd *cobra.Command, _ []string) error { - if c.opts.PrintVersion { - _ = printVersion(logutils.StdOut, info) - return nil - } - - return cmd.Help() - }, - } - - fs := rootCmd.Flags() - fs.BoolVar(&c.opts.PrintVersion, "version", false, color.GreenString("Print version")) - - setupRootPersistentFlags(rootCmd.PersistentFlags(), &c.opts) - - log := logutils.NewStderrLog(logutils.DebugKeyEmpty) - - // Each command uses a dedicated configuration structure to avoid side effects of bindings. - rootCmd.AddCommand( - newLintersCommand(log).cmd, - newFormattersCommand(log).cmd, - newRunCommand(log, info).cmd, - newFmtCommand(log, info).cmd, - newMigrateCommand(log, info).cmd, - newCacheCommand().cmd, - newConfigCommand(log, info).cmd, - newVersionCommand(info).cmd, - newCustomCommand(log).cmd, - ) - - rootCmd.SetHelpCommand(newHelpCommand(log).cmd) - - c.log = log - c.cmd = rootCmd - - return c -} - -func (c *rootCommand) Execute() error { - err := setupLogger(c.log) - if err != nil { - return err - } - - return c.cmd.Execute() -} - -func setupRootPersistentFlags(fs *pflag.FlagSet, opts *rootOptions) { - fs.BoolP("help", "h", false, color.GreenString("Help for a command")) - fs.BoolVarP(&opts.Verbose, "verbose", "v", false, color.GreenString("Verbose output")) - fs.StringVar(&opts.Color, "color", "auto", color.GreenString("Use color when printing; can be 'always', 'auto', or 'never'")) -} - -func setupLogger(logger logutils.Log) error { - opts, err := forceRootParsePersistentFlags() - if err != nil && !errors.Is(err, pflag.ErrHelp) { - return err - } - - if opts == nil { - return nil - } - - logutils.SetupVerboseLog(logger, opts.Verbose) - - switch opts.Color { - case "always": - color.NoColor = false - case "never": - color.NoColor = true - case "auto": - // nothing - default: - logger.Fatalf("invalid value %q for --color; must be 'always', 'auto', or 'never'", opts.Color) - } - - // For log level colors (mainly for verbose output) - logutils.DisableColors(color.NoColor) - - return nil -} - -func forceRootParsePersistentFlags() (*rootOptions, error) { - // We use another pflag.FlagSet here to not set `changed` flag on cmd.Flags() options. - // Otherwise, string slice options will be duplicated. - fs := pflag.NewFlagSet("config flag set", pflag.ContinueOnError) - - // Ignore unknown flags because we will parse the command flags later. - fs.ParseErrorsAllowlist = pflag.ParseErrorsAllowlist{UnknownFlags: true} - - opts := &rootOptions{} - - // Don't do `fs.AddFlagSet(cmd.Flags())` because it shares flags representations: - // `changed` variable inside string slice vars will be shared. - // Use another config variable here, - // to not affect main parsing by this parsing of only config option. - setupRootPersistentFlags(fs, opts) - - fs.Usage = func() {} // otherwise, help text will be printed twice - - if err := fs.Parse(safeArgs(fs, os.Args)); err != nil { - if errors.Is(err, pflag.ErrHelp) { - return nil, err - } - - return nil, fmt.Errorf("can't parse args: %w", err) - } - - return opts, nil -} - -// Shorthands are a problem because pflag, with UnknownFlags, will try to parse all the letters as options. -// A shorthand can aggregate several letters (ex `ps -aux`) -// The function replaces non-supported shorthands by a dumb flag. -func safeArgs(fs *pflag.FlagSet, args []string) []string { - var shorthands []string - fs.VisitAll(func(flag *pflag.Flag) { - shorthands = append(shorthands, flag.Shorthand) - }) - - var cleanArgs []string - for _, arg := range args { - if len(arg) > 1 && arg[0] == '-' && arg[1] != '-' && !slices.Contains(shorthands, string(arg[1])) { - cleanArgs = append(cleanArgs, "--potato") - continue - } - - cleanArgs = append(cleanArgs, arg) - } - - return cleanArgs -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/run.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/run.go deleted file mode 100644 index d1c96b88ee..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/run.go +++ /dev/null @@ -1,733 +0,0 @@ -package commands - -import ( - "bytes" - "context" - "crypto/sha256" - "errors" - "fmt" - "io" - "log" - "maps" - "os" - "path/filepath" - "runtime" - "runtime/pprof" - "runtime/trace" - "slices" - "strconv" - "strings" - "time" - - "github.com/fatih/color" - "github.com/gofrs/flock" - "github.com/ldez/grignotin/goenv" - "github.com/spf13/cobra" - "github.com/spf13/pflag" - "github.com/spf13/viper" - "go.uber.org/automaxprocs/maxprocs" - "golang.org/x/mod/sumdb/dirhash" - "gopkg.in/yaml.v3" - - "github.com/golangci/golangci-lint/v2/internal/cache" - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/exitcodes" - "github.com/golangci/golangci-lint/v2/pkg/fsutils" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis/load" - "github.com/golangci/golangci-lint/v2/pkg/goutil" - "github.com/golangci/golangci-lint/v2/pkg/lint" - "github.com/golangci/golangci-lint/v2/pkg/lint/linter" - "github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb" - "github.com/golangci/golangci-lint/v2/pkg/logutils" - "github.com/golangci/golangci-lint/v2/pkg/printers" - "github.com/golangci/golangci-lint/v2/pkg/report" - "github.com/golangci/golangci-lint/v2/pkg/result" - "github.com/golangci/golangci-lint/v2/pkg/timeutils" -) - -const defaultTimeout = 0 * time.Minute - -const ( - // envFailOnWarnings value: "1" - envFailOnWarnings = "FAIL_ON_WARNINGS" - // envMemLogEvery value: "1" - envMemLogEvery = "GL_MEM_LOG_EVERY" -) - -const ( - envMemProfileRate = "GL_MEM_PROFILE_RATE" -) - -type runOptions struct { - config.LoaderOptions - - CPUProfilePath string // Flag only. - MemProfilePath string // Flag only. - TracePath string // Flag only. - - PrintResourcesUsage bool // Flag only. -} - -type runCommand struct { - viper *viper.Viper - cmd *cobra.Command - - opts runOptions - - cfg *config.Config - - buildInfo BuildInfo - - dbManager *lintersdb.Manager - - printer *printers.Printer - - log logutils.Log - debugf logutils.DebugFunc - reportData *report.Data - - contextBuilder *lint.ContextBuilder - goenv *goutil.Env - - fileCache *fsutils.FileCache - lineCache *fsutils.LineCache - - flock *flock.Flock - - exitCode int -} - -func newRunCommand(logger logutils.Log, info BuildInfo) *runCommand { - reportData := &report.Data{} - - c := &runCommand{ - viper: viper.New(), - log: report.NewLogWrapper(logger, reportData), - debugf: logutils.Debug(logutils.DebugKeyExec), - cfg: config.NewDefault(), - reportData: reportData, - buildInfo: info, - } - - runCmd := &cobra.Command{ - Use: "run", - Short: "Lint the code.", - Run: c.execute, - PreRunE: c.preRunE, - PostRun: c.postRun, - PersistentPreRunE: c.persistentPreRunE, - PersistentPostRunE: c.persistentPostRunE, - SilenceUsage: true, - } - - runCmd.SetOut(logutils.StdOut) // use custom output to properly color it in Windows terminals - runCmd.SetErr(logutils.StdErr) - - fs := runCmd.Flags() - fs.SortFlags = false // sort them as they are defined here - - // Only for testing purpose. - // Don't add other flags here. - fs.BoolVar(&c.cfg.InternalCmdTest, "internal-cmd-test", false, - color.GreenString("Option is used only for testing golangci-lint command, don't use it")) - _ = fs.MarkHidden("internal-cmd-test") - - setupConfigFileFlagSet(fs, &c.opts.LoaderOptions) - - setupLintersFlagSet(c.viper, fs) - setupRunFlagSet(c.viper, fs) - setupOutputFlagSet(c.viper, fs) - setupIssuesFlagSet(c.viper, fs) - - setupRunPersistentFlags(runCmd.PersistentFlags(), &c.opts) - - c.cmd = runCmd - - return c -} - -func (c *runCommand) persistentPreRunE(cmd *cobra.Command, args []string) error { - if err := c.startTracing(); err != nil { - return err - } - - c.log.Infof("%s", c.buildInfo.String()) - - loader := config.NewLintersLoader(c.log.Child(logutils.DebugKeyConfigReader), c.viper, cmd.Flags(), c.opts.LoaderOptions, c.cfg, args) - - err := loader.Load(config.LoadOptions{CheckDeprecation: true, Validation: true}) - if err != nil { - return fmt.Errorf("can't load config: %w", err) - } - - if c.cfg.Run.Concurrency == 0 { - // `runtime.GOMAXPROCS` defaults to the value of `runtime.NumCPU`. - backup := runtime.GOMAXPROCS(0) - - // Automatically set GOMAXPROCS to match Linux container CPU quota. - _, err := maxprocs.Set(maxprocs.Logger(c.log.Infof)) - if err != nil { - runtime.GOMAXPROCS(backup) - } - } else { - runtime.GOMAXPROCS(c.cfg.Run.Concurrency) - } - - return nil -} - -func (c *runCommand) persistentPostRunE(_ *cobra.Command, _ []string) error { - if err := c.stopTracing(); err != nil { - return err - } - - os.Exit(c.exitCode) - - return nil -} - -func (c *runCommand) preRunE(_ *cobra.Command, args []string) error { - dbManager, err := lintersdb.NewManager(c.log.Child(logutils.DebugKeyLintersDB), c.cfg, - lintersdb.NewLinterBuilder(), lintersdb.NewPluginModuleBuilder(c.log), lintersdb.NewPluginGoBuilder(c.log)) - if err != nil { - return err - } - - c.dbManager = dbManager - - c.printer, err = printers.NewPrinter(c.log, &c.cfg.Output.Formats, c.reportData, c.cfg.GetBasePath()) - if err != nil { - return err - } - - c.goenv = goutil.NewEnv(c.log.Child(logutils.DebugKeyGoEnv)) - - c.fileCache = fsutils.NewFileCache() - c.lineCache = fsutils.NewLineCache(c.fileCache) - - sw := timeutils.NewStopwatch("pkgcache", c.log.Child(logutils.DebugKeyStopwatch)) - - pkgCache, err := cache.NewCache(sw, c.log.Child(logutils.DebugKeyPkgCache)) - if err != nil { - return fmt.Errorf("failed to build packages cache: %w", err) - } - - guard := load.NewGuard() - - pkgLoader := lint.NewPackageLoader(c.log.Child(logutils.DebugKeyLoader), c.cfg, args, c.goenv, guard) - - c.contextBuilder = lint.NewContextBuilder(c.cfg, pkgLoader, pkgCache, guard) - - if err = initHashSalt(c.log.Child(logutils.DebugKeyGoModSalt), c.buildInfo.Version, c.cfg); err != nil { - return fmt.Errorf("failed to init hash salt: %w", err) - } - - if ok := c.acquireFileLock(); !ok { - return errors.New("parallel golangci-lint is running") - } - - return nil -} - -func (c *runCommand) postRun(_ *cobra.Command, _ []string) { - c.releaseFileLock() -} - -func (c *runCommand) execute(_ *cobra.Command, _ []string) { - needTrackResources := logutils.IsVerbose() || c.opts.PrintResourcesUsage - - trackResourcesEndCh := make(chan struct{}) - - // Note: this defer must be before ctx.cancel defer - defer func() { - // wait until resource tracking finished to print properly - if needTrackResources { - <-trackResourcesEndCh - } - }() - - ctx, cancel := context.WithCancel(context.Background()) - if c.cfg.Run.Timeout > 0 { - ctx, cancel = context.WithTimeout(ctx, c.cfg.Run.Timeout) - } - defer cancel() - - if needTrackResources { - go watchResources(ctx, trackResourcesEndCh, c.log, c.debugf) - } - - if err := c.runAndPrint(ctx); err != nil { - c.log.Errorf("Running error: %s", err) - if c.exitCode == exitcodes.Success { - var exitErr *exitcodes.ExitError - if errors.As(err, &exitErr) { - c.exitCode = exitErr.Code - } else { - c.exitCode = exitcodes.Failure - } - } - } - - c.setupExitCode(ctx) -} - -func (c *runCommand) startTracing() error { - if c.opts.CPUProfilePath != "" { - f, err := os.Create(c.opts.CPUProfilePath) - if err != nil { - return fmt.Errorf("can't create file %s: %w", c.opts.CPUProfilePath, err) - } - if err := pprof.StartCPUProfile(f); err != nil { - return fmt.Errorf("can't start CPU profiling: %w", err) - } - } - - if c.opts.MemProfilePath != "" { - if rate := os.Getenv(envMemProfileRate); rate != "" { - runtime.MemProfileRate, _ = strconv.Atoi(rate) - } - } - - if c.opts.TracePath != "" { - f, err := os.Create(c.opts.TracePath) - if err != nil { - return fmt.Errorf("can't create file %s: %w", c.opts.TracePath, err) - } - if err = trace.Start(f); err != nil { - return fmt.Errorf("can't start tracing: %w", err) - } - } - - return nil -} - -func (c *runCommand) stopTracing() error { - if c.opts.CPUProfilePath != "" { - pprof.StopCPUProfile() - } - - if c.opts.MemProfilePath != "" { - f, err := os.Create(c.opts.MemProfilePath) - if err != nil { - return fmt.Errorf("can't create file %s: %w", c.opts.MemProfilePath, err) - } - - var ms runtime.MemStats - runtime.ReadMemStats(&ms) - printMemStats(&ms, c.log) - - if err := pprof.WriteHeapProfile(f); err != nil { - return fmt.Errorf("can't write heap profile: %w", err) - } - _ = f.Close() - } - - if c.opts.TracePath != "" { - trace.Stop() - } - - return nil -} - -func (c *runCommand) runAndPrint(ctx context.Context) error { - if err := c.goenv.Discover(ctx); err != nil { - c.log.Warnf("Failed to discover go env: %s", err) - } - - if !logutils.HaveDebugTag(logutils.DebugKeyLintersOutput) { - // Don't allow linters and loader to print anything - log.SetOutput(io.Discard) - savedStdout, savedStderr := c.setOutputToDevNull() - defer func() { - os.Stdout, os.Stderr = savedStdout, savedStderr - }() - } - - enabledLintersMap, err := c.dbManager.GetEnabledLintersMap() - if err != nil { - return err - } - - c.printDeprecatedLinterMessages(enabledLintersMap) - - issues, err := c.runAnalysis(ctx) - if err != nil { - return err // XXX: don't lose type - } - - // Fills linters information for the JSON printer. - for _, lc := range c.dbManager.GetAllSupportedLinterConfigs() { - isEnabled := enabledLintersMap[lc.Name()] != nil - c.reportData.AddLinter(lc.Name(), isEnabled) - } - - err = c.printer.Print(issues) - if err != nil { - return err - } - - c.printStats(issues) - - c.setExitCodeIfIssuesFound(issues) - - c.fileCache.PrintStats(c.log) - - return nil -} - -// runAnalysis executes the linters that have been enabled in the configuration. -func (c *runCommand) runAnalysis(ctx context.Context) ([]*result.Issue, error) { - lintersToRun, err := c.dbManager.GetOptimizedLinters() - if err != nil { - return nil, err - } - - lintCtx, err := c.contextBuilder.Build(ctx, c.log.Child(logutils.DebugKeyLintersContext), lintersToRun) - if err != nil { - return nil, fmt.Errorf("context loading failed: %w", err) - } - - runner, err := lint.NewRunner(c.log.Child(logutils.DebugKeyRunner), c.cfg, - c.goenv, c.lineCache, c.fileCache, c.dbManager, lintCtx) - if err != nil { - return nil, err - } - - return runner.Run(ctx, lintersToRun) -} - -func (c *runCommand) setOutputToDevNull() (savedStdout, savedStderr *os.File) { - savedStdout, savedStderr = os.Stdout, os.Stderr - devNull, err := os.Open(os.DevNull) - if err != nil { - c.log.Warnf("Can't open null device %q: %s", os.DevNull, err) - return - } - - os.Stdout, os.Stderr = devNull, devNull - return -} - -func (c *runCommand) setExitCodeIfIssuesFound(issues []*result.Issue) { - if len(issues) != 0 { - c.exitCode = c.cfg.Run.ExitCodeIfIssuesFound - } -} - -func (c *runCommand) printDeprecatedLinterMessages(enabledLinters map[string]*linter.Config) { - if c.cfg.InternalCmdTest || os.Getenv(logutils.EnvTestRun) == "1" { - return - } - - for name, lc := range enabledLinters { - if !lc.IsDeprecated() { - continue - } - - var extra string - if lc.Deprecation.Replacement != "" { - extra = fmt.Sprintf("Replaced by %s.", lc.Deprecation.Replacement) - } - - c.log.Warnf("The linter '%s' is deprecated (since %s) due to: %s %s", name, lc.Deprecation.Since, lc.Deprecation.Message, extra) - - if lc.Deprecation.ConfigSuggestion != nil { - suggestion, err := lc.Deprecation.ConfigSuggestion() - if err != nil { - c.log.Errorf("New configuration suggestion error: %v", err) - } - - if suggestion != "" { - c.log.Warnf("Suggested new configuration:\n%s", suggestion) - } - } - } -} - -func (c *runCommand) printStats(issues []*result.Issue) { - if !c.cfg.Output.ShowStats { - return - } - - if len(issues) == 0 { - c.cmd.Println("0 issues.") - return - } - - stats := map[string]int{} - for idx := range issues { - stats[issues[idx].FromLinter]++ - } - - c.cmd.Printf("%d issues:\n", len(issues)) - - keys := slices.Sorted(maps.Keys(stats)) - - for _, key := range keys { - c.cmd.Printf("* %s: %d\n", key, stats[key]) - } -} - -func (c *runCommand) setupExitCode(ctx context.Context) { - if ctx.Err() != nil { - c.exitCode = exitcodes.Timeout - c.log.Errorf("Timeout exceeded: try increasing it by passing --timeout option") - return - } - - if c.exitCode != exitcodes.Success { - return - } - - needFailOnWarnings := os.Getenv(logutils.EnvTestRun) == "1" || os.Getenv(envFailOnWarnings) == "1" - if needFailOnWarnings && len(c.reportData.Warnings) != 0 { - c.exitCode = exitcodes.WarningInTest - return - } - - if c.reportData.Error != "" { - // it's a case e.g. when typecheck linter couldn't parse and error and just logged it - c.exitCode = exitcodes.ErrorWasLogged - return - } -} - -func (c *runCommand) acquireFileLock() bool { - if c.cfg.Run.AllowParallelRunners { - c.debugf("Parallel runners are allowed, no locking") - return true - } - - lockFile := filepath.Join(os.TempDir(), "golangci-lint.lock") - c.debugf("Locking on file %s...", lockFile) - f := flock.New(lockFile) - const retryDelay = time.Second - - ctx := context.Background() - if !c.cfg.Run.AllowSerialRunners { - const totalTimeout = 5 * time.Second - var cancel context.CancelFunc - ctx, cancel = context.WithTimeout(ctx, totalTimeout) - defer cancel() - } - if ok, _ := f.TryLockContext(ctx, retryDelay); !ok { - return false - } - - c.flock = f - return true -} - -func (c *runCommand) releaseFileLock() { - if c.cfg.Run.AllowParallelRunners { - return - } - - if err := c.flock.Unlock(); err != nil { - c.debugf("Failed to unlock on file: %s", err) - } - if err := os.Remove(c.flock.Path()); err != nil { - c.debugf("Failed to remove lock file: %s", err) - } -} - -func watchResources(ctx context.Context, done chan struct{}, logger logutils.Log, debugf logutils.DebugFunc) { - startedAt := time.Now() - debugf("Started tracking time") - - var maxRSSMB, totalRSSMB float64 - var iterationsCount int - - const intervalMS = 100 - ticker := time.NewTicker(intervalMS * time.Millisecond) - defer ticker.Stop() - - logEveryRecord := os.Getenv(envMemLogEvery) == "1" - const MB = 1024 * 1024 - - track := func() { - var m runtime.MemStats - runtime.ReadMemStats(&m) - - if logEveryRecord { - debugf("Stopping memory tracing iteration, printing ...") - printMemStats(&m, logger) - } - - rssMB := float64(m.Sys) / MB - if rssMB > maxRSSMB { - maxRSSMB = rssMB - } - totalRSSMB += rssMB - iterationsCount++ - } - - for { - track() - - stop := false - select { - case <-ctx.Done(): - stop = true - debugf("Stopped resources tracking") - case <-ticker.C: - } - - if stop { - break - } - } - track() - - avgRSSMB := totalRSSMB / float64(iterationsCount) - - logger.Infof("Memory: %d samples, avg is %.1fMB, max is %.1fMB", - iterationsCount, avgRSSMB, maxRSSMB) - logger.Infof("Execution took %s", time.Since(startedAt)) - close(done) -} - -func setupConfigFileFlagSet(fs *pflag.FlagSet, cfg *config.LoaderOptions) { - fs.StringVarP(&cfg.Config, "config", "c", "", color.GreenString("Read config from file path `PATH`")) - fs.BoolVar(&cfg.NoConfig, "no-config", false, color.GreenString("Don't read config file")) -} - -func setupRunPersistentFlags(fs *pflag.FlagSet, opts *runOptions) { - fs.BoolVar(&opts.PrintResourcesUsage, "print-resources-usage", false, - color.GreenString("Print avg and max memory usage of golangci-lint and total time")) - _ = fs.MarkDeprecated("print-resources-usage", "use --verbose instead") - - fs.StringVar(&opts.CPUProfilePath, "cpu-profile-path", "", color.GreenString("Path to CPU profile output file")) - fs.StringVar(&opts.MemProfilePath, "mem-profile-path", "", color.GreenString("Path to memory profile output file")) - fs.StringVar(&opts.TracePath, "trace-path", "", color.GreenString("Path to trace output file")) -} - -func printMemStats(ms *runtime.MemStats, logger logutils.Log) { - logger.Infof("Mem stats: alloc=%s total_alloc=%s sys=%s "+ - "heap_alloc=%s heap_sys=%s heap_idle=%s heap_released=%s heap_in_use=%s "+ - "stack_in_use=%s stack_sys=%s "+ - "mspan_sys=%s mcache_sys=%s buck_hash_sys=%s gc_sys=%s other_sys=%s "+ - "mallocs_n=%d frees_n=%d heap_objects_n=%d gc_cpu_fraction=%.2f", - formatMemory(ms.Alloc), formatMemory(ms.TotalAlloc), formatMemory(ms.Sys), - formatMemory(ms.HeapAlloc), formatMemory(ms.HeapSys), - formatMemory(ms.HeapIdle), formatMemory(ms.HeapReleased), formatMemory(ms.HeapInuse), - formatMemory(ms.StackInuse), formatMemory(ms.StackSys), - formatMemory(ms.MSpanSys), formatMemory(ms.MCacheSys), formatMemory(ms.BuckHashSys), - formatMemory(ms.GCSys), formatMemory(ms.OtherSys), - ms.Mallocs, ms.Frees, ms.HeapObjects, ms.GCCPUFraction) -} - -func formatMemory(memBytes uint64) string { - const Kb = 1024 - const Mb = Kb * 1024 - - if memBytes < Kb { - return fmt.Sprintf("%db", memBytes) - } - if memBytes < Mb { - return fmt.Sprintf("%dkb", memBytes/Kb) - } - return fmt.Sprintf("%dmb", memBytes/Mb) -} - -// Related to cache. - -func initHashSalt(logger logutils.Log, version string, cfg *config.Config) error { - binSalt, err := computeBinarySalt(version) - if err != nil { - return fmt.Errorf("failed to calculate binary salt: %w", err) - } - - configSalt, err := computeConfigSalt(cfg) - if err != nil { - return fmt.Errorf("failed to calculate config salt: %w", err) - } - - goModSalt, err := computeGoModSalt() - if err != nil { - // NOTE: missing go.mod must be ignored. - logger.Warnf("Failed to calculate go.mod salt: %v", err) - } - - b := bytes.NewBuffer(binSalt) - b.Write(configSalt) - b.WriteString(goModSalt) - - cache.SetSalt(b) - - return nil -} - -func computeBinarySalt(version string) ([]byte, error) { - if version != "" && version != "(devel)" { - return []byte(version), nil - } - - if logutils.HaveDebugTag(logutils.DebugKeyBinSalt) { - return []byte("debug"), nil - } - - p, err := os.Executable() - if err != nil { - return nil, err - } - - f, err := os.Open(p) - if err != nil { - return nil, err - } - - defer f.Close() - - h := sha256.New() - if _, err := io.Copy(h, f); err != nil { - return nil, err - } - - return h.Sum(nil), nil -} - -// computeConfigSalt computes configuration hash. -// We don't hash all config fields to reduce meaningless cache invalidations. -// At least, it has a huge impact on tests speed. -// Fields: `LintersSettings` and `Run.BuildTags`. -func computeConfigSalt(cfg *config.Config) ([]byte, error) { - lintersSettingsBytes, err := yaml.Marshal(cfg.Linters.Settings) - if err != nil { - return nil, fmt.Errorf("failed to JSON marshal config linter settings: %w", err) - } - - configData := bytes.NewBufferString("linters.settings=") - configData.Write(lintersSettingsBytes) - configData.WriteString("\nbuild-tags=%s" + strings.Join(cfg.Run.BuildTags, ",")) - - h := sha256.New() - if _, err := h.Write(configData.Bytes()); err != nil { - return nil, err - } - - return h.Sum(nil), nil -} - -func computeGoModSalt() (string, error) { - values, err := goenv.Get(context.Background(), goenv.GOMOD) - if err != nil { - return "", fmt.Errorf("failed to get goenv: %w", err) - } - - goModPath := filepath.Clean(values[goenv.GOMOD]) - - data, err := os.ReadFile(goModPath) - if err != nil { - return "", fmt.Errorf("failed to read go.mod: %w", err) - } - - sum, err := dirhash.Hash1([]string{goModPath}, func(string) (io.ReadCloser, error) { - return io.NopCloser(bytes.NewReader(data)), nil - }) - if err != nil { - return "", fmt.Errorf("failed to compute go.sum: %w", err) - } - - return sum, nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/version.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/version.go deleted file mode 100644 index c8057a86c1..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/commands/version.go +++ /dev/null @@ -1,91 +0,0 @@ -package commands - -import ( - "encoding/json" - "fmt" - "io" - "os" - "runtime/debug" - - "github.com/fatih/color" - "github.com/spf13/cobra" -) - -type BuildInfo struct { - GoVersion string `json:"goVersion"` - Version string `json:"version"` - Commit string `json:"commit"` - Date string `json:"date"` - BuildInfo *debug.BuildInfo `json:"buildInfo,omitempty"` -} - -func (b BuildInfo) String() string { - return fmt.Sprintf("golangci-lint has version %s built with %s from %s on %s", - b.Version, b.GoVersion, b.Commit, b.Date) -} - -type versionOptions struct { - Debug bool - JSON bool - Short bool -} - -type versionCommand struct { - cmd *cobra.Command - opts versionOptions - - info BuildInfo -} - -func newVersionCommand(info BuildInfo) *versionCommand { - c := &versionCommand{info: info} - - versionCmd := &cobra.Command{ - Use: "version", - Short: "Display the golangci-lint version.", - Args: cobra.NoArgs, - ValidArgsFunction: cobra.NoFileCompletions, - RunE: c.execute, - } - - fs := versionCmd.Flags() - fs.SortFlags = false // sort them as they are defined here - - fs.BoolVar(&c.opts.Debug, "debug", false, color.GreenString("Add build information")) - fs.BoolVar(&c.opts.JSON, "json", false, color.GreenString("Display as JSON")) - fs.BoolVar(&c.opts.Short, "short", false, color.GreenString("Display only the version number")) - - c.cmd = versionCmd - - return c -} - -func (c *versionCommand) execute(_ *cobra.Command, _ []string) error { - var info *debug.BuildInfo - if c.opts.Debug { - info, _ = debug.ReadBuildInfo() - } - - switch { - case c.opts.JSON: - c.info.BuildInfo = info - - return json.NewEncoder(os.Stdout).Encode(c.info) - case c.opts.Short: - fmt.Println(c.info.Version) - - return nil - - default: - if info != nil { - fmt.Println(info.String()) - } - - return printVersion(os.Stdout, c.info) - } -} - -func printVersion(w io.Writer, info BuildInfo) error { - _, err := fmt.Fprintln(w, info.String()) - return err -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/base_loader.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/base_loader.go deleted file mode 100644 index 9ad332ac23..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/base_loader.go +++ /dev/null @@ -1,232 +0,0 @@ -package config - -import ( - "errors" - "fmt" - "os" - "path/filepath" - "slices" - - "github.com/go-viper/mapstructure/v2" - "github.com/mitchellh/go-homedir" - "github.com/spf13/viper" - - "github.com/golangci/golangci-lint/v2/pkg/exitcodes" - "github.com/golangci/golangci-lint/v2/pkg/fsutils" - "github.com/golangci/golangci-lint/v2/pkg/logutils" -) - -type BaseConfig interface { - IsInternalTest() bool - SetConfigDir(dir string) -} - -type BaseLoader struct { - opts LoaderOptions - - viper *viper.Viper - - log logutils.Log - - cfg BaseConfig - args []string -} - -func NewBaseLoader(log logutils.Log, v *viper.Viper, opts LoaderOptions, cfg BaseConfig, args []string) *BaseLoader { - return &BaseLoader{ - opts: opts, - viper: v, - log: log, - cfg: cfg, - args: args, - } -} - -func (l *BaseLoader) Load() error { - err := l.setConfigFile() - if err != nil { - return err - } - - err = l.parseConfig() - if err != nil { - return err - } - - return nil -} - -func (l *BaseLoader) setConfigFile() error { - configFile, err := l.evaluateOptions() - if err != nil { - if errors.Is(err, errConfigDisabled) { - return nil - } - - return fmt.Errorf("can't parse --config option: %w", err) - } - - if configFile != "" { - l.viper.SetConfigFile(configFile) - - // Assume YAML if the file has no extension. - if filepath.Ext(configFile) == "" { - l.viper.SetConfigType("yaml") - } - } else { - l.setupConfigFileSearch() - } - - return nil -} - -func (l *BaseLoader) evaluateOptions() (string, error) { - if l.opts.NoConfig && l.opts.Config != "" { - return "", errors.New("can't combine option --config and --no-config") - } - - if l.opts.NoConfig { - return "", errConfigDisabled - } - - configFile, err := homedir.Expand(l.opts.Config) - if err != nil { - return "", errors.New("failed to expand configuration path") - } - - return configFile, nil -} - -func (l *BaseLoader) setupConfigFileSearch() { - l.viper.SetConfigName(".golangci") - - configSearchPaths := l.getConfigSearchPaths() - - l.log.Infof("Config search paths: %s", configSearchPaths) - - for _, p := range configSearchPaths { - l.viper.AddConfigPath(p) - } -} - -func (l *BaseLoader) getConfigSearchPaths() []string { - firstArg := "./..." - if len(l.args) > 0 { - firstArg = l.args[0] - } - - absPath, err := filepath.Abs(firstArg) - if err != nil { - l.log.Warnf("Can't make abs path for %q: %s", firstArg, err) - absPath = filepath.Clean(firstArg) - } - - // start from it - var currentDir string - if fsutils.IsDir(absPath) { - currentDir = absPath - } else { - currentDir = filepath.Dir(absPath) - } - - // find all dirs from it up to the root - searchPaths := []string{"./"} - - for { - searchPaths = append(searchPaths, currentDir) - - parent := filepath.Dir(currentDir) - if currentDir == parent || parent == "" { - break - } - - currentDir = parent - } - - // find home directory for global config - if home, err := homedir.Dir(); err != nil { - l.log.Warnf("Can't get user's home directory: %v", err) - } else if !slices.Contains(searchPaths, home) { - searchPaths = append(searchPaths, home) - } - - return searchPaths -} - -func (l *BaseLoader) parseConfig() error { - if err := l.viper.ReadInConfig(); err != nil { - var configFileNotFoundError viper.ConfigFileNotFoundError - if errors.As(err, &configFileNotFoundError) { - // Load configuration from flags only. - err = l.viper.Unmarshal(l.cfg, customDecoderHook()) - if err != nil { - return fmt.Errorf("can't unmarshal config by viper (flags): %w", err) - } - - return nil - } - - return fmt.Errorf("can't read viper config: %w", err) - } - - err := l.setConfigDir() - if err != nil { - return err - } - - // Load configuration from all sources (flags, file). - if err := l.viper.Unmarshal(l.cfg, customDecoderHook()); err != nil { - return fmt.Errorf("can't unmarshal config by viper (flags, file): %w", err) - } - - if l.cfg.IsInternalTest() { // just for testing purposes: to detect config file usage - _, _ = fmt.Fprintln(logutils.StdOut, "test") - os.Exit(exitcodes.Success) - } - - return nil -} - -func (l *BaseLoader) setConfigDir() error { - usedConfigFile := l.viper.ConfigFileUsed() - if usedConfigFile == "" { - return nil - } - - if usedConfigFile == os.Stdin.Name() { - usedConfigFile = "" - l.log.Infof("Reading config file stdin") - } else { - var err error - usedConfigFile, err = fsutils.ShortestRelPath(usedConfigFile, "") - if err != nil { - l.log.Warnf("Can't pretty print config file path: %v", err) - } - - l.log.Infof("Used config file %s", usedConfigFile) - } - - usedConfigDir, err := filepath.Abs(filepath.Dir(usedConfigFile)) - if err != nil { - return errors.New("can't get config directory") - } - - l.cfg.SetConfigDir(usedConfigDir) - - return nil -} - -func customDecoderHook() viper.DecoderConfigOption { - return viper.DecodeHook(DecodeHookFunc()) -} - -func DecodeHookFunc() mapstructure.DecodeHookFunc { - return mapstructure.ComposeDecodeHookFunc( - // Default hooks (https://github.com/spf13/viper/blob/518241257478c557633ab36e474dfcaeb9a3c623/viper.go#L135-L138). - mapstructure.StringToTimeDurationHookFunc(), - mapstructure.StringToSliceHookFunc(","), - - // Needed for forbidigo, and output.formats. - mapstructure.TextUnmarshallerHookFunc(), - ) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/base_rule.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/base_rule.go deleted file mode 100644 index 3a82865046..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/base_rule.go +++ /dev/null @@ -1,75 +0,0 @@ -package config - -import ( - "errors" - "fmt" - "regexp" -) - -type BaseRule struct { - Linters []string `mapstructure:"linters"` - Path string `mapstructure:"path"` - PathExcept string `mapstructure:"path-except"` - Text string `mapstructure:"text"` - Source string `mapstructure:"source"` - - // For compatibility with exclude-use-default/include. - InternalReference string `mapstructure:"-"` -} - -func (b *BaseRule) Validate(minConditionsCount int) error { - if err := validateOptionalRegex(b.Path); err != nil { - return fmt.Errorf("invalid path regex: %w", err) - } - - if err := validateOptionalRegex(b.PathExcept); err != nil { - return fmt.Errorf("invalid path-except regex: %w", err) - } - - if err := validateOptionalRegex(b.Text); err != nil { - return fmt.Errorf("invalid text regex: %w", err) - } - - if err := validateOptionalRegex(b.Source); err != nil { - return fmt.Errorf("invalid source regex: %w", err) - } - - if b.Path != "" && b.PathExcept != "" { - return errors.New("path and path-except should not be set at the same time") - } - - nonBlank := 0 - if len(b.Linters) > 0 { - nonBlank++ - } - - // Filtering by path counts as one condition, regardless how it is done (one or both). - // Otherwise, a rule with Path and PathExcept set would pass validation - // whereas before the introduction of path-except that wouldn't have been precise enough. - if b.Path != "" || b.PathExcept != "" { - nonBlank++ - } - - if b.Text != "" { - nonBlank++ - } - - if b.Source != "" { - nonBlank++ - } - - if nonBlank < minConditionsCount { - return fmt.Errorf("at least %d of (text, source, path[-except], linters) should be set", minConditionsCount) - } - - return nil -} - -func validateOptionalRegex(value string) error { - if value == "" { - return nil - } - - _, err := regexp.Compile(value) - return err -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/config.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/config.go deleted file mode 100644 index 6d7586621d..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/config.go +++ /dev/null @@ -1,201 +0,0 @@ -package config - -import ( - "cmp" - "context" - "fmt" - "os" - "path/filepath" - "slices" - "strings" - - hcversion "github.com/hashicorp/go-version" - "github.com/ldez/grignotin/goenv" - "github.com/ldez/grignotin/gomod" - "golang.org/x/mod/modfile" - - "github.com/golangci/golangci-lint/v2/pkg/logutils" -) - -// defaultGoVersion the value should be "oldstable" - 1. -// If the current stable version is 1.24 then 1.23 - 1 = 1.22. -const defaultGoVersion = "1.22" - -// Config encapsulates the config data specified in the golangci-lint YAML config file. -type Config struct { - cfgDir string // Path to the directory containing golangci-lint config file. - basePath string // Path the root directory related to [Run.RelativePathMode]. - - Version string `mapstructure:"version"` - - Run Run `mapstructure:"run"` - - Output Output `mapstructure:"output"` - - Linters Linters `mapstructure:"linters"` - - Issues Issues `mapstructure:"issues"` - Severity Severity `mapstructure:"severity"` - - Formatters Formatters `mapstructure:"formatters"` - - InternalCmdTest bool // Option is used only for testing golangci-lint command, don't use it - InternalTest bool // Option is used only for testing golangci-lint code, don't use it -} - -// GetConfigDir returns the directory that contains golangci-lint config file. -func (c *Config) GetConfigDir() string { - return c.cfgDir -} - -// SetConfigDir sets the path to directory that contains golangci-lint config file. -func (c *Config) SetConfigDir(dir string) { - c.cfgDir = dir -} - -func (c *Config) GetBasePath() string { - return c.basePath -} - -func (c *Config) IsInternalTest() bool { - return c.InternalTest -} - -func (c *Config) Validate() error { - validators := []func() error{ - c.Run.Validate, - c.Output.Validate, - c.Linters.Validate, - c.Formatters.Validate, - c.Severity.Validate, - } - - for _, v := range validators { - if err := v(); err != nil { - return err - } - } - - return nil -} - -func NewDefault() *Config { - return &Config{ - Linters: Linters{ - Settings: defaultLintersSettings, - }, - Formatters: Formatters{ - Settings: defaultFormatterSettings, - }, - } -} - -func IsGoGreaterThanOrEqual(current, limit string) bool { - v1, err := hcversion.NewVersion(strings.TrimPrefix(current, "go")) - if err != nil { - return false - } - - l, err := hcversion.NewVersion(limit) - if err != nil { - return false - } - - return v1.GreaterThanOrEqual(l) -} - -func detectGoVersion(ctx context.Context, log logutils.Log) string { - return cmp.Or(detectGoVersionFromGoMod(ctx, log), defaultGoVersion) -} - -// detectGoVersionFromGoMod tries to get Go version from go.mod. -// It returns `toolchain` version if present, -// else it returns `go` version if present, -// else it returns `GOVERSION` version if present, -// else it returns empty. -func detectGoVersionFromGoMod(ctx context.Context, log logutils.Log) string { - values, err := goenv.Get(ctx, goenv.GOMOD, goenv.GOVERSION) - if err != nil { - values = map[string]string{ - goenv.GOMOD: detectGoModFallback(ctx), - } - } - - if values[goenv.GOMOD] == "" { - return parseGoVersion(values[goenv.GOVERSION]) - } - - file, err := parseGoMod(values[goenv.GOMOD]) - if err != nil { - return parseGoVersion(values[goenv.GOVERSION]) - } - - if file.Module != nil { - log.Infof("Module name %q", file.Module.Mod.Path) - } - - // The toolchain exists only if 'toolchain' version > 'go' version. - // If 'toolchain' version <= 'go' version, `go mod tidy` will remove 'toolchain' version from go.mod. - if file.Toolchain != nil && file.Toolchain.Name != "" { - return parseGoVersion(file.Toolchain.Name) - } - - if file.Go != nil && file.Go.Version != "" { - return file.Go.Version - } - - return parseGoVersion(values[goenv.GOVERSION]) -} - -func parseGoVersion(v string) string { - raw := strings.TrimPrefix(v, "go") - - // prerelease version (ex: go1.24rc1) - idx := strings.IndexFunc(raw, func(r rune) bool { - return (r < '0' || r > '9') && r != '.' - }) - - if idx != -1 { - raw = raw[:idx] - } - - return raw -} - -func parseGoMod(goMod string) (*modfile.File, error) { - raw, err := os.ReadFile(filepath.Clean(goMod)) - if err != nil { - return nil, fmt.Errorf("reading go.mod file: %w", err) - } - - return modfile.Parse("go.mod", raw, nil) -} - -func detectGoModFallback(ctx context.Context) string { - info, err := gomod.GetModuleInfo(ctx) - if err != nil { - return "" - } - - wd, err := os.Getwd() - if err != nil { - return "" - } - - slices.SortFunc(info, func(a, b gomod.ModInfo) int { - return cmp.Compare(len(b.Path), len(a.Path)) - }) - - goMod := info[0] - for _, m := range info { - if !strings.HasPrefix(wd, m.Dir) { - continue - } - - goMod = m - - break - } - - return goMod.GoMod -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/formatters.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/formatters.go deleted file mode 100644 index e1723ac101..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/formatters.go +++ /dev/null @@ -1,28 +0,0 @@ -package config - -import ( - "fmt" - "slices" -) - -type Formatters struct { - Enable []string `mapstructure:"enable"` - Settings FormatterSettings `mapstructure:"settings"` - Exclusions FormatterExclusions `mapstructure:"exclusions"` -} - -func (f *Formatters) Validate() error { - for _, n := range f.Enable { - if !slices.Contains(getAllFormatterNames(), n) { - return fmt.Errorf("%s is not a formatter", n) - } - } - - return nil -} - -type FormatterExclusions struct { - Generated string `mapstructure:"generated"` - Paths []string `mapstructure:"paths"` - WarnUnused bool `mapstructure:"warn-unused"` -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/formatters_settings.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/formatters_settings.go deleted file mode 100644 index d99354ba3f..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/formatters_settings.go +++ /dev/null @@ -1,61 +0,0 @@ -package config - -var defaultFormatterSettings = FormatterSettings{ - GoFmt: GoFmtSettings{ - Simplify: true, - }, - Gci: GciSettings{ - Sections: []string{"standard", "default"}, - }, - GoLines: GoLinesSettings{ - MaxLen: 100, - TabLen: 4, - ReformatTags: true, - ChainSplitDots: true, - }, -} - -type FormatterSettings struct { - Gci GciSettings `mapstructure:"gci"` - GoFmt GoFmtSettings `mapstructure:"gofmt"` - GoFumpt GoFumptSettings `mapstructure:"gofumpt"` - GoImports GoImportsSettings `mapstructure:"goimports"` - GoLines GoLinesSettings `mapstructure:"golines"` -} - -type GciSettings struct { - Sections []string `mapstructure:"sections"` - NoInlineComments bool `mapstructure:"no-inline-comments"` - NoPrefixComments bool `mapstructure:"no-prefix-comments"` - CustomOrder bool `mapstructure:"custom-order"` - NoLexOrder bool `mapstructure:"no-lex-order"` -} - -type GoFmtSettings struct { - Simplify bool `mapstructure:"simplify"` - RewriteRules []GoFmtRewriteRule `mapstructure:"rewrite-rules"` -} - -type GoFmtRewriteRule struct { - Pattern string `mapstructure:"pattern"` - Replacement string `mapstructure:"replacement"` -} - -type GoFumptSettings struct { - ModulePath string `mapstructure:"module-path"` - ExtraRules bool `mapstructure:"extra-rules"` - - LangVersion string `mapstructure:"-"` -} - -type GoImportsSettings struct { - LocalPrefixes []string `mapstructure:"local-prefixes"` -} - -type GoLinesSettings struct { - MaxLen int `mapstructure:"max-len"` - TabLen int `mapstructure:"tab-len"` - ShortenComments bool `mapstructure:"shorten-comments"` - ReformatTags bool `mapstructure:"reformat-tags"` - ChainSplitDots bool `mapstructure:"chain-split-dots"` -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/issues.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/issues.go deleted file mode 100644 index 5dc630b001..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/issues.go +++ /dev/null @@ -1,15 +0,0 @@ -package config - -type Issues struct { - MaxIssuesPerLinter int `mapstructure:"max-issues-per-linter"` - MaxSameIssues int `mapstructure:"max-same-issues"` - UniqByLine bool `mapstructure:"uniq-by-line"` - - DiffFromRevision string `mapstructure:"new-from-rev"` - DiffFromMergeBase string `mapstructure:"new-from-merge-base"` - DiffPatchFilePath string `mapstructure:"new-from-patch"` - WholeFiles bool `mapstructure:"whole-files"` - Diff bool `mapstructure:"new"` - - NeedFix bool `mapstructure:"fix"` -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/linters.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/linters.go deleted file mode 100644 index 2669f2e647..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/linters.go +++ /dev/null @@ -1,53 +0,0 @@ -package config - -import ( - "fmt" - "slices" -) - -const ( - GroupStandard = "standard" - GroupAll = "all" - GroupNone = "none" - GroupFast = "fast" -) - -type Linters struct { - Default string `mapstructure:"default"` - Enable []string `mapstructure:"enable"` - Disable []string `mapstructure:"disable"` - FastOnly bool `mapstructure:"fast-only"` // Flag only option. - - Settings LintersSettings `mapstructure:"settings"` - - Exclusions LinterExclusions `mapstructure:"exclusions"` -} - -func (l *Linters) Validate() error { - validators := []func() error{ - l.Exclusions.Validate, - l.validateNoFormatters, - } - - for _, v := range validators { - if err := v(); err != nil { - return err - } - } - - return nil -} - -func (l *Linters) validateNoFormatters() error { - for _, n := range slices.Concat(l.Enable, l.Disable) { - if slices.Contains(getAllFormatterNames(), n) { - return fmt.Errorf("%s is a formatter", n) - } - } - - return nil -} - -func getAllFormatterNames() []string { - return []string{"gci", "gofmt", "gofumpt", "goimports", "golines", "swaggo"} -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/linters_exclusions.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/linters_exclusions.go deleted file mode 100644 index 57d08b483e..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/linters_exclusions.go +++ /dev/null @@ -1,61 +0,0 @@ -package config - -import ( - "fmt" - "slices" -) - -const ( - GeneratedModeLax = "lax" - GeneratedModeStrict = "strict" - GeneratedModeDisable = "disable" -) - -const ( - ExclusionPresetComments = "comments" - ExclusionPresetStdErrorHandling = "std-error-handling" - ExclusionPresetCommonFalsePositives = "common-false-positives" - ExclusionPresetLegacy = "legacy" -) - -const excludeRuleMinConditionsCount = 2 - -type LinterExclusions struct { - Generated string `mapstructure:"generated"` - WarnUnused bool `mapstructure:"warn-unused"` - Presets []string `mapstructure:"presets"` - Rules []ExcludeRule `mapstructure:"rules"` - Paths []string `mapstructure:"paths"` - PathsExcept []string `mapstructure:"paths-except"` -} - -func (e *LinterExclusions) Validate() error { - for i, rule := range e.Rules { - if err := rule.Validate(); err != nil { - return fmt.Errorf("error in exclude rule #%d: %w", i, err) - } - } - - allPresets := []string{ - ExclusionPresetComments, - ExclusionPresetStdErrorHandling, - ExclusionPresetCommonFalsePositives, - ExclusionPresetLegacy, - } - - for _, preset := range e.Presets { - if !slices.Contains(allPresets, preset) { - return fmt.Errorf("invalid preset: %s", preset) - } - } - - return nil -} - -type ExcludeRule struct { - BaseRule `mapstructure:",squash"` -} - -func (e *ExcludeRule) Validate() error { - return e.BaseRule.Validate(excludeRuleMinConditionsCount) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/linters_settings.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/linters_settings.go deleted file mode 100644 index ba60dd2c63..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/linters_settings.go +++ /dev/null @@ -1,1124 +0,0 @@ -package config - -import ( - "errors" - "fmt" - "runtime" -) - -var defaultLintersSettings = LintersSettings{ - FormatterSettings: defaultFormatterSettings, - - Asasalint: AsasalintSettings{ - UseBuiltinExclusions: true, - }, - Decorder: DecorderSettings{ - DecOrder: []string{"type", "const", "var", "func"}, - DisableDecNumCheck: true, - DisableDecOrderCheck: true, - DisableInitFuncFirstCheck: true, - }, - Dogsled: DogsledSettings{ - MaxBlankIdentifiers: 2, - }, - Dupl: DuplSettings{ - Threshold: 150, - }, - EmbeddedStructFieldCheck: EmbeddedStructFieldCheckSettings{ - EmptyLine: true, - }, - ErrorLint: ErrorLintSettings{ - Errorf: true, - ErrorfMulti: true, - Asserts: true, - Comparison: true, - }, - Exhaustive: ExhaustiveSettings{ - Check: []string{"switch"}, - DefaultSignifiesExhaustive: false, - IgnoreEnumMembers: "", - PackageScopeOnly: false, - ExplicitExhaustiveMap: false, - ExplicitExhaustiveSwitch: false, - }, - Forbidigo: ForbidigoSettings{ - ExcludeGodocExamples: true, - }, - FuncOrder: FuncOrderSettings{ - Constructor: true, - StructMethod: true, - }, - Funlen: FunlenSettings{ - IgnoreComments: true, - }, - GoChecksumType: GoChecksumTypeSettings{ - DefaultSignifiesExhaustive: true, - }, - Gocognit: GocognitSettings{ - MinComplexity: 30, - }, - Goconst: GoConstSettings{ - MatchWithConstants: true, - MinStringLen: 3, - MinOccurrencesCount: 3, - NumberMin: 3, - NumberMax: 3, - IgnoreCalls: true, - }, - Gocritic: GoCriticSettings{ - SettingsPerCheck: map[string]GoCriticCheckSettings{}, - }, - Gocyclo: GoCycloSettings{ - MinComplexity: 30, - }, - Godox: GodoxSettings{ - Keywords: []string{}, - }, - Godot: GodotSettings{ - Scope: "declarations", - Period: true, - }, - Gosec: GoSecSettings{ - Concurrency: runtime.NumCPU(), - }, - Gosmopolitan: GosmopolitanSettings{ - AllowTimeLocal: false, - EscapeHatches: []string{}, - WatchForScripts: []string{"Han"}, - }, - Inamedparam: INamedParamSettings{ - SkipSingleParam: false, - }, - InterfaceBloat: InterfaceBloatSettings{ - Max: 10, - }, - Lll: LllSettings{ - LineLength: 120, - TabWidth: 1, - }, - LoggerCheck: LoggerCheckSettings{ - Kitlog: true, - Klog: true, - Logr: true, - Slog: true, - Zap: true, - RequireStringKey: false, - NoPrintfLike: false, - Rules: nil, - }, - MaintIdx: MaintIdxSettings{ - Under: 20, - }, - Nakedret: NakedretSettings{ - MaxFuncLines: 30, - }, - Nestif: NestifSettings{ - MinComplexity: 5, - }, - NoLintLint: NoLintLintSettings{ - RequireExplanation: false, - RequireSpecific: false, - AllowUnused: false, - }, - PerfSprint: PerfSprintSettings{ - IntegerFormat: true, - IntConversion: true, - ErrorFormat: true, - ErrError: false, - ErrorF: true, - StringFormat: true, - SprintF1: true, - StrConcat: true, - BoolFormat: true, - HexFormat: true, - ConcatLoop: true, - }, - Prealloc: PreallocSettings{ - Simple: true, - RangeLoops: true, - ForLoops: false, - }, - Predeclared: PredeclaredSettings{ - Qualified: false, - }, - SlogLint: SlogLintSettings{ - NoMixedArgs: true, - KVOnly: false, - AttrOnly: false, - NoGlobal: "", - Context: "", - StaticMsg: false, - NoRawKeys: false, - KeyNamingCase: "", - ForbiddenKeys: nil, - ArgsOnSepLines: false, - }, - TagAlign: TagAlignSettings{ - Align: true, - Sort: true, - Order: nil, - Strict: false, - }, - Testpackage: TestpackageSettings{ - SkipRegexp: `(export|internal)_test\.go`, - AllowPackages: []string{"main"}, - }, - Unqueryvet: UnqueryvetSettings{ - CheckSQLBuilders: true, - }, - Unused: UnusedSettings{ - FieldWritesAreUses: true, - PostStatementsAreReads: false, - ExportedFieldsAreUsed: true, - ParametersAreUsed: true, - LocalVariablesAreUsed: true, - GeneratedIsUsed: true, - }, - UseStdlibVars: UseStdlibVarsSettings{ - HTTPMethod: true, - HTTPStatusCode: true, - }, - UseTesting: UseTestingSettings{ - ContextBackground: false, - ContextTodo: false, - OSChdir: true, - OSMkdirTemp: true, - OSSetenv: true, - OSTempDir: false, - OSCreateTemp: true, - }, - Varnamelen: VarnamelenSettings{ - MaxDistance: 5, - MinNameLength: 3, - }, - WSL: WSLv4Settings{ - StrictAppend: true, - AllowAssignAndCallCuddle: true, - AllowAssignAndAnythingCuddle: false, - AllowMultiLineAssignCuddle: true, - ForceCaseTrailingWhitespaceLimit: 0, - AllowTrailingComment: false, - AllowSeparatedLeadingComment: false, - AllowCuddleDeclaration: false, - AllowCuddleWithCalls: []string{"Lock", "RLock"}, - AllowCuddleWithRHS: []string{"Unlock", "RUnlock"}, - AllowCuddleUsedInBlock: false, - ForceCuddleErrCheckAndAssign: false, - ErrorVariableNames: []string{"err"}, - ForceExclusiveShortDeclarations: false, - }, - WSLv5: WSLv5Settings{ - AllowFirstInBlock: true, - AllowWholeBlock: false, - BranchMaxLines: 2, - CaseMaxLines: 0, - Default: "default", - Enable: nil, - Disable: nil, - }, -} - -type LintersSettings struct { - FormatterSettings `mapstructure:"-"` - - Asasalint AsasalintSettings `mapstructure:"asasalint"` - BiDiChk BiDiChkSettings `mapstructure:"bidichk"` - CopyLoopVar CopyLoopVarSettings `mapstructure:"copyloopvar"` - Cyclop CyclopSettings `mapstructure:"cyclop"` - Decorder DecorderSettings `mapstructure:"decorder"` - Depguard DepGuardSettings `mapstructure:"depguard"` - Dogsled DogsledSettings `mapstructure:"dogsled"` - Dupl DuplSettings `mapstructure:"dupl"` - DupWord DupWordSettings `mapstructure:"dupword"` - EmbeddedStructFieldCheck EmbeddedStructFieldCheckSettings `mapstructure:"embeddedstructfieldcheck"` - Errcheck ErrcheckSettings `mapstructure:"errcheck"` - ErrChkJSON ErrChkJSONSettings `mapstructure:"errchkjson"` - ErrorLint ErrorLintSettings `mapstructure:"errorlint"` - Exhaustive ExhaustiveSettings `mapstructure:"exhaustive"` - Exhaustruct ExhaustructSettings `mapstructure:"exhaustruct"` - Fatcontext FatcontextSettings `mapstructure:"fatcontext"` - Forbidigo ForbidigoSettings `mapstructure:"forbidigo"` - FuncOrder FuncOrderSettings `mapstructure:"funcorder"` - Funlen FunlenSettings `mapstructure:"funlen"` - GinkgoLinter GinkgoLinterSettings `mapstructure:"ginkgolinter"` - Gocognit GocognitSettings `mapstructure:"gocognit"` - GoChecksumType GoChecksumTypeSettings `mapstructure:"gochecksumtype"` - Goconst GoConstSettings `mapstructure:"goconst"` - Gocritic GoCriticSettings `mapstructure:"gocritic"` - Gocyclo GoCycloSettings `mapstructure:"gocyclo"` - Godoclint GodoclintSettings `mapstructure:"godoclint"` - Godot GodotSettings `mapstructure:"godot"` - Godox GodoxSettings `mapstructure:"godox"` - Goheader GoHeaderSettings `mapstructure:"goheader"` - GoModDirectives GoModDirectivesSettings `mapstructure:"gomoddirectives"` - Gomodguard GoModGuardSettings `mapstructure:"gomodguard"` - Gosec GoSecSettings `mapstructure:"gosec"` - Gosmopolitan GosmopolitanSettings `mapstructure:"gosmopolitan"` - Unqueryvet UnqueryvetSettings `mapstructure:"unqueryvet"` - Govet GovetSettings `mapstructure:"govet"` - Grouper GrouperSettings `mapstructure:"grouper"` - Iface IfaceSettings `mapstructure:"iface"` - ImportAs ImportAsSettings `mapstructure:"importas"` - Inamedparam INamedParamSettings `mapstructure:"inamedparam"` - Ineffassign IneffassignSettings `mapstructure:"ineffassign"` - InterfaceBloat InterfaceBloatSettings `mapstructure:"interfacebloat"` - IotaMixing IotaMixingSettings `mapstructure:"iotamixing"` - Ireturn IreturnSettings `mapstructure:"ireturn"` - Lll LllSettings `mapstructure:"lll"` - LoggerCheck LoggerCheckSettings `mapstructure:"loggercheck"` - MaintIdx MaintIdxSettings `mapstructure:"maintidx"` - Makezero MakezeroSettings `mapstructure:"makezero"` - Misspell MisspellSettings `mapstructure:"misspell"` - Mnd MndSettings `mapstructure:"mnd"` - Modernize ModernizeSettings `mapstructure:"modernize"` - MustTag MustTagSettings `mapstructure:"musttag"` - Nakedret NakedretSettings `mapstructure:"nakedret"` - Nestif NestifSettings `mapstructure:"nestif"` - NilNil NilNilSettings `mapstructure:"nilnil"` - Nlreturn NlreturnSettings `mapstructure:"nlreturn"` - NoLintLint NoLintLintSettings `mapstructure:"nolintlint"` - NoNamedReturns NoNamedReturnsSettings `mapstructure:"nonamedreturns"` - ParallelTest ParallelTestSettings `mapstructure:"paralleltest"` - PerfSprint PerfSprintSettings `mapstructure:"perfsprint"` - Prealloc PreallocSettings `mapstructure:"prealloc"` - Predeclared PredeclaredSettings `mapstructure:"predeclared"` - Promlinter PromlinterSettings `mapstructure:"promlinter"` - ProtoGetter ProtoGetterSettings `mapstructure:"protogetter"` - Reassign ReassignSettings `mapstructure:"reassign"` - Recvcheck RecvcheckSettings `mapstructure:"recvcheck"` - Revive ReviveSettings `mapstructure:"revive"` - RowsErrCheck RowsErrCheckSettings `mapstructure:"rowserrcheck"` - SlogLint SlogLintSettings `mapstructure:"sloglint"` - Spancheck SpancheckSettings `mapstructure:"spancheck"` - Staticcheck StaticCheckSettings `mapstructure:"staticcheck"` - TagAlign TagAlignSettings `mapstructure:"tagalign"` - Tagliatelle TagliatelleSettings `mapstructure:"tagliatelle"` - Testifylint TestifylintSettings `mapstructure:"testifylint"` - Testpackage TestpackageSettings `mapstructure:"testpackage"` - Thelper ThelperSettings `mapstructure:"thelper"` - Unconvert UnconvertSettings `mapstructure:"unconvert"` - Unparam UnparamSettings `mapstructure:"unparam"` - Unused UnusedSettings `mapstructure:"unused"` - UseStdlibVars UseStdlibVarsSettings `mapstructure:"usestdlibvars"` - UseTesting UseTestingSettings `mapstructure:"usetesting"` - Varnamelen VarnamelenSettings `mapstructure:"varnamelen"` - Whitespace WhitespaceSettings `mapstructure:"whitespace"` - Wrapcheck WrapcheckSettings `mapstructure:"wrapcheck"` - WSL WSLv4Settings `mapstructure:"wsl"` // Deprecated: use WSLv5 instead. - WSLv5 WSLv5Settings `mapstructure:"wsl_v5"` - - Custom map[string]CustomLinterSettings `mapstructure:"custom"` -} - -func (s *LintersSettings) Validate() error { - if err := s.Govet.Validate(); err != nil { - return err - } - - for name, settings := range s.Custom { - if err := settings.Validate(); err != nil { - return fmt.Errorf("custom linter %q: %w", name, err) - } - } - - return nil -} - -type AsasalintSettings struct { - Exclude []string `mapstructure:"exclude"` - UseBuiltinExclusions bool `mapstructure:"use-builtin-exclusions"` -} - -type BiDiChkSettings struct { - LeftToRightEmbedding bool `mapstructure:"left-to-right-embedding"` - RightToLeftEmbedding bool `mapstructure:"right-to-left-embedding"` - PopDirectionalFormatting bool `mapstructure:"pop-directional-formatting"` - LeftToRightOverride bool `mapstructure:"left-to-right-override"` - RightToLeftOverride bool `mapstructure:"right-to-left-override"` - LeftToRightIsolate bool `mapstructure:"left-to-right-isolate"` - RightToLeftIsolate bool `mapstructure:"right-to-left-isolate"` - FirstStrongIsolate bool `mapstructure:"first-strong-isolate"` - PopDirectionalIsolate bool `mapstructure:"pop-directional-isolate"` -} - -type CopyLoopVarSettings struct { - CheckAlias bool `mapstructure:"check-alias"` -} - -type CyclopSettings struct { - MaxComplexity int `mapstructure:"max-complexity"` - PackageAverage float64 `mapstructure:"package-average"` -} - -type DepGuardSettings struct { - Rules map[string]*DepGuardList `mapstructure:"rules"` -} - -type DepGuardList struct { - ListMode string `mapstructure:"list-mode"` - Files []string `mapstructure:"files"` - Allow []string `mapstructure:"allow"` - Deny []DepGuardDeny `mapstructure:"deny"` -} - -type DepGuardDeny struct { - Pkg string `mapstructure:"pkg"` - Desc string `mapstructure:"desc"` -} - -type DecorderSettings struct { - DecOrder []string `mapstructure:"dec-order"` - IgnoreUnderscoreVars bool `mapstructure:"ignore-underscore-vars"` - DisableDecNumCheck bool `mapstructure:"disable-dec-num-check"` - DisableTypeDecNumCheck bool `mapstructure:"disable-type-dec-num-check"` - DisableConstDecNumCheck bool `mapstructure:"disable-const-dec-num-check"` - DisableVarDecNumCheck bool `mapstructure:"disable-var-dec-num-check"` - DisableDecOrderCheck bool `mapstructure:"disable-dec-order-check"` - DisableInitFuncFirstCheck bool `mapstructure:"disable-init-func-first-check"` -} - -type DogsledSettings struct { - MaxBlankIdentifiers int `mapstructure:"max-blank-identifiers"` -} - -type DuplSettings struct { - Threshold int `mapstructure:"threshold"` -} - -type DupWordSettings struct { - Keywords []string `mapstructure:"keywords"` - Ignore []string `mapstructure:"ignore"` - CommentsOnly bool `mapstructure:"comments-only"` -} - -type EmbeddedStructFieldCheckSettings struct { - ForbidMutex bool `mapstructure:"forbid-mutex"` - EmptyLine bool `mapstructure:"empty-line"` -} - -type ErrcheckSettings struct { - DisableDefaultExclusions bool `mapstructure:"disable-default-exclusions"` - CheckTypeAssertions bool `mapstructure:"check-type-assertions"` - CheckAssignToBlank bool `mapstructure:"check-blank"` - ExcludeFunctions []string `mapstructure:"exclude-functions"` - Verbose bool `mapstructure:"verbose"` -} - -type ErrChkJSONSettings struct { - CheckErrorFreeEncoding bool `mapstructure:"check-error-free-encoding"` - ReportNoExported bool `mapstructure:"report-no-exported"` -} - -type ErrorLintSettings struct { - Errorf bool `mapstructure:"errorf"` - ErrorfMulti bool `mapstructure:"errorf-multi"` - Asserts bool `mapstructure:"asserts"` - Comparison bool `mapstructure:"comparison"` - AllowedErrors []ErrorLintAllowPair `mapstructure:"allowed-errors"` - AllowedErrorsWildcard []ErrorLintAllowPair `mapstructure:"allowed-errors-wildcard"` -} - -type ErrorLintAllowPair struct { - Err string `mapstructure:"err"` - Fun string `mapstructure:"fun"` -} - -type ExhaustiveSettings struct { - Check []string `mapstructure:"check"` - DefaultSignifiesExhaustive bool `mapstructure:"default-signifies-exhaustive"` - IgnoreEnumMembers string `mapstructure:"ignore-enum-members"` - IgnoreEnumTypes string `mapstructure:"ignore-enum-types"` - PackageScopeOnly bool `mapstructure:"package-scope-only"` - ExplicitExhaustiveMap bool `mapstructure:"explicit-exhaustive-map"` - ExplicitExhaustiveSwitch bool `mapstructure:"explicit-exhaustive-switch"` - DefaultCaseRequired bool `mapstructure:"default-case-required"` -} - -type ExhaustructSettings struct { - Include []string `mapstructure:"include"` - Exclude []string `mapstructure:"exclude"` - AllowEmpty bool `mapstructure:"allow-empty"` - AllowEmptyRx []string `mapstructure:"allow-empty-rx"` - AllowEmptyReturns bool `mapstructure:"allow-empty-returns"` - AllowEmptyDeclarations bool `mapstructure:"allow-empty-declarations"` -} - -type FatcontextSettings struct { - CheckStructPointers bool `mapstructure:"check-struct-pointers"` -} - -type ForbidigoSettings struct { - Forbid []ForbidigoPattern `mapstructure:"forbid"` - ExcludeGodocExamples bool `mapstructure:"exclude-godoc-examples"` - AnalyzeTypes bool `mapstructure:"analyze-types"` -} - -type ForbidigoPattern struct { - Pattern string `yaml:"p" mapstructure:"pattern"` - Package string `yaml:"pkg,omitempty" mapstructure:"pkg,omitempty"` - Msg string `yaml:"msg,omitempty" mapstructure:"msg,omitempty"` -} - -type FuncOrderSettings struct { - Constructor bool `mapstructure:"constructor,omitempty"` - StructMethod bool `mapstructure:"struct-method,omitempty"` - Alphabetical bool `mapstructure:"alphabetical,omitempty"` -} - -type FunlenSettings struct { - Lines int `mapstructure:"lines"` - Statements int `mapstructure:"statements"` - IgnoreComments bool `mapstructure:"ignore-comments"` -} - -type GinkgoLinterSettings struct { - SuppressLenAssertion bool `mapstructure:"suppress-len-assertion"` - SuppressNilAssertion bool `mapstructure:"suppress-nil-assertion"` - SuppressErrAssertion bool `mapstructure:"suppress-err-assertion"` - SuppressCompareAssertion bool `mapstructure:"suppress-compare-assertion"` - SuppressAsyncAssertion bool `mapstructure:"suppress-async-assertion"` - SuppressTypeCompareWarning bool `mapstructure:"suppress-type-compare-assertion"` - ForbidFocusContainer bool `mapstructure:"forbid-focus-container"` - AllowHaveLenZero bool `mapstructure:"allow-havelen-zero"` - ForceExpectTo bool `mapstructure:"force-expect-to"` - ValidateAsyncIntervals bool `mapstructure:"validate-async-intervals"` - ForbidSpecPollution bool `mapstructure:"forbid-spec-pollution"` - ForceSucceedForFuncs bool `mapstructure:"force-succeed"` - ForceAssertionDescription bool `mapstructure:"force-assertion-description"` - ForeToNot bool `mapstructure:"force-tonot"` -} - -type GoChecksumTypeSettings struct { - DefaultSignifiesExhaustive bool `mapstructure:"default-signifies-exhaustive"` - IncludeSharedInterfaces bool `mapstructure:"include-shared-interfaces"` -} - -type GocognitSettings struct { - MinComplexity int `mapstructure:"min-complexity"` -} - -type GoConstSettings struct { - IgnoreStringValues []string `mapstructure:"ignore-string-values"` - MatchWithConstants bool `mapstructure:"match-constant"` - MinStringLen int `mapstructure:"min-len"` - MinOccurrencesCount int `mapstructure:"min-occurrences"` - ParseNumbers bool `mapstructure:"numbers"` - NumberMin int `mapstructure:"min"` - NumberMax int `mapstructure:"max"` - IgnoreCalls bool `mapstructure:"ignore-calls"` - FindDuplicates bool `mapstructure:"find-duplicates"` - EvalConstExpressions bool `mapstructure:"eval-const-expressions"` - - // Deprecated: use IgnoreStringValues instead. - IgnoreStrings string `mapstructure:"ignore-strings"` -} - -type GoCriticSettings struct { - Go string `mapstructure:"-"` - DisableAll bool `mapstructure:"disable-all"` - EnabledChecks []string `mapstructure:"enabled-checks"` - EnableAll bool `mapstructure:"enable-all"` - DisabledChecks []string `mapstructure:"disabled-checks"` - EnabledTags []string `mapstructure:"enabled-tags"` - DisabledTags []string `mapstructure:"disabled-tags"` - SettingsPerCheck map[string]GoCriticCheckSettings `mapstructure:"settings"` -} - -type GoCriticCheckSettings map[string]any - -type GoCycloSettings struct { - MinComplexity int `mapstructure:"min-complexity"` -} - -type GodoclintSettings struct { - Default *string `mapstructure:"default"` - Enable []string `mapstructure:"enable"` - Disable []string `mapstructure:"disable"` - Options struct { - MaxLen struct { - Length *uint `mapstructure:"length"` - } `mapstructure:"max-len"` - RequireDoc struct { - IgnoreExported *bool `mapstructure:"ignore-exported"` - IgnoreUnexported *bool `mapstructure:"ignore-unexported"` - } `mapstructure:"require-doc"` - StartWithName struct { - IncludeUnexported *bool `mapstructure:"include-unexported"` - } `mapstructure:"start-with-name"` - } `mapstructure:"options"` -} - -type GodotSettings struct { - Scope string `mapstructure:"scope"` - Exclude []string `mapstructure:"exclude"` - Capital bool `mapstructure:"capital"` - Period bool `mapstructure:"period"` -} - -type GodoxSettings struct { - Keywords []string `mapstructure:"keywords"` -} - -type GoHeaderSettings struct { - Values map[string]map[string]string `mapstructure:"values"` - Template string `mapstructure:"template"` - TemplatePath string `mapstructure:"template-path"` -} - -type GoModDirectivesSettings struct { - ReplaceAllowList []string `mapstructure:"replace-allow-list"` - ReplaceLocal bool `mapstructure:"replace-local"` - ExcludeForbidden bool `mapstructure:"exclude-forbidden"` - RetractAllowNoExplanation bool `mapstructure:"retract-allow-no-explanation"` - ToolchainForbidden bool `mapstructure:"toolchain-forbidden"` - ToolchainPattern string `mapstructure:"toolchain-pattern"` - ToolForbidden bool `mapstructure:"tool-forbidden"` - GoDebugForbidden bool `mapstructure:"go-debug-forbidden"` - GoVersionPattern string `mapstructure:"go-version-pattern"` -} - -type GoModGuardSettings struct { - Allowed GoModGuardAllowed `mapstructure:"allowed"` - Blocked GoModGuardBlocked `mapstructure:"blocked"` -} - -type GoModGuardAllowed struct { - Modules []string `mapstructure:"modules"` - Domains []string `mapstructure:"domains"` -} - -type GoModGuardBlocked struct { - Modules []map[string]GoModGuardModule `mapstructure:"modules"` - Versions []map[string]GoModGuardVersion `mapstructure:"versions"` - LocalReplaceDirectives bool `mapstructure:"local-replace-directives"` -} - -type GoModGuardModule struct { - Recommendations []string `mapstructure:"recommendations"` - Reason string `mapstructure:"reason"` -} - -type GoModGuardVersion struct { - Version string `mapstructure:"version"` - Reason string `mapstructure:"reason"` -} - -type GoSecSettings struct { - Includes []string `mapstructure:"includes"` - Excludes []string `mapstructure:"excludes"` - Severity string `mapstructure:"severity"` - Confidence string `mapstructure:"confidence"` - Config map[string]any `mapstructure:"config"` - Concurrency int `mapstructure:"concurrency"` -} - -type GosmopolitanSettings struct { - AllowTimeLocal bool `mapstructure:"allow-time-local"` - EscapeHatches []string `mapstructure:"escape-hatches"` - WatchForScripts []string `mapstructure:"watch-for-scripts"` -} - -type GovetSettings struct { - Go string `mapstructure:"-"` - - Enable []string `mapstructure:"enable"` - Disable []string `mapstructure:"disable"` - EnableAll bool `mapstructure:"enable-all"` - DisableAll bool `mapstructure:"disable-all"` - - Settings map[string]map[string]any `mapstructure:"settings"` -} - -func (cfg *GovetSettings) Validate() error { - if cfg.EnableAll && cfg.DisableAll { - return errors.New("govet: enable-all and disable-all can't be combined") - } - if cfg.EnableAll && len(cfg.Enable) != 0 { - return errors.New("govet: enable-all and enable can't be combined") - } - if cfg.DisableAll && len(cfg.Disable) != 0 { - return errors.New("govet: disable-all and disable can't be combined") - } - return nil -} - -type GrouperSettings struct { - ConstRequireSingleConst bool `mapstructure:"const-require-single-const"` - ConstRequireGrouping bool `mapstructure:"const-require-grouping"` - ImportRequireSingleImport bool `mapstructure:"import-require-single-import"` - ImportRequireGrouping bool `mapstructure:"import-require-grouping"` - TypeRequireSingleType bool `mapstructure:"type-require-single-type"` - TypeRequireGrouping bool `mapstructure:"type-require-grouping"` - VarRequireSingleVar bool `mapstructure:"var-require-single-var"` - VarRequireGrouping bool `mapstructure:"var-require-grouping"` -} - -type IfaceSettings struct { - Enable []string `mapstructure:"enable"` - Settings map[string]map[string]any `mapstructure:"settings"` -} - -type ImportAsSettings struct { - Alias []ImportAsAlias `mapstructure:"alias"` - NoUnaliased bool `mapstructure:"no-unaliased"` - NoExtraAliases bool `mapstructure:"no-extra-aliases"` -} - -type ImportAsAlias struct { - Pkg string `mapstructure:"pkg"` - Alias string `mapstructure:"alias"` -} - -type INamedParamSettings struct { - SkipSingleParam bool `mapstructure:"skip-single-param"` -} - -type IneffassignSettings struct { - CheckEscapingErrors bool `mapstructure:"check-escaping-errors"` -} - -type InterfaceBloatSettings struct { - Max int `mapstructure:"max"` -} - -type IotaMixingSettings struct { - ReportIndividual bool `mapstructure:"report-individual"` -} - -type IreturnSettings struct { - Allow []string `mapstructure:"allow"` - Reject []string `mapstructure:"reject"` -} - -type LllSettings struct { - LineLength int `mapstructure:"line-length"` - TabWidth int `mapstructure:"tab-width"` -} - -type LoggerCheckSettings struct { - Kitlog bool `mapstructure:"kitlog"` - Klog bool `mapstructure:"klog"` - Logr bool `mapstructure:"logr"` - Slog bool `mapstructure:"slog"` - Zap bool `mapstructure:"zap"` - RequireStringKey bool `mapstructure:"require-string-key"` - NoPrintfLike bool `mapstructure:"no-printf-like"` - Rules []string `mapstructure:"rules"` -} - -type MaintIdxSettings struct { - Under int `mapstructure:"under"` -} - -type MakezeroSettings struct { - Always bool `mapstructure:"always"` -} - -type MisspellSettings struct { - Mode string `mapstructure:"mode"` - Locale string `mapstructure:"locale"` - ExtraWords []MisspellExtraWords `mapstructure:"extra-words"` - IgnoreRules []string `mapstructure:"ignore-rules"` -} - -type MisspellExtraWords struct { - Typo string `mapstructure:"typo"` - Correction string `mapstructure:"correction"` -} - -type MustTagSettings struct { - Functions []MustTagFunction `mapstructure:"functions"` -} - -type MustTagFunction struct { - Name string `mapstructure:"name"` - Tag string `mapstructure:"tag"` - ArgPos int `mapstructure:"arg-pos"` -} - -type NakedretSettings struct { - MaxFuncLines uint `mapstructure:"max-func-lines"` -} - -type NestifSettings struct { - MinComplexity int `mapstructure:"min-complexity"` -} - -type NilNilSettings struct { - OnlyTwo *bool `mapstructure:"only-two"` - DetectOpposite bool `mapstructure:"detect-opposite"` - CheckedTypes []string `mapstructure:"checked-types"` -} - -type NlreturnSettings struct { - BlockSize int `mapstructure:"block-size"` -} - -type MndSettings struct { - Checks []string `mapstructure:"checks"` - IgnoredNumbers []string `mapstructure:"ignored-numbers"` - IgnoredFiles []string `mapstructure:"ignored-files"` - IgnoredFunctions []string `mapstructure:"ignored-functions"` -} - -type ModernizeSettings struct { - Disable []string `mapstructure:"disable"` -} - -type NoLintLintSettings struct { - RequireExplanation bool `mapstructure:"require-explanation"` - RequireSpecific bool `mapstructure:"require-specific"` - AllowNoExplanation []string `mapstructure:"allow-no-explanation"` - AllowUnused bool `mapstructure:"allow-unused"` -} - -type NoNamedReturnsSettings struct { - ReportErrorInDefer bool `mapstructure:"report-error-in-defer"` -} - -type ParallelTestSettings struct { - Go string `mapstructure:"-"` - IgnoreMissing bool `mapstructure:"ignore-missing"` - IgnoreMissingSubtests bool `mapstructure:"ignore-missing-subtests"` -} - -type PerfSprintSettings struct { - IntegerFormat bool `mapstructure:"integer-format"` - IntConversion bool `mapstructure:"int-conversion"` - - ErrorFormat bool `mapstructure:"error-format"` - ErrError bool `mapstructure:"err-error"` - ErrorF bool `mapstructure:"errorf"` - - StringFormat bool `mapstructure:"string-format"` - SprintF1 bool `mapstructure:"sprintf1"` - StrConcat bool `mapstructure:"strconcat"` - - BoolFormat bool `mapstructure:"bool-format"` - HexFormat bool `mapstructure:"hex-format"` - - ConcatLoop bool `mapstructure:"concat-loop"` - LoopOtherOps bool `mapstructure:"loop-other-ops"` -} - -type PreallocSettings struct { - Simple bool `mapstructure:"simple"` - RangeLoops bool `mapstructure:"range-loops"` - ForLoops bool `mapstructure:"for-loops"` -} - -type PredeclaredSettings struct { - Ignore []string `mapstructure:"ignore"` - Qualified bool `mapstructure:"qualified-name"` -} - -type PromlinterSettings struct { - Strict bool `mapstructure:"strict"` - DisabledLinters []string `mapstructure:"disabled-linters"` -} - -type ProtoGetterSettings struct { - SkipGeneratedBy []string `mapstructure:"skip-generated-by"` - SkipFiles []string `mapstructure:"skip-files"` - SkipAnyGenerated bool `mapstructure:"skip-any-generated"` - ReplaceFirstArgInAppend bool `mapstructure:"replace-first-arg-in-append"` -} - -type ReassignSettings struct { - Patterns []string `mapstructure:"patterns"` -} - -type RecvcheckSettings struct { - DisableBuiltin bool `mapstructure:"disable-builtin"` - Exclusions []string `mapstructure:"exclusions"` -} - -type ReviveSettings struct { - Go string `mapstructure:"-"` - MaxOpenFiles int `mapstructure:"max-open-files"` - Confidence float64 `mapstructure:"confidence"` - Severity string `mapstructure:"severity"` - EnableAllRules bool `mapstructure:"enable-all-rules"` - Rules []ReviveRule `mapstructure:"rules"` - ErrorCode int `mapstructure:"error-code"` - WarningCode int `mapstructure:"warning-code"` - Directives []ReviveDirective `mapstructure:"directives"` -} - -type ReviveRule struct { - Name string `mapstructure:"name"` - Arguments []any `mapstructure:"arguments"` - Severity string `mapstructure:"severity"` - Disabled bool `mapstructure:"disabled"` - Exclude []string `mapstructure:"exclude"` -} - -type ReviveDirective struct { - Name string `mapstructure:"name"` - Severity string `mapstructure:"severity"` -} - -type RowsErrCheckSettings struct { - Packages []string `mapstructure:"packages"` -} - -type SlogLintSettings struct { - NoMixedArgs bool `mapstructure:"no-mixed-args"` - KVOnly bool `mapstructure:"kv-only"` - AttrOnly bool `mapstructure:"attr-only"` - NoGlobal string `mapstructure:"no-global"` - Context string `mapstructure:"context"` - StaticMsg bool `mapstructure:"static-msg"` - MsgStyle string `mapstructure:"msg-style"` - NoRawKeys bool `mapstructure:"no-raw-keys"` - KeyNamingCase string `mapstructure:"key-naming-case"` - ForbiddenKeys []string `mapstructure:"forbidden-keys"` - ArgsOnSepLines bool `mapstructure:"args-on-sep-lines"` -} - -type SpancheckSettings struct { - Checks []string `mapstructure:"checks"` - IgnoreCheckSignatures []string `mapstructure:"ignore-check-signatures"` - ExtraStartSpanSignatures []string `mapstructure:"extra-start-span-signatures"` -} - -type StaticCheckSettings struct { - Checks []string `mapstructure:"checks"` - Initialisms []string `mapstructure:"initialisms"` // only for stylecheck - DotImportWhitelist []string `mapstructure:"dot-import-whitelist"` // only for stylecheck - HTTPStatusCodeWhitelist []string `mapstructure:"http-status-code-whitelist"` // only for stylecheck -} - -func (s *StaticCheckSettings) HasConfiguration() bool { - return s.Initialisms == nil || s.HTTPStatusCodeWhitelist == nil || s.DotImportWhitelist == nil || s.Checks == nil -} - -type TagAlignSettings struct { - Align bool `mapstructure:"align"` - Sort bool `mapstructure:"sort"` - Order []string `mapstructure:"order"` - Strict bool `mapstructure:"strict"` -} - -type TagliatelleSettings struct { - Case TagliatelleCase `mapstructure:"case"` -} - -type TagliatelleCase struct { - TagliatelleBase `mapstructure:",squash"` - Overrides []TagliatelleOverrides `mapstructure:"overrides"` -} - -type TagliatelleOverrides struct { - TagliatelleBase `mapstructure:",squash"` - Package string `mapstructure:"pkg"` - Ignore bool `mapstructure:"ignore"` -} - -type TagliatelleBase struct { - Rules map[string]string `mapstructure:"rules"` - ExtendedRules map[string]TagliatelleExtendedRule `mapstructure:"extended-rules"` - UseFieldName bool `mapstructure:"use-field-name"` - IgnoredFields []string `mapstructure:"ignored-fields"` -} - -type TagliatelleExtendedRule struct { - Case string `mapstructure:"case"` - ExtraInitialisms bool `mapstructure:"extra-initialisms"` - InitialismOverrides map[string]bool `mapstructure:"initialism-overrides"` -} - -type TestifylintSettings struct { - EnableAll bool `mapstructure:"enable-all"` - DisableAll bool `mapstructure:"disable-all"` - EnabledCheckers []string `mapstructure:"enable"` - DisabledCheckers []string `mapstructure:"disable"` - - BoolCompare TestifylintBoolCompare `mapstructure:"bool-compare"` - ExpectedActual TestifylintExpectedActual `mapstructure:"expected-actual"` - Formatter TestifylintFormatter `mapstructure:"formatter"` - GoRequire TestifylintGoRequire `mapstructure:"go-require"` - RequireError TestifylintRequireError `mapstructure:"require-error"` - SuiteExtraAssertCall TestifylintSuiteExtraAssertCall `mapstructure:"suite-extra-assert-call"` -} - -type TestifylintBoolCompare struct { - IgnoreCustomTypes bool `mapstructure:"ignore-custom-types"` -} - -type TestifylintExpectedActual struct { - ExpVarPattern string `mapstructure:"pattern"` -} - -type TestifylintFormatter struct { - CheckFormatString *bool `mapstructure:"check-format-string"` - RequireFFuncs bool `mapstructure:"require-f-funcs"` - RequireStringMsg bool `mapstructure:"require-string-msg"` -} - -type TestifylintGoRequire struct { - IgnoreHTTPHandlers bool `mapstructure:"ignore-http-handlers"` -} - -type TestifylintRequireError struct { - FnPattern string `mapstructure:"fn-pattern"` -} - -type TestifylintSuiteExtraAssertCall struct { - Mode string `mapstructure:"mode"` -} - -type TestpackageSettings struct { - SkipRegexp string `mapstructure:"skip-regexp"` - AllowPackages []string `mapstructure:"allow-packages"` -} - -type ThelperSettings struct { - Test ThelperOptions `mapstructure:"test"` - Fuzz ThelperOptions `mapstructure:"fuzz"` - Benchmark ThelperOptions `mapstructure:"benchmark"` - TB ThelperOptions `mapstructure:"tb"` -} - -type ThelperOptions struct { - First *bool `mapstructure:"first"` - Name *bool `mapstructure:"name"` - Begin *bool `mapstructure:"begin"` -} - -type UseStdlibVarsSettings struct { - HTTPMethod bool `mapstructure:"http-method"` - HTTPStatusCode bool `mapstructure:"http-status-code"` - TimeWeekday bool `mapstructure:"time-weekday"` - TimeMonth bool `mapstructure:"time-month"` - TimeLayout bool `mapstructure:"time-layout"` - CryptoHash bool `mapstructure:"crypto-hash"` - DefaultRPCPath bool `mapstructure:"default-rpc-path"` - SQLIsolationLevel bool `mapstructure:"sql-isolation-level"` - TLSSignatureScheme bool `mapstructure:"tls-signature-scheme"` - ConstantKind bool `mapstructure:"constant-kind"` - TimeDateMonth bool `mapstructure:"time-date-month"` -} - -type UseTestingSettings struct { - ContextBackground bool `mapstructure:"context-background"` - ContextTodo bool `mapstructure:"context-todo"` - OSChdir bool `mapstructure:"os-chdir"` - OSMkdirTemp bool `mapstructure:"os-mkdir-temp"` - OSSetenv bool `mapstructure:"os-setenv"` - OSTempDir bool `mapstructure:"os-temp-dir"` - OSCreateTemp bool `mapstructure:"os-create-temp"` -} - -type UnconvertSettings struct { - FastMath bool `mapstructure:"fast-math"` - Safe bool `mapstructure:"safe"` -} - -type UnparamSettings struct { - CheckExported bool `mapstructure:"check-exported"` -} - -type UnqueryvetSettings struct { - CheckSQLBuilders bool `mapstructure:"check-sql-builders"` - AllowedPatterns []string `mapstructure:"allowed-patterns"` -} - -type UnusedSettings struct { - FieldWritesAreUses bool `mapstructure:"field-writes-are-uses"` - PostStatementsAreReads bool `mapstructure:"post-statements-are-reads"` - ExportedFieldsAreUsed bool `mapstructure:"exported-fields-are-used"` - ParametersAreUsed bool `mapstructure:"parameters-are-used"` - LocalVariablesAreUsed bool `mapstructure:"local-variables-are-used"` - GeneratedIsUsed bool `mapstructure:"generated-is-used"` -} - -type VarnamelenSettings struct { - MaxDistance int `mapstructure:"max-distance"` - MinNameLength int `mapstructure:"min-name-length"` - CheckReceiver bool `mapstructure:"check-receiver"` - CheckReturn bool `mapstructure:"check-return"` - CheckTypeParam bool `mapstructure:"check-type-param"` - IgnoreNames []string `mapstructure:"ignore-names"` - IgnoreTypeAssertOk bool `mapstructure:"ignore-type-assert-ok"` - IgnoreMapIndexOk bool `mapstructure:"ignore-map-index-ok"` - IgnoreChanRecvOk bool `mapstructure:"ignore-chan-recv-ok"` - IgnoreDecls []string `mapstructure:"ignore-decls"` -} - -type WhitespaceSettings struct { - MultiIf bool `mapstructure:"multi-if"` - MultiFunc bool `mapstructure:"multi-func"` -} - -type WrapcheckSettings struct { - ExtraIgnoreSigs []string `mapstructure:"extra-ignore-sigs"` - IgnoreSigs []string `mapstructure:"ignore-sigs"` - IgnoreSigRegexps []string `mapstructure:"ignore-sig-regexps"` - IgnorePackageGlobs []string `mapstructure:"ignore-package-globs"` - IgnoreInterfaceRegexps []string `mapstructure:"ignore-interface-regexps"` - ReportInternalErrors bool `mapstructure:"report-internal-errors"` -} - -// Deprecated: use WSLv5Settings instead. -type WSLv4Settings struct { - StrictAppend bool `mapstructure:"strict-append"` - AllowAssignAndCallCuddle bool `mapstructure:"allow-assign-and-call"` - AllowAssignAndAnythingCuddle bool `mapstructure:"allow-assign-and-anything"` - AllowMultiLineAssignCuddle bool `mapstructure:"allow-multiline-assign"` - ForceCaseTrailingWhitespaceLimit int `mapstructure:"force-case-trailing-whitespace"` - AllowTrailingComment bool `mapstructure:"allow-trailing-comment"` - AllowSeparatedLeadingComment bool `mapstructure:"allow-separated-leading-comment"` - AllowCuddleDeclaration bool `mapstructure:"allow-cuddle-declarations"` - AllowCuddleWithCalls []string `mapstructure:"allow-cuddle-with-calls"` - AllowCuddleWithRHS []string `mapstructure:"allow-cuddle-with-rhs"` - AllowCuddleUsedInBlock bool `mapstructure:"allow-cuddle-used-in-block"` - ForceCuddleErrCheckAndAssign bool `mapstructure:"force-err-cuddling"` - ErrorVariableNames []string `mapstructure:"error-variable-names"` - ForceExclusiveShortDeclarations bool `mapstructure:"force-short-decl-cuddling"` -} - -type WSLv5Settings struct { - AllowFirstInBlock bool `mapstructure:"allow-first-in-block"` - AllowWholeBlock bool `mapstructure:"allow-whole-block"` - BranchMaxLines int `mapstructure:"branch-max-lines"` - CaseMaxLines int `mapstructure:"case-max-lines"` - Default string `mapstructure:"default"` - Enable []string `mapstructure:"enable"` - Disable []string `mapstructure:"disable"` -} - -// CustomLinterSettings encapsulates the meta-data of a private linter. -type CustomLinterSettings struct { - // Type plugin type. - // It can be `goplugin` or `module`. - Type string `mapstructure:"type"` - - // Path to a plugin *.so file that implements the private linter. - // Only for Go plugin system. - Path string `mapstructure:"path"` - - // Description describes the purpose of the private linter. - Description string `mapstructure:"description"` - // OriginalURL The URL containing the source code for the private linter. - OriginalURL string `mapstructure:"original-url"` - - // Settings plugin settings only work with linterdb.PluginConstructor symbol. - Settings any `mapstructure:"settings"` -} - -func (s *CustomLinterSettings) Validate() error { - if s.Type == "module" { - if s.Path != "" { - return errors.New("path not supported with module type") - } - - return nil - } - - if s.Path == "" { - return errors.New("path is required") - } - - return nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/loader.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/loader.go deleted file mode 100644 index 511c3ab7da..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/loader.go +++ /dev/null @@ -1,275 +0,0 @@ -package config - -import ( - "context" - "errors" - "fmt" - "os" - "slices" - - "github.com/spf13/pflag" - "github.com/spf13/viper" - - "github.com/golangci/golangci-lint/v2/pkg/fsutils" - "github.com/golangci/golangci-lint/v2/pkg/goutil" - "github.com/golangci/golangci-lint/v2/pkg/logutils" -) - -var errConfigDisabled = errors.New("config is disabled by --no-config") - -const ( - modeLinters = "linters" - modeFormatters = "formatters" -) - -type LoaderOptions struct { - Config string // Flag only. The path to the golangci config file, as specified with the --config argument. - NoConfig bool // Flag only. -} - -type LoadOptions struct { - CheckDeprecation bool - Validation bool -} - -type Loader struct { - *BaseLoader - - fs *pflag.FlagSet - - cfg *Config - - mode string -} - -func NewLintersLoader(log logutils.Log, v *viper.Viper, fs *pflag.FlagSet, opts LoaderOptions, cfg *Config, args []string) *Loader { - loader := newLoader(log, v, fs, opts, cfg, args) - loader.mode = modeLinters - - return loader -} - -func NewFormattersLoader(log logutils.Log, v *viper.Viper, fs *pflag.FlagSet, opts LoaderOptions, cfg *Config, args []string) *Loader { - loader := newLoader(log, v, fs, opts, cfg, args) - loader.mode = modeFormatters - - return loader -} - -func newLoader(log logutils.Log, v *viper.Viper, fs *pflag.FlagSet, opts LoaderOptions, cfg *Config, args []string) *Loader { - return &Loader{ - BaseLoader: NewBaseLoader(log, v, opts, cfg, args), - fs: fs, - cfg: cfg, - } -} - -func (l *Loader) Load(opts LoadOptions) error { - err := l.BaseLoader.Load() - if err != nil { - return err - } - - if l.mode == modeLinters { - l.applyStringSliceHack() - } - - if l.cfg.Linters.Exclusions.Generated == "" { - l.cfg.Linters.Exclusions.Generated = GeneratedModeStrict - } - - err = l.checkConfigurationVersion() - if err != nil { - return err - } - - if !l.cfg.InternalCmdTest { - for _, n := range slices.Concat(l.cfg.Linters.Enable, l.cfg.Linters.Disable) { - if n == "typecheck" { - return fmt.Errorf("%s is not a linter, it cannot be enabled or disabled", n) - } - } - } - - l.handleFormatters() - - if opts.CheckDeprecation { - err = l.handleDeprecation() - if err != nil { - return err - } - - l.handleFormatterDeprecations() - } - - l.handleGoVersion() - - err = goutil.CheckGoVersion(l.cfg.Run.Go) - if err != nil { - return err - } - - l.cfg.basePath, err = fsutils.GetBasePath(context.Background(), l.cfg.Run.RelativePathMode, l.cfg.cfgDir) - if err != nil { - return fmt.Errorf("get base path: %w", err) - } - - err = l.handleEnableOnlyOption() - if err != nil { - return err - } - - if opts.Validation { - err = l.cfg.Validate() - if err != nil { - return err - } - } - - return nil -} - -// Hack to append values from StringSlice flags. -// Viper always overrides StringSlice values. -// https://github.com/spf13/viper/issues/1448 -// So StringSlice flags are not bind to Viper like that their values are obtain via Cobra Flags. -func (l *Loader) applyStringSliceHack() { - if l.fs == nil { - return - } - - l.appendStringSlice("enable", &l.cfg.Linters.Enable) - l.appendStringSlice("disable", &l.cfg.Linters.Disable) - l.appendStringSlice("build-tags", &l.cfg.Run.BuildTags) -} - -func (l *Loader) appendStringSlice(name string, current *[]string) { - if l.fs.Changed(name) { - val, _ := l.fs.GetStringSlice(name) - *current = append(*current, val...) - } -} - -func (l *Loader) checkConfigurationVersion() error { - if l.cfg.GetConfigDir() != "" && l.cfg.Version != "2" { - return fmt.Errorf("unsupported version of the configuration: %q "+ - "See https://golangci-lint.run/docs/product/migration-guide for migration instructions", l.cfg.Version) - } - - return nil -} - -func (l *Loader) handleGoVersion() { - if l.cfg.Run.Go == "" { - l.cfg.Run.Go = detectGoVersion(context.Background(), l.log) - } - - l.cfg.Linters.Settings.Govet.Go = l.cfg.Run.Go - - l.cfg.Linters.Settings.ParallelTest.Go = l.cfg.Run.Go - - l.cfg.Linters.Settings.GoFumpt.LangVersion = l.cfg.Run.Go - l.cfg.Formatters.Settings.GoFumpt.LangVersion = l.cfg.Run.Go - - trimmedGoVersion := goutil.TrimGoVersion(l.cfg.Run.Go) - - l.cfg.Linters.Settings.Revive.Go = trimmedGoVersion - - l.cfg.Linters.Settings.Gocritic.Go = trimmedGoVersion - - os.Setenv("GOSECGOVERSION", l.cfg.Run.Go) -} - -func (l *Loader) handleDeprecation() error { - if l.cfg.InternalTest || l.cfg.InternalCmdTest || os.Getenv(logutils.EnvTestRun) == "1" { - return nil - } - - l.handleLinterOptionDeprecations() - - return nil -} - -func (l *Loader) handleLinterOptionDeprecations() { - // Deprecated since v2.1.0. - if l.cfg.Linters.Settings.Goconst.IgnoreStrings != "" { - l.log.Warnf("The configuration option `linters.settings.goconst.ignore-strings` is deprecated, " + - "please use `linters.settings.goconst.ignore-string-values`.") - - l.cfg.Linters.Settings.Goconst.IgnoreStringValues = append(l.cfg.Linters.Settings.Goconst.IgnoreStringValues, - l.cfg.Linters.Settings.Goconst.IgnoreStrings) - } -} - -func (l *Loader) handleEnableOnlyOption() error { - lookup := l.fs.Lookup("enable-only") - if lookup == nil { - return nil - } - - only, err := l.fs.GetStringSlice("enable-only") - if err != nil { - return err - } - - if len(only) > 0 { - l.cfg.Linters = Linters{ - Default: GroupNone, - Enable: only, - Settings: l.cfg.Linters.Settings, - Exclusions: l.cfg.Linters.Exclusions, - } - - l.cfg.Formatters = Formatters{} - } - - return nil -} - -func (l *Loader) handleFormatters() { - l.handleFormatterOverrides() - l.handleFormatterExclusions() -} - -// Overrides linter settings with formatter settings if the formatter is enabled. -func (l *Loader) handleFormatterOverrides() { - if slices.Contains(l.cfg.Formatters.Enable, "gofmt") { - l.cfg.Linters.Settings.GoFmt = l.cfg.Formatters.Settings.GoFmt - } - - if slices.Contains(l.cfg.Formatters.Enable, "gofumpt") { - l.cfg.Linters.Settings.GoFumpt = l.cfg.Formatters.Settings.GoFumpt - } - - if slices.Contains(l.cfg.Formatters.Enable, "goimports") { - l.cfg.Linters.Settings.GoImports = l.cfg.Formatters.Settings.GoImports - } - - if slices.Contains(l.cfg.Formatters.Enable, "gci") { - l.cfg.Linters.Settings.Gci = l.cfg.Formatters.Settings.Gci - } - - if slices.Contains(l.cfg.Formatters.Enable, "golines") { - l.cfg.Linters.Settings.GoLines = l.cfg.Formatters.Settings.GoLines - } -} - -// Add formatter exclusions to linters exclusions. -func (l *Loader) handleFormatterExclusions() { - if len(l.cfg.Formatters.Enable) == 0 { - return - } - - for _, path := range l.cfg.Formatters.Exclusions.Paths { - l.cfg.Linters.Exclusions.Rules = append(l.cfg.Linters.Exclusions.Rules, ExcludeRule{ - BaseRule: BaseRule{ - Linters: l.cfg.Formatters.Enable, - Path: path, - }, - }) - } -} - -func (*Loader) handleFormatterDeprecations() { - // The function is empty but deprecations will happen in the future. -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/output.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/output.go deleted file mode 100644 index 803dc3ac29..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/output.go +++ /dev/null @@ -1,62 +0,0 @@ -package config - -import ( - "fmt" - "slices" - "strings" - - "github.com/golangci/golangci-lint/v2/pkg/fsutils" -) - -type Output struct { - Formats Formats `mapstructure:"formats"` - SortOrder []string `mapstructure:"sort-order"` - ShowStats bool `mapstructure:"show-stats"` - PathPrefix string `mapstructure:"path-prefix"` - PathMode string `mapstructure:"path-mode"` -} - -func (o *Output) Validate() error { - validators := []func() error{ - o.validateSortOrder, - o.validatePathMode, - } - - for _, v := range validators { - if err := v(); err != nil { - return err - } - } - - return nil -} - -func (o *Output) validateSortOrder() error { - validOrders := []string{"linter", "file", "severity"} - - all := strings.Join(o.SortOrder, " ") - - for _, order := range o.SortOrder { - if strings.Count(all, order) > 1 { - return fmt.Errorf("the sort-order name %q is repeated several times", order) - } - - if !slices.Contains(validOrders, order) { - return fmt.Errorf("unsupported sort-order name %q", order) - } - } - - return nil -} - -func (o *Output) validatePathMode() error { - switch o.PathMode { - case "", fsutils.OutputPathModeAbsolute: - // Valid - - default: - return fmt.Errorf("unsupported output path mode %q", o.PathMode) - } - - return nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/output_formats.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/output_formats.go deleted file mode 100644 index 1c655c1b00..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/output_formats.go +++ /dev/null @@ -1,57 +0,0 @@ -package config - -type Formats struct { - Text Text `mapstructure:"text"` - JSON SimpleFormat `mapstructure:"json"` - Tab Tab `mapstructure:"tab"` - HTML SimpleFormat `mapstructure:"html"` - Checkstyle SimpleFormat `mapstructure:"checkstyle"` - CodeClimate SimpleFormat `mapstructure:"code-climate"` - JUnitXML JUnitXML `mapstructure:"junit-xml"` - TeamCity SimpleFormat `mapstructure:"teamcity"` - Sarif SimpleFormat `mapstructure:"sarif"` -} - -func (f *Formats) IsEmpty() bool { - formats := []SimpleFormat{ - f.Text.SimpleFormat, - f.JSON, - f.Tab.SimpleFormat, - f.HTML, - f.Checkstyle, - f.CodeClimate, - f.JUnitXML.SimpleFormat, - f.TeamCity, - f.Sarif, - } - - for _, format := range formats { - if format.Path != "" { - return false - } - } - - return true -} - -type SimpleFormat struct { - Path string `mapstructure:"path"` -} - -type Text struct { - SimpleFormat `mapstructure:",squash"` - PrintLinterName bool `mapstructure:"print-linter-name"` - PrintIssuedLine bool `mapstructure:"print-issued-lines"` - Colors bool `mapstructure:"colors"` -} - -type Tab struct { - SimpleFormat `mapstructure:",squash"` - PrintLinterName bool `mapstructure:"print-linter-name"` - Colors bool `mapstructure:"colors"` -} - -type JUnitXML struct { - SimpleFormat `mapstructure:",squash"` - Extended bool `mapstructure:"extended"` -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/placeholders.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/placeholders.go deleted file mode 100644 index b3f35f7b3a..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/placeholders.go +++ /dev/null @@ -1,18 +0,0 @@ -package config - -import "strings" - -const ( - // placeholderBasePath used inside linters to evaluate relative paths. - placeholderBasePath = "${base-path}" - - // placeholderConfigPath used inside linters to paths relative to configuration. - placeholderConfigPath = "${config-path}" -) - -func NewPlaceholderReplacer(cfg *Config) *strings.Replacer { - return strings.NewReplacer( - placeholderBasePath, cfg.GetBasePath(), - placeholderConfigPath, cfg.GetConfigDir(), - ) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/run.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/run.go deleted file mode 100644 index dcddf0cb61..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/run.go +++ /dev/null @@ -1,47 +0,0 @@ -package config - -import ( - "fmt" - "slices" - "strings" - "time" - - "github.com/golangci/golangci-lint/v2/pkg/fsutils" -) - -// Run encapsulates the config options for running the linter analysis. -type Run struct { - Timeout time.Duration `mapstructure:"timeout"` - - Concurrency int `mapstructure:"concurrency"` - - Go string `mapstructure:"go"` - - RelativePathMode string `mapstructure:"relative-path-mode"` - - BuildTags []string `mapstructure:"build-tags"` - ModulesDownloadMode string `mapstructure:"modules-download-mode"` - - ExitCodeIfIssuesFound int `mapstructure:"issues-exit-code"` - AnalyzeTests bool `mapstructure:"tests"` - - AllowParallelRunners bool `mapstructure:"allow-parallel-runners"` - AllowSerialRunners bool `mapstructure:"allow-serial-runners"` -} - -func (r *Run) Validate() error { - // go help modules - allowedModes := []string{"mod", "readonly", "vendor"} - - if r.ModulesDownloadMode != "" && !slices.Contains(allowedModes, r.ModulesDownloadMode) { - return fmt.Errorf("invalid modules download path %s, only (%s) allowed", r.ModulesDownloadMode, strings.Join(allowedModes, "|")) - } - - pathRelativeToModes := fsutils.AllRelativePathModes() - - if r.RelativePathMode != "" && !slices.Contains(pathRelativeToModes, r.RelativePathMode) { - return fmt.Errorf("invalid relative path mode %s, only (%s) allowed", r.RelativePathMode, strings.Join(pathRelativeToModes, "|")) - } - - return nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/severity.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/config/severity.go deleted file mode 100644 index f41e17b11b..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/config/severity.go +++ /dev/null @@ -1,40 +0,0 @@ -package config - -import ( - "errors" - "fmt" -) - -const severityRuleMinConditionsCount = 1 - -type Severity struct { - Default string `mapstructure:"default"` - Rules []SeverityRule `mapstructure:"rules"` -} - -func (s *Severity) Validate() error { - if len(s.Rules) > 0 && s.Default == "" { - return errors.New("can't set severity rule option: no default severity defined") - } - - for i, rule := range s.Rules { - if err := rule.Validate(); err != nil { - return fmt.Errorf("error in severity rule #%d: %w", i, err) - } - } - - return nil -} - -type SeverityRule struct { - BaseRule `mapstructure:",squash"` - Severity string `mapstructure:"severity"` -} - -func (s *SeverityRule) Validate() error { - if s.Severity == "" { - return errors.New("severity should be set") - } - - return s.BaseRule.Validate(severityRuleMinConditionsCount) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/exitcodes/exitcodes.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/exitcodes/exitcodes.go deleted file mode 100644 index 83331dbe7b..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/exitcodes/exitcodes.go +++ /dev/null @@ -1,32 +0,0 @@ -package exitcodes - -const ( - Success = iota - IssuesFound - WarningInTest - Failure - Timeout - NoGoFiles - NoConfigFileDetected - ErrorWasLogged -) - -type ExitError struct { - Message string - Code int -} - -func (e ExitError) Error() string { - return e.Message -} - -var ( - ErrNoGoFiles = &ExitError{ - Message: "no go files to analyze", - Code: NoGoFiles, - } - ErrFailure = &ExitError{ - Message: "failed to analyze", - Code: Failure, - } -) diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/basepath.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/basepath.go deleted file mode 100644 index 3761fa0eaa..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/basepath.go +++ /dev/null @@ -1,77 +0,0 @@ -package fsutils - -import ( - "bytes" - "cmp" - "context" - "fmt" - "os/exec" - "path/filepath" - - "github.com/ldez/grignotin/goenv" -) - -// Relative path modes. -const ( - RelativePathModeGoMod = "gomod" - RelativePathModeGitRoot = "gitroot" - RelativePathModeCfg = "cfg" - RelativePathModeWd = "wd" -) - -// OutputPathModeAbsolute path mode used to show absolute paths in output reports (user-facing). -const OutputPathModeAbsolute = "abs" - -func AllRelativePathModes() []string { - return []string{RelativePathModeGoMod, RelativePathModeGitRoot, RelativePathModeCfg, RelativePathModeWd} -} - -func GetBasePath(ctx context.Context, mode, cfgDir string) (string, error) { - mode = cmp.Or(mode, RelativePathModeCfg) - - switch mode { - case RelativePathModeCfg: - if cfgDir == "" { - return GetBasePath(ctx, RelativePathModeWd, cfgDir) - } - - return cfgDir, nil - - case RelativePathModeGoMod: - goMod, err := goenv.GetOne(ctx, goenv.GOMOD) - if err != nil { - return "", fmt.Errorf("get go.mod path: %w", err) - } - - return filepath.Dir(goMod), nil - - case RelativePathModeGitRoot: - root, err := gitRoot(ctx) - if err != nil { - return "", fmt.Errorf("get git root: %w", err) - } - - return root, nil - - case RelativePathModeWd: - wd, err := Getwd() - if err != nil { - return "", fmt.Errorf("get wd: %w", err) - } - - return wd, nil - - default: - return "", fmt.Errorf("unknown relative path mode: %s", mode) - } -} - -func gitRoot(ctx context.Context) (string, error) { - cmd := exec.CommandContext(ctx, "git", "rev-parse", "--show-toplevel") - out, err := cmd.Output() - if err != nil { - return "", err - } - - return string(bytes.TrimSpace(out)), nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/filecache.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/filecache.go deleted file mode 100644 index e91b58748d..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/filecache.go +++ /dev/null @@ -1,65 +0,0 @@ -package fsutils - -import ( - "fmt" - "os" - "sync" - - "github.com/golangci/golangci-lint/v2/pkg/logutils" -) - -type FileCache struct { - files sync.Map -} - -func NewFileCache() *FileCache { - return &FileCache{} -} - -func (fc *FileCache) GetFileBytes(filePath string) ([]byte, error) { - cachedBytes, ok := fc.files.Load(filePath) - if ok { - return cachedBytes.([]byte), nil - } - - fileBytes, err := os.ReadFile(filePath) - if err != nil { - return nil, fmt.Errorf("can't read file %s: %w", filePath, err) - } - - fc.files.Store(filePath, fileBytes) - return fileBytes, nil -} - -func PrettifyBytesCount(n int64) string { - const ( - Multiplexer = 1024 - KiB = 1 * Multiplexer - MiB = KiB * Multiplexer - GiB = MiB * Multiplexer - ) - - if n >= GiB { - return fmt.Sprintf("%.1fGiB", float64(n)/GiB) - } - if n >= MiB { - return fmt.Sprintf("%.1fMiB", float64(n)/MiB) - } - if n >= KiB { - return fmt.Sprintf("%.1fKiB", float64(n)/KiB) - } - return fmt.Sprintf("%dB", n) -} - -func (fc *FileCache) PrintStats(log logutils.Log) { - var size int64 - var mapLen int - fc.files.Range(func(_, fileBytes any) bool { - mapLen++ - size += int64(len(fileBytes.([]byte))) - - return true - }) - - log.Infof("File cache stats: %d entries of total size %s", mapLen, PrettifyBytesCount(size)) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/fsutils.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/fsutils.go deleted file mode 100644 index ead18a5378..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/fsutils.go +++ /dev/null @@ -1,102 +0,0 @@ -package fsutils - -import ( - "fmt" - "os" - "path/filepath" - "sync" -) - -func IsDir(filename string) bool { - fi, err := os.Stat(filename) - return err == nil && fi.IsDir() -} - -var ( - cachedWd string - cachedWdError error - getWdOnce sync.Once - useCache = true -) - -func UseWdCache(use bool) { - useCache = use -} - -func Getwd() (string, error) { - if !useCache { // for tests - return os.Getwd() - } - - getWdOnce.Do(func() { - cachedWd, cachedWdError = os.Getwd() - if cachedWdError != nil { - return - } - - evaluatedWd, err := EvalSymlinks(cachedWd) - if err != nil { - cachedWd, cachedWdError = "", fmt.Errorf("can't eval symlinks on wd %s: %w", cachedWd, err) - return - } - - cachedWd = evaluatedWd - }) - - return cachedWd, cachedWdError -} - -var evalSymlinkCache sync.Map - -type evalSymlinkRes struct { - path string - err error -} - -func EvalSymlinks(path string) (string, error) { - r, ok := evalSymlinkCache.Load(path) - if ok { - er := r.(evalSymlinkRes) - return er.path, er.err - } - - var er evalSymlinkRes - er.path, er.err = evalSymlinks(path) - evalSymlinkCache.Store(path, er) - - return er.path, er.err -} - -func ShortestRelPath(path, wd string) (string, error) { - if wd == "" { // get it if user don't have cached working dir - var err error - wd, err = Getwd() - if err != nil { - return "", fmt.Errorf("can't get working directory: %w", err) - } - } - - evaluatedPath, err := EvalSymlinks(path) - if err != nil { - return "", fmt.Errorf("can't eval symlinks for path %s: %w", path, err) - } - path = evaluatedPath - - // make path absolute and then relative to be able to fix this case: - // we are in `/test` dir, we want to normalize `../test`, and have file `file.go` in this dir; - // it must have normalized path `file.go`, not `../test/file.go`, - var absPath string - if filepath.IsAbs(path) { - absPath = path - } else { - absPath = filepath.Join(wd, path) - } - - relPath, err := filepath.Rel(wd, absPath) - if err != nil { - return "", fmt.Errorf("can't get relative path for path %s and root %s: %w", - absPath, wd, err) - } - - return relPath, nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/fsutils_unix.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/fsutils_unix.go deleted file mode 100644 index 68e762cf4b..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/fsutils_unix.go +++ /dev/null @@ -1,9 +0,0 @@ -//go:build !windows - -package fsutils - -import "path/filepath" - -func evalSymlinks(path string) (string, error) { - return filepath.EvalSymlinks(path) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/fsutils_windows.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/fsutils_windows.go deleted file mode 100644 index 19efb1cfc2..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/fsutils_windows.go +++ /dev/null @@ -1,39 +0,0 @@ -//go:build windows - -package fsutils - -import ( - "errors" - "os" - "path/filepath" - "syscall" -) - -// This is a workaround for the behavior of [filepath.EvalSymlinks], -// which fails with [syscall.ENOTDIR] if the specified path contains a junction on Windows. -// Junctions can occur, for example, when a volume is mounted as a subdirectory inside another drive. -// This can usually happen when using the Dev Drives feature and replacing existing directories. -// See: https://github.com/golang/go/issues/40180 -// -// Since [syscall.ENOTDIR] is only returned when calling [filepath.EvalSymlinks] on Windows -// if part of the presented path is a junction and nothing before was a symlink, -// we simply treat this as NOT symlink, -// because a symlink over the junction makes no sense at all. -func evalSymlinks(path string) (string, error) { - resolved, err := filepath.EvalSymlinks(path) - if err == nil { - return resolved, nil - } - - if !errors.Is(err, syscall.ENOTDIR) { - return "", err - } - - _, err = os.Stat(path) - if err != nil { - return "", err - } - - // If exists, we make the path absolute, to be sure... - return filepath.Abs(path) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/linecache.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/linecache.go deleted file mode 100644 index 2e92264846..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/linecache.go +++ /dev/null @@ -1,68 +0,0 @@ -package fsutils - -import ( - "bytes" - "fmt" - "sync" -) - -type fileLinesCache [][]byte - -type LineCache struct { - files sync.Map - fileCache *FileCache -} - -func NewLineCache(fc *FileCache) *LineCache { - return &LineCache{ - fileCache: fc, - } -} - -// GetLine returns the index1-th (1-based index) line from the file on filePath -func (lc *LineCache) GetLine(filePath string, index1 int) (string, error) { - if index1 == 0 { // some linters, e.g. gosec can do it: it really means first line - index1 = 1 - } - - const index1To0Offset = -1 - rawLine, err := lc.getRawLine(filePath, index1+index1To0Offset) - if err != nil { - return "", err - } - - return string(bytes.Trim(rawLine, "\r")), nil -} - -func (lc *LineCache) getRawLine(filePath string, index0 int) ([]byte, error) { - fc, err := lc.getFileCache(filePath) - if err != nil { - return nil, fmt.Errorf("failed to get file %s lines cache: %w", filePath, err) - } - - if index0 < 0 { - return nil, fmt.Errorf("invalid file line index0 < 0: %d", index0) - } - - if index0 >= len(fc) { - return nil, fmt.Errorf("invalid file line index0 (%d) >= len(fc) (%d)", index0, len(fc)) - } - - return fc[index0], nil -} - -func (lc *LineCache) getFileCache(filePath string) (fileLinesCache, error) { - loadedFc, ok := lc.files.Load(filePath) - if ok { - return loadedFc.(fileLinesCache), nil - } - - fileBytes, err := lc.fileCache.GetFileBytes(filePath) - if err != nil { - return nil, fmt.Errorf("can't get file %s bytes from cache: %w", filePath, err) - } - - fc := bytes.Split(fileBytes, []byte("\n")) - lc.files.Store(filePath, fileLinesCache(fc)) - return fc, nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/path_unix.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/path_unix.go deleted file mode 100644 index 2a171ecc0c..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/path_unix.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build !windows - -package fsutils - -// NormalizePathInRegex it's a noop function on Unix. -func NormalizePathInRegex(path string) string { - return path -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/path_windows.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/path_windows.go deleted file mode 100644 index 650aae1e16..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/fsutils/path_windows.go +++ /dev/null @@ -1,28 +0,0 @@ -//go:build windows - -package fsutils - -import ( - "path/filepath" - "regexp" - "strings" -) - -var separatorToReplace = regexp.QuoteMeta(string(filepath.Separator)) - -// NormalizePathInRegex normalizes path in regular expressions. -// noop on Unix. -// This replacing should be safe because "/" are disallowed in Windows -// https://docs.microsoft.com/windows/win32/fileio/naming-a-file -func NormalizePathInRegex(path string) string { - // remove redundant character escape "\/" https://github.com/golangci/golangci-lint/issues/3277 - clean := regexp.MustCompile(`\\+/`). - ReplaceAllStringFunc(path, func(s string) string { - if strings.Count(s, "\\")%2 == 0 { - return s - } - return s[1:] - }) - - return strings.ReplaceAll(clean, "/", separatorToReplace) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/issue.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/issue.go deleted file mode 100644 index 88a59e53db..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/issue.go +++ /dev/null @@ -1,32 +0,0 @@ -package goanalysis - -import ( - "go/token" - - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -type Issue struct { - *result.Issue - Pass *analysis.Pass -} - -func NewIssue(issue *result.Issue, pass *analysis.Pass) *Issue { - return &Issue{ - Issue: issue, - Pass: pass, - } -} - -type EncodingIssue struct { - FromLinter string - Text string - Severity string - Pos token.Position - LineRange *result.Range - SuggestedFixes []analysis.SuggestedFix - ExpectNoLint bool - ExpectedNoLintLinter string -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/linter.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/linter.go deleted file mode 100644 index 153e538b58..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/linter.go +++ /dev/null @@ -1,253 +0,0 @@ -package goanalysis - -import ( - "context" - "errors" - "flag" - "fmt" - "strings" - - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/v2/pkg/lint/linter" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -type LoadMode int - -func (loadMode LoadMode) String() string { - switch loadMode { - case LoadModeNone: - return "none" - case LoadModeSyntax: - return "syntax" - case LoadModeTypesInfo: - return "types info" - case LoadModeWholeProgram: - return "whole program" - } - panic(fmt.Sprintf("unknown load mode %d", loadMode)) -} - -const ( - LoadModeNone LoadMode = iota - LoadModeSyntax - LoadModeTypesInfo - LoadModeWholeProgram -) - -type Linter struct { - name, desc string - analyzers []*analysis.Analyzer - cfg map[string]map[string]any - issuesReporter func(*linter.Context) []*Issue - contextSetter func(*linter.Context) - loadMode LoadMode - needUseOriginalPackages bool -} - -func NewLinter(name, desc string, analyzers []*analysis.Analyzer, cfg map[string]map[string]any) *Linter { - return &Linter{name: name, desc: desc, analyzers: analyzers, cfg: cfg} -} - -func NewLinterFromAnalyzer(analyzer *analysis.Analyzer) *Linter { - return NewLinter(analyzer.Name, analyzer.Doc, []*analysis.Analyzer{analyzer}, nil) -} - -func (lnt *Linter) Run(_ context.Context, lintCtx *linter.Context) ([]*result.Issue, error) { - if err := lnt.preRun(lintCtx); err != nil { - return nil, err - } - - return runAnalyzers(lnt, lintCtx) -} - -func (lnt *Linter) UseOriginalPackages() { - lnt.needUseOriginalPackages = true -} - -func (lnt *Linter) LoadMode() LoadMode { - return lnt.loadMode -} - -func (lnt *Linter) WithDesc(desc string) *Linter { - lnt.desc = desc - - return lnt -} - -func (lnt *Linter) WithVersion(v int) *Linter { - if v == 0 { - return lnt - } - - for _, analyzer := range lnt.analyzers { - if lnt.name != analyzer.Name { - continue - } - - // The analyzer name should be the same as the linter name to avoid displaying the name inside the reports. - analyzer.Name = fmt.Sprintf("%s_v%d", analyzer.Name, v) - } - - lnt.name = fmt.Sprintf("%s_v%d", lnt.name, v) - - return lnt -} - -func (lnt *Linter) WithConfig(cfg map[string]any) *Linter { - if len(cfg) == 0 { - return lnt - } - - lnt.cfg = map[string]map[string]any{ - lnt.name: cfg, - } - - return lnt -} - -func (lnt *Linter) WithLoadMode(loadMode LoadMode) *Linter { - lnt.loadMode = loadMode - return lnt -} - -func (lnt *Linter) WithIssuesReporter(r func(*linter.Context) []*Issue) *Linter { - lnt.issuesReporter = r - return lnt -} - -func (lnt *Linter) WithContextSetter(cs func(*linter.Context)) *Linter { - lnt.contextSetter = cs - return lnt -} - -func (lnt *Linter) Name() string { - return lnt.name -} - -func (lnt *Linter) Desc() string { - return lnt.desc -} - -func (lnt *Linter) allAnalyzerNames() []string { - var ret []string - for _, a := range lnt.analyzers { - ret = append(ret, a.Name) - } - return ret -} - -func (*Linter) configureAnalyzer(a *analysis.Analyzer, cfg map[string]any) error { - for k, v := range cfg { - f := a.Flags.Lookup(k) - if f == nil { - validFlagNames := allFlagNames(&a.Flags) - if len(validFlagNames) == 0 { - return errors.New("analyzer doesn't have settings") - } - - return fmt.Errorf("analyzer doesn't have setting %q, valid settings: %v", - k, validFlagNames) - } - - if err := f.Value.Set(valueToString(v)); err != nil { - return fmt.Errorf("failed to set analyzer setting %q with value %q: %w", k, v, err) - } - } - - return nil -} - -func (lnt *Linter) configure() error { - analyzersMap := map[string]*analysis.Analyzer{} - for _, a := range lnt.analyzers { - analyzersMap[a.Name] = a - } - - for analyzerName, analyzerSettings := range lnt.cfg { - a := analyzersMap[analyzerName] - if a == nil { - return fmt.Errorf("settings key %q must be valid analyzer name, valid analyzers: %v", - analyzerName, lnt.allAnalyzerNames()) - } - - if err := lnt.configureAnalyzer(a, analyzerSettings); err != nil { - return fmt.Errorf("failed to configure analyzer %s: %w", analyzerName, err) - } - } - - return nil -} - -func (lnt *Linter) preRun(lintCtx *linter.Context) error { - if err := analysis.Validate(lnt.analyzers); err != nil { - return fmt.Errorf("failed to validate analyzers: %w", err) - } - - if err := lnt.configure(); err != nil { - return fmt.Errorf("failed to configure analyzers: %w", err) - } - - if lnt.contextSetter != nil { - lnt.contextSetter(lintCtx) - } - - return nil -} - -func (lnt *Linter) getName() string { - return lnt.name -} - -func (lnt *Linter) getLinterNameForDiagnostic(*Diagnostic) string { - return lnt.name -} - -func (lnt *Linter) getAnalyzers() []*analysis.Analyzer { - return lnt.analyzers -} - -func (lnt *Linter) useOriginalPackages() bool { - return lnt.needUseOriginalPackages -} - -func (lnt *Linter) reportIssues(lintCtx *linter.Context) []*Issue { - if lnt.issuesReporter != nil { - return lnt.issuesReporter(lintCtx) - } - return nil -} - -func (lnt *Linter) getLoadMode() LoadMode { - return lnt.loadMode -} - -func allFlagNames(fs *flag.FlagSet) []string { - var ret []string - fs.VisitAll(func(f *flag.Flag) { - ret = append(ret, f.Name) - }) - return ret -} - -func valueToString(v any) string { - if ss, ok := v.([]string); ok { - return strings.Join(ss, ",") - } - - if is, ok := v.([]any); ok { - var ss []string - for _, i := range is { - ss = append(ss, fmt.Sprint(i)) - } - - return valueToString(ss) - } - - return fmt.Sprint(v) -} - -func DummyRun(_ *analysis.Pass) (any, error) { - return nil, nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/load/guard.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/load/guard.go deleted file mode 100644 index ab7775cc80..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/load/guard.go +++ /dev/null @@ -1,30 +0,0 @@ -package load - -import ( - "sync" - - "golang.org/x/tools/go/packages" -) - -type Guard struct { - loadMutexes map[*packages.Package]*sync.Mutex - mutex sync.Mutex -} - -func NewGuard() *Guard { - return &Guard{ - loadMutexes: map[*packages.Package]*sync.Mutex{}, - } -} - -func (g *Guard) AddMutexForPkg(pkg *packages.Package) { - g.loadMutexes[pkg] = &sync.Mutex{} -} - -func (g *Guard) MutexForPkg(pkg *packages.Package) *sync.Mutex { - return g.loadMutexes[pkg] -} - -func (g *Guard) Mutex() *sync.Mutex { - return &g.mutex -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/metalinter.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/metalinter.go deleted file mode 100644 index b9a210a66f..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/metalinter.go +++ /dev/null @@ -1,90 +0,0 @@ -package goanalysis - -import ( - "context" - "fmt" - - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/v2/pkg/lint/linter" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -type MetaLinter struct { - linters []*Linter - analyzerToLinterName map[*analysis.Analyzer]string -} - -func NewMetaLinter(linters []*Linter) *MetaLinter { - ml := &MetaLinter{linters: linters} - ml.analyzerToLinterName = ml.getAnalyzerToLinterNameMapping() - return ml -} - -func (ml MetaLinter) Run(_ context.Context, lintCtx *linter.Context) ([]*result.Issue, error) { - for _, l := range ml.linters { - if err := l.preRun(lintCtx); err != nil { - return nil, fmt.Errorf("failed to pre-run %s: %w", l.Name(), err) - } - } - - return runAnalyzers(ml, lintCtx) -} - -func (MetaLinter) Name() string { - return "goanalysis_metalinter" -} - -func (MetaLinter) Desc() string { - return "" -} - -func (ml MetaLinter) getLoadMode() LoadMode { - loadMode := LoadModeNone - for _, l := range ml.linters { - if l.loadMode > loadMode { - loadMode = l.loadMode - } - } - return loadMode -} - -func (ml MetaLinter) getAnalyzers() []*analysis.Analyzer { - var allAnalyzers []*analysis.Analyzer - for _, l := range ml.linters { - allAnalyzers = append(allAnalyzers, l.analyzers...) - } - return allAnalyzers -} - -func (MetaLinter) getName() string { - return "metalinter" -} - -func (MetaLinter) useOriginalPackages() bool { - return false // `unused` can't be run by this metalinter -} - -func (ml MetaLinter) reportIssues(lintCtx *linter.Context) []*Issue { - var ret []*Issue - for _, lnt := range ml.linters { - if lnt.issuesReporter != nil { - ret = append(ret, lnt.issuesReporter(lintCtx)...) - } - } - return ret -} - -func (ml MetaLinter) getLinterNameForDiagnostic(diag *Diagnostic) string { - return ml.analyzerToLinterName[diag.Analyzer] -} - -func (ml MetaLinter) getAnalyzerToLinterNameMapping() map[*analysis.Analyzer]string { - analyzerToLinterName := map[*analysis.Analyzer]string{} - for _, l := range ml.linters { - for _, a := range l.analyzers { - analyzerToLinterName[a] = l.Name() - } - } - return analyzerToLinterName -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/pkgerrors/errors.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/pkgerrors/errors.go deleted file mode 100644 index 5d2b816ac6..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/pkgerrors/errors.go +++ /dev/null @@ -1,65 +0,0 @@ -package pkgerrors - -import ( - "errors" - "fmt" - - "golang.org/x/tools/go/packages" - - "github.com/golangci/golangci-lint/v2/pkg/lint/linter" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -type IllTypedError struct { - Pkg *packages.Package -} - -func (e *IllTypedError) Error() string { - return fmt.Sprintf("IllTypedError: errors in package: %v", e.Pkg.Errors) -} - -func BuildIssuesFromIllTypedError(errs []error, lintCtx *linter.Context) ([]*result.Issue, error) { - var issues []*result.Issue - - uniqReportedIssues := map[string]bool{} - - var other error - - for _, err := range errs { - var ill *IllTypedError - if !errors.As(err, &ill) { - if other == nil { - other = err - } - continue - } - - for _, err := range extractErrors(ill.Pkg) { - issue, perr := parseError(err) - if perr != nil { // failed to parse - if uniqReportedIssues[err.Msg] { - continue - } - - uniqReportedIssues[err.Msg] = true - lintCtx.Log.Errorf("typechecking error: %s", err.Msg) - } else { - key := fmt.Sprintf("%s.%d.%d.%s", issue.FilePath(), issue.Line(), issue.Column(), issue.Text) - if uniqReportedIssues[key] { - continue - } - - uniqReportedIssues[key] = true - - issue.Pkg = ill.Pkg // to save to cache later - issues = append(issues, issue) - } - } - } - - if len(issues) == 0 && other != nil { - return nil, other - } - - return issues, nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/pkgerrors/extract.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/pkgerrors/extract.go deleted file mode 100644 index 76a4c90222..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/pkgerrors/extract.go +++ /dev/null @@ -1,125 +0,0 @@ -package pkgerrors - -import ( - "fmt" - "maps" - "regexp" - "strings" - - "golang.org/x/tools/go/packages" -) - -// reFile matches a line who starts with path and position. -// ex: `/example/main.go:11:17: foobar` -var reFile = regexp.MustCompile(`^.+\.go:\d+:\d+: .+`) - -func extractErrors(pkg *packages.Package) []packages.Error { - errors := extractErrorsImpl(pkg, map[*packages.Package]bool{}) - if len(errors) == 0 { - return errors - } - - skippedErrors := map[string]packages.Error{} - seenErrors := map[string]bool{} - - var uniqErrors []packages.Error - for _, err := range errors { - msg := stackCrusher(err.Error()) - if seenErrors[msg] { - continue - } - - // This `if` is important to avoid duplicate errors. - // The goal is to keep the most relevant error. - if msg != err.Error() { - prev, alreadySkip := skippedErrors[msg] - if !alreadySkip { - skippedErrors[msg] = err - continue - } - - if len(err.Error()) < len(prev.Error()) { - skippedErrors[msg] = err - } - - continue - } - - delete(skippedErrors, msg) - - seenErrors[msg] = true - - uniqErrors = append(uniqErrors, err) - } - - // In some cases, the error stack doesn't contain the tip error. - // We must keep at least one of the original errors that contain the specific message. - for skippedError := range maps.Values(skippedErrors) { - uniqErrors = append(uniqErrors, skippedError) - } - - if len(pkg.GoFiles) != 0 { - // errors were extracted from deps and have at least one file in package - for i := range uniqErrors { - if _, parseErr := parseErrorPosition(uniqErrors[i].Pos); parseErr == nil { - continue - } - - // change pos to local file to properly process it by processors (properly read line etc.) - uniqErrors[i].Msg = fmt.Sprintf("%s: %s", uniqErrors[i].Pos, uniqErrors[i].Msg) - uniqErrors[i].Pos = fmt.Sprintf("%s:1", pkg.GoFiles[0]) - } - - // some errors like "code in directory expects import" don't have Pos, set it here - for i := range uniqErrors { - err := &uniqErrors[i] - if err.Pos == "" { - err.Pos = fmt.Sprintf("%s:1", pkg.GoFiles[0]) - } - } - } - - return uniqErrors -} - -func extractErrorsImpl(pkg *packages.Package, seenPackages map[*packages.Package]bool) []packages.Error { - if seenPackages[pkg] { - return nil - } - seenPackages[pkg] = true - - if !pkg.IllTyped { // otherwise, it may take hours to traverse all deps many times - return nil - } - - if len(pkg.Errors) > 0 { - return pkg.Errors - } - - var errors []packages.Error - for _, iPkg := range pkg.Imports { - iPkgErrors := extractErrorsImpl(iPkg, seenPackages) - if iPkgErrors != nil { - errors = append(errors, iPkgErrors...) - } - } - - return errors -} - -func stackCrusher(msg string) string { - index := strings.Index(msg, "(") - lastIndex := strings.LastIndex(msg, ")") - - if index == -1 || index == len(msg)-1 || lastIndex == -1 || lastIndex != len(msg)-1 { - return msg - } - - frag := msg[index+1 : lastIndex] - - if !reFile.MatchString(frag) { - return msg - } - - return stackCrusher(frag) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/pkgerrors/parse.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/pkgerrors/parse.go deleted file mode 100644 index 2fe1fb529f..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/pkgerrors/parse.go +++ /dev/null @@ -1,54 +0,0 @@ -package pkgerrors - -import ( - "errors" - "fmt" - "go/token" - "strconv" - "strings" - - "golang.org/x/tools/go/packages" - - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -func parseError(srcErr packages.Error) (*result.Issue, error) { - pos, err := parseErrorPosition(srcErr.Pos) - if err != nil { - return nil, err - } - - return &result.Issue{ - Pos: *pos, - Text: srcErr.Msg, - FromLinter: "typecheck", - }, nil -} - -func parseErrorPosition(pos string) (*token.Position, error) { - // file:line(:column) - parts := strings.Split(pos, ":") - if len(parts) == 1 { - return nil, errors.New("no colons") - } - - file := parts[0] - line, err := strconv.Atoi(parts[1]) - if err != nil { - return nil, fmt.Errorf("can't parse line number %q: %w", parts[1], err) - } - - var column int - if len(parts) == 3 { // got column - column, err = strconv.Atoi(parts[2]) - if err != nil { - return nil, fmt.Errorf("failed to parse column from %q: %w", parts[2], err) - } - } - - return &token.Position{ - Filename: file, - Line: line, - Column: column, - }, nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/position.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/position.go deleted file mode 100644 index 28441b341a..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/position.go +++ /dev/null @@ -1,50 +0,0 @@ -package goanalysis - -import ( - "go/ast" - "go/token" - "path/filepath" - - "golang.org/x/tools/go/analysis" -) - -func GetGoFilePosition(pass *analysis.Pass, f *ast.File) (token.Position, bool) { - position := GetFilePositionFor(pass.Fset, f.Pos()) - - if filepath.Ext(position.Filename) == ".go" { - return position, true - } - - return position, false -} - -func GetFilePositionFor(fset *token.FileSet, p token.Pos) token.Position { - pos := fset.PositionFor(p, true) - - ext := filepath.Ext(pos.Filename) - if ext != ".go" { - // position has been adjusted to a non-go file, revert to original file - return fset.PositionFor(p, false) - } - - return pos -} - -func EndOfLinePos(f *token.File, line int) token.Pos { - var end token.Pos - - if line >= f.LineCount() { - // missing newline at the end of the file - end = f.Pos(f.Size()) - } else { - end = f.LineStart(line+1) - token.Pos(1) - } - - return end -} - -// AdjustPos is a hack to get the right line to display. -// It should not be used outside some specific cases. -func AdjustPos(line, nonAdjLine, adjLine int) int { - return line + nonAdjLine - adjLine -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner.go deleted file mode 100644 index ba9c0bd066..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner.go +++ /dev/null @@ -1,348 +0,0 @@ -// Package goanalysis defines the implementation of the checker commands. -// The same code drives the multi-analysis driver, the single-analysis -// driver that is conventionally provided for convenience along with -// each analysis package, and the test driver. -package goanalysis - -import ( - "context" - "encoding/gob" - "fmt" - "go/token" - "maps" - "runtime" - "slices" - "sync" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/packages" - - "github.com/golangci/golangci-lint/v2/internal/cache" - "github.com/golangci/golangci-lint/v2/internal/errorutil" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis/load" - "github.com/golangci/golangci-lint/v2/pkg/logutils" - "github.com/golangci/golangci-lint/v2/pkg/timeutils" -) - -var ( - debugf = logutils.Debug(logutils.DebugKeyGoAnalysis) - - analyzeDebugf = logutils.Debug(logutils.DebugKeyGoAnalysisAnalyze) - isMemoryDebug = logutils.HaveDebugTag(logutils.DebugKeyGoAnalysisMemory) - issuesCacheDebugf = logutils.Debug(logutils.DebugKeyGoAnalysisIssuesCache) - - factsDebugf = logutils.Debug(logutils.DebugKeyGoAnalysisFacts) - factsCacheDebugf = logutils.Debug(logutils.DebugKeyGoAnalysisFactsCache) - factsInheritDebugf = logutils.Debug(logutils.DebugKeyGoAnalysisFactsInherit) - factsExportDebugf = logutils.Debug(logutils.DebugKeyGoAnalysisFacts) - isFactsExportDebug = logutils.HaveDebugTag(logutils.DebugKeyGoAnalysisFactsExport) -) - -type Diagnostic struct { - analysis.Diagnostic - Analyzer *analysis.Analyzer - Position token.Position - Pkg *packages.Package - File *token.File -} - -type runner struct { - log logutils.Log - prefix string // ensure unique analyzer names - pkgCache *cache.Cache - loadGuard *load.Guard - loadMode LoadMode - passToPkg map[*analysis.Pass]*packages.Package - passToPkgGuard sync.Mutex - sw *timeutils.Stopwatch -} - -func newRunner(prefix string, logger logutils.Log, pkgCache *cache.Cache, loadGuard *load.Guard, - loadMode LoadMode, sw *timeutils.Stopwatch, -) *runner { - return &runner{ - prefix: prefix, - log: logger, - pkgCache: pkgCache, - loadGuard: loadGuard, - loadMode: loadMode, - passToPkg: map[*analysis.Pass]*packages.Package{}, - sw: sw, - } -} - -// Run loads the packages specified by args using go/packages, -// then applies the specified analyzers to them. -// Analysis flags must already have been set. -// It provides most of the logic for the main functions of both the -// singlechecker and the multi-analysis commands. -// It returns the appropriate exit code. -func (r *runner) run(analyzers []*analysis.Analyzer, initialPackages []*packages.Package) ([]*Diagnostic, - []error, map[*analysis.Pass]*packages.Package, -) { - debugf("Analyzing %d packages on load mode %s", len(initialPackages), r.loadMode) - - roots := r.analyze(initialPackages, analyzers) - - diags, errs := extractDiagnostics(roots) - - return diags, errs, r.passToPkg -} - -type actKey struct { - *analysis.Analyzer - *packages.Package -} - -func (r *runner) markAllActions(a *analysis.Analyzer, pkg *packages.Package, markedActions map[actKey]struct{}) { - k := actKey{a, pkg} - if _, ok := markedActions[k]; ok { - return - } - - for _, req := range a.Requires { - r.markAllActions(req, pkg, markedActions) - } - - if len(a.FactTypes) != 0 { - for path := range pkg.Imports { - r.markAllActions(a, pkg.Imports[path], markedActions) - } - } - - markedActions[k] = struct{}{} -} - -func (r *runner) makeAction(a *analysis.Analyzer, pkg *packages.Package, - initialPkgs map[*packages.Package]bool, actions map[actKey]*action, actAlloc *actionAllocator, -) *action { - k := actKey{a, pkg} - act, ok := actions[k] - if ok { - return act - } - - act = actAlloc.alloc() - act.Analyzer = a - act.Package = pkg - act.runner = r - act.isInitialPkg = initialPkgs[pkg] - act.needAnalyzeSource = initialPkgs[pkg] - act.analysisDoneCh = make(chan struct{}) - - depsCount := len(a.Requires) - if len(a.FactTypes) > 0 { - depsCount += len(pkg.Imports) - } - act.Deps = make([]*action, 0, depsCount) - - // Add a dependency on each required analyzers. - for _, req := range a.Requires { - act.Deps = append(act.Deps, r.makeAction(req, pkg, initialPkgs, actions, actAlloc)) - } - - r.buildActionFactDeps(act, a, pkg, initialPkgs, actions, actAlloc) - - actions[k] = act - - return act -} - -func (r *runner) buildActionFactDeps(act *action, a *analysis.Analyzer, pkg *packages.Package, - initialPkgs map[*packages.Package]bool, actions map[actKey]*action, actAlloc *actionAllocator, -) { - // An analysis that consumes/produces facts - // must run on the package's dependencies too. - if len(a.FactTypes) == 0 { - return - } - - act.objectFacts = make(map[objectFactKey]analysis.Fact) - act.packageFacts = make(map[packageFactKey]analysis.Fact) - - paths := slices.Sorted(maps.Keys(pkg.Imports)) // for determinism - - for _, path := range paths { - dep := r.makeAction(a, pkg.Imports[path], initialPkgs, actions, actAlloc) - act.Deps = append(act.Deps, dep) - } - - // Need to register fact types for pkgcache proper gob encoding. - for _, f := range a.FactTypes { - gob.Register(f) - } -} - -func (r *runner) prepareAnalysis(pkgs []*packages.Package, - analyzers []*analysis.Analyzer, -) (initialPkgs map[*packages.Package]bool, allActions, roots []*action) { - // Construct the action graph. - - // Each graph node (action) is one unit of analysis. - // Edges express package-to-package (vertical) dependencies, - // and analysis-to-analysis (horizontal) dependencies. - - // This place is memory-intensive: e.g. Istio project has 120k total actions. - // Therefore, optimize it carefully. - markedActions := make(map[actKey]struct{}, len(analyzers)*len(pkgs)) - for _, a := range analyzers { - for _, pkg := range pkgs { - r.markAllActions(a, pkg, markedActions) - } - } - totalActionsCount := len(markedActions) - - actions := make(map[actKey]*action, totalActionsCount) - actAlloc := newActionAllocator(totalActionsCount) - - initialPkgs = make(map[*packages.Package]bool, len(pkgs)) - for _, pkg := range pkgs { - initialPkgs[pkg] = true - } - - // Build nodes for initial packages. - roots = make([]*action, 0, len(pkgs)*len(analyzers)) - for _, a := range analyzers { - for _, pkg := range pkgs { - root := r.makeAction(a, pkg, initialPkgs, actions, actAlloc) - root.IsRoot = true - roots = append(roots, root) - } - } - - allActions = slices.Collect(maps.Values(actions)) - - debugf("Built %d actions", len(actions)) - - return initialPkgs, allActions, roots -} - -func (r *runner) analyze(pkgs []*packages.Package, analyzers []*analysis.Analyzer) []*action { - initialPkgs, actions, rootActions := r.prepareAnalysis(pkgs, analyzers) - - actionPerPkg := map[*packages.Package][]*action{} - for _, act := range actions { - actionPerPkg[act.Package] = append(actionPerPkg[act.Package], act) - } - - // Fill Imports field. - loadingPackages := map[*packages.Package]*loadingPackage{} - var dfs func(pkg *packages.Package) - dfs = func(pkg *packages.Package) { - if loadingPackages[pkg] != nil { - return - } - - imports := map[string]*loadingPackage{} - for impPath, imp := range pkg.Imports { - dfs(imp) - impLp := loadingPackages[imp] - impLp.dependents++ - imports[impPath] = impLp - } - - loadingPackages[pkg] = &loadingPackage{ - pkg: pkg, - imports: imports, - isInitial: initialPkgs[pkg], - log: r.log, - actions: actionPerPkg[pkg], - loadGuard: r.loadGuard, - dependents: 1, // self dependent - } - } - for _, act := range actions { - dfs(act.Package) - } - - // Limit memory and IO usage. - gomaxprocs := runtime.GOMAXPROCS(-1) - debugf("Analyzing at most %d packages in parallel", gomaxprocs) - - loadSem := make(chan struct{}, gomaxprocs) - - debugf("There are %d initial and %d total packages", len(initialPkgs), len(loadingPackages)) - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - var wg sync.WaitGroup - - for _, lp := range loadingPackages { - if lp.isInitial { - wg.Add(1) - - go func(lp *loadingPackage) { - lp.analyzeRecursive(ctx, cancel, r.loadMode, loadSem) - - wg.Done() - }(lp) - } - } - - wg.Wait() - - return rootActions -} - -func extractDiagnostics(roots []*action) (retDiags []*Diagnostic, retErrors []error) { - extracted := make(map[*action]bool) - var extract func(*action) - var visitAll func(actions []*action) - visitAll = func(actions []*action) { - for _, act := range actions { - if !extracted[act] { - extracted[act] = true - visitAll(act.Deps) - extract(act) - } - } - } - - // De-duplicate diagnostics by position (not token.Pos) to - // avoid double-reporting in source files that belong to - // multiple packages, such as foo and foo.test. - type key struct { - token.Position - *analysis.Analyzer - message string - } - seen := make(map[key]bool) - - extract = func(act *action) { - if act.Err != nil { - if pe, ok := act.Err.(*errorutil.PanicError); ok { - panic(pe) - } - retErrors = append(retErrors, fmt.Errorf("%s: %w", act.Analyzer.Name, act.Err)) - return - } - - if act.IsRoot { - for _, diag := range act.Diagnostics { - // We don't display a.Name/f.Category - // as most users don't care. - - position := GetFilePositionFor(act.Package.Fset, diag.Pos) - file := act.Package.Fset.File(diag.Pos) - - k := key{Position: position, Analyzer: act.Analyzer, message: diag.Message} - if seen[k] { - continue // duplicate - } - seen[k] = true - - retDiag := &Diagnostic{ - File: file, - Diagnostic: diag, - Analyzer: act.Analyzer, - Position: position, - Pkg: act.Package, - } - retDiags = append(retDiags, retDiag) - } - } - } - visitAll(roots) - return retDiags, retErrors -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_action.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_action.go deleted file mode 100644 index eafc2e4d88..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_action.go +++ /dev/null @@ -1,71 +0,0 @@ -package goanalysis - -import ( - "context" - "fmt" - "runtime/debug" - - "github.com/golangci/golangci-lint/v2/internal/errorutil" -) - -type actionAllocator struct { - allocatedActions []action - nextFreeIndex int -} - -func newActionAllocator(maxCount int) *actionAllocator { - return &actionAllocator{ - allocatedActions: make([]action, maxCount), - nextFreeIndex: 0, - } -} - -func (actAlloc *actionAllocator) alloc() *action { - if actAlloc.nextFreeIndex == len(actAlloc.allocatedActions) { - panic(fmt.Sprintf("Made too many allocations of actions: %d allowed", len(actAlloc.allocatedActions))) - } - act := &actAlloc.allocatedActions[actAlloc.nextFreeIndex] - actAlloc.nextFreeIndex++ - return act -} - -func (act *action) waitUntilDependingAnalyzersWorked(ctx context.Context) { - for _, dep := range act.Deps { - if dep.Package == act.Package { - select { - case <-ctx.Done(): - return - case <-dep.analysisDoneCh: - } - } - } -} - -func (act *action) analyzeSafe() { - defer func() { - if p := recover(); p != nil { - if !act.IsRoot { - // This line allows to display "hidden" panic with analyzers like buildssa. - // Some linters are dependent of sub-analyzers but when a sub-analyzer fails the linter is not aware of that, - // this results to another panic (ex: "interface conversion: interface {} is nil, not *buildssa.SSA"). - act.runner.log.Errorf("%s: panic during analysis: %v, %s", act.Analyzer.Name, p, string(debug.Stack())) - } - - act.Err = errorutil.NewPanicError(fmt.Sprintf("%s: package %q (isInitialPkg: %t, needAnalyzeSource: %t): %s", - act.Analyzer.Name, act.Package.Name, act.isInitialPkg, act.needAnalyzeSource, p), debug.Stack()) - } - }() - - act.runner.sw.TrackStage(act.Analyzer.Name, act.analyze) -} - -func (act *action) markDepsForAnalyzingSource() { - // Horizontal deps (analyzer.Requires) must be loaded from source and analyzed before analyzing - // this action. - for _, dep := range act.Deps { - if dep.Package == act.Package { - // Analyze source only for horizontal dependencies, e.g. from "buildssa". - dep.needAnalyzeSource = true // can't be set in parallel - } - } -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_action_cache.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_action_cache.go deleted file mode 100644 index 2cf4dcfcab..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_action_cache.go +++ /dev/null @@ -1,127 +0,0 @@ -package goanalysis - -import ( - "errors" - "fmt" - "io" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/types/objectpath" - - "github.com/golangci/golangci-lint/v2/internal/cache" -) - -type Fact struct { - Path string // non-empty only for object facts - Fact analysis.Fact -} - -func (act *action) loadCachedFacts() bool { - if act.loadCachedFactsDone { // can't be set in parallel - return act.loadCachedFactsOk - } - - res := func() bool { - if act.isInitialPkg { - return true // load cached facts only for non-initial packages - } - - if len(act.Analyzer.FactTypes) == 0 { - return true // no need to load facts - } - - return act.loadPersistedFacts() - }() - act.loadCachedFactsDone = true - act.loadCachedFactsOk = res - return res -} - -func (act *action) persistFactsToCache() error { - analyzer := act.Analyzer - if len(analyzer.FactTypes) == 0 { - return nil - } - - // Merge new facts into the package and persist them. - var facts []Fact - for key, fact := range act.packageFacts { - if key.pkg != act.Package.Types { - // The fact is from inherited facts from another package - continue - } - facts = append(facts, Fact{ - Path: "", - Fact: fact, - }) - } - for key, fact := range act.objectFacts { - obj := key.obj - if obj.Pkg() != act.Package.Types { - // The fact is from inherited facts from another package - continue - } - - path, err := objectpath.For(obj) - if err != nil { - // The object is not globally addressable - continue - } - - facts = append(facts, Fact{ - Path: string(path), - Fact: fact, - }) - } - - factsCacheDebugf("Caching %d facts for package %q and analyzer %s", len(facts), act.Package.Name, act.Analyzer.Name) - - return act.runner.pkgCache.Put(act.Package, cache.HashModeNeedAllDeps, factCacheKey(analyzer), facts) -} - -func (act *action) loadPersistedFacts() bool { - var facts []Fact - - err := act.runner.pkgCache.Get(act.Package, cache.HashModeNeedAllDeps, factCacheKey(act.Analyzer), &facts) - if err != nil { - if !errors.Is(err, cache.ErrMissing) && !errors.Is(err, io.EOF) { - act.runner.log.Warnf("Failed to get persisted facts: %s", err) - } - - factsCacheDebugf("No cached facts for package %q and analyzer %s", act.Package.Name, act.Analyzer.Name) - return false - } - - factsCacheDebugf("Loaded %d cached facts for package %q and analyzer %s", len(facts), act.Package.Name, act.Analyzer.Name) - - for _, f := range facts { - if f.Path == "" { // this is a package fact - key := packageFactKey{act.Package.Types, act.factType(f.Fact)} - act.packageFacts[key] = f.Fact - continue - } - obj, err := objectpath.Object(act.Package.Types, objectpath.Path(f.Path)) - if err != nil { - // Be lenient about these errors. For example, when - // analyzing io/ioutil from source, we may get a fact - // for methods on the devNull type, and objectpath - // will happily create a path for them. However, when - // we later load io/ioutil from export data, the path - // no longer resolves. - // - // If an exported type embeds the unexported type, - // then (part of) the unexported type will become part - // of the type information and our path will resolve - // again. - continue - } - factKey := objectFactKey{obj, act.factType(f.Fact)} - act.objectFacts[factKey] = f.Fact - } - - return true -} - -func factCacheKey(a *analysis.Analyzer) string { - return fmt.Sprintf("%s/facts", a.Name) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_checker.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_checker.go deleted file mode 100644 index e8fda9947f..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_checker.go +++ /dev/null @@ -1,447 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. -// -// Altered copy of https://github.com/golang/tools/blob/v0.28.0/go/analysis/internal/checker/checker.go - -package goanalysis - -import ( - "bytes" - "encoding/gob" - "errors" - "fmt" - "go/types" - "os" - "reflect" - "time" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/packages" - - "github.com/golangci/golangci-lint/v2/internal/x/tools/analysisflags" - "github.com/golangci/golangci-lint/v2/internal/x/tools/analysisinternal" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis/pkgerrors" -) - -// NOTE(ldez) altered: custom fields; remove 'once' and 'duration'. -// An action represents one unit of analysis work: the application of -// one analysis to one package. Actions form a DAG, both within a -// package (as different analyzers are applied, either in sequence or -// parallel), and across packages (as dependencies are analyzed). -type action struct { - Analyzer *analysis.Analyzer - Package *packages.Package - IsRoot bool // whether this is a root node of the graph - Deps []*action - Result any // computed result of Analyzer.run, if any (and if IsRoot) - Err error // error result of Analyzer.run - Diagnostics []analysis.Diagnostic - Duration time.Duration // execution time of this step - - pass *analysis.Pass - objectFacts map[objectFactKey]analysis.Fact - packageFacts map[packageFactKey]analysis.Fact - - // NOTE(ldez) custom fields. - runner *runner - analysisDoneCh chan struct{} - loadCachedFactsDone bool - loadCachedFactsOk bool - isInitialPkg bool - needAnalyzeSource bool -} - -// NOTE(ldez) no alteration. -type objectFactKey struct { - obj types.Object - typ reflect.Type -} - -// NOTE(ldez) no alteration. -type packageFactKey struct { - pkg *types.Package - typ reflect.Type -} - -// NOTE(ldez) no alteration. -func (act *action) String() string { - return fmt.Sprintf("%s@%s", act.Analyzer, act.Package) -} - -// NOTE(ldez) altered version of `func (act *action) execOnce()`. -func (act *action) analyze() { - defer close(act.analysisDoneCh) // unblock actions depending on this action - - if !act.needAnalyzeSource { - return - } - - // Record time spent in this node but not its dependencies. - // In parallel mode, due to GC/scheduler contention, the - // time is 5x higher than in sequential mode, even with a - // semaphore limiting the number of threads here. - // So use -debug=tp. - t0 := time.Now() - defer func() { - act.Duration = time.Since(t0) - analyzeDebugf("go/analysis: %s: %s: analyzed package %q in %s", act.runner.prefix, act.Analyzer.Name, act.Package.Name, time.Since(t0)) - }() - - // Report an error if any dependency failures. - var depErrors error - for _, dep := range act.Deps { - if dep.Err != nil { - depErrors = errors.Join(depErrors, errors.Unwrap(dep.Err)) - } - } - if depErrors != nil { - act.Err = fmt.Errorf("failed prerequisites: %w", depErrors) - return - } - - // Plumb the output values of the dependencies - // into the inputs of this action. Also facts. - inputs := make(map[*analysis.Analyzer]any) - act.objectFacts = make(map[objectFactKey]analysis.Fact) - act.packageFacts = make(map[packageFactKey]analysis.Fact) - for _, dep := range act.Deps { - if dep.Package == act.Package { - // Same package, different analysis (horizontal edge): - // in-memory outputs of prerequisite analyzers - // become inputs to this analysis pass. - inputs[dep.Analyzer] = dep.Result - - } else if dep.Analyzer == act.Analyzer { // (always true) - // Same analysis, different package (vertical edge): - // serialized facts produced by prerequisite analysis - // become available to this analysis pass. - inheritFacts(act, dep) - } - } - - // NOTE(ldez) this is not compatible with our implementation. - // Quick (nonexhaustive) check that the correct go/packages mode bits were used. - // (If there were errors, all bets are off.) - // if pkg := act.Package; pkg.Errors == nil { - // if pkg.Name == "" || pkg.PkgPath == "" || pkg.Types == nil || pkg.Fset == nil || pkg.TypesSizes == nil { - // panic(fmt.Sprintf("packages must be loaded with packages.LoadSyntax mode: Name: %v, PkgPath: %v, Types: %v, Fset: %v, TypesSizes: %v", - // pkg.Name == "", pkg.PkgPath == "", pkg.Types == nil, pkg.Fset == nil, pkg.TypesSizes == nil)) - // } - // } - - factsDebugf("%s: Inherited facts in %s", act, time.Since(t0)) - - module := &analysis.Module{} // possibly empty (non nil) in go/analysis drivers. - if mod := act.Package.Module; mod != nil { - module.Path = mod.Path - module.Version = mod.Version - module.GoVersion = mod.GoVersion - } - - // Run the analysis. - pass := &analysis.Pass{ - Analyzer: act.Analyzer, - Fset: act.Package.Fset, - Files: act.Package.Syntax, - OtherFiles: act.Package.OtherFiles, - IgnoredFiles: act.Package.IgnoredFiles, - Pkg: act.Package.Types, - TypesInfo: act.Package.TypesInfo, - TypesSizes: act.Package.TypesSizes, - TypeErrors: act.Package.TypeErrors, - Module: module, - - ResultOf: inputs, - Report: func(d analysis.Diagnostic) { act.Diagnostics = append(act.Diagnostics, d) }, - ImportObjectFact: act.ObjectFact, - ExportObjectFact: act.exportObjectFact, - ImportPackageFact: act.PackageFact, - ExportPackageFact: act.exportPackageFact, - AllObjectFacts: act.AllObjectFacts, - AllPackageFacts: act.AllPackageFacts, - } - pass.ReadFile = analysisinternal.CheckedReadFile(pass, os.ReadFile) - act.pass = pass - - act.runner.passToPkgGuard.Lock() - act.runner.passToPkg[pass] = act.Package - act.runner.passToPkgGuard.Unlock() - - act.Result, act.Err = func() (any, error) { - // NOTE(golangci-lint): - // It looks like there should be !pass.Analyzer.RunDespiteErrors - // but govet's cgocall crashes on it. - // Govet itself contains !pass.Analyzer.RunDespiteErrors condition here, - // but it exits before it if packages.Load have failed. - if act.Package.IllTyped { - return nil, fmt.Errorf("analysis skipped: %w", &pkgerrors.IllTypedError{Pkg: act.Package}) - } - - t1 := time.Now() - - result, err := pass.Analyzer.Run(pass) - if err != nil { - return nil, err - } - - analyzedIn := time.Since(t1) - if analyzedIn > 10*time.Millisecond { - debugf("%s: run analyzer in %s", act, analyzedIn) - } - - // correct result type? - if got, want := reflect.TypeOf(result), pass.Analyzer.ResultType; got != want { - return nil, fmt.Errorf( - "internal error: on package %s, analyzer %s returned a result of type %v, but declared ResultType %v", - pass.Pkg.Path(), pass.Analyzer, got, want) - } - - // resolve diagnostic URLs - for i := range act.Diagnostics { - url, err := analysisflags.ResolveURL(act.Analyzer, act.Diagnostics[i]) - if err != nil { - return nil, err - } - act.Diagnostics[i].URL = url - } - return result, nil - }() - - // Help detect (disallowed) calls after Run. - pass.ExportObjectFact = nil - pass.ExportPackageFact = nil - - err := act.persistFactsToCache() - if err != nil { - act.runner.log.Warnf("Failed to persist facts to cache: %s", err) - } -} - -// NOTE(ldez) altered: logger; sanityCheck. -// inheritFacts populates act.facts with -// those it obtains from its dependency, dep. -func inheritFacts(act, dep *action) { - const sanityCheck = false - - for key, fact := range dep.objectFacts { - // Filter out facts related to objects - // that are irrelevant downstream - // (equivalently: not in the compiler export data). - if !exportedFrom(key.obj, dep.Package.Types) { - factsInheritDebugf("%v: discarding %T fact from %s for %s: %s", act, fact, dep, key.obj, fact) - continue - } - - // Optionally serialize/deserialize fact - // to verify that it works across address spaces. - if sanityCheck { - encodedFact, err := codeFact(fact) - if err != nil { - act.runner.log.Panicf("internal error: encoding of %T fact failed in %v: %v", fact, act, err) - } - fact = encodedFact - } - - factsInheritDebugf("%v: inherited %T fact for %s: %s", act, fact, key.obj, fact) - - act.objectFacts[key] = fact - } - - for key, fact := range dep.packageFacts { - // TODO: filter out facts that belong to - // packages not mentioned in the export data - // to prevent side channels. - // - // The Pass.All{Object,Package}Facts accessors expose too much: - // all facts, of all types, for all dependencies in the action - // graph. Not only does the representation grow quadratically, - // but it violates the separate compilation paradigm, allowing - // analysis implementations to communicate with indirect - // dependencies that are not mentioned in the export data. - // - // It's not clear how to fix this short of a rather expensive - // filtering step after each action that enumerates all the - // objects that would appear in export data, and deletes - // facts associated with objects not in this set. - - // Optionally serialize/deserialize fact - // to verify that it works across address spaces - // and is deterministic. - if sanityCheck { - encodedFact, err := codeFact(fact) - if err != nil { - act.runner.log.Panicf("internal error: encoding of %T fact failed in %v", fact, act) - } - fact = encodedFact - } - - factsInheritDebugf("%v: inherited %T fact for %s: %s", act, fact, key.pkg.Path(), fact) - - act.packageFacts[key] = fact - } -} - -// NOTE(ldez) altered: `new` is renamed to `newFact`. -// codeFact encodes then decodes a fact, -// just to exercise that logic. -func codeFact(fact analysis.Fact) (analysis.Fact, error) { - // We encode facts one at a time. - // A real modular driver would emit all facts - // into one encoder to improve gob efficiency. - var buf bytes.Buffer - if err := gob.NewEncoder(&buf).Encode(fact); err != nil { - return nil, err - } - - // Encode it twice and assert that we get the same bits. - // This helps detect nondeterministic Gob encoding (e.g. of maps). - var buf2 bytes.Buffer - if err := gob.NewEncoder(&buf2).Encode(fact); err != nil { - return nil, err - } - if !bytes.Equal(buf.Bytes(), buf2.Bytes()) { - return nil, fmt.Errorf("encoding of %T fact is nondeterministic", fact) - } - - newFact := reflect.New(reflect.TypeOf(fact).Elem()).Interface().(analysis.Fact) - if err := gob.NewDecoder(&buf).Decode(newFact); err != nil { - return nil, err - } - return newFact, nil -} - -// NOTE(ldez) no alteration. -// exportedFrom reports whether obj may be visible to a package that imports pkg. -// This includes not just the exported members of pkg, but also unexported -// constants, types, fields, and methods, perhaps belonging to other packages, -// that find there way into the API. -// This is an overapproximation of the more accurate approach used by -// gc export data, which walks the type graph, but it's much simpler. -// -// TODO(adonovan): do more accurate filtering by walking the type graph. -func exportedFrom(obj types.Object, pkg *types.Package) bool { - switch obj := obj.(type) { - case *types.Func: - return obj.Exported() && obj.Pkg() == pkg || - obj.Type().(*types.Signature).Recv() != nil - case *types.Var: - if obj.IsField() { - return true - } - // we can't filter more aggressively than this because we need - // to consider function parameters exported, but have no way - // of telling apart function parameters from local variables. - return obj.Pkg() == pkg - case *types.TypeName, *types.Const: - return true - } - return false // Nil, Builtin, Label, or PkgName -} - -// NOTE(ldez) altered: logger; `act.factType`. -// ObjectFact retrieves a fact associated with obj, -// and returns true if one was found. -// Given a value ptr of type *T, where *T satisfies Fact, -// ObjectFact copies the value to *ptr. -// -// See documentation at ImportObjectFact field of [analysis.Pass]. -func (act *action) ObjectFact(obj types.Object, ptr analysis.Fact) bool { - if obj == nil { - panic("nil object") - } - key := objectFactKey{obj, act.factType(ptr)} - if v, ok := act.objectFacts[key]; ok { - reflect.ValueOf(ptr).Elem().Set(reflect.ValueOf(v).Elem()) - return true - } - return false -} - -// NOTE(ldez) altered: logger; `act.factType`. -// exportObjectFact implements Pass.ExportObjectFact. -func (act *action) exportObjectFact(obj types.Object, fact analysis.Fact) { - if act.pass.ExportObjectFact == nil { - act.runner.log.Panicf("%s: Pass.ExportObjectFact(%s, %T) called after Run", act, obj, fact) - } - - if obj.Pkg() != act.Package.Types { - act.runner.log.Panicf("internal error: in analysis %s of package %s: Fact.Set(%s, %T): can't set facts on objects belonging another package", - act.Analyzer, act.Package, obj, fact) - } - - key := objectFactKey{obj, act.factType(fact)} - act.objectFacts[key] = fact // clobber any existing entry - if isFactsExportDebug { - objstr := types.ObjectString(obj, (*types.Package).Name) - - factsExportDebugf("%s: object %s has fact %s\n", - act.Package.Fset.Position(obj.Pos()), objstr, fact) - } -} - -// NOTE(ldez) no alteration. -// AllObjectFacts returns a new slice containing all object facts of -// the analysis's FactTypes in unspecified order. -// -// See documentation at AllObjectFacts field of [analysis.Pass]. -func (act *action) AllObjectFacts() []analysis.ObjectFact { - facts := make([]analysis.ObjectFact, 0, len(act.objectFacts)) - for k := range act.objectFacts { - facts = append(facts, analysis.ObjectFact{Object: k.obj, Fact: act.objectFacts[k]}) - } - return facts -} - -// NOTE(ldez) altered: `act.factType`. -// PackageFact retrieves a fact associated with package pkg, -// which must be this package or one of its dependencies. -// -// See documentation at ImportObjectFact field of [analysis.Pass]. -func (act *action) PackageFact(pkg *types.Package, ptr analysis.Fact) bool { - if pkg == nil { - panic("nil package") - } - key := packageFactKey{pkg, act.factType(ptr)} - if v, ok := act.packageFacts[key]; ok { - reflect.ValueOf(ptr).Elem().Set(reflect.ValueOf(v).Elem()) - return true - } - return false -} - -// NOTE(ldez) altered: logger; `act.factType`. -// exportPackageFact implements Pass.ExportPackageFact. -func (act *action) exportPackageFact(fact analysis.Fact) { - if act.pass.ExportPackageFact == nil { - act.runner.log.Panicf("%s: Pass.ExportPackageFact(%T) called after Run", act, fact) - } - - key := packageFactKey{act.pass.Pkg, act.factType(fact)} - act.packageFacts[key] = fact // clobber any existing entry - - factsDebugf("%s: package %s has fact %s\n", - act.Package.Fset.Position(act.pass.Files[0].Pos()), act.pass.Pkg.Path(), fact) -} - -// NOTE(ldez) altered: add receiver to handle logs. -func (act *action) factType(fact analysis.Fact) reflect.Type { - t := reflect.TypeOf(fact) - if t.Kind() != reflect.Ptr { - act.runner.log.Fatalf("invalid Fact type: got %T, want pointer", fact) - } - return t -} - -// NOTE(ldez) no alteration. -// AllPackageFacts returns a new slice containing all package -// facts of the analysis's FactTypes in unspecified order. -// -// See documentation at AllPackageFacts field of [analysis.Pass]. -func (act *action) AllPackageFacts() []analysis.PackageFact { - facts := make([]analysis.PackageFact, 0, len(act.packageFacts)) - for k, fact := range act.packageFacts { - facts = append(facts, analysis.PackageFact{Package: k.pkg, Fact: fact}) - } - return facts -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_loadingpackage.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_loadingpackage.go deleted file mode 100644 index 217803bba7..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_loadingpackage.go +++ /dev/null @@ -1,564 +0,0 @@ -package goanalysis - -import ( - "context" - "errors" - "fmt" - "go/ast" - "go/build" - "go/parser" - "go/scanner" - "go/types" - "os" - "reflect" - "strings" - "sync" - "sync/atomic" - - "golang.org/x/sync/errgroup" - "golang.org/x/tools/go/gcexportdata" - "golang.org/x/tools/go/packages" - - "github.com/golangci/golangci-lint/v2/pkg/goanalysis/load" - "github.com/golangci/golangci-lint/v2/pkg/goutil" - "github.com/golangci/golangci-lint/v2/pkg/logutils" -) - -const unsafePkgName = "unsafe" - -// https://github.com/golang/go/blob/go1.23.8/src/internal/types/errors/codes.go#L1484 -const tooNew = 151 - -type loadingPackage struct { - pkg *packages.Package - imports map[string]*loadingPackage - isInitial bool - log logutils.Log - actions []*action // all actions with this package - loadGuard *load.Guard - dependents int32 // number of depending on it packages - analyzeOnce sync.Once - decUseMutex sync.Mutex -} - -func (lp *loadingPackage) analyzeRecursive(ctx context.Context, cancel context.CancelFunc, loadMode LoadMode, loadSem chan struct{}) { - lp.analyzeOnce.Do(func() { - // Load the direct dependencies, in parallel. - var wg sync.WaitGroup - - wg.Add(len(lp.imports)) - - for _, imp := range lp.imports { - go func(imp *loadingPackage) { - imp.analyzeRecursive(ctx, cancel, loadMode, loadSem) - - wg.Done() - }(imp) - } - - wg.Wait() - - lp.analyze(ctx, cancel, loadMode, loadSem) - }) -} - -func (lp *loadingPackage) analyze(ctx context.Context, cancel context.CancelFunc, loadMode LoadMode, loadSem chan struct{}) { - select { - case <-ctx.Done(): - return - case loadSem <- struct{}{}: - defer func() { - <-loadSem - }() - } - - // Save memory on unused more fields. - defer lp.decUse(loadMode < LoadModeWholeProgram) - - if err := lp.loadWithFacts(loadMode); err != nil { - // Note: this error is ignored when there is no facts loading (e.g. with 98% of linters). - // But this is not a problem because the errors are added to the package.Errors. - // You through an error, try to add it to actions, but there is no action annnddd it's gone! - werr := fmt.Errorf("failed to load package %s: %w", lp.pkg.Name, err) - - // Don't need to write error to errCh, it will be extracted and reported on another layer. - // Unblock depending on actions and propagate error. - for _, act := range lp.actions { - close(act.analysisDoneCh) - - act.Err = werr - } - - if len(lp.actions) == 0 { - lp.log.Warnf("no action but there is an error: %v", err) - } - - return - } - - actsWg, ctxGroup := errgroup.WithContext(ctx) - - for _, act := range lp.actions { - actsWg.Go(func() error { - act.waitUntilDependingAnalyzersWorked(ctxGroup) - - select { - case <-ctxGroup.Done(): - return nil - default: - } - - act.analyzeSafe() - - return act.Err - }) - } - - err := actsWg.Wait() - if err != nil { - cancel() - } -} - -func (lp *loadingPackage) loadFromSource(loadMode LoadMode) error { - pkg := lp.pkg - - // Many packages have few files, much fewer than there - // are CPU cores. Additionally, parsing each individual file is - // very fast. A naive parallel implementation of this loop won't - // be faster, and tends to be slower due to extra scheduling, - // bookkeeping and potentially false sharing of cache lines. - pkg.Syntax = make([]*ast.File, 0, len(pkg.CompiledGoFiles)) - for _, file := range pkg.CompiledGoFiles { - f, err := parser.ParseFile(pkg.Fset, file, nil, parser.ParseComments) - if err != nil { - pkg.Errors = append(pkg.Errors, lp.convertError(err)...) - continue - } - pkg.Syntax = append(pkg.Syntax, f) - } - if len(pkg.Errors) != 0 { - pkg.IllTyped = true - return nil - } - - if loadMode == LoadModeSyntax { - return nil - } - - // Call NewPackage directly with explicit name. - // This avoids skew between golist and go/types when the files' - // package declarations are inconsistent. - // Subtle: we populate all Types fields with an empty Package - // before loading export data so that export data processing - // never has to create a types.Package for an indirect dependency, - // which would then require that such created packages be explicitly - // inserted back into the Import graph as a final step after export data loading. - pkg.Types = types.NewPackage(pkg.PkgPath, pkg.Name) - - pkg.IllTyped = true - - pkg.TypesInfo = &types.Info{ - Types: make(map[ast.Expr]types.TypeAndValue), - Instances: make(map[*ast.Ident]types.Instance), - Defs: make(map[*ast.Ident]types.Object), - Uses: make(map[*ast.Ident]types.Object), - Implicits: make(map[ast.Node]types.Object), - Selections: make(map[*ast.SelectorExpr]*types.Selection), - Scopes: make(map[ast.Node]*types.Scope), - FileVersions: make(map[*ast.File]string), - } - - importer := func(path string) (*types.Package, error) { - if path == unsafePkgName { - return types.Unsafe, nil - } - if path == "C" { - // go/packages doesn't tell us that cgo preprocessing - // failed. When we subsequently try to parse the package, - // we'll encounter the raw C import. - return nil, errors.New("cgo preprocessing failed") - } - imp := pkg.Imports[path] - if imp == nil { - return nil, nil - } - if len(imp.Errors) > 0 { - return nil, imp.Errors[0] - } - return imp.Types, nil - } - - var goVersion string - if pkg.Module != nil && pkg.Module.GoVersion != "" { - goVersion = "go" + strings.TrimPrefix(pkg.Module.GoVersion, "go") - } else { - var err error - goVersion, err = goutil.CleanRuntimeVersion() - if err != nil { - return err - } - } - - tc := &types.Config{ - Importer: importerFunc(importer), - Error: func(err error) { - pkg.Errors = append(pkg.Errors, lp.convertError(err)...) - }, - GoVersion: goVersion, - Sizes: types.SizesFor(build.Default.Compiler, build.Default.GOARCH), - } - - _ = types.NewChecker(tc, pkg.Fset, pkg.Types, pkg.TypesInfo).Files(pkg.Syntax) - // Don't handle error here: errors are adding by tc.Error function. - - illTyped := len(pkg.Errors) != 0 - if !illTyped { - for _, imp := range lp.imports { - if imp.pkg.IllTyped { - illTyped = true - break - } - } - } - pkg.IllTyped = illTyped - return nil -} - -func (lp *loadingPackage) loadFromExportData() error { - pkg := lp.pkg - - // Call NewPackage directly with explicit name. - // This avoids skew between golist and go/types when the files' - // package declarations are inconsistent. - // Subtle: we populate all Types fields with an empty Package - // before loading export data so that export data processing - // never has to create a types.Package for an indirect dependency, - // which would then require that such created packages be explicitly - // inserted back into the Import graph as a final step after export data loading. - pkg.Types = types.NewPackage(pkg.PkgPath, pkg.Name) - - pkg.IllTyped = true - for path, pkg := range pkg.Imports { - if pkg.Types == nil { - return fmt.Errorf("dependency %q hasn't been loaded yet", path) - } - } - - if pkg.ExportFile == "" { - return fmt.Errorf("no export data for %q", pkg.ID) - } - - f, err := os.Open(pkg.ExportFile) - if err != nil { - return err - } - defer f.Close() - - r, err := gcexportdata.NewReader(f) - if err != nil { - return err - } - - view := make(map[string]*types.Package) // view seen by gcexportdata - seen := make(map[*packages.Package]bool) // all visited packages - var visit func(pkgs map[string]*packages.Package) - visit = func(pkgs map[string]*packages.Package) { - for _, pkg := range pkgs { - if !seen[pkg] { - seen[pkg] = true - view[pkg.PkgPath] = pkg.Types - visit(pkg.Imports) - } - } - } - visit(pkg.Imports) - tpkg, err := gcexportdata.Read(r, pkg.Fset, view, pkg.PkgPath) - if err != nil { - return err - } - pkg.Types = tpkg - pkg.IllTyped = false - return nil -} - -func (lp *loadingPackage) loadWithFacts(loadMode LoadMode) error { - pkg := lp.pkg - - if pkg.PkgPath == unsafePkgName { - // Fill in the blanks to avoid surprises. - pkg.Syntax = []*ast.File{} - if loadMode >= LoadModeTypesInfo { - pkg.Types = types.Unsafe - pkg.TypesInfo = new(types.Info) - } - return nil - } - - if pkg.TypesInfo != nil { - // Already loaded package, e.g. because another not go/analysis linter required types for deps. - // Try load cached facts for it. - - for _, act := range lp.actions { - if !act.loadCachedFacts() { - // Cached facts loading failed: analyze later the action from source. - act.needAnalyzeSource = true - factsCacheDebugf("Loading of facts for already loaded %s failed, analyze it from source later", act) - act.markDepsForAnalyzingSource() - } - } - return nil - } - - if lp.isInitial { - // No need to load cached facts: the package will be analyzed from source - // because it's the initial. - return lp.loadFromSource(loadMode) - } - - return lp.loadImportedPackageWithFacts(loadMode) -} - -func (lp *loadingPackage) loadImportedPackageWithFacts(loadMode LoadMode) error { - pkg := lp.pkg - - // Load package from export data - if loadMode >= LoadModeTypesInfo { - if err := lp.loadFromExportData(); err != nil { - // We asked Go to give us up-to-date export data, yet - // we can't load it. There must be something wrong. - // - // Attempt loading from source. This should fail (because - // otherwise there would be export data); we just want to - // get the compile errors. If loading from source succeeds - // we discard the result, anyway. Otherwise, we'll fail - // when trying to reload from export data later. - - // Otherwise, it panics because uses already existing (from exported data) types. - pkg.Types = types.NewPackage(pkg.PkgPath, pkg.Name) - if srcErr := lp.loadFromSource(loadMode); srcErr != nil { - return srcErr - } - - // Make sure this package can't be imported successfully - pkg.Errors = append(pkg.Errors, packages.Error{ - Pos: "-", - Msg: fmt.Sprintf("could not load export data: %s", err), - Kind: packages.ParseError, - }) - - return nil - } - } - - needLoadFromSource := false - for _, act := range lp.actions { - if act.loadCachedFacts() { - continue - } - - // Cached facts loading failed: analyze later the action from source. - factsCacheDebugf("Loading of facts for %s failed, analyze it from source later", act) - act.needAnalyzeSource = true // can't be set in parallel - needLoadFromSource = true - - act.markDepsForAnalyzingSource() - } - - if needLoadFromSource { - // Cached facts loading failed: analyze later the action from source. To perform - // the analysis we need to load the package from source code. - - // Otherwise, it panics because uses already existing (from exported data) types. - if loadMode >= LoadModeTypesInfo { - pkg.Types = types.NewPackage(pkg.PkgPath, pkg.Name) - } - return lp.loadFromSource(loadMode) - } - - return nil -} - -func (lp *loadingPackage) decUse(canClearTypes bool) { - lp.decUseMutex.Lock() - defer lp.decUseMutex.Unlock() - - for _, act := range lp.actions { - pass := act.pass - if pass == nil { - continue - } - - pass.Files = nil - pass.TypesInfo = nil - pass.TypesSizes = nil - pass.ResultOf = nil - pass.Pkg = nil - pass.OtherFiles = nil - pass.AllObjectFacts = nil - pass.AllPackageFacts = nil - pass.ImportObjectFact = nil - pass.ExportObjectFact = nil - pass.ImportPackageFact = nil - pass.ExportPackageFact = nil - act.pass = nil - act.Deps = nil - if act.Result != nil { - if isMemoryDebug { - debugf("%s: decUse: nilling act result of size %d bytes", act, sizeOfValueTreeBytes(act.Result)) - } - act.Result = nil - } - } - - lp.pkg.Syntax = nil - lp.pkg.TypesInfo = nil - lp.pkg.TypesSizes = nil - - // Can't set lp.pkg.Imports to nil because of loadFromExportData.visit. - - dependents := atomic.AddInt32(&lp.dependents, -1) - if dependents != 0 { - return - } - - if canClearTypes { - // canClearTypes is set to true if we can discard type - // information after the package and its dependents have been - // processed. This is the case when no whole program checkers (unused) are - // being run. - lp.pkg.Types = nil - } - lp.pkg = nil - - for _, imp := range lp.imports { - imp.decUse(canClearTypes) - } - lp.imports = nil - - for _, act := range lp.actions { - if !lp.isInitial { - act.Package = nil - } - act.packageFacts = nil - act.objectFacts = nil - } - lp.actions = nil -} - -func (lp *loadingPackage) convertError(err error) []packages.Error { - var errs []packages.Error - // taken from go/packages - switch err := err.(type) { - case packages.Error: - // from driver - errs = append(errs, err) - - case *os.PathError: - // from parser - errs = append(errs, packages.Error{ - Pos: err.Path + ":1", - Msg: err.Err.Error(), - Kind: packages.ParseError, - }) - - case scanner.ErrorList: - // from parser - for _, err := range err { - errs = append(errs, packages.Error{ - Pos: err.Pos.String(), - Msg: err.Msg, - Kind: packages.ParseError, - }) - } - - case types.Error: - // from type checker - - // https://github.com/golang/go/blob/go1.23.8/src/go/types/api.go#L52-L57 - if int(reflect.ValueOf(err).FieldByName("go116code").Int()) == tooNew { - // https://github.com/golang/go/blob/go1.23.8/src/go/types/check.go#L380 - // https://github.com/golang/go/blob/go1.23.8/src/go/types/check.go#L349 - panic(err.Msg) - } - - errs = append(errs, packages.Error{ - Pos: err.Fset.Position(err.Pos).String(), - Msg: err.Msg, - Kind: packages.TypeError, - }) - - default: - // unexpected impoverished error from parser? - errs = append(errs, packages.Error{ - Pos: "-", - Msg: err.Error(), - Kind: packages.UnknownError, - }) - - // If you see this error message, please file a bug. - lp.log.Warnf("Internal error: error %q (%T) without position", err, err) - } - - return errs -} - -func (lp *loadingPackage) String() string { - return fmt.Sprintf("%s@%s", lp.pkg.PkgPath, lp.pkg.Name) -} - -type importerFunc func(path string) (*types.Package, error) - -func (f importerFunc) Import(path string) (*types.Package, error) { return f(path) } - -func sizeOfValueTreeBytes(v any) int { - return sizeOfReflectValueTreeBytes(reflect.ValueOf(v), map[uintptr]struct{}{}) -} - -func sizeOfReflectValueTreeBytes(rv reflect.Value, visitedPtrs map[uintptr]struct{}) int { - switch rv.Kind() { - case reflect.Ptr: - ptrSize := int(rv.Type().Size()) - if rv.IsNil() { - return ptrSize - } - ptr := rv.Pointer() - if _, ok := visitedPtrs[ptr]; ok { - return 0 - } - visitedPtrs[ptr] = struct{}{} - return ptrSize + sizeOfReflectValueTreeBytes(rv.Elem(), visitedPtrs) - case reflect.Interface: - if rv.IsNil() { - return 0 - } - return sizeOfReflectValueTreeBytes(rv.Elem(), visitedPtrs) - case reflect.Struct: - ret := 0 - for i := range rv.NumField() { - ret += sizeOfReflectValueTreeBytes(rv.Field(i), visitedPtrs) - } - return ret - case reflect.Slice, reflect.Array, reflect.Chan: - return int(rv.Type().Size()) + rv.Cap()*int(rv.Type().Elem().Size()) - case reflect.Map: - ret := 0 - for _, key := range rv.MapKeys() { - mv := rv.MapIndex(key) - ret += sizeOfReflectValueTreeBytes(key, visitedPtrs) - ret += sizeOfReflectValueTreeBytes(mv, visitedPtrs) - } - return ret - case reflect.String: - return rv.Len() - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, - reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, - reflect.Uintptr, reflect.Bool, reflect.Float32, reflect.Float64, - reflect.Complex64, reflect.Complex128, reflect.Func, reflect.UnsafePointer: - return int(rv.Type().Size()) - case reflect.Invalid: - return 0 - default: - panic("unknown rv of type " + rv.String()) - } -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runners.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runners.go deleted file mode 100644 index bcbc0033ef..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runners.go +++ /dev/null @@ -1,156 +0,0 @@ -package goanalysis - -import ( - "fmt" - "go/token" - "slices" - "strings" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/packages" - - "github.com/golangci/golangci-lint/v2/pkg/goanalysis/pkgerrors" - "github.com/golangci/golangci-lint/v2/pkg/lint/linter" - "github.com/golangci/golangci-lint/v2/pkg/logutils" - "github.com/golangci/golangci-lint/v2/pkg/result" - "github.com/golangci/golangci-lint/v2/pkg/timeutils" -) - -type runAnalyzersConfig interface { - getName() string - getLinterNameForDiagnostic(*Diagnostic) string - getAnalyzers() []*analysis.Analyzer - useOriginalPackages() bool - reportIssues(*linter.Context) []*Issue - getLoadMode() LoadMode -} - -func runAnalyzers(cfg runAnalyzersConfig, lintCtx *linter.Context) ([]*result.Issue, error) { - log := lintCtx.Log.Child(logutils.DebugKeyGoAnalysis) - sw := timeutils.NewStopwatch("analyzers", log) - - const stagesToPrint = 10 - defer sw.PrintTopStages(stagesToPrint) - - runner := newRunner(cfg.getName(), log, lintCtx.PkgCache, lintCtx.LoadGuard, cfg.getLoadMode(), sw) - - pkgs := lintCtx.Packages - if cfg.useOriginalPackages() { - pkgs = lintCtx.OriginalPackages - } - - issues, pkgsFromCache := loadIssuesFromCache(pkgs, lintCtx, cfg.getAnalyzers()) - var pkgsToAnalyze []*packages.Package - for _, pkg := range pkgs { - if !pkgsFromCache[pkg] { - pkgsToAnalyze = append(pkgsToAnalyze, pkg) - } - } - - diags, errs, passToPkg := runner.run(cfg.getAnalyzers(), pkgsToAnalyze) - - defer func() { - if len(errs) == 0 { - // If we try to save to cache even if we have compilation errors - // we won't see them on repeated runs. - saveIssuesToCache(pkgs, pkgsFromCache, issues, lintCtx, cfg.getAnalyzers()) - } - }() - - buildAllIssues := func() []*result.Issue { - var retIssues []*result.Issue - - reportedIssues := cfg.reportIssues(lintCtx) - for _, reportedIssue := range reportedIssues { - if reportedIssue.Pkg == nil { - reportedIssue.Pkg = passToPkg[reportedIssue.Pass] - } - - retIssues = append(retIssues, reportedIssue.Issue) - } - - return slices.Concat(retIssues, buildIssues(diags, cfg.getLinterNameForDiagnostic)) - } - - errIssues, err := pkgerrors.BuildIssuesFromIllTypedError(errs, lintCtx) - if err != nil { - return nil, err - } - - issues = append(issues, errIssues...) - issues = append(issues, buildAllIssues()...) - - return issues, nil -} - -func buildIssues(diags []*Diagnostic, linterNameBuilder func(diag *Diagnostic) string) []*result.Issue { - var issues []*result.Issue - - for _, diag := range diags { - linterName := linterNameBuilder(diag) - - var text string - if diag.Analyzer.Name == linterName { - text = diag.Message - } else { - text = fmt.Sprintf("%s: %s", diag.Analyzer.Name, diag.Message) - } - - var suggestedFixes []analysis.SuggestedFix - - for _, sf := range diag.SuggestedFixes { - // Skip suggested fixes on cgo files. - // The related error is: "diff has out-of-bounds edits" - // This is a temporary workaround. - if !strings.HasSuffix(diag.File.Name(), ".go") { - continue - } - - nsf := analysis.SuggestedFix{Message: sf.Message} - - for _, edit := range sf.TextEdits { - end := edit.End - - if !end.IsValid() { - end = edit.Pos - } - - // To be applied the positions need to be "adjusted" based on the file. - // This is the difference between the "displayed" positions and "effective" positions. - nsf.TextEdits = append(nsf.TextEdits, analysis.TextEdit{ - Pos: token.Pos(diag.File.Offset(edit.Pos)), - End: token.Pos(diag.File.Offset(end)), - NewText: edit.NewText, - }) - } - - suggestedFixes = append(suggestedFixes, nsf) - } - - issues = append(issues, &result.Issue{ - FromLinter: linterName, - Text: text, - Pos: diag.Position, - Pkg: diag.Pkg, - SuggestedFixes: suggestedFixes, - }) - - if len(diag.Related) > 0 { - for _, info := range diag.Related { - relatedPos := diag.Pkg.Fset.Position(info.Pos) - - if relatedPos.Filename != diag.Position.Filename { - relatedPos = diag.Position - } - - issues = append(issues, &result.Issue{ - FromLinter: linterName, - Text: fmt.Sprintf("%s(related information): %s", diag.Analyzer.Name, info.Message), - Pos: relatedPos, - Pkg: diag.Pkg, - }) - } - } - } - return issues -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runners_cache.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runners_cache.go deleted file mode 100644 index 5cd8a6b1cc..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goanalysis/runners_cache.go +++ /dev/null @@ -1,169 +0,0 @@ -package goanalysis - -import ( - "runtime" - "sort" - "strings" - "sync" - "sync/atomic" - "time" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/packages" - - "github.com/golangci/golangci-lint/v2/internal/cache" - "github.com/golangci/golangci-lint/v2/pkg/lint/linter" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -func saveIssuesToCache(allPkgs []*packages.Package, pkgsFromCache map[*packages.Package]bool, - issues []*result.Issue, lintCtx *linter.Context, analyzers []*analysis.Analyzer, -) { - startedAt := time.Now() - perPkgIssues := map[*packages.Package][]*result.Issue{} - for _, issue := range issues { - perPkgIssues[issue.Pkg] = append(perPkgIssues[issue.Pkg], issue) - } - - var savedIssuesCount int64 = 0 - lintResKey := getIssuesCacheKey(analyzers) - - workerCount := runtime.GOMAXPROCS(-1) - var wg sync.WaitGroup - wg.Add(workerCount) - - pkgCh := make(chan *packages.Package, len(allPkgs)) - for range workerCount { - go func() { - defer wg.Done() - for pkg := range pkgCh { - pkgIssues := perPkgIssues[pkg] - encodedIssues := make([]EncodingIssue, 0, len(pkgIssues)) - for _, issue := range pkgIssues { - encodedIssues = append(encodedIssues, EncodingIssue{ - FromLinter: issue.FromLinter, - Text: issue.Text, - Severity: issue.Severity, - Pos: issue.Pos, - LineRange: issue.LineRange, - SuggestedFixes: issue.SuggestedFixes, - ExpectNoLint: issue.ExpectNoLint, - ExpectedNoLintLinter: issue.ExpectedNoLintLinter, - }) - } - - atomic.AddInt64(&savedIssuesCount, int64(len(encodedIssues))) - if err := lintCtx.PkgCache.Put(pkg, cache.HashModeNeedAllDeps, lintResKey, encodedIssues); err != nil { - lintCtx.Log.Infof("Failed to save package %s issues (%d) to cache: %s", pkg, len(pkgIssues), err) - } else { - issuesCacheDebugf("Saved package %s issues (%d) to cache", pkg, len(pkgIssues)) - } - } - }() - } - - for _, pkg := range allPkgs { - if pkgsFromCache[pkg] { - continue - } - - pkgCh <- pkg - } - close(pkgCh) - wg.Wait() - - lintCtx.PkgCache.Close() - - issuesCacheDebugf("Saved %d issues from %d packages to cache in %s", savedIssuesCount, len(allPkgs), time.Since(startedAt)) -} - -func loadIssuesFromCache(pkgs []*packages.Package, lintCtx *linter.Context, - analyzers []*analysis.Analyzer, -) (issuesFromCache []*result.Issue, pkgsFromCache map[*packages.Package]bool) { - startedAt := time.Now() - - lintResKey := getIssuesCacheKey(analyzers) - type cacheRes struct { - issues []*result.Issue - loadErr error - } - pkgToCacheRes := make(map[*packages.Package]*cacheRes, len(pkgs)) - for _, pkg := range pkgs { - pkgToCacheRes[pkg] = &cacheRes{} - } - - workerCount := runtime.GOMAXPROCS(-1) - var wg sync.WaitGroup - wg.Add(workerCount) - - pkgCh := make(chan *packages.Package, len(pkgs)) - for range workerCount { - go func() { - defer wg.Done() - for pkg := range pkgCh { - var pkgIssues []*EncodingIssue - err := lintCtx.PkgCache.Get(pkg, cache.HashModeNeedAllDeps, lintResKey, &pkgIssues) - cacheRes := pkgToCacheRes[pkg] - cacheRes.loadErr = err - if err != nil { - continue - } - if len(pkgIssues) == 0 { - continue - } - - issues := make([]*result.Issue, 0, len(pkgIssues)) - for _, issue := range pkgIssues { - issues = append(issues, &result.Issue{ - FromLinter: issue.FromLinter, - Text: issue.Text, - Severity: issue.Severity, - Pos: issue.Pos, - LineRange: issue.LineRange, - SuggestedFixes: issue.SuggestedFixes, - Pkg: pkg, - ExpectNoLint: issue.ExpectNoLint, - ExpectedNoLintLinter: issue.ExpectedNoLintLinter, - }) - } - cacheRes.issues = issues - } - }() - } - - for _, pkg := range pkgs { - pkgCh <- pkg - } - close(pkgCh) - wg.Wait() - - loadedIssuesCount := 0 - pkgsFromCache = map[*packages.Package]bool{} - for pkg, cacheRes := range pkgToCacheRes { - if cacheRes.loadErr == nil { - loadedIssuesCount += len(cacheRes.issues) - pkgsFromCache[pkg] = true - issuesFromCache = append(issuesFromCache, cacheRes.issues...) - issuesCacheDebugf("Loaded package %s issues (%d) from cache", pkg, len(cacheRes.issues)) - } else { - issuesCacheDebugf("Didn't load package %s issues from cache: %s", pkg, cacheRes.loadErr) - } - } - issuesCacheDebugf("Loaded %d issues from cache in %s, analyzing %d/%d packages", - loadedIssuesCount, time.Since(startedAt), len(pkgs)-len(pkgsFromCache), len(pkgs)) - return issuesFromCache, pkgsFromCache -} - -func getIssuesCacheKey(analyzers []*analysis.Analyzer) string { - return "lint/result:" + analyzersHashID(analyzers) -} - -func analyzersHashID(analyzers []*analysis.Analyzer) string { - names := make([]string, 0, len(analyzers)) - for _, a := range analyzers { - names = append(names, a.Name) - } - - sort.Strings(names) - return strings.Join(names, ",") -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformat/runner.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformat/runner.go deleted file mode 100644 index 650fb8f5ea..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformat/runner.go +++ /dev/null @@ -1,292 +0,0 @@ -package goformat - -import ( - "bytes" - "context" - "fmt" - "io" - "io/fs" - "log" - "os" - "path/filepath" - "regexp" - "strings" - - "github.com/alecthomas/chroma/v2/quick" - rpdiff "github.com/rogpeppe/go-internal/diff" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/fsutils" - "github.com/golangci/golangci-lint/v2/pkg/goformatters" - "github.com/golangci/golangci-lint/v2/pkg/logutils" - "github.com/golangci/golangci-lint/v2/pkg/result/processors" -) - -type Runner struct { - log logutils.Log - - metaFormatter *goformatters.MetaFormatter - matcher *processors.GeneratedFileMatcher - - opts RunnerOptions - - exitCode int -} - -func NewRunner(logger logutils.Log, - metaFormatter *goformatters.MetaFormatter, matcher *processors.GeneratedFileMatcher, - opts RunnerOptions) *Runner { - return &Runner{ - log: logger, - matcher: matcher, - metaFormatter: metaFormatter, - opts: opts, - } -} - -func (c *Runner) Run(paths []string) error { - savedStdout, savedStderr := os.Stdout, os.Stderr - - if !logutils.HaveDebugTag(logutils.DebugKeyFormattersOutput) { - // Don't allow linters and loader to print anything - log.SetOutput(io.Discard) - c.setOutputToDevNull() - defer func() { - os.Stdout, os.Stderr = savedStdout, savedStderr - }() - } - - if c.opts.stdin { - return c.formatStdIn("", savedStdout, os.Stdin) - } - - for _, path := range paths { - err := c.walk(path, savedStdout) - if err != nil { - return err - } - } - - for pattern, count := range c.opts.excludedPathCounter { - if c.opts.warnUnused && count == 0 { - c.log.Warnf("The pattern %q match no issues", pattern) - } else { - c.log.Infof("Skipped %d issues by pattern %q", count, pattern) - } - } - - return nil -} - -func (c *Runner) walk(root string, stdout *os.File) error { - return filepath.Walk(root, func(path string, f fs.FileInfo, err error) error { - if err != nil { - return err - } - - if f.IsDir() && skipDir(f.Name()) { - return fs.SkipDir - } - - if !isGoFile(f) { - return nil - } - - match, err := c.opts.MatchAnyPattern(path) - if err != nil || match { - return err - } - - in, err := os.Open(path) - if err != nil { - return err - } - - defer func() { _ = in.Close() }() - - return c.process(path, stdout, in) - }) -} - -func (c *Runner) process(path string, stdout io.Writer, in io.Reader) error { - input, err := io.ReadAll(in) - if err != nil { - return err - } - - match, err := c.matcher.IsGeneratedFile(path, input) - if err != nil || match { - return err - } - - output := c.metaFormatter.Format(path, input) - - if bytes.Equal(input, output) { - return nil - } - - if c.opts.diff { - newName := filepath.ToSlash(path) - oldName := newName + ".orig" - - patch := rpdiff.Diff(oldName, input, newName, output) - - if c.opts.colors { - err = quick.Highlight(stdout, string(patch), "diff", "terminal", "native") - if err != nil { - return err - } - } else { - _, err = stdout.Write(patch) - if err != nil { - return err - } - } - - c.exitCode = 1 - - return nil - } - - c.log.Infof("format: %s", path) - - // On Windows, we need to re-set the permissions from the file. See golang/go#38225. - var perms os.FileMode - if fi, err := os.Stat(path); err == nil { - perms = fi.Mode() & os.ModePerm - } - - return os.WriteFile(path, output, perms) -} - -func (c *Runner) formatStdIn(path string, stdout io.Writer, in io.Reader) error { - input, err := io.ReadAll(in) - if err != nil { - return err - } - - match, err := c.matcher.IsGeneratedFile(path, input) - if err != nil { - return err - } - - if match { - // If the file is generated, - // the input should be written to the stdout to avoid emptied the file. - _, err = stdout.Write(input) - if err != nil { - return err - } - - return nil - } - - output := c.metaFormatter.Format(path, input) - - _, err = stdout.Write(output) - if err != nil { - return err - } - - return nil -} - -func (c *Runner) setOutputToDevNull() { - devNull, err := os.Open(os.DevNull) - if err != nil { - c.log.Warnf("Can't open null device %q: %s", os.DevNull, err) - return - } - - os.Stdout, os.Stderr = devNull, devNull -} - -func (c *Runner) ExitCode() int { - return c.exitCode -} - -type RunnerOptions struct { - basePath string - patterns []*regexp.Regexp - generated string - diff bool - colors bool - stdin bool - - warnUnused bool - excludedPathCounter map[*regexp.Regexp]int -} - -func NewRunnerOptions(cfg *config.Config, diff, diffColored, stdin bool) (RunnerOptions, error) { - basePath, err := fsutils.GetBasePath(context.Background(), cfg.Run.RelativePathMode, cfg.GetConfigDir()) - if err != nil { - return RunnerOptions{}, fmt.Errorf("get base path: %w", err) - } - - // Required to be consistent with `RunnerOptions.MatchAnyPattern`. - absBasePath, err := filepath.Abs(basePath) - if err != nil { - return RunnerOptions{}, err - } - - opts := RunnerOptions{ - basePath: absBasePath, - generated: cfg.Formatters.Exclusions.Generated, - diff: diff || diffColored, - colors: diffColored, - stdin: stdin, - excludedPathCounter: make(map[*regexp.Regexp]int), - warnUnused: cfg.Formatters.Exclusions.WarnUnused, - } - - for _, pattern := range cfg.Formatters.Exclusions.Paths { - exp, err := regexp.Compile(fsutils.NormalizePathInRegex(pattern)) - if err != nil { - return RunnerOptions{}, fmt.Errorf("compile path pattern %q: %w", pattern, err) - } - - opts.patterns = append(opts.patterns, exp) - opts.excludedPathCounter[exp] = 0 - } - - return opts, nil -} - -func (o RunnerOptions) MatchAnyPattern(path string) (bool, error) { - if len(o.patterns) == 0 { - return false, nil - } - - abs, err := filepath.Abs(path) - if err != nil { - return false, err - } - - rel, err := filepath.Rel(o.basePath, abs) - if err != nil { - return false, err - } - - for _, pattern := range o.patterns { - if pattern.MatchString(rel) { - o.excludedPathCounter[pattern]++ - return true, nil - } - } - - return false, nil -} - -func skipDir(name string) bool { - switch name { - case "vendor", "testdata", "node_modules": - return true - - default: - return strings.HasPrefix(name, ".") && name != "." - } -} - -func isGoFile(f fs.FileInfo) bool { - return !f.IsDir() && !strings.HasPrefix(f.Name(), ".") && strings.HasSuffix(f.Name(), ".go") -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/analyzer.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/analyzer.go deleted file mode 100644 index d6d92d5b9c..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/analyzer.go +++ /dev/null @@ -1,55 +0,0 @@ -package goformatters - -import ( - "bytes" - "fmt" - "os" - "path/filepath" - - "github.com/rogpeppe/go-internal/diff" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/goformatters/internal" - "github.com/golangci/golangci-lint/v2/pkg/logutils" -) - -// NewAnalyzer converts a [Formatter] to an [analysis.Analyzer]. -func NewAnalyzer(logger logutils.Log, doc string, formatter Formatter) *analysis.Analyzer { - return &analysis.Analyzer{ - Name: formatter.Name(), - Doc: doc, - Run: func(pass *analysis.Pass) (any, error) { - for _, file := range pass.Files { - position, isGoFile := goanalysis.GetGoFilePosition(pass, file) - if !isGoFile { - continue - } - - input, err := os.ReadFile(position.Filename) - if err != nil { - return nil, fmt.Errorf("unable to open file %s: %w", position.Filename, err) - } - - output, err := formatter.Format(position.Filename, input) - if err != nil { - return nil, fmt.Errorf("error while running %s: %w", formatter.Name(), err) - } - - if !bytes.Equal(input, output) { - newName := filepath.ToSlash(position.Filename) - oldName := newName + ".orig" - - patch := diff.Diff(oldName, input, newName, output) - - err = internal.ExtractDiagnosticFromPatch(pass, file, patch, logger) - if err != nil { - return nil, fmt.Errorf("can't extract issues from %s diff output %q: %w", formatter.Name(), patch, err) - } - } - } - - return nil, nil - }, - } -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/formatters.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/formatters.go deleted file mode 100644 index c8953ad3bf..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/formatters.go +++ /dev/null @@ -1,6 +0,0 @@ -package goformatters - -type Formatter interface { - Name() string - Format(filename string, src []byte) ([]byte, error) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/gci.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/gci.go deleted file mode 100644 index cf1e865158..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/gci.go +++ /dev/null @@ -1,74 +0,0 @@ -package gci - -import ( - "context" - "go/format" - - gcicfg "github.com/daixiang0/gci/pkg/config" - "github.com/daixiang0/gci/pkg/gci" - "github.com/daixiang0/gci/pkg/log" - "github.com/ldez/grignotin/gomod" - - "github.com/golangci/golangci-lint/v2/pkg/config" - gcicfgi "github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/config" - "github.com/golangci/golangci-lint/v2/pkg/goformatters/internal" -) - -const Name = "gci" - -type Formatter struct { - config *gcicfg.Config -} - -func New(settings *config.GciSettings) (*Formatter, error) { - log.InitLogger() - _ = log.L().Sync() - - modPath, err := gomod.GetModulePath(context.Background()) - if err != nil { - internal.FormatterLogger.Errorf("gci: %v", err) - } - - cfg := gcicfgi.YamlConfig{ - Cfg: gcicfg.BoolConfig{ - NoInlineComments: settings.NoInlineComments, - NoPrefixComments: settings.NoPrefixComments, - CustomOrder: settings.CustomOrder, - NoLexOrder: settings.NoLexOrder, - - // Should be managed with `formatters.exclusions.generated`. - SkipGenerated: false, - }, - SectionStrings: settings.Sections, - ModPath: modPath, - } - - parsedCfg, err := cfg.Parse() - if err != nil { - return nil, err - } - - return &Formatter{config: &gcicfg.Config{ - BoolConfig: parsedCfg.BoolConfig, - Sections: parsedCfg.Sections, - SectionSeparators: parsedCfg.SectionSeparators, - }}, nil -} - -func (*Formatter) Name() string { - return Name -} - -func (f *Formatter) Format(filename string, src []byte) ([]byte, error) { - _, formatted, err := gci.LoadFormat(src, filename, *f.config) - if err != nil { - return nil, err - } - - // gci format the code only when the imports are modified, - // this produced inconsistencies. - // To be always consistent, the code should always be formatted. - // https://github.com/daixiang0/gci/blob/c4f689991095c0e54843dca76fb9c3bad58ec5c7/pkg/gci/gci.go#L148-L151 - // https://github.com/daixiang0/gci/blob/c4f689991095c0e54843dca76fb9c3bad58ec5c7/pkg/gci/gci.go#L215 - return format.Source(formatted) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/LICENSE b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/LICENSE deleted file mode 100644 index e1292f7389..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/LICENSE +++ /dev/null @@ -1,29 +0,0 @@ -BSD 3-Clause License - -Copyright (c) 2020, Xiang Dai -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/config/config.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/config/config.go deleted file mode 100644 index c859b442fc..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/config/config.go +++ /dev/null @@ -1,108 +0,0 @@ -package config - -import ( - "sort" - "strings" - - "gopkg.in/yaml.v3" - - "github.com/daixiang0/gci/pkg/config" - "github.com/daixiang0/gci/pkg/section" - - sectioni "github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/section" -) - -var defaultOrder = map[string]int{ - section.StandardType: 0, - section.DefaultType: 1, - section.CustomType: 2, - section.BlankType: 3, - section.DotType: 4, - section.AliasType: 5, - section.LocalModuleType: 6, -} - -type Config struct { - config.BoolConfig - Sections section.SectionList - SectionSeparators section.SectionList -} - -type YamlConfig struct { - Cfg config.BoolConfig `yaml:",inline"` - SectionStrings []string `yaml:"sections"` - SectionSeparatorStrings []string `yaml:"sectionseparators"` - - // Since history issue, Golangci-lint needs Analyzer to run and GCI add an Analyzer layer to integrate. - // The ModPath param is only from analyzer.go, no need to set it in all other places. - ModPath string `yaml:"-"` -} - -func (g YamlConfig) Parse() (*Config, error) { - var err error - - sections, err := sectioni.Parse(g.SectionStrings) - if err != nil { - return nil, err - } - if sections == nil { - sections = sectioni.DefaultSections() - } - if err := configureSections(sections, g.ModPath); err != nil { - return nil, err - } - - // if default order sorted sections - if !g.Cfg.CustomOrder { - sort.Slice(sections, func(i, j int) bool { - sectionI, sectionJ := sections[i].Type(), sections[j].Type() - - if g.Cfg.NoLexOrder || strings.Compare(sectionI, sectionJ) != 0 { - return defaultOrder[sectionI] < defaultOrder[sectionJ] - } - - return strings.Compare(sections[i].String(), sections[j].String()) < 0 - }) - } - - sectionSeparators, err := sectioni.Parse(g.SectionSeparatorStrings) - if err != nil { - return nil, err - } - if sectionSeparators == nil { - sectionSeparators = section.DefaultSectionSeparators() - } - - return &Config{g.Cfg, sections, sectionSeparators}, nil -} - -func ParseConfig(in string) (*Config, error) { - config := YamlConfig{} - - err := yaml.Unmarshal([]byte(in), &config) - if err != nil { - return nil, err - } - - gciCfg, err := config.Parse() - if err != nil { - return nil, err - } - - return gciCfg, nil -} - -// configureSections now only do golang module path finding. -// Since history issue, Golangci-lint needs Analyzer to run and GCI add an Analyzer layer to integrate. -// The path param is from analyzer.go, in all other places should pass empty string. -func configureSections(sections section.SectionList, path string) error { - for _, sec := range sections { - switch s := sec.(type) { - case *section.LocalModule: - if err := s.Configure(path); err != nil { - return err - } - } - } - return nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/section/parser.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/section/parser.go deleted file mode 100644 index 9662cbd1a7..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/section/parser.go +++ /dev/null @@ -1,51 +0,0 @@ -package section - -import ( - "errors" - "fmt" - "strings" - - "github.com/daixiang0/gci/pkg/section" -) - -func Parse(data []string) (section.SectionList, error) { - if len(data) == 0 { - return nil, nil - } - - var list section.SectionList - var errString string - for _, d := range data { - s := strings.ToLower(d) - if len(s) == 0 { - return nil, nil - } - - if s == "default" { - list = append(list, section.Default{}) - } else if s == "standard" { - list = append(list, Standard{}) - } else if s == "newline" { - list = append(list, section.NewLine{}) - } else if strings.HasPrefix(s, "prefix(") && len(d) > 8 { - list = append(list, section.Custom{Prefix: d[7 : len(d)-1]}) - } else if strings.HasPrefix(s, "commentline(") && len(d) > 13 { - list = append(list, section.Custom{Prefix: d[12 : len(d)-1]}) - } else if s == "dot" { - list = append(list, section.Dot{}) - } else if s == "blank" { - list = append(list, section.Blank{}) - } else if s == "alias" { - list = append(list, section.Alias{}) - } else if s == "localmodule" { - // pointer because we need to mutate the section at configuration time - list = append(list, §ion.LocalModule{}) - } else { - errString += fmt.Sprintf(" %s", s) - } - } - if errString != "" { - return nil, errors.New(fmt.Sprintf("invalid params:%s", errString)) - } - return list, nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/section/section.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/section/section.go deleted file mode 100644 index e9c6632225..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/section/section.go +++ /dev/null @@ -1,7 +0,0 @@ -package section - -import "github.com/daixiang0/gci/pkg/section" - -func DefaultSections() section.SectionList { - return section.SectionList{Standard{}, section.Default{}} -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/section/standard.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/section/standard.go deleted file mode 100644 index 26c7e9dc7d..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/section/standard.go +++ /dev/null @@ -1,30 +0,0 @@ -package section - -import ( - "github.com/daixiang0/gci/pkg/parse" - "github.com/daixiang0/gci/pkg/specificity" -) - -const StandardType = "standard" - -type Standard struct{} - -func (s Standard) MatchSpecificity(spec *parse.GciImports) specificity.MatchSpecificity { - if isStandard(spec.Path) { - return specificity.StandardMatch{} - } - return specificity.MisMatch{} -} - -func (s Standard) String() string { - return StandardType -} - -func (s Standard) Type() string { - return StandardType -} - -func isStandard(pkg string) bool { - _, ok := standardPackages[pkg] - return ok -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/section/standard_list.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/section/standard_list.go deleted file mode 100644 index f84eb0f33f..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gci/internal/section/standard_list.go +++ /dev/null @@ -1,185 +0,0 @@ -package section - -// Code generated based on go1.25.0 X:boringcrypto,arenas,synctest,jsonv2. DO NOT EDIT. - -var standardPackages = map[string]struct{}{ - "archive/tar": {}, - "archive/zip": {}, - "arena": {}, - "bufio": {}, - "bytes": {}, - "cmp": {}, - "compress/bzip2": {}, - "compress/flate": {}, - "compress/gzip": {}, - "compress/lzw": {}, - "compress/zlib": {}, - "container/heap": {}, - "container/list": {}, - "container/ring": {}, - "context": {}, - "crypto": {}, - "crypto/aes": {}, - "crypto/boring": {}, - "crypto/cipher": {}, - "crypto/des": {}, - "crypto/dsa": {}, - "crypto/ecdh": {}, - "crypto/ecdsa": {}, - "crypto/ed25519": {}, - "crypto/elliptic": {}, - "crypto/fips140": {}, - "crypto/hkdf": {}, - "crypto/hmac": {}, - "crypto/md5": {}, - "crypto/mlkem": {}, - "crypto/pbkdf2": {}, - "crypto/rand": {}, - "crypto/rc4": {}, - "crypto/rsa": {}, - "crypto/sha1": {}, - "crypto/sha256": {}, - "crypto/sha3": {}, - "crypto/sha512": {}, - "crypto/subtle": {}, - "crypto/tls": {}, - "crypto/tls/fipsonly": {}, - "crypto/x509": {}, - "crypto/x509/pkix": {}, - "database/sql": {}, - "database/sql/driver": {}, - "debug/buildinfo": {}, - "debug/dwarf": {}, - "debug/elf": {}, - "debug/gosym": {}, - "debug/macho": {}, - "debug/pe": {}, - "debug/plan9obj": {}, - "embed": {}, - "encoding": {}, - "encoding/ascii85": {}, - "encoding/asn1": {}, - "encoding/base32": {}, - "encoding/base64": {}, - "encoding/binary": {}, - "encoding/csv": {}, - "encoding/gob": {}, - "encoding/hex": {}, - "encoding/json": {}, - "encoding/json/jsontext": {}, - "encoding/json/v2": {}, - "encoding/pem": {}, - "encoding/xml": {}, - "errors": {}, - "expvar": {}, - "flag": {}, - "fmt": {}, - "go/ast": {}, - "go/build": {}, - "go/build/constraint": {}, - "go/constant": {}, - "go/doc": {}, - "go/doc/comment": {}, - "go/format": {}, - "go/importer": {}, - "go/parser": {}, - "go/printer": {}, - "go/scanner": {}, - "go/token": {}, - "go/types": {}, - "go/version": {}, - "hash": {}, - "hash/adler32": {}, - "hash/crc32": {}, - "hash/crc64": {}, - "hash/fnv": {}, - "hash/maphash": {}, - "html": {}, - "html/template": {}, - "image": {}, - "image/color": {}, - "image/color/palette": {}, - "image/draw": {}, - "image/gif": {}, - "image/jpeg": {}, - "image/png": {}, - "index/suffixarray": {}, - "io": {}, - "io/fs": {}, - "io/ioutil": {}, - "iter": {}, - "log": {}, - "log/slog": {}, - "log/syslog": {}, - "maps": {}, - "math": {}, - "math/big": {}, - "math/bits": {}, - "math/cmplx": {}, - "math/rand": {}, - "math/rand/v2": {}, - "mime": {}, - "mime/multipart": {}, - "mime/quotedprintable": {}, - "net": {}, - "net/http": {}, - "net/http/cgi": {}, - "net/http/cookiejar": {}, - "net/http/fcgi": {}, - "net/http/httptest": {}, - "net/http/httptrace": {}, - "net/http/httputil": {}, - "net/http/pprof": {}, - "net/mail": {}, - "net/netip": {}, - "net/rpc": {}, - "net/rpc/jsonrpc": {}, - "net/smtp": {}, - "net/textproto": {}, - "net/url": {}, - "os": {}, - "os/exec": {}, - "os/signal": {}, - "os/user": {}, - "path": {}, - "path/filepath": {}, - "plugin": {}, - "reflect": {}, - "regexp": {}, - "regexp/syntax": {}, - "runtime": {}, - "runtime/cgo": {}, - "runtime/coverage": {}, - "runtime/debug": {}, - "runtime/metrics": {}, - "runtime/pprof": {}, - "runtime/race": {}, - "runtime/trace": {}, - "slices": {}, - "sort": {}, - "strconv": {}, - "strings": {}, - "structs": {}, - "sync": {}, - "sync/atomic": {}, - "syscall": {}, - "syscall/js": {}, - "testing": {}, - "testing/fstest": {}, - "testing/iotest": {}, - "testing/quick": {}, - "testing/slogtest": {}, - "testing/synctest": {}, - "text/scanner": {}, - "text/tabwriter": {}, - "text/template": {}, - "text/template/parse": {}, - "time": {}, - "time/tzdata": {}, - "unicode": {}, - "unicode/utf16": {}, - "unicode/utf8": {}, - "unique": {}, - "unsafe": {}, - "weak": {}, -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gofmt/gofmt.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gofmt/gofmt.go deleted file mode 100644 index 4d5ff86329..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gofmt/gofmt.go +++ /dev/null @@ -1,35 +0,0 @@ -package gofmt - -import ( - "github.com/golangci/gofmt/gofmt" - - "github.com/golangci/golangci-lint/v2/pkg/config" -) - -const Name = "gofmt" - -type Formatter struct { - options gofmt.Options -} - -func New(settings *config.GoFmtSettings) *Formatter { - options := gofmt.Options{} - - if settings != nil { - options.NeedSimplify = settings.Simplify - - for _, rule := range settings.RewriteRules { - options.RewriteRules = append(options.RewriteRules, gofmt.RewriteRule(rule)) - } - } - - return &Formatter{options: options} -} - -func (*Formatter) Name() string { - return Name -} - -func (f *Formatter) Format(filename string, src []byte) ([]byte, error) { - return gofmt.Source(filename, src, f.options) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gofumpt/gofumpt.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gofumpt/gofumpt.go deleted file mode 100644 index d8f5f2f735..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/gofumpt/gofumpt.go +++ /dev/null @@ -1,41 +0,0 @@ -package gofumpt - -import ( - "strings" - - gofumpt "mvdan.cc/gofumpt/format" - - "github.com/golangci/golangci-lint/v2/pkg/config" -) - -const Name = "gofumpt" - -type Formatter struct { - options gofumpt.Options -} - -func New(settings *config.GoFumptSettings, goVersion string) *Formatter { - var options gofumpt.Options - - if settings != nil { - options = gofumpt.Options{ - LangVersion: getLangVersion(goVersion), - ModulePath: settings.ModulePath, - ExtraRules: settings.ExtraRules, - } - } - - return &Formatter{options: options} -} - -func (*Formatter) Name() string { - return Name -} - -func (f *Formatter) Format(_ string, src []byte) ([]byte, error) { - return gofumpt.Source(src, f.options) -} - -func getLangVersion(v string) string { - return "go" + strings.TrimPrefix(v, "go") -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/goimports/goimports.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/goimports/goimports.go deleted file mode 100644 index 5b7edf2e47..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/goimports/goimports.go +++ /dev/null @@ -1,30 +0,0 @@ -package goimports - -import ( - "strings" - - "golang.org/x/tools/imports" - - "github.com/golangci/golangci-lint/v2/pkg/config" -) - -const Name = "goimports" - -type Formatter struct{} - -func New(settings *config.GoImportsSettings) *Formatter { - if settings != nil { - imports.LocalPrefix = strings.Join(settings.LocalPrefixes, ",") - } - - return &Formatter{} -} - -func (*Formatter) Name() string { - return Name -} - -func (*Formatter) Format(filename string, src []byte) ([]byte, error) { - // The `imports.LocalPrefix` (`settings.LocalPrefixes`) is a global var. - return imports.Process(filename, src, nil) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/golines/golines.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/golines/golines.go deleted file mode 100644 index ffd5b5f811..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/golines/golines.go +++ /dev/null @@ -1,41 +0,0 @@ -package golines - -import ( - "github.com/golangci/golines" - - "github.com/golangci/golangci-lint/v2/pkg/config" -) - -const Name = "golines" - -type Formatter struct { - shortener *golines.Shortener -} - -func New(settings *config.GoLinesSettings) *Formatter { - options := golines.ShortenerConfig{} - - if settings != nil { - options = golines.ShortenerConfig{ - MaxLen: settings.MaxLen, - TabLen: settings.TabLen, - KeepAnnotations: false, // golines debug (not usable inside golangci-lint) - ShortenComments: settings.ShortenComments, - ReformatTags: settings.ReformatTags, - IgnoreGenerated: false, // handle globally - DotFile: "", // golines debug (not usable inside golangci-lint) - ChainSplitDots: settings.ChainSplitDots, - BaseFormatterCmd: "go fmt", // fake cmd - } - } - - return &Formatter{shortener: golines.NewShortener(options)} -} - -func (*Formatter) Name() string { - return Name -} - -func (f *Formatter) Format(_ string, src []byte) ([]byte, error) { - return f.shortener.Shorten(src) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/internal/commons.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/internal/commons.go deleted file mode 100644 index f18819e2f1..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/internal/commons.go +++ /dev/null @@ -1,6 +0,0 @@ -package internal - -import "github.com/golangci/golangci-lint/v2/pkg/logutils" - -// FormatterLogger must be used only when the context logger is not available. -var FormatterLogger = logutils.NewStderrLog(logutils.DebugKeyFormatter) diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/internal/diff.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/internal/diff.go deleted file mode 100644 index fcec87bb8b..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/internal/diff.go +++ /dev/null @@ -1,271 +0,0 @@ -package internal - -import ( - "bytes" - "fmt" - "go/ast" - "go/token" - "slices" - "strings" - - diffpkg "github.com/sourcegraph/go-diff/diff" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/logutils" -) - -type Change struct { - From, To int - NewLines []string -} - -type diffLineType string - -const ( - diffLineAdded diffLineType = "added" - diffLineOriginal diffLineType = "original" - diffLineDeleted diffLineType = "deleted" -) - -type diffLine struct { - originalNumber int // 1-based original line number - typ diffLineType - data string // "+" or "-" stripped line -} - -type hunkChangesParser struct { - // needed because we merge currently added lines with the last original line - lastOriginalLine *diffLine - - // if the first line of diff is an adding we save all additions to replacementLinesToPrepend - replacementLinesToPrepend []string - - log logutils.Log - - changes []Change -} - -func (p *hunkChangesParser) parse(h *diffpkg.Hunk) []Change { - lines := parseDiffLines(h) - - for i := 0; i < len(lines); { - line := lines[i] - - if line.typ == diffLineOriginal { - p.handleOriginalLine(lines, line, &i) - continue - } - - var deletedLines []diffLine - for ; i < len(lines) && lines[i].typ == diffLineDeleted; i++ { - deletedLines = append(deletedLines, lines[i]) - } - - var addedLines []string - for ; i < len(lines) && lines[i].typ == diffLineAdded; i++ { - addedLines = append(addedLines, lines[i].data) - } - - if len(deletedLines) != 0 { - p.handleDeletedLines(deletedLines, addedLines) - continue - } - - // no deletions, only additions - p.handleAddedOnlyLines(addedLines) - } - - if len(p.replacementLinesToPrepend) != 0 { - p.log.Infof("The diff contains only additions: no original or deleted lines: %#v", lines) - return nil - } - - return p.changes -} - -func (p *hunkChangesParser) handleOriginalLine(lines []diffLine, line diffLine, i *int) { - if len(p.replacementLinesToPrepend) == 0 { - p.lastOriginalLine = &line - *i++ - return - } - - // check following added lines for the case: - // + added line 1 - // original line - // + added line 2 - - *i++ - var followingAddedLines []string - for ; *i < len(lines) && lines[*i].typ == diffLineAdded; *i++ { - followingAddedLines = append(followingAddedLines, lines[*i].data) - } - - change := Change{ - From: line.originalNumber, - To: line.originalNumber, - NewLines: slices.Concat(p.replacementLinesToPrepend, []string{line.data}, followingAddedLines), - } - p.changes = append(p.changes, change) - - p.replacementLinesToPrepend = nil - p.lastOriginalLine = &line -} - -func (p *hunkChangesParser) handleDeletedLines(deletedLines []diffLine, addedLines []string) { - change := Change{ - From: deletedLines[0].originalNumber, - To: deletedLines[len(deletedLines)-1].originalNumber, - } - - switch { - case len(addedLines) != 0: - change.NewLines = slices.Concat(p.replacementLinesToPrepend, addedLines) - p.replacementLinesToPrepend = nil - - case len(p.replacementLinesToPrepend) != 0: - // delete-only change with possible prepending - change.NewLines = slices.Clone(p.replacementLinesToPrepend) - p.replacementLinesToPrepend = nil - } - - p.changes = append(p.changes, change) -} - -func (p *hunkChangesParser) handleAddedOnlyLines(addedLines []string) { - if p.lastOriginalLine == nil { - // the first line is added; the diff looks like: - // 1. + ... - // 2. - ... - // or - // 1. + ... - // 2. ... - - p.replacementLinesToPrepend = addedLines - - return - } - - // add-only change merged into the last original line with possible prepending - change := Change{ - From: p.lastOriginalLine.originalNumber, - To: p.lastOriginalLine.originalNumber, - NewLines: slices.Concat(p.replacementLinesToPrepend, []string{p.lastOriginalLine.data}, addedLines), - } - - p.changes = append(p.changes, change) - - p.replacementLinesToPrepend = nil -} - -func parseDiffLines(h *diffpkg.Hunk) []diffLine { - lines := bytes.Split(h.Body, []byte{'\n'}) - - currentOriginalLineNumber := int(h.OrigStartLine) - - var diffLines []diffLine - - for i, line := range lines { - dl := diffLine{ - originalNumber: currentOriginalLineNumber, - } - - if i == len(lines)-1 && len(line) == 0 { - // handle last \n: don't add an empty original line - break - } - - lineStr := string(line) - - switch { - case strings.HasPrefix(lineStr, "-"): - dl.typ = diffLineDeleted - dl.data = strings.TrimPrefix(lineStr, "-") - currentOriginalLineNumber++ - - case strings.HasPrefix(lineStr, "+"): - dl.typ = diffLineAdded - dl.data = strings.TrimPrefix(lineStr, "+") - - default: - dl.typ = diffLineOriginal - dl.data = strings.TrimPrefix(lineStr, " ") - currentOriginalLineNumber++ - } - - diffLines = append(diffLines, dl) - } - - // if > 0, then the original file had a 'No newline at end of file' mark - if h.OrigNoNewlineAt > 0 { - dl := diffLine{ - originalNumber: currentOriginalLineNumber + 1, - typ: diffLineAdded, - data: "", - } - diffLines = append(diffLines, dl) - } - - return diffLines -} - -func ExtractDiagnosticFromPatch( - pass *analysis.Pass, - file *ast.File, - patch []byte, - logger logutils.Log, -) error { - diffs, err := diffpkg.ParseMultiFileDiff(patch) - if err != nil { - return fmt.Errorf("can't parse patch: %w", err) - } - - if len(diffs) == 0 { - return fmt.Errorf("got no diffs from patch parser: %s", patch) - } - - ft := pass.Fset.File(file.Pos()) - - adjLine := pass.Fset.PositionFor(file.Pos(), false).Line - pass.Fset.PositionFor(file.Pos(), true).Line - - for _, d := range diffs { - if len(d.Hunks) == 0 { - logger.Warnf("Got no hunks in diff %+v", d) - continue - } - - for _, hunk := range d.Hunks { - p := hunkChangesParser{log: logger} - - changes := p.parse(hunk) - - for _, change := range changes { - pass.Report(toDiagnostic(ft, change, adjLine)) - } - } - } - - return nil -} - -func toDiagnostic(ft *token.File, change Change, adjLine int) analysis.Diagnostic { - from := min(change.From+adjLine, ft.LineCount()) - - start := ft.LineStart(from) - - end := goanalysis.EndOfLinePos(ft, change.To+adjLine) - - return analysis.Diagnostic{ - Pos: start, - End: end, - Message: "File is not properly formatted", - SuggestedFixes: []analysis.SuggestedFix{{ - TextEdits: []analysis.TextEdit{{ - Pos: start, - End: end, - NewText: []byte(strings.Join(change.NewLines, "\n")), - }}, - }}, - } -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/meta_formatter.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/meta_formatter.go deleted file mode 100644 index dbedcd4cba..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/meta_formatter.go +++ /dev/null @@ -1,95 +0,0 @@ -package goformatters - -import ( - "bytes" - "fmt" - "go/format" - "slices" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goformatters/gci" - "github.com/golangci/golangci-lint/v2/pkg/goformatters/gofmt" - "github.com/golangci/golangci-lint/v2/pkg/goformatters/gofumpt" - "github.com/golangci/golangci-lint/v2/pkg/goformatters/goimports" - "github.com/golangci/golangci-lint/v2/pkg/goformatters/golines" - "github.com/golangci/golangci-lint/v2/pkg/goformatters/swaggo" - "github.com/golangci/golangci-lint/v2/pkg/logutils" -) - -type MetaFormatter struct { - log logutils.Log - formatters []Formatter -} - -func NewMetaFormatter(log logutils.Log, cfg *config.Formatters, runCfg *config.Run) (*MetaFormatter, error) { - for _, formatter := range cfg.Enable { - if !IsFormatter(formatter) { - return nil, fmt.Errorf("invalid formatter %q", formatter) - } - } - - m := &MetaFormatter{log: log} - - if slices.Contains(cfg.Enable, gofmt.Name) { - m.formatters = append(m.formatters, gofmt.New(&cfg.Settings.GoFmt)) - } - - if slices.Contains(cfg.Enable, gofumpt.Name) { - m.formatters = append(m.formatters, gofumpt.New(&cfg.Settings.GoFumpt, runCfg.Go)) - } - - if slices.Contains(cfg.Enable, goimports.Name) { - m.formatters = append(m.formatters, goimports.New(&cfg.Settings.GoImports)) - } - - if slices.Contains(cfg.Enable, swaggo.Name) { - m.formatters = append(m.formatters, swaggo.New()) - } - - // gci is a last because the only goal of gci is to handle imports. - if slices.Contains(cfg.Enable, gci.Name) { - formatter, err := gci.New(&cfg.Settings.Gci) - if err != nil { - return nil, fmt.Errorf("gci: creating formatter: %w", err) - } - - m.formatters = append(m.formatters, formatter) - } - - // golines calls `format.Source()` internally so no need to format after it. - if slices.Contains(cfg.Enable, golines.Name) { - m.formatters = append(m.formatters, golines.New(&cfg.Settings.GoLines)) - } - - return m, nil -} - -func (m *MetaFormatter) Format(filename string, src []byte) []byte { - if len(m.formatters) == 0 { - data, err := format.Source(src) - if err != nil { - m.log.Warnf("(fmt) formatting file %s: %v", filename, err) - return src - } - - return data - } - - data := bytes.Clone(src) - - for _, formatter := range m.formatters { - formatted, err := formatter.Format(filename, data) - if err != nil { - m.log.Warnf("(%s) formatting file %s: %v", formatter.Name(), filename, err) - continue - } - - data = formatted - } - - return data -} - -func IsFormatter(name string) bool { - return slices.Contains([]string{gofmt.Name, gofumpt.Name, goimports.Name, gci.Name, golines.Name, swaggo.Name}, name) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/swaggo/swaggo.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/swaggo/swaggo.go deleted file mode 100644 index 2479fb35ba..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goformatters/swaggo/swaggo.go +++ /dev/null @@ -1,23 +0,0 @@ -package swaggo - -import "github.com/golangci/swaggoswag" - -const Name = "swaggo" - -type Formatter struct { - formatter *swaggoswag.Formatter -} - -func New() *Formatter { - return &Formatter{ - formatter: swaggoswag.NewFormatter(), - } -} - -func (*Formatter) Name() string { - return Name -} - -func (f *Formatter) Format(path string, src []byte) ([]byte, error) { - return f.formatter.Format(path, src) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/arangolint/arangolint.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/arangolint/arangolint.go deleted file mode 100644 index 1598d532a8..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/arangolint/arangolint.go +++ /dev/null @@ -1,13 +0,0 @@ -package arangolint - -import ( - "go.augendre.info/arangolint/pkg/analyzer" - - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - return goanalysis. - NewLinterFromAnalyzer(analyzer.NewAnalyzer()). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/asasalint/asasalint.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/asasalint/asasalint.go deleted file mode 100644 index 0261e109d8..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/asasalint/asasalint.go +++ /dev/null @@ -1,29 +0,0 @@ -package asasalint - -import ( - "github.com/alingse/asasalint" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/golinters/internal" -) - -func New(settings *config.AsasalintSettings) *goanalysis.Linter { - cfg := asasalint.LinterSetting{} - if settings != nil { - cfg.Exclude = settings.Exclude - cfg.NoBuiltinExclusions = !settings.UseBuiltinExclusions - - // Should be managed with `linters.exclusions.rules`. - cfg.IgnoreTest = false - } - - analyzer, err := asasalint.NewAnalyzer(cfg) - if err != nil { - internal.LinterLogger.Fatalf("asasalint: create analyzer: %v", err) - } - - return goanalysis. - NewLinterFromAnalyzer(analyzer). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/asciicheck/asciicheck.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/asciicheck/asciicheck.go deleted file mode 100644 index 6a34b256a3..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/asciicheck/asciicheck.go +++ /dev/null @@ -1,13 +0,0 @@ -package asciicheck - -import ( - "github.com/golangci/asciicheck" - - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - return goanalysis. - NewLinterFromAnalyzer(asciicheck.NewAnalyzer()). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/bidichk/bidichk.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/bidichk/bidichk.go deleted file mode 100644 index c35daafbfb..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/bidichk/bidichk.go +++ /dev/null @@ -1,55 +0,0 @@ -package bidichk - -import ( - "strings" - - "github.com/breml/bidichk/pkg/bidichk" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.BiDiChkSettings) *goanalysis.Linter { - var cfg map[string]any - - if settings != nil { - var opts []string - - if settings.LeftToRightEmbedding { - opts = append(opts, "LEFT-TO-RIGHT-EMBEDDING") - } - if settings.RightToLeftEmbedding { - opts = append(opts, "RIGHT-TO-LEFT-EMBEDDING") - } - if settings.PopDirectionalFormatting { - opts = append(opts, "POP-DIRECTIONAL-FORMATTING") - } - if settings.LeftToRightOverride { - opts = append(opts, "LEFT-TO-RIGHT-OVERRIDE") - } - if settings.RightToLeftOverride { - opts = append(opts, "RIGHT-TO-LEFT-OVERRIDE") - } - if settings.LeftToRightIsolate { - opts = append(opts, "LEFT-TO-RIGHT-ISOLATE") - } - if settings.RightToLeftIsolate { - opts = append(opts, "RIGHT-TO-LEFT-ISOLATE") - } - if settings.FirstStrongIsolate { - opts = append(opts, "FIRST-STRONG-ISOLATE") - } - if settings.PopDirectionalIsolate { - opts = append(opts, "POP-DIRECTIONAL-ISOLATE") - } - - cfg = map[string]any{ - "disallowed-runes": strings.Join(opts, ","), - } - } - - return goanalysis. - NewLinterFromAnalyzer(bidichk.NewAnalyzer()). - WithConfig(cfg). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/bodyclose/bodyclose.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/bodyclose/bodyclose.go deleted file mode 100644 index f68c4d0a9e..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/bodyclose/bodyclose.go +++ /dev/null @@ -1,13 +0,0 @@ -package bodyclose - -import ( - "github.com/timakin/bodyclose/passes/bodyclose" - - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - return goanalysis. - NewLinterFromAnalyzer(bodyclose.Analyzer). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/canonicalheader/canonicalheader.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/canonicalheader/canonicalheader.go deleted file mode 100644 index 24e95f143e..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/canonicalheader/canonicalheader.go +++ /dev/null @@ -1,13 +0,0 @@ -package canonicalheader - -import ( - "github.com/lasiar/canonicalheader" - - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - return goanalysis. - NewLinterFromAnalyzer(canonicalheader.Analyzer). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/containedctx/containedctx.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/containedctx/containedctx.go deleted file mode 100644 index 6d17b8e46f..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/containedctx/containedctx.go +++ /dev/null @@ -1,13 +0,0 @@ -package containedctx - -import ( - "github.com/sivchari/containedctx" - - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - return goanalysis. - NewLinterFromAnalyzer(containedctx.Analyzer). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/contextcheck/contextcheck.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/contextcheck/contextcheck.go deleted file mode 100644 index 88c71d2d3e..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/contextcheck/contextcheck.go +++ /dev/null @@ -1,19 +0,0 @@ -package contextcheck - -import ( - "github.com/kkHAIKE/contextcheck" - - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/lint/linter" -) - -func New() *goanalysis.Linter { - analyzer := contextcheck.NewAnalyzer(contextcheck.Configuration{}) - - return goanalysis. - NewLinterFromAnalyzer(analyzer). - WithContextSetter(func(lintCtx *linter.Context) { - analyzer.Run = contextcheck.NewRun(lintCtx.Packages, false) - }). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/copyloopvar/copyloopvar.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/copyloopvar/copyloopvar.go deleted file mode 100644 index 9dc81de58a..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/copyloopvar/copyloopvar.go +++ /dev/null @@ -1,23 +0,0 @@ -package copyloopvar - -import ( - "github.com/karamaru-alpha/copyloopvar" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.CopyLoopVarSettings) *goanalysis.Linter { - var cfg map[string]any - - if settings != nil { - cfg = map[string]any{ - "check-alias": settings.CheckAlias, - } - } - - return goanalysis. - NewLinterFromAnalyzer(copyloopvar.NewAnalyzer()). - WithConfig(cfg). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/cyclop/cyclop.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/cyclop/cyclop.go deleted file mode 100644 index 0a0e2dbc63..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/cyclop/cyclop.go +++ /dev/null @@ -1,30 +0,0 @@ -package cyclop - -import ( - "github.com/bkielbasa/cyclop/pkg/analyzer" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.CyclopSettings) *goanalysis.Linter { - cfg := map[string]any{} - - if settings != nil { - // Should be managed with `linters.exclusions.rules`. - cfg["skipTests"] = false - - if settings.MaxComplexity != 0 { - cfg["maxComplexity"] = settings.MaxComplexity - } - - if settings.PackageAverage != 0 { - cfg["packageAverage"] = settings.PackageAverage - } - } - - return goanalysis. - NewLinterFromAnalyzer(analyzer.NewAnalyzer()). - WithConfig(cfg). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/decorder/decorder.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/decorder/decorder.go deleted file mode 100644 index a67bdfade1..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/decorder/decorder.go +++ /dev/null @@ -1,39 +0,0 @@ -package decorder - -import ( - "strings" - - "gitlab.com/bosi/decorder" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.DecorderSettings) *goanalysis.Linter { - // disable all rules/checks by default - cfg := map[string]any{ - "ignore-underscore-vars": false, - "disable-dec-num-check": true, - "disable-type-dec-num-check": false, - "disable-const-dec-num-check": false, - "disable-var-dec-num-check": false, - "disable-dec-order-check": true, - "disable-init-func-first-check": true, - } - - if settings != nil { - cfg["dec-order"] = strings.Join(settings.DecOrder, ",") - cfg["ignore-underscore-vars"] = settings.IgnoreUnderscoreVars - cfg["disable-dec-num-check"] = settings.DisableDecNumCheck - cfg["disable-type-dec-num-check"] = settings.DisableTypeDecNumCheck - cfg["disable-const-dec-num-check"] = settings.DisableConstDecNumCheck - cfg["disable-var-dec-num-check"] = settings.DisableVarDecNumCheck - cfg["disable-dec-order-check"] = settings.DisableDecOrderCheck - cfg["disable-init-func-first-check"] = settings.DisableInitFuncFirstCheck - } - - return goanalysis. - NewLinterFromAnalyzer(decorder.Analyzer). - WithConfig(cfg). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/depguard/depguard.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/depguard/depguard.go deleted file mode 100644 index cc01f4f47a..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/depguard/depguard.go +++ /dev/null @@ -1,54 +0,0 @@ -package depguard - -import ( - "strings" - - "github.com/OpenPeeDeeP/depguard/v2" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/lint/linter" -) - -func New(settings *config.DepGuardSettings, replacer *strings.Replacer) *goanalysis.Linter { - conf := depguard.LinterSettings{} - - if settings != nil { - for s, rule := range settings.Rules { - var extendedPatterns []string - for _, file := range rule.Files { - extendedPatterns = append(extendedPatterns, replacer.Replace(file)) - } - - list := &depguard.List{ - ListMode: rule.ListMode, - Files: extendedPatterns, - Allow: rule.Allow, - } - - // because of bug with Viper parsing (split on dot) we use a list of struct instead of a map. - // https://github.com/spf13/viper/issues/324 - // https://github.com/golangci/golangci-lint/issues/3749#issuecomment-1492536630 - - deny := map[string]string{} - for _, r := range rule.Deny { - deny[r.Pkg] = r.Desc - } - list.Deny = deny - - conf[s] = list - } - } - - analyzer := depguard.NewUncompiledAnalyzer(&conf) - - return goanalysis. - NewLinterFromAnalyzer(analyzer.Analyzer). - WithContextSetter(func(lintCtx *linter.Context) { - err := analyzer.Compile() - if err != nil { - lintCtx.Log.Errorf("create analyzer: %v", err) - } - }). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/dogsled/dogsled.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/dogsled/dogsled.go deleted file mode 100644 index 5516d2b39c..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/dogsled/dogsled.go +++ /dev/null @@ -1,67 +0,0 @@ -package dogsled - -import ( - "go/ast" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/inspector" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.DogsledSettings) *goanalysis.Linter { - return goanalysis. - NewLinterFromAnalyzer(&analysis.Analyzer{ - Name: "dogsled", - Doc: "Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f())", - Run: func(pass *analysis.Pass) (any, error) { - return run(pass, settings.MaxBlankIdentifiers) - }, - Requires: []*analysis.Analyzer{inspect.Analyzer}, - }). - WithLoadMode(goanalysis.LoadModeSyntax) -} - -func run(pass *analysis.Pass, maxBlanks int) (any, error) { - insp, ok := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - if !ok { - return nil, nil - } - - for node := range insp.PreorderSeq((*ast.FuncDecl)(nil)) { - funcDecl, ok := node.(*ast.FuncDecl) - if !ok { - continue - } - - if funcDecl.Body == nil { - continue - } - - for _, expr := range funcDecl.Body.List { - assgnStmt, ok := expr.(*ast.AssignStmt) - if !ok { - continue - } - - numBlank := 0 - for _, left := range assgnStmt.Lhs { - ident, ok := left.(*ast.Ident) - if !ok { - continue - } - if ident.Name == "_" { - numBlank++ - } - } - - if numBlank > maxBlanks { - pass.Reportf(assgnStmt.Pos(), "declaration has %v blank identifiers", numBlank) - } - } - } - - return nil, nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/dupl/dupl.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/dupl/dupl.go deleted file mode 100644 index 0b6b3a162c..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/dupl/dupl.go +++ /dev/null @@ -1,90 +0,0 @@ -package dupl - -import ( - "fmt" - "go/token" - "sync" - - duplAPI "github.com/golangci/dupl/lib" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/fsutils" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/golinters/internal" - "github.com/golangci/golangci-lint/v2/pkg/lint/linter" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -const linterName = "dupl" - -func New(settings *config.DuplSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []*goanalysis.Issue - - return goanalysis. - NewLinterFromAnalyzer(&analysis.Analyzer{ - Name: linterName, - Doc: "Detects duplicate fragments of code.", - Run: func(pass *analysis.Pass) (any, error) { - issues, err := runDupl(pass, settings) - if err != nil { - return nil, err - } - - if len(issues) == 0 { - return nil, nil - } - - mu.Lock() - resIssues = append(resIssues, issues...) - mu.Unlock() - - return nil, nil - }, - }). - WithIssuesReporter(func(*linter.Context) []*goanalysis.Issue { - return resIssues - }). - WithLoadMode(goanalysis.LoadModeSyntax) -} - -func runDupl(pass *analysis.Pass, settings *config.DuplSettings) ([]*goanalysis.Issue, error) { - issues, err := duplAPI.Run(internal.GetGoFileNames(pass), settings.Threshold) - if err != nil { - return nil, err - } - - if len(issues) == 0 { - return nil, nil - } - - res := make([]*goanalysis.Issue, 0, len(issues)) - - for _, i := range issues { - toFilename, err := fsutils.ShortestRelPath(i.To.Filename(), "") - if err != nil { - return nil, fmt.Errorf("failed to get shortest rel path for %q: %w", i.To.Filename(), err) - } - - dupl := fmt.Sprintf("%s:%d-%d", toFilename, i.To.LineStart(), i.To.LineEnd()) - text := fmt.Sprintf("%d-%d lines are duplicate of %s", - i.From.LineStart(), i.From.LineEnd(), - internal.FormatCode(dupl)) - - res = append(res, goanalysis.NewIssue(&result.Issue{ - Pos: token.Position{ - Filename: i.From.Filename(), - Line: i.From.LineStart(), - }, - LineRange: &result.Range{ - From: i.From.LineStart(), - To: i.From.LineEnd(), - }, - Text: text, - FromLinter: linterName, - }, pass)) - } - - return res, nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/dupword/dupword.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/dupword/dupword.go deleted file mode 100644 index 0308534e31..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/dupword/dupword.go +++ /dev/null @@ -1,28 +0,0 @@ -package dupword - -import ( - "strings" - - "github.com/Abirdcfly/dupword" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.DupWordSettings) *goanalysis.Linter { - var cfg map[string]any - - if settings != nil { - cfg = map[string]any{ - "keyword": strings.Join(settings.Keywords, ","), - "ignore": strings.Join(settings.Ignore, ","), - "comments-only": settings.CommentsOnly, - } - } - - return goanalysis. - NewLinterFromAnalyzer(dupword.NewAnalyzer()). - WithDesc("Checks for duplicate words in the source code"). - WithConfig(cfg). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/durationcheck/durationcheck.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/durationcheck/durationcheck.go deleted file mode 100644 index b6723fa125..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/durationcheck/durationcheck.go +++ /dev/null @@ -1,13 +0,0 @@ -package durationcheck - -import ( - "github.com/charithe/durationcheck" - - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - return goanalysis. - NewLinterFromAnalyzer(durationcheck.Analyzer). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/embeddedstructfieldcheck/embeddedstructfieldcheck.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/embeddedstructfieldcheck/embeddedstructfieldcheck.go deleted file mode 100644 index ba4c06eb7c..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/embeddedstructfieldcheck/embeddedstructfieldcheck.go +++ /dev/null @@ -1,24 +0,0 @@ -package embeddedstructfieldcheck - -import ( - "github.com/manuelarte/embeddedstructfieldcheck/analyzer" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.EmbeddedStructFieldCheckSettings) *goanalysis.Linter { - var cfg map[string]any - - if settings != nil { - cfg = map[string]any{ - analyzer.ForbidMutexCheck: settings.ForbidMutex, - analyzer.EmptyLineCheck: settings.EmptyLine, - } - } - - return goanalysis. - NewLinterFromAnalyzer(analyzer.NewAnalyzer()). - WithConfig(cfg). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/err113/err113.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/err113/err113.go deleted file mode 100644 index d3b3a4c1cc..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/err113/err113.go +++ /dev/null @@ -1,14 +0,0 @@ -package err113 - -import ( - "github.com/Djarvur/go-err113" - - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - return goanalysis. - NewLinterFromAnalyzer(err113.NewAnalyzer()). - WithDesc("Check errors handling expressions"). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/errcheck/errcheck.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/errcheck/errcheck.go deleted file mode 100644 index 6bd473845c..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/errcheck/errcheck.go +++ /dev/null @@ -1,115 +0,0 @@ -package errcheck - -import ( - "cmp" - "fmt" - "regexp" - "sync" - - "github.com/kisielk/errcheck/errcheck" - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/packages" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/golinters/internal" - "github.com/golangci/golangci-lint/v2/pkg/lint/linter" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -const linterName = "errcheck" - -func New(settings *config.ErrcheckSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []*goanalysis.Issue - - analyzer := &analysis.Analyzer{ - Name: linterName, - Doc: "errcheck is a program for checking for unchecked errors in Go code. " + - "These unchecked errors can be critical bugs in some cases", - Run: goanalysis.DummyRun, - } - - return goanalysis. - NewLinterFromAnalyzer(analyzer). - WithContextSetter(func(lintCtx *linter.Context) { - checker := getChecker(settings) - checker.Tags = lintCtx.Cfg.Run.BuildTags - - analyzer.Run = func(pass *analysis.Pass) (any, error) { - issues := runErrCheck(pass, checker, settings.Verbose) - - if len(issues) == 0 { - return nil, nil - } - - mu.Lock() - resIssues = append(resIssues, issues...) - mu.Unlock() - - return nil, nil - } - }). - WithIssuesReporter(func(*linter.Context) []*goanalysis.Issue { - return resIssues - }). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} - -func runErrCheck(pass *analysis.Pass, checker *errcheck.Checker, verbose bool) []*goanalysis.Issue { - pkg := &packages.Package{ - Fset: pass.Fset, - Syntax: pass.Files, - Types: pass.Pkg, - TypesInfo: pass.TypesInfo, - } - - lintIssues := checker.CheckPackage(pkg).Unique() - if len(lintIssues.UncheckedErrors) == 0 { - return nil - } - - issues := make([]*goanalysis.Issue, len(lintIssues.UncheckedErrors)) - - for i, err := range lintIssues.UncheckedErrors { - text := "Error return value is not checked" - - if err.FuncName != "" { - code := cmp.Or(err.SelectorName, err.FuncName) - if verbose { - code = err.FuncName - } - - text = fmt.Sprintf("Error return value of %s is not checked", internal.FormatCode(code)) - } - - issues[i] = goanalysis.NewIssue( - &result.Issue{ - FromLinter: linterName, - Text: text, - Pos: err.Pos, - }, - pass, - ) - } - - return issues -} - -func getChecker(errCfg *config.ErrcheckSettings) *errcheck.Checker { - checker := errcheck.Checker{ - Exclusions: errcheck.Exclusions{ - BlankAssignments: !errCfg.CheckAssignToBlank, - TypeAssertions: !errCfg.CheckTypeAssertions, - SymbolRegexpsByPackage: map[string]*regexp.Regexp{}, - }, - } - - if !errCfg.DisableDefaultExclusions { - checker.Exclusions.Symbols = append(checker.Exclusions.Symbols, errcheck.DefaultExcludedSymbols...) - } - - checker.Exclusions.Symbols = append(checker.Exclusions.Symbols, errCfg.ExcludeFunctions...) - - return &checker -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/errchkjson/errchkjson.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/errchkjson/errchkjson.go deleted file mode 100644 index 02510ab499..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/errchkjson/errchkjson.go +++ /dev/null @@ -1,26 +0,0 @@ -package errchkjson - -import ( - "github.com/breml/errchkjson" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.ErrChkJSONSettings) *goanalysis.Linter { - cfg := map[string]any{ - "omit-safe": true, - } - - if settings != nil { - cfg = map[string]any{ - "omit-safe": !settings.CheckErrorFreeEncoding, - "report-no-exported": settings.ReportNoExported, - } - } - - return goanalysis. - NewLinterFromAnalyzer(errchkjson.NewAnalyzer()). - WithConfig(cfg). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/errname/errname.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/errname/errname.go deleted file mode 100644 index a66f3211f4..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/errname/errname.go +++ /dev/null @@ -1,13 +0,0 @@ -package errname - -import ( - "github.com/Antonboom/errname/pkg/analyzer" - - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - return goanalysis. - NewLinterFromAnalyzer(analyzer.New()). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/errorlint/errorlint.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/errorlint/errorlint.go deleted file mode 100644 index f322177969..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/errorlint/errorlint.go +++ /dev/null @@ -1,49 +0,0 @@ -package errorlint - -import ( - "github.com/polyfloyd/go-errorlint/errorlint" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.ErrorLintSettings) *goanalysis.Linter { - var opts []errorlint.Option - - if settings != nil { - ae := toAllowPairs(settings.AllowedErrors) - if len(ae) > 0 { - opts = append(opts, errorlint.WithAllowedErrors(ae)) - } - - aew := toAllowPairs(settings.AllowedErrorsWildcard) - if len(aew) > 0 { - opts = append(opts, errorlint.WithAllowedWildcard(aew)) - } - } - - var cfg map[string]any - - if settings != nil { - cfg = map[string]any{ - "errorf": settings.Errorf, - "errorf-multi": settings.ErrorfMulti, - "asserts": settings.Asserts, - "comparison": settings.Comparison, - } - } - - return goanalysis. - NewLinterFromAnalyzer(errorlint.NewAnalyzer(opts...)). - WithDesc("Find code that can cause problems with the error wrapping scheme introduced in Go 1.13."). - WithConfig(cfg). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} - -func toAllowPairs(data []config.ErrorLintAllowPair) []errorlint.AllowPair { - var pairs []errorlint.AllowPair - for _, allowedError := range data { - pairs = append(pairs, errorlint.AllowPair(allowedError)) - } - return pairs -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/exhaustive/exhaustive.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/exhaustive/exhaustive.go deleted file mode 100644 index ec240739d6..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/exhaustive/exhaustive.go +++ /dev/null @@ -1,32 +0,0 @@ -package exhaustive - -import ( - "github.com/nishanths/exhaustive" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.ExhaustiveSettings) *goanalysis.Linter { - var cfg map[string]any - - if settings != nil { - cfg = map[string]any{ - exhaustive.CheckFlag: settings.Check, - exhaustive.DefaultSignifiesExhaustiveFlag: settings.DefaultSignifiesExhaustive, - exhaustive.IgnoreEnumMembersFlag: settings.IgnoreEnumMembers, - exhaustive.IgnoreEnumTypesFlag: settings.IgnoreEnumTypes, - exhaustive.PackageScopeOnlyFlag: settings.PackageScopeOnly, - exhaustive.ExplicitExhaustiveMapFlag: settings.ExplicitExhaustiveMap, - exhaustive.ExplicitExhaustiveSwitchFlag: settings.ExplicitExhaustiveSwitch, - exhaustive.DefaultCaseRequiredFlag: settings.DefaultCaseRequired, - // Should be managed with `linters.exclusions.generated`. - exhaustive.CheckGeneratedFlag: true, - } - } - - return goanalysis. - NewLinterFromAnalyzer(exhaustive.Analyzer). - WithConfig(cfg). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/exhaustruct/exhaustruct.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/exhaustruct/exhaustruct.go deleted file mode 100644 index 01136aadc8..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/exhaustruct/exhaustruct.go +++ /dev/null @@ -1,30 +0,0 @@ -package exhaustruct - -import ( - exhaustruct "dev.gaijin.team/go/exhaustruct/v4/analyzer" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/golinters/internal" -) - -func New(settings *config.ExhaustructSettings) *goanalysis.Linter { - cfg := exhaustruct.Config{} - if settings != nil { - cfg.IncludeRx = settings.Include - cfg.ExcludeRx = settings.Exclude - cfg.AllowEmpty = settings.AllowEmpty - cfg.AllowEmptyRx = settings.AllowEmptyRx - cfg.AllowEmptyReturns = settings.AllowEmptyReturns - cfg.AllowEmptyDeclarations = settings.AllowEmptyDeclarations - } - - analyzer, err := exhaustruct.NewAnalyzer(cfg) - if err != nil { - internal.LinterLogger.Fatalf("exhaustruct configuration: %v", err) - } - - return goanalysis. - NewLinterFromAnalyzer(analyzer). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/exptostd/exptostd.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/exptostd/exptostd.go deleted file mode 100644 index dbd78dce91..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/exptostd/exptostd.go +++ /dev/null @@ -1,13 +0,0 @@ -package exptostd - -import ( - "github.com/ldez/exptostd" - - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - return goanalysis. - NewLinterFromAnalyzer(exptostd.NewAnalyzer()). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/fatcontext/fatcontext.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/fatcontext/fatcontext.go deleted file mode 100644 index 58933c6605..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/fatcontext/fatcontext.go +++ /dev/null @@ -1,23 +0,0 @@ -package fatcontext - -import ( - "go.augendre.info/fatcontext/pkg/analyzer" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.FatcontextSettings) *goanalysis.Linter { - var cfg map[string]any - - if settings != nil { - cfg = map[string]any{ - analyzer.FlagCheckStructPointers: settings.CheckStructPointers, - } - } - - return goanalysis. - NewLinterFromAnalyzer(analyzer.NewAnalyzer()). - WithConfig(cfg). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/forbidigo/forbidigo.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/forbidigo/forbidigo.go deleted file mode 100644 index 796faf3a6e..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/forbidigo/forbidigo.go +++ /dev/null @@ -1,85 +0,0 @@ -package forbidigo - -import ( - "fmt" - - "github.com/ashanbrown/forbidigo/v2/forbidigo" - "golang.org/x/tools/go/analysis" - "gopkg.in/yaml.v3" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/logutils" -) - -const linterName = "forbidigo" - -func New(settings *config.ForbidigoSettings) *goanalysis.Linter { - // Without AnalyzeTypes, LoadModeSyntax is enough. - // But we cannot make this depend on the settings and have to mirror the mode chosen in GetAllSupportedLinterConfigs, - // therefore, we have to use LoadModeTypesInfo in all cases. - return goanalysis. - NewLinterFromAnalyzer(&analysis.Analyzer{ - Name: linterName, - Doc: "Forbids identifiers", - Run: func(pass *analysis.Pass) (any, error) { - err := runForbidigo(pass, settings) - if err != nil { - return nil, err - } - - return nil, nil - }, - }). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} - -func runForbidigo(pass *analysis.Pass, settings *config.ForbidigoSettings) error { - options := []forbidigo.Option{ - forbidigo.OptionExcludeGodocExamples(settings.ExcludeGodocExamples), - // disable "//permit" directives so only "//nolint" directives matters within golangci-lint - forbidigo.OptionIgnorePermitDirectives(true), - forbidigo.OptionAnalyzeTypes(settings.AnalyzeTypes), - } - - // Convert patterns back to strings because that is what NewLinter accepts. - var patterns []string - for _, pattern := range settings.Forbid { - buffer, err := yaml.Marshal(pattern) - if err != nil { - return err - } - - patterns = append(patterns, string(buffer)) - } - - forbid, err := forbidigo.NewLinter(patterns, options...) - if err != nil { - return fmt.Errorf("failed to create linter %q: %w", linterName, err) - } - - for _, file := range pass.Files { - runConfig := forbidigo.RunConfig{ - Fset: pass.Fset, - DebugLog: logutils.Debug(logutils.DebugKeyForbidigo), - } - - if settings.AnalyzeTypes { - runConfig.TypesInfo = pass.TypesInfo - } - - hints, err := forbid.RunWithConfig(runConfig, file) - if err != nil { - return fmt.Errorf("forbidigo linter failed on file %q: %w", file.Name.String(), err) - } - - for _, hint := range hints { - pass.Report(analysis.Diagnostic{ - Pos: hint.Pos(), - Message: hint.Details(), - }) - } - } - - return nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/forcetypeassert/forcetypeassert.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/forcetypeassert/forcetypeassert.go deleted file mode 100644 index 19a0e3450b..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/forcetypeassert/forcetypeassert.go +++ /dev/null @@ -1,14 +0,0 @@ -package forcetypeassert - -import ( - "github.com/gostaticanalysis/forcetypeassert" - - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - return goanalysis. - NewLinterFromAnalyzer(forcetypeassert.Analyzer). - WithDesc("Find forced type assertions"). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/funcorder/funcorder.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/funcorder/funcorder.go deleted file mode 100644 index 06400753eb..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/funcorder/funcorder.go +++ /dev/null @@ -1,25 +0,0 @@ -package funcorder - -import ( - "github.com/manuelarte/funcorder/analyzer" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.FuncOrderSettings) *goanalysis.Linter { - var cfg map[string]any - - if settings != nil { - cfg = map[string]any{ - analyzer.ConstructorCheckName: settings.Constructor, - analyzer.StructMethodCheckName: settings.StructMethod, - analyzer.AlphabeticalCheckName: settings.Alphabetical, - } - } - - return goanalysis. - NewLinterFromAnalyzer(analyzer.NewAnalyzer()). - WithConfig(cfg). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/funlen/funlen.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/funlen/funlen.go deleted file mode 100644 index 6e0f93b513..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/funlen/funlen.go +++ /dev/null @@ -1,27 +0,0 @@ -package funlen - -import ( - "github.com/ultraware/funlen" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -type Config struct { - lineLimit int - stmtLimit int - ignoreComments bool -} - -func New(settings *config.FunlenSettings) *goanalysis.Linter { - cfg := Config{} - if settings != nil { - cfg.lineLimit = settings.Lines - cfg.stmtLimit = settings.Statements - cfg.ignoreComments = settings.IgnoreComments - } - - return goanalysis. - NewLinterFromAnalyzer(funlen.NewAnalyzer(cfg.lineLimit, cfg.stmtLimit, cfg.ignoreComments)). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gci/gci.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gci/gci.go deleted file mode 100644 index 4357a3b15f..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gci/gci.go +++ /dev/null @@ -1,28 +0,0 @@ -package gci - -import ( - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/goformatters" - gcibase "github.com/golangci/golangci-lint/v2/pkg/goformatters/gci" - "github.com/golangci/golangci-lint/v2/pkg/golinters/internal" -) - -const linterName = "gci" - -func New(settings *config.GciSettings) *goanalysis.Linter { - formatter, err := gcibase.New(settings) - if err != nil { - internal.LinterLogger.Fatalf("%s: create analyzer: %v", linterName, err) - } - - return goanalysis. - NewLinterFromAnalyzer( - goformatters.NewAnalyzer( - internal.LinterLogger.Child(linterName), - "Check if code and import statements are formatted, with additional rules.", - formatter, - ), - ). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/ginkgolinter/ginkgolinter.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/ginkgolinter/ginkgolinter.go deleted file mode 100644 index 99b9eb474e..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/ginkgolinter/ginkgolinter.go +++ /dev/null @@ -1,37 +0,0 @@ -package ginkgolinter - -import ( - "github.com/nunnatsa/ginkgolinter" - glconfig "github.com/nunnatsa/ginkgolinter/config" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.GinkgoLinterSettings) *goanalysis.Linter { - cfg := &glconfig.Config{} - - if settings != nil { - cfg = &glconfig.Config{ - SuppressLen: settings.SuppressLenAssertion, - SuppressNil: settings.SuppressNilAssertion, - SuppressErr: settings.SuppressErrAssertion, - SuppressCompare: settings.SuppressCompareAssertion, - SuppressAsync: settings.SuppressAsyncAssertion, - ForbidFocus: settings.ForbidFocusContainer, - SuppressTypeCompare: settings.SuppressTypeCompareWarning, - AllowHaveLen0: settings.AllowHaveLenZero, - ForceExpectTo: settings.ForceExpectTo, - ValidateAsyncIntervals: settings.ValidateAsyncIntervals, - ForbidSpecPollution: settings.ForbidSpecPollution, - ForceSucceedForFuncs: settings.ForceSucceedForFuncs, - ForceAssertionDescription: settings.ForceAssertionDescription, - ForeToNot: settings.ForeToNot, - } - } - - return goanalysis. - NewLinterFromAnalyzer(ginkgolinter.NewAnalyzerWithConfig(cfg)). - WithDesc("enforces standards of using ginkgo and gomega"). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gocheckcompilerdirectives/gocheckcompilerdirectives.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gocheckcompilerdirectives/gocheckcompilerdirectives.go deleted file mode 100644 index 71f4be8c41..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gocheckcompilerdirectives/gocheckcompilerdirectives.go +++ /dev/null @@ -1,13 +0,0 @@ -package gocheckcompilerdirectives - -import ( - "4d63.com/gocheckcompilerdirectives/checkcompilerdirectives" - - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - return goanalysis. - NewLinterFromAnalyzer(checkcompilerdirectives.Analyzer()). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gochecknoglobals/gochecknoglobals.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gochecknoglobals/gochecknoglobals.go deleted file mode 100644 index 2fd3f3c3be..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gochecknoglobals/gochecknoglobals.go +++ /dev/null @@ -1,14 +0,0 @@ -package gochecknoglobals - -import ( - "4d63.com/gochecknoglobals/checknoglobals" - - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - return goanalysis. - NewLinterFromAnalyzer(checknoglobals.Analyzer()). - WithDesc("Check that no global variables exist."). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gochecknoinits/gochecknoinits.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gochecknoinits/gochecknoinits.go deleted file mode 100644 index 161db84ee6..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gochecknoinits/gochecknoinits.go +++ /dev/null @@ -1,44 +0,0 @@ -package gochecknoinits - -import ( - "go/ast" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/inspector" - - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/golinters/internal" -) - -func New() *goanalysis.Linter { - return goanalysis. - NewLinterFromAnalyzer(&analysis.Analyzer{ - Name: "gochecknoinits", - Doc: "Checks that no init functions are present in Go code", - Run: run, - Requires: []*analysis.Analyzer{inspect.Analyzer}, - }). - WithLoadMode(goanalysis.LoadModeSyntax) -} - -func run(pass *analysis.Pass) (any, error) { - insp, ok := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - if !ok { - return nil, nil - } - - for node := range insp.PreorderSeq((*ast.FuncDecl)(nil)) { - funcDecl, ok := node.(*ast.FuncDecl) - if !ok { - continue - } - - fnName := funcDecl.Name.Name - if fnName == "init" && funcDecl.Recv.NumFields() == 0 { - pass.Reportf(funcDecl.Pos(), "don't use %s function", internal.FormatCode(fnName)) - } - } - - return nil, nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gochecksumtype/gochecksumtype.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gochecksumtype/gochecksumtype.go deleted file mode 100644 index 825975f145..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gochecksumtype/gochecksumtype.go +++ /dev/null @@ -1,82 +0,0 @@ -package gochecksumtype - -import ( - "strings" - "sync" - - gochecksumtype "github.com/alecthomas/go-check-sumtype" - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/packages" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/lint/linter" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -const linterName = "gochecksumtype" - -func New(settings *config.GoChecksumTypeSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []*goanalysis.Issue - - return goanalysis. - NewLinterFromAnalyzer(&analysis.Analyzer{ - Name: linterName, - Doc: `Run exhaustiveness checks on Go "sum types"`, - Run: func(pass *analysis.Pass) (any, error) { - issues, err := runGoCheckSumType(pass, settings) - if err != nil { - return nil, err - } - - if len(issues) == 0 { - return nil, nil - } - - mu.Lock() - resIssues = append(resIssues, issues...) - mu.Unlock() - - return nil, nil - }, - }). - WithIssuesReporter(func(_ *linter.Context) []*goanalysis.Issue { - return resIssues - }). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} - -func runGoCheckSumType(pass *analysis.Pass, settings *config.GoChecksumTypeSettings) ([]*goanalysis.Issue, error) { - var resIssues []*goanalysis.Issue - - pkg := &packages.Package{ - Fset: pass.Fset, - Syntax: pass.Files, - Types: pass.Pkg, - TypesInfo: pass.TypesInfo, - } - - cfg := gochecksumtype.Config{ - DefaultSignifiesExhaustive: settings.DefaultSignifiesExhaustive, - IncludeSharedInterfaces: settings.IncludeSharedInterfaces, - } - - var unknownError error - errors := gochecksumtype.Run([]*packages.Package{pkg}, cfg) - for _, err := range errors { - err, ok := err.(gochecksumtype.Error) - if !ok { - unknownError = err - continue - } - - resIssues = append(resIssues, goanalysis.NewIssue(&result.Issue{ - FromLinter: linterName, - Text: strings.TrimPrefix(err.Error(), err.Pos().String()+": "), - Pos: err.Pos(), - }, pass)) - } - - return resIssues, unknownError -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gocognit/gocognit.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gocognit/gocognit.go deleted file mode 100644 index b17912c0a6..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gocognit/gocognit.go +++ /dev/null @@ -1,76 +0,0 @@ -package gocognit - -import ( - "fmt" - "sort" - "sync" - - "github.com/uudashr/gocognit" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/golinters/internal" - "github.com/golangci/golangci-lint/v2/pkg/lint/linter" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -const linterName = "gocognit" - -func New(settings *config.GocognitSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []*goanalysis.Issue - - return goanalysis. - NewLinterFromAnalyzer(&analysis.Analyzer{ - Name: linterName, - Doc: "Computes and checks the cognitive complexity of functions", - Run: func(pass *analysis.Pass) (any, error) { - issues := runGocognit(pass, settings) - - if len(issues) == 0 { - return nil, nil - } - - mu.Lock() - resIssues = append(resIssues, issues...) - mu.Unlock() - - return nil, nil - }, - }). - WithIssuesReporter(func(*linter.Context) []*goanalysis.Issue { - return resIssues - }). - WithLoadMode(goanalysis.LoadModeSyntax) -} - -func runGocognit(pass *analysis.Pass, settings *config.GocognitSettings) []*goanalysis.Issue { - var stats []gocognit.Stat - for _, f := range pass.Files { - stats = gocognit.ComplexityStats(f, pass.Fset, stats) - } - if len(stats) == 0 { - return nil - } - - sort.SliceStable(stats, func(i, j int) bool { - return stats[i].Complexity > stats[j].Complexity - }) - - issues := make([]*goanalysis.Issue, 0, len(stats)) - for _, s := range stats { - if s.Complexity <= settings.MinComplexity { - break // Break as the stats is already sorted from greatest to least - } - - issues = append(issues, goanalysis.NewIssue(&result.Issue{ - Pos: s.Pos, - Text: fmt.Sprintf("cognitive complexity %d of func %s is high (> %d)", - s.Complexity, internal.FormatCode(s.FuncName), settings.MinComplexity), - FromLinter: linterName, - }, pass)) - } - - return issues -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/goconst/goconst.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/goconst/goconst.go deleted file mode 100644 index b58d860c6e..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/goconst/goconst.go +++ /dev/null @@ -1,113 +0,0 @@ -package goconst - -import ( - "fmt" - "sync" - - goconstAPI "github.com/jgautheron/goconst" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/golinters/internal" - "github.com/golangci/golangci-lint/v2/pkg/lint/linter" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -const linterName = "goconst" - -func New(settings *config.GoConstSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []*goanalysis.Issue - - return goanalysis. - NewLinterFromAnalyzer(&analysis.Analyzer{ - Name: linterName, - Doc: "Finds repeated strings that could be replaced by a constant", - Run: func(pass *analysis.Pass) (any, error) { - issues, err := runGoconst(pass, settings) - if err != nil { - return nil, err - } - - if len(issues) == 0 { - return nil, nil - } - - mu.Lock() - resIssues = append(resIssues, issues...) - mu.Unlock() - - return nil, nil - }, - }). - WithIssuesReporter(func(*linter.Context) []*goanalysis.Issue { - return resIssues - }). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} - -func runGoconst(pass *analysis.Pass, settings *config.GoConstSettings) ([]*goanalysis.Issue, error) { - cfg := goconstAPI.Config{ - IgnoreStrings: settings.IgnoreStringValues, - MatchWithConstants: settings.MatchWithConstants, - MinStringLength: settings.MinStringLen, - MinOccurrences: settings.MinOccurrencesCount, - ParseNumbers: settings.ParseNumbers, - NumberMin: settings.NumberMin, - NumberMax: settings.NumberMax, - ExcludeTypes: map[goconstAPI.Type]bool{}, - FindDuplicates: settings.FindDuplicates, - EvalConstExpressions: settings.EvalConstExpressions, - - // Should be managed with `linters.exclusions.rules`. - IgnoreTests: false, - } - - if settings.IgnoreCalls { - cfg.ExcludeTypes[goconstAPI.Call] = true - } - - lintIssues, err := goconstAPI.Run(pass.Files, pass.Fset, pass.TypesInfo, &cfg) - if err != nil { - return nil, err - } - - if len(lintIssues) == 0 { - return nil, nil - } - - res := make([]*goanalysis.Issue, 0, len(lintIssues)) - for i := range lintIssues { - issue := &lintIssues[i] - - var text string - - switch { - case issue.OccurrencesCount > 0: - text = fmt.Sprintf("string %s has %d occurrences", internal.FormatCode(issue.Str), issue.OccurrencesCount) - - if issue.MatchingConst == "" { - text += ", make it a constant" - } else { - text += fmt.Sprintf(", but such constant %s already exists", internal.FormatCode(issue.MatchingConst)) - } - - case issue.DuplicateConst != "": - text = fmt.Sprintf("This constant is a duplicate of %s at %s", - internal.FormatCode(issue.DuplicateConst), - issue.DuplicatePos.String()) - - default: - continue - } - - res = append(res, goanalysis.NewIssue(&result.Issue{ - Pos: issue.Pos, - Text: text, - FromLinter: linterName, - }, pass)) - } - - return res, nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gocritic/gocritic.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gocritic/gocritic.go deleted file mode 100644 index cd7337590c..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gocritic/gocritic.go +++ /dev/null @@ -1,166 +0,0 @@ -package gocritic - -import ( - "errors" - "fmt" - "go/ast" - "go/types" - "runtime" - "slices" - "strings" - "sync" - - "github.com/go-critic/go-critic/checkers" - gocriticlinter "github.com/go-critic/go-critic/linter" - _ "github.com/quasilyte/go-ruleguard/dsl" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/lint/linter" - "github.com/golangci/golangci-lint/v2/pkg/logutils" -) - -const linterName = "gocritic" - -var ( - debugf = logutils.Debug(logutils.DebugKeyGoCritic) - isDebug = logutils.HaveDebugTag(logutils.DebugKeyGoCritic) -) - -func New(settings *config.GoCriticSettings, replacer *strings.Replacer) *goanalysis.Linter { - wrapper := &goCriticWrapper{ - sizes: types.SizesFor("gc", runtime.GOARCH), - } - - return goanalysis. - NewLinterFromAnalyzer(&analysis.Analyzer{ - Name: linterName, - Doc: `Provides diagnostics that check for bugs, performance and style issues. -Extensible without recompilation through dynamic rules. -Dynamic rules are written declaratively with AST patterns, filters, report message and optional suggestion.`, - Run: func(pass *analysis.Pass) (any, error) { - err := wrapper.run(pass) - if err != nil { - return nil, err - } - - return nil, nil - }, - }). - WithContextSetter(func(context *linter.Context) { - wrapper.init(context.Log, settings, replacer) - }). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} - -type goCriticWrapper struct { - settingsWrapper *settingsWrapper - sizes types.Sizes - once sync.Once -} - -func (w *goCriticWrapper) init(logger logutils.Log, settings *config.GoCriticSettings, replacer *strings.Replacer) { - if settings == nil { - return - } - - w.once.Do(func() { - err := checkers.InitEmbeddedRules() - if err != nil { - logger.Fatalf("%s: %v: setting an explicit GOROOT can fix this problem", linterName, err) - } - }) - - settingsWrapper := newSettingsWrapper(logger, settings, replacer) - - if err := settingsWrapper.Load(); err != nil { - logger.Fatalf("%s: invalid settings: %s", linterName, err) - } - - w.settingsWrapper = settingsWrapper -} - -func (w *goCriticWrapper) run(pass *analysis.Pass) error { - if w.settingsWrapper == nil { - return errors.New("the settings wrapper is nil") - } - - linterCtx := gocriticlinter.NewContext(pass.Fset, w.sizes) - - linterCtx.SetGoVersion(w.settingsWrapper.Go) - - enabledCheckers, err := w.buildEnabledCheckers(linterCtx) - if err != nil { - return err - } - - linterCtx.SetPackageInfo(pass.TypesInfo, pass.Pkg) - - needFileInfo := slices.ContainsFunc(enabledCheckers, func(c *gocriticlinter.Checker) bool { - // Related to https://github.com/go-critic/go-critic/blob/440ff466685b41e67d231a1c4a8f5e093374ee93/checkers/importShadow_checker.go#L23 - return strings.EqualFold(c.Info.Name, "importShadow") - }) - - for _, f := range pass.Files { - if needFileInfo { - // Related to https://github.com/go-critic/go-critic/blob/440ff466685b41e67d231a1c4a8f5e093374ee93/checkers/importShadow_checker.go#L23 - linterCtx.SetFileInfo(f.Name.Name, f) - } - - runOnFile(pass, f, enabledCheckers) - } - - return nil -} - -func (w *goCriticWrapper) buildEnabledCheckers(linterCtx *gocriticlinter.Context) ([]*gocriticlinter.Checker, error) { - allLowerCasedParams := w.settingsWrapper.GetLowerCasedParams() - - var enabledCheckers []*gocriticlinter.Checker - for _, info := range gocriticlinter.GetCheckersInfo() { - if !w.settingsWrapper.IsCheckEnabled(info.Name) { - continue - } - - err := w.settingsWrapper.setCheckerParams(info, allLowerCasedParams) - if err != nil { - return nil, err - } - - c, err := gocriticlinter.NewChecker(linterCtx, info) - if err != nil { - return nil, err - } - - enabledCheckers = append(enabledCheckers, c) - } - - return enabledCheckers, nil -} - -func runOnFile(pass *analysis.Pass, f *ast.File, checks []*gocriticlinter.Checker) { - for _, c := range checks { - // All checkers are expected to use *lint.Context - // as read-only structure, so no copying is required. - for _, warn := range c.Check(f) { - diag := analysis.Diagnostic{ - Pos: warn.Pos, - Category: c.Info.Name, - Message: fmt.Sprintf("%s: %s", c.Info.Name, warn.Text), - } - - if warn.HasQuickFix() { - diag.SuggestedFixes = []analysis.SuggestedFix{{ - TextEdits: []analysis.TextEdit{{ - Pos: warn.Suggestion.From, - End: warn.Suggestion.To, - NewText: warn.Suggestion.Replacement, - }}, - }} - } - - pass.Report(diag) - } - } -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gocritic/gocritic_settings.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gocritic/gocritic_settings.go deleted file mode 100644 index e3267eeec4..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gocritic/gocritic_settings.go +++ /dev/null @@ -1,431 +0,0 @@ -package gocritic - -import ( - "errors" - "fmt" - "maps" - "reflect" - "slices" - "strings" - - gocriticlinter "github.com/go-critic/go-critic/linter" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/logutils" -) - -type settingsWrapper struct { - *config.GoCriticSettings - - replacer *strings.Replacer - - logger logutils.Log - - allCheckers []*gocriticlinter.CheckerInfo - - allChecks goCriticChecks[struct{}] - allChecksByTag goCriticChecks[[]string] - allTagsSorted []string - inferredEnabledChecks goCriticChecks[struct{}] - - // *LowerCased fields are used for GoCriticSettings.SettingsPerCheck validation only. - - allChecksLowerCased goCriticChecks[struct{}] - inferredEnabledChecksLowerCased goCriticChecks[struct{}] -} - -func newSettingsWrapper(logger logutils.Log, settings *config.GoCriticSettings, replacer *strings.Replacer) *settingsWrapper { - allCheckers := gocriticlinter.GetCheckersInfo() - - allChecks := make(goCriticChecks[struct{}], len(allCheckers)) - allChecksLowerCased := make(goCriticChecks[struct{}], len(allCheckers)) - allChecksByTag := make(goCriticChecks[[]string]) - - for _, checker := range allCheckers { - allChecks[checker.Name] = struct{}{} - allChecksLowerCased[strings.ToLower(checker.Name)] = struct{}{} - - for _, tag := range checker.Tags { - allChecksByTag[tag] = append(allChecksByTag[tag], checker.Name) - } - } - - return &settingsWrapper{ - GoCriticSettings: settings, - replacer: replacer, - logger: logger, - - allCheckers: allCheckers, - allChecks: allChecks, - allChecksByTag: allChecksByTag, - allTagsSorted: slices.Sorted(maps.Keys(allChecksByTag)), - inferredEnabledChecks: make(goCriticChecks[struct{}]), - - allChecksLowerCased: allChecksLowerCased, - inferredEnabledChecksLowerCased: make(goCriticChecks[struct{}]), - } -} - -func (s *settingsWrapper) IsCheckEnabled(name string) bool { - return s.inferredEnabledChecks.has(name) -} - -func (s *settingsWrapper) GetLowerCasedParams() map[string]config.GoCriticCheckSettings { - return normalizeMap(s.SettingsPerCheck) -} - -func (s *settingsWrapper) Load() error { - s.inferEnabledChecks() - - // validate must be after inferEnabledChecks, not before. - // Because it uses gathered information about tags set and finally enabled checks. - return s.validate() -} - -func (s *settingsWrapper) inferEnabledChecks() { - s.debugChecksInitialState() - - enabledByDefaultChecks, disabledByDefaultChecks := s.buildEnabledAndDisabledByDefaultChecks() - - debugChecksListf(enabledByDefaultChecks, "Enabled by default") - debugChecksListf(disabledByDefaultChecks, "Disabled by default") - - var enabledChecks goCriticChecks[struct{}] - - switch { - case s.DisableAll: - // disable-all revokes the default settings. - enabledChecks = make(goCriticChecks[struct{}]) - - case s.EnableAll: - // enable-all revokes the default settings. - enabledChecks = make(goCriticChecks[struct{}], len(s.allCheckers)) - - for _, info := range s.allCheckers { - enabledChecks[info.Name] = struct{}{} - } - - default: - enabledChecks = make(goCriticChecks[struct{}], len(enabledByDefaultChecks)) - - for _, check := range enabledByDefaultChecks { - enabledChecks[check] = struct{}{} - } - } - - if len(s.EnabledTags) > 0 { - enabledFromTags := s.expandTagsToChecks(s.EnabledTags) - - debugChecksListf(enabledFromTags, "Enabled by config tags %s", s.EnabledTags) - - for _, check := range enabledFromTags { - enabledChecks[check] = struct{}{} - } - } - - if len(s.EnabledChecks) > 0 { - debugChecksListf(s.EnabledChecks, "Enabled by config") - - for _, check := range s.EnabledChecks { - if enabledChecks.has(check) { - s.logger.Warnf("%s: no need to enable check %q: it's already enabled", linterName, check) - continue - } - - enabledChecks[check] = struct{}{} - } - } - - if len(s.DisabledTags) > 0 { - disabledFromTags := s.expandTagsToChecks(s.DisabledTags) - - debugChecksListf(disabledFromTags, "Disabled by config tags %s", s.DisabledTags) - - for _, check := range disabledFromTags { - delete(enabledChecks, check) - } - } - - if len(s.DisabledChecks) > 0 { - debugChecksListf(s.DisabledChecks, "Disabled by config") - - for _, check := range s.DisabledChecks { - if !enabledChecks.has(check) { - s.logger.Warnf("%s: no need to disable check %q: it's already disabled", linterName, check) - continue - } - - delete(enabledChecks, check) - } - } - - s.inferredEnabledChecks = enabledChecks - s.inferredEnabledChecksLowerCased = normalizeMap(s.inferredEnabledChecks) - - s.debugChecksFinalState() -} - -func (s *settingsWrapper) buildEnabledAndDisabledByDefaultChecks() (enabled, disabled []string) { - for _, info := range s.allCheckers { - if isEnabledByDefaultGoCriticChecker(info) { - enabled = append(enabled, info.Name) - } else { - disabled = append(disabled, info.Name) - } - } - - return enabled, disabled -} - -func (s *settingsWrapper) expandTagsToChecks(tags []string) []string { - var checks []string - - for _, tag := range tags { - checks = append(checks, s.allChecksByTag[tag]...) - } - - return checks -} - -func (s *settingsWrapper) setCheckerParams( - info *gocriticlinter.CheckerInfo, - allLowerCasedParams map[string]config.GoCriticCheckSettings, -) error { - params := allLowerCasedParams[strings.ToLower(info.Name)] - if params == nil { // no config for this checker - return nil - } - - // To lowercase info param keys here because golangci-lint's config parser lowercases all strings. - infoParams := normalizeMap(info.Params) - for k, p := range params { - v, ok := infoParams[k] - if ok { - v.Value = s.normalizeCheckerParamsValue(p) - continue - } - - // param `k` isn't supported - if len(info.Params) == 0 { - return fmt.Errorf("checker %s config param %s doesn't exist: checker doesn't have params", - info.Name, k) - } - - return fmt.Errorf("checker %s config param %s doesn't exist, all existing: %s", - info.Name, k, slices.Sorted(maps.Keys(info.Params))) - } - - return nil -} - -func (s *settingsWrapper) debugChecksInitialState() { - if !isDebug { - return - } - - debugf("All gocritic existing tags and checks:") - - for _, tag := range s.allTagsSorted { - debugChecksListf(s.allChecksByTag[tag], " tag %q", tag) - } -} - -func (s *settingsWrapper) debugChecksFinalState() { - if !isDebug { - return - } - - var enabledChecks []string - var disabledChecks []string - - for _, checker := range s.allCheckers { - if s.IsCheckEnabled(checker.Name) { - enabledChecks = append(enabledChecks, checker.Name) - } else { - disabledChecks = append(disabledChecks, checker.Name) - } - } - - debugChecksListf(enabledChecks, "Final used") - - if len(disabledChecks) == 0 { - debugf("All checks are enabled") - } else { - debugChecksListf(disabledChecks, "Final not used") - } -} - -// normalizeCheckerParamsValue normalizes value types. -// go-critic asserts that CheckerParam.Value has some specific types, -// but the file parsers (TOML, YAML, JSON) don't create the same representation for raw type. -// then we have to convert value types into the expected value types. -// Maybe in the future, this kind of conversion will be done in go-critic itself. -func (s *settingsWrapper) normalizeCheckerParamsValue(p any) any { - rv := reflect.ValueOf(p) - - switch rv.Type().Kind() { - case reflect.Int64, reflect.Int32, reflect.Int16, reflect.Int8, reflect.Int: - return int(rv.Int()) - - case reflect.Bool: - return rv.Bool() - - case reflect.String: - // Perform variable substitution. - return s.replacer.Replace(rv.String()) - - default: - return p - } -} - -// validate tries to be consistent with (lintersdb.Validator).validateEnabledDisabledLintersConfig. -func (s *settingsWrapper) validate() error { - for _, v := range []func() error{ - s.validateOptionsCombinations, - s.validateCheckerTags, - s.validateCheckerNames, - s.validateDisabledAndEnabledAtOneMoment, - s.validateAtLeastOneCheckerEnabled, - } { - if err := v(); err != nil { - return err - } - } - return nil -} - -func (s *settingsWrapper) validateOptionsCombinations() error { - if s.EnableAll && s.DisableAll { - return errors.New("enable-all and disable-all options must not be combined") - } - - switch { - case s.EnableAll: - if len(s.EnabledTags) > 0 { - return errors.New("enable-all and enabled-tags options must not be combined") - } - - if len(s.EnabledChecks) > 0 { - return errors.New("enable-all and enabled-checks options must not be combined") - } - - case s.DisableAll: - if len(s.DisabledTags) > 0 { - return errors.New("disable-all and disabled-tags options must not be combined") - } - - if len(s.DisabledChecks) > 0 { - return errors.New("disable-all and disabled-checks options must not be combined") - } - - if len(s.EnabledTags) == 0 && len(s.EnabledChecks) == 0 { - return errors.New("all checks were disabled, but no one check was enabled: at least one must be enabled") - } - } - - return nil -} - -func (s *settingsWrapper) validateCheckerTags() error { - for _, tag := range s.EnabledTags { - if !s.allChecksByTag.has(tag) { - return fmt.Errorf("enabled tag %q doesn't exist, see %s's documentation", tag, linterName) - } - } - - for _, tag := range s.DisabledTags { - if !s.allChecksByTag.has(tag) { - return fmt.Errorf("disabled tag %q doesn't exist, see %s's documentation", tag, linterName) - } - } - - return nil -} - -func (s *settingsWrapper) validateCheckerNames() error { - for _, check := range s.EnabledChecks { - if !s.allChecks.has(check) { - return fmt.Errorf("enabled check %q doesn't exist, see %s's documentation", check, linterName) - } - } - - for _, check := range s.DisabledChecks { - if !s.allChecks.has(check) { - return fmt.Errorf("disabled check %q doesn't exist, see %s documentation", check, linterName) - } - } - - for check := range s.SettingsPerCheck { - lcName := strings.ToLower(check) - - if !s.allChecksLowerCased.has(lcName) { - return fmt.Errorf("invalid check settings: check %q doesn't exist, see %s documentation", check, linterName) - } - - if !s.inferredEnabledChecksLowerCased.has(lcName) { - s.logger.Warnf("%s: settings were provided for disabled check %q", check, linterName) - } - } - - return nil -} - -func (s *settingsWrapper) validateDisabledAndEnabledAtOneMoment() error { - for _, tag := range s.DisabledTags { - if slices.Contains(s.EnabledTags, tag) { - return fmt.Errorf("tag %q disabled and enabled at one moment", tag) - } - } - - for _, check := range s.DisabledChecks { - if slices.Contains(s.EnabledChecks, check) { - return fmt.Errorf("check %q disabled and enabled at one moment", check) - } - } - - return nil -} - -func (s *settingsWrapper) validateAtLeastOneCheckerEnabled() error { - if len(s.inferredEnabledChecks) == 0 { - return errors.New("eventually all checks were disabled: at least one must be enabled") - } - - return nil -} - -type goCriticChecks[T any] map[string]T - -func (m goCriticChecks[T]) has(name string) bool { - _, ok := m[name] - return ok -} - -func debugChecksListf(checks []string, format string, args ...any) { - if !isDebug { - return - } - - v := slices.Sorted(slices.Values(checks)) - - debugf("%s checks (%d): %s", fmt.Sprintf(format, args...), len(checks), strings.Join(v, ", ")) -} - -func normalizeMap[ValueT any](in map[string]ValueT) map[string]ValueT { - ret := make(map[string]ValueT, len(in)) - - for k, v := range in { - ret[strings.ToLower(k)] = v - } - - return ret -} - -func isEnabledByDefaultGoCriticChecker(info *gocriticlinter.CheckerInfo) bool { - // https://github.com/go-critic/go-critic/blob/5b67cfd487ae9fe058b4b19321901b3131810f65/cmd/gocritic/check.go#L342-L345 - return !info.HasTag(gocriticlinter.ExperimentalTag) && - !info.HasTag(gocriticlinter.OpinionatedTag) && - !info.HasTag(gocriticlinter.PerformanceTag) && - !info.HasTag(gocriticlinter.SecurityTag) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gocyclo/gocyclo.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gocyclo/gocyclo.go deleted file mode 100644 index de0374607c..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gocyclo/gocyclo.go +++ /dev/null @@ -1,72 +0,0 @@ -package gocyclo - -import ( - "fmt" - "sync" - - "github.com/fzipp/gocyclo" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/golinters/internal" - "github.com/golangci/golangci-lint/v2/pkg/lint/linter" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -const linterName = "gocyclo" - -func New(settings *config.GoCycloSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []*goanalysis.Issue - - return goanalysis. - NewLinterFromAnalyzer(&analysis.Analyzer{ - Name: linterName, - Doc: "Computes and checks the cyclomatic complexity of functions", - Run: func(pass *analysis.Pass) (any, error) { - issues := runGoCyclo(pass, settings) - - if len(issues) == 0 { - return nil, nil - } - - mu.Lock() - resIssues = append(resIssues, issues...) - mu.Unlock() - - return nil, nil - }, - }). - WithIssuesReporter(func(*linter.Context) []*goanalysis.Issue { - return resIssues - }). - WithLoadMode(goanalysis.LoadModeSyntax) -} - -func runGoCyclo(pass *analysis.Pass, settings *config.GoCycloSettings) []*goanalysis.Issue { - var stats gocyclo.Stats - for _, f := range pass.Files { - stats = gocyclo.AnalyzeASTFile(f, pass.Fset, stats) - } - if len(stats) == 0 { - return nil - } - - stats = stats.SortAndFilter(-1, settings.MinComplexity) - - issues := make([]*goanalysis.Issue, 0, len(stats)) - - for _, s := range stats { - text := fmt.Sprintf("cyclomatic complexity %d of func %s is high (> %d)", - s.Complexity, internal.FormatCode(s.FuncName), settings.MinComplexity) - - issues = append(issues, goanalysis.NewIssue(&result.Issue{ - Pos: s.Pos, - Text: text, - FromLinter: linterName, - }, pass)) - } - - return issues -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/godoclint/godoclint.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/godoclint/godoclint.go deleted file mode 100644 index 235909217f..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/godoclint/godoclint.go +++ /dev/null @@ -1,109 +0,0 @@ -package godoclint - -import ( - "errors" - "fmt" - "slices" - - glcompose "github.com/godoc-lint/godoc-lint/pkg/compose" - glconfig "github.com/godoc-lint/godoc-lint/pkg/config" - "github.com/godoc-lint/godoc-lint/pkg/model" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/golinters/internal" -) - -func New(settings *config.GodoclintSettings) *goanalysis.Linter { - var pcfg glconfig.PlainConfig - - if settings != nil { - err := checkSettings(settings) - if err != nil { - internal.LinterLogger.Fatalf("godoclint: %v", err) - } - - // The following options are explicitly ignored: they must be handled globally with exclusions or nolint directives. - // - Include - // - Exclude - - // The following options are explicitly ignored: these options cannot work as expected because the global configuration about tests. - // - Options.MaxLenIncludeTests - // - Options.PkgDocIncludeTests - // - Options.SinglePkgDocIncludeTests - // - Options.RequirePkgDocIncludeTests - // - Options.RequireDocIncludeTests - // - Options.StartWithNameIncludeTests - // - Options.NoUnusedLinkIncludeTests - - pcfg = glconfig.PlainConfig{ - Default: settings.Default, - Enable: settings.Enable, - Disable: settings.Disable, - Options: &glconfig.PlainRuleOptions{ - MaxLenLength: settings.Options.MaxLen.Length, - MaxLenIncludeTests: pointer(true), - PkgDocIncludeTests: pointer(false), - SinglePkgDocIncludeTests: pointer(true), - RequirePkgDocIncludeTests: pointer(false), - RequireDocIncludeTests: pointer(true), - RequireDocIgnoreExported: settings.Options.RequireDoc.IgnoreExported, - RequireDocIgnoreUnexported: settings.Options.RequireDoc.IgnoreUnexported, - StartWithNameIncludeTests: pointer(false), - StartWithNameIncludeUnexported: settings.Options.StartWithName.IncludeUnexported, - NoUnusedLinkIncludeTests: pointer(true), - }, - } - } - - composition := glcompose.Compose(glcompose.CompositionConfig{ - BaseDirPlainConfig: &pcfg, - ExitFunc: func(_ int, err error) { - internal.LinterLogger.Errorf("godoclint: %v", err) - }, - }) - - return goanalysis. - NewLinterFromAnalyzer(composition.Analyzer.GetAnalyzer()). - WithLoadMode(goanalysis.LoadModeSyntax) -} - -func checkSettings(settings *config.GodoclintSettings) error { - switch deref(settings.Default) { - case string(model.DefaultSetAll): - if len(settings.Enable) > 0 { - return errors.New("cannot use 'enable' with 'default=all'") - } - - case string(model.DefaultSetNone): - if len(settings.Disable) > 0 { - return errors.New("cannot use 'disable' with 'default=none'") - } - - default: - for _, rule := range settings.Enable { - if slices.Contains(settings.Disable, rule) { - return fmt.Errorf("a rule cannot be enabled and disabled at the same time: '%s'", rule) - } - } - - for _, rule := range settings.Disable { - if slices.Contains(settings.Enable, rule) { - return fmt.Errorf("a rule cannot be enabled and disabled at the same time: '%s'", rule) - } - } - } - - return nil -} - -func pointer[T any](v T) *T { return &v } - -func deref[T any](v *T) T { - if v == nil { - var zero T - return zero - } - - return *v -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/godot/godot.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/godot/godot.go deleted file mode 100644 index e83495128e..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/godot/godot.go +++ /dev/null @@ -1,76 +0,0 @@ -package godot - -import ( - "cmp" - - "github.com/tetafro/godot" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.GodotSettings) *goanalysis.Linter { - var dotSettings godot.Settings - - if settings != nil { - dotSettings = godot.Settings{ - Scope: godot.Scope(settings.Scope), - Exclude: settings.Exclude, - Period: settings.Period, - Capital: settings.Capital, - } - } - - dotSettings.Scope = cmp.Or(dotSettings.Scope, godot.DeclScope) - - return goanalysis. - NewLinterFromAnalyzer(&analysis.Analyzer{ - Name: "godot", - Doc: "Check if comments end in a period", - Run: func(pass *analysis.Pass) (any, error) { - err := runGodot(pass, dotSettings) - if err != nil { - return nil, err - } - - return nil, nil - }, - }). - WithLoadMode(goanalysis.LoadModeSyntax) -} - -func runGodot(pass *analysis.Pass, settings godot.Settings) error { - for _, file := range pass.Files { - iss, err := godot.Run(file, pass.Fset, settings) - if err != nil { - return err - } - - if len(iss) == 0 { - continue - } - - f := pass.Fset.File(file.Pos()) - - for _, i := range iss { - start := f.Pos(i.Pos.Offset) - end := goanalysis.EndOfLinePos(f, i.Pos.Line) - - pass.Report(analysis.Diagnostic{ - Pos: start, - End: end, - Message: i.Message, - SuggestedFixes: []analysis.SuggestedFix{{ - TextEdits: []analysis.TextEdit{{ - Pos: start, - End: end, - NewText: []byte(i.Replacement), - }}, - }}, - }) - } - } - - return nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/godox/godox.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/godox/godox.go deleted file mode 100644 index e05fc123a8..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/godox/godox.go +++ /dev/null @@ -1,60 +0,0 @@ -package godox - -import ( - "go/token" - "strings" - - "github.com/matoous/godox" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.GodoxSettings) *goanalysis.Linter { - return goanalysis. - NewLinterFromAnalyzer(&analysis.Analyzer{ - Name: "godox", - Doc: "Detects usage of FIXME, TODO and other keywords inside comments", - Run: func(pass *analysis.Pass) (any, error) { - return run(pass, settings), nil - }, - }). - WithLoadMode(goanalysis.LoadModeSyntax) -} - -func run(pass *analysis.Pass, settings *config.GodoxSettings) error { - for _, file := range pass.Files { - position, isGoFile := goanalysis.GetGoFilePosition(pass, file) - if !isGoFile { - continue - } - - messages, err := godox.Run(file, pass.Fset, settings.Keywords...) - if err != nil { - return err - } - - if len(messages) == 0 { - continue - } - - nonAdjPosition := pass.Fset.PositionFor(file.Pos(), false) - - ft := pass.Fset.File(file.Pos()) - - for _, i := range messages { - msg := strings.TrimRight(i.Message, "\n") - - // https://github.com/matoous/godox/blob/1d6ac9d899726279072e1c4d2b10f1eb52f22878/godox.go#L56 - index := strings.Index(msg, "Line contains") - - pass.Report(analysis.Diagnostic{ - Pos: ft.LineStart(goanalysis.AdjustPos(i.Pos.Line, nonAdjPosition.Line, position.Line)) + token.Pos(i.Pos.Column), - Message: msg[index:], - }) - } - } - - return nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gofmt/gofmt.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gofmt/gofmt.go deleted file mode 100644 index 04de51efc0..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gofmt/gofmt.go +++ /dev/null @@ -1,21 +0,0 @@ -package gofmt - -import ( - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/goformatters" - gofmtbase "github.com/golangci/golangci-lint/v2/pkg/goformatters/gofmt" - "github.com/golangci/golangci-lint/v2/pkg/golinters/internal" -) - -func New(settings *config.GoFmtSettings) *goanalysis.Linter { - return goanalysis. - NewLinterFromAnalyzer( - goformatters.NewAnalyzer( - internal.LinterLogger.Child(gofmtbase.Name), - "Check if the code is formatted according to 'gofmt' command.", - gofmtbase.New(settings), - ), - ). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gofumpt/gofumpt.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gofumpt/gofumpt.go deleted file mode 100644 index 1ee7c833a3..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gofumpt/gofumpt.go +++ /dev/null @@ -1,21 +0,0 @@ -package gofumpt - -import ( - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/goformatters" - gofumptbase "github.com/golangci/golangci-lint/v2/pkg/goformatters/gofumpt" - "github.com/golangci/golangci-lint/v2/pkg/golinters/internal" -) - -func New(settings *config.GoFumptSettings) *goanalysis.Linter { - return goanalysis. - NewLinterFromAnalyzer( - goformatters.NewAnalyzer( - internal.LinterLogger.Child(gofumptbase.Name), - "Check if code and import statements are formatted, with additional rules.", - gofumptbase.New(settings, settings.LangVersion), - ), - ). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/goheader/goheader.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/goheader/goheader.go deleted file mode 100644 index 0634dbd428..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/goheader/goheader.go +++ /dev/null @@ -1,126 +0,0 @@ -package goheader - -import ( - "go/token" - "strings" - - goheader "github.com/denis-tingaikin/go-header" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -const linterName = "goheader" - -func New(settings *config.GoHeaderSettings, replacer *strings.Replacer) *goanalysis.Linter { - conf := &goheader.Configuration{} - if settings != nil { - conf = &goheader.Configuration{ - Values: settings.Values, - Template: settings.Template, - TemplatePath: replacer.Replace(settings.TemplatePath), - } - } - - return goanalysis. - NewLinterFromAnalyzer(&analysis.Analyzer{ - Name: linterName, - Doc: "Check if file header matches to pattern", - Run: func(pass *analysis.Pass) (any, error) { - err := runGoHeader(pass, conf) - if err != nil { - return nil, err - } - - return nil, nil - }, - }). - WithLoadMode(goanalysis.LoadModeSyntax) -} - -func runGoHeader(pass *analysis.Pass, conf *goheader.Configuration) error { - if conf.TemplatePath == "" && conf.Template == "" { - // User did not pass template, so then do not run go-header linter - return nil - } - - template, err := conf.GetTemplate() - if err != nil { - return err - } - - values, err := conf.GetValues() - if err != nil { - return err - } - - a := goheader.New(goheader.WithTemplate(template), goheader.WithValues(values)) - - for _, file := range pass.Files { - position, isGoFile := goanalysis.GetGoFilePosition(pass, file) - if !isGoFile { - continue - } - - issue := a.Analyze(&goheader.Target{File: file, Path: position.Filename}) - if issue == nil { - continue - } - - f := pass.Fset.File(file.Pos()) - - commentLine := 1 - var offset int - - // Inspired by https://github.com/denis-tingaikin/go-header/blob/4c75a6a2332f025705325d6c71fff4616aedf48f/analyzer.go#L85-L92 - if len(file.Comments) > 0 && file.Comments[0].Pos() < file.Package { - if !strings.HasPrefix(file.Comments[0].List[0].Text, "/*") { - // When the comment is "//" there is a one character offset. - offset = 1 - } - commentLine = goanalysis.GetFilePositionFor(pass.Fset, file.Comments[0].Pos()).Line - } - - // Skip issues related to build directives. - // https://github.com/denis-tingaikin/go-header/issues/18 - if issue.Location().Position-offset < 0 { - continue - } - - diag := analysis.Diagnostic{ - Pos: f.LineStart(issue.Location().Line+1) + token.Pos(issue.Location().Position-offset), // The position of the first divergence. - Message: issue.Message(), - } - - if fix := issue.Fix(); fix != nil { - current := len(fix.Actual) - for _, s := range fix.Actual { - current += len(s) - } - - start := f.LineStart(commentLine) - - end := start + token.Pos(current) - - header := strings.Join(fix.Expected, "\n") + "\n" - - // Adds an extra line between the package and the header. - if end == file.Package { - header += "\n" - } - - diag.SuggestedFixes = []analysis.SuggestedFix{{ - TextEdits: []analysis.TextEdit{{ - Pos: start, - End: end, - NewText: []byte(header), - }}, - }} - } - - pass.Report(diag) - } - - return nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/goimports/goimports.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/goimports/goimports.go deleted file mode 100644 index b3b9b5800b..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/goimports/goimports.go +++ /dev/null @@ -1,21 +0,0 @@ -package goimports - -import ( - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/goformatters" - goimportsbase "github.com/golangci/golangci-lint/v2/pkg/goformatters/goimports" - "github.com/golangci/golangci-lint/v2/pkg/golinters/internal" -) - -func New(settings *config.GoImportsSettings) *goanalysis.Linter { - return goanalysis. - NewLinterFromAnalyzer( - goformatters.NewAnalyzer( - internal.LinterLogger.Child(goimportsbase.Name), - "Checks if the code and import statements are formatted according to the 'goimports' command.", - goimportsbase.New(settings), - ), - ). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/golines/golines.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/golines/golines.go deleted file mode 100644 index 0a32971dee..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/golines/golines.go +++ /dev/null @@ -1,21 +0,0 @@ -package golines - -import ( - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/goformatters" - golinesbase "github.com/golangci/golangci-lint/v2/pkg/goformatters/golines" - "github.com/golangci/golangci-lint/v2/pkg/golinters/internal" -) - -func New(settings *config.GoLinesSettings) *goanalysis.Linter { - return goanalysis. - NewLinterFromAnalyzer( - goformatters.NewAnalyzer( - internal.LinterLogger.Child(golinesbase.Name), - "Checks if code is formatted, and fixes long lines", - golinesbase.New(settings), - ), - ). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gomoddirectives/gomoddirectives.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gomoddirectives/gomoddirectives.go deleted file mode 100644 index dd6656fb6c..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gomoddirectives/gomoddirectives.go +++ /dev/null @@ -1,86 +0,0 @@ -package gomoddirectives - -import ( - "regexp" - "sync" - - "github.com/ldez/gomoddirectives" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/golinters/internal" - "github.com/golangci/golangci-lint/v2/pkg/lint/linter" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -const linterName = "gomoddirectives" - -func New(settings *config.GoModDirectivesSettings) *goanalysis.Linter { - var issues []*goanalysis.Issue - var once sync.Once - - var opts gomoddirectives.Options - if settings != nil { - opts.ReplaceAllowLocal = settings.ReplaceLocal - opts.ReplaceAllowList = settings.ReplaceAllowList - opts.RetractAllowNoExplanation = settings.RetractAllowNoExplanation - opts.ExcludeForbidden = settings.ExcludeForbidden - opts.ToolchainForbidden = settings.ToolchainForbidden - opts.ToolForbidden = settings.ToolForbidden - opts.GoDebugForbidden = settings.GoDebugForbidden - - if settings.ToolchainPattern != "" { - exp, err := regexp.Compile(settings.ToolchainPattern) - if err != nil { - internal.LinterLogger.Fatalf("%s: invalid toolchain pattern: %v", linterName, err) - } else { - opts.ToolchainPattern = exp - } - } - - if settings.GoVersionPattern != "" { - exp, err := regexp.Compile(settings.GoVersionPattern) - if err != nil { - internal.LinterLogger.Fatalf("%s: invalid Go version pattern: %v", linterName, err) - } else { - opts.GoVersionPattern = exp - } - } - } - - analyzer := &analysis.Analyzer{ - Name: linterName, - Doc: "Manage the use of 'replace', 'retract', and 'excludes' directives in go.mod.", - Run: goanalysis.DummyRun, - } - - return goanalysis. - NewLinterFromAnalyzer(analyzer). - WithContextSetter(func(lintCtx *linter.Context) { - analyzer.Run = func(pass *analysis.Pass) (any, error) { - once.Do(func() { - results, err := gomoddirectives.AnalyzePass(pass, opts) - if err != nil { - lintCtx.Log.Warnf("running %s failed: %s: "+ - "if you are not using go modules it is suggested to disable this linter", linterName, err) - return - } - - for _, p := range results { - issues = append(issues, goanalysis.NewIssue(&result.Issue{ - FromLinter: linterName, - Pos: p.Start, - Text: p.Reason, - }, pass)) - } - }) - - return nil, nil - } - }). - WithIssuesReporter(func(*linter.Context) []*goanalysis.Issue { - return issues - }). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gomodguard/gomodguard.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gomodguard/gomodguard.go deleted file mode 100644 index 7d16f57b3a..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gomodguard/gomodguard.go +++ /dev/null @@ -1,89 +0,0 @@ -package gomodguard - -import ( - "sync" - - "github.com/ryancurrah/gomodguard" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/golinters/internal" - "github.com/golangci/golangci-lint/v2/pkg/lint/linter" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -const linterName = "gomodguard" - -func New(settings *config.GoModGuardSettings) *goanalysis.Linter { - var issues []*goanalysis.Issue - var mu sync.Mutex - - processorCfg := &gomodguard.Configuration{} - if settings != nil { - processorCfg.Allowed.Modules = settings.Allowed.Modules - processorCfg.Allowed.Domains = settings.Allowed.Domains - processorCfg.Blocked.LocalReplaceDirectives = settings.Blocked.LocalReplaceDirectives - - for n := range settings.Blocked.Modules { - for k, v := range settings.Blocked.Modules[n] { - m := map[string]gomodguard.BlockedModule{k: { - Recommendations: v.Recommendations, - Reason: v.Reason, - }} - processorCfg.Blocked.Modules = append(processorCfg.Blocked.Modules, m) - break - } - } - - for n := range settings.Blocked.Versions { - for k, v := range settings.Blocked.Versions[n] { - m := map[string]gomodguard.BlockedVersion{k: { - Version: v.Version, - Reason: v.Reason, - }} - processorCfg.Blocked.Versions = append(processorCfg.Blocked.Versions, m) - break - } - } - } - - analyzer := &analysis.Analyzer{ - Name: linterName, - Doc: "Allow and blocklist linter for direct Go module dependencies. " + - "This is different from depguard where there are different block " + - "types for example version constraints and module recommendations.", - Run: goanalysis.DummyRun, - } - - return goanalysis.NewLinterFromAnalyzer(analyzer). - WithContextSetter(func(lintCtx *linter.Context) { - processor, err := gomodguard.NewProcessor(processorCfg) - if err != nil { - lintCtx.Log.Warnf("running gomodguard failed: %s: if you are not using go modules "+ - "it is suggested to disable this linter", err) - return - } - - analyzer.Run = func(pass *analysis.Pass) (any, error) { - gomodguardIssues := processor.ProcessFiles(internal.GetGoFileNames(pass)) - - mu.Lock() - defer mu.Unlock() - - for _, gomodguardIssue := range gomodguardIssues { - issues = append(issues, goanalysis.NewIssue(&result.Issue{ - FromLinter: linterName, - Pos: gomodguardIssue.Position, - Text: gomodguardIssue.Reason, - }, pass)) - } - - return nil, nil - } - }). - WithIssuesReporter(func(*linter.Context) []*goanalysis.Issue { - return issues - }). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/goprintffuncname/goprintffuncname.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/goprintffuncname/goprintffuncname.go deleted file mode 100644 index a56dce8e05..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/goprintffuncname/goprintffuncname.go +++ /dev/null @@ -1,13 +0,0 @@ -package goprintffuncname - -import ( - "github.com/golangci/go-printf-func-name/pkg/analyzer" - - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - return goanalysis. - NewLinterFromAnalyzer(analyzer.Analyzer). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gosec/gosec.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gosec/gosec.go deleted file mode 100644 index 66d229295a..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gosec/gosec.go +++ /dev/null @@ -1,254 +0,0 @@ -package gosec - -import ( - "fmt" - "go/token" - "io" - "log" - "strconv" - "strings" - "sync" - - "github.com/securego/gosec/v2" - "github.com/securego/gosec/v2/analyzers" - "github.com/securego/gosec/v2/issue" - "github.com/securego/gosec/v2/rules" - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/packages" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/lint/linter" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -const linterName = "gosec" - -func New(settings *config.GoSecSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []*goanalysis.Issue - - conf := gosec.NewConfig() - - var ruleFilters []rules.RuleFilter - var analyzerFilters []analyzers.AnalyzerFilter - if settings != nil { - // TODO(ldez) to remove when the problem will be fixed by gosec. - // https://github.com/securego/gosec/issues/1211 - // https://github.com/securego/gosec/issues/1209 - settings.Excludes = append(settings.Excludes, "G407") - - ruleFilters = createRuleFilters(settings.Includes, settings.Excludes) - analyzerFilters = createAnalyzerFilters(settings.Includes, settings.Excludes) - conf = toGosecConfig(settings) - } - - logger := log.New(io.Discard, "", 0) - - ruleDefinitions := rules.Generate(false, ruleFilters...) - analyzerDefinitions := analyzers.Generate(false, analyzerFilters...) - - analyzer := &analysis.Analyzer{ - Name: linterName, - Doc: "Inspects source code for security problems", - Run: goanalysis.DummyRun, - } - - return goanalysis. - NewLinterFromAnalyzer(analyzer). - WithContextSetter(func(lintCtx *linter.Context) { - analyzer.Run = func(pass *analysis.Pass) (any, error) { - // The `gosecAnalyzer` is here because of concurrency issue. - gosecAnalyzer := gosec.NewAnalyzer(conf, true, false, false, settings.Concurrency, logger) - - gosecAnalyzer.LoadRules(ruleDefinitions.RulesInfo()) - gosecAnalyzer.LoadAnalyzers(analyzerDefinitions.AnalyzersInfo()) - - issues := runGoSec(lintCtx, pass, settings, gosecAnalyzer) - - mu.Lock() - resIssues = append(resIssues, issues...) - mu.Unlock() - - return nil, nil - } - }). - WithIssuesReporter(func(*linter.Context) []*goanalysis.Issue { - return resIssues - }). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} - -func runGoSec(lintCtx *linter.Context, pass *analysis.Pass, settings *config.GoSecSettings, analyzer *gosec.Analyzer) []*goanalysis.Issue { - pkg := &packages.Package{ - Fset: pass.Fset, - Syntax: pass.Files, - Types: pass.Pkg, - TypesInfo: pass.TypesInfo, - } - - analyzer.CheckRules(pkg) - analyzer.CheckAnalyzers(pkg) - - secIssues, _, _ := analyzer.Report() - if len(secIssues) == 0 { - return nil - } - - severity, err := convertToScore(settings.Severity) - if err != nil { - lintCtx.Log.Warnf("The provided severity %v", err) - } - - confidence, err := convertToScore(settings.Confidence) - if err != nil { - lintCtx.Log.Warnf("The provided confidence %v", err) - } - - secIssues = filterIssues(secIssues, severity, confidence) - - issues := make([]*goanalysis.Issue, 0, len(secIssues)) - for _, i := range secIssues { - text := fmt.Sprintf("%s: %s", i.RuleID, i.What) - - var r *result.Range - - line, err := strconv.Atoi(i.Line) - if err != nil { - r = &result.Range{} - if n, rerr := fmt.Sscanf(i.Line, "%d-%d", &r.From, &r.To); rerr != nil || n != 2 { - lintCtx.Log.Warnf("Can't convert gosec line number %q of %v to int: %s", i.Line, i, err) - continue - } - line = r.From - } - - column, err := strconv.Atoi(i.Col) - if err != nil { - lintCtx.Log.Warnf("Can't convert gosec column number %q of %v to int: %s", i.Col, i, err) - continue - } - - issues = append(issues, goanalysis.NewIssue(&result.Issue{ - Severity: convertScoreToString(i.Severity), - Pos: token.Position{ - Filename: i.File, - Line: line, - Column: column, - }, - Text: text, - LineRange: r, - FromLinter: linterName, - }, pass)) - } - - return issues -} - -func toGosecConfig(settings *config.GoSecSettings) gosec.Config { - conf := gosec.NewConfig() - - for k, v := range settings.Config { - if k == gosec.Globals { - convertGosecGlobals(v, conf) - continue - } - - // Uses ToUpper because the parsing of the map's key change the key to lowercase. - // The value is not impacted by that: the case is respected. - conf.Set(strings.ToUpper(k), v) - } - - return conf -} - -func convertScoreToString(score issue.Score) string { - switch score { - case issue.Low: - return "low" - case issue.Medium: - return "medium" - case issue.High: - return "high" - default: - return "" - } -} - -// based on https://github.com/securego/gosec/blob/47bfd4eb6fc7395940933388550b547538b4c946/config.go#L52-L62 -func convertGosecGlobals(globalOptionFromConfig any, conf gosec.Config) { - globalOptionMap, ok := globalOptionFromConfig.(map[string]any) - if !ok { - return - } - - for k, v := range globalOptionMap { - option := gosec.GlobalOption(k) - - // Set nosec global option only if the value is true - // https://github.com/securego/gosec/blob/v2.21.4/analyzer.go#L572 - if option == gosec.Nosec && v == false { - continue - } - - conf.SetGlobal(option, fmt.Sprintf("%v", v)) - } -} - -// based on https://github.com/securego/gosec/blob/81cda2f91fbe1bf4735feb55febcae03e697a92b/cmd/gosec/main.go#L258-L275 -func createAnalyzerFilters(includes, excludes []string) []analyzers.AnalyzerFilter { - var filters []analyzers.AnalyzerFilter - - if len(includes) > 0 { - filters = append(filters, analyzers.NewAnalyzerFilter(false, includes...)) - } - - if len(excludes) > 0 { - filters = append(filters, analyzers.NewAnalyzerFilter(true, excludes...)) - } - - return filters -} - -// based on https://github.com/securego/gosec/blob/569328eade2ccbad4ce2d0f21ee158ab5356a5cf/cmd/gosec/main.go#L170-L188 -func createRuleFilters(includes, excludes []string) []rules.RuleFilter { - var filters []rules.RuleFilter - - if len(includes) > 0 { - filters = append(filters, rules.NewRuleFilter(false, includes...)) - } - - if len(excludes) > 0 { - filters = append(filters, rules.NewRuleFilter(true, excludes...)) - } - - return filters -} - -// code borrowed from https://github.com/securego/gosec/blob/69213955dacfd560562e780f723486ef1ca6d486/cmd/gosec/main.go#L250-L262 -func convertToScore(str string) (issue.Score, error) { - str = strings.ToLower(str) - switch str { - case "", "low": - return issue.Low, nil - case "medium": - return issue.Medium, nil - case "high": - return issue.High, nil - default: - return issue.Low, fmt.Errorf("'%s' is invalid, use low instead. Valid options: low, medium, high", str) - } -} - -// code borrowed from https://github.com/securego/gosec/blob/69213955dacfd560562e780f723486ef1ca6d486/cmd/gosec/main.go#L264-L276 -func filterIssues(issues []*issue.Issue, severity, confidence issue.Score) []*issue.Issue { - res := make([]*issue.Issue, 0) - - for _, i := range issues { - if i.Severity >= severity && i.Confidence >= confidence { - res = append(res, i) - } - } - - return res -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gosmopolitan/gosmopolitan.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gosmopolitan/gosmopolitan.go deleted file mode 100644 index 76261abe14..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/gosmopolitan/gosmopolitan.go +++ /dev/null @@ -1,30 +0,0 @@ -package gosmopolitan - -import ( - "strings" - - "github.com/xen0n/gosmopolitan" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.GosmopolitanSettings) *goanalysis.Linter { - var cfg map[string]any - - if settings != nil { - cfg = map[string]any{ - "allowtimelocal": settings.AllowTimeLocal, - "escapehatches": strings.Join(settings.EscapeHatches, ","), - "watchforscripts": strings.Join(settings.WatchForScripts, ","), - - // Should be managed with `linters.exclusions.rules`. - "lookattests": true, - } - } - - return goanalysis. - NewLinterFromAnalyzer(gosmopolitan.NewAnalyzer()). - WithConfig(cfg). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/govet/govet.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/govet/govet.go deleted file mode 100644 index 7755e4ec26..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/govet/govet.go +++ /dev/null @@ -1,229 +0,0 @@ -package govet - -import ( - "slices" - "strings" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/appends" - "golang.org/x/tools/go/analysis/passes/asmdecl" - "golang.org/x/tools/go/analysis/passes/assign" - "golang.org/x/tools/go/analysis/passes/atomic" - "golang.org/x/tools/go/analysis/passes/atomicalign" - "golang.org/x/tools/go/analysis/passes/bools" - _ "golang.org/x/tools/go/analysis/passes/buildssa" // unused, internal analyzer - "golang.org/x/tools/go/analysis/passes/buildtag" - "golang.org/x/tools/go/analysis/passes/cgocall" - "golang.org/x/tools/go/analysis/passes/composite" - "golang.org/x/tools/go/analysis/passes/copylock" - _ "golang.org/x/tools/go/analysis/passes/ctrlflow" // unused, internal analyzer - "golang.org/x/tools/go/analysis/passes/deepequalerrors" - "golang.org/x/tools/go/analysis/passes/defers" - "golang.org/x/tools/go/analysis/passes/directive" - "golang.org/x/tools/go/analysis/passes/errorsas" - "golang.org/x/tools/go/analysis/passes/fieldalignment" - "golang.org/x/tools/go/analysis/passes/findcall" - "golang.org/x/tools/go/analysis/passes/framepointer" - "golang.org/x/tools/go/analysis/passes/hostport" - "golang.org/x/tools/go/analysis/passes/httpmux" - "golang.org/x/tools/go/analysis/passes/httpresponse" - "golang.org/x/tools/go/analysis/passes/ifaceassert" - _ "golang.org/x/tools/go/analysis/passes/inspect" // unused internal analyzer - "golang.org/x/tools/go/analysis/passes/loopclosure" - "golang.org/x/tools/go/analysis/passes/lostcancel" - "golang.org/x/tools/go/analysis/passes/nilfunc" - "golang.org/x/tools/go/analysis/passes/nilness" - _ "golang.org/x/tools/go/analysis/passes/pkgfact" // unused, internal analyzer - "golang.org/x/tools/go/analysis/passes/printf" - "golang.org/x/tools/go/analysis/passes/reflectvaluecompare" - "golang.org/x/tools/go/analysis/passes/shadow" - "golang.org/x/tools/go/analysis/passes/shift" - "golang.org/x/tools/go/analysis/passes/sigchanyzer" - "golang.org/x/tools/go/analysis/passes/slog" - "golang.org/x/tools/go/analysis/passes/sortslice" - "golang.org/x/tools/go/analysis/passes/stdmethods" - "golang.org/x/tools/go/analysis/passes/stdversion" - "golang.org/x/tools/go/analysis/passes/stringintconv" - "golang.org/x/tools/go/analysis/passes/structtag" - "golang.org/x/tools/go/analysis/passes/testinggoroutine" - "golang.org/x/tools/go/analysis/passes/tests" - "golang.org/x/tools/go/analysis/passes/timeformat" - "golang.org/x/tools/go/analysis/passes/unmarshal" - "golang.org/x/tools/go/analysis/passes/unreachable" - "golang.org/x/tools/go/analysis/passes/unsafeptr" - "golang.org/x/tools/go/analysis/passes/unusedresult" - "golang.org/x/tools/go/analysis/passes/unusedwrite" - "golang.org/x/tools/go/analysis/passes/waitgroup" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/logutils" -) - -var ( - allAnalyzers = []*analysis.Analyzer{ - appends.Analyzer, - asmdecl.Analyzer, - assign.Analyzer, - atomic.Analyzer, - atomicalign.Analyzer, - bools.Analyzer, - buildtag.Analyzer, - cgocall.Analyzer, - composite.Analyzer, - copylock.Analyzer, - deepequalerrors.Analyzer, - defers.Analyzer, - directive.Analyzer, - errorsas.Analyzer, - fieldalignment.Analyzer, - findcall.Analyzer, - framepointer.Analyzer, - hostport.Analyzer, - httpmux.Analyzer, - httpresponse.Analyzer, - ifaceassert.Analyzer, - loopclosure.Analyzer, - lostcancel.Analyzer, - nilfunc.Analyzer, - nilness.Analyzer, - printf.Analyzer, - reflectvaluecompare.Analyzer, - shadow.Analyzer, - shift.Analyzer, - sigchanyzer.Analyzer, - slog.Analyzer, - sortslice.Analyzer, - stdmethods.Analyzer, - stdversion.Analyzer, - stringintconv.Analyzer, - structtag.Analyzer, - testinggoroutine.Analyzer, - tests.Analyzer, - timeformat.Analyzer, - unmarshal.Analyzer, - unreachable.Analyzer, - unsafeptr.Analyzer, - unusedresult.Analyzer, - unusedwrite.Analyzer, - waitgroup.Analyzer, - } - - // https://github.com/golang/go/blob/go1.25.2/src/cmd/vet/main.go#L57-L91 - defaultAnalyzers = []*analysis.Analyzer{ - appends.Analyzer, - asmdecl.Analyzer, - assign.Analyzer, - atomic.Analyzer, - bools.Analyzer, - buildtag.Analyzer, - cgocall.Analyzer, - composite.Analyzer, - copylock.Analyzer, - defers.Analyzer, - directive.Analyzer, - errorsas.Analyzer, - framepointer.Analyzer, - hostport.Analyzer, - httpresponse.Analyzer, - ifaceassert.Analyzer, - loopclosure.Analyzer, - lostcancel.Analyzer, - nilfunc.Analyzer, - printf.Analyzer, - shift.Analyzer, - sigchanyzer.Analyzer, - slog.Analyzer, - stdmethods.Analyzer, - stdversion.Analyzer, - stringintconv.Analyzer, - structtag.Analyzer, - testinggoroutine.Analyzer, - tests.Analyzer, - timeformat.Analyzer, - unmarshal.Analyzer, - unreachable.Analyzer, - unsafeptr.Analyzer, - unusedresult.Analyzer, - waitgroup.Analyzer, - } -) - -var ( - debugf = logutils.Debug(logutils.DebugKeyGovet) - isDebug = logutils.HaveDebugTag(logutils.DebugKeyGovet) -) - -func New(settings *config.GovetSettings) *goanalysis.Linter { - var conf map[string]map[string]any - if settings != nil { - conf = settings.Settings - } - - return goanalysis.NewLinter( - "govet", - "Vet examines Go source code and reports suspicious constructs. "+ - "It is roughly the same as 'go vet' and uses its passes.", - analyzersFromConfig(settings), - conf, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} - -func analyzersFromConfig(settings *config.GovetSettings) []*analysis.Analyzer { - logAnalyzers("All available analyzers", allAnalyzers) - logAnalyzers("Default analyzers", defaultAnalyzers) - - if settings == nil { - return defaultAnalyzers - } - - var enabledAnalyzers []*analysis.Analyzer - for _, a := range allAnalyzers { - if isAnalyzerEnabled(a.Name, settings, defaultAnalyzers) { - enabledAnalyzers = append(enabledAnalyzers, a) - } - } - - logAnalyzers("Enabled by config analyzers", enabledAnalyzers) - - return enabledAnalyzers -} - -func isAnalyzerEnabled(name string, cfg *config.GovetSettings, defaultAnalyzers []*analysis.Analyzer) bool { - // TODO(ldez) remove loopclosure when go1.24 - if name == loopclosure.Analyzer.Name && config.IsGoGreaterThanOrEqual(cfg.Go, "1.22") { - return false - } - - switch { - case cfg.EnableAll: - return !slices.Contains(cfg.Disable, name) - - case slices.Contains(cfg.Enable, name): - return true - - case slices.Contains(cfg.Disable, name): - return false - - case cfg.DisableAll: - return false - - default: - return slices.ContainsFunc(defaultAnalyzers, func(a *analysis.Analyzer) bool { return a.Name == name }) - } -} - -func logAnalyzers(message string, analyzers []*analysis.Analyzer) { - if !isDebug { - return - } - - analyzerNames := make([]string, 0, len(analyzers)) - for _, a := range analyzers { - analyzerNames = append(analyzerNames, a.Name) - } - - slices.Sort(analyzerNames) - - debugf("%s (%d): %s", message, len(analyzerNames), strings.Join(analyzerNames, ", ")) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/grouper/grouper.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/grouper/grouper.go deleted file mode 100644 index ed3601617d..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/grouper/grouper.go +++ /dev/null @@ -1,30 +0,0 @@ -package grouper - -import ( - grouper "github.com/leonklingele/grouper/pkg/analyzer" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.GrouperSettings) *goanalysis.Linter { - var cfg map[string]any - - if settings != nil { - cfg = map[string]any{ - "const-require-single-const": settings.ConstRequireSingleConst, - "const-require-grouping": settings.ConstRequireGrouping, - "import-require-single-import": settings.ImportRequireSingleImport, - "import-require-grouping": settings.ImportRequireGrouping, - "type-require-single-type": settings.TypeRequireSingleType, - "type-require-grouping": settings.TypeRequireGrouping, - "var-require-single-var": settings.VarRequireSingleVar, - "var-require-grouping": settings.VarRequireGrouping, - } - } - return goanalysis. - NewLinterFromAnalyzer(grouper.New()). - WithDesc("Analyze expression groups."). - WithConfig(cfg). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/iface/iface.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/iface/iface.go deleted file mode 100644 index 0a4a38abc9..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/iface/iface.go +++ /dev/null @@ -1,59 +0,0 @@ -package iface - -import ( - "slices" - - "github.com/uudashr/iface/identical" - "github.com/uudashr/iface/opaque" - "github.com/uudashr/iface/unexported" - "github.com/uudashr/iface/unused" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.IfaceSettings) *goanalysis.Linter { - var conf map[string]map[string]any - if settings != nil { - conf = settings.Settings - } - - return goanalysis.NewLinter( - "iface", - "Detect the incorrect use of interfaces, helping developers avoid interface pollution.", - analyzersFromSettings(settings), - conf, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} - -func analyzersFromSettings(settings *config.IfaceSettings) []*analysis.Analyzer { - allAnalyzers := map[string]*analysis.Analyzer{ - "identical": identical.Analyzer, - "unused": unused.Analyzer, - "opaque": opaque.Analyzer, - "unexported": unexported.Analyzer, - } - - if settings == nil || len(settings.Enable) == 0 { - // Default enable `identical` analyzer only - return []*analysis.Analyzer{identical.Analyzer} - } - - var analyzers []*analysis.Analyzer - for _, name := range uniqueNames(settings.Enable) { - if _, ok := allAnalyzers[name]; !ok { - // skip unknown analyzer - continue - } - - analyzers = append(analyzers, allAnalyzers[name]) - } - - return analyzers -} - -func uniqueNames(names []string) []string { - slices.Sort(names) - return slices.Compact(names) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/importas/importas.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/importas/importas.go deleted file mode 100644 index fa7a54300e..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/importas/importas.go +++ /dev/null @@ -1,67 +0,0 @@ -package importas - -import ( - "fmt" - "strconv" - "strings" - - "github.com/julz/importas" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/lint/linter" -) - -func New(settings *config.ImportAsSettings) *goanalysis.Linter { - analyzer := importas.Analyzer - - return goanalysis. - NewLinterFromAnalyzer(analyzer). - WithContextSetter(func(lintCtx *linter.Context) { - if settings == nil { - return - } - if len(settings.Alias) == 0 { - lintCtx.Log.Infof("importas settings found, but no aliases listed. List aliases under alias: key.") - } - - if err := analyzer.Flags.Set("no-unaliased", strconv.FormatBool(settings.NoUnaliased)); err != nil { - lintCtx.Log.Errorf("failed to parse configuration: %v", err) - } - - if err := analyzer.Flags.Set("no-extra-aliases", strconv.FormatBool(settings.NoExtraAliases)); err != nil { - lintCtx.Log.Errorf("failed to parse configuration: %v", err) - } - - uniqPackages := make(map[string]config.ImportAsAlias) - uniqAliases := make(map[string]config.ImportAsAlias) - for _, a := range settings.Alias { - if a.Pkg == "" { - lintCtx.Log.Errorf("invalid configuration, empty package: pkg=%s alias=%s", a.Pkg, a.Alias) - continue - } - - if v, ok := uniqPackages[a.Pkg]; ok { - lintCtx.Log.Errorf("invalid configuration, multiple aliases for the same package: pkg=%s aliases=[%s,%s]", a.Pkg, a.Alias, v.Alias) - } else { - uniqPackages[a.Pkg] = a - } - - // Skips the duplication check when: - // - the alias is empty. - // - the alias is a regular expression replacement pattern (ie. contains `$`). - v, ok := uniqAliases[a.Alias] - if ok && a.Alias != "" && !strings.Contains(a.Alias, "$") { - lintCtx.Log.Errorf("invalid configuration, multiple packages with the same alias: alias=%s packages=[%s,%s]", a.Alias, a.Pkg, v.Pkg) - } else { - uniqAliases[a.Alias] = a - } - - err := analyzer.Flags.Set("alias", fmt.Sprintf("%s:%s", a.Pkg, a.Alias)) - if err != nil { - lintCtx.Log.Errorf("failed to parse configuration: %v", err) - } - } - }). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/inamedparam/inamedparam.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/inamedparam/inamedparam.go deleted file mode 100644 index ecb6f7e502..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/inamedparam/inamedparam.go +++ /dev/null @@ -1,23 +0,0 @@ -package inamedparam - -import ( - "github.com/macabu/inamedparam" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.INamedParamSettings) *goanalysis.Linter { - var cfg map[string]any - - if settings != nil { - cfg = map[string]any{ - "skip-single-param": settings.SkipSingleParam, - } - } - - return goanalysis. - NewLinterFromAnalyzer(inamedparam.Analyzer). - WithConfig(cfg). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/ineffassign/ineffassign.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/ineffassign/ineffassign.go deleted file mode 100644 index 1df737cbf5..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/ineffassign/ineffassign.go +++ /dev/null @@ -1,23 +0,0 @@ -package ineffassign - -import ( - "github.com/gordonklaus/ineffassign/pkg/ineffassign" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.IneffassignSettings) *goanalysis.Linter { - var cfg map[string]any - - if settings != nil { - cfg = map[string]any{ - "check-escaping-errors": settings.CheckEscapingErrors, - } - } - - return goanalysis. - NewLinterFromAnalyzer(ineffassign.Analyzer). - WithConfig(cfg). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/interfacebloat/interfacebloat.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/interfacebloat/interfacebloat.go deleted file mode 100644 index f2e1874232..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/interfacebloat/interfacebloat.go +++ /dev/null @@ -1,23 +0,0 @@ -package interfacebloat - -import ( - "github.com/sashamelentyev/interfacebloat/pkg/analyzer" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.InterfaceBloatSettings) *goanalysis.Linter { - var cfg map[string]any - - if settings != nil { - cfg = map[string]any{ - analyzer.InterfaceMaxMethodsFlag: settings.Max, - } - } - - return goanalysis. - NewLinterFromAnalyzer(analyzer.New()). - WithConfig(cfg). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/internal/commons.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/internal/commons.go deleted file mode 100644 index d19c1fd450..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/internal/commons.go +++ /dev/null @@ -1,6 +0,0 @@ -package internal - -import "github.com/golangci/golangci-lint/v2/pkg/logutils" - -// LinterLogger must be use only when the context logger is not available. -var LinterLogger = logutils.NewStderrLog(logutils.DebugKeyLinter) diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/internal/util.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/internal/util.go deleted file mode 100644 index 86137cf660..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/internal/util.go +++ /dev/null @@ -1,33 +0,0 @@ -package internal - -import ( - "fmt" - "strings" - - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func FormatCode(code string) string { - if strings.Contains(code, "`") { - return code // TODO: properly escape or remove - } - - return fmt.Sprintf("`%s`", code) -} - -func GetGoFileNames(pass *analysis.Pass) []string { - var filenames []string - - for _, f := range pass.Files { - position, b := goanalysis.GetGoFilePosition(pass, f) - if !b { - continue - } - - filenames = append(filenames, position.Filename) - } - - return filenames -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/intrange/intrange.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/intrange/intrange.go deleted file mode 100644 index 1ff02964cb..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/intrange/intrange.go +++ /dev/null @@ -1,13 +0,0 @@ -package intrange - -import ( - "github.com/ckaznocha/intrange" - - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - return goanalysis. - NewLinterFromAnalyzer(intrange.Analyzer). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/iotamixing/iotamixing.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/iotamixing/iotamixing.go deleted file mode 100644 index dee0c3c771..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/iotamixing/iotamixing.go +++ /dev/null @@ -1,26 +0,0 @@ -package iotamixing - -import ( - im "github.com/AdminBenni/iota-mixing/pkg/analyzer" - "github.com/AdminBenni/iota-mixing/pkg/analyzer/flags" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.IotaMixingSettings) *goanalysis.Linter { - cfg := map[string]any{} - - if settings != nil { - cfg[flags.ReportIndividualFlagName] = settings.ReportIndividual - } - - analyzer := im.GetIotaMixingAnalyzer() - - flags.SetupFlags(&analyzer.Flags) - - return goanalysis. - NewLinterFromAnalyzer(analyzer). - WithConfig(cfg). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/ireturn/ireturn.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/ireturn/ireturn.go deleted file mode 100644 index b9cce00018..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/ireturn/ireturn.go +++ /dev/null @@ -1,27 +0,0 @@ -package ireturn - -import ( - "strings" - - "github.com/butuzov/ireturn/analyzer" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.IreturnSettings) *goanalysis.Linter { - var cfg map[string]any - - if settings != nil { - cfg = map[string]any{ - "allow": strings.Join(settings.Allow, ","), - "reject": strings.Join(settings.Reject, ","), - "nonolint": true, - } - } - - return goanalysis. - NewLinterFromAnalyzer(analyzer.NewAnalyzer()). - WithConfig(cfg). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/lll/lll.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/lll/lll.go deleted file mode 100644 index c8e6717dea..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/lll/lll.go +++ /dev/null @@ -1,126 +0,0 @@ -package lll - -import ( - "bufio" - "errors" - "fmt" - "go/ast" - "os" - "strings" - "unicode/utf8" - - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -const goCommentDirectivePrefix = "//go:" - -func New(settings *config.LllSettings) *goanalysis.Linter { - return goanalysis. - NewLinterFromAnalyzer(&analysis.Analyzer{ - Name: "lll", - Doc: "Reports long lines", - Run: func(pass *analysis.Pass) (any, error) { - err := runLll(pass, settings) - if err != nil { - return nil, err - } - - return nil, nil - }, - }). - WithLoadMode(goanalysis.LoadModeSyntax) -} - -func runLll(pass *analysis.Pass, settings *config.LllSettings) error { - spaces := strings.Repeat(" ", settings.TabWidth) - - for _, file := range pass.Files { - err := getLLLIssuesForFile(pass, file, settings.LineLength, spaces) - if err != nil { - return err - } - } - - return nil -} - -func getLLLIssuesForFile(pass *analysis.Pass, file *ast.File, maxLineLen int, tabSpaces string) error { - position, isGoFile := goanalysis.GetGoFilePosition(pass, file) - if !isGoFile { - return nil - } - - nonAdjPosition := pass.Fset.PositionFor(file.Pos(), false) - - f, err := os.Open(position.Filename) - if err != nil { - return fmt.Errorf("can't open file %s: %w", position.Filename, err) - } - - defer f.Close() - - ft := pass.Fset.File(file.Pos()) - - lineNumber := 0 - multiImportEnabled := false - - scanner := bufio.NewScanner(f) - for scanner.Scan() { - lineNumber++ - - line := scanner.Text() - line = strings.ReplaceAll(line, "\t", tabSpaces) - - if strings.HasPrefix(line, goCommentDirectivePrefix) { - continue - } - - if strings.HasPrefix(line, "import") { - multiImportEnabled = strings.HasSuffix(line, "(") - continue - } - - if multiImportEnabled { - if line == ")" { - multiImportEnabled = false - } - - continue - } - - lineLen := utf8.RuneCountInString(line) - if lineLen > maxLineLen { - pass.Report(analysis.Diagnostic{ - Pos: ft.LineStart(goanalysis.AdjustPos(lineNumber, nonAdjPosition.Line, position.Line)), - Message: fmt.Sprintf("The line is %d characters long, which exceeds the maximum of %d characters.", - lineLen, maxLineLen), - }) - } - } - - if err := scanner.Err(); err != nil { - // scanner.Scan() might fail if the line is longer than bufio.MaxScanTokenSize - // In the case where the specified maxLineLen is smaller than bufio.MaxScanTokenSize - // we can return this line as a long line instead of returning an error. - // The reason for this change is that this case might happen with autogenerated files - // The go-bindata tool for instance might generate a file with a very long line. - // In this case, as it's an auto generated file, the warning returned by lll will - // be ignored. - // But if we return a linter error here, and this error happens for an autogenerated - // file the error will be discarded (fine), but all the subsequent errors for lll will - // be discarded for other files, and we'll miss legit error. - if errors.Is(err, bufio.ErrTooLong) && maxLineLen < bufio.MaxScanTokenSize { - pass.Report(analysis.Diagnostic{ - Pos: ft.LineStart(goanalysis.AdjustPos(lineNumber, nonAdjPosition.Line, position.Line)), - Message: fmt.Sprintf("line is more than %d characters", bufio.MaxScanTokenSize), - }) - } else { - return fmt.Errorf("can't scan file %s: %w", position.Filename, err) - } - } - - return nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/loggercheck/loggercheck.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/loggercheck/loggercheck.go deleted file mode 100644 index b9a6efa75f..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/loggercheck/loggercheck.go +++ /dev/null @@ -1,42 +0,0 @@ -package loggercheck - -import ( - "github.com/timonwong/loggercheck" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.LoggerCheckSettings) *goanalysis.Linter { - var opts []loggercheck.Option - - if settings != nil { - var disable []string - if !settings.Kitlog { - disable = append(disable, "kitlog") - } - if !settings.Klog { - disable = append(disable, "klog") - } - if !settings.Logr { - disable = append(disable, "logr") - } - if !settings.Slog { - disable = append(disable, "slog") - } - if !settings.Zap { - disable = append(disable, "zap") - } - - opts = []loggercheck.Option{ - loggercheck.WithDisable(disable), - loggercheck.WithRequireStringKey(settings.RequireStringKey), - loggercheck.WithRules(settings.Rules), - loggercheck.WithNoPrintfLike(settings.NoPrintfLike), - } - } - - return goanalysis. - NewLinterFromAnalyzer(loggercheck.NewAnalyzer(opts...)). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/maintidx/maintidx.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/maintidx/maintidx.go deleted file mode 100644 index f2076c8ab0..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/maintidx/maintidx.go +++ /dev/null @@ -1,23 +0,0 @@ -package maintidx - -import ( - "github.com/yagipy/maintidx" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.MaintIdxSettings) *goanalysis.Linter { - cfg := map[string]any{ - "under": 20, - } - - if settings != nil { - cfg["under"] = settings.Under - } - - return goanalysis. - NewLinterFromAnalyzer(maintidx.Analyzer). - WithConfig(cfg). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/makezero/makezero.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/makezero/makezero.go deleted file mode 100644 index 5ee298d99f..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/makezero/makezero.go +++ /dev/null @@ -1,48 +0,0 @@ -package makezero - -import ( - "fmt" - - "github.com/ashanbrown/makezero/v2/makezero" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.MakezeroSettings) *goanalysis.Linter { - return goanalysis. - NewLinterFromAnalyzer(&analysis.Analyzer{ - Name: "makezero", - Doc: "Find slice declarations with non-zero initial length", - Run: func(pass *analysis.Pass) (any, error) { - err := runMakeZero(pass, settings) - if err != nil { - return nil, err - } - - return nil, nil - }, - }). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} - -func runMakeZero(pass *analysis.Pass, settings *config.MakezeroSettings) error { - zero := makezero.NewLinter(settings.Always) - - for _, file := range pass.Files { - hints, err := zero.Run(pass.Fset, pass.TypesInfo, file) - if err != nil { - return fmt.Errorf("makezero linter failed on file %q: %w", file.Name.String(), err) - } - - for _, hint := range hints { - pass.Report(analysis.Diagnostic{ - Pos: hint.Pos(), - Message: hint.Details(), - }) - } - } - - return nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/mirror/mirror.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/mirror/mirror.go deleted file mode 100644 index 07cfe25e4e..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/mirror/mirror.go +++ /dev/null @@ -1,23 +0,0 @@ -package mirror - -import ( - "github.com/butuzov/mirror" - - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - // mirror only lints test files if the `--with-tests` flag is passed, - // so we pass the `with-tests` flag as true to the analyzer before running it. - // This can be turned off by using the regular golangci-lint flags such as `--tests` or `--skip-files` - // or can be disabled per linter via exclude rules. - // (see https://github.com/golangci/golangci-lint/issues/2527#issuecomment-1023707262) - cfg := map[string]any{ - "with-tests": true, - } - - return goanalysis. - NewLinterFromAnalyzer(mirror.NewAnalyzer()). - WithConfig(cfg). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/misspell/misspell.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/misspell/misspell.go deleted file mode 100644 index cbf378505b..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/misspell/misspell.go +++ /dev/null @@ -1,152 +0,0 @@ -package misspell - -import ( - "fmt" - "go/ast" - "go/token" - "strings" - "unicode" - - "github.com/golangci/misspell" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/golinters/internal" -) - -const linterName = "misspell" - -func New(settings *config.MisspellSettings) *goanalysis.Linter { - replacer, err := createMisspellReplacer(settings) - if err != nil { - internal.LinterLogger.Fatalf("%s: %v", linterName, err) - } - - return goanalysis. - NewLinterFromAnalyzer(&analysis.Analyzer{ - Name: linterName, - Doc: "Finds commonly misspelled English words", - Run: func(pass *analysis.Pass) (any, error) { - for _, file := range pass.Files { - err := runMisspellOnFile(pass, file, replacer, settings.Mode) - if err != nil { - return nil, err - } - } - - return nil, nil - }, - }). - WithLoadMode(goanalysis.LoadModeSyntax) -} - -func createMisspellReplacer(settings *config.MisspellSettings) (*misspell.Replacer, error) { - replacer := &misspell.Replacer{ - Replacements: misspell.DictMain, - } - - // Figure out regional variations - switch strings.ToUpper(settings.Locale) { - case "": - // nothing - case "US": - replacer.AddRuleList(misspell.DictAmerican) - case "UK", "GB": - replacer.AddRuleList(misspell.DictBritish) - case "NZ", "AU", "CA": - return nil, fmt.Errorf("unknown locale: %q", settings.Locale) - } - - err := appendExtraWords(replacer, settings.ExtraWords) - if err != nil { - return nil, fmt.Errorf("process extra words: %w", err) - } - - if len(settings.IgnoreRules) != 0 { - replacer.RemoveRule(settings.IgnoreRules) - } - - // It can panic. - replacer.Compile() - - return replacer, nil -} - -func runMisspellOnFile(pass *analysis.Pass, file *ast.File, replacer *misspell.Replacer, mode string) error { - position, isGoFile := goanalysis.GetGoFilePosition(pass, file) - if !isGoFile { - return nil - } - - // Uses the non-adjusted file to work with cgo: - // if we read the real file, the positions are wrong in some cases. - fileContent, err := pass.ReadFile(pass.Fset.PositionFor(file.Pos(), false).Filename) - if err != nil { - return fmt.Errorf("can't get file %s contents: %w", position.Filename, err) - } - - // `r.ReplaceGo` doesn't find issues inside strings: it searches only inside comments. - // `r.Replace` searches all words: it treats input as a plain text. - // The standalone misspell tool uses `r.Replace` by default. - var replace func(input string) (string, []misspell.Diff) - switch strings.ToLower(mode) { - case "restricted": - replace = replacer.ReplaceGo - default: - replace = replacer.Replace - } - - f := pass.Fset.File(file.Pos()) - - _, diffs := replace(string(fileContent)) - - for _, diff := range diffs { - text := fmt.Sprintf("`%s` is a misspelling of `%s`", diff.Original, diff.Corrected) - - start := f.LineStart(diff.Line) + token.Pos(diff.Column) - end := f.LineStart(diff.Line) + token.Pos(diff.Column+len(diff.Original)) - - pass.Report(analysis.Diagnostic{ - Pos: start, - End: end, - Message: text, - SuggestedFixes: []analysis.SuggestedFix{{ - TextEdits: []analysis.TextEdit{{ - Pos: start, - End: end, - NewText: []byte(diff.Corrected), - }}, - }}, - }) - } - - return nil -} - -func appendExtraWords(replacer *misspell.Replacer, extraWords []config.MisspellExtraWords) error { - if len(extraWords) == 0 { - return nil - } - - extra := make([]string, 0, len(extraWords)*2) - - for _, word := range extraWords { - if word.Typo == "" || word.Correction == "" { - return fmt.Errorf("typo (%q) and correction (%q) fields should not be empty", word.Typo, word.Correction) - } - - if strings.ContainsFunc(word.Typo, func(r rune) bool { return !unicode.IsLetter(r) }) { - return fmt.Errorf("the word %q in the 'typo' field should only contain letters", word.Typo) - } - if strings.ContainsFunc(word.Correction, func(r rune) bool { return !unicode.IsLetter(r) }) { - return fmt.Errorf("the word %q in the 'correction' field should only contain letters", word.Correction) - } - - extra = append(extra, strings.ToLower(word.Typo), strings.ToLower(word.Correction)) - } - - replacer.AddRuleList(extra) - - return nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/mnd/mnd.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/mnd/mnd.go deleted file mode 100644 index 07174c899f..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/mnd/mnd.go +++ /dev/null @@ -1,33 +0,0 @@ -package mnd - -import ( - mnd "github.com/tommy-muehle/go-mnd/v2" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.MndSettings) *goanalysis.Linter { - cfg := map[string]any{} - - if settings != nil { - if len(settings.Checks) > 0 { - cfg["checks"] = settings.Checks - } - if len(settings.IgnoredNumbers) > 0 { - cfg["ignored-numbers"] = settings.IgnoredNumbers - } - if len(settings.IgnoredFiles) > 0 { - cfg["ignored-files"] = settings.IgnoredFiles - } - if len(settings.IgnoredFunctions) > 0 { - cfg["ignored-functions"] = settings.IgnoredFunctions - } - } - - return goanalysis. - NewLinterFromAnalyzer(mnd.Analyzer). - WithDesc("An analyzer to detect magic numbers."). - WithConfig(cfg). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/modernize/modernize.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/modernize/modernize.go deleted file mode 100644 index 97825c07e0..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/modernize/modernize.go +++ /dev/null @@ -1,34 +0,0 @@ -package modernize - -import ( - "slices" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/modernize" -) - -func New(settings *config.ModernizeSettings) *goanalysis.Linter { - var analyzers []*analysis.Analyzer - - if settings == nil { - analyzers = modernize.Suite - } else { - for _, analyzer := range modernize.Suite { - if slices.Contains(settings.Disable, analyzer.Name) { - continue - } - - analyzers = append(analyzers, analyzer) - } - } - - return goanalysis.NewLinter( - "modernize", - "A suite of analyzers that suggest simplifications to Go code, using modern language and library features.", - analyzers, - nil). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/musttag/musttag.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/musttag/musttag.go deleted file mode 100644 index d17df9c2b8..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/musttag/musttag.go +++ /dev/null @@ -1,26 +0,0 @@ -package musttag - -import ( - "go-simpler.org/musttag" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.MustTagSettings) *goanalysis.Linter { - var funcs []musttag.Func - - if settings != nil { - for _, fn := range settings.Functions { - funcs = append(funcs, musttag.Func{ - Name: fn.Name, - Tag: fn.Tag, - ArgPos: fn.ArgPos, - }) - } - } - - return goanalysis. - NewLinterFromAnalyzer(musttag.New(funcs...)). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nakedret/nakedret.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nakedret/nakedret.go deleted file mode 100644 index 90053a1aab..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nakedret/nakedret.go +++ /dev/null @@ -1,21 +0,0 @@ -package nakedret - -import ( - "github.com/alexkohler/nakedret/v2" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.NakedretSettings) *goanalysis.Linter { - cfg := &nakedret.NakedReturnRunner{} - - if settings != nil { - // SkipTestFiles is intentionally ignored => should be managed with `linters.exclusions.rules`. - cfg.MaxLength = settings.MaxFuncLines - } - - return goanalysis. - NewLinterFromAnalyzer(nakedret.NakedReturnAnalyzer(cfg)). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nestif/nestif.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nestif/nestif.go deleted file mode 100644 index e5823723c8..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nestif/nestif.go +++ /dev/null @@ -1,52 +0,0 @@ -package nestif - -import ( - "github.com/nakabonne/nestif" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.NestifSettings) *goanalysis.Linter { - return goanalysis. - NewLinterFromAnalyzer(&analysis.Analyzer{ - Name: "nestif", - Doc: "Reports deeply nested if statements", - Run: func(pass *analysis.Pass) (any, error) { - runNestIf(pass, settings) - - return nil, nil - }, - }). - WithLoadMode(goanalysis.LoadModeSyntax) -} - -func runNestIf(pass *analysis.Pass, settings *config.NestifSettings) { - checker := &nestif.Checker{ - MinComplexity: settings.MinComplexity, - } - - for _, file := range pass.Files { - position, isGoFile := goanalysis.GetGoFilePosition(pass, file) - if !isGoFile { - continue - } - - issues := checker.Check(file, pass.Fset) - if len(issues) == 0 { - continue - } - - nonAdjPosition := pass.Fset.PositionFor(file.Pos(), false) - - f := pass.Fset.File(file.Pos()) - - for _, issue := range issues { - pass.Report(analysis.Diagnostic{ - Pos: f.LineStart(goanalysis.AdjustPos(issue.Pos.Line, nonAdjPosition.Line, position.Line)), - Message: issue.Message, - }) - } - } -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nilerr/nilerr.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nilerr/nilerr.go deleted file mode 100644 index fa5dcdc259..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nilerr/nilerr.go +++ /dev/null @@ -1,14 +0,0 @@ -package nilerr - -import ( - "github.com/gostaticanalysis/nilerr" - - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - return goanalysis. - NewLinterFromAnalyzer(nilerr.Analyzer). - WithDesc("Find the code that returns nil even if it checks that the error is not nil."). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nilnesserr/nilnesserr.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nilnesserr/nilnesserr.go deleted file mode 100644 index 95eaf94abe..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nilnesserr/nilnesserr.go +++ /dev/null @@ -1,19 +0,0 @@ -package nilnesserr - -import ( - "github.com/alingse/nilnesserr" - - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/golinters/internal" -) - -func New() *goanalysis.Linter { - analyzer, err := nilnesserr.NewAnalyzer(nilnesserr.LinterSetting{}) - if err != nil { - internal.LinterLogger.Fatalf("nilnesserr: create analyzer: %v", err) - } - - return goanalysis. - NewLinterFromAnalyzer(analyzer). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nilnil/nilnil.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nilnil/nilnil.go deleted file mode 100644 index 4936a6b84c..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nilnil/nilnil.go +++ /dev/null @@ -1,29 +0,0 @@ -package nilnil - -import ( - "github.com/Antonboom/nilnil/pkg/analyzer" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.NilNilSettings) *goanalysis.Linter { - var cfg map[string]any - - if settings != nil { - cfg = map[string]any{ - "detect-opposite": settings.DetectOpposite, - } - if b := settings.OnlyTwo; b != nil { - cfg["only-two"] = *b - } - if len(settings.CheckedTypes) != 0 { - cfg["checked-types"] = settings.CheckedTypes - } - } - - return goanalysis. - NewLinterFromAnalyzer(analyzer.New()). - WithConfig(cfg). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nlreturn/nlreturn.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nlreturn/nlreturn.go deleted file mode 100644 index 7b7ab745ad..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nlreturn/nlreturn.go +++ /dev/null @@ -1,23 +0,0 @@ -package nlreturn - -import ( - "github.com/ssgreg/nlreturn/v2/pkg/nlreturn" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.NlreturnSettings) *goanalysis.Linter { - var cfg map[string]any - - if settings != nil { - cfg = map[string]any{ - "block-size": settings.BlockSize, - } - } - return goanalysis. - NewLinterFromAnalyzer(nlreturn.NewAnalyzer()). - WithDesc("Checks for a new line before return and branch statements to increase code clarity"). - WithConfig(cfg). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/noctx/noctx.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/noctx/noctx.go deleted file mode 100644 index c3e5be1042..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/noctx/noctx.go +++ /dev/null @@ -1,14 +0,0 @@ -package noctx - -import ( - "github.com/sonatard/noctx" - - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - return goanalysis. - NewLinterFromAnalyzer(noctx.Analyzer). - WithDesc("Detects function and method with missing usage of context.Context"). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/noinlineerr/noinlineerr.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/noinlineerr/noinlineerr.go deleted file mode 100644 index 4f9f82eb4d..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/noinlineerr/noinlineerr.go +++ /dev/null @@ -1,13 +0,0 @@ -package noinlineerr - -import ( - "github.com/AlwxSin/noinlineerr" - - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - return goanalysis. - NewLinterFromAnalyzer(noinlineerr.NewAnalyzer()). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nolintlint/internal/README.md b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nolintlint/internal/README.md deleted file mode 100644 index e4d48f012b..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nolintlint/internal/README.md +++ /dev/null @@ -1,31 +0,0 @@ -# nolintlint - -nolintlint is a Go static analysis tool to find ill-formed or insufficiently explained `//nolint` directives for golangci-lint -(or any other linter, using this package) - -## Purpose - -To ensure that lint exceptions have explanations. Consider the case below: - -```Go -import "crypto/md5" //nolint:all - -func hash(data []byte) []byte { - return md5.New().Sum(data) //nolint:all -} -``` - -In the above case, nolint directives are present, but the user has no idea why this is being done or which linter -is being suppressed (in this case, gosec recommends against use of md5). `nolintlint` can require that the code provide an explanation, which might look as follows: - -```Go -import "crypto/md5" //nolint:gosec // this is not used in a secure application - -func hash(data []byte) []byte { - return md5.New().Sum(data) //nolint:gosec // this result is not used in a secure application -} -``` - -`nolintlint` can also identify cases where you may have written `// nolint`. Finally, `nolintlint`, can also enforce that you -use the machine-readable nolint directive format `//nolint:all` and that you mention what linter is being suppressed, as shown above when we write `//nolint:gosec`. - diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nolintlint/internal/issues.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nolintlint/internal/issues.go deleted file mode 100644 index 5e9ba4117c..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nolintlint/internal/issues.go +++ /dev/null @@ -1,41 +0,0 @@ -package internal - -import ( - "fmt" - "strings" - "unicode" -) - -func formatExtraLeadingSpace(fullDirective string) string { - return fmt.Sprintf("directive `%s` should not have more than one leading space", fullDirective) -} - -func formatNotMachine(fullDirective string) string { - expected := fullDirective[:2] + strings.TrimLeftFunc(fullDirective[2:], unicode.IsSpace) - return fmt.Sprintf("directive `%s` should be written without leading space as `%s`", - fullDirective, expected) -} - -func formatNotSpecific(fullDirective, directiveWithOptionalLeadingSpace string) string { - return fmt.Sprintf("directive `%s` should mention specific linter such as `%s:my-linter`", - fullDirective, directiveWithOptionalLeadingSpace) -} - -func formatParseError(fullDirective, directiveWithOptionalLeadingSpace string) string { - return fmt.Sprintf("directive `%s` should match `%s[:] [// ]`", - fullDirective, - directiveWithOptionalLeadingSpace) -} - -func formatNoExplanation(fullDirective, fullDirectiveWithoutExplanation string) string { - return fmt.Sprintf("directive `%s` should provide explanation such as `%s // this is why`", - fullDirective, fullDirectiveWithoutExplanation) -} - -func formatUnusedCandidate(fullDirective, expectedLinter string) string { - details := fmt.Sprintf("directive `%s` is unused", fullDirective) - if expectedLinter != "" { - details += fmt.Sprintf(" for linter %q", expectedLinter) - } - return details -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nolintlint/internal/nolintlint.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nolintlint/internal/nolintlint.go deleted file mode 100644 index a20161405f..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nolintlint/internal/nolintlint.go +++ /dev/null @@ -1,232 +0,0 @@ -// Package internal provides a linter to ensure that all //nolint directives are followed by explanations -package internal - -import ( - "go/token" - "regexp" - "strings" - - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -const LinterName = "nolintlint" - -const ( - NeedsMachineOnly Needs = 1 << iota - NeedsSpecific - NeedsExplanation - NeedsUnused - NeedsAll = NeedsMachineOnly | NeedsSpecific | NeedsExplanation -) - -type Needs uint - -const commentMark = "//" - -var commentPattern = regexp.MustCompile(`^//\s*(nolint)(:\s*[\w-]+\s*(?:,\s*[\w-]+\s*)*)?\b`) - -// matches a complete nolint directive -var fullDirectivePattern = regexp.MustCompile(`^//\s*nolint(?::(\s*[\w-]+\s*(?:,\s*[\w-]+\s*)*))?\s*(//.*)?\s*\n?$`) - -type Linter struct { - needs Needs // indicates which linter checks to perform - excludeByLinter map[string]bool -} - -// NewLinter creates a linter that enforces that the provided directives fulfill the provided requirements -func NewLinter(needs Needs, excludes []string) (*Linter, error) { - excludeByName := make(map[string]bool) - for _, e := range excludes { - excludeByName[e] = true - } - - return &Linter{ - needs: needs | NeedsMachineOnly, - excludeByLinter: excludeByName, - }, nil -} - -var ( - leadingSpacePattern = regexp.MustCompile(`^//(\s*)`) - trailingBlankExplanation = regexp.MustCompile(`\s*(//\s*)?$`) -) - -//nolint:funlen,gocyclo // the function is going to be refactored in the future -func (l Linter) Run(pass *analysis.Pass) ([]*goanalysis.Issue, error) { - var issues []*goanalysis.Issue - - for _, file := range pass.Files { - for _, c := range file.Comments { - for _, comment := range c.List { - if !commentPattern.MatchString(comment.Text) { - continue - } - - // check for a space between the "//" and the directive - leadingSpaceMatches := leadingSpacePattern.FindStringSubmatch(comment.Text) - - var leadingSpace string - if len(leadingSpaceMatches) > 0 { - leadingSpace = leadingSpaceMatches[1] - } - - directiveWithOptionalLeadingSpace := commentMark - if leadingSpace != "" { - directiveWithOptionalLeadingSpace += " " - } - - split := strings.Split(strings.SplitN(comment.Text, ":", 2)[0], commentMark) - directiveWithOptionalLeadingSpace += strings.TrimSpace(split[1]) - - pos := pass.Fset.Position(comment.Pos()) - end := pass.Fset.Position(comment.End()) - - // check for, report and eliminate leading spaces, so we can check for other issues - if leadingSpace != "" { - removeWhitespace := []analysis.SuggestedFix{{ - TextEdits: []analysis.TextEdit{{ - Pos: token.Pos(pos.Offset), - End: token.Pos(pos.Offset + len(commentMark) + len(leadingSpace)), - NewText: []byte(commentMark), - }}, - }} - - if (l.needs & NeedsMachineOnly) != 0 { - issue := &result.Issue{ - FromLinter: LinterName, - Text: formatNotMachine(comment.Text), - Pos: pos, - SuggestedFixes: removeWhitespace, - } - - issues = append(issues, goanalysis.NewIssue(issue, pass)) - } else if len(leadingSpace) > 1 { - issue := &result.Issue{ - FromLinter: LinterName, - Text: formatExtraLeadingSpace(comment.Text), - Pos: pos, - SuggestedFixes: removeWhitespace, - } - - issues = append(issues, goanalysis.NewIssue(issue, pass)) - } - } - - fullMatches := fullDirectivePattern.FindStringSubmatch(comment.Text) - if len(fullMatches) == 0 { - issue := &result.Issue{ - FromLinter: LinterName, - Text: formatParseError(comment.Text, directiveWithOptionalLeadingSpace), - Pos: pos, - } - - issues = append(issues, goanalysis.NewIssue(issue, pass)) - - continue - } - - lintersText, explanation := fullMatches[1], fullMatches[2] - - var linters []string - if lintersText != "" && !strings.HasPrefix(lintersText, "all") { - lls := strings.Split(lintersText, ",") - linters = make([]string, 0, len(lls)) - rangeStart := (pos.Column - 1) + len(commentMark) + len(leadingSpace) + len("nolint:") - for i, ll := range lls { - rangeEnd := rangeStart + len(ll) - if i < len(lls)-1 { - rangeEnd++ // include trailing comma - } - trimmedLinterName := strings.TrimSpace(ll) - if trimmedLinterName != "" { - linters = append(linters, trimmedLinterName) - } - rangeStart = rangeEnd - } - } - - if (l.needs & NeedsSpecific) != 0 { - if len(linters) == 0 { - issue := &result.Issue{ - FromLinter: LinterName, - Text: formatNotSpecific(comment.Text, directiveWithOptionalLeadingSpace), - Pos: pos, - } - - issues = append(issues, goanalysis.NewIssue(issue, pass)) - } - } - - // when detecting unused directives, we send all the directives through and filter them out in the nolint processor - if (l.needs & NeedsUnused) != 0 { - removeNolintCompletely := []analysis.SuggestedFix{{ - TextEdits: []analysis.TextEdit{{ - Pos: token.Pos(pos.Offset), - End: token.Pos(end.Offset), - NewText: nil, - }}, - }} - - if len(linters) == 0 { - issue := &result.Issue{ - FromLinter: LinterName, - Text: formatUnusedCandidate(comment.Text, ""), - Pos: pos, - ExpectNoLint: true, - SuggestedFixes: removeNolintCompletely, - } - - issues = append(issues, goanalysis.NewIssue(issue, pass)) - } else { - for _, linter := range linters { - issue := &result.Issue{ - FromLinter: LinterName, - Text: formatUnusedCandidate(comment.Text, linter), - Pos: pos, - ExpectNoLint: true, - ExpectedNoLintLinter: linter, - } - - // only offer SuggestedFix if there is a single linter - // because of issues around commas and the possibility of all - // linters being removed - if len(linters) == 1 { - issue.SuggestedFixes = removeNolintCompletely - } - - issues = append(issues, goanalysis.NewIssue(issue, pass)) - } - } - } - - if (l.needs&NeedsExplanation) != 0 && (explanation == "" || strings.TrimSpace(explanation) == commentMark) { - needsExplanation := len(linters) == 0 // if no linters are mentioned, we must have explanation - // otherwise, check if we are excluding all the mentioned linters - for _, ll := range linters { - if !l.excludeByLinter[ll] { // if a linter does require explanation - needsExplanation = true - break - } - } - - if needsExplanation { - fullDirectiveWithoutExplanation := trailingBlankExplanation.ReplaceAllString(comment.Text, "") - - issue := &result.Issue{ - FromLinter: LinterName, - Text: formatNoExplanation(comment.Text, fullDirectiveWithoutExplanation), - Pos: pos, - } - - issues = append(issues, goanalysis.NewIssue(issue, pass)) - } - } - } - } - } - - return issues, nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nolintlint/nolintlint.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nolintlint/nolintlint.go deleted file mode 100644 index 6f3d373063..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nolintlint/nolintlint.go +++ /dev/null @@ -1,63 +0,0 @@ -package nolintlint - -import ( - "fmt" - "sync" - - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/golinters/internal" - nolintlint "github.com/golangci/golangci-lint/v2/pkg/golinters/nolintlint/internal" - "github.com/golangci/golangci-lint/v2/pkg/lint/linter" -) - -const LinterName = nolintlint.LinterName - -func New(settings *config.NoLintLintSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []*goanalysis.Issue - - var needs nolintlint.Needs - if settings.RequireExplanation { - needs |= nolintlint.NeedsExplanation - } - if settings.RequireSpecific { - needs |= nolintlint.NeedsSpecific - } - if !settings.AllowUnused { - needs |= nolintlint.NeedsUnused - } - - lnt, err := nolintlint.NewLinter(needs, settings.AllowNoExplanation) - if err != nil { - internal.LinterLogger.Fatalf("%s: create analyzer: %v", nolintlint.LinterName, err) - } - - return goanalysis. - NewLinterFromAnalyzer(&analysis.Analyzer{ - Name: nolintlint.LinterName, - Doc: "Reports ill-formed or insufficient nolint directives", - Run: func(pass *analysis.Pass) (any, error) { - issues, err := lnt.Run(pass) - if err != nil { - return nil, fmt.Errorf("linter failed to run: %w", err) - } - - if len(issues) == 0 { - return nil, nil - } - - mu.Lock() - resIssues = append(resIssues, issues...) - mu.Unlock() - - return nil, nil - }, - }). - WithIssuesReporter(func(*linter.Context) []*goanalysis.Issue { - return resIssues - }). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nonamedreturns/nonamedreturns.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nonamedreturns/nonamedreturns.go deleted file mode 100644 index 4149ef818e..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nonamedreturns/nonamedreturns.go +++ /dev/null @@ -1,23 +0,0 @@ -package nonamedreturns - -import ( - "github.com/firefart/nonamedreturns/analyzer" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.NoNamedReturnsSettings) *goanalysis.Linter { - var cfg map[string]any - - if settings != nil { - cfg = map[string]any{ - analyzer.FlagReportErrorInDefer: settings.ReportErrorInDefer, - } - } - - return goanalysis. - NewLinterFromAnalyzer(analyzer.Analyzer). - WithConfig(cfg). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nosprintfhostport/nosprintfhostport.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nosprintfhostport/nosprintfhostport.go deleted file mode 100644 index f8ca26b738..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/nosprintfhostport/nosprintfhostport.go +++ /dev/null @@ -1,13 +0,0 @@ -package nosprintfhostport - -import ( - "github.com/stbenjam/no-sprintf-host-port/pkg/analyzer" - - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - return goanalysis. - NewLinterFromAnalyzer(analyzer.Analyzer). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/paralleltest/paralleltest.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/paralleltest/paralleltest.go deleted file mode 100644 index f3eac2e05a..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/paralleltest/paralleltest.go +++ /dev/null @@ -1,29 +0,0 @@ -package paralleltest - -import ( - "github.com/kunwardeep/paralleltest/pkg/paralleltest" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.ParallelTestSettings) *goanalysis.Linter { - var cfg map[string]any - - if settings != nil { - cfg = map[string]any{ - "i": settings.IgnoreMissing, - "ignoremissingsubtests": settings.IgnoreMissingSubtests, - } - - if config.IsGoGreaterThanOrEqual(settings.Go, "1.22") { - cfg["ignoreloopVar"] = true - } - } - - return goanalysis. - NewLinterFromAnalyzer(paralleltest.NewAnalyzer()). - WithDesc("Detects missing usage of t.Parallel() method in your Go test"). - WithConfig(cfg). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/perfsprint/perfsprint.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/perfsprint/perfsprint.go deleted file mode 100644 index e06b5c2a96..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/perfsprint/perfsprint.go +++ /dev/null @@ -1,40 +0,0 @@ -package perfsprint - -import ( - "github.com/catenacyber/perfsprint/analyzer" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.PerfSprintSettings) *goanalysis.Linter { - cfg := map[string]any{ - "fiximports": false, - } - - if settings != nil { - // NOTE: The option `ignore-tests` is not handled because it should be managed with `linters.exclusions.rules` - - cfg["integer-format"] = settings.IntegerFormat - cfg["int-conversion"] = settings.IntConversion - - cfg["error-format"] = settings.ErrorFormat - cfg["err-error"] = settings.ErrError - cfg["errorf"] = settings.ErrorF - - cfg["string-format"] = settings.StringFormat - cfg["sprintf1"] = settings.SprintF1 - cfg["strconcat"] = settings.StrConcat - - cfg["bool-format"] = settings.BoolFormat - cfg["hex-format"] = settings.HexFormat - - cfg["concat-loop"] = settings.ConcatLoop - cfg["loop-other-ops"] = settings.LoopOtherOps - } - - return goanalysis. - NewLinterFromAnalyzer(analyzer.New()). - WithConfig(cfg). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/prealloc/prealloc.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/prealloc/prealloc.go deleted file mode 100644 index c750df9904..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/prealloc/prealloc.go +++ /dev/null @@ -1,37 +0,0 @@ -package prealloc - -import ( - "fmt" - - "github.com/alexkohler/prealloc/pkg" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/golinters/internal" -) - -func New(settings *config.PreallocSettings) *goanalysis.Linter { - return goanalysis. - NewLinterFromAnalyzer(&analysis.Analyzer{ - Name: "prealloc", - Doc: "Find slice declarations that could potentially be pre-allocated", - Run: func(pass *analysis.Pass) (any, error) { - runPreAlloc(pass, settings) - - return nil, nil - }, - }). - WithLoadMode(goanalysis.LoadModeSyntax) -} - -func runPreAlloc(pass *analysis.Pass, settings *config.PreallocSettings) { - hints := pkg.Check(pass.Files, settings.Simple, settings.RangeLoops, settings.ForLoops) - - for _, hint := range hints { - pass.Report(analysis.Diagnostic{ - Pos: hint.Pos, - Message: fmt.Sprintf("Consider pre-allocating %s", internal.FormatCode(hint.DeclaredSliceName)), - }) - } -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/predeclared/predeclared.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/predeclared/predeclared.go deleted file mode 100644 index 8f2be53c4f..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/predeclared/predeclared.go +++ /dev/null @@ -1,26 +0,0 @@ -package predeclared - -import ( - "strings" - - "github.com/nishanths/predeclared/passes/predeclared" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.PredeclaredSettings) *goanalysis.Linter { - var cfg map[string]any - - if settings != nil { - cfg = map[string]any{ - predeclared.IgnoreFlag: strings.Join(settings.Ignore, ","), - predeclared.QualifiedFlag: settings.Qualified, - } - } - - return goanalysis. - NewLinterFromAnalyzer(predeclared.Analyzer). - WithConfig(cfg). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/promlinter/promlinter.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/promlinter/promlinter.go deleted file mode 100644 index 491409f4ef..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/promlinter/promlinter.go +++ /dev/null @@ -1,73 +0,0 @@ -package promlinter - -import ( - "fmt" - "sync" - - "github.com/yeya24/promlinter" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/lint/linter" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -const linterName = "promlinter" - -func New(settings *config.PromlinterSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []*goanalysis.Issue - - var promSettings promlinter.Setting - if settings != nil { - promSettings = promlinter.Setting{ - Strict: settings.Strict, - DisabledLintFuncs: settings.DisabledLinters, - } - } - - return goanalysis. - NewLinterFromAnalyzer(&analysis.Analyzer{ - Name: linterName, - Doc: "Check Prometheus metrics naming via promlint", - Run: func(pass *analysis.Pass) (any, error) { - issues := runPromLinter(pass, promSettings) - - if len(issues) == 0 { - return nil, nil - } - - mu.Lock() - resIssues = append(resIssues, issues...) - mu.Unlock() - - return nil, nil - }, - }). - WithIssuesReporter(func(*linter.Context) []*goanalysis.Issue { - return resIssues - }). - WithLoadMode(goanalysis.LoadModeSyntax) -} - -func runPromLinter(pass *analysis.Pass, promSettings promlinter.Setting) []*goanalysis.Issue { - lintIssues := promlinter.RunLint(pass.Fset, pass.Files, promSettings) - - if len(lintIssues) == 0 { - return nil - } - - issues := make([]*goanalysis.Issue, len(lintIssues)) - for k, i := range lintIssues { - issue := result.Issue{ - Pos: i.Pos, - Text: fmt.Sprintf("Metric: %s Error: %s", i.Metric, i.Text), - FromLinter: linterName, - } - - issues[k] = goanalysis.NewIssue(&issue, pass) - } - - return issues -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/protogetter/protogetter.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/protogetter/protogetter.go deleted file mode 100644 index bee5da2639..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/protogetter/protogetter.go +++ /dev/null @@ -1,25 +0,0 @@ -package protogetter - -import ( - "github.com/ghostiam/protogetter" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.ProtoGetterSettings) *goanalysis.Linter { - var cfg protogetter.Config - - if settings != nil { - cfg = protogetter.Config{ - SkipGeneratedBy: settings.SkipGeneratedBy, - SkipFiles: settings.SkipFiles, - SkipAnyGenerated: settings.SkipAnyGenerated, - ReplaceFirstArgInAppend: settings.ReplaceFirstArgInAppend, - } - } - - return goanalysis. - NewLinterFromAnalyzer(protogetter.NewAnalyzer(&cfg)). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/reassign/reassign.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/reassign/reassign.go deleted file mode 100644 index 35e661cae8..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/reassign/reassign.go +++ /dev/null @@ -1,26 +0,0 @@ -package reassign - -import ( - "fmt" - "strings" - - "github.com/curioswitch/go-reassign" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.ReassignSettings) *goanalysis.Linter { - var cfg map[string]any - - if settings != nil && len(settings.Patterns) > 0 { - cfg = map[string]any{ - reassign.FlagPattern: fmt.Sprintf("^(%s)$", strings.Join(settings.Patterns, "|")), - } - } - - return goanalysis. - NewLinterFromAnalyzer(reassign.NewAnalyzer()). - WithConfig(cfg). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/recvcheck/recvcheck.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/recvcheck/recvcheck.go deleted file mode 100644 index 76db48f939..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/recvcheck/recvcheck.go +++ /dev/null @@ -1,21 +0,0 @@ -package recvcheck - -import ( - "github.com/raeperd/recvcheck" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.RecvcheckSettings) *goanalysis.Linter { - var cfg recvcheck.Settings - - if settings != nil { - cfg.DisableBuiltin = settings.DisableBuiltin - cfg.Exclusions = settings.Exclusions - } - - return goanalysis. - NewLinterFromAnalyzer(recvcheck.NewAnalyzer(cfg)). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/revive/revive.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/revive/revive.go deleted file mode 100644 index 8e5a7835de..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/revive/revive.go +++ /dev/null @@ -1,476 +0,0 @@ -package revive - -import ( - "bytes" - "cmp" - "fmt" - "go/token" - "os" - "reflect" - "slices" - "strings" - "sync" - - "github.com/BurntSushi/toml" - hcversion "github.com/hashicorp/go-version" - reviveConfig "github.com/mgechev/revive/config" - "github.com/mgechev/revive/lint" - "github.com/mgechev/revive/rule" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/golinters/internal" - "github.com/golangci/golangci-lint/v2/pkg/lint/linter" - "github.com/golangci/golangci-lint/v2/pkg/logutils" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -const linterName = "revive" - -var ( - debugf = logutils.Debug(logutils.DebugKeyRevive) - isDebug = logutils.HaveDebugTag(logutils.DebugKeyRevive) -) - -func New(settings *config.ReviveSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []*goanalysis.Issue - - analyzer := &analysis.Analyzer{ - Name: linterName, - Doc: "Fast, configurable, extensible, flexible, and beautiful linter for Go. Drop-in replacement of golint.", - Run: goanalysis.DummyRun, - } - - return goanalysis. - NewLinterFromAnalyzer(analyzer). - WithContextSetter(func(lintCtx *linter.Context) { - w, err := newWrapper(settings) - if err != nil { - lintCtx.Log.Errorf("setup revive: %v", err) - return - } - - analyzer.Run = func(pass *analysis.Pass) (any, error) { - issues, err := w.run(pass) - if err != nil { - return nil, err - } - - if len(issues) == 0 { - return nil, nil - } - - mu.Lock() - resIssues = append(resIssues, issues...) - mu.Unlock() - - return nil, nil - } - }). - WithIssuesReporter(func(*linter.Context) []*goanalysis.Issue { - return resIssues - }). - WithLoadMode(goanalysis.LoadModeSyntax) -} - -type wrapper struct { - revive lint.Linter - lintingRules []lint.Rule - conf *lint.Config -} - -func newWrapper(settings *config.ReviveSettings) (*wrapper, error) { - conf, err := getConfig(settings) - if err != nil { - return nil, err - } - - displayRules(conf) - - conf.GoVersion, err = hcversion.NewVersion(settings.Go) - if err != nil { - return nil, err - } - - lintingRules, err := reviveConfig.GetLintingRules(conf, []lint.Rule{}) - if err != nil { - return nil, err - } - - return &wrapper{ - revive: lint.New(os.ReadFile, settings.MaxOpenFiles), - lintingRules: lintingRules, - conf: conf, - }, nil -} - -func (w *wrapper) run(pass *analysis.Pass) ([]*goanalysis.Issue, error) { - packages := [][]string{internal.GetGoFileNames(pass)} - - failures, err := w.revive.Lint(packages, w.lintingRules, *w.conf) - if err != nil { - return nil, err - } - - var issues []*goanalysis.Issue - for failure := range failures { - if failure.Confidence < w.conf.Confidence { - continue - } - - issues = append(issues, w.toIssue(pass, &failure)) - } - - return issues, nil -} - -func (w *wrapper) toIssue(pass *analysis.Pass, failure *lint.Failure) *goanalysis.Issue { - lineRangeTo := failure.Position.End.Line - if failure.RuleName == (&rule.ExportedRule{}).Name() { - lineRangeTo = failure.Position.Start.Line - } - - issue := &result.Issue{ - Severity: string(severity(w.conf, failure)), - Text: fmt.Sprintf("%s: %s", failure.RuleName, failure.Failure), - Pos: token.Position{ - Filename: failure.Position.Start.Filename, - Line: failure.Position.Start.Line, - Offset: failure.Position.Start.Offset, - Column: failure.Position.Start.Column, - }, - LineRange: &result.Range{ - From: failure.Position.Start.Line, - To: lineRangeTo, - }, - FromLinter: linterName, - } - - if failure.ReplacementLine != "" { - f := pass.Fset.File(token.Pos(failure.Position.Start.Offset)) - - // Skip cgo files because the positions are wrong. - if failure.Filename() == f.Name() { - issue.SuggestedFixes = []analysis.SuggestedFix{{ - TextEdits: []analysis.TextEdit{{ - Pos: f.LineStart(failure.Position.Start.Line), - End: goanalysis.EndOfLinePos(f, failure.Position.End.Line), - NewText: []byte(failure.ReplacementLine), - }}, - }} - } - } - - return goanalysis.NewIssue(issue, pass) -} - -// This function mimics the GetConfig function of revive. -// This allows to get default values and right types. -// https://github.com/golangci/golangci-lint/issues/1745 -// https://github.com/mgechev/revive/blob/v1.6.0/config/config.go#L230 -// https://github.com/mgechev/revive/blob/v1.6.0/config/config.go#L182-L188 -func getConfig(cfg *config.ReviveSettings) (*lint.Config, error) { - conf := defaultConfig() - - // Since the Go version is dynamic, this value must be neutralized in order to compare with a "zero value" of the configuration structure. - zero := &config.ReviveSettings{Go: cfg.Go} - - if !reflect.DeepEqual(cfg, zero) { - rawRoot := createConfigMap(cfg) - buf := bytes.NewBuffer(nil) - - err := toml.NewEncoder(buf).Encode(rawRoot) - if err != nil { - return nil, fmt.Errorf("failed to encode configuration: %w", err) - } - - conf = &lint.Config{} - _, err = toml.NewDecoder(buf).Decode(conf) - if err != nil { - return nil, fmt.Errorf("failed to decode configuration: %w", err) - } - } - - normalizeConfig(conf) - - for k, r := range conf.Rules { - err := r.Initialize() - if err != nil { - return nil, fmt.Errorf("error in config of rule %q: %w", k, err) - } - conf.Rules[k] = r - } - - return conf, nil -} - -func createConfigMap(cfg *config.ReviveSettings) map[string]any { - rawRoot := map[string]any{ - "confidence": cfg.Confidence, - "severity": cfg.Severity, - "errorCode": cfg.ErrorCode, - "warningCode": cfg.WarningCode, - "enableAllRules": cfg.EnableAllRules, - - // Should be managed with `linters.exclusions.generated`. - "ignoreGeneratedHeader": false, - } - - rawDirectives := map[string]map[string]any{} - for _, directive := range cfg.Directives { - rawDirectives[directive.Name] = map[string]any{ - "severity": directive.Severity, - } - } - - if len(rawDirectives) > 0 { - rawRoot["directive"] = rawDirectives - } - - rawRules := map[string]map[string]any{} - for _, s := range cfg.Rules { - rawRules[s.Name] = map[string]any{ - "severity": s.Severity, - "arguments": safeTomlSlice(s.Arguments), - "disabled": s.Disabled, - "exclude": s.Exclude, - } - } - - if len(rawRules) > 0 { - rawRoot["rule"] = rawRules - } - - return rawRoot -} - -func safeTomlSlice(r []any) []any { - if len(r) == 0 { - return nil - } - - if _, ok := r[0].(map[any]any); !ok { - return r - } - - var typed []any - for _, elt := range r { - item := map[string]any{} - for k, v := range elt.(map[any]any) { - item[k.(string)] = v - } - - typed = append(typed, item) - } - - return typed -} - -// This element is not exported by revive, so we need copy the code. -// Extracted from https://github.com/mgechev/revive/blob/v1.12.0/config/config.go#L16 -var defaultRules = []lint.Rule{ - &rule.VarDeclarationsRule{}, - &rule.PackageCommentsRule{}, - &rule.DotImportsRule{}, - &rule.BlankImportsRule{}, - &rule.ExportedRule{}, - &rule.VarNamingRule{}, - &rule.IndentErrorFlowRule{}, - &rule.RangeRule{}, - &rule.ErrorfRule{}, - &rule.ErrorNamingRule{}, - &rule.ErrorStringsRule{}, - &rule.ReceiverNamingRule{}, - &rule.IncrementDecrementRule{}, - &rule.ErrorReturnRule{}, - &rule.UnexportedReturnRule{}, - &rule.TimeNamingRule{}, - &rule.ContextKeysType{}, - &rule.ContextAsArgumentRule{}, - &rule.EmptyBlockRule{}, - &rule.SuperfluousElseRule{}, - &rule.UnusedParamRule{}, - &rule.UnreachableCodeRule{}, - &rule.RedefinesBuiltinIDRule{}, -} - -var allRules = append([]lint.Rule{ - &rule.AddConstantRule{}, - &rule.ArgumentsLimitRule{}, - &rule.AtomicRule{}, - &rule.BannedCharsRule{}, - &rule.BareReturnRule{}, - &rule.BoolLiteralRule{}, - &rule.CallToGCRule{}, - &rule.CognitiveComplexityRule{}, - &rule.CommentsDensityRule{}, - &rule.CommentSpacingsRule{}, - &rule.ConfusingNamingRule{}, - &rule.ConfusingResultsRule{}, - &rule.ConstantLogicalExprRule{}, - &rule.CyclomaticRule{}, - &rule.DataRaceRule{}, - &rule.DeepExitRule{}, - &rule.DeferRule{}, - &rule.DuplicatedImportsRule{}, - &rule.EarlyReturnRule{}, - &rule.EmptyLinesRule{}, - &rule.EnforceMapStyleRule{}, - &rule.EnforceRepeatedArgTypeStyleRule{}, - &rule.EnforceSliceStyleRule{}, - &rule.EnforceSwitchStyleRule{}, - &rule.FileHeaderRule{}, - &rule.FileLengthLimitRule{}, - &rule.FilenameFormatRule{}, - &rule.FlagParamRule{}, - &rule.FunctionLength{}, - &rule.FunctionResultsLimitRule{}, - &rule.GetReturnRule{}, - &rule.IdenticalBranchesRule{}, - &rule.IdenticalIfElseIfBranchesRule{}, - &rule.IdenticalIfElseIfConditionsRule{}, - &rule.IdenticalSwitchBranchesRule{}, - &rule.IdenticalSwitchConditionsRule{}, - &rule.IfReturnRule{}, - &rule.ImportAliasNamingRule{}, - &rule.ImportsBlocklistRule{}, - &rule.ImportShadowingRule{}, - &rule.LineLengthLimitRule{}, - &rule.MaxControlNestingRule{}, - &rule.MaxPublicStructsRule{}, - &rule.ModifiesParamRule{}, - &rule.ModifiesValRecRule{}, - &rule.NestedStructs{}, - &rule.OptimizeOperandsOrderRule{}, - &rule.PackageDirectoryMismatchRule{}, - &rule.RangeValAddress{}, - &rule.RangeValInClosureRule{}, - &rule.RedundantBuildTagRule{}, - &rule.RedundantImportAlias{}, - &rule.RedundantTestMainExitRule{}, - &rule.StringFormatRule{}, - &rule.StringOfIntRule{}, - &rule.StructTagRule{}, - &rule.TimeDateRule{}, - &rule.TimeEqualRule{}, - &rule.UncheckedTypeAssertionRule{}, - &rule.UnconditionalRecursionRule{}, - &rule.UnexportedNamingRule{}, - &rule.UnhandledErrorRule{}, - &rule.UnnecessaryFormatRule{}, - &rule.UnnecessaryStmtRule{}, - &rule.UnsecureURLSchemeRule{}, - &rule.UnusedReceiverRule{}, - &rule.UseAnyRule{}, - &rule.UseErrorsNewRule{}, - &rule.UseFmtPrintRule{}, - &rule.UselessBreak{}, - &rule.UselessFallthroughRule{}, - &rule.UseWaitGroupGoRule{}, - &rule.WaitGroupByValueRule{}, -}, defaultRules...) - -const defaultConfidence = 0.8 - -// This element is not exported by revive, so we need copy the code. -// Extracted from https://github.com/mgechev/revive/blob/v1.12.0/config/config.go#L206 -func normalizeConfig(cfg *lint.Config) { - // NOTE(ldez): this custom section for golangci-lint should be kept. - // --- - cfg.Confidence = cmp.Or(cfg.Confidence, defaultConfidence) - cfg.Severity = cmp.Or(cfg.Severity, lint.SeverityWarning) - // --- - - if len(cfg.Rules) == 0 { - cfg.Rules = map[string]lint.RuleConfig{} - } - if cfg.EnableAllRules { - // Add to the configuration all rules not yet present in it - for _, r := range allRules { - ruleName := r.Name() - _, alreadyInConf := cfg.Rules[ruleName] - if alreadyInConf { - continue - } - // Add the rule with an empty conf for - cfg.Rules[ruleName] = lint.RuleConfig{} - } - } - - severity := cfg.Severity - if severity != "" { - for k, v := range cfg.Rules { - if v.Severity == "" { - v.Severity = severity - } - cfg.Rules[k] = v - } - for k, v := range cfg.Directives { - if v.Severity == "" { - v.Severity = severity - } - cfg.Directives[k] = v - } - } -} - -// This element is not exported by revive, so we need copy the code. -// Extracted from https://github.com/mgechev/revive/blob/v1.12.0/config/config.go#L274 -func defaultConfig() *lint.Config { - defaultConfig := lint.Config{ - Confidence: defaultConfidence, - Severity: lint.SeverityWarning, - Rules: map[string]lint.RuleConfig{}, - } - for _, r := range defaultRules { - defaultConfig.Rules[r.Name()] = lint.RuleConfig{} - } - return &defaultConfig -} - -func displayRules(conf *lint.Config) { - if !isDebug { - return - } - - var enabledRules []string - for k, r := range conf.Rules { - if !r.Disabled { - enabledRules = append(enabledRules, k) - } - } - - slices.Sort(enabledRules) - - debugf("All available rules (%d): %s.", len(allRules), strings.Join(extractRulesName(allRules), ", ")) - debugf("Default rules (%d): %s.", len(defaultRules), strings.Join(extractRulesName(defaultRules), ", ")) - debugf("Enabled by config rules (%d): %s.", len(enabledRules), strings.Join(enabledRules, ", ")) - - debugf("revive configuration: %#v", conf) -} - -func extractRulesName(rules []lint.Rule) []string { - var names []string - - for _, r := range rules { - names = append(names, r.Name()) - } - - slices.Sort(names) - - return names -} - -// Extracted from https://github.com/mgechev/revive/blob/v1.12.0/formatter/severity.go -// Modified to use pointers (related to hugeParam rule). -func severity(cfg *lint.Config, failure *lint.Failure) lint.Severity { - if cfg, ok := cfg.Rules[failure.RuleName]; ok && cfg.Severity == lint.SeverityError { - return lint.SeverityError - } - if cfg, ok := cfg.Directives[failure.RuleName]; ok && cfg.Severity == lint.SeverityError { - return lint.SeverityError - } - return lint.SeverityWarning -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/rowserrcheck/rowserrcheck.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/rowserrcheck/rowserrcheck.go deleted file mode 100644 index de0fe4da91..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/rowserrcheck/rowserrcheck.go +++ /dev/null @@ -1,21 +0,0 @@ -package rowserrcheck - -import ( - "github.com/jingyugao/rowserrcheck/passes/rowserr" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.RowsErrCheckSettings) *goanalysis.Linter { - var pkgs []string - - if settings != nil { - pkgs = settings.Packages - } - - return goanalysis. - NewLinterFromAnalyzer(rowserr.NewAnalyzer(pkgs...)). - WithDesc("checks whether Rows.Err of rows is checked successfully"). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/sloglint/sloglint.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/sloglint/sloglint.go deleted file mode 100644 index 891f1fcfdb..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/sloglint/sloglint.go +++ /dev/null @@ -1,32 +0,0 @@ -package sloglint - -import ( - "go-simpler.org/sloglint" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.SlogLintSettings) *goanalysis.Linter { - var opts *sloglint.Options - - if settings != nil { - opts = &sloglint.Options{ - NoMixedArgs: settings.NoMixedArgs, - KVOnly: settings.KVOnly, - AttrOnly: settings.AttrOnly, - NoGlobal: settings.NoGlobal, - ContextOnly: settings.Context, - StaticMsg: settings.StaticMsg, - MsgStyle: settings.MsgStyle, - NoRawKeys: settings.NoRawKeys, - KeyNamingCase: settings.KeyNamingCase, - ForbiddenKeys: settings.ForbiddenKeys, - ArgsOnSepLines: settings.ArgsOnSepLines, - } - } - - return goanalysis. - NewLinterFromAnalyzer(sloglint.New(opts)). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/spancheck/spancheck.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/spancheck/spancheck.go deleted file mode 100644 index 345c362774..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/spancheck/spancheck.go +++ /dev/null @@ -1,30 +0,0 @@ -package spancheck - -import ( - "github.com/jjti/go-spancheck" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.SpancheckSettings) *goanalysis.Linter { - cfg := spancheck.NewDefaultConfig() - - if settings != nil { - if len(settings.Checks) > 0 { - cfg.EnabledChecks = settings.Checks - } - - if len(settings.IgnoreCheckSignatures) > 0 { - cfg.IgnoreChecksSignaturesSlice = settings.IgnoreCheckSignatures - } - - if len(settings.ExtraStartSpanSignatures) > 0 { - cfg.StartSpanMatchersSlice = append(cfg.StartSpanMatchersSlice, settings.ExtraStartSpanSignatures...) - } - } - - return goanalysis. - NewLinterFromAnalyzer(spancheck.NewAnalyzerWithConfig(cfg)). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/sqlclosecheck/sqlclosecheck.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/sqlclosecheck/sqlclosecheck.go deleted file mode 100644 index 4c970cc529..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/sqlclosecheck/sqlclosecheck.go +++ /dev/null @@ -1,13 +0,0 @@ -package sqlclosecheck - -import ( - "github.com/ryanrolds/sqlclosecheck/pkg/analyzer" - - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - return goanalysis. - NewLinterFromAnalyzer(analyzer.NewAnalyzer()). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/staticcheck/staticcheck.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/staticcheck/staticcheck.go deleted file mode 100644 index 0f529a58e5..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/staticcheck/staticcheck.go +++ /dev/null @@ -1,195 +0,0 @@ -package staticcheck - -import ( - "slices" - "strings" - "unicode" - - "golang.org/x/tools/go/analysis" - "honnef.co/go/tools/analysis/lint" - scconfig "honnef.co/go/tools/config" - "honnef.co/go/tools/quickfix" - "honnef.co/go/tools/simple" - "honnef.co/go/tools/staticcheck" - "honnef.co/go/tools/stylecheck" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/logutils" -) - -var ( - debugf = logutils.Debug(logutils.DebugKeyStaticcheck) - isDebug = logutils.HaveDebugTag(logutils.DebugKeyStaticcheck) -) - -func New(settings *config.StaticCheckSettings) *goanalysis.Linter { - cfg := createConfig(settings) - - // `scconfig.Analyzer` is a singleton. - scconfig.Analyzer.Run = func(_ *analysis.Pass) (any, error) { - return cfg, nil - } - - allAnalyzers := slices.Concat(staticcheck.Analyzers, stylecheck.Analyzers, simple.Analyzers, quickfix.Analyzers) - - analyzers := setupAnalyzers(allAnalyzers, cfg.Checks) - - if isDebug { - allAnalyzerNames := extractAnalyzerNames(allAnalyzers) - slices.Sort(allAnalyzerNames) - debugf("All available checks (%d): %s", len(allAnalyzers), strings.Join(allAnalyzerNames, ",")) - - var cfgAnalyzerNames []string - for _, a := range analyzers { - cfgAnalyzerNames = append(cfgAnalyzerNames, a.Name) - } - slices.Sort(cfgAnalyzerNames) - debugf("Enabled by config checks (%d): %s", len(analyzers), strings.Join(cfgAnalyzerNames, ",")) - - debugf("staticcheck configuration: %#v", cfg) - } - - return goanalysis.NewLinter( - "staticcheck", - "It's the set of rules from staticcheck.", - analyzers, - nil, - ).WithLoadMode(goanalysis.LoadModeTypesInfo) -} - -func createConfig(settings *config.StaticCheckSettings) *scconfig.Config { - defaultChecks := []string{"all", "-ST1000", "-ST1003", "-ST1016", "-ST1020", "-ST1021", "-ST1022"} - - var cfg *scconfig.Config - - if settings == nil || !settings.HasConfiguration() { - return &scconfig.Config{ - Checks: defaultChecks, - Initialisms: scconfig.DefaultConfig.Initialisms, - DotImportWhitelist: scconfig.DefaultConfig.DotImportWhitelist, - HTTPStatusCodeWhitelist: scconfig.DefaultConfig.HTTPStatusCodeWhitelist, - } - } - - cfg = &scconfig.Config{ - Checks: settings.Checks, - Initialisms: settings.Initialisms, - DotImportWhitelist: settings.DotImportWhitelist, - HTTPStatusCodeWhitelist: settings.HTTPStatusCodeWhitelist, - } - - if cfg.Checks == nil { - cfg.Checks = defaultChecks - } - - if cfg.Initialisms == nil { - cfg.Initialisms = append(cfg.Initialisms, scconfig.DefaultConfig.Initialisms...) - } - - if cfg.DotImportWhitelist == nil { - cfg.DotImportWhitelist = append(cfg.DotImportWhitelist, scconfig.DefaultConfig.DotImportWhitelist...) - } - - if cfg.HTTPStatusCodeWhitelist == nil { - cfg.HTTPStatusCodeWhitelist = append(cfg.HTTPStatusCodeWhitelist, scconfig.DefaultConfig.HTTPStatusCodeWhitelist...) - } - - cfg.Checks = normalizeList(cfg.Checks) - cfg.Initialisms = normalizeList(cfg.Initialisms) - cfg.DotImportWhitelist = normalizeList(cfg.DotImportWhitelist) - cfg.HTTPStatusCodeWhitelist = normalizeList(cfg.HTTPStatusCodeWhitelist) - - return cfg -} - -// https://github.com/dominikh/go-tools/blob/9bf17c0388a65710524ba04c2d821469e639fdc2/config/config.go#L95-L116 -func normalizeList(list []string) []string { - if len(list) > 1 { - nlist := make([]string, 0, len(list)) - nlist = append(nlist, list[0]) - for i, el := range list[1:] { - if el != list[i] { - nlist = append(nlist, el) - } - } - list = nlist - } - - for _, el := range list { - if el == "inherit" { - // This should never happen, because the default config - // should not use "inherit" - panic(`unresolved "inherit"`) - } - } - - return list -} - -func setupAnalyzers(src []*lint.Analyzer, checks []string) []*analysis.Analyzer { - filter := filterAnalyzerNames(extractAnalyzerNames(src), checks) - - var ret []*analysis.Analyzer - for _, a := range src { - if filter[a.Analyzer.Name] { - ret = append(ret, a.Analyzer) - } - } - - return ret -} - -func extractAnalyzerNames(analyzers []*lint.Analyzer) []string { - var names []string - for _, a := range analyzers { - names = append(names, a.Analyzer.Name) - } - return names -} - -// https://github.com/dominikh/go-tools/blob/9bf17c0388a65710524ba04c2d821469e639fdc2/lintcmd/lint.go#L437-L477 -// -//nolint:gocritic // Keep the original source code. -func filterAnalyzerNames(analyzers []string, checks []string) map[string]bool { - allowedChecks := map[string]bool{} - - for _, check := range checks { - b := true - if len(check) > 1 && check[0] == '-' { - b = false - check = check[1:] - } - - if check == "*" || check == "all" { - // Match all - for _, c := range analyzers { - allowedChecks[c] = b - } - } else if strings.HasSuffix(check, "*") { - // Glob - prefix := check[:len(check)-1] - isCat := strings.IndexFunc(prefix, func(r rune) bool { return unicode.IsNumber(r) }) == -1 - - for _, a := range analyzers { - idx := strings.IndexFunc(a, func(r rune) bool { return unicode.IsNumber(r) }) - if isCat { - // Glob is S*, which should match S1000 but not SA1000 - cat := a[:idx] - if prefix == cat { - allowedChecks[a] = b - } - } else { - // Glob is S1* - if strings.HasPrefix(a, prefix) { - allowedChecks[a] = b - } - } - } - } else { - // Literal check name - allowedChecks[check] = b - } - } - return allowedChecks -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/swaggo/swaggo.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/swaggo/swaggo.go deleted file mode 100644 index 98f7a6bef4..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/swaggo/swaggo.go +++ /dev/null @@ -1,20 +0,0 @@ -package swaggo - -import ( - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/goformatters" - "github.com/golangci/golangci-lint/v2/pkg/goformatters/swaggo" - "github.com/golangci/golangci-lint/v2/pkg/golinters/internal" -) - -func New() *goanalysis.Linter { - return goanalysis. - NewLinterFromAnalyzer( - goformatters.NewAnalyzer( - internal.LinterLogger.Child(swaggo.Name), - "Check if swaggo comments are formatted", - swaggo.New(), - ), - ). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/tagalign/tagalign.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/tagalign/tagalign.go deleted file mode 100644 index eba51311c0..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/tagalign/tagalign.go +++ /dev/null @@ -1,29 +0,0 @@ -package tagalign - -import ( - "github.com/4meepo/tagalign" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.TagAlignSettings) *goanalysis.Linter { - var options []tagalign.Option - - if settings != nil { - options = append(options, tagalign.WithAlign(settings.Align)) - - if settings.Sort || len(settings.Order) > 0 { - options = append(options, tagalign.WithSort(settings.Order...)) - } - - // Strict style will be applied only if Align and Sort are enabled together. - if settings.Strict && settings.Align && settings.Sort { - options = append(options, tagalign.WithStrictStyle()) - } - } - - return goanalysis. - NewLinterFromAnalyzer(tagalign.NewAnalyzer(options...)). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/tagliatelle/tagliatelle.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/tagliatelle/tagliatelle.go deleted file mode 100644 index d0268d11fe..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/tagliatelle/tagliatelle.go +++ /dev/null @@ -1,67 +0,0 @@ -package tagliatelle - -import ( - "maps" - "strings" - - "github.com/ldez/tagliatelle" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.TagliatelleSettings) *goanalysis.Linter { - cfg := tagliatelle.Config{ - Base: tagliatelle.Base{ - Rules: map[string]string{ - "json": "camel", - "yaml": "camel", - "header": "header", - }, - }, - } - - if settings != nil { - maps.Copy(cfg.Rules, settings.Case.Rules) - - cfg.ExtendedRules = toExtendedRules(settings.Case.ExtendedRules) - cfg.UseFieldName = settings.Case.UseFieldName - cfg.IgnoredFields = settings.Case.IgnoredFields - - for _, override := range settings.Case.Overrides { - cfg.Overrides = append(cfg.Overrides, tagliatelle.Overrides{ - Base: tagliatelle.Base{ - Rules: override.Rules, - ExtendedRules: toExtendedRules(override.ExtendedRules), - UseFieldName: override.UseFieldName, - IgnoredFields: override.IgnoredFields, - Ignore: override.Ignore, - }, - Package: override.Package, - }) - } - } - - return goanalysis. - NewLinterFromAnalyzer(tagliatelle.New(cfg)). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} - -func toExtendedRules(src map[string]config.TagliatelleExtendedRule) map[string]tagliatelle.ExtendedRule { - result := make(map[string]tagliatelle.ExtendedRule, len(src)) - - for k, v := range src { - initialismOverrides := make(map[string]bool, len(v.InitialismOverrides)) - for ki, vi := range v.InitialismOverrides { - initialismOverrides[strings.ToUpper(ki)] = vi - } - - result[k] = tagliatelle.ExtendedRule{ - Case: v.Case, - ExtraInitialisms: v.ExtraInitialisms, - InitialismOverrides: initialismOverrides, - } - } - - return result -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/testableexamples/testableexamples.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/testableexamples/testableexamples.go deleted file mode 100644 index 45fdc900e2..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/testableexamples/testableexamples.go +++ /dev/null @@ -1,13 +0,0 @@ -package testableexamples - -import ( - "github.com/maratori/testableexamples/pkg/testableexamples" - - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - return goanalysis. - NewLinterFromAnalyzer(testableexamples.NewAnalyzer()). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/testifylint/testifylint.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/testifylint/testifylint.go deleted file mode 100644 index bb5eac0e45..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/testifylint/testifylint.go +++ /dev/null @@ -1,48 +0,0 @@ -package testifylint - -import ( - "github.com/Antonboom/testifylint/analyzer" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.TestifylintSettings) *goanalysis.Linter { - var cfg map[string]any - - if settings != nil { - cfg = map[string]any{ - "enable-all": settings.EnableAll, - "disable-all": settings.DisableAll, - - "bool-compare.ignore-custom-types": settings.BoolCompare.IgnoreCustomTypes, - "formatter.require-f-funcs": settings.Formatter.RequireFFuncs, - "formatter.require-string-msg": settings.Formatter.RequireStringMsg, - "go-require.ignore-http-handlers": settings.GoRequire.IgnoreHTTPHandlers, - } - if len(settings.EnabledCheckers) > 0 { - cfg["enable"] = settings.EnabledCheckers - } - if len(settings.DisabledCheckers) > 0 { - cfg["disable"] = settings.DisabledCheckers - } - - if b := settings.Formatter.CheckFormatString; b != nil { - cfg["formatter.check-format-string"] = *b - } - if p := settings.ExpectedActual.ExpVarPattern; p != "" { - cfg["expected-actual.pattern"] = p - } - if p := settings.RequireError.FnPattern; p != "" { - cfg["require-error.fn-pattern"] = p - } - if m := settings.SuiteExtraAssertCall.Mode; m != "" { - cfg["suite-extra-assert-call.mode"] = m - } - } - - return goanalysis. - NewLinterFromAnalyzer(analyzer.New()). - WithConfig(cfg). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/testpackage/testpackage.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/testpackage/testpackage.go deleted file mode 100644 index 39c333f1b5..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/testpackage/testpackage.go +++ /dev/null @@ -1,26 +0,0 @@ -package testpackage - -import ( - "strings" - - "github.com/maratori/testpackage/pkg/testpackage" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.TestpackageSettings) *goanalysis.Linter { - var cfg map[string]any - - if settings != nil { - cfg = map[string]any{ - testpackage.SkipRegexpFlagName: settings.SkipRegexp, - testpackage.AllowPackagesFlagName: strings.Join(settings.AllowPackages, ","), - } - } - - return goanalysis. - NewLinterFromAnalyzer(testpackage.NewAnalyzer()). - WithConfig(cfg). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/thelper/thelper.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/thelper/thelper.go deleted file mode 100644 index 77090c5f8b..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/thelper/thelper.go +++ /dev/null @@ -1,75 +0,0 @@ -package thelper - -import ( - "maps" - "slices" - "strings" - - "github.com/kulti/thelper/pkg/analyzer" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/golinters/internal" -) - -func New(settings *config.ThelperSettings) *goanalysis.Linter { - opts := map[string]struct{}{ - "t_name": {}, - "t_begin": {}, - "t_first": {}, - - "f_name": {}, - "f_begin": {}, - "f_first": {}, - - "b_name": {}, - "b_begin": {}, - "b_first": {}, - - "tb_name": {}, - "tb_begin": {}, - "tb_first": {}, - } - - if settings != nil { - applyTHelperOptions(settings.Test, "t_", opts) - applyTHelperOptions(settings.Fuzz, "f_", opts) - applyTHelperOptions(settings.Benchmark, "b_", opts) - applyTHelperOptions(settings.TB, "tb_", opts) - } - - if len(opts) == 0 { - internal.LinterLogger.Fatalf("thelper: at least one option must be enabled") - } - - args := slices.Collect(maps.Keys(opts)) - - cfg := map[string]any{ - "checks": strings.Join(args, ","), - } - - return goanalysis. - NewLinterFromAnalyzer(analyzer.NewAnalyzer()). - WithConfig(cfg). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} - -func applyTHelperOptions(o config.ThelperOptions, prefix string, opts map[string]struct{}) { - if o.Name != nil { - if !*o.Name { - delete(opts, prefix+"name") - } - } - - if o.Begin != nil { - if !*o.Begin { - delete(opts, prefix+"begin") - } - } - - if o.First != nil { - if !*o.First { - delete(opts, prefix+"first") - } - } -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/tparallel/tparallel.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/tparallel/tparallel.go deleted file mode 100644 index 480ef3b1e9..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/tparallel/tparallel.go +++ /dev/null @@ -1,13 +0,0 @@ -package tparallel - -import ( - "github.com/moricho/tparallel" - - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - return goanalysis. - NewLinterFromAnalyzer(tparallel.Analyzer). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/typecheck.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/typecheck.go deleted file mode 100644 index db29f7c183..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/typecheck.go +++ /dev/null @@ -1,17 +0,0 @@ -package golinters - -import ( - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func NewTypecheck() *goanalysis.Linter { - return goanalysis. - NewLinterFromAnalyzer(&analysis.Analyzer{ - Name: "typecheck", - Doc: "Like the front-end of a Go compiler, parses and type-checks Go code", - Run: goanalysis.DummyRun, - }). - WithLoadMode(goanalysis.LoadModeNone) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/unconvert/unconvert.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/unconvert/unconvert.go deleted file mode 100644 index 593dfbe96e..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/unconvert/unconvert.go +++ /dev/null @@ -1,61 +0,0 @@ -package unconvert - -import ( - "sync" - - "github.com/golangci/unconvert" - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/lint/linter" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -const linterName = "unconvert" - -func New(settings *config.UnconvertSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []*goanalysis.Issue - - unconvert.SetFastMath(settings.FastMath) - unconvert.SetSafe(settings.Safe) - - return goanalysis. - NewLinterFromAnalyzer(&analysis.Analyzer{ - Name: linterName, - Doc: "Remove unnecessary type conversions", - Run: func(pass *analysis.Pass) (any, error) { - issues := runUnconvert(pass) - - if len(issues) == 0 { - return nil, nil - } - - mu.Lock() - resIssues = append(resIssues, issues...) - mu.Unlock() - - return nil, nil - }, - }). - WithIssuesReporter(func(*linter.Context) []*goanalysis.Issue { - return resIssues - }). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} - -func runUnconvert(pass *analysis.Pass) []*goanalysis.Issue { - positions := unconvert.Run(pass) - - var issues []*goanalysis.Issue - for _, position := range positions { - issues = append(issues, goanalysis.NewIssue(&result.Issue{ - Pos: position, - Text: "unnecessary conversion", - FromLinter: linterName, - }, pass)) - } - - return issues -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/unparam/unparam.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/unparam/unparam.go deleted file mode 100644 index b6cb2668b0..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/unparam/unparam.go +++ /dev/null @@ -1,60 +0,0 @@ -package unparam - -import ( - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/buildssa" - "golang.org/x/tools/go/packages" - "mvdan.cc/unparam/check" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.UnparamSettings) *goanalysis.Linter { - return goanalysis. - NewLinterFromAnalyzer(&analysis.Analyzer{ - Name: "unparam", - Doc: "Reports unused function parameters", - Requires: []*analysis.Analyzer{buildssa.Analyzer}, - Run: func(pass *analysis.Pass) (any, error) { - err := runUnparam(pass, settings) - if err != nil { - return nil, err - } - - return nil, nil - }, - }). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} - -func runUnparam(pass *analysis.Pass, settings *config.UnparamSettings) error { - ssa := pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA) - ssaPkg := ssa.Pkg - - pkg := &packages.Package{ - Fset: pass.Fset, - Syntax: pass.Files, - Types: pass.Pkg, - TypesInfo: pass.TypesInfo, - } - - c := &check.Checker{} - c.CheckExportedFuncs(settings.CheckExported) - c.Packages([]*packages.Package{pkg}) - c.ProgramSSA(ssaPkg.Prog) - - unparamIssues, err := c.Check() - if err != nil { - return err - } - - for _, i := range unparamIssues { - pass.Report(analysis.Diagnostic{ - Pos: i.Pos(), - Message: i.Message(), - }) - } - - return nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/unqueryvet/unqueryvet.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/unqueryvet/unqueryvet.go deleted file mode 100644 index db4a4d7522..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/unqueryvet/unqueryvet.go +++ /dev/null @@ -1,24 +0,0 @@ -package unqueryvet - -import ( - "github.com/MirrexOne/unqueryvet" - pkgconfig "github.com/MirrexOne/unqueryvet/pkg/config" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.UnqueryvetSettings) *goanalysis.Linter { - cfg := pkgconfig.DefaultSettings() - - if settings != nil { - cfg.CheckSQLBuilders = settings.CheckSQLBuilders - if len(settings.AllowedPatterns) > 0 { - cfg.AllowedPatterns = settings.AllowedPatterns - } - } - - return goanalysis. - NewLinterFromAnalyzer(unqueryvet.NewWithConfig(&cfg)). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/unused/unused.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/unused/unused.go deleted file mode 100644 index c0f4657dcc..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/unused/unused.go +++ /dev/null @@ -1,112 +0,0 @@ -package unused - -import ( - "fmt" - "sync" - - "golang.org/x/tools/go/analysis" - "honnef.co/go/tools/analysis/facts/directives" - "honnef.co/go/tools/analysis/facts/generated" - "honnef.co/go/tools/analysis/lint" - "honnef.co/go/tools/unused" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/lint/linter" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -const linterName = "unused" - -func New(settings *config.UnusedSettings) *goanalysis.Linter { - var mu sync.Mutex - var resIssues []*goanalysis.Issue - - analyzer := &analysis.Analyzer{ - Name: linterName, - Doc: unused.Analyzer.Analyzer.Doc, - Requires: unused.Analyzer.Analyzer.Requires, - Run: func(pass *analysis.Pass) (any, error) { - issues := runUnused(pass, settings) - if len(issues) == 0 { - return nil, nil - } - - mu.Lock() - resIssues = append(resIssues, issues...) - mu.Unlock() - - return nil, nil - }, - } - - return goanalysis.NewLinter( - linterName, - "Checks Go code for unused constants, variables, functions and types", - []*analysis.Analyzer{analyzer}, - nil, - ).WithIssuesReporter(func(_ *linter.Context) []*goanalysis.Issue { - return resIssues - }).WithLoadMode(goanalysis.LoadModeTypesInfo) -} - -func runUnused(pass *analysis.Pass, cfg *config.UnusedSettings) []*goanalysis.Issue { - res := getUnusedResults(pass, cfg) - - used := make(map[string]bool) - for _, obj := range res.Used { - used[fmt.Sprintf("%s %d %s", obj.Position.Filename, obj.Position.Line, obj.Name)] = true - } - - var issues []*goanalysis.Issue - - // Inspired by https://github.com/dominikh/go-tools/blob/d694aadcb1f50c2d8ac0a1dd06217ebb9f654764/lintcmd/lint.go#L177-L197 - for _, object := range res.Unused { - if object.Kind == "type param" { - continue - } - - key := fmt.Sprintf("%s %d %s", object.Position.Filename, object.Position.Line, object.Name) - if used[key] { - continue - } - - issue := goanalysis.NewIssue(&result.Issue{ - FromLinter: linterName, - Text: fmt.Sprintf("%s %s is unused", object.Kind, object.Name), - Pos: object.Position, - }, pass) - - issues = append(issues, issue) - } - - return issues -} - -func getUnusedResults(pass *analysis.Pass, settings *config.UnusedSettings) unused.Result { - opts := unused.Options{ - FieldWritesAreUses: settings.FieldWritesAreUses, - PostStatementsAreReads: settings.PostStatementsAreReads, - // Related to https://github.com/golangci/golangci-lint/issues/4218 - // https://github.com/dominikh/go-tools/issues/1474#issuecomment-1850760813 - ExportedIsUsed: true, - ExportedFieldsAreUsed: settings.ExportedFieldsAreUsed, - ParametersAreUsed: settings.ParametersAreUsed, - LocalVariablesAreUsed: settings.LocalVariablesAreUsed, - GeneratedIsUsed: settings.GeneratedIsUsed, - } - - // ref: https://github.com/dominikh/go-tools/blob/4ec1f474ca6c0feb8e10a8fcca4ab95f5b5b9881/internal/cmd/unused/unused.go#L68 - nodes := unused.Graph(pass.Fset, - pass.Files, - pass.Pkg, - pass.TypesInfo, - pass.ResultOf[directives.Analyzer].([]lint.Directive), - pass.ResultOf[generated.Analyzer].(map[string]generated.Generator), - opts, - ) - - sg := unused.SerializedGraph{} - sg.Merge(nodes) - return sg.Results() -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/usestdlibvars/usestdlibvars.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/usestdlibvars/usestdlibvars.go deleted file mode 100644 index e4a900ff64..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/usestdlibvars/usestdlibvars.go +++ /dev/null @@ -1,35 +0,0 @@ -package usestdlibvars - -import ( - "github.com/sashamelentyev/usestdlibvars/pkg/analyzer" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.UseStdlibVarsSettings) *goanalysis.Linter { - var cfg map[string]any - - if settings != nil { - cfg = map[string]any{ - analyzer.ConstantKindFlag: settings.ConstantKind, - analyzer.CryptoHashFlag: settings.CryptoHash, - analyzer.HTTPMethodFlag: settings.HTTPMethod, - analyzer.HTTPStatusCodeFlag: settings.HTTPStatusCode, - analyzer.OSDevNullFlag: false, // Noop because the linter ignore it. - analyzer.RPCDefaultPathFlag: settings.DefaultRPCPath, - analyzer.SQLIsolationLevelFlag: settings.SQLIsolationLevel, - analyzer.SyslogPriorityFlag: false, // Noop because the linter ignore it. - analyzer.TimeLayoutFlag: settings.TimeLayout, - analyzer.TimeMonthFlag: settings.TimeMonth, - analyzer.TimeWeekdayFlag: settings.TimeWeekday, - analyzer.TLSSignatureSchemeFlag: settings.TLSSignatureScheme, - analyzer.TimeDateMonthFlag: settings.TimeDateMonth, - } - } - - return goanalysis. - NewLinterFromAnalyzer(analyzer.New()). - WithConfig(cfg). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/usetesting/usetesting.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/usetesting/usetesting.go deleted file mode 100644 index 7371cc28eb..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/usetesting/usetesting.go +++ /dev/null @@ -1,29 +0,0 @@ -package usetesting - -import ( - "github.com/ldez/usetesting" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.UseTestingSettings) *goanalysis.Linter { - var cfg map[string]any - - if settings != nil { - cfg = map[string]any{ - "contextbackground": settings.ContextBackground, - "contexttodo": settings.ContextTodo, - "oschdir": settings.OSChdir, - "osmkdirtemp": settings.OSMkdirTemp, - "ossetenv": settings.OSSetenv, - "ostempdir": settings.OSTempDir, - "oscreatetemp": settings.OSCreateTemp, - } - } - - return goanalysis. - NewLinterFromAnalyzer(usetesting.NewAnalyzer()). - WithConfig(cfg). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/varnamelen/varnamelen.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/varnamelen/varnamelen.go deleted file mode 100644 index 349feefa07..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/varnamelen/varnamelen.go +++ /dev/null @@ -1,42 +0,0 @@ -package varnamelen - -import ( - "strconv" - "strings" - - "github.com/blizzy78/varnamelen" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.VarnamelenSettings) *goanalysis.Linter { - var cfg map[string]any - - if settings != nil { - cfg = map[string]any{ - "checkReceiver": strconv.FormatBool(settings.CheckReceiver), - "checkReturn": strconv.FormatBool(settings.CheckReturn), - "checkTypeParam": strconv.FormatBool(settings.CheckTypeParam), - "ignoreNames": strings.Join(settings.IgnoreNames, ","), - "ignoreTypeAssertOk": strconv.FormatBool(settings.IgnoreTypeAssertOk), - "ignoreMapIndexOk": strconv.FormatBool(settings.IgnoreMapIndexOk), - "ignoreChanRecvOk": strconv.FormatBool(settings.IgnoreChanRecvOk), - "ignoreDecls": strings.Join(settings.IgnoreDecls, ","), - } - - if settings.MaxDistance > 0 { - cfg["maxDistance"] = strconv.Itoa(settings.MaxDistance) - } - - if settings.MinNameLength > 0 { - cfg["minNameLength"] = strconv.Itoa(settings.MinNameLength) - } - } - - return goanalysis. - NewLinterFromAnalyzer(varnamelen.NewAnalyzer()). - WithDesc("checks that the length of a variable's name matches its scope"). - WithConfig(cfg). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/wastedassign/wastedassign.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/wastedassign/wastedassign.go deleted file mode 100644 index d103a8d5a5..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/wastedassign/wastedassign.go +++ /dev/null @@ -1,14 +0,0 @@ -package wastedassign - -import ( - "github.com/sanposhiho/wastedassign/v2" - - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - return goanalysis. - NewLinterFromAnalyzer(wastedassign.Analyzer). - WithDesc("Finds wasted assignment statements"). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/whitespace/whitespace.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/whitespace/whitespace.go deleted file mode 100644 index bf03e1d808..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/whitespace/whitespace.go +++ /dev/null @@ -1,22 +0,0 @@ -package whitespace - -import ( - "github.com/ultraware/whitespace" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.WhitespaceSettings) *goanalysis.Linter { - var wsSettings whitespace.Settings - if settings != nil { - wsSettings = whitespace.Settings{ - MultiIf: settings.MultiIf, - MultiFunc: settings.MultiFunc, - } - } - - return goanalysis. - NewLinterFromAnalyzer(whitespace.NewAnalyzer(&wsSettings)). - WithLoadMode(goanalysis.LoadModeSyntax) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/wrapcheck/wrapcheck.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/wrapcheck/wrapcheck.go deleted file mode 100644 index c29c509a80..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/wrapcheck/wrapcheck.go +++ /dev/null @@ -1,34 +0,0 @@ -package wrapcheck - -import ( - "github.com/tomarrell/wrapcheck/v2/wrapcheck" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New(settings *config.WrapcheckSettings) *goanalysis.Linter { - cfg := wrapcheck.NewDefaultConfig() - - if settings != nil { - cfg.ExtraIgnoreSigs = settings.ExtraIgnoreSigs - cfg.ReportInternalErrors = settings.ReportInternalErrors - - if len(settings.IgnoreSigs) != 0 { - cfg.IgnoreSigs = settings.IgnoreSigs - } - if len(settings.IgnoreSigRegexps) != 0 { - cfg.IgnoreSigRegexps = settings.IgnoreSigRegexps - } - if len(settings.IgnorePackageGlobs) != 0 { - cfg.IgnorePackageGlobs = settings.IgnorePackageGlobs - } - if len(settings.IgnoreInterfaceRegexps) != 0 { - cfg.IgnoreInterfaceRegexps = settings.IgnoreInterfaceRegexps - } - } - - return goanalysis. - NewLinterFromAnalyzer(wrapcheck.NewAnalyzer(cfg)). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/wsl/wsl.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/wsl/wsl.go deleted file mode 100644 index 4a5c6e19b4..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/wsl/wsl.go +++ /dev/null @@ -1,105 +0,0 @@ -package wsl - -import ( - "slices" - - wslv4 "github.com/bombsimon/wsl/v4" - wslv5 "github.com/bombsimon/wsl/v5" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/golinters/internal" -) - -// Deprecated: use NewV5 instead. -func NewV4(settings *config.WSLv4Settings) *goanalysis.Linter { - var conf *wslv4.Configuration - - if settings != nil { - conf = &wslv4.Configuration{ - StrictAppend: settings.StrictAppend, - AllowAssignAndCallCuddle: settings.AllowAssignAndCallCuddle, - AllowAssignAndAnythingCuddle: settings.AllowAssignAndAnythingCuddle, - AllowMultiLineAssignCuddle: settings.AllowMultiLineAssignCuddle, - ForceCaseTrailingWhitespaceLimit: settings.ForceCaseTrailingWhitespaceLimit, - AllowTrailingComment: settings.AllowTrailingComment, - AllowSeparatedLeadingComment: settings.AllowSeparatedLeadingComment, - AllowCuddleDeclaration: settings.AllowCuddleDeclaration, - AllowCuddleWithCalls: settings.AllowCuddleWithCalls, - AllowCuddleWithRHS: settings.AllowCuddleWithRHS, - ForceCuddleErrCheckAndAssign: settings.ForceCuddleErrCheckAndAssign, - AllowCuddleUsedInBlock: settings.AllowCuddleUsedInBlock, - ErrorVariableNames: settings.ErrorVariableNames, - ForceExclusiveShortDeclarations: settings.ForceExclusiveShortDeclarations, - IncludeGenerated: true, // force to true because golangci-lint already have a way to filter generated files. - } - } - - return goanalysis. - NewLinterFromAnalyzer(wslv4.NewAnalyzer(conf)). - WithLoadMode(goanalysis.LoadModeSyntax) -} - -// Only used the set YAML struct tags. -type v5YAML struct { - AllowFirstInBlock bool `yaml:"allow-first-in-block"` - AllowWholeBlock bool `yaml:"allow-whole-block"` - BranchMaxLines int `yaml:"branch-max-lines,omitempty"` - CaseMaxLines int `yaml:"case-max-lines,omitempty"` - Enable []string `yaml:"enable,omitempty"` - Disable []string `yaml:"disable,omitempty"` -} - -func Migration(old *config.WSLv4Settings) any { - if old == nil { - return nil - } - - cfg := v5YAML{ - AllowFirstInBlock: true, - AllowWholeBlock: false, - BranchMaxLines: 2, - CaseMaxLines: old.ForceCaseTrailingWhitespaceLimit, - } - - if !old.StrictAppend { - cfg.Disable = append(cfg.Disable, wslv5.CheckAppend.String()) - } - - if old.AllowAssignAndAnythingCuddle { - cfg.Disable = append(cfg.Disable, wslv5.CheckAssign.String()) - } - - if old.AllowMultiLineAssignCuddle { - internal.LinterLogger.Warnf("`allow-multiline-assign` is deprecated and always allowed in wsl >= v5") - } - - if old.AllowTrailingComment { - internal.LinterLogger.Warnf("`allow-trailing-comment` is deprecated and always allowed in wsl >= v5") - } - - if old.AllowSeparatedLeadingComment { - internal.LinterLogger.Warnf("`allow-separated-leading-comment` is deprecated and always allowed in wsl >= v5") - } - - if old.AllowCuddleDeclaration { - cfg.Disable = append(cfg.Disable, wslv5.CheckDecl.String()) - } - - if old.ForceCuddleErrCheckAndAssign { - cfg.Enable = append(cfg.Enable, wslv5.CheckErr.String()) - } - - if old.ForceExclusiveShortDeclarations { - cfg.Enable = append(cfg.Enable, wslv5.CheckAssignExclusive.String()) - } - - if !old.AllowAssignAndCallCuddle { - cfg.Enable = append(cfg.Enable, wslv5.CheckAssignExpr.String()) - } - - slices.Sort(cfg.Enable) - slices.Sort(cfg.Disable) - - return cfg -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/wsl/wsl_v5.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/wsl/wsl_v5.go deleted file mode 100644 index cb7b256283..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/wsl/wsl_v5.go +++ /dev/null @@ -1,34 +0,0 @@ -package wsl - -import ( - "github.com/bombsimon/wsl/v5" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/golinters/internal" -) - -func NewV5(settings *config.WSLv5Settings) *goanalysis.Linter { - var conf *wsl.Configuration - - if settings != nil { - checkSet, err := wsl.NewCheckSet(settings.Default, settings.Enable, settings.Disable) - if err != nil { - internal.LinterLogger.Fatalf("wsl: invalid check: %v", err) - } - - conf = &wsl.Configuration{ - IncludeGenerated: true, // force to true because golangci-lint already has a way to filter generated files. - AllowFirstInBlock: settings.AllowFirstInBlock, - AllowWholeBlock: settings.AllowWholeBlock, - BranchMaxLines: settings.BranchMaxLines, - CaseMaxLines: settings.CaseMaxLines, - Checks: checkSet, - } - } - - return goanalysis. - NewLinterFromAnalyzer(wsl.NewAnalyzer(conf)). - WithVersion(5). //nolint:mnd // It's the linter version. - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/zerologlint/zerologlint.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/zerologlint/zerologlint.go deleted file mode 100644 index 46832da96c..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/golinters/zerologlint/zerologlint.go +++ /dev/null @@ -1,13 +0,0 @@ -package zerologlint - -import ( - "github.com/ykadowak/zerologlint" - - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" -) - -func New() *goanalysis.Linter { - return goanalysis. - NewLinterFromAnalyzer(zerologlint.Analyzer). - WithLoadMode(goanalysis.LoadModeTypesInfo) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goutil/env.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goutil/env.go deleted file mode 100644 index 89e1634ca2..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goutil/env.go +++ /dev/null @@ -1,49 +0,0 @@ -package goutil - -import ( - "context" - "fmt" - "os" - "time" - - "github.com/ldez/grignotin/goenv" - - "github.com/golangci/golangci-lint/v2/pkg/logutils" -) - -type EnvKey string - -type Env struct { - vars map[string]string - log logutils.Log -} - -func NewEnv(log logutils.Log) *Env { - return &Env{ - vars: map[string]string{}, - log: log, - } -} - -func (e Env) Discover(ctx context.Context) error { - startedAt := time.Now() - - var err error - e.vars, err = goenv.Get(ctx, goenv.GOCACHE, goenv.GOROOT) - if err != nil { - return fmt.Errorf("%w", err) - } - - e.log.Infof("Read go env for %s: %#v", time.Since(startedAt), e.vars) - - return nil -} - -func (e Env) Get(k EnvKey) string { - envValue := os.Getenv(string(k)) - if envValue != "" { - return envValue - } - - return e.vars[string(k)] -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/goutil/version.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/goutil/version.go deleted file mode 100644 index 77e5b0f351..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/goutil/version.go +++ /dev/null @@ -1,73 +0,0 @@ -package goutil - -import ( - "fmt" - "go/version" - "regexp" - "runtime" - "strings" - - hcversion "github.com/hashicorp/go-version" -) - -func CheckGoVersion(goVersion string) error { - rv, err := CleanRuntimeVersion() - if err != nil { - return fmt.Errorf("clean runtime version: %w", err) - } - - langVersion := version.Lang(rv) - - runtimeVersion, err := hcversion.NewVersion(strings.TrimPrefix(langVersion, "go")) - if err != nil { - return err - } - - targetedVersion, err := hcversion.NewVersion(TrimGoVersion(goVersion)) - if err != nil { - return err - } - - if runtimeVersion.LessThan(targetedVersion) { - return fmt.Errorf("the Go language version (%s) used to build golangci-lint is lower than the targeted Go version (%s)", - langVersion, goVersion) - } - - return nil -} - -// TrimGoVersion Trims the Go version to keep only M.m. -// Since Go 1.21 the version inside the go.mod can be a patched version (ex: 1.21.0). -// The version can also include information which we want to remove (ex: 1.21alpha1) -// https://go.dev/doc/toolchain#versions -// This a problem with staticcheck and gocritic. -func TrimGoVersion(v string) string { - if v == "" { - return "" - } - - exp := regexp.MustCompile(`(\d\.\d+)(?:\.\d+|[a-z]+\d)`) - - if exp.MatchString(v) { - return exp.FindStringSubmatch(v)[1] - } - - return v -} - -func CleanRuntimeVersion() (string, error) { - return cleanRuntimeVersion(runtime.Version()) -} - -func cleanRuntimeVersion(rv string) (string, error) { - for part := range strings.FieldsSeq(rv) { - // Allow to handle: - // - GOEXPERIMENT -> "go1.23.0 X:boringcrypto" - // - devel -> "devel go1.24-e705a2d Wed Aug 7 01:16:42 2024 +0000 linux/amd64" - if strings.HasPrefix(part, "go1.") { - return part, nil - } - } - - return "", fmt.Errorf("invalid Go runtime version: %s", rv) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/context.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/context.go deleted file mode 100644 index e8e8cc366d..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/context.go +++ /dev/null @@ -1,60 +0,0 @@ -package lint - -import ( - "context" - "fmt" - - "github.com/golangci/golangci-lint/v2/internal/cache" - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/exitcodes" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis/load" - "github.com/golangci/golangci-lint/v2/pkg/lint/linter" - "github.com/golangci/golangci-lint/v2/pkg/logutils" -) - -type ContextBuilder struct { - cfg *config.Config - - pkgLoader *PackageLoader - - pkgCache *cache.Cache - - loadGuard *load.Guard -} - -func NewContextBuilder(cfg *config.Config, pkgLoader *PackageLoader, - pkgCache *cache.Cache, loadGuard *load.Guard, -) *ContextBuilder { - return &ContextBuilder{ - cfg: cfg, - pkgLoader: pkgLoader, - pkgCache: pkgCache, - loadGuard: loadGuard, - } -} - -func (cl *ContextBuilder) Build(ctx context.Context, log logutils.Log, linters []*linter.Config) (*linter.Context, error) { - pkgs, deduplicatedPkgs, err := cl.pkgLoader.Load(ctx, linters) - if err != nil { - return nil, fmt.Errorf("failed to load packages: %w", err) - } - - if len(deduplicatedPkgs) == 0 { - return nil, fmt.Errorf("%w: running `go mod tidy` may solve the problem", exitcodes.ErrNoGoFiles) - } - - ret := &linter.Context{ - Packages: deduplicatedPkgs, - - // At least `unused` linters works properly only on original (not deduplicated) packages, - // see https://github.com/golangci/golangci-lint/pull/585. - OriginalPackages: pkgs, - - Cfg: cl.cfg, - Log: log, - PkgCache: cl.pkgCache, - LoadGuard: cl.loadGuard, - } - - return ret, nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/linter/config.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/linter/config.go deleted file mode 100644 index 0287dece95..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/linter/config.go +++ /dev/null @@ -1,221 +0,0 @@ -package linter - -import ( - "bytes" - "fmt" - - "golang.org/x/tools/go/packages" - "gopkg.in/yaml.v3" - - "github.com/golangci/golangci-lint/v2/pkg/config" -) - -// LastLinter nolintlint must be last because it looks at the results of all the previous linters for unused nolint directives. -const LastLinter = "nolintlint" - -type DeprecationLevel int - -const ( - DeprecationNone DeprecationLevel = iota - DeprecationWarning - DeprecationError -) - -type Deprecation struct { - Since string - Message string - Replacement string - Level DeprecationLevel - ConfigSuggestion func() (string, error) -} - -type Config struct { - Linter Linter - Groups map[string]struct{} - - LoadMode packages.LoadMode - - AlternativeNames []string - - OriginalURL string // URL of original (not forked) repo, needed for autogenerated README - Internal bool // Internal linters cannot be disabled (ex: typecheck). - CanAutoFix bool - IsSlow bool - DoesChangeTypes bool - - Since string - Deprecation *Deprecation -} - -func NewConfig(linter Linter) *Config { - lc := &Config{ - Linter: linter, - } - return lc.WithLoadFiles() -} - -func (lc *Config) WithInternal() *Config { - lc.Internal = true - return lc -} - -func (lc *Config) ConsiderSlow() *Config { - lc.IsSlow = true - return lc -} - -func (lc *Config) IsSlowLinter() bool { - return lc.IsSlow -} - -func (lc *Config) WithLoadFiles() *Config { - lc.LoadMode |= packages.NeedName | packages.NeedFiles | packages.NeedCompiledGoFiles | packages.NeedModule - return lc -} - -func (lc *Config) WithLoadForGoAnalysis() *Config { - lc = lc.WithLoadFiles() - lc.LoadMode |= packages.NeedImports | packages.NeedDeps | packages.NeedExportFile | packages.NeedTypesSizes - lc.IsSlow = true - return lc -} - -func (lc *Config) WithGroups(names ...string) *Config { - if lc.Groups == nil { - lc.Groups = make(map[string]struct{}) - } - - for _, name := range names { - lc.Groups[name] = struct{}{} - } - - return lc -} - -func (lc *Config) FromGroup(name string) bool { - _, ok := lc.Groups[name] - return ok -} - -func (lc *Config) WithURL(url string) *Config { - lc.OriginalURL = url - return lc -} - -func (lc *Config) WithAlternativeNames(names ...string) *Config { - lc.AlternativeNames = names - return lc -} - -func (lc *Config) WithAutoFix() *Config { - lc.CanAutoFix = true - return lc -} - -func (lc *Config) WithChangeTypes() *Config { - lc.DoesChangeTypes = true - return lc -} - -func (lc *Config) WithSince(version string) *Config { - lc.Since = version - return lc -} - -func (lc *Config) Deprecated(message, version string, level DeprecationLevel, opts ...func(*Deprecation)) *Config { - lc.Deprecation = &Deprecation{ - Since: version, - Message: message, - Level: level, - } - - for _, opt := range opts { - opt(lc.Deprecation) - } - - return lc -} - -func (lc *Config) DeprecatedWarning(message, version string, opts ...func(*Deprecation)) *Config { - return lc.Deprecated(message, version, DeprecationWarning, opts...) -} - -func (lc *Config) DeprecatedError(message, version string, opts ...func(*Deprecation)) *Config { - return lc.Deprecated(message, version, DeprecationError, opts...) -} - -func (lc *Config) IsDeprecated() bool { - return lc.Deprecation != nil -} - -func (lc *Config) AllNames() []string { - return append([]string{lc.Name()}, lc.AlternativeNames...) -} - -func (lc *Config) Name() string { - return lc.Linter.Name() -} - -func (lc *Config) WithNoopFallback(cfg *config.Config, cond func(cfg *config.Config) error) *Config { - if err := cond(cfg); err != nil { - lc.Linter = NewNoop(lc.Linter, err.Error()) - lc.LoadMode = 0 - - return lc.WithLoadFiles() - } - - return lc -} - -func Replacement[T any](replacement string, mgr func(T) any, data T) func(*Deprecation) { - return func(d *Deprecation) { - if replacement == "" { - return - } - - d.Replacement = replacement - - if mgr == nil { - return - } - - d.ConfigSuggestion = func() (string, error) { - buf := bytes.NewBuffer([]byte{}) - - encoder := yaml.NewEncoder(buf) - encoder.SetIndent(2) - - suggestion := map[string]any{ - "linters": map[string]any{ - "enable": []string{ - d.Replacement, - }, - "settings": map[string]any{ - d.Replacement: mgr(data), - }, - }, - } - - err := encoder.Encode(suggestion) - if err != nil { - return "", fmt.Errorf("%s: invalid configuration: %w", d.Replacement, err) - } - - return buf.String(), nil - } - } -} - -func IsGoLowerThanGo122() func(cfg *config.Config) error { - return isGoLowerThanGo("1.22") -} - -func isGoLowerThanGo(v string) func(cfg *config.Config) error { - return func(cfg *config.Config) error { - if cfg == nil || config.IsGoGreaterThanOrEqual(cfg.Run.Go, v) { - return nil - } - - return fmt.Errorf("this linter is disabled because the Go version (%s) of your project is lower than Go %s", cfg.Run.Go, v) - } -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/linter/context.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/linter/context.go deleted file mode 100644 index cf463ea922..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/linter/context.go +++ /dev/null @@ -1,46 +0,0 @@ -package linter - -import ( - "go/ast" - - "golang.org/x/tools/go/packages" - - "github.com/golangci/golangci-lint/v2/internal/cache" - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis/load" - "github.com/golangci/golangci-lint/v2/pkg/logutils" -) - -type Context struct { - // Packages are deduplicated (test and normal packages) packages - Packages []*packages.Package - - // OriginalPackages aren't deduplicated: they contain both normal and test - // version for each of packages - OriginalPackages []*packages.Package - - Cfg *config.Config - Log logutils.Log - - PkgCache *cache.Cache - LoadGuard *load.Guard -} - -func (c *Context) Settings() *config.LintersSettings { - return &c.Cfg.Linters.Settings -} - -func (c *Context) ClearTypesInPackages() { - for _, p := range c.Packages { - clearTypes(p) - } - for _, p := range c.OriginalPackages { - clearTypes(p) - } -} - -func clearTypes(p *packages.Package) { - p.Types = nil - p.TypesInfo = nil - p.Syntax = []*ast.File{} -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/linter/linter.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/linter/linter.go deleted file mode 100644 index e6b484efbb..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/linter/linter.go +++ /dev/null @@ -1,67 +0,0 @@ -package linter - -import ( - "context" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -type Linter interface { - Run(ctx context.Context, lintCtx *Context) ([]*result.Issue, error) - Name() string - Desc() string -} - -type Noop struct { - name string - desc string - reason string - level DeprecationLevel -} - -func NewNoop(l Linter, reason string) Noop { - return Noop{ - name: l.Name(), - desc: l.Desc(), - reason: reason, - } -} - -func NewNoopDeprecated(name string, cfg *config.Config, level DeprecationLevel) Noop { - noop := Noop{ - name: name, - desc: "Deprecated", - reason: "This linter is fully inactivated: it will not produce any reports.", - level: level, - } - - if cfg.InternalCmdTest { - noop.reason = "" - } - - return noop -} - -func (n Noop) Run(_ context.Context, lintCtx *Context) ([]*result.Issue, error) { - if n.reason == "" { - return nil, nil - } - - switch n.level { - case DeprecationError: - lintCtx.Log.Errorf("%s: %s", n.name, n.reason) - default: - lintCtx.Log.Warnf("%s: %s", n.name, n.reason) - } - - return nil, nil -} - -func (n Noop) Name() string { - return n.name -} - -func (n Noop) Desc() string { - return n.desc -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb/builder_linter.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb/builder_linter.go deleted file mode 100644 index 6e9cef1d1b..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb/builder_linter.go +++ /dev/null @@ -1,739 +0,0 @@ -package lintersdb - -import ( - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/golinters" - "github.com/golangci/golangci-lint/v2/pkg/golinters/arangolint" - "github.com/golangci/golangci-lint/v2/pkg/golinters/asasalint" - "github.com/golangci/golangci-lint/v2/pkg/golinters/asciicheck" - "github.com/golangci/golangci-lint/v2/pkg/golinters/bidichk" - "github.com/golangci/golangci-lint/v2/pkg/golinters/bodyclose" - "github.com/golangci/golangci-lint/v2/pkg/golinters/canonicalheader" - "github.com/golangci/golangci-lint/v2/pkg/golinters/containedctx" - "github.com/golangci/golangci-lint/v2/pkg/golinters/contextcheck" - "github.com/golangci/golangci-lint/v2/pkg/golinters/copyloopvar" - "github.com/golangci/golangci-lint/v2/pkg/golinters/cyclop" - "github.com/golangci/golangci-lint/v2/pkg/golinters/decorder" - "github.com/golangci/golangci-lint/v2/pkg/golinters/depguard" - "github.com/golangci/golangci-lint/v2/pkg/golinters/dogsled" - "github.com/golangci/golangci-lint/v2/pkg/golinters/dupl" - "github.com/golangci/golangci-lint/v2/pkg/golinters/dupword" - "github.com/golangci/golangci-lint/v2/pkg/golinters/durationcheck" - "github.com/golangci/golangci-lint/v2/pkg/golinters/embeddedstructfieldcheck" - "github.com/golangci/golangci-lint/v2/pkg/golinters/err113" - "github.com/golangci/golangci-lint/v2/pkg/golinters/errcheck" - "github.com/golangci/golangci-lint/v2/pkg/golinters/errchkjson" - "github.com/golangci/golangci-lint/v2/pkg/golinters/errname" - "github.com/golangci/golangci-lint/v2/pkg/golinters/errorlint" - "github.com/golangci/golangci-lint/v2/pkg/golinters/exhaustive" - "github.com/golangci/golangci-lint/v2/pkg/golinters/exhaustruct" - "github.com/golangci/golangci-lint/v2/pkg/golinters/exptostd" - "github.com/golangci/golangci-lint/v2/pkg/golinters/fatcontext" - "github.com/golangci/golangci-lint/v2/pkg/golinters/forbidigo" - "github.com/golangci/golangci-lint/v2/pkg/golinters/forcetypeassert" - "github.com/golangci/golangci-lint/v2/pkg/golinters/funcorder" - "github.com/golangci/golangci-lint/v2/pkg/golinters/funlen" - "github.com/golangci/golangci-lint/v2/pkg/golinters/gci" - "github.com/golangci/golangci-lint/v2/pkg/golinters/ginkgolinter" - "github.com/golangci/golangci-lint/v2/pkg/golinters/gocheckcompilerdirectives" - "github.com/golangci/golangci-lint/v2/pkg/golinters/gochecknoglobals" - "github.com/golangci/golangci-lint/v2/pkg/golinters/gochecknoinits" - "github.com/golangci/golangci-lint/v2/pkg/golinters/gochecksumtype" - "github.com/golangci/golangci-lint/v2/pkg/golinters/gocognit" - "github.com/golangci/golangci-lint/v2/pkg/golinters/goconst" - "github.com/golangci/golangci-lint/v2/pkg/golinters/gocritic" - "github.com/golangci/golangci-lint/v2/pkg/golinters/gocyclo" - "github.com/golangci/golangci-lint/v2/pkg/golinters/godoclint" - "github.com/golangci/golangci-lint/v2/pkg/golinters/godot" - "github.com/golangci/golangci-lint/v2/pkg/golinters/godox" - "github.com/golangci/golangci-lint/v2/pkg/golinters/gofmt" - "github.com/golangci/golangci-lint/v2/pkg/golinters/gofumpt" - "github.com/golangci/golangci-lint/v2/pkg/golinters/goheader" - "github.com/golangci/golangci-lint/v2/pkg/golinters/goimports" - "github.com/golangci/golangci-lint/v2/pkg/golinters/golines" - "github.com/golangci/golangci-lint/v2/pkg/golinters/gomoddirectives" - "github.com/golangci/golangci-lint/v2/pkg/golinters/gomodguard" - "github.com/golangci/golangci-lint/v2/pkg/golinters/goprintffuncname" - "github.com/golangci/golangci-lint/v2/pkg/golinters/gosec" - "github.com/golangci/golangci-lint/v2/pkg/golinters/gosmopolitan" - "github.com/golangci/golangci-lint/v2/pkg/golinters/govet" - "github.com/golangci/golangci-lint/v2/pkg/golinters/grouper" - "github.com/golangci/golangci-lint/v2/pkg/golinters/iface" - "github.com/golangci/golangci-lint/v2/pkg/golinters/importas" - "github.com/golangci/golangci-lint/v2/pkg/golinters/inamedparam" - "github.com/golangci/golangci-lint/v2/pkg/golinters/ineffassign" - "github.com/golangci/golangci-lint/v2/pkg/golinters/interfacebloat" - "github.com/golangci/golangci-lint/v2/pkg/golinters/intrange" - "github.com/golangci/golangci-lint/v2/pkg/golinters/iotamixing" - "github.com/golangci/golangci-lint/v2/pkg/golinters/ireturn" - "github.com/golangci/golangci-lint/v2/pkg/golinters/lll" - "github.com/golangci/golangci-lint/v2/pkg/golinters/loggercheck" - "github.com/golangci/golangci-lint/v2/pkg/golinters/maintidx" - "github.com/golangci/golangci-lint/v2/pkg/golinters/makezero" - "github.com/golangci/golangci-lint/v2/pkg/golinters/mirror" - "github.com/golangci/golangci-lint/v2/pkg/golinters/misspell" - "github.com/golangci/golangci-lint/v2/pkg/golinters/mnd" - "github.com/golangci/golangci-lint/v2/pkg/golinters/modernize" - "github.com/golangci/golangci-lint/v2/pkg/golinters/musttag" - "github.com/golangci/golangci-lint/v2/pkg/golinters/nakedret" - "github.com/golangci/golangci-lint/v2/pkg/golinters/nestif" - "github.com/golangci/golangci-lint/v2/pkg/golinters/nilerr" - "github.com/golangci/golangci-lint/v2/pkg/golinters/nilnesserr" - "github.com/golangci/golangci-lint/v2/pkg/golinters/nilnil" - "github.com/golangci/golangci-lint/v2/pkg/golinters/nlreturn" - "github.com/golangci/golangci-lint/v2/pkg/golinters/noctx" - "github.com/golangci/golangci-lint/v2/pkg/golinters/noinlineerr" - "github.com/golangci/golangci-lint/v2/pkg/golinters/nolintlint" - "github.com/golangci/golangci-lint/v2/pkg/golinters/nonamedreturns" - "github.com/golangci/golangci-lint/v2/pkg/golinters/nosprintfhostport" - "github.com/golangci/golangci-lint/v2/pkg/golinters/paralleltest" - "github.com/golangci/golangci-lint/v2/pkg/golinters/perfsprint" - "github.com/golangci/golangci-lint/v2/pkg/golinters/prealloc" - "github.com/golangci/golangci-lint/v2/pkg/golinters/predeclared" - "github.com/golangci/golangci-lint/v2/pkg/golinters/promlinter" - "github.com/golangci/golangci-lint/v2/pkg/golinters/protogetter" - "github.com/golangci/golangci-lint/v2/pkg/golinters/reassign" - "github.com/golangci/golangci-lint/v2/pkg/golinters/recvcheck" - "github.com/golangci/golangci-lint/v2/pkg/golinters/revive" - "github.com/golangci/golangci-lint/v2/pkg/golinters/rowserrcheck" - "github.com/golangci/golangci-lint/v2/pkg/golinters/sloglint" - "github.com/golangci/golangci-lint/v2/pkg/golinters/spancheck" - "github.com/golangci/golangci-lint/v2/pkg/golinters/sqlclosecheck" - "github.com/golangci/golangci-lint/v2/pkg/golinters/staticcheck" - "github.com/golangci/golangci-lint/v2/pkg/golinters/swaggo" - "github.com/golangci/golangci-lint/v2/pkg/golinters/tagalign" - "github.com/golangci/golangci-lint/v2/pkg/golinters/tagliatelle" - "github.com/golangci/golangci-lint/v2/pkg/golinters/testableexamples" - "github.com/golangci/golangci-lint/v2/pkg/golinters/testifylint" - "github.com/golangci/golangci-lint/v2/pkg/golinters/testpackage" - "github.com/golangci/golangci-lint/v2/pkg/golinters/thelper" - "github.com/golangci/golangci-lint/v2/pkg/golinters/tparallel" - "github.com/golangci/golangci-lint/v2/pkg/golinters/unconvert" - "github.com/golangci/golangci-lint/v2/pkg/golinters/unparam" - "github.com/golangci/golangci-lint/v2/pkg/golinters/unqueryvet" - "github.com/golangci/golangci-lint/v2/pkg/golinters/unused" - "github.com/golangci/golangci-lint/v2/pkg/golinters/usestdlibvars" - "github.com/golangci/golangci-lint/v2/pkg/golinters/usetesting" - "github.com/golangci/golangci-lint/v2/pkg/golinters/varnamelen" - "github.com/golangci/golangci-lint/v2/pkg/golinters/wastedassign" - "github.com/golangci/golangci-lint/v2/pkg/golinters/whitespace" - "github.com/golangci/golangci-lint/v2/pkg/golinters/wrapcheck" - "github.com/golangci/golangci-lint/v2/pkg/golinters/wsl" - "github.com/golangci/golangci-lint/v2/pkg/golinters/zerologlint" - "github.com/golangci/golangci-lint/v2/pkg/lint/linter" -) - -// LinterBuilder builds the "internal" linters based on the configuration. -type LinterBuilder struct{} - -// NewLinterBuilder creates a new LinterBuilder. -func NewLinterBuilder() *LinterBuilder { - return &LinterBuilder{} -} - -// Build loads all the "internal" linters. -// The configuration is use for the linter settings. -func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) { - if cfg == nil { - return nil, nil - } - - placeholderReplacer := config.NewPlaceholderReplacer(cfg) - - // The linters are sorted in the alphabetical order (case-insensitive). - // When a new linter is added the version in `WithSince(...)` must be the next minor version of golangci-lint. - return []*linter.Config{ - linter.NewConfig(arangolint.New()). - WithSince("v2.2.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/Crocmagnon/arangolint"), - - linter.NewConfig(asasalint.New(&cfg.Linters.Settings.Asasalint)). - WithSince("v1.47.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/alingse/asasalint"), - - linter.NewConfig(asciicheck.New()). - WithSince("v1.26.0"). - WithURL("https://github.com/golangci/asciicheck"), - - linter.NewConfig(bidichk.New(&cfg.Linters.Settings.BiDiChk)). - WithSince("v1.43.0"). - WithURL("https://github.com/breml/bidichk"), - - linter.NewConfig(bodyclose.New()). - WithSince("v1.18.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/timakin/bodyclose"), - - linter.NewConfig(canonicalheader.New()). - WithSince("v1.58.0"). - WithLoadForGoAnalysis(). - WithAutoFix(). - WithURL("https://github.com/lasiar/canonicalheader"), - - linter.NewConfig(containedctx.New()). - WithSince("v1.44.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/sivchari/containedctx"), - - linter.NewConfig(contextcheck.New()). - WithSince("v1.43.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/kkHAIKE/contextcheck"), - - linter.NewConfig(copyloopvar.New(&cfg.Linters.Settings.CopyLoopVar)). - WithSince("v1.57.0"). - WithAutoFix(). - WithURL("https://github.com/karamaru-alpha/copyloopvar"). - WithNoopFallback(cfg, linter.IsGoLowerThanGo122()), - - linter.NewConfig(cyclop.New(&cfg.Linters.Settings.Cyclop)). - WithSince("v1.37.0"). - WithURL("https://github.com/bkielbasa/cyclop"), - - linter.NewConfig(decorder.New(&cfg.Linters.Settings.Decorder)). - WithSince("v1.44.0"). - WithURL("https://gitlab.com/bosi/decorder"), - - linter.NewConfig(depguard.New(&cfg.Linters.Settings.Depguard, placeholderReplacer)). - WithSince("v1.4.0"). - WithURL("https://github.com/OpenPeeDeeP/depguard"), - - linter.NewConfig(dogsled.New(&cfg.Linters.Settings.Dogsled)). - WithSince("v1.19.0"). - WithURL("https://github.com/alexkohler/dogsled"), - - linter.NewConfig(dupl.New(&cfg.Linters.Settings.Dupl)). - WithSince("v1.0.0"). - WithURL("https://github.com/mibk/dupl"), - - linter.NewConfig(dupword.New(&cfg.Linters.Settings.DupWord)). - WithSince("v1.50.0"). - WithAutoFix(). - WithURL("https://github.com/Abirdcfly/dupword"), - - linter.NewConfig(durationcheck.New()). - WithSince("v1.37.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/charithe/durationcheck"), - - linter.NewConfig(embeddedstructfieldcheck.New(&cfg.Linters.Settings.EmbeddedStructFieldCheck)). - WithSince("v2.2.0"). - WithURL("https://github.com/manuelarte/embeddedstructfieldcheck"), - - linter.NewConfig(errcheck.New(&cfg.Linters.Settings.Errcheck)). - WithGroups(config.GroupStandard). - WithSince("v1.0.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/kisielk/errcheck"), - - linter.NewConfig(errchkjson.New(&cfg.Linters.Settings.ErrChkJSON)). - WithSince("v1.44.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/breml/errchkjson"), - - linter.NewConfig(errname.New()). - WithSince("v1.42.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/Antonboom/errname"), - - linter.NewConfig(errorlint.New(&cfg.Linters.Settings.ErrorLint)). - WithSince("v1.32.0"). - WithLoadForGoAnalysis(). - WithAutoFix(). - WithURL("https://github.com/polyfloyd/go-errorlint"), - - linter.NewConfig(exhaustive.New(&cfg.Linters.Settings.Exhaustive)). - WithSince("v1.28.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/nishanths/exhaustive"), - - linter.NewConfig(exhaustruct.New(&cfg.Linters.Settings.Exhaustruct)). - WithSince("v1.46.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/GaijinEntertainment/go-exhaustruct"), - - linter.NewConfig(exptostd.New()). - WithSince("v1.63.0"). - WithLoadForGoAnalysis(). - WithAutoFix(). - WithURL("https://github.com/ldez/exptostd"), - - linter.NewConfig(forbidigo.New(&cfg.Linters.Settings.Forbidigo)). - WithSince("v1.34.0"). - // Strictly speaking, - // the additional information is only needed when forbidigoCfg.AnalyzeTypes is chosen by the user. - // But we don't know that here in all cases (sometimes config is not loaded), - // so we have to assume that it is needed to be on the safe side. - WithLoadForGoAnalysis(). - WithURL("https://github.com/ashanbrown/forbidigo"), - - linter.NewConfig(forcetypeassert.New()). - WithSince("v1.38.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/gostaticanalysis/forcetypeassert"), - - linter.NewConfig(funcorder.New(&cfg.Linters.Settings.FuncOrder)). - WithSince("v2.1.0"). - WithURL("https://github.com/manuelarte/funcorder"), - - linter.NewConfig(fatcontext.New(&cfg.Linters.Settings.Fatcontext)). - WithSince("v1.58.0"). - WithLoadForGoAnalysis(). - WithAutoFix(). - WithURL("https://github.com/Crocmagnon/fatcontext"), - - linter.NewConfig(funlen.New(&cfg.Linters.Settings.Funlen)). - WithSince("v1.18.0"). - WithURL("https://github.com/ultraware/funlen"), - - linter.NewConfig(gci.New(&cfg.Linters.Settings.Gci)). - WithSince("v1.30.0"). - WithAutoFix(). - WithURL("https://github.com/daixiang0/gci"), - - linter.NewConfig(ginkgolinter.New(&cfg.Linters.Settings.GinkgoLinter)). - WithSince("v1.51.0"). - WithLoadForGoAnalysis(). - WithAutoFix(). - WithURL("https://github.com/nunnatsa/ginkgolinter"), - - linter.NewConfig(gocheckcompilerdirectives.New()). - WithSince("v1.51.0"). - WithURL("https://github.com/leighmcculloch/gocheckcompilerdirectives"), - - linter.NewConfig(gochecknoglobals.New()). - WithSince("v1.12.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/leighmcculloch/gochecknoglobals"), - - linter.NewConfig(gochecknoinits.New()). - WithSince("v1.12.0"), - - linter.NewConfig(gochecksumtype.New(&cfg.Linters.Settings.GoChecksumType)). - WithSince("v1.55.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/alecthomas/go-check-sumtype"), - - linter.NewConfig(gocognit.New(&cfg.Linters.Settings.Gocognit)). - WithSince("v1.20.0"). - WithURL("https://github.com/uudashr/gocognit"), - - linter.NewConfig(goconst.New(&cfg.Linters.Settings.Goconst)). - WithSince("v1.0.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/jgautheron/goconst"), - - linter.NewConfig(gocritic.New(&cfg.Linters.Settings.Gocritic, placeholderReplacer)). - WithSince("v1.12.0"). - WithLoadForGoAnalysis(). - WithAutoFix(). - WithURL("https://github.com/go-critic/go-critic"), - - linter.NewConfig(gocyclo.New(&cfg.Linters.Settings.Gocyclo)). - WithSince("v1.0.0"). - WithURL("https://github.com/fzipp/gocyclo"), - - linter.NewConfig(godoclint.New(&cfg.Linters.Settings.Godoclint)). - WithSince("v2.5.0"). - WithURL("https://github.com/godoc-lint/godoc-lint"), - - linter.NewConfig(godot.New(&cfg.Linters.Settings.Godot)). - WithSince("v1.25.0"). - WithAutoFix(). - WithURL("https://github.com/tetafro/godot"), - - linter.NewConfig(godox.New(&cfg.Linters.Settings.Godox)). - WithSince("v1.19.0"). - WithURL("https://github.com/matoous/godox"), - - linter.NewConfig(err113.New()). - WithSince("v1.26.0"). - WithLoadForGoAnalysis(). - WithAutoFix(). - WithURL("https://github.com/Djarvur/go-err113"), - - linter.NewConfig(gofmt.New(&cfg.Linters.Settings.GoFmt)). - WithSince("v1.0.0"). - WithAutoFix(). - WithURL("https://pkg.go.dev/cmd/gofmt"), - - linter.NewConfig(gofumpt.New(&cfg.Linters.Settings.GoFumpt)). - WithSince("v1.28.0"). - WithAutoFix(). - WithURL("https://github.com/mvdan/gofumpt"), - - linter.NewConfig(golines.New(&cfg.Linters.Settings.GoLines)). - WithSince("v2.0.0"). - WithAutoFix(). - WithURL("https://github.com/segmentio/golines"), - - linter.NewConfig(goheader.New(&cfg.Linters.Settings.Goheader, placeholderReplacer)). - WithSince("v1.28.0"). - WithAutoFix(). - WithURL("https://github.com/denis-tingaikin/go-header"), - - linter.NewConfig(goimports.New(&cfg.Linters.Settings.GoImports)). - WithSince("v1.20.0"). - WithAutoFix(). - WithURL("https://pkg.go.dev/golang.org/x/tools/cmd/goimports"), - - linter.NewConfig(mnd.New(&cfg.Linters.Settings.Mnd)). - WithSince("v1.22.0"). - WithURL("https://github.com/tommy-muehle/go-mnd"), - - linter.NewConfig(modernize.New(&cfg.Linters.Settings.Modernize)). - WithSince("v2.6.0"). - WithLoadForGoAnalysis(). - WithURL("https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize"), - - linter.NewConfig(gomoddirectives.New(&cfg.Linters.Settings.GoModDirectives)). - WithSince("v1.39.0"). - WithURL("https://github.com/ldez/gomoddirectives"), - - linter.NewConfig(gomodguard.New(&cfg.Linters.Settings.Gomodguard)). - WithSince("v1.25.0"). - WithURL("https://github.com/ryancurrah/gomodguard"), - - linter.NewConfig(goprintffuncname.New()). - WithSince("v1.23.0"). - WithURL("https://github.com/golangci/go-printf-func-name"), - - linter.NewConfig(gosec.New(&cfg.Linters.Settings.Gosec)). - WithSince("v1.0.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/securego/gosec"), - - linter.NewConfig(gosmopolitan.New(&cfg.Linters.Settings.Gosmopolitan)). - WithSince("v1.53.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/xen0n/gosmopolitan"), - - linter.NewConfig(govet.New(&cfg.Linters.Settings.Govet)). - WithGroups(config.GroupStandard). - WithSince("v1.0.0"). - WithLoadForGoAnalysis(). - WithAutoFix(). - WithURL("https://pkg.go.dev/cmd/vet"), - - linter.NewConfig(grouper.New(&cfg.Linters.Settings.Grouper)). - WithSince("v1.44.0"). - WithURL("https://github.com/leonklingele/grouper"), - - linter.NewConfig(iface.New(&cfg.Linters.Settings.Iface)). - WithSince("v1.62.0"). - WithLoadForGoAnalysis(). - WithAutoFix(). - WithURL("https://github.com/uudashr/iface"), - - linter.NewConfig(importas.New(&cfg.Linters.Settings.ImportAs)). - WithSince("v1.38.0"). - WithLoadForGoAnalysis(). - WithAutoFix(). - WithURL("https://github.com/julz/importas"), - - linter.NewConfig(inamedparam.New(&cfg.Linters.Settings.Inamedparam)). - WithSince("v1.55.0"). - WithURL("https://github.com/macabu/inamedparam"), - - linter.NewConfig(ineffassign.New(&cfg.Linters.Settings.Ineffassign)). - WithGroups(config.GroupStandard). - WithSince("v1.0.0"). - WithURL("https://github.com/gordonklaus/ineffassign"), - - linter.NewConfig(interfacebloat.New(&cfg.Linters.Settings.InterfaceBloat)). - WithSince("v1.49.0"). - WithURL("https://github.com/sashamelentyev/interfacebloat"), - - linter.NewConfig(intrange.New()). - WithSince("v1.57.0"). - WithLoadForGoAnalysis(). - WithAutoFix(). - WithURL("https://github.com/ckaznocha/intrange"). - WithNoopFallback(cfg, linter.IsGoLowerThanGo122()), - - linter.NewConfig(iotamixing.New(&cfg.Linters.Settings.IotaMixing)). - WithSince("v2.5.0"). - WithURL("https://github.com/AdminBenni/iota-mixing"), - - linter.NewConfig(ireturn.New(&cfg.Linters.Settings.Ireturn)). - WithSince("v1.43.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/butuzov/ireturn"), - - linter.NewConfig(lll.New(&cfg.Linters.Settings.Lll)). - WithSince("v1.8.0"), - - linter.NewConfig(loggercheck.New(&cfg.Linters.Settings.LoggerCheck)). - WithSince("v1.49.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/timonwong/loggercheck"), - - linter.NewConfig(maintidx.New(&cfg.Linters.Settings.MaintIdx)). - WithSince("v1.44.0"). - WithURL("https://github.com/yagipy/maintidx"), - - linter.NewConfig(makezero.New(&cfg.Linters.Settings.Makezero)). - WithSince("v1.34.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/ashanbrown/makezero"), - - linter.NewConfig(mirror.New()). - WithSince("v1.53.0"). - WithLoadForGoAnalysis(). - WithAutoFix(). - WithURL("https://github.com/butuzov/mirror"), - - linter.NewConfig(misspell.New(&cfg.Linters.Settings.Misspell)). - WithSince("v1.8.0"). - WithAutoFix(). - WithURL("https://github.com/golangci/misspell"), - - linter.NewConfig(musttag.New(&cfg.Linters.Settings.MustTag)). - WithSince("v1.51.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/go-simpler/musttag"), - - linter.NewConfig(nakedret.New(&cfg.Linters.Settings.Nakedret)). - WithSince("v1.19.0"). - WithAutoFix(). - WithURL("https://github.com/alexkohler/nakedret"), - - linter.NewConfig(nestif.New(&cfg.Linters.Settings.Nestif)). - WithSince("v1.25.0"). - WithURL("https://github.com/nakabonne/nestif"), - - linter.NewConfig(nilerr.New()). - WithSince("v1.38.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/gostaticanalysis/nilerr"), - - linter.NewConfig(nilnesserr.New()). - WithSince("v1.63.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/alingse/nilnesserr"), - - linter.NewConfig(nilnil.New(&cfg.Linters.Settings.NilNil)). - WithSince("v1.43.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/Antonboom/nilnil"), - - linter.NewConfig(nlreturn.New(&cfg.Linters.Settings.Nlreturn)). - WithSince("v1.30.0"). - WithAutoFix(). - WithURL("https://github.com/ssgreg/nlreturn"), - - linter.NewConfig(noctx.New()). - WithSince("v1.28.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/sonatard/noctx"), - - linter.NewConfig(noinlineerr.New()). - WithSince("v2.2.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/AlwxSin/noinlineerr"), - - linter.NewConfig(nonamedreturns.New(&cfg.Linters.Settings.NoNamedReturns)). - WithSince("v1.46.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/firefart/nonamedreturns"), - - linter.NewConfig(nosprintfhostport.New()). - WithSince("v1.46.0"). - WithURL("https://github.com/stbenjam/no-sprintf-host-port"), - - linter.NewConfig(paralleltest.New(&cfg.Linters.Settings.ParallelTest)). - WithSince("v1.33.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/kunwardeep/paralleltest"), - - linter.NewConfig(perfsprint.New(&cfg.Linters.Settings.PerfSprint)). - WithSince("v1.55.0"). - WithLoadForGoAnalysis(). - WithAutoFix(). - WithURL("https://github.com/catenacyber/perfsprint"), - - linter.NewConfig(prealloc.New(&cfg.Linters.Settings.Prealloc)). - WithSince("v1.19.0"). - WithURL("https://github.com/alexkohler/prealloc"), - - linter.NewConfig(predeclared.New(&cfg.Linters.Settings.Predeclared)). - WithSince("v1.35.0"). - WithURL("https://github.com/nishanths/predeclared"), - - linter.NewConfig(promlinter.New(&cfg.Linters.Settings.Promlinter)). - WithSince("v1.40.0"). - WithURL("https://github.com/yeya24/promlinter"), - - linter.NewConfig(protogetter.New(&cfg.Linters.Settings.ProtoGetter)). - WithSince("v1.55.0"). - WithLoadForGoAnalysis(). - WithAutoFix(). - WithURL("https://github.com/ghostiam/protogetter"), - - linter.NewConfig(reassign.New(&cfg.Linters.Settings.Reassign)). - WithSince("v1.49.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/curioswitch/go-reassign"), - - linter.NewConfig(recvcheck.New(&cfg.Linters.Settings.Recvcheck)). - WithSince("v1.62.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/raeperd/recvcheck"), - - linter.NewConfig(revive.New(&cfg.Linters.Settings.Revive)). - WithSince("v1.37.0"). - ConsiderSlow(). - WithAutoFix(). - WithURL("https://github.com/mgechev/revive"), - - linter.NewConfig(rowserrcheck.New(&cfg.Linters.Settings.RowsErrCheck)). - WithSince("v1.23.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/jingyugao/rowserrcheck"), - - linter.NewConfig(sloglint.New(&cfg.Linters.Settings.SlogLint)). - WithSince("v1.55.0"). - WithLoadForGoAnalysis(). - WithAutoFix(). - WithURL("https://github.com/go-simpler/sloglint"), - - linter.NewConfig(sqlclosecheck.New()). - WithSince("v1.28.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/ryanrolds/sqlclosecheck"), - - linter.NewConfig(spancheck.New(&cfg.Linters.Settings.Spancheck)). - WithSince("v1.56.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/jjti/go-spancheck"), - - linter.NewConfig(staticcheck.New(&cfg.Linters.Settings.Staticcheck)). - WithGroups(config.GroupStandard). - WithSince("v1.0.0"). - WithLoadForGoAnalysis(). - WithAutoFix(). - WithURL("https://github.com/dominikh/go-tools"), - - linter.NewConfig(swaggo.New()). - WithSince("v2.2.0"). - WithAutoFix(). - WithURL("https://github.com/swaggo/swaggo"), - - linter.NewConfig(tagalign.New(&cfg.Linters.Settings.TagAlign)). - WithSince("v1.53.0"). - WithAutoFix(). - WithURL("https://github.com/4meepo/tagalign"), - - linter.NewConfig(tagliatelle.New(&cfg.Linters.Settings.Tagliatelle)). - WithSince("v1.40.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/ldez/tagliatelle"), - - linter.NewConfig(testableexamples.New()). - WithSince("v1.50.0"). - WithURL("https://github.com/maratori/testableexamples"), - - linter.NewConfig(testifylint.New(&cfg.Linters.Settings.Testifylint)). - WithSince("v1.55.0"). - WithLoadForGoAnalysis(). - WithAutoFix(). - WithURL("https://github.com/Antonboom/testifylint"), - - linter.NewConfig(testpackage.New(&cfg.Linters.Settings.Testpackage)). - WithSince("v1.25.0"). - WithURL("https://github.com/maratori/testpackage"), - - linter.NewConfig(thelper.New(&cfg.Linters.Settings.Thelper)). - WithSince("v1.34.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/kulti/thelper"), - - linter.NewConfig(tparallel.New()). - WithSince("v1.32.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/moricho/tparallel"), - - linter.NewConfig(golinters.NewTypecheck()). - WithInternal(). - WithSince("v1.3.0"), - - linter.NewConfig(unconvert.New(&cfg.Linters.Settings.Unconvert)). - WithSince("v1.0.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/mdempsky/unconvert"), - - linter.NewConfig(unparam.New(&cfg.Linters.Settings.Unparam)). - WithSince("v1.9.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/mvdan/unparam"), - - linter.NewConfig(unqueryvet.New(&cfg.Linters.Settings.Unqueryvet)). - WithSince("v2.5.0"). - WithURL("https://github.com/MirrexOne/unqueryvet"), - - linter.NewConfig(unused.New(&cfg.Linters.Settings.Unused)). - WithGroups(config.GroupStandard). - WithSince("v1.20.0"). - WithLoadForGoAnalysis(). - ConsiderSlow(). - WithChangeTypes(). - WithURL("https://github.com/dominikh/go-tools/tree/HEAD/unused"), - - linter.NewConfig(usestdlibvars.New(&cfg.Linters.Settings.UseStdlibVars)). - WithSince("v1.48.0"). - WithAutoFix(). - WithURL("https://github.com/sashamelentyev/usestdlibvars"), - - linter.NewConfig(usetesting.New(&cfg.Linters.Settings.UseTesting)). - WithSince("v1.63.0"). - WithLoadForGoAnalysis(). - WithAutoFix(). - WithURL("https://github.com/ldez/usetesting"), - - linter.NewConfig(varnamelen.New(&cfg.Linters.Settings.Varnamelen)). - WithSince("v1.43.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/blizzy78/varnamelen"), - - linter.NewConfig(wastedassign.New()). - WithSince("v1.38.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/sanposhiho/wastedassign"), - - linter.NewConfig(whitespace.New(&cfg.Linters.Settings.Whitespace)). - WithSince("v1.19.0"). - WithAutoFix(). - WithURL("https://github.com/ultraware/whitespace"), - - linter.NewConfig(wrapcheck.New(&cfg.Linters.Settings.Wrapcheck)). - WithSince("v1.32.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/tomarrell/wrapcheck"), - - linter.NewConfig(wsl.NewV4(&cfg.Linters.Settings.WSL)). - DeprecatedWarning("new major version.", "v2.2.0", - linter.Replacement("wsl_v5", wsl.Migration, &cfg.Linters.Settings.WSL)). - WithSince("v1.20.0"). - WithAutoFix(). - WithURL("https://github.com/bombsimon/wsl"), - - linter.NewConfig(wsl.NewV5(&cfg.Linters.Settings.WSLv5)). - WithSince("v2.2.0"). - WithLoadForGoAnalysis(). - WithAutoFix(). - WithURL("https://github.com/bombsimon/wsl"), - - linter.NewConfig(zerologlint.New()). - WithSince("v1.53.0"). - WithLoadForGoAnalysis(). - WithURL("https://github.com/ykadowak/zerologlint"), - - // nolintlint must be last because it looks at the results of all the previous linters for unused nolint directives - linter.NewConfig(nolintlint.New(&cfg.Linters.Settings.NoLintLint)). - WithSince("v1.26.0"). - WithAutoFix(). - WithURL("https://github.com/golangci/golangci-lint/tree/HEAD/pkg/golinters/nolintlint/internal"), - }, nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb/builder_plugin_go.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb/builder_plugin_go.go deleted file mode 100644 index 005ca61698..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb/builder_plugin_go.go +++ /dev/null @@ -1,143 +0,0 @@ -package lintersdb - -import ( - "context" - "errors" - "fmt" - "path/filepath" - "plugin" - - "golang.org/x/tools/go/analysis" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/fsutils" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/lint/linter" - "github.com/golangci/golangci-lint/v2/pkg/logutils" -) - -const goPluginType = "goplugin" - -type AnalyzerPlugin interface { - GetAnalyzers() []*analysis.Analyzer -} - -// PluginGoBuilder builds the custom linters (Go plugin) based on the configuration. -type PluginGoBuilder struct { - log logutils.Log -} - -// NewPluginGoBuilder creates new PluginGoBuilder. -func NewPluginGoBuilder(log logutils.Log) *PluginGoBuilder { - return &PluginGoBuilder{log: log} -} - -// Build loads custom linters that are specified in the golangci-lint config file. -func (b *PluginGoBuilder) Build(cfg *config.Config) ([]*linter.Config, error) { - if cfg == nil || b.log == nil { - return nil, nil - } - - var linters []*linter.Config - - for name, settings := range cfg.Linters.Settings.Custom { - if settings.Type != goPluginType && settings.Type != "" { - continue - } - - lc, err := b.loadConfig(cfg, name, &settings) - if err != nil { - return nil, fmt.Errorf("unable to load custom analyzer %q: %s, %w", name, settings.Path, err) - } - linters = append(linters, lc) - } - - return linters, nil -} - -// loadConfig loads the configuration of private linters. -// Private linters are dynamically loaded from .so plugin files. -func (b *PluginGoBuilder) loadConfig(cfg *config.Config, name string, settings *config.CustomLinterSettings) (*linter.Config, error) { - analyzers, err := b.getAnalyzerPlugin(cfg, settings.Path, settings.Settings) - if err != nil { - return nil, err - } - - b.log.Infof("Loaded %s: %s", settings.Path, name) - - customLinter := goanalysis.NewLinter(name, settings.Description, analyzers, nil). - WithLoadMode(goanalysis.LoadModeTypesInfo) - - linterConfig := linter.NewConfig(customLinter). - WithGroups(config.GroupStandard). - WithLoadForGoAnalysis(). - WithURL(settings.OriginalURL) - - return linterConfig, nil -} - -// getAnalyzerPlugin loads a private linter as specified in the config file, -// loads the plugin from a .so file, -// and returns the 'AnalyzerPlugin' interface implemented by the private plugin. -// An error is returned if the private linter cannot be loaded -// or the linter does not implement the AnalyzerPlugin interface. -func (b *PluginGoBuilder) getAnalyzerPlugin(cfg *config.Config, path string, settings any) ([]*analysis.Analyzer, error) { - if !filepath.IsAbs(path) { - basePath, err := fsutils.GetBasePath(context.Background(), cfg.Run.RelativePathMode, cfg.GetConfigDir()) - if err != nil { - return nil, fmt.Errorf("get base path: %w", err) - } - - // resolve non-absolute paths relative to config file's directory - path = filepath.Join(basePath, path) - } - - plug, err := plugin.Open(path) - if err != nil { - return nil, err - } - - analyzers, err := b.lookupPlugin(plug, settings) - if err != nil { - return nil, fmt.Errorf("lookup plugin %s: %w", path, err) - } - - return analyzers, nil -} - -func (b *PluginGoBuilder) lookupPlugin(plug *plugin.Plugin, settings any) ([]*analysis.Analyzer, error) { - symbol, err := plug.Lookup("New") - if err != nil { - analyzers, errP := b.lookupAnalyzerPlugin(plug) - if errP != nil { - return nil, errors.Join(err, errP) - } - - return analyzers, nil - } - - // The type func cannot be used here, must be the explicit signature. - constructor, ok := symbol.(func(any) ([]*analysis.Analyzer, error)) - if !ok { - return nil, fmt.Errorf("plugin does not abide by 'New' function: %T", symbol) - } - - return constructor(settings) -} - -func (b *PluginGoBuilder) lookupAnalyzerPlugin(plug *plugin.Plugin) ([]*analysis.Analyzer, error) { - symbol, err := plug.Lookup("AnalyzerPlugin") - if err != nil { - return nil, err - } - - b.log.Warnf("plugin: 'AnalyzerPlugin' plugins are deprecated, please use the new plugin signature: " + - "https://golangci-lint.run/docs/plugins/go-plugins#create-a-plugin") - - analyzerPlugin, ok := symbol.(AnalyzerPlugin) - if !ok { - return nil, fmt.Errorf("plugin does not abide by 'AnalyzerPlugin' interface: %T", symbol) - } - - return analyzerPlugin.GetAnalyzers(), nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb/builder_plugin_module.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb/builder_plugin_module.go deleted file mode 100644 index 71a01302d9..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb/builder_plugin_module.go +++ /dev/null @@ -1,85 +0,0 @@ -package lintersdb - -import ( - "fmt" - "strings" - - "github.com/golangci/plugin-module-register/register" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/lint/linter" - "github.com/golangci/golangci-lint/v2/pkg/logutils" -) - -const modulePluginType = "module" - -// PluginModuleBuilder builds the custom linters (module plugin) based on the configuration. -type PluginModuleBuilder struct { - log logutils.Log -} - -// NewPluginModuleBuilder creates new PluginModuleBuilder. -func NewPluginModuleBuilder(log logutils.Log) *PluginModuleBuilder { - return &PluginModuleBuilder{log: log} -} - -// Build loads custom linters that are specified in the golangci-lint config file. -func (b *PluginModuleBuilder) Build(cfg *config.Config) ([]*linter.Config, error) { - if cfg == nil || b.log == nil { - return nil, nil - } - - var linters []*linter.Config - - for name, settings := range cfg.Linters.Settings.Custom { - if settings.Type != modulePluginType { - continue - } - - b.log.Infof("Loaded %s: %s", settings.Path, name) - - newPlugin, err := register.GetPlugin(name) - if err != nil { - return nil, fmt.Errorf("plugin(%s): %w", name, err) - } - - p, err := newPlugin(settings.Settings) - if err != nil { - return nil, fmt.Errorf("plugin(%s): newPlugin %w", name, err) - } - - analyzers, err := p.BuildAnalyzers() - if err != nil { - return nil, fmt.Errorf("plugin(%s): BuildAnalyzers %w", name, err) - } - - customLinter := goanalysis.NewLinter(name, settings.Description, analyzers, nil) - - switch strings.ToLower(p.GetLoadMode()) { - case register.LoadModeSyntax: - customLinter = customLinter.WithLoadMode(goanalysis.LoadModeSyntax) - case register.LoadModeTypesInfo: - customLinter = customLinter.WithLoadMode(goanalysis.LoadModeTypesInfo) - default: - customLinter = customLinter.WithLoadMode(goanalysis.LoadModeTypesInfo) - } - - lc := linter.NewConfig(customLinter). - WithGroups(config.GroupStandard). - WithURL(settings.OriginalURL) - - switch strings.ToLower(p.GetLoadMode()) { - case register.LoadModeSyntax: - // noop - case register.LoadModeTypesInfo: - lc = lc.WithLoadForGoAnalysis() - default: - lc = lc.WithLoadForGoAnalysis() - } - - linters = append(linters, lc) - } - - return linters, nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb/manager.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb/manager.go deleted file mode 100644 index 9750301bfc..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb/manager.go +++ /dev/null @@ -1,291 +0,0 @@ -package lintersdb - -import ( - "cmp" - "fmt" - "maps" - "os" - "slices" - "sort" - "strings" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis" - "github.com/golangci/golangci-lint/v2/pkg/goformatters" - "github.com/golangci/golangci-lint/v2/pkg/lint/linter" - "github.com/golangci/golangci-lint/v2/pkg/logutils" -) - -type Builder interface { - Build(cfg *config.Config) ([]*linter.Config, error) -} - -// Manager is a type of database for all linters (internals or plugins). -// It provides methods to access to the linter sets. -type Manager struct { - log logutils.Log - debugf logutils.DebugFunc - - cfg *config.Config - - linters []*linter.Config - - nameToLCs map[string][]*linter.Config -} - -// NewManager creates a new Manager. -// This constructor will call the builders to build and store the linters. -func NewManager(log logutils.Log, cfg *config.Config, builders ...Builder) (*Manager, error) { - m := &Manager{ - log: log, - debugf: logutils.Debug(logutils.DebugKeyEnabledLinters), - nameToLCs: make(map[string][]*linter.Config), - } - - m.cfg = cfg - if cfg == nil { - m.cfg = config.NewDefault() - } - - for _, builder := range builders { - linters, err := builder.Build(m.cfg) - if err != nil { - return nil, fmt.Errorf("build linters: %w", err) - } - - m.linters = append(m.linters, linters...) - } - - for _, lc := range m.linters { - for _, name := range lc.AllNames() { - m.nameToLCs[name] = append(m.nameToLCs[name], lc) - } - } - - err := NewValidator(m).Validate(m.cfg) - if err != nil { - return nil, err - } - - return m, nil -} - -func (m *Manager) GetLinterConfigs(name string) []*linter.Config { - return m.nameToLCs[name] -} - -func (m *Manager) GetAllSupportedLinterConfigs() []*linter.Config { - return m.linters -} - -func (m *Manager) GetEnabledLintersMap() (map[string]*linter.Config, error) { - enabledLinters, err := m.build() - if err != nil { - return nil, err - } - - if os.Getenv(logutils.EnvTestRun) == "1" { - m.verbosePrintLintersStatus(enabledLinters) - } - - return enabledLinters, nil -} - -// GetOptimizedLinters returns enabled linters after optimization (merging) of multiple linters into a fewer number of linters. -// E.g. some go/analysis linters can be optimized into one metalinter for data reuse and speed up. -func (m *Manager) GetOptimizedLinters() ([]*linter.Config, error) { - resultLintersSet, err := m.build() - if err != nil { - return nil, err - } - - m.verbosePrintLintersStatus(resultLintersSet) - - m.combineGoAnalysisLinters(resultLintersSet) - - // Make order of execution of linters (go/analysis metalinter and unused) stable. - resultLinters := slices.SortedFunc(maps.Values(resultLintersSet), func(a *linter.Config, b *linter.Config) int { - if b.Name() == linter.LastLinter { - return -1 - } - - if a.Name() == linter.LastLinter { - return 1 - } - - if a.DoesChangeTypes != b.DoesChangeTypes { - // move type-changing linters to the end to optimize speed - if b.DoesChangeTypes { - return -1 - } - return 1 - } - - return strings.Compare(a.Name(), b.Name()) - }) - - return resultLinters, nil -} - -//nolint:gocyclo // the complexity cannot be reduced. -func (m *Manager) build() (map[string]*linter.Config, error) { - m.debugf("Linters config: %#v", m.cfg.Linters) - - resultLintersSet := map[string]*linter.Config{} - - groupName := cmp.Or(m.cfg.Linters.Default, config.GroupStandard) - - switch groupName { - case config.GroupNone: - // no default linters - - case config.GroupAll: - resultLintersSet = linterConfigsToMap(m.linters) - - case config.GroupFast: - var selected []*linter.Config - for _, lc := range m.linters { - if lc.IsSlowLinter() { - continue - } - - selected = append(selected, lc) - } - - resultLintersSet = linterConfigsToMap(selected) - - case config.GroupStandard: - var selected []*linter.Config - for _, lc := range m.linters { - if !lc.FromGroup(config.GroupStandard) { - continue - } - - selected = append(selected, lc) - } - - resultLintersSet = linterConfigsToMap(selected) - - default: - return nil, fmt.Errorf("unknown group: %s", groupName) - } - - for _, name := range slices.Concat(m.cfg.Linters.Enable, m.cfg.Formatters.Enable) { - for _, lc := range m.GetLinterConfigs(name) { - // it's important to use lc.Name() nor name because name can be alias - resultLintersSet[lc.Name()] = lc - } - } - - for _, name := range m.cfg.Linters.Disable { - for _, lc := range m.GetLinterConfigs(name) { - // it's important to use lc.Name() nor name because name can be alias - delete(resultLintersSet, lc.Name()) - } - } - - if m.cfg.Linters.FastOnly { - for lc := range maps.Values(resultLintersSet) { - if lc.IsSlowLinter() { - // it's important to use lc.Name() nor name because name can be alias - delete(resultLintersSet, lc.Name()) - } - } - } - - // typecheck is not a real linter and cannot be disabled. - if _, ok := resultLintersSet["typecheck"]; !ok && (m.cfg == nil || !m.cfg.InternalCmdTest) { - for _, lc := range m.GetLinterConfigs("typecheck") { - // it's important to use lc.Name() nor name because name can be alias - resultLintersSet[lc.Name()] = lc - } - } - - return resultLintersSet, nil -} - -func (m *Manager) combineGoAnalysisLinters(linters map[string]*linter.Config) { - mlConfig := &linter.Config{} - - var goanalysisLinters []*goanalysis.Linter - - for _, lc := range linters { - lnt, ok := lc.Linter.(*goanalysis.Linter) - if !ok { - continue - } - - if lnt.LoadMode() == goanalysis.LoadModeWholeProgram { - // It's ineffective by CPU and memory to run whole-program and incremental analyzers at once. - continue - } - - mlConfig.LoadMode |= lc.LoadMode - - if lc.IsSlowLinter() { - mlConfig.ConsiderSlow() - } - - goanalysisLinters = append(goanalysisLinters, lnt) - } - - if len(goanalysisLinters) <= 1 { - m.debugf("Didn't combine go/analysis linters: got only %d linters", len(goanalysisLinters)) - return - } - - for _, lnt := range goanalysisLinters { - delete(linters, lnt.Name()) - } - - // Make order of execution of go/analysis analyzers stable. - sort.Slice(goanalysisLinters, func(i, j int) bool { - a, b := goanalysisLinters[i], goanalysisLinters[j] - - if b.Name() == linter.LastLinter { - return true - } - - if a.Name() == linter.LastLinter { - return false - } - - return a.Name() <= b.Name() - }) - - mlConfig.Linter = goanalysis.NewMetaLinter(goanalysisLinters) - - linters[mlConfig.Linter.Name()] = mlConfig - - m.debugf("Combined %d go/analysis linters into one metalinter", len(goanalysisLinters)) -} - -func (m *Manager) verbosePrintLintersStatus(lcs map[string]*linter.Config) { - var linterNames []string - for _, lc := range lcs { - if lc.Internal { - continue - } - - linterNames = append(linterNames, lc.Name()) - } - sort.Strings(linterNames) - m.log.Infof("Active %d linters: %s", len(linterNames), linterNames) -} - -func linterConfigsToMap(lcs []*linter.Config) map[string]*linter.Config { - ret := map[string]*linter.Config{} - for _, lc := range lcs { - if lc.IsDeprecated() && lc.Deprecation.Level > linter.DeprecationWarning { - continue - } - - if goformatters.IsFormatter(lc.Name()) { - continue - } - - ret[lc.Name()] = lc - } - - return ret -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb/validator.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb/validator.go deleted file mode 100644 index 34a6c63f91..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb/validator.go +++ /dev/null @@ -1,100 +0,0 @@ -package lintersdb - -import ( - "fmt" - "os" - "strings" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/lint/linter" - "github.com/golangci/golangci-lint/v2/pkg/logutils" -) - -type Validator struct { - m *Manager -} - -func NewValidator(m *Manager) *Validator { - return &Validator{m: m} -} - -// Validate validates the configuration by calling all other validators for different -// sections in the configuration and then some additional linter validation functions. -func (v Validator) Validate(cfg *config.Config) error { - validators := []func(cfg *config.Linters) error{ - v.validateLintersNames, - v.alternativeNamesDeprecation, - } - - for _, v := range validators { - if err := v(&cfg.Linters); err != nil { - return err - } - } - - return nil -} - -func (v Validator) validateLintersNames(cfg *config.Linters) error { - var unknownNames []string - - for _, name := range cfg.Enable { - if v.m.GetLinterConfigs(name) == nil { - unknownNames = append(unknownNames, name) - } - } - - for _, name := range cfg.Disable { - lcs := v.m.GetLinterConfigs(name) - if len(lcs) == 0 { - unknownNames = append(unknownNames, name) - continue - } - - for _, lc := range lcs { - if lc.IsDeprecated() && lc.Deprecation.Level > linter.DeprecationWarning { - v.m.log.Warnf("The linter %q is deprecated (step 2) and deactivated. "+ - "It should be removed from the list of disabled linters. "+ - "https://golangci-lint.run/docs/product/roadmap/#linter-deprecation-cycle", lc.Name()) - } - } - } - - if len(unknownNames) > 0 { - return fmt.Errorf("unknown linters: '%v', run 'golangci-lint help linters' to see the list of supported linters", - strings.Join(unknownNames, ",")) - } - - return nil -} - -func (v Validator) alternativeNamesDeprecation(cfg *config.Linters) error { - if v.m.cfg.InternalTest || v.m.cfg.InternalCmdTest || os.Getenv(logutils.EnvTestRun) == "1" { - return nil - } - - altNames := map[string][]string{} - for _, lc := range v.m.GetAllSupportedLinterConfigs() { - for _, alt := range lc.AlternativeNames { - altNames[alt] = append(altNames[alt], lc.Name()) - } - } - - names := cfg.Enable - names = append(names, cfg.Disable...) - - for _, name := range names { - lc, ok := altNames[name] - if !ok { - continue - } - - if len(lc) > 1 { - v.m.log.Warnf("The linter named %q is deprecated. It has been split into: %s.", name, strings.Join(lc, ", ")) - } else { - v.m.log.Warnf("The name %q is deprecated. The linter has been renamed to: %s.", name, lc[0]) - } - } - - return nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/package.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/package.go deleted file mode 100644 index 3127a24b8e..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/package.go +++ /dev/null @@ -1,285 +0,0 @@ -package lint - -import ( - "context" - "fmt" - "go/build" - "go/token" - "os" - "path/filepath" - "regexp" - "strings" - "time" - - "github.com/ldez/grignotin/goenv" - "golang.org/x/tools/go/packages" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/exitcodes" - "github.com/golangci/golangci-lint/v2/pkg/goanalysis/load" - "github.com/golangci/golangci-lint/v2/pkg/goutil" - "github.com/golangci/golangci-lint/v2/pkg/lint/linter" - "github.com/golangci/golangci-lint/v2/pkg/logutils" -) - -// PackageLoader loads packages based on [golang.org/x/tools/go/packages.Load]. -type PackageLoader struct { - log logutils.Log - debugf logutils.DebugFunc - - cfg *config.Config - - args []string - - pkgTestIDRe *regexp.Regexp - - goenv *goutil.Env - - loadGuard *load.Guard -} - -// NewPackageLoader creates a new PackageLoader. -func NewPackageLoader(log logutils.Log, cfg *config.Config, args []string, env *goutil.Env, loadGuard *load.Guard) *PackageLoader { - return &PackageLoader{ - cfg: cfg, - args: args, - log: log, - debugf: logutils.Debug(logutils.DebugKeyLoader), - goenv: env, - pkgTestIDRe: regexp.MustCompile(`^(.*) \[(.*)\.test\]`), - loadGuard: loadGuard, - } -} - -// Load loads packages. -func (l *PackageLoader) Load(ctx context.Context, linters []*linter.Config) (pkgs, deduplicatedPkgs []*packages.Package, err error) { - loadMode := findLoadMode(linters) - - pkgs, err = l.loadPackages(ctx, loadMode) - if err != nil { - return nil, nil, fmt.Errorf("failed to load packages: %w", err) - } - - return pkgs, l.filterDuplicatePackages(pkgs), nil -} - -func (l *PackageLoader) loadPackages(ctx context.Context, loadMode packages.LoadMode) ([]*packages.Package, error) { - defer func(startedAt time.Time) { - l.log.Infof("Go packages loading at mode %s took %s", stringifyLoadMode(loadMode), time.Since(startedAt)) - }(time.Now()) - - l.prepareBuildContext() - - conf := &packages.Config{ - Mode: loadMode, - Tests: l.cfg.Run.AnalyzeTests, - Context: ctx, - BuildFlags: l.makeBuildFlags(), - Logf: l.debugf, - // TODO: use fset, parsefile, overlay - } - - args := buildArgs(l.args) - - l.debugf("Built loader args are %s", args) - - pkgs, err := packages.Load(conf, args...) - if err != nil { - return nil, fmt.Errorf("failed to load with go/packages: %w", err) - } - - if loadMode&packages.NeedSyntax == 0 { - // Needed e.g. for go/analysis loading. - fset := token.NewFileSet() - packages.Visit(pkgs, nil, func(pkg *packages.Package) { - pkg.Fset = fset - l.loadGuard.AddMutexForPkg(pkg) - }) - } - - l.debugPrintLoadedPackages(pkgs) - - if err := l.parseLoadedPackagesErrors(pkgs); err != nil { - return nil, err - } - - return l.filterTestMainPackages(pkgs), nil -} - -func (*PackageLoader) parseLoadedPackagesErrors(pkgs []*packages.Package) error { - for _, pkg := range pkgs { - var errs []packages.Error - for _, err := range pkg.Errors { - // quick fix: skip error related to `go list` invocation by packages.Load() - // The behavior has been changed between go1.19 and go1.20, the error is now inside the JSON content. - // https://github.com/golangci/golangci-lint/pull/3414#issuecomment-1364756303 - if strings.Contains(err.Msg, "# command-line-arguments") { - continue - } - - errs = append(errs, err) - - if strings.Contains(err.Msg, "no Go files") { - return fmt.Errorf("package %s: %w", pkg.PkgPath, exitcodes.ErrNoGoFiles) - } - if strings.Contains(err.Msg, "cannot find package") { - // when analyzing not existing directory - return fmt.Errorf("%v: %w", err.Msg, exitcodes.ErrFailure) - } - } - - pkg.Errors = errs - } - - return nil -} - -func (l *PackageLoader) tryParseTestPackage(pkg *packages.Package) (name string, isTest bool) { - matches := l.pkgTestIDRe.FindStringSubmatch(pkg.ID) - if matches == nil { - return "", false - } - - return matches[1], true -} - -func (l *PackageLoader) filterDuplicatePackages(pkgs []*packages.Package) []*packages.Package { - packagesWithTests := map[string]bool{} - for _, pkg := range pkgs { - name, isTest := l.tryParseTestPackage(pkg) - if !isTest { - continue - } - packagesWithTests[name] = true - } - - l.debugf("package with tests: %#v", packagesWithTests) - - var retPkgs []*packages.Package - for _, pkg := range pkgs { - _, isTest := l.tryParseTestPackage(pkg) - if !isTest && packagesWithTests[pkg.PkgPath] { - // If tests loading is enabled, - // for package with files a.go and a_test.go go/packages loads two packages: - // 1. ID=".../a" GoFiles=[a.go] - // 2. ID=".../a [.../a.test]" GoFiles=[a.go a_test.go] - // We need only the second package, otherwise we can get warnings about unused variables/fields/functions - // in a.go if they are used only in a_test.go. - l.debugf("skip pkg ID=%s because we load it with test package", pkg.ID) - continue - } - - retPkgs = append(retPkgs, pkg) - } - - return retPkgs -} - -func (l *PackageLoader) filterTestMainPackages(pkgs []*packages.Package) []*packages.Package { - var retPkgs []*packages.Package - for _, pkg := range pkgs { - if pkg.Name == "main" && strings.HasSuffix(pkg.PkgPath, ".test") { - // it's an implicit testmain package - l.debugf("skip pkg ID=%s", pkg.ID) - continue - } - - retPkgs = append(retPkgs, pkg) - } - - return retPkgs -} - -func (l *PackageLoader) debugPrintLoadedPackages(pkgs []*packages.Package) { - l.debugf("loaded %d pkgs", len(pkgs)) - for i, pkg := range pkgs { - var syntaxFiles []string - for _, sf := range pkg.Syntax { - syntaxFiles = append(syntaxFiles, pkg.Fset.Position(sf.Pos()).Filename) - } - l.debugf("Loaded pkg #%d: ID=%s GoFiles=%s CompiledGoFiles=%s Syntax=%s", - i, pkg.ID, pkg.GoFiles, pkg.CompiledGoFiles, syntaxFiles) - } -} - -func (l *PackageLoader) prepareBuildContext() { - // Set GOROOT to have working cross-compilation: cross-compiled binaries - // have invalid GOROOT. XXX: can't use runtime.GOROOT(). - goroot := l.goenv.Get(goenv.GOROOT) - if goroot == "" { - return - } - - _ = os.Setenv(goenv.GOROOT, goroot) - - build.Default.GOROOT = goroot - build.Default.BuildTags = l.cfg.Run.BuildTags -} - -func (l *PackageLoader) makeBuildFlags() []string { - var buildFlags []string - - if len(l.cfg.Run.BuildTags) != 0 { - // go help build - buildFlags = append(buildFlags, "-tags", strings.Join(l.cfg.Run.BuildTags, " ")) - l.log.Infof("Using build tags: %v", l.cfg.Run.BuildTags) - } - - if l.cfg.Run.ModulesDownloadMode != "" { - // go help modules - buildFlags = append(buildFlags, fmt.Sprintf("-mod=%s", l.cfg.Run.ModulesDownloadMode)) - } - - return buildFlags -} - -func buildArgs(args []string) []string { - if len(args) == 0 { - return []string{"./..."} - } - - var retArgs []string - for _, arg := range args { - if strings.HasPrefix(arg, ".") || filepath.IsAbs(arg) { - retArgs = append(retArgs, arg) - } else { - // go/packages doesn't work well if we don't have the prefix ./ for local packages - retArgs = append(retArgs, fmt.Sprintf(".%c%s", filepath.Separator, arg)) - } - } - - return retArgs -} - -func findLoadMode(linters []*linter.Config) packages.LoadMode { - loadMode := packages.LoadMode(0) - for _, lc := range linters { - loadMode |= lc.LoadMode - } - - return loadMode -} - -func stringifyLoadMode(mode packages.LoadMode) string { - m := map[packages.LoadMode]string{ - packages.NeedCompiledGoFiles: "compiled_files", - packages.NeedDeps: "deps", - packages.NeedExportFile: "exports_file", - packages.NeedFiles: "files", - packages.NeedImports: "imports", - packages.NeedName: "name", - packages.NeedSyntax: "syntax", - packages.NeedTypes: "types", - packages.NeedTypesInfo: "types_info", - packages.NeedTypesSizes: "types_sizes", - } - - var flags []string - for flag, flagStr := range m { - if mode&flag != 0 { - flags = append(flags, flagStr) - } - } - - return fmt.Sprintf("%d (%s)", mode, strings.Join(flags, "|")) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/runner.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/runner.go deleted file mode 100644 index ba7750f285..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/lint/runner.go +++ /dev/null @@ -1,251 +0,0 @@ -package lint - -import ( - "context" - "errors" - "fmt" - "maps" - "runtime/debug" - "strings" - - "github.com/golangci/golangci-lint/v2/internal/errorutil" - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/fsutils" - "github.com/golangci/golangci-lint/v2/pkg/goformatters" - "github.com/golangci/golangci-lint/v2/pkg/goutil" - "github.com/golangci/golangci-lint/v2/pkg/lint/linter" - "github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb" - "github.com/golangci/golangci-lint/v2/pkg/logutils" - "github.com/golangci/golangci-lint/v2/pkg/result" - "github.com/golangci/golangci-lint/v2/pkg/result/processors" - "github.com/golangci/golangci-lint/v2/pkg/timeutils" -) - -type processorStat struct { - inCount int - outCount int -} - -type Runner struct { - Log logutils.Log - - lintCtx *linter.Context - Processors []processors.Processor -} - -func NewRunner(log logutils.Log, cfg *config.Config, goenv *goutil.Env, - lineCache *fsutils.LineCache, fileCache *fsutils.FileCache, - dbManager *lintersdb.Manager, lintCtx *linter.Context, -) (*Runner, error) { - pathRelativity, err := processors.NewPathRelativity(log, cfg.GetBasePath()) - if err != nil { - return nil, fmt.Errorf("error creating path relativity processor: %w", err) - } - - exclusionPaths, err := processors.NewExclusionPaths(log, &cfg.Linters.Exclusions) - if err != nil { - return nil, err - } - - enabledLinters, err := dbManager.GetEnabledLintersMap() - if err != nil { - return nil, fmt.Errorf("failed to get enabled linters: %w", err) - } - - var enabledFormatters []string - for name := range maps.Keys(enabledLinters) { - if goformatters.IsFormatter(name) { - enabledFormatters = append(enabledFormatters, name) - } - } - - formattersCfg := &config.Formatters{ - Enable: enabledFormatters, - Settings: cfg.Linters.Settings.FormatterSettings, - } - - metaFormatter, err := goformatters.NewMetaFormatter(log, formattersCfg, &cfg.Run) - if err != nil { - return nil, fmt.Errorf("failed to create meta-formatter: %w", err) - } - - return &Runner{ - Processors: []processors.Processor{ - // Must be the first processor. - processors.NewPathAbsoluter(log), - - processors.NewCgo(goenv), - - // Must be after Cgo. - processors.NewFilenameUnadjuster(lintCtx.Packages, log.Child(logutils.DebugKeyFilenameUnadjuster)), - - // Must be after FilenameUnadjuster. - processors.NewInvalidIssue(log.Child(logutils.DebugKeyInvalidIssue)), - - // Must be after PathAbsoluter, Cgo, FilenameUnadjuster InvalidIssue. - pathRelativity, - - // Must be after PathRelativity. - exclusionPaths, - - processors.NewGeneratedFileFilter(cfg.Linters.Exclusions.Generated), - - processors.NewExclusionRules(log.Child(logutils.DebugKeyExclusionRules), lineCache, - &cfg.Linters.Exclusions), - - processors.NewNolintFilter(log.Child(logutils.DebugKeyNolintFilter), dbManager, enabledLinters), - - processors.NewDiff(&cfg.Issues), - - // The fixer still needs to see paths for the issues that are relative to the current directory. - processors.NewFixer(cfg, log, fileCache, metaFormatter), - - // Must be after the Fixer. - processors.NewUniqByLine(cfg.Issues.UniqByLine), - processors.NewMaxPerFileFromLinter(cfg), - processors.NewMaxSameIssues(cfg.Issues.MaxSameIssues, log.Child(logutils.DebugKeyMaxSameIssues), cfg), - processors.NewMaxFromLinter(cfg.Issues.MaxIssuesPerLinter, log.Child(logutils.DebugKeyMaxFromLinter), cfg), - - // Now we can modify the issues for output. - processors.NewSourceCode(lineCache, log.Child(logutils.DebugKeySourceCode)), - processors.NewPathShortener(), - processors.NewSeverity(log.Child(logutils.DebugKeySeverityRules), lineCache, &cfg.Severity), - processors.NewPathPrettifier(log, &cfg.Output), - processors.NewSortResults(&cfg.Output), - }, - lintCtx: lintCtx, - Log: log, - }, nil -} - -func (r *Runner) Run(ctx context.Context, linters []*linter.Config) ([]*result.Issue, error) { - sw := timeutils.NewStopwatch("linters", r.Log) - defer sw.Print() - - var ( - lintErrors error - issues []*result.Issue - ) - - for _, lc := range linters { - linterIssues, err := timeutils.TrackStage(sw, lc.Name(), func() ([]*result.Issue, error) { - return r.runLinterSafe(ctx, r.lintCtx, lc) - }) - if err != nil { - lintErrors = errors.Join(lintErrors, fmt.Errorf("can't run linter %s", lc.Linter.Name()), err) - r.Log.Warnf("Can't run linter %s: %v", lc.Linter.Name(), err) - - continue - } - - issues = append(issues, linterIssues...) - } - - return r.processLintResults(issues), lintErrors -} - -func (r *Runner) runLinterSafe(ctx context.Context, lintCtx *linter.Context, - lc *linter.Config, -) (ret []*result.Issue, err error) { - defer func() { - if panicData := recover(); panicData != nil { - if pe, ok := panicData.(*errorutil.PanicError); ok { - err = fmt.Errorf("%s: %w", lc.Name(), pe) - - // Don't print stacktrace from goroutines twice - r.Log.Errorf("Panic: %s: %s", pe, pe.Stack()) - } else { - err = fmt.Errorf("panic occurred: %s", panicData) - r.Log.Errorf("Panic stack trace: %s", debug.Stack()) - } - } - }() - - issues, err := lc.Linter.Run(ctx, lintCtx) - - if lc.DoesChangeTypes { - // Packages in lintCtx might be dirty due to the last analysis, - // which affects to the next analysis. - // To avoid this issue, we clear type information from the packages. - // See https://github.com/golangci/golangci-lint/pull/944. - // Currently, DoesChangeTypes is true only for `unused`. - lintCtx.ClearTypesInPackages() - } - - if err != nil { - return nil, err - } - - for i := range issues { - if issues[i].FromLinter == "" { - issues[i].FromLinter = lc.Name() - } - } - - return issues, nil -} - -func (r *Runner) processLintResults(inIssues []*result.Issue) []*result.Issue { - sw := timeutils.NewStopwatch("processing", r.Log) - - var issuesBefore, issuesAfter int - statPerProcessor := map[string]processorStat{} - - var outIssues []*result.Issue - if len(inIssues) != 0 { - issuesBefore += len(inIssues) - outIssues = r.processIssues(inIssues, sw, statPerProcessor) - issuesAfter += len(outIssues) - } - - // finalize processors: logging, clearing, no heavy work here - - for _, p := range r.Processors { - sw.TrackStage(p.Name(), p.Finish) - } - - if issuesBefore != issuesAfter { - r.Log.Infof("Issues before processing: %d, after processing: %d", issuesBefore, issuesAfter) - } - r.printPerProcessorStat(statPerProcessor) - sw.PrintStages() - - return outIssues -} - -func (r *Runner) printPerProcessorStat(stat map[string]processorStat) { - parts := make([]string, 0, len(stat)) - for name, ps := range stat { - if ps.inCount != 0 { - parts = append(parts, fmt.Sprintf("%s: %d/%d", name, ps.inCount, ps.outCount)) - } - } - if len(parts) != 0 { - r.Log.Infof("Processors filtering stat (in/out): %s", strings.Join(parts, ", ")) - } -} - -func (r *Runner) processIssues(issues []*result.Issue, sw *timeutils.Stopwatch, statPerProcessor map[string]processorStat) []*result.Issue { - for _, p := range r.Processors { - newIssues, err := timeutils.TrackStage(sw, p.Name(), func() ([]*result.Issue, error) { - return p.Process(issues) - }) - - if err != nil { - r.Log.Warnf("Can't process results by %s processor: %s", p.Name(), err) - } else { - stat := statPerProcessor[p.Name()] - stat.inCount += len(issues) - stat.outCount += len(newIssues) - statPerProcessor[p.Name()] = stat - issues = newIssues - } - - // This is required by JSON serialization - if issues == nil { - issues = []*result.Issue{} - } - } - - return issues -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/logutils/log.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/logutils/log.go deleted file mode 100644 index 16067e490e..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/logutils/log.go +++ /dev/null @@ -1,31 +0,0 @@ -package logutils - -type Log interface { - Fatalf(format string, args ...any) - Panicf(format string, args ...any) - Errorf(format string, args ...any) - Warnf(format string, args ...any) - Infof(format string, args ...any) - - Child(name string) Log - SetLevel(level LogLevel) -} - -type LogLevel int - -const ( - // LogLevelDebug Debug messages, write to debug logs only by logutils.Debug. - LogLevelDebug LogLevel = 0 - - // LogLevelInfo Information messages, don't write too many messages, - // only useful ones: they are shown when running with -v. - LogLevelInfo LogLevel = 1 - - // LogLevelWarn Hidden errors: non-critical errors: work can be continued, no need to fail whole program; - // tests will crash if any warning occurred. - LogLevelWarn LogLevel = 2 - - // LogLevelError Only not hidden from user errors: whole program failing, usually - // error logging happens in 1-2 places: in the "main" function. - LogLevelError LogLevel = 3 -) diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/logutils/logutils.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/logutils/logutils.go deleted file mode 100644 index 50b8fa3f32..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/logutils/logutils.go +++ /dev/null @@ -1,138 +0,0 @@ -package logutils - -import ( - "os" - "strings" -) - -// EnvTestRun value: "1" -const EnvTestRun = "GL_TEST_RUN" - -// envDebug value: one or several debug keys. -// examples: -// - Remove output to `/dev/null`: `GL_DEBUG=linters_output ./golangci-lint run` -// - Show linters configuration: `GL_DEBUG=enabled_linters golangci-lint run` -// - Some analysis details: `GL_DEBUG=goanalysis/analyze,goanalysis/facts golangci-lint run` -const envDebug = "GL_DEBUG" - -const ( - DebugKeyBinSalt = "bin_salt" // Forces the usage of constant as salt (only for maintainers). - DebugKeyGoModSalt = "gomod_salt" // Display logs related to the salt computation from the go.mod file. - DebugKeyConfigReader = "config_reader" // Display logs related to configuration loading. - DebugKeyEmpty = "" - DebugKeyEnabledLinters = "enabled_linters" // Display logs related to the enabled linters inside the [lintersdb.Manager]. - DebugKeyExec = "exec" // Display logs related to the lock file. - DebugKeyGoEnv = "goenv" // Display logs related to [goenv.Env]. - DebugKeyLintersContext = "linters_context" // Display logs related to the package analysis context (not related to [context.Context]). - DebugKeyLintersDB = "lintersdb" // Display logs related to the linters/formatters loading. - DebugKeyLoader = "loader" // Display logs related to package loading (including `go/packages` internal debugging). - DebugKeyPkgCache = "pkgcache" // Display logs related to cache. - DebugKeyRunner = "runner" // Display logs related to the linter runner. - DebugKeyStopwatch = "stopwatch" // Display logs related to the stopwatch of the cache. - DebugKeyTest = "test" // Display debug logs during integration tests. -) - -// Printers. -const ( - DebugKeyCheckstylePrinter = "checkstyle_printer" - DebugKeyCodeClimatePrinter = "codeclimate_printer" - DebugKeySarifPrinter = "sarif_printer" - DebugKeyTabPrinter = "tab_printer" - DebugKeyTeamCityPrinter = "teamcity_printer" - DebugKeyTextPrinter = "text_printer" -) - -// Processors. -const ( - DebugKeyExclusionPaths = "exclusion_paths" - DebugKeyExclusionRules = "exclusion_rules" - DebugKeyFilenameUnadjuster = "filename_unadjuster" - DebugKeyGeneratedFileFilter = "generated_file_filter" // Debugs a filter excluding autogenerated source code. - DebugKeyInvalidIssue = "invalid_issue" - DebugKeyMaxFromLinter = "max_from_linter" - DebugKeyMaxSameIssues = "max_same_issues" - DebugKeyNolintFilter = "nolint_filter" // Debugs a filter excluding issues by `//nolint` comments. - DebugKeyPathAbsoluter = "path_absoluter" - DebugKeyPathPrettifier = "path_prettifier" - DebugKeyPathRelativity = "path_relativity" - DebugKeySeverityRules = "severity_rules" - DebugKeySourceCode = "source_code" -) - -// Analysis. -const ( - DebugKeyGoAnalysis = "goanalysis" - - DebugKeyGoAnalysisAnalyze = DebugKeyGoAnalysis + "/analyze" - DebugKeyGoAnalysisIssuesCache = DebugKeyGoAnalysis + "/issues/cache" - DebugKeyGoAnalysisMemory = DebugKeyGoAnalysis + "/memory" - - DebugKeyGoAnalysisFacts = DebugKeyGoAnalysis + "/facts" - DebugKeyGoAnalysisFactsCache = DebugKeyGoAnalysisFacts + "/cache" - DebugKeyGoAnalysisFactsExport = DebugKeyGoAnalysisFacts + "/export" - DebugKeyGoAnalysisFactsInherit = DebugKeyGoAnalysisFacts + "/inherit" -) - -// Linters and Formatters. -const ( - DebugKeyFormatter = "formatter" // Display logs from the shared logger for formatters. - DebugKeyFormattersOutput = "formatters_output" // Display logs from formatters themselves. - DebugKeyLinter = "linter" // Display logs from the shared logger for linters. - DebugKeyLintersOutput = "linters_output" // Display logs from linters themselves. - - DebugKeyForbidigo = "forbidigo" // Debugs `forbidigo` linter. - DebugKeyGoCritic = "gocritic" // Debugs `gocritic` linter. - DebugKeyGovet = "govet" // Debugs `govet` linter. - DebugKeyRevive = "revive" // Debugs `revive` linter. - DebugKeyStaticcheck = "staticcheck" // Debugs `staticcheck` linter. -) - -func getEnabledDebugs() map[string]bool { - ret := map[string]bool{} - debugVar := os.Getenv(envDebug) - if debugVar == "" { - return ret - } - - for tag := range strings.SplitSeq(debugVar, ",") { - ret[tag] = true - } - - return ret -} - -var enabledDebugs = getEnabledDebugs() - -type DebugFunc func(format string, args ...any) - -func nopDebugf(_ string, _ ...any) {} - -func Debug(tag string) DebugFunc { - if !enabledDebugs[tag] { - return nopDebugf - } - - logger := NewStderrLog(tag) - logger.SetLevel(LogLevelDebug) - - return func(format string, args ...any) { - logger.Debugf(format, args...) - } -} - -func HaveDebugTag(tag string) bool { - return enabledDebugs[tag] -} - -var verbose bool - -func SetupVerboseLog(log Log, isVerbose bool) { - if isVerbose { - verbose = isVerbose - log.SetLevel(LogLevelInfo) - } -} - -func IsVerbose() bool { - return verbose -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/logutils/mock.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/logutils/mock.go deleted file mode 100644 index bddcf85523..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/logutils/mock.go +++ /dev/null @@ -1,82 +0,0 @@ -package logutils - -import ( - "github.com/stretchr/testify/mock" -) - -type MockLog struct { - mock.Mock -} - -func NewMockLog() *MockLog { - return &MockLog{} -} - -func (m *MockLog) Fatalf(format string, args ...any) { - m.Called(append([]any{format}, args...)...) -} - -func (m *MockLog) Panicf(format string, args ...any) { - m.Called(append([]any{format}, args...)...) -} - -func (m *MockLog) Errorf(format string, args ...any) { - m.Called(append([]any{format}, args...)...) -} - -func (m *MockLog) Warnf(format string, args ...any) { - m.Called(append([]any{format}, args...)...) -} - -func (m *MockLog) Infof(format string, args ...any) { - m.Called(append([]any{format}, args...)...) -} - -func (m *MockLog) Child(name string) Log { - m.Called(name) - return m -} - -func (m *MockLog) SetLevel(level LogLevel) { - m.Called(level) -} - -func (m *MockLog) OnFatalf(format string, args ...any) *MockLog { - arguments := append([]any{format}, args...) - - m.On("Fatalf", arguments...) - - return m -} - -func (m *MockLog) OnPanicf(format string, args ...any) *MockLog { - arguments := append([]any{format}, args...) - - m.On("Panicf", arguments...) - - return m -} - -func (m *MockLog) OnErrorf(format string, args ...any) *MockLog { - arguments := append([]any{format}, args...) - - m.On("Errorf", arguments...) - - return m -} - -func (m *MockLog) OnWarnf(format string, args ...any) *MockLog { - arguments := append([]any{format}, args...) - - m.On("Warnf", arguments...) - - return m -} - -func (m *MockLog) OnInfof(format string, args ...any) *MockLog { - arguments := append([]any{format}, args...) - - m.On("Infof", arguments...) - - return m -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/logutils/out.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/logutils/out.go deleted file mode 100644 index ef13754867..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/logutils/out.go +++ /dev/null @@ -1,11 +0,0 @@ -package logutils - -import ( - "github.com/fatih/color" - colorable "github.com/mattn/go-colorable" -) - -var ( - StdOut = color.Output // https://github.com/golangci/golangci-lint/issues/14 - StdErr = colorable.NewColorableStderr() -) diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/logutils/stderr_log.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/logutils/stderr_log.go deleted file mode 100644 index af42964291..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/logutils/stderr_log.go +++ /dev/null @@ -1,141 +0,0 @@ -package logutils - -import ( - "fmt" - "os" - "time" - - "github.com/sirupsen/logrus" - - "github.com/golangci/golangci-lint/v2/pkg/exitcodes" -) - -const ( - // envLogLevel values: "error", "err", "warning", "warn","info" - envLogLevel = "LOG_LEVEL" - // envLogTimestamp value: "1" - envLogTimestamp = "LOG_TIMESTAMP" -) - -var _ Log = NewStderrLog(DebugKeyEmpty) - -type StderrLog struct { - name string - logger *logrus.Logger - level LogLevel -} - -func NewStderrLog(name string) *StderrLog { - sl := &StderrLog{ - name: name, - logger: logrus.New(), - level: LogLevelWarn, - } - - switch os.Getenv(envLogLevel) { - case "error", "err": - sl.logger.SetLevel(logrus.ErrorLevel) - case "warning", "warn": - sl.logger.SetLevel(logrus.WarnLevel) - case "info": - sl.logger.SetLevel(logrus.InfoLevel) - default: - sl.logger.SetLevel(logrus.DebugLevel) - } - - sl.logger.Out = StdErr - sl.logger.Formatter = logFormatter - - return sl -} - -func (sl StderrLog) prefix() string { - prefix := "" - if sl.name != "" { - prefix = fmt.Sprintf("[%s] ", sl.name) - } - - return prefix -} - -func (sl StderrLog) Fatalf(format string, args ...any) { - sl.logger.Errorf("%s%s", sl.prefix(), fmt.Sprintf(format, args...)) - os.Exit(exitcodes.Failure) -} - -func (sl StderrLog) Panicf(format string, args ...any) { - v := fmt.Sprintf("%s%s", sl.prefix(), fmt.Sprintf(format, args...)) - panic(v) -} - -func (sl StderrLog) Errorf(format string, args ...any) { - if sl.level > LogLevelError { - return - } - - sl.logger.Errorf("%s%s", sl.prefix(), fmt.Sprintf(format, args...)) - // don't call exitIfTest() because the idea is to - // crash on hidden errors (warnings); but Errorf MUST NOT be - // called on hidden errors, see log levels comments. -} - -func (sl StderrLog) Warnf(format string, args ...any) { - if sl.level > LogLevelWarn { - return - } - - sl.logger.Warnf("%s%s", sl.prefix(), fmt.Sprintf(format, args...)) -} - -func (sl StderrLog) Infof(format string, args ...any) { - if sl.level > LogLevelInfo { - return - } - - sl.logger.Infof("%s%s", sl.prefix(), fmt.Sprintf(format, args...)) -} - -func (sl StderrLog) Debugf(format string, args ...any) { - if sl.level > LogLevelDebug { - return - } - - sl.logger.Debugf("%s%s", sl.prefix(), fmt.Sprintf(format, args...)) -} - -func (sl StderrLog) Child(name string) Log { - prefix := "" - if sl.name != "" { - prefix = sl.name + "/" - } - - child := sl - child.name = prefix + name - - return &child -} - -func (sl *StderrLog) SetLevel(level LogLevel) { - sl.level = level -} - -var logFormatter = newLogFormatter() - -func DisableColors(disable bool) { - logFormatter.DisableColors = disable -} - -func newLogFormatter() *logrus.TextFormatter { - formatter := &logrus.TextFormatter{ - DisableTimestamp: true, // `INFO[0007] msg` -> `INFO msg` - EnvironmentOverrideColors: true, - } - - if os.Getenv(envLogTimestamp) == "1" { - formatter.DisableTimestamp = false - formatter.FullTimestamp = true - formatter.TimestampFormat = time.StampMilli - } - - return formatter -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/checkstyle.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/checkstyle.go deleted file mode 100644 index c3869bd39d..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/checkstyle.go +++ /dev/null @@ -1,107 +0,0 @@ -package printers - -import ( - "encoding/xml" - "fmt" - "io" - "maps" - "slices" - "strings" - - "github.com/go-xmlfmt/xmlfmt" - - "github.com/golangci/golangci-lint/v2/pkg/logutils" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -const defaultCheckstyleSeverity = "error" - -// Checkstyle prints issues in the Checkstyle format. -// https://checkstyle.org/config.html -type Checkstyle struct { - log logutils.Log - w io.Writer - sanitizer severitySanitizer -} - -func NewCheckstyle(log logutils.Log, w io.Writer) *Checkstyle { - return &Checkstyle{ - log: log.Child(logutils.DebugKeyCheckstylePrinter), - w: w, - sanitizer: severitySanitizer{ - // https://checkstyle.org/config.html#Severity - // https://checkstyle.org/property_types.html#SeverityLevel - allowedSeverities: []string{"ignore", "info", "warning", defaultCheckstyleSeverity}, - defaultSeverity: defaultCheckstyleSeverity, - }, - } -} - -func (p *Checkstyle) Print(issues []*result.Issue) error { - out := checkstyleOutput{ - Version: "5.0", - } - - files := map[string]*checkstyleFile{} - - for _, issue := range issues { - file, ok := files[issue.FilePath()] - if !ok { - file = &checkstyleFile{ - Name: issue.FilePath(), - } - - files[issue.FilePath()] = file - } - - newError := &checkstyleError{ - Column: issue.Column(), - Line: issue.Line(), - Message: issue.Text, - Source: issue.FromLinter, - Severity: p.sanitizer.Sanitize(issue.Severity), - } - - file.Errors = append(file.Errors, newError) - } - - err := p.sanitizer.Err() - if err != nil { - p.log.Infof("%v", err) - } - - out.Files = slices.SortedFunc(maps.Values(files), func(a *checkstyleFile, b *checkstyleFile) int { - return strings.Compare(a.Name, b.Name) - }) - - data, err := xml.Marshal(&out) - if err != nil { - return err - } - - _, err = fmt.Fprintf(p.w, "%s%s\n", xml.Header, xmlfmt.FormatXML(string(data), "", " ")) - if err != nil { - return err - } - - return nil -} - -type checkstyleOutput struct { - XMLName xml.Name `xml:"checkstyle"` - Version string `xml:"version,attr"` - Files []*checkstyleFile `xml:"file"` -} - -type checkstyleFile struct { - Name string `xml:"name,attr"` - Errors []*checkstyleError `xml:"error"` -} - -type checkstyleError struct { - Column int `xml:"column,attr"` - Line int `xml:"line,attr"` - Message string `xml:"message,attr"` - Severity string `xml:"severity,attr"` - Source string `xml:"source,attr"` -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/codeclimate.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/codeclimate.go deleted file mode 100644 index e2eded608f..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/codeclimate.go +++ /dev/null @@ -1,73 +0,0 @@ -package printers - -import ( - "encoding/json" - "io" - - "github.com/golangci/golangci-lint/v2/pkg/logutils" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -const defaultCodeClimateSeverity = "critical" - -// CodeClimate prints issues in the Code Climate format. -// https://github.com/codeclimate/platform/blob/HEAD/spec/analyzers/SPEC.md -type CodeClimate struct { - log logutils.Log - w io.Writer - sanitizer severitySanitizer -} - -func NewCodeClimate(log logutils.Log, w io.Writer) *CodeClimate { - return &CodeClimate{ - log: log.Child(logutils.DebugKeyCodeClimatePrinter), - w: w, - sanitizer: severitySanitizer{ - // https://github.com/codeclimate/platform/blob/HEAD/spec/analyzers/SPEC.md#data-types - allowedSeverities: []string{"info", "minor", "major", defaultCodeClimateSeverity, "blocker"}, - defaultSeverity: defaultCodeClimateSeverity, - }, - } -} - -func (p *CodeClimate) Print(issues []*result.Issue) error { - ccIssues := make([]codeClimateIssue, 0, len(issues)) - - for _, issue := range issues { - ccIssue := codeClimateIssue{ - Description: issue.Description(), - CheckName: issue.FromLinter, - Severity: p.sanitizer.Sanitize(issue.Severity), - Fingerprint: issue.Fingerprint(), - } - - ccIssue.Location.Path = issue.Pos.Filename - ccIssue.Location.Lines.Begin = issue.Pos.Line - - ccIssues = append(ccIssues, ccIssue) - } - - err := p.sanitizer.Err() - if err != nil { - p.log.Infof("%v", err) - } - - return json.NewEncoder(p.w).Encode(ccIssues) -} - -// codeClimateIssue is a subset of the Code Climate spec. -// https://github.com/codeclimate/platform/blob/HEAD/spec/analyzers/SPEC.md#data-types -// It is just enough to support GitLab CI Code Quality. -// https://docs.gitlab.com/ee/ci/testing/code_quality.html#code-quality-report-format -type codeClimateIssue struct { - Description string `json:"description"` - CheckName string `json:"check_name"` - Severity string `json:"severity,omitempty"` - Fingerprint string `json:"fingerprint"` - Location struct { - Path string `json:"path"` - Lines struct { - Begin int `json:"begin"` - } `json:"lines"` - } `json:"location"` -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/html.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/html.go deleted file mode 100644 index 1f6ed18344..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/html.go +++ /dev/null @@ -1,158 +0,0 @@ -package printers - -import ( - "fmt" - "html/template" - "io" - "strings" - - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -const templateContent = ` - - - - golangci-lint - - - - - - - - - - -
-
-
-
-
- - - -` - -type htmlIssue struct { - Title string - Pos string - Linter string - Code string -} - -// HTML prints issues in an HTML page. -// It uses the Cloudflare CDN (cdnjs) and React. -type HTML struct { - w io.Writer -} - -func NewHTML(w io.Writer) *HTML { - return &HTML{w: w} -} - -func (p HTML) Print(issues []*result.Issue) error { - var htmlIssues []htmlIssue - - for _, issue := range issues { - pos := fmt.Sprintf("%s:%d", issue.FilePath(), issue.Line()) - if issue.Pos.Column != 0 { - pos += fmt.Sprintf(":%d", issue.Pos.Column) - } - - htmlIssues = append(htmlIssues, htmlIssue{ - Title: strings.TrimSpace(issue.Text), - Pos: pos, - Linter: issue.FromLinter, - Code: strings.Join(issue.SourceLines, "\n"), - }) - } - - t, err := template.New("golangci-lint").Parse(templateContent) - if err != nil { - return err - } - - return t.Execute(p.w, struct{ Issues []htmlIssue }{Issues: htmlIssues}) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/json.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/json.go deleted file mode 100644 index 97354081c9..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/json.go +++ /dev/null @@ -1,39 +0,0 @@ -package printers - -import ( - "encoding/json" - "io" - - "github.com/golangci/golangci-lint/v2/pkg/report" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -// JSON prints issues in a JSON representation. -type JSON struct { - rd *report.Data - w io.Writer -} - -func NewJSON(w io.Writer, rd *report.Data) *JSON { - return &JSON{ - rd: rd, - w: w, - } -} - -type JSONResult struct { - Issues []*result.Issue - Report *report.Data -} - -func (p JSON) Print(issues []*result.Issue) error { - res := JSONResult{ - Issues: issues, - Report: p.rd, - } - if res.Issues == nil { - res.Issues = []*result.Issue{} - } - - return json.NewEncoder(p.w).Encode(res) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/junitxml.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/junitxml.go deleted file mode 100644 index b040e74670..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/junitxml.go +++ /dev/null @@ -1,100 +0,0 @@ -package printers - -import ( - "encoding/xml" - "fmt" - "io" - "maps" - "slices" - "strings" - - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -// JUnitXML prints issues in the JUnit XML format. -// There is no official specification for the JUnit XML file format, -// and various tools generate and support different flavors of this format. -// https://github.com/testmoapp/junitxml -type JUnitXML struct { - extended bool - w io.Writer -} - -func NewJUnitXML(w io.Writer, extended bool) *JUnitXML { - return &JUnitXML{ - extended: extended, - w: w, - } -} - -func (p JUnitXML) Print(issues []*result.Issue) error { - suites := make(map[string]testSuiteXML) // use a map to group by file - - for _, issue := range issues { - suiteName := issue.FilePath() - testSuite := suites[suiteName] - testSuite.Suite = issue.FilePath() - testSuite.Tests++ - testSuite.Failures++ - - tc := testCaseXML{ - Name: issue.FromLinter, - ClassName: issue.Pos.String(), - Failure: failureXML{ - Type: issue.Severity, - Message: issue.Pos.String() + ": " + issue.Text, - Content: fmt.Sprintf("%s: %s\nCategory: %s\nFile: %s\nLine: %d\nDetails: %s", - issue.Severity, issue.Text, issue.FromLinter, issue.Pos.Filename, issue.Pos.Line, strings.Join(issue.SourceLines, "\n")), - }, - } - - if p.extended { - tc.File = issue.Pos.Filename - tc.Line = issue.Pos.Line - } - - testSuite.TestCases = append(testSuite.TestCases, tc) - suites[suiteName] = testSuite - } - - var res testSuitesXML - - res.TestSuites = slices.SortedFunc(maps.Values(suites), func(a testSuiteXML, b testSuiteXML) int { - return strings.Compare(a.Suite, b.Suite) - }) - - enc := xml.NewEncoder(p.w) - enc.Indent("", " ") - if err := enc.Encode(res); err != nil { - return err - } - return nil -} - -type testSuitesXML struct { - XMLName xml.Name `xml:"testsuites"` - TestSuites []testSuiteXML -} - -type testSuiteXML struct { - XMLName xml.Name `xml:"testsuite"` - Suite string `xml:"name,attr"` - Tests int `xml:"tests,attr"` - Errors int `xml:"errors,attr"` - Failures int `xml:"failures,attr"` - TestCases []testCaseXML `xml:"testcase"` -} - -type testCaseXML struct { - Name string `xml:"name,attr"` - ClassName string `xml:"classname,attr"` - Failure failureXML `xml:"failure"` - File string `xml:"file,attr,omitempty"` - Line int `xml:"line,attr,omitempty"` -} - -type failureXML struct { - Message string `xml:"message,attr"` - Type string `xml:"type,attr"` - Content string `xml:",cdata"` -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/printer.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/printer.go deleted file mode 100644 index bb3eab6205..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/printer.go +++ /dev/null @@ -1,241 +0,0 @@ -package printers - -import ( - "errors" - "fmt" - "io" - "os" - "path/filepath" - "slices" - "strings" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/logutils" - "github.com/golangci/golangci-lint/v2/pkg/report" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -const ( - outputStdOut = "stdout" - outputStdErr = "stderr" -) - -const defaultFileMode = 0o644 - -type issuePrinter interface { - Print(issues []*result.Issue) error -} - -// Printer prints issues. -type Printer struct { - cfg *config.Formats - reportData *report.Data - basePath string - - log logutils.Log - - stdOut io.Writer - stdErr io.Writer -} - -// NewPrinter creates a new Printer. -func NewPrinter(log logutils.Log, cfg *config.Formats, reportData *report.Data, basePath string) (*Printer, error) { - if log == nil { - return nil, errors.New("missing log argument in constructor") - } - if cfg == nil { - return nil, errors.New("missing config argument in constructor") - } - if reportData == nil { - return nil, errors.New("missing reportData argument in constructor") - } - - return &Printer{ - cfg: cfg, - reportData: reportData, - basePath: basePath, - log: log, - stdOut: logutils.StdOut, - stdErr: logutils.StdErr, - }, nil -} - -// Print prints issues based on the formats defined. -// -//nolint:gocyclo,funlen // the complexity is related to the number of formats. -func (c *Printer) Print(issues []*result.Issue) error { - if c.cfg.IsEmpty() { - c.cfg.Text.Path = outputStdOut - } - - var printers []issuePrinter - - if c.cfg.Text.Path != "" { - w, closer, err := c.createWriter(&c.cfg.Text.SimpleFormat) - if err != nil { - return fmt.Errorf("can't create output for %s: %w", c.cfg.Text.Path, err) - } - - defer closer() - - printers = append(printers, NewText(c.log, w, &c.cfg.Text)) - } - - if c.cfg.JSON.Path != "" { - w, closer, err := c.createWriter(&c.cfg.JSON) - if err != nil { - return fmt.Errorf("can't create output for %s: %w", c.cfg.JSON.Path, err) - } - - defer closer() - - printers = append(printers, NewJSON(w, c.reportData)) - } - - if c.cfg.Tab.Path != "" { - w, closer, err := c.createWriter(&c.cfg.Tab.SimpleFormat) - if err != nil { - return fmt.Errorf("can't create output for %s: %w", c.cfg.Tab.Path, err) - } - - defer closer() - - printers = append(printers, NewTab(c.log, w, &c.cfg.Tab)) - } - - if c.cfg.HTML.Path != "" { - w, closer, err := c.createWriter(&c.cfg.HTML) - if err != nil { - return fmt.Errorf("can't create output for %s: %w", c.cfg.HTML.Path, err) - } - - defer closer() - - printers = append(printers, NewHTML(w)) - } - - if c.cfg.Checkstyle.Path != "" { - w, closer, err := c.createWriter(&c.cfg.Checkstyle) - if err != nil { - return fmt.Errorf("can't create output for %s: %w", c.cfg.Checkstyle.Path, err) - } - - defer closer() - - printers = append(printers, NewCheckstyle(c.log, w)) - } - - if c.cfg.CodeClimate.Path != "" { - w, closer, err := c.createWriter(&c.cfg.CodeClimate) - if err != nil { - return fmt.Errorf("can't create output for %s: %w", c.cfg.CodeClimate.Path, err) - } - - defer closer() - - printers = append(printers, NewCodeClimate(c.log, w)) - } - - if c.cfg.JUnitXML.Path != "" { - w, closer, err := c.createWriter(&c.cfg.JUnitXML.SimpleFormat) - if err != nil { - return fmt.Errorf("can't create output for %s: %w", c.cfg.JUnitXML.Path, err) - } - - defer closer() - - printers = append(printers, NewJUnitXML(w, c.cfg.JUnitXML.Extended)) - } - - if c.cfg.TeamCity.Path != "" { - w, closer, err := c.createWriter(&c.cfg.TeamCity) - if err != nil { - return fmt.Errorf("can't create output for %s: %w", c.cfg.TeamCity.Path, err) - } - - defer closer() - - printers = append(printers, NewTeamCity(c.log, w)) - } - - if c.cfg.Sarif.Path != "" { - w, closer, err := c.createWriter(&c.cfg.Sarif) - if err != nil { - return fmt.Errorf("can't create output for %s: %w", c.cfg.Sarif.Path, err) - } - - defer closer() - - printers = append(printers, NewSarif(c.log, w)) - } - - for _, printer := range printers { - err := printer.Print(issues) - if err != nil { - return err - } - } - - return nil -} - -func (c *Printer) createWriter(cfg *config.SimpleFormat) (io.Writer, func(), error) { - if cfg.Path == "" || cfg.Path == outputStdOut { - return c.stdOut, func() {}, nil - } - - if cfg.Path == outputStdErr { - return c.stdErr, func() {}, nil - } - - if !filepath.IsAbs(cfg.Path) { - cfg.Path = filepath.Join(c.basePath, cfg.Path) - } - - err := os.MkdirAll(filepath.Dir(cfg.Path), os.ModePerm) - if err != nil { - return nil, func() {}, err - } - - f, err := os.OpenFile(cfg.Path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, defaultFileMode) - if err != nil { - return nil, func() {}, err - } - - return f, func() { _ = f.Close() }, nil -} - -type severitySanitizer struct { - allowedSeverities []string - defaultSeverity string - - unsupportedSeverities map[string]struct{} -} - -func (s *severitySanitizer) Sanitize(severity string) string { - if slices.Contains(s.allowedSeverities, severity) { - return severity - } - - if s.unsupportedSeverities == nil { - s.unsupportedSeverities = make(map[string]struct{}) - } - - s.unsupportedSeverities[severity] = struct{}{} - - return s.defaultSeverity -} - -func (s *severitySanitizer) Err() error { - if len(s.unsupportedSeverities) == 0 { - return nil - } - - var names []string - for k := range s.unsupportedSeverities { - names = append(names, "'"+k+"'") - } - - return fmt.Errorf("severities (%v) are not inside supported values (%v), fallback to '%s'", - strings.Join(names, ", "), strings.Join(s.allowedSeverities, ", "), s.defaultSeverity) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/sarif.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/sarif.go deleted file mode 100644 index e1caf179a8..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/sarif.go +++ /dev/null @@ -1,126 +0,0 @@ -package printers - -import ( - "encoding/json" - "io" - - "github.com/golangci/golangci-lint/v2/pkg/logutils" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -const ( - sarifVersion = "2.1.0" - sarifSchemaURI = "https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.6.json" -) - -const defaultSarifSeverity = "error" - -// Sarif prints issues in the SARIF format. -// https://sarifweb.azurewebsites.net/ -// https://docs.oasis-open.org/sarif/sarif/v2.1.0/ -type Sarif struct { - log logutils.Log - w io.Writer - sanitizer severitySanitizer -} - -func NewSarif(log logutils.Log, w io.Writer) *Sarif { - return &Sarif{ - log: log.Child(logutils.DebugKeySarifPrinter), - w: w, - sanitizer: severitySanitizer{ - // https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/sarif-v2.1.0-errata01-os-complete.html#_Toc141790898 - allowedSeverities: []string{"none", "note", "warning", defaultSarifSeverity}, - defaultSeverity: defaultSarifSeverity, - }, - } -} - -func (p *Sarif) Print(issues []*result.Issue) error { - run := sarifRun{} - run.Tool.Driver.Name = "golangci-lint" - run.Results = make([]sarifResult, 0) - - for _, issue := range issues { - sr := sarifResult{ - RuleID: issue.FromLinter, - Level: p.sanitizer.Sanitize(issue.Severity), - Message: sarifMessage{Text: issue.Text}, - Locations: []sarifLocation{ - { - PhysicalLocation: sarifPhysicalLocation{ - ArtifactLocation: sarifArtifactLocation{URI: issue.FilePath()}, - Region: sarifRegion{ - StartLine: issue.Line(), - // If startColumn is absent, it SHALL default to 1. - // https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/sarif-v2.1.0-errata01-os-complete.html#_Toc141790941 - StartColumn: max(1, issue.Column()), - }, - }, - }, - }, - } - - run.Results = append(run.Results, sr) - } - - err := p.sanitizer.Err() - if err != nil { - p.log.Infof("%v", err) - } - - output := SarifOutput{ - Version: sarifVersion, - Schema: sarifSchemaURI, - Runs: []sarifRun{run}, - } - - return json.NewEncoder(p.w).Encode(output) -} - -type SarifOutput struct { - Version string `json:"version"` - Schema string `json:"$schema"` - Runs []sarifRun `json:"runs"` -} - -type sarifRun struct { - Tool sarifTool `json:"tool"` - Results []sarifResult `json:"results"` -} - -type sarifTool struct { - Driver struct { - Name string `json:"name"` - } `json:"driver"` -} - -type sarifResult struct { - RuleID string `json:"ruleId"` - Level string `json:"level"` - Message sarifMessage `json:"message"` - Locations []sarifLocation `json:"locations"` -} - -type sarifMessage struct { - Text string `json:"text"` -} - -type sarifLocation struct { - PhysicalLocation sarifPhysicalLocation `json:"physicalLocation"` -} - -type sarifPhysicalLocation struct { - ArtifactLocation sarifArtifactLocation `json:"artifactLocation"` - Region sarifRegion `json:"region"` -} - -type sarifArtifactLocation struct { - URI string `json:"uri"` - Index int `json:"index"` -} - -type sarifRegion struct { - StartLine int `json:"startLine"` - StartColumn int `json:"startColumn"` -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/tab.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/tab.go deleted file mode 100644 index 8edbb05e11..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/tab.go +++ /dev/null @@ -1,69 +0,0 @@ -package printers - -import ( - "fmt" - "io" - "text/tabwriter" - - "github.com/fatih/color" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/logutils" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -// Tab prints issues using tabulation as a field separator. -type Tab struct { - printLinterName bool - colors bool - - log logutils.Log - w io.Writer -} - -func NewTab(log logutils.Log, w io.Writer, cfg *config.Tab) *Tab { - return &Tab{ - printLinterName: cfg.PrintLinterName, - colors: cfg.Colors, - log: log.Child(logutils.DebugKeyTabPrinter), - w: w, - } -} - -func (p *Tab) SprintfColored(ca color.Attribute, format string, args ...any) string { - c := color.New(ca) - - if !p.colors { - c.DisableColor() - } - - return c.Sprintf(format, args...) -} - -func (p *Tab) Print(issues []*result.Issue) error { - w := tabwriter.NewWriter(p.w, 0, 0, 2, ' ', 0) - - for _, issue := range issues { - p.printIssue(issue, w) - } - - if err := w.Flush(); err != nil { - p.log.Warnf("Can't flush tab writer: %s", err) - } - - return nil -} - -func (p *Tab) printIssue(issue *result.Issue, w io.Writer) { - text := p.SprintfColored(color.FgRed, "%s", issue.Text) - if p.printLinterName { - text = fmt.Sprintf("%s\t%s", issue.FromLinter, text) - } - - pos := p.SprintfColored(color.Bold, "%s:%d", issue.FilePath(), issue.Line()) - if issue.Pos.Column != 0 { - pos += fmt.Sprintf(":%d", issue.Pos.Column) - } - - fmt.Fprintf(w, "%s\t%s\n", pos, text) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/teamcity.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/teamcity.go deleted file mode 100644 index 36114fedfc..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/teamcity.go +++ /dev/null @@ -1,134 +0,0 @@ -package printers - -import ( - "fmt" - "io" - "strings" - - "github.com/golangci/golangci-lint/v2/pkg/logutils" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -// Field limits. -const ( - smallLimit = 255 - largeLimit = 4000 -) - -const defaultTeamCitySeverity = "ERROR" - -// TeamCity prints issues in the TeamCity format. -// https://www.jetbrains.com/help/teamcity/service-messages.html -type TeamCity struct { - log logutils.Log - w io.Writer - escaper *strings.Replacer - sanitizer severitySanitizer -} - -// NewTeamCity output format outputs issues according to TeamCity service message format. -func NewTeamCity(log logutils.Log, w io.Writer) *TeamCity { - return &TeamCity{ - log: log.Child(logutils.DebugKeyTeamCityPrinter), - w: w, - // https://www.jetbrains.com/help/teamcity/service-messages.html#Escaped+Values - escaper: strings.NewReplacer( - "'", "|'", - "\n", "|n", - "\r", "|r", - "|", "||", - "[", "|[", - "]", "|]", - ), - sanitizer: severitySanitizer{ - // https://www.jetbrains.com/help/teamcity/service-messages.html#Inspection+Instance - allowedSeverities: []string{"INFO", defaultTeamCitySeverity, "WARNING", "WEAK WARNING"}, - defaultSeverity: defaultTeamCitySeverity, - }, - } -} - -func (p *TeamCity) Print(issues []*result.Issue) error { - uniqLinters := map[string]struct{}{} - - for _, issue := range issues { - _, ok := uniqLinters[issue.FromLinter] - if !ok { - inspectionType := InspectionType{ - id: issue.FromLinter, - name: issue.FromLinter, - description: issue.FromLinter, - category: "Golangci-lint reports", - } - - _, err := inspectionType.Print(p.w, p.escaper) - if err != nil { - return err - } - - uniqLinters[issue.FromLinter] = struct{}{} - } - - instance := InspectionInstance{ - typeID: issue.FromLinter, - message: issue.Text, - file: issue.FilePath(), - line: issue.Line(), - severity: p.sanitizer.Sanitize(strings.ToUpper(issue.Severity)), - } - - _, err := instance.Print(p.w, p.escaper) - if err != nil { - return err - } - } - - err := p.sanitizer.Err() - if err != nil { - p.log.Infof("%v", err) - } - - return nil -} - -// InspectionType is the unique description of the conducted inspection. Each specific warning or -// an error in code (inspection instance) has an inspection type. -// https://www.jetbrains.com/help/teamcity/service-messages.html#Inspection+Type -type InspectionType struct { - id string // (mandatory) limited by 255 characters. - name string // (mandatory) limited by 255 characters. - description string // (mandatory) limited by 255 characters. - category string // (mandatory) limited by 4000 characters. -} - -func (i InspectionType) Print(w io.Writer, escaper *strings.Replacer) (int, error) { - return fmt.Fprintf(w, "##teamcity[inspectionType id='%s' name='%s' description='%s' category='%s']\n", - cutVal(i.id, smallLimit), cutVal(i.name, smallLimit), cutVal(escaper.Replace(i.description), largeLimit), cutVal(i.category, smallLimit)) -} - -// InspectionInstance reports a specific defect, warning, error message. -// Includes location, description, and various optional and custom attributes. -// https://www.jetbrains.com/help/teamcity/service-messages.html#Inspection+Instance -type InspectionInstance struct { - typeID string // (mandatory) limited by 255 characters. - message string // (optional) limited by 4000 characters. - file string // (mandatory) file path limited by 4000 characters. - line int // (optional) line of the file. - severity string // (optional) any linter severity. -} - -func (i InspectionInstance) Print(w io.Writer, replacer *strings.Replacer) (int, error) { - return fmt.Fprintf(w, "##teamcity[inspection typeId='%s' message='%s' file='%s' line='%d' SEVERITY='%s']\n", - cutVal(i.typeID, smallLimit), - cutVal(replacer.Replace(i.message), largeLimit), - cutVal(i.file, largeLimit), - i.line, i.severity) -} - -func cutVal(s string, limit int) string { - runes := []rune(s) - if len(runes) > limit { - return string(runes[:limit]) - } - return s -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/text.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/text.go deleted file mode 100644 index eb9297615b..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/printers/text.go +++ /dev/null @@ -1,96 +0,0 @@ -package printers - -import ( - "fmt" - "io" - "strings" - - "github.com/fatih/color" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/logutils" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -// Text prints issues with a human friendly representation. -type Text struct { - printLinterName bool - printIssuedLine bool - colors bool - - log logutils.Log - w io.Writer -} - -func NewText(log logutils.Log, w io.Writer, cfg *config.Text) *Text { - return &Text{ - printLinterName: cfg.PrintLinterName, - printIssuedLine: cfg.PrintIssuedLine, - colors: cfg.Colors, - log: log.Child(logutils.DebugKeyTextPrinter), - w: w, - } -} - -func (p *Text) SprintfColored(ca color.Attribute, format string, args ...any) string { - c := color.New(ca) - - if !p.colors { - c.DisableColor() - } - - return c.Sprintf(format, args...) -} - -func (p *Text) Print(issues []*result.Issue) error { - for _, issue := range issues { - p.printIssue(issue) - - if !p.printIssuedLine { - continue - } - - p.printSourceCode(issue) - p.printUnderLinePointer(issue) - } - - return nil -} - -func (p *Text) printIssue(issue *result.Issue) { - text := p.SprintfColored(color.FgRed, "%s", strings.TrimSpace(issue.Text)) - if p.printLinterName { - text += fmt.Sprintf(" (%s)", issue.FromLinter) - } - pos := p.SprintfColored(color.Bold, "%s:%d", issue.FilePath(), issue.Line()) - if issue.Pos.Column != 0 { - pos += fmt.Sprintf(":%d", issue.Pos.Column) - } - fmt.Fprintf(p.w, "%s: %s\n", pos, text) -} - -func (p *Text) printSourceCode(issue *result.Issue) { - for _, line := range issue.SourceLines { - fmt.Fprintln(p.w, line) - } -} - -func (p *Text) printUnderLinePointer(issue *result.Issue) { - // if column == 0 it means column is unknown (e.g. for gosec) - if len(issue.SourceLines) != 1 || issue.Pos.Column == 0 { - return - } - - col0 := issue.Pos.Column - 1 - line := issue.SourceLines[0] - prefixRunes := make([]rune, 0, len(line)) - for j := 0; j < len(line) && j < col0; j++ { - if line[j] == '\t' { - prefixRunes = append(prefixRunes, '\t') - } else { - prefixRunes = append(prefixRunes, ' ') - } - } - - fmt.Fprintf(p.w, "%s%s\n", string(prefixRunes), p.SprintfColored(color.FgYellow, "^")) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/report/data.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/report/data.go deleted file mode 100644 index 7aedc55224..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/report/data.go +++ /dev/null @@ -1,24 +0,0 @@ -package report - -type Warning struct { - Tag string `json:",omitempty"` - Text string -} - -type LinterData struct { - Name string - Enabled bool `json:",omitempty"` -} - -type Data struct { - Warnings []Warning `json:",omitempty"` - Linters []LinterData `json:",omitempty"` - Error string `json:",omitempty"` -} - -func (d *Data) AddLinter(name string, enabled bool) { - d.Linters = append(d.Linters, LinterData{ - Name: name, - Enabled: enabled, - }) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/report/log.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/report/log.go deleted file mode 100644 index c964af5593..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/report/log.go +++ /dev/null @@ -1,65 +0,0 @@ -package report - -import ( - "fmt" - "slices" - "strings" - - "github.com/golangci/golangci-lint/v2/pkg/logutils" -) - -type LogWrapper struct { - rd *Data - tags []string - origLog logutils.Log -} - -func NewLogWrapper(log logutils.Log, reportData *Data) *LogWrapper { - return &LogWrapper{ - rd: reportData, - origLog: log, - } -} - -func (lw LogWrapper) Fatalf(format string, args ...any) { - lw.origLog.Fatalf(format, args...) -} - -func (lw LogWrapper) Panicf(format string, args ...any) { - lw.origLog.Panicf(format, args...) -} - -func (lw LogWrapper) Errorf(format string, args ...any) { - lw.origLog.Errorf(format, args...) - lw.rd.Error = fmt.Sprintf(format, args...) -} - -func (lw LogWrapper) Warnf(format string, args ...any) { - lw.origLog.Warnf(format, args...) - w := Warning{ - Tag: strings.Join(lw.tags, "/"), - Text: fmt.Sprintf(format, args...), - } - - lw.rd.Warnings = append(lw.rd.Warnings, w) -} - -func (lw LogWrapper) Infof(format string, args ...any) { - lw.origLog.Infof(format, args...) -} - -func (lw LogWrapper) Child(name string) logutils.Log { - c := lw - c.origLog = lw.origLog.Child(name) - c.tags = slices.Clone(lw.tags) - c.tags = append(c.tags, name) - return c -} - -func (lw LogWrapper) SetLevel(level logutils.LogLevel) { - lw.origLog.SetLevel(level) -} - -func (lw LogWrapper) GoString() string { - return fmt.Sprintf("lw: %+v, orig log: %#v", lw, lw.origLog) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/issue.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/issue.go deleted file mode 100644 index 2587ffff2c..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/issue.go +++ /dev/null @@ -1,93 +0,0 @@ -package result - -import ( - "crypto/md5" //nolint:gosec // for md5 hash - "fmt" - "go/token" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/packages" -) - -type Range struct { - From, To int -} - -type Issue struct { - FromLinter string - Text string - - Severity string - - // Source lines of a code with the issue to show - SourceLines []string - - // Pkg is needed for proper caching of linting results - Pkg *packages.Package `json:"-"` - - Pos token.Position - - LineRange *Range `json:",omitempty"` - - // HunkPos is used only when golangci-lint is run over a diff - HunkPos int `json:",omitempty"` - - // If we know how to fix the issue, we can provide replacement lines - SuggestedFixes []analysis.SuggestedFix `json:",omitempty"` - - // If we are expecting a nolint (because this is from nolintlint), record the expected linter - ExpectNoLint bool - ExpectedNoLintLinter string - - // Only for Diff processor needs. - WorkingDirectoryRelativePath string `json:"-"` - - // Only for processors that need relative paths evaluation. - RelativePath string `json:"-"` -} - -func (i *Issue) FilePath() string { - return i.Pos.Filename -} - -func (i *Issue) Line() int { - return i.Pos.Line -} - -func (i *Issue) Column() int { - return i.Pos.Column -} - -func (i *Issue) GetLineRange() Range { - if i.LineRange == nil { - return Range{ - From: i.Line(), - To: i.Line(), - } - } - - if i.LineRange.From == 0 { - return Range{ - From: i.Line(), - To: i.Line(), - } - } - - return *i.LineRange -} - -func (i *Issue) Description() string { - return fmt.Sprintf("%s: %s", i.FromLinter, i.Text) -} - -func (i *Issue) Fingerprint() string { - firstLine := "" - if len(i.SourceLines) > 0 { - firstLine = i.SourceLines[0] - } - - hash := md5.New() //nolint:gosec // we don't need a strong hash here - _, _ = fmt.Fprintf(hash, "%s%s%s", i.Pos.Filename, i.Text, firstLine) - - return fmt.Sprintf("%X", hash.Sum(nil)) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/base_rule.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/base_rule.go deleted file mode 100644 index 4688662484..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/base_rule.go +++ /dev/null @@ -1,102 +0,0 @@ -package processors - -import ( - "regexp" - "slices" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/fsutils" - "github.com/golangci/golangci-lint/v2/pkg/logutils" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -type baseRule struct { - text *regexp.Regexp - source *regexp.Regexp - path *regexp.Regexp - pathExcept *regexp.Regexp - linters []string -} - -// The usage of `regexp.MustCompile()` is safe here, -// because the regular expressions are checked before inside [config.BaseRule.Validate]. -func newBaseRule(rule *config.BaseRule, prefix string) baseRule { - base := baseRule{ - linters: rule.Linters, - } - - if rule.Text != "" { - base.text = regexp.MustCompile(prefix + rule.Text) - } - - if rule.Source != "" { - base.source = regexp.MustCompile(prefix + rule.Source) - } - - if rule.Path != "" { - base.path = regexp.MustCompile(fsutils.NormalizePathInRegex(rule.Path)) - } - - if rule.PathExcept != "" { - base.pathExcept = regexp.MustCompile(fsutils.NormalizePathInRegex(rule.PathExcept)) - } - - return base -} - -func (r *baseRule) isEmpty() bool { - return r.text == nil && r.source == nil && r.path == nil && r.pathExcept == nil && len(r.linters) == 0 -} - -func (r *baseRule) match(issue *result.Issue, lines *fsutils.LineCache, log logutils.Log) bool { - if r.isEmpty() { - return false - } - if r.text != nil && !r.text.MatchString(issue.Text) { - return false - } - if r.path != nil && !r.path.MatchString(issue.RelativePath) { - return false - } - if r.pathExcept != nil && r.pathExcept.MatchString(issue.RelativePath) { - return false - } - if len(r.linters) != 0 && !r.matchLinter(issue) { - return false - } - - // the most heavyweight checking last - if r.source != nil && !r.matchSource(issue, lines, log) { - return false - } - - return true -} - -func (r *baseRule) matchLinter(issue *result.Issue) bool { - return slices.Contains(r.linters, issue.FromLinter) -} - -func (r *baseRule) matchSource(issue *result.Issue, lineCache *fsutils.LineCache, log logutils.Log) bool { - sourceLine, errSourceLine := lineCache.GetLine(issue.FilePath(), issue.Line()) - if errSourceLine != nil { - log.Warnf("Failed to get line %s:%d from line cache: %s", issue.FilePath(), issue.Line(), errSourceLine) - return false // can't properly match - } - - return r.source.MatchString(sourceLine) -} - -func parseRules[T, V any](rules []T, prefix string, newFn func(*T, string) V) []V { - if len(rules) == 0 { - return nil - } - - parsedRules := make([]V, 0, len(rules)) - - for _, r := range rules { - parsedRules = append(parsedRules, newFn(&r, prefix)) - } - - return parsedRules -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/cgo.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/cgo.go deleted file mode 100644 index 4cc7b57dbf..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/cgo.go +++ /dev/null @@ -1,52 +0,0 @@ -package processors - -import ( - "path/filepath" - "strings" - - "github.com/ldez/grignotin/goenv" - - "github.com/golangci/golangci-lint/v2/pkg/goutil" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -var _ Processor = (*Cgo)(nil) - -// Cgo filters cgo artifacts. -// -// Some linters (e.g. gosec, etc.) return incorrect file paths for cgo files. -// -// Require absolute file path. -type Cgo struct { - goCacheDir string -} - -func NewCgo(env *goutil.Env) *Cgo { - return &Cgo{ - goCacheDir: env.Get(goenv.GOCACHE), - } -} - -func (*Cgo) Name() string { - return "cgo" -} - -func (p *Cgo) Process(issues []*result.Issue) ([]*result.Issue, error) { - return filterIssuesErr(issues, p.shouldPassIssue) -} - -func (*Cgo) Finish() {} - -func (p *Cgo) shouldPassIssue(issue *result.Issue) (bool, error) { - // [p.goCacheDir] contains all preprocessed files including cgo files. - if p.goCacheDir != "" && strings.HasPrefix(issue.FilePath(), p.goCacheDir) { - return false, nil - } - - if filepath.Base(issue.FilePath()) == "_cgo_gotypes.go" { - // skip cgo warning for go1.10 - return false, nil - } - - return true, nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/diff.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/diff.go deleted file mode 100644 index 15574ff0d3..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/diff.go +++ /dev/null @@ -1,100 +0,0 @@ -package processors - -import ( - "bytes" - "context" - "fmt" - "io" - "os" - "strings" - - "github.com/golangci/revgrep" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -const envGolangciDiffProcessorPatch = "GOLANGCI_DIFF_PROCESSOR_PATCH" - -var _ Processor = (*Diff)(nil) - -// Diff filters issues based on options `new`, `new-from-rev`, etc. -// -// Uses `git`. -// The paths inside the patch are relative to the path where git is run (the same location where golangci-lint is run). -// -// Warning: it doesn't use `path-prefix` option. -type Diff struct { - onlyNew bool - fromRev string - fromMergeBase string - patchFilePath string - wholeFiles bool - patch string -} - -func NewDiff(cfg *config.Issues) *Diff { - return &Diff{ - onlyNew: cfg.Diff, - fromRev: cfg.DiffFromRevision, - fromMergeBase: cfg.DiffFromMergeBase, - patchFilePath: cfg.DiffPatchFilePath, - wholeFiles: cfg.WholeFiles, - patch: os.Getenv(envGolangciDiffProcessorPatch), - } -} - -func (*Diff) Name() string { - return "diff" -} - -func (p *Diff) Process(issues []*result.Issue) ([]*result.Issue, error) { - if !p.onlyNew && p.fromRev == "" && p.fromMergeBase == "" && p.patchFilePath == "" && p.patch == "" { - return issues, nil - } - - var patchReader io.Reader - switch { - case p.patchFilePath != "": - patch, err := os.ReadFile(p.patchFilePath) - if err != nil { - return nil, fmt.Errorf("can't read from patch file %s: %w", p.patchFilePath, err) - } - - patchReader = bytes.NewReader(patch) - - case p.patch != "": - patchReader = strings.NewReader(p.patch) - } - - checker := revgrep.Checker{ - Patch: patchReader, - RevisionFrom: p.fromRev, - MergeBase: p.fromMergeBase, - WholeFiles: p.wholeFiles, - } - - err := checker.Prepare(context.Background()) - if err != nil { - return nil, fmt.Errorf("can't prepare diff by revgrep: %w", err) - } - - return transformIssues(issues, func(issue *result.Issue) *result.Issue { - if issue.FromLinter == typeCheckName { - // Never hide typechecking errors. - return issue - } - - hunkPos, isNew := checker.IsNew(issue.WorkingDirectoryRelativePath, issue.Line()) - if !isNew { - return nil - } - - newIssue := *issue - newIssue.HunkPos = hunkPos - - return &newIssue - }), nil -} - -func (*Diff) Finish() {} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/exclusion_generated_file_filter.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/exclusion_generated_file_filter.go deleted file mode 100644 index d76ec3184f..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/exclusion_generated_file_filter.go +++ /dev/null @@ -1,77 +0,0 @@ -package processors - -import ( - "fmt" - "path/filepath" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/logutils" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -var _ Processor = (*GeneratedFileFilter)(nil) - -type fileSummary struct { - generated bool -} - -// GeneratedFileFilter filters generated files. -type GeneratedFileFilter struct { - debugf logutils.DebugFunc - - mode string - matcher *GeneratedFileMatcher - - fileSummaryCache map[string]*fileSummary -} - -func NewGeneratedFileFilter(mode string) *GeneratedFileFilter { - return &GeneratedFileFilter{ - debugf: logutils.Debug(logutils.DebugKeyGeneratedFileFilter), - - mode: mode, - matcher: NewGeneratedFileMatcher(mode), - - fileSummaryCache: map[string]*fileSummary{}, - } -} - -func (*GeneratedFileFilter) Name() string { - return "generated_file_filter" -} - -func (p *GeneratedFileFilter) Process(issues []*result.Issue) ([]*result.Issue, error) { - if p.mode == config.GeneratedModeDisable { - return issues, nil - } - - return filterIssuesErr(issues, p.shouldPassIssue) -} - -func (*GeneratedFileFilter) Finish() {} - -func (p *GeneratedFileFilter) shouldPassIssue(issue *result.Issue) (bool, error) { - if filepath.Base(issue.FilePath()) == "go.mod" { - return true, nil - } - - // The file is already known. - fs := p.fileSummaryCache[issue.FilePath()] - if fs != nil { - return !fs.generated, nil - } - - fs = &fileSummary{} - p.fileSummaryCache[issue.FilePath()] = fs - - var err error - fs.generated, err = p.matcher.IsGeneratedFile(issue.FilePath(), nil) - if err != nil { - return false, fmt.Errorf("failed to get doc (%s) of file %s: %w", p.mode, issue.FilePath(), err) - } - - p.debugf("file %q is generated: %t", issue.FilePath(), fs.generated) - - // don't report issues for autogenerated files - return !fs.generated, nil -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/exclusion_generated_file_matcher.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/exclusion_generated_file_matcher.go deleted file mode 100644 index 763ca9e38f..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/exclusion_generated_file_matcher.go +++ /dev/null @@ -1,107 +0,0 @@ -package processors - -import ( - "fmt" - "go/ast" - "go/parser" - "go/token" - "strings" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/logutils" -) - -// The values must be in lowercase. -const ( - genCodeGenerated = "code generated" - genDoNotEdit = "do not edit" - - // Related to easyjson. - genAutoFile = "autogenerated file" - - //nolint:lll // Long URL - // Related to Swagger Codegen. - // https://github.com/swagger-api/swagger-codegen/blob/61cfeac3b9d855b4eb8bffa0d118bece117bcb7d/modules/swagger-codegen/src/main/resources/go/partial_header.mustache#L16 - // https://github.com/swagger-api/swagger-codegen/issues/12358 - genSwaggerCodegen = "* generated by: swagger codegen " -) - -// GeneratedFileMatcher detects generated files. -// - mode "lax": see `isGeneratedFileLax` documentation. -// - mode "strict": see `isGeneratedFileStrict` documentation. -// - mode "disable": skips this processor. -type GeneratedFileMatcher struct { - debugf logutils.DebugFunc - - mode string -} - -func NewGeneratedFileMatcher(mode string) *GeneratedFileMatcher { - return &GeneratedFileMatcher{ - debugf: logutils.Debug(logutils.DebugKeyGeneratedFileFilter), - mode: mode, - } -} - -func (p *GeneratedFileMatcher) IsGeneratedFile(filepath string, src any) (bool, error) { - if p.mode == config.GeneratedModeDisable { - return false, nil - } - - file, err := parser.ParseFile(token.NewFileSet(), filepath, src, parser.PackageClauseOnly|parser.ParseComments) - if err != nil { - return false, fmt.Errorf("failed to parse file: %w", err) - } - - if p.mode == config.GeneratedModeStrict { - return isGeneratedFileStrict(file), nil - } - - doc := getComments(file) - - return p.isGeneratedFileLax(doc), nil -} - -// isGeneratedFileLax reports whether the source file is generated code. -// The function uses a bit laxer rules than isGeneratedFileStrict to match more generated code. -// See https://github.com/golangci/golangci-lint/issues/48 and https://github.com/golangci/golangci-lint/issues/72. -func (p *GeneratedFileMatcher) isGeneratedFileLax(doc string) bool { - markers := []string{genCodeGenerated, genDoNotEdit, genAutoFile, genSwaggerCodegen} - - doc = strings.ToLower(doc) - - for _, marker := range markers { - if strings.Contains(doc, marker) { - p.debugf("doc contains marker %q: file is generated", marker) - - return true - } - } - - p.debugf("doc of len %d doesn't contain any of markers: %s", len(doc), markers) - - return false -} - -// isGeneratedFileStrict returns true if the source file has a line that matches the regular expression: -// -// ^// Code generated .* DO NOT EDIT\.$ -// -// This line must appear before the first non-comment, non-blank text in the file. -// Based on https://go.dev/s/generatedcode. -func isGeneratedFileStrict(file *ast.File) bool { - if file == nil || len(file.Comments) == 0 { - return false - } - - return ast.IsGenerated(file) -} - -func getComments(file *ast.File) string { - var docLines []string - for _, c := range file.Comments { - docLines = append(docLines, strings.TrimSpace(c.Text())) - } - - return strings.Join(docLines, "\n") -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/exclusion_paths.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/exclusion_paths.go deleted file mode 100644 index acf13edd07..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/exclusion_paths.go +++ /dev/null @@ -1,118 +0,0 @@ -package processors - -import ( - "fmt" - "regexp" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/fsutils" - "github.com/golangci/golangci-lint/v2/pkg/logutils" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -var _ Processor = (*ExclusionPaths)(nil) - -type ExclusionPaths struct { - pathPatterns []*regexp.Regexp - pathExceptPatterns []*regexp.Regexp - - warnUnused bool - excludedPathCounter map[*regexp.Regexp]int - excludedPathExceptCounter map[*regexp.Regexp]int - - log logutils.Log -} - -func NewExclusionPaths(log logutils.Log, cfg *config.LinterExclusions) (*ExclusionPaths, error) { - excludedPathCounter := make(map[*regexp.Regexp]int) - - var pathPatterns []*regexp.Regexp - for _, p := range cfg.Paths { - p = fsutils.NormalizePathInRegex(p) - - patternRe, err := regexp.Compile(p) - if err != nil { - return nil, fmt.Errorf("can't compile regexp %q: %w", p, err) - } - - pathPatterns = append(pathPatterns, patternRe) - excludedPathCounter[patternRe] = 0 - } - - excludedPathExceptCounter := make(map[*regexp.Regexp]int) - - var pathExceptPatterns []*regexp.Regexp - for _, p := range cfg.PathsExcept { - p = fsutils.NormalizePathInRegex(p) - - patternRe, err := regexp.Compile(p) - if err != nil { - return nil, fmt.Errorf("can't compile regexp %q: %w", p, err) - } - - pathExceptPatterns = append(pathExceptPatterns, patternRe) - excludedPathExceptCounter[patternRe] = 0 - } - - return &ExclusionPaths{ - pathPatterns: pathPatterns, - pathExceptPatterns: pathExceptPatterns, - warnUnused: cfg.WarnUnused, - excludedPathCounter: excludedPathCounter, - excludedPathExceptCounter: excludedPathExceptCounter, - log: log.Child(logutils.DebugKeyExclusionPaths), - }, nil -} - -func (*ExclusionPaths) Name() string { - return "exclusion_paths" -} - -func (p *ExclusionPaths) Process(issues []*result.Issue) ([]*result.Issue, error) { - if len(p.pathPatterns) == 0 && len(p.pathExceptPatterns) == 0 { - return issues, nil - } - - return filterIssues(issues, p.shouldPassIssue), nil -} - -func (p *ExclusionPaths) Finish() { - for pattern, count := range p.excludedPathCounter { - if p.warnUnused && count == 0 { - p.log.Warnf("The pattern %q match no issues", pattern) - } else { - p.log.Infof("Skipped %d issues by pattern %q", count, pattern) - } - } - - for pattern, count := range p.excludedPathExceptCounter { - if p.warnUnused && count == 0 { - p.log.Warnf("The pattern %q match no issues", pattern) - } - } -} - -func (p *ExclusionPaths) shouldPassIssue(issue *result.Issue) bool { - for _, pattern := range p.pathPatterns { - if pattern.MatchString(issue.RelativePath) { - p.excludedPathCounter[pattern]++ - return false - } - } - - if len(p.pathExceptPatterns) == 0 { - return true - } - - matched := false - for _, pattern := range p.pathExceptPatterns { - if !pattern.MatchString(issue.RelativePath) { - continue - } - - p.excludedPathExceptCounter[pattern]++ - matched = true - } - - return matched -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/exclusion_presets.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/exclusion_presets.go deleted file mode 100644 index 4c2fa4c477..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/exclusion_presets.go +++ /dev/null @@ -1,138 +0,0 @@ -package processors - -import "github.com/golangci/golangci-lint/v2/pkg/config" - -var LinterExclusionPresets = map[string][]config.ExcludeRule{ - config.ExclusionPresetComments: { - { - // Annoying issue about not having a comment. The rare codebase has such comments. - // CheckPackageComment, CheckExportedFunctionDocs, CheckExportedTypeDocs, CheckExportedVarDocs - BaseRule: config.BaseRule{ - Text: "(ST1000|ST1020|ST1021|ST1022)", - Linters: []string{"staticcheck"}, - InternalReference: "EXC0011", - }, - }, - { - // Annoying issue about not having a comment. The rare codebase has such comments. - // rule: exported - BaseRule: config.BaseRule{ - Text: `exported (.+) should have comment( \(or a comment on this block\))? or be unexported`, - Linters: []string{"revive"}, - InternalReference: "EXC0012", - }, - }, - { - // Annoying issue about not having a comment. The rare codebase has such comments. - // rule: package-comments - BaseRule: config.BaseRule{ - Text: `package comment should be of the form "(.+)..."`, - Linters: []string{"revive"}, - InternalReference: "EXC0013", - }, - }, - { - // Annoying issue about not having a comment. The rare codebase has such comments. - // rule: exported - BaseRule: config.BaseRule{ - Text: `comment on exported (.+) should be of the form "(.+)..."`, - Linters: []string{"revive"}, - InternalReference: "EXC0014", - }, - }, - { - // Annoying issue about not having a comment. The rare codebase has such comments. - // rule: package-comments - BaseRule: config.BaseRule{ - Text: `should have a package comment`, - Linters: []string{"revive"}, - InternalReference: "EXC0015", - }, - }, - }, - config.ExclusionPresetStdErrorHandling: { - { - // Almost all programs ignore errors on these functions and in most cases it's ok. - BaseRule: config.BaseRule{ - Text: "(?i)Error return value of .((os\\.)?std(out|err)\\..*|.*Close" + - "|.*Flush|os\\.Remove(All)?|.*print(f|ln)?|os\\.(Un)?Setenv). is not checked", - Linters: []string{"errcheck"}, - InternalReference: "EXC0001", - }, - }, - }, - config.ExclusionPresetCommonFalsePositives: { - { - // Too many false-positives on 'unsafe' usage. - BaseRule: config.BaseRule{ - Text: "G103: Use of unsafe calls should be audited", - Linters: []string{"gosec"}, - InternalReference: "EXC0006", - }, - }, - { - // Too many false-positives for parametrized shell calls. - BaseRule: config.BaseRule{ - Text: "G204: Subprocess launched with variable", - Linters: []string{"gosec"}, - InternalReference: "EXC0007", - }, - }, - { - // False positive is triggered by 'src, err := ioutil.ReadFile(filename)'. - BaseRule: config.BaseRule{ - Text: "G304: Potential file inclusion via variable", - Linters: []string{"gosec"}, - InternalReference: "EXC0010", - }, - }, - }, - config.ExclusionPresetLegacy: { - { - // Common false positives. - BaseRule: config.BaseRule{ - Text: "(possible misuse of unsafe.Pointer|should have signature)", - Linters: []string{"govet"}, - InternalReference: "EXC0004", - }, - }, - { - // Developers tend to write in C-style with an explicit 'break' in a 'switch', so it's ok to ignore. - // CheckScopedBreak - BaseRule: config.BaseRule{ - Text: "SA4011", - Linters: []string{"staticcheck"}, - InternalReference: "EXC0005", - }, - }, - { - // Duplicated errcheck checks. - // Errors unhandled. - BaseRule: config.BaseRule{ - Text: "G104", - Linters: []string{"gosec"}, - InternalReference: "EXC0008", - }, - }, - { - // Too many issues in popular repos. - BaseRule: config.BaseRule{ - Text: "(G301|G302|G307): Expect (directory permissions to be 0750|file permissions to be 0600) or less", - Linters: []string{"gosec"}, - InternalReference: "EXC0009", - }, - }, - }, -} - -func getLinterExclusionPresets(names []string) []config.ExcludeRule { - var rules []config.ExcludeRule - - for _, name := range names { - if p, ok := LinterExclusionPresets[name]; ok { - rules = append(rules, p...) - } - } - - return rules -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/exclusion_rules.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/exclusion_rules.go deleted file mode 100644 index 2b5221a890..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/exclusion_rules.go +++ /dev/null @@ -1,123 +0,0 @@ -package processors - -import ( - "fmt" - "slices" - "strings" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/fsutils" - "github.com/golangci/golangci-lint/v2/pkg/logutils" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -var _ Processor = (*ExclusionRules)(nil) - -type ExclusionRules struct { - log logutils.Log - - lines *fsutils.LineCache - - warnUnused bool - skippedCounter map[string]int - - rules []excludeRule -} - -func NewExclusionRules(log logutils.Log, lines *fsutils.LineCache, cfg *config.LinterExclusions) *ExclusionRules { - p := &ExclusionRules{ - log: log, - lines: lines, - warnUnused: cfg.WarnUnused, - skippedCounter: map[string]int{}, - } - - excludeRules := slices.Concat(slices.Clone(cfg.Rules), getLinterExclusionPresets(cfg.Presets)) - - p.rules = parseRules(excludeRules, "", newExcludeRule) - - for _, rule := range p.rules { - if rule.internalReference == "" { - p.skippedCounter[rule.String()] = 0 - } - } - - return p -} - -func (*ExclusionRules) Name() string { - return "exclusion_rules" -} - -func (p *ExclusionRules) Process(issues []*result.Issue) ([]*result.Issue, error) { - if len(p.rules) == 0 { - return issues, nil - } - - return filterIssues(issues, func(issue *result.Issue) bool { - for _, rule := range p.rules { - if !rule.match(issue, p.lines, p.log) { - continue - } - - // Ignore default rules. - if rule.internalReference == "" { - p.skippedCounter[rule.String()]++ - } - - return false - } - - return true - }), nil -} - -func (p *ExclusionRules) Finish() { - for rule, count := range p.skippedCounter { - if p.warnUnused && count == 0 { - p.log.Warnf("Skipped %d issues by rules: [%s]", count, rule) - } else { - p.log.Infof("Skipped %d issues by rules: [%s]", count, rule) - } - } -} - -type excludeRule struct { - baseRule - - // For compatibility with exclude-use-default/include. - internalReference string `mapstructure:"-"` -} - -func newExcludeRule(rule *config.ExcludeRule, prefix string) excludeRule { - return excludeRule{ - baseRule: newBaseRule(&rule.BaseRule, prefix), - internalReference: rule.InternalReference, - } -} - -func (e excludeRule) String() string { - var msg []string - - if e.text != nil && e.text.String() != "" { - msg = append(msg, fmt.Sprintf("Text: %q", e.text)) - } - - if e.source != nil && e.source.String() != "" { - msg = append(msg, fmt.Sprintf("Source: %q", e.source)) - } - - if e.path != nil && e.path.String() != "" { - msg = append(msg, fmt.Sprintf("Path: %q", e.path)) - } - - if e.pathExcept != nil && e.pathExcept.String() != "" { - msg = append(msg, fmt.Sprintf("Path Except: %q", e.pathExcept)) - } - - if len(e.linters) > 0 { - msg = append(msg, fmt.Sprintf("Linters: %q", strings.Join(e.linters, ", "))) - } - - return strings.Join(msg, ", ") -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/filename_unadjuster.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/filename_unadjuster.go deleted file mode 100644 index e39601d5a4..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/filename_unadjuster.go +++ /dev/null @@ -1,130 +0,0 @@ -package processors - -import ( - "go/parser" - "go/token" - "strings" - "sync" - "time" - - "golang.org/x/tools/go/packages" - - "github.com/golangci/golangci-lint/v2/pkg/logutils" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -var _ Processor = (*FilenameUnadjuster)(nil) - -type posMapper func(pos token.Position) token.Position - -type adjustMap struct { - sync.Mutex - m map[string]posMapper -} - -// FilenameUnadjuster fixes filename based on adjusted and unadjusted position (related to line directives and cgo). -// -// A lot of linters use `fset.Position(f.Pos())` to get filename, -// and they return adjusted filename (e.g.` *.qtpl`) for an issue. -// We need restore real `.go` filename to properly output it, parse it, etc. -// -// Require absolute file path. -type FilenameUnadjuster struct { - m map[string]posMapper // map from adjusted filename to position mapper: adjusted -> unadjusted position - log logutils.Log - loggedUnadjustments map[string]bool -} - -func NewFilenameUnadjuster(pkgs []*packages.Package, log logutils.Log) *FilenameUnadjuster { - m := adjustMap{m: map[string]posMapper{}} - - startedAt := time.Now() - - var wg sync.WaitGroup - wg.Add(len(pkgs)) - - for _, pkg := range pkgs { - go func(pkg *packages.Package) { - // It's important to call func here to run GC - processUnadjusterPkg(&m, pkg, log) - wg.Done() - }(pkg) - } - - wg.Wait() - - log.Infof("Pre-built %d adjustments in %s", len(m.m), time.Since(startedAt)) - - return &FilenameUnadjuster{ - m: m.m, - log: log, - loggedUnadjustments: map[string]bool{}, - } -} - -func (*FilenameUnadjuster) Name() string { - return "filename_unadjuster" -} - -func (p *FilenameUnadjuster) Process(issues []*result.Issue) ([]*result.Issue, error) { - return transformIssues(issues, func(issue *result.Issue) *result.Issue { - mapper := p.m[issue.FilePath()] - if mapper == nil { - return issue - } - - newIssue := *issue - newIssue.Pos = mapper(issue.Pos) - if !p.loggedUnadjustments[issue.Pos.Filename] { - p.log.Infof("Unadjusted from %v to %v", issue.Pos, newIssue.Pos) - p.loggedUnadjustments[issue.Pos.Filename] = true - } - return &newIssue - }), nil -} - -func (*FilenameUnadjuster) Finish() {} - -func processUnadjusterPkg(m *adjustMap, pkg *packages.Package, log logutils.Log) { - fset := token.NewFileSet() // it's more memory efficient to not store all in one fset - - for _, filename := range pkg.CompiledGoFiles { - // It's important to call func here to run GC - processUnadjusterFile(filename, m, log, fset) - } -} - -func processUnadjusterFile(filename string, m *adjustMap, log logutils.Log, fset *token.FileSet) { - syntax, err := parser.ParseFile(fset, filename, nil, parser.ParseComments) - if err != nil { - // Error will be reported by typecheck - return - } - - adjustedFilename := fset.PositionFor(syntax.Pos(), true).Filename - if adjustedFilename == "" { - return - } - - unadjustedFilename := fset.PositionFor(syntax.Pos(), false).Filename - if unadjustedFilename == "" || unadjustedFilename == adjustedFilename { - return - } - - if !strings.HasSuffix(unadjustedFilename, ".go") { - return // file.go -> /caches/cgo-xxx - } - - m.Lock() - defer m.Unlock() - - m.m[adjustedFilename] = func(adjustedPos token.Position) token.Position { - tokenFile := fset.File(syntax.Pos()) - if tokenFile == nil { - log.Warnf("Failed to get token file for %s", adjustedFilename) - return adjustedPos - } - - return fset.PositionFor(tokenFile.Pos(adjustedPos.Offset), false) - } -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/fixer.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/fixer.go deleted file mode 100644 index ce33b27fb2..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/fixer.go +++ /dev/null @@ -1,306 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. -// -// This file is inspired by go/analysis/internal/checker/checker.go - -package processors - -import ( - "errors" - "fmt" - "maps" - "os" - "slices" - - "github.com/golangci/golangci-lint/v2/internal/x/tools/diff" - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/fsutils" - "github.com/golangci/golangci-lint/v2/pkg/goformatters" - "github.com/golangci/golangci-lint/v2/pkg/goformatters/gci" - "github.com/golangci/golangci-lint/v2/pkg/goformatters/gofmt" - "github.com/golangci/golangci-lint/v2/pkg/goformatters/gofumpt" - "github.com/golangci/golangci-lint/v2/pkg/goformatters/goimports" - "github.com/golangci/golangci-lint/v2/pkg/goformatters/golines" - "github.com/golangci/golangci-lint/v2/pkg/goformatters/swaggo" - "github.com/golangci/golangci-lint/v2/pkg/logutils" - "github.com/golangci/golangci-lint/v2/pkg/result" - "github.com/golangci/golangci-lint/v2/pkg/timeutils" -) - -var _ Processor = (*Fixer)(nil) - -const filePerm = 0644 - -// Fixer fixes reports if possible. -// The reports that are not fixed are passed to the next processor. -type Fixer struct { - cfg *config.Config - log logutils.Log - fileCache *fsutils.FileCache - sw *timeutils.Stopwatch - formatter *goformatters.MetaFormatter -} - -func NewFixer(cfg *config.Config, log logutils.Log, fileCache *fsutils.FileCache, formatter *goformatters.MetaFormatter) *Fixer { - return &Fixer{ - cfg: cfg, - log: log, - fileCache: fileCache, - sw: timeutils.NewStopwatch("fixer", log), - formatter: formatter, - } -} - -func (Fixer) Name() string { - return "fixer" -} - -func (p Fixer) Process(issues []*result.Issue) ([]*result.Issue, error) { - if !p.cfg.Issues.NeedFix { - return issues, nil - } - - p.log.Infof("Applying suggested fixes") - - notFixableIssues, err := timeutils.TrackStage(p.sw, "all", func() ([]*result.Issue, error) { - return p.process(issues) - }) - if err != nil { - p.log.Warnf("Failed to fix issues: %v", err) - } - - p.printStat() - - return notFixableIssues, nil -} - -//nolint:funlen,gocyclo // This function should not be split. -func (p Fixer) process(issues []*result.Issue) ([]*result.Issue, error) { - // filenames / linters / edits - editsByLinter := make(map[string]map[string][]diff.Edit) - - formatters := []string{gofumpt.Name, goimports.Name, gofmt.Name, gci.Name, golines.Name, swaggo.Name} - - var notFixableIssues []*result.Issue - - toBeFormattedFiles := make(map[string]struct{}) - - for i := range issues { - issue := issues[i] - - if slices.Contains(formatters, issue.FromLinter) { - toBeFormattedFiles[issue.FilePath()] = struct{}{} - continue - } - - if issue.SuggestedFixes == nil || skipNoTextEdit(issue) { - notFixableIssues = append(notFixableIssues, issue) - continue - } - - for _, sf := range issue.SuggestedFixes { - for _, edit := range sf.TextEdits { - start, end := edit.Pos, edit.End - if start > end { - return nil, fmt.Errorf("%q suggests invalid fix: pos (%v) > end (%v)", - issue.FromLinter, edit.Pos, edit.End) - } - - edit := diff.Edit{ - Start: int(start), - End: int(end), - New: string(edit.NewText), - } - - if _, ok := editsByLinter[issue.FilePath()]; !ok { - editsByLinter[issue.FilePath()] = make(map[string][]diff.Edit) - } - - editsByLinter[issue.FilePath()][issue.FromLinter] = append(editsByLinter[issue.FilePath()][issue.FromLinter], edit) - } - } - } - - // Validate and group the edits to each actual file. - editsByPath := make(map[string][]diff.Edit) - for path, linterToEdits := range editsByLinter { - excludedLinters := make(map[string]struct{}) - - linters := slices.Collect(maps.Keys(linterToEdits)) - - // Does any linter create conflicting edits? - for _, linter := range linters { - edits := linterToEdits[linter] - if _, invalid := validateEdits(edits); invalid > 0 { - name, x, y := linter, edits[invalid-1], edits[invalid] - excludedLinters[name] = struct{}{} - - err := diff3Conflict(path, name, name, []diff.Edit{x}, []diff.Edit{y}) - // TODO(ldez) TUI? - p.log.Warnf("Changes related to %q are skipped for the file %q: %v", - name, path, err) - } - } - - // Does any pair of different linters create edits that conflict? - for j := range linters { - for k := range linters[:j] { - x, y := linters[j], linters[k] - if x > y { - x, y = y, x - } - - _, foundX := excludedLinters[x] - _, foundY := excludedLinters[y] - if foundX || foundY { - continue - } - - xedits, yedits := linterToEdits[x], linterToEdits[y] - - combined := slices.Concat(xedits, yedits) - - if _, invalid := validateEdits(combined); invalid > 0 { - excludedLinters[x] = struct{}{} - p.log.Warnf("Changes related to %q are skipped for the file %q due to conflicts with %q.", x, path, y) - } - } - } - - var edits []diff.Edit - for linter := range linterToEdits { - if _, found := excludedLinters[linter]; !found { - edits = append(edits, linterToEdits[linter]...) - } - } - - editsByPath[path], _ = validateEdits(edits) // remove duplicates. already validated. - } - - var editError error - - var formattedFiles []string - - // Now we've got a set of valid edits for each file. Apply them. - for path, edits := range editsByPath { - contents, err := p.fileCache.GetFileBytes(path) - if err != nil { - editError = errors.Join(editError, fmt.Errorf("%s: %w", path, err)) - continue - } - - out, err := diff.ApplyBytes(contents, edits) - if err != nil { - editError = errors.Join(editError, fmt.Errorf("%s: %w", path, err)) - continue - } - - // Try to format the file. - out = p.formatter.Format(path, out) - - if err := os.WriteFile(path, out, filePerm); err != nil { - editError = errors.Join(editError, fmt.Errorf("%s: %w", path, err)) - continue - } - - formattedFiles = append(formattedFiles, path) - } - - for path := range toBeFormattedFiles { - // Skips files already formatted by the previous fix step. - if !slices.Contains(formattedFiles, path) { - content, err := p.fileCache.GetFileBytes(path) - if err != nil { - p.log.Warnf("Error reading file %s: %v", path, err) - continue - } - - out := p.formatter.Format(path, content) - - if err := os.WriteFile(path, out, filePerm); err != nil { - editError = errors.Join(editError, fmt.Errorf("%s: %w", path, err)) - continue - } - } - } - - return notFixableIssues, editError -} - -func (Fixer) Finish() {} - -func (p Fixer) printStat() { - p.sw.PrintStages() -} - -func skipNoTextEdit(issue *result.Issue) bool { - var onlyMessage int - for _, sf := range issue.SuggestedFixes { - if len(sf.TextEdits) == 0 { - onlyMessage++ - } - } - - return len(issue.SuggestedFixes) == onlyMessage -} - -// validateEdits returns a list of edits that is sorted and -// contains no duplicate edits. Returns the index of some -// overlapping adjacent edits if there is one and <0 if the -// edits are valid. -// -//nolint:gocritic // Copy of go/analysis/internal/checker/checker.go -func validateEdits(edits []diff.Edit) ([]diff.Edit, int) { - if len(edits) == 0 { - return nil, -1 - } - - equivalent := func(x, y diff.Edit) bool { - return x.Start == y.Start && x.End == y.End && x.New == y.New - } - - diff.SortEdits(edits) - - unique := []diff.Edit{edits[0]} - - invalid := -1 - - for i := 1; i < len(edits); i++ { - prev, cur := edits[i-1], edits[i] - // We skip over equivalent edits without considering them - // an error. This handles identical edits coming from the - // multiple ways of loading a package into a - // *go/packages.Packages for testing, e.g. packages "p" and "p [p.test]". - if !equivalent(prev, cur) { - unique = append(unique, cur) - if prev.End > cur.Start { - invalid = i - } - } - } - return unique, invalid -} - -// diff3Conflict returns an error describing two conflicting sets of -// edits on a file at path. -// Copy of go/analysis/internal/checker/checker.go -func diff3Conflict(path, xlabel, ylabel string, xedits, yedits []diff.Edit) error { - contents, err := os.ReadFile(path) - if err != nil { - return err - } - oldlabel, old := "base", string(contents) - - xdiff, err := diff.ToUnified(oldlabel, xlabel, old, xedits, diff.DefaultContextLines) - if err != nil { - return err - } - ydiff, err := diff.ToUnified(oldlabel, ylabel, old, yedits, diff.DefaultContextLines) - if err != nil { - return err - } - - return fmt.Errorf("conflicting edits from %s and %s on %s\nfirst edits:\n%s\nsecond edits:\n%s", - xlabel, ylabel, path, xdiff, ydiff) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/invalid_issue.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/invalid_issue.go deleted file mode 100644 index fa1b19e82c..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/invalid_issue.go +++ /dev/null @@ -1,63 +0,0 @@ -package processors - -import ( - "path/filepath" - - "github.com/golangci/golangci-lint/v2/pkg/logutils" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -var _ Processor = (*InvalidIssue)(nil) - -// InvalidIssue filters invalid reports. -// - non-go files (except `go.mod`) -// - reports without file path -type InvalidIssue struct { - log logutils.Log -} - -func NewInvalidIssue(log logutils.Log) *InvalidIssue { - return &InvalidIssue{log: log} -} - -func (InvalidIssue) Name() string { - return "invalid_issue" -} - -func (p InvalidIssue) Process(issues []*result.Issue) ([]*result.Issue, error) { - tcIssues := filterIssuesUnsafe(issues, func(issue *result.Issue) bool { - return issue.FromLinter == typeCheckName - }) - - if len(tcIssues) > 0 { - return tcIssues, nil - } - - return filterIssuesErr(issues, p.shouldPassIssue) -} - -func (InvalidIssue) Finish() {} - -func (p InvalidIssue) shouldPassIssue(issue *result.Issue) (bool, error) { - if issue.FilePath() == "" { - p.log.Warnf("no file path for the issue: probably a bug inside the linter %q: %#v", issue.FromLinter, issue) - - return false, nil - } - - if filepath.Base(issue.FilePath()) == "go.mod" { - return true, nil - } - - if !isGoFile(issue.FilePath()) { - p.log.Infof("issue related to file %s is skipped", issue.FilePath()) - - return false, nil - } - - return true, nil -} - -func isGoFile(name string) bool { - return filepath.Ext(name) == ".go" -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/issues.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/issues.go deleted file mode 100644 index cc4deeb526..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/issues.go +++ /dev/null @@ -1,69 +0,0 @@ -package processors - -import ( - "fmt" - - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -func filterIssues(issues []*result.Issue, filter func(issue *result.Issue) bool) []*result.Issue { - retIssues := make([]*result.Issue, 0, len(issues)) - for _, issue := range issues { - if issue.FromLinter == typeCheckName { - // don't hide typechecking errors in generated files: users expect to see why the project isn't compiling - retIssues = append(retIssues, issue) - continue - } - - if filter(issue) { - retIssues = append(retIssues, issue) - } - } - - return retIssues -} - -func filterIssuesUnsafe(issues []*result.Issue, filter func(issue *result.Issue) bool) []*result.Issue { - retIssues := make([]*result.Issue, 0, len(issues)) - for _, issue := range issues { - if filter(issue) { - retIssues = append(retIssues, issue) - } - } - - return retIssues -} - -func filterIssuesErr(issues []*result.Issue, filter func(issue *result.Issue) (bool, error)) ([]*result.Issue, error) { - retIssues := make([]*result.Issue, 0, len(issues)) - for _, issue := range issues { - if issue.FromLinter == typeCheckName { - // don't hide typechecking errors in generated files: users expect to see why the project isn't compiling - retIssues = append(retIssues, issue) - continue - } - - ok, err := filter(issue) - if err != nil { - return nil, fmt.Errorf("can't filter issue %#v: %w", issue, err) - } - - if ok { - retIssues = append(retIssues, issue) - } - } - - return retIssues, nil -} - -func transformIssues(issues []*result.Issue, transform func(issue *result.Issue) *result.Issue) []*result.Issue { - retIssues := make([]*result.Issue, 0, len(issues)) - for _, issue := range issues { - newIssue := transform(issue) - if newIssue != nil { - retIssues = append(retIssues, newIssue) - } - } - - return retIssues -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/max_from_linter.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/max_from_linter.go deleted file mode 100644 index bc7572f2cc..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/max_from_linter.go +++ /dev/null @@ -1,51 +0,0 @@ -package processors - -import ( - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/logutils" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -var _ Processor = (*MaxFromLinter)(nil) - -// MaxFromLinter limits the number of reports from the same linter. -type MaxFromLinter struct { - linterCounter map[string]int - limit int - log logutils.Log - cfg *config.Config -} - -func NewMaxFromLinter(limit int, log logutils.Log, cfg *config.Config) *MaxFromLinter { - return &MaxFromLinter{ - linterCounter: map[string]int{}, - limit: limit, - log: log, - cfg: cfg, - } -} - -func (*MaxFromLinter) Name() string { - return "max_from_linter" -} - -func (p *MaxFromLinter) Process(issues []*result.Issue) ([]*result.Issue, error) { - if p.limit <= 0 { // no limit - return issues, nil - } - - return filterIssuesUnsafe(issues, func(issue *result.Issue) bool { - p.linterCounter[issue.FromLinter]++ // always inc for stat - - return p.linterCounter[issue.FromLinter] <= p.limit - }), nil -} - -func (p *MaxFromLinter) Finish() { - walkStringToIntMapSortedByValue(p.linterCounter, func(linter string, count int) { - if count > p.limit { - p.log.Infof("%d/%d issues from linter %s were hidden, use --max-issues-per-linter", - count-p.limit, count, linter) - } - }) -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/max_per_file_from_linter.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/max_per_file_from_linter.go deleted file mode 100644 index b04b92ea7a..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/max_per_file_from_linter.go +++ /dev/null @@ -1,81 +0,0 @@ -package processors - -import ( - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/goformatters/gci" - "github.com/golangci/golangci-lint/v2/pkg/goformatters/gofmt" - "github.com/golangci/golangci-lint/v2/pkg/goformatters/gofumpt" - "github.com/golangci/golangci-lint/v2/pkg/goformatters/goimports" - "github.com/golangci/golangci-lint/v2/pkg/goformatters/golines" - "github.com/golangci/golangci-lint/v2/pkg/goformatters/swaggo" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -var _ Processor = (*MaxPerFileFromLinter)(nil) - -// MaxPerFileFromLinter limits the number of reports by file and by linter. -type MaxPerFileFromLinter struct { - fileLinterCounter fileLinterCounter - maxPerFileFromLinterConfig map[string]int -} - -func NewMaxPerFileFromLinter(cfg *config.Config) *MaxPerFileFromLinter { - maxPerFileFromLinterConfig := map[string]int{} - - if !cfg.Issues.NeedFix { - // if we don't fix we do this limiting to not annoy user; - // otherwise we need to fix all issues in the file at once - for _, f := range []string{gofmt.Name, gofumpt.Name, goimports.Name, gci.Name, golines.Name, swaggo.Name} { - maxPerFileFromLinterConfig[f] = 1 - } - } - - return &MaxPerFileFromLinter{ - fileLinterCounter: fileLinterCounter{}, - maxPerFileFromLinterConfig: maxPerFileFromLinterConfig, - } -} - -func (*MaxPerFileFromLinter) Name() string { - return "max_per_file_from_linter" -} - -func (p *MaxPerFileFromLinter) Process(issues []*result.Issue) ([]*result.Issue, error) { - return filterIssuesUnsafe(issues, func(issue *result.Issue) bool { - limit := p.maxPerFileFromLinterConfig[issue.FromLinter] - if limit == 0 { - return true - } - - if p.fileLinterCounter.GetCount(issue) >= limit { - return false - } - - p.fileLinterCounter.Increment(issue) - - return true - }), nil -} - -func (*MaxPerFileFromLinter) Finish() {} - -type fileLinterCounter map[string]map[string]int - -func (f fileLinterCounter) GetCount(issue *result.Issue) int { - return f.getCounter(issue)[issue.FromLinter] -} - -func (f fileLinterCounter) Increment(issue *result.Issue) { - f.getCounter(issue)[issue.FromLinter]++ -} - -func (f fileLinterCounter) getCounter(issue *result.Issue) map[string]int { - lc := f[issue.FilePath()] - - if lc == nil { - lc = map[string]int{} - f[issue.FilePath()] = lc - } - - return lc -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/max_same_issues.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/max_same_issues.go deleted file mode 100644 index ba22cf31fb..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/max_same_issues.go +++ /dev/null @@ -1,76 +0,0 @@ -package processors - -import ( - "sort" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/logutils" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -var _ Processor = (*MaxSameIssues)(nil) - -// MaxSameIssues limits the number of reports with the same text. -type MaxSameIssues struct { - textCounter map[string]int - limit int - log logutils.Log - cfg *config.Config -} - -func NewMaxSameIssues(limit int, log logutils.Log, cfg *config.Config) *MaxSameIssues { - return &MaxSameIssues{ - textCounter: map[string]int{}, - limit: limit, - log: log, - cfg: cfg, - } -} - -func (*MaxSameIssues) Name() string { - return "max_same_issues" -} - -func (p *MaxSameIssues) Process(issues []*result.Issue) ([]*result.Issue, error) { - if p.limit <= 0 { // no limit - return issues, nil - } - - return filterIssuesUnsafe(issues, func(issue *result.Issue) bool { - p.textCounter[issue.Text]++ // always inc for stat - - return p.textCounter[issue.Text] <= p.limit - }), nil -} - -func (p *MaxSameIssues) Finish() { - walkStringToIntMapSortedByValue(p.textCounter, func(text string, count int) { - if count > p.limit { - p.log.Infof("%d/%d issues with text %q were hidden, use --max-same-issues", - count-p.limit, count, text) - } - }) -} - -type kv struct { - Key string - Value int -} - -func walkStringToIntMapSortedByValue(m map[string]int, walk func(k string, v int)) { - var ss []kv - for k, v := range m { - ss = append(ss, kv{ - Key: k, - Value: v, - }) - } - - sort.Slice(ss, func(i, j int) bool { - return ss[i].Value > ss[j].Value - }) - - for _, kv := range ss { - walk(kv.Key, kv.Value) - } -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/nolint_filter.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/nolint_filter.go deleted file mode 100644 index b1ba3be1e2..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/nolint_filter.go +++ /dev/null @@ -1,315 +0,0 @@ -package processors - -import ( - "go/ast" - "go/parser" - "go/token" - "maps" - "regexp" - "slices" - "sort" - "strings" - - "github.com/golangci/golangci-lint/v2/pkg/golinters/nolintlint" - "github.com/golangci/golangci-lint/v2/pkg/lint/linter" - "github.com/golangci/golangci-lint/v2/pkg/lint/lintersdb" - "github.com/golangci/golangci-lint/v2/pkg/logutils" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -var _ Processor = (*NolintFilter)(nil) - -var nolintDebugf = logutils.Debug(logutils.DebugKeyNolintFilter) - -type ignoredRange struct { - linters []string - matchedIssueFromLinter map[string]bool - result.Range - col int - originalRange *ignoredRange // pre-expanded range (used to match nolintlint issues) -} - -func (i *ignoredRange) doesMatch(issue *result.Issue) bool { - if issue.Line() < i.From || issue.Line() > i.To { - return false - } - - // only allow selective nolinting of nolintlint - nolintFoundForLinter := len(i.linters) == 0 && issue.FromLinter != nolintlint.LinterName - - for _, linterName := range i.linters { - if linterName == issue.FromLinter { - nolintFoundForLinter = true - break - } - } - - if nolintFoundForLinter { - return true - } - - // handle possible unused nolint directives - // nolintlint generates potential issues for every nolint directive, and they are filtered out here - if issue.FromLinter == nolintlint.LinterName && issue.ExpectNoLint { - if issue.ExpectedNoLintLinter != "" { - return i.matchedIssueFromLinter[issue.ExpectedNoLintLinter] - } - return len(i.matchedIssueFromLinter) > 0 - } - - return false -} - -type fileData struct { - ignoredRanges []ignoredRange -} - -// NolintFilter filters and sorts reports related to `nolint` directives. -type NolintFilter struct { - fileCache map[string]*fileData - dbManager *lintersdb.Manager - enabledLinters map[string]*linter.Config - log logutils.Log - - unknownLintersSet map[string]bool - - pattern *regexp.Regexp -} - -func NewNolintFilter(log logutils.Log, dbManager *lintersdb.Manager, enabledLinters map[string]*linter.Config) *NolintFilter { - return &NolintFilter{ - fileCache: map[string]*fileData{}, - dbManager: dbManager, - enabledLinters: enabledLinters, - log: log, - unknownLintersSet: map[string]bool{}, - pattern: regexp.MustCompile(`^nolint( |:|$)`), - } -} - -func (*NolintFilter) Name() string { - return "nolint_filter" -} - -func (p *NolintFilter) Process(issues []*result.Issue) ([]*result.Issue, error) { - // put nolintlint issues last because we process other issues first to determine which nolint directives are unused - sort.Stable(sortWithNolintlintLast(issues)) - return filterIssuesErr(issues, p.shouldPassIssue) -} - -func (p *NolintFilter) Finish() { - if len(p.unknownLintersSet) == 0 { - return - } - - unknownLinters := slices.Sorted(maps.Keys(p.unknownLintersSet)) - - p.log.Warnf("Found unknown linters in //nolint directives: %s", strings.Join(unknownLinters, ", ")) -} - -func (p *NolintFilter) shouldPassIssue(issue *result.Issue) (bool, error) { - nolintDebugf("got issue: %v", *issue) - - // don't expect disabled linters to cover their nolint statements - if issue.FromLinter == nolintlint.LinterName && issue.ExpectNoLint && issue.ExpectedNoLintLinter != "" { - nolintDebugf("enabled linters: %v", p.enabledLinters) - - if p.enabledLinters[issue.ExpectedNoLintLinter] == nil { - return false, nil - } - - nolintDebugf("checking that lint issue was used for %s: %v", issue.ExpectedNoLintLinter, issue) - } - - fd := p.getOrCreateFileData(issue) - - for _, ir := range fd.ignoredRanges { - if !ir.doesMatch(issue) { - continue - } - - nolintDebugf("found ignored range for issue %v: %v", issue, ir) - - ir.matchedIssueFromLinter[issue.FromLinter] = true - - if ir.originalRange != nil { - ir.originalRange.matchedIssueFromLinter[issue.FromLinter] = true - } - - return false, nil - } - - return true, nil -} - -func (p *NolintFilter) getOrCreateFileData(issue *result.Issue) *fileData { - fd := p.fileCache[issue.FilePath()] - if fd != nil { - return fd - } - - fd = &fileData{} - p.fileCache[issue.FilePath()] = fd - - // TODO: migrate this parsing to go/analysis facts - // or cache them somehow per file. - - // Don't use cached AST because they consume a lot of memory on large projects. - fset := token.NewFileSet() - f, err := parser.ParseFile(fset, issue.FilePath(), nil, parser.ParseComments) - if err != nil { - // Don't report error because it's already must be reporter by typecheck or go/analysis. - return fd - } - - fd.ignoredRanges = p.buildIgnoredRangesForFile(f, fset, issue.FilePath()) - - nolintDebugf("file %s: built nolint ranges are %+v", issue.FilePath(), fd.ignoredRanges) - - return fd -} - -func (p *NolintFilter) buildIgnoredRangesForFile(f *ast.File, fset *token.FileSet, filePath string) []ignoredRange { - inlineRanges := p.extractFileCommentsInlineRanges(fset, f.Comments...) - nolintDebugf("file %s: inline nolint ranges are %+v", filePath, inlineRanges) - - if len(inlineRanges) == 0 { - return nil - } - - e := rangeExpander{ - fset: fset, - inlineRanges: inlineRanges, - } - - ast.Walk(&e, f) - - // TODO: merge all ranges: there are repeated ranges - allRanges := slices.Concat(inlineRanges, e.expandedRanges) - - return allRanges -} - -func (p *NolintFilter) extractFileCommentsInlineRanges(fset *token.FileSet, comments ...*ast.CommentGroup) []ignoredRange { - var ret []ignoredRange - for _, g := range comments { - for _, c := range g.List { - ir := p.extractInlineRangeFromComment(c.Text, g, fset) - if ir != nil { - ret = append(ret, *ir) - } - } - } - - return ret -} - -func (p *NolintFilter) extractInlineRangeFromComment(text string, g ast.Node, fset *token.FileSet) *ignoredRange { - text = strings.TrimLeft(text, "/ ") - if !p.pattern.MatchString(text) { - return nil - } - - buildRange := func(linters []string) *ignoredRange { - pos := fset.Position(g.Pos()) - return &ignoredRange{ - Range: result.Range{ - From: pos.Line, - To: fset.Position(g.End()).Line, - }, - col: pos.Column, - linters: linters, - matchedIssueFromLinter: make(map[string]bool), - } - } - - if strings.HasPrefix(text, "nolint:all") || !strings.HasPrefix(text, "nolint:") { - return buildRange(nil) // ignore all linters - } - - text, _, _ = strings.Cut(text, "//") // allow another comment after this comment - - // ignore specific linters - var linters []string - - for item := range strings.SplitSeq(strings.TrimPrefix(text, "nolint:"), ",") { - linterName := strings.ToLower(strings.TrimSpace(item)) - if linterName == "all" { - p.unknownLintersSet = map[string]bool{} - return buildRange(nil) - } - - lcs := p.dbManager.GetLinterConfigs(linterName) - if lcs == nil { - p.unknownLintersSet[linterName] = true - linters = append(linters, linterName) - nolintDebugf("unknown linter %s on line %d", linterName, fset.Position(g.Pos()).Line) - continue - } - - for _, lc := range lcs { - linters = append(linters, lc.Name()) // normalize name to work with aliases - } - } - - nolintDebugf("%d: linters are %s", fset.Position(g.Pos()).Line, linters) - return buildRange(linters) -} - -type rangeExpander struct { - fset *token.FileSet - inlineRanges []ignoredRange - expandedRanges []ignoredRange -} - -func (e *rangeExpander) Visit(node ast.Node) ast.Visitor { - if node == nil { - return e - } - - nodeStartPos := e.fset.Position(node.Pos()) - nodeStartLine := nodeStartPos.Line - nodeEndLine := e.fset.Position(node.End()).Line - - var foundRange *ignoredRange - for _, r := range e.inlineRanges { - if r.To == nodeStartLine-1 && nodeStartPos.Column == r.col { - r := r - foundRange = &r - break - } - } - if foundRange == nil { - return e - } - - expandedRange := *foundRange - // store the original unexpanded range for matching nolintlint issues - if expandedRange.originalRange == nil { - expandedRange.originalRange = foundRange - } - if expandedRange.To < nodeEndLine { - expandedRange.To = nodeEndLine - } - - nolintDebugf("found range is %v for node %#v [%d;%d], expanded range is %v", - *foundRange, node, nodeStartLine, nodeEndLine, expandedRange) - e.expandedRanges = append(e.expandedRanges, expandedRange) - - return e -} - -// put nolintlint last -type sortWithNolintlintLast []*result.Issue - -func (issues sortWithNolintlintLast) Len() int { - return len(issues) -} - -func (issues sortWithNolintlintLast) Less(i, j int) bool { - return issues[i].FromLinter != nolintlint.LinterName && issues[j].FromLinter == nolintlint.LinterName -} - -func (issues sortWithNolintlintLast) Swap(i, j int) { - issues[j], issues[i] = issues[i], issues[j] -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/path_absoluter.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/path_absoluter.go deleted file mode 100644 index 240cedf8ea..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/path_absoluter.go +++ /dev/null @@ -1,44 +0,0 @@ -package processors - -import ( - "path/filepath" - - "github.com/golangci/golangci-lint/v2/pkg/logutils" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -var _ Processor = (*PathAbsoluter)(nil) - -// PathAbsoluter ensures that representation of path are absolute. -type PathAbsoluter struct { - log logutils.Log -} - -func NewPathAbsoluter(log logutils.Log) *PathAbsoluter { - return &PathAbsoluter{log: log.Child(logutils.DebugKeyPathAbsoluter)} -} - -func (*PathAbsoluter) Name() string { - return "path_absoluter" -} - -func (p *PathAbsoluter) Process(issues []*result.Issue) ([]*result.Issue, error) { - return transformIssues(issues, func(issue *result.Issue) *result.Issue { - if filepath.IsAbs(issue.FilePath()) { - return issue - } - - absPath, err := filepath.Abs(issue.FilePath()) - if err != nil { - p.log.Warnf("failed to get absolute path for %q: %v", issue.FilePath(), err) - return nil - } - - newIssue := issue - newIssue.Pos.Filename = absPath - - return newIssue - }), nil -} - -func (*PathAbsoluter) Finish() {} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/path_prettifier.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/path_prettifier.go deleted file mode 100644 index 94dfbab370..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/path_prettifier.go +++ /dev/null @@ -1,51 +0,0 @@ -package processors - -import ( - "path/filepath" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/fsutils" - "github.com/golangci/golangci-lint/v2/pkg/logutils" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -var _ Processor = (*PathPrettifier)(nil) - -// PathPrettifier modifies report file path to be relative to the base path. -// Also handles the `output.path-prefix` option. -type PathPrettifier struct { - cfg *config.Output - - log logutils.Log -} - -func NewPathPrettifier(log logutils.Log, cfg *config.Output) *PathPrettifier { - return &PathPrettifier{ - cfg: cfg, - log: log.Child(logutils.DebugKeyPathPrettifier), - } -} - -func (*PathPrettifier) Name() string { - return "path_prettifier" -} - -func (p *PathPrettifier) Process(issues []*result.Issue) ([]*result.Issue, error) { - if p.cfg.PathMode == fsutils.OutputPathModeAbsolute { - return issues, nil - } - - return transformIssues(issues, func(issue *result.Issue) *result.Issue { - newIssue := issue - - if p.cfg.PathPrefix == "" { - newIssue.Pos.Filename = issue.RelativePath - } else { - newIssue.Pos.Filename = filepath.Join(p.cfg.PathPrefix, issue.RelativePath) - } - - return newIssue - }), nil -} - -func (*PathPrettifier) Finish() {} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/path_relativity.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/path_relativity.go deleted file mode 100644 index c68662c7bb..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/path_relativity.go +++ /dev/null @@ -1,60 +0,0 @@ -package processors - -import ( - "fmt" - "path/filepath" - - "github.com/golangci/golangci-lint/v2/pkg/fsutils" - "github.com/golangci/golangci-lint/v2/pkg/logutils" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -var _ Processor = (*PathRelativity)(nil) - -// PathRelativity computes [result.Issue.RelativePath] and [result.Issue.WorkingDirectoryRelativePath], -// based on the base path. -type PathRelativity struct { - log logutils.Log - basePath string - workingDirectory string -} - -func NewPathRelativity(log logutils.Log, basePath string) (*PathRelativity, error) { - wd, err := fsutils.Getwd() - if err != nil { - return nil, fmt.Errorf("error getting working directory: %w", err) - } - - return &PathRelativity{ - log: log.Child(logutils.DebugKeyPathRelativity), - basePath: basePath, - workingDirectory: wd, - }, nil -} - -func (*PathRelativity) Name() string { - return "path_relativity" -} - -func (p *PathRelativity) Process(issues []*result.Issue) ([]*result.Issue, error) { - return transformIssues(issues, func(issue *result.Issue) *result.Issue { - newIssue := *issue - - var err error - newIssue.RelativePath, err = filepath.Rel(p.basePath, issue.FilePath()) - if err != nil { - p.log.Warnf("Getting relative path (basepath): %v", err) - return nil - } - - newIssue.WorkingDirectoryRelativePath, err = filepath.Rel(p.workingDirectory, issue.FilePath()) - if err != nil { - p.log.Warnf("Getting relative path (wd): %v", err) - return nil - } - - return &newIssue - }), nil -} - -func (*PathRelativity) Finish() {} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/path_shortener.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/path_shortener.go deleted file mode 100644 index 23df4f02cc..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/path_shortener.go +++ /dev/null @@ -1,41 +0,0 @@ -package processors - -import ( - "fmt" - "strings" - - "github.com/golangci/golangci-lint/v2/pkg/fsutils" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -var _ Processor = (*PathShortener)(nil) - -// PathShortener modifies text of the reports to reduce file path inside the text. -// It uses the rooted path name corresponding to the current directory (`wd`). -type PathShortener struct { - wd string -} - -func NewPathShortener() *PathShortener { - wd, err := fsutils.Getwd() - if err != nil { - panic(fmt.Sprintf("Can't get working dir: %s", err)) - } - - return &PathShortener{wd: wd} -} - -func (PathShortener) Name() string { - return "path_shortener" -} - -func (p PathShortener) Process(issues []*result.Issue) ([]*result.Issue, error) { - return transformIssues(issues, func(issue *result.Issue) *result.Issue { - newIssue := issue - newIssue.Text = strings.ReplaceAll(newIssue.Text, p.wd+"/", "") - newIssue.Text = strings.ReplaceAll(newIssue.Text, p.wd, "") - return newIssue - }), nil -} - -func (PathShortener) Finish() {} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/processor.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/processor.go deleted file mode 100644 index f5603c94dc..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/processor.go +++ /dev/null @@ -1,13 +0,0 @@ -package processors - -import ( - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -const typeCheckName = "typecheck" - -type Processor interface { - Process(issues []*result.Issue) ([]*result.Issue, error) - Name() string - Finish() -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/severity.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/severity.go deleted file mode 100644 index 33c3997f88..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/severity.go +++ /dev/null @@ -1,86 +0,0 @@ -package processors - -import ( - "cmp" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/fsutils" - "github.com/golangci/golangci-lint/v2/pkg/logutils" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -const severityFromLinter = "@linter" - -var _ Processor = (*Severity)(nil) - -// Severity modifies report severity. -// It uses the same `baseRule` structure as [ExcludeRules] processor. -// -// Warning: it doesn't use `path-prefix` option. -type Severity struct { - name string - - log logutils.Log - - lines *fsutils.LineCache - - defaultSeverity string - rules []severityRule -} - -func NewSeverity(log logutils.Log, lines *fsutils.LineCache, cfg *config.Severity) *Severity { - p := &Severity{ - name: "severity-rules", - lines: lines, - log: log, - defaultSeverity: cfg.Default, - } - - p.rules = parseRules(cfg.Rules, "", newSeverityRule) - - return p -} - -func (p *Severity) Name() string { return p.name } - -func (p *Severity) Process(issues []*result.Issue) ([]*result.Issue, error) { - if len(p.rules) == 0 && p.defaultSeverity == "" { - return issues, nil - } - - return transformIssues(issues, p.transform), nil -} - -func (*Severity) Finish() {} - -func (p *Severity) transform(issue *result.Issue) *result.Issue { - for _, rule := range p.rules { - if rule.match(issue, p.lines, p.log) { - if rule.severity == severityFromLinter || (rule.severity == "" && p.defaultSeverity == severityFromLinter) { - return issue - } - - issue.Severity = cmp.Or(rule.severity, p.defaultSeverity) - - return issue - } - } - - if p.defaultSeverity != severityFromLinter { - issue.Severity = p.defaultSeverity - } - - return issue -} - -type severityRule struct { - baseRule - severity string -} - -func newSeverityRule(rule *config.SeverityRule, prefix string) severityRule { - return severityRule{ - baseRule: newBaseRule(&rule.BaseRule, prefix), - severity: rule.Severity, - } -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/sort_results.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/sort_results.go deleted file mode 100644 index 8ba06bccfd..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/sort_results.go +++ /dev/null @@ -1,143 +0,0 @@ -package processors - -import ( - "cmp" - "fmt" - "slices" - "strings" - - "github.com/golangci/golangci-lint/v2/pkg/config" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -const ( - orderNameFile = "file" - orderNameLinter = "linter" - orderNameSeverity = "severity" -) - -const ( - less = iota - 1 - equal - greater -) - -var _ Processor = (*SortResults)(nil) - -type issueComparator func(a, b *result.Issue) int - -// SortResults sorts reports based on criteria: -// - file names, line numbers, positions -// - linter names -// - severity names -type SortResults struct { - cmps map[string][]issueComparator - - cfg *config.Output -} - -func NewSortResults(cfg *config.Output) *SortResults { - return &SortResults{ - cmps: map[string][]issueComparator{ - // For sorting we are comparing (in next order): - // file names, line numbers, position, and finally - giving up. - orderNameFile: {byFileName, byLine, byColumn}, - // For sorting we are comparing: linter name - orderNameLinter: {byLinter}, - // For sorting we are comparing: severity - orderNameSeverity: {bySeverity}, - }, - cfg: cfg, - } -} - -func (SortResults) Name() string { return "sort_results" } - -// Process is performing sorting of the result issues. -func (p SortResults) Process(issues []*result.Issue) ([]*result.Issue, error) { - if len(p.cfg.SortOrder) == 0 { - p.cfg.SortOrder = []string{orderNameLinter, orderNameFile} - } - - var cmps []issueComparator - - for _, name := range p.cfg.SortOrder { - c, ok := p.cmps[name] - if !ok { - return nil, fmt.Errorf("unsupported sort-order name %q", name) - } - - cmps = append(cmps, c...) - } - - comp := mergeComparators(cmps...) - - slices.SortFunc(issues, func(a, b *result.Issue) int { - return comp(a, b) - }) - - return issues, nil -} - -func (SortResults) Finish() {} - -func byFileName(a, b *result.Issue) int { - return strings.Compare(a.FilePath(), b.FilePath()) -} - -func byLine(a, b *result.Issue) int { - return numericCompare(a.Line(), b.Line()) -} - -func byColumn(a, b *result.Issue) int { - return numericCompare(a.Column(), b.Column()) -} - -func byLinter(a, b *result.Issue) int { - return strings.Compare(a.FromLinter, b.FromLinter) -} - -func bySeverity(a, b *result.Issue) int { - return severityCompare(a.Severity, b.Severity) -} - -func severityCompare(a, b string) int { - // The position inside the slice define the importance (lower to higher). - classic := []string{"low", "medium", "high", "warning", "error"} - - if slices.Contains(classic, a) && slices.Contains(classic, b) { - return cmp.Compare(slices.Index(classic, a), slices.Index(classic, b)) - } - - if slices.Contains(classic, a) { - return greater - } - - if slices.Contains(classic, b) { - return less - } - - return strings.Compare(a, b) -} - -func numericCompare(a, b int) int { - // Negative values and zeros are skipped (equal) because they either invalid or "neutral" (default int value). - if a <= 0 || b <= 0 { - return equal - } - - return cmp.Compare(a, b) -} - -func mergeComparators(comps ...issueComparator) issueComparator { - return func(a, b *result.Issue) int { - for _, comp := range comps { - i := comp(a, b) - if i != equal { - return i - } - } - - return equal - } -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/source_code.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/source_code.go deleted file mode 100644 index d4e82643c0..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/source_code.go +++ /dev/null @@ -1,57 +0,0 @@ -package processors - -import ( - "github.com/golangci/golangci-lint/v2/pkg/fsutils" - "github.com/golangci/golangci-lint/v2/pkg/logutils" - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -var _ Processor = (*SourceCode)(nil) - -// SourceCode modifies displayed information based on [result.Issue.GetLineRange()]. -// -// This is used: -// - to display the "UnderLinePointer". -// - in some rare cases to display multiple lines instead of one (ex: `dupl`) -// -// It requires to use [fsutils.LineCache] ([fsutils.FileCache]) to get the file information before the fixes. -type SourceCode struct { - lineCache *fsutils.LineCache - log logutils.Log -} - -func NewSourceCode(lc *fsutils.LineCache, log logutils.Log) *SourceCode { - return &SourceCode{ - lineCache: lc, - log: log, - } -} - -func (SourceCode) Name() string { - return "source_code" -} - -func (p SourceCode) Process(issues []*result.Issue) ([]*result.Issue, error) { - return transformIssues(issues, p.transform), nil -} - -func (SourceCode) Finish() {} - -func (p SourceCode) transform(issue *result.Issue) *result.Issue { - newIssue := *issue - - lineRange := issue.GetLineRange() - for lineNumber := lineRange.From; lineNumber <= lineRange.To; lineNumber++ { - line, err := p.lineCache.GetLine(issue.FilePath(), lineNumber) - if err != nil { - p.log.Warnf("Failed to get line %d for file %s: %s", - lineNumber, issue.FilePath(), err) - - return issue - } - - newIssue.SourceLines = append(newIssue.SourceLines, line) - } - - return &newIssue -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/uniq_by_line.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/uniq_by_line.go deleted file mode 100644 index 953496355b..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/result/processors/uniq_by_line.go +++ /dev/null @@ -1,67 +0,0 @@ -package processors - -import ( - "github.com/golangci/golangci-lint/v2/pkg/result" -) - -const uniqByLineLimit = 1 - -var _ Processor = (*UniqByLine)(nil) - -// UniqByLine filters reports to keep only one report by line of code. -type UniqByLine struct { - fileLineCounter fileLineCounter - enabled bool -} - -func NewUniqByLine(enable bool) *UniqByLine { - return &UniqByLine{ - fileLineCounter: fileLineCounter{}, - enabled: enable, - } -} - -func (*UniqByLine) Name() string { - return "uniq_by_line" -} - -func (p *UniqByLine) Process(issues []*result.Issue) ([]*result.Issue, error) { - if !p.enabled { - return issues, nil - } - - return filterIssuesUnsafe(issues, p.shouldPassIssue), nil -} - -func (*UniqByLine) Finish() {} - -func (p *UniqByLine) shouldPassIssue(issue *result.Issue) bool { - if p.fileLineCounter.GetCount(issue) == uniqByLineLimit { - return false - } - - p.fileLineCounter.Increment(issue) - - return true -} - -type fileLineCounter map[string]map[int]int - -func (f fileLineCounter) GetCount(issue *result.Issue) int { - return f.getCounter(issue)[issue.Line()] -} - -func (f fileLineCounter) Increment(issue *result.Issue) { - f.getCounter(issue)[issue.Line()]++ -} - -func (f fileLineCounter) getCounter(issue *result.Issue) map[int]int { - lc := f[issue.FilePath()] - - if lc == nil { - lc = map[int]int{} - f[issue.FilePath()] = lc - } - - return lc -} diff --git a/vendor/github.com/golangci/golangci-lint/v2/pkg/timeutils/stopwatch.go b/vendor/github.com/golangci/golangci-lint/v2/pkg/timeutils/stopwatch.go deleted file mode 100644 index 332c24c88a..0000000000 --- a/vendor/github.com/golangci/golangci-lint/v2/pkg/timeutils/stopwatch.go +++ /dev/null @@ -1,138 +0,0 @@ -package timeutils - -import ( - "fmt" - "sort" - "strings" - "sync" - "time" - - "github.com/golangci/golangci-lint/v2/pkg/logutils" -) - -const noStagesText = "no stages" - -type Stopwatch struct { - name string - startedAt time.Time - log logutils.Log - - stages map[string]time.Duration - mu sync.Mutex -} - -func NewStopwatch(name string, log logutils.Log) *Stopwatch { - return &Stopwatch{ - name: name, - startedAt: time.Now(), - stages: map[string]time.Duration{}, - log: log, - } -} - -type stageDuration struct { - name string - d time.Duration -} - -func (s *Stopwatch) stageDurationsSorted() []stageDuration { - stageDurations := make([]stageDuration, 0, len(s.stages)) - for n, d := range s.stages { - stageDurations = append(stageDurations, stageDuration{ - name: n, - d: d, - }) - } - sort.Slice(stageDurations, func(i, j int) bool { - return stageDurations[i].d > stageDurations[j].d - }) - return stageDurations -} - -func (s *Stopwatch) sprintStages() string { - if len(s.stages) == 0 { - return noStagesText - } - - stageDurations := s.stageDurationsSorted() - - stagesStrings := make([]string, 0, len(stageDurations)) - for _, s := range stageDurations { - stagesStrings = append(stagesStrings, fmt.Sprintf("%s: %s", s.name, s.d)) - } - - return fmt.Sprintf("stages: %s", strings.Join(stagesStrings, ", ")) -} - -func (s *Stopwatch) sprintTopStages(n int) string { - if len(s.stages) == 0 { - return noStagesText - } - - stageDurations := s.stageDurationsSorted() - - var stagesStrings []string - for i := 0; i < len(stageDurations) && i < n; i++ { - s := stageDurations[i] - stagesStrings = append(stagesStrings, fmt.Sprintf("%s: %s", s.name, s.d)) - } - - return fmt.Sprintf("top %d stages: %s", n, strings.Join(stagesStrings, ", ")) -} - -func (s *Stopwatch) Print() { - p := fmt.Sprintf("%s took %s", s.name, time.Since(s.startedAt)) - if len(s.stages) == 0 { - s.log.Infof("%s", p) - return - } - - s.log.Infof("%s with %s", p, s.sprintStages()) -} - -func (s *Stopwatch) PrintStages() { - var stagesDuration time.Duration - for _, s := range s.stages { - stagesDuration += s - } - s.log.Infof("%s took %s with %s", s.name, stagesDuration, s.sprintStages()) -} - -func (s *Stopwatch) PrintTopStages(n int) { - var stagesDuration time.Duration - for _, s := range s.stages { - stagesDuration += s - } - s.log.Infof("%s took %s with %s", s.name, stagesDuration, s.sprintTopStages(n)) -} - -func (s *Stopwatch) TrackStage(name string, f func()) { - startedAt := time.Now() - f() - - s.mu.Lock() - s.stages[name] += time.Since(startedAt) - s.mu.Unlock() -} - -func (s *Stopwatch) TrackStageErr(name string, f func() error) error { - startedAt := time.Now() - err := f() - - s.mu.Lock() - s.stages[name] += time.Since(startedAt) - s.mu.Unlock() - - return err -} - -func TrackStage[T any](s *Stopwatch, name string, f func() (T, error)) (T, error) { - var result T - var err error - - s.TrackStage(name, func() { - result, err = f() - }) - - return result, err -} diff --git a/vendor/github.com/golangci/golines/.gitattributes b/vendor/github.com/golangci/golines/.gitattributes deleted file mode 100644 index 148ff868c3..0000000000 --- a/vendor/github.com/golangci/golines/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -_fixtures/* text eol=lf diff --git a/vendor/github.com/golangci/golines/.gitignore b/vendor/github.com/golangci/golines/.gitignore deleted file mode 100644 index 48e5593d20..0000000000 --- a/vendor/github.com/golangci/golines/.gitignore +++ /dev/null @@ -1,20 +0,0 @@ -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib -/dist - -# Test binary, build with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -vendor -.vscode -.idea -golines - -coverage.out diff --git a/vendor/github.com/golangci/golines/LICENSE b/vendor/github.com/golangci/golines/LICENSE deleted file mode 100644 index 1fbffdf72a..0000000000 --- a/vendor/github.com/golangci/golines/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2019 Segment.io, Inc. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/golangci/golines/README.md b/vendor/github.com/golangci/golines/README.md deleted file mode 100644 index 24ec221a08..0000000000 --- a/vendor/github.com/golangci/golines/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# Fork of golines - -This is a fork of [golines](https://github.com/segmentio/golines) to be usable as a library. - -## Modifications - -- The original code is under the `main` package -> uses `golines` package. -- Some files have been removed to reduce dependencies: - - `main.go`, `main_test.go` - - `graph.go`, `graph_generated.go`, `graph.test` - - `diff.go`, `diff_test.go` - - `doc.go` -- Some other files have been removed because unused by the fork: - - `.goreleaser.yaml`, `.pre-commit-hooks.yaml` - - `.github/build.yml`, `.github/release.yml` - - `Makefile` -- The workflow files (`lint.yml` and `test.yml`) are modified to run for this fork. -- The file `shortener.go` has been modified: - - The `baseFormatterCmd` is hardcoded. - - The code related to debug logs has been removed. - - The code related to graph has been removed. -- The module name has been changed to `github.com/golangci/golines` to avoid replacement directives inside golangci-lint. - -**No modifications will be accepted other than the synchronization of the fork.** - -The synchronization of the fork will be done by the golangci-lint maintainers only. - -## History - -- sync with fc305205784a70b4cfc17397654f4c94e3153ce4 (after v0.12.2) diff --git a/vendor/github.com/golangci/golines/annotation.go b/vendor/github.com/golangci/golines/annotation.go deleted file mode 100644 index fc7f92ca22..0000000000 --- a/vendor/github.com/golangci/golines/annotation.go +++ /dev/null @@ -1,99 +0,0 @@ -package golines - -import ( - "fmt" - "strconv" - "strings" - - "github.com/dave/dst" -) - -const annotationPrefix = "// __golines:shorten:" - -// CreateAnnotation generates the text of a comment that will annotate long lines. -func CreateAnnotation(length int) string { - return fmt.Sprintf( - "%s%d", - annotationPrefix, - length, - ) -} - -// IsAnnotation determines whether the given line is an annotation created with CreateAnnotation. -func IsAnnotation(line string) bool { - return strings.HasPrefix( - strings.Trim(line, " \t"), - annotationPrefix, - ) -} - -// HasAnnotation determines whether the given AST node has a line length annotation on it. -func HasAnnotation(node dst.Node) bool { - startDecorations := node.Decorations().Start.All() - return len(startDecorations) > 0 && - IsAnnotation(startDecorations[len(startDecorations)-1]) -} - -// HasTailAnnotation determines whether the given AST node has a line length annotation at its -// end. This is needed to catch long function declarations with inline interface definitions. -func HasTailAnnotation(node dst.Node) bool { - endDecorations := node.Decorations().End.All() - return len(endDecorations) > 0 && - IsAnnotation(endDecorations[len(endDecorations)-1]) -} - -// HasAnnotationRecursive determines whether the given node or one of its children has a -// golines annotation on it. It's currently implemented for function declarations, fields, -// call expressions, and selector expressions only. -func HasAnnotationRecursive(node dst.Node) bool { - if HasAnnotation(node) { - return true - } - - switch n := node.(type) { - case *dst.FuncDecl: - if n.Type != nil && n.Type.Params != nil { - for _, item := range n.Type.Params.List { - if HasAnnotationRecursive(item) { - return true - } - } - } - case *dst.Field: - return HasTailAnnotation(n) || HasAnnotationRecursive(n.Type) - case *dst.SelectorExpr: - return HasAnnotation(n.Sel) || HasAnnotation(n.X) - case *dst.CallExpr: - if HasAnnotationRecursive(n.Fun) { - return true - } - - for _, arg := range n.Args { - if HasAnnotation(arg) { - return true - } - } - case *dst.InterfaceType: - for _, field := range n.Methods.List { - if HasAnnotationRecursive(field) { - return true - } - } - } - - return false -} - -// ParseAnnotation returns the line length encoded in a golines annotation. If none is found, -// it returns -1. -func ParseAnnotation(line string) int { - if IsAnnotation(line) { - components := strings.SplitN(line, ":", 3) - val, err := strconv.Atoi(components[2]) - if err != nil { - return -1 - } - return val - } - return -1 -} diff --git a/vendor/github.com/golangci/golines/shortener.go b/vendor/github.com/golangci/golines/shortener.go deleted file mode 100644 index c35b5f35bf..0000000000 --- a/vendor/github.com/golangci/golines/shortener.go +++ /dev/null @@ -1,594 +0,0 @@ -package golines - -import ( - "bufio" - "bytes" - "fmt" - "go/format" - "go/token" - "os/exec" - "reflect" - "regexp" - "strings" - - "github.com/dave/dst" - "github.com/dave/dst/decorator" -) - -var ( - // Strings to look for to identify generated files - generatedTerms = []string{ - "do not edit", - "generated by", - "automatically regenerated", - } - // Go directives (should be ignored) - goDirectiveLine = regexp.MustCompile(`\s*//\s*go:.*`) -) - -// The maximum number of shortening "rounds" that we'll allow. The shortening -// process should converge quickly, but we have this here as a safety mechanism to -// prevent loops that prevent termination. -const maxRounds = 20 - -// ShortenerConfig stores the configuration options exposed by a Shortener instance. -type ShortenerConfig struct { - MaxLen int // Max target width for each line - TabLen int // Width of a tab character - KeepAnnotations bool // Whether to keep annotations in final result (for debugging only) - ShortenComments bool // Whether to shorten comments - ReformatTags bool // Whether to reformat struct tags in addition to shortening long lines - IgnoreGenerated bool // Whether to ignore generated files - DotFile string // Path to write dot-formatted output to (for debugging only) - ChainSplitDots bool // Whether to split chain methods by putting dots at ends of lines - - // Formatter that will be run before and after main shortening process. If empty, - // defaults to goimports (if found), otherwise gofmt. - BaseFormatterCmd string -} - -// Shortener shortens a single go file according to a small set of user style -// preferences. -type Shortener struct { - config ShortenerConfig - - // Some extra params around the base formatter generated from the BaseFormatterCmd - // argument in the config. - baseFormatter string - baseFormatterArgs []string -} - -// NewShortener creates a new shortener instance from the provided config. -func NewShortener(config ShortenerConfig) *Shortener { - var formatterComponents []string - - // golangci-lint: hardcoded base formatter. - // Note: - // - the command `gofmt` is not used, it calls `format.Source`. - // - the format is related to `go fmt` and not `gofmt`. - config.BaseFormatterCmd = "gofmt" - - if config.BaseFormatterCmd == "" { - _, err := exec.LookPath("goimports") - if err != nil { - formatterComponents = []string{"gofmt"} - } else { - formatterComponents = []string{"goimports"} - } - } else { - formatterComponents = strings.Split(config.BaseFormatterCmd, " ") - } - - s := &Shortener{ - config: config, - baseFormatter: formatterComponents[0], - } - - if len(formatterComponents) > 1 { - s.baseFormatterArgs = formatterComponents[1:] - } else { - s.baseFormatterArgs = []string{} - } - - return s -} - -// Shorten shortens the provided golang file content bytes. -func (s *Shortener) Shorten(contents []byte) ([]byte, error) { - if s.config.IgnoreGenerated && s.isGenerated(contents) { - return contents, nil - } - - round := 0 - var err error - - // Do initial, non-line-length-aware formatting - contents, err = s.formatSrc(contents) - if err != nil { - return nil, fmt.Errorf("Error formatting source: %+v", err) - } - - for { - // Annotate all long lines - lines := strings.Split(string(contents), "\n") - annotatedLines, linesToShorten := s.annotateLongLines(lines) - var stop bool - - if linesToShorten == 0 { - if round == 0 { - if !s.config.ReformatTags { - stop = true - } else if !HasMultiKeyTags(lines) { - stop = true - } - } else { - stop = true - } - } - - if stop { - break - } - - contents = []byte(strings.Join(annotatedLines, "\n")) - - // Generate AST - result, err := decorator.Parse(contents) - if err != nil { - return nil, err - } - - // Shorten the file starting at the top-level declarations - for _, decl := range result.Decls { - s.formatNode(decl) - } - - // Materialize output - output := bytes.NewBuffer([]byte{}) - err = decorator.Fprint(output, result) - if err != nil { - return nil, fmt.Errorf("Error parsing source: %+v", err) - } - contents = output.Bytes() - - round++ - - if round > maxRounds { - break - } - } - - if !s.config.KeepAnnotations { - contents = s.removeAnnotations(contents) - } - if s.config.ShortenComments { - contents = s.shortenCommentsFunc(contents) - } - - // Do final round of non-line-length-aware formatting after we've fixed up the comments - contents, err = s.formatSrc(contents) - if err != nil { - return nil, fmt.Errorf("Error formatting source: %+v", err) - } - - return contents, nil -} - -// formatSrc formats the provided source bytes using the configured "base" formatter (typically -// goimports or gofmt). -func (s *Shortener) formatSrc(contents []byte) ([]byte, error) { - if s.baseFormatter == "gofmt" { - return format.Source(contents) - } - - cmd := exec.Command(s.baseFormatter, s.baseFormatterArgs...) - stdinPipe, err := cmd.StdinPipe() - if err != nil { - return nil, err - } - - outBuffer := &bytes.Buffer{} - cmd.Stdout = outBuffer - - if err = cmd.Start(); err != nil { - return nil, err - } - - _, err = stdinPipe.Write(contents) - if err != nil { - return nil, err - } - stdinPipe.Close() - - err = cmd.Wait() - if err != nil { - return nil, err - } - - return outBuffer.Bytes(), nil -} - -// annotateLongLines adds specially-formatted comments to all eligible lines that are longer than -// the configured target length. If a line already has one of these comments from a previous -// shortening round, then the comment contents are updated. -func (s *Shortener) annotateLongLines(lines []string) ([]string, int) { - annotatedLines := []string{} - linesToShorten := 0 - prevLen := -1 - - for _, line := range lines { - length := s.lineLen(line) - - if prevLen > -1 { - if length <= s.config.MaxLen { - // Shortening successful, remove previous annotation - annotatedLines = annotatedLines[:len(annotatedLines)-1] - } else if length < prevLen { - // Replace annotation with new length - annotatedLines[len(annotatedLines)-1] = CreateAnnotation(length) - linesToShorten++ - } - } else if !s.isComment(line) && length > s.config.MaxLen { - annotatedLines = append( - annotatedLines, - CreateAnnotation(length), - ) - linesToShorten++ - } - - annotatedLines = append(annotatedLines, line) - prevLen = ParseAnnotation(line) - } - - return annotatedLines, linesToShorten -} - -// removeAnnotations removes all comments that were added by the annotateLongLines -// function above. -func (s *Shortener) removeAnnotations(contents []byte) []byte { - cleanedLines := []string{} - lines := strings.Split(string(contents), "\n") - - for _, line := range lines { - if !IsAnnotation(line) { - cleanedLines = append(cleanedLines, line) - } - } - - return []byte(strings.Join(cleanedLines, "\n")) -} - -// shortenCommentsFunc attempts to shorten long comments in the provided source. As noted -// in the repo README, this functionality has some quirks and is disabled by default. -func (s *Shortener) shortenCommentsFunc(contents []byte) []byte { - cleanedLines := []string{} - words := []string{} // all words in a contiguous sequence of long comments - prefix := "" - lines := strings.Split(string(contents), "\n") - for _, line := range lines { - if s.isComment(line) && !IsAnnotation(line) && - !s.isGoDirective(line) && - s.lineLen(line) > s.config.MaxLen { - start := strings.Index(line, "//") - prefix = line[0:(start + 2)] - trimmedLine := strings.Trim(line[(start+2):], " ") - currLineWords := strings.Split(trimmedLine, " ") - words = append(words, currLineWords...) - } else { - // Reflow the accumulated `words` before appending the unprocessed `line`. - currLineLen := 0 - currLineWords := []string{} - maxCommentLen := s.config.MaxLen - s.lineLen(prefix) - for _, word := range words { - if currLineLen > 0 && currLineLen+1+len(word) > maxCommentLen { - cleanedLines = append( - cleanedLines, - fmt.Sprintf( - "%s %s", - prefix, - strings.Join(currLineWords, " "), - ), - ) - currLineWords = []string{} - currLineLen = 0 - } - currLineWords = append(currLineWords, word) - currLineLen += 1 + len(word) - } - if currLineLen > 0 { - cleanedLines = append( - cleanedLines, - fmt.Sprintf( - "%s %s", - prefix, - strings.Join(currLineWords, " "), - ), - ) - } - words = []string{} - - cleanedLines = append(cleanedLines, line) - } - } - return []byte(strings.Join(cleanedLines, "\n")) -} - -// lineLen gets the width of the provided line after tab expansion. -func (s *Shortener) lineLen(line string) int { - length := 0 - - for _, char := range line { - if char == '\t' { - length += s.config.TabLen - } else { - length++ - } - } - - return length -} - -// isComment determines whether the provided line is a non-block comment. -func (s *Shortener) isComment(line string) bool { - return strings.HasPrefix(strings.Trim(line, " \t"), "//") -} - -// isGoDirective determines whether the provided line is a go directive, e.g. for go generate. -func (s *Shortener) isGoDirective(line string) bool { - return goDirectiveLine.MatchString(line) -} - -// formatNode formats the provided AST node. The appropriate helper function is called -// based on whether the node is a declaration, expression, statement, or spec. -func (s *Shortener) formatNode(node dst.Node) { - switch n := node.(type) { - case dst.Decl: - s.formatDecl(n) - case dst.Expr: - s.formatExpr(n, false, false) - case dst.Stmt: - s.formatStmt(n) - case dst.Spec: - s.formatSpec(n, false) - default: - // noop - } -} - -// formatDecl formats an AST declaration node. These include function declarations, -// imports, and constants. -func (s *Shortener) formatDecl(decl dst.Decl) { - switch d := decl.(type) { - case *dst.FuncDecl: - if HasAnnotationRecursive(decl) { - if d.Type != nil && d.Type.Params != nil { - s.formatFieldList(d.Type.Params) - } - } - s.formatStmt(d.Body) - case *dst.GenDecl: - for _, spec := range d.Specs { - s.formatSpec(spec, HasAnnotation(decl)) - } - default: - // noop - } -} - -// formatFieldList formats a field list in a function declaration. -func (s *Shortener) formatFieldList(fieldList *dst.FieldList) { - for f, field := range fieldList.List { - if f == 0 { - field.Decorations().Before = dst.NewLine - } else { - field.Decorations().Before = dst.None - } - - field.Decorations().After = dst.NewLine - } -} - -// formatStmt formats an AST statement node. Among other examples, these include assignments, -// case clauses, for statements, if statements, and select statements. -func (s *Shortener) formatStmt(stmt dst.Stmt) { - // Explicitly check for nil statements - stmtType := reflect.TypeOf(stmt) - if reflect.ValueOf(stmt) == reflect.Zero(stmtType) { - return - } - - shouldShorten := HasAnnotation(stmt) - - switch st := stmt.(type) { - case *dst.AssignStmt: - for _, expr := range st.Rhs { - s.formatExpr(expr, shouldShorten, false) - } - case *dst.BlockStmt: - for _, stmt := range st.List { - s.formatStmt(stmt) - } - case *dst.CaseClause: - if shouldShorten { - for _, arg := range st.List { - arg.Decorations().After = dst.NewLine - s.formatExpr(arg, false, false) - } - } - - for _, stmt := range st.Body { - s.formatStmt(stmt) - } - case *dst.CommClause: - for _, stmt := range st.Body { - s.formatStmt(stmt) - } - case *dst.DeclStmt: - s.formatDecl(st.Decl) - case *dst.DeferStmt: - s.formatExpr(st.Call, shouldShorten, false) - case *dst.ExprStmt: - s.formatExpr(st.X, shouldShorten, false) - case *dst.ForStmt: - s.formatStmt(st.Body) - case *dst.GoStmt: - s.formatExpr(st.Call, shouldShorten, false) - case *dst.IfStmt: - s.formatExpr(st.Cond, shouldShorten, false) - s.formatStmt(st.Body) - case *dst.RangeStmt: - s.formatStmt(st.Body) - case *dst.ReturnStmt: - for _, expr := range st.Results { - s.formatExpr(expr, shouldShorten, false) - } - case *dst.SelectStmt: - s.formatStmt(st.Body) - case *dst.SwitchStmt: - s.formatStmt(st.Body) - default: - // noop - } -} - -// formatExpr formats an AST expression node. These include uniary and binary expressions, function -// literals, and key/value pair statements, among others. -func (s *Shortener) formatExpr(expr dst.Expr, force bool, isChain bool) { - shouldShorten := force || HasAnnotation(expr) - - switch e := expr.(type) { - case *dst.BinaryExpr: - if (e.Op == token.LAND || e.Op == token.LOR) && shouldShorten { - if e.Y.Decorations().Before == dst.NewLine { - s.formatExpr(e.X, force, isChain) - } else { - e.Y.Decorations().Before = dst.NewLine - } - } else { - s.formatExpr(e.X, shouldShorten, isChain) - s.formatExpr(e.Y, shouldShorten, isChain) - } - case *dst.CallExpr: - _, ok := e.Fun.(*dst.SelectorExpr) - - if ok && - s.config.ChainSplitDots && - (shouldShorten || HasAnnotationRecursive(e)) && - (isChain || s.chainLength(e) > 1) { - e.Decorations().After = dst.NewLine - - for _, arg := range e.Args { - s.formatExpr(arg, false, true) - } - - s.formatExpr(e.Fun, shouldShorten, true) - } else { - shortenChildArgs := shouldShorten || HasAnnotationRecursive(e) - - for a, arg := range e.Args { - if shortenChildArgs { - if a == 0 { - arg.Decorations().Before = dst.NewLine - } else { - arg.Decorations().After = dst.None - } - arg.Decorations().After = dst.NewLine - } - s.formatExpr(arg, false, isChain) - } - s.formatExpr(e.Fun, shouldShorten, isChain) - } - case *dst.CompositeLit: - if shouldShorten { - for i, element := range e.Elts { - if i == 0 { - element.Decorations().Before = dst.NewLine - } - element.Decorations().After = dst.NewLine - } - } - - for _, element := range e.Elts { - s.formatExpr(element, false, isChain) - } - case *dst.FuncLit: - s.formatStmt(e.Body) - case *dst.FuncType: - if shouldShorten { - s.formatFieldList(e.Params) - } - case *dst.InterfaceType: - for _, method := range e.Methods.List { - if HasAnnotation(method) { - s.formatExpr(method.Type, true, isChain) - } - } - case *dst.KeyValueExpr: - s.formatExpr(e.Value, shouldShorten, isChain) - case *dst.SelectorExpr: - s.formatExpr(e.X, shouldShorten, isChain) - case *dst.StructType: - if s.config.ReformatTags { - FormatStructTags(e.Fields) - } - case *dst.UnaryExpr: - s.formatExpr(e.X, shouldShorten, isChain) - default: - // noop - } -} - -// formatSpec formats an AST spec node. These include type specifications, among other things. -func (s *Shortener) formatSpec(spec dst.Spec, force bool) { - shouldShorten := HasAnnotation(spec) || force - switch sp := spec.(type) { - case *dst.ValueSpec: - for _, expr := range sp.Values { - s.formatExpr(expr, shouldShorten, false) - } - case *dst.TypeSpec: - s.formatExpr(sp.Type, false, false) - default: - // noop - } -} - -// isGenerated checks whether the provided file bytes are from a generated file. -// This is done by looking for a set of typically-used strings in the first 5 lines. -func (s *Shortener) isGenerated(contents []byte) bool { - scanner := bufio.NewScanner(bytes.NewBuffer(contents)) - - for i := 0; scanner.Scan(); i++ { - if i >= 5 { - return false - } - - for _, term := range generatedTerms { - if strings.Contains(strings.ToLower(scanner.Text()), term) { - return true - } - } - } - - return false -} - -// chainLength determines the length of the function call chain in an expression. -func (s *Shortener) chainLength(callExpr *dst.CallExpr) int { - numCalls := 1 - currCall := callExpr - - for { - selectorExpr, ok := currCall.Fun.(*dst.SelectorExpr) - if !ok { - break - } - currCall, ok = selectorExpr.X.(*dst.CallExpr) - if !ok { - break - } - numCalls++ - } - - return numCalls -} diff --git a/vendor/github.com/golangci/golines/tags.go b/vendor/github.com/golangci/golines/tags.go deleted file mode 100644 index f5321fab47..0000000000 --- a/vendor/github.com/golangci/golines/tags.go +++ /dev/null @@ -1,217 +0,0 @@ -package golines - -import ( - "fmt" - "reflect" - "regexp" - "strings" - - "github.com/dave/dst" - "github.com/fatih/structtag" -) - -var structTagRegexp = regexp.MustCompile("`([ ]*[a-zA-Z0-9_-]+:\".*\"[ ]*){2,}`") - -// HasMultiKeyTags returns whether the given lines have a multikey struct line. -// It's used as an optimization step to avoid unnnecessary shortening rounds. -func HasMultiKeyTags(lines []string) bool { - for _, line := range lines { - if structTagRegexp.MatchString(line) { - return true - } - } - - return false -} - -// FormatStructTags formats struct tags so that the keys within each block of fields are aligned. -// It's not technically a shortening (and it usually makes these tags longer), so it's being -// kept separate from the core shortening logic for now. -// -// See the struct_tags fixture for examples. -func FormatStructTags(fieldList *dst.FieldList) { - if fieldList == nil || len(fieldList.List) == 0 { - return - } - - blockFields := []*dst.Field{} - - // Divide fields into "blocks" so that we don't do alignments across blank lines - for f, field := range fieldList.List { - if f == 0 || field.Decorations().Before == dst.EmptyLine { - alignTags(blockFields) - blockFields = blockFields[:0] - } - - blockFields = append(blockFields, field) - } - - alignTags(blockFields) -} - -// alignTags formats the struct tags within a single field block. -func alignTags(fields []*dst.Field) { - if len(fields) == 0 { - return - } - - maxTagWidths := map[string]int{} - tagKeys := []string{} - tagKVs := make([]map[string]string, len(fields)) - - maxTypeWidth := 0 - invalidWidths := false - - // First, scan over all field tags so that we can understand their values and widths - for f, field := range fields { - if len(field.Names) > 0 { - typeWidth, err := getWidth(field.Type) - if err != nil { - // We couldn't figure out the proper width of this field - invalidWidths = true - } else if typeWidth > maxTypeWidth { - maxTypeWidth = typeWidth - } - } - - if field.Tag == nil { - continue - } - - tagValue := field.Tag.Value - - // The dst library doesn't strip off the backticks, so we need to do this manually - if tagValue[0] != '`' || tagValue[len(tagValue)-1] != '`' { - continue - } - tagValue = tagValue[1 : len(tagValue)-1] - - subTags, err := structtag.Parse(tagValue) - if err != nil { - return - } - subTagKeys := subTags.Keys() - - structTag := reflect.StructTag(tagValue) - - for _, key := range subTagKeys { - value := structTag.Get(key) - - // Tag is key, value, and some extra chars (two quotes + one colon) - width := len(key) + tagValueLen(value) + 3 - - if _, ok := maxTagWidths[key]; !ok { - maxTagWidths[key] = width - tagKeys = append(tagKeys, key) - } else if width > maxTagWidths[key] { - maxTagWidths[key] = width - } - - if tagKVs[f] == nil { - tagKVs[f] = map[string]string{} - } - - tagKVs[f][key] = value - } - } - - // Go over all the fields again, replacing each tag with a reformatted one - for f, field := range fields { - if tagKVs[f] == nil { - continue - } - - tagComponents := []string{} - - if len(field.Names) == 0 && maxTypeWidth > 0 && !invalidWidths { - // Add extra spacing at beginning so that tag aligns with named field tags - tagComponents = append(tagComponents, "") - - for i := 0; i < maxTypeWidth; i++ { - tagComponents[len(tagComponents)-1] += " " - } - } - - for _, key := range tagKeys { - value, ok := tagKVs[f][key] - lenUsed := 0 - - if ok { - tagComponents = append(tagComponents, fmt.Sprintf("%s:\"%s\"", key, value)) - lenUsed += len(key) + tagValueLen(value) + 3 - } else { - tagComponents = append(tagComponents, "") - } - - if len(field.Names) > 0 || !invalidWidths { - lenRemaining := maxTagWidths[key] - lenUsed - - for i := 0; i < lenRemaining; i++ { - tagComponents[len(tagComponents)-1] += " " - } - } - } - - updatedTagValue := strings.TrimRight(strings.Join(tagComponents, " "), " ") - field.Tag.Value = fmt.Sprintf("`%s`", updatedTagValue) - } -} - -// get real tag value's length, fix multi-byte character's length, such as `ï` -// or `中文` -func tagValueLen(s string) int { - return len([]rune(s)) -} - -// getWidth tries to guess the formatted width of a dst node expression. If this isn't (yet) -// possible, it returns an error. -func getWidth(node dst.Node) (int, error) { - switch n := node.(type) { - case *dst.ArrayType: - eltWidth, err := getWidth(n.Elt) - if err != nil { - return 0, err - } - - return 2 + eltWidth, nil - case *dst.ChanType: - valWidth, err := getWidth(n.Value) - if err != nil { - return 0, err - } - - isSend := n.Dir&dst.SEND > 0 - isRecv := n.Dir&dst.RECV > 0 - - if isSend && isRecv { - // Channel does not include an arrow - return 5 + valWidth, nil - } - - // Channel includes an arrow - return 7 + valWidth, nil - case *dst.Ident: - return len(n.Name), nil - case *dst.MapType: - keyWidth, err := getWidth(n.Key) - if err != nil { - return 0, err - } - - valWidth, err := getWidth(n.Value) - if err != nil { - return 0, err - } - - return 5 + keyWidth + valWidth, nil - case *dst.StarExpr: - xWidth, err := getWidth(n.X) - if err != nil { - return 0, err - } - - return 1 + xWidth, nil - } - - return 0, fmt.Errorf("Could not get width of node %+v", node) -} diff --git a/vendor/github.com/golangci/misspell/.gitignore b/vendor/github.com/golangci/misspell/.gitignore deleted file mode 100644 index 5e5c368f87..0000000000 --- a/vendor/github.com/golangci/misspell/.gitignore +++ /dev/null @@ -1,37 +0,0 @@ -dist/ -bin/ -vendor/ - -.idea/ -/misspell - -# editor turds -*~ -*.gz -*.bz2 -*.csv - -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -*.test -*.prof diff --git a/vendor/github.com/golangci/misspell/.golangci.yml b/vendor/github.com/golangci/misspell/.golangci.yml deleted file mode 100644 index 1811db3a0d..0000000000 --- a/vendor/github.com/golangci/misspell/.golangci.yml +++ /dev/null @@ -1,102 +0,0 @@ -version: "2" - -formatters: - enable: - - gci - - gofumpt - settings: - gofumpt: - extra-rules: true - -linters: - default: all - disable: - - cyclop # duplicate of gocyclo - - dupl - - err113 - - errcheck # FIXME(ldez) must be fixed - - exhaustive - - exhaustruct - - forbidigo - - gochecknoglobals - - gochecknoinits - - gosmopolitan - - gosec # FIXME(ldez) must be fixed - - lll - - misspell - - mnd - - nakedret # FIXME(ldez) must be fixed - - nilnil - - nlreturn - - nonamedreturns # FIXME(ldez) must be fixed - - paralleltest - - prealloc - - rowserrcheck # not relevant (SQL) - - sqlclosecheck # not relevant (SQL) - - testpackage - - tparallel - - varnamelen - - wrapcheck - - wsl # FIXME(ldez) must be fixed - - settings: - depguard: - rules: - main: - deny: - - pkg: github.com/instana/testify - desc: not allowed - - pkg: github.com/pkg/errors - desc: Should be replaced by standard lib errors package - forbidigo: - forbid: - - pattern: ^print(ln)?$ - - pattern: ^panic$ - - pattern: ^spew\.Print(f|ln)?$ - - pattern: ^spew\.Dump$ - funlen: - lines: -1 - statements: 40 - goconst: - min-len: 3 - min-occurrences: 3 - gocritic: - disabled-checks: - - sloppyReassign - - rangeValCopy - - octalLiteral - - paramTypeCombine # already handle by gofumpt.extra-rules - - exitAfterDefer # FIXME(ldez) must be fixed - - ifElseChain # FIXME(ldez) must be fixed - enabled-tags: - - diagnostic - - style - - performance - settings: - hugeParam: - sizeThreshold: 100 - gocyclo: - min-complexity: 16 - godox: - keywords: - - FIXME - govet: - disable: - - fieldalignment - enable-all: true - misspell: - locale: US - - exclusions: - warn-unused: true - presets: - - comments - rules: - - linters: - - funlen - - goconst - path: .*_test.go - -issues: - max-issues-per-linter: 0 - max-same-issues: 0 diff --git a/vendor/github.com/golangci/misspell/.pre-commit-hooks.yaml b/vendor/github.com/golangci/misspell/.pre-commit-hooks.yaml deleted file mode 100644 index 5319a75ebe..0000000000 --- a/vendor/github.com/golangci/misspell/.pre-commit-hooks.yaml +++ /dev/null @@ -1,8 +0,0 @@ -- id: misspell - name: misspell - description: Correct commonly misspelled English words... quickly - language: golang - entry: misspell - args: - - -w - - -error diff --git a/vendor/github.com/golangci/misspell/CONTRIBUTING.md b/vendor/github.com/golangci/misspell/CONTRIBUTING.md deleted file mode 100644 index 1efa9fde6a..0000000000 --- a/vendor/github.com/golangci/misspell/CONTRIBUTING.md +++ /dev/null @@ -1,29 +0,0 @@ -# Contributing - -The files `words.go`, `works_uk.go`, and `works_us.go` must never be edited by hand. - -## Adding a word - -Misspell is neither a complete spell-checking program nor a grammar checker. -It is a tool to correct commonly misspelled English words. - -The list of words must contain only common mistakes. - -Before adding a word, you should have information about the misspelling frequency. - -- [ ] more than 15k inside GitHub (this limit is arbitrary and can involve) -- [ ] don't exist inside the [Wiktionary](https://en.wiktionary.org/wiki/) (as a modern form) -- [ ] don't exist inside the [Cambridge Dictionary](https://dictionary.cambridge.org) (as a modern form) -- [ ] don't exist inside the [Oxford Dictionary](https://www.oed.com/search/dictionary/) (as a modern form) - -If all criteria are met, a word can be added to the list of misspellings. - -The word should be added to one of the following files. - -- `internal/gen/sources/main.json`: common words. -- `internal/gen/sources/uk.json`: UK only words. -- `internal/gen/sources/us.json`: US only words. - -The target `make generate` will generate the Go files. - -The PR description must provide all the information (links) about the misspelling frequency. diff --git a/vendor/github.com/golangci/misspell/Dockerfile b/vendor/github.com/golangci/misspell/Dockerfile deleted file mode 100644 index c85cd6875e..0000000000 --- a/vendor/github.com/golangci/misspell/Dockerfile +++ /dev/null @@ -1,35 +0,0 @@ -FROM golang:1.22-alpine - -# cache buster -RUN echo 4 - -# git is needed for "go get" below -RUN apk add --no-cache git make - -# these are my standard testing / linting tools -RUN /bin/true \ - && rm -rf /go/src /go/pkg -# -# * SCOWL word list -# -# Downloads -# http://wordlist.aspell.net/dicts/ -# --> http://app.aspell.net/create -# - -# use en_US large size -# use regular size for others -ENV SOURCE_US_BIG http://app.aspell.net/create?max_size=70&spelling=US&max_variant=2&diacritic=both&special=hacker&special=roman-numerals&download=wordlist&encoding=utf-8&format=inline - -# should be able tell difference between English variations using this -ENV SOURCE_US http://app.aspell.net/create?max_size=60&spelling=US&max_variant=1&diacritic=both&download=wordlist&encoding=utf-8&format=inline -ENV SOURCE_GB_ISE http://app.aspell.net/create?max_size=60&spelling=GBs&max_variant=2&diacritic=both&download=wordlist&encoding=utf-8&format=inline -ENV SOURCE_GB_IZE http://app.aspell.net/create?max_size=60&spelling=GBz&max_variant=2&diacritic=both&download=wordlist&encoding=utf-8&format=inline -ENV SOURCE_CA http://app.aspell.net/create?max_size=60&spelling=CA&max_variant=2&diacritic=both&download=wordlist&encoding=utf-8&format=inline - -RUN /bin/true \ - && mkdir /scowl-wl \ - && wget -O /scowl-wl/words-US-60.txt ${SOURCE_US} \ - && wget -O /scowl-wl/words-GB-ise-60.txt ${SOURCE_GB_ISE} - -RUN git config --global --add safe.directory "/go/src/github.com/golangci/misspell" diff --git a/vendor/github.com/golangci/misspell/LICENSE b/vendor/github.com/golangci/misspell/LICENSE deleted file mode 100644 index bfcfcd3013..0000000000 --- a/vendor/github.com/golangci/misspell/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015-2017 Nick Galbreath - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/golangci/misspell/Makefile b/vendor/github.com/golangci/misspell/Makefile deleted file mode 100644 index a5275d9fd8..0000000000 --- a/vendor/github.com/golangci/misspell/Makefile +++ /dev/null @@ -1,69 +0,0 @@ -CONTAINER=golangci/misspell - -default: generate lint test build - -install: ## install misspell into GOPATH/bin - go install ./cmd/misspell - -build: ## build misspell - go build ./cmd/misspell - -test: ## run all tests - CGO_ENABLED=1 go test -v -race . - -lint: ## run linter - golangci-lint run - -generate: - go run ./internal/gen/ - -# the grep in line 2 is to remove misspellings in the spelling dictionary -# that trigger false positives!! -falsepositives: /scowl-wl - cat /scowl-wl/words-US-60.txt | \ - grep -i -v -E "payed|Tyre|Euclidian|nonoccurence|dependancy|reenforced|accidently|surprize|dependance|idealogy|binominal|causalities|conquerer|withing|casette|analyse|analogue|dialogue|paralyse|catalogue|archaeolog|clarinettist|catalyses|cancell|chisell|ageing|cataloguing" | \ - misspell -debug -error - cat /scowl-wl/words-GB-ise-60.txt | \ - grep -v -E "payed|nonoccurence|withing" | \ - misspell -locale=UK -debug -error -# cat /scowl-wl/words-GB-ize-60.txt | \ -# grep -v -E "withing" | \ -# misspell -debug -error -# cat /scowl-wl/words-CA-60.txt | \ -# grep -v -E "withing" | \ -# misspell -debug -error - -bench: ## run benchmarks - go test -bench '.*' - -clean: ## clean up time - rm -rf dist/ bin/ - go clean ./... - git gc --aggressive - -ci: docker-build ## run test like travis-ci does, requires docker - docker run --rm \ - -v $(PWD):/go/src/github.com/golangci/misspell \ - -w /go/src/github.com/golangci/misspell \ - ${CONTAINER} \ - make install falsepositives - -docker-build: ## build a docker test image - docker build -t ${CONTAINER} . - -docker-console: ## log into the test image - docker run --rm -it \ - -v $(PWD):/go/src/github.com/golangci/misspell \ - -w /go/src/github.com/golangci/misspell \ - ${CONTAINER} sh - -.PHONY: help ci console docker-build bench - -# https://www.client9.com/self-documenting-makefiles/ -help: - @awk -F ':|##' '/^[^\t].+?:.*?##/ {\ - printf "\033[36m%-30s\033[0m %s\n", $$1, $$NF \ - }' $(MAKEFILE_LIST) -.DEFAULT_GOAL=default -.PHONY=help - diff --git a/vendor/github.com/golangci/misspell/README.md b/vendor/github.com/golangci/misspell/README.md deleted file mode 100644 index 7a6abbe5f1..0000000000 --- a/vendor/github.com/golangci/misspell/README.md +++ /dev/null @@ -1,397 +0,0 @@ -[![Main](https://github.com/golangci/misspell/actions/workflows/ci.yml/badge.svg)](https://github.com/golangci/misspell/actions/workflows/ci.yml) -[![Go Report Card](https://goreportcard.com/badge/github.com/golangci/misspell)](https://goreportcard.com/report/github.com/golangci/misspell) -[![Go Reference](https://pkg.go.dev/badge/github.com/golangci/misspell.svg)](https://pkg.go.dev/github.com/golangci/misspell) -[![license](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](https://raw.golangci.com/golangci/misspell/head/LICENSE) - -Correct commonly misspelled English words... quickly. - -### Install - -If you just want a binary and to start using `misspell`: - -```bash -curl -sfL https://raw.githubusercontent.com/golangci/misspell/head/install-misspell.sh | sh -s -- -b ./bin ${MISSPELL_VERSION} -``` - -Both will install as `./bin/misspell`. -You can adjust the download location using the `-b` flag. -File a ticket if you want another platform supported. - -If you use [Go](https://golang.org/), the best way to run `misspell` is by using [golangci-lint](https://github.com/golangci/golangci-lint). -Otherwise, install `misspell` the old-fashioned way: - -```bash -go install github.com/golangci/misspell/cmd/misspell@latest -``` - -Also, if you like to live dangerously, one could do - -```bash -curl -sfL https://raw.githubusercontent.com/golangci/misspell/head/install-misspell.sh | sh -s -- -b $(go env GOPATH)/bin ${MISSPELL_VERSION} -``` - -### Usage - -```bash -$ misspell all.html your.txt important.md files.go -your.txt:42:10 found "langauge" a misspelling of "language" - -# ^ file, line, column -``` - -```console -$ misspell -help -Usage of misspell: - -debug - Debug matching, very slow - -dict string - User defined corrections file path (.csv). CSV format: typo,fix - -error - Exit with 2 if misspelling found - -f string - 'csv', 'sqlite3' or custom Go template for output - -i string - ignore the following corrections, comma-separated - -j int - Number of workers, 0 = number of CPUs - -legal - Show legal information and exit - -locale string - Correct spellings using locale preferences for US or UK. Default is to use a neutral variety of English. Setting locale to US will correct the British spelling of 'colour' to 'color' - -o string - output file or [stderr|stdout|] (default "stdout") - -q Do not emit misspelling output - -source string - Source mode: text (default), go (comments only) (default "text") - -v Show version and exit - -w Overwrite file with corrections (default is just to display) -``` - -### Pre-commit hook - -To use misspell with [pre-commit](https://pre-commit.com/), add the following to your `.pre-commit-config.yaml`: - - -```yaml -- repo: https://github.com/golangci/misspell - rev: v0.6.0 - hooks: - - id: misspell - # The hook will run on all files by default. - # To limit to some files only, use pre-commit patterns/types - # files: - # exclude: - # types: -``` - -## FAQ - -* [Automatic Corrections](#correct) -* [Converting UK spellings to US](#locale) -* [Using pipes and stdin](#stdin) -* [Go special support](#golang) -* [CSV Output](#csv) -* [Using SQLite3](#sqlite) -* [Changing output format](#output) -* [Checking a folder recursively](#recursive) -* [Performance](#performance) -* [Known Issues](#issues) -* [Debugging](#debug) -* [False Negatives and missing words](#missing) -* [Origin of Word Lists](#words) -* [Software License](#license) -* [Problem statement](#problem) -* [Other spelling correctors](#others) -* [Other ideas](#otherideas) - - -### How can I make the corrections automatically? - -Just add the `-w` flag! - -```console -$ misspell -w all.html your.txt important.md files.go -your.txt:9:21:corrected "langauge" to "language" - -# ^ File is rewritten only if a misspelling is found -``` - - -### How do I convert British spellings to American (or vice-versa)? - -Add the `-locale US` flag! - -```console -$ misspell -locale US important.txt -important.txt:10:20 found "colour" a misspelling of "color" -``` - -Add the `-locale UK` flag! - -```console -$ echo "My favorite color is blue" | misspell -locale UK -stdin:1:3:found "favorite color" a misspelling of "favourite colour" -``` - -Help is appreciated as I'm neither British nor an expert in the English language. - - -### How do you check an entire folder recursively? - -Just list a directory you'd like to check - -```bash -misspell . -misspell aDirectory anotherDirectory aFile -``` - -You can also run misspell recursively using the following shell tricks: - -```bash -misspell directory/**/* -``` - -or - -```bash -find . -type f | xargs misspell -``` - -You can select a type of file as well. -The following examples selects all `.txt` files that are *not* in the `vendor` directory: - -```bash -find . -type f -name '*.txt' | grep -v vendor/ | xargs misspell -error -``` - - -### Can I use pipes or `stdin` for input? - -Yes! - -Print messages to `stderr` only: - -```console -$ echo "zeebra" | misspell -stdin:1:0:found "zeebra" a misspelling of "zebra" -``` - -Print messages to `stderr`, and corrected text to `stdout`: - -```console -$ echo "zeebra" | misspell -w -stdin:1:0:corrected "zeebra" to "zebra" -zebra -``` - -Only print the corrected text to `stdout`: - -```console -$ echo "zeebra" | misspell -w -q -zebra -``` - - -### Are there special rules for Go source files? - -Yes, if you want to force a file to be checked as a Go source, use `-source=go` on the command line. -Conversely, you can check a Go source as if it was pure text by using `-source=text`. -You might want to do this since many variable names have misspellings in them! - -### Can I check only-comments in other programming languages? - -I'm told the using `-source=go` works well for Ruby, Javascript, Java, C and C++. - -It doesn't work well for Python and Bash. - - -### How Can I Get CSV Output? - -Using `-f csv`, the output is standard comma-separated values with headers in the first row. - -```console -$ misspell -f csv * -file,line,column,typo,corrected -"README.md",9,22,langauge,language -"README.md",47,25,langauge,language -``` - - -### How can I export to SQLite3? - -Using `-f sqlite`, the output is a [sqlite3](https://www.sqlite.org/index.html) dump-file. - -```console -$ misspell -f sqlite * > /tmp/misspell.sql -$ cat /tmp/misspell.sql - -PRAGMA foreign_keys=OFF; -BEGIN TRANSACTION; -CREATE TABLE misspell( - "file" TEXT, - "line" INTEGER,i - "column" INTEGER,i - "typo" TEXT, - "corrected" TEXT -); -INSERT INTO misspell VALUES("install.txt",202,31,"immediatly","immediately"); -# etc... -COMMIT; -``` - -```console -$ sqlite3 -init /tmp/misspell.sql :memory: 'select count(*) from misspell' -1 -``` - -With some tricks you can directly pipe output to `sqlite3` by using `-init /dev/stdin`: - -``` -misspell -f sqlite * | sqlite3 -init /dev/stdin -column -cmd '.width 60 15' ':memory' \ - 'select substr(file,35),typo,count(*) as count from misspell group by file, typo order by count desc;' -``` - - -### How can I ignore the rules? - -Using the `-i "comma,separated,rules"` flag you can specify corrections to ignore. - -For example, if you were to run `misspell -w -error -source=text` against document that contains the string `Guy Finkelshteyn Braswell`, -misspell would change the text to `Guy Finkelstheyn Bras well`. -You can then determine the rules to ignore by reverting the change and running the with the `-debug` flag. -You can then see that the corrections were `htey -> they` and `aswell -> as well`. -To ignore these two rules, you add `-i "htey,aswell"` to your command. -With debug mode on, you can see it print the corrections, but it will no longer make them. - - -### How can I change the output format? - -Using the `-f template` flag you can pass in a [Go text template](https://golang.org/pkg/text/template/) to format the output. - -One can use `printf "%q" VALUE` to safely quote a value. - -The default template: - -``` -{{ .Filename }}:{{ .Line }}:{{ .Column }}:corrected {{ printf "%q" .Original }} to "{{ printf "%q" .Corrected }}" -``` - -To just print probable misspellings: - -``` --f '{{ .Original }}' -``` - - -### What problem does this solve? - -This corrects commonly misspelled English words in computer source code, and other text-based formats (`.txt`, `.md`, etc.). - -It is designed to run quickly, -so it can be used as a [pre-commit hook](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) with minimal burden on the developer. - -It does not work with binary formats (e.g., Word, etc.). - -It is not a complete spell-checking program nor a grammar checker. - - -### What are other misspelling correctors and what's wrong with them? - -Some other misspelling correctors: - -* https://github.com/vlajos/misspell_fixer -* https://github.com/lyda/misspell-check -* https://github.com/lucasdemarchi/codespell - -They all work but have problems that prevented me from using them at scale: - -* slow, all of the above check one misspelling at a time (i.e., linear) using regexps -* not MIT/Apache2 licensed (or equivalent) -* have dependencies that don't work for me (Python3, Bash, GNU sed, etc.) -* don't understand American vs. British English and sometimes makes unwelcome "corrections" - -That said, they might be perfect for you and many have more features than this project! - - -### How fast is it? - -Misspell is easily 100x to 1000x faster than other spelling correctors. -You should be able to check and correct 1000 files in under 250ms. - -This uses the mighty power of Go's [strings.Replacer](https://golang.org/pkg/strings/#Replacer) -which is an implementation or variation of the [Aho–Corasick algorithm](https://en.wikipedia.org/wiki/Aho–Corasick_algorithm). -This makes multiple substring matches *simultaneously*. - -It also uses multiple CPU cores to work on multiple files concurrently. - - -### What problems does it have? - -Unlike the other projects, this doesn't know what a "word" is. -There may be more false positives and false negatives due to this. -On the other hand, it sometimes catches things others don't. - -Either way, please file bugs and we'll fix them! - -Since it operates in parallel to make corrections, -it can be non-obvious to determine exactly what word was corrected. - - -### It's making mistakes. How can I debug? - -Run using `-debug` flag on the file you want. -It should then print what word it is trying to correct. -Then [file a bug](https://github.com/golangci/misspell/issues) describing the problem. -Thanks! - - -### Why is it making mistakes or missing items in Go files? - -The matching function is *case-sensitive*, -so variable names that are multiple worlds either in all-uppercase or all-lowercase case sometimes can cause false positives. -For instance a variable named `bodyreader` could trigger a false positive since `yrea` is in the middle that could be corrected to `year`. -Other problems happen if the variable name uses an English contraction that should use an apostrophe. -The best way of fixing this is to use the [Effective Go naming conventions](https://golang.org/doc/effective_go.html#mixed-caps) -and use [camelCase](https://en.wikipedia.org/wiki/CamelCase) for variable names. -You can check your code using [golint](https://github.com/golang/lint) - - -### What license is this? - -The main code is [MIT](https://github.com/golangci/misspell/blob/head/LICENSE). - -Misspell also makes use of the Go standard library and contains a modified version of Go's [strings.Replacer](https://golang.org/pkg/strings/#Replacer) -which is covered under a [BSD License](https://github.com/golang/go/blob/head/LICENSE). -Type `misspell -legal` for more details or see [legal.go](https://github.com/golangci/misspell/blob/head/legal.go) - - -### Where do the word lists come from? - -It started with a word list from -[Wikipedia](https://en.wikipedia.org/wiki/Wikipedia:Lists_of_common_misspellings/For_machines). -Unfortunately, this list had to be highly edited as many of the words are obsolete or based on mistakes on mechanical typewriters (I'm guessing). - -Additional words were added based on actual mistakes seen in the wild (meaning self-generated). - -Variations of UK and US spellings are based on many sources, including: - -* [Comprehensive* list of American and British spelling differences (archive)](https://web.archive.org/web/20230326222449/http://tysto.com/uk-us-spelling-list.html) (with heavy editing, many are incorrect) -* [American and British spelling (archive)](https://web.archive.org/web/20160820231624/http://www.oxforddictionaries.com/us/words/american-and-british-spelling-american) (excellent site but incomplete) -* Diffing US and UK [SCOWL dictionaries](http://wordlist.aspell.net) - -American English is more accepting of spelling variations than is British English, -so "what is American or not" is subject to opinion. -Corrections and help welcome. - - -### What are some other enhancements that could be done? - -Here are some ideas for enhancements: - -- Capitalization of proper nouns: could be done (e.g., weekday and month names, country names, language names) -- Opinionated US spellings: US English has a number of words with alternate spellings. -Think [adviser vs. advisor](http://grammarist.com/spelling/adviser-advisor/). -While "advisor" is not wrong, the opinionated US locale would correct "advisor" to "adviser". -- Versioning: Some type of versioning is needed, so reporting mistakes and errors is easier. -- Feedback: Mistakes would be sent to some server for aggregation and feedback review. -- Contractions and Apostrophes: This would optionally correct "isnt" to "isn't", etc. diff --git a/vendor/github.com/golangci/misspell/RELEASE-HOWTO.md b/vendor/github.com/golangci/misspell/RELEASE-HOWTO.md deleted file mode 100644 index 55b52d962e..0000000000 --- a/vendor/github.com/golangci/misspell/RELEASE-HOWTO.md +++ /dev/null @@ -1,38 +0,0 @@ -# Release HOWTO - -since I forget. - - -1. Review existing tags and pick new release number - - ```sh - git tag - ``` - -2. Tag locally - - ```sh - git tag -a v0.1.0 -m "First release" - ``` - - If things get screwed up, delete the tag with - - ```sh - git tag -d v0.1.0 - ``` - -3. Test goreleaser - - TODO: how to install goreleaser - - ```sh - ./scripts/goreleaser-dryrun.sh - ``` - -4. Push - - ```bash - git push origin v0.1.0 - ``` - -5. Verify release and edit notes. See https://github.com/client9/misspell/releases diff --git a/vendor/github.com/golangci/misspell/ascii.go b/vendor/github.com/golangci/misspell/ascii.go deleted file mode 100644 index 74abe51419..0000000000 --- a/vendor/github.com/golangci/misspell/ascii.go +++ /dev/null @@ -1,60 +0,0 @@ -package misspell - -// ByteToUpper converts an ascii byte to upper cases. -// Uses a branch-less algorithm. -func ByteToUpper(x byte) byte { - b := byte(0x80) | x - c := b - byte(0x61) - d := ^(b - byte(0x7b)) - e := (c & d) & (^x & 0x7f) - return x - (e >> 2) -} - -// ByteToLower converts an ascii byte to lower case. -// Uses a branch-less algorithm. -func ByteToLower(eax byte) byte { - ebx := eax&byte(0x7f) + byte(0x25) - ebx = ebx&byte(0x7f) + byte(0x1a) - ebx = ((ebx & ^eax) >> 2) & byte(0x20) - return eax + ebx -} - -// ByteEqualFold does ascii compare, case insensitive. -func ByteEqualFold(a, b byte) bool { - return a == b || ByteToLower(a) == ByteToLower(b) -} - -// StringEqualFold ASCII case-insensitive comparison -// golang toUpper/toLower for both bytes and strings -// appears to be Unicode based which is super slow -// based from https://codereview.appspot.com/5180044/patch/14007/21002. -func StringEqualFold(s1, s2 string) bool { - if len(s1) != len(s2) { - return false - } - for i := range len(s1) { - c1 := s1[i] - c2 := s2[i] - // c1 & c2 - if c1 != c2 { - c1 |= 'a' - 'A' - c2 |= 'a' - 'A' - if c1 != c2 || c1 < 'a' || c1 > 'z' { - return false - } - } - } - return true -} - -// StringHasPrefixFold is similar to strings.HasPrefix but comparison is done ignoring ASCII case. -func StringHasPrefixFold(s1, s2 string) bool { - // prefix is bigger than input --> false - if len(s1) < len(s2) { - return false - } - if len(s1) == len(s2) { - return StringEqualFold(s1, s2) - } - return StringEqualFold(s1[:len(s2)], s2) -} diff --git a/vendor/github.com/golangci/misspell/case.go b/vendor/github.com/golangci/misspell/case.go deleted file mode 100644 index 533ce4db3b..0000000000 --- a/vendor/github.com/golangci/misspell/case.go +++ /dev/null @@ -1,58 +0,0 @@ -package misspell - -import ( - "strings" -) - -// WordCase is an enum of various word casing styles. -type WordCase int - -// Various WordCase types... likely to be not correct. -const ( - CaseUnknown WordCase = iota - CaseLower - CaseUpper - CaseTitle -) - -// CaseStyle returns what case style a word is in. -func CaseStyle(word string) WordCase { - upperCount := 0 - lowerCount := 0 - - // this iterates over RUNES not BYTES - for i := range len(word) { - ch := word[i] - switch { - case ch >= 'a' && ch <= 'z': - lowerCount++ - case ch >= 'A' && ch <= 'Z': - upperCount++ - } - } - - switch { - case upperCount != 0 && lowerCount == 0: - return CaseUpper - case upperCount == 0 && lowerCount != 0: - return CaseLower - case upperCount == 1 && lowerCount > 0 && word[0] >= 'A' && word[0] <= 'Z': - return CaseTitle - } - return CaseUnknown -} - -// CaseVariations returns: -// If AllUpper or First-Letter-Only is upper-cased: add the all upper case version. -// If AllLower, add the original, the title and upper-case forms. -// If Mixed, return the original, and the all upper-case form. -func CaseVariations(word string, style WordCase) []string { - switch style { - case CaseLower: - return []string{word, strings.ToUpper(word[0:1]) + word[1:], strings.ToUpper(word)} - case CaseUpper: - return []string{strings.ToUpper(word)} - default: - return []string{word, strings.ToUpper(word)} - } -} diff --git a/vendor/github.com/golangci/misspell/goreleaser.yml b/vendor/github.com/golangci/misspell/goreleaser.yml deleted file mode 100644 index 2d2be1a759..0000000000 --- a/vendor/github.com/golangci/misspell/goreleaser.yml +++ /dev/null @@ -1,31 +0,0 @@ -project_name: misspell - -builds: - - main: cmd/misspell/main.go - binary: misspell - ldflags: -s -w -X main.version={{.Version}} - goos: - - darwin - - linux - - windows - goarch: - - amd64 - - arm64 - env: - - CGO_ENABLED=0 - -archives: - - format: tar.gz - wrap_in_directory: true - format_overrides: - - goos: windows - format: zip - name_template: '{{ .Binary }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}' - files: - - LICENSE - -checksum: - name_template: "{{ .ProjectName }}_{{ .Version }}_checksums.txt" - -snapshot: - name_template: "SNAPSHOT-{{.Commit}}" diff --git a/vendor/github.com/golangci/misspell/install-misspell.sh b/vendor/github.com/golangci/misspell/install-misspell.sh deleted file mode 100644 index 7d0655b2f5..0000000000 --- a/vendor/github.com/golangci/misspell/install-misspell.sh +++ /dev/null @@ -1,397 +0,0 @@ -#!/bin/sh -set -e - -usage() { - this=$1 - cat <] [-d] [] - -b sets bindir or installation directory, Defaults to ./bin - -d turns on debug logging - is a tag from - https://github.com/golangci/misspell/releases - If tag is missing, then the latest will be used. - -EOF - exit 2 -} - -parse_args() { - # BINDIR is ./bin unless set be ENV - # overridden by flag below - - BINDIR=${BINDIR:-./bin} - while getopts "b:dh?x" arg; do - case "$arg" in - b) BINDIR="$OPTARG" ;; - d) log_set_priority 10 ;; - h | \?) usage "$0" ;; - x) set -x ;; - esac - done - shift $((OPTIND - 1)) - TAG=$1 -} -# this function wraps all the destructive operations -# if a curl|bash cuts off the end of the script due to -# network, either nothing will happen or will syntax error -# out preventing half-done work -execute() { - tmpdir=$(mktemp -d) - log_debug "downloading files into ${tmpdir}" - http_download "${tmpdir}/${TARBALL}" "${TARBALL_URL}" - http_download "${tmpdir}/${CHECKSUM}" "${CHECKSUM_URL}" - hash_sha256_verify "${tmpdir}/${TARBALL}" "${tmpdir}/${CHECKSUM}" - srcdir="${tmpdir}/${NAME}" - rm -rf "${srcdir}" - (cd "${tmpdir}" && untar "${TARBALL}") - test ! -d "${BINDIR}" && install -d "${BINDIR}" - for binexe in $BINARIES; do - if [ "$OS" = "windows" ]; then - binexe="${binexe}.exe" - fi - install "${srcdir}/${binexe}" "${BINDIR}/" - log_info "installed ${BINDIR}/${binexe}" - done - rm -rf "${tmpdir}" -} -get_binaries() { - case "$PLATFORM" in - darwin/amd64) BINARIES="misspell" ;; - darwin/arm64) BINARIES="misspell" ;; - linux/amd64) BINARIES="misspell" ;; - linux/arm64) BINARIES="misspell" ;; - windows/amd64) BINARIES="misspell" ;; - windows/arm64) BINARIES="misspell" ;; - *) - log_crit "platform $PLATFORM is not supported. Make sure this script is up-to-date and file request at https://github.com/${PREFIX}/issues/new" - exit 1 - ;; - esac -} -tag_to_version() { - if [ -z "${TAG}" ]; then - log_info "checking GitHub for latest tag" - else - log_info "checking GitHub for tag '${TAG}'" - fi - REALTAG=$(github_release "$OWNER/$REPO" "${TAG}") && true - if test -z "$REALTAG"; then - log_crit "unable to find '${TAG}' - use 'latest' or see https://github.com/${PREFIX}/releases for details" - exit 1 - fi - # if version starts with 'v', remove it - TAG="$REALTAG" - VERSION=${TAG#v} -} -adjust_format() { - # change format (tar.gz or zip) based on OS - case ${OS} in - windows) FORMAT=zip ;; - esac - true -} -adjust_os() { - # adjust archive name based on OS - true -} -adjust_arch() { - # adjust archive name based on ARCH - true -} - -cat /dev/null </dev/null -} -echoerr() { - echo "$@" 1>&2 -} -_logp=6 -log_set_priority() { - _logp="$1" -} -log_priority() { - if test -z "$1"; then - echo "$_logp" - return - fi - [ "$1" -le "$_logp" ] -} -log_tag() { - case $1 in - 0) echo "emerg" ;; - 1) echo "alert" ;; - 2) echo "crit" ;; - 3) echo "err" ;; - 4) echo "warning" ;; - 5) echo "notice" ;; - 6) echo "info" ;; - 7) echo "debug" ;; - *) echo "$1" ;; - esac -} -log_debug() { - log_priority 7 || return 0 - echoerr "$(log_prefix)" "$(log_tag 7)" "$@" -} -log_info() { - log_priority 6 || return 0 - echoerr "$(log_prefix)" "$(log_tag 6)" "$@" -} -log_err() { - log_priority 3 || return 0 - echoerr "$(log_prefix)" "$(log_tag 3)" "$@" -} -log_crit() { - log_priority 2 || return 0 - echoerr "$(log_prefix)" "$(log_tag 2)" "$@" -} -uname_os() { - os=$(uname -s | tr '[:upper:]' '[:lower:]') - case "$os" in - msys*) os="windows" ;; - mingw*) os="windows" ;; - cygwin*) os="windows" ;; - win*) os="windows" ;; - sunos) [ "$(uname -o)" = "illumos" ] && os=illumos ;; - esac - echo "$os" -} -uname_arch() { - arch=$(uname -m) - case $arch in - x86_64) arch="amd64" ;; - x86) arch="386" ;; - i686) arch="386" ;; - i386) arch="386" ;; - i86pc) arch="amd64" ;; - aarch64) arch="arm64" ;; - armv5*) arch="armv5" ;; - armv6*) arch="armv6" ;; - armv7*) arch="armv7" ;; - loongarch64) arch="loong64" ;; - esac - echo "${arch}" -} -uname_os_check() { - os=$(uname_os) - case "$os" in - darwin) return 0 ;; - dragonfly) return 0 ;; - freebsd) return 0 ;; - illumos) return 0;; - linux) return 0 ;; - android) return 0 ;; - nacl) return 0 ;; - netbsd) return 0 ;; - openbsd) return 0 ;; - plan9) return 0 ;; - solaris) return 0 ;; - windows) return 0 ;; - esac - log_crit "uname_os_check '$(uname -s)' got converted to '$os' which is not a GOOS value." - return 1 -} -uname_arch_check() { - arch=$(uname_arch) - case "$arch" in - 386) return 0 ;; - amd64) return 0 ;; - arm64) return 0 ;; - armv5) return 0 ;; - armv6) return 0 ;; - armv7) return 0 ;; - ppc64) return 0 ;; - ppc64le) return 0 ;; - mips) return 0 ;; - mipsle) return 0 ;; - mips64) return 0 ;; - mips64le) return 0 ;; - s390x) return 0 ;; - riscv64) return 0 ;; - amd64p32) return 0 ;; - loong64) return 0 ;; - esac - log_crit "uname_arch_check '$(uname -m)' got converted to '$arch' which is not a GOARCH value." - return 1 -} -untar() { - tarball=$1 - case "${tarball}" in - *.tar.gz | *.tgz) tar --no-same-owner -xzf "${tarball}" ;; - *.tar) tar --no-same-owner -xf "${tarball}" ;; - *.zip) unzip "${tarball}" ;; - *) - log_err "untar unknown archive format for ${tarball}" - return 1 - ;; - esac -} - -http_download_curl() { - local_file=$1 - source_url=$2 - header=$3 - - # workaround https://github.com/curl/curl/issues/13845 - curl_version=$(curl --version | head -n 1 | awk '{ print $2 }') - if [ "$curl_version" = "8.8.0" ]; then - log_debug "http_download_curl curl $curl_version detected" - if [ -z "$header" ]; then - curl -sL -o "$local_file" "$source_url" - else - curl -sL -H "$header" -o "$local_file" "$source_url" - nf=$(jq -r '.error // ""' "$local_file") - if [ -n "$nf" ]; then - log_debug "http_download_curl received an error: $nf" - return 1 - fi - fi - return 0 - fi - - if [ -z "$header" ]; then - code=$(curl -w '%{http_code}' -sL -o "$local_file" "$source_url") - else - code=$(curl -w '%{http_code}' -sL -H "$header" -o "$local_file" "$source_url") - fi - if [ "$code" != "200" ]; then - log_debug "http_download_curl received HTTP status $code" - return 1 - fi - return 0 -} - -http_download_wget() { - local_file=$1 - source_url=$2 - header=$3 - if [ -z "$header" ]; then - wget -q -O "$local_file" "$source_url" - else - wget -q --header "$header" -O "$local_file" "$source_url" - fi -} -http_download() { - log_debug "http_download $2" - if is_command curl; then - http_download_curl "$@" - return - elif is_command wget; then - http_download_wget "$@" - return - fi - log_crit "http_download unable to find wget or curl" - return 1 -} -http_copy() { - tmp=$(mktemp) - http_download "${tmp}" "$1" "$2" || return 1 - body=$(cat "$tmp") - rm -f "${tmp}" - echo "$body" -} -github_release() { - owner_repo=$1 - version=$2 - test -z "$version" && version="latest" - giturl="https://github.com/${owner_repo}/releases/${version}" - json=$(http_copy "$giturl" "Accept:application/json") - test -z "$json" && return 1 - version=$(echo "$json" | tr -s '\n' ' ' | sed 's/.*"tag_name":"//' | sed 's/".*//') - test -z "$version" && return 1 - echo "$version" -} -hash_sha256() { - TARGET=${1:-/dev/stdin} - if is_command gsha256sum; then - hash=$(gsha256sum "$TARGET") || return 1 - echo "$hash" | cut -d ' ' -f 1 - elif is_command sha256sum; then - hash=$(sha256sum "$TARGET") || return 1 - echo "$hash" | cut -d ' ' -f 1 - elif is_command shasum; then - hash=$(shasum -a 256 "$TARGET" 2>/dev/null) || return 1 - echo "$hash" | cut -d ' ' -f 1 - elif is_command openssl; then - hash=$(openssl -dst openssl dgst -sha256 "$TARGET") || return 1 - echo "$hash" | cut -d ' ' -f a - else - log_crit "hash_sha256 unable to find command to compute sha-256 hash" - return 1 - fi -} -hash_sha256_verify() { - TARGET=$1 - checksums=$2 - if [ -z "$checksums" ]; then - log_err "hash_sha256_verify checksum file not specified in arg2" - return 1 - fi - BASENAME=${TARGET##*/} - want=$(grep "${BASENAME}" "${checksums}" 2>/dev/null | tr '\t' ' ' | cut -d ' ' -f 1) - if [ -z "$want" ]; then - log_err "hash_sha256_verify unable to find checksum for '${TARGET}' in '${checksums}'" - return 1 - fi - got=$(hash_sha256 "$TARGET") - if [ "$want" != "$got" ]; then - log_err "hash_sha256_verify checksum for '$TARGET' did not verify ${want} vs $got" - return 1 - fi -} -cat /dev/null < 50000 { - var fin *os.File - fin, err = os.Open(filename) - if err != nil { - return "", fmt.Errorf("unable to open large file %q: %w", filename, err) - } - defer fin.Close() - buf := make([]byte, 512) - _, err = io.ReadFull(fin, buf) - if err != nil { - return "", fmt.Errorf("unable to read 512 bytes from %q: %w", filename, err) - } - if !isTextFile(buf) { - return "", nil - } - - // set so we don't double-check this file - isText = true - } - - // read in whole file - raw, err := os.ReadFile(filename) - if err != nil { - return "", fmt.Errorf("unable to read all %q: %w", filename, err) - } - - if !isText && !isTextFile(raw) { - return "", nil - } - return string(raw), nil -} diff --git a/vendor/github.com/golangci/misspell/notwords.go b/vendor/github.com/golangci/misspell/notwords.go deleted file mode 100644 index f694f46dc0..0000000000 --- a/vendor/github.com/golangci/misspell/notwords.go +++ /dev/null @@ -1,102 +0,0 @@ -package misspell - -import ( - "bytes" - "regexp" - "strings" - "unicode" -) - -var ( - reEmail = regexp.MustCompile(`[[:alnum:]_.%+-]+@[[:alnum:]-.]+\.[[:alpha:]]{2,6}[^[:alpha:]]`) - reBackslash = regexp.MustCompile(`\\[[:lower:]]`) - - // reHost Host name regular expression. - // The length of any one label is limited between 1 and 63 octets. (https://www.ietf.org/rfc/rfc2181.txt) - // A TLD has at least 2 letters. - reHost = regexp.MustCompile(`([[:alnum:]-]+\.)+[[:alpha:]]{2,63}`) -) - -// RemovePath attempts to strip away embedded file system paths, e.g. -// -// /foo/bar or /static/myimg.png -// -// TODO: windows style. -func RemovePath(s string) string { - out := bytes.Buffer{} - var idx int - for s != "" { - if idx = strings.IndexByte(s, '/'); idx == -1 { - out.WriteString(s) - break - } - - if idx > 0 { - idx-- - } - - var chclass string - switch s[idx] { - case '/', ' ', '\n', '\t', '\r': - chclass = " \n\r\t" - case '[': - chclass = "]\n" - case '(': - chclass = ")\n" - default: - out.WriteString(s[:idx+2]) - s = s[idx+2:] - continue - } - - endx := strings.IndexAny(s[idx+1:], chclass) - if endx != -1 { - out.WriteString(s[:idx+1]) - out.Write(bytes.Repeat([]byte{' '}, endx)) - s = s[idx+endx+1:] - } else { - out.WriteString(s) - break - } - } - return out.String() -} - -// replaceWithBlanks returns a string with the same number of spaces as the input. -func replaceWithBlanks(s string) string { - return strings.Repeat(" ", len(s)) -} - -// replaceHost same as replaceWithBlanks but if the string contains at least one uppercase letter returns the string. -// Domain names are case-insensitive but browsers and DNS convert uppercase to lower case. (https://www.ietf.org/rfc/rfc4343.txt) -func replaceHost(s string) string { - for _, r := range s { - if unicode.IsUpper(r) { - return s - } - } - - return replaceWithBlanks(s) -} - -// RemoveEmail remove email-like strings, e.g. "nickg+junk@xfoobar.com", "nickg@xyz.abc123.biz". -func RemoveEmail(s string) string { - return reEmail.ReplaceAllStringFunc(s, replaceWithBlanks) -} - -// RemoveHost removes host-like strings "foobar.com" "abc123.fo1231.biz". -func RemoveHost(s string) string { - return reHost.ReplaceAllStringFunc(s, replaceHost) -} - -// RemoveBackslashEscapes removes characters that are preceded by a backslash. -// commonly found in printf format string "\nto". -func removeBackslashEscapes(s string) string { - return reBackslash.ReplaceAllStringFunc(s, replaceWithBlanks) -} - -// RemoveNotWords blanks out all the not words. -func RemoveNotWords(s string) string { - // do most selective/specific first - return removeBackslashEscapes(RemoveHost(RemoveEmail(RemovePath(StripURL(s))))) -} diff --git a/vendor/github.com/golangci/misspell/replace.go b/vendor/github.com/golangci/misspell/replace.go deleted file mode 100644 index f51ac3b3bc..0000000000 --- a/vendor/github.com/golangci/misspell/replace.go +++ /dev/null @@ -1,238 +0,0 @@ -package misspell - -import ( - "bufio" - "bytes" - "io" - "regexp" - "slices" - "strings" - "text/scanner" -) - -func inArray(haystack []string, needle string) bool { - return slices.ContainsFunc(haystack, func(word string) bool { - return strings.EqualFold(needle, word) - }) -} - -var wordRegexp = regexp.MustCompile(`[a-zA-Z0-9']+`) - -// Diff is datastructures showing what changed in a single line. -type Diff struct { - Filename string - FullLine string - Line int - Column int - Original string - Corrected string -} - -// Replacer is the main struct for spelling correction. -type Replacer struct { - Replacements []string - Debug bool - engine *StringReplacer - corrected map[string]string -} - -// New creates a new default Replacer using the main rule list. -func New() *Replacer { - r := Replacer{ - Replacements: DictMain, - } - r.Compile() - return &r -} - -// RemoveRule deletes existing rules. -// The content of `ignore` is case-insensitive. -// TODO: make in place to save memory. -func (r *Replacer) RemoveRule(ignore []string) { - newWords := make([]string, 0, len(r.Replacements)) - for i := 0; i < len(r.Replacements); i += 2 { - if inArray(ignore, r.Replacements[i]) { - continue - } - newWords = append(newWords, r.Replacements[i:i+2]...) - } - r.engine = nil - r.Replacements = newWords -} - -// AddRuleList appends new rules. -// Input is in the same form as Strings.Replacer: [ old1, new1, old2, new2, ....] -// Note: does not check for duplicates. -func (r *Replacer) AddRuleList(additions []string) { - r.engine = nil - r.Replacements = append(r.Replacements, additions...) -} - -// Compile compiles the rules. -// Required before using the Replace functions. -func (r *Replacer) Compile() { - r.corrected = make(map[string]string, len(r.Replacements)/2) - for i := 0; i < len(r.Replacements); i += 2 { - r.corrected[r.Replacements[i]] = r.Replacements[i+1] - } - r.engine = NewStringReplacer(r.Replacements...) -} - -// ReplaceGo is a specialized routine for correcting Golang source files. -// Currently only checks comments, not identifiers for spelling. -func (r *Replacer) ReplaceGo(input string) (string, []Diff) { - var s scanner.Scanner - s.Init(strings.NewReader(input)) - s.Mode = scanner.ScanIdents | scanner.ScanFloats | scanner.ScanChars | scanner.ScanStrings | scanner.ScanRawStrings | scanner.ScanComments - lastPos := 0 - output := "" -Loop: - for { - switch s.Scan() { - case scanner.Comment: - origComment := s.TokenText() - newComment := r.engine.Replace(origComment) - - if origComment != newComment { - // s.Pos().Offset is the end of the current token - // subtract len(origComment) to get the start of the token - offset := s.Pos().Offset - output = output + input[lastPos:offset-len(origComment)] + newComment - lastPos = offset - } - case scanner.EOF: - break Loop - } - } - - if lastPos == 0 { - // no changes, no copies - return input, nil - } - if lastPos < len(input) { - output += input[lastPos:] - } - diffs := make([]Diff, 0, 8) - buf := bytes.NewBuffer(make([]byte, 0, max(len(input), len(output))+100)) - // faster that making a bytes.Buffer and bufio.ReadString - outlines := strings.SplitAfter(output, "\n") - inlines := strings.SplitAfter(input, "\n") - for i := range inlines { - if inlines[i] == outlines[i] { - buf.WriteString(outlines[i]) - continue - } - r.recheckLine(inlines[i], i+1, buf, func(d Diff) { - diffs = append(diffs, d) - }) - } - - return buf.String(), diffs -} - -// Replace is correcting misspellings in input, returning corrected version along with a list of diffs. -func (r *Replacer) Replace(input string) (string, []Diff) { - output := r.engine.Replace(input) - if input == output { - return input, nil - } - diffs := make([]Diff, 0, 8) - buf := bytes.NewBuffer(make([]byte, 0, max(len(input), len(output))+100)) - // faster that making a bytes.Buffer and bufio.ReadString - outlines := strings.SplitAfter(output, "\n") - inlines := strings.SplitAfter(input, "\n") - for i := range inlines { - if inlines[i] == outlines[i] { - buf.WriteString(outlines[i]) - continue - } - r.recheckLine(inlines[i], i+1, buf, func(d Diff) { - diffs = append(diffs, d) - }) - } - - return buf.String(), diffs -} - -// ReplaceReader applies spelling corrections to a reader stream. -// Diffs are emitted through a callback. -func (r *Replacer) ReplaceReader(raw io.Reader, w io.Writer, next func(Diff)) error { - var ( - err error - line string - lineNum int - ) - reader := bufio.NewReader(raw) - for err == nil { - lineNum++ - line, err = reader.ReadString('\n') - - // if it's EOF, then line has the last line - // don't like the check of err here and - // in for loop - if err != nil && err != io.EOF { - return err - } - // easily 5x faster than regexp+map - if line == r.engine.Replace(line) { - io.WriteString(w, line) - continue - } - // but it can be inaccurate, so we need to double-check - r.recheckLine(line, lineNum, w, next) - } - return nil -} - -/* -line1 and line2 are different -extract words from each line1 - -replace word -> newword -if word == new-word - - continue - -if new-word in list of replacements - - continue - -new word not original, and not in list of replacements some substring got mixed up. UNdo. -*/ -func (r *Replacer) recheckLine(s string, lineNum int, buf io.Writer, next func(Diff)) { - first := 0 - redacted := RemoveNotWords(s) - - idx := wordRegexp.FindAllStringIndex(redacted, -1) - for _, ab := range idx { - word := s[ab[0]:ab[1]] - newword := r.engine.Replace(word) - if newword == word { - // no replacement done - continue - } - - // ignore camelCase words - // https://github.com/client9/misspell/issues/113 - if CaseStyle(word) == CaseUnknown { - continue - } - - if StringEqualFold(r.corrected[strings.ToLower(word)], newword) { - // word got corrected into something we know - io.WriteString(buf, s[first:ab[0]]) - io.WriteString(buf, newword) - first = ab[1] - next(Diff{ - FullLine: s, - Line: lineNum, - Original: word, - Corrected: newword, - Column: ab[0], - }) - continue - } - // Word got corrected into something unknown. Ignore it - } - io.WriteString(buf, s[first:]) -} diff --git a/vendor/github.com/golangci/misspell/stringreplacer.go b/vendor/github.com/golangci/misspell/stringreplacer.go deleted file mode 100644 index a037168491..0000000000 --- a/vendor/github.com/golangci/misspell/stringreplacer.go +++ /dev/null @@ -1,336 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package misspell - -import ( - "io" - "strings" -) - -// StringReplacer replaces a list of strings with replacements. -// It is safe for concurrent use by multiple goroutines. -type StringReplacer struct { - r replacer -} - -// replacer is the interface that a replacement algorithm needs to implement. -type replacer interface { - Replace(s string) string - WriteString(w io.Writer, s string) (n int, err error) -} - -// NewStringReplacer returns a new Replacer from a list of old, new string pairs. -// Replacements are performed in order, without overlapping matches. -func NewStringReplacer(oldnew ...string) *StringReplacer { - if len(oldnew)%2 == 1 { - panic("strings.NewReplacer: odd argument count") - } - - return &StringReplacer{r: makeGenericReplacer(oldnew)} -} - -// Replace returns a copy of s with all replacements performed. -func (r *StringReplacer) Replace(s string) string { - return r.r.Replace(s) -} - -// WriteString writes s to w with all replacements performed. -func (r *StringReplacer) WriteString(w io.Writer, s string) (int, error) { - return r.r.WriteString(w, s) -} - -// trieNode is a node in a lookup trie for prioritized key/value pairs. Keys -// and values may be empty. For example, the trie containing keys "ax", "ay", -// "bcbc", "x" and "xy" could have eight nodes: -// -// n0 - -// n1 a- -// n2 .x+ -// n3 .y+ -// n4 b- -// n5 .cbc+ -// n6 x+ -// n7 .y+ -// -// n0 is the root node, and its children are n1, n4 and n6; n1's children are -// n2 and n3; n4's child is n5; n6's child is n7. Nodes n0, n1 and n4 (marked -// with a trailing "-") are partial keys, and nodes n2, n3, n5, n6 and n7 -// (marked with a trailing "+") are complete keys. -type trieNode struct { - // value is the value of the trie node's key/value pair. It is empty if - // this node is not a complete key. - value string - // priority is the priority (higher is more important) of the trie node's - // key/value pair; keys are not necessarily matched shortest- or longest- - // first. Priority is positive if this node is a complete key, and zero - // otherwise. In the example above, positive/zero priorities are marked - // with a trailing "+" or "-". - priority int - - // A trie node may have zero, one or more child nodes: - // * if the remaining fields are zero, there are no children. - // * if prefix and next are non-zero, there is one child in next. - // * if table is non-zero, it defines all the children. - // - // Prefixes are preferred over tables when there is one child, but the - // root node always uses a table for lookup efficiency. - - // prefix is the difference in keys between this trie node and the next. - // In the example above, node n4 has prefix "cbc" and n4's next node is n5. - // Node n5 has no children and so has zero prefix, next and table fields. - prefix string - next *trieNode - - // table is a lookup table indexed by the next byte in the key, after - // remapping that byte through genericReplacer.mapping to create a dense - // index. In the example above, the keys only use 'a', 'b', 'c', 'x' and - // 'y', which remap to 0, 1, 2, 3 and 4. All other bytes remap to 5, and - // genericReplacer.tableSize will be 5. Node n0's table will be - // []*trieNode{ 0:n1, 1:n4, 3:n6 }, where the 0, 1 and 3 are the remapped - // 'a', 'b' and 'x'. - table []*trieNode -} - -func (t *trieNode) add(key, val string, priority int, r *genericReplacer) { - if key == "" { - if t.priority == 0 { - t.value = val - t.priority = priority - } - return - } - - if t.prefix != "" { - // Need to split the prefix among multiple nodes. - var n int // length of the longest common prefix - for ; n < len(t.prefix) && n < len(key); n++ { - if t.prefix[n] != key[n] { - break - } - } - switch n { - case len(t.prefix): - t.next.add(key[n:], val, priority, r) - case 0: - // First byte differs, start a new lookup table here. Looking up - // what is currently t.prefix[0] will lead to prefixNode, and - // looking up key[0] will lead to keyNode. - var prefixNode *trieNode - if len(t.prefix) == 1 { - prefixNode = t.next - } else { - prefixNode = &trieNode{ - prefix: t.prefix[1:], - next: t.next, - } - } - keyNode := new(trieNode) - t.table = make([]*trieNode, r.tableSize) - t.table[r.mapping[t.prefix[0]]] = prefixNode - t.table[r.mapping[key[0]]] = keyNode - t.prefix = "" - t.next = nil - keyNode.add(key[1:], val, priority, r) - default: - // Insert new node after the common section of the prefix. - next := &trieNode{ - prefix: t.prefix[n:], - next: t.next, - } - t.prefix = t.prefix[:n] - t.next = next - next.add(key[n:], val, priority, r) - } - return - } - - if t.table != nil { - // Insert into existing table. - m := r.mapping[key[0]] - if t.table[m] == nil { - t.table[m] = new(trieNode) - } - t.table[m].add(key[1:], val, priority, r) - return - } - - t.prefix = key - t.next = new(trieNode) - t.next.add("", val, priority, r) -} - -// genericReplacer is the fully generic algorithm. -// It's used as a fallback when nothing faster can be used. -type genericReplacer struct { - root trieNode - // tableSize is the size of a trie node's lookup table. It is the number - // of unique key bytes. - tableSize int - // mapping maps from key bytes to a dense index for trieNode.table. - mapping [256]byte -} - -func makeGenericReplacer(oldnew []string) *genericReplacer { - r := new(genericReplacer) - // Find each byte used, then assign them each an index. - for i := 0; i < len(oldnew); i += 2 { - key := strings.ToLower(oldnew[i]) - for j := range len(key) { - r.mapping[key[j]] = 1 - } - } - - for _, b := range r.mapping { - r.tableSize += int(b) - } - - var index byte - for i, b := range r.mapping { - if b == 0 { - r.mapping[i] = byte(r.tableSize) - } else { - r.mapping[i] = index - index++ - } - } - // Ensure root node uses a lookup table (for performance). - r.root.table = make([]*trieNode, r.tableSize) - - for i := 0; i < len(oldnew); i += 2 { - r.root.add(strings.ToLower(oldnew[i]), oldnew[i+1], len(oldnew)-i, r) - } - return r -} - -func (r *genericReplacer) Replace(s string) string { - buf := make(appendSliceWriter, 0, len(s)) - r.WriteString(&buf, s) - return string(buf) -} - -func (r *genericReplacer) WriteString(w io.Writer, s string) (n int, err error) { - sw := getStringWriter(w) - var last, wn int - var prevMatchEmpty bool - for i := 0; i <= len(s); { - // Fast path: s[i] is not a prefix of any pattern. - if i != len(s) && r.root.priority == 0 { - index := int(r.mapping[ByteToLower(s[i])]) - if index == r.tableSize || r.root.table[index] == nil { - i++ - continue - } - } - - // Ignore the empty match iff the previous loop found the empty match. - val, keylen, match := r.lookup(s[i:], prevMatchEmpty) - prevMatchEmpty = match && keylen == 0 - if match { - orig := s[i : i+keylen] - switch CaseStyle(orig) { - case CaseUnknown: - // pretend we didn't match - // i++ - // continue - case CaseUpper: - val = strings.ToUpper(val) - case CaseLower: - val = strings.ToLower(val) - case CaseTitle: - if len(val) < 2 { - val = strings.ToUpper(val) - } else { - val = strings.ToUpper(val[:1]) + strings.ToLower(val[1:]) - } - } - wn, err = sw.WriteString(s[last:i]) - n += wn - if err != nil { - return - } - // debug helper: log.Printf("%d: Going to correct %q with %q", i, s[i:i+keylen], val) - wn, err = sw.WriteString(val) - n += wn - if err != nil { - return - } - i += keylen - last = i - continue - } - i++ - } - if last != len(s) { - wn, err = sw.WriteString(s[last:]) - n += wn - } - return -} - -func (r *genericReplacer) lookup(s string, ignoreRoot bool) (val string, keylen int, found bool) { - // Iterate down the trie to the end, and grab the value and keylen with - // the highest priority. - bestPriority := 0 - node := &r.root - n := 0 - for node != nil { - if node.priority > bestPriority && (!ignoreRoot || node != &r.root) { - bestPriority = node.priority - val = node.value - keylen = n - found = true - } - - if s == "" { - break - } - if node.table != nil { - index := r.mapping[ByteToLower(s[0])] - if int(index) == r.tableSize { - break - } - node = node.table[index] - s = s[1:] - n++ - } else if node.prefix != "" && StringHasPrefixFold(s, node.prefix) { - n += len(node.prefix) - s = s[len(node.prefix):] - node = node.next - } else { - break - } - } - return -} - -type appendSliceWriter []byte - -// Write writes to the buffer to satisfy io.Writer. -func (w *appendSliceWriter) Write(p []byte) (int, error) { - *w = append(*w, p...) - return len(p), nil -} - -// WriteString writes to the buffer without string->[]byte->string allocations. -func (w *appendSliceWriter) WriteString(s string) (int, error) { - *w = append(*w, s...) - return len(s), nil -} - -type stringWriter struct { - w io.Writer -} - -func (w stringWriter) WriteString(s string) (int, error) { - return w.w.Write([]byte(s)) -} - -func getStringWriter(w io.Writer) io.StringWriter { - sw, ok := w.(io.StringWriter) - if !ok { - sw = stringWriter{w} - } - return sw -} diff --git a/vendor/github.com/golangci/misspell/stringreplacer_test.gox b/vendor/github.com/golangci/misspell/stringreplacer_test.gox deleted file mode 100644 index 70da997f6e..0000000000 --- a/vendor/github.com/golangci/misspell/stringreplacer_test.gox +++ /dev/null @@ -1,421 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package misspell_test - -import ( - "bytes" - "fmt" - "strings" - "testing" - - . "github.com/client9/misspell" -) - -var htmlEscaper = NewStringReplacer( - "&", "&", - "<", "<", - ">", ">", - `"`, """, - "'", "'", -) - -var htmlUnescaper = NewStringReplacer( - "&", "&", - "<", "<", - ">", ">", - """, `"`, - "'", "'", -) - -// The http package's old HTML escaping function. -func oldHTMLEscape(s string) string { - s = strings.Replace(s, "&", "&", -1) - s = strings.Replace(s, "<", "<", -1) - s = strings.Replace(s, ">", ">", -1) - s = strings.Replace(s, `"`, """, -1) - s = strings.Replace(s, "'", "'", -1) - return s -} - -var capitalLetters = NewStringReplacer("a", "A", "b", "B") - -// TestReplacer tests the replacer implementations. -func TestReplacer(t *testing.T) { - type testCase struct { - r *StringReplacer - in, out string - } - var testCases []testCase - - // str converts 0xff to "\xff". This isn't just string(b) since that converts to UTF-8. - str := func(b byte) string { - return string([]byte{b}) - } - var s []string - - // inc maps "\x00"->"\x01", ..., "a"->"b", "b"->"c", ..., "\xff"->"\x00". - for i := 0; i < 256; i++ { - s = append(s, str(byte(i)), str(byte(i+1))) - } - inc := NewStringReplacer(s...) - - // Test cases with 1-byte old strings, 1-byte new strings. - testCases = append(testCases, - testCase{capitalLetters, "brad", "BrAd"}, - testCase{capitalLetters, strings.Repeat("a", (32<<10)+123), strings.Repeat("A", (32<<10)+123)}, - testCase{capitalLetters, "", ""}, - - testCase{inc, "brad", "csbe"}, - testCase{inc, "\x00\xff", "\x01\x00"}, - testCase{inc, "", ""}, - - testCase{NewStringReplacer("a", "1", "a", "2"), "brad", "br1d"}, - ) - - // repeat maps "a"->"a", "b"->"bb", "c"->"ccc", ... - s = nil - for i := 0; i < 256; i++ { - n := i + 1 - 'a' - if n < 1 { - n = 1 - } - s = append(s, str(byte(i)), strings.Repeat(str(byte(i)), n)) - } - repeat := NewStringReplacer(s...) - - // Test cases with 1-byte old strings, variable length new strings. - testCases = append(testCases, - testCase{htmlEscaper, "No changes", "No changes"}, - testCase{htmlEscaper, "I <3 escaping & stuff", "I <3 escaping & stuff"}, - testCase{htmlEscaper, "&&&", "&&&"}, - testCase{htmlEscaper, "", ""}, - - testCase{repeat, "brad", "bbrrrrrrrrrrrrrrrrrradddd"}, - testCase{repeat, "abba", "abbbba"}, - testCase{repeat, "", ""}, - - testCase{NewStringReplacer("a", "11", "a", "22"), "brad", "br11d"}, - ) - - // The remaining test cases have variable length old strings. - - testCases = append(testCases, - testCase{htmlUnescaper, "&amp;", "&"}, - testCase{htmlUnescaper, "<b>HTML's neat</b>", "HTML's neat"}, - testCase{htmlUnescaper, "", ""}, - - testCase{NewStringReplacer("a", "1", "a", "2", "xxx", "xxx"), "brad", "br1d"}, - - testCase{NewStringReplacer("a", "1", "aa", "2", "aaa", "3"), "aaaa", "1111"}, - - testCase{NewStringReplacer("aaa", "3", "aa", "2", "a", "1"), "aaaa", "31"}, - ) - - // gen1 has multiple old strings of variable length. There is no - // overall non-empty common prefix, but some pairwise common prefixes. - gen1 := NewStringReplacer( - "aaa", "3[aaa]", - "aa", "2[aa]", - "a", "1[a]", - "i", "i", - "longerst", "most long", - "longer", "medium", - "long", "short", - "xx", "xx", - "x", "X", - "X", "Y", - "Y", "Z", - ) - testCases = append(testCases, - testCase{gen1, "fooaaabar", "foo3[aaa]b1[a]r"}, - testCase{gen1, "long, longerst, longer", "short, most long, medium"}, - testCase{gen1, "xxxxx", "xxxxX"}, - testCase{gen1, "XiX", "YiY"}, - testCase{gen1, "", ""}, - ) - - // gen2 has multiple old strings with no pairwise common prefix. - gen2 := NewStringReplacer( - "roses", "red", - "violets", "blue", - "sugar", "sweet", - ) - testCases = append(testCases, - testCase{gen2, "roses are red, violets are blue...", "red are red, blue are blue..."}, - testCase{gen2, "", ""}, - ) - - // gen3 has multiple old strings with an overall common prefix. - gen3 := NewStringReplacer( - "abracadabra", "poof", - "abracadabrakazam", "splat", - "abraham", "lincoln", - "abrasion", "scrape", - "abraham", "isaac", - ) - testCases = append(testCases, - testCase{gen3, "abracadabrakazam abraham", "poofkazam lincoln"}, - testCase{gen3, "abrasion abracad", "scrape abracad"}, - testCase{gen3, "abba abram abrasive", "abba abram abrasive"}, - testCase{gen3, "", ""}, - ) - - // foo{1,2,3,4} have multiple old strings with an overall common prefix - // and 1- or 2- byte extensions from the common prefix. - foo1 := NewStringReplacer( - "foo1", "A", - "foo2", "B", - "foo3", "C", - ) - foo2 := NewStringReplacer( - "foo1", "A", - "foo2", "B", - "foo31", "C", - "foo32", "D", - ) - foo3 := NewStringReplacer( - "foo11", "A", - "foo12", "B", - "foo31", "C", - "foo32", "D", - ) - foo4 := NewStringReplacer( - "foo12", "B", - "foo32", "D", - ) - testCases = append(testCases, - testCase{foo1, "fofoofoo12foo32oo", "fofooA2C2oo"}, - testCase{foo1, "", ""}, - - testCase{foo2, "fofoofoo12foo32oo", "fofooA2Doo"}, - testCase{foo2, "", ""}, - - testCase{foo3, "fofoofoo12foo32oo", "fofooBDoo"}, - testCase{foo3, "", ""}, - - testCase{foo4, "fofoofoo12foo32oo", "fofooBDoo"}, - testCase{foo4, "", ""}, - ) - - // genAll maps "\x00\x01\x02...\xfe\xff" to "[all]", amongst other things. - allBytes := make([]byte, 256) - for i := range allBytes { - allBytes[i] = byte(i) - } - allString := string(allBytes) - genAll := NewStringReplacer( - allString, "[all]", - "\xff", "[ff]", - "\x00", "[00]", - ) - testCases = append(testCases, - testCase{genAll, allString, "[all]"}, - testCase{genAll, "a\xff" + allString + "\x00", "a[ff][all][00]"}, - testCase{genAll, "", ""}, - ) - - // Test cases with empty old strings. - - blankToX1 := NewStringReplacer("", "X") - blankToX2 := NewStringReplacer("", "X", "", "") - blankHighPriority := NewStringReplacer("", "X", "o", "O") - blankLowPriority := NewStringReplacer("o", "O", "", "X") - blankNoOp1 := NewStringReplacer("", "") - blankNoOp2 := NewStringReplacer("", "", "", "A") - blankFoo := NewStringReplacer("", "X", "foobar", "R", "foobaz", "Z") - testCases = append(testCases, - testCase{blankToX1, "foo", "XfXoXoX"}, - testCase{blankToX1, "", "X"}, - - testCase{blankToX2, "foo", "XfXoXoX"}, - testCase{blankToX2, "", "X"}, - - testCase{blankHighPriority, "oo", "XOXOX"}, - testCase{blankHighPriority, "ii", "XiXiX"}, - testCase{blankHighPriority, "oiio", "XOXiXiXOX"}, - testCase{blankHighPriority, "iooi", "XiXOXOXiX"}, - testCase{blankHighPriority, "", "X"}, - - testCase{blankLowPriority, "oo", "OOX"}, - testCase{blankLowPriority, "ii", "XiXiX"}, - testCase{blankLowPriority, "oiio", "OXiXiOX"}, - testCase{blankLowPriority, "iooi", "XiOOXiX"}, - testCase{blankLowPriority, "", "X"}, - - testCase{blankNoOp1, "foo", "foo"}, - testCase{blankNoOp1, "", ""}, - - testCase{blankNoOp2, "foo", "foo"}, - testCase{blankNoOp2, "", ""}, - - testCase{blankFoo, "foobarfoobaz", "XRXZX"}, - testCase{blankFoo, "foobar-foobaz", "XRX-XZX"}, - testCase{blankFoo, "", "X"}, - ) - - // single string replacer - - abcMatcher := NewStringReplacer("abc", "[match]") - - testCases = append(testCases, - testCase{abcMatcher, "", ""}, - testCase{abcMatcher, "ab", "ab"}, - testCase{abcMatcher, "abc", "[match]"}, - testCase{abcMatcher, "abcd", "[match]d"}, - testCase{abcMatcher, "cabcabcdabca", "c[match][match]d[match]a"}, - ) - - // Issue 6659 cases (more single string replacer) - - noHello := NewStringReplacer("Hello", "") - testCases = append(testCases, - testCase{noHello, "Hello", ""}, - testCase{noHello, "Hellox", "x"}, - testCase{noHello, "xHello", "x"}, - testCase{noHello, "xHellox", "xx"}, - ) - - // No-arg test cases. - - nop := NewStringReplacer() - testCases = append(testCases, - testCase{nop, "abc", "abc"}, - testCase{nop, "", ""}, - ) - - // Run the test cases. - - for i, tc := range testCases { - if s := tc.r.Replace(tc.in); s != tc.out { - t.Errorf("%d. strings.Replace(%q) = %q, want %q", i, tc.in, s, tc.out) - } - var buf bytes.Buffer - n, err := tc.r.WriteString(&buf, tc.in) - if err != nil { - t.Errorf("%d. WriteString: %v", i, err) - continue - } - got := buf.String() - if got != tc.out { - t.Errorf("%d. WriteString(%q) wrote %q, want %q", i, tc.in, got, tc.out) - continue - } - if n != len(tc.out) { - t.Errorf("%d. WriteString(%q) wrote correct string but reported %d bytes; want %d (%q)", - i, tc.in, n, len(tc.out), tc.out) - } - } -} - -type errWriter struct{} - -func (errWriter) Write(p []byte) (n int, err error) { - return 0, fmt.Errorf("unwritable") -} - -func BenchmarkGenericNoMatch(b *testing.B) { - str := strings.Repeat("A", 100) + strings.Repeat("B", 100) - generic := NewStringReplacer("a", "A", "b", "B", "12", "123") // varying lengths forces generic - for i := 0; i < b.N; i++ { - generic.Replace(str) - } -} - -func BenchmarkGenericMatch1(b *testing.B) { - str := strings.Repeat("a", 100) + strings.Repeat("b", 100) - generic := NewStringReplacer("a", "A", "b", "B", "12", "123") - for i := 0; i < b.N; i++ { - generic.Replace(str) - } -} - -func BenchmarkGenericMatch2(b *testing.B) { - str := strings.Repeat("It's <b>HTML</b>!", 100) - for i := 0; i < b.N; i++ { - htmlUnescaper.Replace(str) - } -} - -func benchmarkSingleString(b *testing.B, pattern, text string) { - r := NewStringReplacer(pattern, "[match]") - b.SetBytes(int64(len(text))) - b.ResetTimer() - for i := 0; i < b.N; i++ { - r.Replace(text) - } -} - -func BenchmarkSingleMaxSkipping(b *testing.B) { - benchmarkSingleString(b, strings.Repeat("b", 25), strings.Repeat("a", 10000)) -} - -func BenchmarkSingleLongSuffixFail(b *testing.B) { - benchmarkSingleString(b, "b"+strings.Repeat("a", 500), strings.Repeat("a", 1002)) -} - -func BenchmarkSingleMatch(b *testing.B) { - benchmarkSingleString(b, "abcdef", strings.Repeat("abcdefghijklmno", 1000)) -} - -func BenchmarkByteByteNoMatch(b *testing.B) { - str := strings.Repeat("A", 100) + strings.Repeat("B", 100) - for i := 0; i < b.N; i++ { - capitalLetters.Replace(str) - } -} - -func BenchmarkByteByteMatch(b *testing.B) { - str := strings.Repeat("a", 100) + strings.Repeat("b", 100) - for i := 0; i < b.N; i++ { - capitalLetters.Replace(str) - } -} - -func BenchmarkByteStringMatch(b *testing.B) { - str := "<" + strings.Repeat("a", 99) + strings.Repeat("b", 99) + ">" - for i := 0; i < b.N; i++ { - htmlEscaper.Replace(str) - } -} - -func BenchmarkHTMLEscapeNew(b *testing.B) { - str := "I <3 to escape HTML & other text too." - for i := 0; i < b.N; i++ { - htmlEscaper.Replace(str) - } -} - -func BenchmarkHTMLEscapeOld(b *testing.B) { - str := "I <3 to escape HTML & other text too." - for i := 0; i < b.N; i++ { - oldHTMLEscape(str) - } -} - -func BenchmarkByteStringReplacerWriteString(b *testing.B) { - str := strings.Repeat("I <3 to escape HTML & other text too.", 100) - buf := new(bytes.Buffer) - for i := 0; i < b.N; i++ { - htmlEscaper.WriteString(buf, str) - buf.Reset() - } -} - -func BenchmarkByteReplacerWriteString(b *testing.B) { - str := strings.Repeat("abcdefghijklmnopqrstuvwxyz", 100) - buf := new(bytes.Buffer) - for i := 0; i < b.N; i++ { - capitalLetters.WriteString(buf, str) - buf.Reset() - } -} - -// BenchmarkByteByteReplaces compares byteByteImpl against multiple Replaces. -func BenchmarkByteByteReplaces(b *testing.B) { - str := strings.Repeat("a", 100) + strings.Repeat("b", 100) - for i := 0; i < b.N; i++ { - strings.Replace(strings.Replace(str, "a", "A", -1), "b", "B", -1) - } -} diff --git a/vendor/github.com/golangci/misspell/url.go b/vendor/github.com/golangci/misspell/url.go deleted file mode 100644 index a91d1d967d..0000000000 --- a/vendor/github.com/golangci/misspell/url.go +++ /dev/null @@ -1,18 +0,0 @@ -package misspell - -import ( - "regexp" -) - -// Regexp for URL https://mathiasbynens.be/demo/url-regex -// -// original @imme_emosol (54 chars) has trouble with dashes in hostname -// @(https?|ftp)://(-\.)?([^\s/?\.#-]+\.?)+(/[^\s]*)?$@iS. -var reURL = regexp.MustCompile(`(?i)(https?|ftp)://(-\.)?([^\s/?.#]+\.?)+(/\S*)?`) - -// StripURL attempts to replace URLs with blank spaces, e.g. -// -// "xxx http://foo.com/ yyy -> "xxx yyyy". -func StripURL(s string) string { - return reURL.ReplaceAllStringFunc(s, replaceWithBlanks) -} diff --git a/vendor/github.com/golangci/misspell/words.go b/vendor/github.com/golangci/misspell/words.go deleted file mode 100644 index 64bfd88e5d..0000000000 --- a/vendor/github.com/golangci/misspell/words.go +++ /dev/null @@ -1,28101 +0,0 @@ -// Code generated by 'internal/gen'. DO NOT EDIT. - -package misspell - -// DictMain is the main rule set, not including locale-specific spellings -var DictMain = []string{ - "differentiatiations", "differentiations", - "disproportionaltely", "disproportionately", - "oversimplificiation", "oversimplification", - "transcendentational", "transcendental", - "anthromorphization", "anthropomorphization", - "disporportionately", "disproportionately", - "dispraportionately", "disproportionately", - "disproportianately", "disproportionately", - "disproportionatley", "disproportionately", - "disproprotionately", "disproportionately", - "fundamentalistisch", "fundamentalists", - "fundamentalistiska", "fundamentalists", - "fundamentalistiske", "fundamentalists", - "fundamentalistiskt", "fundamentalists", - "histocompatability", "histocompatibility", - "microtransacations", "microtransactions", - "microtransacciones", "microtransactions", - "microtransactional", "microtransactions", - "microtransactioned", "microtransactions", - "misunderstandingly", "misunderstandings", - "oversemplification", "oversimplification", - "oversimplifacation", "oversimplification", - "oversimplificaiton", "oversimplification", - "oversimplificating", "oversimplification", - "oversimplyfication", "oversimplification", - "cardiovasculaires", "cardiovascular", - "certificationkits", "certifications", - "counterporductive", "counterproductive", - "coutnerproductive", "counterproductive", - "disporportionatly", "disproportionately", - "disproportiantely", "disproportionately", - "disproportionatly", "disproportionately", - "disproportionnate", "disproportionate", - "disrepresentation", "misrepresentation", - "fundamentalistisk", "fundamentalists", - "incompatabilities", "incompatibilities", - "inconsequentional", "inconsequential", - "indistinguishible", "indistinguishable", - "indistingusihable", "indistinguishable", - "indistinquishable", "indistinguishable", - "indistuingishable", "indistinguishable", - "instatutionalized", "institutionalized", - "institucionalized", "institutionalized", - "institutionilized", "institutionalized", - "instutitionalized", "institutionalized", - "instututionalized", "institutionalized", - "interchangeablely", "interchangeably", - "interchangeablity", "interchangeably", - "intercontinential", "intercontinental", - "micortransactions", "microtransactions", - "microstansactions", "microtransactions", - "microtramsactions", "microtransactions", - "microtranasctions", "microtransactions", - "microtransacitons", "microtransactions", - "microtransacrions", "microtransactions", - "microtransactioms", "microtransactions", - "microtransactiosn", "microtransactions", - "microtranscations", "microtransactions", - "microtrasnactions", "microtransactions", - "mircotransactions", "microtransactions", - "misinterpretating", "misinterpreting", - "misrepresantation", "misrepresentation", - "misrepresentaiton", "misrepresentation", - "misrepresentating", "misrepresenting", - "misunderstantings", "misunderstandings", - "mocrotransactions", "microtransactions", - "oversimplifaction", "oversimplification", - "oversimplificaton", "oversimplification", - "oversimplifiction", "oversimplification", - "responsibillities", "responsibilities", - "unconstitutionnal", "unconstitutional", - "accomplishements", "accomplishments", - "admininistrative", "administrative", - "antidepresssants", "antidepressants", - "architechturally", "architecturally", - "cardiovasculaire", "cardiovascular", - "charactarization", "characterization", - "characterazation", "characterization", - "characterisitics", "characteristics", - "characteristsics", "characteristic", - "characterizarion", "characterization", - "charecterization", "characterization", - "charicterization", "characterization", - "circumstantional", "circumstantial", - "conversationable", "conversational", - "counterprodutive", "counterproductive", - "demonstrationens", "demonstrations", - "deterministische", "deterministic", - "differenciations", "differentiation", - "differentiantion", "differentiation", - "differentiatiors", "differentiation", - "differentitation", "differentiation", - "disperportionate", "disproportionate", - "disporportionate", "disproportionate", - "dispraportionate", "disproportionate", - "disproportianate", "disproportionate", - "disproportionaly", "disproportionately", - "disproprotionate", "disproportionate", - "electromagnectic", "electromagnetic", - "enviornmentalist", "environmentalist", - "environmentality", "environmentally", - "extraordinairily", "extraordinarily", - "extraordinarilly", "extraordinary", - "extraterrestials", "extraterrestrials", - "fundamentalismos", "fundamentalists", - "fundamentalismus", "fundamentalists", - "fundamentalistas", "fundamentalists", - "fundamentalisten", "fundamentalists", - "fundamentalister", "fundamentalists", - "imcomprehensible", "incomprehensible", - "immunosupressant", "immunosuppressant", - "imperfectionists", "imperfections", - "implementaciones", "implementations", - "implementationen", "implementations", - "implementationer", "implementations", - "inappropriatelly", "inappropriately", - "incompatablities", "incompatibilities", - "incompatiblities", "incompatibilities", - "incomprehencible", "incomprehensible", - "incomprehendible", "incomprehensible", - "incomprehenisble", "incomprehensible", - "incomprehensable", "incomprehensible", - "incomprehinsible", "incomprehensible", - "incomprihensible", "incomprehensible", - "inconprehensible", "incomprehensible", - "inconsistentcies", "inconsistencies", - "inconstitutional", "unconstitutional", - "incrompehensible", "incomprehensible", - "indistinguisable", "indistinguishable", - "institutionlized", "institutionalized", - "intellectualiser", "intellectuals", - "intellectualisme", "intellectuals", - "interchangeabley", "interchangeably", - "internationnally", "internationally", - "interpretaciones", "interpretations", - "interpretationen", "interpretations", - "manoeuverability", "maneuverability", - "massachusettians", "massachusetts", - "microtransacions", "microtransactions", - "microtransacting", "microtransactions", - "microtransactios", "microtransactions", - "microtransactons", "microtransactions", - "microtransations", "microtransactions", - "microtranscation", "microtransactions", - "mircotransaction", "microtransactions", - "miscommunciation", "miscommunication", - "miscommunicaiton", "miscommunication", - "miscomunnication", "miscommunication", - "miscummunication", "miscommunication", - "misinterpretated", "misinterpreted", - "misinterpretions", "misinterpreting", - "misinterpretting", "misinterpreting", - "misproportionate", "disproportionate", - "misrepresenation", "misrepresentation", - "misrepresentaion", "misrepresentation", - "misrepresentated", "misrepresented", - "misrepresentatie", "misrepresentation", - "misrepresentativ", "misrepresentation", - "misubderstanding", "misunderstandings", - "misudnerstanding", "misunderstandings", - "misundarstanding", "misunderstandings", - "misunderatanding", "misunderstandings", - "misunderdtanding", "misunderstandings", - "misundersatnding", "misunderstandings", - "misundersranding", "misunderstandings", - "misunderstadings", "misunderstandings", - "misunderstadning", "misunderstandings", - "misunderstamding", "misunderstandings", - "misunderstandigs", "misunderstandings", - "misunderstandimg", "misunderstandings", - "misunderstandind", "misunderstandings", - "misunderstanging", "misunderstandings", - "misunderstanidng", "misunderstandings", - "misunderstanings", "misunderstandings", - "misunderstansing", "misunderstandings", - "misunderstanting", "misunderstandings", - "misunderstending", "misunderstandings", - "misunderstnading", "misunderstandings", - "misunderstsnding", "misunderstandings", - "misunderstunding", "misunderstandings", - "misundertsanding", "misunderstandings", - "misundrestanding", "misunderstandings", - "misunterstanding", "misunderstandings", - "nationalistische", "nationalistic", - "nationalististic", "nationalistic", - "neconstitutional", "unconstitutional", - "notwhithstanding", "notwithstanding", - "objectificiation", "objectification", - "organisationnels", "organisations", - "perpendiculaires", "perpendicular", - "phillosophically", "philosophically", - "preinitalization", "preinitialization", - "prescriptionists", "prescriptions", - "procrastinarting", "procrastinating", - "procrastinationg", "procrastinating", - "procrastinazione", "procrastination", - "professionalisim", "professionalism", - "professionalisme", "professionals", - "professionallism", "professionalism", - "professionnalism", "professionalism", - "programattically", "programmatically", - "proportionallity", "proportionally", - "reaponsibilities", "responsibilities", - "reinitalizations", "reinitializations", - "representaciones", "representations", - "representationen", "representations", - "representationer", "representations", - "repsonsibilities", "responsibilities", - "responcibilities", "responsibilities", - "responisbilities", "responsibilities", - "responsabilities", "responsibilities", - "responsebilities", "responsibilities", - "straightforeward", "straightforward", - "surrepetitiously", "surreptitiously", - "technologicially", "technologically", - "unconditionnally", "unconditionally", - "unconfortability", "discomfort", - "unconstititional", "unconstitutional", - "uncontrollablely", "uncontrollably", - "underestimateing", "underestimating", - "understandablely", "understandably", - "unintentionnally", "unintentionally", - "unsubstantianted", "unsubstantiated", - "unsubstantiative", "unsubstantiated", - "acclimitization", "acclimatization", - "accomplishemnts", "accomplishments", - "accountabillity", "accountability", - "acknolwedgement", "acknowledgement", - "acknoweldgement", "acknowledgement", - "acknowldegement", "acknowledgement", - "acknowlegdement", "acknowledgement", - "administratieve", "administrative", - "administratiors", "administrators", - "administrativne", "administrative", - "aforementionned", "aforementioned", - "anitdepressants", "antidepressants", - "antidepressents", "antidepressants", - "archetecturally", "architecturally", - "associationthis", "associations", - "authobiographic", "autobiographic", - "awknowledgement", "acknowledgement", - "bureaucratische", "bureaucratic", - "cardiovascualar", "cardiovascular", - "carnagie-mellon", "carnegie-mellon", - "carnigie-mellon", "carnegie-mellon", - "celebrationists", "celebrations", - "charactaristics", "characteristics", - "characterisitcs", "characteristics", - "characterisitic", "characteristic", - "characterizaton", "characterization", - "charactersistic", "characteristic", - "charactersitics", "characteristics", - "charactoristics", "characteristics", - "charecteristics", "characteristics", - "comfrontational", "confrontational", - "commuinications", "communications", - "compatabilities", "compatibilities", - "complimentarity", "complimentary", - "compositionwise", "compositions", - "confidenciality", "confidential", - "confidentuality", "confidential", - "confrentational", "confrontational", - "confrontacional", "confrontational", - "conglaturations", "congratulations", - "congradulations", "congratulations", - "congragulations", "congratulations", - "congratualtions", "congratulations", - "congraturations", "congratulations", - "consequentually", "consequently", - "constitutionnal", "constitutional", - "deinitalization", "deinitialization", - "denominationals", "denominations", - "destinationhash", "destinations", - "deterministisch", "deterministic", - "developmentwise", "developments", - "differantiation", "differentiation", - "differenciation", "differentiation", - "differientation", "differentiation", - "discriminatoire", "discriminate", - "discriminatorie", "discriminate", - "disproportiante", "disproportionate", - "disproportinate", "disproportionate", - "elecrtomagnetic", "electromagnetic", - "electormagnetic", "electromagnetic", - "electromagentic", "electromagnetic", - "electromagnatic", "electromagnetic", - "electromangetic", "electromagnetic", - "electromegnetic", "electromagnetic", - "electronagnetic", "electromagnetic", - "enivronmentally", "environmentally", - "entrepreneurers", "entrepreneurs", - "enviornmentally", "environmentally", - "enviromentalist", "environmentalist", - "environemntally", "environmentally", - "envrionmentally", "environmentally", - "evolutionarilly", "evolutionary", - "experementation", "experimentation", - "experimantation", "experimentation", - "experimentacion", "experimentation", - "experimentating", "experimentation", - "experimenterade", "experimented", - "experimintation", "experimentation", - "expirementation", "experimentation", - "extraodrinarily", "extraordinarily", - "extraordinairly", "extraordinarily", - "extraordinarely", "extraordinarily", - "extraordinaryly", "extraordinarily", - "extraterrestial", "extraterrestrial", - "extroardinarily", "extraordinarily", - "fondamentalists", "fundamentalists", - "fundamendalists", "fundamentalists", - "fundamentalisme", "fundamentals", - "fundamentalismo", "fundamentals", - "fundamentalista", "fundamentals", - "fundamentalisti", "fundamentals", - "fundamnetalists", "fundamentalists", - "fundemantalists", "fundamentalists", - "fundimentalists", "fundamentalists", - "fundumentalists", "fundamentalists", - "gongratulations", "congratulations", - "grammaticallity", "grammatically", - "gundamentalists", "fundamentalists", - "idiosynchracies", "idiosyncrasies", - "implementaitons", "implementations", - "implimentations", "implementations", - "inapporpriately", "inappropriately", - "inappropraitely", "inappropriately", - "inappropriatley", "inappropriately", - "incompatability", "incompatibility", - "incompetentence", "incompetence", - "incomprehensibe", "incomprehensible", - "incomprehesible", "incomprehensible", - "inconcequential", "inconsequential", - "inconcistencies", "inconsistencies", - "inconditionally", "unconditionally", - "inconsecuential", "inconsequential", - "inconsequantial", "inconsequential", - "inconsequencial", "inconsequential", - "inconsequentual", "inconsequential", - "inconsiquential", "inconsequential", - "inconsistancies", "inconsistencies", - "inconsistencias", "inconsistencies", - "inconsistensies", "inconsistencies", - "inconsistenties", "inconsistencies", - "independentisme", "independents", - "independentiste", "independents", - "independentness", "independents", - "inexperiencable", "inexperience", - "inplementations", "implementations", - "instantaneoulsy", "instantaneous", - "institutionella", "institutional", - "institutionnels", "institutions", - "instutionalized", "institutionalized", - "insubstantiated", "unsubstantiated", - "interchangabley", "interchangeably", - "interchangebale", "interchangeable", - "intercontinetal", "intercontinental", - "interpertations", "interpretations", - "interpratations", "interpretations", - "interpritations", "interpretations", - "intersectionals", "intersections", - "intrepretations", "interpretations", - "investigationes", "investigations", - "journalistische", "journalistic", - "libertarianisim", "libertarianism", - "libertarianisme", "libertarians", - "libertarianismo", "libertarians", - "libertarianists", "libertarians", - "libertariansism", "libertarianism", - "manisfestations", "manifestations", - "manouverability", "maneuverability", - "manufacturerers", "manufacturers", - "marshmallowiest", "marshmallows", - "marshmallowness", "marshmallows", - "microtransacton", "microtransactions", - "mininterpreting", "misinterpreting", - "miscommuniation", "miscommunication", - "miscommunicatie", "miscommunication", - "miscommuniction", "miscommunication", - "misinterperting", "misinterpreting", - "misinterprating", "misinterpreting", - "misinterprented", "misinterpret", - "misinterprested", "misinterpret", - "misinterpretion", "misinterpreting", - "misinterpretted", "misinterpreted", - "misinterpriting", "misinterpreting", - "misintrepreting", "misinterpreting", - "misrepresention", "misrepresenting", - "misunderstading", "misunderstanding", - "misunderstandig", "misunderstandings", - "misunderstandng", "misunderstandings", - "misunderstaning", "misunderstanding", - "multicultralism", "multiculturalism", - "multinationella", "multinational", - "nationalistisch", "nationalists", - "nationalistisen", "nationalists", - "nationalistiska", "nationalists", - "nationalistiske", "nationalists", - "nationalistiskt", "nationalists", - "nationalistista", "nationalists", - "objectificaiton", "objectification", - "objectivication", "objectification", - "organisationens", "organisations", - "organisationers", "organisations", - "overestimateing", "overestimating", - "paychologically", "psychologically", - "performancetest", "performances", - "performancewise", "performances", - "perpendiculaire", "perpendicular", - "pharamceuticals", "pharmaceutical", - "pharmacueticals", "pharmaceutical", - "philoshopically", "philosophically", - "philosohpically", "philosophically", - "philosophycally", "philosophically", - "phsycologically", "psychologically", - "phychologically", "psychologically", - "phylosophically", "philosophically", - "physcologically", "psychologically", - "precrastination", "procrastination", - "prefessionalism", "professionalism", - "premonasterians", "premonstratensians", - "procastrinating", "procrastinating", - "procastrination", "procrastination", - "procrascinating", "procrastinating", - "procrastenating", "procrastinating", - "procrastiantion", "procrastination", - "procrastibating", "procrastinating", - "procrastibation", "procrastination", - "procrastonating", "procrastinating", - "procrestinating", "procrastinating", - "procrestination", "procrastination", - "professionalsim", "professionalism", - "prograstination", "procrastination", - "progressionists", "progressions", - "progressionwise", "progressions", - "prokrastination", "procrastination", - "proportionallly", "proportionally", - "proscratination", "procrastination", - "pscyhologically", "psychologically", - "pshycologically", "psychologically", - "psichologically", "psychologically", - "psychedelicious", "psychedelics", - "psychedelicness", "psychedelics", - "psycholigically", "psychologically", - "psychopathische", "psychopathic", - "pyschologically", "psychologically", - "racionalization", "rationalization", - "rationalizaiton", "rationalization", - "rationalizating", "rationalization", - "reccomendations", "recommendations", - "recommandations", "recommendations", - "recommondations", "recommendations", - "reinitalization", "reinitialization", - "repersentations", "representations", - "represantations", "representations", - "represantatives", "representatives", - "representatieve", "representative", - "representativas", "representatives", - "representetives", "representatives", - "representitives", "representatives", - "responibilities", "responsibilities", - "responsibilites", "responsibilities", - "responsibilitys", "responsibilities", - "responsibillity", "responsibility", - "responsibilties", "responsibilities", - "responsiblities", "responsibilities", - "ridiculoussness", "ridiculousness", - "saskatchewinian", "saskatchewan", - "satisfactorally", "satisfactory", - "satisfactorilly", "satisfactory", - "schizophreniiic", "schizophrenic", - "sensationalisim", "sensationalism", - "spreadsheeticus", "spreadsheets", - "starightforward", "straightforward", - "straigthforward", "straightforward", - "striaghtforward", "straightforward", - "sustainabillity", "sustainability", - "technoligically", "technologically", - "troubelshooting", "troubleshooting", - "troublehsooting", "troubleshooting", - "troubleshotting", "troubleshooting", - "trustworthyness", "trustworthiness", - "ubsubstantiated", "unsubstantiated", - "unappropriately", "inappropriately", - "uncomfortablely", "uncomfortably", - "uncomfortablity", "uncomfortably", - "unconditionable", "unconditional", - "unconstituional", "unconstitutional", - "uncontitutional", "unconstitutional", - "uncontrollabley", "uncontrollably", - "uncontrollablly", "uncontrollably", - "unconventionnal", "unconventional", - "underastimating", "underestimating", - "underestemating", "underestimating", - "understandabley", "understandably", - "unintensionally", "unintentionally", - "unprofessionnal", "unprofessional", - "unresponsivness", "unresponsive", - "unsibstantiated", "unsubstantiated", - "unsubstanciated", "unsubstantiated", - "unsubstansiated", "unsubstantiated", - "unsusbtantiated", "unsubstantiated", - "untranslateable", "untranslatable", - "vulernabilities", "vulnerabilities", - "vulnarabilities", "vulnerabilities", - "vulnurabilities", "vulnerabilities", - "vunlerabilities", "vulnerabilities", - "vurnerabilities", "vulnerabilities", - "accomplishemnt", "accomplishment", - "accomplishents", "accomplishes", - "acconplishment", "accomplishment", - "acknowledgeing", "acknowledging", - "acknowledgemnt", "acknowledgement", - "acomplishments", "accomplishments", - "administartion", "administration", - "administartors", "administrators", - "administraters", "administrators", - "administratief", "administrative", - "administratiei", "administrative", - "administratior", "administrator", - "administrativo", "administration", - "adminsitration", "administration", - "adminsitrative", "administrative", - "adminsitrators", "administrators", - "affectionatley", "affectionate", - "aforememtioned", "aforementioned", - "aforementioend", "aforementioned", - "alternativelly", "alternatively", - "amministrative", "administrative", - "anitdepressant", "antidepressants", - "approproximate", "approximate", - "approximatelly", "approximately", - "archeaologists", "archeologists", - "architechtures", "architectures", - "architectureal", "architectural", - "architecturial", "architectural", - "assassintation", "assassination", - "authenitcation", "authentication", - "authenticaiton", "authentication", - "authobiography", "autobiography", - "breakthroughts", "breakthroughs", - "bureaucratisch", "bureaucratic", - "calssification", "classification", - "capatilization", "capitalization", - "capitalizacion", "capitalization", - "capitalizaiton", "capitalization", - "capitalizating", "capitalization", - "capitilazation", "capitalization", - "capitolization", "capitalization", - "captialization", "capitalization", - "cardiocascular", "cardiovascular", - "cardiovascualr", "cardiovascular", - "cardiovasuclar", "cardiovascular", - "caridovascular", "cardiovascular", - "cessationalism", "sensationalism", - "cessationalist", "sensationalist", - "charactaristic", "characteristic", - "characterisics", "characteristics", - "characterisitc", "characteristics", - "characteristcs", "characteristics", - "characteritics", "characteristic", - "charactersitic", "characteristics", - "charasteristic", "characteristics", - "charecteristic", "characteristic", - "cheeseburguers", "cheeseburgers", - "cinematagraphy", "cinematography", - "cinematagrophy", "cinematography", - "cinematograhpy", "cinematography", - "cinematogrophy", "cinematography", - "cinematogrpahy", "cinematography", - "cinemetography", "cinematography", - "cinimatography", "cinematography", - "circumstansial", "circumstantial", - "circumstantual", "circumstantial", - "circumstential", "circumstantial", - "circunstantial", "circumstantial", - "classificaiton", "classification", - "coincedentally", "coincidentally", - "coinsidentally", "coincidentally", - "commemmorating", "commemorating", - "communciations", "communications", - "compatablities", "compatibilities", - "compatibillity", "compatibility", - "compatiblities", "compatibilities", - "competitioners", "competitions", - "comphrehensive", "comprehensive", - "computationnal", "computational", - "concatentation", "concatenation", - "conciderations", "considerations", - "condescenscion", "condescension", - "condradictions", "contradictions", - "configuartions", "configurations", - "confugurations", "configurations", - "conglaturation", "congratulations", - "congratulatons", "congratulations", - "conicidentally", "coincidentally", - "conifgurations", "configurations", - "conscioussness", "consciousness", - "consentrations", "concentrations", - "consiciousness", "consciousness", - "considerablely", "considerably", - "considerstions", "considerations", - "constititional", "constitutional", - "constitucional", "constitutional", - "contamporaries", "contemporaries", - "contemporaneus", "contemporaneous", - "contraceptivos", "contraceptives", - "contradicitons", "contradictions", - "contradictiong", "contradicting", - "contriceptives", "contraceptives", - "controceptives", "contraceptives", - "controdictions", "contradictions", - "conversacional", "conversational", - "converstaional", "conversational", - "correpsondence", "correspondence", - "correspondants", "correspondents", - "correspondense", "correspondence", - "correspondente", "correspondence", - "corrispondants", "correspondents", - "corrispondence", "correspondence", - "corrospondence", "correspondence", - "costumizations", "customization", - "councidentally", "coincidentally", - "crystalisation", "crystallisation", - "curcumstantial", "circumstantial", - "demenstrations", "demonstrations", - "deminstrations", "demonstrations", - "demonstartions", "demonstrations", - "demonstrativno", "demonstrations", - "demonstrativos", "demonstrations", - "demosntrations", "demonstrations", - "desintegration", "disintegration", - "deterioriating", "deteriorating", - "determinisitic", "deterministic", - "differentiaton", "differentiation", - "disatisfaction", "dissatisfaction", - "discrimanatory", "discriminatory", - "discriminacion", "discrimination", - "discriminitory", "discriminatory", - "disillusionned", "disillusioned", - "diskrimination", "discrimination", - "disproportiate", "disproportionate", - "distingiushing", "distinguishing", - "distingquished", "distinguished", - "distingusihing", "distinguishing", - "distinquishing", "distinguishing", - "distuingishing", "distinguishing", - "dysfunctionnal", "dysfunctional", - "eldistribution", "redistribution", - "electromagnetc", "electromagnetic", - "electromagntic", "electromagnetic", - "endoctrination", "indoctrination", - "enthusiastisch", "enthusiastic", - "entrepreneuers", "entrepreneurs", - "entrepreneures", "entrepreneurs", - "enviormentally", "environmentally", - "enviromentally", "environmentally", - "environmentals", "environments", - "environmentaly", "environmentally", - "experimentaion", "experimentation", - "experimentella", "experimental", - "extraordinairy", "extraordinary", - "extraordinarly", "extraordinary", - "extrordinarily", "extraordinarily", - "fondamentalist", "fundamentalist", - "foreshadowning", "foreshadowing", - "functionallity", "functionality", - "fundamendalist", "fundamentalist", - "fundamentalits", "fundamentalists", - "fundamnetalist", "fundamentalist", - "fundemantalist", "fundamentalist", - "fundimentalist", "fundamentalist", - "fundumentalist", "fundamentalist", - "generalizacion", "generalization", - "generalizating", "generalization", - "generelization", "generalization", - "geographacilly", "geographically", - "geographycally", "geographically", - "geogrpahically", "geographically", - "geopraphically", "geographically", - "goegraphically", "geographically", - "grandchilderen", "grandchildren", - "gravitationnal", "gravitational", - "groubdbreaking", "groundbreaking", - "groudnbreaking", "groundbreaking", - "hallcuinations", "hallucination", - "hallicunations", "hallucinations", - "hallucenations", "hallucinations", - "halluciantions", "hallucinations", - "hallucinaitons", "hallucination", - "hallunications", "hallucinations", - "hallusinations", "hallucinations", - "halluzinations", "hallucinations", - "hellucinations", "hallucinations", - "heterosexuella", "heterosexual", - "hipothetically", "hypothetically", - "homosexuallity", "homosexuality", - "hullucinations", "hallucinations", - "hyopthetically", "hypothetically", - "hypathetically", "hypothetically", - "hypethetically", "hypothetically", - "hypotehtically", "hypothetically", - "hypotethically", "hypothetically", - "identificacion", "identification", - "identificaiton", "identification", - "identificativo", "identification", - "identifikation", "identification", - "imlpementation", "implementations", - "impelmentation", "implementations", - "impersonationg", "impersonating", - "implementacion", "implementation", - "implementaiton", "implementation", - "implementating", "implementation", - "implementatino", "implementations", - "implemetnation", "implementations", - "implimentation", "implementation", - "impossibillity", "impossibility", - "inadvertantely", "inadvertently", - "inappropriatly", "inappropriately", - "inapproprietly", "inappropriately", - "incompatablity", "incompatibility", - "incompatiblity", "incompatibility", - "inconsequental", "inconsequential", - "inconsistentcy", "inconsistency", - "incontrollably", "uncontrollably", - "inconventional", "unconventional", - "inconvienenced", "inconvenience", - "indestrictible", "indestructible", - "indestructuble", "indestructible", - "indetification", "identification", - "indistructible", "indestructible", - "individuallity", "individuality", - "indocrtination", "indoctrination", - "indoctrication", "indoctrination", - "indoktrination", "indoctrination", - "industiralized", "industrialized", - "industrailized", "industrialized", - "industrualized", "industrialized", - "industructible", "indestructible", - "inexplicablely", "inexplicably", - "infrastracture", "infrastructure", - "infrastructuur", "infrastructure", - "infrastrucutre", "infrastructure", - "infrastrukture", "infrastructure", - "infrastrutture", "infrastructure", - "infrasturcture", "infrastructure", - "initalisations", "initialisations", - "initalizations", "initializations", - "inplementation", "implementation", - "inspirationnal", "inspirational", - "instinctivelly", "instinctively", - "institutionale", "institutionalized", - "institutionals", "institutions", - "institutionnal", "institutional", - "intellectualis", "intellectuals", - "intellectualls", "intellectuals", - "intellecutally", "intellectually", - "intercepticons", "interceptions", - "interchangable", "interchangeable", - "interchangably", "interchangeably", - "interchangeble", "interchangeable", - "interchangebly", "interchangeably", - "interlectually", "intellectually", - "internationaal", "international", - "internationaly", "internationally", - "internationnal", "international", - "interpersonnal", "interpersonal", - "interpertation", "interpretation", - "interpratation", "interpretation", - "interpretacion", "interpretation", - "interpretaiton", "interpretations", - "interpretating", "interpretation", - "interpritation", "interpretation", - "interstellaire", "interstellar", - "intillectually", "intellectually", - "intrepretation", "interpretation", - "invesitgations", "investigations", - "investiagtions", "investigations", - "investigatiors", "investigations", - "investigativos", "investigations", - "investigstions", "investigations", - "irrationallity", "irrationally", - "irresponsibile", "irresponsible", - "journalistisch", "journalistic", - "justificativos", "justifications", - "koncentrations", "concentrations", - "liberatrianism", "libertarianism", - "libertarainism", "libertarianism", - "libertariansim", "libertarianism", - "libertarinaism", "libertarianism", - "libertaryanism", "libertarianism", - "libertatianism", "libertarianism", - "liberterianism", "libertarianism", - "libretarianism", "libertarianism", - "manufactureers", "manufactures", - "manufactureras", "manufactures", - "manufacturered", "manufactured", - "manufactureres", "manufacturers", - "manufactureros", "manufactures", - "massachusettes", "massachusetts", - "massachussetts", "massachusetts", - "mataphorically", "metaphorically", - "mathameticians", "mathematicians", - "mathemagically", "mathematically", - "mathematitians", "mathematicians", - "mathemetically", "mathematically", - "mathemeticians", "mathematicians", - "mathimatically", "mathematically", - "mediterainnean", "mediterranean", - "mediterrannean", "mediterranean", - "metaphotically", "metaphorically", - "metephorically", "metaphorically", - "methaporically", "metaphorically", - "metiphorically", "metaphorically", - "metophorically", "metaphorically", - "metropolitaine", "metropolitan", - "misconseptions", "misconceptions", - "misinterperted", "misinterpreted", - "misintrepreted", "misinterpreted", - "mulitnationals", "multinational", - "mulitplication", "multiplication", - "multiplicacion", "multiplication", - "multiplicaiton", "multiplication", - "multiplicativo", "multiplication", - "multiplikation", "multiplication", - "mutlinationals", "multinational", - "mutliplication", "multiplication", - "nationalisitic", "nationalistic", - "nationalistics", "nationalists", - "nationalisties", "nationalists", - "nationalistisk", "nationalists", - "neighbourhoood", "neighbourhood", - "nieghbourhoods", "neighbourhood", - "northereastern", "northeastern", - "objectificaton", "objectification", - "opthalmologist", "ophthalmologist", - "organizacional", "organizational", - "organizaitonal", "organizational", - "organziational", "organizational", - "orginazational", "organizational", - "overestemating", "overestimating", - "overextimating", "overestimating", - "overhwelmingly", "overwhelmingly", - "overhwlemingly", "overwhelmingly", - "overpolulation", "overpopulation", - "overpopluation", "overpopulation", - "oversetimating", "overestimating", - "overshadowered", "overshadowed", - "overwhemlingly", "overwhelmingly", - "overwhlemingly", "overwhelmingly", - "paliamentarian", "parliamentarian", - "parliamentiary", "parliamentary", - "performancepcs", "performances", - "personalitites", "personalities", - "pharamceutical", "pharmaceutical", - "pharmaceudical", "pharmaceutical", - "pharmacuetical", "pharmaceutical", - "pharmaseutical", "pharmaceutical", - "pharmeceutical", "pharmaceutical", - "philosophicaly", "philosophically", - "phramaceutical", "pharmaceutical", - "playthroughers", "playthroughs", - "porportionally", "proportionally", - "practitionners", "practitioners", - "predeterminded", "predetermined", - "predominantely", "predominantly", - "predominantley", "predominantly", - "preinitalizing", "preinitializing", - "prerequisities", "prerequisite", - "procrastinatin", "procrastination", - "procrastinaton", "procrastination", - "professionials", "professionalism", - "professionnals", "professionals", - "profitabillity", "profitability", - "progressivelly", "progressively", - "progressivisme", "progressives", - "pronounciation", "pronunciation", - "proportianally", "proportionally", - "proportionalty", "proportionally", - "proportionella", "proportionally", - "proprotionally", "proportionally", - "protruberances", "protuberances", - "pseudononymous", "pseudonymous", - "psychologicaly", "psychologically", - "qaulifications", "qualification", - "qualifiactions", "qualification", - "qualificaitons", "qualifications", - "quarterbackers", "quarterbacks", - "rationalizaton", "rationalization", - "reaponsibility", "responsibility", - "recommandation", "recommendation", - "recommedations", "recommendations", - "recommondation", "recommendation", - "reconnaissence", "reconnaissance", - "reconstruccion", "reconstruction", - "reconsturction", "reconstruction", - "redistirbution", "redistribution", - "redistribucion", "redistribution", - "redistributivo", "redistribution", - "redistrubition", "redistribution", - "refridgeration", "refrigeration", - "rehabilitacion", "rehabilitation", - "rehabilitaiton", "rehabilitation", - "reinforcemnets", "reinforcements", - "rekommendation", "recommendation", - "rektifications", "certifications", - "reniforcements", "reinforcements", - "repersentation", "representation", - "represantation", "representation", - "represantative", "representative", - "representacion", "representation", - "representaiton", "representations", - "representatief", "representative", - "representating", "representation", - "representativo", "representation", - "representetive", "representative", - "representitive", "representative", - "representstion", "representations", - "representstive", "representatives", - "represetnation", "representations", - "represnetation", "representations", - "reprezentative", "representative", - "repsonsibility", "responsibility", - "resistribution", "redistribution", - "responcibility", "responsibility", - "responisbility", "responsibility", - "responnsibilty", "responsibility", - "responsability", "responsibility", - "responsibilies", "responsibilities", - "responsibities", "responsibilities", - "restaraunteurs", "restaurateurs", - "retroactivelly", "retroactively", - "revolutionairy", "revolutionary", - "revolutionnary", "revolutionary", - "ridicilousness", "ridiculousness", - "ridicoulusness", "ridiculousness", - "rienforcements", "reinforcements", - "righteoussness", "righteousness", - "satisfactoraly", "satisfactory", - "satisfactority", "satisfactorily", - "sceintifically", "scientifically", - "schizophrentic", "schizophrenic", - "screenwrighter", "screenwriter", - "sensacionalism", "sensationalism", - "sensacionalist", "sensationalist", - "sensasionalism", "sensationalism", - "sensasionalist", "sensationalist", - "sensationality", "sensationalist", - "sensationalizm", "sensationalism", - "sensationalsim", "sensationalism", - "sensationilism", "sensationalism", - "sensationilist", "sensationalist", - "sensationslism", "sensationalism", - "sensetionalism", "sensationalism", - "sensibilisiert", "sensibilities", - "sentationalism", "sensationalism", - "sentationalist", "sensationalist", - "senzationalism", "sensationalism", - "senzationalist", "sensationalist", - "sepcifications", "specification", - "simaltaneously", "simultaneously", - "simeltaneously", "simultaneously", - "similtaneously", "simultaneously", - "simlutaneously", "simultaneously", - "simplificacion", "simplification", - "simplificaiton", "simplification", - "simplificating", "simplification", - "simulatenously", "simultaneously", - "simulatneously", "simultaneously", - "simultaenously", "simultaneously", - "simultainously", "simultaneously", - "simultaneoulsy", "simultaneously", - "simultaniously", "simultaneously", - "simulteanously", "simultaneously", - "sistematically", "systematically", - "slaugterhouses", "slaughterhouses", - "specailization", "specialization", - "specialication", "specialization", - "specializaiton", "specialization", - "specificaitons", "specification", - "speciliazation", "specialization", - "spectacularely", "spectacularly", - "spectacularily", "spectacularly", - "spesifications", "specifications", - "spezialisation", "specialization", - "sportsmansship", "sportsmanship", - "spreadsheeters", "spreadsheets", - "straightforwad", "straightforward", - "subconcsiously", "subconsciously", - "subconsicously", "subconsciously", - "subsconciously", "subconsciously", - "sunconsciously", "subconsciously", - "superintendant", "superintendent", - "suppliementing", "supplementing", - "surrepetitious", "surreptitious", - "survivabililty", "survivability", - "survivabillity", "survivability", - "sustainabiltiy", "sustainability", - "syncronization", "synchronization", - "systemetically", "systematically", - "systimatically", "systematically", - "technologicaly", "technologically", - "thermodinamics", "thermodynamics", - "thermodyanmics", "thermodynamics", - "thermodymamics", "thermodynamics", - "thermodymanics", "thermodynamics", - "thermodynamcis", "thermodynamics", - "thermodynanics", "thermodynamics", - "thermodynmaics", "thermodynamics", - "thernodynamics", "thermodynamics", - "theromdynamics", "thermodynamics", - "transformacion", "transformation", - "transfromation", "transformation", - "transitionable", "transitional", - "transitionning", "transitioning", - "transofrmation", "transformation", - "trasnformation", "transformation", - "trasnportation", "transportation", - "unbelievablely", "unbelievably", - "unchallengable", "unchallengeable", - "uncomfortabley", "uncomfortably", - "uncomfortablly", "uncomfortably", - "unconciousness", "unconsciousness", - "unconditionaly", "unconditionally", - "unconditionnal", "unconditional", - "unconsciouslly", "unconsciously", - "uncontrallable", "uncontrollable", - "uncontrallably", "uncontrollably", - "uncontrolablly", "uncontrollably", - "unconvectional", "unconventional", - "unconvencional", "unconventional", - "unconvensional", "unconventional", - "unconventianal", "unconventional", - "underastimated", "underestimated", - "underestamated", "underestimated", - "underestemated", "underestimated", - "underestimeted", "underestimated", - "undersetimated", "underestimated", - "understandebly", "understandably", - "understandible", "understandable", - "understandibly", "understandably", - "undestructible", "indestructible", - "unforetunately", "unfortunately", - "unfortunatelly", "unfortunately", - "unfourtunately", "unfortunately", - "uninitalizable", "uninitializable", - "unintelligient", "unintelligent", - "unintentionaly", "unintentionally", - "unintentionnal", "unintentional", - "unmanouverable", "unmaneuverable", - "unneccessarily", "unnecessarily", - "unnecessarilly", "unnecessarily", - "unprecendented", "unprecedented", - "unprofessionel", "unprofessional", - "unreasonablely", "unreasonably", - "unsubstantiaed", "unsubstantiated", - "unsurprizingly", "unsurprisingly", - "vizualisations", "visualization", - "vulnerabilites", "vulnerabilities", - "vulnerabillity", "vulnerability", - "vulnerablility", "vulnerability", - "wholeheartadly", "wholeheartedly", - "wholeheartidly", "wholeheartedly", - "abbrievations", "abbreviation", - "accelleration", "acceleration", - "accomadations", "accommodations", - "accommadating", "accommodating", - "accommadation", "accommodation", - "accommidation", "accommodation", - "accomodations", "accommodations", - "accomondating", "accommodating", - "accomondation", "accommodation", - "accomplishent", "accomplishment", - "accountabilty", "accountability", - "accredidation", "accreditation", - "acknolwedging", "acknowledging", - "acknowlegding", "acknowledging", - "acomplishment", "accomplishment", - "acquaintaince", "acquaintance", - "acquaintences", "acquaintances", - "acquaintinces", "acquaintances", - "acquanitances", "acquaintance", - "acquantainces", "acquaintances", - "acquantiances", "acquaintances", - "acquiantances", "acquaintances", - "acquiantences", "acquaintances", - "adminastrator", "administrator", - "administartor", "administrator", - "administraion", "administration", - "administraron", "administrator", - "administrater", "administrator", - "administratio", "administrator", - "administraton", "administration", - "adminsitrator", "administrator", - "adminstration", "administration", - "adminstrative", "administrative", - "admissability", "admissibility", - "adnimistrator", "administrators", - "adverticement", "advertisement", - "advertisiment", "advertisement", - "advertisments", "advertisements", - "advirtisement", "advertisement", - "aestethically", "aesthetically", - "aesthatically", "aesthetically", - "aesthitically", "aesthetically", - "affectionnate", "affectionate", - "aforementiond", "aforementioned", - "agriculturual", "agricultural", - "agrumentative", "argumentative", - "alterantively", "alternatively", - "alternativets", "alternatives", - "alternativley", "alternatively", - "alternitavely", "alternatively", - "alternitively", "alternatively", - "aninteresting", "uninteresting", - "annoucnements", "announcements", - "antagonisitic", "antagonistic", - "anthropolgist", "anthropologist", - "apporpriately", "appropriately", - "apporpriation", "appropriation", - "apporximately", "approximately", - "appreciateing", "appreciating", - "appreciateive", "appreciative", - "appreciationg", "appreciating", - "appropirately", "appropriately", - "appropiration", "appropriation", - "appropraitely", "appropriately", - "appropreation", "appropriation", - "appropriatley", "appropriately", - "appropropiate", "appropriate", - "approrpiation", "appropriation", - "approxamately", "approximately", - "approxiamtely", "approximately", - "approximatley", "approximately", - "approximitely", "approximately", - "aqcuaintances", "acquaintances", - "aqquaintances", "acquaintances", - "archaelogical", "archaeological", - "archaelogists", "archaeologists", - "archeaologist", "archeologist", - "archetectural", "architectural", - "architechture", "architecture", - "architechural", "architectural", - "architectrual", "architectural", - "architecutral", "architectural", - "argumentitive", "argumentative", - "arugmentative", "argumentative", - "asethetically", "aesthetically", - "assasinations", "assassinations", - "audomoderator", "automoderator", - "australianess", "australians", - "authenticaion", "authentication", - "authenticaton", "authentication", - "autherization", "authorization", - "authoratitive", "authoritative", - "authoritatian", "authoritarian", - "authoritation", "authorization", - "authorititive", "authoritative", - "authoritorian", "authoritarian", - "authorotative", "authoritative", - "authroization", "authorization", - "automoderador", "automoderator", - "automoderater", "automoderator", - "automodorator", "automoderator", - "automoterator", "automoderator", - "autoritharian", "authoritarian", - "availabillity", "availability", - "awknowledging", "acknowledging", - "billingualism", "bilingualism", - "billionairres", "billionaire", - "borderlanders", "borderlands", - "breadtfeeding", "breastfeeding", - "breastfeading", "breastfeeding", - "breatsfeeding", "breastfeeding", - "broadacasting", "broadcasting", - "bureaucractic", "bureaucratic", - "bureaucratics", "bureaucrats", - "bureaucratius", "bureaucrats", - "californiaman", "californian", - "calrification", "clarification", - "capitalizaton", "capitalization", - "carbohdyrates", "carbohydrates", - "carbohidrates", "carbohydrates", - "carbohyrdates", "carbohydrates", - "carboyhdrates", "carbohydrates", - "carthographer", "cartographer", - "catagorically", "categorically", - "catastrophies", "catastrophe", - "catastrophize", "catastrophe", - "catigorically", "categorically", - "catterpillars", "caterpillars", - "celebrationis", "celebrations", - "ceritfication", "certifications", - "certificaiton", "certification", - "championchips", "championship", - "championshiop", "championships", - "championsship", "championships", - "chanpionships", "championships", - "charactarized", "characterized", - "characterisic", "characteristic", - "characteristc", "characteristics", - "characterists", "characteristics", - "charicterized", "characterized", - "charismatisch", "charismatic", - "checkpointusa", "checkpoints", - "cheeseburgare", "cheeseburger", - "cheeseburgler", "cheeseburger", - "cheeseburguer", "cheeseburger", - "cheezeburgers", "cheeseburgers", - "chornological", "chronological", - "chronoligical", "chronological", - "chronologicly", "chronological", - "cinematograhy", "cinematography", - "cinematograpy", "cinematography", - "circomference", "circumference", - "circumcission", "circumcision", - "circumferance", "circumference", - "circumsicions", "circumcision", - "circumstanial", "circumstantial", - "circumstantal", "circumstantial", - "circumstnaces", "circumstance", - "circunference", "circumference", - "circunstances", "circumstances", - "cirucmference", "circumference", - "cirucmstances", "circumstances", - "civilications", "civilizations", - "civilizaitons", "civilizations", - "clarificaiton", "clarification", - "clasification", "clarification", - "clerification", "clarification", - "coincidentaly", "coincidentally", - "coincidential", "coincidental", - "colaborations", "collaborations", - "collabaration", "collaboration", - "collaberation", "collaboration", - "collaberative", "collaborative", - "collaboratore", "collaborate", - "collectioners", "collections", - "collectivelly", "collectively", - "collobaration", "collaboration", - "combatibility", "compatibility", - "comeptitively", "competitively", - "comfortablely", "comfortably", - "comfortablity", "comfortably", - "comfrontation", "confrontation", - "commemerative", "commemorative", - "commericially", "commercially", - "commerorative", "commemorative", - "comminication", "communication", - "comminucation", "communications", - "commissionees", "commissions", - "commissionned", "commissioned", - "commissionner", "commissioner", - "commmemorated", "commemorated", - "commuications", "communications", - "commuincation", "communications", - "communciation", "communication", - "communiaction", "communications", - "communicaiton", "communication", - "communicatoin", "communications", - "communicatons", "communications", - "compadibility", "compatibility", - "comparativley", "comparatively", - "comparetively", "comparatively", - "comparitavely", "comparatively", - "comparitively", "comparatively", - "compatability", "compatibility", - "compatibiltiy", "compatibility", - "compeditively", "competitively", - "compensantion", "compensation", - "compensationg", "compensating", - "comperatively", "comparatively", - "comperhension", "comprehension", - "competatively", "competitively", - "competitavely", "competitively", - "competitevely", "competitively", - "competitivley", "competitively", - "competiveness", "competitiveness", - "compilcations", "complication", - "compitability", "compatibility", - "complciations", "complication", - "complecations", "complications", - "compliactions", "complication", - "complicaitons", "complication", - "complilations", "complications", - "complimentery", "complimentary", - "complimentoni", "complimenting", - "complimentory", "complimentary", - "comprehention", "comprehension", - "computacional", "computational", - "comtamination", "contamination", - "comtemplating", "contemplating", - "concatination", "contamination", - "conceivablely", "conceivably", - "concencration", "concentration", - "concenrtation", "concentrations", - "concentartion", "concentrations", - "concentracion", "concentration", - "concentraited", "concentrated", - "concentraiton", "concentrations", - "concentratons", "concentrations", - "concervatives", "conservatives", - "concideration", "consideration", - "concioussness", "consciousness", - "concnetration", "concentrations", - "concsiousness", "consciousness", - "condascending", "condescending", - "condescencion", "condescension", - "condescendion", "condescension", - "condescensing", "condescension", - "condiscending", "condescending", - "conditionning", "conditioning", - "condradicting", "contradicting", - "condradiction", "contradiction", - "condradictory", "contradictory", - "conecntration", "concentrations", - "conenctration", "concentrations", - "confidentally", "confidentially", - "configrations", "configurations", - "configruation", "configurations", - "configuartion", "configuration", - "configuracion", "configuration", - "configuraiton", "configuration", - "configuratoin", "configurations", - "configureable", "configurable", - "confrentation", "confrontation", - "confrontacion", "confrontation", - "confrontating", "confrontation", - "confrontativo", "confrontation", - "congratualted", "congratulate", - "conifguration", "configurations", - "conisderation", "considerations", - "connecticunts", "connecticut", - "connectivitiy", "connectivity", - "conpassionate", "compassionate", - "conplications", "complications", - "conplimentary", "complimentary", - "conplimenting", "complimenting", - "conprehension", "comprehension", - "consdieration", "considerations", - "consenquently", "consequently", - "consentrating", "concentrating", - "consentration", "concentration", - "consequencies", "consequence", - "consequentely", "consequently", - "consequeseces", "consequences", - "conservatisim", "conservatism", - "conservativsm", "conservatism", - "conservitives", "conservatives", - "consicousness", "consciousness", - "considerabely", "considerable", - "considerabile", "considerable", - "considerabley", "considerably", - "considerablly", "considerably", - "consideracion", "consideration", - "consideratoin", "considerations", - "considerstion", "considerations", - "considertaion", "considerations", - "consituencies", "constituencies", - "consitutional", "constitutional", - "constallation", "constellation", - "constarnation", "consternation", - "constillation", "constellation", - "constituintes", "constituents", - "constituional", "constitutional", - "constitutents", "constitutes", - "constitutinal", "constitutional", - "constructicon", "construction", - "constructieve", "constructive", - "constructiong", "constructing", - "consttruction", "construction", - "contaminacion", "contamination", - "contaminanted", "contaminated", - "contanimation", "contamination", - "contenplating", "contemplating", - "contimplating", "contemplating", - "contraceptivo", "contraception", - "contradiccion", "contradiction", - "contradicitng", "contradicting", - "contradiciton", "contradiction", - "contradictary", "contradictory", - "contradictons", "contradicts", - "contraticting", "contradicting", - "contravercial", "controversial", - "contraversial", "controversial", - "contreception", "contraception", - "contreversial", "controversial", - "contributeurs", "contributes", - "contributiors", "contributors", - "contriception", "contraception", - "contridictory", "contradictory", - "contritutions", "contributions", - "contriversial", "controversial", - "controception", "contraception", - "controdicting", "contradicting", - "controdiction", "contradiction", - "controvercial", "controversial", - "controverisal", "controversial", - "controversary", "controversy", - "controversity", "controversy", - "controvertial", "controversial", - "contstruction", "construction", - "conventionnal", "conventional", - "converastions", "conservation", - "conversationa", "conservation", - "conversationg", "conservation", - "conversationy", "conservation", - "conversatiosn", "conservation", - "conversatives", "conservatives", - "converstaions", "conversations", - "convorsations", "conversations", - "cooresponding", "corresponding", - "coorperations", "corporations", - "correctionals", "corrections", - "correpsonding", "corresponding", - "correspondant", "correspondent", - "correspondece", "correspondence", - "corresponders", "corresponds", - "corresponsing", "corresponding", - "corrispondant", "correspondent", - "corrisponding", "corresponding", - "corrosponding", "corresponding", - "costomization", "customization", - "costumization", "customization", - "counterfeight", "counterfeit", - "creationistas", "creationists", - "cricumference", "circumference", - "cringeworthey", "cringeworthy", - "cringeworthly", "cringeworthy", - "crytopgraphic", "cryptographic", - "curcumference", "circumference", - "curcumstances", "circumstances", - "custumization", "customization", - "cuztomization", "customization", - "decentraliced", "decentralized", - "decentrilized", "decentralized", - "decomissioned", "decommissioned", - "decompositing", "decomposing", - "definitivelly", "definitively", - "deinitalizing", "deinitializing", - "demenstration", "demonstration", - "democraticaly", "democratically", - "democraticlly", "democratically", - "demoninations", "denominations", - "demonstarting", "demonstrating", - "demonstartion", "demonstration", - "demonstraiton", "demonstrations", - "demonstratbly", "demonstrably", - "demonstraties", "demonstrate", - "demonstrativo", "demonstration", - "demosntrating", "demonstrating", - "demosntration", "demonstrations", - "denomenations", "denominations", - "denomonations", "denominations", - "deomnstration", "demonstrations", - "dermatalogist", "dermatologist", - "dermatolagist", "dermatologist", - "dermatoligist", "dermatologist", - "dermatologyst", "dermatologist", - "dermetologist", "dermatologist", - "dermitologist", "dermatologist", - "derpatologist", "dermatologist", - "desentralized", "decentralized", - "desillusioned", "disillusioned", - "desintegrated", "disintegrated", - "desinterested", "disinterested", - "determenation", "determination", - "determinacion", "determination", - "determinining", "determining", - "determinisitc", "deterministic", - "determinsitic", "deterministic", - "detmatologist", "dermatologist", - "developmently", "developmental", - "dezentralized", "decentralized", - "differantiate", "differentiate", - "differenciate", "differentiate", - "differintiate", "differentiate", - "diffirentiate", "differentiate", - "disadvandages", "disadvantaged", - "disadvantadge", "disadvantaged", - "disadvanteged", "disadvantaged", - "disadvanteges", "disadvantages", - "disadvatanges", "disadvantages", - "disadventaged", "disadvantaged", - "disadventages", "disadvantages", - "disallusioned", "disillusioned", - "disappearence", "disappearance", - "disappearnace", "disappearance", - "disappearring", "disappearing", - "disatvantaged", "disadvantaged", - "disatvantages", "disadvantages", - "disciplinairy", "disciplinary", - "disciplinerad", "disciplined", - "discipliniary", "disciplinary", - "disconnecters", "disconnects", - "discontinuted", "discontinued", - "discrimianted", "discriminated", - "discriminante", "discriminate", - "discriminatie", "discriminate", - "discriminatin", "discrimination", - "disillisioned", "disillusioned", - "disillutioned", "disillusioned", - "disingenuious", "disingenuous", - "disollusioned", "disillusioned", - "disrecpectful", "disrespectful", - "disrecpecting", "disrespecting", - "disrepsectful", "disrespectful", - "disrepsecting", "disrespecting", - "disresepctful", "disrespectful", - "disresepcting", "disrespecting", - "disrespection", "disrespecting", - "disrespekting", "disrespecting", - "disrispectful", "disrespectful", - "disrispecting", "disrespecting", - "dissagreement", "disagreement", - "dissapearance", "disappearance", - "dissapointted", "dissapointed", - "dissappointed", "disappointed", - "dissobediance", "disobedience", - "dissobedience", "disobedience", - "distingishing", "distinguishing", - "distinguising", "distinguishing", - "distinquished", "distinguished", - "distirbutions", "distributions", - "distiungished", "distinguished", - "distribustion", "distributions", - "distributiors", "distributors", - "distributivos", "distributions", - "distrobutions", "distributions", - "distrubitions", "distributions", - "distuingished", "distinguished", - "documantaries", "documentaries", - "documenatries", "documentaries", - "documentacion", "documentation", - "documentaires", "documentaries", - "documentaiton", "documentation", - "documentarios", "documentaries", - "documentaties", "documentaries", - "documentating", "documentation", - "documenteries", "documentaries", - "documentories", "documentaries", - "drammatically", "grammatically", - "dsyfunctional", "dysfunctional", - "dumbfoundeads", "dumbfounded", - "dusfunctional", "dysfunctional", - "dustification", "justification", - "dysfonctional", "dysfunctional", - "dysfucntional", "dysfunctional", - "dysfuncitonal", "dysfunctional", - "dysfunktional", "dysfunctional", - "easthetically", "aesthetically", - "effectiviness", "effectiveness", - "effictiveness", "effectiveness", - "effortlessely", "effortlessly", - "effortlessley", "effortlessly", - "embarrasement", "embarrassment", - "embarrasments", "embarrassment", - "embarressment", "embarrassment", - "emberrassment", "embarrassment", - "encarceration", "incarceration", - "encorporating", "incorporating", - "encyclopeadia", "encyclopedia", - "encyclopeadic", "encyclopedia", - "encyclopeedia", "encyclopedia", - "encycolpedias", "encyclopedia", - "endoctrinated", "indoctrinated", - "enlightenting", "enlightening", - "enlightnement", "enlightenment", - "enligthenment", "enlightenment", - "enteratinment", "entertainment", - "enterpreneurs", "entrepreneurs", - "enterprenuers", "entrepreneurs", - "enterpreuners", "entrepreneurs", - "entertianment", "entertainment", - "enthusiasists", "enthusiasts", - "enthusiastics", "enthusiasts", - "entrepraneurs", "entrepreneurs", - "entreprenaurs", "entrepreneurs", - "entrepreneuer", "entrepreneurs", - "entreprenours", "entrepreneurs", - "entreprenuers", "entrepreneurs", - "entreprenures", "entrepreneurs", - "entrepreuners", "entrepreneurs", - "entretainment", "entertainment", - "enviornmental", "environmental", - "environemntal", "environmental", - "environmently", "environmental", - "envolutionary", "evolutionary", - "envrionmental", "environmental", - "estabilshment", "establishments", - "establishemnt", "establishments", - "establishmnet", "establishments", - "establsihment", "establishments", - "estbalishment", "establishments", - "ethnocentricm", "ethnocentrism", - "evolutionairy", "evolutionary", - "evolutionarly", "evolutionary", - "evolutionnary", "evolutionary", - "exaggeratting", "exaggerating", - "excpetionally", "exceptionally", - "executioneers", "executioner", - "existentiella", "existential", - "expectionally", "exceptionally", - "experementing", "experimenting", - "experienceing", "experiencing", - "experimentais", "experiments", - "experimention", "experimenting", - "experimentors", "experiments", - "expirementing", "experimenting", - "expodentially", "exponentially", - "exponantially", "exponentially", - "exponencially", "exponentially", - "exponentiella", "exponential", - "extraodrinary", "extraordinary", - "extraordianry", "extraordinary", - "extraordinair", "extraordinary", - "extraordinaly", "extraordinary", - "extraoridnary", "extraordinary", - "extremeophile", "extremophile", - "extroardinary", "extraordinary", - "familiarizate", "familiarize", - "fantasitcally", "fantastically", - "fantasmically", "fantastically", - "fantistically", "fantastically", - "faptastically", "fantastically", - "figurativeley", "figuratively", - "figurativelly", "figuratively", - "frankenstiens", "frankenstein", - "frankenstined", "frankenstein", - "frankenstiner", "frankenstein", - "frankenstines", "frankenstein", - "friendzoneado", "friendzoned", - "fucntionality", "functionality", - "funcitonality", "functionality", - "functionailty", "functionality", - "fundamentalis", "fundamentals", - "fundamnetally", "fundamentally", - "fundementally", "fundamentally", - "fundimentally", "fundamentally", - "gamifications", "ramifications", - "generalizaing", "generalizing", - "generalizaton", "generalization", - "generationals", "generations", - "generationens", "generations", - "generationers", "generations", - "generationnal", "generational", - "geographicaly", "geographically", - "geographicial", "geographical", - "geometricians", "geometers", - "goreshadowing", "foreshadowing", - "governmential", "governmental", - "gradification", "gratification", - "grammarically", "grammatically", - "grandchildern", "grandchildren", - "gratificacion", "gratification", - "gratificaiton", "gratification", - "grativational", "gravitational", - "gravitacional", "gravitational", - "gravitaitonal", "gravitational", - "hallcuination", "hallucination", - "hallicunation", "hallucination", - "hallucenation", "hallucination", - "halluciantion", "hallucinations", - "hallukination", "hallucination", - "hallunication", "hallucination", - "hallusination", "hallucination", - "halluzination", "hallucination", - "heiroglyphics", "hieroglyphics", - "hellucination", "hallucination", - "highlightning", "highlighting", - "homesexuality", "homosexuality", - "homosexualtiy", "homosexuality", - "homosexulaity", "homosexuality", - "horizontallly", "horizontally", - "hullucination", "hallucination", - "hypocriticial", "hypocritical", - "hypotheticaly", "hypothetically", - "hystericallly", "hysterically", - "identificaton", "identification", - "ideoligically", "ideologically", - "ideosyncratic", "idiosyncratic", - "idiologically", "ideologically", - "illistrations", "illustrations", - "illustartions", "illustrations", - "imperfactions", "imperfections", - "impersinating", "impersonating", - "implementaion", "implementation", - "implementatin", "implementations", - "implimenation", "implementation", - "imprefections", "imperfections", - "impresonating", "impersonating", - "inaccessibile", "inaccessible", - "inadventently", "inadvertently", - "inadverdently", "inadvertently", - "inadvertantly", "inadvertently", - "inadvertendly", "inadvertently", - "inapporpriate", "inappropriate", - "inappropirate", "inappropriate", - "inappropraite", "inappropriate", - "inaproppriate", "inappropriate", - "incarcaration", "incarceration", - "incarciration", "incarceration", - "incarseration", "incarceration", - "incerceration", "incarceration", - "incidentially", "incidentally", - "incomfortable", "uncomfortable", - "incomfortably", "uncomfortably", - "incompatabile", "incompatible", - "incompatiable", "incompatible", - "incompatibile", "incompatible", - "inconciderate", "inconsiderate", - "inconcistency", "inconsistency", - "inconditional", "unconditional", - "inconsciously", "unconsciously", - "inconsiderant", "inconsiderate", - "inconsistance", "inconsistency", - "inconsistancy", "inconsistency", - "inconsistenly", "inconsistency", - "inconsistensy", "inconsistency", - "inconsistenty", "inconsistency", - "inconveinence", "inconvenience", - "inconveniance", "inconvenience", - "inconveniente", "inconvenience", - "inconvienence", "inconvenience", - "incoroporated", "incorporated", - "incorparating", "incorporating", - "incorperating", "incorporating", - "incorperation", "incorporation", - "incorruptable", "incorruptible", - "incramentally", "incrementally", - "incrementarla", "incremental", - "incrementarlo", "incremental", - "indavertently", "inadvertently", - "indefinitelly", "indefinitely", - "independantes", "independents", - "independantly", "independently", - "independendet", "independent", - "independendly", "independently", - "indepentently", "independently", - "indespensable", "indispensable", - "indespensible", "indispensable", - "indestructble", "indestructible", - "indestructibe", "indestructible", - "indictrinated", "indoctrinated", - "indipendently", "independently", - "indispensible", "indispensable", - "indivuduality", "individuality", - "indocrtinated", "indoctrinated", - "indocternated", "indoctrinated", - "indoctornated", "indoctrinated", - "indoctrinatie", "indoctrinated", - "indoctrinatin", "indoctrination", - "indoctronated", "indoctrinated", - "industrialied", "industrialized", - "industrialzed", "industrialized", - "inexeprienced", "inexperience", - "inexpeirenced", "inexperience", - "inexpereinced", "inexperienced", - "inexperianced", "inexperienced", - "inexperiecned", "inexperience", - "inexperineced", "inexperience", - "inexpierenced", "inexperienced", - "inexplicabley", "inexplicably", - "inexplicablly", "inexplicably", - "infilitration", "infiltration", - "infrastructre", "infrastructure", - "infrastrucure", "infrastructure", - "inintelligent", "unintelligent", - "ininteresting", "uninteresting", - "initalisation", "initialisation", - "initalization", "initialization", - "inperfections", "imperfections", - "inpersonating", "impersonating", - "inpossibility", "impossibility", - "inpredictable", "unpredictable", - "inresponsible", "irresponsible", - "insectiverous", "insectivorous", - "insecuritites", "insecurities", - "insiginficant", "insignificant", - "insiginifcant", "insignificant", - "insignificent", "insignificant", - "insignificunt", "insignificant", - "insignifigant", "insignificant", - "insiprational", "inspirational", - "insperational", "inspirational", - "inspiritional", "inspirational", - "inspriational", "inspirational", - "instantaenous", "instantaneous", - "instantanious", "instantaneous", - "instanteneous", "instantaneous", - "instantenious", "instantaneous", - "instincitvely", "instinctively", - "instinctivley", "instinctively", - "instititional", "institutional", - "institutionel", "institutional", - "insturmentals", "instrumental", - "instutitional", "institutional", - "insustainable", "unsustainable", - "intelelctuals", "intellectuals", - "intellectualy", "intellectually", - "intellectuels", "intellectuals", - "intellecutals", "intellectuals", - "intellegently", "intelligently", - "intelluctuals", "intellectuals", - "intepretation", "interpretation", - "intereactions", "intersections", - "interesctions", "intersections", - "interlectuals", "intellectuals", - "intermittient", "intermittent", - "intermittment", "intermittent", - "internacional", "international", - "interpersonel", "interpersonal", - "interpresonal", "interpersonal", - "interpretaion", "interpretation", - "interpretarea", "interpreter", - "interpretarem", "interpreter", - "interpretares", "interpreter", - "interpretarse", "interpreter", - "interpretarte", "interpreter", - "interpretatin", "interpretations", - "interpreteert", "interpreter", - "interragation", "interrogation", - "interregation", "interrogation", - "interrigation", "interrogation", - "interrogacion", "interrogation", - "interrogativo", "interrogation", - "intertainment", "entertainment", - "intillectuals", "intellectuals", - "intraspection", "introspection", - "intrensically", "intrinsically", - "intriniscally", "intrinsically", - "intrinsecally", "intrinsically", - "intrisincally", "intrinsically", - "intristically", "intrinsically", - "introductiory", "introductory", - "introspeccion", "introspection", - "introspectivo", "introspection", - "introspektion", "introspection", - "invertibrates", "invertebrates", - "invesitgation", "investigation", - "invesitgative", "investigative", - "invesitgators", "investigators", - "investagators", "investigators", - "investegating", "investigating", - "investegators", "investigators", - "investiagtion", "investigation", - "investiagtive", "investigative", - "investigacion", "investigation", - "investigaiton", "investigations", - "investigaters", "investigators", - "investigativo", "investigation", - "investigatons", "investigations", - "investigsting", "investigating", - "investigstion", "investigations", - "investogators", "investigators", - "invisibillity", "invisibility", - "involuntarely", "involuntary", - "involuntarity", "involuntary", - "invulnerabile", "invulnerable", - "irrationallly", "irrationally", - "irresponcible", "irresponsible", - "irresponisble", "irresponsible", - "irresponsable", "irresponsible", - "irresponsbile", "irresponsible", - "irreversiable", "irreversible", - "irreversibelt", "irreversible", - "irreversibile", "irreversible", - "irrisponsible", "irresponsible", - "jacksonvillle", "jacksonville", - "journalisitic", "journalistic", - "journalistens", "journalists", - "journalisters", "journalists", - "journalistisk", "journalists", - "jsutification", "justifications", - "jurisdicitons", "jurisdictions", - "jurisidctions", "jurisdictions", - "juristictions", "jurisdictions", - "jursidictions", "jurisdictions", - "jusitfication", "justifications", - "justifiaction", "justifications", - "justificacion", "justification", - "justificaiton", "justification", - "justificativo", "justification", - "justificatons", "justifications", - "justificstion", "justifications", - "justiifcation", "justifications", - "karbohydrates", "carbohydrates", - "knoweldgeable", "knowledgeable", - "knowledegable", "knowledgeable", - "knowledgebale", "knowledgable", - "knowlegdeable", "knowledgeable", - "kollaboration", "collaboration", - "koncentration", "concentration", - "konfiguration", "configuration", - "konfrontation", "confrontation", - "konservatives", "conservatives", - "konstellation", "constellation", - "kontamination", "contamination", - "legitimatelly", "legitimately", - "libertariaism", "libertarianism", - "libertariansm", "libertarianism", - "libitarianisn", "libertarianism", - "lighthearthed", "lighthearted", - "mainfestation", "manifestation", - "manafacturers", "manufacturers", - "manafacturing", "manufacturing", - "manafestation", "manifestation", - "manefestation", "manifestation", - "manfuacturers", "manufactures", - "manifacturers", "manufacturers", - "manifacturing", "manufacturing", - "manifastation", "manifestation", - "manifestacion", "manifestation", - "manifestating", "manifestation", - "manifistation", "manifestation", - "manipulationg", "manipulating", - "manufacterers", "manufacturers", - "manufactering", "manufacturing", - "manufacterurs", "manufactures", - "manufactorers", "manufacturers", - "manufactoring", "manufacturing", - "manufactuered", "manufactured", - "manufactuerer", "manufacturer", - "manufactueres", "manufactures", - "manufacturedd", "manufactured", - "manufactureds", "manufactures", - "manufacturerd", "manufactured", - "manufacturier", "manufacturer", - "manufacturors", "manufacturers", - "manufactuters", "manufactures", - "manufacutrers", "manufactures", - "manufcaturers", "manufactures", - "marshmalllows", "marshmallows", - "massachsuetts", "massachusetts", - "massachucetts", "massachusetts", - "massachuestts", "massachusetts", - "massachusents", "massachusetts", - "massachusites", "massachusetts", - "massachussets", "massachusetts", - "massechusetts", "massachusetts", - "masturbateing", "masturbating", - "materialisimo", "materialism", - "mathamatician", "mathematician", - "mathametician", "mathematician", - "mathematicals", "mathematics", - "mathematicaly", "mathematically", - "mathematicans", "mathematics", - "mathematicion", "mathematician", - "mathematitian", "mathematician", - "mathemetician", "mathematician", - "mathmatically", "mathematically", - "mathmaticians", "mathematicians", - "mechanicallly", "mechanically", - "medeterranean", "mediterranean", - "meditarrenean", "mediterranean", - "meditereanean", "mediterranean", - "membranaphone", "membranophone", - "metamorphysis", "metamorphosis", - "metaphoricaly", "metaphorically", - "metaphoricial", "metaphorical", - "metaphysicals", "metaphysics", - "metaphysicans", "metaphysics", - "methamatician", "mathematician", - "methematician", "mathematician", - "metropolitain", "metropolitan", - "metropolitcan", "metropolitan", - "metropolitian", "metropolitan", - "millionairres", "millionaire", - "minneapolites", "minneapolis", - "misanderstood", "misunderstood", - "miscellanious", "miscellaneous", - "misconcpetion", "misconceptions", - "misconecption", "misconceptions", - "misinterperet", "misinterpret", - "misinterprate", "misinterpret", - "misinterprent", "misinterpret", - "misinterprted", "misinterpret", - "misogynisitic", "misogynistic", - "misrepreseted", "misrepresented", - "misunterstood", "misunderstood", - "modificaitons", "modifications", - "motivationals", "motivations", - "motivationnal", "motivational", - "mulitnational", "multinational", - "multimational", "multinational", - "multiplicaton", "multiplication", - "muncipalities", "municipalities", - "munnicipality", "municipality", - "mutlinational", "multinational", - "nacionalistic", "nationalistic", - "narcissisitic", "narcissistic", - "narcississtic", "narcissistic", - "natioanlistic", "nationalistic", - "nationalisitc", "nationalistic", - "nationalistes", "nationalists", - "nationalsitic", "nationalistic", - "neigbhourhood", "neighbourhood", - "neighboorhoud", "neighbourhood", - "neighborehood", "neighbourhood", - "neighborhoood", "neighborhoods", - "neighbourbood", "neighbourhood", - "neighbourgood", "neighbourhood", - "neighbourhoud", "neighbourhood", - "neighourhoods", "neighborhoods", - "nieghborhoods", "neighborhoods", - "nieghbourhood", "neighbourhood", - "noncombatents", "noncombatants", - "noninitalized", "noninitialized", - "northwestener", "northwestern", - "notificaitons", "notifications", - "occassionally", "occasionally", - "operationable", "operational", - "oppertunities", "opportunities", - "opprotunities", "opportunities", - "oppurtunities", "opportunities", - "opthamologist", "ophthalmologist", - "organistaions", "organisations", - "organizatinal", "organizational", - "organizativos", "organizations", - "organsiations", "organisations", - "organziations", "organizations", - "orginasations", "organisations", - "orginazations", "organizations", - "overpopulaton", "overpopulation", - "overreactiong", "overreacting", - "overshaddowed", "overshadowed", - "overwheliming", "overwhelming", - "overwhelmigly", "overwhelmingly", - "overwhelmingy", "overwhelmingly", - "overwhelminly", "overwhelmingly", - "palestininans", "palestinians", - "paraphraseing", "paraphrasing", - "paraphrashing", "paraphrasing", - "parilamentary", "parliamentary", - "parlaimentary", "parliamentary", - "parliamantary", "parliamentary", - "parliamentery", "parliamentary", - "parliamnetary", "parliamentary", - "parliementary", "parliamentary", - "particiaption", "participation", - "participacion", "participation", - "participantes", "participants", - "participativo", "participation", - "particularely", "particularly", - "particularily", "particularly", - "particularlly", "particularly", - "partizipation", "participation", - "passionatelly", "passionately", - "paychiatrists", "psychiatrists", - "paychologists", "psychologists", - "pennsylvainia", "pennsylvania", - "pennsylvanica", "pennsylvania", - "pennsylvannia", "pennsylvania", - "perdominantly", "predominantly", - "perpandicular", "perpendicular", - "perpendicualr", "perpendicular", - "perpenticular", "perpendicular", - "perpetuationg", "perpetuating", - "perpindicular", "perpendicular", - "personalitits", "personalities", - "pessimistisch", "pessimistic", - "pharmaceutial", "pharmaceutical", - "philisophical", "philosophical", - "philosiphical", "philosophical", - "philosohpical", "philosophical", - "philosophycal", "philosophically", - "philospohical", "philosophical", - "phisiological", "physiological", - "photagraphers", "photographers", - "photographics", "photographs", - "photographied", "photographed", - "photographier", "photographer", - "photograpphed", "photographed", - "photogrophers", "photographers", - "photogrpahers", "photographers", - "photoshoppade", "photoshopped", - "photoshoppped", "photoshopped", - "phsyiological", "physiological", - "phychiatrists", "psychiatrists", - "phychological", "psychological", - "phychologists", "psychologists", - "phylosophical", "philosophical", - "physciatrists", "psychiatrists", - "physcological", "psychological", - "physcologists", "psychologists", - "physioligical", "physiological", - "planeswlakers", "planeswalker", - "plansewalkers", "planeswalker", - "playthroughts", "playthroughs", - "polysaccaride", "polysaccharide", - "practicallity", "practically", - "practicioners", "practitioners", - "practisioners", "practitioners", - "practitioneer", "practitioners", - "practitionner", "practitioner", - "pratictioners", "practitioners", - "preconceieved", "preconceived", - "predecessores", "predecessors", - "predetermiend", "predetermined", - "predetirmined", "predetermined", - "preditermined", "predetermined", - "predomenantly", "predominantly", - "predominently", "predominantly", - "pregressively", "progressively", - "preinitalized", "preinitialized", - "preinitalizes", "preinitializes", - "preliferation", "proliferation", - "prependicular", "perpendicular", - "preposterious", "preposterous", - "prerequisties", "prerequisite", - "prerequistite", "prerequisite", - "prescribtions", "prescriptions", - "presumptuious", "presumptuous", - "pretedermined", "predetermined", - "problematisch", "problematic", - "proclaimation", "proclamation", - "prodominantly", "predominantly", - "professionnal", "professional", - "profitiablity", "profitability", - "profitibality", "profitability", - "progressivily", "progressively", - "progressivley", "progressively", - "prononciation", "pronunciation", - "pronouciation", "pronunciation", - "pronunciacion", "pronunciation", - "pronunciating", "pronunciation", - "pronuncuation", "pronunciation", - "pronunication", "pronunciation", - "pronuntiation", "pronunciation", - "propabilities", "probabilities", - "proportionaly", "proportionally", - "proportionnal", "proportional", - "proseletyzing", "proselytizing", - "protagonistas", "protagonists", - "protagonistes", "protagonists", - "protestantisk", "protestants", - "protruberance", "protuberance", - "provocativley", "provocative", - "pscyhiatrists", "psychiatrists", - "pscyhological", "psychological", - "pscyhologists", "psychologists", - "pshycological", "psychological", - "pshycologists", "psychologists", - "psichological", "psychological", - "psychaitrists", "psychiatrists", - "psychedellics", "psychedelics", - "psychiatrisch", "psychiatric", - "psycholigical", "psychological", - "psycholigists", "psychologists", - "psychologycal", "psychologically", - "psychologysts", "psychologists", - "psychyatrists", "psychiatrists", - "psysiological", "physiological", - "purpendicular", "perpendicular", - "pyschiatrists", "psychiatrists", - "pyschological", "psychological", - "pyschologists", "psychologists", - "qaulification", "qualification", - "qualifiaction", "qualification", - "qualificaiton", "qualifications", - "qualificatons", "qualifications", - "qualifikation", "qualification", - "questionalble", "questionable", - "quinessential", "quintessential", - "ramificaitons", "ramifications", - "realisitcally", "realistically", - "realtionships", "relationships", - "reccommending", "recommending", - "receptionnist", "receptionist", - "receptionsist", "receptionist", - "reconaissance", "reconnaissance", - "reconcilation", "reconciliation", - "reconnaisance", "reconnaissance", - "reconstrucion", "reconstruction", - "recreationnal", "recreational", - "rectangulaire", "rectangular", - "redistribuito", "redistribution", - "redistributin", "redistribution", - "reencarnation", "reincarnation", - "refridgerator", "refrigerator", - "rehabilitaion", "rehabilitation", - "rehabilitatin", "rehabilitation", - "rehabilitaton", "rehabilitation", - "reincarantion", "reincarnation", - "reincatnation", "reincarnation", - "reinforcemens", "reinforcements", - "reinforcemnts", "reinforcements", - "reinitalising", "reinitialising", - "reinitalizing", "reinitializing", - "reinkarnation", "reincarnation", - "reinstallling", "reinstalling", - "reintarnation", "reincarnation", - "relationshits", "relationships", - "relationsship", "relationships", - "relatiopnship", "relationship", - "relentlessely", "relentlessly", - "relentlessley", "relentlessly", - "relinqushment", "relinquishment", - "remifications", "ramifications", - "reprehenisble", "reprehensible", - "reprehensable", "reprehensible", - "reprehinsible", "reprehensible", - "represenation", "representation", - "represensible", "reprehensible", - "representaion", "representation", - "representatie", "representatives", - "representatin", "representations", - "representerad", "represented", - "representitve", "representative", - "representives", "representatives", - "repricussions", "repercussions", - "reprihensible", "reprehensible", - "resolutionary", "revolutionary", - "respectivelly", "respectively", - "responsibiliy", "responsibility", - "responsibilty", "responsibility", - "responsiblity", "responsibility", - "respositories", "repositories", - "resssurecting", "resurrecting", - "ressurrection", "resurrection", - "restaraunteur", "restaurateur", - "retoractively", "retroactively", - "retroactivily", "retroactively", - "retroactivley", "retroactively", - "retrocatively", "retroactively", - "revelutionary", "revolutionary", - "revolutionair", "revolutionary", - "revolutionens", "revolutions", - "revolutioners", "revolutions", - "revoultionary", "revolutionary", - "ridiculouness", "ridiculousness", - "rienforcement", "reinforcements", - "righetousness", "righteousness", - "rightiousness", "righteousness", - "rigtheousness", "righteousness", - "rollarcoaster", "rollercoaster", - "rollercaoster", "rollercoaster", - "rollercoaters", "rollercoaster", - "rollercoatser", "rollercoaster", - "rollerocaster", "rollercoaster", - "rollertoaster", "rollercoaster", - "rollorcoaster", "rollercoaster", - "sacrastically", "sarcastically", - "sarcasitcally", "sarcastically", - "satisfactorly", "satisfactory", - "scandianvians", "scandinavian", - "scateboarding", "skateboarding", - "schisophrenic", "schizophrenic", - "schiziphrenic", "schizophrenic", - "schizophernia", "schizophrenia", - "schizophernic", "schizophrenic", - "schizophrania", "schizophrenia", - "schizoprhenia", "schizophrenia", - "schizoprhenic", "schizophrenic", - "schozophrenia", "schizophrenia", - "schozophrenic", "schizophrenic", - "schyzophrenia", "schizophrenia", - "schyzophrenic", "schizophrenic", - "schziophrenia", "schizophrenia", - "schziophrenic", "schizophrenic", - "scientificaly", "scientifically", - "scientificlly", "scientifically", - "segementation", "segmentation", - "sensationable", "sensational", - "sensationails", "sensationalism", - "sensationaism", "sensationalism", - "sensationalim", "sensationalism", - "sensationella", "sensational", - "shcizophrenic", "schizophrenic", - "significanlty", "significantly", - "significently", "significantly", - "signifigantly", "significantly", - "simultaneosly", "simultaneously", - "simultaneuous", "simultaneous", - "simultanously", "simultaneously", - "singificantly", "significantly", - "skatebaording", "skateboarding", - "skateborading", "skateboarding", - "socioecenomic", "socioeconomic", - "socioecomonic", "socioeconomic", - "socioeconimic", "socioeconomic", - "sohpisticated", "sophisticated", - "sophisitcated", "sophisticated", - "sophistacated", "sophisticated", - "sophistocated", "sophisticated", - "sophosticated", "sophisticated", - "spacification", "specification", - "specializaton", "specialization", - "specificaiton", "specifications", - "specificatons", "specifications", - "specifikation", "specification", - "spectaculaire", "spectacular", - "spectaculalry", "spectacularly", - "spectatularly", "spectacularly", - "spesification", "specification", - "spirituallity", "spiritually", - "sponatenously", "spontaneously", - "spontaenously", "spontaneously", - "spontainously", "spontaneously", - "spontaneoulsy", "spontaneously", - "spontaneuosly", "spontaneously", - "spontaniously", "spontaneously", - "spontanuously", "spontaneously", - "sponteanously", "spontaneously", - "sponteneously", "spontaneously", - "sporstmanship", "sportsmanship", - "sportmansship", "sportsmanship", - "sportsmamship", "sportsmanship", - "sportsmenship", "sportsmanship", - "sprotsmanship", "sportsmanship", - "stakeboarding", "skateboarding", - "startegically", "strategically", - "statisitcally", "statistically", - "statistacally", "statistically", - "stereotipical", "stereotypical", - "stereotpyical", "stereotypical", - "stereotypcial", "stereotypical", - "stereotypeing", "stereotyping", - "stereotypying", "stereotyping", - "steriotypical", "stereotypical", - "steroetypical", "stereotypical", - "steryotypical", "stereotypical", - "storytellling", "storytelling", - "stragegically", "strategically", - "stragetically", "strategically", - "straightenend", "straightened", - "straitforward", "straightforward", - "stratagically", "strategically", - "stratigically", "strategically", - "strawberrries", "strawberries", - "stregnthening", "strengthening", - "strenghtening", "strengthening", - "strengthining", "strengthening", - "stretegically", "strategically", - "subcatagories", "subcategories", - "subconsciosly", "subconsciously", - "subconsciouly", "subconsciously", - "subconsiously", "subconsciously", - "subjectivelly", "subjectively", - "subscribtions", "subscriptions", - "substancially", "substantially", - "substanitally", "substantially", - "substansially", "substantially", - "substantiable", "substantial", - "substantually", "substantially", - "substitutents", "substitutes", - "successfullly", "successfully", - "supermarkedet", "supermarket", - "supermarkerts", "supermarkets", - "superpowereds", "superpowers", - "supersticious", "superstitious", - "superstisious", "superstitious", - "superstitiosi", "superstitious", - "superstitiuos", "superstitious", - "superstituous", "superstitious", - "suphisticated", "sophisticated", - "supscriptions", "subscriptions", - "surreptiously", "surreptitiously", - "survavibility", "survivability", - "survibability", "survivability", - "survivabiltiy", "survivability", - "survivalibity", "survivability", - "survivavility", "survivability", - "survivebility", "survivability", - "susbtantially", "substantially", - "sustainabilty", "sustainability", - "synchornously", "synchronously", - "systematicaly", "systematically", - "systematiclly", "systematically", - "techmological", "technological", - "technicallity", "technically", - "technoligical", "technological", - "technologicly", "technological", - "techonlogical", "technological", - "telaportation", "teleportation", - "teleportating", "teleportation", - "teleprotation", "teleportation", - "teliportation", "teleportation", - "teloportation", "teleportation", - "territoriella", "territorial", - "theoratically", "theoretically", - "theoritically", "theoretically", - "therapeutisch", "therapeutic", - "thereotically", "theoretically", - "thermodynaics", "thermodynamics", - "thermodynamcs", "thermodynamics", - "theroetically", "theoretically", - "thoeretically", "theoretically", - "tranistioning", "transitioning", - "transcendance", "transcendence", - "transcribtion", "transcription", - "transcripcion", "transcription", - "transferrring", "transferring", - "transformarea", "transformer", - "transformarem", "transformer", - "transformarse", "transformers", - "transformaton", "transformation", - "transformered", "transformed", - "transgengered", "transgendered", - "transisioning", "transitioning", - "transitionals", "transitions", - "transitionnal", "transitional", - "transitionned", "transitioned", - "transkription", "transcription", - "translyvanian", "transylvania", - "transmisisons", "transmissions", - "transmissable", "transmissible", - "transmisssion", "transmissions", - "transparantie", "transparent", - "transparentcy", "transparency", - "transplantees", "transplants", - "transporation", "transportation", - "transportaion", "transportation", - "transportarme", "transporter", - "transportarse", "transporter", - "transportarte", "transporter", - "transporteurs", "transporter", - "transsexuella", "transsexual", - "transylvannia", "transylvania", - "trasngendered", "transgendered", - "troubleshooot", "troubleshoot", - "udnerestimate", "underestimated", - "umcomfortable", "uncomfortable", - "umcomfortably", "uncomfortably", - "umpredictable", "unpredictable", - "unappropriate", "inappropriate", - "unbelievabley", "unbelievably", - "unbelievablly", "unbelievably", - "uncertaintity", "uncertainty", - "uncomfertable", "uncomfortable", - "uncomfertably", "uncomfortably", - "uncomfortabel", "uncomfortably", - "uncomforyable", "uncomfortably", - "uncomfrotable", "uncomfortable", - "uncomfrotably", "uncomfortably", - "uncomftorable", "uncomfortable", - "uncomftorably", "uncomfortably", - "unconcsiously", "unconsciously", - "unconfortable", "uncomfortable", - "unconfortably", "uncomfortably", - "unconscioulsy", "unconsciously", - "unconsicously", "unconsciously", - "unconsiderate", "inconsiderate", - "uncontrollabe", "uncontrollable", - "uncontrollaby", "uncontrollably", - "unconventinal", "unconventional", - "uncounciously", "unconsciously", - "uncousciously", "unconsciously", - "underastimate", "underestimate", - "underesitmate", "underestimated", - "underestamate", "underestimate", - "underestemate", "underestimate", - "underestiamte", "underestimated", - "undergratuate", "undergraduate", - "underhwelming", "underwhelming", - "underhwleming", "underwhelming", - "underminining", "undermining", - "underpowererd", "underpowered", - "undersetimate", "underestimate", - "understandble", "understandable", - "understandbly", "understandably", - "underwealming", "underwhelming", - "underwhemling", "underwhelming", - "underwhleming", "underwhelming", - "undoctrinated", "indoctrinated", - "unexpectadely", "unexpectedly", - "unfomfortable", "uncomfortable", - "unforgiveable", "unforgivable", - "unfortuantely", "unfortunately", - "unfortunantly", "unfortunately", - "unfortunatley", "unfortunately", - "unfortuneatly", "unfortunately", - "unfortunetely", "unfortunately", - "unilaterallly", "unilaterally", - "uninstallling", "uninstalling", - "unintellegent", "unintelligent", - "unintelligant", "unintelligent", - "unintensional", "unintentional", - "uninteristing", "uninteresting", - "universitites", "universities", - "unnecassarily", "unnecessarily", - "unneccesarily", "unnecessarily", - "unnecessairly", "unnecessarily", - "unnecessarely", "unnecessarily", - "unnecessarity", "unnecessarily", - "unnecesserily", "unnecessarily", - "unnecissarily", "unnecessarily", - "unnessecarily", "unnecessarily", - "unoperational", "nonoperational", - "unprecendeted", "unprecedented", - "unprecidented", "unprecedented", - "unpredecented", "unprecedented", - "unpredicatble", "unpredictable", - "unpredictible", "unpredictable", - "unpresedented", "unprecedented", - "unpridictable", "unpredictable", - "unprofessinal", "unprofessional", - "unrealistisch", "unrealistic", - "unreasonabley", "unreasonably", - "unreasonablly", "unreasonably", - "unrestrictred", "unrestricted", - "unsistainable", "unsustainable", - "unsubscribade", "unsubscribed", - "unsubscribbed", "unsubscribe", - "unsuccesfully", "unsuccessfully", - "unsuccessfull", "unsuccessful", - "unsucessfully", "unsuccessfully", - "unsuprisingly", "unsurprisingly", - "unsuprizingly", "unsurprisingly", - "unsustainible", "unsustainable", - "unsustianable", "unsustainable", - "vertification", "certification", - "villification", "vilification", - "virualization", "visualization", - "visualizacion", "visualization", - "visualizaiton", "visualization", - "visualizating", "visualization", - "vitualization", "visualization", - "vizualization", "visualization", - "volounteering", "volunteering", - "vulberability", "vulnerability", - "vulernability", "vulnerability", - "vulnarability", "vulnerability", - "vulnerabiltiy", "vulnerability", - "vulnurability", "vulnerability", - "vunlerability", "vulnerability", - "vurnerability", "vulnerability", - "weightlfiting", "weightlifting", - "weightlifitng", "weightlifting", - "weightligting", "weightlifting", - "weigthlifting", "weightlifting", - "wholeheartdly", "wholeheartedly", - "wholeheartedy", "wholeheartedly", - "wholeheartely", "wholeheartedly", - "wieghtlifting", "weightlifting", - "abberivation", "abbreviation", - "abberviation", "abbreviation", - "abbreivation", "abbreviation", - "abbreveation", "abbreviation", - "abbrievation", "abbreviation", - "abortificant", "abortifacient", - "abrreviation", "abbreviation", - "academcially", "academically", - "accedentally", "accidentally", - "accelarating", "accelerating", - "accelaration", "acceleration", - "acceleartion", "acceleration", - "acceleraptor", "accelerator", - "accelorating", "accelerating", - "accessibilty", "accessibility", - "accidentlaly", "accidentally", - "accomadating", "accommodating", - "accomadation", "accommodation", - "accomodating", "accommodating", - "accomodation", "accommodation", - "accrediation", "accreditation", - "acculumation", "accumulation", - "accumalation", "accumulation", - "accumilation", "accumulation", - "acedemically", "academically", - "acheivements", "achievements", - "acknolwedged", "acknowledged", - "acknolwedges", "acknowledges", - "acknoweldged", "acknowledged", - "acknoweldges", "acknowledges", - "acknowiedged", "acknowledged", - "acknowladges", "acknowledges", - "acknowldeged", "acknowledged", - "acknowledget", "acknowledgement", - "acknowleding", "acknowledging", - "acknowlegded", "acknowledged", - "acknowlegdes", "acknowledges", - "ackumulation", "accumulation", - "acquaintaces", "acquaintances", - "acquaintence", "acquaintance", - "acquantaince", "acquaintance", - "acquantiance", "acquaintance", - "acquiantance", "acquaintance", - "acquiantence", "acquaintance", - "adknowledged", "acknowledged", - "adknowledges", "acknowledges", - "administored", "administered", - "adminsitered", "administered", - "adminstrator", "administrator", - "advantagious", "advantageous", - "advantegeous", "advantageous", - "adventageous", "advantageous", - "adventureous", "adventures", - "adventureres", "adventures", - "adventurious", "adventurous", - "adventuruous", "adventurous", - "advertisiers", "advertisers", - "advertisment", "advertisement", - "advertisters", "advertisers", - "advertisting", "advertising", - "aestheticaly", "aesthetically", - "aestheticlly", "aesthetically", - "afficianados", "aficionados", - "afficionados", "aficionados", - "afghanisthan", "afghanistan", - "afterhtought", "afterthought", - "afterthougth", "afterthought", - "aggressivley", "aggressively", - "agircultural", "agricultural", - "agknowledged", "acknowledged", - "agnosticisim", "agnosticism", - "agracultural", "agricultural", - "agriculteral", "agricultural", - "agriculteurs", "agriculture", - "agricultrual", "agricultural", - "agriculutral", "agricultural", - "agrigultural", "agricultural", - "agrocultural", "agricultural", - "allegiancies", "allegiance", - "alterantives", "alternatives", - "alternatevly", "alternately", - "alternatiely", "alternately", - "alternatieve", "alternative", - "alternativly", "alternatively", - "alternativos", "alternatives", - "alternatvely", "alternately", - "alternitives", "alternatives", - "altruistisch", "altruistic", - "amendmenters", "amendments", - "amohetamines", "amphetamines", - "ampehtamines", "amphetamines", - "ampethamines", "amphetamines", - "amphatamines", "amphetamines", - "amphedamines", "amphetamines", - "amphetamenes", "amphetamines", - "amphetemines", "amphetamines", - "amphetimines", "amphetamines", - "amphetmaines", "amphetamines", - "anecdotallly", "anecdotally", - "annhiliation", "annihilation", - "annihalition", "annihilation", - "annihilatron", "annihilation", - "annihliation", "annihilation", - "annilihation", "annihilation", - "anniversairy", "anniversary", - "anniversarry", "anniversary", - "anniversiary", "anniversary", - "annoucenment", "announcements", - "annoucnement", "announcement", - "announcemnet", "announcements", - "announcemnts", "announcements", - "anphetamines", "amphetamines", - "ansalisation", "nasalisation", - "ansalization", "nasalization", - "antaganistic", "antagonistic", - "antagonisitc", "antagonistic", - "antagonostic", "antagonist", - "antibioticos", "antibiotics", - "anticiaption", "anticipation", - "anticipacion", "anticipation", - "antisipation", "anticipation", - "antogonistic", "antagonistic", - "antrhopology", "anthropology", - "antrophology", "anthropology", - "apllications", "applications", - "apocalypitic", "apocalyptic", - "apologistics", "apologists", - "apologizeing", "apologizing", - "apostrophied", "apostrophe", - "apostrophies", "apostrophe", - "apperciation", "appreciation", - "applicaitons", "applications", - "appoitnments", "appointments", - "apporachable", "approachable", - "appraochable", "approachable", - "appreceating", "appreciating", - "appreciaters", "appreciates", - "appreciatied", "appreciative", - "appreicating", "appreciating", - "appreication", "appreciation", - "appretiation", "appreciation", - "appropriatin", "appropriation", - "appropriatly", "appropriately", - "appropriaton", "appropriation", - "approprietly", "appropriately", - "approstraphe", "apostrophe", - "approxiately", "approximately", - "approximatly", "approximately", - "approximetly", "approximately", - "aproximately", "approximately", - "aqcuaintance", "acquaintance", - "aqquaintance", "acquaintance", - "arbitrariliy", "arbitrarily", - "arbitrarilly", "arbitrarily", - "archetecture", "architecture", - "architechure", "architecture", - "architectual", "architectural", - "architectuur", "architecture", - "architecutre", "architecture", - "architexture", "architecture", - "arcitechture", "architecture", - "areodynamics", "aerodynamics", - "argicultural", "agricultural", - "argumentatie", "argumentative", - "arithmetisch", "arithmetic", - "armageddomon", "armageddon", - "arrengements", "arrangements", - "articifially", "artificially", - "artificailly", "artificially", - "artificiella", "artificial", - "artificually", "artificially", - "artifiically", "artificially", - "assasination", "assassination", - "assassinatin", "assassination", - "assissinated", "assassinated", - "associationg", "associating", - "assoications", "associations", - "assosiations", "associations", - "assosication", "assassination", - "assotiations", "associations", - "assymetrical", "asymmetrical", - "asthetically", "aesthetically", - "astranomical", "astronomical", - "astromonical", "astronomical", - "astronautlis", "astronauts", - "astronimical", "astronomical", - "astronomicly", "astronomical", - "athleticisim", "athleticism", - "atmosphereic", "atmospheric", - "audiobookmrs", "audiobooks", - "auhtenticate", "authenticate", - "australianas", "australians", - "australianos", "australians", - "authentisity", "authenticity", - "authorithies", "authorities", - "authoritiers", "authorities", - "authorizaton", "authorization", - "authrorities", "authorities", - "autochtonous", "autochthonous", - "autocorrrect", "autocorrect", - "automobilies", "automobile", - "automodertor", "automoderator", - "automonomous", "autonomous", - "auxilliaries", "auxiliaries", - "avaliability", "availability", - "avialability", "availability", - "awknowledged", "acknowledged", - "awknowledges", "acknowledges", - "awkwardsness", "awkwardness", - "babysittting", "babysitting", - "beaurocratic", "bureaucratic", - "beautifullly", "beautifully", - "belligerante", "belligerent", - "beuraucratic", "bureaucratic", - "billionairre", "billionaire", - "billionaries", "billionaires", - "billioniares", "billionaires", - "bioligically", "biologically", - "birmingharam", "birmingham", - "bittersweeet", "bittersweet", - "blamethrower", "flamethrower", - "blueberrries", "blueberries", - "blueprintcss", "blueprints", - "boardcasting", "broadcasting", - "bobybuilding", "bodybuilding", - "bodybuidling", "bodybuilding", - "bodybuilidng", "bodybuilding", - "bodybuliding", "bodybuilding", - "bodydbuilder", "bodybuilder", - "bombardement", "bombardment", - "boradcasting", "broadcasting", - "botivational", "motivational", - "brainwahsing", "brainwashing", - "brakethrough", "breakthrough", - "braodcasting", "broadcasting", - "brazilianese", "brazilians", - "brazilianess", "brazilians", - "breakthorugh", "breakthrough", - "breaktrhough", "breakthrough", - "breastfeedig", "breastfeeding", - "breastfeeing", "breastfeeding", - "breasttaking", "breathtaking", - "brianwashing", "brainwashing", - "broadcastors", "broadcasts", - "brotherhoood", "brotherhood", - "buearucratic", "bureaucratic", - "bueraucratic", "bureaucratic", - "bulletprooof", "bulletproof", - "bureaocratic", "bureaucratic", - "bureaucracie", "bureaucratic", - "bureaucracts", "bureaucrats", - "bureaucrates", "bureaucrats", - "bureuacratic", "bureaucratic", - "businessemen", "businessmen", - "cababilities", "capabilities", - "caclulations", "calculations", - "calcluations", "calculation", - "calcualtions", "calculations", - "calculationg", "calculating", - "calculatoare", "calculator", - "californains", "californian", - "californican", "californian", - "californinan", "californian", - "caluclations", "calculations", - "camouflagued", "camouflage", - "canceltation", "cancellation", - "cannibalisim", "cannibalism", - "canniballism", "cannibalism", - "cannotations", "connotations", - "capitalistes", "capitalists", - "caracterized", "characterized", - "carbohydrats", "carbohydrates", - "carbohyrdate", "carbohydrates", - "caricaturale", "caricature", - "caricaturile", "caricature", - "caricaturise", "caricature", - "caricaturize", "caricature", - "catastraphic", "catastrophic", - "catastrohpic", "catastrophic", - "catastrophie", "catastrophe", - "categoricaly", "categorically", - "categoriezed", "categorized", - "catergorized", "categorized", - "caterpillers", "caterpillars", - "catestrophic", "catastrophic", - "catholicisim", "catholicism", - "catholocisim", "catholicism", - "catistrophic", "catastrophic", - "catostraphic", "catastrophic", - "catostrophic", "catastrophic", - "catterpilars", "caterpillars", - "catterpillar", "caterpillar", - "celebratings", "celebrations", - "celebritites", "celebrities", - "celibrations", "celebrations", - "cententenial", "centennial", - "cercumstance", "circumstance", - "cerification", "verification", - "certificiate", "certificate", - "challengeing", "challenging", - "chamiponship", "championships", - "champinoship", "championships", - "championchip", "championship", - "championsihp", "championships", - "championsips", "championships", - "champiosnhip", "championships", - "champoinship", "championship", - "chanpionship", "championship", - "charactarize", "characterize", - "charaterized", "characterized", - "charismastic", "charismatic", - "cheerlearder", "cheerleader", - "cheerleeders", "cheerleaders", - "cheeseberger", "cheeseburger", - "cheeseborger", "cheeseburger", - "cheesebruger", "cheeseburgers", - "cheeseburges", "cheeseburgers", - "cheeseburgie", "cheeseburger", - "cheezeburger", "cheeseburger", - "chirstianity", "christianity", - "chocolateers", "chocolates", - "chrisitanity", "christianity", - "christainity", "christianity", - "christiantiy", "christianity", - "christinaity", "christianity", - "chromosomers", "chromosomes", - "chronologial", "chronological", - "chrsitianity", "christianity", - "cilivization", "civilizations", - "circulatiing", "circulating", - "circulationg", "circulating", - "circumcisied", "circumcised", - "circumcition", "circumcision", - "circumsicion", "circumcision", - "circumsision", "circumcision", - "circumsition", "circumcision", - "circumsizion", "circumcision", - "circumstanes", "circumstance", - "circumstanta", "circumstantial", - "circumstante", "circumstance", - "circuncision", "circumcision", - "circunstance", "circumstance", - "civiliaztion", "civilizations", - "civilizacion", "civilization", - "civilizaiton", "civilization", - "civilizatoin", "civilizations", - "civilizatons", "civilizations", - "civilziation", "civilizations", - "civizilation", "civilizations", - "claculations", "calculations", - "classificato", "classification", - "cockroachers", "cockroaches", - "coefficienct", "coefficient", - "coencidental", "coincidental", - "coincedental", "coincidental", - "coincidencal", "coincidental", - "coincidentia", "coincidental", - "coindidental", "coincidental", - "coinsidental", "coincidental", - "cointerpoint", "counterpoint", - "collaberator", "collaborate", - "collaboratie", "collaborate", - "collaboratin", "collaboration", - "collectivily", "collectively", - "collectivley", "collectively", - "colonialisim", "colonialism", - "colonizacion", "colonization", - "colonizators", "colonizers", - "colonozation", "colonization", - "combanations", "combinations", - "combonations", "combinations", - "comdemnation", "condemnation", - "comemmorates", "commemorates", - "comemoretion", "commemoration", - "comeptitions", "competitions", - "comfirmation", "confirmation", - "comfortabley", "comfortably", - "comfortablly", "comfortably", - "comissioning", "commissioning", - "commandemnts", "commandment", - "commandmants", "commandments", - "commandmends", "commandments", - "commemmorate", "commemorate", - "commendments", "commandments", - "commenteries", "commenters", - "commenwealth", "commonwealth", - "commerciales", "commercials", - "commerically", "commercially", - "comminicated", "communicated", - "commishioned", "commissioned", - "commishioner", "commissioner", - "commisioning", "commissioning", - "commissionar", "commissioner", - "commissionor", "commissioner", - "committments", "commitments", - "commoditites", "commodities", - "commomwealth", "commonwealth", - "commonhealth", "commonwealth", - "commonweatlh", "commonwealth", - "commonwelath", "commonwealth", - "communciated", "communicated", - "communiation", "communication", - "communicatie", "communicate", - "communicatin", "communications", - "communicaton", "communication", - "communitites", "communities", - "compansating", "compensating", - "compansation", "compensation", - "comparativly", "comparatively", - "comparisions", "comparisons", - "comparission", "comparisons", - "comparissons", "comparisons", - "compatablity", "compatibility", - "compatibiliy", "compatibility", - "compatibilty", "compatibility", - "compatiblity", "compatibility", - "compensacion", "compensation", - "compensative", "compensate", - "compesitions", "compositions", - "competetions", "competitions", - "competitevly", "competitively", - "competitiion", "competition", - "competitiors", "competitors", - "competitivly", "competitively", - "competitivos", "competitions", - "compinsating", "compensating", - "compinsation", "compensation", - "complainging", "complaining", - "completetion", "completion", - "compliations", "compilation", - "complicacion", "complication", - "complicatied", "complicate", - "complicaties", "complicate", - "complicatred", "complicate", - "complicatted", "complicate", - "complilation", "complication", - "complimation", "complication", - "complimenary", "complimentary", - "complimentje", "complimented", - "complimentry", "complimentary", - "complination", "complication", - "complitation", "complication", - "composistion", "compositions", - "compramising", "compromising", - "compremising", "compromising", - "compresssion", "compression", - "compromissen", "compromise", - "compromisses", "compromises", - "compromizing", "compromising", - "compromosing", "compromising", - "comptability", "compatibility", - "compulsivley", "compulsive", - "compulsorary", "compulsory", - "computarized", "computerized", - "comrpomising", "compromising", - "comtaminated", "contaminated", - "comtemporary", "contemporary", - "conbinations", "combinations", - "concatinated", "contaminated", - "conceivabley", "conceivably", - "concellation", "cancellation", - "concentraded", "concentrated", - "concentraing", "concentrating", - "concentraion", "concentration", - "concentrarte", "concentrate", - "concentratie", "concentrate", - "concentratin", "concentration", - "concequences", "consequences", - "concequently", "consequently", - "concersation", "conservation", - "concervation", "conservation", - "concervatism", "conservatism", - "concervative", "conservative", - "conciderable", "considerable", - "conciderably", "considerably", - "conciousness", "consciousness", - "conclusiones", "conclusions", - "conclusivley", "conclusive", - "condamnation", "condemnation", - "condemantion", "condemnation", - "condenmation", "condemnation", - "condescening", "condescending", - "condescenion", "condescension", - "conditionnal", "conditional", - "conditionned", "conditioned", - "conditionner", "conditioner", - "condmenation", "condemnation", - "condolencies", "condolences", - "condolensces", "condolences", - "condomnation", "condemnation", - "condradicted", "contradicted", - "conenctivity", "connectivity", - "confedential", "confidential", - "confederancy", "confederacy", - "confederatie", "confederate", - "confermation", "confirmation", - "confersation", "conservation", - "confessionis", "confessions", - "confidencial", "confidential", - "confidentail", "confidential", - "confidentaly", "confidently", - "confidentely", "confidently", - "confidentiel", "confidential", - "configration", "configuration", - "configuratin", "configurations", - "configuraton", "configuration", - "confirmacion", "confirmation", - "confrimation", "confirmation", - "confrontaion", "confrontation", - "congegration", "congregation", - "congergation", "congregation", - "congradulate", "congratulate", - "congragation", "congregation", - "congragulate", "congratulate", - "congratualte", "congratulate", - "congregacion", "congregation", - "congresional", "congressional", - "congresssman", "congressman", - "congresssmen", "congressmen", - "congretation", "congregation", - "congrigation", "congregation", - "conicidental", "coincidental", - "connatations", "connotations", - "connecticuit", "connecticut", - "connectivety", "connectivity", - "connetations", "connotations", - "connitations", "connotations", - "connonations", "connotations", - "conolization", "colonization", - "conpensating", "compensating", - "conpensation", "compensation", - "conpetitions", "competitions", - "conplimented", "complimented", - "conpromising", "compromising", - "consciouness", "consciousness", - "consciouslly", "consciously", - "consectutive", "consecutive", - "consecuences", "consequences", - "consecuentes", "consequences", - "consecuently", "consequently", - "consensuarlo", "consensual", - "consentrated", "concentrated", - "consentrates", "concentrates", - "conseqeunces", "consequence", - "consequenses", "consequences", - "consequental", "consequently", - "consequneces", "consequence", - "conservacion", "conservation", - "conservaties", "conservatives", - "conservativo", "conservation", - "conservativs", "conservatism", - "conservitave", "conservatives", - "conservitism", "conservatism", - "conservitive", "conservative", - "considerarle", "considerable", - "considerarte", "considerate", - "consideraste", "considerate", - "consideratie", "considerate", - "consideratin", "considerations", - "consideribly", "considerably", - "consilidated", "consolidated", - "consipracies", "conspiracies", - "consiquently", "consequently", - "consistantly", "consistently", - "consistencey", "consistency", - "consistentcy", "consistently", - "consitutents", "constituents", - "consoldiated", "consolidated", - "consolitated", "consolidate", - "consolodated", "consolidated", - "consoltation", "consultation", - "conspericies", "conspiracies", - "conspiracize", "conspiracies", - "conspiriator", "conspirator", - "conspiricies", "conspiracies", - "conspriacies", "conspiracies", - "consqeuences", "consequence", - "constinually", "continually", - "constitition", "constitution", - "constituante", "constituents", - "constituants", "constituents", - "constituates", "constitutes", - "constitucion", "constitution", - "constituient", "constitute", - "constituinte", "constituents", - "constitutiei", "constitute", - "constitutues", "constitute", - "constiutents", "constituents", - "constracting", "constructing", - "constraction", "construction", - "constrainsts", "constraints", - "construccion", "construction", - "construciton", "construction", - "constructeds", "constructs", - "constructief", "constructive", - "constructies", "constructs", - "constructifs", "constructs", - "constructiin", "constructing", - "constructivo", "construction", - "consturction", "construction", - "consultating", "consultation", - "consumerisim", "consumerism", - "contaiminate", "contaminate", - "contaminatie", "contaminated", - "contaminaton", "contamination", - "contaminents", "containment", - "contamporary", "contemporary", - "contanimated", "contaminated", - "contaniments", "containment", - "contemperary", "contemporary", - "contemporany", "contemporary", - "continentais", "continents", - "continential", "continental", - "contineously", "continuously", - "continiously", "continuously", - "continuacion", "continuation", - "continuating", "continuation", - "continuativo", "continuation", - "continuining", "continuing", - "contirbution", "contribution", - "contirbutors", "contributors", - "contiunation", "continuation", - "contrabution", "contribution", - "contraceptie", "contraceptives", - "contradicing", "contradicting", - "contradicion", "contradiction", - "contradicory", "contradictory", - "contradictie", "contradicted", - "contradictin", "contradiction", - "contradicton", "contradiction", - "contraticted", "contradicted", - "contribucion", "contribution", - "contribuitor", "contributor", - "contributers", "contributors", - "contributivo", "contribution", - "contributons", "contributors", - "contrictions", "contractions", - "contridicted", "contradicted", - "controlleras", "controllers", - "controlllers", "controllers", - "controverial", "controversial", - "controveries", "controversies", - "controversal", "controversial", - "controversey", "controversy", - "contructions", "contractions", - "conveinently", "conveniently", - "convencional", "conventional", - "conveniantly", "conveniently", - "converastion", "conversations", - "converdation", "conservation", - "conversacion", "conversation", - "conversaiton", "conversations", - "conversatino", "conservation", - "conversatism", "conservatism", - "conversatoin", "conversations", - "conversiones", "conversions", - "converstaion", "conversation", - "convertables", "convertibles", - "convertiable", "convertible", - "convertibile", "convertible", - "convervation", "conservation", - "convervatism", "conservatism", - "converzation", "conservation", - "convesration", "conservation", - "convienently", "conveniently", - "convorsation", "conversation", - "convseration", "conservation", - "coordenation", "coordination", - "coordiantion", "coordination", - "coordinacion", "coordination", - "coordinaters", "coordinates", - "coordinatior", "coordinator", - "coordinatore", "coordinate", - "coordonation", "coordination", - "cooridnation", "coordination", - "coorperation", "cooperation", - "coprorations", "corporations", - "corinthianos", "corinthians", - "corinthinans", "corinthians", - "corparations", "corporations", - "corperations", "corporations", - "corporativos", "corporations", - "corproations", "corporations", - "corrdination", "coordination", - "correponding", "corresponding", - "correposding", "corresponding", - "correspondes", "corresponds", - "correspondig", "corresponding", - "corresponing", "corresponding", - "corrisponded", "corresponded", - "costomizable", "customizable", - "costumizable", "customizable", - "councidental", "coincidental", - "counsellling", "counselling", - "counterfiets", "counterfeit", - "counterfited", "counterfeit", - "counterracts", "counterparts", - "countertraps", "counterparts", - "countrywides", "countryside", - "coutnerparts", "counterparts", - "coutnerpoint", "counterpoint", - "covnersation", "conservation", - "crankenstein", "frankenstein", - "creationisim", "creationism", - "creationnism", "creationism", - "creationnist", "creationist", - "creationsism", "creationism", - "creationsist", "creationist", - "creationsits", "creationists", - "credibillity", "credibility", - "crigneworthy", "cringeworthy", - "cringewhorty", "cringeworthy", - "cringeworhty", "cringeworthy", - "cringewrothy", "cringeworthy", - "cringyworthy", "cringeworthy", - "criticallity", "critically", - "criticiszing", "criticising", - "croporations", "corporations", - "crucifiction", "crucifixion", - "cuestionable", "questionable", - "culiminating", "culminating", - "cumulatative", "cumulative", - "cuntaminated", "contaminated", - "curcumcision", "circumcision", - "curcumstance", "circumstance", - "custamizable", "customizable", - "custimizable", "customizable", - "customizaton", "customization", - "customizeble", "customizable", - "customizible", "customizable", - "custumizable", "customizable", - "cuztomizable", "customizable", - "dabilitating", "debilitating", - "dangerousely", "dangerously", - "decensitized", "desensitized", - "deceptionist", "receptionist", - "declareation", "declaration", - "decomposeion", "decomposition", - "decomposited", "decomposed", - "decscription", "description", - "deffensively", "defensively", - "deficiancies", "deficiencies", - "deficiencias", "deficiencies", - "deficiensies", "deficiencies", - "definatively", "definitively", - "defininitely", "definitively", - "definitavely", "definitively", - "definitevely", "definitively", - "definitifely", "definitively", - "definitinely", "definitively", - "definititely", "definitively", - "definitivley", "definitively", - "deinitalized", "deinitialized", - "deinitalizes", "deinitializes", - "delibaretely", "deliberately", - "deliberatley", "deliberately", - "delibirately", "deliberately", - "delibitating", "debilitating", - "deliverately", "deliberately", - "delusionally", "delusively", - "demesticated", "domesticated", - "democracries", "democracies", - "democraphics", "demographics", - "democratisch", "democratic", - "demograhpics", "demographics", - "demogrpahics", "demographics", - "demonination", "denominations", - "demonstarted", "demonstrated", - "demonstartes", "demonstrates", - "demonstrabil", "demonstrably", - "demonstraion", "demonstration", - "demonstraits", "demonstrates", - "demonstrants", "demonstrates", - "demonstratie", "demonstrate", - "demonstratin", "demonstration", - "demonstrerat", "demonstrate", - "demosntrably", "demonstrably", - "demosntrated", "demonstrated", - "demosntrates", "demonstrates", - "demostration", "demonstration", - "denomenation", "denomination", - "denominacion", "denomination", - "denominatior", "denominator", - "denominatons", "denominations", - "denomonation", "denomination", - "deomgraphics", "demographics", - "depencencies", "dependencies", - "dependancies", "dependencies", - "dependencias", "dependencies", - "dependenices", "dependencies", - "dependensies", "dependencies", - "deperecation", "deprecation", - "deplacements", "replacements", - "deregualtion", "deregulation", - "deregulaiton", "deregulation", - "derugulation", "deregulation", - "describtions", "descriptions", - "descriminant", "discriminant", - "descriptivos", "descriptions", - "desctiptions", "descriptions", - "desctruction", "destruction", - "desencitized", "desensitized", - "desensatized", "desensitized", - "desensitived", "desensitized", - "desentisized", "desensitized", - "desentitized", "desensitized", - "desentizised", "desensitized", - "desginations", "destinations", - "desgustingly", "disgustingly", - "desitnations", "destinations", - "despectively", "respectively", - "despensaries", "dispensaries", - "desperatedly", "desperately", - "desperatelly", "desperately", - "desqualified", "disqualified", - "desregarding", "disregarding", - "dessertation", "dissertation", - "destiantions", "destinations", - "destinctions", "destinations", - "destractions", "distractions", - "destributors", "distributors", - "determinanti", "determination", - "determinaton", "determination", - "determinging", "determining", - "determinisic", "deterministic", - "determinisim", "determinism", - "deterministc", "deterministic", - "determinitic", "deterministic", - "detrimential", "detrimental", - "developement", "development", - "developmenet", "developments", - "develpoments", "developments", - "devolopement", "development", - "devolopments", "developments", - "diasspointed", "dissapointed", - "dicitonaries", "dictionaries", - "dictadorship", "dictatorship", - "dictarorship", "dictatorship", - "dictatorshop", "dictatorship", - "dictionaires", "dictionaries", - "didsapointed", "dissapointed", - "differencial", "differential", - "differencies", "differences", - "differentate", "differentiate", - "differnetial", "differential", - "difficulites", "difficulties", - "difficutlies", "difficulties", - "diffuculties", "difficulties", - "dimensionals", "dimensions", - "dimensionnal", "dimensional", - "dimensionsal", "dimensional", - "diplomatisch", "diplomatic", - "directionnal", "directional", - "disaapointed", "dissapointed", - "disadvandage", "disadvantaged", - "disadvantged", "disadvantaged", - "disadvantges", "disadvantages", - "disadvatange", "disadvantage", - "disadventage", "disadvantage", - "disagremeent", "disagreements", - "disapointing", "disappointing", - "disappearnce", "disappearance", - "disappearred", "disappeared", - "disapperaing", "disappearing", - "disaspointed", "dissapointed", - "disastisfied", "dissatisfied", - "disatissfied", "dissatisfied", - "disatvantage", "disadvantage", - "discertation", "dissertation", - "disciniplary", "disciplinary", - "disciplanary", "disciplinary", - "disciplenary", "disciplinary", - "disciplinare", "discipline", - "disciplinera", "disciplinary", - "disciplinery", "disciplinary", - "disclipinary", "disciplinary", - "disconencted", "disconnected", - "disconnectes", "disconnects", - "disconnectme", "disconnected", - "disconnectus", "disconnects", - "discontiuned", "discontinued", - "discountined", "discontinued", - "discreditied", "discredited", - "discreditted", "discredited", - "discriminare", "discriminate", - "discriminted", "discriminated", - "disctinction", "distinction", - "disctinctive", "distinctive", - "disctintions", "distinctions", - "discualified", "disqualified", - "discustingly", "disgustingly", - "disemination", "dissemination", - "disenchanged", "disenchanted", - "disengenuous", "disingenuous", - "disenginuous", "disingenuous", - "disensitized", "desensitized", - "disgareement", "disagreements", - "disgruntaled", "disgruntled", - "disgrunteled", "disgruntled", - "disguntingly", "disgustingly", - "disingeneous", "disingenuous", - "disingenious", "disingenuous", - "disinteresed", "disinterested", - "disintereted", "disinterested", - "dismantleing", "dismantling", - "disobediance", "disobedience", - "disobeidence", "disobedience", - "dispalcement", "displacement", - "dispapointed", "dissapointed", - "dispencaries", "dispensaries", - "dispensaires", "dispensaries", - "dispensarios", "dispensaries", - "dispensiries", "dispensaries", - "dispensories", "dispensaries", - "disqaulified", "disqualified", - "disqualifyed", "disqualified", - "disqustingly", "disgustingly", - "disrecpected", "disrespected", - "disrepsected", "disrespected", - "disresepcted", "disrespected", - "disrespecful", "disrespectful", - "disrespecing", "disrespecting", - "disrespectul", "disrespectful", - "disrespekted", "disrespected", - "disrtibution", "distributions", - "dissapearing", "disappearing", - "dissapionted", "dissapointed", - "dissapoimted", "dissapointed", - "dissapoitned", "dissapointed", - "dissaponited", "dissapointed", - "dissapoonted", "dissapointed", - "dissapounted", "dissapointed", - "dissappinted", "dissapointed", - "dissapponted", "dissapointed", - "dissastified", "dissatisfied", - "dissatisifed", "dissatisfied", - "dissatsified", "dissatisfied", - "dissepointed", "dissapointed", - "dissipointed", "dissapointed", - "dissobediant", "disobedient", - "dissobedient", "disobedient", - "dissopointed", "dissapointed", - "disspaointed", "dissapointed", - "dissppointed", "dissapointed", - "dissspointed", "dissapointed", - "distinations", "distinctions", - "distincitons", "distinctions", - "distingished", "distinguished", - "distingishes", "distinguishes", - "distinguised", "distinguished", - "distirbuting", "distributing", - "distirbution", "distribution", - "distrabution", "distribution", - "distribitors", "distributors", - "distribtuion", "distributions", - "distribucion", "distribution", - "distribuited", "distributed", - "distribuiton", "distributions", - "distribuitor", "distributor", - "distribusion", "distributions", - "distributino", "distributions", - "distributior", "distributor", - "distributons", "distributors", - "distributore", "distribute", - "distriubtion", "distributions", - "distrobution", "distribution", - "distrubances", "disturbance", - "distrubiting", "distributing", - "distrubition", "distribution", - "distrubitors", "distributors", - "distrubution", "distribution", - "distrubutors", "distributors", - "distructions", "distractions", - "distustingly", "disgustingly", - "ditactorship", "dictatorship", - "documenation", "documentation", - "documentaion", "documentation", - "documentaire", "documentaries", - "documentarse", "documentaries", - "documentarsi", "documentaries", - "domesitcated", "domesticated", - "domisticated", "domesticated", - "donesticated", "domesticated", - "donwloadable", "downloadable", - "dossapointed", "dissapointed", - "downlaodable", "downloadable", - "downloadbale", "downloadable", - "downloadeble", "downloadable", - "drankenstein", "frankenstein", - "dublications", "publications", - "dusgustingly", "disgustingly", - "dynamicallly", "dynamically", - "dyregulation", "deregulation", - "earthquackes", "earthquakes", - "earthquakers", "earthquakes", - "econimically", "economically", - "economisesti", "economists", - "educationnal", "educational", - "effectionate", "affectionate", - "effectivelly", "effectively", - "effectivenss", "effectiveness", - "efficienctly", "efficiency", - "effordlessly", "effortlessly", - "ejacualtions", "ejaculation", - "electorlytes", "electrolytes", - "electricrain", "electrician", - "electrictian", "electrician", - "electrobytes", "electrolytes", - "electrocytes", "electrolytes", - "electrolites", "electrolytes", - "electroltyes", "electrolytes", - "electronicas", "electronics", - "electronicos", "electronics", - "electroyltes", "electrolytes", - "elektrolytes", "electrolytes", - "eloctrolytes", "electrolytes", - "embarassment", "embarrassment", - "embarasssing", "embarrassing", - "embarrasment", "embarrassment", - "embarressing", "embarrassing", - "embarrissing", "embarrassing", - "emberrassing", "embarrassing", - "emphetamines", "amphetamines", - "emprisonment", "imprisonment", - "encarcerated", "incarcerated", - "enceclopedia", "encyclopedia", - "enchancement", "enhancement", - "enchancments", "enchantments", - "enchantmants", "enchantments", - "enchentments", "enchantments", - "enciclopedia", "encyclopedia", - "enclycopedia", "encyclopedia", - "encorporated", "incorporated", - "encourageing", "encouraging", - "encyclapedia", "encyclopedia", - "encyclepedia", "encyclopedia", - "encyclopadia", "encyclopedia", - "encyclopeida", "encyclopedia", - "encyclopidia", "encyclopedia", - "encycolpedia", "encyclopedia", - "encyklopedia", "encyclopedia", - "encylcopedia", "encyclopedia", - "encyplopedia", "encyclopedia", - "endoresments", "endorsement", - "enemployment", "unemployment", - "enfringement", "infringement", - "enlightended", "enlightened", - "enlightenend", "enlightened", - "enlightented", "enlightened", - "enlightining", "enlightening", - "enligthening", "enlightening", - "entaglements", "entanglements", - "entartaining", "entertaining", - "enterpreneur", "entrepreneurs", - "enterprenuer", "entrepreneur", - "entertainted", "entertained", - "enthusiaists", "enthusiasts", - "enthusuastic", "enthusiastic", - "entoxication", "intoxication", - "entrepeneurs", "entrepreneurs", - "entreperneur", "entrepreneurs", - "entreprenaur", "entrepreneur", - "entrepreners", "entrepreneurs", - "entrepreneus", "entrepreneurs", - "entreprenour", "entrepreneur", - "entreprenure", "entrepreneurs", - "entreprenurs", "entrepreneurs", - "entrepreuner", "entrepreneurs", - "entretaining", "entertaining", - "enviormental", "environmental", - "enviornments", "environments", - "enviromental", "environmental", - "environemnts", "environments", - "environmentl", "environmentally", - "environmetal", "environmental", - "envrionments", "environments", - "errorneously", "erroneously", - "establishmet", "establishments", - "evelutionary", "evolutionary", - "exagerrating", "exaggerating", - "exaggarating", "exaggerating", - "exaggaration", "exaggeration", - "exaggeratted", "exaggerated", - "exaggurating", "exaggerating", - "exagguration", "exaggeration", - "exceptionaly", "exceptionally", - "exceptionnal", "exceptional", - "exclusiveity", "exclusivity", - "exclusivelly", "exclusively", - "exclusivitiy", "exclusivity", - "excorciating", "excruciating", - "excrusiating", "excruciating", - "excurciating", "excruciating", - "exectuioners", "executioner", - "executioneer", "executioner", - "executionees", "executions", - "executioness", "executions", - "executionier", "executioner", - "executionner", "executioner", - "exeggerating", "exaggerating", - "exeggeration", "exaggeration", - "expeditonary", "expeditionary", - "expendatures", "expenditures", - "expendetures", "expenditures", - "expentitures", "expenditures", - "experamental", "experimental", - "expereincing", "experiencing", - "experemental", "experimental", - "experiancing", "experiencing", - "experiemntal", "experimental", - "experiemnted", "experimented", - "experimantal", "experimental", - "experimentan", "experimentation", - "experimentes", "experiments", - "experimentle", "experimented", - "experimentos", "experiments", - "experimentul", "experimental", - "expidentures", "expenditures", - "expierencing", "experiencing", - "expiremental", "experimental", - "expiremented", "experimented", - "explaination", "explanation", - "explenations", "explanations", - "expliotation", "exploitation", - "exploitaiton", "exploitation", - "exploitating", "exploitation", - "exploititive", "exploitative", - "explortation", "exploitation", - "explotiation", "exploitation", - "explotiative", "exploitative", - "expolitation", "exploitation", - "expolitative", "exploitative", - "exponentialy", "exponentially", - "expropiation", "expropriation", - "extensivelly", "extensively", - "extradiction", "extradition", - "extraordiary", "extraordinary", - "extraordinay", "extraordinary", - "extrapolerat", "extrapolate", - "extrapoloate", "extrapolate", - "extremistisk", "extremists", - "extrordinary", "extraordinary", - "extruciating", "excruciating", - "facilitatile", "facilitate", - "fahrenheight", "fahrenheit", - "falmethrower", "flamethrower", - "familiarlize", "familiarize", - "fanslaughter", "manslaughter", - "fantasticaly", "fantastically", - "fantasticlly", "fantastically", - "fashionalble", "fashionable", - "fermantation", "fermentation", - "fermentacion", "fermentation", - "fermentaiton", "fermentation", - "fermentating", "fermentation", - "fermintation", "fermentation", - "fictionaries", "dictionaries", - "figuartively", "figuratively", - "figuratevely", "figuratively", - "figurativley", "figuratively", - "figuretively", "figuratively", - "figuritively", "figuratively", - "fingerpoints", "fingerprints", - "firefigthers", "firefighters", - "flamethorwer", "flamethrower", - "flametrhower", "flamethrower", - "flanethrower", "flamethrower", - "flexibillity", "flexibility", - "flourishment", "flourishing", - "fluctiations", "fluctuations", - "flucutations", "fluctuations", - "fluxtuations", "fluctuations", - "forgivenness", "forgiveness", - "fortunatelly", "fortunately", - "framethrower", "flamethrower", - "frankenstain", "frankenstein", - "frankensteen", "frankenstein", - "frankenstine", "frankenstein", - "frankinstein", "frankenstein", - "frementation", "fermentation", - "friendzonded", "friendzoned", - "friendzonned", "friendzoned", - "friendzowned", "friendzoned", - "fringeworthy", "cringeworthy", - "fronkenstein", "frankenstein", - "fruitsations", "frustrations", - "frustrastion", "frustrations", - "fucntionally", "functionally", - "funcitonally", "functionally", - "functionable", "functional", - "functionaliy", "functionally", - "functionalty", "functionality", - "functionlity", "functionality", - "functionning", "functioning", - "fundamentais", "fundamentals", - "fundamentalt", "fundamentalist", - "fundamentaly", "fundamentally", - "fundemantals", "fundamentals", - "fundementals", "fundamentals", - "fundimentals", "fundamentals", - "furstrations", "frustrations", - "futuristisch", "futuristic", - "fwankenstein", "frankenstein", - "geneological", "genealogical", - "generacional", "generational", - "generalizare", "generalize", - "generalizate", "generalize", - "generelizing", "generalizing", - "geograhpical", "geographical", - "geographicly", "geographical", - "geographisch", "geographic", - "geogrpahical", "geographical", - "goegraphical", "geographical", - "governemntal", "governmental", - "governmently", "governmental", - "grammaticaal", "grammatical", - "grammaticaly", "grammatically", - "grandchilden", "grandchildren", - "grandchilder", "grandchildren", - "grandchilren", "grandchildren", - "grassrooters", "grassroots", - "gringeworthy", "cringeworthy", - "guantanameow", "guantanamo", - "guantanamero", "guantanamo", - "hallucinatin", "hallucinations", - "hallucinaton", "hallucination", - "handwritting", "handwriting", - "harrassments", "harassments", - "headqaurters", "headquarters", - "headquatered", "headquartered", - "healthercare", "healthcare", - "heavywieghts", "heavyweight", - "helicopteros", "helicopters", - "hererosexual", "heterosexual", - "heretosexual", "heterosexual", - "heteresexual", "heterosexual", - "hetreosexual", "heterosexual", - "highligthing", "highlighting", - "hipocritical", "hypocritical", - "hipothetical", "hypothetical", - "histarically", "historically", - "histerically", "historically", - "historicians", "historians", - "homogeneized", "homogenized", - "homogenenous", "homogeneous", - "homosexuales", "homosexuals", - "homosexualiy", "homosexuality", - "homosexualls", "homosexuals", - "homosexualty", "homosexuality", - "homosexuella", "homosexual", - "hopsitalized", "hospitalized", - "horisontally", "horizontally", - "horizantally", "horizontally", - "horiztonally", "horizontally", - "horozontally", "horizontally", - "hospitallity", "hospitality", - "hospitilized", "hospitalized", - "hospitolized", "hospitalized", - "hosptialized", "hospitalized", - "humanitarien", "humanitarian", - "humanitarion", "humanitarian", - "humanitatian", "humanitarian", - "humaniterian", "humanitarian", - "humantiarian", "humanitarian", - "huminatarian", "humanitarian", - "hurricanefps", "hurricanes", - "hyopthetical", "hypothetical", - "hypathetical", "hypothetical", - "hypertrophey", "hypertrophy", - "hypethetical", "hypothetical", - "hypocrticial", "hypocritical", - "hypocrytical", "hypocritical", - "hypotehtical", "hypothetical", - "hypotethical", "hypothetical", - "hypotherical", "hypothetical", - "hypotheticly", "hypothetical", - "hystarically", "hysterically", - "hystorically", "hysterically", - "idealistisch", "idealistic", - "identificato", "identification", - "identifierad", "identified", - "identifieras", "identifies", - "identifyable", "identifiable", - "ideologicaly", "ideologically", - "idiosyncracy", "idiosyncrasy", - "illegetimate", "illegitimate", - "illegitamate", "illegitimate", - "illegitamite", "illegitimate", - "illegitemate", "illegitimate", - "illegitimite", "illegitimate", - "illigetimate", "illegitimate", - "illigitemate", "illegitimate", - "illistration", "illustration", - "illsutration", "illustrations", - "illustartion", "illustration", - "illustraitor", "illustrator", - "illustraties", "illustrate", - "illustratior", "illustrator", - "imcompatible", "incompatible", - "imcompetence", "incompetence", - "imexperience", "inexperience", - "immediatelly", "immediately", - "immortallity", "immortality", - "imperialfist", "imperialist", - "imperialisim", "imperialism", - "imperialstic", "imperialist", - "implamenting", "implementing", - "implausibile", "implausible", - "implecations", "implications", - "implementase", "implements", - "implementasi", "implements", - "implementato", "implementation", - "implentation", "implementation", - "implimenting", "implementing", - "imporvements", "improvements", - "impossibilty", "impossibility", - "impossiblely", "impossibly", - "impossiblity", "impossibly", - "impovershied", "impoverished", - "impoversihed", "impoverished", - "imprefection", "imperfections", - "improsonment", "imprisonment", - "improviserad", "improvised", - "imrpovements", "improvements", - "imtimidating", "intimidating", - "imtimidation", "intimidation", - "inaccesibles", "inaccessible", - "inaccessable", "inaccessible", - "inaccessbile", "inaccessible", - "inaccurasies", "inaccuracies", - "inaccuraties", "inaccuracies", - "inaccuricies", "inaccuracies", - "inacuraccies", "inaccuracies", - "inadvertenly", "inadvertently", - "inappropiate", "inappropriate", - "inapproprate", "inappropriate", - "inappropriae", "inappropriately", - "inappropriet", "inappropriately", - "inattractive", "unattractive", - "inbelievable", "unbelievable", - "incarcelated", "incarcerated", - "incarcirated", "incarcerated", - "incarserated", "incarcerated", - "incedentally", "incidentally", - "incentiveise", "incentives", - "incestigator", "investigator", - "incomaptible", "incompatible", - "incomparible", "incompatible", - "incompatable", "incompatible", - "incompatibil", "incompatible", - "incompetance", "incompetence", - "incompetente", "incompetence", - "incompitable", "incompatible", - "incomptetent", "incompetent", - "inconcistent", "inconsistent", - "inconsistant", "inconsistent", - "inconsistecy", "inconsistency", - "inconsisteny", "inconsistency", - "inconveinent", "inconvenient", - "inconveniant", "inconvenient", - "inconveniece", "inconvenience", - "inconvenince", "inconvenience", - "inconvienent", "inconvenient", - "incorparated", "incorporated", - "incorperated", "incorporated", - "incorportaed", "incorporated", - "incorportate", "incorporate", - "incrediblely", "incredibly", - "incrementers", "increments", - "incremential", "incremental", - "indefinately", "indefinitely", - "indefineable", "undefinable", - "indefinetely", "indefinitely", - "indefinitive", "indefinite", - "indefinitley", "indefinitely", - "indefintiely", "indefinitely", - "indepedantly", "independently", - "indepencence", "independence", - "independance", "independence", - "independante", "independents", - "independenet", "independents", - "independenly", "independently", - "independense", "independents", - "independente", "independence", - "independetly", "independently", - "indepentents", "independents", - "indetifiable", "identifiable", - "indianaoplis", "indianapolis", - "indianopolis", "indianapolis", - "indicentally", "incidentally", - "indifferance", "indifference", - "indifferente", "indifference", - "indiffernece", "indifference", - "indimidating", "intimidating", - "indimidation", "intimidation", - "indipendence", "independence", - "indisputible", "indisputable", - "indisputibly", "indisputably", - "individuales", "individuals", - "individualty", "individuality", - "individuella", "individual", - "indiviudally", "individually", - "indivudually", "individually", - "indpendently", "independently", - "indroduction", "introduction", - "indroductory", "introductory", - "industriella", "industrial", - "industrijske", "industries", - "inefficienct", "inefficient", - "inefficienty", "inefficiently", - "inevitablely", "inevitably", - "inevitablity", "inevitably", - "inevititably", "inevitably", - "inexblicably", "inexplicably", - "inexpectedly", "unexpectedly", - "inexpereince", "inexperience", - "inexperiance", "inexperience", - "inexperieced", "inexperienced", - "inexperiened", "inexperienced", - "inexperiente", "inexperience", - "inexpierence", "inexperienced", - "inexplicabil", "inexplicably", - "inexplicibly", "inexplicably", - "infalability", "infallibility", - "infilitrated", "infiltrated", - "infiltraitor", "infiltrator", - "infiltratior", "infiltrator", - "infiltratred", "infiltrate", - "influenceing", "influencing", - "infogrpahics", "infographic", - "inforgivable", "unforgivable", - "infrantryman", "infantryman", - "infridgement", "infringement", - "infrignement", "infringement", - "ingestigator", "investigator", - "ingredientes", "ingredients", - "ingreediants", "ingredients", - "ininterested", "uninterested", - "initalizable", "initializable", - "inkompatible", "incompatible", - "inkompetence", "incompetence", - "inkonsistent", "inconsistent", - "inlightening", "enlightening", - "innersection", "intersection", - "innerstellar", "interstellar", - "inpenetrable", "impenetrable", - "inplementing", "implementing", - "inplications", "implications", - "inpoverished", "impoverished", - "inprisonment", "imprisonment", - "inproductive", "unproductive", - "inprovements", "improvements", - "inresponsive", "unresponsive", - "insentivised", "insensitive", - "insentivises", "insensitive", - "insignifiant", "insignificant", - "insignificat", "insignificant", - "insinuationg", "insinuating", - "instabillity", "instability", - "instalaltion", "installations", - "installatons", "installations", - "installatron", "installation", - "instantaneos", "instantaneous", - "instantaneus", "instantaneous", - "instantanous", "instantaneous", - "instinctivly", "instinctively", - "institutuion", "institution", - "instramental", "instrumental", - "instrcutions", "instruction", - "instrucitons", "instruction", - "instructiosn", "instruction", - "instructores", "instructors", - "instrumentos", "instruments", - "instrumentul", "instrumental", - "insturmental", "instrumental", - "instutitions", "institutions", - "insuccessful", "unsuccessful", - "insufficiant", "insufficient", - "insuffucient", "insufficient", - "insuspecting", "unsuspecting", - "intaxication", "intoxication", - "intelelctual", "intellectuals", - "intellectals", "intellectuals", - "intellectaul", "intellectuals", - "intellectuel", "intellectual", - "intellecutal", "intellectual", - "intelligance", "intelligence", - "intelligenly", "intelligently", - "intelligente", "intelligence", - "intelligenty", "intelligently", - "intelligient", "intelligent", - "intenational", "international", - "intentionnal", "intentional", - "intepretator", "interpreter", - "interatellar", "interstellar", - "interational", "international", - "intercection", "interception", - "intercepcion", "interception", - "interceptons", "interceptions", - "intereaction", "intersection", - "interections", "interactions", - "interersting", "interpreting", - "interesction", "intersection", - "interestigly", "interestingly", - "interestinly", "interestingly", - "interferance", "interference", - "interfereing", "interfering", - "interferisce", "interferes", - "interferisse", "interferes", - "interferring", "interfering", - "intergration", "integration", - "interlectual", "intellectual", - "intermediare", "intermediate", - "intermediete", "intermediate", - "intermettent", "intermittent", - "intermideate", "intermediate", - "intermidiate", "intermediate", - "internatinal", "international", - "internationl", "international", - "internations", "interactions", - "internediate", "intermediate", - "internelized", "internalized", - "internilized", "internalized", - "interperters", "interpreter", - "interperting", "interpreting", - "interprating", "interpreting", - "interpretare", "interpreter", - "interpretato", "interpretation", - "interpreteer", "interpreter", - "interpretier", "interpreter", - "interpretion", "interpreting", - "interpretter", "interpreter", - "interpriting", "interpreting", - "interraccial", "interracial", - "interractial", "interracial", - "interrogatin", "interrogation", - "interrumping", "interrupting", - "interrupteds", "interrupts", - "interruptors", "interrupts", - "interseccion", "intersection", - "interseciton", "intersections", - "interseption", "interception", - "intersetllar", "interstellar", - "interstallar", "interstellar", - "interstaller", "interstellar", - "intersteller", "interstellar", - "interstellor", "interstellar", - "intertaining", "entertaining", - "intertwinded", "intertwined", - "intertwinned", "intertwined", - "interveiwing", "interviewing", - "intervencion", "intervention", - "interveneing", "intervening", - "intervension", "intervention", - "interviening", "interviewing", - "intidimation", "intimidation", - "intillectual", "intellectual", - "intimidacion", "intimidation", - "intimidative", "intimidate", - "intimitading", "intimidating", - "intimitating", "intimidating", - "intimitation", "intimidation", - "intorduction", "introduction", - "intorductory", "introductory", - "intoxicacion", "intoxication", - "intoxination", "intoxication", - "intrepreting", "interpreting", - "intrinsicaly", "intrinsically", - "introdiction", "introduction", - "introduccion", "introduction", - "introduceras", "introduces", - "introduceres", "introduces", - "introduciton", "introduction", - "introductary", "introductory", - "introducting", "introduction", - "introductury", "introductory", - "introduktion", "introduction", - "introspectin", "introspection", - "intruduction", "introduction", - "intruductory", "introductory", - "intsrumental", "instrumental", - "intuitivelly", "intuitively", - "inturrupting", "interrupting", - "invervention", "intervention", - "investagated", "investigated", - "investagator", "investigator", - "investegated", "investigated", - "investegator", "investigator", - "investigaron", "investigator", - "investigater", "investigator", - "investigatie", "investigative", - "investigatin", "investigation", - "investigatio", "investigator", - "investigaton", "investigation", - "investingate", "investigate", - "investogator", "investigator", - "invicibility", "invisibility", - "invididually", "individually", - "invisibiltiy", "invisibility", - "invisilibity", "invisibility", - "invisivility", "invisibility", - "invlunerable", "invulnerable", - "involnerable", "invulnerable", - "involuntairy", "involuntary", - "involuntarly", "involuntary", - "invonvenient", "inconvenient", - "invulenrable", "invulnerable", - "invulernable", "invulnerable", - "invulnarable", "invulnerable", - "invulnerbale", "invulnerable", - "invulnurable", "invulnerable", - "invulverable", "invulnerable", - "invunlerable", "invulnerable", - "invurnerable", "invulnerable", - "irrationably", "irrationally", - "irrationatly", "irrationally", - "irrationella", "irrational", - "irreplacable", "irreplaceable", - "irresistable", "irresistible", - "irresistably", "irresistibly", - "irrespecitve", "irrespective", - "irresponsble", "irresponsible", - "irresponsibe", "irresponsible", - "irreverisble", "irreversible", - "irreversebly", "irreversible", - "irreversibel", "irreversible", - "irrevirsible", "irreversible", - "irrispective", "irrespective", - "irriversible", "irreversible", - "isdefinitely", "indefinitely", - "isntallation", "installation", - "isntrumental", "instrumental", - "jackonsville", "jacksonville", - "jounralistic", "journalistic", - "jouranlistic", "journalistic", - "journalisitc", "journalistic", - "journalistes", "journalists", - "judgementals", "judgements", - "juggernaunts", "juggernaut", - "juridisction", "jurisdictions", - "jurisdiccion", "jurisdiction", - "jurisdiciton", "jurisdiction", - "jurisdiktion", "jurisdiction", - "jurisfiction", "jurisdiction", - "jurisidction", "jurisdiction", - "juristiction", "jurisdiction", - "jursidiction", "jurisdiction", - "jusridiction", "jurisdiction", - "justificatin", "justifications", - "katastrophic", "catastrophic", - "kidnergarten", "kindergarten", - "kindergarden", "kindergarten", - "kingergarten", "kindergarten", - "kintergarten", "kindergarten", - "knolwedgable", "knowledgable", - "knoweldgable", "knowledgable", - "knowladgable", "knowledgable", - "knowldegable", "knowledgable", - "knowldgeable", "knowledgable", - "knowleagable", "knowledgable", - "knowledagble", "knowledgable", - "knowledeable", "knowledgable", - "knowledgabel", "knowledgable", - "knowledgeble", "knowledgeable", - "knowledgebly", "knowledgable", - "knowledgible", "knowledgable", - "knowlegdable", "knowledgable", - "knowlegeable", "knowledgeable", - "knwoledgable", "knowledgable", - "kolonization", "colonization", - "kombinations", "combinations", - "kommissioner", "commissioner", - "kompensation", "compensation", - "konfidential", "confidential", - "konfirmation", "confirmation", - "kongregation", "congregation", - "konservatism", "conservatism", - "konservative", "conservative", - "konsultation", "consultation", - "konversation", "conversation", - "koordination", "coordination", - "krankenstein", "frankenstein", - "leaglization", "legalization", - "legalizacion", "legalization", - "legalizaiton", "legalization", - "legendariske", "legendaries", - "legimitately", "legitimately", - "legislatiors", "legislators", - "legistration", "registration", - "legitamately", "legitimately", - "legitamitely", "legitimately", - "legitemately", "legitimately", - "legitimatley", "legitimately", - "legitimitely", "legitimately", - "liberatrians", "libertarians", - "libertarains", "libertarians", - "libertariens", "libertarians", - "libertaryans", "libertarians", - "libertatians", "libertarians", - "liberterians", "libertarians", - "libretarians", "libertarians", - "lighthearded", "lighthearted", - "linguisticas", "linguistics", - "linguisticos", "linguistics", - "linguistisch", "linguistics", - "litllefinger", "littlefinger", - "littelfinger", "littlefinger", - "litterfinger", "littlefinger", - "littiefinger", "littlefinger", - "littlefigner", "littlefinger", - "littlefinder", "littlefinger", - "littlepinger", "littlefinger", - "lnowledgable", "knowledgable", - "longitudonal", "longitudinal", - "madturbating", "masturbating", - "madturbation", "masturbation", - "magnificient", "magnificent", - "maintainance", "maintenance", - "maintainence", "maintenance", - "maintenaince", "maintenance", - "malfucntions", "malfunction", - "manafactured", "manufactured", - "manafacturer", "manufacturer", - "manafactures", "manufactures", - "manifactured", "manufactured", - "manifacturer", "manufacturer", - "manifactures", "manufactures", - "manifestaion", "manifestation", - "manifestanti", "manifestation", - "manipluating", "manipulating", - "manipluation", "manipulation", - "manipualting", "manipulating", - "manipualtion", "manipulation", - "manipualtive", "manipulative", - "manipulacion", "manipulation", - "manipulitive", "manipulative", - "maniuplating", "manipulating", - "maniuplation", "manipulation", - "maniuplative", "manipulative", - "manouverable", "maneuverable", - "mansalughter", "manslaughter", - "manslaugther", "manslaughter", - "mansluaghter", "manslaughter", - "manufactered", "manufactured", - "manufacterer", "manufacturer", - "manufacteres", "manufactures", - "manufacteurs", "manufactures", - "manufactored", "manufactured", - "manufactorer", "manufacturer", - "manufactores", "manufactures", - "manufactuers", "manufacturers", - "manufactuing", "manufacturing", - "manufacturas", "manufactures", - "manufacturor", "manufacturer", - "manufactuter", "manufacture", - "manufacuters", "manufactures", - "manufacutred", "manufacture", - "manufacutres", "manufactures", - "manufaturing", "manufacturing", - "manupilating", "manipulating", - "manupulating", "manipulating", - "manupulation", "manipulation", - "manupulative", "manipulative", - "marchmallows", "marshmallows", - "marganilized", "marginalized", - "margenalized", "marginalized", - "marginilized", "marginalized", - "marhsmallows", "marshmallows", - "marshamllows", "marshmallows", - "marshmallons", "marshmallows", - "masoginistic", "misogynistic", - "masogynistic", "misogynistic", - "massachusets", "massachusetts", - "massachustts", "massachusetts", - "masterbation", "masturbation", - "masterpeices", "masterpiece", - "mastrubating", "masturbating", - "mastrubation", "masturbation", - "mastubration", "masturbation", - "masturabting", "masturbating", - "masturabtion", "masturbation", - "masturbacion", "masturbation", - "masturbaited", "masturbated", - "masturbathon", "masturbation", - "masturbsting", "masturbating", - "masturdating", "masturbating", - "mastutbation", "masturbation", - "mataphorical", "metaphorical", - "mataphysical", "metaphysical", - "matchmakeing", "matchmaking", - "mathemathics", "mathematics", - "mathematican", "mathematician", - "mathematicas", "mathematics", - "mathematicks", "mathematics", - "mathematicly", "mathematical", - "mathematisch", "mathematics", - "mathemetical", "mathematical", - "matheticians", "mathematicians", - "mathimatical", "mathematical", - "mathmatician", "mathematician", - "mecahnically", "mechanically", - "mechancially", "mechanically", - "meditaciones", "medications", - "mediteranean", "mediterranean", - "mediterraean", "mediterranean", - "mediterranen", "mediterranean", - "memerization", "memorization", - "memorizacion", "memorization", - "memorozation", "memorization", - "metalurgical", "metallurgical", - "metaphisical", "metaphysical", - "metaphoricly", "metaphorical", - "metaphsyical", "metaphysical", - "metaphyiscal", "metaphysical", - "metaphyscial", "metaphysical", - "metaphysisch", "metaphysics", - "metephorical", "metaphorical", - "metephysical", "metaphysical", - "meterologist", "meteorologist", - "meterosexual", "heterosexual", - "methaporical", "metaphorical", - "methematical", "mathematical", - "metiphorical", "metaphorical", - "metophorical", "metaphorical", - "metorpolitan", "metropolitan", - "metrololitan", "metropolitan", - "metropilitan", "metropolitan", - "metroploitan", "metropolitan", - "metropolians", "metropolis", - "metropoliten", "metropolitan", - "metropolitin", "metropolitan", - "metropoliton", "metropolitan", - "microcentres", "microcenter", - "microphonies", "microphones", - "microscophic", "microscopic", - "microscopice", "microscope", - "microscoptic", "microscopic", - "midfieldiers", "midfielders", - "millenialism", "millennialism", - "millionairre", "millionaire", - "millionaries", "millionaires", - "millioniares", "millionaires", - "minimalisitc", "minimalist", - "minimalisity", "minimalist", - "mininterpret", "misinterpret", - "minipulating", "manipulating", - "minipulation", "manipulation", - "minipulative", "manipulative", - "miracilously", "miraculously", - "miracurously", "miraculous", - "miscarraiges", "miscarriage", - "miscelaneous", "miscellaneous", - "miscellanous", "miscellaneous", - "mischievious", "mischievous", - "misdameanors", "misdemeanors", - "misdeamenors", "misdemeanor", - "misfourtunes", "misfortunes", - "misgoynistic", "misogynistic", - "misinterpert", "misinterpret", - "misinterpred", "misinterpreted", - "misinterprit", "misinterpreting", - "misinterpted", "misinterpret", - "misintrepret", "misinterpret", - "misisonaries", "missionaries", - "misoganistic", "misogynistic", - "misogenistic", "misogynistic", - "misoginystic", "misogynistic", - "misognyistic", "misogynistic", - "misogonistic", "misogynistic", - "misogynisitc", "misogynistic", - "misogynsitic", "misogynistic", - "misogynystic", "misogynistic", - "missionaires", "missionaries", - "mississipppi", "mississippi", - "misspellling", "misspelling", - "misteriously", "mysteriously", - "misundersood", "misunderstood", - "misunderstod", "misunderstood", - "misygonistic", "misogynistic", - "modificacion", "modification", - "modificaiton", "modification", - "modificatons", "modifications", - "modifikation", "modification", - "modivational", "motivational", - "moisterizing", "moisturizing", - "moistorizing", "moisturizing", - "moisutrizing", "moisturizing", - "momentarilly", "momentarily", - "monolithisch", "monolithic", - "mositurizing", "moisturizing", - "motherbaords", "motherboards", - "motherborads", "motherboards", - "motivacional", "motivational", - "motovational", "motivational", - "mousturizing", "moisturizing", - "muktitasking", "multitasking", - "mulittasking", "multitasking", - "multinatinal", "multinational", - "multitaksing", "multitasking", - "munipulative", "manipulative", - "mutlitasking", "multitasking", - "mysoganistic", "misogynistic", - "mysogenistic", "misogynistic", - "mysogonistic", "misogynistic", - "mysterioulsy", "mysteriously", - "nacionalists", "nationalists", - "narcisisstic", "narcissistic", - "narcissictic", "narcissistic", - "narcissisism", "narcissism", - "narcissisist", "narcissist", - "narcissisitc", "narcissist", - "narcississts", "narcissist", - "narssicistic", "narcissistic", - "natioanlists", "nationalists", - "nationalisic", "nationalistic", - "nationalisim", "nationalism", - "nationalistc", "nationalistic", - "nationalites", "nationalist", - "nationalitic", "nationalistic", - "nationalitys", "nationalist", - "nationallity", "nationally", - "nationalsits", "nationalists", - "nationalties", "nationalist", - "nazionalists", "nationalists", - "neccessarily", "necessarily", - "neccessities", "necessities", - "necessarilly", "necessarily", - "necessitites", "necessities", - "neckbearders", "neckbeards", - "neckbeardese", "neckbeards", - "neckbeardest", "neckbeards", - "neckbeardies", "neckbeards", - "neckbeardius", "neckbeards", - "negociations", "negotiations", - "negoitations", "negotiations", - "negotiatians", "negotiations", - "negotiatiing", "negotiating", - "negotiationg", "negotiating", - "negotiatiors", "negotiations", - "neigbhorhood", "neighborhoods", - "neigbourhood", "neighbourhood", - "neighboorhod", "neighbourhood", - "neighborhing", "neighboring", - "neighborhods", "neighborhoods", - "neighbourghs", "neighbours", - "neighbourhod", "neighbourhood", - "neighbourood", "neighbourhood", - "neighbrohood", "neighborhoods", - "neighourhood", "neighborhood", - "neoroscience", "neuroscience", - "neruological", "neurological", - "neruoscience", "neuroscience", - "netropolitan", "metropolitan", - "neuorscience", "neuroscience", - "neuralogical", "neurological", - "neuroligical", "neurological", - "neurosceince", "neuroscience", - "neuroscienze", "neuroscience", - "neurosicence", "neuroscience", - "neverhteless", "nevertheless", - "nieghborhood", "neighborhood", - "norhtwestern", "northwestern", - "nothingsness", "nothingness", - "noticeablely", "noticeably", - "notificacion", "notification", - "notificaiton", "notification", - "notificatons", "notifications", - "nuerological", "neurological", - "nueroscience", "neuroscience", - "nutritionnal", "nutritional", - "obersvations", "observations", - "objectivelly", "objectively", - "objectiviser", "objectives", - "objectivitiy", "objectivity", - "obversations", "observations", - "ocassionally", "occasionally", - "occaisonally", "occasionally", - "occasioanlly", "occasionally", - "occassionaly", "occasionally", - "occationally", "occasionally", - "occurrencies", "occurrences", - "offensivelly", "offensively", - "ogranisation", "organisation", - "omniverously", "omnivorously", - "operationnal", "operational", - "opportuniste", "opportunities", - "opportunites", "opportunities", - "oppositition", "opposition", - "opthalmology", "ophthalmology", - "optimistisch", "optimistic", - "optimizacion", "optimization", - "optimizating", "optimization", - "optimziation", "optimization", - "optmizations", "optimizations", - "oragnisation", "organisation", - "orchastrated", "orchestrated", - "orchestarted", "orchestrated", - "orchestraded", "orchestrated", - "orchistrated", "orchestrated", - "orgainsation", "organisation", - "orgainzation", "organizations", - "organisaiton", "organisation", - "organisatons", "organisations", - "organistaion", "organisation", - "organizacion", "organization", - "organizaiton", "organization", - "organizativo", "organization", - "organizatons", "organizations", - "organsiation", "organisation", - "organziation", "organization", - "orginasation", "organisation", - "orginazation", "organization", - "orgnaisation", "organisations", - "originallity", "originality", - "outraegously", "outrageously", - "outrageoulsy", "outrageously", - "outragesouly", "outrageously", - "outrageuosly", "outrageously", - "outragiously", "outrageously", - "outsourceing", "outsourcing", - "overbearring", "overbearing", - "overblocking", "overclocking", - "overclcoking", "overclocking", - "overclicking", "overclocking", - "overcloaking", "overclocking", - "overclockign", "overclocking", - "overclokcing", "overclocking", - "overhearting", "overreacting", - "overheathing", "overheating", - "overhtinking", "overthinking", - "overhwelming", "overwhelming", - "overlappping", "overlapping", - "overlcocking", "overclocking", - "overreaktion", "overreaction", - "overwealming", "overwhelming", - "overwhelemed", "overwhelmed", - "overwhemling", "overwhelming", - "overwhleming", "overwhelming", - "owerpowering", "overpowering", - "painkilllers", "painkillers", - "palastinians", "palestinians", - "palesitnians", "palestinians", - "palestenians", "palestinians", - "palestinains", "palestinians", - "palestiniens", "palestinians", - "palestininan", "palestinian", - "palestininas", "palestinians", - "palistinians", "palestinians", - "palythroughs", "playthroughs", - "parapharsing", "paraphrasing", - "paraphenalia", "paraphernalia", - "paraphrashed", "paraphrase", - "paraphrazing", "paraphrasing", - "paraprashing", "paraphrasing", - "paraprhasing", "paraphrasing", - "parenthesees", "parentheses", - "parenthesies", "parenthesis", - "parliamentry", "parliamentary", - "partecipants", "participants", - "partecipated", "participated", - "parternships", "partnership", - "particapated", "participated", - "particiapnts", "participant", - "particiapted", "participated", - "participante", "participate", - "participaste", "participants", - "participatie", "participated", - "participatin", "participation", - "participatns", "participant", - "participaton", "participant", - "participents", "participants", - "particualrly", "particularly", - "particulalry", "particularly", - "particullary", "particularly", - "passionatley", "passionately", - "pathalogical", "pathological", - "pathelogical", "pathological", - "patholigical", "pathological", - "paychedelics", "psychedelics", - "paychiatrist", "psychiatrist", - "paychologist", "psychologist", - "paychopathic", "psychopathic", - "penetratiing", "penetrating", - "penisylvania", "pennsylvania", - "pennsilvania", "pennsylvania", - "pennslyvania", "pennsylvania", - "pennsylvaina", "pennsylvania", - "pennsyvlania", "pennsylvania", - "pennyslvania", "pennsylvania", - "penssylvania", "pennsylvania", - "pentsylvania", "pennsylvania", - "percentagens", "percentages", - "perferential", "preferential", - "performantes", "performances", - "performences", "performances", - "perfromances", "performances", - "peridoically", "periodically", - "peripathetic", "peripatetic", - "periphereals", "peripherals", - "peripherials", "peripherals", - "permanantely", "permanently", - "permanentely", "permanently", - "permissiable", "permissible", - "peroidically", "periodically", - "perpatrators", "perpetrators", - "perpatuating", "perpetuating", - "perpertators", "perpetrators", - "perpertrated", "perpetrated", - "perpetraitor", "perpetrator", - "perpetraters", "perpetrators", - "perpetuaters", "perpetuates", - "perpitrators", "perpetrators", - "perposefully", "purposefully", - "perposterous", "preposterous", - "perpretators", "perpetrators", - "perpsectives", "perspectives", - "perputrators", "perpetrators", - "perputuating", "perpetuating", - "persepctives", "perspectives", - "perservation", "preservation", - "perseverence", "perseverance", - "personalites", "personalities", - "personallity", "personally", - "personilized", "personalized", - "perspecitves", "perspectives", - "perspectivas", "perspectives", - "persumptuous", "presumptuous", - "perticularly", "particularly", - "pertubations", "perturbations", - "pessimisitic", "pessimistic", - "pessimisstic", "pessimistic", - "phenomenonal", "phenomenal", - "phenomenonly", "phenomenally", - "phenomonenon", "phenomenon", - "phialdelphia", "philadelphia", - "philadalphia", "philadelphia", - "philadelhpia", "philadelphia", - "philadeplhia", "philadelphia", - "philadlephia", "philadelphia", - "philedalphia", "philadelphia", - "philedelphia", "philadelphia", - "philidalphia", "philadelphia", - "philippinnes", "philippines", - "philippinoes", "philippines", - "philisophers", "philosophers", - "philisophies", "philosophies", - "phillippines", "philippines", - "philosiphers", "philosophers", - "philosiphies", "philosophies", - "philosohpers", "philosopher", - "philosohpies", "philosophies", - "philosophiae", "philosophies", - "philosophics", "philosophies", - "philosophios", "philosophies", - "philospohers", "philosophers", - "philospohies", "philosophies", - "photagrapher", "photographer", - "photochopped", "photoshopped", - "photograhper", "photographer", - "photograpers", "photographers", - "photographes", "photographs", - "photographyi", "photographic", - "photogropher", "photographer", - "photogrpahed", "photographed", - "photogrpaher", "photographer", - "photoshipped", "photoshopped", - "photoshooped", "photoshopped", - "photoshoppad", "photoshopped", - "phychedelics", "psychedelics", - "phychiatrist", "psychiatrist", - "phychologist", "psychologist", - "phychopathic", "psychopathic", - "physcedelics", "psychedelics", - "physciatrist", "psychiatrist", - "physcologist", "psychologist", - "physcopathic", "psychopathic", - "physicallity", "physically", - "physiologial", "physiological", - "pilgrimmages", "pilgrimages", - "pitchforkers", "pitchforks", - "pkaythroughs", "playthroughs", - "plabeswalker", "planeswalker", - "plaestinians", "palestinians", - "planeswaller", "planeswalker", - "planeswlaker", "planeswalker", - "planetwalker", "planeswalker", - "plansewalker", "planeswalker", - "plauthroughs", "playthroughs", - "playhtroughs", "playthroughs", - "playtgroughs", "playthroughs", - "playthorughs", "playthroughs", - "playthourghs", "playthroughs", - "playthrougth", "playthroughs", - "playthrouhgs", "playthroughs", - "playthtoughs", "playthroughs", - "playtrhoughs", "playthroughs", - "populationes", "populations", - "pornograpghy", "pornography", - "porportional", "proportional", - "portabillity", "portability", - "portagonists", "protagonists", - "positionning", "positioning", - "positivitely", "positivity", - "possessivize", "possessive", - "possibillity", "possibility", - "possiblility", "possibility", - "possiblities", "possibilities", - "powerfisting", "powerlifting", - "powerlfiting", "powerlifting", - "powerlifitng", "powerlifting", - "powerlisting", "powerlifting", - "powetlifting", "powerlifting", - "powrrlifting", "powerlifting", - "practicioner", "practitioner", - "practisioner", "practitioner", - "pratictioner", "practitioners", - "precedessors", "predecessors", - "preconveived", "preconceived", - "predacessors", "predecessors", - "predeccesors", "predecessor", - "predecesores", "predecessor", - "predescesors", "predecessors", - "predessecors", "predecessors", - "predetermind", "predetermined", - "predicessors", "predecessors", - "predocessors", "predecessors", - "predomiantly", "predominately", - "predominanty", "predominantly", - "predominatly", "predominantly", - "preferantial", "preferential", - "preferentail", "preferential", - "preformances", "performances", - "preinitalize", "preinitialize", - "preliminarly", "preliminary", - "prematurelly", "prematurely", - "premillenial", "premillennial", - "preocupation", "preoccupation", - "preperations", "preparations", - "prepetrators", "perpetrators", - "prepetuating", "perpetuating", - "prepostorous", "preposterous", - "preposturous", "preposterous", - "prerequisets", "prerequisite", - "prescirption", "prescriptions", - "prescribtion", "prescription", - "prescripcion", "prescription", - "prescriptons", "prescriptions", - "prescritpion", "prescriptions", - "presedential", "presidential", - "presentacion", "presentation", - "presentaiton", "presentations", - "preservacion", "preservation", - "preservating", "preservation", - "preservativo", "preservation", - "presidencial", "presidential", - "presidenital", "presidential", - "presidentail", "presidential", - "presnetation", "presentations", - "presonalized", "personalized", - "prespectives", "perspectives", - "presrciption", "prescriptions", - "presumpteous", "presumptuous", - "presumputous", "presumptuous", - "prevantative", "preventative", - "preventation", "presentation", - "preventetive", "preventative", - "preventitive", "preventative", - "prezidential", "presidential", - "principlaity", "principality", - "probabiliste", "probabilities", - "probabilites", "probabilities", - "probabillity", "probability", - "probablistic", "probabilistic", - "proclomation", "proclamation", - "proconceived", "preconceived", - "profesisonal", "professionals", - "professiinal", "professionalism", - "professioanl", "professionals", - "professiomal", "professionalism", - "professionel", "professional", - "professionsl", "professionalism", - "professoinal", "professionals", - "professonial", "professionals", - "proffesional", "professional", - "proficientcy", "proficiency", - "profissional", "professional", - "profitabiliy", "profitability", - "profitabilty", "profitability", - "profressions", "progressions", - "progatonists", "protagonists", - "programmeurs", "programmer", - "progressieve", "progressive", - "progressioin", "progressions", - "progressiong", "progressing", - "progressisme", "progresses", - "progressiste", "progresses", - "progressivas", "progressives", - "progressivey", "progressively", - "progressivly", "progressively", - "progressivsm", "progressives", - "progresssing", "progressing", - "progresssion", "progressions", - "progresssive", "progressives", - "prohibitting", "prohibiting", - "projecticles", "projectiles", - "proletariaat", "proletariat", - "proletariant", "proletariat", - "proletaricat", "proletariat", - "prominantely", "prominently", - "promiscuious", "promiscuous", - "promisculous", "promiscuous", - "promotionnal", "promotional", - "pronounceing", "pronouncing", - "pronunciaton", "pronunciation", - "propertional", "proportional", - "propesterous", "preposterous", - "proportianal", "proportional", - "proportionel", "proportional", - "proposterous", "preposterous", - "proprotional", "proportional", - "prostetution", "prostitution", - "prostitition", "prostitution", - "prostitucion", "prostitution", - "prostituiton", "prostitution", - "prostitutiei", "prostitute", - "protaganists", "protagonists", - "protaginists", "protagonists", - "protagnoists", "protagonists", - "protestantes", "protestants", - "protoganists", "protagonists", - "prouncements", "pronouncements", - "pruposefully", "purposefully", - "pscyhologist", "psychologist", - "pscyhopathic", "psychopathic", - "pshyciatrist", "psychiatrist", - "pshycologist", "psychologist", - "pshycopathic", "psychopathic", - "psichologist", "psychologist", - "psychaitrist", "psychiatrist", - "psychedellic", "psychedelic", - "psychedilics", "psychedelics", - "psychemedics", "psychedelics", - "psychiatirst", "psychiatrists", - "psychiatrics", "psychiatrist", - "psychiatrict", "psychiatrist", - "psychiatrits", "psychiatrists", - "psychistrist", "psychiatrist", - "psychodelics", "psychedelics", - "psycholigist", "psychologist", - "psychologial", "psychological", - "psychologits", "psychologists", - "psychologyst", "psychologist", - "psychopathes", "psychopaths", - "psychyatrist", "psychiatrist", - "puplications", "publications", - "puritannical", "puritanical", - "purpetrators", "perpetrators", - "purpetuating", "perpetuating", - "purpusefully", "purposefully", - "pyschedelics", "psychedelics", - "pyschiatrist", "psychiatrist", - "pyschologist", "psychologist", - "pyschopathic", "psychopathic", - "qualificaton", "qualification", - "qualifierais", "qualifiers", - "qualtitative", "quantitative", - "quantatitive", "quantitative", - "quantititive", "quantitative", - "quarterblack", "quarterback", - "quesitonable", "questionable", - "questionalbe", "questionable", - "questionning", "questioning", - "questionsign", "questioning", - "radioactieve", "radioactive", - "rationallity", "rationally", - "reactionairy", "reactionary", - "reactionnary", "reactionary", - "realisticaly", "realistically", - "realisticlly", "realistically", - "reasonablely", "reasonably", - "recallection", "recollection", - "reccomending", "recommending", - "reccommended", "recommended", - "recepcionist", "receptionist", - "receptionest", "receptionist", - "recgonizable", "recognizable", - "reciporcated", "reciprocate", - "reciprociate", "reciprocate", - "reciprocrate", "reciprocate", - "recognizible", "recognizable", - "recolleciton", "recollection", - "recommanding", "recommending", - "recommendeds", "recommends", - "recommendors", "recommends", - "recommeneded", "recommended", - "recommenting", "recommending", - "recongizable", "recognizable", - "recontructed", "reconstructed", - "recpetionist", "receptionist", - "recreacional", "recreational", - "recriational", "recreational", - "referenceing", "referencing", - "refirgerator", "refrigerator", - "refriderator", "refrigerator", - "refrigarator", "refrigerator", - "refrigerador", "refrigerator", - "refrigerater", "refrigerator", - "refrigirator", "refrigerator", - "regenaration", "regeneration", - "regeneracion", "regeneration", - "regestration", "registration", - "registartion", "registration", - "registrating", "registration", - "regrigerator", "refrigerator", - "regulatorias", "regulators", - "regulatories", "regulators", - "regulatorios", "regulators", - "reicarnation", "reincarnation", - "reinforcemnt", "reinforcement", - "reinitalised", "reinitialised", - "reinitalises", "reinitialises", - "reinitalized", "reinitialized", - "reinitalizes", "reinitializes", - "reinstallled", "reinstalled", - "reisntalling", "reinstalling", - "relaitonship", "relationships", - "relatinoship", "relationships", - "reliabillity", "reliability", - "reluctanctly", "reluctantly", - "remarkablely", "remarkably", - "rememberance", "remembrance", - "reminiscient", "reminiscent", - "renaissaince", "renaissance", - "renegeration", "regeneration", - "reorganision", "reorganisation", - "repalcements", "replacements", - "repersenting", "representing", - "reporduction", "reproduction", - "reporductive", "reproductive", - "reprecussion", "repercussions", - "representate", "representative", - "represention", "representing", - "representive", "representative", - "reproducable", "reproducible", - "reproduccion", "reproduction", - "reproduciton", "reproduction", - "reproducting", "reproduction", - "reproductivo", "reproduction", - "reproduktion", "reproduction", - "repsectfully", "respectfully", - "repsectively", "respectively", - "republicanas", "republicans", - "republicanos", "republicans", - "republicants", "republicans", - "republicians", "republicans", - "requerimento", "requirement", - "requeriments", "requirements", - "requierments", "requirements", - "requriements", "requirements", - "resembelance", "resemblance", - "reseptionist", "receptionist", - "reserrection", "resurrection", - "resintalling", "reinstalling", - "resistancies", "resistances", - "resistencias", "resistances", - "respecitvely", "respectively", - "respectabile", "respectable", - "respectivily", "respectively", - "respectivley", "respectively", - "respectuflly", "respectfully", - "respiratiory", "respiratory", - "responsabile", "responsible", - "responsaveis", "responsive", - "responsbilty", "responsibly", - "responsibile", "responsible", - "responsibily", "responsibility", - "responsibley", "responsibly", - "responsibliy", "responsibly", - "responsiblty", "responsibly", - "ressemblance", "resemblance", - "ressemblence", "resemblance", - "ressurection", "resurrection", - "restaurantes", "restaurants", - "restauration", "restoration", - "restauraunts", "restaurants", - "restirctions", "restrictions", - "restrainting", "restraining", - "restrcitions", "restriction", - "restricitons", "restrictions", - "resurreccion", "resurrection", - "resurrektion", "resurrection", - "retalitation", "retaliation", - "retributioon", "retribution", - "retroactivly", "retroactively", - "revolutionay", "revolutionary", - "revolutionos", "revolutions", - "rezurrection", "resurrection", - "rictatorship", "dictatorship", - "ridicilously", "ridiculously", - "ridicoulusly", "ridiculously", - "righteouness", "righteousness", - "rockerfeller", "rockefeller", - "rollercoaser", "rollercoaster", - "rollercoater", "rollercoaster", - "romanitcally", "romantically", - "roundabounts", "roundabout", - "rudimentatry", "rudimentary", - "rysurrection", "resurrection", - "sacksonville", "jacksonville", - "sacreligious", "sacrilegious", - "sacrificeing", "sacrificing", - "saksatchewan", "saskatchewan", - "salughtering", "slaughtering", - "sanctionning", "sanctioning", - "sarcasticaly", "sarcastically", - "sarcasticlly", "sarcastically", - "sascatchewan", "saskatchewan", - "saskatcehwan", "saskatchewan", - "saskatchawan", "saskatchewan", - "saskatechwan", "saskatchewan", - "sasketchawan", "saskatchewan", - "sasketchewan", "saskatchewan", - "sasktachewan", "saskatchewan", - "satasfaction", "satisfaction", - "satasfactory", "satisfactory", - "satisfaccion", "satisfaction", - "satisfacting", "satisfaction", - "satisfcation", "satisfaction", - "satisfiction", "satisfaction", - "satistactory", "satisfactory", - "satsifaction", "satisfaction", - "satsifactory", "satisfactory", - "scandanivian", "scandinavian", - "scandenavian", "scandinavian", - "scandianvian", "scandinavian", - "scandinacian", "scandinavian", - "scandinaivan", "scandinavia", - "scandinavica", "scandinavian", - "scandinavien", "scandinavian", - "scandinavion", "scandinavian", - "scandivanian", "scandinavian", - "scandonavian", "scandinavian", - "schizophrena", "schizophrenia", - "scholarhsips", "scholarships", - "scholerships", "scholarships", - "scholorships", "scholarships", - "scnadinavian", "scandinavian", - "screenshoots", "screenshot", - "sensationail", "sensational", - "sensationnal", "sensational", - "sensibilites", "sensibilities", - "sensitivitiy", "sensitivity", - "sentimentals", "sentiments", - "sertificates", "certificates", - "serveillance", "surveillance", - "seskatchewan", "saskatchewan", - "shakesperean", "shakespeare", - "shamelessely", "shamelessly", - "shamelessley", "shamelessly", - "shampionship", "championship", - "shardholders", "shareholders", - "shenanigains", "shenanigans", - "shenanigangs", "shenanigans", - "shenaniganns", "shenanigans", - "shenanighans", "shenanigans", - "shopkeeepers", "shopkeepers", - "showboarding", "snowboarding", - "siginificant", "significant", - "significanly", "significantly", - "significante", "significance", - "significanty", "significantly", - "significatly", "significantly", - "signleplayer", "singleplayer", - "simaltaneous", "simultaneous", - "simeltaneous", "simultaneous", - "similaraties", "similarities", - "similiarites", "similarities", - "similiarties", "similarities", - "similiraties", "similarities", - "similtaneous", "simultaneous", - "simliarities", "similarities", - "simlutaneous", "simultaneous", - "simpathizers", "sympathizers", - "simplistisch", "simplistic", - "simulatenous", "simultaneous", - "simulatneous", "simultaneous", - "simultaenous", "simultaneous", - "simultaneuos", "simultaneous", - "simultanious", "simultaneous", - "simulteneous", "simultaneous", - "singelplayer", "singleplayer", - "singlepalyer", "singleplayer", - "sinlgeplayer", "singleplayer", - "situationals", "situations", - "situationnal", "situational", - "skandinavian", "scandinavian", - "skateboaring", "skateboarding", - "skrawberries", "strawberries", - "slaugthering", "slaughtering", - "sloughtering", "slaughtering", - "sluaghtering", "slaughtering", - "snowballling", "snowballing", - "snowbaording", "snowboarding", - "socialistisk", "socialists", - "socialogical", "sociological", - "socioeconimc", "socioeconomic", - "socioeconmic", "socioeconomic", - "socioligical", "sociological", - "sociopolical", "sociological", - "somethingest", "somethings", - "sophisticaed", "sophisticated", - "sophisticted", "sophisticated", - "southamption", "southampton", - "southernerns", "southerners", - "sovereighnty", "sovereignty", - "sovereignety", "sovereignty", - "sovereignity", "sovereignty", - "specialistes", "specialists", - "specializare", "specialize", - "specializate", "specialize", - "specializeds", "specializes", - "specializied", "specialize", - "speciallized", "specialised", - "specifcation", "specification", - "spectacuarly", "spectacular", - "spectaculair", "spectacular", - "spectaculary", "spectacularly", - "spectacullar", "spectacularly", - "specualtions", "speculation", - "spermatozoan", "spermatozoon", - "spesifically", "specifically", - "spirituallly", "spiritually", - "spirtiuality", "spirituality", - "spirutuality", "spirituality", - "spontaneosly", "spontaneously", - "spontaneouly", "spontaneously", - "spreadhseets", "spreadsheets", - "spreadsheats", "spreadsheets", - "spreadsheeds", "spreadsheets", - "spreadsheeet", "spreadsheets", - "standartized", "standardized", - "standerdized", "standardized", - "stardardized", "standardized", - "starightened", "straightened", - "starwberries", "strawberries", - "statisticaly", "statistically", - "stereotpying", "stereotyping", - "stereotypers", "stereotypes", - "stereotypian", "stereotyping", - "steriotyping", "stereotyping", - "steroetyping", "stereotyping", - "steryotyping", "stereotyping", - "straigntened", "straightened", - "straigthened", "straightened", - "strategicaly", "strategically", - "strategiclly", "strategically", - "strawburries", "strawberries", - "streemlining", "streamlining", - "streightened", "straightened", - "strenghening", "strengthening", - "strenghtened", "strengthened", - "strengtheing", "strengthening", - "stroytelling", "storytelling", - "subconcsious", "subconscious", - "subconsicous", "subconscious", - "subcouncious", "subconscious", - "subcsription", "subscriptions", - "subesquently", "subsequently", - "subjectivety", "subjectively", - "subjectivily", "subjectively", - "subjectivley", "subjectively", - "subjudgation", "subjugation", - "subredditors", "subreddits", - "subscirption", "subscriptions", - "subsconcious", "subconscious", - "subscribbers", "subscribers", - "subscribbing", "subscribing", - "subscribirse", "subscriber", - "subscribtion", "subscription", - "subscriptons", "subscriptions", - "subscritpion", "subscriptions", - "subscrpition", "subscriptions", - "subsiquently", "subsequently", - "subsrciption", "subscriptions", - "subsricption", "subscriptions", - "substantialy", "substantially", - "substantitve", "substantive", - "substitition", "substitution", - "substituters", "substitutes", - "substitutivo", "substitution", - "substitutues", "substitutes", - "substracting", "subtracting", - "substraction", "subtraction", - "subterranian", "subterranean", - "succsessfull", "successful", - "sunconscious", "subconscious", - "supermarkeds", "supermarkets", - "supermarkers", "supermarkets", - "supermarkert", "supermarkets", - "supermarkten", "supermarket", - "supermarktes", "supermarkets", - "supernarkets", "supermarkets", - "supernatrual", "supernatural", - "supersticion", "superstition", - "superstision", "superstition", - "superstitios", "superstitious", - "superstitous", "superstitious", - "supervisiors", "supervisors", - "supervisoras", "supervisors", - "supervisores", "supervisors", - "supllemental", "supplemental", - "supplamental", "supplemental", - "supplamented", "supplemented", - "supplimental", "supplemental", - "suppresssion", "suppression", - "supscription", "subscription", - "supsiciously", "suspiciously", - "surprizingly", "surprisingly", - "surrenderred", "surrendered", - "surrundering", "surrendering", - "survaillance", "surveillance", - "survaillence", "surveillance", - "survallience", "surveillance", - "surveillence", "surveillance", - "survelliance", "surveillance", - "surviellance", "surveillance", - "survivabiity", "survivability", - "survivabiliy", "survivability", - "survivabilty", "survivability", - "susceptiable", "susceptible", - "susceptibile", "susceptible", - "suspeciously", "suspiciously", - "suspicioulsy", "suspiciously", - "suspiciuosly", "suspiciously", - "suspisiously", "suspiciously", - "sustainabily", "sustainability", - "symapthizers", "sympathizers", - "symetrically", "symmetrically", - "symmetricaly", "symmetrically", - "sympathethic", "sympathetic", - "sympathsizer", "sympathizers", - "sympathyzers", "sympathizers", - "sympethizers", "sympathizers", - "symphatizers", "sympathizers", - "sympithizers", "sympathizers", - "syncronously", "synchronously", - "sysmatically", "systematically", - "systematisch", "systematic", - "tablespooons", "tablespoon", - "tacticallity", "tactically", - "tangencially", "tangentially", - "tangenitally", "tangentially", - "tangientally", "tangentially", - "teamfighters", "teamfights", - "teansylvania", "transylvania", - "techanically", "mechanically", - "techincality", "technicality", - "technologial", "technological", - "telelevision", "television", - "teleportaion", "teleportation", - "teleportaton", "teleportation", - "temepratures", "temperatures", - "temparatures", "temperatures", - "temperaturas", "temperatures", - "temporarilly", "temporarily", - "tempreatures", "temperatures", - "tempuratures", "temperatures", - "tengentially", "tangentially", - "termendously", "tremendously", - "territorrial", "territorial", - "territorries", "territories", - "testasterone", "testosterone", - "testestorone", "testosterone", - "thanskgiving", "thanksgiving", - "theologicial", "theological", - "theoreticaly", "theoretically", - "thermomenter", "thermometer", - "thermomether", "thermometer", - "thumbnailers", "thumbnails", - "thunderboldt", "thunderbolt", - "tindergarten", "kindergarten", - "torubleshoot", "troubleshoot", - "totalitarion", "totalitarian", - "totalitatian", "totalitarian", - "touchscreeen", "touchscreen", - "traditionaly", "traditionally", - "traditionnal", "traditional", - "tradtionally", "traditionally", - "tramendously", "tremendously", - "tramsformers", "transformers", - "tramsforming", "transforming", - "tranditional", "transitional", - "tranistional", "transitional", - "tranistioned", "transitioned", - "tranlsations", "translations", - "tranmsission", "transmissions", - "transaltions", "translations", - "transaprency", "transparency", - "transational", "transitional", - "transcations", "transactions", - "transcendant", "transcendent", - "transcripton", "transcription", - "transcriptus", "transcripts", - "transesxuals", "transsexuals", - "transfarmers", "transformers", - "transfarring", "transferring", - "transferrred", "transferred", - "transformare", "transformers", - "transformase", "transforms", - "transformees", "transforms", - "transforners", "transformers", - "transfromers", "transformers", - "transfroming", "transforming", - "transgenderd", "transgendered", - "transgendred", "transgendered", - "transgenered", "transgender", - "transicional", "transitional", - "transilvania", "transylvania", - "transimssion", "transmissions", - "transisioned", "transitioned", - "translastion", "translations", - "translateing", "translating", - "translationg", "translating", - "translucient", "translucent", - "translyvania", "transylvania", - "transmisions", "transmission", - "transmisison", "transmission", - "transmissons", "transmissions", - "transmitirte", "transmitter", - "transmittted", "transmitted", - "transmorfers", "transformer", - "transofrmers", "transformers", - "transofrming", "transforming", - "transparancy", "transparency", - "transparenty", "transparency", - "transparrent", "transparent", - "transperancy", "transparency", - "transperency", "transparency", - "transplantes", "transplants", - "transporteur", "transporter", - "transportion", "transporting", - "transpotting", "transporting", - "transsmision", "transmissions", - "transylmania", "transylvania", - "transylvanai", "transylvania", - "trasnferring", "transferring", - "trasnformers", "transformers", - "trasnforming", "transforming", - "trasnmission", "transmissions", - "trasnparency", "transparency", - "trasnporting", "transporting", - "trememdously", "tremendously", - "tremendoulsy", "tremendously", - "tremondously", "tremendously", - "troubelshoot", "troubleshoot", - "troublehsoot", "troubleshoot", - "trumendously", "tremendously", - "trustworthly", "trustworthy", - "ubsubscribed", "unsubscribed", - "udnerpowered", "underpowered", - "umbelievable", "unbelievable", - "umemployment", "unemployment", - "unaccaptable", "unacceptable", - "unacceptible", "unacceptable", - "unaccpetable", "unacceptable", - "unacompanied", "unaccompanied", - "unappealling", "unappealing", - "unattractice", "unattractive", - "unautherized", "unauthorized", - "unauthroized", "unauthorized", - "unbeleivable", "unbelievable", - "unbeleivably", "unbelievably", - "unbeliavable", "unbelievable", - "unbeliavably", "unbelievably", - "unbeliebable", "unbelievable", - "unbelieveble", "unbelievable", - "unbelievibly", "unbelievably", - "unbeliveable", "unbelievable", - "unbeliveably", "unbelievably", - "unbelizeable", "unbelievable", - "unbolievable", "unbelievable", - "uncertainity", "uncertainty", - "uncertaintly", "uncertainty", - "uncompatible", "incompatible", - "unconditinal", "unconditional", - "unconsciosly", "unconsciously", - "unconsciouly", "unconsciously", - "unconsistent", "inconsistent", - "unconvenient", "inconvenient", - "unconvential", "unconventional", - "undecideable", "undecidable", - "undefinitely", "indefinitely", - "undeniablely", "undeniably", - "undergradate", "undergraduate", - "undergradute", "undergraduate", - "underminding", "undermining", - "undermineing", "undermining", - "undermineras", "undermines", - "undermineres", "undermines", - "underminging", "undermining", - "underminning", "undermining", - "undertakeing", "undertaking", - "underwhelimg", "underwhelming", - "underwheling", "underwhelming", - "undesireable", "undesirable", - "undoubtedbly", "undoubtedly", - "unemployemnt", "unemployment", - "unemplyoment", "unemployment", - "unempolyment", "unemployment", - "unenployment", "unemployment", - "unequalities", "inequalities", - "unexpectadly", "unexpectedly", - "unexpectetly", "unexpectedly", - "unexpectidly", "unexpectedly", - "unexperience", "inexperience", - "unexpextedly", "unexpectedly", - "unexplicably", "inexplicably", - "unforgetable", "unforgettable", - "unforgiveble", "unforgivable", - "unforgivible", "unforgivable", - "unfortunatly", "unfortunately", - "unfortunetly", "unfortunately", - "unilatreally", "unilaterally", - "uniliterally", "unilaterally", - "unimpresssed", "unimpressed", - "uninitalised", "uninitialised", - "uninitalized", "uninitialized", - "uninstallimg", "uninstalling", - "uninstallled", "uninstalled", - "unintentinal", "unintentional", - "uninteresing", "uninteresting", - "uninterneted", "uninterested", - "uninterruped", "uninterrupted", - "uninterupted", "uninterrupted", - "unisntalling", "uninstalling", - "unitesstates", "unitedstates", - "univerisites", "universities", - "univeristies", "universities", - "universitets", "universities", - "unliaterally", "unilaterally", - "unneccessary", "unnecessary", - "unnecesarily", "unnecessarily", - "unnecessairy", "unnecessarily", - "unnecessarly", "unnecessarily", - "unnistalling", "uninstalling", - "unpredictabe", "unpredictable", - "unpreductive", "unproductive", - "unproduktive", "unproductive", - "unrealisitic", "unrealistic", - "unreaponsive", "unresponsive", - "unreasonalby", "unreasonably", - "unrepsonsive", "unresponsive", - "unresponcive", "unresponsive", - "unresponisve", "unresponsive", - "unresponsibe", "unresponsive", - "unrestircted", "unrestricted", - "unrestrcited", "unrestricted", - "unristricted", "unrestricted", - "unseccessful", "unsuccessful", - "unsespecting", "unsuspecting", - "unsibscribed", "unsubscribed", - "unsoliciated", "unsolicited", - "unsolicitied", "unsolicited", - "unsubscirbed", "unsubscribed", - "unsubscrible", "unsubscribed", - "unsubscrided", "unsubscribed", - "unsubscriped", "unsubscribed", - "unsubscrubed", "unsubscribed", - "unsubsrcibed", "unsubscribed", - "unsucessfull", "unsuccessful", - "unsunscribed", "unsubscribed", - "unsurprizing", "unsurprising", - "unsusbcribed", "unsubscribed", - "unsustainble", "unsustainable", - "unvelievable", "unbelievable", - "unvelievably", "unbelievably", - "unviersities", "universities", - "unvulnerable", "invulnerable", - "varification", "verification", - "vegetarianas", "vegetarians", - "vegetarianos", "vegetarians", - "verficiation", "verification", - "verificacion", "verification", - "verificaiton", "verification", - "verifikation", "verification", - "vernaculaire", "vernacular", - "versatillity", "versatility", - "verticallity", "vertically", - "videogamemes", "videogames", - "visualizaton", "visualization", - "vocabularily", "vocabulary", - "vocabularity", "vocabulary", - "volonteering", "volunteering", - "volounteered", "volunteered", - "voluntarilly", "voluntarily", - "volunterring", "volunteering", - "vulnerabilty", "vulnerability", - "weightlifing", "weightlifting", - "withdrawalls", "withdrawals", - "withdrawling", "withdrawing", - "withdrawning", "withdrawing", - "wonderfullly", "wonderfully", - "worshippping", "worshipping", - "xenophobical", "xenophobia", - "abandenment", "abandonment", - "abandomnent", "abandonment", - "abandonding", "abandoning", - "abandonnent", "abandonment", - "abandonning", "abandoning", - "abbreviatin", "abbreviation", - "abbreviaton", "abbreviation", - "abdominable", "abdominal", - "abomanation", "abomination", - "abominacion", "abomination", - "abomonation", "abomination", - "abonimation", "abomination", - "aboriginial", "aboriginal", - "aborigional", "aboriginal", - "abreviation", "abbreviation", - "abritrarily", "arbitrarily", - "abritration", "arbitration", - "absolutelly", "absolutely", - "absolutelys", "absolutes", - "absolutisme", "absolutes", - "absolutiste", "absolutes", - "abstraccion", "abstraction", - "abstraktion", "abstraction", - "abstruction", "abstraction", - "abundancies", "abundances", - "academicaly", "academically", - "academicese", "academics", - "accelarated", "accelerated", - "accelarator", "accelerator", - "accelerater", "accelerator", - "acceleratie", "accelerate", - "acceleratio", "accelerator", - "acceleraton", "acceleration", - "accelorated", "accelerated", - "accelorator", "accelerator", - "acceptabelt", "acceptable", - "accesseries", "accessories", - "accessibile", "accessible", - "accessibily", "accessibility", - "accessoires", "accessories", - "accidantely", "accidentally", - "accidentaly", "accidentally", - "accidentely", "accidentally", - "accidential", "accidental", - "accidentily", "accidentally", - "accidentlay", "accidentally", - "accidentley", "accidentally", - "accidentlly", "accidentally", - "accomadated", "accommodated", - "accomadates", "accommodates", - "accommadate", "accommodate", - "accommidate", "accommodate", - "accomodated", "accommodated", - "accomodates", "accommodates", - "accomondate", "accommodate", - "accompained", "accompanied", - "accompanyed", "accompanied", - "accompianed", "accompanied", - "accompinied", "accompanied", - "accomplises", "accomplishes", - "accomplishs", "accomplishes", - "accomponied", "accompanied", - "accountatns", "accountants", - "accountents", "accountants", - "accquainted", "acquainted", - "accrediated", "accredited", - "accreditied", "accredited", - "accreditted", "accredited", - "acculumated", "accumulated", - "accumalated", "accumulated", - "accumelated", "accumulated", - "accumilated", "accumulated", - "accumulatin", "accumulation", - "accumulaton", "accumulation", - "accuratelly", "accurately", - "accustommed", "accustomed", - "acheivement", "achievement", - "acheivments", "achievements", - "achievemint", "achievement", - "achievemnts", "achievements", - "achievments", "achievements", - "achivements", "achievements", - "acknolwedge", "acknowledge", - "acknoweldge", "acknowledge", - "acknowleded", "acknowledged", - "acknowlegde", "acknowledge", - "acknowleged", "acknowledge", - "acknowleges", "acknowledges", - "acknwoledge", "acknowledges", - "acomplished", "accomplished", - "acopalyptic", "apocalyptic", - "acquaintace", "acquaintance", - "acquisation", "acquisition", - "activateing", "activating", - "activationg", "activating", - "activistion", "activision", - "additinally", "additionally", - "additionaly", "additionally", - "additonally", "additionally", - "adequatedly", "adequately", - "adjectiveus", "adjectives", - "administerd", "administered", - "administrar", "administrator", - "administren", "administer", - "administrer", "administer", - "administres", "administer", - "administrez", "administer", - "adminstered", "administered", - "adminstrate", "administrate", - "admittadely", "admittedly", - "adolencence", "adolescence", - "adolescance", "adolescence", - "adolescense", "adolescence", - "advantadges", "advantages", - "advantageos", "advantageous", - "advantageus", "advantageous", - "advantagous", "advantageous", - "adventerous", "adventures", - "adventourus", "adventurous", - "adversiting", "advertising", - "advertisors", "advertisers", - "advertisted", "advertised", - "aesthethics", "aesthetics", - "afficionado", "aficionado", - "affiliction", "affiliation", - "affirmitave", "affirmative", - "affirmitive", "affirmative", - "affixiation", "affiliation", - "affrimative", "affirmative", - "afgahnistan", "afghanistan", - "afganhistan", "afghanistan", - "afghanastan", "afghanistan", - "afghansitan", "afghanistan", - "afhganistan", "afghanistan", - "afternarket", "aftermarket", - "afterthougt", "afterthought", - "aggaravates", "aggravates", - "aggragating", "aggravating", - "aggregatore", "aggregate", - "aggressivly", "aggressively", - "aggresssion", "aggression", - "aggrovating", "aggravating", - "agnostacism", "agnosticism", - "agnostisicm", "agnosticism", - "agnostisism", "agnosticism", - "agnostocism", "agnosticism", - "agnsoticism", "agnosticism", - "agonsticism", "agnosticism", - "agressively", "aggressively", - "agressivley", "aggressive", - "agressivnes", "aggressive", - "agricolture", "agriculture", - "agriculteur", "agriculture", - "agricultral", "agricultural", - "agricultual", "agricultural", - "agricutlure", "agriculture", - "ahtleticism", "athleticism", - "alcoholicas", "alcoholics", - "alcoholicos", "alcoholics", - "alcoholisim", "alcoholism", - "algorithems", "algorithm", - "algorithims", "algorithm", - "algorithmes", "algorithms", - "algorithmns", "algorithms", - "algorithmus", "algorithms", - "algorithyms", "algorithm", - "algorythims", "algorithms", - "alientating", "alienating", - "alleigances", "allegiance", - "alltogether", "altogether", - "alterantive", "alternative", - "alternatley", "alternately", - "alternitive", "alternative", - "altheticism", "athleticism", - "altnerately", "alternately", - "altruisitic", "altruistic", - "altruistric", "altruistic", - "amalgomated", "amalgamated", - "ambulancier", "ambulance", - "amerliorate", "ameliorate", - "ammendments", "amendments", - "ampehtamine", "amphetamine", - "ampethamine", "amphetamine", - "amphetamies", "amphetamines", - "amphetamins", "amphetamines", - "amphetemine", "amphetamine", - "amphetimine", "amphetamine", - "amphetmaine", "amphetamines", - "analyticals", "analytics", - "anarchistes", "anarchists", - "ancedotally", "anecdotally", - "androgenous", "androgynous", - "anecdatally", "anecdotally", - "anecdotelly", "anecdotally", - "anecodtally", "anecdotally", - "anectodally", "anecdotally", - "anectotally", "anecdotally", - "anedoctally", "anecdotally", - "angosticism", "agnosticism", - "anihilation", "annihilation", - "anitbiotics", "antibiotics", - "annihalated", "annihilated", - "annihilaton", "annihilation", - "annihilited", "annihilated", - "annihliated", "annihilated", - "annilihated", "annihilated", - "anniversery", "anniversary", - "annonymouse", "anonymous", - "announceing", "announcing", - "announcemet", "announcement", - "announcemnt", "announcement", - "announcents", "announces", - "annoymously", "anonymously", - "anonamously", "anonymously", - "anonimously", "anonymously", - "anonmyously", "anonymously", - "anonomously", "anonymously", - "anonymousny", "anonymously", - "anouncement", "announcement", - "antagonisic", "antagonistic", - "antagonistc", "antagonistic", - "antagonstic", "antagonist", - "anthropolgy", "anthropology", - "anthropoloy", "anthropology", - "antibiodics", "antibiotics", - "antibioitcs", "antibiotic", - "antibioitic", "antibiotic", - "antibitoics", "antibiotics", - "antiboitics", "antibiotics", - "anticapated", "anticipated", - "anticiapted", "anticipated", - "anticipatin", "anticipation", - "antiobitics", "antibiotic", - "antiquaited", "antiquated", - "antisipated", "anticipated", - "apacolyptic", "apocalyptic", - "apocaliptic", "apocalyptic", - "apocalpytic", "apocalyptic", - "apocalytpic", "apocalyptic", - "apolagizing", "apologizing", - "apolegetics", "apologetics", - "apologistas", "apologists", - "apologistes", "apologists", - "apostrophie", "apostrophe", - "apparantely", "apparently", - "appareances", "appearances", - "apparentely", "apparently", - "appartments", "apartments", - "appeareance", "appearance", - "appearences", "appearances", - "apperciated", "appreciated", - "apperciates", "appreciates", - "appereances", "appearances", - "applicabile", "applicable", - "applicaiton", "application", - "applicatins", "applicants", - "applicatons", "applications", - "appoitnment", "appointments", - "apporaching", "approaching", - "apporpriate", "appropriate", - "apporximate", "approximate", - "appraoching", "approaching", - "apprearance", "appearance", - "apprecaited", "appreciated", - "apprecaites", "appreciates", - "appreciaite", "appreciative", - "appreciatie", "appreciative", - "appreciatin", "appreciation", - "appreciaton", "appreciation", - "appreciatve", "appreciative", - "appreicated", "appreciated", - "appreicates", "appreciates", - "apprentince", "apprentice", - "appriciated", "appreciated", - "appriciates", "appreciates", - "apprieciate", "appreciate", - "appropirate", "appropriate", - "appropraite", "appropriate", - "appropriato", "appropriation", - "approxamate", "approximate", - "approxiamte", "approximate", - "approxmiate", "approximate", - "aprehensive", "apprehensive", - "apsirations", "aspirations", - "aqcuisition", "acquisition", - "aquaintance", "acquaintance", - "aquiantance", "acquaintance", - "arbitrairly", "arbitrarily", - "arbitralily", "arbitrarily", - "arbitrarely", "arbitrarily", - "arbitrarion", "arbitration", - "arbitratily", "arbitrarily", - "arbritarily", "arbitrarily", - "arbritation", "arbitration", - "arcaheology", "archaeology", - "archaoelogy", "archeology", - "archeaology", "archaeology", - "archimedian", "archimedean", - "architechts", "architects", - "architectes", "architects", - "architecure", "architecture", - "archtecture", "architecture", - "argiculture", "agriculture", - "argumentate", "argumentative", - "aribtrarily", "arbitrarily", - "aribtration", "arbitration", - "arithmentic", "arithmetic", - "arithmethic", "arithmetic", - "arithmetric", "arithmetic", - "armagedddon", "armageddon", - "armageddeon", "armageddon", - "arrangments", "arrangements", - "arrengement", "arrangement", - "articluated", "articulated", - "articualted", "articulated", - "artifically", "artificially", - "artificialy", "artificially", - "aspergerers", "aspergers", - "asphyxation", "asphyxiation", - "aspriations", "aspirations", - "assasinated", "assassinated", - "assasinates", "assassinates", - "assassiante", "assassinate", - "assassinare", "assassinate", - "assassinatd", "assassinated", - "assassinato", "assassination", - "assassinats", "assassins", - "assassinted", "assassinated", - "assembleing", "assembling", - "assemblying", "assembling", - "assertation", "assertion", - "assignemnts", "assignments", - "assimialted", "assimilate", - "assimilatie", "assimilate", - "assimilerat", "assimilate", - "assimiliate", "assimilate", - "assimliated", "assimilate", - "assingments", "assignments", - "assistantes", "assistants", - "assocaition", "associations", - "associaiton", "associations", - "associaties", "associates", - "associatons", "associations", - "assoication", "association", - "assosiating", "associating", - "assosiation", "association", - "assoziation", "association", - "assumptious", "assumptions", - "astonashing", "astonishing", - "astonoshing", "astonishing", - "astronaught", "astronaut", - "astronaunts", "astronaut", - "astronautas", "astronauts", - "astronautes", "astronauts", - "asychronous", "asynchronous", - "asyncronous", "asynchronous", - "atatchments", "attachments", - "atheistisch", "atheistic", - "athelticism", "athleticism", - "athletecism", "athleticism", - "athleticsim", "athleticism", - "athletisicm", "athleticism", - "athletisism", "athleticism", - "atmopsheric", "atmospheric", - "atmoshperic", "atmospheric", - "atmosoheric", "atmospheric", - "atomspheric", "atmospheric", - "atrocitites", "atrocities", - "attachemnts", "attachments", - "attackerasu", "attackers", - "attackerats", "attackers", - "attactments", "attachments", - "attributred", "attributed", - "attributted", "attribute", - "attrocities", "atrocities", - "atttributes", "attributes", - "audiobookas", "audiobooks", - "audioboooks", "audiobook", - "auotcorrect", "autocorrect", - "austrailans", "australians", - "austrailian", "australian", - "australiaan", "australians", - "australiams", "australians", - "australiens", "australians", - "australlian", "australian", - "authenticiy", "authenticity", - "authenticor", "authenticator", - "authenticty", "authenticity", - "authorative", "authoritative", - "authoritate", "authoritative", - "authoroties", "authorities", - "autoatttack", "autoattack", - "autocoreect", "autocorrect", - "autocorrekt", "autocorrect", - "autocorrent", "autocorrect", - "autocorrext", "autocorrect", - "autoctonous", "autochthonous", - "autokorrect", "autocorrect", - "automaticly", "automatically", - "automatonic", "automation", - "automoblies", "automobile", - "auxillaries", "auxiliaries", - "availabiliy", "availability", - "availabilty", "availability", - "availablity", "availability", - "awesoneness", "awesomeness", - "babysittter", "babysitter", - "backbacking", "backpacking", - "backgorunds", "backgrounds", - "backhacking", "backpacking", - "backjacking", "backpacking", - "backtacking", "backpacking", - "bangaldeshi", "bangladesh", - "bangladesch", "bangladesh", - "barceloneta", "barcelona", - "bargainning", "bargaining", - "battelfield", "battlefield", - "battelfront", "battlefront", - "battelships", "battleship", - "battlefeild", "battlefield", - "battlefiend", "battlefield", - "battlefiled", "battlefield", - "battlefornt", "battlefront", - "battlehsips", "battleship", - "beastiality", "bestiality", - "beaurocracy", "bureaucracy", - "beautyfully", "beautifully", - "behaviorial", "behavioral", - "belittleing", "belittling", - "belittlling", "belittling", - "belligerant", "belligerent", - "belligirent", "belligerent", - "bellweather", "bellwether", - "benefitical", "beneficial", - "bestiallity", "bestiality", - "beuatifully", "beautifully", - "beuraucracy", "bureaucracy", - "beuraucrats", "bureaucrats", - "billegerent", "belligerent", - "billionairs", "billionaires", - "billionarie", "billionaire", - "billioniare", "billionaire", - "biologicaly", "biologically", - "birthdayers", "birthdays", - "birthdaymas", "birthdays", - "bittersweat", "bittersweet", - "bitterwseet", "bittersweet", - "blackberrry", "blackberry", - "blacksmitch", "blacksmith", - "bloodboorne", "bloodborne", - "bluebarries", "blueberries", - "blueburries", "blueberries", - "blueprients", "blueprints", - "bodybuildig", "bodybuilding", - "bodybuildng", "bodybuilding", - "bodybuiling", "bodybuilding", - "bombardeada", "bombarded", - "bombardeado", "bombarded", - "bombarderad", "bombarded", - "bordelrands", "borderlands", - "bordlerands", "borderlands", - "bortherhood", "brotherhood", - "bourgeousie", "bourgeois", - "boycottting", "boycotting", - "bracelettes", "bracelets", - "brainwahsed", "brainwashed", - "brainwasing", "brainwashing", - "braziliians", "brazilians", - "breakthough", "breakthrough", - "breakthrouh", "breakthrough", - "breathtakng", "breathtaking", - "brianwashed", "brainwashed", - "brillaintly", "brilliantly", - "broadcasing", "broadcasting", - "broadcastes", "broadcasts", - "broderlands", "borderlands", - "brotherwood", "brotherhood", - "buddhistisk", "buddhists", - "buearucrats", "bureaucrats", - "bueraucracy", "bureaucracy", - "bueraucrats", "bureaucrats", - "buisnessman", "businessman", - "buisnessmen", "businessmen", - "bullerproof", "bulletproof", - "bulletbroof", "bulletproof", - "bulletproff", "bulletproof", - "bulletprrof", "bulletproof", - "bullitproof", "bulletproof", - "bureacuracy", "bureaucracy", - "bureaocracy", "bureaucracy", - "bureaocrats", "bureaucrats", - "bureaucraps", "bureaucrats", - "bureaucrash", "bureaucrats", - "bureaucrasy", "bureaucrats", - "bureaucrazy", "bureaucracy", - "bureuacracy", "bureaucracy", - "bureuacrats", "bureaucrats", - "burueacrats", "bureaucrats", - "businessnes", "businessmen", - "busniessmen", "businessmen", - "butterfiles", "butterflies", - "butterfleye", "butterfly", - "butterflyes", "butterflies", - "butterfries", "butterflies", - "butterlfies", "butterflies", - "caclulating", "calculating", - "caclulation", "calculation", - "caclulators", "calculators", - "cailbration", "calibration", - "calbiration", "calibration", - "calcualting", "calculating", - "calcualtion", "calculations", - "calcualtors", "calculators", - "calculaters", "calculators", - "calculatios", "calculators", - "calculatons", "calculations", - "calibartion", "calibration", - "calibraiton", "calibration", - "califorinan", "californian", - "californain", "californian", - "californica", "california", - "californien", "californian", - "californiia", "californian", - "californina", "californian", - "californnia", "californian", - "califronian", "californian", - "caluclating", "calculating", - "caluclation", "calculation", - "caluclators", "calculators", - "caluculated", "calculated", - "caluiflower", "cauliflower", - "camouflague", "camouflage", - "camouflauge", "camouflage", - "campagining", "campaigning", - "campainging", "campaigning", - "canadianese", "canadians", - "cannabilism", "cannibalism", - "cannabolism", "cannibalism", - "canniablism", "cannibalism", - "cannibalizm", "cannibalism", - "cannibaljim", "cannibalism", - "cannibalsim", "cannibalism", - "cannibilism", "cannibalism", - "cannobalism", "cannibalism", - "cannotation", "connotation", - "capabilites", "capabilities", - "capabilitiy", "capability", - "capabillity", "capability", - "capacitaron", "capacitor", - "capacitores", "capacitors", - "capatilists", "capitalists", - "capatilized", "capitalized", - "caperbility", "capability", - "capitalisim", "capitalism", - "capitilists", "capitalists", - "capitilized", "capitalized", - "capitolists", "capitalists", - "capitolized", "capitalized", - "captialists", "capitalists", - "captialized", "capitalized", - "cariactures", "caricature", - "carniverous", "carnivorous", - "castatrophe", "catastrophe", - "catagorized", "categorized", - "catapillars", "caterpillars", - "catapillers", "caterpillars", - "catasthrope", "catastrophe", - "catastraphe", "catastrophe", - "catastrohpe", "catastrophe", - "catastropic", "catastrophic", - "categroized", "categorized", - "catepillars", "caterpillars", - "catergorize", "categorize", - "caterogized", "categorized", - "caterpilars", "caterpillars", - "caterpiller", "caterpillar", - "catholacism", "catholicism", - "catholicsim", "catholicism", - "catholisicm", "catholicism", - "catholisism", "catholicism", - "catholizism", "catholicism", - "catholocism", "catholicism", - "catogerized", "categorized", - "catterpilar", "caterpillar", - "cauilflower", "cauliflower", - "caulfilower", "cauliflower", - "celebartion", "celebrations", - "celebirties", "celebrities", - "celebracion", "celebration", - "celebrasion", "celebrations", - "celebratons", "celebrations", - "centipeddle", "centipede", - "cerimonious", "ceremonious", - "certaintity", "certainty", - "certificaat", "certificate", - "certificare", "certificate", - "certificato", "certification", - "certificats", "certificates", - "challanging", "challenging", - "challeneged", "challenged", - "challeneger", "challenger", - "challeneges", "challenges", - "chameleooon", "chameleon", - "championshp", "championship", - "championsip", "championship", - "chancellour", "chancellor", - "charachters", "characters", - "charasmatic", "charismatic", - "charimastic", "charismatic", - "charsimatic", "charismatic", - "cheerleadra", "cheerleader", - "cheerleards", "cheerleaders", - "cheerleeder", "cheerleader", - "cheesebuger", "cheeseburger", - "cheeseburgs", "cheeseburgers", - "chihuahuita", "chihuahua", - "childrenmrs", "childrens", - "chloesterol", "cholesterol", - "cholesteral", "cholesterol", - "cholestoral", "cholesterol", - "cholestorol", "cholesterol", - "cholosterol", "cholesterol", - "chormosomes", "chromosomes", - "christianty", "christianity", - "chromasomes", "chromosomes", - "chromesomes", "chromosomes", - "chromisomes", "chromosomes", - "chromosones", "chromosomes", - "chromossome", "chromosomes", - "chromozomes", "chromosomes", - "chronicales", "chronicles", - "chronichles", "chronicles", - "cicrulating", "circulating", - "cincinnasti", "cincinnati", - "cincinnatti", "cincinnati", - "cincinnnati", "cincinnati", - "circimcised", "circumcised", - "circluating", "circulating", - "circualtion", "circulation", - "circulacion", "circulation", - "circumcison", "circumcision", - "circumsiced", "circumcised", - "circumsised", "circumcised", - "circumstace", "circumstance", - "circumvrent", "circumvent", - "circuncised", "circumcised", - "cirticising", "criticising", - "ciruclating", "circulating", - "ciruclation", "circulation", - "citicenship", "citizenship", - "citisenship", "citizenship", - "citizinship", "citizenship", - "civilizatin", "civilizations", - "civilizaton", "civilization", - "claculators", "calculators", - "classifides", "classified", - "cleanilness", "cleanliness", - "cleanleness", "cleanliness", - "cleanlyness", "cleanliness", - "cleansiness", "cleanliness", - "cliffbanger", "cliffhanger", - "cliffhander", "cliffhanger", - "cliffhangar", "cliffhanger", - "clifthanger", "cliffhanger", - "cockaroches", "cockroaches", - "cockraoches", "cockroaches", - "cockroackes", "cockroaches", - "cocktailers", "cocktails", - "coefficeint", "coefficient", - "coefficiant", "coefficient", - "coincedince", "coincidence", - "coincidance", "coincidence", - "coincidense", "coincidence", - "coincidente", "coincidence", - "coincidince", "coincidence", - "coinsidence", "coincidence", - "collabarate", "collaborate", - "collaberate", "collaborate", - "collaborant", "collaborate", - "collaborare", "collaborate", - "collaborato", "collaboration", - "collapseing", "collapsing", - "collaterial", "collateral", - "collectieve", "collective", - "collectivly", "collectively", - "collectivos", "collections", - "collobarate", "collaborate", - "colloborate", "collaborate", - "colonializm", "colonialism", - "colonialsim", "colonialism", - "colonianism", "colonialism", - "colonizaton", "colonization", - "comaprisons", "comparisons", - "combiantion", "combinations", - "combinacion", "combination", - "combinaison", "combinations", - "combinaiton", "combinations", - "combinatino", "combinations", - "combinatins", "combinations", - "combinatios", "combinations", - "combinining", "combining", - "combonation", "combination", - "comediantes", "comedians", - "comeptition", "competition", - "comeptitive", "competitive", - "comeptitors", "competitors", - "comfertable", "comfortable", - "comfertably", "comfortably", - "comfortabel", "comfortably", - "comfortabil", "comfortably", - "comfrotable", "comfortable", - "comftorable", "comfortable", - "comftorably", "comfortably", - "comisioning", "commissioning", - "comissioned", "commissioned", - "comissioner", "commissioner", - "commandered", "commanded", - "commandmant", "commandment", - "commantator", "commentator", - "commendment", "commandment", - "commentarea", "commenter", - "commentaren", "commenter", - "commentater", "commentator", - "commenteers", "commenter", - "commentries", "commenters", - "commercialy", "commercially", - "commericals", "commercials", - "commericial", "commercial", - "comminicate", "communicate", - "comminucate", "communicate", - "commisioned", "commissioned", - "commisioner", "commissioner", - "commisssion", "commissions", - "committment", "commitment", - "commodoties", "commodities", - "commomplace", "commonplace", - "commonspace", "commonplace", - "commonweath", "commonwealth", - "commonwelth", "commonwealth", - "commuincate", "communicated", - "communciate", "communicate", - "communicted", "communicated", - "communistas", "communists", - "communistes", "communists", - "compability", "compatibility", - "compalation", "compilation", - "compansated", "compensated", - "comparabile", "comparable", - "comparasion", "comparison", - "comparasons", "comparisons", - "comparement", "compartment", - "comparetive", "comparative", - "comparision", "comparison", - "comparisson", "comparisons", - "comparitave", "comparative", - "comparitive", "comparative", - "comparsions", "comparisons", - "compassione", "compassionate", - "compasssion", "compassion", - "compatabile", "compatible", - "compatative", "comparative", - "compatiable", "compatible", - "compatibile", "compatible", - "compatibily", "compatibility", - "compeditive", "competitive", - "compeditors", "competitors", - "compeitions", "competitions", - "compeittion", "competitions", - "compelation", "compilation", - "compensante", "compensate", - "compensatie", "compensate", - "compensatin", "compensation", - "compenstate", "compensate", - "comperative", "comparative", - "compesition", "composition", - "competation", "computation", - "competative", "competitive", - "competators", "competitors", - "competetion", "competition", - "competetors", "competitors", - "competiters", "competitors", - "competiting", "competition", - "competitior", "competitor", - "competitivo", "competition", - "competitoin", "competitions", - "competitons", "competitors", - "competution", "computation", - "compilacion", "compilation", - "compilcated", "complicate", - "compination", "compilation", - "compinsated", "compensated", - "compitation", "computation", - "compitetion", "competitions", - "complacient", "complacent", - "complciated", "complicate", - "compleation", "compilation", - "complecated", "complicated", - "completaste", "completes", - "completeing", "completing", - "completeion", "completion", - "completelly", "completely", - "completelyl", "completely", - "completelys", "completes", - "completenes", "completes", - "complexitiy", "complexity", - "compliacted", "complicate", - "compliation", "compilation", - "complicarte", "complicate", - "complicatie", "complicit", - "complicatii", "complicit", - "complicatin", "complicit", - "complictaed", "complicate", - "complimente", "complement", - "complimenty", "complimentary", - "complusions", "compulsion", - "compolation", "compilation", - "componenets", "components", - "componentes", "components", - "composicion", "composition", - "composiiton", "compositions", - "composision", "compositions", - "compositied", "composite", - "composities", "composite", - "compositoin", "compositions", - "compositons", "compositions", - "compositore", "composite", - "compostiion", "compositions", - "compotition", "composition", - "compramised", "compromised", - "compramises", "compromises", - "compremised", "compromised", - "compremises", "compromises", - "comprension", "compression", - "compresores", "compressor", - "compresssed", "compressed", - "compresssor", "compressor", - "comprimised", "compromised", - "comprimises", "compromises", - "compromessi", "compromises", - "compromisng", "compromising", - "compromisse", "compromises", - "compromisso", "compromises", - "compromized", "compromised", - "compulstion", "compulsion", - "compunation", "computation", - "computacion", "computation", - "computating", "computation", - "computition", "computation", - "conceivibly", "conceivably", - "concencrate", "concentrate", - "concentrace", "concentrate", - "concentrade", "concentrated", - "concentrait", "concentrate", - "concentrant", "concentrate", - "concentrare", "concentrate", - "concentrato", "concentration", - "concertmate", "concentrate", - "conceviable", "conceivable", - "conceviably", "conceivably", - "concidering", "considering", - "conciveable", "conceivable", - "conciveably", "conceivably", - "conclsuions", "concussions", - "concludendo", "concluded", - "conclussion", "conclusions", - "conclussive", "conclusive", - "conclutions", "conclusions", - "concsiously", "consciously", - "conculsions", "conclusions", - "concusssion", "concussions", - "condeferacy", "confederacy", - "condicional", "conditional", - "condidtions", "conditions", - "conditionar", "conditioner", - "conditionel", "conditional", - "condolances", "condolences", - "condolenses", "condolences", - "condolonces", "condolences", - "conductiong", "conducting", - "condulences", "condolences", - "conenctions", "connections", - "conescutive", "consecutive", - "confedaracy", "confederacy", - "confedarate", "confederate", - "confederecy", "confederacy", - "conferances", "conferences", - "conferedate", "confederate", - "confererate", "confederate", - "confescated", "confiscated", - "confesssion", "confessions", - "confidantly", "confidently", - "configurare", "configure", - "configurate", "configure", - "configurato", "configuration", - "confilcting", "conflicting", - "confisgated", "confiscated", - "conflciting", "conflicting", - "confortable", "comfortable", - "confrontato", "confrontation", - "confussions", "confessions", - "congrassman", "congressman", - "congratuate", "congratulate", - "conicidence", "coincidence", - "conjonction", "conjunction", - "conjucntion", "conjunction", - "conjuncting", "conjunction", - "conlcusions", "conclusions", - "connatation", "connotation", - "connecitcut", "connecticut", - "connecticon", "connection", - "connectiong", "connecting", - "connectivty", "connectivity", - "connetation", "connotation", - "connonation", "connotation", - "connotacion", "connotation", - "conontation", "connotation", - "conotations", "connotations", - "conquerring", "conquering", - "consdidered", "considered", - "consectuive", "consecutive", - "consecuence", "consequence", - "conseguence", "consequence", - "conselation", "consolation", - "consentrate", "concentrate", - "consequenes", "consequence", - "consequense", "consequences", - "consequente", "consequence", - "consequenty", "consequently", - "consequtive", "consecutive", - "conservanti", "conservation", - "conservatie", "conservatives", - "conservaton", "conservation", - "consficated", "confiscated", - "considerabe", "considerate", - "considerais", "considers", - "considerant", "considerate", - "considerato", "consideration", - "considerble", "considerable", - "considerbly", "considerably", - "considereis", "considers", - "consilation", "consolation", - "consilidate", "consolidate", - "consistance", "consistency", - "consistenly", "consistently", - "consistensy", "consistency", - "consistenty", "consistently", - "consitution", "constitution", - "conslutants", "consultant", - "consolacion", "consolation", - "consoldiate", "consolidate", - "consolidare", "consolidate", - "consolodate", "consolidate", - "consomation", "consolation", - "conspiraces", "conspiracies", - "conspiracys", "conspiracies", - "conspirancy", "conspiracy", - "constantins", "constants", - "constantivs", "constants", - "constarints", "constraint", - "constituant", "constituent", - "constituion", "constitution", - "constituite", "constitute", - "constitutie", "constitutes", - "constrating", "constraint", - "constriants", "constraints", - "construcing", "constructing", - "construcion", "construction", - "construcive", "constructive", - "constructie", "constructive", - "constructos", "constructs", - "constructur", "constructor", - "constructus", "constructs", - "constuction", "construction", - "consturcted", "constructed", - "consuelling", "counselling", - "consulation", "consolation", - "consultaion", "consultation", - "consultanti", "consultation", - "consumation", "consumption", - "consumbales", "consumables", - "consumersim", "consumerism", - "consumibles", "consumables", - "contagiosum", "contagious", - "containered", "contained", - "containmemt", "containment", - "containters", "containers", - "containting", "containing", - "contaminato", "contamination", - "contaminent", "containment", - "contaminted", "contaminated", - "contancting", "contracting", - "contanimate", "contaminated", - "contemplare", "contemplate", - "contempoary", "contemporary", - "contemporay", "contemporary", - "contencious", "contentious", - "contenental", "continental", - "contengency", "contingency", - "contenintal", "continental", - "contenplate", "contemplate", - "contensious", "contentious", - "contentants", "contestants", - "contentuous", "contentious", - "contestaste", "contestants", - "contestents", "contestants", - "contianment", "containment", - "contientous", "contentious", - "contimplate", "contemplate", - "continenets", "continents", - "continentes", "continents", - "continentul", "continental", - "contingancy", "contingency", - "contingient", "contingent", - "contingincy", "contingency", - "continously", "continuously", - "continuarla", "continual", - "continuarlo", "continual", - "continuasse", "continues", - "continueing", "continuing", - "continuemos", "continues", - "continueous", "continuous", - "continuious", "continuous", - "continuning", "continuing", - "continunity", "continuity", - "continuosly", "continuously", - "continuting", "continuing", - "continutity", "continuity", - "continuuing", "continuing", - "continuuity", "continuity", - "contirbuted", "contributed", - "contiunally", "continually", - "contraccion", "contraction", - "contraddice", "contradicted", - "contradices", "contradicts", - "contradtion", "contraction", - "contraversy", "controversy", - "contreversy", "controversy", - "contribuent", "contribute", - "contribuito", "contribution", - "contributer", "contributor", - "contributie", "contribute", - "contributin", "contribution", - "contributos", "contributors", - "contribuyes", "contributes", - "contricting", "contracting", - "contriction", "contraction", - "contridicts", "contradicts", - "contriversy", "controversy", - "controleurs", "controllers", - "controllore", "controllers", - "controvercy", "controversy", - "controversa", "controversial", - "contrubutes", "contributes", - "contructing", "contracting", - "contruction", "construction", - "contructors", "contractors", - "conveinence", "convenience", - "conveneince", "convenience", - "conveniance", "convenience", - "conveniente", "convenience", - "convenietly", "conveniently", - "conventinal", "conventional", - "converitble", "convertible", - "conversaion", "conversion", - "conversatin", "conversations", - "converseley", "conversely", - "converstion", "conversion", - "convertirea", "converter", - "convertirle", "convertible", - "convertirme", "converter", - "convertirte", "converter", - "convicitons", "convictions", - "convienence", "convenience", - "convienient", "convenient", - "convinceing", "convincing", - "convincente", "convenient", - "convincersi", "convinces", - "convirtible", "convertible", - "cooperacion", "cooperation", - "cooperativo", "cooperation", - "cooporation", "cooperation", - "cooporative", "cooperative", - "coordenated", "coordinated", - "coordenates", "coordinates", - "coordianted", "coordinated", - "coordiantes", "coordinates", - "coordiantor", "coordinator", - "coordinador", "coordinator", - "coordinants", "coordinates", - "coordinater", "coordinator", - "coordinaton", "coordination", - "coordonated", "coordinated", - "coordonates", "coordinates", - "coordonator", "coordinator", - "cooridnated", "coordinated", - "cooridnates", "coordinates", - "cooridnator", "coordinator", - "copenhaagen", "copenhagen", - "copenhaegen", "copenhagen", - "copenhaguen", "copenhagen", - "copenhangen", "copenhagen", - "copmetitors", "competitors", - "coproration", "corporation", - "copyrigthed", "copyrighted", - "corinthains", "corinthians", - "corintheans", "corinthians", - "corinthiens", "corinthians", - "corinthinas", "corinthians", - "cornithians", "corinthians", - "corparation", "corporation", - "corperation", "corporation", - "corporacion", "corporation", - "corporativo", "corporation", - "corralation", "correlation", - "correctings", "corrections", - "correctivos", "corrections", - "correktions", "corrections", - "correktness", "correctness", - "correlacion", "correlation", - "correlaties", "correlates", - "corrilation", "correlation", - "corrisponds", "corresponds", - "corrolation", "correlation", - "corrosponds", "corresponds", - "costitution", "constitution", - "councellors", "councillors", - "counrtyside", "countryside", - "counsilling", "counselling", - "countercoat", "counteract", - "counteredit", "counterfeit", - "counterfact", "counteract", - "counterfait", "counterfeit", - "counterfest", "counterfeit", - "counterfiet", "counterfeit", - "counterpaly", "counterplay", - "counterpary", "counterplay", - "counterpath", "counterpart", - "counterpats", "counterparts", - "counterpont", "counterpoint", - "counterract", "counterpart", - "counterside", "countryside", - "countertrap", "counterpart", - "countriside", "countryside", - "countrycide", "countryside", - "countrywise", "countryside", - "courthourse", "courthouse", - "coutnerfeit", "counterfeit", - "coutnerpart", "counterpart", - "coutnerplay", "counterplay", - "creacionism", "creationism", - "creationkit", "creationist", - "creationsim", "creationism", - "creationsit", "creationist", - "creationsts", "creationists", - "creativelly", "creatively", - "credencials", "credentials", - "credentails", "credentials", - "credentaisl", "credentials", - "credientals", "credentials", - "credintials", "credentials", - "cricitising", "criticising", - "criculating", "circulating", - "cringeworhy", "cringeworthy", - "cringeworty", "cringeworthy", - "cringewothy", "cringeworthy", - "criticicing", "criticising", - "criticisied", "criticise", - "criticisims", "criticisms", - "criticisize", "criticise", - "criticiszed", "criticise", - "critisicing", "criticizing", - "critisising", "criticising", - "critizicing", "criticizing", - "critizising", "criticizing", - "critizizing", "criticizing", - "crockodiles", "crocodiles", - "crocodiller", "crocodile", - "crocodilule", "crocodile", - "croporation", "corporation", - "crossfiters", "crossfire", - "cultivative", "cultivate", - "curricullum", "curriculum", - "customizabe", "customizable", - "customizble", "customizable", - "dangeroulsy", "dangerously", - "dardenelles", "dardanelles", - "deadlifters", "deadlifts", - "dealershits", "dealerships", - "deceptivley", "deceptive", - "declaracion", "declaration", - "decleration", "declaration", - "declinining", "declining", - "decloration", "declaration", - "decoartions", "decoration", - "decomposits", "decomposes", - "decoratieve", "decorative", - "decorativos", "decorations", - "decotations", "decorations", - "decsendants", "descendants", - "deductiable", "deductible", - "defenderlas", "defenders", - "defenderlos", "defenders", - "defendernos", "defenders", - "defenesless", "defenseless", - "defenisvely", "defensively", - "defensivley", "defensively", - "deficiencey", "deficiency", - "deficienies", "deficiencies", - "deficientcy", "deficiency", - "definantley", "definitely", - "definatedly", "definitely", - "definateley", "definitely", - "definatelly", "definitely", - "definatelty", "definitely", - "definatetly", "definitely", - "definations", "definitions", - "definatlely", "definitely", - "definetally", "definitely", - "definetlely", "definitely", - "definitaley", "definitely", - "definitelly", "definitely", - "definitevly", "definitively", - "definitiely", "definitively", - "definitieve", "definitive", - "definitiley", "definitively", - "definitivly", "definitively", - "definitivno", "definition", - "definitivos", "definitions", - "definitlely", "definitely", - "definitlety", "definitely", - "deflecticon", "deflection", - "degenererat", "degenerate", - "degradacion", "degradation", - "degradating", "degradation", - "degragation", "degradation", - "degridation", "degradation", - "dehyrdation", "dehydration", - "deinitalize", "deinitialize", - "delaerships", "dealerships", - "delapidated", "dilapidated", - "delcaration", "declaration", - "delearships", "dealerships", - "delevopment", "development", - "deliberante", "deliberate", - "deliberatly", "deliberately", - "deliberetly", "deliberately", - "delightlful", "delightful", - "deliverying", "delivering", - "delusionnal", "delusional", - "deminsional", "dimensional", - "democarcies", "democracies", - "democracize", "democracies", - "democractic", "democratic", - "democraphic", "demographic", - "democrasies", "democracies", - "democrazies", "democracies", - "democrocies", "democracies", - "demograhpic", "demographic", - "demographis", "demographics", - "demograpics", "demographics", - "demogrpahic", "demographic", - "demoninator", "denominator", - "demonstarte", "demonstrate", - "demonstates", "demonstrates", - "demonstraby", "demonstrably", - "demonstrant", "demonstrate", - "demonstrats", "demonstrates", - "demosntrate", "demonstrate", - "denegrating", "denigrating", - "denomenator", "denominator", - "denominador", "denominator", - "denominaron", "denominator", - "denominater", "denominator", - "denominaton", "denomination", - "denomitator", "denominator", - "denomonator", "denominator", - "denonimator", "denominator", - "deocrations", "decorations", - "deomcracies", "democracies", - "deparmental", "departmental", - "depedencies", "dependencies", - "dependancey", "dependency", - "dependencey", "dependency", - "dependencie", "dependence", - "dependenies", "dependencies", - "deplorabile", "deplorable", - "depressieve", "depressive", - "depresssion", "depression", - "deprevation", "deprivation", - "deprication", "deprivation", - "deprivating", "deprivation", - "deprivition", "deprivation", - "deprovation", "deprivation", - "depserately", "desperately", - "depseration", "desperation", - "deregulatin", "deregulation", - "derivativos", "derivatives", - "derivitaves", "derivatives", - "derivitives", "derivatives", - "derpivation", "deprivation", - "derviatives", "derivatives", - "descandants", "descendants", - "descendands", "descendants", - "descendends", "descended", - "descendenta", "descendants", - "descentants", "descendants", - "descirption", "descriptions", - "descprition", "descriptions", - "describiste", "describes", - "describtion", "description", - "descripcion", "description", - "descripiton", "descriptions", - "descripters", "descriptors", - "descriptoin", "descriptions", - "descriptons", "descriptions", - "descritpion", "descriptions", - "descrpition", "descriptions", - "desensitied", "desensitized", - "desensitzed", "desensitized", - "desentisize", "desensitized", - "desgination", "designation", - "designacion", "designation", - "designstion", "designation", - "desinations", "destinations", - "desingation", "designation", - "desitnation", "destination", - "desoriented", "disoriented", - "desparately", "desperately", - "desparation", "desperation", - "desperating", "desperation", - "desperatley", "desperately", - "despirately", "desperately", - "despiration", "desperation", - "destablized", "destabilized", - "destiantion", "destinations", - "destinaiton", "destinations", - "destinatons", "destinations", - "destinction", "destination", - "destraction", "destruction", - "destruccion", "destruction", - "destruciton", "destruction", - "destructivo", "destruction", - "destruktion", "destruction", - "destruktive", "destructive", - "deteoriated", "deteriorated", - "determanism", "determinism", - "determening", "determining", - "determenism", "determinism", - "determinare", "determine", - "determinato", "determination", - "determinded", "determine", - "determinsim", "determinism", - "detramental", "detrimental", - "detremental", "detrimental", - "detrimentul", "detrimental", - "detuschland", "deutschland", - "deustchland", "deutschland", - "deutchsland", "deutschland", - "deutcshland", "deutschland", - "deutschalnd", "deutschland", - "deutshcland", "deutschland", - "develepmont", "developments", - "develompent", "developments", - "developemnt", "developments", - "developmant", "developmental", - "developmetn", "developments", - "developmnet", "developments", - "developpers", "developers", - "develpoment", "developments", - "deveolpment", "developments", - "deveploment", "developments", - "devestating", "devastating", - "devistating", "devastating", - "deyhdration", "dehydration", - "diagnositcs", "diagnostic", - "diagnositic", "diagnostic", - "diagonstics", "diagnostic", - "dictatorhip", "dictatorship", - "dictionaire", "dictionaries", - "dictionairy", "dictionary", - "dictionarys", "dictionaries", - "dictionnary", "dictionary", - "differances", "differences", - "differantly", "differently", - "differental", "differential", - "differentes", "differences", - "differneces", "differences", - "differnetly", "differently", - "difficulity", "difficulty", - "difficultes", "difficulties", - "dificulties", "difficulties", - "dimensiones", "dimensions", - "dimentional", "dimensional", - "dimesnional", "dimensional", - "diminisheds", "diminishes", - "diminsihing", "diminishing", - "diminuitive", "diminutive", - "diminushing", "diminishing", - "dinosaurios", "dinosaurs", - "direccional", "directional", - "direcitonal", "directional", - "directorguy", "directory", - "directorios", "directors", - "direktional", "directional", - "disadvantge", "disadvantage", - "disagreemet", "disagreements", - "disagreemtn", "disagreements", - "disapperead", "disappeared", - "disapporval", "disapproval", - "disapprovel", "disapproval", - "disasterous", "disastrous", - "disastreous", "disastrous", - "disastrious", "disastrous", - "disastruous", "disastrous", - "disatisfied", "dissatisfied", - "disciplened", "disciplined", - "disciplinas", "disciplines", - "disciplince", "disciplines", - "disclipined", "disciplined", - "disclipines", "disciplines", - "discogrophy", "discography", - "discogrpahy", "discography", - "disconencts", "disconnects", - "disconneted", "disconnected", - "disconnnect", "disconnect", - "discontined", "discontinued", - "discontiued", "discontinued", - "discrapency", "discrepancy", - "discretited", "discredited", - "discrimante", "discriminate", - "discrimiate", "discriminate", - "discussiong", "discussing", - "discusssion", "discussions", - "disgraseful", "disgraceful", - "disgrateful", "disgraceful", - "disgrunteld", "disgruntled", - "disgustigly", "disgustingly", - "disgustingy", "disgustingly", - "disgustinly", "disgustingly", - "disicplined", "disciplined", - "disicplines", "disciplines", - "disingenuos", "disingenuous", - "dismanlting", "dismantling", - "dismantaled", "dismantled", - "dismanteled", "dismantled", - "disobediant", "disobedient", - "disocgraphy", "discography", - "disparingly", "disparagingly", - "dispensaire", "dispensaries", - "dispensarie", "dispenser", - "dispensiary", "dispensary", - "displacemnt", "displacement", - "disposicion", "disposition", - "disputandem", "disputandum", - "disqualifed", "disqualified", - "disregaring", "disregarding", - "dissapeared", "disappeared", - "dissapoined", "dissapointed", - "dissapointd", "dissapointed", - "dissapoited", "dissapointed", - "dissappears", "disappears", - "dissatisfed", "dissatisfied", - "disscusions", "discussions", - "dissertaion", "dissertation", - "dissipatore", "dissipate", - "distatesful", "distasteful", - "distatseful", "distasteful", - "disterbance", "disturbance", - "disticntion", "distinctions", - "distinciton", "distinction", - "distincitve", "distinctive", - "distinctily", "distinctly", - "distingiush", "distinguish", - "distinguise", "distinguished", - "distinktion", "distinction", - "distinquish", "distinguish", - "distirbance", "disturbance", - "distirbuted", "distribute", - "distirbutor", "distributor", - "distraccion", "distraction", - "distractons", "distracts", - "distraktion", "distraction", - "distribitor", "distributor", - "distribuent", "distribute", - "distribuite", "distribute", - "distribuito", "distribution", - "distributie", "distributed", - "distributin", "distribution", - "distributio", "distributor", - "distrobuted", "distributed", - "distrubance", "disturbance", - "distrubited", "distributed", - "distrubitor", "distributor", - "distrubuted", "distributed", - "distrubutor", "distributor", - "distructive", "destructive", - "distuingish", "distinguish", - "distunguish", "distinguish", - "disturbante", "disturbance", - "disturbence", "disturbance", - "disucssions", "discussions", - "divisionals", "divisions", - "doccumented", "documented", - "documantary", "documentary", - "documenatry", "documentary", - "documentare", "documentaries", - "documentato", "documentation", - "documentery", "documentary", - "documentory", "documentary", - "domesticted", "domesticated", - "dominateurs", "dominates", - "dominationg", "dominating", - "donwloading", "downloading", - "doublellift", "doublelift", - "downlaoding", "downloading", - "downloadbel", "downloadable", - "downloadbig", "downloading", - "downloadble", "downloadable", - "downvoteers", "downvoters", - "downvoteing", "downvoting", - "downvoteres", "downvoters", - "downvoteros", "downvoters", - "downvoteurs", "downvoters", - "downvotters", "downvoters", - "downvotting", "downvoting", - "dramaticaly", "dramatically", - "dramaticlly", "dramatically", - "drasitcally", "drastically", - "dsyfunction", "dysfunction", - "duetschland", "deutschland", - "durabillity", "durability", - "dyanmically", "dynamically", - "dymanically", "dynamically", - "dysfonction", "dysfunction", - "dysfucntion", "dysfunction", - "dysfunciton", "dysfunction", - "dysfunktion", "dysfunction", - "earhtquakes", "earthquakes", - "earthqaukes", "earthquakes", - "earthquacks", "earthquakes", - "economicaly", "economically", - "economiclly", "economically", - "economisiti", "economist", - "economistes", "economists", - "educacional", "educational", - "effeciently", "efficiently", - "effecitvely", "effectively", - "effectivley", "effectively", - "efficeintly", "efficiently", - "efficiantly", "efficiently", - "efficientcy", "efficiently", - "effortlesly", "effortlessly", - "effortlessy", "effortlessly", - "egaletarian", "egalitarian", - "egalitatian", "egalitarian", - "egaliterian", "egalitarian", - "egostitical", "egotistical", - "egotastical", "egotistical", - "egotestical", "egotistical", - "egotisitcal", "egotistical", - "egotisticle", "egotistical", - "egotystical", "egotistical", - "ehtnicities", "ethnicities", - "ejacluation", "ejaculation", - "ejacualtion", "ejaculation", - "electoratul", "electoral", - "electornics", "electronics", - "electricain", "electrician", - "electricial", "electrical", - "electricien", "electrician", - "electricion", "electrician", - "electricman", "electrician", - "electrisity", "electricity", - "electritian", "electrician", - "electrocity", "electricity", - "electrolyes", "electrolytes", - "electrolyts", "electrolytes", - "electroncis", "electrons", - "electroylte", "electrolytes", - "elementrary", "elementary", - "eleminating", "eliminating", - "elimanation", "elimination", - "eliminacion", "elimination", - "elimintates", "eliminates", - "ellipitcals", "elliptical", - "eloquentely", "eloquently", - "emabrassing", "embarrassing", - "embaraasing", "embarrassing", - "embarasaing", "embarrassing", - "embarassign", "embarrassing", - "embarassimg", "embarrassing", - "embarassing", "embarrassing", - "embarissing", "embarrassing", - "embarrasing", "embarrassing", - "embarressed", "embarrassed", - "embarrssing", "embarrassing", - "emergancies", "emergencies", - "emergencias", "emergencies", - "emergenices", "emergencies", - "emmediately", "immediately", - "emmisarries", "emissaries", - "emotionella", "emotionally", - "empahsizing", "emphasizing", - "empathethic", "empathetic", - "emphacizing", "emphasizing", - "emphatising", "emphasizing", - "emphatizing", "emphasizing", - "emphazising", "emphasizing", - "emphesizing", "emphasizing", - "empiracally", "empirically", - "empirialism", "imperialism", - "empirialist", "imperialist", - "enchamtment", "enchantment", - "enchancment", "enchantment", - "enchanement", "enchantment", - "enchanthing", "enchanting", - "enchantmant", "enchantment", - "enchantmens", "enchantments", - "enchantmets", "enchantments", - "encomapsses", "encompasses", - "encompasess", "encompasses", - "encompesses", "encompasses", - "encounteres", "encounters", - "encoutnered", "encountered", - "encryptiion", "encryption", - "encyclopdia", "encyclopedia", - "encylopedia", "encyclopedia", - "endagnering", "endangering", - "endandering", "endangering", - "endorcement", "endorsement", - "endoresment", "endorsement", - "engagaments", "engagements", - "engeneering", "engineering", - "enginerring", "engineering", - "enginnering", "engineering", - "enlargments", "enlargements", - "enligthened", "enlightened", - "enourmously", "enormously", - "enterpirses", "enterprises", - "enterprices", "enterprises", - "enterprishe", "enterprises", - "entertainig", "entertaining", - "entertwined", "entertained", - "enthicities", "ethnicities", - "enthisiasts", "enthusiasts", - "enthuasists", "enthusiasts", - "enthuisasts", "enthusiasts", - "enthusaists", "enthusiasts", - "enthusiants", "enthusiast", - "enthusiasic", "enthusiastic", - "enthusiasim", "enthusiasm", - "enthusiasum", "enthusiasm", - "enthusiatic", "enthusiastic", - "enthusiests", "enthusiasts", - "enthusigasm", "enthusiasm", - "enthusisast", "enthusiasts", - "entrepeneur", "entrepreneur", - "entreperure", "entrepreneur", - "entrepeuner", "entrepreneur", - "entreprener", "entrepreneurs", - "entreprenur", "entrepreneur", - "entretained", "entertained", - "envinroment", "environments", - "enviorments", "environments", - "enviornment", "environment", - "envirnoment", "environment", - "enviroments", "environments", - "enviromnent", "environments", - "environemnt", "environment", - "environmnet", "environments", - "envrionment", "environment", - "equilavents", "equivalents", - "equilbirium", "equilibrium", - "equilevants", "equivalents", - "equilibirum", "equilibrium", - "equilibriam", "equilibrium", - "equilibruim", "equilibrium", - "equivalance", "equivalence", - "equivalants", "equivalents", - "equivalenet", "equivalents", - "equivallent", "equivalent", - "equivelance", "equivalence", - "equivelants", "equivalents", - "equivelents", "equivalents", - "equivilants", "equivalents", - "equivilence", "equivalence", - "equivilents", "equivalents", - "equivlalent", "equivalent", - "equivlanets", "equivalents", - "equivolence", "equivalence", - "equivolents", "equivalents", - "essencially", "essentially", - "essentailly", "essentially", - "essentialls", "essentials", - "essentually", "essentially", - "establising", "establishing", - "ethicallity", "ethically", - "ethincities", "ethnicities", - "ethniticies", "ethnicities", - "europeaners", "europeans", - "europeaness", "europeans", - "evaluatiing", "evaluating", - "evaluationg", "evaluating", - "evangalical", "evangelical", - "evangelikal", "evangelical", - "evengalical", "evangelical", - "evenhtually", "eventually", - "everyonehas", "everyones", - "everyonelse", "everyones", - "evidentally", "evidently", - "exacarbated", "exacerbated", - "exacberated", "exacerbated", - "exagerating", "exaggerating", - "exagerrated", "exaggerated", - "exagerrates", "exaggerates", - "exaggarated", "exaggerated", - "exaggareted", "exaggerate", - "exaggeratin", "exaggeration", - "exaggerrate", "exaggerate", - "exaggurated", "exaggerated", - "exarcebated", "exacerbated", - "excalmation", "exclamation", - "excepcional", "exceptional", - "exceptionel", "exceptional", - "excessivley", "excessively", - "exceutioner", "executioner", - "exchanching", "exchanging", - "exclamacion", "exclamation", - "exclamating", "exclamation", - "exclamativo", "exclamation", - "exclemation", "exclamation", - "exclimation", "exclamation", - "exclucivity", "exclusivity", - "exclusivety", "exclusivity", - "exclusivily", "exclusivity", - "exclusivley", "exclusively", - "excpetional", "exceptional", - "exculsively", "exclusively", - "exculsivity", "exclusivity", - "execitioner", "executioner", - "execptional", "exceptional", - "exectuables", "executable", - "exectuioner", "executioner", - "executionar", "executioner", - "executionor", "executioner", - "exerciseing", "exercising", - "exeuctioner", "executioner", - "existantial", "existential", - "existencial", "existential", - "existensial", "existential", - "existentiel", "existential", - "exlcamation", "exclamation", - "exlcusively", "exclusively", - "exlcusivity", "exclusivity", - "exoskelaton", "exoskeleton", - "expansiones", "expansions", - "expectantcy", "expectancy", - "expectating", "expectation", - "expectional", "exceptional", - "expendature", "expenditure", - "expendeture", "expenditure", - "expentiture", "expenditure", - "expereinced", "experienced", - "expereinces", "experiences", - "experements", "experiments", - "experianced", "experienced", - "experiances", "experiences", - "experiemnts", "experiments", - "experiening", "experiencing", - "experimetal", "experimental", - "experimeted", "experimented", - "experssions", "expressions", - "expiditions", "expeditions", - "expierenced", "experienced", - "expierences", "experiences", - "expirements", "experiments", - "explainging", "explaining", - "explaintory", "explanatory", - "explanaiton", "explanations", - "explanetary", "explanatory", - "explanetory", "explanatory", - "explanitary", "explanatory", - "explanotory", "explanatory", - "explenation", "explanation", - "explenatory", "explanatory", - "explicitely", "explicitly", - "explicitily", "explicitly", - "explination", "explanation", - "explinatory", "explanatory", - "exploitaion", "exploitation", - "exploitatie", "exploitative", - "explonation", "exploration", - "exploracion", "exploration", - "explorating", "exploration", - "explorerers", "explorers", - "explosiones", "explosions", - "explotacion", "exploration", - "expodential", "exponential", - "exponantial", "exponential", - "exponencial", "exponential", - "exponentiel", "exponential", - "expresscoin", "expression", - "expressivos", "expressions", - "expresssive", "expressive", - "expressview", "expressive", - "exprimental", "experimental", - "expropiated", "expropriated", - "extensiones", "extensions", - "extensivley", "extensively", - "extragavant", "extravagant", - "extrapalate", "extrapolate", - "extraploate", "extrapolate", - "extrapolant", "extrapolate", - "extrapolare", "extrapolate", - "extrapolite", "extrapolate", - "extrapulate", "extrapolate", - "extravagent", "extravagant", - "extravagina", "extravagant", - "extravegant", "extravagant", - "extravigant", "extravagant", - "extravogant", "extravagant", - "extremistas", "extremists", - "extremistes", "extremists", - "extropolate", "extrapolate", - "fabircation", "fabrication", - "fabricacion", "fabrication", - "fabrikation", "fabrication", - "facilitarte", "facilitate", - "facilitiate", "facilitate", - "facillitate", "facilitate", - "facisnation", "fascination", - "facsination", "fascination", - "factuallity", "factually", - "familairity", "familiarity", - "familairize", "familiarize", - "familiaries", "familiarize", - "familierize", "familiarize", - "fanatsizing", "fantasizing", - "fanficitons", "fanfiction", - "fantacising", "fantasizing", - "fantacizing", "fantasizing", - "fantasazing", "fantasizing", - "fantasiaing", "fantasizing", - "fantasyzing", "fantasizing", - "fantazising", "fantasizing", - "fascinacion", "fascination", - "fascinatinf", "fascination", - "fascisation", "fascination", - "fascization", "fascination", - "fashionalbe", "fashionable", - "fashoinable", "fashionable", - "fatalitites", "fatalities", - "favoritisme", "favorites", - "favoutrable", "favourable", - "felxibility", "flexibility", - "feministers", "feminists", - "feministisk", "feminists", - "fermentaion", "fermentation", - "fermenterad", "fermented", - "fertilizier", "fertilizer", - "fertizilers", "fertilizer", - "festivalens", "festivals", - "fignernails", "fingernails", - "fignerprint", "fingerprint", - "figurativly", "figuratively", - "finanically", "financially", - "finantially", "financially", - "fingerpints", "fingertips", - "fingerpoint", "fingerprint", - "fingertrips", "fingertips", - "firefighers", "firefighters", - "firefigther", "firefighters", - "firendzoned", "friendzoned", - "firghtening", "frightening", - "flatterende", "flattered", - "flawlessely", "flawlessly", - "flawlessley", "flawlessly", - "flexibiltiy", "flexibility", - "flourescent", "fluorescent", - "fluctuaties", "fluctuate", - "fluctuative", "fluctuate", - "flutteryshy", "fluttershy", - "forcefullly", "forcefully", - "foreseaable", "foreseeable", - "foresseable", "foreseeable", - "forgettting", "forgetting", - "forgiviness", "forgiveness", - "formallized", "formalized", - "formattting", "formatting", - "formidabble", "formidable", - "formidabelt", "formidable", - "formidabile", "formidable", - "fortitudine", "fortitude", - "fortuantely", "fortunately", - "fortunantly", "fortunately", - "fortunatley", "fortunately", - "fortunetely", "fortunately", - "franchieses", "franchises", - "frankensite", "frankenstein", - "frankensten", "frankenstein", - "fransiscans", "franciscans", - "freindships", "friendships", - "freindzoned", "friendzoned", - "frequenices", "frequencies", - "frequensies", "frequencies", - "frequenties", "frequencies", - "frequentily", "frequently", - "frequenzies", "frequencies", - "friendboned", "friendzoned", - "friendlines", "friendlies", - "friendzonie", "friendzoned", - "frientships", "friendships", - "frientzoned", "friendzoned", - "frightenend", "frightened", - "frightining", "frightening", - "frigthening", "frightening", - "frinedzoned", "friendzoned", - "frontlinies", "frontline", - "frontlinjen", "frontline", - "frustartion", "frustrations", - "frustracion", "frustration", - "frustraited", "frustrated", - "frustrantes", "frustrates", - "frustrasion", "frustrations", - "frustrasted", "frustrates", - "frustraties", "frustrates", - "fucntioning", "functioning", - "fulfillling", "fulfilling", - "fulfullment", "fulfillment", - "fullfilment", "fulfillment", - "fullscreeen", "fullscreen", - "funcitoning", "functioning", - "functionaly", "functionally", - "functionnal", "functional", - "fundamentas", "fundamentals", - "fundamently", "fundamental", - "fundametals", "fundamentals", - "fundamnetal", "fundamentals", - "fundemantal", "fundamental", - "fundemental", "fundamental", - "fundimental", "fundamental", - "furhtermore", "furthermore", - "furstration", "frustration", - "furthremore", "furthermore", - "furthurmore", "furthermore", - "futurisitic", "futuristic", - "gangsterest", "gangsters", - "gangsterous", "gangsters", - "gauntlettes", "gauntlets", - "geneologies", "genealogies", - "generalizng", "generalizing", - "generatting", "generating", - "genitaliban", "genitalia", - "gentlemanne", "gentlemen", - "girlfirends", "girlfriends", - "girlfreinds", "girlfriends", - "girlfrients", "girlfriends", - "glorifierad", "glorified", - "glorifindel", "glorified", - "goosebumbps", "goosebumps", - "govenrments", "governments", - "govermental", "governmental", - "governemnts", "governments", - "governmanet", "governmental", - "governmeant", "governmental", - "govormental", "governmental", - "gracefullly", "gracefully", - "grahpically", "graphically", - "grammarical", "grammatical", - "grammaticly", "grammatical", - "grammitical", "grammatical", - "graphcially", "graphically", - "grassrooots", "grassroots", - "gratuitious", "gratuitous", - "gratuituous", "gratuitous", - "gravitatiei", "gravitate", - "grilfriends", "girlfriends", - "grpahically", "graphically", - "guaranteeds", "guarantees", - "guerrillera", "guerrilla", - "gunslingner", "gunslinger", - "hamburgaren", "hamburger", - "hamburgeres", "hamburgers", - "hamburglers", "hamburgers", - "hamburguers", "hamburgers", - "handlebards", "handlebars", - "handrwiting", "handwriting", - "handycapped", "handicapped", - "hanidcapped", "handicapped", - "harassement", "harassment", - "harrasments", "harassments", - "harrassment", "harassment", - "harvestgain", "harvesting", - "headquartes", "headquarters", - "headquaters", "headquarters", - "hearhtstone", "hearthstone", - "heartborken", "heartbroken", - "heartbraker", "heartbreak", - "heartbrakes", "heartbreak", - "heartsthone", "hearthstone", - "heaviweight", "heavyweight", - "heavyweigth", "heavyweight", - "heavywieght", "heavyweight", - "helicoptors", "helicopters", - "helicotpers", "helicopters", - "helicpoters", "helicopters", - "helictopers", "helicopters", - "helikopters", "helicopters", - "hemipsheres", "hemisphere", - "hemishperes", "hemisphere", - "herathstone", "hearthstone", - "heterosexal", "heterosexual", - "hexidecimal", "hexadecimal", - "hierachical", "hierarchical", - "hierarcical", "hierarchical", - "highlighing", "highlighting", - "highschoool", "highschool", - "hipopotamus", "hippopotamus", - "historicaly", "historically", - "historicans", "historians", - "historietas", "histories", - "historinhas", "historians", - "homecomeing", "homecoming", - "homecomming", "homecoming", - "homelesness", "homelessness", - "homelessess", "homelessness", - "homeowneris", "homeowners", - "homoegenous", "homogeneous", - "homogeneize", "homogenize", - "homogenious", "homogeneous", - "homogenuous", "homogeneous", - "homophoboes", "homophobe", - "homosexuais", "homosexuals", - "homosexuels", "homosexuals", - "hopelessely", "hopelessly", - "hopelessley", "hopelessly", - "hopsitality", "hospitality", - "horizonatal", "horizontal", - "horizontaal", "horizontal", - "horizontaly", "horizontally", - "horrendeous", "horrendous", - "horrendious", "horrendous", - "horrenduous", "horrendous", - "hospitalzed", "hospitalized", - "hospotality", "hospitality", - "househoulds", "households", - "humanitarna", "humanitarian", - "humanitites", "humanities", - "humilitaing", "humiliating", - "humilitaion", "humiliation", - "humillating", "humiliating", - "humillation", "humiliation", - "hurricaines", "hurricanes", - "hurricances", "hurricanes", - "hurricanger", "hurricane", - "hyperbollic", "hyperbolic", - "hyperbrophy", "hypertrophy", - "hyperthropy", "hypertrophy", - "hypertorphy", "hypertrophy", - "hypertrohpy", "hypertrophy", - "hypocritcal", "hypocritical", - "hypocritial", "hypocritical", - "hypocrities", "hypocrite", - "hypothesees", "hypotheses", - "hypothesies", "hypothesis", - "hystericaly", "hysterically", - "hystericlly", "hysterically", - "iconclastic", "iconoclastic", - "idealisitic", "idealistic", - "identifible", "identifiable", - "identitites", "identities", - "identitties", "identities", - "ideologiers", "ideologies", - "ideologisen", "ideologies", - "ideologiset", "ideologies", - "ideologiske", "ideologies", - "illegallity", "illegally", - "illegitamte", "illegitimate", - "illegitmate", "illegitimate", - "illsutrator", "illustrator", - "illuminanti", "illuminati", - "illuminarti", "illuminati", - "illuminatti", "illuminati", - "illuminauti", "illuminati", - "illuminiati", "illuminati", - "illuminista", "illuminati", - "illumintati", "illuminati", - "illustarted", "illustrated", - "illustartor", "illustrator", - "illustraded", "illustrated", - "illustraion", "illustration", - "illustrater", "illustrator", - "illustratie", "illustrate", - "illustratin", "illustrations", - "illustraton", "illustration", - "imaganative", "imaginative", - "imaganitive", "imaginative", - "imaginacion", "imagination", - "imaginatiei", "imaginative", - "imaginating", "imagination", - "imaginativo", "imagination", - "imaginitave", "imaginative", - "imbalanaced", "imbalanced", - "imbalanaces", "imbalances", - "imbalancers", "imbalances", - "immatureity", "immaturity", - "immedeately", "immediately", - "immediantly", "immediately", - "immediatley", "immediately", - "immedietely", "immediately", - "immideately", "immediately", - "immidiately", "immediately", - "immigraiton", "immigration", - "immigrantes", "immigrants", - "immoratlity", "immortality", - "immortailty", "immortality", - "immortalisy", "immortals", - "impeccabile", "impeccable", - "imperailist", "imperialist", - "imperealist", "imperialist", - "imperialims", "imperialism", - "imperialsim", "imperialism", - "imperiarist", "imperialist", - "imperically", "empirically", - "imperislist", "imperialist", - "implausable", "implausible", - "implausbile", "implausible", - "implementas", "implements", - "implementes", "implements", - "implementig", "implementing", - "implementos", "implements", - "implicacion", "implication", - "implicatons", "implications", - "implicitely", "implicitly", - "implicitily", "implicitly", - "implikation", "implication", - "implimented", "implemented", - "importantce", "importance", - "importently", "importantly", - "imporvement", "improvement", - "impossibile", "impossible", - "impossibily", "impossibly", - "impossibley", "impossibly", - "impossiblly", "impossibly", - "impoverised", "impoverished", - "impracticle", "impractical", - "impressario", "impresario", - "impresssion", "impressions", - "imprisonent", "imprisonment", - "imprisonned", "imprisoned", - "improbabile", "improbable", - "improtantly", "importantly", - "improvemnts", "improvements", - "improvished", "improvised", - "improvision", "improvisation", - "improvments", "improvements", - "impulsivley", "impulsive", - "imrpovement", "improvement", - "inaccessble", "inaccessible", - "inaccuraces", "inaccuracies", - "inaccurrate", "inaccurate", - "inadvertant", "inadvertent", - "inaguration", "inauguration", - "inahbitants", "inhabitants", - "incarantion", "incarnation", - "incarcerato", "incarceration", - "incarnacion", "incarnation", - "incentivare", "incentive", - "incentivate", "incentive", - "incentivice", "incentive", - "incentivies", "incentives", - "incidencies", "incidence", - "incidentaly", "incidentally", - "incidential", "incidental", - "inclanation", "inclination", - "inclenation", "inclination", - "inclinacion", "inclination", - "inclinaison", "inclination", - "incognition", "incognito", - "incoherrent", "incoherent", - "incompatble", "incompatible", - "incompatent", "incompetent", - "incompetant", "incompetent", - "incompitent", "incompetent", - "incompotent", "incompetent", - "incomptable", "incompatible", - "inconsisent", "inconsistent", - "inconveniet", "inconvenient", - "incoroprate", "incorporate", - "incorparate", "incorporate", - "incorperate", "incorporate", - "incorporare", "incorporate", - "incorported", "incorporated", - "incorprates", "incorporates", - "incorproate", "incorporated", - "incramental", "incremental", - "increadible", "incredible", - "incrediable", "incredible", - "incrediably", "incredibly", - "incredibile", "incredible", - "incredibily", "incredibly", - "incredibley", "incredibly", - "incrememnts", "increments", - "incremenets", "increments", - "incrementas", "increments", - "incremently", "incremental", - "incrementos", "increments", - "incrimental", "incremental", - "inctroduced", "introduced", - "indefinetly", "indefinitely", - "indefininte", "indefinite", - "indefinitly", "indefinitely", - "indepdenent", "independents", - "indepedence", "independence", - "indepednent", "independents", - "independant", "independent", - "independece", "independence", - "independens", "independents", - "independetn", "independents", - "independets", "independents", - "independnet", "independents", - "indepentend", "independents", - "indepentent", "independent", - "indianapols", "indianapolis", - "indicateurs", "indicates", - "indicatiors", "indicators", - "indictement", "indictment", - "indifferant", "indifferent", - "indiffernce", "indifference", - "indigeneous", "indigenous", - "indigenious", "indigenous", - "indigenuous", "indigenous", - "indigineous", "indigenous", - "indipendent", "independent", - "indirectely", "indirectly", - "individiual", "individual", - "individuais", "individuals", - "individualy", "individually", - "individuati", "individuality", - "individuels", "individuals", - "indivuduals", "individuals", - "industriels", "industries", - "ineffecitve", "ineffective", - "ineffektive", "ineffective", - "inefficeint", "inefficient", - "inefficiant", "inefficient", - "ineffictive", "ineffective", - "ineffizient", "inefficient", - "inequallity", "inequality", - "inevitabile", "inevitable", - "inevitabily", "inevitably", - "inevitabley", "inevitably", - "inevitablly", "inevitably", - "inexpencive", "inexpensive", - "inexpenisve", "inexpensive", - "inexperiece", "inexperience", - "inexperince", "inexperience", - "inexplicaby", "inexplicably", - "infallibale", "infallible", - "infallibile", "infallible", - "infectation", "infestation", - "inferioirty", "inferiority", - "infestating", "infestation", - "infilitrate", "infiltrate", - "infiltartor", "infiltrator", - "infiltraron", "infiltrator", - "infiltrarte", "infiltrate", - "infiltrater", "infiltrator", - "infiltratie", "infiltrate", - "infiltrerat", "infiltrate", - "infinitelly", "infinitely", - "infintrator", "infiltrator", - "inflamation", "inflammation", - "inflatabale", "inflatable", - "inflitrator", "infiltrator", - "influancing", "influencing", - "influencial", "influential", - "influencian", "influencing", - "influenting", "influencing", - "influentual", "influential", - "influincing", "influencing", - "infograhpic", "infographic", - "infograpgic", "infographic", - "infogrpahic", "infographic", - "informacion", "information", - "informatice", "informative", - "informatief", "informative", - "informatiei", "informative", - "informatike", "informative", - "informativo", "information", - "informitive", "informative", - "infrigement", "infringement", - "infringeing", "infringing", - "infromation", "information", - "infromative", "informative", - "infulential", "influential", - "ingerdients", "ingredients", - "ingrediants", "ingredients", - "ingreidents", "ingredient", - "ingriedents", "ingredient", - "inhabitents", "inhabitants", - "inheirtance", "inheritance", - "inheratance", "inheritance", - "inheretance", "inheritance", - "inheritence", "inheritance", - "inhertiance", "inheritance", - "initaitives", "initiatives", - "initalisers", "initialisers", - "initalising", "initialising", - "initalizers", "initializers", - "initalizing", "initializing", - "initiaitive", "initiative", - "inititiaves", "initiatives", - "innocenters", "innocents", - "innocentius", "innocents", - "innoculated", "inoculated", - "inpsiration", "inspiration", - "inquisicion", "inquisition", - "inquisistor", "inquisitor", - "inquisiting", "inquisition", - "inquisitior", "inquisitor", - "inquisitivo", "inquisition", - "inquizition", "inquisition", - "insecurites", "insecurities", - "insensative", "insensitive", - "insensetive", "insensitive", - "insentitive", "insensitive", - "insepctions", "inspections", - "inseperable", "inseparable", - "insipration", "inspiration", - "insitutions", "institutions", - "insparation", "inspiration", - "inspecticon", "inspection", - "inspectoras", "inspectors", - "insperation", "inspiration", - "inspiracion", "inspiration", - "inspirating", "inspiration", - "inspriation", "inspiration", - "instalation", "installation", - "instalement", "installment", - "installatin", "installations", - "installeert", "installer", - "installemnt", "installment", - "installling", "installing", - "installmant", "installment", - "instanciate", "instantiate", - "instantaneu", "instantaneous", - "institucion", "institution", - "institutiei", "institute", - "instituttet", "institute", - "instraments", "instruments", - "instruccion", "instruction", - "instruciton", "instruction", - "instructers", "instructors", - "instructior", "instructor", - "instructios", "instructors", - "instructivo", "instruction", - "instructons", "instructors", - "instruktion", "instruction", - "instrumenal", "instrumental", - "instrumetal", "instrumental", - "insturction", "instruction", - "insturctors", "instructors", - "insturments", "instruments", - "instutition", "institution", - "instutution", "institution", - "insufficent", "insufficient", - "insuinating", "insinuating", - "insuniating", "insinuating", - "insurgencey", "insurgency", - "intangiable", "intangible", - "intangibile", "intangible", - "inteferring", "interfering", - "integracion", "integration", - "integratron", "integration", - "integrering", "interfering", - "intelectual", "intellectual", - "inteligence", "intelligence", - "intellectul", "intellectuals", - "intellectus", "intellectuals", - "intellecual", "intellectual", - "intellegent", "intelligent", - "intelligant", "intelligent", - "intencional", "intentional", - "intentionly", "intentional", - "interaccion", "interaction", - "interactice", "interactive", - "interacties", "interacts", - "interactifs", "interacts", - "interactins", "interacts", - "interactios", "interacts", - "interactivo", "interaction", - "interactons", "interacts", - "interaktion", "interaction", - "interaktive", "interactive", - "interasting", "interacting", - "intercation", "integration", - "interceptin", "interception", - "intercoarse", "intercourse", - "intercource", "intercourse", - "interecting", "interacting", - "interection", "interaction", - "interelated", "interrelated", - "interersted", "interpreted", - "interesring", "interfering", - "interessted", "interested", - "interferece", "interference", - "interferens", "interferes", - "interferire", "interfere", - "interfernce", "interference", - "interferred", "interfere", - "interferres", "interferes", - "intergation", "integration", - "intergrated", "integrated", - "intermedate", "intermediate", - "intermedite", "intermediate", - "intermitent", "intermittent", - "internation", "international", - "interneters", "internets", - "internetese", "internets", - "internetest", "internets", - "interneting", "interesting", - "internetors", "internets", - "internettes", "internets", - "interperted", "interpreted", - "interperter", "interpreter", - "interprered", "interpreter", - "interpretor", "interpreter", - "interratial", "interracial", - "interresing", "interfering", - "interrogato", "interrogation", - "interrputed", "interrupted", - "interruping", "interrupting", - "interruptes", "interrupts", - "interruptis", "interrupts", - "intersecton", "intersection", - "interstelar", "interstellar", - "intertained", "intertwined", - "intertvined", "intertwined", - "intertwyned", "intertwined", - "intervalles", "intervals", - "intervation", "integration", - "interveiwed", "interviewed", - "interveiwer", "interviewer", - "intervenion", "intervening", - "intervenire", "intervene", - "interventie", "intervene", - "intervewing", "intervening", - "interviened", "interviewed", - "interviewes", "interviews", - "interviewie", "interviewer", - "intervining", "intervening", - "interwebers", "interwebs", - "interwiever", "interviewer", - "intestinces", "intestines", - "inticracies", "intricacies", - "intimadated", "intimidated", - "intimidades", "intimidated", - "intimidante", "intimidate", - "intimidatie", "intimidated", - "intimidatin", "intimidation", - "intimidaton", "intimidation", - "intimidiate", "intimidate", - "intiminated", "intimidated", - "intimitaded", "intimidated", - "intimitated", "intimidated", - "intiutively", "intuitively", - "intoleranse", "intolerance", - "intolerante", "intolerance", - "intolerence", "intolerance", - "intolernace", "intolerance", - "intolorance", "intolerance", - "intolorence", "intolerance", - "intorducing", "introducing", - "intorverted", "introverted", - "intoxicatin", "intoxication", - "intoxicaton", "intoxication", - "intoxinated", "intoxicated", - "intoxocated", "intoxicated", - "intracacies", "intricacies", - "intracicies", "intricacies", - "intraverted", "introverted", - "intrecacies", "intricacies", - "intrepreted", "interpreted", - "intrepreter", "interpreter", - "intrerupted", "interrupted", - "intricasies", "intricacies", - "intricicies", "intricacies", - "intrigueing", "intriguing", - "intrinsisch", "intrinsic", - "introducion", "introduction", - "introducted", "introduced", - "introductie", "introduce", - "introvertie", "introverted", - "introvertis", "introverts", - "intruducing", "introducing", - "intrumental", "instrumental", - "intuatively", "intuitively", - "intuitevely", "intuitively", - "intuitivley", "intuitively", - "intuituvely", "intuitively", - "inutitively", "intuitively", - "invaldiates", "invalidates", - "invalidades", "invalidates", - "invalidante", "invalidate", - "invariabley", "invariably", - "invariablly", "invariably", - "inventiones", "inventions", - "invesitgate", "investigate", - "investagate", "investigate", - "investiagte", "investigate", - "investigare", "investigate", - "invincibile", "invincible", - "invincinble", "invincible", - "invisibiity", "invisibility", - "invisibiliy", "invisibility", - "invokations", "invocations", - "involantary", "involuntary", - "involentary", "involuntary", - "involintary", "involuntary", - "involontary", "involuntary", - "involunatry", "involuntary", - "invulnerabe", "invulnerable", - "invulnerble", "invulnerable", - "iresistable", "irresistible", - "iresistably", "irresistibly", - "iresistible", "irresistible", - "iresistibly", "irresistibly", - "irrationaly", "irrationally", - "irrationnal", "irrational", - "islamisists", "islamists", - "islamisters", "islamists", - "islamistisk", "islamists", - "isntruments", "instruments", - "jacksonvile", "jacksonville", - "jailbroaken", "jailbroken", - "jailbrocken", "jailbroken", - "jounralists", "journalists", - "jouranlists", "journalists", - "journalisim", "journalism", - "journalistc", "journalistic", - "journolists", "journalists", - "judegmental", "judgemental", - "judgamental", "judgemental", - "judgementle", "judgemental", - "judgementsl", "judgemental", - "judgenental", "judgemental", - "jugdemental", "judgemental", - "juggernaugt", "juggernaut", - "juggernault", "juggernaut", - "juggernaunt", "juggernaut", - "justifyable", "justifiable", - "kidnappning", "kidnapping", - "kidnappping", "kidnapping", - "kilometeres", "kilometers", - "kindergaten", "kindergarten", - "knowledgabe", "knowledgable", - "knowledgble", "knowledgable", - "kryptoninte", "kryptonite", - "lacklusture", "lackluster", - "laughablely", "laughably", - "legalizaing", "legalizing", - "legalizaton", "legalization", - "legalizeing", "legalizing", - "legenadries", "legendaries", - "legendaires", "legendaries", - "legendarios", "legendaries", - "legendarisk", "legendaries", - "legendaryes", "legendaries", - "legenderies", "legendaries", - "legilsation", "legislation", - "legislacion", "legislation", - "legislativo", "legislation", - "legistation", "legislation", - "legistative", "legislative", - "legistators", "legislators", - "legitematly", "legitimately", - "legitimancy", "legitimacy", - "legitimatcy", "legitimacy", - "legitimatly", "legitimately", - "legitimetly", "legitimately", - "legnedaries", "legendaries", - "lengedaries", "legendaries", - "liberalisim", "liberalism", - "liberatrian", "libertarians", - "libertairan", "libertarians", - "libertarain", "libertarian", - "libertarias", "libertarians", - "libertarien", "libertarian", - "libertaryan", "libertarian", - "libertatian", "libertarian", - "liberterian", "libertarian", - "libguistics", "linguistics", - "libretarian", "libertarian", - "lieutennant", "lieutenant", - "lieutentant", "lieutenant", - "lightenning", "lightening", - "lightenting", "lightening", - "lightheared", "lighthearted", - "lightheated", "lighthearted", - "lightweigth", "lightweight", - "lightwieght", "lightweight", - "lightwright", "lightweight", - "ligthweight", "lightweight", - "limitaitons", "limitation", - "linguisitcs", "linguistics", - "linguisitic", "linguistic", - "lingusitics", "linguistics", - "lithuaninan", "lithuania", - "littlefiger", "littlefinger", - "littlefiner", "littlefinger", - "lockscreeen", "lockscreen", - "longevitity", "longevity", - "lotharingen", "lothringen", - "louisvillle", "louisville", - "maginficent", "magnificent", - "magneficent", "magnificent", - "magnicifent", "magnificent", - "magnifacent", "magnificent", - "magnifecent", "magnificent", - "magnificant", "magnificent", - "magnitudine", "magnitude", - "maintainted", "maintained", - "maintanance", "maintenance", - "maintanence", "maintenance", - "maintenence", "maintenance", - "maintianing", "maintaining", - "maintinaing", "maintaining", - "maintinance", "maintenance", - "maintinence", "maintenance", - "malfonction", "malfunction", - "malfucntion", "malfunction", - "malfunciton", "malfunction", - "malfuncting", "malfunction", - "malfunktion", "malfunction", - "malpractise", "malpractice", - "malpractive", "malpractice", - "maneouvring", "manoeuvring", - "manifestado", "manifesto", - "manifestano", "manifesto", - "manifestato", "manifesto", - "manifestion", "manifesto", - "manifestior", "manifesto", - "manifestons", "manifests", - "manifestors", "manifests", - "manipluated", "manipulated", - "manipualted", "manipulated", - "manipulatie", "manipulative", - "manipulatin", "manipulation", - "manipulaton", "manipulation", - "maniuplated", "manipulated", - "mannerisims", "mannerisms", - "manslaugher", "manslaughter", - "manslaugter", "manslaughter", - "manufacters", "manufactures", - "manufacteur", "manufactures", - "manufactued", "manufactured", - "manufactuer", "manufacture", - "manufacturs", "manufactures", - "manufacuter", "manufacture", - "manufacutre", "manufactures", - "manufatured", "manufactured", - "manupilated", "manipulated", - "marganilize", "marginalized", - "marhsmallow", "marshmallow", - "marijuannas", "marijuana", - "markerplace", "marketplace", - "marketpalce", "marketplace", - "marshamllow", "marshmallow", - "marshmalows", "marshmallows", - "masculanity", "masculinity", - "masculenity", "masculinity", - "masrhmallow", "marshmallow", - "mastermined", "mastermind", - "masterpeace", "masterpiece", - "masterpeice", "masterpiece", - "mastrubated", "masturbated", - "mastrubates", "masturbate", - "masturabted", "masturbated", - "masturbaing", "masturbating", - "masturbarte", "masturbate", - "masturbathe", "masturbated", - "masturbatie", "masturbated", - "masturbatin", "masturbation", - "masturbaton", "masturbation", - "masturbsted", "masturbated", - "masturpiece", "masterpiece", - "masuclinity", "masculinity", - "matchamking", "matchmaking", - "materalists", "materialist", - "materialsim", "materialism", - "mathamatics", "mathematics", - "mathcmaking", "matchmaking", - "mathemagics", "mathematics", - "mathemetics", "mathematics", - "mathimatics", "mathematics", - "matieralism", "materialism", - "maybelleine", "maybelline", - "maybelliene", "maybelline", - "maybellinne", "maybelline", - "maybellline", "maybelline", - "mdifielders", "midfielders", - "meatballers", "meatballs", - "mecernaries", "mercenaries", - "mechanicaly", "mechanically", - "mechanichal", "mechanical", - "mechaniclly", "mechanically", - "mechanicsms", "mechanisms", - "mechanisims", "mechanism", - "mechanismus", "mechanisms", - "medicaitons", "medications", - "medicineras", "medicines", - "meditatiing", "meditating", - "meditationg", "meditating", - "mentionning", "mentioning", - "mercanaries", "mercenaries", - "mercaneries", "mercenaries", - "mercenaires", "mercenaries", - "mercenarias", "mercenaries", - "mercenarios", "mercenaries", - "merceneries", "mercenaries", - "merchandice", "merchandise", - "merchandies", "merchandise", - "merchanidse", "merchandise", - "merchanters", "merchants", - "merchendise", "merchandise", - "merchindise", "merchandise", - "mercinaries", "mercenaries", - "mercineries", "mercenaries", - "metabolisim", "metabolism", - "metabolitic", "metabolic", - "metaphisics", "metaphysics", - "metaphorial", "metaphorical", - "metaphorics", "metaphors", - "metaphsyics", "metaphysics", - "metaphyiscs", "metaphysics", - "methodoligy", "methodology", - "metholodogy", "methodology", - "metropolian", "metropolitan", - "metropolies", "metropolis", - "metropollis", "metropolis", - "metropolois", "metropolis", - "micorcenter", "microcenter", - "micorphones", "microphones", - "microcender", "microcenter", - "microcentre", "microcenter", - "microcentro", "microcenter", - "microhpones", "microphones", - "microscrope", "microscope", - "microwavees", "microwaves", - "microwavers", "microwaves", - "midfeilders", "midfielders", - "midfiedlers", "midfielders", - "midfileders", "midfielders", - "midifelders", "midfielders", - "millienaire", "millionaire", - "millionairs", "millionaires", - "millionarie", "millionaire", - "millioniare", "millionaire", - "mindlessely", "mindlessly", - "mindlessley", "mindlessly", - "minimalstic", "minimalist", - "ministerens", "ministers", - "ministerios", "ministers", - "minneaoplis", "minneapolis", - "minneaplois", "minneapolis", - "minniapolis", "minneapolis", - "miraculaous", "miraculous", - "miraculosly", "miraculously", - "miraculousy", "miraculously", - "mircocenter", "microcenter", - "mircophones", "microphones", - "mircoscopic", "microscopic", - "miscairrage", "miscarriage", - "miscarraige", "miscarriage", - "miscarridge", "miscarriage", - "miscarriege", "miscarriage", - "mischeivous", "mischievous", - "mischevious", "mischievous", - "misdameanor", "misdemeanor", - "misdeamenor", "misdemeanor", - "misdemeaner", "misdemeanor", - "misdemenaor", "misdemeanor", - "misdemenors", "misdemeanors", - "misdimeanor", "misdemeanor", - "misdomeanor", "misdemeanor", - "miserablely", "miserably", - "misfortunte", "misfortune", - "misimformed", "misinformed", - "misinterept", "misinterpret", - "misinterpet", "misinterpret", - "misoginysts", "misogynist", - "misognyists", "misogynist", - "misogyinsts", "misogynist", - "misogynisic", "misogynistic", - "misogynistc", "misogynistic", - "misogynstic", "misogynist", - "missionaire", "missionaries", - "missionairy", "missionary", - "missionares", "missionaries", - "missionaris", "missionaries", - "missionarry", "missionary", - "missionnary", "missionary", - "mississipis", "mississippi", - "misspeeling", "misspelling", - "misspellled", "misspelled", - "mistakengly", "mistakenly", - "mistakently", "mistakenly", - "moderatedly", "moderately", - "moderateurs", "moderates", - "moderatorin", "moderation", - "modificaton", "modification", - "moisterizer", "moisturizer", - "moistruizer", "moisturizer", - "moisturizng", "moisturizing", - "moisturizor", "moisturizer", - "moistutizer", "moisturizer", - "moisutrizer", "moisturizer", - "moleculaire", "molecular", - "molestating", "molestation", - "moleststion", "molestation", - "momemtarily", "momentarily", - "momentairly", "momentarily", - "momentaraly", "momentarily", - "momentarely", "momentarily", - "momenterily", "momentarily", - "monestaries", "monasteries", - "monitoreada", "monitored", - "monitoreado", "monitored", - "monogameous", "monogamous", - "monolitihic", "monolithic", - "monopollies", "monopolies", - "monstorsity", "monstrosity", - "monstrasity", "monstrosity", - "monstrisity", "monstrosity", - "monstrocity", "monstrosity", - "monstrosoty", "monstrosity", - "monstrostiy", "monstrosity", - "monumentaal", "monumental", - "monumentais", "monuments", - "monumentals", "monuments", - "monumentous", "monuments", - "mositurizer", "moisturizer", - "mosntrosity", "monstrosity", - "motehrboard", "motherboard", - "mothebroard", "motherboards", - "motherbaord", "motherboard", - "motherboads", "motherboards", - "motherboars", "motherboards", - "motherborad", "motherboard", - "motherbords", "motherboards", - "motherobard", "motherboards", - "mothreboard", "motherboards", - "motivatinal", "motivational", - "motorcicles", "motorcycles", - "motorcylces", "motorcycles", - "mouthpeices", "mouthpiece", - "mulitplayer", "multiplayer", - "mulitplying", "multiplying", - "multipalyer", "multiplayer", - "multiplater", "multiplayer", - "multiplebgs", "multiples", - "multipleies", "multiples", - "multitaskng", "multitasking", - "multitudine", "multitude", - "multiverese", "multiverse", - "multyplayer", "multiplayer", - "multyplying", "multiplying", - "muncipality", "municipality", - "murdererous", "murderers", - "musicallity", "musically", - "mutliplayer", "multiplayer", - "mutliplying", "multiplying", - "mysterieuse", "mysteries", - "mysteriosly", "mysteriously", - "mysteriouly", "mysteriously", - "mysteriousy", "mysteriously", - "napoleonian", "napoleonic", - "narcisissim", "narcissism", - "narcisissts", "narcissist", - "narcisscism", "narcissism", - "narcisscist", "narcissist", - "narcissisim", "narcissism", - "narcississm", "narcissism", - "narcississt", "narcissist", - "narcissistc", "narcissistic", - "narcissitic", "narcissistic", - "narcisssism", "narcissism", - "narcisssist", "narcissist", - "narcissstic", "narcissist", - "natioanlist", "nationalist", - "nationailty", "nationality", - "nationalesl", "nationals", - "nationalisn", "nationals", - "nationalite", "nationalist", - "nationalits", "nationalist", - "nationalizm", "nationalism", - "nationalsim", "nationalism", - "neccesarily", "necessarily", - "necessairly", "necessarily", - "necessaties", "necessities", - "necesseraly", "necessarily", - "necesserily", "necessarily", - "necessiates", "necessities", - "necessitive", "necessities", - "neckbeardos", "neckbeards", - "neckbeardus", "neckbeards", - "necormancer", "necromancer", - "necromamcer", "necromancer", - "necromanser", "necromancer", - "necromencer", "necromancer", - "needlessley", "needlessly", - "negativeity", "negativity", - "negativelly", "negatively", - "negativitiy", "negativity", - "negiotating", "negotiating", - "negligiable", "negligible", - "negociating", "negotiating", - "negociation", "negotiation", - "negoitating", "negotiating", - "negoitation", "negotiation", - "negotiatied", "negotiate", - "negotiative", "negotiate", - "negotiatons", "negotiations", - "neigborhood", "neighborhood", - "neigbouring", "neighbouring", - "neighborhod", "neighborhood", - "neighbourgs", "neighbours", - "neighouring", "neighboring", - "nercomancer", "necromancer", - "nessasarily", "necessarily", - "neurologial", "neurological", - "neurosciene", "neuroscience", - "neutrallity", "neutrality", - "neverthelss", "nevertheless", - "neverthless", "nevertheless", - "newspapaers", "newspapers", - "newspappers", "newspapers", - "nieghboring", "neighboring", - "nightmarket", "nightmare", - "nonsencical", "nonsensical", - "nonsenscial", "nonsensical", - "nonsensicle", "nonsensical", - "normallized", "normalized", - "northwesten", "northwestern", - "nostalgisch", "nostalgic", - "noteworthly", "noteworthy", - "noticeabley", "noticeably", - "notificaton", "notification", - "notoriuosly", "notoriously", - "numericable", "numerical", - "nurtitional", "nutritional", - "nutricional", "nutritional", - "nutrutional", "nutritional", - "obamination", "abomination", - "obersvation", "observation", - "obilterated", "obliterated", - "objectivety", "objectivity", - "objectivify", "objectivity", - "objectivily", "objectivity", - "objectivley", "objectively", - "obliberated", "obliterated", - "obliderated", "obliterated", - "obligerated", "obliterated", - "oblitarated", "obliterated", - "obliteraded", "obliterated", - "obliterared", "obliterated", - "oblitirated", "obliterated", - "oblitorated", "obliterated", - "obliverated", "obliterated", - "observacion", "observation", - "observaiton", "observant", - "observasion", "observations", - "observating", "observation", - "observerats", "observers", - "obsessivley", "obsessive", - "obstruccion", "obstruction", - "obstruktion", "obstruction", - "obsturction", "obstruction", - "obversation", "observation", - "ocasionally", "occasionally", - "ocassionaly", "occasionally", - "occasionals", "occasions", - "occasionaly", "occasionally", - "occasionnal", "occasional", - "occassional", "occasional", - "occassioned", "occasioned", - "occurrances", "occurrences", - "offensivley", "offensively", - "offesnively", "offensively", - "officiallly", "officially", - "olbiterated", "obliterated", - "omniscienct", "omniscient", - "operacional", "operational", - "operasional", "operational", - "operationel", "operational", - "oppresssing", "oppressing", - "oppresssion", "oppression", - "opprotunity", "opportunity", - "optimisitic", "optimistic", - "optimizaton", "optimization", - "optmization", "optimization", - "orchestraed", "orchestrated", - "orchestrial", "orchestra", - "oreintation", "orientation", - "organisaton", "organisation", - "organiserad", "organised", - "organistion", "organisation", - "organizarea", "organizer", - "organizarem", "organizer", - "organizarme", "organizer", - "organizarte", "organizer", - "organiztion", "organization", - "oridinarily", "ordinarily", - "orientacion", "orientation", - "originially", "originally", - "originnally", "originally", - "origniality", "originality", - "ostensiably", "ostensibly", - "ostensibily", "ostensibly", - "outclasssed", "outclassed", - "outnunbered", "outnumbered", - "outperfroms", "outperform", - "outpreforms", "outperform", - "outrageosly", "outrageously", - "outrageouly", "outrageously", - "outragerous", "outrageous", - "outskirters", "outskirts", - "outsorucing", "outsourcing", - "outsourcade", "outsourced", - "outsoursing", "outsourcing", - "overbraking", "overbearing", - "overcapping", "overlapping", - "overcharing", "overarching", - "overclcoked", "overclocked", - "overclicked", "overclocked", - "overcloaked", "overclocked", - "overclocing", "overclocking", - "overclockig", "overclocking", - "overclocled", "overclocked", - "overcomeing", "overcoming", - "overcomming", "overcoming", - "overeaching", "overarching", - "overfapping", "overlapping", - "overheading", "overheating", - "overhooking", "overlooking", - "overhwelmed", "overwhelmed", - "overkapping", "overlapping", - "overklocked", "overclocked", - "overlapsing", "overlapping", - "overlcocked", "overclocked", - "overlcoking", "overlooking", - "overlooming", "overlooking", - "overloooked", "overlooked", - "overlordess", "overlords", - "overmapping", "overlapping", - "overpooling", "overlooking", - "overpovered", "overpowered", - "overpoweing", "overpowering", - "overreacing", "overreacting", - "overreactin", "overreaction", - "overreacton", "overreaction", - "overshaddow", "overshadowed", - "overshadowd", "overshadowed", - "overtapping", "overlapping", - "overthining", "overthinking", - "overthinkig", "overthinking", - "overvlocked", "overclocked", - "overwealmed", "overwhelmed", - "overwelming", "overwhelming", - "overwhelemd", "overwhelmed", - "overwhelimg", "overwhelm", - "overwheling", "overwhelming", - "overwhemled", "overwhelmed", - "overwhlemed", "overwhelmed", - "overwritted", "overwrite", - "pakistanais", "pakistani", - "pakistanezi", "pakistani", - "palceholder", "placeholder", - "palesitnian", "palestinians", - "palestenian", "palestinian", - "palestinain", "palestinians", - "palestinans", "palestinians", - "palestinier", "palestine", - "palistinian", "palestinian", - "palythrough", "playthrough", - "papanicalou", "papanicolaou", - "parachutage", "parachute", - "paragraphes", "paragraphs", - "paramedicks", "paramedics", - "paramedicos", "paramedics", - "parameteres", "parameters", - "paranthesis", "parenthesis", - "parapharsed", "paraphrase", - "paraprhased", "paraphrase", - "parasitisme", "parasites", - "parenthasis", "parenthesis", - "parenthesys", "parentheses", - "parenthises", "parenthesis", - "parenthisis", "parenthesis", - "parliamenty", "parliamentary", - "parntership", "partnership", - "parrallelly", "parallelly", - "partecipant", "participant", - "partecipate", "participate", - "parternship", "partnership", - "partiarchal", "patriarchal", - "particapate", "participate", - "particiapte", "participate", - "participait", "participant", - "participans", "participants", - "participare", "participate", - "participatd", "participant", - "participati", "participant", - "participats", "participant", - "participent", "participant", - "particpiate", "participated", - "particually", "particularly", - "particulaly", "particularly", - "particulary", "particularly", - "partnetship", "partnership", - "partonizing", "patronizing", - "passionatly", "passionately", - "passionetly", "passionately", - "passionnate", "passionate", - "passporters", "passports", - "pathologial", "pathological", - "patriarchia", "patriarchal", - "patriarcial", "patriarchal", - "patriarical", "patriarchal", - "patriotisch", "patriotic", - "patriotisim", "patriotism", - "patriottism", "patriotism", - "patronozing", "patronizing", - "peacefullly", "peacefully", - "pedestirans", "pedestrians", - "pedestrains", "pedestrians", - "pedophilies", "pedophile", - "pedophilles", "pedophile", - "penetracion", "penetration", - "penetrading", "penetrating", - "penetrarion", "penetration", - "penninsular", "peninsular", - "pennsylvnia", "pennsylvania", - "pepperocini", "pepperoni", - "percantages", "percentages", - "percautions", "precautions", - "percentille", "percentile", - "percpetions", "perceptions", - "percusssion", "percussion", - "perdicament", "predicament", - "perdictable", "predictable", - "perdictions", "predictions", - "perephirals", "peripherals", - "pereptually", "perpetually", - "perferences", "preferences", - "perfomrance", "performances", - "perforamnce", "performances", - "performaces", "performances", - "performacne", "performances", - "performanes", "performances", - "performanse", "performances", - "performence", "performance", - "performnace", "performances", - "perfromance", "performance", - "perhiperals", "peripherals", - "perihperals", "peripherals", - "periodicaly", "periodically", - "periperhals", "peripherals", - "periphereal", "peripheral", - "peripherial", "peripheral", - "periphirals", "peripherals", - "periphreals", "peripherals", - "periphrials", "peripherals", - "perjorative", "pejorative", - "perliminary", "preliminary", - "permamently", "permanently", - "permanantly", "permanently", - "permaturely", "prematurely", - "permenantly", "permanently", - "permenently", "permanently", - "perminantly", "permanently", - "perminently", "permanently", - "permisisons", "permissions", - "permissable", "permissible", - "permisssion", "permissions", - "pernamently", "permanently", - "perosnality", "personality", - "perparation", "preparation", - "perpatrated", "perpetrated", - "perpatrator", "perpetrator", - "perpatuated", "perpetuated", - "perpatuates", "perpetuates", - "perpertated", "perpetuated", - "perpertator", "perpetrators", - "perpetraded", "perpetrated", - "perpetrador", "perpetrator", - "perpetraron", "perpetrator", - "perpetrater", "perpetrator", - "perpetuaded", "perpetuated", - "perpetutate", "perpetuate", - "perpetuties", "perpetuates", - "perpitrated", "perpetrated", - "perpitrator", "perpetrator", - "perpretated", "perpetrated", - "perpretator", "perpetrators", - "perpsective", "perspective", - "perputrator", "perpetrator", - "perputually", "perpetually", - "perputuated", "perpetuated", - "perputuates", "perpetuates", - "perrogative", "prerogative", - "persceptive", "perspectives", - "persectuion", "persecution", - "persecucion", "persecution", - "persecusion", "persecution", - "persecutted", "persecuted", - "persepctive", "perspective", - "persicution", "persecution", - "persistance", "persistence", - "persistante", "persistent", - "persistense", "persistence", - "persistente", "persistence", - "personhoood", "personhood", - "perspecitve", "perspective", - "perspectief", "perspective", - "perspektive", "perspective", - "persuassion", "persuasion", - "persuassive", "persuasive", - "persucution", "persecution", - "persumption", "presumption", - "pertubation", "perturbation", - "pessimestic", "pessimistic", - "pharamcists", "pharmacist", - "phenomenona", "phenomena", - "philadelpha", "philadelphia", - "philadelpia", "philadelphia", - "philiphines", "philippines", - "philippenes", "philippines", - "philippenis", "philippines", - "philippides", "philippines", - "philippinas", "philippines", - "philippinos", "philippines", - "philisopher", "philosopher", - "phillipines", "philippines", - "philosipher", "philosopher", - "philosopers", "philosophers", - "philosophae", "philosopher", - "philosophia", "philosophical", - "philosopies", "philosophies", - "philosphies", "philosophies", - "philospoher", "philosopher", - "photograhed", "photographed", - "photograher", "photographer", - "photograhic", "photographic", - "photograhpy", "photography", - "photograped", "photographed", - "photograper", "photographer", - "photograpgh", "photographs", - "photograpic", "photographic", - "photogrpahs", "photographs", - "photogrpahy", "photography", - "physcedelic", "psychedelic", - "physciatric", "psychiatric", - "physcopaths", "psychopaths", - "piankillers", "painkillers", - "pilgrimmage", "pilgrimage", - "pitchforcks", "pitchforks", - "pitchforkes", "pitchforks", - "plaestinian", "palestinian", - "plagiariasm", "plagiarism", - "planeswaker", "planeswalker", - "planeswaler", "planeswalker", - "planeswalkr", "planeswalker", - "platfromers", "platformer", - "playhtrough", "playthrough", - "playthorugh", "playthrough", - "playthourgh", "playthrough", - "playthroguh", "playthroughs", - "playthrougs", "playthroughs", - "playthrouhg", "playthroughs", - "playthtough", "playthrough", - "playtrhough", "playthrough", - "ploretariat", "proletariat", - "policitally", "politically", - "policitians", "politicians", - "politicains", "politicians", - "politicanti", "politician", - "politiciens", "politicians", - "politiicans", "politician", - "polititians", "politicians", - "polyphonyic", "polyphonic", - "pomegranite", "pomegranate", - "popluations", "populations", - "poportional", "proportional", - "popoulation", "population", - "porjectiles", "projectiles", - "porletariat", "proletariat", - "pornagraphy", "pornography", - "pornograghy", "pornography", - "pornograhpy", "pornography", - "pornograpgy", "pornography", - "pornogrophy", "pornography", - "pornogrpahy", "pornography", - "porportions", "proportions", - "portestants", "protestants", - "portuguease", "portuguese", - "portuguesse", "portuguese", - "positionial", "positional", - "positionnal", "positional", - "positionned", "positioned", - "positiveity", "positivity", - "positiviely", "positively", - "positivisme", "positives", - "positivisty", "positivity", - "positivitey", "positivity", - "positivitiy", "positivity", - "possesseurs", "possesses", - "possesssion", "possessions", - "possestions", "possessions", - "possiblilty", "possibility", - "potencially", "potentially", - "potentailly", "potentially", - "powerhourse", "powerhouse", - "powerlifing", "powerlifting", - "powerliftng", "powerlifting", - "pracitcally", "practically", - "practicarlo", "practical", - "practioners", "practitioners", - "practitions", "practitioners", - "pragmatisch", "pragmatic", - "precausions", "precautions", - "precedessor", "predecessor", - "precendence", "precedence", - "precentages", "percentages", - "preconceved", "preconceived", - "preconcieve", "preconceived", - "precuations", "precautions", - "predacessor", "predecessor", - "predecesser", "predecessor", - "predections", "predictions", - "predescesor", "predecessors", - "predesessor", "predecessors", - "predesposed", "predisposed", - "predessecor", "predecessor", - "predicatble", "predictable", - "predicement", "predicament", - "predicessor", "predecessor", - "prediciment", "predicament", - "predicitons", "predictions", - "predictible", "predictable", - "predictious", "predictions", - "predictment", "predicament", - "predisposte", "predisposed", - "predocessor", "predecessor", - "preferabbly", "preferably", - "preferabely", "preferable", - "preferabley", "preferably", - "preferablly", "preferably", - "preferances", "preferences", - "preferenser", "preferences", - "preferental", "preferential", - "preferentes", "preferences", - "preferrably", "preferably", - "preferrring", "preferring", - "preformance", "performance", - "pregnanices", "pregnancies", - "pregnencies", "pregnancies", - "pregorative", "prerogative", - "preipherals", "peripherals", - "prejudicies", "prejudice", - "preleminary", "preliminary", - "prelimanary", "preliminary", - "prelimenary", "preliminary", - "premanently", "permanently", - "prematuraly", "prematurely", - "prematurily", "prematurely", - "prematurley", "prematurely", - "premilinary", "preliminary", - "premissible", "permissible", - "premissions", "permissions", - "preorderded", "preordered", - "preorderers", "preorders", - "preparacion", "preparation", - "preperation", "preparation", - "prepetrated", "perpetrated", - "prepetrator", "perpetrator", - "prepetually", "perpetually", - "prepetuated", "perpetuated", - "prepetuates", "perpetuates", - "preporation", "preparation", - "preposterus", "preposterous", - "prerequesit", "prerequisite", - "prerequiste", "prerequisite", - "prerequites", "prerequisite", - "prerogitive", "prerogative", - "prerogotive", "prerogative", - "prescripton", "prescription", - "presecution", "persecution", - "presedintia", "presidential", - "presentaion", "presentation", - "presentatin", "presentations", - "preservaton", "preservation", - "preservered", "preserved", - "presidencey", "presidency", - "presidental", "presidential", - "presidentcy", "presidency", - "presistence", "persistence", - "presitgious", "prestigious", - "presitigous", "prestigious", - "presomption", "presumption", - "prespective", "perspective", - "pressureing", "pressuring", - "prestegious", "prestigious", - "prestigeous", "prestigious", - "prestigieus", "prestigious", - "prestigiosa", "prestigious", - "prestigiose", "prestigious", - "prestigiosi", "prestigious", - "prestigioso", "prestigious", - "prestiguous", "prestigious", - "presumabely", "presumably", - "presumabley", "presumably", - "presumptous", "presumptuous", - "presumptuos", "presumptuous", - "pretencious", "pretentious", - "pretendendo", "pretended", - "pretensious", "pretentious", - "pretentieus", "pretentious", - "prevailaing", "prevailing", - "prevailling", "prevailing", - "preventitve", "preventative", - "preventivno", "prevention", - "primatively", "primitively", - "princessses", "princesses", - "principales", "principles", - "principalis", "principals", - "principielt", "principle", - "privatizied", "privatized", - "priveledges", "privileges", - "privelleges", "privileges", - "privilegeds", "privileges", - "privilegied", "privileged", - "privilegien", "privilege", - "privilegier", "privilege", - "privilegies", "privilege", - "proactivley", "proactive", - "probabilaty", "probability", - "probabilite", "probabilities", - "probalibity", "probability", - "probelmatic", "problematic", - "problamatic", "problematic", - "problimatic", "problematic", - "problomatic", "problematic", - "proccedings", "proceedings", - "proccessing", "processing", - "proceddings", "proceedings", - "procedureal", "procedural", - "procedurial", "procedural", - "procedurile", "procedure", - "processesor", "processors", - "processeurs", "processes", - "processsors", "processors", - "procrastion", "procreation", - "procriation", "procreation", - "prodcutions", "productions", - "prodictions", "productions", - "producerats", "producers", - "producitons", "productions", - "productioin", "productions", - "productivos", "productions", - "productivty", "productivity", - "produktions", "productions", - "professinal", "professional", - "professionl", "professionals", - "professoras", "professors", - "professores", "professors", - "professorin", "profession", - "professsion", "professions", - "proficiancy", "proficiency", - "proficienct", "proficient", - "proficienty", "proficiency", - "proficinecy", "proficiency", - "profitabile", "profitable", - "progerssion", "progressions", - "progerssive", "progressives", - "programable", "programmable", - "programmare", "programmer", - "programmars", "programmers", - "programmate", "programme", - "programmets", "programmers", - "programmeur", "programmer", - "programmier", "programmer", - "programmmed", "programme", - "programmmer", "programme", - "progresison", "progressions", - "progressers", "progresses", - "progressief", "progressive", - "progressino", "progressions", - "progressivo", "progression", - "progressoin", "progressions", - "progressvie", "progressives", - "prohabition", "prohibition", - "prohibation", "prohibition", - "prohibicion", "prohibition", - "prohibiteds", "prohibits", - "prohibitied", "prohibited", - "prohibitifs", "prohibits", - "prohibitivo", "prohibition", - "prohibitons", "prohibits", - "prohibitted", "prohibited", - "projecticle", "projectile", - "projectives", "projectiles", - "projectlies", "projectiles", - "prolateriat", "proletariat", - "proletariet", "proletariat", - "proletariot", "proletariat", - "proletaryat", "proletariat", - "proleteriat", "proletariat", - "prolitariat", "proletariat", - "prologomena", "prolegomena", - "promenantly", "prominently", - "promenently", "prominently", - "prometheius", "prometheus", - "prometheous", "prometheus", - "promethesus", "prometheus", - "prometheyus", "prometheus", - "promimently", "prominently", - "prominantly", "prominently", - "prominately", "prominently", - "promiscious", "promiscuous", - "promocional", "promotional", - "promsicuous", "promiscuous", - "pronography", "pornography", - "pronoucning", "pronouncing", - "pronounched", "pronounced", - "pronunciato", "pronunciation", - "propaganada", "propaganda", - "properitary", "proprietary", - "propertiary", "proprietary", - "propertions", "proportions", - "prophechies", "prophecies", - "propiertary", "proprietary", - "propogation", "propagation", - "proponenets", "proponents", - "proponentes", "proponents", - "proporition", "proposition", - "proportians", "proportions", - "proportinal", "proportional", - "proposicion", "proposition", - "propositivo", "proposition", - "propostions", "proportions", - "propreitary", "proprietary", - "propriatary", "proprietary", - "propriatery", "proprietary", - "propriatory", "proprietary", - "proprietery", "proprietary", - "proprietory", "proprietary", - "propriotary", "proprietary", - "proprotions", "proportions", - "propsective", "prospective", - "propulstion", "propulsion", - "prosectuion", "prosecution", - "prosectuors", "prosecutors", - "prosecuters", "prosecutors", - "prosicution", "prosecution", - "prosocution", "prosecution", - "prosperious", "prosperous", - "prospertity", "prosperity", - "prospettive", "prospective", - "prostethics", "prosthetic", - "prosthethic", "prosthetic", - "prostitites", "prostitutes", - "prostitiute", "prostitute", - "prostituate", "prostitute", - "prostitudes", "prostitutes", - "prostituees", "prostitutes", - "prostituion", "prostitution", - "prostitures", "prostitutes", - "prostitutas", "prostitutes", - "prostitutie", "prostitute", - "prostitutin", "prostitution", - "prostitutke", "prostitutes", - "prostituton", "prostitution", - "prostitutos", "prostitutes", - "protability", "portability", - "protaganist", "protagonist", - "protaginist", "protagonist", - "protagnoist", "protagonist", - "protagoinst", "protagonists", - "protagonits", "protagonists", - "protagonsit", "protagonists", - "protectings", "protections", - "protectoras", "protectors", - "protectores", "protectors", - "protectrons", "protections", - "protelariat", "proletariat", - "protestents", "protestants", - "protistants", "protestants", - "protoganist", "protagonist", - "protogonist", "protagonist", - "protostants", "protestants", - "protototype", "prototype", - "provacative", "provocative", - "provacotive", "provocative", - "provicative", "provocative", - "providencie", "providence", - "provinciaal", "provincial", - "provinicial", "provincial", - "provisiones", "provisions", - "provoactive", "provocative", - "provocatief", "provocative", - "provocitive", "provocative", - "provocotive", "provocative", - "provokative", "provocative", - "pscyhedelic", "psychedelic", - "pscyhiatric", "psychiatric", - "pscyhopaths", "psychopaths", - "pshyciatric", "psychiatric", - "pshycopaths", "psychopaths", - "psychaitric", "psychiatric", - "psychedilic", "psychedelic", - "psychedleic", "psychedelics", - "psychiatist", "psychiatrist", - "psychidelic", "psychedelic", - "psychodelic", "psychedelic", - "psychopants", "psychopaths", - "psychopatch", "psychopath", - "psychopatic", "psychopathic", - "psychotisch", "psychotic", - "psychriatic", "psychiatric", - "publikation", "publication", - "punctiation", "punctuation", - "puncutation", "punctuation", - "punshiments", "punishments", - "punsihments", "punishments", - "purchaseing", "purchasing", - "purchashing", "purchasing", - "purposefuly", "purposefully", - "pyschedelic", "psychedelic", - "pyschiatric", "psychiatric", - "pyschopaths", "psychopaths", - "qaurterback", "quarterback", - "qualificato", "qualification", - "qualifieres", "qualifiers", - "quantitaive", "quantitative", - "quantitatve", "quantitative", - "quantitites", "quantities", - "quantitties", "quantities", - "quarantaine", "quarantine", - "quarantenni", "quarantine", - "quartercask", "quarterbacks", - "quesitoning", "questioning", - "questionned", "questioned", - "questonable", "questionable", - "radiaoctive", "radioactive", - "radioactice", "radioactive", - "radioactief", "radioactive", - "radioaktive", "radioactive", - "radiocative", "radioactive", - "raidoactive", "radioactive", - "reaccurring", "recurring", - "reactionair", "reactionary", - "realibility", "reliability", - "realistisch", "realistic", - "reaserchers", "researchers", - "reaserching", "researching", - "reasonabley", "reasonably", - "reasonablly", "reasonably", - "reassureing", "reassuring", - "reassurring", "reassuring", - "rebuildling", "rebuilding", - "rebuplicans", "republicans", - "reccomended", "recommended", - "receptionst", "receptionist", - "recgonition", "recognition", - "recgonizing", "recognizing", - "rechargable", "rechargeable", - "recipientes", "recipients", - "reciporcate", "reciprocate", - "recipricate", "reciprocate", - "reciprocant", "reciprocate", - "reciprocite", "reciprocate", - "recivership", "receivership", - "reclutantly", "reluctantly", - "recognicing", "recognizing", - "recognision", "recognition", - "recomending", "recommending", - "recommandes", "recommends", - "recommendes", "recommends", - "recommented", "recommended", - "reconcilled", "reconcile", - "recongition", "recognition", - "recongizing", "recognizing", - "reconsidder", "reconsider", - "recrational", "recreational", - "recrutiment", "recruitment", - "rectangluar", "rectangular", - "rectangualr", "rectangular", - "rectengular", "rectangular", - "recuritment", "recruitment", - "redundantcy", "redundancy", - "reevalulate", "reevaluate", - "reevalutate", "reevaluate", - "reevaulated", "reevaluate", - "refelctions", "reflections", - "referancing", "referencing", - "refereneced", "referenced", - "refereneces", "references", - "referincing", "referencing", - "referrences", "references", - "reflectivos", "reflections", - "refreshener", "refresher", - "refrubished", "refurbished", - "refubrished", "refurbished", - "refurbushed", "refurbished", - "regeneratin", "regeneration", - "regeneraton", "regeneration", - "registerdns", "registers", - "registeries", "registers", - "registerred", "registered", - "registraion", "registration", - "regocnition", "recognition", - "regresssion", "regression", - "regresssive", "regressive", - "regualtions", "regulations", - "regulationg", "regulating", - "regulatiors", "regulators", - "reinassance", "renaissance", - "reinforcemt", "reinforcement", - "reinfornced", "reinforced", - "reinitalise", "reinitialise", - "reinitalize", "reinitialize", - "reinstaling", "reinstalling", - "reinstallng", "reinstalling", - "reisntalled", "reinstalled", - "relaibility", "reliability", - "relatiation", "retaliation", - "relationshp", "relationships", - "relativiser", "relatives", - "relativisme", "relatives", - "relativitiy", "relativity", - "relativitly", "relativity", - "relcutantly", "reluctantly", - "relentlesly", "relentlessly", - "relentlessy", "relentlessly", - "relevations", "revelations", - "relfections", "reflections", - "religeously", "religiously", - "religionens", "religions", - "religioners", "religions", - "relpacement", "replacement", - "reluctently", "reluctantly", - "remarkabley", "remarkably", - "remarkablly", "remarkably", - "remasterred", "remastered", - "remembrence", "remembrance", - "reminescent", "reminiscent", - "reminicient", "reminiscent", - "reminiscant", "reminiscent", - "reminiscint", "reminiscent", - "reminscient", "reminiscent", - "reminsicent", "reminiscent", - "renaiisance", "renaissance", - "renaiscance", "renaissance", - "renaissanse", "renaissance", - "renaissence", "renaissance", - "renassaince", "renaissance", - "renassiance", "renaissance", - "reniassance", "renaissance", - "rennovating", "renovating", - "rennovation", "renovation", - "repalcement", "replacement", - "repbulicans", "republicans", - "repeateadly", "repeatedly", - "repectively", "respectively", - "repersented", "represented", - "replacemnet", "replacements", - "replacemnts", "replacements", - "repleacable", "replaceable", - "repositiory", "repository", - "representas", "represents", - "representes", "represents", - "represssion", "repression", - "reproducion", "reproduction", - "reproducive", "reproductive", - "repsectable", "respectable", - "repsonsible", "responsible", - "repsonsibly", "responsibly", - "republcians", "republicans", - "republician", "republican", - "republicons", "republicans", - "repuglicans", "republicans", - "requeriment", "requirement", - "requierment", "requirements", - "resemblence", "resemblance", - "resemblense", "resembles", - "reserachers", "researchers", - "reseraching", "researching", - "resgination", "resignation", - "residencial", "residential", - "residentail", "residential", - "residentual", "residential", - "resignacion", "resignation", - "resignating", "resignation", - "resignement", "resignment", - "resignition", "resignation", - "resintalled", "reinstalled", - "resistansen", "resistances", - "resistanses", "resistances", - "resistences", "resistances", - "resistnaces", "resistances", - "resoltuions", "resolutions", - "resotration", "restoration", - "resoultions", "resolutions", - "respecatble", "respectable", - "respectabil", "respectable", - "respectfuly", "respectfully", - "respectible", "respectable", - "respectivly", "respectively", - "respectuful", "respectful", - "respektable", "respectable", - "resperatory", "respiratory", - "resperitory", "respiratory", - "respiritory", "respiratory", - "respitatory", "respiratory", - "responcible", "responsible", - "responcibly", "responsibly", - "respondendo", "responded", - "responisble", "responsible", - "responisbly", "responsibly", - "responsable", "responsible", - "responsably", "responsibly", - "responsbile", "responsible", - "responsbily", "responsibly", - "responsibel", "responsibly", - "responsibil", "responsibly", - "responsivle", "responsive", - "resporatory", "respiratory", - "respository", "repository", - "respriatory", "respiratory", - "ressembling", "resembling", - "ressurected", "resurrected", - "restaraunts", "restaurants", - "restaruants", "restaurants", - "restauraunt", "restaurant", - "restaurents", "restaurants", - "resteraunts", "restaurants", - "restirction", "restriction", - "restorarion", "restoration", - "restorating", "restoration", - "restrainted", "restrained", - "restrective", "restrictive", - "restriccion", "restriction", - "restricitng", "restricting", - "restriciton", "restrictions", - "restricitve", "restrictive", - "restricteds", "restricts", - "restricters", "restricts", - "restrictied", "restrictive", - "restrictifs", "restricts", - "restrictins", "restricts", - "restrictios", "restricts", - "restrictivo", "restriction", - "restrictons", "restricts", - "restriktion", "restriction", - "restriktive", "restrictive", - "restrittive", "restrictive", - "restructing", "restricting", - "restruction", "restriction", - "restuarants", "restaurants", - "resturaunts", "restaurants", - "resurecting", "resurrecting", - "resurrecion", "resurrection", - "retailation", "retaliation", - "retalitated", "retaliated", - "retardathon", "retardation", - "retardating", "retardation", - "retardatron", "retardation", - "retartation", "retardation", - "retirbution", "retribution", - "retrebution", "retribution", - "retribucion", "retribution", - "retribuiton", "retribution", - "retributivo", "retribution", - "retribvtion", "retribution", - "retrobution", "retribution", - "retrubution", "retribution", - "revealtions", "revelations", - "revelaitons", "revelations", - "revolations", "revolutions", - "revoultions", "revolutions", - "ridiculious", "ridiculous", - "ridiculosly", "ridiculously", - "ridiculouly", "ridiculously", - "ridiculousy", "ridiculously", - "rightfullly", "rightfully", - "rolepalying", "roleplaying", - "romanticaly", "romantically", - "roundabaout", "roundabout", - "roundabount", "roundabout", - "rudimentery", "rudimentary", - "rudimentory", "rudimentary", - "ruidmentary", "rudimentary", - "sacrifacing", "sacrificing", - "sacrificare", "sacrifice", - "sacrificied", "sacrifice", - "sacrificies", "sacrifice", - "sacrifieced", "sacrificed", - "sacrifising", "sacrificing", - "sacrifizing", "sacrificing", - "salughtered", "slaughtered", - "sanctionned", "sanctioned", - "sarcastisch", "sarcastic", - "saskatchewn", "saskatchewan", - "saskatchwan", "saskatchewan", - "satisfacion", "satisfaction", - "satisfacory", "satisfactory", - "scandanavia", "scandinavia", - "scandanivia", "scandinavian", - "scandenavia", "scandinavia", - "scandianvia", "scandinavian", - "scandimania", "scandinavia", - "scandinaiva", "scandinavian", - "scandinavan", "scandinavian", - "scandivania", "scandinavian", - "scandonavia", "scandinavia", - "scarificing", "sacrificing", - "scheduleing", "scheduling", - "schedulling", "scheduling", - "schoalrship", "scholarships", - "scholarhips", "scholarship", - "scholarstic", "scholastic", - "scholership", "scholarship", - "scholorship", "scholarship", - "scientiests", "scientists", - "scnadinavia", "scandinavia", - "scrambleing", "scrambling", - "screenshoot", "screenshot", - "seamlessley", "seamlessly", - "sedentarity", "sedentary", - "seflishness", "selfishness", - "segergation", "segregation", - "segragation", "segregation", - "segregacion", "segregation", - "segretation", "segregation", - "segrigation", "segregation", - "selectivley", "selectively", - "selfeshness", "selfishness", - "senitmental", "sentimental", - "sensacional", "sensational", - "sensasional", "sensational", - "sensationel", "sensational", - "sensetional", "sensational", - "sensitivety", "sensitivity", - "sentamental", "sentimental", - "sentemental", "sentimental", - "sentenceing", "sentencing", - "sentimentos", "sentiments", - "sentimentul", "sentimental", - "separatedly", "separately", - "separatelly", "separately", - "separatisme", "separates", - "separatiste", "separates", - "sepculating", "speculating", - "serivceable", "serviceable", - "serviciable", "serviceable", - "settelement", "settlement", - "settelments", "settlements", - "settlemetns", "settlements", - "sexualizied", "sexualized", - "shakeapeare", "shakespeare", - "shakepseare", "shakespeare", - "shakesphere", "shakespeare", - "shanenigans", "shenanigans", - "shareholdes", "shareholders", - "sharpeneing", "sharpening", - "sharpenning", "sharpening", - "shatterling", "shattering", - "shatterring", "shattering", - "sheakspeare", "shakespeare", - "shenadigans", "shenanigans", - "shenanagans", "shenanigans", - "shenanagins", "shenanigans", - "shenanegans", "shenanigans", - "shenanegins", "shenanigans", - "shenangians", "shenanigans", - "shenanigens", "shenanigans", - "shenanigins", "shenanigans", - "shenenigans", "shenanigans", - "sheninigans", "shenanigans", - "shennaigans", "shenanigans", - "shortenning", "shortening", - "shortenting", "shortening", - "signficiant", "significant", - "signifantly", "significantly", - "significane", "significance", - "significato", "significant", - "signifigant", "significant", - "signifikant", "significant", - "signitories", "signatories", - "signularity", "singularity", - "similarites", "similarities", - "similarlity", "similarity", - "similiarity", "similarity", - "simluations", "simulations", - "simplefying", "simplifying", - "simplicitly", "simplicity", - "simplifiing", "simplifying", - "simplisitic", "simplistic", - "simplyifing", "simplifying", - "simualtions", "simulations", - "simulatious", "simulations", - "simultaneos", "simultaneous", - "simultaneus", "simultaneous", - "simultanous", "simultaneous", - "singluarity", "singularity", - "singualrity", "singularity", - "singulairty", "singularity", - "singularily", "singularity", - "sitautional", "situational", - "situacional", "situational", - "situationly", "situational", - "siutational", "situational", - "skatebaords", "skateboard", - "skateboader", "skateboard", - "skepticisim", "skepticism", - "skillshoots", "skillshots", - "skillshosts", "skillshots", - "slaugthered", "slaughtered", - "slefishness", "selfishness", - "sluaghtered", "slaughtered", - "smarthpones", "smartphones", - "snowboaring", "snowboarding", - "snowbolling", "snowballing", - "snowfalling", "snowballing", - "socailizing", "socializing", - "socialicing", "socializing", - "socialistes", "socialists", - "socialistos", "socialists", - "socializare", "socialize", - "sociapathic", "sociopathic", - "sociologial", "sociological", - "sociopathes", "sociopaths", - "sociopathis", "sociopaths", - "sociophatic", "sociopathic", - "solidariety", "solidarity", - "somethingis", "somethings", - "sorrounding", "surrounding", - "soundtrakcs", "soundtracks", - "southamtpon", "southampton", - "southanpton", "southampton", - "southapmton", "southampton", - "southernese", "southerners", - "southerness", "southerners", - "southernest", "southerners", - "southernors", "southerners", - "southmapton", "southampton", - "southtampon", "southampton", - "soveregnity", "sovereignty", - "sovereighty", "sovereignty", - "sovereingty", "sovereignty", - "sovereinity", "sovereignty", - "soveriegnty", "sovereignty", - "soveriengty", "sovereignty", - "soverignity", "sovereignty", - "specailists", "specialists", - "specailized", "specialized", - "specailizes", "specializes", - "specatcular", "spectacular", - "specialiced", "specialized", - "specialices", "specializes", - "specialites", "specializes", - "speciallist", "specialist", - "speciallity", "specially", - "speciallize", "specialize", - "specialzied", "specialized", - "specifcally", "specifically", - "specificaly", "specifically", - "specificato", "specification", - "specificies", "specifics", - "specifiying", "specifying", - "specilaized", "specialize", - "speciliazed", "specialize", - "spectatores", "spectators", - "spectatular", "spectacular", - "spectauclar", "spectacular", - "spectaulars", "spectaculars", - "spectecular", "spectacular", - "specualting", "speculating", - "specualtion", "speculation", - "specualtive", "speculative", - "specularite", "speculative", - "speculaties", "speculative", - "spiritualiy", "spiritually", - "spiritualty", "spirituality", - "spirituella", "spiritually", - "spirtiually", "spiritually", - "spirutually", "spiritually", - "spitirually", "spiritually", - "sponatenous", "spontaneous", - "sponatneous", "spontaneous", - "sponsership", "sponsorship", - "sponsorhips", "sponsorship", - "sponsorhsip", "sponsorship", - "sponsorshop", "sponsorship", - "spontaenous", "spontaneous", - "spontainous", "spontaneous", - "spontaneuos", "spontaneous", - "spontanious", "spontaneous", - "sponteanous", "spontaneous", - "sponteneous", "spontaneous", - "spreadhseet", "spreadsheet", - "spreadsheat", "spreadsheet", - "spreadshets", "spreadsheets", - "spreedsheet", "spreadsheet", - "springfeild", "springfield", - "springfiled", "springfield", - "sprinklered", "sprinkled", - "squirrelies", "squirrels", - "squirrelius", "squirrels", - "stabilizare", "stabilize", - "stabilizied", "stabilize", - "stabilizier", "stabilize", - "stabilizies", "stabilize", - "staggerring", "staggering", - "staggerwing", "staggering", - "stationairy", "stationary", - "stationerad", "stationed", - "stationnary", "stationary", - "statisitcal", "statistical", - "statisticly", "statistical", - "statistisch", "statistics", - "statsitical", "statistical", - "stereotpyes", "stereotypes", - "stereotying", "stereotyping", - "steriotypes", "stereotypes", - "steroetypes", "stereotypes", - "steryotypes", "stereotypes", - "stimluating", "stimulating", - "stimualting", "stimulating", - "stimualtion", "stimulation", - "stimulantes", "stimulants", - "stockpilled", "stockpile", - "stormfrount", "stormfront", - "storyteling", "storytelling", - "straightden", "straightened", - "straightend", "straightened", - "straightmen", "straighten", - "straightned", "straightened", - "straightner", "straighten", - "strangeshit", "strangest", - "strategisch", "strategic", - "strategiske", "strategies", - "strawberies", "strawberries", - "strawberrry", "strawberry", - "strawbrerry", "strawberry", - "strenghened", "strengthened", - "strenghtend", "strengthen", - "strenghtens", "strengthen", - "strengtened", "strengthened", - "structurels", "structures", - "strugglebus", "struggles", - "struggleing", "struggling", - "stubborness", "stubbornness", - "stutterring", "stuttering", - "subcatagory", "subcategory", - "subconscius", "subconscious", - "subconscous", "subconscious", - "subisdizing", "subsidizing", - "subjectivly", "subjectively", - "submergered", "submerged", - "submisisons", "submissions", - "subredddits", "subreddits", - "subscirbers", "subscribers", - "subscribbed", "subscribe", - "subscribber", "subscriber", - "subscriping", "subscribing", - "subscriptin", "subscriptions", - "subscripton", "subscription", - "subsequenty", "subsequently", - "subsidiezed", "subsidized", - "subsidizied", "subsidized", - "subsidizies", "subsidize", - "subsiziding", "subsidizing", - "subsquently", "subsequently", - "subsrcibers", "subscribers", - "substancial", "substantial", - "substansial", "substantial", - "substansive", "substantive", - "substantied", "substantive", - "substanties", "substantive", - "substential", "substantial", - "substitiute", "substitute", - "substituded", "substituted", - "substitudes", "substitutes", - "substituion", "substitution", - "substitures", "substitutes", - "substitutie", "substitutes", - "substitutos", "substitutes", - "substitutue", "substitutes", - "substracted", "subtracted", - "suburburban", "suburban", - "succesfully", "successfully", - "successeurs", "successes", - "successfull", "successful", - "successfuly", "successfully", - "successsion", "succession", - "successully", "successfully", - "succsesfull", "successfully", - "sucessfully", "successfully", - "sucseptible", "susceptible", - "sufficently", "sufficiently", - "suggestieve", "suggestive", - "sumbissions", "submissions", - "sunglassses", "sunglasses", - "superceeded", "superseded", - "superficiel", "superficial", - "superfulous", "superfluous", - "superhereos", "superhero", - "superifical", "superficial", - "superiorest", "superiors", - "supermacist", "supremacist", - "supermakert", "supermarkets", - "supermakret", "supermarkets", - "supermakter", "supermarkets", - "supermarkts", "supermarkets", - "supermaster", "supermarkets", - "supernatual", "supernatural", - "supersition", "supervision", - "superstiton", "superstition", - "supervisers", "supervisors", - "supervisior", "supervisor", - "suplimented", "supplemented", - "supplaments", "supplements", - "supplemetal", "supplemental", - "supporteurs", "supporters", - "supposedely", "supposedly", - "supposidely", "supposedly", - "supposingly", "supposedly", - "suppresions", "suppression", - "suppresssor", "suppressor", - "supramacist", "supremacist", - "supremacits", "supremacist", - "supremasist", "supremacist", - "supremicist", "supremacist", - "suprimacist", "supremacist", - "suprisingly", "surprisingly", - "suprizingly", "surprisingly", - "suroundings", "surroundings", - "surpemacist", "supremacist", - "surprisinly", "surprisingly", - "surreptious", "surreptitious", - "surroundign", "surroundings", - "surroundigs", "surrounds", - "surroundins", "surrounds", - "surroundngs", "surrounds", - "surveilence", "surveillance", - "survivabily", "survivability", - "susbtantial", "substantial", - "susbtantive", "substantive", - "suscepitble", "susceptible", - "susceptable", "susceptible", - "suscpetible", "susceptible", - "susecptible", "susceptible", - "suspectible", "susceptible", - "suspiciosly", "suspiciously", - "suspiciouly", "suspiciously", - "suspiciouns", "suspicion", - "suspicision", "suspicions", - "suspicisons", "suspicions", - "sustainible", "sustainable", - "switerzland", "switzerland", - "switserland", "switzerland", - "switzlerand", "switzerland", - "swizterland", "switzerland", - "swtizerland", "switzerland", - "symapthetic", "sympathetic", - "symmertical", "symmetrical", - "sympathatic", "sympathetic", - "sympathiers", "sympathizers", - "sympathsize", "sympathize", - "sympethetic", "sympathetic", - "symphatetic", "sympathetic", - "symphatized", "sympathize", - "symphatizer", "sympathizers", - "symphatizes", "sympathize", - "sympothetic", "sympathetic", - "synthesasia", "synthesis", - "synthesesia", "synthesis", - "sypmathetic", "sympathetic", - "tabelspoons", "tablespoons", - "tablepsoons", "tablespoons", - "tablespooon", "tablespoon", - "tablesppons", "tablespoons", - "tailgateing", "tailgating", - "tailgatting", "tailgating", - "tangentialy", "tangentially", - "techincally", "technically", - "techincians", "technicians", - "techiniques", "techniques", - "techncially", "technically", - "technicalty", "technicality", - "technichian", "technician", - "technicials", "technicians", - "techniciens", "technicians", - "technitians", "technicians", - "technnology", "technology", - "technologia", "technological", - "techticians", "technicians", - "teleportato", "teleportation", - "teleportion", "teleporting", - "teleproting", "teleporting", - "temeprature", "temperature", - "temparament", "temperament", - "temparature", "temperature", - "temparement", "temperament", - "tempearture", "temperatures", - "temperamant", "temperament", - "temperarily", "temporarily", - "temperatues", "temperatures", - "temperaturs", "temperatures", - "temperatuur", "temperature", - "temperement", "temperament", - "tempermeant", "temperament", - "tempertaure", "temperature", - "temporairly", "temporarily", - "temporaraly", "temporarily", - "temporarity", "temporarily", - "tempreature", "temperature", - "temproarily", "temporarily", - "tempurature", "temperature", - "tepmorarily", "temporarily", - "termanology", "terminology", - "terminacion", "termination", - "terminaison", "termination", - "terminalogy", "terminology", - "terminatior", "terminator", - "terminatorn", "termination", - "terminilogy", "terminology", - "terminoligy", "terminology", - "terratorial", "territorial", - "terratories", "territories", - "terretorial", "territorial", - "terretories", "territories", - "terrirorial", "territorial", - "terrirories", "territories", - "terriroties", "territories", - "terristrial", "territorial", - "territoires", "territories", - "territorist", "terrorist", - "territority", "territory", - "terroristas", "terrorists", - "terroristes", "terrorists", - "terrorities", "territories", - "terrotorial", "territorial", - "terrotories", "territories", - "testiclular", "testicular", - "thankfullly", "thankfully", - "thanksgivng", "thanksgiving", - "theoligical", "theological", - "theoratical", "theoretical", - "theoreticly", "theoretical", - "theoritical", "theoretical", - "therapautic", "therapeutic", - "therapeudic", "therapeutic", - "therapeutuc", "therapeutic", - "therapuetic", "therapeutic", - "theraupetic", "therapeutic", - "thereaputic", "therapeutic", - "thereotical", "theoretical", - "therepeutic", "therapeutic", - "thermometor", "thermometer", - "thermometre", "thermometer", - "thermomiter", "thermometer", - "thermomoter", "thermometer", - "thermoneter", "thermometer", - "thermostaat", "thermostat", - "theroetical", "theoretical", - "thoeretical", "theoretical", - "threataning", "threatening", - "threatended", "threatened", - "threatining", "threatening", - "throttleing", "throttling", - "throughoput", "throughput", - "throughtout", "throughout", - "throughtput", "throughput", - "thudnerbolt", "thunderbolt", - "thunberbolt", "thunderbolt", - "thunderblot", "thunderbolt", - "thunderboat", "thunderbolt", - "thunderbots", "thunderbolt", - "thunderbowl", "thunderbolt", - "thunderjolt", "thunderbolt", - "thundervolt", "thunderbolt", - "tightenting", "tightening", - "tocuhscreen", "touchscreen", - "torrentking", "torrenting", - "torrentting", "torrenting", - "torublesome", "troublesome", - "torunaments", "tournaments", - "totalitaran", "totalitarian", - "totalitarni", "totalitarian", - "touranments", "tournaments", - "tournamnets", "tournaments", - "tournemants", "tournaments", - "tournements", "tournaments", - "tournmanets", "tournaments", - "tradicional", "traditional", - "tradionally", "traditionally", - "tradisional", "traditional", - "traditionel", "traditional", - "traditition", "tradition", - "tragicallly", "tragically", - "tramautized", "traumatized", - "tramuatized", "traumatized", - "trancendent", "transcendent", - "trancending", "transcending", - "tranclucent", "translucent", - "trandgender", "transgender", - "tranditions", "transitions", - "tranistions", "transitions", - "tranlastion", "translations", - "tranlsating", "translating", - "tranlsation", "translation", - "tranluscent", "translucent", - "trannsexual", "transsexual", - "tranpshobic", "transphobic", - "transaccion", "transaction", - "transaciton", "transactions", - "transalting", "translating", - "transaltion", "translation", - "transations", "transitions", - "transcluent", "translucent", - "transcripto", "transcription", - "transctions", "transitions", - "transculent", "translucent", - "transending", "transcending", - "transfender", "transgender", - "transferers", "transfers", - "transfering", "transferring", - "transfersom", "transforms", - "transfomers", "transforms", - "transformas", "transforms", - "transformes", "transformers", - "transformis", "transforms", - "transformus", "transforms", - "transforums", "transforms", - "transfromed", "transformed", - "transfromer", "transformers", - "transgemder", "transgender", - "transgended", "transgendered", - "transgenger", "transgender", - "transgenres", "transgender", - "transhpobic", "transphobic", - "transisions", "transitions", - "transisitor", "transistor", - "transistion", "transition", - "transistior", "transistor", - "transitiond", "transitioned", - "transitiong", "transitioning", - "translatron", "translation", - "translusent", "translucent", - "transmatter", "transmitter", - "transmision", "transmission", - "transmissin", "transmissions", - "transmisson", "transmission", - "transmittor", "transmitter", - "transmorged", "transformed", - "transmutter", "transmitter", - "transofrmed", "transformed", - "transohobic", "transphobic", - "transparant", "transparent", - "transparecy", "transparency", - "transpareny", "transparency", - "transperant", "transparent", - "transperent", "transparent", - "transphonic", "transphobic", - "transphopic", "transphobic", - "transplanet", "transplant", - "transporder", "transporter", - "transporing", "transporting", - "transportar", "transporter", - "transportng", "transporting", - "transportor", "transporter", - "transseuxal", "transsexual", - "transsexaul", "transsexual", - "transsexuel", "transsexual", - "transulcent", "translucent", - "transylvnia", "transylvania", - "tranzformer", "transformer", - "tranzitions", "transitions", - "tranzporter", "transporter", - "trasncripts", "transcripts", - "trasnferred", "transferred", - "trasnformed", "transformed", - "trasnformer", "transformer", - "trasngender", "transgender", - "trasnmitted", "transmitted", - "trasnmitter", "transmitter", - "trasnparent", "transparent", - "trasnphobic", "transphobic", - "trasnported", "transported", - "trasnporter", "transporter", - "traumatisch", "traumatic", - "traumetized", "traumatized", - "traumitized", "traumatized", - "travellerhd", "travelled", - "travellodge", "travelled", - "tremendeous", "tremendous", - "tremendious", "tremendous", - "tremenduous", "tremendous", - "trespessing", "trespassing", - "tresspasing", "trespassing", - "triggereing", "triggering", - "triggerring", "triggering", - "troubelsome", "troublesome", - "truamatized", "traumatized", - "trushworthy", "trustworthy", - "trustowrthy", "trustworthy", - "trustwhorty", "trustworthy", - "trustworhty", "trustworthy", - "truthfullly", "truthfully", - "tupperwears", "tupperware", - "turstworthy", "trustworthy", - "ubiquitious", "ubiquitous", - "ubiquituous", "ubiquitous", - "ukraininans", "ukrainians", - "ultimatelly", "ultimately", - "unanimoulsy", "unanimous", - "unappeasing", "unappealing", - "unappeeling", "unappealing", - "unathorised", "unauthorised", - "unattendend", "unattended", - "unatteneded", "unattended", - "unattracive", "unattractive", - "unauthoried", "unauthorized", - "unavailible", "unavailable", - "unavaliable", "unavailable", - "unaviodable", "unavoidable", - "unbalanaced", "unbalanced", - "unbraikable", "unbreakable", - "unbrakeable", "unbreakable", - "unbreakabie", "unbreakable", - "unbreakabke", "unbreakable", - "unbreakbale", "unbreakable", - "unbreakeble", "unbreakable", - "unbrearable", "unbreakable", - "uncensorred", "uncensored", - "uncertaincy", "uncertainty", - "uncertanity", "uncertainty", - "uncertianty", "uncertainty", - "unchangable", "unchangeable", - "uncompetive", "uncompetitive", - "unconcsious", "unconscious", - "unconsicous", "unconscious", - "uncouncious", "unconscious", - "undeniabely", "undeniably", - "undeniabley", "undeniably", - "undeniablly", "undeniably", - "undenialbly", "undeniably", - "underestime", "underestimate", - "undergating", "undertaking", - "undergorund", "underground", - "underheight", "underweight", - "undermiming", "undermining", - "undermindes", "undermines", - "undernearth", "underneath", - "underneight", "underweight", - "underpining", "undermining", - "underpowerd", "underpowered", - "underpowred", "underpowered", - "underratted", "underrated", - "understannd", "understands", - "understsand", "understands", - "undertacker", "undertaker", - "underwarter", "underwater", - "underwieght", "underweight", - "underwright", "underweight", - "undesireble", "undesirable", - "undesriable", "undesirable", - "undetecable", "undetectable", - "undiserable", "undesirable", - "undoubedtly", "undoubtedly", - "undoubetdly", "undoubtedly", - "undoubtadly", "undoubtedly", - "undoubtebly", "undoubtedly", - "undoubtetly", "undoubtedly", - "undreground", "underground", - "unemployeed", "unemployed", - "unemployent", "unemployment", - "unemploymed", "unemployed", - "unexpectdly", "unexpectedly", - "unexpectely", "unexpectedly", - "unfamilliar", "unfamiliar", - "unfortuante", "unfortunate", - "ungreatfull", "ungrateful", - "unilateraly", "unilaterally", - "unilaterlly", "unilaterally", - "unimportent", "unimportant", - "uninspiried", "uninspired", - "uninstaling", "uninstalling", - "uninstallng", "uninstalling", - "uninteresed", "uninterested", - "uniquesness", "uniqueness", - "unisntalled", "uninstalled", - "universella", "universally", - "universites", "universities", - "univesities", "universities", - "unjustifyed", "unjustified", - "unknowinlgy", "unknowingly", - "unkowningly", "unknowingly", - "unnecassary", "unnecessary", - "unneccesary", "unnecessary", - "unnecessery", "unnecessary", - "unnecissary", "unnecessary", - "unnessecary", "unnecessary", - "unnistalled", "uninstalled", - "unoriginial", "unoriginal", - "unorigional", "unoriginal", - "unoticeable", "unnoticeable", - "unpleaseant", "unpleasant", - "unportected", "unprotected", - "unprepaired", "unprepared", - "unpreparred", "unprepared", - "unproducive", "unproductive", - "unprotexted", "unprotected", - "unqaulified", "unqualified", - "unrealisitc", "unrealistic", - "unrealsitic", "unrealistic", - "unreasonbly", "unreasonably", - "unregluated", "unregulated", - "unregualted", "unregulated", - "unregulared", "unregulated", - "unrepentent", "unrepentant", - "unresponive", "unresponsive", - "unrestriced", "unrestricted", - "unsettleing", "unsettling", - "unsintalled", "uninstalled", - "unsolicated", "unsolicited", - "unsoliticed", "unsolicited", - "unsolocited", "unsolicited", - "unsubscirbe", "unsubscribe", - "unsubscrbed", "unsubscribed", - "unsubscried", "unsubscribed", - "unsubscripe", "unsubscribe", - "unsubscrive", "unsubscribe", - "unsubscrube", "unsubscribe", - "unsubsrcibe", "unsubscribe", - "unsuccesful", "unsuccessful", - "unsuccessul", "unsuccessful", - "unsucesfuly", "unsuccessfully", - "unsucessful", "unsuccessful", - "unsunscribe", "unsubscribe", - "unsuprising", "unsurprising", - "unsuprizing", "unsurprising", - "unsurprized", "unsurprised", - "unsusbcribe", "unsubscribe", - "unviersally", "universally", - "unwarrented", "unwarranted", - "utiliatrian", "utilitarian", - "utilitatian", "utilitarian", - "utiliterian", "utilitarian", - "utilizacion", "utilization", - "utilizaiton", "utilization", - "utilizating", "utilization", - "utiltiarian", "utilitarian", - "vacciantion", "vaccination", - "vaccinaties", "vaccinate", - "vegaterians", "vegetarians", - "vegetariens", "vegetarians", - "vegetatians", "vegetarians", - "vegeterians", "vegetarians", - "vehementely", "vehemently", - "venezuelean", "venezuela", - "venezuelian", "venezuela", - "ventalation", "ventilation", - "ventelation", "ventilation", - "ventialtion", "ventilation", - "ventilacion", "ventilation", - "verastility", "versatility", - "verfication", "verification", - "versatality", "versatility", - "versitality", "versatility", - "versitilaty", "versatility", - "victorieuse", "victories", - "victoriuous", "victorious", - "vietnameese", "vietnamese", - "vietnamesse", "vietnamese", - "vietnamiese", "vietnamese", - "vietnamnese", "vietnamese", - "vigilanties", "vigilante", - "visibillity", "visibility", - "vocabularly", "vocabulary", - "volatillity", "volatility", - "volonteered", "volunteered", - "volounteers", "volunteers", - "volunatrily", "voluntarily", - "voluntairly", "voluntarily", - "volunteeers", "volunteers", - "volunteraly", "voluntarily", - "voluntereed", "volunteered", - "volunterily", "voluntarily", - "vulnerabile", "vulnerable", - "wallpapaers", "wallpapers", - "wallpappers", "wallpapers", - "washingtion", "washington", - "watermeleon", "watermelon", - "waterprooof", "waterproof", - "wavelegnths", "wavelength", - "wavelenghth", "wavelength", - "wavelenghts", "wavelength", - "weaknessses", "weaknesses", - "wellingston", "wellington", - "wellingtion", "wellington", - "westernerns", "westerners", - "westmisnter", "westminster", - "westmnister", "westminster", - "westmonster", "westminster", - "whisperered", "whispered", - "whitholding", "withholding", - "wikileakers", "wikileaks", - "willingless", "willingness", - "wincheseter", "winchester", - "windsheilds", "windshield", - "withdrawels", "withdrawals", - "withdrawles", "withdrawals", - "withhelding", "withholding", - "withrdawing", "withdrawing", - "witnesssing", "witnessing", - "woodowrking", "woodworking", - "woodworkign", "woodworking", - "worhsipping", "worshipping", - "workstaiton", "workstation", - "workststion", "workstation", - "worshopping", "worshipping", - "xenophoblic", "xenophobic", - "abandining", "abandoning", - "abandonned", "abandoned", - "abbreviato", "abbreviation", - "abnoramlly", "abnormally", - "abnormalty", "abnormally", - "abnornally", "abnormally", - "abominaton", "abomination", - "abondoning", "abandoning", - "aborginial", "aboriginal", - "aboriganal", "aboriginal", - "aborigenal", "aboriginal", - "aborignial", "aboriginal", - "aborigonal", "aboriginal", - "aboroginal", "aboriginal", - "aboslutely", "absolutely", - "abosrption", "absorption", - "abreviated", "abbreviated", - "absintence", "abstinence", - "absitnence", "abstinence", - "absolument", "absolute", - "absolutley", "absolutely", - "absoprtion", "absorption", - "absorbsion", "absorption", - "absorbtion", "absorption", - "absorpsion", "absorption", - "absoultely", "absolutely", - "abstanence", "abstinence", - "abstenance", "abstinence", - "abstenince", "abstinence", - "abstinense", "abstinence", - "abstinince", "abstinence", - "absurditiy", "absurdity", - "abundacies", "abundances", - "academicas", "academics", - "academicos", "academics", - "academicus", "academics", - "accdiently", "accidentally", - "accelarate", "accelerate", - "accelerade", "accelerated", - "accelerare", "accelerate", - "accelerato", "acceleration", - "acceleread", "accelerated", - "accelertor", "accelerator", - "accelorate", "accelerate", - "acceptabel", "acceptable", - "acceptabil", "acceptable", - "acceptence", "acceptance", - "accepterad", "accepted", - "acceptible", "acceptable", - "accerelate", "accelerated", - "accesories", "accessories", - "accessable", "accessible", - "accessbile", "accessible", - "accessoire", "accessories", - "accessoirs", "accessories", - "accicently", "accidentally", - "accidantly", "accidentally", - "accidebtly", "accidentally", - "accidenlty", "accidentally", - "accidentes", "accidents", - "accidentky", "accidentally", - "accidently", "accidentally", - "accidnetly", "accidentally", - "accomadate", "accommodate", - "accomodate", "accommodate", - "accompined", "accompanied", - "accomplise", "accomplishes", - "accompliss", "accomplishes", - "accostumed", "accustomed", - "accountent", "accountant", - "accpetable", "acceptable", - "accpetance", "acceptance", - "accuastion", "accusation", - "acculumate", "accumulate", - "accumalate", "accumulate", - "accumelate", "accumulate", - "accumilate", "accumulate", - "accumulare", "accumulate", - "accumulato", "accumulation", - "accumulted", "accumulated", - "accuratley", "accurately", - "accusating", "accusation", - "accusition", "accusation", - "accustumed", "accustomed", - "acheivable", "achievable", - "acheivment", "achievement", - "acheviable", "achievable", - "achiavable", "achievable", - "achieveble", "achievable", - "achievemnt", "achievement", - "achievemts", "achievements", - "achievents", "achievements", - "achievment", "achievement", - "achilleous", "achilles", - "achiveable", "achievable", - "achivement", "achievement", - "acitvating", "activating", - "acitvision", "activision", - "acknowldge", "acknowledge", - "acknowlede", "acknowledge", - "acknowlege", "acknowledge", - "acommodate", "accommodate", - "acopalypse", "apocalypse", - "acordingly", "accordingly", - "acqauinted", "acquainted", - "acquanited", "acquainted", - "acquianted", "acquainted", - "acquinated", "acquainted", - "acquisiton", "acquisition", - "acticating", "activating", - "actication", "activation", - "activacion", "activation", - "activaters", "activates", - "activiates", "activist", - "activiites", "activist", - "activisiom", "activism", - "activisits", "activist", - "activistas", "activists", - "activistes", "activists", - "activiting", "activating", - "activizion", "activision", - "acustommed", "accustomed", - "adaptacion", "adaptation", - "adaptating", "adaptation", - "adaquetely", "adequately", - "addicitons", "addictions", - "addionally", "additionally", - "additivies", "additive", - "additivley", "additive", - "addittions", "addictions", - "addmission", "admission", - "addresable", "addressable", - "addressess", "addresses", - "adequatley", "adequately", - "adequetely", "adequately", - "adequitely", "adequately", - "adernaline", "adrenaline", - "adjectivos", "adjectives", - "adjustible", "adjustable", - "admendment", "amendment", - "administed", "administered", - "administor", "administer", - "administre", "administer", - "administro", "administer", - "adminsiter", "administer", - "admissable", "admissible", - "admittadly", "admittedly", - "admittetly", "admittedly", - "admittidly", "admittedly", - "adolencent", "adolescent", - "adolescant", "adolescent", - "adolescene", "adolescence", - "adoloscent", "adolescent", - "adolsecent", "adolescent", - "adpatation", "adaptation", - "adreanline", "adrenaline", - "adrelanine", "adrenaline", - "adreneline", "adrenaline", - "adreniline", "adrenaline", - "adressable", "addressable", - "advanteges", "advantages", - "advatanges", "advantages", - "adventrous", "adventurous", - "adventrues", "adventures", - "adventuers", "adventures", - "adventuous", "adventurous", - "adventuros", "adventurous", - "adventurus", "adventurous", - "adverticed", "advertised", - "aestethics", "aesthetics", - "aesthatics", "aesthetics", - "aesthestic", "aesthetics", - "affiliaton", "affiliation", - "affilliate", "affiliate", - "affirmitve", "affirmative", - "afflcition", "affliction", - "afflection", "affliction", - "affliation", "affliction", - "affliciton", "affliction", - "afforadble", "affordable", - "affordible", "affordable", - "affortable", "affordable", - "africaners", "africans", - "africaness", "africans", - "aftermaket", "aftermarket", - "afternooon", "afternoon", - "aggravanti", "aggravating", - "aggraveted", "aggravated", - "aggreement", "agreement", - "aggregious", "egregious", - "aggresions", "aggression", - "aggressivo", "aggression", - "aggrovated", "aggravated", - "agnosticim", "agnosticism", - "agnosticsm", "agnosticism", - "agnostisch", "agnostic", - "agnostiscm", "agnosticism", - "agnostisim", "agnosticism", - "agreeement", "agreement", - "agricultre", "agriculture", - "agricultue", "agriculture", - "agriculure", "agriculture", - "agricuture", "agriculture", - "ailenating", "alienating", - "ajdectives", "adjectives", - "alchoholic", "alcoholic", - "alchoolism", "alcoholism", - "alcohalics", "alcoholics", - "alcohalism", "alcoholism", - "alcoholsim", "alcoholism", - "aleinating", "alienating", - "algorhitms", "algorithms", - "algorithem", "algorithm", - "algorithim", "algorithm", - "algorithsm", "algorithms", - "algorithum", "algorithm", - "algorithym", "algorithm", - "algoritmes", "algorithms", - "algoritmos", "algorithms", - "algorthims", "algorithms", - "algortihms", "algorithms", - "algorythms", "algorithms", - "alievating", "alienating", - "alledgedly", "allegedly", - "allegeance", "allegiance", - "allegedely", "allegedly", - "allegedley", "allegedly", - "allegience", "allegiance", - "alleigance", "allegiance", - "allergisch", "allergic", - "alliegance", "allegiance", - "alligeance", "allegiance", - "allignment", "alignment", - "alocholics", "alcoholics", - "alocholism", "alcoholism", - "alogrithms", "algorithms", - "alphabeast", "alphabet", - "alteracion", "alteration", - "alterarion", "alteration", - "alterating", "alteration", - "alternador", "alternator", - "alternater", "alternator", - "alternatie", "alternatives", - "alternatly", "alternately", - "alternatve", "alternate", - "alternetly", "alternately", - "altogehter", "altogether", - "altogheter", "altogether", - "altriustic", "altruistic", - "altruisitc", "altruistic", - "altrusitic", "altruistic", - "alturistic", "altruistic", - "aluminimum", "aluminium", - "amargeddon", "armageddon", - "amateurest", "amateurs", - "ambassabor", "ambassador", - "ambassader", "ambassador", - "ambassator", "ambassador", - "ambassedor", "ambassador", - "ambassidor", "ambassador", - "ambassodor", "ambassador", - "ambiguitiy", "ambiguity", - "amendmants", "amendments", - "amendmends", "amendments", - "americains", "americas", - "americanas", "americans", - "americanis", "americas", - "americanss", "americas", - "americants", "americas", - "americanus", "americans", - "americares", "americas", - "ammendment", "amendment", - "amrageddon", "armageddon", - "analitical", "analytical", - "analitycal", "analytical", - "analogeous", "analogous", - "analyitcal", "analytical", - "analyseles", "analyses", - "analyseras", "analyses", - "analyseres", "analyses", - "analysised", "analyses", - "analysises", "analyses", - "analysisto", "analysts", - "analystics", "analysts", - "anarchisim", "anarchism", - "anarchistm", "anarchism", - "anarchiszm", "anarchism", - "anarchsits", "anarchists", - "anayltical", "analytical", - "ancilliary", "ancillary", - "androiders", "androids", - "androidtvs", "androids", - "anecdotale", "anecdote", - "anecdotice", "anecdote", - "anestheisa", "anesthesia", - "anesthetia", "anesthesia", - "anesthisia", "anesthesia", - "anitbiotic", "antibiotic", - "anitquated", "antiquated", - "anitsocial", "antisocial", - "aniversary", "anniversary", - "annilihate", "annihilated", - "anniverary", "anniversary", - "anniversay", "anniversary", - "anniversry", "anniversary", - "annointing", "anointing", - "annonceurs", "announcers", - "annoucners", "announcers", - "annoucning", "announcing", - "announched", "announce", - "annyoingly", "annoyingly", - "anonymosly", "anonymously", - "anonymousy", "anonymously", - "antaganist", "antagonist", - "antagnoist", "antagonist", - "antarcitca", "antarctica", - "antarctida", "antarctica", - "anthropoly", "anthropology", - "antibiodic", "antibiotic", - "antibiotcs", "antibiotics", - "antibitoic", "antibiotic", - "antiboitic", "antibiotics", - "anticapate", "anticipate", - "anticiapte", "anticipate", - "anticipare", "anticipate", - "anticipato", "anticipation", - "anticuated", "antiquated", - "antiquited", "antiquated", - "antiqvated", "antiquated", - "antisipate", "anticipate", - "antisocail", "antisocial", - "antisosial", "antisocial", - "antoganist", "antagonist", - "antractica", "antarctica", - "apacolypse", "apocalypse", - "apartheied", "apartheid", - "aplication", "application", - "apocalipse", "apocalypse", - "apocalpyse", "apocalypse", - "apocalypes", "apocalypse", - "apocalypic", "apocalyptic", - "apocalyspe", "apocalypse", - "apocalytic", "apocalyptic", - "apocaplyse", "apocalypse", - "apocolapse", "apocalypse", - "apolagetic", "apologetic", - "apolagized", "apologized", - "apolegetic", "apologetic", - "apoligetic", "apologetic", - "apoligists", "apologists", - "apoligized", "apologized", - "apologisms", "apologists", - "apologiste", "apologise", - "apologitic", "apologetic", - "apostraphe", "apostrophe", - "apostrephe", "apostrophe", - "apostrohpe", "apostrophe", - "apostropes", "apostrophe", - "apparantly", "apparently", - "appareance", "appearance", - "apparenlty", "apparently", - "appartment", "apartment", - "appealling", "appealing", - "appearence", "appearance", - "appearnace", "appearances", - "apperances", "appearances", - "apperantly", "apparently", - "apperciate", "appreciate", - "appereance", "appearance", - "appetities", "appetite", - "appetitite", "appetite", - "appication", "application", - "applainces", "appliances", - "applicaple", "applicable", - "applicates", "applicants", - "applicaton", "application", - "applicible", "applicable", - "appliences", "appliances", - "appointmet", "appointments", - "appologies", "apologies", - "apporached", "approached", - "apporaches", "approaches", - "appraoched", "approached", - "appraoches", "approaches", - "apprecaite", "appreciate", - "appreciato", "appreciation", - "appreciste", "appreciates", - "apprecitae", "appreciates", - "apprecited", "appreciated", - "apprectice", "apprentice", - "appreicate", "appreciate", - "apprendice", "apprentice", - "apprentace", "apprentice", - "apprentise", "apprentice", - "appretiate", "appreciate", - "appretince", "apprentice", - "appriceate", "appreciates", - "appriciate", "appreciate", - "appriecate", "appreciates", - "approacing", "approaching", - "appropiate", "appropriate", - "approprate", "appropriate", - "apropriate", "appropriate", - "aproximate", "approximate", - "apsotrophe", "apostrophe", - "aptitudine", "aptitude", - "aqcuainted", "acquainted", - "aquisition", "acquisition", - "aramgeddon", "armageddon", - "arangement", "arrangement", - "arbitarily", "arbitrarily", - "arbitraily", "arbitrarily", - "arbitraion", "arbitration", - "arbitrairy", "arbitrarily", - "arbitrarly", "arbitrary", - "arbitraton", "arbitration", - "arcehtypes", "archetypes", - "archaelogy", "archaeology", - "archaeolgy", "archaeology", - "archaology", "archeology", - "archatypes", "archetypes", - "archetects", "architects", - "archetipes", "archetypes", - "archetpyes", "archetypes", - "archetypus", "archetypes", - "archeytpes", "archetypes", - "archictect", "architect", - "architechs", "architects", - "architecht", "architect", - "architecte", "architect", - "architexts", "architects", - "architypes", "archetypes", - "archtiects", "architects", - "archytypes", "archetypes", - "argentinia", "argentina", - "arguements", "arguments", - "argumentas", "arguments", - "argumentos", "arguments", - "arithemtic", "arithmetic", - "arithmitic", "arithmetic", - "aritmethic", "arithmetic", - "armagaddon", "armageddon", - "armageddan", "armageddon", - "armagedden", "armageddon", - "armageddin", "armageddon", - "armagedeon", "armageddon", - "armageedon", "armageddon", - "armagideon", "armageddon", - "armegaddon", "armageddon", - "arrangerad", "arranged", - "arrangment", "arrangement", - "arthimetic", "arithmetic", - "articifial", "artificial", - "articluate", "articulate", - "articualte", "articulate", - "articulted", "articulated", - "artifactos", "artifacts", - "artificiel", "artificial", - "artihmetic", "arithmetic", - "artillerly", "artillery", - "asbestoast", "asbestos", - "asethetics", "aesthetics", - "asisstants", "assistants", - "aspiratons", "aspirations", - "assasinate", "assassinate", - "assassians", "assassin", - "assassinas", "assassins", - "assassines", "assassins", - "assassinos", "assassins", - "assemblare", "assemble", - "assempling", "assembling", - "assersions", "assertions", - "assesement", "assessment", - "assestment", "assessment", - "assigments", "assignments", - "assignemnt", "assignment", - "assimalate", "assimilate", - "assimilant", "assimilate", - "assimilare", "assimilate", - "assimliate", "assimilate", - "assimulate", "assimilate", - "assingment", "assignment", - "assistanat", "assistants", - "assistanse", "assistants", - "assistante", "assistance", - "assistence", "assistance", - "assistendo", "assisted", - "assistents", "assistants", - "assmebling", "assembling", - "assocaited", "associated", - "assocaites", "associates", - "assocation", "association", - "associatie", "associated", - "associatin", "associations", - "associaton", "association", - "associsted", "associates", - "assoicated", "associated", - "assoicates", "associates", - "assosiated", "associated", - "assosiates", "associates", - "asssassans", "assassins", - "assupmtion", "assumptions", - "assymetric", "asymmetric", - "asteroides", "asteroids", - "asthetical", "aesthetical", - "astonising", "astonishing", - "astornauts", "astronauts", - "astranauts", "astronauts", - "astronatus", "astronauts", - "astronaunt", "astronaut", - "astronomia", "astronomical", - "astronouts", "astronauts", - "astronuats", "astronauts", - "asutralian", "australian", - "atatchment", "attachment", - "athleticos", "athletics", - "athleticsm", "athleticism", - "athletiscm", "athleticism", - "athletisim", "athleticism", - "atmopshere", "atmosphere", - "atmoshpere", "atmosphere", - "atomsphere", "atmosphere", - "atriculate", "articulate", - "atrocoties", "atrocities", - "atrosities", "atrocities", - "attachemnt", "attachment", - "attackeras", "attackers", - "attactment", "attachment", - "attemtping", "attempting", - "attendence", "attendance", - "attendents", "attendants", - "attirbutes", "attributes", - "attmepting", "attempting", - "attracters", "attracts", - "attractice", "attractive", - "attracties", "attracts", - "attractifs", "attracts", - "attraktion", "attraction", - "attraktive", "attractive", - "attribuito", "attribution", - "attritubes", "attributes", - "auctioners", "auctions", - "audioboook", "audiobook", - "audioboost", "audiobooks", - "auidobooks", "audiobooks", - "auotattack", "autoattack", - "austrailan", "australian", - "austrailia", "australia", - "australain", "australians", - "australien", "australian", - "australina", "australians", - "austrlaian", "australians", - "authenticy", "authenticity", - "autherized", "authorized", - "authoritay", "authority", - "authorites", "authorities", - "authorithy", "authority", - "authroized", "authorized", - "autistisch", "autistic", - "autoattaks", "autoattack", - "autocorect", "autocorrect", - "autocorrct", "autocorrect", - "autocorret", "autocorrect", - "autograpgh", "autograph", - "automatice", "automate", - "automatico", "automation", - "automatied", "automate", - "automatiek", "automate", - "automatron", "automation", - "automatted", "automate", - "automibile", "automobile", - "automitive", "automotive", - "automoblie", "automobile", - "automomous", "autonomous", - "automonous", "autonomous", - "automotice", "automotive", - "automotion", "automation", - "automotize", "automotive", - "automotove", "automotive", - "autonamous", "autonomous", - "autonation", "automation", - "autonimous", "autonomous", - "autonomity", "autonomy", - "autononous", "autonomous", - "auttoatack", "autoattack", - "auxilliary", "auxiliary", - "availabale", "available", - "availaible", "available", - "availiable", "available", - "averageadi", "averaged", - "averageifs", "averages", - "awesomeley", "awesomely", - "awesomelly", "awesomely", - "awesomenss", "awesomeness", - "awkwardess", "awkwardness", - "babysister", "babysitter", - "babysiting", "babysitting", - "babysittng", "babysitting", - "bachelores", "bachelors", - "backgorund", "background", - "backgroudn", "backgrounds", - "backgrouds", "backgrounds", - "backgrouns", "backgrounds", - "backgruond", "backgrounds", - "backpacing", "backpacking", - "backpackng", "backpacking", - "backrgound", "backgrounds", - "backrounds", "backgrounds", - "baksetball", "basketball", - "balanceada", "balanced", - "balanceado", "balanced", - "balckberry", "blackberry", - "balckhawks", "blackhawks", - "balcksmith", "blacksmith", - "bandwagoon", "bandwagon", - "bangaldesh", "bangladesh", - "bangladash", "bangladesh", - "bangledash", "bangladesh", - "bangledesh", "bangladesh", - "banglidesh", "bangladesh", - "bankrupcty", "bankruptcy", - "bankruptsy", "bankruptcy", - "bankrutpcy", "bankruptcy", - "barabrians", "barbarians", - "barbariens", "barbarians", - "barbarions", "barbarians", - "barbarisch", "barbaric", - "barberians", "barbarians", - "bargianing", "bargaining", - "bartendars", "bartenders", - "basektball", "basketball", - "baskteball", "basketball", - "bastardous", "bastards", - "battelship", "battleship", - "battelstar", "battlestar", - "battlearts", "battlestar", - "battlechip", "battleship", - "battlefied", "battlefield", - "battlefont", "battlefront", - "battlehips", "battleship", - "battlesaur", "battlestar", - "battlescar", "battlestar", - "battleshop", "battleship", - "battlestsr", "battlestar", - "beahviours", "behaviours", - "beautifuly", "beautifully", - "beautilful", "beautifully", - "beautyfull", "beautiful", - "becnhmarks", "benchmarks", - "beethoveen", "beethoven", - "begginings", "beginnings", - "begininngs", "beginnings", - "beginninng", "beginnings", - "behaivours", "behaviours", - "behaviorly", "behavioral", - "behavoiral", "behavioral", - "behavoiurs", "behaviours", - "behavorial", "behavioral", - "behavoural", "behavioral", - "behvaiours", "behaviours", - "beleagured", "beleaguered", - "beleivable", "believable", - "beliavable", "believable", - "beliebable", "believable", - "believeble", "believable", - "beliveable", "believable", - "benchamrks", "benchmarks", - "benchmakrs", "benchmarks", - "benckmarks", "benchmarks", - "benefecial", "beneficial", - "beneficary", "beneficiary", - "beneficiul", "beneficial", - "benefitial", "beneficial", - "beneifical", "beneficial", - "benelovent", "benevolent", - "benevalent", "benevolent", - "benevelant", "benevolent", - "benevelent", "benevolent", - "benevelont", "benevolent", - "benevloent", "benevolent", - "benevolant", "benevolent", - "benificial", "beneficial", - "benovelent", "benevolent", - "bernouilli", "bernoulli", - "besitality", "bestiality", - "bestaility", "bestiality", - "besteality", "bestiality", - "betrayeado", "betrayed", - "bilateraly", "bilaterally", - "billborads", "billboards", - "bioligical", "biological", - "biologiset", "biologist", - "biologiskt", "biologist", - "birghtness", "brightness", - "birmignham", "birmingham", - "birmimgham", "birmingham", - "bisexuella", "bisexual", - "bitterseet", "bittersweet", - "bitterswet", "bittersweet", - "blackahwks", "blackhawks", - "blackbarry", "blackberry", - "blackbeary", "blackberry", - "blackbeery", "blackberry", - "blackcawks", "blackhawks", - "blackhakws", "blackhawks", - "blackhwaks", "blackhawks", - "blackmsith", "blacksmith", - "blackshits", "blacksmith", - "blasphemey", "blasphemy", - "blitzkreig", "blitzkrieg", - "blochchain", "blockchain", - "blockcahin", "blockchain", - "blockchian", "blockchain", - "bloodboner", "bloodborne", - "bloodbonre", "bloodborne", - "bloodborbe", "bloodborne", - "bloodbrone", "bloodborne", - "bloodporne", "bloodborne", - "bloorborne", "bloodborne", - "blueberies", "blueberries", - "blueberris", "blueberries", - "blueberrry", "blueberry", - "bluebrints", "blueprints", - "boardcasts", "broadcasts", - "bodyheight", "bodyweight", - "bodyweigth", "bodyweight", - "bodywieght", "bodyweight", - "bombarment", "bombardment", - "bookmakred", "bookmarked", - "bootlaoder", "bootloader", - "bootleader", "bootloader", - "boradcasts", "broadcasts", - "borderlads", "borderlands", - "borderlans", "borderlands", - "bottelneck", "bottleneck", - "bottlebeck", "bottleneck", - "boundaires", "boundaries", - "bounderies", "boundaries", - "bourgeoius", "bourgeois", - "boycutting", "boycotting", - "boyfirends", "boyfriends", - "boyfreinds", "boyfriends", - "boyfrients", "boyfriends", - "braceletes", "bracelets", - "braceletts", "bracelets", - "brainwased", "brainwashed", - "brakedowns", "breakdowns", - "braodcasts", "broadcasts", - "brasillian", "brazilian", - "bratenders", "bartenders", - "brazilains", "brazilians", - "brazileans", "brazilians", - "braziliaan", "brazilians", - "brazilions", "brazilians", - "brazillans", "brazilians", - "brightoner", "brighten", - "brigthness", "brightness", - "brillaince", "brilliance", - "brilliante", "brilliance", - "brillianty", "brilliantly", - "brimestone", "brimstone", - "brimingham", "birmingham", - "broacasted", "broadcast", - "brotherhod", "brotherhood", - "brotherood", "brotherhood", - "brusselers", "brussels", - "brutallity", "brutally", - "buisnesses", "businesses", - "bulgariska", "bulgaria", - "bulletpoof", "bulletproof", - "bulletprof", "bulletproof", - "bureaucats", "bureaucrats", - "businesman", "businessman", - "businesmen", "businessmen", - "businessen", "businessmen", - "butterfies", "butterflies", - "cabinettas", "cabinets", - "caclulated", "calculated", - "caclulator", "calculator", - "cahracters", "characters", - "calcluator", "calculators", - "calcualted", "calculated", - "calcualtor", "calculator", - "calculador", "calculator", - "calcularon", "calculator", - "calculater", "calculator", - "calculatin", "calculations", - "calibratin", "calibration", - "calibraton", "calibration", - "califnoria", "californian", - "califonria", "californian", - "califorian", "californian", - "califorina", "california", - "californai", "californian", - "califronia", "california", - "caligraphy", "calligraphy", - "caliofrnia", "californian", - "calrifying", "clarifying", - "calssified", "classified", - "caluclated", "calculated", - "caluclator", "calculator", - "caluculate", "calculate", - "cambodican", "cambodia", - "camofluage", "camouflage", - "camoufalge", "camouflage", - "camouglage", "camouflage", - "campaiging", "campaigning", - "campaignes", "campaigns", - "cancellato", "cancellation", - "candidatas", "candidates", - "candidatxs", "candidates", - "candidiate", "candidate", - "canditates", "candidates", - "cannibalsm", "cannibalism", - "cannisters", "canisters", - "cannonical", "canonical", - "capabality", "capability", - "capabiltiy", "capability", - "capacators", "capacitors", - "capaciters", "capacitors", - "capactiors", "capacitors", - "capasitors", "capacitors", - "capatilism", "capitalism", - "capatilist", "capitalist", - "capatilize", "capitalize", - "capialized", "capitalized", - "capicators", "capacitors", - "capitalisn", "capitals", - "capitalits", "capitalists", - "capitalsim", "capitalism", - "capitalsit", "capitalists", - "capitarist", "capitalist", - "capitilism", "capitalism", - "capitilist", "capitalist", - "capitilize", "capitalize", - "capitlaism", "capitalism", - "capitlaist", "capitalist", - "capitlaize", "capitalized", - "capitolism", "capitalism", - "capitolist", "capitalist", - "capitolize", "capitalize", - "captainers", "captains", - "captialism", "capitalism", - "captialist", "capitalist", - "captialize", "capitalize", - "captivitiy", "captivity", - "caraciture", "caricature", - "carciature", "caricature", - "cardinales", "cardinals", - "cardinalis", "cardinals", - "carefullly", "carefully", - "cariacture", "caricature", - "caricatore", "caricature", - "cariciture", "caricature", - "caricuture", "caricature", - "carismatic", "charismatic", - "carribbean", "caribbean", - "cartdridge", "cartridge", - "cartdriges", "cartridges", - "carthagian", "carthaginian", - "cartilidge", "cartilage", - "cartirdges", "cartridges", - "cartrdiges", "cartridges", - "cartriages", "cartridges", - "cartrigdes", "cartridges", - "casaulties", "casualties", - "cassowarry", "cassowary", - "casualites", "casualties", - "casualries", "casualties", - "casulaties", "casualties", - "cataclysim", "cataclysm", - "cataclysym", "cataclysm", - "catagories", "categories", - "catapillar", "caterpillar", - "catapiller", "caterpillar", - "catastrope", "catastrophe", - "catastrphe", "catastrophe", - "categorice", "categorize", - "categoried", "categorized", - "categoriei", "categorize", - "cateogrize", "categorized", - "catepillar", "caterpillar", - "caterpilar", "caterpillar", - "catholicsm", "catholicism", - "catholicus", "catholics", - "catholisim", "catholicism", - "cativating", "activating", - "cattleship", "battleship", - "causalties", "casualties", - "cautionsly", "cautiously", - "celebratin", "celebration", - "celebrites", "celebrities", - "celebritiy", "celebrity", - "cellpading", "cellpadding", - "cellulaire", "cellular", - "cemetaries", "cemeteries", - "censorhsip", "censorship", - "censurship", "censorship", - "centipedle", "centipede", - "ceremonias", "ceremonies", - "ceremoniis", "ceremonies", - "ceremonije", "ceremonies", - "cerimonial", "ceremonial", - "cerimonies", "ceremonies", - "certainity", "certainty", - "certainlyt", "certainty", - "chairtable", "charitable", - "chalenging", "challenging", - "challanged", "challenged", - "challanges", "challenges", - "challegner", "challenger", - "challender", "challenger", - "challengue", "challenger", - "challengur", "challenger", - "challening", "challenging", - "challneger", "challenger", - "chanceller", "chancellor", - "chancillor", "chancellor", - "chansellor", "chancellor", - "charachter", "character", - "charactere", "characterize", - "characterz", "characterize", - "charactors", "characters", - "charakters", "characters", - "charatable", "charitable", - "charecters", "characters", - "charistics", "characteristics", - "charitible", "charitable", - "chartiable", "charitable", - "chechpoint", "checkpoint", - "checkpiont", "checkpoint", - "checkpoins", "checkpoints", - "checkponts", "checkpoints", - "cheesecase", "cheesecake", - "cheesecave", "cheesecake", - "cheeseface", "cheesecake", - "cheezecake", "cheesecake", - "chemcially", "chemically", - "chidlbirth", "childbirth", - "chihuahuha", "chihuahua", - "childbrith", "childbirth", - "childrends", "childrens", - "childrenis", "childrens", - "childrents", "childrens", - "chirstians", "christians", - "chocalates", "chocolates", - "chocloates", "chocolates", - "chocoaltes", "chocolates", - "chocolatie", "chocolates", - "chocolatos", "chocolates", - "chocolatte", "chocolates", - "chocolotes", "chocolates", - "cholestrol", "cholesterol", - "chormosome", "chromosome", - "chornicles", "chronicles", - "chrisitans", "christians", - "christains", "christians", - "christiaan", "christian", - "christimas", "christians", - "christinas", "christians", - "christines", "christians", - "christmans", "christians", - "chromasome", "chromosome", - "chromesome", "chromosome", - "chromisome", "chromosome", - "chromosmes", "chromosomes", - "chromosoms", "chromosomes", - "chromosone", "chromosome", - "chromosoom", "chromosome", - "chromozome", "chromosome", - "chronciles", "chronicles", - "chronicals", "chronicles", - "chronicels", "chronicles", - "chronocles", "chronicles", - "chronosome", "chromosome", - "chrsitians", "christians", - "cigarattes", "cigarettes", - "cigerattes", "cigarettes", - "cincinatti", "cincinnati", - "cinncinati", "cincinnati", - "circulaire", "circular", - "circulaton", "circulation", - "circumsice", "circumcised", - "circumsied", "circumcised", - "circumwent", "circumvent", - "circunvent", "circumvent", - "cirruculum", "curriculum", - "claculator", "calculator", - "clairfying", "clarifying", - "clasically", "classically", - "classicals", "classics", - "classrooom", "classroom", - "cleanliess", "cleanliness", - "cleareance", "clearance", - "cleverleys", "cleverly", - "cliffhager", "cliffhanger", - "climateers", "climates", - "climatiser", "climates", - "clincially", "clinically", - "clitoridis", "clitoris", - "clitorious", "clitoris", - "co-incided", "coincided", - "cockroachs", "cockroaches", - "cockroahes", "cockroaches", - "coefficent", "coefficient", - "cognatious", "contagious", - "cognitivie", "cognitive", - "coincidnce", "coincide", - "colelctive", "collective", - "colelctors", "collectors", - "collapsers", "collapses", - "collaquial", "colloquial", - "collasping", "collapsing", - "collataral", "collateral", - "collaterol", "collateral", - "collatoral", "collateral", - "collcetion", "collections", - "colleauges", "colleagues", - "colleciton", "collection", - "collectems", "collects", - "collectief", "collective", - "collecties", "collects", - "collectifs", "collects", - "collectivo", "collection", - "collectoin", "collections", - "collectons", "collections", - "collectros", "collects", - "collegaues", "colleagues", - "collequial", "colloquial", - "colleteral", "collateral", - "colliquial", "colloquial", - "collission", "collisions", - "collitions", "collisions", - "colloqiual", "colloquial", - "colloquail", "colloquial", - "colloqueal", "colloquial", - "collpasing", "collapsing", - "colonialsm", "colonialism", - "colorblend", "colorblind", - "coloublind", "colorblind", - "columbidae", "columbia", - "comapnions", "companions", - "comaprable", "comparable", - "comaprison", "comparison", - "comaptible", "compatible", - "combatabts", "combatants", - "combatents", "combatants", - "combinatin", "combinations", - "combinaton", "combination", - "comediants", "comedians", - "comepndium", "compendium", - "comferting", "comforting", - "comforming", "comforting", - "comfortbly", "comfortably", - "comisioned", "commissioned", - "comisioner", "commissioner", - "comissions", "commissions", - "commandbox", "commando", - "commandent", "commandment", - "commandeur", "commanders", - "commandore", "commanders", - "commandpod", "commando", - "commanists", "communists", - "commemters", "commenters", - "commencera", "commerce", - "commenciez", "commence", - "commentaar", "commentary", - "commentare", "commenter", - "commentars", "commenters", - "commentart", "commentator", - "commentery", "commentary", - "commentsry", "commenters", - "commercail", "commercials", - "commercent", "commence", - "commerical", "commercial", - "comminists", "communists", - "commisison", "commissions", - "commissons", "commissions", - "commiteted", "committed", - "commodites", "commodities", - "commtiment", "commitments", - "communicae", "communicated", - "communisim", "communism", - "communiste", "communities", - "communites", "communities", - "communters", "commenters", - "compadible", "compatible", - "compagnons", "companions", - "compainons", "companions", - "compairson", "comparison", - "compalined", "complained", - "compandium", "compendium", - "companians", "companions", - "companines", "companions", - "compansate", "compensate", - "comparabil", "comparable", - "comparason", "comparison", - "comparaste", "compares", - "comparatie", "comparative", - "compareble", "comparable", - "comparemos", "compares", - "comparions", "comparison", - "compariosn", "comparisons", - "comparisen", "compares", - "comparitve", "comparative", - "comparsion", "comparison", - "compartent", "compartment", - "compartmet", "compartment", - "compatibel", "compatible", - "compatibil", "compatible", - "compeating", "completing", - "compeditor", "competitor", - "compednium", "compendium", - "compeeting", "completing", - "compeltely", "completely", - "compelting", "completing", - "compeltion", "completion", - "compemdium", "compendium", - "compenduim", "compendium", - "compenents", "components", - "compenidum", "compendium", - "compensare", "compensate", - "comperable", "comparable", - "comperhend", "comprehend", - "compession", "compassion", - "competance", "competence", - "competator", "competitor", - "competenet", "competence", - "competense", "competence", - "competenze", "competence", - "competeted", "competed", - "competetor", "competitor", - "competidor", "competitor", - "competiors", "competitors", - "competitie", "competitive", - "competitin", "competitions", - "competitio", "competitor", - "competiton", "competition", - "competitve", "competitive", - "compilance", "compliance", - "compilaton", "compilation", - "compinsate", "compensate", - "compitable", "compatible", - "compitance", "compliance", - "complacant", "complacent", - "complaince", "compliance", - "complaines", "complaints", - "complainig", "complaining", - "complainte", "complained", - "complation", "completion", - "compleatly", "completely", - "complecate", "complicate", - "completeds", "completes", - "completent", "complement", - "completily", "complexity", - "completito", "completion", - "completley", "completely", - "complexers", "complexes", - "complexety", "complexity", - "complianed", "compliance", - "compliants", "complaints", - "complicaed", "complicate", - "complicare", "complicate", - "complicati", "complicit", - "complicato", "complication", - "complicite", "complicate", - "complicted", "complicated", - "complience", "compliance", - "complimate", "complicate", - "complition", "completion", - "complusion", "compulsion", - "complusive", "compulsive", - "complusory", "compulsory", - "compolsive", "compulsive", - "compolsory", "compulsory", - "compolsury", "compulsory", - "componants", "components", - "componenet", "components", - "componsate", "compensate", - "comporable", "comparable", - "compositae", "composite", - "compositie", "composite", - "compositon", "composition", - "compraison", "comparisons", - "compramise", "compromise", - "comprassem", "compress", - "comprehand", "comprehend", - "compresion", "compression", - "compresors", "compressor", - "compresser", "compressor", - "compressio", "compressor", - "compresson", "compression", - "comprihend", "comprehend", - "comprimise", "compromise", - "compromiss", "compromises", - "compromize", "compromise", - "compromsie", "compromises", - "comprossor", "compressor", - "compteting", "completing", - "comptetion", "completion", - "compulisve", "compulsive", - "compulosry", "compulsory", - "compulsary", "compulsory", - "compulsery", "compulsory", - "compulsing", "compulsion", - "compulsivo", "compulsion", - "compulsury", "compulsory", - "compuslion", "compulsion", - "compuslive", "compulsive", - "compuslory", "compulsory", - "compustion", "compulsion", - "computanti", "computation", - "conatiners", "containers", - "concedendo", "conceded", - "concedered", "conceded", - "conceitual", "conceptual", - "concentate", "concentrate", - "concenting", "connecting", - "conceptial", "conceptual", - "conceptuel", "conceptual", - "concersion", "concession", - "concesions", "concession", - "concidered", "considered", - "conciously", "consciously", - "concission", "concession", - "conclsuion", "concussion", - "conclusies", "conclusive", - "conclution", "conclusion", - "concorrent", "concurrent", - "concsience", "conscience", - "conculsion", "conclusion", - "conculsive", "conclusive", - "concurment", "concurrent", - "concurrant", "concurrent", - "concurrect", "concurrent", - "concusions", "concussion", - "concusison", "concussions", - "condamning", "condemning", - "condemming", "condemning", - "condencing", "condemning", - "condenming", "condemning", - "condensend", "condensed", - "condidtion", "condition", - "conditinal", "conditional", - "conditiner", "conditioner", - "conditiond", "conditioned", - "conditiong", "conditioning", - "condmening", "condemning", - "conduiting", "conducting", - "conencting", "connecting", - "conenction", "connection", - "conenctors", "connectors", - "conesencus", "consensus", - "confedarcy", "confederacy", - "confedence", "conference", - "confedercy", "confederacy", - "conferance", "conference", - "conferenze", "conference", - "conferming", "confirming", - "confernece", "conferences", - "confessino", "confessions", - "confidance", "confidence", - "confidenly", "confidently", - "confidense", "confidence", - "confidenty", "confidently", - "conflcting", "conflating", - "conflicing", "conflicting", - "conflictos", "conflicts", - "confliting", "conflating", - "confriming", "confirming", - "confussion", "confession", - "congratule", "congratulate", - "congresman", "congressman", - "congresmen", "congressmen", - "congressen", "congressmen", - "conjecutre", "conjecture", - "conjuction", "conjunction", - "conjuncion", "conjunction", - "conlcusion", "conclusion", - "conncetion", "connections", - "conneciton", "connection", - "connecties", "connects", - "connectins", "connects", - "connectivy", "connectivity", - "connectpro", "connector", - "conneticut", "connecticut", - "connotaion", "connotation", - "conpsiracy", "conspiracy", - "conqeuring", "conquering", - "conqouring", "conquering", - "conquerers", "conquerors", - "conquoring", "conquering", - "consciense", "conscience", - "consciouly", "consciously", - "consdiered", "considered", - "consending", "consenting", - "consensuel", "consensual", - "consenusal", "consensual", - "consequece", "consequence", - "consequnce", "consequence", - "conservare", "conserve", - "conservato", "conservation", - "conservice", "conserve", - "conservies", "conserve", - "conservite", "conserve", - "consicence", "conscience", - "consideras", "considers", - "consideret", "considerate", - "consipracy", "conspiracy", - "consistant", "consistent", - "consistens", "consists", - "consisteny", "consistency", - "consitency", "consistency", - "consituted", "constituted", - "conslutant", "consultant", - "consluting", "consulting", - "consolidad", "consolidated", - "consonents", "consonants", - "consorcium", "consortium", - "conspirace", "conspiracies", - "conspiricy", "conspiracy", - "conspriacy", "conspiracy", - "constaints", "constraints", - "constatnly", "constantly", - "constently", "constantly", - "constitude", "constitute", - "constitued", "constitute", - "constituem", "constitute", - "constituer", "constitute", - "constitues", "constitutes", - "constituie", "constitute", - "constituit", "constitute", - "constitutn", "constituents", - "constituye", "constitute", - "constnatly", "constantly", - "constracts", "constructs", - "constraits", "constraints", - "constransi", "constraints", - "constrants", "constraints", - "construced", "constructed", - "constructo", "construction", - "construint", "constraint", - "construits", "constructs", - "construted", "constructed", - "consueling", "consulting", - "consultata", "consultant", - "consultate", "consultant", - "consultati", "consultant", - "consultato", "consultation", - "consultent", "consultant", - "consumated", "consummated", - "consumbale", "consumables", - "consuments", "consumes", - "consumirem", "consumerism", - "consumires", "consumerism", - "consumirse", "consumerism", - "consumiste", "consumes", - "consumpion", "consumption", - "contaction", "contacting", - "contageous", "contagious", - "contagiosa", "contagious", - "contagioso", "contagious", - "contaigous", "contagious", - "containors", "containers", - "contaminen", "containment", - "contanting", "contacting", - "contection", "contention", - "contectual", "contextual", - "conteiners", "contenders", - "contempate", "contemplate", - "contemplat", "contempt", - "contempory", "contemporary", - "contenants", "continents", - "contencion", "contention", - "contendors", "contenders", - "contenents", "continents", - "conteneurs", "contenders", - "contengent", "contingent", - "contension", "contention", - "contentino", "contention", - "contentios", "contentious", - "contentous", "contentious", - "contestais", "contests", - "contestans", "contests", - "contestase", "contests", - "contestion", "contention", - "contestors", "contests", - "contextful", "contextual", - "contextuel", "contextual", - "contextura", "contextual", - "contianers", "containers", - "contianing", "containing", - "contibuted", "contributed", - "contibutes", "contributes", - "contigents", "continents", - "contigious", "contagious", - "contignent", "contingent", - "continants", "continents", - "continenal", "continental", - "continenet", "continents", - "contineous", "continuous", - "continetal", "continental", - "contingecy", "contingency", - "contingeny", "contingency", - "continient", "contingent", - "continious", "continuous", - "continiuty", "continuity", - "contintent", "contingent", - "continualy", "continually", - "continuare", "continue", - "continuati", "continuity", - "continuato", "continuation", - "continuent", "contingent", - "continuety", "continuity", - "continunes", "continents", - "continuons", "continuous", - "continutiy", "continuity", - "continuuum", "continuum", - "contitnent", "contingent", - "contiuning", "containing", - "contiunity", "continuity", - "contorller", "controllers", - "contracing", "contracting", - "contractar", "contractor", - "contracter", "contractor", - "contractin", "contraction", - "contractos", "contracts", - "contradice", "contradicted", - "contradics", "contradicts", - "contredict", "contradict", - "contribued", "contributed", - "contribuem", "contribute", - "contribuer", "contribute", - "contribues", "contributes", - "contribuie", "contribute", - "contribuit", "contribute", - "contributo", "contribution", - "contributs", "contributes", - "contribuye", "contribute", - "contricted", "contracted", - "contridict", "contradict", - "contriubte", "contributes", - "controlelr", "controllers", - "controlers", "controls", - "controling", "controlling", - "controlles", "controls", - "controvery", "controversy", - "controvesy", "controversy", - "contrubite", "contributes", - "contrubute", "contribute", - "contuining", "continuing", - "contuinity", "continuity", - "convaluted", "convoluted", - "convcition", "convictions", - "conveinent", "convenient", - "conveluted", "convoluted", - "convencion", "convention", - "conveniant", "convenient", - "conveniece", "convenience", - "convenince", "convenience", - "convential", "conventional", - "converesly", "conversely", - "convergens", "converse", - "converison", "conversions", - "converning", "converting", - "conversare", "converse", - "conversino", "conversions", - "conversley", "conversely", - "conversoin", "conversions", - "conversons", "conversions", - "convertion", "conversion", - "convertire", "converter", - "converying", "converting", - "conveyered", "conveyed", - "conviccion", "conviction", - "conviciton", "conviction", - "convienent", "convenient", - "conviluted", "convoluted", - "convincted", "convince", - "convinsing", "convincing", - "convinving", "convincing", - "convoluded", "convoluted", - "convoulted", "convoluted", - "convulated", "convoluted", - "convuluted", "convoluted", - "cooperatve", "cooperative", - "coordenate", "coordinate", - "coordiante", "coordinate", - "coordinare", "coordinate", - "coordinato", "coordination", - "coordinats", "coordinates", - "coordonate", "coordinate", - "cooridnate", "coordinate", - "copehnagen", "copenhagen", - "copenaghen", "copenhagen", - "copenahgen", "copenhagen", - "copengagen", "copenhagen", - "copengahen", "copenhagen", - "copenhagan", "copenhagen", - "copenhague", "copenhagen", - "copenhagun", "copenhagen", - "copenhaven", "copenhagen", - "copenhegan", "copenhagen", - "copyrighed", "copyrighted", - "copyrigted", "copyrighted", - "corinthans", "corinthians", - "corinthias", "corinthians", - "corinthins", "corinthians", - "cornmitted", "committed", - "corporatie", "corporate", - "corralated", "correlated", - "corralates", "correlates", - "correccion", "correction", - "correciton", "corrections", - "correcters", "correctors", - "correctess", "correctness", - "correctivo", "correction", - "correctons", "corrections", - "corregated", "correlated", - "correkting", "correcting", - "correlatas", "correlates", - "correlatie", "correlated", - "correlatos", "correlates", - "correspend", "correspond", - "corrilated", "correlated", - "corrilates", "correlates", - "corrispond", "correspond", - "corrolated", "correlated", - "corrolates", "correlates", - "corrospond", "correspond", - "corrpution", "corruption", - "corrulates", "correlates", - "corrupcion", "corruption", - "cosmeticas", "cosmetics", - "cosmeticos", "cosmetics", - "costumized", "customized", - "counceling", "counseling", - "councellor", "councillor", - "councelors", "counselors", - "councilers", "councils", - "counselers", "counselors", - "counsellng", "counselling", - "counsilers", "counselors", - "counsiling", "counseling", - "counsilors", "counselors", - "counsolers", "counselors", - "counsoling", "counseling", - "countepart", "counteract", - "counteratk", "counteract", - "counterbat", "counteract", - "countercat", "counteract", - "countercut", "counteract", - "counteries", "counters", - "countoring", "countering", - "countryies", "countryside", - "countrying", "countering", - "courcework", "coursework", - "coursefork", "coursework", - "courthosue", "courthouse", - "courtrooom", "courtroom", - "cousnelors", "counselors", - "coutneract", "counteract", - "coutnering", "countering", - "covenental", "covenant", - "cranberrry", "cranberry", - "creationis", "creations", - "creationsm", "creationism", - "creationst", "creationist", - "creativily", "creatively", - "creativley", "creatively", - "credibilty", "credibility", - "creeperest", "creepers", - "crimanally", "criminally", - "criminalty", "criminally", - "criminalul", "criminally", - "criticable", "critical", - "criticarlo", "critical", - "criticiing", "criticising", - "criticisim", "criticism", - "criticisme", "criticise", - "criticisng", "criticising", - "criticists", "critics", - "criticisze", "criticise", - "criticizms", "criticisms", - "criticizng", "criticizing", - "critisiced", "criticized", - "critisicms", "criticisms", - "critisicsm", "criticisms", - "critisiscm", "criticisms", - "critisisms", "criticisms", - "critisizes", "criticises", - "critisizms", "criticisms", - "critiziced", "criticized", - "critizised", "criticized", - "critizisms", "criticisms", - "critizized", "criticized", - "crocodille", "crocodile", - "crossfiter", "crossfire", - "crutchetts", "crutches", - "crystalens", "crystals", - "crystalisk", "crystals", - "crystallis", "crystals", - "cuatiously", "cautiously", - "culterally", "culturally", - "cultrually", "culturally", - "culumative", "cumulative", - "culutrally", "culturally", - "cumbersone", "cumbersome", - "cumbursome", "cumbersome", - "cumpolsory", "compulsory", - "cumulitive", "cumulative", - "currancies", "currencies", - "currenctly", "currency", - "currenices", "currencies", - "currentfps", "currents", - "currentlys", "currents", - "currentpos", "currents", - "currentusa", "currents", - "curriculem", "curriculum", - "curriculim", "curriculum", - "curriences", "currencies", - "curroption", "corruption", - "custimized", "customized", - "customzied", "customized", - "custumized", "customized", - "cutscences", "cutscene", - "cutscenses", "cutscene", - "dangerouly", "dangerously", - "dealerhsip", "dealerships", - "deathamtch", "deathmatch", - "deathmacth", "deathmatch", - "debateable", "debatable", - "decembeard", "december", - "decendants", "descendants", - "decendents", "descendants", - "decideable", "decidable", - "deciptions", "depictions", - "decisiones", "decisions", - "declarasen", "declares", - "declaraste", "declares", - "declaremos", "declares", - "decomposit", "decompose", - "decoracion", "decoration", - "decorativo", "decoration", - "decoritive", "decorative", - "decroative", "decorative", - "decsending", "descending", - "dedicacion", "dedication", - "dedikation", "dedication", - "deducatble", "deductible", - "deducitble", "deductible", - "defacation", "defamation", - "defamating", "defamation", - "defanitely", "definitely", - "defelction", "deflection", - "defendeers", "defender", - "defendents", "defendants", - "defenderes", "defenders", - "defenesman", "defenseman", - "defenselss", "defenseless", - "defensivly", "defensively", - "defianetly", "definitely", - "defiantely", "definitely", - "defiantley", "definitely", - "defibately", "definitely", - "deficately", "definitely", - "deficiancy", "deficiency", - "deficience", "deficiencies", - "deficienct", "deficient", - "deficienty", "deficiency", - "defiintely", "definitely", - "definaetly", "definitely", - "definaitly", "definitely", - "definaltey", "definitely", - "definataly", "definitely", - "definateky", "definitely", - "definately", "definitely", - "definatily", "definitely", - "defination", "definition", - "definative", "definitive", - "definatlly", "definitely", - "definatrly", "definitely", - "definayely", "definitely", - "defineatly", "definitely", - "definetaly", "definitely", - "definetely", "definitely", - "definetily", "definitely", - "definetlly", "definitely", - "definettly", "definitely", - "definicion", "definition", - "definietly", "definitely", - "definining", "defining", - "definitaly", "definitely", - "definiteyl", "definitely", - "definitivo", "definition", - "definitley", "definitely", - "definitlly", "definitely", - "definitlry", "definitely", - "definitlty", "definitely", - "definjtely", "definitely", - "definltely", "definitely", - "definotely", "definitely", - "definstely", "definitely", - "defintaley", "definitely", - "defintiely", "definitely", - "defintiion", "definitions", - "definutely", "definitely", - "deflaction", "deflection", - "defleciton", "deflection", - "deflektion", "deflection", - "defniately", "definitely", - "degenarate", "degenerate", - "degenerare", "degenerate", - "degenerite", "degenerate", - "degoratory", "derogatory", - "degraderad", "degraded", - "dehydraded", "dehydrated", - "dehyrdated", "dehydrated", - "deifnately", "definitely", - "deisgnated", "designated", - "delaership", "dealership", - "delearship", "dealership", - "delegaties", "delegate", - "delegative", "delegate", - "delfection", "deflection", - "delibarate", "deliberate", - "deliberant", "deliberate", - "delibirate", "deliberate", - "deligthful", "delightful", - "deliverate", "deliberate", - "deliverees", "deliveries", - "deliviered", "delivered", - "deliviring", "delivering", - "delporable", "deplorable", - "delpoyment", "deployment", - "delutional", "delusional", - "dementieva", "dementia", - "deminsions", "dimensions", - "democracis", "democracies", - "democracts", "democrat", - "democratas", "democrats", - "democrates", "democrats", - "demograhic", "demographic", - "demographs", "demographics", - "demograpic", "demographic", - "demolation", "demolition", - "demolicion", "demolition", - "demolision", "demolition", - "demolitian", "demolition", - "demoliting", "demolition", - "demoloshed", "demolished", - "demolution", "demolition", - "demonished", "demolished", - "demonstate", "demonstrate", - "demonstras", "demonstrates", - "demorcracy", "democracy", - "denegerate", "degenerate", - "denominato", "denomination", - "denomintor", "denominator", - "deocrative", "decorative", - "deomcratic", "democratic", - "deparments", "departments", - "departmens", "departments", - "departmnet", "departments", - "depcitions", "depictions", - "depdending", "depending", - "depencency", "dependency", - "dependance", "dependence", - "dependancy", "dependency", - "dependandt", "dependant", - "dependends", "depended", - "dependened", "depended", - "dependenta", "dependant", - "dependente", "dependence", - "depicitons", "depictions", - "deplorabel", "deplorable", - "deplorabil", "deplorable", - "deplorible", "deplorable", - "deplyoment", "deployment", - "depolyment", "deployment", - "depositers", "deposits", - "depressief", "depressive", - "depressies", "depressive", - "deprivaton", "deprivation", - "deragotory", "derogatory", - "derivaties", "derivatives", - "deriviated", "derived", - "derivitave", "derivative", - "derivitive", "derivative", - "derogatary", "derogatory", - "derogatery", "derogatory", - "derogetory", "derogatory", - "derogitory", "derogatory", - "derogotary", "derogatory", - "derogotory", "derogatory", - "derviative", "derivative", - "descendats", "descendants", - "descendend", "descended", - "descenting", "descending", - "descerning", "descending", - "descipable", "despicable", - "descisions", "decisions", - "descriibes", "describes", - "descripton", "description", - "desginated", "designated", - "desigining", "designing", - "desireable", "desirable", - "desktopbsd", "desktops", - "despciable", "despicable", - "desperatly", "desperately", - "desperetly", "desperately", - "despicaple", "despicable", - "despicible", "despicable", - "dessicated", "desiccated", - "destinatin", "destinations", - "destinaton", "destination", - "destoryers", "destroyers", - "destorying", "destroying", - "destroyeds", "destroyers", - "destroyeer", "destroyers", - "destrucion", "destruction", - "destrucive", "destructive", - "destryoing", "destroying", - "detectarlo", "detector", - "detectaron", "detector", - "detectoare", "detector", - "determinas", "determines", - "determinig", "determining", - "determinsm", "determinism", - "deutschand", "deutschland", - "devastaded", "devastated", - "devastaing", "devastating", - "devastanti", "devastating", - "devasteted", "devastated", - "develepors", "developers", - "develoeprs", "developers", - "developmet", "developments", - "developors", "develops", - "developped", "developed", - "developres", "develops", - "develpment", "development", - "devestated", "devastated", - "devolvendo", "devolved", - "deyhdrated", "dehydrated", - "diagnosied", "diagnose", - "diagnosies", "diagnosis", - "diagnositc", "diagnostic", - "diagnossed", "diagnose", - "diagnosted", "diagnose", - "diagnotics", "diagnostic", - "diagonstic", "diagnostic", - "dichotomoy", "dichotomy", - "dicitonary", "dictionary", - "diconnects", "disconnects", - "dicovering", "discovering", - "dictateurs", "dictates", - "dictionare", "dictionaries", - "differance", "difference", - "differenly", "differently", - "differense", "differences", - "differente", "difference", - "differentl", "differential", - "differenty", "differently", - "differnece", "difference", - "difficulte", "difficulties", - "difficults", "difficulties", - "difficutly", "difficulty", - "diffuculty", "difficulty", - "diganostic", "diagnostic", - "dimensinal", "dimensional", - "dimentions", "dimensions", - "dimesnions", "dimensions", - "dimineshes", "diminishes", - "diminising", "diminishing", - "dimunitive", "diminutive", - "dinosaures", "dinosaurs", - "dinosaurus", "dinosaurs", - "dipections", "depictions", - "diplimatic", "diplomatic", - "diplomacia", "diplomatic", - "diplomancy", "diplomacy", - "dipolmatic", "diplomatic", - "directinla", "directional", - "directionl", "directional", - "directivos", "directions", - "directores", "directors", - "directorys", "directors", - "directsong", "directions", - "disaapoint", "disappoint", - "disagreeed", "disagreed", - "disapeared", "disappeared", - "disappeard", "disappeared", - "disappered", "disappeared", - "disappiont", "disappoint", - "disaproval", "disapproval", - "disastorus", "disastrous", - "disastrosa", "disastrous", - "disastrose", "disastrous", - "disastrosi", "disastrous", - "disastroso", "disastrous", - "disaterous", "disastrous", - "discalimer", "disclaimer", - "discapline", "discipline", - "discepline", "discipline", - "disception", "discretion", - "discharded", "discharged", - "disciplers", "disciples", - "disciplies", "disciplines", - "disciplins", "disciplines", - "disciprine", "discipline", - "disclamier", "disclaimer", - "discliamer", "disclaimer", - "disclipine", "discipline", - "disclousre", "disclosure", - "disclsoure", "disclosure", - "discograhy", "discography", - "discograpy", "discography", - "discolsure", "disclosure", - "disconenct", "disconnect", - "disconncet", "disconnects", - "disconnets", "disconnects", - "discontued", "discounted", - "discoruage", "discourages", - "discources", "discourse", - "discourgae", "discourages", - "discourges", "discourages", - "discoveres", "discovers", - "discoveryd", "discovered", - "discoverys", "discovers", - "discrecion", "discretion", - "discreddit", "discredited", - "discrepany", "discrepancy", - "discresion", "discretion", - "discreting", "discretion", - "discribing", "describing", - "discrimine", "discriminate", - "discrouage", "discourages", - "discrption", "discretion", - "discusison", "discussions", - "discusting", "discussing", - "disgracful", "disgraceful", - "disgrunted", "disgruntled", - "disgruntld", "disgruntled", - "disguisted", "disguise", - "disgustiny", "disgustingly", - "disgustosa", "disgusts", - "disgustose", "disgusts", - "disgustosi", "disgusts", - "disgustoso", "disgusts", - "dishcarged", "discharged", - "dishinored", "dishonored", - "disicpline", "discipline", - "disiplined", "disciplined", - "dislcaimer", "disclaimer", - "dismanteld", "dismantled", - "dismanting", "dismantling", - "dismentled", "dismantled", - "dispecable", "despicable", - "dispencary", "dispensary", - "dispencers", "dispenser", - "dispencing", "dispensing", - "dispensare", "dispenser", - "dispensory", "dispensary", - "dispesnary", "dispensary", - "dispicable", "despicable", - "displayfps", "displays", - "dispositon", "disposition", - "dispostion", "disposition", - "disputerad", "disputed", - "disrecpect", "disrespect", - "disrection", "discretion", - "disrepsect", "disrespect", - "disresepct", "disrespect", - "disrespekt", "disrespect", - "disription", "disruption", - "disrispect", "disrespect", - "disrputing", "disrupting", - "disruptivo", "disruption", - "disruptron", "disruption", - "dissapears", "disappears", - "dissappear", "disappear", - "disscusion", "discussion", - "dissmisive", "dismissive", - "dissodance", "dissonance", - "dissonante", "dissonance", - "dissonence", "dissonance", - "distastful", "distasteful", - "disticntly", "distinctly", - "distiction", "distinction", - "distincion", "distinction", - "distincive", "distinctive", - "distinclty", "distinctly", - "distinctie", "distinctive", - "distinctin", "distinctions", - "distingish", "distinguish", - "distingush", "distinguish", - "distintcly", "distinctly", - "distoriton", "distortion", - "distorsion", "distortion", - "distortian", "distortion", - "distortron", "distortion", - "distractes", "distracts", - "distractia", "district", - "distractin", "district", - "distractiv", "district", - "distration", "distortion", - "distribuem", "distribute", - "distribuer", "distribute", - "distribuie", "distribute", - "distribuit", "distribute", - "distributs", "distributors", - "distribuye", "distribute", - "distrotion", "distortion", - "distrubing", "disturbing", - "distrubtes", "distrust", - "distrubute", "distribute", - "distubring", "disturbing", - "disturbace", "disturbance", - "disturping", "disrupting", - "disucssing", "discussing", - "disucssion", "discussion", - "disurption", "disruption", - "ditributed", "distributed", - "diversifiy", "diversify", - "dividendes", "dividends", - "dividendos", "dividends", - "divideneds", "dividend", - "divinition", "divination", - "divinitory", "divinity", - "divisiones", "divisions", - "dobulelift", "doublelift", - "doccuments", "documents", - "documentry", "documentary", - "dogmatisch", "dogmatic", - "dolphinese", "dolphins", - "domianting", "dominating", - "domimation", "domination", - "dominacion", "domination", - "dominaters", "dominates", - "donwgraded", "downgraded", - "donwloaded", "downloaded", - "donwvoters", "downvoters", - "donwvoting", "downvoting", - "doomsdaily", "doomsday", - "doubellift", "doublelift", - "doubleiift", "doublelift", - "doubleleft", "doublelift", - "doublelfit", "doublelift", - "doublerift", "doublelift", - "doulbelift", "doublelift", - "downgarded", "downgraded", - "downgrated", "downgrade", - "downlaoded", "downloaded", - "downloadas", "downloads", - "downloades", "downloads", - "downovting", "downvoting", - "downroaded", "downgraded", - "downsiders", "downsides", - "downstaris", "downstairs", - "downstiars", "downstairs", - "downtokers", "downvoters", - "downtoking", "downvoting", - "downtraded", "downgraded", - "downviting", "downvoting", - "downvotear", "downvoters", - "downvoteas", "downvoters", - "downvoteds", "downvoters", - "downvotees", "downvoters", - "downvotesd", "downvoters", - "downvotess", "downvoters", - "downvotest", "downvoters", - "downvoteur", "downvoters", - "downvoties", "downvoters", - "downvotres", "downvoters", - "downvotted", "downvote", - "downvottes", "downvoters", - "downwoters", "downvoters", - "downwoting", "downvoting", - "drasticaly", "drastically", - "drasticlly", "drastically", - "draughtman", "draughtsman", - "dumbbellls", "dumbbells", - "dumbfouded", "dumbfounded", - "dumbfouned", "dumbfounded", - "dungeoness", "dungeons", - "dupilcates", "duplicates", - "duplicants", "duplicates", - "duplicatas", "duplicates", - "duplicitas", "duplicates", - "duplifaces", "duplicates", - "durabiltiy", "durability", - "dyamically", "dynamically", - "dynamicaly", "dynamically", - "dynamicdns", "dynamics", - "dynamiclly", "dynamically", - "dynamicpsf", "dynamics", - "dynamitage", "dynamite", - "dysfuncion", "dysfunction", - "earhtbound", "earthbound", - "earthqauke", "earthquake", - "earthquack", "earthquake", - "earthquaks", "earthquakes", - "earthquate", "earthquake", - "earthqukes", "earthquakes", - "easthetics", "aesthetics", - "ecoligical", "ecological", - "ecomonical", "economical", - "econimical", "economical", - "econimists", "economists", - "economicas", "economics", - "economicos", "economics", - "economicus", "economics", - "economisch", "economic", - "economisit", "economists", - "effeciency", "efficiency", - "effectivly", "effectively", - "efficeincy", "efficiency", - "efficently", "efficiently", - "efficiancy", "efficiency", - "efficienct", "efficient", - "efficienty", "efficiently", - "egotistcal", "egotistical", - "ehtnically", "ethnically", - "ejaculaion", "ejaculation", - "ejaculatie", "ejaculate", - "ejaculatin", "ejaculation", - "ejaculaton", "ejaculation", - "ejaculatte", "ejaculate", - "electircal", "electrical", - "electivite", "elective", - "electoraat", "electorate", - "electorale", "electorate", - "electorite", "electorate", - "electornic", "electronic", - "electrican", "electrician", - "electriciy", "electricity", - "electricty", "electricity", - "electrinic", "electrician", - "electroate", "electorate", - "electrodan", "electron", - "electroinc", "electron", - "electrolye", "electrolytes", - "electroman", "electron", - "electroncs", "electrons", - "electrones", "electrons", - "electronik", "election", - "electronis", "electronics", - "electronix", "election", - "elemantary", "elementary", - "elementery", "elementary", - "elementray", "elementary", - "eleminated", "eliminated", - "elephantes", "elephants", - "elephantis", "elephants", - "elephantos", "elephants", - "elephantus", "elephants", - "eletricity", "electricity", - "elimanates", "eliminates", - "elimenates", "eliminates", - "elimentary", "elementary", - "elimimates", "eliminates", - "eliminaste", "eliminates", - "eliminatin", "elimination", - "eliminaton", "elimination", - "eliminster", "eliminates", - "ellipitcal", "elliptical", - "ellipsical", "elliptical", - "ellipticle", "elliptical", - "ellitpical", "elliptical", - "ellpitical", "elliptical", - "eloquantly", "eloquently", - "eloquintly", "eloquently", - "emapthetic", "empathetic", - "embarassed", "embarrassed", - "embarassig", "embarrassing", - "embarrased", "embarrassed", - "embarrases", "embarrassed", - "embezelled", "embezzled", - "emblamatic", "emblematic", - "embodyment", "embodiment", - "emergenies", "emergencies", - "emmigrated", "emigrated", - "emminently", "eminently", - "emmisaries", "emissaries", - "emobdiment", "embodiment", - "emotionaly", "emotionally", - "empahsized", "emphasized", - "empahsizes", "emphasizes", - "empathatic", "empathetic", - "emphacized", "emphasized", - "emphatetic", "empathetic", - "emphatised", "emphasized", - "emphatized", "emphasized", - "emphatizes", "emphasizes", - "emphazised", "emphasized", - "emphazises", "emphasizes", - "emphesized", "emphasized", - "emphesizes", "emphasizes", - "emphisized", "emphasized", - "emphisizes", "emphasizes", - "empiricaly", "empirically", - "employeers", "employees", - "employeurs", "employer", - "emprisoned", "imprisoned", - "encahnting", "enchanting", - "enchancing", "enchanting", - "enchanging", "enchanting", - "enchantent", "enchantment", - "enchantmet", "enchantments", - "encompases", "encompasses", - "encounterd", "encountered", - "encountred", "encountered", - "encouraing", "encouraging", - "encoutners", "encounters", - "encription", "encryption", - "encrpytion", "encryption", - "encyrption", "encryption", - "endlessley", "endlessly", - "endolithes", "endoliths", - "enforceing", "enforcing", - "engagemnet", "engagements", - "engagemnts", "engagements", - "engieneers", "engineers", - "enginereed", "engineered", - "enivitable", "inevitable", - "enlargment", "enlargement", - "enlighment", "enlighten", - "enlightend", "enlightened", - "enlightned", "enlightened", - "enrolement", "enrollment", - "enrollemnt", "enrollment", - "enterpirse", "enterprise", - "enterprice", "enterprise", - "enterpries", "enterprises", - "enterprize", "enterprise", - "enterprsie", "enterprises", - "enterrpise", "enterprises", - "entertaing", "entertaining", - "enthically", "ethnically", - "enthisiast", "enthusiast", - "enthuiasts", "enthusiast", - "enthuisast", "enthusiasts", - "enthusiams", "enthusiasm", - "enthusiant", "enthusiast", - "enthusiats", "enthusiast", - "enthusiest", "enthusiast", - "enthusists", "enthusiasts", - "envelopped", "envelope", - "enveloppen", "envelope", - "enveloppes", "envelope", - "enviorment", "environment", - "enviroment", "environment", - "environmet", "environments", - "equiavlent", "equivalents", - "equilavent", "equivalent", - "equilibium", "equilibrium", - "equilibrim", "equilibrium", - "equilibrum", "equilibrium", - "equippment", "equipment", - "equitorial", "equatorial", - "equivalant", "equivalent", - "equivalnce", "equivalence", - "equivalnet", "equivalents", - "equivelant", "equivalent", - "equivelent", "equivalent", - "equivilant", "equivalent", - "equivilent", "equivalent", - "equivlaent", "equivalents", - "equivolent", "equivalent", - "eratically", "erratically", - "escalative", "escalate", - "escavation", "escalation", - "esitmation", "estimation", - "esoterisch", "esoteric", - "especailly", "especially", - "espeically", "especially", - "espressino", "espresso", - "espression", "espresso", - "essencials", "essentials", - "essensials", "essentials", - "essentails", "essentials", - "essentialy", "essentially", - "essentiels", "essentials", - "essentuals", "essentials", - "estabishes", "establishes", - "estimacion", "estimation", - "estimativo", "estimation", - "estination", "estimation", - "ethicallly", "ethically", - "ethincally", "ethnically", - "ethnicites", "ethnicities", - "ethnicitiy", "ethnicity", - "euphorical", "euphoria", - "euphorisch", "euphoric", - "euthanaisa", "euthanasia", - "euthanazia", "euthanasia", - "euthanesia", "euthanasia", - "evaluacion", "evaluation", - "evalutaion", "evaluation", - "evaulating", "evaluating", - "evaulation", "evaluation", - "eventaully", "eventually", - "eventially", "eventually", - "everyoneis", "everyones", - "exacberate", "exacerbated", - "exagerated", "exaggerated", - "exagerates", "exaggerates", - "exagerrate", "exaggerate", - "exaggarate", "exaggerate", - "exaggurate", "exaggerate", - "exahusting", "exhausting", - "exahustion", "exhaustion", - "examinated", "examined", - "examinerad", "examined", - "exapansion", "expansion", - "exapnsions", "expansions", - "exauhsting", "exhausting", - "exauhstion", "exhaustion", - "excecuting", "executing", - "excecution", "execution", - "exceedigly", "exceedingly", - "exceedinly", "exceedingly", - "excellance", "excellence", - "excellenet", "excellence", - "excellenze", "excellence", - "excerising", "exercising", - "excessivly", "excessively", - "exchangees", "exchanges", - "excitiment", "excitement", - "exclsuives", "exclusives", - "exclusivas", "exclusives", - "exclusivly", "exclusively", - "exclusivos", "exclusives", - "exclusivty", "exclusivity", - "exclussive", "exclusives", - "exclusvies", "exclusives", - "excpetions", "exceptions", - "exculsives", "exclusives", - "exculsivly", "exclusively", - "execptions", "exceptions", - "exectuable", "executable", - "exectuions", "executions", - "exectuives", "executives", - "execusions", "executions", - "executabil", "executable", - "executible", "executable", - "executiner", "executioner", - "executings", "executions", - "executivas", "executives", - "exeedingly", "exceedingly", - "exepmtions", "exemptions", - "exeptional", "exceptional", - "exercicing", "exercising", - "exercizing", "exercising", - "exersicing", "exercising", - "exersising", "exercising", - "exersizing", "exercising", - "exerternal", "external", - "exeuctions", "executions", - "exhasuting", "exhausting", - "exhasution", "exhaustion", - "exhaustivo", "exhaustion", - "exhibicion", "exhibition", - "exhibitons", "exhibits", - "exhuasting", "exhausting", - "exhuastion", "exhaustion", - "exibitions", "exhibitions", - "exictement", "excitement", - "exipration", "expiration", - "existantes", "existent", - "existenial", "existential", - "existental", "existential", - "exlcusives", "exclusives", - "exorbatant", "exorbitant", - "exorbatent", "exorbitant", - "exorbidant", "exorbitant", - "exorbirant", "exorbitant", - "exorbitent", "exorbitant", - "expalining", "explaining", - "expanisons", "expansions", - "expansivos", "expansions", - "expanssion", "expansions", - "expantions", "expansions", - "expecially", "especially", - "expectaion", "expectation", - "expectansy", "expectancy", - "expectency", "expectancy", - "expections", "exceptions", - "expedetion", "expedition", - "expedicion", "expedition", - "expeditivo", "expedition", - "expeiments", "experiments", - "expemtions", "exemptions", - "expendeble", "expendable", - "expendible", "expendable", - "expensable", "expendable", - "expentancy", "expectancy", - "expereince", "experience", - "experement", "experiment", - "experiance", "experience", - "experieced", "experienced", - "experieces", "experiences", - "experiemnt", "experiment", - "experiened", "experienced", - "experiense", "experiences", - "expermient", "experiments", - "experssion", "expression", - "expextancy", "expectancy", - "expidetion", "expedition", - "expierence", "experience", - "expination", "expiration", - "expirement", "experiment", - "explanatin", "explanations", - "explicatia", "explicit", - "explicatie", "explicit", - "explicatif", "explicit", - "explicatii", "explicit", - "explicetly", "explicitly", - "explicilty", "explicitly", - "explioting", "exploiting", - "exploiding", "exploiting", - "exploition", "exploiting", - "explorarea", "explorer", - "exploreres", "explorers", - "explosivas", "explosives", - "explossion", "explosions", - "explossive", "explosives", - "explosvies", "explosives", - "explotions", "explosions", - "explusions", "explosions", - "expodition", "exposition", - "expoliting", "exploiting", - "expolsions", "explosions", - "expolsives", "explosives", - "exponental", "exponential", - "exposicion", "exposition", - "expositivo", "exposition", - "expotition", "exposition", - "exprensive", "expressive", - "expresions", "expression", - "expresison", "expressions", - "expressens", "expresses", - "expressief", "expressive", - "expressley", "expressly", - "expriation", "expiration", - "extensivly", "extensively", - "extentions", "extensions", - "exterioara", "exterior", - "exterioare", "exterior", - "extermally", "externally", - "extermists", "extremists", - "extraccion", "extraction", - "extractivo", "extraction", - "extractnow", "extraction", - "extradtion", "extraction", - "extremaste", "extremes", - "extremeley", "extremely", - "extremelly", "extremely", - "extrememly", "extremely", - "extremests", "extremists", - "extremised", "extremes", - "extremisim", "extremism", - "extremisme", "extremes", - "extremiste", "extremes", - "extrenally", "externally", - "extrimists", "extremists", - "eyeballers", "eyeballs", - "fabriacted", "fabricated", - "fabricatie", "fabricated", - "faciliated", "facilitated", - "facilitait", "facilitate", - "facilitant", "facilitate", - "facilitare", "facilitate", - "facisnated", "fascinated", - "facitilies", "facilities", - "facsinated", "fascinated", - "fahernheit", "fahrenheit", - "fahrenhiet", "fahrenheit", - "fallatious", "fallacious", - "fallicious", "fallacious", - "falshbacks", "flashbacks", - "familiarty", "familiarity", - "familiarze", "familiarize", - "fanaticals", "fanatics", - "fanfaction", "fanfiction", - "fanfcition", "fanfiction", - "fanficiton", "fanfiction", - "fanserivce", "fanservice", - "fanservise", "fanservice", - "fanservive", "fanservice", - "fantasiose", "fantasies", - "farehnheit", "fahrenheit", - "farhenheit", "fahrenheit", - "fascianted", "fascinated", - "fascinatie", "fascinated", - "fascinatin", "fascination", - "fascistisk", "fascists", - "fatalaties", "fatalities", - "favoruites", "favourites", - "favourates", "favourites", - "favouritsm", "favourites", - "favourties", "favourites", - "federacion", "federation", - "federativo", "federation", - "fellowhsip", "fellowship", - "fellowshop", "fellowship", - "feminimity", "femininity", - "feministas", "feminists", - "feminitity", "femininity", - "fermentato", "fermentation", - "fertalizer", "fertilizer", - "fertelizer", "fertilizer", - "fertilizar", "fertilizer", - "fertilzier", "fertilizer", - "fertiziler", "fertilizer", - "festivales", "festivals", - "fetishiste", "fetishes", - "ficticious", "fictitious", - "filessytem", "filesystem", - "filesytems", "filesystem", - "filmamkers", "filmmakers", - "filmmakare", "filmmakers", - "finallizes", "finalizes", - "financialy", "financially", - "fingernals", "fingernails", - "fingerpies", "fingertips", - "fingerpint", "fingerprint", - "fingertaps", "fingertips", - "fingertits", "fingertips", - "fingertops", "fingertips", - "fireballls", "fireballs", - "firefigher", "firefighter", - "firefigter", "firefighter", - "firendlies", "friendlies", - "firghtened", "frightened", - "fisionable", "fissionable", - "flashligth", "flashlight", - "flaskbacks", "flashbacks", - "flawleslly", "flawlessly", - "flexibiliy", "flexibility", - "flexibilty", "flexibility", - "flimmakers", "filmmakers", - "fluctuatie", "fluctuate", - "fluctuatin", "fluctuations", - "flutterhsy", "fluttershy", - "fluttersky", "fluttershy", - "flutterspy", "fluttershy", - "forcifully", "forcefully", - "forecfully", "forcefully", - "foreginers", "foreigners", - "foregorund", "foreground", - "foreignese", "foreigners", - "foreigness", "foreigners", - "foreignors", "foreigners", - "foreingers", "foreigners", - "forensisch", "forensic", - "foreseeble", "foreseeable", - "forgeiners", "foreigners", - "forgieners", "foreigners", - "forgivance", "forgiven", - "forgivenss", "forgiveness", - "forgotting", "forgetting", - "foriegners", "foreigners", - "formadible", "formidable", - "formalhaut", "fomalhaut", - "formallity", "formally", - "formallize", "formalize", - "formatiing", "formatting", - "formatings", "formations", - "formativos", "formations", - "formidabel", "formidable", - "formidabil", "formidable", - "formidible", "formidable", - "forminable", "formidable", - "formitable", "formidable", - "formuladas", "formulas", - "formulados", "formulas", - "forseeable", "foreseeable", - "fortelling", "foretelling", - "fortunatly", "fortunately", - "fortunetly", "fortunately", - "foundaiton", "foundations", - "foundaries", "foundries", - "foundatoin", "foundations", - "fractalers", "fractals", - "fractalius", "fractals", - "fractalpus", "fractals", - "fracturare", "fracture", - "fragmanted", "fragment", - "francaises", "franchises", - "franchices", "franchises", - "franchines", "franchises", - "franchizes", "franchises", - "franchsies", "franchises", - "fransiscan", "franciscan", - "franticaly", "frantically", - "franticlly", "frantically", - "fraternaty", "fraternity", - "fraternety", "fraternity", - "fraterntiy", "fraternity", - "fraturnity", "fraternity", - "fraudalent", "fraudulent", - "fraudelant", "fraudulent", - "fraudelent", "fraudulent", - "fraudolent", "fraudulent", - "fraudulant", "fraudulent", - "freedomers", "freedoms", - "freedomest", "freedoms", - "freindlies", "friendlies", - "freindship", "friendship", - "frequencey", "frequency", - "friednship", "friendships", - "friednzone", "friendzoned", - "friendhsip", "friendship", - "friendsies", "friendlies", - "friendzies", "friendlies", - "friendzond", "friendzoned", - "frientship", "friendship", - "frigthened", "frightened", - "fromatting", "formatting", - "fromidable", "formidable", - "frontlinie", "frontline", - "fruadulent", "fraudulent", - "frustraded", "frustrated", - "frustradet", "frustrates", - "frustraits", "frustrates", - "frustrants", "frustrates", - "frustratin", "frustration", - "frustrsted", "frustrates", - "fucntional", "functional", - "fulfulling", "fulfilling", - "fullfiling", "fulfilling", - "fullfilled", "fulfilled", - "fullscrean", "fullscreen", - "fulttershy", "fluttershy", - "funcitonal", "functional", - "fundametal", "fundamental", - "furstrated", "frustrated", - "furstrates", "frustrates", - "furutistic", "futuristic", - "futhermore", "furthermore", - "futurestic", "futuristic", - "futurisitc", "futuristic", - "futurustic", "futuristic", - "galvinized", "galvanized", - "garuanteed", "guaranteed", - "garuantees", "guarantees", - "gauntanamo", "guantanamo", - "gauntlents", "gauntlet", - "gauranteed", "guaranteed", - "gaurantees", "guarantees", - "gaurenteed", "guaranteed", - "gaurentees", "guarantees", - "generalice", "generalize", - "generalife", "generalize", - "generalnie", "generalize", - "generaters", "generates", - "generaties", "generate", - "generatios", "generators", - "generatons", "generators", - "generatore", "generate", - "generelize", "generalize", - "generocity", "generosity", - "generoisty", "generosity", - "generostiy", "generosity", - "geneticaly", "genetically", - "geneticlly", "genetically", - "genitalias", "genitals", - "genuinelly", "genuinely", - "geographia", "geographical", - "geogrpahic", "geographic", - "germanisch", "germanic", - "gigantisch", "gigantic", - "gimmickers", "gimmicks", - "girlfirend", "girlfriend", - "girlfreind", "girlfriend", - "girlfriens", "girlfriends", - "girlfrinds", "girlfriends", - "girlfrined", "girlfriends", - "goalkeaper", "goalkeeper", - "goalkeeprs", "goalkeeper", - "goalkepeer", "goalkeeper", - "goegraphic", "geographic", - "golakeeper", "goalkeeper", - "goldburger", "goldberg", - "goosebumbs", "goosebumps", - "goosegumps", "goosebumps", - "goosepumps", "goosebumps", - "gothenberg", "gothenburg", - "govenrment", "government", - "govermenet", "government", - "govermnent", "governments", - "governemnt", "government", - "governened", "governed", - "governered", "governed", - "governmant", "governmental", - "governmetn", "governments", - "governmnet", "government", - "govnerment", "government", - "govornment", "government", - "gradiating", "graduating", - "gradiation", "graduation", - "graduacion", "graduation", - "grapefriut", "grapefruit", - "grapefrukt", "grapefruit", - "graphicaly", "graphically", - "graphiclly", "graphically", - "gratituous", "gratuitous", - "gratiutous", "gratuitous", - "gratuidous", "gratuitous", - "gratuituos", "gratuitous", - "gratutious", "gratuitous", - "graudating", "graduating", - "graudation", "graduation", - "gravitatie", "gravitate", - "greatfully", "gratefully", - "greenhosue", "greenhouse", - "greviances", "grievances", - "grievences", "grievances", - "grilfriend", "girlfriend", - "guaduloupe", "guadalupe", - "guanatanmo", "guantanamo", - "guantamamo", "guantanamo", - "guantamano", "guantanamo", - "guantanano", "guantanamo", - "guantanemo", "guantanamo", - "guantanoma", "guantanamo", - "guantanomo", "guantanamo", - "guantonamo", "guantanamo", - "guarantess", "guarantees", - "guardiands", "guardians", - "guardianes", "guardians", - "guardianis", "guardians", - "guarenteed", "guaranteed", - "guarentees", "guarantees", - "guarnateed", "guaranteed", - "guarnatees", "guarantees", - "guarunteed", "guaranteed", - "guaruntees", "guarantees", - "guatamalan", "guatemalan", - "gunatanamo", "guantanamo", - "gunlsinger", "gunslinger", - "gunsiinger", "gunslinger", - "gunslanger", "gunslinger", - "gunsligner", "gunslinger", - "gunstinger", "gunslinger", - "gymanstics", "gymnastics", - "gymnasitcs", "gymnastics", - "gynmastics", "gymnastics", - "haemorrage", "haemorrhage", - "halloweeen", "halloween", - "hambergers", "hamburgers", - "hamburgare", "hamburger", - "hamburgesa", "hamburgers", - "hamburgles", "hamburgers", - "hamburgurs", "hamburgers", - "handcuffes", "handcuffs", - "handelbars", "handlebars", - "handicaped", "handicapped", - "handwritng", "handwriting", - "harasments", "harassments", - "hardlinked", "hardline", - "harmoniacs", "harmonic", - "harmonisch", "harmonic", - "harrasment", "harassment", - "harrassing", "harassing", - "harvasting", "harvesting", - "haversting", "harvesting", - "headhpones", "headphones", - "headphoens", "headphones", - "headquarer", "headquarter", - "headquater", "headquarter", - "headshoots", "headshot", - "healtchare", "healthcare", - "healtheast", "healthiest", - "healthyest", "healthiest", - "heapdhones", "headphones", - "heartbeart", "heartbeat", - "heartbeast", "heartbeat", - "heartborne", "heartbroken", - "heartbrake", "heartbreak", - "hearthsone", "hearthstone", - "heatlhcare", "healthcare", - "heavyweght", "heavyweight", - "heavyweigt", "heavyweight", - "hedgehodge", "hedgehog", - "heidelburg", "heidelberg", - "heigthened", "heightened", - "heistation", "hesitation", - "helathcare", "healthcare", - "helicopers", "helicopters", - "helicoptor", "helicopter", - "helicotper", "helicopters", - "helicpoter", "helicopter", - "helictoper", "helicopters", - "helikopter", "helicopter", - "hemingwary", "hemingway", - "hemingwavy", "hemingway", - "hemipshere", "hemisphere", - "hemishpere", "hemisphere", - "hemmorhage", "hemorrhage", - "hempishere", "hemisphere", - "herculeans", "hercules", - "herculeasy", "hercules", - "herculeees", "hercules", - "hesitstion", "hesitation", - "hestiation", "hesitation", - "hieghtened", "heightened", - "hierachies", "hierarchies", - "hieroglphs", "hieroglyphs", - "highalnder", "highlander", - "highlighed", "highlighted", - "highligted", "highlighted", - "highloader", "highlander", - "highpander", "highlander", - "highscholl", "highschool", - "highshcool", "highschool", - "hillarious", "hilarious", - "hinderance", "hindrance", - "hinderence", "hindrance", - "hipsterest", "hipsters", - "hispanicos", "hispanics", - "hispanicus", "hispanics", - "histarical", "historical", - "histerical", "historical", - "historiaan", "historians", - "historicas", "historians", - "historicly", "historical", - "historiens", "histories", - "historisch", "historic", - "hoemopathy", "homeopathy", - "hollywoood", "hollywood", - "homecuming", "homecoming", - "homeoapthy", "homeopathy", - "homeonwers", "homeowners", - "homeopahty", "homeopathy", - "homeophaty", "homeopathy", - "homeopothy", "homeopathy", - "homeothapy", "homeopathy", - "homepoathy", "homeopathy", - "homewoners", "homeowners", - "homoepathy", "homeopathy", - "homogeneos", "homogeneous", - "homogeneus", "homogeneous", - "homophibia", "homophobia", - "homophibic", "homophobic", - "homophobie", "homophobe", - "homophonia", "homophobia", - "homophopia", "homophobia", - "homophopic", "homophobic", - "homosexaul", "homosexual", - "homosexuel", "homosexual", - "honeymooon", "honeymoon", - "hopefullly", "hopefully", - "hopeleslly", "hopelessly", - "horisontal", "horizontal", - "horizantal", "horizontal", - "horizontes", "horizons", - "horiztonal", "horizontal", - "horrendeus", "horrendous", - "horriblely", "horribly", - "hospitales", "hospitals", - "hospitalty", "hospitality", - "hospitible", "hospitable", - "hsitorians", "historians", - "humanaties", "humanities", - "humanitary", "humanity", - "humiliatin", "humiliation", - "humiliaton", "humiliation", - "humilitied", "humiliated", - "humillated", "humiliated", - "hurricance", "hurricane", - "hurriganes", "hurricanes", - "hurrikanes", "hurricanes", - "hurrycanes", "hurricanes", - "hydropilic", "hydrophilic", - "hydropobic", "hydrophobic", - "hyperbolie", "hyperbole", - "hyperlobic", "hyperbolic", - "hyperlogic", "hyperbolic", - "hypertrohy", "hypertrophy", - "hypertropy", "hypertrophy", - "hyphotesis", "hypothesis", - "hypocrates", "hypocrites", - "hypocriscy", "hypocrisy", - "hypocrises", "hypocrites", - "hypocritus", "hypocrites", - "hypocrties", "hypocrites", - "hypocrytes", "hypocrites", - "hypokrites", "hypocrites", - "hypothecis", "hypothesis", - "hypotheiss", "hypotheses", - "hypothesus", "hypotheses", - "hypothises", "hypotheses", - "hypothisis", "hypothesis", - "hypothosis", "hypothesis", - "hyprocites", "hypocrites", - "hystarical", "hysterical", - "hystericly", "hysterical", - "hysteriska", "hysteria", - "ibuprofein", "ibuprofen", - "ibuprofine", "ibuprofen", - "icelandinc", "icelandic", - "idealisitc", "idealistic", - "idealogies", "ideologies", - "identicial", "identical", - "identifyed", "identified", - "identitets", "identities", - "ideolagies", "ideologies", - "ideoligies", "ideologies", - "ideologias", "ideologies", - "ideologice", "ideologies", - "ideologije", "ideologies", - "ideologins", "ideologies", - "ideologisk", "ideologies", - "ideolouges", "ideologies", - "illegalest", "illegals", - "illegallly", "illegally", - "illegimacy", "illegitimacy", - "illegitime", "illegitimate", - "illegitimt", "illegitimate", - "illimunati", "illuminati", - "illinoians", "illinois", - "illistrate", "illiterate", - "illitarate", "illiterate", - "illitirate", "illiterate", - "illumanati", "illuminati", - "illumaniti", "illuminati", - "illumianti", "illuminati", - "illumimati", "illuminati", - "illuminaci", "illuminati", - "illuminadi", "illuminati", - "illuminami", "illuminati", - "illuminazi", "illuminati", - "illuminite", "illuminati", - "illuminiti", "illuminati", - "illuminoti", "illuminati", - "illuminuti", "illuminati", - "illumniati", "illuminati", - "illumunati", "illuminati", - "illuninati", "illuminati", - "illusiones", "illusions", - "illustrant", "illustrate", - "illustrare", "illustrate", - "illustrato", "illustration", - "imablanced", "imbalanced", - "imablances", "imbalances", - "imaginatie", "imaginative", - "imaginaton", "imagination", - "imaginitve", "imaginative", - "imbalenced", "imbalanced", - "imbalences", "imbalances", - "imcomplete", "incomplete", - "imediately", "immediately", - "imigration", "emigration", - "immaturaty", "immaturity", - "immaturety", "immaturity", - "immedeatly", "immediately", - "immediatly", "immediately", - "immedietly", "immediately", - "immenseley", "immensely", - "immidately", "immediately", - "immigranti", "immigration", - "immigrents", "immigrants", - "immitating", "imitating", - "immobilien", "immobile", - "immobilier", "immobile", - "immobilzed", "immobile", - "immobilzer", "immobile", - "immobilzes", "immobile", - "immortales", "immortals", - "immortalis", "immortals", - "immortaliy", "immortality", - "immortalls", "immortals", - "immortalty", "immortality", - "impartirla", "impartial", - "impecabbly", "impeccably", - "impeccible", "impeccable", - "impeckable", "impeccable", - "impelments", "implements", - "imperetive", "imperative", - "imperialsm", "imperialism", - "imperialst", "imperialist", - "imperitave", "imperative", - "imperitive", "imperative", - "implaments", "implements", - "implantase", "implants", - "implausble", "implausible", - "implausibe", "implausible", - "implemenet", "implements", - "implicatia", "implicit", - "implicatie", "implicit", - "implicatii", "implicit", - "implicetly", "implicitly", - "impliciete", "implicit", - "implicilty", "implicitly", - "impliments", "implements", - "implmented", "implemented", - "imporbable", "improbable", - "importanly", "importantly", - "importanty", "importantly", - "importence", "importance", - "importerad", "imported", - "imporvised", "improvised", - "impossable", "impossible", - "impossbily", "impossibly", - "impossibal", "impossibly", - "impossibel", "impossibly", - "impossibry", "impossibly", - "impossibul", "impossibly", - "impractial", "impractical", - "impreative", "imperative", - "impresison", "impressions", - "impressoin", "impressions", - "impressons", "impressions", - "improbabil", "improbable", - "improbible", "improbable", - "impropable", "improbable", - "improsined", "imprisoned", - "improsoned", "imprisoned", - "improvemnt", "improvement", - "improvents", "improves", - "improvized", "improvised", - "imprsioned", "imprisoned", - "impulsemos", "impulses", - "imrpovised", "improvised", - "inablility", "inability", - "inaccruate", "inaccurate", - "inadaquate", "inadequate", - "inadaquete", "inadequate", - "inadecuate", "inadequate", - "inadeguate", "inadequate", - "inadeqaute", "inadequate", - "inadequete", "inadequate", - "inadequite", "inadequate", - "inadiquate", "inadequate", - "inagurated", "inaugurated", - "inbalanced", "imbalanced", - "inbetweeen", "between", - "incarnaton", "incarnation", - "incentivos", "incentives", - "inchoerent", "incoherent", - "incidentes", "incidents", - "incidently", "incidentally", - "incidentul", "incidental", - "inclreased", "increased", - "incognitio", "incognito", - "incoherant", "incoherent", - "incohorent", "incoherent", - "incorectly", "incorrectly", - "incorrecly", "incorrectly", - "incorrecty", "incorrectly", - "incorretly", "incorrectly", - "incraments", "increments", - "incredable", "incredible", - "incredably", "incredibly", - "incremetal", "incremental", - "incriments", "increments", - "inctroduce", "introduce", - "indefenite", "indefinite", - "indefinate", "indefinite", - "indefinete", "indefinite", - "indefinity", "indefinitely", - "indeginous", "indigenous", - "indentical", "identical", - "independet", "independent", - "indepenent", "independent", - "inderictly", "indirectly", - "indicaters", "indicates", - "indicativo", "indication", - "indicatore", "indicate", - "indicitave", "indicative", - "indicitive", "indicative", - "indiffernt", "indifferent", - "indigenius", "indigenous", - "indiginous", "indigenous", - "indigneous", "indigenous", - "indikation", "indication", - "indireclty", "indirectly", - "indirektly", "indirectly", - "individuel", "individual", - "indiviudal", "individuals", - "indivudual", "individual", - "indoensian", "indonesian", - "indonasian", "indonesian", - "indoneisan", "indonesian", - "indonesean", "indonesian", - "indonesien", "indonesian", - "indonesion", "indonesian", - "indonisian", "indonesian", - "indonistan", "indonesian", - "indpendent", "independent", - "industiral", "industrial", - "industires", "industries", - "industrail", "industrial", - "industrees", "industries", - "industrias", "industries", - "industriel", "industrial", - "industrija", "industrial", - "industrije", "industries", - "indviduals", "individuals", - "inefficent", "inefficient", - "ineqaulity", "inequality", - "inequailty", "inequality", - "inevatible", "inevitable", - "inevetable", "inevitable", - "inevetably", "inevitably", - "inevetible", "inevitable", - "inevidable", "inevitable", - "inevidably", "inevitably", - "inevitible", "inevitable", - "inevitibly", "inevitably", - "inevtiable", "inevitable", - "inevtiably", "inevitably", - "infallable", "infallible", - "infaltable", "inflatable", - "infeccious", "infectious", - "infecteous", "infectious", - "infectuous", "infectious", - "infedility", "infidelity", - "infektious", "infectious", - "inferioara", "inferior", - "inferioare", "inferior", - "inferiorty", "inferiority", - "inferrence", "inference", - "infestaion", "infestation", - "infestaton", "infestation", - "infestions", "infections", - "infideltiy", "infidelity", - "infidility", "infidelity", - "infiltrade", "infiltrate", - "infiltrait", "infiltrate", - "infiltrare", "infiltrate", - "infiltrase", "infiltrate", - "infinately", "infinitely", - "infinetely", "infinitely", - "infiniment", "infinite", - "infinitley", "infinitely", - "infintiely", "infinitely", - "inflamable", "inflatable", - "inflateble", "inflatable", - "inflatible", "inflatable", - "infleunced", "influenced", - "inflitrate", "infiltrate", - "influanced", "influenced", - "influances", "influences", - "influencie", "influences", - "influening", "influencing", - "influensed", "influences", - "influenser", "influences", - "influenses", "influences", - "influental", "influential", - "influented", "influenced", - "influentes", "influences", - "influneced", "influenced", - "infograhic", "infographic", - "infograpic", "infographic", - "infomation", "information", - "informable", "informal", - "informarla", "informal", - "informarle", "informal", - "informarlo", "informal", - "informatie", "informative", - "informella", "informal", - "informerad", "informed", - "informtion", "information", - "infridging", "infringing", - "infrigning", "infringing", - "infulenced", "influenced", - "infulences", "influences", - "ingenuitiy", "ingenuity", - "ingrediant", "ingredient", - "ingrediens", "ingredients", - "ingrediets", "ingredient", - "inhabitans", "inhabitants", - "inhabitats", "inhabitants", - "inherantly", "inherently", - "inherintly", "inherently", - "inheritage", "heritage", - "inhernetly", "inherently", - "inifnitely", "infinitely", - "initaition", "initiation", - "initalised", "initialised", - "initaliser", "initialiser", - "initalises", "initialises", - "initalisms", "initialisms", - "initalized", "initialized", - "initalizer", "initializer", - "initalizes", "initializes", - "initalling", "initialling", - "initalness", "initialness", - "initiaitve", "initiatives", - "initiaties", "initiatives", - "initiativs", "initiatives", - "initiatves", "initiatives", - "initiavite", "initiatives", - "inititaive", "initiatives", - "inititiave", "initiatives", - "initmately", "intimately", - "initmidate", "intimidate", - "inituition", "initiation", - "injustaces", "injustices", - "injusticas", "injustices", - "inmigrants", "immigrants", - "innoavtion", "innovations", - "innocentes", "innocents", - "innotation", "innovation", - "innovacion", "innovation", - "innovaiton", "innovations", - "innovatief", "innovate", - "innovaties", "innovate", - "innovativo", "innovation", - "innvoation", "innovation", - "inofficial", "unofficial", - "inpsection", "inspection", - "inquisator", "inquisitor", - "inquisidor", "inquisitor", - "inquisiter", "inquisitor", - "inquisitio", "inquisitor", - "inquisitir", "inquisitor", - "inquisiton", "inquisition", - "inquistior", "inquisitor", - "inquizitor", "inquisitor", - "inqusitior", "inquisitor", - "insensitve", "insensitive", - "insepction", "inspection", - "insistance", "insistence", - "insistente", "insistence", - "insistenze", "insistence", - "insistince", "insistence", - "insitution", "institution", - "inspeccion", "inspection", - "inspeciton", "inspections", - "inspectons", "inspections", - "inspectres", "inspectors", - "inspektion", "inspection", - "inspektors", "inspectors", - "inspiraste", "inspires", - "inspiraton", "inspiration", - "inspirerad", "inspired", - "inspireras", "inspires", - "insrugency", "insurgency", - "instabiliy", "instability", - "instabilty", "instability", - "installeer", "installer", - "installent", "installment", - "installesd", "installs", - "installion", "installing", - "instatance", "instance", - "instelling", "installing", - "instituded", "instituted", - "instituion", "institution", - "institutie", "institute", - "institutue", "instituted", - "instrament", "instrument", - "instrcutor", "instructors", - "instrucion", "instruction", - "instructer", "instructor", - "instructie", "instructed", - "instruktor", "instructor", - "instuction", "instruction", - "instuments", "instruments", - "insturcted", "instructed", - "insturctor", "instructor", - "insturment", "instrument", - "instutions", "intuitions", - "instututed", "instituted", - "insurgance", "insurgency", - "insurgancy", "insurgency", - "intangable", "intangible", - "intangeble", "intangible", - "intangibil", "intangible", - "intanjible", "intangible", - "integraded", "integrated", - "integrarla", "integral", - "integrarlo", "integral", - "integratie", "integrated", - "integreres", "interferes", - "integreted", "integrated", - "inteligent", "intelligent", - "intenseley", "intensely", - "intensitiy", "intensity", - "intentinal", "intentional", - "intentines", "intestines", - "interacive", "interactive", - "interactes", "interacts", - "interactie", "interactive", - "interactue", "interacted", - "interasted", "interacted", - "interbread", "interbreed", - "intercepto", "interception", - "intercorse", "intercourse", - "intercouse", "intercourse", - "intereacts", "interfaces", - "interected", "interacted", - "interefers", "interferes", - "interesant", "interest", - "interesing", "interesting", - "interestes", "interests", - "interfacce", "interfaces", - "interfears", "interferes", - "interfeers", "interferes", - "interferce", "interferes", - "interferre", "interfere", - "intergated", "integrated", - "interioara", "interior", - "interioare", "interior", - "intermedie", "intermediate", - "internetbs", "internets", - "internetes", "internets", - "internetis", "internets", - "internetts", "internets", - "internetus", "internets", - "interprate", "interpret", - "interrugum", "interregnum", - "interruped", "interrupted", - "interstela", "interstellar", - "intervalls", "intervals", - "intervalos", "intervals", - "interveign", "intervening", - "interveing", "intervening", - "interveiws", "interviews", - "intervento", "intervention", - "intervenue", "intervene", - "interveres", "interferes", - "intervieni", "interviewing", - "intervieuw", "interviews", - "interviewd", "interviewed", - "interviewr", "interviewer", - "intervines", "intervenes", - "interviwed", "interviewed", - "interviwer", "interviewer", - "interwebbs", "interwebs", - "intestents", "intestines", - "intestinas", "intestines", - "intestinos", "intestines", - "intestions", "intestines", - "intidimate", "intimidate", - "intimadate", "intimidate", - "intimatley", "intimately", - "intimiated", "intimidate", - "intimidade", "intimidated", - "intimidant", "intimidate", - "intimidare", "intimidate", - "intimitade", "intimidated", - "intimitaly", "intimately", - "intimitate", "intimidate", - "intimitely", "intimately", - "intolarant", "intolerant", - "intolerace", "intolerance", - "intolerate", "intolerant", - "intolerent", "intolerant", - "intolorant", "intolerant", - "intolorent", "intolerant", - "intorduced", "introduced", - "intorduces", "introduces", - "intorverts", "introverts", - "intoxicted", "intoxicated", - "intraverts", "introverts", - "intreguing", "intriguing", - "intricaces", "intricacies", - "intriguied", "intrigue", - "intrigured", "intrigue", - "intrinseci", "intrinsic", - "intrinsinc", "intrinsic", - "intriquing", "intriguing", - "intriuging", "intriguing", - "introdecks", "introduces", - "introdused", "introduces", - "introvents", "introverts", - "introvered", "introverted", - "introversa", "introverts", - "introverse", "introverts", - "introversi", "introverts", - "introverso", "introverts", - "introversy", "introverts", - "introveted", "introverted", - "intruduced", "introduced", - "intruduces", "introduces", - "intruiging", "intriguing", - "intruments", "instruments", - "intuitevly", "intuitively", - "intuitivly", "intuitively", - "intuitivno", "intuition", - "intutively", "intuitively", - "inumerable", "enumerable", - "inusrgency", "insurgency", - "invaderats", "invaders", - "invaildate", "invalidates", - "invairably", "invariably", - "invaldiate", "invalidates", - "invalidade", "invalidate", - "invalidare", "invalidate", - "invalubale", "invaluable", - "invalueble", "invaluable", - "invaraibly", "invariably", - "invariabil", "invariably", - "invaribaly", "invariably", - "invaulable", "invaluable", - "inveitable", "inevitable", - "inveitably", "inevitably", - "invensions", "inventions", - "inventario", "inventor", - "inventarlo", "inventor", - "inventaron", "inventor", - "inventings", "inventions", - "inventivos", "inventions", - "invertendo", "inverted", - "inverterad", "inverted", - "invertions", "inventions", - "investemnt", "investments", - "investiage", "investigate", - "investions", "inventions", - "investirat", "investigator", - "investmens", "investments", - "invicinble", "invincible", - "invididual", "individual", - "invincable", "invincible", - "invinceble", "invincible", - "invinicble", "invincible", - "invinsible", "invincible", - "invinvible", "invincible", - "invisibily", "invisibility", - "invitacion", "invitation", - "invitating", "invitation", - "involunary", "involuntary", - "involvment", "involvement", - "ironcially", "ironically", - "irracional", "irrational", - "irrationel", "irrational", - "irrelavant", "irrelevant", - "irrelavent", "irrelevant", - "irrelevent", "irrelevant", - "irrelivant", "irrelevant", - "irrelivent", "irrelevant", - "irrevelant", "irrelevant", - "irreverant", "irrelevant", - "irridation", "irritation", - "irriration", "irritation", - "irritacion", "irritation", - "irritaties", "irritate", - "islamisist", "islamist", - "islamistas", "islamists", - "isntalling", "installing", - "isntructed", "instructed", - "isntrument", "instrument", - "israeliens", "israelis", - "israelitas", "israelis", - "italianess", "italians", - "itnroduced", "introduced", - "jailborken", "jailbroken", - "jalibroken", "jailbroken", - "jamaicains", "jamaican", - "jamaicaman", "jamaican", - "jerusaleum", "jerusalem", - "jounralism", "journalism", - "jounralist", "journalist", - "jouranlism", "journalism", - "jouranlist", "journalist", - "journalims", "journals", - "journalits", "journals", - "journalizm", "journalism", - "journalsim", "journalism", - "journolist", "journalist", - "judegments", "judgements", - "judgemenal", "judgemental", - "judgemetal", "judgemental", - "jugdements", "judgements", - "juggarnaut", "juggernaut", - "juggeranut", "juggernaut", - "juggernath", "juggernaut", - "juggernout", "juggernaut", - "juggernuat", "juggernaut", - "juggetnaut", "juggernaut", - "jugglenaut", "juggernaut", - "juggurnaut", "juggernaut", - "justifible", "justifiable", - "juvenilles", "juvenile", - "kickstarer", "kickstarter", - "kickstartr", "kickstarter", - "kickstater", "kickstarter", - "kidnapning", "kidnapping", - "kidnappade", "kidnapped", - "killingest", "killings", - "kilometros", "kilometers", - "kilomiters", "kilometers", - "kilomoters", "kilometers", - "kilomteres", "kilometers", - "kindapping", "kidnapping", - "kingdomers", "kingdoms", - "krpytonite", "kryptonite", - "krypotnite", "kryptonite", - "krypronite", "kryptonite", - "kryptinite", "kryptonite", - "kryptolite", "kryptonite", - "kryptonyte", "kryptonite", - "krypyonite", "kryptonite", - "krytponite", "kryptonite", - "kyrptonite", "kryptonite", - "labarotory", "laboratory", - "laboratroy", "laboratory", - "laborerers", "laborers", - "laboritory", "laboratory", - "laborotory", "laboratory", - "lackbuster", "lackluster", - "lacklaster", "lackluster", - "landacapes", "landscapes", - "landingers", "landings", - "landshapes", "landscapes", - "landspaces", "landscapes", - "lannasters", "lannisters", - "lannesters", "lannisters", - "lannistars", "lannisters", - "lannsiters", "lannisters", - "lateration", "alteration", - "latitudine", "latitude", - "laughabley", "laughably", - "laughablly", "laughably", - "launchered", "launched", - "leaglizing", "legalizing", - "lectureres", "lectures", - "legalazing", "legalizing", - "legalizare", "legalize", - "legalizate", "legalize", - "legendaies", "legendaries", - "legendaris", "legendaries", - "legimitacy", "legitimacy", - "legimitate", "legitimate", - "legislatie", "legislative", - "legitamacy", "legitimacy", - "legitamate", "legitimate", - "legitamicy", "legitimacy", - "legitamite", "legitimate", - "legitemacy", "legitimacy", - "legitemate", "legitimate", - "legitimaly", "legitimacy", - "legitimicy", "legitimacy", - "legitimite", "legitimate", - "leiutenant", "lieutenant", - "lesbianese", "lesbians", - "lesbianest", "lesbians", - "leuitenant", "lieutenant", - "levetating", "levitating", - "liberacion", "liberation", - "liberalest", "liberate", - "liberalizm", "liberalism", - "liberalnim", "liberalism", - "liberalsim", "liberalism", - "liberarion", "liberation", - "liberaties", "liberate", - "liberatore", "liberate", - "libertania", "libertarians", - "libguistic", "linguistic", - "lietuenant", "lieutenant", - "lieutanant", "lieutenant", - "lieutanent", "lieutenant", - "lieutenent", "lieutenant", - "lifestiles", "lifestyles", - "lifestlyes", "lifestyles", - "lifesystem", "filesystem", - "lifesytles", "lifestyles", - "lifetimers", "lifetimes", - "lifetsyles", "lifestyles", - "lighhtning", "lightening", - "lightergas", "lighters", - "lighthning", "lightening", - "lighthorse", "lighthouse", - "lighthosue", "lighthouse", - "lighthours", "lighthouse", - "lightining", "lighting", - "lightneing", "lightening", - "lightnting", "lightening", - "lightrooom", "lightroom", - "lightweigt", "lightweight", - "ligitation", "litigation", - "ligthening", "lightening", - "ligthhouse", "lighthouse", - "likelyhood", "likelihood", - "limination", "limitation", - "limitacion", "limitation", - "limitaiton", "limitation", - "limitating", "limitation", - "limitativo", "limitation", - "linguisics", "linguistics", - "linguisitc", "linguistics", - "linguistcs", "linguistics", - "linguistis", "linguistics", - "linguitics", "linguistic", - "lingusitic", "linguistics", - "lingvistic", "linguistic", - "liousville", "louisville", - "listeneres", "listeners", - "literallly", "literally", - "literarely", "literary", - "literarlly", "literary", - "literatire", "literate", - "literative", "literate", - "literatute", "literate", - "lithuanina", "lithuania", - "litterally", "literally", - "liuetenant", "lieutenant", - "liveatream", "livestream", - "livelehood", "livelihood", - "liverpoool", "liverpool", - "livescream", "livestream", - "livestreem", "livestream", - "livestrems", "livestream", - "livilehood", "livelihood", - "livliehood", "livelihood", - "lobbyistes", "lobbyists", - "lockacreen", "lockscreen", - "logictical", "logistical", - "logisitcal", "logistical", - "logisticas", "logistics", - "logisticly", "logistical", - "loiusville", "louisville", - "lollipoopy", "lollipop", - "lonelyness", "loneliness", - "longevitiy", "longevity", - "lonileness", "loneliness", - "lonlieness", "loneliness", - "louieville", "louisville", - "louisiania", "louisiana", - "louisianna", "louisiana", - "louisivlle", "louisville", - "louisviile", "louisville", - "lousiville", "louisville", - "luietenant", "lieutenant", - "mabyelline", "maybelline", - "magnifient", "magnificent", - "mainpulate", "manipulate", - "mainstreem", "mainstream", - "maintaince", "maintained", - "maintaines", "maintains", - "maintainig", "maintaining", - "maintenace", "maintenance", - "maintianed", "maintained", - "maintioned", "mentioned", - "malfuncion", "malfunction", - "malpractce", "malpractice", - "managebale", "manageable", - "maneagable", "manageable", - "maneouvred", "manoeuvred", - "maneouvres", "manoeuvres", - "maneuveres", "maneuvers", - "maneuveurs", "maneuver", - "manifestas", "manifests", - "manifestes", "manifests", - "manifestus", "manifests", - "manipluate", "manipulate", - "manipualte", "manipulate", - "manipulant", "manipulate", - "manipulare", "manipulate", - "manipulted", "manipulated", - "maniuplate", "manipulate", - "mannarisms", "mannerisms", - "mannersims", "mannerisms", - "mannorisms", "mannerisms", - "manufacter", "manufacture", - "manufacure", "manufacture", - "manufature", "manufacture", - "maraudeurs", "marauder", - "margaritte", "margaret", - "margianlly", "marginally", - "marginaali", "marginal", - "marginable", "marginal", - "marignally", "marginally", - "marijuanna", "marijuana", - "marketting", "marketing", - "marshmalow", "marshmallow", - "masculinty", "masculinity", - "massacrare", "massacre", - "massivelly", "massively", - "masteriers", "masteries", - "masternind", "mastermind", - "masterpice", "masterpiece", - "mastrubate", "masturbate", - "mastubrate", "masturbated", - "masturabte", "masturbate", - "masturbait", "masturbate", - "masturbare", "masturbate", - "masturbeta", "masturbated", - "masturdate", "masturbate", - "materiales", "materials", - "materialsm", "materialism", - "maximazing", "maximizing", - "maximixing", "maximizing", - "mayballine", "maybelline", - "maybellene", "maybelline", - "maybellibe", "maybelline", - "maybilline", "maybelline", - "mccarthyst", "mccarthyist", - "mdifielder", "midfielder", - "meagthread", "megathread", - "meaningess", "meanings", - "meaningles", "meanings", - "meatballls", "meatballs", - "mecahnical", "mechanical", - "mecahnisms", "mechanisms", - "mechancial", "mechanical", - "mechandise", "merchandise", - "mechanichs", "mechanics", - "mechanicle", "mechanical", - "mechanicly", "mechanical", - "mechanicus", "mechanics", - "mechanincs", "mechanic", - "mechanisim", "mechanism", - "mechansims", "mechanisms", - "mechinical", "mechanical", - "mechinisms", "mechanisms", - "mediaction", "medications", - "medicacion", "medication", - "medicaiton", "medication", - "medicalert", "medicare", - "medicallly", "medically", - "medicatons", "medications", - "medicinens", "medicines", - "medicinske", "medicine", - "medicority", "mediocrity", - "medidating", "meditating", - "mediocirty", "mediocrity", - "mediocraty", "mediocrity", - "mediocrety", "mediocrity", - "mediocricy", "mediocrity", - "mediocrily", "mediocrity", - "mediocrisy", "mediocrity", - "meditacion", "medications", - "meditaiton", "meditation", - "melatonian", "melatonin", - "melatonion", "melatonin", - "mellinnium", "millennium", - "melodieuse", "melodies", - "membrances", "membrane", - "mentallity", "mentally", - "mentionnes", "mentions", - "mercenaire", "mercenaries", - "mercenares", "mercenaries", - "mercentile", "mercantile", - "merchanise", "merchandise", - "merchantos", "merchants", - "messagease", "messages", - "messagepad", "messaged", - "messenging", "messaging", - "metabalism", "metabolism", - "metabilism", "metabolism", - "metabloism", "metabolism", - "metablosim", "metabolism", - "metabolics", "metabolism", - "metabolizm", "metabolism", - "metabolsim", "metabolism", - "metalurgic", "metallurgic", - "metaphoras", "metaphors", - "metaphores", "metaphors", - "metaphyics", "metaphysics", - "meterology", "meteorology", - "methaphors", "metaphors", - "methodolgy", "methodology", - "methodoloy", "methodology", - "metrapolis", "metropolis", - "metrolopis", "metropolis", - "metropilis", "metropolis", - "metroplois", "metropolis", - "metropolin", "metropolitan", - "metropolos", "metropolis", - "metropolys", "metropolis", - "mexicanese", "mexicans", - "mexicaness", "mexicans", - "michelline", "michelle", - "micorwaves", "microwaves", - "microhpone", "microphone", - "microscoop", "microscope", - "microvaves", "microwaves", - "microvaxes", "microwaves", - "micrpohone", "microphones", - "midfeilder", "midfielder", - "midfiedler", "midfielder", - "midfieldes", "midfielders", - "midfielers", "midfielders", - "midfileder", "midfielder", - "midifelder", "midfielder", - "midnlessly", "mindlessly", - "migitation", "mitigation", - "migrainers", "migraines", - "miletsones", "milestones", - "milisecond", "millisecond", - "militiades", "militias", - "militiants", "militias", - "millinnium", "millennium", - "miminalist", "minimalist", - "minamilist", "minimalist", - "mindleslly", "mindlessly", - "minimazing", "minimizing", - "minimilast", "minimalist", - "minimilist", "minimalist", - "mininalist", "minimalist", - "ministeres", "ministers", - "ministerns", "ministers", - "minneaplis", "minneapolis", - "minneapols", "minneapolis", - "minnesotta", "minnesota", - "minoritets", "minorities", - "minoroties", "minorities", - "miracalous", "miraculous", - "miracluous", "miraculous", - "miracoulus", "miraculous", - "mircophone", "microphone", - "mircoscope", "microscope", - "mircowaves", "microwaves", - "misandrony", "misandry", - "miscarrage", "miscarriage", - "miscarrige", "miscarriage", - "misdemenor", "misdemeanor", - "miserabley", "miserably", - "miserablly", "miserably", - "misforture", "misfortune", - "misgoynist", "misogynist", - "misinfomed", "misinformed", - "misinterpt", "misinterpret", - "misisonary", "missionary", - "misoganist", "misogynist", - "misogenist", "misogynist", - "misoginist", "misogynist", - "misoginyst", "misogynist", - "misognyist", "misogynist", - "misogonist", "misogynist", - "misogonyst", "misogynist", - "misogyinst", "misogynist", - "misogynyst", "misogynist", - "misoygnist", "misogynist", - "mispelling", "misspelling", - "missionare", "missionaries", - "missionera", "missionary", - "missisippi", "mississippi", - "mississipi", "mississippi", - "mississppi", "mississippi", - "misspeling", "misspelling", - "misspellng", "misspelling", - "mistakedly", "mistakenly", - "mistakinly", "mistakenly", - "mistankely", "mistakenly", - "misterious", "mysterious", - "misteryous", "mysterious", - "mistreaded", "mistreated", - "misygonist", "misogynist", - "mitigaiton", "mitigation", - "moderacion", "moderation", - "moderaters", "moderates", - "moderatley", "moderately", - "moderatore", "moderate", - "moderatorn", "moderation", - "modificato", "modification", - "modifieras", "modifiers", - "modifieres", "modifiers", - "moisturier", "moisturizer", - "moleculair", "molecular", - "molestaion", "molestation", - "molestarle", "molester", - "molestarme", "molester", - "molestarse", "molester", - "molestarte", "molester", - "molestered", "molested", - "momentarly", "momentarily", - "monagomous", "monogamous", - "monetizare", "monetize", - "monitering", "monitoring", - "monogymous", "monogamous", - "monolistic", "monolithic", - "monolitich", "monolithic", - "monolopies", "monopolies", - "monolothic", "monolithic", - "monolythic", "monolithic", - "monopilies", "monopolies", - "monoploies", "monopolies", - "monopolets", "monopolies", - "monopolice", "monopolies", - "monopolios", "monopolies", - "monothilic", "monolithic", - "monsterous", "monsters", - "montioring", "monitoring", - "monumentos", "monuments", - "monumentul", "monumental", - "monumentus", "monuments", - "mormonisim", "mormonism", - "morphinate", "morphine", - "morrisette", "morissette", - "morrisound", "morrison", - "mosquitero", "mosquito", - "mosquiters", "mosquitoes", - "motherbard", "motherboard", - "motherboad", "motherboard", - "motherbord", "motherboard", - "motivaiton", "motivations", - "motiviated", "motivated", - "motorcicle", "motorcycle", - "motorcylce", "motorcycle", - "motorcyles", "motorcycles", - "motorollas", "motorola", - "mouthpeace", "mouthpiece", - "mouthpeice", "mouthpiece", - "movespeeed", "movespeed", - "mozzaralla", "mozzarella", - "mozzeralla", "mozzarella", - "mozzorella", "mozzarella", - "mulitation", "mutilation", - "mulitplied", "multiplied", - "mulitplier", "multiplier", - "mulitverse", "multiverse", - "multilpier", "multiplier", - "multiplaer", "multiplier", - "multiplaye", "multiply", - "multiplayr", "multiply", - "multiplays", "multiply", - "multipleye", "multiply", - "multipling", "multiplying", - "multiplyed", "multiplied", - "multiplyer", "multiple", - "multiplyng", "multiplying", - "murderered", "murdered", - "murdereres", "murderers", - "muscicians", "musicians", - "musculaire", "muscular", - "mushroooms", "mushroom", - "mutialtion", "mutilation", - "mutiliated", "mutilated", - "mutliation", "mutilation", - "mutliplied", "multiplied", - "mutliplier", "multiplier", - "mutliverse", "multiverse", - "mysogynist", "misogynist", - "mysterieus", "mysteries", - "nagivating", "navigating", - "nagivation", "navigation", - "narcassism", "narcissism", - "narcassist", "narcissist", - "narcessist", "narcissist", - "narciscism", "narcissism", - "narciscist", "narcissist", - "narcisissm", "narcissism", - "narcisisst", "narcissist", - "narcisists", "narcissist", - "narcissicm", "narcissism", - "narcissict", "narcissist", - "narcissitc", "narcissist", - "narcissits", "narcissist", - "narcoticos", "narcotics", - "narrativas", "narratives", - "narrativos", "narratives", - "narritives", "narratives", - "nashvillle", "nashville", - "nationales", "nationals", - "nationalis", "nationals", - "nationalit", "nationalist", - "nationaliy", "nationality", - "nationalty", "nationality", - "nationella", "national", - "naturually", "naturally", - "naviagting", "navigating", - "naviagtion", "navigation", - "navigatore", "navigate", - "neccessary", "necessary", - "necesarily", "necessarily", - "necessairy", "necessarily", - "necessarly", "necessary", - "necessarry", "necessary", - "necessiate", "necessitate", - "necessites", "necessities", - "neckbeared", "neckbeard", - "neckboards", "neckbeards", - "neckbreads", "neckbeards", - "neckneards", "neckbeards", - "necromacer", "necromancer", - "necromaner", "necromancer", - "needleslly", "needlessly", - "negativaty", "negativity", - "negativley", "negatively", - "negelcting", "neglecting", - "negilgence", "negligence", - "negiotated", "negotiated", - "neglacting", "neglecting", - "neglagence", "negligence", - "neglegance", "negligence", - "neglegible", "negligible", - "neglegting", "neglecting", - "neglibible", "negligible", - "neglicence", "negligence", - "neglicible", "negligible", - "neglicting", "neglecting", - "negligable", "negligible", - "negligance", "negligence", - "negligeble", "negligible", - "negligente", "negligence", - "negociated", "negotiated", - "negogiated", "negotiated", - "negoitated", "negotiated", - "negotaited", "negotiated", - "negotation", "negotiation", - "negotiaion", "negotiation", - "negotiatie", "negotiated", - "negotiatin", "negotiations", - "negotiaton", "negotiation", - "neigbhours", "neighbours", - "neighbhors", "neighbours", - "neighbords", "neighbours", - "neighbores", "neighbours", - "netowrking", "networking", - "netruality", "neutrality", - "neturality", "neutrality", - "netwroking", "networking", - "neurologia", "neurological", - "neutrailty", "neutrality", - "newletters", "newsletters", - "newlsetter", "newsletter", - "newsettler", "newsletter", - "newslatter", "newsletter", - "nieghbours", "neighbours", - "nightmates", "nightmares", - "nightmears", "nightmares", - "nightmeres", "nightmares", - "nigthmares", "nightmares", - "nipticking", "nitpicking", - "nitpciking", "nitpicking", - "nominacion", "nomination", - "nominatino", "nominations", - "nominativo", "nomination", - "nominatons", "nominations", - "nonsencial", "nonsensical", - "nontheless", "nonetheless", - "northerend", "northern", - "nostalgica", "nostalgia", - "nostalgija", "nostalgia", - "noteworhty", "noteworthy", - "nothingess", "nothingness", - "noticabely", "noticeably", - "noticabley", "noticeably", - "noticiably", "noticeably", - "notoriosly", "notoriously", - "novembeard", "november", - "nuetrality", "neutrality", - "nutricious", "nutritious", - "nutrientes", "nutrients", - "nutritents", "nutrients", - "nutritinal", "nutritional", - "nutritiuos", "nutritious", - "nutritivos", "nutritious", - "nutrituous", "nutritious", - "nutrutious", "nutritious", - "obatinable", "obtainable", - "obejctives", "objectives", - "obilgatory", "obligatory", - "objecitves", "objectives", - "objectivas", "objectives", - "objectivly", "objectively", - "objectivst", "objectives", - "objectivty", "objectivity", - "objektives", "objectives", - "obligitary", "obligatory", - "obligitory", "obligatory", - "observabil", "observable", - "observarse", "observers", - "observaton", "observation", - "observeras", "observers", - "observered", "observed", - "observeres", "observers", - "observible", "observable", - "obstancles", "obstacles", - "obstrucion", "obstruction", - "obstructin", "obstruction", - "obtainabie", "obtainable", - "obtaineble", "obtainable", - "obtainible", "obtainable", - "obtianable", "obtainable", - "ocasionaly", "occasionally", - "ocassional", "occasional", - "ocassioned", "occasioned", - "occaisonal", "occasional", - "occasionly", "occasional", - "occassions", "occasions", - "occational", "occasional", - "occulation", "occupation", - "occupaiton", "occupation", - "occurances", "occurrences", - "occurences", "occurrences", - "occurrance", "occurrence", - "octohedral", "octahedral", - "octohedron", "octahedron", - "offensivly", "offensively", - "offereings", "offerings", - "officailly", "officially", - "olbigatory", "obligatory", - "ominpotent", "omnipotent", - "ominscient", "omniscient", - "omnipetent", "omnipotent", - "omnipitent", "omnipotent", - "omnipotant", "omnipotent", - "omnisicent", "omniscient", - "omniverous", "omnivorous", - "omnsicient", "omniscient", - "on-premise", "on-premises", - "onmipotent", "omnipotent", - "onmiscient", "omniscient", - "operatings", "operations", - "operativne", "operative", - "operativos", "operations", - "oportunity", "opportunity", - "opponenets", "opponent", - "oppononent", "opponent", - "oppressiun", "oppressing", - "optimisitc", "optimistic", - "optimizare", "optimize", - "optimizate", "optimize", - "optimizied", "optimize", - "organicaly", "organically", - "organiclly", "organically", - "organisate", "organise", - "organische", "organise", - "organisera", "organizers", - "organisere", "organizers", - "organisert", "organizers", - "organisier", "organise", - "organisims", "organism", - "organismed", "organise", - "organismen", "organise", - "organismer", "organise", - "organismes", "organisms", - "organismus", "organisms", - "organisten", "organise", - "organiszed", "organise", - "organizaed", "organize", - "organizare", "organizer", - "organizate", "organize", - "organizors", "organizers", - "organizuje", "organize", - "organziers", "organizers", - "orientaion", "orientation", - "orientarla", "oriental", - "orientarlo", "oriental", - "origianlly", "originally", - "originales", "originals", - "originalet", "originated", - "originalis", "originals", - "originalty", "originality", - "orignially", "originally", - "origniated", "originated", - "origonally", "originally", - "origonated", "originated", - "ostencibly", "ostensibly", - "ostenisbly", "ostensibly", - "ostensably", "ostensibly", - "ostentibly", "ostensibly", - "ostrasiced", "ostracized", - "ostrasized", "ostracized", - "ostraziced", "ostracized", - "ostrazised", "ostracized", - "ostrecized", "ostracized", - "ostricized", "ostracized", - "ostrocized", "ostracized", - "oustanding", "outstanding", - "outcalssed", "outclassed", - "outlcassed", "outclassed", - "outnumberd", "outnumbered", - "outnumbred", "outnumbered", - "outperfoms", "outperform", - "outperfrom", "outperform", - "outpreform", "outperform", - "outrageuos", "outrageous", - "outragious", "outrageous", - "outragoues", "outrageous", - "outreagous", "outrageous", - "outsourcad", "outsourced", - "outsouring", "outsourcing", - "outsoursed", "outsourced", - "outweighes", "outweighs", - "overarcing", "overarching", - "overclockd", "overclocked", - "overcloked", "overclocked", - "overcoding", "overcoming", - "overheards", "overhead", - "overheared", "overhead", - "overhooked", "overlooked", - "overlanded", "overloaded", - "overlaoded", "overloaded", - "overlaping", "overlapping", - "overlauded", "overloaded", - "overloards", "overload", - "overlorded", "overloaded", - "overlordes", "overlords", - "overnurfed", "overturned", - "overpirced", "overpriced", - "overpowerd", "overpowered", - "overpowred", "overpowered", - "overprised", "overpriced", - "overtunned", "overturned", - "overtunred", "overturned", - "overturing", "overturn", - "overweigth", "overweight", - "overwhemed", "overwhelmed", - "overwieght", "overweight", - "overwritte", "overwrite", - "pahtfinder", "pathfinder", - "painfullly", "painfully", - "painkilers", "painkillers", - "pairlament", "parliament", - "pakistanti", "pakistani", - "paladinlst", "paladins", - "palcements", "placements", - "paleolitic", "paleolithic", - "palestinan", "palestinian", - "paltformer", "platformer", - "palyerbase", "playerbase", - "parachutte", "parachute", - "parademics", "paramedics", - "paradiggum", "paradigm", - "paragraghs", "paragraphs", - "paragrahps", "paragraphs", - "paragrapgh", "paragraphs", - "paragrpahs", "paragraphs", - "parahprase", "paraphrase", - "paralleles", "parallels", - "parallells", "parallels", - "paramadics", "paramedics", - "paramaters", "parameters", - "paramecias", "paramedics", - "parametics", "paramedics", - "parametros", "parameters", - "paramiters", "parameters", - "paramormal", "paranormal", - "paranoicas", "paranoia", - "paranomral", "paranormal", - "paranornal", "paranormal", - "parapharse", "paraphrase", - "paraphraze", "paraphrase", - "paraprhase", "paraphrase", - "parasitter", "parasite", - "parilament", "parliament", - "parituclar", "particular", - "parlaiment", "parliament", - "parliamant", "parliament", - "parliamone", "parliament", - "parliement", "parliament", - "parrallell", "parallel", - "parrallely", "parallelly", - "partiarchy", "patriarchy", - "participas", "participants", - "participat", "participants", - "participte", "participate", - "particualr", "particular", - "partiotism", "patriotism", - "passionais", "passions", - "passionale", "passionately", - "passionant", "passionate", - "passionite", "passionate", - "passivedns", "passives", - "passivelly", "passively", - "patenterad", "patented", - "pathfidner", "pathfinder", - "pathfindir", "pathfinder", - "pathifnder", "pathfinder", - "patientens", "patients", - "patrairchy", "patriarchy", - "patriachry", "patriarchy", - "patriarcal", "patriarchal", - "patriarhal", "patriarchal", - "patriatchy", "patriarchy", - "patriatism", "patriotism", - "patrionism", "patriotism", - "patriotics", "patriotism", - "patriotisk", "patriots", - "patroitism", "patriotism", - "patryarchy", "patriarchy", - "pedantisch", "pedantic", - "pedestiran", "pedestrian", - "pedestrain", "pedestrian", - "pedictions", "depictions", - "pedohpiles", "pedophiles", - "pedohpilia", "pedophilia", - "pedophilac", "pedophilia", - "pedophilea", "pedophilia", - "pedophilie", "pedophile", - "pedophilla", "pedophilia", - "pedophille", "pedophile", - "pedopholia", "pedophilia", - "penetraion", "penetration", - "penetratin", "penetration", - "penetraton", "penetration", - "penguinese", "penguins", - "penguiness", "penguins", - "peninsulla", "peninsula", - "penninsula", "peninsula", - "peodphiles", "pedophiles", - "peodphilia", "pedophilia", - "pepperment", "peppermint", - "pepperonni", "pepperoni", - "percantage", "percentage", - "percantile", "percentile", - "percaution", "precaution", - "percenatge", "percentages", - "percential", "percentile", - "percentige", "percentile", - "perceptoin", "perceptions", - "percession", "percussion", - "percetange", "percentages", - "percetnage", "percentages", - "percintile", "percentile", - "percission", "percussion", - "percpetion", "perceptions", - "percusions", "percussion", - "perdicting", "predicting", - "perdiction", "prediction", - "perdictive", "predictive", - "perenially", "perennially", - "perfeccion", "perfection", - "perfecxion", "perfection", - "perfektion", "perfection", - "perferable", "preferable", - "perferably", "preferably", - "perference", "preference", - "perferring", "preferring", - "perfexcion", "perfection", - "perfomance", "performance", - "performace", "performance", - "performane", "performances", - "performans", "performances", - "performens", "performers", - "performous", "performs", - "perfromers", "performers", - "perhiperal", "peripheral", - "peridinkle", "periwinkle", - "perihperal", "peripheral", - "periodisch", "periodic", - "periperhal", "peripheral", - "peripheals", "peripherals", - "peripheria", "peripheral", - "periphiral", "peripheral", - "periphreal", "peripheral", - "periphrial", "peripheral", - "peritinkle", "periwinkle", - "periwankle", "periwinkle", - "periwinkel", "periwinkle", - "periwinkie", "periwinkle", - "periwinlke", "periwinkle", - "permanenty", "permanently", - "permanetly", "permanently", - "permisions", "permission", - "permisison", "permissions", - "permissble", "permissible", - "permissibe", "permissible", - "permissons", "permissions", - "perogative", "prerogative", - "perordered", "preordered", - "perpatuate", "perpetuate", - "perpetualy", "perpetually", - "perpetuare", "perpetuate", - "persausion", "persuasion", - "persausive", "persuasive", - "persective", "respective", - "persectued", "persecuted", - "persecutie", "persecuted", - "persecutin", "persecution", - "perserving", "preserving", - "persicuted", "persecuted", - "persistant", "persistent", - "persistens", "persists", - "persoanlly", "personally", - "persocuted", "persecuted", - "personalie", "personalized", - "personalis", "personas", - "personarse", "personas", - "personatus", "personas", - "personnell", "personnel", - "perspecive", "perspective", - "perspectie", "perspectives", - "persuasian", "persuasion", - "persuasing", "persuasion", - "persuasivo", "persuasion", - "persuation", "persuasion", - "persucuted", "persecuted", - "persumably", "presumably", - "persussion", "persuasion", - "persvasive", "persuasive", - "perswasion", "persuasion", - "pertinante", "pertinent", - "pervailing", "prevailing", - "pervalence", "prevalence", - "pervention", "prevention", - "perversley", "perverse", - "pesitcides", "pesticides", - "pessimistc", "pessimistic", - "pessimitic", "pessimistic", - "pestacides", "pesticides", - "pestecides", "pesticides", - "pesticedes", "pesticides", - "pesticidas", "pesticides", - "pestisides", "pesticides", - "pestizides", "pesticides", - "pharamcist", "pharmacist", - "pharmacias", "pharmacist", - "pharmacyst", "pharmacist", - "pharmasist", "pharmacist", - "pharmicist", "pharmacist", - "phemonenon", "phenomenon", - "phenemenon", "phenomenon", - "phenemonal", "phenomenal", - "phenomanal", "phenomenal", - "phenomanon", "phenomenon", - "phenomemon", "phenomenon", - "phenomenen", "phenomenon", - "phenomenol", "phenomenal", - "phenomenom", "phenomenon", - "phenominon", "phenomenon", - "phenomonal", "phenomenal", - "phenomonen", "phenomenon", - "phenomonon", "phenomenon", - "phenonemal", "phenomenal", - "phenonemon", "phenomenon", - "phenonmena", "phenomena", - "philipines", "philippines", - "philippins", "philippines", - "philisophy", "philosophy", - "phillipine", "philippine", - "phillipses", "phillies", - "philosiphy", "philosophy", - "philosohpy", "philosophy", - "philosoper", "philosopher", - "philospher", "philosopher", - "philospohy", "philosophy", - "photogragh", "photograph", - "photograhs", "photographs", - "photograhy", "photography", - "photograps", "photographs", - "photograpy", "photography", - "photogrpah", "photographs", - "photoshopd", "photoshopped", - "photoshope", "photoshopped", - "phramacist", "pharmacist", - "phsyically", "physically", - "phsyicians", "physicians", - "phsyicists", "physicists", - "phsyiology", "physiology", - "phycisians", "physicians", - "phycisists", "physicists", - "phyiscally", "physically", - "phyisology", "physiology", - "physcially", "physically", - "physcology", "psychology", - "physcopath", "psychopath", - "physicials", "physicians", - "physiciens", "physicians", - "physioligy", "physiology", - "picthforks", "pitchforks", - "pinoneered", "pioneered", - "pitchferks", "pitchforks", - "pitchfolks", "pitchforks", - "pitchfords", "pitchforks", - "pitchworks", "pitchforks", - "pitckforks", "pitchforks", - "pittaburgh", "pittsburgh", - "pittsbrugh", "pittsburgh", - "placehoder", "placeholder", - "placeholdr", "placeholder", - "placeholer", "placeholder", - "placemenet", "placements", - "plagairism", "plagiarism", - "plagarisim", "plagiarism", - "plagiariam", "plagiarism", - "plagiarios", "plagiarism", - "plagiarius", "plagiarism", - "plagiarizm", "plagiarism", - "plagierism", "plagiarism", - "plaguarism", "plagiarism", - "plaigarism", "plagiarism", - "plasticosa", "plastics", - "platfarmer", "platformer", - "platformar", "platformer", - "platformie", "platformer", - "platfotmer", "platformer", - "platfromer", "platformer", - "platofrmer", "platformer", - "playaround", "playground", - "playersare", "playerbase", - "playgorund", "playground", - "playthrogh", "playthrough", - "playthrouh", "playthrough", - "playwrites", "playwrights", - "plethorian", "plethora", - "policitian", "politician", - "polinators", "pollinators", - "polishuset", "polishes", - "politessen", "politeness", - "politicain", "politician", - "politicaly", "politically", - "politicien", "politician", - "politicing", "politician", - "politicion", "politician", - "politickin", "politician", - "politiikan", "politician", - "politiness", "politeness", - "polititian", "politician", - "popualtion", "populations", - "populairty", "popularity", - "populaiton", "populations", - "popularaty", "popularity", - "popularest", "populate", - "popularily", "popularity", - "populaties", "populate", - "populatiry", "popularity", - "populative", "populate", - "populatoin", "populations", - "popultaion", "populations", - "pormetheus", "prometheus", - "pornograhy", "pornography", - "pornograpy", "pornography", - "pornogrphy", "pornography", - "porportion", "proportion", - "portabilty", "portability", - "portarying", "portraying", - "portoguese", "portuguese", - "portraiing", "portraying", - "portrating", "portraying", - "portrayels", "portrays", - "portugeuse", "portuguese", - "portuguise", "portuguese", - "posessions", "possessions", - "posicional", "positional", - "positevely", "positively", - "positioing", "positioning", - "positionly", "positional", - "positionne", "positioned", - "positivley", "positively", - "possesives", "possessive", - "possessers", "possesses", - "possessess", "possesses", - "possibiliy", "possibility", - "possibilty", "possibility", - "possissive", "possessive", - "posthomous", "posthumous", - "potentialy", "potentially", - "poulations", "populations", - "powerhorse", "powerhouse", - "powerhosue", "powerhouse", - "powerhours", "powerhouse", - "powerhsell", "powershell", - "powerprint", "powerpoint", - "powersehll", "powershell", - "ppublisher", "publisher", - "practially", "practically", - "practicaly", "practically", - "practicess", "practise", - "practiclly", "practically", - "practioner", "practitioner", - "precaucion", "precaution", - "precausion", "precaution", - "precautios", "precautions", - "precedance", "precedence", - "precedense", "precedence", - "preceeding", "preceding", - "precendece", "precedence", - "precentage", "percentage", - "precentile", "percentile", - "preciselly", "precisely", - "precuation", "precautions", - "precussion", "percussion", - "predecated", "predicated", - "predecence", "precedence", - "predecesor", "predecessor", - "predection", "prediction", - "predective", "predictive", - "prediccion", "prediction", - "prediceted", "predicated", - "predicited", "predicated", - "predicitng", "predicting", - "prediciton", "prediction", - "predicitve", "predictive", - "predickted", "predicated", - "predictave", "predictive", - "predictivo", "prediction", - "predictons", "predictions", - "predjuiced", "prejudiced", - "predjuices", "prejudices", - "preduction", "prediction", - "preductive", "predictive", - "predujiced", "prejudiced", - "predujices", "prejudices", - "prefarable", "preferable", - "prefarably", "preferably", - "prefection", "perfection", - "preferance", "preference", - "prefereble", "preferable", - "preferente", "preference", - "preferenze", "preference", - "preferible", "preferable", - "preferibly", "preferably", - "prefernece", "preferences", - "preformers", "performers", - "pregancies", "pregnancies", - "pregnanies", "pregnancies", - "preipheral", "peripheral", - "preisdents", "presidents", - "preisthood", "priesthood", - "prejeduced", "prejudiced", - "prejeduces", "prejudices", - "prejiduced", "prejudiced", - "prejiduces", "prejudices", - "prejucided", "prejudiced", - "prejucides", "prejudices", - "prejuduced", "prejudiced", - "prejuduces", "prejudices", - "prelimiary", "preliminary", - "prematurly", "prematurely", - "preminence", "preeminence", - "premission", "permission", - "preorderes", "preorders", - "prepartion", "preparation", - "prepetuate", "perpetuate", - "preposters", "preposterous", - "prescients", "presidents", - "prescirbed", "prescribed", - "prescriped", "prescribed", - "presearing", "preserving", - "presecuted", "persecuted", - "presedency", "presidency", - "presedents", "presidents", - "presenning", "presenting", - "presentase", "presents", - "presentato", "presentation", - "presention", "presenting", - "presentors", "presents", - "preservare", "preserve", - "preservato", "preservation", - "preserverd", "preserved", - "presidancy", "presidency", - "presidante", "presidents", - "presidenta", "presidential", - "presidenty", "presidency", - "presidunce", "presidency", - "presistent", "persistent", - "presonally", "personally", - "presonhood", "personhood", - "pressuming", "pressuring", - "prestigios", "prestigious", - "prestigous", "prestigious", - "presuambly", "presumably", - "presuasion", "persuasion", - "presuasive", "persuasive", - "presumebly", "presumably", - "presumendo", "presumed", - "presumibly", "presumably", - "presumpton", "presumption", - "pretaining", "pertaining", - "pretection", "protection", - "pretendias", "pretends", - "pretensive", "pretense", - "pretentios", "pretentious", - "pretentous", "pretentious", - "prevalecen", "prevalence", - "prevalente", "prevalence", - "prevencion", "prevention", - "preventivo", "prevention", - "preventors", "prevents", - "previaling", "prevailing", - "previosuly", "previously", - "previoulsy", "previously", - "prevolence", "prevalence", - "pricinpals", "principals", - "primarilly", "primarily", - "primatives", "primitives", - "princepals", "principals", - "princesess", "princesses", - "princibles", "principles", - "principaly", "principality", - "principels", "principals", - "principial", "principal", - "principias", "principals", - "principlas", "principals", - "prinicipal", "principal", - "prinicpals", "principals", - "prinicples", "principles", - "printerest", "printers", - "prioratize", "prioritize", - "prioretize", "prioritize", - "prioritice", "prioritize", - "prioritied", "prioritize", - "prioroties", "priorities", - "priorotize", "prioritize", - "priotities", "priorities", - "priotitize", "prioritize", - "privaleged", "privileged", - "privaleges", "privileges", - "privaticed", "privatized", - "privelaged", "privileged", - "privelages", "privileges", - "priveldges", "privileges", - "priveleged", "privileged", - "priveleges", "privileges", - "privelidge", "privileged", - "priveliged", "privileged", - "priveliges", "privileges", - "privetized", "privatized", - "privilaged", "privileged", - "privilages", "privileges", - "priviledge", "privilege", - "privilegde", "privileges", - "privilegie", "privilege", - "priviliged", "privileged", - "priviliges", "privileges", - "privitazed", "privatized", - "privitized", "privatized", - "probabiliy", "probability", - "probabilty", "probability", - "probablies", "probable", - "probablybe", "probable", - "problemita", "problematic", - "procalimed", "proclaimed", - "procceding", "proceeding", - "procedding", "proceeding", - "procederal", "procedural", - "procedings", "proceedings", - "procedrual", "procedural", - "proceededs", "proceeds", - "proceedure", "procedure", - "proceesing", "proceeding", - "processsor", "processors", - "proclamied", "proclaimed", - "proclaming", "proclaiming", - "procliamed", "proclaimed", - "procreatin", "procreation", - "procudures", "procedures", - "prodcution", "production", - "prodecural", "procedural", - "prodecures", "procedures", - "produccion", "production", - "produceras", "produces", - "produceres", "produces", - "producirse", "producers", - "produciton", "production", - "producting", "production", - "productino", "productions", - "productivo", "production", - "productivy", "productivity", - "productoin", "productions", - "produktion", "production", - "produktive", "productive", - "produtcion", "productions", - "profesions", "profession", - "professers", "professors", - "professorn", "profession", - "professsor", "professors", - "proffesion", "profession", - "proficeint", "proficient", - "proficiant", "proficient", - "proficieny", "proficiency", - "proficincy", "proficiency", - "profitabel", "profitable", - "profitabil", "profitable", - "profitible", "profitable", - "proftiable", "profitable", - "programmar", "programmer", - "programmme", "programme", - "progresing", "progressing", - "progresion", "progression", - "progresive", "progressive", - "progressie", "progressives", - "progressin", "progression", - "progresson", "progression", - "progressos", "progresses", - "progressus", "progresses", - "prohibirte", "prohibit", - "prohibites", "prohibits", - "prohibitng", "prohibiting", - "prohibiton", "prohibition", - "prohibitus", "prohibits", - "prohibitve", "prohibited", - "prohobited", "prohibited", - "prohpecies", "prophecies", - "projecitle", "projectiles", - "projectiel", "projectiles", - "projecties", "projectiles", - "projectils", "projectiles", - "projectles", "projectiles", - "projectlie", "projectiles", - "projectyle", "projectile", - "projektile", "projectile", - "projektion", "projection", - "prometheas", "prometheus", - "promethese", "prometheus", - "promethius", "prometheus", - "promethous", "prometheus", - "promethues", "prometheus", - "prominance", "prominence", - "prominenty", "prominently", - "prominetly", "prominently", - "promiscous", "promiscuous", - "promiscuos", "promiscuous", - "promoteurs", "promotes", - "promotheus", "prometheus", - "promotinal", "promotional", - "pronoucned", "pronounced", - "pronouning", "pronouncing", - "propechies", "prophecies", - "propencity", "propensity", - "propenents", "proponents", - "properites", "properties", - "propersity", "propensity", - "propertion", "proportion", - "propertius", "properties", - "prophacies", "prophecies", - "prophocies", "prophecies", - "propietary", "proprietary", - "proplusion", "propulsion", - "propoganda", "propaganda", - "propogates", "propagates", - "propolsion", "propulsion", - "proponants", "proponents", - "proponenet", "proponent", - "proporcion", "proportion", - "proporties", "properties", - "proporting", "proportion", - "propositon", "proposition", - "propotions", "proportions", - "proprietry", "proprietary", - "proprotion", "proportion", - "propserity", "prosperity", - "propserous", "prosperous", - "propulaios", "propulsion", - "propulsing", "propulsion", - "propultion", "propulsion", - "propuslion", "propulsion", - "prosectued", "prosecuted", - "prosectuor", "prosecutor", - "prosecuter", "prosecutor", - "prosecutie", "prosecuted", - "prosicuted", "prosecuted", - "prosicutor", "prosecutor", - "prosocuted", "prosecuted", - "prosparity", "prosperity", - "prospectos", "prospects", - "prosperety", "prosperity", - "prospertiy", "prosperity", - "prosphetic", "prosthetic", - "prosporous", "prosperous", - "prostehtic", "prosthetic", - "prosterity", "prosperity", - "prostethic", "prosthetic", - "prostitite", "prostitute", - "prostitude", "prostitute", - "prostituee", "prostitute", - "prostituer", "prostitute", - "prostitues", "prostitutes", - "prostiture", "prostitute", - "prostituto", "prostitution", - "prostituye", "prostitute", - "protaginst", "protagonist", - "protastant", "protestant", - "proteccion", "protection", - "proteciton", "protections", - "protectice", "protective", - "protectiei", "protective", - "protectoin", "protections", - "protectons", "protectors", - "protectron", "protection", - "protestans", "protests", - "protestare", "protesters", - "protestato", "protestant", - "protestent", "protestant", - "protestina", "protestant", - "prothsetic", "prosthetic", - "protistant", "protestant", - "protocoles", "protocols", - "protocolls", "protocols", - "protocolos", "protocols", - "protohypes", "prototypes", - "protostant", "protestant", - "prototipes", "prototypes", - "prototpyes", "prototypes", - "protraying", "portraying", - "protuguese", "portuguese", - "provencial", "provincial", - "proveribal", "proverbial", - "provervial", "proverbial", - "providance", "providence", - "providince", "providence", - "provinciae", "province", - "provincies", "province", - "provincija", "provincial", - "provinence", "providence", - "provinical", "provincial", - "provintial", "provincial", - "provinvial", "provincial", - "provisiosn", "provision", - "provisonal", "provisional", - "provocatie", "provocative", - "pscyhology", "psychology", - "pscyhopath", "psychopath", - "pshycology", "psychology", - "pshycopath", "psychopath", - "psychedlic", "psychedelic", - "psychiatic", "psychiatric", - "psycholoog", "psychology", - "psychopaat", "psychopath", - "psychopats", "psychopaths", - "ptichforks", "pitchforks", - "publicitan", "publication", - "publisheed", "published", - "publisherr", "publisher", - "publishher", "publisher", - "publissher", "publisher", - "publlisher", "publisher", - "punihsment", "punishments", - "punishemnt", "punishments", - "punishible", "punishable", - "punishmnet", "punishments", - "punissable", "punishable", - "punsihable", "punishable", - "purchacing", "purchasing", - "purpolsion", "propulsion", - "purposedly", "purposely", - "purposelly", "purposely", - "purpotedly", "purportedly", - "pususading", "persuading", - "pyschology", "psychology", - "pyschopath", "psychopath", - "qaulifiers", "qualifiers", - "quailfiers", "qualifiers", - "qualfiiers", "qualifiers", - "qualifieds", "qualifies", - "qualifiies", "qualifiers", - "qualifiing", "qualifying", - "qualifires", "qualifiers", - "qualifyers", "qualifiers", - "qualitying", "qualifying", - "quanitites", "quantities", - "quantaties", "quantities", - "quantitize", "quantities", - "quarantena", "quarantine", - "quarantene", "quarantine", - "quarantied", "quarantine", - "quarintine", "quarantine", - "quaruntine", "quarantine", - "quesitoned", "questioned", - "questional", "questionable", - "questionne", "questioned", - "rabinnical", "rabbinical", - "radiactive", "radioactive", - "radioacive", "radioactive", - "rainbowers", "rainbows", - "randmoness", "randomness", - "randomzied", "randomized", - "randonmess", "randomness", - "randumness", "randomness", - "raspberrry", "raspberry", - "rationalle", "rationale", - "readmition", "readmission", - "realitvely", "relatively", - "realtively", "relatively", - "realtivity", "relativity", - "reaserched", "researched", - "reasercher", "researcher", - "rebiulding", "rebuilding", - "reboudning", "rebounding", - "rebouncing", "rebounding", - "rebuidling", "rebuilding", - "rebuliding", "rebuilding", - "rebuplican", "republican", - "reccommend", "recommend", - "recepients", "recipients", - "receptoras", "receptors", - "receptores", "receptors", - "recgonised", "recognised", - "recgonized", "recognized", - "recgonizes", "recognizes", - "reciepents", "recipients", - "recipeints", "recipients", - "recipiants", "recipients", - "recocnised", "recognised", - "recoginsed", "recognised", - "recoginzed", "recognized", - "recognices", "recognizes", - "recogniton", "recognition", - "recognzied", "recognised", - "recomended", "recommended", - "recommande", "recommend", - "recommands", "recommends", - "recommeded", "recommended", - "recommened", "recommend", - "recommennd", "recommends", - "recomments", "recommends", - "recompence", "recompense", - "reconcider", "reconsider", - "reconcille", "reconcile", - "recongised", "recognised", - "recongized", "recognized", - "recongizes", "recognizes", - "reconisder", "reconsider", - "reconsiled", "reconsider", - "recordarle", "recorder", - "recordarme", "recorder", - "recordarse", "recorder", - "recordarte", "recorder", - "recreacion", "recreation", - "recreatief", "recreate", - "recreativo", "recreation", - "recrutiers", "recruiters", - "rectanglar", "rectangular", - "rectangual", "rectangular", - "rectanguar", "rectangular", - "recuriters", "recruiters", - "recurrance", "recurrence", - "recursivly", "recursively", - "redefinied", "redefine", - "redefinine", "redefine", - "redemtpion", "redemption", - "redepmtion", "redemption", - "redesiging", "redesign", - "rediculous", "ridiculous", - "redmeption", "redemption", - "redneckers", "rednecks", - "redneckese", "rednecks", - "redneckest", "rednecks", - "reduncancy", "redundancy", - "redundency", "redundancy", - "redundnacy", "redundancy", - "redunduncy", "redundancy", - "reenforced", "reinforced", - "reevaulate", "reevaluate", - "refedendum", "referendum", - "refelcting", "reflecting", - "refelction", "reflection", - "refelctive", "reflective", - "referances", "references", - "referandum", "referendum", - "referemces", "references", - "referemdum", "referendum", - "referendim", "referendum", - "referendom", "referendum", - "referenece", "reference", - "referening", "referencing", - "referenses", "referees", - "referentes", "references", - "referneces", "references", - "referrence", "reference", - "referundum", "referendum", - "refference", "reference", - "refleciton", "reflections", - "reflecters", "reflects", - "reflektion", "reflection", - "reflextion", "reflection", - "reformerad", "reformed", - "refrigerar", "refrigerator", - "refurbised", "refurbished", - "regenarate", "regenerate", - "registeres", "registers", - "registrato", "registration", - "regresives", "regressive", - "regressivo", "regression", - "regualting", "regulating", - "regualtion", "regulations", - "regualtors", "regulators", - "regulacion", "regulation", - "regulament", "regulate", - "regulaotrs", "regulators", - "regularily", "regularly", - "regularing", "regulating", - "regularlas", "regulars", - "regularlos", "regulars", - "regulaters", "regulators", - "regulatios", "regulators", - "regulatons", "regulations", - "rehtorical", "rhetorical", - "reinstaled", "reinstalled", - "reitrement", "retirement", - "relagation", "relaxation", - "relatation", "relaxation", - "relativety", "relativity", - "relativily", "relativity", - "relativley", "relatively", - "relavation", "relaxation", - "relaxating", "relaxation", - "relazation", "relaxation", - "releagtion", "relegation", - "relegetion", "relegation", - "relentness", "relentless", - "reletnless", "relentless", - "relevation", "revelation", - "relexation", "relegation", - "relfecting", "reflecting", - "relfection", "reflection", - "relfective", "reflective", - "reliabilty", "reliability", - "reliablely", "reliably", - "religiones", "religions", - "religiosly", "religiously", - "religiousy", "religiously", - "religously", "religiously", - "relitavely", "relatively", - "reluctanct", "reluctant", - "reluctanly", "reluctantly", - "reluctanty", "reluctantly", - "remarcably", "remarkably", - "remarkibly", "remarkably", - "rememberes", "remembers", - "remenicent", "reminiscent", - "reminisent", "reminiscent", - "reminscent", "reminiscent", - "remmebered", "remembered", - "renaissace", "renaissance", - "renderered", "rendered", - "renegerate", "regenerate", - "renewabels", "renewables", - "renewebles", "renewables", - "rennovated", "renovated", - "renweables", "renewables", - "repatition", "repetition", - "repblicans", "republicans", - "repbulican", "republican", - "repeadedly", "repeatedly", - "repeadetly", "repeatedly", - "repearable", "repeatable", - "repearedly", "repealed", - "repeatadly", "repeatedly", - "repeatedlt", "repealed", - "repeatetly", "repeatedly", - "repeatible", "repeatable", - "repeatidly", "repeatedly", - "repectable", "repeatable", - "repentable", "repeatable", - "repentence", "repentance", - "repersents", "represents", - "repetation", "repetition", - "repeteadly", "repeatedly", - "repetetion", "repetition", - "repeticion", "repetition", - "repetitivo", "repetition", - "replacated", "replicated", - "replaceble", "replaceable", - "replacemet", "replacements", - "replacemnt", "replacement", - "replacemtn", "replacements", - "replecated", "replicated", - "repoistory", "repository", - "reponsible", "responsible", - "reportadly", "reportedly", - "reporteros", "reporters", - "reportidly", "reportedly", - "repositary", "repository", - "reposotory", "repository", - "repostiory", "repository", - "representn", "representing", - "repressent", "represents", - "repressivo", "repression", - "repsectful", "respectful", - "repsecting", "respecting", - "repsective", "respective", - "repsonding", "responding", - "repsonsive", "responsive", - "reptuation", "reputation", - "repubicans", "republicans", - "republcian", "republican", - "republians", "republicans", - "republicon", "republican", - "repuglican", "republican", - "repulicans", "republicans", - "reputacion", "reputation", - "requirment", "requirement", - "requrement", "requirement", - "resemblace", "resemble", - "reserached", "researched", - "reseracher", "researchers", - "reserverad", "reserved", - "reservered", "reserved", - "residental", "residential", - "resistable", "resistible", - "resistanes", "resistances", - "resistanse", "resistances", - "resistence", "resistance", - "resistendo", "resisted", - "resistered", "resisted", - "resistnace", "resistances", - "resitsance", "resistances", - "resoltuion", "resolutions", - "resolucion", "resolution", - "resolutino", "resolutions", - "resolutoin", "resolutions", - "resolutons", "resolutions", - "resolvemos", "resolves", - "resolvendo", "resolved", - "resolveres", "resolves", - "resolverse", "resolves", - "resolviste", "resolves", - "resonabelt", "resonate", - "resoultion", "resolution", - "respecitve", "respective", - "respectifs", "respects", - "respection", "respecting", - "respectons", "respects", - "respectuos", "respects", - "respektive", "respective", - "respiratoy", "respiratory", - "responcive", "responsive", - "responisve", "responsive", - "responsibe", "responsive", - "responsiby", "responsibly", - "responsile", "responsive", - "responsing", "responding", - "ressembled", "resembled", - "restarants", "restaurants", - "restaraunt", "restaurant", - "restaruant", "restaurant", - "restatting", "restarting", - "restaurent", "restaurant", - "restauring", "restarting", - "resteraunt", "restaurant", - "restircted", "restricted", - "restorting", "restarting", - "restrainig", "restraining", - "restrcited", "restricted", - "restrcting", "restarting", - "restricing", "restricting", - "restricion", "restriction", - "restricive", "restrictive", - "restrictes", "restricts", - "restrictie", "restrictive", - "restricton", "restriction", - "restructed", "restricted", - "restuarant", "restaurant", - "resturants", "restaurants", - "resturaunt", "restaurant", - "retaliaton", "retaliation", - "rethorical", "rhetorical", - "retierment", "retirement", - "retribuito", "retribution", - "retrosepct", "retrospect", - "retrospekt", "retrospect", - "revaluated", "reevaluated", - "revealtion", "revelations", - "revelaiton", "revelations", - "revelatons", "revelations", - "revelution", "revelation", - "reversable", "reversible", - "reversably", "reversal", - "reviewtrue", "reviewer", - "revisiones", "revisions", - "revisionis", "revisions", - "revoltuion", "revolution", - "revoluiton", "revolutions", - "revolutoin", "revolutions", - "revoultion", "revolution", - "rewarching", "rewatching", - "rewatchibg", "rewatching", - "rewatchign", "rewatching", - "rewatchimg", "rewatching", - "rhapsodomy", "rhapsody", - "rhetorisch", "rhetoric", - "ridicilous", "ridiculous", - "ridicoulus", "ridiculous", - "ridiculise", "ridicule", - "ridiculize", "ridicule", - "ridiculled", "ridicule", - "ridiculose", "ridicule", - "ridiculued", "ridicule", - "rienforced", "reinforced", - "rigthfully", "rightfully", - "roleplaing", "roleplaying", - "romanmania", "romanian", - "roundaboot", "roundabout", - "rucuperate", "recuperate", - "rudimentry", "rudimentary", - "sacarmento", "sacramento", - "sacntioned", "sanctioned", - "sacraficed", "sacrificed", - "sacrafices", "sacrifices", - "sacramenno", "sacramento", - "sacreficed", "sacrificed", - "sacrefices", "sacrifices", - "sacremento", "sacramento", - "sacrifaced", "sacrificed", - "sacrifaces", "sacrifices", - "sacrifical", "sacrificial", - "sacrificas", "sacrifices", - "sacrificie", "sacrificed", - "sacrificng", "sacrificing", - "sacrifises", "sacrifices", - "sacrifized", "sacrificed", - "sacrifizes", "sacrifices", - "sacromento", "sacramento", - "sadistisch", "sadistic", - "sanctionne", "sanctioned", - "sandiwches", "sandwiches", - "sandviches", "sandwiches", - "sandwishes", "sandwiches", - "sanitazion", "sanitation", - "santiation", "sanitation", - "sastifying", "satisfying", - "satellitte", "satellites", - "satifsying", "satisfying", - "satrically", "satirically", - "satsifying", "satisfying", - "sattelites", "satellites", - "saturacion", "saturation", - "scandalosa", "scandals", - "scandalose", "scandals", - "scandalosi", "scandals", - "scandaloso", "scandals", - "scandaniva", "scandinavia", - "scandinava", "scandinavian", - "scandinvia", "scandinavia", - "scaramento", "sacramento", - "scarificed", "sacrificed", - "scarifices", "sacrifices", - "scarmbling", "scrambling", - "scartching", "scratching", - "sceintific", "scientific", - "sceintists", "scientists", - "scenarioes", "scenarios", - "scenarions", "scenarios", - "scenarious", "scenarios", - "scheudling", "scheduling", - "scholarhip", "scholarship", - "scholarley", "scholarly", - "sciencists", "scientists", - "scientests", "scientists", - "scirptures", "scriptures", - "scooterers", "scooters", - "scorebaord", "scoreboard", - "scoreborad", "scoreboard", - "scorebored", "scoreboard", - "scorpiomon", "scorpion", - "scracthing", "scratching", - "scramblies", "scramble", - "screenshat", "screenshot", - "screenshit", "screenshot", - "scriptores", "scriptures", - "scripturae", "scriptures", - "scriputres", "scriptures", - "scritpures", "scriptures", - "scrutinity", "scrutiny", - "seahawkers", "seahawks", - "sebastiaan", "sebastian", - "segegrated", "segregated", - "segragated", "segregated", - "segregaded", "segregated", - "segregatie", "segregated", - "segretated", "segregated", - "segrigated", "segregated", - "selectiose", "selections", - "selectivly", "selectively", - "selectivos", "selections", - "selfishess", "selfishness", - "senitments", "sentiments", - "sensitiviy", "sensitivity", - "sensitivty", "sensitivity", - "sentaments", "sentiments", - "sentancing", "sentencing", - "sentements", "sentiments", - "sentencian", "sentencing", - "sentensing", "sentencing", - "sentimenal", "sentimental", - "sentimetal", "sentimental", - "sentincing", "sentencing", - "sentinents", "sentiments", - "separacion", "separation", - "separaters", "separates", - "separatley", "separately", - "separatron", "separation", - "separetely", "separately", - "seperately", "separately", - "seperating", "separating", - "seperation", "separation", - "seperatism", "separatism", - "seperatist", "separatist", - "seperatley", "separate", - "sepulchure", "sepulchre", - "serenitary", "serenity", - "serviceble", "serviceable", - "settelment", "settlement", - "settlemens", "settlements", - "settlemets", "settlements", - "settlemnts", "settlements", - "seuxalized", "sexualized", - "seventeeen", "seventeen", - "sexaulized", "sexualized", - "sexualixed", "sexualized", - "sexuallity", "sexually", - "sexualzied", "sexualized", - "sexulaized", "sexualized", - "shakespare", "shakespeare", - "shakespeer", "shakespeare", - "shakespere", "shakespeare", - "shamelesly", "shamelessly", - "shamelessy", "shamelessly", - "shaprening", "sharpening", - "shareholds", "shareholders", - "sharkening", "sharpening", - "sharpining", "sharpening", - "shartening", "sharpening", - "shatnering", "shattering", - "shattening", "shattering", - "shepharded", "shepherd", - "shilouette", "silhouette", - "shitlasses", "shitless", - "shortenend", "shortened", - "shortining", "shortening", - "sidelinien", "sideline", - "sidelinjen", "sideline", - "sidelinked", "sideline", - "sigantures", "signatures", - "sightstine", "sightstone", - "signficant", "significant", - "signifiant", "significant", - "significat", "significant", - "signitures", "signatures", - "sigthstone", "sightstone", - "sihlouette", "silhouette", - "silohuette", "silhouette", - "silouhette", "silhouette", - "similairty", "similarity", - "similarily", "similarly", - "similarlly", "similarly", - "similiarly", "similarly", - "similiarty", "similarity", - "simliarity", "similarity", - "simluation", "simulation", - "simplictic", "simplistic", - "simplifing", "simplifying", - "simplifyed", "simplified", - "simplifyng", "simplifying", - "simplisitc", "simplistic", - "simplisity", "simplicity", - "simplistes", "simplest", - "simplivity", "simplicity", - "simplyfied", "simplified", - "simualtion", "simulation", - "simulacion", "simulation", - "simulaiton", "simulations", - "simulaties", "simulate", - "simulative", "simulate", - "simulatons", "simulations", - "simulatore", "simulate", - "sincereley", "sincerely", - "sincerelly", "sincerely", - "singatures", "signatures", - "singulaire", "singular", - "singulariy", "singularity", - "singularty", "singularity", - "singulator", "singular", - "sitautions", "situations", - "situatinal", "situational", - "skatebaord", "skateboard", - "skateborad", "skateboard", - "skatebored", "skateboard", - "skatebrand", "skateboard", - "skeletones", "skeletons", - "skeptecism", "skepticism", - "skepticals", "skeptics", - "skepticles", "skeptics", - "skepticons", "skeptics", - "skeptisicm", "skepticism", - "skeptisism", "skepticism", - "sketchysex", "sketches", - "sketpicism", "skepticism", - "skillhosts", "skillshots", - "skillshits", "skillshots", - "skillshoot", "skillshots", - "skillslots", "skillshots", - "skillsofts", "skillshots", - "skillsshot", "skillshots", - "skirmiches", "skirmish", - "skpeticism", "skepticism", - "slaughterd", "slaughtered", - "slipperies", "slippers", - "smarpthone", "smartphones", - "smarthpone", "smartphone", - "snadwiches", "sandwiches", - "snowbaling", "snowballing", - "snowballes", "snowballs", - "snowballls", "snowballs", - "socailists", "socialists", - "socailized", "socialized", - "socialisim", "socialism", - "socializng", "socializing", - "socialsits", "socialists", - "sociapaths", "sociopaths", - "socilaists", "socialists", - "socilaized", "socialized", - "sociologia", "sociological", - "sociopatas", "sociopaths", - "sociopatch", "sociopaths", - "sociopatic", "sociopathic", - "socratease", "socrates", - "socreboard", "scoreboard", - "soemthings", "somethings", - "soldiarity", "solidarity", - "solidairty", "solidarity", - "soliditary", "solidarity", - "solitudine", "solitude", - "somehtings", "somethings", - "someonelse", "someones", - "somethibng", "somethin", - "somethigng", "somethin", - "somethigns", "somethings", - "somethihng", "somethin", - "somethiing", "somethin", - "somethijng", "somethin", - "somethikng", "somethin", - "somethimng", "somethin", - "somethinbg", "somethings", - "somethines", "somethings", - "somethinfg", "somethings", - "somethinhg", "somethings", - "somethinig", "somethings", - "somethinkg", "somethings", - "somethinks", "somethings", - "somethinmg", "somethings", - "somethinng", "somethings", - "somethintg", "somethings", - "somethiong", "somethin", - "somethiung", "somethin", - "sophicated", "sophisticated", - "sotrmfront", "stormfront", - "sotrylines", "storylines", - "soudntrack", "soundtrack", - "soundrtack", "soundtracks", - "soundtracs", "soundtracks", - "soundtrakc", "soundtracks", - "soundtrakk", "soundtrack", - "soundtraks", "soundtracks", - "southampon", "southampton", - "southamton", "southampton", - "southerers", "southerners", - "southernes", "southerners", - "southerton", "southern", - "souveniers", "souvenirs", - "sovereigny", "sovereignty", - "sovereinty", "sovereignty", - "soverignty", "sovereignty", - "spartaniis", "spartans", - "spartanops", "spartans", - "specailist", "specialist", - "specailize", "specializes", - "specialice", "specialize", - "specialied", "specialized", - "specialies", "specializes", - "specialits", "specials", - "speciallly", "specially", - "speciallty", "specially", - "specialops", "specials", - "specialsts", "specialists", - "specialtys", "specials", - "specialzed", "specialized", - "specialzes", "specializes", - "specifices", "specifics", - "specifiing", "specifying", - "specifiyng", "specifying", - "speciliast", "specialists", - "specimines", "specimen", - "spectarors", "spectators", - "spectaters", "spectators", - "spectracal", "spectral", - "spectraply", "spectral", - "spectrolab", "spectral", - "speculatie", "speculative", - "speculatin", "speculation", - "speecheasy", "speeches", - "speicalist", "specialist", - "spiritualy", "spiritually", - "sponsorees", "sponsors", - "sponsorhip", "sponsorship", - "sponsorise", "sponsors", - "spontaneos", "spontaneous", - "spontaneus", "spontaneous", - "spontanous", "spontaneous", - "spoonfulls", "spoonfuls", - "spreadshet", "spreadsheet", - "springfeld", "springfield", - "springfied", "springfield", - "spriritual", "spiritual", - "squirrells", "squirrels", - "squirrelus", "squirrels", - "stabelized", "stabilized", - "stabilzied", "stabilized", - "stablility", "stability", - "stablizied", "stabilized", - "staggaring", "staggering", - "stakeboard", "skateboard", - "starighten", "straighten", - "starnation", "starvation", - "startegies", "strategies", - "startupbus", "startups", - "starwberry", "strawberry", - "statememts", "statements", - "statictics", "statistics", - "stationair", "stationary", - "statisitcs", "statistics", - "statistcal", "statistical", - "statistisk", "statistics", - "stauration", "saturation", - "stealthboy", "stealthy", - "stealthely", "stealthy", - "stealthify", "stealthy", - "stealthray", "stealthy", - "steeleries", "steelers", - "stereotipe", "stereotype", - "stereotpye", "stereotypes", - "steriotype", "stereotype", - "steroetype", "stereotype", - "sterotypes", "stereotypes", - "steryotype", "stereotype", - "stimilants", "stimulants", - "stimilated", "stimulated", - "stimualted", "stimulated", - "stimulatie", "stimulated", - "stimulatin", "stimulation", - "stimulaton", "stimulation", - "stimulents", "stimulants", - "stomrfront", "stormfront", - "storelines", "storylines", - "stormfornt", "stormfront", - "stormfromt", "stormfront", - "stornfront", "stormfront", - "stornghold", "stronghold", - "stradegies", "strategies", - "strageties", "strategies", - "straighted", "straightened", - "straightie", "straighten", - "straightin", "straighten", - "straigthen", "straighten", - "stranglove", "strangle", - "strangreal", "strangle", - "stratagies", "strategies", - "strategems", "strategies", - "strategice", "strategies", - "strategisk", "strategies", - "stravation", "starvation", - "strawbarry", "strawberry", - "strawbeary", "strawberry", - "strawbeery", "strawberry", - "strawbrary", "strawberry", - "strawburry", "strawberry", - "streaching", "stretching", - "streamtrue", "streamer", - "strechting", "stretching", - "strecthing", "stretching", - "stregnthen", "strengthen", - "streichung", "stretching", - "strenghten", "strengthen", - "strengsten", "strengthen", - "strengthes", "strengths", - "strengthin", "strengthen", - "stressende", "stressed", - "striaghten", "straighten", - "stromfront", "stormfront", - "stronkhold", "stronghold", - "stroylines", "storylines", - "structered", "structured", - "structrual", "structural", - "structurel", "structural", - "strucutral", "structural", - "strucutred", "structured", - "strucutres", "structures", - "strugglign", "struggling", - "strwaberry", "strawberry", - "sttutering", "stuttering", - "stupidfree", "stupider", - "stupiditiy", "stupidity", - "sturctural", "structural", - "sturctures", "structures", - "sturggling", "struggling", - "subarmines", "submarines", - "subcultuur", "subculture", - "subesquent", "subsequent", - "subisdized", "subsidized", - "subjectief", "subjective", - "subjectifs", "subjects", - "subjectivy", "subjectively", - "subjektive", "subjective", - "submariens", "submarines", - "submarinas", "submarines", - "submergerd", "submerged", - "submerines", "submarines", - "submisison", "submissions", - "submissies", "submissive", - "submissons", "submissions", - "submittion", "submitting", - "subsadized", "subsidized", - "subscirbed", "subscribed", - "subscirber", "subscribers", - "subscribar", "subscriber", - "subscribir", "subscriber", - "subscrible", "subscriber", - "subscriped", "subscribed", - "subscrubed", "subscribed", - "subscryber", "subscriber", - "subsedized", "subsidized", - "subsequant", "subsequent", - "subsidezed", "subsidized", - "subsidiced", "subsidized", - "subsidizng", "subsidizing", - "subsiduary", "subsidiary", - "subsiquent", "subsequent", - "subsittute", "substitutes", - "subsizided", "subsidized", - "subsrcibed", "subscribed", - "substanial", "substantial", - "substansen", "substances", - "substanser", "substances", - "substanses", "substances", - "substantie", "substantive", - "substatial", "substantial", - "substences", "substances", - "substitite", "substitute", - "substittue", "substitutes", - "substitude", "substitute", - "substitued", "substitute", - "substituer", "substitute", - "substitues", "substitutes", - "substiture", "substitute", - "substituto", "substitution", - "substituts", "substitutes", - "substracts", "subtracts", - "substutite", "substitutes", - "subsudized", "subsidized", - "subtitltes", "subtitle", - "succceeded", "succeeded", - "succcesses", "successes", - "succesfuly", "successfully", - "succesions", "succession", - "successing", "succession", - "successivo", "succession", - "sucesfully", "successfully", - "sucessfull", "successful", - "sucessfuly", "successfully", - "sudnerland", "sunderland", - "sufferered", "suffered", - "sufferring", "suffering", - "sufficiant", "sufficient", - "suggestied", "suggestive", - "suggestief", "suggestive", - "suggestons", "suggests", - "sumbarines", "submarines", - "sumbissive", "submissive", - "sumbitting", "submitting", - "summerized", "summarized", - "summorized", "summarized", - "summurized", "summarized", - "sunderlona", "sunderland", - "sunderlund", "sunderland", - "sungalsses", "sunglasses", - "sunglesses", "sunglasses", - "sunglinger", "gunslinger", - "sunscreeen", "sunscreen", - "superfical", "superficial", - "superfluos", "superfluous", - "superioara", "superior", - "superioare", "superior", - "superioris", "superiors", - "superivsor", "supervisors", - "supermaket", "supermarket", - "supermarkt", "supermarket", - "superouman", "superhuman", - "superposer", "superpowers", - "superviors", "supervisors", - "superviosr", "supervisors", - "supervisar", "supervisor", - "superviser", "supervisor", - "supervisin", "supervision", - "supervison", "supervision", - "supervsior", "supervisors", - "supperssor", "suppressor", - "supplament", "supplement", - "supplemant", "supplemental", - "supplemets", "supplements", - "supportare", "supporters", - "supporteur", "supporter", - "supportied", "supported", - "supportors", "supporters", - "supposdely", "supposedly", - "supposebly", "supposedly", - "supposidly", "supposedly", - "suppresion", "suppression", - "suppresors", "suppressor", - "suppressin", "suppression", - "suppressio", "suppressor", - "suppresson", "suppression", - "suprassing", "surpassing", - "supressing", "suppressing", - "supression", "suppression", - "supsension", "suspension", - "supsicions", "suspicions", - "supsicious", "suspicious", - "surounding", "surrounding", - "surplanted", "supplanted", - "surpressed", "suppressed", - "surprizing", "surprising", - "surrenderd", "surrendered", - "surrouding", "surrounding", - "surroundes", "surrounds", - "surroundig", "surroundings", - "survivours", "survivor", - "suseptable", "susceptible", - "suseptible", "susceptible", - "suspecions", "suspicions", - "suspecious", "suspicious", - "suspencion", "suspension", - "suspendeds", "suspense", - "suspention", "suspension", - "suspicians", "suspicions", - "suspiciois", "suspicions", - "suspicioso", "suspicions", - "suspicioun", "suspicion", - "suspicison", "suspicions", - "suspiciuos", "suspicions", - "suspicsion", "suspicions", - "suspisions", "suspicions", - "suspisious", "suspicious", - "suspitions", "suspicions", - "sustainble", "sustainable", - "swaetshirt", "sweatshirt", - "swearengin", "swearing", - "swearshirt", "sweatshirt", - "sweathsirt", "sweatshirt", - "sweatshits", "sweatshirt", - "sweatshort", "sweatshirt", - "sweatshrit", "sweatshirt", - "sweerheart", "sweetheart", - "sweetshart", "sweetheart", - "switcheasy", "switches", - "switzerand", "switzerland", - "symapthize", "sympathize", - "symbolisch", "symbolic", - "symbolisim", "symbolism", - "symetrical", "symmetrical", - "sympatheic", "sympathetic", - "sympathiek", "sympathize", - "sympathien", "sympathize", - "sympathtic", "sympathetic", - "sympathyze", "sympathize", - "sympethize", "sympathize", - "symphatize", "sympathize", - "symphonity", "symphony", - "sympothize", "sympathize", - "syncronous", "synchronous", - "synomymous", "synonymous", - "synomynous", "synonymous", - "synonamous", "synonymous", - "synonimous", "synonymous", - "synonmyous", "synonymous", - "synonomous", "synonymous", - "synonumous", "synonymous", - "synonynous", "synonymous", - "sypmathize", "sympathize", - "systamatic", "systematic", - "systemetic", "systematic", - "systemisch", "systemic", - "systimatic", "systematic", - "tabelspoon", "tablespoon", - "tablespons", "tablespoons", - "tablesppon", "tablespoon", - "tacitcally", "tactically", - "taiwanesse", "taiwanese", - "taligating", "tailgating", - "tantrumers", "tantrums", - "targetting", "targeting", - "teamfigths", "teamfights", - "teamifghts", "teamfights", - "teamspeack", "teamspeak", - "techicians", "technicians", - "techincian", "technician", - "techinican", "technician", - "techinques", "techniques", - "technicain", "technician", - "technicaly", "technically", - "technicans", "technicians", - "technichan", "technician", - "technicien", "technician", - "technicion", "technician", - "technitian", "technician", - "technqiues", "techniques", - "techtician", "technician", - "tehnically", "ethnically", - "telegrapgh", "telegraph", - "teleporing", "teleporting", - "televesion", "television", - "televisivo", "television", - "temafights", "teamfights", - "temerature", "temperature", - "temperatue", "temperature", - "temperment", "temperament", - "temperture", "temperature", - "templarios", "templars", - "templarius", "templars", - "temporaily", "temporarily", - "temporarly", "temporary", - "temptating", "temptation", - "temptetion", "temptation", - "tendancies", "tendencies", - "tendencias", "tendencies", - "tendencije", "tendencies", - "tendensies", "tendencies", - "tendincies", "tendencies", - "tensionors", "tensions", - "tentacreul", "tentacle", - "termanator", "terminator", - "termendous", "tremendous", - "termiantor", "terminator", - "termigator", "terminator", - "terminales", "terminals", - "terminalis", "terminals", - "terminarla", "terminal", - "terminarlo", "terminal", - "terminaron", "terminator", - "terminater", "terminator", - "terminolgy", "terminology", - "terorrists", "terrorists", - "terrerists", "terrorists", - "terrestial", "terrestrial", - "terriblely", "terribly", - "terriories", "territories", - "territoral", "territorial", - "territores", "territories", - "territoris", "territories", - "territorry", "territory", - "terrorisim", "terrorism", - "terrorsits", "terrorists", - "terrurists", "terrorists", - "testiclees", "testicles", - "testiclies", "testicle", - "testimoney", "testimony", - "thankyooou", "thankyou", - "themselfes", "themselves", - "themsevles", "themselves", - "themsleves", "themselves", - "theocracry", "theocracy", - "theologial", "theological", - "therapetic", "therapeutic", - "therepists", "therapists", - "theripists", "therapists", - "thermastat", "thermostat", - "thermistat", "thermostat", - "thermomter", "thermometer", - "theromstat", "thermostat", - "thorttling", "throttling", - "thorughout", "throughout", - "thouroghly", "thoroughly", - "threadened", "threaded", - "threatenes", "threatens", - "threatning", "threatening", - "threshhold", "threshold", - "throthling", "throttling", - "throtlling", "throttling", - "throughiut", "throughput", - "thubmnails", "thumbnails", - "thumbmails", "thumbnails", - "thunderbot", "thunderbolt", - "thunderolt", "thunderbolt", - "tighetning", "tightening", - "tightining", "tightening", - "tigthening", "tightening", - "tjpanishad", "upanishad", - "toothbruch", "toothbrush", - "toothbruth", "toothbrush", - "toothbursh", "toothbrush", - "toothrbush", "toothbrush", - "toppingest", "toppings", - "torchilght", "torchlight", - "torchlgiht", "torchlight", - "torchligth", "torchlight", - "torhclight", "torchlight", - "torrentbig", "torrenting", - "torrenters", "torrents", - "torrentors", "torrents", - "tortillera", "tortilla", - "tortillias", "tortilla", - "tortillita", "tortilla", - "tortilllas", "tortilla", - "torunament", "tournament", - "totalitara", "totalitarian", - "touchsceen", "touchscreen", - "touchscren", "touchscreen", - "touranment", "tournaments", - "tourmanent", "tournaments", - "tournamets", "tournaments", - "tournamnet", "tournament", - "tournemant", "tournament", - "tournement", "tournament", - "toxicitity", "toxicity", - "trafficing", "trafficking", - "trainwreak", "trainwreck", - "traitorise", "traitors", - "tramboline", "trampoline", - "tramploine", "trampoline", - "trampolene", "trampoline", - "tranformed", "transformed", - "tranistion", "transition", - "tranlsated", "translated", - "transalted", "translated", - "transaltes", "translates", - "transaltor", "translator", - "transation", "transition", - "transciprt", "transcripts", - "transcirpt", "transcripts", - "transcrips", "transcripts", - "transcrito", "transcript", - "transcrits", "transcripts", - "transcrpit", "transcript", - "transfered", "transferred", - "transferer", "transferred", - "transferes", "transfers", - "transferrs", "transfers", - "transferts", "transfers", - "transfomed", "transformed", - "transfored", "transformed", - "transforme", "transfer", - "transfroms", "transforms", - "transgeder", "transgender", - "transgener", "transgender", - "transicion", "transition", - "transision", "transition", - "transister", "transistor", - "transitons", "transitions", - "transitors", "transistor", - "transkript", "transcript", - "translater", "translator", - "translatin", "translations", - "translatio", "translator", - "translpant", "transplants", - "transluent", "translucent", - "transmited", "transmitted", - "transmiter", "transmitter", - "transmitor", "transistor", - "transmorgs", "transforms", - "transpalnt", "transplants", - "transphoic", "transphobic", - "transplain", "transplant", - "transplate", "transplant", - "transplats", "transplants", - "transpoder", "transported", - "transportr", "transporter", - "transsexal", "transsexual", - "transtator", "translator", - "tranzistor", "transistor", - "trasncript", "transcript", - "trasnforms", "transforms", - "trasnlated", "translated", - "trasnlator", "translator", - "trasnplant", "transplant", - "traveleres", "travelers", - "travelodge", "traveled", - "traverlers", "traverse", - "traversare", "traverse", - "traversier", "traverse", - "treasurery", "treasury", - "trememdous", "tremendous", - "tremondous", "tremendous", - "trespasing", "trespassing", - "trianwreck", "trainwreck", - "trochlight", "torchlight", - "trustworhy", "trustworthy", - "trustworty", "trustworthy", - "trustwothy", "trustworthy", - "tryannical", "tyrannical", - "tunraround", "turnaround", - "tupparware", "tupperware", - "turnapound", "turnaround", - "turthfully", "truthfully", - "tutoriales", "tutorials", - "tyrantical", "tyrannical", - "ubiqituous", "ubiquitous", - "ubiquotous", "ubiquitous", - "ubiqutious", "ubiquitous", - "ukrainains", "ukrainians", - "ukraineans", "ukrainians", - "ukrainiens", "ukrainians", - "ukraininas", "ukrainians", - "ukrianians", "ukrainians", - "ulitmately", "ultimately", - "ulterioara", "ulterior", - "ulterioare", "ulterior", - "ultimative", "ultimate", - "ultimatley", "ultimately", - "ultimatuum", "ultimatum", - "unanwsered", "unanswered", - "unasnwered", "unanswered", - "unattanded", "unattended", - "unattented", "unattended", - "unavailabe", "unavailable", - "unavailble", "unavailable", - "unavoidble", "unavoidable", - "unawnsered", "unanswered", - "unbalenced", "unbalanced", - "unballance", "unbalance", - "unbalnaced", "unbalanced", - "unbareable", "unbearable", - "unbeakable", "unbeatable", - "unbeareble", "unbearable", - "unbeatbale", "unbeatable", - "unbeateble", "unbeatable", - "unbeerable", "unbearable", - "unbeetable", "unbeatable", - "unbeknowst", "unbeknownst", - "unbreakble", "unbreakable", - "uncencored", "uncensored", - "uncensered", "uncensored", - "uncersored", "uncensored", - "uncertainy", "uncertainty", - "uncertanty", "uncertainty", - "uncesnored", "uncensored", - "uncomitted", "uncommitted", - "uncommited", "uncommitted", - "unconcious", "unconscious", - "unconscous", "unconscious", - "undebiably", "undeniably", - "undeinable", "undeniable", - "undeinably", "undeniably", - "undenaible", "undeniable", - "undenaibly", "undeniably", - "undenyable", "undeniable", - "undenyably", "undeniably", - "underbaker", "undertaker", - "undercling", "underlying", - "underfaker", "undertaker", - "undergated", "underrated", - "undergrand", "undergrad", - "undergroud", "underground", - "undergrund", "underground", - "undermimes", "undermines", - "underminde", "undermines", - "underminig", "undermining", - "underneeth", "underneath", - "underneith", "underneath", - "undernieth", "underneath", - "underpowed", "underpowered", - "underraged", "underrated", - "underraker", "undertaker", - "underrater", "undertaker", - "undersatnd", "understands", - "understadn", "understands", - "understans", "understands", - "understnad", "understands", - "understoon", "understood", - "understsnd", "understands", - "undertoker", "undertaker", - "undertsand", "understands", - "undertunes", "undertones", - "underwager", "underwater", - "underwares", "underwater", - "underwolrd", "underworld", - "underwoord", "underworld", - "underwrold", "underworld", - "underyling", "underlying", - "undesrtand", "understands", - "undoubtedy", "undoubtedly", - "undoubtely", "undoubtedly", - "undoubtley", "undoubtedly", - "uneccesary", "unnecessary", - "unecessary", "unnecessary", - "unedcuated", "uneducated", - "unedicated", "uneducated", - "unempolyed", "unemployed", - "unexplaind", "unexplained", - "unexplaned", "unexplained", - "unfamilair", "unfamiliar", - "unfamilier", "unfamiliar", - "unfinsihed", "unfinished", - "unfirendly", "unfriendly", - "unfortuate", "unfortunate", - "unfreindly", "unfriendly", - "unfriednly", "unfriendly", - "unfriently", "unfriendly", - "ungrapeful", "ungrateful", - "ungreatful", "ungrateful", - "unhealthly", "unhealthy", - "unicornios", "unicorns", - "unifnished", "unfinished", - "unihabited", "uninhabited", - "unilatreal", "unilateral", - "unimporant", "unimportant", - "unimpresed", "unimpressed", - "unimpressd", "unimpressed", - "uninsipred", "uninspired", - "uninspried", "uninspired", - "uninstaled", "uninstalled", - "uniquiness", "uniqueness", - "univercity", "university", - "univeristy", "university", - "universale", "universe", - "universaly", "universally", - "universels", "universes", - "universets", "universes", - "universite", "universities", - "universtiy", "university", - "unjustifed", "unjustified", - "unknowingy", "unknowingly", - "unknowinly", "unknowingly", - "unnecesary", "unnecessary", - "unofficail", "unofficial", - "unoffocial", "unofficial", - "unorginial", "unoriginal", - "unorignial", "unoriginal", - "unorigonal", "unoriginal", - "unplacable", "unplayable", - "unplaybale", "unplayable", - "unplayeble", "unplayable", - "unpleasent", "unpleasant", - "unpopulair", "unpopular", - "unproteced", "unprotected", - "unqiueness", "uniqueness", - "unqualifed", "unqualified", - "unrealesed", "unreleased", - "unrealible", "unreliable", - "unrealistc", "unrealistic", - "unrealitic", "unrealistic", - "unreasonal", "unreasonably", - "unrelaible", "unreliable", - "unreleated", "unreleased", - "unrelyable", "unreliable", - "unrepetant", "unrepentant", - "unrepetent", "unrepentant", - "unresponse", "unresponsive", - "unsencored", "uncensored", - "unsetlling", "unsettling", - "unsolicted", "unsolicited", - "unsubscibe", "unsubscribe", - "unsubscrbe", "unsubscribe", - "unsucesful", "unsuccessful", - "unsuprised", "unsurprised", - "unsuprized", "unsurprised", - "unviersity", "university", - "unwrittern", "unwritten", - "urkainians", "ukrainians", - "utlimately", "ultimately", - "utlrasound", "ultrasound", - "vaccinatie", "vaccinated", - "vaccineras", "vaccines", - "valentians", "valentines", - "valentiens", "valentines", - "valentimes", "valentines", - "valentinas", "valentines", - "valentinos", "valentines", - "valentones", "valentines", - "validitity", "validity", - "valnetines", "valentines", - "vandalisim", "vandalism", - "vasectomey", "vasectomy", - "vegatarian", "vegetarian", - "vegaterian", "vegetarian", - "vegeratian", "vegetarians", - "vegetairan", "vegetarians", - "vegetarain", "vegetarians", - "vegetarien", "vegetarian", - "vegetarion", "vegetarian", - "vegetatian", "vegetarian", - "vegeterian", "vegetarian", - "vegitables", "vegetables", - "vehemantly", "vehemently", - "vehemontly", "vehemently", - "veitnamese", "vietnamese", - "veiwership", "viewership", - "veiwpoints", "viewpoints", - "venezuella", "venezuela", - "verificato", "verification", - "verifyable", "verifiable", - "veritcally", "vertically", - "veritiable", "verifiable", - "vernecular", "vernacular", - "vernicular", "vernacular", - "versatiliy", "versatility", - "versatille", "versatile", - "versatilty", "versatility", - "versitlity", "versatility", - "vewiership", "viewership", - "vibratoare", "vibrator", - "vicitmized", "victimized", - "vicotrious", "victorious", - "victemized", "victimized", - "victomized", "victimized", - "victorinos", "victorious", - "victorinus", "victorious", - "victoriosa", "victorious", - "victorioso", "victorious", - "victoriuos", "victorious", - "victumized", "victimized", - "videogaems", "videogames", - "videojames", "videogames", - "vidoegames", "videogames", - "vientamese", "vietnamese", - "vietmanese", "vietnamese", - "vietnamees", "vietnamese", - "vietnamise", "vietnamese", - "viewpionts", "viewpoints", - "vigilantie", "vigilante", - "vigoruosly", "vigorously", - "vigourosly", "vigorously", - "villageois", "villages", - "vindicitve", "vindictive", - "vindictave", "vindictive", - "visibiltiy", "visibility", - "vitenamese", "vietnamese", - "vocabluary", "vocabulary", - "volatiltiy", "volatility", - "volativity", "volatility", - "volitality", "volatility", - "volleyboll", "volleyball", - "vollyeball", "volleyball", - "volonteers", "volunteers", - "volounteer", "volunteer", - "voluntairy", "voluntarily", - "voluntarly", "voluntary", - "voluntears", "volunteers", - "volunteeer", "volunteers", - "volunteerd", "volunteered", - "voluntered", "volunteered", - "vulernable", "vulnerable", - "vulnarable", "vulnerable", - "vulnerabil", "vulnerable", - "vulnurable", "vulnerable", - "vunlerable", "vulnerable", - "warrandyte", "warranty", - "warrantles", "warranties", - "warrenties", "warranties", - "washignton", "washington", - "waterlemon", "watermelon", - "watermalon", "watermelon", - "waterproff", "waterproof", - "wavelegnth", "wavelength", - "wavelenghs", "wavelength", - "wavelenght", "wavelength", - "weakensses", "weaknesses", - "weaknesess", "weaknesses", - "weathliest", "wealthiest", - "wedensdays", "wednesdays", - "wednesdsay", "wednesdays", - "wednessday", "wednesdays", - "wednsedays", "wednesdays", - "weightened", "weighted", - "welathiest", "wealthiest", - "wellignton", "wellington", - "wellingotn", "wellington", - "wendesdays", "wednesdays", - "wereabouts", "whereabouts", - "westbroook", "westbrook", - "westernese", "westerners", - "westerness", "westerners", - "westminser", "westminster", - "westminter", "westminster", - "whatosever", "whatsoever", - "whatseover", "whatsoever", - "whipsering", "whispering", - "whsipering", "whispering", - "widepsread", "widespread", - "wikileakes", "wikileaks", - "wilderniss", "wilderness", - "wildreness", "wilderness", - "willfullly", "willfully", - "winchestor", "winchester", - "windhsield", "windshield", - "windsheild", "windshield", - "windshiled", "windshield", - "wisconsion", "wisconsin", - "wishpering", "whispering", - "withdrawan", "withdrawn", - "withdrawel", "withdrawal", - "withdrawin", "withdrawn", - "withholdng", "withholding", - "withrdawal", "withdrawals", - "witnissing", "witnessing", - "wonderfull", "wonderful", - "wonderfuly", "wonderfully", - "wonderwand", "wonderland", - "worhsiping", "worshiping", - "workingest", "workings", - "workstaion", "workstation", - "workstaton", "workstation", - "worshippig", "worshipping", - "worshoping", "worshiping", - "wrestlewar", "wrestler", - "xenohpobic", "xenophobic", - "xenophibia", "xenophobia", - "xenophibic", "xenophobic", - "xenophonic", "xenophobic", - "xenophopia", "xenophobia", - "xenophopic", "xenophobic", - "xeonphobia", "xenophobia", - "xeonphobic", "xenophobic", - "yourselfes", "yourselves", - "yoursleves", "yourselves", - "zimbabwaen", "zimbabwe", - "zionistisk", "zionists", - "abandonig", "abandoning", - "abandonne", "abandonment", - "abanonded", "abandoned", - "abdomnial", "abdominal", - "abdonimal", "abdominal", - "aberation", "aberration", - "abnormaly", "abnormally", - "abodminal", "abdominal", - "abondoned", "abandoned", - "aborigene", "aborigine", - "aboslutes", "absolutes", - "abosrbing", "absorbing", - "abreviate", "abbreviate", - "abritrary", "arbitrary", - "abruptley", "abruptly", - "absailing", "abseiling", - "absloutes", "absolutes", - "absolutey", "absolutely", - "absolutly", "absolutely", - "absoultes", "absolutes", - "abstracto", "abstraction", - "absurdley", "absurdly", - "absuridty", "absurdity", - "abusrdity", "absurdity", - "academica", "academia", - "accademic", "academic", - "accalimed", "acclaimed", - "accelerar", "accelerator", - "accending", "ascending", - "accension", "accession", - "accidenty", "accidentally", - "acclamied", "acclaimed", - "accliamed", "acclaimed", - "accomdate", "accommodate", - "accordeon", "accordion", - "accordian", "accordion", - "accoridng", "according", - "accountas", "accountants", - "accountat", "accountants", - "accoustic", "acoustic", - "accroding", "according", - "accuraccy", "accuracy", - "acftually", "factually", - "acheiving", "achieving", - "achieveds", "achieves", - "achillees", "achilles", - "achilleos", "achilles", - "achilleus", "achilles", - "achiveing", "achieving", - "acitvates", "activates", - "aclhemist", "alchemist", - "acomplish", "accomplish", - "acquisito", "acquisition", - "acronymes", "acronyms", - "acronymns", "acronyms", - "acsending", "ascending", - "acsension", "ascension", - "activaste", "activates", - "activatin", "activation", - "activelly", "actively", - "activisim", "activism", - "activisit", "activist", - "activites", "activities", - "actresess", "actresses", - "acusation", "causation", - "acutality", "actuality", - "adavanced", "advanced", - "adbominal", "abdominal", - "additonal", "additional", - "addoptive", "adoptive", - "addresing", "addressing", - "addtional", "additional", - "adhearing", "adhering", - "adherance", "adherence", - "adjectivs", "adjectives", - "adjustabe", "adjustable", - "administr", "administer", - "admitedly", "admittedly", - "adolecent", "adolescent", - "adovcated", "advocated", - "adovcates", "advocates", - "adquiring", "acquiring", - "adresable", "addressable", - "adressing", "addressing", - "aduiobook", "audiobook", - "advatange", "advantage", - "adventurs", "adventures", - "adveristy", "adversity", - "advertisy", "adversity", - "advisorys", "advisors", - "aeorspace", "aerospace", - "aeropsace", "aerospace", - "aerosapce", "aerospace", - "aersopace", "aerospace", - "aestethic", "aesthetic", - "aethistic", "atheistic", - "affiliato", "affiliation", - "affinitiy", "affinity", - "affirmate", "affirmative", - "affliated", "affiliated", - "africanas", "africans", - "africanos", "africans", - "aggegrate", "aggregate", - "aggresive", "aggressive", - "agnosticm", "agnosticism", - "agregates", "aggregates", - "agreggate", "aggregate", - "agrentina", "argentina", - "agression", "aggression", - "agressive", "aggressive", - "agressvie", "aggressive", - "agruement", "argument", - "agruments", "arguments", - "agurement", "argument", - "ailenated", "alienated", - "airbourne", "airborne", - "aircrafts", "aircraft", - "airplance", "airplane", - "airrcraft", "aircraft", - "aksreddit", "askreddit", - "alcehmist", "alchemist", - "alchemsit", "alchemist", - "alchimest", "alchemist", - "alchmeist", "alchemist", - "alchoolic", "alcoholic", - "alcoholis", "alcoholics", - "alechmist", "alchemist", - "alegience", "allegiance", - "aleinated", "alienated", - "algoriths", "algorithms", - "algoritms", "algorithms", - "algorthim", "algorithm", - "algortihm", "algorithm", - "alignemnt", "alignment", - "alimunium", "aluminium", - "alingment", "alignment", - "allainces", "alliances", - "alledgely", "allegedly", - "allegence", "allegiance", - "alleivate", "alleviate", - "allievate", "alleviate", - "alliviate", "alleviate", - "allopones", "allophones", - "allthough", "although", - "almightly", "almighty", - "alocholic", "alcoholic", - "alogrithm", "algorithm", - "alphabeat", "alphabet", - "alrightey", "alrighty", - "alrightly", "alrighty", - "alrightty", "alrighty", - "alrington", "arlington", - "alrorythm", "algorithm", - "alterante", "alternate", - "alternatr", "alternator", - "althetics", "athletics", - "althought", "although", - "altruisim", "altruism", - "amateures", "amateurs", - "ambluance", "ambulance", - "ambuigity", "ambiguity", - "amendmant", "amendment", - "amercians", "americans", - "americain", "american", - "americams", "americas", - "americaps", "americas", - "americats", "americas", - "amibguity", "ambiguity", - "aminosity", "animosity", - "amrstrong", "armstrong", - "amublance", "ambulance", - "amunition", "ammunition", - "anachrist", "anarchist", - "analagous", "analogous", - "analitycs", "analytics", - "analtyics", "analytics", - "analyitcs", "analytics", - "analyseas", "analyses", - "analysees", "analyses", - "analysens", "analyses", - "analysise", "analyses", - "analystes", "analysts", - "analzying", "analyzing", - "anarchsim", "anarchism", - "anayltics", "analytics", - "anaylzing", "analyzing", - "ancedotal", "anecdotal", - "ancedotes", "anecdotes", - "ancestory", "ancestry", - "androgeny", "androgyny", - "androides", "androids", - "androidos", "androids", - "anecdotle", "anecdote", - "anecodtal", "anecdotal", - "anecodtes", "anecdotes", - "anectodal", "anecdotal", - "anectodes", "anecdotes", - "anedoctal", "anecdotal", - "anedoctes", "anecdotes", - "animostiy", "animosity", - "anitvirus", "antivirus", - "anlaytics", "analytics", - "anniversy", "anniversary", - "annointed", "anointed", - "annoucnes", "announces", - "annoyingy", "annoyingly", - "annoymous", "anonymous", - "annoynace", "annoyance", - "annyoance", "annoyance", - "anomisity", "animosity", - "anomolies", "anomalies", - "anomolous", "anomalous", - "anomynity", "anonymity", - "anomynous", "anonymous", - "anonimity", "anonymity", - "anonmyous", "anonymous", - "anonymoys", "anonymously", - "anorexiac", "anorexic", - "anorexica", "anorexia", - "anrachist", "anarchist", - "ansestors", "ancestors", - "antarctia", "antarctica", - "antennaes", "antennas", - "antiviurs", "antivirus", - "antivrius", "antivirus", - "antivuris", "antivirus", - "anwsering", "answering", - "anynomity", "anonymity", - "anynomous", "anonymous", - "aparthide", "apartheid", - "aparthied", "apartheid", - "apartmens", "apartments", - "apocalype", "apocalypse", - "apostrope", "apostrophe", - "apparenty", "apparently", - "appearane", "appearances", - "appenines", "apennines", - "apperance", "appearance", - "appetitie", "appetite", - "applaudes", "applause", - "applicato", "application", - "appreciae", "appreciate", - "apprentie", "apprentice", - "approachs", "approaches", - "apratheid", "apartheid", - "apsaragus", "asparagus", - "apsergers", "aspergers", - "aquainted", "acquainted", - "arbirtary", "arbitrary", - "arbritary", "arbitrary", - "arcehtype", "archetype", - "archetect", "architect", - "archetpye", "archetype", - "archetyps", "archetypes", - "architecs", "architects", - "archtypes", "archetypes", - "aregument", "argument", - "areospace", "aerospace", - "argessive", "aggressive", - "argeument", "argument", - "arguabley", "arguably", - "arguablly", "arguably", - "arguement", "argument", - "arguemnet", "argument", - "arguemnts", "arguments", - "argumeent", "argument", - "arhtritis", "arthritis", - "aribtrary", "arbitrary", - "ariplanes", "airplanes", - "aristolte", "aristotle", - "aristotel", "aristotle", - "aritfacts", "artifacts", - "arlignton", "arlington", - "arlingotn", "arlington", - "armistace", "armistice", - "armstorng", "armstrong", - "arpatheid", "apartheid", - "arthirtis", "arthritis", - "artifcats", "artifacts", - "artifical", "artificial", - "artillary", "artillery", - "arugement", "argument", - "arugments", "arguments", - "asapragus", "asparagus", - "asbestoes", "asbestos", - "asborbing", "absorbing", - "asburdity", "absurdity", - "ascendend", "ascended", - "ascneding", "ascending", - "ascnesion", "ascension", - "asethetic", "aesthetic", - "asnwering", "answering", - "asociated", "associated", - "assasined", "assassinated", - "assassian", "assassin", - "assassine", "assassinate", - "assasssin", "assassins", - "assaultes", "assaults", - "assembeld", "assembled", - "assembley", "assembly", - "assemblie", "assemble", - "assisnate", "assassinate", - "assistans", "assistants", - "assistsnt", "assistants", - "assmebled", "assembled", - "associato", "association", - "assoicate", "associate", - "asssasins", "assassins", - "assualted", "assaulted", - "assulated", "assaulted", - "asteorids", "asteroids", - "astericks", "asterisk", - "asteriods", "asteroids", - "astroanut", "astronaut", - "astronuat", "astronaut", - "astrounat", "astronaut", - "asuterity", "austerity", - "atempting", "attempting", - "atheltics", "athletics", - "atheneans", "athenians", - "athesitic", "atheistic", - "athetlics", "athletics", - "athiestic", "atheistic", - "athleticm", "athleticism", - "atmosphir", "atmospheric", - "atributed", "attributed", - "atributes", "attributes", - "atrifacts", "artifacts", - "atrillery", "artillery", - "atrittion", "attrition", - "attachmet", "attachments", - "attaindre", "attainder", - "attemting", "attempting", - "attemtped", "attempted", - "attendent", "attendant", - "attension", "attention", - "attirbute", "attribute", - "attirtion", "attrition", - "attmepted", "attempted", - "attractes", "attracts", - "attractin", "attraction", - "attributo", "attribution", - "attributs", "attributes", - "attritube", "attribute", - "auctionrs", "auctions", - "auidobook", "audiobook", - "auromated", "automated", - "australin", "australians", - "authroity", "authority", - "autoattak", "autoattack", - "autogrpah", "autograph", - "autonomos", "autonomous", - "auxillary", "auxiliary", - "avaialble", "available", - "availible", "available", - "avalaible", "available", - "avaliable", "available", - "averageed", "averaged", - "avialable", "available", - "awakenend", "awakened", - "awesomley", "awesomely", - "awkawrdly", "awkwardly", - "awnsering", "answering", - "bacehlors", "bachelors", - "bachelour", "bachelor", - "bachleors", "bachelors", - "bacholers", "bachelors", - "backdooor", "backdoor", - "backfeild", "backfield", - "backfiled", "backfield", - "backgroud", "background", - "backpakcs", "backpacks", - "badnwagon", "bandwagon", - "badnwidth", "bandwidth", - "balckjack", "blackjack", - "balcklist", "blacklist", - "balitmore", "baltimore", - "ballisitc", "ballistic", - "ballsitic", "ballistic", - "balsphemy", "blasphemy", - "bandiwdth", "bandwidth", - "bandwdith", "bandwidth", - "bandwidht", "bandwidth", - "bandwitdh", "bandwidth", - "bankrupcy", "bankruptcy", - "bankrupty", "bankruptcy", - "banruptcy", "bankruptcy", - "baordwalk", "boardwalk", - "barabrian", "barbarian", - "barbarain", "barbarian", - "barbarina", "barbarian", - "barcelets", "bracelets", - "barcleona", "barcelona", - "bareclona", "barcelona", - "barrackus", "barracks", - "bascially", "basically", - "bastardes", "bastards", - "bastardos", "bastards", - "bastardus", "bastards", - "bathrooom", "bathroom", - "batlimore", "baltimore", - "battailon", "battalion", - "battlaion", "battalion", - "beahviour", "behaviour", - "beauitful", "beautiful", - "beautifyl", "beautifully", - "becnhmark", "benchmark", - "becomeing", "becoming", - "becomming", "becoming", - "beehtoven", "beethoven", - "begginers", "beginners", - "beggining", "beginning", - "begininng", "beginning", - "beginnins", "beginnings", - "behaivors", "behaviors", - "behaivour", "behaviour", - "behavoirs", "behaviors", - "behavoiur", "behaviour", - "behvaiour", "behaviour", - "beleiving", "believing", - "beliveing", "believing", - "belssings", "blessings", - "bemusemnt", "bemusement", - "benchamrk", "benchmark", - "benchmars", "benchmarks", - "benedicat", "benedict", - "benedickt", "benedict", - "benghazhi", "benghazi", - "benghazzi", "benghazi", - "bergamont", "bergamot", - "berkelely", "berkeley", - "bersekrer", "berserker", - "berskerer", "berserker", - "beseiging", "besieging", - "bestialiy", "bestiality", - "beuatiful", "beautiful", - "biginning", "beginning", - "bigrading", "brigading", - "billbaord", "billboard", - "billboars", "billboards", - "binominal", "binomial", - "birgading", "brigading", - "birghtest", "brightest", - "birhtdays", "birthdays", - "bitcoints", "bitcoins", - "blackbery", "blackberry", - "blackhaws", "blackhawks", - "blackshit", "blacksmith", - "blanketts", "blankets", - "blapshemy", "blasphemy", - "blashpemy", "blasphemy", - "blaspehmy", "blasphemy", - "blasphmey", "blasphemy", - "blatanlty", "blatantly", - "blatimore", "baltimore", - "bleuberry", "blueberry", - "bleutooth", "bluetooth", - "blisteres", "blisters", - "blizzcoin", "blizzcon", - "blockchan", "blockchain", - "blockeras", "blockers", - "bloodbore", "bloodborne", - "boardband", "broadband", - "boardcast", "broadcast", - "bodyweigt", "bodyweight", - "bookamrks", "bookmarks", - "bookmakrs", "bookmarks", - "bookmarkd", "bookmarked", - "boradband", "broadband", - "boradcast", "broadcast", - "boradwalk", "boardwalk", - "bouregois", "bourgeois", - "bourgeios", "bourgeois", - "bourgoeis", "bourgeois", - "boyfirend", "boyfriend", - "boyfreind", "boyfriend", - "boyfriens", "boyfriends", - "brabarian", "barbarian", - "bracelona", "barcelona", - "braodband", "broadband", - "braodcast", "broadcast", - "brazilias", "brazilians", - "breakdows", "breakdowns", - "breserker", "berserker", - "bretheren", "brethren", - "bridaging", "brigading", - "brightern", "brighten", - "brigthest", "brightest", - "brilliany", "brilliantly", - "brithdays", "birthdays", - "broadwalk", "boardwalk", - "bruiseres", "bruisers", - "brunettte", "brunette", - "brusseles", "brussels", - "brussells", "brussels", - "brutailty", "brutality", - "brutallly", "brutally", - "buddhisim", "buddhism", - "buddihsts", "buddhists", - "buddishts", "buddhists", - "buhddists", "buddhists", - "buidlings", "buildings", - "bulidings", "buildings", - "burgunday", "burgundy", - "burgundry", "burgundy", - "burritoes", "burritos", - "burtality", "brutality", - "busineses", "business", - "businessa", "businessman", - "businesse", "businessmen", - "businesss", "businesses", - "bussiness", "business", - "buthcered", "butchered", - "butterlfy", "butterfly", - "cacausian", "caucasian", - "caclulate", "calculate", - "cacuasian", "caucasian", - "caculater", "calculator", - "cafeteira", "cafeteria", - "cafetiera", "cafeteria", - "caffeinne", "caffeine", - "calcualte", "calculate", - "californa", "california", - "caluclate", "calculate", - "calulated", "calculated", - "calulater", "calculator", - "cambirdge", "cambridge", - "cambrdige", "cambridge", - "cambrigde", "cambridge", - "camoflage", "camouflage", - "campagins", "campaigns", - "campaings", "campaigns", - "campiagns", "campaigns", - "campusers", "campuses", - "camrbidge", "cambridge", - "canadains", "canadians", - "candadate", "candidate", - "candidats", "candidates", - "cannister", "canister", - "cannoical", "canonical", - "canoncial", "canonical", - "capactior", "capacitor", - "capicator", "capacitor", - "capitalis", "capitals", - "caprenter", "carpenter", - "capsulers", "capsules", - "capsulets", "capsules", - "carachter", "character", - "cardbaord", "cardboard", - "cardborad", "cardboard", - "cardianls", "cardinals", - "cardnials", "cardinals", - "caridnals", "cardinals", - "carmalite", "carmelite", - "carnberry", "cranberry", - "carolinia", "carolina", - "carpetner", "carpenter", - "carptener", "carpenter", - "carribean", "caribbean", - "cartdrige", "cartridge", - "cartilege", "cartilage", - "cartirdge", "cartridge", - "cartrdige", "cartridge", - "cartrigde", "cartridge", - "casaulity", "causality", - "cashieres", "cashiers", - "cassawory", "cassowary", - "cassettte", "cassette", - "casuation", "causation", - "cataclsym", "cataclysm", - "cataclyms", "cataclysm", - "catacylsm", "cataclysm", - "catacyslm", "cataclysm", - "catalcysm", "cataclysm", - "catalgoue", "catalogue", - "cathderal", "cathedral", - "catherdal", "cathedral", - "cathloics", "catholics", - "cathredal", "cathedral", - "caucaisan", "caucasian", - "caucasain", "caucasian", - "causacian", "caucasian", - "causailty", "causality", - "celebirty", "celebrity", - "celebrato", "celebration", - "celebrite", "celebrities", - "celesital", "celestial", - "celestail", "celestial", - "cementary", "cemetery", - "cemetarey", "cemetery", - "cenitpede", "centipede", - "centepide", "centipede", - "centipeed", "centipede", - "centruies", "centuries", - "centuties", "centuries", - "cerebrawl", "cerebral", - "certanity", "certainty", - "certianty", "certainty", - "cesspoool", "cesspool", - "chairmain", "chairman", - "challange", "challenge", - "challengr", "challenger", - "challengs", "challenges", - "chameloen", "chameleon", - "champagen", "champagne", - "champange", "champagne", - "chandlure", "chandler", - "changable", "changeable", - "charactor", "character", - "chatedral", "cathedral", - "chatolics", "catholics", - "checkmeat", "checkmate", - "checkpoit", "checkpoints", - "chekcmate", "checkmate", - "chemestry", "chemistry", - "chemicaly", "chemically", - "chemsitry", "chemistry", - "chernboyl", "chernobyl", - "chernobly", "chernobyl", - "chernoybl", "chernobyl", - "chernyobl", "chernobyl", - "cheronbyl", "chernobyl", - "chidlfree", "childfree", - "chidlrens", "childrens", - "chihauhua", "chihuahua", - "chihuahau", "chihuahua", - "childbird", "childbirth", - "childerns", "childrens", - "childisch", "childish", - "childresn", "childrens", - "chirstian", "christian", - "chirstmas", "christmas", - "chiuhahua", "chihuahua", - "chlidfree", "childfree", - "chlidrens", "childrens", - "chocloate", "chocolate", - "chocoalte", "chocolate", - "chocolats", "chocolates", - "chocolste", "chocolates", - "cholocate", "chocolate", - "chrenobyl", "chernobyl", - "chrisitan", "christian", - "christain", "christian", - "christams", "christmas", - "chrsitian", "christian", - "chrsitmas", "christmas", - "churchers", "churches", - "cigaretts", "cigarettes", - "cigeratte", "cigarette", - "cilivians", "civilians", - "cilpboard", "clipboard", - "cilynders", "cylinders", - "circuitos", "circuits", - "ciriculum", "curriculum", - "cirticise", "criticise", - "civilains", "civilians", - "civillian", "civilian", - "classicos", "classics", - "classicus", "classics", - "classifiy", "classify", - "cleanisng", "cleansing", - "cleasning", "cleansing", - "clikcbait", "clickbait", - "clinicaly", "clinically", - "clipbaord", "clipboard", - "clitories", "clitoris", - "clitorios", "clitoris", - "clitorius", "clitoris", - "clucthing", "clutching", - "clutchign", "clutching", - "cluthcing", "clutching", - "coca cola", "coca-cola", - "cockatils", "cocktails", - "cocktials", "cocktails", - "cognizent", "cognizant", - "colateral", "collateral", - "collabore", "collaborate", - "collasped", "collapsed", - "collaspes", "collapses", - "colleauge", "colleague", - "collectes", "collects", - "collectie", "collective", - "collecton", "collection", - "collectos", "collectors", - "collegaue", "colleague", - "collegues", "colleagues", - "collisson", "collisions", - "collonade", "colonnade", - "collonies", "colonies", - "collpased", "collapsed", - "collpases", "collapses", - "colombina", "colombia", - "columbina", "columbia", - "comapnies", "companies", - "combatans", "combatants", - "combinato", "combination", - "combusion", "combustion", - "comestics", "cosmetics", - "comisions", "commissions", - "comission", "commission", - "comitting", "committing", - "commandes", "commands", - "commentar", "commentator", - "commentes", "commenters", - "commercie", "commerce", - "commision", "commission", - "commiteed", "committed", - "commiting", "committing", - "commitmet", "commitments", - "commments", "comments", - "commongly", "commonly", - "communiss", "communists", - "communite", "communities", - "communits", "communist", - "communsim", "communism", - "compaines", "companies", - "compalins", "complains", - "compalint", "compliant", - "comparisn", "comparisons", - "compeltes", "completes", - "competant", "competent", - "competend", "competed", - "competion", "competition", - "competive", "competitive", - "compilant", "compliant", - "compilare", "compiler", - "compilato", "compilation", - "compitent", "competent", - "complaind", "complained", - "complaing", "complaining", - "completen", "complement", - "completey", "completely", - "completin", "completion", - "complians", "complains", - "componant", "component", - "comprable", "comparable", - "compresas", "compress", - "compreses", "compress", - "compteurs", "computers", - "comptuers", "computers", - "computato", "computation", - "comradets", "comrades", - "comsetics", "cosmetics", - "conanical", "canonical", - "conatiner", "container", - "concelaed", "concealed", - "concelaer", "concealer", - "concelear", "concealer", - "concensus", "consensus", - "conceptos", "concepts", - "conceptul", "conceptual", - "concernig", "concerning", - "concertas", "concerts", - "concevied", "conceived", - "conciders", "considers", - "concieted", "conceited", - "concieved", "conceived", - "conclusie", "conclusive", - "concsious", "conscious", - "concurret", "concurrent", - "condamned", "condemned", - "condemend", "condemned", - "condemmed", "condemned", - "condemnig", "condemning", - "condenmed", "condemned", - "condesend", "condensed", - "condesned", "condensed", - "condmened", "condemned", - "conection", "connection", - "conenctor", "connector", - "conferene", "conferences", - "confessin", "confession", - "confideny", "confidently", - "confilcts", "conflicts", - "confimred", "confirmed", - "confirmas", "confirms", - "conflcits", "conflicts", - "confrimed", "confirmed", - "congitive", "cognitive", - "conlcuded", "concluded", - "connectes", "connects", - "connectit", "connecticut", - "connectos", "connectors", - "conquerer", "conqueror", - "consdider", "consider", - "consensul", "consensual", - "conserned", "concerned", - "consicous", "conscious", - "considerd", "considered", - "considert", "considerate", - "consisent", "consistent", - "consistes", "consists", - "consolato", "consolation", - "consolide", "consolidate", - "consonent", "consonant", - "constanly", "constantly", - "constanst", "constants", - "constanty", "constantly", - "constasnt", "constants", - "constitue", "constitutes", - "constrait", "constraints", - "construcs", "constructs", - "construde", "construed", - "construst", "constructs", - "constucts", "constructs", - "constured", "construed", - "consulant", "consultant", - "consultat", "consultant", - "consumate", "consummate", - "contactes", "contacts", - "contactos", "contacts", - "contagios", "contagious", - "containes", "contains", - "containig", "containing", - "containts", "contains", - "contemple", "contemplate", - "contendor", "contender", - "contentas", "contents", - "contentes", "contents", - "contentos", "contents", - "contestas", "contests", - "contestat", "contestants", - "contestes", "contests", - "contextes", "contexts", - "contextos", "contexts", - "contianer", "container", - "contibute", "contribute", - "contigent", "contingent", - "continant", "continental", - "continens", "continents", - "continous", "continuous", - "continuos", "continuous", - "continute", "continue", - "contiunal", "continual", - "contracto", "contraction", - "contribue", "contribute", - "contribuo", "contributor", - "controlas", "controls", - "controled", "controlled", - "controles", "controls", - "controlls", "controls", - "convenant", "covenant", - "convencen", "convenience", - "conveniet", "convenient", - "conversie", "converse", - "conversin", "conversions", - "convertie", "convertible", - "convertis", "converts", - "cooldwons", "cooldowns", - "coordinar", "coordinator", - "copenhagn", "copenhagen", - "coprorate", "corporate", - "copywrite", "copyright", - "corcodile", "crocodile", - "corparate", "corporate", - "corproate", "corporate", - "correclty", "correctly", - "correctin", "correction", - "correlato", "correlation", - "corridoor", "corridor", - "corruptin", "corruption", - "corssfire", "crossfire", - "corsshair", "crosshair", - "corsspost", "crosspost", - "coruching", "crouching", - "cosemtics", "cosmetics", - "costumise", "costumes", - "counciles", "councils", - "councills", "councils", - "councilos", "councils", - "countains", "contains", - "counteres", "counters", - "countires", "countries", - "courching", "crouching", - "courtesey", "courtesy", - "courtesty", "courtesy", - "coururier", "courier", - "coutnered", "countered", - "crapenter", "carpenter", - "creativey", "creatively", - "creedence", "credence", - "crhistmas", "christmas", - "cricketts", "crickets", - "criminaly", "criminally", - "critereon", "criterion", - "criterias", "criteria", - "criticaly", "critically", - "criticies", "criticise", - "criticisn", "criticising", - "critisice", "criticise", - "critisicm", "criticism", - "critising", "criticising", - "critisism", "criticism", - "critisize", "criticise", - "critizing", "criticizing", - "crosshiar", "crosshair", - "crossifre", "crossfire", - "crticised", "criticised", - "crusdaers", "crusaders", - "crutchers", "crutches", - "crystalls", "crystals", - "crystalus", "crystals", - "crystalys", "crystals", - "cuacasian", "caucasian", - "cuasality", "causality", - "culitvate", "cultivate", - "culturaly", "culturally", - "culturels", "cultures", - "curiostiy", "curiosity", - "curisoity", "curiosity", - "currenlty", "currently", - "curriculm", "curriculum", - "cursaders", "crusaders", - "custcenes", "cutscenes", - "cutsceens", "cutscenes", - "cutscence", "cutscene", - "cutsences", "cutscenes", - "cyclinder", "cylinder", - "cyclistes", "cyclists", - "cylindres", "cylinders", - "cynicisim", "cynicism", - "dahsboard", "dashboard", - "dalmation", "dalmatian", - "dangeroys", "dangerously", - "dashbaord", "dashboard", - "daugthers", "daughters", - "davantage", "advantage", - "deadlfits", "deadlifts", - "deadpoool", "deadpool", - "dealershp", "dealerships", - "deathmath", "deathmatch", - "decalring", "declaring", - "decendant", "descendant", - "decendent", "descendant", - "decipting", "depicting", - "deciption", "depiction", - "decisivie", "decisive", - "declarase", "declares", - "declarees", "declares", - "decoratie", "decorative", - "decoratin", "decorations", - "decpetion", "deception", - "decpetive", "deceptive", - "decribing", "describing", - "decsended", "descended", - "deductibe", "deductible", - "defaintly", "defiantly", - "defaltion", "deflation", - "defanitly", "defiantly", - "defeintly", "definitely", - "defendent", "defendant", - "defensese", "defenseless", - "defianlty", "defiantly", - "deficeint", "deficient", - "deficieny", "deficiency", - "deficites", "deficits", - "definance", "defiance", - "definatey", "definitely", - "definatly", "definitely", - "definetly", "definitely", - "definetyl", "definitely", - "definilty", "definitely", - "definitie", "definitive", - "definitin", "definitions", - "definitly", "definitely", - "definiton", "definition", - "definitve", "definite", - "definityl", "definitely", - "definltey", "definitely", - "defintaly", "defiantly", - "defintily", "definitely", - "defintion", "definition", - "defintley", "definitely", - "defitenly", "definitely", - "defitinly", "definitely", - "defitnaly", "defiantly", - "defitnely", "definitely", - "deflectin", "deflection", - "defnietly", "definitely", - "degeneret", "degenerate", - "degradato", "degradation", - "degradead", "degraded", - "degrassie", "degrasse", - "degrassse", "degrasse", - "deifnetly", "definitely", - "deifnitly", "definitely", - "deisgners", "designers", - "delagates", "delegates", - "delcaring", "declaring", - "delcining", "declining", - "delegatie", "delegate", - "delerious", "delirious", - "deleteing", "deleting", - "delfation", "deflation", - "deliveres", "delivers", - "deliverys", "delivers", - "delpoying", "deploying", - "demcorats", "democrats", - "deminsion", "dimension", - "democarcy", "democracy", - "democract", "democrat", - "demonstre", "demonstrate", - "denominar", "denominator", - "dentistas", "dentists", - "dentistes", "dentists", - "deomcrats", "democrats", - "deopsited", "deposited", - "deparment", "department", - "departmet", "departments", - "depciting", "depicting", - "depcition", "depiction", - "depection", "deception", - "depedency", "dependency", - "depicitng", "depicting", - "depiciton", "depiction", - "deplyoing", "deploying", - "depoisted", "deposited", - "depolying", "deploying", - "depositas", "deposits", - "deposites", "deposits", - "depositis", "deposits", - "depositos", "deposits", - "depostied", "deposited", - "depressie", "depressive", - "depressin", "depression", - "depserate", "desperate", - "depsoited", "deposited", - "descirbes", "describes", - "descision", "decision", - "desginers", "designers", - "desgining", "designing", - "desicions", "decisions", - "designade", "designated", - "designato", "designation", - "desingage", "disengage", - "desingers", "designers", - "desinging", "designing", - "desktopos", "desktops", - "desparate", "desperate", - "desperato", "desperation", - "despoited", "deposited", - "desriable", "desirable", - "dessigned", "designed", - "destinato", "destination", - "destoryed", "destroyed", - "destoryer", "destroyer", - "destroyes", "destroys", - "destructo", "destruction", - "destryoed", "destroyed", - "destryoer", "destroyer", - "desuction", "seduction", - "detailled", "detailed", - "detatched", "detached", - "detectivs", "detectives", - "deteriate", "deteriorate", - "determing", "determining", - "determins", "determines", - "developrs", "develops", - "diabetees", "diabetes", - "diablical", "diabolical", - "diagonaal", "diagonal", - "diagonsed", "diagnosed", - "diagonsis", "diagnosis", - "diagramas", "diagrams", - "diagramms", "diagrams", - "dialectes", "dialects", - "dialectos", "dialects", - "diarrheoa", "diarrhea", - "diasbling", "disabling", - "dichomoty", "dichotomy", - "dicovered", "discovered", - "dictaters", "dictates", - "dictionay", "dictionary", - "difenitly", "definitely", - "diferrent", "different", - "differene", "differences", - "differens", "differences", - "differeny", "differently", - "difficuly", "difficulty", - "diffucult", "difficult", - "dificulty", "difficulty", - "diganosed", "diagnosed", - "diganosis", "diagnosis", - "dimenions", "dimensions", - "dimention", "dimension", - "dimesnion", "dimension", - "diminishs", "diminishes", - "dinasours", "dinosaurs", - "dinosuars", "dinosaurs", - "dinsoaurs", "dinosaurs", - "dionsaurs", "dinosaurs", - "diphtongs", "diphthongs", - "dipthongs", "diphthongs", - "direcotry", "directory", - "directoty", "directory", - "directroy", "directory", - "disapears", "disappears", - "disaprity", "disparity", - "disastros", "disastrous", - "disatrous", "disastrous", - "disbaling", "disabling", - "disbeleif", "disbelief", - "disbelife", "disbelief", - "disciplen", "disciplines", - "disclamer", "disclaimer", - "disclosue", "disclosure", - "disconnet", "disconnect", - "discosure", "discourse", - "discoverd", "discovered", - "discovere", "discoveries", - "discredid", "discredited", - "discribed", "described", - "discribes", "describes", - "discussin", "discussion", - "diserable", "desirable", - "disgarees", "disagrees", - "disgiused", "disguised", - "disgusied", "disguised", - "disgustes", "disgusts", - "disgustos", "disgusts", - "disgustus", "disgusts", - "dishonesy", "dishonesty", - "dishonord", "dishonored", - "disicples", "disciples", - "dismantel", "dismantle", - "dismisals", "dismissal", - "disnegage", "disengage", - "dispairty", "disparity", - "dispalyed", "displayed", - "dispartiy", "disparity", - "dispenced", "dispensed", - "dispeners", "dispenser", - "displayes", "displays", - "disruptin", "disruption", - "dissapear", "disappear", - "dissarray", "disarray", - "dissmisal", "dismissal", - "disspiate", "dissipate", - "distincte", "distinctive", - "distrcits", "districts", - "distribue", "distributed", - "distrubed", "disturbed", - "distrupts", "distrust", - "disturben", "disturbance", - "diverisfy", "diversify", - "diveristy", "diversity", - "diverstiy", "diversity", - "dividened", "dividend", - "divinitiy", "divinity", - "doccument", "document", - "docrtines", "doctrines", - "docuhebag", "douchebag", - "dogdammit", "goddammit", - "dogfather", "godfather", - "dolphines", "dolphins", - "domecracy", "democracy", - "domecrats", "democrats", - "domiantes", "dominates", - "dominatin", "domination", - "dominaton", "domination", - "dominiant", "dominant", - "donwgrade", "downgrade", - "donwloads", "downloads", - "donwsides", "downsides", - "donwvoted", "downvoted", - "donwvotes", "downvotes", - "doublelit", "doublelift", - "doucehbag", "douchebag", - "downgarde", "downgrade", - "downlaods", "downloads", - "downloaad", "download", - "downovted", "downvoted", - "dravadian", "dravidian", - "drummless", "drumless", - "dsyphoria", "dysphoria", - "dsytopian", "dystopian", - "duaghters", "daughters", - "duplicats", "duplicates", - "durabiliy", "durability", - "dynamicus", "dynamics", - "dypshoria", "dysphoria", - "dyshporia", "dysphoria", - "dysoptian", "dystopian", - "dysphoira", "dysphoria", - "dysphroia", "dysphoria", - "dyspohria", "dysphoria", - "dyspotian", "dystopian", - "dystopain", "dystopian", - "dystpoian", "dystopian", - "eachohter", "eachother", - "eachotehr", "eachother", - "eachtoher", "eachother", - "earpluggs", "earplugs", - "earthboud", "earthbound", - "eastwoood", "eastwood", - "eastwoord", "eastwood", - "ecclectic", "eclectic", - "ecomonics", "economics", - "edficient", "deficient", - "effecient", "efficient", - "efficeint", "efficient", - "efficency", "efficiency", - "efficieny", "efficiency", - "effulence", "effluence", - "egalitara", "egalitarian", - "egpytians", "egyptians", - "egyptains", "egyptians", - "egytpians", "egyptians", - "ehtically", "ethically", - "ehtnicity", "ethnicity", - "eighteeen", "eighteen", - "eitquette", "etiquette", - "ejacualte", "ejaculate", - "electivre", "elective", - "electorns", "electrons", - "electrial", "electrical", - "electricy", "electricity", - "electroal", "electoral", - "elementay", "elementary", - "elepahnts", "elephants", - "eliminase", "eliminates", - "eliminato", "elimination", - "ellignton", "ellington", - "ellingotn", "ellington", - "eloquenty", "eloquently", - "elsehwere", "elsewhere", - "emapthize", "empathize", - "embarress", "embarrassed", - "emmisarry", "emissary", - "emmisions", "emissions", - "emmitting", "emitting", - "empahsize", "emphasize", - "emperical", "empirical", - "emphaised", "emphasised", - "emphatize", "empathize", - "emphazise", "emphasize", - "emphysyma", "emphysema", - "empitness", "emptiness", - "employeer", "employer", - "employeur", "employer", - "empolyees", "employees", - "emtpiness", "emptiness", - "emualtion", "emulation", - "enahncing", "enhancing", - "enchantig", "enchanting", - "enclousre", "enclosure", - "enclsoure", "enclosure", - "encolsure", "enclosure", - "encompase", "encompass", - "enconding", "encoding", - "encounted", "encountered", - "encrpyted", "encrypted", - "encrytped", "encrypted", - "encyrpted", "encrypted", - "endangerd", "endangered", - "enevlopes", "envelopes", - "enforcees", "enforces", - "engagemet", "engagements", - "engagment", "engagement", - "engieneer", "engineer", - "engineeer", "engineer", - "engineerd", "engineered", - "enhacning", "enhancing", - "enhanceds", "enhances", - "enligthen", "enlighten", - "enourmous", "enormous", - "ensconsed", "ensconced", - "enthicity", "ethnicity", - "enthusiam", "enthusiasm", - "enthusiat", "enthusiast", - "entirelly", "entirely", - "entitlied", "entitled", - "enveloppe", "envelope", - "epidsodes", "episodes", - "epilepsey", "epilepsy", - "epiphanny", "epiphany", - "episonage", "espionage", - "epscially", "specially", - "epsionage", "espionage", - "eqautions", "equations", - "equialent", "equivalent", - "equivalet", "equivalents", - "ermington", "remington", - "erroenous", "erroneous", - "escalatie", "escalate", - "escalatin", "escalation", - "esitmated", "estimated", - "esitmates", "estimates", - "eslewhere", "elsewhere", - "especialy", "especially", - "espianoge", "espionage", - "espinoage", "espionage", - "espoinage", "espionage", - "esponiage", "espionage", - "espressso", "espresso", - "essencial", "essential", - "essentail", "essential", - "essentias", "essentials", - "essentual", "essential", - "essesital", "essential", - "estiamted", "estimated", - "estiamtes", "estimates", - "estimatin", "estimation", - "ethcially", "ethically", - "ethincity", "ethnicity", - "ethnicaly", "ethnically", - "ethniticy", "ethnicity", - "etmyology", "etymology", - "euclidian", "euclidean", - "euorpeans", "europeans", - "euphoriac", "euphoric", - "euphorica", "euphoria", - "europenas", "europeans", - "europians", "europeans", - "eurpoeans", "europeans", - "evangelia", "evangelical", - "evelation", "elevation", - "evenlopes", "envelopes", - "eventally", "eventually", - "eventualy", "eventually", - "everthing", "everything", - "evertyime", "everytime", - "everwhere", "everywhere", - "everyoens", "everyones", - "everyteim", "everytime", - "everytiem", "everytime", - "everyting", "everything", - "eveyrones", "everyones", - "evreyones", "everyones", - "evreytime", "everytime", - "exagerate", "exaggerate", - "exahusted", "exhausted", - "exapnsive", "expansive", - "exauhsted", "exhausted", - "excahnges", "exchanges", - "excecuted", "executed", - "excecutes", "executes", - "excellant", "excellent", - "excercise", "exercise", - "excerised", "exercised", - "excerises", "exercises", - "exceuting", "executing", - "exchnages", "exchanges", - "exclsuive", "exclusive", - "excludeds", "excludes", - "exclusivs", "exclusives", - "exclusivy", "exclusivity", - "excpetion", "exception", - "exculding", "excluding", - "exculsion", "exclusion", - "exculsive", "exclusive", - "execising", "exercising", - "execption", "exception", - "exectuing", "executing", - "exectuion", "execution", - "exectuive", "executive", - "executabe", "executable", - "exepmtion", "exemption", - "exerbated", "exacerbated", - "exercices", "exercise", - "exerciese", "exercises", - "exercizes", "exercise", - "exersices", "exercises", - "exhasuted", "exhausted", - "exhaustin", "exhaustion", - "exhibites", "exhibits", - "exhibitin", "exhibition", - "exhibtion", "exhibition", - "exhuasted", "exhausted", - "exibition", "exhibition", - "existance", "existence", - "existenta", "existential", - "existince", "existence", - "existnace", "existence", - "exlcuding", "excluding", - "exlcusion", "exclusion", - "exlcusive", "exclusive", - "exlpoding", "exploding", - "exlporers", "explorers", - "exlposion", "explosion", - "exonorate", "exonerate", - "expalined", "explained", - "expanisve", "expansive", - "expatriot", "expatriate", - "expectany", "expectancy", - "expection", "exception", - "expemtion", "exemption", - "experimet", "experiments", - "explaines", "explains", - "explainig", "explaining", - "explaning", "explaining", - "expliciet", "explicit", - "explicity", "explicitly", - "explictly", "explicitly", - "explioted", "exploited", - "explodeds", "explodes", - "exploites", "exploits", - "explorare", "explorer", - "explotied", "exploited", - "expolding", "exploding", - "expolited", "exploited", - "expolsion", "explosion", - "expolsive", "explosive", - "expressie", "expressive", - "expressin", "expression", - "exsitance", "existence", - "extention", "extension", - "exteriour", "exterior", - "extermely", "extremely", - "extermism", "extremism", - "extermist", "extremist", - "externaly", "externally", - "extractin", "extraction", - "extrapole", "extrapolate", - "extreemly", "extremely", - "extremers", "extremes", - "extremley", "extremely", - "extrotion", "extortion", - "eyeballls", "eyeballs", - "eyebrowes", "eyebrows", - "eyebrowns", "eyebrows", - "eyesahdow", "eyeshadow", - "eyeshdaow", "eyeshadow", - "eygptians", "egyptians", - "eytmology", "etymology", - "faceboook", "facebook", - "faciliate", "facilitate", - "facilites", "facilities", - "facilitiy", "facility", - "facinated", "fascinated", - "facutally", "factually", - "familiair", "familiar", - "familiare", "familiarize", - "familiary", "familiarity", - "familliar", "familiar", - "fanaticas", "fanatics", - "fanaticos", "fanatics", - "fanaticus", "fanatics", - "fanatsies", "fantasies", - "fanatsize", "fantasize", - "fandation", "foundation", - "fanservie", "fanservice", - "fantazise", "fantasize", - "farenheit", "fahrenheit", - "fascistes", "fascists", - "fashoined", "fashioned", - "favorties", "favorites", - "favoruite", "favourite", - "favourits", "favourites", - "favourtie", "favourite", - "fedreally", "federally", - "feminisim", "feminism", - "feminsits", "feminists", - "femminist", "feminist", - "fesitvals", "festivals", - "fetishers", "fetishes", - "fightings", "fighting", - "filetimes", "lifetimes", - "filiament", "filament", - "filmmakes", "filmmakers", - "fingernal", "fingernails", - "flashligt", "flashlight", - "flavorade", "flavored", - "flavoures", "flavours", - "flavourus", "flavours", - "flawlessy", "flawlessly", - "flexibily", "flexibility", - "fluctaute", "fluctuate", - "flucutate", "fluctuate", - "fluttersy", "fluttershy", - "follwoing", "following", - "foootball", "football", - "forcefuly", "forcefully", - "forcibley", "forcibly", - "forciblly", "forcibly", - "forearmes", "forearms", - "foreginer", "foreigner", - "foregroud", "foreground", - "foreinger", "foreigner", - "forgeiner", "foreigner", - "forgiener", "foreigner", - "forgivens", "forgiveness", - "foriegner", "foreigner", - "forigener", "foreigner", - "formerlly", "formerly", - "formualte", "formulate", - "formulaes", "formulas", - "formulars", "formulas", - "forntline", "frontline", - "forntpage", "frontpage", - "fortuante", "fortunate", - "forumlate", "formulate", - "foundatin", "foundations", - "fourteeen", "fourteen", - "fractales", "fractals", - "fractalis", "fractals", - "fractalus", "fractals", - "fragement", "fragment", - "fragmenot", "fragment", - "franchies", "franchise", - "francsico", "francisco", - "franscico", "francisco", - "frecklers", "freckles", - "freedomes", "freedoms", - "freestlye", "freestyle", - "freesytle", "freestyle", - "fremented", "fermented", - "freqeuncy", "frequency", - "frequence", "frequencies", - "friendlis", "friendlies", - "frightend", "frightened", - "fromation", "formation", - "frontapge", "frontpage", - "frontilne", "frontline", - "frustrato", "frustration", - "frustrats", "frustrates", - "fucntions", "functions", - "fullscren", "fullscreen", - "funcitons", "functions", - "functiong", "functioning", - "functtion", "function", - "furiosuly", "furiously", - "furiuosly", "furiously", - "futuristc", "futuristic", - "gagnsters", "gangsters", - "galations", "galatians", - "galdiator", "gladiator", - "gallaxies", "galaxies", - "garanteed", "guaranteed", - "garantees", "guarantees", - "garuantee", "guarantee", - "gatherins", "gatherings", - "gauntelts", "gauntlets", - "gauntlent", "gauntlet", - "gaurantee", "guarantee", - "gaurentee", "guarantee", - "genatilia", "genitalia", - "geneology", "genealogy", - "generalbs", "generals", - "generalis", "generals", - "generaste", "generates", - "generatie", "generate", - "generatin", "generations", - "generatos", "generators", - "genitaila", "genitalia", - "genitales", "genitals", - "genitalis", "genitals", - "geniunely", "genuinely", - "gentailia", "genitalia", - "gentelmen", "gentlemen", - "gentialia", "genitalia", - "genuienly", "genuinely", - "genuinley", "genuinely", - "geogrpahy", "geography", - "germaniac", "germanic", - "geurrilla", "guerrilla", - "gimmickey", "gimmicky", - "gimmickly", "gimmicky", - "girlfried", "girlfriend", - "goalkeepr", "goalkeeper", - "godafther", "godfather", - "godspeeed", "godspeed", - "goegraphy", "geography", - "goldfisch", "goldfish", - "goosebums", "goosebumps", - "gorvement", "government", - "govemrent", "government", - "govenment", "government", - "goverance", "governance", - "goveremnt", "government", - "goverment", "government", - "govermetn", "government", - "govermnet", "government", - "governmet", "governments", - "govorment", "government", - "govrement", "government", - "gracefull", "graceful", - "gracefuly", "gracefully", - "graduaste", "graduates", - "graduatin", "graduation", - "grahpical", "graphical", - "grativate", "gravitate", - "graudally", "gradually", - "graudates", "graduates", - "greenalnd", "greenland", - "grenaders", "grenades", - "grpahical", "graphical", - "guadulupe", "guadalupe", - "guaranted", "guaranteed", - "guarantes", "guarantees", - "guardains", "guardians", - "guarentee", "guarantee", - "guaridans", "guardians", - "guatamala", "guatemala", - "guerrilas", "guerrillas", - "guradians", "guardians", - "guranteed", "guaranteed", - "gurantees", "guarantees", - "gutiarist", "guitarist", - "habsbourg", "habsburg", - "hairstlye", "hairstyle", - "hairsytle", "hairstyle", - "halarious", "hilarious", - "hambruger", "hamburger", - "hamburges", "hamburgers", - "hamphsire", "hampshire", - "hamsphire", "hampshire", - "handboook", "handbook", - "handedley", "handedly", - "handedlly", "handedly", - "handicape", "handicapped", - "hapmshire", "hampshire", - "happended", "happened", - "happenend", "happened", - "happenned", "happened", - "harasment", "harassment", - "hardenend", "hardened", - "hardwoord", "hardwood", - "haristyle", "hairstyle", - "harrasing", "harassing", - "harrassed", "harassed", - "harrasses", "harassed", - "hdinsight", "hindsight", - "headahces", "headaches", - "headhpone", "headphone", - "headshoot", "headshot", - "healither", "healthier", - "healtheir", "healthier", - "healthiet", "healthiest", - "healthire", "healthier", - "heapdhone", "headphone", - "hedgehoog", "hedgehog", - "hedgehorg", "hedgehog", - "heightend", "heightened", - "heirarchy", "hierarchy", - "herculase", "hercules", - "herculeas", "hercules", - "herculees", "hercules", - "herculeus", "hercules", - "heriarchy", "hierarchy", - "hesistant", "hesitant", - "hesistate", "hesitate", - "hesitatin", "hesitation", - "hieroglph", "hieroglyph", - "highschol", "highschool", - "hindisght", "hindsight", - "hindrence", "hindrance", - "hinduisim", "hinduism", - "hinduisum", "hinduism", - "hipsanics", "hispanics", - "hirearchy", "hierarchy", - "hirsohima", "hiroshima", - "hispancis", "hispanics", - "hitboxers", "hitboxes", - "hoepfully", "hopefully", - "holocasut", "holocaust", - "holocuast", "holocaust", - "homeonwer", "homeowner", - "homeopaty", "homeopathy", - "homewolrd", "homeworld", - "homewoner", "homeowner", - "homewrold", "homeworld", - "homogenes", "homogeneous", - "homosexul", "homosexuals", - "hopelessy", "hopelessly", - "hopsitals", "hospitals", - "horishima", "hiroshima", - "horizones", "horizons", - "horizonts", "horizons", - "horrendos", "horrendous", - "horribley", "horribly", - "horriblly", "horribly", - "horrifing", "horrifying", - "hositlity", "hostility", - "hospitaly", "hospitality", - "hosptials", "hospitals", - "hourgalss", "hourglass", - "hourlgass", "hourglass", - "househols", "households", - "humanitis", "humanities", - "humanoind", "humanoid", - "humiditiy", "humidity", - "hunagrian", "hungarian", - "hurriance", "hurricane", - "hurricans", "hurricanes", - "husbandos", "husbands", - "hydraluic", "hydraulic", - "hydropile", "hydrophile", - "hydropobe", "hydrophobe", - "hydrualic", "hydraulic", - "hyopcrite", "hypocrite", - "hypcorite", "hypocrite", - "hyperoble", "hyperbole", - "hypocracy", "hypocrisy", - "hypocrasy", "hypocrisy", - "hypocricy", "hypocrisy", - "hypocriet", "hypocrite", - "hypocrits", "hypocrites", - "hyporcite", "hypocrite", - "hypothess", "hypotheses", - "hyprocisy", "hypocrisy", - "hyprocite", "hypocrite", - "hyrdation", "hydration", - "hyrdaulic", "hydraulic", - "hysterica", "hysteria", - "hysteriia", "hysteria", - "iburpofen", "ibuprofen", - "icleandic", "icelandic", - "icongnito", "incognito", - "idealisim", "idealism", - "idealistc", "idealistic", - "identifer", "identifier", - "identifiy", "identify", - "ideologis", "ideologies", - "ignornace", "ignorance", - "illegales", "illegals", - "illegalis", "illegals", - "illegalls", "illegals", - "illnesess", "illnesses", - "illsuions", "illusions", - "illuminai", "illuminati", - "imagenary", "imaginary", - "imaginery", "imaginary", - "imaptient", "impatient", - "imigrated", "emigrated", - "immensley", "immensely", - "immerisve", "immersive", - "immesnely", "immensely", - "immidiate", "immediate", - "immigrato", "immigration", - "immitated", "imitated", - "immitator", "imitator", - "immobilie", "immobile", - "immobille", "immobile", - "immobilze", "immobile", - "immortaly", "immortality", - "immserive", "immersive", - "impaitent", "impatient", - "imparital", "impartial", - "impedence", "impedance", - "implantes", "implants", - "implicati", "implicit", - "impliciet", "implicit", - "implicity", "implicitly", - "impliment", "implement", - "implusive", "impulsive", - "importamt", "important", - "importend", "imported", - "imporving", "improving", - "impossibe", "impossible", - "imprefect", "imperfect", - "impressin", "impressions", - "imprioned", "imprisoned", - "improbabe", "improbable", - "impulisve", "impulsive", - "impuslive", "impulsive", - "imrpoving", "improving", - "inadequet", "inadequate", - "inadquate", "inadequate", - "inaugures", "inaugurates", - "inbalance", "imbalance", - "inbeetwen", "between", - "inbetween", "between", - "inbewteen", "between", - "incarnato", "incarnation", - "incgonito", "incognito", - "inclinato", "inclination", - "includeds", "includes", - "incoginto", "incognito", - "incongito", "incognito", - "incorpore", "incorporate", - "incpetion", "inception", - "incredibe", "incredible", - "incrediby", "incredibly", - "inculding", "including", - "incunabla", "incunabula", - "indicaste", "indicates", - "indicatie", "indicative", - "indicence", "incidence", - "indicents", "incidents", - "indigenos", "indigenous", - "indirecty", "indirectly", - "indisious", "insidious", - "individul", "individual", - "individus", "individuals", - "indoensia", "indonesia", - "indoneisa", "indonesia", - "indutrial", "industrial", - "inersting", "inserting", - "inexpense", "inexpensive", - "infallibe", "infallible", - "inferioir", "inferior", - "inferiour", "inferior", - "infestato", "infestation", - "infiltrar", "infiltrator", - "infinitey", "infinity", - "infinitie", "infinite", - "infinitiy", "infinity", - "infinitly", "infinity", - "inflatabe", "inflatable", - "influense", "influences", - "influenta", "influential", - "informate", "informative", - "infraread", "infrared", - "ingeniuty", "ingenuity", - "ingeunity", "ingenuity", - "ingocnito", "incognito", - "ingorance", "ignorance", - "inguenity", "ingenuity", - "inhabitat", "inhabitants", - "inheirted", "inherited", - "inhertied", "inherited", - "initailly", "initially", - "initalese", "initialese", - "initaling", "initialing", - "initalise", "initialise", - "initalism", "initialism", - "initalize", "initialize", - "initalled", "initialled", - "initation", "initiation", - "initiales", "initials", - "initiatie", "initiatives", - "initiatin", "initiation", - "initiatve", "initiate", - "injustics", "injustices", - "inlcuding", "including", - "inmigrant", "immigrant", - "innoucous", "innocuous", - "innovatin", "innovations", - "innovatve", "innovate", - "inpection", "inception", - "inpending", "impending", - "inproving", "improving", - "inpsector", "inspector", - "inpsiring", "inspiring", - "inquisito", "inquisition", - "inquisitr", "inquisitor", - "inresting", "inserting", - "insanelly", "insanely", - "insepctor", "inspector", - "insidiuos", "insidious", - "insipring", "inspiring", - "insluated", "insulated", - "inspectin", "inspection", - "instabilt", "instability", - "installes", "installs", - "installus", "installs", - "instering", "inserting", - "insticnts", "instincts", - "institude", "instituted", - "instituto", "institution", - "insualted", "insulated", - "insurence", "insurance", - "insurgeny", "insurgency", - "integirty", "integrity", - "integraal", "integral", - "integrade", "integrated", - "integrato", "integration", - "intenisty", "intensity", - "intensley", "intensely", - "interacte", "interactive", - "interents", "internets", - "interesat", "interest", - "interesst", "interests", - "interewbs", "interwebs", - "interfase", "interfaces", - "interfeer", "interfere", - "interfers", "interferes", - "intergate", "integrate", - "intergity", "integrity", - "interiour", "interior", - "internest", "internets", - "interpert", "interpret", - "interprut", "interrupt", - "interrups", "interrupts", - "interstae", "interstate", - "interveen", "intervene", - "intervied", "interviewed", - "intervier", "interviewer", - "intervies", "interviews", - "intesnely", "intensely", - "intesnity", "intensity", - "intestins", "intestines", - "intialize", "initialize", - "inticrate", "intricate", - "intimidad", "intimidated", - "intircate", "intricate", - "intiution", "intuition", - "intiutive", "intuitive", - "intorduce", "introduce", - "intorvert", "introvert", - "intracite", "intricate", - "intrduced", "introduced", - "intregity", "integrity", - "intrenets", "internets", - "intrepret", "interpret", - "intrerupt", "interrupt", - "intrewebs", "interwebs", - "intrinisc", "intrinsic", - "intrisinc", "intrinsic", - "intrisnic", "intrinsic", - "intriuged", "intrigued", - "introdued", "introduced", - "introduse", "introduces", - "introvers", "introverts", - "intruiged", "intrigued", - "intrument", "instrument", - "inutition", "intuition", - "inutitive", "intuitive", - "invaderas", "invaders", - "invalidas", "invalidates", - "inventios", "inventions", - "investige", "investigate", - "investmet", "investments", - "invincibe", "invincible", - "invloving", "involving", - "invovling", "involving", - "ipubrofen", "ibuprofen", - "iranianos", "iranians", - "irelevent", "irrelevant", - "ironicaly", "ironically", - "irritatie", "irritate", - "irritatin", "irritation", - "isalmists", "islamists", - "isalnders", "islanders", - "islamiskt", "islamist", - "islamsits", "islamists", - "islmaists", "islamists", - "isntaller", "installer", - "isntances", "instances", - "isntantly", "instantly", - "israelies", "israelis", - "israelits", "israelis", - "italianas", "italians", - "italianos", "italians", - "jailbrake", "jailbreak", - "jalibreak", "jailbreak", - "jamaicain", "jamaican", - "jersualem", "jerusalem", - "jeruselam", "jerusalem", - "jeruslaem", "jerusalem", - "journalis", "journals", - "judegment", "judgement", - "judgemant", "judgemental", - "judisuary", "judiciary", - "jugdement", "judgement", - "juggernat", "juggernaut", - "juvenille", "juvenile", - "keneysian", "keynesian", - "kentuckey", "kentucky", - "kenyesian", "keynesian", - "keybaords", "keyboards", - "keyensian", "keynesian", - "keyesnian", "keynesian", - "keynseian", "keynesian", - "keysenian", "keynesian", - "kilometes", "kilometers", - "kindapped", "kidnapped", - "kncokback", "knockback", - "knoweldge", "knowledge", - "knowlegde", "knowledge", - "konckback", "knockback", - "kryptonie", "kryptonite", - "labirynth", "labyrinth", - "laboratoy", "laboratory", - "laboreres", "laborers", - "labratory", "laboratory", - "labriynth", "labyrinth", - "labryinth", "labyrinth", - "labyrnith", "labyrinth", - "landscaps", "landscapes", - "landscspe", "landscapes", - "langauges", "languages", - "languague", "language", - "lanuchers", "launchers", - "lanugages", "languages", - "larington", "arlington", - "latitudie", "latitude", - "lattitude", "latitude", - "laucnhers", "launchers", - "laucnhing", "launching", - "launchign", "launching", - "laybrinth", "labyrinth", - "lebanesse", "lebanese", - "leceister", "leicester", - "leciester", "leicester", - "legitmate", "legitimate", - "legnedary", "legendary", - "lesbianas", "lesbians", - "lesbianus", "lesbians", - "letivicus", "leviticus", - "leutenant", "lieutenant", - "levaithan", "leviathan", - "levellign", "levelling", - "levetated", "levitated", - "levetates", "levitates", - "levicitus", "leviticus", - "levleling", "levelling", - "lfiesteal", "lifesteal", - "liberales", "liberals", - "liberalim", "liberalism", - "liberalis", "liberals", - "liberatin", "liberation", - "libraires", "libraries", - "liecester", "leicester", - "lieuenant", "lieutenant", - "lieutenat", "lieutenant", - "lifespawn", "lifespan", - "lifestlye", "lifestyle", - "lighnting", "lightning", - "lightnign", "lightning", - "ligthning", "lightning", - "ligthroom", "lightroom", - "lingerine", "lingerie", - "lispticks", "lipsticks", - "listenend", "listened", - "literarly", "literary", - "literarry", "literary", - "literatre", "literate", - "literatue", "literate", - "literture", "literature", - "lithaunia", "lithuania", - "lithuaina", "lithuania", - "lithuiana", "lithuania", - "lithunaia", "lithuania", - "litigatin", "litigation", - "lituhania", "lithuania", - "liveprool", "liverpool", - "livestrem", "livestream", - "lobbysits", "lobbyists", - "lockscren", "lockscreen", - "logisitcs", "logistics", - "logsitics", "logistics", - "loiusiana", "louisiana", - "lollipoop", "lollipop", - "louisvile", "louisville", - "luanchers", "launchers", - "luanching", "launching", - "lubicrant", "lubricant", - "lubircant", "lubricant", - "ludcrious", "ludicrous", - "ludricous", "ludicrous", - "lunaticos", "lunatics", - "lunaticus", "lunatics", - "macaronni", "macaroni", - "maestries", "masteries", - "magainzes", "magazines", - "magensium", "magnesium", - "magincian", "magician", - "magintude", "magnitude", - "magneisum", "magnesium", - "magnesuim", "magnesium", - "magnifine", "magnificent", - "mainfesto", "manifesto", - "mainfests", "manifests", - "mainstrem", "mainstream", - "maintaing", "maintaining", - "maintance", "maintenance", - "maintians", "maintains", - "mairjuana", "marijuana", - "malasyian", "malaysian", - "malayisan", "malaysian", - "malaysain", "malaysian", - "maletonin", "melatonin", - "maltesian", "maltese", - "malyasian", "malaysian", - "managable", "manageable", - "managment", "management", - "mandarian", "mandarin", - "mandarijn", "mandarin", - "mandarion", "mandarin", - "maneouvre", "manoeuvre", - "maneuveur", "maneuver", - "maneveurs", "maneuvers", - "manfiesto", "manifesto", - "manfiests", "manifests", - "mangesium", "magnesium", - "mangitude", "magnitude", - "manouvers", "maneuvers", - "mantained", "maintained", - "manuevers", "maneuvers", - "maraudeur", "marauder", - "marevlous", "marvelous", - "margarent", "margaret", - "margarite", "margaret", - "marginaal", "marginal", - "marginaly", "marginally", - "marijauna", "marijuana", - "marineras", "mariners", - "marineris", "mariners", - "marineros", "mariners", - "marjiuana", "marijuana", - "marjority", "majority", - "marmelade", "marmalade", - "marrtyred", "martyred", - "massagens", "massages", - "massivley", "massively", - "masteires", "masteries", - "mastereis", "masteries", - "masterise", "masteries", - "mastermid", "mastermind", - "mastieres", "masteries", - "masturbae", "masturbated", - "materiaal", "material", - "matierals", "materials", - "mattreses", "mattress", - "mayalsian", "malaysian", - "maylasian", "malaysian", - "mccarthey", "mccarthy", - "mecahnics", "mechanics", - "mecernary", "mercenary", - "mechancis", "mechanics", - "mechanims", "mechanism", - "mechaninc", "mechanic", - "mechansim", "mechanism", - "medicince", "medicine", - "mediciney", "mediciny", - "meditatie", "meditate", - "meditatin", "meditation", - "megathred", "megathread", - "melanotin", "melatonin", - "melborune", "melbourne", - "melbounre", "melbourne", - "membrance", "membrane", - "menstraul", "menstrual", - "menstural", "menstrual", - "mensutral", "menstrual", - "mentiones", "mentions", - "mercanery", "mercenary", - "merhcants", "merchants", - "messagers", "messages", - "messanger", "messenger", - "metabloic", "metabolic", - "metalurgy", "metallurgy", - "methaphor", "metaphor", - "methapors", "metaphors", - "methodoly", "methodology", - "metropols", "metropolis", - "mexicanas", "mexicans", - "mexicants", "mexicans", - "mexicanus", "mexicans", - "michellle", "michelle", - "micorwave", "microwave", - "micoscopy", "microscopy", - "microphen", "microphone", - "migrantes", "migrants", - "migrianes", "migraines", - "milawukee", "milwaukee", - "milennium", "millennium", - "milestons", "milestones", - "militians", "militias", - "millenial", "millennial", - "millenian", "millennia", - "millenium", "millennium", - "millionar", "millionaire", - "millitary", "military", - "miluwakee", "milwaukee", - "milwakuee", "milwaukee", - "milwuakee", "milwaukee", - "mindcarck", "mindcrack", - "mindlessy", "mindlessly", - "minerales", "minerals", - "minisclue", "miniscule", - "miniscuel", "miniscule", - "ministery", "ministry", - "minisucle", "miniscule", - "minitaure", "miniature", - "minituare", "miniature", - "minneosta", "minnesota", - "minnestoa", "minnesota", - "minsicule", "miniscule", - "minsiters", "ministers", - "minstries", "ministries", - "miraculos", "miraculous", - "mircowave", "microwave", - "mirrorred", "mirrored", - "miserabel", "miserable", - "mispelled", "misspelled", - "misreable", "miserable", - "misreably", "miserably", - "missisipi", "mississippi", - "missonary", "missionary", - "missourri", "missouri", - "misspelld", "misspelled", - "mobilitiy", "mobility", - "moderatey", "moderately", - "moderatin", "moderation", - "modifires", "modifiers", - "moelcules", "molecules", - "moleclues", "molecules", - "molestare", "molester", - "molestato", "molestation", - "molesterd", "molested", - "monestary", "monastery", - "monitores", "monitors", - "monolgoue", "monologue", - "monolight", "moonlight", - "monolouge", "monologue", - "monopolis", "monopolies", - "monopolly", "monopoly", - "monopoloy", "monopoly", - "monserrat", "montserrat", - "monstorus", "monstrous", - "monstruos", "monstrous", - "montanous", "mountainous", - "montoring", "monitoring", - "monumnets", "monuments", - "moratlity", "mortality", - "morbidley", "morbidly", - "morgatges", "mortgages", - "morgtages", "mortgages", - "morisette", "morissette", - "mormonsim", "mormonism", - "morroccan", "moroccan", - "mortailty", "mortality", - "mosquitto", "mosquito", - "motivatie", "motivate", - "motivatin", "motivations", - "motorcyce", "motorcycles", - "motorolja", "motorola", - "motoroloa", "motorola", - "moustahce", "moustache", - "movepseed", "movespeed", - "mozzarela", "mozzarella", - "mucisians", "musicians", - "mulitated", "mutilated", - "mulitples", "multiples", - "multipled", "multiplied", - "multplies", "multiples", - "murdererd", "murdered", - "muscially", "musically", - "muscician", "musician", - "musculair", "muscular", - "mushrooom", "mushroom", - "musicains", "musicians", - "mutatiohn", "mutation", - "mutialted", "mutilated", - "mutilatin", "mutilation", - "mutliated", "mutilated", - "mutliples", "multiples", - "mutlitude", "multitude", - "mysterise", "mysteries", - "mysterous", "mysterious", - "nacrotics", "narcotics", - "naferious", "nefarious", - "nahsville", "nashville", - "narcissim", "narcissism", - "narcissit", "narcissist", - "narcissts", "narcissist", - "narctoics", "narcotics", - "nasvhille", "nashville", - "nationaal", "national", - "nationaly", "nationally", - "nativelly", "natively", - "natrually", "naturally", - "navigatie", "navigate", - "navigatin", "navigation", - "neccesary", "necessary", - "necessite", "necessities", - "neckbears", "neckbeards", - "neckbread", "neckbeard", - "nedlessly", "endlessly", - "needlessy", "needlessly", - "negiotate", "negotiate", - "negociate", "negotiate", - "negoitate", "negotiate", - "neigbhour", "neighbour", - "neigbours", "neighbours", - "neighboor", "neighbor", - "nessecary", "necessary", - "newcaslte", "newcastle", - "newcastel", "newcastle", - "nieghbour", "neighbour", - "nightfa;;", "nightfall", - "nightlcub", "nightclub", - "nigthclub", "nightclub", - "nigthlife", "nightlife", - "nigthmare", "nightmare", - "nihilisim", "nihilism", - "ninteenth", "nineteenth", - "nominatie", "nominate", - "nominatin", "nomination", - "noninital", "noninitial", - "norhteast", "northeast", - "norhtwest", "northwest", - "normanday", "normandy", - "northeren", "northern", - "norwegain", "norwegian", - "norwiegan", "norwegian", - "nostaglia", "nostalgia", - "nostaglic", "nostalgic", - "nostaliga", "nostalgia", - "nostaligc", "nostalgic", - "nostlagia", "nostalgia", - "nostlagic", "nostalgic", - "nostriles", "nostrils", - "nostrills", "nostrils", - "notacible", "noticeable", - "notciable", "noticeable", - "noteboook", "notebook", - "noteriety", "notoriety", - "noteworty", "noteworthy", - "noticable", "noticeable", - "noticably", "noticeably", - "noticalbe", "noticeable", - "noticeing", "noticing", - "noticible", "noticeable", - "notoroius", "notorious", - "novermber", "november", - "nullabour", "nullarbor", - "numberous", "numerous", - "numercial", "numerical", - "numerious", "numerous", - "nuremburg", "nuremberg", - "nurtients", "nutrients", - "nutirents", "nutrients", - "nutreints", "nutrients", - "nutritent", "nutrient", - "nutritian", "nutritional", - "nutritios", "nutritious", - "obediance", "obedience", - "obeidence", "obedience", - "obersvant", "observant", - "obersvers", "observers", - "obesssion", "obsession", - "obiedence", "obedience", - "obivously", "obviously", - "objectivs", "objectives", - "objectivy", "objectivity", - "obscruity", "obscurity", - "obscuirty", "obscurity", - "observare", "observer", - "observerd", "observed", - "obssesion", "obsession", - "obssesive", "obsessive", - "obssessed", "obsessed", - "obstruced", "obstructed", - "obsucrity", "obscurity", - "obtainabe", "obtainable", - "obviosuly", "obviously", - "obvioulsy", "obviously", - "obvisouly", "obviously", - "obvoiusly", "obviously", - "ocasional", "occasional", - "ocasioned", "occasioned", - "ocassions", "occasions", - "occaisons", "occasions", - "occassion", "occasion", - "occurance", "occurrence", - "occurence", "occurrence", - "octohedra", "octahedra", - "ocuntries", "countries", - "ocurrance", "occurrence", - "ocurrence", "occurrence", - "offcially", "officially", - "offically", "officially", - "officialy", "officially", - "offpsring", "offspring", - "offspirng", "offspring", - "offsrping", "offspring", - "ogliarchy", "oligarchy", - "oilgarchy", "oligarchy", - "oligrachy", "oligarchy", - "ommitting", "omitting", - "onlsaught", "onslaught", - "onsalught", "onslaught", - "onslaugth", "onslaught", - "onsluaght", "onslaught", - "onwership", "ownership", - "opiniones", "opinions", - "oposition", "opposition", - "opponenet", "opponent", - "opposiste", "opposites", - "opposties", "opposites", - "oppressin", "oppression", - "opression", "oppression", - "opressive", "oppressive", - "opthalmic", "ophthalmic", - "optimisim", "optimism", - "optimistc", "optimistic", - "optinally", "optimally", - "oragnered", "orangered", - "oragnised", "organised", - "oragnizer", "organizer", - "orcehstra", "orchestra", - "ordinarly", "ordinary", - "orgainsed", "organised", - "orgainzer", "organizer", - "organered", "orangered", - "organices", "organise", - "organisim", "organism", - "organiske", "organise", - "organiste", "organise", - "organites", "organise", - "organizms", "organism", - "organsied", "organised", - "organsims", "organisms", - "organzier", "organizer", - "orginally", "originally", - "orgnaised", "organised", - "orhcestra", "orchestra", - "orientato", "orientation", - "origanaly", "originally", - "originall", "original", - "originalt", "originality", - "originaly", "originally", - "origintea", "originate", - "origional", "original", - "orignally", "originally", - "orignials", "originals", - "oublisher", "publisher", - "oursleves", "ourselves", - "oustiders", "outsiders", - "oustpoken", "outspoken", - "outisders", "outsiders", - "outnumbed", "outnumbered", - "outpalyed", "outplayed", - "outperfom", "outperform", - "outpsoken", "outspoken", - "outrageos", "outrageous", - "outskirst", "outskirts", - "outskrits", "outskirts", - "outwieghs", "outweighs", - "overbaord", "overboard", - "overclcok", "overclock", - "overdirve", "overdrive", - "overhpyed", "overhyped", - "overhwelm", "overwhelm", - "overlcock", "overclock", - "overloard", "overload", - "overpaied", "overpaid", - "overpowed", "overpowered", - "overriden", "overridden", - "overwhlem", "overwhelm", - "overwirte", "overwrite", - "overwtach", "overwatch", - "overyhped", "overhyped", - "owernship", "ownership", - "pacificts", "pacifist", - "packageid", "packaged", - "pactivity", "captivity", - "painkills", "painkillers", - "paitently", "patiently", - "paitience", "patience", - "pakistain", "pakistani", - "pakistian", "pakistani", - "pakistnai", "pakistani", - "paksitani", "pakistani", - "paladines", "paladins", - "paladinos", "paladins", - "palestein", "palestine", - "palestina", "palestinian", - "palistian", "palestinian", - "paltforms", "platforms", - "palystyle", "playstyle", - "pancakers", "pancakes", - "pantomine", "pantomime", - "paradimes", "paradise", - "paragraps", "paragraphs", - "paragrpah", "paragraph", - "paralells", "parallels", - "paralelly", "parallelly", - "paralisys", "paralysis", - "parallely", "parallelly", - "paralzyed", "paralyzed", - "paramedis", "paramedics", - "paramters", "parameters", - "paranoica", "paranoia", - "paranoida", "paranoia", - "parasties", "parasites", - "paraylsis", "paralysis", - "paraylzed", "paralyzed", - "parellels", "parallels", - "paricular", "particular", - "parisitic", "parasitic", - "paritally", "partially", - "parliment", "parliament", - "parmesaen", "parmesan", - "parntered", "partnered", - "parrallel", "parallel", - "partchett", "pratchett", - "parterned", "partnered", - "participe", "participate", - "partiotic", "patriotic", - "partisain", "partisan", - "pasengers", "passengers", - "passagens", "passages", - "passagers", "passages", - "passerbys", "passersby", - "passiones", "passions", - "passivley", "passively", - "passowrds", "passwords", - "pateintly", "patiently", - "paticular", "particular", - "patinetly", "patiently", - "patriarca", "patriarchal", - "patriarcy", "patriarchy", - "patriotas", "patriots", - "patriotes", "patriots", - "patroitic", "patriotic", - "pattented", "patented", - "pavillion", "pavilion", - "pbulisher", "publisher", - "peacefuly", "peacefully", - "pedohpile", "pedophile", - "pedophila", "pedophilia", - "pedophils", "pedophiles", - "peircings", "piercings", - "penalites", "penalties", - "penatlies", "penalties", - "penduluum", "pendulum", - "penerator", "penetrator", - "penguines", "penguins", - "penguings", "penguins", - "penguinos", "penguins", - "peninsual", "peninsula", - "peninusla", "peninsula", - "penisnula", "peninsula", - "penisular", "peninsular", - "pennisula", "peninsula", - "pensinula", "peninsula", - "pentagoon", "pentagon", - "peodphile", "pedophile", - "pepperino", "pepperoni", - "peppermit", "peppermint", - "percepted", "perceived", - "percevied", "perceived", - "percieved", "perceived", - "percisely", "precisely", - "percision", "precision", - "percursor", "precursor", - "perdators", "predators", - "peremiter", "perimeter", - "perfeclty", "perfectly", - "perfomers", "performers", - "performas", "performs", - "perfromer", "performer", - "pericings", "piercings", - "perimetre", "perimeter", - "peristent", "persistent", - "periwinke", "periwinkle", - "permanant", "permanent", - "permature", "premature", - "permenant", "permanent", - "permieter", "perimeter", - "permissie", "permissible", - "permissin", "permissions", - "permisson", "permission", - "pernament", "permanent", - "perorders", "preorders", - "perpetrar", "perpetrator", - "perpetuae", "perpetuate", - "perpetuas", "perpetuates", - "persauded", "persuaded", - "perscribe", "prescribe", - "perserved", "preserved", - "persistes", "persists", - "personaes", "personas", - "personaly", "personally", - "personell", "personnel", - "personhod", "personhood", - "persuated", "persuade", - "pertended", "pretended", - "pertoleum", "petroleum", - "perusaded", "persuaded", - "pervertes", "perverse", - "pesticids", "pesticides", - "petroluem", "petroleum", - "phemonena", "phenomena", - "phenemona", "phenomena", - "phenonema", "phenomena", - "phillipse", "phillies", - "philosopy", "philosophy", - "philosphy", "philosophy", - "phonecian", "phoenecian", - "phonemena", "phenomena", - "phongraph", "phonograph", - "photograh", "photograph", - "phsyician", "physician", - "phsyicist", "physicist", - "phycisian", "physician", - "phycisist", "physicist", - "physicaly", "physically", - "physicits", "physicist", - "physisict", "physicist", - "piblisher", "publisher", - "picthfork", "pitchfork", - "pinetrest", "pinterest", - "placeheld", "placeholder", - "placemens", "placements", - "plaestine", "palestine", - "plagarism", "plagiarism", - "planatery", "planetary", - "planation", "plantation", - "planteary", "planetary", - "plasticas", "plastics", - "plasticos", "plastics", - "plasticus", "plastics", - "platfroms", "platforms", - "platofrms", "platforms", - "plausable", "plausible", - "plausbile", "plausible", - "plausibel", "plausible", - "playgroud", "playground", - "playright", "playwright", - "playstlye", "playstyle", - "playwrite", "playwright", - "plebicite", "plebiscite", - "plethoria", "plethora", - "ploarized", "polarized", - "pointeres", "pointers", - "polinator", "pollinator", - "polishees", "polishes", - "politelly", "politely", - "politican", "politician", - "politicas", "politics", - "politicin", "politician", - "politicus", "politics", - "polygammy", "polygamy", - "populatin", "populations", - "poralized", "polarized", - "porcelian", "porcelain", - "porcelina", "porcelain", - "poreclain", "porcelain", - "porftolio", "portfolio", - "porgramme", "programme", - "portfoilo", "portfolio", - "portoflio", "portfolio", - "portraing", "portraying", - "portrayes", "portrays", - "portrayls", "portrays", - "portriats", "portraits", - "portugese", "portuguese", - "portugues", "portuguese", - "posessing", "possessing", - "posession", "possession", - "positiond", "positioned", - "positiong", "positioning", - "positionl", "positional", - "positiviy", "positivity", - "possesess", "possesses", - "possesing", "possessing", - "possesion", "possession", - "possessin", "possessions", - "possibile", "possible", - "possibily", "possibility", - "possibley", "possibly", - "possiblly", "possibly", - "possition", "position", - "powderade", "powdered", - "powerfull", "powerful", - "pracitcal", "practical", - "practhett", "pratchett", - "practicly", "practically", - "practives", "practise", - "pragamtic", "pragmatic", - "preadtors", "predators", - "precedeed", "preceded", - "preceeded", "preceded", - "preceived", "perceived", - "preciesly", "precisely", - "precisley", "precisely", - "precurors", "precursor", - "precurosr", "precursor", - "precurser", "precursor", - "predatobr", "predator", - "predictie", "predictive", - "predictin", "prediction", - "predjuice", "prejudice", - "predujice", "prejudice", - "prefectly", "perfectly", - "preferens", "preferences", - "prefering", "preferring", - "preformer", "performer", - "pregnance", "pregnancies", - "preimeter", "perimeter", - "prejiduce", "prejudice", - "prejucide", "prejudice", - "premanent", "permanent", - "premeired", "premiered", - "preorderd", "preordered", - "preparato", "preparation", - "prepatory", "preparatory", - "presentas", "presents", - "presentes", "presents", - "presicely", "precisely", - "presicion", "precision", - "presideny", "presidency", - "prestigiu", "prestigious", - "prestigue", "prestige", - "presuaded", "persuaded", - "pretendas", "pretends", - "pretensje", "pretense", - "pretinent", "pertinent", - "prevelant", "prevalent", - "preventin", "prevention", - "previvous", "previous", - "priesthod", "priesthood", - "priestood", "priesthood", - "primaires", "primaries", - "primairly", "primarily", - "primarliy", "primarily", - "primative", "primitive", - "primordal", "primordial", - "princesas", "princess", - "princeses", "princess", - "princesss", "princesses", - "principas", "principals", - "principly", "principally", - "prinicple", "principle", - "prioritie", "prioritize", - "prioritse", "priorities", - "privalege", "privilege", - "privelege", "privilege", - "privelige", "privilege", - "privilage", "privilege", - "privilegs", "privileges", - "privledge", "privilege", - "probabily", "probability", - "probablly", "probably", - "problemas", "problems", - "procative", "proactive", - "procedger", "procedure", - "proceding", "proceeding", - "proceedes", "proceeds", - "procelain", "porcelain", - "procesess", "processes", - "processer", "processor", - "processos", "processors", - "proclamed", "proclaimed", - "procotols", "protocols", - "prodecure", "procedure", - "productie", "productive", - "productin", "productions", - "productos", "products", - "profesion", "profusion", - "professer", "professor", - "professin", "professions", - "proffesed", "professed", - "proffesor", "professor", - "progessed", "progressed", - "programas", "programs", - "programem", "programme", - "programes", "programs", - "programms", "programs", - "progresso", "progression", - "progresss", "progresses", - "projectie", "projectile", - "projectin", "projection", - "prominant", "prominent", - "promiscus", "promiscuous", - "promotted", "promoted", - "pronomial", "pronominal", - "pronouced", "pronounced", - "pronounds", "pronouns", - "pronounes", "pronouns", - "propagana", "propaganda", - "properies", "properties", - "propertly", "property", - "propeties", "properties", - "prophesie", "prophecies", - "prophetes", "prophets", - "propogate", "propagate", - "proposels", "proposes", - "proposito", "proposition", - "propperly", "properly", - "propsects", "prospects", - "prosperos", "prosperous", - "prostitue", "prostitute", - "protectes", "protects", - "protectie", "protective", - "protectos", "protectors", - "proteinas", "proteins", - "proteines", "proteins", - "protestas", "protests", - "protestat", "protestant", - "protestes", "protests", - "protestos", "protests", - "protfolio", "portfolio", - "protocool", "protocol", - "prototpye", "prototype", - "prototyps", "prototypes", - "protraits", "portraits", - "protrayal", "portrayal", - "protrayed", "portrayed", - "provicial", "provincial", - "provincie", "province", - "provisios", "provisions", - "pruchased", "purchased", - "pruchases", "purchases", - "prugatory", "purgatory", - "pruposely", "purposely", - "pscyhotic", "psychotic", - "pseudonyn", "pseudonym", - "pshycosis", "psychosis", - "pshycotic", "psychotic", - "psycology", "psychology", - "psycothic", "psychotic", - "ptichfork", "pitchfork", - "pubilsher", "publisher", - "publiaher", "publisher", - "publicaly", "publicly", - "publicani", "publication", - "publicher", "publisher", - "publiclly", "publicly", - "publihser", "publisher", - "publisehr", "publisher", - "publisger", "publisher", - "publishor", "publisher", - "publishre", "publisher", - "publsiher", "publisher", - "publusher", "publisher", - "puchasing", "purchasing", - "punishmet", "punishments", - "puplisher", "publisher", - "puragtory", "purgatory", - "purcahsed", "purchased", - "purcahses", "purchases", - "purhcased", "purchased", - "purposley", "purposely", - "pursuaded", "persuaded", - "pursuades", "persuades", - "pyramidas", "pyramids", - "pyramides", "pyramids", - "pyschosis", "psychosis", - "pyschotic", "psychotic", - "qaulifies", "qualifies", - "quantifiy", "quantify", - "quantitiy", "quantity", - "quantitty", "quantity", - "quartlery", "quarterly", - "queations", "equations", - "queenland", "queensland", - "questiond", "questioned", - "questiong", "questioning", - "questionn", "questioning", - "radicalis", "radicals", - "rapsberry", "raspberry", - "rasbperry", "raspberry", - "rationaly", "rationally", - "reactiony", "reactionary", - "realisitc", "realistic", - "realoding", "reloading", - "realsitic", "realistic", - "realtable", "relatable", - "realtions", "relations", - "realtives", "relatives", - "reamining", "remaining", - "reaplying", "replaying", - "reasearch", "research", - "reaveling", "revealing", - "rebellios", "rebellious", - "rebllions", "rebellions", - "recations", "creations", - "reccomend", "recommend", - "reccuring", "recurring", - "receeding", "receding", - "recepient", "recipient", - "recgonise", "recognise", - "recgonize", "recognize", - "recidents", "residents", - "recievers", "receivers", - "recieving", "receiving", - "recipiant", "recipient", - "reciproce", "reciprocate", - "reclutant", "reluctant", - "recoginse", "recognise", - "recoginze", "recognize", - "recomends", "recommends", - "recommens", "recommends", - "reconenct", "reconnect", - "recongise", "recognise", - "recongize", "recognize", - "reconicle", "reconcile", - "reconized", "recognized", - "recordare", "recorder", - "recoveres", "recovers", - "recoverys", "recovers", - "recpetive", "receptive", - "recpetors", "receptors", - "recquired", "required", - "recreatie", "recreate", - "recruitcs", "recruits", - "recruites", "recruits", - "recrusion", "recursion", - "recrutied", "recruited", - "recrutier", "recruiter", - "rectangel", "rectangle", - "rectanlge", "rectangle", - "recuiting", "recruiting", - "recurison", "recursion", - "recurited", "recruited", - "recuriter", "recruiter", - "recusrion", "recursion", - "redeemeed", "redeemed", - "redundany", "redundancy", - "redundent", "redundant", - "reedeming", "redeeming", - "refection", "reflection", - "refelcted", "reflected", - "refereces", "references", - "refereees", "referees", - "refereers", "referees", - "referemce", "reference", - "referencs", "references", - "referense", "references", - "referiang", "referring", - "referinng", "referring", - "refernces", "references", - "refernece", "reference", - "refershed", "refreshed", - "refersher", "refresher", - "reffering", "referring", - "reflectie", "reflective", - "refrehser", "refresher", - "refrences", "references", - "refromist", "reformist", - "regionaal", "regional", - "registerd", "registered", - "registery", "registry", - "regualrly", "regularly", - "regualtor", "regulator", - "regulaion", "regulation", - "regulalry", "regularly", - "regulares", "regulars", - "regularis", "regulars", - "regulatin", "regulations", - "regurally", "regularly", - "reigining", "reigning", - "reinstale", "reinstalled", - "reisntall", "reinstall", - "reknowned", "renowned", - "relaoding", "reloading", - "relatiate", "retaliate", - "relativiy", "relativity", - "relativly", "relatively", - "relativno", "relation", - "relavence", "relevance", - "relcutant", "reluctant", - "relevence", "relevance", - "relfected", "reflected", - "reliabily", "reliability", - "reliabley", "reliably", - "religeous", "religious", - "remasterd", "remastered", - "rememberd", "remembered", - "rememebrs", "remembers", - "remianing", "remaining", - "remignton", "remington", - "remingotn", "remington", - "remmebers", "remembers", - "remotelly", "remotely", - "rendevous", "rendezvous", - "rendezous", "rendezvous", - "renedered", "rende", - "renegated", "renegade", - "rennovate", "renovate", - "repalying", "replaying", - "repblican", "republican", - "repeatedy", "repeatedly", - "repective", "receptive", - "repeition", "repetition", - "repentent", "repentant", - "rephrasse", "rephrase", - "replusive", "repulsive", - "reportedy", "reportedly", - "represend", "represented", - "repressin", "repression", - "reprtoire", "repertoire", - "repsonded", "responded", - "reptition", "repetition", - "reptuable", "reputable", - "repubican", "republican", - "republian", "republican", - "repulican", "republican", - "repulisve", "repulsive", - "repuslive", "repulsive", - "resaurant", "restaurant", - "researchs", "researchers", - "resembels", "resembles", - "reserverd", "reserved", - "resintall", "reinstall", - "resistane", "resistances", - "resistans", "resistances", - "resistend", "resisted", - "resistent", "resistant", - "resmebles", "resembles", - "resolutin", "resolutions", - "resoruces", "resources", - "respectes", "respects", - "respectos", "respects", - "responces", "response", - "respondas", "responds", - "respondis", "responds", - "respondus", "responds", - "respoting", "reposting", - "ressemble", "resemble", - "ressurect", "resurrect", - "restarant", "restaurant", - "resticted", "restricted", - "restircts", "restricts", - "restorani", "restoration", - "restraind", "restrained", - "restraing", "restraining", - "restraunt", "restraint", - "restriant", "restraint", - "restricte", "restrictive", - "resturant", "restaurant", - "retailate", "retaliate", - "retalaite", "retaliate", - "retaliers", "retailers", - "reteriver", "retriever", - "retirever", "retriever", - "retrevier", "retriever", - "retriving", "retrieving", - "reuptable", "reputable", - "reveiwers", "reviewers", - "revelaing", "revealing", - "revelance", "relevance", - "revolutin", "revolutions", - "rewachted", "rewatched", - "rewatchig", "rewatching", - "rferences", "references", - "ridiculos", "ridiculous", - "ridiculue", "ridicule", - "ridiculus", "ridiculous", - "righetous", "righteous", - "rightfuly", "rightfully", - "rightoues", "righteous", - "rigourous", "rigorous", - "rigtheous", "righteous", - "rilvaries", "rivalries", - "rininging", "ringing", - "rivarlies", "rivalries", - "rivlaries", "rivalries", - "roaylties", "royalties", - "roboticus", "robotics", - "roganisms", "organisms", - "royalites", "royalties", - "roylaties", "royalties", - "ruleboook", "rulebook", - "sacarstic", "sarcastic", - "sacntuary", "sanctuary", - "sacrafice", "sacrifice", - "sacrastic", "sarcastic", - "sacrifise", "sacrifices", - "salughter", "slaughter", - "samckdown", "smackdown", - "sanctiond", "sanctioned", - "sancturay", "sanctuary", - "sancutary", "sanctuary", - "sandstrom", "sandstorm", - "sandwhich", "sandwich", - "sanhedrim", "sanhedrin", - "santcuary", "sanctuary", - "santioned", "sanctioned", - "sapphirre", "sapphire", - "sastified", "satisfied", - "sastifies", "satisfies", - "satelites", "satellites", - "saterdays", "saturdays", - "satisifed", "satisfied", - "satisifes", "satisfies", - "satrudays", "saturdays", - "satsified", "satisfied", - "satsifies", "satisfies", - "sattelite", "satellite", - "saxaphone", "saxophone", - "scaepgoat", "scapegoat", - "scaleable", "scalable", - "scandales", "scandals", - "scandalos", "scandals", - "scantuary", "sanctuary", - "scaricity", "scarcity", - "scarifice", "sacrifice", - "scarmbled", "scrambled", - "scartched", "scratched", - "scartches", "scratches", - "scavanged", "scavenged", - "sceintist", "scientist", - "scholalry", "scholarly", - "sciencers", "sciences", - "scientfic", "scientific", - "scientifc", "scientific", - "scientits", "scientist", - "sclupture", "sculpture", - "scnearios", "scenarios", - "scoreboad", "scoreboard", - "scottisch", "scottish", - "scracthed", "scratched", - "scracthes", "scratches", - "scrambeld", "scrambled", - "scrathces", "scratches", - "scrollade", "scrolled", - "scrutiney", "scrutiny", - "scrutinty", "scrutiny", - "sculpteur", "sculpture", - "sculputre", "sculpture", - "scultpure", "sculpture", - "scuplture", "sculpture", - "scuptures", "sculptures", - "seamlessy", "seamlessly", - "searchign", "searching", - "sebasitan", "sebastian", - "sebastain", "sebastian", - "sebsatian", "sebastian", - "secceeded", "seceded", - "secertary", "secretary", - "secratary", "secretary", - "secratery", "secretary", - "secretery", "secretary", - "secretley", "secretly", - "sednetary", "sedentary", - "seduciton", "seduction", - "semanitcs", "semantics", - "semestres", "semesters", - "semnatics", "semantics", - "semseters", "semesters", - "senatores", "senators", - "sendetary", "sedentary", - "sensitivy", "sensitivity", - "sentimant", "sentimental", - "sepcially", "specially", - "seperated", "separated", - "seperates", "separates", - "seperator", "separator", - "septmeber", "september", - "seraching", "searching", - "seriosuly", "seriously", - "serioulsy", "seriously", - "seriuosly", "seriously", - "servantes", "servants", - "settlment", "settlement", - "sexualizd", "sexualized", - "sexuallly", "sexually", - "shadasloo", "shadaloo", - "shaprness", "sharpness", - "sharpenss", "sharpness", - "shawhsank", "shawshank", - "sheilding", "shielding", - "shephered", "shepherd", - "shileding", "shielding", - "shitstrom", "shitstorm", - "shletered", "sheltered", - "shoudlers", "shoulders", - "shouldnot", "shouldnt", - "shperical", "spherical", - "shwashank", "shawshank", - "sidebaord", "sideboard", - "siganture", "signature", - "signapore", "singapore", - "signitory", "signatory", - "silhouete", "silhouette", - "similiair", "similar", - "simliarly", "similarly", - "simluated", "simulated", - "simluator", "simulator", - "simplifiy", "simplify", - "simualted", "simulated", - "simualtor", "simulator", - "simulatie", "simulate", - "simulatin", "simulation", - "sinagpore", "singapore", - "sincerley", "sincerely", - "singature", "signature", - "singpaore", "singapore", - "singulair", "singular", - "singulary", "singularity", - "skateboad", "skateboard", - "skeletaal", "skeletal", - "skepitcal", "skeptical", - "skepticim", "skepticism", - "sketpical", "skeptical", - "slaughted", "slaughtered", - "slaugther", "slaughter", - "slipperly", "slippery", - "sluaghter", "slaughter", - "smackdwon", "smackdown", - "smealting", "smelting", - "smeesters", "semesters", - "snadstorm", "sandstorm", - "snippetts", "snippets", - "snowfalke", "snowflake", - "snowflaek", "snowflake", - "snowlfake", "snowflake", - "snwoballs", "snowballs", - "snythesis", "synthesis", - "snythetic", "synthetic", - "socailism", "socialism", - "socailist", "socialist", - "socailize", "socialize", - "soceities", "societies", - "socialini", "socializing", - "socialiss", "socialists", - "socialsim", "socialism", - "socieites", "societies", - "socilaism", "socialism", - "socilaist", "socialist", - "sociopati", "sociopathic", - "sociopats", "sociopaths", - "socratees", "socrates", - "socrateks", "socrates", - "soemthing", "something", - "sohpomore", "sophomore", - "soliliquy", "soliloquy", - "somehting", "something", - "someoneis", "someones", - "somethign", "something", - "somethins", "somethings", - "sopohmore", "sophomore", - "sotryline", "storyline", - "soundtrak", "soundtrack", - "sountrack", "soundtrack", - "sourthern", "southern", - "souvenier", "souvenir", - "soveregin", "sovereign", - "sovereing", "sovereign", - "soveriegn", "sovereign", - "spacegoat", "scapegoat", - "spagehtti", "spaghetti", - "spahgetti", "spaghetti", - "sparlking", "sparkling", - "spartants", "spartans", - "specailly", "specially", - "specailty", "specialty", - "specality", "specialty", - "speciales", "specials", - "specialis", "specials", - "speciatly", "specialty", - "specifing", "specifying", - "specimine", "specimen", - "spectrail", "spectral", - "specualte", "speculate", - "speechers", "speeches", - "spehrical", "spherical", - "speically", "specially", - "spetember", "september", - "sphagetti", "spaghetti", - "splatooon", "splatoon", - "sponosred", "sponsored", - "sponsered", "sponsored", - "sponsores", "sponsors", - "spontanes", "spontaneous", - "sponzored", "sponsored", - "sprakling", "sparkling", - "sprinkeld", "sprinkled", - "squadroon", "squadron", - "squirrles", "squirrels", - "squirrtle", "squirrel", - "squrriels", "squirrels", - "srirachia", "sriracha", - "srirachra", "sriracha", - "stabliize", "stabilize", - "stainlees", "stainless", - "startegic", "strategic", - "startlxde", "startled", - "statisitc", "statistic", - "staurdays", "saturdays", - "steadilly", "steadily", - "stealthly", "stealthy", - "stichting", "stitching", - "sticthing", "stitching", - "stimulans", "stimulants", - "stockplie", "stockpile", - "stornegst", "strongest", - "stragetic", "strategic", - "straightn", "straighten", - "strangets", "strangest", - "strategis", "strategies", - "strawbery", "strawberry", - "streamade", "streamed", - "streamare", "streamer", - "streamear", "streamer", - "strechted", "stretched", - "strechtes", "stretches", - "strecthed", "stretched", - "strecthes", "stretches", - "stregnths", "strengths", - "strenghen", "strengthen", - "strengthn", "strengthen", - "strentghs", "strengths", - "stressade", "stressed", - "stressers", "stresses", - "strictist", "strictest", - "stringnet", "stringent", - "stroyline", "storyline", - "structual", "structural", - "structurs", "structures", - "strucutre", "structure", - "struggeld", "struggled", - "struggels", "struggles", - "stryofoam", "styrofoam", - "stuctured", "structured", - "stuggling", "struggling", - "stupitidy", "stupidity", - "sturcture", "structure", - "sturggled", "struggled", - "sturggles", "struggles", - "styrofaom", "styrofoam", - "subarmine", "submarine", - "subculter", "subculture", - "submachne", "submachine", - "subpecies", "subspecies", - "subscirbe", "subscribe", - "subsidary", "subsidiary", - "subsizide", "subsidize", - "subsquent", "subsequent", - "subsrcibe", "subscribe", - "substanse", "substances", - "substanta", "substantial", - "substante", "substantive", - "substarte", "substrate", - "substitue", "substitute", - "substract", "subtract", - "subtances", "substances", - "subtiltes", "subtitles", - "subtitels", "subtitles", - "subtletly", "subtlety", - "subtlties", "subtitles", - "succedded", "succeeded", - "succeedes", "succeeds", - "succesful", "successful", - "succesion", "succession", - "succesive", "successive", - "suceeding", "succeeding", - "sucesfuly", "successfully", - "sucessful", "successful", - "sucession", "succession", - "sucessive", "successive", - "sufferage", "suffrage", - "sufferred", "suffered", - "sufficent", "sufficient", - "suggestes", "suggests", - "suggestie", "suggestive", - "sumbarine", "submarine", - "sumberged", "submerged", - "summenors", "summoners", - "summoenrs", "summoners", - "sunderlad", "sunderland", - "sunglases", "sunglasses", - "superfluu", "superfluous", - "superiour", "superior", - "superisor", "superiors", - "supermare", "supermarket", - "superviso", "supervision", - "suposedly", "supposedly", - "supportes", "supports", - "suppreses", "suppress", - "supressed", "suppressed", - "supresses", "suppresses", - "suprising", "surprising", - "suprizing", "surprising", - "supsicion", "suspicion", - "surounded", "surrounded", - "surprized", "surprised", - "surronded", "surrounded", - "surrouded", "surrounded", - "surrouned", "surround", - "survivers", "survivors", - "survivied", "survived", - "survivour", "survivor", - "susbcribe", "subscribe", - "susbtrate", "substrate", - "susncreen", "sunscreen", - "suspectes", "suspects", - "suspendes", "suspense", - "suspensie", "suspense", - "swastikka", "swastika", - "sweatshit", "sweatshirt", - "sweetheat", "sweetheart", - "switchign", "switching", - "swithcing", "switching", - "swtiching", "switching", - "sydnicate", "syndicate", - "sykwalker", "skywalker", - "sylablles", "syllables", - "syllabels", "syllables", - "symbolsim", "symbolism", - "symettric", "symmetric", - "symmetral", "symmetric", - "symmetria", "symmetrical", - "symoblism", "symbolism", - "sympathie", "sympathize", - "symphoney", "symphony", - "symptomes", "symptoms", - "symptomps", "symptoms", - "synagouge", "synagogue", - "syndacite", "syndicate", - "syndiacte", "syndicate", - "synidcate", "syndicate", - "synonymes", "synonyms", - "synonymis", "synonyms", - "synonymns", "synonyms", - "synonymos", "synonymous", - "synonymus", "synonyms", - "synopsies", "synopsis", - "syntehsis", "synthesis", - "syntehtic", "synthetic", - "syntethic", "synthetic", - "syphyllis", "syphilis", - "syracusae", "syracuse", - "sytrofoam", "styrofoam", - "tablespon", "tablespoon", - "tacticaly", "tactically", - "tanenhill", "tannehill", - "tannheill", "tannehill", - "targetted", "targeted", - "tawainese", "taiwanese", - "tawianese", "taiwanese", - "taxanomic", "taxonomic", - "teamfighs", "teamfights", - "teamfigth", "teamfight", - "teamifght", "teamfight", - "teampseak", "teamspeak", - "teaspooon", "teaspoon", - "techician", "technician", - "techinque", "technique", - "technolgy", "technology", - "teeangers", "teenagers", - "tehtering", "tethering", - "telegrpah", "telegraph", - "televsion", "television", - "temafight", "teamfight", - "tempaltes", "templates", - "temparate", "temperate", - "templaras", "templars", - "templares", "templars", - "temporali", "temporarily", - "tenacitiy", "tenacity", - "tensiones", "tensions", - "tentacels", "tentacles", - "tentacuel", "tentacle", - "tentalces", "tentacles", - "termianls", "terminals", - "terminato", "termination", - "terorrism", "terrorism", - "terorrist", "terrorist", - "terrabyte", "terabyte", - "terribley", "terribly", - "terriblly", "terribly", - "terriroty", "territory", - "terrorits", "terrorist", - "terrorsim", "terrorism", - "tesitcles", "testicles", - "tesitmony", "testimony", - "testicels", "testicles", - "testomony", "testimony", - "texturers", "textures", - "thankfuly", "thankfully", - "thankyoou", "thankyou", - "themselfs", "themselves", - "themselvs", "themselves", - "themslves", "themselves", - "theologia", "theological", - "therafter", "thereafter", - "therefoer", "therefor", - "therefour", "therefor", - "theroists", "theorists", - "thetering", "tethering", - "thirlling", "thrilling", - "thirteeen", "thirteen", - "thoecracy", "theocracy", - "thoerists", "theorists", - "thoroughy", "thoroughly", - "thoughout", "throughout", - "threatend", "threatened", - "throrough", "thorough", - "throughly", "thoroughly", - "througout", "throughout", - "thrusdays", "thursdays", - "thurdsays", "thursdays", - "thursdsay", "thursdays", - "thursters", "thrusters", - "tiawanese", "taiwanese", - "timestmap", "timestamp", - "tirangles", "triangles", - "tocuhdown", "touchdown", - "toghether", "together", - "tolerence", "tolerance", - "tommorrow", "tomorrow", - "torandoes", "tornadoes", - "torchligt", "torchlight", - "torelable", "tolerable", - "toritllas", "tortillas", - "tornaodes", "tornadoes", - "torpeados", "torpedoes", - "torrentas", "torrents", - "torrentes", "torrents", - "tortialls", "tortillas", - "tortillia", "tortilla", - "tortillla", "tortilla", - "tottehnam", "tottenham", - "tottenahm", "tottenham", - "tottneham", "tottenham", - "toturials", "tutorials", - "touchdwon", "touchdown", - "touristas", "tourists", - "touristes", "tourists", - "touristey", "touristy", - "touristly", "touristy", - "touristsy", "touristy", - "tournamet", "tournament", - "toxicitiy", "toxicity", - "trafficed", "trafficked", - "tragicaly", "tragically", - "traileras", "trailers", - "traingles", "triangles", - "trainwrek", "trainwreck", - "traitoris", "traitors", - "traitorus", "traitors", - "tramautic", "traumatic", - "tranlsate", "translate", - "transalte", "translate", - "transcris", "transcripts", - "transcrit", "transcript", - "transferd", "transferred", - "transfere", "transferred", - "transfors", "transforms", - "transfrom", "transform", - "transiten", "transient", - "transitin", "transitions", - "transofrm", "transform", - "transplat", "transplant", - "trasnfers", "transfers", - "trasnform", "transform", - "trasnport", "transport", - "traversie", "traverse", - "travestry", "travesty", - "treasuers", "treasures", - "treasurey", "treasury", - "treatmens", "treatments", - "treausres", "treasures", - "tremendos", "tremendous", - "trhilling", "thrilling", - "trhusters", "thrusters", - "triangels", "triangles", - "trianlges", "triangles", - "tribunaal", "tribunal", - "triguered", "triggered", - "trinagles", "triangles", - "truamatic", "traumatic", - "truthfuly", "truthfully", - "tunrtable", "turntable", - "turnaroud", "turnaround", - "turntabel", "turntable", - "typcially", "typically", - "tyrranies", "tyrannies", - "ubiquitos", "ubiquitous", - "ugprading", "upgrading", - "ukrainain", "ukrainian", - "ukrainias", "ukrainians", - "ukrainina", "ukrainian", - "ukrainisn", "ukrainians", - "ukrianian", "ukrainian", - "ulitmatum", "ultimatum", - "ulteriour", "ulterior", - "umbrellla", "umbrella", - "unaminous", "unanimous", - "unanmious", "unanimous", - "unanswerd", "unanswered", - "unanymous", "unanimous", - "unbannend", "unbanned", - "uncensord", "uncensored", - "uncomited", "uncommitted", - "undercunt", "undercut", - "underdong", "underdog", - "undergard", "undergrad", - "underming", "undermining", - "understad", "understands", - "underwaer", "underwear", - "underware", "underwear", - "undescore", "underscore", - "unforseen", "unforeseen", - "unfortune", "unfortunate", - "unfriendy", "unfriendly", - "unhealhty", "unhealthy", - "unheathly", "unhealthy", - "unhelathy", "unhealthy", - "unicornis", "unicorns", - "unicornus", "unicorns", - "uniformes", "uniforms", - "uninamous", "unanimous", - "unintuive", "unintuitive", - "uniquelly", "uniquely", - "unisntall", "uninstall", - "univerity", "university", - "universse", "universes", - "univesity", "university", - "unnistall", "uninstall", - "unoffical", "unofficial", - "unopenend", "unopened", - "unplayabe", "unplayable", - "unplesant", "unpleasant", - "unpopluar", "unpopular", - "unrankend", "unranked", - "unreliabe", "unreliable", - "unrwitten", "unwritten", - "untrianed", "untrained", - "unusaully", "unusually", - "unuseable", "unusable", - "unusuable", "unusable", - "unvierses", "universes", - "unweildly", "unwieldy", - "unwieldly", "unwieldy", - "unwirtten", "unwritten", - "unworthly", "unworthy", - "upcomming", "upcoming", - "upgarding", "upgrading", - "upgradded", "upgraded", - "uplfiting", "uplifting", - "uplifitng", "uplifting", - "urkainian", "ukrainian", - "utlimatum", "ultimatum", - "vacciante", "vaccinate", - "vaccinato", "vaccination", - "vacciners", "vaccines", - "vacestomy", "vasectomy", - "vaguaries", "vagaries", - "vaibility", "viability", - "vaildated", "validated", - "vairables", "variables", - "valdiated", "validated", - "valentein", "valentine", - "valentien", "valentine", - "valentins", "valentines", - "validitiy", "validity", - "valueable", "valuable", - "vanadlism", "vandalism", - "vandalsim", "vandalism", - "varaibles", "variables", - "varations", "variations", - "variantes", "variants", - "vascetomy", "vasectomy", - "vastecomy", "vasectomy", - "veganisim", "veganism", - "vegetarin", "vegetarians", - "vegitable", "vegetable", - "vehementy", "vehemently", - "veiwpoint", "viewpoint", - "velantine", "valentine", - "vendettta", "vendetta", - "venegance", "vengeance", - "veneuzela", "venezuela", - "venezeula", "venezuela", - "venezulea", "venezuela", - "vengaence", "vengeance", - "vengenace", "vengeance", - "ventilato", "ventilation", - "verbatium", "verbatim", - "verfiying", "verifying", - "verifiyng", "verifying", - "verisions", "revisions", - "versalite", "versatile", - "versatily", "versatility", - "versiones", "versions", - "versitale", "versatile", - "verstaile", "versatile", - "verticaly", "vertically", - "veryifing", "verifying", - "vicotrian", "victorian", - "vicotries", "victories", - "victoires", "victories", - "victorain", "victorian", - "victorina", "victorian", - "victorios", "victorious", - "videogaem", "videogame", - "videogams", "videogames", - "vidoegame", "videogame", - "viewpiont", "viewpoint", - "vigilence", "vigilance", - "vigliante", "vigilante", - "vigourous", "vigorous", - "viligante", "vigilante", - "viloently", "violently", - "vincinity", "vicinity", - "vioalting", "violating", - "violentce", "violence", - "virbation", "vibration", - "virgintiy", "virginity", - "virignity", "virginity", - "virutally", "virtually", - "visibiliy", "visibility", - "vitaminas", "vitamins", - "vitamines", "vitamins", - "vitrually", "virtually", - "vociemail", "voicemail", - "voilating", "violating", - "voilation", "violation", - "voilently", "violently", - "volatiliy", "volatility", - "voleyball", "volleyball", - "volontary", "voluntary", - "volonteer", "volunteer", - "volunatry", "voluntary", - "volunteed", "volunteered", - "vriginity", "virginity", - "wallpapes", "wallpapers", - "warrantly", "warranty", - "warrriors", "warriors", - "wavelengh", "wavelength", - "weakenend", "weakened", - "weakneses", "weakness", - "weaknesss", "weaknesses", - "wealtheir", "wealthier", - "weaponary", "weaponry", - "wedensday", "wednesday", - "wednesdsy", "wednesdays", - "wednessay", "wednesdays", - "wednseday", "wednesday", - "welathier", "wealthier", - "wendesday", "wednesday", - "wesbtrook", "westbrook", - "westernes", "westerners", - "westrbook", "westbrook", - "whereever", "wherever", - "whietlist", "whitelist", - "whilrwind", "whirlwind", - "whilsting", "whistling", - "whipsered", "whispered", - "whislting", "whistling", - "whisperes", "whispers", - "whitelsit", "whitelist", - "whitleist", "whitelist", - "whitsling", "whistling", - "whrilwind", "whirlwind", - "whsipered", "whispered", - "whtielist", "whitelist", - "widespred", "widespread", - "widesread", "widespread", - "windshied", "windshield", - "wintesses", "witnesses", - "wisconisn", "wisconsin", - "wishlisht", "wishlist", - "wishpered", "whispered", - "withdrawl", "withdrawal", - "withelist", "whitelist", - "witnesess", "witnesses", - "wolrdview", "worldview", - "wolrdwide", "worldwide", - "wonderlad", "wonderland", - "wordlview", "worldview", - "wordlwide", "worldwide", - "worhtless", "worthless", - "workfroce", "workforce", - "worldivew", "worldview", - "worldveiw", "worldview", - "worstened", "worsened", - "worthelss", "worthless", - "xenbolade", "xenoblade", - "xenobalde", "xenoblade", - "xenophoby", "xenophobia", - "xeonblade", "xenoblade", - "yementite", "yemenite", - "yorkshrie", "yorkshire", - "yorskhire", "yorkshire", - "yosemitie", "yosemite", - "youngents", "youngest", - "yourselvs", "yourselves", - "zimbabwae", "zimbabwe", - "zionistas", "zionists", - "zionistes", "zionists", - "abandond", "abandoned", - "abdomine", "abdomen", - "abilitiy", "ability", - "abilties", "abilities", - "abondons", "abandons", - "aboslute", "absolute", - "abosrbed", "absorbed", - "abruplty", "abruptly", - "abrutply", "abruptly", - "abscence", "absence", - "absestos", "asbestos", - "absoluts", "absolutes", - "absolvte", "absolve", - "absorbes", "absorbs", - "absoulte", "absolute", - "abstante", "bastante", - "abudance", "abundance", - "abudcted", "abducted", - "abundunt", "abundant", - "aburptly", "abruptly", - "abuseres", "abusers", - "abusrdly", "absurdly", - "academis", "academics", - "accademy", "academy", - "acccused", "accused", - "acceptes", "accepts", - "accidens", "accidents", - "accideny", "accidentally", - "accoring", "according", - "accountt", "accountant", - "accpeted", "accepted", - "accuarcy", "accuracy", - "accumule", "accumulate", - "accusato", "accusation", - "accussed", "accused", - "acedamia", "academia", - "acedemic", "academic", - "acheived", "achieved", - "acheives", "achieves", - "achieval", "achievable", - "acnedote", "anecdote", - "acording", "according", - "acornyms", "acronyms", - "acousitc", "acoustic", - "acoutsic", "acoustic", - "acovados", "avocados", - "acquifer", "acquire", - "acquited", "acquitted", - "acquried", "acquired", - "acronmys", "acronyms", - "acronysm", "acronyms", - "acroynms", "acronyms", - "acrynoms", "acronyms", - "acsended", "ascended", - "actaully", "actually", - "activite", "activities", - "activits", "activities", - "activley", "actively", - "actresss", "actresses", - "actualey", "actually", - "actualiy", "actuality", - "actualky", "actually", - "actualmy", "actually", - "actualoy", "actually", - "actualpy", "actually", - "actualty", "actually", - "acutally", "actually", - "acutions", "auctions", - "adaptare", "adapter", - "adbandon", "abandon", - "adbucted", "abducted", - "addictes", "addicts", - "addictin", "addictions", - "addictis", "addictions", - "addional", "additional", - "addopted", "adopted", - "addresed", "addressed", - "adealide", "adelaide", - "adecuate", "adequate", - "adeilade", "adelaide", - "adeladie", "adelaide", - "adeliade", "adelaide", - "adeqaute", "adequate", - "adheisve", "adhesive", - "adhevise", "adhesive", - "adivsors", "advisors", - "admiraal", "admiral", - "adolence", "adolescent", - "adorbale", "adorable", - "adovcacy", "advocacy", - "adpaters", "adapters", - "adquired", "acquired", - "adquires", "acquires", - "adresing", "addressing", - "adressed", "addressed", - "adroable", "adorable", - "adultrey", "adultery", - "adventue", "adventures", - "adventus", "adventures", - "advertis", "adverts", - "advesary", "adversary", - "adviseer", "adviser", - "adviseur", "adviser", - "advocade", "advocated", - "advocats", "advocates", - "advsiors", "advisors", - "aethists", "atheists", - "affaires", "affairs", - "affilate", "affiliate", - "affintiy", "affinity", - "affleunt", "affluent", - "affulent", "affluent", - "afircans", "africans", - "africain", "african", - "afternon", "afternoon", - "againnst", "against", - "agnositc", "agnostic", - "agonstic", "agnostic", - "agravate", "aggravate", - "agreemnt", "agreement", - "agregate", "aggregate", - "agressie", "aggressive", - "agressor", "aggressor", - "agrieved", "aggrieved", - "agruable", "arguable", - "agruably", "arguably", - "agrument", "argument", - "ahtletes", "athletes", - "aincents", "ancients", - "airboner", "airborne", - "airbrone", "airborne", - "aircarft", "aircraft", - "airplans", "airplanes", - "airporta", "airports", - "airpsace", "airspace", - "airscape", "airspace", - "akransas", "arkansas", - "alchemey", "alchemy", - "alchohol", "alcohol", - "alcholic", "alcoholic", - "alcoholc", "alcoholics", - "aldutery", "adultery", - "aleniate", "alienate", - "algoritm", "algorithm", - "alimoney", "alimony", - "alirghty", "alrighty", - "allaince", "alliance", - "alledged", "alleged", - "alledges", "alleges", - "allegedy", "allegedly", - "allegely", "allegedly", - "allegric", "allergic", - "allergey", "allergy", - "allianse", "alliances", - "alligned", "aligned", - "allinace", "alliance", - "allopone", "allophone", - "allready", "already", - "almigthy", "almighty", - "alpahbet", "alphabet", - "alrigthy", "alrighty", - "altantic", "atlantic", - "alterato", "alteration", - "alternar", "alternator", - "althetes", "athletes", - "althetic", "athletic", - "altriusm", "altruism", - "altrusim", "altruism", - "alturism", "altruism", - "aluminim", "aluminium", - "alumnium", "aluminium", - "alunimum", "aluminium", - "amatersu", "amateurs", - "amaterus", "amateurs", - "amendmet", "amendment", - "amercian", "american", - "amercias", "americas", - "amernian", "armenian", - "amethsyt", "amethyst", - "ameythst", "amethyst", - "ammended", "amended", - "amnestry", "amnesty", - "amoungst", "amongst", - "amplifiy", "amplify", - "amplifly", "amplify", - "amrchair", "armchair", - "amrenian", "armenian", - "amtheyst", "amethyst", - "analgoue", "analogue", - "analisys", "analysis", - "analitic", "analytic", - "analouge", "analogue", - "analysie", "analyse", - "analysit", "analyst", - "analyste", "analyse", - "analysze", "analyse", - "analzyed", "analyzed", - "anaolgue", "analogue", - "anarchim", "anarchism", - "anaylses", "analyses", - "anaylsis", "analysis", - "anaylsts", "analysts", - "anaylzed", "analyzed", - "ancedote", "anecdote", - "anceints", "ancients", - "ancinets", "ancients", - "andoirds", "androids", - "andorids", "androids", - "andriods", "androids", - "anecdots", "anecdotes", - "anectode", "anecdote", - "anedocte", "anecdote", - "aneroxia", "anorexia", - "aneroxic", "anorexic", - "angostic", "agnostic", - "angrilly", "angrily", - "anicents", "ancients", - "animatie", "animate", - "animatte", "animate", - "anlayses", "analyses", - "annoints", "anoints", - "annouced", "announced", - "annoucne", "announce", - "anntenas", "antennas", - "anoerxia", "anorexia", - "anoerxic", "anorexic", - "anonymos", "anonymous", - "anoreixa", "anorexia", - "anounced", "announced", - "anoxeria", "anorexia", - "anoxeric", "anorexic", - "answeres", "answers", - "antartic", "antarctic", - "antennea", "antenna", - "antennna", "antenna", - "anticipe", "anticipate", - "antiquae", "antique", - "antivirs", "antivirus", - "anwsered", "answered", - "anyhting", "anything", - "anyhwere", "anywhere", - "anyoneis", "anyones", - "anythign", "anything", - "anytying", "anything", - "aparment", "apartment", - "apartmet", "apartment", - "apenines", "apennines", - "aperutre", "aperture", - "aplhabet", "alphabet", - "apologes", "apologise", - "aposltes", "apostles", - "apostels", "apostles", - "appaluse", "applause", - "apparant", "apparent", - "appareal", "apparel", - "appareil", "apparel", - "apperead", "appeared", - "applaued", "applaud", - "appluase", "applause", - "appology", "apology", - "apporach", "approach", - "appraoch", "approach", - "apreture", "aperture", - "apsotles", "apostles", - "aqaurium", "aquarium", - "aqcuired", "acquired", - "aquaduct", "aqueduct", - "aquairum", "aquarium", - "aquaruim", "aquarium", - "aquiring", "acquiring", - "aquitted", "acquitted", - "arbitary", "arbitrary", - "arbitray", "arbitrary", - "arbiture", "arbiter", - "architet", "architect", - "archtype", "archetype", - "aremnian", "armenian", - "argentia", "argentina", - "argubaly", "arguably", - "arguemet", "argument", - "arguemtn", "argument", - "ariborne", "airborne", - "aricraft", "aircraft", - "ariplane", "airplane", - "ariports", "airports", - "arispace", "airspace", - "aristote", "aristotle", - "aritfact", "artifact", - "arizonia", "arizona", - "arkasnas", "arkansas", - "arlighty", "alrighty", - "armamant", "armament", - "armenain", "armenian", - "armenina", "armenian", - "armpitts", "armpits", - "armstrog", "armstrong", - "arpanoid", "paranoid", - "arpeture", "aperture", - "arragned", "arranged", - "arrestes", "arrests", - "arrestos", "arrests", - "arsenaal", "arsenal", - "artemios", "artemis", - "artemius", "artemis", - "arthrits", "arthritis", - "articule", "articulate", - "artifacs", "artifacts", - "artifcat", "artifact", - "artilley", "artillery", - "artisitc", "artistic", - "artistas", "artists", - "arugable", "arguable", - "arugably", "arguably", - "arugment", "argument", - "asborbed", "absorbed", - "asburdly", "absurdly", - "ascneded", "ascended", - "asissted", "assisted", - "askreddt", "askreddit", - "asnwered", "answered", - "aspectos", "aspects", - "asperges", "aspergers", - "assasins", "assassins", - "assemple", "assemble", - "assertin", "assertions", - "asshates", "asshats", - "asshatts", "asshats", - "assimile", "assimilate", - "assistat", "assistants", - "assitant", "assistant", - "assmeble", "assemble", - "assmebly", "assembly", - "asssasin", "assassin", - "assualts", "assaults", - "asteorid", "asteroid", - "asteriks", "asterisk", - "asteriod", "asteroid", - "asterois", "asteroids", - "astersik", "asterisk", - "asthetic", "aesthetic", - "astronat", "astronaut", - "asutrian", "austrian", - "atheisim", "atheism", - "atheistc", "atheistic", - "atheltes", "athletes", - "atheltic", "athletic", - "athenean", "athenian", - "athesits", "atheists", - "athetlic", "athletic", - "athients", "atheist", - "atittude", "attitude", - "atlantia", "atlanta", - "atmoizer", "atomizer", - "atomzier", "atomizer", - "atribute", "attribute", - "atrifact", "artifact", - "attackes", "attackers", - "attemped", "attempted", - "attemted", "attempted", - "attemtps", "attempts", - "attidute", "attitude", - "attitide", "attitude", - "attribue", "attribute", - "aucitons", "auctions", - "audactiy", "audacity", - "audcaity", "audacity", - "audeince", "audience", - "audiobok", "audiobook", - "austeriy", "austerity", - "austiran", "austrian", - "austitic", "autistic", - "austrain", "austrian", - "australa", "australian", - "austrija", "austria", - "austrila", "austria", - "autisitc", "autistic", - "autoattk", "autoattack", - "autograh", "autograph", - "automato", "automation", - "automony", "autonomy", - "autority", "authority", - "autsitic", "autistic", - "auxilary", "auxiliary", - "avacodos", "avocados", - "avaiable", "available", - "availabe", "available", - "availble", "available", - "avaition", "aviation", - "avalable", "available", - "avalance", "avalanche", - "avataras", "avatars", - "avatards", "avatars", - "avatares", "avatars", - "averadge", "averaged", - "avergaed", "averaged", - "avergaes", "averages", - "aviaiton", "aviation", - "avilable", "available", - "avnegers", "avengers", - "avodacos", "avocados", - "awekened", "weakened", - "awesomey", "awesomely", - "awfullly", "awfully", - "awkwardy", "awkwardly", - "awnsered", "answered", - "babysite", "babysitter", - "baceause", "because", - "bacehlor", "bachelor", - "bachleor", "bachelor", - "bacholer", "bachelor", - "backeast", "backseat", - "backerds", "backers", - "backfied", "backfield", - "backpacs", "backpacks", - "balcanes", "balances", - "balconey", "balcony", - "balconny", "balcony", - "ballistc", "ballistic", - "balnaced", "balanced", - "banannas", "bananas", - "banditas", "bandits", - "bandwith", "bandwidth", - "bangkock", "bangkok", - "baptisim", "baptism", - "barabric", "barbaric", - "barbarin", "barbarian", - "barbaris", "barbarians", - "bardford", "bradford", - "bargaing", "bargaining", - "baristia", "barista", - "barrakcs", "barracks", - "barrells", "barrels", - "basicaly", "basically", - "basiclay", "basically", - "basicley", "basically", - "basicliy", "basically", - "batistia", "batista", - "battalin", "battalion", - "bayonent", "bayonet", - "beachead", "beachhead", - "beacuoup", "beaucoup", - "beardude", "bearded", - "beastley", "beastly", - "beatiful", "beautiful", - "beccause", "because", - "becuasse", "because", - "befirend", "befriend", - "befreind", "befriend", - "begginer", "beginner", - "begginig", "begging", - "begginng", "begging", - "begining", "beginning", - "beginnig", "beginning", - "behaivor", "behavior", - "behavios", "behaviours", - "behavoir", "behavior", - "behavour", "behavior", - "behngazi", "benghazi", - "behtesda", "bethesda", - "beleived", "believed", - "beleiver", "believer", - "beleives", "believes", - "beliefes", "beliefs", - "benefica", "beneficial", - "bengahzi", "benghazi", - "bengalas", "bengals", - "bengalos", "bengals", - "bengazhi", "benghazi", - "benghzai", "benghazi", - "bengzhai", "benghazi", - "benhgazi", "benghazi", - "benidect", "benedict", - "benifits", "benefits", - "berekley", "berkeley", - "berserkr", "berserker", - "beseiged", "besieged", - "betehsda", "bethesda", - "beteshda", "bethesda", - "bethdesa", "bethesda", - "bethedsa", "bethesda", - "bethseda", "bethesda", - "beyoncye", "beyonce", - "bibilcal", "biblical", - "bicylces", "bicycles", - "bigfooot", "bigfoot", - "bigining", "beginning", - "bilbical", "biblical", - "billboad", "billboard", - "bilsters", "blisters", - "bilzzard", "blizzard", - "bilzzcon", "blizzcon", - "biologia", "biological", - "birhtday", "birthday", - "birsbane", "brisbane", - "birthdsy", "birthdays", - "biseuxal", "bisexual", - "bisexaul", "bisexual", - "bitcions", "bitcoins", - "bitocins", "bitcoins", - "blackade", "blacked", - "blackend", "blacked", - "blackjak", "blackjack", - "blacklit", "blacklist", - "blatanty", "blatantly", - "blessins", "blessings", - "blessure", "blessing", - "bloggare", "blogger", - "bloggeur", "blogger", - "bluebery", "blueberry", - "bluetooh", "bluetooth", - "blugaria", "bulgaria", - "boardway", "broadway", - "bollcoks", "bollocks", - "bomberos", "bombers", - "bookmars", "bookmarks", - "boradway", "broadway", - "boredoom", "boredom", - "bouldore", "boulder", - "bounites", "bounties", - "boutnies", "bounties", - "boutqiue", "boutique", - "bouyancy", "buoyancy", - "boyfried", "boyfriend", - "bradcast", "broadcast", - "bradfrod", "bradford", - "brakeout", "breakout", - "braodway", "broadway", - "braverly", "bravery", - "breathis", "breaths", - "breathos", "breaths", - "brekaout", "breakout", - "brendamn", "brendan", - "breweres", "brewers", - "brewerey", "brewery", - "brewerks", "brewers", - "brewerys", "brewers", - "brigaged", "brigade", - "brigated", "brigade", - "brigthen", "brighten", - "briliant", "brilliant", - "brillant", "brilliant", - "bristool", "bristol", - "brithday", "birthday", - "brittish", "british", - "briusers", "bruisers", - "broadbad", "broadband", - "broadcat", "broadcasts", - "broadley", "broadly", - "brocolli", "broccoli", - "brodaway", "broadway", - "broncoes", "broncos", - "broswing", "browsing", - "browines", "brownies", - "browisng", "browsing", - "brtually", "brutally", - "brugundy", "burgundy", - "bruisend", "bruised", - "brussles", "brussels", - "brusting", "bursting", - "bubblews", "bubbles", - "buddhits", "buddhist", - "buddhsim", "buddhism", - "buddishm", "buddhism", - "buddisht", "buddhist", - "buglaria", "bulgaria", - "buhddism", "buddhism", - "buhddist", "buddhist", - "buidlers", "builders", - "buidling", "building", - "buildins", "buildings", - "buisness", "business", - "bulagria", "bulgaria", - "bulgaira", "bulgaria", - "buliders", "builders", - "buliding", "building", - "bulletts", "bullets", - "burisers", "bruisers", - "burriots", "burritos", - "burritio", "burrito", - "burritto", "burrito", - "burrtios", "burritos", - "burssels", "brussels", - "burtally", "brutally", - "burtsing", "bursting", - "busrting", "bursting", - "butcherd", "butchered", - "butterey", "buttery", - "butterfy", "butterfly", - "butterry", "buttery", - "butthoel", "butthole", - "bycicles", "bicycles", - "cabbagge", "cabbage", - "cabients", "cabinets", - "cabinate", "cabinet", - "cabinent", "cabinet", - "cabniets", "cabinets", - "caclulus", "calculus", - "cafetera", "cafeteria", - "caffinee", "caffeine", - "cahsiers", "cashiers", - "cainster", "canister", - "calander", "calendar", - "calcular", "calculator", - "calgarry", "calgary", - "calibler", "calibre", - "caloires", "calories", - "calrkson", "clarkson", - "calroies", "calories", - "calssify", "classify", - "calulate", "calculate", - "calymore", "claymore", - "camapign", "campaign", - "cambodai", "cambodia", - "camboida", "cambodia", - "cambpell", "campbell", - "cambride", "cambridge", - "cambrige", "cambridge", - "camoufle", "camouflage", - "campagin", "campaign", - "campaing", "campaign", - "campains", "campaigns", - "camperas", "campers", - "camperos", "campers", - "canadias", "canadians", - "cananbis", "cannabis", - "cancelas", "cancels", - "canceles", "cancels", - "cancells", "cancels", - "canceres", "cancers", - "cancerns", "cancers", - "cancerus", "cancers", - "candiate", "candidate", - "candiens", "candies", - "canistre", "canister", - "cannabil", "cannibal", - "cannbial", "cannibal", - "cannibas", "cannabis", - "cansiter", "canister", - "capitans", "captains", - "capitola", "capital", - "capitulo", "capitol", - "capmbell", "campbell", - "capsuels", "capsules", - "capsulse", "capsules", - "capsumel", "capsule", - "capteurs", "captures", - "captials", "capitals", - "captians", "captains", - "capusles", "capsules", - "caputres", "captures", - "cardboad", "cardboard", - "cardianl", "cardinal", - "cardnial", "cardinal", - "careflly", "carefully", - "carefull", "careful", - "carefuly", "carefully", - "caricate", "caricature", - "caridgan", "cardigan", - "caridnal", "cardinal", - "carinval", "carnival", - "carloina", "carolina", - "carnagie", "carnegie", - "carnigie", "carnegie", - "carnvial", "carnival", - "carrotts", "carrots", - "carrotus", "carrots", - "cartells", "cartels", - "cartmaan", "cartman", - "cartride", "cartridge", - "cartrige", "cartridge", - "carvinal", "carnival", - "casaulty", "casualty", - "casheirs", "cashiers", - "cashieer", "cashier", - "cashires", "cashiers", - "castleos", "castles", - "castlers", "castles", - "casulaty", "casualty", - "cataclym", "cataclysm", - "catagory", "category", - "cataline", "catiline", - "cataloge", "catalogue", - "catalsyt", "catalyst", - "cataylst", "catalyst", - "cathloic", "catholic", - "catlayst", "catalyst", - "caucasin", "caucasian", - "causalty", "casualty", - "cellural", "cellular", - "celullar", "cellular", - "celverly", "cleverly", - "cemetary", "cemetery", - "centeres", "centers", - "centerns", "centers", - "centrase", "centres", - "centrers", "centres", - "ceratine", "creatine", - "cerberal", "cerebral", - "cerbreus", "cerberus", - "cerbures", "cerberus", - "ceremone", "ceremonies", - "cerimony", "ceremony", - "ceromony", "ceremony", - "certainy", "certainty", - "challege", "challenge", - "chambear", "chamber", - "chambres", "chambers", - "champage", "champagne", - "chanisaw", "chainsaw", - "chanlder", "chandler", - "charcaol", "charcoal", - "chargehr", "charger", - "chargeur", "charger", - "chariman", "chairman", - "charimsa", "charisma", - "charmisa", "charisma", - "charocal", "charcoal", - "charsima", "charisma", - "chasiers", "cashiers", - "chassids", "chassis", - "chassies", "chassis", - "chatolic", "catholic", - "chcukles", "chuckles", - "checkare", "checker", - "checkear", "checker", - "cheesees", "cheeses", - "cheeseus", "cheeses", - "cheetoos", "cheetos", - "chemcial", "chemical", - "chemisty", "chemistry", - "chernobl", "chernobyl", - "chiansaw", "chainsaw", - "chidlish", "childish", - "chihuaha", "chihuahua", - "childres", "childrens", - "chillade", "chilled", - "chillead", "chilled", - "chillend", "chilled", - "chilvary", "chivalry", - "chinesse", "chinese", - "chivarly", "chivalry", - "chivlary", "chivalry", - "chlidish", "childish", - "chlroine", "chlorine", - "chmabers", "chambers", - "chocolae", "chocolates", - "chocolet", "chocolates", - "choesive", "cohesive", - "choicers", "choices", - "cholrine", "chlorine", - "chorline", "chlorine", - "chracter", "character", - "christin", "christian", - "chroline", "chlorine", - "chromose", "chromosome", - "chronice", "chronicles", - "chruches", "churches", - "chuckels", "chuckles", - "cielings", "ceilings", - "cigarete", "cigarettes", - "cigarets", "cigarettes", - "cilmbers", "climbers", - "cilnatro", "cilantro", - "ciltoris", "clitoris", - "circiuts", "circuits", - "circkets", "crickets", - "circlebs", "circles", - "circluar", "circular", - "ciricuit", "circuit", - "cirlcing", "circling", - "ciruclar", "circular", - "clannand", "clannad", - "clarifiy", "clarify", - "clarskon", "clarkson", - "clasical", "classical", - "classrom", "classroom", - "classsic", "classics", - "clausens", "clauses", - "cleanies", "cleanse", - "cleasner", "cleanser", - "clenaser", "cleanser", - "clevelry", "cleverly", - "clhorine", "chlorine", - "cliamtes", "climates", - "cliantro", "cilantro", - "clickare", "clicker", - "clickbat", "clickbait", - "clickear", "clicker", - "clientes", "clients", - "clincial", "clinical", - "clinicas", "clinics", - "clinicos", "clinics", - "clipboad", "clipboard", - "clitiros", "clitoris", - "closeing", "closing", - "closeley", "closely", - "clyamore", "claymore", - "clyinder", "cylinder", - "cmoputer", "computer", - "coindice", "coincide", - "collapes", "collapse", - "collares", "collars", - "collaris", "collars", - "collaros", "collars", - "collaspe", "collapse", - "colleage", "colleagues", - "collecte", "collective", - "collegue", "colleague", - "collisin", "collisions", - "collosal", "colossal", - "collpase", "collapse", - "coloardo", "colorado", - "colordao", "colorado", - "colubmia", "columbia", - "columnas", "columns", - "comadres", "comrades", - "comander", "commander", - "comandos", "commandos", - "comapany", "company", - "comapres", "compares", - "combiens", "combines", - "combinig", "combining", - "comediac", "comedic", - "comedias", "comedians", - "comestic", "cosmetic", - "comision", "commission", - "comiting", "committing", - "comitted", "committed", - "comittee", "committee", - "commandd", "commanded", - "commecen", "commence", - "commedic", "comedic", - "commense", "commenters", - "commenty", "commentary", - "commiest", "commits", - "commited", "committed", - "commitee", "committee", - "commites", "commits", - "committe", "committee", - "committs", "commits", - "commitus", "commits", - "commmand", "command", - "communit", "communist", - "companis", "companions", - "comparse", "compares", - "comparte", "compare", - "compasso", "compassion", - "compelte", "complete", - "compense", "compensate", - "complais", "complains", - "complane", "complacent", - "complate", "complacent", - "compleet", "complete", - "completi", "complexity", - "complets", "completes", - "complety", "completely", - "complexs", "complexes", - "complext", "complexity", - "complexy", "complexity", - "complict", "complicit", - "complier", "compiler", - "compones", "compose", - "componet", "components", - "componts", "compost", - "composet", "compost", - "composit", "compost", - "composte", "compose", - "comprese", "compressed", - "compreso", "compressor", - "compsers", "compress", - "comptown", "compton", - "compunet", "compute", - "computre", "compute", - "comradre", "comrade", - "comsetic", "cosmetic", - "conatins", "contains", - "conceald", "concealed", - "conceide", "conceived", - "conceled", "concede", - "concened", "concede", - "concepta", "conceptual", - "concered", "concede", - "concernt", "concert", - "concerte", "concrete", - "concesso", "concession", - "conceted", "concede", - "conceved", "concede", - "concibes", "concise", - "concider", "consider", - "concides", "concise", - "concious", "conscious", - "conclued", "conclude", - "concluse", "conclusive", - "concluso", "conclusion", - "concreet", "concrete", - "concrets", "concerts", - "condemnd", "condemned", - "conditon", "condition", - "condomes", "condoms", - "condomns", "condoms", - "conduict", "conduit", - "conected", "connected", - "conencts", "connects", - "confeses", "confess", - "confesos", "confess", - "confesso", "confession", - "configue", "configure", - "confilct", "conflict", - "confirmd", "confirmed", - "conflcit", "conflict", - "conflics", "conflicts", - "confrims", "confirms", - "conicide", "coincide", - "conlcude", "conclude", - "conqueor", "conquer", - "conquerd", "conquered", - "conqured", "conquered", - "conscent", "consent", - "consious", "conscious", - "constans", "constants", - "constast", "constants", - "constatn", "constant", - "constrat", "constraint", - "construt", "constructs", - "containd", "contained", - "containg", "containing", - "contaire", "containers", - "contanti", "contacting", - "contants", "constants", - "contense", "contenders", - "contenst", "contents", - "contexta", "contextual", - "contextl", "contextual", - "contians", "contains", - "contined", "continued", - "contines", "continents", - "continum", "continuum", - "continus", "continues", - "continut", "continuity", - "continuu", "continuous", - "contracr", "contractor", - "contracs", "contracts", - "controll", "control", - "contruct", "construct", - "convenit", "convenient", - "convento", "convention", - "converst", "converts", - "convertr", "converter", - "conviced", "convinced", - "convicto", "conviction", - "convingi", "convincing", - "convinse", "convinces", - "cooldows", "cooldowns", - "coordine", "coordinate", - "coralina", "carolina", - "corollla", "corolla", - "corolloa", "corolla", - "corosion", "corrosion", - "corpsers", "corpses", - "corrdior", "corridor", - "correcty", "correctly", - "correnti", "correcting", - "corretly", "correctly", - "corrupto", "corruption", - "cosemtic", "cosmetic", - "cosutmes", "costumes", - "couldnot", "couldnt", - "coulored", "coloured", - "counries", "countries", - "counseil", "counsel", - "counsole", "counsel", - "counterd", "countered", - "countert", "counteract", - "countres", "counters", - "courtrom", "courtroom", - "courtsey", "courtesy", - "cousines", "cousins", - "cousings", "cousins", - "coutners", "counters", - "covanent", "covenant", - "coverted", "converted", - "coyotees", "coyotes", - "cpatains", "captains", - "cranbery", "cranberry", - "crayones", "crayons", - "creaeted", "created", - "createin", "creatine", - "createur", "creature", - "creatien", "creatine", - "creepgin", "creeping", - "cricling", "circling", - "cringely", "cringey", - "cringery", "cringey", - "criticas", "critics", - "critices", "critics", - "criticie", "criticise", - "criticim", "criticisms", - "criticis", "critics", - "criticms", "critics", - "criticos", "critics", - "criticts", "critics", - "criticus", "critics", - "critiera", "criteria", - "critized", "criticized", - "croatioa", "croatia", - "crossfie", "crossfire", - "crosshar", "crosshair", - "crosspot", "crosspost", - "crowbahr", "crowbar", - "cruasder", "crusader", - "cruciaal", "crucial", - "crucibel", "crucible", - "cruicble", "crucible", - "crusdaer", "crusader", - "crusiers", "cruisers", - "crusiing", "cruising", - "cruthces", "crutches", - "cthulhlu", "cthulhu", - "cthulluh", "cthulhu", - "cubpoard", "cupboard", - "cuddleys", "cuddles", - "culprint", "culprit", - "cultrual", "cultural", - "culutral", "cultural", - "cupbaord", "cupboard", - "cupborad", "cupboard", - "curcible", "crucible", - "curisers", "cruisers", - "curising", "cruising", - "currecny", "currency", - "currence", "currencies", - "currenly", "currently", - "currenty", "currently", - "cursader", "crusader", - "custcene", "cutscene", - "cutsceen", "cutscene", - "cutscens", "cutscenes", - "cutsence", "cutscene", - "cylcists", "cyclists", - "cylidner", "cylinder", - "cylindre", "cylinder", - "cynisicm", "cynicism", - "cyrstals", "crystals", - "dacquiri", "daiquiri", - "daimonds", "diamonds", - "dangeros", "dangers", - "dangerus", "dangers", - "darkenss", "darkness", - "darnkess", "darkness", - "dashboad", "dashboard", - "daugther", "daughter", - "deadlfit", "deadlift", - "deadlifs", "deadlifts", - "deafauts", "defaults", - "deafeted", "defeated", - "deafults", "defaults", - "dealying", "delaying", - "deamenor", "demeanor", - "deathcat", "deathmatch", - "debuffes", "debuffs", - "debufffs", "debuffs", - "decalred", "declared", - "decalres", "declares", - "decembre", "december", - "decidely", "decidedly", - "decieved", "deceived", - "decifits", "deficits", - "decipted", "depicted", - "declears", "declares", - "declinig", "declining", - "decmeber", "december", - "decribed", "described", - "decribes", "describes", - "dedicato", "dedication", - "deductie", "deductible", - "defautls", "defaults", - "defectos", "defects", - "defectus", "defects", - "defendas", "defends", - "defendes", "defenders", - "defendis", "defends", - "defendre", "defender", - "defendrs", "defends", - "defensea", "defenseman", - "defensen", "defenseman", - "defensie", "defensive", - "defetead", "defeated", - "deffined", "defined", - "deficiet", "deficient", - "definate", "definite", - "definaty", "definitely", - "definety", "definitely", - "definito", "definition", - "definitv", "definitive", - "deflatin", "deflation", - "deflecto", "deflection", - "defualts", "defaults", - "degarded", "degraded", - "degenere", "degenerate", - "degraged", "degrade", - "degrated", "degrade", - "deisgned", "designed", - "deisgner", "designer", - "dekstops", "desktops", - "delcared", "declared", - "delcares", "declares", - "delepted", "depleted", - "delivere", "deliveries", - "delpeted", "depleted", - "delpoyed", "deployed", - "delyaing", "delaying", - "demandas", "demands", - "demandes", "demands", - "demenaor", "demeanor", - "democray", "democracy", - "demolito", "demolition", - "denseley", "densely", - "densitiy", "density", - "deomcrat", "democrat", - "deovtion", "devotion", - "departer", "departure", - "departue", "departure", - "depcited", "depicted", - "depelted", "depleted", - "dependat", "dependant", - "depictes", "depicts", - "depictin", "depictions", - "depolyed", "deployed", - "depositd", "deposited", - "depostis", "deposits", - "depresse", "depressive", - "depresso", "depression", - "derivate", "derivative", - "descened", "descend", - "descibed", "described", - "descirbe", "describe", - "descrise", "describes", - "desgined", "designed", - "desginer", "designer", - "desicive", "decisive", - "designad", "designated", - "designes", "designs", - "designet", "designated", - "desinged", "designed", - "desinger", "designer", - "desitned", "destined", - "desktiop", "desktop", - "desorder", "disorder", - "despides", "despised", - "despiste", "despise", - "destiney", "destiny", - "destinty", "destiny", - "destkops", "desktops", - "destorys", "destroys", - "destrose", "destroyers", - "destroyd", "destroyed", - "destroyr", "destroyers", - "detalied", "detailed", - "detectas", "detects", - "detectes", "detects", - "detectie", "detectives", - "determen", "determines", - "devasted", "devastated", - "develope", "develop", - "devialet", "deviate", - "deviatie", "deviate", - "devilers", "delivers", - "devloved", "devolved", - "devovled", "devolved", - "diaganol", "diagonal", - "diagnoal", "diagonal", - "diagnoes", "diagnose", - "diagnosi", "diagnostic", - "diagonse", "diagnose", - "diahrrea", "diarrhea", - "dialetcs", "dialects", - "dialgoue", "dialogue", - "dialouge", "dialogue", - "diarreah", "diarrhea", - "diarreha", "diarrhea", - "dichtomy", "dichotomy", - "dickisch", "dickish", - "dicovers", "discovers", - "dicovery", "discovery", - "dicussed", "discussed", - "diferent", "different", - "differnt", "different", - "difficut", "difficulty", - "diffrent", "different", - "diganose", "diagnose", - "dignitiy", "dignity", - "dimaonds", "diamonds", - "dinasour", "dinosaur", - "dinosaus", "dinosaurs", - "dinosuar", "dinosaur", - "dinsoaur", "dinosaur", - "dionsaur", "dinosaur", - "diphtong", "diphthong", - "diplomma", "diploma", - "dipthong", "diphthong", - "direclty", "directly", - "directin", "directions", - "directix", "directx", - "directos", "directors", - "directoy", "directory", - "directrx", "directx", - "dirfting", "drifting", - "disabeld", "disabled", - "disabels", "disables", - "disagred", "disagreed", - "disagres", "disagrees", - "disbaled", "disabled", - "disbales", "disables", - "disbelif", "disbelief", - "dischard", "discharged", - "dischare", "discharged", - "discound", "discounted", - "discoure", "discourse", - "discoved", "discovered", - "discreto", "discretion", - "discribe", "describe", - "disentry", "dysentery", - "disgiuse", "disguise", - "dishoner", "dishonored", - "dishonet", "dishonesty", - "dislikse", "dislikes", - "dismante", "dismantle", - "dismisse", "dismissive", - "disolved", "dissolved", - "dispacth", "dispatch", - "dispalys", "displays", - "dispence", "dispense", - "dispersa", "dispensary", - "displayd", "displayed", - "disposle", "dispose", - "disposte", "dispose", - "dispoves", "dispose", - "disptach", "dispatch", - "disricts", "districts", - "dissovle", "dissolve", - "distates", "distaste", - "distatse", "distaste", - "disticnt", "distinct", - "distorto", "distortion", - "distrcit", "district", - "districs", "districts", - "disturbd", "disturbed", - "disupted", "disputed", - "disuptes", "disputes", - "diversed", "diverse", - "diversiy", "diversify", - "dividens", "dividends", - "divintiy", "divinity", - "divisons", "divisions", - "doapmine", "dopamine", - "docrines", "doctrines", - "docrtine", "doctrine", - "doctines", "doctrines", - "doctirne", "doctrine", - "doctrins", "doctrines", - "dogamtic", "dogmatic", - "dolhpins", "dolphins", - "domapine", "dopamine", - "domecrat", "democrat", - "domiante", "dominate", - "dominato", "domination", - "dominats", "dominates", - "dominent", "dominant", - "dominoin", "dominion", - "donwload", "download", - "donwvote", "downvote", - "doomdsay", "doomsday", - "doosmday", "doomsday", - "doplhins", "dolphins", - "dopmaine", "dopamine", - "dormtund", "dortmund", - "dortumnd", "dortmund", - "dotrmund", "dortmund", - "douchely", "douchey", - "doucheus", "douches", - "dowloads", "downloads", - "downlaod", "download", - "downloas", "downloads", - "downstar", "downstairs", - "downvore", "downvoters", - "downvotr", "downvoters", - "downvots", "downvotes", - "draculea", "dracula", - "draculla", "dracula", - "dragones", "dragons", - "dragonus", "dragons", - "drfiting", "drifting", - "driectly", "directly", - "drifitng", "drifting", - "driveris", "drivers", - "drotmund", "dortmund", - "duaghter", "daughter", - "dumbbels", "dumbbells", - "dumptser", "dumpster", - "dumspter", "dumpster", - "dunegons", "dungeons", - "dungeoun", "dungeon", - "dungoens", "dungeons", - "dupicate", "duplicate", - "duplicas", "duplicates", - "dwarvens", "dwarves", - "dyanmics", "dynamics", - "dyanmite", "dynamite", - "dymanics", "dynamics", - "dymanite", "dynamite", - "dynastry", "dynasty", - "dysentry", "dysentery", - "dysphora", "dysphoria", - "earilest", "earliest", - "eatswood", "eastwood", - "eceonomy", "economy", - "ecidious", "deciduous", - "ecologia", "ecological", - "ecomonic", "economic", - "ecstacys", "ecstasy", - "ecstascy", "ecstasy", - "ecstasty", "ecstasy", - "ectastic", "ecstatic", - "editoras", "editors", - "editores", "editors", - "efficent", "efficient", - "egpytian", "egyptian", - "egyptain", "egyptian", - "egytpian", "egyptian", - "ehtereal", "ethereal", - "ehternet", "ethernet", - "eigtheen", "eighteen", - "electhor", "electro", - "electorn", "electron", - "elementy", "elementary", - "elephans", "elephants", - "elevatin", "elevation", - "elicided", "elicited", - "eligable", "eligible", - "elimiate", "eliminate", - "eliminas", "eliminates", - "elitisim", "elitism", - "elitistm", "elitism", - "ellected", "elected", - "embarass", "embarrass", - "embargos", "embargoes", - "embarras", "embarrass", - "embassay", "embassy", - "embassey", "embassy", - "embasssy", "embassy", - "emergend", "emerged", - "emergerd", "emerged", - "eminated", "emanated", - "emminent", "eminent", - "emmisary", "emissary", - "emmision", "emission", - "emmiting", "emitting", - "emmitted", "emitted", - "empathie", "empathize", - "empirial", "empirical", - "emulatin", "emulation", - "enahnces", "enhances", - "enchanct", "enchant", - "encolsed", "enclosed", - "endanged", "endangered", - "endevors", "endeavors", - "endevour", "endeavour", - "endlessy", "endlessly", - "endorces", "endorse", - "engeneer", "engineer", - "engeries", "energies", - "engineed", "engineered", - "engrames", "engrams", - "engramms", "engrams", - "enigneer", "engineer", - "enitrely", "entirely", - "enlcosed", "enclosed", - "enlsaved", "enslaved", - "ensalved", "enslaved", - "enterity", "entirety", - "entierly", "entirely", - "entierty", "entirety", - "entilted", "entitled", - "entirley", "entirely", - "entiteld", "entitled", - "entitity", "entity", - "entropay", "entropy", - "entrophy", "entropy", - "ephipany", "epiphany", - "epihpany", "epiphany", - "epilespy", "epilepsy", - "epilgoue", "epilogue", - "episdoes", "episodes", - "epitomie", "epitome", - "epliepsy", "epilepsy", - "epliogue", "epilogue", - "epsiodes", "episodes", - "epsresso", "espresso", - "eqaulity", "equality", - "eqaution", "equation", - "equailty", "equality", - "eraticly", "erratically", - "erroneos", "erroneous", - "errupted", "erupted", - "escalato", "escalation", - "esctatic", "ecstatic", - "esential", "essential", - "esitmate", "estimate", - "esperate", "separate", - "esportes", "esports", - "estiamte", "estimate", - "estoeric", "esoteric", - "estonija", "estonia", - "estoniya", "estonia", - "etherael", "ethereal", - "etherent", "ethernet", - "ethicaly", "ethically", - "etiquete", "etiquette", - "etrailer", "retailer", - "eugencis", "eugenics", - "eugneics", "eugenics", - "euhporia", "euphoria", - "euhporic", "euphoric", - "euorpean", "european", - "euphoira", "euphoria", - "euphroia", "euphoria", - "euphroic", "euphoric", - "europian", "european", - "eurpoean", "european", - "evangers", "avengers", - "everyons", "everyones", - "evidencd", "evidenced", - "evidende", "evidenced", - "evloving", "evolving", - "evolveds", "evolves", - "evolveos", "evolves", - "evovling", "evolving", - "excecute", "execute", - "excedded", "exceeded", - "excelent", "excellent", - "exceptin", "exceptions", - "excerise", "exercise", - "excisted", "existed", - "exclusie", "exclusives", - "exculded", "excluded", - "exculdes", "excludes", - "exection", "execution", - "exectued", "executed", - "executie", "executive", - "executin", "execution", - "exellent", "excellent", - "exerbate", "exacerbate", - "exercide", "exercised", - "exercies", "exercise", - "exersice", "exercise", - "exersize", "exercise", - "exhalted", "exalted", - "exhaustn", "exhaustion", - "exhausto", "exhaustion", - "exicting", "exciting", - "exisitng", "existing", - "existane", "existence", - "existant", "existent", - "existend", "existed", - "exlcuded", "excluded", - "exlcudes", "excludes", - "exlporer", "explorer", - "exoticas", "exotics", - "exoticos", "exotics", - "expalins", "explains", - "expandas", "expands", - "expandes", "expands", - "expansie", "expansive", - "expectes", "expects", - "expectus", "expects", - "expedito", "expedition", - "expences", "expense", - "expensie", "expense", - "expensve", "expense", - "expertas", "experts", - "expertis", "experts", - "expertos", "experts", - "expireds", "expires", - "explaind", "explained", - "explaing", "explaining", - "expliots", "exploits", - "explodie", "explode", - "exploint", "exploit", - "explosie", "explosive", - "explosin", "explosions", - "exploted", "explode", - "expoldes", "explodes", - "expolits", "exploits", - "exportas", "exports", - "exportes", "exports", - "exportfs", "exports", - "exposees", "exposes", - "exposito", "exposition", - "expresse", "expressive", - "expresss", "expresses", - "expressy", "expressly", - "exressed", "expressed", - "exsitent", "existent", - "exsiting", "existing", - "extactly", "exactly", - "extemely", "extremely", - "extendes", "extends", - "extendos", "extends", - "extenion", "extension", - "extensie", "extensive", - "extensis", "extensions", - "extortin", "extortion", - "extracto", "extraction", - "extreems", "extremes", - "extremly", "extremely", - "eygptian", "egyptian", - "faboulus", "fabulous", - "fabricas", "fabrics", - "fabrices", "fabrics", - "fabricus", "fabrics", - "faceplam", "facepalm", - "facilisi", "facilities", - "faciltiy", "facility", - "facsists", "fascists", - "factores", "factors", - "factorys", "factors", - "factualy", "factually", - "faggotts", "faggots", - "faggotus", "faggots", - "falcones", "falcons", - "falgship", "flagship", - "faliures", "failures", - "falseley", "falsely", - "falshing", "flashing", - "falvored", "flavored", - "falvours", "flavours", - "familair", "familiar", - "famoulsy", "famously", - "fanatism", "fanaticism", - "fanatsic", "fanatics", - "fanserve", "fanservice", - "fantasty", "fantasy", - "farcking", "fracking", - "fascisim", "fascism", - "fashiond", "fashioned", - "fasicsts", "fascists", - "fatigure", "fatigue", - "favorits", "favorites", - "favourie", "favourites", - "feasable", "feasible", - "feasbile", "feasible", - "febraury", "february", - "februray", "february", - "feburary", "february", - "fedility", "fidelity", - "fedorahs", "fedoras", - "fedorans", "fedoras", - "feilding", "fielding", - "feisable", "feasible", - "feitshes", "fetishes", - "feltcher", "fletcher", - "felxible", "flexible", - "feminint", "femininity", - "feminsim", "feminism", - "feromone", "pheromone", - "fesiable", "feasible", - "festivas", "festivals", - "festivle", "festive", - "fictious", "fictitious", - "fideling", "fielding", - "fideltiy", "fidelity", - "fiedling", "fielding", - "fiedlity", "fidelity", - "fighitng", "fighting", - "figthing", "fighting", - "fileding", "fielding", - "fimilies", "families", - "finacial", "financial", - "fineshes", "finesse", - "fingersi", "fingertips", - "finnisch", "finnish", - "finsihes", "finishes", - "firebals", "fireballs", - "firendly", "friendly", - "firmwear", "firmware", - "firwmare", "firmware", - "flaghsip", "flagship", - "flamable", "flammable", - "flasghip", "flagship", - "flatterd", "flattered", - "flatteur", "flatter", - "flattire", "flatter", - "flavores", "flavors", - "flechter", "fletcher", - "flecther", "fletcher", - "flemmish", "flemish", - "flethcer", "fletcher", - "flexbile", "flexible", - "flexibel", "flexible", - "flippade", "flipped", - "flitered", "filtered", - "florecen", "florence", - "floridia", "florida", - "floruide", "fluoride", - "floruish", "flourish", - "flourine", "fluorine", - "floursih", "flourish", - "fluorish", "flourish", - "fluroide", "fluoride", - "folowing", "following", - "fontrier", "fontier", - "forasken", "forsaken", - "forbiden", "forbidden", - "foreamrs", "forearms", - "foreksin", "foreskin", - "forenics", "forensic", - "forenisc", "forensic", - "foresnic", "forensic", - "foreward", "foreword", - "foricbly", "forcibly", - "forigven", "forgiven", - "formatin", "formation", - "formelly", "formerly", - "formuals", "formulas", - "fornesic", "forensic", - "forresst", "forrest", - "forsekan", "forsaken", - "forsekin", "foreskin", - "forsenic", "forensic", - "forskaen", "forsaken", - "forsting", "frosting", - "fortitue", "fortitude", - "fortunae", "fortune", - "fortunte", "fortune", - "forumlas", "formulas", - "forunner", "forerunner", - "fossiles", "fossils", - "fossilis", "fossils", - "foundary", "foundry", - "fountian", "fountain", - "fourties", "forties", - "fowrards", "forwards", - "frackign", "fracking", - "framgent", "fragment", - "franches", "franchise", - "franchie", "franchises", - "franciso", "francisco", - "frankiln", "franklin", - "franlkin", "franklin", - "freckels", "freckles", - "freindly", "friendly", - "freqency", "frequency", - "frequeny", "frequency", - "friendle", "friendlies", - "friendsi", "friendlies", - "frimware", "firmware", - "frogiven", "forgiven", - "frointer", "frontier", - "fromerly", "formerly", - "froniter", "frontier", - "fronteir", "frontier", - "frosaken", "forsaken", - "frquency", "frequency", - "frutcose", "fructose", - "fucntion", "function", - "fufilled", "fulfilled", - "fulfiled", "fulfilled", - "fullfill", "fulfill", - "funciton", "function", - "fundirse", "fundies", - "funniliy", "funnily", - "funnilly", "funnily", - "furctose", "fructose", - "furition", "fruition", - "furuther", "further", - "futurers", "futures", - "futureus", "futures", - "gamemdoe", "gamemode", - "gamepaly", "gameplay", - "gamergat", "gamertag", - "gammeode", "gamemode", - "ganerate", "generate", - "garantee", "guarantee", - "gardient", "gradient", - "garfeild", "garfield", - "garfiled", "garfield", - "garflied", "garfield", - "garnison", "garrison", - "garrions", "garrison", - "garriosn", "garrison", - "garrsion", "garrison", - "gatherig", "gatherings", - "gauarana", "guaraná", - "gauntelt", "gauntlet", - "gauntles", "gauntlets", - "gaurdian", "guardian", - "gaurding", "guarding", - "gautnlet", "gauntlet", - "gemoetry", "geometry", - "generaly", "generally", - "generase", "generates", - "generats", "generates", - "genialia", "genitalia", - "genisues", "geniuses", - "genitala", "genitalia", - "genrates", "generates", - "gentials", "genitals", - "gentlemn", "gentlemen", - "genuises", "geniuses", - "geograpy", "geography", - "geomerty", "geometry", - "geomtery", "geometry", - "germanos", "germans", - "germanus", "germans", - "gernades", "grenades", - "giagbyte", "gigabyte", - "gigabtye", "gigabyte", - "gigaybte", "gigabyte", - "gigbayte", "gigabyte", - "gignatic", "gigantic", - "giltched", "glitched", - "giltches", "glitches", - "girafffe", "giraffe", - "girefing", "griefing", - "girlling", "grilling", - "gladiatr", "gladiator", - "glichted", "glitched", - "glichtes", "glitches", - "glicthed", "glitched", - "glicthes", "glitches", - "glitchey", "glitchy", - "glitchly", "glitchy", - "glitchty", "glitchy", - "glithced", "glitched", - "glithces", "glitches", - "gloablly", "globally", - "glodberg", "goldberg", - "glodfish", "goldfish", - "gloriuos", "glorious", - "gltiched", "glitched", - "gltiches", "glitches", - "gmaertag", "gamertag", - "goblings", "goblins", - "goddammn", "goddamn", - "goddammt", "goddammit", - "godesses", "goddesses", - "godlberg", "goldberg", - "godlfish", "goldfish", - "godounov", "godunov", - "godpseed", "godspeed", - "godspede", "godspeed", - "goldifsh", "goldfish", - "gonewidl", "gonewild", - "goodlcuk", "goodluck", - "goregous", "gorgeous", - "gorgoeus", "gorgeous", - "gorillia", "gorilla", - "gorillla", "gorilla", - "gospells", "gospels", - "gottleib", "gottlieb", - "gourmelt", "gourmet", - "gourment", "gourmet", - "gouvener", "governor", - "govement", "government", - "goverend", "governed", - "govermet", "government", - "governer", "governor", - "gradualy", "gradually", - "grafield", "garfield", - "grafitti", "graffiti", - "grahpics", "graphics", - "grahpite", "graphite", - "graident", "gradient", - "granolla", "granola", - "graphcis", "graphics", - "grapichs", "graphics", - "grappnel", "grapple", - "greandes", "grenades", - "greatful", "grateful", - "greeneer", "greener", - "greenhoe", "greenhouse", - "greenlad", "greenland", - "greenore", "greener", - "greusome", "gruesome", - "grieifng", "griefing", - "grifeing", "griefing", - "grizzlay", "grizzly", - "grizzley", "grizzly", - "grpahics", "graphics", - "grpahite", "graphite", - "gruseome", "gruesome", - "guantano", "guantanamo", - "guardain", "guardian", - "guardias", "guardians", - "guaridan", "guardian", - "guerrila", "guerrilla", - "guidence", "guidance", - "guiseppe", "giuseppe", - "guitards", "guitars", - "guitares", "guitars", - "guitarit", "guitarist", - "gullbile", "gullible", - "gunanine", "guanine", - "guniness", "guinness", - "gunniess", "guinness", - "guradian", "guardian", - "gurading", "guarding", - "gurantee", "guarantee", - "guresome", "gruesome", - "guttaral", "guttural", - "gutteral", "guttural", - "hacthing", "hatching", - "hafltime", "halftime", - "haircuit", "haircut", - "halfitme", "halftime", - "hallowen", "halloween", - "hamburgr", "hamburgers", - "hamitlon", "hamilton", - "hamliton", "hamilton", - "handcufs", "handcuffs", - "handeldy", "handedly", - "handlade", "handled", - "handlare", "handler", - "handledy", "handedly", - "hannbial", "hannibal", - "haording", "hoarding", - "hapening", "happening", - "happends", "happens", - "happenes", "happens", - "happilly", "happily", - "harldine", "hardline", - "harrased", "harassed", - "harrases", "harasses", - "hatchign", "hatching", - "hatesink", "heatsink", - "hathcing", "hatching", - "headachs", "headaches", - "headests", "headsets", - "headhsot", "headshot", - "headseat", "headset", - "healthit", "healthiest", - "heastink", "heatsink", - "heathern", "heathen", - "heatskin", "heatsink", - "heaviliy", "heavily", - "heavilly", "heavily", - "heavnely", "heavenly", - "hedeghog", "hedgehog", - "hegdehog", "hedgehog", - "heighest", "heights", - "heighted", "heightened", - "heirachy", "hierarchy", - "heistant", "hesitant", - "heistate", "hesitate", - "hellifre", "hellfire", - "helluvva", "helluva", - "helpfull", "helpful", - "heratige", "heritage", - "herclues", "hercules", - "heridity", "heredity", - "heroicas", "heroics", - "heroices", "heroics", - "heroicos", "heroics", - "heroicus", "heroics", - "hertiage", "heritage", - "herucles", "hercules", - "hestiant", "hesitant", - "hestiate", "hesitate", - "heveanly", "heavenly", - "hierachy", "hierarchy", - "hierarcy", "hierarchy", - "highlane", "highlander", - "hindiusm", "hinduism", - "hindusim", "hinduism", - "hinudism", "hinduism", - "hiptsers", "hipsters", - "hispanis", "hispanics", - "hispters", "hipsters", - "histroic", "historic", - "hodlings", "holdings", - "hoenstly", "honestly", - "hoildays", "holidays", - "holdiays", "holidays", - "hollywod", "hollywood", - "homeword", "homeworld", - "homineim", "hominem", - "homineum", "hominem", - "honeslty", "honestly", - "honeymon", "honeymoon", - "honsetly", "honestly", - "hopefuly", "hopefully", - "hopkings", "hopkins", - "hopsital", "hospital", - "horading", "hoarding", - "horzions", "horizons", - "hosptial", "hospital", - "hosteles", "hostels", - "hostiliy", "hostility", - "hotshoot", "hotshot", - "hotsport", "hotspot", - "hsyteria", "hysteria", - "htaching", "hatching", - "htiboxes", "hitboxes", - "huanting", "haunting", - "humaniod", "humanoid", - "humanite", "humanities", - "humantiy", "humanity", - "humerous", "humorous", - "huminoid", "humanoid", - "humitidy", "humidity", - "humoural", "humoral", - "humouros", "humorous", - "humurous", "humorous", - "hunderds", "hundreds", - "hundread", "hundred", - "hungarin", "hungarian", - "huntmsan", "huntsman", - "hutnsman", "huntsman", - "hybrides", "hybrids", - "hybridus", "hybrids", - "hydorgen", "hydrogen", - "hydratin", "hydration", - "hydregon", "hydrogen", - "hygience", "hygiene", - "hygienne", "hygiene", - "hyperbel", "hyperbole", - "hypocrit", "hypocrite", - "hyponsis", "hypnosis", - "hyrdogen", "hydrogen", - "icefrong", "icefrog", - "icelings", "ceilings", - "idaeidae", "idea", - "idealogy", "ideology", - "idealsim", "idealism", - "idenfity", "identify", - "idenitfy", "identify", - "identite", "identities", - "ideologe", "ideologies", - "illiegal", "illegal", - "illinios", "illinois", - "illionis", "illinois", - "illnesss", "illnesses", - "illumini", "illuminati", - "illustre", "illustrate", - "illution", "illusion", - "ilogical", "illogical", - "ilterate", "literate", - "imapired", "impaired", - "imgrants", "migrants", - "imigrant", "emigrant", - "immboile", "immobile", - "immenint", "imminent", - "immersie", "immerse", - "immersve", "immerse", - "immitate", "imitate", - "immoblie", "immobile", - "immortas", "immortals", - "impactes", "impacts", - "impactos", "impacts", - "imparied", "impaired", - "imperavi", "imperative", - "imperfet", "imperfect", - "implemet", "implements", - "implosed", "implode", - "impluses", "impulses", - "imporper", "improper", - "importas", "imports", - "importen", "importance", - "importes", "imports", - "imporved", "improved", - "imporves", "improves", - "impropre", "improper", - "improted", "imported", - "improvie", "improvised", - "impusles", "impulses", - "imrpoved", "improved", - "imrpoves", "improves", - "inbetwen", "between", - "inclince", "incline", - "inclinde", "incline", - "includng", "including", - "incorect", "incorrect", - "incuding", "including", - "inculded", "included", - "indianas", "indians", - "indiands", "indians", - "indiania", "indiana", - "indianna", "indiana", - "indianos", "indians", - "indicato", "indication", - "indicats", "indicators", - "indonesa", "indonesia", - "indulgue", "indulge", - "infantis", "infants", - "infantus", "infants", - "infarred", "infrared", - "infectin", "infections", - "infermon", "inferno", - "infiltre", "infiltrate", - "infintie", "infinite", - "infintiy", "infinity", - "inflatie", "inflate", - "influens", "influences", - "informas", "informs", - "informis", "informs", - "infromal", "informal", - "infromed", "informed", - "ingenius", "ingenious", - "ingition", "ignition", - "ingorant", "ignorant", - "inheriet", "inherit", - "inherint", "inherit", - "inhumaan", "inhuman", - "inhumain", "inhuman", - "inifnite", "infinite", - "inifnity", "infinity", - "inisghts", "insights", - "initails", "initials", - "initaite", "initiate", - "initaled", "initialed", - "initally", "initially", - "initialy", "initially", - "initmacy", "intimacy", - "initmate", "intimate", - "injustie", "injustices", - "inlcuded", "included", - "inlcudes", "includes", - "innocens", "innocents", - "innocuos", "innocuous", - "innvoate", "innovate", - "inocence", "innocence", - "inpolite", "impolite", - "inpsired", "inspired", - "inquirey", "inquiry", - "inquirie", "inquire", - "inquiriy", "inquiry", - "inrested", "inserted", - "insanley", "insanely", - "insectes", "insects", - "insectos", "insects", - "insertas", "inserts", - "insertes", "inserts", - "insertos", "inserts", - "insidios", "insidious", - "insigths", "insights", - "insipred", "inspired", - "insipres", "inspires", - "insistas", "insists", - "insistes", "insists", - "insistis", "insists", - "insmonia", "insomnia", - "insomina", "insomnia", - "insonmia", "insomnia", - "inspried", "inspired", - "inspries", "inspires", - "instanse", "instances", - "instanty", "instantly", - "instered", "inserted", - "insticnt", "instinct", - "instincs", "instincts", - "institue", "institute", - "insultas", "insults", - "insultes", "insults", - "insultos", "insults", - "intamicy", "intimacy", - "intamite", "intimate", - "intendes", "intends", - "intendos", "intends", - "intentas", "intents", - "intented", "intended", - "interace", "interacted", - "interacs", "interacts", - "interect", "interacted", - "interent", "internet", - "interese", "interested", - "interfce", "interface", - "intergal", "integral", - "internts", "interns", - "internus", "interns", - "interpet", "interpret", - "interrim", "interim", - "interrut", "interrupt", - "interste", "interstate", - "interupt", "interrupt", - "intevene", "intervene", - "intially", "initially", - "intiials", "initials", - "intimaty", "intimately", - "intimide", "intimidate", - "intregal", "integral", - "intriuge", "intrigue", - "introdue", "introduces", - "introdus", "introduces", - "introvet", "introvert", - "intruige", "intrigue", - "intutive", "intuitive", - "inudstry", "industry", - "inventer", "inventor", - "invertes", "inverse", - "invincil", "invincible", - "invitato", "invitation", - "invloved", "involved", - "invloves", "involves", - "invovled", "involved", - "invovles", "involves", - "iranains", "iranians", - "iraninas", "iranians", - "iritable", "irritable", - "iritated", "irritated", - "ironicly", "ironically", - "irritato", "irritation", - "isalmist", "islamist", - "isarelis", "israelis", - "islamits", "islamist", - "islamsit", "islamist", - "islandes", "islanders", - "ismalist", "islamist", - "isntalls", "installs", - "isolatie", "isolate", - "israelli", "israeli", - "israleis", "israelis", - "isralies", "israelis", - "isrealis", "israelis", - "issueing", "issuing", - "italains", "italians", - "jaguards", "jaguars", - "jaguares", "jaguars", - "jailbrek", "jailbreak", - "jaimacan", "jamaican", - "jamacain", "jamaican", - "jamaicia", "jamaica", - "jamiacan", "jamaican", - "januaray", "january", - "janurary", "january", - "jeapardy", "jeopardy", - "jefferry", "jeffery", - "jefferty", "jeffery", - "jennigns", "jennings", - "jeoprady", "jeopardy", - "jepoardy", "jeopardy", - "jerusalm", "jerusalem", - "jewelrey", "jewelry", - "jewllery", "jewellery", - "joanthan", "jonathan", - "joepardy", "jeopardy", - "johanine", "johannine", - "jonatahn", "jonathan", - "journaal", "journal", - "journied", "journeyed", - "journies", "journeys", - "joysitck", "joystick", - "juadaism", "judaism", - "judaisim", "judaism", - "judgemet", "judgements", - "juducial", "judicial", - "jugnling", "jungling", - "junglign", "jungling", - "junlging", "jungling", - "justifiy", "justify", - "juveline", "juvenile", - "juvenlie", "juvenile", - "katemine", "ketamine", - "kennedey", "kennedy", - "ketmaine", "ketamine", - "keybaord", "keyboard", - "keyboars", "keyboards", - "keyborad", "keyboard", - "keychian", "keychain", - "kicthens", "kitchens", - "kindgoms", "kingdoms", - "kittiens", "kitties", - "knockbak", "knockback", - "knowlege", "knowledge", - "knuckels", "knuckles", - "koreanos", "koreans", - "kunckles", "knuckles", - "kurdisch", "kurdish", - "labatory", "lavatory", - "labenese", "lebanese", - "laboraty", "laboratory", - "laguages", "languages", - "landscae", "landscapes", - "langauge", "language", - "lanucher", "launcher", - "lanuches", "launches", - "laodouts", "loadouts", - "larwence", "lawrence", - "lasagnea", "lasagna", - "lasagnia", "lasagna", - "laucnhed", "launched", - "laucnher", "launcher", - "laucnhes", "launches", - "laundrey", "laundry", - "lawernce", "lawrence", - "lazyness", "laziness", - "leaglize", "legalize", - "lecteurs", "lectures", - "lecutres", "lectures", - "lefitsts", "leftists", - "leftsits", "leftists", - "legenday", "legendary", - "legionis", "legions", - "legitimt", "legitimate", - "lengthes", "lengths", - "lengthly", "lengthy", - "lentiles", "lentils", - "lentills", "lentils", - "lesbains", "lesbians", - "lesibans", "lesbians", - "levander", "lavender", - "levelign", "leveling", - "levetate", "levitate", - "leviathn", "leviathan", - "levleing", "leveling", - "liberato", "liberation", - "libertae", "liberate", - "libertea", "liberate", - "librarse", "libraries", - "licencie", "licence", - "licencse", "licence", - "liebrals", "liberals", - "liekable", "likeable", - "lifepsan", "lifespan", - "lifestel", "lifesteal", - "lifestye", "lifestyle", - "lighitng", "lighting", - "lightnig", "lightning", - "lightres", "lighters", - "lightrom", "lightroom", - "ligthers", "lighters", - "ligthing", "lighting", - "likebale", "likeable", - "limitant", "militant", - "limitato", "limitation", - "lincolin", "lincoln", - "lincolon", "lincoln", - "lineupes", "lineups", - "lingeire", "lingerie", - "lingiere", "lingerie", - "linnaena", "linnaean", - "lipstics", "lipsticks", - "liquidas", "liquids", - "liquides", "liquids", - "liquidos", "liquids", - "liscense", "license", - "lisenced", "silenced", - "listenes", "listens", - "listents", "listens", - "listners", "listeners", - "litature", "literature", - "litecion", "litecoin", - "liteicon", "litecoin", - "literaly", "literally", - "lithuana", "lithuania", - "litigato", "litigation", - "liverpol", "liverpool", - "locagion", "location", - "logtiech", "logitech", - "longitme", "longtime", - "longtiem", "longtime", - "looseley", "loosely", - "loreplay", "roleplay", - "luanched", "launched", - "luancher", "launcher", - "luanches", "launches", - "lubricat", "lubricant", - "lucifear", "lucifer", - "luckilly", "luckily", - "macarino", "macaroni", - "machiens", "machines", - "mackeral", "mackerel", - "macthups", "matchups", - "magasine", "magazine", - "magazins", "magazines", - "magentic", "magnetic", - "magicain", "magician", - "magisine", "magazine", - "magizine", "magazine", - "magnetis", "magnets", - "magnited", "magnitude", - "magnitue", "magnitude", - "mainfest", "manifest", - "maintian", "maintain", - "majoroty", "majority", - "makrsman", "marksman", - "malariya", "malaria", - "malasiya", "malaysia", - "malasyia", "malaysia", - "malayisa", "malaysia", - "malyasia", "malaysia", - "mamalian", "mammalian", - "manadrin", "mandarin", - "manaully", "manually", - "mandaste", "mandates", - "mandrain", "mandarin", - "mandrian", "mandarin", - "maneveur", "maneuver", - "manevuer", "maneuver", - "manfiest", "manifest", - "mangetic", "magnetic", - "manglade", "mangled", - "manifeso", "manifesto", - "manipule", "manipulate", - "manouver", "maneuver", - "manuales", "manuals", - "manuever", "maneuver", - "maraconi", "macaroni", - "maradeur", "marauder", - "maraduer", "marauder", - "maragret", "margaret", - "marbleds", "marbles", - "margerat", "margaret", - "margines", "margins", - "margings", "margins", - "marginis", "margins", - "marignal", "marginal", - "marilyin", "marilyn", - "marinens", "marines", - "markedet", "marketed", - "markeras", "markers", - "markerts", "markers", - "marniers", "mariners", - "marraige", "marriage", - "marryied", "married", - "marskman", "marksman", - "maruader", "marauder", - "marvelos", "marvelous", - "marxisim", "marxism", - "mascarra", "mascara", - "massacer", "massacre", - "massarce", "massacre", - "massasge", "massages", - "masscare", "massacre", - "masteris", "masteries", - "masturbe", "masturbate", - "materias", "materials", - "mathcups", "matchups", - "mathewes", "mathews", - "matieral", "material", - "matterss", "mattress", - "mauarder", "marauder", - "maximini", "maximizing", - "mayalsia", "malaysia", - "maybelle", "maybelline", - "maylasia", "malaysia", - "mccarhty", "mccarthy", - "mcgergor", "mcgregor", - "mchanics", "mechanics", - "mclarean", "mclaren", - "mcreggor", "mcgregor", - "meagtron", "megatron", - "meancing", "menacing", - "meaninng", "meaning", - "meatbals", "meatballs", - "mecahnic", "mechanic", - "mechanim", "mechanism", - "mechanis", "mechanics", - "medacine", "medicine", - "medatite", "meditate", - "medeival", "medieval", - "medevial", "medieval", - "mediavel", "medieval", - "medicaly", "medically", - "mediciad", "medicaid", - "medicins", "medicines", - "medicore", "mediocre", - "medievel", "medieval", - "mediocer", "mediocre", - "mediocry", "mediocrity", - "mediorce", "mediocre", - "meditato", "meditation", - "mediveal", "medieval", - "medoicre", "mediocre", - "meerkrat", "meerkat", - "megatorn", "megatron", - "meidcare", "medicare", - "meixcans", "mexicans", - "melboure", "melbourne", - "meltodwn", "meltdown", - "memoriez", "memorize", - "mencaing", "menacing", - "menstrul", "menstrual", - "mentiong", "mentioning", - "meoldies", "melodies", - "merchans", "merchants", - "mercurcy", "mercury", - "mercurey", "mercury", - "merficul", "merciful", - "merhcant", "merchant", - "mericful", "merciful", - "messgaed", "messaged", - "messiach", "messiah", - "metagaem", "metagame", - "metahpor", "metaphor", - "metamage", "metagame", - "methapor", "metaphor", - "metldown", "meltdown", - "metricas", "metrics", - "metrices", "metrics", - "metropos", "metropolis", - "mexcians", "mexicans", - "mexicain", "mexican", - "mhytical", "mythical", - "michagan", "michigan", - "michgian", "michigan", - "microtax", "microatx", - "microwae", "microwaves", - "midfeild", "midfield", - "midfiled", "midfield", - "midifeld", "midfield", - "migrains", "migraines", - "migriane", "migraine", - "milennia", "millennia", - "miligram", "milligram", - "miliitas", "militias", - "miliraty", "military", - "militais", "militias", - "millenia", "millennia", - "millenna", "millennia", - "miltiant", "militant", - "minature", "miniature", - "mindcrak", "mindcrack", - "minerial", "mineral", - "mingiame", "minigame", - "minimage", "minigame", - "minimals", "minimalist", - "minimalt", "minimalist", - "minimini", "minimizing", - "minimium", "minimum", - "miniscue", "miniscule", - "minsiter", "minister", - "minsitry", "ministry", - "miraculu", "miraculous", - "miralces", "miracles", - "mircales", "miracles", - "mircoatx", "microatx", - "mirgaine", "migraine", - "mirorred", "mirrored", - "misnadry", "misandry", - "misogynt", "misogynist", - "missigno", "mission", - "missiony", "missionary", - "misslies", "missiles", - "missorui", "missouri", - "misspeld", "misspelled", - "mistakey", "mistakenly", - "mistread", "mistreated", - "mobiltiy", "mobility", - "moderats", "moderates", - "modulair", "modular", - "moleculs", "molecules", - "momentos", "moments", - "momentus", "moments", - "monagomy", "monogamy", - "mongoles", "mongols", - "mongolos", "mongols", - "monitord", "monitored", - "monogmay", "monogamy", - "monolite", "monolithic", - "monologe", "monologue", - "monolopy", "monopoly", - "monoploy", "monopoly", - "monopols", "monopolies", - "monrachy", "monarchy", - "monstros", "monstrous", - "montaban", "montana", - "montains", "mountains", - "montanha", "montana", - "montania", "montana", - "montanna", "montana", - "montanta", "montana", - "montanya", "montana", - "montaran", "montana", - "monteize", "monetize", - "monteral", "montreal", - "montiors", "monitors", - "montnana", "montana", - "montypic", "monotypic", - "monumnet", "monument", - "moonligt", "moonlight", - "moprhine", "morphine", - "morbildy", "morbidly", - "mordibly", "morbidly", - "morevoer", "moreover", - "morhpine", "morphine", - "moribdly", "morbidly", - "mormones", "mormons", - "mormonts", "mormons", - "moroever", "moreover", - "morotola", "motorola", - "morphein", "morphine", - "morriosn", "morrison", - "morrocco", "morocco", - "morrsion", "morrison", - "mortards", "mortars", - "mortarts", "mortars", - "moruning", "mourning", - "mosnters", "monsters", - "mosqueto", "mosquitoes", - "mosquite", "mosquitoes", - "mosqutio", "mosquito", - "motoroal", "motorola", - "mounment", "monument", - "mounring", "mourning", - "mountian", "mountain", - "moustace", "moustache", - "movesped", "movespeed", - "mozillia", "mozilla", - "mozillla", "mozilla", - "msytical", "mystical", - "mucnhies", "munchies", - "mudering", "murdering", - "muffings", "muffins", - "muffinus", "muffins", - "mulitple", "multiple", - "mulitply", "multiply", - "multiplr", "multiplier", - "multipls", "multiples", - "mundance", "mundane", - "mundande", "mundane", - "muniches", "munchies", - "murderes", "murders", - "murderus", "murders", - "muscluar", "muscular", - "muscualr", "muscular", - "musicaly", "musically", - "musuclar", "muscular", - "mutliple", "multiple", - "mutliply", "multiply", - "myhtical", "mythical", - "mysitcal", "mystical", - "mysogyny", "misogyny", - "mysteris", "mysteries", - "mythraic", "mithraic", - "nagivate", "navigate", - "naopleon", "napoleon", - "napcakes", "pancakes", - "naploeon", "napoleon", - "napoelon", "napoleon", - "napolean", "napoleon", - "napoloen", "napoleon", - "narcissm", "narcissism", - "narcisst", "narcissist", - "narcotis", "narcotics", - "narwharl", "narwhal", - "naseuous", "nauseous", - "nashvile", "nashville", - "nasueous", "nauseous", - "natievly", "natively", - "nationas", "nationals", - "nationsl", "nationals", - "nativley", "natively", - "natuilus", "nautilus", - "naturaly", "naturally", - "naturels", "natures", - "naturely", "naturally", - "naturens", "natures", - "naturual", "natural", - "nauesous", "nauseous", - "naughtly", "naughty", - "nauitlus", "nautilus", - "nauseuos", "nauseous", - "nautiuls", "nautilus", - "nautlius", "nautilus", - "nautulis", "nautilus", - "naviagte", "navigate", - "navigato", "navigation", - "nazereth", "nazareth", - "necesary", "necessary", - "neckbead", "neckbeard", - "needlees", "needles", - "nefarios", "nefarious", - "negativy", "negativity", - "neglectn", "neglecting", - "neglible", "negligible", - "neigbour", "neighbour", - "neolitic", "neolithic", - "netboook", "netbook", - "neuronas", "neurons", - "neutraal", "neutral", - "neutralt", "neutrality", - "neutraly", "neutrality", - "newcaste", "newcastle", - "nickanme", "nickname", - "nickmane", "nickname", - "nieghbor", "neighbor", - "nightime", "nighttime", - "nightley", "nightly", - "nightlie", "nightlife", - "nihilsim", "nihilism", - "nilihism", "nihilism", - "nirtogen", "nitrogen", - "nirvanna", "nirvana", - "nitorgen", "nitrogen", - "niusance", "nuisance", - "noctrune", "nocturne", - "noctunre", "nocturne", - "nocturen", "nocturne", - "nominato", "nomination", - "nonsence", "nonsense", - "nonsesne", "nonsense", - "noramlly", "normally", - "norhtern", "northern", - "normalis", "normals", - "normalls", "normals", - "normalos", "normals", - "northeat", "northeast", - "northren", "northern", - "northwet", "northwest", - "norwegin", "norwegian", - "nostalga", "nostalgia", - "nostirls", "nostrils", - "notabley", "notably", - "notablly", "notably", - "noteable", "notable", - "noteably", "notably", - "noticabe", "noticeable", - "notorios", "notorious", - "novmeber", "november", - "nromandy", "normandy", - "nuatilus", "nautilus", - "nuculear", "nuclear", - "nuetered", "neutered", - "nuisanse", "nuisance", - "nullifiy", "nullify", - "nurtient", "nutrient", - "nusaince", "nuisance", - "nusiance", "nuisance", - "nutirent", "nutrient", - "nutriens", "nutrients", - "nuturing", "nurturing", - "obdisian", "obsidian", - "obediant", "obedient", - "obession", "obsession", - "obilvion", "oblivion", - "obisdian", "obsidian", - "obsessie", "obsessive", - "obsessin", "obsession", - "obsidain", "obsidian", - "obstacal", "obstacle", - "obvilion", "oblivion", - "ocasions", "occasions", - "ocassion", "occasion", - "occaison", "occasion", - "occupato", "occupation", - "occuring", "occurring", - "octobear", "october", - "octopuns", "octopus", - "ofcoruse", "ofcourse", - "ofcoures", "ofcourse", - "ofcousre", "ofcourse", - "ofcrouse", "ofcourse", - "officals", "officials", - "officaly", "officially", - "offsited", "offside", - "ofocurse", "ofcourse", - "oligarcy", "oligarchy", - "olmypics", "olympics", - "olymipcs", "olympics", - "olypmics", "olympics", - "ommision", "omission", - "ommiting", "omitting", - "ommitted", "omitted", - "ongewild", "gonewild", - "onslaugt", "onslaught", - "operatie", "operative", - "opinoins", "opinions", - "oppinion", "opinion", - "opponant", "opponent", - "opposits", "opposites", - "oppossed", "opposed", - "oppresso", "oppression", - "optimaal", "optimal", - "optomism", "optimism", - "oragnise", "organise", - "orangerd", "orangered", - "orangers", "oranges", - "orangism", "organism", - "orchesta", "orchestra", - "ordianry", "ordinary", - "oreintal", "oriental", - "orgainse", "organise", - "orgainze", "organize", - "organims", "organism", - "organsie", "organise", - "organsim", "organism", - "organzie", "organize", - "orgasmes", "orgasms", - "orgasmos", "orgasms", - "orgasmus", "orgasms", - "orginize", "organise", - "orhtodox", "orthodox", - "oridnary", "ordinary", - "originas", "origins", - "origines", "origins", - "originsl", "originals", - "orphanes", "orphans", - "osbidian", "obsidian", - "othrodox", "orthodox", - "ourselvs", "ourselves", - "oustider", "outsider", - "outfeild", "outfield", - "outfidel", "outfield", - "outfiled", "outfield", - "outisder", "outsider", - "outplayd", "outplayed", - "outputed", "outputted", - "outsoure", "outsourced", - "overboad", "overboard", - "overclok", "overclock", - "overdrev", "overdrive", - "overhual", "overhaul", - "overlaod", "overload", - "overpiad", "overpaid", - "overules", "overuse", - "overwath", "overwatch", - "overwhem", "overwhelm", - "oximoron", "oxymoron", - "oylmpics", "olympics", - "pacakged", "packaged", - "packadge", "packaged", - "paficist", "pacifist", - "painfuly", "painfully", - "paitence", "patience", - "paitents", "patients", - "palidans", "paladins", - "palstics", "plastics", - "paltform", "platform", - "paltinum", "platinum", - "palyable", "playable", - "palyoffs", "playoffs", - "pancaeks", "pancakes", - "panckaes", "pancakes", - "pandoria", "pandora", - "pandorra", "pandora", - "panedmic", "pandemic", - "panethon", "pantheon", - "pankaces", "pancakes", - "panmedic", "pandemic", - "pantehon", "pantheon", - "panthoen", "pantheon", - "paradies", "paradise", - "paradyse", "parades", - "paragrah", "paragraph", - "paraiste", "parasite", - "paralell", "parallel", - "paralely", "parallelly", - "paralles", "parallels", - "parameds", "paramedics", - "paramter", "parameter", - "paranioa", "paranoia", - "paraniod", "paranoid", - "paraside", "paradise", - "parasits", "parasites", - "parastie", "parasite", - "parctise", "practise", - "paremsan", "parmesan", - "paristan", "partisan", - "parmasen", "parmesan", - "parmenas", "parmesan", - "parmsean", "parmesan", - "parnters", "partners", - "parralel", "parallel", - "parterns", "partners", - "partialy", "partially", - "partians", "partisan", - "partical", "particular", - "particel", "particle", - "partiets", "parties", - "partiots", "patriots", - "partnerd", "partnered", - "partsian", "partisan", - "passabel", "passable", - "passione", "passionate", - "passisve", "passives", - "passpost", "passports", - "passvies", "passives", - "passwors", "passwords", - "pasttime", "pastime", - "pastural", "pastoral", - "pateince", "patience", - "pateints", "patients", - "patethic", "pathetic", - "patheitc", "pathetic", - "patienty", "patiently", - "patirots", "patriots", - "patriarh", "patriarchy", - "patroits", "patriots", - "patrolls", "patrols", - "patronas", "patrons", - "patrones", "patrons", - "patronis", "patrons", - "patronos", "patrons", - "pattened", "patented", - "patterno", "patterson", - "pattersn", "patterson", - "pblisher", "publisher", - "peageant", "pageant", - "pebbleos", "pebbles", - "pebblers", "pebbles", - "pebblets", "pebbles", - "peciluar", "peculiar", - "pecuilar", "peculiar", - "peculair", "peculiar", - "peculure", "peculiar", - "peformed", "performed", - "peircing", "piercing", - "penaltis", "penalties", - "penatgon", "pentagon", - "penciles", "pencils", - "pendatic", "pedantic", - "pengiuns", "penguins", - "penisula", "peninsula", - "pensioen", "pension", - "pepperin", "pepperoni", - "perceded", "preceded", - "percente", "percentile", - "percieve", "perceive", - "percious", "precious", - "perclude", "preclude", - "perfecty", "perfectly", - "perfroms", "performs", - "perheaps", "perhaps", - "pericing", "piercing", - "peridoic", "periodic", - "perimetr", "perimeter", - "periodes", "periods", - "periodos", "periods", - "permanet", "permanent", - "permiere", "premiere", - "permises", "premises", - "permitas", "permits", - "permites", "permits", - "permitis", "permits", - "permitts", "permits", - "permiums", "premiums", - "peroidic", "periodic", - "perosnas", "personas", - "perpetue", "perpetuate", - "persaude", "persuade", - "perserve", "preserve", - "persisit", "persist", - "personel", "personnel", - "persones", "persons", - "personis", "persons", - "personsa", "personas", - "perstige", "prestige", - "persuaso", "persuasion", - "persuded", "persuaded", - "persuing", "pursuing", - "persuits", "pursuits", - "persumed", "presumed", - "pertaing", "pertaining", - "pertians", "pertains", - "pertinet", "pertinent", - "pervents", "prevents", - "perverst", "pervert", - "perviews", "previews", - "pervious", "previous", - "perxoide", "peroxide", - "pessiary", "pessary", - "petetion", "petition", - "petrolem", "petroleum", - "phantoom", "phantom", - "pharamcy", "pharmacy", - "pharmacs", "pharmacist", - "pharmsci", "pharmacist", - "phenomon", "phenomenon", - "phramacy", "pharmacy", - "phsyical", "physical", - "phsyique", "physique", - "phyiscal", "physical", - "phyisque", "physique", - "physcial", "physical", - "physicis", "physicians", - "physicks", "physics", - "physicts", "physicist", - "physqiue", "physique", - "picthers", "pitchers", - "pillards", "pillars", - "pillaris", "pillars", - "pinancle", "pinnacle", - "pinapple", "pineapple", - "pinnalce", "pinnacle", - "pinnaple", "pineapple", - "pinncale", "pinnacle", - "pinpiont", "pinpoint", - "pinteret", "pinterest", - "piolting", "piloting", - "pioneeer", "pioneer", - "pithcers", "pitchers", - "placebro", "placebo", - "placemet", "placements", - "planetas", "planets", - "planetos", "planets", - "plantiff", "plaintiff", - "plantium", "platinum", - "plasitcs", "plastics", - "platfrom", "platform", - "platimun", "platinum", - "platnium", "platinum", - "platnuim", "platinum", - "plausibe", "plausible", - "playbody", "playboy", - "playstye", "playstyle", - "pleasent", "pleasant", - "plehtora", "plethora", - "pleothra", "plethora", - "plethroa", "plethora", - "ploygamy", "polygamy", - "pnatheon", "pantheon", - "poeoples", "peoples", - "poingant", "poignant", - "pointeur", "pointer", - "pointure", "pointer", - "poisones", "poisons", - "poisonis", "poisons", - "poisonos", "poisons", - "poisonus", "poisons", - "polgyamy", "polygamy", - "polietly", "politely", - "politing", "piloting", - "politley", "politely", - "poltical", "political", - "poluting", "polluting", - "polution", "pollution", - "polygoon", "polygon", - "polymore", "polymer", - "pomotion", "promotion", - "popoulus", "populous", - "populair", "popular", - "populare", "popular", - "populary", "popularity", - "porcelan", "porcelain", - "porposes", "proposes", - "portabel", "portable", - "portalis", "portals", - "portalus", "portals", - "portayed", "portrayed", - "portgual", "portugal", - "portrais", "portraits", - "portrary", "portray", - "portrayl", "portrayal", - "portriat", "portrait", - "posessed", "possessed", - "posesses", "possesses", - "posioned", "poisoned", - "positivs", "positives", - "positivy", "positivity", - "possable", "possible", - "possably", "possibly", - "possbily", "possibly", - "posseses", "possesses", - "possesse", "possessive", - "possesss", "possesses", - "potrayed", "portrayed", - "poverful", "powerful", - "powerded", "powdered", - "powerpot", "powerpoint", - "pracitse", "practise", - "practial", "practical", - "practies", "practise", - "pratcise", "practise", - "praticle", "particle", - "prceeded", "preceded", - "preadtor", "predator", - "preample", "preamble", - "preceeds", "precedes", - "precisie", "precise", - "precisly", "precisely", - "precisou", "precious", - "preculde", "preclude", - "predicat", "predict", - "predicte", "predictive", - "preferas", "prefers", - "prefered", "preferred", - "preferes", "prefers", - "preferis", "prefers", - "preferrs", "prefers", - "preimere", "premiere", - "preimums", "premiums", - "preiodic", "periodic", - "preivews", "previews", - "prejudis", "prejudices", - "prelayed", "replayed", - "premeire", "premiere", - "premesis", "premises", - "premiare", "premier", - "premines", "premise", - "premuims", "premiums", - "preorded", "preordered", - "preordes", "preorders", - "preoxide", "peroxide", - "prepaird", "prepaid", - "preqeuls", "prequels", - "prequles", "prequels", - "prescrie", "prescribed", - "presense", "presence", - "presenst", "presets", - "presidet", "presidents", - "presists", "persists", - "presitge", "prestige", - "presonas", "personas", - "presuade", "persuade", - "pretador", "predator", - "pretains", "pertains", - "preveiws", "previews", - "preverse", "perverse", - "previwes", "previews", - "pricipal", "principal", - "priciple", "principle", - "priemere", "premiere", - "priestes", "priests", - "primaris", "primaries", - "primarly", "primarily", - "princila", "principals", - "principl", "principals", - "prisitne", "pristine", - "probelms", "problems", - "probleem", "problem", - "procalim", "proclaim", - "proccess", "process", - "proceded", "proceeded", - "proceder", "procedure", - "procedes", "proceeds", - "procedue", "procedure", - "proceeed", "proceed", - "procesed", "proceeds", - "processs", "processes", - "proclami", "proclaim", - "procliam", "proclaim", - "procotol", "protocol", - "prodcuts", "products", - "producto", "production", - "profesor", "professor", - "proficit", "proficient", - "profilic", "prolific", - "progroms", "pogroms", - "prohibis", "prohibits", - "prohpecy", "prophecy", - "prohpets", "prophets", - "projecte", "projectile", - "projecto", "projection", - "prolouge", "prologue", - "promplty", "promptly", - "promptes", "prompts", - "promptus", "prompts", - "promtply", "promptly", - "pronoune", "pronounced", - "propechy", "prophecy", - "propehcy", "prophecy", - "propehts", "prophets", - "prophacy", "prophecy", - "propmted", "prompted", - "propmtly", "promptly", - "proponet", "proponents", - "proposse", "proposes", - "proposte", "propose", - "proprety", "property", - "propsect", "prospect", - "prosepct", "prospect", - "prostite", "prostitute", - "protable", "portable", - "protecte", "protective", - "protiens", "proteins", - "protines", "proteins", - "protocal", "protocol", - "prototye", "prototype", - "protrait", "portrait", - "protrays", "portrays", - "protugal", "portugal", - "proverai", "proverbial", - "providee", "providence", - "proximty", "proximity", - "pruchase", "purchase", - "pryamids", "pyramids", - "ptichers", "pitchers", - "pubisher", "publisher", - "publiser", "publisher", - "puinsher", "punisher", - "pulisher", "publisher", - "pumkpins", "pumpkins", - "pumpinks", "pumpkins", - "pumpknis", "pumpkins", - "punshier", "punisher", - "punsiher", "punisher", - "punsihes", "punishes", - "purcahse", "purchase", - "pyramind", "pyramid", - "pyrimads", "pyramids", - "pyrmaids", "pyramids", - "qauntity", "quantity", - "qualifiy", "qualify", - "quanitfy", "quantify", - "quantaty", "quantity", - "quantite", "quantities", - "quantuum", "quantum", - "quarante", "quarantine", - "quartery", "quarterly", - "qucikest", "quickest", - "queation", "equation", - "quention", "quentin", - "quickets", "quickest", - "quicklyu", "quickly", - "rabbitos", "rabbits", - "rabbitts", "rabbits", - "racistas", "racists", - "racistes", "racists", - "radaince", "radiance", - "rahpsody", "rhapsody", - "raidance", "radiance", - "railraod", "railroad", - "randomes", "randoms", - "randomez", "randomized", - "randomns", "randoms", - "randomrs", "randoms", - "randomus", "randoms", - "raosting", "roasting", - "raphsody", "rhapsody", - "raptores", "raptors", - "raspbery", "raspberry", - "rationel", "rationale", - "realible", "reliable", - "realibly", "reliably", - "realiest", "earliest", - "realisim", "realism", - "realisme", "realise", - "realistc", "realistic", - "realiste", "realise", - "realoded", "reloaded", - "realsied", "realised", - "realtion", "relation", - "realtive", "relative", - "reamined", "remained", - "reapired", "repaired", - "reaplugs", "earplugs", - "reaserch", "research", - "reasonal", "reasonably", - "reatiler", "retailer", - "reaveled", "revealed", - "rebellis", "rebellious", - "reboudns", "rebounds", - "rebounce", "rebound", - "rebuildt", "rebuilt", - "rebuplic", "republic", - "receeded", "receded", - "recepits", "receipts", - "receptie", "receptive", - "receptos", "receptors", - "receving", "receiving", - "recident", "resident", - "reciding", "residing", - "recieved", "received", - "reciever", "receiver", - "recieves", "receives", - "recipees", "recipes", - "recipets", "recipes", - "recogise", "recognise", - "recogize", "recognize", - "recognie", "recognizes", - "recomend", "recommend", - "recommed", "recommend", - "reconnet", "reconnect", - "rectange", "rectangle", - "rectifiy", "rectify", - "recuring", "recurring", - "recurits", "recruits", - "redeisgn", "redesign", - "redemeed", "redeemed", - "redesgin", "redesign", - "redesing", "redesign", - "reedemed", "redeemed", - "refeeres", "referees", - "refelcts", "reflects", - "refelxes", "reflexes", - "referede", "referee", - "referene", "referee", - "referens", "references", - "referere", "referee", - "referign", "referring", - "refering", "referring", - "refernce", "references", - "reffered", "referred", - "refilles", "refills", - "refillls", "refills", - "reflecte", "reflective", - "reflecto", "reflection", - "reformes", "reforms", - "refreing", "referring", - "refrence", "reference", - "refreshd", "refreshed", - "refreshr", "refresher", - "refromed", "reformed", - "regardes", "regards", - "regenade", "renegade", - "regenere", "regenerate", - "regiones", "regions", - "regisrty", "registry", - "registed", "registered", - "regresas", "regress", - "regreses", "regress", - "regresos", "regress", - "regresse", "regressive", - "regresso", "regression", - "regrests", "regress", - "regretts", "regrets", - "regsitry", "registry", - "regualrs", "regulars", - "regualte", "regulate", - "reguarly", "regularly", - "regulary", "regularly", - "regulatr", "regulator", - "regulats", "regulators", - "rehersal", "rehearsal", - "rehtoric", "rhetoric", - "reiceved", "received", - "reigment", "regiment", - "reigonal", "regional", - "rekenton", "renekton", - "relaible", "reliable", - "relaibly", "reliably", - "relaised", "realised", - "relaoded", "reloaded", - "relasped", "relapsed", - "relatabe", "relatable", - "relateds", "relates", - "relativy", "relativity", - "relavent", "relevant", - "relected", "reelected", - "relegato", "relegation", - "releived", "relieved", - "releiver", "reliever", - "relevent", "relevant", - "relfects", "reflects", - "relfexes", "reflexes", - "reliased", "realised", - "religous", "religious", - "relpased", "relapsed", - "remainds", "remains", - "remainig", "remaining", - "remannts", "remnants", - "remarkes", "remarks", - "remembed", "remembered", - "remembee", "remembered", - "rememebr", "remember", - "remenant", "remnant", - "reminent", "remnant", - "remmeber", "remember", - "remotley", "remotely", - "renderes", "renders", - "reneagde", "renegade", - "renetkon", "renekton", - "renewabe", "renewables", - "renketon", "renekton", - "renmants", "remnants", - "renoylds", "reynolds", - "renteris", "renters", - "renyolds", "reynolds", - "reowrked", "reworked", - "repaires", "repairs", - "repalces", "replaces", - "reparied", "repaired", - "repblics", "republics", - "repbulic", "republic", - "repeatae", "repeatable", - "repeates", "repeats", - "repetion", "repetition", - "repharse", "rephrase", - "repitles", "reptiles", - "replased", "relapsed", - "replayes", "replays", - "replicae", "replicated", - "replubic", "republic", - "reportes", "reporters", - "reposity", "repository", - "repostas", "reposts", - "repostes", "reposts", - "repostig", "reposting", - "repostus", "reposts", - "represet", "represents", - "represso", "repression", - "reprhase", "rephrase", - "repsects", "respects", - "repsonds", "responds", - "repsonse", "response", - "repsoted", "reposted", - "repubics", "republics", - "republis", "republics", - "repulics", "republics", - "repulsie", "repulsive", - "requiers", "requires", - "requieum", "requiem", - "requilme", "requiem", - "requried", "required", - "requries", "requires", - "rescuecd", "rescued", - "researce", "researcher", - "resembes", "resembles", - "reserach", "research", - "resevoir", "reservoir", - "resgined", "resigned", - "residude", "residue", - "residule", "residue", - "resinged", "resigned", - "resistas", "resists", - "resisten", "resistance", - "resistes", "resists", - "resloved", "resolved", - "resloves", "resolves", - "resmeble", "resemble", - "resotred", "restored", - "resourse", "resources", - "resovled", "resolved", - "resovles", "resolves", - "respecte", "respective", - "respesct", "respects", - "responce", "response", - "responed", "respond", - "respones", "response", - "responsd", "responds", - "respoted", "reposted", - "restanti", "restarting", - "restrait", "restraint", - "restrics", "restricts", - "resuable", "reusable", - "retailes", "retailers", - "retalier", "retailer", - "rethoric", "rhetoric", - "retirase", "retires", - "retireds", "retires", - "retireus", "retires", - "retireve", "retrieve", - "retreive", "retrieve", - "retrived", "retrieved", - "retunred", "returned", - "reuasble", "reusable", - "reveales", "reveals", - "reveiwed", "reviewed", - "reveiwer", "reviewer", - "revelaed", "revealed", - "revelant", "relevant", - "revelead", "revealed", - "reverals", "reversal", - "reviewes", "reviewers", - "revlover", "revolver", - "revloves", "revolves", - "revovler", "revolver", - "revovles", "revolves", - "rewatchd", "rewatched", - "rewitten", "rewritten", - "rewritte", "rewrite", - "rewtched", "wretched", - "reynlods", "reynolds", - "reyonlds", "reynolds", - "rhaposdy", "rhapsody", - "rhaspody", "rhapsody", - "rheotric", "rhetoric", - "righteos", "righteous", - "rigntone", "ringtone", - "ringotne", "ringtone", - "ritalian", "ritalin", - "rivalrly", "rivalry", - "roachers", "roaches", - "robberts", "robbers", - "robberys", "robbers", - "robocoop", "robocop", - "robocorp", "robocop", - "robocoup", "robocop", - "roelplay", "roleplay", - "roganism", "organism", - "rolepaly", "roleplay", - "romaanin", "romanian", - "romainan", "romanian", - "romanain", "romanian", - "romanica", "romania", - "rosettta", "rosetta", - "rostaing", "roasting", - "routeros", "routers", - "rutgerus", "rutgers", - "ryenolds", "reynolds", - "sacrifie", "sacrifice", - "saddends", "saddens", - "saddenes", "saddens", - "sadisitc", "sadistic", - "salaires", "salaries", - "sandales", "sandals", - "sandalls", "sandals", - "sandstom", "sandstorm", - "sanotrum", "santorum", - "santourm", "santorum", - "santroum", "santorum", - "santurom", "santorum", - "sapcebar", "spacebar", - "sapphrie", "sapphire", - "sarcasam", "sarcasm", - "sarcasim", "sarcasm", - "sarcastc", "sarcastic", - "sargeant", "sergeant", - "sasauges", "sausages", - "sasuages", "sausages", - "satelite", "satellite", - "satellie", "satellites", - "saterday", "saturday", - "satifies", "satisfies", - "satisfiy", "satisfy", - "satrical", "satirical", - "satruday", "saturday", - "saturdsy", "saturdays", - "sawstika", "swastika", - "scandlas", "scandals", - "scannign", "scanning", - "scarmble", "scramble", - "scepture", "scepter", - "schedual", "schedule", - "schoalrs", "scholars", - "scholary", "scholarly", - "schoodle", "schooled", - "scientic", "scientific", - "scientis", "scientist", - "scoprion", "scorpion", - "scorates", "socrates", - "scoripon", "scorpion", - "scorpoin", "scorpion", - "scostman", "scotsman", - "scratchs", "scratches", - "scriptue", "scriptures", - "scriptus", "scripts", - "scritped", "scripted", - "scroates", "socrates", - "scropion", "scorpion", - "scrpited", "scripted", - "scruitny", "scrutiny", - "scrunity", "scrutiny", - "sctosman", "scotsman", - "sculpter", "sculpture", - "scurtiny", "scrutiny", - "seahakws", "seahawks", - "seahwaks", "seahawks", - "seantors", "senators", - "sebastin", "sebastian", - "seceeded", "succeeded", - "secertly", "secretly", - "secrelty", "secretly", - "secretas", "secrets", - "secretos", "secrets", - "secruity", "security", - "secuirty", "security", - "sedereal", "sidereal", - "seldomly", "seldom", - "selectie", "selective", - "selfiers", "selfies", - "semestre", "semester", - "semseter", "semester", - "senarios", "scenarios", - "senerity", "serenity", - "seniores", "seniors", - "senisble", "sensible", - "sensibel", "sensible", - "sensores", "sensors", - "senstive", "sensitive", - "sentaors", "senators", - "sentiers", "sentries", - "sentinet", "sentient", - "sentinte", "sentient", - "sentires", "sentries", - "sentreis", "sentries", - "separato", "separation", - "separete", "separate", - "sepearte", "separate", - "seperate", "separate", - "seplling", "spelling", - "sepreate", "separate", - "sepulcre", "sepulchre", - "serached", "searched", - "seraches", "searches", - "serentiy", "serenity", - "sergaent", "sergeant", - "settigns", "settings", - "settting", "setting", - "seventen", "seventeen", - "severeal", "several", - "severeid", "severed", - "severide", "severed", - "severley", "severely", - "sexaully", "sexually", - "seziures", "seizures", - "sezuires", "seizures", - "shadoloo", "shadaloo", - "shangahi", "shanghai", - "shanghia", "shanghai", - "sharplay", "sharply", - "sharpley", "sharply", - "shawshak", "shawshank", - "shcolars", "scholars", - "shcooled", "schooled", - "sheilded", "shielded", - "shelterd", "sheltered", - "shelvers", "shelves", - "shelveys", "shelves", - "sherlcok", "sherlock", - "shetlers", "shelters", - "shfiting", "shifting", - "shifitng", "shifting", - "shifteer", "shifter", - "shileded", "shielded", - "shineing", "shining", - "shitstom", "shitstorm", - "shittoon", "shitton", - "shittown", "shitton", - "shleters", "shelters", - "shnaghai", "shanghai", - "shortend", "shortened", - "shotuout", "shoutout", - "shoudlnt", "shouldnt", - "shouldes", "shoulders", - "shoulndt", "shouldnt", - "shrapenl", "shrapnel", - "shrelock", "sherlock", - "shrinked", "shrunk", - "shrpanel", "shrapnel", - "shtiless", "shitless", - "shuoldnt", "shouldnt", - "sideboad", "sideboard", - "sidleine", "sideline", - "siezable", "sizeable", - "siezures", "seizures", - "signatue", "signatures", - "signfies", "signifies", - "signifiy", "signify", - "signigns", "signings", - "signular", "singular", - "silbings", "siblings", - "silicoln", "silicon", - "silicoon", "silicon", - "silimiar", "similar", - "simialir", "similar", - "simiilar", "similar", - "similair", "similar", - "similari", "similar", - "similart", "similarity", - "similary", "similarly", - "similiar", "similar", - "simliiar", "similar", - "simluate", "simulate", - "simmilar", "similar", - "simpelst", "simplest", - "simplets", "simplest", - "simplicy", "simplicity", - "simplier", "simpler", - "simulato", "simulation", - "singlers", "singles", - "singluar", "singular", - "sinistre", "sinister", - "sinsiter", "sinister", - "sitckers", "stickers", - "sitrring", "stirring", - "sizebale", "sizeable", - "skateing", "skating", - "skecthes", "sketches", - "skelatel", "skeletal", - "skeletos", "skeletons", - "sketchey", "sketchy", - "sketpics", "skeptics", - "skillsto", "skillshots", - "skimrish", "skirmish", - "skpetics", "skeptics", - "skrimish", "skirmish", - "skteches", "sketches", - "skywalkr", "skywalker", - "slaptoon", "splatoon", - "slaverly", "slavery", - "slienced", "silenced", - "sliently", "silently", - "slighlty", "slightly", - "sligthly", "slightly", - "smartare", "smarter", - "snetries", "sentries", - "snippent", "snippet", - "snippert", "snippet", - "snowbals", "snowballs", - "snugglie", "snuggle", - "snydrome", "syndrome", - "snyopsis", "synopsis", - "soberity", "sobriety", - "sobreity", "sobriety", - "socailly", "socially", - "socalism", "socialism", - "socartes", "socrates", - "socialim", "socialism", - "socities", "societies", - "socttish", "scottish", - "soemthin", "somethin", - "soilders", "soldiers", - "solatary", "solitary", - "soldeirs", "soldiers", - "soliders", "soldiers", - "soluable", "soluble", - "solutide", "solitude", - "somalija", "somalia", - "somehtin", "somethin", - "someoens", "someones", - "somethis", "somethings", - "sometihn", "somethin", - "sometinh", "somethin", - "somoenes", "someones", - "somtimes", "sometimes", - "somwhere", "somewhere", - "soparnos", "sopranos", - "sophmore", "sophomore", - "sorcercy", "sorcery", - "sorcerey", "sorcery", - "sorceror", "sorcerer", - "sorcerry", "sorcery", - "sorpanos", "sopranos", - "southren", "southern", - "soverein", "sovereign", - "soverign", "sovereign", - "sovietes", "soviets", - "spagheti", "spaghetti", - "spainish", "spanish", - "spaltoon", "splatoon", - "spammade", "spammed", - "spammare", "spammer", - "spammear", "spammer", - "spammend", "spammed", - "spammeur", "spammer", - "spanisch", "spanish", - "sparklie", "sparkle", - "spawnign", "spawning", - "specemin", "specimen", - "speciaal", "special", - "specialt", "specialist", - "specialy", "specially", - "specialz", "specialize", - "specifed", "specified", - "specifiy", "specify", - "speciman", "specimen", - "specrtal", "spectral", - "speicals", "specials", - "spellign", "spelling", - "spendour", "splendour", - "sphereos", "spheres", - "spilnter", "splinter", - "spiltter", "splitter", - "spindrel", "spindle", - "spirites", "spirits", - "spiritis", "spirits", - "spiritus", "spirits", - "spirtied", "spirited", - "spleling", "spelling", - "splitner", "splinter", - "spoilerd", "spoiled", - "spoliers", "spoilers", - "sponsord", "sponsored", - "sporanos", "sopranos", - "spotifiy", "spotify", - "spotifty", "spotify", - "sppeches", "speeches", - "sprayade", "sprayed", - "spreaded", "spread", - "springst", "sprints", - "sprinkel", "sprinkle", - "sprintas", "sprints", - "spritual", "spiritual", - "sproutes", "sprouts", - "spwaning", "spawning", - "sqaudron", "squadron", - "sqaurely", "squarely", - "sqiurtle", "squirtle", - "squardon", "squadron", - "squareds", "squares", - "squarley", "squarely", - "squeakey", "squeaky", - "squeakly", "squeaky", - "squirlte", "squirtle", - "squirrle", "squirrel", - "squirtel", "squirtle", - "squishey", "squishy", - "squishly", "squishy", - "squritle", "squirtle", - "squrriel", "squirrel", - "squrtile", "squirtle", - "sriarcha", "sriracha", - "srriacha", "sriracha", - "sryacuse", "syracuse", - "staduims", "stadiums", - "staidums", "stadiums", - "staklers", "stalkers", - "stalekrs", "stalkers", - "stalkear", "stalker", - "staminia", "stamina", - "stampade", "stamped", - "stampeed", "stamped", - "stancels", "stances", - "stancers", "stances", - "standars", "standards", - "standbay", "standby", - "standbuy", "standby", - "stangant", "stagnant", - "staright", "straight", - "starined", "strained", - "starlted", "startled", - "startegy", "strategy", - "starteld", "startled", - "startsup", "startups", - "stateman", "statesman", - "staticts", "statist", - "stationd", "stationed", - "stationy", "stationary", - "statiskt", "statist", - "statistc", "statistic", - "statment", "statement", - "stattues", "statutes", - "statuets", "statutes", - "statuser", "stature", - "staurday", "saturday", - "steadliy", "steadily", - "stealhty", "stealthy", - "steathly", "stealthy", - "stelathy", "stealthy", - "sterilze", "sterile", - "steriods", "steroids", - "stichted", "stitched", - "sticthed", "stitched", - "sticthes", "stitches", - "stimulai", "stimuli", - "stimulas", "stimulants", - "stimulat", "stimulants", - "stimulli", "stimuli", - "stingent", "stringent", - "stirkers", "strikers", - "stlakers", "stalkers", - "stomache", "stomach", - "stormade", "stormed", - "stormend", "stormed", - "stradegy", "strategy", - "stragety", "strategy", - "straignt", "straighten", - "straigth", "straight", - "straings", "strains", - "strangel", "strangle", - "stranget", "strangest", - "stratgey", "strategy", - "stratled", "startled", - "streames", "streams", - "streamos", "streams", - "streamus", "streams", - "streamys", "streams", - "stregnth", "strength", - "stremear", "streamer", - "strenght", "strength", - "strengts", "strengths", - "strenous", "strenuous", - "strentgh", "strength", - "stretchs", "stretches", - "striaght", "straight", - "striclty", "strictly", - "striekrs", "strikers", - "strikely", "strikingly", - "stringet", "stringent", - "stubbron", "stubborn", - "stubmled", "stumbled", - "stucture", "structure", - "studioes", "studios", - "stuipder", "stupider", - "stumbeld", "stumbled", - "stupdily", "stupidly", - "stupidiy", "stupidity", - "stylisch", "stylish", - "styrofom", "styrofoam", - "suasages", "sausages", - "subltety", "subtlety", - "submarie", "submarines", - "subruban", "suburban", - "subscrie", "subscriber", - "subsidie", "subsidized", - "subsidiy", "subsidy", - "substace", "substance", - "substans", "substances", - "substite", "substitute", - "subtelty", "subtlety", - "subtetly", "subtlety", - "subtilte", "subtitle", - "subtitel", "subtitle", - "subtitls", "subtitles", - "subtltey", "subtlety", - "succeded", "succeeded", - "succedes", "succeeds", - "succeeed", "succeed", - "succesed", "succeeds", - "successs", "successes", - "succsess", "success", - "suceeded", "succeeded", - "sucesful", "successful", - "sucesion", "succession", - "sucesses", "successes", - "sucessor", "successor", - "sucessot", "successor", - "sucidial", "suicidal", - "suddnely", "suddenly", - "sufficit", "sufficient", - "suggesst", "suggests", - "suggeste", "suggestive", - "summenor", "summoner", - "summones", "summoners", - "sunfiber", "sunfire", - "sunscren", "sunscreen", - "superham", "superhuman", - "superheo", "superhero", - "superios", "superiors", - "supirsed", "surprised", - "suposing", "supposing", - "supporre", "supporters", - "suppoted", "supported", - "suprised", "surprised", - "suprized", "surprised", - "suprsied", "surprised", - "supsects", "suspects", - "supsense", "suspense", - "surbuban", "suburban", - "surounds", "surrounds", - "surpases", "surpass", - "surpress", "suppress", - "surprize", "surprise", - "surrouns", "surrounds", - "surveill", "surveil", - "surveyer", "surveyor", - "surviver", "survivor", - "suspened", "suspend", - "suspenso", "suspension", - "swaering", "swearing", - "swansoon", "swanson", - "swasitka", "swastika", - "swaskita", "swastika", - "swatiska", "swastika", - "swatsika", "swastika", - "swedisch", "swedish", - "swiftley", "swiftly", - "swithced", "switched", - "swithces", "switches", - "swtiched", "switched", - "swtiches", "switches", - "syarcuse", "syracuse", - "sydnrome", "syndrome", - "sylablle", "syllable", - "syllabel", "syllable", - "symapthy", "sympathy", - "symboles", "symbols", - "symhpony", "symphony", - "symmerty", "symmetry", - "symmtery", "symmetry", - "symoblic", "symbolic", - "symphaty", "sympathy", - "symptoom", "symptom", - "symtpoms", "symptoms", - "synomyns", "synonyms", - "synonmys", "synonyms", - "synonomy", "synonym", - "synoynms", "synonyms", - "synphony", "symphony", - "synposis", "synopsis", - "sypmathy", "sympathy", - "sypmtoms", "symptoms", - "sypnosis", "synopsis", - "syraucse", "syracuse", - "syrcause", "syracuse", - "syringae", "syringe", - "syringue", "syringe", - "sysamdin", "sysadmin", - "sysdamin", "sysadmin", - "tacticas", "tactics", - "tacticts", "tactics", - "tacticus", "tactics", - "tagliate", "tailgate", - "tahnkyou", "thankyou", - "tailsman", "talisman", - "taiwanee", "taiwanese", - "taligate", "tailgate", - "taliored", "tailored", - "tallents", "tallest", - "talsiman", "talisman", - "tanturms", "tantrums", - "tapitude", "aptitude", - "tasliman", "talisman", - "tattooes", "tattoos", - "tattooos", "tattoos", - "taxanomy", "taxonomy", - "teamfigt", "teamfight", - "teamspek", "teamspeak", - "teancity", "tenacity", - "teapsoon", "teaspoon", - "techniqe", "technique", - "teenages", "teenagers", - "telegrah", "telegraph", - "telphony", "telephony", - "tempalrs", "templars", - "tempalte", "template", - "templats", "templates", - "templeos", "temples", - "templers", "temples", - "temporay", "temporary", - "temprary", "temporary", - "tenacles", "tentacles", - "tenactiy", "tenacity", - "tencaity", "tenacity", - "tendancy", "tendency", - "tendence", "tendencies", - "tentacel", "tentacle", - "tentacls", "tentacles", - "tentalce", "tentacle", - "tequilia", "tequila", - "terriory", "territory", - "territoy", "territory", - "terroist", "terrorist", - "tesitcle", "testicle", - "testicel", "testicle", - "testifiy", "testify", - "teusdays", "tuesdays", - "texutres", "textures", - "thaliand", "thailand", - "theather", "theater", - "theathre", "theater", - "theature", "theater", - "theisitc", "theistic", - "themslef", "themself", - "theorits", "theorist", - "theraphy", "therapy", - "thereian", "therein", - "theroies", "theories", - "theroist", "theorist", - "thesitic", "theistic", - "thialand", "thailand", - "thiestic", "theistic", - "thikning", "thinking", - "thirites", "thirties", - "thirstay", "thirsty", - "thnakyou", "thankyou", - "thoeries", "theories", - "thoerist", "theorist", - "thomspon", "thompson", - "thopmson", "thompson", - "thougths", "thoughts", - "thourogh", "thorough", - "threates", "threatens", - "threefor", "therefor", - "thriteen", "thirteen", - "thrities", "thirties", - "throaths", "throats", - "throners", "thrones", - "throough", "thorough", - "throught", "thought", - "thrusday", "thursday", - "thumbnal", "thumbnails", - "thurdsay", "thursday", - "thursdsy", "thursdays", - "tightare", "tighter", - "timestap", "timestamp", - "tirangle", "triangle", - "tirbunal", "tribunal", - "titainum", "titanium", - "titanuim", "titanium", - "tocuhpad", "touchpad", - "togehter", "together", - "togheter", "together", - "toiletts", "toilets", - "tolerabe", "tolerable", - "tommorow", "tomorrow", - "tonguers", "tongues", - "toriodal", "toroidal", - "toritlla", "tortilla", - "tornadoe", "tornado", - "torotise", "tortoise", - "torpedeo", "torpedo", - "torphies", "trophies", - "tortiose", "tortoise", - "toruisty", "touristy", - "toruneys", "tourneys", - "touchapd", "touchpad", - "tounreys", "tourneys", - "tourisim", "tourism", - "touritsy", "touristy", - "tournyes", "tourneys", - "toursits", "tourists", - "toursity", "touristy", - "toxiticy", "toxicity", - "trabajao", "trabajo", - "trabajdo", "trabajo", - "trackres", "trackers", - "trageted", "targeted", - "traingle", "triangle", - "traitour", "traitor", - "trakcers", "trackers", - "traliers", "trailers", - "tranform", "transform", - "transeat", "translates", - "transfom", "transform", - "transfos", "transforms", - "transiet", "transient", - "transito", "transition", - "transpot", "transport", - "trasnfer", "transfer", - "tratiors", "traitors", - "traveles", "travels", - "traveres", "traverse", - "treasurs", "treasures", - "treatmet", "treatments", - "treatsie", "treaties", - "treausre", "treasure", - "tredning", "trending", - "tremelos", "tremolos", - "tresuary", "treasury", - "trialers", "trailers", - "trianers", "trainers", - "triangel", "triangle", - "triangls", "triangles", - "trianing", "training", - "trianlge", "triangle", - "triators", "traitors", - "tribuanl", "tribunal", - "trickyer", "trickery", - "triggern", "triggering", - "trilogoy", "trilogy", - "trinagle", "triangle", - "trinekts", "trinkets", - "tringale", "triangle", - "trinitiy", "trinity", - "triology", "trilogy", - "triumpth", "triumph", - "trohpies", "trophies", - "trollade", "trolled", - "tropcial", "tropical", - "trotilla", "tortilla", - "trpoical", "tropical", - "trubinal", "tribunal", - "trubines", "turbines", - "tsunamai", "tsunami", - "tuesdsay", "tuesdays", - "tunnells", "tunnels", - "turkisch", "turkish", - "turntabe", "turntable", - "turretts", "turrets", - "tusedays", "tuesdays", - "tutorual", "tutorial", - "twilgiht", "twilight", - "tylenool", "tylenol", - "typicaly", "typically", - "tyranies", "tyrannies", - "tyrannia", "tyrannical", - "ublisher", "publisher", - "udnercut", "undercut", - "udnerdog", "underdog", - "ugpraded", "upgraded", - "ugprades", "upgrades", - "ukrainie", "ukraine", - "ukrainin", "ukrainian", - "ukranian", "ukrainian", - "ulitmate", "ultimate", - "ultamite", "ultimate", - "ultiamte", "ultimate", - "ultimely", "ultimately", - "ultrason", "ultrasound", - "umberlla", "umbrella", - "unabnned", "unbanned", - "unbanend", "unbanned", - "uncanney", "uncanny", - "uncannny", "uncanny", - "underbog", "undergo", - "underglo", "undergo", - "undersog", "undergo", - "undertoe", "undertones", - "underwar", "underwater", - "unfailry", "unfairly", - "unfarily", "unfairly", - "ungodley", "ungodly", - "unhapppy", "unhappy", - "unhealty", "unhealthy", - "unicrons", "unicorns", - "unifroms", "uniforms", - "uniquley", "uniquely", - "univeral", "universal", - "unlikley", "unlikely", - "unlockes", "unlocks", - "unluckly", "unlucky", - "unpoened", "unopened", - "unqiuely", "uniquely", - "unrakned", "unranked", - "unrnaked", "unranked", - "unrpoven", "unproven", - "unsuable", "unusable", - "untraind", "untrained", - "unusualy", "unusually", - "unvierse", "universe", - "unworhty", "unworthy", - "upgarded", "upgraded", - "upgardes", "upgrades", - "uploades", "uploads", - "upstaris", "upstairs", - "upstiars", "upstairs", - "urethrea", "urethra", - "uruguary", "uruguay", - "ususally", "usually", - "utilitiy", "utility", - "utlimate", "ultimate", - "vaccinae", "vaccinated", - "vaccinet", "vaccinated", - "vacinity", "vicinity", - "vaguelly", "vaguely", - "vaiation", "aviation", - "vaieties", "varieties", - "vailidty", "validity", - "vairable", "variable", - "vaklyrie", "valkyrie", - "valenica", "valencia", - "valentie", "valentines", - "valentis", "valentines", - "validade", "validated", - "valkirye", "valkyrie", - "valkiyre", "valkyrie", - "valkriye", "valkyrie", - "valkryie", "valkyrie", - "valkyire", "valkyrie", - "valnecia", "valencia", - "valubale", "valuable", - "valykrie", "valkyrie", - "vamipres", "vampires", - "vampiers", "vampires", - "vampries", "vampires", - "vangurad", "vanguard", - "vanillia", "vanilla", - "vanillla", "vanilla", - "vanugard", "vanguard", - "varaible", "variable", - "varaints", "variants", - "variabel", "variable", - "varibale", "variable", - "varities", "varieties", - "vassales", "vassals", - "vassalls", "vassals", - "vassalos", "vassals", - "vaticaan", "vatican", - "vaticina", "vatican", - "vaulable", "valuable", - "vaylkrie", "valkyrie", - "vechiles", "vehicles", - "vectores", "vectors", - "vegansim", "veganism", - "vegtable", "vegetable", - "vehciles", "vehicles", - "vehicels", "vehicles", - "vehicule", "vehicle", - "veichles", "vehicles", - "venelope", "envelope", - "venemous", "venomous", - "vengance", "vengeance", - "vengence", "vengeance", - "verablly", "verbally", - "verbaitm", "verbatim", - "verisons", "versions", - "versatel", "versatile", - "vertabim", "verbatim", - "vertigro", "vertigo", - "vesseles", "vessels", - "vessells", "vessels", - "viabiliy", "viability", - "viatmins", "vitamins", - "vibratie", "vibrate", - "vibratin", "vibration", - "vicintiy", "vicinity", - "vicseral", "visceral", - "victimas", "victims", - "victimes", "victims", - "victorin", "victorian", - "victoris", "victories", - "vieweres", "viewers", - "viewpoit", "viewpoints", - "vigilane", "vigilante", - "vigliant", "vigilant", - "vikingos", "vikings", - "viligant", "vigilant", - "villegas", "villages", - "vindicte", "vindictive", - "vinicity", "vicinity", - "violatin", "violation", - "violenty", "violently", - "violetas", "violates", - "virament", "vraiment", - "virbator", "vibrator", - "virginas", "virgins", - "virgines", "virgins", - "virgings", "virgins", - "virginis", "virgins", - "virginus", "virgins", - "virtualy", "virtually", - "virtuels", "virtues", - "virtuose", "virtues", - "viscreal", "visceral", - "visercal", "visceral", - "visibily", "visibility", - "visibley", "visibly", - "visiblly", "visibly", - "vitailty", "vitality", - "vitimans", "vitamins", - "vitmains", "vitamins", - "vitories", "victories", - "voicemal", "voicemail", - "voilates", "violates", - "volatily", "volatility", - "volcando", "volcano", - "volcanoe", "volcano", - "volcaron", "volcano", - "vriament", "vraiment", - "wahtever", "whatever", - "wallpapr", "wallpapers", - "warantee", "warranty", - "warcarft", "warcraft", - "warrante", "warranties", - "warriros", "warriors", - "watchemn", "watchmen", - "watchign", "watching", - "wathcing", "watching", - "wathcmen", "watchmen", - "wathever", "whatever", - "watkings", "watkins", - "wealthly", "wealthy", - "webistes", "websites", - "websties", "websites", - "wednesdy", "wednesdays", - "weigthed", "weighted", - "weridest", "weirdest", - "werstler", "wrestler", - "wesbites", "websites", - "westbrok", "westbrook", - "westerse", "westerners", - "wherease", "whereas", - "whipsers", "whispers", - "whislist", "wishlist", - "whisltes", "whistles", - "whisperd", "whispered", - "whistels", "whistles", - "whitsles", "whistles", - "whsipers", "whispers", - "widgetas", "widgets", - "wieghted", "weighted", - "willaims", "williams", - "willfuly", "willfully", - "willimas", "williams", - "windsoar", "windsor", - "wininpeg", "winnipeg", - "winnigns", "winnings", - "winnpieg", "winnipeg", - "wiredest", "weirdest", - "wishlsit", "wishlist", - "wishpers", "whispers", - "withdral", "withdrawal", - "witnesss", "witnesses", - "wonderes", "wonders", - "wonderus", "wonders", - "workfore", "workforce", - "wouldnot", "wouldnt", - "wranlger", "wrangler", - "wreckign", "wrecking", - "wrecthed", "wretched", - "wrekcing", "wrecking", - "wreslter", "wrestler", - "wresters", "wrestlers", - "writting", "writing", - "wrnagler", "wrangler", - "wrteched", "wretched", - "yeilding", "yielding", - "yoesmite", "yosemite", - "yorksher", "yorkshire", - "yorkshie", "yorkshire", - "yosemeti", "yosemite", - "yosimete", "yosemite", - "zealotes", "zealots", - "zealoths", "zealots", - "zealotus", "zealots", - "zealouts", "zealous", - "zepplein", "zeppelin", - "zepplien", "zeppelin", - "zimbabew", "zimbabwe", - "zimbawbe", "zimbabwe", - "zinoists", "zionists", - "zionisim", "zionism", - "zionistm", "zionism", - "zionsits", "zionists", - "zoinists", "zionists", - "abiltiy", "ability", - "abodmen", "abdomen", - "abondon", "abandon", - "aboslve", "absolve", - "abosrbs", "absorbs", - "abriter", "arbiter", - "abrupty", "abruptly", - "absense", "absence", - "absolue", "absolute", - "absovle", "absolve", - "absrobs", "absorbs", - "absuers", "abusers", - "absurdy", "absurdly", - "absymal", "abysmal", - "abymsal", "abysmal", - "acadamy", "academy", - "acadmic", "academic", - "accesss", "access", - "accpets", "accepts", - "accross", "across", - "accuray", "accuracy", - "acheive", "achieve", - "achived", "achieved", - "acident", "accident", - "ackward", "awkward", - "acrlyic", "acrylic", - "actauly", "actually", - "activit", "activist", - "activly", "actively", - "actualy", "actually", - "actulay", "actually", - "acuracy", "accuracy", - "acusing", "causing", - "acustom", "accustom", - "acutaly", "actually", - "acyrlic", "acrylic", - "adaptes", "adapters", - "adatper", "adapter", - "adbomen", "abdomen", - "addcits", "addicts", - "adderss", "address", - "addtion", "addition", - "adequet", "adequate", - "adequit", "adequate", - "adivser", "adviser", - "adivsor", "advisor", - "admited", "admitted", - "admrial", "admiral", - "adpater", "adapter", - "adquire", "acquire", - "adultey", "adultery", - "adverst", "adverts", - "adviced", "advised", - "advocay", "advocacy", - "advsior", "advisor", - "aeriels", "aerials", - "affaris", "affairs", - "affiars", "affairs", - "afircan", "african", - "africas", "africans", - "afwully", "awfully", - "againts", "against", - "agaisnt", "against", - "aganist", "against", - "aggreed", "agreed", - "agianst", "against", - "agreing", "agreeing", - "agruing", "arguing", - "ahtiest", "atheist", - "aicraft", "aircraft", - "ailmony", "alimony", - "airbore", "airborne", - "aircaft", "aircraft", - "airlfow", "airflow", - "airosft", "airsoft", - "airpost", "airports", - "airsfot", "airsoft", - "airzona", "arizona", - "alchmey", "alchemy", - "alchool", "alcohol", - "alcohal", "alcohol", - "aledged", "alleged", - "aledges", "alleges", - "alegbra", "algebra", - "algerba", "algebra", - "alienet", "alienate", - "alledge", "allege", - "allegry", "allergy", - "alltime", "all-time", - "almighy", "almighty", - "alochol", "alcohol", - "alotted", "allotted", - "alowing", "allowing", - "alphabt", "alphabet", - "alreayd", "already", - "alrighy", "alrighty", - "altanta", "atlanta", - "alteast", "atleast", - "altough", "although", - "alusion", "allusion", - "amateus", "amateurs", - "amatuer", "amateur", - "amature", "armature", - "amensia", "amnesia", - "amensty", "amnesty", - "amercia", "america", - "americs", "americas", - "ammount", "amount", - "ammused", "amused", - "amneisa", "amnesia", - "amnsety", "amnesty", - "amognst", "amongst", - "amongts", "amongst", - "amonsgt", "amongst", - "ampilfy", "amplify", - "amrpits", "armpits", - "analoge", "analogue", - "analsyt", "analyst", - "analyes", "analyse", - "analyts", "analyst", - "analzye", "analyze", - "anaylse", "analyse", - "anaylst", "analyst", - "anaylze", "analyze", - "anceint", "ancient", - "andorid", "android", - "andriod", "android", - "androis", "androids", - "angirly", "angrily", - "angluar", "angular", - "angualr", "angular", - "anicent", "ancient", - "anitque", "antique", - "anixety", "anxiety", - "anmesia", "amnesia", - "anmesty", "amnesty", - "annoint", "anoint", - "annualy", "annually", - "annuled", "annulled", - "anohter", "another", - "anomoly", "anomaly", - "answerd", "answered", - "anuglar", "angular", - "anulled", "annulled", - "anwsers", "answers", - "anwyays", "anyways", - "anxeity", "anxiety", - "anyoens", "anyones", - "anyonse", "anyones", - "anywyas", "anyways", - "aparent", "apparent", - "appeard", "appeared", - "appluad", "applaud", - "aproval", "approval", - "apsects", "aspects", - "apshalt", "asphalt", - "apsirin", "aspirin", - "aqcuire", "acquire", - "aquarim", "aquarium", - "aquired", "acquired", - "aranged", "arranged", - "arbitre", "arbiter", - "arcahic", "archaic", - "archiac", "archaic", - "arcylic", "acrylic", - "aresnal", "arsenal", - "aretmis", "artemis", - "argubly", "arguably", - "aribter", "arbiter", - "ariflow", "airflow", - "arisoft", "airsoft", - "aritsts", "artists", - "armchar", "armchair", - "arogant", "arrogant", - "arogent", "arrogant", - "arresst", "arrests", - "arround", "around", - "arsneal", "arsenal", - "artcile", "article", - "artical", "article", - "articel", "article", - "artistc", "artistic", - "artmeis", "artemis", - "artsits", "artists", - "aruging", "arguing", - "aseuxal", "asexual", - "asexaul", "asexual", - "ashpalt", "asphalt", - "asiprin", "aspirin", - "asissts", "assists", - "asnwers", "answers", - "asorbed", "absorbed", - "aspahlt", "asphalt", - "asphlat", "asphalt", - "aspriin", "aspirin", - "assagne", "assange", - "assasin", "assassin", - "assembe", "assemble", - "assemby", "assembly", - "assisst", "assists", - "assnage", "assange", - "asssits", "assists", - "assualt", "assault", - "asterik", "asterisk", - "asutria", "austria", - "atcualy", "actually", - "atelast", "atleast", - "athesim", "atheism", - "athiesm", "atheism", - "athiest", "atheist", - "athiets", "atheist", - "athlets", "athletes", - "atlantc", "atlantic", - "atleats", "atleast", - "atlesat", "atleast", - "atorney", "attorney", - "atremis", "artemis", - "attemps", "attempts", - "attemts", "attempts", - "attened", "attended", - "attracs", "attracts", - "audbile", "audible", - "audibel", "audible", - "austira", "austria", - "austrai", "austria", - "autistc", "autistic", - "avation", "aviation", - "avtaars", "avatars", - "awakend", "awakened", - "bablyon", "babylon", - "backdor", "backdoor", - "backsta", "backseat", - "baclony", "balcony", - "badnits", "bandits", - "baiscly", "basically", - "bakcers", "backers", - "balanse", "balances", - "balcked", "blacked", - "banhsee", "banshee", - "bankgok", "bangkok", - "baoynet", "bayonet", - "baptims", "baptism", - "baptsim", "baptism", - "baragin", "bargain", - "bargani", "bargain", - "bargian", "bargain", - "bariner", "brainer", - "barlkey", "barkley", - "barracs", "barracks", - "barrles", "barrels", - "barsita", "barista", - "barvery", "bravery", - "bascily", "basically", - "basicly", "basically", - "basilcy", "basically", - "basiton", "bastion", - "basnhee", "banshee", - "bastane", "bastante", - "bastars", "bastards", - "bastino", "bastion", - "bathrom", "bathroom", - "batitsa", "batista", - "batsita", "batista", - "bayblon", "babylon", - "baynoet", "bayonet", - "bayoent", "bayonet", - "bceuase", "because", - "beacuse", "because", - "bealtes", "beatles", - "beaslty", "beastly", - "beatels", "beatles", - "beaucop", "beaucoup", - "becamae", "became", - "becames", "becomes", - "becasue", "because", - "becouse", "because", - "becuaes", "because", - "becuase", "because", - "becusae", "because", - "befried", "befriend", - "beggins", "begins", - "beglian", "belgian", - "beglium", "belgium", - "begnals", "bengals", - "bejiing", "beijing", - "beleifs", "beliefs", - "beleive", "believe", - "belgain", "belgian", - "belguim", "belgium", - "believr", "believer", - "believs", "believes", - "belifes", "beliefs", - "beligan", "belgian", - "beligum", "belgium", - "belived", "believed", - "belives", "believes", - "benagls", "bengals", - "benedit", "benedict", - "benghai", "benghazi", - "benglas", "bengals", - "benifit", "benefit", - "beoynce", "beyonce", - "beraded", "bearded", - "bersekr", "berserk", - "beseige", "besiege", - "betales", "beatles", - "bethesa", "bethesda", - "betrayd", "betrayed", - "beucase", "because", - "bewteen", "between", - "bicthes", "bitches", - "bidrman", "birdman", - "biejing", "beijing", - "bifgoot", "bigfoot", - "bigorty", "bigotry", - "bigtoed", "bigoted", - "bigtory", "bigotry", - "biogted", "bigoted", - "biogtry", "bigotry", - "bioplar", "bipolar", - "biploar", "bipolar", - "birdamn", "birdman", - "birdges", "bridges", - "birgade", "brigade", - "bitcion", "bitcoin", - "bithced", "bitched", - "bithces", "bitches", - "bitocin", "bitcoin", - "bizzare", "bizarre", - "blacony", "balcony", - "blaimed", "blamed", - "blankes", "blankets", - "blegian", "belgian", - "blegium", "belgium", - "blizzad", "blizzard", - "blockes", "blockers", - "bloster", "bolster", - "blulets", "bullets", - "bobmers", "bombers", - "bollocs", "bollocks", - "bondary", "boundary", - "bonnano", "bonanno", - "bonsues", "bonuses", - "boraden", "broaden", - "borader", "broader", - "boradly", "broadly", - "bordeom", "boredom", - "boslter", "bolster", - "boudler", "boulder", - "boundry", "boundary", - "bounses", "bonuses", - "boutiqe", "boutique", - "bouyant", "buoyant", - "braevry", "bravery", - "braista", "barista", - "brakley", "barkley", - "branier", "brainer", - "braoden", "broaden", - "braoder", "broader", - "braodly", "broadly", - "brednan", "brendan", - "breifly", "briefly", - "breserk", "berserk", - "brethen", "brethren", - "brewrey", "brewery", - "briagde", "brigade", - "brianer", "brainer", - "bridman", "birdman", - "brielfy", "briefly", - "brigdes", "bridges", - "brightn", "brighten", - "brisben", "brisbane", - "britian", "britain", - "britsol", "bristol", - "briused", "bruised", - "briuser", "bruiser", - "briuses", "bruises", - "brocoli", "broccoli", - "bronocs", "broncos", - "browine", "brownie", - "brownei", "brownie", - "brownis", "brownies", - "bruglar", "burglar", - "brunete", "brunette", - "bruning", "burning", - "brusied", "bruised", - "brusies", "bruises", - "brusses", "brussels", - "brutaly", "brutally", - "btiched", "bitched", - "btiches", "bitches", - "bubbels", "bubbles", - "buddhim", "buddhism", - "buddhit", "buddhist", - "buddist", "buddhist", - "budgest", "budgets", - "bugdets", "budgets", - "buildes", "builders", - "bulgara", "bulgaria", - "bullest", "bullets", - "buoancy", "buoyancy", - "burguny", "burgundy", - "buriser", "bruiser", - "burlgar", "burglar", - "burnign", "burning", - "burried", "buried", - "burrtio", "burrito", - "busines", "business", - "busness", "business", - "butthoe", "butthole", - "buttrey", "buttery", - "cababge", "cabbage", - "cabines", "cabinets", - "cabniet", "cabinet", - "caclium", "calcium", - "cacuses", "caucuses", - "caffeen", "caffeine", - "cahched", "cached", - "cahotic", "chaotic", - "cahsier", "cashier", - "cailbre", "calibre", - "calaber", "caliber", - "calagry", "calgary", - "calback", "callback", - "calbire", "calibre", - "calcuim", "calcium", - "calculs", "calculus", - "calicum", "calcium", - "calrify", "clarify", - "calrity", "clarity", - "caluses", "clauses", - "camboda", "cambodia", - "campain", "campaign", - "campuss", "campuses", - "cancles", "cancels", - "cancres", "cancers", - "cancuks", "canucks", - "canides", "candies", - "cannnot", "cannot", - "canrage", "carnage", - "capible", "capable", - "capitas", "capitals", - "capsuls", "capsules", - "captais", "captains", - "captial", "capital", - "captiol", "capitol", - "captued", "captured", - "capturd", "captured", - "capusle", "capsule", - "carange", "carnage", - "carbien", "carbine", - "cardaic", "cardiac", - "cardina", "cardigan", - "careing", "caring", - "caridac", "cardiac", - "carmtan", "cartman", - "carnege", "carnage", - "carnige", "carnage", - "carolan", "carolina", - "carreer", "career", - "carrers", "careers", - "cartles", "cartels", - "caryons", "crayons", - "casette", "cassette", - "casheir", "cashier", - "cashies", "cashiers", - "cashire", "cashier", - "casltes", "castles", - "caspule", "capsule", - "cassete", "cassette", - "castels", "castles", - "casuing", "causing", - "cathlic", "catholic", - "cauncks", "canucks", - "cavarly", "cavalry", - "cavlary", "cavalry", - "celcius", "celsius", - "celisus", "celsius", - "celitcs", "celtics", - "celsuis", "celsius", - "centruy", "century", - "centuty", "century", - "ceratin", "certain", - "cermaic", "ceramic", - "certian", "certain", - "cervial", "cervical", - "cesspol", "cesspool", - "cetlics", "celtics", - "chambre", "chamber", - "charcol", "charcoal", - "charisa", "charisma", - "chasiss", "chassis", - "chatoic", "chaotic", - "cheeots", "cheetos", - "cheesse", "cheeses", - "chekcer", "checker", - "chelsae", "chelsea", - "cheslea", "chelsea", - "chiense", "chinese", - "childen", "children", - "chimeny", "chimney", - "chinees", "chinese", - "chinmey", "chimney", - "chipest", "chipset", - "chispet", "chipset", - "chivaly", "chivalry", - "chlesea", "chelsea", - "chnages", "changes", - "choatic", "chaotic", - "chocies", "choices", - "choosen", "chosen", - "chtulhu", "cthulhu", - "churchs", "churches", - "cilanto", "cilantro", - "cilents", "clients", - "circels", "circles", - "circuis", "circuits", - "cirlces", "circles", - "clacium", "calcium", - "claerer", "clearer", - "claerly", "clearly", - "clagary", "calgary", - "claibre", "calibre", - "claimes", "claims", - "clairfy", "clarify", - "clairty", "clarity", - "clanand", "clannad", - "clarfiy", "clarify", - "classis", "classics", - "clasues", "clauses", - "claymer", "claymore", - "claymoe", "claymore", - "cleanes", "cleanse", - "cleasne", "cleanse", - "cleints", "clients", - "clenase", "cleanse", - "clesius", "celsius", - "cletics", "celtics", - "clevery", "cleverly", - "climats", "climates", - "climbes", "climbers", - "clincis", "clinics", - "clitors", "clitoris", - "cloesly", "closely", - "closley", "closely", - "cluases", "clauses", - "cluprit", "culprit", - "coalese", "coalesce", - "coctail", "cocktail", - "cohesie", "cohesive", - "colgone", "cologne", - "collape", "collapse", - "collest", "collects", - "collony", "colony", - "collumn", "column", - "cologen", "cologne", - "colomba", "colombia", - "colonge", "cologne", - "colorao", "colorado", - "colourd", "coloured", - "columsn", "columns", - "comando", "commando", - "comapny", "company", - "comapre", "compare", - "comarde", "comrade", - "comback", "comeback", - "combins", "combines", - "comdeic", "comedic", - "comited", "committed", - "commano", "commando", - "commans", "commands", - "commere", "commerce", - "comming", "coming", - "commitd", "committed", - "compase", "compares", - "compede", "competed", - "compilr", "compiler", - "compnay", "company", - "compots", "compost", - "comrads", "comrades", - "comtpon", "compton", - "conceed", "concede", - "conceps", "concepts", - "conclue", "conclude", - "concret", "concert", - "condenm", "condemn", - "condiut", "conduit", - "condmen", "condemn", - "confids", "confides", - "confins", "confines", - "confise", "confines", - "conflit", "conflict", - "conived", "connived", - "connecs", "connects", - "conqeur", "conquer", - "conqure", "conquer", - "consept", "concept", - "consern", "concern", - "consums", "consumes", - "contacs", "contacts", - "contais", "contains", - "contast", "contacts", - "contemt", "contempt", - "contens", "contents", - "contess", "contests", - "contian", "contain", - "contine", "continue", - "convers", "converts", - "conveyd", "conveyed", - "convine", "convince", - "coprses", "corpses", - "coputer", "computer", - "corasir", "corsair", - "coratia", "croatia", - "coridal", "cordial", - "corsari", "corsair", - "corsiar", "corsair", - "corspes", "corpses", - "corwbar", "crowbar", - "costums", "costumes", - "coudlnt", "couldnt", - "coulmns", "columns", - "coulndt", "couldnt", - "counsle", "counsel", - "countes", "counters", - "courtey", "courtesy", - "covenat", "covenant", - "coytoes", "coyotes", - "crabine", "carbine", - "cralwed", "crawled", - "craotia", "croatia", - "craweld", "crawled", - "creamic", "ceramic", - "createn", "creatine", - "creater", "creature", - "creatie", "creatine", - "creatue", "creature", - "creepes", "creepers", - "creepig", "creeping", - "creulty", "cruelty", - "cricles", "circles", - "critera", "criteria", - "cropses", "corpses", - "crosair", "corsair", - "crpytic", "cryptic", - "crsytal", "crystal", - "crtical", "critical", - "crucibe", "crucible", - "cruetly", "cruelty", - "cruical", "crucial", - "crulety", "cruelty", - "crusdae", "crusade", - "crusier", "cruiser", - "crusies", "cruises", - "crusive", "cursive", - "crutchs", "crutches", - "crypitc", "cryptic", - "crystas", "crystals", - "crystsl", "crystals", - "crytpic", "cryptic", - "crytsal", "crystal", - "cthluhu", "cthulhu", - "cthuhlu", "cthulhu", - "cthuluh", "cthulhu", - "ctuhlhu", "cthulhu", - "cuasing", "causing", - "cubcile", "cubicle", - "cubilce", "cubicle", - "cuddels", "cuddles", - "culrpit", "culprit", - "culturs", "cultures", - "cupboad", "cupboard", - "cuplrit", "culprit", - "curatin", "curtain", - "curcial", "crucial", - "curcuit", "circuit", - "curelty", "cruelty", - "curiser", "cruiser", - "curisve", "cursive", - "currate", "curate", - "currens", "currents", - "curreny", "currency", - "currest", "currents", - "cursade", "crusade", - "curtian", "curtain", - "cyandie", "cyanide", - "cyclits", "cyclist", - "cycloen", "cyclone", - "cycolps", "cyclops", - "cylcist", "cyclist", - "cylcone", "cyclone", - "cylcops", "cyclops", - "cynaide", "cyanide", - "cyrptic", "cryptic", - "cyrstal", "crystal", - "dagners", "dangers", - "daimond", "diamond", - "damenor", "demeanor", - "dammage", "damage", - "darcula", "dracula", - "dargons", "dragons", - "darkets", "darkest", - "datbase", "database", - "daulity", "duality", - "dawrves", "dwarves", - "ddogers", "dodgers", - "ddoging", "dodging", - "deadlit", "deadlift", - "deadpol", "deadpool", - "deafult", "default", - "deahtly", "deathly", - "deatils", "details", - "deatlhy", "deathly", - "decalre", "declare", - "decison", "decision", - "declars", "declares", - "declase", "declares", - "decress", "decrees", - "decribe", "describe", - "decsend", "descend", - "dectect", "detect", - "defaint", "defiant", - "defauls", "defaults", - "defelct", "deflect", - "defensd", "defends", - "deffine", "define", - "definat", "defiant", - "definet", "definite", - "definie", "definite", - "definig", "defining", - "definit", "definite", - "defualt", "default", - "degarde", "degrade", - "degrase", "degrasse", - "degrate", "degrade", - "deiners", "deniers", - "deisgns", "designs", - "deivant", "deviant", - "dekstop", "desktop", - "delcare", "declare", - "delfect", "deflect", - "demenor", "demeanor", - "dementa", "dementia", - "demsond", "desmond", - "deneirs", "deniers", - "denisty", "density", - "densley", "densely", - "depcits", "depicts", - "dependd", "depended", - "depitcs", "depicts", - "deployd", "deployed", - "depsise", "despise", - "descrie", "describe", - "descuss", "discuss", - "desgins", "designs", - "desings", "designs", - "desitny", "destiny", - "desnely", "densely", - "desnity", "density", - "desomnd", "desmond", - "despict", "depict", - "despide", "despised", - "despies", "despise", - "destkop", "desktop", - "destory", "destroy", - "destros", "destroys", - "detaild", "detailed", - "detials", "details", - "detorit", "detroit", - "detriot", "detroit", - "deuling", "dueling", - "devaint", "deviant", - "devaite", "deviate", - "devided", "divided", - "devlove", "devolve", - "devotin", "devotion", - "devovle", "devolve", - "diabets", "diabetes", - "dialecs", "dialects", - "dialoge", "dialogue", - "diamons", "diamonds", - "diasble", "disable", - "dicksih", "dickish", - "dicover", "discover", - "dictats", "dictates", - "dieties", "deities", - "dilpoma", "diploma", - "dimaond", "diamond", - "dingity", "dignity", - "dinosar", "dinosaur", - "diosese", "diocese", - "dipolma", "diploma", - "dirbble", "dribble", - "directy", "directly", - "diretcx", "directx", - "dirived", "derived", - "dirvers", "drivers", - "disbale", "disable", - "disguss", "disgusts", - "disliks", "dislikes", - "disover", "discover", - "dispair", "despair", - "dispath", "dispatch", - "dispite", "despite", - "dispuse", "disputes", - "disputs", "disputes", - "dissole", "dissolve", - "distase", "distaste", - "distint", "distinct", - "divison", "division", - "docuhes", "douches", - "docuhey", "douchey", - "dogders", "dodgers", - "dogding", "dodging", - "dolhpin", "dolphin", - "dolphis", "dolphins", - "dominae", "dominate", - "dominno", "dominion", - "doplhin", "dolphin", - "dortmud", "dortmund", - "draclua", "dracula", - "dracual", "dracula", - "drakest", "darkest", - "dramtic", "dramatic", - "dribbel", "dribble", - "driectx", "directx", - "driftig", "drifting", - "drinkes", "drinkers", - "druming", "drumming", - "duailty", "duality", - "dualtiy", "duality", - "dubsetp", "dubstep", - "dulaity", "duality", - "duleing", "dueling", - "dunegon", "dungeon", - "dungeos", "dungeons", - "dungoen", "dungeon", - "durring", "during", - "dusbtep", "dubstep", - "dyansty", "dynasty", - "dynamis", "dynamics", - "dynsaty", "dynasty", - "earlies", "earliest", - "earliet", "earliest", - "earplus", "earplugs", - "eastwod", "eastwood", - "ebcuase", "because", - "ecilpse", "eclipse", - "eclipes", "eclipse", - "eclispe", "eclipse", - "eclpise", "eclipse", - "ectsasy", "ecstasy", - "edbiles", "edibles", - "edibels", "edibles", - "effords", "efforts", - "ehtanol", "ethanol", - "eifnach", "einfach", - "eighten", "eighteen", - "einfahc", "einfach", - "elasped", "elapsed", - "elcipse", "eclipse", - "elction", "election", - "elecrto", "electro", - "electic", "electric", - "electon", "election", - "ellitot", "elliott", - "elloitt", "elliott", - "elphant", "elephant", - "emabrgo", "embargo", - "emabssy", "embassy", - "emapthy", "empathy", - "embeded", "embedded", - "embrago", "embargo", - "eminate", "emanate", - "emipres", "empires", - "emision", "emission", - "emiting", "emitting", - "emition", "emission", - "emmited", "emitted", - "empahty", "empathy", - "emphsis", "emphasis", - "empiers", "empires", - "empited", "emptied", - "emplore", "employer", - "emporer", "emperor", - "empries", "empires", - "emtpied", "emptied", - "enameld", "enameled", - "encahnt", "enchant", - "encalve", "enclave", - "encrpyt", "encrypt", - "encyrpt", "encrypt", - "endores", "endorse", - "endrose", "endorse", - "energis", "energies", - "enforse", "enforces", - "enginer", "engineer", - "englsih", "english", - "enhanse", "enhances", - "enlcave", "enclave", - "enlgish", "english", - "enlsave", "enslave", - "ensalve", "enslave", - "entbook", "netbook", - "entirey", "entirety", - "entorpy", "entropy", - "epiloge", "epilogue", - "episdoe", "episode", - "epsiode", "episode", - "epsorts", "esports", - "eptiome", "epitome", - "equiped", "equipped", - "erested", "arrested", - "escapse", "escapes", - "escpaes", "escapes", - "esctasy", "ecstasy", - "esporst", "esports", - "espreso", "espresso", - "esprots", "esports", - "essense", "essence", - "etherel", "ethereal", - "ethnaol", "ethanol", - "euphora", "euphoria", - "europen", "european", - "eurpean", "european", - "everets", "everest", - "everset", "everest", - "evloved", "evolved", - "evloves", "evolves", - "evovled", "evolved", - "evovles", "evolves", - "exaclty", "exactly", - "exahust", "exhaust", - "examind", "examined", - "exapnds", "expands", - "exatled", "exalted", - "excange", "exchange", - "excatly", "exactly", - "excells", "excels", - "exceprt", "excerpt", - "excluse", "excludes", - "excrept", "excerpt", - "exculde", "exclude", - "exelent", "excellent", - "exemple", "example", - "exerpts", "excerpts", - "exhasut", "exhaust", - "exhuast", "exhaust", - "exising", "existing", - "existet", "existent", - "exlated", "exalted", - "exlcude", "exclude", - "exliled", "exiled", - "exludes", "excludes", - "exmaple", "example", - "exoitcs", "exotics", - "expalin", "explain", - "expeced", "expected", - "expells", "expels", - "expiers", "expires", - "explict", "explicit", - "expliot", "exploit", - "explods", "explodes", - "explose", "explodes", - "expolde", "explode", - "expolit", "exploit", - "exposse", "exposes", - "expries", "expires", - "exracts", "extracts", - "exsited", "existed", - "extered", "exerted", - "exterme", "extreme", - "extoics", "exotics", - "extreem", "extreme", - "extrems", "extremes", - "eyebals", "eyeballs", - "eyebros", "eyebrows", - "fabulos", "fabulous", - "facebok", "facebook", - "facepam", "facepalm", - "faclons", "falcons", - "facsism", "fascism", - "facsist", "fascist", - "failurs", "failures", - "faincee", "fiancee", - "falesly", "falsely", - "falired", "flaired", - "falshed", "flashed", - "falshes", "flashes", - "falsley", "falsely", - "falvors", "flavors", - "familes", "families", - "famoust", "famous", - "famousy", "famously", - "fanatsy", "fantasy", - "fantaic", "fanatic", - "faoming", "foaming", - "fascits", "fascist", - "fasicsm", "fascism", - "fasicst", "fascist", - "faslely", "falsely", - "fatiuge", "fatigue", - "febuary", "february", - "fecthed", "fetched", - "fecthes", "fetches", - "feminen", "feminine", - "feminie", "feminine", - "feminim", "feminism", - "feodras", "fedoras", - "fertily", "fertility", - "fesitve", "festive", - "fethced", "fetched", - "fethces", "fetches", - "fetishs", "fetishes", - "fianite", "finite", - "fianlly", "finally", - "fiercly", "fiercely", - "filcker", "flicker", - "filpped", "flipped", - "filterd", "filtered", - "finacee", "fiancee", - "fineses", "finesse", - "fininsh", "finnish", - "finishs", "finishes", - "finisse", "finishes", - "finnsih", "finnish", - "firends", "friends", - "firggin", "friggin", - "firsbee", "frisbee", - "firslty", "firstly", - "firtsly", "firstly", - "fitlers", "filters", - "flacons", "falcons", - "flahsed", "flashed", - "flahses", "flashes", - "flaried", "flaired", - "flasely", "falsely", - "flashig", "flashing", - "flavord", "flavored", - "flavous", "flavours", - "flawess", "flawless", - "flciker", "flicker", - "fliters", "filters", - "flordia", "florida", - "florene", "florence", - "fnaatic", "fanatic", - "fomaing", "foaming", - "fonetic", "phonetic", - "forefit", "forfeit", - "foregin", "foreign", - "foreing", "foreign", - "forfiet", "forfeit", - "forhead", "forehead", - "foriegn", "foreign", - "formaly", "formally", - "formery", "formerly", - "formost", "foremost", - "formual", "formula", - "formuls", "formulas", - "forrset", "forrest", - "forsakn", "forsaken", - "forsane", "forsaken", - "forumla", "formula", - "fountan", "fountain", - "fourten", "fourteen", - "fracter", "fracture", - "fragmet", "fragment", - "freedos", "freedoms", - "freinds", "friends", - "frigign", "friggin", - "fristly", "firstly", - "frostig", "frosting", - "frsibee", "frisbee", - "fruitin", "fruition", - "fullets", "fullest", - "fullset", "fullest", - "funides", "fundies", - "funtion", "function", - "furance", "furnace", - "furncae", "furnace", - "futhroc", "futhark", - "gadgest", "gadgets", - "gagdets", "gadgets", - "galatic", "galactic", - "galcier", "glacier", - "galsgow", "glasgow", - "gameply", "gameplay", - "gamerga", "gamertag", - "gankign", "ganking", - "ganster", "gangster", - "garabge", "garbage", - "garfied", "garfield", - "garnola", "granola", - "generas", "generals", - "genersl", "generals", - "geniuss", "geniuses", - "geogria", "georgia", - "geomety", "geometry", - "georiga", "georgia", - "gernade", "grenade", - "gerogia", "georgia", - "gigabye", "gigabyte", - "giltchy", "glitchy", - "gimmics", "gimmicks", - "gimmicy", "gimmicky", - "girzzly", "grizzly", - "glagsow", "glasgow", - "glaicer", "glacier", - "glicthy", "glitchy", - "glimpes", "glimpse", - "glimspe", "glimpse", - "glipmse", "glimpse", - "glitchd", "glitched", - "glitchs", "glitches", - "glithcy", "glitchy", - "globaly", "globally", - "gloiath", "goliath", - "glorios", "glorious", - "gltichy", "glitchy", - "gnaking", "ganking", - "gnawwed", "gnawed", - "goddanm", "goddamn", - "goddman", "goddamn", - "godliek", "godlike", - "godlman", "goldman", - "godsped", "godspeed", - "goergia", "georgia", - "goilath", "goliath", - "golaith", "goliath", - "golbins", "goblins", - "goldamn", "goldman", - "goldbeg", "goldberg", - "goldike", "godlike", - "golitah", "goliath", - "goodluk", "goodluck", - "gorumet", "gourmet", - "gosepls", "gospels", - "gosples", "gospels", - "gpysies", "gypsies", - "grabage", "garbage", - "grahpic", "graphic", - "grainte", "granite", - "grammer", "grammar", - "graniet", "granite", - "grantie", "granite", - "graphie", "graphite", - "graphis", "graphics", - "grappel", "grapple", - "greande", "grenade", - "grenads", "grenades", - "greneer", "greener", - "griaffe", "giraffe", - "gridles", "griddles", - "grillig", "grilling", - "grpahic", "graphic", - "guardin", "guardian", - "guiness", "guinness", - "gullibe", "gullible", - "gutiars", "guitars", - "gypises", "gypsies", - "gyspies", "gypsies", - "habaeus", "habeas", - "haethen", "heathen", - "hailfax", "halifax", - "halfiax", "halifax", - "handbok", "handbook", - "handedy", "handedly", - "handeld", "handled", - "hanlder", "handler", - "hannibl", "hannibal", - "hanuted", "haunted", - "haorder", "hoarder", - "hapened", "happened", - "happend", "happened", - "happliy", "happily", - "harased", "harassed", - "harases", "harasses", - "hardend", "hardened", - "hardwod", "hardwood", - "haricut", "haircut", - "hatchig", "hatching", - "hauntig", "haunting", - "haviest", "heaviest", - "headest", "headset", - "headses", "headsets", - "heaveny", "heavenly", - "heigher", "higher", - "heigths", "heights", - "helemts", "helmets", - "hellfie", "hellfire", - "hellvua", "helluva", - "helment", "helmet", - "helpped", "helped", - "hemlets", "helmets", - "henious", "heinous", - "heorics", "heroics", - "heorine", "heroine", - "heriocs", "heroics", - "herione", "heroine", - "herocis", "heroics", - "heronie", "heroine", - "hesiman", "heisman", - "hieghts", "heights", - "hienous", "heinous", - "hiesman", "heisman", - "himselv", "himself", - "hiptser", "hipster", - "hismelf", "himself", - "hispter", "hipster", - "hitboxs", "hitboxes", - "hoilday", "holiday", - "hokpins", "hopkins", - "holdiay", "holiday", - "holdins", "holdings", - "homniem", "hominem", - "horader", "hoarder", - "hosited", "hoisted", - "hosthot", "hotshot", - "hostles", "hostels", - "hostpot", "hotspot", - "hothsot", "hotshot", - "hotpsot", "hotspot", - "hotsopt", "hotspot", - "hounour", "honour", - "hseldon", "sheldon", - "huanted", "haunted", - "humanit", "humanist", - "humants", "humanist", - "humidiy", "humidity", - "humoros", "humorous", - "hunagry", "hungary", - "hunderd", "hundred", - "hundres", "hundreds", - "hungray", "hungary", - "hurdels", "hurdles", - "hurldes", "hurdles", - "husbans", "husbands", - "hweaton", "wheaton", - "hybirds", "hybrids", - "hydogen", "hydrogen", - "hygeine", "hygiene", - "hypnoss", "hypnosis", - "hyrbids", "hybrids", - "hystera", "hysteria", - "iceforg", "icefrog", - "ierland", "ireland", - "ignitin", "ignition", - "ignorat", "ignorant", - "illegas", "illegals", - "illegsl", "illegals", - "illinos", "illinois", - "imanent", "eminent", - "imapcts", "impacts", - "iminent", "eminent", - "imminet", "imminent", - "implict", "implicit", - "imploed", "implode", - "imploys", "employs", - "impluse", "impulse", - "impolde", "implode", - "importd", "imported", - "imporve", "improve", - "impules", "impulse", - "impusle", "impulse", - "imrpove", "improve", - "incldue", "include", - "incluse", "includes", - "indains", "indians", - "indeces", "indices", - "indiaan", "indiana", - "indluge", "indulge", - "indugle", "indulge", - "infalte", "inflate", - "infenro", "inferno", - "infered", "inferred", - "inferir", "inferior", - "infinet", "infinite", - "infinie", "infinite", - "infinit", "infinite", - "infornt", "infront", - "infroms", "informs", - "infrotn", "infront", - "inheirt", "inherit", - "inidans", "indians", - "initals", "initials", - "initisl", "initials", - "inlcine", "incline", - "inovker", "invoker", - "inpeach", "impeach", - "inpsect", "inspect", - "inpsire", "inspire", - "inquier", "inquire", - "inquriy", "inquiry", - "insaney", "insanely", - "inscets", "insects", - "insepct", "inspect", - "insipre", "inspire", - "insluts", "insults", - "instade", "instead", - "instint", "instinct", - "intenst", "intents", - "intered", "interred", - "interet", "interest", - "internt", "internet", - "interro", "interior", - "intrest", "interest", - "intrige", "intrigue", - "invlove", "involve", - "invoekr", "invoker", - "invovle", "involve", - "iornman", "ironman", - "iranain", "iranian", - "iranias", "iranians", - "iranina", "iranian", - "irleand", "ireland", - "ironamn", "ironman", - "isalmic", "islamic", - "isareli", "israeli", - "islamit", "islamist", - "islmaic", "islamic", - "isloate", "isolate", - "isralei", "israeli", - "isreali", "israeli", - "italias", "italians", - "jagaurs", "jaguars", - "jaguras", "jaguars", - "jamacia", "jamaica", - "jamaina", "jamaican", - "jamiaca", "jamaica", - "jamsine", "jasmine", - "janaury", "january", - "januray", "january", - "japanes", "japanese", - "jasmien", "jasmine", - "jaugars", "jaguars", - "jaunary", "january", - "jeircho", "jericho", - "jennins", "jennings", - "jeopary", "jeopardy", - "jeresys", "jerseys", - "jericoh", "jericho", - "jersyes", "jerseys", - "jewerly", "jewelry", - "jorunal", "journal", - "jounral", "journal", - "joystik", "joystick", - "juadism", "judaism", - "judasim", "judaism", - "judical", "judicial", - "juipter", "jupiter", - "junglig", "jungling", - "juptier", "jupiter", - "jusitfy", "justify", - "justfiy", "justify", - "karakoe", "karaoke", - "karoake", "karaoke", - "kenendy", "kennedy", - "kenndey", "kennedy", - "kentucy", "kentucky", - "keyboad", "keyboard", - "keychan", "keychain", - "keynode", "keynote", - "kicthen", "kitchen", - "killins", "killings", - "kineitc", "kinetic", - "kinghts", "knights", - "kinteic", "kinetic", - "kitches", "kitchens", - "kitites", "kitties", - "knietic", "kinetic", - "knigths", "knights", - "knuckel", "knuckle", - "kroeans", "koreans", - "krudish", "kurdish", - "ktichen", "kitchen", - "kubirck", "kubrick", - "kunckle", "knuckle", - "kurbick", "kubrick", - "kuridsh", "kurdish", - "laguage", "language", - "landins", "landings", - "lantren", "lantern", - "laready", "already", - "laregly", "largely", - "largley", "largely", - "lasanga", "lasagna", - "lasgana", "lasagna", - "latitue", "latitude", - "latnern", "lantern", - "launhed", "launched", - "lavendr", "lavender", - "leathal", "lethal", - "lefitst", "leftist", - "leftits", "leftist", - "legnths", "lengths", - "legnthy", "lengthy", - "legoins", "legions", - "leigons", "legions", - "lenghts", "lengths", - "lenoard", "leonard", - "lepoard", "leopard", - "lesbain", "lesbian", - "lesiban", "lesbian", - "lesiure", "leisure", - "liasion", "liaison", - "liasons", "liaisons", - "liberae", "liberate", - "liberas", "liberals", - "lienups", "lineups", - "liesure", "leisure", - "liftime", "lifetime", - "lighlty", "lightly", - "lightes", "lighters", - "ligthly", "lightly", - "linclon", "lincoln", - "linueps", "lineups", - "liqiuds", "liquids", - "lisence", "license", - "lisense", "license", - "listend", "listened", - "litecon", "litecoin", - "literae", "literate", - "lithuim", "lithium", - "litihum", "lithium", - "loadous", "loadouts", - "loenard", "leonard", - "loepard", "leopard", - "logiteh", "logitech", - "loosley", "loosely", - "luandry", "laundry", - "luckliy", "luckily", - "luicfer", "lucifer", - "lunatis", "lunatics", - "maching", "machine", - "machins", "machines", - "maclolm", "malcolm", - "macthup", "matchup", - "madsion", "madison", - "magents", "magnets", - "magicin", "magician", - "magolia", "magnolia", - "maidson", "madison", - "maintan", "maintain", - "mairlyn", "marilyn", - "malaira", "malaria", - "malaysa", "malaysia", - "malclom", "malcolm", - "manauls", "manuals", - "mandase", "mandates", - "mandats", "mandates", - "mangeld", "mangled", - "mangets", "magnets", - "manualy", "manually", - "manuver", "maneuver", - "marbels", "marbles", - "margart", "margaret", - "mariage", "marriage", - "mariens", "marines", - "maritan", "martian", - "marixsm", "marxism", - "mariyln", "marilyn", - "markede", "marketed", - "marlbes", "marbles", - "marliyn", "marilyn", - "marnies", "marines", - "marrage", "marriage", - "martail", "martial", - "martain", "martian", - "masacra", "mascara", - "massace", "massacre", - "mathcup", "matchup", - "mathwes", "mathews", - "matrial", "martial", - "maunals", "manuals", - "mcalren", "mclaren", - "meanins", "meanings", - "medicad", "medicaid", - "medicae", "medicare", - "medioce", "mediocre", - "meixcan", "mexican", - "meldoic", "melodic", - "melieux", "milieux", - "melodis", "melodies", - "memeber", "member", - "memoery", "memory", - "memorie", "memory", - "menally", "mentally", - "mentaly", "mentally", - "meoldic", "melodic", - "meranda", "veranda", - "merchat", "merchant", - "merucry", "mercury", - "messagd", "messaged", - "messaih", "messiah", - "metagem", "metagame", - "metalic", "metallic", - "mexcian", "mexican", - "michina", "michigan", - "midfied", "midfield", - "midotwn", "midtown", - "midtwon", "midtown", - "migrans", "migrants", - "militat", "militant", - "militis", "militias", - "miltary", "military", - "mimimum", "minimum", - "mineras", "minerals", - "mininos", "minions", - "ministr", "minister", - "ministy", "ministry", - "minoins", "minions", - "minstry", "ministry", - "minumum", "minimum", - "mirrord", "mirrored", - "misandy", "misandry", - "misison", "mission", - "misouri", "missouri", - "mispell", "misspell", - "missils", "missiles", - "mistery", "mystery", - "mobiliy", "mobility", - "modualr", "modular", - "momento", "memento", - "momment", "moment", - "monarcy", "monarchy", - "monatge", "montage", - "monglos", "mongols", - "monitos", "monitors", - "monstre", "monster", - "montaeg", "montage", - "montrel", "montreal", - "monumet", "monument", - "morbidy", "morbidly", - "morgage", "mortgage", - "morphen", "morphine", - "morphie", "morphine", - "morroco", "morocco", - "mortage", "mortgage", - "mosnter", "monster", - "mosture", "moisture", - "motivet", "motivate", - "motnage", "montage", - "motoral", "motorola", - "mountan", "mountain", - "movment", "movement", - "mucuous", "mucous", - "muesums", "museums", - "muliple", "multiple", - "mulsims", "muslims", - "multipe", "multiple", - "multipy", "multiply", - "munbers", "numbers", - "munchis", "munchies", - "murderd", "murdered", - "muscial", "musical", - "mushrom", "mushroom", - "musilms", "muslims", - "muslces", "muscles", - "musuems", "museums", - "mutatin", "mutation", - "mypsace", "myspace", - "mysapce", "myspace", - "napolen", "napoleon", - "narhwal", "narwhal", - "natique", "antique", - "nativey", "natively", - "natrual", "natural", - "naugthy", "naughty", - "nauseos", "nauseous", - "nautils", "nautilus", - "nautral", "natural", - "nautres", "natures", - "nectode", "netcode", - "needels", "needles", - "neruons", "neurons", - "neslave", "enslave", - "netocde", "netcode", - "netowrk", "network", - "netural", "neutral", - "neturon", "neutron", - "netwrok", "network", - "neurton", "neutron", - "neuterd", "neutered", - "nighlty", "nightly", - "nigthly", "nightly", - "nihilim", "nihilism", - "ninties", "1990s", - "niverse", "inverse", - "nocture", "nocturne", - "nominae", "nominate", - "nominet", "nominate", - "nonsene", "nonsense", - "noramls", "normals", - "norhern", "northern", - "normaly", "normally", - "normany", "normandy", - "northen", "northern", - "nostris", "nostrils", - "notario", "ontario", - "notebok", "notebook", - "nothern", "northern", - "nowdays", "nowadays", - "nrivana", "nirvana", - "nuaghty", "naughty", - "nubmers", "numbers", - "nucelar", "nuclear", - "nucelus", "nucleus", - "nuclean", "unclean", - "nuclues", "nucleus", - "nucular", "nuclear", - "nuerons", "neurons", - "nuetral", "neutral", - "nuetron", "neutron", - "nulcear", "nuclear", - "nullfiy", "nullify", - "nusance", "nuisance", - "nutriet", "nutrient", - "oarcles", "oracles", - "obivous", "obvious", - "obvoius", "obvious", - "ocarnia", "ocarina", - "ocasion", "occasion", - "occured", "occurred", - "ocotber", "october", - "ocotpus", "octopus", - "ocraina", "ocarina", - "ocuntry", "country", - "ocurred", "occurred", - "ofcoure", "ofcourse", - "offcers", "officers", - "offical", "official", - "offisde", "offside", - "oftenly", "often", - "ogrilla", "gorilla", - "olmypic", "olympic", - "olreans", "orleans", - "olympis", "olympics", - "olypmic", "olympic", - "omision", "omission", - "omiting", "omitting", - "omlette", "omelette", - "ommited", "omitted", - "onatrio", "ontario", - "onbaord", "onboard", - "onborad", "onboard", - "ontairo", "ontario", - "ontraio", "ontario", - "opartor", "operator", - "openess", "openness", - "opitcal", "optical", - "opitmal", "optimal", - "oponent", "opponent", - "oposite", "opposite", - "oppenly", "openly", - "opponet", "opponent", - "oprhans", "orphans", - "optimim", "optimism", - "oracels", "oracles", - "oragnes", "oranges", - "oragsms", "orgasms", - "oralces", "oracles", - "orbtial", "orbital", - "orcales", "oracles", - "orelans", "orleans", - "organes", "organise", - "organie", "organise", - "organim", "organism", - "orginal", "original", - "orhpans", "orphans", - "oribtal", "orbital", - "orlenas", "orleans", - "orpahns", "orphans", - "orthodx", "orthodox", - "outfied", "outfield", - "outsidr", "outsider", - "overhal", "overhaul", - "overpad", "overpaid", - "oversue", "overuse", - "overtun", "overturn", - "ownders", "wonders", - "owuldve", "wouldve", - "oylmpic", "olympic", - "pacakge", "package", - "pacifit", "pacifist", - "packade", "packaged", - "pacthes", "patches", - "pahntom", "phantom", - "paitent", "patient", - "palcebo", "placebo", - "pallete", "palette", - "palster", "plaster", - "palyboy", "playboy", - "pamflet", "pamphlet", - "pamplet", "pamphlet", - "pancaks", "pancakes", - "pandroa", "pandora", - "panthen", "pantheon", - "paradim", "paradigm", - "paradse", "parades", - "paralel", "parallel", - "paranoa", "paranoia", - "parises", "praises", - "parites", "parties", - "partice", "particle", - "partick", "patrick", - "partiel", "particle", - "partiot", "patriot", - "partols", "patrols", - "passabe", "passable", - "passivs", "passives", - "pasuing", "pausing", - "pateint", "patient", - "pathces", "patches", - "patiens", "patients", - "patirot", "patriot", - "patrcik", "patrick", - "patrios", "patriots", - "patroit", "patriot", - "peaples", "peoples", - "pebbels", "pebbles", - "peirced", "pierced", - "penatly", "penalty", - "pendulm", "pendulum", - "penguis", "penguins", - "penicls", "pencils", - "penison", "pension", - "penisse", "penises", - "penitum", "pentium", - "pensies", "penises", - "pensino", "pension", - "pentuim", "pentium", - "peopels", "peoples", - "percise", "precise", - "perdict", "predict", - "perfers", "prefers", - "perhasp", "perhaps", - "perhpas", "perhaps", - "perisan", "persian", - "perjery", "perjury", - "permade", "premade", - "permier", "premier", - "permise", "premise", - "permium", "premium", - "peroids", "periods", - "peronal", "personal", - "perpaid", "prepaid", - "perphas", "perhaps", - "persain", "persian", - "persets", "presets", - "persits", "persist", - "persued", "pursued", - "persuit", "pursuit", - "pervail", "prevail", - "perview", "preview", - "pharoah", "pharaoh", - "phatnom", "phantom", - "phsyics", "physics", - "phyiscs", "physics", - "physcis", "physics", - "physiqe", "physique", - "picthed", "pitched", - "picther", "pitcher", - "picthes", "pitches", - "piegons", "pigeons", - "piglrim", "pilgrim", - "pigoens", "pigeons", - "pilgirm", "pilgrim", - "pilrgim", "pilgrim", - "pinoeer", "pioneer", - "pinpoit", "pinpoint", - "pionere", "pioneer", - "pireced", "pierced", - "pithces", "pitches", - "plantes", "planets", - "plastis", "plastics", - "plastre", "plaster", - "plataeu", "plateau", - "plateua", "plateau", - "playabe", "playable", - "playofs", "playoffs", - "plesant", "pleasant", - "pligrim", "pilgrim", - "ploygon", "polygon", - "ploymer", "polymer", - "podemso", "podemos", - "podmeos", "podemos", - "poeples", "peoples", - "poignat", "poignant", - "poineer", "pioneer", - "pointes", "pointers", - "poisond", "poisoned", - "polgyon", "polygon", - "polical", "political", - "polishs", "polishes", - "polisse", "polishes", - "politey", "politely", - "poluted", "polluted", - "polutes", "pollutes", - "popluar", "popular", - "populer", "popular", - "populos", "populous", - "porpose", "propose", - "porshan", "portion", - "porshon", "portion", - "portait", "portrait", - "portary", "portray", - "portras", "portrays", - "portrat", "portrait", - "posions", "poisons", - "positon", "position", - "positve", "positive", - "possibe", "possible", - "possiby", "possibly", - "postdam", "potsdam", - "postion", "position", - "postive", "positive", - "potatos", "potatoes", - "potical", "optical", - "potrait", "portrait", - "powderd", "powdered", - "poweful", "powerful", - "poylgon", "polygon", - "poylmer", "polymer", - "practie", "practise", - "praisse", "praises", - "praries", "prairies", - "prasied", "praised", - "prasies", "praises", - "pratice", "practice", - "preamde", "premade", - "preceed", "precede", - "precice", "precise", - "preests", "presets", - "prehaps", "perhaps", - "preimer", "premier", - "preimum", "premium", - "preists", "priests", - "preivew", "preview", - "premeir", "premier", - "premiee", "premiere", - "premire", "premier", - "premits", "permits", - "premius", "premiums", - "premuim", "premium", - "prepair", "prepare", - "preriod", "period", - "presens", "presents", - "presest", "presets", - "presist", "persist", - "prestes", "presets", - "presude", "presumed", - "pretene", "pretense", - "pretens", "pretends", - "preveiw", "preview", - "prevert", "pervert", - "previal", "prevail", - "previes", "previews", - "previos", "previous", - "priased", "praised", - "priases", "praises", - "printes", "printers", - "pristen", "pristine", - "probabe", "probable", - "probaly", "probably", - "probelm", "problem", - "procede", "proceed", - "procees", "proceeds", - "procesd", "proceeds", - "proclam", "proclaim", - "produly", "proudly", - "produse", "produces", - "progidy", "prodigy", - "progrom", "pogrom", - "prohibt", "prohibit", - "prohpet", "prophet", - "prologe", "prologue", - "promose", "promotes", - "promots", "promotes", - "prompty", "promptly", - "promtps", "prompts", - "pronous", "pronouns", - "prooved", "proved", - "propeht", "prophet", - "prophey", "prophecy", - "propper", "proper", - "protals", "portals", - "protecs", "protects", - "protess", "protests", - "protocl", "protocol", - "protray", "portray", - "prouldy", "proudly", - "provded", "provided", - "provine", "province", - "prusuit", "pursuit", - "pryamid", "pyramid", - "pscyhed", "psyched", - "ptiched", "pitched", - "pticher", "pitcher", - "puasing", "pausing", - "publicy", "publicly", - "publsih", "publish", - "puhsups", "pushups", - "punishs", "punishes", - "punisse", "punishes", - "pursiut", "pursuit", - "pursude", "pursued", - "purused", "pursued", - "pushpus", "pushups", - "pyarmid", "pyramid", - "pyramis", "pyramids", - "pyrmaid", "pyramid", - "pysched", "psyched", - "qaulify", "qualify", - "qaulity", "quality", - "qauntum", "quantum", - "quailfy", "qualify", - "quailty", "quality", - "queires", "queries", - "queitly", "quietly", - "quereis", "queries", - "quicket", "quickest", - "quielty", "quietly", - "quitely", "quietly", - "qunatum", "quantum", - "qunetin", "quentin", - "racisst", "racists", - "racthet", "ratchet", - "radaint", "radiant", - "radiane", "radiance", - "radicas", "radicals", - "radiers", "raiders", - "raelism", "realism", - "raidant", "radiant", - "railrod", "railroad", - "rainbos", "rainbows", - "raoches", "roaches", - "raoming", "roaming", - "raptros", "raptors", - "raputre", "rapture", - "rathcet", "ratchet", - "ratpure", "rapture", - "reacing", "reaching", - "reagrds", "regards", - "realies", "realise", - "realsie", "realise", - "realsim", "realism", - "realtes", "relates", - "reamins", "remains", - "reapirs", "repairs", - "rebouns", "rebounds", - "rebulit", "rebuilt", - "recalim", "reclaim", - "receips", "receipts", - "recided", "resided", - "reciept", "receipt", - "recievd", "received", - "recieve", "receive", - "recitfy", "rectify", - "recived", "received", - "reclami", "reclaim", - "recliam", "reclaim", - "recorre", "recorder", - "recoves", "recovers", - "recpies", "recipes", - "redeemd", "redeemed", - "redners", "renders", - "refelct", "reflect", - "referal", "referral", - "refered", "referred", - "referig", "referring", - "referrs", "refers", - "reflexs", "reflexes", - "refrers", "refers", - "refroms", "reforms", - "refusla", "refusal", - "regerts", "regrets", - "regiems", "regimes", - "regimet", "regiment", - "registy", "registry", - "regluar", "regular", - "regrest", "regrets", - "regulae", "regulate", - "regulas", "regulars", - "regulsr", "regulars", - "reigmes", "regimes", - "reigons", "regions", - "reitres", "retires", - "reivews", "reviews", - "reknown", "renown", - "relaise", "realise", - "relapes", "relapse", - "relaspe", "relapse", - "relatie", "relative", - "relatin", "relation", - "relcaim", "reclaim", - "releive", "relieve", - "releses", "releases", - "relfect", "reflect", - "reliabe", "reliable", - "relient", "reliant", - "relized", "realised", - "relpase", "relapse", - "remaind", "remained", - "remaing", "remaining", - "remakrs", "remarks", - "remannt", "remnant", - "remeber", "remember", - "remians", "remains", - "remnans", "remnants", - "renderd", "rendered", - "renegae", "renegade", - "renmant", "remnant", - "rentors", "renters", - "rentres", "renters", - "renuion", "reunion", - "repaird", "repaired", - "repalys", "replays", - "repblic", "republic", - "repeast", "repeats", - "repects", "respects", - "repitle", "reptile", - "replase", "replaces", - "replayd", "replayed", - "reponse", "response", - "repostd", "reposted", - "repsawn", "respawn", - "repsond", "respond", - "repsots", "reposts", - "reptiel", "reptile", - "reptils", "reptiles", - "repubic", "republic", - "republi", "republic", - "repulic", "republic", - "reqiuem", "requiem", - "requeim", "requiem", - "requime", "requiem", - "requred", "required", - "resapwn", "respawn", - "rescuse", "rescues", - "resembe", "resemble", - "reslove", "resolve", - "resolvs", "resolves", - "resonet", "resonate", - "resouce", "resource", - "resovle", "resolve", - "respest", "respects", - "respone", "response", - "respwan", "respawn", - "ressits", "resists", - "restord", "restored", - "resuced", "rescued", - "resuces", "rescues", - "retrive", "retrieve", - "returnd", "returned", - "reuinon", "reunion", - "reveald", "revealed", - "reveiws", "reviews", - "revelas", "reveals", - "reveral", "reversal", - "reviere", "reviewer", - "reviewd", "reviewed", - "reviewr", "reviewer", - "revolvr", "revolver", - "revolvs", "revolves", - "rewirte", "rewrite", - "reworkd", "reworked", - "rewriet", "rewrite", - "reynols", "reynolds", - "rhapsoy", "rhapsody", - "rhythem", "rhythm", - "rhythim", "rhythm", - "rhytmic", "rhythmic", - "riaders", "raiders", - "ritlain", "ritalin", - "ritoers", "rioters", - "rivarly", "rivalry", - "rivlary", "rivalry", - "roahces", "roaches", - "robotis", "robotics", - "rococco", "rococo", - "roestta", "rosetta", - "roiters", "rioters", - "roleply", "roleplay", - "romaina", "romania", - "romaing", "roaming", - "romanin", "romanian", - "romanna", "romanian", - "roomate", "roommate", - "rotuers", "routers", - "rugters", "rutgers", - "rulebok", "rulebook", - "rumorus", "rumours", - "rumuors", "rumours", - "runnung", "running", - "ruslted", "rustled", - "russina", "russian", - "russion", "russian", - "rusteld", "rustled", - "rythmic", "rhythmic", - "rythyms", "rhythms", - "sacrasm", "sarcasm", - "saddnes", "saddens", - "sadistc", "sadistic", - "sadning", "sanding", - "salaris", "salaries", - "salavge", "salvage", - "salvery", "slavery", - "salying", "slaying", - "sampels", "samples", - "samruai", "samurai", - "samuari", "samurai", - "samuria", "samurai", - "sandlas", "sandals", - "sandnig", "sanding", - "sanlder", "sandler", - "santorm", "santorum", - "sapphie", "sapphire", - "sarcams", "sarcasm", - "sargant", "sergeant", - "sasuage", "sausage", - "satifsy", "satisfy", - "satsify", "satisfy", - "satsohi", "satoshi", - "savanha", "savannah", - "savannh", "savannah", - "saveing", "saving", - "sawnsea", "swansea", - "sawnson", "swanson", - "scandas", "scandals", - "scannig", "scanning", - "scartch", "scratch", - "scheems", "schemes", - "schoold", "schooled", - "sciense", "sciences", - "scinece", "science", - "scootes", "scooters", - "scorpin", "scorpion", - "scpeter", "scepter", - "scracth", "scratch", - "scrambe", "scramble", - "scritps", "scripts", - "scrolld", "scrolled", - "scrpits", "scripts", - "scyhter", "scyther", - "seached", "searched", - "seaches", "searches", - "seahaws", "seahawks", - "seantor", "senator", - "searchd", "searched", - "searchs", "searches", - "sebrian", "serbian", - "secerts", "secrets", - "secpter", "scepter", - "secrest", "secrets", - "secrety", "secretly", - "seflies", "selfies", - "seguoys", "segues", - "seinors", "seniors", - "selifes", "selfies", - "senoirs", "seniors", - "sensure", "censure", - "sentaor", "senator", - "sentris", "sentries", - "serbain", "serbian", - "sergeat", "sergeant", - "sergent", "sergeant", - "seriban", "serbian", - "servans", "servants", - "sesnors", "sensors", - "settins", "settings", - "severly", "severely", - "sexualy", "sexually", - "seziure", "seizure", - "shaddow", "shadow", - "shanghi", "shanghai", - "shaprie", "sharpie", - "shaprly", "sharply", - "sharipe", "sharpie", - "shcemes", "schemes", - "sheelpe", "sheeple", - "sheepel", "sheeple", - "shephed", "shepherd", - "sherlok", "sherlock", - "shetler", "shelter", - "shevles", "shelves", - "shfiter", "shifter", - "shieldd", "shielded", - "shiping", "shipping", - "shirely", "shirley", - "shitfer", "shifter", - "shledon", "sheldon", - "shleter", "shelter", - "shoudln", "should", - "shouldt", "shouldnt", - "shoutot", "shoutout", - "showede", "showered", - "showerd", "showered", - "shperes", "spheres", - "shriley", "shirley", - "siblins", "siblings", - "sidelen", "sideline", - "sideral", "sidereal", - "siezing", "seizing", - "siezure", "seizure", - "signfiy", "signify", - "signins", "signings", - "signles", "singles", - "silders", "sliders", - "silenty", "silently", - "similir", "similar", - "simliar", "similar", - "simplet", "simplest", - "simpley", "simply", - "simplfy", "simplify", - "simpliy", "simplify", - "simposn", "simpson", - "simspon", "simpson", - "singals", "signals", - "singels", "singles", - "singify", "signify", - "singsog", "singsong", - "sitmuli", "stimuli", - "skecthy", "sketchy", - "skeletl", "skeletal", - "skeptis", "skeptics", - "sketchs", "sketches", - "sketpic", "skeptic", - "skpetic", "skeptic", - "sktechy", "sketchy", - "skwyard", "skyward", - "slavage", "salvage", - "slayign", "slaying", - "sldiers", "sliders", - "slefies", "selfies", - "slighly", "slightly", - "slighty", "slightly", - "slippes", "slippers", - "slippey", "slippery", - "smaples", "samples", - "smartre", "smarter", - "smaurai", "samurai", - "snadler", "sandler", - "snigles", "singles", - "snippes", "snippets", - "snodwen", "snowden", - "snwoden", "snowden", - "snycing", "syncing", - "snyergy", "synergy", - "socialy", "socially", - "sofware", "software", - "soildly", "solidly", - "soldies", "soldiers", - "soldily", "solidly", - "somaila", "somalia", - "someons", "someones", - "somethn", "somethin", - "southen", "southern", - "soveits", "soviets", - "spacebr", "spacebar", - "spainsh", "spanish", - "spansih", "spanish", - "spanwed", "spawned", - "sparkel", "sparkle", - "spartas", "spartans", - "spartsn", "spartans", - "sparyed", "sprayed", - "spawend", "spawned", - "spawnig", "spawning", - "specail", "special", - "specfic", "specific", - "specias", "specials", - "specisl", "specials", - "spectum", "spectrum", - "speechs", "speeches", - "spehres", "spheres", - "speical", "special", - "speices", "species", - "spellig", "spelling", - "spindel", "spindle", - "spiritd", "spirited", - "splaton", "splatoon", - "splittr", "splitter", - "spoiles", "spoilers", - "spoitfy", "spotify", - "spolied", "spoiled", - "sponser", "sponsor", - "sporles", "sproles", - "sporuts", "sprouts", - "spotfiy", "spotify", - "sprinke", "sprinkle", - "sproels", "sproles", - "spwaned", "spawned", - "sqaures", "squares", - "sqeuaky", "squeaky", - "sqiushy", "squishy", - "squarey", "squarely", - "squirel", "squirtle", - "squirle", "squirrel", - "squirrl", "squirrel", - "squirte", "squirtle", - "squsihy", "squishy", - "sriraca", "sriracha", - "srpouts", "sprouts", - "sryians", "syrians", - "sryinge", "syringe", - "stadius", "stadiums", - "staduim", "stadium", - "stagnat", "stagnant", - "staidum", "stadium", - "stakler", "stalker", - "stalkes", "stalkers", - "stamnia", "stamina", - "staoshi", "satoshi", - "starins", "strains", - "startde", "startled", - "startus", "startups", - "statits", "statist", - "statsit", "statist", - "statuer", "stature", - "statuse", "statutes", - "statuts", "statutes", - "stautes", "statues", - "stealty", "stealthy", - "steeles", "steelers", - "steorid", "steroid", - "steriel", "sterile", - "sterlie", "sterile", - "stickes", "stickers", - "stiring", "stirring", - "stirker", "striker", - "stirrig", "stirring", - "stitchs", "stitches", - "stlaker", "stalker", - "stlyish", "stylish", - "storeis", "stories", - "storise", "stories", - "stormde", "stormed", - "straigt", "straight", - "straind", "strained", - "streamd", "streamed", - "stregth", "strength", - "strengh", "strength", - "streoid", "steroid", - "stresss", "stresses", - "strians", "strains", - "stricty", "strictly", - "striekr", "striker", - "stromed", "stormed", - "stubbon", "stubborn", - "studing", "studying", - "stuidos", "studios", - "stunami", "tsunami", - "stupidr", "stupider", - "stupidy", "stupidly", - "stupire", "stupider", - "suasage", "sausage", - "subisdy", "subsidy", - "subjest", "subjects", - "subtiel", "subtitle", - "succede", "succeed", - "succeds", "succeeds", - "succees", "succeeds", - "succesd", "succeeds", - "suceeds", "succeeds", - "suddeny", "suddenly", - "suefull", "useful", - "sufferd", "suffered", - "summonr", "summoner", - "summore", "summoner", - "sunggle", "snuggle", - "sunifre", "sunfire", - "superme", "supreme", - "suposed", "supposed", - "suposes", "supposes", - "suppoed", "supposed", - "suppost", "supports", - "suprass", "surpass", - "supress", "suppress", - "suprisd", "surprised", - "suprise", "surprise", - "suprize", "surprise", - "supsend", "suspend", - "suround", "surround", - "surpeme", "supreme", - "surroud", "surround", - "sweidsh", "swedish", - "swiflty", "swiftly", - "swiming", "swimming", - "switchs", "switches", - "switfly", "swiftly", - "swnasea", "swansea", - "sycning", "syncing", - "sycther", "scyther", - "syirans", "syrians", - "sykward", "skyward", - "syllabe", "syllable", - "symetry", "symmetry", - "symmety", "symmetry", - "symobls", "symbols", - "sympaty", "sympathy", - "symtpom", "symptom", - "synegry", "synergy", - "synoynm", "synonym", - "sypmtom", "symptom", - "syracue", "syracuse", - "syrains", "syrians", - "sysadmn", "sysadmin", - "systemc", "systemic", - "sytlish", "stylish", - "tabacco", "tobacco", - "tailban", "taliban", - "tailord", "tailored", - "talbian", "taliban", - "tallets", "tallest", - "tangeld", "tangled", - "tanlged", "tangled", - "targetd", "targeted", - "taryvon", "trayvon", - "teached", "taught", - "teaspon", "teaspoon", - "techeis", "techies", - "tehcies", "techies", - "temepst", "tempest", - "tempels", "temples", - "tempets", "tempest", - "templas", "templars", - "tempset", "tempest", - "tenacle", "tentacle", - "tendacy", "tendency", - "tequlia", "tequila", - "tesitfy", "testify", - "testice", "testicle", - "teusday", "tuesday", - "thankyu", "thankyou", - "thearpy", "therapy", - "theistc", "theistic", - "theives", "thieves", - "themsef", "themself", - "therefo", "thereof", - "therien", "therein", - "theroem", "theorem", - "thesits", "theists", - "thiests", "theists", - "thirldy", "thirdly", - "thirten", "thirteen", - "thirtsy", "thirsty", - "thoerem", "theorem", - "thorats", "throats", - "thornes", "thrones", - "thoruim", "thorium", - "thoughs", "thoughts", - "threadd", "threaded", - "threeof", "thereof", - "thridly", "thirdly", - "thristy", "thirsty", - "throast", "throats", - "throium", "thorium", - "thryoid", "thyroid", - "thyorid", "thyroid", - "thyriod", "thyroid", - "tigther", "tighter", - "tiolets", "toilets", - "tirdent", "trident", - "titanim", "titanium", - "tlaking", "talking", - "tobbaco", "tobacco", - "toliets", "toilets", - "tolkein", "tolkien", - "tomatos", "tomatoes", - "tongiht", "tonight", - "tonuges", "tongues", - "toppins", "toppings", - "torando", "tornado", - "torndao", "tornado", - "torpdeo", "torpedo", - "torrest", "torrents", - "tortila", "tortilla", - "toruney", "tourney", - "toubles", "troubles", - "touchda", "touchpad", - "tounrey", "tourney", - "tourisy", "touristy", - "tourits", "tourist", - "tournes", "tourneys", - "toursim", "tourism", - "toursit", "tourist", - "towords", "towards", - "trackes", "trackers", - "trailes", "trailers", - "traines", "trainers", - "trainig", "training", - "tralier", "trailer", - "tratior", "traitor", - "traveld", "traveled", - "travere", "traverse", - "travesy", "travesty", - "travles", "travels", - "treasue", "treasure", - "treatis", "treaties", - "tremelo", "tremolo", - "trendig", "trending", - "trialer", "trailer", - "triange", "triangle", - "triator", "traitor", - "trickey", "trickery", - "tridnet", "trident", - "trimuph", "triumph", - "trinkes", "trinkets", - "trinkst", "trinkets", - "trintiy", "trinity", - "triolgy", "trilogy", - "troleld", "trolled", - "troling", "trolling", - "tronado", "tornado", - "tropedo", "torpedo", - "trudnle", "trundle", - "truimph", "triumph", - "trukish", "turkish", - "trundel", "trundle", - "trunlde", "trundle", - "tryahrd", "tryhard", - "tryavon", "trayvon", - "tsamina", "stamina", - "tsnuami", "tsunami", - "tsuanmi", "tsunami", - "tsunmai", "tsunami", - "tuesdsy", "tuesdays", - "tunnles", "tunnels", - "turbins", "turbines", - "turksih", "turkish", - "turltes", "turtles", - "turrest", "turrets", - "turtels", "turtles", - "tuseday", "tuesday", - "tusnami", "tsunami", - "tutrles", "turtles", - "twiligt", "twilight", - "tyelnol", "tylenol", - "typcial", "typical", - "tyrhard", "tryhard", - "tyrrany", "tyranny", - "udpated", "updated", - "uesfull", "useful", - "ugprade", "upgrade", - "ukarine", "ukraine", - "ukranie", "ukraine", - "ukriane", "ukraine", - "ultimae", "ultimate", - "umbrela", "umbrella", - "unahppy", "unhappy", - "unbannd", "unbanned", - "underog", "undergo", - "unfairy", "unfairly", - "ungoldy", "ungodly", - "unicors", "unicorns", - "uniquey", "uniquely", - "unknwon", "unknown", - "unkonwn", "unknown", - "unlcean", "unclean", - "unlcoks", "unlocks", - "unlcuky", "unlucky", - "unlikey", "unlikely", - "unopend", "unopened", - "unprone", "unproven", - "unusabe", "unusable", - "unworty", "unworthy", - "upgarde", "upgrade", - "upgrads", "upgrades", - "uplaods", "uploads", - "upsteam", "upstream", - "urainum", "uranium", - "uranuim", "uranium", - "uretrha", "urethra", - "urkaine", "ukraine", - "urnaium", "uranium", - "urugauy", "uruguay", - "usefull", "useful", - "usefuly", "usefully", - "utiltiy", "utility", - "utopain", "utopian", - "utpoian", "utopian", - "vaccins", "vaccines", - "vaccume", "vacuum", - "vageuly", "vaguely", - "vaguley", "vaguely", - "vairant", "variant", - "valenca", "valencia", - "valetta", "valletta", - "valkyre", "valkyrie", - "valuabe", "valuable", - "valuble", "valuable", - "vampirs", "vampires", - "vanguad", "vanguard", - "varaint", "variant", - "vareity", "variety", - "varians", "variants", - "varient", "variant", - "varisty", "varsity", - "varitey", "variety", - "varstiy", "varsity", - "vasalls", "vassals", - "vasslas", "vassals", - "vaugely", "vaguely", - "vecotrs", "vectors", - "vectros", "vectors", - "veitnam", "vietnam", - "veiwers", "viewers", - "vendeta", "vendetta", - "verbaly", "verbally", - "verical", "vertical", - "verious", "various", - "verison", "version", - "veritgo", "vertigo", - "versoin", "version", - "vertgio", "vertigo", - "vessles", "vessels", - "vetween", "between", - "viatmin", "vitamin", - "vibratr", "vibrator", - "vicitms", "victims", - "vientam", "vietnam", - "vigrins", "virgins", - "vikigns", "vikings", - "villian", "villain", - "villify", "vilify", - "virbate", "vibrate", - "virigns", "virgins", - "virtiol", "vitriol", - "virutal", "virtual", - "virutes", "virtues", - "visable", "visible", - "visably", "visibly", - "visbily", "visibly", - "visting", "visiting", - "vistors", "visitors", - "vitaliy", "vitality", - "vitamis", "vitamins", - "vitenam", "vietnam", - "vitirol", "vitriol", - "vitmain", "vitamin", - "vitroil", "vitriol", - "vitrual", "virtual", - "vitrues", "virtues", - "volatge", "voltage", - "volumne", "volume", - "votlage", "voltage", - "vrigins", "virgins", - "waclott", "walcott", - "wacther", "watcher", - "waitres", "waiters", - "waktins", "watkins", - "warcrat", "warcraft", - "wardobe", "wardrobe", - "wariwck", "warwick", - "warrany", "warranty", - "warrent", "warrant", - "warrios", "warriors", - "warwcik", "warwick", - "wathcer", "watcher", - "watiers", "waiters", - "waviers", "waivers", - "wawrick", "warwick", - "wayword", "wayward", - "webapge", "webpage", - "webiste", "website", - "webstie", "website", - "weigths", "weights", - "weilded", "wielded", - "weirldy", "weirdly", - "weirods", "weirdos", - "welathy", "wealthy", - "wendsay", "wednesday", - "wensday", "wednesday", - "wepbage", "webpage", - "weridly", "weirdly", - "weridos", "weirdos", - "werstle", "wrestle", - "wesbite", "website", - "whaeton", "wheaton", - "whipser", "whisper", - "whislte", "whistle", - "whistel", "whistle", - "whitsle", "whistle", - "whsiper", "whisper", - "wiaters", "waiters", - "wiavers", "waivers", - "widgest", "widgets", - "wieghts", "weights", - "wigdets", "widgets", - "windosr", "windsor", - "winnins", "winnings", - "winsdor", "windsor", - "wintson", "winston", - "wirting", "writing", - "wisnton", "winston", - "withces", "witches", - "witheld", "withheld", - "withing", "within", - "withold", "withhold", - "wlacott", "walcott", - "wokring", "working", - "workins", "workings", - "woudlnt", "wouldnt", - "woudlve", "wouldve", - "woulndt", "wouldnt", - "wreslte", "wrestle", - "wroking", "working", - "wtiches", "witches", - "wupport", "support", - "yaching", "yachting", - "younget", "youngest", - "youseff", "yousef", - "youself", "yourself", - "zaelots", "zealots", - "zealtos", "zealots", - "zelaots", "zealots", - "zelaous", "zealous", - "zimbabe", "zimbabwe", - "zionsim", "zionism", - "zionsit", "zionist", - "zoinism", "zionism", - "zoinist", "zionist", - "abbout", "about", - "abilty", "ability", - "absail", "abseil", - "abutts", "abuts", - "achive", "achieve", - "acused", "accused", - "addopt", "adopt", - "addres", "address", - "adress", "address", - "aeriel", "aerial", - "affort", "afford", - "agains", "against", - "aginst", "against", - "ahppen", "happen", - "aiport", "airport", - "aisian", "asian", - "albiet", "albeit", - "alchol", "alcohol", - "aledge", "allege", - "aleged", "alleged", - "allign", "align", - "almsot", "almost", - "alomst", "almost", - "alowed", "allowed", - "alwasy", "always", - "alwyas", "always", - "amking", "making", - "ammend", "amend", - "amoung", "among", - "aplied", "applied", - "appart", "apart", - "aquire", "acquire", - "arcive", "archive", - "aready", "already", - "arised", "arose", - "arival", "arrival", - "arrary", "array", - "artice", "article", - "asetic", "ascetic", - "asside", "aside", - "attemp", "attempt", - "attemt", "attempt", - "auther", "author", - "awared", "awarded", - "bedore", "before", - "beeing", "being", - "befoer", "before", - "beggin", "begin", - "beleif", "belief", - "belive", "believe", - "beteen", "between", - "betwen", "between", - "beween", "between", - "bianry", "binary", - "boyant", "buoyant", - "broady", "broadly", - "buddah", "buddha", - "buring", "burying", - "carcas", "carcass", - "casion", "caisson", - "casued", "caused", - "casues", "causes", - "ceasar", "caesar", - "cencus", "census", - "censur", "censor", - "cheifs", "chiefs", - "circut", "circuit", - "clasic", "classic", - "coform", "conform", - "comany", "company", - "coucil", "council", - "curent", "current", - "densly", "densely", - "deside", "decide", - "devels", "delves", - "devide", "divide", - "dieing", "dying", - "divice", "device", - "doulbe", "double", - "dreasm", "dreams", - "duting", "during", - "ealier", "earlier", - "eearly", "early", - "efford", "effort", - "emited", "emitted", - "emnity", "enmity", - "enduce", "induce", - "enlish", "english", - "erally", "orally", - "eratic", "erratic", - "ethose", "those", - "exampt", "exempt", - "excact", "exact", - "excell", "excel", - "exerpt", "excerpt", - "exinct", "extinct", - "expell", "expel", - "expoch", "epoch", - "extint", "extinct", - "facist", "fascist", - "faught", "fought", - "finaly", "finally", - "forsaw", "foresaw", - "fougth", "fought", - "fourty", "forty", - "foward", "forward", - "freind", "friend", - "fromed", "formed", - "fufill", "fulfill", - "futher", "further", - "gardai", "gardaí", - "geting", "getting", - "ghandi", "gandhi", - "glight", "flight", - "gloabl", "global", - "godess", "goddess", - "guilia", "giulia", - "guilio", "giulio", - "habeus", "habeas", - "harras", "harass", - "hatian", "haitian", - "heared", "heard", - "hertzs", "hertz", - "hieght", "height", - "higest", "highest", - "higway", "highway", - "honory", "honorary", - "howver", "however", - "hstory", "history", - "hunman", "human", - "husban", "husband", - "hvaing", "having", - "illess", "illness", - "ilness", "illness", - "imagin", "imagine", - "imense", "immense", - "includ", "include", - "inital", "initial", - "interm", "interim", - "intial", "initial", - "invlid", "invalid", - "iunior", "junior", - "jaques", "jacques", - "jospeh", "joseph", - "jouney", "journey", - "klenex", "kleenex", - "labled", "labelled", - "largst", "largest", - "larrry", "larry", - "lefted", "left", - "lenght", "length", - "lerans", "learns", - "liason", "liaison", - "libary", "library", - "lieing", "lying", - "lieved", "lived", - "littel", "little", - "livley", "lively", - "lonley", "lonely", - "mailny", "mainly", - "markes", "marks", - "mileau", "milieu", - "milion", "million", - "millon", "million", - "misile", "missile", - "missen", "mizzen", - "missle", "missile", - "mkaing", "making", - "moderm", "modem", - "moreso", "more", - "mounth", "month", - "myraid", "myriad", - "naieve", "naive", - "nestin", "nesting", - "nineth", "ninth", - "noveau", "nouveau", - "occour", "occur", - "occurr", "occur", - "offred", "offered", - "omited", "omitted", - "ouevre", "oeuvre", - "oxigen", "oxygen", - "p0enis", "penis", - "packge", "package", - "peaple", "people", - "pensle", "pencil", - "peopel", "people", - "peotry", "poetry", - "perade", "parade", - "persan", "person", - "persue", "pursue", - "plateu", "plateau", - "poenis", "penis", - "poisin", "poison", - "polute", "pollute", - "posess", "possess", - "posion", "poison", - "prairy", "prairie", - "prarie", "prairie", - "preiod", "period", - "privte", "private", - "proces", "process", - "proove", "prove", - "psuedo", "pseudo", - "psyhic", "psychic", - "pucini", "puccini", - "pumkin", "pumpkin", - "puting", "putting", - "pyscic", "psychic", - "quizes", "quizzes", - "quuery", "query", - "racaus", "raucous", - "radify", "ratify", - "raelly", "really", - "reacll", "recall", - "realyl", "really", - "reched", "reached", - "recide", "reside", - "recrod", "record", - "refect", "reflect", - "relaly", "really", - "renewl", "renewal", - "retuns", "returns", - "reveiw", "review", - "rhymme", "rhyme", - "rigeur", "rigueur", - "rocord", "record", - "rougly", "roughly", - "runing", "running", - "rythem", "rhythm", - "rythim", "rhythm", - "saftey", "safety", - "salery", "salary", - "satisy", "satisfy", - "satric", "satiric", - "saught", "sought", - "scince", "science", - "scirpt", "script", - "seceed", "succeed", - "seinor", "senior", - "sepina", "subpoena", - "sevice", "service", - "shamen", "shaman", - "sheild", "shield", - "shiped", "shipped", - "shorly", "shortly", - "shoudl", "should", - "shreak", "shriek", - "siezed", "seized", - "sixtin", "sistine", - "skiped", "skipped", - "sneeks", "sneaks", - "somene", "someone", - "soruce", "source", - "soudns", "sounds", - "sourth", "south", - "speach", "speech", - "spects", "aspects", - "spoace", "space", - "sqaure", "square", - "staion", "station", - "stange", "strange", - "stilus", "stylus", - "stirrs", "stirs", - "stopry", "story", - "strnad", "strand", - "studdy", "study", - "suceed", "succeed", - "sucess", "success", - "sucide", "suicide", - "sumary", "summary", - "suport", "support", - "supose", "suppose", - "surfce", "surface", - "surley", "surly", - "swaers", "swears", - "swepth", "swept", - "talekd", "talked", - "theese", "these", - "therby", "thereby", - "thigns", "things", - "thigsn", "things", - "thikns", "thinks", - "thiunk", "think", - "thnigs", "things", - "threee", "three", - "tkaing", "taking", - "tounge", "tongue", - "tourch", "torch", - "towrad", "toward", - "trafic", "traffic", - "troups", "troupes", - "truely", "truly", - "twelth", "twelfth", - "tyrany", "tyranny", - "unabel", "unable", - "unkown", "unknown", - "unmont", "unmount", - "unmout", "unmount", - "untill", "until", - "usally", "usually", - "useage", "usage", - "useing", "using", - "usualy", "usually", - "vaccum", "vacuum", - "variey", "variety", - "varing", "varying", - "varity", "variety", - "vasall", "vassal", - "vigeur", "vigueur", - "villin", "villain", - "vreity", "variety", - "vriety", "variety", - "whants", "wants", - "wheras", "whereas", - "wheter", "whether", - "wholey", "wholly", - "whther", "whether", - "wnated", "wanted", - "writen", "written", - "yaerly", "yearly", - "yotube", "youtube", - "zeebra", "zebra", - "abotu", "about", - "adres", "address", - "afair", "affair", - "agian", "again", - "agina", "again", - "agred", "agreed", - "alege", "allege", - "alsot", "also", - "altho", "although", - "amung", "among", - "anual", "annual", - "aroud", "around", - "arund", "around", - "asign", "assign", - "assit", "assist", - "asume", "assume", - "atain", "attain", - "autor", "author", - "baout", "about", - "blaim", "blame", - "boaut", "bout", - "boook", "book", - "borke", "broke", - "breif", "brief", - "caost", "coast", - "casue", "cause", - "chasr", "chaser", - "cheif", "chief", - "chuch", "church", - "claer", "clear", - "clera", "clear", - "coudl", "could", - "crowm", "crown", - "deram", "dram", - "diety", "deity", - "doens", "does", - "doign", "doing", - "donig", "doing", - "drnik", "drink", - "durig", "during", - "earnt", "earned", - "eigth", "eighth", - "eiter", "either", - "emtpy", "empty", - "endig", "ending", - "eveyr", "every", - "exept", "except", - "eyars", "years", - "eyasr", "years", - "fiels", "fields", - "firts", "flirts", - "fleed", "fled", - "fomed", "formed", - "foucs", "focus", - "foudn", "found", - "fouth", "fourth", - "frome", "from", - "ganes", "games", - "gaurd", "guard", - "gerat", "great", - "gogin", "going", - "goign", "going", - "gonig", "going", - "graet", "great", - "greif", "grief", - "gropu", "group", - "guage", "gauge", - "hapen", "happen", - "herad", "heard", - "heroe", "hero", - "higer", "higher", - "housr", "hours", - "htere", "there", - "htikn", "think", - "hting", "thing", - "htink", "think", - "hwihc", "which", - "hwile", "while", - "hwole", "whole", - "idaes", "ideas", - "idesa", "ideas", - "ihaca", "ithaca", - "knwos", "knows", - "konws", "knows", - "lastr", "last", - "lavae", "larvae", - "layed", "laid", - "leage", "league", - "leanr", "lean", - "leran", "learn", - "levle", "level", - "lible", "libel", - "liekd", "liked", - "liuke", "like", - "lmits", "limits", - "lonly", "lonely", - "lukid", "likud", - "lybia", "libya", - "maked", "marked", - "makse", "makes", - "mamal", "mammal", - "mileu", "milieu", - "mkaes", "makes", - "modle", "model", - "moent", "moment", - "moeny", "money", - "monts", "months", - "movei", "movie", - "muder", "murder", - "mysef", "myself", - "neice", "niece", - "ninty", "ninety", - "ocurr", "occur", - "oging", "going", - "opose", "oppose", - "orded", "ordered", - "orgin", "origin", - "otehr", "other", - "ouput", "output", - "owudl", "would", - "paide", "paid", - "palce", "place", - "pased", "passed", - "payed", "paid", - "peice", "piece", - "peoms", "poems", - "poety", "poetry", - "pwoer", "power", - "qtuie", "quite", - "qutie", "quite", - "realy", "really", - "repid", "rapid", - "rised", "raised", - "rulle", "rule", - "rwite", "write", - "rythm", "rhythm", - "safty", "safety", - "scoll", "scroll", - "seach", "search", - "seige", "siege", - "seing", "seeing", - "sence", "sense", - "sicne", "since", - "sieze", "seize", - "sinse", "sines", - "slowy", "slowly", - "snese", "sneeze", - "soley", "solely", - "sotry", "story", - "sotyr", "satyr", - "soudn", "sound", - "sould", "could", - "spred", "spread", - "stlye", "style", - "stong", "strong", - "stoyr", "story", - "strat", "start", - "stroy", "story", - "suppy", "supply", - "swaer", "swear", - "syrap", "syrup", - "sytem", "system", - "sytle", "style", - "tatoo", "tattoo", - "thast", "that", - "theif", "thief", - "theri", "their", - "thgat", "that", - "thier", "their", - "thign", "thing", - "thikn", "think", - "thnig", "thing", - "thrid", "third", - "thsoe", "those", - "thyat", "that", - "tihkn", "think", - "timne", "time", - "tiome", "time", - "tkaes", "takes", - "todya", "today", - "tyhat", "that", - "unsed", "used", - "weild", "wield", - "whant", "want", - "whcih", "which", - "whihc", "which", - "whith", "with", - "whlch", "which", - "wholy", "wholly", - "wierd", "weird", - "wille", "will", - "willk", "will", - "withh", "with", - "witht", "with", - "wiull", "will", - "wnats", "wants", - "wohle", "whole", - "worls", "world", - "woudl", "would", - "wriet", "write", - "wroet", "wrote", - "yaers", "years", - "yatch", "yacht", - "yearm", "year", - "yeasr", "years", - "yeild", "yield", - "yeras", "years", - "yersa", "years", - "agin", "again", - "agre", "agree", - "ahev", "have", - "ahve", "have", - "alse", "else", - "amke", "make", - "anbd", "and", - "andd", "and", - "apon", "upon", - "aslo", "also", - "awya", "away", - "bakc", "back", - "bcak", "back", - "clas", "class", - "cpoy", "coy", - "cxan", "cyan", - "daed", "dead", - "dael", "deal", - "diea", "idea", - "doub", "doubt", - "dyas", "dryas", - "eahc", "each", - "efel", "evil", - "eles", "eels", - "ened", "need", - "enxt", "next", - "esle", "else", - "eyar", "year", - "fatc", "fact", - "fidn", "find", - "fomr", "from", - "grwo", "grow", - "haev", "have", - "halp", "help", - "holf", "hold", - "hten", "then", - "htey", "they", - "htis", "this", - "hvae", "have", - "hvea", "have", - "inot", "into", - "iwll", "will", - "iwth", "with", - "jstu", "just", - "jsut", "just", - "knwo", "know", - "konw", "know", - "kwno", "know", - "liek", "like", - "loev", "love", - "lveo", "love", - "lvoe", "love", - "mkae", "make", - "mkea", "make", - "mroe", "more", - "nkow", "know", - "nkwo", "know", - "nmae", "name", - "noth", "north", - "nowe", "now", - "omre", "more", - "onlu", "only", - "onot", "note", - "onyl", "only", - "owrk", "work", - "peom", "poem", - "pich", "pitch", - "rela", "real", - "sasy", "says", - "smae", "same", - "smoe", "some", - "soem", "some", - "sohw", "show", - "stpo", "stop", - "suop", "soup", - "syas", "says", - "tahn", "than", - "taht", "that", - "tast", "taste", - "tath", "that", - "tehy", "they", - "tghe", "the", - "ther", "there", - "thge", "the", - "thna", "than", - "thne", "then", - "thsi", "this", - "thta", "that", - "tiem", "time", - "tihs", "this", - "tjhe", "the", - "tkae", "take", - "tood", "todo", - "tust", "trust", - "twon", "town", - "twpo", "two", - "tyhe", "they", - "uise", "use", - "vell", "well", - "veyr", "very", - "vrey", "very", - "vyer", "very", - "vyre", "very", - "waht", "what", - "wass", "was", - "watn", "want", - "weas", "was", - "wehn", "when", - "whic", "which", - "whta", "what", - "wich", "which", - "wief", "wife", - "wiew", "view", - "wiht", "with", - "witn", "with", - "wnat", "want", - "wokr", "work", - "wrok", "work", - "wtih", "with", - "yaer", "year", - "yera", "year", - "yrea", "year", - "ytou", "you", - "adn", "and", - "ect", "etc", - "nto", "not", - "teh", "the", - "thn", "then", - "tje", "the", - "whn", "when", - "wih", "with", - "yuo", "you", -} diff --git a/vendor/github.com/golangci/misspell/words_uk.go b/vendor/github.com/golangci/misspell/words_uk.go deleted file mode 100644 index 01ae087029..0000000000 --- a/vendor/github.com/golangci/misspell/words_uk.go +++ /dev/null @@ -1,1484 +0,0 @@ -// Code generated by 'internal/gen'. DO NOT EDIT. - -package misspell - -// DictBritish converts US spellings to UK spellings -var DictBritish = []string{ - "institutionalization", "institutionalisation", - "internationalization", "internationalisation", - "professionalization", "professionalisation", - "compartmentalizing", "compartmentalising", - "institutionalizing", "institutionalising", - "internationalizing", "internationalising", - "compartmentalized", "compartmentalised", - "compartmentalizes", "compartmentalises", - "decriminalization", "decriminalisation", - "denationalization", "denationalisation", - "fictionalizations", "fictionalisations", - "institutionalized", "institutionalised", - "institutionalizes", "institutionalises", - "intellectualizing", "intellectualising", - "internationalized", "internationalised", - "internationalizes", "internationalises", - "pedestrianization", "pedestrianisation", - "professionalizing", "professionalising", - "compartmentalize", "compartmentalise", - "decentralization", "decentralisation", - "demilitarization", "demilitarisation", - "externalizations", "externalisations", - "fictionalization", "fictionalisation", - "institutionalize", "institutionalise", - "intellectualized", "intellectualised", - "intellectualizes", "intellectualises", - "internationalize", "internationalise", - "nationalizations", "nationalisations", - "professionalized", "professionalised", - "professionalizes", "professionalises", - "rationalizations", "rationalisations", - "sensationalizing", "sensationalising", - "sentimentalizing", "sentimentalising", - "acclimatization", "acclimatisation", - "commercializing", "commercialising", - "conceptualizing", "conceptualising", - "contextualizing", "contextualising", - "crystallization", "crystallisation", - "decriminalizing", "decriminalising", - "democratization", "democratisation", - "denationalizing", "denationalising", - "depersonalizing", "depersonalising", - "desensitization", "desensitisation", - "disorganization", "disorganisation", - "extemporization", "extemporisation", - "externalization", "externalisation", - "familiarization", "familiarisation", - "generalizations", "generalisations", - "hospitalization", "hospitalisation", - "individualizing", "individualising", - "industrializing", "industrialising", - "intellectualize", "intellectualise", - "internalization", "internalisation", - "maneuverability", "manoeuvrability", - "materialization", "materialisation", - "miniaturization", "miniaturisation", - "nationalization", "nationalisation", - "overemphasizing", "overemphasising", - "paleontologists", "palaeontologists", - "particularizing", "particularising", - "pedestrianizing", "pedestrianising", - "professionalize", "professionalise", - "psychoanalyzing", "psychoanalysing", - "rationalization", "rationalisation", - "reorganizations", "reorganisations", - "revolutionizing", "revolutionising", - "sensationalized", "sensationalised", - "sensationalizes", "sensationalises", - "sentimentalized", "sentimentalised", - "sentimentalizes", "sentimentalises", - "specializations", "specialisations", - "standardization", "standardisation", - "synchronization", "synchronisation", - "systematization", "systematisation", - "aggrandizement", "aggrandisement", - "characterizing", "characterising", - "collectivizing", "collectivising", - "commercialized", "commercialised", - "commercializes", "commercialises", - "conceptualized", "conceptualised", - "conceptualizes", "conceptualises", - "contextualized", "contextualised", - "contextualizes", "contextualises", - "decentralizing", "decentralising", - "decriminalized", "decriminalised", - "decriminalizes", "decriminalises", - "dehumanization", "dehumanisation", - "demilitarizing", "demilitarising", - "demobilization", "demobilisation", - "demoralization", "demoralisation", - "denationalized", "denationalised", - "denationalizes", "denationalises", - "depersonalized", "depersonalised", - "depersonalizes", "depersonalises", - "dramatizations", "dramatisations", - "editorializing", "editorialising", - "fictionalizing", "fictionalising", - "fraternization", "fraternisation", - "generalization", "generalisation", - "immobilization", "immobilisation", - "individualized", "individualised", - "individualizes", "individualises", - "industrialized", "industrialised", - "industrializes", "industrialises", - "liberalization", "liberalisation", - "monopolization", "monopolisation", - "naturalization", "naturalisation", - "neighborliness", "neighbourliness", - "neutralization", "neutralisation", - "organizational", "organisational", - "outmaneuvering", "outmanoeuvring", - "overemphasized", "overemphasised", - "overemphasizes", "overemphasises", - "paleontologist", "palaeontologist", - "particularized", "particularised", - "particularizes", "particularises", - "pasteurization", "pasteurisation", - "pedestrianized", "pedestrianised", - "pedestrianizes", "pedestrianises", - "philosophizing", "philosophising", - "politicization", "politicisation", - "popularization", "popularisation", - "pressurization", "pressurisation", - "prioritization", "prioritisation", - "privatizations", "privatisations", - "propagandizing", "propagandising", - "psychoanalyzed", "psychoanalysed", - "psychoanalyzes", "psychoanalyses", - "reconnoitering", "reconnoitring", - "regularization", "regularisation", - "reorganization", "reorganisation", - "revolutionized", "revolutionised", - "revolutionizes", "revolutionises", - "secularization", "secularisation", - "sensationalize", "sensationalise", - "sentimentalize", "sentimentalise", - "serializations", "serialisations", - "specialization", "specialisation", - "sterilizations", "sterilisations", - "stigmatization", "stigmatisation", - "transistorized", "transistorised", - "unrecognizable", "unrecognisable", - "visualizations", "visualisations", - "westernization", "westernisation", - "accessorizing", "accessorising", - "acclimatizing", "acclimatising", - "amortizations", "amortisations", - "amphitheaters", "amphitheatres", - "anesthetizing", "anaesthetising", - "archeologists", "archaeologists", - "breathalyzers", "breathalysers", - "breathalyzing", "breathalysing", - "cannibalizing", "cannibalising", - "characterized", "characterised", - "characterizes", "characterises", - "circularizing", "circularising", - "collectivized", "collectivised", - "collectivizes", "collectivises", - "commercialize", "commercialise", - "computerizing", "computerising", - "conceptualize", "conceptualise", - "contextualize", "contextualise", - "criminalizing", "criminalising", - "crystallizing", "crystallising", - "decentralized", "decentralised", - "decentralizes", "decentralises", - "decriminalize", "decriminalise", - "demilitarized", "demilitarised", - "demilitarizes", "demilitarises", - "democratizing", "democratising", - "denationalize", "denationalise", - "depersonalize", "depersonalise", - "desensitizing", "desensitising", - "destabilizing", "destabilising", - "disemboweling", "disembowelling", - "dramatization", "dramatisation", - "editorialized", "editorialised", - "editorializes", "editorialises", - "extemporizing", "extemporising", - "externalizing", "externalising", - "familiarizing", "familiarising", - "fertilization", "fertilisation", - "fictionalized", "fictionalised", - "fictionalizes", "fictionalises", - "formalization", "formalisation", - "fossilization", "fossilisation", - "globalization", "globalisation", - "gynecological", "gynaecological", - "gynecologists", "gynaecologists", - "harmonization", "harmonisation", - "hematological", "haematological", - "hematologists", "haematologists", - "hospitalizing", "hospitalising", - "hypothesizing", "hypothesising", - "immortalizing", "immortalising", - "individualize", "individualise", - "industrialize", "industrialise", - "internalizing", "internalising", - "marginalizing", "marginalising", - "materializing", "materialising", - "mechanization", "mechanisation", - "memorializing", "memorialising", - "miniaturizing", "miniaturising", - "nationalizing", "nationalising", - "neighborhoods", "neighbourhoods", - "normalization", "normalisation", - "organizations", "organisations", - "outmaneuvered", "outmanoeuvred", - "overemphasize", "overemphasise", - "particularize", "particularise", - "passivization", "passivisation", - "patronizingly", "patronisingly", - "pedestrianize", "pedestrianise", - "pediatricians", "paediatricians", - "personalizing", "personalising", - "philosophized", "philosophised", - "philosophizes", "philosophises", - "privatization", "privatisation", - "propagandized", "propagandised", - "propagandizes", "propagandises", - "proselytizers", "proselytisers", - "proselytizing", "proselytising", - "psychoanalyze", "psychoanalyse", - "pulverization", "pulverisation", - "rationalizing", "rationalising", - "reconnoitered", "reconnoitred", - "revolutionize", "revolutionise", - "romanticizing", "romanticising", - "serialization", "serialisation", - "socialization", "socialisation", - "standardizing", "standardising", - "sterilization", "sterilisation", - "subsidization", "subsidisation", - "synchronizing", "synchronising", - "systematizing", "systematising", - "tantalizingly", "tantalisingly", - "underutilized", "underutilised", - "victimization", "victimisation", - "visualization", "visualisation", - "vocalizations", "vocalisations", - "vulgarization", "vulgarisation", - "accessorized", "accessorised", - "accessorizes", "accessorises", - "acclimatized", "acclimatised", - "acclimatizes", "acclimatises", - "amortization", "amortisation", - "amphitheater", "amphitheatre", - "anesthetists", "anaesthetists", - "anesthetized", "anaesthetised", - "anesthetizes", "anaesthetises", - "antagonizing", "antagonising", - "appetizingly", "appetisingly", - "archeologist", "archaeologist", - "backpedaling", "backpedalling", - "bastardizing", "bastardising", - "behaviorists", "behaviourists", - "bowdlerizing", "bowdlerising", - "breathalyzed", "breathalysed", - "breathalyzes", "breathalyses", - "cannibalized", "cannibalised", - "cannibalizes", "cannibalises", - "capitalizing", "capitalising", - "caramelizing", "caramelising", - "categorizing", "categorising", - "centerpieces", "centrepieces", - "centralizing", "centralising", - "characterize", "characterise", - "circularized", "circularised", - "circularizes", "circularises", - "clarinetists", "clarinettists", - "collectivize", "collectivise", - "colonization", "colonisation", - "computerized", "computerised", - "computerizes", "computerises", - "criminalized", "criminalised", - "criminalizes", "criminalises", - "crystallized", "crystallised", - "crystallizes", "crystallises", - "decentralize", "decentralise", - "dehumanizing", "dehumanising", - "demilitarize", "demilitarise", - "demobilizing", "demobilising", - "democratized", "democratised", - "democratizes", "democratises", - "demoralizing", "demoralising", - "desensitized", "desensitised", - "desensitizes", "desensitises", - "destabilized", "destabilised", - "destabilizes", "destabilises", - "disemboweled", "disembowelled", - "dishonorable", "dishonourable", - "dishonorably", "dishonourably", - "disorganized", "disorganised", - "editorialize", "editorialise", - "equalization", "equalisation", - "evangelizing", "evangelising", - "extemporized", "extemporised", - "extemporizes", "extemporises", - "externalized", "externalised", - "externalizes", "externalises", - "familiarized", "familiarised", - "familiarizes", "familiarises", - "fictionalize", "fictionalise", - "finalization", "finalisation", - "fraternizing", "fraternising", - "generalizing", "generalising", - "gynecologist", "gynaecologist", - "hematologist", "haematologist", - "hemophiliacs", "haemophiliacs", - "hemorrhaging", "haemorrhaging", - "homogenizing", "homogenising", - "hospitalized", "hospitalised", - "hospitalizes", "hospitalises", - "hypothesized", "hypothesised", - "hypothesizes", "hypothesises", - "idealization", "idealisation", - "immobilizers", "immobilisers", - "immobilizing", "immobilising", - "immortalized", "immortalised", - "immortalizes", "immortalises", - "immunization", "immunisation", - "initializing", "initialising", - "installments", "instalments", - "internalized", "internalised", - "internalizes", "internalises", - "jeopardizing", "jeopardising", - "legalization", "legalisation", - "legitimizing", "legitimising", - "liberalizing", "liberalising", - "maneuverable", "manoeuvrable", - "maneuverings", "manoeuvrings", - "marginalized", "marginalised", - "marginalizes", "marginalises", - "materialized", "materialised", - "materializes", "materialises", - "maximization", "maximisation", - "memorialized", "memorialised", - "memorializes", "memorialises", - "metabolizing", "metabolising", - "militarizing", "militarising", - "miniaturized", "miniaturised", - "miniaturizes", "miniaturises", - "miscataloged", "miscatalogued", - "misdemeanors", "misdemeanours", - "mobilization", "mobilisation", - "moisturizers", "moisturisers", - "moisturizing", "moisturising", - "monopolizing", "monopolising", - "multicolored", "multicoloured", - "nationalized", "nationalised", - "nationalizes", "nationalises", - "naturalizing", "naturalising", - "neighborhood", "neighbourhood", - "neutralizing", "neutralising", - "organization", "organisation", - "outmaneuvers", "outmanoeuvres", - "paleontology", "palaeontology", - "pasteurizing", "pasteurising", - "pediatrician", "paediatrician", - "personalized", "personalised", - "personalizes", "personalises", - "philosophize", "philosophise", - "plagiarizing", "plagiarising", - "polarization", "polarisation", - "politicizing", "politicising", - "popularizing", "popularising", - "pressurizing", "pressurising", - "prioritizing", "prioritising", - "propagandize", "propagandise", - "proselytized", "proselytised", - "proselytizer", "proselytiser", - "proselytizes", "proselytises", - "radicalizing", "radicalising", - "rationalized", "rationalised", - "rationalizes", "rationalises", - "realizations", "realisations", - "recognizable", "recognisable", - "recognizably", "recognisably", - "recognizance", "recognisance", - "reconnoiters", "reconnoitres", - "regularizing", "regularising", - "reorganizing", "reorganising", - "revitalizing", "revitalising", - "rhapsodizing", "rhapsodising", - "romanticized", "romanticised", - "romanticizes", "romanticises", - "scandalizing", "scandalising", - "scrutinizing", "scrutinising", - "secularizing", "secularising", - "standardized", "standardised", - "standardizes", "standardises", - "stigmatizing", "stigmatising", - "sympathizers", "sympathisers", - "sympathizing", "sympathising", - "synchronized", "synchronised", - "synchronizes", "synchronises", - "synthesizing", "synthesising", - "systematized", "systematised", - "systematizes", "systematises", - "theatergoers", "theatregoers", - "traumatizing", "traumatising", - "trivializing", "trivialising", - "unauthorized", "unauthorised", - "unionization", "unionisation", - "unrecognized", "unrecognised", - "urbanization", "urbanisation", - "vaporization", "vaporisation", - "vocalization", "vocalisation", - "westernizing", "westernising", - "accessorize", "accessorise", - "acclimatize", "acclimatise", - "agonizingly", "agonisingly", - "amortizable", "amortisable", - "anesthetics", "anaesthetics", - "anesthetist", "anaesthetist", - "anesthetize", "anaesthetise", - "anglicizing", "anglicising", - "antagonized", "antagonised", - "antagonizes", "antagonises", - "apologizing", "apologising", - "backpedaled", "backpedalled", - "bastardized", "bastardised", - "bastardizes", "bastardises", - "behaviorism", "behaviourism", - "behaviorist", "behaviourist", - "bowdlerized", "bowdlerised", - "bowdlerizes", "bowdlerises", - "brutalizing", "brutalising", - "cannibalize", "cannibalise", - "capitalized", "capitalised", - "capitalizes", "capitalises", - "caramelized", "caramelised", - "caramelizes", "caramelises", - "carbonizing", "carbonising", - "categorized", "categorised", - "categorizes", "categorises", - "cauterizing", "cauterising", - "centerfolds", "centrefolds", - "centerpiece", "centrepiece", - "centiliters", "centilitres", - "centimeters", "centimetres", - "centralized", "centralised", - "centralizes", "centralises", - "circularize", "circularise", - "clarinetist", "clarinettist", - "computerize", "computerise", - "criminalize", "criminalise", - "criticizing", "criticising", - "crystallize", "crystallise", - "customizing", "customising", - "defenseless", "defenceless", - "dehumanized", "dehumanised", - "dehumanizes", "dehumanises", - "demobilized", "demobilised", - "demobilizes", "demobilises", - "democratize", "democratise", - "demoralized", "demoralised", - "demoralizes", "demoralises", - "deodorizing", "deodorising", - "desensitize", "desensitise", - "destabilize", "destabilise", - "discoloring", "discolouring", - "dishonoring", "dishonouring", - "dramatizing", "dramatising", - "economizing", "economising", - "empathizing", "empathising", - "emphasizing", "emphasising", - "endeavoring", "endeavouring", - "epitomizing", "epitomising", - "esophaguses", "oesophaguses", - "evangelized", "evangelised", - "evangelizes", "evangelises", - "extemporize", "extemporise", - "externalize", "externalise", - "factorizing", "factorising", - "familiarize", "familiarise", - "fantasizing", "fantasising", - "fertilizers", "fertilisers", - "fertilizing", "fertilising", - "formalizing", "formalising", - "fossilizing", "fossilising", - "fraternized", "fraternised", - "fraternizes", "fraternises", - "fulfillment", "fulfilment", - "galvanizing", "galvanising", - "generalized", "generalised", - "generalizes", "generalises", - "ghettoizing", "ghettoising", - "globalizing", "globalising", - "harmonizing", "harmonising", - "hemophiliac", "haemophiliac", - "hemorrhaged", "haemorrhaged", - "hemorrhages", "haemorrhages", - "hemorrhoids", "haemorrhoids", - "homogenized", "homogenised", - "homogenizes", "homogenises", - "hospitalize", "hospitalise", - "hybridizing", "hybridising", - "hypnotizing", "hypnotising", - "hypothesize", "hypothesise", - "immobilized", "immobilised", - "immobilizer", "immobiliser", - "immobilizes", "immobilises", - "immortalize", "immortalise", - "initialized", "initialised", - "initializes", "initialises", - "installment", "instalment", - "internalize", "internalise", - "italicizing", "italicising", - "jeopardized", "jeopardised", - "jeopardizes", "jeopardises", - "legitimized", "legitimised", - "legitimizes", "legitimises", - "liberalized", "liberalised", - "liberalizes", "liberalises", - "lionization", "lionisation", - "liquidizers", "liquidisers", - "liquidizing", "liquidising", - "magnetizing", "magnetising", - "maneuvering", "manoeuvring", - "marginalize", "marginalise", - "marvelously", "marvellously", - "materialize", "materialise", - "mechanizing", "mechanising", - "memorialize", "memorialise", - "mesmerizing", "mesmerising", - "metabolized", "metabolised", - "metabolizes", "metabolises", - "militarized", "militarised", - "militarizes", "militarises", - "milliliters", "millilitres", - "millimeters", "millimetres", - "miniaturize", "miniaturise", - "misbehavior", "misbehaviour", - "misdemeanor", "misdemeanour", - "modernizing", "modernising", - "moisturized", "moisturised", - "moisturizer", "moisturiser", - "moisturizes", "moisturises", - "monopolized", "monopolised", - "monopolizes", "monopolises", - "nationalize", "nationalise", - "naturalized", "naturalised", - "naturalizes", "naturalises", - "neighboring", "neighbouring", - "neutralized", "neutralised", - "neutralizes", "neutralises", - "normalizing", "normalising", - "orthopedics", "orthopaedics", - "ostracizing", "ostracising", - "outmaneuver", "outmanoeuvre", - "oxidization", "oxidisation", - "pasteurized", "pasteurised", - "pasteurizes", "pasteurises", - "patronizing", "patronising", - "personalize", "personalise", - "plagiarized", "plagiarised", - "plagiarizes", "plagiarises", - "politicized", "politicised", - "politicizes", "politicises", - "popularized", "popularised", - "popularizes", "popularises", - "pressurized", "pressurised", - "pressurizes", "pressurises", - "prioritized", "prioritised", - "prioritizes", "prioritises", - "privatizing", "privatising", - "proselytize", "proselytise", - "publicizing", "publicising", - "pulverizing", "pulverising", - "radicalized", "radicalised", - "radicalizes", "radicalises", - "randomizing", "randomising", - "rationalize", "rationalise", - "realization", "realisation", - "recognizing", "recognising", - "reconnoiter", "reconnoitre", - "regularized", "regularised", - "regularizes", "regularises", - "reorganized", "reorganised", - "reorganizes", "reorganises", - "revitalized", "revitalised", - "revitalizes", "revitalises", - "rhapsodized", "rhapsodised", - "rhapsodizes", "rhapsodises", - "romanticize", "romanticise", - "scandalized", "scandalised", - "scandalizes", "scandalises", - "scrutinized", "scrutinised", - "scrutinizes", "scrutinises", - "secularized", "secularised", - "secularizes", "secularises", - "sensitizing", "sensitising", - "serializing", "serialising", - "sermonizing", "sermonising", - "signalizing", "signalising", - "skeptically", "sceptically", - "socializing", "socialising", - "solemnizing", "solemnising", - "specialized", "specialised", - "specializes", "specialises", - "squirreling", "squirrelling", - "stabilizers", "stabilisers", - "stabilizing", "stabilising", - "standardize", "standardise", - "sterilizers", "sterilisers", - "sterilizing", "sterilising", - "stigmatized", "stigmatised", - "stigmatizes", "stigmatises", - "subsidizers", "subsidisers", - "subsidizing", "subsidising", - "summarizing", "summarising", - "symbolizing", "symbolising", - "sympathized", "sympathised", - "sympathizer", "sympathiser", - "sympathizes", "sympathises", - "synchronize", "synchronise", - "synthesized", "synthesised", - "synthesizes", "synthesises", - "systematize", "systematise", - "tantalizing", "tantalising", - "temporizing", "temporising", - "tenderizing", "tenderising", - "terrorizing", "terrorising", - "theatergoer", "theatregoer", - "traumatized", "traumatised", - "traumatizes", "traumatises", - "trivialized", "trivialised", - "trivializes", "trivialises", - "tyrannizing", "tyrannising", - "uncataloged", "uncatalogued", - "uncivilized", "uncivilised", - "unfavorable", "unfavourable", - "unfavorably", "unfavourably", - "unorganized", "unorganised", - "untrammeled", "untrammelled", - "utilization", "utilisation", - "vandalizing", "vandalising", - "verbalizing", "verbalising", - "victimizing", "victimising", - "visualizing", "visualising", - "vulgarizing", "vulgarising", - "watercolors", "watercolours", - "westernized", "westernised", - "westernizes", "westernises", - "amortizing", "amortising", - "anesthesia", "anaesthesia", - "anesthetic", "anaesthetic", - "anglicized", "anglicised", - "anglicizes", "anglicises", - "annualized", "annualised", - "antagonize", "antagonise", - "apologized", "apologised", - "apologizes", "apologises", - "appetizers", "appetisers", - "appetizing", "appetising", - "archeology", "archaeology", - "authorizes", "authorises", - "bastardize", "bastardise", - "bedeviling", "bedevilling", - "behavioral", "behavioural", - "belaboring", "belabouring", - "bowdlerize", "bowdlerise", - "brutalized", "brutalised", - "brutalizes", "brutalises", - "canalizing", "canalising", - "canonizing", "canonising", - "capitalize", "capitalise", - "caramelize", "caramelise", - "carbonized", "carbonised", - "carbonizes", "carbonises", - "cataloging", "cataloguing", - "catalyzing", "catalysing", - "categorize", "categorise", - "cauterized", "cauterised", - "cauterizes", "cauterises", - "centerfold", "centrefold", - "centiliter", "centilitre", - "centimeter", "centimetre", - "centralize", "centralise", - "channeling", "channelling", - "checkbooks", "chequebooks", - "civilizing", "civilising", - "colonizers", "colonisers", - "colonizing", "colonising", - "colorfully", "colourfully", - "colorizing", "colourizing", - "councilors", "councillors", - "counselors", "counsellors", - "criticized", "criticised", - "criticizes", "criticises", - "customized", "customised", - "customizes", "customises", - "dehumanize", "dehumanise", - "demobilize", "demobilise", - "demonizing", "demonising", - "demoralize", "demoralise", - "deodorized", "deodorised", - "deodorizes", "deodorises", - "deputizing", "deputising", - "digitizing", "digitising", - "discolored", "discoloured", - "disheveled", "dishevelled", - "dishonored", "dishonoured", - "dramatized", "dramatised", - "dramatizes", "dramatises", - "economized", "economised", - "economizes", "economises", - "empathized", "empathised", - "empathizes", "empathises", - "emphasized", "emphasised", - "emphasizes", "emphasises", - "endeavored", "endeavoured", - "energizing", "energising", - "epicenters", "epicentres", - "epitomized", "epitomised", - "epitomizes", "epitomises", - "equalizers", "equalisers", - "equalizing", "equalising", - "eulogizing", "eulogising", - "evangelize", "evangelise", - "factorized", "factorised", - "factorizes", "factorises", - "fantasized", "fantasised", - "fantasizes", "fantasises", - "favoritism", "favouritism", - "feminizing", "feminising", - "fertilized", "fertilised", - "fertilizer", "fertiliser", - "fertilizes", "fertilises", - "fiberglass", "fibreglass", - "finalizing", "finalising", - "flavorings", "flavourings", - "flavorless", "flavourless", - "flavorsome", "flavoursome", - "formalized", "formalised", - "formalizes", "formalises", - "fossilized", "fossilised", - "fossilizes", "fossilises", - "fraternize", "fraternise", - "galvanized", "galvanised", - "galvanizes", "galvanises", - "generalize", "generalise", - "ghettoized", "ghettoised", - "ghettoizes", "ghettoises", - "globalized", "globalised", - "globalizes", "globalises", - "gruelingly", "gruellingly", - "gynecology", "gynaecology", - "harmonized", "harmonised", - "harmonizes", "harmonises", - "hematology", "haematology", - "hemoglobin", "haemoglobin", - "hemophilia", "haemophilia", - "hemorrhage", "haemorrhage", - "homogenize", "homogenise", - "humanizing", "humanising", - "hybridized", "hybridised", - "hybridizes", "hybridises", - "hypnotized", "hypnotised", - "hypnotizes", "hypnotises", - "idealizing", "idealising", - "immobilize", "immobilise", - "immunizing", "immunising", - "impaneling", "impanelling", - "imperiling", "imperilling", - "initialing", "initialling", - "initialize", "initialise", - "ionization", "ionisation", - "italicized", "italicised", - "italicizes", "italicises", - "jeopardize", "jeopardise", - "kilometers", "kilometres", - "lackluster", "lacklustre", - "legalizing", "legalising", - "legitimize", "legitimise", - "liberalize", "liberalise", - "liquidized", "liquidised", - "liquidizer", "liquidiser", - "liquidizes", "liquidises", - "localizing", "localising", - "magnetized", "magnetised", - "magnetizes", "magnetises", - "maneuvered", "manoeuvred", - "marshaling", "marshalling", - "maximizing", "maximising", - "mechanized", "mechanised", - "mechanizes", "mechanises", - "memorizing", "memorising", - "mesmerized", "mesmerised", - "mesmerizes", "mesmerises", - "metabolize", "metabolise", - "militarize", "militarise", - "milliliter", "millilitre", - "millimeter", "millimetre", - "minimizing", "minimising", - "mobilizing", "mobilising", - "modernized", "modernised", - "modernizes", "modernises", - "moisturize", "moisturise", - "monopolize", "monopolise", - "moralizing", "moralising", - "naturalize", "naturalise", - "neighborly", "neighbourly", - "neutralize", "neutralise", - "normalized", "normalised", - "normalizes", "normalises", - "optimizing", "optimising", - "organizers", "organisers", - "organizing", "organising", - "orthopedic", "orthopaedic", - "ostracized", "ostracised", - "ostracizes", "ostracises", - "paralyzing", "paralysing", - "pasteurize", "pasteurise", - "patronized", "patronised", - "patronizes", "patronises", - "pedophiles", "paedophiles", - "pedophilia", "paedophilia", - "penalizing", "penalising", - "plagiarize", "plagiarise", - "plowshares", "ploughshares", - "polarizing", "polarising", - "politicize", "politicise", - "popularize", "popularise", - "prioritize", "prioritise", - "privatized", "privatised", - "privatizes", "privatises", - "publicized", "publicised", - "publicizes", "publicises", - "pulverized", "pulverised", - "pulverizes", "pulverises", - "quarreling", "quarrelling", - "radicalize", "radicalise", - "randomized", "randomised", - "randomizes", "randomises", - "realizable", "realisable", - "recognized", "recognised", - "recognizes", "recognises", - "regularize", "regularise", - "remodeling", "remodelling", - "reorganize", "reorganise", - "revitalize", "revitalise", - "rhapsodize", "rhapsodise", - "ritualized", "ritualised", - "sanitizing", "sanitising", - "satirizing", "satirising", - "scandalize", "scandalise", - "scrutinize", "scrutinise", - "secularize", "secularise", - "sensitized", "sensitised", - "sensitizes", "sensitises", - "sepulchers", "sepulchres", - "serialized", "serialised", - "serializes", "serialises", - "sermonized", "sermonised", - "sermonizes", "sermonises", - "shriveling", "shrivelling", - "signalized", "signalised", - "signalizes", "signalises", - "skepticism", "scepticism", - "socialized", "socialised", - "socializes", "socialises", - "sodomizing", "sodomising", - "solemnized", "solemnised", - "solemnizes", "solemnises", - "specialize", "specialise", - "squirreled", "squirrelled", - "stabilized", "stabilised", - "stabilizer", "stabiliser", - "stabilizes", "stabilises", - "stenciling", "stencilling", - "sterilized", "sterilised", - "sterilizer", "steriliser", - "sterilizes", "sterilises", - "stigmatize", "stigmatise", - "subsidized", "subsidised", - "subsidizer", "subsidiser", - "subsidizes", "subsidises", - "summarized", "summarised", - "summarizes", "summarises", - "symbolized", "symbolised", - "symbolizes", "symbolises", - "sympathize", "sympathise", - "tantalized", "tantalised", - "tantalizes", "tantalises", - "temporized", "temporised", - "temporizes", "temporises", - "tenderized", "tenderised", - "tenderizes", "tenderises", - "terrorized", "terrorised", - "terrorizes", "terrorises", - "theorizing", "theorising", - "traumatize", "traumatise", - "trivialize", "trivialise", - "tyrannized", "tyrannised", - "tyrannizes", "tyrannises", - "unionizing", "unionising", - "unraveling", "unravelling", - "urbanizing", "urbanising", - "utilizable", "utilisable", - "vandalized", "vandalised", - "vandalizes", "vandalises", - "vaporizing", "vaporising", - "verbalized", "verbalised", - "verbalizes", "verbalises", - "victimized", "victimised", - "victimizes", "victimises", - "visualized", "visualised", - "visualizes", "visualises", - "vocalizing", "vocalising", - "vulcanized", "vulcanised", - "vulgarized", "vulgarised", - "vulgarizes", "vulgarises", - "watercolor", "watercolour", - "westernize", "westernise", - "womanizers", "womanisers", - "womanizing", "womanising", - "worshiping", "worshipping", - "agonizing", "agonising", - "airplanes", "aeroplanes", - "amortized", "amortised", - "amortizes", "amortises", - "analyzing", "analysing", - "apologize", "apologise", - "appetizer", "appetiser", - "artifacts", "artefacts", - "baptizing", "baptising", - "bedeviled", "bedevilled", - "behaviors", "behaviours", - "bejeweled", "bejewelled", - "belabored", "belaboured", - "brutalize", "brutalise", - "canalized", "canalised", - "canalizes", "canalises", - "canonized", "canonised", - "canonizes", "canonises", - "carbonize", "carbonise", - "cataloged", "catalogued", - "catalyzed", "catalysed", - "catalyzes", "catalyses", - "cauterize", "cauterise", - "channeled", "channelled", - "checkbook", "chequebook", - "checkered", "chequered", - "chiseling", "chiselling", - "civilized", "civilised", - "civilizes", "civilises", - "clamoring", "clamouring", - "colonized", "colonised", - "colonizer", "coloniser", - "colonizes", "colonises", - "colorants", "colourants", - "colorized", "colourized", - "colorizes", "colourizes", - "colorless", "colourless", - "councilor", "councillor", - "counseled", "counselled", - "counselor", "counsellor", - "criticize", "criticise", - "cudgeling", "cudgelling", - "customize", "customise", - "demonized", "demonised", - "demonizes", "demonises", - "deodorize", "deodorise", - "deputized", "deputised", - "deputizes", "deputises", - "digitized", "digitised", - "digitizes", "digitises", - "discolors", "discolours", - "dishonors", "dishonours", - "dramatize", "dramatise", - "driveling", "drivelling", - "economize", "economise", - "empathize", "empathise", - "emphasize", "emphasise", - "enameling", "enamelling", - "endeavors", "endeavours", - "energized", "energised", - "energizes", "energises", - "enthralls", "enthrals", - "epicenter", "epicentre", - "epitomize", "epitomise", - "equalized", "equalised", - "equalizer", "equaliser", - "equalizes", "equalises", - "eulogized", "eulogised", - "eulogizes", "eulogises", - "factorize", "factorise", - "fantasize", "fantasise", - "favorable", "favourable", - "favorably", "favourably", - "favorites", "favourites", - "feminized", "feminised", - "feminizes", "feminises", - "fertilize", "fertilise", - "finalized", "finalised", - "finalizes", "finalises", - "flavoring", "flavouring", - "formalize", "formalise", - "fossilize", "fossilise", - "funneling", "funnelling", - "galvanize", "galvanise", - "gamboling", "gambolling", - "ghettoize", "ghettoise", - "globalize", "globalise", - "gonorrhea", "gonorrhoea", - "groveling", "grovelling", - "harboring", "harbouring", - "harmonize", "harmonise", - "honorably", "honourably", - "humanized", "humanised", - "humanizes", "humanises", - "hybridize", "hybridise", - "hypnotize", "hypnotise", - "idealized", "idealised", - "idealizes", "idealises", - "idolizing", "idolising", - "immunized", "immunised", - "immunizes", "immunises", - "impaneled", "impanelled", - "imperiled", "imperilled", - "initialed", "initialled", - "italicize", "italicise", - "itemizing", "itemising", - "kilometer", "kilometre", - "legalized", "legalised", - "legalizes", "legalises", - "lionizing", "lionising", - "liquidize", "liquidise", - "localized", "localised", - "localizes", "localises", - "magnetize", "magnetise", - "maneuvers", "manoeuvres", - "marshaled", "marshalled", - "marveling", "marvelling", - "marvelous", "marvellous", - "maximized", "maximised", - "maximizes", "maximises", - "mechanize", "mechanise", - "memorized", "memorised", - "memorizes", "memorises", - "mesmerize", "mesmerise", - "minimized", "minimised", - "minimizes", "minimises", - "mobilized", "mobilised", - "mobilizes", "mobilises", - "modernize", "modernise", - "moldering", "mouldering", - "moralized", "moralised", - "moralizes", "moralises", - "motorized", "motorised", - "mustached", "moustached", - "mustaches", "moustaches", - "neighbors", "neighbours", - "normalize", "normalise", - "optimized", "optimised", - "optimizes", "optimises", - "organized", "organised", - "organizer", "organiser", - "organizes", "organises", - "ostracize", "ostracise", - "oxidizing", "oxidising", - "panelists", "panellists", - "paralyzed", "paralysed", - "paralyzes", "paralyses", - "parceling", "parcelling", - "patronize", "patronise", - "pedophile", "paedophile", - "penalized", "penalised", - "penalizes", "penalises", - "penciling", "pencilling", - "plowshare", "ploughshare", - "polarized", "polarised", - "polarizes", "polarises", - "practiced", "practised", - "pretenses", "pretences", - "privatize", "privatise", - "publicize", "publicise", - "pulverize", "pulverise", - "quarreled", "quarrelled", - "randomize", "randomise", - "realizing", "realising", - "recognize", "recognise", - "refueling", "refuelling", - "remodeled", "remodelled", - "remolding", "remoulding", - "saltpeter", "saltpetre", - "sanitized", "sanitised", - "sanitizes", "sanitises", - "satirized", "satirised", - "satirizes", "satirises", - "sensitize", "sensitise", - "sepulcher", "sepulchre", - "serialize", "serialise", - "sermonize", "sermonise", - "shoveling", "shovelling", - "shriveled", "shrivelled", - "signaling", "signalling", - "signalize", "signalise", - "skeptical", "sceptical", - "sniveling", "snivelling", - "snorkeled", "snorkelled", - "socialize", "socialise", - "sodomized", "sodomised", - "sodomizes", "sodomises", - "solemnize", "solemnise", - "spiraling", "spiralling", - "splendors", "splendours", - "stabilize", "stabilise", - "stenciled", "stencilled", - "sterilize", "sterilise", - "subsidize", "subsidise", - "succoring", "succouring", - "sulfurous", "sulphurous", - "summarize", "summarise", - "swiveling", "swivelling", - "symbolize", "symbolise", - "tantalize", "tantalise", - "temporize", "temporise", - "tenderize", "tenderise", - "terrorize", "terrorise", - "theorized", "theorised", - "theorizes", "theorises", - "travelers", "travellers", - "traveling", "travelling", - "tricolors", "tricolours", - "tunneling", "tunnelling", - "tyrannize", "tyrannise", - "unequaled", "unequalled", - "unionized", "unionised", - "unionizes", "unionises", - "unraveled", "unravelled", - "unrivaled", "unrivalled", - "urbanized", "urbanised", - "urbanizes", "urbanises", - "utilizing", "utilising", - "vandalize", "vandalise", - "vaporized", "vaporised", - "vaporizes", "vaporises", - "verbalize", "verbalise", - "victimize", "victimise", - "visualize", "visualise", - "vocalized", "vocalised", - "vocalizes", "vocalises", - "vulgarize", "vulgarise", - "weaseling", "weaselling", - "womanized", "womanised", - "womanizer", "womaniser", - "womanizes", "womanises", - "worshiped", "worshipped", - "worshiper", "worshipper", - "agonized", "agonised", - "agonizes", "agonises", - "airplane", "aeroplane", - "aluminum", "aluminium", - "amortize", "amortise", - "analyzed", "analysed", - "analyzes", "analyses", - "armorers", "armourers", - "armories", "armouries", - "artifact", "artefact", - "baptized", "baptised", - "baptizes", "baptises", - "behavior", "behaviour", - "behooved", "behoved", - "behooves", "behoves", - "belabors", "belabours", - "calibers", "calibres", - "canalize", "canalise", - "canonize", "canonise", - "catalogs", "catalogues", - "catalyze", "catalyse", - "caviling", "cavilling", - "centered", "centred", - "chiseled", "chiselled", - "civilize", "civilise", - "clamored", "clamoured", - "colonize", "colonise", - "colorant", "colourant", - "coloreds", "coloureds", - "colorful", "colourful", - "coloring", "colouring", - "colorize", "colourize", - "coziness", "cosiness", - "cruelest", "cruellest", - "cudgeled", "cudgelled", - "defenses", "defences", - "demeanor", "demeanour", - "demonize", "demonise", - "deputize", "deputise", - "diarrhea", "diarrhoea", - "digitize", "digitise", - "disfavor", "disfavour", - "dishonor", "dishonour", - "distills", "distils", - "driveled", "drivelled", - "enameled", "enamelled", - "enamored", "enamoured", - "endeavor", "endeavour", - "energize", "energise", - "epaulets", "epaulettes", - "equalize", "equalise", - "estrogen", "oestrogen", - "etiology", "aetiology", - "eulogize", "eulogise", - "favoring", "favouring", - "favorite", "favourite", - "feminize", "feminise", - "finalize", "finalise", - "flavored", "flavoured", - "flutists", "flautists", - "fulfills", "fulfils", - "funneled", "funnelled", - "gamboled", "gambolled", - "graveled", "gravelled", - "groveled", "grovelled", - "grueling", "gruelling", - "harbored", "harboured", - "honoring", "honouring", - "humanize", "humanise", - "humoring", "humouring", - "idealize", "idealise", - "idolized", "idolised", - "idolizes", "idolises", - "immunize", "immunise", - "ionizing", "ionising", - "itemized", "itemised", - "itemizes", "itemises", - "jewelers", "jewellers", - "labeling", "labelling", - "laborers", "labourers", - "laboring", "labouring", - "legalize", "legalise", - "leukemia", "leukaemia", - "levelers", "levellers", - "leveling", "levelling", - "libeling", "libelling", - "libelous", "libellous", - "lionized", "lionised", - "lionizes", "lionises", - "localize", "localise", - "louvered", "louvred", - "maneuver", "manoeuvre", - "marveled", "marvelled", - "maximize", "maximise", - "memorize", "memorise", - "minimize", "minimise", - "mobilize", "mobilise", - "modelers", "modellers", - "modeling", "modelling", - "moldered", "mouldered", - "moldiest", "mouldiest", - "moldings", "mouldings", - "moralize", "moralise", - "mustache", "moustache", - "neighbor", "neighbour", - "odorless", "odourless", - "offenses", "offences", - "optimize", "optimise", - "organize", "organise", - "oxidized", "oxidised", - "oxidizes", "oxidises", - "paneling", "panelling", - "panelist", "panellist", - "paralyze", "paralyse", - "parceled", "parcelled", - "pedaling", "pedalling", - "penalize", "penalise", - "penciled", "pencilled", - "polarize", "polarise", - "pretense", "pretence", - "pummeled", "pummelling", - "raveling", "ravelling", - "realized", "realised", - "realizes", "realises", - "refueled", "refuelled", - "remolded", "remoulded", - "revelers", "revellers", - "reveling", "revelling", - "rivaling", "rivalling", - "sanitize", "sanitise", - "satirize", "satirise", - "savories", "savouries", - "savoring", "savouring", - "scepters", "sceptres", - "shoveled", "shovelled", - "signaled", "signalled", - "skeptics", "sceptics", - "sniveled", "snivelled", - "sodomize", "sodomise", - "specters", "spectres", - "spiraled", "spiralled", - "splendor", "splendour", - "succored", "succoured", - "sulfates", "sulphates", - "sulfides", "sulphides", - "swiveled", "swivelled", - "tasseled", "tasselled", - "theaters", "theatres", - "theorize", "theorise", - "toweling", "towelling", - "traveler", "traveller", - "trialing", "trialling", - "tricolor", "tricolour", - "tunneled", "tunnelled", - "unionize", "unionise", - "unsavory", "unsavoury", - "urbanize", "urbanise", - "utilized", "utilised", - "utilizes", "utilises", - "vaporize", "vaporise", - "vocalize", "vocalise", - "weaseled", "weaselled", - "womanize", "womanise", - "yodeling", "yodelling", - "agonize", "agonise", - "analyze", "analyse", - "appalls", "appals", - "armored", "armoured", - "armorer", "armourer", - "baptize", "baptise", - "behoove", "behove", - "belabor", "belabour", - "beveled", "bevelled", - "caliber", "calibre", - "caroled", "carolled", - "caviled", "cavilled", - "centers", "centres", - "clamors", "clamours", - "clangor", "clangour", - "colored", "coloured", - "coziest", "cosiest", - "crueler", "crueller", - "defense", "defence", - "dialing", "dialling", - "dialogs", "dialogues", - "distill", "distil", - "dueling", "duelling", - "enrolls", "enrols", - "epaulet", "epaulette", - "favored", "favoured", - "flavors", "flavours", - "flutist", "flautist", - "fueling", "fuelling", - "fulfill", "fulfil", - "goiters", "goitres", - "harbors", "harbours", - "honored", "honoured", - "humored", "humoured", - "idolize", "idolise", - "ionized", "ionised", - "ionizes", "ionises", - "itemize", "itemise", - "jeweled", "jewelled", - "jeweler", "jeweller", - "jewelry", "jewellery", - "labeled", "labelled", - "labored", "laboured", - "laborer", "labourer", - "leveled", "levelled", - "leveler", "leveller", - "libeled", "libelled", - "lionize", "lionise", - "louvers", "louvres", - "modeled", "modelled", - "modeler", "modeller", - "molders", "moulders", - "moldier", "mouldier", - "molding", "moulding", - "molting", "moulting", - "offense", "offence", - "oxidize", "oxidise", - "pajamas", "pyjamas", - "paneled", "panelled", - "parlors", "parlours", - "pedaled", "pedalled", - "plowing", "ploughing", - "plowman", "ploughman", - "plowmen", "ploughmen", - "realize", "realise", - "remolds", "remoulds", - "reveled", "revelled", - "reveler", "reveller", - "rivaled", "rivalled", - "rumored", "rumoured", - "saviors", "saviours", - "savored", "savoured", - "scepter", "sceptre", - "skeptic", "sceptic", - "specter", "spectre", - "succors", "succours", - "sulfate", "sulphate", - "sulfide", "sulphide", - "theater", "theatre", - "toweled", "towelled", - "toxemia", "toxaemia", - "trialed", "trialled", - "utilize", "utilise", - "yodeled", "yodelled", - "anemia", "anaemia", - "anemic", "anaemic", - "appall", "appal", - "arbors", "arbours", - "armory", "armoury", - "candor", "candour", - "center", "centre", - "clamor", "clamour", - "colors", "colours", - "cozier", "cosier", - "cozies", "cosies", - "cozily", "cosily", - "dialed", "dialled", - "drafty", "draughty", - "dueled", "duelled", - "favors", "favours", - "fervor", "fervour", - "fibers", "fibres", - "flavor", "flavour", - "fueled", "fuelled", - "goiter", "goitre", - "harbor", "harbour", - "honors", "honours", - "humors", "humours", - "labors", "labours", - "liters", "litres", - "louver", "louvre", - "luster", "lustre", - "meager", "meagre", - "miters", "mitres", - "molded", "moulded", - "molder", "moulder", - "molted", "moulted", - "pajama", "pyjama", - "parlor", "parlour", - "plowed", "ploughed", - "rancor", "rancour", - "remold", "remould", - "rigors", "rigours", - "rumors", "rumours", - "savors", "savours", - "savory", "savoury", - "succor", "succour", - "tumors", "tumours", - "vapors", "vapours", - "aging", "ageing", - "arbor", "arbour", - "ardor", "ardour", - "armor", "armour", - "chili", "chilli", - "color", "colour", - "edema", "edoema", - "favor", "favour", - "fecal", "faecal", - "feces", "faeces", - "fiber", "fibre", - "honor", "honour", - "humor", "humour", - "labor", "labour", - "liter", "litre", - "miter", "mitre", - "molds", "moulds", - "moldy", "mouldy", - "molts", "moults", - "odors", "odours", - "plows", "ploughs", - "rigor", "rigour", - "rumor", "rumour", - "savor", "savour", - "valor", "valour", - "vapor", "vapour", - "vigor", "vigour", - "cozy", "cosy", - "mold", "mould", - "molt", "moult", - "odor", "odour", - "plow", "plough", -} diff --git a/vendor/github.com/golangci/misspell/words_us.go b/vendor/github.com/golangci/misspell/words_us.go deleted file mode 100644 index 4dee20bc78..0000000000 --- a/vendor/github.com/golangci/misspell/words_us.go +++ /dev/null @@ -1,1625 +0,0 @@ -// Code generated by 'internal/gen'. DO NOT EDIT. - -package misspell - -// DictAmerican converts UK spellings to US spellings -var DictAmerican = []string{ - "institutionalisation", "institutionalization", - "internationalisation", "internationalization", - "professionalisation", "professionalization", - "compartmentalising", "compartmentalizing", - "institutionalising", "institutionalizing", - "internationalising", "internationalizing", - "compartmentalised", "compartmentalized", - "compartmentalises", "compartmentalizes", - "decriminalisation", "decriminalization", - "denationalisation", "denationalization", - "fictionalisations", "fictionalizations", - "institutionalised", "institutionalized", - "institutionalises", "institutionalizes", - "intellectualising", "intellectualizing", - "internationalised", "internationalized", - "internationalises", "internationalizes", - "pedestrianisation", "pedestrianization", - "professionalising", "professionalizing", - "archaeologically", "archeologically", - "compartmentalise", "compartmentalize", - "decentralisation", "decentralization", - "demilitarisation", "demilitarization", - "externalisations", "externalizations", - "fictionalisation", "fictionalization", - "institutionalise", "institutionalize", - "intellectualised", "intellectualized", - "intellectualises", "intellectualizes", - "internationalise", "internationalize", - "nationalisations", "nationalizations", - "palaeontologists", "paleontologists", - "professionalised", "professionalized", - "professionalises", "professionalizes", - "rationalisations", "rationalizations", - "sensationalising", "sensationalizing", - "sentimentalising", "sentimentalizing", - "acclimatisation", "acclimatization", - "bougainvillaeas", "bougainvilleas", - "commercialising", "commercializing", - "conceptualising", "conceptualizing", - "contextualising", "contextualizing", - "crystallisation", "crystallization", - "decriminalising", "decriminalizing", - "democratisation", "democratization", - "denationalising", "denationalizing", - "depersonalising", "depersonalizing", - "desensitisation", "desensitization", - "destabilisation", "destabilization", - "disorganisation", "disorganization", - "extemporisation", "extemporization", - "externalisation", "externalization", - "familiarisation", "familiarization", - "generalisations", "generalizations", - "hospitalisation", "hospitalization", - "individualising", "individualizing", - "industrialising", "industrializing", - "intellectualise", "intellectualize", - "internalisation", "internalization", - "manoeuvrability", "maneuverability", - "marginalisation", "marginalization", - "materialisation", "materialization", - "miniaturisation", "miniaturization", - "nationalisation", "nationalization", - "neighbourliness", "neighborliness", - "overemphasising", "overemphasizing", - "palaeontologist", "paleontologist", - "particularising", "particularizing", - "pedestrianising", "pedestrianizing", - "professionalise", "professionalize", - "psychoanalysing", "psychoanalyzing", - "rationalisation", "rationalization", - "reorganisations", "reorganizations", - "revolutionising", "revolutionizing", - "sensationalised", "sensationalized", - "sensationalises", "sensationalizes", - "sentimentalised", "sentimentalized", - "sentimentalises", "sentimentalizes", - "specialisations", "specializations", - "standardisation", "standardization", - "synchronisation", "synchronization", - "systematisation", "systematization", - "aggrandisement", "aggrandizement", - "anaesthetising", "anesthetizing", - "archaeological", "archeological", - "archaeologists", "archeologists", - "bougainvillaea", "bougainvillea", - "characterising", "characterizing", - "collectivising", "collectivizing", - "commercialised", "commercialized", - "commercialises", "commercializes", - "conceptualised", "conceptualized", - "conceptualises", "conceptualizes", - "contextualised", "contextualized", - "contextualises", "contextualizes", - "decentralising", "decentralizing", - "decriminalised", "decriminalized", - "decriminalises", "decriminalizes", - "dehumanisation", "dehumanization", - "demilitarising", "demilitarizing", - "demobilisation", "demobilization", - "demoralisation", "demoralization", - "denationalised", "denationalized", - "denationalises", "denationalizes", - "depersonalised", "depersonalized", - "depersonalises", "depersonalizes", - "disembowelling", "disemboweling", - "dramatisations", "dramatizations", - "editorialising", "editorializing", - "encyclopaedias", "encyclopedias", - "fictionalising", "fictionalizing", - "fraternisation", "fraternization", - "generalisation", "generalization", - "gynaecological", "gynecological", - "gynaecologists", "gynecologists", - "haematological", "hematological", - "haematologists", "hematologists", - "immobilisation", "immobilization", - "individualised", "individualized", - "individualises", "individualizes", - "industrialised", "industrialized", - "industrialises", "industrializes", - "liberalisation", "liberalization", - "monopolisation", "monopolization", - "naturalisation", "naturalization", - "neighbourhoods", "neighborhoods", - "neutralisation", "neutralization", - "organisational", "organizational", - "outmanoeuvring", "outmaneuvering", - "overemphasised", "overemphasized", - "overemphasises", "overemphasizes", - "paediatricians", "pediatricians", - "particularised", "particularized", - "particularises", "particularizes", - "pasteurisation", "pasteurization", - "pedestrianised", "pedestrianized", - "pedestrianises", "pedestrianizes", - "philosophising", "philosophizing", - "politicisation", "politicization", - "popularisation", "popularization", - "pressurisation", "pressurization", - "prioritisation", "prioritization", - "privatisations", "privatizations", - "propagandising", "propagandizing", - "psychoanalysed", "psychoanalyzed", - "psychoanalyses", "psychoanalyzes", - "regularisation", "regularization", - "reorganisation", "reorganization", - "revolutionised", "revolutionized", - "revolutionises", "revolutionizes", - "secularisation", "secularization", - "sensationalise", "sensationalize", - "sentimentalise", "sentimentalize", - "serialisations", "serializations", - "specialisation", "specialization", - "sterilisations", "sterilizations", - "stigmatisation", "stigmatization", - "transistorised", "transistorized", - "unrecognisable", "unrecognizable", - "visualisations", "visualizations", - "westernisation", "westernization", - "accessorising", "accessorizing", - "acclimatising", "acclimatizing", - "amortisations", "amortizations", - "amphitheatres", "amphitheaters", - "anaesthetised", "anesthetized", - "anaesthetises", "anesthetizes", - "anaesthetists", "anesthetists", - "archaeologist", "archeologist", - "backpedalling", "backpedaling", - "behaviourists", "behaviorists", - "breathalysers", "breathalyzers", - "breathalysing", "breathalyzing", - "callisthenics", "calisthenics", - "cannibalising", "cannibalizing", - "characterised", "characterized", - "characterises", "characterizes", - "circularising", "circularizing", - "clarinettists", "clarinetists", - "collectivised", "collectivized", - "collectivises", "collectivizes", - "commercialise", "commercialize", - "computerising", "computerizing", - "conceptualise", "conceptualize", - "contextualise", "contextualize", - "criminalising", "criminalizing", - "crystallising", "crystallizing", - "decentralised", "decentralized", - "decentralises", "decentralizes", - "decriminalise", "decriminalize", - "demilitarised", "demilitarized", - "demilitarises", "demilitarizes", - "democratising", "democratizing", - "denationalise", "denationalize", - "depersonalise", "depersonalize", - "desensitising", "desensitizing", - "destabilising", "destabilizing", - "disembowelled", "disemboweled", - "dishonourable", "dishonorable", - "dishonourably", "dishonorably", - "dramatisation", "dramatization", - "editorialised", "editorialized", - "editorialises", "editorializes", - "encyclopaedia", "encyclopedia", - "encyclopaedic", "encyclopedic", - "extemporising", "extemporizing", - "externalising", "externalizing", - "familiarising", "familiarizing", - "fertilisation", "fertilization", - "fictionalised", "fictionalized", - "fictionalises", "fictionalizes", - "formalisation", "formalization", - "fossilisation", "fossilization", - "globalisation", "globalization", - "gynaecologist", "gynecologist", - "haematologist", "hematologist", - "haemophiliacs", "hemophiliacs", - "haemorrhaging", "hemorrhaging", - "harmonisation", "harmonization", - "hospitalising", "hospitalizing", - "hypothesising", "hypothesizing", - "immortalising", "immortalizing", - "individualise", "individualize", - "industrialise", "industrialize", - "internalising", "internalizing", - "marginalising", "marginalizing", - "materialising", "materializing", - "mechanisation", "mechanization", - "memorialising", "memorializing", - "miniaturising", "miniaturizing", - "miscatalogued", "miscataloged", - "misdemeanours", "misdemeanors", - "multicoloured", "multicolored", - "nationalising", "nationalizing", - "neighbourhood", "neighborhood", - "normalisation", "normalization", - "organisations", "organizations", - "outmanoeuvred", "outmaneuvered", - "outmanoeuvres", "outmaneuvers", - "overemphasise", "overemphasize", - "paediatrician", "pediatrician", - "palaeontology", "paleontology", - "particularise", "particularize", - "passivisation", "passivization", - "patronisingly", "patronizingly", - "pedestrianise", "pedestrianize", - "personalising", "personalizing", - "philosophised", "philosophized", - "philosophises", "philosophizes", - "privatisation", "privatization", - "propagandised", "propagandized", - "propagandises", "propagandizes", - "proselytisers", "proselytizers", - "proselytising", "proselytizing", - "psychoanalyse", "psychoanalyze", - "pulverisation", "pulverization", - "rationalising", "rationalizing", - "reconnoitring", "reconnoitering", - "revolutionise", "revolutionize", - "romanticising", "romanticizing", - "serialisation", "serialization", - "socialisation", "socialization", - "stabilisation", "stabilization", - "standardising", "standardizing", - "sterilisation", "sterilization", - "subsidisation", "subsidization", - "synchronising", "synchronizing", - "systematising", "systematizing", - "tantalisingly", "tantalizingly", - "underutilised", "underutilized", - "victimisation", "victimization", - "visualisation", "visualization", - "vocalisations", "vocalizations", - "vulgarisation", "vulgarization", - "accessorised", "accessorized", - "accessorises", "accessorizes", - "acclimatised", "acclimatized", - "acclimatises", "acclimatizes", - "amortisation", "amortization", - "amphitheatre", "amphitheater", - "anaesthetics", "anesthetics", - "anaesthetise", "anesthetize", - "anaesthetist", "anesthetist", - "antagonising", "antagonizing", - "appetisingly", "appetizingly", - "backpedalled", "backpedaled", - "bastardising", "bastardizing", - "behaviourism", "behaviorism", - "behaviourist", "behaviorist", - "bowdlerising", "bowdlerizing", - "breathalysed", "breathalyzed", - "breathalyser", "breathalyzer", - "breathalyses", "breathalyzes", - "cannibalised", "cannibalized", - "cannibalises", "cannibalizes", - "capitalising", "capitalizing", - "caramelising", "caramelizing", - "categorising", "categorizing", - "centigrammes", "centigrams", - "centralising", "centralizing", - "centrepieces", "centerpieces", - "characterise", "characterize", - "circularised", "circularized", - "circularises", "circularizes", - "clarinettist", "clarinetist", - "collectivise", "collectivize", - "colonisation", "colonization", - "computerised", "computerized", - "computerises", "computerizes", - "criminalised", "criminalized", - "criminalises", "criminalizes", - "crystallised", "crystallized", - "crystallises", "crystallizes", - "decentralise", "decentralize", - "dehumanising", "dehumanizing", - "demilitarise", "demilitarize", - "demobilising", "demobilizing", - "democratised", "democratized", - "democratises", "democratizes", - "demoralising", "demoralizing", - "desensitised", "desensitized", - "desensitises", "desensitizes", - "destabilised", "destabilized", - "destabilises", "destabilizes", - "discolouring", "discoloring", - "dishonouring", "dishonoring", - "disorganised", "disorganized", - "editorialise", "editorialize", - "endeavouring", "endeavoring", - "equalisation", "equalization", - "evangelising", "evangelizing", - "extemporised", "extemporized", - "extemporises", "extemporizes", - "externalised", "externalized", - "externalises", "externalizes", - "familiarised", "familiarized", - "familiarises", "familiarizes", - "fictionalise", "fictionalize", - "finalisation", "finalization", - "fraternising", "fraternizing", - "generalising", "generalizing", - "haemophiliac", "hemophiliac", - "haemorrhaged", "hemorrhaged", - "haemorrhages", "hemorrhages", - "haemorrhoids", "hemorrhoids", - "homoeopathic", "homeopathic", - "homogenising", "homogenizing", - "hospitalised", "hospitalized", - "hospitalises", "hospitalizes", - "hypothesised", "hypothesized", - "hypothesises", "hypothesizes", - "idealisation", "idealization", - "immobilisers", "immobilizers", - "immobilising", "immobilizing", - "immortalised", "immortalized", - "immortalises", "immortalizes", - "immunisation", "immunization", - "initialising", "initializing", - "internalised", "internalized", - "internalises", "internalizes", - "jeopardising", "jeopardizing", - "legalisation", "legalization", - "legitimising", "legitimizing", - "liberalising", "liberalizing", - "manoeuvrable", "maneuverable", - "manoeuvrings", "maneuverings", - "marginalised", "marginalized", - "marginalises", "marginalizes", - "marvellously", "marvelously", - "materialised", "materialized", - "materialises", "materializes", - "maximisation", "maximization", - "memorialised", "memorialized", - "memorialises", "memorializes", - "metabolising", "metabolizing", - "militarising", "militarizing", - "milligrammes", "milligrams", - "miniaturised", "miniaturized", - "miniaturises", "miniaturizes", - "misbehaviour", "misbehavior", - "misdemeanour", "misdemeanor", - "mobilisation", "mobilization", - "moisturisers", "moisturizers", - "moisturising", "moisturizing", - "monopolising", "monopolizing", - "moustachioed", "mustachioed", - "nationalised", "nationalized", - "nationalises", "nationalizes", - "naturalising", "naturalizing", - "neighbouring", "neighboring", - "neutralising", "neutralizing", - "oesophaguses", "esophaguses", - "organisation", "organization", - "orthopaedics", "orthopedics", - "outmanoeuvre", "outmaneuver", - "palaeolithic", "paleolithic", - "pasteurising", "pasteurizing", - "personalised", "personalized", - "personalises", "personalizes", - "philosophise", "philosophize", - "plagiarising", "plagiarizing", - "ploughshares", "plowshares", - "polarisation", "polarization", - "politicising", "politicizing", - "popularising", "popularizing", - "pressurising", "pressurizing", - "prioritising", "prioritizing", - "propagandise", "propagandize", - "proselytised", "proselytized", - "proselytiser", "proselytizer", - "proselytises", "proselytizes", - "radicalising", "radicalizing", - "rationalised", "rationalized", - "rationalises", "rationalizes", - "realisations", "realizations", - "recognisable", "recognizable", - "recognisably", "recognizably", - "recognisance", "recognizance", - "reconnoitred", "reconnoitered", - "reconnoitres", "reconnoiters", - "regularising", "regularizing", - "reorganising", "reorganizing", - "revitalising", "revitalizing", - "rhapsodising", "rhapsodizing", - "romanticised", "romanticized", - "romanticises", "romanticizes", - "scandalising", "scandalizing", - "scrutinising", "scrutinizing", - "secularising", "secularizing", - "specialising", "specializing", - "squirrelling", "squirreling", - "standardised", "standardized", - "standardises", "standardizes", - "stigmatising", "stigmatizing", - "sympathisers", "sympathizers", - "sympathising", "sympathizing", - "synchronised", "synchronized", - "synchronises", "synchronizes", - "synthesisers", "synthesizers", - "synthesising", "synthesizing", - "systematised", "systematized", - "systematises", "systematizes", - "technicolour", "technicolor", - "theatregoers", "theatergoers", - "traumatising", "traumatizing", - "trivialising", "trivializing", - "unauthorised", "unauthorized", - "uncatalogued", "uncataloged", - "unfavourable", "unfavorable", - "unfavourably", "unfavorably", - "unionisation", "unionization", - "unrecognised", "unrecognized", - "untrammelled", "untrammeled", - "urbanisation", "urbanization", - "vaporisation", "vaporization", - "vocalisation", "vocalization", - "watercolours", "watercolors", - "westernising", "westernizing", - "accessorise", "accessorize", - "acclimatise", "acclimatize", - "agonisingly", "agonizingly", - "amortisable", "amortizable", - "anaesthesia", "anesthesia", - "anaesthetic", "anesthetic", - "anglicising", "anglicizing", - "antagonised", "antagonized", - "antagonises", "antagonizes", - "apologising", "apologizing", - "archaeology", "archeology", - "authorising", "authorizing", - "bastardised", "bastardized", - "bastardises", "bastardizes", - "bedevilling", "bedeviling", - "behavioural", "behavioral", - "belabouring", "belaboring", - "bowdlerised", "bowdlerized", - "bowdlerises", "bowdlerizes", - "breathalyse", "breathalyze", - "brutalising", "brutalizing", - "cannibalise", "cannibalize", - "capitalised", "capitalized", - "capitalises", "capitalizes", - "caramelised", "caramelized", - "caramelises", "caramelizes", - "carbonising", "carbonizing", - "cataloguing", "cataloging", - "categorised", "categorized", - "categorises", "categorizes", - "cauterising", "cauterizing", - "centigramme", "centigram", - "centilitres", "centiliters", - "centimetres", "centimeters", - "centralised", "centralized", - "centralises", "centralizes", - "centrefolds", "centerfolds", - "centrepiece", "centerpiece", - "channelling", "channeling", - "chequebooks", "checkbooks", - "circularise", "circularize", - "colourfully", "colorfully", - "colourizing", "colorizing", - "computerise", "computerize", - "councillors", "councilors", - "counselling", "counseling", - "counsellors", "counselors", - "criminalise", "criminalize", - "criticising", "criticizing", - "crystallise", "crystallize", - "customising", "customizing", - "defenceless", "defenseless", - "dehumanised", "dehumanized", - "dehumanises", "dehumanizes", - "demobilised", "demobilized", - "demobilises", "demobilizes", - "democratise", "democratize", - "demoralised", "demoralized", - "demoralises", "demoralizes", - "deodorising", "deodorizing", - "desensitise", "desensitize", - "destabilise", "destabilize", - "discoloured", "discolored", - "dishevelled", "disheveled", - "dishonoured", "dishonored", - "dramatising", "dramatizing", - "economising", "economizing", - "empathising", "empathizing", - "emphasising", "emphasizing", - "endeavoured", "endeavored", - "epitomising", "epitomizing", - "evangelised", "evangelized", - "evangelises", "evangelizes", - "extemporise", "extemporize", - "externalise", "externalize", - "factorising", "factorizing", - "familiarise", "familiarize", - "fantasising", "fantasizing", - "favouritism", "favoritism", - "fertilisers", "fertilizers", - "fertilising", "fertilizing", - "flavourings", "flavorings", - "flavourless", "flavorless", - "flavoursome", "flavorsome", - "formalising", "formalizing", - "fossilising", "fossilizing", - "fraternised", "fraternized", - "fraternises", "fraternizes", - "galvanising", "galvanizing", - "generalised", "generalized", - "generalises", "generalizes", - "ghettoising", "ghettoizing", - "globalising", "globalizing", - "gruellingly", "gruelingly", - "gynaecology", "gynecology", - "haematology", "hematology", - "haemoglobin", "hemoglobin", - "haemophilia", "hemophilia", - "haemorrhage", "hemorrhage", - "harmonising", "harmonizing", - "homoeopaths", "homeopaths", - "homoeopathy", "homeopathy", - "homogenised", "homogenized", - "homogenises", "homogenizes", - "hospitalise", "hospitalize", - "hybridising", "hybridizing", - "hypnotising", "hypnotizing", - "hypothesise", "hypothesize", - "immobilised", "immobilized", - "immobiliser", "immobilizer", - "immobilises", "immobilizes", - "immortalise", "immortalize", - "impanelling", "impaneling", - "imperilling", "imperiling", - "initialised", "initialized", - "initialises", "initializes", - "initialling", "initialing", - "instalments", "installments", - "internalise", "internalize", - "italicising", "italicizing", - "jeopardised", "jeopardized", - "jeopardises", "jeopardizes", - "kilogrammes", "kilograms", - "legitimised", "legitimized", - "legitimises", "legitimizes", - "liberalised", "liberalized", - "liberalises", "liberalizes", - "lionisation", "lionization", - "liquidisers", "liquidizers", - "liquidising", "liquidizing", - "magnetising", "magnetizing", - "manoeuvring", "maneuvering", - "marginalise", "marginalize", - "marshalling", "marshaling", - "materialise", "materialize", - "mechanising", "mechanizing", - "memorialise", "memorialize", - "mesmerising", "mesmerizing", - "metabolised", "metabolized", - "metabolises", "metabolizes", - "micrometres", "micrometers", - "militarised", "militarized", - "militarises", "militarizes", - "milligramme", "milligram", - "millilitres", "milliliters", - "millimetres", "millimeters", - "miniaturise", "miniaturize", - "modernising", "modernizing", - "moisturised", "moisturized", - "moisturiser", "moisturizer", - "moisturises", "moisturizes", - "monopolised", "monopolized", - "monopolises", "monopolizes", - "nationalise", "nationalize", - "naturalised", "naturalized", - "naturalises", "naturalizes", - "neighbourly", "neighborly", - "neutralised", "neutralized", - "neutralises", "neutralizes", - "normalising", "normalizing", - "orthopaedic", "orthopedic", - "ostracising", "ostracizing", - "oxidisation", "oxidization", - "paediatrics", "pediatrics", - "paedophiles", "pedophiles", - "paedophilia", "pedophilia", - "passivising", "passivizing", - "pasteurised", "pasteurized", - "pasteurises", "pasteurizes", - "patronising", "patronizing", - "personalise", "personalize", - "plagiarised", "plagiarized", - "plagiarises", "plagiarizes", - "ploughshare", "plowshare", - "politicised", "politicized", - "politicises", "politicizes", - "popularised", "popularized", - "popularises", "popularizes", - "praesidiums", "presidiums", - "pressurised", "pressurized", - "pressurises", "pressurizes", - "prioritised", "prioritized", - "prioritises", "prioritizes", - "privatising", "privatizing", - "proselytise", "proselytize", - "publicising", "publicizing", - "pulverising", "pulverizing", - "quarrelling", "quarreling", - "radicalised", "radicalized", - "radicalises", "radicalizes", - "randomising", "randomizing", - "rationalise", "rationalize", - "realisation", "realization", - "recognising", "recognizing", - "reconnoitre", "reconnoiter", - "regularised", "regularized", - "regularises", "regularizes", - "remodelling", "remodeling", - "reorganised", "reorganized", - "reorganises", "reorganizes", - "revitalised", "revitalized", - "revitalises", "revitalizes", - "rhapsodised", "rhapsodized", - "rhapsodises", "rhapsodizes", - "romanticise", "romanticize", - "scandalised", "scandalized", - "scandalises", "scandalizes", - "sceptically", "skeptically", - "scrutinised", "scrutinized", - "scrutinises", "scrutinizes", - "secularised", "secularized", - "secularises", "secularizes", - "sensitising", "sensitizing", - "serialising", "serializing", - "sermonising", "sermonizing", - "shrivelling", "shriveling", - "signalising", "signalizing", - "snorkelling", "snorkeling", - "snowploughs", "snowplow", - "socialising", "socializing", - "solemnising", "solemnizing", - "specialised", "specialized", - "specialises", "specializes", - "squirrelled", "squirreled", - "stabilisers", "stabilizers", - "stabilising", "stabilizing", - "standardise", "standardize", - "stencilling", "stenciling", - "sterilisers", "sterilizers", - "sterilising", "sterilizing", - "stigmatised", "stigmatized", - "stigmatises", "stigmatizes", - "subsidisers", "subsidizers", - "subsidising", "subsidizing", - "summarising", "summarizing", - "symbolising", "symbolizing", - "sympathised", "sympathized", - "sympathiser", "sympathizer", - "sympathises", "sympathizes", - "synchronise", "synchronize", - "synthesised", "synthesized", - "synthesiser", "synthesizer", - "synthesises", "synthesizes", - "systematise", "systematize", - "tantalising", "tantalizing", - "temporising", "temporizing", - "tenderising", "tenderizing", - "terrorising", "terrorizing", - "theatregoer", "theatergoer", - "traumatised", "traumatized", - "traumatises", "traumatizes", - "trivialised", "trivialized", - "trivialises", "trivializes", - "tyrannising", "tyrannizing", - "uncivilised", "uncivilized", - "unorganised", "unorganized", - "unravelling", "unraveling", - "utilisation", "utilization", - "vandalising", "vandalizing", - "verbalising", "verbalizing", - "victimising", "victimizing", - "visualising", "visualizing", - "vulgarising", "vulgarizing", - "watercolour", "watercolor", - "westernised", "westernized", - "westernises", "westernizes", - "worshipping", "worshiping", - "aeroplanes", "airplanes", - "amortising", "amortizing", - "anglicised", "anglicized", - "anglicises", "anglicizes", - "annualised", "annualized", - "antagonise", "antagonize", - "apologised", "apologized", - "apologises", "apologizes", - "appetisers", "appetizers", - "appetising", "appetizing", - "authorised", "authorized", - "authorises", "authorizes", - "bannisters", "banisters", - "bastardise", "bastardize", - "bedevilled", "bedeviled", - "behaviours", "behaviors", - "bejewelled", "bejeweled", - "belaboured", "belabored", - "bowdlerise", "bowdlerize", - "brutalised", "brutalized", - "brutalises", "brutalizes", - "canalising", "canalizing", - "cancelling", "canceling", - "canonising", "canonizing", - "capitalise", "capitalize", - "caramelise", "caramelize", - "carbonised", "carbonized", - "carbonises", "carbonizes", - "catalogued", "cataloged", - "catalogues", "catalogs", - "catalysing", "catalyzing", - "categorise", "categorize", - "cauterised", "cauterized", - "cauterises", "cauterizes", - "centilitre", "centiliter", - "centimetre", "centimeter", - "centralise", "centralize", - "centrefold", "centerfold", - "channelled", "channeled", - "chequebook", "checkbook", - "chiselling", "chiseling", - "civilising", "civilizing", - "clamouring", "clamoring", - "colonisers", "colonizers", - "colonising", "colonizing", - "colourants", "colorants", - "colourized", "colorized", - "colourizes", "colorizes", - "colourless", "colorless", - "connexions", "connections", - "councillor", "councilor", - "counselled", "counseled", - "counsellor", "counselor", - "criticised", "criticized", - "criticises", "criticizes", - "cudgelling", "cudgeling", - "customised", "customized", - "customises", "customizes", - "dehumanise", "dehumanize", - "demobilise", "demobilize", - "demonising", "demonizing", - "demoralise", "demoralize", - "deodorised", "deodorized", - "deodorises", "deodorizes", - "deputising", "deputizing", - "digitising", "digitizing", - "discolours", "discolors", - "dishonours", "dishonors", - "dramatised", "dramatized", - "dramatises", "dramatizes", - "drivelling", "driveling", - "economised", "economized", - "economises", "economizes", - "empathised", "empathized", - "empathises", "empathizes", - "emphasised", "emphasized", - "emphasises", "emphasizes", - "enamelling", "enameling", - "endeavours", "endeavors", - "energising", "energizing", - "epaulettes", "epaulets", - "epicentres", "epicenters", - "epitomised", "epitomized", - "epitomises", "epitomizes", - "equalisers", "equalizers", - "equalising", "equalizing", - "eulogising", "eulogizing", - "evangelise", "evangelize", - "factorised", "factorized", - "factorises", "factorizes", - "fantasised", "fantasized", - "fantasises", "fantasizes", - "favourable", "favorable", - "favourably", "favorably", - "favourites", "favorites", - "feminising", "feminizing", - "fertilised", "fertilized", - "fertiliser", "fertilizer", - "fertilises", "fertilizes", - "fibreglass", "fiberglass", - "finalising", "finalizing", - "flavouring", "flavoring", - "formalised", "formalized", - "formalises", "formalizes", - "fossilised", "fossilized", - "fossilises", "fossilizes", - "fraternise", "fraternize", - "fulfilment", "fulfillment", - "funnelling", "funneling", - "galvanised", "galvanized", - "galvanises", "galvanizes", - "gambolling", "gamboling", - "gaolbreaks", "jailbreaks", - "generalise", "generalize", - "ghettoised", "ghettoized", - "ghettoises", "ghettoizes", - "globalised", "globalized", - "globalises", "globalizes", - "gonorrhoea", "gonorrhea", - "grovelling", "groveling", - "harbouring", "harboring", - "harmonised", "harmonized", - "harmonises", "harmonizes", - "homoeopath", "homeopath", - "homogenise", "homogenize", - "honourable", "honorable", - "honourably", "honorably", - "humanising", "humanizing", - "humourless", "humorless", - "hybridised", "hybridized", - "hybridises", "hybridizes", - "hypnotised", "hypnotized", - "hypnotises", "hypnotizes", - "idealising", "idealizing", - "immobilise", "immobilize", - "immunising", "immunizing", - "impanelled", "impaneled", - "imperilled", "imperiled", - "inflexions", "inflections", - "initialise", "initialize", - "initialled", "initialed", - "instalment", "installment", - "ionisation", "ionization", - "italicised", "italicized", - "italicises", "italicizes", - "jeopardise", "jeopardize", - "kilogramme", "kilogram", - "kilometres", "kilometers", - "lacklustre", "lackluster", - "legalising", "legalizing", - "legitimise", "legitimize", - "liberalise", "liberalize", - "liquidised", "liquidized", - "liquidiser", "liquidizer", - "liquidises", "liquidizes", - "localising", "localizing", - "magnetised", "magnetized", - "magnetises", "magnetizes", - "manoeuvred", "maneuvered", - "manoeuvres", "maneuvers", - "marshalled", "marshaled", - "marvelling", "marveling", - "marvellous", "marvelous", - "maximising", "maximizing", - "mechanised", "mechanized", - "mechanises", "mechanizes", - "memorising", "memorizing", - "mesmerised", "mesmerized", - "mesmerises", "mesmerizes", - "metabolise", "metabolize", - "micrometre", "micrometer", - "militarise", "militarize", - "millilitre", "milliliter", - "millimetre", "millimeter", - "minimising", "minimizing", - "mobilising", "mobilizing", - "modernised", "modernized", - "modernises", "modernizes", - "moisturise", "moisturize", - "monopolise", "monopolize", - "moralising", "moralizing", - "mouldering", "moldering", - "moustached", "mustached", - "moustaches", "mustaches", - "naturalise", "naturalize", - "neighbours", "neighbors", - "neutralise", "neutralize", - "normalised", "normalized", - "normalises", "normalizes", - "oesophagus", "esophagus", - "optimising", "optimizing", - "organisers", "organizers", - "organising", "organizing", - "ostracised", "ostracized", - "ostracises", "ostracizes", - "paederasts", "pederasts", - "paediatric", "pediatric", - "paedophile", "pedophile", - "panellists", "panelists", - "paralysing", "paralyzing", - "parcelling", "parceling", - "passivised", "passivized", - "passivises", "passivizes", - "pasteurise", "pasteurize", - "patronised", "patronized", - "patronises", "patronizes", - "penalising", "penalizing", - "pencilling", "penciling", - "plagiarise", "plagiarize", - "polarising", "polarizing", - "politicise", "politicize", - "popularise", "popularize", - "practising", "practicing", - "praesidium", "presidium", - "pressurise", "pressurize", - "prioritise", "prioritize", - "privatised", "privatized", - "privatises", "privatizes", - "programmes", "programs", - "publicised", "publicized", - "publicises", "publicizes", - "pulverised", "pulverized", - "pulverises", "pulverizes", - "pummelling", "pummeled", - "quarrelled", "quarreled", - "radicalise", "radicalize", - "randomised", "randomized", - "randomises", "randomizes", - "realisable", "realizable", - "recognised", "recognized", - "recognises", "recognizes", - "refuelling", "refueling", - "regularise", "regularize", - "remodelled", "remodeled", - "remoulding", "remolding", - "reorganise", "reorganize", - "revitalise", "revitalize", - "rhapsodise", "rhapsodize", - "ritualised", "ritualized", - "sanitising", "sanitizing", - "satirising", "satirizing", - "scandalise", "scandalize", - "scepticism", "skepticism", - "scrutinise", "scrutinize", - "secularise", "secularize", - "sensitised", "sensitized", - "sensitises", "sensitizes", - "sepulchres", "sepulchers", - "serialised", "serialized", - "serialises", "serializes", - "sermonised", "sermonized", - "sermonises", "sermonizes", - "shovelling", "shoveling", - "shrivelled", "shriveled", - "signalised", "signalized", - "signalises", "signalizes", - "signalling", "signaling", - "snivelling", "sniveling", - "snorkelled", "snorkeled", - "snowplough", "snowplow", - "socialised", "socialized", - "socialises", "socializes", - "sodomising", "sodomizing", - "solemnised", "solemnized", - "solemnises", "solemnizes", - "specialise", "specialize", - "spiralling", "spiraling", - "splendours", "splendors", - "stabilised", "stabilized", - "stabiliser", "stabilizer", - "stabilises", "stabilizes", - "stencilled", "stenciled", - "sterilised", "sterilized", - "steriliser", "sterilizer", - "sterilises", "sterilizes", - "stigmatise", "stigmatize", - "subsidised", "subsidized", - "subsidiser", "subsidizer", - "subsidises", "subsidizes", - "succouring", "succoring", - "sulphurous", "sulfurous", - "summarised", "summarized", - "summarises", "summarizes", - "swivelling", "swiveling", - "symbolised", "symbolized", - "symbolises", "symbolizes", - "sympathise", "sympathize", - "synthesise", "synthesize", - "tantalised", "tantalized", - "tantalises", "tantalizes", - "temporised", "temporized", - "temporises", "temporizes", - "tenderised", "tenderized", - "tenderises", "tenderizes", - "terrorised", "terrorized", - "terrorises", "terrorizes", - "theorising", "theorizing", - "traumatise", "traumatize", - "travellers", "travelers", - "travelling", "traveling", - "tricolours", "tricolors", - "trivialise", "trivialize", - "tunnelling", "tunneling", - "tyrannised", "tyrannized", - "tyrannises", "tyrannizes", - "unequalled", "unequaled", - "unionising", "unionizing", - "unravelled", "unraveled", - "unrivalled", "unrivaled", - "urbanising", "urbanizing", - "utilisable", "utilizable", - "vandalised", "vandalized", - "vandalises", "vandalizes", - "vaporising", "vaporizing", - "verbalised", "verbalized", - "verbalises", "verbalizes", - "victimised", "victimized", - "victimises", "victimizes", - "visualised", "visualized", - "visualises", "visualizes", - "vocalising", "vocalizing", - "vulcanised", "vulcanized", - "vulgarised", "vulgarized", - "vulgarises", "vulgarizes", - "weaselling", "weaseling", - "westernise", "westernize", - "womanisers", "womanizers", - "womanising", "womanizing", - "worshipped", "worshiped", - "worshipper", "worshiper", - "aeroplane", "airplane", - "aetiology", "etiology", - "agonising", "agonizing", - "almanacks", "almanacs", - "aluminium", "aluminum", - "amortised", "amortized", - "amortises", "amortizes", - "analogues", "analogs", - "analysing", "analyzing", - "anglicise", "anglicize", - "apologise", "apologize", - "appetiser", "appetizer", - "armourers", "armorers", - "armouries", "armories", - "artefacts", "artifacts", - "authorise", "authorize", - "baptising", "baptizing", - "behaviour", "behavior", - "belabours", "belabors", - "brutalise", "brutalize", - "callipers", "calipers", - "canalised", "canalized", - "canalises", "canalizes", - "cancelled", "canceled", - "canonised", "canonized", - "canonises", "canonizes", - "carbonise", "carbonize", - "carolling", "caroling", - "catalogue", "catalog", - "catalysed", "catalyzed", - "catalyses", "catalyzes", - "cauterise", "cauterize", - "cavilling", "caviling", - "chequered", "checkered", - "chiselled", "chiseled", - "civilised", "civilized", - "civilises", "civilizes", - "clamoured", "clamored", - "colonised", "colonized", - "coloniser", "colonizer", - "colonises", "colonizes", - "colourant", "colorant", - "coloureds", "coloreds", - "colourful", "colorful", - "colouring", "coloring", - "colourize", "colorize", - "connexion", "connection", - "criticise", "criticize", - "cruellest", "cruelest", - "cudgelled", "cudgeled", - "customise", "customize", - "demeanour", "demeanor", - "demonised", "demonized", - "demonises", "demonizes", - "deodorise", "deodorize", - "deputised", "deputized", - "deputises", "deputizes", - "dialogues", "dialogs", - "diarrhoea", "diarrhea", - "digitised", "digitized", - "digitises", "digitizes", - "discolour", "discolor", - "disfavour", "disfavor", - "dishonour", "dishonor", - "dramatise", "dramatize", - "drivelled", "driveled", - "economise", "economize", - "empathise", "empathize", - "emphasise", "emphasize", - "enamelled", "enameled", - "enamoured", "enamored", - "endeavour", "endeavor", - "energised", "energized", - "energises", "energizes", - "epaulette", "epaulet", - "epicentre", "epicenter", - "epitomise", "epitomize", - "equalised", "equalized", - "equaliser", "equalizer", - "equalises", "equalizes", - "eulogised", "eulogized", - "eulogises", "eulogizes", - "factorise", "factorize", - "fantasise", "fantasize", - "favouring", "favoring", - "favourite", "favorite", - "feminised", "feminized", - "feminises", "feminizes", - "fertilise", "fertilize", - "finalised", "finalized", - "finalises", "finalizes", - "flautists", "flutists", - "flavoured", "flavored", - "formalise", "formalize", - "fossilise", "fossilize", - "funnelled", "funneled", - "galvanise", "galvanize", - "gambolled", "gamboled", - "gaolbirds", "jailbirds", - "gaolbreak", "jailbreak", - "ghettoise", "ghettoize", - "globalise", "globalize", - "gravelled", "graveled", - "grovelled", "groveled", - "gruelling", "grueling", - "harboured", "harbored", - "harmonise", "harmonize", - "honouring", "honoring", - "humanised", "humanized", - "humanises", "humanizes", - "humouring", "humoring", - "hybridise", "hybridize", - "hypnotise", "hypnotize", - "idealised", "idealized", - "idealises", "idealizes", - "idolising", "idolizing", - "immunised", "immunized", - "immunises", "immunizes", - "inflexion", "inflection", - "italicise", "italicize", - "itemising", "itemizing", - "jewellers", "jewelers", - "jewellery", "jewelry", - "kilometre", "kilometer", - "labelling", "labeling", - "labourers", "laborers", - "labouring", "laboring", - "legalised", "legalized", - "legalises", "legalizes", - "leukaemia", "leukemia", - "levellers", "levelers", - "levelling", "leveling", - "libelling", "libeling", - "libellous", "libelous", - "licencing", "licensing", - "lionising", "lionizing", - "liquidise", "liquidize", - "localised", "localized", - "localises", "localizes", - "magnetise", "magnetize", - "manoeuvre", "maneuver", - "marvelled", "marveled", - "maximised", "maximized", - "maximises", "maximizes", - "mechanise", "mechanize", - "mediaeval", "medieval", - "memorised", "memorized", - "memorises", "memorizes", - "mesmerise", "mesmerize", - "minimised", "minimized", - "minimises", "minimizes", - "mobilised", "mobilized", - "mobilises", "mobilizes", - "modellers", "modelers", - "modelling", "modeling", - "modernise", "modernize", - "moralised", "moralized", - "moralises", "moralizes", - "motorised", "motorized", - "mouldered", "moldered", - "mouldiest", "moldiest", - "mouldings", "moldings", - "moustache", "mustache", - "neighbour", "neighbor", - "normalise", "normalize", - "odourless", "odorless", - "oestrogen", "estrogen", - "optimised", "optimized", - "optimises", "optimizes", - "organised", "organized", - "organiser", "organizer", - "organises", "organizes", - "ostracise", "ostracize", - "oxidising", "oxidizing", - "paederast", "pederast", - "panelling", "paneling", - "panellist", "panelist", - "paralysed", "paralyzed", - "paralyses", "paralyzes", - "parcelled", "parceled", - "passivise", "passivize", - "patronise", "patronize", - "pedalling", "pedaling", - "penalised", "penalized", - "penalises", "penalizes", - "pencilled", "penciled", - "ploughing", "plowing", - "ploughman", "plowman", - "ploughmen", "plowmen", - "polarised", "polarized", - "polarises", "polarizes", - "practised", "practiced", - "practises", "practices", - "pretences", "pretenses", - "primaeval", "primeval", - "privatise", "privatize", - "programme", "program", - "publicise", "publicize", - "pulverise", "pulverize", - "pummelled", "pummel", - "randomise", "randomize", - "ravelling", "raveling", - "realising", "realizing", - "recognise", "recognize", - "refuelled", "refueled", - "remoulded", "remolded", - "revellers", "revelers", - "revelling", "reveling", - "rivalling", "rivaling", - "saltpetre", "saltpeter", - "sanitised", "sanitized", - "sanitises", "sanitizes", - "satirised", "satirized", - "satirises", "satirizes", - "savouries", "savories", - "savouring", "savoring", - "sceptical", "skeptical", - "sensitise", "sensitize", - "sepulchre", "sepulcher", - "serialise", "serialize", - "sermonise", "sermonize", - "shovelled", "shoveled", - "signalise", "signalize", - "signalled", "signaled", - "snivelled", "sniveled", - "socialise", "socialize", - "sodomised", "sodomized", - "sodomises", "sodomizes", - "solemnise", "solemnize", - "spiralled", "spiraled", - "splendour", "splendor", - "stabilise", "stabilize", - "sterilise", "sterilize", - "subsidise", "subsidize", - "succoured", "succored", - "sulphates", "sulfates", - "sulphides", "sulfides", - "summarise", "summarize", - "swivelled", "swiveled", - "symbolise", "symbolize", - "syphoning", "siphoning", - "tantalise", "tantalize", - "tasselled", "tasseled", - "temporise", "temporize", - "tenderise", "tenderize", - "terrorise", "terrorize", - "theorised", "theorized", - "theorises", "theorizes", - "towelling", "toweling", - "travelled", "traveled", - "traveller", "traveler", - "trialling", "trialing", - "tricolour", "tricolor", - "tunnelled", "tunneled", - "tyrannise", "tyrannize", - "unionised", "unionized", - "unionises", "unionizes", - "unsavoury", "unsavory", - "urbanised", "urbanized", - "urbanises", "urbanizes", - "utilising", "utilizing", - "vandalise", "vandalize", - "vaporised", "vaporized", - "vaporises", "vaporizes", - "verbalise", "verbalize", - "victimise", "victimize", - "visualise", "visualize", - "vocalised", "vocalized", - "vocalises", "vocalizes", - "vulgarise", "vulgarize", - "weaselled", "weaseled", - "womanised", "womanized", - "womaniser", "womanizer", - "womanises", "womanizes", - "yodelling", "yodeling", - "yoghourts", "yogurts", - "agonised", "agonized", - "agonises", "agonizes", - "almanack", "almanac", - "amortise", "amortize", - "analogue", "analog", - "analysed", "analyzed", - "armoured", "armored", - "armourer", "armorer", - "artefact", "artifact", - "baptised", "baptized", - "baptises", "baptizes", - "baulking", "balking", - "belabour", "belabor", - "bevelled", "beveled", - "calibres", "calibers", - "calliper", "caliper", - "canalise", "canalize", - "canonise", "canonize", - "carolled", "caroled", - "catalyse", "catalyze", - "cavilled", "caviled", - "civilise", "civilize", - "clamours", "clamors", - "clangour", "clangor", - "colonise", "colonize", - "coloured", "colored", - "cosiness", "coziness", - "crueller", "crueler", - "defences", "defenses", - "demonise", "demonize", - "deputise", "deputize", - "dialling", "dialing", - "dialogue", "dialog", - "digitise", "digitize", - "draughty", "drafty", - "duelling", "dueling", - "energise", "energize", - "enthrals", "enthralls", - "equalise", "equalize", - "eulogise", "eulogize", - "favoured", "favored", - "feminise", "feminize", - "finalise", "finalize", - "flautist", "flutist", - "flavours", "flavors", - "foetuses", "fetuses", - "fuelling", "fueling", - "gaolbird", "jailbird", - "gryphons", "griffins", - "harbours", "harbors", - "honoured", "honored", - "humanise", "humanize", - "humoured", "humored", - "idealise", "idealize", - "idolised", "idolized", - "idolises", "idolizes", - "immunise", "immunize", - "ionisers", "ionizers", - "ionising", "ionizing", - "itemised", "itemized", - "itemises", "itemizes", - "jewelled", "jeweled", - "jeweller", "jeweler", - "labelled", "labeled", - "laboured", "labored", - "labourer", "laborer", - "legalise", "legalize", - "levelled", "leveled", - "leveller", "leveler", - "libelled", "libeled", - "licenced", "licensed", - "licences", "licenses", - "lionised", "lionized", - "lionises", "lionizes", - "localise", "localize", - "maximise", "maximize", - "memorise", "memorize", - "minimise", "minimize", - "misspelt", "misspelled", - "mobilise", "mobilize", - "modelled", "modeled", - "modeller", "modeler", - "moralise", "moralize", - "moulders", "molders", - "mouldier", "moldier", - "moulding", "molding", - "moulting", "molting", - "offences", "offenses", - "optimise", "optimize", - "organise", "organize", - "oxidised", "oxidized", - "oxidises", "oxidizes", - "panelled", "paneled", - "paralyse", "paralyze", - "parlours", "parlors", - "pedalled", "pedaled", - "penalise", "penalize", - "philtres", "filters", - "ploughed", "plowed", - "polarise", "polarize", - "practise", "practice", - "pretence", "pretense", - "ravelled", "raveled", - "realised", "realized", - "realises", "realizes", - "remoulds", "remolds", - "revelled", "reveled", - "reveller", "reveler", - "rivalled", "rivaled", - "rumoured", "rumored", - "sanitise", "sanitize", - "satirise", "satirize", - "saviours", "saviors", - "savoured", "savored", - "sceptics", "skeptics", - "sceptres", "scepters", - "sodomise", "sodomize", - "spectres", "specters", - "succours", "succors", - "sulphate", "sulfate", - "sulphide", "sulfide", - "syphoned", "siphoned", - "theatres", "theaters", - "theorise", "theorize", - "towelled", "toweled", - "toxaemia", "toxemia", - "trialled", "trialed", - "unionise", "unionize", - "urbanise", "urbanize", - "utilised", "utilized", - "utilises", "utilizes", - "vaporise", "vaporize", - "vocalise", "vocalize", - "womanise", "womanize", - "yodelled", "yodeled", - "yoghourt", "yogurt", - "yoghurts", "yogurts", - "agonise", "agonize", - "anaemia", "anemia", - "anaemic", "anemic", - "analyse", "analyze", - "arbours", "arbors", - "armoury", "armory", - "baptise", "baptize", - "baulked", "balked", - "behoved", "behooved", - "behoves", "behooves", - "calibre", "caliber", - "candour", "candor", - "centred", "centered", - "centres", "centers", - "cheques", "checks", - "clamour", "clamor", - "colours", "colors", - "cosiest", "coziest", - "defence", "defense", - "dialled", "dialed", - "distils", "distills", - "duelled", "dueled", - "enthral", "enthrall", - "favours", "favors", - "fervour", "fervor", - "flavour", "flavor", - "fuelled", "fueled", - "fulfils", "fulfills", - "gaolers", "jailers", - "gaoling", "jailing", - "gipsies", "gypsies", - "glueing", "gluing", - "goitres", "goiters", - "grammes", "grams", - "groynes", "groins", - "gryphon", "griffin", - "harbour", "harbor", - "honours", "honors", - "humours", "humors", - "idolise", "idolize", - "instals", "installs", - "instils", "instills", - "ionised", "ionized", - "ioniser", "ionizer", - "ionises", "ionizes", - "itemise", "itemize", - "labours", "labors", - "licence", "license", - "lionise", "lionize", - "louvred", "louvered", - "louvres", "louvers", - "moulded", "molded", - "moulder", "molder", - "moulted", "molted", - "offence", "offense", - "oxidise", "oxidize", - "parlour", "parlor", - "philtre", "filter", - "ploughs", "plows", - "pyjamas", "pajamas", - "rancour", "rancor", - "realise", "realize", - "remould", "remold", - "rigours", "rigors", - "rumours", "rumors", - "saviour", "savior", - "savours", "savors", - "savoury", "savory", - "sceptic", "skeptic", - "sceptre", "scepter", - "spectre", "specter", - "storeys", "stories", - "succour", "succor", - "sulphur", "sulfur", - "syphons", "siphons", - "theatre", "theater", - "tumours", "tumors", - "utilise", "utilize", - "vapours", "vapors", - "waggons", "wagons", - "yoghurt", "yogurt", - "ageing", "aging", - "appals", "appalls", - "arbour", "arbor", - "ardour", "ardor", - "baulks", "balks", - "behove", "behoove", - "centre", "center", - "cheque", "check", - "chilli", "chili", - "colour", "color", - "cosier", "cozier", - "cosies", "cozies", - "cosily", "cozily", - "distil", "distill", - "edoema", "edema", - "enrols", "enrolls", - "faecal", "fecal", - "faeces", "feces", - "favour", "favor", - "fibres", "fibers", - "foetal", "fetal", - "foetid", "fetid", - "foetus", "fetus", - "fulfil", "fulfill", - "gaoled", "jailed", - "gaoler", "jailer", - "goitre", "goiter", - "gramme", "gram", - "groyne", "groin", - "honour", "honor", - "humour", "humor", - "instal", "install", - "instil", "instill", - "ionise", "ionize", - "labour", "labor", - "litres", "liters", - "lustre", "luster", - "meagre", "meager", - "metres", "meters", - "mitres", "miters", - "moulds", "molds", - "mouldy", "moldy", - "moults", "molts", - "odours", "odors", - "plough", "plow", - "pyjama", "pajama", - "rigour", "rigor", - "rumour", "rumor", - "savour", "savor", - "storey", "story", - "syphon", "siphon", - "tumour", "tumor", - "valour", "valor", - "vapour", "vapor", - "vigour", "vigor", - "waggon", "wagon", - "appal", "appall", - "baulk", "balk", - "enrol", "enroll", - "fibre", "fiber", - "gaols", "jails", - "litre", "liter", - "metre", "meter", - "mitre", "miter", - "mould", "mold", - "moult", "molt", - "odour", "odor", - "tyres", "tires", - "cosy", "cozy", - "gaol", "jail", - "tyre", "tire", -} diff --git a/vendor/github.com/golangci/plugin-module-register/LICENSE b/vendor/github.com/golangci/plugin-module-register/LICENSE deleted file mode 100644 index cbdf3d374d..0000000000 --- a/vendor/github.com/golangci/plugin-module-register/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2024 GolangCI Authors - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/golangci/plugin-module-register/register/register.go b/vendor/github.com/golangci/plugin-module-register/register/register.go deleted file mode 100644 index 72ad7f46f2..0000000000 --- a/vendor/github.com/golangci/plugin-module-register/register/register.go +++ /dev/null @@ -1,73 +0,0 @@ -package register - -import ( - "bytes" - "encoding/json" - "fmt" - "sync" - - "golang.org/x/tools/go/analysis" -) - -// Plugins load mode. -const ( - LoadModeSyntax = "syntax" - LoadModeTypesInfo = "typesinfo" -) - -var ( - pluginsMu sync.RWMutex - plugins = make(map[string]NewPlugin) -) - -// LinterPlugin the interface of the plugin structure. -type LinterPlugin interface { - BuildAnalyzers() ([]*analysis.Analyzer, error) - GetLoadMode() string -} - -// NewPlugin the contract of the constructor of a plugin. -type NewPlugin func(conf any) (LinterPlugin, error) - -// Plugin registers a plugin. -func Plugin(name string, p NewPlugin) { - pluginsMu.Lock() - - plugins[name] = p - - pluginsMu.Unlock() -} - -// GetPlugin gets a plugin by name. -func GetPlugin(name string) (NewPlugin, error) { - pluginsMu.Lock() - defer pluginsMu.Unlock() - - p, ok := plugins[name] - if !ok { - return nil, fmt.Errorf("plugin %q not found", name) - } - - return p, nil -} - -// DecodeSettings decode settings from golangci-lint to the structure of the plugin configuration. -func DecodeSettings[T any](rawSettings any) (T, error) { - var buffer bytes.Buffer - - if err := json.NewEncoder(&buffer).Encode(rawSettings); err != nil { - var zero T - return zero, fmt.Errorf("encoding settings: %w", err) - } - - decoder := json.NewDecoder(&buffer) - decoder.DisallowUnknownFields() - - s := new(T) - if err := decoder.Decode(s); err != nil { - var zero T - return zero, fmt.Errorf("decoding settings: %w", err) - } - - return *s, nil -} diff --git a/vendor/github.com/golangci/revgrep/.gitignore b/vendor/github.com/golangci/revgrep/.gitignore deleted file mode 100644 index 0540fe2caf..0000000000 --- a/vendor/github.com/golangci/revgrep/.gitignore +++ /dev/null @@ -1 +0,0 @@ -testdata/git diff --git a/vendor/github.com/golangci/revgrep/.golangci.yml b/vendor/github.com/golangci/revgrep/.golangci.yml deleted file mode 100644 index f08807b12b..0000000000 --- a/vendor/github.com/golangci/revgrep/.golangci.yml +++ /dev/null @@ -1,71 +0,0 @@ -linters: - enable-all: true - disable: - - exportloopref # deprecated - - cyclop # duplicate of gocyclo - - sqlclosecheck # not relevant (SQL) - - rowserrcheck # not relevant (SQL) - - dupl - - lll - - nestif - - mnd - - err113 - - nlreturn - - wsl - - exhaustive - - exhaustruct - - tparallel - - testpackage - - paralleltest - - forcetypeassert - - varnamelen - - prealloc # false-positives - - nonamedreturns - - nilerr - - depguard - -linters-settings: - govet: - enable-all: true - disable: - - fieldalignment - gocyclo: - min-complexity: 30 # 30 by default (but we recommend 10-20) - goconst: - min-len: 3 - min-occurrences: 3 - misspell: - locale: US - funlen: - lines: -1 - statements: 80 # default 40 - gocognit: - min-complexity: 65 # default 30 - gofumpt: - extra-rules: true - godox: - keywords: - - FIXME - gosec: - excludes: - - G115 # integer overflow conversion - -issues: - exclude-use-default: false - max-issues-per-linter: 0 - max-same-issues: 0 - exclude: - - 'ST1000: at least one file in a package should have a package comment' - exclude-rules: - - path: (.+)_test.go - linters: - - funlen - - goconst - - gosec - - maintidx - - path: cmd/revgrep/main.go - linters: - - forbidigo - -run: - timeout: 2m diff --git a/vendor/github.com/golangci/revgrep/LICENSE b/vendor/github.com/golangci/revgrep/LICENSE deleted file mode 100644 index 8dada3edaf..0000000000 --- a/vendor/github.com/golangci/revgrep/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/golangci/revgrep/Makefile b/vendor/github.com/golangci/revgrep/Makefile deleted file mode 100644 index 5ac8725d00..0000000000 --- a/vendor/github.com/golangci/revgrep/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -.PHONY: clean lint lint-fix test - -default: lint test - -test: - go test -v -cover ./... - -lint: - golangci-lint run - -lint-fix: - golangci-lint run --fix diff --git a/vendor/github.com/golangci/revgrep/README.md b/vendor/github.com/golangci/revgrep/README.md deleted file mode 100644 index c776cb4519..0000000000 --- a/vendor/github.com/golangci/revgrep/README.md +++ /dev/null @@ -1,55 +0,0 @@ -## Overview - -`revgrep` is a CLI tool used to filter static analysis tools to only lines changed based on a commit reference. - -## Install - -```bash -go install github.com/golangci/revgrep/cmd/revgrep@latest -``` - -## Usage - -In the scenario below, a change was made causing a warning in `go vet` on line 5, but `go vet` will show all warnings. -Using `revgrep`, you can show only warnings for lines of code that have been changed (in this case, hiding line 6). - -```bash -[user@host dir (master)]$ go vet -main.go:5: missing argument for Sprintf("%s"): format reads arg 1, have only 0 args -main.go:6: missing argument for Sprintf("%s"): format reads arg 1, have only 0 args -[user@host dir (master)]$ go vet |& revgrep -main.go:5: missing argument for Sprintf("%s"): format reads arg 1, have only 0 args -``` - -`|&` is shown above as many static analysis programs write to `stderr`, not `stdout`, `|&` combines both `stderr` and -`stdout`. It could also be achieved with `go vet 2>&1 | revgrep`. - -`revgrep` CLI tool will return an exit status of 1 if any issues match, else it will return 0. Consider using -`${PIPESTATUS[0]}` for the exit status of the `go vet` command in the above example. - -``` -Usage: revgrep [options] [from-rev] [to-rev] - -from-rev filters issues to lines changed since (and including) this revision - to-rev filters issues to lines changed since (and including) this revision, requires - - If no revisions are given, and there are unstaged changes or untracked files, only those changes are shown - If no revisions are given, and there are no unstaged changes or untracked files, only changes in HEAD~ are shown - If from-rev is given and to-rev is not, only changes between from-rev and HEAD are shown. - - -d Show debug output - -regexp string - Regexp to match path, line number, optional column number, and message -``` - -## Other Examples - -Issues between branches: -```bash -[user@host dir (feature/branch)]$ go vet |& revgrep master -``` - -Issues since last push: -```bash -[user@host dir (master)]$ go vet |& revgrep origin/master -``` diff --git a/vendor/github.com/golangci/revgrep/issue.go b/vendor/github.com/golangci/revgrep/issue.go deleted file mode 100644 index 694d416390..0000000000 --- a/vendor/github.com/golangci/revgrep/issue.go +++ /dev/null @@ -1,37 +0,0 @@ -package revgrep - -// Issue contains metadata about an issue found. -type Issue struct { - // File is the name of the file as it appeared from the patch. - File string - // LineNo is the line number of the file. - LineNo int - // ColNo is the column number or 0 if none could be parsed. - ColNo int - // HunkPos is position from file's first @@, for new files this will be the line number. - // See also: https://developer.github.com/v3/pulls/comments/#create-a-comment - HunkPos int - // Issue text as it appeared from the tool. - Issue string - // Message is the issue without file name, line number and column number. - Message string -} - -// InputIssue represents issue found by some linter. -type InputIssue interface { - FilePath() string - Line() int -} - -type simpleInputIssue struct { - filePath string - lineNumber int -} - -func (i simpleInputIssue) FilePath() string { - return i.filePath -} - -func (i simpleInputIssue) Line() int { - return i.lineNumber -} diff --git a/vendor/github.com/golangci/revgrep/patch.go b/vendor/github.com/golangci/revgrep/patch.go deleted file mode 100644 index 81a2acd7e5..0000000000 --- a/vendor/github.com/golangci/revgrep/patch.go +++ /dev/null @@ -1,195 +0,0 @@ -package revgrep - -import ( - "bytes" - "context" - "errors" - "fmt" - "io" - "os/exec" - "regexp" - "strconv" - "strings" -) - -type patchOption struct { - revisionFrom string - revisionTo string - mergeBase string -} - -// GitPatch returns a patch from a git repository. -// If no git repository was found and no errors occurred, nil is returned, -// else an error is returned revisionFrom and revisionTo defines the git diff parameters, -// if left blank and there are unstaged changes or untracked files, -// only those will be returned else only check changes since HEAD~. -// If revisionFrom is set but revisionTo is not, -// untracked files will be included, to exclude untracked files set revisionTo to HEAD~. -// It's incorrect to specify revisionTo without a revisionFrom. -func GitPatch(ctx context.Context, option patchOption) (io.Reader, []string, error) { - // check if git repo exists - if err := exec.CommandContext(ctx, "git", "status", "--porcelain").Run(); err != nil { - // don't return an error, we assume the error is not repo exists - return nil, nil, nil - } - - // make a patch for untracked files - ls, err := exec.CommandContext(ctx, "git", "ls-files", "--others", "--exclude-standard").CombinedOutput() - if err != nil { - return nil, nil, fmt.Errorf("error executing git ls-files: %w", err) - } - - var newFiles []string - for _, file := range bytes.Split(ls, []byte{'\n'}) { - if len(file) == 0 || bytes.HasSuffix(file, []byte{'/'}) { - // ls-files was sometimes showing directories when they were ignored - // I couldn't create a test case for this as I couldn't reproduce correctly for the moment, - // just exclude files with trailing / - continue - } - - newFiles = append(newFiles, string(file)) - } - - if option.mergeBase != "" { - var base string - base, err = getMergeBase(ctx, option.mergeBase) - if err != nil { - return nil, nil, err - } - - if base != "" { - option.revisionFrom = base - } - } - - if option.revisionFrom != "" { - args := []string{option.revisionFrom} - - if option.revisionTo != "" { - args = append(args, option.revisionTo) - } - - args = append(args, "--") - - patch, errDiff := gitDiff(ctx, args...) - if errDiff != nil { - return nil, nil, errDiff - } - - if option.revisionTo == "" { - return patch, newFiles, nil - } - - return patch, nil, nil - } - - // make a patch for unstaged changes - patch, err := gitDiff(ctx, "--") - if err != nil { - return nil, nil, err - } - - unstaged := patch.Len() > 0 - - // If there's unstaged changes OR untracked changes (or both), - // then this is a suitable patch - if unstaged || newFiles != nil { - return patch, newFiles, nil - } - - // check for changes in recent commit - patch, err = gitDiff(ctx, "HEAD~", "--") - if err != nil { - return nil, nil, err - } - - return patch, nil, nil -} - -func gitDiff(ctx context.Context, extraArgs ...string) (*bytes.Buffer, error) { - cmd := exec.CommandContext(ctx, "git", "diff", "--color=never", "--no-ext-diff") - - if isSupportedByGit(ctx, 2, 41, 0) { - cmd.Args = append(cmd.Args, "--default-prefix") - } - - cmd.Args = append(cmd.Args, "--relative") - cmd.Args = append(cmd.Args, extraArgs...) - - patch := new(bytes.Buffer) - errBuff := new(bytes.Buffer) - - cmd.Stdout = patch - cmd.Stderr = errBuff - - if err := cmd.Run(); err != nil { - return nil, fmt.Errorf("error executing %q: %w: %w", strings.Join(cmd.Args, " "), err, readAsError(errBuff)) - } - - return patch, nil -} - -func readAsError(buff io.Reader) error { - output, err := io.ReadAll(buff) - if err != nil { - return fmt.Errorf("read stderr: %w", err) - } - - return errors.New(string(output)) -} - -func isSupportedByGit(ctx context.Context, major, minor, patch int) bool { - output, err := exec.CommandContext(ctx, "git", "version").CombinedOutput() - if err != nil { - return false - } - - parts := bytes.Split(bytes.TrimSpace(output), []byte(" ")) - if len(parts) < 3 { - return false - } - - v := string(parts[2]) - if v == "" { - return false - } - - vp := regexp.MustCompile(`^(\d+)\.(\d+)(?:\.(\d+))?.*$`).FindStringSubmatch(v) - if len(vp) < 4 { - return false - } - - currentMajor, err := strconv.Atoi(vp[1]) - if err != nil { - return false - } - - currentMinor, err := strconv.Atoi(vp[2]) - if err != nil { - return false - } - - currentPatch, err := strconv.Atoi(vp[3]) - if err != nil { - return false - } - - return currentMajor*1_000_000_000+currentMinor*1_000_000+currentPatch*1_000 >= major*1_000_000_000+minor*1_000_000+patch*1_000 -} - -func getMergeBase(ctx context.Context, base string) (string, error) { - cmd := exec.CommandContext(ctx, "git", "merge-base", base, "HEAD") - - patch := new(bytes.Buffer) - errBuff := new(bytes.Buffer) - - cmd.Stdout = patch - cmd.Stderr = errBuff - - if err := cmd.Run(); err != nil { - return "", fmt.Errorf("error executing %q: %w: %w", strings.Join(cmd.Args, " "), err, readAsError(errBuff)) - } - - return strings.TrimSpace(patch.String()), nil -} diff --git a/vendor/github.com/golangci/revgrep/revgrep.go b/vendor/github.com/golangci/revgrep/revgrep.go deleted file mode 100644 index ca4ac791c8..0000000000 --- a/vendor/github.com/golangci/revgrep/revgrep.go +++ /dev/null @@ -1,344 +0,0 @@ -// Package revgrep filter static analysis tools to only lines changed based on a commit reference. -package revgrep - -import ( - "bufio" - "context" - "errors" - "fmt" - "io" - "os" - "path/filepath" - "regexp" - "strconv" - "strings" -) - -// Checker provides APIs to filter static analysis tools to specific commits, -// such as showing only issues since last commit. -type Checker struct { - // Patch file (unified) to read to detect lines being changed, - // if nil revgrep will attempt to detect the VCS and generate an appropriate patch. - // Auto-detection will search for uncommitted changes first, - // if none found, will generate a patch from last committed change. - // File paths within patches must be relative to current working directory. - Patch io.Reader - // NewFiles is a list of file names (with absolute paths) where the entire contents of the file is new. - NewFiles []string - // Debug sets the debug writer for additional output. - Debug io.Writer - // RevisionFrom check revision starting at, leave blank for auto-detection ignored if patch is set. - RevisionFrom string - // RevisionTo checks revision finishing at, leave blank for auto-detection ignored if patch is set. - RevisionTo string - // MergeBase checks revision starting at the best common ancestor, leave blank for auto-detection ignored if patch is set. - MergeBase string - // WholeFiles indicates that the user wishes to see all issues that comes up anywhere in any file that has been changed in this revision or patch. - WholeFiles bool - // Regexp to match path, line number, optional column number, and message. - Regexp string - // AbsPath is used to make an absolute path of an issue's filename to be relative in order to match patch file. - // If not set, current working directory is used. - AbsPath string - - // Calculated changes for next calls to [Checker.IsNewIssue]/[Checker.IsNew]. - changes map[string][]pos -} - -// Prepare extracts a patch and changed lines. -// -// WARNING: it should only be used before an explicit call to [Checker.IsNewIssue]/[Checker.IsNew]. -// -// WARNING: only [Checker.Patch], [Checker.RevisionFrom], [Checker.RevisionTo], [Checker.WholeFiles] options are used, -// the other options ([Checker.Regexp], [Checker.AbsPath]) are only used by [Checker.Check]. -func (c *Checker) Prepare(ctx context.Context) error { - err := c.loadPatch(ctx) - - c.changes = c.linesChanged() - - return err -} - -// IsNew checks whether issue found by linter is new: it was found in changed lines. -// -// WARNING: it requires to call [Checker.Prepare] before call this method to load the changes from patch. -func (c *Checker) IsNew(filePath string, line int) (hunkPos int, isNew bool) { - changes, ok := c.changes[filepath.ToSlash(filePath)] - if !ok { - // file wasn't changed - return 0, false - } - - if c.WholeFiles { - return line, true - } - - var ( - fpos pos - changed bool - ) - - // found file, see if lines matched - for _, pos := range changes { - if pos.lineNo == line { - fpos = pos - changed = true - - break - } - } - - if changed || changes == nil { - // either file changed or it's a new file - hunkPos := fpos.lineNo - - // existing file changed - if changed { - hunkPos = fpos.hunkPos - } - - return hunkPos, true - } - - return 0, false -} - -// IsNewIssue checks whether issue found by linter is new: it was found in changed lines. -// -// WARNING: it requires to call [Checker.Prepare] before call this method to load the changes from patch. -func (c *Checker) IsNewIssue(i InputIssue) (hunkPos int, isNew bool) { - return c.IsNew(i.FilePath(), i.Line()) -} - -// Check scans reader and writes any lines to writer that have been added in [Checker.Patch]. -// -// Returns the issues written to writer when no error occurs. -// -// If no VCS could be found or other VCS errors occur, -// all issues are written to writer and an error is returned. -// -// File paths in reader must be relative to current working directory or absolute. -func (c *Checker) Check(ctx context.Context, reader io.Reader, writer io.Writer) (issues []Issue, err error) { - errPrepare := c.Prepare(ctx) - - writeAll := errPrepare != nil - - // file.go:lineNo:colNo:message - // colNo is optional, strip spaces before message - lineRE := regexp.MustCompile(`(.+\.go):([0-9]+):([0-9]+)?:?\s*(.*)`) - if c.Regexp != "" { - lineRE, err = regexp.Compile(c.Regexp) - if err != nil { - return nil, fmt.Errorf("could not parse regexp: %w", err) - } - } - - // TODO consider lazy loading this, if there's nothing in stdin, no point - // checking for recent changes - c.debugf("lines changed: %+v", c.changes) - - absPath := c.AbsPath - if absPath == "" { - absPath, err = os.Getwd() - if err != nil { - errPrepare = fmt.Errorf("could not get current working directory: %w", err) - } - } - - // Scan each line in reader and only write those lines if lines changed - scanner := bufio.NewScanner(reader) - for scanner.Scan() { - line := lineRE.FindSubmatch(scanner.Bytes()) - if line == nil { - c.debugf("cannot parse file+line number: %s", scanner.Text()) - continue - } - - if writeAll { - _, _ = fmt.Fprintln(writer, scanner.Text()) - continue - } - - // Make absolute path names relative - path := string(line[1]) - if rel, err := filepath.Rel(absPath, path); err == nil { - c.debugf("rewrote path from %q to %q (absPath: %q)", path, rel, absPath) - path = rel - } - - // Parse line number - lno, err := strconv.ParseUint(string(line[2]), 10, 64) - if err != nil { - c.debugf("cannot parse line number: %q", scanner.Text()) - continue - } - - // Parse optional column number - var cno uint64 - if len(line[3]) > 0 { - cno, err = strconv.ParseUint(string(line[3]), 10, 64) - if err != nil { - c.debugf("cannot parse column number: %q", scanner.Text()) - // Ignore this error and continue - } - } - - // Extract message - msg := string(line[4]) - - c.debugf("path: %q, lineNo: %v, colNo: %v, msg: %q", path, lno, cno, msg) - - simpleIssue := simpleInputIssue{filePath: path, lineNumber: int(lno)} - - hunkPos, changed := c.IsNewIssue(simpleIssue) - if changed { - issue := Issue{ - File: path, - LineNo: int(lno), - ColNo: int(cno), - HunkPos: hunkPos, - Issue: scanner.Text(), - Message: msg, - } - issues = append(issues, issue) - - _, _ = fmt.Fprintln(writer, scanner.Text()) - } else { - c.debugf("unchanged: %s", scanner.Text()) - } - } - - if err := scanner.Err(); err != nil { - errPrepare = fmt.Errorf("error reading standard input: %w", err) - } - - return issues, errPrepare -} - -func (c *Checker) debugf(format string, s ...any) { - if c.Debug == nil { - return - } - - _, _ = fmt.Fprint(c.Debug, "DEBUG: ") - _, _ = fmt.Fprintf(c.Debug, format+"\n", s...) -} - -// loadPatch checks if patch is supplied, if not, retrieve from VCS. -func (c *Checker) loadPatch(ctx context.Context) error { - if c.Patch != nil { - return nil - } - - option := patchOption{ - revisionFrom: c.RevisionFrom, - revisionTo: c.RevisionTo, - mergeBase: c.MergeBase, - } - - var err error - c.Patch, c.NewFiles, err = GitPatch(ctx, option) - if err != nil { - return fmt.Errorf("could not read git repo: %w", err) - } - - if c.Patch == nil { - return errors.New("no version control repository found") - } - - return nil -} - -// linesChanges returns a map of file names to line numbers being changed. -// If key is nil, the file has been recently added, else it contains a slice of positions that have been added. -func (c *Checker) linesChanged() map[string][]pos { - type state struct { - file string - lineNo int // current line number within chunk - hunkPos int // current line count since first @@ in file - changes []pos // position of changes - } - - changes := make(map[string][]pos) - - for _, file := range c.NewFiles { - changes[file] = nil - } - - if c.Patch == nil { - return changes - } - - var s state - - scanner := bufio.NewReader(c.Patch) - var scanErr error - for { - lineB, isPrefix, err := scanner.ReadLine() - if isPrefix { - // If a single line overflowed the buffer, don't bother processing it as - // it's likey part of a file and not relevant to the patch. - continue - } - - if err != nil { - scanErr = err - break - } - - line := strings.TrimRight(string(lineB), "\n") - - c.debugf(line) - - s.lineNo++ - s.hunkPos++ - - switch { - case strings.HasPrefix(line, "+++ ") && len(line) > 4: - if s.changes != nil { - // record the last state - changes[s.file] = s.changes - } - // 6 removes "+++ b/" - s = state{file: line[6:], hunkPos: -1, changes: []pos{}} - - case strings.HasPrefix(line, "@@ "): - // @@ -1 +2,4 @@ - // chdr ^^^^^^^^^^^^^ - // ahdr ^^^^ - // cstart ^ - chdr := strings.Split(line, " ") - ahdr := strings.Split(chdr[2], ",") - - // [1:] to remove leading plus - cstart, err := strconv.ParseUint(ahdr[0][1:], 10, 64) - if err != nil { - panic(err) - } - - s.lineNo = int(cstart) - 1 // -1 as cstart is the next line number - - case strings.HasPrefix(line, "-"): - s.lineNo-- - - case strings.HasPrefix(line, "+"): - s.changes = append(s.changes, pos{lineNo: s.lineNo, hunkPos: s.hunkPos}) - } - } - - if !errors.Is(scanErr, io.EOF) { - _, _ = fmt.Fprintln(os.Stderr, "reading standard input:", scanErr) - } - - // record the last state - changes[s.file] = s.changes - - return changes -} - -type pos struct { - // Line number. - lineNo int - // Position relative to first @@ in file. - hunkPos int -} diff --git a/vendor/github.com/golangci/swaggoswag/.gitignore b/vendor/github.com/golangci/swaggoswag/.gitignore deleted file mode 100644 index 865a6f357f..0000000000 --- a/vendor/github.com/golangci/swaggoswag/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -dist -testdata/simple*/docs -testdata/quotes/docs -testdata/quotes/quotes.so -testdata/delims/docs -testdata/delims/delims.so -example/basic/docs/* -example/celler/docs/* -cover.out - - -# Test binary, build with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out -.idea -.vscode - -# Etc -.DS_Store - -/swag -/swag.exe diff --git a/vendor/github.com/golangci/swaggoswag/formatter.go b/vendor/github.com/golangci/swaggoswag/formatter.go deleted file mode 100644 index 6bf92861d9..0000000000 --- a/vendor/github.com/golangci/swaggoswag/formatter.go +++ /dev/null @@ -1,180 +0,0 @@ -package swaggoswag - -import ( - "bytes" - "fmt" - "go/ast" - goparser "go/parser" - "go/token" - "regexp" - "sort" - "strings" - "text/tabwriter" - - "golang.org/x/tools/imports" -) - -// Check of @Param @Success @Failure @Response @Header -var specialTagForSplit = map[string]bool{ - paramAttr: true, - successAttr: true, - failureAttr: true, - responseAttr: true, - headerAttr: true, -} - -var skipChar = map[byte]byte{ - '"': '"', - '(': ')', - '{': '}', - '[': ']', -} - -// Formatter implements a formatter for Go source files. -type Formatter struct{} - -// NewFormatter create a new formatter instance. -func NewFormatter() *Formatter { - formatter := &Formatter{} - return formatter -} - -// Format formats swag comments in contents. It uses fileName to report errors -// that happen during parsing of contents. -func (f *Formatter) Format(fileName string, contents []byte) ([]byte, error) { - fileSet := token.NewFileSet() - ast, err := goparser.ParseFile(fileSet, fileName, contents, goparser.ParseComments) - if err != nil { - return nil, err - } - - // Formatting changes are described as an edit list of byte range - // replacements. We make these content-level edits directly rather than - // changing the AST nodes and writing those out (via [go/printer] or - // [go/format]) so that we only change the formatting of Swag attribute - // comments. This won't touch the formatting of any other comments, or of - // functions, etc. - maxEdits := 0 - for _, comment := range ast.Comments { - maxEdits += len(comment.List) - } - edits := make(edits, 0, maxEdits) - - for _, comment := range ast.Comments { - formatFuncDoc(fileSet, comment.List, &edits) - } - formatted, err := imports.Process(fileName, edits.apply(contents), nil) - if err != nil { - return nil, err - } - return formatted, nil -} - -type edit struct { - begin int - end int - replacement []byte -} - -type edits []edit - -func (edits edits) apply(contents []byte) []byte { - // Apply the edits with the highest offset first, so that earlier edits - // don't affect the offsets of later edits. - sort.Slice(edits, func(i, j int) bool { - return edits[i].begin > edits[j].begin - }) - - for _, edit := range edits { - prefix := contents[:edit.begin] - suffix := contents[edit.end:] - contents = append(prefix, append(edit.replacement, suffix...)...) - } - - return contents -} - -// formatFuncDoc reformats the comment lines in commentList, and appends any -// changes to the edit list. -func formatFuncDoc(fileSet *token.FileSet, commentList []*ast.Comment, edits *edits) { - // Building the edit list to format a comment block is a two-step process. - // First, we iterate over each comment line looking for Swag attributes. In - // each one we find, we replace alignment whitespace with a tab character, - // then write the result into a tab writer. - - linesToComments := make(map[int]int, len(commentList)) - - buffer := &bytes.Buffer{} - w := tabwriter.NewWriter(buffer, 1, 4, 1, '\t', 0) - - for commentIndex, comment := range commentList { - text := comment.Text - if attr, body, found := swagComment(text); found { - formatted := "//\t" + attr - if body != "" { - formatted += "\t" + splitComment2(attr, body) - } - _, _ = fmt.Fprintln(w, formatted) - linesToComments[len(linesToComments)] = commentIndex - } - } - - // Once we've loaded all of the comment lines to be aligned into the tab - // writer, flushing it causes the aligned text to be written out to the - // backing buffer. - _ = w.Flush() - - // Now the second step: we iterate over the aligned comment lines that were - // written into the backing buffer, pair each one up to its original - // comment line, and use the combination to describe the edit that needs to - // be made to the original input. - formattedComments := bytes.Split(buffer.Bytes(), []byte("\n")) - for lineIndex, commentIndex := range linesToComments { - comment := commentList[commentIndex] - *edits = append(*edits, edit{ - begin: fileSet.Position(comment.Pos()).Offset, - end: fileSet.Position(comment.End()).Offset, - replacement: formattedComments[lineIndex], - }) - } -} - -func splitComment2(attr, body string) string { - if specialTagForSplit[strings.ToLower(attr)] { - for i := 0; i < len(body); i++ { - if skipEnd, ok := skipChar[body[i]]; ok { - skipStart, n := body[i], 1 - for i++; i < len(body); i++ { - if skipStart != skipEnd && body[i] == skipStart { - n++ - } else if body[i] == skipEnd { - n-- - if n == 0 { - break - } - } - } - } else if body[i] == ' ' || body[i] == '\t' { - j := i - for ; j < len(body) && (body[j] == ' ' || body[j] == '\t'); j++ { - } - body = replaceRange(body, i, j, "\t") - } - } - } - return body -} - -func replaceRange(s string, start, end int, new string) string { - return s[:start] + new + s[end:] -} - -var swagCommentLineExpression = regexp.MustCompile(`^\/\/\s+(@[\S.]+)\s*(.*)`) - -func swagComment(comment string) (string, string, bool) { - matches := swagCommentLineExpression.FindStringSubmatch(comment) - if matches == nil { - return "", "", false - } - return matches[1], matches[2], true -} diff --git a/vendor/github.com/golangci/swaggoswag/license b/vendor/github.com/golangci/swaggoswag/license deleted file mode 100644 index a97865bf46..0000000000 --- a/vendor/github.com/golangci/swaggoswag/license +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2017 Eason Lin - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/golangci/swaggoswag/parser.go b/vendor/github.com/golangci/swaggoswag/parser.go deleted file mode 100644 index 368517b61c..0000000000 --- a/vendor/github.com/golangci/swaggoswag/parser.go +++ /dev/null @@ -1,48 +0,0 @@ -package swaggoswag - -const ( - // CamelCase indicates using CamelCase strategy for struct field. - CamelCase = "camelcase" - - // PascalCase indicates using PascalCase strategy for struct field. - PascalCase = "pascalcase" - - // SnakeCase indicates using SnakeCase strategy for struct field. - SnakeCase = "snakecase" - - idAttr = "@id" - acceptAttr = "@accept" - produceAttr = "@produce" - paramAttr = "@param" - successAttr = "@success" - failureAttr = "@failure" - responseAttr = "@response" - headerAttr = "@header" - tagsAttr = "@tags" - routerAttr = "@router" - deprecatedRouterAttr = "@deprecatedrouter" - summaryAttr = "@summary" - deprecatedAttr = "@deprecated" - securityAttr = "@security" - titleAttr = "@title" - conNameAttr = "@contact.name" - conURLAttr = "@contact.url" - conEmailAttr = "@contact.email" - licNameAttr = "@license.name" - licURLAttr = "@license.url" - versionAttr = "@version" - descriptionAttr = "@description" - descriptionMarkdownAttr = "@description.markdown" - secBasicAttr = "@securitydefinitions.basic" - secAPIKeyAttr = "@securitydefinitions.apikey" - secApplicationAttr = "@securitydefinitions.oauth2.application" - secImplicitAttr = "@securitydefinitions.oauth2.implicit" - secPasswordAttr = "@securitydefinitions.oauth2.password" - secAccessCodeAttr = "@securitydefinitions.oauth2.accesscode" - tosAttr = "@termsofservice" - extDocsDescAttr = "@externaldocs.description" - extDocsURLAttr = "@externaldocs.url" - xCodeSamplesAttr = "@x-codesamples" - scopeAttrPrefix = "@scope." - stateAttr = "@state" -) diff --git a/vendor/github.com/golangci/swaggoswag/readme.md b/vendor/github.com/golangci/swaggoswag/readme.md deleted file mode 100644 index 4d1c260052..0000000000 --- a/vendor/github.com/golangci/swaggoswag/readme.md +++ /dev/null @@ -1,26 +0,0 @@ -# Fork of swaggo/swag - -This is a hard fork of [swaggo/swag](https://github.com/swaggo/swag) to be usable as a library. - -I considered other options before deciding to fork, but there are no straightforward or non-invasive changes. - -Issues should be open either on the original [swaggo/swag repository](https://github.com/swaggo/swag) or on [golangci-lint repository](https://github.com/golangci/golangci-lint). - -**No modifications will be accepted other than the synchronization of the fork.** - -The synchronization of the fork will be done by the golangci-lint maintainers only. - -## Modifications - -- All the files have been removed except: - - `formatter.go` (the unused field `debug Debugger` is removed) - - `formatter_test.go` - - `parser.go` (only the constants are kept.) - - `license` - - `.gitignore` -- The module name has been changed to `github.com/golangci/swaggoswag` to avoid replacement directives inside golangci-lint. - - The package name has been changed from `swag` to `swaggoswag`. - -## History - -- sync with 93e86851e9f22f1f2db57812cf71fc004c02159c (after v1.16.4) diff --git a/vendor/github.com/golangci/unconvert/LICENSE b/vendor/github.com/golangci/unconvert/LICENSE deleted file mode 100644 index 7448756763..0000000000 --- a/vendor/github.com/golangci/unconvert/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2012 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/golangci/unconvert/README.md b/vendor/github.com/golangci/unconvert/README.md deleted file mode 100644 index e9230c2183..0000000000 --- a/vendor/github.com/golangci/unconvert/README.md +++ /dev/null @@ -1,6 +0,0 @@ -Fork of [unconvert](https://github.com/mdempsky/unconvert) to be usable as a library. - -The specific elements are inside the file `golangci.go`. - -The only modification of the file `unconvert.go` is the remove of the global variables for the flags. -The tests will never work because of that, then the CI is disabled. diff --git a/vendor/github.com/golangci/unconvert/golangci.go b/vendor/github.com/golangci/unconvert/golangci.go deleted file mode 100644 index 04e385a0bd..0000000000 --- a/vendor/github.com/golangci/unconvert/golangci.go +++ /dev/null @@ -1,85 +0,0 @@ -package unconvert - -import ( - "go/ast" - "go/token" - "strings" - "sync" - - "golang.org/x/tools/go/analysis" -) - -// Transformed version of the original unconvert flags section. -// The section has been removed inside `unconvert.go` -var ( - flagAll = pointer(false) - flagApply = pointer(false) - flagCPUProfile = pointer("") - flagSafe = pointer(false) - flagV = pointer(false) - flagTests = pointer(true) - flagFastMath = pointer(false) - flagTags = pointer("") - flagConfigs = pointer("") -) - -func pointer[T string | int | int32 | int64 | bool](v T) *T { return &v } - -func SetFastMath(fastMath bool) { - // To avoid race condition, the settings should not be defined during the Run. - flagFastMath = pointer(fastMath) -} - -func SetSafe(safe bool) { - // To avoid race condition, the settings should not be defined during the Run. - flagSafe = pointer(safe) -} - -func Run(pass *analysis.Pass) []token.Position { - type res struct { - file string - edits editSet - } - - ch := make(chan res) - var wg sync.WaitGroup - for _, file := range pass.Files { - file := file - - tokenFile := pass.Fset.File(file.Package) - filename := tokenFile.Position(file.Package).Filename - - // Hack to recognize _cgo_gotypes.go. - if strings.HasSuffix(filename, "-d") || strings.HasSuffix(filename, "/_cgo_gotypes.go") { - continue - } - - wg.Add(1) - go func() { - defer wg.Done() - - v := visitor{info: pass.TypesInfo, file: tokenFile, edits: make(editSet)} - ast.Walk(&v, file) - - ch <- res{filename, v.edits} - }() - } - go func() { - wg.Wait() - close(ch) - }() - - m := make(fileToEditSet) - for r := range ch { - m[r.file] = r.edits - } - - var positions []token.Position - for _, edit := range m { - for position, _ := range edit { - positions = append(positions, position) - } - } - - return positions -} diff --git a/vendor/github.com/golangci/unconvert/unconvert.go b/vendor/github.com/golangci/unconvert/unconvert.go deleted file mode 100644 index 36c34fa461..0000000000 --- a/vendor/github.com/golangci/unconvert/unconvert.go +++ /dev/null @@ -1,649 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package unconvert Unconvert removes redundant type conversions from Go packages. -package unconvert - -import ( - "bytes" - "encoding/json" - "flag" - "fmt" - "go/ast" - "go/format" - "go/parser" - "go/token" - "go/types" - "log" - "os" - "os/exec" - "reflect" - "runtime/pprof" - "sort" - "strings" - "sync" - "unicode" - - "golang.org/x/text/width" - "golang.org/x/tools/go/packages" -) - -// Unnecessary conversions are identified by the position -// of their left parenthesis within a source file. - -type editSet map[token.Position]struct{} - -func (e editSet) add(pos token.Position) { - pos.Offset = 0 - e[pos] = struct{}{} -} - -func (e editSet) has(pos token.Position) bool { - pos.Offset = 0 - _, ok := e[pos] - return ok -} - -func (e editSet) remove(pos token.Position) { - pos.Offset = 0 - delete(e, pos) -} - -// intersect removes positions from e that are not present in x. -func (e editSet) intersect(x editSet) { - for pos := range e { - if _, ok := x[pos]; !ok { - delete(e, pos) - } - } -} - -type fileToEditSet map[string]editSet - -func apply(file string, edits editSet) { - if len(edits) == 0 { - return - } - - fset := token.NewFileSet() - f, err := parser.ParseFile(fset, file, nil, parser.ParseComments) - if err != nil { - log.Fatal(err) - } - - // Note: We modify edits during the walk. - v := editor{edits: edits, file: fset.File(f.Package)} - ast.Walk(&v, f) - if len(edits) != 0 { - log.Printf("%s: missing edits %s", file, edits) - } - - // TODO(mdempsky): Write to temporary file and rename. - var buf bytes.Buffer - err = format.Node(&buf, fset, f) - if err != nil { - log.Fatal(err) - } - - err = os.WriteFile(file, buf.Bytes(), 0) - if err != nil { - log.Fatal(err) - } -} - -type editor struct { - edits editSet - file *token.File -} - -func (e *editor) Visit(n ast.Node) ast.Visitor { - if n == nil { - return nil - } - v := reflect.ValueOf(n).Elem() - for i, n := 0, v.NumField(); i < n; i++ { - switch f := v.Field(i).Addr().Interface().(type) { - case *ast.Expr: - e.rewrite(f) - case *[]ast.Expr: - for i := range *f { - e.rewrite(&(*f)[i]) - } - } - } - return e -} - -func (e *editor) rewrite(f *ast.Expr) { - call, ok := (*f).(*ast.CallExpr) - if !ok { - return - } - - pos := e.file.Position(call.Lparen) - if !e.edits.has(pos) { - return - } - *f = call.Args[0] - e.edits.remove(pos) -} - -var ( - cr = []byte{'\r'} - nl = []byte{'\n'} -) - -func print(conversions []token.Position) { - var file string - var lines [][]byte - - for _, pos := range conversions { - fmt.Printf("%s:%d:%d: unnecessary conversion\n", pos.Filename, pos.Line, pos.Column) - if *flagV { - if pos.Filename != file { - buf, err := os.ReadFile(pos.Filename) - if err != nil { - log.Fatal(err) - } - file = pos.Filename - lines = bytes.Split(buf, nl) - } - - line := bytes.TrimSuffix(lines[pos.Line-1], cr) - fmt.Printf("%s\n", line) - - // For files processed by cgo, Column is the - // column location after cgo processing, which - // may be different than the source column - // that we want here. In lieu of a better - // heuristic for detecting this case, at least - // avoid panicking if column is out of bounds. - if pos.Column <= len(line) { - fmt.Printf("%s^\n", rub(line[:pos.Column-1])) - } - } - } -} - -// Rub returns a copy of buf with all non-whitespace characters replaced -// by spaces (like rubbing them out with white out). -func rub(buf []byte) []byte { - // TODO(mdempsky): Handle combining characters? - var res bytes.Buffer - for _, r := range string(buf) { - if unicode.IsSpace(r) { - res.WriteRune(r) - continue - } - switch width.LookupRune(r).Kind() { - case width.EastAsianWide, width.EastAsianFullwidth: - res.WriteString(" ") - default: - res.WriteByte(' ') - } - } - return res.Bytes() -} - -func usage() { - fmt.Fprintf(os.Stderr, "usage: unconvert [flags] [package ...]\n") - flag.PrintDefaults() -} - -func main() { - flag.Usage = usage - flag.Parse() - - if *flagCPUProfile != "" { - f, err := os.Create(*flagCPUProfile) - if err != nil { - log.Fatal(err) - } - pprof.StartCPUProfile(f) - defer pprof.StopCPUProfile() - } - - patterns := flag.Args() // 0 or more import path patterns. - - var configs [][]string - if *flagConfigs != "" { - if os.Getenv("UNCONVERT_CONFIGS_EXPERIMENT") != "1" { - fmt.Println("WARNING: -configs is experimental and subject to change without notice.") - fmt.Println("Please comment at https://github.com/mdempsky/unconvert/issues/26") - fmt.Println("if you'd like to rely on this interface.") - fmt.Println("(Set UNCONVERT_CONFIGS_EXPERIMENT=1 to silence this warning.)") - fmt.Println() - } - - if err := json.Unmarshal([]byte(*flagConfigs), &configs); err != nil { - log.Fatal(err) - } - } else if *flagAll { - configs = allConfigs() - } else { - configs = [][]string{nil} - } - - m := mergeEdits(patterns, configs) - - if *flagApply { - var wg sync.WaitGroup - for f, e := range m { - wg.Add(1) - f, e := f, e - go func() { - defer wg.Done() - apply(f, e) - }() - } - wg.Wait() - } else { - var conversions []token.Position - for _, positions := range m { - for pos := range positions { - conversions = append(conversions, pos) - } - } - sort.Sort(byPosition(conversions)) - print(conversions) - if len(conversions) > 0 { - os.Exit(1) - } - } -} - -func allConfigs() [][]string { - out, err := exec.Command("go", "tool", "dist", "list", "-json").Output() - if err != nil { - log.Fatal(err) - } - - var platforms []struct { - GOOS, GOARCH string - } - err = json.Unmarshal(out, &platforms) - if err != nil { - log.Fatal(err) - } - - var res [][]string - for _, platform := range platforms { - res = append(res, []string{ - "GOOS=" + platform.GOOS, - "GOARCH=" + platform.GOARCH, - }) - } - return res -} - -func mergeEdits(patterns []string, configs [][]string) fileToEditSet { - m := make(fileToEditSet) - for _, config := range configs { - for f, e := range computeEdits(patterns, config) { - if e0, ok := m[f]; ok { - e0.intersect(e) - } else { - m[f] = e - } - } - } - return m -} - -func computeEdits(patterns []string, config []string) fileToEditSet { - // TODO(mdempsky): Move into config? - var buildFlags []string - if *flagTags != "" { - buildFlags = []string{"-tags", *flagTags} - } - - pkgs, err := packages.Load(&packages.Config{ - Mode: packages.NeedSyntax | packages.NeedTypes | packages.NeedTypesInfo, - Env: append(os.Environ(), config...), - BuildFlags: buildFlags, - Tests: *flagTests, - }, patterns...) - if err != nil { - log.Fatal(err) - } - packages.PrintErrors(pkgs) - - type res struct { - file string - edits editSet - } - - ch := make(chan res) - var wg sync.WaitGroup - for _, pkg := range pkgs { - for _, file := range pkg.Syntax { - pkg, file := pkg, file - tokenFile := pkg.Fset.File(file.Package) - filename := tokenFile.Position(file.Package).Filename - - // Hack to recognize _cgo_gotypes.go. - if strings.HasSuffix(filename, "-d") || strings.HasSuffix(filename, "/_cgo_gotypes.go") { - continue - } - - wg.Add(1) - go func() { - defer wg.Done() - v := visitor{info: pkg.TypesInfo, file: tokenFile, edits: make(editSet)} - ast.Walk(&v, file) - ch <- res{filename, v.edits} - }() - } - } - go func() { - wg.Wait() - close(ch) - }() - - m := make(fileToEditSet) - for r := range ch { - m[r.file] = r.edits - } - return m -} - -type step struct { - n ast.Node - i int -} - -type visitor struct { - info *types.Info - file *token.File - edits editSet - path []step -} - -func (v *visitor) Visit(node ast.Node) ast.Visitor { - if node != nil { - v.path = append(v.path, step{n: node}) - } else { - n := len(v.path) - v.path = v.path[:n-1] - if n >= 2 { - v.path[n-2].i++ - } - } - - if call, ok := node.(*ast.CallExpr); ok { - v.unconvert(call) - } - return v -} - -func (v *visitor) unconvert(call *ast.CallExpr) { - // TODO(mdempsky): Handle useless multi-conversions. - - // Conversions have exactly one argument. - if len(call.Args) != 1 || call.Ellipsis != token.NoPos { - return - } - ft, ok := v.info.Types[call.Fun] - if !ok { - fmt.Println("Missing type for function") - return - } - if !ft.IsType() { - // Function call; not a conversion. - return - } - at, ok := v.info.Types[call.Args[0]] - if !ok { - fmt.Println("Missing type for argument") - return - } - if !types.Identical(ft.Type, at.Type) { - // A real conversion. - return - } - if !*flagFastMath && isFloatingPoint(ft.Type) { - // As of Go 1.9, explicit floating-point type - // conversions are always significant because they - // force rounding and prevent operation fusing. - return - } - if isUntypedValue(call.Args[0], v.info) { - // Workaround golang.org/issue/13061. - return - } - if *flagSafe && !v.isSafeContext(at.Type) { - // TODO(mdempsky): Remove this message. - fmt.Println("Skipped a possible type conversion because of -safe at", v.file.Position(call.Pos())) - return - } - - v.edits.add(v.file.Position(call.Lparen)) -} - -// isFloatingPointer reports whether t's underlying type is a floating -// point type. -func isFloatingPoint(t types.Type) bool { - ut, ok := t.Underlying().(*types.Basic) - return ok && ut.Info()&(types.IsFloat|types.IsComplex) != 0 -} - -// isSafeContext reports whether the current context requires -// an expression of type t. -// -// TODO(mdempsky): That's a bad explanation. -func (v *visitor) isSafeContext(t types.Type) bool { - ctxt := &v.path[len(v.path)-2] - switch n := ctxt.n.(type) { - case *ast.AssignStmt: - pos := ctxt.i - len(n.Lhs) - if pos < 0 { - fmt.Println("Type conversion on LHS of assignment?") - return false - } - if n.Tok == token.DEFINE { - // Skip := assignments. - return true - } - // We're a conversion in the pos'th element of n.Rhs. - // Check that the corresponding element of n.Lhs is of type t. - lt, ok := v.info.Types[n.Lhs[pos]] - if !ok { - fmt.Println("Missing type for LHS expression") - return false - } - return types.Identical(t, lt.Type) - case *ast.BinaryExpr: - if n.Op == token.SHL || n.Op == token.SHR { - if ctxt.i == 1 { - // RHS of a shift is always safe. - return true - } - // For the LHS, we should inspect up another level. - fmt.Println("TODO(mdempsky): Handle LHS of shift expressions") - return true - } - var other ast.Expr - if ctxt.i == 0 { - other = n.Y - } else { - other = n.X - } - ot, ok := v.info.Types[other] - if !ok { - fmt.Println("Missing type for other binop subexpr") - return false - } - return types.Identical(t, ot.Type) - case *ast.CallExpr: - pos := ctxt.i - 1 - if pos < 0 { - // Type conversion in the function subexpr is okay. - return true - } - ft, ok := v.info.Types[n.Fun] - if !ok { - fmt.Println("Missing type for function expression") - return false - } - sig, ok := ft.Type.(*types.Signature) - if !ok { - // "Function" is either a type conversion (ok) or a builtin (ok?). - return true - } - params := sig.Params() - var pt types.Type - if sig.Variadic() && n.Ellipsis == token.NoPos && pos >= params.Len()-1 { - pt = params.At(params.Len() - 1).Type().(*types.Slice).Elem() - } else { - pt = params.At(pos).Type() - } - return types.Identical(t, pt) - case *ast.CompositeLit, *ast.KeyValueExpr: - fmt.Println("TODO(mdempsky): Compare against value type of composite literal type at", v.file.Position(n.Pos())) - return true - case *ast.ReturnStmt: - // TODO(mdempsky): Is there a better way to get the corresponding - // return parameter type? - var funcType *ast.FuncType - for i := len(v.path) - 1; funcType == nil && i >= 0; i-- { - switch f := v.path[i].n.(type) { - case *ast.FuncDecl: - funcType = f.Type - case *ast.FuncLit: - funcType = f.Type - } - } - var typeExpr ast.Expr - for i, j := ctxt.i, 0; j < len(funcType.Results.List); j++ { - f := funcType.Results.List[j] - if len(f.Names) == 0 { - if i >= 1 { - i-- - continue - } - } else { - if i >= len(f.Names) { - i -= len(f.Names) - continue - } - } - typeExpr = f.Type - break - } - if typeExpr == nil { - fmt.Println(ctxt) - } - pt, ok := v.info.Types[typeExpr] - if !ok { - fmt.Println("Missing type for return parameter at", v.file.Position(n.Pos())) - return false - } - return types.Identical(t, pt.Type) - case *ast.StarExpr, *ast.UnaryExpr: - // TODO(mdempsky): I think these are always safe. - return true - case *ast.SwitchStmt: - // TODO(mdempsky): I think this is always safe? - return true - default: - // TODO(mdempsky): When can this happen? - fmt.Printf("... huh, %T at %v\n", n, v.file.Position(n.Pos())) - return true - } -} - -func isUntypedValue(n ast.Expr, info *types.Info) (res bool) { - switch n := n.(type) { - case *ast.BinaryExpr: - switch n.Op { - case token.SHL, token.SHR: - // Shifts yield an untyped value if their LHS is untyped. - return isUntypedValue(n.X, info) - case token.EQL, token.NEQ, token.LSS, token.GTR, token.LEQ, token.GEQ: - // Comparisons yield an untyped boolean value. - return true - case token.ADD, token.SUB, token.MUL, token.QUO, token.REM, - token.AND, token.OR, token.XOR, token.AND_NOT, - token.LAND, token.LOR: - return isUntypedValue(n.X, info) && isUntypedValue(n.Y, info) - } - case *ast.UnaryExpr: - switch n.Op { - case token.ADD, token.SUB, token.NOT, token.XOR: - return isUntypedValue(n.X, info) - } - case *ast.BasicLit: - // Basic literals are always untyped. - return true - case *ast.ParenExpr: - return isUntypedValue(n.X, info) - case *ast.SelectorExpr: - return isUntypedValue(n.Sel, info) - case *ast.Ident: - if obj, ok := info.Uses[n]; ok { - if obj.Pkg() == nil && obj.Name() == "nil" { - // The universal untyped zero value. - return true - } - if b, ok := obj.Type().(*types.Basic); ok && b.Info()&types.IsUntyped != 0 { - // Reference to an untyped constant. - return true - } - } - case *ast.CallExpr: - if b, ok := asBuiltin(n.Fun, info); ok { - switch b.Name() { - case "real", "imag": - return isUntypedValue(n.Args[0], info) - case "complex": - return isUntypedValue(n.Args[0], info) && isUntypedValue(n.Args[1], info) - } - } - } - - return false -} - -func asBuiltin(n ast.Expr, info *types.Info) (*types.Builtin, bool) { - for { - paren, ok := n.(*ast.ParenExpr) - if !ok { - break - } - n = paren.X - } - - ident, ok := n.(*ast.Ident) - if !ok { - return nil, false - } - - obj, ok := info.Uses[ident] - if !ok { - return nil, false - } - - b, ok := obj.(*types.Builtin) - return b, ok -} - -type byPosition []token.Position - -func (p byPosition) Len() int { - return len(p) -} - -func (p byPosition) Less(i, j int) bool { - if p[i].Filename != p[j].Filename { - return p[i].Filename < p[j].Filename - } - if p[i].Line != p[j].Line { - return p[i].Line < p[j].Line - } - return p[i].Column < p[j].Column -} - -func (p byPosition) Swap(i, j int) { - p[i], p[j] = p[j], p[i] -} diff --git a/vendor/github.com/gordonklaus/ineffassign/LICENSE b/vendor/github.com/gordonklaus/ineffassign/LICENSE deleted file mode 100644 index 9e3d9bcc02..0000000000 --- a/vendor/github.com/gordonklaus/ineffassign/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2016 Gordon Klaus and contributors - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/gordonklaus/ineffassign/pkg/ineffassign/ineffassign.go b/vendor/github.com/gordonklaus/ineffassign/pkg/ineffassign/ineffassign.go deleted file mode 100644 index 19da47b5c3..0000000000 --- a/vendor/github.com/gordonklaus/ineffassign/pkg/ineffassign/ineffassign.go +++ /dev/null @@ -1,616 +0,0 @@ -package ineffassign - -import ( - "fmt" - "go/ast" - "go/token" - "sort" - - "golang.org/x/tools/go/analysis" -) - -var checkEscapingErrors bool - -// Analyzer is the ineffassign analysis.Analyzer instance. -var Analyzer = &analysis.Analyzer{ - Name: "ineffassign", - Doc: "detects when assignments to existing variables are not used", - Run: checkPath, -} - -func init() { - Analyzer.Flags.BoolVar(&checkEscapingErrors, "check-escaping-errors", false, "check escaping variables of type error, may cause false positives") -} - -func checkPath(pass *analysis.Pass) (interface{}, error) { - for _, file := range pass.Files { - if ast.IsGenerated(file) { - continue - } - - bld := &builder{vars: map[*ast.Object]*variable{}} - bld.walk(file) - - chk := &checker{vars: bld.vars, seen: map[*block]bool{}} - for _, b := range bld.roots { - chk.check(b) - } - sort.Sort(chk.ineff) - - for _, id := range chk.ineff { - pass.Report(analysis.Diagnostic{ - Pos: id.Pos(), - End: id.End(), - Message: fmt.Sprintf("ineffectual assignment to %s", id.Name), - }) - } - } - - return nil, nil -} - -type builder struct { - roots []*block - block *block - vars map[*ast.Object]*variable - results []*ast.FieldList - defers []bool - breaks branchStack - continues branchStack - gotos branchStack - labelStmt *ast.LabeledStmt -} - -type block struct { - children []*block - ops map[*ast.Object][]operation -} - -func (b *block) addChild(c *block) { - b.children = append(b.children, c) -} - -type operation struct { - id *ast.Ident - assign bool -} - -type variable struct { - fundept int - escapes bool -} - -func (bld *builder) walk(n ast.Node) { - if n != nil { - ast.Walk(bld, n) - } -} - -func (bld *builder) Visit(n ast.Node) ast.Visitor { - switch n := n.(type) { - case *ast.FuncDecl: - if n.Body != nil { - bld.fun(n.Recv, n.Type, n.Body) - } - case *ast.FuncLit: - bld.fun(nil, n.Type, n.Body) - case *ast.IfStmt: - bld.walk(n.Init) - bld.walk(n.Cond) - b0 := bld.block - bld.newBlock(b0) - bld.walk(n.Body) - b1 := bld.block - if n.Else != nil { - bld.newBlock(b0) - bld.walk(n.Else) - b0 = bld.block - } - bld.newBlock(b0, b1) - case *ast.ForStmt: - lbl := bld.stmtLabel(n) - brek := bld.breaks.push(lbl) - continu := bld.continues.push(lbl) - bld.walk(n.Init) - start := bld.newBlock(bld.block) - bld.walk(n.Cond) - cond := bld.block - bld.newBlock(cond) - bld.walk(n.Body) - continu.setDestination(bld.newBlock(bld.block)) - bld.walk(n.Post) - bld.block.addChild(start) - brek.setDestination(bld.newBlock(cond)) - bld.breaks.pop() - bld.continues.pop() - case *ast.RangeStmt: - lbl := bld.stmtLabel(n) - brek := bld.breaks.push(lbl) - continu := bld.continues.push(lbl) - bld.walk(n.X) - pre := bld.newBlock(bld.block) - start := bld.newBlock(pre) - if n.Key != nil { - lhs := []ast.Expr{n.Key} - if n.Value != nil { - lhs = append(lhs, n.Value) - } - bld.walk(&ast.AssignStmt{Lhs: lhs, Tok: n.Tok, TokPos: n.TokPos, Rhs: []ast.Expr{&ast.Ident{NamePos: n.X.End()}}}) - } - bld.walk(n.Body) - bld.block.addChild(start) - continu.setDestination(pre) - brek.setDestination(bld.newBlock(pre, bld.block)) - bld.breaks.pop() - bld.continues.pop() - case *ast.SwitchStmt: - bld.walk(n.Init) - bld.walk(n.Tag) - bld.swtch(n, n.Body.List) - case *ast.TypeSwitchStmt: - bld.walk(n.Init) - bld.walk(n.Assign) - bld.swtch(n, n.Body.List) - case *ast.SelectStmt: - brek := bld.breaks.push(bld.stmtLabel(n)) - for _, c := range n.Body.List { - c := c.(*ast.CommClause).Comm - if s, ok := c.(*ast.AssignStmt); ok { - bld.walk(s.Rhs[0]) - } else { - bld.walk(c) - } - } - b0 := bld.block - exits := make([]*block, len(n.Body.List)) - dfault := false - for i, c := range n.Body.List { - c := c.(*ast.CommClause) - bld.newBlock(b0) - bld.walk(c) - exits[i] = bld.block - dfault = dfault || c.Comm == nil - } - if !dfault { - exits = append(exits, b0) - } - brek.setDestination(bld.newBlock(exits...)) - bld.breaks.pop() - case *ast.DeferStmt: - bld.walk(n.Call.Fun) - for _, a := range n.Call.Args { - bld.walk(a) - } - bld.defers[len(bld.defers)-1] = true - case *ast.LabeledStmt: - bld.gotos.get(n.Label).setDestination(bld.newBlock(bld.block)) - bld.labelStmt = n - bld.walk(n.Stmt) - case *ast.BranchStmt: - switch n.Tok { - case token.BREAK: - bld.breaks.get(n.Label).addSource(bld.block) - bld.newBlock() - case token.CONTINUE: - bld.continues.get(n.Label).addSource(bld.block) - bld.newBlock() - case token.GOTO: - bld.gotos.get(n.Label).addSource(bld.block) - bld.newBlock() - } - - case *ast.AssignStmt: - if n.Tok == token.QUO_ASSIGN || n.Tok == token.REM_ASSIGN { - bld.maybePanic() - } - - for _, x := range n.Rhs { - bld.walk(x) - } - for i, x := range n.Lhs { - if id, ok := ident(x); ok { - if n.Tok >= token.ADD_ASSIGN && n.Tok <= token.AND_NOT_ASSIGN { - bld.use(id) - } - // Don't treat explicit initialization to zero as assignment; it is often used as shorthand for a bare declaration. - if n.Tok == token.DEFINE && i < len(n.Rhs) && isZeroInitializer(n.Rhs[i]) { - bld.use(id) - } else { - bld.assign(id) - } - } else { - bld.walk(x) - } - } - case *ast.GenDecl: - if n.Tok == token.VAR { - for _, s := range n.Specs { - s := s.(*ast.ValueSpec) - for _, x := range s.Values { - bld.walk(x) - } - for _, id := range s.Names { - if len(s.Values) > 0 { - bld.assign(id) - } else { - bld.use(id) - } - } - } - } - case *ast.IncDecStmt: - if id, ok := ident(n.X); ok { - bld.use(id) - bld.assign(id) - } else { - bld.walk(n.X) - } - case *ast.Ident: - bld.use(n) - case *ast.ReturnStmt: - for _, x := range n.Results { - bld.walk(x) - } - if res := bld.results[len(bld.results)-1]; res != nil { - for _, f := range res.List { - for _, id := range f.Names { - if n.Results != nil { - bld.assign(id) - } - bld.use(id) - } - } - } - bld.newBlock() - case *ast.SendStmt: - bld.maybePanic() - return bld - - case *ast.BinaryExpr: - if n.Op == token.EQL || n.Op == token.QUO || n.Op == token.REM { - bld.maybePanic() - } - return bld - case *ast.CallExpr: - bld.maybePanic() - return bld - case *ast.IndexExpr: - bld.maybePanic() - return bld - case *ast.UnaryExpr: - id, ok := ident(n.X) - if ix, isIx := n.X.(*ast.IndexExpr); isIx { - // We don't care about indexing into slices, but without type information we can do no better. - id, ok = ident(ix.X) - } - if ok && n.Op == token.AND { - bld.escape(id) - } - return bld - case *ast.SelectorExpr: - bld.maybePanic() - // A method call (possibly delayed via a method value) might implicitly take - // the address of its receiver, causing it to escape. - // We can't do any better here without knowing the variable's type. - if id, ok := ident(n.X); ok { - bld.escape(id) - } - return bld - case *ast.SliceExpr: - bld.maybePanic() - // We don't care about slicing into slices, but without type information we can do no better. - if id, ok := ident(n.X); ok { - bld.escape(id) - } - return bld - case *ast.StarExpr: - bld.maybePanic() - return bld - case *ast.TypeAssertExpr: - bld.maybePanic() - return bld - - default: - return bld - } - return nil -} - -func (bld *builder) escape(id *ast.Ident) { - if checkEscapingErrors && id.Obj != nil { - if d, ok := id.Obj.Decl.(*ast.ValueSpec); ok { - if t, ok := d.Type.(*ast.Ident); ok { - if t.Name == "error" { - return - } - } - } - } - if v, ok := bld.vars[id.Obj]; ok { - v.escapes = true - } -} - -func isZeroInitializer(x ast.Expr) bool { - // Assume that a call expression of a single argument is a conversion expression. We can't do better without type information. - if c, ok := x.(*ast.CallExpr); ok { - fun := c.Fun - if p, ok := fun.(*ast.ParenExpr); ok { - fun = p.X - } - if s, ok := fun.(*ast.StarExpr); ok { - fun = s.X - } - switch fun.(type) { - case *ast.Ident, *ast.SelectorExpr, *ast.ArrayType, *ast.StructType, *ast.FuncType, *ast.InterfaceType, *ast.MapType, *ast.ChanType: - default: - return false - } - if len(c.Args) != 1 { - return false - } - x = c.Args[0] - } - - switch x := x.(type) { - case *ast.BasicLit: - switch x.Value { - case "0", "0.0", "0.", ".0", `""`: - return true - } - case *ast.Ident: - return (x.Name == "false" || x.Name == "nil") && x.Obj == nil - } - - return false -} - -func (bld *builder) fun(recv *ast.FieldList, typ *ast.FuncType, body *ast.BlockStmt) { - for _, v := range bld.vars { - v.fundept++ - } - bld.results = append(bld.results, typ.Results) - bld.defers = append(bld.defers, false) - - b := bld.block - bld.newBlock() - bld.roots = append(bld.roots, bld.block) - if recv != nil { - bld.walk(recv) - } - bld.walk(typ) - bld.walk(body) - bld.block = b - - bld.results = bld.results[:len(bld.results)-1] - bld.defers = bld.defers[:len(bld.defers)-1] - for _, v := range bld.vars { - v.fundept-- - } -} - -func (bld *builder) swtch(stmt ast.Stmt, cases []ast.Stmt) { - brek := bld.breaks.push(bld.stmtLabel(stmt)) - b0 := bld.block - list := b0 - exits := make([]*block, 0, len(cases)+1) - var dfault, fallthru *block - for _, c := range cases { - c := c.(*ast.CaseClause) - - if c.List != nil { - list = bld.newBlock(list) - for _, x := range c.List { - bld.walk(x) - } - } - - parents := []*block{} - if c.List != nil { - parents = append(parents, list) - } - if fallthru != nil { - parents = append(parents, fallthru) - fallthru = nil - } - bld.newBlock(parents...) - if c.List == nil { - dfault = bld.block - } - for _, s := range c.Body { - bld.walk(s) - if s, ok := s.(*ast.BranchStmt); ok && s.Tok == token.FALLTHROUGH { - fallthru = bld.block - } - } - - if fallthru == nil { - exits = append(exits, bld.block) - } - } - if dfault != nil { - list.addChild(dfault) - } else { - exits = append(exits, b0) - } - brek.setDestination(bld.newBlock(exits...)) - bld.breaks.pop() -} - -// If an operation might panic and be recovered, mark named function results as used. -func (bld *builder) maybePanic() { - if len(bld.defers) == 0 || !bld.defers[len(bld.defers)-1] { - return - } - if len(bld.results) == 0 { - return - } - res := bld.results[len(bld.results)-1] - if res == nil { - return - } - for _, f := range res.List { - for _, id := range f.Names { - bld.use(id) - } - } -} - -func (bld *builder) newBlock(parents ...*block) *block { - bld.block = &block{ops: map[*ast.Object][]operation{}} - for _, b := range parents { - b.addChild(bld.block) - } - return bld.block -} - -func (bld *builder) stmtLabel(s ast.Stmt) *ast.Object { - if ls := bld.labelStmt; ls != nil && ls.Stmt == s { - return ls.Label.Obj - } - return nil -} - -func (bld *builder) assign(id *ast.Ident) { - bld.newOp(id, true) -} - -func (bld *builder) use(id *ast.Ident) { - bld.newOp(id, false) -} - -func (bld *builder) newOp(id *ast.Ident, assign bool) { - if id.Name == "_" || id.Obj == nil { - return - } - - v, ok := bld.vars[id.Obj] - if !ok { - v = &variable{} - bld.vars[id.Obj] = v - } - v.escapes = v.escapes || v.fundept > 0 || bld.block == nil - - if b := bld.block; b != nil && !v.escapes { - b.ops[id.Obj] = append(b.ops[id.Obj], operation{id, assign}) - } -} - -type branchStack []*branch - -type branch struct { - label *ast.Object - srcs []*block - dst *block -} - -func (s *branchStack) push(lbl *ast.Object) *branch { - br := &branch{label: lbl} - *s = append(*s, br) - return br -} - -func (s *branchStack) get(lbl *ast.Ident) *branch { - for i := len(*s) - 1; i >= 0; i-- { - if br := (*s)[i]; lbl == nil || br.label == lbl.Obj { - return br - } - } - - // Guard against invalid code (break/continue outside of loop). - if lbl == nil { - return &branch{} - } - - return s.push(lbl.Obj) -} - -func (br *branch) addSource(src *block) { - br.srcs = append(br.srcs, src) - if br.dst != nil { - src.addChild(br.dst) - } -} - -func (br *branch) setDestination(dst *block) { - br.dst = dst - for _, src := range br.srcs { - src.addChild(dst) - } -} - -func (s *branchStack) pop() { - *s = (*s)[:len(*s)-1] -} - -func ident(x ast.Expr) (*ast.Ident, bool) { - if p, ok := x.(*ast.ParenExpr); ok { - return ident(p.X) - } - id, ok := x.(*ast.Ident) - return id, ok -} - -type checker struct { - vars map[*ast.Object]*variable - seen map[*block]bool - ineff idents -} - -func (chk *checker) check(b *block) { - if chk.seen[b] { - return - } - chk.seen[b] = true - - for obj, ops := range b.ops { - ops: - for i, op := range ops { - if !op.assign { - continue - } - if i+1 < len(ops) { - if ops[i+1].assign { - chk.ineff = append(chk.ineff, op.id) - } - continue - } - seen := map[*block]bool{} - for _, b := range b.children { - if used(obj, b, seen) { - continue ops - } - } - if !chk.vars[obj].escapes { - chk.ineff = append(chk.ineff, op.id) - } - } - } - - for _, b := range b.children { - chk.check(b) - } -} - -func used(obj *ast.Object, b *block, seen map[*block]bool) bool { - if seen[b] { - return false - } - seen[b] = true - - if ops := b.ops[obj]; len(ops) > 0 { - return !ops[0].assign - } - for _, b := range b.children { - if used(obj, b, seen) { - return true - } - } - return false -} - -type idents []*ast.Ident - -func (ids idents) Len() int { return len(ids) } -func (ids idents) Less(i, j int) bool { return ids[i].Pos() < ids[j].Pos() } -func (ids idents) Swap(i, j int) { ids[i], ids[j] = ids[j], ids[i] } diff --git a/vendor/github.com/gostaticanalysis/analysisutil/LICENSE b/vendor/github.com/gostaticanalysis/analysisutil/LICENSE deleted file mode 100644 index bf7e33db84..0000000000 --- a/vendor/github.com/gostaticanalysis/analysisutil/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2019 GoStaticAnalysis - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/gostaticanalysis/analysisutil/README.md b/vendor/github.com/gostaticanalysis/analysisutil/README.md deleted file mode 100644 index d8fd3d2a47..0000000000 --- a/vendor/github.com/gostaticanalysis/analysisutil/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# analysisutil - -[![PkgGoDev](https://pkg.go.dev/badge/github.com/gostaticanalysis/analysisutil)](https://pkg.go.dev/github.com/gostaticanalysis/analysisutil) - -Utilities for x/tools/go/analysis package. diff --git a/vendor/github.com/gostaticanalysis/analysisutil/call.go b/vendor/github.com/gostaticanalysis/analysisutil/call.go deleted file mode 100644 index e3d98d1dc7..0000000000 --- a/vendor/github.com/gostaticanalysis/analysisutil/call.go +++ /dev/null @@ -1,405 +0,0 @@ -package analysisutil - -import ( - "go/types" - - "golang.org/x/tools/go/ssa" -) - -// CalledChecker checks a function is called. -// See From and Func. -type CalledChecker struct { - Ignore func(instr ssa.Instruction) bool -} - -// NotIn checks whether receiver's method is called in a function. -// If there is no methods calling at a path from an instruction -// which type is receiver to all return instruction, NotIn returns these instructions. -func (c *CalledChecker) NotIn(f *ssa.Function, receiver types.Type, methods ...*types.Func) []ssa.Instruction { - done := map[ssa.Value]bool{} - var instrs []ssa.Instruction - for _, b := range f.Blocks { - for i, instr := range b.Instrs { - v, _ := instr.(ssa.Value) - if v == nil || done[v] { - continue - } - - if v, _ := v.(*ssa.UnOp); v != nil && done[v.X] { - continue - } - - called, ok := c.From(b, i, receiver, methods...) - if ok && !called { - instrs = append(instrs, instr) - done[v] = true - if v, _ := v.(*ssa.UnOp); v != nil { - done[v.X] = true - } - } - } - } - return instrs -} - -// Func returns true when f is called in the instr. -// If recv is not nil, Func also checks the receiver. -func (c *CalledChecker) Func(instr ssa.Instruction, recv ssa.Value, f *types.Func) bool { - - if c.Ignore != nil && c.Ignore(instr) { - return false - } - - call, ok := instr.(ssa.CallInstruction) - if !ok { - return false - } - - common := call.Common() - if common == nil { - return false - } - - callee := common.StaticCallee() - if callee == nil { - return false - } - - fn, ok := callee.Object().(*types.Func) - if !ok { - return false - } - - if recv != nil && - common.Signature().Recv() != nil && - (len(common.Args) == 0 && recv != nil || common.Args[0] != recv && - !referrer(recv, common.Args[0])) { - return false - } - - return fn == f -} - -func referrer(a, b ssa.Value) bool { - return isReferrerOf(a, b) || isReferrerOf(b, a) -} - -func isReferrerOf(a, b ssa.Value) bool { - if a == nil || b == nil { - return false - } - if b.Referrers() != nil { - brs := *b.Referrers() - - for _, br := range brs { - brv, ok := br.(ssa.Value) - if !ok { - continue - } - if brv == a { - return true - } - } - } - return false -} - -// From checks whether receiver's method is called in an instruction -// which belogns to after i-th instructions, or in succsor blocks of b. -// The first result is above value. -// The second result is whether type of i-th instruction does not much receiver -// or matches with ignore cases. -func (c *CalledChecker) From(b *ssa.BasicBlock, i int, receiver types.Type, methods ...*types.Func) (called, ok bool) { - if b == nil || i < 0 || i >= len(b.Instrs) || - receiver == nil || len(methods) == 0 { - return false, false - } - - v, ok := b.Instrs[i].(ssa.Value) - if !ok { - return false, false - } - - from := &calledFrom{recv: v, fs: methods, ignore: c.Ignore} - - if !from.isRecv(receiver, v.Type()) { - return false, false - } - - if from.ignored() { - return false, false - } - - if from.instrs(b.Instrs[i+1:]) || - from.succs(b) { - return true, true - } - - from.done = nil - if from.storedInInstrs(b.Instrs[i+1:]) || - from.storedInSuccs(b) { - return false, false - } - - return false, true -} - -type calledFrom struct { - recv ssa.Value - fs []*types.Func - done map[*ssa.BasicBlock]bool - ignore func(ssa.Instruction) bool -} - -func (c *calledFrom) ignored() bool { - - switch v := c.recv.(type) { - case *ssa.UnOp: - switch v.X.(type) { - case *ssa.FreeVar, *ssa.Global: - return true - } - } - - refs := c.recv.Referrers() - if refs == nil { - return false - } - - for _, ref := range *refs { - done := map[ssa.Instruction]bool{} - if !c.isOwn(ref) && - ((c.ignore != nil && c.ignore(ref)) || - c.isRet(ref, done) || c.isArg(ref)) { - return true - } - } - - return false -} - -func (c *calledFrom) isOwn(instr ssa.Instruction) bool { - v, ok := instr.(ssa.Value) - if !ok { - return false - } - return v == c.recv -} - -func (c *calledFrom) isRet(instr ssa.Instruction, done map[ssa.Instruction]bool) bool { - if done[instr] { - return false - } - done[instr] = true - - switch instr := instr.(type) { - case *ssa.Return: - return true - case *ssa.MapUpdate: - return c.isRetInRefs(instr.Map, done) - case *ssa.Store: - if instr, _ := instr.Addr.(ssa.Instruction); instr != nil { - return c.isRet(instr, done) - } - return c.isRetInRefs(instr.Addr, done) - case *ssa.FieldAddr: - return c.isRetInRefs(instr.X, done) - case ssa.Value: - return c.isRetInRefs(instr, done) - default: - return false - } -} - -func (c *calledFrom) isRetInRefs(v ssa.Value, done map[ssa.Instruction]bool) bool { - refs := v.Referrers() - if refs == nil { - return false - } - for _, ref := range *refs { - if c.isRet(ref, done) { - return true - } - } - return false -} - -func (c *calledFrom) isArg(instr ssa.Instruction) bool { - - call, ok := instr.(ssa.CallInstruction) - if !ok { - return false - } - - common := call.Common() - if common == nil { - return false - } - - args := common.Args - if common.Signature().Recv() != nil { - args = args[1:] - } - - for i := range args { - if args[i] == c.recv { - return true - } - } - - return false -} - -func (c *calledFrom) instrs(instrs []ssa.Instruction) bool { - for _, instr := range instrs { - for _, f := range c.fs { - if Called(instr, c.recv, f) { - return true - } - } - } - return false -} - -func (c *calledFrom) succs(b *ssa.BasicBlock) bool { - if c.done == nil { - c.done = map[*ssa.BasicBlock]bool{} - } - - if c.done[b] { - return true - } - c.done[b] = true - - if len(b.Succs) == 0 { - return false - } - - for _, s := range b.Succs { - if !c.instrs(s.Instrs) && !c.succs(s) { - return false - } - } - - return true -} - -func (c *calledFrom) storedInInstrs(instrs []ssa.Instruction) bool { - for _, instr := range instrs { - switch instr := instr.(type) { - case *ssa.Store: - if instr.Val == c.recv { - return true - } - } - } - return false -} - -func (c *calledFrom) storedInSuccs(b *ssa.BasicBlock) bool { - if c.done == nil { - c.done = map[*ssa.BasicBlock]bool{} - } - - if c.done[b] { - return true - } - c.done[b] = true - - if len(b.Succs) == 0 { - return false - } - - for _, s := range b.Succs { - if !c.storedInInstrs(s.Instrs) && !c.succs(s) { - return false - } - } - - return true -} - -func (c *calledFrom) isRecv(recv, typ types.Type) bool { - return recv == typ || identical(recv, typ) || - c.isRecvInTuple(recv, typ) || c.isRecvInEmbedded(recv, typ) -} - -func (c *calledFrom) isRecvInTuple(recv, typ types.Type) bool { - tuple, _ := typ.(*types.Tuple) - if tuple == nil { - return false - } - - for i := 0; i < tuple.Len(); i++ { - if c.isRecv(recv, tuple.At(i).Type()) { - return true - } - } - - return false -} - -func (c *calledFrom) isRecvInEmbedded(recv, typ types.Type) bool { - - var st *types.Struct - switch typ := typ.(type) { - case *types.Struct: - st = typ - case *types.Pointer: - return c.isRecvInEmbedded(recv, typ.Elem()) - case *types.Named: - return c.isRecvInEmbedded(recv, typ.Underlying()) - default: - return false - } - - for i := 0; i < st.NumFields(); i++ { - field := st.Field(i) - if !field.Embedded() { - continue - } - - ft := field.Type() - if c.isRecv(recv, ft) { - return true - } - - var ptrOrUnptr types.Type - switch ft := ft.(type) { - case *types.Pointer: - // struct { *T } -> T - ptrOrUnptr = ft.Elem() - default: - // struct { T } -> *T - ptrOrUnptr = types.NewPointer(ft) - } - - if c.isRecv(recv, ptrOrUnptr) { - return true - } - } - - return false -} - -// NotCalledIn checks whether receiver's method is called in a function. -// If there is no methods calling at a path from an instruction -// which type is receiver to all return instruction, NotCalledIn returns these instructions. -func NotCalledIn(f *ssa.Function, receiver types.Type, methods ...*types.Func) []ssa.Instruction { - return new(CalledChecker).NotIn(f, receiver, methods...) -} - -// CalledFrom checks whether receiver's method is called in an instruction -// which belogns to after i-th instructions, or in succsor blocks of b. -// The first result is above value. -// The second result is whether type of i-th instruction does not much receiver -// or matches with ignore cases. -func CalledFrom(b *ssa.BasicBlock, i int, receiver types.Type, methods ...*types.Func) (called, ok bool) { - return new(CalledChecker).From(b, i, receiver, methods...) -} - -// Called returns true when f is called in the instr. -// If recv is not nil, Called also checks the receiver. -func Called(instr ssa.Instruction, recv ssa.Value, f *types.Func) bool { - return new(CalledChecker).Func(instr, recv, f) -} diff --git a/vendor/github.com/gostaticanalysis/analysisutil/diagnostic.go b/vendor/github.com/gostaticanalysis/analysisutil/diagnostic.go deleted file mode 100644 index a911db6f19..0000000000 --- a/vendor/github.com/gostaticanalysis/analysisutil/diagnostic.go +++ /dev/null @@ -1,45 +0,0 @@ -package analysisutil - -import ( - "go/token" - - "github.com/gostaticanalysis/comment" - "github.com/gostaticanalysis/comment/passes/commentmap" - "golang.org/x/tools/go/analysis" -) - -// ReportWithoutIgnore returns a report function which can set to (analysis.Pass).Report. -// The report function ignores a diagnostic which annotated by ignore comment as the below. -// //lint:ignore Check1[,Check2,...,CheckN] reason -// names is a list of checker names. -// If names was omitted, the report function ignores by pass.Analyzer.Name. -func ReportWithoutIgnore(pass *analysis.Pass, names ...string) func(analysis.Diagnostic) { - cmaps, _ := pass.ResultOf[commentmap.Analyzer].(comment.Maps) - if cmaps == nil { - cmaps = comment.New(pass.Fset, pass.Files) - } - - if len(names) == 0 { - names = []string{pass.Analyzer.Name} - } - - report := pass.Report // original report func - - return func(d analysis.Diagnostic) { - start := pass.Fset.File(d.Pos).Line(d.Pos) - end := start - if d.End != token.NoPos { - end = pass.Fset.File(d.End).Line(d.End) - } - - for l := start; l <= end; l++ { - for _, n := range names { - if cmaps.IgnoreLine(pass.Fset, l, n) { - return - } - } - } - - report(d) - } -} diff --git a/vendor/github.com/gostaticanalysis/analysisutil/file.go b/vendor/github.com/gostaticanalysis/analysisutil/file.go deleted file mode 100644 index b9b2955304..0000000000 --- a/vendor/github.com/gostaticanalysis/analysisutil/file.go +++ /dev/null @@ -1,30 +0,0 @@ -package analysisutil - -import ( - "go/ast" - "go/token" - "regexp" - - "golang.org/x/tools/go/analysis" -) - -// File finds *ast.File in pass.Files by pos. -func File(pass *analysis.Pass, pos token.Pos) *ast.File { - for _, f := range pass.Files { - if f.Pos() <= pos && pos <= f.End() { - return f - } - } - return nil -} - -var genCommentRegexp = regexp.MustCompile(`^// Code generated .* DO NOT EDIT\.$`) - -// IsGeneratedFile reports whether the file has been generated automatically. -// If file is nil, IsGeneratedFile will return false. -func IsGeneratedFile(file *ast.File) bool { - if file == nil || len(file.Comments) == 0 { - return false - } - return genCommentRegexp.MatchString(file.Comments[0].List[0].Text) -} diff --git a/vendor/github.com/gostaticanalysis/analysisutil/pkg.go b/vendor/github.com/gostaticanalysis/analysisutil/pkg.go deleted file mode 100644 index b64150d810..0000000000 --- a/vendor/github.com/gostaticanalysis/analysisutil/pkg.go +++ /dev/null @@ -1,49 +0,0 @@ -package analysisutil - -import ( - "go/types" - "strconv" - "strings" - - "golang.org/x/tools/go/analysis" -) - -// RemoVendor removes vendoring information from import path. -func RemoveVendor(path string) string { - i := strings.Index(path, "vendor/") - if i >= 0 { - return path[i+len("vendor/"):] - } - return path -} - -// LookupFromImports finds an object from import paths. -func LookupFromImports(imports []*types.Package, path, name string) types.Object { - path = RemoveVendor(path) - for i := range imports { - if path == RemoveVendor(imports[i].Path()) { - return imports[i].Scope().Lookup(name) - } - } - return nil -} - -// Imported returns true when the given pass imports the pkg. -func Imported(pkgPath string, pass *analysis.Pass) bool { - fs := pass.Files - if len(fs) == 0 { - return false - } - for _, f := range fs { - for _, i := range f.Imports { - path, err := strconv.Unquote(i.Path.Value) - if err != nil { - continue - } - if RemoveVendor(path) == pkgPath { - return true - } - } - } - return false -} diff --git a/vendor/github.com/gostaticanalysis/analysisutil/ssa.go b/vendor/github.com/gostaticanalysis/analysisutil/ssa.go deleted file mode 100644 index 2e22bbe798..0000000000 --- a/vendor/github.com/gostaticanalysis/analysisutil/ssa.go +++ /dev/null @@ -1,152 +0,0 @@ -package analysisutil - -import ( - "golang.org/x/tools/go/ssa" -) - -// IfInstr returns *ssa.If which is contained in the block b. -// If the block b has not any if instruction, IfInstr returns nil. -func IfInstr(b *ssa.BasicBlock) *ssa.If { - if len(b.Instrs) == 0 { - return nil - } - - ifinstr, ok := b.Instrs[len(b.Instrs)-1].(*ssa.If) - if !ok { - return nil - } - - return ifinstr -} - -// Phi returns phi values which are contained in the block b. -func Phi(b *ssa.BasicBlock) []*ssa.Phi { - var phis []*ssa.Phi - for _, instr := range b.Instrs { - if phi, ok := instr.(*ssa.Phi); ok { - phis = append(phis, phi) - } else { - // no more phi - break - } - } - return phis -} - -// Returns returns a slice of *ssa.Return in the function. -func Returns(v ssa.Value) []*ssa.Return { - var fn *ssa.Function - switch v := v.(type) { - case *ssa.Function: - fn = v - case *ssa.MakeClosure: - return Returns(v.Fn) - default: - return nil - } - - var rets []*ssa.Return - done := map[*ssa.BasicBlock]bool{} - for _, b := range fn.Blocks { - rets = append(rets, returnsInBlock(b, done)...) - } - return rets -} - -func returnsInBlock(b *ssa.BasicBlock, done map[*ssa.BasicBlock]bool) (rets []*ssa.Return) { - if done[b] { - return nil - } - done[b] = true - - if b.Index != 0 && len(b.Preds) == 0 { - return nil - } - - if len(b.Instrs) != 0 { - switch instr := b.Instrs[len(b.Instrs)-1].(type) { - case *ssa.Return: - rets = append(rets, instr) - } - } - - for _, s := range b.Succs { - rets = append(rets, returnsInBlock(s, done)...) - } - - return rets -} - -// BinOp returns binary operator values which are contained in the block b. -func BinOp(b *ssa.BasicBlock) []*ssa.BinOp { - var binops []*ssa.BinOp - for _, instr := range b.Instrs { - if binop, ok := instr.(*ssa.BinOp); ok { - binops = append(binops, binop) - } - } - return binops -} - -// Used returns an instruction which uses the value in the instructions. -func Used(v ssa.Value, instrs []ssa.Instruction) ssa.Instruction { - if len(instrs) == 0 || v.Referrers() == nil { - return nil - } - - for _, instr := range instrs { - if used := usedInInstr(v, instr); used != nil { - return used - } - } - - return nil -} - -func usedInInstr(v ssa.Value, instr ssa.Instruction) ssa.Instruction { - switch instr := instr.(type) { - case *ssa.MakeClosure: - return usedInClosure(v, instr) - default: - operands := instr.Operands(nil) - for _, x := range operands { - if x != nil && *x == v { - return instr - } - } - } - - switch v := v.(type) { - case *ssa.UnOp: - return usedInInstr(v.X, instr) - } - - return nil -} - -func usedInClosure(v ssa.Value, instr *ssa.MakeClosure) ssa.Instruction { - fn, _ := instr.Fn.(*ssa.Function) - if fn == nil { - return nil - } - - var fv *ssa.FreeVar - for i := range instr.Bindings { - if instr.Bindings[i] == v { - fv = fn.FreeVars[i] - break - } - } - - if fv == nil { - return nil - } - - for _, b := range fn.Blocks { - if used := Used(fv, b.Instrs); used != nil { - return used - } - } - - return nil -} diff --git a/vendor/github.com/gostaticanalysis/analysisutil/ssainspect.go b/vendor/github.com/gostaticanalysis/analysisutil/ssainspect.go deleted file mode 100644 index b2ae75f244..0000000000 --- a/vendor/github.com/gostaticanalysis/analysisutil/ssainspect.go +++ /dev/null @@ -1,47 +0,0 @@ -package analysisutil - -import "golang.org/x/tools/go/ssa" - -// InspectFuncs inspects functions. -func InspectFuncs(funcs []*ssa.Function, f func(i int, instr ssa.Instruction) bool) { - for _, fun := range funcs { - if len(fun.Blocks) == 0 { - continue - } - new(instrInspector).block(fun.Blocks[0], 0, f) - } -} - -// InspectInstr inspects from i-th instruction of start block to succsessor blocks. -func InspectInstr(start *ssa.BasicBlock, i int, f func(i int, instr ssa.Instruction) bool) { - new(instrInspector).block(start, i, f) -} - -type instrInspector struct { - done map[*ssa.BasicBlock]bool -} - -func (ins *instrInspector) block(b *ssa.BasicBlock, i int, f func(i int, instr ssa.Instruction) bool) { - if ins.done == nil { - ins.done = map[*ssa.BasicBlock]bool{} - } - - if b == nil || ins.done[b] || len(b.Instrs) <= i { - return - } - - ins.done[b] = true - ins.instrs(i, b.Instrs[i:], f) - for _, s := range b.Succs { - ins.block(s, 0, f) - } - -} - -func (ins *instrInspector) instrs(offset int, instrs []ssa.Instruction, f func(i int, instr ssa.Instruction) bool) { - for i, instr := range instrs { - if !f(offset+i, instr) { - break - } - } -} diff --git a/vendor/github.com/gostaticanalysis/analysisutil/types.go b/vendor/github.com/gostaticanalysis/analysisutil/types.go deleted file mode 100644 index 8265efc8ed..0000000000 --- a/vendor/github.com/gostaticanalysis/analysisutil/types.go +++ /dev/null @@ -1,228 +0,0 @@ -package analysisutil - -import ( - "go/ast" - "go/types" - - "golang.org/x/tools/go/analysis" -) - -var errType = types.Universe.Lookup("error").Type().Underlying().(*types.Interface) - -// ImplementsError return whether t implements error interface. -func ImplementsError(t types.Type) bool { - return types.Implements(t, errType) -} - -// ObjectOf returns types.Object by given name in the package. -func ObjectOf(pass *analysis.Pass, pkg, name string) types.Object { - obj := LookupFromImports(pass.Pkg.Imports(), pkg, name) - if obj != nil { - return obj - } - if RemoveVendor(pass.Pkg.Name()) != RemoveVendor(pkg) { - return nil - } - return pass.Pkg.Scope().Lookup(name) -} - -// TypeOf returns types.Type by given name in the package. -// TypeOf accepts pointer types such as *T. -func TypeOf(pass *analysis.Pass, pkg, name string) types.Type { - if name == "" { - return nil - } - - if name[0] == '*' { - obj := TypeOf(pass, pkg, name[1:]) - if obj == nil { - return nil - } - return types.NewPointer(obj) - } - - obj := ObjectOf(pass, pkg, name) - if obj == nil { - return nil - } - - return obj.Type() -} - -// MethodOf returns a method which has given name in the type. -func MethodOf(typ types.Type, name string) *types.Func { - switch typ := typ.(type) { - case *types.Named: - for i := 0; i < typ.NumMethods(); i++ { - if f := typ.Method(i); f.Name() == name { - return f - } - } - case *types.Pointer: - return MethodOf(typ.Elem(), name) - } - return nil -} - -// see: https://github.com/golang/go/issues/19670 -func identical(x, y types.Type) (ret bool) { - defer func() { - r := recover() - switch r := r.(type) { - case string: - if r == "unreachable" { - ret = false - return - } - case nil: - return - } - panic(r) - }() - return types.Identical(x, y) -} - -// Interfaces returns a map of interfaces which are declared in the package. -func Interfaces(pkg *types.Package) map[string]*types.Interface { - ifs := map[string]*types.Interface{} - - for _, n := range pkg.Scope().Names() { - o := pkg.Scope().Lookup(n) - if o != nil { - i, ok := o.Type().Underlying().(*types.Interface) - if ok { - ifs[n] = i - } - } - } - - return ifs -} - -// Structs returns a map of structs which are declared in the package. -func Structs(pkg *types.Package) map[string]*types.Struct { - structs := map[string]*types.Struct{} - - for _, n := range pkg.Scope().Names() { - o := pkg.Scope().Lookup(n) - if o != nil { - s, ok := o.Type().Underlying().(*types.Struct) - if ok { - structs[n] = s - } - } - } - - return structs -} - -// HasField returns whether the struct has the field. -func HasField(s *types.Struct, f *types.Var) bool { - if s == nil || f == nil { - return false - } - - for i := 0; i < s.NumFields(); i++ { - if s.Field(i) == f { - return true - } - } - - return false -} - -// Field returns field of the struct type. -// If the type is not struct or has not the field, -// Field returns -1, nil. -// If the type is a named type or a pointer type, -// Field calls itself recursively with -// an underlying type or an element type of pointer. -func Field(t types.Type, name string) (int, *types.Var) { - switch t := t.(type) { - case *types.Pointer: - return Field(t.Elem(), name) - case *types.Named: - return Field(t.Underlying(), name) - case *types.Struct: - for i := 0; i < t.NumFields(); i++ { - f := t.Field(i) - if f.Name() == name { - return i, f - } - } - } - - return -1, nil -} - -func TypesInfo(info ...*types.Info) *types.Info { - if len(info) == 0 { - return nil - } - - var merged types.Info - for i := range info { - mergeTypesInfo(&merged, info[i]) - } - - return &merged -} - -func mergeTypesInfo(i1, i2 *types.Info) { - // Types - if i1.Types == nil && i2.Types != nil { - i1.Types = map[ast.Expr]types.TypeAndValue{} - } - for expr, tv := range i2.Types { - i1.Types[expr] = tv - } - - // Defs - if i1.Defs == nil && i2.Defs != nil { - i1.Defs = map[*ast.Ident]types.Object{} - } - for ident, obj := range i2.Defs { - i1.Defs[ident] = obj - } - - // Uses - if i1.Uses == nil && i2.Uses != nil { - i1.Uses = map[*ast.Ident]types.Object{} - } - for ident, obj := range i2.Uses { - i1.Uses[ident] = obj - } - - // Implicits - if i1.Implicits == nil && i2.Implicits != nil { - i1.Implicits = map[ast.Node]types.Object{} - } - for n, obj := range i2.Implicits { - i1.Implicits[n] = obj - } - - // Selections - if i1.Selections == nil && i2.Selections != nil { - i1.Selections = map[*ast.SelectorExpr]*types.Selection{} - } - for expr, sel := range i2.Selections { - i1.Selections[expr] = sel - } - - // Scopes - if i1.Scopes == nil && i2.Scopes != nil { - i1.Scopes = map[ast.Node]*types.Scope{} - } - for n, s := range i2.Scopes { - i1.Scopes[n] = s - } - - // InitOrder - i1.InitOrder = append(i1.InitOrder, i2.InitOrder...) -} - -// Under returns the most bottom underlying type. -// Deprecated: (types.Type).Underlying returns same value of it. -func Under(t types.Type) types.Type { - return t.Underlying() -} diff --git a/vendor/github.com/gostaticanalysis/comment/.tagpr b/vendor/github.com/gostaticanalysis/comment/.tagpr deleted file mode 100644 index 59bf985413..0000000000 --- a/vendor/github.com/gostaticanalysis/comment/.tagpr +++ /dev/null @@ -1,35 +0,0 @@ -# config file for the tagpr in git config format -# The tagpr generates the initial configuration, which you can rewrite to suit your environment. -# CONFIGURATIONS: -# tagpr.releaseBranch -# Generally, it is "main." It is the branch for releases. The pcpr tracks this branch, -# creates or updates a pull request as a release candidate, or tags when they are merged. -# -# tagpr.versionFile -# Versioning file containing the semantic version needed to be updated at release. -# It will be synchronized with the "git tag". -# Often this is a meta-information file such as gemspec, setup.cfg, package.json, etc. -# Sometimes the source code file, such as version.go or Bar.pm, is used. -# If you do not want to use versioning files but only git tags, specify the "-" string here. -# You can specify multiple version files by comma separated strings. -# -# tagpr.vPrefix -# Flag whether or not v-prefix is added to semver when git tagging. (e.g. v1.2.3 if true) -# This is only a tagging convention, not how it is described in the version file. -# -# tagpr.changelog (Optional) -# Flag whether or not changelog is added or changed during the release. -# -# tagpr.command (Optional) -# Command to change files just before release. -# -# tagpr.tmplate (Optional) -# Pull request template in go template format -# -# tagpr.release (Optional) -# GitHub Release creation behavior after tagging [true, draft, false] -# If this value is not set, the release is to be created. -[tagpr] - vPrefix = true - releaseBranch = main - versionFile = version.txt diff --git a/vendor/github.com/gostaticanalysis/comment/CHANGELOG.md b/vendor/github.com/gostaticanalysis/comment/CHANGELOG.md deleted file mode 100644 index 941cc15ff1..0000000000 --- a/vendor/github.com/gostaticanalysis/comment/CHANGELOG.md +++ /dev/null @@ -1,34 +0,0 @@ -# Changelog - -## [v1.5.0](https://github.com/gostaticanalysis/comment/compare/v1.4.2...v1.5.0) - 2024-11-15 -- Add tagpr and testvet by @tenntenn in https://github.com/gostaticanalysis/comment/pull/18 -- Add IgnorePosLine and deprecate IgnoreLine by @neglect-yp in https://github.com/gostaticanalysis/comment/pull/17 -- Fix errors for testvet by @tenntenn in https://github.com/gostaticanalysis/comment/pull/20 -- Add version.txt by @tenntenn in https://github.com/gostaticanalysis/comment/pull/21 -- Update go version and dependencies by @tenntenn in https://github.com/gostaticanalysis/comment/pull/19 - -## [v1.4.2](https://github.com/gostaticanalysis/comment/compare/v1.4.1...v1.4.2) - 2021-03-03 -- passes/commentmap: use txtar for testdata by @zchee in https://github.com/gostaticanalysis/comment/pull/14 -- github/workflows: add test GHA by @zchee in https://github.com/gostaticanalysis/comment/pull/15 -- omment: fix hasIgnoreCheck to more pares lines by @zchee in https://github.com/gostaticanalysis/comment/pull/16 - -## [v1.4.1](https://github.com/gostaticanalysis/comment/compare/v1.4.0...v1.4.1) - 2020-09-10 -- Fix comment directive parsing in Go 1.15+ by @nmiyake in https://github.com/gostaticanalysis/comment/pull/13 -- gofmt files by @nmiyake in https://github.com/gostaticanalysis/comment/pull/12 -- Fix logic error in hasIgnoreCheck by @nmiyake in https://github.com/gostaticanalysis/comment/pull/11 - -## [v1.4.0](https://github.com/gostaticanalysis/comment/compare/v1.3.0...v1.4.0) - 2020-08-20 -- Add CommentsByPosLine by @tenntenn in https://github.com/gostaticanalysis/comment/pull/9 - -## [v1.3.0](https://github.com/gostaticanalysis/comment/compare/v1.2.0...v1.3.0) - 2020-01-30 -- Fix link to ast package by @po3rin in https://github.com/gostaticanalysis/comment/pull/4 -- Add IgnoreLine by @tenntenn in https://github.com/gostaticanalysis/comment/pull/5 - -## [v1.2.0](https://github.com/gostaticanalysis/comment/compare/v1.1.0...v1.2.0) - 2019-03-18 -- Add IgnorePos by @tenntenn in https://github.com/gostaticanalysis/comment/pull/3 - -## [v1.1.0](https://github.com/gostaticanalysis/comment/compare/v1.0.0...v1.1.0) - 2019-03-08 -- Add ignore by @tenntenn in https://github.com/gostaticanalysis/comment/pull/1 -- Fix Ignore and add tests by @tenntenn in https://github.com/gostaticanalysis/comment/pull/2 - -## [v1.0.0](https://github.com/gostaticanalysis/comment/commits/v1.0.0) - 2019-03-08 diff --git a/vendor/github.com/gostaticanalysis/comment/LICENSE b/vendor/github.com/gostaticanalysis/comment/LICENSE deleted file mode 100644 index 4f7eeff5ba..0000000000 --- a/vendor/github.com/gostaticanalysis/comment/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2018 Takuya Ueda - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/gostaticanalysis/comment/README.md b/vendor/github.com/gostaticanalysis/comment/README.md deleted file mode 100644 index 5335553137..0000000000 --- a/vendor/github.com/gostaticanalysis/comment/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# gostaticanalysis/comment - -[![godoc.org][godoc-badge]][godoc] - -`comment` provides utilities for [ast.CommentMap](https://golang.org/pkg/go/ast/#CommentMap). - - -[godoc]: https://godoc.org/github.com/gostaticanalysis/comment -[godoc-badge]: https://img.shields.io/badge/godoc-reference-4F73B3.svg?style=flat-square&label=%20godoc.org - diff --git a/vendor/github.com/gostaticanalysis/comment/comment.go b/vendor/github.com/gostaticanalysis/comment/comment.go deleted file mode 100644 index 2e418a4669..0000000000 --- a/vendor/github.com/gostaticanalysis/comment/comment.go +++ /dev/null @@ -1,169 +0,0 @@ -package comment - -import ( - "go/ast" - "go/token" - "strings" -) - -// Maps is slice of ast.CommentMap. -type Maps []ast.CommentMap - -// New creates new a CommentMap slice from specified files. -func New(fset *token.FileSet, files []*ast.File) Maps { - maps := make(Maps, len(files)) - for i := range files { - maps[i] = ast.NewCommentMap(fset, files[i], files[i].Comments) - } - return maps -} - -// Comments returns correspond a CommentGroup slice to specified AST node. -func (maps Maps) Comments(n ast.Node) []*ast.CommentGroup { - for i := range maps { - if maps[i][n] != nil { - return maps[i][n] - } - } - return nil -} - -// CommentsByPos returns correspond a CommentGroup slice to specified pos. -func (maps Maps) CommentsByPos(pos token.Pos) []*ast.CommentGroup { - for i := range maps { - for n, cgs := range maps[i] { - if n.Pos() == pos { - return cgs - } - } - } - return nil -} - -// Annotated checks either specified AST node is annotated or not. -func (maps Maps) Annotated(n ast.Node, annotation string) bool { - for _, cg := range maps.Comments(n) { - if strings.HasPrefix(strings.TrimSpace(cg.Text()), annotation) { - return true - } - } - return false -} - -// Ignore checks either specified AST node is ignored by the check. -// It follows staticcheck style as the below. -// -// //lint:ignore Check1[,Check2,...,CheckN] reason -func (maps Maps) Ignore(n ast.Node, check string) bool { - for _, cg := range maps.Comments(n) { - if hasIgnoreCheck(cg, check) { - return true - } - } - return false -} - -// IgnorePos checks either specified postion of AST node is ignored by the check. -// It follows staticcheck style as the below. -// -// //lint:ignore Check1[,Check2,...,CheckN] reason -func (maps Maps) IgnorePos(pos token.Pos, check string) bool { - for _, cg := range maps.CommentsByPos(pos) { - if hasIgnoreCheck(cg, check) { - return true - } - } - return false -} - -// Deprecated: This function does not work with multiple files. -// CommentsByPosLine can be used instead of CommentsByLine. -// -// CommentsByLine returns correspond a CommentGroup slice to specified line. -func (maps Maps) CommentsByLine(fset *token.FileSet, line int) []*ast.CommentGroup { - for i := range maps { - for n, cgs := range maps[i] { - l := fset.File(n.Pos()).Line(n.Pos()) - if l == line { - return cgs - } - } - } - return nil -} - -// CommentsByPosLine returns correspond a CommentGroup slice to specified line. -func (maps Maps) CommentsByPosLine(fset *token.FileSet, pos token.Pos) []*ast.CommentGroup { - f1 := fset.File(pos) - for i := range maps { - for n, cgs := range maps[i] { - f2 := fset.File(n.Pos()) - if f1 != f2 { - // different file - continue - } - - if f1.Line(pos) == f2.Line(n.Pos()) { - return cgs - } - } - } - return nil -} - -// Deprecated: This function does not work with multiple files. -// IgnoreLine checks either specified lineof AST node is ignored by the check. -// It follows staticcheck style as the below. -// -// //lint:ignore Check1[,Check2,...,CheckN] reason -func (maps Maps) IgnoreLine(fset *token.FileSet, line int, check string) bool { - for _, cg := range maps.CommentsByLine(fset, line) { - if hasIgnoreCheck(cg, check) { - return true - } - } - return false -} - -// IgnorePosLine checks either specified lineof AST node is ignored by the check. -// It follows staticcheck style as the below. -// -// //lint:ignore Check1[,Check2,...,CheckN] reason -func (maps Maps) IgnorePosLine(fset *token.FileSet, pos token.Pos, check string) bool { - for _, cg := range maps.CommentsByPosLine(fset, pos) { - if hasIgnoreCheck(cg, check) { - return true - } - } - return false -} - -// hasIgnoreCheck returns true if the provided CommentGroup starts with a comment -// of the form "//lint:ignore Check1[,Check2,...,CheckN] reason" and one of the -// checks matches the provided check. -// -// The *ast.CommentGroup is checked directly rather than using "cg.Text()" because, -// starting in Go 1.15, the "cg.Text()" call no longer returns directive-style -// comments (see https://github.com/golang/go/issues/37974). -func hasIgnoreCheck(cg *ast.CommentGroup, check string) bool { - for _, list := range cg.List { - if !strings.HasPrefix(list.Text, "//") { - continue - } - - s := strings.TrimSpace(list.Text[2:]) // list.Text[2:]: trim "//" - txt := strings.Split(s, " ") - if len(txt) < 3 || txt[0] != "lint:ignore" { - continue - } - - checks := strings.Split(txt[1], ",") // txt[1]: trim "lint:ignore" - for i := range checks { - if check == checks[i] { - return true - } - } - } - - return false -} diff --git a/vendor/github.com/gostaticanalysis/comment/passes/commentmap/commentmap.go b/vendor/github.com/gostaticanalysis/comment/passes/commentmap/commentmap.go deleted file mode 100644 index 1b60a160ca..0000000000 --- a/vendor/github.com/gostaticanalysis/comment/passes/commentmap/commentmap.go +++ /dev/null @@ -1,21 +0,0 @@ -package commentmap - -import ( - "reflect" - - "golang.org/x/tools/go/analysis" - - "github.com/gostaticanalysis/comment" -) - -var Analyzer = &analysis.Analyzer{ - Name: "commentmap", - Doc: "create comment map", - Run: run, - RunDespiteErrors: true, - ResultType: reflect.TypeOf(comment.Maps{}), -} - -func run(pass *analysis.Pass) (interface{}, error) { - return comment.New(pass.Fset, pass.Files), nil -} diff --git a/vendor/github.com/gostaticanalysis/comment/version.txt b/vendor/github.com/gostaticanalysis/comment/version.txt deleted file mode 100644 index 2e7bd91085..0000000000 --- a/vendor/github.com/gostaticanalysis/comment/version.txt +++ /dev/null @@ -1 +0,0 @@ -v1.5.0 diff --git a/vendor/github.com/gostaticanalysis/forcetypeassert/.reviewdog.yml b/vendor/github.com/gostaticanalysis/forcetypeassert/.reviewdog.yml deleted file mode 100644 index 2e243ff73a..0000000000 --- a/vendor/github.com/gostaticanalysis/forcetypeassert/.reviewdog.yml +++ /dev/null @@ -1,8 +0,0 @@ -runner: - golint: - cmd: golint ./... - errorformat: - - "%f:%l:%c: %m" - level: warning - govet: - cmd: go vet -all . diff --git a/vendor/github.com/gostaticanalysis/forcetypeassert/.tagpr b/vendor/github.com/gostaticanalysis/forcetypeassert/.tagpr deleted file mode 100644 index 59bf985413..0000000000 --- a/vendor/github.com/gostaticanalysis/forcetypeassert/.tagpr +++ /dev/null @@ -1,35 +0,0 @@ -# config file for the tagpr in git config format -# The tagpr generates the initial configuration, which you can rewrite to suit your environment. -# CONFIGURATIONS: -# tagpr.releaseBranch -# Generally, it is "main." It is the branch for releases. The pcpr tracks this branch, -# creates or updates a pull request as a release candidate, or tags when they are merged. -# -# tagpr.versionFile -# Versioning file containing the semantic version needed to be updated at release. -# It will be synchronized with the "git tag". -# Often this is a meta-information file such as gemspec, setup.cfg, package.json, etc. -# Sometimes the source code file, such as version.go or Bar.pm, is used. -# If you do not want to use versioning files but only git tags, specify the "-" string here. -# You can specify multiple version files by comma separated strings. -# -# tagpr.vPrefix -# Flag whether or not v-prefix is added to semver when git tagging. (e.g. v1.2.3 if true) -# This is only a tagging convention, not how it is described in the version file. -# -# tagpr.changelog (Optional) -# Flag whether or not changelog is added or changed during the release. -# -# tagpr.command (Optional) -# Command to change files just before release. -# -# tagpr.tmplate (Optional) -# Pull request template in go template format -# -# tagpr.release (Optional) -# GitHub Release creation behavior after tagging [true, draft, false] -# If this value is not set, the release is to be created. -[tagpr] - vPrefix = true - releaseBranch = main - versionFile = version.txt diff --git a/vendor/github.com/gostaticanalysis/forcetypeassert/CHANGELOG.md b/vendor/github.com/gostaticanalysis/forcetypeassert/CHANGELOG.md deleted file mode 100644 index 7575fec629..0000000000 --- a/vendor/github.com/gostaticanalysis/forcetypeassert/CHANGELOG.md +++ /dev/null @@ -1,19 +0,0 @@ -# Changelog - -## [v0.2.0](https://github.com/gostaticanalysis/forcetypeassert/compare/v0.1.0...v0.2.0) - 2025-02-13 -- Update x/tools to fix panic in tests by @alexandear in https://github.com/gostaticanalysis/forcetypeassert/pull/19 -- go.mod: bump golang.org/x/tools dependency by @egonelbre in https://github.com/gostaticanalysis/forcetypeassert/pull/20 -- Add tagpr and version up Go and dependencies by @tenntenn in https://github.com/gostaticanalysis/forcetypeassert/pull/21 -- Support any by @tenntenn in https://github.com/gostaticanalysis/forcetypeassert/pull/23 -- Fix for #18 by @tenntenn in https://github.com/gostaticanalysis/forcetypeassert/pull/24 - -## [v0.1.0](https://github.com/gostaticanalysis/forcetypeassert/commits/v0.1.0) - 2021-09-08 -- update check pattern by @knsh14 in https://github.com/gostaticanalysis/forcetypeassert/pull/1 -- Fix typo by @tenntenn in https://github.com/gostaticanalysis/forcetypeassert/pull/3 -- Add reviewdog setting by @tenntenn in https://github.com/gostaticanalysis/forcetypeassert/pull/4 -- Add an explanation on how to fix the linter errors by @ozon2 in https://github.com/gostaticanalysis/forcetypeassert/pull/9 -- Delete reviewdog.yml by @tenntenn in https://github.com/gostaticanalysis/forcetypeassert/pull/11 -- Create testandvet.yml by @tenntenn in https://github.com/gostaticanalysis/forcetypeassert/pull/10 -- Fix bug for valuespec by @tenntenn in https://github.com/gostaticanalysis/forcetypeassert/pull/12 -- Fix bugs for expressions by @tenntenn in https://github.com/gostaticanalysis/forcetypeassert/pull/13 -- Add result by @tenntenn in https://github.com/gostaticanalysis/forcetypeassert/pull/14 diff --git a/vendor/github.com/gostaticanalysis/forcetypeassert/LICENSE b/vendor/github.com/gostaticanalysis/forcetypeassert/LICENSE deleted file mode 100644 index bf7e33db84..0000000000 --- a/vendor/github.com/gostaticanalysis/forcetypeassert/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2019 GoStaticAnalysis - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/gostaticanalysis/forcetypeassert/README.md b/vendor/github.com/gostaticanalysis/forcetypeassert/README.md deleted file mode 100644 index 36a47594e3..0000000000 --- a/vendor/github.com/gostaticanalysis/forcetypeassert/README.md +++ /dev/null @@ -1,28 +0,0 @@ -# forcetypeassert - -[![godoc.org][godoc-badge]][godoc] - -`forcetypeassert` finds type assertions which did forcely such as below. - -```go -func f() { - var a interface{} - _ = a.(int) // type assertion must be checked -} -``` - -You need to check if the assertion failed like so: -```go -func f() { - var a interface{} - _, ok := a.(int) - if !ok { // type assertion failed - // handle error - } -} -``` - - -[godoc]: https://godoc.org/github.com/gostaticanalysis/forcetypeassert -[godoc-badge]: https://img.shields.io/badge/godoc-reference-4F73B3.svg?style=flat-square&label=%20godoc.org - diff --git a/vendor/github.com/gostaticanalysis/forcetypeassert/forcetypeassert.go b/vendor/github.com/gostaticanalysis/forcetypeassert/forcetypeassert.go deleted file mode 100644 index e1b21825b1..0000000000 --- a/vendor/github.com/gostaticanalysis/forcetypeassert/forcetypeassert.go +++ /dev/null @@ -1,164 +0,0 @@ -package forcetypeassert - -import ( - "go/ast" - "go/types" - "reflect" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/inspector" -) - -var Analyzer = &analysis.Analyzer{ - Name: "forcetypeassert", - Doc: Doc, - Run: run, - Requires: []*analysis.Analyzer{ - inspect.Analyzer, - }, - ResultType: reflect.TypeOf((*Panicable)(nil)), -} - -// Panicable stores panicable type assertions. -type Panicable struct { - m map[ast.Node]bool - nodes []ast.Node -} - -// Check checks whether the node may occur panic or not. -func (p *Panicable) Check(n ast.Node) bool { - return p.m[n] -} - -// Len is number of panicable nodes. -func (p *Panicable) Len() int { - return len(p.nodes) -} - -// At returns the i-th panicable node. -func (p *Panicable) At(i int) ast.Node { - return p.nodes[i] -} - -const Doc = "forcetypeassert is finds type assertions which did forcely" - -var anyTyp = types.Universe.Lookup("any").Type() - -func run(pass *analysis.Pass) (any, error) { - inspect, _ := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - result := &Panicable{m: make(map[ast.Node]bool)} - - nodeFilter := []ast.Node{ - (*ast.AssignStmt)(nil), - (*ast.ValueSpec)(nil), - (*ast.TypeAssertExpr)(nil), - } - - inspect.Nodes(nodeFilter, func(n ast.Node, push bool) bool { - if !push { - return false - } - switch n := n.(type) { - case *ast.AssignStmt: - return checkAssignStmt(pass, result, n) - case *ast.ValueSpec: - return checkValueSpec(pass, result, n) - case *ast.TypeAssertExpr: - if n.Type != nil && !isAny(pass, n.Type) { - result.m[n] = true - result.nodes = append(result.nodes, n) - pass.Reportf(n.Pos(), "type assertion must be checked") - } - return false - } - - return true - }) - - return result, nil -} - -func isAny(pass *analysis.Pass, expr ast.Expr) bool { - return types.Identical(pass.TypesInfo.TypeOf(expr), anyTyp) -} - -func checkAssignStmt(pass *analysis.Pass, result *Panicable, n *ast.AssignStmt) bool { - tae := findTypeAssertion(n.Rhs) - if tae == nil { - return true - } - - switch { - - // if right hand is a call expression, assign statement can't assert boolean value which describes type assertion is succeeded - case len(n.Rhs) == 1 && isCallExpr(n.Rhs[0]): - pass.Reportf(n.Pos(), "right hand must be only type assertion") - return false - // if right hand has 2 or more values, assign statement can't assert boolean value which describes type assertion is succeeded - case len(n.Rhs) > 1: - pass.Reportf(n.Pos(), "right hand must be only type assertion") - return false - case len(n.Lhs) != 2 && tae.Type != nil && !isAny(pass, tae.Type): - result.m[n] = true - result.nodes = append(result.nodes, n) - pass.Reportf(n.Pos(), "type assertion must be checked") - return false - case len(n.Lhs) == 2: - return false - } - - return true -} - -func checkValueSpec(pass *analysis.Pass, result *Panicable, n *ast.ValueSpec) bool { - tae := findTypeAssertion(n.Values) - if tae == nil { - return true - } - - switch { - // if right hand is a call expression, assign statement can't assert boolean value which describes type assertion is succeeded - case len(n.Values) == 1 && isCallExpr(n.Values[0]): - pass.Reportf(n.Pos(), "right hand must be only type assertion") - return false - // if right hand has 2 or more values, assign statement can't assert boolean value which describes type assertion is succeeded - case len(n.Values) > 1: - pass.Reportf(n.Pos(), "right hand must be only type assertion") - return false - case len(n.Names) != 2 && tae.Type != nil && !isAny(pass, tae.Type): - result.m[n] = true - result.nodes = append(result.nodes, n) - pass.Reportf(n.Pos(), "type assertion must be checked") - return false - case len(n.Names) == 2: - return false - } - - return true -} - -func findTypeAssertion(exprs []ast.Expr) *ast.TypeAssertExpr { - for _, expr := range exprs { - var typeAssertExpr *ast.TypeAssertExpr - ast.Inspect(expr, func(n ast.Node) bool { - switch n := n.(type) { - case *ast.FuncLit: - return false - case *ast.TypeAssertExpr: - typeAssertExpr = n - return false - } - return true - }) - if typeAssertExpr != nil { - return typeAssertExpr - } - } - return nil -} - -func isCallExpr(expr ast.Expr) bool { - _, isCallExpr := expr.(*ast.CallExpr) - return isCallExpr -} diff --git a/vendor/github.com/gostaticanalysis/forcetypeassert/version.txt b/vendor/github.com/gostaticanalysis/forcetypeassert/version.txt deleted file mode 100644 index 1474d00f01..0000000000 --- a/vendor/github.com/gostaticanalysis/forcetypeassert/version.txt +++ /dev/null @@ -1 +0,0 @@ -v0.2.0 diff --git a/vendor/github.com/gostaticanalysis/nilerr/LICENSE b/vendor/github.com/gostaticanalysis/nilerr/LICENSE deleted file mode 100644 index bf7e33db84..0000000000 --- a/vendor/github.com/gostaticanalysis/nilerr/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2019 GoStaticAnalysis - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/gostaticanalysis/nilerr/README.md b/vendor/github.com/gostaticanalysis/nilerr/README.md deleted file mode 100644 index d2d8069bbd..0000000000 --- a/vendor/github.com/gostaticanalysis/nilerr/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# nilerr - -[![pkg.go.dev][gopkg-badge]][gopkg] - -`nilerr` finds code which returns nil even though it checks that error is not nil. - -```go -func f() error { - err := do() - if err != nil { - return nil // miss - } -} -``` - -`nilerr` also finds code which returns error even though it checks that error is nil. - -```go -func f() error { - err := do() - if err == nil { - return err // miss - } -} -``` - -`nilerr` ignores code which has a miss with ignore comment. - -```go -func f() error { - err := do() - if err != nil { - //lint:ignore nilerr reason - return nil // ignore - } -} -``` - -## How to use -``` -$ go install github.com/gostaticanalysis/nilerr/cmd/nilerr@latest -$ nilerr ./... -``` - - -[gopkg]: https://pkg.go.dev/github.com/gostaticanalysis/nilerr -[gopkg-badge]: https://pkg.go.dev/badge/github.com/gostaticanalysis/nilerr?status.svg diff --git a/vendor/github.com/gostaticanalysis/nilerr/nilerr.go b/vendor/github.com/gostaticanalysis/nilerr/nilerr.go deleted file mode 100644 index 4615e6d149..0000000000 --- a/vendor/github.com/gostaticanalysis/nilerr/nilerr.go +++ /dev/null @@ -1,311 +0,0 @@ -package nilerr - -import ( - "fmt" - "go/token" - "go/types" - "slices" - - "github.com/gostaticanalysis/comment" - "github.com/gostaticanalysis/comment/passes/commentmap" - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/buildssa" - "golang.org/x/tools/go/ssa" -) - -var Analyzer = &analysis.Analyzer{ - Name: "nilerr", - Doc: Doc, - Run: run, - Requires: []*analysis.Analyzer{ - buildssa.Analyzer, - commentmap.Analyzer, - }, -} - -const Doc = "nilerr checks returning nil when err is not nil" - -func run(pass *analysis.Pass) (interface{}, error) { - funcs := pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).SrcFuncs - cmaps := pass.ResultOf[commentmap.Analyzer].(comment.Maps) - - reportFail := func(v ssa.Value, ret *ssa.Return, format string) { - pos := ret.Pos() - if !cmaps.IgnorePos(pos, "nilerr") { - seen := map[string]struct{}{} - errLines := getValueLineNumbers(pass, v, seen) - - var errLineText string - if len(errLines) == 1 { - errLineText = fmt.Sprintf("line %d", errLines[0]) - } else { - errLineText = fmt.Sprintf("lines %v", errLines) - } - pass.Reportf(pos, format, errLineText) - } - } - - for i := range funcs { - for _, b := range funcs[i].Blocks { - if v := binOpErrNil(b, token.NEQ); v != nil { - if ret := isReturnNil(b.Succs[0]); ret != nil { - if !usesErrorValue(b.Succs[0], v) { - reportFail(v, ret, "error is not nil (%s) but it returns nil") - } - } - } else if v := binOpErrNil(b, token.EQL); v != nil { - if len(b.Succs[0].Preds) == 1 { // if there are multiple conditions, this may be false positive - if ret := isReturnError(b.Succs[0], v); ret != nil { - reportFail(v, ret, "error is nil (%s) but it returns error") - } - } - } - - } - } - - return nil, nil -} - -// getValueLineNumbers returns the line numbers. -// `seen` is used to avoid infinite loop. -func getValueLineNumbers(pass *analysis.Pass, v ssa.Value, seen map[string]struct{}) []int { - if phi, ok := v.(*ssa.Phi); ok { - result := make([]int, 0, len(phi.Edges)) - - for _, edge := range phi.Edges { - if _, ok := seen[edge.Name()]; ok { - if edge.Pos() == token.NoPos { - // Skip elements without a position. - continue - } - - result = append(result, pass.Fset.File(edge.Pos()).Line(edge.Pos())) - continue - } - - seen[edge.Name()] = struct{}{} - - result = append(result, getValueLineNumbers(pass, edge, seen)...) - } - - slices.Sort(result) - - return result - } - - value := v - if extract, ok := value.(*ssa.Extract); ok { - value = extract.Tuple - } - - pos := value.Pos() - - if pos == token.NoPos { - return nil - } - - return []int{pass.Fset.File(pos).Line(pos)} -} - -var errType = types.Universe.Lookup("error").Type().Underlying().(*types.Interface) - -func binOpErrNil(b *ssa.BasicBlock, op token.Token) ssa.Value { - if len(b.Instrs) == 0 { - return nil - } - - ifinst, ok := b.Instrs[len(b.Instrs)-1].(*ssa.If) - if !ok { - return nil - } - - binop, ok := ifinst.Cond.(*ssa.BinOp) - if !ok { - return nil - } - - if binop.Op != op { - return nil - } - - if !types.Implements(binop.X.Type(), errType) { - return nil - } - - if !types.Implements(binop.Y.Type(), errType) { - return nil - } - - xIsConst, yIsConst := isConst(binop.X), isConst(binop.Y) - switch { - case !xIsConst && yIsConst: // err != nil or err == nil - return binop.X - case xIsConst && !yIsConst: // nil != err or nil == err - return binop.Y - } - - return nil -} - -func isConst(v ssa.Value) bool { - _, ok := v.(*ssa.Const) - return ok -} - -func isReturnNil(b *ssa.BasicBlock) *ssa.Return { - if len(b.Instrs) == 0 { - return nil - } - - ret, ok := b.Instrs[len(b.Instrs)-1].(*ssa.Return) - if !ok { - return nil - } - - errorReturnValues := 0 - for _, res := range ret.Results { - if !types.Implements(res.Type(), errType) { - continue - } - - errorReturnValues++ - v, ok := res.(*ssa.Const) - if !ok { - return nil - } - - if !v.IsNil() { - return nil - } - } - - if errorReturnValues == 0 { - return nil - } - - return ret -} - -func isReturnError(b *ssa.BasicBlock, errVal ssa.Value) *ssa.Return { - if len(b.Instrs) == 0 { - return nil - } - - ret, ok := b.Instrs[len(b.Instrs)-1].(*ssa.Return) - if !ok { - return nil - } - - for _, v := range ret.Results { - if v == errVal { - return ret - } - } - - return nil -} - -func usesErrorValue(b *ssa.BasicBlock, errVal ssa.Value) bool { - for _, instr := range b.Instrs { - if callInstr, ok := instr.(*ssa.Call); ok { - for _, arg := range callInstr.Call.Args { - if isUsedInValue(arg, errVal) { - return true - } - - sliceArg, ok := arg.(*ssa.Slice) - if ok { - if isUsedInSlice(sliceArg, errVal) { - return true - } - } - } - } - } - return false -} - -type ReferrersHolder interface { - Referrers() *[]ssa.Instruction -} - -var _ ReferrersHolder = (ssa.Node)(nil) -var _ ReferrersHolder = (ssa.Value)(nil) - -func isUsedInSlice(sliceArg *ssa.Slice, errVal ssa.Value) bool { - var valueBuf [10]*ssa.Value - operands := sliceArg.Operands(valueBuf[:0]) - - var valuesToInspect []ssa.Value - addValueForInspection := func(value ssa.Value) { - if value != nil { - valuesToInspect = append(valuesToInspect, value) - } - } - - var nodesToInspect []ssa.Node - visitedNodes := map[ssa.Node]bool{} - addNodeForInspection := func(node ssa.Node) { - if !visitedNodes[node] { - visitedNodes[node] = true - nodesToInspect = append(nodesToInspect, node) - } - } - addReferrersForInspection := func(h ReferrersHolder) { - if h == nil { - return - } - - referrers := h.Referrers() - if referrers == nil { - return - } - - for _, r := range *referrers { - if node, ok := r.(ssa.Node); ok { - addNodeForInspection(node) - } - } - } - - for _, operand := range operands { - addReferrersForInspection(*operand) - addValueForInspection(*operand) - } - - for i := 0; i < len(nodesToInspect); i++ { - switch node := nodesToInspect[i].(type) { - case *ssa.IndexAddr: - addReferrersForInspection(node) - case *ssa.Store: - addValueForInspection(node.Val) - } - } - - for _, value := range valuesToInspect { - if isUsedInValue(value, errVal) { - return true - } - } - return false -} - -func isUsedInValue(value, lookedFor ssa.Value) bool { - if value == lookedFor { - return true - } - - switch value := value.(type) { - case *ssa.ChangeInterface: - return isUsedInValue(value.X, lookedFor) - case *ssa.MakeInterface: - return isUsedInValue(value.X, lookedFor) - case *ssa.Call: - if value.Call.IsInvoke() { - return isUsedInValue(value.Call.Value, lookedFor) - } - } - - return false -} diff --git a/vendor/github.com/hashicorp/errwrap/errwrap.go b/vendor/github.com/hashicorp/errwrap/errwrap.go index a733bef18c..44e368e569 100644 --- a/vendor/github.com/hashicorp/errwrap/errwrap.go +++ b/vendor/github.com/hashicorp/errwrap/errwrap.go @@ -44,6 +44,8 @@ func Wrap(outer, inner error) error { // // format is the format of the error message. The string '{{err}}' will // be replaced with the original error message. +// +// Deprecated: Use fmt.Errorf() func Wrapf(format string, err error) error { outerMsg := "" if err != nil { @@ -148,6 +150,9 @@ func Walk(err error, cb WalkFunc) { for _, err := range e.WrappedErrors() { Walk(err, cb) } + case interface{ Unwrap() error }: + cb(err) + Walk(e.Unwrap(), cb) default: cb(err) } @@ -167,3 +172,7 @@ func (w *wrappedError) Error() string { func (w *wrappedError) WrappedErrors() []error { return []error{w.Outer, w.Inner} } + +func (w *wrappedError) Unwrap() error { + return w.Inner +} diff --git a/vendor/github.com/hashicorp/go-immutable-radix/v2/.gitignore b/vendor/github.com/hashicorp/go-immutable-radix/v2/.gitignore deleted file mode 100644 index daf913b1b3..0000000000 --- a/vendor/github.com/hashicorp/go-immutable-radix/v2/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -*.test -*.prof diff --git a/vendor/github.com/hashicorp/go-immutable-radix/v2/CHANGELOG.md b/vendor/github.com/hashicorp/go-immutable-radix/v2/CHANGELOG.md deleted file mode 100644 index 556f1a67b1..0000000000 --- a/vendor/github.com/hashicorp/go-immutable-radix/v2/CHANGELOG.md +++ /dev/null @@ -1,27 +0,0 @@ -# UNRELEASED - -# 2.0.0 (December 15th, 2022) - -* Update API to use generics [[GH-43](https://github.com/hashicorp/go-immutable-radix/pull/43)) - -# 1.3.0 (September 17th, 2020) - -FEATURES - -* Add reverse tree traversal [[GH-30](https://github.com/hashicorp/go-immutable-radix/pull/30)] - -# 1.2.0 (March 18th, 2020) - -FEATURES - -* Adds a `Clone` method to `Txn` allowing transactions to be split either into two independently mutable trees. [[GH-26](https://github.com/hashicorp/go-immutable-radix/pull/26)] - -# 1.1.0 (May 22nd, 2019) - -FEATURES - -* Add `SeekLowerBound` to allow for range scans. [[GH-24](https://github.com/hashicorp/go-immutable-radix/pull/24)] - -# 1.0.0 (August 30th, 2018) - -* go mod adopted diff --git a/vendor/github.com/hashicorp/go-immutable-radix/v2/LICENSE b/vendor/github.com/hashicorp/go-immutable-radix/v2/LICENSE deleted file mode 100644 index f4f97ee585..0000000000 --- a/vendor/github.com/hashicorp/go-immutable-radix/v2/LICENSE +++ /dev/null @@ -1,365 +0,0 @@ -Copyright (c) 2015 HashiCorp, Inc. - -Mozilla Public License, version 2.0 - -1. Definitions - -1.1. "Contributor" - - means each individual or legal entity that creates, contributes to the - creation of, or owns Covered Software. - -1.2. "Contributor Version" - - means the combination of the Contributions of others (if any) used by a - Contributor and that particular Contributor's Contribution. - -1.3. "Contribution" - - means Covered Software of a particular Contributor. - -1.4. "Covered Software" - - means Source Code Form to which the initial Contributor has attached the - notice in Exhibit A, the Executable Form of such Source Code Form, and - Modifications of such Source Code Form, in each case including portions - thereof. - -1.5. "Incompatible With Secondary Licenses" - means - - a. that the initial Contributor has attached the notice described in - Exhibit B to the Covered Software; or - - b. that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the terms of - a Secondary License. - -1.6. "Executable Form" - - means any form of the work other than Source Code Form. - -1.7. "Larger Work" - - means a work that combines Covered Software with other material, in a - separate file or files, that is not Covered Software. - -1.8. "License" - - means this document. - -1.9. "Licensable" - - means having the right to grant, to the maximum extent possible, whether - at the time of the initial grant or subsequently, any and all of the - rights conveyed by this License. - -1.10. "Modifications" - - means any of the following: - - a. any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered Software; or - - b. any new file in Source Code Form that contains any Covered Software. - -1.11. "Patent Claims" of a Contributor - - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the License, - by the making, using, selling, offering for sale, having made, import, - or transfer of either its Contributions or its Contributor Version. - -1.12. "Secondary License" - - means either the GNU General Public License, Version 2.0, the GNU Lesser - General Public License, Version 2.1, the GNU Affero General Public - License, Version 3.0, or any later versions of those licenses. - -1.13. "Source Code Form" - - means the form of the work preferred for making modifications. - -1.14. "You" (or "Your") - - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that controls, is - controlled by, or is under common control with You. For purposes of this - definition, "control" means (a) the power, direct or indirect, to cause - the direction or management of such entity, whether by contract or - otherwise, or (b) ownership of more than fifty percent (50%) of the - outstanding shares or beneficial ownership of such entity. - - -2. License Grants and Conditions - -2.1. Grants - - Each Contributor hereby grants You a world-wide, royalty-free, - non-exclusive license: - - a. under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and - - b. under Patent Claims of such Contributor to make, use, sell, offer for - sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. - -2.2. Effective Date - - The licenses granted in Section 2.1 with respect to any Contribution - become effective for each Contribution on the date the Contributor first - distributes such Contribution. - -2.3. Limitations on Grant Scope - - The licenses granted in this Section 2 are the only rights granted under - this License. No additional rights or licenses will be implied from the - distribution or licensing of Covered Software under this License. - Notwithstanding Section 2.1(b) above, no patent license is granted by a - Contributor: - - a. for any code that a Contributor has removed from Covered Software; or - - b. for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - - c. under Patent Claims infringed by Covered Software in the absence of - its Contributions. - - This License does not grant any rights in the trademarks, service marks, - or logos of any Contributor (except as may be necessary to comply with - the notice requirements in Section 3.4). - -2.4. Subsequent Licenses - - No Contributor makes additional grants as a result of Your choice to - distribute the Covered Software under a subsequent version of this - License (see Section 10.2) or under the terms of a Secondary License (if - permitted under the terms of Section 3.3). - -2.5. Representation - - Each Contributor represents that the Contributor believes its - Contributions are its original creation(s) or it has sufficient rights to - grant the rights to its Contributions conveyed by this License. - -2.6. Fair Use - - This License is not intended to limit any rights You have under - applicable copyright doctrines of fair use, fair dealing, or other - equivalents. - -2.7. Conditions - - Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in - Section 2.1. - - -3. Responsibilities - -3.1. Distribution of Source Form - - All distribution of Covered Software in Source Code Form, including any - Modifications that You create or to which You contribute, must be under - the terms of this License. You must inform recipients that the Source - Code Form of the Covered Software is governed by the terms of this - License, and how they can obtain a copy of this License. You may not - attempt to alter or restrict the recipients' rights in the Source Code - Form. - -3.2. Distribution of Executable Form - - If You distribute Covered Software in Executable Form then: - - a. such Covered Software must also be made available in Source Code Form, - as described in Section 3.1, and You must inform recipients of the - Executable Form how they can obtain a copy of such Source Code Form by - reasonable means in a timely manner, at a charge no more than the cost - of distribution to the recipient; and - - b. You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter the - recipients' rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - - You may create and distribute a Larger Work under terms of Your choice, - provided that You also comply with the requirements of this License for - the Covered Software. If the Larger Work is a combination of Covered - Software with a work governed by one or more Secondary Licenses, and the - Covered Software is not Incompatible With Secondary Licenses, this - License permits You to additionally distribute such Covered Software - under the terms of such Secondary License(s), so that the recipient of - the Larger Work may, at their option, further distribute the Covered - Software under the terms of either this License or such Secondary - License(s). - -3.4. Notices - - You may not remove or alter the substance of any license notices - (including copyright notices, patent notices, disclaimers of warranty, or - limitations of liability) contained within the Source Code Form of the - Covered Software, except that You may alter any license notices to the - extent required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - - You may choose to offer, and to charge a fee for, warranty, support, - indemnity or liability obligations to one or more recipients of Covered - Software. However, You may do so only on Your own behalf, and not on - behalf of any Contributor. You must make it absolutely clear that any - such warranty, support, indemnity, or liability obligation is offered by - You alone, and You hereby agree to indemnify every Contributor for any - liability incurred by such Contributor as a result of warranty, support, - indemnity or liability terms You offer. You may include additional - disclaimers of warranty and limitations of liability specific to any - jurisdiction. - -4. Inability to Comply Due to Statute or Regulation - - If it is impossible for You to comply with any of the terms of this License - with respect to some or all of the Covered Software due to statute, - judicial order, or regulation then You must: (a) comply with the terms of - this License to the maximum extent possible; and (b) describe the - limitations and the code they affect. Such description must be placed in a - text file included with all distributions of the Covered Software under - this License. Except to the extent prohibited by statute or regulation, - such description must be sufficiently detailed for a recipient of ordinary - skill to be able to understand it. - -5. Termination - -5.1. The rights granted under this License will terminate automatically if You - fail to comply with any of its terms. However, if You become compliant, - then the rights granted under this License from a particular Contributor - are reinstated (a) provisionally, unless and until such Contributor - explicitly and finally terminates Your grants, and (b) on an ongoing - basis, if such Contributor fails to notify You of the non-compliance by - some reasonable means prior to 60 days after You have come back into - compliance. Moreover, Your grants from a particular Contributor are - reinstated on an ongoing basis if such Contributor notifies You of the - non-compliance by some reasonable means, this is the first time You have - received notice of non-compliance with this License from such - Contributor, and You become compliant prior to 30 days after Your receipt - of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent - infringement claim (excluding declaratory judgment actions, - counter-claims, and cross-claims) alleging that a Contributor Version - directly or indirectly infringes any patent, then the rights granted to - You by any and all Contributors for the Covered Software under Section - 2.1 of this License shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user - license agreements (excluding distributors and resellers) which have been - validly granted by You or Your distributors under this License prior to - termination shall survive termination. - -6. Disclaimer of Warranty - - Covered Software is provided under this License on an "as is" basis, - without warranty of any kind, either expressed, implied, or statutory, - including, without limitation, warranties that the Covered Software is free - of defects, merchantable, fit for a particular purpose or non-infringing. - The entire risk as to the quality and performance of the Covered Software - is with You. Should any Covered Software prove defective in any respect, - You (not any Contributor) assume the cost of any necessary servicing, - repair, or correction. This disclaimer of warranty constitutes an essential - part of this License. No use of any Covered Software is authorized under - this License except under this disclaimer. - -7. Limitation of Liability - - Under no circumstances and under no legal theory, whether tort (including - negligence), contract, or otherwise, shall any Contributor, or anyone who - distributes Covered Software as permitted above, be liable to You for any - direct, indirect, special, incidental, or consequential damages of any - character including, without limitation, damages for lost profits, loss of - goodwill, work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses, even if such party shall have been - informed of the possibility of such damages. This limitation of liability - shall not apply to liability for death or personal injury resulting from - such party's negligence to the extent applicable law prohibits such - limitation. Some jurisdictions do not allow the exclusion or limitation of - incidental or consequential damages, so this exclusion and limitation may - not apply to You. - -8. Litigation - - Any litigation relating to this License may be brought only in the courts - of a jurisdiction where the defendant maintains its principal place of - business and such litigation shall be governed by laws of that - jurisdiction, without reference to its conflict-of-law provisions. Nothing - in this Section shall prevent a party's ability to bring cross-claims or - counter-claims. - -9. Miscellaneous - - This License represents the complete agreement concerning the subject - matter hereof. If any provision of this License is held to be - unenforceable, such provision shall be reformed only to the extent - necessary to make it enforceable. Any law or regulation which provides that - the language of a contract shall be construed against the drafter shall not - be used to construe this License against a Contributor. - - -10. Versions of the License - -10.1. New Versions - - Mozilla Foundation is the license steward. Except as provided in Section - 10.3, no one other than the license steward has the right to modify or - publish new versions of this License. Each version will be given a - distinguishing version number. - -10.2. Effect of New Versions - - You may distribute the Covered Software under the terms of the version - of the License under which You originally received the Covered Software, - or under the terms of any subsequent version published by the license - steward. - -10.3. Modified Versions - - If you create software not governed by this License, and you want to - create a new license for such software, you may create and use a - modified version of this License if you rename the license and remove - any references to the name of the license steward (except to note that - such modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary - Licenses If You choose to distribute Source Code Form that is - Incompatible With Secondary Licenses under the terms of this version of - the License, the notice described in Exhibit B of this License must be - attached. - -Exhibit A - Source Code Form License Notice - - This Source Code Form is subject to the - terms of the Mozilla Public License, v. - 2.0. If a copy of the MPL was not - distributed with this file, You can - obtain one at - http://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular file, -then You may include the notice in a location (such as a LICENSE file in a -relevant directory) where a recipient would be likely to look for such a -notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - "Incompatible With Secondary Licenses" Notice - - This Source Code Form is "Incompatible - With Secondary Licenses", as defined by - the Mozilla Public License, v. 2.0. - diff --git a/vendor/github.com/hashicorp/go-immutable-radix/v2/README.md b/vendor/github.com/hashicorp/go-immutable-radix/v2/README.md deleted file mode 100644 index e17ccf4d11..0000000000 --- a/vendor/github.com/hashicorp/go-immutable-radix/v2/README.md +++ /dev/null @@ -1,73 +0,0 @@ -go-immutable-radix [![Run CI Tests](https://github.com/hashicorp/go-immutable-radix/actions/workflows/ci.yaml/badge.svg)](https://github.com/hashicorp/go-immutable-radix/actions/workflows/ci.yaml) -========= - -Provides the `iradix` package that implements an immutable [radix tree](http://en.wikipedia.org/wiki/Radix_tree). -The package only provides a single `Tree` implementation, optimized for sparse nodes. - -As a radix tree, it provides the following: - * O(k) operations. In many cases, this can be faster than a hash table since - the hash function is an O(k) operation, and hash tables have very poor cache locality. - * Minimum / Maximum value lookups - * Ordered iteration - -A tree supports using a transaction to batch multiple updates (insert, delete) -in a more efficient manner than performing each operation one at a time. - -For a mutable variant, see [go-radix](https://github.com/armon/go-radix). - -V2 -== - -The v2 of go-immutable-radix introduces generics to improve compile-time type -safety for users of the package. The module name for v2 is -`github.com/hashicorp/go-immutable-radix/v2`. - -Documentation -============= - -The full documentation is available on [Godoc](http://godoc.org/github.com/hashicorp/go-immutable-radix). - -Example -======= - -Below is a simple example of usage - -```go -// Create a tree -r := iradix.New[int]() -r, _, _ = r.Insert([]byte("foo"), 1) -r, _, _ = r.Insert([]byte("bar"), 2) -r, _, _ = r.Insert([]byte("foobar"), 2) - -// Find the longest prefix match -m, _, _ := r.Root().LongestPrefix([]byte("foozip")) -if string(m) != "foo" { - panic("should be foo") -} -``` - -Here is an example of performing a range scan of the keys. - -```go -// Create a tree -r := iradix.New[int]() -r, _, _ = r.Insert([]byte("001"), 1) -r, _, _ = r.Insert([]byte("002"), 2) -r, _, _ = r.Insert([]byte("005"), 5) -r, _, _ = r.Insert([]byte("010"), 10) -r, _, _ = r.Insert([]byte("100"), 10) - -// Range scan over the keys that sort lexicographically between [003, 050) -it := r.Root().Iterator() -it.SeekLowerBound([]byte("003")) -for key, _, ok := it.Next(); ok; key, _, ok = it.Next() { - if string(key) >= "050" { - break - } - fmt.Println(string(key)) -} -// Output: -// 005 -// 010 -``` - diff --git a/vendor/github.com/hashicorp/go-immutable-radix/v2/edges.go b/vendor/github.com/hashicorp/go-immutable-radix/v2/edges.go deleted file mode 100644 index 2e452f3e6f..0000000000 --- a/vendor/github.com/hashicorp/go-immutable-radix/v2/edges.go +++ /dev/null @@ -1,21 +0,0 @@ -package iradix - -import "sort" - -type edges[T any] []edge[T] - -func (e edges[T]) Len() int { - return len(e) -} - -func (e edges[T]) Less(i, j int) bool { - return e[i].label < e[j].label -} - -func (e edges[T]) Swap(i, j int) { - e[i], e[j] = e[j], e[i] -} - -func (e edges[T]) Sort() { - sort.Sort(e) -} diff --git a/vendor/github.com/hashicorp/go-immutable-radix/v2/iradix.go b/vendor/github.com/hashicorp/go-immutable-radix/v2/iradix.go deleted file mode 100644 index 8774020bcc..0000000000 --- a/vendor/github.com/hashicorp/go-immutable-radix/v2/iradix.go +++ /dev/null @@ -1,679 +0,0 @@ -package iradix - -import ( - "bytes" - "strings" - - "github.com/hashicorp/golang-lru/v2/simplelru" -) - -const ( - // defaultModifiedCache is the default size of the modified node - // cache used per transaction. This is used to cache the updates - // to the nodes near the root, while the leaves do not need to be - // cached. This is important for very large transactions to prevent - // the modified cache from growing to be enormous. This is also used - // to set the max size of the mutation notify maps since those should - // also be bounded in a similar way. - defaultModifiedCache = 8192 -) - -// Tree implements an immutable radix tree. This can be treated as a -// Dictionary abstract data type. The main advantage over a standard -// hash map is prefix-based lookups and ordered iteration. The immutability -// means that it is safe to concurrently read from a Tree without any -// coordination. -type Tree[T any] struct { - root *Node[T] - size int -} - -// New returns an empty Tree -func New[T any]() *Tree[T] { - t := &Tree[T]{ - root: &Node[T]{ - mutateCh: make(chan struct{}), - }, - } - return t -} - -// Len is used to return the number of elements in the tree -func (t *Tree[T]) Len() int { - return t.size -} - -// Txn is a transaction on the tree. This transaction is applied -// atomically and returns a new tree when committed. A transaction -// is not thread safe, and should only be used by a single goroutine. -type Txn[T any] struct { - // root is the modified root for the transaction. - root *Node[T] - - // snap is a snapshot of the root node for use if we have to run the - // slow notify algorithm. - snap *Node[T] - - // size tracks the size of the tree as it is modified during the - // transaction. - size int - - // writable is a cache of writable nodes that have been created during - // the course of the transaction. This allows us to re-use the same - // nodes for further writes and avoid unnecessary copies of nodes that - // have never been exposed outside the transaction. This will only hold - // up to defaultModifiedCache number of entries. - writable *simplelru.LRU[*Node[T], any] - - // trackChannels is used to hold channels that need to be notified to - // signal mutation of the tree. This will only hold up to - // defaultModifiedCache number of entries, after which we will set the - // trackOverflow flag, which will cause us to use a more expensive - // algorithm to perform the notifications. Mutation tracking is only - // performed if trackMutate is true. - trackChannels map[chan struct{}]struct{} - trackOverflow bool - trackMutate bool -} - -// Txn starts a new transaction that can be used to mutate the tree -func (t *Tree[T]) Txn() *Txn[T] { - txn := &Txn[T]{ - root: t.root, - snap: t.root, - size: t.size, - } - return txn -} - -// Clone makes an independent copy of the transaction. The new transaction -// does not track any nodes and has TrackMutate turned off. The cloned transaction will contain any uncommitted writes in the original transaction but further mutations to either will be independent and result in different radix trees on Commit. A cloned transaction may be passed to another goroutine and mutated there independently however each transaction may only be mutated in a single thread. -func (t *Txn[T]) Clone() *Txn[T] { - // reset the writable node cache to avoid leaking future writes into the clone - t.writable = nil - - txn := &Txn[T]{ - root: t.root, - snap: t.snap, - size: t.size, - } - return txn -} - -// TrackMutate can be used to toggle if mutations are tracked. If this is enabled -// then notifications will be issued for affected internal nodes and leaves when -// the transaction is committed. -func (t *Txn[T]) TrackMutate(track bool) { - t.trackMutate = track -} - -// trackChannel safely attempts to track the given mutation channel, setting the -// overflow flag if we can no longer track any more. This limits the amount of -// state that will accumulate during a transaction and we have a slower algorithm -// to switch to if we overflow. -func (t *Txn[T]) trackChannel(ch chan struct{}) { - // In overflow, make sure we don't store any more objects. - if t.trackOverflow { - return - } - - // If this would overflow the state we reject it and set the flag (since - // we aren't tracking everything that's required any longer). - if len(t.trackChannels) >= defaultModifiedCache { - // Mark that we are in the overflow state - t.trackOverflow = true - - // Clear the map so that the channels can be garbage collected. It is - // safe to do this since we have already overflowed and will be using - // the slow notify algorithm. - t.trackChannels = nil - return - } - - // Create the map on the fly when we need it. - if t.trackChannels == nil { - t.trackChannels = make(map[chan struct{}]struct{}) - } - - // Otherwise we are good to track it. - t.trackChannels[ch] = struct{}{} -} - -// writeNode returns a node to be modified, if the current node has already been -// modified during the course of the transaction, it is used in-place. Set -// forLeafUpdate to true if you are getting a write node to update the leaf, -// which will set leaf mutation tracking appropriately as well. -func (t *Txn[T]) writeNode(n *Node[T], forLeafUpdate bool) *Node[T] { - // Ensure the writable set exists. - if t.writable == nil { - lru, err := simplelru.NewLRU[*Node[T], any](defaultModifiedCache, nil) - if err != nil { - panic(err) - } - t.writable = lru - } - - // If this node has already been modified, we can continue to use it - // during this transaction. We know that we don't need to track it for - // a node update since the node is writable, but if this is for a leaf - // update we track it, in case the initial write to this node didn't - // update the leaf. - if _, ok := t.writable.Get(n); ok { - if t.trackMutate && forLeafUpdate && n.leaf != nil { - t.trackChannel(n.leaf.mutateCh) - } - return n - } - - // Mark this node as being mutated. - if t.trackMutate { - t.trackChannel(n.mutateCh) - } - - // Mark its leaf as being mutated, if appropriate. - if t.trackMutate && forLeafUpdate && n.leaf != nil { - t.trackChannel(n.leaf.mutateCh) - } - - // Copy the existing node. If you have set forLeafUpdate it will be - // safe to replace this leaf with another after you get your node for - // writing. You MUST replace it, because the channel associated with - // this leaf will be closed when this transaction is committed. - nc := &Node[T]{ - mutateCh: make(chan struct{}), - leaf: n.leaf, - } - if n.prefix != nil { - nc.prefix = make([]byte, len(n.prefix)) - copy(nc.prefix, n.prefix) - } - if len(n.edges) != 0 { - nc.edges = make([]edge[T], len(n.edges)) - copy(nc.edges, n.edges) - } - - // Mark this node as writable. - t.writable.Add(nc, nil) - return nc -} - -// Visit all the nodes in the tree under n, and add their mutateChannels to the transaction -// Returns the size of the subtree visited -func (t *Txn[T]) trackChannelsAndCount(n *Node[T]) int { - // Count only leaf nodes - leaves := 0 - if n.leaf != nil { - leaves = 1 - } - // Mark this node as being mutated. - if t.trackMutate { - t.trackChannel(n.mutateCh) - } - - // Mark its leaf as being mutated, if appropriate. - if t.trackMutate && n.leaf != nil { - t.trackChannel(n.leaf.mutateCh) - } - - // Recurse on the children - for _, e := range n.edges { - leaves += t.trackChannelsAndCount(e.node) - } - return leaves -} - -// mergeChild is called to collapse the given node with its child. This is only -// called when the given node is not a leaf and has a single edge. -func (t *Txn[T]) mergeChild(n *Node[T]) { - // Mark the child node as being mutated since we are about to abandon - // it. We don't need to mark the leaf since we are retaining it if it - // is there. - e := n.edges[0] - child := e.node - if t.trackMutate { - t.trackChannel(child.mutateCh) - } - - // Merge the nodes. - n.prefix = concat(n.prefix, child.prefix) - n.leaf = child.leaf - if len(child.edges) != 0 { - n.edges = make([]edge[T], len(child.edges)) - copy(n.edges, child.edges) - } else { - n.edges = nil - } -} - -// insert does a recursive insertion -func (t *Txn[T]) insert(n *Node[T], k, search []byte, v T) (*Node[T], T, bool) { - var zero T - - // Handle key exhaustion - if len(search) == 0 { - var oldVal T - didUpdate := false - if n.isLeaf() { - oldVal = n.leaf.val - didUpdate = true - } - - nc := t.writeNode(n, true) - nc.leaf = &leafNode[T]{ - mutateCh: make(chan struct{}), - key: k, - val: v, - } - return nc, oldVal, didUpdate - } - - // Look for the edge - idx, child := n.getEdge(search[0]) - - // No edge, create one - if child == nil { - e := edge[T]{ - label: search[0], - node: &Node[T]{ - mutateCh: make(chan struct{}), - leaf: &leafNode[T]{ - mutateCh: make(chan struct{}), - key: k, - val: v, - }, - prefix: search, - }, - } - nc := t.writeNode(n, false) - nc.addEdge(e) - return nc, zero, false - } - - // Determine longest prefix of the search key on match - commonPrefix := longestPrefix(search, child.prefix) - if commonPrefix == len(child.prefix) { - search = search[commonPrefix:] - newChild, oldVal, didUpdate := t.insert(child, k, search, v) - if newChild != nil { - nc := t.writeNode(n, false) - nc.edges[idx].node = newChild - return nc, oldVal, didUpdate - } - return nil, oldVal, didUpdate - } - - // Split the node - nc := t.writeNode(n, false) - splitNode := &Node[T]{ - mutateCh: make(chan struct{}), - prefix: search[:commonPrefix], - } - nc.replaceEdge(edge[T]{ - label: search[0], - node: splitNode, - }) - - // Restore the existing child node - modChild := t.writeNode(child, false) - splitNode.addEdge(edge[T]{ - label: modChild.prefix[commonPrefix], - node: modChild, - }) - modChild.prefix = modChild.prefix[commonPrefix:] - - // Create a new leaf node - leaf := &leafNode[T]{ - mutateCh: make(chan struct{}), - key: k, - val: v, - } - - // If the new key is a subset, add to to this node - search = search[commonPrefix:] - if len(search) == 0 { - splitNode.leaf = leaf - return nc, zero, false - } - - // Create a new edge for the node - splitNode.addEdge(edge[T]{ - label: search[0], - node: &Node[T]{ - mutateCh: make(chan struct{}), - leaf: leaf, - prefix: search, - }, - }) - return nc, zero, false -} - -// delete does a recursive deletion -func (t *Txn[T]) delete(n *Node[T], search []byte) (*Node[T], *leafNode[T]) { - // Check for key exhaustion - if len(search) == 0 { - if !n.isLeaf() { - return nil, nil - } - // Copy the pointer in case we are in a transaction that already - // modified this node since the node will be reused. Any changes - // made to the node will not affect returning the original leaf - // value. - oldLeaf := n.leaf - - // Remove the leaf node - nc := t.writeNode(n, true) - nc.leaf = nil - - // Check if this node should be merged - if n != t.root && len(nc.edges) == 1 { - t.mergeChild(nc) - } - return nc, oldLeaf - } - - // Look for an edge - label := search[0] - idx, child := n.getEdge(label) - if child == nil || !bytes.HasPrefix(search, child.prefix) { - return nil, nil - } - - // Consume the search prefix - search = search[len(child.prefix):] - newChild, leaf := t.delete(child, search) - if newChild == nil { - return nil, nil - } - - // Copy this node. WATCH OUT - it's safe to pass "false" here because we - // will only ADD a leaf via nc.mergeChild() if there isn't one due to - // the !nc.isLeaf() check in the logic just below. This is pretty subtle, - // so be careful if you change any of the logic here. - nc := t.writeNode(n, false) - - // Delete the edge if the node has no edges - if newChild.leaf == nil && len(newChild.edges) == 0 { - nc.delEdge(label) - if n != t.root && len(nc.edges) == 1 && !nc.isLeaf() { - t.mergeChild(nc) - } - } else { - nc.edges[idx].node = newChild - } - return nc, leaf -} - -// delete does a recursive deletion -func (t *Txn[T]) deletePrefix(n *Node[T], search []byte) (*Node[T], int) { - // Check for key exhaustion - if len(search) == 0 { - nc := t.writeNode(n, true) - if n.isLeaf() { - nc.leaf = nil - } - nc.edges = nil - return nc, t.trackChannelsAndCount(n) - } - - // Look for an edge - label := search[0] - idx, child := n.getEdge(label) - // We make sure that either the child node's prefix starts with the search term, or the search term starts with the child node's prefix - // Need to do both so that we can delete prefixes that don't correspond to any node in the tree - if child == nil || (!bytes.HasPrefix(child.prefix, search) && !bytes.HasPrefix(search, child.prefix)) { - return nil, 0 - } - - // Consume the search prefix - if len(child.prefix) > len(search) { - search = []byte("") - } else { - search = search[len(child.prefix):] - } - newChild, numDeletions := t.deletePrefix(child, search) - if newChild == nil { - return nil, 0 - } - // Copy this node. WATCH OUT - it's safe to pass "false" here because we - // will only ADD a leaf via nc.mergeChild() if there isn't one due to - // the !nc.isLeaf() check in the logic just below. This is pretty subtle, - // so be careful if you change any of the logic here. - - nc := t.writeNode(n, false) - - // Delete the edge if the node has no edges - if newChild.leaf == nil && len(newChild.edges) == 0 { - nc.delEdge(label) - if n != t.root && len(nc.edges) == 1 && !nc.isLeaf() { - t.mergeChild(nc) - } - } else { - nc.edges[idx].node = newChild - } - return nc, numDeletions -} - -// Insert is used to add or update a given key. The return provides -// the previous value and a bool indicating if any was set. -func (t *Txn[T]) Insert(k []byte, v T) (T, bool) { - newRoot, oldVal, didUpdate := t.insert(t.root, k, k, v) - if newRoot != nil { - t.root = newRoot - } - if !didUpdate { - t.size++ - } - return oldVal, didUpdate -} - -// Delete is used to delete a given key. Returns the old value if any, -// and a bool indicating if the key was set. -func (t *Txn[T]) Delete(k []byte) (T, bool) { - var zero T - newRoot, leaf := t.delete(t.root, k) - if newRoot != nil { - t.root = newRoot - } - if leaf != nil { - t.size-- - return leaf.val, true - } - return zero, false -} - -// DeletePrefix is used to delete an entire subtree that matches the prefix -// This will delete all nodes under that prefix -func (t *Txn[T]) DeletePrefix(prefix []byte) bool { - newRoot, numDeletions := t.deletePrefix(t.root, prefix) - if newRoot != nil { - t.root = newRoot - t.size = t.size - numDeletions - return true - } - return false - -} - -// Root returns the current root of the radix tree within this -// transaction. The root is not safe across insert and delete operations, -// but can be used to read the current state during a transaction. -func (t *Txn[T]) Root() *Node[T] { - return t.root -} - -// Get is used to lookup a specific key, returning -// the value and if it was found -func (t *Txn[T]) Get(k []byte) (T, bool) { - return t.root.Get(k) -} - -// GetWatch is used to lookup a specific key, returning -// the watch channel, value and if it was found -func (t *Txn[T]) GetWatch(k []byte) (<-chan struct{}, T, bool) { - return t.root.GetWatch(k) -} - -// Commit is used to finalize the transaction and return a new tree. If mutation -// tracking is turned on then notifications will also be issued. -func (t *Txn[T]) Commit() *Tree[T] { - nt := t.CommitOnly() - if t.trackMutate { - t.Notify() - } - return nt -} - -// CommitOnly is used to finalize the transaction and return a new tree, but -// does not issue any notifications until Notify is called. -func (t *Txn[T]) CommitOnly() *Tree[T] { - nt := &Tree[T]{t.root, t.size} - t.writable = nil - return nt -} - -// slowNotify does a complete comparison of the before and after trees in order -// to trigger notifications. This doesn't require any additional state but it -// is very expensive to compute. -func (t *Txn[T]) slowNotify() { - snapIter := t.snap.rawIterator() - rootIter := t.root.rawIterator() - for snapIter.Front() != nil || rootIter.Front() != nil { - // If we've exhausted the nodes in the old snapshot, we know - // there's nothing remaining to notify. - if snapIter.Front() == nil { - return - } - snapElem := snapIter.Front() - - // If we've exhausted the nodes in the new root, we know we need - // to invalidate everything that remains in the old snapshot. We - // know from the loop condition there's something in the old - // snapshot. - if rootIter.Front() == nil { - close(snapElem.mutateCh) - if snapElem.isLeaf() { - close(snapElem.leaf.mutateCh) - } - snapIter.Next() - continue - } - - // Do one string compare so we can check the various conditions - // below without repeating the compare. - cmp := strings.Compare(snapIter.Path(), rootIter.Path()) - - // If the snapshot is behind the root, then we must have deleted - // this node during the transaction. - if cmp < 0 { - close(snapElem.mutateCh) - if snapElem.isLeaf() { - close(snapElem.leaf.mutateCh) - } - snapIter.Next() - continue - } - - // If the snapshot is ahead of the root, then we must have added - // this node during the transaction. - if cmp > 0 { - rootIter.Next() - continue - } - - // If we have the same path, then we need to see if we mutated a - // node and possibly the leaf. - rootElem := rootIter.Front() - if snapElem != rootElem { - close(snapElem.mutateCh) - if snapElem.leaf != nil && (snapElem.leaf != rootElem.leaf) { - close(snapElem.leaf.mutateCh) - } - } - snapIter.Next() - rootIter.Next() - } -} - -// Notify is used along with TrackMutate to trigger notifications. This must -// only be done once a transaction is committed via CommitOnly, and it is called -// automatically by Commit. -func (t *Txn[T]) Notify() { - if !t.trackMutate { - return - } - - // If we've overflowed the tracking state we can't use it in any way and - // need to do a full tree compare. - if t.trackOverflow { - t.slowNotify() - } else { - for ch := range t.trackChannels { - close(ch) - } - } - - // Clean up the tracking state so that a re-notify is safe (will trigger - // the else clause above which will be a no-op). - t.trackChannels = nil - t.trackOverflow = false -} - -// Insert is used to add or update a given key. The return provides -// the new tree, previous value and a bool indicating if any was set. -func (t *Tree[T]) Insert(k []byte, v T) (*Tree[T], T, bool) { - txn := t.Txn() - old, ok := txn.Insert(k, v) - return txn.Commit(), old, ok -} - -// Delete is used to delete a given key. Returns the new tree, -// old value if any, and a bool indicating if the key was set. -func (t *Tree[T]) Delete(k []byte) (*Tree[T], T, bool) { - txn := t.Txn() - old, ok := txn.Delete(k) - return txn.Commit(), old, ok -} - -// DeletePrefix is used to delete all nodes starting with a given prefix. Returns the new tree, -// and a bool indicating if the prefix matched any nodes -func (t *Tree[T]) DeletePrefix(k []byte) (*Tree[T], bool) { - txn := t.Txn() - ok := txn.DeletePrefix(k) - return txn.Commit(), ok -} - -// Root returns the root node of the tree which can be used for richer -// query operations. -func (t *Tree[T]) Root() *Node[T] { - return t.root -} - -// Get is used to lookup a specific key, returning -// the value and if it was found -func (t *Tree[T]) Get(k []byte) (T, bool) { - return t.root.Get(k) -} - -// longestPrefix finds the length of the shared prefix -// of two strings -func longestPrefix(k1, k2 []byte) int { - max := len(k1) - if l := len(k2); l < max { - max = l - } - var i int - for i = 0; i < max; i++ { - if k1[i] != k2[i] { - break - } - } - return i -} - -// concat two byte slices, returning a third new copy -func concat(a, b []byte) []byte { - c := make([]byte, len(a)+len(b)) - copy(c, a) - copy(c[len(a):], b) - return c -} diff --git a/vendor/github.com/hashicorp/go-immutable-radix/v2/iter.go b/vendor/github.com/hashicorp/go-immutable-radix/v2/iter.go deleted file mode 100644 index ffd2721c1a..0000000000 --- a/vendor/github.com/hashicorp/go-immutable-radix/v2/iter.go +++ /dev/null @@ -1,205 +0,0 @@ -package iradix - -import ( - "bytes" -) - -// Iterator is used to iterate over a set of nodes -// in pre-order -type Iterator[T any] struct { - node *Node[T] - stack []edges[T] -} - -// SeekPrefixWatch is used to seek the iterator to a given prefix -// and returns the watch channel of the finest granularity -func (i *Iterator[T]) SeekPrefixWatch(prefix []byte) (watch <-chan struct{}) { - // Wipe the stack - i.stack = nil - n := i.node - watch = n.mutateCh - search := prefix - for { - // Check for key exhaustion - if len(search) == 0 { - i.node = n - return - } - - // Look for an edge - _, n = n.getEdge(search[0]) - if n == nil { - i.node = nil - return - } - - // Update to the finest granularity as the search makes progress - watch = n.mutateCh - - // Consume the search prefix - if bytes.HasPrefix(search, n.prefix) { - search = search[len(n.prefix):] - - } else if bytes.HasPrefix(n.prefix, search) { - i.node = n - return - } else { - i.node = nil - return - } - } -} - -// SeekPrefix is used to seek the iterator to a given prefix -func (i *Iterator[T]) SeekPrefix(prefix []byte) { - i.SeekPrefixWatch(prefix) -} - -func (i *Iterator[T]) recurseMin(n *Node[T]) *Node[T] { - // Traverse to the minimum child - if n.leaf != nil { - return n - } - nEdges := len(n.edges) - if nEdges > 1 { - // Add all the other edges to the stack (the min node will be added as - // we recurse) - i.stack = append(i.stack, n.edges[1:]) - } - if nEdges > 0 { - return i.recurseMin(n.edges[0].node) - } - // Shouldn't be possible - return nil -} - -// SeekLowerBound is used to seek the iterator to the smallest key that is -// greater or equal to the given key. There is no watch variant as it's hard to -// predict based on the radix structure which node(s) changes might affect the -// result. -func (i *Iterator[T]) SeekLowerBound(key []byte) { - // Wipe the stack. Unlike Prefix iteration, we need to build the stack as we - // go because we need only a subset of edges of many nodes in the path to the - // leaf with the lower bound. Note that the iterator will still recurse into - // children that we don't traverse on the way to the reverse lower bound as it - // walks the stack. - i.stack = []edges[T]{} - // i.node starts off in the common case as pointing to the root node of the - // tree. By the time we return we have either found a lower bound and setup - // the stack to traverse all larger keys, or we have not and the stack and - // node should both be nil to prevent the iterator from assuming it is just - // iterating the whole tree from the root node. Either way this needs to end - // up as nil so just set it here. - n := i.node - i.node = nil - search := key - - found := func(n *Node[T]) { - i.stack = append( - i.stack, - edges[T]{edge[T]{node: n}}, - ) - } - - findMin := func(n *Node[T]) { - n = i.recurseMin(n) - if n != nil { - found(n) - return - } - } - - for { - // Compare current prefix with the search key's same-length prefix. - var prefixCmp int - if len(n.prefix) < len(search) { - prefixCmp = bytes.Compare(n.prefix, search[0:len(n.prefix)]) - } else { - prefixCmp = bytes.Compare(n.prefix, search) - } - - if prefixCmp > 0 { - // Prefix is larger, that means the lower bound is greater than the search - // and from now on we need to follow the minimum path to the smallest - // leaf under this subtree. - findMin(n) - return - } - - if prefixCmp < 0 { - // Prefix is smaller than search prefix, that means there is no lower - // bound - i.node = nil - return - } - - // Prefix is equal, we are still heading for an exact match. If this is a - // leaf and an exact match we're done. - if n.leaf != nil && bytes.Equal(n.leaf.key, key) { - found(n) - return - } - - // Consume the search prefix if the current node has one. Note that this is - // safe because if n.prefix is longer than the search slice prefixCmp would - // have been > 0 above and the method would have already returned. - search = search[len(n.prefix):] - - if len(search) == 0 { - // We've exhausted the search key, but the current node is not an exact - // match or not a leaf. That means that the leaf value if it exists, and - // all child nodes must be strictly greater, the smallest key in this - // subtree must be the lower bound. - findMin(n) - return - } - - // Otherwise, take the lower bound next edge. - idx, lbNode := n.getLowerBoundEdge(search[0]) - if lbNode == nil { - return - } - - // Create stack edges for the all strictly higher edges in this node. - if idx+1 < len(n.edges) { - i.stack = append(i.stack, n.edges[idx+1:]) - } - - // Recurse - n = lbNode - } -} - -// Next returns the next node in order -func (i *Iterator[T]) Next() ([]byte, T, bool) { - var zero T - // Initialize our stack if needed - if i.stack == nil && i.node != nil { - i.stack = []edges[T]{{edge[T]{node: i.node}}} - } - - for len(i.stack) > 0 { - // Inspect the last element of the stack - n := len(i.stack) - last := i.stack[n-1] - elem := last[0].node - - // Update the stack - if len(last) > 1 { - i.stack[n-1] = last[1:] - } else { - i.stack = i.stack[:n-1] - } - - // Push the edges onto the frontier - if len(elem.edges) > 0 { - i.stack = append(i.stack, elem.edges) - } - - // Return the leaf values if any - if elem.leaf != nil { - return elem.leaf.key, elem.leaf.val, true - } - } - return nil, zero, false -} diff --git a/vendor/github.com/hashicorp/go-immutable-radix/v2/node.go b/vendor/github.com/hashicorp/go-immutable-radix/v2/node.go deleted file mode 100644 index 1be963922f..0000000000 --- a/vendor/github.com/hashicorp/go-immutable-radix/v2/node.go +++ /dev/null @@ -1,326 +0,0 @@ -package iradix - -import ( - "bytes" - "sort" -) - -// WalkFn is used when walking the tree. Takes a -// key and value, returning if iteration should -// be terminated. -type WalkFn[T any] func(k []byte, v T) bool - -// leafNode is used to represent a value -type leafNode[T any] struct { - mutateCh chan struct{} - key []byte - val T -} - -// edge is used to represent an edge node -type edge[T any] struct { - label byte - node *Node[T] -} - -// Node is an immutable node in the radix tree -type Node[T any] struct { - // mutateCh is closed if this node is modified - mutateCh chan struct{} - - // leaf is used to store possible leaf - leaf *leafNode[T] - - // prefix is the common prefix we ignore - prefix []byte - - // Edges should be stored in-order for iteration. - // We avoid a fully materialized slice to save memory, - // since in most cases we expect to be sparse - edges edges[T] -} - -func (n *Node[T]) isLeaf() bool { - return n.leaf != nil -} - -func (n *Node[T]) addEdge(e edge[T]) { - num := len(n.edges) - idx := sort.Search(num, func(i int) bool { - return n.edges[i].label >= e.label - }) - n.edges = append(n.edges, e) - if idx != num { - copy(n.edges[idx+1:], n.edges[idx:num]) - n.edges[idx] = e - } -} - -func (n *Node[T]) replaceEdge(e edge[T]) { - num := len(n.edges) - idx := sort.Search(num, func(i int) bool { - return n.edges[i].label >= e.label - }) - if idx < num && n.edges[idx].label == e.label { - n.edges[idx].node = e.node - return - } - panic("replacing missing edge") -} - -func (n *Node[T]) getEdge(label byte) (int, *Node[T]) { - num := len(n.edges) - idx := sort.Search(num, func(i int) bool { - return n.edges[i].label >= label - }) - if idx < num && n.edges[idx].label == label { - return idx, n.edges[idx].node - } - return -1, nil -} - -func (n *Node[T]) getLowerBoundEdge(label byte) (int, *Node[T]) { - num := len(n.edges) - idx := sort.Search(num, func(i int) bool { - return n.edges[i].label >= label - }) - // we want lower bound behavior so return even if it's not an exact match - if idx < num { - return idx, n.edges[idx].node - } - return -1, nil -} - -func (n *Node[T]) delEdge(label byte) { - num := len(n.edges) - idx := sort.Search(num, func(i int) bool { - return n.edges[i].label >= label - }) - if idx < num && n.edges[idx].label == label { - copy(n.edges[idx:], n.edges[idx+1:]) - n.edges[len(n.edges)-1] = edge[T]{} - n.edges = n.edges[:len(n.edges)-1] - } -} - -func (n *Node[T]) GetWatch(k []byte) (<-chan struct{}, T, bool) { - search := k - watch := n.mutateCh - for { - // Check for key exhaustion - if len(search) == 0 { - if n.isLeaf() { - return n.leaf.mutateCh, n.leaf.val, true - } - break - } - - // Look for an edge - _, n = n.getEdge(search[0]) - if n == nil { - break - } - - // Update to the finest granularity as the search makes progress - watch = n.mutateCh - - // Consume the search prefix - if bytes.HasPrefix(search, n.prefix) { - search = search[len(n.prefix):] - } else { - break - } - } - var zero T - return watch, zero, false -} - -func (n *Node[T]) Get(k []byte) (T, bool) { - _, val, ok := n.GetWatch(k) - return val, ok -} - -// LongestPrefix is like Get, but instead of an -// exact match, it will return the longest prefix match. -func (n *Node[T]) LongestPrefix(k []byte) ([]byte, T, bool) { - var last *leafNode[T] - search := k - for { - // Look for a leaf node - if n.isLeaf() { - last = n.leaf - } - - // Check for key exhaustion - if len(search) == 0 { - break - } - - // Look for an edge - _, n = n.getEdge(search[0]) - if n == nil { - break - } - - // Consume the search prefix - if bytes.HasPrefix(search, n.prefix) { - search = search[len(n.prefix):] - } else { - break - } - } - if last != nil { - return last.key, last.val, true - } - var zero T - return nil, zero, false -} - -// Minimum is used to return the minimum value in the tree -func (n *Node[T]) Minimum() ([]byte, T, bool) { - for { - if n.isLeaf() { - return n.leaf.key, n.leaf.val, true - } - if len(n.edges) > 0 { - n = n.edges[0].node - } else { - break - } - } - var zero T - return nil, zero, false -} - -// Maximum is used to return the maximum value in the tree -func (n *Node[T]) Maximum() ([]byte, T, bool) { - for { - if num := len(n.edges); num > 0 { - n = n.edges[num-1].node // bug? - continue - } - if n.isLeaf() { - return n.leaf.key, n.leaf.val, true - } else { - break - } - } - var zero T - return nil, zero, false -} - -// Iterator is used to return an iterator at -// the given node to walk the tree -func (n *Node[T]) Iterator() *Iterator[T] { - return &Iterator[T]{node: n} -} - -// ReverseIterator is used to return an iterator at -// the given node to walk the tree backwards -func (n *Node[T]) ReverseIterator() *ReverseIterator[T] { - return NewReverseIterator(n) -} - -// Iterator is used to return an iterator at -// the given node to walk the tree -func (n *Node[T]) PathIterator(path []byte) *PathIterator[T] { - return &PathIterator[T]{node: n, path: path} -} - -// rawIterator is used to return a raw iterator at the given node to walk the -// tree. -func (n *Node[T]) rawIterator() *rawIterator[T] { - iter := &rawIterator[T]{node: n} - iter.Next() - return iter -} - -// Walk is used to walk the tree -func (n *Node[T]) Walk(fn WalkFn[T]) { - recursiveWalk(n, fn) -} - -// WalkBackwards is used to walk the tree in reverse order -func (n *Node[T]) WalkBackwards(fn WalkFn[T]) { - reverseRecursiveWalk(n, fn) -} - -// WalkPrefix is used to walk the tree under a prefix -func (n *Node[T]) WalkPrefix(prefix []byte, fn WalkFn[T]) { - search := prefix - for { - // Check for key exhaustion - if len(search) == 0 { - recursiveWalk(n, fn) - return - } - - // Look for an edge - _, n = n.getEdge(search[0]) - if n == nil { - break - } - - // Consume the search prefix - if bytes.HasPrefix(search, n.prefix) { - search = search[len(n.prefix):] - - } else if bytes.HasPrefix(n.prefix, search) { - // Child may be under our search prefix - recursiveWalk(n, fn) - return - } else { - break - } - } -} - -// WalkPath is used to walk the tree, but only visiting nodes -// from the root down to a given leaf. Where WalkPrefix walks -// all the entries *under* the given prefix, this walks the -// entries *above* the given prefix. -func (n *Node[T]) WalkPath(path []byte, fn WalkFn[T]) { - i := n.PathIterator(path) - - for path, val, ok := i.Next(); ok; path, val, ok = i.Next() { - if fn(path, val) { - return - } - } -} - -// recursiveWalk is used to do a pre-order walk of a node -// recursively. Returns true if the walk should be aborted -func recursiveWalk[T any](n *Node[T], fn WalkFn[T]) bool { - // Visit the leaf values if any - if n.leaf != nil && fn(n.leaf.key, n.leaf.val) { - return true - } - - // Recurse on the children - for _, e := range n.edges { - if recursiveWalk(e.node, fn) { - return true - } - } - return false -} - -// reverseRecursiveWalk is used to do a reverse pre-order -// walk of a node recursively. Returns true if the walk -// should be aborted -func reverseRecursiveWalk[T any](n *Node[T], fn WalkFn[T]) bool { - // Visit the leaf values if any - if n.leaf != nil && fn(n.leaf.key, n.leaf.val) { - return true - } - - // Recurse on the children in reverse order - for i := len(n.edges) - 1; i >= 0; i-- { - e := n.edges[i] - if reverseRecursiveWalk(e.node, fn) { - return true - } - } - return false -} diff --git a/vendor/github.com/hashicorp/go-immutable-radix/v2/path_iter.go b/vendor/github.com/hashicorp/go-immutable-radix/v2/path_iter.go deleted file mode 100644 index 21942afc8a..0000000000 --- a/vendor/github.com/hashicorp/go-immutable-radix/v2/path_iter.go +++ /dev/null @@ -1,59 +0,0 @@ -package iradix - -import "bytes" - -// PathIterator is used to iterate over a set of nodes from the root -// down to a specified path. This will iterate over the same values that -// the Node.WalkPath method will. -type PathIterator[T any] struct { - node *Node[T] - path []byte - done bool -} - -// Next returns the next node in order -func (i *PathIterator[T]) Next() ([]byte, T, bool) { - // This is mostly just an asynchronous implementation of the WalkPath - // method on the node. - var zero T - var leaf *leafNode[T] - - for leaf == nil && i.node != nil { - // visit the leaf values if any - if i.node.leaf != nil { - leaf = i.node.leaf - } - - i.iterate() - } - - if leaf != nil { - return leaf.key, leaf.val, true - } - - return nil, zero, false -} - -func (i *PathIterator[T]) iterate() { - // Check for key exhaustion - if len(i.path) == 0 { - i.node = nil - return - } - - // Look for an edge - _, i.node = i.node.getEdge(i.path[0]) - if i.node == nil { - return - } - - // Consume the search prefix - if bytes.HasPrefix(i.path, i.node.prefix) { - i.path = i.path[len(i.node.prefix):] - } else { - // there are no more nodes to iterate through so - // nil out the node to prevent returning results - // for subsequent calls to Next() - i.node = nil - } -} diff --git a/vendor/github.com/hashicorp/go-immutable-radix/v2/raw_iter.go b/vendor/github.com/hashicorp/go-immutable-radix/v2/raw_iter.go deleted file mode 100644 index dd84f089d7..0000000000 --- a/vendor/github.com/hashicorp/go-immutable-radix/v2/raw_iter.go +++ /dev/null @@ -1,78 +0,0 @@ -package iradix - -// rawIterator visits each of the nodes in the tree, even the ones that are not -// leaves. It keeps track of the effective path (what a leaf at a given node -// would be called), which is useful for comparing trees. -type rawIterator[T any] struct { - // node is the starting node in the tree for the iterator. - node *Node[T] - - // stack keeps track of edges in the frontier. - stack []rawStackEntry[T] - - // pos is the current position of the iterator. - pos *Node[T] - - // path is the effective path of the current iterator position, - // regardless of whether the current node is a leaf. - path string -} - -// rawStackEntry is used to keep track of the cumulative common path as well as -// its associated edges in the frontier. -type rawStackEntry[T any] struct { - path string - edges edges[T] -} - -// Front returns the current node that has been iterated to. -func (i *rawIterator[T]) Front() *Node[T] { - return i.pos -} - -// Path returns the effective path of the current node, even if it's not actually -// a leaf. -func (i *rawIterator[T]) Path() string { - return i.path -} - -// Next advances the iterator to the next node. -func (i *rawIterator[T]) Next() { - // Initialize our stack if needed. - if i.stack == nil && i.node != nil { - i.stack = []rawStackEntry[T]{ - { - edges: edges[T]{ - edge[T]{node: i.node}, - }, - }, - } - } - - for len(i.stack) > 0 { - // Inspect the last element of the stack. - n := len(i.stack) - last := i.stack[n-1] - elem := last.edges[0].node - - // Update the stack. - if len(last.edges) > 1 { - i.stack[n-1].edges = last.edges[1:] - } else { - i.stack = i.stack[:n-1] - } - - // Push the edges onto the frontier. - if len(elem.edges) > 0 { - path := last.path + string(elem.prefix) - i.stack = append(i.stack, rawStackEntry[T]{path, elem.edges}) - } - - i.pos = elem - i.path = last.path + string(elem.prefix) - return - } - - i.pos = nil - i.path = "" -} diff --git a/vendor/github.com/hashicorp/go-immutable-radix/v2/reverse_iter.go b/vendor/github.com/hashicorp/go-immutable-radix/v2/reverse_iter.go deleted file mode 100644 index 2a06cde7cb..0000000000 --- a/vendor/github.com/hashicorp/go-immutable-radix/v2/reverse_iter.go +++ /dev/null @@ -1,240 +0,0 @@ -package iradix - -import ( - "bytes" -) - -// ReverseIterator is used to iterate over a set of nodes -// in reverse in-order -type ReverseIterator[T any] struct { - i *Iterator[T] - - // expandedParents stores the set of parent nodes whose relevant children have - // already been pushed into the stack. This can happen during seek or during - // iteration. - // - // Unlike forward iteration we need to recurse into children before we can - // output the value stored in an internal leaf since all children are greater. - // We use this to track whether we have already ensured all the children are - // in the stack. - expandedParents map[*Node[T]]struct{} -} - -// NewReverseIterator returns a new ReverseIterator at a node -func NewReverseIterator[T any](n *Node[T]) *ReverseIterator[T] { - return &ReverseIterator[T]{ - i: &Iterator[T]{node: n}, - } -} - -// SeekPrefixWatch is used to seek the iterator to a given prefix -// and returns the watch channel of the finest granularity -func (ri *ReverseIterator[T]) SeekPrefixWatch(prefix []byte) (watch <-chan struct{}) { - return ri.i.SeekPrefixWatch(prefix) -} - -// SeekPrefix is used to seek the iterator to a given prefix -func (ri *ReverseIterator[T]) SeekPrefix(prefix []byte) { - ri.i.SeekPrefixWatch(prefix) -} - -// SeekReverseLowerBound is used to seek the iterator to the largest key that is -// lower or equal to the given key. There is no watch variant as it's hard to -// predict based on the radix structure which node(s) changes might affect the -// result. -func (ri *ReverseIterator[T]) SeekReverseLowerBound(key []byte) { - // Wipe the stack. Unlike Prefix iteration, we need to build the stack as we - // go because we need only a subset of edges of many nodes in the path to the - // leaf with the lower bound. Note that the iterator will still recurse into - // children that we don't traverse on the way to the reverse lower bound as it - // walks the stack. - ri.i.stack = []edges[T]{} - // ri.i.node starts off in the common case as pointing to the root node of the - // tree. By the time we return we have either found a lower bound and setup - // the stack to traverse all larger keys, or we have not and the stack and - // node should both be nil to prevent the iterator from assuming it is just - // iterating the whole tree from the root node. Either way this needs to end - // up as nil so just set it here. - n := ri.i.node - ri.i.node = nil - search := key - - if ri.expandedParents == nil { - ri.expandedParents = make(map[*Node[T]]struct{}) - } - - found := func(n *Node[T]) { - ri.i.stack = append(ri.i.stack, edges[T]{edge[T]{node: n}}) - // We need to mark this node as expanded in advance too otherwise the - // iterator will attempt to walk all of its children even though they are - // greater than the lower bound we have found. We've expanded it in the - // sense that all of its children that we want to walk are already in the - // stack (i.e. none of them). - ri.expandedParents[n] = struct{}{} - } - - for { - // Compare current prefix with the search key's same-length prefix. - var prefixCmp int - if len(n.prefix) < len(search) { - prefixCmp = bytes.Compare(n.prefix, search[0:len(n.prefix)]) - } else { - prefixCmp = bytes.Compare(n.prefix, search) - } - - if prefixCmp < 0 { - // Prefix is smaller than search prefix, that means there is no exact - // match for the search key. But we are looking in reverse, so the reverse - // lower bound will be the largest leaf under this subtree, since it is - // the value that would come right before the current search key if it - // were in the tree. So we need to follow the maximum path in this subtree - // to find it. Note that this is exactly what the iterator will already do - // if it finds a node in the stack that has _not_ been marked as expanded - // so in this one case we don't call `found` and instead let the iterator - // do the expansion and recursion through all the children. - ri.i.stack = append(ri.i.stack, edges[T]{edge[T]{node: n}}) - return - } - - if prefixCmp > 0 { - // Prefix is larger than search prefix, or there is no prefix but we've - // also exhausted the search key. Either way, that means there is no - // reverse lower bound since nothing comes before our current search - // prefix. - return - } - - // If this is a leaf, something needs to happen! Note that if it's a leaf - // and prefixCmp was zero (which it must be to get here) then the leaf value - // is either an exact match for the search, or it's lower. It can't be - // greater. - if n.isLeaf() { - - // Firstly, if it's an exact match, we're done! - if bytes.Equal(n.leaf.key, key) { - found(n) - return - } - - // It's not so this node's leaf value must be lower and could still be a - // valid contender for reverse lower bound. - - // If it has no children then we are also done. - if len(n.edges) == 0 { - // This leaf is the lower bound. - found(n) - return - } - - // Finally, this leaf is internal (has children) so we'll keep searching, - // but we need to add it to the iterator's stack since it has a leaf value - // that needs to be iterated over. It needs to be added to the stack - // before its children below as it comes first. - ri.i.stack = append(ri.i.stack, edges[T]{edge[T]{node: n}}) - // We also need to mark it as expanded since we'll be adding any of its - // relevant children below and so don't want the iterator to re-add them - // on its way back up the stack. - ri.expandedParents[n] = struct{}{} - } - - // Consume the search prefix. Note that this is safe because if n.prefix is - // longer than the search slice prefixCmp would have been > 0 above and the - // method would have already returned. - search = search[len(n.prefix):] - - if len(search) == 0 { - // We've exhausted the search key but we are not at a leaf. That means all - // children are greater than the search key so a reverse lower bound - // doesn't exist in this subtree. Note that there might still be one in - // the whole radix tree by following a different path somewhere further - // up. If that's the case then the iterator's stack will contain all the - // smaller nodes already and Previous will walk through them correctly. - return - } - - // Otherwise, take the lower bound next edge. - idx, lbNode := n.getLowerBoundEdge(search[0]) - - // From here, we need to update the stack with all values lower than - // the lower bound edge. Since getLowerBoundEdge() returns -1 when the - // search prefix is larger than all edges, we need to place idx at the - // last edge index so they can all be place in the stack, since they - // come before our search prefix. - if idx == -1 { - idx = len(n.edges) - } - - // Create stack edges for the all strictly lower edges in this node. - if len(n.edges[:idx]) > 0 { - ri.i.stack = append(ri.i.stack, n.edges[:idx]) - } - - // Exit if there's no lower bound edge. The stack will have the previous - // nodes already. - if lbNode == nil { - return - } - - // Recurse - n = lbNode - } -} - -// Previous returns the previous node in reverse order -func (ri *ReverseIterator[T]) Previous() ([]byte, T, bool) { - // Initialize our stack if needed - if ri.i.stack == nil && ri.i.node != nil { - ri.i.stack = []edges[T]{ - { - edge[T]{node: ri.i.node}, - }, - } - } - - if ri.expandedParents == nil { - ri.expandedParents = make(map[*Node[T]]struct{}) - } - - for len(ri.i.stack) > 0 { - // Inspect the last element of the stack - n := len(ri.i.stack) - last := ri.i.stack[n-1] - m := len(last) - elem := last[m-1].node - - _, alreadyExpanded := ri.expandedParents[elem] - - // If this is an internal node and we've not seen it already, we need to - // leave it in the stack so we can return its possible leaf value _after_ - // we've recursed through all its children. - if len(elem.edges) > 0 && !alreadyExpanded { - // record that we've seen this node! - ri.expandedParents[elem] = struct{}{} - // push child edges onto stack and skip the rest of the loop to recurse - // into the largest one. - ri.i.stack = append(ri.i.stack, elem.edges) - continue - } - - // Remove the node from the stack - if m > 1 { - ri.i.stack[n-1] = last[:m-1] - } else { - ri.i.stack = ri.i.stack[:n-1] - } - // We don't need this state any more as it's no longer in the stack so we - // won't visit it again - if alreadyExpanded { - delete(ri.expandedParents, elem) - } - - // If this is a leaf, return it - if elem.leaf != nil { - return elem.leaf.key, elem.leaf.val, true - } - - // it's not a leaf so keep walking the stack to find the previous leaf - } - var zero T - return nil, zero, false -} diff --git a/vendor/github.com/hashicorp/golang-lru/v2/LICENSE b/vendor/github.com/hashicorp/golang-lru/v2/LICENSE deleted file mode 100644 index 0e5d580e0e..0000000000 --- a/vendor/github.com/hashicorp/golang-lru/v2/LICENSE +++ /dev/null @@ -1,364 +0,0 @@ -Copyright (c) 2014 HashiCorp, Inc. - -Mozilla Public License, version 2.0 - -1. Definitions - -1.1. "Contributor" - - means each individual or legal entity that creates, contributes to the - creation of, or owns Covered Software. - -1.2. "Contributor Version" - - means the combination of the Contributions of others (if any) used by a - Contributor and that particular Contributor's Contribution. - -1.3. "Contribution" - - means Covered Software of a particular Contributor. - -1.4. "Covered Software" - - means Source Code Form to which the initial Contributor has attached the - notice in Exhibit A, the Executable Form of such Source Code Form, and - Modifications of such Source Code Form, in each case including portions - thereof. - -1.5. "Incompatible With Secondary Licenses" - means - - a. that the initial Contributor has attached the notice described in - Exhibit B to the Covered Software; or - - b. that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the terms of - a Secondary License. - -1.6. "Executable Form" - - means any form of the work other than Source Code Form. - -1.7. "Larger Work" - - means a work that combines Covered Software with other material, in a - separate file or files, that is not Covered Software. - -1.8. "License" - - means this document. - -1.9. "Licensable" - - means having the right to grant, to the maximum extent possible, whether - at the time of the initial grant or subsequently, any and all of the - rights conveyed by this License. - -1.10. "Modifications" - - means any of the following: - - a. any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered Software; or - - b. any new file in Source Code Form that contains any Covered Software. - -1.11. "Patent Claims" of a Contributor - - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the License, - by the making, using, selling, offering for sale, having made, import, - or transfer of either its Contributions or its Contributor Version. - -1.12. "Secondary License" - - means either the GNU General Public License, Version 2.0, the GNU Lesser - General Public License, Version 2.1, the GNU Affero General Public - License, Version 3.0, or any later versions of those licenses. - -1.13. "Source Code Form" - - means the form of the work preferred for making modifications. - -1.14. "You" (or "Your") - - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that controls, is - controlled by, or is under common control with You. For purposes of this - definition, "control" means (a) the power, direct or indirect, to cause - the direction or management of such entity, whether by contract or - otherwise, or (b) ownership of more than fifty percent (50%) of the - outstanding shares or beneficial ownership of such entity. - - -2. License Grants and Conditions - -2.1. Grants - - Each Contributor hereby grants You a world-wide, royalty-free, - non-exclusive license: - - a. under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and - - b. under Patent Claims of such Contributor to make, use, sell, offer for - sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. - -2.2. Effective Date - - The licenses granted in Section 2.1 with respect to any Contribution - become effective for each Contribution on the date the Contributor first - distributes such Contribution. - -2.3. Limitations on Grant Scope - - The licenses granted in this Section 2 are the only rights granted under - this License. No additional rights or licenses will be implied from the - distribution or licensing of Covered Software under this License. - Notwithstanding Section 2.1(b) above, no patent license is granted by a - Contributor: - - a. for any code that a Contributor has removed from Covered Software; or - - b. for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - - c. under Patent Claims infringed by Covered Software in the absence of - its Contributions. - - This License does not grant any rights in the trademarks, service marks, - or logos of any Contributor (except as may be necessary to comply with - the notice requirements in Section 3.4). - -2.4. Subsequent Licenses - - No Contributor makes additional grants as a result of Your choice to - distribute the Covered Software under a subsequent version of this - License (see Section 10.2) or under the terms of a Secondary License (if - permitted under the terms of Section 3.3). - -2.5. Representation - - Each Contributor represents that the Contributor believes its - Contributions are its original creation(s) or it has sufficient rights to - grant the rights to its Contributions conveyed by this License. - -2.6. Fair Use - - This License is not intended to limit any rights You have under - applicable copyright doctrines of fair use, fair dealing, or other - equivalents. - -2.7. Conditions - - Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in - Section 2.1. - - -3. Responsibilities - -3.1. Distribution of Source Form - - All distribution of Covered Software in Source Code Form, including any - Modifications that You create or to which You contribute, must be under - the terms of this License. You must inform recipients that the Source - Code Form of the Covered Software is governed by the terms of this - License, and how they can obtain a copy of this License. You may not - attempt to alter or restrict the recipients' rights in the Source Code - Form. - -3.2. Distribution of Executable Form - - If You distribute Covered Software in Executable Form then: - - a. such Covered Software must also be made available in Source Code Form, - as described in Section 3.1, and You must inform recipients of the - Executable Form how they can obtain a copy of such Source Code Form by - reasonable means in a timely manner, at a charge no more than the cost - of distribution to the recipient; and - - b. You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter the - recipients' rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - - You may create and distribute a Larger Work under terms of Your choice, - provided that You also comply with the requirements of this License for - the Covered Software. If the Larger Work is a combination of Covered - Software with a work governed by one or more Secondary Licenses, and the - Covered Software is not Incompatible With Secondary Licenses, this - License permits You to additionally distribute such Covered Software - under the terms of such Secondary License(s), so that the recipient of - the Larger Work may, at their option, further distribute the Covered - Software under the terms of either this License or such Secondary - License(s). - -3.4. Notices - - You may not remove or alter the substance of any license notices - (including copyright notices, patent notices, disclaimers of warranty, or - limitations of liability) contained within the Source Code Form of the - Covered Software, except that You may alter any license notices to the - extent required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - - You may choose to offer, and to charge a fee for, warranty, support, - indemnity or liability obligations to one or more recipients of Covered - Software. However, You may do so only on Your own behalf, and not on - behalf of any Contributor. You must make it absolutely clear that any - such warranty, support, indemnity, or liability obligation is offered by - You alone, and You hereby agree to indemnify every Contributor for any - liability incurred by such Contributor as a result of warranty, support, - indemnity or liability terms You offer. You may include additional - disclaimers of warranty and limitations of liability specific to any - jurisdiction. - -4. Inability to Comply Due to Statute or Regulation - - If it is impossible for You to comply with any of the terms of this License - with respect to some or all of the Covered Software due to statute, - judicial order, or regulation then You must: (a) comply with the terms of - this License to the maximum extent possible; and (b) describe the - limitations and the code they affect. Such description must be placed in a - text file included with all distributions of the Covered Software under - this License. Except to the extent prohibited by statute or regulation, - such description must be sufficiently detailed for a recipient of ordinary - skill to be able to understand it. - -5. Termination - -5.1. The rights granted under this License will terminate automatically if You - fail to comply with any of its terms. However, if You become compliant, - then the rights granted under this License from a particular Contributor - are reinstated (a) provisionally, unless and until such Contributor - explicitly and finally terminates Your grants, and (b) on an ongoing - basis, if such Contributor fails to notify You of the non-compliance by - some reasonable means prior to 60 days after You have come back into - compliance. Moreover, Your grants from a particular Contributor are - reinstated on an ongoing basis if such Contributor notifies You of the - non-compliance by some reasonable means, this is the first time You have - received notice of non-compliance with this License from such - Contributor, and You become compliant prior to 30 days after Your receipt - of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent - infringement claim (excluding declaratory judgment actions, - counter-claims, and cross-claims) alleging that a Contributor Version - directly or indirectly infringes any patent, then the rights granted to - You by any and all Contributors for the Covered Software under Section - 2.1 of this License shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user - license agreements (excluding distributors and resellers) which have been - validly granted by You or Your distributors under this License prior to - termination shall survive termination. - -6. Disclaimer of Warranty - - Covered Software is provided under this License on an "as is" basis, - without warranty of any kind, either expressed, implied, or statutory, - including, without limitation, warranties that the Covered Software is free - of defects, merchantable, fit for a particular purpose or non-infringing. - The entire risk as to the quality and performance of the Covered Software - is with You. Should any Covered Software prove defective in any respect, - You (not any Contributor) assume the cost of any necessary servicing, - repair, or correction. This disclaimer of warranty constitutes an essential - part of this License. No use of any Covered Software is authorized under - this License except under this disclaimer. - -7. Limitation of Liability - - Under no circumstances and under no legal theory, whether tort (including - negligence), contract, or otherwise, shall any Contributor, or anyone who - distributes Covered Software as permitted above, be liable to You for any - direct, indirect, special, incidental, or consequential damages of any - character including, without limitation, damages for lost profits, loss of - goodwill, work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses, even if such party shall have been - informed of the possibility of such damages. This limitation of liability - shall not apply to liability for death or personal injury resulting from - such party's negligence to the extent applicable law prohibits such - limitation. Some jurisdictions do not allow the exclusion or limitation of - incidental or consequential damages, so this exclusion and limitation may - not apply to You. - -8. Litigation - - Any litigation relating to this License may be brought only in the courts - of a jurisdiction where the defendant maintains its principal place of - business and such litigation shall be governed by laws of that - jurisdiction, without reference to its conflict-of-law provisions. Nothing - in this Section shall prevent a party's ability to bring cross-claims or - counter-claims. - -9. Miscellaneous - - This License represents the complete agreement concerning the subject - matter hereof. If any provision of this License is held to be - unenforceable, such provision shall be reformed only to the extent - necessary to make it enforceable. Any law or regulation which provides that - the language of a contract shall be construed against the drafter shall not - be used to construe this License against a Contributor. - - -10. Versions of the License - -10.1. New Versions - - Mozilla Foundation is the license steward. Except as provided in Section - 10.3, no one other than the license steward has the right to modify or - publish new versions of this License. Each version will be given a - distinguishing version number. - -10.2. Effect of New Versions - - You may distribute the Covered Software under the terms of the version - of the License under which You originally received the Covered Software, - or under the terms of any subsequent version published by the license - steward. - -10.3. Modified Versions - - If you create software not governed by this License, and you want to - create a new license for such software, you may create and use a - modified version of this License if you rename the license and remove - any references to the name of the license steward (except to note that - such modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary - Licenses If You choose to distribute Source Code Form that is - Incompatible With Secondary Licenses under the terms of this version of - the License, the notice described in Exhibit B of this License must be - attached. - -Exhibit A - Source Code Form License Notice - - This Source Code Form is subject to the - terms of the Mozilla Public License, v. - 2.0. If a copy of the MPL was not - distributed with this file, You can - obtain one at - http://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular file, -then You may include the notice in a location (such as a LICENSE file in a -relevant directory) where a recipient would be likely to look for such a -notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - "Incompatible With Secondary Licenses" Notice - - This Source Code Form is "Incompatible - With Secondary Licenses", as defined by - the Mozilla Public License, v. 2.0. diff --git a/vendor/github.com/hashicorp/golang-lru/v2/internal/list.go b/vendor/github.com/hashicorp/golang-lru/v2/internal/list.go deleted file mode 100644 index 5cd74a0343..0000000000 --- a/vendor/github.com/hashicorp/golang-lru/v2/internal/list.go +++ /dev/null @@ -1,142 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE_list file. - -package internal - -import "time" - -// Entry is an LRU Entry -type Entry[K comparable, V any] struct { - // Next and previous pointers in the doubly-linked list of elements. - // To simplify the implementation, internally a list l is implemented - // as a ring, such that &l.root is both the next element of the last - // list element (l.Back()) and the previous element of the first list - // element (l.Front()). - next, prev *Entry[K, V] - - // The list to which this element belongs. - list *LruList[K, V] - - // The LRU Key of this element. - Key K - - // The Value stored with this element. - Value V - - // The time this element would be cleaned up, optional - ExpiresAt time.Time - - // The expiry bucket item was put in, optional - ExpireBucket uint8 -} - -// PrevEntry returns the previous list element or nil. -func (e *Entry[K, V]) PrevEntry() *Entry[K, V] { - if p := e.prev; e.list != nil && p != &e.list.root { - return p - } - return nil -} - -// LruList represents a doubly linked list. -// The zero Value for LruList is an empty list ready to use. -type LruList[K comparable, V any] struct { - root Entry[K, V] // sentinel list element, only &root, root.prev, and root.next are used - len int // current list Length excluding (this) sentinel element -} - -// Init initializes or clears list l. -func (l *LruList[K, V]) Init() *LruList[K, V] { - l.root.next = &l.root - l.root.prev = &l.root - l.len = 0 - return l -} - -// NewList returns an initialized list. -func NewList[K comparable, V any]() *LruList[K, V] { return new(LruList[K, V]).Init() } - -// Length returns the number of elements of list l. -// The complexity is O(1). -func (l *LruList[K, V]) Length() int { return l.len } - -// Back returns the last element of list l or nil if the list is empty. -func (l *LruList[K, V]) Back() *Entry[K, V] { - if l.len == 0 { - return nil - } - return l.root.prev -} - -// lazyInit lazily initializes a zero List Value. -func (l *LruList[K, V]) lazyInit() { - if l.root.next == nil { - l.Init() - } -} - -// insert inserts e after at, increments l.len, and returns e. -func (l *LruList[K, V]) insert(e, at *Entry[K, V]) *Entry[K, V] { - e.prev = at - e.next = at.next - e.prev.next = e - e.next.prev = e - e.list = l - l.len++ - return e -} - -// insertValue is a convenience wrapper for insert(&Entry{Value: v, ExpiresAt: ExpiresAt}, at). -func (l *LruList[K, V]) insertValue(k K, v V, expiresAt time.Time, at *Entry[K, V]) *Entry[K, V] { - return l.insert(&Entry[K, V]{Value: v, Key: k, ExpiresAt: expiresAt}, at) -} - -// Remove removes e from its list, decrements l.len -func (l *LruList[K, V]) Remove(e *Entry[K, V]) V { - e.prev.next = e.next - e.next.prev = e.prev - e.next = nil // avoid memory leaks - e.prev = nil // avoid memory leaks - e.list = nil - l.len-- - - return e.Value -} - -// move moves e to next to at. -func (l *LruList[K, V]) move(e, at *Entry[K, V]) { - if e == at { - return - } - e.prev.next = e.next - e.next.prev = e.prev - - e.prev = at - e.next = at.next - e.prev.next = e - e.next.prev = e -} - -// PushFront inserts a new element e with value v at the front of list l and returns e. -func (l *LruList[K, V]) PushFront(k K, v V) *Entry[K, V] { - l.lazyInit() - return l.insertValue(k, v, time.Time{}, &l.root) -} - -// PushFrontExpirable inserts a new expirable element e with Value v at the front of list l and returns e. -func (l *LruList[K, V]) PushFrontExpirable(k K, v V, expiresAt time.Time) *Entry[K, V] { - l.lazyInit() - return l.insertValue(k, v, expiresAt, &l.root) -} - -// MoveToFront moves element e to the front of list l. -// If e is not an element of l, the list is not modified. -// The element must not be nil. -func (l *LruList[K, V]) MoveToFront(e *Entry[K, V]) { - if e.list != l || l.root.next == e { - return - } - // see comment in List.Remove about initialization of l - l.move(e, &l.root) -} diff --git a/vendor/github.com/hashicorp/golang-lru/v2/simplelru/LICENSE_list b/vendor/github.com/hashicorp/golang-lru/v2/simplelru/LICENSE_list deleted file mode 100644 index c4764e6b2f..0000000000 --- a/vendor/github.com/hashicorp/golang-lru/v2/simplelru/LICENSE_list +++ /dev/null @@ -1,29 +0,0 @@ -This license applies to simplelru/list.go - -Copyright (c) 2009 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/hashicorp/golang-lru/v2/simplelru/lru.go b/vendor/github.com/hashicorp/golang-lru/v2/simplelru/lru.go deleted file mode 100644 index f69792388c..0000000000 --- a/vendor/github.com/hashicorp/golang-lru/v2/simplelru/lru.go +++ /dev/null @@ -1,177 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package simplelru - -import ( - "errors" - - "github.com/hashicorp/golang-lru/v2/internal" -) - -// EvictCallback is used to get a callback when a cache entry is evicted -type EvictCallback[K comparable, V any] func(key K, value V) - -// LRU implements a non-thread safe fixed size LRU cache -type LRU[K comparable, V any] struct { - size int - evictList *internal.LruList[K, V] - items map[K]*internal.Entry[K, V] - onEvict EvictCallback[K, V] -} - -// NewLRU constructs an LRU of the given size -func NewLRU[K comparable, V any](size int, onEvict EvictCallback[K, V]) (*LRU[K, V], error) { - if size <= 0 { - return nil, errors.New("must provide a positive size") - } - - c := &LRU[K, V]{ - size: size, - evictList: internal.NewList[K, V](), - items: make(map[K]*internal.Entry[K, V]), - onEvict: onEvict, - } - return c, nil -} - -// Purge is used to completely clear the cache. -func (c *LRU[K, V]) Purge() { - for k, v := range c.items { - if c.onEvict != nil { - c.onEvict(k, v.Value) - } - delete(c.items, k) - } - c.evictList.Init() -} - -// Add adds a value to the cache. Returns true if an eviction occurred. -func (c *LRU[K, V]) Add(key K, value V) (evicted bool) { - // Check for existing item - if ent, ok := c.items[key]; ok { - c.evictList.MoveToFront(ent) - ent.Value = value - return false - } - - // Add new item - ent := c.evictList.PushFront(key, value) - c.items[key] = ent - - evict := c.evictList.Length() > c.size - // Verify size not exceeded - if evict { - c.removeOldest() - } - return evict -} - -// Get looks up a key's value from the cache. -func (c *LRU[K, V]) Get(key K) (value V, ok bool) { - if ent, ok := c.items[key]; ok { - c.evictList.MoveToFront(ent) - return ent.Value, true - } - return -} - -// Contains checks if a key is in the cache, without updating the recent-ness -// or deleting it for being stale. -func (c *LRU[K, V]) Contains(key K) (ok bool) { - _, ok = c.items[key] - return ok -} - -// Peek returns the key value (or undefined if not found) without updating -// the "recently used"-ness of the key. -func (c *LRU[K, V]) Peek(key K) (value V, ok bool) { - var ent *internal.Entry[K, V] - if ent, ok = c.items[key]; ok { - return ent.Value, true - } - return -} - -// Remove removes the provided key from the cache, returning if the -// key was contained. -func (c *LRU[K, V]) Remove(key K) (present bool) { - if ent, ok := c.items[key]; ok { - c.removeElement(ent) - return true - } - return false -} - -// RemoveOldest removes the oldest item from the cache. -func (c *LRU[K, V]) RemoveOldest() (key K, value V, ok bool) { - if ent := c.evictList.Back(); ent != nil { - c.removeElement(ent) - return ent.Key, ent.Value, true - } - return -} - -// GetOldest returns the oldest entry -func (c *LRU[K, V]) GetOldest() (key K, value V, ok bool) { - if ent := c.evictList.Back(); ent != nil { - return ent.Key, ent.Value, true - } - return -} - -// Keys returns a slice of the keys in the cache, from oldest to newest. -func (c *LRU[K, V]) Keys() []K { - keys := make([]K, c.evictList.Length()) - i := 0 - for ent := c.evictList.Back(); ent != nil; ent = ent.PrevEntry() { - keys[i] = ent.Key - i++ - } - return keys -} - -// Values returns a slice of the values in the cache, from oldest to newest. -func (c *LRU[K, V]) Values() []V { - values := make([]V, len(c.items)) - i := 0 - for ent := c.evictList.Back(); ent != nil; ent = ent.PrevEntry() { - values[i] = ent.Value - i++ - } - return values -} - -// Len returns the number of items in the cache. -func (c *LRU[K, V]) Len() int { - return c.evictList.Length() -} - -// Resize changes the cache size. -func (c *LRU[K, V]) Resize(size int) (evicted int) { - diff := c.Len() - size - if diff < 0 { - diff = 0 - } - for i := 0; i < diff; i++ { - c.removeOldest() - } - c.size = size - return diff -} - -// removeOldest removes the oldest item from the cache. -func (c *LRU[K, V]) removeOldest() { - if ent := c.evictList.Back(); ent != nil { - c.removeElement(ent) - } -} - -// removeElement is used to remove a given list element from the cache -func (c *LRU[K, V]) removeElement(e *internal.Entry[K, V]) { - c.evictList.Remove(e) - delete(c.items, e.Key) - if c.onEvict != nil { - c.onEvict(e.Key, e.Value) - } -} diff --git a/vendor/github.com/hashicorp/golang-lru/v2/simplelru/lru_interface.go b/vendor/github.com/hashicorp/golang-lru/v2/simplelru/lru_interface.go deleted file mode 100644 index 043b8bcc3f..0000000000 --- a/vendor/github.com/hashicorp/golang-lru/v2/simplelru/lru_interface.go +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Package simplelru provides simple LRU implementation based on build-in container/list. -package simplelru - -// LRUCache is the interface for simple LRU cache. -type LRUCache[K comparable, V any] interface { - // Adds a value to the cache, returns true if an eviction occurred and - // updates the "recently used"-ness of the key. - Add(key K, value V) bool - - // Returns key's value from the cache and - // updates the "recently used"-ness of the key. #value, isFound - Get(key K) (value V, ok bool) - - // Checks if a key exists in cache without updating the recent-ness. - Contains(key K) (ok bool) - - // Returns key's value without updating the "recently used"-ness of the key. - Peek(key K) (value V, ok bool) - - // Removes a key from the cache. - Remove(key K) bool - - // Removes the oldest entry from cache. - RemoveOldest() (K, V, bool) - - // Returns the oldest entry from the cache. #key, value, isFound - GetOldest() (K, V, bool) - - // Returns a slice of the keys in the cache, from oldest to newest. - Keys() []K - - // Values returns a slice of the values in the cache, from oldest to newest. - Values() []V - - // Returns the number of items in the cache. - Len() int - - // Clears all cache entries. - Purge() - - // Resizes cache, returning number evicted - Resize(int) int -} diff --git a/vendor/github.com/hashicorp/hcl/.gitignore b/vendor/github.com/hashicorp/hcl/.gitignore deleted file mode 100644 index 15586a2b54..0000000000 --- a/vendor/github.com/hashicorp/hcl/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -y.output - -# ignore intellij files -.idea -*.iml -*.ipr -*.iws - -*.test diff --git a/vendor/github.com/hashicorp/hcl/.travis.yml b/vendor/github.com/hashicorp/hcl/.travis.yml deleted file mode 100644 index cb63a32161..0000000000 --- a/vendor/github.com/hashicorp/hcl/.travis.yml +++ /dev/null @@ -1,13 +0,0 @@ -sudo: false - -language: go - -go: - - 1.x - - tip - -branches: - only: - - master - -script: make test diff --git a/vendor/github.com/hashicorp/hcl/LICENSE b/vendor/github.com/hashicorp/hcl/LICENSE deleted file mode 100644 index c33dcc7c92..0000000000 --- a/vendor/github.com/hashicorp/hcl/LICENSE +++ /dev/null @@ -1,354 +0,0 @@ -Mozilla Public License, version 2.0 - -1. Definitions - -1.1. “Contributor” - - means each individual or legal entity that creates, contributes to the - creation of, or owns Covered Software. - -1.2. “Contributor Version” - - means the combination of the Contributions of others (if any) used by a - Contributor and that particular Contributor’s Contribution. - -1.3. “Contribution” - - means Covered Software of a particular Contributor. - -1.4. “Covered Software” - - means Source Code Form to which the initial Contributor has attached the - notice in Exhibit A, the Executable Form of such Source Code Form, and - Modifications of such Source Code Form, in each case including portions - thereof. - -1.5. “Incompatible With Secondary Licenses” - means - - a. that the initial Contributor has attached the notice described in - Exhibit B to the Covered Software; or - - b. that the Covered Software was made available under the terms of version - 1.1 or earlier of the License, but not also under the terms of a - Secondary License. - -1.6. “Executable Form” - - means any form of the work other than Source Code Form. - -1.7. “Larger Work” - - means a work that combines Covered Software with other material, in a separate - file or files, that is not Covered Software. - -1.8. “License” - - means this document. - -1.9. “Licensable” - - means having the right to grant, to the maximum extent possible, whether at the - time of the initial grant or subsequently, any and all of the rights conveyed by - this License. - -1.10. “Modifications” - - means any of the following: - - a. any file in Source Code Form that results from an addition to, deletion - from, or modification of the contents of Covered Software; or - - b. any new file in Source Code Form that contains any Covered Software. - -1.11. “Patent Claims” of a Contributor - - means any patent claim(s), including without limitation, method, process, - and apparatus claims, in any patent Licensable by such Contributor that - would be infringed, but for the grant of the License, by the making, - using, selling, offering for sale, having made, import, or transfer of - either its Contributions or its Contributor Version. - -1.12. “Secondary License” - - means either the GNU General Public License, Version 2.0, the GNU Lesser - General Public License, Version 2.1, the GNU Affero General Public - License, Version 3.0, or any later versions of those licenses. - -1.13. “Source Code Form” - - means the form of the work preferred for making modifications. - -1.14. “You” (or “Your”) - - means an individual or a legal entity exercising rights under this - License. For legal entities, “You” includes any entity that controls, is - controlled by, or is under common control with You. For purposes of this - definition, “control” means (a) the power, direct or indirect, to cause - the direction or management of such entity, whether by contract or - otherwise, or (b) ownership of more than fifty percent (50%) of the - outstanding shares or beneficial ownership of such entity. - - -2. License Grants and Conditions - -2.1. Grants - - Each Contributor hereby grants You a world-wide, royalty-free, - non-exclusive license: - - a. under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or as - part of a Larger Work; and - - b. under Patent Claims of such Contributor to make, use, sell, offer for - sale, have made, import, and otherwise transfer either its Contributions - or its Contributor Version. - -2.2. Effective Date - - The licenses granted in Section 2.1 with respect to any Contribution become - effective for each Contribution on the date the Contributor first distributes - such Contribution. - -2.3. Limitations on Grant Scope - - The licenses granted in this Section 2 are the only rights granted under this - License. No additional rights or licenses will be implied from the distribution - or licensing of Covered Software under this License. Notwithstanding Section - 2.1(b) above, no patent license is granted by a Contributor: - - a. for any code that a Contributor has removed from Covered Software; or - - b. for infringements caused by: (i) Your and any other third party’s - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - - c. under Patent Claims infringed by Covered Software in the absence of its - Contributions. - - This License does not grant any rights in the trademarks, service marks, or - logos of any Contributor (except as may be necessary to comply with the - notice requirements in Section 3.4). - -2.4. Subsequent Licenses - - No Contributor makes additional grants as a result of Your choice to - distribute the Covered Software under a subsequent version of this License - (see Section 10.2) or under the terms of a Secondary License (if permitted - under the terms of Section 3.3). - -2.5. Representation - - Each Contributor represents that the Contributor believes its Contributions - are its original creation(s) or it has sufficient rights to grant the - rights to its Contributions conveyed by this License. - -2.6. Fair Use - - This License is not intended to limit any rights You have under applicable - copyright doctrines of fair use, fair dealing, or other equivalents. - -2.7. Conditions - - Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in - Section 2.1. - - -3. Responsibilities - -3.1. Distribution of Source Form - - All distribution of Covered Software in Source Code Form, including any - Modifications that You create or to which You contribute, must be under the - terms of this License. You must inform recipients that the Source Code Form - of the Covered Software is governed by the terms of this License, and how - they can obtain a copy of this License. You may not attempt to alter or - restrict the recipients’ rights in the Source Code Form. - -3.2. Distribution of Executable Form - - If You distribute Covered Software in Executable Form then: - - a. such Covered Software must also be made available in Source Code Form, - as described in Section 3.1, and You must inform recipients of the - Executable Form how they can obtain a copy of such Source Code Form by - reasonable means in a timely manner, at a charge no more than the cost - of distribution to the recipient; and - - b. You may distribute such Executable Form under the terms of this License, - or sublicense it under different terms, provided that the license for - the Executable Form does not attempt to limit or alter the recipients’ - rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - - You may create and distribute a Larger Work under terms of Your choice, - provided that You also comply with the requirements of this License for the - Covered Software. If the Larger Work is a combination of Covered Software - with a work governed by one or more Secondary Licenses, and the Covered - Software is not Incompatible With Secondary Licenses, this License permits - You to additionally distribute such Covered Software under the terms of - such Secondary License(s), so that the recipient of the Larger Work may, at - their option, further distribute the Covered Software under the terms of - either this License or such Secondary License(s). - -3.4. Notices - - You may not remove or alter the substance of any license notices (including - copyright notices, patent notices, disclaimers of warranty, or limitations - of liability) contained within the Source Code Form of the Covered - Software, except that You may alter any license notices to the extent - required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - - You may choose to offer, and to charge a fee for, warranty, support, - indemnity or liability obligations to one or more recipients of Covered - Software. However, You may do so only on Your own behalf, and not on behalf - of any Contributor. You must make it absolutely clear that any such - warranty, support, indemnity, or liability obligation is offered by You - alone, and You hereby agree to indemnify every Contributor for any - liability incurred by such Contributor as a result of warranty, support, - indemnity or liability terms You offer. You may include additional - disclaimers of warranty and limitations of liability specific to any - jurisdiction. - -4. Inability to Comply Due to Statute or Regulation - - If it is impossible for You to comply with any of the terms of this License - with respect to some or all of the Covered Software due to statute, judicial - order, or regulation then You must: (a) comply with the terms of this License - to the maximum extent possible; and (b) describe the limitations and the code - they affect. Such description must be placed in a text file included with all - distributions of the Covered Software under this License. Except to the - extent prohibited by statute or regulation, such description must be - sufficiently detailed for a recipient of ordinary skill to be able to - understand it. - -5. Termination - -5.1. The rights granted under this License will terminate automatically if You - fail to comply with any of its terms. However, if You become compliant, - then the rights granted under this License from a particular Contributor - are reinstated (a) provisionally, unless and until such Contributor - explicitly and finally terminates Your grants, and (b) on an ongoing basis, - if such Contributor fails to notify You of the non-compliance by some - reasonable means prior to 60 days after You have come back into compliance. - Moreover, Your grants from a particular Contributor are reinstated on an - ongoing basis if such Contributor notifies You of the non-compliance by - some reasonable means, this is the first time You have received notice of - non-compliance with this License from such Contributor, and You become - compliant prior to 30 days after Your receipt of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent - infringement claim (excluding declaratory judgment actions, counter-claims, - and cross-claims) alleging that a Contributor Version directly or - indirectly infringes any patent, then the rights granted to You by any and - all Contributors for the Covered Software under Section 2.1 of this License - shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user - license agreements (excluding distributors and resellers) which have been - validly granted by You or Your distributors under this License prior to - termination shall survive termination. - -6. Disclaimer of Warranty - - Covered Software is provided under this License on an “as is” basis, without - warranty of any kind, either expressed, implied, or statutory, including, - without limitation, warranties that the Covered Software is free of defects, - merchantable, fit for a particular purpose or non-infringing. The entire - risk as to the quality and performance of the Covered Software is with You. - Should any Covered Software prove defective in any respect, You (not any - Contributor) assume the cost of any necessary servicing, repair, or - correction. This disclaimer of warranty constitutes an essential part of this - License. No use of any Covered Software is authorized under this License - except under this disclaimer. - -7. Limitation of Liability - - Under no circumstances and under no legal theory, whether tort (including - negligence), contract, or otherwise, shall any Contributor, or anyone who - distributes Covered Software as permitted above, be liable to You for any - direct, indirect, special, incidental, or consequential damages of any - character including, without limitation, damages for lost profits, loss of - goodwill, work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses, even if such party shall have been - informed of the possibility of such damages. This limitation of liability - shall not apply to liability for death or personal injury resulting from such - party’s negligence to the extent applicable law prohibits such limitation. - Some jurisdictions do not allow the exclusion or limitation of incidental or - consequential damages, so this exclusion and limitation may not apply to You. - -8. Litigation - - Any litigation relating to this License may be brought only in the courts of - a jurisdiction where the defendant maintains its principal place of business - and such litigation shall be governed by laws of that jurisdiction, without - reference to its conflict-of-law provisions. Nothing in this Section shall - prevent a party’s ability to bring cross-claims or counter-claims. - -9. Miscellaneous - - This License represents the complete agreement concerning the subject matter - hereof. If any provision of this License is held to be unenforceable, such - provision shall be reformed only to the extent necessary to make it - enforceable. Any law or regulation which provides that the language of a - contract shall be construed against the drafter shall not be used to construe - this License against a Contributor. - - -10. Versions of the License - -10.1. New Versions - - Mozilla Foundation is the license steward. Except as provided in Section - 10.3, no one other than the license steward has the right to modify or - publish new versions of this License. Each version will be given a - distinguishing version number. - -10.2. Effect of New Versions - - You may distribute the Covered Software under the terms of the version of - the License under which You originally received the Covered Software, or - under the terms of any subsequent version published by the license - steward. - -10.3. Modified Versions - - If you create software not governed by this License, and you want to - create a new license for such software, you may create and use a modified - version of this License if you rename the license and remove any - references to the name of the license steward (except to note that such - modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses - If You choose to distribute Source Code Form that is Incompatible With - Secondary Licenses under the terms of this version of the License, the - notice described in Exhibit B of this License must be attached. - -Exhibit A - Source Code Form License Notice - - This Source Code Form is subject to the - terms of the Mozilla Public License, v. - 2.0. If a copy of the MPL was not - distributed with this file, You can - obtain one at - http://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular file, then -You may include the notice in a location (such as a LICENSE file in a relevant -directory) where a recipient would be likely to look for such a notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - “Incompatible With Secondary Licenses” Notice - - This Source Code Form is “Incompatible - With Secondary Licenses”, as defined by - the Mozilla Public License, v. 2.0. - diff --git a/vendor/github.com/hashicorp/hcl/Makefile b/vendor/github.com/hashicorp/hcl/Makefile deleted file mode 100644 index 84fd743f5c..0000000000 --- a/vendor/github.com/hashicorp/hcl/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -TEST?=./... - -default: test - -fmt: generate - go fmt ./... - -test: generate - go get -t ./... - go test $(TEST) $(TESTARGS) - -generate: - go generate ./... - -updatedeps: - go get -u golang.org/x/tools/cmd/stringer - -.PHONY: default generate test updatedeps diff --git a/vendor/github.com/hashicorp/hcl/README.md b/vendor/github.com/hashicorp/hcl/README.md deleted file mode 100644 index c8223326dd..0000000000 --- a/vendor/github.com/hashicorp/hcl/README.md +++ /dev/null @@ -1,125 +0,0 @@ -# HCL - -[![GoDoc](https://godoc.org/github.com/hashicorp/hcl?status.png)](https://godoc.org/github.com/hashicorp/hcl) [![Build Status](https://travis-ci.org/hashicorp/hcl.svg?branch=master)](https://travis-ci.org/hashicorp/hcl) - -HCL (HashiCorp Configuration Language) is a configuration language built -by HashiCorp. The goal of HCL is to build a structured configuration language -that is both human and machine friendly for use with command-line tools, but -specifically targeted towards DevOps tools, servers, etc. - -HCL is also fully JSON compatible. That is, JSON can be used as completely -valid input to a system expecting HCL. This helps makes systems -interoperable with other systems. - -HCL is heavily inspired by -[libucl](https://github.com/vstakhov/libucl), -nginx configuration, and others similar. - -## Why? - -A common question when viewing HCL is to ask the question: why not -JSON, YAML, etc.? - -Prior to HCL, the tools we built at [HashiCorp](http://www.hashicorp.com) -used a variety of configuration languages from full programming languages -such as Ruby to complete data structure languages such as JSON. What we -learned is that some people wanted human-friendly configuration languages -and some people wanted machine-friendly languages. - -JSON fits a nice balance in this, but is fairly verbose and most -importantly doesn't support comments. With YAML, we found that beginners -had a really hard time determining what the actual structure was, and -ended up guessing more often than not whether to use a hyphen, colon, etc. -in order to represent some configuration key. - -Full programming languages such as Ruby enable complex behavior -a configuration language shouldn't usually allow, and also forces -people to learn some set of Ruby. - -Because of this, we decided to create our own configuration language -that is JSON-compatible. Our configuration language (HCL) is designed -to be written and modified by humans. The API for HCL allows JSON -as an input so that it is also machine-friendly (machines can generate -JSON instead of trying to generate HCL). - -Our goal with HCL is not to alienate other configuration languages. -It is instead to provide HCL as a specialized language for our tools, -and JSON as the interoperability layer. - -## Syntax - -For a complete grammar, please see the parser itself. A high-level overview -of the syntax and grammar is listed here. - - * Single line comments start with `#` or `//` - - * Multi-line comments are wrapped in `/*` and `*/`. Nested block comments - are not allowed. A multi-line comment (also known as a block comment) - terminates at the first `*/` found. - - * Values are assigned with the syntax `key = value` (whitespace doesn't - matter). The value can be any primitive: a string, number, boolean, - object, or list. - - * Strings are double-quoted and can contain any UTF-8 characters. - Example: `"Hello, World"` - - * Multi-line strings start with `<- - echo %Path% - - go version - - go env - - go get -t ./... - -build_script: -- cmd: go test -v ./... diff --git a/vendor/github.com/hashicorp/hcl/decoder.go b/vendor/github.com/hashicorp/hcl/decoder.go deleted file mode 100644 index bed9ebbe14..0000000000 --- a/vendor/github.com/hashicorp/hcl/decoder.go +++ /dev/null @@ -1,729 +0,0 @@ -package hcl - -import ( - "errors" - "fmt" - "reflect" - "sort" - "strconv" - "strings" - - "github.com/hashicorp/hcl/hcl/ast" - "github.com/hashicorp/hcl/hcl/parser" - "github.com/hashicorp/hcl/hcl/token" -) - -// This is the tag to use with structures to have settings for HCL -const tagName = "hcl" - -var ( - // nodeType holds a reference to the type of ast.Node - nodeType reflect.Type = findNodeType() -) - -// Unmarshal accepts a byte slice as input and writes the -// data to the value pointed to by v. -func Unmarshal(bs []byte, v interface{}) error { - root, err := parse(bs) - if err != nil { - return err - } - - return DecodeObject(v, root) -} - -// Decode reads the given input and decodes it into the structure -// given by `out`. -func Decode(out interface{}, in string) error { - obj, err := Parse(in) - if err != nil { - return err - } - - return DecodeObject(out, obj) -} - -// DecodeObject is a lower-level version of Decode. It decodes a -// raw Object into the given output. -func DecodeObject(out interface{}, n ast.Node) error { - val := reflect.ValueOf(out) - if val.Kind() != reflect.Ptr { - return errors.New("result must be a pointer") - } - - // If we have the file, we really decode the root node - if f, ok := n.(*ast.File); ok { - n = f.Node - } - - var d decoder - return d.decode("root", n, val.Elem()) -} - -type decoder struct { - stack []reflect.Kind -} - -func (d *decoder) decode(name string, node ast.Node, result reflect.Value) error { - k := result - - // If we have an interface with a valid value, we use that - // for the check. - if result.Kind() == reflect.Interface { - elem := result.Elem() - if elem.IsValid() { - k = elem - } - } - - // Push current onto stack unless it is an interface. - if k.Kind() != reflect.Interface { - d.stack = append(d.stack, k.Kind()) - - // Schedule a pop - defer func() { - d.stack = d.stack[:len(d.stack)-1] - }() - } - - switch k.Kind() { - case reflect.Bool: - return d.decodeBool(name, node, result) - case reflect.Float32, reflect.Float64: - return d.decodeFloat(name, node, result) - case reflect.Int, reflect.Int32, reflect.Int64: - return d.decodeInt(name, node, result) - case reflect.Interface: - // When we see an interface, we make our own thing - return d.decodeInterface(name, node, result) - case reflect.Map: - return d.decodeMap(name, node, result) - case reflect.Ptr: - return d.decodePtr(name, node, result) - case reflect.Slice: - return d.decodeSlice(name, node, result) - case reflect.String: - return d.decodeString(name, node, result) - case reflect.Struct: - return d.decodeStruct(name, node, result) - default: - return &parser.PosError{ - Pos: node.Pos(), - Err: fmt.Errorf("%s: unknown kind to decode into: %s", name, k.Kind()), - } - } -} - -func (d *decoder) decodeBool(name string, node ast.Node, result reflect.Value) error { - switch n := node.(type) { - case *ast.LiteralType: - if n.Token.Type == token.BOOL { - v, err := strconv.ParseBool(n.Token.Text) - if err != nil { - return err - } - - result.Set(reflect.ValueOf(v)) - return nil - } - } - - return &parser.PosError{ - Pos: node.Pos(), - Err: fmt.Errorf("%s: unknown type %T", name, node), - } -} - -func (d *decoder) decodeFloat(name string, node ast.Node, result reflect.Value) error { - switch n := node.(type) { - case *ast.LiteralType: - if n.Token.Type == token.FLOAT || n.Token.Type == token.NUMBER { - v, err := strconv.ParseFloat(n.Token.Text, 64) - if err != nil { - return err - } - - result.Set(reflect.ValueOf(v).Convert(result.Type())) - return nil - } - } - - return &parser.PosError{ - Pos: node.Pos(), - Err: fmt.Errorf("%s: unknown type %T", name, node), - } -} - -func (d *decoder) decodeInt(name string, node ast.Node, result reflect.Value) error { - switch n := node.(type) { - case *ast.LiteralType: - switch n.Token.Type { - case token.NUMBER: - v, err := strconv.ParseInt(n.Token.Text, 0, 0) - if err != nil { - return err - } - - if result.Kind() == reflect.Interface { - result.Set(reflect.ValueOf(int(v))) - } else { - result.SetInt(v) - } - return nil - case token.STRING: - v, err := strconv.ParseInt(n.Token.Value().(string), 0, 0) - if err != nil { - return err - } - - if result.Kind() == reflect.Interface { - result.Set(reflect.ValueOf(int(v))) - } else { - result.SetInt(v) - } - return nil - } - } - - return &parser.PosError{ - Pos: node.Pos(), - Err: fmt.Errorf("%s: unknown type %T", name, node), - } -} - -func (d *decoder) decodeInterface(name string, node ast.Node, result reflect.Value) error { - // When we see an ast.Node, we retain the value to enable deferred decoding. - // Very useful in situations where we want to preserve ast.Node information - // like Pos - if result.Type() == nodeType && result.CanSet() { - result.Set(reflect.ValueOf(node)) - return nil - } - - var set reflect.Value - redecode := true - - // For testing types, ObjectType should just be treated as a list. We - // set this to a temporary var because we want to pass in the real node. - testNode := node - if ot, ok := node.(*ast.ObjectType); ok { - testNode = ot.List - } - - switch n := testNode.(type) { - case *ast.ObjectList: - // If we're at the root or we're directly within a slice, then we - // decode objects into map[string]interface{}, otherwise we decode - // them into lists. - if len(d.stack) == 0 || d.stack[len(d.stack)-1] == reflect.Slice { - var temp map[string]interface{} - tempVal := reflect.ValueOf(temp) - result := reflect.MakeMap( - reflect.MapOf( - reflect.TypeOf(""), - tempVal.Type().Elem())) - - set = result - } else { - var temp []map[string]interface{} - tempVal := reflect.ValueOf(temp) - result := reflect.MakeSlice( - reflect.SliceOf(tempVal.Type().Elem()), 0, len(n.Items)) - set = result - } - case *ast.ObjectType: - // If we're at the root or we're directly within a slice, then we - // decode objects into map[string]interface{}, otherwise we decode - // them into lists. - if len(d.stack) == 0 || d.stack[len(d.stack)-1] == reflect.Slice { - var temp map[string]interface{} - tempVal := reflect.ValueOf(temp) - result := reflect.MakeMap( - reflect.MapOf( - reflect.TypeOf(""), - tempVal.Type().Elem())) - - set = result - } else { - var temp []map[string]interface{} - tempVal := reflect.ValueOf(temp) - result := reflect.MakeSlice( - reflect.SliceOf(tempVal.Type().Elem()), 0, 1) - set = result - } - case *ast.ListType: - var temp []interface{} - tempVal := reflect.ValueOf(temp) - result := reflect.MakeSlice( - reflect.SliceOf(tempVal.Type().Elem()), 0, 0) - set = result - case *ast.LiteralType: - switch n.Token.Type { - case token.BOOL: - var result bool - set = reflect.Indirect(reflect.New(reflect.TypeOf(result))) - case token.FLOAT: - var result float64 - set = reflect.Indirect(reflect.New(reflect.TypeOf(result))) - case token.NUMBER: - var result int - set = reflect.Indirect(reflect.New(reflect.TypeOf(result))) - case token.STRING, token.HEREDOC: - set = reflect.Indirect(reflect.New(reflect.TypeOf(""))) - default: - return &parser.PosError{ - Pos: node.Pos(), - Err: fmt.Errorf("%s: cannot decode into interface: %T", name, node), - } - } - default: - return fmt.Errorf( - "%s: cannot decode into interface: %T", - name, node) - } - - // Set the result to what its supposed to be, then reset - // result so we don't reflect into this method anymore. - result.Set(set) - - if redecode { - // Revisit the node so that we can use the newly instantiated - // thing and populate it. - if err := d.decode(name, node, result); err != nil { - return err - } - } - - return nil -} - -func (d *decoder) decodeMap(name string, node ast.Node, result reflect.Value) error { - if item, ok := node.(*ast.ObjectItem); ok { - node = &ast.ObjectList{Items: []*ast.ObjectItem{item}} - } - - if ot, ok := node.(*ast.ObjectType); ok { - node = ot.List - } - - n, ok := node.(*ast.ObjectList) - if !ok { - return &parser.PosError{ - Pos: node.Pos(), - Err: fmt.Errorf("%s: not an object type for map (%T)", name, node), - } - } - - // If we have an interface, then we can address the interface, - // but not the slice itself, so get the element but set the interface - set := result - if result.Kind() == reflect.Interface { - result = result.Elem() - } - - resultType := result.Type() - resultElemType := resultType.Elem() - resultKeyType := resultType.Key() - if resultKeyType.Kind() != reflect.String { - return &parser.PosError{ - Pos: node.Pos(), - Err: fmt.Errorf("%s: map must have string keys", name), - } - } - - // Make a map if it is nil - resultMap := result - if result.IsNil() { - resultMap = reflect.MakeMap( - reflect.MapOf(resultKeyType, resultElemType)) - } - - // Go through each element and decode it. - done := make(map[string]struct{}) - for _, item := range n.Items { - if item.Val == nil { - continue - } - - // github.com/hashicorp/terraform/issue/5740 - if len(item.Keys) == 0 { - return &parser.PosError{ - Pos: node.Pos(), - Err: fmt.Errorf("%s: map must have string keys", name), - } - } - - // Get the key we're dealing with, which is the first item - keyStr := item.Keys[0].Token.Value().(string) - - // If we've already processed this key, then ignore it - if _, ok := done[keyStr]; ok { - continue - } - - // Determine the value. If we have more than one key, then we - // get the objectlist of only these keys. - itemVal := item.Val - if len(item.Keys) > 1 { - itemVal = n.Filter(keyStr) - done[keyStr] = struct{}{} - } - - // Make the field name - fieldName := fmt.Sprintf("%s.%s", name, keyStr) - - // Get the key/value as reflection values - key := reflect.ValueOf(keyStr) - val := reflect.Indirect(reflect.New(resultElemType)) - - // If we have a pre-existing value in the map, use that - oldVal := resultMap.MapIndex(key) - if oldVal.IsValid() { - val.Set(oldVal) - } - - // Decode! - if err := d.decode(fieldName, itemVal, val); err != nil { - return err - } - - // Set the value on the map - resultMap.SetMapIndex(key, val) - } - - // Set the final map if we can - set.Set(resultMap) - return nil -} - -func (d *decoder) decodePtr(name string, node ast.Node, result reflect.Value) error { - // Create an element of the concrete (non pointer) type and decode - // into that. Then set the value of the pointer to this type. - resultType := result.Type() - resultElemType := resultType.Elem() - val := reflect.New(resultElemType) - if err := d.decode(name, node, reflect.Indirect(val)); err != nil { - return err - } - - result.Set(val) - return nil -} - -func (d *decoder) decodeSlice(name string, node ast.Node, result reflect.Value) error { - // If we have an interface, then we can address the interface, - // but not the slice itself, so get the element but set the interface - set := result - if result.Kind() == reflect.Interface { - result = result.Elem() - } - // Create the slice if it isn't nil - resultType := result.Type() - resultElemType := resultType.Elem() - if result.IsNil() { - resultSliceType := reflect.SliceOf(resultElemType) - result = reflect.MakeSlice( - resultSliceType, 0, 0) - } - - // Figure out the items we'll be copying into the slice - var items []ast.Node - switch n := node.(type) { - case *ast.ObjectList: - items = make([]ast.Node, len(n.Items)) - for i, item := range n.Items { - items[i] = item - } - case *ast.ObjectType: - items = []ast.Node{n} - case *ast.ListType: - items = n.List - default: - return &parser.PosError{ - Pos: node.Pos(), - Err: fmt.Errorf("unknown slice type: %T", node), - } - } - - for i, item := range items { - fieldName := fmt.Sprintf("%s[%d]", name, i) - - // Decode - val := reflect.Indirect(reflect.New(resultElemType)) - - // if item is an object that was decoded from ambiguous JSON and - // flattened, make sure it's expanded if it needs to decode into a - // defined structure. - item := expandObject(item, val) - - if err := d.decode(fieldName, item, val); err != nil { - return err - } - - // Append it onto the slice - result = reflect.Append(result, val) - } - - set.Set(result) - return nil -} - -// expandObject detects if an ambiguous JSON object was flattened to a List which -// should be decoded into a struct, and expands the ast to properly deocode. -func expandObject(node ast.Node, result reflect.Value) ast.Node { - item, ok := node.(*ast.ObjectItem) - if !ok { - return node - } - - elemType := result.Type() - - // our target type must be a struct - switch elemType.Kind() { - case reflect.Ptr: - switch elemType.Elem().Kind() { - case reflect.Struct: - //OK - default: - return node - } - case reflect.Struct: - //OK - default: - return node - } - - // A list value will have a key and field name. If it had more fields, - // it wouldn't have been flattened. - if len(item.Keys) != 2 { - return node - } - - keyToken := item.Keys[0].Token - item.Keys = item.Keys[1:] - - // we need to un-flatten the ast enough to decode - newNode := &ast.ObjectItem{ - Keys: []*ast.ObjectKey{ - &ast.ObjectKey{ - Token: keyToken, - }, - }, - Val: &ast.ObjectType{ - List: &ast.ObjectList{ - Items: []*ast.ObjectItem{item}, - }, - }, - } - - return newNode -} - -func (d *decoder) decodeString(name string, node ast.Node, result reflect.Value) error { - switch n := node.(type) { - case *ast.LiteralType: - switch n.Token.Type { - case token.NUMBER: - result.Set(reflect.ValueOf(n.Token.Text).Convert(result.Type())) - return nil - case token.STRING, token.HEREDOC: - result.Set(reflect.ValueOf(n.Token.Value()).Convert(result.Type())) - return nil - } - } - - return &parser.PosError{ - Pos: node.Pos(), - Err: fmt.Errorf("%s: unknown type for string %T", name, node), - } -} - -func (d *decoder) decodeStruct(name string, node ast.Node, result reflect.Value) error { - var item *ast.ObjectItem - if it, ok := node.(*ast.ObjectItem); ok { - item = it - node = it.Val - } - - if ot, ok := node.(*ast.ObjectType); ok { - node = ot.List - } - - // Handle the special case where the object itself is a literal. Previously - // the yacc parser would always ensure top-level elements were arrays. The new - // parser does not make the same guarantees, thus we need to convert any - // top-level literal elements into a list. - if _, ok := node.(*ast.LiteralType); ok && item != nil { - node = &ast.ObjectList{Items: []*ast.ObjectItem{item}} - } - - list, ok := node.(*ast.ObjectList) - if !ok { - return &parser.PosError{ - Pos: node.Pos(), - Err: fmt.Errorf("%s: not an object type for struct (%T)", name, node), - } - } - - // This slice will keep track of all the structs we'll be decoding. - // There can be more than one struct if there are embedded structs - // that are squashed. - structs := make([]reflect.Value, 1, 5) - structs[0] = result - - // Compile the list of all the fields that we're going to be decoding - // from all the structs. - type field struct { - field reflect.StructField - val reflect.Value - } - fields := []field{} - for len(structs) > 0 { - structVal := structs[0] - structs = structs[1:] - - structType := structVal.Type() - for i := 0; i < structType.NumField(); i++ { - fieldType := structType.Field(i) - tagParts := strings.Split(fieldType.Tag.Get(tagName), ",") - - // Ignore fields with tag name "-" - if tagParts[0] == "-" { - continue - } - - if fieldType.Anonymous { - fieldKind := fieldType.Type.Kind() - if fieldKind != reflect.Struct { - return &parser.PosError{ - Pos: node.Pos(), - Err: fmt.Errorf("%s: unsupported type to struct: %s", - fieldType.Name, fieldKind), - } - } - - // We have an embedded field. We "squash" the fields down - // if specified in the tag. - squash := false - for _, tag := range tagParts[1:] { - if tag == "squash" { - squash = true - break - } - } - - if squash { - structs = append( - structs, result.FieldByName(fieldType.Name)) - continue - } - } - - // Normal struct field, store it away - fields = append(fields, field{fieldType, structVal.Field(i)}) - } - } - - usedKeys := make(map[string]struct{}) - decodedFields := make([]string, 0, len(fields)) - decodedFieldsVal := make([]reflect.Value, 0) - unusedKeysVal := make([]reflect.Value, 0) - for _, f := range fields { - field, fieldValue := f.field, f.val - if !fieldValue.IsValid() { - // This should never happen - panic("field is not valid") - } - - // If we can't set the field, then it is unexported or something, - // and we just continue onwards. - if !fieldValue.CanSet() { - continue - } - - fieldName := field.Name - - tagValue := field.Tag.Get(tagName) - tagParts := strings.SplitN(tagValue, ",", 2) - if len(tagParts) >= 2 { - switch tagParts[1] { - case "decodedFields": - decodedFieldsVal = append(decodedFieldsVal, fieldValue) - continue - case "key": - if item == nil { - return &parser.PosError{ - Pos: node.Pos(), - Err: fmt.Errorf("%s: %s asked for 'key', impossible", - name, fieldName), - } - } - - fieldValue.SetString(item.Keys[0].Token.Value().(string)) - continue - case "unusedKeys": - unusedKeysVal = append(unusedKeysVal, fieldValue) - continue - } - } - - if tagParts[0] != "" { - fieldName = tagParts[0] - } - - // Determine the element we'll use to decode. If it is a single - // match (only object with the field), then we decode it exactly. - // If it is a prefix match, then we decode the matches. - filter := list.Filter(fieldName) - - prefixMatches := filter.Children() - matches := filter.Elem() - if len(matches.Items) == 0 && len(prefixMatches.Items) == 0 { - continue - } - - // Track the used key - usedKeys[fieldName] = struct{}{} - - // Create the field name and decode. We range over the elements - // because we actually want the value. - fieldName = fmt.Sprintf("%s.%s", name, fieldName) - if len(prefixMatches.Items) > 0 { - if err := d.decode(fieldName, prefixMatches, fieldValue); err != nil { - return err - } - } - for _, match := range matches.Items { - var decodeNode ast.Node = match.Val - if ot, ok := decodeNode.(*ast.ObjectType); ok { - decodeNode = &ast.ObjectList{Items: ot.List.Items} - } - - if err := d.decode(fieldName, decodeNode, fieldValue); err != nil { - return err - } - } - - decodedFields = append(decodedFields, field.Name) - } - - if len(decodedFieldsVal) > 0 { - // Sort it so that it is deterministic - sort.Strings(decodedFields) - - for _, v := range decodedFieldsVal { - v.Set(reflect.ValueOf(decodedFields)) - } - } - - return nil -} - -// findNodeType returns the type of ast.Node -func findNodeType() reflect.Type { - var nodeContainer struct { - Node ast.Node - } - value := reflect.ValueOf(nodeContainer).FieldByName("Node") - return value.Type() -} diff --git a/vendor/github.com/hashicorp/hcl/hcl.go b/vendor/github.com/hashicorp/hcl/hcl.go deleted file mode 100644 index 575a20b50b..0000000000 --- a/vendor/github.com/hashicorp/hcl/hcl.go +++ /dev/null @@ -1,11 +0,0 @@ -// Package hcl decodes HCL into usable Go structures. -// -// hcl input can come in either pure HCL format or JSON format. -// It can be parsed into an AST, and then decoded into a structure, -// or it can be decoded directly from a string into a structure. -// -// If you choose to parse HCL into a raw AST, the benefit is that you -// can write custom visitor implementations to implement custom -// semantic checks. By default, HCL does not perform any semantic -// checks. -package hcl diff --git a/vendor/github.com/hashicorp/hcl/hcl/ast/ast.go b/vendor/github.com/hashicorp/hcl/hcl/ast/ast.go deleted file mode 100644 index 6e5ef654bb..0000000000 --- a/vendor/github.com/hashicorp/hcl/hcl/ast/ast.go +++ /dev/null @@ -1,219 +0,0 @@ -// Package ast declares the types used to represent syntax trees for HCL -// (HashiCorp Configuration Language) -package ast - -import ( - "fmt" - "strings" - - "github.com/hashicorp/hcl/hcl/token" -) - -// Node is an element in the abstract syntax tree. -type Node interface { - node() - Pos() token.Pos -} - -func (File) node() {} -func (ObjectList) node() {} -func (ObjectKey) node() {} -func (ObjectItem) node() {} -func (Comment) node() {} -func (CommentGroup) node() {} -func (ObjectType) node() {} -func (LiteralType) node() {} -func (ListType) node() {} - -// File represents a single HCL file -type File struct { - Node Node // usually a *ObjectList - Comments []*CommentGroup // list of all comments in the source -} - -func (f *File) Pos() token.Pos { - return f.Node.Pos() -} - -// ObjectList represents a list of ObjectItems. An HCL file itself is an -// ObjectList. -type ObjectList struct { - Items []*ObjectItem -} - -func (o *ObjectList) Add(item *ObjectItem) { - o.Items = append(o.Items, item) -} - -// Filter filters out the objects with the given key list as a prefix. -// -// The returned list of objects contain ObjectItems where the keys have -// this prefix already stripped off. This might result in objects with -// zero-length key lists if they have no children. -// -// If no matches are found, an empty ObjectList (non-nil) is returned. -func (o *ObjectList) Filter(keys ...string) *ObjectList { - var result ObjectList - for _, item := range o.Items { - // If there aren't enough keys, then ignore this - if len(item.Keys) < len(keys) { - continue - } - - match := true - for i, key := range item.Keys[:len(keys)] { - key := key.Token.Value().(string) - if key != keys[i] && !strings.EqualFold(key, keys[i]) { - match = false - break - } - } - if !match { - continue - } - - // Strip off the prefix from the children - newItem := *item - newItem.Keys = newItem.Keys[len(keys):] - result.Add(&newItem) - } - - return &result -} - -// Children returns further nested objects (key length > 0) within this -// ObjectList. This should be used with Filter to get at child items. -func (o *ObjectList) Children() *ObjectList { - var result ObjectList - for _, item := range o.Items { - if len(item.Keys) > 0 { - result.Add(item) - } - } - - return &result -} - -// Elem returns items in the list that are direct element assignments -// (key length == 0). This should be used with Filter to get at elements. -func (o *ObjectList) Elem() *ObjectList { - var result ObjectList - for _, item := range o.Items { - if len(item.Keys) == 0 { - result.Add(item) - } - } - - return &result -} - -func (o *ObjectList) Pos() token.Pos { - // always returns the uninitiliazed position - return o.Items[0].Pos() -} - -// ObjectItem represents a HCL Object Item. An item is represented with a key -// (or keys). It can be an assignment or an object (both normal and nested) -type ObjectItem struct { - // keys is only one length long if it's of type assignment. If it's a - // nested object it can be larger than one. In that case "assign" is - // invalid as there is no assignments for a nested object. - Keys []*ObjectKey - - // assign contains the position of "=", if any - Assign token.Pos - - // val is the item itself. It can be an object,list, number, bool or a - // string. If key length is larger than one, val can be only of type - // Object. - Val Node - - LeadComment *CommentGroup // associated lead comment - LineComment *CommentGroup // associated line comment -} - -func (o *ObjectItem) Pos() token.Pos { - // I'm not entirely sure what causes this, but removing this causes - // a test failure. We should investigate at some point. - if len(o.Keys) == 0 { - return token.Pos{} - } - - return o.Keys[0].Pos() -} - -// ObjectKeys are either an identifier or of type string. -type ObjectKey struct { - Token token.Token -} - -func (o *ObjectKey) Pos() token.Pos { - return o.Token.Pos -} - -// LiteralType represents a literal of basic type. Valid types are: -// token.NUMBER, token.FLOAT, token.BOOL and token.STRING -type LiteralType struct { - Token token.Token - - // comment types, only used when in a list - LeadComment *CommentGroup - LineComment *CommentGroup -} - -func (l *LiteralType) Pos() token.Pos { - return l.Token.Pos -} - -// ListStatement represents a HCL List type -type ListType struct { - Lbrack token.Pos // position of "[" - Rbrack token.Pos // position of "]" - List []Node // the elements in lexical order -} - -func (l *ListType) Pos() token.Pos { - return l.Lbrack -} - -func (l *ListType) Add(node Node) { - l.List = append(l.List, node) -} - -// ObjectType represents a HCL Object Type -type ObjectType struct { - Lbrace token.Pos // position of "{" - Rbrace token.Pos // position of "}" - List *ObjectList // the nodes in lexical order -} - -func (o *ObjectType) Pos() token.Pos { - return o.Lbrace -} - -// Comment node represents a single //, # style or /*- style commment -type Comment struct { - Start token.Pos // position of / or # - Text string -} - -func (c *Comment) Pos() token.Pos { - return c.Start -} - -// CommentGroup node represents a sequence of comments with no other tokens and -// no empty lines between. -type CommentGroup struct { - List []*Comment // len(List) > 0 -} - -func (c *CommentGroup) Pos() token.Pos { - return c.List[0].Pos() -} - -//------------------------------------------------------------------- -// GoStringer -//------------------------------------------------------------------- - -func (o *ObjectKey) GoString() string { return fmt.Sprintf("*%#v", *o) } -func (o *ObjectList) GoString() string { return fmt.Sprintf("*%#v", *o) } diff --git a/vendor/github.com/hashicorp/hcl/hcl/ast/walk.go b/vendor/github.com/hashicorp/hcl/hcl/ast/walk.go deleted file mode 100644 index ba07ad42b0..0000000000 --- a/vendor/github.com/hashicorp/hcl/hcl/ast/walk.go +++ /dev/null @@ -1,52 +0,0 @@ -package ast - -import "fmt" - -// WalkFunc describes a function to be called for each node during a Walk. The -// returned node can be used to rewrite the AST. Walking stops the returned -// bool is false. -type WalkFunc func(Node) (Node, bool) - -// Walk traverses an AST in depth-first order: It starts by calling fn(node); -// node must not be nil. If fn returns true, Walk invokes fn recursively for -// each of the non-nil children of node, followed by a call of fn(nil). The -// returned node of fn can be used to rewrite the passed node to fn. -func Walk(node Node, fn WalkFunc) Node { - rewritten, ok := fn(node) - if !ok { - return rewritten - } - - switch n := node.(type) { - case *File: - n.Node = Walk(n.Node, fn) - case *ObjectList: - for i, item := range n.Items { - n.Items[i] = Walk(item, fn).(*ObjectItem) - } - case *ObjectKey: - // nothing to do - case *ObjectItem: - for i, k := range n.Keys { - n.Keys[i] = Walk(k, fn).(*ObjectKey) - } - - if n.Val != nil { - n.Val = Walk(n.Val, fn) - } - case *LiteralType: - // nothing to do - case *ListType: - for i, l := range n.List { - n.List[i] = Walk(l, fn) - } - case *ObjectType: - n.List = Walk(n.List, fn).(*ObjectList) - default: - // should we panic here? - fmt.Printf("unknown type: %T\n", n) - } - - fn(nil) - return rewritten -} diff --git a/vendor/github.com/hashicorp/hcl/hcl/parser/error.go b/vendor/github.com/hashicorp/hcl/hcl/parser/error.go deleted file mode 100644 index 5c99381dfb..0000000000 --- a/vendor/github.com/hashicorp/hcl/hcl/parser/error.go +++ /dev/null @@ -1,17 +0,0 @@ -package parser - -import ( - "fmt" - - "github.com/hashicorp/hcl/hcl/token" -) - -// PosError is a parse error that contains a position. -type PosError struct { - Pos token.Pos - Err error -} - -func (e *PosError) Error() string { - return fmt.Sprintf("At %s: %s", e.Pos, e.Err) -} diff --git a/vendor/github.com/hashicorp/hcl/hcl/parser/parser.go b/vendor/github.com/hashicorp/hcl/hcl/parser/parser.go deleted file mode 100644 index 64c83bcfb5..0000000000 --- a/vendor/github.com/hashicorp/hcl/hcl/parser/parser.go +++ /dev/null @@ -1,532 +0,0 @@ -// Package parser implements a parser for HCL (HashiCorp Configuration -// Language) -package parser - -import ( - "bytes" - "errors" - "fmt" - "strings" - - "github.com/hashicorp/hcl/hcl/ast" - "github.com/hashicorp/hcl/hcl/scanner" - "github.com/hashicorp/hcl/hcl/token" -) - -type Parser struct { - sc *scanner.Scanner - - // Last read token - tok token.Token - commaPrev token.Token - - comments []*ast.CommentGroup - leadComment *ast.CommentGroup // last lead comment - lineComment *ast.CommentGroup // last line comment - - enableTrace bool - indent int - n int // buffer size (max = 1) -} - -func newParser(src []byte) *Parser { - return &Parser{ - sc: scanner.New(src), - } -} - -// Parse returns the fully parsed source and returns the abstract syntax tree. -func Parse(src []byte) (*ast.File, error) { - // normalize all line endings - // since the scanner and output only work with "\n" line endings, we may - // end up with dangling "\r" characters in the parsed data. - src = bytes.Replace(src, []byte("\r\n"), []byte("\n"), -1) - - p := newParser(src) - return p.Parse() -} - -var errEofToken = errors.New("EOF token found") - -// Parse returns the fully parsed source and returns the abstract syntax tree. -func (p *Parser) Parse() (*ast.File, error) { - f := &ast.File{} - var err, scerr error - p.sc.Error = func(pos token.Pos, msg string) { - scerr = &PosError{Pos: pos, Err: errors.New(msg)} - } - - f.Node, err = p.objectList(false) - if scerr != nil { - return nil, scerr - } - if err != nil { - return nil, err - } - - f.Comments = p.comments - return f, nil -} - -// objectList parses a list of items within an object (generally k/v pairs). -// The parameter" obj" tells this whether to we are within an object (braces: -// '{', '}') or just at the top level. If we're within an object, we end -// at an RBRACE. -func (p *Parser) objectList(obj bool) (*ast.ObjectList, error) { - defer un(trace(p, "ParseObjectList")) - node := &ast.ObjectList{} - - for { - if obj { - tok := p.scan() - p.unscan() - if tok.Type == token.RBRACE { - break - } - } - - n, err := p.objectItem() - if err == errEofToken { - break // we are finished - } - - // we don't return a nil node, because might want to use already - // collected items. - if err != nil { - return node, err - } - - node.Add(n) - - // object lists can be optionally comma-delimited e.g. when a list of maps - // is being expressed, so a comma is allowed here - it's simply consumed - tok := p.scan() - if tok.Type != token.COMMA { - p.unscan() - } - } - return node, nil -} - -func (p *Parser) consumeComment() (comment *ast.Comment, endline int) { - endline = p.tok.Pos.Line - - // count the endline if it's multiline comment, ie starting with /* - if len(p.tok.Text) > 1 && p.tok.Text[1] == '*' { - // don't use range here - no need to decode Unicode code points - for i := 0; i < len(p.tok.Text); i++ { - if p.tok.Text[i] == '\n' { - endline++ - } - } - } - - comment = &ast.Comment{Start: p.tok.Pos, Text: p.tok.Text} - p.tok = p.sc.Scan() - return -} - -func (p *Parser) consumeCommentGroup(n int) (comments *ast.CommentGroup, endline int) { - var list []*ast.Comment - endline = p.tok.Pos.Line - - for p.tok.Type == token.COMMENT && p.tok.Pos.Line <= endline+n { - var comment *ast.Comment - comment, endline = p.consumeComment() - list = append(list, comment) - } - - // add comment group to the comments list - comments = &ast.CommentGroup{List: list} - p.comments = append(p.comments, comments) - - return -} - -// objectItem parses a single object item -func (p *Parser) objectItem() (*ast.ObjectItem, error) { - defer un(trace(p, "ParseObjectItem")) - - keys, err := p.objectKey() - if len(keys) > 0 && err == errEofToken { - // We ignore eof token here since it is an error if we didn't - // receive a value (but we did receive a key) for the item. - err = nil - } - if len(keys) > 0 && err != nil && p.tok.Type == token.RBRACE { - // This is a strange boolean statement, but what it means is: - // We have keys with no value, and we're likely in an object - // (since RBrace ends an object). For this, we set err to nil so - // we continue and get the error below of having the wrong value - // type. - err = nil - - // Reset the token type so we don't think it completed fine. See - // objectType which uses p.tok.Type to check if we're done with - // the object. - p.tok.Type = token.EOF - } - if err != nil { - return nil, err - } - - o := &ast.ObjectItem{ - Keys: keys, - } - - if p.leadComment != nil { - o.LeadComment = p.leadComment - p.leadComment = nil - } - - switch p.tok.Type { - case token.ASSIGN: - o.Assign = p.tok.Pos - o.Val, err = p.object() - if err != nil { - return nil, err - } - case token.LBRACE: - o.Val, err = p.objectType() - if err != nil { - return nil, err - } - default: - keyStr := make([]string, 0, len(keys)) - for _, k := range keys { - keyStr = append(keyStr, k.Token.Text) - } - - return nil, &PosError{ - Pos: p.tok.Pos, - Err: fmt.Errorf( - "key '%s' expected start of object ('{') or assignment ('=')", - strings.Join(keyStr, " ")), - } - } - - // key=#comment - // val - if p.lineComment != nil { - o.LineComment, p.lineComment = p.lineComment, nil - } - - // do a look-ahead for line comment - p.scan() - if len(keys) > 0 && o.Val.Pos().Line == keys[0].Pos().Line && p.lineComment != nil { - o.LineComment = p.lineComment - p.lineComment = nil - } - p.unscan() - return o, nil -} - -// objectKey parses an object key and returns a ObjectKey AST -func (p *Parser) objectKey() ([]*ast.ObjectKey, error) { - keyCount := 0 - keys := make([]*ast.ObjectKey, 0) - - for { - tok := p.scan() - switch tok.Type { - case token.EOF: - // It is very important to also return the keys here as well as - // the error. This is because we need to be able to tell if we - // did parse keys prior to finding the EOF, or if we just found - // a bare EOF. - return keys, errEofToken - case token.ASSIGN: - // assignment or object only, but not nested objects. this is not - // allowed: `foo bar = {}` - if keyCount > 1 { - return nil, &PosError{ - Pos: p.tok.Pos, - Err: fmt.Errorf("nested object expected: LBRACE got: %s", p.tok.Type), - } - } - - if keyCount == 0 { - return nil, &PosError{ - Pos: p.tok.Pos, - Err: errors.New("no object keys found!"), - } - } - - return keys, nil - case token.LBRACE: - var err error - - // If we have no keys, then it is a syntax error. i.e. {{}} is not - // allowed. - if len(keys) == 0 { - err = &PosError{ - Pos: p.tok.Pos, - Err: fmt.Errorf("expected: IDENT | STRING got: %s", p.tok.Type), - } - } - - // object - return keys, err - case token.IDENT, token.STRING: - keyCount++ - keys = append(keys, &ast.ObjectKey{Token: p.tok}) - case token.ILLEGAL: - return keys, &PosError{ - Pos: p.tok.Pos, - Err: fmt.Errorf("illegal character"), - } - default: - return keys, &PosError{ - Pos: p.tok.Pos, - Err: fmt.Errorf("expected: IDENT | STRING | ASSIGN | LBRACE got: %s", p.tok.Type), - } - } - } -} - -// object parses any type of object, such as number, bool, string, object or -// list. -func (p *Parser) object() (ast.Node, error) { - defer un(trace(p, "ParseType")) - tok := p.scan() - - switch tok.Type { - case token.NUMBER, token.FLOAT, token.BOOL, token.STRING, token.HEREDOC: - return p.literalType() - case token.LBRACE: - return p.objectType() - case token.LBRACK: - return p.listType() - case token.COMMENT: - // implement comment - case token.EOF: - return nil, errEofToken - } - - return nil, &PosError{ - Pos: tok.Pos, - Err: fmt.Errorf("Unknown token: %+v", tok), - } -} - -// objectType parses an object type and returns a ObjectType AST -func (p *Parser) objectType() (*ast.ObjectType, error) { - defer un(trace(p, "ParseObjectType")) - - // we assume that the currently scanned token is a LBRACE - o := &ast.ObjectType{ - Lbrace: p.tok.Pos, - } - - l, err := p.objectList(true) - - // if we hit RBRACE, we are good to go (means we parsed all Items), if it's - // not a RBRACE, it's an syntax error and we just return it. - if err != nil && p.tok.Type != token.RBRACE { - return nil, err - } - - // No error, scan and expect the ending to be a brace - if tok := p.scan(); tok.Type != token.RBRACE { - return nil, &PosError{ - Pos: tok.Pos, - Err: fmt.Errorf("object expected closing RBRACE got: %s", tok.Type), - } - } - - o.List = l - o.Rbrace = p.tok.Pos // advanced via parseObjectList - return o, nil -} - -// listType parses a list type and returns a ListType AST -func (p *Parser) listType() (*ast.ListType, error) { - defer un(trace(p, "ParseListType")) - - // we assume that the currently scanned token is a LBRACK - l := &ast.ListType{ - Lbrack: p.tok.Pos, - } - - needComma := false - for { - tok := p.scan() - if needComma { - switch tok.Type { - case token.COMMA, token.RBRACK: - default: - return nil, &PosError{ - Pos: tok.Pos, - Err: fmt.Errorf( - "error parsing list, expected comma or list end, got: %s", - tok.Type), - } - } - } - switch tok.Type { - case token.BOOL, token.NUMBER, token.FLOAT, token.STRING, token.HEREDOC: - node, err := p.literalType() - if err != nil { - return nil, err - } - - // If there is a lead comment, apply it - if p.leadComment != nil { - node.LeadComment = p.leadComment - p.leadComment = nil - } - - l.Add(node) - needComma = true - case token.COMMA: - // get next list item or we are at the end - // do a look-ahead for line comment - p.scan() - if p.lineComment != nil && len(l.List) > 0 { - lit, ok := l.List[len(l.List)-1].(*ast.LiteralType) - if ok { - lit.LineComment = p.lineComment - l.List[len(l.List)-1] = lit - p.lineComment = nil - } - } - p.unscan() - - needComma = false - continue - case token.LBRACE: - // Looks like a nested object, so parse it out - node, err := p.objectType() - if err != nil { - return nil, &PosError{ - Pos: tok.Pos, - Err: fmt.Errorf( - "error while trying to parse object within list: %s", err), - } - } - l.Add(node) - needComma = true - case token.LBRACK: - node, err := p.listType() - if err != nil { - return nil, &PosError{ - Pos: tok.Pos, - Err: fmt.Errorf( - "error while trying to parse list within list: %s", err), - } - } - l.Add(node) - case token.RBRACK: - // finished - l.Rbrack = p.tok.Pos - return l, nil - default: - return nil, &PosError{ - Pos: tok.Pos, - Err: fmt.Errorf("unexpected token while parsing list: %s", tok.Type), - } - } - } -} - -// literalType parses a literal type and returns a LiteralType AST -func (p *Parser) literalType() (*ast.LiteralType, error) { - defer un(trace(p, "ParseLiteral")) - - return &ast.LiteralType{ - Token: p.tok, - }, nil -} - -// scan returns the next token from the underlying scanner. If a token has -// been unscanned then read that instead. In the process, it collects any -// comment groups encountered, and remembers the last lead and line comments. -func (p *Parser) scan() token.Token { - // If we have a token on the buffer, then return it. - if p.n != 0 { - p.n = 0 - return p.tok - } - - // Otherwise read the next token from the scanner and Save it to the buffer - // in case we unscan later. - prev := p.tok - p.tok = p.sc.Scan() - - if p.tok.Type == token.COMMENT { - var comment *ast.CommentGroup - var endline int - - // fmt.Printf("p.tok.Pos.Line = %+v prev: %d endline %d \n", - // p.tok.Pos.Line, prev.Pos.Line, endline) - if p.tok.Pos.Line == prev.Pos.Line { - // The comment is on same line as the previous token; it - // cannot be a lead comment but may be a line comment. - comment, endline = p.consumeCommentGroup(0) - if p.tok.Pos.Line != endline { - // The next token is on a different line, thus - // the last comment group is a line comment. - p.lineComment = comment - } - } - - // consume successor comments, if any - endline = -1 - for p.tok.Type == token.COMMENT { - comment, endline = p.consumeCommentGroup(1) - } - - if endline+1 == p.tok.Pos.Line && p.tok.Type != token.RBRACE { - switch p.tok.Type { - case token.RBRACE, token.RBRACK: - // Do not count for these cases - default: - // The next token is following on the line immediately after the - // comment group, thus the last comment group is a lead comment. - p.leadComment = comment - } - } - - } - - return p.tok -} - -// unscan pushes the previously read token back onto the buffer. -func (p *Parser) unscan() { - p.n = 1 -} - -// ---------------------------------------------------------------------------- -// Parsing support - -func (p *Parser) printTrace(a ...interface{}) { - if !p.enableTrace { - return - } - - const dots = ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . " - const n = len(dots) - fmt.Printf("%5d:%3d: ", p.tok.Pos.Line, p.tok.Pos.Column) - - i := 2 * p.indent - for i > n { - fmt.Print(dots) - i -= n - } - // i <= n - fmt.Print(dots[0:i]) - fmt.Println(a...) -} - -func trace(p *Parser, msg string) *Parser { - p.printTrace(msg, "(") - p.indent++ - return p -} - -// Usage pattern: defer un(trace(p, "...")) -func un(p *Parser) { - p.indent-- - p.printTrace(")") -} diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/nodes.go b/vendor/github.com/hashicorp/hcl/hcl/printer/nodes.go deleted file mode 100644 index 7c038d12a2..0000000000 --- a/vendor/github.com/hashicorp/hcl/hcl/printer/nodes.go +++ /dev/null @@ -1,789 +0,0 @@ -package printer - -import ( - "bytes" - "fmt" - "sort" - - "github.com/hashicorp/hcl/hcl/ast" - "github.com/hashicorp/hcl/hcl/token" -) - -const ( - blank = byte(' ') - newline = byte('\n') - tab = byte('\t') - infinity = 1 << 30 // offset or line -) - -var ( - unindent = []byte("\uE123") // in the private use space -) - -type printer struct { - cfg Config - prev token.Pos - - comments []*ast.CommentGroup // may be nil, contains all comments - standaloneComments []*ast.CommentGroup // contains all standalone comments (not assigned to any node) - - enableTrace bool - indentTrace int -} - -type ByPosition []*ast.CommentGroup - -func (b ByPosition) Len() int { return len(b) } -func (b ByPosition) Swap(i, j int) { b[i], b[j] = b[j], b[i] } -func (b ByPosition) Less(i, j int) bool { return b[i].Pos().Before(b[j].Pos()) } - -// collectComments comments all standalone comments which are not lead or line -// comment -func (p *printer) collectComments(node ast.Node) { - // first collect all comments. This is already stored in - // ast.File.(comments) - ast.Walk(node, func(nn ast.Node) (ast.Node, bool) { - switch t := nn.(type) { - case *ast.File: - p.comments = t.Comments - return nn, false - } - return nn, true - }) - - standaloneComments := make(map[token.Pos]*ast.CommentGroup, 0) - for _, c := range p.comments { - standaloneComments[c.Pos()] = c - } - - // next remove all lead and line comments from the overall comment map. - // This will give us comments which are standalone, comments which are not - // assigned to any kind of node. - ast.Walk(node, func(nn ast.Node) (ast.Node, bool) { - switch t := nn.(type) { - case *ast.LiteralType: - if t.LeadComment != nil { - for _, comment := range t.LeadComment.List { - if _, ok := standaloneComments[comment.Pos()]; ok { - delete(standaloneComments, comment.Pos()) - } - } - } - - if t.LineComment != nil { - for _, comment := range t.LineComment.List { - if _, ok := standaloneComments[comment.Pos()]; ok { - delete(standaloneComments, comment.Pos()) - } - } - } - case *ast.ObjectItem: - if t.LeadComment != nil { - for _, comment := range t.LeadComment.List { - if _, ok := standaloneComments[comment.Pos()]; ok { - delete(standaloneComments, comment.Pos()) - } - } - } - - if t.LineComment != nil { - for _, comment := range t.LineComment.List { - if _, ok := standaloneComments[comment.Pos()]; ok { - delete(standaloneComments, comment.Pos()) - } - } - } - } - - return nn, true - }) - - for _, c := range standaloneComments { - p.standaloneComments = append(p.standaloneComments, c) - } - - sort.Sort(ByPosition(p.standaloneComments)) -} - -// output prints creates b printable HCL output and returns it. -func (p *printer) output(n interface{}) []byte { - var buf bytes.Buffer - - switch t := n.(type) { - case *ast.File: - // File doesn't trace so we add the tracing here - defer un(trace(p, "File")) - return p.output(t.Node) - case *ast.ObjectList: - defer un(trace(p, "ObjectList")) - - var index int - for { - // Determine the location of the next actual non-comment - // item. If we're at the end, the next item is at "infinity" - var nextItem token.Pos - if index != len(t.Items) { - nextItem = t.Items[index].Pos() - } else { - nextItem = token.Pos{Offset: infinity, Line: infinity} - } - - // Go through the standalone comments in the file and print out - // the comments that we should be for this object item. - for _, c := range p.standaloneComments { - // Go through all the comments in the group. The group - // should be printed together, not separated by double newlines. - printed := false - newlinePrinted := false - for _, comment := range c.List { - // We only care about comments after the previous item - // we've printed so that comments are printed in the - // correct locations (between two objects for example). - // And before the next item. - if comment.Pos().After(p.prev) && comment.Pos().Before(nextItem) { - // if we hit the end add newlines so we can print the comment - // we don't do this if prev is invalid which means the - // beginning of the file since the first comment should - // be at the first line. - if !newlinePrinted && p.prev.IsValid() && index == len(t.Items) { - buf.Write([]byte{newline, newline}) - newlinePrinted = true - } - - // Write the actual comment. - buf.WriteString(comment.Text) - buf.WriteByte(newline) - - // Set printed to true to note that we printed something - printed = true - } - } - - // If we're not at the last item, write a new line so - // that there is a newline separating this comment from - // the next object. - if printed && index != len(t.Items) { - buf.WriteByte(newline) - } - } - - if index == len(t.Items) { - break - } - - buf.Write(p.output(t.Items[index])) - if index != len(t.Items)-1 { - // Always write a newline to separate us from the next item - buf.WriteByte(newline) - - // Need to determine if we're going to separate the next item - // with a blank line. The logic here is simple, though there - // are a few conditions: - // - // 1. The next object is more than one line away anyways, - // so we need an empty line. - // - // 2. The next object is not a "single line" object, so - // we need an empty line. - // - // 3. This current object is not a single line object, - // so we need an empty line. - current := t.Items[index] - next := t.Items[index+1] - if next.Pos().Line != t.Items[index].Pos().Line+1 || - !p.isSingleLineObject(next) || - !p.isSingleLineObject(current) { - buf.WriteByte(newline) - } - } - index++ - } - case *ast.ObjectKey: - buf.WriteString(t.Token.Text) - case *ast.ObjectItem: - p.prev = t.Pos() - buf.Write(p.objectItem(t)) - case *ast.LiteralType: - buf.Write(p.literalType(t)) - case *ast.ListType: - buf.Write(p.list(t)) - case *ast.ObjectType: - buf.Write(p.objectType(t)) - default: - fmt.Printf(" unknown type: %T\n", n) - } - - return buf.Bytes() -} - -func (p *printer) literalType(lit *ast.LiteralType) []byte { - result := []byte(lit.Token.Text) - switch lit.Token.Type { - case token.HEREDOC: - // Clear the trailing newline from heredocs - if result[len(result)-1] == '\n' { - result = result[:len(result)-1] - } - - // Poison lines 2+ so that we don't indent them - result = p.heredocIndent(result) - case token.STRING: - // If this is a multiline string, poison lines 2+ so we don't - // indent them. - if bytes.IndexRune(result, '\n') >= 0 { - result = p.heredocIndent(result) - } - } - - return result -} - -// objectItem returns the printable HCL form of an object item. An object type -// starts with one/multiple keys and has a value. The value might be of any -// type. -func (p *printer) objectItem(o *ast.ObjectItem) []byte { - defer un(trace(p, fmt.Sprintf("ObjectItem: %s", o.Keys[0].Token.Text))) - var buf bytes.Buffer - - if o.LeadComment != nil { - for _, comment := range o.LeadComment.List { - buf.WriteString(comment.Text) - buf.WriteByte(newline) - } - } - - // If key and val are on different lines, treat line comments like lead comments. - if o.LineComment != nil && o.Val.Pos().Line != o.Keys[0].Pos().Line { - for _, comment := range o.LineComment.List { - buf.WriteString(comment.Text) - buf.WriteByte(newline) - } - } - - for i, k := range o.Keys { - buf.WriteString(k.Token.Text) - buf.WriteByte(blank) - - // reach end of key - if o.Assign.IsValid() && i == len(o.Keys)-1 && len(o.Keys) == 1 { - buf.WriteString("=") - buf.WriteByte(blank) - } - } - - buf.Write(p.output(o.Val)) - - if o.LineComment != nil && o.Val.Pos().Line == o.Keys[0].Pos().Line { - buf.WriteByte(blank) - for _, comment := range o.LineComment.List { - buf.WriteString(comment.Text) - } - } - - return buf.Bytes() -} - -// objectType returns the printable HCL form of an object type. An object type -// begins with a brace and ends with a brace. -func (p *printer) objectType(o *ast.ObjectType) []byte { - defer un(trace(p, "ObjectType")) - var buf bytes.Buffer - buf.WriteString("{") - - var index int - var nextItem token.Pos - var commented, newlinePrinted bool - for { - // Determine the location of the next actual non-comment - // item. If we're at the end, the next item is the closing brace - if index != len(o.List.Items) { - nextItem = o.List.Items[index].Pos() - } else { - nextItem = o.Rbrace - } - - // Go through the standalone comments in the file and print out - // the comments that we should be for this object item. - for _, c := range p.standaloneComments { - printed := false - var lastCommentPos token.Pos - for _, comment := range c.List { - // We only care about comments after the previous item - // we've printed so that comments are printed in the - // correct locations (between two objects for example). - // And before the next item. - if comment.Pos().After(p.prev) && comment.Pos().Before(nextItem) { - // If there are standalone comments and the initial newline has not - // been printed yet, do it now. - if !newlinePrinted { - newlinePrinted = true - buf.WriteByte(newline) - } - - // add newline if it's between other printed nodes - if index > 0 { - commented = true - buf.WriteByte(newline) - } - - // Store this position - lastCommentPos = comment.Pos() - - // output the comment itself - buf.Write(p.indent(p.heredocIndent([]byte(comment.Text)))) - - // Set printed to true to note that we printed something - printed = true - - /* - if index != len(o.List.Items) { - buf.WriteByte(newline) // do not print on the end - } - */ - } - } - - // Stuff to do if we had comments - if printed { - // Always write a newline - buf.WriteByte(newline) - - // If there is another item in the object and our comment - // didn't hug it directly, then make sure there is a blank - // line separating them. - if nextItem != o.Rbrace && nextItem.Line != lastCommentPos.Line+1 { - buf.WriteByte(newline) - } - } - } - - if index == len(o.List.Items) { - p.prev = o.Rbrace - break - } - - // At this point we are sure that it's not a totally empty block: print - // the initial newline if it hasn't been printed yet by the previous - // block about standalone comments. - if !newlinePrinted { - buf.WriteByte(newline) - newlinePrinted = true - } - - // check if we have adjacent one liner items. If yes we'll going to align - // the comments. - var aligned []*ast.ObjectItem - for _, item := range o.List.Items[index:] { - // we don't group one line lists - if len(o.List.Items) == 1 { - break - } - - // one means a oneliner with out any lead comment - // two means a oneliner with lead comment - // anything else might be something else - cur := lines(string(p.objectItem(item))) - if cur > 2 { - break - } - - curPos := item.Pos() - - nextPos := token.Pos{} - if index != len(o.List.Items)-1 { - nextPos = o.List.Items[index+1].Pos() - } - - prevPos := token.Pos{} - if index != 0 { - prevPos = o.List.Items[index-1].Pos() - } - - // fmt.Println("DEBUG ----------------") - // fmt.Printf("prev = %+v prevPos: %s\n", prev, prevPos) - // fmt.Printf("cur = %+v curPos: %s\n", cur, curPos) - // fmt.Printf("next = %+v nextPos: %s\n", next, nextPos) - - if curPos.Line+1 == nextPos.Line { - aligned = append(aligned, item) - index++ - continue - } - - if curPos.Line-1 == prevPos.Line { - aligned = append(aligned, item) - index++ - - // finish if we have a new line or comment next. This happens - // if the next item is not adjacent - if curPos.Line+1 != nextPos.Line { - break - } - continue - } - - break - } - - // put newlines if the items are between other non aligned items. - // newlines are also added if there is a standalone comment already, so - // check it too - if !commented && index != len(aligned) { - buf.WriteByte(newline) - } - - if len(aligned) >= 1 { - p.prev = aligned[len(aligned)-1].Pos() - - items := p.alignedItems(aligned) - buf.Write(p.indent(items)) - } else { - p.prev = o.List.Items[index].Pos() - - buf.Write(p.indent(p.objectItem(o.List.Items[index]))) - index++ - } - - buf.WriteByte(newline) - } - - buf.WriteString("}") - return buf.Bytes() -} - -func (p *printer) alignedItems(items []*ast.ObjectItem) []byte { - var buf bytes.Buffer - - // find the longest key and value length, needed for alignment - var longestKeyLen int // longest key length - var longestValLen int // longest value length - for _, item := range items { - key := len(item.Keys[0].Token.Text) - val := len(p.output(item.Val)) - - if key > longestKeyLen { - longestKeyLen = key - } - - if val > longestValLen { - longestValLen = val - } - } - - for i, item := range items { - if item.LeadComment != nil { - for _, comment := range item.LeadComment.List { - buf.WriteString(comment.Text) - buf.WriteByte(newline) - } - } - - for i, k := range item.Keys { - keyLen := len(k.Token.Text) - buf.WriteString(k.Token.Text) - for i := 0; i < longestKeyLen-keyLen+1; i++ { - buf.WriteByte(blank) - } - - // reach end of key - if i == len(item.Keys)-1 && len(item.Keys) == 1 { - buf.WriteString("=") - buf.WriteByte(blank) - } - } - - val := p.output(item.Val) - valLen := len(val) - buf.Write(val) - - if item.Val.Pos().Line == item.Keys[0].Pos().Line && item.LineComment != nil { - for i := 0; i < longestValLen-valLen+1; i++ { - buf.WriteByte(blank) - } - - for _, comment := range item.LineComment.List { - buf.WriteString(comment.Text) - } - } - - // do not print for the last item - if i != len(items)-1 { - buf.WriteByte(newline) - } - } - - return buf.Bytes() -} - -// list returns the printable HCL form of an list type. -func (p *printer) list(l *ast.ListType) []byte { - if p.isSingleLineList(l) { - return p.singleLineList(l) - } - - var buf bytes.Buffer - buf.WriteString("[") - buf.WriteByte(newline) - - var longestLine int - for _, item := range l.List { - // for now we assume that the list only contains literal types - if lit, ok := item.(*ast.LiteralType); ok { - lineLen := len(lit.Token.Text) - if lineLen > longestLine { - longestLine = lineLen - } - } - } - - haveEmptyLine := false - for i, item := range l.List { - // If we have a lead comment, then we want to write that first - leadComment := false - if lit, ok := item.(*ast.LiteralType); ok && lit.LeadComment != nil { - leadComment = true - - // Ensure an empty line before every element with a - // lead comment (except the first item in a list). - if !haveEmptyLine && i != 0 { - buf.WriteByte(newline) - } - - for _, comment := range lit.LeadComment.List { - buf.Write(p.indent([]byte(comment.Text))) - buf.WriteByte(newline) - } - } - - // also indent each line - val := p.output(item) - curLen := len(val) - buf.Write(p.indent(val)) - - // if this item is a heredoc, then we output the comma on - // the next line. This is the only case this happens. - comma := []byte{','} - if lit, ok := item.(*ast.LiteralType); ok && lit.Token.Type == token.HEREDOC { - buf.WriteByte(newline) - comma = p.indent(comma) - } - - buf.Write(comma) - - if lit, ok := item.(*ast.LiteralType); ok && lit.LineComment != nil { - // if the next item doesn't have any comments, do not align - buf.WriteByte(blank) // align one space - for i := 0; i < longestLine-curLen; i++ { - buf.WriteByte(blank) - } - - for _, comment := range lit.LineComment.List { - buf.WriteString(comment.Text) - } - } - - buf.WriteByte(newline) - - // Ensure an empty line after every element with a - // lead comment (except the first item in a list). - haveEmptyLine = leadComment && i != len(l.List)-1 - if haveEmptyLine { - buf.WriteByte(newline) - } - } - - buf.WriteString("]") - return buf.Bytes() -} - -// isSingleLineList returns true if: -// * they were previously formatted entirely on one line -// * they consist entirely of literals -// * there are either no heredoc strings or the list has exactly one element -// * there are no line comments -func (printer) isSingleLineList(l *ast.ListType) bool { - for _, item := range l.List { - if item.Pos().Line != l.Lbrack.Line { - return false - } - - lit, ok := item.(*ast.LiteralType) - if !ok { - return false - } - - if lit.Token.Type == token.HEREDOC && len(l.List) != 1 { - return false - } - - if lit.LineComment != nil { - return false - } - } - - return true -} - -// singleLineList prints a simple single line list. -// For a definition of "simple", see isSingleLineList above. -func (p *printer) singleLineList(l *ast.ListType) []byte { - buf := &bytes.Buffer{} - - buf.WriteString("[") - for i, item := range l.List { - if i != 0 { - buf.WriteString(", ") - } - - // Output the item itself - buf.Write(p.output(item)) - - // The heredoc marker needs to be at the end of line. - if lit, ok := item.(*ast.LiteralType); ok && lit.Token.Type == token.HEREDOC { - buf.WriteByte(newline) - } - } - - buf.WriteString("]") - return buf.Bytes() -} - -// indent indents the lines of the given buffer for each non-empty line -func (p *printer) indent(buf []byte) []byte { - var prefix []byte - if p.cfg.SpacesWidth != 0 { - for i := 0; i < p.cfg.SpacesWidth; i++ { - prefix = append(prefix, blank) - } - } else { - prefix = []byte{tab} - } - - var res []byte - bol := true - for _, c := range buf { - if bol && c != '\n' { - res = append(res, prefix...) - } - - res = append(res, c) - bol = c == '\n' - } - return res -} - -// unindent removes all the indentation from the tombstoned lines -func (p *printer) unindent(buf []byte) []byte { - var res []byte - for i := 0; i < len(buf); i++ { - skip := len(buf)-i <= len(unindent) - if !skip { - skip = !bytes.Equal(unindent, buf[i:i+len(unindent)]) - } - if skip { - res = append(res, buf[i]) - continue - } - - // We have a marker. we have to backtrace here and clean out - // any whitespace ahead of our tombstone up to a \n - for j := len(res) - 1; j >= 0; j-- { - if res[j] == '\n' { - break - } - - res = res[:j] - } - - // Skip the entire unindent marker - i += len(unindent) - 1 - } - - return res -} - -// heredocIndent marks all the 2nd and further lines as unindentable -func (p *printer) heredocIndent(buf []byte) []byte { - var res []byte - bol := false - for _, c := range buf { - if bol && c != '\n' { - res = append(res, unindent...) - } - res = append(res, c) - bol = c == '\n' - } - return res -} - -// isSingleLineObject tells whether the given object item is a single -// line object such as "obj {}". -// -// A single line object: -// -// * has no lead comments (hence multi-line) -// * has no assignment -// * has no values in the stanza (within {}) -// -func (p *printer) isSingleLineObject(val *ast.ObjectItem) bool { - // If there is a lead comment, can't be one line - if val.LeadComment != nil { - return false - } - - // If there is assignment, we always break by line - if val.Assign.IsValid() { - return false - } - - // If it isn't an object type, then its not a single line object - ot, ok := val.Val.(*ast.ObjectType) - if !ok { - return false - } - - // If the object has no items, it is single line! - return len(ot.List.Items) == 0 -} - -func lines(txt string) int { - endline := 1 - for i := 0; i < len(txt); i++ { - if txt[i] == '\n' { - endline++ - } - } - return endline -} - -// ---------------------------------------------------------------------------- -// Tracing support - -func (p *printer) printTrace(a ...interface{}) { - if !p.enableTrace { - return - } - - const dots = ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . " - const n = len(dots) - i := 2 * p.indentTrace - for i > n { - fmt.Print(dots) - i -= n - } - // i <= n - fmt.Print(dots[0:i]) - fmt.Println(a...) -} - -func trace(p *printer, msg string) *printer { - p.printTrace(msg, "(") - p.indentTrace++ - return p -} - -// Usage pattern: defer un(trace(p, "...")) -func un(p *printer) { - p.indentTrace-- - p.printTrace(")") -} diff --git a/vendor/github.com/hashicorp/hcl/hcl/printer/printer.go b/vendor/github.com/hashicorp/hcl/hcl/printer/printer.go deleted file mode 100644 index 6617ab8e7a..0000000000 --- a/vendor/github.com/hashicorp/hcl/hcl/printer/printer.go +++ /dev/null @@ -1,66 +0,0 @@ -// Package printer implements printing of AST nodes to HCL format. -package printer - -import ( - "bytes" - "io" - "text/tabwriter" - - "github.com/hashicorp/hcl/hcl/ast" - "github.com/hashicorp/hcl/hcl/parser" -) - -var DefaultConfig = Config{ - SpacesWidth: 2, -} - -// A Config node controls the output of Fprint. -type Config struct { - SpacesWidth int // if set, it will use spaces instead of tabs for alignment -} - -func (c *Config) Fprint(output io.Writer, node ast.Node) error { - p := &printer{ - cfg: *c, - comments: make([]*ast.CommentGroup, 0), - standaloneComments: make([]*ast.CommentGroup, 0), - // enableTrace: true, - } - - p.collectComments(node) - - if _, err := output.Write(p.unindent(p.output(node))); err != nil { - return err - } - - // flush tabwriter, if any - var err error - if tw, _ := output.(*tabwriter.Writer); tw != nil { - err = tw.Flush() - } - - return err -} - -// Fprint "pretty-prints" an HCL node to output -// It calls Config.Fprint with default settings. -func Fprint(output io.Writer, node ast.Node) error { - return DefaultConfig.Fprint(output, node) -} - -// Format formats src HCL and returns the result. -func Format(src []byte) ([]byte, error) { - node, err := parser.Parse(src) - if err != nil { - return nil, err - } - - var buf bytes.Buffer - if err := DefaultConfig.Fprint(&buf, node); err != nil { - return nil, err - } - - // Add trailing newline to result - buf.WriteString("\n") - return buf.Bytes(), nil -} diff --git a/vendor/github.com/hashicorp/hcl/hcl/scanner/scanner.go b/vendor/github.com/hashicorp/hcl/hcl/scanner/scanner.go deleted file mode 100644 index 624a18fe3a..0000000000 --- a/vendor/github.com/hashicorp/hcl/hcl/scanner/scanner.go +++ /dev/null @@ -1,652 +0,0 @@ -// Package scanner implements a scanner for HCL (HashiCorp Configuration -// Language) source text. -package scanner - -import ( - "bytes" - "fmt" - "os" - "regexp" - "unicode" - "unicode/utf8" - - "github.com/hashicorp/hcl/hcl/token" -) - -// eof represents a marker rune for the end of the reader. -const eof = rune(0) - -// Scanner defines a lexical scanner -type Scanner struct { - buf *bytes.Buffer // Source buffer for advancing and scanning - src []byte // Source buffer for immutable access - - // Source Position - srcPos token.Pos // current position - prevPos token.Pos // previous position, used for peek() method - - lastCharLen int // length of last character in bytes - lastLineLen int // length of last line in characters (for correct column reporting) - - tokStart int // token text start position - tokEnd int // token text end position - - // Error is called for each error encountered. If no Error - // function is set, the error is reported to os.Stderr. - Error func(pos token.Pos, msg string) - - // ErrorCount is incremented by one for each error encountered. - ErrorCount int - - // tokPos is the start position of most recently scanned token; set by - // Scan. The Filename field is always left untouched by the Scanner. If - // an error is reported (via Error) and Position is invalid, the scanner is - // not inside a token. - tokPos token.Pos -} - -// New creates and initializes a new instance of Scanner using src as -// its source content. -func New(src []byte) *Scanner { - // even though we accept a src, we read from a io.Reader compatible type - // (*bytes.Buffer). So in the future we might easily change it to streaming - // read. - b := bytes.NewBuffer(src) - s := &Scanner{ - buf: b, - src: src, - } - - // srcPosition always starts with 1 - s.srcPos.Line = 1 - return s -} - -// next reads the next rune from the bufferred reader. Returns the rune(0) if -// an error occurs (or io.EOF is returned). -func (s *Scanner) next() rune { - ch, size, err := s.buf.ReadRune() - if err != nil { - // advance for error reporting - s.srcPos.Column++ - s.srcPos.Offset += size - s.lastCharLen = size - return eof - } - - // remember last position - s.prevPos = s.srcPos - - s.srcPos.Column++ - s.lastCharLen = size - s.srcPos.Offset += size - - if ch == utf8.RuneError && size == 1 { - s.err("illegal UTF-8 encoding") - return ch - } - - if ch == '\n' { - s.srcPos.Line++ - s.lastLineLen = s.srcPos.Column - s.srcPos.Column = 0 - } - - if ch == '\x00' { - s.err("unexpected null character (0x00)") - return eof - } - - if ch == '\uE123' { - s.err("unicode code point U+E123 reserved for internal use") - return utf8.RuneError - } - - // debug - // fmt.Printf("ch: %q, offset:column: %d:%d\n", ch, s.srcPos.Offset, s.srcPos.Column) - return ch -} - -// unread unreads the previous read Rune and updates the source position -func (s *Scanner) unread() { - if err := s.buf.UnreadRune(); err != nil { - panic(err) // this is user fault, we should catch it - } - s.srcPos = s.prevPos // put back last position -} - -// peek returns the next rune without advancing the reader. -func (s *Scanner) peek() rune { - peek, _, err := s.buf.ReadRune() - if err != nil { - return eof - } - - s.buf.UnreadRune() - return peek -} - -// Scan scans the next token and returns the token. -func (s *Scanner) Scan() token.Token { - ch := s.next() - - // skip white space - for isWhitespace(ch) { - ch = s.next() - } - - var tok token.Type - - // token text markings - s.tokStart = s.srcPos.Offset - s.lastCharLen - - // token position, initial next() is moving the offset by one(size of rune - // actually), though we are interested with the starting point - s.tokPos.Offset = s.srcPos.Offset - s.lastCharLen - if s.srcPos.Column > 0 { - // common case: last character was not a '\n' - s.tokPos.Line = s.srcPos.Line - s.tokPos.Column = s.srcPos.Column - } else { - // last character was a '\n' - // (we cannot be at the beginning of the source - // since we have called next() at least once) - s.tokPos.Line = s.srcPos.Line - 1 - s.tokPos.Column = s.lastLineLen - } - - switch { - case isLetter(ch): - tok = token.IDENT - lit := s.scanIdentifier() - if lit == "true" || lit == "false" { - tok = token.BOOL - } - case isDecimal(ch): - tok = s.scanNumber(ch) - default: - switch ch { - case eof: - tok = token.EOF - case '"': - tok = token.STRING - s.scanString() - case '#', '/': - tok = token.COMMENT - s.scanComment(ch) - case '.': - tok = token.PERIOD - ch = s.peek() - if isDecimal(ch) { - tok = token.FLOAT - ch = s.scanMantissa(ch) - ch = s.scanExponent(ch) - } - case '<': - tok = token.HEREDOC - s.scanHeredoc() - case '[': - tok = token.LBRACK - case ']': - tok = token.RBRACK - case '{': - tok = token.LBRACE - case '}': - tok = token.RBRACE - case ',': - tok = token.COMMA - case '=': - tok = token.ASSIGN - case '+': - tok = token.ADD - case '-': - if isDecimal(s.peek()) { - ch := s.next() - tok = s.scanNumber(ch) - } else { - tok = token.SUB - } - default: - s.err("illegal char") - } - } - - // finish token ending - s.tokEnd = s.srcPos.Offset - - // create token literal - var tokenText string - if s.tokStart >= 0 { - tokenText = string(s.src[s.tokStart:s.tokEnd]) - } - s.tokStart = s.tokEnd // ensure idempotency of tokenText() call - - return token.Token{ - Type: tok, - Pos: s.tokPos, - Text: tokenText, - } -} - -func (s *Scanner) scanComment(ch rune) { - // single line comments - if ch == '#' || (ch == '/' && s.peek() != '*') { - if ch == '/' && s.peek() != '/' { - s.err("expected '/' for comment") - return - } - - ch = s.next() - for ch != '\n' && ch >= 0 && ch != eof { - ch = s.next() - } - if ch != eof && ch >= 0 { - s.unread() - } - return - } - - // be sure we get the character after /* This allows us to find comment's - // that are not erminated - if ch == '/' { - s.next() - ch = s.next() // read character after "/*" - } - - // look for /* - style comments - for { - if ch < 0 || ch == eof { - s.err("comment not terminated") - break - } - - ch0 := ch - ch = s.next() - if ch0 == '*' && ch == '/' { - break - } - } -} - -// scanNumber scans a HCL number definition starting with the given rune -func (s *Scanner) scanNumber(ch rune) token.Type { - if ch == '0' { - // check for hexadecimal, octal or float - ch = s.next() - if ch == 'x' || ch == 'X' { - // hexadecimal - ch = s.next() - found := false - for isHexadecimal(ch) { - ch = s.next() - found = true - } - - if !found { - s.err("illegal hexadecimal number") - } - - if ch != eof { - s.unread() - } - - return token.NUMBER - } - - // now it's either something like: 0421(octal) or 0.1231(float) - illegalOctal := false - for isDecimal(ch) { - ch = s.next() - if ch == '8' || ch == '9' { - // this is just a possibility. For example 0159 is illegal, but - // 0159.23 is valid. So we mark a possible illegal octal. If - // the next character is not a period, we'll print the error. - illegalOctal = true - } - } - - if ch == 'e' || ch == 'E' { - ch = s.scanExponent(ch) - return token.FLOAT - } - - if ch == '.' { - ch = s.scanFraction(ch) - - if ch == 'e' || ch == 'E' { - ch = s.next() - ch = s.scanExponent(ch) - } - return token.FLOAT - } - - if illegalOctal { - s.err("illegal octal number") - } - - if ch != eof { - s.unread() - } - return token.NUMBER - } - - s.scanMantissa(ch) - ch = s.next() // seek forward - if ch == 'e' || ch == 'E' { - ch = s.scanExponent(ch) - return token.FLOAT - } - - if ch == '.' { - ch = s.scanFraction(ch) - if ch == 'e' || ch == 'E' { - ch = s.next() - ch = s.scanExponent(ch) - } - return token.FLOAT - } - - if ch != eof { - s.unread() - } - return token.NUMBER -} - -// scanMantissa scans the mantissa beginning from the rune. It returns the next -// non decimal rune. It's used to determine wheter it's a fraction or exponent. -func (s *Scanner) scanMantissa(ch rune) rune { - scanned := false - for isDecimal(ch) { - ch = s.next() - scanned = true - } - - if scanned && ch != eof { - s.unread() - } - return ch -} - -// scanFraction scans the fraction after the '.' rune -func (s *Scanner) scanFraction(ch rune) rune { - if ch == '.' { - ch = s.peek() // we peek just to see if we can move forward - ch = s.scanMantissa(ch) - } - return ch -} - -// scanExponent scans the remaining parts of an exponent after the 'e' or 'E' -// rune. -func (s *Scanner) scanExponent(ch rune) rune { - if ch == 'e' || ch == 'E' { - ch = s.next() - if ch == '-' || ch == '+' { - ch = s.next() - } - ch = s.scanMantissa(ch) - } - return ch -} - -// scanHeredoc scans a heredoc string -func (s *Scanner) scanHeredoc() { - // Scan the second '<' in example: '<= len(identBytes) && identRegexp.Match(s.src[lineStart:s.srcPos.Offset-s.lastCharLen]) { - break - } - - // Not an anchor match, record the start of a new line - lineStart = s.srcPos.Offset - } - - if ch == eof { - s.err("heredoc not terminated") - return - } - } - - return -} - -// scanString scans a quoted string -func (s *Scanner) scanString() { - braces := 0 - for { - // '"' opening already consumed - // read character after quote - ch := s.next() - - if (ch == '\n' && braces == 0) || ch < 0 || ch == eof { - s.err("literal not terminated") - return - } - - if ch == '"' && braces == 0 { - break - } - - // If we're going into a ${} then we can ignore quotes for awhile - if braces == 0 && ch == '$' && s.peek() == '{' { - braces++ - s.next() - } else if braces > 0 && ch == '{' { - braces++ - } - if braces > 0 && ch == '}' { - braces-- - } - - if ch == '\\' { - s.scanEscape() - } - } - - return -} - -// scanEscape scans an escape sequence -func (s *Scanner) scanEscape() rune { - // http://en.cppreference.com/w/cpp/language/escape - ch := s.next() // read character after '/' - switch ch { - case 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', '"': - // nothing to do - case '0', '1', '2', '3', '4', '5', '6', '7': - // octal notation - ch = s.scanDigits(ch, 8, 3) - case 'x': - // hexademical notation - ch = s.scanDigits(s.next(), 16, 2) - case 'u': - // universal character name - ch = s.scanDigits(s.next(), 16, 4) - case 'U': - // universal character name - ch = s.scanDigits(s.next(), 16, 8) - default: - s.err("illegal char escape") - } - return ch -} - -// scanDigits scans a rune with the given base for n times. For example an -// octal notation \184 would yield in scanDigits(ch, 8, 3) -func (s *Scanner) scanDigits(ch rune, base, n int) rune { - start := n - for n > 0 && digitVal(ch) < base { - ch = s.next() - if ch == eof { - // If we see an EOF, we halt any more scanning of digits - // immediately. - break - } - - n-- - } - if n > 0 { - s.err("illegal char escape") - } - - if n != start && ch != eof { - // we scanned all digits, put the last non digit char back, - // only if we read anything at all - s.unread() - } - - return ch -} - -// scanIdentifier scans an identifier and returns the literal string -func (s *Scanner) scanIdentifier() string { - offs := s.srcPos.Offset - s.lastCharLen - ch := s.next() - for isLetter(ch) || isDigit(ch) || ch == '-' || ch == '.' { - ch = s.next() - } - - if ch != eof { - s.unread() // we got identifier, put back latest char - } - - return string(s.src[offs:s.srcPos.Offset]) -} - -// recentPosition returns the position of the character immediately after the -// character or token returned by the last call to Scan. -func (s *Scanner) recentPosition() (pos token.Pos) { - pos.Offset = s.srcPos.Offset - s.lastCharLen - switch { - case s.srcPos.Column > 0: - // common case: last character was not a '\n' - pos.Line = s.srcPos.Line - pos.Column = s.srcPos.Column - case s.lastLineLen > 0: - // last character was a '\n' - // (we cannot be at the beginning of the source - // since we have called next() at least once) - pos.Line = s.srcPos.Line - 1 - pos.Column = s.lastLineLen - default: - // at the beginning of the source - pos.Line = 1 - pos.Column = 1 - } - return -} - -// err prints the error of any scanning to s.Error function. If the function is -// not defined, by default it prints them to os.Stderr -func (s *Scanner) err(msg string) { - s.ErrorCount++ - pos := s.recentPosition() - - if s.Error != nil { - s.Error(pos, msg) - return - } - - fmt.Fprintf(os.Stderr, "%s: %s\n", pos, msg) -} - -// isHexadecimal returns true if the given rune is a letter -func isLetter(ch rune) bool { - return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_' || ch >= 0x80 && unicode.IsLetter(ch) -} - -// isDigit returns true if the given rune is a decimal digit -func isDigit(ch rune) bool { - return '0' <= ch && ch <= '9' || ch >= 0x80 && unicode.IsDigit(ch) -} - -// isDecimal returns true if the given rune is a decimal number -func isDecimal(ch rune) bool { - return '0' <= ch && ch <= '9' -} - -// isHexadecimal returns true if the given rune is an hexadecimal number -func isHexadecimal(ch rune) bool { - return '0' <= ch && ch <= '9' || 'a' <= ch && ch <= 'f' || 'A' <= ch && ch <= 'F' -} - -// isWhitespace returns true if the rune is a space, tab, newline or carriage return -func isWhitespace(ch rune) bool { - return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' -} - -// digitVal returns the integer value of a given octal,decimal or hexadecimal rune -func digitVal(ch rune) int { - switch { - case '0' <= ch && ch <= '9': - return int(ch - '0') - case 'a' <= ch && ch <= 'f': - return int(ch - 'a' + 10) - case 'A' <= ch && ch <= 'F': - return int(ch - 'A' + 10) - } - return 16 // larger than any legal digit val -} diff --git a/vendor/github.com/hashicorp/hcl/hcl/strconv/quote.go b/vendor/github.com/hashicorp/hcl/hcl/strconv/quote.go deleted file mode 100644 index 5f981eaa2f..0000000000 --- a/vendor/github.com/hashicorp/hcl/hcl/strconv/quote.go +++ /dev/null @@ -1,241 +0,0 @@ -package strconv - -import ( - "errors" - "unicode/utf8" -) - -// ErrSyntax indicates that a value does not have the right syntax for the target type. -var ErrSyntax = errors.New("invalid syntax") - -// Unquote interprets s as a single-quoted, double-quoted, -// or backquoted Go string literal, returning the string value -// that s quotes. (If s is single-quoted, it would be a Go -// character literal; Unquote returns the corresponding -// one-character string.) -func Unquote(s string) (t string, err error) { - n := len(s) - if n < 2 { - return "", ErrSyntax - } - quote := s[0] - if quote != s[n-1] { - return "", ErrSyntax - } - s = s[1 : n-1] - - if quote != '"' { - return "", ErrSyntax - } - if !contains(s, '$') && !contains(s, '{') && contains(s, '\n') { - return "", ErrSyntax - } - - // Is it trivial? Avoid allocation. - if !contains(s, '\\') && !contains(s, quote) && !contains(s, '$') { - switch quote { - case '"': - return s, nil - case '\'': - r, size := utf8.DecodeRuneInString(s) - if size == len(s) && (r != utf8.RuneError || size != 1) { - return s, nil - } - } - } - - var runeTmp [utf8.UTFMax]byte - buf := make([]byte, 0, 3*len(s)/2) // Try to avoid more allocations. - for len(s) > 0 { - // If we're starting a '${}' then let it through un-unquoted. - // Specifically: we don't unquote any characters within the `${}` - // section. - if s[0] == '$' && len(s) > 1 && s[1] == '{' { - buf = append(buf, '$', '{') - s = s[2:] - - // Continue reading until we find the closing brace, copying as-is - braces := 1 - for len(s) > 0 && braces > 0 { - r, size := utf8.DecodeRuneInString(s) - if r == utf8.RuneError { - return "", ErrSyntax - } - - s = s[size:] - - n := utf8.EncodeRune(runeTmp[:], r) - buf = append(buf, runeTmp[:n]...) - - switch r { - case '{': - braces++ - case '}': - braces-- - } - } - if braces != 0 { - return "", ErrSyntax - } - if len(s) == 0 { - // If there's no string left, we're done! - break - } else { - // If there's more left, we need to pop back up to the top of the loop - // in case there's another interpolation in this string. - continue - } - } - - if s[0] == '\n' { - return "", ErrSyntax - } - - c, multibyte, ss, err := unquoteChar(s, quote) - if err != nil { - return "", err - } - s = ss - if c < utf8.RuneSelf || !multibyte { - buf = append(buf, byte(c)) - } else { - n := utf8.EncodeRune(runeTmp[:], c) - buf = append(buf, runeTmp[:n]...) - } - if quote == '\'' && len(s) != 0 { - // single-quoted must be single character - return "", ErrSyntax - } - } - return string(buf), nil -} - -// contains reports whether the string contains the byte c. -func contains(s string, c byte) bool { - for i := 0; i < len(s); i++ { - if s[i] == c { - return true - } - } - return false -} - -func unhex(b byte) (v rune, ok bool) { - c := rune(b) - switch { - case '0' <= c && c <= '9': - return c - '0', true - case 'a' <= c && c <= 'f': - return c - 'a' + 10, true - case 'A' <= c && c <= 'F': - return c - 'A' + 10, true - } - return -} - -func unquoteChar(s string, quote byte) (value rune, multibyte bool, tail string, err error) { - // easy cases - switch c := s[0]; { - case c == quote && (quote == '\'' || quote == '"'): - err = ErrSyntax - return - case c >= utf8.RuneSelf: - r, size := utf8.DecodeRuneInString(s) - return r, true, s[size:], nil - case c != '\\': - return rune(s[0]), false, s[1:], nil - } - - // hard case: c is backslash - if len(s) <= 1 { - err = ErrSyntax - return - } - c := s[1] - s = s[2:] - - switch c { - case 'a': - value = '\a' - case 'b': - value = '\b' - case 'f': - value = '\f' - case 'n': - value = '\n' - case 'r': - value = '\r' - case 't': - value = '\t' - case 'v': - value = '\v' - case 'x', 'u', 'U': - n := 0 - switch c { - case 'x': - n = 2 - case 'u': - n = 4 - case 'U': - n = 8 - } - var v rune - if len(s) < n { - err = ErrSyntax - return - } - for j := 0; j < n; j++ { - x, ok := unhex(s[j]) - if !ok { - err = ErrSyntax - return - } - v = v<<4 | x - } - s = s[n:] - if c == 'x' { - // single-byte string, possibly not UTF-8 - value = v - break - } - if v > utf8.MaxRune { - err = ErrSyntax - return - } - value = v - multibyte = true - case '0', '1', '2', '3', '4', '5', '6', '7': - v := rune(c) - '0' - if len(s) < 2 { - err = ErrSyntax - return - } - for j := 0; j < 2; j++ { // one digit already; two more - x := rune(s[j]) - '0' - if x < 0 || x > 7 { - err = ErrSyntax - return - } - v = (v << 3) | x - } - s = s[2:] - if v > 255 { - err = ErrSyntax - return - } - value = v - case '\\': - value = '\\' - case '\'', '"': - if c != quote { - err = ErrSyntax - return - } - value = rune(c) - default: - err = ErrSyntax - return - } - tail = s - return -} diff --git a/vendor/github.com/hashicorp/hcl/hcl/token/position.go b/vendor/github.com/hashicorp/hcl/hcl/token/position.go deleted file mode 100644 index 59c1bb72d4..0000000000 --- a/vendor/github.com/hashicorp/hcl/hcl/token/position.go +++ /dev/null @@ -1,46 +0,0 @@ -package token - -import "fmt" - -// Pos describes an arbitrary source position -// including the file, line, and column location. -// A Position is valid if the line number is > 0. -type Pos struct { - Filename string // filename, if any - Offset int // offset, starting at 0 - Line int // line number, starting at 1 - Column int // column number, starting at 1 (character count) -} - -// IsValid returns true if the position is valid. -func (p *Pos) IsValid() bool { return p.Line > 0 } - -// String returns a string in one of several forms: -// -// file:line:column valid position with file name -// line:column valid position without file name -// file invalid position with file name -// - invalid position without file name -func (p Pos) String() string { - s := p.Filename - if p.IsValid() { - if s != "" { - s += ":" - } - s += fmt.Sprintf("%d:%d", p.Line, p.Column) - } - if s == "" { - s = "-" - } - return s -} - -// Before reports whether the position p is before u. -func (p Pos) Before(u Pos) bool { - return u.Offset > p.Offset || u.Line > p.Line -} - -// After reports whether the position p is after u. -func (p Pos) After(u Pos) bool { - return u.Offset < p.Offset || u.Line < p.Line -} diff --git a/vendor/github.com/hashicorp/hcl/hcl/token/token.go b/vendor/github.com/hashicorp/hcl/hcl/token/token.go deleted file mode 100644 index e37c0664ec..0000000000 --- a/vendor/github.com/hashicorp/hcl/hcl/token/token.go +++ /dev/null @@ -1,219 +0,0 @@ -// Package token defines constants representing the lexical tokens for HCL -// (HashiCorp Configuration Language) -package token - -import ( - "fmt" - "strconv" - "strings" - - hclstrconv "github.com/hashicorp/hcl/hcl/strconv" -) - -// Token defines a single HCL token which can be obtained via the Scanner -type Token struct { - Type Type - Pos Pos - Text string - JSON bool -} - -// Type is the set of lexical tokens of the HCL (HashiCorp Configuration Language) -type Type int - -const ( - // Special tokens - ILLEGAL Type = iota - EOF - COMMENT - - identifier_beg - IDENT // literals - literal_beg - NUMBER // 12345 - FLOAT // 123.45 - BOOL // true,false - STRING // "abc" - HEREDOC // < 0 { - // Pop the current item - n := len(frontier) - item := frontier[n-1] - frontier = frontier[:n-1] - - switch v := item.Val.(type) { - case *ast.ObjectType: - items, frontier = flattenObjectType(v, item, items, frontier) - case *ast.ListType: - items, frontier = flattenListType(v, item, items, frontier) - default: - items = append(items, item) - } - } - - // Reverse the list since the frontier model runs things backwards - for i := len(items)/2 - 1; i >= 0; i-- { - opp := len(items) - 1 - i - items[i], items[opp] = items[opp], items[i] - } - - // Done! Set the original items - list.Items = items - return n, true - }) -} - -func flattenListType( - ot *ast.ListType, - item *ast.ObjectItem, - items []*ast.ObjectItem, - frontier []*ast.ObjectItem) ([]*ast.ObjectItem, []*ast.ObjectItem) { - // If the list is empty, keep the original list - if len(ot.List) == 0 { - items = append(items, item) - return items, frontier - } - - // All the elements of this object must also be objects! - for _, subitem := range ot.List { - if _, ok := subitem.(*ast.ObjectType); !ok { - items = append(items, item) - return items, frontier - } - } - - // Great! We have a match go through all the items and flatten - for _, elem := range ot.List { - // Add it to the frontier so that we can recurse - frontier = append(frontier, &ast.ObjectItem{ - Keys: item.Keys, - Assign: item.Assign, - Val: elem, - LeadComment: item.LeadComment, - LineComment: item.LineComment, - }) - } - - return items, frontier -} - -func flattenObjectType( - ot *ast.ObjectType, - item *ast.ObjectItem, - items []*ast.ObjectItem, - frontier []*ast.ObjectItem) ([]*ast.ObjectItem, []*ast.ObjectItem) { - // If the list has no items we do not have to flatten anything - if ot.List.Items == nil { - items = append(items, item) - return items, frontier - } - - // All the elements of this object must also be objects! - for _, subitem := range ot.List.Items { - if _, ok := subitem.Val.(*ast.ObjectType); !ok { - items = append(items, item) - return items, frontier - } - } - - // Great! We have a match go through all the items and flatten - for _, subitem := range ot.List.Items { - // Copy the new key - keys := make([]*ast.ObjectKey, len(item.Keys)+len(subitem.Keys)) - copy(keys, item.Keys) - copy(keys[len(item.Keys):], subitem.Keys) - - // Add it to the frontier so that we can recurse - frontier = append(frontier, &ast.ObjectItem{ - Keys: keys, - Assign: item.Assign, - Val: subitem.Val, - LeadComment: item.LeadComment, - LineComment: item.LineComment, - }) - } - - return items, frontier -} diff --git a/vendor/github.com/hashicorp/hcl/json/parser/parser.go b/vendor/github.com/hashicorp/hcl/json/parser/parser.go deleted file mode 100644 index 125a5f0729..0000000000 --- a/vendor/github.com/hashicorp/hcl/json/parser/parser.go +++ /dev/null @@ -1,313 +0,0 @@ -package parser - -import ( - "errors" - "fmt" - - "github.com/hashicorp/hcl/hcl/ast" - hcltoken "github.com/hashicorp/hcl/hcl/token" - "github.com/hashicorp/hcl/json/scanner" - "github.com/hashicorp/hcl/json/token" -) - -type Parser struct { - sc *scanner.Scanner - - // Last read token - tok token.Token - commaPrev token.Token - - enableTrace bool - indent int - n int // buffer size (max = 1) -} - -func newParser(src []byte) *Parser { - return &Parser{ - sc: scanner.New(src), - } -} - -// Parse returns the fully parsed source and returns the abstract syntax tree. -func Parse(src []byte) (*ast.File, error) { - p := newParser(src) - return p.Parse() -} - -var errEofToken = errors.New("EOF token found") - -// Parse returns the fully parsed source and returns the abstract syntax tree. -func (p *Parser) Parse() (*ast.File, error) { - f := &ast.File{} - var err, scerr error - p.sc.Error = func(pos token.Pos, msg string) { - scerr = fmt.Errorf("%s: %s", pos, msg) - } - - // The root must be an object in JSON - object, err := p.object() - if scerr != nil { - return nil, scerr - } - if err != nil { - return nil, err - } - - // We make our final node an object list so it is more HCL compatible - f.Node = object.List - - // Flatten it, which finds patterns and turns them into more HCL-like - // AST trees. - flattenObjects(f.Node) - - return f, nil -} - -func (p *Parser) objectList() (*ast.ObjectList, error) { - defer un(trace(p, "ParseObjectList")) - node := &ast.ObjectList{} - - for { - n, err := p.objectItem() - if err == errEofToken { - break // we are finished - } - - // we don't return a nil node, because might want to use already - // collected items. - if err != nil { - return node, err - } - - node.Add(n) - - // Check for a followup comma. If it isn't a comma, then we're done - if tok := p.scan(); tok.Type != token.COMMA { - break - } - } - - return node, nil -} - -// objectItem parses a single object item -func (p *Parser) objectItem() (*ast.ObjectItem, error) { - defer un(trace(p, "ParseObjectItem")) - - keys, err := p.objectKey() - if err != nil { - return nil, err - } - - o := &ast.ObjectItem{ - Keys: keys, - } - - switch p.tok.Type { - case token.COLON: - pos := p.tok.Pos - o.Assign = hcltoken.Pos{ - Filename: pos.Filename, - Offset: pos.Offset, - Line: pos.Line, - Column: pos.Column, - } - - o.Val, err = p.objectValue() - if err != nil { - return nil, err - } - } - - return o, nil -} - -// objectKey parses an object key and returns a ObjectKey AST -func (p *Parser) objectKey() ([]*ast.ObjectKey, error) { - keyCount := 0 - keys := make([]*ast.ObjectKey, 0) - - for { - tok := p.scan() - switch tok.Type { - case token.EOF: - return nil, errEofToken - case token.STRING: - keyCount++ - keys = append(keys, &ast.ObjectKey{ - Token: p.tok.HCLToken(), - }) - case token.COLON: - // If we have a zero keycount it means that we never got - // an object key, i.e. `{ :`. This is a syntax error. - if keyCount == 0 { - return nil, fmt.Errorf("expected: STRING got: %s", p.tok.Type) - } - - // Done - return keys, nil - case token.ILLEGAL: - return nil, errors.New("illegal") - default: - return nil, fmt.Errorf("expected: STRING got: %s", p.tok.Type) - } - } -} - -// object parses any type of object, such as number, bool, string, object or -// list. -func (p *Parser) objectValue() (ast.Node, error) { - defer un(trace(p, "ParseObjectValue")) - tok := p.scan() - - switch tok.Type { - case token.NUMBER, token.FLOAT, token.BOOL, token.NULL, token.STRING: - return p.literalType() - case token.LBRACE: - return p.objectType() - case token.LBRACK: - return p.listType() - case token.EOF: - return nil, errEofToken - } - - return nil, fmt.Errorf("Expected object value, got unknown token: %+v", tok) -} - -// object parses any type of object, such as number, bool, string, object or -// list. -func (p *Parser) object() (*ast.ObjectType, error) { - defer un(trace(p, "ParseType")) - tok := p.scan() - - switch tok.Type { - case token.LBRACE: - return p.objectType() - case token.EOF: - return nil, errEofToken - } - - return nil, fmt.Errorf("Expected object, got unknown token: %+v", tok) -} - -// objectType parses an object type and returns a ObjectType AST -func (p *Parser) objectType() (*ast.ObjectType, error) { - defer un(trace(p, "ParseObjectType")) - - // we assume that the currently scanned token is a LBRACE - o := &ast.ObjectType{} - - l, err := p.objectList() - - // if we hit RBRACE, we are good to go (means we parsed all Items), if it's - // not a RBRACE, it's an syntax error and we just return it. - if err != nil && p.tok.Type != token.RBRACE { - return nil, err - } - - o.List = l - return o, nil -} - -// listType parses a list type and returns a ListType AST -func (p *Parser) listType() (*ast.ListType, error) { - defer un(trace(p, "ParseListType")) - - // we assume that the currently scanned token is a LBRACK - l := &ast.ListType{} - - for { - tok := p.scan() - switch tok.Type { - case token.NUMBER, token.FLOAT, token.STRING: - node, err := p.literalType() - if err != nil { - return nil, err - } - - l.Add(node) - case token.COMMA: - continue - case token.LBRACE: - node, err := p.objectType() - if err != nil { - return nil, err - } - - l.Add(node) - case token.BOOL: - // TODO(arslan) should we support? not supported by HCL yet - case token.LBRACK: - // TODO(arslan) should we support nested lists? Even though it's - // written in README of HCL, it's not a part of the grammar - // (not defined in parse.y) - case token.RBRACK: - // finished - return l, nil - default: - return nil, fmt.Errorf("unexpected token while parsing list: %s", tok.Type) - } - - } -} - -// literalType parses a literal type and returns a LiteralType AST -func (p *Parser) literalType() (*ast.LiteralType, error) { - defer un(trace(p, "ParseLiteral")) - - return &ast.LiteralType{ - Token: p.tok.HCLToken(), - }, nil -} - -// scan returns the next token from the underlying scanner. If a token has -// been unscanned then read that instead. -func (p *Parser) scan() token.Token { - // If we have a token on the buffer, then return it. - if p.n != 0 { - p.n = 0 - return p.tok - } - - p.tok = p.sc.Scan() - return p.tok -} - -// unscan pushes the previously read token back onto the buffer. -func (p *Parser) unscan() { - p.n = 1 -} - -// ---------------------------------------------------------------------------- -// Parsing support - -func (p *Parser) printTrace(a ...interface{}) { - if !p.enableTrace { - return - } - - const dots = ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . " - const n = len(dots) - fmt.Printf("%5d:%3d: ", p.tok.Pos.Line, p.tok.Pos.Column) - - i := 2 * p.indent - for i > n { - fmt.Print(dots) - i -= n - } - // i <= n - fmt.Print(dots[0:i]) - fmt.Println(a...) -} - -func trace(p *Parser, msg string) *Parser { - p.printTrace(msg, "(") - p.indent++ - return p -} - -// Usage pattern: defer un(trace(p, "...")) -func un(p *Parser) { - p.indent-- - p.printTrace(")") -} diff --git a/vendor/github.com/hashicorp/hcl/json/scanner/scanner.go b/vendor/github.com/hashicorp/hcl/json/scanner/scanner.go deleted file mode 100644 index fe3f0f0950..0000000000 --- a/vendor/github.com/hashicorp/hcl/json/scanner/scanner.go +++ /dev/null @@ -1,451 +0,0 @@ -package scanner - -import ( - "bytes" - "fmt" - "os" - "unicode" - "unicode/utf8" - - "github.com/hashicorp/hcl/json/token" -) - -// eof represents a marker rune for the end of the reader. -const eof = rune(0) - -// Scanner defines a lexical scanner -type Scanner struct { - buf *bytes.Buffer // Source buffer for advancing and scanning - src []byte // Source buffer for immutable access - - // Source Position - srcPos token.Pos // current position - prevPos token.Pos // previous position, used for peek() method - - lastCharLen int // length of last character in bytes - lastLineLen int // length of last line in characters (for correct column reporting) - - tokStart int // token text start position - tokEnd int // token text end position - - // Error is called for each error encountered. If no Error - // function is set, the error is reported to os.Stderr. - Error func(pos token.Pos, msg string) - - // ErrorCount is incremented by one for each error encountered. - ErrorCount int - - // tokPos is the start position of most recently scanned token; set by - // Scan. The Filename field is always left untouched by the Scanner. If - // an error is reported (via Error) and Position is invalid, the scanner is - // not inside a token. - tokPos token.Pos -} - -// New creates and initializes a new instance of Scanner using src as -// its source content. -func New(src []byte) *Scanner { - // even though we accept a src, we read from a io.Reader compatible type - // (*bytes.Buffer). So in the future we might easily change it to streaming - // read. - b := bytes.NewBuffer(src) - s := &Scanner{ - buf: b, - src: src, - } - - // srcPosition always starts with 1 - s.srcPos.Line = 1 - return s -} - -// next reads the next rune from the bufferred reader. Returns the rune(0) if -// an error occurs (or io.EOF is returned). -func (s *Scanner) next() rune { - ch, size, err := s.buf.ReadRune() - if err != nil { - // advance for error reporting - s.srcPos.Column++ - s.srcPos.Offset += size - s.lastCharLen = size - return eof - } - - if ch == utf8.RuneError && size == 1 { - s.srcPos.Column++ - s.srcPos.Offset += size - s.lastCharLen = size - s.err("illegal UTF-8 encoding") - return ch - } - - // remember last position - s.prevPos = s.srcPos - - s.srcPos.Column++ - s.lastCharLen = size - s.srcPos.Offset += size - - if ch == '\n' { - s.srcPos.Line++ - s.lastLineLen = s.srcPos.Column - s.srcPos.Column = 0 - } - - // debug - // fmt.Printf("ch: %q, offset:column: %d:%d\n", ch, s.srcPos.Offset, s.srcPos.Column) - return ch -} - -// unread unreads the previous read Rune and updates the source position -func (s *Scanner) unread() { - if err := s.buf.UnreadRune(); err != nil { - panic(err) // this is user fault, we should catch it - } - s.srcPos = s.prevPos // put back last position -} - -// peek returns the next rune without advancing the reader. -func (s *Scanner) peek() rune { - peek, _, err := s.buf.ReadRune() - if err != nil { - return eof - } - - s.buf.UnreadRune() - return peek -} - -// Scan scans the next token and returns the token. -func (s *Scanner) Scan() token.Token { - ch := s.next() - - // skip white space - for isWhitespace(ch) { - ch = s.next() - } - - var tok token.Type - - // token text markings - s.tokStart = s.srcPos.Offset - s.lastCharLen - - // token position, initial next() is moving the offset by one(size of rune - // actually), though we are interested with the starting point - s.tokPos.Offset = s.srcPos.Offset - s.lastCharLen - if s.srcPos.Column > 0 { - // common case: last character was not a '\n' - s.tokPos.Line = s.srcPos.Line - s.tokPos.Column = s.srcPos.Column - } else { - // last character was a '\n' - // (we cannot be at the beginning of the source - // since we have called next() at least once) - s.tokPos.Line = s.srcPos.Line - 1 - s.tokPos.Column = s.lastLineLen - } - - switch { - case isLetter(ch): - lit := s.scanIdentifier() - if lit == "true" || lit == "false" { - tok = token.BOOL - } else if lit == "null" { - tok = token.NULL - } else { - s.err("illegal char") - } - case isDecimal(ch): - tok = s.scanNumber(ch) - default: - switch ch { - case eof: - tok = token.EOF - case '"': - tok = token.STRING - s.scanString() - case '.': - tok = token.PERIOD - ch = s.peek() - if isDecimal(ch) { - tok = token.FLOAT - ch = s.scanMantissa(ch) - ch = s.scanExponent(ch) - } - case '[': - tok = token.LBRACK - case ']': - tok = token.RBRACK - case '{': - tok = token.LBRACE - case '}': - tok = token.RBRACE - case ',': - tok = token.COMMA - case ':': - tok = token.COLON - case '-': - if isDecimal(s.peek()) { - ch := s.next() - tok = s.scanNumber(ch) - } else { - s.err("illegal char") - } - default: - s.err("illegal char: " + string(ch)) - } - } - - // finish token ending - s.tokEnd = s.srcPos.Offset - - // create token literal - var tokenText string - if s.tokStart >= 0 { - tokenText = string(s.src[s.tokStart:s.tokEnd]) - } - s.tokStart = s.tokEnd // ensure idempotency of tokenText() call - - return token.Token{ - Type: tok, - Pos: s.tokPos, - Text: tokenText, - } -} - -// scanNumber scans a HCL number definition starting with the given rune -func (s *Scanner) scanNumber(ch rune) token.Type { - zero := ch == '0' - pos := s.srcPos - - s.scanMantissa(ch) - ch = s.next() // seek forward - if ch == 'e' || ch == 'E' { - ch = s.scanExponent(ch) - return token.FLOAT - } - - if ch == '.' { - ch = s.scanFraction(ch) - if ch == 'e' || ch == 'E' { - ch = s.next() - ch = s.scanExponent(ch) - } - return token.FLOAT - } - - if ch != eof { - s.unread() - } - - // If we have a larger number and this is zero, error - if zero && pos != s.srcPos { - s.err("numbers cannot start with 0") - } - - return token.NUMBER -} - -// scanMantissa scans the mantissa beginning from the rune. It returns the next -// non decimal rune. It's used to determine wheter it's a fraction or exponent. -func (s *Scanner) scanMantissa(ch rune) rune { - scanned := false - for isDecimal(ch) { - ch = s.next() - scanned = true - } - - if scanned && ch != eof { - s.unread() - } - return ch -} - -// scanFraction scans the fraction after the '.' rune -func (s *Scanner) scanFraction(ch rune) rune { - if ch == '.' { - ch = s.peek() // we peek just to see if we can move forward - ch = s.scanMantissa(ch) - } - return ch -} - -// scanExponent scans the remaining parts of an exponent after the 'e' or 'E' -// rune. -func (s *Scanner) scanExponent(ch rune) rune { - if ch == 'e' || ch == 'E' { - ch = s.next() - if ch == '-' || ch == '+' { - ch = s.next() - } - ch = s.scanMantissa(ch) - } - return ch -} - -// scanString scans a quoted string -func (s *Scanner) scanString() { - braces := 0 - for { - // '"' opening already consumed - // read character after quote - ch := s.next() - - if ch == '\n' || ch < 0 || ch == eof { - s.err("literal not terminated") - return - } - - if ch == '"' { - break - } - - // If we're going into a ${} then we can ignore quotes for awhile - if braces == 0 && ch == '$' && s.peek() == '{' { - braces++ - s.next() - } else if braces > 0 && ch == '{' { - braces++ - } - if braces > 0 && ch == '}' { - braces-- - } - - if ch == '\\' { - s.scanEscape() - } - } - - return -} - -// scanEscape scans an escape sequence -func (s *Scanner) scanEscape() rune { - // http://en.cppreference.com/w/cpp/language/escape - ch := s.next() // read character after '/' - switch ch { - case 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', '"': - // nothing to do - case '0', '1', '2', '3', '4', '5', '6', '7': - // octal notation - ch = s.scanDigits(ch, 8, 3) - case 'x': - // hexademical notation - ch = s.scanDigits(s.next(), 16, 2) - case 'u': - // universal character name - ch = s.scanDigits(s.next(), 16, 4) - case 'U': - // universal character name - ch = s.scanDigits(s.next(), 16, 8) - default: - s.err("illegal char escape") - } - return ch -} - -// scanDigits scans a rune with the given base for n times. For example an -// octal notation \184 would yield in scanDigits(ch, 8, 3) -func (s *Scanner) scanDigits(ch rune, base, n int) rune { - for n > 0 && digitVal(ch) < base { - ch = s.next() - n-- - } - if n > 0 { - s.err("illegal char escape") - } - - // we scanned all digits, put the last non digit char back - s.unread() - return ch -} - -// scanIdentifier scans an identifier and returns the literal string -func (s *Scanner) scanIdentifier() string { - offs := s.srcPos.Offset - s.lastCharLen - ch := s.next() - for isLetter(ch) || isDigit(ch) || ch == '-' { - ch = s.next() - } - - if ch != eof { - s.unread() // we got identifier, put back latest char - } - - return string(s.src[offs:s.srcPos.Offset]) -} - -// recentPosition returns the position of the character immediately after the -// character or token returned by the last call to Scan. -func (s *Scanner) recentPosition() (pos token.Pos) { - pos.Offset = s.srcPos.Offset - s.lastCharLen - switch { - case s.srcPos.Column > 0: - // common case: last character was not a '\n' - pos.Line = s.srcPos.Line - pos.Column = s.srcPos.Column - case s.lastLineLen > 0: - // last character was a '\n' - // (we cannot be at the beginning of the source - // since we have called next() at least once) - pos.Line = s.srcPos.Line - 1 - pos.Column = s.lastLineLen - default: - // at the beginning of the source - pos.Line = 1 - pos.Column = 1 - } - return -} - -// err prints the error of any scanning to s.Error function. If the function is -// not defined, by default it prints them to os.Stderr -func (s *Scanner) err(msg string) { - s.ErrorCount++ - pos := s.recentPosition() - - if s.Error != nil { - s.Error(pos, msg) - return - } - - fmt.Fprintf(os.Stderr, "%s: %s\n", pos, msg) -} - -// isHexadecimal returns true if the given rune is a letter -func isLetter(ch rune) bool { - return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_' || ch >= 0x80 && unicode.IsLetter(ch) -} - -// isHexadecimal returns true if the given rune is a decimal digit -func isDigit(ch rune) bool { - return '0' <= ch && ch <= '9' || ch >= 0x80 && unicode.IsDigit(ch) -} - -// isHexadecimal returns true if the given rune is a decimal number -func isDecimal(ch rune) bool { - return '0' <= ch && ch <= '9' -} - -// isHexadecimal returns true if the given rune is an hexadecimal number -func isHexadecimal(ch rune) bool { - return '0' <= ch && ch <= '9' || 'a' <= ch && ch <= 'f' || 'A' <= ch && ch <= 'F' -} - -// isWhitespace returns true if the rune is a space, tab, newline or carriage return -func isWhitespace(ch rune) bool { - return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' -} - -// digitVal returns the integer value of a given octal,decimal or hexadecimal rune -func digitVal(ch rune) int { - switch { - case '0' <= ch && ch <= '9': - return int(ch - '0') - case 'a' <= ch && ch <= 'f': - return int(ch - 'a' + 10) - case 'A' <= ch && ch <= 'F': - return int(ch - 'A' + 10) - } - return 16 // larger than any legal digit val -} diff --git a/vendor/github.com/hashicorp/hcl/json/token/position.go b/vendor/github.com/hashicorp/hcl/json/token/position.go deleted file mode 100644 index 59c1bb72d4..0000000000 --- a/vendor/github.com/hashicorp/hcl/json/token/position.go +++ /dev/null @@ -1,46 +0,0 @@ -package token - -import "fmt" - -// Pos describes an arbitrary source position -// including the file, line, and column location. -// A Position is valid if the line number is > 0. -type Pos struct { - Filename string // filename, if any - Offset int // offset, starting at 0 - Line int // line number, starting at 1 - Column int // column number, starting at 1 (character count) -} - -// IsValid returns true if the position is valid. -func (p *Pos) IsValid() bool { return p.Line > 0 } - -// String returns a string in one of several forms: -// -// file:line:column valid position with file name -// line:column valid position without file name -// file invalid position with file name -// - invalid position without file name -func (p Pos) String() string { - s := p.Filename - if p.IsValid() { - if s != "" { - s += ":" - } - s += fmt.Sprintf("%d:%d", p.Line, p.Column) - } - if s == "" { - s = "-" - } - return s -} - -// Before reports whether the position p is before u. -func (p Pos) Before(u Pos) bool { - return u.Offset > p.Offset || u.Line > p.Line -} - -// After reports whether the position p is after u. -func (p Pos) After(u Pos) bool { - return u.Offset < p.Offset || u.Line < p.Line -} diff --git a/vendor/github.com/hashicorp/hcl/json/token/token.go b/vendor/github.com/hashicorp/hcl/json/token/token.go deleted file mode 100644 index 95a0c3eee6..0000000000 --- a/vendor/github.com/hashicorp/hcl/json/token/token.go +++ /dev/null @@ -1,118 +0,0 @@ -package token - -import ( - "fmt" - "strconv" - - hcltoken "github.com/hashicorp/hcl/hcl/token" -) - -// Token defines a single HCL token which can be obtained via the Scanner -type Token struct { - Type Type - Pos Pos - Text string -} - -// Type is the set of lexical tokens of the HCL (HashiCorp Configuration Language) -type Type int - -const ( - // Special tokens - ILLEGAL Type = iota - EOF - - identifier_beg - literal_beg - NUMBER // 12345 - FLOAT // 123.45 - BOOL // true,false - STRING // "abc" - NULL // null - literal_end - identifier_end - - operator_beg - LBRACK // [ - LBRACE // { - COMMA // , - PERIOD // . - COLON // : - - RBRACK // ] - RBRACE // } - - operator_end -) - -var tokens = [...]string{ - ILLEGAL: "ILLEGAL", - - EOF: "EOF", - - NUMBER: "NUMBER", - FLOAT: "FLOAT", - BOOL: "BOOL", - STRING: "STRING", - NULL: "NULL", - - LBRACK: "LBRACK", - LBRACE: "LBRACE", - COMMA: "COMMA", - PERIOD: "PERIOD", - COLON: "COLON", - - RBRACK: "RBRACK", - RBRACE: "RBRACE", -} - -// String returns the string corresponding to the token tok. -func (t Type) String() string { - s := "" - if 0 <= t && t < Type(len(tokens)) { - s = tokens[t] - } - if s == "" { - s = "token(" + strconv.Itoa(int(t)) + ")" - } - return s -} - -// IsIdentifier returns true for tokens corresponding to identifiers and basic -// type literals; it returns false otherwise. -func (t Type) IsIdentifier() bool { return identifier_beg < t && t < identifier_end } - -// IsLiteral returns true for tokens corresponding to basic type literals; it -// returns false otherwise. -func (t Type) IsLiteral() bool { return literal_beg < t && t < literal_end } - -// IsOperator returns true for tokens corresponding to operators and -// delimiters; it returns false otherwise. -func (t Type) IsOperator() bool { return operator_beg < t && t < operator_end } - -// String returns the token's literal text. Note that this is only -// applicable for certain token types, such as token.IDENT, -// token.STRING, etc.. -func (t Token) String() string { - return fmt.Sprintf("%s %s %s", t.Pos.String(), t.Type.String(), t.Text) -} - -// HCLToken converts this token to an HCL token. -// -// The token type must be a literal type or this will panic. -func (t Token) HCLToken() hcltoken.Token { - switch t.Type { - case BOOL: - return hcltoken.Token{Type: hcltoken.BOOL, Text: t.Text} - case FLOAT: - return hcltoken.Token{Type: hcltoken.FLOAT, Text: t.Text} - case NULL: - return hcltoken.Token{Type: hcltoken.STRING, Text: ""} - case NUMBER: - return hcltoken.Token{Type: hcltoken.NUMBER, Text: t.Text} - case STRING: - return hcltoken.Token{Type: hcltoken.STRING, Text: t.Text, JSON: true} - default: - panic(fmt.Sprintf("unimplemented HCLToken for type: %s", t.Type)) - } -} diff --git a/vendor/github.com/hashicorp/hcl/lex.go b/vendor/github.com/hashicorp/hcl/lex.go deleted file mode 100644 index d9993c2928..0000000000 --- a/vendor/github.com/hashicorp/hcl/lex.go +++ /dev/null @@ -1,38 +0,0 @@ -package hcl - -import ( - "unicode" - "unicode/utf8" -) - -type lexModeValue byte - -const ( - lexModeUnknown lexModeValue = iota - lexModeHcl - lexModeJson -) - -// lexMode returns whether we're going to be parsing in JSON -// mode or HCL mode. -func lexMode(v []byte) lexModeValue { - var ( - r rune - w int - offset int - ) - - for { - r, w = utf8.DecodeRune(v[offset:]) - offset += w - if unicode.IsSpace(r) { - continue - } - if r == '{' { - return lexModeJson - } - break - } - - return lexModeHcl -} diff --git a/vendor/github.com/hashicorp/hcl/parse.go b/vendor/github.com/hashicorp/hcl/parse.go deleted file mode 100644 index 1fca53c4ce..0000000000 --- a/vendor/github.com/hashicorp/hcl/parse.go +++ /dev/null @@ -1,39 +0,0 @@ -package hcl - -import ( - "fmt" - - "github.com/hashicorp/hcl/hcl/ast" - hclParser "github.com/hashicorp/hcl/hcl/parser" - jsonParser "github.com/hashicorp/hcl/json/parser" -) - -// ParseBytes accepts as input byte slice and returns ast tree. -// -// Input can be either JSON or HCL -func ParseBytes(in []byte) (*ast.File, error) { - return parse(in) -} - -// ParseString accepts input as a string and returns ast tree. -func ParseString(input string) (*ast.File, error) { - return parse([]byte(input)) -} - -func parse(in []byte) (*ast.File, error) { - switch lexMode(in) { - case lexModeHcl: - return hclParser.Parse(in) - case lexModeJson: - return jsonParser.Parse(in) - } - - return nil, fmt.Errorf("unknown config format") -} - -// Parse parses the given input and returns the root object. -// -// The input format can be either HCL or JSON. -func Parse(input string) (*ast.File, error) { - return parse([]byte(input)) -} diff --git a/vendor/github.com/hashicorp/terraform-exec/internal/version/version.go b/vendor/github.com/hashicorp/terraform-exec/internal/version/version.go index 72f2e1f7be..d360cb7525 100644 --- a/vendor/github.com/hashicorp/terraform-exec/internal/version/version.go +++ b/vendor/github.com/hashicorp/terraform-exec/internal/version/version.go @@ -3,7 +3,7 @@ package version -const version = "0.23.1" +const version = "0.24.0" // ModuleVersion returns the current version of the github.com/hashicorp/terraform-exec Go module. // This is a function to allow for future possible enhancement using debug.BuildInfo. diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/cmd.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/cmd.go index cd5a7e28bb..47e0e68766 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/cmd.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/cmd.go @@ -12,12 +12,14 @@ import ( "fmt" "io" "io/ioutil" + "iter" "os" "os/exec" "runtime" "strings" "github.com/hashicorp/terraform-exec/internal/version" + tfjson "github.com/hashicorp/terraform-json" ) const ( @@ -216,6 +218,72 @@ func (tf *Terraform) runTerraformCmdJSON(ctx context.Context, cmd *exec.Cmd, v i return dec.Decode(v) } +func (tf *Terraform) runTerraformCmdJSONLog(ctx context.Context, cmd *exec.Cmd) iter.Seq[NextMessage] { + pr, pw := io.Pipe() + tf.SetStdout(pw) + + emitter := newLogMsgEmitter(pr) + + go func() { + err := tf.runTerraformCmd(ctx, cmd) + emitter.done <- errors.Join(err, pw.Close()) + }() + + return func(yield func(msg NextMessage) bool) { + for { + nextMsg := emitter.NextMessage() + ok := yield(nextMsg) + if !ok || nextMsg.Msg == nil { + return + } + } + } +} + +func newLogMsgEmitter(stdoutReader io.ReadCloser) *logMsgEmitter { + return &logMsgEmitter{ + scanner: bufio.NewScanner(stdoutReader), + stdoutReader: stdoutReader, + done: make(chan error, 1), + } +} + +type logMsgEmitter struct { + scanner *bufio.Scanner + stdoutReader io.Closer + done chan error +} + +type NextMessage struct { + Msg tfjson.LogMsg + Err error +} + +// NextMessage returns next decoded message, if any, along with any errors. +// Stdout reader is closed when the last message is received. +// +// Error returned can be related to decoding of the message, the Terraform command +// or closing of stdout reader. +// +// Any error coming from Terraform (such as wrong configuration syntax) is +// represented as LogMsg of Level [tfjson.Error]. +func (e *logMsgEmitter) NextMessage() NextMessage { + if e.scanner.Scan() { + msg, err := tfjson.UnmarshalLogMessage(e.scanner.Bytes()) + return NextMessage{ + Msg: msg, + Err: err, + } + } + + err := <-e.done + err = errors.Join(err, e.scanner.Err(), e.stdoutReader.Close()) + return NextMessage{ + Msg: nil, + Err: err, + } +} + // mergeUserAgent does some minor deduplication to ensure we aren't // just using the same append string over and over. func mergeUserAgent(uas ...string) string { diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/options.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/options.go index 339bf39ec9..0129bd5c69 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/options.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/options.go @@ -184,6 +184,14 @@ func FromModule(source string) *FromModuleOption { return &FromModuleOption{source} } +type GenerateConfigOutOption struct { + path string +} + +func GenerateConfigOut(path string) *GenerateConfigOutOption { + return &GenerateConfigOutOption{path} +} + type GetOption struct { get bool } diff --git a/vendor/github.com/hashicorp/terraform-exec/tfexec/version.go b/vendor/github.com/hashicorp/terraform-exec/tfexec/version.go index 87addd1ec5..40b9301ea2 100644 --- a/vendor/github.com/hashicorp/terraform-exec/tfexec/version.go +++ b/vendor/github.com/hashicorp/terraform-exec/tfexec/version.go @@ -34,6 +34,8 @@ var ( tf1_4_0 = version.Must(version.NewVersion("1.4.0")) tf1_6_0 = version.Must(version.NewVersion("1.6.0")) tf1_9_0 = version.Must(version.NewVersion("1.9.0")) + tf1_13_0 = version.Must(version.NewVersion("1.13.0")) + tf1_14_0 = version.Must(version.NewVersion("1.14.0")) ) // Version returns structured output from the terraform version command including both the Terraform CLI version diff --git a/vendor/github.com/hashicorp/terraform-json/logging_types.go b/vendor/github.com/hashicorp/terraform-json/logging_types.go index 3e712a0fdd..6f9008c4d1 100644 --- a/vendor/github.com/hashicorp/terraform-json/logging_types.go +++ b/vendor/github.com/hashicorp/terraform-json/logging_types.go @@ -3,6 +3,7 @@ package tfjson import ( + "bytes" "encoding/json" ) @@ -29,31 +30,36 @@ var allLogMessageTypes = []any{ } func unmarshalByType(t LogMessageType, b []byte) (LogMsg, error) { + d := json.NewDecoder(bytes.NewReader(b)) + + // decode numbers as json.Number to avoid losing precision + d.UseNumber() + switch t { // generic case MessageTypeVersion: v := VersionLogMessage{} - return v, json.Unmarshal(b, &v) + return v, d.Decode(&v) case MessageTypeLog: v := LogMessage{} - return v, json.Unmarshal(b, &v) + return v, d.Decode(&v) case MessageTypeDiagnostic: v := DiagnosticLogMessage{} - return v, json.Unmarshal(b, &v) + return v, d.Decode(&v) // query case MessageListStart: v := ListStartMessage{} - return v, json.Unmarshal(b, &v) + return v, d.Decode(&v) case MessageListResourceFound: v := ListResourceFoundMessage{} - return v, json.Unmarshal(b, &v) + return v, d.Decode(&v) case MessageListComplete: v := ListCompleteMessage{} - return v, json.Unmarshal(b, &v) + return v, d.Decode(&v) } v := UnknownLogMessage{} - return v, json.Unmarshal(b, &v) + return v, d.Decode(&v) } diff --git a/vendor/github.com/hexops/gotextdiff/LICENSE b/vendor/github.com/hexops/gotextdiff/LICENSE deleted file mode 100644 index 6a66aea5ea..0000000000 --- a/vendor/github.com/hexops/gotextdiff/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/hexops/gotextdiff/README.md b/vendor/github.com/hexops/gotextdiff/README.md deleted file mode 100644 index bfd49a0c97..0000000000 --- a/vendor/github.com/hexops/gotextdiff/README.md +++ /dev/null @@ -1,54 +0,0 @@ -# gotextdiff - unified text diffing in Go Hexops logo - -This is a copy of the Go text diffing packages that [the official Go language server gopls uses internally](https://github.com/golang/tools/tree/master/internal/lsp/diff) to generate unified diffs. - -If you've previously tried to generate unified text diffs in Go (like the ones you see in Git and on GitHub), you may have found [github.com/sergi/go-diff](https://github.com/sergi/go-diff) which is a Go port of Neil Fraser's google-diff-match-patch code - however it [does not support unified diffs](https://github.com/sergi/go-diff/issues/57). - -This is arguably one of the best (and most maintained) unified text diffing packages in Go as of at least 2020. - -(All credit goes to [the Go authors](http://tip.golang.org/AUTHORS), I am merely re-publishing their work so others can use it.) - -## Example usage - -Import the packages: - -```Go -import ( - "github.com/hexops/gotextdiff" - "github.com/hexops/gotextdiff/myers" -) -``` - -Assuming you want to diff `a.txt` and `b.txt`, whose contents are stored in `aString` and `bString` then: - -```Go -edits := myers.ComputeEdits(span.URIFromPath("a.txt"), aString, bString) -diff := fmt.Sprint(gotextdiff.ToUnified("a.txt", "b.txt", aString, edits)) -``` - -`diff` will be a string like: - -```diff ---- a.txt -+++ b.txt -@@ -1,13 +1,28 @@ --foo -+bar -``` - -## API compatability - -We will publish a new major version anytime the API changes in a backwards-incompatible way. Because the upstream is not being developed with this being a public package in mind, API breakages may occur more often than in other Go packages (but you can always continue using the old version thanks to Go modules.) - -## Alternatives - -- [github.com/andreyvit/diff](https://github.com/andreyvit/diff): Quick'n'easy string diffing functions for Golang based on github.com/sergi/go-diff. -- [github.com/kylelemons/godebug/diff](https://github.com/kylelemons/godebug/tree/master/diff): implements a linewise diff algorithm ([inactive](https://github.com/kylelemons/godebug/issues/22#issuecomment-524573477)). - -## Contributing - -We will only accept changes made [upstream](https://github.com/golang/tools/tree/master/internal/lsp/diff), please send any contributions to the upstream instead! Compared to the upstream, only import paths will be modified (to be non-`internal` so they are importable.) The only thing we add here is this README. - -## License - -See https://github.com/golang/tools/blob/master/LICENSE diff --git a/vendor/github.com/hexops/gotextdiff/diff.go b/vendor/github.com/hexops/gotextdiff/diff.go deleted file mode 100644 index 53e499bc0c..0000000000 --- a/vendor/github.com/hexops/gotextdiff/diff.go +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// package gotextdiff supports a pluggable diff algorithm. -package gotextdiff - -import ( - "sort" - "strings" - - "github.com/hexops/gotextdiff/span" -) - -// TextEdit represents a change to a section of a document. -// The text within the specified span should be replaced by the supplied new text. -type TextEdit struct { - Span span.Span - NewText string -} - -// ComputeEdits is the type for a function that produces a set of edits that -// convert from the before content to the after content. -type ComputeEdits func(uri span.URI, before, after string) []TextEdit - -// SortTextEdits attempts to order all edits by their starting points. -// The sort is stable so that edits with the same starting point will not -// be reordered. -func SortTextEdits(d []TextEdit) { - // Use a stable sort to maintain the order of edits inserted at the same position. - sort.SliceStable(d, func(i int, j int) bool { - return span.Compare(d[i].Span, d[j].Span) < 0 - }) -} - -// ApplyEdits applies the set of edits to the before and returns the resulting -// content. -// It may panic or produce garbage if the edits are not valid for the provided -// before content. -func ApplyEdits(before string, edits []TextEdit) string { - // Preconditions: - // - all of the edits apply to before - // - and all the spans for each TextEdit have the same URI - if len(edits) == 0 { - return before - } - _, edits, _ = prepareEdits(before, edits) - after := strings.Builder{} - last := 0 - for _, edit := range edits { - start := edit.Span.Start().Offset() - if start > last { - after.WriteString(before[last:start]) - last = start - } - after.WriteString(edit.NewText) - last = edit.Span.End().Offset() - } - if last < len(before) { - after.WriteString(before[last:]) - } - return after.String() -} - -// LineEdits takes a set of edits and expands and merges them as necessary -// to ensure that there are only full line edits left when it is done. -func LineEdits(before string, edits []TextEdit) []TextEdit { - if len(edits) == 0 { - return nil - } - c, edits, partial := prepareEdits(before, edits) - if partial { - edits = lineEdits(before, c, edits) - } - return edits -} - -// prepareEdits returns a sorted copy of the edits -func prepareEdits(before string, edits []TextEdit) (*span.TokenConverter, []TextEdit, bool) { - partial := false - c := span.NewContentConverter("", []byte(before)) - copied := make([]TextEdit, len(edits)) - for i, edit := range edits { - edit.Span, _ = edit.Span.WithAll(c) - copied[i] = edit - partial = partial || - edit.Span.Start().Offset() >= len(before) || - edit.Span.Start().Column() > 1 || edit.Span.End().Column() > 1 - } - SortTextEdits(copied) - return c, copied, partial -} - -// lineEdits rewrites the edits to always be full line edits -func lineEdits(before string, c *span.TokenConverter, edits []TextEdit) []TextEdit { - adjusted := make([]TextEdit, 0, len(edits)) - current := TextEdit{Span: span.Invalid} - for _, edit := range edits { - if current.Span.IsValid() && edit.Span.Start().Line() <= current.Span.End().Line() { - // overlaps with the current edit, need to combine - // first get the gap from the previous edit - gap := before[current.Span.End().Offset():edit.Span.Start().Offset()] - // now add the text of this edit - current.NewText += gap + edit.NewText - // and then adjust the end position - current.Span = span.New(current.Span.URI(), current.Span.Start(), edit.Span.End()) - } else { - // does not overlap, add previous run (if there is one) - adjusted = addEdit(before, adjusted, current) - // and then remember this edit as the start of the next run - current = edit - } - } - // add the current pending run if there is one - return addEdit(before, adjusted, current) -} - -func addEdit(before string, edits []TextEdit, edit TextEdit) []TextEdit { - if !edit.Span.IsValid() { - return edits - } - // if edit is partial, expand it to full line now - start := edit.Span.Start() - end := edit.Span.End() - if start.Column() > 1 { - // prepend the text and adjust to start of line - delta := start.Column() - 1 - start = span.NewPoint(start.Line(), 1, start.Offset()-delta) - edit.Span = span.New(edit.Span.URI(), start, end) - edit.NewText = before[start.Offset():start.Offset()+delta] + edit.NewText - } - if start.Offset() >= len(before) && start.Line() > 1 && before[len(before)-1] != '\n' { - // after end of file that does not end in eol, so join to last line of file - // to do this we need to know where the start of the last line was - eol := strings.LastIndex(before, "\n") - if eol < 0 { - // file is one non terminated line - eol = 0 - } - delta := len(before) - eol - start = span.NewPoint(start.Line()-1, 1, start.Offset()-delta) - edit.Span = span.New(edit.Span.URI(), start, end) - edit.NewText = before[start.Offset():start.Offset()+delta] + edit.NewText - } - if end.Column() > 1 { - remains := before[end.Offset():] - eol := strings.IndexRune(remains, '\n') - if eol < 0 { - eol = len(remains) - } else { - eol++ - } - end = span.NewPoint(end.Line()+1, 1, end.Offset()+eol) - edit.Span = span.New(edit.Span.URI(), start, end) - edit.NewText = edit.NewText + remains[:eol] - } - edits = append(edits, edit) - return edits -} diff --git a/vendor/github.com/hexops/gotextdiff/myers/diff.go b/vendor/github.com/hexops/gotextdiff/myers/diff.go deleted file mode 100644 index 5e3e923648..0000000000 --- a/vendor/github.com/hexops/gotextdiff/myers/diff.go +++ /dev/null @@ -1,205 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package myers implements the Myers diff algorithm. -package myers - -import ( - "strings" - - diff "github.com/hexops/gotextdiff" - "github.com/hexops/gotextdiff/span" -) - -// Sources: -// https://blog.jcoglan.com/2017/02/17/the-myers-diff-algorithm-part-3/ -// https://www.codeproject.com/Articles/42279/%2FArticles%2F42279%2FInvestigating-Myers-diff-algorithm-Part-1-of-2 - -func ComputeEdits(uri span.URI, before, after string) []diff.TextEdit { - ops := operations(splitLines(before), splitLines(after)) - edits := make([]diff.TextEdit, 0, len(ops)) - for _, op := range ops { - s := span.New(uri, span.NewPoint(op.I1+1, 1, 0), span.NewPoint(op.I2+1, 1, 0)) - switch op.Kind { - case diff.Delete: - // Delete: unformatted[i1:i2] is deleted. - edits = append(edits, diff.TextEdit{Span: s}) - case diff.Insert: - // Insert: formatted[j1:j2] is inserted at unformatted[i1:i1]. - if content := strings.Join(op.Content, ""); content != "" { - edits = append(edits, diff.TextEdit{Span: s, NewText: content}) - } - } - } - return edits -} - -type operation struct { - Kind diff.OpKind - Content []string // content from b - I1, I2 int // indices of the line in a - J1 int // indices of the line in b, J2 implied by len(Content) -} - -// operations returns the list of operations to convert a into b, consolidating -// operations for multiple lines and not including equal lines. -func operations(a, b []string) []*operation { - if len(a) == 0 && len(b) == 0 { - return nil - } - - trace, offset := shortestEditSequence(a, b) - snakes := backtrack(trace, len(a), len(b), offset) - - M, N := len(a), len(b) - - var i int - solution := make([]*operation, len(a)+len(b)) - - add := func(op *operation, i2, j2 int) { - if op == nil { - return - } - op.I2 = i2 - if op.Kind == diff.Insert { - op.Content = b[op.J1:j2] - } - solution[i] = op - i++ - } - x, y := 0, 0 - for _, snake := range snakes { - if len(snake) < 2 { - continue - } - var op *operation - // delete (horizontal) - for snake[0]-snake[1] > x-y { - if op == nil { - op = &operation{ - Kind: diff.Delete, - I1: x, - J1: y, - } - } - x++ - if x == M { - break - } - } - add(op, x, y) - op = nil - // insert (vertical) - for snake[0]-snake[1] < x-y { - if op == nil { - op = &operation{ - Kind: diff.Insert, - I1: x, - J1: y, - } - } - y++ - } - add(op, x, y) - op = nil - // equal (diagonal) - for x < snake[0] { - x++ - y++ - } - if x >= M && y >= N { - break - } - } - return solution[:i] -} - -// backtrack uses the trace for the edit sequence computation and returns the -// "snakes" that make up the solution. A "snake" is a single deletion or -// insertion followed by zero or diagonals. -func backtrack(trace [][]int, x, y, offset int) [][]int { - snakes := make([][]int, len(trace)) - d := len(trace) - 1 - for ; x > 0 && y > 0 && d > 0; d-- { - V := trace[d] - if len(V) == 0 { - continue - } - snakes[d] = []int{x, y} - - k := x - y - - var kPrev int - if k == -d || (k != d && V[k-1+offset] < V[k+1+offset]) { - kPrev = k + 1 - } else { - kPrev = k - 1 - } - - x = V[kPrev+offset] - y = x - kPrev - } - if x < 0 || y < 0 { - return snakes - } - snakes[d] = []int{x, y} - return snakes -} - -// shortestEditSequence returns the shortest edit sequence that converts a into b. -func shortestEditSequence(a, b []string) ([][]int, int) { - M, N := len(a), len(b) - V := make([]int, 2*(N+M)+1) - offset := N + M - trace := make([][]int, N+M+1) - - // Iterate through the maximum possible length of the SES (N+M). - for d := 0; d <= N+M; d++ { - copyV := make([]int, len(V)) - // k lines are represented by the equation y = x - k. We move in - // increments of 2 because end points for even d are on even k lines. - for k := -d; k <= d; k += 2 { - // At each point, we either go down or to the right. We go down if - // k == -d, and we go to the right if k == d. We also prioritize - // the maximum x value, because we prefer deletions to insertions. - var x int - if k == -d || (k != d && V[k-1+offset] < V[k+1+offset]) { - x = V[k+1+offset] // down - } else { - x = V[k-1+offset] + 1 // right - } - - y := x - k - - // Diagonal moves while we have equal contents. - for x < M && y < N && a[x] == b[y] { - x++ - y++ - } - - V[k+offset] = x - - // Return if we've exceeded the maximum values. - if x == M && y == N { - // Makes sure to save the state of the array before returning. - copy(copyV, V) - trace[d] = copyV - return trace, offset - } - } - - // Save the state of the array. - copy(copyV, V) - trace[d] = copyV - } - return nil, 0 -} - -func splitLines(text string) []string { - lines := strings.SplitAfter(text, "\n") - if lines[len(lines)-1] == "" { - lines = lines[:len(lines)-1] - } - return lines -} diff --git a/vendor/github.com/hexops/gotextdiff/span/parse.go b/vendor/github.com/hexops/gotextdiff/span/parse.go deleted file mode 100644 index aa17c84ec1..0000000000 --- a/vendor/github.com/hexops/gotextdiff/span/parse.go +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package span - -import ( - "strconv" - "strings" - "unicode/utf8" -) - -// Parse returns the location represented by the input. -// Only file paths are accepted, not URIs. -// The returned span will be normalized, and thus if printed may produce a -// different string. -func Parse(input string) Span { - // :0:0#0-0:0#0 - valid := input - var hold, offset int - hadCol := false - suf := rstripSuffix(input) - if suf.sep == "#" { - offset = suf.num - suf = rstripSuffix(suf.remains) - } - if suf.sep == ":" { - valid = suf.remains - hold = suf.num - hadCol = true - suf = rstripSuffix(suf.remains) - } - switch { - case suf.sep == ":": - return New(URIFromPath(suf.remains), NewPoint(suf.num, hold, offset), Point{}) - case suf.sep == "-": - // we have a span, fall out of the case to continue - default: - // separator not valid, rewind to either the : or the start - return New(URIFromPath(valid), NewPoint(hold, 0, offset), Point{}) - } - // only the span form can get here - // at this point we still don't know what the numbers we have mean - // if have not yet seen a : then we might have either a line or a column depending - // on whether start has a column or not - // we build an end point and will fix it later if needed - end := NewPoint(suf.num, hold, offset) - hold, offset = 0, 0 - suf = rstripSuffix(suf.remains) - if suf.sep == "#" { - offset = suf.num - suf = rstripSuffix(suf.remains) - } - if suf.sep != ":" { - // turns out we don't have a span after all, rewind - return New(URIFromPath(valid), end, Point{}) - } - valid = suf.remains - hold = suf.num - suf = rstripSuffix(suf.remains) - if suf.sep != ":" { - // line#offset only - return New(URIFromPath(valid), NewPoint(hold, 0, offset), end) - } - // we have a column, so if end only had one number, it is also the column - if !hadCol { - end = NewPoint(suf.num, end.v.Line, end.v.Offset) - } - return New(URIFromPath(suf.remains), NewPoint(suf.num, hold, offset), end) -} - -type suffix struct { - remains string - sep string - num int -} - -func rstripSuffix(input string) suffix { - if len(input) == 0 { - return suffix{"", "", -1} - } - remains := input - num := -1 - // first see if we have a number at the end - last := strings.LastIndexFunc(remains, func(r rune) bool { return r < '0' || r > '9' }) - if last >= 0 && last < len(remains)-1 { - number, err := strconv.ParseInt(remains[last+1:], 10, 64) - if err == nil { - num = int(number) - remains = remains[:last+1] - } - } - // now see if we have a trailing separator - r, w := utf8.DecodeLastRuneInString(remains) - if r != ':' && r != '#' && r == '#' { - return suffix{input, "", -1} - } - remains = remains[:len(remains)-w] - return suffix{remains, string(r), num} -} diff --git a/vendor/github.com/hexops/gotextdiff/span/span.go b/vendor/github.com/hexops/gotextdiff/span/span.go deleted file mode 100644 index 4d2ad09866..0000000000 --- a/vendor/github.com/hexops/gotextdiff/span/span.go +++ /dev/null @@ -1,285 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package span contains support for representing with positions and ranges in -// text files. -package span - -import ( - "encoding/json" - "fmt" - "path" -) - -// Span represents a source code range in standardized form. -type Span struct { - v span -} - -// Point represents a single point within a file. -// In general this should only be used as part of a Span, as on its own it -// does not carry enough information. -type Point struct { - v point -} - -type span struct { - URI URI `json:"uri"` - Start point `json:"start"` - End point `json:"end"` -} - -type point struct { - Line int `json:"line"` - Column int `json:"column"` - Offset int `json:"offset"` -} - -// Invalid is a span that reports false from IsValid -var Invalid = Span{v: span{Start: invalidPoint.v, End: invalidPoint.v}} - -var invalidPoint = Point{v: point{Line: 0, Column: 0, Offset: -1}} - -// Converter is the interface to an object that can convert between line:column -// and offset forms for a single file. -type Converter interface { - //ToPosition converts from an offset to a line:column pair. - ToPosition(offset int) (int, int, error) - //ToOffset converts from a line:column pair to an offset. - ToOffset(line, col int) (int, error) -} - -func New(uri URI, start Point, end Point) Span { - s := Span{v: span{URI: uri, Start: start.v, End: end.v}} - s.v.clean() - return s -} - -func NewPoint(line, col, offset int) Point { - p := Point{v: point{Line: line, Column: col, Offset: offset}} - p.v.clean() - return p -} - -func Compare(a, b Span) int { - if r := CompareURI(a.URI(), b.URI()); r != 0 { - return r - } - if r := comparePoint(a.v.Start, b.v.Start); r != 0 { - return r - } - return comparePoint(a.v.End, b.v.End) -} - -func ComparePoint(a, b Point) int { - return comparePoint(a.v, b.v) -} - -func comparePoint(a, b point) int { - if !a.hasPosition() { - if a.Offset < b.Offset { - return -1 - } - if a.Offset > b.Offset { - return 1 - } - return 0 - } - if a.Line < b.Line { - return -1 - } - if a.Line > b.Line { - return 1 - } - if a.Column < b.Column { - return -1 - } - if a.Column > b.Column { - return 1 - } - return 0 -} - -func (s Span) HasPosition() bool { return s.v.Start.hasPosition() } -func (s Span) HasOffset() bool { return s.v.Start.hasOffset() } -func (s Span) IsValid() bool { return s.v.Start.isValid() } -func (s Span) IsPoint() bool { return s.v.Start == s.v.End } -func (s Span) URI() URI { return s.v.URI } -func (s Span) Start() Point { return Point{s.v.Start} } -func (s Span) End() Point { return Point{s.v.End} } -func (s *Span) MarshalJSON() ([]byte, error) { return json.Marshal(&s.v) } -func (s *Span) UnmarshalJSON(b []byte) error { return json.Unmarshal(b, &s.v) } - -func (p Point) HasPosition() bool { return p.v.hasPosition() } -func (p Point) HasOffset() bool { return p.v.hasOffset() } -func (p Point) IsValid() bool { return p.v.isValid() } -func (p *Point) MarshalJSON() ([]byte, error) { return json.Marshal(&p.v) } -func (p *Point) UnmarshalJSON(b []byte) error { return json.Unmarshal(b, &p.v) } -func (p Point) Line() int { - if !p.v.hasPosition() { - panic(fmt.Errorf("position not set in %v", p.v)) - } - return p.v.Line -} -func (p Point) Column() int { - if !p.v.hasPosition() { - panic(fmt.Errorf("position not set in %v", p.v)) - } - return p.v.Column -} -func (p Point) Offset() int { - if !p.v.hasOffset() { - panic(fmt.Errorf("offset not set in %v", p.v)) - } - return p.v.Offset -} - -func (p point) hasPosition() bool { return p.Line > 0 } -func (p point) hasOffset() bool { return p.Offset >= 0 } -func (p point) isValid() bool { return p.hasPosition() || p.hasOffset() } -func (p point) isZero() bool { - return (p.Line == 1 && p.Column == 1) || (!p.hasPosition() && p.Offset == 0) -} - -func (s *span) clean() { - //this presumes the points are already clean - if !s.End.isValid() || (s.End == point{}) { - s.End = s.Start - } -} - -func (p *point) clean() { - if p.Line < 0 { - p.Line = 0 - } - if p.Column <= 0 { - if p.Line > 0 { - p.Column = 1 - } else { - p.Column = 0 - } - } - if p.Offset == 0 && (p.Line > 1 || p.Column > 1) { - p.Offset = -1 - } -} - -// Format implements fmt.Formatter to print the Location in a standard form. -// The format produced is one that can be read back in using Parse. -func (s Span) Format(f fmt.State, c rune) { - fullForm := f.Flag('+') - preferOffset := f.Flag('#') - // we should always have a uri, simplify if it is file format - //TODO: make sure the end of the uri is unambiguous - uri := string(s.v.URI) - if c == 'f' { - uri = path.Base(uri) - } else if !fullForm { - uri = s.v.URI.Filename() - } - fmt.Fprint(f, uri) - if !s.IsValid() || (!fullForm && s.v.Start.isZero() && s.v.End.isZero()) { - return - } - // see which bits of start to write - printOffset := s.HasOffset() && (fullForm || preferOffset || !s.HasPosition()) - printLine := s.HasPosition() && (fullForm || !printOffset) - printColumn := printLine && (fullForm || (s.v.Start.Column > 1 || s.v.End.Column > 1)) - fmt.Fprint(f, ":") - if printLine { - fmt.Fprintf(f, "%d", s.v.Start.Line) - } - if printColumn { - fmt.Fprintf(f, ":%d", s.v.Start.Column) - } - if printOffset { - fmt.Fprintf(f, "#%d", s.v.Start.Offset) - } - // start is written, do we need end? - if s.IsPoint() { - return - } - // we don't print the line if it did not change - printLine = fullForm || (printLine && s.v.End.Line > s.v.Start.Line) - fmt.Fprint(f, "-") - if printLine { - fmt.Fprintf(f, "%d", s.v.End.Line) - } - if printColumn { - if printLine { - fmt.Fprint(f, ":") - } - fmt.Fprintf(f, "%d", s.v.End.Column) - } - if printOffset { - fmt.Fprintf(f, "#%d", s.v.End.Offset) - } -} - -func (s Span) WithPosition(c Converter) (Span, error) { - if err := s.update(c, true, false); err != nil { - return Span{}, err - } - return s, nil -} - -func (s Span) WithOffset(c Converter) (Span, error) { - if err := s.update(c, false, true); err != nil { - return Span{}, err - } - return s, nil -} - -func (s Span) WithAll(c Converter) (Span, error) { - if err := s.update(c, true, true); err != nil { - return Span{}, err - } - return s, nil -} - -func (s *Span) update(c Converter, withPos, withOffset bool) error { - if !s.IsValid() { - return fmt.Errorf("cannot add information to an invalid span") - } - if withPos && !s.HasPosition() { - if err := s.v.Start.updatePosition(c); err != nil { - return err - } - if s.v.End.Offset == s.v.Start.Offset { - s.v.End = s.v.Start - } else if err := s.v.End.updatePosition(c); err != nil { - return err - } - } - if withOffset && (!s.HasOffset() || (s.v.End.hasPosition() && !s.v.End.hasOffset())) { - if err := s.v.Start.updateOffset(c); err != nil { - return err - } - if s.v.End.Line == s.v.Start.Line && s.v.End.Column == s.v.Start.Column { - s.v.End.Offset = s.v.Start.Offset - } else if err := s.v.End.updateOffset(c); err != nil { - return err - } - } - return nil -} - -func (p *point) updatePosition(c Converter) error { - line, col, err := c.ToPosition(p.Offset) - if err != nil { - return err - } - p.Line = line - p.Column = col - return nil -} - -func (p *point) updateOffset(c Converter) error { - offset, err := c.ToOffset(p.Line, p.Column) - if err != nil { - return err - } - p.Offset = offset - return nil -} diff --git a/vendor/github.com/hexops/gotextdiff/span/token.go b/vendor/github.com/hexops/gotextdiff/span/token.go deleted file mode 100644 index 6f8b9b570c..0000000000 --- a/vendor/github.com/hexops/gotextdiff/span/token.go +++ /dev/null @@ -1,194 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package span - -import ( - "fmt" - "go/token" -) - -// Range represents a source code range in token.Pos form. -// It also carries the FileSet that produced the positions, so that it is -// self contained. -type Range struct { - FileSet *token.FileSet - Start token.Pos - End token.Pos - Converter Converter -} - -type FileConverter struct { - file *token.File -} - -// TokenConverter is a Converter backed by a token file set and file. -// It uses the file set methods to work out the conversions, which -// makes it fast and does not require the file contents. -type TokenConverter struct { - FileConverter - fset *token.FileSet -} - -// NewRange creates a new Range from a FileSet and two positions. -// To represent a point pass a 0 as the end pos. -func NewRange(fset *token.FileSet, start, end token.Pos) Range { - return Range{ - FileSet: fset, - Start: start, - End: end, - } -} - -// NewTokenConverter returns an implementation of Converter backed by a -// token.File. -func NewTokenConverter(fset *token.FileSet, f *token.File) *TokenConverter { - return &TokenConverter{fset: fset, FileConverter: FileConverter{file: f}} -} - -// NewContentConverter returns an implementation of Converter for the -// given file content. -func NewContentConverter(filename string, content []byte) *TokenConverter { - fset := token.NewFileSet() - f := fset.AddFile(filename, -1, len(content)) - f.SetLinesForContent(content) - return NewTokenConverter(fset, f) -} - -// IsPoint returns true if the range represents a single point. -func (r Range) IsPoint() bool { - return r.Start == r.End -} - -// Span converts a Range to a Span that represents the Range. -// It will fill in all the members of the Span, calculating the line and column -// information. -func (r Range) Span() (Span, error) { - if !r.Start.IsValid() { - return Span{}, fmt.Errorf("start pos is not valid") - } - f := r.FileSet.File(r.Start) - if f == nil { - return Span{}, fmt.Errorf("file not found in FileSet") - } - return FileSpan(f, r.Converter, r.Start, r.End) -} - -// FileSpan returns a span within tok, using converter to translate between -// offsets and positions. -func FileSpan(tok *token.File, converter Converter, start, end token.Pos) (Span, error) { - var s Span - var err error - var startFilename string - startFilename, s.v.Start.Line, s.v.Start.Column, err = position(tok, start) - if err != nil { - return Span{}, err - } - s.v.URI = URIFromPath(startFilename) - if end.IsValid() { - var endFilename string - endFilename, s.v.End.Line, s.v.End.Column, err = position(tok, end) - if err != nil { - return Span{}, err - } - // In the presence of line directives, a single File can have sections from - // multiple file names. - if endFilename != startFilename { - return Span{}, fmt.Errorf("span begins in file %q but ends in %q", startFilename, endFilename) - } - } - s.v.Start.clean() - s.v.End.clean() - s.v.clean() - if converter != nil { - return s.WithOffset(converter) - } - if startFilename != tok.Name() { - return Span{}, fmt.Errorf("must supply Converter for file %q containing lines from %q", tok.Name(), startFilename) - } - return s.WithOffset(&FileConverter{tok}) -} - -func position(f *token.File, pos token.Pos) (string, int, int, error) { - off, err := offset(f, pos) - if err != nil { - return "", 0, 0, err - } - return positionFromOffset(f, off) -} - -func positionFromOffset(f *token.File, offset int) (string, int, int, error) { - if offset > f.Size() { - return "", 0, 0, fmt.Errorf("offset %v is past the end of the file %v", offset, f.Size()) - } - pos := f.Pos(offset) - p := f.Position(pos) - // TODO(golang/go#41029): Consider returning line, column instead of line+1, 1 if - // the file's last character is not a newline. - if offset == f.Size() { - return p.Filename, p.Line + 1, 1, nil - } - return p.Filename, p.Line, p.Column, nil -} - -// offset is a copy of the Offset function in go/token, but with the adjustment -// that it does not panic on invalid positions. -func offset(f *token.File, pos token.Pos) (int, error) { - if int(pos) < f.Base() || int(pos) > f.Base()+f.Size() { - return 0, fmt.Errorf("invalid pos") - } - return int(pos) - f.Base(), nil -} - -// Range converts a Span to a Range that represents the Span for the supplied -// File. -func (s Span) Range(converter *TokenConverter) (Range, error) { - s, err := s.WithOffset(converter) - if err != nil { - return Range{}, err - } - // go/token will panic if the offset is larger than the file's size, - // so check here to avoid panicking. - if s.Start().Offset() > converter.file.Size() { - return Range{}, fmt.Errorf("start offset %v is past the end of the file %v", s.Start(), converter.file.Size()) - } - if s.End().Offset() > converter.file.Size() { - return Range{}, fmt.Errorf("end offset %v is past the end of the file %v", s.End(), converter.file.Size()) - } - return Range{ - FileSet: converter.fset, - Start: converter.file.Pos(s.Start().Offset()), - End: converter.file.Pos(s.End().Offset()), - Converter: converter, - }, nil -} - -func (l *FileConverter) ToPosition(offset int) (int, int, error) { - _, line, col, err := positionFromOffset(l.file, offset) - return line, col, err -} - -func (l *FileConverter) ToOffset(line, col int) (int, error) { - if line < 0 { - return -1, fmt.Errorf("line is not valid") - } - lineMax := l.file.LineCount() + 1 - if line > lineMax { - return -1, fmt.Errorf("line is beyond end of file %v", lineMax) - } else if line == lineMax { - if col > 1 { - return -1, fmt.Errorf("column is beyond end of file") - } - // at the end of the file, allowing for a trailing eol - return l.file.Size(), nil - } - pos := lineStart(l.file, line) - if !pos.IsValid() { - return -1, fmt.Errorf("line is not in file") - } - // we assume that column is in bytes here, and that the first byte of a - // line is at column 1 - pos += token.Pos(col - 1) - return offset(l.file, pos) -} diff --git a/vendor/github.com/hexops/gotextdiff/span/token111.go b/vendor/github.com/hexops/gotextdiff/span/token111.go deleted file mode 100644 index bf7a5406b6..0000000000 --- a/vendor/github.com/hexops/gotextdiff/span/token111.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !go1.12 - -package span - -import ( - "go/token" -) - -// lineStart is the pre-Go 1.12 version of (*token.File).LineStart. For Go -// versions <= 1.11, we borrow logic from the analysisutil package. -// TODO(rstambler): Delete this file when we no longer support Go 1.11. -func lineStart(f *token.File, line int) token.Pos { - // Use binary search to find the start offset of this line. - - min := 0 // inclusive - max := f.Size() // exclusive - for { - offset := (min + max) / 2 - pos := f.Pos(offset) - posn := f.Position(pos) - if posn.Line == line { - return pos - (token.Pos(posn.Column) - 1) - } - - if min+1 >= max { - return token.NoPos - } - - if posn.Line < line { - min = offset - } else { - max = offset - } - } -} diff --git a/vendor/github.com/hexops/gotextdiff/span/token112.go b/vendor/github.com/hexops/gotextdiff/span/token112.go deleted file mode 100644 index 017aec9c13..0000000000 --- a/vendor/github.com/hexops/gotextdiff/span/token112.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build go1.12 - -package span - -import ( - "go/token" -) - -// TODO(rstambler): Delete this file when we no longer support Go 1.11. -func lineStart(f *token.File, line int) token.Pos { - return f.LineStart(line) -} diff --git a/vendor/github.com/hexops/gotextdiff/span/uri.go b/vendor/github.com/hexops/gotextdiff/span/uri.go deleted file mode 100644 index 2504921356..0000000000 --- a/vendor/github.com/hexops/gotextdiff/span/uri.go +++ /dev/null @@ -1,169 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package span - -import ( - "fmt" - "net/url" - "os" - "path" - "path/filepath" - "runtime" - "strings" - "unicode" -) - -const fileScheme = "file" - -// URI represents the full URI for a file. -type URI string - -func (uri URI) IsFile() bool { - return strings.HasPrefix(string(uri), "file://") -} - -// Filename returns the file path for the given URI. -// It is an error to call this on a URI that is not a valid filename. -func (uri URI) Filename() string { - filename, err := filename(uri) - if err != nil { - panic(err) - } - return filepath.FromSlash(filename) -} - -func filename(uri URI) (string, error) { - if uri == "" { - return "", nil - } - u, err := url.ParseRequestURI(string(uri)) - if err != nil { - return "", err - } - if u.Scheme != fileScheme { - return "", fmt.Errorf("only file URIs are supported, got %q from %q", u.Scheme, uri) - } - // If the URI is a Windows URI, we trim the leading "/" and lowercase - // the drive letter, which will never be case sensitive. - if isWindowsDriveURIPath(u.Path) { - u.Path = strings.ToUpper(string(u.Path[1])) + u.Path[2:] - } - return u.Path, nil -} - -func URIFromURI(s string) URI { - if !strings.HasPrefix(s, "file://") { - return URI(s) - } - - if !strings.HasPrefix(s, "file:///") { - // VS Code sends URLs with only two slashes, which are invalid. golang/go#39789. - s = "file:///" + s[len("file://"):] - } - // Even though the input is a URI, it may not be in canonical form. VS Code - // in particular over-escapes :, @, etc. Unescape and re-encode to canonicalize. - path, err := url.PathUnescape(s[len("file://"):]) - if err != nil { - panic(err) - } - - // File URIs from Windows may have lowercase drive letters. - // Since drive letters are guaranteed to be case insensitive, - // we change them to uppercase to remain consistent. - // For example, file:///c:/x/y/z becomes file:///C:/x/y/z. - if isWindowsDriveURIPath(path) { - path = path[:1] + strings.ToUpper(string(path[1])) + path[2:] - } - u := url.URL{Scheme: fileScheme, Path: path} - return URI(u.String()) -} - -func CompareURI(a, b URI) int { - if equalURI(a, b) { - return 0 - } - if a < b { - return -1 - } - return 1 -} - -func equalURI(a, b URI) bool { - if a == b { - return true - } - // If we have the same URI basename, we may still have the same file URIs. - if !strings.EqualFold(path.Base(string(a)), path.Base(string(b))) { - return false - } - fa, err := filename(a) - if err != nil { - return false - } - fb, err := filename(b) - if err != nil { - return false - } - // Stat the files to check if they are equal. - infoa, err := os.Stat(filepath.FromSlash(fa)) - if err != nil { - return false - } - infob, err := os.Stat(filepath.FromSlash(fb)) - if err != nil { - return false - } - return os.SameFile(infoa, infob) -} - -// URIFromPath returns a span URI for the supplied file path. -// It will always have the file scheme. -func URIFromPath(path string) URI { - if path == "" { - return "" - } - // Handle standard library paths that contain the literal "$GOROOT". - // TODO(rstambler): The go/packages API should allow one to determine a user's $GOROOT. - const prefix = "$GOROOT" - if len(path) >= len(prefix) && strings.EqualFold(prefix, path[:len(prefix)]) { - suffix := path[len(prefix):] - path = runtime.GOROOT() + suffix - } - if !isWindowsDrivePath(path) { - if abs, err := filepath.Abs(path); err == nil { - path = abs - } - } - // Check the file path again, in case it became absolute. - if isWindowsDrivePath(path) { - path = "/" + strings.ToUpper(string(path[0])) + path[1:] - } - path = filepath.ToSlash(path) - u := url.URL{ - Scheme: fileScheme, - Path: path, - } - return URI(u.String()) -} - -// isWindowsDrivePath returns true if the file path is of the form used by -// Windows. We check if the path begins with a drive letter, followed by a ":". -// For example: C:/x/y/z. -func isWindowsDrivePath(path string) bool { - if len(path) < 3 { - return false - } - return unicode.IsLetter(rune(path[0])) && path[1] == ':' -} - -// isWindowsDriveURI returns true if the file URI is of the format used by -// Windows URIs. The url.Parse package does not specially handle Windows paths -// (see golang/go#6027), so we check if the URI path has a drive prefix (e.g. "/C:"). -func isWindowsDriveURIPath(uri string) bool { - if len(uri) < 4 { - return false - } - return uri[0] == '/' && unicode.IsLetter(rune(uri[1])) && uri[2] == ':' -} diff --git a/vendor/github.com/hexops/gotextdiff/span/utf16.go b/vendor/github.com/hexops/gotextdiff/span/utf16.go deleted file mode 100644 index f06a2468b6..0000000000 --- a/vendor/github.com/hexops/gotextdiff/span/utf16.go +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package span - -import ( - "fmt" - "unicode/utf16" - "unicode/utf8" -) - -// ToUTF16Column calculates the utf16 column expressed by the point given the -// supplied file contents. -// This is used to convert from the native (always in bytes) column -// representation and the utf16 counts used by some editors. -func ToUTF16Column(p Point, content []byte) (int, error) { - if !p.HasPosition() { - return -1, fmt.Errorf("ToUTF16Column: point is missing position") - } - if !p.HasOffset() { - return -1, fmt.Errorf("ToUTF16Column: point is missing offset") - } - offset := p.Offset() // 0-based - colZero := p.Column() - 1 // 0-based - if colZero == 0 { - // 0-based column 0, so it must be chr 1 - return 1, nil - } else if colZero < 0 { - return -1, fmt.Errorf("ToUTF16Column: column is invalid (%v)", colZero) - } - // work out the offset at the start of the line using the column - lineOffset := offset - colZero - if lineOffset < 0 || offset > len(content) { - return -1, fmt.Errorf("ToUTF16Column: offsets %v-%v outside file contents (%v)", lineOffset, offset, len(content)) - } - // Use the offset to pick out the line start. - // This cannot panic: offset > len(content) and lineOffset < offset. - start := content[lineOffset:] - - // Now, truncate down to the supplied column. - start = start[:colZero] - - // and count the number of utf16 characters - // in theory we could do this by hand more efficiently... - return len(utf16.Encode([]rune(string(start)))) + 1, nil -} - -// FromUTF16Column advances the point by the utf16 character offset given the -// supplied line contents. -// This is used to convert from the utf16 counts used by some editors to the -// native (always in bytes) column representation. -func FromUTF16Column(p Point, chr int, content []byte) (Point, error) { - if !p.HasOffset() { - return Point{}, fmt.Errorf("FromUTF16Column: point is missing offset") - } - // if chr is 1 then no adjustment needed - if chr <= 1 { - return p, nil - } - if p.Offset() >= len(content) { - return p, fmt.Errorf("FromUTF16Column: offset (%v) greater than length of content (%v)", p.Offset(), len(content)) - } - remains := content[p.Offset():] - // scan forward the specified number of characters - for count := 1; count < chr; count++ { - if len(remains) <= 0 { - return Point{}, fmt.Errorf("FromUTF16Column: chr goes beyond the content") - } - r, w := utf8.DecodeRune(remains) - if r == '\n' { - // Per the LSP spec: - // - // > If the character value is greater than the line length it - // > defaults back to the line length. - break - } - remains = remains[w:] - if r >= 0x10000 { - // a two point rune - count++ - // if we finished in a two point rune, do not advance past the first - if count >= chr { - break - } - } - p.v.Column += w - p.v.Offset += w - } - return p, nil -} diff --git a/vendor/github.com/hexops/gotextdiff/unified.go b/vendor/github.com/hexops/gotextdiff/unified.go deleted file mode 100644 index b7d85cfccf..0000000000 --- a/vendor/github.com/hexops/gotextdiff/unified.go +++ /dev/null @@ -1,210 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package gotextdiff - -import ( - "fmt" - "strings" -) - -// Unified represents a set of edits as a unified diff. -type Unified struct { - // From is the name of the original file. - From string - // To is the name of the modified file. - To string - // Hunks is the set of edit hunks needed to transform the file content. - Hunks []*Hunk -} - -// Hunk represents a contiguous set of line edits to apply. -type Hunk struct { - // The line in the original source where the hunk starts. - FromLine int - // The line in the original source where the hunk finishes. - ToLine int - // The set of line based edits to apply. - Lines []Line -} - -// Line represents a single line operation to apply as part of a Hunk. -type Line struct { - // Kind is the type of line this represents, deletion, insertion or copy. - Kind OpKind - // Content is the content of this line. - // For deletion it is the line being removed, for all others it is the line - // to put in the output. - Content string -} - -// OpKind is used to denote the type of operation a line represents. -type OpKind int - -const ( - // Delete is the operation kind for a line that is present in the input - // but not in the output. - Delete OpKind = iota - // Insert is the operation kind for a line that is new in the output. - Insert - // Equal is the operation kind for a line that is the same in the input and - // output, often used to provide context around edited lines. - Equal -) - -// String returns a human readable representation of an OpKind. It is not -// intended for machine processing. -func (k OpKind) String() string { - switch k { - case Delete: - return "delete" - case Insert: - return "insert" - case Equal: - return "equal" - default: - panic("unknown operation kind") - } -} - -const ( - edge = 3 - gap = edge * 2 -) - -// ToUnified takes a file contents and a sequence of edits, and calculates -// a unified diff that represents those edits. -func ToUnified(from, to string, content string, edits []TextEdit) Unified { - u := Unified{ - From: from, - To: to, - } - if len(edits) == 0 { - return u - } - c, edits, partial := prepareEdits(content, edits) - if partial { - edits = lineEdits(content, c, edits) - } - lines := splitLines(content) - var h *Hunk - last := 0 - toLine := 0 - for _, edit := range edits { - start := edit.Span.Start().Line() - 1 - end := edit.Span.End().Line() - 1 - switch { - case h != nil && start == last: - //direct extension - case h != nil && start <= last+gap: - //within range of previous lines, add the joiners - addEqualLines(h, lines, last, start) - default: - //need to start a new hunk - if h != nil { - // add the edge to the previous hunk - addEqualLines(h, lines, last, last+edge) - u.Hunks = append(u.Hunks, h) - } - toLine += start - last - h = &Hunk{ - FromLine: start + 1, - ToLine: toLine + 1, - } - // add the edge to the new hunk - delta := addEqualLines(h, lines, start-edge, start) - h.FromLine -= delta - h.ToLine -= delta - } - last = start - for i := start; i < end; i++ { - h.Lines = append(h.Lines, Line{Kind: Delete, Content: lines[i]}) - last++ - } - if edit.NewText != "" { - for _, line := range splitLines(edit.NewText) { - h.Lines = append(h.Lines, Line{Kind: Insert, Content: line}) - toLine++ - } - } - } - if h != nil { - // add the edge to the final hunk - addEqualLines(h, lines, last, last+edge) - u.Hunks = append(u.Hunks, h) - } - return u -} - -func splitLines(text string) []string { - lines := strings.SplitAfter(text, "\n") - if lines[len(lines)-1] == "" { - lines = lines[:len(lines)-1] - } - return lines -} - -func addEqualLines(h *Hunk, lines []string, start, end int) int { - delta := 0 - for i := start; i < end; i++ { - if i < 0 { - continue - } - if i >= len(lines) { - return delta - } - h.Lines = append(h.Lines, Line{Kind: Equal, Content: lines[i]}) - delta++ - } - return delta -} - -// Format converts a unified diff to the standard textual form for that diff. -// The output of this function can be passed to tools like patch. -func (u Unified) Format(f fmt.State, r rune) { - if len(u.Hunks) == 0 { - return - } - fmt.Fprintf(f, "--- %s\n", u.From) - fmt.Fprintf(f, "+++ %s\n", u.To) - for _, hunk := range u.Hunks { - fromCount, toCount := 0, 0 - for _, l := range hunk.Lines { - switch l.Kind { - case Delete: - fromCount++ - case Insert: - toCount++ - default: - fromCount++ - toCount++ - } - } - fmt.Fprint(f, "@@") - if fromCount > 1 { - fmt.Fprintf(f, " -%d,%d", hunk.FromLine, fromCount) - } else { - fmt.Fprintf(f, " -%d", hunk.FromLine) - } - if toCount > 1 { - fmt.Fprintf(f, " +%d,%d", hunk.ToLine, toCount) - } else { - fmt.Fprintf(f, " +%d", hunk.ToLine) - } - fmt.Fprint(f, " @@\n") - for _, l := range hunk.Lines { - switch l.Kind { - case Delete: - fmt.Fprintf(f, "-%s", l.Content) - case Insert: - fmt.Fprintf(f, "+%s", l.Content) - default: - fmt.Fprintf(f, " %s", l.Content) - } - if !strings.HasSuffix(l.Content, "\n") { - fmt.Fprintf(f, "\n\\ No newline at end of file\n") - } - } - } -} diff --git a/vendor/github.com/inconshreveable/mousetrap/LICENSE b/vendor/github.com/inconshreveable/mousetrap/LICENSE deleted file mode 100644 index 5f920e9732..0000000000 --- a/vendor/github.com/inconshreveable/mousetrap/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2022 Alan Shreve (@inconshreveable) - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/inconshreveable/mousetrap/README.md b/vendor/github.com/inconshreveable/mousetrap/README.md deleted file mode 100644 index 7a950d1774..0000000000 --- a/vendor/github.com/inconshreveable/mousetrap/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# mousetrap - -mousetrap is a tiny library that answers a single question. - -On a Windows machine, was the process invoked by someone double clicking on -the executable file while browsing in explorer? - -### Motivation - -Windows developers unfamiliar with command line tools will often "double-click" -the executable for a tool. Because most CLI tools print the help and then exit -when invoked without arguments, this is often very frustrating for those users. - -mousetrap provides a way to detect these invocations so that you can provide -more helpful behavior and instructions on how to run the CLI tool. To see what -this looks like, both from an organizational and a technical perspective, see -https://inconshreveable.com/09-09-2014/sweat-the-small-stuff/ - -### The interface - -The library exposes a single interface: - - func StartedByExplorer() (bool) diff --git a/vendor/github.com/inconshreveable/mousetrap/trap_others.go b/vendor/github.com/inconshreveable/mousetrap/trap_others.go deleted file mode 100644 index 06a91f0868..0000000000 --- a/vendor/github.com/inconshreveable/mousetrap/trap_others.go +++ /dev/null @@ -1,16 +0,0 @@ -//go:build !windows -// +build !windows - -package mousetrap - -// StartedByExplorer returns true if the program was invoked by the user -// double-clicking on the executable from explorer.exe -// -// It is conservative and returns false if any of the internal calls fail. -// It does not guarantee that the program was run from a terminal. It only can tell you -// whether it was launched from explorer.exe -// -// On non-Windows platforms, it always returns false. -func StartedByExplorer() bool { - return false -} diff --git a/vendor/github.com/inconshreveable/mousetrap/trap_windows.go b/vendor/github.com/inconshreveable/mousetrap/trap_windows.go deleted file mode 100644 index 0c56880216..0000000000 --- a/vendor/github.com/inconshreveable/mousetrap/trap_windows.go +++ /dev/null @@ -1,42 +0,0 @@ -package mousetrap - -import ( - "syscall" - "unsafe" -) - -func getProcessEntry(pid int) (*syscall.ProcessEntry32, error) { - snapshot, err := syscall.CreateToolhelp32Snapshot(syscall.TH32CS_SNAPPROCESS, 0) - if err != nil { - return nil, err - } - defer syscall.CloseHandle(snapshot) - var procEntry syscall.ProcessEntry32 - procEntry.Size = uint32(unsafe.Sizeof(procEntry)) - if err = syscall.Process32First(snapshot, &procEntry); err != nil { - return nil, err - } - for { - if procEntry.ProcessID == uint32(pid) { - return &procEntry, nil - } - err = syscall.Process32Next(snapshot, &procEntry) - if err != nil { - return nil, err - } - } -} - -// StartedByExplorer returns true if the program was invoked by the user double-clicking -// on the executable from explorer.exe -// -// It is conservative and returns false if any of the internal calls fail. -// It does not guarantee that the program was run from a terminal. It only can tell you -// whether it was launched from explorer.exe -func StartedByExplorer() bool { - pe, err := getProcessEntry(syscall.Getppid()) - if err != nil { - return false - } - return "explorer.exe" == syscall.UTF16ToString(pe.ExeFile[:]) -} diff --git a/vendor/github.com/jgautheron/goconst/.gitignore b/vendor/github.com/jgautheron/goconst/.gitignore deleted file mode 100644 index 38dc761f15..0000000000 --- a/vendor/github.com/jgautheron/goconst/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/goconst diff --git a/vendor/github.com/jgautheron/goconst/LICENSE b/vendor/github.com/jgautheron/goconst/LICENSE deleted file mode 100644 index e926495431..0000000000 --- a/vendor/github.com/jgautheron/goconst/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015 Jonathan Gautheron - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/jgautheron/goconst/README.md b/vendor/github.com/jgautheron/goconst/README.md deleted file mode 100644 index 727974d001..0000000000 --- a/vendor/github.com/jgautheron/goconst/README.md +++ /dev/null @@ -1,89 +0,0 @@ -# goconst - -Find repeated strings that could be replaced by a constant. - -### Motivation - -There are obvious benefits to using constants instead of repeating strings, mostly to ease maintenance. Cannot argue against changing a single constant versus many strings. - -While this could be considered a beginner mistake, across time, multiple packages and large codebases, some repetition could have slipped in. - -### Get Started - - $ go install github.com/jgautheron/goconst/cmd/goconst@latest - $ goconst ./... - -### Usage - -``` -Usage: - - goconst ARGS [...] - -Flags: - - -ignore exclude files matching the given regular expression - -ignore-strings exclude strings matching the given regular expression - -ignore-tests exclude tests from the search (default: true) - -min-occurrences report from how many occurrences (default: 2) - -min-length only report strings with the minimum given length (default: 3) - -match-constant look for existing constants matching the strings - -find-duplicates look for constants with identical values - -eval-const-expr enable evaluation of constant expressions (e.g., Prefix + "suffix") - -numbers search also for duplicated numbers - -min minimum value, only works with -numbers - -max maximum value, only works with -numbers - -output output formatting (text or json) - -set-exit-status Set exit status to 2 if any issues are found - -grouped print single line per match, only works with -output text - -Examples: - - goconst ./... - goconst -ignore "yacc|\.pb\." $GOPATH/src/github.com/cockroachdb/cockroach/... - goconst -min-occurrences 3 -output json $GOPATH/src/github.com/cockroachdb/cockroach - goconst -numbers -min 60 -max 512 . - goconst -min-occurrences 5 $(go list -m -f '{{.Dir}}') - goconst -eval-const-expr -match-constant . # Matches constant expressions like Prefix + "suffix" -``` - -### Development - -#### Running Tests - -The project includes a comprehensive test suite. To run the tests: - -```bash -# Run all tests -go test ./... - -# Run tests with verbose output -go test -v ./... - -# Run tests with race detector -go test -race ./... - -# Run benchmarks -go test -bench=. ./... - -# Check test coverage -go test -cover ./... -``` - -#### Contributing - -Contributions are welcome! Before submitting a PR: - -1. Make sure all tests pass -2. Add tests for new functionality -3. Ensure your code passes linting checks -4. Update documentation as needed - -### Other static analysis tools - -- [gogetimports](https://github.com/jgautheron/gogetimports): Get a JSON-formatted list of imports. -- [usedexports](https://github.com/jgautheron/usedexports): Find exported variables that could be unexported. - -### License - -MIT diff --git a/vendor/github.com/jgautheron/goconst/api.go b/vendor/github.com/jgautheron/goconst/api.go deleted file mode 100644 index 10cece1515..0000000000 --- a/vendor/github.com/jgautheron/goconst/api.go +++ /dev/null @@ -1,255 +0,0 @@ -package goconst - -import ( - "go/ast" - "go/token" - "go/types" - "sort" - "strings" - "sync" -) - -// Issue represents a finding of duplicated strings, numbers, or constants. -// Each Issue includes the position where it was found, how many times it occurs, -// the string itself, and any matching constant name. -type Issue struct { - Pos token.Position - OccurrencesCount int - Str string - MatchingConst string - DuplicateConst string - DuplicatePos token.Position -} - -// Config contains all configuration options for the goconst analyzer. -type Config struct { - // IgnoreStrings is a list of regular expressions to filter strings - IgnoreStrings []string - // IgnoreTests indicates whether test files should be excluded - IgnoreTests bool - // MatchWithConstants enables matching strings with existing constants - MatchWithConstants bool - // MinStringLength is the minimum length a string must have to be reported - MinStringLength int - // MinOccurrences is the minimum number of occurrences required to report a string - MinOccurrences int - // ParseNumbers enables detection of duplicated numbers - ParseNumbers bool - // NumberMin sets the minimum value for reported number matches - NumberMin int - // NumberMax sets the maximum value for reported number matches - NumberMax int - // ExcludeTypes allows excluding specific types of contexts - ExcludeTypes map[Type]bool - // FindDuplicates enables finding constants whose values match existing constants in other packages. - FindDuplicates bool - // EvalConstExpressions enables evaluation of constant expressions like Prefix + "suffix" - EvalConstExpressions bool -} - -// NewWithIgnorePatterns creates a new instance of the parser with support for multiple ignore patterns. -// This is an alternative constructor that takes a slice of ignore string patterns. -func NewWithIgnorePatterns( - path, ignore string, - ignoreStrings []string, - ignoreTests, matchConstant, numbers, findDuplicates, evalConstExpressions bool, - numberMin, numberMax, minLength, minOccurrences int, - excludeTypes map[Type]bool) *Parser { - - // Join multiple patterns with OR for regex - var ignoreStringsPattern string - if len(ignoreStrings) > 0 { - if len(ignoreStrings) > 1 { - // Wrap each pattern in parentheses and join with OR - patterns := make([]string, len(ignoreStrings)) - for i, pattern := range ignoreStrings { - patterns[i] = "(" + pattern + ")" - } - ignoreStringsPattern = strings.Join(patterns, "|") - } else { - // Single pattern case - ignoreStringsPattern = ignoreStrings[0] - } - } - - return New( - path, - ignore, - ignoreStringsPattern, - ignoreTests, - matchConstant, - numbers, - findDuplicates, - evalConstExpressions, - numberMin, - numberMax, - minLength, - minOccurrences, - excludeTypes, - ) -} - -// RunWithConfig is a convenience function that runs the analysis with a Config object -// directly supporting multiple ignore patterns. -func RunWithConfig(files []*ast.File, fset *token.FileSet, typeInfo *types.Info, cfg *Config) ([]Issue, error) { - p := NewWithIgnorePatterns( - "", - "", - cfg.IgnoreStrings, - cfg.IgnoreTests, - cfg.MatchWithConstants, - cfg.ParseNumbers, - cfg.FindDuplicates, - cfg.EvalConstExpressions, - cfg.NumberMin, - cfg.NumberMax, - cfg.MinStringLength, - cfg.MinOccurrences, - cfg.ExcludeTypes, - ) - - // Pre-allocate slice based on estimated result size - expectedIssues := len(files) * 5 // Assuming average of 5 issues per file - if expectedIssues > 1000 { - expectedIssues = 1000 // Cap at reasonable maximum - } - - // Allocate a new buffer - issueBuffer := make([]Issue, 0, expectedIssues) - - // Process files concurrently - var wg sync.WaitGroup - sem := make(chan struct{}, p.maxConcurrency) - - // Create a filtered files slice with capacity hint - filteredFiles := make([]*ast.File, 0, len(files)) - - // Filter test files first if needed - for _, f := range files { - if p.ignoreTests { - if filename := fset.Position(f.Pos()).Filename; strings.HasSuffix(filename, "_test.go") { - continue - } - } - filteredFiles = append(filteredFiles, f) - } - - // Process each file in parallel - for _, f := range filteredFiles { - wg.Add(1) - sem <- struct{}{} // acquire semaphore - - go func(f *ast.File) { - defer func() { - <-sem // release semaphore - wg.Done() - }() - - // Use empty interned strings for package/file names - // The visitor logic will set these appropriately - emptyStr := InternString("") - - ast.Walk(&treeVisitor{ - fileSet: fset, - packageName: emptyStr, - p: p, - ignoreRegex: p.ignoreStringsRegex, - typeInfo: typeInfo, - }, f) - }(f) - } - - wg.Wait() - - p.ProcessResults() - - // Process each string that passed the filters - p.stringMutex.RLock() - p.stringCountMutex.RLock() - - // Create a slice to hold the string keys - stringKeys := make([]string, 0, len(p.strs)) - - // Create an array of strings to sort for stable output - for str := range p.strs { - if count := p.stringCount[str]; count >= p.minOccurrences { - stringKeys = append(stringKeys, str) - } - } - - sort.Strings(stringKeys) - - // Process strings in a predictable order for stable output - for _, str := range stringKeys { - positions := p.strs[str] - if len(positions) == 0 { - continue - } - - // Use the first position as representative - fi := positions[0] - - // Create issue using the counted value to avoid recounting - issue := Issue{ - Pos: fi.Position, - OccurrencesCount: p.stringCount[str], - Str: str, - } - - // Check for matching constants - if len(p.consts) > 0 { - p.constMutex.RLock() - if csts, ok := p.consts[str]; ok && len(csts) > 0 { - // const should be in the same package and exported - issue.MatchingConst = csts[0].Name - } - p.constMutex.RUnlock() - } - - issueBuffer = append(issueBuffer, issue) - } - - p.stringCountMutex.RUnlock() - p.stringMutex.RUnlock() - - // process duplicate constants - p.constMutex.RLock() - - // Create a new slice for const keys - stringKeys = make([]string, 0, len(p.consts)) - - // Create an array of strings and sort for stable output - for str := range p.consts { - if len(p.consts[str]) > 1 { - stringKeys = append(stringKeys, str) - } - } - - sort.Strings(stringKeys) - - // report an issue for every duplicated const - for _, str := range stringKeys { - positions := p.consts[str] - - for i := 1; i < len(positions); i++ { - issueBuffer = append(issueBuffer, Issue{ - Pos: positions[i].Position, - Str: str, - DuplicateConst: positions[0].Name, - DuplicatePos: positions[0].Position, - }) - } - } - - p.constMutex.RUnlock() - - // Don't return the buffer to pool as the caller now owns it - return issueBuffer, nil -} - -// Run analyzes the provided AST files for duplicated strings or numbers -// according to the provided configuration. -// It returns a slice of Issue objects containing the findings. -func Run(files []*ast.File, fset *token.FileSet, typeInfo *types.Info, cfg *Config) ([]Issue, error) { - return RunWithConfig(files, fset, typeInfo, cfg) -} diff --git a/vendor/github.com/jgautheron/goconst/parser.go b/vendor/github.com/jgautheron/goconst/parser.go deleted file mode 100644 index 9505d463e6..0000000000 --- a/vendor/github.com/jgautheron/goconst/parser.go +++ /dev/null @@ -1,884 +0,0 @@ -// Package goconst finds repeated strings that could be replaced by a constant. -// -// There are obvious benefits to using constants instead of repeating strings, -// mostly to ease maintenance. Cannot argue against changing a single constant versus many strings. -// While this could be considered a beginner mistake, across time, -// multiple packages and large codebases, some repetition could have slipped in. -package goconst - -import ( - "go/ast" - "go/constant" - "go/parser" - "go/token" - "go/types" - "io" - "log" - "os" - "path/filepath" - "regexp" - "runtime" - "strconv" - "strings" - "sync" -) - -// StringBuilderPool is a pool of string builders to reduce memory allocations -var StringBuilderPool = sync.Pool{ - New: func() interface{} { - return new(strings.Builder) - }, -} - -// FileReaderPool is a pool of byte buffers used for reading files -var FileReaderPool = sync.Pool{ - New: func() interface{} { - // Start with a 32KB buffer, which is sufficient for most Go files - return make([]byte, 32*1024) - }, -} - -// ByteBufferPool is a pool for temporary byte slices -var ByteBufferPool = sync.Pool{ - New: func() interface{} { - slice := make([]byte, 0, 8*1024) - return &slice - }, -} - -// ExtendedPosPool is a pool for slices of ExtendedPos -var ExtendedPosPool = sync.Pool{ - New: func() interface{} { - slice := make([]ExtendedPos, 0, 8) - return &slice - }, -} - -// StringInternPool is a pool for deduplicating strings to reduce memory usage -var StringInternPool = sync.Map{} - -// InternString returns a deduplicated reference to the given string -// to reduce memory usage when the same string appears multiple times -func InternString(s string) string { - if s == "" { - return "" - } - - if interned, ok := StringInternPool.Load(s); ok { - return interned.(string) - } - // Store a copy to prevent external modifications - interned := string([]byte(s)) - StringInternPool.Store(interned, interned) - return interned -} - -// GetStringBuilder retrieves a string builder from the pool -func GetStringBuilder() *strings.Builder { - return StringBuilderPool.Get().(*strings.Builder) -} - -// PutStringBuilder returns a string builder to the pool after resetting it -func PutStringBuilder(sb *strings.Builder) { - sb.Reset() - StringBuilderPool.Put(sb) -} - -// GetByteBuffer retrieves a byte buffer from the pool -func GetByteBuffer() []byte { - return (*ByteBufferPool.Get().(*[]byte))[:0] // Reset length but keep capacity -} - -// PutByteBuffer returns a byte buffer to the pool -func PutByteBuffer(buf []byte) { - bufCopy := make([]byte, 0, cap(buf)) - ByteBufferPool.Put(&bufCopy) -} - -// GetExtendedPosBuffer retrieves an ExtendedPos slice from the pool -func GetExtendedPosBuffer() []ExtendedPos { - return (*ExtendedPosPool.Get().(*[]ExtendedPos))[:0] // Reset length but keep capacity -} - -// PutExtendedPosBuffer returns an ExtendedPos slice to the pool -func PutExtendedPosBuffer(slice []ExtendedPos) { - sliceCopy := make([]ExtendedPos, 0, cap(slice)) - ExtendedPosPool.Put(&sliceCopy) -} - -const ( - testSuffix = "_test.go" -) - -// Parser represents the core analysis engine for finding repeated strings and constants. -// It holds both configuration options and the internal state during analysis. -type Parser struct { - // Meant to be passed via New() - path, ignore, ignoreStrings string - ignoreTests, matchConstant bool - findDuplicates bool - minLength, minOccurrences int - numberMin, numberMax int - excludeTypes map[Type]bool - maxConcurrency int - evalConstExpressions bool // Whether to evaluate constant expressions - - supportedTokens []token.Token - supportedKinds []constant.Kind - - // Internals - strs Strings - consts Constants - stringMutex sync.RWMutex - constMutex sync.RWMutex - - // Pre-compiled regexes for efficiency - ignoreRegex *regexp.Regexp - ignoreStringsRegex *regexp.Regexp - - // String occurrence counter - // Using a separate counter map improves performance for - // tracking frequency without having to compute len(items) repeatedly - stringCount map[string]int - stringCountMutex sync.RWMutex - - // Batch processing options - batchSize int - enableBatching bool - - // FileSet cache to avoid creating multiple fileSets - fileSetCache *token.FileSet - fileSetMutex sync.Mutex -} - -// New creates a new instance of the parser. -// This is your entry point if you'd like to use goconst as an API. -// -// Parameters: -// - path: the file or directory path to analyze -// - ignore: regex pattern to ignore files -// - ignoreStrings: regex pattern to ignore strings -// - ignoreTests: whether to ignore test files -// - matchConstant: whether to match strings with existing constants -// - numbers: whether to analyze number literals -// - findDuplicates: whether to find consts with duplicate values -// - evalConstExpressions: whether to evaluate constant expressions -// - numberMin/numberMax: range limits for number analysis -// - minLength: minimum string length to consider -// - minOccurrences: minimum occurrences to report -// - excludeTypes: map of context types to exclude -func New(path, ignore, ignoreStrings string, ignoreTests, matchConstant, numbers, findDuplicates, evalConstExpressions bool, numberMin, numberMax, minLength, minOccurrences int, excludeTypes map[Type]bool) *Parser { - supportedTokens := []token.Token{token.STRING} - supportedKinds := []constant.Kind{constant.String} - if numbers { - supportedTokens = append(supportedTokens, token.INT, token.FLOAT) - supportedKinds = append(supportedKinds, constant.Complex, constant.Float, constant.Int) - } - - // Set default concurrency to number of CPUs - maxConcurrency := runtime.NumCPU() - - // Pre-compile regular expressions for efficiency - var ignoreRegex, ignoreStringsRegex *regexp.Regexp - var err error - - if ignore != "" { - ignoreRegex, err = regexp.Compile(ignore) - if err != nil { - log.Printf("Warning: Invalid ignore regex pattern '%s': %v", ignore, err) - } - } - - if ignoreStrings != "" { - ignoreStringsRegex, err = regexp.Compile(ignoreStrings) - if err != nil { - log.Printf("Warning: Invalid ignore-strings regex pattern '%s': %v", ignoreStrings, err) - } - } - - // Estimate capacity based on typical usage patterns - stringMapCapacity := 500 - constMapCapacity := 100 - - // For large codebases, increase capacity estimates - if numbers { - stringMapCapacity *= 2 // Numbers typically increase the result set - } - - // Intern common strings to reduce memory usage - path = InternString(path) - ignore = InternString(ignore) - ignoreStrings = InternString(ignoreStrings) - - // Create a single FileSet to be reused - fileSet := token.NewFileSet() - - return &Parser{ - path: path, - ignore: ignore, - ignoreStrings: ignoreStrings, - ignoreTests: ignoreTests, - matchConstant: matchConstant, - findDuplicates: findDuplicates, - evalConstExpressions: evalConstExpressions, - minLength: minLength, - minOccurrences: minOccurrences, - numberMin: numberMin, - numberMax: numberMax, - supportedTokens: supportedTokens, - supportedKinds: supportedKinds, - excludeTypes: excludeTypes, - maxConcurrency: maxConcurrency, - ignoreRegex: ignoreRegex, - ignoreStringsRegex: ignoreStringsRegex, - - // Initialize the maps with capacity hints - strs: make(Strings, stringMapCapacity), - consts: make(Constants, constMapCapacity), - stringCount: make(map[string]int, stringMapCapacity), - - // Default batch processing settings - batchSize: 50, - enableBatching: true, - - // Cache a single FileSet for reuse - fileSetCache: fileSet, - } -} - -// SetConcurrency allows setting the maximum number of goroutines to use -// for parallel file processing. Default is the number of CPUs. -func (p *Parser) SetConcurrency(max int) { - if max > 0 { - p.maxConcurrency = max - } -} - -// EnableBatchProcessing activates batch processing mode for very large codebases. -// This mode collects files in batches before processing them to reduce memory usage. -// The batchSize parameter controls how many files to process in each batch. -func (p *Parser) EnableBatchProcessing(batchSize int) { - p.enableBatching = true - if batchSize > 0 { - p.batchSize = batchSize - } -} - -// ParseTree will search the given path for occurrences that could be moved into constants. -// If "..." is appended, the search will be recursive. -// -// It returns maps of strings and constants found during the analysis, and any error encountered. -// Use ProcessResults to filter the results based on configuration before retrieving them. -func (p *Parser) ParseTree() (Strings, Constants, error) { - pathLen := len(p.path) - // Parse recursively the given path if the recursive notation is found - if pathLen >= 5 && p.path[pathLen-3:] == "..." { - return p.parseTreeConcurrent(p.path[:pathLen-3], true) - } else { - return p.parseTreeConcurrent(p.path, false) - } -} - -const ( - chanSize = 1000 -) - -// parseTreeConcurrent implements an optimized concurrent file traversal -// that efficiently processes directories and files using worker pools. -func (p *Parser) parseTreeConcurrent(rootPath string, recursive bool) (Strings, Constants, error) { - - // If batch processing is enabled, use that implementation instead - if p.enableBatching { - return p.parseTreeBatched(rootPath, recursive) - } - - // Process files directly if the input is a single file - fi, err := os.Stat(rootPath) - if err == nil && !fi.IsDir() { - fset := p.getFileSet() - src, err := p.readFileEfficiently(rootPath) - if err != nil { - return nil, nil, err - } - - f, err := parser.ParseFile(fset, rootPath, src, 0) - if err != nil { - return nil, nil, err - } - // run type checker - info := &types.Info{ - Types: make(map[ast.Expr]types.TypeAndValue), - } - - chkConfig := &types.Config{ - Error: func(err error) {}, // type checking is only used to evaluate constant expressions, so we ignore most errors - } - pkg := types.NewPackage("", f.Name.Name) - _ = types.NewChecker(chkConfig, fset, pkg, info).Files([]*ast.File{f}) - - // Process the file - ast.Walk(&treeVisitor{ - fileSet: fset, - packageName: f.Name.Name, - p: p, - ignoreRegex: p.ignoreStringsRegex, - typeInfo: info, - }, f) - - // Post-process and filter results - p.ProcessResults() - return p.strs, p.consts, nil - } - - // Create a channel to collect all files to be processed - filesChan := make(chan string, chanSize) - - // Start a goroutine to collect all Go files - var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() - defer close(filesChan) - - // If not recursive, just handle a single directory - if !recursive { - entries, err := os.ReadDir(rootPath) - if err != nil { - log.Printf("Error reading directory %s: %v", rootPath, err) - return - } - - // Process entries - for _, entry := range entries { - if entry.IsDir() { - continue - } - - path := filepath.Join(rootPath, entry.Name()) - if strings.HasSuffix(path, ".go") { - // Skip test files if configured - if p.ignoreTests && strings.HasSuffix(path, testSuffix) { - continue - } - - // Skip files matching ignore pattern - if p.shouldSkipPath(path) { - continue - } - - filesChan <- path - } - } - return - } - - // Walk the directory tree recursively - err := filepath.Walk(rootPath, func(path string, info os.FileInfo, err error) error { - if err != nil { - log.Printf("Error accessing path %s: %v", path, err) - return nil // Continue walking - } - - // Skip directories based on ignore patterns - if info.IsDir() { - if p.shouldSkipPath(path) { - return filepath.SkipDir - } - return nil - } - - // Only process Go files - if strings.HasSuffix(path, ".go") { - // Skip test files if configured - if p.ignoreTests && strings.HasSuffix(path, testSuffix) { - return nil - } - - // Skip files matching ignore pattern - if p.shouldSkipPath(path) { - return nil - } - - // Send the file path to the channel - filesChan <- path - } - - return nil - }) - - if err != nil { - log.Printf("Error walking directory tree: %v", err) - } - }() - - // Read and parse files concurrently - fset, filesByPackage := p.parseConcurrently(filesChan) - - wg.Wait() - - // Type checking must be performed serially to avoid data races. - info := &types.Info{ - Types: make(map[ast.Expr]types.TypeAndValue), - } - - chkConfig := &types.Config{ - Error: func(err error) {}, // type checking is only used to evaluate constant expressions, so we ignore most errors - } - - for pkgName, files := range filesByPackage { - chk := types.NewChecker(chkConfig, fset, types.NewPackage("", pkgName), info) - _ = chk.Files(files) - } - - // Visit all files - p.visitConcurrently(fset, info, filesByPackage) - - // Post-process and filter results - p.ProcessResults() - - return p.strs, p.consts, nil -} - -func (p *Parser) parseConcurrently(filesChan <-chan string) (*token.FileSet, map[string][]*ast.File) { - // Start file parser workers - var parserWg sync.WaitGroup - - fset := p.getFileSet() - - parsedFilesChan := make(chan parsedFile, chanSize) - - // Add all workers to the WaitGroup before starting any goroutines - // This prevents a race condition with the goroutine that waits - parserWg.Add(p.maxConcurrency) - - // Start a separate goroutine to close the channel after all parsers are done - go func() { - parserWg.Wait() - close(parsedFilesChan) - }() - - for i := 0; i < p.maxConcurrency; i++ { - go func() { - defer parserWg.Done() - - for filePath := range filesChan { - // Parse a single file - src, err := p.readFileEfficiently(filePath) - if err != nil { - log.Printf("Error reading file %s: %v", filePath, err) - continue - } - - f, err := parser.ParseFile(fset, filePath, src, 0) - if err != nil { - log.Printf("Error parsing file %s: %v", filePath, err) - continue - } - - // Process the file - pkgName := f.Name.Name - parsedFilesChan <- parsedFile{pkgName, f} - } - }() - } - - // Read all parsed files into packgageFiles map. All packages must be parsed prior to type-checking. - fileCount := 0 - packageFiles := map[string][]*ast.File{} - - var readerWg sync.WaitGroup - readerWg.Add(1) - go func() { - defer readerWg.Done() - for parsed := range parsedFilesChan { - packageFiles[parsed.pkgName] = append(packageFiles[parsed.pkgName], parsed.f) - fileCount++ // safe since this is single-threaded. - } - }() - - // Wait for all file parsing to complete - parserWg.Wait() - // Wait for collection to complete - readerWg.Wait() - - return fset, packageFiles -} - -// visitConcurrently visits all files in filesByPackage on a worker pool goroutines. -func (p *Parser) visitConcurrently(fset *token.FileSet, info *types.Info, filesByPackage map[string][]*ast.File) { - var visitorWg sync.WaitGroup - - parsedFilesChan := make(chan parsedFile, chanSize) - - // Add all workers to the WaitGroup before starting any goroutines - visitorWg.Add(p.maxConcurrency) - - for i := 0; i < p.maxConcurrency; i++ { - go func() { - defer visitorWg.Done() - for pf := range parsedFilesChan { - ast.Walk(&treeVisitor{ - fileSet: fset, - typeInfo: info, - packageName: pf.pkgName, - p: p, - ignoreRegex: p.ignoreStringsRegex, - }, pf.f) - } - }() - } - - for pkgName, files := range filesByPackage { - for _, f := range files { - parsedFilesChan <- parsedFile{pkgName, f} - } - } - close(parsedFilesChan) - - visitorWg.Wait() -} - -// parseTreeBatched implements batch processing for very large codebases. -// Instead of processing files immediately as they are found, it collects them -// in batches and processes each batch completely before moving to the next. -// This helps manage memory usage for extremely large codebases. -func (p *Parser) parseTreeBatched(rootPath string, recursive bool) (Strings, Constants, error) { - var ( - allFiles []string - allFilesByDir = make(map[string][]string) - ) - - // First, collect all file paths that need to be processed - if recursive { - // If recursive, walk the entire directory tree - err := filepath.Walk(rootPath, func(path string, info os.FileInfo, err error) error { - if err != nil { - log.Printf("Error accessing path %s: %v", path, err) - return nil // Continue walking - } - - // Only process Go files - if !info.IsDir() && strings.HasSuffix(path, ".go") { - // Skip test files if configured to do so - if p.ignoreTests && strings.HasSuffix(path, testSuffix) { - return nil - } - - // Skip files matching ignore pattern - if p.shouldSkipPath(path) { - return nil - } - - allFiles = append(allFiles, path) - dir := filepath.Dir(path) - allFilesByDir[dir] = append(allFilesByDir[dir], path) - } - - return nil - }) - - if err != nil { - return nil, nil, err - } - } else { - // If not recursive, just read the files in the specified directory - entries, err := os.ReadDir(rootPath) - if err != nil { - return nil, nil, err - } - - for _, entry := range entries { - if entry.IsDir() { - continue - } - - path := filepath.Join(rootPath, entry.Name()) - - // Only process Go files - if strings.HasSuffix(path, ".go") { - // Skip test files if configured to do so - if p.ignoreTests && strings.HasSuffix(path, testSuffix) { - continue - } - - // Skip files matching ignore pattern - if p.shouldSkipPath(path) { - continue - } - - allFiles = append(allFiles, path) - allFilesByDir[rootPath] = append(allFilesByDir[rootPath], path) - } - } - } - - // Split into batches, ensuring each package's files are all in the same batch, since the typechecker requires - // entire packages. Some batches may exceed the requested batchSize. - totalFiles := 0 - largeBatches := 0 - maxBatchSize := 0 - - var batches [][]string - var currBatch []string - for _, pkgFiles := range allFilesByDir { - size := len(currBatch) - if size >= p.batchSize { - batches = append(batches, currBatch) - currBatch = nil - } - currBatch = append(currBatch, pkgFiles...) - - // compute some stats - if size >= p.batchSize { - largeBatches++ - } - if size >= maxBatchSize { - maxBatchSize = size - } - totalFiles += len(pkgFiles) - } - if len(currBatch) > 0 { - batches = append(batches, currBatch) - } - - // Process batches - log.Printf("Found %d Go files to process in batches of %d", totalFiles, p.batchSize) - if largeBatches > 0 { - log.Printf("Warning: %d batches exceed the configured batch size. Largest batch contains %d files", largeBatches, maxBatchSize) - } - - for i, batch := range batches { - log.Printf("Processing batch %d/%d (%d files)", i+1, len(batches), len(batch)) - - // Process this batch concurrently - - // Queue all files in this batch - fileChan := make(chan string, len(batch)) - for _, filePath := range batch { - fileChan <- filePath - } - close(fileChan) // safe to close since len(fileChan) == len(batch) - - // Parse files concurrently - fset, filesByPackage := p.parseConcurrently(fileChan) - - // Type check -- must be processed serially to avoid data races - info := &types.Info{ - Types: make(map[ast.Expr]types.TypeAndValue), - } - - chkConfig := &types.Config{ - Error: func(err error) {}, // type checking is only used to evaluate constant expressions, so we ignore most errors - } - for pkgName, files := range filesByPackage { - chk := types.NewChecker(chkConfig, fset, types.NewPackage("", pkgName), info) - _ = chk.Files(files) - } - - // Visit all files concurrently - p.visitConcurrently(fset, info, filesByPackage) - - // Optional: Run garbage collection between batches for very large codebases - if totalFiles > 10000 && len(batch) >= 1000 { - runtime.GC() - } - } - - // Post-process and filter results - p.ProcessResults() - - return p.strs, p.consts, nil -} - -// readFileEfficiently reads a file in the most efficient way. -// Benchmarks showed that for our specific use case, the standard -// library's ReadFile is already well-optimized. -func (p *Parser) readFileEfficiently(path string) ([]byte, error) { - // Optimized file reading to reduce allocations - f, err := os.Open(path) - if err != nil { - return nil, err - } - defer func() { - if closeErr := f.Close(); closeErr != nil { - log.Printf("Error closing file: %v", closeErr) - } - }() - - // Get file size to allocate buffer exactly once - info, err := f.Stat() - if err != nil { - return nil, err - } - - // For very small files, use ReadAll - if info.Size() < 8192 { - return io.ReadAll(f) - } - - // For larger files, allocate exact buffer size to avoid resize allocations - size := info.Size() - buf := make([]byte, size) - - // Read in a single operation - n, err := io.ReadFull(f, buf) - if err != nil && err != io.EOF && err != io.ErrUnexpectedEOF { - return nil, err - } - - return buf[:n], nil -} - -// getFileSet returns a cached FileSet for reuse -func (p *Parser) getFileSet() *token.FileSet { - p.fileSetMutex.Lock() - defer p.fileSetMutex.Unlock() - - // Return existing cache if available - if p.fileSetCache != nil { - return p.fileSetCache - } - - // Create a new one if needed - p.fileSetCache = token.NewFileSet() - return p.fileSetCache -} - -// shouldSkipPath determines if a path should be skipped based on ignore patterns -func (p *Parser) shouldSkipPath(path string) bool { - if p.ignoreRegex != nil { - if p.ignoreRegex.MatchString(path) { - return true - } - } else if len(p.ignore) != 0 { - // Fallback to non-compiled regex if compilation failed - match, err := regexp.MatchString(p.ignore, path) - if err != nil { - log.Printf("Error matching ignore pattern on %s: %v", path, err) - return false - } - if match { - return true - } - } - return false -} - -// IncrementStringCount safely increments the count for a string and returns the new count -func (p *Parser) IncrementStringCount(str string) int { - p.stringCountMutex.Lock() - defer p.stringCountMutex.Unlock() - - p.stringCount[str]++ - return p.stringCount[str] -} - -// GetStringCount safely gets the count for a string -func (p *Parser) GetStringCount(str string) int { - p.stringCountMutex.RLock() - defer p.stringCountMutex.RUnlock() - - return p.stringCount[str] -} - -// ProcessResults post-processes the raw results. -// It filters the discovered strings based on the parser's configuration: -// - Removes strings that don't meet the minimum occurrences threshold -// - Filters out strings matching the ignore pattern -// - Applies number range filtering if min/max values are set -func (p *Parser) ProcessResults() { - p.stringMutex.Lock() - defer p.stringMutex.Unlock() - - // Also acquire stringCount lock to ensure consistency during processing - p.stringCountMutex.Lock() - defer p.stringCountMutex.Unlock() - - for str := range p.strs { - // Check count first as it's faster than looking at slice length - count := p.stringCount[str] - if count < p.minOccurrences { - delete(p.strs, str) - delete(p.stringCount, str) - continue - } - - // Apply ignoreStrings filter - if p.ignoreStrings != "" { - if p.ignoreStringsRegex != nil { - // Use pre-compiled regex if available - if p.ignoreStringsRegex.MatchString(str) { - delete(p.strs, str) - delete(p.stringCount, str) - continue - } - } else { - // Fallback to the non-compiled version - match, err := regexp.MatchString(p.ignoreStrings, str) - if err != nil { - log.Println(err) - } - if match { - delete(p.strs, str) - delete(p.stringCount, str) - continue - } - } - } - - // Apply number range filtering if applicable - if i, err := strconv.ParseInt(str, 0, 0); err == nil { - if (p.numberMin != 0 && i < int64(p.numberMin)) || - (p.numberMax != 0 && i > int64(p.numberMax)) { - delete(p.strs, str) - delete(p.stringCount, str) - } - } - } -} - -type parsedFile struct { - pkgName string - f *ast.File -} - -// Strings maps string literals to their positions in the code. -type Strings map[string][]ExtendedPos - -// Constants maps string values to their constant definitions. -type Constants map[string][]ConstType - -// ConstType holds information about a constant declaration. -type ConstType struct { - // Using embedded Position to save memory vs. a separate field - token.Position - // Interned strings to reduce memory usage - Name string - packageName string -} - -// ExtendedPos extends token.Position with package information. -// This structure is optimized for memory usage in large codebases. -type ExtendedPos struct { - // Using embedded Position to save memory vs. a separate field - token.Position - // Interned package name to reduce memory usage when many positions - // reference the same package - packageName string -} - -// Type represents the context in which a string literal appears. -type Type int - -const ( - // Assignment represents a string in an assignment context (e.g., x := "foo") - Assignment Type = iota - // Binary represents a string in a binary expression (e.g., x == "foo") - Binary - // Case represents a string in a case clause (e.g., case "foo":) - Case - // Return represents a string in a return statement (e.g., return "foo") - Return - // Call represents a string passed as an argument to a function call (e.g., f("foo")) - Call -) diff --git a/vendor/github.com/jgautheron/goconst/visitor.go b/vendor/github.com/jgautheron/goconst/visitor.go deleted file mode 100644 index 350e3ae627..0000000000 --- a/vendor/github.com/jgautheron/goconst/visitor.go +++ /dev/null @@ -1,270 +0,0 @@ -package goconst - -import ( - "go/ast" - "go/constant" - "go/token" - "go/types" - "regexp" - "strconv" - "strings" -) - -// treeVisitor is used to walk the AST and find strings that could be constants. -type treeVisitor struct { - fileSet *token.FileSet - typeInfo *types.Info - packageName string - p *Parser - ignoreRegex *regexp.Regexp -} - -// Visit browses the AST tree for strings that could be potentially -// replaced by constants. -// A map of existing constants is built as well (-match-constant). -func (v *treeVisitor) Visit(node ast.Node) ast.Visitor { - if node == nil { - return v - } - - // A single case with "ast.BasicLit" would be much easier - // but then we wouldn't be able to tell in which context - // the string is defined (could be a constant definition). - switch t := node.(type) { - // Scan for constants in an attempt to match strings with existing constants - case *ast.GenDecl: - if !v.p.matchConstant && !v.p.findDuplicates { - return v - } - if t.Tok != token.CONST { - return v - } - - for _, spec := range t.Specs { - val := spec.(*ast.ValueSpec) - for i, str := range val.Values { - if v.typeInfo != nil && v.p.evalConstExpressions { - typedVal, ok := v.typeInfo.Types[str] - if !ok || !v.isSupportedKind(typedVal.Value.Kind()) { - continue - } - - v.addConst(val.Names[i].Name, typedVal.Value.String(), str.Pos()) - } else { - lit, ok := str.(*ast.BasicLit) - if !ok || !v.isSupported(lit.Kind) { - continue - } - v.addConst(val.Names[i].Name, lit.Value, val.Names[i].Pos()) - } - } - } - - // foo := "moo" - case *ast.AssignStmt: - for _, rhs := range t.Rhs { - lit, ok := rhs.(*ast.BasicLit) - if !ok || !v.isSupported(lit.Kind) { - continue - } - - v.addString(lit.Value, rhs.(*ast.BasicLit).Pos(), Assignment) - } - - // if foo == "moo" - case *ast.BinaryExpr: - if t.Op != token.EQL && t.Op != token.NEQ { - return v - } - - var lit *ast.BasicLit - var ok bool - - lit, ok = t.X.(*ast.BasicLit) - if ok && v.isSupported(lit.Kind) { - v.addString(lit.Value, lit.Pos(), Binary) - } - - lit, ok = t.Y.(*ast.BasicLit) - if ok && v.isSupported(lit.Kind) { - v.addString(lit.Value, lit.Pos(), Binary) - } - - // case "foo": - case *ast.CaseClause: - for _, item := range t.List { - lit, ok := item.(*ast.BasicLit) - if ok && v.isSupported(lit.Kind) { - v.addString(lit.Value, lit.Pos(), Case) - } - } - - // return "boo" - case *ast.ReturnStmt: - for _, item := range t.Results { - lit, ok := item.(*ast.BasicLit) - if ok && v.isSupported(lit.Kind) { - v.addString(lit.Value, lit.Pos(), Return) - } - } - - // fn("http://") - case *ast.CallExpr: - for _, item := range t.Args { - lit, ok := item.(*ast.BasicLit) - if ok && v.isSupported(lit.Kind) { - v.addString(lit.Value, lit.Pos(), Call) - } - } - } - - return v -} - -// addString adds a string in the map along with its position in the tree. -func (v *treeVisitor) addString(str string, pos token.Pos, typ Type) { - // Early type exclusion check - ok, excluded := v.p.excludeTypes[typ] - if ok && excluded { - return - } - - // Drop quotes if any - var unquotedStr string - if strings.HasPrefix(str, `"`) || strings.HasPrefix(str, "`") { - var err error - unquotedStr, err = strconv.Unquote(str) - if err != nil { - // Reuse strings from pool if possible to avoid allocations - sb := GetStringBuilder() - defer PutStringBuilder(sb) - - // If unquoting fails, manually strip quotes - // This avoids additional temporary strings - if len(str) >= 2 { - sb.WriteString(str[1 : len(str)-1]) - unquotedStr = sb.String() - } else { - unquotedStr = str - } - } - } else { - unquotedStr = str - } - - // Early length check - if len(unquotedStr) == 0 || len(unquotedStr) < v.p.minLength { - return - } - - // Early regex filtering - pre-compiled for efficiency - if v.ignoreRegex != nil && v.ignoreRegex.MatchString(unquotedStr) { - return - } - - // Early number range filtering - if v.p.numberMin != 0 || v.p.numberMax != 0 { - if i, err := strconv.ParseInt(unquotedStr, 0, 0); err == nil { - if (v.p.numberMin != 0 && i < int64(v.p.numberMin)) || - (v.p.numberMax != 0 && i > int64(v.p.numberMax)) { - return - } - } - } - - // Use interned string to reduce memory usage - identical strings share the same memory - internedStr := InternString(unquotedStr) - - // Update the count first, this is faster than appending to slices - count := v.p.IncrementStringCount(internedStr) - - // Only continue if we're still adding the position to the map - // or if count has reached threshold - if count == 1 || count == v.p.minOccurrences { - // Lock to safely update the shared map - v.p.stringMutex.Lock() - defer v.p.stringMutex.Unlock() - - _, exists := v.p.strs[internedStr] - if !exists { - v.p.strs[internedStr] = make([]ExtendedPos, 0, v.p.minOccurrences) // Preallocate with expected size - } - - // Create an optimized position record - newPos := ExtendedPos{ - packageName: InternString(v.packageName), // Intern the package name to reduce memory - Position: v.fileSet.Position(pos), - } - - v.p.strs[internedStr] = append(v.p.strs[internedStr], newPos) - } -} - -// addConst adds a const in the map along with its position in the tree. -func (v *treeVisitor) addConst(name string, val string, pos token.Pos) { - // Early filtering using the same criteria as for strings - var unquotedVal string - if strings.HasPrefix(val, `"`) || strings.HasPrefix(val, "`") { - var err error - // Use string builder from pool to reduce allocations - sb := GetStringBuilder() - defer PutStringBuilder(sb) - - if unquotedVal, err = strconv.Unquote(val); err != nil { - // If unquoting fails, manually strip quotes without allocations - if len(val) >= 2 { - sb.WriteString(val[1 : len(val)-1]) - unquotedVal = sb.String() - } else { - unquotedVal = val - } - } - } else { - unquotedVal = val - } - - // Skip constants with values that would be filtered anyway - if len(unquotedVal) < v.p.minLength { - return - } - - if v.ignoreRegex != nil && v.ignoreRegex.MatchString(unquotedVal) { - return - } - - // Use interned string to reduce memory usage - internedVal := InternString(unquotedVal) - internedName := InternString(name) - internedPkg := InternString(v.packageName) - - // Lock to safely update the shared map - v.p.constMutex.Lock() - defer v.p.constMutex.Unlock() - - // track this const if this is a new const, or if we are searching for duplicate consts - if _, ok := v.p.consts[internedVal]; !ok || v.p.findDuplicates { - v.p.consts[internedVal] = append(v.p.consts[internedVal], ConstType{ - Name: internedName, - packageName: internedPkg, - Position: v.fileSet.Position(pos), - }) - } -} - -func (v *treeVisitor) isSupported(tk token.Token) bool { - for _, s := range v.p.supportedTokens { - if tk == s { - return true - } - } - return false -} - -func (v *treeVisitor) isSupportedKind(kind constant.Kind) bool { - for _, s := range v.p.supportedKinds { - if kind == s { - return true - } - } - return false -} diff --git a/vendor/github.com/jingyugao/rowserrcheck/LICENSE b/vendor/github.com/jingyugao/rowserrcheck/LICENSE deleted file mode 100644 index 6957f1889c..0000000000 --- a/vendor/github.com/jingyugao/rowserrcheck/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2019 Seiji Takahashi - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/jingyugao/rowserrcheck/passes/rowserr/rowserr.go b/vendor/github.com/jingyugao/rowserrcheck/passes/rowserr/rowserr.go deleted file mode 100644 index a142a67442..0000000000 --- a/vendor/github.com/jingyugao/rowserrcheck/passes/rowserr/rowserr.go +++ /dev/null @@ -1,304 +0,0 @@ -package rowserr - -import ( - "go/ast" - "go/types" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/buildssa" - "golang.org/x/tools/go/ssa" -) - -func NewAnalyzer(sqlPkgs ...string) *analysis.Analyzer { - return &analysis.Analyzer{ - Name: "rowserrcheck", - Doc: Doc, - Run: NewRun(sqlPkgs...), - Requires: []*analysis.Analyzer{ - buildssa.Analyzer, - }, - } -} - -const ( - Doc = "rowserrcheck checks whether Rows.Err is checked" - errMethod = "Err" - rowsName = "Rows" -) - -type runner struct { - pass *analysis.Pass - rowsTyp *types.Pointer - rowsInterface *types.Interface - rowsObj types.Object - skipFile map[*ast.File]bool - sqlPkgs []string -} - -func NewRun(pkgs ...string) func(pass *analysis.Pass) (interface{}, error) { - return func(pass *analysis.Pass) (interface{}, error) { - sqlPkgs := append(pkgs, "database/sql") - for _, pkg := range sqlPkgs { - r := new(runner) - r.sqlPkgs = sqlPkgs - r.run(pass, pkg) - } - return nil, nil - } -} - -// run executes an analysis for the pass. The receiver is passed -// by value because this func is called in parallel for different passes. -func (r runner) run(pass *analysis.Pass, pkgPath string) { - r.pass = pass - pssa := pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA) - funcs := pssa.SrcFuncs - - pkg := pssa.Pkg.Prog.ImportedPackage(pkgPath) - if pkg == nil { - // skip - return - } - - rowsType := pkg.Type(rowsName) - if rowsType == nil { - // skip checking - return - } - r.rowsObj = rowsType.Object() - if r.rowsObj == nil { - // skip checking - return - } - - resNamed, ok := r.rowsObj.Type().(*types.Named) - if !ok { - return - } - - rowsInterface, ok := r.rowsObj.Type().Underlying().(*types.Interface) - if ok { - r.rowsInterface = rowsInterface - } - - r.rowsTyp = types.NewPointer(resNamed) - r.skipFile = map[*ast.File]bool{} - - for _, f := range funcs { - // skip if the function is just referenced - var isRefFunc bool - - for i := 0; i < f.Signature.Results().Len(); i++ { - if types.Identical(f.Signature.Results().At(i).Type(), r.rowsTyp) { - isRefFunc = true - } - } - - if isRefFunc { - continue - } - - for _, b := range f.Blocks { - for i := range b.Instrs { - if r.errCallMissing(b, i) { - pass.Reportf(b.Instrs[i].Pos(), "rows.Err must be checked") - } - } - } - } -} - -func (r *runner) errCallMissing(b *ssa.BasicBlock, i int) (ret bool) { - call, ok := r.getCallReturnsRow(b.Instrs[i]) - if !ok { - return false - } - - for _, cRef := range *call.Referrers() { - val, ok := r.getRowsVal(cRef) - if !ok { - continue - } - if len(*val.Referrers()) == 0 { - continue - } - resRefs := *val.Referrers() - var errCalled func(resRef ssa.Instruction) bool - errCalled = func(resRef ssa.Instruction) bool { - switch resRef := resRef.(type) { - case *ssa.Phi: - for _, rf := range *resRef.Referrers() { - if errCalled(rf) { - return true - } - } - case *ssa.Store: // Call in Closure function - for _, aref := range *resRef.Addr.Referrers() { - switch c := aref.(type) { - case *ssa.MakeClosure: - f := c.Fn.(*ssa.Function) - called := r.isClosureCalled(c) - if r.calledInFunc(f, called) { - return true - } - case *ssa.UnOp: - for _, rf := range *c.Referrers() { - if errCalled(rf) { - return true - } - } - } - } - case *ssa.Call: // Indirect function call - if r.isErrCall(resRef) { - return true - } - if f, ok := resRef.Call.Value.(*ssa.Function); ok { - for _, b := range f.Blocks { - for i := range b.Instrs { - if !r.errCallMissing(b, i) { - return true - } - } - } - } - case *ssa.FieldAddr: - for _, bRef := range *resRef.Referrers() { - bOp, ok := r.getBodyOp(bRef) - if !ok { - continue - } - - for _, ccall := range *bOp.Referrers() { - if r.isErrCall(ccall) { - return true - } - } - } - } - - return false - } - - for _, resRef := range resRefs { - if errCalled(resRef) { - return false - } - } - } - - return true -} - -func (r *runner) getCallReturnsRow(instr ssa.Instruction) (*ssa.Call, bool) { - call, ok := instr.(*ssa.Call) - if !ok { - return nil, false - } - - res := call.Call.Signature().Results() - - for i := 0; i < res.Len(); i++ { - typeToCheck := res.At(i).Type() - if types.Identical(typeToCheck, r.rowsTyp) { - return call, true - } - if r.rowsInterface != nil && types.Implements(typeToCheck, r.rowsInterface) { - return call, true - } - } - - return nil, false -} - -func (r *runner) getRowsVal(instr ssa.Instruction) (ssa.Value, bool) { - switch instr := instr.(type) { - case *ssa.Call: - if len(instr.Call.Args) == 1 && types.Identical(instr.Call.Args[0].Type(), r.rowsTyp) { - return instr.Call.Args[0], true - } - if len(instr.Call.Args) == 1 && r.rowsInterface != nil && types.Implements(instr.Call.Args[0].Type(), r.rowsInterface) { - return instr.Call.Args[0], true - } - case ssa.Value: - if types.Identical(instr.Type(), r.rowsTyp) { - return instr, true - } - if r.rowsInterface != nil && types.Implements(instr.Type(), r.rowsInterface) { - return instr, true - } - default: - } - - return nil, false -} - -func (r *runner) getBodyOp(instr ssa.Instruction) (*ssa.UnOp, bool) { - op, ok := instr.(*ssa.UnOp) - if !ok { - return nil, false - } - // fix: try to check type - // if op.Type() != r.rowsObj.Type() { - // return nil, false - // } - return op, true -} - -func (r *runner) isErrCall(ccall ssa.Instruction) bool { - switch ccall := ccall.(type) { - case *ssa.Defer: - if ccall.Call.Value != nil && ccall.Call.Value.Name() == errMethod { - return true - } - if ccall.Call.Method != nil && ccall.Call.Method.Name() == errMethod { - return true - } - case *ssa.Call: - if ccall.Call.Value != nil && ccall.Call.Value.Name() == errMethod { - return true - } - if ccall.Call.Method != nil && ccall.Call.Method.Name() == errMethod { - return true - } - } - - return false -} - -func (r *runner) isClosureCalled(c *ssa.MakeClosure) bool { - for _, ref := range *c.Referrers() { - switch ref.(type) { - case *ssa.Call, *ssa.Defer: - return true - } - } - - return false -} - -func (r *runner) calledInFunc(f *ssa.Function, called bool) bool { - for _, b := range f.Blocks { - for i, instr := range b.Instrs { - switch instr := instr.(type) { - case *ssa.UnOp: - for _, ref := range *instr.Referrers() { - if v, ok := ref.(ssa.Value); ok { - if vCall, ok := v.(*ssa.Call); ok { - if vCall.Call.Value != nil && vCall.Call.Value.Name() == errMethod { - if called { - return true - } - } - } - } - } - default: - if r.errCallMissing(b, i) || !called { - return false - } - } - } - } - return false -} diff --git a/vendor/github.com/jjti/go-spancheck/.gitignore b/vendor/github.com/jjti/go-spancheck/.gitignore deleted file mode 100644 index fc9b2a1090..0000000000 --- a/vendor/github.com/jjti/go-spancheck/.gitignore +++ /dev/null @@ -1,22 +0,0 @@ -# If you prefer the allow list template instead of the deny list, see community template: -# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore -# -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib - -# Test binary, built with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -# Dependency directories (remove the comment below to include it) -# vendor/ -src/ - -.vscode -.DS_Store \ No newline at end of file diff --git a/vendor/github.com/jjti/go-spancheck/.golangci.yml b/vendor/github.com/jjti/go-spancheck/.golangci.yml deleted file mode 100644 index 74a4377ab2..0000000000 --- a/vendor/github.com/jjti/go-spancheck/.golangci.yml +++ /dev/null @@ -1,93 +0,0 @@ -## A good ref for this: https://gist.github.com/maratori/47a4d00457a92aa426dbd48a18776322 - -run: - timeout: 5m - tests: true -linters: - enable: - - asasalint # checks for pass []any as any in variadic func(...any) - - asciicheck # checks that your code does not contain non-ASCII identifiers - - bidichk # checks for dangerous unicode character sequences - - bodyclose - - containedctx - - decorder # checks declaration order and count of types, constants, variables and functions - - dogsled - - dupword # checks for duplicate words in the source code - - durationcheck # checks for two durations multiplied together - - errcheck - - errname - - errorlint - - gci - - gochecknoinits # checks that no init functions are present in Go code - - gocritic - - gosimple - - govet - - importas # enforces consistent import aliases - - ineffassign - - loggercheck - - makezero # finds slice declarations with non-zero initial length - - mirror - - misspell - - musttag # enforces field tags in (un)marshaled structs - - nakedret - - nestif # reports deeply nested if statements - - nilerr # finds the code that returns nil even if it checks that the error is not nil - - noctx # finds sending http request without context.Context - - nolintlint # reports ill-formed or insufficient nolint directives - - predeclared # finds code that shadows one of Go's predeclared identifiers - - promlinter - - reassign # checks that package variables are not reassigned - - revive # fast, configurable, extensible, flexible, and beautiful linter for Go, drop-in replacement of golint - - staticcheck - - stylecheck - - thelper # detects golang test helpers without t.Helper() call and checks the consistency of test helpers - - unconvert # removes unnecessary type conversions - - unparam # reports unused function parameters - - unused - - usestdlibvars # detects the possibility to use variables/constants from the Go standard library - - wastedassign # finds wasted assignment statements - - whitespace # detects leading and trailing whitespace -linters-settings: - gci: - skip-generated: true - custom-order: true - sections: - - standard # Standard section: captures all standard packages. - - default # Default section: contains all imports that could not be matched to another section type. - - prefix(github.com/jjti) - gocritic: - settings: - captLocal: - # Whether to restrict checker to params only. - # Default: true - paramsOnly: false - underef: - # Whether to skip (*x).method() calls where x is a pointer receiver. - # Default: true - skipRecvDeref: false - govet: - enable-all: true - disable: - - fieldalignment # too strict - - shadow # bunch of false positive, doesn't realize when we return from a func - misspell: - locale: US - nakedret: - max-func-lines: 0 - nestif: - # Minimal complexity of if statements to report. - # Default: 5 - min-complexity: 5 - nolintlint: - # Enable to require an explanation of nonzero length after each nolint directive. - # Default: false - require-explanation: true - stylecheck: - checks: ["all"] -issues: - include: - - EXC0001 # Error return value of x is not checked - - EXC0013 # package comment should be of the form "(.+)... - - EXC0014 # comment on exported (.+) should be of the form "(.+)..." - exclude: - - ifElseChain diff --git a/vendor/github.com/jjti/go-spancheck/CONTRIBUTING.md b/vendor/github.com/jjti/go-spancheck/CONTRIBUTING.md deleted file mode 100644 index 32932fae10..0000000000 --- a/vendor/github.com/jjti/go-spancheck/CONTRIBUTING.md +++ /dev/null @@ -1,51 +0,0 @@ -# Contributing guideline - -Contributions are welcome + appreciated. - -## Open Requests - -These are a couple contributions I would especially appreciate: - -1. Add check for SetAttributes: https://github.com/jjti/go-spancheck/issues/1 -1. Add SuggestedFix(es): https://github.com/jjti/go-spancheck/issues/2 - -## Steps - -### 1. Create an Issue - -If one does not exist already, open a bug report or feature request in [https://github.com/jjti/go-spancheck/issues](https://github.com/jjti/go-spancheck/issues). - -### 2. Add a test case - -Test cases are in `/testdata`. - -If fixing a bug, you can add it to `testdata/enableall/enable_all.go` (for example): - -```go -func _() { - ctx, span := otel.Tracer("foo").Start(context.Background(), "bar") // want "span.End is not called on all paths, possible memory leak" - print(ctx.Done(), span.IsRecording()) -} // want "return can be reached without calling span.End" -``` - -If adding a new feature with a new combination of flags, create a new module within `testdata`: - -1. Create a new module, eg `testdata/setattributes` -1. Copy/paste go.mod/sum into the new module directory and update the module definition, eg `module github.com/jjti/go-spancheck/testdata/setattributes` -1. Add the module to the workspace in [go.work](./go.work) -1. Add the module's directory to the `testvendor` Make target in [Makefile](./Makefile) - -### 3. Run tests - -```bash -make test -``` - -### 4. Open a PR - -Eg of a GitHub snippet for PRs: - -```bash -alias gpr='gh pr view --web 2>/dev/null || gh pr create --web --fill' -gpr -``` diff --git a/vendor/github.com/jjti/go-spancheck/LICENSE b/vendor/github.com/jjti/go-spancheck/LICENSE deleted file mode 100644 index 552ddf2dc5..0000000000 --- a/vendor/github.com/jjti/go-spancheck/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 Joshua Timmons - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/jjti/go-spancheck/Makefile b/vendor/github.com/jjti/go-spancheck/Makefile deleted file mode 100644 index 8e9d07be31..0000000000 --- a/vendor/github.com/jjti/go-spancheck/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -.PHONY: fmt -fmt: - golangci-lint run --fix --config ./.golangci.yml - -.PHONY: test -test: testvendor - go test -v ./... - -# note: I'm copying https://github.com/ghostiam/protogetter/blob/main/testdata/Makefile -# -# x/tools/go/analysis/analysistest does not support go modules. To work around this issue -# we need to vendor any external modules to `./src`. -# -# Follow https://github.com/golang/go/issues/37054 for more details. -.PHONY: testvendor -testvendor: - rm -rf testdata/base/src - cd testdata/base && GOWORK=off go mod vendor - cp -r testdata/base/vendor testdata/base/src - cp -r testdata/base/vendor testdata/disableerrorchecks/src - cp -r testdata/base/vendor testdata/enableall/src - rm -rf testdata/base/vendor - -.PHONY: install -install: - go install ./cmd/spancheck - @echo "Installed in $(shell which spancheck)" \ No newline at end of file diff --git a/vendor/github.com/jjti/go-spancheck/README.md b/vendor/github.com/jjti/go-spancheck/README.md deleted file mode 100644 index 87c32fc668..0000000000 --- a/vendor/github.com/jjti/go-spancheck/README.md +++ /dev/null @@ -1,274 +0,0 @@ -# go-spancheck - -![Latest release](https://img.shields.io/github/v/release/jjti/go-spancheck) -[![ci](https://github.com/jjti/go-spancheck/actions/workflows/ci.yaml/badge.svg)](https://github.com/jjti/go-spancheck/actions/workflows/ci.yaml) -[![Go Report Card](https://goreportcard.com/badge/github.com/jjti/go-spancheck)](https://goreportcard.com/report/github.com/jjti/go-spancheck) -[![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](LICENSE) - -Checks usage of: - -- [OpenTelemetry spans](https://opentelemetry.io/docs/instrumentation/go/manual/) from [go.opentelemetry.io/otel/trace](go.opentelemetry.io/otel/trace) -- [OpenCensus spans](https://opencensus.io/quickstart/go/tracing/) from [go.opencensus.io/trace](https://pkg.go.dev/go.opencensus.io/trace#Span) - -## Example - -```bash -spancheck -checks 'end,set-status,record-error' ./... -``` - -```go -func _() error { - // span.End is not called on all paths, possible memory leak - // span.SetStatus is not called on all paths - // span.RecordError is not called on all paths - _, span := otel.Tracer("foo").Start(context.Background(), "bar") - - if true { - // return can be reached without calling span.End - // return can be reached without calling span.SetStatus - // return can be reached without calling span.RecordError - return errors.New("err") - } - - return nil // return can be reached without calling span.End -} -``` - -## Configuration - -### golangci-lint - -Docs on configuring the linter are also available at [https://golangci-lint.run/usage/linters/#spancheck](https://golangci-lint.run/usage/linters/#spancheck): - -```yaml -linters: - enable: - - spancheck - -linters-settings: - spancheck: - # Checks to enable. - # Options include: - # - `end`: check that `span.End()` is called - # - `record-error`: check that `span.RecordError(err)` is called when an error is returned - # - `set-status`: check that `span.SetStatus(codes.Error, msg)` is called when an error is returned - # Default: ["end"] - checks: - - end - - record-error - - set-status - # A list of regexes for function signatures that silence `record-error` and `set-status` reports - # if found in the call path to a returned error. - # https://github.com/jjti/go-spancheck#ignore-check-signatures - # Default: [] - ignore-check-signatures: - - "telemetry.RecordError" - # A list of regexes for additional function signatures that create spans. This is useful if you have a utility - # method to create spans. Each entry should be of the form :, where `telemetry-type` - # can be `opentelemetry` or `opencensus`. - # https://github.com/jjti/go-spancheck#extra-start-span-signatures - # Default: [] - extra-start-span-signatures: - - "github.com/user/repo/telemetry/trace.Start:opentelemetry" -``` - -### CLI - -To install the linter as a CLI: - -```bash -go install github.com/jjti/go-spancheck/cmd/spancheck@latest -spancheck ./... -``` - -Only the `span.End()` check is enabled by default. The others can be enabled with `-checks 'end,set-status,record-error'`. - -```txt -$ spancheck -h -... -Flags: - -checks string - comma-separated list of checks to enable (options: end, set-status, record-error) (default "end") - -extra-start-span-signatures string - comma-separated list of regex:telemetry-type for function signatures that indicate the start of a span - -ignore-check-signatures string - comma-separated list of regex for function signatures that disable checks on errors -``` - -### Ignore Check Signatures - -This setting avoids false positives from utility functions that return spans (which are handled gracefully by callers of the function). - -The `span.SetStatus()` and `span.RecordError()` checks warn when there is: - -1. a path to return statement -1. that returns an error -1. without a call (to `SetStatus` or `RecordError`, respectively) - -But it's convenient to call `SetStatus` and `RecordError` from utility methods [[1](https://andydote.co.uk/2023/09/19/tracing-is-better/#step-2-wrap-the-errors)]. To support that, the `ignore-*-check-signatures` settings will suppress warnings if the configured function is present in the path. - -For example, by default, the code below would have warnings as shown: - -```go -func task(ctx context.Context) error { - ctx, span := otel.Tracer("foo").Start(ctx, "bar") // span.SetStatus is not called on all paths - defer span.End() - - if err := subTask(ctx); err != nil { - return recordErr(span, err) // return can be reached without calling span.SetStatus - } - - return nil -} - -func recordErr(span trace.Span, err error) error { - span.SetStatus(codes.Error, err.Error()) - span.RecordError(err) - return err -} -``` - -The warnings are can be ignored by setting `-ignore-check-signatures` flag to `recordErr`: - -```bash -spancheck -checks 'end,set-status,record-error' -ignore-check-signatures 'recordErr' ./... -``` - -### Extra Start Span Signatures - -This setting informs spancheck of additional Span creation functions that should be linted (besides the library defaults). - -By default, Span creation will be tracked from calls to [(go.opentelemetry.io/otel/trace.Tracer).Start](https://github.com/open-telemetry/opentelemetry-go/blob/98b32a6c3a87fbee5d34c063b9096f416b250897/trace/trace.go#L523), [go.opencensus.io/trace.StartSpan](https://pkg.go.dev/go.opencensus.io/trace#StartSpan), or [go.opencensus.io/trace.StartSpanWithRemoteParent](https://github.com/census-instrumentation/opencensus-go/blob/v0.24.0/trace/trace_api.go#L66). - -You can use the `-extra-start-span-signatures` flag to list additional Span creation functions. For all such functions: - -1. their Spans will be linted (for all enable checks) -1. checks will be disabled (i.e. there is no linting of Spans within the creation functions) - -You must pass a comma-separated list of regex patterns and the telemetry library corresponding to the returned Span. Each entry should be of the form `:`, where `telemetry-type` can be `opentelemetry` or `opencensus`. For example, if you have created a function named `StartTrace` in a `telemetry` package, using the `go.opentelemetry.io/otel` library, you can include this function for analysis like so: - -```bash -spancheck -extra-start-span-signatures 'github.com/user/repo/telemetry/StartTrace:opentelemetry' ./... -``` - -## Problem Statement - -Tracing is a celebrated [[1](https://andydote.co.uk/2023/09/19/tracing-is-better/),[2](https://charity.wtf/2022/08/15/live-your-best-life-with-structured-events/)] and well marketed [[3](https://docs.datadoghq.com/tracing/),[4](https://www.honeycomb.io/distributed-tracing)] pillar of observability. But self-instrumented tracing requires a lot of easy-to-forget boilerplate: - -```go -import ( - "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/codes" -) - -func task(ctx context.Context) error { - ctx, span := otel.Tracer("foo").Start(ctx, "bar") - defer span.End() // call `.End()` - - if err := subTask(ctx); err != nil { - span.SetStatus(codes.Error, err.Error()) // call SetStatus(codes.Error, msg) to set status:error - span.RecordError(err) // call RecordError(err) to record an error event - return err - } - - return nil -} -``` - -For spans to be _really_ useful, developers need to: - -1. call `span.End()` always -1. call `span.SetStatus(codes.Error, msg)` on error -1. call `span.RecordError(err)` on error -1. call `span.SetAttributes()` liberally - -- OpenTelemetry: [Creating spans](https://opentelemetry.io/docs/instrumentation/go/manual/#creating-spans) -- Uptrace: [OpenTelemetry Go Tracing API](https://uptrace.dev/opentelemetry/go-tracing.html#quickstart) - -This linter helps developers with steps 1-3. - -## Checks - -This linter supports three checks, each documented below. Only the check for `span.End()` is enabled by default. See [Configuration](#configuration) for instructions on enabling the others. - -### `span.End()` - -Enabled by default. - -Not calling `End` can cause memory leaks and prevents spans from being closed. - -> Any Span that is created MUST also be ended. This is the responsibility of the user. Implementations of this API may leak memory or other resources if Spans are not ended. - -[source: trace.go](https://github.com/open-telemetry/opentelemetry-go/blob/98b32a6c3a87fbee5d34c063b9096f416b250897/trace/trace.go#L523) - -```go -func task(ctx context.Context) error { - otel.Tracer("app").Start(ctx, "foo") // span is unassigned, probable memory leak - _, span := otel.Tracer().Start(ctx, "foo") // span.End is not called on all paths, possible memory leak - return nil // return can be reached without calling span.End -} -``` - -### `span.SetStatus(codes.Error, "msg")` - -Disabled by default. Enable with `-checks 'set-status'`. - -Developers should call `SetStatus` on spans. The status attribute is an important, first-class attribute: - -1. observability platforms and APMs differentiate "success" vs "failure" using [span's status codes](https://docs.datadoghq.com/tracing/metrics/). -1. telemetry collector agents, like the [Open Telemetry Collector's Tail Sampling Processor](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/processor/tailsamplingprocessor/README.md#:~:text=Sampling%20Processor.-,status_code,-%3A%20Sample%20based%20upon), are configurable to sample `Error` spans at a higher rate than `OK` spans. -1. observability platforms, like [DataDog, have trace retention filters that use spans' status](https://docs.datadoghq.com/tracing/trace_pipeline/trace_retention/). In other words, `status:error` spans often receive special treatment with the assumption they are more useful for debugging. And forgetting to set the status can lead to spans, with useful debugging information, being dropped. - -```go -func _() error { - _, span := otel.Tracer("foo").Start(context.Background(), "bar") // span.SetStatus is not called on all paths - defer span.End() - - if err := subTask(); err != nil { - span.RecordError(err) - return errors.New(err) // return can be reached without calling span.SetStatus - } - - return nil -} -``` - -OpenTelemetry docs: [Set span status](https://opentelemetry.io/docs/instrumentation/go/manual/#set-span-status). - -### `span.RecordError(err)` - -Disabled by default. Enable with `-checks 'record-error'`. - -Calling `RecordError` creates a new exception-type [event (structured log message)](https://opentelemetry.io/docs/concepts/signals/traces/#span-events) on the span. This is recommended to capture the error's stack trace. - -```go -func _() error { - _, span := otel.Tracer("foo").Start(context.Background(), "bar") // span.RecordError is not called on all paths - defer span.End() - - if err := subTask(); err != nil { - span.SetStatus(codes.Error, err.Error()) - return errors.New(err) // return can be reached without calling span.RecordError - } - - return nil -} -``` - -OpenTelemetry docs: [Record errors](https://opentelemetry.io/docs/instrumentation/go/manual/#record-errors). - -Note: this check is not applied to [OpenCensus spans](https://pkg.go.dev/go.opencensus.io/trace#SpanInterface) because they have no `RecordError` method. - -## Attribution - -This linter is the product of liberal copying of: - -- [github.com/golang/tools/go/analysis/passes/lostcancel](https://github.com/golang/tools/tree/master/go/analysis/passes/lostcancel) (half the linter) -- [github.com/tomarrell/wrapcheck](https://github.com/tomarrell/wrapcheck) (error type checking and config) -- [github.com/Antonboom/testifylint](https://github.com/Antonboom/testifylint) (README) -- [github.com/ghostiam/protogetter](https://github.com/ghostiam/protogetter/blob/main/testdata/Makefile) (test setup) - -And the contributions of: - -- [@trixnz](https://github.com/trixnz) who [added support for custom span start functions](https://github.com/jjti/go-spancheck/pull/16) -- [@parsaaes](https://github.com/parsaaes) who [fixed a false negative bug in deferred methods that reference spans](https://github.com/jjti/go-spancheck/pull/31) diff --git a/vendor/github.com/jjti/go-spancheck/config.go b/vendor/github.com/jjti/go-spancheck/config.go deleted file mode 100644 index ed02a1ad91..0000000000 --- a/vendor/github.com/jjti/go-spancheck/config.go +++ /dev/null @@ -1,223 +0,0 @@ -package spancheck - -import ( - "flag" - "fmt" - "log" - "regexp" - "strings" -) - -// Check is a type of check that can be enabled or disabled. -type Check int - -const ( - // EndCheck if enabled, checks that span.End() is called after span creation and before the function returns. - EndCheck Check = iota - - // SetStatusCheck if enabled, checks that `span.SetStatus(codes.Error, msg)` is called when returning an error. - SetStatusCheck - - // RecordErrorCheck if enabled, checks that span.RecordError(err) is called when returning an error. - RecordErrorCheck -) - -var ( - startSpanSignatureCols = 2 - defaultStartSpanSignatures = []string{ - // https://github.com/open-telemetry/opentelemetry-go/blob/98b32a6c3a87fbee5d34c063b9096f416b250897/trace/trace.go#L523 - `\(go.opentelemetry.io/otel/trace.Tracer\).Start:opentelemetry`, - // https://pkg.go.dev/go.opencensus.io/trace#StartSpan - `go.opencensus.io/trace.StartSpan:opencensus`, - // https://github.com/census-instrumentation/opencensus-go/blob/v0.24.0/trace/trace_api.go#L66 - `go.opencensus.io/trace.StartSpanWithRemoteParent:opencensus`, - } -) - -func (c Check) String() string { - switch c { - case EndCheck: - return "end" - case SetStatusCheck: - return "set-status" - case RecordErrorCheck: - return "record-error" - default: - return "" - } -} - -// Checks is a list of all checks by name. -var Checks = map[string]Check{ - EndCheck.String(): EndCheck, - SetStatusCheck.String(): SetStatusCheck, - RecordErrorCheck.String(): RecordErrorCheck, -} - -type spanStartMatcher struct { - signature *regexp.Regexp - spanType spanType -} - -// Config is a configuration for the spancheck analyzer. -type Config struct { - fs flag.FlagSet - - // EnabledChecks is a list of checks to enable by name. - EnabledChecks []string - - // IgnoreChecksSignaturesSlice is a slice of strings that are turned into - // the IgnoreSetStatusCheckSignatures regex. - IgnoreChecksSignaturesSlice []string - - StartSpanMatchersSlice []string - - endCheckEnabled bool - setStatusEnabled bool - recordErrorEnabled bool - - // ignoreChecksSignatures is a regex that, if matched, disables the - // SetStatus and RecordError checks on error. - ignoreChecksSignatures *regexp.Regexp - - startSpanMatchers []spanStartMatcher - startSpanMatchersCustomRegex *regexp.Regexp -} - -// NewDefaultConfig returns a new Config with default values. -func NewDefaultConfig() *Config { - return &Config{ - EnabledChecks: []string{EndCheck.String()}, - StartSpanMatchersSlice: defaultStartSpanSignatures, - } -} - -// finalize parses checks and signatures from the public string slices of Config. -func (c *Config) finalize() { - c.parseSignatures() - - checks := parseChecks(c.EnabledChecks) - c.endCheckEnabled = contains(checks, EndCheck) - c.setStatusEnabled = contains(checks, SetStatusCheck) - c.recordErrorEnabled = contains(checks, RecordErrorCheck) -} - -// parseSignatures sets the Ignore*CheckSignatures regex from the string slices. -func (c *Config) parseSignatures() { - c.parseIgnoreSignatures() - c.parseStartSpanSignatures() -} - -func (c *Config) parseIgnoreSignatures() { - if c.ignoreChecksSignatures == nil && len(c.IgnoreChecksSignaturesSlice) > 0 { - if len(c.IgnoreChecksSignaturesSlice) == 1 && c.IgnoreChecksSignaturesSlice[0] == "" { - return - } - - c.ignoreChecksSignatures = createRegex(c.IgnoreChecksSignaturesSlice) - } -} - -func (c *Config) parseStartSpanSignatures() { - if c.startSpanMatchers != nil { - return - } - - customMatchers := []string{} - for i, sig := range c.StartSpanMatchersSlice { - parts := strings.Split(sig, ":") - - // Make sure we have both a signature and a telemetry type - if len(parts) != startSpanSignatureCols { - log.Default().Printf("[WARN] invalid start span signature \"%s\". expected regex:telemetry-type\n", sig) - - continue - } - - sig, sigType := parts[0], parts[1] - if len(sig) < 1 { - log.Default().Print("[WARN] invalid start span signature, empty pattern") - - continue - } - - spanType, ok := SpanTypes[sigType] - if !ok { - validSpanTypes := make([]string, 0, len(SpanTypes)) - for k := range SpanTypes { - validSpanTypes = append(validSpanTypes, k) - } - - log.Default(). - Printf("[WARN] invalid start span type \"%s\". expected one of %s\n", sigType, strings.Join(validSpanTypes, ", ")) - - continue - } - - regex, err := regexp.Compile(sig) - if err != nil { - log.Default().Printf("[WARN] failed to compile regex from signature %s: %v\n", sig, err) - - continue - } - - c.startSpanMatchers = append(c.startSpanMatchers, spanStartMatcher{ - signature: regex, - spanType: spanType, - }) - - if i >= len(defaultStartSpanSignatures) { - customMatchers = append(customMatchers, sig) - } - } - - c.startSpanMatchersCustomRegex = createRegex(customMatchers) -} - -func parseChecks(checksSlice []string) []Check { - if len(checksSlice) == 0 { - return nil - } - - checks := []Check{} - for _, check := range checksSlice { - checkName := strings.TrimSpace(check) - if checkName == "" { - continue - } - - check, ok := Checks[checkName] - if !ok { - continue - } - - checks = append(checks, check) - } - - return checks -} - -func createRegex(sigs []string) *regexp.Regexp { - if len(sigs) == 0 { - return nil - } - - regex := fmt.Sprintf("(%s)", strings.Join(sigs, "|")) - regexCompiled, err := regexp.Compile(regex) - if err != nil { - log.Default().Print("[WARN] failed to compile regex from signature flag", "regex", regex, "err", err) - return nil - } - - return regexCompiled -} - -func contains(s []Check, e Check) bool { - for _, a := range s { - if a == e { - return true - } - } - - return false -} diff --git a/vendor/github.com/jjti/go-spancheck/doc.go b/vendor/github.com/jjti/go-spancheck/doc.go deleted file mode 100644 index f9dec043f6..0000000000 --- a/vendor/github.com/jjti/go-spancheck/doc.go +++ /dev/null @@ -1,37 +0,0 @@ -// Package spancheck defines a linter that checks for mistakes with OTEL trace spans. -// -// # Analyzer spancheck -// -// spancheck: check for mistakes with OpenTelemetry trace spans. -// -// Common mistakes with OTEL trace spans include forgetting to call End: -// -// func(ctx context.Context) { -// ctx, span := otel.Tracer("app").Start(ctx, "span") -// // defer span.End() should be here -// -// // do stuff -// } -// -// Forgetting to set an Error status: -// -// ctx, span := otel.Tracer("app").Start(ctx, "span") -// defer span.End() -// -// if err := task(); err != nil { -// // span.SetStatus(codes.Error, err.Error()) should be here -// span.RecordError(err) -// return fmt.Errorf("failed to run task: %w", err) -// } -// -// Forgetting to record the Error: -// -// ctx, span := otel.Tracer("app").Start(ctx, "span") -// defer span.End() -// -// if err := task(); err != nil { -// span.SetStatus(codes.Error, err.Error()) -// // span.RecordError(err) should be here -// return fmt.Errorf("failed to run task: %w", err) -// } -package spancheck diff --git a/vendor/github.com/jjti/go-spancheck/go.work b/vendor/github.com/jjti/go-spancheck/go.work deleted file mode 100644 index ff04ca17e2..0000000000 --- a/vendor/github.com/jjti/go-spancheck/go.work +++ /dev/null @@ -1,8 +0,0 @@ -go 1.22.1 - -use ( - . - ./testdata/base - ./testdata/disableerrorchecks - ./testdata/enableall -) diff --git a/vendor/github.com/jjti/go-spancheck/go.work.sum b/vendor/github.com/jjti/go-spancheck/go.work.sum deleted file mode 100644 index c96d590d61..0000000000 --- a/vendor/github.com/jjti/go-spancheck/go.work.sum +++ /dev/null @@ -1,11 +0,0 @@ -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= -golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= -golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= -golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= -golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0= diff --git a/vendor/github.com/jjti/go-spancheck/spancheck.go b/vendor/github.com/jjti/go-spancheck/spancheck.go deleted file mode 100644 index 1618682aab..0000000000 --- a/vendor/github.com/jjti/go-spancheck/spancheck.go +++ /dev/null @@ -1,539 +0,0 @@ -package spancheck - -import ( - "go/ast" - "go/types" - "regexp" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/ctrlflow" - "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/inspector" - "golang.org/x/tools/go/cfg" -) - -const stackLen = 32 - -// spanType differentiates span types. -type spanType int - -const ( - spanUnset spanType = iota // not a span - spanOpenTelemetry // from go.opentelemetry.io/otel - spanOpenCensus // from go.opencensus.io/trace -) - -const ( - selNameEnd = "End" - selNameSetStatus = "SetStatus" - selNameRecordError = "RecordError" -) - -// SpanTypes is a list of all span types by name. -var SpanTypes = map[string]spanType{ - "opentelemetry": spanOpenTelemetry, - "opencensus": spanOpenCensus, -} - -// this approach stolen from errcheck -// https://github.com/kisielk/errcheck/blob/7f94c385d0116ccc421fbb4709e4a484d98325ee/errcheck/errcheck.go#L22 -var errorType = types.Universe.Lookup("error").Type().Underlying().(*types.Interface) - -// NewAnalyzerWithConfig returns a new analyzer configured with the Config passed in. -// Its config can be set for testing. -func NewAnalyzerWithConfig(config *Config) *analysis.Analyzer { - return newAnalyzer(config) -} - -func newAnalyzer(config *Config) *analysis.Analyzer { - config.finalize() - - return &analysis.Analyzer{ - Name: "spancheck", - Doc: "Checks for mistakes with OpenTelemetry/Census spans.", - Flags: config.fs, - Run: run(config), - Requires: []*analysis.Analyzer{ - ctrlflow.Analyzer, - inspect.Analyzer, - }, - } -} - -func run(config *Config) func(*analysis.Pass) (interface{}, error) { - return func(pass *analysis.Pass) (interface{}, error) { - inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - - nodeFilter := []ast.Node{ - (*ast.FuncLit)(nil), // f := func() {} - (*ast.FuncDecl)(nil), // func foo() {} - } - inspect.Preorder(nodeFilter, func(n ast.Node) { - runFunc(pass, n, config) - }) - - return nil, nil - } -} - -type spanVar struct { - stmt ast.Node - id *ast.Ident - vr *types.Var - spanType spanType -} - -// runFunc checks if the node is a function, has a span, and the span never has SetStatus set. -func runFunc(pass *analysis.Pass, node ast.Node, config *Config) { - // copying https://cs.opensource.google/go/x/tools/+/master:go/analysis/passes/lostcancel/lostcancel.go - - // Find scope of function node - var funcScope *types.Scope - switch v := node.(type) { - case *ast.FuncLit: - funcScope = pass.TypesInfo.Scopes[v.Type] - case *ast.FuncDecl: - funcScope = pass.TypesInfo.Scopes[v.Type] - fnSig := pass.TypesInfo.ObjectOf(v.Name).String() - - // Skip checking spans in this function if it's a custom starter/creator. - if config.startSpanMatchersCustomRegex != nil && config.startSpanMatchersCustomRegex.MatchString(fnSig) { - return - } - } - - // Maps each span variable to its defining ValueSpec/AssignStmt. - spanVars := make(map[*ast.Ident]spanVar) - - // Find the set of span vars to analyze. - stack := make([]ast.Node, 0, stackLen) - ast.Inspect(node, func(n ast.Node) bool { - switch n.(type) { - case *ast.FuncLit: - if len(stack) > 0 { - return false // don't stray into nested functions - } - case nil: - stack = stack[:len(stack)-1] // pop - return true - } - stack = append(stack, n) // push - - // Look for [{AssignStmt,ValueSpec} CallExpr SelectorExpr]: - // - // ctx, span := otel.Tracer("app").Start(...) - // ctx, span = otel.Tracer("app").Start(...) - // var ctx, span = otel.Tracer("app").Start(...) - sType, isStart := isSpanStart(pass.TypesInfo, n, config.startSpanMatchers) - if !isStart { - return true - } - - if !isCall(stack[len(stack)-2]) { - return true - } - - stmt := stack[len(stack)-3] - id := getID(stmt) - if id == nil { - pass.ReportRangef(n, "span is unassigned, probable memory leak") - return true - } - - if id.Name == "_" { - pass.ReportRangef(id, "span is unassigned, probable memory leak") - } else if v, ok := pass.TypesInfo.Uses[id].(*types.Var); ok { - // If the span variable is defined outside function scope, - // do not analyze it. - if funcScope.Contains(v.Pos()) { - spanVars[id] = spanVar{ - vr: v, - stmt: stmt, - id: id, - spanType: sType, - } - } - } else if v, ok := pass.TypesInfo.Defs[id].(*types.Var); ok { - spanVars[id] = spanVar{ - vr: v, - stmt: stmt, - id: id, - spanType: sType, - } - } - - return true - }) - - if len(spanVars) == 0 { - return // no need to inspect CFG - } - - // Obtain the CFG. - cfgs := pass.ResultOf[ctrlflow.Analyzer].(*ctrlflow.CFGs) - var g *cfg.CFG - var sig *types.Signature - switch node := node.(type) { - case *ast.FuncDecl: - sig, _ = pass.TypesInfo.Defs[node.Name].Type().(*types.Signature) - g = cfgs.FuncDecl(node) - case *ast.FuncLit: - sig, _ = pass.TypesInfo.Types[node.Type].Type.(*types.Signature) - g = cfgs.FuncLit(node) - } - if sig == nil { - return // missing type information - } - - // Check for missing calls. - for _, sv := range spanVars { - if config.endCheckEnabled { - // Check if there's no End to the span. - if ret := getMissingSpanCalls(pass, g, sv, selNameEnd, func(_ *analysis.Pass, ret *ast.ReturnStmt) *ast.ReturnStmt { return ret }, nil, config.startSpanMatchers); ret != nil { - pass.ReportRangef(sv.stmt, "%s.End is not called on all paths, possible memory leak", sv.vr.Name()) - pass.ReportRangef(ret, "return can be reached without calling %s.End", sv.vr.Name()) - } - } - - if config.setStatusEnabled { - // Check if there's no SetStatus to the span setting an error. - if ret := getMissingSpanCalls(pass, g, sv, selNameSetStatus, getErrorReturn, config.ignoreChecksSignatures, config.startSpanMatchers); ret != nil { - pass.ReportRangef(sv.stmt, "%s.SetStatus is not called on all paths", sv.vr.Name()) - pass.ReportRangef(ret, "return can be reached without calling %s.SetStatus", sv.vr.Name()) - } - } - - if config.recordErrorEnabled && sv.spanType == spanOpenTelemetry { // RecordError only exists in OpenTelemetry - // Check if there's no RecordError to the span setting an error. - if ret := getMissingSpanCalls(pass, g, sv, selNameRecordError, getErrorReturn, config.ignoreChecksSignatures, config.startSpanMatchers); ret != nil { - pass.ReportRangef(sv.stmt, "%s.RecordError is not called on all paths", sv.vr.Name()) - pass.ReportRangef(ret, "return can be reached without calling %s.RecordError", sv.vr.Name()) - } - } - } -} - -// isSpanStart reports whether n is tracer.Start() -func isSpanStart(info *types.Info, n ast.Node, startSpanMatchers []spanStartMatcher) (spanType, bool) { - sel, ok := n.(*ast.SelectorExpr) - if !ok { - return spanUnset, false - } - - fnSig := info.ObjectOf(sel.Sel).String() - - // Check if the function is a span start function. - for _, matcher := range startSpanMatchers { - if matcher.signature.MatchString(fnSig) { - return matcher.spanType, true - } - } - - return 0, false -} - -func isCall(n ast.Node) bool { - _, ok := n.(*ast.CallExpr) - return ok -} - -func getID(node ast.Node) *ast.Ident { - switch stmt := node.(type) { - case *ast.ValueSpec: - if len(stmt.Names) > 1 { - return stmt.Names[1] - } else if len(stmt.Names) == 1 { - return stmt.Names[0] - } - case *ast.AssignStmt: - if len(stmt.Lhs) > 1 { - id, _ := stmt.Lhs[1].(*ast.Ident) - return id - } else if len(stmt.Lhs) == 1 { - id, _ := stmt.Lhs[0].(*ast.Ident) - return id - } - } - return nil -} - -// getMissingSpanCalls finds a path through the CFG, from stmt (which defines -// the 'span' variable v) to a return statement, that doesn't call the passed selector on the span. -func getMissingSpanCalls( - pass *analysis.Pass, - g *cfg.CFG, - sv spanVar, - selName string, - checkErr func(pass *analysis.Pass, ret *ast.ReturnStmt) *ast.ReturnStmt, - ignoreCheckSig *regexp.Regexp, - spanStartMatchers []spanStartMatcher, -) *ast.ReturnStmt { - // blockUses computes "uses" for each block, caching the result. - memo := make(map[*cfg.Block]bool) - blockUses := func(pass *analysis.Pass, b *cfg.Block) bool { - res, ok := memo[b] - if !ok { - res = usesCall(pass, b.Nodes, sv, selName, ignoreCheckSig, spanStartMatchers, 0) - memo[b] = res - } - return res - } - - // Find the var's defining block in the CFG, - // plus the rest of the statements of that block. - var defBlock *cfg.Block - var rest []ast.Node -outer: - for _, b := range g.Blocks { - for i, n := range b.Nodes { - if n == sv.stmt { - defBlock = b - rest = b.Nodes[i+1:] - break outer - } - } - } - - // Is the call "used" in the remainder of its defining block? - if usesCall(pass, rest, sv, selName, ignoreCheckSig, spanStartMatchers, 0) { - return nil - } - - // Does the defining block return without making the call? - if ret := defBlock.Return(); ret != nil { - return checkErr(pass, ret) - } - - // Search the CFG depth-first for a path, from defblock to a - // return block, in which v is never "used". - seen := make(map[*cfg.Block]bool) - var search func(blocks []*cfg.Block) *ast.ReturnStmt - search = func(blocks []*cfg.Block) *ast.ReturnStmt { - for _, b := range blocks { - if seen[b] { - continue - } - seen[b] = true - - // Skip successors that are not nested within this current block. - if _, ok := nestedBlockTypes[b.Kind]; !ok { - continue - } - - // Prune the search if the block uses v. - if blockUses(pass, b) { - continue - } - - // Found path to return statement? - if ret := getErrorReturn(pass, b.Return()); ret != nil { - return ret // found - } - - // Recur - if ret := getErrorReturn(pass, search(b.Succs)); ret != nil { - return ret - } - } - return nil - } - - return search(defBlock.Succs) -} - -var nestedBlockTypes = map[cfg.BlockKind]struct{}{ - cfg.KindBody: {}, - cfg.KindForBody: {}, - cfg.KindForLoop: {}, - cfg.KindIfElse: {}, - cfg.KindIfThen: {}, - cfg.KindLabel: {}, - cfg.KindRangeBody: {}, - cfg.KindRangeLoop: {}, - cfg.KindSelectCaseBody: {}, - cfg.KindSelectAfterCase: {}, - cfg.KindSwitchCaseBody: {}, - cfg.KindSwitchNextCase: {}, -} - -// usesCall reports whether stmts contain a use of the selName call on variable v. -func usesCall( - pass *analysis.Pass, - stmts []ast.Node, - sv spanVar, - selName string, - ignoreCheckSig *regexp.Regexp, - startSpanMatchers []spanStartMatcher, - depth int, -) bool { - if depth > 1 { // for perf reasons, do not dive too deep thru func literals, just two levels deep. - return false - } - - cfgs := pass.ResultOf[ctrlflow.Analyzer].(*ctrlflow.CFGs) - - found, reAssigned := false, false - for _, subStmt := range stmts { - stack := []ast.Node{} - ast.Inspect(subStmt, func(n ast.Node) bool { - switch n := n.(type) { - case *ast.FuncLit: - if len(stack) > 0 { - g := cfgs.FuncLit(n) - if g != nil && len(g.Blocks) > 0 { - return usesCall(pass, g.Blocks[0].Nodes, sv, selName, ignoreCheckSig, startSpanMatchers, depth+1) - } - - return false - } - case *ast.CallExpr: - if ident, ok := n.Fun.(*ast.Ident); ok { - fnSig := pass.TypesInfo.ObjectOf(ident).String() - if ignoreCheckSig != nil && ignoreCheckSig.MatchString(fnSig) { - found = true - return false - } - } - case *ast.DeferStmt: - if n.Call == nil { - break - } - - f, ok := n.Call.Fun.(*ast.FuncLit) - if !ok { - break - } - - if g := cfgs.FuncLit(f); g != nil && len(g.Blocks) > 0 { - if selName == selNameEnd { - // Check if all returning blocks call end. - for _, b := range g.Blocks { - if b.Return() != nil && !usesCall( - pass, - b.Nodes, - sv, - selName, - ignoreCheckSig, - startSpanMatchers, - depth+1, - ) { - return false - } - } - - found = true - return false - } - - for _, b := range g.Blocks { - if usesCall( - pass, - b.Nodes, - sv, - selName, - ignoreCheckSig, - startSpanMatchers, - depth+1, - ) { - found = true - return false - } - } - } - case nil: - if len(stack) > 0 { - stack = stack[:len(stack)-1] // pop - return true - } - return false - } - stack = append(stack, n) // push - - // Check whether the span was assigned over top of its old value. - _, isStart := isSpanStart(pass.TypesInfo, n, startSpanMatchers) - if isStart { - if id := getID(stack[len(stack)-3]); id != nil && id.Obj.Decl == sv.id.Obj.Decl { - reAssigned = true - return false - } - } - - if n, ok := n.(*ast.SelectorExpr); ok { - // Selector (End, SetStatus, RecordError) hit. - if n.Sel.Name == selName { - id, ok := n.X.(*ast.Ident) - found = ok && id.Obj != nil && id.Obj.Decl == sv.id.Obj.Decl - } - - // Check if an ignore signature matches. - fnSig := pass.TypesInfo.ObjectOf(n.Sel).String() - if ignoreCheckSig != nil && ignoreCheckSig.MatchString(fnSig) { - found = true - } - } - - return !found - }) - } - - return found && !reAssigned -} - -func getErrorReturn(pass *analysis.Pass, ret *ast.ReturnStmt) *ast.ReturnStmt { - if ret == nil { - return nil - } - - for _, r := range ret.Results { - if isErrorType(pass.TypesInfo.TypeOf(r)) { - return ret - } - - if r, ok := r.(*ast.CallExpr); ok { - for _, err := range errorsByArg(pass, r) { - if err { - return ret - } - } - } - } - - return nil -} - -// errorsByArg returns a slice s such that -// len(s) == number of return types of call -// s[i] == true iff return type at position i from left is an error type -// -// copied from https://github.com/kisielk/errcheck/blob/master/errcheck/errcheck.go -func errorsByArg(pass *analysis.Pass, call *ast.CallExpr) []bool { - switch t := pass.TypesInfo.Types[call].Type.(type) { - case *types.Named: - // Single return - return []bool{isErrorType(t)} - case *types.Pointer: - // Single return via pointer - return []bool{isErrorType(t)} - case *types.Tuple: - // Multiple returns - s := make([]bool, t.Len()) - for i := 0; i < t.Len(); i++ { - switch et := t.At(i).Type().(type) { - case *types.Named: - // Single return - s[i] = isErrorType(et) - case *types.Pointer: - // Single return via pointer - s[i] = isErrorType(et) - default: - s[i] = false - } - } - return s - } - return []bool{false} -} - -func isErrorType(t types.Type) bool { - return types.Implements(t, errorType) -} diff --git a/vendor/github.com/julz/importas/.gitignore b/vendor/github.com/julz/importas/.gitignore deleted file mode 100644 index c264e642fe..0000000000 --- a/vendor/github.com/julz/importas/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -.idea/ -importas diff --git a/vendor/github.com/julz/importas/LICENSE b/vendor/github.com/julz/importas/LICENSE deleted file mode 100644 index 261eeb9e9f..0000000000 --- a/vendor/github.com/julz/importas/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/julz/importas/Makefile b/vendor/github.com/julz/importas/Makefile deleted file mode 100644 index e9838b43bd..0000000000 --- a/vendor/github.com/julz/importas/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -# default task since it's first -.PHONY: all -all: build test - -BINARY = importas -$(BINARY): *.go go.mod go.sum - go build -o $(BINARY) - -.PHONY: build -build: $(BINARY) ## Build binary - -.PHONY: test -test: build ## Unit test - go test -v ./... - -install: ## Install binary - go install diff --git a/vendor/github.com/julz/importas/README.md b/vendor/github.com/julz/importas/README.md deleted file mode 100644 index 1ea7b4fb26..0000000000 --- a/vendor/github.com/julz/importas/README.md +++ /dev/null @@ -1,59 +0,0 @@ -A linter to enforce importing certain packages consistently. - -## What is this for? - -Ideally, go imports should avoid aliasing. Sometimes though, especially with -Kubernetes API code, it becomes unavoidable, because many packages are imported -as e.g. "[package]/v1alpha1" and you end up with lots of collisions if you use -"v1alpha1". - -This linter lets you enforce that whenever (for example) -"pkg/apis/serving/v1alpha1" is aliased, it is aliased as "servingv1alpha1". - -## Usage - -~~~~ -importas \ - -alias knative.dev/serving/pkg/apis/autoscaling/v1alpha1:autoscalingv1alpha1 \ - -alias knative.dev/serving/pkg/apis/serving/v1:servingv1 \ - ./... -~~~~ - -### `-no-unaliased` option - -By default, importas allows non-aliased imports, even when the package is specified by `-alias` flag. -With `-no-unaliased` option, importas does not allow this. - -~~~~ -importas -no-unaliased \ - -alias knative.dev/serving/pkg/apis/autoscaling/v1alpha1:autoscalingv1alpha1 \ - -alias knative.dev/serving/pkg/apis/serving/v1:servingv1 \ - ./... -~~~~ - -### `-no-extra-aliases` option - -By default, importas allows aliases which are not specified by `-alias` flags. -With `-no-extra-aliases` option, importas does not allow any unspecified aliases. - -~~~~ -importas -no-extra-aliases \ - -alias knative.dev/serving/pkg/apis/autoscaling/v1alpha1:autoscalingv1alpha1 \ - -alias knative.dev/serving/pkg/apis/serving/v1:servingv1 \ - ./... -~~~~ - -### Use regular expression - -You can specify the package path by regular expression, and alias by regular expression replacement syntax like following snippet. - -~~~~ -importas -alias 'knative.dev/serving/pkg/apis/(\w+)/(v[\w\d]+):$1$2' -~~~~ - -`$1` represents the text of the first submatch. See [detail](https://golang.org/pkg/regexp/#Regexp.Expand). - -So it will enforce that - -"knative.dev/serving/pkg/apis/autoscaling/v1alpha1" is aliased by "autoscalingv1alpha1", and -"knative.dev/serving/pkg/apis/serving/v1" is aliased by "servingv1" diff --git a/vendor/github.com/julz/importas/analyzer.go b/vendor/github.com/julz/importas/analyzer.go deleted file mode 100644 index 25bc09b82f..0000000000 --- a/vendor/github.com/julz/importas/analyzer.go +++ /dev/null @@ -1,149 +0,0 @@ -package importas - -import ( - "fmt" - "go/ast" - "go/types" - "strconv" - "strings" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/inspector" -) - -var config = &Config{ - RequiredAlias: make([][]string, 0), -} - -var Analyzer = &analysis.Analyzer{ - Name: "importas", - Doc: "Enforces consistent import aliases", - Run: run, - - Flags: flags(config), - - Requires: []*analysis.Analyzer{inspect.Analyzer}, -} - -func run(pass *analysis.Pass) (interface{}, error) { - return runWithConfig(config, pass) -} - -func runWithConfig(config *Config, pass *analysis.Pass) (interface{}, error) { - if err := config.CompileRegexp(); err != nil { - return nil, err - } - - inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - inspect.Preorder([]ast.Node{(*ast.ImportSpec)(nil)}, func(n ast.Node) { - visitImportSpecNode(config, n.(*ast.ImportSpec), pass) - }) - - return nil, nil -} - -func visitImportSpecNode(config *Config, node *ast.ImportSpec, pass *analysis.Pass) { - if !config.DisallowUnaliased && node.Name == nil { - return - } - - alias := "" - if node.Name != nil { - alias = node.Name.String() - } - - if alias == "." { - return // Dot aliases are generally used in tests, so ignore. - } - - if strings.HasPrefix(alias, "_") { - return // Used by go test and for auto-includes, not a conflict. - } - - path, err := strconv.Unquote(node.Path.Value) - if err != nil { - pass.Reportf(node.Pos(), "import not quoted") - } - - if required, exists := config.AliasFor(path); exists && required != alias { - message := fmt.Sprintf("import %q imported as %q but must be %q according to config", path, alias, required) - if alias == "" { - message = fmt.Sprintf("import %q imported without alias but must be with alias %q according to config", path, required) - } - - pass.Report(analysis.Diagnostic{ - Pos: node.Pos(), - End: node.End(), - Message: message, - SuggestedFixes: []analysis.SuggestedFix{{ - Message: "Use correct alias", - TextEdits: findEdits(node, pass.TypesInfo.Uses, path, alias, required), - }}, - }) - } else if !exists && config.DisallowExtraAliases { - pass.Report(analysis.Diagnostic{ - Pos: node.Pos(), - End: node.End(), - Message: fmt.Sprintf("import %q has alias %q which is not part of config", path, alias), - SuggestedFixes: []analysis.SuggestedFix{{ - Message: "remove alias", - TextEdits: findEdits(node, pass.TypesInfo.Uses, path, alias, ""), - }}, - }) - } -} - -func findEdits(node ast.Node, uses map[*ast.Ident]types.Object, importPath, original, required string) []analysis.TextEdit { - // Edit the actual import line. - importLine := strconv.Quote(importPath) - if required != "" { - importLine = required + " " + importLine - } - result := []analysis.TextEdit{{ - Pos: node.Pos(), - End: node.End(), - NewText: []byte(importLine), - }} - - packageReplacement := required - if required == "" { - packageParts := strings.Split(importPath, "/") - if len(packageParts) != 0 { - packageReplacement = packageParts[len(packageParts)-1] - } else { - // fall back to original - packageReplacement = original - } - } - - // Edit all the uses of the alias in the code. - for use, pkg := range uses { - pkgName, ok := pkg.(*types.PkgName) - if !ok { - // skip identifiers that aren't pointing at a PkgName. - continue - } - - if pkgName.Pos() != node.Pos() { - // skip identifiers pointing to a different import statement. - continue - } - pos := use.Pos() - end := use.End() - replacement := packageReplacement - - if packageReplacement == "." { - replacement = "" - end = end + 1 - } - - result = append(result, analysis.TextEdit{ - Pos: pos, - End: end, - NewText: []byte(replacement), - }) - } - - return result -} diff --git a/vendor/github.com/julz/importas/config.go b/vendor/github.com/julz/importas/config.go deleted file mode 100644 index 58be86c75f..0000000000 --- a/vendor/github.com/julz/importas/config.go +++ /dev/null @@ -1,80 +0,0 @@ -package importas - -import ( - "errors" - "fmt" - "regexp" - "sync" -) - -type Config struct { - RequiredAlias aliasList - Rules []*Rule - DisallowUnaliased bool - DisallowExtraAliases bool - muRules sync.Mutex -} - -func (c *Config) CompileRegexp() error { - c.muRules.Lock() - defer c.muRules.Unlock() - if c.Rules != nil { - return nil - } - rules := make([]*Rule, 0, len(c.RequiredAlias)) - for _, aliases := range c.RequiredAlias { - path, alias := aliases[0], aliases[1] - reg, err := regexp.Compile(fmt.Sprintf("^%s$", path)) - if err != nil { - return err - } - - rules = append(rules, &Rule{ - Regexp: reg, - Alias: alias, - }) - } - c.Rules = rules - return nil -} - -func (c *Config) findRule(path string) *Rule { - c.muRules.Lock() - rules := c.Rules - c.muRules.Unlock() - for _, rule := range rules { - if rule.Regexp.MatchString(path) { - return rule - } - } - - return nil -} - -func (c *Config) AliasFor(path string) (string, bool) { - rule := c.findRule(path) - if rule == nil { - return "", false - } - - alias, err := rule.aliasFor(path) - if err != nil { - return "", false - } - - return alias, true -} - -type Rule struct { - Alias string - Regexp *regexp.Regexp -} - -func (r *Rule) aliasFor(path string) (string, error) { - str := r.Regexp.FindString(path) - if len(str) > 0 { - return r.Regexp.ReplaceAllString(str, r.Alias), nil - } - - return "", errors.New("mismatch rule") -} diff --git a/vendor/github.com/julz/importas/flags.go b/vendor/github.com/julz/importas/flags.go deleted file mode 100644 index cc3f1f3aae..0000000000 --- a/vendor/github.com/julz/importas/flags.go +++ /dev/null @@ -1,33 +0,0 @@ -package importas - -import ( - "errors" - "flag" - "fmt" - "strings" -) - -var errWrongAlias = errors.New("import flag must be of form path:alias") - -func flags(config *Config) flag.FlagSet { - fs := flag.FlagSet{} - fs.Var(&config.RequiredAlias, "alias", "required import alias in form path:alias") - fs.BoolVar(&config.DisallowUnaliased, "no-unaliased", false, "do not allow unaliased imports of aliased packages") - fs.BoolVar(&config.DisallowExtraAliases, "no-extra-aliases", false, "do not allow non-required aliases") - return fs -} - -type aliasList [][]string - -func (v *aliasList) Set(val string) error { - lastColon := strings.LastIndex(val, ":") - if lastColon <= 1 { - return errWrongAlias - } - *v = append(*v, []string{val[:lastColon], val[lastColon+1:]}) - return nil -} - -func (v *aliasList) String() string { - return fmt.Sprintf("%v", ([][]string)(*v)) -} diff --git a/vendor/github.com/karamaru-alpha/copyloopvar/.gitignore b/vendor/github.com/karamaru-alpha/copyloopvar/.gitignore deleted file mode 100644 index 816abbd923..0000000000 --- a/vendor/github.com/karamaru-alpha/copyloopvar/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -.idea/ -copyloopvar diff --git a/vendor/github.com/karamaru-alpha/copyloopvar/LICENSE b/vendor/github.com/karamaru-alpha/copyloopvar/LICENSE deleted file mode 100644 index e2567fd0c5..0000000000 --- a/vendor/github.com/karamaru-alpha/copyloopvar/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2024 Ryosei Karaki - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/karamaru-alpha/copyloopvar/README.md b/vendor/github.com/karamaru-alpha/copyloopvar/README.md deleted file mode 100644 index d31d1abd97..0000000000 --- a/vendor/github.com/karamaru-alpha/copyloopvar/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# copyloopvar - -copyloopvar is a linter detects places where loop variables are copied. - -cf. [Fixing For Loops in Go 1.22](https://go.dev/blog/loopvar-preview) - -## Example - -```go -for i, v := range []int{1, 2, 3} { - i := i // The copy of the 'for' variable "i" can be deleted (Go 1.22+) - v := v // The copy of the 'for' variable "v" can be deleted (Go 1.22+) - _, _ = i, v -} - -for i := 1; i <= 3; i++ { - i := i // The copy of the 'for' variable "i" can be deleted (Go 1.22+) - _ = i -} -``` - -## Install - -```bash -go install github.com/karamaru-alpha/copyloopvar/cmd/copyloopvar@latest -go vet -vettool=`which copyloopvar` ./... -``` diff --git a/vendor/github.com/karamaru-alpha/copyloopvar/copyloopvar.go b/vendor/github.com/karamaru-alpha/copyloopvar/copyloopvar.go deleted file mode 100644 index 00c8e0e3dc..0000000000 --- a/vendor/github.com/karamaru-alpha/copyloopvar/copyloopvar.go +++ /dev/null @@ -1,161 +0,0 @@ -package copyloopvar - -import ( - "fmt" - "go/ast" - "go/token" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/inspector" -) - -var checkAlias bool - -func NewAnalyzer() *analysis.Analyzer { - analyzer := &analysis.Analyzer{ - Name: "copyloopvar", - Doc: "a linter detects places where loop variables are copied", - Run: run, - Requires: []*analysis.Analyzer{ - inspect.Analyzer, - }, - } - analyzer.Flags.BoolVar(&checkAlias, "check-alias", false, "check all assigning the loop variable to another variable") - return analyzer -} - -func run(pass *analysis.Pass) (any, error) { - pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{ - (*ast.RangeStmt)(nil), - (*ast.ForStmt)(nil), - }, func(n ast.Node) { - switch node := n.(type) { - case *ast.RangeStmt: - checkRangeStmt(pass, node) - case *ast.ForStmt: - checkForStmt(pass, node) - } - }) - - return nil, nil -} - -func checkRangeStmt(pass *analysis.Pass, rangeStmt *ast.RangeStmt) { - key, ok := rangeStmt.Key.(*ast.Ident) - if !ok { - return - } - var value *ast.Ident - if rangeStmt.Value != nil { - if value, ok = rangeStmt.Value.(*ast.Ident); !ok { - return - } - } - for _, stmt := range rangeStmt.Body.List { - assignStmt, ok := stmt.(*ast.AssignStmt) - if !ok { - continue - } - if assignStmt.Tok != token.DEFINE { - continue - } - for i, rh := range assignStmt.Rhs { - right, ok := rh.(*ast.Ident) - if !ok { - continue - } - if right.Name != key.Name && (value == nil || right.Name != value.Name) { - continue - } - if !checkAlias { - left, ok := assignStmt.Lhs[i].(*ast.Ident) - if !ok { - continue - } - if left.Name != right.Name { - continue - } - } - - report(pass, assignStmt, right, i) - } - } -} - -func checkForStmt(pass *analysis.Pass, forStmt *ast.ForStmt) { - if forStmt.Init == nil { - return - } - initAssignStmt, ok := forStmt.Init.(*ast.AssignStmt) - if !ok { - return - } - initVarNameMap := make(map[string]interface{}, len(initAssignStmt.Lhs)) - for _, lh := range initAssignStmt.Lhs { - if initVar, ok := lh.(*ast.Ident); ok { - initVarNameMap[initVar.Name] = struct{}{} - } - } - for _, stmt := range forStmt.Body.List { - assignStmt, ok := stmt.(*ast.AssignStmt) - if !ok { - continue - } - if assignStmt.Tok != token.DEFINE { - continue - } - for i, rh := range assignStmt.Rhs { - right, ok := rh.(*ast.Ident) - if !ok { - continue - } - if _, ok := initVarNameMap[right.Name]; !ok { - continue - } - if !checkAlias { - left, ok := assignStmt.Lhs[i].(*ast.Ident) - if !ok { - continue - } - if left.Name != right.Name { - continue - } - } - - report(pass, assignStmt, right, i) - } - } -} - -func report(pass *analysis.Pass, assignStmt *ast.AssignStmt, right *ast.Ident, i int) { - diagnostic := analysis.Diagnostic{ - Pos: assignStmt.Pos(), - Message: fmt.Sprintf(`The copy of the 'for' variable "%s" can be deleted (Go 1.22+)`, right.Name), - } - - if i == 0 && isSimpleAssignStmt(assignStmt, right) { - diagnostic.SuggestedFixes = append(diagnostic.SuggestedFixes, analysis.SuggestedFix{ - TextEdits: []analysis.TextEdit{{ - Pos: assignStmt.Pos(), - End: assignStmt.End(), - NewText: nil, - }}, - }) - } - - pass.Report(diagnostic) -} - -func isSimpleAssignStmt(assignStmt *ast.AssignStmt, rhs *ast.Ident) bool { - if len(assignStmt.Lhs) != 1 { - return false - } - - lhs, ok := assignStmt.Lhs[0].(*ast.Ident) - if !ok { - return false - } - - return rhs.Name == lhs.Name -} diff --git a/vendor/github.com/kisielk/errcheck/LICENSE b/vendor/github.com/kisielk/errcheck/LICENSE deleted file mode 100644 index a2b16b5bd9..0000000000 --- a/vendor/github.com/kisielk/errcheck/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2013 Kamil Kisiel - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/kisielk/errcheck/errcheck/analyzer.go b/vendor/github.com/kisielk/errcheck/errcheck/analyzer.go deleted file mode 100644 index 82ab6298a9..0000000000 --- a/vendor/github.com/kisielk/errcheck/errcheck/analyzer.go +++ /dev/null @@ -1,77 +0,0 @@ -package errcheck - -import ( - "fmt" - "go/ast" - "reflect" - "regexp" - - "golang.org/x/tools/go/analysis" -) - -var Analyzer = &analysis.Analyzer{ - Name: "errcheck", - Doc: "check for unchecked errors", - Run: runAnalyzer, - ResultType: reflect.TypeOf(Result{}), -} - -var ( - argBlank bool - argAsserts bool - argExcludeFile string - argExcludeOnly bool -) - -func init() { - Analyzer.Flags.BoolVar(&argBlank, "blank", false, "if true, check for errors assigned to blank identifier") - Analyzer.Flags.BoolVar(&argAsserts, "assert", false, "if true, check for ignored type assertion results") - Analyzer.Flags.StringVar(&argExcludeFile, "exclude", "", "Path to a file containing a list of functions to exclude from checking") - Analyzer.Flags.BoolVar(&argExcludeOnly, "excludeonly", false, "Use only excludes from exclude file") -} - -func runAnalyzer(pass *analysis.Pass) (interface{}, error) { - exclude := map[string]bool{} - if !argExcludeOnly { - for _, name := range DefaultExcludedSymbols { - exclude[name] = true - } - } - if argExcludeFile != "" { - excludes, err := ReadExcludes(argExcludeFile) - if err != nil { - return nil, fmt.Errorf("Could not read exclude file: %v\n", err) - } - for _, name := range excludes { - exclude[name] = true - } - } - - var allErrors []UncheckedError - for _, f := range pass.Files { - v := &visitor{ - typesInfo: pass.TypesInfo, - fset: pass.Fset, - blank: argBlank, - asserts: argAsserts, - exclude: exclude, - ignore: map[string]*regexp.Regexp{}, // deprecated & not used - lines: make(map[string][]string), - errors: nil, - } - - ast.Walk(v, f) - - for _, err := range v.errors { - pass.Report(analysis.Diagnostic{ - Pos: pass.Fset.File(f.Pos()).Pos(err.Pos.Offset), - Message: "unchecked error", - Category: "errcheck", - }) - } - - allErrors = append(allErrors, v.errors...) - } - - return Result{UncheckedErrors: allErrors}, nil -} diff --git a/vendor/github.com/kisielk/errcheck/errcheck/embedded_walker.go b/vendor/github.com/kisielk/errcheck/errcheck/embedded_walker.go deleted file mode 100644 index 98f28e9a6b..0000000000 --- a/vendor/github.com/kisielk/errcheck/errcheck/embedded_walker.go +++ /dev/null @@ -1,144 +0,0 @@ -package errcheck - -import ( - "fmt" - "go/types" -) - -// walkThroughEmbeddedInterfaces returns a slice of Interfaces that -// we need to walk through in order to reach the actual definition, -// in an Interface, of the method selected by the given selection. -// -// false will be returned in the second return value if: -// - the right side of the selection is not a function -// - the actual definition of the function is not in an Interface -// -// The returned slice will contain all the interface types that need -// to be walked through to reach the actual definition. -// -// For example, say we have: -// -// type Inner interface {Method()} -// type Middle interface {Inner} -// type Outer interface {Middle} -// type T struct {Outer} -// type U struct {T} -// type V struct {U} -// -// And then the selector: -// -// V.Method -// -// We'll return [Outer, Middle, Inner] by first walking through the embedded structs -// until we reach the Outer interface, then descending through the embedded interfaces -// until we find the one that actually explicitly defines Method. -func walkThroughEmbeddedInterfaces(sel *types.Selection) ([]types.Type, bool) { - fn, ok := sel.Obj().(*types.Func) - if !ok { - return nil, false - } - - // Start off at the receiver. - currentT := sel.Recv() - - // First, we can walk through any Struct fields provided - // by the selection Index() method. We ignore the last - // index because it would give the method itself. - indexes := sel.Index() - for _, fieldIndex := range indexes[:len(indexes)-1] { - currentT = getTypeAtFieldIndex(currentT, fieldIndex) - } - - // Now currentT is either a type implementing the actual function, - // an Invalid type (if the receiver is a package), or an interface. - // - // If it's not an Interface, then we're done, as this function - // only cares about Interface-defined functions. - // - // If it is an Interface, we potentially need to continue digging until - // we find the Interface that actually explicitly defines the function. - interfaceT, ok := maybeUnname(currentT).(*types.Interface) - if !ok { - return nil, false - } - - // The first interface we pass through is this one we've found. We return the possibly - // wrapping types.Named because it is more useful to work with for callers. - result := []types.Type{currentT} - - // If this interface itself explicitly defines the given method - // then we're done digging. - for !explicitlyDefinesMethod(interfaceT, fn) { - // Otherwise, we find which of the embedded interfaces _does_ - // define the method, add it to our list, and loop. - namedInterfaceT, ok := getEmbeddedInterfaceDefiningMethod(interfaceT, fn) - if !ok { - // Returned a nil interface, we are done. - break - } - result = append(result, namedInterfaceT) - interfaceT = namedInterfaceT.Underlying().(*types.Interface) - } - - return result, true -} - -func getTypeAtFieldIndex(startingAt types.Type, fieldIndex int) types.Type { - t := maybeDereference(maybeUnalias(startingAt)) - t = maybeUnname(maybeUnalias(t)) - s, ok := t.(*types.Struct) - if !ok { - panic(fmt.Sprintf("cannot get Field of a type that is not a struct, got a %T", t)) - } - - return s.Field(fieldIndex).Type() -} - -// getEmbeddedInterfaceDefiningMethod searches through any embedded interfaces of the -// passed interface searching for one that defines the given function. If found, the -// types.Named wrapping that interface will be returned along with true in the second value. -// -// If no such embedded interface is found, nil and false are returned. -func getEmbeddedInterfaceDefiningMethod(interfaceT *types.Interface, fn *types.Func) (*types.Named, bool) { - for i := 0; i < interfaceT.NumEmbeddeds(); i++ { - embedded := interfaceT.Embedded(i) - if embedded != nil && definesMethod(embedded.Underlying().(*types.Interface), fn) { - return embedded, true - } - } - return nil, false -} - -func explicitlyDefinesMethod(interfaceT *types.Interface, fn *types.Func) bool { - for i := 0; i < interfaceT.NumExplicitMethods(); i++ { - if interfaceT.ExplicitMethod(i) == fn { - return true - } - } - return false -} - -func definesMethod(interfaceT *types.Interface, fn *types.Func) bool { - for i := 0; i < interfaceT.NumMethods(); i++ { - if interfaceT.Method(i) == fn { - return true - } - } - return false -} - -func maybeDereference(t types.Type) types.Type { - p, ok := t.(*types.Pointer) - if ok { - return p.Elem() - } - return t -} - -func maybeUnname(t types.Type) types.Type { - n, ok := t.(*types.Named) - if ok { - return n.Underlying() - } - return t -} diff --git a/vendor/github.com/kisielk/errcheck/errcheck/embedded_walker_121.go b/vendor/github.com/kisielk/errcheck/errcheck/embedded_walker_121.go deleted file mode 100644 index f2df6849bb..0000000000 --- a/vendor/github.com/kisielk/errcheck/errcheck/embedded_walker_121.go +++ /dev/null @@ -1,10 +0,0 @@ -//go:build !go1.22 -// +build !go1.22 - -package errcheck - -import "go/types" - -func maybeUnalias(t types.Type) types.Type { - return t -} diff --git a/vendor/github.com/kisielk/errcheck/errcheck/embedded_walker_122.go b/vendor/github.com/kisielk/errcheck/errcheck/embedded_walker_122.go deleted file mode 100644 index cbff3cd434..0000000000 --- a/vendor/github.com/kisielk/errcheck/errcheck/embedded_walker_122.go +++ /dev/null @@ -1,10 +0,0 @@ -//go:build go1.22 -// +build go1.22 - -package errcheck - -import "go/types" - -func maybeUnalias(t types.Type) types.Type { - return types.Unalias(t) -} diff --git a/vendor/github.com/kisielk/errcheck/errcheck/errcheck.go b/vendor/github.com/kisielk/errcheck/errcheck/errcheck.go deleted file mode 100644 index 325aeec98b..0000000000 --- a/vendor/github.com/kisielk/errcheck/errcheck/errcheck.go +++ /dev/null @@ -1,696 +0,0 @@ -// Package errcheck is the library used to implement the errcheck command-line tool. -package errcheck - -import ( - "bufio" - "errors" - "fmt" - "go/ast" - "go/token" - "go/types" - "os" - "regexp" - "sort" - "strings" - - "golang.org/x/tools/go/packages" -) - -var errorType *types.Interface - -func init() { - errorType = types.Universe.Lookup("error").Type().Underlying().(*types.Interface) -} - -var ( - // ErrNoGoFiles is returned when CheckPackage is run on a package with no Go source files. - // - // Deprecated: this error is no longer returned by errcheck.LoadPackages. - ErrNoGoFiles = errors.New("package contains no go source files") -) - -// UncheckedError indicates the position of an unchecked error return. -type UncheckedError struct { - Pos token.Position - Line string - FuncName string - SelectorName string -} - -// Result is returned from the CheckPackage function, and holds all the errors -// that were found to be unchecked in a package. -// -// Aggregation can be done using the Append method for users that want to -// combine results from multiple packages. -type Result struct { - // UncheckedErrors is a list of all the unchecked errors in the package. - // Printing an error reports its position within the file and the contents of the line. - UncheckedErrors []UncheckedError -} - -type byName []UncheckedError - -// Less reports whether the element with index i should sort before the element with index j. -func (b byName) Less(i, j int) bool { - ei, ej := b[i], b[j] - - pi, pj := ei.Pos, ej.Pos - - if pi.Filename != pj.Filename { - return pi.Filename < pj.Filename - } - if pi.Line != pj.Line { - return pi.Line < pj.Line - } - if pi.Column != pj.Column { - return pi.Column < pj.Column - } - - return ei.Line < ej.Line -} - -func (b byName) Swap(i, j int) { - b[i], b[j] = b[j], b[i] -} - -func (b byName) Len() int { - return len(b) -} - -// Append appends errors to e. Append does not do any duplicate checking. -func (r *Result) Append(other Result) { - r.UncheckedErrors = append(r.UncheckedErrors, other.UncheckedErrors...) -} - -// Unique returns the unique errors that have been accumulated. Duplicates may occur -// when a file containing an unchecked error belongs to > 1 package. -// -// The method receiver remains unmodified after the call to Unique. -func (r Result) Unique() Result { - result := make([]UncheckedError, len(r.UncheckedErrors)) - copy(result, r.UncheckedErrors) - sort.Sort((byName)(result)) - uniq := result[:0] // compact in-place - for i, err := range result { - if i == 0 || err != result[i-1] { - uniq = append(uniq, err) - } - } - return Result{UncheckedErrors: uniq} -} - -// Exclusions define symbols and language elements that will be not checked -type Exclusions struct { - - // Packages lists paths of excluded packages. - Packages []string - - // SymbolRegexpsByPackage maps individual package paths to regular - // expressions that match symbols to be excluded. - // - // Packages whose paths appear both here and in Packages list will - // be excluded entirely. - // - // This is a legacy input that will be deprecated in errcheck version 2 and - // should not be used. - SymbolRegexpsByPackage map[string]*regexp.Regexp - - // Symbols lists patterns that exclude individual package symbols. - // - // For example: - // - // "fmt.Errorf" // function - // "fmt.Fprintf(os.Stderr)" // function with set argument value - // "(hash.Hash).Write" // method - // - Symbols []string - - // TestFiles excludes _test.go files. - TestFiles bool - - // GeneratedFiles excludes generated source files. - // - // Source file is assumed to be generated if its contents - // match the following regular expression: - // - // ^// Code generated .* DO NOT EDIT\\.$ - // - GeneratedFiles bool - - // BlankAssignments ignores assignments to blank identifier. - BlankAssignments bool - - // TypeAssertions ignores unchecked type assertions. - TypeAssertions bool -} - -// Checker checks that you checked errors. -type Checker struct { - // Exclusions defines code packages, symbols, and other elements that will not be checked. - Exclusions Exclusions - - // Tags are a list of build tags to use. - Tags []string - - // The mod flag for go build. - Mod string -} - -// loadPackages is used for testing. -var loadPackages = func(cfg *packages.Config, paths ...string) ([]*packages.Package, error) { - return packages.Load(cfg, paths...) -} - -// LoadPackages loads all the packages in all the paths provided. It uses the -// exclusions and build tags provided to by the user when loading the packages. -func (c *Checker) LoadPackages(paths ...string) ([]*packages.Package, error) { - buildFlags := []string{fmt.Sprintf("-tags=%s", strings.Join(c.Tags, ","))} - if c.Mod != "" { - buildFlags = append(buildFlags, fmt.Sprintf("-mod=%s", c.Mod)) - } - cfg := &packages.Config{ - Mode: packages.NeedSyntax | packages.NeedTypes | packages.NeedTypesInfo, - Tests: !c.Exclusions.TestFiles, - BuildFlags: buildFlags, - } - return loadPackages(cfg, paths...) -} - -var generatedCodeRegexp = regexp.MustCompile("^// Code generated .* DO NOT EDIT\\.$") -var dotStar = regexp.MustCompile(".*") - -func (c *Checker) shouldSkipFile(file *ast.File) bool { - if !c.Exclusions.GeneratedFiles { - return false - } - - for _, cg := range file.Comments { - for _, comment := range cg.List { - if generatedCodeRegexp.MatchString(comment.Text) { - return true - } - } - } - - return false -} - -// CheckPackage checks packages for errors that have not been checked. -// -// It will exclude specific errors from analysis if the user has configured -// exclusions. -func (c *Checker) CheckPackage(pkg *packages.Package) Result { - excludedSymbols := map[string]bool{} - for _, sym := range c.Exclusions.Symbols { - excludedSymbols[sym] = true - } - - ignore := map[string]*regexp.Regexp{} - // Apply SymbolRegexpsByPackage first so that if the same path appears in - // Packages, a more narrow regexp will be superseded by dotStar below. - if regexps := c.Exclusions.SymbolRegexpsByPackage; regexps != nil { - for pkg, re := range regexps { - // TODO warn if previous entry overwritten? - ignore[nonVendoredPkgPath(pkg)] = re - } - } - for _, pkg := range c.Exclusions.Packages { - // TODO warn if previous entry overwritten? - ignore[nonVendoredPkgPath(pkg)] = dotStar - } - - v := &visitor{ - typesInfo: pkg.TypesInfo, - fset: pkg.Fset, - ignore: ignore, - blank: !c.Exclusions.BlankAssignments, - asserts: !c.Exclusions.TypeAssertions, - lines: make(map[string][]string), - exclude: excludedSymbols, - errors: []UncheckedError{}, - } - - for _, astFile := range pkg.Syntax { - if c.shouldSkipFile(astFile) { - continue - } - ast.Walk(v, astFile) - } - return Result{UncheckedErrors: v.errors} -} - -// visitor implements the errcheck algorithm -type visitor struct { - typesInfo *types.Info - fset *token.FileSet - ignore map[string]*regexp.Regexp - blank bool - asserts bool - lines map[string][]string - exclude map[string]bool - - errors []UncheckedError -} - -// selectorAndFunc tries to get the selector and function from call expression. -// For example, given the call expression representing "a.b()", the selector -// is "a.b" and the function is "b" itself. -// -// The final return value will be true if it is able to do extract a selector -// from the call and look up the function object it refers to. -// -// If the call does not include a selector (like if it is a plain "f()" function call) -// then the final return value will be false. -func (v *visitor) selectorAndFunc(call *ast.CallExpr) (*ast.SelectorExpr, *types.Func, bool) { - sel, ok := call.Fun.(*ast.SelectorExpr) - if !ok { - return nil, nil, false - } - - fn, ok := v.typesInfo.ObjectOf(sel.Sel).(*types.Func) - if !ok { - // Shouldn't happen, but be paranoid - return nil, nil, false - } - - return sel, fn, true - -} - -// fullName will return a package / receiver-type qualified name for a called function -// if the function is the result of a selector. Otherwise it will return -// the empty string. -// -// The name is fully qualified by the import path, possible type, -// function/method name and pointer receiver. -// -// For example, -// - for "fmt.Printf(...)" it will return "fmt.Printf" -// - for "base64.StdEncoding.Decode(...)" it will return "(*encoding/base64.Encoding).Decode" -// - for "myFunc()" it will return "" -func (v *visitor) fullName(call *ast.CallExpr) string { - _, fn, ok := v.selectorAndFunc(call) - if !ok { - return "" - } - - // TODO(dh): vendored packages will have /vendor/ in their name, - // thus not matching vendored standard library packages. If we - // want to support vendored stdlib packages, we need to implement - // FullName with our own logic. - return fn.FullName() -} - -func getSelectorName(sel *ast.SelectorExpr) string { - if ident, ok := sel.X.(*ast.Ident); ok { - return fmt.Sprintf("%s.%s", ident.Name, sel.Sel.Name) - } - if s, ok := sel.X.(*ast.SelectorExpr); ok { - return fmt.Sprintf("%s.%s", getSelectorName(s), sel.Sel.Name) - } - - return "" -} - -// selectorName will return a name for a called function -// if the function is the result of a selector. Otherwise it will return -// the empty string. -// -// The name is fully qualified by the import path, possible type, -// function/method name and pointer receiver. -// -// For example, -// - for "fmt.Printf(...)" it will return "fmt.Printf" -// - for "base64.StdEncoding.Decode(...)" it will return "base64.StdEncoding.Decode" -// - for "myFunc()" it will return "" -func (v *visitor) selectorName(call *ast.CallExpr) string { - sel, _, ok := v.selectorAndFunc(call) - if !ok { - return "" - } - - return getSelectorName(sel) -} - -// namesForExcludeCheck will return a list of fully-qualified function names -// from a function call that can be used to check against the exclusion list. -// -// If a function call is against a local function (like "myFunc()") then no -// names are returned. If the function is package-qualified (like "fmt.Printf()") -// then just that function's fullName is returned. -// -// Otherwise, we walk through all the potentially embedded interfaces of the receiver -// to collect a list of type-qualified function names that we will check. -func (v *visitor) namesForExcludeCheck(call *ast.CallExpr) []string { - sel, fn, ok := v.selectorAndFunc(call) - if !ok { - return nil - } - - name := v.fullName(call) - if name == "" { - return nil - } - - // This will be missing for functions without a receiver (like fmt.Printf), - // so just fall back to the function's fullName in that case. - selection, ok := v.typesInfo.Selections[sel] - if !ok { - return []string{name} - } - - // This will return with ok false if the function isn't defined - // on an interface, so just fall back to the fullName. - ts, ok := walkThroughEmbeddedInterfaces(selection) - if !ok { - return []string{name} - } - - result := make([]string, len(ts)) - for i, t := range ts { - // Like in fullName, vendored packages will have /vendor/ in their name, - // thus not matching vendored standard library packages. If we - // want to support vendored stdlib packages, we need to implement - // additional logic here. - result[i] = fmt.Sprintf("(%s).%s", t.String(), fn.Name()) - } - return result -} - -// isBufferType checks if the expression type is a known in-memory buffer type. -func (v *visitor) argName(expr ast.Expr) string { - // Special-case literal "os.Stdout" and "os.Stderr" - if sel, ok := expr.(*ast.SelectorExpr); ok { - if obj := v.typesInfo.ObjectOf(sel.Sel); obj != nil { - vr, ok := obj.(*types.Var) - if ok && vr.Pkg() != nil && vr.Pkg().Name() == "os" && (vr.Name() == "Stderr" || vr.Name() == "Stdout") { - return "os." + vr.Name() - } - } - } - t := v.typesInfo.TypeOf(expr) - if t == nil { - return "" - } - return t.String() -} - -func (v *visitor) excludeCall(call *ast.CallExpr) bool { - var arg0 string - if len(call.Args) > 0 { - arg0 = v.argName(call.Args[0]) - } - for _, name := range v.namesForExcludeCheck(call) { - if v.exclude[name] { - return true - } - if arg0 != "" && v.exclude[name+"("+arg0+")"] { - return true - } - } - return false -} - -func (v *visitor) ignoreCall(call *ast.CallExpr) bool { - if v.excludeCall(call) { - return true - } - - // Try to get an identifier. - // Currently only supports simple expressions: - // 1. f() - // 2. x.y.f() - var id *ast.Ident - switch exp := call.Fun.(type) { - case *ast.Ident: - id = exp - case *ast.SelectorExpr: - id = exp.Sel - default: - // eg: *ast.SliceExpr, *ast.IndexExpr - } - - if id == nil { - return false - } - - // If we got an identifier for the function, see if it is ignored - if re, ok := v.ignore[""]; ok && re.MatchString(id.Name) { - return true - } - - if obj := v.typesInfo.Uses[id]; obj != nil { - if pkg := obj.Pkg(); pkg != nil { - if re, ok := v.ignore[nonVendoredPkgPath(pkg.Path())]; ok { - return re.MatchString(id.Name) - } - } - } - - return false -} - -// nonVendoredPkgPath returns the unvendored version of the provided package -// path (or returns the provided path if it does not represent a vendored -// path). -func nonVendoredPkgPath(pkgPath string) string { - lastVendorIndex := strings.LastIndex(pkgPath, "/vendor/") - if lastVendorIndex == -1 { - return pkgPath - } - return pkgPath[lastVendorIndex+len("/vendor/"):] -} - -// errorsByArg returns a slice s such that -// len(s) == number of return types of call -// s[i] == true iff return type at position i from left is an error type -func (v *visitor) errorsByArg(call *ast.CallExpr) []bool { - switch t := v.typesInfo.Types[call].Type.(type) { - case *types.Named: - // Single return - return []bool{isErrorType(t)} - case *types.Pointer: - // Single return via pointer - return []bool{isErrorType(t)} - case *types.Tuple: - // Multiple returns - s := make([]bool, t.Len()) - for i := 0; i < t.Len(); i++ { - switch et := t.At(i).Type().(type) { - case *types.Named: - // Single return - s[i] = isErrorType(et) - case *types.Pointer: - // Single return via pointer - s[i] = isErrorType(et) - default: - s[i] = false - } - } - return s - } - return []bool{false} -} - -func (v *visitor) callReturnsError(call *ast.CallExpr) bool { - if v.isRecover(call) { - return true - } - for _, isError := range v.errorsByArg(call) { - if isError { - return true - } - } - return false -} - -// isRecover returns true if the given CallExpr is a call to the built-in recover() function. -func (v *visitor) isRecover(call *ast.CallExpr) bool { - if fun, ok := call.Fun.(*ast.Ident); ok { - if _, ok := v.typesInfo.Uses[fun].(*types.Builtin); ok { - return fun.Name == "recover" - } - } - return false -} - -// TODO (dtcaciuc) collect token.Pos and then convert them to UncheckedErrors -// after visitor is done running. This will allow to integrate more cleanly -// with analyzer so that we don't have to convert Position back to Pos. -func (v *visitor) addErrorAtPosition(position token.Pos, call *ast.CallExpr) { - pos := v.fset.Position(position) - lines, ok := v.lines[pos.Filename] - if !ok { - lines = readfile(pos.Filename) - v.lines[pos.Filename] = lines - } - - line := "??" - if pos.Line-1 < len(lines) { - line = strings.TrimSpace(lines[pos.Line-1]) - } - - var name string - var sel string - if call != nil { - name = v.fullName(call) - sel = v.selectorName(call) - } - - v.errors = append(v.errors, UncheckedError{pos, line, name, sel}) -} - -func readfile(filename string) []string { - var f, err = os.Open(filename) - if err != nil { - return nil - } - defer f.Close() - - var lines []string - var scanner = bufio.NewScanner(f) - for scanner.Scan() { - lines = append(lines, scanner.Text()) - } - return lines -} - -func (v *visitor) Visit(node ast.Node) ast.Visitor { - switch stmt := node.(type) { - case *ast.ExprStmt: - if call, ok := stmt.X.(*ast.CallExpr); ok { - if !v.ignoreCall(call) && v.callReturnsError(call) { - v.addErrorAtPosition(call.Lparen, call) - } - } - case *ast.GoStmt: - if !v.ignoreCall(stmt.Call) && v.callReturnsError(stmt.Call) { - v.addErrorAtPosition(stmt.Call.Lparen, stmt.Call) - } - case *ast.DeferStmt: - if !v.ignoreCall(stmt.Call) && v.callReturnsError(stmt.Call) { - v.addErrorAtPosition(stmt.Call.Lparen, stmt.Call) - } - case *ast.GenDecl: - if stmt.Tok != token.VAR { - break - } - - for _, spec := range stmt.Specs { - vspec := spec.(*ast.ValueSpec) - - if len(vspec.Values) == 0 { - // ignore declarations w/o assignments - continue - } - - var lhs []ast.Expr - for _, name := range vspec.Names { - lhs = append(lhs, ast.Expr(name)) - } - followed := v.checkAssignment(lhs, vspec.Values) - if !followed { - return nil - } - } - - case *ast.AssignStmt: - followed := v.checkAssignment(stmt.Lhs, stmt.Rhs) - if !followed { - return nil - } - - case *ast.TypeAssertExpr: - v.checkAssertExpr(stmt) - return nil - - default: - } - return v -} - -// checkAssignment checks the assignment statement and returns a boolean value -// indicating whether to continue checking the substructure in AssignStmt or not -func (v *visitor) checkAssignment(lhs, rhs []ast.Expr) (followed bool) { - if len(rhs) == 1 { - // single value on rhs; check against lhs identifiers - if call, ok := rhs[0].(*ast.CallExpr); ok { - if !v.blank { - return true - } - if v.ignoreCall(call) { - return true - } - isError := v.errorsByArg(call) - for i := 0; i < len(lhs); i++ { - if id, ok := lhs[i].(*ast.Ident); ok { - // We shortcut calls to recover() because errorsByArg can't - // check its return types for errors since it returns interface{}. - if id.Name == "_" && (v.isRecover(call) || isError[i]) { - v.addErrorAtPosition(id.NamePos, call) - } - } - } - } else if assert, ok := rhs[0].(*ast.TypeAssertExpr); ok { - if !v.asserts { - return false - } - if assert.Type == nil { - // type switch - return false - } - if len(lhs) < 2 { - // assertion result not read - v.addErrorAtPosition(rhs[0].Pos(), nil) - } else if id, ok := lhs[1].(*ast.Ident); ok && v.blank && id.Name == "_" { - // assertion result ignored - v.addErrorAtPosition(id.NamePos, nil) - } - return false - } - } else { - // multiple value on rhs; in this case a call can't return - // multiple values. Assume len(lhs) == len(rhs) - for i := 0; i < len(lhs); i++ { - if id, ok := lhs[i].(*ast.Ident); ok { - if call, ok := rhs[i].(*ast.CallExpr); ok { - if !v.blank { - continue - } - if v.ignoreCall(call) { - continue - } - if id.Name == "_" && v.callReturnsError(call) { - v.addErrorAtPosition(id.NamePos, call) - } - } else if assert, ok := rhs[i].(*ast.TypeAssertExpr); ok { - if !v.asserts { - continue - } - if assert.Type == nil { - // Shouldn't happen anyway, no multi assignment in type switches - continue - } - v.addErrorAtPosition(id.NamePos, nil) - } - } - } - } - - return true -} - -func (v *visitor) checkAssertExpr(expr *ast.TypeAssertExpr) { - if !v.asserts { - return - } - if expr.Type == nil { - // type switch - return - } - v.addErrorAtPosition(expr.Pos(), nil) -} - -func isErrorType(t types.Type) bool { - return types.Implements(t, errorType) -} diff --git a/vendor/github.com/kisielk/errcheck/errcheck/excludes.go b/vendor/github.com/kisielk/errcheck/errcheck/excludes.go deleted file mode 100644 index 450b798e4e..0000000000 --- a/vendor/github.com/kisielk/errcheck/errcheck/excludes.go +++ /dev/null @@ -1,84 +0,0 @@ -package errcheck - -import ( - "bufio" - "bytes" - "os" - "strings" -) - -// DefaultExcludedSymbols is a list of symbol names that are usually excluded from checks by default. -// -// Note, that they still need to be explicitly copied to Checker.Exclusions.Symbols -var DefaultExcludedSymbols = []string{ - // bytes - "(*bytes.Buffer).Write", - "(*bytes.Buffer).WriteByte", - "(*bytes.Buffer).WriteRune", - "(*bytes.Buffer).WriteString", - - // fmt - "fmt.Print", - "fmt.Printf", - "fmt.Println", - "fmt.Fprint(*bytes.Buffer)", - "fmt.Fprintf(*bytes.Buffer)", - "fmt.Fprintln(*bytes.Buffer)", - "fmt.Fprint(*strings.Builder)", - "fmt.Fprintf(*strings.Builder)", - "fmt.Fprintln(*strings.Builder)", - "fmt.Fprint(os.Stderr)", - "fmt.Fprintf(os.Stderr)", - "fmt.Fprintln(os.Stderr)", - - // io - "(*io.PipeReader).CloseWithError", - "(*io.PipeWriter).CloseWithError", - - // math/rand - "math/rand.Read", - "(*math/rand.Rand).Read", - - // strings - "(*strings.Builder).Write", - "(*strings.Builder).WriteByte", - "(*strings.Builder).WriteRune", - "(*strings.Builder).WriteString", - - // hash - "(hash.Hash).Write", - - // hash/maphash - "(*hash/maphash.Hash).Write", - "(*hash/maphash.Hash).WriteByte", - "(*hash/maphash.Hash).WriteString", -} - -// ReadExcludes reads an excludes file, a newline delimited file that lists -// patterns for which to allow unchecked errors. -// -// Lines that start with two forward slashes are considered comments and are ignored. -func ReadExcludes(path string) ([]string, error) { - var excludes []string - - buf, err := os.ReadFile(path) - if err != nil { - return nil, err - } - - scanner := bufio.NewScanner(bytes.NewReader(buf)) - - for scanner.Scan() { - name := scanner.Text() - // Skip comments and empty lines. - if strings.HasPrefix(name, "//") || name == "" { - continue - } - excludes = append(excludes, name) - } - if err := scanner.Err(); err != nil { - return nil, err - } - - return excludes, nil -} diff --git a/vendor/github.com/kkHAIKE/contextcheck/.gitignore b/vendor/github.com/kkHAIKE/contextcheck/.gitignore deleted file mode 100644 index 1c2ffa5f47..0000000000 --- a/vendor/github.com/kkHAIKE/contextcheck/.gitignore +++ /dev/null @@ -1,20 +0,0 @@ -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib - -# Test binary, built with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -# Dependency directories (remove the comment below to include it) -# vendor/ - -.idea -.DS_Store - -/contextcheck diff --git a/vendor/github.com/kkHAIKE/contextcheck/LICENSE b/vendor/github.com/kkHAIKE/contextcheck/LICENSE deleted file mode 100644 index 99e1c482a1..0000000000 --- a/vendor/github.com/kkHAIKE/contextcheck/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2021 sylvia.wang - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/kkHAIKE/contextcheck/Makefile b/vendor/github.com/kkHAIKE/contextcheck/Makefile deleted file mode 100644 index 613d35e939..0000000000 --- a/vendor/github.com/kkHAIKE/contextcheck/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -.PHONY: clean test build - -default: test build - -clean: - rm -rf dist/ cover.out - -test: clean - go test -v -cover ./... - -build: - go build -ldflags '-s -w' -o contextcheck ./cmd/contextcheck/main.go - -install: - go install -ldflags '-s -w' ./cmd/contextcheck diff --git a/vendor/github.com/kkHAIKE/contextcheck/README.md b/vendor/github.com/kkHAIKE/contextcheck/README.md deleted file mode 100644 index 105b2de5a1..0000000000 --- a/vendor/github.com/kkHAIKE/contextcheck/README.md +++ /dev/null @@ -1,157 +0,0 @@ -[![CircleCI](https://circleci.com/gh/sylvia7788/contextcheck.svg?style=svg)](https://circleci.com/gh/sylvia7788/contextcheck) - - -# contextcheck - -`contextcheck` is a static analysis tool used to check whether a function uses a non-inherited context that could result in a broken call link. - -For example: - -```go -func call1(ctx context.Context) { - ... - - ctx = getNewCtx(ctx) - call2(ctx) // OK - - call2(context.Background()) // Non-inherited new context, use function like `context.WithXXX` instead - - call3() // Function `call3` should pass the context parameter - call4() // Function `call4->call3` should pass the context parameter - ... -} - -func call2(ctx context.Context) { - ... -} - -func call3() { - ctx := context.TODO() - call2(ctx) -} - -func call4() { - call3() -} - - -// if you want none-inherit ctx, use this function -func getNewCtx(ctx context.Context) (newCtx context.Context) { - ... - return -} - -/* ---------- check net/http.HandleFunc ---------- */ - -func call5(ctx context.Context, w http.ResponseWriter, r *http.Request) { -} - -func call6(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - call5(ctx, w, r) - call5(context.Background(), w, r) // Non-inherited new context, use function like `context.WithXXX` or `r.Context` instead -} - -func call7(in bool, w http.ResponseWriter, r *http.Request) { - call5(r.Context(), w, r) - call5(context.Background(), w, r) -} - -func call8() { - http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - call5(r.Context(), w, r) - call5(context.Background(), w, r) // Non-inherited new context, use function like `context.WithXXX` or `r.Context` instead - - call6(w, r) - - // call7 should be like `func call7(ctx context.Context, in bool, w http.ResponseWriter, r *http.Request)` - call7(true, w, r) // Function `call7` should pass the context parameter - }) -} -``` - -## Tips -### need break ctx inheritance -eg: [issue](https://github.com/kkHAIKE/contextcheck/issues/2). - -```go -func call1(ctx context.Context) { - ... - - newCtx, cancel := NoInheritCancel(ctx) - defer cancel() - - call2(newCtx) - ... -} - -func call2(ctx context.Context) { - ... -} - -func NoInheritCancel(_ context.Context) (context.Context,context.CancelFunc) { - return context.WithCancel(context.Background()) -} -``` - -### skip the check for the specified function -To skip this linter in some false-positive cases, you can add // nolint: contextcheck to the function declaration's comment. - -```go -// nolint: contextcheck -func call1() { - doSomeThing(context.Background()) // add nolint will no issuss for that -} - -func call2(ctx context.Context) { - call1() -} - -func call3() { - call2(context.Background()) -} -``` - -### force the marking of a specified function as having a server-side http.Request parameter -The default behavior is to mark `http.HandlerFunc` or any function that uses `r.Context()`. - -```go -// @contextcheck(req_has_ctx) -func writeErr(w http.ResponseWriter, r *http.Request, err error) { - doSomeThing(r.Context()) -} - -func handler(w http.ResponseWriter, r *http.Request) { - ... - if err != nil { - writeErr(w, r, err) - return - } - ... -} -``` - -## Installation - -You can get `contextcheck` by `go get` command. - -```bash -$ go get -u github.com/kkHAIKE/contextcheck -``` - -or build yourself. - -```bash -$ make build -$ make install -``` - -## Usage - -Invoke `contextcheck` with your package name - -```bash -$ contextcheck ./... -$ # or -$ go vet -vettool=`which contextcheck` ./... -``` diff --git a/vendor/github.com/kkHAIKE/contextcheck/contextcheck.go b/vendor/github.com/kkHAIKE/contextcheck/contextcheck.go deleted file mode 100644 index c62909a873..0000000000 --- a/vendor/github.com/kkHAIKE/contextcheck/contextcheck.go +++ /dev/null @@ -1,833 +0,0 @@ -package contextcheck - -import ( - "go/ast" - "go/token" - "go/types" - "regexp" - "strings" - "sync" - - "github.com/gostaticanalysis/analysisutil" - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/buildssa" - "golang.org/x/tools/go/packages" - "golang.org/x/tools/go/ssa" -) - -type Configuration struct { - DisableFact bool -} - -var pkgprefix string - -func NewAnalyzer(cfg Configuration) *analysis.Analyzer { - analyzer := &analysis.Analyzer{ - Name: "contextcheck", - Doc: "check whether the function uses a non-inherited context", - Run: NewRun(nil, cfg.DisableFact), - Requires: []*analysis.Analyzer{ - buildssa.Analyzer, - }, - } - analyzer.Flags.StringVar(&pkgprefix, "pkgprefix", "", "filter init pkgs (only for cmd)") - - if !cfg.DisableFact { - analyzer.FactTypes = append(analyzer.FactTypes, (*ctxFact)(nil)) - } - - return analyzer -} - -const ( - ctxPkg = "context" - ctxName = "Context" - - httpPkg = "net/http" - httpRes = "ResponseWriter" - httpReq = "Request" -) - -const ( - CtxIn int = 1 << iota // ctx in function's param - CtxOut // ctx in function's results - CtxInField // ctx in function's field param -) - -type entryType int - -const ( - EntryNone entryType = iota - EntryNormal // without ctx in - EntryWithCtx // has ctx in - EntryWithHttpHandler // is http handler -) - -var ( - pkgFactMap = make(map[*types.Package]ctxFact) - pkgFactMu sync.RWMutex -) - -type element interface { - Pos() token.Pos - Parent() *ssa.Function -} - -type resInfo struct { - Valid bool - Funcs []string - - // reuse for doc - ReqCtx bool - Skip bool - - EntryType entryType -} - -type ctxFact map[string]resInfo - -func (*ctxFact) String() string { return "ctxCheck" } -func (*ctxFact) AFact() {} - -type runner struct { - pass *analysis.Pass - ctxTyp *types.Named - ctxPTyp *types.Pointer - skipFile map[*ast.File]bool - - httpResTyps []types.Type - httpReqTyps []types.Type - - currentFact ctxFact - disableFact bool -} - -func getPkgRoot(pkg string) string { - arr := strings.Split(pkg, "/") - if len(arr) < 3 { - return arr[0] - } - if strings.IndexByte(arr[0], '.') == -1 { - return arr[0] - } - return strings.Join(arr[:3], "/") -} - -func NewRun(pkgs []*packages.Package, disableFact bool) func(pass *analysis.Pass) (interface{}, error) { - m := make(map[string]bool) - for _, pkg := range pkgs { - m[getPkgRoot(pkg.PkgPath)] = true - } - return func(pass *analysis.Pass) (interface{}, error) { - // skip different repo - if len(m) > 0 && !m[getPkgRoot(pass.Pkg.Path())] { - return nil, nil - } - if len(m) == 0 && pkgprefix != "" && !strings.HasPrefix(pass.Pkg.Path(), pkgprefix) { - return nil, nil - } - - r := &runner{disableFact: disableFact} - r.run(pass) - return nil, nil - } -} - -func (r *runner) run(pass *analysis.Pass) { - r.pass = pass - pssa := pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA) - funcs := pssa.SrcFuncs - - // collect ctx obj - var ok bool - r.ctxTyp, r.ctxPTyp, ok = r.getRequiedType(pssa, ctxPkg, ctxName) - if !ok { - return - } - - // collect http obj - r.collectHttpTyps(pssa) - - r.skipFile = make(map[*ast.File]bool) - r.currentFact = make(ctxFact) - - type entryInfo struct { - f *ssa.Function // entryfunc - tp entryType // entrytype - } - var tmpFuncs []entryInfo - for _, f := range funcs { - // skip checked function - key := f.RelString(nil) - if _, ok := r.currentFact[key]; ok { - continue - } - - if entryType := r.checkIsEntry(f); entryType == EntryNormal { - if _, ok := r.getValue(key, f); ok { - continue - } - // record the result of nomal function - checkingMap := make(map[string]bool) - checkingMap[key] = true - r.setFact(key, r.checkFuncWithoutCtx(f, checkingMap), f.Name()) - continue - } else if entryType == EntryWithCtx || entryType == EntryWithHttpHandler { - tmpFuncs = append(tmpFuncs, entryInfo{f: f, tp: entryType}) - } - } - - for _, v := range tmpFuncs { - r.checkFuncWithCtx(v.f, v.tp) - } - - if len(r.currentFact) > 0 { - if r.disableFact { - setPkgFact(pass.Pkg, r.currentFact) - } else { - pass.ExportPackageFact(&r.currentFact) - } - } -} - -func (r *runner) getRequiedType(pssa *buildssa.SSA, path, name string) (obj *types.Named, pobj *types.Pointer, ok bool) { - pkg := pssa.Pkg.Prog.ImportedPackage(path) - if pkg == nil { - return - } - - objTyp := pkg.Type(name) - if objTyp == nil { - return - } - obj, ok = objTyp.Object().Type().(*types.Named) - if !ok { - return - } - pobj = types.NewPointer(obj) - - return -} - -func (r *runner) collectHttpTyps(pssa *buildssa.SSA) { - objRes, _, ok := r.getRequiedType(pssa, httpPkg, httpRes) - if ok { - r.httpResTyps = append(r.httpResTyps, objRes) - } - - _, pobjReq, ok := r.getRequiedType(pssa, httpPkg, httpReq) - if ok { - r.httpReqTyps = append(r.httpReqTyps, pobjReq) - } -} - -func (r *runner) checkIsEntry(f *ssa.Function) (ret entryType) { - // if r.noImportedContextAndHttp(f) { - // return EntryNormal - // } - key := "entry:" + f.RelString(nil) - res, ok := r.getValue(key, f) - if ok { - return res.EntryType - } - defer func() { - r.currentFact[key] = resInfo{EntryType: ret} - }() - - ctxIn, ctxOut := r.checkIsCtx(f) - if ctxOut { - // skip the function which generate ctx - return EntryNone - } else if ctxIn { - // has ctx in, ignore *http.Request.Context() - return EntryWithCtx - } - - reqctx, skip := r.docFlag(f) - - // check is `func handler(w http.ResponseWriter, r *http.Request) {}` - // or use '// @contextcheck(req_has_ctx)' - if r.checkIsHttpHandler(f, reqctx) { - return EntryWithHttpHandler - } - - if skip { - return EntryNone - } - - return EntryNormal -} - -func (r *runner) docFlag(f *ssa.Function) (reqctx, skip bool) { - for _, v := range r.getDocFromFunc(f) { - if len(nolintRe.FindString(v.Text)) > 0 && strings.Contains(v.Text, "contextcheck") { - skip = true - } else if strings.HasPrefix(v.Text, "// @contextcheck(req_has_ctx)") { - reqctx = true - } - } - return -} - -var nolintRe = regexp.MustCompile(`^//\s?nolint:`) - -func (r *runner) getDocFromFunc(f *ssa.Function) []*ast.Comment { - file := analysisutil.File(r.pass, f.Pos()) - if file == nil { - return nil - } - - // only support FuncDecl comment - var fd *ast.FuncDecl - for _, v := range file.Decls { - if tmp, ok := v.(*ast.FuncDecl); ok && tmp.Name.Pos() == f.Pos() { - fd = tmp - break - } - } - if fd == nil || fd.Doc == nil || len(fd.Doc.List) == 0 { - return nil - } - return fd.Doc.List -} - -func (r *runner) checkIsCtx(f *ssa.Function) (in, out bool) { - // check params - tuple := f.Signature.Params() - for i := 0; i < tuple.Len(); i++ { - if r.isCtxType(tuple.At(i).Type()) { - in = true - break - } - } - - // check freevars - for _, param := range f.FreeVars { - if r.isCtxType(param.Type()) { - in = true - break - } - } - - // check results - tuple = f.Signature.Results() - for i := 0; i < tuple.Len(); i++ { - if r.isCtxType(tuple.At(i).Type()) { - out = true - break - } - } - return -} - -func (r *runner) checkIsHttpHandler(f *ssa.Function, reqctx bool) bool { - var hasReq bool - tuple := f.Signature.Params() - for i := 0; i < tuple.Len(); i++ { - if r.isHttpReqType(tuple.At(i).Type()) { - hasReq = true - break - } - } - if !hasReq { - return false - } - if reqctx { - return true - } - - // must be `func f(w http.ResponseWriter, r *http.Request) {}` - if f.Signature.Results().Len() == 0 && tuple.Len() == 2 && - r.isHttpResType(tuple.At(0).Type()) && r.isHttpReqType(tuple.At(1).Type()) { - return true - } - - // check if use r.Context() - return f.Blocks != nil && len(r.getHttpReqCtx(f, true)) > 0 -} - -func (r *runner) collectCtxRef(f *ssa.Function, isHttpHandler bool) (refMap map[ssa.Instruction]bool, ok bool) { - ok = true - refMap = make(map[ssa.Instruction]bool) - checkedRefMap := make(map[ssa.Value]bool) - storeInstrs := make(map[*ssa.Store]bool) - phiInstrs := make(map[*ssa.Phi]bool) - - var checkRefs func(val ssa.Value, fromAddr bool) - var checkInstr func(instr ssa.Instruction, fromAddr bool) - - checkRefs = func(val ssa.Value, fromAddr bool) { - if val == nil || val.Referrers() == nil { - return - } - - if checkedRefMap[val] { - return - } - checkedRefMap[val] = true - - for _, instr := range *val.Referrers() { - checkInstr(instr, fromAddr) - } - } - - checkInstr = func(instr ssa.Instruction, fromAddr bool) { - switch i := instr.(type) { - case ssa.CallInstruction: - refMap[i] = true - tp := r.getCallInstrCtxType(i) - if tp&CtxOut != 0 { - // collect referrers of the results - checkRefs(i.Value(), false) - return - } - case *ssa.Store: - if fromAddr { - // collect all store to judge whether it's right value is valid - storeInstrs[i] = true - } else { - checkRefs(i.Addr, true) - } - case *ssa.UnOp: - checkRefs(i, false) - case *ssa.MakeClosure: - for _, param := range i.Bindings { - if r.isCtxType(param.Type()) { - refMap[i] = true - break - } - } - case *ssa.Extract: - // only care about ctx - if r.isCtxType(i.Type()) { - checkRefs(i, false) - } - case *ssa.Phi: - phiInstrs[i] = true - checkRefs(i, false) - case *ssa.TypeAssert: - // ctx.(*bm.Context) - } - } - - if isHttpHandler { - for _, v := range r.getHttpReqCtx(f, false) { - checkRefs(v, false) - } - } else { - for _, param := range f.Params { - if r.isCtxType(param.Type()) { - checkRefs(param, false) - } - } - - for _, param := range f.FreeVars { - if r.isCtxType(param.Type()) { - checkRefs(param, false) - } - } - } - - for instr := range storeInstrs { - if !checkedRefMap[instr.Val] { - r.Reportf(instr, "Non-inherited new context, use function like `context.WithXXX` instead") - ok = false - } - } - - for instr := range phiInstrs { - for _, v := range instr.Edges { - if !checkedRefMap[v] { - r.Reportf(instr, "Non-inherited new context, use function like `context.WithXXX` instead") - ok = false - } - } - } - - return -} - -func (r *runner) getHttpReqCtx(f *ssa.Function, least1 bool) (rets []ssa.Value) { - checkedRefMap := make(map[ssa.Value]bool) - - var checkRefs func(val ssa.Value, fromAddr bool) - var checkInstr func(instr ssa.Instruction, fromAddr bool) - - checkRefs = func(val ssa.Value, fromAddr bool) { - if val == nil || val.Referrers() == nil { - return - } - - if checkedRefMap[val] { - return - } - checkedRefMap[val] = true - - for _, instr := range *val.Referrers() { - checkInstr(instr, fromAddr) - } - } - - checkInstr = func(instr ssa.Instruction, fromAddr bool) { - switch i := instr.(type) { - case ssa.CallInstruction: - // r.Context() only has one recv - if len(i.Common().Args) != 1 { - break - } - - // find r.Context() - if r.getCallInstrCtxType(i)&CtxOut != CtxOut { - break - } - - // check is r.Context - f := r.getFunction(instr) - if f == nil || f.Name() != ctxName { - break - } - if f.Signature.Recv() != nil { - // collect the return of r.Context - rets = append(rets, i.Value()) - if least1 { - return - } - } - case *ssa.Store: - if !fromAddr { - checkRefs(i.Addr, true) - } - case *ssa.UnOp: - checkRefs(i, false) - case *ssa.Phi: - checkRefs(i, false) - case *ssa.MakeClosure: - case *ssa.Extract: - // http.Request can only be input - } - } - - for _, param := range f.Params { - if r.isHttpReqType(param.Type()) { - checkRefs(param, false) - } - } - - return -} - -func (r *runner) checkFuncWithCtx(f *ssa.Function, tp entryType) { - isHttpHandler := tp == EntryWithHttpHandler - refMap, ok := r.collectCtxRef(f, isHttpHandler) - if !ok { - return - } - - for _, b := range f.Blocks { - for _, instr := range b.Instrs { - tp, ok := r.getCtxType(instr) - if !ok { - continue - } - - // checked in collectCtxRef, skipped - if tp&CtxOut != 0 { - continue - } - - if tp&CtxIn != 0 { - if !refMap[instr] { - if isHttpHandler { - r.Reportf(instr, "Non-inherited new context, use function like `context.WithXXX` or `r.Context` instead") - } else { - r.Reportf(instr, "Non-inherited new context, use function like `context.WithXXX` instead") - } - } - } - - ff := r.getFunction(instr) - if ff == nil { - continue - } - - key := ff.RelString(nil) - res, ok := r.getValue(key, ff) - if ok && !res.Valid { - if instr.Pos().IsValid() { - r.Reportf(instr, "Function `%s` should pass the context parameter", strings.Join(reverse(res.Funcs), "->")) - } else { - r.Reportf(ff, "Function `%s` should pass the context parameter", strings.Join(reverse(res.Funcs), "->")) - } - } - } - } -} - -func (r *runner) checkFuncWithoutCtx(f *ssa.Function, checkingMap map[string]bool) (ret bool) { - ret = true - orgKey := f.RelString(nil) - var seted bool - for _, b := range f.Blocks { - for _, instr := range b.Instrs { - tp, ok := r.getCtxType(instr) - if !ok { - continue - } - - if tp&CtxOut != 0 { - continue - } - - // it is considered illegal as long as ctx is in the input and not in *struct X - if tp&CtxIn != 0 { - if tp&CtxInField == 0 { - ret = false - } - } - - ff := r.getFunction(instr) - if ff == nil { - continue - } - - key := ff.RelString(nil) - res, ok := r.getValue(key, ff) - if ok { - if !res.Valid { - ret = false - - // save the call link - if !seted { - seted = true - r.setFact(orgKey, res.Valid, res.Funcs...) - } - } - continue - } - - // check is thunk or bound - if strings.HasSuffix(key, "$thunk") || strings.HasSuffix(key, "$bound") { - continue - } - - if entryType := r.checkIsEntry(ff); entryType == EntryNormal { - // cannot get info from fact, skip - if ff.Blocks == nil { - continue - } - - // handler cycle call - if checkingMap[key] { - continue - } - checkingMap[key] = true - - valid := r.checkFuncWithoutCtx(ff, checkingMap) - r.setFact(key, valid, ff.Name()) - if res, ok := r.getValue(key, ff); ok && !valid && !seted { - seted = true - r.setFact(orgKey, valid, res.Funcs...) - } - if !valid { - ret = false - } - } - } - } - return ret -} - -func (r *runner) getCtxType(instr ssa.Instruction) (tp int, ok bool) { - switch i := instr.(type) { - case ssa.CallInstruction: - tp = r.getCallInstrCtxType(i) - ok = true - case *ssa.MakeClosure: - tp = r.getMakeClosureCtxType(i) - ok = true - } - return -} - -func (r *runner) getCallInstrCtxType(c ssa.CallInstruction) (tp int) { - // check params - for _, v := range c.Common().Args { - if r.isCtxType(v.Type()) { - if vv, ok := v.(*ssa.UnOp); ok { - if _, ok := vv.X.(*ssa.FieldAddr); ok { - tp |= CtxInField - } - } - - tp |= CtxIn - break - } - } - - // check results - if v := c.Value(); v != nil { - if r.isCtxType(v.Type()) { - tp |= CtxOut - } else { - tuple, ok := v.Type().(*types.Tuple) - if !ok { - return - } - for i := 0; i < tuple.Len(); i++ { - if r.isCtxType(tuple.At(i).Type()) { - tp |= CtxOut - break - } - } - } - } - - return -} - -func (r *runner) getMakeClosureCtxType(c *ssa.MakeClosure) (tp int) { - for _, v := range c.Bindings { - if r.isCtxType(v.Type()) { - if vv, ok := v.(*ssa.UnOp); ok { - if _, ok := vv.X.(*ssa.FieldAddr); ok { - tp |= CtxInField - } - } - - tp |= CtxIn - break - } - } - return -} - -func (r *runner) getFunction(instr ssa.Instruction) (f *ssa.Function) { - switch i := instr.(type) { - case ssa.CallInstruction: - if i.Common().IsInvoke() { - return - } - - switch c := i.Common().Value.(type) { - case *ssa.Function: - f = c - case *ssa.MakeClosure: - // captured in the outer layer - case *ssa.Builtin, *ssa.UnOp, *ssa.Lookup, *ssa.Phi: - // skipped - case *ssa.Extract, *ssa.Call: - // function is a result of a call, skipped - case *ssa.Parameter: - // function is a param, skipped - } - case *ssa.MakeClosure: - f = i.Fn.(*ssa.Function) - } - return -} - -func (r *runner) isCtxType(tp types.Type) bool { - if p, ok := tp.(*types.Pointer); ok { - // opaqueType is not exposed and lead to unreachable error. - // Related to https://github.com/golang/tools/blob/63229bc79404d8cf2fe4e88ad569168fe251d993/go/ssa/builder.go#L107 - if p.Elem().String() == "deferStack" { - return false - } - } - - return types.Identical(tp, r.ctxTyp) || types.Identical(tp, r.ctxPTyp) -} - -func (r *runner) isHttpResType(tp types.Type) bool { - for _, v := range r.httpResTyps { - if ok := types.Identical(v, v); ok { - return true - } - } - return false -} - -func (r *runner) isHttpReqType(tp types.Type) bool { - for _, v := range r.httpReqTyps { - if ok := types.Identical(tp, v); ok { - return true - } - } - return false -} - -func (r *runner) getValue(key string, f *ssa.Function) (res resInfo, ok bool) { - res, ok = r.currentFact[key] - if ok { - return - } - - if f.Pkg == nil { - return - } - - var fact ctxFact - var got bool - if r.disableFact { - fact, got = getPkgFact(f.Pkg.Pkg) - } else { - got = r.pass.ImportPackageFact(f.Pkg.Pkg, &fact) - } - if got { - res, ok = fact[key] - } - return -} - -func (r *runner) setFact(key string, valid bool, funcs ...string) { - var names []string - if !valid { - names = append(r.currentFact[key].Funcs, funcs...) - } - r.currentFact[key] = resInfo{ - Valid: valid, - Funcs: names, - } -} - -func (r *runner) Reportf(instr element, format string, args ...interface{}) { - pos := instr.Pos() - - if !pos.IsValid() && instr.Parent() != nil { - pos = instr.Parent().Pos() - } - - if !pos.IsValid() { - return - } - - r.pass.Reportf(pos, format, args...) -} - -// setPkgFact save fact to mem -func setPkgFact(pkg *types.Package, fact ctxFact) { - pkgFactMu.Lock() - pkgFactMap[pkg] = fact - pkgFactMu.Unlock() -} - -// getPkgFact get fact from mem -func getPkgFact(pkg *types.Package) (fact ctxFact, ok bool) { - pkgFactMu.RLock() - fact, ok = pkgFactMap[pkg] - pkgFactMu.RUnlock() - return -} - -func reverse(arr1 []string) (arr2 []string) { - l := len(arr1) - if l == 0 { - return - } - arr2 = make([]string, l) - for i := 0; i <= l/2; i++ { - arr2[i] = arr1[l-1-i] - arr2[l-1-i] = arr1[i] - } - return -} diff --git a/vendor/github.com/kulti/thelper/LICENSE b/vendor/github.com/kulti/thelper/LICENSE deleted file mode 100644 index e070215fe2..0000000000 --- a/vendor/github.com/kulti/thelper/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2020 Aleksey Bakin - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/kulti/thelper/pkg/analyzer/analyzer.go b/vendor/github.com/kulti/thelper/pkg/analyzer/analyzer.go deleted file mode 100644 index 5a2d0f89d9..0000000000 --- a/vendor/github.com/kulti/thelper/pkg/analyzer/analyzer.go +++ /dev/null @@ -1,735 +0,0 @@ -// Package analyzer implements the thelper linter logic. -package analyzer - -import ( - "flag" - "fmt" - "go/ast" - "go/token" - "go/types" - "sort" - "strings" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/inspector" -) - -const ( - doc = "thelper detects tests helpers which do not start with the t.Helper() method." - - checksDoc = `coma separated list of enabled checks - -Available checks - -` + checkTBegin + ` - check t.Helper() begins helper function -` + checkTFirst + ` - check *testing.T is first param of helper function -` + checkTName + ` - check *testing.T param has t name - -Also available similar checks for benchmark and TB helpers: ` + - checkFBegin + `, ` + checkFFirst + `, ` + checkFName + `,` + - checkBBegin + `, ` + checkBFirst + `, ` + checkBName + `,` + - checkTBBegin + `, ` + checkTBFirst + `, ` + checkTBName + ` - -` -) - -type enabledChecksValue map[string]struct{} - -func (m enabledChecksValue) Enabled(c string) bool { - _, ok := m[c] - return ok -} - -func (m enabledChecksValue) String() string { - ss := make([]string, 0, len(m)) - for s := range m { - ss = append(ss, s) - } - - sort.Strings(ss) - - return strings.Join(ss, ",") -} - -func (m enabledChecksValue) Set(s string) error { - ss := strings.FieldsFunc(s, func(c rune) bool { return c == ',' }) - if len(ss) == 0 { - return nil - } - - for k := range m { - delete(m, k) - } - - for _, v := range ss { - switch v { - case checkTBegin, checkTFirst, checkTName, - checkFBegin, checkFFirst, checkFName, - checkBBegin, checkBFirst, checkBName, - checkTBBegin, checkTBFirst, checkTBName: - m[v] = struct{}{} - default: - return fmt.Errorf("unknown check name %q (see help for full list)", v) - } - } - - return nil -} - -const ( - checkTBegin = "t_begin" - checkTFirst = "t_first" - checkTName = "t_name" - checkFBegin = "f_begin" - checkFFirst = "f_first" - checkFName = "f_name" - checkBBegin = "b_begin" - checkBFirst = "b_first" - checkBName = "b_name" - checkTBBegin = "tb_begin" - checkTBFirst = "tb_first" - checkTBName = "tb_name" -) - -type thelper struct { - enabledChecks enabledChecksValue -} - -// NewAnalyzer return a new thelper analyzer. -// thelper analyzes Go test codes how they use t.Helper() method. -func NewAnalyzer() *analysis.Analyzer { - thelper := thelper{} - thelper.enabledChecks = enabledChecksValue{ - checkTBegin: struct{}{}, - checkTFirst: struct{}{}, - checkTName: struct{}{}, - checkFBegin: struct{}{}, - checkFFirst: struct{}{}, - checkFName: struct{}{}, - checkBBegin: struct{}{}, - checkBFirst: struct{}{}, - checkBName: struct{}{}, - checkTBBegin: struct{}{}, - checkTBFirst: struct{}{}, - checkTBName: struct{}{}, - } - - a := &analysis.Analyzer{ - Name: "thelper", - Doc: doc, - Run: thelper.run, - Requires: []*analysis.Analyzer{ - inspect.Analyzer, - }, - } - - a.Flags.Init("thelper", flag.ExitOnError) - a.Flags.Var(&thelper.enabledChecks, "checks", checksDoc) - - return a -} - -//nolint:funlen // The function is easier to grok this way. -func (t thelper) run(pass *analysis.Pass) (interface{}, error) { - tCheckOpts, fCheckOpts, bCheckOpts, tbCheckOpts, ok := t.buildCheckFuncOpts(pass) - if !ok { - return nil, nil - } - - inspect, ok := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - if !ok { - return nil, nil - } - - var reports reports - - nodeFilter := []ast.Node{ - (*ast.FuncDecl)(nil), - (*ast.FuncLit)(nil), - (*ast.CallExpr)(nil), - } - inspect.Preorder(nodeFilter, func(node ast.Node) { - var fd funcDecl - - switch n := node.(type) { - case *ast.FuncLit: - fd.Pos = n.Pos() - fd.Type = n.Type - fd.Body = n.Body - fd.Name = ast.NewIdent("") - case *ast.FuncDecl: - fd.Pos = n.Name.NamePos - fd.Type = n.Type - fd.Body = n.Body - fd.Name = n.Name - case *ast.CallExpr: - runSubtestExprs := extractSubtestExp(pass, n, tCheckOpts.subRun, tCheckOpts.subTestFuncType) - - if len(runSubtestExprs) == 0 { - runSubtestExprs = extractSubtestExp(pass, n, bCheckOpts.subRun, bCheckOpts.subTestFuncType) - } - - if len(runSubtestExprs) == 0 { - runSubtestExprs = extractSubtestFuzzExp(pass, n, fCheckOpts.subRun) - } - - if len(runSubtestExprs) == 0 { - runSubtestExprs = extractSynctestExp(pass, n, tCheckOpts.subTestFuncType) - } - - if len(runSubtestExprs) > 0 { - for _, expr := range runSubtestExprs { - reports.Filter(funcDefPosition(pass, expr)) - } - } else { - reports.NoFilter(funcDefPosition(pass, n.Fun)) - } - - return - default: - return - } - - checkFunc(pass, &reports, fd, tCheckOpts) - checkFunc(pass, &reports, fd, fCheckOpts) - checkFunc(pass, &reports, fd, bCheckOpts) - checkFunc(pass, &reports, fd, tbCheckOpts) - }) - - reports.Flush(pass) - - return nil, nil -} - -type checkFuncOpts struct { - skipPrefix string - varName string - fnHelper types.Object - subRun types.Object - subTestFuncType types.Type - hpType types.Type - ctxType types.Type - checkBegin bool - checkFirst bool - checkName bool -} - -func (t thelper) buildCheckFuncOpts(pass *analysis.Pass) (checkFuncOpts, checkFuncOpts, checkFuncOpts, checkFuncOpts, bool) { - var ctxType types.Type - - ctxObj := findTypeObject(pass, "context.Context") - if ctxObj != nil { - ctxType = ctxObj.Type() - } - - tCheckOpts, ok := t.buildTestCheckFuncOpts(pass, ctxType) - if !ok { - return checkFuncOpts{}, checkFuncOpts{}, checkFuncOpts{}, checkFuncOpts{}, false - } - - fCheckOpts, ok := t.buildFuzzCheckFuncOpts(pass, ctxType) - if !ok { - return checkFuncOpts{}, checkFuncOpts{}, checkFuncOpts{}, checkFuncOpts{}, false - } - - bCheckOpts, ok := t.buildBenchmarkCheckFuncOpts(pass, ctxType) - if !ok { - return checkFuncOpts{}, checkFuncOpts{}, checkFuncOpts{}, checkFuncOpts{}, false - } - - tbCheckOpts, ok := t.buildTBCheckFuncOpts(pass, ctxType) - if !ok { - return checkFuncOpts{}, checkFuncOpts{}, checkFuncOpts{}, checkFuncOpts{}, false - } - - return tCheckOpts, fCheckOpts, bCheckOpts, tbCheckOpts, true -} - -func (t thelper) buildTestCheckFuncOpts(pass *analysis.Pass, ctxType types.Type) (checkFuncOpts, bool) { - tObj := findTypeObject(pass, "testing.T") - if tObj == nil { - return checkFuncOpts{}, false - } - - tHelper, _, _ := types.LookupFieldOrMethod(tObj.Type(), true, tObj.Pkg(), "Helper") - if tHelper == nil { - return checkFuncOpts{}, false - } - - tRun, _, _ := types.LookupFieldOrMethod(tObj.Type(), true, tObj.Pkg(), "Run") - if tRun == nil { - return checkFuncOpts{}, false - } - - tType := types.NewPointer(tObj.Type()) - tVar := types.NewVar(token.NoPos, nil, "t", tType) - - return checkFuncOpts{ - skipPrefix: "Test", - varName: "t", - fnHelper: tHelper, - subRun: tRun, - hpType: tType, - subTestFuncType: types.NewSignatureType(nil, nil, nil, types.NewTuple(tVar), nil, false), - ctxType: ctxType, - checkBegin: t.enabledChecks.Enabled(checkTBegin), - checkFirst: t.enabledChecks.Enabled(checkTFirst), - checkName: t.enabledChecks.Enabled(checkTName), - }, true -} - -func (t thelper) buildFuzzCheckFuncOpts(pass *analysis.Pass, ctxType types.Type) (checkFuncOpts, bool) { - fObj := findTypeObject(pass, "testing.F") - if fObj == nil { - return checkFuncOpts{}, true // fuzzing supports since go1.18, it's ok, that testig.F is missed. - } - - fHelper, _, _ := types.LookupFieldOrMethod(fObj.Type(), true, fObj.Pkg(), "Helper") - if fHelper == nil { - return checkFuncOpts{}, false - } - - tFuzz, _, _ := types.LookupFieldOrMethod(fObj.Type(), true, fObj.Pkg(), "Fuzz") - if tFuzz == nil { - return checkFuncOpts{}, false - } - - return checkFuncOpts{ - skipPrefix: "Fuzz", - varName: "f", - fnHelper: fHelper, - subRun: tFuzz, - hpType: types.NewPointer(fObj.Type()), - ctxType: ctxType, - checkBegin: t.enabledChecks.Enabled(checkFBegin), - checkFirst: t.enabledChecks.Enabled(checkFFirst), - checkName: t.enabledChecks.Enabled(checkFName), - }, true -} - -func (t thelper) buildBenchmarkCheckFuncOpts(pass *analysis.Pass, ctxType types.Type) (checkFuncOpts, bool) { - bObj := findTypeObject(pass, "testing.B") - if bObj == nil { - return checkFuncOpts{}, false - } - - bHelper, _, _ := types.LookupFieldOrMethod(bObj.Type(), true, bObj.Pkg(), "Helper") - if bHelper == nil { - return checkFuncOpts{}, false - } - - bRun, _, _ := types.LookupFieldOrMethod(bObj.Type(), true, bObj.Pkg(), "Run") - if bRun == nil { - return checkFuncOpts{}, false - } - - bType := types.NewPointer(bObj.Type()) - bVar := types.NewVar(token.NoPos, nil, "b", bType) - - return checkFuncOpts{ - skipPrefix: "Benchmark", - varName: "b", - fnHelper: bHelper, - subRun: bRun, - hpType: types.NewPointer(bObj.Type()), - subTestFuncType: types.NewSignatureType(nil, nil, nil, types.NewTuple(bVar), nil, false), - ctxType: ctxType, - checkBegin: t.enabledChecks.Enabled(checkBBegin), - checkFirst: t.enabledChecks.Enabled(checkBFirst), - checkName: t.enabledChecks.Enabled(checkBName), - }, true -} - -func (t thelper) buildTBCheckFuncOpts(pass *analysis.Pass, ctxType types.Type) (checkFuncOpts, bool) { - tbObj := findTypeObject(pass, "testing.TB") - if tbObj == nil { - return checkFuncOpts{}, false - } - - tbHelper, _, _ := types.LookupFieldOrMethod(tbObj.Type(), true, tbObj.Pkg(), "Helper") - if tbHelper == nil { - return checkFuncOpts{}, false - } - - return checkFuncOpts{ - skipPrefix: "", - varName: "tb", - fnHelper: tbHelper, - hpType: tbObj.Type(), - ctxType: ctxType, - checkBegin: t.enabledChecks.Enabled(checkTBBegin), - checkFirst: t.enabledChecks.Enabled(checkTBFirst), - checkName: t.enabledChecks.Enabled(checkTBName), - }, true -} - -type funcDecl struct { - Pos token.Pos - Name *ast.Ident - Type *ast.FuncType - Body *ast.BlockStmt -} - -func checkFunc(pass *analysis.Pass, reports *reports, funcDecl funcDecl, opts checkFuncOpts) { - if !opts.checkFirst && !opts.checkBegin && !opts.checkName { - return - } - - if opts.skipPrefix != "" && strings.HasPrefix(funcDecl.Name.Name, opts.skipPrefix) { - return - } - - p, pos, ok := searchFuncParam(pass, funcDecl, opts.hpType) - if !ok { - return - } - - if opts.checkFirst { - if pos != 0 { - checkFirstPassed := false - - if pos == 1 && opts.ctxType != nil { - _, pos, ok := searchFuncParam(pass, funcDecl, opts.ctxType) - checkFirstPassed = ok && (pos == 0) - } - - if !checkFirstPassed { - reports.Reportf(funcDecl.Pos, "parameter %s should be the first or after context.Context", opts.hpType) - } - } - } - - if len(p.Names) > 0 && p.Names[0].Name != "_" { - if opts.checkName { - if p.Names[0].Name != opts.varName { - reports.Reportf(funcDecl.Pos, "parameter %s should have name %s", opts.hpType, opts.varName) - } - } - - if opts.checkBegin { - if len(funcDecl.Body.List) == 0 || !isTHelperCall(pass, funcDecl.Body.List[0], opts.fnHelper) { - reports.Reportf(funcDecl.Pos, "test helper function should start from %s.Helper()", opts.varName) - } - } - } -} - -// searchFuncParam search a function param with desired type. -// It returns the param field, its position, and true if something is found. -func searchFuncParam(pass *analysis.Pass, f funcDecl, p types.Type) (*ast.Field, int, bool) { - for i, f := range f.Type.Params.List { - if isExprHasType(pass, f.Type, p) { - return f, i, true - } - } - - return nil, 0, false -} - -// isTHelperCall returns true if provided statement 's' is t.Helper() or b.Helper() call. -func isTHelperCall(pass *analysis.Pass, s ast.Stmt, tHelper types.Object) bool { - exprStmt, ok := s.(*ast.ExprStmt) - if !ok { - return false - } - - callExpr, ok := exprStmt.X.(*ast.CallExpr) - if !ok { - return false - } - - selExpr, ok := callExpr.Fun.(*ast.SelectorExpr) - if !ok { - return false - } - - return isSelectorCall(pass, selExpr, tHelper) -} - -// extractSubtestExp analyzes that call expresion 'e' is t.Run or b.Run -// and returns subtest function. -func extractSubtestExp( - pass *analysis.Pass, e *ast.CallExpr, tbRun types.Object, testFuncType types.Type, -) []ast.Expr { - selExpr, ok := e.Fun.(*ast.SelectorExpr) - if !ok { - return nil - } - - if !isSelectorCall(pass, selExpr, tbRun) { - return nil - } - - if len(e.Args) != 2 { - return nil - } - - if funcs := unwrapTestingFunctionBuilding(pass, e.Args[1], testFuncType); funcs != nil { - return funcs - } - - return []ast.Expr{e.Args[1]} -} - -// extractSubtestFuzzExp analyzes that call expresion 'e' is f.Fuzz -// and returns subtest function. -func extractSubtestFuzzExp( - pass *analysis.Pass, e *ast.CallExpr, fuzzRun types.Object, -) []ast.Expr { - selExpr, ok := e.Fun.(*ast.SelectorExpr) - if !ok { - return nil - } - - if !isSelectorCall(pass, selExpr, fuzzRun) { - return nil - } - - if len(e.Args) != 1 { - return nil - } - - return []ast.Expr{e.Args[0]} -} - -// extractSynctestExp analyzes that call expression 'e' is synctest.Test -// and returns the test function. -func extractSynctestExp( - pass *analysis.Pass, e *ast.CallExpr, testFuncType types.Type, -) []ast.Expr { - // Check if this is a call to synctest.Test - selExpr, ok := e.Fun.(*ast.SelectorExpr) - if !ok { - return nil - } - - // Check if the selector is "Test" - if selExpr.Sel.Name != "Test" { - return nil - } - - // Check if the package is synctest by looking at the identifier - ident, ok := selExpr.X.(*ast.Ident) - if !ok { - return nil - } - - if !isIdentPackageName(pass, ident, "testing/synctest") { - return nil - } - - // synctest.Test takes 2 arguments: t *testing.T, f func(*testing.T) - if len(e.Args) != 2 { - return nil - } - - if funcs := unwrapTestingFunctionBuilding(pass, e.Args[1], testFuncType); funcs != nil { - return funcs - } - - return []ast.Expr{e.Args[1]} -} - -// unwrapTestingFunctionConstruction checks that expresion is build testing functions -// and returns the result of building. -func unwrapTestingFunctionBuilding(pass *analysis.Pass, expr ast.Expr, testFuncType types.Type) []ast.Expr { - callExpr, ok := expr.(*ast.CallExpr) - if !ok { - return nil - } - - var funcDecl funcDecl - - switch f := callExpr.Fun.(type) { - case *ast.FuncLit: - funcDecl.Body = f.Body - funcDecl.Type = f.Type - case *ast.Ident: - funObjDecl := findFunctionDeclaration(pass, f) - if funObjDecl == nil { - return nil - } - - funcDecl.Body = funObjDecl.Body - funcDecl.Type = funObjDecl.Type - case *ast.SelectorExpr: - fd := findSelectorDeclaration(pass, f) - if fd == nil { - return nil - } - - funcDecl.Body = fd.Body - funcDecl.Type = fd.Type - default: - return nil - } - - results := funcDecl.Type.Results.List - if len(results) != 1 || !isExprHasType(pass, results[0].Type, testFuncType) { - return nil - } - - var funcs []ast.Expr - - ast.Inspect(funcDecl.Body, func(n ast.Node) bool { - if n == nil { - return false - } - - if retStmt, ok := n.(*ast.ReturnStmt); ok { - if len(retStmt.Results) == 1 { - funcs = append(funcs, retStmt.Results[0]) - } - } - - return true - }) - - return funcs -} - -// funcDefPosition returns a function's position. -// It works with anonymous functions as well with function names. -func funcDefPosition(pass *analysis.Pass, e ast.Expr) token.Pos { - anonFunLit, ok := e.(*ast.FuncLit) - if ok { - return anonFunLit.Pos() - } - - funIdent, ok := e.(*ast.Ident) - if !ok { - selExpr, ok := e.(*ast.SelectorExpr) - if !ok { - return token.NoPos - } - - funIdent = selExpr.Sel - } - - funDef, ok := pass.TypesInfo.Uses[funIdent] - if !ok { - return token.NoPos - } - - return funDef.Pos() -} - -// isSelectorCall checks is selExpr is a call expresion on specific callObj. -// Useful to check Run() call for t.Run or b.Run. -func isSelectorCall(pass *analysis.Pass, selExpr *ast.SelectorExpr, callObj types.Object) bool { - sel, ok := pass.TypesInfo.Selections[selExpr] - if !ok { - return false - } - - return sel.Obj() == callObj -} - -// isExprHasType returns true if expr has expected type. -func isExprHasType(pass *analysis.Pass, expr ast.Expr, expType types.Type) bool { - typeInfo, ok := pass.TypesInfo.Types[expr] - if !ok { - return false - } - - return types.Identical(typeInfo.Type, expType) -} - -// isIdentPackageName returns true if ident refers to the specified package. -func isIdentPackageName(pass *analysis.Pass, ident *ast.Ident, pkgName string) bool { - obj := pass.TypesInfo.Uses[ident] - if obj == nil { - return false - } - - pkgObj, ok := obj.(*types.PkgName) - if !ok { - return false - } - - return pkgObj.Imported().Path() == pkgName -} - -// findSelectorDeclaration returns function declaration called by selector expression. -func findSelectorDeclaration(pass *analysis.Pass, expr *ast.SelectorExpr) *ast.FuncDecl { - xsel, ok := pass.TypesInfo.Selections[expr] - if !ok { - return nil - } - - for _, file := range pass.Files { - for _, decl := range file.Decls { - fd, ok := decl.(*ast.FuncDecl) - if ok && fd.Recv != nil && len(fd.Recv.List) == 1 { - recvType, ok := fd.Recv.List[0].Type.(*ast.Ident) - if !ok { - continue - } - - recvObj, ok := pass.TypesInfo.Uses[recvType] - if !ok { - continue - } - - if !(types.Identical(recvObj.Type(), xsel.Recv())) { - continue - } - - if fd.Name.Name == expr.Sel.Name { - return fd - } - } - } - } - - return nil -} - -// findFunctionDeclaration returns function declaration called by identity. -func findFunctionDeclaration(pass *analysis.Pass, ident *ast.Ident) *ast.FuncDecl { - if ident.Obj != nil { - if funObjDecl, ok := ident.Obj.Decl.(*ast.FuncDecl); ok { - return funObjDecl - } - } - - obj := pass.TypesInfo.ObjectOf(ident) - if obj == nil { - return nil - } - - for _, file := range pass.Files { - for _, decl := range file.Decls { - funcDecl, ok := decl.(*ast.FuncDecl) - if !ok { - continue - } - - if funcDecl.Name.Pos() == obj.Pos() { - return funcDecl - } - } - } - - return nil -} - -func findTypeObject(pass *analysis.Pass, typeName string) types.Object { - parts := strings.Split(typeName, ".") - pkgName := parts[0] - typeName = parts[1] - - for _, pkg := range pass.Pkg.Imports() { - if pkg.Name() != pkgName { - continue - } - - obj := pkg.Scope().Lookup(typeName) - if obj != nil { - return obj - } - } - - return nil -} diff --git a/vendor/github.com/kulti/thelper/pkg/analyzer/report.go b/vendor/github.com/kulti/thelper/pkg/analyzer/report.go deleted file mode 100644 index 3ee3327428..0000000000 --- a/vendor/github.com/kulti/thelper/pkg/analyzer/report.go +++ /dev/null @@ -1,59 +0,0 @@ -package analyzer - -import ( - "go/token" - - "golang.org/x/tools/go/analysis" -) - -type reports struct { - reports []report - filter map[token.Pos]struct{} - nofilter map[token.Pos]struct{} -} - -type report struct { - pos token.Pos - format string - args []interface{} -} - -func (rr *reports) Reportf(pos token.Pos, format string, args ...interface{}) { - rr.reports = append(rr.reports, report{ - pos: pos, - format: format, - args: args, - }) -} - -func (rr *reports) Filter(pos token.Pos) { - if pos.IsValid() { - if rr.filter == nil { - rr.filter = make(map[token.Pos]struct{}) - } - - rr.filter[pos] = struct{}{} - } -} - -func (rr *reports) NoFilter(pos token.Pos) { - if pos.IsValid() { - if rr.nofilter == nil { - rr.nofilter = make(map[token.Pos]struct{}) - } - - rr.nofilter[pos] = struct{}{} - } -} - -func (rr *reports) Flush(pass *analysis.Pass) { - for _, r := range rr.reports { - if _, ok := rr.filter[r.pos]; ok { - if _, ok := rr.nofilter[r.pos]; !ok { - continue - } - } - - pass.Reportf(r.pos, r.format, r.args...) - } -} diff --git a/vendor/github.com/kunwardeep/paralleltest/LICENSE b/vendor/github.com/kunwardeep/paralleltest/LICENSE deleted file mode 100644 index 77f0d26a64..0000000000 --- a/vendor/github.com/kunwardeep/paralleltest/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2020 Kunwardeep Bedi - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/kunwardeep/paralleltest/pkg/paralleltest/paralleltest.go b/vendor/github.com/kunwardeep/paralleltest/pkg/paralleltest/paralleltest.go deleted file mode 100644 index 6f59e8408b..0000000000 --- a/vendor/github.com/kunwardeep/paralleltest/pkg/paralleltest/paralleltest.go +++ /dev/null @@ -1,499 +0,0 @@ -package paralleltest - -import ( - "flag" - "go/ast" - "go/types" - "strings" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/ast/inspector" -) - -const Doc = `check that tests use t.Parallel() method -It also checks that the t.Parallel is used if multiple tests cases are run as part of single test. -As part of ensuring parallel tests works as expected it checks for reinitializing of the range value -over the test cases.(https://tinyurl.com/y6555cy6) -With the -checkcleanup flag, it also checks that defer is not used with t.Parallel (use t.Cleanup instead).` - -func NewAnalyzer() *analysis.Analyzer { - return newParallelAnalyzer().analyzer -} - -// parallelAnalyzer is an internal analyzer that makes options available to a -// run pass. It wraps an `analysis.Analyzer` that should be returned for -// linters. -type parallelAnalyzer struct { - analyzer *analysis.Analyzer - ignoreMissing bool - ignoreMissingSubtests bool - ignoreLoopVar bool - checkCleanup bool -} - -func newParallelAnalyzer() *parallelAnalyzer { - a := ¶llelAnalyzer{} - - var flags flag.FlagSet - flags.BoolVar(&a.ignoreMissing, "i", false, "ignore missing calls to t.Parallel") - flags.BoolVar(&a.ignoreMissingSubtests, "ignoremissingsubtests", false, "ignore missing calls to t.Parallel in subtests") - flags.BoolVar(&a.ignoreLoopVar, "ignoreloopVar", false, "ignore loop variable detection") - flags.BoolVar(&a.checkCleanup, "checkcleanup", false, "check that defer is not used with t.Parallel (use t.Cleanup instead)") - - a.analyzer = &analysis.Analyzer{ - Name: "paralleltest", - Doc: Doc, - Run: a.run, - Flags: flags, - } - return a -} - -type testFunctionAnalysis struct { - funcHasParallelMethod, - funcCantParallelMethod, - rangeStatementOverTestCasesExists, - rangeStatementHasParallelMethod, - rangeStatementCantParallelMethod, - funcHasDeferStatement bool - loopVariableUsedInRun *string - numberOfTestRun int - positionOfTestRunNode []ast.Node - rangeNode ast.Node - deferStatements []ast.Node -} - -type testRunAnalysis struct { - hasParallel bool - cantParallel bool - numberOfTestRun int - positionOfTestRunNode []ast.Node -} - -func (a *parallelAnalyzer) analyzeTestRun(pass *analysis.Pass, n ast.Node, testVar string) testRunAnalysis { - var analysis testRunAnalysis - - if methodRunIsCalledInTestFunction(n, testVar) { - innerTestVar := getRunCallbackParameterName(n) - analysis.numberOfTestRun++ - - if callExpr, ok := n.(*ast.CallExpr); ok && len(callExpr.Args) > 1 { - if funcLit, ok := callExpr.Args[1].(*ast.FuncLit); ok { - ast.Inspect(funcLit, func(p ast.Node) bool { - if !analysis.hasParallel { - analysis.hasParallel = methodParallelIsCalledInTestFunction(p, innerTestVar) - } - if !analysis.cantParallel { - analysis.cantParallel = methodSetenvIsCalledInTestFunction(p, innerTestVar) - } - return true - }) - } else if ident, ok := callExpr.Args[1].(*ast.Ident); ok { - // Case 2: Direct function identifier: t.Run("name", myFunc) - foundFunc := false - for _, file := range pass.Files { - for _, decl := range file.Decls { - if funcDecl, ok := decl.(*ast.FuncDecl); ok && funcDecl.Name.Name == ident.Name { - foundFunc = true - isReceivingTestContext, testParamName := isFunctionReceivingTestContext(funcDecl) - if isReceivingTestContext { - ast.Inspect(funcDecl, func(p ast.Node) bool { - if !analysis.hasParallel { - analysis.hasParallel = methodParallelIsCalledInTestFunction(p, testParamName) - } - return true - }) - } - } - } - } - if !foundFunc { - analysis.hasParallel = false - } - } else if builderCall, ok := callExpr.Args[1].(*ast.CallExpr); ok { - // Case 3: Function call that returns a function: t.Run("name", builder()) - analysis.hasParallel = a.checkBuilderFunctionForParallel(pass, builderCall) - } - } - - if !analysis.hasParallel && !analysis.cantParallel { - analysis.positionOfTestRunNode = append(analysis.positionOfTestRunNode, n) - } - } - - return analysis -} - -func (a *parallelAnalyzer) analyzeTestFunction(pass *analysis.Pass, funcDecl *ast.FuncDecl) { - var analysis testFunctionAnalysis - - // Check runs for test functions only - isTest, testVar := isTestFunction(funcDecl) - if !isTest { - return - } - - for _, l := range funcDecl.Body.List { - switch v := l.(type) { - case *ast.DeferStmt: - if a.checkCleanup { - analysis.funcHasDeferStatement = true - analysis.deferStatements = append(analysis.deferStatements, v) - } - - case *ast.ExprStmt: - ast.Inspect(v, func(n ast.Node) bool { - if !analysis.funcHasParallelMethod { - analysis.funcHasParallelMethod = methodParallelIsCalledInTestFunction(n, testVar) - } - if !analysis.funcCantParallelMethod { - analysis.funcCantParallelMethod = methodSetenvIsCalledInTestFunction(n, testVar) - } - runAnalysis := a.analyzeTestRun(pass, n, testVar) - analysis.numberOfTestRun += runAnalysis.numberOfTestRun - analysis.positionOfTestRunNode = append(analysis.positionOfTestRunNode, runAnalysis.positionOfTestRunNode...) - return true - }) - - case *ast.RangeStmt: - analysis.rangeNode = v - - var loopVars []types.Object - for _, expr := range []ast.Expr{v.Key, v.Value} { - if id, ok := expr.(*ast.Ident); ok { - loopVars = append(loopVars, pass.TypesInfo.ObjectOf(id)) - } - } - - ast.Inspect(v, func(n ast.Node) bool { - if r, ok := n.(*ast.ExprStmt); ok { - if methodRunIsCalledInRangeStatement(r.X, testVar) { - innerTestVar := getRunCallbackParameterName(r.X) - analysis.rangeStatementOverTestCasesExists = true - - if !analysis.rangeStatementHasParallelMethod { - analysis.rangeStatementHasParallelMethod = methodParallelIsCalledInMethodRun(r.X, innerTestVar) - } - if !analysis.rangeStatementCantParallelMethod { - analysis.rangeStatementCantParallelMethod = methodSetenvIsCalledInMethodRun(r.X, innerTestVar) - } - if !a.ignoreLoopVar && analysis.loopVariableUsedInRun == nil { - if run, ok := r.X.(*ast.CallExpr); ok { - analysis.loopVariableUsedInRun = loopVarReferencedInRun(run, loopVars, pass.TypesInfo) - } - } - - // Check nested test runs - if callExpr, ok := r.X.(*ast.CallExpr); ok && len(callExpr.Args) > 1 { - if funcLit, ok := callExpr.Args[1].(*ast.FuncLit); ok { - ast.Inspect(funcLit, func(p ast.Node) bool { - runAnalysis := a.analyzeTestRun(pass, p, innerTestVar) - analysis.numberOfTestRun += runAnalysis.numberOfTestRun - analysis.positionOfTestRunNode = append(analysis.positionOfTestRunNode, runAnalysis.positionOfTestRunNode...) - return true - }) - } - } - } - } - return true - }) - } - } - - if analysis.rangeStatementCantParallelMethod { - analysis.funcCantParallelMethod = true - } - - if !a.ignoreMissing && !analysis.funcHasParallelMethod && !analysis.funcCantParallelMethod { - pass.Reportf(funcDecl.Pos(), "Function %s missing the call to method parallel\n", funcDecl.Name.Name) - } - - if analysis.rangeStatementOverTestCasesExists && analysis.rangeNode != nil { - if !analysis.rangeStatementHasParallelMethod && !analysis.rangeStatementCantParallelMethod { - if !a.ignoreMissing && !a.ignoreMissingSubtests { - pass.Reportf(analysis.rangeNode.Pos(), "Range statement for test %s missing the call to method parallel in test Run\n", funcDecl.Name.Name) - } - } else if analysis.loopVariableUsedInRun != nil && !a.ignoreLoopVar { - pass.Reportf(analysis.rangeNode.Pos(), "Range statement for test %s does not reinitialise the variable %s\n", funcDecl.Name.Name, *analysis.loopVariableUsedInRun) - } - } - - if !a.ignoreMissing && !a.ignoreMissingSubtests { - if analysis.numberOfTestRun > 1 && len(analysis.positionOfTestRunNode) > 0 { - for _, n := range analysis.positionOfTestRunNode { - pass.Reportf(n.Pos(), "Function %s missing the call to method parallel in the test run\n", funcDecl.Name.Name) - } - } - } - - if a.checkCleanup && analysis.funcHasParallelMethod && analysis.funcHasDeferStatement { - for _, deferStmt := range analysis.deferStatements { - pass.Reportf(deferStmt.Pos(), "Function %s uses defer with t.Parallel, use t.Cleanup instead to ensure cleanup runs after parallel subtests complete", funcDecl.Name.Name) - } - } -} - -// checkBuilderFunctionForParallel analyzes a function call that returns a test function -// to see if the returned function contains t.Parallel() -func (a *parallelAnalyzer) checkBuilderFunctionForParallel(pass *analysis.Pass, builderCall *ast.CallExpr) bool { - // Get the name of the builder function being called - var builderFuncName string - switch fun := builderCall.Fun.(type) { - case *ast.Ident: - builderFuncName = fun.Name - case *ast.SelectorExpr: - // Handle method calls like obj.Builder() - builderFuncName = fun.Sel.Name - default: - return false - } - - if builderFuncName == "" { - return false - } - - // Find the builder function declaration - for _, file := range pass.Files { - for _, decl := range file.Decls { - funcDecl, ok := decl.(*ast.FuncDecl) - if !ok || funcDecl.Name.Name != builderFuncName { - continue - } - - // Found the builder function, analyze it and return immediately - hasParallel := false - ast.Inspect(funcDecl, func(n ast.Node) bool { - // Look for return statements - returnStmt, ok := n.(*ast.ReturnStmt) - if !ok || len(returnStmt.Results) == 0 { - return true - } - - // Check if the return value is a function literal - for _, result := range returnStmt.Results { - if funcLit, ok := result.(*ast.FuncLit); ok { - // Get the parameter name from the returned function - var paramName string - if funcLit.Type != nil && funcLit.Type.Params != nil && len(funcLit.Type.Params.List) > 0 { - param := funcLit.Type.Params.List[0] - if len(param.Names) > 0 { - paramName = param.Names[0].Name - } - } - - // Inspect the returned function for t.Parallel() - if paramName != "" { - ast.Inspect(funcLit, func(p ast.Node) bool { - if methodParallelIsCalledInTestFunction(p, paramName) { - hasParallel = true - return false - } - return true - }) - - // Exit inspection immediately if we found t.Parallel() - if hasParallel { - return false - } - } - } - } - // Continue to next return statement if t.Parallel() not found yet - return true - }) - - // Return immediately after processing the matching function - return hasParallel - } - } - - return false -} - -func (a *parallelAnalyzer) run(pass *analysis.Pass) (interface{}, error) { - inspector := inspector.New(pass.Files) - - nodeFilter := []ast.Node{ - (*ast.FuncDecl)(nil), - } - - inspector.Preorder(nodeFilter, func(node ast.Node) { - funcDecl := node.(*ast.FuncDecl) - // Only process _test.go files - if !strings.HasSuffix(pass.Fset.File(funcDecl.Pos()).Name(), "_test.go") { - return - } - a.analyzeTestFunction(pass, funcDecl) - }) - - return nil, nil -} - -func methodParallelIsCalledInMethodRun(node ast.Node, testVar string) bool { - return targetMethodIsCalledInMethodRun(node, testVar, "Parallel") -} - -func methodSetenvIsCalledInMethodRun(node ast.Node, testVar string) bool { - return targetMethodIsCalledInMethodRun(node, testVar, "Setenv") -} - -func targetMethodIsCalledInMethodRun(node ast.Node, testVar, targetMethod string) bool { - var called bool - // nolint: gocritic - switch callExp := node.(type) { - case *ast.CallExpr: - for _, arg := range callExp.Args { - if !called { - ast.Inspect(arg, func(n ast.Node) bool { - if !called { - called = exprCallHasMethod(n, testVar, targetMethod) - return true - } - return false - }) - } - } - } - return called -} - -func methodParallelIsCalledInTestFunction(node ast.Node, testVar string) bool { - return exprCallHasMethod(node, testVar, "Parallel") -} - -func methodRunIsCalledInRangeStatement(node ast.Node, testVar string) bool { - return exprCallHasMethod(node, testVar, "Run") -} - -func methodRunIsCalledInTestFunction(node ast.Node, testVar string) bool { - return exprCallHasMethod(node, testVar, "Run") -} - -func methodSetenvIsCalledInTestFunction(node ast.Node, testVar string) bool { - return exprCallHasMethod(node, testVar, "Setenv") -} - -func exprCallHasMethod(node ast.Node, receiverName, methodName string) bool { - // nolint: gocritic - switch n := node.(type) { - case *ast.CallExpr: - if fun, ok := n.Fun.(*ast.SelectorExpr); ok { - if receiver, ok := fun.X.(*ast.Ident); ok { - return receiver.Name == receiverName && fun.Sel.Name == methodName - } - } - } - return false -} - -// In an expression of the form t.Run(x, func(q *testing.T) {...}), return the -// value "q". In _most_ code, the name is probably t, but we shouldn't just -// assume. -func getRunCallbackParameterName(node ast.Node) string { - if n, ok := node.(*ast.CallExpr); ok { - if len(n.Args) < 2 { - // We want argument #2, but this call doesn't have two - // arguments. Maybe it's not really t.Run. - return "" - } - funcArg := n.Args[1] - if fun, ok := funcArg.(*ast.FuncLit); ok { - if len(fun.Type.Params.List) < 1 { - // Subtest function doesn't have any parameters. - return "" - } - firstArg := fun.Type.Params.List[0] - // We'll assume firstArg.Type is *testing.T. - if len(firstArg.Names) < 1 { - return "" - } - return firstArg.Names[0].Name - } - } - return "" -} - -// isFunctionReceivingTestContext checks if a function declaration receives a *testing.T parameter -// Returns (true, paramName) if it does, (false, "") if it doesn't -func isFunctionReceivingTestContext(funcDecl *ast.FuncDecl) (bool, string) { - testMethodPackageType := "testing" - testMethodStruct := "T" - - if funcDecl.Type.Params != nil && len(funcDecl.Type.Params.List) != 1 { - return false, "" - } - - param := funcDecl.Type.Params.List[0] - if starExp, ok := param.Type.(*ast.StarExpr); ok { - if selectExpr, ok := starExp.X.(*ast.SelectorExpr); ok { - if selectExpr.Sel.Name == testMethodStruct { - if s, ok := selectExpr.X.(*ast.Ident); ok { - if len(param.Names) > 0 { - return s.Name == testMethodPackageType, param.Names[0].Name - } - } - } - } - } - - return false, "" -} - -// isTestFunction checks if a function declaration is a test function -// A test function must: -// 1. Start with "Test" -// 2. Have exactly one parameter -// 3. Have that parameter be of type *testing.T -// Returns (true, paramName) if it is a test function, (false, "") if it isn't -func isTestFunction(funcDecl *ast.FuncDecl) (bool, string) { - testMethodPackageType := "testing" - testMethodStruct := "T" - testPrefix := "Test" - - if !strings.HasPrefix(funcDecl.Name.Name, testPrefix) { - return false, "" - } - - if funcDecl.Type.Params != nil && len(funcDecl.Type.Params.List) != 1 { - return false, "" - } - - param := funcDecl.Type.Params.List[0] - if starExp, ok := param.Type.(*ast.StarExpr); ok { - if selectExpr, ok := starExp.X.(*ast.SelectorExpr); ok { - if selectExpr.Sel.Name == testMethodStruct { - if s, ok := selectExpr.X.(*ast.Ident); ok { - if len(param.Names) > 0 { - return s.Name == testMethodPackageType, param.Names[0].Name - } - } - } - } - } - - return false, "" -} - -// loopVarReferencedInRun checks if a loop variable is referenced within a test run -// This is important for detecting potential race conditions in parallel tests -func loopVarReferencedInRun(call *ast.CallExpr, vars []types.Object, typeInfo *types.Info) (found *string) { - if len(call.Args) != 2 { - return - } - - ast.Inspect(call.Args[1], func(n ast.Node) bool { - ident, ok := n.(*ast.Ident) - if !ok { - return true - } - for _, o := range vars { - if typeInfo.ObjectOf(ident) == o { - found = &ident.Name - } - } - return true - }) - - return -} diff --git a/vendor/github.com/lasiar/canonicalheader/.gitignore b/vendor/github.com/lasiar/canonicalheader/.gitignore deleted file mode 100644 index 723ef36f4e..0000000000 --- a/vendor/github.com/lasiar/canonicalheader/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.idea \ No newline at end of file diff --git a/vendor/github.com/lasiar/canonicalheader/.golangci.yaml b/vendor/github.com/lasiar/canonicalheader/.golangci.yaml deleted file mode 100644 index 997ec0cb01..0000000000 --- a/vendor/github.com/lasiar/canonicalheader/.golangci.yaml +++ /dev/null @@ -1,784 +0,0 @@ -# See: https://olegk.dev/go-linters-configuration-the-right-version - -run: - # Automatically adjust the maximum concurrency to the container CPU quota. - concurrency: 0 - - # I really care about the result, so I'm fine to wait for it. - timeout: 30m - - # Fail if the error was met. - issues-exit-code: 1 - - # This is very important, bugs in tests are not acceptable either. - tests: true - - # In most cases this can be empty but there is a popular pattern - # to keep integration tests under this tag. Such tests often require - # additional setups like Postgres, Redis etc and are run separately. - # (to be honest I don't find this useful but I have such tags) - build-tags: - - integration - - # Autogenerated files can be skipped (I'm looking at you gRPC). - # AFAIK autogen files are skipped but skipping the whole directory should be somewhat faster. - #skip-files: - # - "protobuf/.*.go" - - # With the read-only mode linter will fail if go.mod file is outdated. - modules-download-mode: readonly - - # Till today I didn't know this param exists, never ran 2 golangci-lint at once. - allow-parallel-runners: false - - # Keep this empty to use the Go version from the go.mod file. - go: "" - -linters: - # Set to true runs only fast linters. - # Good option for 'lint on save', pre-commit hook or CI. - fast: false - - enable: - # Globals and init() are no ok, because this linter use on golangci lint. - - gochecknoglobals - - gochecknoinits - # Check for pass []any as any in variadic func(...any). - # Rare case but saved me from debugging a few times. - - asasalint - - # I prefer plane ASCII identifiers. - # Symbol `∆` instead of `delta` looks cool but no thanks. - - asciicheck - - # Checks for dangerous unicode character sequences. - # Super rare but why not to be a bit paranoid? - - bidichk - - # Checks whether HTTP response body is closed successfully. - - bodyclose - - # Check whether the function uses a non-inherited context. - - contextcheck - - # after go 1.22 don't need copy var at for range. - - copyloopvar - - # Find duplicate words, rare. - - dupword - - # Check for two durations multiplied together. - - durationcheck - - # Forces to not skip error check. - - errcheck - - # Checks `Err-` prefix for var and `-Error` suffix for error type. - - errname - - # Suggests to use `%w` for error-wrapping. - - errorlint - - # Checks for pointers to enclosing loop variables. - - exportloopref - - - # Imports order. - - gci - - # As you already know I'm a co-author. It would be strange to not use - # one of my warmly loved projects. - - gocritic - - # Forces to put `.` at the end of the comment. Code is poetry. - - godot - - # Might not be that important but I prefer to keep all of them. - # `gofumpt` is amazing, kudos to Daniel Marti https://github.com/mvdan/gofumpt - - gofmt - - gofumpt - - goimports - - # Allow or ban replace directives in go.mod - # or force explanation for retract directives. - - gomoddirectives - - # Powerful security-oriented linter. But requires some time to - # configure it properly, see https://github.com/securego/gosec#available-rules - - gosec - - # Linter that specializes in simplifying code. - - gosimple - - # Official Go tool. Must have. - - govet - - # Detects when assignments to existing variables are not used - # Last week I caught a bug with it. - - ineffassign - - # range over int, work after go 1.22 - - intrange - - # Fix all the misspells, amazing thing. - - misspell - - # Reports wrong mirror patterns of bytes/strings usage. - - mirror - - # Finds naked/bare returns and requires change them. - - nakedret - - # Both require a bit more explicit returns. - - nilerr - - nilnil - - # Finds sending HTTP request without context.Context. - - noctx - - # Forces comment why another check is disabled. - # Better not to have //nolint: at all ;) - - nolintlint - - # aiming at usages of fmt.Sprintf which have faster alternatives. - - perfsprint - - # Finds slices that could potentially be pre-allocated. - # Small performance win + cleaner code. - - prealloc - - # Finds shadowing of Go's predeclared identifiers. - # I hear a lot of complaints from junior developers. - # But after some time they find it very useful. - - predeclared - - # Lint your Prometheus metrics name. - - promlinter - - # Checks that package variables are not reassigned. - # Super rare case but can catch bad things (like `io.EOF = nil`) - - reassign - - # Drop-in replacement of `golint`. - - revive - - # Somewhat similar to `bodyclose` but for `database/sql` package. - - rowserrcheck - - sqlclosecheck - - # Ensure consistent code style when using log/slog. - - sloglint - - # I have found that it's not the same as staticcheck binary :\ - - staticcheck - - # Is a replacement for `golint`, similar to `revive`. - - stylecheck - - # Check struct tags. - - tagliatelle - - # Test-related checks. All of them are good. - - tenv - - testableexamples - - testifylint - - thelper - - tparallel - - # Remove unnecessary type conversions, make code cleaner - - unconvert - - # Might be noisy but better to know what is unused - - unparam - - # Must have. Finds unused declarations. - - unused - - # Detect the possibility to use variables/constants from stdlib. - - usestdlibvars - - # Finds wasted assignment statements. - - wastedassign - - disable: - # Detects struct contained context.Context field. Not a problem. - - containedctx - - # Checks function and package cyclomatic complexity. - # I can have a long but trivial switch-case. - # - # Cyclomatic complexity is a measurement, not a goal. - # (c) Bryan C. Mills / https://github.com/bcmills - - cyclop - - # Check declaration order of types, consts, vars and funcs. - # I like it but I don't use it. - - decorder - - # Checks if package imports are in a list of acceptable packages. - # I'm very picky about what I import, so no automation. - - depguard - - # Checks assignments with too many blank identifiers. Very rare. - - dogsled - - # Tool for code clone detection. - - dupl - - # I'm fine to check the error from json.Marshal ¯\_(ツ)_/¯ - - errchkjson - - # All SQL queries MUST BE covered with tests. - - execinquery - - # Forces to handle more cases. Cool but noisy. - - exhaustive - - exhaustruct - - # Forbids some identifiers. I don't have a case for it. - - forbidigo - - # Finds forced type assertions, very good for juniors. - - forcetypeassert - - # I might have long but a simple function. - - funlen - - # I'm not a fan of ginkgo and gomega packages. - - ginkgolinter - - # Checks that compiler directive comments (//go:) are valid. Rare. - - gocheckcompilerdirectives - - # Same as `cyclop` linter (see above) - - gocognit - - goconst - - gocyclo - - # TODO and friends are ok. - - godox - - # Check the error handling expressions. Too noisy. - - err113 - - # I don't use file headers. - - goheader - - # Reports magic consts. Might be noisy but still good. - - mnd - - # Allowed/blocked packages to import. I prefer to do it manually. - - gomodguard - - # Printf-like functions must have -f. - - goprintffuncname - - # Groupt declarations, I prefer manually. - - grouper - - # Checks imports aliases, rare. - - importas - - # Forces tiny interfaces, very subjective. - - interfacebloat - - # Accept interfaces, return types. Not always. - - ireturn - - # I don't set line length. 120 is fine by the way ;) - - lll - - # Some log checkers, might be useful. - - loggercheck - - # Maintainability index of each function, subjective. - - maintidx - - # Slice declarations with non-zero initial length. Not my case. - - makezero - - # Enforce tags in un/marshaled structs. Cool but not my case. - - musttag - - # Deeply nested if statements, subjective. - - nestif - - # Forces newlines in some places. - - nlreturn - - # Reports all named returns, not that bad. - - nonamedreturns - - # Finds misuse of Sprintf with host:port in a URL. Cool but rare. - - nosprintfhostport - - # I don't use t.Parallel() that much. - - paralleltest - - # Often non-`_test` package is ok. - - testpackage - - # Compiler can do it too :) - - typecheck - - # I'm fine with long variable names with a small scope. - - varnamelen - - # gofmt,gofumpt covers that (from what I know). - - whitespace - - # Don't find it useful to wrap all errors from external packages. - - wrapcheck - - # Forces you to use empty lines. Great if configured correctly. - # I mean there is an agreement in a team. - - wsl - -linters-settings: - gci: - sections: - - standard - - default - - localmodule - - revive: - # Maximum number of open files at the same time. - # See https://github.com/mgechev/revive#command-line-flags - # Defaults to unlimited. - max-open-files: 2048 - # When set to false, ignores files with "GENERATED" header, similar to golint. - # See https://github.com/mgechev/revive#available-rules for details. - # Default: false - ignore-generated-header: true - # Sets the default severity. - # See https://github.com/mgechev/revive#configuration - # Default: warning - severity: error - # Enable all available rules. - # Default: false - enable-all-rules: true - # Sets the default failure confidence. - # This means that linting errors with less than 0.8 confidence will be ignored. - # Default: 0.8 - confidence: 0.1 - rules: - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#add-constant - - name: add-constant - severity: warning - disabled: false - arguments: - - maxLitCount: "3" - allowStrs: '""' - allowInts: "0,1,2" - allowFloats: "0.0,0.,1.0,1.,2.0,2." - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#argument-limit - - name: argument-limit - severity: warning - disabled: false - arguments: [4] - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#atomic - - name: atomic - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#banned-characters - - name: banned-characters - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#bare-return - - name: bare-return - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#blank-imports - - name: blank-imports - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#bool-literal-in-expr - - name: bool-literal-in-expr - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#call-to-gc - - name: call-to-gc - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#cognitive-complexity - - name: cognitive-complexity - severity: warning - disabled: true - arguments: [7] - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#comment-spacings - - name: comment-spacings - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#confusing-naming - - name: confusing-naming - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#confusing-results - - name: confusing-results - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#constant-logical-expr - - name: constant-logical-expr - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#context-as-argument - - name: context-as-argument - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#context-keys-type - - name: context-keys-type - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#cyclomatic - - name: cyclomatic - severity: warning - disabled: true - arguments: [3] - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#datarace - - name: datarace - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#deep-exit - - name: deep-exit - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#defer - - name: defer - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#dot-imports - - name: dot-imports - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#duplicated-imports - - name: duplicated-imports - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#early-return - - name: early-return - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#empty-block - - name: empty-block - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#empty-lines - - name: empty-lines - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#enforce-map-style - - name: enforce-map-style - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#error-naming - - name: error-naming - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#error-return - - name: error-return - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#function-length - - name: function-length - severity: warning - disabled: true - arguments: [10, 0] - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#error-strings - - name: error-strings - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#errorf - - name: errorf - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#exported - - name: exported - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#file-header - - name: file-header - severity: warning - disabled: true - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#flag-parameter - - name: flag-parameter - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#function-result-limit - - name: function-result-limit - severity: warning - disabled: false - arguments: [2] - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#get-return - - name: get-return - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#identical-branches - - name: identical-branches - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#if-return - - name: if-return - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#increment-decrement - - name: increment-decrement - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#indent-error-flow - - name: indent-error-flow - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#import-alias-naming - - name: import-alias-naming - severity: warning - disabled: false - arguments: - - "^[a-z][a-z0-9]{0,}$" - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#imports-blacklist - - name: imports-blacklist - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#import-shadowing - - name: import-shadowing - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#line-length-limit - - name: line-length-limit - severity: warning - disabled: true - arguments: [80] - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#max-public-structs - - name: max-public-structs - severity: warning - disabled: false - arguments: [3] - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#modifies-parameter - - name: modifies-parameter - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#modifies-value-receiver - - name: modifies-value-receiver - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#nested-structs - - name: nested-structs - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#optimize-operands-order - - name: optimize-operands-order - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#package-comments - - name: package-comments - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#range - - name: range - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#range-val-in-closure - - name: range-val-in-closure - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#range-val-address - - name: range-val-address - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#receiver-naming - - name: receiver-naming - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#redundant-import-alias - - name: redundant-import-alias - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#redefines-builtin-id - - name: redefines-builtin-id - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#string-of-int - - name: string-of-int - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#string-format - - name: string-format - severity: warning - disabled: false - arguments: - - - 'core.WriteError[1].Message' - - '/^([^A-Z]|$)/' - - must not start with a capital letter - - - 'fmt.Errorf[0]' - - '/(^|[^\.!?])$/' - - must not end in punctuation - - - panic - - '/^[^\n]*$/' - - must not contain line breaks - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#struct-tag - - name: struct-tag - arguments: - - "json,inline" - - "bson,outline,gnu" - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#superfluous-else - - name: superfluous-else - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#time-equal - - name: time-equal - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#time-naming - - name: time-naming - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#var-naming - - name: var-naming - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#var-declaration - - name: var-declaration - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unconditional-recursion - - name: unconditional-recursion - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unexported-naming - - name: unexported-naming - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unexported-return - - name: unexported-return - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unhandled-error - - name: unhandled-error - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unnecessary-stmt - - name: unnecessary-stmt - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unreachable-code - - name: unreachable-code - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unused-parameter - - name: unused-parameter - severity: warning - disabled: false - arguments: - - allowRegex: "^_" - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unused-receiver - - name: unused-receiver - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#useless-break - - name: useless-break - severity: warning - disabled: false - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#waitgroup-by-value - - name: waitgroup-by-value - severity: warning - disabled: false - # I'm biased and I'm enabling more than 100 checks - # Might be too much for you. See https://go-critic.com/overview.html - gocritic: - enabled-tags: - - diagnostic - - experimental - - opinionated - - performance - - style - disabled-checks: - # These 3 will detect many cases, but they do sense - # if it's performance oriented code - - hugeParam - - rangeExprCopy - - rangeValCopy - - godot: - scope: all - - errcheck: - # Report `a := b.(MyStruct)` when `a, ok := ...` should be. - check-type-assertions: true # Default: false - - # Report skipped checks:`num, _ := strconv.Atoi(numStr)`. - check-blank: true # Default: false - - # Function to skip. - exclude-functions: - - io/ioutil.ReadFile - - io.Copy(*bytes.Buffer) - - io.Copy(os.Stdout) - - govet: - disable: - - fieldalignment # I'm ok to waste some bytes - - nakedret: - # No naked returns, ever. - max-func-lines: 1 # Default: 30 - - tagliatelle: - case: - rules: - json: snake # why it's not a `snake` by default?! - yaml: snake # why it's not a `snake` by default?! - xml: camel - bson: camel - avro: snake - mapstructure: kebab - -# See also https://gist.github.com/cristaloleg/dc29ca0ef2fb554de28d94c3c6f6dc88 - -output: - # I prefer the simplest one: `line-number` and saving to `lint.txt` - # - # The `tab` also looks good and with the next release I will switch to it - # (ref: https://github.com/golangci/golangci-lint/issues/3728) - # - # There are more formats which can be used on CI or by your IDE. - formats: - - format: line-number - - # I do not find this useful, parameter above already enables filepath - # with a line and column. For me, it's easier to follow the path and - # see the line in an IDE where I see more code and understand it better. - print-issued-lines: false - - # Must have. Easier to understand the output. - print-linter-name: true - - # No, no skips, everything should be reported. - uniq-by-line: false - - # To be honest no idea when this can be needed, maybe a multi-module setup? - path-prefix: "" - - # Slightly easier to follow the results + getting deterministic output. - sort-results: true - -issues: - exclude-dirs-use-default: false - # I found it strange to skip the errors, setting 0 to have all the results. - max-issues-per-linter: 0 - - # Same here, nothing should be skipped to not miss errors. - max-same-issues: 0 - - # When set to `true` linter will analyze only new code which are - # not committed or after some specific revision. This is a cool - # feature when you're going to introduce linter into a big project. - # But I prefer going gradually package by package. - # So, it's set to `false` to scan all code. - new: false - - # 2 other params regarding git integration - - # Even with a recent GPT-4 release I still believe that - # I know better how to do my job and fix the suggestions. - fix: false \ No newline at end of file diff --git a/vendor/github.com/lasiar/canonicalheader/.goreleaser.yaml b/vendor/github.com/lasiar/canonicalheader/.goreleaser.yaml deleted file mode 100644 index ada67063eb..0000000000 --- a/vendor/github.com/lasiar/canonicalheader/.goreleaser.yaml +++ /dev/null @@ -1,18 +0,0 @@ -builds: - - main: ./cmd/canonicalheader - env: - - CGO_ENABLED=0 - flags: - - -trimpath - ldflags: - - -s -w - targets: - - darwin_amd64 - - darwin_arm64 - - linux_amd64 - - windows_amd64 - -archives: - - format_overrides: - - goos: windows - format: zip \ No newline at end of file diff --git a/vendor/github.com/lasiar/canonicalheader/LICENCE b/vendor/github.com/lasiar/canonicalheader/LICENCE deleted file mode 100644 index 5b93b736c7..0000000000 --- a/vendor/github.com/lasiar/canonicalheader/LICENCE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 Roman Chaliy - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/vendor/github.com/lasiar/canonicalheader/README.md b/vendor/github.com/lasiar/canonicalheader/README.md deleted file mode 100644 index 9971452197..0000000000 --- a/vendor/github.com/lasiar/canonicalheader/README.md +++ /dev/null @@ -1,77 +0,0 @@ -# canonicalheader - -[![CI](https://github.com/lasiar/canonicalheader/actions/workflows/test.yml/badge.svg)](https://github.com/lasiar/canonicalheader/actions/workflows/test.yml) -[![tag](https://img.shields.io/github/tag/lasiar/canonicalheader.svg)](https://github.com/lasiar/canonicalheader/releases) -[![Go Report Card](https://goreportcard.com/badge/github.com/lasiar/canonicalheader)](https://goreportcard.com/report/github.com/lasiar/canonicalheader) -[![License](https://img.shields.io/github/license/lasiar/canonicalheader)](./LICENCE) - -Golang linter for check canonical header. - -### Install - -```shell -go install -v github.com/lasiar/canonicalheader/cmd/canonicalheader@latest -``` - -Or download the binary file from the [release](https://github.com/lasiar/canonicalheader/releases/latest). - - -### Example - -before - -```go -package main - -import ( - "net/http" -) - -const testHeader = "testHeader" - -func main() { - v := http.Header{} - v.Get(testHeader) - - v.Get("Test-HEader") - v.Set("Test-HEader", "value") - v.Add("Test-HEader", "value") - v.Del("Test-HEader") - v.Values("Test-HEader") - - v.Set("Test-Header", "value") - v.Add("Test-Header", "value") - v.Del("Test-Header") - v.Values("Test-Header") -} - -``` - -after - -```go -package main - -import ( - "net/http" -) - -const testHeader = "testHeader" - -func main() { - v := http.Header{} - v.Get(testHeader) - - v.Get("Test-Header") - v.Set("Test-Header", "value") - v.Add("Test-Header", "value") - v.Del("Test-Header") - v.Values("Test-Header") - - v.Set("Test-Header", "value") - v.Add("Test-Header", "value") - v.Del("Test-Header") - v.Values("Test-Header") -} - -``` diff --git a/vendor/github.com/lasiar/canonicalheader/analyzer.go b/vendor/github.com/lasiar/canonicalheader/analyzer.go deleted file mode 100644 index 258ebdfd4d..0000000000 --- a/vendor/github.com/lasiar/canonicalheader/analyzer.go +++ /dev/null @@ -1,265 +0,0 @@ -package canonicalheader - -import ( - "fmt" - "go/ast" - "go/types" - "net/http" - - "github.com/go-toolsmith/astcast" - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/inspector" - "golang.org/x/tools/go/types/typeutil" -) - -const ( - pkgPath = "net/http" - name = "Header" -) - -//nolint:gochecknoglobals // struct is not big, can be skip. -var Analyzer = &analysis.Analyzer{ - Name: "canonicalheader", - Doc: "canonicalheader checks whether net/http.Header uses canonical header", - Run: run, - Requires: []*analysis.Analyzer{inspect.Analyzer}, -} - -type argumenter interface { - diagnostic(canonicalHeader string) analysis.Diagnostic - value() string -} - -func run(pass *analysis.Pass) (any, error) { - var headerObject types.Object - for _, object := range pass.TypesInfo.Uses { - if object.Pkg() != nil && - object.Pkg().Path() == pkgPath && - object.Name() == name { - headerObject = object - break - } - } - - if headerObject == nil { - //nolint:nilnil // nothing to do here, because http.Header{} not usage. - return nil, nil - } - - spctor, ok := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - if !ok { - return nil, fmt.Errorf("want %T, got %T", spctor, pass.ResultOf[inspect.Analyzer]) - } - - wellKnownHeaders := initialism() - - nodeFilter := []ast.Node{ - (*ast.CallExpr)(nil), - } - var outerErr error - - spctor.Preorder(nodeFilter, func(n ast.Node) { - if outerErr != nil { - return - } - - callExp, ok := n.(*ast.CallExpr) - if !ok { - return - } - - var ( - // gotType type receiver. - gotType types.Type - gotMethodName string - ) - - switch t := typeutil.Callee(pass.TypesInfo, callExp).(type) { - // Direct call method. - case *types.Func: - fn := t - // Find net/http.Header{} by function call. - signature, ok := fn.Type().(*types.Signature) - if !ok { - return - } - - recv := signature.Recv() - - // It's a func, not a method. - if recv == nil { - return - } - gotType = recv.Type() - gotMethodName = astcast.ToSelectorExpr(callExp.Fun).Sel.Name - - // h := http.Header{} - // f := h.Get - // v("Test-Value"). - case *types.Var: - ident, ok := callExp.Fun.(*ast.Ident) - if !ok { - return - } - - if ident.Obj == nil { - return - } - - // f := h.Get. - assign, ok := ident.Obj.Decl.(*ast.AssignStmt) - if !ok { - return - } - - // For case `i, v := 0, h.Get`. - // indexAssign--^. - indexAssign := -1 - for i, lh := range assign.Lhs { - // Find by name of variable. - if astcast.ToIdent(lh).Name == ident.Name { - indexAssign = i - } - } - - // Not found. - if indexAssign == -1 { - return - } - - if len(assign.Rhs) <= indexAssign { - return - } - - sel, ok := assign.Rhs[indexAssign].(*ast.SelectorExpr) - if !ok { - return - } - - gotMethodName = sel.Sel.Name - ident, ok = sel.X.(*ast.Ident) - if !ok { - return - } - - obj := pass.TypesInfo.ObjectOf(ident) - gotType = obj.Type() - - default: - return - } - - // It is not net/http.Header{}. - if !types.Identical(gotType, headerObject.Type()) { - return - } - - // Search for known methods where the key is the first arg. - if !isValidMethod(gotMethodName) { - return - } - - // Should be more than one. Because get the value by index it - // will not be superfluous. - if len(callExp.Args) == 0 { - return - } - - callArg := callExp.Args[0] - - // Check for type casting from myString to string. - // it could be: Get(string(string(string(myString)))). - // need this node------------------------^^^^^^^^. - for { - // If it is not *ast.CallExpr, this is a value. - c, ok := callArg.(*ast.CallExpr) - if !ok { - break - } - - // Some function is called, skip this case. - if len(c.Args) == 0 { - return - } - - f, ok := c.Fun.(*ast.Ident) - if !ok { - break - } - - obj := pass.TypesInfo.ObjectOf(f) - // nil may be by code, but not by logic. - // TypeInfo should contain of type. - if obj == nil { - break - } - - // This is function. - // Skip this method call. - _, ok = obj.Type().(*types.Signature) - if ok { - return - } - - callArg = c.Args[0] - } - - var arg argumenter - switch t := callArg.(type) { - case *ast.BasicLit: - lString, err := newLiteralString(t) - if err != nil { - return - } - - arg = lString - - case *ast.Ident: - constString, err := newConstantKey(pass.TypesInfo, t) - if err != nil { - return - } - - arg = constString - - default: - return - } - - argValue := arg.value() - headerKeyCanonical := http.CanonicalHeaderKey(argValue) - if argValue == headerKeyCanonical { - return - } - - headerKeyCanonical, isWellKnown := canonicalHeaderKey(argValue, wellKnownHeaders) - if argValue == headerKeyCanonical || isWellKnown { - return - } - - pass.Report(arg.diagnostic(headerKeyCanonical)) - }) - - return nil, outerErr -} - -func canonicalHeaderKey(s string, m map[string]string) (string, bool) { - canonical := http.CanonicalHeaderKey(s) - - wellKnown, ok := m[canonical] - if !ok { - return canonical, ok - } - - return wellKnown, ok -} - -func isValidMethod(name string) bool { - switch name { - case "Get", "Set", "Add", "Del", "Values": - return true - default: - return false - } -} diff --git a/vendor/github.com/lasiar/canonicalheader/constant_string.go b/vendor/github.com/lasiar/canonicalheader/constant_string.go deleted file mode 100644 index 27988f0d53..0000000000 --- a/vendor/github.com/lasiar/canonicalheader/constant_string.go +++ /dev/null @@ -1,50 +0,0 @@ -package canonicalheader - -import ( - "fmt" - "go/ast" - "go/constant" - "go/token" - "go/types" - - "golang.org/x/tools/go/analysis" -) - -type constantString struct { - originalValue, - nameOfConst string - - pos token.Pos - end token.Pos -} - -func newConstantKey(info *types.Info, ident *ast.Ident) (constantString, error) { - c, ok := info.ObjectOf(ident).(*types.Const) - if !ok { - return constantString{}, fmt.Errorf("type %T is not support", c) - } - - return constantString{ - nameOfConst: c.Name(), - originalValue: constant.StringVal(c.Val()), - pos: ident.Pos(), - end: ident.End(), - }, nil -} - -func (c constantString) diagnostic(canonicalHeader string) analysis.Diagnostic { - return analysis.Diagnostic{ - Pos: c.pos, - End: c.end, - Message: fmt.Sprintf( - "const %q used as a key at http.Header, but %q is not canonical, want %q", - c.nameOfConst, - c.originalValue, - canonicalHeader, - ), - } -} - -func (c constantString) value() string { - return c.originalValue -} diff --git a/vendor/github.com/lasiar/canonicalheader/initialism.go b/vendor/github.com/lasiar/canonicalheader/initialism.go deleted file mode 100644 index c3d91c23e9..0000000000 --- a/vendor/github.com/lasiar/canonicalheader/initialism.go +++ /dev/null @@ -1,75 +0,0 @@ -// Code generated by initialismer; DO NOT EDIT. -package canonicalheader - -// initialism mapping of not canonical headers from -// https://en.wikipedia.org/wiki/List_of_HTTP_header_fields -// https://www.iana.org/assignments/http-fields/http-fields.xhtml. -func initialism() map[string]string { - return map[string]string{ - "A-Im": "A-IM", - "Accept-Ch": "Accept-CH", - "Alpn": "ALPN", - "Amp-Cache-Transform": "AMP-Cache-Transform", - "C-Pep": "C-PEP", - "C-Pep-Info": "C-PEP-Info", - "Cal-Managed-Id": "Cal-Managed-ID", - "Caldav-Timezones": "CalDAV-Timezones", - "Cdn-Cache-Control": "CDN-Cache-Control", - "Cdn-Loop": "CDN-Loop", - "Content-Id": "Content-ID", - "Content-Md5": "Content-MD5", - "Dasl": "DASL", - "Dav": "DAV", - "Differential-Id": "Differential-ID", - "Dnt": "DNT", - "Dpop": "DPoP", - "Dpop-Nonce": "DPoP-Nonce", - "Ediint-Features": "EDIINT-Features", - "Etag": "ETag", - "Expect-Ct": "Expect-CT", - "Getprofile": "GetProfile", - "Http2-Settings": "HTTP2-Settings", - "Im": "IM", - "Include-Referred-Token-Binding-Id": "Include-Referred-Token-Binding-ID", - "Last-Event-Id": "Last-Event-ID", - "Mime-Version": "MIME-Version", - "Nel": "NEL", - "Odata-Entityid": "OData-EntityId", - "Odata-Isolation": "OData-Isolation", - "Odata-Maxversion": "OData-MaxVersion", - "Odata-Version": "OData-Version", - "Optional-Www-Authenticate": "Optional-WWW-Authenticate", - "Oscore": "OSCORE", - "Oslc-Core-Version": "OSLC-Core-Version", - "P3p": "P3P", - "Pep": "PEP", - "Pep-Info": "PEP-Info", - "Pics-Label": "PICS-Label", - "Profileobject": "ProfileObject", - "Repeatability-Client-Id": "Repeatability-Client-ID", - "Repeatability-Request-Id": "Repeatability-Request-ID", - "Sec-Gpc": "Sec-GPC", - "Sec-Websocket-Accept": "Sec-WebSocket-Accept", - "Sec-Websocket-Extensions": "Sec-WebSocket-Extensions", - "Sec-Websocket-Key": "Sec-WebSocket-Key", - "Sec-Websocket-Protocol": "Sec-WebSocket-Protocol", - "Sec-Websocket-Version": "Sec-WebSocket-Version", - "Setprofile": "SetProfile", - "Slug": "SLUG", - "Soapaction": "SoapAction", - "Status-Uri": "Status-URI", - "Tcn": "TCN", - "Te": "TE", - "Ttl": "TTL", - "Uri": "URI", - "Www-Authenticate": "WWW-Authenticate", - "X-Correlation-Id": "X-Correlation-ID", - "X-Dns-Prefetch-Control": "X-DNS-Prefetch-Control", - "X-Real-Ip": "X-Real-IP", - "X-Request-Id": "X-Request-ID", - "X-Ua-Compatible": "X-UA-Compatible", - "X-Webkit-Csp": "X-WebKit-CSP", - "X-Xss": "X-XSS", - "X-Xss-Protection": "X-XSS-Protection", - } -} diff --git a/vendor/github.com/lasiar/canonicalheader/literal_string.go b/vendor/github.com/lasiar/canonicalheader/literal_string.go deleted file mode 100644 index 71cd5f3974..0000000000 --- a/vendor/github.com/lasiar/canonicalheader/literal_string.go +++ /dev/null @@ -1,80 +0,0 @@ -package canonicalheader - -import ( - "fmt" - "go/ast" - "go/token" - "strconv" - "unicode/utf8" - "unsafe" - - "golang.org/x/tools/go/analysis" -) - -type literalString struct { - originalValue string - quote byte - pos, end token.Pos -} - -func newLiteralString(basicList *ast.BasicLit) (literalString, error) { - if basicList.Kind != token.STRING { - return literalString{}, fmt.Errorf("%#v is not a string", basicList) - } - - if len(basicList.Value) < 2 { - return literalString{}, fmt.Errorf("%#v has a strange value length %q", basicList, basicList.Value) - } - - quote := basicList.Value[0] - switch quote { - case '`', '"': - default: - return literalString{}, fmt.Errorf("%q is a strange quote", quote) - } - - originalValue, err := strconv.Unquote(basicList.Value) - if err != nil { - return literalString{}, fmt.Errorf("unquote %q: %w", basicList.Value, err) - } - - if !utf8.ValidString(originalValue) { - return literalString{}, fmt.Errorf("%#v is not a valid utf8 string", basicList.Value) - } - - return literalString{ - originalValue: originalValue, - quote: quote, - pos: basicList.Pos(), - end: basicList.End(), - }, nil -} - -func (l literalString) diagnostic(canonicalHeader string) analysis.Diagnostic { - newText := make([]byte, 0, len(canonicalHeader)+2) - newText = append(newText, l.quote) - newText = append(newText, unsafe.Slice(unsafe.StringData(canonicalHeader), len(canonicalHeader))...) - newText = append(newText, l.quote) - - return analysis.Diagnostic{ - Pos: l.pos, - End: l.end, - Message: fmt.Sprintf("non-canonical header %q, instead use: %q", l.originalValue, canonicalHeader), - SuggestedFixes: []analysis.SuggestedFix{ - { - Message: fmt.Sprintf("should replace %q with %q", l.originalValue, canonicalHeader), - TextEdits: []analysis.TextEdit{ - { - Pos: l.pos, - End: l.end, - NewText: newText, - }, - }, - }, - }, - } -} - -func (l literalString) value() string { - return l.originalValue -} diff --git a/vendor/github.com/lasiar/canonicalheader/makefile b/vendor/github.com/lasiar/canonicalheader/makefile deleted file mode 100644 index a96cb628e5..0000000000 --- a/vendor/github.com/lasiar/canonicalheader/makefile +++ /dev/null @@ -1,12 +0,0 @@ -.PHONY: - -test: - go test -v -race ./... - -linter: - golangci-lint -v run ./... - -generate: - go run ./cmd/initialismer/*.go -target="mapping" > ./initialism.go - go run ./cmd/initialismer/*.go -target="test" > ./testdata/src/initialism/initialism.go - gofmt -w ./initialism.go ./testdata/src/initialism/initialism.go diff --git a/vendor/github.com/ldez/exptostd/.gitignore b/vendor/github.com/ldez/exptostd/.gitignore deleted file mode 100644 index ec3a603988..0000000000 --- a/vendor/github.com/ldez/exptostd/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/exptostd -.idea diff --git a/vendor/github.com/ldez/exptostd/.golangci.yml b/vendor/github.com/ldez/exptostd/.golangci.yml deleted file mode 100644 index 2675c2863e..0000000000 --- a/vendor/github.com/ldez/exptostd/.golangci.yml +++ /dev/null @@ -1,79 +0,0 @@ -version: "2" - -formatters: - enable: - - gci - - gofumpt - settings: - gofumpt: - extra-rules: true - -linters: - default: all - disable: - - cyclop # duplicate of gocyclo - - dupl - - errchkjson - - exhaustive - - exhaustruct - - lll - - nilnil - - nlreturn - - nonamedreturns - - paralleltest - - prealloc - - rowserrcheck # not relevant (SQL) - - sqlclosecheck # not relevant (SQL) - - testpackage - - tparallel - - varnamelen - - wsl # deprecated - settings: - depguard: - rules: - main: - deny: - - pkg: github.com/instana/testify - desc: not allowed - - pkg: github.com/pkg/errors - desc: Should be replaced by standard lib errors package - funlen: - lines: -1 - statements: 40 - goconst: - min-len: 5 - min-occurrences: 3 - gocritic: - disabled-checks: - - sloppyReassign - - rangeValCopy - - octalLiteral - - paramTypeCombine # already handle by gofumpt.extra-rules - enabled-tags: - - diagnostic - - style - - performance - settings: - hugeParam: - sizeThreshold: 100 - gocyclo: - min-complexity: 20 - godox: - keywords: - - FIXME - govet: - disable: - - fieldalignment - enable-all: true - misspell: - locale: US - nolintlint: - require-explanation: true - require-specific: true - wsl: - force-case-trailing-whitespace: 1 - allow-trailing-comment: true - -issues: - max-issues-per-linter: 0 - max-same-issues: 0 diff --git a/vendor/github.com/ldez/exptostd/LICENSE b/vendor/github.com/ldez/exptostd/LICENSE deleted file mode 100644 index c1bf0c3288..0000000000 --- a/vendor/github.com/ldez/exptostd/LICENSE +++ /dev/null @@ -1,190 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2024 Fernandez Ludovic - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/ldez/exptostd/Makefile b/vendor/github.com/ldez/exptostd/Makefile deleted file mode 100644 index ad72751490..0000000000 --- a/vendor/github.com/ldez/exptostd/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -.PHONY: clean check test build - -default: clean check test build - -clean: - rm -rf dist/ cover.out - -test: clean - go test -v -cover ./... - -check: - golangci-lint run - -build: - go build -ldflags "-s -w" -trimpath ./cmd/exptostd/ diff --git a/vendor/github.com/ldez/exptostd/exptostd.go b/vendor/github.com/ldez/exptostd/exptostd.go deleted file mode 100644 index aa5dc5ada1..0000000000 --- a/vendor/github.com/ldez/exptostd/exptostd.go +++ /dev/null @@ -1,482 +0,0 @@ -// Package exptostd It is an analyzer that detects functions from golang.org/x/exp/ that can be replaced by std functions. -package exptostd - -import ( - "bytes" - "fmt" - "go/ast" - "go/build" - "go/printer" - "go/token" - "go/types" - "os" - "slices" - "strconv" - "strings" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/inspector" -) - -const ( - pkgExpMaps = "golang.org/x/exp/maps" - pkgExpSlices = "golang.org/x/exp/slices" - pkgExpConstraints = "golang.org/x/exp/constraints" -) - -const ( - pkgMaps = "maps" - pkgSlices = "slices" - pkgComp = "cmp" -) - -const ( - go123 = 123 - go121 = 121 - goDevel = 666 -) - -// Result is step analysis results. -type Result struct { - shouldKeepImport bool - Diagnostics []analysis.Diagnostic -} - -type stdReplacement[T ast.Expr] struct { - MinGo int - Text string - Suggested func(callExpr T) (analysis.SuggestedFix, error) -} - -type analyzer struct { - mapsPkgReplacements map[string]stdReplacement[*ast.CallExpr] - slicesPkgReplacements map[string]stdReplacement[*ast.CallExpr] - constraintsPkgReplacements map[string]stdReplacement[*ast.SelectorExpr] - - skipGoVersionDetection bool -} - -// NewAnalyzer create a new Analyzer. -func NewAnalyzer() *analysis.Analyzer { - _, skip := os.LookupEnv("EXPTOSTD_SKIP_GO_VERSION_CHECK") - - l := &analyzer{ - skipGoVersionDetection: skip, - mapsPkgReplacements: map[string]stdReplacement[*ast.CallExpr]{ - "Keys": {MinGo: go123, Text: "slices.AppendSeq(make([]T, 0, len(data)), maps.Keys(data))", Suggested: suggestedFixForKeysOrValues}, - "Values": {MinGo: go123, Text: "slices.AppendSeq(make([]T, 0, len(data)), maps.Values(data))", Suggested: suggestedFixForKeysOrValues}, - "Equal": {MinGo: go121, Text: "maps.Equal()"}, - "EqualFunc": {MinGo: go121, Text: "maps.EqualFunc()"}, - "Clone": {MinGo: go121, Text: "maps.Clone()"}, - "Copy": {MinGo: go121, Text: "maps.Copy()"}, - "DeleteFunc": {MinGo: go121, Text: "maps.DeleteFunc()"}, - "Clear": {MinGo: go121, Text: "clear()", Suggested: suggestedFixForClear}, - }, - slicesPkgReplacements: map[string]stdReplacement[*ast.CallExpr]{ - "Equal": {MinGo: go121, Text: "slices.Equal()"}, - "EqualFunc": {MinGo: go121, Text: "slices.EqualFunc()"}, - "Compare": {MinGo: go121, Text: "slices.Compare()"}, - "CompareFunc": {MinGo: go121, Text: "slices.CompareFunc()"}, - "Index": {MinGo: go121, Text: "slices.Index()"}, - "IndexFunc": {MinGo: go121, Text: "slices.IndexFunc()"}, - "Contains": {MinGo: go121, Text: "slices.Contains()"}, - "ContainsFunc": {MinGo: go121, Text: "slices.ContainsFunc()"}, - "Insert": {MinGo: go121, Text: "slices.Insert()"}, - "Delete": {MinGo: go121, Text: "slices.Delete()"}, - "DeleteFunc": {MinGo: go121, Text: "slices.DeleteFunc()"}, - "Replace": {MinGo: go121, Text: "slices.Replace()"}, - "Clone": {MinGo: go121, Text: "slices.Clone()"}, - "Compact": {MinGo: go121, Text: "slices.Compact()"}, - "CompactFunc": {MinGo: go121, Text: "slices.CompactFunc()"}, - "Grow": {MinGo: go121, Text: "slices.Grow()"}, - "Clip": {MinGo: go121, Text: "slices.Clip()"}, - "Reverse": {MinGo: go121, Text: "slices.Reverse()"}, - - "Sort": {MinGo: go121, Text: "slices.Sort()"}, - "SortFunc": {MinGo: go121, Text: "slices.SortFunc()"}, - "SortStableFunc": {MinGo: go121, Text: "slices.SortStableFunc()"}, - "IsSorted": {MinGo: go121, Text: "slices.IsSorted()"}, - "IsSortedFunc": {MinGo: go121, Text: "slices.IsSortedFunc()"}, - "Min": {MinGo: go121, Text: "slices.Min()"}, - "MinFunc": {MinGo: go121, Text: "slices.MinFunc()"}, - "Max": {MinGo: go121, Text: "slices.Max()"}, - "MaxFunc": {MinGo: go121, Text: "slices.MaxFunc()"}, - "BinarySearch": {MinGo: go121, Text: "slices.BinarySearch()"}, - "BinarySearchFunc": {MinGo: go121, Text: "slices.BinarySearchFunc()"}, - }, - constraintsPkgReplacements: map[string]stdReplacement[*ast.SelectorExpr]{ - "Ordered": {MinGo: go121, Text: "cmp.Ordered", Suggested: suggestedFixForConstraintsOrder}, - }, - } - - return &analysis.Analyzer{ - Name: "exptostd", - Doc: "Detects functions from golang.org/x/exp/ that can be replaced by std functions.", - Run: l.run, - Requires: []*analysis.Analyzer{inspect.Analyzer}, - } -} - -//nolint:gocognit,gocyclo // The complexity is expected by the cases to handle. -func (a *analyzer) run(pass *analysis.Pass) (any, error) { - insp, ok := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - if !ok { - return nil, nil - } - - goVersion := getGoVersion(pass) - - nodeFilter := []ast.Node{ - (*ast.CallExpr)(nil), - (*ast.FuncDecl)(nil), - (*ast.TypeSpec)(nil), - (*ast.ImportSpec)(nil), - } - - imports := map[string]*ast.ImportSpec{} - - var shouldKeepExpMaps bool - - var resultExpSlices Result - - resultExpConstraints := &Result{} - - insp.Preorder(nodeFilter, func(n ast.Node) { - switch node := n.(type) { - case *ast.ImportSpec: - // skip aliases - if node.Name == nil || node.Name.Name == "" { - imports[trimImportPath(node)] = node - } - - return - - case *ast.CallExpr: - selExpr, ok := node.Fun.(*ast.SelectorExpr) - if !ok { - return - } - - ident, ok := selExpr.X.(*ast.Ident) - if !ok { - return - } - - switch ident.Name { - case pkgMaps: - diagnostic, usage := a.detectPackageUsage(pass, a.mapsPkgReplacements, selExpr, ident, node, pkgExpMaps, goVersion) - if usage { - pass.Report(diagnostic) - } - - shouldKeepExpMaps = shouldKeepExpMaps || !usage - - case pkgSlices: - diagnostic, usage := a.detectPackageUsage(pass, a.slicesPkgReplacements, selExpr, ident, node, pkgExpSlices, goVersion) - if usage { - resultExpSlices.Diagnostics = append(resultExpSlices.Diagnostics, diagnostic) - } - - resultExpSlices.shouldKeepImport = resultExpSlices.shouldKeepImport || !usage - } - - case *ast.FuncDecl: - if node.Type.TypeParams != nil { - for _, field := range node.Type.TypeParams.List { - a.detectConstraintsUsage(pass, field.Type, resultExpConstraints, goVersion) - } - } - - case *ast.TypeSpec: - if node.TypeParams != nil { - for _, field := range node.TypeParams.List { - a.detectConstraintsUsage(pass, field.Type, resultExpConstraints, goVersion) - } - } - - interfaceType, ok := node.Type.(*ast.InterfaceType) - if !ok { - return - } - - for _, method := range interfaceType.Methods.List { - switch exp := method.Type.(type) { - case *ast.BinaryExpr: - a.detectConstraintsUsage(pass, exp.X, resultExpConstraints, goVersion) - a.detectConstraintsUsage(pass, exp.Y, resultExpConstraints, goVersion) - - case *ast.SelectorExpr: - a.detectConstraintsUsage(pass, exp, resultExpConstraints, goVersion) - } - } - } - }) - - // maps - a.suggestReplaceImport(pass, imports, shouldKeepExpMaps, pkgExpMaps, pkgMaps) - - // slices - if resultExpSlices.shouldKeepImport { - for _, diagnostic := range resultExpSlices.Diagnostics { - pass.Report(diagnostic) - } - } else { - a.suggestReplaceImport(pass, imports, resultExpSlices.shouldKeepImport, pkgExpSlices, pkgSlices) - } - - // constraints - a.suggestReplaceImport(pass, imports, resultExpConstraints.shouldKeepImport, pkgExpConstraints, pkgComp) - - return nil, nil -} - -func (a *analyzer) detectPackageUsage(pass *analysis.Pass, - replacements map[string]stdReplacement[*ast.CallExpr], - selExpr *ast.SelectorExpr, ident *ast.Ident, callExpr *ast.CallExpr, - importPath string, goVersion int, -) (analysis.Diagnostic, bool) { - rp, ok := replacements[selExpr.Sel.Name] - if !ok { - return analysis.Diagnostic{}, false - } - - if !a.skipGoVersionDetection && rp.MinGo > goVersion { - return analysis.Diagnostic{}, false - } - - if !isPackageUsed(pass, ident, importPath) { - return analysis.Diagnostic{}, false - } - - diagnostic := analysis.Diagnostic{ - Pos: callExpr.Pos(), - Message: fmt.Sprintf("%s.%s() can be replaced by %s", importPath, selExpr.Sel.Name, rp.Text), - } - - if rp.Suggested != nil { - fix, err := rp.Suggested(callExpr) - if err != nil { - diagnostic.Message = fmt.Sprintf("Suggested fix error: %v", err) - } else { - diagnostic.SuggestedFixes = append(diagnostic.SuggestedFixes, fix) - } - } - - return diagnostic, true -} - -func (a *analyzer) detectConstraintsUsage(pass *analysis.Pass, expr ast.Expr, result *Result, goVersion int) { - switch selExpr := expr.(type) { - case *ast.SelectorExpr: - ident, ok := selExpr.X.(*ast.Ident) - if !ok { - return - } - - if !isPackageUsed(pass, ident, pkgExpConstraints) { - return - } - - rp, ok := a.constraintsPkgReplacements[selExpr.Sel.Name] - if !ok { - result.shouldKeepImport = true - return - } - - if !a.skipGoVersionDetection && rp.MinGo > goVersion { - result.shouldKeepImport = true - return - } - - diagnostic := analysis.Diagnostic{ - Pos: selExpr.Pos(), - Message: fmt.Sprintf("%s.%s can be replaced by %s", pkgExpConstraints, selExpr.Sel.Name, rp.Text), - } - - if rp.Suggested != nil { - fix, err := rp.Suggested(selExpr) - if err != nil { - diagnostic.Message = fmt.Sprintf("Suggested fix error: %v", err) - } else { - diagnostic.SuggestedFixes = append(diagnostic.SuggestedFixes, fix) - } - } - - pass.Report(diagnostic) - - case *ast.BinaryExpr: - a.detectConstraintsUsage(pass, selExpr.X, result, goVersion) - a.detectConstraintsUsage(pass, selExpr.Y, result, goVersion) - - case *ast.UnaryExpr: - a.detectConstraintsUsage(pass, selExpr.X, result, goVersion) - - default: - return - } -} - -func (a *analyzer) suggestReplaceImport(pass *analysis.Pass, imports map[string]*ast.ImportSpec, shouldKeep bool, importPath, stdPackage string) { - imp, ok := imports[importPath] - if !ok || shouldKeep { - return - } - - src := trimImportPath(imp) - - pass.Report(analysis.Diagnostic{ - Pos: imp.Pos(), - End: imp.End(), - Message: fmt.Sprintf("Import statement '%s' may be replaced by '%s'", src, stdPackage), - SuggestedFixes: []analysis.SuggestedFix{{ - TextEdits: []analysis.TextEdit{{ - Pos: imp.Path.Pos(), - End: imp.Path.End(), - NewText: []byte(string(imp.Path.Value[0]) + stdPackage + string(imp.Path.Value[0])), - }}, - }}, - }) -} - -func suggestedFixForClear(callExpr *ast.CallExpr) (analysis.SuggestedFix, error) { - s := &ast.CallExpr{ - Fun: ast.NewIdent("clear"), - Args: callExpr.Args, - Ellipsis: callExpr.Ellipsis, - } - - buf := bytes.NewBuffer(nil) - - err := printer.Fprint(buf, token.NewFileSet(), s) - if err != nil { - return analysis.SuggestedFix{}, fmt.Errorf("print suggested fix: %w", err) - } - - return analysis.SuggestedFix{ - TextEdits: []analysis.TextEdit{{ - Pos: callExpr.Pos(), - End: callExpr.End(), - NewText: buf.Bytes(), - }}, - }, nil -} - -func suggestedFixForKeysOrValues(callExpr *ast.CallExpr) (analysis.SuggestedFix, error) { - s := &ast.CallExpr{ - Fun: &ast.SelectorExpr{ - X: &ast.Ident{Name: "slices"}, - Sel: &ast.Ident{Name: "AppendSeq"}, - }, - Args: []ast.Expr{ - &ast.CallExpr{ - Fun: &ast.Ident{Name: "make"}, - Args: []ast.Expr{ - &ast.ArrayType{ - Elt: &ast.Ident{Name: "FIXME"}, // TODO(ldez) improve the type detection. - }, - &ast.BasicLit{Kind: token.INT, Value: "0"}, - &ast.CallExpr{ - Fun: &ast.Ident{Name: "len"}, - Args: callExpr.Args, - }, - }, - }, - callExpr, - }, - } - - buf := bytes.NewBuffer(nil) - - err := printer.Fprint(buf, token.NewFileSet(), s) - if err != nil { - return analysis.SuggestedFix{}, fmt.Errorf("print suggested fix: %w", err) - } - - return analysis.SuggestedFix{ - TextEdits: []analysis.TextEdit{{ - Pos: callExpr.Pos(), - End: callExpr.End(), - NewText: buf.Bytes(), - }}, - }, nil -} - -func suggestedFixForConstraintsOrder(selExpr *ast.SelectorExpr) (analysis.SuggestedFix, error) { - s := &ast.SelectorExpr{ - X: &ast.Ident{Name: pkgComp}, - Sel: &ast.Ident{Name: "Ordered"}, - } - - buf := bytes.NewBuffer(nil) - - err := printer.Fprint(buf, token.NewFileSet(), s) - if err != nil { - return analysis.SuggestedFix{}, fmt.Errorf("print suggested fix: %w", err) - } - - return analysis.SuggestedFix{ - TextEdits: []analysis.TextEdit{{ - Pos: selExpr.Pos(), - End: selExpr.End(), - NewText: buf.Bytes(), - }}, - }, nil -} - -func isPackageUsed(pass *analysis.Pass, ident *ast.Ident, importPath string) bool { - obj := pass.TypesInfo.Uses[ident] - if obj == nil { - return false - } - - pkg, ok := obj.(*types.PkgName) - if !ok { - return false - } - - if pkg.Imported().Path() != importPath { - return false - } - - return true -} - -func getGoVersion(pass *analysis.Pass) int { - // Prior to go1.22, versions.FileVersion returns only the toolchain version, - // which is of no use to us, - // so disable this analyzer on earlier versions. - if !slices.Contains(build.Default.ReleaseTags, "go1.22") { - return 0 // false - } - - pkgVersion := pass.Pkg.GoVersion() - if pkgVersion == "" { - // Empty means Go devel. - return goDevel // true - } - - raw := strings.TrimPrefix(pkgVersion, "go") - - // prerelease version (go1.24rc1) - idx := strings.IndexFunc(raw, func(r rune) bool { - return (r < '0' || r > '9') && r != '.' - }) - - if idx != -1 { - raw = raw[:idx] - } - - vParts := strings.Split(raw, ".") - - v, err := strconv.Atoi(strings.Join(vParts[:2], "")) - if err != nil { - v = 116 - } - - return v -} - -func trimImportPath(spec *ast.ImportSpec) string { - return spec.Path.Value[1 : len(spec.Path.Value)-1] -} diff --git a/vendor/github.com/ldez/exptostd/readme.md b/vendor/github.com/ldez/exptostd/readme.md deleted file mode 100644 index bd1df8d547..0000000000 --- a/vendor/github.com/ldez/exptostd/readme.md +++ /dev/null @@ -1,116 +0,0 @@ -# ExpToStd - -Detects functions from golang.org/x/exp/ that can be replaced by std functions. - -[![Sponsor](https://img.shields.io/badge/Sponsor%20me-%E2%9D%A4%EF%B8%8F-pink)](https://github.com/sponsors/ldez) - -Actual detections: - -- `golang.org/x/exp/maps`: - - `Keys` - - `Values` - - `Equal` - - `EqualFunc` - - `Clone` - - `Copy` - - `DeleteFunc` - - `Clear` - -- `golang.org/x/exp/slices`: - - `Equal` - - `EqualFunc` - - `Compare` - - `CompareFunc` - - `Index` - - `IndexFunc` - - `Contains` - - `ContainsFunc` - - `Insert` - - `Delete` - - `DeleteFunc` - - `Replace` - - `Clone` - - `Compact` - - `CompactFunc` - - `Grow` - - `Clip` - - `Reverse` - - `Sort` - - `SortFunc` - - `SortStableFunc` - - `IsSorted` - - `IsSortedFunc` - - `Min` - - `MinFunc` - - `Max` - - `MaxFunc` - - `BinarySearch` - - `BinarySearchFunc` - -- `golang.org/x/exp/constraints`: - - `Ordered` - -## Usages - -### Inside golangci-lint - -Recommended. - -```yaml -linters: - enable: - - exptostd -``` - -### As a CLI - -```bash -go install github.com/ldez/exptostd/cmd/exptostd@latest -``` - -```bash -./exptostd ./... -``` - -## Examples - -```go -package foo - -import ( - "fmt" - - "golang.org/x/exp/maps" -) - -func foo(m map[string]string) { - clone := maps.Clone(m) - - fmt.Println(clone) -} -``` - -It can be replaced by: - -```go -package foo - -import ( - "fmt" - "maps" -) - -func foo(m map[string]string) { - clone := maps.Clone(m) - - fmt.Println(clone) -} - -``` - -## References - -- https://tip.golang.org/doc/go1.21#maps -- https://tip.golang.org/doc/go1.21#slices -- https://tip.golang.org/doc/go1.23#iterators -- https://tip.golang.org/doc/go1.21#cmp diff --git a/vendor/github.com/ldez/gomoddirectives/.gitignore b/vendor/github.com/ldez/gomoddirectives/.gitignore deleted file mode 100644 index 9da3e0da99..0000000000 --- a/vendor/github.com/ldez/gomoddirectives/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -.idea/ -/gomoddirectives diff --git a/vendor/github.com/ldez/gomoddirectives/.golangci.yml b/vendor/github.com/ldez/gomoddirectives/.golangci.yml deleted file mode 100644 index 8eb11ff019..0000000000 --- a/vendor/github.com/ldez/gomoddirectives/.golangci.yml +++ /dev/null @@ -1,100 +0,0 @@ -version: "2" - -formatters: - enable: - - gci - - gofumpt - settings: - gofumpt: - extra-rules: true - -linters: - default: all - disable: - - bodyclose - - cyclop # duplicate of gocyclo - - dupl - - err113 - - exhaustive - - exhaustruct - - lll - - mnd - - nlreturn - - paralleltest - - prealloc - - rowserrcheck # not relevant (SQL) - - sqlclosecheck # not relevant (SQL) - - testpackage - - tparallel - - varnamelen - - wrapcheck - - wsl # deprecated - - settings: - depguard: - rules: - main: - deny: - - pkg: github.com/instana/testify - desc: not allowed - - pkg: github.com/pkg/errors - desc: Should be replaced by standard lib errors package - forbidigo: - forbid: - - pattern: ^print(ln)?$ - - pattern: ^fmt\.Print(f|ln)?$ - - pattern: ^panic$ - - pattern: ^spew\.Print(f|ln)?$ - - pattern: ^spew\.Dump$ - funlen: - lines: -1 - goconst: - min-len: 3 - min-occurrences: 3 - gocritic: - disabled-checks: - - sloppyReassign - - rangeValCopy - - octalLiteral - - paramTypeCombine # already handle by gofumpt.extra-rules - enabled-tags: - - diagnostic - - style - - performance - settings: - hugeParam: - sizeThreshold: 100 - gocyclo: - min-complexity: 12 - godox: - keywords: - - FIXME - govet: - disable: - - fieldalignment - enable-all: true - misspell: - locale: US - tagliatelle: - case: - rules: - json: pascal - - exclusions: - warn-unused: true - presets: - - comments - rules: - - linters: - - funlen - - goconst - - maintidx - path: (.+)_test.go - - linters: - - forbidigo - path: cmd/gomoddirectives/gomoddirectives.go - text: use of `fmt.Println` forbidden - -issues: - max-issues-per-linter: 0 - max-same-issues: 0 diff --git a/vendor/github.com/ldez/gomoddirectives/LICENSE b/vendor/github.com/ldez/gomoddirectives/LICENSE deleted file mode 100644 index c1bf0c3288..0000000000 --- a/vendor/github.com/ldez/gomoddirectives/LICENSE +++ /dev/null @@ -1,190 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2024 Fernandez Ludovic - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/ldez/gomoddirectives/Makefile b/vendor/github.com/ldez/gomoddirectives/Makefile deleted file mode 100644 index 5a0a852c8d..0000000000 --- a/vendor/github.com/ldez/gomoddirectives/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -.PHONY: clean check test build - -default: clean check test build - -clean: - rm -rf dist/ cover.out - -test: clean - go test -v -cover ./... - -check: - golangci-lint run - -build: - go build -ldflags "-s -w" -trimpath ./cmd/gomoddirectives/ diff --git a/vendor/github.com/ldez/gomoddirectives/gomoddirectives.go b/vendor/github.com/ldez/gomoddirectives/gomoddirectives.go deleted file mode 100644 index 7e3df677cb..0000000000 --- a/vendor/github.com/ldez/gomoddirectives/gomoddirectives.go +++ /dev/null @@ -1,273 +0,0 @@ -// Package gomoddirectives a linter that handle directives into `go.mod`. -package gomoddirectives - -import ( - "context" - "fmt" - "go/token" - "regexp" - "strings" - - "github.com/ldez/grignotin/gomod" - "golang.org/x/mod/modfile" - "golang.org/x/tools/go/analysis" -) - -const ( - reasonExclude = "exclude directive is not allowed" - reasonGoDebug = "godebug directive is not allowed" - reasonGoVersion = "go directive (%s) doesn't match the pattern '%s'" - reasonIgnore = "ignore directive is not allowed" - reasonReplace = "replacement are not allowed" - reasonReplaceDuplicate = "multiple replacement of the same module" - reasonReplaceIdentical = "the original module and the replacement are identical" - reasonReplaceLocal = "local replacement are not allowed" - reasonRetract = "a comment is mandatory to explain why the version has been retracted" - reasonTool = "tool directive is not allowed" - reasonToolchain = "toolchain directive is not allowed" - reasonToolchainPattern = "toolchain directive (%s) doesn't match the pattern '%s'" -) - -// Result the analysis result. -type Result struct { - Reason string - Start token.Position - End token.Position -} - -// NewResult creates a new Result. -func NewResult(file *modfile.File, line *modfile.Line, reason string) Result { - return Result{ - Start: token.Position{Filename: file.Syntax.Name, Line: line.Start.Line, Column: line.Start.LineRune}, - End: token.Position{Filename: file.Syntax.Name, Line: line.End.Line, Column: line.End.LineRune}, - Reason: reason, - } -} - -func (r Result) String() string { - return fmt.Sprintf("%s: %s", r.Start, r.Reason) -} - -// Options the analyzer options. -type Options struct { - ReplaceAllowList []string - ReplaceAllowLocal bool - ExcludeForbidden bool - IgnoreForbidden bool - RetractAllowNoExplanation bool - ToolchainForbidden bool - ToolchainPattern *regexp.Regexp - ToolForbidden bool - GoDebugForbidden bool - GoVersionPattern *regexp.Regexp -} - -// AnalyzePass analyzes a pass. -func AnalyzePass(pass *analysis.Pass, opts Options) ([]Result, error) { - info, err := gomod.GetModuleInfo(context.Background()) - if err != nil { - return nil, fmt.Errorf("get information about modules: %w", err) - } - - goMod := info[0].GoMod - - if pass.Module != nil && pass.Module.Path != "" { - for _, m := range info { - if m.Path == pass.Module.Path { - goMod = m.GoMod - break - } - } - } - - f, err := parseGoMod(goMod) - if err != nil { - return nil, fmt.Errorf("parse %s: %w", goMod, err) - } - - return AnalyzeFile(f, opts), nil -} - -// Analyze analyzes a project. -func Analyze(opts Options) ([]Result, error) { - f, err := GetModuleFile() - if err != nil { - return nil, fmt.Errorf("failed to get module file: %w", err) - } - - return AnalyzeFile(f, opts), nil -} - -// AnalyzeFile analyzes a mod file. -func AnalyzeFile(file *modfile.File, opts Options) []Result { - checks := []func(file *modfile.File, opts Options) []Result{ - checkRetractDirectives, - checkExcludeDirectives, - checkToolDirectives, - checkIgnoreDirectives, - checkReplaceDirectives, - checkToolchainDirective, - checkGoDebugDirectives, - checkGoVersionDirectives, - } - - var results []Result - for _, check := range checks { - results = append(results, check(file, opts)...) - } - - return results -} - -func checkGoVersionDirectives(file *modfile.File, opts Options) []Result { - if file == nil || file.Go == nil || opts.GoVersionPattern == nil || opts.GoVersionPattern.MatchString(file.Go.Version) { - return nil - } - - return []Result{NewResult(file, file.Go.Syntax, fmt.Sprintf(reasonGoVersion, file.Go.Version, opts.GoVersionPattern.String()))} -} - -func checkToolchainDirective(file *modfile.File, opts Options) []Result { - if file.Toolchain == nil { - return nil - } - - if opts.ToolchainForbidden { - return []Result{NewResult(file, file.Toolchain.Syntax, reasonToolchain)} - } - - if opts.ToolchainPattern == nil { - return nil - } - - if !opts.ToolchainPattern.MatchString(file.Toolchain.Name) { - return []Result{NewResult(file, file.Toolchain.Syntax, fmt.Sprintf(reasonToolchainPattern, file.Toolchain.Name, opts.ToolchainPattern.String()))} - } - - return nil -} - -func checkRetractDirectives(file *modfile.File, opts Options) []Result { - if opts.RetractAllowNoExplanation { - return nil - } - - var results []Result - - for _, retract := range file.Retract { - if retract.Rationale != "" { - continue - } - - results = append(results, NewResult(file, retract.Syntax, reasonRetract)) - } - - return results -} - -func checkExcludeDirectives(file *modfile.File, opts Options) []Result { - if !opts.ExcludeForbidden { - return nil - } - - var results []Result - - for _, exclude := range file.Exclude { - results = append(results, NewResult(file, exclude.Syntax, reasonExclude)) - } - - return results -} - -func checkIgnoreDirectives(file *modfile.File, opts Options) []Result { - if !opts.IgnoreForbidden { - return nil - } - - var results []Result - - for _, exclude := range file.Ignore { - results = append(results, NewResult(file, exclude.Syntax, reasonIgnore)) - } - - return results -} - -func checkToolDirectives(file *modfile.File, opts Options) []Result { - if !opts.ToolForbidden { - return nil - } - - var results []Result - - for _, tool := range file.Tool { - results = append(results, NewResult(file, tool.Syntax, reasonTool)) - } - - return results -} - -func checkReplaceDirectives(file *modfile.File, opts Options) []Result { - var results []Result - - uniqReplace := map[string]struct{}{} - - for _, replace := range file.Replace { - reason := checkReplaceDirective(opts, replace) - if reason != "" { - results = append(results, NewResult(file, replace.Syntax, reason)) - continue - } - - if replace.Old.Path == replace.New.Path && replace.Old.Version == replace.New.Version { - results = append(results, NewResult(file, replace.Syntax, reasonReplaceIdentical)) - continue - } - - if _, ok := uniqReplace[replace.Old.Path+replace.Old.Version]; ok { - results = append(results, NewResult(file, replace.Syntax, reasonReplaceDuplicate)) - } - - uniqReplace[replace.Old.Path+replace.Old.Version] = struct{}{} - } - - return results -} - -func checkReplaceDirective(opts Options, r *modfile.Replace) string { - if isLocal(r) { - if opts.ReplaceAllowLocal { - return "" - } - - return fmt.Sprintf("%s: %s", reasonReplaceLocal, r.Old.Path) - } - - for _, v := range opts.ReplaceAllowList { - if r.Old.Path == v { - return "" - } - } - - return fmt.Sprintf("%s: %s", reasonReplace, r.Old.Path) -} - -func checkGoDebugDirectives(file *modfile.File, opts Options) []Result { - if !opts.GoDebugForbidden { - return nil - } - - var results []Result - - for _, goDebug := range file.Godebug { - results = append(results, NewResult(file, goDebug.Syntax, reasonGoDebug)) - } - - return results -} - -// Filesystem paths found in "replace" directives are represented by a path with an empty version. -// https://github.com/golang/mod/blob/bc388b264a244501debfb9caea700c6dcaff10e2/module/module.go#L122-L124 -func isLocal(r *modfile.Replace) bool { - return strings.TrimSpace(r.New.Version) == "" -} diff --git a/vendor/github.com/ldez/gomoddirectives/module.go b/vendor/github.com/ldez/gomoddirectives/module.go deleted file mode 100644 index c3e47c8a4f..0000000000 --- a/vendor/github.com/ldez/gomoddirectives/module.go +++ /dev/null @@ -1,35 +0,0 @@ -package gomoddirectives - -import ( - "context" - "fmt" - "os" - "path/filepath" - - "github.com/ldez/grignotin/goenv" - "golang.org/x/mod/modfile" -) - -// GetModuleFile gets module file. -func GetModuleFile() (*modfile.File, error) { - goMod, err := goenv.GetOne(context.Background(), goenv.GOMOD) - if err != nil { - return nil, err - } - - mod, err := parseGoMod(goMod) - if err != nil { - return nil, fmt.Errorf("failed to parse go.mod (%s): %w", goMod, err) - } - - return mod, nil -} - -func parseGoMod(goMod string) (*modfile.File, error) { - raw, err := os.ReadFile(filepath.Clean(goMod)) - if err != nil { - return nil, fmt.Errorf("reading go.mod file: %w", err) - } - - return modfile.Parse("go.mod", raw, nil) -} diff --git a/vendor/github.com/ldez/gomoddirectives/readme.md b/vendor/github.com/ldez/gomoddirectives/readme.md deleted file mode 100644 index 054af46259..0000000000 --- a/vendor/github.com/ldez/gomoddirectives/readme.md +++ /dev/null @@ -1,222 +0,0 @@ -# gomoddirectives - -A linter that handle directives into `go.mod`. - -[![Sponsor](https://img.shields.io/badge/Sponsor%20me-%E2%9D%A4%EF%B8%8F-pink)](https://github.com/sponsors/ldez) -[![Build Status](https://github.com/ldez/gomoddirectives/workflows/Main/badge.svg?branch=master)](https://github.com/ldez/gomoddirectives/actions) - -## Usage - -### Inside golangci-lint - -Recommended. - -```yml -linters: - enable: - - gomoddirectives - - settings: - gomoddirectives: - # Allow local `replace` directives. - # Default: false - replace-local: true - - # List of allowed `replace` directives. - # Default: [] - replace-allow-list: - - launchpad.net/gocheck - - # Allow to not explain why the version has been retracted in the `retract` directives. - # Default: false - retract-allow-no-explanation: true - - # Forbid the use of the `exclude` directives. - # Default: false - exclude-forbidden: true - - # Forbid the use of the `ignore` directives (go >= 1.25). - # Default: false - ignore-forbidden: true - - # Forbid the use of the `toolchain` directive. - # Default: false - toolchain-forbidden: true - - # Defines a pattern to validate `toolchain` directive. - # Default: '' (no match) - toolchain-pattern: 'go1\.22\.\d+$' - - # Forbid the use of the `tool` directives. - # Default: false - tool-forbidden: true - - # Forbid the use of the `godebug` directive. - # Default: false - go-debug-forbidden: true - - # Defines a pattern to validate `go` minimum version directive. - # Default: '' (no match) - go-version-pattern: '1\.\d+(\.0)?$' -``` - -### As a CLI - -``` -gomoddirectives [flags] - -Flags: - -exclude - Forbid the use of exclude directives - -godebug - Forbid the use of godebug directives - -goversion string - Pattern to validate go min version directive - -h Show this help. - -ignore - Forbid the use of ignore directives - -list value - List of allowed replace directives - -local - Allow local replace directives - -retract-no-explanation - Allow to use retract directives without explanation - -tool - Forbid the use of tool directives - -toolchain - Forbid the use of toolchain directive - -toolchain-pattern string - Pattern to validate toolchain directive -``` - -## Details - -### [`retract`](https://golang.org/ref/mod#go-mod-file-retract) directives - -- Force explanation for `retract` directives. - -```go -module example.com/foo - -go 1.22 - -require ( - github.com/ldez/grignotin v0.4.1 -) - -retract ( - v1.0.0 // Explanation -) -``` - -### [`replace`](https://golang.org/ref/mod#go-mod-file-replace) directives - -- Ban all `replace` directives. -- Allow only local `replace` directives. -- Allow only some `replace` directives. -- Detect duplicated `replace` directives. -- Detect identical `replace` directives. - -```go -module example.com/foo - -go 1.22 - -require ( - github.com/ldez/grignotin v0.4.1 -) - -replace github.com/ldez/grignotin => ../grignotin/ -``` - -### [`exclude`](https://golang.org/ref/mod#go-mod-file-exclude) directives - -- Ban all `exclude` directives. - -```go -module example.com/foo - -go 1.22 - -require ( - github.com/ldez/grignotin v0.4.1 -) - -exclude ( - golang.org/x/crypto v1.4.5 - golang.org/x/text v1.6.7 -) -``` - -### [`ignore`](TODO) directives - -- Ban all `ignore` directives. - -```go -module example.com/foo - -go 1.25 - -require ( - github.com/ldez/grignotin v0.4.1 -) - -ignore ( - ./foo/bar/path - foo/bar -) -``` - -### [`tool`](https://golang.org/ref/mod#go-mod-file-tool) directives - -- Ban all `tool` directives. - -```go -module example.com/foo - -go 1.24 - -tool ( - example.com/module/cmd/a - example.com/module/cmd/b -) -``` - -### [`toolchain`](https://golang.org/ref/mod#go-mod-file-toolchain) directive - -- Ban `toolchain` directive. -- Use a regular expression to constraint the Go minimum version. - -```go -module example.com/foo - -go 1.22 - -toolchain go1.23.3 -``` - -### [`godebug`](https://go.dev/ref/mod#go-mod-file-godebug) directives - -- Ban `godebug` directive. - -```go -module example.com/foo - -go 1.22 - -godebug default=go1.21 -godebug ( - panicnil=1 - asynctimerchan=0 -) -``` - -### [`go`](https://go.dev/ref/mod#go-mod-file-go) directive - -- Use a regular expression to constraint the Go minimum version. - -```go -module example.com/foo - -go 1.22.0 -``` diff --git a/vendor/github.com/ldez/grignotin/LICENSE b/vendor/github.com/ldez/grignotin/LICENSE deleted file mode 100644 index 79f380e5c8..0000000000 --- a/vendor/github.com/ldez/grignotin/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2024 Fernandez Ludovic - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/ldez/grignotin/goenv/goenv.go b/vendor/github.com/ldez/grignotin/goenv/goenv.go deleted file mode 100644 index 58dbb5f8c4..0000000000 --- a/vendor/github.com/ldez/grignotin/goenv/goenv.go +++ /dev/null @@ -1,51 +0,0 @@ -// Package goenv A set of functions to get information from `go env`. -package goenv - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "os/exec" - "strings" -) - -// GetAll gets information from "go env". -func GetAll(ctx context.Context) (map[string]string, error) { - v, err := Get(ctx) - if err != nil { - return nil, err - } - - return v, nil -} - -// GetOne gets information from "go env" for one environment variable. -func GetOne(ctx context.Context, name string) (string, error) { - v, err := Get(ctx, name) - if err != nil { - return "", err - } - - return v[name], nil -} - -// Get gets information from "go env" for one or several environment variables. -func Get(ctx context.Context, name ...string) (map[string]string, error) { - args := append([]string{"env", "-json"}, name...) - cmd := exec.CommandContext(ctx, "go", args...) //nolint:gosec // The env var names must be checked by the user. - - out, err := cmd.Output() - if err != nil { - return nil, fmt.Errorf("command %q: %w: %s", strings.Join(cmd.Args, " "), err, string(out)) - } - - v := map[string]string{} - - err = json.NewDecoder(bytes.NewBuffer(out)).Decode(&v) - if err != nil { - return nil, err - } - - return v, nil -} diff --git a/vendor/github.com/ldez/grignotin/goenv/names.go b/vendor/github.com/ldez/grignotin/goenv/names.go deleted file mode 100644 index a5d6eeeebd..0000000000 --- a/vendor/github.com/ldez/grignotin/goenv/names.go +++ /dev/null @@ -1,276 +0,0 @@ -package goenv - -// General-purpose environment variables. -// Reference: https://github.com/golang/go/blob/0afd7e85e5d7154161770f06a17d09bf1ffa3e94/src/cmd/go/internal/help/helpdoc.go#L490 -const ( - // GCCGO The gccgo command to run for 'go build -compiler=gccgo'. - GCCGO = "GCCGO" - // GO111MODULE Controls whether the go command runs in module-aware mode or GOPATH mode. - // May be "off", "on", or "auto". - // See https://golang.org/ref/mod#mod-commands. - GO111MODULE = "GO111MODULE" - // GOARCH The architecture, or processor, for which to compile code. - // Examples are amd64, 386, arm, ppc64. - GOARCH = "GOARCH" - // GOAUTH Controls authentication for go-import and HTTPS module mirror interactions. - // See 'go help goauth'. - GOAUTH = "GOAUTH" - // GOBIN The directory where 'go install' will install a command. - GOBIN = "GOBIN" - // GOCACHE The directory where the go command will store cached - // information for reuse in future builds. - GOCACHE = "GOCACHE" - // GOCACHEPROG A command (with optional space-separated flags) that implements an - // external go command build cache. - // See 'go doc cmd/go/internal/cacheprog'. - GOCACHEPROG = "GOCACHEPROG" - // GODEBUG Enable various debugging facilities. See https://go.dev/doc/godebug - // for details. - GODEBUG = "GODEBUG" - // GOENV The location of the Go environment configuration file. - // Cannot be set using 'go env -w'. - // Setting GOENV=off in the environment disables the use of the - // default configuration file. - GOENV = "GOENV" - // GOFLAGS A space-separated list of -flag=value settings to apply - // to go commands by default, when the given flag is known by - // the current command. Each entry must be a standalone flag. - // Because the entries are space-separated, flag values must - // not contain spaces. Flags listed on the command line - // are applied after this list and therefore override it. - GOFLAGS = "GOFLAGS" - // GOINSECURE Comma-separated list of glob patterns (in the syntax of Go's path.Match) - // of module path prefixes that should always be fetched in an insecure - // manner. Only applies to dependencies that are being fetched directly. - // GOINSECURE does not disable checksum database validation. GOPRIVATE or - // GONOSUMDB may be used to achieve that. - GOINSECURE = "GOINSECURE" - // GOMODCACHE The directory where the go command will store downloaded modules. - GOMODCACHE = "GOMODCACHE" - // GOOS The operating system for which to compile code. - // Examples are linux, darwin, windows, netbsd. - GOOS = "GOOS" - // GOPATH Controls where various files are stored. See: 'go help gopath'. - GOPATH = "GOPATH" - // GOPROXY URL of Go module proxy. See https://golang.org/ref/mod#environment-variables - // and https://golang.org/ref/mod#module-proxy for details. - GOPROXY = "GOPROXY" - // GOROOT The root of the go tree. - GOROOT = "GOROOT" - // GOSUMDB The name of checksum database to use and optionally its public key and - // URL. See https://golang.org/ref/mod#authenticating. - GOSUMDB = "GOSUMDB" - // GOTMPDIR The directory where the go command will write - // temporary source files, packages, and binaries. - GOTMPDIR = "GOTMPDIR" - // GOTOOLCHAIN Controls which Go toolchain is used. See https://go.dev/doc/toolchain. - GOTOOLCHAIN = "GOTOOLCHAIN" - // GOVCS Lists version control commands that may be used with matching servers. - // See 'go help vcs'. - GOVCS = "GOVCS" - // GOWORK In module aware mode, use the given go.work file as a workspace file. - // By default or when GOWORK is "auto", the go command searches for a - // file named go.work in the current directory and then containing directories - // until one is found. If a valid go.work file is found, the modules - // specified will collectively be used as the main modules. If GOWORK - // is "off", or a go.work file is not found in "auto" mode, workspace - // mode is disabled. - GOWORK = "GOWORK" - - // GOPRIVATE Comma-separated list of glob patterns (in the syntax of Go's path.Match) - // of module path prefixes that should always be fetched directly - // or that should not be compared against the checksum database. - // See https://golang.org/ref/mod#private-modules. - GOPRIVATE = "GOPRIVATE" - // GONOPROXY Comma-separated list of glob patterns (in the syntax of Go's path.Match) - // of module path prefixes that should always be fetched directly - // or that should not be compared against the checksum database. - // See https://golang.org/ref/mod#private-modules. - GONOPROXY = "GONOPROXY" - // GONOSUMDB Comma-separated list of glob patterns (in the syntax of Go's path.Match) - // of module path prefixes that should always be fetched directly - // or that should not be compared against the checksum database. - // See https://golang.org/ref/mod#private-modules. - GONOSUMDB = "GONOSUMDB" -) - -// Environment variables for use with cgo. -// Reference: https://github.com/golang/go/blob/0afd7e85e5d7154161770f06a17d09bf1ffa3e94/src/cmd/go/internal/help/helpdoc.go#L571 -const ( - // AR The command to use to manipulate library archives when - // building with the gccgo compiler. - // The default is 'ar'. - AR = "AR" - // CC The command to use to compile C code. - CC = "CC" - // CGO_CFLAGS Flags that cgo will pass to the compiler when compiling - // C code. - CGO_CFLAGS = "CGO_CFLAGS" - // CGO_CFLAGS_ALLOW A regular expression specifying additional flags to allow - // to appear in #cgo CFLAGS source code directives. - // Does not apply to the CGO_CFLAGS environment variable. - CGO_CFLAGS_ALLOW = "CGO_CFLAGS_ALLOW" - // CGO_CFLAGS_DISALLOW A regular expression specifying flags that must be disallowed - // from appearing in #cgo CFLAGS source code directives. - // Does not apply to the CGO_CFLAGS environment variable. - CGO_CFLAGS_DISALLOW = "CGO_CFLAGS_DISALLOW" - // CGO_ENABLED Whether the cgo command is supported. Either 0 or 1. - CGO_ENABLED = "CGO_ENABLED" - // CXX The command to use to compile C++ code. - CXX = "CXX" - // FC The command to use to compile Fortran code. - FC = "FC" - // PKG_CONFIG Path to pkg-config tool. - PKG_CONFIG = "PKG_CONFIG" - - // CGO_CPPFLAGS Like CGO_CFLAGS, CGO_CFLAGS_ALLOW, and CGO_CFLAGS_DISALLOW, - // but for the C preprocessor. - CGO_CPPFLAGS = "CGO_CPPFLAGS" - // CGO_CPPFLAGS_ALLOW Like CGO_CFLAGS, CGO_CFLAGS_ALLOW, and CGO_CFLAGS_DISALLOW, - // but for the C preprocessor. - CGO_CPPFLAGS_ALLOW = "CGO_CPPFLAGS_ALLOW" - // CGO_CPPFLAGS_DISALLOW Like CGO_CFLAGS, CGO_CFLAGS_ALLOW, and CGO_CFLAGS_DISALLOW, - // but for the C preprocessor. - CGO_CPPFLAGS_DISALLOW = "CGO_CPPFLAGS_DISALLOW" - - // CGO_CXXFLAGS Like CGO_CFLAGS, CGO_CFLAGS_ALLOW, and CGO_CFLAGS_DISALLOW, - // but for the C++ compiler. - CGO_CXXFLAGS = "CGO_CXXFLAGS" - // CGO_CXXFLAGS_ALLOW Like CGO_CFLAGS, CGO_CFLAGS_ALLOW, and CGO_CFLAGS_DISALLOW, - // but for the C++ compiler. - CGO_CXXFLAGS_ALLOW = "CGO_CXXFLAGS_ALLOW" - // CGO_CXXFLAGS_DISALLOW Like CGO_CFLAGS, CGO_CFLAGS_ALLOW, and CGO_CFLAGS_DISALLOW, - // but for the C++ compiler. - CGO_CXXFLAGS_DISALLOW = "CGO_CXXFLAGS_DISALLOW" - - // CGO_FFLAGS Like CGO_CFLAGS, CGO_CFLAGS_ALLOW, and CGO_CFLAGS_DISALLOW, - // but for the Fortran compiler. - CGO_FFLAGS = "CGO_FFLAGS" - // CGO_FFLAGS_ALLOW Like CGO_CFLAGS, CGO_CFLAGS_ALLOW, and CGO_CFLAGS_DISALLOW, - // but for the Fortran compiler. - CGO_FFLAGS_ALLOW = "CGO_FFLAGS_ALLOW" - // CGO_FFLAGS_DISALLOW Like CGO_CFLAGS, CGO_CFLAGS_ALLOW, and CGO_CFLAGS_DISALLOW, - // but for the Fortran compiler. - CGO_FFLAGS_DISALLOW = "CGO_FFLAGS_DISALLOW" - - // CGO_LDFLAGS Like CGO_CFLAGS, CGO_CFLAGS_ALLOW, and CGO_CFLAGS_DISALLOW, - // but for the linker. - CGO_LDFLAGS = "CGO_LDFLAGS" - // CGO_LDFLAGS_ALLOW Like CGO_CFLAGS, CGO_CFLAGS_ALLOW, and CGO_CFLAGS_DISALLOW, - // but for the linker. - CGO_LDFLAGS_ALLOW = "CGO_LDFLAGS_ALLOW" - // CGO_LDFLAGS_DISALLOW Like CGO_CFLAGS, CGO_CFLAGS_ALLOW, and CGO_CFLAGS_DISALLOW, - // but for the linker. - CGO_LDFLAGS_DISALLOW = "CGO_LDFLAGS_DISALLOW" -) - -// Architecture-specific environment variables. -// Reference: https://github.com/golang/go/blob/0afd7e85e5d7154161770f06a17d09bf1ffa3e94/src/cmd/go/internal/help/helpdoc.go#L611 -const ( - // GO386 For GOARCH=386, how to implement floating point instructions. - // Valid values are sse2 (default), softfloat. - GO386 = "GO386" - // GOAMD64 For GOARCH=amd64, the microarchitecture level for which to compile. - // Valid values are v1 (default), v2, v3, v4. - // See https://golang.org/wiki/MinimumRequirements#amd64 - GOAMD64 = "GOAMD64" - // GOARM For GOARCH=arm, the ARM architecture for which to compile. - // Valid values are 5, 6, 7. - // When the Go tools are built on an arm system, - // the default value is set based on what the build system supports. - // When the Go tools are not built on an arm system - // (that is, when building a cross-compiler), - // the default value is 7. - // The value can be followed by an option specifying how to implement floating point instructions. - // Valid options are ,softfloat (default for 5) and ,hardfloat (default for 6 and 7). - GOARM = "GOARM" - // GOARM64 For GOARCH=arm64, the ARM64 architecture for which to compile. - // Valid values are v8.0 (default), v8.{1-9}, v9.{0-5}. - // The value can be followed by an option specifying extensions implemented by target hardware. - // Valid options are ,lse and ,crypto. - // Note that some extensions are enabled by default starting from a certain GOARM64 version; - // for example, lse is enabled by default starting from v8.1. - GOARM64 = "GOARM64" - // GOMIPS For GOARCH=mips{,le}, whether to use floating point instructions. - // Valid values are hardfloat (default), softfloat. - GOMIPS = "GOMIPS" - // GOMIPS64 For GOARCH=mips64{,le}, whether to use floating point instructions. - // Valid values are hardfloat (default), softfloat. - GOMIPS64 = "GOMIPS64" - // GOPPC64 For GOARCH=ppc64{,le}, the target ISA (Instruction Set Architecture). - // Valid values are power8 (default), power9, power10. - GOPPC64 = "GOPPC64" - // GORISCV64 For GOARCH=riscv64, the RISC-V user-mode application profile for which - // to compile. Valid values are rva20u64 (default), rva22u64. - // See https://github.com/riscv/riscv-profiles/blob/main/src/profiles.adoc - GORISCV64 = "GORISCV64" - // GOWASM For GOARCH=wasm, comma-separated list of experimental WebAssembly features to use. - // Valid values are satconv, signext. - GOWASM = "GOWASM" -) - -// Environment variables for use with code coverage. -// Reference: https://github.com/golang/go/blob/0afd7e85e5d7154161770f06a17d09bf1ffa3e94/src/cmd/go/internal/help/helpdoc.go#L654 -const ( - // GOCOVERDIR Directory into which to write code coverage data files - // generated by running a "go build -cover" binary. - // Requires that GOEXPERIMENT=coverageredesign is enabled. - GOCOVERDIR = "GOCOVERDIR" -) - -// Special-purpose environment variables. -// Reference: https://github.com/golang/go/blob/0afd7e85e5d7154161770f06a17d09bf1ffa3e94/src/cmd/go/internal/help/helpdoc.go#L661 -const ( - // GCCGOTOOLDIR If set, where to find gccgo tools, such as cgo. - // The default is based on how gccgo was configured. - GCCGOTOOLDIR = "GCCGOTOOLDIR" - // GOEXPERIMENT Comma-separated list of toolchain experiments to enable or disable. - // The list of available experiments may change arbitrarily over time. - // See GOROOT/src/internal/goexperiment/flags.go for currently valid values. - // Warning: This variable is provided for the development and testing - // of the Go toolchain itself. Use beyond that purpose is unsupported. - GOEXPERIMENT = "GOEXPERIMENT" - // GOFIPS140 The FIPS-140 cryptography mode to use when building binaries. - // The default is GOFIPS140=off, which makes no FIPS-140 changes at all. - // Other values enable FIPS-140 compliance measures and select alternate - // versions of the cryptography source code. - // See https://go.dev/security/fips140 for details. - GOFIPS140 = "GOFIPS140" - // GO_EXTLINK_ENABLED Whether the linker should use external linking mode - // when using -linkmode=auto with code that uses cgo. - // Set to 0 to disable external linking mode, 1 to enable it. - GO_EXTLINK_ENABLED = "GO_EXTLINK_ENABLED" - // GIT_ALLOW_PROTOCOL Defined by Git. A colon-separated list of schemes that are allowed - // to be used with git fetch/clone. If set, any scheme not explicitly - // mentioned will be considered insecure by 'go get'. - // Because the variable is defined by Git, the default value cannot - // be set using 'go env -w'. - GIT_ALLOW_PROTOCOL = "GIT_ALLOW_PROTOCOL" -) - -// Additional information available from 'go env' but not read from the environment. -// Reference: https://github.com/golang/go/blob/0afd7e85e5d7154161770f06a17d09bf1ffa3e94/src/cmd/go/internal/help/helpdoc.go#L689 -const ( - // GOEXE The executable file name suffix (".exe" on Windows, "" on other systems). - GOEXE = "GOEXE" - // GOGCCFLAGS A space-separated list of arguments supplied to the CC command. - GOGCCFLAGS = "GOGCCFLAGS" - // GOHOSTARCH The architecture (GOARCH) of the Go toolchain binaries. - GOHOSTARCH = "GOHOSTARCH" - // GOHOSTOS The operating system (GOOS) of the Go toolchain binaries. - GOHOSTOS = "GOHOSTOS" - // GOMOD The absolute path to the go.mod of the main module. - // If module-aware mode is enabled, but there is no go.mod, GOMOD will be - // os.DevNull ("/dev/null" on Unix-like systems, "NUL" on Windows). - // If module-aware mode is disabled, GOMOD will be the empty string. - GOMOD = "GOMOD" - // GOTELEMETRY The current Go telemetry mode ("off", "local", or "on"). - // See "go help telemetry" for more information. - GOTELEMETRY = "GOTELEMETRY" - // GOTELEMETRYDIR The directory Go telemetry data is written is written to. - GOTELEMETRYDIR = "GOTELEMETRYDIR" - // GOTOOLDIR The directory where the go tools (compile, cover, doc, etc...) are installed. - GOTOOLDIR = "GOTOOLDIR" - // GOVERSION The version of the installed Go tree, as reported by runtime.Version. - GOVERSION = "GOVERSION" -) diff --git a/vendor/github.com/ldez/grignotin/gomod/gomod.go b/vendor/github.com/ldez/grignotin/gomod/gomod.go deleted file mode 100644 index 76e17870df..0000000000 --- a/vendor/github.com/ldez/grignotin/gomod/gomod.go +++ /dev/null @@ -1,85 +0,0 @@ -// Package gomod A set of functions to get information about module (go list). -package gomod - -import ( - "bytes" - "context" - "encoding/json" - "errors" - "fmt" - "os" - "os/exec" - "path/filepath" - "strings" - - "github.com/ldez/grignotin/goenv" - "golang.org/x/mod/modfile" -) - -// ModInfo Module information. -// -//nolint:tagliatelle // temporary: the next version of golangci-lint will allow configuration by package. -type ModInfo struct { - Path string `json:"Path"` - Dir string `json:"Dir"` - GoMod string `json:"GoMod"` - GoVersion string `json:"GoVersion"` - Main bool `json:"Main"` -} - -// GetModuleInfo gets modules information from `go list`. -func GetModuleInfo(ctx context.Context) ([]ModInfo, error) { - // https://github.com/golang/go/issues/44753#issuecomment-790089020 - cmd := exec.CommandContext(ctx, "go", "list", "-m", "-json") - - out, err := cmd.Output() - if err != nil { - return nil, fmt.Errorf("command %q: %w: %s", strings.Join(cmd.Args, " "), err, string(out)) - } - - var infos []ModInfo - - for dec := json.NewDecoder(bytes.NewBuffer(out)); dec.More(); { - var v ModInfo - if err := dec.Decode(&v); err != nil { - return nil, fmt.Errorf("unmarshaling error: %w: %s", err, string(out)) - } - - if v.GoMod == "" { - return nil, errors.New("working directory is not part of a module") - } - - if !v.Main || v.Dir == "" { - continue - } - - infos = append(infos, v) - } - - if len(infos) == 0 { - return nil, errors.New("go.mod file not found") - } - - return infos, nil -} - -// GetModulePath extracts module path from go.mod. -func GetModulePath(ctx context.Context) (string, error) { - p, err := goenv.GetOne(ctx, goenv.GOMOD) - if err != nil { - return "", err - } - - b, err := os.ReadFile(filepath.Clean(p)) - if err != nil { - return "", fmt.Errorf("reading go.mod: %w", err) - } - - return modfile.ModulePath(b), nil -} - -// GetGoModPath extracts go.mod path from "go env". -// Deprecated: use `goenv.GetOne(context.Background(), goenv.GOMOD)` instead. -func GetGoModPath() (string, error) { - return goenv.GetOne(context.Background(), goenv.GOMOD) -} diff --git a/vendor/github.com/ldez/tagliatelle/.gitignore b/vendor/github.com/ldez/tagliatelle/.gitignore deleted file mode 100644 index 74c84ce62e..0000000000 --- a/vendor/github.com/ldez/tagliatelle/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.idea/ -/tagliatelle -notes.md diff --git a/vendor/github.com/ldez/tagliatelle/.golangci.yml b/vendor/github.com/ldez/tagliatelle/.golangci.yml deleted file mode 100644 index 371822b51f..0000000000 --- a/vendor/github.com/ldez/tagliatelle/.golangci.yml +++ /dev/null @@ -1,83 +0,0 @@ -version: "2" - -formatters: - enable: - - gci - - gofumpt - settings: - gofumpt: - extra-rules: true - -linters: - default: all - disable: - - cyclop # duplicate of gocyclo - - dupl - - err113 - - errchkjson - - exhaustive - - exhaustruct - - forcetypeassert - - lll - - mnd - - nilnil - - nlreturn - - nonamedreturns - - paralleltest - - prealloc - - rowserrcheck # not relevant (SQL) - - sqlclosecheck # not relevant (SQL) - - testpackage - - tparallel - - varnamelen - - wrapcheck - - wsl # Deprecated - - settings: - depguard: - rules: - main: - deny: - - pkg: github.com/instana/testify - desc: not allowed - - pkg: github.com/pkg/errors - desc: Should be replaced by standard lib errors package - funlen: - lines: -1 - statements: 40 - goconst: - min-len: 5 - min-occurrences: 3 - gocritic: - disabled-checks: - - sloppyReassign - - rangeValCopy - - octalLiteral - - paramTypeCombine # already handle by gofumpt.extra-rules - enabled-tags: - - diagnostic - - style - - performance - settings: - hugeParam: - sizeThreshold: 100 - gocyclo: - min-complexity: 20 - godox: - keywords: - - FIXME - govet: - disable: - - fieldalignment - enable-all: true - misspell: - locale: US - - exclusions: - warn-unused: true - presets: - - comments - -issues: - max-issues-per-linter: 0 - max-same-issues: 0 diff --git a/vendor/github.com/ldez/tagliatelle/LICENSE b/vendor/github.com/ldez/tagliatelle/LICENSE deleted file mode 100644 index caed523b49..0000000000 --- a/vendor/github.com/ldez/tagliatelle/LICENSE +++ /dev/null @@ -1,190 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2021 Fernandez Ludovic - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/ldez/tagliatelle/Makefile b/vendor/github.com/ldez/tagliatelle/Makefile deleted file mode 100644 index 196f70c022..0000000000 --- a/vendor/github.com/ldez/tagliatelle/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -.PHONY: clean check test build - -default: clean check test build - -clean: - rm -rf dist/ cover.out - -test: clean - go test -v -cover ./... - -check: - golangci-lint run - -build: - go build -ldflags "-s -w" -trimpath ./cmd/tagliatelle/ diff --git a/vendor/github.com/ldez/tagliatelle/converter.go b/vendor/github.com/ldez/tagliatelle/converter.go deleted file mode 100644 index 97bcf369c3..0000000000 --- a/vendor/github.com/ldez/tagliatelle/converter.go +++ /dev/null @@ -1,119 +0,0 @@ -package tagliatelle - -import ( - "fmt" - "maps" - "strings" - - "github.com/ettle/strcase" -) - -// https://github.com/dominikh/go-tools/blob/v0.5.1/config/config.go#L167-L175 -// -//nolint:gochecknoglobals // For now I'll accept this, but I think will refactor to use a structure. -var staticcheckInitialisms = map[string]bool{ - "AMQP": true, - "DB": true, - "GID": true, - "LHS": false, - "RHS": false, - "RTP": true, - "SIP": true, - "TS": true, -} - -// Converter is the signature of a case converter. -type Converter func(s string) string - -// ConverterCallback allows to abstract `getSimpleConverter` and `ruleToConverter`. -type ConverterCallback func() (Converter, error) - -func getSimpleConverter(c string) (Converter, error) { - switch c { - case "camel": - return strcase.ToCamel, nil - case "pascal": - return strcase.ToPascal, nil - case "kebab": - return strcase.ToKebab, nil - case "snake": - return strcase.ToSnake, nil - case "goCamel": - return strcase.ToGoCamel, nil - case "goPascal": - return strcase.ToGoPascal, nil - case "goKebab": - return strcase.ToGoKebab, nil - case "goSnake": - return strcase.ToGoSnake, nil - case "upperSnake": - return strcase.ToSNAKE, nil - case "header": - return toHeader, nil - case "upper": - return strings.ToUpper, nil - case "lower": - return strings.ToLower, nil - default: - return nil, fmt.Errorf("unsupported case: %s", c) - } -} - -func toHeader(s string) string { - return strcase.ToCase(s, strcase.TitleCase, '-') -} - -func ruleToConverter(rule ExtendedRule) (Converter, error) { - initialismOverrides := maps.Clone(rule.InitialismOverrides) - - if rule.ExtraInitialisms { - for k, v := range staticcheckInitialisms { - if _, found := initialismOverrides[k]; found { - continue - } - - initialismOverrides[k] = v - } - } - - caser := strcase.NewCaser(strings.HasPrefix(rule.Case, "go"), initialismOverrides, nil) - - switch strings.ToLower(strings.TrimPrefix(rule.Case, "go")) { - case "camel": - return caser.ToCamel, nil - - case "pascal": - return caser.ToPascal, nil - - case "kebab": - return caser.ToKebab, nil - - case "snake": - return caser.ToSnake, nil - - case "uppersnake": - return caser.ToSNAKE, nil - - case "header": - return toHeaderCase(caser), nil - - case "upper": - return func(s string) string { - return caser.ToCase(s, strcase.UpperCase, 0) - }, nil - - case "lower": - return func(s string) string { - return caser.ToCase(s, strcase.LowerCase, 0) - }, nil - - default: - return nil, fmt.Errorf("unsupported case: %s", rule.Case) - } -} - -func toHeaderCase(caser *strcase.Caser) Converter { - return func(s string) string { - return caser.ToCase(s, strcase.TitleCase, '-') - } -} diff --git a/vendor/github.com/ldez/tagliatelle/readme.md b/vendor/github.com/ldez/tagliatelle/readme.md deleted file mode 100644 index 77dd416ca6..0000000000 --- a/vendor/github.com/ldez/tagliatelle/readme.md +++ /dev/null @@ -1,317 +0,0 @@ -# Tagliatelle - -[![Sponsor](https://img.shields.io/badge/Sponsor%20me-%E2%9D%A4%EF%B8%8F-pink)](https://github.com/sponsors/ldez) -[![Build Status](https://github.com/ldez/tagliatelle/workflows/Main/badge.svg?branch=master)](https://github.com/ldez/tagliatelle/actions) - -A linter that handles struct tags. - -Supported string casing: - -- `camel` -- `pascal` -- `kebab` -- `snake` -- `upperSnake` -- `goCamel` Respects [Go's common initialisms](https://github.com/golang/lint/blob/83fdc39ff7b56453e3793356bcff3070b9b96445/lint.go#L770-L809) (e.g. HttpResponse -> HTTPResponse). -- `goPascal` Respects [Go's common initialisms](https://github.com/golang/lint/blob/83fdc39ff7b56453e3793356bcff3070b9b96445/lint.go#L770-L809) (e.g. HttpResponse -> HTTPResponse). -- `goKebab` Respects [Go's common initialisms](https://github.com/golang/lint/blob/83fdc39ff7b56453e3793356bcff3070b9b96445/lint.go#L770-L809) (e.g. HttpResponse -> HTTPResponse). -- `goSnake` Respects [Go's common initialisms](https://github.com/golang/lint/blob/83fdc39ff7b56453e3793356bcff3070b9b96445/lint.go#L770-L809) (e.g. HttpResponse -> HTTPResponse). -- `header` -- `upper` -- `lower` - -| Source | Camel Case | Go Camel Case | -|----------------|----------------|----------------| -| GooID | gooId | gooID | -| HTTPStatusCode | httpStatusCode | httpStatusCode | -| FooBAR | fooBar | fooBar | -| URL | url | url | -| ID | id | id | -| hostIP | hostIp | hostIP | -| JSON | json | json | -| JSONName | jsonName | jsonName | -| NameJSON | nameJson | nameJSON | -| UneTête | uneTête | uneTête | - -| Source | Pascal Case | Go Pascal Case | -|----------------|----------------|----------------| -| GooID | GooId | GooID | -| HTTPStatusCode | HttpStatusCode | HTTPStatusCode | -| FooBAR | FooBar | FooBar | -| URL | Url | URL | -| ID | Id | ID | -| hostIP | HostIp | HostIP | -| JSON | Json | JSON | -| JSONName | JsonName | JSONName | -| NameJSON | NameJson | NameJSON | -| UneTête | UneTête | UneTête | - -| Source | Snake Case | Upper Snake Case | Go Snake Case | -|----------------|------------------|------------------|------------------| -| GooID | goo_id | GOO_ID | goo_ID | -| HTTPStatusCode | http_status_code | HTTP_STATUS_CODE | HTTP_status_code | -| FooBAR | foo_bar | FOO_BAR | foo_bar | -| URL | url | URL | URL | -| ID | id | ID | ID | -| hostIP | host_ip | HOST_IP | host_IP | -| JSON | json | JSON | JSON | -| JSONName | json_name | JSON_NAME | JSON_name | -| NameJSON | name_json | NAME_JSON | name_JSON | -| UneTête | une_tête | UNE_TÊTE | une_tête | - -| Source | Kebab Case | Go KebabCase | -|----------------|------------------|------------------| -| GooID | goo-id | goo-ID | -| HTTPStatusCode | http-status-code | HTTP-status-code | -| FooBAR | foo-bar | foo-bar | -| URL | url | URL | -| ID | id | ID | -| hostIP | host-ip | host-IP | -| JSON | json | JSON | -| JSONName | json-name | JSON-name | -| NameJSON | name-json | name-JSON | -| UneTête | une-tête | une-tête | - -| Source | Header Case | -|----------------|------------------| -| GooID | Goo-Id | -| HTTPStatusCode | Http-Status-Code | -| FooBAR | Foo-Bar | -| URL | Url | -| ID | Id | -| hostIP | Host-Ip | -| JSON | Json | -| JSONName | Json-Name | -| NameJSON | Name-Json | -| UneTête | Une-Tête | - -## Examples - -```go -// json and camel case -type Foo struct { - ID string `json:"ID"` // must be "id" - UserID string `json:"UserID"`// must be "userId" - Name string `json:"name"` - Value string `json:"val,omitempty"`// must be "value" -} -``` - -## What this linter is about - -This linter is about validating tags according to the rules you define. -The linter also allows you to fix tags according to the rules you defined. - -This linter is not intended to validate the fact a tag is valid or not. - -## How to use the linter - -### As a golangci-lint linter - -Define the rules, you want via your [golangci-lint](https://golangci-lint.run) configuration file: - -```yaml -linters: - enable: - - tagliatelle - - settings: - tagliatelle: - # Checks the struct tag name case. - case: - # Defines the association between tag name and case. - # Any struct tag name can be used. - # Supported string cases: - # - `camel` - # - `pascal` - # - `kebab` - # - `snake` - # - `upperSnake` - # - `goCamel` - # - `goPascal` - # - `goKebab` - # - `goSnake` - # - `upper` - # - `lower` - # - `header` - rules: - json: camel - yaml: camel - xml: camel - toml: camel - bson: camel - avro: snake - mapstructure: kebab - env: upperSnake - envconfig: upperSnake - whatever: snake - # Defines the association between tag name and case. - # Important: the `extended-rules` overrides `rules`. - # Default: empty - extended-rules: - json: - # Supported string cases: - # - `camel` - # - `pascal` - # - `kebab` - # - `snake` - # - `upperSnake` - # - `goCamel` - # - `goPascal` - # - `goKebab` - # - `goSnake` - # - `header` - # - `lower` - # - `header` - # - # Required - case: camel - # Adds 'AMQP', 'DB', 'GID', 'RTP', 'SIP', 'TS' to initialisms, - # and removes 'LHS', 'RHS' from initialisms. - # Default: false - extra-initialisms: true - # Defines initialism additions and overrides. - # Default: empty - initialism-overrides: - DB: true # add a new initialism - LHS: false # disable a default initialism. - # ... - # Uses the struct field name to check the name of the struct tag. - # Default: false - use-field-name: true - # The field names to ignore. - # Default: [] - ignored-fields: - - Bar - - Foo - # Overrides the default/root configuration. - # Default: [] - overrides: - - - # The package path (uses `/` only as a separator). - # Required - pkg: foo/bar - # Default: empty or the same as the default/root configuration. - rules: - json: snake - xml: pascal - # Default: empty or the same as the default/root configuration. - extended-rules: - # same options as the base `extended-rules`. - # Default: false (WARNING: it doesn't follow the default/root configuration) - use-field-name: true - # The field names to ignore. - # Default: [] or the same as the default/root configuration. - ignored-fields: - - Bar - - Foo - # Ignore the package (takes precedence over all other configurations). - # Default: false - ignore: true -``` - -#### Examples - -Overrides case rules for the package `foo/bar`: - -```yaml -linters: - settings: - tagliatelle: - case: - rules: - json: camel - yaml: camel - xml: camel - overrides: - - pkg: foo/bar - rules: - json: snake - xml: pascal -``` - -Ignore fields inside the package `foo/bar`: - -```yaml -linters: - settings: - tagliatelle: - case: - rules: - json: camel - yaml: camel - xml: camel - overrides: - - pkg: foo/bar - ignored-fields: - - Bar - - Foo -``` - -Ignore the package `foo/bar`: - -```yaml -linters: - settings: - tagliatelle: - case: - rules: - json: camel - yaml: camel - xml: camel - overrides: - - pkg: foo/bar - ignore: true -``` - -More information here https://golangci-lint.run/usage/linters/#tagliatelle - -### Install and run it from the binary - -Not recommended. - -```shell -go install github.com/ldez/tagliatelle/cmd/tagliatelle@latest -``` - -then launch it manually. - -## Rules - -Here are the default rules for the well-known and used tags, when using tagliatelle as a binary or [golangci-lint linter](https://golangci-lint.run/usage/linters/#tagliatelle): - -- `json`: `camel` -- `yaml`: `camel` -- `xml`: `camel` -- `bson`: `camel` -- `avro`: `snake` -- `header`: `header` -- `env`: `upperSnake` -- `envconfig`: `upperSnake` - -### Custom Rules - -The linter is not limited to the tags used in example, **you can use it to validate any tag**. - -You can add your own tag, for example `whatever` and tells the linter you want to use `kebab`. - -This option is only available via [golangci-lint](https://golangci-lint.run). - -```yaml -linters: - settings: - tagliatelle: - # Check the struck tag name case. - case: - rules: - # Any struct tag type can be used. - # Support string case: `camel`, `pascal`, `kebab`, `snake`, `goCamel`, `goPascal`, `goKebab`, `goSnake`, `upper`, `lower` - json: camel - yaml: camel - xml: camel - toml: camel - whatever: kebab - # Use the struct field name to check the name of the struct tag. - # Default: false - use-field-name: true -``` diff --git a/vendor/github.com/ldez/tagliatelle/tagliatelle.go b/vendor/github.com/ldez/tagliatelle/tagliatelle.go deleted file mode 100644 index ccd1b63e60..0000000000 --- a/vendor/github.com/ldez/tagliatelle/tagliatelle.go +++ /dev/null @@ -1,296 +0,0 @@ -// Package tagliatelle a linter that handle struct tags. -package tagliatelle - -import ( - "encoding/json" - "errors" - "fmt" - "go/ast" - "maps" - "path" - "path/filepath" - "reflect" - "slices" - "strings" - - iradix "github.com/hashicorp/go-immutable-radix/v2" - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/inspector" -) - -// Config the tagliatelle configuration. -type Config struct { - Base - - Overrides []Overrides -} - -// Overrides applies configuration overrides by package. -type Overrides struct { - Base - - Package string -} - -// Base shared configuration between rules. -type Base struct { - Rules map[string]string - ExtendedRules map[string]ExtendedRule - UseFieldName bool - IgnoredFields []string - Ignore bool -} - -// ExtendedRule allows to customize rules. -type ExtendedRule struct { - Case string - ExtraInitialisms bool - InitialismOverrides map[string]bool -} - -// New creates an analyzer. -func New(config Config) *analysis.Analyzer { - return &analysis.Analyzer{ - Name: "tagliatelle", - Doc: "Checks the struct tags.", - Run: func(pass *analysis.Pass) (any, error) { - if len(config.Rules) == 0 && len(config.ExtendedRules) == 0 && len(config.Overrides) == 0 { - return nil, nil - } - - return run(pass, config) - }, - Requires: []*analysis.Analyzer{inspect.Analyzer}, - } -} - -func run(pass *analysis.Pass, config Config) (any, error) { - isp, ok := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - if !ok { - return nil, errors.New("missing inspect analyser") - } - - nodeFilter := []ast.Node{ - (*ast.StructType)(nil), - } - - cfg := config.Base - - if pass.Module != nil { - radixTree := createRadixTree(config, pass.Module.Path) - _, cfg, _ = radixTree.Root().LongestPrefix([]byte(pass.Pkg.Path())) - } - - if cfg.Ignore { - return nil, nil - } - - isp.Preorder(nodeFilter, func(n ast.Node) { - node, ok := n.(*ast.StructType) - if !ok { - return - } - - for _, field := range node.Fields.List { - analyze(pass, cfg, node, field) - } - }) - - return nil, nil -} - -func analyze(pass *analysis.Pass, config Base, n *ast.StructType, field *ast.Field) { - if n.Fields == nil || n.Fields.NumFields() < 1 { - // skip empty structs - return - } - - if field.Tag == nil { - // skip when no struct tag - return - } - - fieldName, err := getFieldName(field) - if err != nil { - pass.Reportf(n.Pos(), "unable to get field name: %v", err) - return - } - - cleanRules(config) - - if slices.Contains(config.IgnoredFields, fieldName) { - return - } - - for key, extRule := range config.ExtendedRules { - report(pass, config, key, extRule.Case, fieldName, n, field, func() (Converter, error) { - return ruleToConverter(extRule) - }) - } - - for key, convName := range config.Rules { - report(pass, config, key, convName, fieldName, n, field, func() (Converter, error) { - return getSimpleConverter(convName) - }) - } -} - -func report(pass *analysis.Pass, config Base, key, convName, fieldName string, n *ast.StructType, field *ast.Field, fn ConverterCallback) { - if convName == "" { - return - } - - value, flags, ok := lookupTagValue(field.Tag, key) - if !ok { - // skip when no struct tag for the key - return - } - - if value == "-" { - // skip when skipped :) - return - } - - // TODO(ldez): need to be rethink. - // tagliatelle should try to remain neutral in terms of format. - if key == "xml" && strings.ContainsAny(value, ">:") { - // ignore XML names than contains path - return - } - - // TODO(ldez): need to be rethink. - // This is an exception because of a bug. - // https://github.com/ldez/tagliatelle/issues/8 - // For now, tagliatelle should try to remain neutral in terms of format. - if slices.Contains(flags, "inline") { - // skip for inline children (no name to lint) - return - } - - if value == "" { - value = fieldName - } - - converter, err := fn() - if err != nil { - pass.Reportf(n.Pos(), "%s(%s): %v", key, convName, err) - return - } - - expected := value - if config.UseFieldName { - expected = fieldName - } - - if value != converter(expected) { - pass.Reportf(field.Tag.Pos(), "%s(%s): got '%s' want '%s'", key, convName, value, converter(expected)) - } -} - -func getFieldName(field *ast.Field) (string, error) { - var name string - - for _, n := range field.Names { - if n.Name != "" { - name = n.Name - } - } - - if name != "" { - return name, nil - } - - return getTypeName(field.Type) -} - -func getTypeName(exp ast.Expr) (string, error) { - switch typ := exp.(type) { - case *ast.Ident: - return typ.Name, nil - case *ast.StarExpr: - return getTypeName(typ.X) - case *ast.SelectorExpr: - return getTypeName(typ.Sel) - default: - bytes, _ := json.Marshal(exp) - return "", fmt.Errorf("unexpected error: type %T: %s", typ, string(bytes)) - } -} - -func lookupTagValue(tag *ast.BasicLit, key string) (name string, flags []string, ok bool) { - raw := strings.Trim(tag.Value, "`") - - value, ok := reflect.StructTag(raw).Lookup(key) - if !ok { - return value, nil, ok - } - - values := strings.Split(value, ",") - - if len(values) < 1 { - return "", nil, true - } - - return values[0], values[1:], true -} - -func createRadixTree(config Config, modPath string) *iradix.Tree[Base] { - r := iradix.New[Base]() - - defaultRule := Base{ - Rules: maps.Clone(config.Rules), - ExtendedRules: maps.Clone(config.ExtendedRules), - UseFieldName: config.UseFieldName, - Ignore: config.Ignore, - } - - defaultRule.IgnoredFields = append(defaultRule.IgnoredFields, config.IgnoredFields...) - - r, _, _ = r.Insert([]byte(""), defaultRule) - - for _, override := range config.Overrides { - c := Base{ - UseFieldName: override.UseFieldName, - Ignore: override.Ignore, - } - - // If there is an override, the base configuration is ignored. - if len(override.IgnoredFields) == 0 { - c.IgnoredFields = append(c.IgnoredFields, config.IgnoredFields...) - } else { - c.IgnoredFields = append(c.IgnoredFields, override.IgnoredFields...) - } - - // Copy the rules from the base. - c.Rules = maps.Clone(config.Rules) - - // Overrides the rule from the base. - for k, v := range override.Rules { - c.Rules[k] = v - } - - // Copy the extended rules from the base. - c.ExtendedRules = maps.Clone(config.ExtendedRules) - - // Overrides the extended rule from the base. - for k, v := range override.ExtendedRules { - c.ExtendedRules[k] = v - } - - key := path.Join(modPath, override.Package) - if filepath.Base(modPath) == override.Package { - key = modPath - } - - r, _, _ = r.Insert([]byte(key), c) - } - - return r -} - -func cleanRules(config Base) { - for k := range config.ExtendedRules { - delete(config.Rules, k) - } -} diff --git a/vendor/github.com/ldez/usetesting/.gitignore b/vendor/github.com/ldez/usetesting/.gitignore deleted file mode 100644 index 0907a9069e..0000000000 --- a/vendor/github.com/ldez/usetesting/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/usetesting -.idea diff --git a/vendor/github.com/ldez/usetesting/.golangci.yml b/vendor/github.com/ldez/usetesting/.golangci.yml deleted file mode 100644 index 1c66174ea1..0000000000 --- a/vendor/github.com/ldez/usetesting/.golangci.yml +++ /dev/null @@ -1,78 +0,0 @@ -version: "2" - -formatters: - enable: - - gci - - gofumpt - settings: - gofumpt: - extra-rules: true - -linters: - default: all - disable: - - cyclop # duplicate of gocyclo - - dupl - - errchkjson - - exhaustive - - exhaustruct - - lll - - nilnil - - nlreturn - - nonamedreturns - - paralleltest - - prealloc - - rowserrcheck # not relevant (SQL) - - sqlclosecheck # not relevant (SQL) - - testpackage - - tparallel - - varnamelen - settings: - depguard: - rules: - main: - deny: - - pkg: github.com/instana/testify - desc: not allowed - - pkg: github.com/pkg/errors - desc: Should be replaced by standard lib errors package - funlen: - lines: -1 - statements: 40 - goconst: - min-len: 5 - min-occurrences: 3 - gocritic: - disabled-checks: - - sloppyReassign - - rangeValCopy - - octalLiteral - - paramTypeCombine # already handle by gofumpt.extra-rules - enabled-tags: - - diagnostic - - style - - performance - settings: - hugeParam: - sizeThreshold: 100 - gocyclo: - min-complexity: 20 - godox: - keywords: - - FIXME - govet: - disable: - - fieldalignment - enable-all: true - misspell: - locale: US - mnd: - ignored-numbers: - - "124" - wsl: - force-case-trailing-whitespace: 1 - allow-trailing-comment: true - -issues: - max-issues-per-linter: 0 - max-same-issues: 0 diff --git a/vendor/github.com/ldez/usetesting/LICENSE b/vendor/github.com/ldez/usetesting/LICENSE deleted file mode 100644 index c1bf0c3288..0000000000 --- a/vendor/github.com/ldez/usetesting/LICENSE +++ /dev/null @@ -1,190 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2024 Fernandez Ludovic - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/ldez/usetesting/Makefile b/vendor/github.com/ldez/usetesting/Makefile deleted file mode 100644 index b8eca65980..0000000000 --- a/vendor/github.com/ldez/usetesting/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -.PHONY: clean check test build - -default: clean check test build - -clean: - rm -rf dist/ cover.out - -test: clean - go test -v -cover ./... - -check: - golangci-lint run - -build: - go build -ldflags "-s -w" -trimpath ./cmd/usetesting/ diff --git a/vendor/github.com/ldez/usetesting/readme.md b/vendor/github.com/ldez/usetesting/readme.md deleted file mode 100644 index c4dd3daa1c..0000000000 --- a/vendor/github.com/ldez/usetesting/readme.md +++ /dev/null @@ -1,213 +0,0 @@ -# UseTesting - -Detects when some calls can be replaced by methods from the testing package. - -[![Sponsor](https://img.shields.io/badge/Sponsor%20me-%E2%9D%A4%EF%B8%8F-pink)](https://github.com/sponsors/ldez) - -## Usages - -### Inside golangci-lint - -Recommended. - -```yml -linters: - enable: - - usetesting - - settings: - usetesting: - # Enable/disable `os.CreateTemp("", ...)` detections. - # Default: true - os-create-temp: false - - # Enable/disable `os.MkdirTemp()` detections. - # Default: true - os-mkdir-temp: false - - # Enable/disable `os.Setenv()` detections. - # Default: true - os-setenv: false - - # Enable/disable `os.TempDir()` detections. - # Default: false - os-temp-dir: true - - # Enable/disable `os.Chdir()` detections. - # Disabled if Go < 1.24. - # Default: true - os-chdir: false - - # Enable/disable `context.Background()` detections. - # Disabled if Go < 1.24. - # Default: false - context-background: true - - # Enable/disable `context.TODO()` detections. - # Disabled if Go < 1.24. - # Default: false - context-todo: true -``` - -### As a CLI - -```shell -go install github.com/ldez/usetesting/cmd/usetesting@latest -``` - -``` -usetesting: Reports uses of functions with replacement inside the testing package. - -Usage: usetesting [-flag] [package] - -Flags: - -contextbackground - Enable/disable context.Background() detections (default true) - -contexttodo - Enable/disable context.TODO() detections (default true) - -oschdir - Enable/disable os.Chdir() detections (default true) - -osmkdirtemp - Enable/disable os.MkdirTemp() detections (default true) - -ossetenv - Enable/disable os.Setenv() detections (default false) - -ostempdir - Enable/disable os.TempDir() detections (default false) - -oscreatetemp - Enable/disable os.CreateTemp("", ...) detections (default true) -... -``` - -## Examples - -### `os.MkdirTemp` - -```go -func TestExample(t *testing.T) { - os.MkdirTemp("a", "b") - // ... -} -``` - -It can be replaced by: - -```go -func TestExample(t *testing.T) { - t.TempDir() - // ... -} -``` - -### `os.TempDir` - -```go -func TestExample(t *testing.T) { - os.TempDir() - // ... -} -``` - -It can be replaced by: - -```go -func TestExample(t *testing.T) { - t.TempDir() - // ... -} -``` - -### `os.CreateTemp` - -```go -func TestExample(t *testing.T) { - os.CreateTemp("", "x") - // ... -} -``` - -It can be replaced by: - -```go -func TestExample(t *testing.T) { - os.CreateTemp(t.TempDir(), "x") - // ... -} -``` - -### `os.Setenv` - -```go -func TestExample(t *testing.T) { - os.Setenv("A", "b") - // ... -} -``` - -It can be replaced by: - -```go -func TestExample(t *testing.T) { - t.Setenv("A", "b") - // ... -} -``` - -### `os.Chdir` (Go >= 1.24) - -```go -func TestExample(t *testing.T) { - os.Chdir("x") - // ... -} -``` - -It can be replaced by: - -```go -func TestExample(t *testing.T) { - t.Chdir("x") - // ... -} -``` - -### `context.Background` (Go >= 1.24) - -```go -func TestExample(t *testing.T) { - ctx := context.Background() - // ... -} -``` - -It can be replaced by: - -```go -func TestExample(t *testing.T) { - ctx := t.Context() - // ... -} -``` - -### `context.TODO` (Go >= 1.24) - -```go -func TestExample(t *testing.T) { - ctx := context.TODO() - // ... -} -``` - -It can be replaced by: - -```go -func TestExample(t *testing.T) { - ctx := t.Context() - // ... -} -``` - -## References - -- https://tip.golang.org/doc/go1.15#testingpkgtesting (`TempDir`) -- https://tip.golang.org/doc/go1.17#testingpkgtesting (`SetEnv`) -- https://tip.golang.org/doc/go1.24#testingpkgtesting (`Chdir`, `Context`) diff --git a/vendor/github.com/ldez/usetesting/report.go b/vendor/github.com/ldez/usetesting/report.go deleted file mode 100644 index 333931c36a..0000000000 --- a/vendor/github.com/ldez/usetesting/report.go +++ /dev/null @@ -1,200 +0,0 @@ -package usetesting - -import ( - "bytes" - "fmt" - "go/ast" - "go/printer" - "go/token" - "slices" - "strings" - - "golang.org/x/tools/go/analysis" -) - -// because [os.CreateTemp] takes 2 args. -const nbArgCreateTemp = 2 - -func (a *analyzer) reportCallExpr(pass *analysis.Pass, ce *ast.CallExpr, fnInfo *FuncInfo) bool { - if !a.osCreateTemp { - return false - } - - if len(ce.Args) != nbArgCreateTemp { - return false - } - - switch fun := ce.Fun.(type) { - case *ast.SelectorExpr: - if fun.Sel == nil || fun.Sel.Name != createTempName { - return false - } - - expr, ok := fun.X.(*ast.Ident) - if !ok { - return false - } - - if expr.Name == osPkgName && isFirstArgEmptyString(ce) { - pass.Report(diagnosticOSCreateTemp(ce, fnInfo)) - - return true - } - - case *ast.Ident: - if fun.Name != createTempName { - return false - } - - pkgName := getPkgNameFromType(pass, fun) - - if pkgName == osPkgName && isFirstArgEmptyString(ce) { - pass.Report(diagnosticOSCreateTemp(ce, fnInfo)) - - return true - } - } - - return false -} - -func diagnosticOSCreateTemp(ce *ast.CallExpr, fnInfo *FuncInfo) analysis.Diagnostic { - diagnostic := analysis.Diagnostic{ - Pos: ce.Pos(), - Message: fmt.Sprintf( - `%s.%s("", ...) could be replaced by %[1]s.%[2]s(%s.%s(), ...) in %s`, - osPkgName, createTempName, fnInfo.ArgName, tempDirName, fnInfo.Name, - ), - } - - // Skip `` arg names. - if !strings.Contains(fnInfo.ArgName, "<") { - g := &ast.CallExpr{ - Fun: ce.Fun, - Args: []ast.Expr{ - &ast.CallExpr{ - Fun: &ast.SelectorExpr{ - X: &ast.Ident{Name: fnInfo.ArgName}, - Sel: &ast.Ident{Name: tempDirName}, - }, - }, - ce.Args[1], - }, - } - - buf := bytes.NewBuffer(nil) - - err := printer.Fprint(buf, token.NewFileSet(), g) - if err != nil { - diagnostic.Message = fmt.Sprintf("Suggested fix error: %v", err) - return diagnostic - } - - diagnostic.SuggestedFixes = append(diagnostic.SuggestedFixes, analysis.SuggestedFix{ - TextEdits: []analysis.TextEdit{{ - Pos: ce.Pos(), - End: ce.End(), - NewText: buf.Bytes(), - }}, - }) - } - - return diagnostic -} - -func (a *analyzer) reportSelector(pass *analysis.Pass, se *ast.SelectorExpr, fnInfo *FuncInfo, geGo124 bool) bool { - if se.Sel == nil || !se.Sel.IsExported() { - return false - } - - ident, ok := se.X.(*ast.Ident) - if !ok { - return false - } - - return a.report(pass, se, ident.Name, se.Sel.Name, fnInfo, geGo124) -} - -func (a *analyzer) reportIdent(pass *analysis.Pass, ident *ast.Ident, fnInfo *FuncInfo, geGo124 bool) bool { - if !ident.IsExported() { - return false - } - - if !slices.Contains(a.fieldNames, ident.Name) { - return false - } - - pkgName := getPkgNameFromType(pass, ident) - - return a.report(pass, ident, pkgName, ident.Name, fnInfo, geGo124) -} - -//nolint:gocyclo // The complexity is expected by the number of cases to check. -func (a *analyzer) report(pass *analysis.Pass, rg analysis.Range, origPkgName, origName string, fnInfo *FuncInfo, geGo124 bool) bool { - switch { - case a.osMkdirTemp && origPkgName == osPkgName && origName == mkdirTempName: - report(pass, rg, origPkgName, origName, tempDirName, fnInfo) - - case a.osTempDir && origPkgName == osPkgName && origName == tempDirName: - report(pass, rg, origPkgName, origName, tempDirName, fnInfo) - - case a.osSetenv && origPkgName == osPkgName && origName == setenvName: - report(pass, rg, origPkgName, origName, setenvName, fnInfo) - - case geGo124 && a.osChdir && origPkgName == osPkgName && origName == chdirName: - report(pass, rg, origPkgName, origName, chdirName, fnInfo) - - case geGo124 && a.contextBackground && origPkgName == contextPkgName && origName == backgroundName: - report(pass, rg, origPkgName, origName, contextName, fnInfo) - - case geGo124 && a.contextTodo && origPkgName == contextPkgName && origName == todoName: - report(pass, rg, origPkgName, origName, contextName, fnInfo) - - default: - return false - } - - return true -} - -func report(pass *analysis.Pass, rg analysis.Range, origPkgName, origName, expectName string, fnInfo *FuncInfo) { - diagnostic := analysis.Diagnostic{ - Pos: rg.Pos(), - Message: fmt.Sprintf("%s.%s() could be replaced by %s.%s() in %s", - origPkgName, origName, fnInfo.ArgName, expectName, fnInfo.Name, - ), - } - - // Skip `` arg names. - // Only applies on `context.XXX` because the nb of return parameters is the same as the replacement. - if !strings.Contains(fnInfo.ArgName, "<") && origPkgName == contextPkgName { - diagnostic.SuggestedFixes = append(diagnostic.SuggestedFixes, analysis.SuggestedFix{ - TextEdits: []analysis.TextEdit{{ - Pos: rg.Pos(), - End: rg.End(), - NewText: []byte(fmt.Sprintf("%s.%s", fnInfo.ArgName, expectName)), - }}, - }) - } - - pass.Report(diagnostic) -} - -func isFirstArgEmptyString(ce *ast.CallExpr) bool { - bl, ok := ce.Args[0].(*ast.BasicLit) - if !ok { - return false - } - - return bl.Kind == token.STRING && bl.Value == `""` -} - -func getPkgNameFromType(pass *analysis.Pass, ident *ast.Ident) string { - o := pass.TypesInfo.ObjectOf(ident) - - if o == nil || o.Pkg() == nil { - return "" - } - - return o.Pkg().Name() -} diff --git a/vendor/github.com/ldez/usetesting/usetesting.go b/vendor/github.com/ldez/usetesting/usetesting.go deleted file mode 100644 index ecd113b95b..0000000000 --- a/vendor/github.com/ldez/usetesting/usetesting.go +++ /dev/null @@ -1,267 +0,0 @@ -// Package usetesting It is an analyzer that detects when some calls can be replaced by methods from the testing package. -package usetesting - -import ( - "go/ast" - "go/build" - "os" - "slices" - "strconv" - "strings" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/inspector" -) - -const ( - chdirName = "Chdir" - mkdirTempName = "MkdirTemp" - createTempName = "CreateTemp" - setenvName = "Setenv" - tempDirName = "TempDir" - backgroundName = "Background" - todoName = "TODO" - contextName = "Context" -) - -const ( - osPkgName = "os" - contextPkgName = "context" - testingPkgName = "testing" -) - -// FuncInfo information about the test function. -type FuncInfo struct { - Name string - ArgName string -} - -// analyzer is the UseTesting linter. -type analyzer struct { - contextBackground bool - contextTodo bool - osChdir bool - osMkdirTemp bool - osTempDir bool - osSetenv bool - osCreateTemp bool - - fieldNames []string - - skipGoVersionDetection bool -} - -// NewAnalyzer create a new UseTesting. -func NewAnalyzer() *analysis.Analyzer { - _, skip := os.LookupEnv("USETESTING_SKIP_GO_VERSION_CHECK") // TODO should be removed when go1.25 will be released. - - l := &analyzer{ - fieldNames: []string{ - chdirName, - mkdirTempName, - tempDirName, - setenvName, - backgroundName, - todoName, - createTempName, - }, - skipGoVersionDetection: skip, - } - - a := &analysis.Analyzer{ - Name: "usetesting", - Doc: "Reports uses of functions with replacement inside the testing package.", - Requires: []*analysis.Analyzer{inspect.Analyzer}, - Run: l.run, - } - - a.Flags.BoolVar(&l.contextBackground, "contextbackground", false, "Enable/disable context.Background() detections") - a.Flags.BoolVar(&l.contextTodo, "contexttodo", false, "Enable/disable context.TODO() detections") - a.Flags.BoolVar(&l.osChdir, "oschdir", true, "Enable/disable os.Chdir() detections") - a.Flags.BoolVar(&l.osMkdirTemp, "osmkdirtemp", true, "Enable/disable os.MkdirTemp() detections") - a.Flags.BoolVar(&l.osSetenv, "ossetenv", false, "Enable/disable os.Setenv() detections") - a.Flags.BoolVar(&l.osTempDir, "ostempdir", false, "Enable/disable os.TempDir() detections") - a.Flags.BoolVar(&l.osCreateTemp, "oscreatetemp", true, `Enable/disable os.CreateTemp("", ...) detections`) - - return a -} - -func (a *analyzer) run(pass *analysis.Pass) (any, error) { - if !a.contextBackground && !a.contextTodo && !a.osChdir && !a.osMkdirTemp && !a.osSetenv && !a.osTempDir && !a.osCreateTemp { - return nil, nil - } - - geGo124 := a.isGoSupported(pass) - - insp, ok := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - if !ok { - return nil, nil - } - - nodeFilter := []ast.Node{ - (*ast.FuncDecl)(nil), - (*ast.FuncLit)(nil), - } - - insp.WithStack(nodeFilter, func(node ast.Node, push bool, stack []ast.Node) (proceed bool) { - if !push { - return false - } - - switch fn := node.(type) { - case *ast.FuncDecl: - a.checkFunc(pass, fn.Type, fn.Body, fn.Name.Name, geGo124) - - case *ast.FuncLit: - if hasParentFunc(stack) { - return true - } - - a.checkFunc(pass, fn.Type, fn.Body, "anonymous function", geGo124) - } - - return true - }) - - return nil, nil -} - -func (a *analyzer) checkFunc(pass *analysis.Pass, ft *ast.FuncType, block *ast.BlockStmt, fnName string, geGo124 bool) { - if len(ft.Params.List) < 1 { - return - } - - fnInfo := checkTestFunctionSignature(ft.Params.List[0], fnName) - if fnInfo == nil { - return - } - - ast.Inspect(block, func(n ast.Node) bool { - switch v := n.(type) { - case *ast.SelectorExpr: - return !a.reportSelector(pass, v, fnInfo, geGo124) - - case *ast.Ident: - return !a.reportIdent(pass, v, fnInfo, geGo124) - - case *ast.CallExpr: - return !a.reportCallExpr(pass, v, fnInfo) - } - - return true - }) -} - -func (a *analyzer) isGoSupported(pass *analysis.Pass) bool { - if a.skipGoVersionDetection { - return true - } - - // Prior to go1.22, versions.FileVersion returns only the toolchain version, - // which is of no use to us, - // so disable this analyzer on earlier versions. - if !slices.Contains(build.Default.ReleaseTags, "go1.22") { - return false - } - - pkgVersion := pass.Pkg.GoVersion() - if pkgVersion == "" { - // Empty means Go devel. - return true - } - - raw := strings.TrimPrefix(pkgVersion, "go") - - // prerelease version (go1.24rc1) - idx := strings.IndexFunc(raw, func(r rune) bool { - return (r < '0' || r > '9') && r != '.' - }) - - if idx != -1 { - raw = raw[:idx] - } - - vParts := strings.Split(raw, ".") - - v, err := strconv.Atoi(strings.Join(vParts[:2], "")) - if err != nil { - v = 116 - } - - return v >= 124 -} - -func hasParentFunc(stack []ast.Node) bool { - // -2 because the last parent is the node. - const skipSelf = 2 - - // skip 0 because it's always [*ast.File]. - for i := len(stack) - skipSelf; i > 0; i-- { - s := stack[i] - - switch fn := s.(type) { - case *ast.FuncDecl: - if len(fn.Type.Params.List) < 1 { - continue - } - - if checkTestFunctionSignature(fn.Type.Params.List[0], fn.Name.Name) != nil { - return true - } - - case *ast.FuncLit: - if len(fn.Type.Params.List) < 1 { - continue - } - - if checkTestFunctionSignature(fn.Type.Params.List[0], "anonymous function") != nil { - return true - } - } - } - - return false -} - -func checkTestFunctionSignature(arg *ast.Field, fnName string) *FuncInfo { - switch at := arg.Type.(type) { - case *ast.StarExpr: - if se, ok := at.X.(*ast.SelectorExpr); ok { - return createFuncInfo(arg, "", se, testingPkgName, fnName, "T", "B") - } - - case *ast.SelectorExpr: - return createFuncInfo(arg, "tb", at, testingPkgName, fnName, "TB") - } - - return nil -} - -func createFuncInfo(arg *ast.Field, defaultName string, se *ast.SelectorExpr, pkgName, fnName string, selectorNames ...string) *FuncInfo { - ok := checkSelectorName(se, pkgName, selectorNames...) - if !ok { - return nil - } - - return &FuncInfo{ - Name: fnName, - ArgName: getTestArgName(arg, defaultName), - } -} - -func checkSelectorName(se *ast.SelectorExpr, pkgName string, selectorNames ...string) bool { - if ident, ok := se.X.(*ast.Ident); ok { - return pkgName == ident.Name && slices.Contains(selectorNames, se.Sel.Name) - } - - return false -} - -func getTestArgName(arg *ast.Field, defaultName string) string { - if len(arg.Names) > 0 && arg.Names[0].Name != "_" { - return arg.Names[0].Name - } - - return defaultName -} diff --git a/vendor/github.com/leonklingele/grouper/LICENSE b/vendor/github.com/leonklingele/grouper/LICENSE deleted file mode 100644 index f288702d2f..0000000000 --- a/vendor/github.com/leonklingele/grouper/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/vendor/github.com/leonklingele/grouper/pkg/analyzer/analyzer.go b/vendor/github.com/leonklingele/grouper/pkg/analyzer/analyzer.go deleted file mode 100644 index 7d8c0c4f0d..0000000000 --- a/vendor/github.com/leonklingele/grouper/pkg/analyzer/analyzer.go +++ /dev/null @@ -1,91 +0,0 @@ -package analyzer - -import ( - "fmt" - "go/ast" - - "github.com/leonklingele/grouper/pkg/analyzer/consts" - "github.com/leonklingele/grouper/pkg/analyzer/imports" - "github.com/leonklingele/grouper/pkg/analyzer/types" - "github.com/leonklingele/grouper/pkg/analyzer/vars" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" -) - -const ( - Name = "grouper" - Doc = `analyze expression groups - -Require 'import', 'const', 'var' and/or 'type' declaration groups.` -) - -func New() *analysis.Analyzer { - return &analysis.Analyzer{ //nolint:exhaustivestruct // we do not need all fields - Name: Name, - Doc: Doc, - Flags: Flags(), - Run: run, - Requires: []*analysis.Analyzer{inspect.Analyzer}, - } -} - -func run(p *analysis.Pass) (interface{}, error) { - flagLookupBool := func(name string) bool { - return p.Analyzer.Flags.Lookup(name).Value.String() == "true" - } - - c := &Config{ - ConstsConfig: &consts.Config{ - RequireSingleConst: flagLookupBool(FlagNameConstRequireSingleConst), - RequireGrouping: flagLookupBool(FlagNameConstRequireGrouping), - }, - - ImportsConfig: &imports.Config{ - RequireSingleImport: flagLookupBool(FlagNameImportRequireSingleImport), - RequireGrouping: flagLookupBool(FlagNameImportRequireGrouping), - }, - - TypesConfig: &types.Config{ - RequireSingleType: flagLookupBool(FlagNameTypeRequireSingleType), - RequireGrouping: flagLookupBool(FlagNameTypeRequireGrouping), - }, - - VarsConfig: &vars.Config{ - RequireSingleVar: flagLookupBool(FlagNameVarRequireSingleVar), - RequireGrouping: flagLookupBool(FlagNameVarRequireGrouping), - }, - } - - return nil, pass(c, p) -} - -func pass(c *Config, p *analysis.Pass) error { - for _, f := range p.Files { - if err := filepass(c, p, f); err != nil { - return err - } - } - - return nil -} - -func filepass(c *Config, p *analysis.Pass, f *ast.File) error { - if err := consts.Filepass(c.ConstsConfig, p, f); err != nil { - return fmt.Errorf("failed to consts.Filepass: %w", err) - } - - if err := imports.Filepass(c.ImportsConfig, p, f); err != nil { - return fmt.Errorf("failed to imports.Filepass: %w", err) - } - - if err := types.Filepass(c.TypesConfig, p, f); err != nil { - return fmt.Errorf("failed to types.Filepass: %w", err) - } - - if err := vars.Filepass(c.VarsConfig, p, f); err != nil { - return fmt.Errorf("failed to vars.Filepass: %w", err) - } - - return nil -} diff --git a/vendor/github.com/leonklingele/grouper/pkg/analyzer/config.go b/vendor/github.com/leonklingele/grouper/pkg/analyzer/config.go deleted file mode 100644 index b00595f9a5..0000000000 --- a/vendor/github.com/leonklingele/grouper/pkg/analyzer/config.go +++ /dev/null @@ -1,15 +0,0 @@ -package analyzer - -import ( - "github.com/leonklingele/grouper/pkg/analyzer/consts" - "github.com/leonklingele/grouper/pkg/analyzer/imports" - "github.com/leonklingele/grouper/pkg/analyzer/types" - "github.com/leonklingele/grouper/pkg/analyzer/vars" -) - -type Config struct { - ConstsConfig *consts.Config - ImportsConfig *imports.Config - TypesConfig *types.Config - VarsConfig *vars.Config -} diff --git a/vendor/github.com/leonklingele/grouper/pkg/analyzer/consts/analyzer.go b/vendor/github.com/leonklingele/grouper/pkg/analyzer/consts/analyzer.go deleted file mode 100644 index e4e04c1270..0000000000 --- a/vendor/github.com/leonklingele/grouper/pkg/analyzer/consts/analyzer.go +++ /dev/null @@ -1,19 +0,0 @@ -package consts - -import ( - "go/ast" - "go/token" - - "github.com/leonklingele/grouper/pkg/analyzer/globals" - - "golang.org/x/tools/go/analysis" -) - -// https://go.dev/ref/spec#Constant_declarations - -func Filepass(c *Config, p *analysis.Pass, f *ast.File) error { - return globals.Filepass( - p, f, - token.CONST, c.RequireSingleConst, c.RequireGrouping, - ) -} diff --git a/vendor/github.com/leonklingele/grouper/pkg/analyzer/consts/config.go b/vendor/github.com/leonklingele/grouper/pkg/analyzer/consts/config.go deleted file mode 100644 index aeeab40c78..0000000000 --- a/vendor/github.com/leonklingele/grouper/pkg/analyzer/consts/config.go +++ /dev/null @@ -1,6 +0,0 @@ -package consts - -type Config struct { - RequireSingleConst bool // Require the use of a single global 'const' declaration only - RequireGrouping bool // Require the use of grouped global 'const' declarations -} diff --git a/vendor/github.com/leonklingele/grouper/pkg/analyzer/flags.go b/vendor/github.com/leonklingele/grouper/pkg/analyzer/flags.go deleted file mode 100644 index 42447cbefe..0000000000 --- a/vendor/github.com/leonklingele/grouper/pkg/analyzer/flags.go +++ /dev/null @@ -1,37 +0,0 @@ -package analyzer - -import ( - "flag" -) - -const ( - FlagNameConstRequireSingleConst = "const-require-single-const" - FlagNameConstRequireGrouping = "const-require-grouping" - - FlagNameImportRequireSingleImport = "import-require-single-import" - FlagNameImportRequireGrouping = "import-require-grouping" - - FlagNameTypeRequireSingleType = "type-require-single-type" - FlagNameTypeRequireGrouping = "type-require-grouping" - - FlagNameVarRequireSingleVar = "var-require-single-var" - FlagNameVarRequireGrouping = "var-require-grouping" -) - -func Flags() flag.FlagSet { - fs := flag.NewFlagSet(Name, flag.ExitOnError) - - fs.Bool(FlagNameConstRequireSingleConst, false, "require the use of a single global 'const' declaration only") - fs.Bool(FlagNameConstRequireGrouping, false, "require the use of grouped global 'const' declarations") - - fs.Bool(FlagNameImportRequireSingleImport, false, "require the use of a single 'import' declaration only") - fs.Bool(FlagNameImportRequireGrouping, false, "require the use of grouped 'import' declarations") - - fs.Bool(FlagNameTypeRequireSingleType, false, "require the use of a single global 'type' declaration only") - fs.Bool(FlagNameTypeRequireGrouping, false, "require the use of grouped global 'type' declarations") - - fs.Bool(FlagNameVarRequireSingleVar, false, "require the use of a single global 'var' declaration only") - fs.Bool(FlagNameVarRequireGrouping, false, "require the use of grouped global 'var' declarations") - - return *fs -} diff --git a/vendor/github.com/leonklingele/grouper/pkg/analyzer/globals/analyzer.go b/vendor/github.com/leonklingele/grouper/pkg/analyzer/globals/analyzer.go deleted file mode 100644 index 15940a4807..0000000000 --- a/vendor/github.com/leonklingele/grouper/pkg/analyzer/globals/analyzer.go +++ /dev/null @@ -1,105 +0,0 @@ -package globals - -import ( - "fmt" - "go/ast" - "go/token" - - "golang.org/x/tools/go/analysis" -) - -type Global struct { - Decl *ast.GenDecl - IsGroup bool -} - -func Filepass( - p *analysis.Pass, f *ast.File, - tkn token.Token, requireSingle, requireGrouping bool, -) error { - var globals []*Global - for _, decl := range f.Decls { - genDecl, ok := decl.(*ast.GenDecl) - if !ok { - continue - } - - if genDecl.Tok == tkn { - globals = append(globals, &Global{ - Decl: genDecl, - IsGroup: genDecl.Lparen != 0, - }) - } - } - - numGlobals := len(globals) - if numGlobals == 0 { - // Bail out early - return nil - } - - if requireSingle && numGlobals > 1 { - msg := fmt.Sprintf("should only use a single global '%s' declaration, %d found", tkn.String(), numGlobals) - dups := globals[1:] - firstdup := dups[0] - decl := firstdup.Decl - - report := analysis.Diagnostic{ //nolint:exhaustivestruct // we do not need all fields - Pos: decl.Pos(), - End: decl.End(), - Message: msg, - // TODO(leon): Suggest fix - } - - if len(dups) > 1 { - report.Related = toRelated(dups[1:]) - } - - p.Report(report) - } - - if requireGrouping { - var ungrouped []*Global - for _, g := range globals { - if !g.IsGroup { - ungrouped = append(ungrouped, g) - } - } - - if numUngrouped := len(ungrouped); numUngrouped != 0 { - msg := fmt.Sprintf("should only use grouped global '%s' declarations", tkn.String()) - firstmatch := ungrouped[0] - decl := firstmatch.Decl - - report := analysis.Diagnostic{ //nolint:exhaustivestruct // we do not need all fields - Pos: decl.Pos(), - End: decl.End(), - Message: msg, - // TODO(leon): Suggest fix - } - - if numUngrouped > 1 { - report.Related = toRelated(ungrouped[1:]) - } - - p.Report(report) - } - } - - return nil -} - -func toRelated(globals []*Global) []analysis.RelatedInformation { - related := make([]analysis.RelatedInformation, 0, len(globals)) - for _, g := range globals { - decl := g.Decl - - related = append(related, analysis.RelatedInformation{ - Pos: decl.Pos(), - End: decl.End(), - Message: "found here", - }) - } - - return related -} diff --git a/vendor/github.com/leonklingele/grouper/pkg/analyzer/imports/analyzer.go b/vendor/github.com/leonklingele/grouper/pkg/analyzer/imports/analyzer.go deleted file mode 100644 index b545f00c05..0000000000 --- a/vendor/github.com/leonklingele/grouper/pkg/analyzer/imports/analyzer.go +++ /dev/null @@ -1,103 +0,0 @@ -package imports - -import ( - "fmt" - "go/ast" - "go/token" - - "golang.org/x/tools/go/analysis" -) - -// https://go.dev/ref/spec#Import_declarations - -type Import struct { - Decl *ast.GenDecl - IsGroup bool -} - -func Filepass(c *Config, p *analysis.Pass, f *ast.File) error { - var imports []*Import - ast.Inspect(f, func(n ast.Node) bool { - if decl, ok := n.(*ast.GenDecl); ok { - if decl.Tok == token.IMPORT { - imports = append(imports, &Import{ - Decl: decl, - IsGroup: decl.Lparen != 0, - }) - } - } - - return true - }) - - numImports := len(imports) - if numImports == 0 { - // Bail out early - return nil - } - - if c.RequireSingleImport && numImports > 1 { - msg := fmt.Sprintf("should only use a single 'import' declaration, %d found", numImports) - dups := imports[1:] - firstdup := dups[0] - decl := firstdup.Decl - - report := analysis.Diagnostic{ //nolint:exhaustivestruct // we do not need all fields - Pos: decl.Pos(), - End: decl.End(), - Message: msg, - // TODO(leon): Suggest fix - } - - if len(dups) > 1 { - report.Related = toRelated(dups[1:]) - } - - p.Report(report) - } - - if c.RequireGrouping { - var ungroupedImports []*Import - for _, imp := range imports { - if !imp.IsGroup { - ungroupedImports = append(ungroupedImports, imp) - } - } - - if numUngroupedImports := len(ungroupedImports); numUngroupedImports != 0 { - msg := "should only use grouped 'import' declarations" - firstmatch := ungroupedImports[0] - decl := firstmatch.Decl - - report := analysis.Diagnostic{ //nolint:exhaustivestruct // we do not need all fields - Pos: decl.Pos(), - End: decl.End(), - Message: msg, - // TODO(leon): Suggest fix - } - - if numUngroupedImports > 1 { - report.Related = toRelated(ungroupedImports[1:]) - } - - p.Report(report) - } - } - - return nil -} - -func toRelated(imports []*Import) []analysis.RelatedInformation { - related := make([]analysis.RelatedInformation, 0, len(imports)) - for _, imp := range imports { - decl := imp.Decl - - related = append(related, analysis.RelatedInformation{ - Pos: decl.Pos(), - End: decl.End(), - Message: "found here", - }) - } - - return related -} diff --git a/vendor/github.com/leonklingele/grouper/pkg/analyzer/imports/config.go b/vendor/github.com/leonklingele/grouper/pkg/analyzer/imports/config.go deleted file mode 100644 index 6a6971b4ad..0000000000 --- a/vendor/github.com/leonklingele/grouper/pkg/analyzer/imports/config.go +++ /dev/null @@ -1,6 +0,0 @@ -package imports - -type Config struct { - RequireSingleImport bool // Require the use of a single 'import' declaration only - RequireGrouping bool // Require the use of grouped 'import' declarations -} diff --git a/vendor/github.com/leonklingele/grouper/pkg/analyzer/types/analyzer.go b/vendor/github.com/leonklingele/grouper/pkg/analyzer/types/analyzer.go deleted file mode 100644 index 63bbab33b7..0000000000 --- a/vendor/github.com/leonklingele/grouper/pkg/analyzer/types/analyzer.go +++ /dev/null @@ -1,19 +0,0 @@ -package types - -import ( - "go/ast" - "go/token" - - "github.com/leonklingele/grouper/pkg/analyzer/globals" - - "golang.org/x/tools/go/analysis" -) - -// https://go.dev/ref/spec#Type_declarations - -func Filepass(c *Config, p *analysis.Pass, f *ast.File) error { - return globals.Filepass( - p, f, - token.TYPE, c.RequireSingleType, c.RequireGrouping, - ) -} diff --git a/vendor/github.com/leonklingele/grouper/pkg/analyzer/types/config.go b/vendor/github.com/leonklingele/grouper/pkg/analyzer/types/config.go deleted file mode 100644 index e24cef9dae..0000000000 --- a/vendor/github.com/leonklingele/grouper/pkg/analyzer/types/config.go +++ /dev/null @@ -1,6 +0,0 @@ -package types - -type Config struct { - RequireSingleType bool // Require the use of a single global 'type' declaration only - RequireGrouping bool // Require the use of grouped global 'type' declarations -} diff --git a/vendor/github.com/leonklingele/grouper/pkg/analyzer/vars/analyzer.go b/vendor/github.com/leonklingele/grouper/pkg/analyzer/vars/analyzer.go deleted file mode 100644 index 20c7812233..0000000000 --- a/vendor/github.com/leonklingele/grouper/pkg/analyzer/vars/analyzer.go +++ /dev/null @@ -1,19 +0,0 @@ -package vars - -import ( - "go/ast" - "go/token" - - "github.com/leonklingele/grouper/pkg/analyzer/globals" - - "golang.org/x/tools/go/analysis" -) - -// https://go.dev/ref/spec#Variable_declarations - -func Filepass(c *Config, p *analysis.Pass, f *ast.File) error { - return globals.Filepass( - p, f, - token.VAR, c.RequireSingleVar, c.RequireGrouping, - ) -} diff --git a/vendor/github.com/leonklingele/grouper/pkg/analyzer/vars/config.go b/vendor/github.com/leonklingele/grouper/pkg/analyzer/vars/config.go deleted file mode 100644 index 4c7c1d8384..0000000000 --- a/vendor/github.com/leonklingele/grouper/pkg/analyzer/vars/config.go +++ /dev/null @@ -1,6 +0,0 @@ -package vars - -type Config struct { - RequireSingleVar bool // Require the use of a single global 'var' declaration only - RequireGrouping bool // Require the use of grouped global 'var' declarations -} diff --git a/vendor/github.com/lucasb-eyer/go-colorful/.gitignore b/vendor/github.com/lucasb-eyer/go-colorful/.gitignore deleted file mode 100644 index 0aa2c92281..0000000000 --- a/vendor/github.com/lucasb-eyer/go-colorful/.gitignore +++ /dev/null @@ -1,101 +0,0 @@ -# Created by https://www.toptal.com/developers/gitignore/api/code,go,linux,macos,windows -# Edit at https://www.toptal.com/developers/gitignore?templates=code,go,linux,macos,windows - -### Code ### -.vscode/* -!.vscode/tasks.json -!.vscode/launch.json -*.code-workspace - -### Go ### -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib - -# Test binary, built with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -# Dependency directories (remove the comment below to include it) -# vendor/ - -### Go Patch ### -/vendor/ -/Godeps/ - -### 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* - -### macOS ### -# 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 - -### Windows ### -# Windows thumbnail cache files -Thumbs.db -Thumbs.db:encryptable -ehthumbs.db -ehthumbs_vista.db - -# Dump file -*.stackdump - -# Folder config file -[Dd]esktop.ini - -# Recycle Bin used on file shares -$RECYCLE.BIN/ - -# Windows Installer files -*.cab -*.msi -*.msix -*.msm -*.msp - -# Windows shortcuts -*.lnk - -# End of https://www.toptal.com/developers/gitignore/api/code,go,linux,macos,windows diff --git a/vendor/github.com/lucasb-eyer/go-colorful/CHANGELOG.md b/vendor/github.com/lucasb-eyer/go-colorful/CHANGELOG.md deleted file mode 100644 index 84f9c7b2c7..0000000000 --- a/vendor/github.com/lucasb-eyer/go-colorful/CHANGELOG.md +++ /dev/null @@ -1,42 +0,0 @@ -# Changelog -All notable changes to this project will be documented in this file. - -This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -The format of this file is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -but only releases after v1.0.3 properly adhere to it. - - -## [1.2.0] - 2021-01-27 -### Added -- HSLuv and HPLuv color spaces (#41, #51) -- CIE LCh(uv) color space, called `LuvLCh` in code (#51) -- JSON and envconfig serialization support for `HexColor` (#42) -- `DistanceLinearRGB` (#53) - -### Fixed -- RGB to/from XYZ conversion is more accurate (#51) -- A bug in `XYZToLuvWhiteRef` that only applied to very small values was fixed (#51) -- `BlendHCL` output is clamped so that it's not invalid (#46) -- Properly documented `DistanceCIE76` (#40) -- Some small godoc fixes - - -## [1.0.3] - 2019-11-11 -- Remove SQLMock dependency - - -## [1.0.2] - 2019-04-07 -- Fixes SQLMock dependency - - -## [1.0.1] - 2019-03-24 -- Adds support for Go Modules - - -## [1.0.0] - 2018-05-26 -- API Breaking change in `MakeColor`: instead of `panic`ing when alpha is zero, it now returns a secondary, boolean return value indicating success. See [the color.Color interface](#the-colorcolor-interface) section and [this FAQ entry](#q-why-would-makecolor-ever-fail) for details. - - -## [0.9.0] - 2018-05-26 -- Initial version number after having ignored versioning for a long time :) diff --git a/vendor/github.com/lucasb-eyer/go-colorful/LICENSE b/vendor/github.com/lucasb-eyer/go-colorful/LICENSE deleted file mode 100644 index 4e402a00e5..0000000000 --- a/vendor/github.com/lucasb-eyer/go-colorful/LICENSE +++ /dev/null @@ -1,7 +0,0 @@ -Copyright (c) 2013 Lucas Beyer - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/lucasb-eyer/go-colorful/README.md b/vendor/github.com/lucasb-eyer/go-colorful/README.md deleted file mode 100644 index 8b9bd49991..0000000000 --- a/vendor/github.com/lucasb-eyer/go-colorful/README.md +++ /dev/null @@ -1,482 +0,0 @@ -go-colorful -=========== - -[![go reportcard](https://goreportcard.com/badge/github.com/lucasb-eyer/go-colorful)](https://goreportcard.com/report/github.com/lucasb-eyer/go-colorful) - -A library for playing with colors in Go. Supports Go 1.13 onwards. - -Why? -==== -I love games. I make games. I love detail and I get lost in detail. -One such detail popped up during the development of [Memory Which Does Not Suck](https://github.com/lucasb-eyer/mwdns/), -when we wanted the server to assign the players random colors. Sometimes -two players got very similar colors, which bugged me. The very same evening, -[I want hue](http://tools.medialab.sciences-po.fr/iwanthue/) was the top post -on HackerNews' frontpage and showed me how to Do It Right™. Last but not -least, there was no library for handling color spaces available in go. Colorful -does just that and implements Go's `color.Color` interface. - -What? -===== -Go-Colorful stores colors in RGB and provides methods from converting these to various color-spaces. Currently supported colorspaces are: - -- **RGB:** All three of Red, Green and Blue in [0..1]. -- **HSL:** Hue in [0..360], Saturation and Luminance in [0..1]. For legacy reasons; please forget that it exists. -- **HSV:** Hue in [0..360], Saturation and Value in [0..1]. You're better off using HCL, see below. -- **Hex RGB:** The "internet" color format, as in #FF00FF. -- **Linear RGB:** See [gamma correct rendering](http://www.sjbrown.co.uk/2004/05/14/gamma-correct-rendering/). -- **CIE-XYZ:** CIE's standard color space, almost in [0..1]. -- **CIE-xyY:** encodes chromacity in x and y and luminance in Y, all in [0..1] -- **CIE-L\*a\*b\*:** A *perceptually uniform* color space, i.e. distances are meaningful. L\* in [0..1] and a\*, b\* almost in [-1..1]. -- **CIE-L\*u\*v\*:** Very similar to CIE-L\*a\*b\*, there is [no consensus](http://en.wikipedia.org/wiki/CIELUV#Historical_background) on which one is "better". -- **CIE-L\*C\*h° (HCL):** This is generally the [most useful](http://vis4.net/blog/posts/avoid-equidistant-hsv-colors/) one; CIE-L\*a\*b\* space in polar coordinates, i.e. a *better* HSV. H° is in [0..360], C\* almost in [-1..1] and L\* as in CIE-L\*a\*b\*. -- **CIE LCh(uv):** Called `LuvLCh` in code, this is a cylindrical transformation of the CIE-L\*u\*v\* color space. Like HCL above: H° is in [0..360], C\* almost in [-1..1] and L\* as in CIE-L\*u\*v\*. -- **HSLuv:** The better alternative to HSL, see [here](https://www.hsluv.org/) and [here](https://www.kuon.ch/post/2020-03-08-hsluv/). Hue in [0..360], Saturation and Luminance in [0..1]. -- **HPLuv:** A variant of HSLuv. The color space is smoother, but only pastel colors can be included. Because the valid colors are limited, it's easy to get invalid Saturation values way above 1.0, indicating the color can't be represented in HPLuv beccause it's not pastel. - -For the colorspaces where it makes sense (XYZ, Lab, Luv, HCl), the -[D65](http://en.wikipedia.org/wiki/Illuminant_D65) is used as reference white -by default but methods for using your own reference white are provided. - -A coordinate being *almost in* a range means that generally it is, but for very -bright colors and depending on the reference white, it might overflow this -range slightly. For example, C\* of #0000ff is 1.338. - -Unit-tests are provided. - -Nice, but what's it useful for? -------------------------------- - -- Converting color spaces. Some people like to do that. -- Blending (interpolating) between colors in a "natural" look by using the right colorspace. -- Generating random colors under some constraints (e.g. colors of the same shade, or shades of one color.) -- Generating gorgeous random palettes with distinct colors of a same temperature. - -What not (yet)? -=============== -There are a few features which are currently missing and might be useful. -I just haven't implemented them yet because I didn't have the need for it. -Pull requests welcome. - -- Sorting colors (potentially using above mentioned distances) - -So which colorspace should I use? -================================= -It depends on what you want to do. I think the folks from *I want hue* are -on-spot when they say that RGB fits to how *screens produce* color, CIE L\*a\*b\* -fits how *humans perceive* color and HCL fits how *humans think* colors. - -Whenever you'd use HSV, rather go for CIE-L\*C\*h°. for fixed lightness L\* and -chroma C\* values, the hue angle h° rotates through colors of the same -perceived brightness and intensity. - -How? -==== - -### Installing -Installing the library is as easy as - -```bash -$ go get github.com/lucasb-eyer/go-colorful -``` - -The package can then be used through an - -```go -import "github.com/lucasb-eyer/go-colorful" -``` - -### Basic usage - -Create a beautiful blue color using different source space: - -```go -// Any of the following should be the same -c := colorful.Color{0.313725, 0.478431, 0.721569} -c, err := colorful.Hex("#517AB8") -if err != nil { - log.Fatal(err) -} -c = colorful.Hsv(216.0, 0.56, 0.722) -c = colorful.Xyz(0.189165, 0.190837, 0.480248) -c = colorful.Xyy(0.219895, 0.221839, 0.190837) -c = colorful.Lab(0.507850, 0.040585,-0.370945) -c = colorful.Luv(0.507849,-0.194172,-0.567924) -c = colorful.Hcl(276.2440, 0.373160, 0.507849) -fmt.Printf("RGB values: %v, %v, %v", c.R, c.G, c.B) -``` - -And then converting this color back into various color spaces: - -```go -hex := c.Hex() -h, s, v := c.Hsv() -x, y, z := c.Xyz() -x, y, Y := c.Xyy() -l, a, b := c.Lab() -l, u, v := c.Luv() -h, c, l := c.Hcl() -``` - -Note that, because of Go's unfortunate choice of requiring an initial uppercase, -the name of the functions relating to the xyY space are just off. If you have -any good suggestion, please open an issue. (I don't consider XyY good.) - -### The `color.Color` interface -Because a `colorful.Color` implements Go's `color.Color` interface (found in the -`image/color` package), it can be used anywhere that expects a `color.Color`. - -Furthermore, you can convert anything that implements the `color.Color` interface -into a `colorful.Color` using the `MakeColor` function: - -```go -c, ok := colorful.MakeColor(color.Gray16{12345}) -``` - -**Caveat:** Be aware that this latter conversion (using `MakeColor`) hits a -corner-case when alpha is exactly zero. Because `color.Color` uses pre-multiplied -alpha colors, this means the RGB values are lost (set to 0) and it's impossible -to recover them. In such a case `MakeColor` will return `false` as its second value. - -### Comparing colors -In the RGB color space, the Euclidian distance between colors *doesn't* correspond -to visual/perceptual distance. This means that two pairs of colors which have the -same distance in RGB space can look much further apart. This is fixed by the -CIE-L\*a\*b\*, CIE-L\*u\*v\* and CIE-L\*C\*h° color spaces. -Thus you should only compare colors in any of these space. -(Note that the distance in CIE-L\*a\*b\* and CIE-L\*C\*h° are the same, since it's the same space but in cylindrical coordinates) - -![Color distance comparison](doc/colordist/colordist.png) - -The two colors shown on the top look much more different than the two shown on -the bottom. Still, in RGB space, their distance is the same. -Here is a little example program which shows the distances between the top two -and bottom two colors in RGB, CIE-L\*a\*b\* and CIE-L\*u\*v\* space. You can find it in `doc/colordist/colordist.go`. - -```go -package main - -import "fmt" -import "github.com/lucasb-eyer/go-colorful" - -func main() { - c1a := colorful.Color{150.0 / 255.0, 10.0 / 255.0, 150.0 / 255.0} - c1b := colorful.Color{53.0 / 255.0, 10.0 / 255.0, 150.0 / 255.0} - c2a := colorful.Color{10.0 / 255.0, 150.0 / 255.0, 50.0 / 255.0} - c2b := colorful.Color{99.9 / 255.0, 150.0 / 255.0, 10.0 / 255.0} - - fmt.Printf("DistanceRgb: c1: %v\tand c2: %v\n", c1a.DistanceRgb(c1b), c2a.DistanceRgb(c2b)) - fmt.Printf("DistanceLab: c1: %v\tand c2: %v\n", c1a.DistanceLab(c1b), c2a.DistanceLab(c2b)) - fmt.Printf("DistanceLuv: c1: %v\tand c2: %v\n", c1a.DistanceLuv(c1b), c2a.DistanceLuv(c2b)) - fmt.Printf("DistanceCIE76: c1: %v\tand c2: %v\n", c1a.DistanceCIE76(c1b), c2a.DistanceCIE76(c2b)) - fmt.Printf("DistanceCIE94: c1: %v\tand c2: %v\n", c1a.DistanceCIE94(c1b), c2a.DistanceCIE94(c2b)) - fmt.Printf("DistanceCIEDE2000: c1: %v\tand c2: %v\n", c1a.DistanceCIEDE2000(c1b), c2a.DistanceCIEDE2000(c2b)) -} -``` - -Running the above program shows that you should always prefer any of the CIE distances: - -```bash -$ go run colordist.go -DistanceRgb: c1: 0.3803921568627451 and c2: 0.3858713931171159 -DistanceLab: c1: 0.32048458312798056 and c2: 0.24397151758565272 -DistanceLuv: c1: 0.5134369614199698 and c2: 0.2568692839860636 -DistanceCIE76: c1: 0.32048458312798056 and c2: 0.24397151758565272 -DistanceCIE94: c1: 0.19799168128511324 and c2: 0.12207136371167401 -DistanceCIEDE2000: c1: 0.17274551120971166 and c2: 0.10665210031428465 -``` - -It also shows that `DistanceLab` is more formally known as `DistanceCIE76` and -has been superseded by the slightly more accurate, but much more expensive -`DistanceCIE94` and `DistanceCIEDE2000`. - -Note that `AlmostEqualRgb` is provided mainly for (unit-)testing purposes. Use -it only if you really know what you're doing. It will eat your cat. - -### Blending colors -Blending is highly connected to distance, since it basically "walks through" the -colorspace thus, if the colorspace maps distances well, the walk is "smooth". - -Colorful comes with blending functions in RGB, HSV and any of the LAB spaces. -Of course, you'd rather want to use the blending functions of the LAB spaces since -these spaces map distances well but, just in case, here is an example showing -you how the blendings (`#fdffcc` to `#242a42`) are done in the various spaces: - -![Blending colors in different spaces.](doc/colorblend/colorblend.png) - -What you see is that HSV is really bad: it adds some green, which is not present -in the original colors at all! RGB is much better, but it stays light a little -too long. LUV and LAB both hit the right lightness but LAB has a little more -color. HCL works in the same vein as HSV (both cylindrical interpolations) but -it does it right in that there is no green appearing and the lighthness changes -in a linear manner. - -While this seems all good, you need to know one thing: When interpolating in any -of the CIE color spaces, you might get invalid RGB colors! This is important if -the starting and ending colors are user-input or random. An example of where this -happens is when blending between `#eeef61` and `#1e3140`: - -![Invalid RGB colors may crop up when blending in CIE spaces.](doc/colorblend/invalid.png) - -You can test whether a color is a valid RGB color by calling the `IsValid` method -and indeed, calling IsValid will return false for the redish colors on the bottom. -One way to "fix" this is to get a valid color close to the invalid one by calling -`Clamped`, which always returns a nearby valid color. Doing this, we get the -following result, which is satisfactory: - -![Fixing invalid RGB colors by clamping them to the valid range.](doc/colorblend/clamped.png) - -The following is the code creating the above three images; it can be found in `doc/colorblend/colorblend.go` - -```go -package main - -import "fmt" -import "github.com/lucasb-eyer/go-colorful" -import "image" -import "image/draw" -import "image/png" -import "os" - -func main() { - blocks := 10 - blockw := 40 - img := image.NewRGBA(image.Rect(0,0,blocks*blockw,200)) - - c1, _ := colorful.Hex("#fdffcc") - c2, _ := colorful.Hex("#242a42") - - // Use these colors to get invalid RGB in the gradient. - //c1, _ := colorful.Hex("#EEEF61") - //c2, _ := colorful.Hex("#1E3140") - - for i := 0 ; i < blocks ; i++ { - draw.Draw(img, image.Rect(i*blockw, 0,(i+1)*blockw, 40), &image.Uniform{c1.BlendHsv(c2, float64(i)/float64(blocks-1))}, image.Point{}, draw.Src) - draw.Draw(img, image.Rect(i*blockw, 40,(i+1)*blockw, 80), &image.Uniform{c1.BlendLuv(c2, float64(i)/float64(blocks-1))}, image.Point{}, draw.Src) - draw.Draw(img, image.Rect(i*blockw, 80,(i+1)*blockw,120), &image.Uniform{c1.BlendRgb(c2, float64(i)/float64(blocks-1))}, image.Point{}, draw.Src) - draw.Draw(img, image.Rect(i*blockw,120,(i+1)*blockw,160), &image.Uniform{c1.BlendLab(c2, float64(i)/float64(blocks-1))}, image.Point{}, draw.Src) - draw.Draw(img, image.Rect(i*blockw,160,(i+1)*blockw,200), &image.Uniform{c1.BlendHcl(c2, float64(i)/float64(blocks-1))}, image.Point{}, draw.Src) - - // This can be used to "fix" invalid colors in the gradient. - //draw.Draw(img, image.Rect(i*blockw,160,(i+1)*blockw,200), &image.Uniform{c1.BlendHcl(c2, float64(i)/float64(blocks-1)).Clamped()}, image.Point{}, draw.Src) - } - - toimg, err := os.Create("colorblend.png") - if err != nil { - fmt.Printf("Error: %v", err) - return - } - defer toimg.Close() - - png.Encode(toimg, img) -} -``` - -#### Generating color gradients -A very common reason to blend colors is creating gradients. There is an example -program in [doc/gradientgen.go](doc/gradientgen/gradientgen.go); it doesn't use any API -which hasn't been used in the previous example code, so I won't bother pasting -the code in here. Just look at that gorgeous gradient it generated in HCL space: - -!["Spectral" colorbrewer gradient in HCL space.](doc/gradientgen/gradientgen.png) - -### Getting random colors -It is sometimes necessary to generate random colors. You could simply do this -on your own by generating colors with random values. By restricting the random -values to a range smaller than [0..1] and using a space such as CIE-H\*C\*l° or -HSV, you can generate both random shades of a color or random colors of a -lightness: - -```go -random_blue := colorful.Hcl(180.0+rand.Float64()*50.0, 0.2+rand.Float64()*0.8, 0.3+rand.Float64()*0.7) -random_dark := colorful.Hcl(rand.Float64()*360.0, rand.Float64(), rand.Float64()*0.4) -random_light := colorful.Hcl(rand.Float64()*360.0, rand.Float64(), 0.6+rand.Float64()*0.4) -``` - -Since getting random "warm" and "happy" colors is quite a common task, there -are some helper functions: - -```go -colorful.WarmColor() -colorful.HappyColor() -colorful.FastWarmColor() -colorful.FastHappyColor() -``` - -The ones prefixed by `Fast` are faster but less coherent since they use the HSV -space as opposed to the regular ones which use CIE-L\*C\*h° space. The -following picture shows the warm colors in the top two rows and happy colors -in the bottom two rows. Within these, the first is the regular one and the -second is the fast one. - -![Warm, fast warm, happy and fast happy random colors, respectively.](doc/colorgens/colorgens.png) - -Don't forget to initialize the random seed! You can see the code used for -generating this picture in `doc/colorgens/colorgens.go`. - -### Getting random palettes -As soon as you need to generate more than one random color, you probably want -them to be distinguishible. Playing against an opponent which has almost the -same blue as I do is not fun. This is where random palettes can help. - -These palettes are generated using an algorithm which ensures that all colors -on the palette are as distinguishible as possible. Again, there is a `Fast` -method which works in HSV and is less perceptually uniform and a non-`Fast` -method which works in CIE spaces. For more theory on `SoftPalette`, check out -[I want hue](http://tools.medialab.sciences-po.fr/iwanthue/theory.php). Yet -again, there is a `Happy` and a `Warm` version, which do what you expect, but -now there is an additional `Soft` version, which is more configurable: you can -give a constraint on the color space in order to get colors within a certain *feel*. - -Let's start with the simple methods first, all they take is the amount of -colors to generate, which could, for example, be the player count. They return -an array of `colorful.Color` objects: - -```go -pal1, err1 := colorful.WarmPalette(10) -pal2 := colorful.FastWarmPalette(10) -pal3, err3 := colorful.HappyPalette(10) -pal4 := colorful.FastHappyPalette(10) -pal5, err5 := colorful.SoftPalette(10) -``` - -Note that the non-fast methods *may* fail if you ask for way too many colors. -Let's move on to the advanced one, namely `SoftPaletteEx`. Besides the color -count, this function takes a `SoftPaletteSettings` object as argument. The -interesting part here is its `CheckColor` member, which is a boolean function -taking three floating points as arguments: `l`, `a` and `b`. This function -should return `true` for colors which lie within the region you want and `false` -otherwise. The other members are `Iteration`, which should be within [5..100] -where higher means slower but more exact palette, and `ManySamples` which you -should set to `true` in case your `CheckColor` constraint rejects a large part -of the color space. - -For example, to create a palette of 10 brownish colors, you'd call it like this: - -```go -func isbrowny(l, a, b float64) bool { - h, c, L := colorful.LabToHcl(l, a, b) - return 10.0 < h && h < 50.0 && 0.1 < c && c < 0.5 && L < 0.5 -} -// Since the above function is pretty restrictive, we set ManySamples to true. -brownies := colorful.SoftPaletteEx(10, colorful.SoftPaletteSettings{isbrowny, 50, true}) -``` - -The following picture shows the palettes generated by all of these methods -(sourcecode in `doc/palettegens/palettegens.go`), in the order they were presented, i.e. -from top to bottom: `Warm`, `FastWarm`, `Happy`, `FastHappy`, `Soft`, -`SoftEx(isbrowny)`. All of them contain some randomness, so YMMV. - -![All example palettes](doc/palettegens/palettegens.png) - -Again, the code used for generating the above image is available as [doc/palettegens/palettegens.go](https://github.com/lucasb-eyer/go-colorful/blob/master/doc/palettegens/palettegens.go). - -### Sorting colors -TODO: Sort using dist fn. - -### Using linear RGB for computations -There are two methods for transforming RGB<->Linear RGB: a fast and almost precise one, -and a slow and precise one. - -```go -r, g, b := colorful.Hex("#FF0000").FastLinearRgb() -``` - -TODO: describe some more. - -### Want to use some other reference point? - -```go -c := colorful.LabWhiteRef(0.507850, 0.040585,-0.370945, colorful.D50) -l, a, b := c.LabWhiteRef(colorful.D50) -``` - -### Reading and writing colors from databases - -The type `HexColor` makes it easy to store colors as strings in a database. It -implements the [https://godoc.org/database/sql#Scanner](database/sql.Scanner) -and [database/sql/driver.Value](https://godoc.org/database/sql/driver.Value) -interfaces which provide automatic type conversion. - -Example: - -```go -var hc HexColor -_, err := db.QueryRow("SELECT '#ff0000';").Scan(&hc) -// hc == HexColor{R: 1, G: 0, B: 0}; err == nil -``` - -FAQ -=== - -### Q: I get all f!@#ed up values! Your library sucks! -A: You probably provided values in the wrong range. For example, RGB values are -expected to reside between 0 and 1, *not* between 0 and 255. Normalize your colors. - -### Q: Lab/Luv/HCl seem broken! Your library sucks! -They look like this: - - - -A: You're likely trying to generate and display colors that can't be represented by RGB, -and thus monitors. When you're trying to convert, say, `HCL(190.0, 1.0, 1.0).RGB255()`, -you're asking for RGB values of `(-2105.254 300.680 286.185)`, which clearly don't exist, -and the `RGB255` function just casts these numbers to `uint8`, creating wrap-around and -what looks like a completely broken gradient. What you want to do, is either use more -reasonable values of colors which actually exist in RGB, or just `Clamp()` the resulting -color to its nearest existing one, living with the consequences: -`HCL(190.0, 1.0, 1.0).Clamp().RGB255()`. It will look something like this: - - - -[Here's an issue going in-depth about this](https://github.com/lucasb-eyer/go-colorful/issues/14), -as well as [my answer](https://github.com/lucasb-eyer/go-colorful/issues/14#issuecomment-324205385), -both with code and pretty pictures. Also note that this was somewhat covered above in the -["Blending colors" section](https://github.com/lucasb-eyer/go-colorful#blending-colors). - -### Q: In a tight loop, conversion to Lab/Luv/HCl/... are slooooow! -A: Yes, they are. -This library aims for correctness, readability, and modularity; it wasn't written with speed in mind. -A large part of the slowness comes from these conversions going through `LinearRgb` which uses powers. -I implemented a fast approximation to `LinearRgb` called `FastLinearRgb` by using Taylor approximations. -The approximation is roughly 5x faster and precise up to roughly 0.5%, -the major caveat being that if the input values are outside the range 0-1, accuracy drops dramatically. -You can use these in your conversions as follows: - -```go -col := // Get your color somehow -l, a, b := XyzToLab(LinearRgbToXyz(col.LinearRgb())) -``` - -If you need faster versions of `Distance*` and `Blend*` that make use of this fast approximation, -feel free to implement them and open a pull-request, I'll happily accept. - -The derivation of these functions can be followed in [this Jupyter notebook](doc/LinearRGB Approximations.ipynb). -Here's the main figure showing the approximation quality: - -![approximation quality](doc/approx-quality.png) - -More speed could be gained by using SIMD instructions in many places. -You can also get more speed for specific conversions by approximating the full conversion function, -but that is outside the scope of this library. -Thanks to [@ZirconiumX](https://github.com/ZirconiumX) for starting this investigation, -see [issue #18](https://github.com/lucasb-eyer/go-colorful/issues/18) for details. - -### Q: Why would `MakeColor` ever fail!? -A: `MakeColor` fails when the alpha channel is zero. In that case, the -conversion is undefined. See [issue 21](https://github.com/lucasb-eyer/go-colorful/issues/21) -as well as the short caveat note in the ["The `color.Color` interface"](README.md#the-colorcolor-interface) -section above. - -Who? -==== - -This library was developed by Lucas Beyer with contributions from -Bastien Dejean (@baskerville), Phil Kulak (@pkulak) and Christian Muehlhaeuser (@muesli). - -It is now maintained by makeworld (@makeworld-the-better-one). - - -## License - -This repo is under the MIT license, see [LICENSE](LICENSE) for details. diff --git a/vendor/github.com/lucasb-eyer/go-colorful/colorgens.go b/vendor/github.com/lucasb-eyer/go-colorful/colorgens.go deleted file mode 100644 index 2e2e49e19f..0000000000 --- a/vendor/github.com/lucasb-eyer/go-colorful/colorgens.go +++ /dev/null @@ -1,55 +0,0 @@ -// Various ways to generate single random colors - -package colorful - -import ( - "math/rand" -) - -// Creates a random dark, "warm" color through a restricted HSV space. -func FastWarmColor() Color { - return Hsv( - rand.Float64()*360.0, - 0.5+rand.Float64()*0.3, - 0.3+rand.Float64()*0.3) -} - -// Creates a random dark, "warm" color through restricted HCL space. -// This is slower than FastWarmColor but will likely give you colors which have -// the same "warmness" if you run it many times. -func WarmColor() (c Color) { - for c = randomWarm(); !c.IsValid(); c = randomWarm() { - } - return -} - -func randomWarm() Color { - return Hcl( - rand.Float64()*360.0, - 0.1+rand.Float64()*0.3, - 0.2+rand.Float64()*0.3) -} - -// Creates a random bright, "pimpy" color through a restricted HSV space. -func FastHappyColor() Color { - return Hsv( - rand.Float64()*360.0, - 0.7+rand.Float64()*0.3, - 0.6+rand.Float64()*0.3) -} - -// Creates a random bright, "pimpy" color through restricted HCL space. -// This is slower than FastHappyColor but will likely give you colors which -// have the same "brightness" if you run it many times. -func HappyColor() (c Color) { - for c = randomPimp(); !c.IsValid(); c = randomPimp() { - } - return -} - -func randomPimp() Color { - return Hcl( - rand.Float64()*360.0, - 0.5+rand.Float64()*0.3, - 0.5+rand.Float64()*0.3) -} diff --git a/vendor/github.com/lucasb-eyer/go-colorful/colors.go b/vendor/github.com/lucasb-eyer/go-colorful/colors.go deleted file mode 100644 index 0d5bffe5db..0000000000 --- a/vendor/github.com/lucasb-eyer/go-colorful/colors.go +++ /dev/null @@ -1,979 +0,0 @@ -// The colorful package provides all kinds of functions for working with colors. -package colorful - -import ( - "fmt" - "image/color" - "math" -) - -// A color is stored internally using sRGB (standard RGB) values in the range 0-1 -type Color struct { - R, G, B float64 -} - -// Implement the Go color.Color interface. -func (col Color) RGBA() (r, g, b, a uint32) { - r = uint32(col.R*65535.0 + 0.5) - g = uint32(col.G*65535.0 + 0.5) - b = uint32(col.B*65535.0 + 0.5) - a = 0xFFFF - return -} - -// Constructs a colorful.Color from something implementing color.Color -func MakeColor(col color.Color) (Color, bool) { - r, g, b, a := col.RGBA() - if a == 0 { - return Color{0, 0, 0}, false - } - - // Since color.Color is alpha pre-multiplied, we need to divide the - // RGB values by alpha again in order to get back the original RGB. - r *= 0xffff - r /= a - g *= 0xffff - g /= a - b *= 0xffff - b /= a - - return Color{float64(r) / 65535.0, float64(g) / 65535.0, float64(b) / 65535.0}, true -} - -// Might come in handy sometimes to reduce boilerplate code. -func (col Color) RGB255() (r, g, b uint8) { - r = uint8(col.R*255.0 + 0.5) - g = uint8(col.G*255.0 + 0.5) - b = uint8(col.B*255.0 + 0.5) - return -} - -// Used to simplify HSLuv testing. -func (col Color) values() (float64, float64, float64) { - return col.R, col.G, col.B -} - -// This is the tolerance used when comparing colors using AlmostEqualRgb. -const Delta = 1.0 / 255.0 - -// This is the default reference white point. -var D65 = [3]float64{0.95047, 1.00000, 1.08883} - -// And another one. -var D50 = [3]float64{0.96422, 1.00000, 0.82521} - -// Checks whether the color exists in RGB space, i.e. all values are in [0..1] -func (c Color) IsValid() bool { - return 0.0 <= c.R && c.R <= 1.0 && - 0.0 <= c.G && c.G <= 1.0 && - 0.0 <= c.B && c.B <= 1.0 -} - -// clamp01 clamps from 0 to 1. -func clamp01(v float64) float64 { - return math.Max(0.0, math.Min(v, 1.0)) -} - -// Returns Clamps the color into valid range, clamping each value to [0..1] -// If the color is valid already, this is a no-op. -func (c Color) Clamped() Color { - return Color{clamp01(c.R), clamp01(c.G), clamp01(c.B)} -} - -func sq(v float64) float64 { - return v * v -} - -func cub(v float64) float64 { - return v * v * v -} - -// DistanceRgb computes the distance between two colors in RGB space. -// This is not a good measure! Rather do it in Lab space. -func (c1 Color) DistanceRgb(c2 Color) float64 { - return math.Sqrt(sq(c1.R-c2.R) + sq(c1.G-c2.G) + sq(c1.B-c2.B)) -} - -// DistanceLinearRGB computes the distance between two colors in linear RGB -// space. This is not useful for measuring how humans perceive color, but -// might be useful for other things, like dithering. -func (c1 Color) DistanceLinearRGB(c2 Color) float64 { - r1, g1, b1 := c1.LinearRgb() - r2, g2, b2 := c2.LinearRgb() - return math.Sqrt(sq(r1-r2) + sq(g1-g2) + sq(b1-b2)) -} - -// Check for equality between colors within the tolerance Delta (1/255). -func (c1 Color) AlmostEqualRgb(c2 Color) bool { - return math.Abs(c1.R-c2.R)+ - math.Abs(c1.G-c2.G)+ - math.Abs(c1.B-c2.B) < 3.0*Delta -} - -// You don't really want to use this, do you? Go for BlendLab, BlendLuv or BlendHcl. -func (c1 Color) BlendRgb(c2 Color, t float64) Color { - return Color{c1.R + t*(c2.R-c1.R), - c1.G + t*(c2.G-c1.G), - c1.B + t*(c2.B-c1.B)} -} - -// Utility used by Hxx color-spaces for interpolating between two angles in [0,360]. -func interp_angle(a0, a1, t float64) float64 { - // Based on the answer here: http://stackoverflow.com/a/14498790/2366315 - // With potential proof that it works here: http://math.stackexchange.com/a/2144499 - delta := math.Mod(math.Mod(a1-a0, 360.0)+540, 360.0) - 180.0 - return math.Mod(a0+t*delta+360.0, 360.0) -} - -/// HSV /// -/////////// -// From http://en.wikipedia.org/wiki/HSL_and_HSV -// Note that h is in [0..360] and s,v in [0..1] - -// Hsv returns the Hue [0..360], Saturation and Value [0..1] of the color. -func (col Color) Hsv() (h, s, v float64) { - min := math.Min(math.Min(col.R, col.G), col.B) - v = math.Max(math.Max(col.R, col.G), col.B) - C := v - min - - s = 0.0 - if v != 0.0 { - s = C / v - } - - h = 0.0 // We use 0 instead of undefined as in wp. - if min != v { - if v == col.R { - h = math.Mod((col.G-col.B)/C, 6.0) - } - if v == col.G { - h = (col.B-col.R)/C + 2.0 - } - if v == col.B { - h = (col.R-col.G)/C + 4.0 - } - h *= 60.0 - if h < 0.0 { - h += 360.0 - } - } - return -} - -// Hsv creates a new Color given a Hue in [0..360], a Saturation and a Value in [0..1] -func Hsv(H, S, V float64) Color { - Hp := H / 60.0 - C := V * S - X := C * (1.0 - math.Abs(math.Mod(Hp, 2.0)-1.0)) - - m := V - C - r, g, b := 0.0, 0.0, 0.0 - - switch { - case 0.0 <= Hp && Hp < 1.0: - r = C - g = X - case 1.0 <= Hp && Hp < 2.0: - r = X - g = C - case 2.0 <= Hp && Hp < 3.0: - g = C - b = X - case 3.0 <= Hp && Hp < 4.0: - g = X - b = C - case 4.0 <= Hp && Hp < 5.0: - r = X - b = C - case 5.0 <= Hp && Hp < 6.0: - r = C - b = X - } - - return Color{m + r, m + g, m + b} -} - -// You don't really want to use this, do you? Go for BlendLab, BlendLuv or BlendHcl. -func (c1 Color) BlendHsv(c2 Color, t float64) Color { - h1, s1, v1 := c1.Hsv() - h2, s2, v2 := c2.Hsv() - - // We know that h are both in [0..360] - return Hsv(interp_angle(h1, h2, t), s1+t*(s2-s1), v1+t*(v2-v1)) -} - -/// HSL /// -/////////// - -// Hsl returns the Hue [0..360], Saturation [0..1], and Luminance (lightness) [0..1] of the color. -func (col Color) Hsl() (h, s, l float64) { - min := math.Min(math.Min(col.R, col.G), col.B) - max := math.Max(math.Max(col.R, col.G), col.B) - - l = (max + min) / 2 - - if min == max { - s = 0 - h = 0 - } else { - if l < 0.5 { - s = (max - min) / (max + min) - } else { - s = (max - min) / (2.0 - max - min) - } - - if max == col.R { - h = (col.G - col.B) / (max - min) - } else if max == col.G { - h = 2.0 + (col.B-col.R)/(max-min) - } else { - h = 4.0 + (col.R-col.G)/(max-min) - } - - h *= 60 - - if h < 0 { - h += 360 - } - } - - return -} - -// Hsl creates a new Color given a Hue in [0..360], a Saturation [0..1], and a Luminance (lightness) in [0..1] -func Hsl(h, s, l float64) Color { - if s == 0 { - return Color{l, l, l} - } - - var r, g, b float64 - var t1 float64 - var t2 float64 - var tr float64 - var tg float64 - var tb float64 - - if l < 0.5 { - t1 = l * (1.0 + s) - } else { - t1 = l + s - l*s - } - - t2 = 2*l - t1 - h /= 360 - tr = h + 1.0/3.0 - tg = h - tb = h - 1.0/3.0 - - if tr < 0 { - tr++ - } - if tr > 1 { - tr-- - } - if tg < 0 { - tg++ - } - if tg > 1 { - tg-- - } - if tb < 0 { - tb++ - } - if tb > 1 { - tb-- - } - - // Red - if 6*tr < 1 { - r = t2 + (t1-t2)*6*tr - } else if 2*tr < 1 { - r = t1 - } else if 3*tr < 2 { - r = t2 + (t1-t2)*(2.0/3.0-tr)*6 - } else { - r = t2 - } - - // Green - if 6*tg < 1 { - g = t2 + (t1-t2)*6*tg - } else if 2*tg < 1 { - g = t1 - } else if 3*tg < 2 { - g = t2 + (t1-t2)*(2.0/3.0-tg)*6 - } else { - g = t2 - } - - // Blue - if 6*tb < 1 { - b = t2 + (t1-t2)*6*tb - } else if 2*tb < 1 { - b = t1 - } else if 3*tb < 2 { - b = t2 + (t1-t2)*(2.0/3.0-tb)*6 - } else { - b = t2 - } - - return Color{r, g, b} -} - -/// Hex /// -/////////// - -// Hex returns the hex "html" representation of the color, as in #ff0080. -func (col Color) Hex() string { - // Add 0.5 for rounding - return fmt.Sprintf("#%02x%02x%02x", uint8(col.R*255.0+0.5), uint8(col.G*255.0+0.5), uint8(col.B*255.0+0.5)) -} - -// Hex parses a "html" hex color-string, either in the 3 "#f0c" or 6 "#ff1034" digits form. -func Hex(scol string) (Color, error) { - format := "#%02x%02x%02x" - factor := 1.0 / 255.0 - if len(scol) == 4 { - format = "#%1x%1x%1x" - factor = 1.0 / 15.0 - } - - var r, g, b uint8 - n, err := fmt.Sscanf(scol, format, &r, &g, &b) - if err != nil { - return Color{}, err - } - if n != 3 { - return Color{}, fmt.Errorf("color: %v is not a hex-color", scol) - } - - return Color{float64(r) * factor, float64(g) * factor, float64(b) * factor}, nil -} - -/// Linear /// -////////////// -// http://www.sjbrown.co.uk/2004/05/14/gamma-correct-rendering/ -// http://www.brucelindbloom.com/Eqn_RGB_to_XYZ.html - -func linearize(v float64) float64 { - if v <= 0.04045 { - return v / 12.92 - } - return math.Pow((v+0.055)/1.055, 2.4) -} - -// LinearRgb converts the color into the linear RGB space (see http://www.sjbrown.co.uk/2004/05/14/gamma-correct-rendering/). -func (col Color) LinearRgb() (r, g, b float64) { - r = linearize(col.R) - g = linearize(col.G) - b = linearize(col.B) - return -} - -// A much faster and still quite precise linearization using a 6th-order Taylor approximation. -// See the accompanying Jupyter notebook for derivation of the constants. -func linearize_fast(v float64) float64 { - v1 := v - 0.5 - v2 := v1 * v1 - v3 := v2 * v1 - v4 := v2 * v2 - //v5 := v3*v2 - return -0.248750514614486 + 0.925583310193438*v + 1.16740237321695*v2 + 0.280457026598666*v3 - 0.0757991963780179*v4 //+ 0.0437040411548932*v5 -} - -// FastLinearRgb is much faster than and almost as accurate as LinearRgb. -// BUT it is important to NOTE that they only produce good results for valid colors r,g,b in [0,1]. -func (col Color) FastLinearRgb() (r, g, b float64) { - r = linearize_fast(col.R) - g = linearize_fast(col.G) - b = linearize_fast(col.B) - return -} - -func delinearize(v float64) float64 { - if v <= 0.0031308 { - return 12.92 * v - } - return 1.055*math.Pow(v, 1.0/2.4) - 0.055 -} - -// LinearRgb creates an sRGB color out of the given linear RGB color (see http://www.sjbrown.co.uk/2004/05/14/gamma-correct-rendering/). -func LinearRgb(r, g, b float64) Color { - return Color{delinearize(r), delinearize(g), delinearize(b)} -} - -func delinearize_fast(v float64) float64 { - // This function (fractional root) is much harder to linearize, so we need to split. - if v > 0.2 { - v1 := v - 0.6 - v2 := v1 * v1 - v3 := v2 * v1 - v4 := v2 * v2 - v5 := v3 * v2 - return 0.442430344268235 + 0.592178981271708*v - 0.287864782562636*v2 + 0.253214392068985*v3 - 0.272557158129811*v4 + 0.325554383321718*v5 - } else if v > 0.03 { - v1 := v - 0.115 - v2 := v1 * v1 - v3 := v2 * v1 - v4 := v2 * v2 - v5 := v3 * v2 - return 0.194915592891669 + 1.55227076330229*v - 3.93691860257828*v2 + 18.0679839248761*v3 - 101.468750302746*v4 + 632.341487393927*v5 - } else { - v1 := v - 0.015 - v2 := v1 * v1 - v3 := v2 * v1 - v4 := v2 * v2 - v5 := v3 * v2 - // You can clearly see from the involved constants that the low-end is highly nonlinear. - return 0.0519565234928877 + 5.09316778537561*v - 99.0338180489702*v2 + 3484.52322764895*v3 - 150028.083412663*v4 + 7168008.42971613*v5 - } -} - -// FastLinearRgb is much faster than and almost as accurate as LinearRgb. -// BUT it is important to NOTE that they only produce good results for valid inputs r,g,b in [0,1]. -func FastLinearRgb(r, g, b float64) Color { - return Color{delinearize_fast(r), delinearize_fast(g), delinearize_fast(b)} -} - -// XyzToLinearRgb converts from CIE XYZ-space to Linear RGB space. -func XyzToLinearRgb(x, y, z float64) (r, g, b float64) { - r = 3.2409699419045214*x - 1.5373831775700935*y - 0.49861076029300328*z - g = -0.96924363628087983*x + 1.8759675015077207*y + 0.041555057407175613*z - b = 0.055630079696993609*x - 0.20397695888897657*y + 1.0569715142428786*z - return -} - -func LinearRgbToXyz(r, g, b float64) (x, y, z float64) { - x = 0.41239079926595948*r + 0.35758433938387796*g + 0.18048078840183429*b - y = 0.21263900587151036*r + 0.71516867876775593*g + 0.072192315360733715*b - z = 0.019330818715591851*r + 0.11919477979462599*g + 0.95053215224966058*b - return -} - -/// XYZ /// -/////////// -// http://www.sjbrown.co.uk/2004/05/14/gamma-correct-rendering/ - -func (col Color) Xyz() (x, y, z float64) { - return LinearRgbToXyz(col.LinearRgb()) -} - -func Xyz(x, y, z float64) Color { - return LinearRgb(XyzToLinearRgb(x, y, z)) -} - -/// xyY /// -/////////// -// http://www.brucelindbloom.com/Eqn_XYZ_to_xyY.html - -// Well, the name is bad, since it's xyY but Golang needs me to start with a -// capital letter to make the method public. -func XyzToXyy(X, Y, Z float64) (x, y, Yout float64) { - return XyzToXyyWhiteRef(X, Y, Z, D65) -} - -func XyzToXyyWhiteRef(X, Y, Z float64, wref [3]float64) (x, y, Yout float64) { - Yout = Y - N := X + Y + Z - if math.Abs(N) < 1e-14 { - // When we have black, Bruce Lindbloom recommends to use - // the reference white's chromacity for x and y. - x = wref[0] / (wref[0] + wref[1] + wref[2]) - y = wref[1] / (wref[0] + wref[1] + wref[2]) - } else { - x = X / N - y = Y / N - } - return -} - -func XyyToXyz(x, y, Y float64) (X, Yout, Z float64) { - Yout = Y - - if -1e-14 < y && y < 1e-14 { - X = 0.0 - Z = 0.0 - } else { - X = Y / y * x - Z = Y / y * (1.0 - x - y) - } - - return -} - -// Converts the given color to CIE xyY space using D65 as reference white. -// (Note that the reference white is only used for black input.) -// x, y and Y are in [0..1] -func (col Color) Xyy() (x, y, Y float64) { - return XyzToXyy(col.Xyz()) -} - -// Converts the given color to CIE xyY space, taking into account -// a given reference white. (i.e. the monitor's white) -// (Note that the reference white is only used for black input.) -// x, y and Y are in [0..1] -func (col Color) XyyWhiteRef(wref [3]float64) (x, y, Y float64) { - X, Y2, Z := col.Xyz() - return XyzToXyyWhiteRef(X, Y2, Z, wref) -} - -// Generates a color by using data given in CIE xyY space. -// x, y and Y are in [0..1] -func Xyy(x, y, Y float64) Color { - return Xyz(XyyToXyz(x, y, Y)) -} - -/// L*a*b* /// -////////////// -// http://en.wikipedia.org/wiki/Lab_color_space#CIELAB-CIEXYZ_conversions -// For L*a*b*, we need to L*a*b*<->XYZ->RGB and the first one is device dependent. - -func lab_f(t float64) float64 { - if t > 6.0/29.0*6.0/29.0*6.0/29.0 { - return math.Cbrt(t) - } - return t/3.0*29.0/6.0*29.0/6.0 + 4.0/29.0 -} - -func XyzToLab(x, y, z float64) (l, a, b float64) { - // Use D65 white as reference point by default. - // http://www.fredmiranda.com/forum/topic/1035332 - // http://en.wikipedia.org/wiki/Standard_illuminant - return XyzToLabWhiteRef(x, y, z, D65) -} - -func XyzToLabWhiteRef(x, y, z float64, wref [3]float64) (l, a, b float64) { - fy := lab_f(y / wref[1]) - l = 1.16*fy - 0.16 - a = 5.0 * (lab_f(x/wref[0]) - fy) - b = 2.0 * (fy - lab_f(z/wref[2])) - return -} - -func lab_finv(t float64) float64 { - if t > 6.0/29.0 { - return t * t * t - } - return 3.0 * 6.0 / 29.0 * 6.0 / 29.0 * (t - 4.0/29.0) -} - -func LabToXyz(l, a, b float64) (x, y, z float64) { - // D65 white (see above). - return LabToXyzWhiteRef(l, a, b, D65) -} - -func LabToXyzWhiteRef(l, a, b float64, wref [3]float64) (x, y, z float64) { - l2 := (l + 0.16) / 1.16 - x = wref[0] * lab_finv(l2+a/5.0) - y = wref[1] * lab_finv(l2) - z = wref[2] * lab_finv(l2-b/2.0) - return -} - -// Converts the given color to CIE L*a*b* space using D65 as reference white. -func (col Color) Lab() (l, a, b float64) { - return XyzToLab(col.Xyz()) -} - -// Converts the given color to CIE L*a*b* space, taking into account -// a given reference white. (i.e. the monitor's white) -func (col Color) LabWhiteRef(wref [3]float64) (l, a, b float64) { - x, y, z := col.Xyz() - return XyzToLabWhiteRef(x, y, z, wref) -} - -// Generates a color by using data given in CIE L*a*b* space using D65 as reference white. -// WARNING: many combinations of `l`, `a`, and `b` values do not have corresponding -// valid RGB values, check the FAQ in the README if you're unsure. -func Lab(l, a, b float64) Color { - return Xyz(LabToXyz(l, a, b)) -} - -// Generates a color by using data given in CIE L*a*b* space, taking -// into account a given reference white. (i.e. the monitor's white) -func LabWhiteRef(l, a, b float64, wref [3]float64) Color { - return Xyz(LabToXyzWhiteRef(l, a, b, wref)) -} - -// DistanceLab is a good measure of visual similarity between two colors! -// A result of 0 would mean identical colors, while a result of 1 or higher -// means the colors differ a lot. -func (c1 Color) DistanceLab(c2 Color) float64 { - l1, a1, b1 := c1.Lab() - l2, a2, b2 := c2.Lab() - return math.Sqrt(sq(l1-l2) + sq(a1-a2) + sq(b1-b2)) -} - -// DistanceCIE76 is the same as DistanceLab. -func (c1 Color) DistanceCIE76(c2 Color) float64 { - return c1.DistanceLab(c2) -} - -// Uses the CIE94 formula to calculate color distance. More accurate than -// DistanceLab, but also more work. -func (cl Color) DistanceCIE94(cr Color) float64 { - l1, a1, b1 := cl.Lab() - l2, a2, b2 := cr.Lab() - - // NOTE: Since all those formulas expect L,a,b values 100x larger than we - // have them in this library, we either need to adjust all constants - // in the formula, or convert the ranges of L,a,b before, and then - // scale the distances down again. The latter is less error-prone. - l1, a1, b1 = l1*100.0, a1*100.0, b1*100.0 - l2, a2, b2 = l2*100.0, a2*100.0, b2*100.0 - - kl := 1.0 // 2.0 for textiles - kc := 1.0 - kh := 1.0 - k1 := 0.045 // 0.048 for textiles - k2 := 0.015 // 0.014 for textiles. - - deltaL := l1 - l2 - c1 := math.Sqrt(sq(a1) + sq(b1)) - c2 := math.Sqrt(sq(a2) + sq(b2)) - deltaCab := c1 - c2 - - // Not taking Sqrt here for stability, and it's unnecessary. - deltaHab2 := sq(a1-a2) + sq(b1-b2) - sq(deltaCab) - sl := 1.0 - sc := 1.0 + k1*c1 - sh := 1.0 + k2*c1 - - vL2 := sq(deltaL / (kl * sl)) - vC2 := sq(deltaCab / (kc * sc)) - vH2 := deltaHab2 / sq(kh*sh) - - return math.Sqrt(vL2+vC2+vH2) * 0.01 // See above. -} - -// DistanceCIEDE2000 uses the Delta E 2000 formula to calculate color -// distance. It is more expensive but more accurate than both DistanceLab -// and DistanceCIE94. -func (cl Color) DistanceCIEDE2000(cr Color) float64 { - return cl.DistanceCIEDE2000klch(cr, 1.0, 1.0, 1.0) -} - -// DistanceCIEDE2000klch uses the Delta E 2000 formula with custom values -// for the weighting factors kL, kC, and kH. -func (cl Color) DistanceCIEDE2000klch(cr Color, kl, kc, kh float64) float64 { - l1, a1, b1 := cl.Lab() - l2, a2, b2 := cr.Lab() - - // As with CIE94, we scale up the ranges of L,a,b beforehand and scale - // them down again afterwards. - l1, a1, b1 = l1*100.0, a1*100.0, b1*100.0 - l2, a2, b2 = l2*100.0, a2*100.0, b2*100.0 - - cab1 := math.Sqrt(sq(a1) + sq(b1)) - cab2 := math.Sqrt(sq(a2) + sq(b2)) - cabmean := (cab1 + cab2) / 2 - - g := 0.5 * (1 - math.Sqrt(math.Pow(cabmean, 7)/(math.Pow(cabmean, 7)+math.Pow(25, 7)))) - ap1 := (1 + g) * a1 - ap2 := (1 + g) * a2 - cp1 := math.Sqrt(sq(ap1) + sq(b1)) - cp2 := math.Sqrt(sq(ap2) + sq(b2)) - - hp1 := 0.0 - if b1 != ap1 || ap1 != 0 { - hp1 = math.Atan2(b1, ap1) - if hp1 < 0 { - hp1 += math.Pi * 2 - } - hp1 *= 180 / math.Pi - } - hp2 := 0.0 - if b2 != ap2 || ap2 != 0 { - hp2 = math.Atan2(b2, ap2) - if hp2 < 0 { - hp2 += math.Pi * 2 - } - hp2 *= 180 / math.Pi - } - - deltaLp := l2 - l1 - deltaCp := cp2 - cp1 - dhp := 0.0 - cpProduct := cp1 * cp2 - if cpProduct != 0 { - dhp = hp2 - hp1 - if dhp > 180 { - dhp -= 360 - } else if dhp < -180 { - dhp += 360 - } - } - deltaHp := 2 * math.Sqrt(cpProduct) * math.Sin(dhp/2*math.Pi/180) - - lpmean := (l1 + l2) / 2 - cpmean := (cp1 + cp2) / 2 - hpmean := hp1 + hp2 - if cpProduct != 0 { - hpmean /= 2 - if math.Abs(hp1-hp2) > 180 { - if hp1+hp2 < 360 { - hpmean += 180 - } else { - hpmean -= 180 - } - } - } - - t := 1 - 0.17*math.Cos((hpmean-30)*math.Pi/180) + 0.24*math.Cos(2*hpmean*math.Pi/180) + 0.32*math.Cos((3*hpmean+6)*math.Pi/180) - 0.2*math.Cos((4*hpmean-63)*math.Pi/180) - deltaTheta := 30 * math.Exp(-sq((hpmean-275)/25)) - rc := 2 * math.Sqrt(math.Pow(cpmean, 7)/(math.Pow(cpmean, 7)+math.Pow(25, 7))) - sl := 1 + (0.015*sq(lpmean-50))/math.Sqrt(20+sq(lpmean-50)) - sc := 1 + 0.045*cpmean - sh := 1 + 0.015*cpmean*t - rt := -math.Sin(2*deltaTheta*math.Pi/180) * rc - - return math.Sqrt(sq(deltaLp/(kl*sl))+sq(deltaCp/(kc*sc))+sq(deltaHp/(kh*sh))+rt*(deltaCp/(kc*sc))*(deltaHp/(kh*sh))) * 0.01 -} - -// BlendLab blends two colors in the L*a*b* color-space, which should result in a smoother blend. -// t == 0 results in c1, t == 1 results in c2 -func (c1 Color) BlendLab(c2 Color, t float64) Color { - l1, a1, b1 := c1.Lab() - l2, a2, b2 := c2.Lab() - return Lab(l1+t*(l2-l1), - a1+t*(a2-a1), - b1+t*(b2-b1)) -} - -/// L*u*v* /// -////////////// -// http://en.wikipedia.org/wiki/CIELUV#XYZ_.E2.86.92_CIELUV_and_CIELUV_.E2.86.92_XYZ_conversions -// For L*u*v*, we need to L*u*v*<->XYZ<->RGB and the first one is device dependent. - -func XyzToLuv(x, y, z float64) (l, a, b float64) { - // Use D65 white as reference point by default. - // http://www.fredmiranda.com/forum/topic/1035332 - // http://en.wikipedia.org/wiki/Standard_illuminant - return XyzToLuvWhiteRef(x, y, z, D65) -} - -func XyzToLuvWhiteRef(x, y, z float64, wref [3]float64) (l, u, v float64) { - if y/wref[1] <= 6.0/29.0*6.0/29.0*6.0/29.0 { - l = y / wref[1] * (29.0 / 3.0 * 29.0 / 3.0 * 29.0 / 3.0) / 100.0 - } else { - l = 1.16*math.Cbrt(y/wref[1]) - 0.16 - } - ubis, vbis := xyz_to_uv(x, y, z) - un, vn := xyz_to_uv(wref[0], wref[1], wref[2]) - u = 13.0 * l * (ubis - un) - v = 13.0 * l * (vbis - vn) - return -} - -// For this part, we do as R's graphics.hcl does, not as wikipedia does. -// Or is it the same? -func xyz_to_uv(x, y, z float64) (u, v float64) { - denom := x + 15.0*y + 3.0*z - if denom == 0.0 { - u, v = 0.0, 0.0 - } else { - u = 4.0 * x / denom - v = 9.0 * y / denom - } - return -} - -func LuvToXyz(l, u, v float64) (x, y, z float64) { - // D65 white (see above). - return LuvToXyzWhiteRef(l, u, v, D65) -} - -func LuvToXyzWhiteRef(l, u, v float64, wref [3]float64) (x, y, z float64) { - //y = wref[1] * lab_finv((l + 0.16) / 1.16) - if l <= 0.08 { - y = wref[1] * l * 100.0 * 3.0 / 29.0 * 3.0 / 29.0 * 3.0 / 29.0 - } else { - y = wref[1] * cub((l+0.16)/1.16) - } - un, vn := xyz_to_uv(wref[0], wref[1], wref[2]) - if l != 0.0 { - ubis := u/(13.0*l) + un - vbis := v/(13.0*l) + vn - x = y * 9.0 * ubis / (4.0 * vbis) - z = y * (12.0 - 3.0*ubis - 20.0*vbis) / (4.0 * vbis) - } else { - x, y = 0.0, 0.0 - } - return -} - -// Converts the given color to CIE L*u*v* space using D65 as reference white. -// L* is in [0..1] and both u* and v* are in about [-1..1] -func (col Color) Luv() (l, u, v float64) { - return XyzToLuv(col.Xyz()) -} - -// Converts the given color to CIE L*u*v* space, taking into account -// a given reference white. (i.e. the monitor's white) -// L* is in [0..1] and both u* and v* are in about [-1..1] -func (col Color) LuvWhiteRef(wref [3]float64) (l, u, v float64) { - x, y, z := col.Xyz() - return XyzToLuvWhiteRef(x, y, z, wref) -} - -// Generates a color by using data given in CIE L*u*v* space using D65 as reference white. -// L* is in [0..1] and both u* and v* are in about [-1..1] -// WARNING: many combinations of `l`, `u`, and `v` values do not have corresponding -// valid RGB values, check the FAQ in the README if you're unsure. -func Luv(l, u, v float64) Color { - return Xyz(LuvToXyz(l, u, v)) -} - -// Generates a color by using data given in CIE L*u*v* space, taking -// into account a given reference white. (i.e. the monitor's white) -// L* is in [0..1] and both u* and v* are in about [-1..1] -func LuvWhiteRef(l, u, v float64, wref [3]float64) Color { - return Xyz(LuvToXyzWhiteRef(l, u, v, wref)) -} - -// DistanceLuv is a good measure of visual similarity between two colors! -// A result of 0 would mean identical colors, while a result of 1 or higher -// means the colors differ a lot. -func (c1 Color) DistanceLuv(c2 Color) float64 { - l1, u1, v1 := c1.Luv() - l2, u2, v2 := c2.Luv() - return math.Sqrt(sq(l1-l2) + sq(u1-u2) + sq(v1-v2)) -} - -// BlendLuv blends two colors in the CIE-L*u*v* color-space, which should result in a smoother blend. -// t == 0 results in c1, t == 1 results in c2 -func (c1 Color) BlendLuv(c2 Color, t float64) Color { - l1, u1, v1 := c1.Luv() - l2, u2, v2 := c2.Luv() - return Luv(l1+t*(l2-l1), - u1+t*(u2-u1), - v1+t*(v2-v1)) -} - -/// HCL /// -/////////// -// HCL is nothing else than L*a*b* in cylindrical coordinates! -// (this was wrong on English wikipedia, I fixed it, let's hope the fix stays.) -// But it is widely popular since it is a "correct HSV" -// http://www.hunterlab.com/appnotes/an09_96a.pdf - -// Converts the given color to HCL space using D65 as reference white. -// H values are in [0..360], C and L values are in [0..1] although C can overshoot 1.0 -func (col Color) Hcl() (h, c, l float64) { - return col.HclWhiteRef(D65) -} - -func LabToHcl(L, a, b float64) (h, c, l float64) { - // Oops, floating point workaround necessary if a ~= b and both are very small (i.e. almost zero). - if math.Abs(b-a) > 1e-4 && math.Abs(a) > 1e-4 { - h = math.Mod(57.29577951308232087721*math.Atan2(b, a)+360.0, 360.0) // Rad2Deg - } else { - h = 0.0 - } - c = math.Sqrt(sq(a) + sq(b)) - l = L - return -} - -// Converts the given color to HCL space, taking into account -// a given reference white. (i.e. the monitor's white) -// H values are in [0..360], C and L values are in [0..1] -func (col Color) HclWhiteRef(wref [3]float64) (h, c, l float64) { - L, a, b := col.LabWhiteRef(wref) - return LabToHcl(L, a, b) -} - -// Generates a color by using data given in HCL space using D65 as reference white. -// H values are in [0..360], C and L values are in [0..1] -// WARNING: many combinations of `h`, `c`, and `l` values do not have corresponding -// valid RGB values, check the FAQ in the README if you're unsure. -func Hcl(h, c, l float64) Color { - return HclWhiteRef(h, c, l, D65) -} - -func HclToLab(h, c, l float64) (L, a, b float64) { - H := 0.01745329251994329576 * h // Deg2Rad - a = c * math.Cos(H) - b = c * math.Sin(H) - L = l - return -} - -// Generates a color by using data given in HCL space, taking -// into account a given reference white. (i.e. the monitor's white) -// H values are in [0..360], C and L values are in [0..1] -func HclWhiteRef(h, c, l float64, wref [3]float64) Color { - L, a, b := HclToLab(h, c, l) - return LabWhiteRef(L, a, b, wref) -} - -// BlendHcl blends two colors in the CIE-L*C*h° color-space, which should result in a smoother blend. -// t == 0 results in c1, t == 1 results in c2 -func (col1 Color) BlendHcl(col2 Color, t float64) Color { - h1, c1, l1 := col1.Hcl() - h2, c2, l2 := col2.Hcl() - - // We know that h are both in [0..360] - return Hcl(interp_angle(h1, h2, t), c1+t*(c2-c1), l1+t*(l2-l1)).Clamped() -} - -// LuvLch - -// Converts the given color to LuvLCh space using D65 as reference white. -// h values are in [0..360], C and L values are in [0..1] although C can overshoot 1.0 -func (col Color) LuvLCh() (l, c, h float64) { - return col.LuvLChWhiteRef(D65) -} - -func LuvToLuvLCh(L, u, v float64) (l, c, h float64) { - // Oops, floating point workaround necessary if u ~= v and both are very small (i.e. almost zero). - if math.Abs(v-u) > 1e-4 && math.Abs(u) > 1e-4 { - h = math.Mod(57.29577951308232087721*math.Atan2(v, u)+360.0, 360.0) // Rad2Deg - } else { - h = 0.0 - } - l = L - c = math.Sqrt(sq(u) + sq(v)) - return -} - -// Converts the given color to LuvLCh space, taking into account -// a given reference white. (i.e. the monitor's white) -// h values are in [0..360], c and l values are in [0..1] -func (col Color) LuvLChWhiteRef(wref [3]float64) (l, c, h float64) { - return LuvToLuvLCh(col.LuvWhiteRef(wref)) -} - -// Generates a color by using data given in LuvLCh space using D65 as reference white. -// h values are in [0..360], C and L values are in [0..1] -// WARNING: many combinations of `l`, `c`, and `h` values do not have corresponding -// valid RGB values, check the FAQ in the README if you're unsure. -func LuvLCh(l, c, h float64) Color { - return LuvLChWhiteRef(l, c, h, D65) -} - -func LuvLChToLuv(l, c, h float64) (L, u, v float64) { - H := 0.01745329251994329576 * h // Deg2Rad - u = c * math.Cos(H) - v = c * math.Sin(H) - L = l - return -} - -// Generates a color by using data given in LuvLCh space, taking -// into account a given reference white. (i.e. the monitor's white) -// h values are in [0..360], C and L values are in [0..1] -func LuvLChWhiteRef(l, c, h float64, wref [3]float64) Color { - L, u, v := LuvLChToLuv(l, c, h) - return LuvWhiteRef(L, u, v, wref) -} - -// BlendLuvLCh blends two colors in the cylindrical CIELUV color space. -// t == 0 results in c1, t == 1 results in c2 -func (col1 Color) BlendLuvLCh(col2 Color, t float64) Color { - l1, c1, h1 := col1.LuvLCh() - l2, c2, h2 := col2.LuvLCh() - - // We know that h are both in [0..360] - return LuvLCh(l1+t*(l2-l1), c1+t*(c2-c1), interp_angle(h1, h2, t)) -} diff --git a/vendor/github.com/lucasb-eyer/go-colorful/happy_palettegen.go b/vendor/github.com/lucasb-eyer/go-colorful/happy_palettegen.go deleted file mode 100644 index bb66dfa4f9..0000000000 --- a/vendor/github.com/lucasb-eyer/go-colorful/happy_palettegen.go +++ /dev/null @@ -1,25 +0,0 @@ -package colorful - -import ( - "math/rand" -) - -// Uses the HSV color space to generate colors with similar S,V but distributed -// evenly along their Hue. This is fast but not always pretty. -// If you've got time to spare, use Lab (the non-fast below). -func FastHappyPalette(colorsCount int) (colors []Color) { - colors = make([]Color, colorsCount) - - for i := 0; i < colorsCount; i++ { - colors[i] = Hsv(float64(i)*(360.0/float64(colorsCount)), 0.8+rand.Float64()*0.2, 0.65+rand.Float64()*0.2) - } - return -} - -func HappyPalette(colorsCount int) ([]Color, error) { - pimpy := func(l, a, b float64) bool { - _, c, _ := LabToHcl(l, a, b) - return 0.3 <= c && 0.4 <= l && l <= 0.8 - } - return SoftPaletteEx(colorsCount, SoftPaletteSettings{pimpy, 50, true}) -} diff --git a/vendor/github.com/lucasb-eyer/go-colorful/hexcolor.go b/vendor/github.com/lucasb-eyer/go-colorful/hexcolor.go deleted file mode 100644 index 76f31d8f9f..0000000000 --- a/vendor/github.com/lucasb-eyer/go-colorful/hexcolor.go +++ /dev/null @@ -1,67 +0,0 @@ -package colorful - -import ( - "database/sql/driver" - "encoding/json" - "fmt" - "reflect" -) - -// A HexColor is a Color stored as a hex string "#rrggbb". It implements the -// database/sql.Scanner, database/sql/driver.Value, -// encoding/json.Unmarshaler and encoding/json.Marshaler interfaces. -type HexColor Color - -type errUnsupportedType struct { - got interface{} - want reflect.Type -} - -func (hc *HexColor) Scan(value interface{}) error { - s, ok := value.(string) - if !ok { - return errUnsupportedType{got: reflect.TypeOf(value), want: reflect.TypeOf("")} - } - c, err := Hex(s) - if err != nil { - return err - } - *hc = HexColor(c) - return nil -} - -func (hc *HexColor) Value() (driver.Value, error) { - return Color(*hc).Hex(), nil -} - -func (e errUnsupportedType) Error() string { - return fmt.Sprintf("unsupported type: got %v, want a %s", e.got, e.want) -} - -func (hc *HexColor) UnmarshalJSON(data []byte) error { - var hexCode string - if err := json.Unmarshal(data, &hexCode); err != nil { - return err - } - - var col, err = Hex(hexCode) - if err != nil { - return err - } - *hc = HexColor(col) - return nil -} - -func (hc HexColor) MarshalJSON() ([]byte, error) { - return json.Marshal(Color(hc).Hex()) -} - -// Decode - deserialize function for https://github.com/kelseyhightower/envconfig -func (hc *HexColor) Decode(hexCode string) error { - var col, err = Hex(hexCode) - if err != nil { - return err - } - *hc = HexColor(col) - return nil -} diff --git a/vendor/github.com/lucasb-eyer/go-colorful/hsluv-snapshot-rev4.json b/vendor/github.com/lucasb-eyer/go-colorful/hsluv-snapshot-rev4.json deleted file mode 100644 index 16354abf51..0000000000 --- a/vendor/github.com/lucasb-eyer/go-colorful/hsluv-snapshot-rev4.json +++ /dev/null @@ -1 +0,0 @@ -{"#11ee00":{"lch":[82.5213119008325577,127.202882727266427,127.478988192005161],"luv":[82.5213119008325577,-77.3991947082883627,100.945222931227221],"rgb":[0.0666666666666666657,0.933333333333333348,0],"xyz":[0.308043578886299796,0.612655858810891907,0.102019012460713238],"hpluv":[127.478988192005161,308.195222762673438,82.5213119008325577],"hsluv":[127.478988192005161,100.000000000002416,82.5213119008325577]},"#11ee11":{"lch":[82.5429986110943759,126.352581314528209,127.715012949240403],"luv":[82.5429986110943759,-77.2942129186682,99.9528861720763473],"rgb":[0.0666666666666666657,0.933333333333333348,0.0666666666666666657],"xyz":[0.3090552443859369,0.613060525010746815,0.107347117425468874],"hpluv":[127.715012949240403,306.573296560288782,82.5429986110943759],"hsluv":[127.715012949240403,98.9038130800949205,82.5429986110943759]},"#11ee22":{"lch":[82.5831747617793184,124.791738379333623,128.158354445562821],"luv":[82.5831747617793184,-77.1009570540098,98.1245147202868253],"rgb":[0.0666666666666666657,0.933333333333333348,0.133333333333333331],"xyz":[0.310930602524413957,0.613810668266137616,0.117224003621448067],"hpluv":[128.158354445562821,303.59085997924285,82.5831747617793184],"hsluv":[128.158354445562821,98.9085620232469864,82.5831747617793184]},"#11ee33":{"lch":[82.6492529720821381,122.265269823008623,128.905098358231896],"luv":[82.6492529720821381,-76.7865393115689301,95.1452762119380537],"rgb":[0.0666666666666666657,0.933333333333333348,0.2],"xyz":[0.314018353256871663,0.615045768559120742,0.133486157479059203],"hpluv":[128.905098358231896,298.749143147736106,82.6492529720821381],"hsluv":[128.905098358231896,98.916292078887,82.6492529720821381]},"#11ee44":{"lch":[82.7444986901015511,118.712635154498344,130.021230388522838],"luv":[82.7444986901015511,-76.3407023620842,90.9108734321077],"rgb":[0.0666666666666666657,0.933333333333333348,0.266666666666666663],"xyz":[0.318476348501090578,0.616828966656808308,0.156964932431945842],"hpluv":[130.021230388522838,291.911386756693616,82.7444986901015511],"hsluv":[130.021230388522838,98.9272612770947148,82.7444986901015511]},"#11ee55":{"lch":[82.8716000285422894,114.135934527262179,131.587310643629934],"luv":[82.8716000285422894,-75.758934185545,85.3674144008224],"rgb":[0.0666666666666666657,0.933333333333333348,0.333333333333333315],"xyz":[0.324438762540452563,0.619213932272553058,0.188366979705919757],"hpluv":[131.587310643629934,283.052591495130912,82.8716000285422894],"hsluv":[131.587310643629934,98.941589727101146,82.8716000285422894]},"#11ee66":{"lch":[83.0328193013522622,108.602333046050703,133.707640253052432],"luv":[83.0328193013522622,-75.0419109433949103,78.5059128028513697],"rgb":[0.0666666666666666657,0.933333333333333348,0.4],"xyz":[0.332023758313960748,0.622247930581956377,0.228314624113063719],"hpluv":[133.707640253052432,272.269449526145593,83.0328193013522622],"hsluv":[133.707640253052432,98.9592735060659,83.0328193013522622]},"#11ee77":{"lch":[83.2300736177455747,102.250357200027821,136.520544097163679],"luv":[83.2300736177455747,-74.1950209885278866,70.3579022430685228],"rgb":[0.0666666666666666657,0.933333333333333348,0.466666666666666674],"xyz":[0.341337771334162654,0.625973535790037228,0.277368426019461656],"hpluv":[136.520544097163679,259.803949175129901,83.2300736177455747],"hsluv":[136.520544097163679,98.9801962733070155,83.2300736177455747]},"#11ee88":{"lch":[83.4649827070576151,95.3003261118453651,140.209511574476238],"luv":[83.4649827070576151,-73.2277962837693082,60.990507527375577],"rgb":[0.0666666666666666657,0.933333333333333348,0.533333333333333326],"xyz":[0.352478188436106454,0.63042970263081477,0.336041289423033795],"hpluv":[140.209511574476238,246.084644167270028,83.4649827070576151],"hsluv":[140.209511574476238,99.0041428894333109,83.4649827070576151]},"#11ee99":{"lch":[83.7388997377875626,88.07037792773761,145.011549795441141],"luv":[83.7388997377875626,-72.1532115864445416,50.5005497603372433],"rgb":[0.0666666666666666657,0.933333333333333348,0.6],"xyz":[0.365535152545179209,0.635652488274444,0.404807967064151675],"hpluv":[145.011549795441141,231.793725377578141,83.7388997377875626],"hsluv":[145.011549795441141,99.0308160530368582,83.7388997377875626]},"#11eeaa":{"lch":[84.0529327571252907,80.9984265129003802,151.210882439188083],"luv":[84.0529327571252907,-70.9868724309634729,39.0078074241021824],"rgb":[0.0666666666666666657,0.933333333333333348,0.66666666666666663],"xyz":[0.38059284551043171,0.641675565460545,0.484111816681150331],"hpluv":[151.210882439188083,217.967504021816438,84.0529327571252907],"hsluv":[151.210882439188083,99.0598554997167895,84.0529327571252907]},"#11eebb":{"lch":[84.4079608499599914,74.6634505604909435,159.089705667287262],"luv":[84.4079608499599914,-69.7461428935043273,26.6478216947980826],"rgb":[0.0666666666666666657,0.933333333333333348,0.733333333333333282],"xyz":[0.397730437617768384,0.648530602303479808,0.574369801779792],"hpluv":[159.089705667287262,206.122134265545043,84.4079608499599914],"hsluv":[159.089705667287262,99.0908585861444209,84.4079608499599914]},"#11eecc":{"lch":[84.8046473826435,69.7804076798411,168.790807110150524],"luv":[84.8046473826435,-68.449275126866155,13.5647348138992196],"rgb":[0.0666666666666666657,0.933333333333333348,0.8],"xyz":[0.417022813061490139,0.656247552480968666,0.675976312450062178],"hpluv":[168.790807110150524,198.342538571842852,84.8046473826435],"hsluv":[168.790807110150524,99.123400814408285,84.8046473826435]},"#11eedd":{"lch":[85.2434517572140749,67.1146678094459,180.081412911690762],"luv":[85.2434517572140749,-67.114600056421537,-0.0953647673755886743],"rgb":[0.0666666666666666657,0.933333333333333348,0.866666666666666696],"xyz":[0.438541138612123627,0.664854882701222172,0.789306160350068176],"hpluv":[180.081412911690762,197.173954094180345,85.2434517572140749],"hsluv":[180.081412911690762,99.1570549081779546,85.2434517572140749]},"#11eeee":{"lch":[85.7246405502341275,67.2734484234975,192.17705063006116],"luv":[85.7246405502341275,-65.759826803247222,-14.1902093570146306],"rgb":[0.0666666666666666657,0.933333333333333348,0.933333333333333348],"xyz":[0.462353318878298392,0.674379754807692189,0.914716976418591399],"hpluv":[192.17705063006116,205.138082793863816,85.7246405502341275],"hsluv":[192.17705063006116,99.1914073274009098,85.7246405502341275]},"#11eeff":{"lch":[86.2482985645723517,70.4606934075819282,203.935071880927921],"luv":[86.2482985645723517,-64.401481656171029,-28.585983907627277],"rgb":[0.0666666666666666657,0.933333333333333348,1],"xyz":[0.488524367288129757,0.684848174171624913,1.05255116471037335],"hpluv":[203.935071880927921,224.026806300523,86.2482985645723517],"hsluv":[203.935071880927921,99.9999999999942304,86.2482985645723517]},"#11ff00":{"lch":[87.7931168603164,135.408535196841626,127.513270797457935],"luv":[87.7931168603164,-82.4563732780469,107.407718111808407],"rgb":[0.0666666666666666657,1,0],"xyz":[0.359895951315973628,0.716360603670241,0.119303136603937349],"hpluv":[127.513270797457935,491.310985978769054,87.7931168603164],"hsluv":[127.513270797457935,100.000000000002373,87.7931168603164]},"#11ff11":{"lch":[87.8126571401035108,134.634318462908169,127.715012949240432],"luv":[87.8126571401035108,-82.3604359259359313,106.50426424355777],"rgb":[0.0666666666666666657,1,0.0666666666666666657],"xyz":[0.360907616815610732,0.716765269870095922,0.124631241568692985],"hpluv":[127.715012949240432,489.364334505449051,87.8126571401035108],"hsluv":[127.715012949240432,99.999999999991914,87.8126571401035108]},"#11ff22":{"lch":[87.848860165327963,133.211117719966126,128.093229681784152],"luv":[87.848860165327963,-82.1836510367646,104.838205757586152],"rgb":[0.0666666666666666657,1,0.133333333333333331],"xyz":[0.362782974954087789,0.717515413125486723,0.134508127764672164],"hpluv":[128.093229681784152,485.7796458877379,87.848860165327963],"hsluv":[128.093229681784152,99.9999999999918572,87.848860165327963]},"#11ff33":{"lch":[87.9084130007832698,130.901693692038833,128.728166832562891],"luv":[87.9084130007832698,-81.8955348861488659,102.119414300885666],"rgb":[0.0666666666666666657,1,0.2],"xyz":[0.365870725686545495,0.71875051341846985,0.150770281622283314],"hpluv":[128.728166832562891,479.945632467831388,87.9084130007832698],"hsluv":[128.728166832562891,99.9999999999919567,87.9084130007832698]},"#11ff44":{"lch":[87.9942732352876,127.641489512823171,129.672386074694657],"luv":[87.9942732352876,-81.4859348177847806,98.2465891108891185],"rgb":[0.0666666666666666657,1,0.266666666666666663],"xyz":[0.37032872093076441,0.720533711516157416,0.174249056575169953],"hpluv":[129.672386074694657,471.674193406224788,87.9942732352876],"hsluv":[129.672386074694657,99.9999999999918856,87.9942732352876]},"#11ff55":{"lch":[88.1088871723243727,123.41738800901625,130.987994113812931],"luv":[88.1088871723243727,-80.9495722978130772,93.1612494966077662],"rgb":[0.0666666666666666657,1,0.333333333333333315],"xyz":[0.376291134970126395,0.722918677131902165,0.205651103849143868],"hpluv":[130.987994113812931,460.897243009671797,88.1088871723243727],"hsluv":[130.987994113812931,99.9999999999917,88.1088871723243727]},"#11ff66":{"lch":[88.2543278429396,118.268592142924746,132.753132104158254],"luv":[88.2543278429396,-80.2855559529031382,86.8429006471038],"rgb":[0.0666666666666666657,1,0.4],"xyz":[0.38387613074363458,0.725952675441305484,0.24559874825628783],"hpluv":[132.753132104158254,447.675525940365219,88.2543278429396],"hsluv":[132.753132104158254,99.9999999999916724,88.2543278429396]},"#11ff77":{"lch":[88.4323687925046613,112.290518027227137,135.069051083024959],"luv":[88.4323687925046613,-79.4970211443964558,79.3056370505300521],"rgb":[0.0666666666666666657,1,0.466666666666666674],"xyz":[0.393190143763836486,0.729678280649386335,0.294652550162685767],"hpluv":[135.069051083024959,432.222948715922314,88.4323687925046613],"hsluv":[135.069051083024959,99.999999999991644,88.4323687925046613]},"#11ff88":{"lch":[88.6445280109338825,105.641380676940045,138.068036362648229],"luv":[88.6445280109338825,-78.5907289650887577,70.5946076698930369],"rgb":[0.0666666666666666657,1,0.533333333333333326],"xyz":[0.404330560865780286,0.734134447490163877,0.353325413566257907],"hpluv":[138.068036362648229,414.95023459347243,88.6445280109338825],"hsluv":[138.068036362648229,99.9999999999915,88.6445280109338825]},"#11ff99":{"lch":[88.8920961876840465,98.552301258979881,141.921030988541872],"luv":[88.8920961876840465,-77.5765731609304225,60.7818342932124338],"rgb":[0.0666666666666666657,1,0.6],"xyz":[0.417387524974853,0.73935723313379309,0.422092091207375786],"hpluv":[141.921030988541872,396.537381185702543,88.8920961876840465],"hsluv":[141.921030988541872,99.9999999999913456,88.8920961876840465]},"#11ffaa":{"lch":[89.1761561490339147,91.3418654410923523,146.840553381528281],"luv":[89.1761561490339147,-76.4669946123218,49.9613362233014158],"rgb":[0.0666666666666666657,1,0.66666666666666663],"xyz":[0.432445217940105542,0.745380310319894157,0.501395940824374442],"hpluv":[146.840553381528281,378.048392077141443,89.1761561490339147],"hsluv":[146.840553381528281,99.9999999999913,89.1761561490339147]},"#11ffbb":{"lch":[89.4975971674113,84.4340589142561413,153.067388238784645],"luv":[89.4975971674113,-75.2763296710648859,38.2437510711127],"rgb":[0.0666666666666666657,1,0.733333333333333282],"xyz":[0.449582810047442216,0.752235347162828916,0.591653925923016133],"hpluv":[153.067388238784645,361.099415032935838,89.4975971674113],"hsluv":[153.067388238784645,99.9999999999909335,89.4975971674113]},"#11ffcc":{"lch":[89.8571262823018628,78.3714319324892159,160.817799258328876],"luv":[89.8571262823018628,-74.0201316086282901,25.7507564896672143],"rgb":[0.0666666666666666657,1,0.8],"xyz":[0.468875185491163915,0.759952297340317773,0.693260436593286289],"hpluv":[160.817799258328876,348.067615225706845,89.8571262823018628],"hsluv":[160.817799258328876,99.999999999991,89.8571262823018628]},"#11ffdd":{"lch":[90.2552779380141317,73.7997451229305,170.162013498752287],"luv":[90.2552779380141317,-72.7145076797264238,12.6096293801408788],"rgb":[0.0666666666666666657,1,0.866666666666666696],"xyz":[0.490393511041797514,0.768559627560571279,0.806590284493292287],"hpluv":[170.162013498752287,342.256686666565315,90.2552779380141317],"hsluv":[170.162013498752287,99.999999999990834,90.2552779380141317]},"#11ffee":{"lch":[90.6924227584195819,71.3832589696730793,180.844217403257659],"luv":[90.6924227584195819,-71.3755103944163665,-1.05174952720347981],"rgb":[0.0666666666666666657,1,0.933333333333333348],"xyz":[0.514205691307972224,0.778084499667041296,0.93200110056181551],"hpluv":[180.844217403257659,347.82122947809512,90.6924227584195819],"hsluv":[180.844217403257659,99.9999999999901803,90.6924227584195819]},"#11ffff":{"lch":[91.1687759776689859,71.6302608322469467,192.17705063006116],"luv":[91.1687759776689859,-70.0186129384549361,-15.1092061032524665],"rgb":[0.0666666666666666657,1,1],"xyz":[0.540376739717803645,0.788552919030974,1.06983528885359735],"hpluv":[192.17705063006116,369.258709956275879,91.1687759776689859],"hsluv":[192.17705063006116,99.9999999999898108,91.1687759776689859]},"#00aa00":{"lch":[60.5587499434736287,93.727653253516209,127.71501294924046],"luv":[60.5587499434736287,-57.3364240886418415,74.1445038903004559],"rgb":[0,0.66666666666666663,0],"xyz":[0.143740958848290495,0.287481917696585,0.0479136529494288144],"hpluv":[127.71501294924046,196.394882900214554,60.5587499434736287],"hsluv":[127.71501294924046,100.000000000002359,60.5587499434736287]},"#00aa11":{"lch":[60.5946550577951939,92.4075267438518182,128.220974416403209],"luv":[60.5946550577951939,-57.1721703645967665,72.5981675713458543],"rgb":[0,0.66666666666666663,0.0666666666666666657],"xyz":[0.144752624347927628,0.28788658389643984,0.0532417579141844441],"hpluv":[128.220974416403209,193.513984665985475,60.5946550577951939],"hsluv":[128.220974416403209,99.9999999999907772,60.5946550577951939]},"#00aa22":{"lch":[60.661124672570665,90.0113827545795715,129.185497299711983],"luv":[60.661124672570665,-56.8721735728637725,69.7682226983709199],"rgb":[0,0.66666666666666663,0.133333333333333331],"xyz":[0.146627982486404629,0.288636727151830641,0.0631186441101636436],"hpluv":[129.185497299711983,188.289586599726533,60.661124672570665],"hsluv":[129.185497299711983,99.9999999999908624,60.661124672570665]},"#00aa33":{"lch":[60.7703154938824355,86.2098857925288513,130.852037745481823],"luv":[60.7703154938824355,-56.3905639077229353,65.2092685937350751],"rgb":[0,0.66666666666666663,0.2],"xyz":[0.14971573321886239,0.289871827444813768,0.0793807979677747799],"hpluv":[130.852037745481823,180.013429236819462,60.7703154938824355],"hsluv":[130.852037745481823,99.9999999999908,60.7703154938824355]},"#00aa44":{"lch":[60.9274158721733841,81.0355822964375108,133.441426631804489],"luv":[60.9274158721733841,-55.7210928860807044,58.8381288426430444],"rgb":[0,0.66666666666666663,0.266666666666666663],"xyz":[0.15417372846308125,0.291655025542501334,0.102859572920661418],"hpluv":[133.441426631804489,168.77274926729055,60.9274158721733841],"hsluv":[133.441426631804489,99.9999999999908908,60.9274158721733841]},"#00aa55":{"lch":[61.1365343944832915,74.6960845180523592,137.272019015051796],"luv":[61.1365343944832915,-54.8704978500827636,50.6826746335676717],"rgb":[0,0.66666666666666663,0.333333333333333315],"xyz":[0.160136142502443235,0.294039991158246194,0.134261620194635334],"hpluv":[137.272019015051796,155.037353806827582,61.1365343944832915],"hsluv":[137.272019015051796,99.9999999999910614,61.1365343944832915]},"#00aa66":{"lch":[61.4009335299549264,67.6053275851037512,142.80970662058607],"luv":[61.4009335299549264,-53.8565898531593703,40.8649978254956139],"rgb":[0,0.66666666666666663,0.4],"xyz":[0.16772113827595142,0.297073989467649513,0.174209264601779296],"hpluv":[142.80970662058607,139.715720243970395,61.4009335299549264],"hsluv":[142.80970662058607,99.9999999999911893,61.4009335299549264]},"#00aa77":{"lch":[61.7231520087844814,60.4394033477847188,150.696962972825474],"luv":[61.7231520087844814,-52.7057786154446859,29.5807771631501382],"rgb":[0,0.66666666666666663,0.466666666666666674],"xyz":[0.177035151296153326,0.300799594675730309,0.223263066508177205],"hpluv":[150.696962972825474,124.254291935777843,61.7231520087844814],"hsluv":[150.696962972825474,99.9999999999911893,61.7231520087844814]},"#00aa88":{"lch":[62.1050795642419615,54.2095218153359397,161.640221068188367],"luv":[62.1050795642419615,-51.4501140589855126,17.0750700954568337],"rgb":[0,0.66666666666666663,0.533333333333333326],"xyz":[0.188175568398097182,0.305255761516507906,0.281935929911749372],"hpluv":[161.640221068188367,110.761232665855573,62.1050795642419615],"hsluv":[161.640221068188367,99.9999999999911466,62.1050795642419615]},"#00aa99":{"lch":[62.5480102999456307,50.2545412813378576,175.872445658321794],"luv":[62.5480102999456307,-50.1241952468173793,3.61717711159146882],"rgb":[0,0.66666666666666663,0.6],"xyz":[0.201232532507169881,0.310478547160137064,0.350702607552867307],"hpluv":[175.872445658321794,101.95326553071466,62.5480102999456307],"hsluv":[175.872445658321794,99.9999999999913314,62.5480102999456307]},"#00aaaa":{"lch":[63.0526871437625829,49.8847230087107931,192.17705063006116],"luv":[63.0526871437625829,-48.762339705407328,-10.5223484123201398],"rgb":[0,0.66666666666666663,0.66666666666666663],"xyz":[0.216290225472422437,0.316501624346238186,0.430006457169865852],"hpluv":[192.17705063006116,100.392967527320806,63.0526871437625829],"hsluv":[192.17705063006116,99.9999999999914451,63.0526871437625829]},"#00aabb":{"lch":[63.6193436646561565,53.6276681768737,207.895374658889665],"luv":[63.6193436646561565,-47.3963155750249143,-25.0901587081772526],"rgb":[0,0.66666666666666663,0.733333333333333282],"xyz":[0.233427817579759056,0.323356661189172945,0.520264442268507654],"hpluv":[207.895374658889665,106.964349821245364,63.6193436646561565],"hsluv":[207.895374658889665,99.9999999999916,63.6193436646561565]},"#00aacc":{"lch":[64.2477463386430259,60.9097449106327886,220.878520684721707],"luv":[64.2477463386430259,-46.0537892020538,-39.8628338833449],"rgb":[0,0.66666666666666663,0.8],"xyz":[0.25272019302348081,0.331073611366661746,0.62187095293877781],"hpluv":[220.878520684721707,120.300715116377788,64.2477463386430259],"hsluv":[220.878520684721707,99.9999999999916298,64.2477463386430259]},"#00aadd":{"lch":[64.9372385342214926,70.6418801813473465,230.685034316882962],"luv":[64.9372385342214926,-44.7574928469198525,-54.6538385624811625],"rgb":[0,0.66666666666666663,0.866666666666666696],"xyz":[0.274238518574114354,0.339680941586915253,0.735200800838783808],"hpluv":[230.685034316882962,138.04089297290011,64.9372385342214926],"hsluv":[230.685034316882962,99.9999999999918145,64.9372385342214926]},"#00aaee":{"lch":[65.6867863979168618,81.8478503674051,237.87423205753521],"luv":[65.6867863979168618,-43.5250094774703129,-69.3155405356638283],"rgb":[0,0.66666666666666663,0.933333333333333348],"xyz":[0.298050698840289119,0.34920581369338527,0.860611616907307],"hpluv":[237.87423205753521,158.11336767521891,65.6867863979168618],"hsluv":[237.87423205753521,99.999999999991843,65.6867863979168618]},"#00aaff":{"lch":[66.4950261675888,93.8462134827344,243.161780722675303],"luv":[66.4950261675888,-42.369016683119284,-83.7375555551541],"rgb":[0,0.66666666666666663,1],"xyz":[0.324221747250120484,0.359674233057318,0.998445805199088876],"hpluv":[243.161780722675303,179.088178632175044,66.4950261675888],"hsluv":[243.161780722675303,99.9999999999982805,66.4950261675888]},"#00bb00":{"lch":[66.1662429166961772,102.406451239047826,127.71501294924046],"luv":[66.1662429166961772,-62.6455428450044352,81.0099822060849135],"rgb":[0,0.733333333333333282,0],"xyz":[0.177695456756889275,0.355390913513783546,0.0592318189189614333],"hpluv":[127.71501294924046,196.39488290021464,66.1662429166961772],"hsluv":[127.71501294924046,100.000000000002373,66.1662429166961772]},"#00bb11":{"lch":[66.1974173108447559,101.237205455569821,128.123527834983577],"luv":[66.1974173108447559,-62.4996967519340956,79.6414444518024425],"rgb":[0,0.733333333333333282,0.0666666666666666657],"xyz":[0.178707122256526407,0.355795579713638399,0.064559923883717063],"hpluv":[128.123527834983577,194.061073356438868,66.1974173108447559],"hsluv":[128.123527834983577,99.9999999999909335,66.1974173108447559]},"#00bb22":{"lch":[66.2551438620851911,99.1062916374383747,128.898124119483072],"luv":[66.2551438620851911,-62.232564676438038,77.1308299962987718],"rgb":[0,0.733333333333333282,0.133333333333333331],"xyz":[0.180582480395003409,0.3565457229690292,0.0744368100796962556],"hpluv":[128.898124119483072,189.810813804630897,66.2551438620851911],"hsluv":[128.898124119483072,99.9999999999908624,66.2551438620851911]},"#00bb33":{"lch":[66.3500136661217255,95.7008075372637137,130.224174268563928],"luv":[66.3500136661217255,-61.8016571104716235,73.0698278476423155],"rgb":[0,0.733333333333333282,0.2],"xyz":[0.18367023112746117,0.357780823262012326,0.0906989639373074],"hpluv":[130.224174268563928,183.02647365261987,66.3500136661217255],"hsluv":[130.224174268563928,99.9999999999909335,66.3500136661217255]},"#00bb44":{"lch":[66.4865992404304,91.0092453899789859,132.255785626190885],"luv":[66.4865992404304,-61.1983980271068,67.3605138443080875],"rgb":[0,0.733333333333333282,0.266666666666666663],"xyz":[0.18812822637168003,0.359564021359699892,0.114177738890194044],"hpluv":[132.255785626190885,173.696361176634838,66.4865992404304],"hsluv":[132.255785626190885,99.9999999999909619,66.4865992404304]},"#00bb55":{"lch":[66.6685736373934219,85.1496193371524,135.204737263674588],"luv":[66.6685736373934219,-60.4246386982598,59.9943389949978751],"rgb":[0,0.733333333333333282,0.333333333333333315],"xyz":[0.194090640411042015,0.361948986975444753,0.145579786164167946],"hpluv":[135.204737263674588,162.069343805127659,66.6685736373934219],"hsluv":[135.204737263674588,99.9999999999909477,66.6685736373934219]},"#00bb66":{"lch":[66.8989180170192412,78.3861452968700689,139.371990675590268],"luv":[66.8989180170192412,-59.4914065933894,51.0407711152765629],"rgb":[0,0.733333333333333282,0.4],"xyz":[0.2016756361845502,0.364982985284848072,0.185527430571311908],"hpluv":[139.371990675590268,148.682392510907704,66.8989180170192412],"hsluv":[139.371990675590268,99.9999999999911182,66.8989180170192412]},"#00bb77":{"lch":[67.1800303821267448,71.1598447269708316,145.178146497089472],"luv":[67.1800303821267448,-58.4173559625633061,40.6341731047866617],"rgb":[0,0.733333333333333282,0.466666666666666674],"xyz":[0.210989649204752105,0.368708590492928867,0.234581232477709817],"hpluv":[145.178146497089472,134.410786503463328,67.1800303821267448],"hsluv":[145.178146497089472,99.9999999999910898,67.1800303821267448]},"#00bb88":{"lch":[67.5137905946342,64.1363411600919,153.159702568813543],"luv":[67.5137905946342,-57.2268359754185525,28.9578918715820954],"rgb":[0,0.733333333333333282,0.533333333333333326],"xyz":[0.222130066306695961,0.373164757333706465,0.293254095881282],"hpluv":[153.159702568813543,120.545503395456095,67.5137905946342],"hsluv":[153.159702568813543,99.9999999999911608,67.5137905946342]},"#00bb99":{"lch":[67.9016044714860811,58.2533417764790187,163.826150797364875],"luv":[67.9016044714860811,-55.9477282230567141,16.2266304205851419],"rgb":[0,0.733333333333333282,0.6],"xyz":[0.235187030415768661,0.378387542977335622,0.362020773522399919],"hpluv":[163.826150797364875,108.862958898475256,67.9016044714860811],"hsluv":[163.826150797364875,99.9999999999912461,67.9016044714860811]},"#00bbaa":{"lch":[68.3444379186728384,54.6744668749029543,177.202021912208522],"luv":[68.3444379186728384,-54.6092872876890922,2.66890801368250408],"rgb":[0,0.733333333333333282,0.66666666666666663],"xyz":[0.250244723381021217,0.384410620163436745,0.44132462313939852],"hpluv":[177.202021912208522,101.512776720033713,68.3444379186728384],"hsluv":[177.202021912208522,99.9999999999913598,68.3444379186728384]},"#00bbbb":{"lch":[68.8428468315880338,54.4656619866929645,192.177050630061132],"luv":[68.8428468315880338,-53.2402096652165113,-11.4886209116881091],"rgb":[0,0.733333333333333282,0.733333333333333282],"xyz":[0.267382315488357836,0.391265657006371503,0.531582608238040266],"hpluv":[192.177050630061132,100.392967527320806,68.8428468315880338],"hsluv":[192.177050630061132,99.9999999999914451,68.8428468315880338]},"#00bbcc":{"lch":[69.3970058395379397,58.0340346662075675,206.653495587531239],"luv":[69.3970058395379397,-51.8670935918889384,-26.0337047299998297],"rgb":[0,0.733333333333333282,0.8],"xyz":[0.28667469093207959,0.398982607183860305,0.633189118908310422],"hpluv":[206.653495587531239,106.116119046155191,69.3970058395379397],"hsluv":[206.653495587531239,99.9999999999915161,69.3970058395379397]},"#00bbdd":{"lch":[70.0067374807312461,64.9183055759271923,218.91244904401708],"luv":[70.0067374807312461,-50.5133677649133119,-40.7772740125682844],"rgb":[0,0.733333333333333282,0.866666666666666696],"xyz":[0.308193016482713134,0.407589937404113811,0.74651896680831642],"hpluv":[218.91244904401708,117.670246608059514,70.0067374807312461],"hsluv":[218.91244904401708,99.999999999991644,70.0067374807312461]},"#00bbee":{"lch":[70.6715424904064236,74.2108860535778,228.474155043258463],"luv":[70.6715424904064236,-49.1986871961444336,-55.5584807840624819],"rgb":[0,0.733333333333333282,0.933333333333333348],"xyz":[0.332005196748887843,0.417114809510583828,0.871929782876839643],"hpluv":[228.474155043258463,133.248513578578667,70.6715424904064236],"hsluv":[228.474155043258463,99.9999999999918288,70.6715424904064236]},"#00bbff":{"lch":[71.3906313155650167,85.0452269855302,235.688960914523477],"luv":[71.3906313155650167,-47.9387359102869155,-70.246481992653],"rgb":[0,0.733333333333333282,1],"xyz":[0.358176245158719264,0.427583228874516552,1.00976397116862149],"hpluv":[235.688960914523477,151.163886263776277,71.3906313155650167],"hsluv":[235.688960914523477,99.9999999999978,71.3906313155650167]},"#00cc00":{"lch":[71.6795694698327139,110.939506494120423,127.71501294924046],"luv":[71.6795694698327139,-67.8655057683618566,87.7601688009055181],"rgb":[0,0.8,0],"xyz":[0.215919200066506195,0.431838400133018441,0.0719730666888333814],"hpluv":[127.71501294924046,196.394882900214611,71.6795694698327139],"hsluv":[127.71501294924046,100.000000000002359,71.6795694698327139]},"#00cc11":{"lch":[71.7069484470386698,109.895339051400697,128.05073784188761],"luv":[71.7069484470386698,-67.7349868616780668,86.5387606802328548],"rgb":[0,0.8,0.0666666666666666657],"xyz":[0.216930865566143327,0.432243066332873294,0.0773011716535890181],"hpluv":[128.05073784188761,194.472124503698296,71.7069484470386698],"hsluv":[128.05073784188761,99.9999999999908766,71.7069484470386698]},"#00cc22":{"lch":[71.7576566073484,107.986601617430239,128.68476606632143],"luv":[71.7576566073484,-67.4954197535952289,84.2939763041676287],"rgb":[0,0.8,0.133333333333333331],"xyz":[0.218806223704620328,0.432993209588264094,0.0871780578495682107],"hpluv":[128.68476606632143,190.959361108477,71.7576566073484],"hsluv":[128.68476606632143,99.9999999999909193,71.7576566073484]},"#00cc33":{"lch":[71.8410194320707,104.91966800737103,129.762682813168567],"luv":[71.8410194320707,-67.1075822658835364,80.6517770244687853],"rgb":[0,0.8,0.2],"xyz":[0.22189397443707809,0.434228309881247221,0.103440211707179347],"hpluv":[129.762682813168567,185.320621425294917,71.8410194320707],"hsluv":[129.762682813168567,99.9999999999909761,71.8410194320707]},"#00cc44":{"lch":[71.9610975929873717,100.65733905537941,131.396818004218431],"luv":[71.9610975929873717,-66.561699323308261,75.5078809721416491],"rgb":[0,0.8,0.266666666666666663],"xyz":[0.226351969681296949,0.436011507978934787,0.126918986660065986],"hpluv":[131.396818004218431,177.495355343216744,71.9610975929873717],"hsluv":[131.396818004218431,99.9999999999909903,71.9610975929873717]},"#00cc55":{"lch":[72.1211872877728837,95.2615727691762828,133.734892870047815],"luv":[72.1211872877728837,-65.8564749898269639,68.8308938513177],"rgb":[0,0.8,0.333333333333333315],"xyz":[0.232314383720658935,0.438396473594679648,0.158321033934039901],"hpluv":[133.734892870047815,167.607792551030144,72.1211872877728837],"hsluv":[133.734892870047815,99.999999999991033,72.1211872877728837]},"#00cc66":{"lch":[72.3240060759138,88.9026050634798821,136.980115521422647],"luv":[72.3240060759138,-64.9982032665013207,60.6539921126355495],"rgb":[0,0.8,0.4],"xyz":[0.23989937949416712,0.441430471904082966,0.198268678341183863],"hpluv":[136.980115521422647,155.980870440536961,72.3240060759138],"hsluv":[136.980115521422647,99.9999999999910614,72.3240060759138]},"#00cc77":{"lch":[72.5717906268391459,81.8763194870781206,141.413175407098493],"luv":[72.5717906268391459,-63.9997644777707464,51.066249515114805],"rgb":[0,0.8,0.466666666666666674],"xyz":[0.249213392514369025,0.445156077112163762,0.247322480247581772],"hpluv":[141.413175407098493,143.162673336571032,72.5717906268391459],"hsluv":[141.413175407098493,99.9999999999910756,72.5717906268391459]},"#00cc88":{"lch":[72.8663546950801,74.6325704710961162,147.40707881161012],"luv":[72.8663546950801,-62.8793552775828672,40.2020802322297683],"rgb":[0,0.8,0.533333333333333326],"xyz":[0.260353809616312881,0.449612243952941359,0.305995343651153939],"hpluv":[147.40707881161012,129.969270924532168,72.8663546950801],"hsluv":[147.40707881161012,99.9999999999911608,72.8663546950801]},"#00cc99":{"lch":[73.2091273059676695,67.813783770663278,155.40051707617576],"luv":[73.2091273059676695,-61.6589956558222809,28.2290191825639418],"rgb":[0,0.8,0.6],"xyz":[0.273410773725385581,0.454835029596570517,0.374762021292271874],"hpluv":[155.40051707617576,117.541728748843539,73.2091273059676695],"hsluv":[155.40051707617576,99.9999999999911893,73.2091273059676695]},"#00ccaa":{"lch":[73.6011808048110368,62.2803364521242102,165.745935171574274],"luv":[73.6011808048110368,-60.3629393869259374,15.3347923742089414],"rgb":[0,0.8,0.66666666666666663],"xyz":[0.288468466690638137,0.460858106782671639,0.454065870909270419],"hpluv":[165.745935171574274,107.375573062224,73.6011808048110368],"hsluv":[165.745935171574274,99.9999999999912887,73.6011808048110368]},"#00ccbb":{"lch":[74.043253901593,59.041045922693165,178.335616576813749],"luv":[74.043253901593,-59.0161369965186395,1.7148404163965667],"rgb":[0,0.8,0.733333333333333282],"xyz":[0.305606058797974756,0.467713143625606398,0.544323856007912221],"hpluv":[178.335616576813749,101.183074845522739,74.043253901593],"hsluv":[178.335616576813749,99.9999999999913882,74.043253901593]},"#00cccc":{"lch":[74.5357725840108714,58.9696734274942429,192.177050630061132],"luv":[74.5357725840108714,-57.64288292201784,-12.4386668330598962],"rgb":[0,0.8,0.8],"xyz":[0.32489843424169651,0.4754300938030952,0.645930366678182377],"hpluv":[192.177050630061132,100.392967527320835,74.5357725840108714],"hsluv":[192.177050630061132,99.9999999999914877,74.5357725840108714]},"#00ccdd":{"lch":[75.0788705190671,62.3850861111967063,205.58971515357635],"luv":[75.0788705190671,-56.2657375800620656,-26.9456071312750254],"rgb":[0,0.8,0.866666666666666696],"xyz":[0.346416759792330053,0.484037424023348706,0.759260214578188375],"hpluv":[205.58971515357635,105.439266222061761,75.0788705190671],"hsluv":[205.58971515357635,99.9999999999915588,75.0788705190671]},"#00ccee":{"lch":[75.672409810316779,68.9113069897593,217.179575991302841],"luv":[75.672409810316779,-54.9047659259632326,-41.6441461630807765],"rgb":[0,0.8,0.933333333333333348],"xyz":[0.370228940058504818,0.493562296129818723,0.884671030646711598],"hpluv":[217.179575991302841,115.555933163518176,75.672409810316779],"hsluv":[217.179575991302841,99.9999999999916,75.672409810316779]},"#00ccff":{"lch":[76.3160024985922263,77.7871508482342193,226.46755023570978],"luv":[76.3160024985922263,-53.5770891110031471,-56.3944710009551713],"rgb":[0,0.8,1],"xyz":[0.396399988468336184,0.504030715493751447,1.02250521893849333],"hpluv":[226.46755023570978,131.600547876461974,76.3160024985922263],"hsluv":[226.46755023570978,99.9999999999969731,76.3160024985922263]},"#00dd00":{"lch":[77.1074905447145369,119.34037845513086,127.715012949240503],"luv":[77.1074905447145369,-73.004607631587163,94.4057900468603],"rgb":[0,0.866666666666666696,0],"xyz":[0.258553190613681372,0.51710638122737,0.0861843968712247],"hpluv":[127.715012949240503,210.385995725156505,77.1074905447145369],"hsluv":[127.715012949240503,100.000000000002203,77.1074905447145369]},"#00dd11":{"lch":[77.1317715771024268,118.40111864948102,127.995077421524911],"luv":[77.1317715771024268,-72.8869911141770359,93.3076171797906255],"rgb":[0,0.866666666666666696,0.0666666666666666657],"xyz":[0.259564856113318476,0.517511047427224868,0.0915125018359803366],"hpluv":[127.995077421524911,208.997725019578468,77.1317715771024268],"hsluv":[127.995077421524911,99.9999999999909193,77.1317715771024268]},"#00dd22":{"lch":[77.1767486793617081,116.680170458435171,128.522366120948305],"luv":[77.1767486793617081,-72.6707542705971434,91.2864921658838568],"rgb":[0,0.866666666666666696,0.133333333333333331],"xyz":[0.261440214251795533,0.518261190682615669,0.101389388031959529],"hpluv":[128.522366120948305,206.449864525990506,77.1767486793617081],"hsluv":[128.522366120948305,99.9999999999909335,77.1767486793617081]},"#00dd33":{"lch":[77.2507083817471312,113.903613467858165,129.414072915332611],"luv":[77.2507083817471312,-72.3197155087496668,87.9993858488157485],"rgb":[0,0.866666666666666696,0.2],"xyz":[0.264527964984253239,0.519496290975598796,0.117651541889570666],"hpluv":[129.414072915332611,202.327676795977681,77.2507083817471312],"hsluv":[129.414072915332611,99.9999999999909335,77.2507083817471312]},"#00dd44":{"lch":[77.3572825066044,110.019432359123073,130.755032484191332],"luv":[77.3572825066044,-71.8235777962907633,83.3405613681826907],"rgb":[0,0.866666666666666696,0.266666666666666663],"xyz":[0.268985960228472154,0.521279489073286362,0.141130316842457304],"hpluv":[130.755032484191332,196.537344059934071,77.3572825066044],"hsluv":[130.755032484191332,99.9999999999909193,77.3572825066044]},"#00dd55":{"lch":[77.499442461574418,105.05363654061,132.652443872197409],"luv":[77.499442461574418,-71.1790335676869717,77.2645567564888],"rgb":[0,0.866666666666666696,0.333333333333333315],"xyz":[0.274948374267834139,0.523664454689031111,0.172532364116431219],"hpluv":[132.652443872197409,189.094972829508237,77.499442461574418],"hsluv":[132.652443872197409,99.9999999999909477,77.499442461574418]},"#00dd66":{"lch":[77.6796666807438,99.1151742217995,135.249123061333165],"luv":[77.6796666807438,-70.3890792332532413,69.7796194150732276],"rgb":[0,0.866666666666666696,0.4],"xyz":[0.282533370041342324,0.52669845299843443,0.212480008523575181],"hpluv":[135.249123061333165,180.139247328423863,77.6796666807438],"hsluv":[135.249123061333165,99.9999999999909903,77.6796666807438]},"#00dd77":{"lch":[77.9000291762011301,92.4061998396230138,138.73841210181584],"luv":[77.9000291762011301,-69.4623356452591878,60.9416909472136155],"rgb":[0,0.866666666666666696,0.466666666666666674],"xyz":[0.29184738306154423,0.530424058206515281,0.26153381042997309],"hpluv":[138.73841210181584,169.957910917592017,77.9000291762011301],"hsluv":[138.73841210181584,99.9999999999910187,77.9000291762011301]},"#00dd88":{"lch":[78.1622519856154,85.2389230174627386,143.3784757437721],"luv":[78.1622519856154,-68.4122000424903,50.8472701580255091],"rgb":[0,0.866666666666666696,0.533333333333333326],"xyz":[0.30298780016348803,0.534880225047292823,0.320206673833545286],"hpluv":[143.3784757437721,159.033158409305884,78.1622519856154],"hsluv":[143.3784757437721,99.9999999999911608,78.1622519856154]},"#00dd99":{"lch":[78.4677391993035798,78.0607504013048583,149.494791226300919],"luv":[78.4677391993035798,-67.2558167964087801,39.6249398770864545],"rgb":[0,0.866666666666666696,0.6],"xyz":[0.316044764272560785,0.540103010690922,0.388973351474663165],"hpluv":[149.494791226300919,148.113090063328627,78.4677391993035798],"hsluv":[149.494791226300919,99.9999999999911466,78.4677391993035798]},"#00ddaa":{"lch":[78.8176011215583401,71.4835041270533225,157.438879868811341],"luv":[78.8176011215583401,-66.0129273361177,27.4259874352573583],"rgb":[0,0.866666666666666696,0.66666666666666663],"xyz":[0.331102457237813286,0.546126087877023103,0.468277201091661766],"hpluv":[157.438879868811341,138.307036304413771,78.8176011215583401],"hsluv":[157.438879868811341,99.9999999999912319,78.8176011215583401]},"#00ddbb":{"lch":[79.21267314937,66.2909050184163675,167.440816272526462],"luv":[79.21267314937,-64.7046905962200896,14.4148223370296193],"rgb":[0,0.866666666666666696,0.733333333333333282],"xyz":[0.34824004934514996,0.552981124719957862,0.558535186190303512],"hpluv":[167.440816272526462,131.160951364069831,79.21267314937],"hsluv":[167.440816272526462,99.9999999999912319,79.21267314937]},"#00ddcc":{"lch":[79.6535319864315738,63.3571261830985,179.312753048293331],"luv":[79.6535319864315738,-63.3525685364998381,0.759932897798095253],"rgb":[0,0.866666666666666696,0.8],"xyz":[0.367532424788871714,0.560698074897446719,0.660141696860573668],"hpluv":[179.312753048293331,128.577362979680402,79.6535319864315738],"hsluv":[179.312753048293331,99.9999999999913314,79.6535319864315738]},"#00dddd":{"lch":[80.1405107346531338,63.4039144225475795,192.177050630061245],"luv":[80.1405107346531338,-61.9773555359817649,-13.3739958452306631],"rgb":[0,0.866666666666666696,0.866666666666666696],"xyz":[0.389050750339505202,0.569305405117700225,0.773471544760579666],"hpluv":[192.177050630061245,132.399857962191078,80.1405107346531338],"hsluv":[192.177050630061245,99.9999999999915,80.1405107346531338]},"#00ddee":{"lch":[80.6737137665329,66.6843941199945078,204.668960845135786],"luv":[80.6737137665329,-60.59840405426975,-27.8323884211582282],"rgb":[0,0.866666666666666696,0.933333333333333348],"xyz":[0.412862930605679967,0.578830277224170242,0.898882360829102889],"hpluv":[204.668960845135786,143.769811077134563,80.6737137665329],"hsluv":[204.668960845135786,99.9999999999914735,80.6737137665329]},"#00ddff":{"lch":[81.2530318771427,72.8883394631876627,215.643856178856652],"luv":[81.2530318771427,-59.2330695533496296,-42.475328144570291],"rgb":[0,0.866666666666666696,1],"xyz":[0.439033979015511333,0.589298696588103,1.03671654912088473],"hpluv":[215.643856178856652,162.831862460855405,81.2530318771427],"hsluv":[215.643856178856652,99.9999999999960636,81.2530318771427]},"#00ee00":{"lch":[82.4573791946470749,127.620478503329409,127.715012949240503],"luv":[82.4573791946470749,-78.0698291684561241,100.955873068518613],"rgb":[0,0.933333333333333348,0],"xyz":[0.305731966954196188,0.611463933908400925,0.101910655651395884],"hpluv":[127.715012949240503,307.908475174189959,82.4573791946470749],"hsluv":[127.715012949240503,100.000000000002217,82.4573791946470749]},"#00ee11":{"lch":[82.4790940690076582,126.770138643430457,127.951660682688043],"luv":[82.4790940690076582,-77.963182339567652,99.9620440525398],"rgb":[0,0.933333333333333348,0.0666666666666666657],"xyz":[0.306743632453833293,0.611868600108255833,0.107238760616151521],"hpluv":[127.951660682688043,306.293921948395678,82.4790940690076582],"hsluv":[127.951660682688043,99.9999999999909193,82.4790940690076582]},"#00ee22":{"lch":[82.5193223464761729,125.209295581045268,128.396138884075839],"luv":[82.5193223464761729,-77.7668632323815814,98.1309466116455],"rgb":[0,0.933333333333333348,0.133333333333333331],"xyz":[0.308618990592310349,0.612618743363646634,0.117115646812130714],"hpluv":[128.396138884075839,303.325246698320768,82.5193223464761729],"hsluv":[128.396138884075839,99.9999999999907914,82.5193223464761729]},"#00ee33":{"lch":[82.5854861516441616,122.683025615083068,129.144698003447559],"luv":[82.5854861516441616,-77.4474668310457304,95.1473313105795881],"rgb":[0,0.933333333333333348,0.2],"xyz":[0.311706741324768055,0.613853843656629761,0.133377800669741864],"hpluv":[129.144698003447559,298.506449004286878,82.5854861516441616],"hsluv":[129.144698003447559,99.9999999999910187,82.5854861516441616]},"#00ee44":{"lch":[82.680854944152216,119.131104912681948,130.263308305441626],"luv":[82.680854944152216,-76.994580956063885,90.9068460629701889],"rgb":[0,0.933333333333333348,0.266666666666666663],"xyz":[0.31616473656898697,0.615637041754317327,0.156856575622628502],"hpluv":[130.263308305441626,291.702339981024693,82.680854944152216],"hsluv":[130.263308305441626,99.9999999999908624,82.680854944152216]},"#00ee55":{"lch":[82.8081199656530913,114.556122924925475,131.832385242542614],"luv":[82.8081199656530913,-76.4036333062175572,85.3556683366704192],"rgb":[0,0.933333333333333348,0.333333333333333315],"xyz":[0.322127150608348956,0.618022007370062076,0.18825862289660239],"hpluv":[131.832385242542614,282.889526663711365,82.8081199656530913],"hsluv":[131.832385242542614,99.9999999999908908,82.8081199656530913]},"#00ee66":{"lch":[82.9695459516691756,109.025909834785097,133.955863991345211],"luv":[82.9695459516691756,-75.6753248662734137,78.4849936082476347],"rgb":[0,0.933333333333333348,0.4],"xyz":[0.329712146381857141,0.621056005679465395,0.22820626730374638],"hpluv":[133.955863991345211,272.166364406401044,82.9695459516691756],"hsluv":[133.955863991345211,99.9999999999909193,82.9695459516691756]},"#00ee77":{"lch":[83.167051813506589,102.679799146220446,136.771308753659213],"luv":[83.167051813506589,-74.8151450958190338,70.3266323450776127],"rgb":[0,0.933333333333333348,0.466666666666666674],"xyz":[0.339026159402059046,0.624781610887546246,0.277260069210144289],"hpluv":[136.771308753659213,259.776444306911685,83.167051813506589],"hsluv":[136.771308753659213,99.9999999999910898,83.167051813506589]},"#00ee88":{"lch":[83.4022585136551839,95.7389522528198427,140.46074817536558],"luv":[83.4022585136551839,-73.8327925713246742,60.9480575538504],"rgb":[0,0.933333333333333348,0.533333333333333326],"xyz":[0.350166576504002847,0.629237777728323788,0.335932932613716428],"hpluv":[140.46074817536558,246.149488794882956,83.4022585136551839],"hsluv":[140.46074817536558,99.999999999991033,83.4022585136551839]},"#00ee99":{"lch":[83.6765199188301096,88.5221307628359142,145.258543938418427],"luv":[83.6765199188301096,-72.7414610621927,50.4464813176313],"rgb":[0,0.933333333333333348,0.6],"xyz":[0.363223540613075602,0.634460563371953,0.404699610254834363],"hpluv":[145.258543938418427,231.96752956627526,83.6765199188301096],"hsluv":[145.258543938418427,99.9999999999911,83.6765199188301096]},"#00eeaa":{"lch":[83.9909442670452364,81.4671227341597159,151.444498676017645],"luv":[83.9909442670452364,-71.557012704351564,38.9420854527837363],"rgb":[0,0.933333333333333348,0.66666666666666663],"xyz":[0.378281233578328102,0.640483640558054068,0.484003459871832964],"hpluv":[151.444498676017645,218.263507316576721,83.9909442670452364],"hsluv":[151.444498676017645,99.9999999999911893,83.9909442670452364]},"#00eebb":{"lch":[84.3464103530465366,75.1511025294100392,159.294479220170871],"luv":[84.3464103530465366,-70.2970903476626319,26.5707978811035801],"rgb":[0,0.933333333333333348,0.733333333333333282],"xyz":[0.395418825685664777,0.647338677400988827,0.57426144497047471],"hpluv":[159.294479220170871,206.543608310772072,84.3464103530465366],"hsluv":[159.294479220170871,99.9999999999912,84.3464103530465366]},"#00eecc":{"lch":[84.743580800257746,70.2844566194431195,168.945018717488722],"luv":[84.743580800257746,-68.9802322625990456,13.4771064879770393],"rgb":[0,0.933333333333333348,0.8],"xyz":[0.414711201129386531,0.655055627578477684,0.675867955640744866],"hpluv":[168.945018717488722,198.871854707918374,84.743580800257746],"hsluv":[168.945018717488722,99.9999999999913,84.743580800257746]},"#00eedd":{"lch":[85.1829138464002114,67.6253239558150625,180.163192871920216],"luv":[85.1829138464002114,-67.6250496492668418,-0.192613766721418916],"rgb":[0,0.933333333333333348,0.866666666666666696],"xyz":[0.43622952668002,0.66366295779873119,0.789197803540750864],"hpluv":[180.163192871920216,197.760624486431198,85.1829138464002114],"hsluv":[180.163192871920216,99.9999999999913882,85.1829138464002114]},"#00eeee":{"lch":[85.6646745174910507,67.7744082531008303,192.177050630061217],"luv":[85.6646745174910507,-66.2495152673009358,-14.2958784586901881],"rgb":[0,0.933333333333333348,0.933333333333333348],"xyz":[0.460041706946194784,0.673187829905201207,0.914608619609274087],"hpluv":[192.177050630061217,205.696714727687493,85.6646745174910507],"hsluv":[192.177050630061217,99.9999999999914309,85.6646745174910507]},"#00eeff":{"lch":[86.1889457184888,70.9350767712842867,203.864647638418489],"luv":[86.1889457184888,-64.8703943995767247,-28.6987290135183635],"rgb":[0,0.933333333333333348,1],"xyz":[0.486212755356026149,0.683656249269133931,1.05244280790105593],"hpluv":[203.864647638418489,224.453619733699583,86.1889457184888],"hsluv":[203.864647638418489,99.9999999999939888,86.1889457184888]},"#00ff00":{"lch":[87.7355191096597338,135.789531996666284,127.715012949240474],"luv":[87.7355191096597338,-83.0671197143942663,107.418111239344327],"rgb":[0,1,0],"xyz":[0.35758433938387,0.71516867876775,0.11919477979462],"hpluv":[127.715012949240474,490.145375063702204,87.7355191096597338],"hsluv":[127.715012949240474,100.000000000002217,87.7355191096597338]},"#00ff11":{"lch":[87.7550810882892165,135.01527678270574,127.917210072153054],"luv":[87.7550810882892165,-82.9698837721702915,106.513489059100834],"rgb":[0,1,0.0666666666666666657],"xyz":[0.358596004883507125,0.715573344967604941,0.124522884759375632],"hpluv":[127.917210072153054,488.208403570135204,87.7550810882892165],"hsluv":[127.917210072153054,99.9999999999917719,87.7550810882892165]},"#00ff22":{"lch":[87.7913242833811864,133.592052176160422,128.296258949772664],"luv":[87.7913242833811864,-82.7907071985999892,104.845291769319132],"rgb":[0,1,0.133333333333333331],"xyz":[0.360471363021984181,0.716323488222995741,0.134399770955354825],"hpluv":[128.296258949772664,484.641757887342919,87.7913242833811864],"hsluv":[128.296258949772664,99.9999999999919,87.7913242833811864]},"#00ff33":{"lch":[87.850943105558116,131.282721750620482,128.932531697131338],"luv":[87.850943105558116,-82.4986966230128616,102.123053644879462],"rgb":[0,1,0.2],"xyz":[0.363559113754441887,0.717558588515978868,0.150661924812965975],"hpluv":[128.932531697131338,478.837727878060548,87.850943105558116],"hsluv":[128.932531697131338,99.999999999991843,87.850943105558116]},"#00ff44":{"lch":[87.9368982766027756,128.022939247233296,129.878593634905172],"luv":[87.9368982766027756,-82.0835673214571528,98.245411848516369],"rgb":[0,1,0.266666666666666663],"xyz":[0.368017108998660802,0.719341786613666434,0.174140699765852613],"hpluv":[129.878593634905172,470.610169071279643,87.9368982766027756],"hsluv":[129.878593634905172,99.9999999999916724,87.9368982766027756]},"#00ff55":{"lch":[88.0516385770734189,123.799916713223595,131.196479790431113],"luv":[88.0516385770734189,-81.5399771501718362,93.1539129857171133],"rgb":[0,1,0.333333333333333315],"xyz":[0.373979523038022788,0.721726752229411184,0.205542747039826501],"hpluv":[131.196479790431113,459.892953467552729,88.0516385770734189],"hsluv":[131.196479790431113,99.9999999999917719,88.0516385770734189]},"#00ff66":{"lch":[88.197238997611,118.653311588493224,132.964137709394919],"luv":[88.197238997611,-80.8670327043222557,86.8281715373192498],"rgb":[0,1,0.4],"xyz":[0.381564518811531,0.724760750538814502,0.245490391446970491],"hpluv":[132.964137709394919,446.748834194207859,88.197238997611],"hsluv":[132.964137709394919,99.9999999999917719,88.197238997611]},"#00ff77":{"lch":[88.3754745956423164,112.679107800887323,135.2824164931273],"luv":[88.3754745956423164,-80.0679233099649537,79.2824633297525452],"rgb":[0,1,0.466666666666666674],"xyz":[0.390878531831732878,0.728486355746895353,0.2945441933533684],"hpluv":[135.2824164931273,431.3936933951166,88.3754745956423164],"hsluv":[135.2824164931273,99.9999999999915445,88.3754745956423164]},"#00ff88":{"lch":[88.587864465470858,106.036155512425779,138.2828406903445],"luv":[88.587864465470858,-79.1495135423216425,70.5621767086956311],"rgb":[0,1,0.533333333333333326],"xyz":[0.402018948933676679,0.732942522587672896,0.353217056756940539],"hpluv":[138.2828406903445,414.239888157084465,88.587864465470858],"hsluv":[138.2828406903445,99.9999999999914,88.587864465470858]},"#00ff99":{"lch":[88.8357000190422,98.9561663203651278,142.1349886621461],"luv":[88.8357000190422,-78.1218422027535695,60.739613298668921],"rgb":[0,1,0.6],"xyz":[0.415075913042749378,0.738165308231302109,0.421983734398058474],"hpluv":[142.1349886621461,395.967958147281365,88.8357000190422],"hsluv":[142.1349886621461,99.9999999999915303,88.8357000190422]},"#00ffaa":{"lch":[89.1200644426462674,91.7580340339716258,147.049061977519528],"luv":[89.1200644426462674,-76.997527549554917,49.9090929694682828],"rgb":[0,1,0.66666666666666663],"xyz":[0.430133606008001934,0.744188385417403175,0.501287584015057],"hpluv":[147.049061977519528,377.639750156066668,89.1200644426462674],"hsluv":[147.049061977519528,99.9999999999913,89.1200644426462674]},"#00ffbb":{"lch":[89.4418470234824241,84.8653215767476468,153.262243037154207],"luv":[89.4418470234824241,-75.791105608661141,38.1815546689964407],"rgb":[0,1,0.733333333333333282],"xyz":[0.447271198115338608,0.751043422260337934,0.591545569113698821],"hpluv":[153.262243037154207,360.863433446149145,89.4418470234824241],"hsluv":[153.262243037154207,99.9999999999912,89.4418470234824241]},"#00ffcc":{"lch":[89.801754487955634,78.8187300060100569,160.986090443114392],"luv":[89.801754487955634,-74.5183415032407197,25.6789598575702236],"rgb":[0,1,0.8],"xyz":[0.466563573559060307,0.758760372437826791,0.693152079783969],"hpluv":[160.986090443114392,347.997153451554084,89.801754487955634],"hsluv":[160.986090443114392,99.9999999999912461,89.801754487955634]},"#00ffdd":{"lch":[90.2003206582774339,74.260092310928,170.286849800478649],"luv":[90.2003206582774339,-73.1955569867131572,12.5288366352336915],"rgb":[0,1,0.866666666666666696],"xyz":[0.488081899109693906,0.767367702658080297,0.806481927683975],"hpluv":[170.286849800478649,342.308208972166483,90.2003206582774339],"hsluv":[170.286849800478649,99.9999999999913314,90.2003206582774339]},"#00ffee":{"lch":[90.6379152481429458,71.8480695265374294,180.909719109957],"luv":[90.6379152481429458,-71.8390133400929898,-1.14072652818200426],"rgb":[0,1,0.933333333333333348],"xyz":[0.511894079375868616,0.776892574764550314,0.931892743752498198],"hpluv":[180.909719109957,347.895283980605143,90.6379152481429458],"hsluv":[180.909719109957,99.999999999991374,90.6379152481429458]},"#00ffff":{"lch":[91.114752316705065,72.0862882649682,192.17705063006116],"luv":[91.114752316705065,-70.4643799638718207,-15.205397466925735],"rgb":[0,1,1],"xyz":[0.5380651277857,0.787360994128483,1.06972693204428],"hpluv":[192.17705063006116,369.190533917051368,91.114752316705065],"hsluv":[192.17705063006116,99.9999999999914877,91.114752316705065]},"#ff0000":{"lch":[53.23711559542933,179.038096923620287,12.1770506300617765],"luv":[53.23711559542933,175.009822162883836,37.7650936255616],"rgb":[1,0,0],"xyz":[0.41239079926595,0.21263900587151,0.019330818715591],"hpluv":[12.1770506300617765,426.746789183125202,53.23711559542933],"hsluv":[12.1770506300617765,100.000000000002203,53.23711559542933]},"#ff0011":{"lch":[53.2810087118185294,177.689248384364731,11.7592124156573554],"luv":[53.2810087118185294,173.960033822228979,36.2129206771479346],"rgb":[1,0,0.0666666666666666657],"xyz":[0.413402464765587119,0.213043672071364848,0.0246589236803466325],"hpluv":[11.7592124156573554,423.182830024727082,53.2810087118185294],"hsluv":[11.7592124156573554,99.9999999999986073,53.2810087118185294]},"#ff0022":{"lch":[53.362228057366309,175.255817292919801,10.9800713678561319],"luv":[53.362228057366309,172.047495148921342,33.3805468497921751],"rgb":[1,0,0.133333333333333331],"xyz":[0.415277822904064176,0.213793815326755676,0.0345358098763258251],"hpluv":[10.9800713678561319,416.75211680728853,53.362228057366309],"hsluv":[10.9800713678561319,99.9999999999986215,53.362228057366309]},"#ff0033":{"lch":[53.4955416476677499,171.43316235878109,9.68478250033725],"luv":[53.4955416476677499,168.989928530586468,28.8397852204116347],"rgb":[1,0,0.2],"xyz":[0.418365573636521881,0.215028915619738775,0.0507979637339369683],"hpluv":[9.68478250033725,406.646064741178918,53.4955416476677499],"hsluv":[9.68478250033725,99.9999999999986215,53.4955416476677499]},"#ff0044":{"lch":[53.6871179383659722,166.29954793496961,7.78930386328567259],"luv":[53.6871179383659722,164.765128442936401,22.5386799204815809],"rgb":[1,0,0.266666666666666663],"xyz":[0.422823568880740797,0.216812113717426369,0.0742767386868236],"hpluv":[7.78930386328567259,393.061316669856922,53.6871179383659722],"hsluv":[7.78930386328567259,99.9999999999987637,53.6871179383659722]},"#ff0055":{"lch":[53.9417095924386558,160.100368719231,5.2128969892355661],"luv":[53.9417095924386558,159.438189183864722,14.5461986032050437],"rgb":[1,0,0.333333333333333315],"xyz":[0.428785982920102782,0.219197079333171202,0.105678785960797522],"hpluv":[5.2128969892355661,376.623098544524225,53.9417095924386558],"hsluv":[5.2128969892355661,99.9999999999988,53.9417095924386558]},"#ff0066":{"lch":[54.2629295430466669,153.227313284557312,1.88082466234467849],"luv":[54.2629295430466669,153.144763004983872,5.02902580538230204],"rgb":[1,0,0.4],"xyz":[0.436370978693610967,0.222231077642574493,0.145626430367941484],"hpluv":[1.88082466234467849,358.321012364802243,54.2629295430466669],"hsluv":[1.88082466234467849,99.99999999999892,54.2629295430466669]},"#ff0077":{"lch":[54.6533978532017244,146.184101175375929,357.735148851436577],"luv":[54.6533978532017244,146.06990602550718,-5.77702260269427281],"rgb":[1,0,0.466666666666666674],"xyz":[0.445684991713812872,0.225956682850655316,0.194680232274339393],"hpluv":[357.735148851436577,339.408176675868503,54.6533978532017244],"hsluv":[357.735148851436577,99.9999999999990479,54.6533978532017244]},"#ff0088":{"lch":[55.1148373309560782,139.538803635294983,352.754628092234327],"luv":[55.1148373309560782,138.424605854630585,-17.5984719211521572],"rgb":[1,0,0.533333333333333326],"xyz":[0.456825408815756673,0.230412849691432914,0.253353095677911533],"hpluv":[352.754628092234327,321.26675874055752,55.1148373309560782],"hsluv":[352.754628092234327,99.9999999999991616,55.1148373309560782]},"#ff0099":{"lch":[55.6481496721619493,133.863929319774144,346.981903482220218],"luv":[55.6481496721619493,130.423488026195145,-30.1540269949209758],"rgb":[1,0,0.6],"xyz":[0.469882372924829372,0.235635635335062071,0.322119773319029468],"hpluv":[346.981903482220218,305.247535929832054,55.6481496721619493],"hsluv":[346.981903482220218,99.9999999999993463,55.6481496721619493]},"#ff00aa":{"lch":[56.2534865150640258,129.667114810270476,340.549180922221581],"luv":[56.2534865150640258,122.266710865918853,-43.1788383036143273],"rgb":[1,0,0.66666666666666663],"xyz":[0.484940065890081928,0.241658712521163166,0.401423622936028068],"hpluv":[340.549180922221581,292.495864077812769,56.2534865150640258],"hsluv":[340.549180922221581,99.9999999999994742,56.2534865150640258]},"#ff00bb":{"lch":[56.9303217870161689,127.321325924901956,333.685619315648239],"luv":[56.9303217870161689,114.127678427447606,-56.4410582115202928],"rgb":[1,0,0.733333333333333282],"xyz":[0.502077657997418547,0.248513749364097924,0.491681608034669815],"hpluv":[333.685619315648239,283.789838362024682,56.9303217870161689],"hsluv":[333.685619315648239,99.9999999999995879,56.9303217870161689]},"#ff00cc":{"lch":[57.6775275187384153,127.012826563172382,326.690520651062286],"luv":[57.6775275187384153,106.146716951325558,-69.7505024499586312],"rgb":[1,0,0.8],"xyz":[0.521370033441140301,0.256230699541586726,0.593288118704939915],"hpluv":[326.690520651062286,279.434659423159303,57.6775275187384153],"hsluv":[326.690520651062286,99.9999999999997726,57.6775275187384153]},"#ff00dd":{"lch":[58.4934529509690151,128.727977043064641,319.874434183361473],"luv":[58.4934529509690151,98.4297766537384149,-82.9606602040687],"rgb":[1,0,0.866666666666666696],"xyz":[0.542888358991773901,0.264838029761840288,0.706617966604945913],"hpluv":[319.874434183361473,279.257606739571429,58.4934529509690151],"hsluv":[319.874434183361473,99.9999999999999716,58.4934529509690151]},"#ff00ee":{"lch":[59.3760054748790367,132.286429048213932,313.494468670954461],"luv":[59.3760054748790367,91.0507046157626,-95.9659757377649214],"rgb":[1,0,0.933333333333333348],"xyz":[0.56670053925794861,0.274362901868310305,0.832028782673469136],"hpluv":[313.494468670954461,282.711609251625362,59.3760054748790367],"hsluv":[313.494468670954461,100.000000000000156,59.3760054748790367]},"#ff00ff":{"lch":[60.3227313545512942,137.405400537897037,307.715012949243601],"luv":[60.3227313545512942,84.0556019897527875,-108.696365491768773],"rgb":[1,0,1],"xyz":[0.59287158766778,0.284831321232243,0.969862970965251],"hpluv":[307.715012949243601,289.042783730483336,60.3227313545512942],"hsluv":[307.715012949243601,100.000000000000384,60.3227313545512942]},"#ff1100":{"lch":[53.6695097624616864,176.771562285449363,12.5954542867932275],"luv":[53.6695097624616864,172.517389506501019,38.5478345786208934],"rgb":[1,0.0666666666666666657,0],"xyz":[0.414395199526878422,0.216647806393366865,0.019998952135900451],"hpluv":[12.5954542867932275,417.949777534481484,53.6695097624616864],"hsluv":[12.5954542867932275,100.000000000002245,53.6695097624616864]},"#ff1111":{"lch":[53.7128602445647658,175.445128796306847,12.1770506300617765],"luv":[53.7128602445647658,171.497694164414924,37.0072170615611569],"rgb":[1,0.0666666666666666657,0.0666666666666666657],"xyz":[0.415406865026515526,0.217052472593221718,0.0253270571006560807],"hpluv":[12.1770506300617765,414.478837946685644,53.7128602445647658],"hsluv":[12.1770506300617765,99.9999999999986215,53.7128602445647658]},"#ff1122":{"lch":[53.7930781791116743,173.051572118951754,11.3967197916969329],"luv":[53.7930781791116743,169.639425839354459,34.1952016185739538],"rgb":[1,0.0666666666666666657,0.133333333333333331],"xyz":[0.417282223164992583,0.217802615848612546,0.0352039432966352803],"hpluv":[11.3967197916969329,408.214548988049671,53.7930781791116743],"hsluv":[11.3967197916969329,99.9999999999987,53.7930781791116743]},"#ff1133":{"lch":[53.9247555399676912,169.290109899416,10.0990648343251674],"luv":[53.9247555399676912,166.667136068812482,29.6851320424264138],"rgb":[1,0.0666666666666666657,0.2],"xyz":[0.420369973897450289,0.219037716141595645,0.0514660971542464235],"hpluv":[10.0990648343251674,398.366425235699353,53.9247555399676912],"hsluv":[10.0990648343251674,99.9999999999987,53.9247555399676912]},"#ff1144":{"lch":[54.1139966850166445,164.235972949617775,8.19925898659400154],"luv":[54.1139966850166445,162.55716522781,23.4226993279181244],"rgb":[1,0.0666666666666666657,0.266666666666666663],"xyz":[0.424827969141669204,0.220820914239283239,0.074944872107133062],"hpluv":[8.19925898659400154,385.121711929848118,54.1139966850166445],"hsluv":[8.19925898659400154,99.9999999999988489,54.1139966850166445]},"#ff1155":{"lch":[54.365514290002,158.12888296709221,5.61535385404219856],"luv":[54.365514290002,157.370056367003059,15.4728467796533362],"rgb":[1,0.0666666666666666657,0.333333333333333315],"xyz":[0.430790383181031189,0.223205879855028072,0.106346919381106964],"hpluv":[5.61535385404219856,369.085538340858477,54.365514290002],"hsluv":[5.61535385404219856,99.9999999999988916,54.365514290002]},"#ff1166":{"lch":[54.6829025612910442,151.353597545298243,2.27091305216541839],"luv":[54.6829025612910442,151.234730451097789,5.99731567352495443],"rgb":[1,0.0666666666666666657,0.4],"xyz":[0.438375378954539374,0.226239878164431363,0.146294563788250925],"hpluv":[2.27091305216541839,351.221033033747858,54.6829025612910442],"hsluv":[2.27091305216541839,99.999999999999,54.6829025612910442]},"#ff1177":{"lch":[55.0687823252034292,144.407362773795285,358.105880212246802],"luv":[55.0687823252034292,144.328460520523464,-4.77303960367160496],"rgb":[1,0.0666666666666666657,0.466666666666666674],"xyz":[0.44768939197474128,0.229965483372512186,0.195348365694648834],"hpluv":[358.105880212246802,332.753927221166919,55.0687823252034292],"hsluv":[358.105880212246802,99.9999999999990905,55.0687823252034292]},"#ff1188":{"lch":[55.5248949860500716,137.85386672349216,353.096828842063303],"luv":[55.5248949860500716,136.85452147125136,-16.5689023019976744],"rgb":[1,0.0666666666666666657,0.533333333333333326],"xyz":[0.45882980907668508,0.234421650213289784,0.254021229098221],"hpluv":[353.096828842063303,315.043506786171235,55.5248949860500716],"hsluv":[353.096828842063303,99.9999999999992,55.5248949860500716]},"#ff1199":{"lch":[56.0521767726019249,132.264360312052816,347.28491936957397],"luv":[56.0521767726019249,129.020794472918823,-29.1117777254046715],"rgb":[1,0.0666666666666666657,0.6],"xyz":[0.47188677318575778,0.239644435856918941,0.322787906739338937],"hpluv":[347.28491936957397,299.426117704125659,56.0521767726019249],"hsluv":[347.28491936957397,99.9999999999993605,56.0521767726019249]},"#ff11aa":{"lch":[56.6508275614924912,128.148315107741439,340.802676353967],"luv":[56.6508275614924912,121.022209124101792,-42.1380536294115586],"rgb":[1,0.0666666666666666657,0.66666666666666663],"xyz":[0.486944466151010336,0.245667513043020036,0.402091756356337537],"hpluv":[340.802676353967,287.042344439162662,56.6508275614924912],"hsluv":[340.802676353967,99.9999999999995168,56.6508275614924912]},"#ff11bb":{"lch":[57.3203806938084455,125.882364893771992,333.882217516525884],"luv":[57.3203806938084455,113.02864145467457,-55.4156656746030762],"rgb":[1,0.0666666666666666657,0.733333333333333282],"xyz":[0.504082058258347,0.252522549885954795,0.492349741454979284],"hpluv":[333.882217516525884,278.673167271969135,57.3203806938084455],"hsluv":[333.882217516525884,99.9999999999996163,57.3203806938084455]},"#ff11cc":{"lch":[58.0597760671947754,125.656277294901628,326.828156543045054],"luv":[58.0597760671947754,105.178488239830273,-68.7530772780178694],"rgb":[1,0.0666666666666666657,0.8],"xyz":[0.523374433702068709,0.260239500063443596,0.593956252125249384],"hpluv":[326.828156543045054,274.630115267561905,58.0597760671947754],"hsluv":[326.828156543045054,99.9999999999997868,58.0597760671947754]},"#ff11dd":{"lch":[58.8674364673636177,127.458097444326981,319.957026901825429],"luv":[58.8674364673636177,97.5770916499376568,-82.0016938195011846],"rgb":[1,0.0666666666666666657,0.866666666666666696],"xyz":[0.544892759252702308,0.268846830283697158,0.707286100025255382],"hpluv":[319.957026901825429,274.746161939823423,58.8674364673636177],"hsluv":[319.957026901825429,100.000000000000028,58.8674364673636177]},"#ff11ee":{"lch":[59.7413458233107519,131.106916258937218,313.5305052972667],"luv":[59.7413458233107519,90.2986667085849319,-95.0535337669245877],"rgb":[1,0.0666666666666666657,0.933333333333333348],"xyz":[0.568704939518877,0.278371702390167175,0.832696916093778605],"hpluv":[313.5305052972667,278.477381794919836,59.7413458233107519],"hsluv":[313.5305052972667,100.000000000000199,59.7413458233107519]},"#ff11ff":{"lch":[60.6791274610807534,136.317870534400242,307.715012949243601],"luv":[60.6791274610807534,83.3903225409976,-107.83606045076894],"rgb":[1,0.0666666666666666657,1],"xyz":[0.594875987928708438,0.288840121754099899,0.97053110438556045],"hpluv":[307.715012949243601,285.070838096226908,60.6791274610807534],"hsluv":[307.715012949243601,100.000000000000398,60.6791274610807534]},"#ff2200":{"lch":[54.4571507543770679,172.725520469573979,13.3786813235288875],"luv":[54.4571507543770679,168.038102184023103,39.9662562154253393],"rgb":[1,0.133333333333333331,0],"xyz":[0.418110823261646336,0.224079053862902833,0.0212374933808230602],"hpluv":[13.3786813235288875,402.476865089738737,54.4571507543770679],"hsluv":[13.3786813235288875,100.00000000000216,54.4571507543770679]},"#ff2211":{"lch":[54.4995382972682876,171.437527349711331,12.9593558016228254],"luv":[54.4995382972682876,167.070909686171433,38.446546274251638],"rgb":[1,0.133333333333333331,0.0666666666666666657],"xyz":[0.41912248876128344,0.224483720062757686,0.0265655983455786934],"hpluv":[12.9593558016228254,399.164948195999784,54.4995382972682876],"hsluv":[12.9593558016228254,99.999999999998721,54.4995382972682876]},"#ff2222":{"lch":[54.5779789595956117,169.112342257331477,12.1770506300617924],"luv":[54.5779789595956117,165.307392407273255,35.6714216042562171],"rgb":[1,0.133333333333333331,0.133333333333333331],"xyz":[0.420997846899760497,0.225233863318148514,0.036442484541557886],"hpluv":[12.1770506300617924,393.185217729465933,54.5779789595956117],"hsluv":[12.1770506300617924,99.9999999999987494,54.5779789595956117]},"#ff2233":{"lch":[54.7067518227456,165.455769736233549,10.8753803895539445],"luv":[54.7067518227456,162.484163442906947,31.2171166072114978],"rgb":[1,0.133333333333333331,0.2],"xyz":[0.424085597632218203,0.226468963611131613,0.0527046383991690293],"hpluv":[10.8753803895539445,383.778210348001721,54.7067518227456],"hsluv":[10.8753803895539445,99.9999999999987779,54.7067518227456]},"#ff2244":{"lch":[54.8918465894738148,160.537768894747074,8.96806115251763103],"luv":[54.8918465894738148,158.575257224785304,25.0252480066910863],"rgb":[1,0.133333333333333331,0.266666666666666663],"xyz":[0.428543592876437118,0.228252161708819207,0.0761834133520556678],"hpluv":[8.96806115251763103,371.115171122776133,54.8918465894738148],"hsluv":[8.96806115251763103,99.9999999999988347,54.8918465894738148]},"#ff2255":{"lch":[55.1379036013317432,154.588213330392733,6.3708707633682522],"luv":[55.1379036013317432,153.633547891150499,17.1536778289841081],"rgb":[1,0.133333333333333331,0.333333333333333315],"xyz":[0.434506006915799103,0.23063712732456404,0.107585460626029583],"hpluv":[6.3708707633682522,355.76683037739258,55.1379036013317432],"hsluv":[6.3708707633682522,99.9999999999989342,55.1379036013317432]},"#ff2266":{"lch":[55.4484819892530254,147.979820726080618,3.00414546296194196],"luv":[55.4484819892530254,147.776458796099433,7.75535736170059753],"rgb":[1,0.133333333333333331,0.4],"xyz":[0.442091002689307289,0.23367112563396733,0.147533105033173545],"hpluv":[3.00414546296194196,338.650844053811227,55.4484819892530254],"hsluv":[3.00414546296194196,99.9999999999990763,55.4484819892530254]},"#ff2277":{"lch":[55.8262016697843961,141.198613687408425,358.803757025958646],"luv":[55.8262016697843961,141.167840095073672,-2.94778393674187145],"rgb":[1,0.133333333333333331,0.466666666666666674],"xyz":[0.451405015709509194,0.237396730842048154,0.196586906939571454],"hpluv":[358.803757025958646,320.945787006908631,55.8262016697843961],"hsluv":[358.803757025958646,99.9999999999991616,55.8262016697843961]},"#ff2288":{"lch":[56.2728344602164299,134.800794021339357,353.742009538390391],"luv":[56.2728344602164299,133.997535770156077,-14.694028593592142],"rgb":[1,0.133333333333333331,0.533333333333333326],"xyz":[0.462545432811453,0.241852897682825752,0.255259770343143622],"hpluv":[353.742009538390391,303.971583410200083,56.2728344602164299],"hsluv":[353.742009538390391,99.9999999999992752,56.2728344602164299]},"#ff2299":{"lch":[56.7893750973531866,129.355771045476672,347.857065824102108],"luv":[56.7893750973531866,126.461550291410035,-27.2101415039127161],"rgb":[1,0.133333333333333331,0.6],"xyz":[0.47560239692052575,0.247075683326454909,0.324026447984261501],"hpluv":[347.857065824102108,289.040064659782502,56.7893750973531866],"hsluv":[347.857065824102108,99.9999999999994316,56.7893750973531866]},"#ff22aa":{"lch":[57.3761062638205743,125.376808270539939,341.281866819384959],"luv":[57.3761062638205743,118.745473604842076,-40.2350164715945766],"rgb":[1,0.133333333333333331,0.66666666666666663],"xyz":[0.49066008988577825,0.253098760512556031,0.403330297601260102],"hpluv":[341.281866819384959,277.284417349873706,57.3761062638205743],"hsluv":[341.281866819384959,99.999999999999531,57.3761062638205743]},"#ff22bb":{"lch":[58.0326640845464112,123.247659375493754,334.254064951888324],"luv":[58.0326640845464112,111.01274832153284,-53.5364852379920606],"rgb":[1,0.133333333333333331,0.733333333333333282],"xyz":[0.507797681993114924,0.25995379735549079,0.493588282699901848],"hpluv":[334.254064951888324,269.491764983662165,58.0326640845464112],"hsluv":[334.254064951888324,99.9999999999997726,58.0326640845464112]},"#ff22cc":{"lch":[58.7581065478829316,123.164795236141373,327.088444575119183],"luv":[58.7581065478829316,103.398114188518221,-66.9208246199849128],"rgb":[1,0.133333333333333331,0.8],"xyz":[0.527090057436836679,0.267670747532979592,0.595194793370172],"hpluv":[327.088444575119183,265.985598747154427,58.7581065478829316],"hsluv":[327.088444575119183,99.9999999999998721,58.7581065478829316]},"#ff22dd":{"lch":[59.550985046801415,125.119413407905796,320.113090366201448],"luv":[59.550985046801415,96.0055877759378,-80.2358693312108358],"rgb":[1,0.133333333333333331,0.866666666666666696],"xyz":[0.548608382987470167,0.276278077753233098,0.708524641270178],"hpluv":[320.113090366201448,266.609166102550091,59.550985046801415],"hsluv":[320.113090366201448,100.000000000000028,59.550985046801415]},"#ff22ee":{"lch":[60.4094179672163705,128.929416765847606,313.598505937960113],"luv":[60.4094179672163705,88.9098108664153273,-93.3693742041783281],"rgb":[1,0.133333333333333331,0.933333333333333348],"xyz":[0.572420563253645,0.285802949859703115,0.833935457338701225],"hpluv":[313.598505937960113,270.823716236275,60.4094179672163705],"hsluv":[313.598505937960113,100.000000000000227,60.4094179672163705]},"#ff22ff":{"lch":[61.3311646171935223,134.305840538380238,307.715012949243601],"luv":[61.3311646171935223,82.1594946996257249,-106.244417422389745],"rgb":[1,0.133333333333333331,1],"xyz":[0.598591611663476297,0.296271369223635839,0.97176964563048307],"hpluv":[307.715012949243601,277.877263991976,61.3311646171935223],"hsluv":[307.715012949243601,100.000000000000398,61.3311646171935223]},"#ff3300":{"lch":[55.7168894472394811,166.476173059961667,14.689559134518138],"luv":[55.7168894472394811,161.034729269155179,42.2153072463082495],"rgb":[1,0.2,0],"xyz":[0.424228545350657182,0.236314498040924637,0.0232767340771599419],"hpluv":[14.689559134518138,379.144314271077917,55.7168894472394811],"hsluv":[14.689559134518138,100.000000000002203,55.7168894472394811]},"#ff3311":{"lch":[55.7578022303213,165.243627812887922,14.2690908575150317],"luv":[55.7578022303213,160.145669888681539,40.7286256663500339],"rgb":[1,0.2,0.0666666666666666657],"xyz":[0.425240210850294287,0.236719164240779489,0.0286048390419155751],"hpluv":[14.2690908575150317,376.06108995847427,55.7578022303213],"hsluv":[14.2690908575150317,99.9999999999988,55.7578022303213]},"#ff3322":{"lch":[55.8335204651182835,163.01701714894287,13.4842232594842422],"luv":[55.8335204651182835,158.523316810386802,38.0119179675594552],"rgb":[1,0.2,0.133333333333333331],"xyz":[0.427115568988771344,0.237469307496170318,0.0384817252378947677],"hpluv":[13.4842232594842422,370.490653647292163,55.8335204651182835],"hsluv":[13.4842232594842422,99.9999999999987494,55.8335204651182835]},"#ff3333":{"lch":[55.9578428172660267,159.511521097175432,12.1770506300617853],"luv":[55.9578428172660267,155.922585303490365,33.6462888742638455],"rgb":[1,0.2,0.2],"xyz":[0.430203319721229049,0.238704407789153417,0.0547438790955059179],"hpluv":[12.1770506300617853,361.718248261175631,55.9578428172660267],"hsluv":[12.1770506300617853,99.9999999999988773,55.9578428172660267]},"#ff3344":{"lch":[56.1365811585215368,154.789240798906889,10.2588910791084782],"luv":[56.1365811585215368,152.31463646984821,27.5673826135157078],"rgb":[1,0.2,0.266666666666666663],"xyz":[0.434661314965447965,0.240487605886841,0.0782226540483925564],"hpluv":[10.2588910791084782,349.892100101075414,56.1365811585215368],"hsluv":[10.2588910791084782,99.9999999999989626,56.1365811585215368]},"#ff3355":{"lch":[56.3742616664660403,149.065442517766684,7.64169944339336649],"luv":[56.3742616664660403,147.741595680550319,19.8223878173745902],"rgb":[1,0.2,0.333333333333333315],"xyz":[0.44062372900480995,0.242872571502585843,0.109624701322366458],"hpluv":[7.64169944339336649,335.533149366899124,56.3742616664660403],"hsluv":[7.64169944339336649,99.9999999999990195,56.3742616664660403]},"#ff3366":{"lch":[56.674385203130754,142.694983818340035,4.24028319431916056],"luv":[56.674385203130754,142.304390380845462,10.550776523662277],"rgb":[1,0.2,0.4],"xyz":[0.448208724778318135,0.245906569811989134,0.14957234572951042],"hpluv":[4.24028319431916056,319.492902958598108,56.674385203130754],"hsluv":[4.24028319431916056,99.9999999999991758,56.674385203130754]},"#ff3377":{"lch":[57.0395646827704468,136.14730874514737,359.983392279567909],"luv":[57.0395646827704468,136.147303025702882,-0.0394635770517579934],"rgb":[1,0.2,0.466666666666666674],"xyz":[0.457522737798520041,0.249632175020069957,0.198626147635908329],"hpluv":[359.983392279567909,302.881107814185,57.0395646827704468],"hsluv":[359.983392279567909,99.9999999999992895,57.0395646827704468]},"#ff3388":{"lch":[57.4716120619286954,129.967879448766553,354.83565117969431],"luv":[57.4716120619286954,129.440287861866665,-11.6987848363070146],"rgb":[1,0.2,0.533333333333333326],"xyz":[0.468663154900463841,0.254088341860847555,0.257299011039480496],"hpluv":[354.83565117969431,286.960407533356261,57.4716120619286954],"hsluv":[354.83565117969431,99.9999999999993889,57.4716120619286954]},"#ff3399":{"lch":[57.9716047421228353,124.724336507791776,348.82951213288959],"luv":[57.9716047421228353,122.361442957788952,-24.1627273832372573],"rgb":[1,0.2,0.6],"xyz":[0.481720119009536596,0.259311127504476713,0.326065688680598431],"hpluv":[348.82951213288959,273.007894976207297,57.9716047421228353],"hsluv":[348.82951213288959,99.9999999999995737,57.9716047421228353]},"#ff33aa":{"lch":[58.5399451724763935,120.937271340322638,342.098036856126953],"luv":[58.5399451724763935,115.081956962752116,-37.174813797329108],"rgb":[1,0.2,0.66666666666666663],"xyz":[0.496777811974789096,0.265334204690577835,0.405369538297597032],"hpluv":[342.098036856126953,262.148381504719794,58.5399451724763935],"hsluv":[342.098036856126953,99.9999999999996732,58.5399451724763935]},"#ff33bb":{"lch":[59.1764201449825862,119.003132790944747,334.888094830460091],"luv":[59.1764201449825862,107.755032536641394,-50.5034511403585498],"rgb":[1,0.2,0.733333333333333282],"xyz":[0.513915404082125771,0.272189241533512594,0.495627523396238778],"hpluv":[334.888094830460091,255.181409444549388,59.1764201449825862],"hsluv":[334.888094830460091,99.9999999999998295,59.1764201449825862]},"#ff33cc":{"lch":[59.8802624584280494,119.13012657470172,327.532171012183937],"luv":[59.8802624584280494,100.509254029343069,-63.9521454852723039],"rgb":[1,0.2,0.8],"xyz":[0.533207779525847525,0.279906191711001395,0.597234034066508879],"hpluv":[327.532171012183937,252.451080902073329,59.8802624584280494],"hsluv":[327.532171012183937,100.000000000000043,59.8802624584280494]},"#ff33dd":{"lch":[60.650215463767978,121.314823858854638,320.378757122173454],"luv":[60.650215463767978,93.4460015542912146,-77.3636302238999747],"rgb":[1,0.2,0.866666666666666696],"xyz":[0.554726105076481,0.288513521931254902,0.710563881966514876],"hpluv":[320.378757122173454,253.817084039055629,60.650215463767978],"hsluv":[320.378757122173454,100.000000000000171,60.650215463767978]},"#ff33ee":{"lch":[61.484599762034378,125.372817174433621,313.71398784253438],"luv":[61.484599762034378,86.6400000332951805,-90.6192787462169775],"rgb":[1,0.2,0.933333333333333348],"xyz":[0.578538285342655723,0.298038394037724919,0.8359746980350381],"hpluv":[313.71398784253438,258.747618308410438,61.484599762034378],"hsluv":[313.71398784253438,100.000000000000242,61.484599762034378]},"#ff33ff":{"lch":[62.3813806681475,131.007738376122177,307.715012949243658],"luv":[62.3813806681475,80.141932350642,-103.635409940481253],"rgb":[1,0.2,1],"xyz":[0.604709333752487144,0.308506813401657642,0.97380888632682],"hpluv":[307.715012949243658,266.490230971107223,62.3813806681475],"hsluv":[307.715012949243658,100.000000000000597,62.3813806681475]},"#ff4400":{"lch":[57.461133143380664,158.273971604467,16.6278363926044079],"luv":[57.461133143380664,151.655533944896689,45.2907177172089845],"rgb":[1,0.266666666666666663,0],"xyz":[0.433061115833623222,0.253979639006856939,0.0262209242381485352],"hpluv":[16.6278363926044079,349.522099776260404,57.461133143380664],"hsluv":[16.6278363926044079,100.000000000002203,57.461133143380664]},"#ff4411":{"lch":[57.500127691013958,157.107055615985729,16.2066010587584444],"luv":[57.500127691013958,150.863862649088418,43.84885256105823],"rgb":[1,0.266666666666666663,0.0666666666666666657],"xyz":[0.434072781333260327,0.254384305206711792,0.031549029202904165],"hpluv":[16.2066010587584444,346.709871357654038,57.500127691013958],"hsluv":[16.2066010587584444,99.9999999999990195,57.500127691013958]},"#ff4422":{"lch":[57.5723039440668174,154.996970095022306,15.4196600073807488],"luv":[57.5723039440668174,149.417734299680745,41.2116660108183908],"rgb":[1,0.266666666666666663,0.133333333333333331],"xyz":[0.435948139471737384,0.255134448462102592,0.0414259153988833645],"hpluv":[15.4196600073807488,341.624434338608523,57.5723039440668174],"hsluv":[15.4196600073807488,99.9999999999990195,57.5723039440668174]},"#ff4433":{"lch":[57.6908335218327437,151.669616752661852,14.1071803519879388],"luv":[57.6908335218327437,147.095485225188412,36.9674298845038223],"rgb":[1,0.266666666666666663,0.2],"xyz":[0.439035890204195089,0.256369548755085719,0.0576880692564945077],"hpluv":[14.1071803519879388,333.603886972203838,57.6908335218327437],"hsluv":[14.1071803519879388,99.9999999999991189,57.6908335218327437]},"#ff4444":{"lch":[57.8612930010941682,147.177084719743902,12.177050630061812],"luv":[57.8612930010941682,143.865668066403089,31.0445457111261],"rgb":[1,0.266666666666666663,0.266666666666666663],"xyz":[0.443493885448414,0.258152746852773285,0.0811668442093811393],"hpluv":[12.177050630061812,322.76868159643891,57.8612930010941682],"hsluv":[12.177050630061812,99.9999999999991616,57.8612930010941682]},"#ff4455":{"lch":[58.088054010202,141.716285969530816,9.53556562214303405],"luv":[58.088054010202,139.758186425649882,23.4766913344092778],"rgb":[1,0.266666666666666663,0.333333333333333315],"xyz":[0.449456299487776,0.260537712468518146,0.112568891483355055],"hpluv":[9.53556562214303405,309.579547415252762,58.088054010202],"hsluv":[9.53556562214303405,99.9999999999992184,58.088054010202]},"#ff4466":{"lch":[58.3745334436288772,135.619673907166316,6.08910281061040859],"luv":[58.3745334436288772,134.854526247228307,14.3858507333331573],"rgb":[1,0.266666666666666663,0.4],"xyz":[0.457041295261284175,0.263571710777921464,0.152516535890499016],"hpluv":[6.08910281061040859,294.807548797669426,58.3745334436288772],"hsluv":[6.08910281061040859,99.9999999999992468,58.3745334436288772]},"#ff4477":{"lch":[58.7233249761193292,129.336052383116169,1.75519751784143763],"luv":[58.7233249761193292,129.275370036155351,3.96145782045869943],"rgb":[1,0.266666666666666663,0.466666666666666674],"xyz":[0.466355308281486081,0.26729731598600226,0.201570337796896926],"hpluv":[1.75519751784143763,279.478426792191101,58.7233249761193292],"hsluv":[1.75519751784143763,99.99999999999946,58.7233249761193292]},"#ff4488":{"lch":[59.1362810655005831,123.398173767481396,356.485857706034096],"luv":[59.1362810655005831,123.16614811103635,-7.56367957014252212],"rgb":[1,0.266666666666666663,0.533333333333333326],"xyz":[0.477495725383429881,0.271753482826779857,0.260243201200469065],"hpluv":[356.485857706034096,264.785408966002421,59.1362810655005831],"hsluv":[356.485857706034096,99.9999999999995595,59.1362810655005831]},"#ff4499":{"lch":[59.6145739069951901,118.37348532064955,350.303370213710309],"luv":[59.6145739069951901,116.682328099077466,-19.9378117238896806],"rgb":[1,0.266666666666666663,0.6],"xyz":[0.490552689492502636,0.276976268470409,0.329009878841587],"hpluv":[350.303370213710309,251.965637795338,59.6145739069951901],"hsluv":[350.303370213710309,99.9999999999997158,59.6145739069951901]},"#ff44aa":{"lch":[60.1587486598557177,114.795436800176844,343.339450530546515],"luv":[60.1587486598557177,109.976338996192666,-32.9119609129858475],"rgb":[1,0.266666666666666663,0.66666666666666663],"xyz":[0.505610382457755136,0.282999345656510137,0.408313728458585601],"hpluv":[343.339450530546515,242.139230170638513,60.1587486598557177],"hsluv":[343.339450530546515,99.9999999999997726,60.1587486598557177]},"#ff44bb":{"lch":[60.768775409955694,113.081121999454581,335.854341209703],"luv":[60.768775409955694,103.187483930843442,-46.2567110015126133],"rgb":[1,0.266666666666666663,0.733333333333333282],"xyz":[0.522747974565091811,0.289854382499444896,0.498571713557227347],"hpluv":[335.854341209703,236.128794952899398,60.768775409955694],"hsluv":[335.854341209703,99.9999999999999716,60.768775409955694]},"#ff44cc":{"lch":[61.4441027606342232,113.457557937670586,328.208302422827],"luv":[61.4441027606342232,96.4354118722023088,-59.7731443895883743],"rgb":[1,0.266666666666666663,0.8],"xyz":[0.542040350008813565,0.297571332676933697,0.600178224227497559],"hpluv":[328.208302422827,234.310931883055929,61.4441027606342232],"hsluv":[328.208302422827,100.000000000000128,61.4441027606342232]},"#ff44dd":{"lch":[62.1837139115479403,115.929787300919912,320.782684481283354],"luv":[62.1837139115479403,89.8170022013310358,-73.2981698216444357],"rgb":[1,0.266666666666666663,0.866666666666666696],"xyz":[0.563558675559447,0.306178662897187204,0.713508072127503556],"hpluv":[320.782684481283354,236.568931830040128,62.1837139115479403],"hsluv":[320.782684481283354,100.000000000000384,62.1837139115479403]},"#ff44ee":{"lch":[62.986184892514558,120.309477517885213,313.888915695758442],"luv":[62.986184892514558,83.4060394378513195,-86.7052649261745643],"rgb":[1,0.266666666666666663,0.933333333333333348],"xyz":[0.587370855825621874,0.315703535003657221,0.83891888819602678],"hpluv":[313.888915695758442,242.378371703623515,62.986184892514558],"hsluv":[313.888915695758442,100.000000000000512,62.986184892514558]},"#ff44ff":{"lch":[63.8497439492436,126.288239910703226,307.715012949243771],"luv":[63.8497439492436,77.2548530724802447,-99.9019880507531468],"rgb":[1,0.266666666666666663,1],"xyz":[0.613541904235453184,0.326171954367589945,0.976753076487808514],"hpluv":[307.715012949243771,250.982289693600563,63.8497439492436],"hsluv":[307.715012949243771,100.000000000000711,63.8497439492436]},"#ff5500":{"lch":[59.6718499915998279,148.630700843778015,19.3008598736449528],"luv":[59.6718499915998279,140.27705963161867,49.1266910591374923],"rgb":[1,0.333333333333333315,0],"xyz":[0.444874372547969188,0.277606152435549203,0.030158676476263746],"hpluv":[19.3008598736449528,316.066414507984518,59.6718499915998279],"hsluv":[19.3008598736449528,100.00000000000226,59.6718499915998279]},"#ff5511":{"lch":[59.7086010657385486,147.530698996531413,18.8803784611224046],"luv":[59.7086010657385486,139.59299153240957,47.7399608445355526],"rgb":[1,0.333333333333333315,0.0666666666666666657],"xyz":[0.445886038047606292,0.278010818635404056,0.0354867814410193758],"hpluv":[18.8803784611224046,313.53413530658878,59.7086010657385486],"hsluv":[18.8803784611224046,99.9999999999992184,59.7086010657385486]},"#ff5522":{"lch":[59.7766335415963255,145.539064184811622,18.0939597274483681],"luv":[59.7766335415963255,138.341936048844929,45.2009727113036],"rgb":[1,0.333333333333333315,0.133333333333333331],"xyz":[0.447761396186083349,0.278760961890794856,0.0453636676369985753],"hpluv":[18.0939597274483681,308.949467849715688,59.7766335415963255],"hsluv":[18.0939597274483681,99.9999999999993,59.7766335415963255]},"#ff5533":{"lch":[59.8883826376776085,142.391759670631302,16.7797766500676033],"luv":[59.8883826376776085,136.328925827546385,41.1076295206398825],"rgb":[1,0.333333333333333315,0.2],"xyz":[0.450849146918541055,0.279996062183778,0.0616258214946097185],"hpluv":[16.7797766500676033,301.704368813615531,59.8883826376776085],"hsluv":[16.7797766500676033,99.9999999999992752,59.8883826376776085]},"#ff5544":{"lch":[60.0491441299879654,138.129067713899872,14.841281480974498],"luv":[60.0491441299879654,133.520956258941027,35.3806951204903228],"rgb":[1,0.333333333333333315,0.266666666666666663],"xyz":[0.45530714216275997,0.281779260281465549,0.0851045964474963501],"hpluv":[14.841281480974498,291.888903616465711,60.0491441299879654],"hsluv":[14.841281480974498,99.9999999999994458,60.0491441299879654]},"#ff5555":{"lch":[60.2631003442631936,132.926854505406169,12.1770506300618191],"luv":[60.2631003442631936,129.936061471805857,28.0386978637829927],"rgb":[1,0.333333333333333315,0.333333333333333315],"xyz":[0.461269556202121955,0.28416422589721041,0.116506643721470265],"hpluv":[12.1770506300618191,279.898508055628838,60.2631003442631936],"hsluv":[12.1770506300618191,99.99999999999946,60.2631003442631936]},"#ff5566":{"lch":[60.5335583680784168,127.091978224389294,8.68145952340772098],"luv":[60.5335583680784168,125.635857711143842,19.1833830742614],"rgb":[1,0.333333333333333315,0.4],"xyz":[0.468854551975630141,0.287198224206613728,0.156454288128614227],"hpluv":[8.68145952340772098,266.416588145649541,60.5335583680784168],"hsluv":[8.68145952340772098,99.9999999999995737,60.5335583680784168]},"#ff5577":{"lch":[60.8630749033481351,121.049870295691591,4.25532383082281918],"luv":[60.8630749033481351,120.716171483201308,8.98203991541407],"rgb":[1,0.333333333333333315,0.466666666666666674],"xyz":[0.478168564995832046,0.290923829414694524,0.205508090035012136],"hpluv":[4.25532383082281918,252.376995060411161,60.8630749033481351],"hsluv":[4.25532383082281918,99.9999999999997158,60.8630749033481351]},"#ff5588":{"lch":[61.2535329118914404,115.319895978664789,358.830706871579594],"luv":[61.2535329118914404,115.295882188952703,-2.35328680810625102],"rgb":[1,0.333333333333333315,0.533333333333333326],"xyz":[0.489308982097775846,0.295379996255472121,0.264180953438584276],"hpluv":[358.830706871579594,238.897951612134108,61.2535329118914404],"hsluv":[358.830706871579594,99.9999999999997868,61.2535329118914404]},"#ff5599":{"lch":[61.7061969251912075,110.472562823261683,352.412124726619879],"luv":[61.7061969251912075,109.505210454219565,-14.5875296097928366],"rgb":[1,0.333333333333333315,0.6],"xyz":[0.502365946206848601,0.300602781899101279,0.332947631079702211],"hpluv":[352.412124726619879,227.177321581811952,61.7061969251912075],"hsluv":[352.412124726619879,99.9999999999998721,61.7061969251912075]},"#ff55aa":{"lch":[62.2217597266614177,107.062368992166355,345.125792918237266],"luv":[62.2217597266614177,103.474894783269619,-27.4826673342684735],"rgb":[1,0.333333333333333315,0.66666666666666663],"xyz":[0.517423639172101102,0.306625859085202401,0.412251480696700812],"hpluv":[345.125792918237266,218.340291577764589,62.2217597266614177],"hsluv":[345.125792918237266,100.000000000000071,62.2217597266614177]},"#ff55bb":{"lch":[62.8003867495987862,105.538663220643826,337.249357740418191],"luv":[62.8003867495987862,97.3274002701012,-40.8140489422941855],"rgb":[1,0.333333333333333315,0.733333333333333282],"xyz":[0.534561231279437776,0.31348089592813716,0.502509465795342614],"hpluv":[337.249357740418191,213.249782655969199,62.8003867495987862],"hsluv":[337.249357740418191,100.000000000000284,62.8003867495987862]},"#ff55cc":{"lch":[63.441761241476712,106.157882562261193,329.184616986090759],"luv":[63.441761241476712,91.1707664760994447,-54.3818661895983837],"rgb":[1,0.333333333333333315,0.8],"xyz":[0.553853606723159531,0.321197846105625961,0.60411597646561277],"hpluv":[329.184616986090759,212.332436268611161,63.441761241476712],"hsluv":[329.184616986090759,100.000000000000441,63.441761241476712]},"#ff55dd":{"lch":[64.1451313698934769,108.938462409011748,321.364198961949114],"luv":[64.1451313698934769,85.0951546537234549,-68.0176686346904518],"rgb":[1,0.333333333333333315,0.866666666666666696],"xyz":[0.575371932273793,0.329805176325879468,0.717445824365618767],"hpluv":[321.364198961949114,215.504760823814451,64.1451313698934769],"hsluv":[321.364198961949114,100.000000000000597,64.1451313698934769]},"#ff55ee":{"lch":[64.9093593252901258,113.686114680552976,314.13939983200612],"luv":[64.9093593252901258,79.1717442713053288,-81.5865649491316418],"rgb":[1,0.333333333333333315,0.933333333333333348],"xyz":[0.599184112539967728,0.339330048432349485,0.842856640434142],"hpluv":[314.13939983200612,222.248801840624651,64.9093593252901258],"hsluv":[314.13939983200612,100.000000000000753,64.9093593252901258]},"#ff55ff":{"lch":[65.7329718140353378,120.074032289562709,307.715012949243885],"luv":[65.7329718140353378,73.4534088756767147,-94.9861566483116633],"rgb":[1,0.333333333333333315,1],"xyz":[0.625355160949799149,0.349798467796282209,0.980690828725923724],"hpluv":[307.715012949243885,231.795582155087629,65.7329718140353378],"hsluv":[307.715012949243885,100.000000000000981,65.7329718140353378]},"#ff6600":{"lch":[62.3097916023938438,138.227046243322206,22.8239093069931798],"luv":[62.3097916023938438,127.404056867086908,53.6183047751569717],"rgb":[1,0.4,0],"xyz":[0.459902430253815608,0.307662267847242543,0.03516802904487909],"hpluv":[22.8239093069931798,281.498480884542573,62.3097916023938438],"hsluv":[22.8239093069931798,100.000000000002359,62.3097916023938438]},"#ff6611":{"lch":[62.344110015411573,137.186959502953613,22.4076195476895244],"luv":[62.344110015411573,126.828705913080029,52.2947532174930245],"rgb":[1,0.4,0.0666666666666666657],"xyz":[0.460914095753452713,0.308066934047097396,0.0404961340096347197],"hpluv":[22.4076195476895244,279.226561167599414,62.344110015411573],"hsluv":[22.4076195476895244,99.9999999999995737,62.344110015411573]},"#ff6622":{"lch":[62.4076477973658257,135.300699513710725,21.6278909170268392],"luv":[62.4076477973658257,125.775148313603225,49.8687412673566115],"rgb":[1,0.4,0.133333333333333331],"xyz":[0.46278945389192977,0.308817077302488197,0.0503730202056139192],"hpluv":[21.6278909170268392,275.106945224361368,62.4076477973658257],"hsluv":[21.6278909170268392,99.9999999999996163,62.4076477973658257]},"#ff6633":{"lch":[62.5120380635233346,132.311574345484274,20.3215228987586443],"luv":[62.5120380635233346,124.076309265494103,45.9502141979128851],"rgb":[1,0.4,0.2],"xyz":[0.465877204624387475,0.310052177595471323,0.0666351740632250555],"hpluv":[20.3215228987586443,268.579898420339646,62.5120380635233346],"hsluv":[20.3215228987586443,99.9999999999995879,62.5120380635233346]},"#ff6644":{"lch":[62.6622654373265675,128.246261163642686,18.3868048135947362],"luv":[62.6622654373265675,121.699120282046835,40.4527826611364603],"rgb":[1,0.4,0.266666666666666663],"xyz":[0.470335199868606391,0.311835375693158889,0.0901139490161117],"hpluv":[18.3868048135947362,259.703586528718,62.6622654373265675],"hsluv":[18.3868048135947362,99.9999999999997726,62.6622654373265675]},"#ff6655":{"lch":[62.8622967709428764,123.257362768531593,15.7125644918265355],"luv":[62.8622967709428764,118.651528823693667,33.3795174388964284],"rgb":[1,0.4,0.333333333333333315],"xyz":[0.476297613907968376,0.31422034130890375,0.121515996290085609],"hpluv":[15.7125644918265355,248.806632458920831,62.8622967709428764],"hsluv":[15.7125644918265355,99.9999999999997158,62.8622967709428764]},"#ff6666":{"lch":[63.1153061541487119,117.623502253606588,12.1770506300618742],"luv":[63.1153061541487119,114.97702760078576,24.8107115273291683],"rgb":[1,0.4,0.4],"xyz":[0.483882609681476561,0.317254339618307069,0.161463640697229571],"hpluv":[12.1770506300618742,236.482353971627703,63.1153061541487119],"hsluv":[12.1770506300618742,99.9999999999999,63.1153061541487119]},"#ff6677":{"lch":[63.4237926928396121,111.744324598031497,7.65713975886231157],"luv":[63.4237926928396121,110.747917341816802,14.8893547314965815],"rgb":[1,0.4,0.466666666666666674],"xyz":[0.493196622701678467,0.320979944826387864,0.21051744260362748],"hpluv":[7.65713975886231157,223.569519019308729,63.4237926928396121],"hsluv":[7.65713975886231157,100.000000000000071,63.4237926928396121]},"#ff6688":{"lch":[63.7896518301749751,106.125321016318935,2.05404070639815961],"luv":[63.7896518301749751,106.057131857198982,3.80375380925921824],"rgb":[1,0.4,0.533333333333333326],"xyz":[0.504337039803622322,0.325436111667165462,0.26919030600719962],"hpluv":[2.05404070639815961,211.109662635719985,63.7896518301749751],"hsluv":[2.05404070639815961,100.000000000000128,63.7896518301749751]},"#ff6699":{"lch":[64.2142253202301276,101.344202045456129,355.341285926877504],"luv":[64.2142253202301276,101.009378125853075,-8.23121004826552394],"rgb":[1,0.4,0.6],"xyz":[0.517394003912695,0.330658897310794619,0.337956983648317555],"hpluv":[355.341285926877504,200.265890662959123,64.2142253202301276],"hsluv":[355.341285926877504,100.000000000000199,64.2142253202301276]},"#ff66aa":{"lch":[64.6983418323177233,97.9876087444390436,347.629516841099075],"luv":[64.6983418323177233,95.7126081968365838,-20.9920961224008664],"rgb":[1,0.4,0.66666666666666663],"xyz":[0.532451696877947578,0.336681974496895742,0.417260833265316156],"hpluv":[347.629516841099075,192.184047560801417,64.6983418323177233],"hsluv":[347.629516841099075,100.000000000000441,64.6983418323177233]},"#ff66bb":{"lch":[65.2423543089962408,96.5541832870936787,339.215698562051898],"luv":[65.2423543089962408,90.270720679111,-34.2623306024503123],"rgb":[1,0.4,0.733333333333333282],"xyz":[0.549589288985284141,0.3435370113398305,0.507518818363957847],"hpluv":[339.215698562051898,187.793604034801348,65.2423543089962408],"hsluv":[339.215698562051898,100.000000000000597,65.2423543089962408]},"#ff66cc":{"lch":[65.8461771980182533,97.3465701370285,330.562118792095362],"luv":[65.8461771980182533,84.7780628468697159,-47.8438583036069218],"rgb":[1,0.4,0.8],"xyz":[0.568881664429005895,0.351253961517319302,0.609125329034228],"hpluv":[330.562118792095362,187.598522894675455,65.8461771980182533],"hsluv":[330.562118792095362,100.000000000000711,65.8461771980182533]},"#ff66dd":{"lch":[66.5093249736543157,100.405273498350255,322.181562409870594],"luv":[66.5093249736543157,79.3159229397089831,-61.5646271368605298],"rgb":[1,0.4,0.866666666666666696],"xyz":[0.590399989979639495,0.359861291737572808,0.722455176934234],"hpluv":[322.181562409870594,191.563741116159406,66.5093249736543157],"hsluv":[322.181562409870594,100.000000000000952,66.5093249736543157]},"#ff66ee":{"lch":[67.2309523334132706,105.527911758853008,314.488878023448478],"luv":[67.2309523334132706,73.9508789773533408,-75.2821868615750702],"rgb":[1,0.4,0.933333333333333348],"xyz":[0.614212170245814204,0.369386163844042825,0.847865993002757223],"hpluv":[314.488878023448478,199.176184031939982,67.2309523334132706],"hsluv":[314.488878023448478,100.000000000001066,67.2309523334132706]},"#ff66ff":{"lch":[68.0098958254125137,112.360313920932768,307.715012949244056],"luv":[68.0098958254125137,68.7346624616611592,-88.8841173702707437],"rgb":[1,0.4,1],"xyz":[0.640383218655645625,0.379854583207975549,0.985700181294539179],"hpluv":[307.715012949244056,209.642901019847784,68.0098958254125137],"hsluv":[307.715012949244056,100.000000000001421,68.0098958254125137]},"#ff7700":{"lch":[65.3236824647912755,127.817378582796977,27.3102887077963814],"luv":[65.3236824647912755,113.570196302134065,58.6437786953806466],"rgb":[1,0.466666666666666674,0],"xyz":[0.478356168307233265,0.344569743954078356,0.0413192750626848],"hpluv":[27.3102887077963814,248.289625700463205,65.3236824647912755],"hsluv":[27.3102887077963814,100.00000000000226,65.3236824647912755]},"#ff7711":{"lch":[65.3555057958206476,126.824695098806032,26.9045059733925385],"luv":[65.3555057958206476,113.097436843789765,57.3887886809793],"rgb":[1,0.466666666666666674,0.0666666666666666657],"xyz":[0.479367833806870369,0.344974410153933209,0.0466473800274404271],"hpluv":[26.9045059733925385,246.24134425049084,65.3555057958206476],"hsluv":[26.9045059733925385,99.9999999999999716,65.3555057958206476]},"#ff7722":{"lch":[65.4144320044565291,125.020679344179442,26.1430666348463],"luv":[65.4144320044565291,112.230643754756542,55.0858681158159058],"rgb":[1,0.466666666666666674,0.133333333333333331],"xyz":[0.481243191945347426,0.345724553409324,0.0565242662234196266],"hpluv":[26.1430666348463,242.520026060215031,65.4144320044565291],"hsluv":[26.1430666348463,100.000000000000156,65.4144320044565291]},"#ff7733":{"lch":[65.511267747206432,122.151716277204869,24.8632302030062533],"luv":[65.511267747206432,110.829965834679456,51.3591322215488688],"rgb":[1,0.466666666666666674,0.2],"xyz":[0.484330942677805132,0.346959653702307136,0.0727864200810307699],"hpluv":[24.8632302030062533,236.604443239770575,65.511267747206432],"hsluv":[24.8632302030062533,100.000000000000128,65.511267747206432]},"#ff7744":{"lch":[65.6506715027637853,118.22870540382597,22.9581907744090898],"luv":[65.6506715027637853,108.863777518532288,46.1162089276663139],"rgb":[1,0.466666666666666674,0.266666666666666663],"xyz":[0.488788937922024047,0.348742851799994702,0.0962651950339174084],"hpluv":[22.9581907744090898,228.519406804146513,65.6506715027637853],"hsluv":[22.9581907744090898,100.000000000000199,65.6506715027637853]},"#ff7755":{"lch":[65.8363783536997857,113.378413750733145,20.3056908730066645],"luv":[65.8363783536997857,106.332452226692425,39.3455754576116092],"rgb":[1,0.466666666666666674,0.333333333333333315],"xyz":[0.494751351961386032,0.351127817415739563,0.12766724230789131],"hpluv":[20.3056908730066645,218.526329281612362,65.8363783536997857],"hsluv":[20.3056908730066645,100.000000000000171,65.8363783536997857]},"#ff7766":{"lch":[66.0714111968285351,107.847817312906827,16.7638759706376135],"luv":[66.0714111968285351,103.264450834403533,31.1063481146080676],"rgb":[1,0.466666666666666674,0.4],"xyz":[0.502336347734894217,0.354161815725142881,0.167614886715035272],"hpluv":[16.7638759706376135,207.127185394700234,66.0714111968285351],"hsluv":[16.7638759706376135,100.000000000000426,66.0714111968285351]},"#ff7777":{"lch":[66.3581913431115851,102.006782949974053,12.1770506300619488],"luv":[66.3581913431115851,99.7116772923406671,21.5166256497442419],"rgb":[1,0.466666666666666674,0.466666666666666674],"xyz":[0.511650360755096067,0.357887420933223677,0.216668688621433181],"hpluv":[12.1770506300619488,195.062523033846361,66.3581913431115851],"hsluv":[12.1770506300619488,100.000000000000355,66.3581913431115851]},"#ff7788":{"lch":[66.6986047917809,96.3441833198397291,6.39999172914420456],"luv":[66.6986047917809,95.7437601312525,10.7393694179903871],"rgb":[1,0.466666666666666674,0.533333333333333326],"xyz":[0.52279077785704,0.362343587774001274,0.275341552025005376],"hpluv":[6.39999172914420456,183.293927388427107,66.6986047917809],"hsluv":[6.39999172914420456,100.000000000000639,66.6986047917809]},"#ff7799":{"lch":[67.0940474565320244,91.4474963932601,359.352586865695173],"luv":[67.0940474565320244,91.4416585161261679,-1.0332881570442134],"rgb":[1,0.466666666666666674,0.6],"xyz":[0.535847741966112623,0.367566373417630432,0.344108229666123255],"hpluv":[359.352586865695173,172.952623850798517,67.0940474565320244],"hsluv":[359.352586865695173,100.000000000000782,67.0940474565320244]},"#ff77aa":{"lch":[67.5454605183692,87.9484746627524,351.107126776790835],"luv":[67.5454605183692,86.8912550098467449,-13.5957345634056814],"rgb":[1,0.466666666666666674,0.66666666666666663],"xyz":[0.550905434931365234,0.373589450603731554,0.423412079283121856],"hpluv":[351.107126776790835,165.223368139110704,67.5454605183692],"hsluv":[351.107126776790835,100.000000000000938,67.5454605183692]},"#ff77bb":{"lch":[68.0533617234635244,86.4195813509952,341.973592157308417],"luv":[68.0533617234635244,82.1775887588569,-26.7429980866295693],"rgb":[1,0.466666666666666674,0.733333333333333282],"xyz":[0.568043027038701798,0.380444487446666313,0.513670064381763658],"hpluv":[341.973592157308417,161.139458954487083,68.0533617234635244],"hsluv":[341.973592157308417,100.000000000001037,68.0533617234635244]},"#ff77cc":{"lch":[68.6178757233526682,87.2373067072756214,332.49967924393593],"luv":[68.6178757233526682,77.3802105983984347,-40.2821385887937],"rgb":[1,0.466666666666666674,0.8],"xyz":[0.587335402482423552,0.388161437624155115,0.615276575052033814],"hpluv":[332.49967924393593,161.325977991170333,68.6178757233526682],"hsluv":[332.49967924393593,100.000000000001265,68.6178757233526682]},"#ff77dd":{"lch":[69.238765020261809,90.480647802514838,323.326201907778],"luv":[69.238765020261809,72.5699004301545756,-54.0403291840472],"rgb":[1,0.466666666666666674,0.866666666666666696],"xyz":[0.608853728033057151,0.396768767844408621,0.728606422952039812],"hpluv":[323.326201907778,165.823361543811586,69.238765020261809],"hsluv":[323.326201907778,100.00000000000145,69.238765020261809]},"#ff77ee":{"lch":[69.9154621504300593,95.9376886025569604,314.973456368277198],"luv":[69.9154621504300593,67.8067552495039791,-67.8696105553513149],"rgb":[1,0.466666666666666674,0.933333333333333348],"xyz":[0.632665908299231861,0.406293639950878638,0.854017239020563],"hpluv":[314.973456368277198,174.122680701596721,69.9154621504300593],"hsluv":[314.973456368277198,100.000000000001535,69.9154621504300593]},"#ff77ff":{"lch":[70.6471031550122,103.213892868752552,307.715012949244283],"luv":[70.6471031550122,63.1394826173239494,-81.6487196221654],"rgb":[1,0.466666666666666674,1],"xyz":[0.658836956709063282,0.416762059314811362,0.99185142731234488],"hpluv":[307.715012949244283,185.388643374650655,70.6471031550122],"hsluv":[307.715012949244283,100.000000000001975,70.6471031550122]},"#ff8800":{"lch":[68.6580440198892603,118.150361410828182,32.8458067740872153],"luv":[68.6580440198892603,99.2620471866307383,64.0823992202883375],"rgb":[1,0.533333333333333326,0],"xyz":[0.500428538032203774,0.388714483404019873,0.0486767316376747472],"hpluv":[32.8458067740872153,218.364961888913399,68.6580440198892603],"hsluv":[32.8458067740872153,100.000000000002245,68.6580440198892603]},"#ff8811":{"lch":[68.6874112197728408,117.19102013872596,32.4606037779481582],"luv":[68.6874112197728408,98.8811760474647485,62.89871401408422],"rgb":[1,0.533333333333333326,0.0666666666666666657],"xyz":[0.501440203531840933,0.389119149603874726,0.0540048366024303769],"hpluv":[32.4606037779481582,216.499308154785638,68.6874112197728408],"hsluv":[32.4606037779481582,100.000000000000739,68.6874112197728408]},"#ff8822":{"lch":[68.7417963707939492,115.443262249268372,31.7362513605757321],"luv":[68.7417963707939492,98.1820090833864754,60.724294076614548],"rgb":[1,0.533333333333333326,0.133333333333333331],"xyz":[0.503315561670317879,0.389869292859265526,0.0638817227984095765],"hpluv":[31.7362513605757321,213.101761826290613,68.7417963707939492],"hsluv":[31.7362513605757321,100.000000000000668,68.7417963707939492]},"#ff8833":{"lch":[68.8311889682804292,112.651741292777714,30.5141745142023382],"luv":[68.8311889682804292,97.0498776480180823,57.1990914683060439],"rgb":[1,0.533333333333333326,0.2],"xyz":[0.506403312402775696,0.391104393152248653,0.0801438766560207128],"hpluv":[30.5141745142023382,207.678703624478942,68.8311889682804292],"hsluv":[30.5141745142023382,100.000000000000824,68.8311889682804292]},"#ff8844":{"lch":[68.9599197258043688,108.808998086617962,28.6842020071901302],"luv":[68.9599197258043688,95.4557990826346554,52.2263198599069725],"rgb":[1,0.533333333333333326,0.266666666666666663],"xyz":[0.510861307646994556,0.392887591249936219,0.103622651608907351],"hpluv":[28.6842020071901302,200.2199693629492,68.9599197258043688],"hsluv":[28.6842020071901302,100.000000000000838,68.9599197258043688]},"#ff8855":{"lch":[69.1314852187197602,104.012526361958052,26.1137258191789492],"luv":[69.1314852187197602,93.395152113439849,45.7815596272609682],"rgb":[1,0.533333333333333326,0.333333333333333315],"xyz":[0.516823721686356485,0.39527255686568108,0.135024698882881267],"hpluv":[26.1137258191789492,190.918970683811096,69.1314852187197602],"hsluv":[26.1137258191789492,100.000000000000867,69.1314852187197602]},"#ff8866":{"lch":[69.3487452092138881,98.4723154092605171,22.6389332988698087],"luv":[69.3487452092138881,90.8849122177262529,37.9042165627661802],"rgb":[1,0.533333333333333326,0.4],"xyz":[0.524408717459864726,0.398306555175084398,0.174972343290025228],"hpluv":[22.6389332988698087,180.183437843423292,69.3487452092138881],"hsluv":[22.6389332988698087,100.000000000001066,69.3487452092138881]},"#ff8877":{"lch":[69.6140261744794344,92.5206854303452246,18.0637242730473773],"luv":[69.6140261744794344,87.9605480867009248,28.6883114314535526],"rgb":[1,0.533333333333333326,0.466666666666666674],"xyz":[0.533722730480066576,0.402032160383165194,0.224026145196423138],"hpluv":[18.0637242730473773,168.648085666048672,69.6140261744794344],"hsluv":[18.0637242730473773,100.000000000001108,69.6140261744794344]},"#ff8888":{"lch":[69.9291829132988596,86.6211090413054,12.1770506300619186],"luv":[69.9291829132988596,84.672173963834382,18.2712749359175248],"rgb":[1,0.533333333333333326,0.533333333333333326],"xyz":[0.544863147582010487,0.406488327223942791,0.282699008599995305],"hpluv":[12.1770506300619186,157.182652238587849,69.9291829132988596],"hsluv":[12.1770506300619186,100.000000000001251,69.9291829132988596]},"#ff8899":{"lch":[70.29563969089034,81.3665448969888274,4.80888772903122597],"luv":[70.29563969089034,81.0801238487794791,6.82115423812421362],"rgb":[1,0.533333333333333326,0.6],"xyz":[0.557920111691083132,0.411711112867571949,0.351465686241113184],"hpluv":[4.80888772903122597,146.878021536398364,70.29563969089034],"hsluv":[4.80888772903122597,100.00000000000135,70.29563969089034]},"#ff88aa":{"lch":[70.7144212664750427,77.4442353273614827,355.944797831634332],"luv":[70.7144212664750427,77.2503443699940533,-5.47666688388778589],"rgb":[1,0.533333333333333326,0.66666666666666663],"xyz":[0.572977804656335743,0.417734190053673071,0.430769535858111841],"hpluv":[355.944797831634332,138.969799542374091,70.7144212664750427],"hsluv":[355.944797831634332,100.000000000001648,70.7144212664750427]},"#ff88bb":{"lch":[71.1861792611668847,75.5334875912487718,345.875835641341098],"luv":[71.1861792611668847,73.2500487000805,-18.431986141845023],"rgb":[1,0.533333333333333326,0.733333333333333282],"xyz":[0.590115396763672306,0.42458922689660783,0.521027520956753532],"hpluv":[345.875835641341098,134.642814203514433,71.1861792611668847],"hsluv":[345.875835641341098,100.000000000001776,71.1861792611668847]},"#ff88cc":{"lch":[71.711216864189268,76.1313589407537563,335.260476444218114],"luv":[71.711216864189268,69.1440007334156377,-31.8604924121286039],"rgb":[1,0.533333333333333326,0.8],"xyz":[0.609407772207394061,0.432306177074096631,0.622634031627023687],"hpluv":[335.260476444218114,134.714956877670915,71.711216864189268],"hsluv":[335.260476444218114,100.000000000001933,71.711216864189268]},"#ff88dd":{"lch":[72.2895135005839649,79.3885839073469413,324.950129439258774],"luv":[72.2895135005839649,64.9916618916399784,-45.5920074067441803],"rgb":[1,0.533333333333333326,0.866666666666666696],"xyz":[0.63092609775802766,0.440913507294350138,0.735963879527029685],"hpluv":[324.950129439258774,139.354847315526115,72.2895135005839649],"hsluv":[324.950129439258774,100.000000000002245,72.2895135005839649]},"#ff88ee":{"lch":[72.9207502525545124,85.0855243828499,315.651995307064169],"luv":[72.9207502525545124,60.845281511842515,-59.4760302748021203],"rgb":[1,0.533333333333333326,0.933333333333333348],"xyz":[0.654738278024202369,0.450438379400820155,0.861374695595552908],"hpluv":[315.651995307064169,148.062090862911901,72.9207502525545124],"hsluv":[315.651995307064169,100.000000000002444,72.9207502525545124]},"#ff88ff":{"lch":[73.6043362991539709,92.7672005781522842,307.715012949244624],"luv":[73.6043362991539709,56.7488822053271349,-73.3847250560567375],"rgb":[1,0.533333333333333326,1],"xyz":[0.68090932643403379,0.460906798764752879,0.999208883887334753],"hpluv":[307.715012949244624,159.930161835956909,73.6043362991539709],"hsluv":[307.715012949244624,100.000000000002771,73.6043362991539709]},"#ff9900":{"lch":[72.2588108283115389,109.907462524380705,39.4434130396340095],"luv":[72.2588108283115389,84.8763034831777077,69.8259509464759418],"rgb":[1,0.6,0],"xyz":[0.526298138484671219,0.440453684308955595,0.057299931788497],"hpluv":[39.4434130396340095,193.008172097547572,72.2588108283115389],"hsluv":[39.4434130396340095,100.000000000002288,72.2588108283115389]},"#ff9911":{"lch":[72.2858317740783889,108.970035258541955,39.0927051304156805],"luv":[72.2858317740783889,84.5745536570817791,68.7139975401902348],"rgb":[1,0.6,0.0666666666666666657],"xyz":[0.527309803984308378,0.440858350508810448,0.0626280367532526389],"hpluv":[39.0927051304156805,191.2904264008464,72.2858317740783889],"hsluv":[39.0927051304156805,100.000000000001506,72.2858317740783889]},"#ff9922":{"lch":[72.3358777005795304,107.257428554778556,38.4317580680427469],"luv":[72.3358777005795304,84.0200042697796,66.6692947517044274],"rgb":[1,0.6,0.133333333333333331],"xyz":[0.529185162122785324,0.441608493764201249,0.0725049229492318315],"hpluv":[38.4317580680427469,188.15378179700545,72.3358777005795304],"hsluv":[38.4317580680427469,100.00000000000145,72.3358777005795304]},"#ff9933":{"lch":[72.418154282067718,104.508625212907305,37.3122251519614778],"luv":[72.418154282067718,83.1203251002183237,63.3487513620113845],"rgb":[1,0.6,0.2],"xyz":[0.532272912855243141,0.442843594057184375,0.0887670768068429816],"hpluv":[37.3122251519614778,183.123470124205028,72.418154282067718],"hsluv":[37.3122251519614778,100.00000000000162,72.418154282067718]},"#ff9944":{"lch":[72.5366731246789556,100.695423976150749,35.6250099256014607],"luv":[72.5366731246789556,81.8499313718691326,58.6528528219818952],"rgb":[1,0.6,0.266666666666666663],"xyz":[0.536730908099462,0.444626792154871942,0.11224585175972962],"hpluv":[35.6250099256014607,176.153561585765658,72.5366731246789556],"hsluv":[35.6250099256014607,100.000000000001748,72.5366731246789556]},"#ff9955":{"lch":[72.6946936633514582,95.8821930466240673,33.2320443565807508],"luv":[72.6946936633514582,80.201421842029859,52.5464259293328269],"rgb":[1,0.6,0.333333333333333315],"xyz":[0.54269332213882393,0.447011757770616802,0.143647899033703508],"hpluv":[33.2320443565807508,167.368827825995851,72.6946936633514582],"hsluv":[33.2320443565807508,100.000000000001705,72.6946936633514582]},"#ff9966":{"lch":[72.8949069034106,90.2347392462793749,29.9516480142673025],"luv":[72.8949069034106,78.1836232693519406,45.0514064077924345],"rgb":[1,0.6,0.4],"xyz":[0.550278317912332171,0.450045756080020121,0.183595543440847497],"hpluv":[29.9516480142673025,157.078197331028889,72.8949069034106],"hsluv":[29.9516480142673025,100.000000000001819,72.8949069034106]},"#ff9977":{"lch":[73.1395321193821,84.0351966301436,25.5464816978182121],"luv":[73.1395321193821,75.8195571045914,36.2396058633438045],"rgb":[1,0.6,0.466666666666666674],"xyz":[0.559592330932534,0.453771361288100916,0.232649345347245406],"hpluv":[25.5464816978182121,145.796926659053128,73.1395321193821],"hsluv":[25.5464816978182121,100.000000000002018,73.1395321193821]},"#ff9988":{"lch":[73.430374185650777,77.702838567593929,19.7240568661095921],"luv":[73.430374185650777,73.1439295084068419,26.2239718107454713],"rgb":[1,0.6,0.533333333333333326],"xyz":[0.570732748034477932,0.458227528128878514,0.291322208750817546],"hpluv":[19.7240568661095921,134.276641294628575,73.430374185650777],"hsluv":[19.7240568661095921,100.000000000002203,73.430374185650777]},"#ff9999":{"lch":[73.76886125649402,71.8160022700114098,12.1770506300620251],"luv":[73.76886125649402,70.2001752793754,15.1483851545719261],"rgb":[1,0.6,0.6],"xyz":[0.583789712143550577,0.463450313772507672,0.360088886391935481],"hpluv":[12.1770506300620251,123.534275619879125,73.76886125649402],"hsluv":[12.1770506300620251,100.000000000002331,73.76886125649402]},"#ff99aa":{"lch":[74.1560723225582592,67.1124973440613,2.7130535693684088],"luv":[74.1560723225582592,67.0372720786985923,3.17670458229478481],"rgb":[1,0.6,0.66666666666666663],"xyz":[0.598847405108803188,0.469473390958608794,0.439392736008934082],"hpluv":[2.7130535693684088,114.840746523486033,74.1560723225582592],"hsluv":[2.7130535693684088,100.00000000000253,74.1560723225582592]},"#ff99bb":{"lch":[74.5927597146433925,64.4136927281220864,351.502648062184],"luv":[74.5927597146433925,63.7066038913843187,-9.51800564715024322],"rgb":[1,0.6,0.733333333333333282],"xyz":[0.615984997216139751,0.476328427801543552,0.529650721107575828],"hpluv":[351.502648062184,109.577363966618833,74.5927597146433925],"hsluv":[351.502648062184,100.000000000002615,74.5927597146433925]},"#ff99cc":{"lch":[75.0793694015197,64.4152606478183145,339.305696269483292],"luv":[75.0793694015197,60.259134450288677,-22.7631834247409977],"rgb":[1,0.6,0.8],"xyz":[0.635277372659861506,0.484045377979032354,0.631257231777846],"hpluv":[339.305696269483292,108.869813431806975,75.0793694015197],"hsluv":[339.305696269483292,100.000000000002871,75.0793694015197]},"#ff99dd":{"lch":[75.6160606971696296,67.4118390527965232,327.324068761847229],"luv":[75.6160606971696296,56.7430830794555,-36.3947601601954887],"rgb":[1,0.6,0.866666666666666696],"xyz":[0.656795698210495105,0.49265270819928586,0.744587079677852],"hpluv":[327.324068761847229,113.125745227459021,75.6160606971696296],"hsluv":[327.324068761847229,100.00000000000324,75.6160606971696296]},"#ff99ee":{"lch":[76.202726253448489,73.1905233351813393,316.627151984536795],"luv":[76.202726253448489,53.2022056350908201,-50.2630880631028845],"rgb":[1,0.6,0.933333333333333348],"xyz":[0.680607878476669814,0.502177580305755877,0.869997895746375205],"hpluv":[316.627151984536795,123.107716827744753,76.202726253448489],"hsluv":[316.627151984536795,100.000000000003524,76.202726253448489]},"#ff99ff":{"lch":[76.8390127436129,81.2030526869262275,307.715012949245],"luv":[76.8390127436129,49.6746958291708154,-64.2367524082209229],"rgb":[1,0.6,1],"xyz":[0.706778926886501235,0.512645999669688601,1.00783208403815694],"hpluv":[307.715012949245,141.150312559224801,76.8390127436129],"hsluv":[307.715012949245,100.000000000003752,76.8390127436129]},"#ee0000":{"lch":[49.7142799595632,167.190689697178925,12.1770506300617765],"luv":[49.7142799595632,163.428976145092918,35.2660811203203934],"rgb":[0.933333333333333348,0,0],"xyz":[0.352591085030832,0.181804778219026603,0.0165277071108199],"hpluv":[12.1770506300617765,426.746789183125202,49.7142799595632],"hsluv":[12.1770506300617765,100.000000000002217,49.7142799595632]},"#ee0011":{"lch":[49.7630000621001756,165.722449822455,11.6881730851639158],"luv":[49.7630000621001756,162.286136628676445,33.5729092170260728],"rgb":[0.933333333333333348,0,0.0666666666666666657],"xyz":[0.353602750530469079,0.182209444418881455,0.0218558120755755342],"hpluv":[11.6881730851639158,422.585038037937124,49.7630000621001756],"hsluv":[11.6881730851639158,99.9999999999963762,49.7630000621001756]},"#ee0022":{"lch":[49.8531236873270558,163.0858535413212,10.7756858750078184],"luv":[49.8531236873270558,160.210108449799208,30.4912573667411486],"rgb":[0.933333333333333348,0,0.133333333333333331],"xyz":[0.355478108668946136,0.182959587674272284,0.0317326982715547268],"hpluv":[10.7756858750078184,415.110044299310516,49.8531236873270558],"hsluv":[10.7756858750078184,99.9999999999964473,49.8531236873270558]},"#ee0033":{"lch":[50.000975779064234,158.977402767524836,9.25647316775448559],"luv":[50.000975779064234,156.907230803998146,25.5721628363475],"rgb":[0.933333333333333348,0,0.2],"xyz":[0.358565859401403841,0.184194687967255383,0.047994852129165877],"hpluv":[9.25647316775448559,403.456061197389261,50.000975779064234],"hsluv":[9.25647316775448559,99.9999999999965183,50.000975779064234]},"#ee0044":{"lch":[50.2132784041556164,153.529579514286212,7.02933300215353],"luv":[50.2132784041556164,152.375594335021788,18.7885613308314312],"rgb":[0.933333333333333348,0,0.266666666666666663],"xyz":[0.363023854645622757,0.185977886064942977,0.0714736270820525155],"hpluv":[7.02933300215353,387.983100931209492,50.2132784041556164],"hsluv":[7.02933300215353,99.9999999999966462,50.2132784041556164]},"#ee0055":{"lch":[50.4951150037793326,147.071833727726926,3.99754465361350508],"luv":[50.4951150037793326,146.714013644902735,10.2529252527975352],"rgb":[0.933333333333333348,0,0.333333333333333315],"xyz":[0.368986268684984742,0.188362851680687809,0.102875674356026417],"hpluv":[3.99754465361350508,369.589367027053072,50.4951150037793326],"hsluv":[3.99754465361350508,99.999999999996831,50.4951150037793326]},"#ee0066":{"lch":[50.8502318550204109,140.098840030056522,0.0757634158231174915],"luv":[50.8502318550204109,140.0987175463531,0.185255592479522613],"rgb":[0.933333333333333348,0,0.4],"xyz":[0.376571264458492927,0.1913968499900911,0.142823318763170393],"hpluv":[0.0757634158231174915,349.60765112382461,50.8502318550204109],"hsluv":[0.0757634158231174915,99.9999999999970584,50.8502318550204109]},"#ee0077":{"lch":[51.2812017254514956,133.219993530026585,355.209470699020642],"luv":[51.2812017254514956,132.754613083251769,-11.1256182415379214],"rgb":[0.933333333333333348,0,0.466666666666666674],"xyz":[0.385885277478694833,0.195122455198171924,0.191877120669568302],"hpluv":[355.209470699020642,329.648072606093592,51.2812017254514956],"hsluv":[355.209470699020642,99.9999999999973284,51.2812017254514956]},"#ee0088":{"lch":[51.7895361854883163,127.090944021268115,349.407446028193533],"luv":[51.7895361854883163,124.925218603260163,-23.3623160055840167],"rgb":[0.933333333333333348,0,0.533333333333333326],"xyz":[0.397025694580638633,0.199578622038949521,0.250549984073140442],"hpluv":[349.407446028193533,311.395197619459395,51.7895361854883163],"hsluv":[349.407446028193533,99.9999999999974705,51.7895361854883163]},"#ee0099":{"lch":[52.3757812732210652,122.329563392952366,342.780178840499048],"luv":[52.3757812732210652,116.846263825073436,-36.2142611415956637],"rgb":[0.933333333333333348,0,0.6],"xyz":[0.410082658689711388,0.204801407682578679,0.319316661714258376],"hpluv":[342.780178840499048,296.374093031221,52.3757812732210652],"hsluv":[342.780178840499048,99.9999999999978,52.3757812732210652]},"#ee00aa":{"lch":[53.0396114453995722,119.424239873739239,335.563712743666827],"luv":[53.0396114453995722,108.726436909364494,-49.403552366347],"rgb":[0.933333333333333348,0,0.66666666666666663],"xyz":[0.425140351654963888,0.210824484868679773,0.398620511331257],"hpluv":[335.563712743666827,285.713971708863653,53.0396114453995722],"hsluv":[335.563712743666827,99.999999999998,53.0396114453995722]},"#ee00bb":{"lch":[53.779927529436435,118.655378520732356,328.101249142938343],"luv":[53.779927529436435,100.736423933687789,-62.6998544252744381],"rgb":[0.933333333333333348,0,0.733333333333333282],"xyz":[0.442277943762300563,0.217679521711614532,0.488878496429898723],"hpluv":[328.101249142938343,279.966806180862307,53.779927529436435],"hsluv":[328.101249142938343,99.9999999999982094,53.779927529436435]},"#ee00cc":{"lch":[54.5949595671901,120.061129768120921,320.773339602207614],"luv":[54.5949595671901,93.0053918954961,-75.9254368414351575],"rgb":[0.933333333333333348,0,0.8],"xyz":[0.461570319206022317,0.225396471889103334,0.590485007100168824],"hpluv":[320.773339602207614,279.054611328209262,54.5949595671901],"hsluv":[320.773339602207614,99.9999999999984,54.5949595671901]},"#ee00dd":{"lch":[55.4823728661035744,123.466264594666441,313.907226483092529],"luv":[55.4823728661035744,85.6229535549924634,-88.9529556421808252],"rgb":[0.933333333333333348,0,0.866666666666666696],"xyz":[0.483088644756655805,0.234003802109356868,0.703814855000174822],"hpluv":[313.907226483092529,282.379138449157608,55.4823728661035744],"hsluv":[313.907226483092529,99.9999999999986215,55.4823728661035744]},"#ee00ee":{"lch":[56.4393743497109597,128.559742977308588,307.715012949243601],"luv":[56.4393743497109597,78.644409501394918,-101.698890694877051],"rgb":[0.933333333333333348,0,0.933333333333333348],"xyz":[0.506900825022830626,0.243528674215826912,0.829225671068698],"hpluv":[307.715012949243601,289.042783730483393,56.4393743497109597],"hsluv":[307.715012949243601,99.9999999999988489,56.4393743497109597]},"#ee00ff":{"lch":[57.4628159598150745,134.982567880189606,302.284502363601803],"luv":[57.4628159598150745,72.0973885084188879,-114.115118199983058],"rgb":[0.933333333333333348,0,1],"xyz":[0.533071873432661936,0.253997093579759636,0.96705985936047989],"hpluv":[302.284502363601803,298.078126285043766,57.4628159598150745],"hsluv":[302.284502363601803,99.9999999999989484,57.4628159598150745]},"#ee1100":{"lch":[50.1937733395544683,164.746074066243921,12.6667024036514828],"luv":[50.1937733395544683,160.736507742479517,36.1253927174799117],"rgb":[0.933333333333333348,0.0666666666666666657,0],"xyz":[0.354595485291760382,0.185813578740883473,0.0171958405311293527],"hpluv":[12.6667024036514828,416.489977947977081,50.1937733395544683],"hsluv":[12.6667024036514828,100.000000000002245,50.1937733395544683]},"#ee1111":{"lch":[50.2417909300708345,163.305921695383518,12.1770506300617907],"luv":[50.2417909300708345,159.631613634988071,34.4466542507197317],"rgb":[0.933333333333333348,0.0666666666666666657,0.0666666666666666657],"xyz":[0.355607150791397486,0.186218244940738326,0.0225239454958849825],"hpluv":[12.1770506300617907,412.454596338970589,50.2417909300708345],"hsluv":[12.1770506300617907,96.6508962208003197,50.2417909300708345]},"#ee1122":{"lch":[50.3306190654122219,160.718934991358793,11.2629010575952293],"luv":[50.3306190654122219,157.623701713525833,31.390201064696047],"rgb":[0.933333333333333348,0.0666666666666666657,0.133333333333333331],"xyz":[0.357482508929874543,0.186968388196129154,0.032400831691864182],"hpluv":[11.2629010575952293,405.204351077732667,50.3306190654122219],"hsluv":[11.2629010575952293,96.6948337079543592,50.3306190654122219]},"#ee1133":{"lch":[50.4763571232054318,156.685700791802191,9.74029685215880647],"luv":[50.4763571232054318,154.427033260746356,26.5084935615454427],"rgb":[0.933333333333333348,0.0666666666666666657,0.2],"xyz":[0.360570259662332249,0.188203488489112253,0.0486629855494753252],"hpluv":[9.74029685215880647,393.895198182016713,50.4763571232054318],"hsluv":[9.74029685215880647,96.7647175585846,50.4763571232054318]},"#ee1144":{"lch":[50.6856484752898382,151.333831494518165,7.50679337730589413],"luv":[50.6856484752898382,150.036806479185287,19.7708183022028514],"rgb":[0.933333333333333348,0.0666666666666666657,0.266666666666666663],"xyz":[0.365028254906551164,0.189986686586799847,0.0721417605023619568],"hpluv":[7.50679337730589413,378.870112575267399,50.6856484752898382],"hsluv":[7.50679337730589413,96.8605546889772455,50.6856484752898382]},"#ee1155":{"lch":[50.9635312364098496,144.984673036864649,4.46374659640210858],"luv":[50.9635312364098496,144.544902405536135,11.283909082431693],"rgb":[0.933333333333333348,0.0666666666666666657,0.333333333333333315],"xyz":[0.370990668945913149,0.19237165220254468,0.103543807776335872],"hpluv":[4.46374659640210858,360.995599227985224,50.9635312364098496],"hsluv":[4.46374659640210858,96.9801964566503,50.9635312364098496]},"#ee1166":{"lch":[51.3137360134299598,138.123816003378664,0.523151936541392],"luv":[51.3137360134299598,138.118058344046318,1.26115288756691357],"rgb":[0.933333333333333348,0.0666666666666666657,0.4],"xyz":[0.378575664719421334,0.19540565051194797,0.143491452183479834],"hpluv":[0.523151936541392,341.565705345826359,51.3137360134299598],"hsluv":[0.523151936541392,97.1198273857598764,51.3137360134299598]},"#ee1177":{"lch":[51.7388469835676119,131.353183798903302,355.627348241097309],"luv":[51.7388469835676119,130.970848560864681,-10.014775152519368],"rgb":[0.933333333333333348,0.0666666666666666657,0.466666666666666674],"xyz":[0.38788967773962324,0.199131255720028794,0.192545254089877743],"hpluv":[355.627348241097309,322.153744971780554,51.7388469835676119],"hsluv":[355.627348241097309,97.2745732157476,51.7388469835676119]},"#ee1188":{"lch":[52.2404115410600411,125.324707533591734,349.782339698165117],"luv":[52.2404115410600411,123.337180279157977,-22.2311106147846438],"rgb":[0.933333333333333348,0.0666666666666666657,0.533333333333333326],"xyz":[0.39903009484156704,0.203587422560806391,0.251218117493449911],"hpluv":[349.782339698165117,304.417375015566734,52.2404115410600411],"hsluv":[349.782339698165117,97.4391430985313605,52.2404115410600411]},"#ee1199":{"lch":[52.819032808459994,120.657103381490217,343.097768544337384],"luv":[52.819032808459994,115.44498939014953,-35.079780802050081],"rgb":[0.933333333333333348,0.0666666666666666657,0.6],"xyz":[0.412087058950639795,0.208810208204435549,0.31998479513456779],"hpluv":[343.097768544337384,289.869003225703352,52.819032808459994],"hsluv":[343.097768544337384,97.6083995478766298,52.819032808459994]},"#ee11aa":{"lch":[53.4744599034404615,117.843047501566133,335.812437212199143],"luv":[53.4744599034404615,107.497497568615216,-48.2832461723726496],"rgb":[0.933333333333333348,0.0666666666666666657,0.66666666666666663],"xyz":[0.427144751915892296,0.214833285390536644,0.399288644751566446],"hpluv":[335.812437212199143,279.638449078323276,53.4744599034404615],"hsluv":[335.812437212199143,97.7777799659692,53.4744599034404615]},"#ee11bb":{"lch":[54.205681814132376,117.167943285093472,328.276238054291071],"luv":[54.205681814132376,99.6622453247977376,-61.6097702517929662],"rgb":[0.933333333333333348,0.0666666666666666657,0.733333333333333282],"xyz":[0.44428234402322897,0.221688322233471402,0.489546629850208137],"hpluv":[328.276238054291071,274.285798241860448,54.205681814132376],"hsluv":[328.276238054291071,97.9435422525978652,54.205681814132376]},"#ee11cc":{"lch":[55.0110259993956703,118.672848043699901,320.878255441103249],"luv":[55.0110259993956703,92.0672263164348266,-74.8790404666182781],"rgb":[0.933333333333333348,0.0666666666666666657,0.8],"xyz":[0.463574719466950724,0.229405272410960204,0.591153140520478293],"hpluv":[320.878255441103249,273.741691636115945,55.0110259993956703],"hsluv":[320.878255441103249,98.102849778989,55.0110259993956703]},"#ee11dd":{"lch":[55.8882602794840864,122.182226882396691,313.952719233652829],"luv":[55.8882602794840864,84.8023500190691522,-87.9605479586430334],"rgb":[0.933333333333333348,0.0666666666666666657,0.866666666666666696],"xyz":[0.485093045017584212,0.238012602631213738,0.704482988420484291],"hpluv":[313.952719233652829,277.412976370396279,55.8882602794840864],"hsluv":[313.952719233652829,98.2537358693348608,55.8882602794840864]},"#ee11ee":{"lch":[56.83469533821048,127.382376320214306,307.715012949243601],"luv":[56.83469533821048,77.9241738866570302,-100.767519176899128],"rgb":[0.933333333333333348,0.0666666666666666657,0.933333333333333348],"xyz":[0.508905225283758922,0.247537474737683783,0.829893804489007514],"hpluv":[307.715012949243601,284.403630900032795,56.83469533821048],"hsluv":[307.715012949243601,98.3949944120453495,56.83469533821048]},"#ee11ff":{"lch":[57.8472847680859275,133.910906422249354,302.2526850652647],"luv":[57.8472847680859275,71.4621107907268254,-113.248830369952643],"rgb":[0.933333333333333348,0.0666666666666666657,1],"xyz":[0.535076273693590343,0.258005894101616451,0.967727992780789359],"hpluv":[302.2526850652647,293.746227206253536,57.8472847680859275],"hsluv":[302.2526850652647,99.99999999999892,57.8472847680859275]},"#ee2200":{"lch":[51.0646940471157222,160.407609402057773,13.5847947923325787],"luv":[51.0646940471157222,155.919944837816502,37.677207378671163],"rgb":[0.933333333333333348,0.133333333333333331,0],"xyz":[0.358311109026528296,0.19324482621041944,0.018434381776051962],"hpluv":[13.5847947923325787,398.605749597291435,51.0646940471157222],"hsluv":[13.5847947923325787,100.000000000002203,51.0646940471157222]},"#ee2211":{"lch":[51.1114738997186322,159.015005648229618,13.0939108674416342],"luv":[51.1114738997186322,154.880623331235768,36.0244991337056817],"rgb":[0.933333333333333348,0.133333333333333331,0.0666666666666666657],"xyz":[0.3593227745261654,0.193649492410274293,0.0237624867408075952],"hpluv":[13.0939108674416342,394.783534202752207,51.1114738997186322],"hsluv":[13.0939108674416342,96.7702863870018462,51.1114738997186322]},"#ee2222":{"lch":[51.1980191888258105,156.511980987808,12.1770506300618031],"luv":[51.1980191888258105,152.990533465747774,33.0135860305098348],"rgb":[0.933333333333333348,0.133333333333333331,0.133333333333333331],"xyz":[0.361198132664642457,0.194399635665665121,0.0336393729367867877],"hpluv":[12.1770506300618031,387.912483642854795,51.1980191888258105],"hsluv":[12.1770506300618031,90.899918517349,51.1980191888258105]},"#ee2233":{"lch":[51.340031013958,152.605977320930094,10.6487510890373542],"luv":[51.340031013958,149.977869701108148,28.1996970549978769],"rgb":[0.933333333333333348,0.133333333333333331,0.2],"xyz":[0.364285883397100163,0.19563473595864822,0.0499015267943979379],"hpluv":[10.6487510890373542,377.185287566809563,51.340031013958],"hsluv":[10.6487510890373542,91.0856949770771,51.340031013958]},"#ee2244":{"lch":[51.5440125284501391,147.416232714385046,8.4042516634418849],"luv":[51.5440125284501391,145.833202035739902,21.5458314229178391],"rgb":[0.933333333333333348,0.133333333333333331,0.266666666666666663],"xyz":[0.368743878641319078,0.197417934056335814,0.0733803017472845764],"hpluv":[8.4042516634418849,362.916246958463432,51.5440125284501391],"hsluv":[8.4042516634418849,91.3409150161676848,51.5440125284501391]},"#ee2255":{"lch":[51.8149196409757,141.25016266814734,5.34127242035781613],"luv":[51.8149196409757,140.636840571385164,13.1486701942394504],"rgb":[0.933333333333333348,0.133333333333333331,0.333333333333333315],"xyz":[0.374706292680681063,0.199802899672080647,0.104782349021258478],"hpluv":[5.34127242035781613,345.918233291596209,51.8149196409757],"hsluv":[5.34127242035781613,91.6602615743055082,51.8149196409757]},"#ee2266":{"lch":[52.1564522427987924,134.577740656965489,1.36671179444129165],"luv":[52.1564522427987924,134.539455426625494,3.20986196595936],"rgb":[0.933333333333333348,0.133333333333333331,0.4],"xyz":[0.382291288454189249,0.202836897981483938,0.144729993428402454],"hpluv":[1.36671179444129165,327.419481975304109,52.1564522427987924],"hsluv":[1.36671179444129165,92.0339967122243365,52.1564522427987924]},"#ee2277":{"lch":[52.5712108639856694,127.988129961564283,356.416786702014292],"luv":[52.5712108639856694,127.737923683219179,-7.99901644943552803],"rgb":[0.933333333333333348,0.133333333333333331,0.466666666666666674],"xyz":[0.391605301474391154,0.206562503189564761,0.193783795334800363],"hpluv":[356.416786702014292,308.930679724572485,52.5712108639856694],"hsluv":[356.416786702014292,92.4494947830095,52.5712108639856694]},"#ee2288":{"lch":[53.0608018273771194,122.127216672078461,350.491948161024197],"luv":[53.0608018273771194,120.449481512132621,-20.1737318195523763],"rgb":[0.933333333333333348,0.133333333333333331,0.533333333333333326],"xyz":[0.402745718576334955,0.211018670030342359,0.25245665873837253],"hpluv":[350.491948161024197,292.063965437042782,53.0608018273771194],"hsluv":[350.491948161024197,92.892885362452958,53.0608018273771194]},"#ee2299":{"lch":[53.6259244704506557,117.615935516390621,343.699890485995525],"luv":[53.6259244704506557,112.888334232708232,-33.0110933105844282],"rgb":[0.933333333333333348,0.133333333333333331,0.6],"xyz":[0.415802682685407654,0.216241455673971517,0.32122333637949041],"hpluv":[343.699890485995525,278.311211390643507,53.6259244704506557],"hsluv":[343.699890485995525,93.3505397228777412,53.6259244704506557]},"#ee22aa":{"lch":[54.266455218013121,114.955451111725907,336.284451026203612],"luv":[54.266455218013121,105.247863162980167,-46.2346519390706305],"rgb":[0.933333333333333348,0.133333333333333331,0.66666666666666663],"xyz":[0.43086037565066021,0.222264532860072611,0.400527185996489],"hpluv":[336.284451026203612,268.805062052359688,54.266455218013121],"hsluv":[336.284451026203612,93.8102001508292,54.266455218013121]},"#ee22bb":{"lch":[54.981534566577821,114.440827463928798,328.608334651454868],"luv":[54.981534566577821,97.6897319326175,-59.6105633722921],"rgb":[0.933333333333333348,0.133333333333333331,0.733333333333333282],"xyz":[0.447997967757996884,0.22911956970300737,0.490785171095130757],"hpluv":[328.608334651454868,264.121319791368,54.981534566577821],"hsluv":[328.608334651454868,94.2616688954678636,54.981534566577821]},"#ee22cc":{"lch":[55.7696584616915629,116.118636638570607,321.077185717181408],"luv":[55.7696584616915629,90.3394913251054419,-72.9541916679335856],"rgb":[0.933333333333333348,0.133333333333333331,0.8],"xyz":[0.467290343201718583,0.236836519880496171,0.592391681765400913],"hpluv":[321.077185717181408,264.206361207665168,55.7696584616915629],"hsluv":[321.077185717181408,94.6970823725699518,55.7696584616915629]},"#ee22dd":{"lch":[56.6287730491083749,119.812596042269817,314.038835862099],"luv":[56.6287730491083749,83.2872216309056,-86.1295354880806201],"rgb":[0.933333333333333348,0.133333333333333331,0.866666666666666696],"xyz":[0.488808668752352182,0.245443850100749705,0.70572152966540691],"hpluv":[314.038835862099,268.475495638829329,56.6287730491083749],"hsluv":[314.038835862099,95.1108639535381,56.6287730491083749]},"#ee22ee":{"lch":[57.5563705104872128,125.203701850491953,307.715012949243658],"luv":[57.5563705104872128,76.5914038981754,-99.0440498261932163],"rgb":[0.933333333333333348,0.133333333333333331,0.933333333333333348],"xyz":[0.512620849018526892,0.254968722207219722,0.831132345733930133],"hpluv":[307.715012949243658,276.03432908057755,57.5563705104872128],"hsluv":[307.715012949243658,95.4994708803944263,57.5563705104872128]},"#ee22ff":{"lch":[58.5495832280214046,131.922896299071255,302.192710378625122],"luv":[58.5495832280214046,70.2843784028787582,-111.641196341030223],"rgb":[0.933333333333333348,0.133333333333333331,1],"xyz":[0.538791897428358313,0.265437141571152446,0.968966534025712],"hpluv":[302.192710378625122,285.914180736870946,58.5495832280214046],"hsluv":[302.192710378625122,99.9999999999989,58.5495832280214046]},"#ee3300":{"lch":[52.4512471844783761,153.77210005382733,15.1254552240259841],"luv":[52.4512471844783761,148.444942331914945,40.1242800687903269],"rgb":[0.933333333333333348,0.2,0],"xyz":[0.364428831115539142,0.205480270388441244,0.0204736224723888437],"hpluv":[15.1254552240259841,372.015515114283232,52.4512471844783761],"hsluv":[15.1254552240259841,100.000000000002174,52.4512471844783761]},"#ee3311":{"lch":[52.4961529429458693,152.446596739109111,14.6331501802662043],"luv":[52.4961529429458693,147.501711829562538,38.5124637576621893],"rgb":[0.933333333333333348,0.2,0.0666666666666666657],"xyz":[0.365440496615176247,0.205884936588296097,0.0258017274371444769],"hpluv":[14.6331501802662043,368.493287978140756,52.4961529429458693],"hsluv":[14.6331501802662043,96.9493433827183395,52.4961529429458693]},"#ee3322":{"lch":[52.5792408568970302,150.061966488521733,13.7129404445972121],"luv":[52.5792408568970302,145.784540850223095,35.5733247742160685],"rgb":[0.933333333333333348,0.2,0.133333333333333331],"xyz":[0.367315854753653304,0.206635079843686925,0.0356786136331236695],"hpluv":[13.7129404445972121,362.155969729293304,52.5792408568970302],"hsluv":[13.7129404445972121,91.3983957113456,52.5792408568970302]},"#ee3333":{"lch":[52.7156069212027916,146.335083442311,12.177050630061796],"luv":[52.7156069212027916,143.042611430097821,30.8669396171076365],"rgb":[0.933333333333333348,0.2,0.2],"xyz":[0.370403605486111,0.207870180136670024,0.0519407674907348127],"hpluv":[12.177050630061796,352.248031751653059,52.7156069212027916],"hsluv":[12.177050630061796,82.5426319963487316,52.7156069212027916]},"#ee3344":{"lch":[52.9115382124740705,141.372894204534333,9.91688783885485314],"luv":[52.9115382124740705,139.260586308771792,24.3471623953096028],"rgb":[0.933333333333333348,0.2,0.266666666666666663],"xyz":[0.374861600730329925,0.209653378234357618,0.0754195424436214512],"hpluv":[9.91688783885485314,339.043238938553714,52.9115382124740705],"hsluv":[9.91688783885485314,83.0163224279527867,52.9115382124740705]},"#ee3355":{"lch":[53.1718605143623222,135.462446214194244,6.82400118051175664],"luv":[53.1718605143623222,134.502806079917804,16.0956357737583851],"rgb":[0.933333333333333348,0.2,0.333333333333333315],"xyz":[0.38082401476969191,0.212038343850102451,0.106821589717595367],"hpluv":[6.82400118051175664,323.278173463789,53.1718605143623222],"hsluv":[6.82400118051175664,83.6110915378108,53.1718605143623222]},"#ee3366":{"lch":[53.5002196972096158,129.050901787066266,2.79642975700151464],"luv":[53.5002196972096158,128.89722530875369,6.29607494868134765],"rgb":[0.933333333333333348,0.2,0.4],"xyz":[0.388409010543200095,0.215072342159505742,0.146769234124739328],"hpluv":[2.79642975700151464,306.086943567777439,53.5002196972096158],"hsluv":[2.79642975700151464,84.310080928774866,53.5002196972096158]},"#ee3377":{"lch":[53.8992319384372252,122.709031404530748,357.759441587930837],"luv":[53.8992319384372252,122.615219389586755,-4.79732866099687261],"rgb":[0.933333333333333348,0.2,0.466666666666666674],"xyz":[0.397723023563402,0.218797947367586565,0.195823036031137238],"hpluv":[357.759441587930837,288.89051161323988,53.8992319384372252],"hsluv":[357.759441587930837,85.0909052409050872,53.8992319384372252]},"#ee3388":{"lch":[54.3705825415329,117.074862235921088,351.703100554939169],"luv":[54.3705825415329,115.849509832295894,-16.8942131860788436],"rgb":[0.933333333333333348,0.2,0.533333333333333326],"xyz":[0.408863440665345801,0.223254114208364163,0.254495899434709405],"hpluv":[351.703100554939169,273.2366774905733,54.3705825415329],"hsluv":[351.703100554939169,85.9285066952877,54.3705825415329]},"#ee3399":{"lch":[54.9151057717267292,112.774715889061866,344.730687431692274],"luv":[54.9151057717267292,108.793611621096844,-29.6999430015709507],"rgb":[0.933333333333333348,0.2,0.6],"xyz":[0.4219204047744185,0.22847689985199332,0.323262577075827284],"hpluv":[344.730687431692274,260.590898768244074,54.9151057717267292],"hsluv":[344.730687431692274,86.7978129198036896,54.9151057717267292]},"#ee33aa":{"lch":[55.5328602544255,110.325325240584178,337.093995035693695],"luv":[55.5328602544255,101.625579555338021,-42.9408776049389047],"rgb":[0.933333333333333348,0.2,0.66666666666666663],"xyz":[0.436978097739671056,0.234499977038094415,0.402566426692825885],"hpluv":[337.093995035693695,252.095155701888757,55.5328602544255],"hsluv":[337.093995035693695,87.6758366884225779,55.5328602544255]},"#ee33bb":{"lch":[56.2232062298057826,110.03895679054483,329.178007243031175],"luv":[56.2232062298057826,94.4974163460242664,-56.3809392922602726],"rgb":[0.933333333333333348,0.2,0.733333333333333282],"xyz":[0.454115689847007731,0.241355013881029173,0.492824411791467631],"hpluv":[329.178007243031175,248.353441541401367,56.2232062298057826],"hsluv":[329.178007243031175,88.5430404155392665,56.2232062298057826]},"#ee33cc":{"lch":[56.9848866198670123,111.971807156825847,321.417898872172259],"luv":[56.9848866198670123,87.5300782585605788,-69.8295854062993726],"rgb":[0.933333333333333348,0.2,0.8],"xyz":[0.47340806529072943,0.249071964058517975,0.594430922461737787],"hpluv":[321.417898872172259,249.337916143678171,56.9848866198670123],"hsluv":[321.417898872172259,89.3839737673679764,56.9848866198670123]},"#ee33dd":{"lch":[57.8161114567543848,115.945977330727956,314.185904182223908],"luv":[57.8161114567543848,80.813036999634221,-83.1427850752753557],"rgb":[0.933333333333333348,0.2,0.866666666666666696],"xyz":[0.494926390841363029,0.257679294278771509,0.707760770361743785],"hpluv":[314.185904182223908,254.475591939392586,57.8161114567543848],"hsluv":[314.185904182223908,90.1873197259471482,57.8161114567543848]},"#ee33ee":{"lch":[58.7146439354817886,121.632779311923699,307.715012949243715],"luv":[58.7146439354817886,74.4069479563921448,-96.2192241652253415],"rgb":[0.933333333333333348,0.2,0.933333333333333348],"xyz":[0.518738571107537738,0.267204166385241526,0.833171586430267],"hpluv":[307.715012949243715,262.87151341613469,58.7146439354817886],"hsluv":[307.715012949243715,90.9455375510239747,58.7146439354817886]},"#ee33ff":{"lch":[59.6778857977730581,128.651158016084139,302.091050100274117],"luv":[59.6778857977730581,68.3480180420837229,-108.993893813362092],"rgb":[0.933333333333333348,0.2,1],"xyz":[0.544909619517369159,0.27767258574917425,0.971005774722048853],"hpluv":[302.091050100274117,273.551812848380507,59.6778857977730581],"hsluv":[302.091050100274117,99.9999999999986784,59.6778857977730581]},"#ee4400":{"lch":[54.3591594970822598,145.188828472067655,17.4116852889838647],"luv":[54.3591594970822598,138.536177662057611,43.4456372018905412],"rgb":[0.933333333333333348,0.266666666666666663,0],"xyz":[0.373261401598505183,0.223145411354373546,0.023417812633377437],"hpluv":[17.4116852889838647,338.922026437804789,54.3591594970822598],"hsluv":[17.4116852889838647,100.000000000002217,54.3591594970822598]},"#ee4411":{"lch":[54.4016650840252112,143.940172045268554,16.9187727396215735],"luv":[54.4016650840252112,137.710194578710485,41.8888462184768713],"rgb":[0.933333333333333348,0.266666666666666663,0.0666666666666666657],"xyz":[0.374273067098142287,0.223550077554228399,0.0287459175981330667],"hpluv":[16.9187727396215735,335.744689025208913,54.4016650840252112],"hsluv":[16.9187727396215735,97.1754310281257574,54.4016650840252112]},"#ee4422":{"lch":[54.4803236312215944,141.690847159829417,15.9963876830432117],"luv":[54.4803236312215944,136.204446081142294,39.0467032744039173],"rgb":[0.933333333333333348,0.266666666666666663,0.133333333333333331],"xyz":[0.376148425236619344,0.224300220809619227,0.0386228037941122662],"hpluv":[15.9963876830432117,330.020900264600868,54.4803236312215944],"hsluv":[15.9963876830432117,92.0288025918740118,54.4803236312215944]},"#ee4433":{"lch":[54.6094526105793534,138.167821982121467,14.4538486850626899],"luv":[54.6094526105793534,133.794673004457735,34.4867004352900608],"rgb":[0.933333333333333348,0.266666666666666663,0.2],"xyz":[0.37923617596907705,0.225535321102602326,0.0548849576517234095],"hpluv":[14.4538486850626899,321.054243711338643,54.6094526105793534],"hsluv":[14.4538486850626899,83.7991355104008591,54.6094526105793534]},"#ee4444":{"lch":[54.7950558424119549,133.462657054844783,12.1770506300618084],"luv":[54.7950558424119549,130.459808710538397,28.151716454753565],"rgb":[0.933333333333333348,0.266666666666666663,0.266666666666666663],"xyz":[0.383694171213295965,0.22731851920028992,0.078363732604610048],"hpluv":[12.1770506300618084,309.070617226475065,54.7950558424119549],"hsluv":[12.1770506300618084,79.6495466444067546,54.7950558424119549]},"#ee4455":{"lch":[55.04178262974213,127.837203216659944,9.0482956458548145],"luv":[55.04178262974213,126.246413461005446,20.1045670057943724],"rgb":[0.933333333333333348,0.266666666666666663,0.333333333333333315],"xyz":[0.38965658525265795,0.229703484816034753,0.109765779878583963],"hpluv":[9.0482956458548145,294.716259365516066,55.04178262974213],"hsluv":[9.0482956458548145,80.0457187830871106,55.04178262974213]},"#ee4466":{"lch":[55.3531965298607105,121.710491561886229,4.95183922571805102],"luv":[55.3531965298607105,121.256220070521849,10.5058483924504795],"rgb":[0.933333333333333348,0.266666666666666663,0.4],"xyz":[0.397241581026166135,0.232737483125438044,0.149713424285727925],"hpluv":[4.95183922571805102,279.013127650855779,55.3531965298607105],"hsluv":[4.95183922571805102,80.511500113091131,55.3531965298607105]},"#ee4477":{"lch":[55.7319177265462855,115.631099927359429,359.795147057523252],"luv":[55.7319177265462855,115.63036086114974,-0.41342173536332294],"rgb":[0.933333333333333348,0.266666666666666663,0.466666666666666674],"xyz":[0.406555594046368041,0.236463088333518867,0.198767226192125834],"hpluv":[359.795147057523252,263.275227085929203,55.7319177265462855],"hsluv":[359.795147057523252,81.0316034214938412,55.7319177265462855]},"#ee4488":{"lch":[56.1797144871475069,110.229334232011354,353.550243523911263],"luv":[56.1797144871475069,109.531664472369371,-12.3822697089333467],"rgb":[0.933333333333333348,0.266666666666666663,0.533333333333333326],"xyz":[0.417696011148311841,0.240919255174296465,0.257440089595698],"hpluv":[353.550243523911263,248.975712077739217,56.1797144871475069],"hsluv":[353.550243523911263,81.5885451367485217,56.1797144871475069]},"#ee4499":{"lch":[56.6975745677487,106.142668326601637,346.310852745323245],"luv":[56.6975745677487,103.127575819694869,-25.1190992084518889],"rgb":[0.933333333333333348,0.266666666666666663,0.6],"xyz":[0.430752975257384541,0.246142040817925623,0.326206767236815909],"hpluv":[346.310852745323245,237.55536706581762,56.6975745677487],"hsluv":[346.310852745323245,82.1643886194057,56.6975745677487]},"#ee44aa":{"lch":[57.2857706939250164,103.913945498461985,338.339047623856459],"luv":[57.2857706939250164,96.5759938315173798,-38.356035828954532],"rgb":[0.933333333333333348,0.266666666666666663,0.66666666666666663],"xyz":[0.445810668222637096,0.252165118004026745,0.405510616853814509],"hpluv":[338.339047623856459,230.179372132151769,57.2857706939250164],"hsluv":[338.339047623856459,82.742186475039972,57.2857706939250164]},"#ee44bb":{"lch":[57.9439265752057224,103.883653730246948,330.054621671216069],"luv":[57.9439265752057224,90.015359877018625,-51.8560362788815183],"rgb":[0.933333333333333348,0.266666666666666663,0.733333333333333282],"xyz":[0.462948260329973771,0.259020154846961503,0.495768601952456256],"hpluv":[330.054621671216069,227.498543532010189,57.9439265752057224],"hsluv":[330.054621671216069,83.3069826860278,57.9439265752057224]},"#ee44cc":{"lch":[58.6710858878032866,106.123661593235155,321.940977409416575],"luv":[58.6710858878032866,83.5592367986741493,-65.4223623509468837],"rgb":[0.933333333333333348,0.266666666666666663,0.8],"xyz":[0.48224063577369547,0.266737105024450305,0.597375112622726356],"hpluv":[321.940977409416575,229.523641905846944,58.6710858878032866],"hsluv":[321.940977409416575,83.8463488142865288,58.6710858878032866]},"#ee44dd":{"lch":[59.4657843936948041,110.45324904546132,314.41066654104867],"luv":[59.4657843936948041,77.2947793232282407,-78.9014405069524116],"rgb":[0.933333333333333348,0.266666666666666663,0.866666666666666696],"xyz":[0.503758961324329069,0.275344435244703811,0.710704960522732354],"hpluv":[314.41066654104867,235.695163072106425,59.4657843936948041],"hsluv":[314.41066654104867,84.3505154479208699,59.4657843936948041]},"#ee44ee":{"lch":[60.3261240941145189,116.527805305600168,307.715012949243771],"luv":[60.3261240941145189,71.28406005268711,-92.180866733529669],"rgb":[0.933333333333333348,0.266666666666666663,0.933333333333333348],"xyz":[0.527571141590503778,0.284869307351173828,0.836115776591255577],"hpluv":[307.715012949243771,245.111377339321677,60.3261240941145189],"hsluv":[307.715012949243771,84.8122051950840898,60.3261240941145189]},"#ee44ff":{"lch":[61.2498476847862321,123.946828366557639,301.937515996566106],"luv":[61.2498476847862321,65.5671420475233617,-105.184438705774298],"rgb":[0.933333333333333348,0.266666666666666663,1],"xyz":[0.553742190000335199,0.295337726715106552,0.973949964883037422],"hpluv":[301.937515996566106,256.785047727470896,61.2498476847862321],"hsluv":[301.937515996566106,99.9999999999986073,61.2498476847862321]},"#ee5500":{"lch":[56.7595334156469136,135.29504726150742,20.5772435658132551],"luv":[56.7595334156469136,126.663115619922038,47.5521288161507414],"rgb":[0.933333333333333348,0.333333333333333315,0],"xyz":[0.385074658312851148,0.24677192478306581,0.0273555648714926478],"hpluv":[20.5772435658132551,302.470071141489655,56.7595334156469136],"hsluv":[20.5772435658132551,100.000000000002331,56.7595334156469136]},"#ee5511":{"lch":[56.7992830001534799,134.121232245619609,20.0864579205919],"luv":[56.7992830001534799,125.963368804879124,46.0622910677426],"rgb":[0.933333333333333348,0.333333333333333315,0.0666666666666666657],"xyz":[0.386086323812488252,0.247176590982920663,0.0326836698362482775],"hpluv":[20.0864579205919,299.636011805134103,56.7992830001534799],"hsluv":[20.0864579205919,97.4301566790671245,56.7992830001534799]},"#ee5522":{"lch":[56.8728535321199331,132.003018379302972,19.1666168944474329],"luv":[56.8728535321199331,124.685803630375247,43.3387498007741385],"rgb":[0.933333333333333348,0.333333333333333315,0.133333333333333331],"xyz":[0.387961681950965309,0.247926734238311491,0.042560556032227477],"hpluv":[19.1666168944474329,294.522290528054612,56.8728535321199331],"hsluv":[19.1666168944474329,92.7404035063857748,56.8728535321199331]},"#ee5533":{"lch":[56.9936637318031813,128.675597773649343,17.6241311186411558],"luv":[56.9936637318031813,122.635981466153211,38.9592801812266671],"rgb":[0.933333333333333348,0.333333333333333315,0.2],"xyz":[0.391049432683423,0.24916183453129459,0.0588227098898386203],"hpluv":[17.6241311186411558,286.489655583397507,56.9936637318031813],"hsluv":[17.6241311186411558,85.2217597168545353,56.9936637318031813]},"#ee5544":{"lch":[57.1673833238913431,124.212647444540593,15.3377586553938237],"luv":[57.1673833238913431,119.788604494467549,32.8553194848226298],"rgb":[0.933333333333333348,0.333333333333333315,0.266666666666666663],"xyz":[0.39550742792764193,0.250945032628982156,0.0823014848427252588],"hpluv":[15.3377586553938237,275.712737821839653,57.1673833238913431],"hsluv":[15.3377586553938237,78.8138286806830308,57.1673833238913431]},"#ee5555":{"lch":[57.3984455800741813,118.847398490007407,12.1770506300618084],"luv":[57.3984455800741813,116.173386735287238,25.068871978930396],"rgb":[0.933333333333333348,0.333333333333333315,0.333333333333333315],"xyz":[0.401469841967003915,0.253329998244727,0.113703532116699174],"hpluv":[12.1770506300618084,262.741620924066638,57.3984455800741813],"hsluv":[12.1770506300618084,79.1862648733910817,57.3984455800741813]},"#ee5566":{"lch":[57.6903015433249777,112.967028718059339,8.00617638558467881],"luv":[57.6903015433249777,111.865945908872092,15.7340307391382019],"rgb":[0.933333333333333348,0.333333333333333315,0.4],"xyz":[0.409054837740512101,0.256363996554130336,0.153651176523843136],"hpluv":[8.00617638558467881,248.478160638648092,57.6903015433249777],"hsluv":[8.00617638558467881,79.626682914648967,57.6903015433249777]},"#ee5577":{"lch":[58.0455538260385,107.095574323644513,2.70497781295448236],"luv":[58.0455538260385,106.976246145051803,5.05418642558356],"rgb":[0.933333333333333348,0.333333333333333315,0.466666666666666674],"xyz":[0.418368850760714,0.260089601762211131,0.202704978430241045],"hpluv":[2.70497781295448236,234.121819944652458,58.0455538260385],"hsluv":[2.70497781295448236,80.121743738144815,58.0455538260385]},"#ee5588":{"lch":[58.4660405277881523,101.857434077675435,356.214905006905212],"luv":[58.4660405277881523,101.63524992227579,-6.72405012805051783],"rgb":[0.933333333333333348,0.333333333333333315,0.533333333333333326],"xyz":[0.429509267862657806,0.264545768602988729,0.261377841833813185],"hpluv":[356.214905006905212,221.069268787819283,58.4660405277881523],"hsluv":[356.214905006905212,80.6557447307456385,58.4660405277881523]},"#ee5599":{"lch":[58.9528982622070714,97.9100075268454475,348.609359498013816],"luv":[58.9528982622070714,95.9815181358717808,-19.3369529719717974],"rgb":[0.933333333333333348,0.333333333333333315,0.6],"xyz":[0.442566231971730506,0.269768554246617887,0.33014451947493112],"hpluv":[348.609359498013816,210.746926462762332,58.9528982622070714],"hsluv":[348.609359498013816,81.2121283261168685,58.9528982622070714]},"#ee55aa":{"lch":[59.5066178042993812,95.8379147411847327,340.160257686713578],"luv":[59.5066178042993812,90.1495111294489817,-32.5264745255299346],"rgb":[0.933333333333333348,0.333333333333333315,0.66666666666666663],"xyz":[0.457623924936983062,0.275791631432719,0.40944836909192972],"hpluv":[340.160257686713578,204.36730380296666,59.5066178042993812],"hsluv":[340.160257686713578,81.7747968800248515,59.5066178042993812]},"#ee55bb":{"lch":[60.1270988419473156,96.02691270708236,331.338718337462637],"luv":[60.1270988419473156,84.2607812264238305,-46.0574501157669],"rgb":[0.933333333333333348,0.333333333333333315,0.733333333333333282],"xyz":[0.474761517044319736,0.282646668275653767,0.499706354190571467],"hpluv":[331.338718337462637,202.657202566236862,60.1270988419473156],"hsluv":[331.338718337462637,82.3290961128101202,60.1270988419473156]},"#ee55cc":{"lch":[60.8137066481247359,98.5745380895967855,322.704854800823],"luv":[60.8137066481247359,78.4184921400445774,-59.728382282288],"rgb":[0.933333333333333348,0.333333333333333315,0.8],"xyz":[0.494053892488041435,0.290363618453142569,0.601312864860841567],"hpluv":[322.704854800823,205.68499115665557,60.8137066481247359],"hsluv":[322.704854800823,82.862416210457269,60.8137066481247359]},"#ee55dd":{"lch":[61.5653314057239669,103.296154527471415,314.73674606959],"luv":[61.5653314057239669,72.7050419742243577,-73.3762387404091925],"rgb":[0.933333333333333348,0.333333333333333315,0.866666666666666696],"xyz":[0.515572218038675,0.298970948673396075,0.714642712760847565],"hpluv":[314.73674606959,212.905685416828703,61.5653314057239669],"hsluv":[314.73674606959,83.3644351442966496,61.5653314057239669]},"#ee55ee":{"lch":[62.3804497031794796,109.822432229930158,307.715012949243942],"luv":[62.3804497031794796,67.1821530808003473,-86.8764923804219364],"rgb":[0.933333333333333348,0.333333333333333315,0.933333333333333348],"xyz":[0.539384398304849744,0.308495820779866092,0.840053528829370788],"hpluv":[307.715012949243942,223.399338603574023,62.3804497031794796],"hsluv":[307.715012949243942,83.8270760150894318,62.3804497031794796]},"#ee55ff":{"lch":[63.2571870514493355,117.722992850638121,301.718618818209791],"luv":[63.2571870514493355,61.8926401270512301,-100.139922827085911],"rgb":[0.933333333333333348,0.333333333333333315,1],"xyz":[0.565555446714681165,0.318964240143798816,0.977887717121152633],"hpluv":[301.718618818209791,236.15152010236153,63.2571870514493355],"hsluv":[301.718618818209791,99.9999999999986358,63.2571870514493355]},"#ee6600":{"lch":[59.6010827175637274,124.896403377083828,24.7633991985742],"luv":[59.6010827175637274,113.411584725929117,52.315619335764687],"rgb":[0.933333333333333348,0.4,0],"xyz":[0.400102716018697624,0.276828040194759151,0.032364917440108],"hpluv":[24.7633991985742,265.910269095548301,59.6010827175637274],"hsluv":[24.7633991985742,100.000000000002458,59.6010827175637274]},"#ee6611":{"lch":[59.6379025762155521,123.785593795891074,24.2806773941880323],"luv":[59.6379025762155521,112.835768380983566,50.9014990474188],"rgb":[0.933333333333333348,0.4,0.0666666666666666657],"xyz":[0.401114381518334728,0.277232706394614,0.0376930224048636284],"hpluv":[24.2806773941880323,263.38259338209491,59.6379025762155521],"hsluv":[24.2806773941880323,97.6946368166697425,59.6379025762155521]},"#ee6622":{"lch":[59.7060621192549235,121.776511986799889,23.3741045361832462],"luv":[59.7060621192549235,111.782804083827386,48.312768320888857],"rgb":[0.933333333333333348,0.4,0.133333333333333331],"xyz":[0.402989739656811785,0.277982849650004804,0.0475699086008428279],"hpluv":[23.3741045361832462,258.812011755725052,59.7060621192549235],"hsluv":[23.3741045361832462,93.4807634058905847,59.7060621192549235]},"#ee6633":{"lch":[59.818019190990654,118.60827278102343,21.848413141726418],"luv":[59.818019190990654,110.088842330137865,44.1403349161252621],"rgb":[0.933333333333333348,0.4,0.2],"xyz":[0.406077490389269491,0.279217949942987931,0.0638320624584539642],"hpluv":[21.848413141726418,251.606745577849637,59.818019190990654],"hsluv":[21.848413141726418,86.7067277856042722,59.818019190990654]},"#ee6644":{"lch":[59.9790782653121,114.334087778781978,19.5741908506499591],"luv":[59.9790782653121,107.726545105393242,38.3050271878496318],"rgb":[0.933333333333333348,0.4,0.266666666666666663],"xyz":[0.410535485633488406,0.281001148040675497,0.0873108374113406],"hpluv":[19.5741908506499591,241.888527179759762,59.9790782653121],"hsluv":[19.5741908506499591,77.7164494297015551,59.9790782653121]},"#ee6655":{"lch":[60.1934276072459227,109.155383321287928,16.4048569251700904],"luv":[60.1934276072459227,104.711671726378157,30.827966398783424],"rgb":[0.933333333333333348,0.4,0.333333333333333315],"xyz":[0.416497899672850391,0.283386113656420358,0.118712884685314518],"hpluv":[16.4048569251700904,230.109957101660228,60.1934276072459227],"hsluv":[16.4048569251700904,78.0627041699660822,60.1934276072459227]},"#ee6666":{"lch":[60.4643778553048179,103.423697151150392,12.1770506300619203],"luv":[60.4643778553048179,101.096711576265875,21.8155000143976636],"rgb":[0.933333333333333348,0.4,0.4],"xyz":[0.424082895446358576,0.286420111965823676,0.15866052909245848],"hpluv":[12.1770506300619203,217.050003231938149,60.4643778553048179],"hsluv":[12.1770506300619203,78.4746058088251601,60.4643778553048179]},"#ee6677":{"lch":[60.7944870758990845,97.6355083856116,6.72933164538236728],"luv":[60.7944870758990845,96.9628770314166388,11.4408468002682859],"rgb":[0.933333333333333348,0.4,0.466666666666666674],"xyz":[0.433396908466560482,0.290145717173904472,0.207714330998856389],"hpluv":[6.72933164538236728,203.79002370037793,60.7944870758990845],"hsluv":[6.72933164538236728,78.9407958828298177,60.7944870758990845]},"#ee6688":{"lch":[61.1856375663111294,92.4106294683140419,359.951978350089689],"luv":[61.1856375663111294,92.4105970103857,-0.0774526573243247418],"rgb":[0.933333333333333348,0.4,0.533333333333333326],"xyz":[0.444537325568504282,0.294601884014682069,0.266387194402428529],"hpluv":[359.951978350089689,191.6512981090967,61.1856375663111294],"hsluv":[359.951978350089689,79.4474583444281706,61.1856375663111294]},"#ee6699":{"lch":[61.6390913266860281,88.437141466109523,351.875732288608958],"luv":[61.6390913266860281,87.5495765855601746,-12.4979850530316181],"rgb":[0.933333333333333348,0.4,0.6],"xyz":[0.457594289677577,0.299824669658311227,0.335153872043546464],"hpluv":[351.875732288608958,182.061365307506776,61.6390913266860281],"hsluv":[351.875732288608958,79.9795786975914353,61.6390913266860281]},"#ee66aa":{"lch":[62.1555369290736337,86.3639450462453624,342.77320214224],"luv":[62.1555369290736337,82.489654306882187,-25.5770978862333536],"rgb":[0.933333333333333348,0.4,0.66666666666666663],"xyz":[0.472651982642829538,0.305847746844412349,0.414457721660545064],"hpluv":[342.77320214224,176.316102232879075,62.1555369290736337],"hsluv":[342.77320214224,80.5221008496243,62.1555369290736337]},"#ee66bb":{"lch":[62.735134131647655,86.6495273870251168,333.187217955259598],"luv":[62.735134131647655,77.3334216921159765,-39.0855790002422907],"rgb":[0.933333333333333348,0.4,0.733333333333333282],"xyz":[0.489789574750166212,0.312702783687347108,0.504715706759186755],"hpluv":[333.187217955259598,175.264796900814019,62.735134131647655],"hsluv":[333.187217955259598,81.0608551813628679,62.735134131647655]},"#ee66cc":{"lch":[63.3775592853136516,89.4351699392481549,323.800511847500275],"luv":[63.3775592853136516,72.1711045195964545,-52.8202735176909144],"rgb":[0.933333333333333348,0.4,0.8],"xyz":[0.509081950193887911,0.320419733864835909,0.606322217429456911],"hpluv":[323.800511847500275,179.065596131410075,63.3775592853136516],"hsluv":[323.800511847500275,81.5831918811758072,63.3775592853136516]},"#ee66dd":{"lch":[64.0820526997291751,94.5324861988586918,315.200217206616742],"luv":[64.0820526997291751,67.0777383779463179,-66.6105694393704795],"rgb":[0.933333333333333348,0.4,0.866666666666666696],"xyz":[0.53060027574452151,0.329027064085089416,0.719652065329462909],"hpluv":[315.200217206616742,187.190580763285084,64.0820526997291751],"hsluv":[315.200217206616742,82.0783141076240241,64.0820526997291751]},"#ee66ee":{"lch":[64.8474680131467,101.534802649490857,307.715012949244169],"luv":[64.8474680131467,62.1123254704966499,-80.32045302236628],"rgb":[0.933333333333333348,0.4,0.933333333333333348],"xyz":[0.55441245601069622,0.338551936191559433,0.845062881397986132],"hpluv":[307.715012949244169,198.683239249207219,64.8474680131467],"hsluv":[307.715012949244169,82.5373501246235,64.8474680131467]},"#ee66ff":{"lch":[65.6723229483953759,109.966867844968618,301.415067453827589],"luv":[65.6723229483953759,57.3184789471434897,-93.8472375449520797],"rgb":[0.933333333333333348,0.4,1],"xyz":[0.580583504420527641,0.349020355555492157,0.982897069689768088],"hpluv":[301.415067453827589,212.480364902930489,65.6723229483953759],"hsluv":[301.415067453827589,99.9999999999984794,65.6723229483953759]},"#ee7700":{"lch":[62.8217158048736763,114.851740825540901,30.0981414692213356],"luv":[62.8217158048736763,99.3660150566978,57.5961580525066097],"rgb":[0.933333333333333348,0.466666666666666674,0],"xyz":[0.418556454072115225,0.313735516301594908,0.0385161634579137],"hpluv":[30.0981414692213356,231.988851559171735,62.8217158048736763],"hsluv":[30.0981414692213356,100.000000000002203,62.8217158048736763]},"#ee7711":{"lch":[62.8555901763931075,113.786950077776382,29.6341042910547],"luv":[62.8555901763931075,98.9037041004629458,56.2630191441096059],"rgb":[0.933333333333333348,0.466666666666666674,0.0666666666666666657],"xyz":[0.419568119571752329,0.314140182501449761,0.0438442684226693288],"hpluv":[29.6341042910547,229.71421718860654,62.8555901763931075],"hsluv":[29.6341042910547,97.9532933827149463,62.8555901763931075]},"#ee7722":{"lch":[62.9183073649527955,111.855609649988921,28.7604537228304977],"luv":[62.9183073649527955,98.0569879769147406,53.8191835600085398],"rgb":[0.933333333333333348,0.466666666666666674,0.133333333333333331],"xyz":[0.421443477710229386,0.314890325756840561,0.0537211546186485284],"hpluv":[28.7604537228304977,225.59011469442973,62.9183073649527955],"hsluv":[28.7604537228304977,94.206312745702121,62.9183073649527955]},"#ee7733":{"lch":[63.0213536795682501,108.794922632811733,27.2836719807386174],"luv":[63.0213536795682501,96.6912591797812411,49.8711899688373208],"rgb":[0.933333333333333348,0.466666666666666674,0.2],"xyz":[0.424531228442687092,0.316125426049823688,0.0699833084762596647],"hpluv":[27.2836719807386174,219.058559128587405,63.0213536795682501],"hsluv":[27.2836719807386174,88.1668112455654,63.0213536795682501]},"#ee7744":{"lch":[63.1696562136619235,104.634411539935968,25.0668522383795889],"luv":[63.1696562136619235,94.7793214210065571,44.3310309972846497],"rgb":[0.933333333333333348,0.466666666666666674,0.266666666666666663],"xyz":[0.428989223686906,0.317908624147511254,0.0934620834291463],"hpluv":[25.0668522383795889,210.186756956079222,63.1696562136619235],"hsluv":[25.0668522383795889,79.7210233436604199,63.1696562136619235]},"#ee7755":{"lch":[63.3671413614491286,99.5393983003294096,21.9455950678528],"luv":[63.3671413614491286,92.3266881357997278,37.2004633286522051],"rgb":[0.933333333333333348,0.466666666666666674,0.333333333333333315],"xyz":[0.434951637726268,0.320293589763256115,0.124864130703120219],"hpluv":[21.9455950678528,199.328877993420377,63.3671413614491286],"hsluv":[21.9455950678528,76.6090179557391,63.3671413614491286]},"#ee7766":{"lch":[63.6169573916324822,93.8195852400781263,17.7221756586824775],"luv":[63.6169573916324822,89.367258373090749,28.5588463614608763],"rgb":[0.933333333333333348,0.466666666666666674,0.4],"xyz":[0.442536633499776177,0.323327588072659433,0.16481177511026418],"hpluv":[17.7221756586824775,187.13711975631665,63.6169573916324822],"hsluv":[17.7221756586824775,76.9903860669667,63.6169573916324822]},"#ee7777":{"lch":[63.9215909451051232,87.936547917610838,12.1770506300618937],"luv":[63.9215909451051232,85.9580160709841863,18.5487447771187846],"rgb":[0.933333333333333348,0.466666666666666674,0.466666666666666674],"xyz":[0.451850646519978083,0.327053193280740229,0.21386557701666209],"hpluv":[12.1770506300618937,174.56660414904394,63.9215909451051232],"hsluv":[12.1770506300618937,77.4248320836617268,63.9215909451051232]},"#ee7788":{"lch":[64.2829374304473,82.5014209284754543,5.11726519711922112],"luv":[64.2829374304473,82.1725895095950847,7.35866757674724514],"rgb":[0.933333333333333348,0.466666666666666674,0.533333333333333326],"xyz":[0.462991063621921883,0.331509360121517827,0.272538440420234229],"hpluv":[5.11726519711922112,162.85647909200884,64.2829374304473],"hsluv":[5.11726519711922112,77.9003779592442669,64.2829374304473]},"#ee7799":{"lch":[64.7023501026032477,78.2413537817778177,356.48599323172067],"luv":[64.7023501026032477,78.0942478632934893,-4.79561177242263259],"rgb":[0.933333333333333348,0.466666666666666674,0.6],"xyz":[0.476048027730994638,0.336732145765147,0.341305118061352164],"hpluv":[356.48599323172067,153.446019679421255,64.7023501026032477],"hsluv":[356.48599323172067,78.4035888028378167,64.7023501026032477]},"#ee77aa":{"lch":[65.1806796634753596,75.8992199041959,346.522692233148291],"luv":[65.1806796634753596,73.8091300431969302,-17.6890899803221124],"rgb":[0.933333333333333348,0.466666666666666674,0.66666666666666663],"xyz":[0.491105720696247139,0.342755222951248106,0.420608967678350765],"hpluv":[346.522692233148291,147.76029654451807,65.1806796634753596],"hsluv":[346.522692233148291,78.9205551316135256,65.1806796634753596]},"#ee77bb":{"lch":[65.7183104585581646,76.0514193956389875,335.85959217762661],"luv":[65.7183104585581646,69.4004166910179094,-31.1030634376174824],"rgb":[0.933333333333333348,0.466666666666666674,0.733333333333333282],"xyz":[0.508243312803583813,0.349610259794182865,0.510866952776992456],"hpluv":[335.85959217762661,146.845370988132231,65.7183104585581646],"hsluv":[335.85959217762661,79.4377328719524627,65.7183104585581646]},"#ee77cc":{"lch":[66.3151963922866,78.9180750862202416,325.378996221060731],"luv":[66.3151963922866,64.9439055461397459,-44.8369457894756067],"rgb":[0.933333333333333348,0.466666666666666674,0.8],"xyz":[0.527535688247305568,0.357327209971671667,0.612473463447262612],"hpluv":[325.378996221060731,151.008971652655617,66.3151963922866],"hsluv":[325.378996221060731,79.9425706591808307,66.3151963922866]},"#ee77dd":{"lch":[66.9708980107196652,84.3115421117289543,315.859798591258766],"luv":[66.9708980107196652,60.5051526262217152,-58.7159487612646842],"rgb":[0.933333333333333348,0.466666666666666674,0.866666666666666696],"xyz":[0.549054013797939056,0.365934540191925173,0.725803311347268609],"hpluv":[315.859798591258766,159.749768323538632,66.9708980107196652],"hsluv":[315.859798591258766,80.4238985377879345,66.9708980107196652]},"#ee77ee":{"lch":[67.6846211881785251,91.7687338274624409,307.715012949244453],"luv":[67.6846211881785251,56.1380858067324056,-72.5948746830766112],"rgb":[0.933333333333333348,0.466666666666666674,0.933333333333333348],"xyz":[0.572866194064113765,0.37545941229839519,0.851214127415791832],"hpluv":[307.715012949244453,172.045795420537047,67.6846211881785251],"hsluv":[307.715012949244453,80.8720902094370757,67.6846211881785251]},"#ee77ff":{"lch":[68.4552572311626761,100.746525491660947,300.997699928034137],"luv":[68.4552572311626761,51.8848298156272918,-86.3587102361150585],"rgb":[0.933333333333333348,0.466666666666666674,1],"xyz":[0.599037242473945186,0.385927831662327914,0.989048315707573789],"hpluv":[300.997699928034137,186.750854251257437,68.4552572311626761],"hsluv":[300.997699928034137,99.9999999999982,68.4552572311626761]},"#ee8800":{"lch":[66.3576417146455,105.981377873447272,36.6492300119340797],"luv":[66.3576417146455,85.0293774107247771,63.2618165491550428],"rgb":[0.933333333333333348,0.533333333333333326,0],"xyz":[0.440628823797085678,0.35788025575153648,0.045873620032903642],"hpluv":[36.6492300119340797,202.664622836431278,66.3576417146455],"hsluv":[36.6492300119340797,100.000000000002288,66.3576417146455]},"#ee8811":{"lch":[66.3886714607036907,104.946342152180421,36.2201184819273792],"luv":[66.3886714607036907,84.6657638625926552,62.0116373004794923],"rgb":[0.933333333333333348,0.533333333333333326,0.0666666666666666657],"xyz":[0.441640489296722782,0.358284921951391333,0.0512017249976592717],"hpluv":[36.2201184819273792,200.591559481147556,66.3886714607036907],"hsluv":[36.2201184819273792,98.1954604930108701,66.3886714607036907]},"#ee8822":{"lch":[66.4461305943750773,103.062674429887437,35.4099902294173745],"luv":[66.4461305943750773,83.9988395226221201,59.7169140151578],"rgb":[0.933333333333333348,0.533333333333333326,0.133333333333333331],"xyz":[0.443515847435199839,0.359035065206782134,0.0610786111936384712],"hpluv":[35.4099902294173745,196.820821024497235,66.4461305943750773],"hsluv":[35.4099902294173745,94.8869488142181581,66.4461305943750773]},"#ee8833":{"lch":[66.5405621290638578,100.059958052790449,34.0337853874148877],"luv":[66.5405621290638578,82.920456825626232,56.0017235927220369],"rgb":[0.933333333333333348,0.533333333333333326,0.2],"xyz":[0.446603598167657545,0.36027016549976526,0.0773407650512496214],"hpluv":[34.0337853874148877,190.815292572549708,66.5405621290638578],"hsluv":[34.0337853874148877,89.5408718212573689,66.5405621290638578]},"#ee8844":{"lch":[66.6765193585480347,95.9403990837829639,31.9512880443390657],"luv":[66.6765193585480347,81.4052672986078107,50.7714745934935223],"rgb":[0.933333333333333348,0.533333333333333326,0.266666666666666663],"xyz":[0.45106159341187646,0.362053363597452826,0.10081954000413626],"hpluv":[31.9512880443390657,182.586190035925256,66.6765193585480347],"hsluv":[31.9512880443390657,82.0371002457568608,66.6765193585480347]},"#ee8855":{"lch":[66.8576614114874559,90.8274017958005,28.983496619036984],"luv":[66.8576614114874559,79.4521157428502391,44.0111147434430805],"rgb":[0.933333333333333348,0.533333333333333326,0.333333333333333315],"xyz":[0.457024007451238445,0.364438329213197687,0.132221587278110175],"hpluv":[28.983496619036984,172.387208051834335,66.8576614114874559],"hsluv":[28.983496619036984,74.7174368883009663,66.8576614114874559]},"#ee8866":{"lch":[67.0869600103699213,84.978663004295683,24.8971939400565283],"luv":[67.0869600103699213,77.081139807049837,35.7752854921339249],"rgb":[0.933333333333333348,0.533333333333333326,0.4],"xyz":[0.464609003224746631,0.367472327522601,0.172169231685254109],"hpluv":[24.8971939400565283,160.735241770302764,67.0869600103699213],"hsluv":[24.8971939400565283,75.0669061044520447,67.0869600103699213]},"#ee8877":{"lch":[67.3668077908477727,78.8051510957513841,19.4009345351312952],"luv":[67.3668077908477727,74.3303771171996743,26.1772205713113095],"rgb":[0.933333333333333348,0.533333333333333326,0.466666666666666674],"xyz":[0.473923016244948536,0.371197932730681801,0.221223033591652019],"hpluv":[19.4009345351312952,148.438980876884,67.3668077908477727],"hsluv":[19.4009345351312952,75.4672397967126329,67.3668077908477727]},"#ee8888":{"lch":[67.6990830402889117,72.8916076032019191,12.177050630062066],"luv":[67.6990830402889117,71.2515799877231757,15.3752661190709663],"rgb":[0.933333333333333348,0.533333333333333326,0.533333333333333326],"xyz":[0.485063433346892336,0.375654099571459399,0.279895896995224214],"hpluv":[12.177050630062066,136.626224949154164,67.6990830402889117],"hsluv":[12.177050630062066,75.9081099773692927,67.6990830402889117]},"#ee8899":{"lch":[68.0851935471165319,67.9986383575237312,2.99916583787236446],"luv":[68.0851935471165319,67.9055003914663615,3.55778513430191889],"rgb":[0.933333333333333348,0.533333333333333326,0.6],"xyz":[0.498120397455965036,0.380876885215088556,0.348662574636342093],"hpluv":[2.99916583787236446,126.732168582193651,68.0851935471165319],"hsluv":[2.99916583787236446,76.3775584855855385,68.0851935471165319]},"#ee88aa":{"lch":[68.5261104708773274,64.9933943358063573,351.976176804910949],"luv":[68.5261104708773274,64.3571165389368,-9.07209226602857832],"rgb":[0.933333333333333348,0.533333333333333326,0.66666666666666663],"xyz":[0.513178090421217648,0.386899962401189679,0.427966424253340694],"hpluv":[351.976176804910949,120.351764916629207,68.5261104708773274],"hsluv":[351.976176804910949,76.8628030471707859,68.5261104708773274]},"#ee88bb":{"lch":[69.0223979406526098,64.6433047463018,339.810246341231903],"luv":[69.0223979406526098,60.6712812589502875,-22.3103670727442456],"rgb":[0.933333333333333348,0.533333333333333326,0.733333333333333282],"xyz":[0.530315682528554211,0.393754999244124437,0.51822440935198244],"hpluv":[339.810246341231903,118.842788638920595,69.0223979406526098],"hsluv":[339.810246341231903,77.3509666785266887,69.0223979406526098]},"#ee88cc":{"lch":[69.5742414545850778,67.3203562589766307,327.709288072293873],"luv":[69.5742414545850778,56.9091584539883399,-35.9635656031820687],"rgb":[0.933333333333333348,0.533333333333333326,0.8],"xyz":[0.549608057972276,0.401471949421613239,0.619830920022252596],"hpluv":[327.709288072293873,122.782720563937247,69.5742414545850778],"hsluv":[327.709288072293873,77.8296635442389686,69.5742414545850778]},"#ee88dd":{"lch":[70.1814766713242,72.856404222049747,316.817937357318669],"luv":[70.1814766713242,53.1256441200966663,-49.8570112721525547],"rgb":[0.933333333333333348,0.533333333333333326,0.866666666666666696],"xyz":[0.571126383522909564,0.410079279641866745,0.733160767922258594],"hpluv":[316.817937357318669,131.729959343498166,70.1814766713242],"hsluv":[316.817937357318669,78.2874043120714163,70.1814766713242]},"#ee88ee":{"lch":[70.8436192863675558,80.7013698438951224,307.715012949244851],"luv":[70.8436192863675558,49.367799206375345,-63.839889537812887],"rgb":[0.933333333333333348,0.533333333333333326,0.933333333333333348],"xyz":[0.594938563789084274,0.419604151748336762,0.858571583990781817],"hpluv":[307.715012949244851,144.550464850223619,70.8436192863675558],"hsluv":[307.715012949244851,78.7138135635212848,70.8436192863675558]},"#ee88ff":{"lch":[71.5598961203093182,90.2054153167292583,300.42003582834775],"luv":[71.5598961203093182,45.674190228859068,-77.7874366424399426],"rgb":[0.933333333333333348,0.533333333333333326,1],"xyz":[0.621109612198915695,0.430072571112269486,0.996405772282563662],"hpluv":[300.42003582834775,159.956626210428567,71.5598961203093182],"hsluv":[300.42003582834775,99.99999999999784,71.5598961203093182]},"#ee9900":{"lch":[70.1492527845175715,98.9919938823364731,44.3502140795235036],"luv":[70.1492527845175715,70.7872313214223112,69.1995862317686772],"rgb":[0.933333333333333348,0.6,0],"xyz":[0.466498424249553179,0.409619456656472147,0.0544968201837259],"hpluv":[44.3502140795235036,179.06732625175573,70.1492527845175715],"hsluv":[44.3502140795235036,100.000000000002217,70.1492527845175715]},"#ee9911":{"lch":[70.1776126165771785,97.9766822185852533,43.9766782844564119],"luv":[70.1776126165771785,70.5062245085518526,68.0316291449155273],"rgb":[0.933333333333333348,0.6,0.0666666666666666657],"xyz":[0.467510089749190283,0.410024122856327,0.0598249251484815267],"hpluv":[43.9766782844564119,177.15910010767405,70.1776126165771785],"hsluv":[43.9766782844564119,98.4152296143538337,70.1776126165771785]},"#ee9922":{"lch":[70.2301348691785,96.1222676294158447,43.2696050504519505],"luv":[70.2301348691785,69.9901292501651824,65.8852953379296622],"rgb":[0.933333333333333348,0.6,0.133333333333333331],"xyz":[0.46938544788766734,0.410774266111717801,0.0697018113444607262],"hpluv":[43.2696050504519505,173.676009463775955,70.2301348691785],"hsluv":[43.2696050504519505,95.5057584668238,70.2301348691785]},"#ee9933":{"lch":[70.3164728806357573,93.1473438817036339,42.0626701373461103],"luv":[70.3164728806357573,69.1537511222041417,62.4034163964169508],"rgb":[0.933333333333333348,0.6,0.2],"xyz":[0.472473198620125046,0.412009366404700927,0.0859639652020718625],"hpluv":[42.0626701373461103,168.094198140054317,70.3164728806357573],"hsluv":[42.0626701373461103,90.7937976503380213,70.3164728806357573]},"#ee9944":{"lch":[70.4408210614760719,89.024296887742608,40.221678197216157],"luv":[70.4408210614760719,67.9746586813449483,57.4871395488729533],"rgb":[0.933333333333333348,0.6,0.266666666666666663],"xyz":[0.476931193864343961,0.413792564502388494,0.109442740154958501],"hpluv":[40.221678197216157,160.370125602871781,70.4408210614760719],"hsluv":[40.221678197216157,84.1577311163605657,70.4408210614760719]},"#ee9955":{"lch":[70.6065752665828654,83.8291063606938138,37.5652459120346904],"luv":[70.6065752665828654,66.4479455240540631,51.1076276974862154],"rgb":[0.933333333333333348,0.6,0.333333333333333315],"xyz":[0.482893607903705946,0.416177530118133354,0.140844787428932416],"hpluv":[37.5652459120346904,150.656896294971034,70.6065752665828654],"hsluv":[37.5652459120346904,75.5772228053980797,70.6065752665828654]},"#ee9966":{"lch":[70.8165243284349373,77.7550236522342,33.8383101580563],"luv":[70.8165243284349373,64.5842808158336652,43.297971946282189],"rgb":[0.933333333333333348,0.6,0.4],"xyz":[0.490478603677214131,0.419211528427536673,0.180792431836076378],"hpluv":[33.8383101580563,139.326323276972687,70.8165243284349373],"hsluv":[33.8383101580563,72.525293376848623,70.8165243284349373]},"#ee9977":{"lch":[71.0729506656700778,71.1378337295946,28.6840524218341386],"luv":[71.0729506656700778,62.4077841236731601,34.1446901949989154],"rgb":[0.933333333333333348,0.6,0.466666666666666674],"xyz":[0.499792616697416037,0.422937133635617468,0.229846233742474287],"hpluv":[28.6840524218341386,127.009327518651787,71.0729506656700778],"hsluv":[28.6840524218341386,72.8885787597460677,71.0729506656700778]},"#ee9988":{"lch":[71.3776900371935312,64.4963091800695878,21.6331741754282376],"luv":[71.3776900371935312,59.9533946760230378,23.7773918811996943],"rgb":[0.933333333333333348,0.6,0.533333333333333326],"xyz":[0.510933033799359837,0.427393300476395066,0.288519097146046455],"hpluv":[21.6331741754282376,114.659937381049531,71.3776900371935312],"hsluv":[21.6331741754282376,73.2902809537896189,71.3776900371935312]},"#ee9999":{"lch":[71.732171153908709,58.5818834203282179,12.1770506300621602],"luv":[71.732171153908709,57.263818011494017,12.3568690136061505],"rgb":[0.933333333333333348,0.6,0.6],"xyz":[0.523989997908432592,0.432616086120024224,0.35728577478716439],"hpluv":[12.1770506300621602,103.630759412975706,71.732171153908709],"hsluv":[12.1770506300621602,73.7196701825771186,71.732171153908709]},"#ee99aa":{"lch":[72.1374451439022408,54.3863410009709725,0.0659165211073427237],"luv":[72.1374451439022408,54.3863050092105,0.0625693137293968082],"rgb":[0.933333333333333348,0.6,0.66666666666666663],"xyz":[0.539047690873685093,0.438639163306125346,0.436589624404162935],"hpluv":[0.0659165211073427237,95.6683780017161,72.1374451439022408],"hsluv":[0.0659165211073427237,74.1649147609968082,72.1374451439022408]},"#ee99bb":{"lch":[72.5942101669252366,52.9692652640659247,345.882936464906891],"luv":[72.5942101669252366,51.3695627363271683,-12.9194073739288822],"rgb":[0.933333333333333348,0.6,0.733333333333333282],"xyz":[0.556185282981021767,0.445494200149060104,0.526847609502804737],"hpluv":[345.882936464906891,92.5894045166522091,72.5942101669252366],"hsluv":[345.882936464906891,74.6136876066909878,72.5942101669252366]},"#ee99cc":{"lch":[73.1028341171650737,55.013164482536844,331.314039518972208],"luv":[73.1028341171650737,48.2610582375421515,-26.4067893575727517],"rgb":[0.933333333333333348,0.6,0.8],"xyz":[0.575477658424743521,0.453211150326548906,0.628454120173074893],"hpluv":[331.314039518972208,95.4930444317639342,73.1028341171650737],"hsluv":[331.314039518972208,75.0536815693659491,73.1028341171650737]},"#ee99dd":{"lch":[73.6633770412179274,60.4388711558699896,318.269971219550712],"luv":[73.6633770412179274,45.1048908137830935,-40.2294167403973049],"rgb":[0.933333333333333348,0.6,0.866666666666666696],"xyz":[0.596995983975377,0.461818480546802412,0.74178396807308089],"hpluv":[318.269971219550712,104.112780668711437,73.6633770412179274],"hsluv":[318.269971219550712,75.472992612571872,73.6633770412179274]},"#ee99ee":{"lch":[74.2756141069900337,68.5596754700476083,307.71501294924542],"luv":[74.2756141069900337,41.9403078139404499,-54.2350410807456953],"rgb":[0.933333333333333348,0.6,0.933333333333333348],"xyz":[0.620808164241551719,0.471343352653272429,0.867194784141604114],"hpluv":[307.71501294924542,117.128296895720368,74.2756141069900337],"hsluv":[307.71501294924542,75.8603506282489235,74.2756141069900337]},"#ee99ff":{"lch":[74.9390594560707,78.5455210447045857,299.603294913962486],"luv":[74.9390594560707,38.8008486558083519,-68.2927010724659],"rgb":[0.933333333333333348,0.6,1],"xyz":[0.64697921265138314,0.481811772017205153,1.00502897243338585],"hpluv":[299.603294913962486,133.000267199001968,74.9390594560707],"hsluv":[299.603294913962486,99.9999999999973284,74.9390594560707]},"#dd0000":{"lch":[46.1435564305616239,155.182233977468201,12.1770506300617765],"luv":[46.1435564305616239,151.69070515099267,32.7330981276182555],"rgb":[0.866666666666666696,0,0],"xyz":[0.298181282529475455,0.153749723804264049,0.0139772476185688679],"hpluv":[12.1770506300617765,426.746789183125316,46.1435564305616239],"hsluv":[12.1770506300617765,100.000000000002217,46.1435564305616239]},"#dd0011":{"lch":[46.1980288678146636,153.577384001942391,11.5987087531524224],"luv":[46.1980288678146636,150.441300178721519,30.8776306962803169],"rgb":[0.866666666666666696,0,0.0666666666666666657],"xyz":[0.29919294802911256,0.154154390004118902,0.0193053525833244977],"hpluv":[11.5987087531524224,421.835520233675084,46.1980288678146636],"hsluv":[11.5987087531524224,99.9999999999964473,46.1980288678146636]},"#dd0022":{"lch":[46.2987546285526292,150.712226421231577,10.5179424282654246],"luv":[46.2987546285526292,148.17992816752087,27.5115263319381462],"rgb":[0.866666666666666696,0,0.133333333333333331],"xyz":[0.301068306167589617,0.15490453325950973,0.0291822387793036972],"hpluv":[10.5179424282654246,413.065099977246746,46.2987546285526292],"hsluv":[10.5179424282654246,99.9999999999964615,46.2987546285526292]},"#dd0033":{"lch":[46.4638920568500637,146.293058552209629,8.71533624525386585],"luv":[46.4638920568500637,144.603865814948932,22.1671146505918131],"rgb":[0.866666666666666696,0,0.2],"xyz":[0.304156056900047322,0.156139633552492829,0.0454443926369148404],"hpluv":[8.71533624525386585,399.528220173505417,46.4638920568500637],"hsluv":[8.71533624525386585,99.9999999999966,46.4638920568500637]},"#dd0044":{"lch":[46.7007828741672242,140.527307525302433,6.06736355557067153],"luv":[46.7007828741672242,139.740117429456177,14.853408400522655],"rgb":[0.866666666666666696,0,0.266666666666666663],"xyz":[0.308614052144266238,0.157922831650180423,0.0689231675898014789],"hpluv":[6.06736355557067153,381.835137536210595,46.7007828741672242],"hsluv":[6.06736355557067153,99.9999999999967315,46.7007828741672242]},"#dd0055":{"lch":[47.0148448700731194,133.854751810486647,2.4577968894866693],"luv":[47.0148448700731194,133.731616129679537,5.74015936982693],"rgb":[0.866666666666666696,0,0.333333333333333315],"xyz":[0.314576466183628223,0.160307797265925256,0.10032521486377538],"hpluv":[2.4577968894866693,361.275168455412427,47.0148448700731194],"hsluv":[2.4577968894866693,99.9999999999969873,47.0148448700731194]},"#dd0066":{"lch":[47.4099042919878073,126.898325188331157,357.792852491951692],"luv":[47.4099042919878073,126.80418183984473,-4.88716722969802841],"rgb":[0.866666666666666696,0,0.4],"xyz":[0.322161461957136408,0.163341795575328547,0.140272859270919342],"hpluv":[357.792852491951692,339.645713706877359,47.4099042919878073],"hsluv":[357.792852491951692,99.9999999999972857,47.4099042919878073]},"#dd0077":{"lch":[47.8883827301537,120.388643903007392,352.036106438093952],"luv":[47.8883827301537,119.227564738695264,-16.6797298325047478],"rgb":[0.866666666666666696,0,0.466666666666666674],"xyz":[0.331475474977338314,0.16706740078340937,0.189326661177317251],"hpluv":[352.036106438093952,319.002934776287759,47.8883827301537],"hsluv":[352.036106438093952,99.9999999999974136,47.8883827301537]},"#dd0088":{"lch":[48.4514347566520058,115.064311489444805,345.260130057314882],"luv":[48.4514347566520058,111.277652945923506,-29.2759241252361342],"rgb":[0.866666666666666696,0,0.533333333333333326],"xyz":[0.342615892079282114,0.171523567624186968,0.247999524580889419],"hpluv":[345.260130057314882,301.351479235409442,48.4514347566520058],"hsluv":[345.260130057314882,99.9999999999976836,48.4514347566520058]},"#dd0099":{"lch":[49.0990738312553816,111.554442433955828,337.69359677942],"luv":[49.0990738312553816,103.206522936464793,-42.3415546492536166],"rgb":[0.866666666666666696,0,0.6],"xyz":[0.355672856188354869,0.176746353267816125,0.316766202222007354],"hpluv":[337.69359677942,288.305479360883112,49.0990738312553816],"hsluv":[337.69359677942,99.9999999999979252,49.0990738312553816]},"#dd00aa":{"lch":[49.8303011832281442,110.265023964610052,329.72204926251294],"luv":[49.8303011832281442,95.2237329190616606,-55.5951094870335041],"rgb":[0.866666666666666696,0,0.66666666666666663],"xyz":[0.370730549153607369,0.18276943045391722,0.396070051839005954],"hpluv":[329.72204926251294,280.791263168904948,49.8303011832281442],"hsluv":[329.72204926251294,99.9999999999981526,49.8303011832281442]},"#dd00bb":{"lch":[50.6432416523731064,111.311454300018838,321.811503537589374],"luv":[50.6432416523731064,87.4886923962170613,-68.8183737179635244],"rgb":[0.866666666666666696,0,0.733333333333333282],"xyz":[0.387868141260944044,0.189624467296851978,0.486328036937647701],"hpluv":[321.811503537589374,278.905890401213071,50.6432416523731064],"hsluv":[321.811503537589374,99.9999999999984,50.6432416523731064]},"#dd00cc":{"lch":[51.5352850119508901,114.534817141075266,314.3830496716472],"luv":[51.5352850119508901,80.1116001600253753,-81.8557014345352201],"rgb":[0.866666666666666696,0,0.8],"xyz":[0.407160516704665798,0.19734141747434078,0.587934547607917857],"hpluv":[314.3830496716472,282.014975724645751,51.5352850119508901],"hsluv":[314.3830496716472,99.9999999999986215,51.5352850119508901]},"#dd00dd":{"lch":[52.5032286812834883,119.593841400887641,307.715012949243601],"luv":[52.5032286812834883,73.1596596193909647,-94.6062952735996419],"rgb":[0.866666666666666696,0,0.866666666666666696],"xyz":[0.428678842255299286,0.205948747694594314,0.701264395507923854],"hpluv":[307.715012949243601,289.042783730483222,52.5032286812834883],"hsluv":[307.715012949243601,99.9999999999987779,52.5032286812834883]},"#dd00ee":{"lch":[53.5434168792756111,126.080010820296707,301.921476351261958],"luv":[53.5434168792756111,66.6656277920787659,-107.01337860068783],"rgb":[0.866666666666666696,0,0.933333333333333348],"xyz":[0.452491022521474051,0.215473619801064359,0.826675211576447078],"hpluv":[301.921476351261958,298.799235277631283,53.5434168792756111],"hsluv":[301.921476351261958,99.999999999998991,53.5434168792756111]},"#dd00ff":{"lch":[54.6518715304170399,133.605457484958208,296.990855958497434],"luv":[54.6518715304170399,60.6366090811706258,-119.053013019000375],"rgb":[0.866666666666666696,0,1],"xyz":[0.478662070931305417,0.225942039164997055,0.964509399868228923],"hpluv":[296.990855958497434,310.211923209940835,54.6518715304170399],"hsluv":[296.990855958497434,99.99999999999919,54.6518715304170399]},"#dd1100":{"lch":[46.6790301132195,152.538998994032681,12.7564763340959253],"luv":[46.6790301132195,148.773935032481603,33.6817824506429915],"rgb":[0.866666666666666696,0.0666666666666666657,0],"xyz":[0.300185682790403863,0.157758524326120919,0.0146453810388783197],"hpluv":[12.7564763340959253,414.665968881342394,46.6790301132195],"hsluv":[12.7564763340959253,100.000000000002373,46.6790301132195]},"#dd1111":{"lch":[46.7325769897078942,150.969760125239,12.1770506300617818],"luv":[46.7325769897078942,147.573010021229663,31.8445471870185592],"rgb":[0.866666666666666696,0.0666666666666666657,0.0666666666666666657],"xyz":[0.301197348290040967,0.158163190525975772,0.0199734860036339529],"hpluv":[12.1770506300617818,409.92986676092562,46.7325769897078942],"hsluv":[12.1770506300617818,96.0592738250283,46.7325769897078942]},"#dd1122":{"lch":[46.8315975390355774,148.166934443607602,11.093898425687982],"luv":[46.8315975390355774,145.398162733087418,28.509905932130728],"rgb":[0.866666666666666696,0.0666666666666666657,0.133333333333333331],"xyz":[0.303072706428518,0.1589133337813666,0.0298503721996131455],"hpluv":[11.093898425687982,401.468660625611221,46.8315975390355774],"hsluv":[11.093898425687982,96.1199649520447821,46.8315975390355774]},"#dd1133":{"lch":[46.9939567691892393,143.840838530693645,9.28627571582045697],"luv":[46.9939567691892393,141.955717705878527,23.2112265902085468],"rgb":[0.866666666666666696,0.0666666666666666657,0.2],"xyz":[0.30616045716097573,0.160148434074349699,0.0461125260572242957],"hpluv":[9.28627571582045697,388.400266865181436,46.9939567691892393],"hsluv":[9.28627571582045697,96.2159198798013477,46.9939567691892393]},"#dd1144":{"lch":[47.2268997120704555,138.191174032002039,6.62861883301083665],"luv":[47.2268997120704555,137.267398010546174,15.951865839373701],"rgb":[0.866666666666666696,0.0666666666666666657,0.266666666666666663],"xyz":[0.310618452405194645,0.161931632172037293,0.0695913010101109342],"hpluv":[6.62861883301083665,371.304486157060069,47.2268997120704555],"hsluv":[6.62861883301083665,96.346372634165391,47.2268997120704555]},"#dd1155":{"lch":[47.5357948285950442,131.646215003298352,3.00154982487266553],"luv":[47.5357948285950442,131.465612026054913,6.89338663571585908],"rgb":[0.866666666666666696,0.0666666666666666657,0.333333333333333315],"xyz":[0.31658086644455663,0.164316597787782126,0.100993348284084836],"hpluv":[3.00154982487266553,351.420379681935685,47.5357948285950442],"hsluv":[3.00154982487266553,96.5074087268808114,47.5357948285950442]},"#dd1166":{"lch":[47.9244613368761776,124.817323026056556,358.307054390798669],"luv":[47.9244613368761776,124.762840903711279,-3.68750010524401839],"rgb":[0.866666666666666696,0.0666666666666666657,0.4],"xyz":[0.324165862218064815,0.167350596097185417,0.140940992691228811],"hpluv":[358.307054390798669,330.488955339688346,47.9244613368761776],"hsluv":[358.307054390798669,96.6928417837132912,47.9244613368761776]},"#dd1177":{"lch":[48.3953520744879313,118.427317384197096,352.504166614065639],"luv":[48.3953520744879313,117.415279069986227,-15.4493282615978131],"rgb":[0.866666666666666696,0.0666666666666666657,0.466666666666666674],"xyz":[0.333479875238266721,0.17107620130526624,0.189994794597626721],"hpluv":[352.504166614065639,310.51856077863863,48.3953520744879313],"hsluv":[352.504166614065639,96.8952584834877229,48.3953520744879313]},"#dd1188":{"lch":[48.949686611979061,113.213254375126112,345.662599129740954],"luv":[48.949686611979061,109.687147393784173,-28.0351683216148473],"rgb":[0.866666666666666696,0.0666666666666666657,0.533333333333333326],"xyz":[0.344620292340210521,0.175532368146043838,0.248667658001198888],"hpluv":[345.662599129740954,293.48552443008623,48.949686611979061],"hsluv":[345.662599129740954,97.1070447043031209,48.949686611979061]},"#dd1199":{"lch":[49.5875717372425,109.808639676001164,338.012756373247385],"luv":[49.5875717372425,101.821953610845213,-41.1123717433662961],"rgb":[0.866666666666666696,0.0666666666666666657,0.6],"xyz":[0.357677256449283276,0.180755153789673,0.317434335642316767],"hpluv":[338.012756373247385,280.997849503034615,49.5875717372425],"hsluv":[338.012756373247385,97.321211179253126,49.5875717372425]},"#dd11aa":{"lch":[50.3081241313593779,108.626384639058173,329.948207544292131],"luv":[50.3081241313593779,94.0240738412992556,-54.3982074892042462],"rgb":[0.866666666666666696,0.0666666666666666657,0.66666666666666663],"xyz":[0.372734949414535777,0.18677823097577409,0.396738185259315368],"hpluv":[329.948207544292131,273.991145484396441,50.3081241313593779],"hsluv":[329.948207544292131,97.5319211216277751,50.3081241313593779]},"#dd11bb":{"lch":[51.1095995740137,109.78676639377484,321.947120969557943],"luv":[51.1095995740137,86.4507346157054855,-67.6712979010019495],"rgb":[0.866666666666666696,0.0666666666666666657,0.733333333333333282],"xyz":[0.389872541521872451,0.193633267818708849,0.486996170357957114],"hpluv":[321.947120969557943,272.57551535007633,51.1095995740137],"hsluv":[321.947120969557943,97.7347175386083791,51.1095995740137]},"#dd11cc":{"lch":[51.9895276454598303,113.13117809908816,314.441471026924035],"luv":[51.9895276454598303,79.2122218564644527,-80.7718228508547469],"rgb":[0.866666666666666696,0.0666666666666666657,0.8],"xyz":[0.409164916965594205,0.20135021799619765,0.588602681028227326],"hpluv":[314.441471026924035,276.12502270002949,51.9895276454598303],"hsluv":[314.441471026924035,97.9265130550616,51.9895276454598303]},"#dd11dd":{"lch":[52.9448482611329325,118.314931067086022,307.715012949243601],"luv":[52.9448482611329325,72.3773062506166553,-93.594596282658145],"rgb":[0.866666666666666696,0.0666666666666666657,0.866666666666666696],"xyz":[0.430683242516227693,0.209957548216451184,0.701932528928233324],"hpluv":[307.715012949243601,283.566663729067216,52.9448482611329325],"hsluv":[307.715012949243601,98.1054292618058525,52.9448482611329325]},"#dd11ee":{"lch":[53.9720454332022257,124.924845967379298,301.881652150577509],"luv":[53.9720454332022257,65.9811112999591103,-106.078791902980541],"rgb":[0.866666666666666696,0.0666666666666666657,0.933333333333333348],"xyz":[0.454495422782402458,0.219482420322921229,0.827343344996756547],"hpluv":[301.881652150577509,293.71036424495378,53.9720454332022257],"hsluv":[301.881652150577509,98.2705657762439841,53.9720454332022257]},"#dd11ff":{"lch":[55.067273793018515,132.56906123155207,296.926443611211937],"luv":[55.067273793018515,60.0334023394080774,-118.197066796810802],"rgb":[0.866666666666666696,0.0666666666666666657,1],"xyz":[0.480666471192233824,0.229950839686853925,0.965177533288538392],"hpluv":[296.926443611211937,305.483621811531123,55.067273793018515],"hsluv":[296.926443611211937,99.9999999999990763,55.067273793018515]},"#dd2200":{"lch":[47.6481385708110494,147.881667770992,13.8451074484812633],"luv":[47.6481385708110494,143.585141583480663,35.3877772568702937],"rgb":[0.866666666666666696,0.133333333333333331,0],"xyz":[0.303901306525171777,0.165189771795656887,0.0158839222838009289],"hpluv":[13.8451074484812633,393.829031299888356,47.6481385708110494],"hsluv":[13.8451074484812633,100.000000000002302,47.6481385708110494]},"#dd2211":{"lch":[47.7000692420668,146.371743885583,13.2640103652051735],"luv":[47.7000692420668,142.467011758872331,33.583298953557744],"rgb":[0.866666666666666696,0.133333333333333331,0.0666666666666666657],"xyz":[0.304912972024808882,0.16559443799551174,0.0212120272485565586],"hpluv":[13.2640103652051735,389.383517616197651,47.7000692420668],"hsluv":[13.2640103652051735,96.2235359913314596,47.7000692420668]},"#dd2222":{"lch":[47.796111526211412,143.672697420673273,12.1770506300617871],"luv":[47.796111526211412,140.440127868319678,30.3053537920670948],"rgb":[0.866666666666666696,0.133333333333333331,0.133333333333333331],"xyz":[0.306788330163285938,0.166344581250902568,0.0310889134445357582],"hpluv":[12.1770506300617871,381.435408792809369,47.796111526211412],"hsluv":[12.1770506300617871,89.3821391188339618,47.796111526211412]},"#dd2233":{"lch":[47.9536166692339805,139.501418135148583,10.3611027729364178],"luv":[47.9536166692339805,137.226679529052944,25.0895214611231978],"rgb":[0.866666666666666696,0.133333333333333331,0.2],"xyz":[0.309876080895743644,0.167579681543885667,0.0473510673021469],"hpluv":[10.3611027729364178,369.144652707036585,47.9536166692339805],"hsluv":[10.3611027729364178,89.634195646670733,47.9536166692339805]},"#dd2244":{"lch":[48.1796580724099073,134.044487106872765,7.68678657448498281],"luv":[48.1796580724099073,132.839973125453383,17.9294747210675],"rgb":[0.866666666666666696,0.133333333333333331,0.266666666666666663],"xyz":[0.314334076139962559,0.169362879641573261,0.0708298422550335399],"hpluv":[7.68678657448498281,353.040533161258963,48.1796580724099073],"hsluv":[7.68678657448498281,89.9776949827144819,48.1796580724099073]},"#dd2255":{"lch":[48.4795139291676236,127.710640494506933,4.02871777991100277],"luv":[48.4795139291676236,127.395062601571667,8.9724979943620351],"rgb":[0.866666666666666696,0.133333333333333331,0.333333333333333315],"xyz":[0.320296490179324544,0.171747845257318094,0.102231889529007441],"hpluv":[4.02871777991100277,334.278275235680212,48.4795139291676236],"hsluv":[4.02871777991100277,90.4030378986951746,48.4795139291676236]},"#dd2266":{"lch":[48.8569858046774499,121.091623353111601,359.280669781128381],"luv":[48.8569858046774499,121.082080247128843,-1.52022673298942879],"rgb":[0.866666666666666696,0.133333333333333331,0.4],"xyz":[0.32788148595283273,0.174781843566721384,0.142179533936151403],"hpluv":[359.280669781128381,314.504423311283745,48.8569858046774499],"hsluv":[359.280669781128381,90.8946273178398627,48.8569858046774499]},"#dd2277":{"lch":[49.3145747506863046,114.897314975199777,353.392641366134796],"luv":[49.3145747506863046,114.134166521370943,-13.2206286152450421],"rgb":[0.866666666666666696,0.133333333333333331,0.466666666666666674],"xyz":[0.337195498973034635,0.178507448774802208,0.191233335842549312],"hpluv":[353.392641366134796,295.64729776044,49.3145747506863046],"hsluv":[353.392641366134796,91.4334620569677128,49.3145747506863046]},"#dd2288":{"lch":[49.8536069462695934,109.863045744465836,346.42832123602642],"luv":[49.8536069462695934,106.795352255968297,-25.780643063628979],"rgb":[0.866666666666666696,0.133333333333333331,0.533333333333333326],"xyz":[0.348335916074978436,0.182963615615579805,0.24990619924612148],"hpluv":[346.42832123602642,279.636833718457694,49.8536069462695934],"hsluv":[346.42832123602642,91.999736258284841,49.8536069462695934]},"#dd2299":{"lch":[50.4743452384724947,106.631383564155598,338.620922954440232],"luv":[50.4743452384724947,99.2939711585852507,-38.8710593162073792],"rgb":[0.866666666666666696,0.133333333333333331,0.6],"xyz":[0.361392880184051135,0.188186401259208963,0.318672876887239387],"hpluv":[338.620922954440232,268.07337181170567,50.4743452384724947],"hsluv":[338.620922954440232,92.5749897333771088,50.4743452384724947]},"#dd22aa":{"lch":[51.176101525576982,105.62881092572934,330.379319008457628],"luv":[51.176101525576982,91.8248770713425699,-52.2076397514415902],"rgb":[0.866666666666666696,0.133333333333333331,0.66666666666666663],"xyz":[0.376450573149303691,0.194209478445310058,0.397976726504238],"hpluv":[330.379319008457628,261.911470041672374,51.176101525576982],"hsluv":[330.379319008457628,93.1435427232804898,51.176101525576982]},"#dd22bb":{"lch":[51.9573548685870321,106.984993341056935,322.205396597718504],"luv":[51.9573548685870321,84.5409044706425306,-65.5638945721781425],"rgb":[0.866666666666666696,0.133333333333333331,0.733333333333333282],"xyz":[0.393588165256640365,0.201064515288244816,0.488234711602879734],"hpluv":[322.205396597718504,261.285408571692301,51.9573548685870321],"hsluv":[322.205396597718504,93.6931794305449301,51.9573548685870321]},"#dd22cc":{"lch":[52.8158750154556174,110.541708291411879,314.55250800555325],"luv":[52.8158750154556174,77.5519304210182838,-78.7728846745956],"rgb":[0.866666666666666696,0.133333333333333331,0.8],"xyz":[0.412880540700362064,0.208781465465733618,0.58984122227315],"hpluv":[314.55250800555325,265.583456637160452,52.8158750154556174],"hsluv":[314.55250800555325,94.2152138812719073,52.8158750154556174]},"#dd22dd":{"lch":[53.7488483860564088,115.947384169062644,307.715012949243658],"luv":[53.7488483860564088,70.9289965118926204,-91.721716891171],"rgb":[0.866666666666666696,0.133333333333333331,0.866666666666666696],"xyz":[0.434398866250995663,0.217388795685987152,0.703171070173155943],"hpluv":[307.715012949243658,273.735496610715643,53.7488483860564088],"hsluv":[307.715012949243658,94.704144859729837,53.7488483860564088]},"#dd22ee":{"lch":[54.7530025006588374,122.779599443276055,301.806367069585178],"luv":[54.7530025006588374,64.7110170709106,-104.342293961267828],"rgb":[0.866666666666666696,0.133333333333333331,0.933333333333333348],"xyz":[0.458211046517170373,0.226913667792457197,0.828581886241679166],"hpluv":[301.806367069585178,284.549350776984397,54.7530025006588374],"hsluv":[301.806367069585178,95.1571011878196629,54.7530025006588374]},"#dd22ff":{"lch":[55.8247247862810525,130.638613434108407,296.804995701950531],"luv":[55.8247247862810525,58.9121835814083425,-116.601037498200881],"rgb":[0.866666666666666696,0.133333333333333331,1],"xyz":[0.484382094927001794,0.237382087156389893,0.966416074533461],"hpluv":[296.804995701950531,296.950662194199822,55.8247247862810525],"hsluv":[296.804995701950531,99.9999999999989768,55.8247247862810525]},"#dd3300":{"lch":[49.1823134049741526,140.84390252957769,15.6779143459349193],"luv":[49.1823134049741526,135.603943521894649,38.06015476941716],"rgb":[0.866666666666666696,0.2,0],"xyz":[0.310019028614182623,0.17742521597367869,0.0179231629801378106],"hpluv":[15.6779143459349193,363.386194305474646,49.1823134049741526],"hsluv":[15.6779143459349193,100.000000000002331,49.1823134049741526]},"#dd3311":{"lch":[49.2318310772226226,139.415415721210906,15.0950854994101622],"luv":[49.2318310772226226,134.60488288385605,36.3067988748864323],"rgb":[0.866666666666666696,0.2,0.0666666666666666657],"xyz":[0.311030694113819728,0.177829882173533543,0.0232512679448934403],"hpluv":[15.0950854994101622,359.338818773581409,49.2318310772226226],"hsluv":[15.0950854994101622,96.4660724045404834,49.2318310772226226]},"#dd3322":{"lch":[49.3234253076193,136.858666305461554,14.0037238091571297],"luv":[49.3234253076193,132.791226888227897,33.117738516222083],"rgb":[0.866666666666666696,0.2,0.133333333333333331],"xyz":[0.312906052252296785,0.178580025428924372,0.0331281541408726399],"hpluv":[14.0037238091571297,352.093818956611813,49.3234253076193],"hsluv":[14.0037238091571297,90.0546185843159321,49.3234253076193]},"#dd3333":{"lch":[49.4736766963079901,132.899088309008249,12.1770506300618315],"luv":[49.4736766963079901,129.908920002044738,28.0328410488111714],"rgb":[0.866666666666666696,0.2,0.2],"xyz":[0.31599380298475449,0.179815125721907471,0.0493903079984837831],"hpluv":[12.1770506300618315,340.868713502871344,49.4736766963079901],"hsluv":[12.1770506300618315,79.876105021286179,49.4736766963079901]},"#dd3344":{"lch":[49.6893958667399289,127.704341644457742,9.47932118493828391],"luv":[49.6893958667399289,125.960552293014786,21.031836364974712],"rgb":[0.866666666666666696,0.2,0.266666666666666663],"xyz":[0.320451798228973406,0.181598323819595064,0.0728690829513704286],"hpluv":[9.47932118493828391,326.122882655454703,49.6893958667399289],"hsluv":[9.47932118493828391,80.502956859434363,49.6893958667399289]},"#dd3355":{"lch":[49.9757165444531495,121.655077778432485,5.77481987360355742],"luv":[49.9757165444531495,121.037681249067731,12.2408197080725127],"rgb":[0.866666666666666696,0.2,0.333333333333333315],"xyz":[0.326414212268335391,0.183983289435339897,0.10427113022534433],"hpluv":[5.77481987360355742,308.89475746512926,49.9757165444531495],"hsluv":[5.77481987360355742,81.2827465905028674,49.9757165444531495]},"#dd3366":{"lch":[50.3364012453720164,115.314978813651479,0.942739432835561],"luv":[50.3364012453720164,115.29936949267524,1.8972963354308543],"rgb":[0.866666666666666696,0.2,0.4],"xyz":[0.333999208041843576,0.187017287744743188,0.144218774632488278],"hpluv":[0.942739432835561,290.698564526315124,50.3364012453720164],"hsluv":[0.942739432835561,82.1889615211792375,50.3364012453720164]},"#dd3377":{"lch":[50.77400791740952,109.376176789803836,354.916348657894],"luv":[50.77400791740952,108.945933542464203,-9.69183231981436],"rgb":[0.866666666666666696,0.2,0.466666666666666674],"xyz":[0.343313221062045482,0.190742892952824,0.193272576538886187],"hpluv":[354.916348657894,273.35096965093777,50.77400791740952],"hsluv":[354.916348657894,83.1884512053650269,50.77400791740952]},"#dd3388":{"lch":[51.2900053848270545,104.574014460431073,347.747121452304157],"luv":[51.2900053848270545,102.191864987712989,-22.1934051173651383],"rgb":[0.866666666666666696,0.2,0.533333333333333326],"xyz":[0.354453638163989282,0.195199059793601609,0.251945439942458382],"hpluv":[347.747121452304157,258.720214242298141,51.2900053848270545],"hsluv":[347.747121452304157,84.245872474104587,51.2900053848270545]},"#dd3399":{"lch":[51.8848727297214509,101.568582070491487,339.671486537323062],"luv":[51.8848727297214509,95.2425012264059347,-35.2851643605103433],"rgb":[0.866666666666666696,0.2,0.6],"xyz":[0.367510602273062,0.200421845437230767,0.320712117583576262],"hpluv":[339.671486537323062,248.403642764366595,51.8848727297214509],"hsluv":[339.671486537323062,85.3275173092541763,51.8848727297214509]},"#dd33aa":{"lch":[52.5581975758694284,100.811065681036794,331.124654782349864],"luv":[52.5581975758694284,88.2774684157494,-48.6822301651504219],"rgb":[0.866666666666666696,0.2,0.66666666666666663],"xyz":[0.382568295238314537,0.206444922623331861,0.400015967200574862],"hpluv":[331.124654782349864,243.392431352391867,52.5581975758694284],"hsluv":[331.124654782349864,86.4040244757801,52.5581975758694284]},"#dd33bb":{"lch":[53.3087788146031301,102.447919096954379,322.651217662355],"luv":[53.3087788146031301,81.4417156804123579,-62.1516136100020091],"rgb":[0.866666666666666696,0.2,0.733333333333333282],"xyz":[0.399705887345651212,0.21329995946626662,0.490273952299216609],"hpluv":[322.651217662355,243.861776984359892,53.3087788146031301],"hsluv":[322.651217662355,87.4518397844355633,53.3087788146031301]},"#dd33cc":{"lch":[54.1347343907921612,106.321268361530926,314.743497623169446],"luv":[54.1347343907921612,74.8431687457043751,-75.5163041872859253],"rgb":[0.866666666666666696,0.2,0.8],"xyz":[0.418998262789372911,0.221016909643755421,0.59188046296948682],"hpluv":[314.743497623169446,249.220329072313831,54.1347343907921612],"hsluv":[314.743497623169446,88.4535853271675734,54.1347343907921612]},"#dd33dd":{"lch":[55.033612168624586,112.066789743934578,307.715012949243715],"luv":[55.033612168624586,68.5551036430149,-88.6519211749340741],"rgb":[0.866666666666666696,0.2,0.866666666666666696],"xyz":[0.44051658834000651,0.229624239864008955,0.705210310869492818],"hpluv":[307.715012949243715,258.397459164480438,55.033612168624586],"hsluv":[307.715012949243715,89.3976510430439077,55.033612168624586]},"#dd33ee":{"lch":[56.0025007026426351,119.245240694744666,301.678101579798295],"luv":[56.0025007026426351,62.6212128139869506,-101.479116738632214],"rgb":[0.866666666666666696,0.2,0.933333333333333348],"xyz":[0.464328768606181219,0.239149111970479,0.830621126938016],"hpluv":[301.678101579798295,270.192295422478139,56.0025007026426351],"hsluv":[301.678101579798295,90.277343199481848,56.0025007026426351]},"#dd33ff":{"lch":[57.0381364623091116,127.442655532056975,296.59904001960814],"luv":[57.0381364623091116,57.0616979163907772,-113.954346472440875],"rgb":[0.866666666666666696,0.2,1],"xyz":[0.49049981701601264,0.249617531334411696,0.968455315229797886],"hpluv":[296.59904001960814,283.523336448078851,57.0381364623091116],"hsluv":[296.59904001960814,99.9999999999989626,57.0381364623091116]},"#dd4400":{"lch":[51.2775121999195278,131.902040393952689,18.409420821930695],"luv":[51.2775121999195278,125.151834557466444,41.6553305951168156],"rgb":[0.866666666666666696,0.266666666666666663,0],"xyz":[0.318851599097148664,0.19509035693961102,0.0208673531411264039],"hpluv":[18.409420821930695,326.410329295551833,51.2775121999195278],"hsluv":[18.409420821930695,100.000000000002245,51.2775121999195278]},"#dd4411":{"lch":[51.3239968707682124,130.563017922041524,17.8265447991253865],"luv":[51.3239968707682124,124.294382399750674,39.9700907276414128],"rgb":[0.866666666666666696,0.266666666666666663,0.0666666666666666657],"xyz":[0.319863264596785768,0.195495023139465873,0.0261954581058820371],"hpluv":[17.8265447991253865,322.804096021626094,51.3239968707682124],"hsluv":[17.8265447991253865,96.7659447415066154,51.3239968707682124]},"#dd4422":{"lch":[51.4099976690743148,128.162025810787327,16.7333496749677373],"luv":[51.4099976690743148,122.735013936090269,36.9001519513490237],"rgb":[0.866666666666666696,0.266666666666666663,0.133333333333333331],"xyz":[0.321738622735262825,0.196245166394856702,0.0360723443018612297],"hpluv":[16.7333496749677373,316.337811591652041,51.4099976690743148],"hsluv":[16.7333496749677373,90.8878404873512551,51.4099976690743148]},"#dd4433":{"lch":[51.551120550377874,124.432504768689228,14.8985084842763058],"luv":[51.551120550377874,120.249428964759446,31.9925472049216744],"rgb":[0.866666666666666696,0.266666666666666663,0.2],"xyz":[0.324826373467720531,0.197480266687839801,0.0523344981594723729],"hpluv":[14.8985084842763058,306.291581325991444,51.551120550377874],"hsluv":[14.8985084842763058,81.5276169642245634,51.551120550377874]},"#dd4444":{"lch":[51.7538349343952575,119.518854000271219,12.1770506300618191],"luv":[51.7538349343952575,116.829734805674121,25.2105042943215345],"rgb":[0.866666666666666696,0.266666666666666663,0.266666666666666663],"xyz":[0.329284368711939446,0.199263464785527394,0.0758132731123590115],"hpluv":[12.1770506300618191,293.044254198223086,51.7538349343952575],"hsluv":[12.1770506300618191,68.6693518559736,51.7538349343952575]},"#dd4455":{"lch":[52.0230766847265045,113.767549619287195,8.41751308754220773],"luv":[52.0230766847265045,112.542004033713866,16.6539086839248256],"rgb":[0.866666666666666696,0.266666666666666663,0.333333333333333315],"xyz":[0.335246782751301431,0.201648430401272227,0.107215320386332927],"hpluv":[8.41751308754220773,277.499175779034886,52.0230766847265045],"hsluv":[8.41751308754220773,69.8262296658756867,52.0230766847265045]},"#dd4466":{"lch":[52.3625377834239316,107.708396397149357,3.47572472865958737],"luv":[52.3625377834239316,107.51027478189765,6.52989056311981209],"rgb":[0.866666666666666696,0.266666666666666663,0.4],"xyz":[0.342831778524809616,0.204682428710675518,0.147162964793476875],"hpluv":[3.47572472865958737,261.016642983210886,52.3625377834239316],"hsluv":[3.47572472865958737,71.1800009153795088,52.3625377834239316]},"#dd4477":{"lch":[52.7748219535637304,102.013560717275851,357.256373562230806],"luv":[52.7748219535637304,101.896624345108023,-4.88308481282748108],"rgb":[0.866666666666666696,0.266666666666666663,0.466666666666666674],"xyz":[0.352145791545011522,0.208408033918756341,0.196216766699874784],"hpluv":[357.256373562230806,245.284698321799027,52.7748219535637304],"hsluv":[357.256373562230806,72.6848757644217898,52.7748219535637304]},"#dd4488":{"lch":[53.2615487789460502,97.4233940898595137,349.787328406912707],"luv":[53.2615487789460502,95.8798587184095368,-17.273401753155067],"rgb":[0.866666666666666696,0.266666666666666663,0.533333333333333326],"xyz":[0.363286208646955322,0.212864200759533939,0.254889630103446951],"hpluv":[349.787328406912707,232.107295472344475,53.2615487789460502],"hsluv":[349.787328406912707,74.290572198007979,53.2615487789460502]},"#dd4499":{"lch":[53.8234397136373133,94.6288173232078123,341.30539151945959],"luv":[53.8234397136373133,89.63624285692255,-30.330793502376995],"rgb":[0.866666666666666696,0.266666666666666663,0.6],"xyz":[0.376343172756028,0.218086986403163097,0.323656307744564886],"hpluv":[341.30539151945959,223.095746339835301,53.8234397136373133],"hsluv":[341.30539151945959,75.9477058190526577,53.8234397136373133]},"#dd44aa":{"lch":[54.4604007326765327,94.1226543521493539,332.285935566136516],"luv":[54.4604007326765327,83.3248558176969425,-43.7726223255380802],"rgb":[0.866666666666666696,0.266666666666666663,0.66666666666666663],"xyz":[0.391400865721280578,0.224110063589264191,0.402960157361563487],"hpluv":[332.285935566136516,219.307083848265933,54.4604007326765327],"hsluv":[332.285935566136516,77.6118806813578175,54.4604007326765327]},"#dd44bb":{"lch":[55.1716077278512387,96.0796222427451596,323.344264550451],"luv":[55.1716077278512387,77.0786382371216,-57.3600674495728526],"rgb":[0.866666666666666696,0.266666666666666663,0.733333333333333282],"xyz":[0.408538457828617252,0.23096510043219895,0.493218142460205233],"hpluv":[323.344264550451,220.981019921853772,55.1716077278512387],"hsluv":[323.344264550451,79.2461809113807334,55.1716077278512387]},"#dd44cc":{"lch":[55.9555962107488511,100.342448880687911,315.038748994660807],"luv":[55.9555962107488511,71.0007950362134,-70.9048246002984],"rgb":[0.866666666666666696,0.266666666666666663,0.8],"xyz":[0.427830833272338951,0.238682050609687751,0.594824653130475389],"hpluv":[315.038748994660807,227.551915064947707,55.9555962107488511],"hsluv":[315.038748994660807,80.8221578956601547,55.9555962107488511]},"#dd44dd":{"lch":[56.8103543983327484,106.525561993860563,307.715012949243828],"luv":[56.8103543983327484,65.1653443433699664,-84.2684594300729515],"rgb":[0.866666666666666696,0.266666666666666663,0.866666666666666696],"xyz":[0.44934915882297255,0.247289380829941285,0.708154501030481387],"hpluv":[307.715012949243828,237.939016458104504,56.8103543983327484],"hsluv":[307.715012949243828,82.3196529548951474,56.8103543983327484]},"#dd44ee":{"lch":[57.7334174818232384,114.162073161526394,301.482814132357476],"luv":[57.7334174818232384,59.6203198077272134,-97.3570563162323452],"rgb":[0.866666666666666696,0.266666666666666663,0.933333333333333348],"xyz":[0.473161339089147259,0.256814252936411302,0.83356531709900461],"hpluv":[301.482814132357476,250.91920763959763,57.7334174818232384],"hsluv":[301.482814132357476,85.8927976857303577,57.7334174818232384]},"#dd44ff":{"lch":[58.721960397178492,122.814959128704743,296.287773174859751],"luv":[58.721960397178492,54.3922733794591196,-110.113554035820684],"rgb":[0.866666666666666696,0.266666666666666663,1],"xyz":[0.49933238749897868,0.267282672300344,0.971399505390786455],"hpluv":[296.287773174859751,265.393357493052918,58.721960397178492],"hsluv":[296.287773174859751,99.9999999999987779,58.721960397178492]},"#dd5500":{"lch":[53.8905970004369834,121.845910621274882,22.2085433527856502],"luv":[53.8905970004369834,112.806678507237621,46.055175814369008],"rgb":[0.866666666666666696,0.333333333333333315,0],"xyz":[0.330664855811494629,0.218716870368303284,0.0248051053792416147],"hpluv":[22.2085433527856502,286.904453583707834,53.8905970004369834],"hsluv":[22.2085433527856502,100.000000000002217,53.8905970004369834]},"#dd5511":{"lch":[53.9336739056601573,120.58904296901602,21.6306448037720749],"luv":[53.9336739056601573,112.097097503939963,44.4517492948856656],"rgb":[0.866666666666666696,0.333333333333333315,0.0666666666666666657],"xyz":[0.331676521311131733,0.219121536568158137,0.0301332103439972479],"hpluv":[21.6306448037720749,283.71818310283129,53.9336739056601573],"hsluv":[21.6306448037720749,97.0955711707227493,53.9336739056601573]},"#dd5522":{"lch":[54.0133869328819856,118.329807147086328,20.5443811064534074],"luv":[54.0133869328819856,110.804107011743554,41.5258128011568957],"rgb":[0.866666666666666696,0.333333333333333315,0.133333333333333331],"xyz":[0.33355187944960879,0.219871679823548966,0.0400100965399764405],"hpluv":[20.5443811064534074,277.99185559962018,54.0133869328819856],"hsluv":[20.5443811064534074,91.805999212684128,54.0133869328819856]},"#dd5533":{"lch":[54.1442392255445526,114.805940194650788,18.7140712474621722],"luv":[54.1442392255445526,108.736323489647134,36.8349814433582736],"rgb":[0.866666666666666696,0.333333333333333315,0.2],"xyz":[0.336639630182066496,0.221106780116532065,0.0562722503975875837],"hpluv":[18.7140712474621722,269.061420184977408,54.1442392255445526],"hsluv":[18.7140712474621722,83.3546452149230674,54.1442392255445526]},"#dd5544":{"lch":[54.3323026853354207,110.135081135525823,15.9827981501284579],"luv":[54.3323026853354207,105.877744255237971,30.3255563535325479],"rgb":[0.866666666666666696,0.333333333333333315,0.266666666666666663],"xyz":[0.341097625426285411,0.222889978214219658,0.0797510253504742223],"hpluv":[15.9827981501284579,257.221277658214035,54.3323026853354207],"hsluv":[15.9827981501284579,71.6878656400709104,54.3323026853354207]},"#dd5555":{"lch":[54.5822696158357132,104.625049281135261,12.1770506300618937],"luv":[54.5822696158357132,102.271033836367579,22.0689051636128752],"rgb":[0.866666666666666696,0.333333333333333315,0.333333333333333315],"xyz":[0.347060039465647396,0.225274943829964491,0.111153072624448138],"hpluv":[12.1770506300618937,243.233512665758,54.5822696158357132],"hsluv":[12.1770506300618937,61.8784513389384,54.5822696158357132]},"#dd5566":{"lch":[54.8977244977922254,98.7674373059184205,7.11744080010036573],"luv":[54.8977244977922254,98.0063618739055897,12.2376347477602359],"rgb":[0.866666666666666696,0.333333333333333315,0.4],"xyz":[0.354645035239155582,0.228308942139367782,0.151100717031592086],"hpluv":[7.11744080010036573,228.296245111676484,54.8977244977922254],"hsluv":[7.11744080010036573,62.7979151590930655,54.8977244977922254]},"#dd5577":{"lch":[55.2812881935381597,93.2135187108595886,0.661514811515945267],"luv":[55.2812881935381597,93.2073060454778783,1.07618316489082022],"rgb":[0.866666666666666696,0.333333333333333315,0.466666666666666674],"xyz":[0.363959048259357487,0.232034547347448605,0.20015451893799],"hpluv":[0.661514811515945267,213.963687644495565,55.2812881935381597],"hsluv":[0.661514811515945267,63.8225359413096456,55.2812881935381597]},"#dd5588":{"lch":[55.7347110848163538,88.7163187329837,352.791835078768599],"luv":[55.7347110848163538,88.0151786426913532,-11.1316457915027787],"rgb":[0.866666666666666696,0.333333333333333315,0.533333333333333326],"xyz":[0.375099465361301287,0.236490714188226203,0.258827382341562162],"hpluv":[352.791835078768599,201.984054112510194,55.7347110848163538],"hsluv":[352.791835078768599,64.9173177009572,55.7347110848163538]},"#dd5599":{"lch":[56.2589463845586408,86.0173277442407169,343.733753082454825],"luv":[56.2589463845586408,82.5740942724548717,-24.0935598727929836],"rgb":[0.866666666666666696,0.333333333333333315,0.6],"xyz":[0.388156429470374,0.241713499831855361,0.327594059982680097],"hpluv":[343.733753082454825,194.014271994181229,56.2589463845586408],"hsluv":[343.733753082454825,66.0466553819121,56.2589463845586408]},"#dd55aa":{"lch":[56.8542178605490278,85.677853149792881,334.018383993549605],"luv":[56.8542178605490278,77.0187914763158545,-37.5339883290498477],"rgb":[0.866666666666666696,0.333333333333333315,0.66666666666666663],"xyz":[0.403214122435626543,0.247736577017956455,0.406897909599678698],"hpluv":[334.018383993549605,191.225239227061849,56.8542178605490278],"hsluv":[334.018383993549605,67.3075554564469485,56.8542178605490278]},"#dd55bb":{"lch":[57.5200884026389332,87.9206422548043633,324.375348896731964],"luv":[57.5200884026389332,71.4663144117056817,-51.2113780219251638],"rgb":[0.866666666666666696,0.333333333333333315,0.733333333333333282],"xyz":[0.420351714542963217,0.254591613860891242,0.497155894698320444],"hpluv":[324.375348896731964,193.959311397505388,57.5200884026389332],"hsluv":[324.375348896731964,69.5366313504716,57.5200884026389332]},"#dd55cc":{"lch":[58.2555317670128829,92.5910381182408315,315.474469199465034],"luv":[58.2555317670128829,66.0116746837007895,-64.9273374262858596],"rgb":[0.866666666666666696,0.333333333333333315,0.8],"xyz":[0.439644089986684916,0.262308564038380043,0.5987624053685906],"hpluv":[315.474469199465034,201.683843426221756,58.2555317670128829],"hsluv":[315.474469199465034,71.7082017587958802,58.2555317670128829]},"#dd55dd":{"lch":[59.0590075291469532,99.2700295618383848,307.715012949244056],"luv":[59.0590075291469532,60.7268860008133231,-78.5288742174016363],"rgb":[0.866666666666666696,0.333333333333333315,0.866666666666666696],"xyz":[0.461162415537318515,0.270915894258633549,0.712092253268596598],"hpluv":[307.715012949244056,213.290412049590259,59.0590075291469532],"hsluv":[307.715012949244056,73.7919865345850923,59.0590075291469532]},"#dd55ee":{"lch":[59.9285380001613674,107.447476486145689,301.201070052482692],"luv":[59.9285380001613674,55.6624113436061592,-91.905691698915],"rgb":[0.866666666666666696,0.333333333333333315,0.933333333333333348],"xyz":[0.484974595803493225,0.280440766365103566,0.837503069337119821],"hpluv":[301.201070052482692,227.510719406260364,59.9285380001613674],"hsluv":[301.201070052482692,84.9240358585231405,59.9285380001613674]},"#dd55ff":{"lch":[60.8617852443614,116.651127585902827,295.843561463814751],"luv":[60.8617852443614,50.8500320114402413,-104.984569397117028],"rgb":[0.866666666666666696,0.333333333333333315,1],"xyz":[0.511145644213324646,0.29090918572903629,0.975337257628901666],"hpluv":[295.843561463814751,243.211205533984923,60.8617852443614],"hsluv":[295.843561463814751,99.9999999999987,60.8617852443614]},"#dd6600":{"lch":[56.9556719941368783,111.624872970007345,27.247071009398578],"luv":[56.9556719941368783,99.2390381331236568,51.1050445257873349],"rgb":[0.866666666666666696,0.4,0],"xyz":[0.345692913517341105,0.248772985779996625,0.0298144579478569621],"hpluv":[27.247071009398578,248.69286407076,56.9556719941368783],"hsluv":[27.247071009398578,100.000000000002402,56.9556719941368783]},"#dd6611":{"lch":[56.9952083090352204,110.431802069127656,26.6846840374429064],"luv":[56.9952083090352204,98.6698726856829325,49.5927326573774181],"rgb":[0.866666666666666696,0.4,0.0666666666666666657],"xyz":[0.346704579016978209,0.249177651979851478,0.0351425629126125919],"hpluv":[26.6846840374429064,245.864111809588593,56.9952083090352204],"hsluv":[26.6846840374429064,97.4289366186781,56.9952083090352204]},"#dd6622":{"lch":[57.0683850250612181,108.280332786330632,25.6245441521289443],"luv":[57.0683850250612181,97.630674939023308,46.8282156319165637],"rgb":[0.866666666666666696,0.4,0.133333333333333331],"xyz":[0.348579937155455266,0.249927795235242306,0.0450194491085917914],"hpluv":[25.6245441521289443,240.764984433182946,57.0683850250612181],"hsluv":[25.6245441521289443,92.7369917538900239,57.0683850250612181]},"#dd6633":{"lch":[57.1885511035567617,104.905985735707603,23.8291565941278485],"luv":[57.1885511035567617,95.9631904105633566,42.3831561992078036],"rgb":[0.866666666666666696,0.4,0.2],"xyz":[0.351667687887912972,0.251162895528225405,0.0612816029662029346],"hpluv":[23.8291565941278485,232.771873337598265,57.1885511035567617],"hsluv":[23.8291565941278485,85.2149281001260306,57.1885511035567617]},"#dd6644":{"lch":[57.3613500282636153,100.395707721520722,21.1283100845564071],"luv":[57.3613500282636153,93.6466609873464222,36.1884099516133162],"rgb":[0.866666666666666696,0.4,0.266666666666666663],"xyz":[0.356125683132131887,0.252946093625912971,0.0847603779190895801],"hpluv":[21.1283100845564071,222.093121414046323,57.3613500282636153],"hsluv":[21.1283100845564071,74.7790089775498785,57.3613500282636153]},"#dd6655":{"lch":[57.5911977652478555,95.0134939889914136,17.3206113628181804],"luv":[57.5911977652478555,90.7049894048208927,28.2872575034667619],"rgb":[0.866666666666666696,0.4,0.333333333333333315],"xyz":[0.362088097171493872,0.255331059241657832,0.116162425193063482],"hpluv":[17.3206113628181804,209.347849744778358,57.5911977652478555],"hsluv":[17.3206113628181804,61.5516693045169205,57.5911977652478555]},"#dd6666":{"lch":[57.8815358558834703,89.2064417623026742,12.1770506300619559],"luv":[57.8815358558834703,87.1993378887650579,18.8166076552624659],"rgb":[0.866666666666666696,0.4,0.4],"xyz":[0.369673092945002058,0.25836505755106115,0.156110069600207457],"hpluv":[12.1770506300619559,195.566965385494854,57.8815358558834703],"hsluv":[12.1770506300619559,60.6635523422702,57.8815358558834703]},"#dd6677":{"lch":[58.2349645673757834,83.6008411979688901,5.48003957367995387],"luv":[58.2349645673757834,83.2187459143753188,7.98379467713524704],"rgb":[0.866666666666666696,0.4,0.466666666666666674],"xyz":[0.378987105965203963,0.262090662759141946,0.205163871506605366],"hpluv":[5.48003957367995387,182.165511808695555,58.2349645673757834],"hsluv":[5.48003957367995387,61.6238417996400329,58.2349645673757834]},"#dd6688":{"lch":[58.6533262634944208,78.9686504698842,357.125632416080862],"luv":[58.6533262634944208,78.8692993006444,-3.95997283577995],"rgb":[0.866666666666666696,0.4,0.533333333333333326],"xyz":[0.390127523067147763,0.266546829599919544,0.263836734910177506],"hpluv":[357.125632416080862,170.8446551494321,58.6533262634944208],"hsluv":[357.125632416080862,62.6596910240402778,58.6533262634944208]},"#dd6699":{"lch":[59.1377678367746853,76.1279623836736192,347.292482429378936],"luv":[59.1377678367746853,74.2632604984211184,-16.746187531306056],"rgb":[0.866666666666666696,0.4,0.6],"xyz":[0.403184487176220463,0.271769615243548701,0.332603412551295441],"hpluv":[347.292482429378936,163.349798950832565,59.1377678367746853],"hsluv":[347.292482429378936,63.7390009960191435,59.1377678367746853]},"#dd66aa":{"lch":[59.6887956605557406,75.751758533498986,336.577260120739709],"luv":[59.6887956605557406,69.5095811529117,-30.1122408476074845],"rgb":[0.866666666666666696,0.4,0.66666666666666663],"xyz":[0.418242180141473,0.277792692429649823,0.411907262168294042],"hpluv":[336.577260120739709,161.042027442088397,59.6887956605557406],"hsluv":[336.577260120739709,64.8305690383666473,59.6887956605557406]},"#dd66bb":{"lch":[60.3063295400458372,78.1477005551706,325.894443158435308],"luv":[60.3063295400458372,64.706761589723726,-43.8189240697585518],"rgb":[0.866666666666666696,0.4,0.733333333333333282],"xyz":[0.435379772248809693,0.284647729272584582,0.502165247266935788],"hpluv":[325.894443158435308,164.434383230317081,60.3063295400458372],"hsluv":[325.894443158435308,65.9059953936301213,60.3063295400458372]},"#dd66cc":{"lch":[60.9897585015337427,83.1712006992562891,316.109248272524042],"luv":[60.9897585015337427,59.9384091909213694,-57.6613885491638314],"rgb":[0.866666666666666696,0.4,0.8],"xyz":[0.454672147692531392,0.292364679450073384,0.603771757937205944],"hpluv":[316.109248272524042,173.043537218511,60.9897585015337427],"hsluv":[316.109248272524042,66.9408479310096709,60.9897585015337427]},"#dd66dd":{"lch":[61.7379991889007158,90.3518241723814555,307.715012949244283],"luv":[61.7379991889007158,55.2713135142553753,-71.4740094977595675],"rgb":[0.866666666666666696,0.4,0.866666666666666696],"xyz":[0.476190473243165,0.30097200967032689,0.717101605837211942],"hpluv":[307.715012949244283,185.705044478150711,61.7379991889007158],"hsluv":[307.715012949244283,67.9151328937623759,61.7379991889007158]},"#dd66ee":{"lch":[62.5495564285741779,99.1126076890086125,300.803780654240427],"luv":[62.5495564285741779,50.7555210146825431,-85.1304063742412183],"rgb":[0.866666666666666696,0.4,0.933333333333333348],"xyz":[0.500002653509339701,0.310496881776796907,0.842512421905735165],"hpluv":[300.803780654240427,201.068480083703747,62.5495564285741779],"hsluv":[300.803780654240427,83.670703518064812,62.5495564285741779]},"#dd66ff":{"lch":[63.4225848554444696,108.928953372808309,295.226788235463459],"luv":[63.4225848554444696,46.4257694276883512,-98.5401685402585628],"rgb":[0.866666666666666696,0.4,1],"xyz":[0.526173701919171122,0.320965301140729631,0.980346610197517],"hpluv":[295.226788235463459,217.940889521273107,63.4225848554444696],"hsluv":[295.226788235463459,99.9999999999986073,63.4225848554444696]},"#dd7700":{"lch":[60.3985006876916088,102.209421710697811,33.6568691403047779],"luv":[60.3985006876916088,85.0762157619203,56.6463008330327753],"rgb":[0.866666666666666696,0.466666666666666674,0],"xyz":[0.364146651570758706,0.285680461886832382,0.0359657039656626626],"hpluv":[33.6568691403047779,214.735624532269611,60.3985006876916088],"hsluv":[33.6568691403047779,100.000000000002245,60.3985006876916088]},"#dd7711":{"lch":[60.4345564785723894,101.058408313912437,33.1281817520222],"luv":[60.4345564785723894,84.6313647704988,55.2298287886556736],"rgb":[0.866666666666666696,0.466666666666666674,0.0666666666666666657],"xyz":[0.36515831707039581,0.286085128086687235,0.0412938089304182923],"hpluv":[33.1281817520222,212.190746676882327,60.4345564785723894],"hsluv":[33.1281817520222,97.7465438968969238,60.4345564785723894]},"#dd7722":{"lch":[60.5013044729937803,98.9745052833742136,32.1281810047412648],"luv":[60.5013044729937803,83.8175940663154364,52.6361436754539582],"rgb":[0.866666666666666696,0.466666666666666674,0.133333333333333331],"xyz":[0.367033675208872867,0.286835271342078035,0.0511706951263974918],"hpluv":[32.1281810047412648,207.585936448863947,60.5013044729937803],"hsluv":[32.1281810047412648,93.6262478826975126,60.5013044729937803]},"#dd7733":{"lch":[60.6109510167574115,95.6833141687104813,30.4242910043150516],"luv":[60.6109510167574115,82.5076313520097813,48.4539717565960331],"rgb":[0.866666666666666696,0.466666666666666674,0.2],"xyz":[0.370121425941330573,0.288070371635061162,0.067432848984008642],"hpluv":[30.4242910043150516,200.320058173129354,60.6109510167574115],"hsluv":[30.4242910043150516,86.9991150080846722,60.6109510167574115]},"#dd7744":{"lch":[60.7687036553482756,91.2360291121886888,27.8356422373186483],"luv":[60.7687036553482756,80.6791699404734857,42.6014617809804932],"rgb":[0.866666666666666696,0.466666666666666674,0.266666666666666663],"xyz":[0.374579421185549488,0.289853569732748728,0.0909116239368952805],"hpluv":[27.8356422373186483,190.513488615549676,60.7687036553482756],"hsluv":[27.8356422373186483,77.760618312285672,60.7687036553482756]},"#dd7755":{"lch":[60.9786842032445122,85.8448802225428125,24.131655223886618],"luv":[60.9786842032445122,78.3427622472179479,35.096368243717265],"rgb":[0.866666666666666696,0.466666666666666674,0.333333333333333315],"xyz":[0.380541835224911473,0.292238535348493589,0.122313671210869182],"hpluv":[24.131655223886618,178.63875223296418,60.9786842032445122],"hsluv":[24.131655223886618,65.9765814384596894,60.9786842032445122]},"#dd7766":{"lch":[61.2441632046235895,79.8999585154359693,19.0216316495787474],"luv":[61.2441632046235895,75.5370685872685073,26.0414024201977448],"rgb":[0.866666666666666696,0.466666666666666674,0.4],"xyz":[0.388126830998419659,0.295272533657896907,0.162261315618013158],"hpluv":[19.0216316495787474,165.546946717194828,61.2441632046235895],"hsluv":[19.0216316495787474,57.9572057581871576,61.2441632046235895]},"#dd7777":{"lch":[61.5676827516498122,73.9875996712566,12.1770506300619097],"luv":[61.5676827516498122,72.3229127387857318,15.6064473244910626],"rgb":[0.866666666666666696,0.466666666666666674,0.466666666666666674],"xyz":[0.397440844018621564,0.298998138865977703,0.211315117524411067],"hpluv":[12.1770506300619097,152.491436777287873,61.5676827516498122],"hsluv":[12.1770506300619097,58.8480912007490744,61.5676827516498122]},"#dd7788":{"lch":[61.9511315612573,68.8928540500868252,3.33484257213660307],"luv":[61.9511315612573,68.7761927043778769,4.00757485979294081],"rgb":[0.866666666666666696,0.466666666666666674,0.533333333333333326],"xyz":[0.408581261120565364,0.303454305706755301,0.269987980927983207],"hpluv":[3.33484257213660307,141.112101622994089,61.9511315612573],"hsluv":[3.33484257213660307,59.8177792812577849,61.9511315612573]},"#dd7799":{"lch":[62.395798681375723,65.5359342889949659,352.534540584191575],"luv":[62.395798681375723,64.9804103256140309,-8.5149842657693231],"rgb":[0.866666666666666696,0.466666666666666674,0.6],"xyz":[0.421638225229638119,0.308677091350384458,0.338754658569101141],"hpluv":[352.534540584191575,133.27953643418,62.395798681375723],"hsluv":[352.534540584191575,60.8378233331756135,62.395798681375723]},"#dd77aa":{"lch":[62.9024183325334576,64.7691926058513587,340.409048511657261],"luv":[62.9024183325334576,61.0197310981447743,-21.7172909803219412],"rgb":[0.866666666666666696,0.466666666666666674,0.66666666666666663],"xyz":[0.43669591819489062,0.314700168536485581,0.418058508186099742],"hpluv":[340.409048511657261,130.659342151792146,62.9024183325334576],"hsluv":[340.409048511657261,61.8795186032410598,62.9024183325334576]},"#dd77bb":{"lch":[63.4712121738611472,67.0588140204747,328.168414880738283],"luv":[63.4712121738611472,56.973307333119962,-35.3684434115847779],"rgb":[0.866666666666666696,0.466666666666666674,0.733333333333333282],"xyz":[0.453833510302227294,0.321555205379420339,0.508316493284741489],"hpluv":[328.168414880738283,134.065922948238125,63.4712121738611472],"hsluv":[328.168414880738283,62.9156692244191049,63.4712121738611472]},"#dd77cc":{"lch":[64.1019320742502856,72.2937871392105649,317.045265551381931],"luv":[64.1019320742502856,52.9112642996390861,-49.2624580095555586],"rgb":[0.866666666666666696,0.466666666666666674,0.8],"xyz":[0.473125885745949049,0.329272155556909141,0.609923003955011644],"hpluv":[317.045265551381931,143.109736775843601,64.1019320742502856],"hsluv":[317.045265551381931,63.9218174738772262,64.1019320742502856]},"#dd77dd":{"lch":[64.7939046430230547,79.9242419089019904,307.715012949244624],"luv":[64.7939046430230547,48.8924033620837761,-63.225132172198613],"rgb":[0.866666666666666696,0.466666666666666674,0.866666666666666696],"xyz":[0.494644211296582537,0.337879485777162647,0.723252851855017642],"hpluv":[307.715012949244624,156.524995415635317,64.7939046430230547],"hsluv":[307.715012949244624,64.8769154463944,64.7939046430230547]},"#dd77ee":{"lch":[65.5460776792256,89.2673698488479772,300.244676230176196],"luv":[65.5460776792256,44.9634126652007424,-77.116501743983946],"rgb":[0.866666666666666696,0.466666666666666674,0.933333333333333348],"xyz":[0.518456391562757357,0.347404357883632664,0.848663667923540865],"hpluv":[300.244676230176196,172.816560464305326,65.5460776792256],"hsluv":[300.244676230176196,82.07388698168063,65.5460776792256]},"#dd77ff":{"lch":[66.3570680439545,99.7204006423648366,294.377473048092611],"luv":[66.3570680439545,41.1592308753033436,-90.8299290874281837],"rgb":[0.866666666666666696,0.466666666666666674,1],"xyz":[0.544627439972588667,0.357872777247565388,0.98649785621532271],"hpluv":[294.377473048092611,190.693615319177383,66.3570680439545],"hsluv":[294.377473048092611,99.9999999999983373,66.3570680439545]},"#dd8800":{"lch":[64.1467534130096766,94.4821411478558701,41.4445641191571781],"luv":[64.1467534130096766,70.8234804869986192,62.5372657508392],"rgb":[0.866666666666666696,0.533333333333333326,0],"xyz":[0.386219021295729159,0.329825201336773954,0.0433231605406526124],"hpluv":[41.4445641191571781,186.902182331454583,64.1467534130096766],"hsluv":[41.4445641191571781,100.000000000002416,64.1467534130096766]},"#dd8811":{"lch":[64.1795176641247593,93.3565504581455,40.9755438084832377],"luv":[64.1795176641247593,70.4832194968749235,61.2173282886440333],"rgb":[0.866666666666666696,0.533333333333333326,0.0666666666666666657],"xyz":[0.387230686795366263,0.330229867536628807,0.0486512655054082421],"hpluv":[40.9755438084832377,184.581288668542754,64.1795176641247593],"hsluv":[40.9755438084832377,98.0366401848460072,64.1795176641247593]},"#dd8822":{"lch":[64.2401831232140665,91.3094921720035444,40.0852847486271529],"luv":[64.2401831232140665,69.8596876954725303,58.7966614341343359],"rgb":[0.866666666666666696,0.533333333333333326,0.133333333333333331],"xyz":[0.38910604493384332,0.330980010792019608,0.0585281517013874417],"hpluv":[40.0852847486271529,180.363429125237786,64.2401831232140665],"hsluv":[40.0852847486271529,94.440421143342,64.2401831232140665]},"#dd8833":{"lch":[64.3398685532121704,88.0506151089842319,38.5586382769189342],"luv":[64.3398685532121704,68.8529964065635,54.8832916916272],"rgb":[0.866666666666666696,0.533333333333333326,0.2],"xyz":[0.392193795666301,0.332215111085002734,0.0747903055589985849],"hpluv":[38.5586382769189342,173.656703033806934,64.3398685532121704],"hsluv":[38.5586382769189342,88.6389494712849171,64.3398685532121704]},"#dd8844":{"lch":[64.4833562447751376,83.590391105324656,36.2144134416389392],"luv":[64.4833562447751376,67.4417066096926305,49.3859260793323571],"rgb":[0.866666666666666696,0.533333333333333326,0.266666666666666663],"xyz":[0.396651790910519941,0.333998309182690301,0.0982690805118852234],"hpluv":[36.2144134416389392,164.493238171948974,64.4833562447751376],"hsluv":[36.2144134416389392,80.515719620269337,64.4833562447751376]},"#dd8855":{"lch":[64.6744699451661234,78.0792033713498768,32.8038905377638059],"luv":[64.6744699451661234,65.6278986079903746,42.3006019272060527],"rgb":[0.866666666666666696,0.533333333333333326,0.333333333333333315],"xyz":[0.402614204949881926,0.336383274798435161,0.129671127785859125],"hpluv":[32.8038905377638059,153.194023310958244,64.6744699451661234],"hsluv":[32.8038905377638059,70.0933757373770874,64.6744699451661234]},"#dd8866":{"lch":[64.9162913059566762,71.8298791231791114,27.9793586637294176],"luv":[64.9162913059566762,63.4341634455056251,33.69923504798588],"rgb":[0.866666666666666696,0.533333333333333326,0.4],"xyz":[0.410199200723390112,0.33941727310783848,0.169618772193003087],"hpluv":[27.9793586637294176,140.40764710249897,64.9162913059566762],"hsluv":[27.9793586637294176,57.516131894534638,64.9162913059566762]},"#dd8877":{"lch":[65.211273186305,65.3549274640793243,21.2774014292581],"luv":[65.211273186305,60.8999714810578325,23.7162395299384023],"rgb":[0.866666666666666696,0.533333333333333326,0.466666666666666674],"xyz":[0.419513213743592,0.343142878315919275,0.218672574099401],"hpluv":[21.2774014292581,127.173019810527066,65.211273186305],"hsluv":[21.2774014292581,55.3192807564291797,65.211273186305]},"#dd8888":{"lch":[65.5613077882642585,59.4140252364257222,12.17705063006205],"luv":[65.5613077882642585,58.0772370198051675,12.5323954190731097],"rgb":[0.866666666666666696,0.533333333333333326,0.533333333333333326],"xyz":[0.430653630845535818,0.347599045156696873,0.277345437502973191],"hpluv":[12.17705063006205,114.995459986814794,65.5613077882642585],"hsluv":[12.17705063006205,56.217054427929,65.5613077882642585]},"#dd8899":{"lch":[65.9677735951440809,55.0265961591163304,0.371909902430330563],"luv":[65.9677735951440809,55.0254369244830599,0.357178006339119947],"rgb":[0.866666666666666696,0.533333333333333326,0.6],"xyz":[0.443710594954608517,0.352821830800326031,0.34611211514409107],"hpluv":[0.371909902430330563,105.847388780281833,65.9677735951440809],"hsluv":[0.371909902430330563,57.1692646853200088,65.9677735951440809]},"#dd88aa":{"lch":[66.4315725960282,53.3143351650078756,346.342357286170909],"luv":[66.4315725960282,51.8068159744011751,-12.5885723051236678],"rgb":[0.866666666666666696,0.533333333333333326,0.66666666666666663],"xyz":[0.458768287919861073,0.358844907986427153,0.425415964761089671],"hpluv":[346.342357286170909,101.837748961685463,66.4315725960282],"hsluv":[346.342357286170909,58.1497775423036174,66.4315725960282]},"#dd88bb":{"lch":[66.9531637379342754,55.0554122119122695,331.715662007953938],"luv":[66.9531637379342754,48.482176665295448,-26.0878699709014299],"rgb":[0.866666666666666696,0.533333333333333326,0.733333333333333282],"xyz":[0.475905880027197747,0.365699944829361911,0.515673949859731473],"hpluv":[331.715662007953938,104.344182679937973,66.9531637379342754],"hsluv":[331.715662007953938,59.1328526037280824,66.9531637379342754]},"#dd88cc":{"lch":[67.5325957217288391,60.2482932018326949,318.477460357427788],"luv":[67.5325957217288391,45.1075955230381,-39.9394749572899741],"rgb":[0.866666666666666696,0.533333333333333326,0.8],"xyz":[0.495198255470919446,0.373416895006850713,0.617280460530001629],"hpluv":[318.477460357427788,113.206309259525241,67.5325957217288391],"hsluv":[318.477460357427788,60.0943355072680134,67.5325957217288391]},"#dd88dd":{"lch":[68.1695406599531566,68.219499196860184,307.715012949245079],"luv":[68.1695406599531566,41.7322103060295,-53.965940125636024],"rgb":[0.866666666666666696,0.533333333333333326,0.866666666666666696],"xyz":[0.516716581021553,0.382024225227104219,0.730610308430007627],"hpluv":[307.715012949245079,126.986480244117786,68.1695406599531566],"hsluv":[307.715012949245079,61.0124281772922785,68.1695406599531566]},"#dd88ee":{"lch":[68.8633291469121,78.1074456653267504,299.445313850889818],"luv":[68.8633291469121,38.3970440138518896,-68.0179393936650456],"rgb":[0.866666666666666696,0.533333333333333326,0.933333333333333348],"xyz":[0.540528761287727755,0.391549097333574236,0.85602112449853085],"hpluv":[299.445313850889818,143.92748858218269,68.8633291469121],"hsluv":[299.445313850889818,80.0342386911036385,68.8633291469121]},"#dd88ff":{"lch":[69.6129866887261244,89.1875622693819281,293.199992160066699],"luv":[69.6129866887261244,35.1347073752451706,-81.975445111391565],"rgb":[0.866666666666666696,0.533333333333333326,1],"xyz":[0.566699809697559176,0.40201751669750696,0.993855312790312695],"hpluv":[293.199992160066699,162.574846632166981,69.6129866887261244],"hsluv":[293.199992160066699,99.9999999999981242,69.6129866887261244]},"#dd9900":{"lch":[68.1357569139589287,89.1370219700488775,50.3810095729648921],"luv":[68.1357569139589287,56.8408371488252229,68.6624199829113735],"rgb":[0.866666666666666696,0.6,0],"xyz":[0.41208862174819666,0.381564402241709621,0.0519463606914748674],"hpluv":[50.3810095729648921,166.005456049637957,68.1357569139589287],"hsluv":[50.3810095729648921,100.000000000002245,68.1357569139589287]},"#dd9911":{"lch":[68.1654896561650077,88.0318570495471278,50.0002977758109424],"luv":[68.1654896561650077,56.5854364905009248,67.4366089951992507],"rgb":[0.866666666666666696,0.6,0.0666666666666666657],"xyz":[0.413100287247833764,0.381969068441564474,0.0572744656562305],"hpluv":[50.0002977758109424,163.875726960716179,68.1654896561650077],"hsluv":[50.0002977758109424,98.2940371374324826,68.1654896561650077]},"#dd9922":{"lch":[68.2205507365204,86.012937831153792,49.27558445879027],"luv":[68.2205507365204,56.1166821435168472,65.1854543556261774],"rgb":[0.866666666666666696,0.6,0.133333333333333331],"xyz":[0.414975645386310821,0.382719211696955275,0.0671513518522096897],"hpluv":[49.27558445879027,159.988175949224541,68.2205507365204],"hsluv":[49.27558445879027,95.1643810214000325,68.2205507365204]},"#dd9933":{"lch":[68.3110514885433133,82.7730333151944677,48.0261582829398179],"luv":[68.3110514885433133,55.3578808500206918,61.5376313485756867],"rgb":[0.866666666666666696,0.6,0.2],"xyz":[0.418063396118768527,0.383954311989938402,0.0834135057098208399],"hpluv":[48.0261582829398179,153.757824966526499,68.3110514885433133],"hsluv":[48.0261582829398179,90.1021642959546512,68.3110514885433133]},"#dd9944":{"lch":[68.4413718194248,78.2806718730308688,46.0898611008159875],"luv":[68.4413718194248,54.2899414547091936,56.3956190296495805],"rgb":[0.866666666666666696,0.6,0.266666666666666663],"xyz":[0.422521391362987442,0.385737510087625968,0.106892280662707478],"hpluv":[46.0898611008159875,145.136005207448051,68.4413718194248],"hsluv":[46.0898611008159875,82.9860784920926449,68.4413718194248]},"#dd9955":{"lch":[68.615044439797245,72.617894762441864,43.2298844404699452],"luv":[68.615044439797245,52.9102318436571935,49.7379734808277689],"rgb":[0.866666666666666696,0.6,0.333333333333333315],"xyz":[0.428483805402349427,0.388122475703370828,0.138294327936681394],"hpluv":[43.2298844404699452,134.296171447129637,68.615044439797245],"hsluv":[43.2298844404699452,73.8078183466747362,68.615044439797245]},"#dd9966":{"lch":[68.8349542760461333,65.9999398631214262,39.0839575312566296],"luv":[68.8349542760461333,51.2306688139135815,41.6102227200810404],"rgb":[0.866666666666666696,0.6,0.4],"xyz":[0.436068801175857612,0.391156474012774147,0.178241972343825356],"hpluv":[39.0839575312566296,121.667290932950721,68.8349542760461333],"hsluv":[39.0839575312566296,62.6592399312796076,68.8349542760461333]},"#dd9977":{"lch":[69.1034430542988929,58.8170492635600723,33.0939178586399834],"luv":[69.1034430542988929,49.2755524050587468,32.1148753578207291],"rgb":[0.866666666666666696,0.6,0.466666666666666674],"xyz":[0.445382814196059518,0.394882079220854942,0.227295774250223265],"hpluv":[33.0939178586399834,108.004754244465147,69.1034430542988929],"hsluv":[33.0939178586399834,50.7393036295826789,69.1034430542988929]},"#dd9988":{"lch":[69.4223715869125328,51.7141196395305656,24.4437159362198635],"luv":[69.4223715869125328,47.0788901370553745,21.3992587150758773],"rgb":[0.866666666666666696,0.6,0.533333333333333326],"xyz":[0.456523231298003318,0.39933824606163254,0.285968637653795432],"hpluv":[24.4437159362198635,94.5255072345235305,69.4223715869125328],"hsluv":[24.4437159362198635,51.5589665528693786,69.4223715869125328]},"#dd9999":{"lch":[69.7931614924381591,45.7097919546320597,12.1770506300622632],"luv":[69.7931614924381591,44.6813426781189875,9.64171649740066705],"rgb":[0.866666666666666696,0.6,0.6],"xyz":[0.469580195407076073,0.404561031705261698,0.354735315294913311],"hpluv":[12.1770506300622632,83.1066353202273689,69.7931614924381591],"hsluv":[12.1770506300622632,52.4335711570844438,69.7931614924381591]},"#dd99aa":{"lch":[70.2168268189972196,42.2311183685245624,355.977290330288042],"luv":[70.2168268189972196,42.1270745474506256,-2.96259155636920823],"rgb":[0.866666666666666696,0.6,0.66666666666666663],"xyz":[0.484637888372328574,0.41058410889136282,0.434039164911911912],"hpluv":[355.977290330288042,76.3186553239153369,70.2168268189972196],"hsluv":[355.977290330288042,53.3392978779897788,70.2168268189972196]},"#dd99bb":{"lch":[70.694001085559151,42.6623948649138427,337.661645838825223],"luv":[70.694001085559151,39.4608168046039651,-16.2149274658665163],"rgb":[0.866666666666666696,0.6,0.733333333333333282],"xyz":[0.501775480479665248,0.417439145734297579,0.524297150010553659],"hpluv":[337.661645838825223,76.5776430619999502,70.694001085559151],"hsluv":[337.661645838825223,54.2517942883204398,70.694001085559151]},"#dd99cc":{"lch":[71.2249627580945912,47.3730793907595,320.82657583403028],"luv":[71.2249627580945912,36.7253906259007294,-29.9241430008982121],"rgb":[0.866666666666666696,0.6,0.8],"xyz":[0.521067855923387,0.42515609591178638,0.625903660680823815],"hpluv":[320.82657583403028,84.3992741769230719,71.2249627580945912],"hsluv":[320.82657583403028,55.1472527266246075,71.2249627580945912]},"#dd99dd":{"lch":[71.8096607795551876,55.5140341348433424,307.715012949246],"luv":[71.8096607795551876,33.9598410238411077,-43.9151133843462844],"rgb":[0.866666666666666696,0.6,0.866666666666666696],"xyz":[0.54258618147402049,0.433763426132039887,0.739233508580829812],"hpluv":[307.715012949246,98.0977936102115677,71.8096607795551876],"hsluv":[307.715012949246,56.0031828352742878,71.8096607795551876]},"#dd99ee":{"lch":[72.447740927007942,65.8885644567307907,298.26171852853804],"luv":[72.447740927007942,31.1982236173053273,-58.0342465212858656],"rgb":[0.866666666666666696,0.6,0.933333333333333348],"xyz":[0.566398361740195311,0.443288298238509904,0.864644324649353],"hpluv":[298.26171852853804,115.404973126410823,72.447740927007942],"hsluv":[298.26171852853804,77.3800261839098908,72.447740927007942]},"#dd99ff":{"lch":[73.1385732331520302,77.5656763031263,291.532620718417377],"luv":[73.1385732331520302,28.4689992262389602,-72.1522710898123592],"rgb":[0.866666666666666696,0.6,1],"xyz":[0.592569410150026621,0.453756717602442627,1.00247851294113488],"hpluv":[291.532620718417377,134.574391894016571,73.1385732331520302],"hsluv":[291.532620718417377,99.9999999999977689,73.1385732331520302]},"#cc0000":{"lch":[42.5207510295766156,142.998625281495549,12.1770506300617818],"luv":[42.5207510295766156,139.781222041964895,30.163169542547891],"rgb":[0.8,0,0],"xyz":[0.249012838889184379,0.128397245052238429,0.0116724768229302719],"hpluv":[12.1770506300617818,426.746789183124861,42.5207510295766156],"hsluv":[12.1770506300617818,100.000000000002174,42.5207510295766156]},"#cc0011":{"lch":[42.5821659889152784,141.236718626044905,11.4841194603559],"luv":[42.5821659889152784,138.409148973409117,28.119711390930437],"rgb":[0.8,0,0.0666666666666666657],"xyz":[0.250024504388821511,0.128801911252093282,0.0170005817876859033],"hpluv":[11.4841194603559,420.880880123779207,42.5821659889152784],"hsluv":[11.4841194603559,99.9999999999964331,42.5821659889152784]},"#cc0022":{"lch":[42.6956735686566518,138.114600243667155,10.1872609469282853],"luv":[42.6956735686566518,135.937217546775798,24.4277646564013864],"rgb":[0.8,0,0.133333333333333331],"xyz":[0.251899862527298513,0.12955205450748411,0.0268774679836651],"hpluv":[10.1872609469282853,410.482879191578036,42.6956735686566518],"hsluv":[10.1872609469282853,99.9999999999964615,42.6956735686566518]},"#cc0033":{"lch":[42.881611378965772,133.362165770655935,8.01952044887972626],"luv":[42.881611378965772,132.057963211529,18.6054188736068511],"rgb":[0.8,0,0.2],"xyz":[0.254987613259756274,0.130787154800467209,0.0431396218412762461],"hpluv":[8.01952044887972626,394.639788400466045,42.881611378965772],"hsluv":[8.01952044887972626,99.9999999999966604,42.881611378965772]},"#cc0044":{"lch":[43.1480085091585153,127.29097956278504,4.82801781999359658],"luv":[43.1480085091585153,126.839328429887985,10.7134607624411853],"rgb":[0.8,0,0.266666666666666663],"xyz":[0.259445608503975134,0.132570352898154803,0.0666183967941628846],"hpluv":[4.82801781999359658,374.34858804079829,43.1480085091585153],"hsluv":[4.82801781999359658,99.9999999999967741,43.1480085091585153]},"#cc0055":{"lch":[43.5005971125795,120.485699890795146,0.473888563816867114],"luv":[43.5005971125795,120.481578818580687,0.996515708296922487],"rgb":[0.8,0,0.333333333333333315],"xyz":[0.265408022543337119,0.134955318513899636,0.0980204440681367861],"hpluv":[0.473888563816867114,351.463000970195878,43.5005971125795],"hsluv":[0.473888563816867114,99.999999999997,43.5005971125795]},"#cc0066":{"lch":[43.9431844272177372,113.726547538665841,354.863826263116096],"luv":[43.9431844272177372,113.269906269789104,-10.1811565500985228],"rgb":[0.8,0,0.4],"xyz":[0.272993018316845304,0.137989316823302927,0.137968088475280748],"hpluv":[354.863826263116096,328.404920869645196,43.9431844272177372],"hsluv":[354.863826263116096,99.9999999999972857,43.9431844272177372]},"#cc0077":{"lch":[44.4778741065655,107.874648109024193,348.012259047653401],"luv":[44.4778741065655,105.522124609829902,-22.4058234053856609],"rgb":[0.8,0,0.466666666666666674],"xyz":[0.28230703133704721,0.14171492203138375,0.187021890381678657],"hpluv":[348.012259047653401,307.761788629886667,44.4778741065655],"hsluv":[348.012259047653401,99.9999999999975273,44.4778741065655]},"#cc0088":{"lch":[45.1052440924579,103.725434836726933,340.1176986346278],"luv":[45.1052440924579,97.5426962017022703,-35.2758876538989838],"rgb":[0.8,0,0.533333333333333326],"xyz":[0.293447448438991065,0.146171088872161348,0.245694753785250825],"hpluv":[340.1176986346278,291.808241377507443,45.1052440924579],"hsluv":[340.1176986346278,99.9999999999978,45.1052440924579]},"#cc0099":{"lch":[45.8245205562958589,101.850048541314862,331.598662995615],"luv":[45.8245205562958589,89.5911194129305102,-48.4444394147173441],"rgb":[0.8,0,0.6],"xyz":[0.306504412548063765,0.151393874515790505,0.314461431426368732],"hpluv":[331.598662995615,282.034759885138044,45.8245205562958589],"hsluv":[331.598662995615,99.9999999999981,45.8245205562958589]},"#cc00aa":{"lch":[46.633760692471931,102.477609530343315,323.022725489580409],"luv":[46.633760692471931,81.8667129915779,-61.640098629123905],"rgb":[0.8,0,0.66666666666666663],"xyz":[0.321562105513316321,0.1574169517018916,0.393765281043367332],"hpluv":[323.022725489580409,278.848217687739293,46.633760692471931],"hsluv":[323.022725489580409,99.9999999999983658,46.633760692471931]},"#cc00bb":{"lch":[47.5300446684938933,105.484027274260768,314.937463984289479],"luv":[47.5300446684938933,74.5070162947061903,-74.6698368342758414],"rgb":[0.8,0,0.733333333333333282],"xyz":[0.33869969762065294,0.164271988544826358,0.484023266142009079],"hpluv":[314.937463984289479,281.616311803476265,47.5300446684938933],"hsluv":[314.937463984289479,99.9999999999986,47.5300446684938933]},"#cc00cc":{"lch":[48.5096711653281147,110.497164945278598,307.715012949243601],"luv":[48.5096711653281147,67.5949102529980621,-87.4102486487325],"rgb":[0.8,0,0.8],"xyz":[0.357992073064374694,0.17198893872231516,0.585629776812279235],"hpluv":[307.715012949243601,289.042783730483393,48.5096711653281147],"hsluv":[307.715012949243601,99.9999999999988,48.5096711653281147]},"#cc00dd":{"lch":[49.5683488162236614,117.049051317219835,301.506761454082039],"luv":[49.5683488162236614,61.1697383356450075,-99.7935044289451],"rgb":[0.8,0,0.866666666666666696],"xyz":[0.379510398615008238,0.180596268942568694,0.698959624712285232],"hpluv":[301.506761454082039,299.64205877637869,49.5683488162236614],"hsluv":[301.506761454082039,99.9999999999990337,49.5683488162236614]},"#cc00ee":{"lch":[50.7013760136427862,124.695255359169607,296.294949026353493],"luv":[50.7013760136427862,55.2390203059142522,-111.792474454818787],"rgb":[0.8,0,0.933333333333333348],"xyz":[0.403322578881182947,0.190121141049038739,0.824370440780808456],"hpluv":[296.294949026353493,312.082566880879938,50.7013760136427862],"hsluv":[296.294949026353493,99.99999999999919,50.7013760136427862]},"#cc00ff":{"lch":[51.9038030272213,133.072735088441448,291.971633700566258],"luv":[51.9038030272213,49.7888328026579075,-123.407556300526],"rgb":[0.8,0,1],"xyz":[0.429493627291014368,0.200589560412971435,0.962204629072590301],"hpluv":[291.971633700566258,325.333832743425603,51.9038030272213],"hsluv":[291.971633700566258,99.9999999999993321,51.9038030272213]},"#cc1100":{"lch":[43.1235624482234172,140.134259476931788,12.8715382160273855],"luv":[43.1235624482234172,136.61296213687416,31.2171307992428524],"rgb":[0.8,0.0666666666666666657,0],"xyz":[0.251017239150112814,0.132406045574095299,0.0123406102432397219],"hpluv":[12.8715382160273855,412.352867097941,43.1235624482234172],"hsluv":[12.8715382160273855,100.000000000002245,43.1235624482234172]},"#cc1111":{"lch":[43.1837333530957892,138.41807101963343,12.1770506300617676],"luv":[43.1837333530957892,135.303728142340162,29.196978192614182],"rgb":[0.8,0.0666666666666666657,0.0666666666666666657],"xyz":[0.252028904649749919,0.132810711773950152,0.0176687152079953516],"hpluv":[12.1770506300617676,406.735363437937394,43.1837333530957892],"hsluv":[12.1770506300617676,95.3107026807431197,43.1837333530957892]},"#cc1122":{"lch":[43.294951674171287,135.375047793376126,10.8766574447476163],"luv":[43.294951674171287,132.943125696930394,25.5446451333550044],"rgb":[0.8,0.0666666666666666657,0.133333333333333331],"xyz":[0.253904262788227,0.13356085502934098,0.0275456014039745511],"hpluv":[10.8766574447476163,396.771701832449367,43.294951674171287],"hsluv":[10.8766574447476163,95.396390587568618,43.294951674171287]},"#cc1133":{"lch":[43.4771672841157724,130.73841758888139,8.7012157385065958],"luv":[43.4771672841157724,129.233706917218683,19.7783424502448213],"rgb":[0.8,0.0666666666666666657,0.2],"xyz":[0.256992013520684681,0.134795955322324079,0.0438077552615856944],"hpluv":[8.7012157385065958,381.576227833431062,43.4771672841157724],"hsluv":[8.7012157385065958,95.5308510527687389,43.4771672841157724]},"#cc1144":{"lch":[43.7382910834512586,124.807582872189826,5.49437317543092796],"luv":[43.7382910834512586,124.234167693991893,11.9500761411646046],"rgb":[0.8,0.0666666666666666657,0.266666666666666663],"xyz":[0.261450008764903596,0.136579153420011673,0.0672865302144723398],"hpluv":[5.49437317543092796,362.091632024479338,43.7382910834512586],"hsluv":[5.49437317543092796,95.7116850897169229,43.7382910834512586]},"#cc1155":{"lch":[44.0840061747103107,118.151091154502552,1.11194247693657511],"luv":[44.0840061747103107,118.128842001262925,2.29282106589917234],"rgb":[0.8,0.0666666666666666657,0.333333333333333315],"xyz":[0.267412422804265582,0.138964119035756506,0.0986885774884462413],"hpluv":[1.11194247693657511,340.091681007194666,44.0840061747103107],"hsluv":[1.11194247693657511,95.9318436200579754,44.0840061747103107]},"#cc1166":{"lch":[44.5181325219627837,111.53522478210337,355.453854482233226],"luv":[44.5181325219627837,111.184314904818763,-8.84050260677650712],"rgb":[0.8,0.0666666666666666657,0.4],"xyz":[0.274997418577773767,0.141998117345159797,0.138636221895590217],"hpluv":[355.453854482233226,317.917500588946211,44.5181325219627837],"hsluv":[355.453854482233226,96.1812476973727115,44.5181325219627837]},"#cc1177":{"lch":[45.0428415016287857,105.814757555455103,348.528515458334311],"luv":[45.0428415016287857,103.700981473984271,-21.0444614531261323],"rgb":[0.8,0.0666666666666666657,0.466666666666666674],"xyz":[0.284311431597975672,0.14572372255324062,0.187690023801988126],"hpluv":[348.528515458334311,298.098498005115459,45.0428415016287857],"hsluv":[348.528515458334311,96.4486017572014589,45.0428415016287857]},"#cc1188":{"lch":[45.6588256994622341,101.788242110562607,340.533613155211185],"luv":[45.6588256994622341,95.9697371205835594,-33.9213176183443323],"rgb":[0.8,0.0666666666666666657,0.533333333333333326],"xyz":[0.295451848699919473,0.150179889394018218,0.246362887205560266],"hpluv":[340.533613155211185,282.886487347344485,45.6588256994622341],"hsluv":[340.533613155211185,96.7230145871901215,45.6588256994622341]},"#cc1199":{"lch":[46.3654632546324876,100.035938879036408,331.896400713626349],"luv":[46.3654632546324876,88.2414291467186,-47.1236591273953138],"rgb":[0.8,0.0666666666666666657,0.6],"xyz":[0.308508812808992228,0.155402675037647375,0.315129564846678201],"hpluv":[331.896400713626349,273.779405248492822,46.3654632546324876],"hsluv":[331.896400713626349,96.9951405388504355,46.3654632546324876]},"#cc11aa":{"lch":[47.1609900317596882,100.794975336059878,323.201580807901109],"luv":[47.1609900317596882,80.7113646178594735,-60.3763420100941488],"rgb":[0.8,0.0666666666666666657,0.66666666666666663],"xyz":[0.323566505774244728,0.16142575222374847,0.394433414463676801],"hpluv":[323.201580807901109,271.203503720358924,47.1609900317596882],"hsluv":[323.201580807901109,97.2577546113476075,47.1609900317596882]},"#cc11bb":{"lch":[48.0426807208370548,103.942897448445919,315.013990059648165],"luv":[48.0426807208370548,73.5166718264647727,-73.4807790754699681],"rgb":[0.8,0.0666666666666666657,0.733333333333333282],"xyz":[0.340704097881581403,0.168280789066683228,0.484691399562318548],"hpluv":[315.013990059648165,274.540811344802705,48.0426807208370548],"hsluv":[315.013990059648165,97.5058443216483,48.0426807208370548]},"#cc11cc":{"lch":[49.0070341259591515,109.103198367120783,307.715012949243601],"luv":[49.0070341259591515,66.7421730285370387,-86.3075328888743769],"rgb":[0.8,0.0666666666666666657,0.8],"xyz":[0.359996473325303157,0.17599773924417203,0.586297910232588704],"hpluv":[307.715012949243601,282.499958642668389,49.0070341259591515],"hsluv":[307.715012949243601,97.7363817897909541,49.0070341259591515]},"#cc11dd":{"lch":[50.0499556366759037,115.801352096543823,301.456118533327128],"luv":[50.0499556366759037,60.4304023076134555,-98.7831950502093292],"rgb":[0.8,0.0666666666666666657,0.866666666666666696],"xyz":[0.381514798875936645,0.184605069464425564,0.699627758132594701],"hpluv":[301.456118533327128,293.595408819402792,50.0499556366759037],"hsluv":[301.456118533327128,97.9479403979501342,50.0499556366759037]},"#cc11ee":{"lch":[51.1669298024285837,123.587345912593733,296.214453457233276],"luv":[51.1669298024285837,54.5925079172689109,-110.876012505059137],"rgb":[0.8,0.0666666666666666657,0.933333333333333348],"xyz":[0.40532697914211141,0.194129941570895609,0.825038574201117925],"hpluv":[296.214453457233276,306.495409047480564,51.1669298024285837],"hsluv":[296.214453457233276,98.1402788193950215,51.1669298024285837]},"#cc11ff":{"lch":[52.3531771468210678,132.094610043027387,291.87590029388349],"luv":[52.3531771468210678,49.2181193296501576,-122.582881072651375],"rgb":[0.8,0.0666666666666666657,1],"xyz":[0.431498027551942775,0.204598360934828305,0.96287276249289977],"hpluv":[291.87590029388349,320.170549145207644,52.3531771468210678],"hsluv":[291.87590029388349,99.9999999999991189,52.3531771468210678]},"#cc2200":{"lch":[44.2095884480383674,135.132222138307952,14.1797238149512133],"luv":[44.2095884480383674,131.015027118873576,33.102569825888537],"rgb":[0.8,0.133333333333333331,0],"xyz":[0.254732862884880729,0.139837293043631267,0.0135791514881623328],"hpluv":[14.1797238149512133,387.866054960954045,44.2095884480383674],"hsluv":[14.1797238149512133,100.00000000000226,44.2095884480383674]},"#cc2211":{"lch":[44.2676114068871129,133.490625771231663,13.482935392010976],"luv":[44.2676114068871129,129.81154471696064,31.1241068464871375],"rgb":[0.8,0.133333333333333331,0.0666666666666666657],"xyz":[0.255744528384517833,0.14024195924348612,0.0189072564529179643],"hpluv":[13.482935392010976,382.652016671578622,44.2676114068871129],"hsluv":[13.482935392010976,95.5414705532830197,44.2676114068871129]},"#cc2222":{"lch":[44.3748759613401162,130.576558981694717,12.1770506300617747],"luv":[44.3748759613401162,127.638646515421286,27.5429423121666019],"rgb":[0.8,0.133333333333333331,0.133333333333333331],"xyz":[0.25761988652299489,0.140992102498876948,0.0287841426488971604],"hpluv":[12.1770506300617747,373.394050741154899,44.3748759613401162],"hsluv":[12.1770506300617747,87.4977996802062847,44.3748759613401162]},"#cc2233":{"lch":[44.5506596541482907,126.128431434884163,9.98899557195718657],"luv":[44.5506596541482907,124.216461430809,21.8781152257824267],"rgb":[0.8,0.133333333333333331,0.2],"xyz":[0.260707637255452596,0.142227202791860047,0.0450462965065083071],"hpluv":[9.98899557195718657,359.251162664680805,44.5506596541482907],"hsluv":[9.98899557195718657,87.8457930667704829,44.5506596541482907]},"#cc2244":{"lch":[44.8026641682027602,120.425301369152351,6.75586226508684629],"luv":[44.8026641682027602,119.589119356054482,14.1667124448306829],"rgb":[0.8,0.133333333333333331,0.266666666666666663],"xyz":[0.265165632499671511,0.144010400889547641,0.0685250714593949456],"hpluv":[6.75586226508684629,341.077623618219945,44.8026641682027602],"hsluv":[6.75586226508684629,88.3153597242729,44.8026641682027602]},"#cc2255":{"lch":[45.136480402373536,114.008772215671115,2.323188749975583],"luv":[45.136480402373536,113.915065115628011,4.62148047999889577],"rgb":[0.8,0.133333333333333331,0.333333333333333315],"xyz":[0.271128046539033496,0.146395366505292474,0.0999271187333688471],"hpluv":[2.323188749975583,320.51614012782295,45.136480402373536],"hsluv":[2.323188749975583,88.8894607126765663,45.136480402373536]},"#cc2266":{"lch":[45.5559407124691731,107.622008592458101,356.577515499379103],"luv":[45.5559407124691731,107.430062323442542,-6.42483016556681452],"rgb":[0.8,0.133333333333333331,0.4],"xyz":[0.278713042312541681,0.149429364814695764,0.139874763140512809],"hpluv":[356.577515499379103,299.774992396016216,45.5559407124691731],"hsluv":[356.577515499379103,89.543058875786258,45.5559407124691731]},"#cc2277":{"lch":[46.0633224094211542,102.110102175352239,349.514816334356908],"luv":[46.0633224094211542,100.405067655344695,-18.5821246198201955],"rgb":[0.8,0.133333333333333331,0.466666666666666674],"xyz":[0.288027055332743587,0.153154970022776588,0.188928565046910718],"hpluv":[349.514816334356908,281.289018816444,46.0633224094211542],"hsluv":[349.514816334356908,90.2475430222303174,46.0633224094211542]},"#cc2288":{"lch":[46.6595045299101443,98.2790088680822294,341.330158110485115],"luv":[46.6595045299101443,93.107459692013677,-31.4605234189234864],"rgb":[0.8,0.133333333333333331,0.533333333333333326],"xyz":[0.299167472434687387,0.157611136863554185,0.247601428450482886],"hpluv":[341.330158110485115,267.276005324070297,46.6595045299101443],"hsluv":[341.330158110485115,90.9748001704168,46.6595045299101443]},"#cc2299":{"lch":[47.3441166442187154,96.727251962869147,332.467163788405],"luv":[47.3441166442187154,85.772509513995189,-44.7128380217581167],"rgb":[0.8,0.133333333333333331,0.6],"xyz":[0.312224436543760087,0.162833922507183343,0.31636810609160082],"hpluv":[332.467163788405,259.252025571181889,47.3441166442187154],"hsluv":[332.467163788405,91.7002075152857259,47.3441166442187154]},"#cc22aa":{"lch":[48.1156936783416285,97.7076198445846131,323.544141865814368],"luv":[48.1156936783416285,78.5876931080813534,-58.0581903579838254],"rgb":[0.8,0.133333333333333331,0.66666666666666663],"xyz":[0.327282129509012643,0.168856999693284437,0.395671955708599421],"hpluv":[323.544141865814368,257.680176436907345,48.1156936783416285],"hsluv":[323.544141865814368,92.4042695013683328,48.1156936783416285]},"#cc22bb":{"lch":[48.9718390817589295,101.100583268181566,315.160199675634601],"luv":[48.9718390817589295,71.6885121422158846,-71.2887450022924867],"rgb":[0.8,0.133333333333333331,0.733333333333333282],"xyz":[0.344419721616349317,0.175712036536219196,0.485929940807241167],"hpluv":[315.160199675634601,261.96699229126267,48.9718390817589295],"hsluv":[315.160199675634601,93.0730408422972602,48.9718390817589295]},"#cc22cc":{"lch":[49.9093929354593513,106.520702596514482,307.715012949243658],"luv":[49.9093929354593513,65.1623716831421405,-84.2646153393173876],"rgb":[0.8,0.133333333333333331,0.8],"xyz":[0.363712097060071,0.183428986713708,0.587536451477511323],"hpluv":[307.715012949243658,270.826440261226253,49.9093929354593513],"hsluv":[307.715012949243658,93.6976999618693327,49.9093929354593513]},"#cc22dd":{"lch":[50.9245991417877377,113.480326695625976,301.360030221234524],"luv":[50.9245991417877377,59.0567580516805819,-96.9024451465042347],"rgb":[0.8,0.133333333333333331,0.866666666666666696],"xyz":[0.385230422610704615,0.192036316933961532,0.700866299377517321],"hpluv":[301.360030221234524,282.769318292038,50.9245991417877377],"hsluv":[301.360030221234524,94.2736696463096848,50.9245991417877377]},"#cc22ee":{"lch":[52.0132654143591964,121.518329969744158,296.062236941936249],"luv":[52.0132654143591964,53.3887372455597244,-109.162022947361166],"rgb":[0.8,0.133333333333333331,0.933333333333333348],"xyz":[0.409042602876879324,0.201561189040431576,0.826277115446040544],"hpluv":[296.062236941936249,296.460610812118318,52.0132654143591964],"hsluv":[296.062236941936249,94.7995997265514,52.0132654143591964]},"#cc22ff":{"lch":[53.170910599170611,130.261070707018604,291.695402941657903],"luv":[53.170910599170611,48.1538976563848422,-121.033667556747687],"rgb":[0.8,0.133333333333333331,1],"xyz":[0.435213651286710745,0.212029608404364273,0.964111303737822389],"hpluv":[291.695402941657903,310.870757963074425,53.170910599170611],"hsluv":[291.695402941657903,99.9999999999990621,53.170910599170611]},"#cc3300":{"lch":[45.9167915379707807,127.686226573765651,16.3911473443809399],"luv":[45.9167915379707807,122.496750231663356,36.0321889333482446],"rgb":[0.8,0.2,0],"xyz":[0.260850584973891519,0.15207273722165307,0.0156183921844992128],"hpluv":[16.3911473443809399,352.867650162608584,45.9167915379707807],"hsluv":[16.3911473443809399,100.000000000002288,45.9167915379707807]},"#cc3311":{"lch":[45.9716631772740811,126.14350976506573,15.6923563051461095],"luv":[45.9716631772740811,121.44186843726601,34.118289029712578],"rgb":[0.8,0.2,0.0666666666666666657],"xyz":[0.261862250473528624,0.152477403421507923,0.020946497149254846],"hpluv":[15.6923563051461095,348.188177538365835,45.9716631772740811],"hsluv":[15.6923563051461095,95.8756509753329595,45.9716631772740811]},"#cc3322":{"lch":[46.0731243265426613,123.399991281457972,14.3806932854006604],"luv":[46.0731243265426613,119.533487768482047,30.6480529588105668],"rgb":[0.8,0.2,0.133333333333333331],"xyz":[0.263737608612005681,0.153227546676898752,0.0308233833452340386],"hpluv":[14.3806932854006604,339.865273437066321,46.0731243265426613],"hsluv":[14.3806932854006604,88.4197842587317524,46.0731243265426613]},"#cc3333":{"lch":[46.2394596481243951,119.199958247304309,12.1770506300617924],"luv":[46.2394596481243951,116.518014060345578,25.1432385661076303],"rgb":[0.8,0.2,0.2],"xyz":[0.266825359344463386,0.154462646969881851,0.0470855372028451818],"hpluv":[12.1770506300617924,327.11667224844831,46.2394596481243951],"hsluv":[12.1770506300617924,76.6535755019082,46.2394596481243951]},"#cc3344":{"lch":[46.4780522046582405,113.793717346871745,8.90746564227168669],"luv":[46.4780522046582405,112.421330819758609,17.6197186224449389],"rgb":[0.8,0.2,0.266666666666666663],"xyz":[0.271283354588682302,0.156245845067569444,0.0705643121557318204],"hpluv":[8.90746564227168669,310.677421508065,46.4780522046582405],"hsluv":[8.90746564227168669,77.4930753906613887,46.4780522046582405]},"#cc3355":{"lch":[46.7943405275181661,107.68493286266704,4.39945159143432907],"luv":[46.7943405275181661,107.367637754253522,8.26045572038872855],"rgb":[0.8,0.2,0.333333333333333315],"xyz":[0.277245768628044287,0.158630810683314277,0.101966359429705736],"hpluv":[4.39945159143432907,292.012160158640199,46.7943405275181661],"hsluv":[4.39945159143432907,78.5258346284665265,46.7943405275181661]},"#cc3366":{"lch":[47.192153202602185,101.584765682520938,358.514989280316684],"luv":[47.192153202602185,101.55064731932022,-2.63261235272558647],"rgb":[0.8,0.2,0.4],"xyz":[0.284830764401552472,0.161664808992717568,0.141914003836849684],"hpluv":[358.514989280316684,273.148057687163259,47.192153202602185],"hsluv":[358.514989280316684,79.7102211537212781,47.192153202602185]},"#cc3377":{"lch":[47.6738975277608859,96.3272258277819589,351.225603296168742],"luv":[47.6738975277608859,95.1998742335289876,-14.6941614798792699],"rgb":[0.8,0.2,0.466666666666666674],"xyz":[0.294144777421754378,0.165390414200798391,0.190967805743247593],"hpluv":[351.225603296168742,256.39391915093114,47.6738975277608859],"hsluv":[351.225603296168742,80.9972134637005894,47.6738975277608859]},"#cc3388":{"lch":[48.2406991607903279,92.7347249941698095,342.718318936463845],"luv":[48.2406991607903279,88.5482927213948301,-27.5486674064369161],"rgb":[0.8,0.2,0.533333333333333326],"xyz":[0.305285194523698178,0.169846581041576,0.24964066914681976],"hpluv":[342.718318936463845,243.93163202064531,48.2406991607903279],"hsluv":[342.718318936463845,82.3372641433758758,48.2406991607903279]},"#cc3399":{"lch":[48.8925304323200436,91.4400639314067405,333.463846826874658],"luv":[48.8925304323200436,81.8070942553503926,-40.8519843003490877],"rgb":[0.8,0.2,0.6],"xyz":[0.318342158632770933,0.175069366685205147,0.318407346787937695],"hpluv":[333.463846826874658,237.319449797121564,48.8925304323200436],"hsluv":[333.463846826874658,83.6856508008112,48.8925304323200436]},"#cc33aa":{"lch":[49.6283419748853873,92.7248127600779242,324.141487451800515],"luv":[49.6283419748853873,75.1503095778714254,-54.3168654447363792],"rgb":[0.8,0.2,0.66666666666666663],"xyz":[0.333399851598023433,0.181092443871306241,0.397711196404936296],"hpluv":[324.141487451800515,237.085790295602294,49.6283419748853873],"hsluv":[324.141487451800515,85.0057245198840263,49.6283419748853873]},"#cc33bb":{"lch":[50.4462014889725054,96.4744776262418355,315.414049480091705],"luv":[50.4462014889725054,68.7089492450233905,-67.7230029377097],"rgb":[0.8,0.2,0.733333333333333282],"xyz":[0.350537443705360108,0.187947480714241,0.487969181503578042],"hpluv":[315.414049480091705,242.674024226837219,50.4462014889725054],"hsluv":[315.414049480091705,86.2701296035756258,50.4462014889725054]},"#cc33cc":{"lch":[51.3434379695087273,102.286811532428814,307.715012949243771],"luv":[51.3434379695087273,62.5723551280607779,-80.915339628518268],"rgb":[0.8,0.2,0.8],"xyz":[0.369829819149081862,0.195664430891729801,0.589575692173848198],"hpluv":[307.715012949243771,252.798225898109365,51.3434379695087273],"hsluv":[307.715012949243771,87.4604868647498,51.3434379695087273]},"#cc33dd":{"lch":[52.3167871114961827,109.649949983538605,301.195256028086874],"luv":[52.3167871114961827,56.7938698017029751,-93.7953510806358],"rgb":[0.8,0.2,0.866666666666666696],"xyz":[0.39134814469971535,0.204271761111983335,0.702905540073854196],"hpluv":[301.195256028086874,265.954105752122757,52.3167871114961827],"hsluv":[301.195256028086874,88.5661577004671,52.3167871114961827]},"#cc33ee":{"lch":[53.3625327970638494,118.082474280319559,295.802769884900215],"luv":[53.3625327970638494,51.3983045372134626,-106.309383512755787],"rgb":[0.8,0.2,0.933333333333333348],"xyz":[0.415160324965890115,0.21379663321845338,0.828316356142377419],"hpluv":[295.802769884900215,280.794331636146467,53.3625327970638494],"hsluv":[295.802769884900215,89.5826266077864375,53.3625327970638494]},"#cc33ff":{"lch":[54.4766398815527566,127.197777570935344,291.389330811727291],"luv":[54.4766398815527566,46.3894624378335,-118.436870921660102],"rgb":[0.8,0.2,1],"xyz":[0.441331373375721481,0.224265052582386076,0.966150544434159264],"hpluv":[291.389330811727291,296.284230666095709,54.4766398815527566],"hsluv":[291.389330811727291,99.9999999999990195,54.4766398815527566]},"#cc4400":{"lch":[48.2269914221542848,118.435883841274119,19.7039935064818295],"luv":[48.2269914221542848,111.501113106022,39.9319465764175447],"rgb":[0.8,0.266666666666666663,0],"xyz":[0.26968315545685756,0.1697378781875854,0.0185625823454878096],"hpluv":[19.7039935064818295,311.625122342549162,48.2269914221542848],"hsluv":[19.7039935064818295,100.000000000002174,48.2269914221542848]},"#cc4411":{"lch":[48.2779913635395,116.996103035931512,19.0066631306561966],"luv":[48.2779913635395,110.617558299276112,38.1030697123021],"rgb":[0.8,0.266666666666666663,0.0666666666666666657],"xyz":[0.270694820956494664,0.170142544387440253,0.0238906873102434428],"hpluv":[19.0066631306561966,307.511619232155283,48.2779913635395],"hsluv":[19.0066631306561966,96.278384876640132,48.2779913635395]},"#cc4422":{"lch":[48.3723181772035389,114.428966114904512,17.6946931608209894],"luv":[48.3723181772035389,109.015290220227484,34.7800917814421453],"rgb":[0.8,0.266666666666666663,0.133333333333333331],"xyz":[0.272570179094971721,0.170892687642831081,0.0337675735062226354],"hpluv":[17.6946931608209894,300.177682052924467,48.3723181772035389],"hsluv":[17.6946931608209894,89.5341066932624869,48.3723181772035389]},"#cc4433":{"lch":[48.5270263662828114,110.48209503335984,15.4815426750504042],"luv":[48.5270263662828114,106.473417017787412,29.4907577304601034],"rgb":[0.8,0.266666666666666663,0.2],"xyz":[0.275657929827429427,0.17212778793581418,0.0500297273638337786],"hpluv":[15.4815426750504042,288.900004133964501,48.5270263662828114],"hsluv":[15.4815426750504042,78.8475327486048,48.5270263662828114]},"#cc4444":{"lch":[48.7490888960709725,105.371058014361893,12.1770506300618457],"luv":[48.7490888960709725,103.000257716521162,22.2262632351064191],"rgb":[0.8,0.266666666666666663,0.266666666666666663],"xyz":[0.280115925071648342,0.173910986033501774,0.0735085023167204171],"hpluv":[12.1770506300618457,274.28001464324592,48.7490888960709725],"hsluv":[12.1770506300618457,64.2723089184284788,48.7490888960709725]},"#cc4455":{"lch":[49.0437296069087,99.5540950311582691,7.58056168126664254],"luv":[49.0437296069087,98.6840273694228074,13.1331861946711772],"rgb":[0.8,0.266666666666666663,0.333333333333333315],"xyz":[0.286078339111010327,0.176295951649246607,0.104910549590694333],"hpluv":[7.58056168126664254,257.581676799067395,49.0437296069087],"hsluv":[7.58056168126664254,65.7689369270132858,49.0437296069087]},"#cc4466":{"lch":[49.4147368002801244,93.7049448509207679,1.51289058041819868],"luv":[49.4147368002801244,93.6722802728102835,2.47398423725391092],"rgb":[0.8,0.266666666666666663,0.4],"xyz":[0.293663334884518512,0.179329949958649898,0.14485819399783828],"hpluv":[1.51289058041819868,240.627550105868352,49.4147368002801244],"hsluv":[1.51289058041819868,67.500804726855,49.4147368002801244]},"#cc4477":{"lch":[49.8646356184384132,88.6490107187132566,353.900159994018],"luv":[49.8646356184384132,88.1471013723349586,-9.41995865499641383],"rgb":[0.8,0.266666666666666663,0.466666666666666674],"xyz":[0.302977347904720418,0.183055555166730721,0.19391199590423619],"hpluv":[353.900159994018,225.590377060975072,49.8646356184384132],"hsluv":[353.900159994018,69.4017616341687784,49.8646356184384132]},"#cc4488":{"lch":[50.3948096201307436,85.2405150759366279,344.907000147604322],"luv":[50.3948096201307436,82.3000967091543743,-22.1954835963269055],"rgb":[0.8,0.266666666666666663,0.533333333333333326],"xyz":[0.314117765006664218,0.187511722007508319,0.252584859307808385],"hpluv":[344.907000147604322,214.634525667930632,50.3948096201307436],"hsluv":[344.907000147604322,71.4025087995354824,50.3948096201307436]},"#cc4499":{"lch":[51.0056074652318046,84.1718897613591679,335.041688295241613],"luv":[51.0056074652318046,76.3115014820887581,-35.5170630478867793],"rgb":[0.8,0.266666666666666663,0.6],"xyz":[0.327174729115737,0.192734507651137477,0.321351536948926264],"hpluv":[335.041688295241613,209.40569084337892,51.0056074652318046],"hsluv":[335.041688295241613,73.4381222823911344,51.0056074652318046]},"#cc44aa":{"lch":[51.6964496814969152,85.7749410926589348,325.085448007895536],"luv":[51.6964496814969152,70.3360122964612913,-49.093644127128691],"rgb":[0.8,0.266666666666666663,0.66666666666666663],"xyz":[0.342232422080989473,0.198757584837238571,0.400655386565924865],"hpluv":[325.085448007895536,210.542141790665795,51.6964496814969152],"hsluv":[325.085448007895536,75.4531429469973602,51.6964496814969152]},"#cc44bb":{"lch":[52.465940673938249,89.9444778306290829,315.812454406659811],"luv":[52.465940673938249,64.4957791941851326,-62.692133145710109],"rgb":[0.8,0.266666666666666663,0.733333333333333282],"xyz":[0.359370014188326148,0.20561262168017333,0.490913371664566611],"hpluv":[315.812454406659811,217.538619181736436,52.465940673938249],"hsluv":[315.812454406659811,77.4040753157756143,52.465940673938249]},"#cc44cc":{"lch":[53.3119860408958175,96.2498903650287758,307.715012949243885],"luv":[53.3119860408958175,58.8793631430003828,-76.1397530279337502],"rgb":[0.8,0.266666666666666663,0.8],"xyz":[0.378662389632047902,0.213329571857662131,0.592519882334836767],"hpluv":[307.715012949243885,229.094523932317799,53.3119860408958175],"hsluv":[307.715012949243885,79.2597279113993,53.3119860408958175]},"#cc44dd":{"lch":[54.2319126329379486,104.138844540210442,300.941773361922515],"luv":[54.2319126329379486,53.5447276840333259,-89.31887303035586],"rgb":[0.8,0.266666666666666663,0.866666666666666696],"xyz":[0.40018071518268139,0.221936902077915665,0.705849730234842765],"hpluv":[300.941773361922515,243.66724889744043,54.2319126329379486],"hsluv":[300.941773361922515,81.0000946003390538,54.2319126329379486]},"#cc44ee":{"lch":[55.2225876682288401,113.096616320403683,295.407423092027],"luv":[55.2225876682288401,48.5243479249087528,-102.157879194837463],"rgb":[0.8,0.266666666666666663,0.933333333333333348],"xyz":[0.423992895448856155,0.23146177418438571,0.831260546303366],"hpluv":[295.407423092027,259.879597148300718,55.2225876682288401],"hsluv":[295.407423092027,86.8652077390175634,55.2225876682288401]},"#cc44ff":{"lch":[56.2805330741479537,122.715491745326418,290.92682559337851],"luv":[56.2805330741479537,43.8309487146615382,-114.62085259266739],"rgb":[0.8,0.266666666666666663,1],"xyz":[0.450163943858687521,0.241930193548318406,0.969094734595147833],"hpluv":[290.92682559337851,276.681751484143376,56.2805330741479537],"hsluv":[290.92682559337851,99.9999999999989768,56.2805330741479537]},"#cc5500":{"lch":[51.07852272981998,108.355754132896138,24.3337665629108457],"luv":[51.07852272981998,98.7294936728878838,44.6481414260866],"rgb":[0.8,0.333333333333333315,0],"xyz":[0.281496412171203525,0.193364391616277664,0.0225003345836030169],"hpluv":[24.3337665629108457,269.186315008697875,51.07852272981998],"hsluv":[24.3337665629108457,100.000000000002217,51.07852272981998]},"#cc5511":{"lch":[51.1252833166066,107.003417336388864,23.6474066829241423],"luv":[51.1252833166066,98.0184651549503201,42.91983003616388],"rgb":[0.8,0.333333333333333315,0.0666666666666666657],"xyz":[0.282508077670840629,0.193769057816132517,0.0278284395483586466],"hpluv":[23.6474066829241423,265.583595811902,51.1252833166066],"hsluv":[23.6474066829241423,96.7082849697218307,51.1252833166066]},"#cc5522":{"lch":[51.2117930688627467,104.583581473170284,22.351909846807331],"luv":[51.2117930688627467,96.7257518395109486,39.7725337995530808],"rgb":[0.8,0.333333333333333315,0.133333333333333331],"xyz":[0.284383435809317686,0.194519201071523345,0.0377053257443378462],"hpluv":[22.351909846807331,259.139045481141636,51.2117930688627467],"hsluv":[22.351909846807331,90.7274756498525079,51.2117930688627467]},"#cc5533":{"lch":[51.3537468781662625,100.840694749975015,20.1540565840537802],"luv":[51.3537468781662625,94.6661789932146718,34.7442120716858369],"rgb":[0.8,0.333333333333333315,0.2],"xyz":[0.287471186541775392,0.195754301364506444,0.0539674796019489894],"hpluv":[20.1540565840537802,249.174169543579183,51.3537468781662625],"hsluv":[20.1540565840537802,81.2092815218714321,51.3537468781662625]},"#cc5544":{"lch":[51.5576456995760424,95.9504499860225764,16.842752904303623],"luv":[51.5576456995760424,91.8345174188591074,27.8012636936791502],"rgb":[0.8,0.333333333333333315,0.266666666666666663],"xyz":[0.291929181785994307,0.197537499462194038,0.0774462545548356279],"hpluv":[16.842752904303623,236.152889903020736,51.5576456995760424],"hsluv":[16.842752904303623,68.1451659970290109,51.5576456995760424]},"#cc5555":{"lch":[51.8284441386287114,90.3192908744292851,12.1770506300618919],"luv":[51.8284441386287114,88.2871484081680364,19.0513445723360242],"rgb":[0.8,0.333333333333333315,0.333333333333333315],"xyz":[0.297891595825356292,0.199922465077938871,0.108848301828809529],"hpluv":[12.1770506300618919,221.132040760117775,51.8284441386287114],"hsluv":[12.1770506300618919,51.8180912815801,51.8284441386287114]},"#cc5566":{"lch":[52.1698415772242612,84.57836719340618,5.91246023067467696],"luv":[52.1698415772242612,84.1284474176031836,8.71232071300305577],"rgb":[0.8,0.333333333333333315,0.4],"xyz":[0.305476591598864478,0.202956463387342162,0.148795946235953491],"hpluv":[5.91246023067467696,205.721226704565879,52.1698415772242612],"hsluv":[5.91246023067467696,54.0130370973951415,52.1698415772242612]},"#cc5577":{"lch":[52.5844387621358607,79.5477054283049654,357.892334615122479],"luv":[52.5844387621358607,79.493890006545314,-2.92555815796844554],"rgb":[0.8,0.333333333333333315,0.466666666666666674],"xyz":[0.314790604619066383,0.206682068595422985,0.1978497481423514],"hpluv":[357.892334615122479,191.959557587962337,52.5844387621358607],"hsluv":[357.892334615122479,56.4492590331968884,52.5844387621358607]},"#cc5588":{"lch":[53.0738428910491962,76.1348505840982,348.222799824086337],"luv":[53.0738428910491962,74.5321119975331072,-15.5396188708133902],"rgb":[0.8,0.333333333333333315,0.533333333333333326],"xyz":[0.325931021721010183,0.211138235436200583,0.256522611545923596],"hpluv":[348.222799824086337,182.029716109510787,53.0738428910491962],"hsluv":[348.222799824086337,59.0443947768825339,53.0738428910491962]},"#cc5599":{"lch":[53.6387547547300443,75.1322702050955655,337.451566852479516],"luv":[53.6387547547300443,69.3888374020903314,-28.8105409556599774],"rgb":[0.8,0.333333333333333315,0.6],"xyz":[0.338987985830082938,0.216361021079829741,0.325289289187041475],"hpluv":[337.451566852479516,177.740808472615271,53.6387547547300443],"hsluv":[337.451566852479516,61.7180151219793274,53.6387547547300443]},"#cc55aa":{"lch":[54.2790527162633651,76.9604755372169507,326.525055670409472],"luv":[54.2790527162633651,64.1948187783047359,-42.449264268479169],"rgb":[0.8,0.333333333333333315,0.66666666666666663],"xyz":[0.354045678795335439,0.222384098265930835,0.404593138804040076],"hpluv":[326.525055670409472,179.918080614224607,54.2790527162633651],"hsluv":[326.525055670409472,64.3982563598392517,54.2790527162633651]},"#cc55bb":{"lch":[54.9938795911038767,81.534325182187132,316.414019967357433],"luv":[54.9938795911038767,59.0586208757266817,-56.2132144888709888],"rgb":[0.8,0.333333333333333315,0.733333333333333282],"xyz":[0.371183270902672113,0.229239135108865594,0.494851123902681822],"hpluv":[316.414019967357433,188.133202867989326,54.9938795911038767],"hsluv":[316.414019967357433,67.0257727218245378,54.9938795911038767]},"#cc55cc":{"lch":[55.7817339145568667,88.3780574248019,307.715012949244169],"luv":[55.7817339145568667,54.0638926159085145,-69.9126351198200382],"rgb":[0.8,0.333333333333333315,0.8],"xyz":[0.390475646346393868,0.236956085286354395,0.596457634572952],"hpluv":[307.715012949244169,201.044301715196383,55.7817339145568667],"hsluv":[307.715012949244169,69.5552053299685156,55.7817339145568667]},"#cc55dd":{"lch":[56.6405645837994882,96.8744721490496232,300.570417552325068],"luv":[56.6405645837994882,49.2700598324241312,-83.4093793183137],"rgb":[0.8,0.333333333333333315,0.866666666666666696],"xyz":[0.411993971897027356,0.245563415506607929,0.709787482472958],"hpluv":[300.570417552325068,217.030665421015726,56.6405645837994882],"hsluv":[300.570417552325068,72.1703256475756234,56.6405645837994882]},"#cc55ee":{"lch":[57.5678665910353118,106.457154357221242,294.836459829444038],"luv":[57.5678665910353118,44.7151619549172707,-96.6109724885468],"rgb":[0.8,0.333333333333333315,0.933333333333333348],"xyz":[0.435806152163202121,0.255088287613077946,0.835198298541481199],"hpluv":[294.836459829444038,234.657286550118499,57.5678665910353118],"hsluv":[294.836459829444038,85.8995510844284809,57.5678665910353118]},"#cc55ff":{"lch":[58.560775097021633,116.686665261471418,290.266986003053091],"luv":[58.560775097021633,40.4196983751927874,-109.462440284789551],"rgb":[0.8,0.333333333333333315,1],"xyz":[0.461977200573033486,0.26555670697701067,0.973032486833263],"hpluv":[290.266986003053091,252.844632524376181,58.560775097021633],"hsluv":[290.266986003053091,99.9999999999988,58.560775097021633]},"#cc6600":{"lch":[54.388060759003551,98.5584029412379579,30.482787603130209],"luv":[54.388060759003551,84.9358174587045482,49.9966569177284157],"rgb":[0.8,0.4,0],"xyz":[0.29652446987705,0.223420507027971,0.0275096871522183678],"hpluv":[30.482787603130209,229.947880001204965,54.388060759003551],"hsluv":[30.482787603130209,100.000000000002359,54.388060759003551]},"#cc6611":{"lch":[54.430531479182676,97.2669366851907711,29.8266301777559697],"luv":[54.430531479182676,84.3824110244092367,48.3783596438383583],"rgb":[0.8,0.4,0.0666666666666666657],"xyz":[0.297536135376687105,0.223825173227825858,0.032837792116974],"hpluv":[29.8266301777559697,226.757672191171366,54.430531479182676],"hsluv":[29.8266301777559697,97.1300271864182463,54.430531479182676]},"#cc6622":{"lch":[54.5091256699603548,94.945229062596681,28.5830621108902889],"luv":[54.5091256699603548,83.3737269438019695,45.4248629854764],"rgb":[0.8,0.4,0.133333333333333331],"xyz":[0.299411493515164162,0.224575316483216686,0.0427146783129532],"hpluv":[28.5830621108902889,221.025945543219876,54.5091256699603548],"hsluv":[28.5830621108902889,91.902111940908739,54.5091256699603548]},"#cc6633":{"lch":[54.6381494647888388,91.324965774397,26.4577509745500876],"luv":[54.6381494647888388,81.7598754062496624,40.688722605278663],"rgb":[0.8,0.4,0.2],"xyz":[0.302499244247621868,0.225810416776199785,0.0589768321705643403],"hpluv":[26.4577509745500876,212.096187894217309,54.6381494647888388],"hsluv":[26.4577509745500876,83.5463344335908289,54.6381494647888388]},"#cc6644":{"lch":[54.8236025158742137,86.5353782352002,23.2174871910251],"luv":[54.8236025158742137,79.5273159773273903,34.1141861950638798],"rgb":[0.8,0.4,0.266666666666666663],"xyz":[0.306957239491840783,0.227593614873887379,0.0824556071234509858],"hpluv":[23.2174871910251,200.292852977212362,54.8236025158742137],"hsluv":[23.2174871910251,72.0055590941951635,54.8236025158742137]},"#cc6655":{"lch":[55.0701314820163077,80.921365039871,18.5706632184066578],"luv":[55.0701314820163077,76.7079190692017505,25.7713498286149552],"rgb":[0.8,0.4,0.333333333333333315],"xyz":[0.312919653531202768,0.229978580489632212,0.113857654397424887],"hpluv":[18.5706632184066578,186.460314881725708,55.0701314820163077],"hsluv":[18.5706632184066578,57.463707489477386,55.0701314820163077]},"#cc6666":{"lch":[55.3812986167643686,75.0592421503045841,12.1770506300619576],"luv":[55.3812986167643686,73.3704437553848834,15.8324923911544637],"rgb":[0.8,0.4,0.4],"xyz":[0.320504649304710953,0.233012578799035502,0.153805298804568835],"hpluv":[12.1770506300619576,171.980959079196282,55.3812986167643686],"hsluv":[12.1770506300619576,45.9214429163451925,55.3812986167643686]},"#cc6677":{"lch":[55.7597240294908403,69.7578535305897702,3.7339069954147126],"luv":[55.7597240294908403,69.6097753289024,4.54283037928401079],"rgb":[0.8,0.4,0.466666666666666674],"xyz":[0.329818662324912859,0.236738184007116326,0.202859100710966744],"hpluv":[3.7339069954147126,158.749300244695775,55.7597240294908403],"hsluv":[3.7339069954147126,47.4001946683844935,55.7597240294908403]},"#cc6688":{"lch":[56.2071770412836855,65.9988703650454198,353.20230012342131],"luv":[56.2071770412836855,65.534915505775615,-7.81189727997758432],"rgb":[0.8,0.4,0.533333333333333326],"xyz":[0.340959079426856659,0.241194350847893924,0.26153196411453894],"hpluv":[353.20230012342131,148.999240608904586,56.2071770412836855],"hsluv":[353.20230012342131,48.9818497710332537,56.2071770412836855]},"#cc6699":{"lch":[56.7246474757154573,64.7364860461136544,341.13073016495332],"luv":[56.7246474757154573,61.2574795353059756,-20.9364234428957907],"rgb":[0.8,0.4,0.6],"xyz":[0.354016043535929414,0.246417136491523081,0.330298641755656819],"hpluv":[341.13073016495332,144.81603174775961,56.7246474757154573],"hsluv":[341.13073016495332,50.615240188358726,56.7246474757154573]},"#cc66aa":{"lch":[57.3124110050500661,66.5536753014576874,328.724652687595039],"luv":[57.3124110050500661,56.882247269492467,-34.5514347271451925],"rgb":[0.8,0.4,0.66666666666666663],"xyz":[0.369073736501181915,0.252440213677624203,0.40960249137265542],"hpluv":[328.724652687595039,147.354258527000582,57.3124110050500661],"hsluv":[328.724652687595039,52.5782983823555057,57.3124110050500661]},"#cc66bb":{"lch":[57.9700950113726634,71.4140361316817831,317.320615294889421],"luv":[57.9700950113726634,52.5006394421278628,-48.4112323204526405],"rgb":[0.8,0.4,0.733333333333333282],"xyz":[0.386211328608518589,0.259295250520558962,0.499860476471297166],"hpluv":[317.320615294889421,156.321564636453559,57.9700950113726634],"hsluv":[317.320615294889421,55.7867325729046044,57.9700950113726634]},"#cc66cc":{"lch":[58.6967474031167882,78.7715159072838844,307.71501294924451],"luv":[58.6967474031167882,48.1872412824568599,-62.3132529717215391],"rgb":[0.8,0.4,0.8],"xyz":[0.405503704052240344,0.267012200698047764,0.601466987141567322],"hpluv":[307.71501294924451,170.292097080892688,58.6967474031167882],"hsluv":[307.71501294924451,58.9158791245518429,58.6967474031167882]},"#cc66dd":{"lch":[59.4909085631812928,87.9045601549668589,300.035118747227784],"luv":[59.4909085631812928,43.9989332886277964,-76.1006278916348151],"rgb":[0.8,0.4,0.866666666666666696],"xyz":[0.427022029602873832,0.27561953091830127,0.71479683504157332],"hpluv":[300.035118747227784,187.499506963343748,59.4909085631812928],"hsluv":[300.035118747227784,69.8010448945604907,59.4909085631812928]},"#cc66ee":{"lch":[60.3506853352839272,98.1678970647401314,294.030303780460372],"luv":[60.3506853352839272,39.9759075841908498,-89.6597057040320919],"rgb":[0.8,0.4,0.933333333333333348],"xyz":[0.450834209869048597,0.285144403024771287,0.840207651110096543],"hpluv":[294.030303780460372,206.408039079415715,60.3506853352839272],"hsluv":[294.030303780460372,84.6650997716967169,60.3506853352839272]},"#cc66ff":{"lch":[61.2738253236974799,109.076950193692937,289.351384827957531],"luv":[61.2738253236974799,36.143813792667018,-102.914555763887847],"rgb":[0.8,0.4,1],"xyz":[0.477005258278879962,0.295612822388704,0.978041839401878388],"hpluv":[289.351384827957531,225.890163025573315,61.2738253236974799],"hsluv":[289.351384827957531,99.9999999999987,61.2738253236974799]},"#cc7700":{"lch":[58.0681687130694684,90.1274111260576,38.2527636780657616],"luv":[58.0681687130694684,70.775890411238,55.8007488550273862],"rgb":[0.8,0.466666666666666674,0],"xyz":[0.314978207930467602,0.260327983134806762,0.0336609331700240683],"hpluv":[38.2527636780657616,196.95095583694345,58.0681687130694684],"hsluv":[38.2527636780657616,100.00000000000226,58.0681687130694684]},"#cc7711":{"lch":[58.1065272060428,88.8714225311590837,37.658223554494576],"luv":[58.1065272060428,70.356768805075,54.2959927252558288],"rgb":[0.8,0.466666666666666674,0.0666666666666666657],"xyz":[0.315989873430104706,0.260732649334661615,0.0389890381347797],"hpluv":[37.658223554494576,194.078102813960953,58.1065272060428],"hsluv":[37.658223554494576,97.5201736027742925,58.1065272060428]},"#cc7722":{"lch":[58.1775287784180364,86.6008188207648573,36.5262538454337786],"luv":[58.1775287784180364,69.5910513475594286,51.5440335321973748],"rgb":[0.8,0.466666666666666674,0.133333333333333331],"xyz":[0.317865231568581763,0.261482792590052415,0.0488659243307589],"hpluv":[36.5262538454337786,188.888733728089306,58.1775287784180364],"hsluv":[36.5262538454337786,92.9922153048462832,58.1775287784180364]},"#cc7733":{"lch":[58.2941365993826111,83.0249283524691606,34.5753600294232513],"luv":[58.2941365993826111,68.3611064237300781,47.1157920070976459],"rgb":[0.8,0.466666666666666674,0.2],"xyz":[0.320952982301039469,0.262717892883035542,0.0651280781883700477],"hpluv":[34.5753600294232513,180.726967614303447,58.2941365993826111],"hsluv":[34.5753600294232513,85.7262720770138458,58.2941365993826111]},"#cc7744":{"lch":[58.4618482438389577,78.2181767747613321,31.5590767862408974],"luv":[58.4618482438389577,66.6497843857434447,40.9376284034837923],"rgb":[0.8,0.466666666666666674,0.266666666666666663],"xyz":[0.325410977545258384,0.264501090980723108,0.0886068531412566862],"hpluv":[31.5590767862408974,169.775287201810244,58.4618482438389577],"hsluv":[31.5590767862408974,75.6318325574838,58.4618482438389577]},"#cc7755":{"lch":[58.6849825995062133,72.4480337937475,27.1381330463907204],"luv":[58.6849825995062133,64.4721877935720187,33.0462494345479811],"rgb":[0.8,0.466666666666666674,0.333333333333333315],"xyz":[0.331373391584620369,0.266886056596467969,0.120008900415230588],"hpluv":[27.1381330463907204,156.653084219512607,58.6849825995062133],"hsluv":[27.1381330463907204,62.8141161752895059,58.6849825995062133]},"#cc7766":{"lch":[58.9669266929607829,66.2083874258113667,20.8554290651987451],"luv":[58.9669266929607829,61.8705265372573407,23.5709251309504673],"rgb":[0.8,0.466666666666666674,0.4],"xyz":[0.338958387358128554,0.269920054905871287,0.159956544822374536],"hpluv":[20.8554290651987451,142.476698671576116,58.9669266929607829],"hsluv":[20.8554290651987451,47.542957476979069,58.9669266929607829]},"#cc7777":{"lch":[59.3102652975897229,60.2635194006596251,12.177050630062082],"luv":[59.3102652975897229,58.907617956407762,12.7115820123061383],"rgb":[0.8,0.466666666666666674,0.466666666666666674],"xyz":[0.34827240037833046,0.273645660113952083,0.209010346728772445],"hpluv":[12.177050630062082,128.932959302114057,59.3102652975897229],"hsluv":[12.177050630062082,43.5373021749198443,59.3102652975897229]},"#cc7788":{"lch":[59.7168613687891963,55.6638868177661834,0.734433949810619269],"luv":[59.7168613687891963,55.6593138534775917,0.713496335773026069],"rgb":[0.8,0.466666666666666674,0.533333333333333326],"xyz":[0.35941281748027426,0.278101826954729681,0.26768321013234464],"hpluv":[0.734433949810619269,118.281243349182901,59.7168613687891963],"hsluv":[0.734433949810619269,45.0130000154657779,59.7168613687891963]},"#cc7799":{"lch":[60.187915321807921,53.6038783156568073,346.890122071781263],"luv":[60.187915321807921,52.2067938730354371,-12.1583898596044406],"rgb":[0.8,0.466666666666666674,0.6],"xyz":[0.37246978158934696,0.283324612598358838,0.336449887773462519],"hpluv":[346.890122071781263,113.012436406344946,60.187915321807921],"hsluv":[346.890122071781263,46.5549497102544,60.187915321807921]},"#cc77aa":{"lch":[60.7240163061688349,54.9761438743297148,332.197464335395125],"luv":[60.7240163061688349,48.6297161920954863,-25.6422912074417866],"rgb":[0.8,0.466666666666666674,0.66666666666666663],"xyz":[0.387527474554599516,0.28934768978445996,0.41575373739046112],"hpluv":[332.197464335395125,114.882297594683308,60.7240163061688349],"hsluv":[332.197464335395125,48.1189262345266471,60.7240163061688349]},"#cc77bb":{"lch":[61.3251919150652043,59.875823087291181,318.726648244723037],"luv":[61.3251919150652043,45.0009333565193046,-39.4972174643062743],"rgb":[0.8,0.466666666666666674,0.733333333333333282],"xyz":[0.40466506666193619,0.296202726627394719,0.506011722489102866],"hpluv":[318.726648244723037,123.894465684476771,61.3251919150652043],"hsluv":[318.726648244723037,49.6642191709372156,61.3251919150652043]},"#cc77cc":{"lch":[61.9909592768387228,67.6487625915650881,307.715012949244965],"luv":[61.9909592768387228,41.3830711255614219,-53.514451360232222],"rgb":[0.8,0.466666666666666674,0.8],"xyz":[0.423957442105657889,0.303919676804883521,0.607618233159373],"hpluv":[307.715012949244965,138.474825543749517,61.9909592768387228],"hsluv":[307.715012949244965,51.1553628289834066,61.9909592768387228]},"#cc77dd":{"lch":[62.7203784873954362,77.3966796673740305,299.257833182927357],"luv":[62.7203784873954362,37.8268934727942252,-67.5231231041040161],"rgb":[0.8,0.466666666666666674,0.866666666666666696],"xyz":[0.445475767656291488,0.312527007025137,0.720948081059379],"hpluv":[299.257833182927357,156.586020071329443,62.7203784873954362],"hsluv":[299.257833182927357,66.8390608629672158,62.7203784873954362]},"#cc77ee":{"lch":[63.5121081687847351,88.3507940057556453,292.894169444170245],"luv":[63.5121081687847351,34.371127600373157,-81.3909601179783],"rgb":[0.8,0.466666666666666674,0.933333333333333348],"xyz":[0.469287947922466198,0.322051879131607044,0.846358897127902243],"hpluv":[292.894169444170245,176.519730115921618,63.5121081687847351],"hsluv":[292.894169444170245,83.1130682001540322,63.5121081687847351]},"#cc77ff":{"lch":[64.3644622692190467,99.9639900757921112,288.092077643344339],"luv":[64.3644622692190467,31.0433170684360782,-95.0216384686225553],"rgb":[0.8,0.466666666666666674,1],"xyz":[0.495458996332297619,0.332520298495539768,0.984193085419684088],"hpluv":[288.092077643344339,197.077372703744913,64.3644622692190467],"hsluv":[288.092077643344339,99.9999999999984794,64.3644622692190467]},"#cc8800":{"lch":[62.03823759594124,83.9779445354575813,47.4964941193052752],"luv":[62.03823759594124,56.738465406715342,61.9115636346826221],"rgb":[0.8,0.533333333333333326,0],"xyz":[0.337050577655438111,0.304472722584748334,0.0410183897450140181],"hpluv":[47.4964941193052752,171.769129739761638,62.03823759594124],"hsluv":[47.4964941193052752,100.000000000002245,62.03823759594124]},"#cc8811":{"lch":[62.0727951053461879,82.7448035916202542,47.0033697453910904],"luv":[62.0727951053461879,56.4282611354359744,60.519037225048919],"rgb":[0.8,0.533333333333333326,0.0666666666666666657],"xyz":[0.338062243155075215,0.304877388784603187,0.0463464947097696478],"hpluv":[47.0033697453910904,169.152629782786704,62.0727951053461879],"hsluv":[47.0033697453910904,97.8669953021426,62.0727951053461879]},"#cc8822":{"lch":[62.1367747194074127,80.5023095814055836,46.0605806208152728],"luv":[62.1367747194074127,55.8603434591127268,57.9676105818622389],"rgb":[0.8,0.533333333333333326,0.133333333333333331],"xyz":[0.339937601293552272,0.305627532039994,0.0562233809057488473],"hpluv":[46.0605806208152728,164.398919884807611,62.1367747194074127],"hsluv":[46.0605806208152728,93.9640765124603,62.1367747194074127]},"#cc8833":{"lch":[62.2418885518498541,76.9329948636363241,44.4230175211057343],"luv":[62.2418885518498541,54.9448944756850963,53.8492736231801246],"rgb":[0.8,0.533333333333333326,0.2],"xyz":[0.34302535202601,0.306862632332977114,0.0724855347633599906],"hpluv":[44.4230175211057343,156.844467463147254,62.2418885518498541],"hsluv":[44.4230175211057343,87.678806867525978,62.2418885518498541]},"#cc8844":{"lch":[62.3931521103864668,72.0506908450526424,41.8566920827827929],"luv":[62.3931521103864668,53.6645163812677168,48.0772475586321661],"rgb":[0.8,0.533333333333333326,0.266666666666666663],"xyz":[0.347483347270228893,0.30864583043066468,0.0959643097162466291],"hpluv":[41.8566920827827929,146.534723453778,62.3931521103864668],"hsluv":[41.8566920827827929,78.900857077449,62.3931521103864668]},"#cc8855":{"lch":[62.5945538889838673,66.028576146577123,38.0101307109045408],"luv":[62.5945538889838673,52.0240395147187513,40.6604498316892062],"rgb":[0.8,0.533333333333333326,0.333333333333333315],"xyz":[0.353445761309590878,0.311030796046409541,0.127366356990220531],"hpluv":[38.0101307109045408,133.855034432196135,62.5945538889838673],"hsluv":[38.0101307109045408,67.6770944211119314,62.5945538889838673]},"#cc8866":{"lch":[62.8492816845599265,59.2369010326618337,32.3420191431213624],"luv":[62.8492816845599265,50.047464385327217,31.6900891849924626],"rgb":[0.8,0.533333333333333326,0.4],"xyz":[0.361030757083099063,0.31406479435581286,0.167314001397364492],"hpluv":[32.3420191431213624,119.60004374597824,62.8492816845599265],"hsluv":[32.3420191431213624,54.1901780257147436,62.8492816845599265]},"#cc8877":{"lch":[63.1598410661450771,52.3169991415742,24.053169540805424],"luv":[63.1598410661450771,47.7741895619322392,21.3235834436907119],"rgb":[0.8,0.533333333333333326,0.466666666666666674],"xyz":[0.370344770103300969,0.317790399563893655,0.216367803303762402],"hpluv":[24.053169540805424,105.109295035123296,63.1598410661450771],"hsluv":[24.053169540805424,38.7316682482548558,63.1598410661450771]},"#cc8888":{"lch":[63.5281271999152182,46.2961098245983322,12.1770506300622312],"luv":[63.5281271999152182,45.2544686659219906,9.76539045078869528],"rgb":[0.8,0.533333333333333326,0.533333333333333326],"xyz":[0.381485187205244769,0.322246566404671253,0.275040666707334569],"hpluv":[12.1770506300622312,92.4736018048895403,63.5281271999152182],"hsluv":[12.1770506300622312,40.0703189706204199,63.5281271999152182]},"#cc8899":{"lch":[63.9554753143552119,42.6335463086933615,356.296984030050055],"luv":[63.9554753143552119,42.5445368433351,-2.7534806412255004],"rgb":[0.8,0.533333333333333326,0.6],"xyz":[0.394542151314317469,0.327469352048300411,0.343807344348452504],"hpluv":[356.296984030050055,84.588837176407921,63.9554753143552119],"hsluv":[356.296984030050055,41.5088242950414781,63.9554753143552119]},"#cc88aa":{"lch":[64.442701858069384,42.8028595258545153,338.056731442080661],"luv":[64.442701858069384,39.701977128446444,-15.9949303118941444],"rgb":[0.8,0.533333333333333326,0.66666666666666663],"xyz":[0.40959984427957,0.333492429234401533,0.423111193965451104],"hpluv":[338.056731442080661,84.28268641071584,64.442701858069384],"hsluv":[338.056731442080661,42.9831867606486924,64.442701858069384]},"#cc88bb":{"lch":[64.9901424985427099,47.2946673003310707,321.051918945199532],"luv":[64.9901424985427099,36.7818149859187784,-29.7301806484697622],"rgb":[0.8,0.533333333333333326,0.733333333333333282],"xyz":[0.426737436386906699,0.340347466077336291,0.513369179064092851],"hpluv":[321.051918945199532,92.3430068912496296,64.9901424985427099],"hsluv":[321.051918945199532,44.4548878388224864,64.9901424985427099]},"#cc88cc":{"lch":[65.5976900795525637,55.3077284551996158,307.715012949245761],"luv":[65.5976900795525637,33.8336367550969399,-43.751912538747959],"rgb":[0.8,0.533333333333333326,0.8],"xyz":[0.446029811830628398,0.348064416254825093,0.614975689734363],"hpluv":[307.715012949245761,106.988377595373095,65.5976900795525637],"hsluv":[307.715012949245761,45.8886814173124122,65.5976900795525637]},"#cc88dd":{"lch":[66.2648339334855905,65.6132669537387727,298.095232643272539],"luv":[66.2648339334855905,30.8998122908772608,-57.8817967994354774],"rgb":[0.8,0.533333333333333326,0.866666666666666696],"xyz":[0.467548137381262,0.356671746475078599,0.728305537634369],"hpluv":[298.095232643272539,125.645770778198369,66.2648339334855905],"hsluv":[298.095232643272539,63.1276078601331037,66.2648339334855905]},"#cc88ee":{"lch":[66.9907009061042,77.2337728548956193,291.267726386147558],"luv":[66.9907009061042,28.0147259973813227,-71.9738202174461463],"rgb":[0.8,0.533333333333333326,0.933333333333333348],"xyz":[0.491360317647436706,0.366196618581548616,0.853716353702892228],"hpluv":[291.267726386147558,146.295866424915545,66.9907009061042],"hsluv":[291.267726386147558,81.1585487563552874,66.9907009061042]},"#cc88ff":{"lch":[67.7740978167257,89.535143384050329,286.350196506734335],"luv":[67.7740978167257,25.2048126805589376,-85.914255618845857],"rgb":[0.8,0.533333333333333326,1],"xyz":[0.517531366057268127,0.37666503794548134,0.991550541994674073],"hpluv":[286.350196506734335,167.63670457649863,67.7740978167257],"hsluv":[286.350196506734335,99.9999999999982379,67.7740978167257]},"#cc9900":{"lch":[66.2294666531998217,80.7116888085701163,57.6888018595631422],"luv":[66.2294666531998217,43.1418134232290527,68.2140795209226383],"rgb":[0.8,0.6,0],"xyz":[0.362920178107905556,0.356211923489684,0.0496415898958362731],"hpluv":[57.6888018595631422,154.64094800189136,66.2294666531998217],"hsluv":[57.6888018595631422,100.000000000002331,66.2294666531998217]},"#cc9911":{"lch":[66.2605931548954459,79.5070460268624,57.3307205104302042],"luv":[66.2605931548954459,42.9170325725223805,66.9290570909725915],"rgb":[0.8,0.6,0.0666666666666666657],"xyz":[0.36393184360754266,0.356616589689538854,0.0549696948605919],"hpluv":[57.3307205104302042,152.261332222626407,66.2605931548954459],"hsluv":[57.3307205104302042,98.1673920986410877,66.2605931548954459]},"#cc9922":{"lch":[66.318231165714252,77.3048675578901339,56.6444543825244],"luv":[66.318231165714252,42.5047546114663533,64.5708013235236535],"rgb":[0.8,0.6,0.133333333333333331],"xyz":[0.365807201746019717,0.357366732944929655,0.0648465810565711],"hpluv":[56.6444543825244,147.915345655385721,66.318231165714252],"hsluv":[56.6444543825244,94.8079930897652901,66.318231165714252]},"#cc9933":{"lch":[66.4129558628457772,73.7662990604099207,55.446788144651876],"luv":[66.4129558628457772,41.8381333944198062,60.7539091017242114],"rgb":[0.8,0.6,0.2],"xyz":[0.368894952478477423,0.358601833237912782,0.0811087349141822456],"hpluv":[55.446788144651876,140.943324602767206,66.4129558628457772],"hsluv":[55.446788144651876,89.3812598244831804,66.4129558628457772]},"#cc9944":{"lch":[66.5493334014023361,68.8491039809152596,53.5533094328142383],"luv":[66.5493334014023361,40.9015039610359423,55.3829043360877122],"rgb":[0.8,0.6,0.266666666666666663],"xyz":[0.373352947722696338,0.360385031335600348,0.104587509867068884],"hpluv":[53.5533094328142383,131.278591794008349,66.5493334014023361],"hsluv":[53.5533094328142383,81.7675495661837459,66.5493334014023361]},"#cc9955":{"lch":[66.7310322275847341,62.6300376921671571,50.6698876242401539],"luv":[66.7310322275847341,39.6941340540006422,48.4447865412296466],"rgb":[0.8,0.6,0.333333333333333315],"xyz":[0.379315361762058323,0.362769996951345208,0.135989557141042799],"hpluv":[50.6698876242401539,119.095172229338388,66.7310322275847341],"hsluv":[50.6698876242401539,71.9728873324543912,66.7310322275847341]},"#cc9966":{"lch":[66.9610303820851,55.3290996264574488,46.2964172073191236],"luv":[66.9610303820851,38.2284030091626121,39.9987308404091877],"rgb":[0.8,0.6,0.4],"xyz":[0.386900357535566508,0.365803995260748527,0.175937201548186761],"hpluv":[46.2964172073191236,104.850571413887963,66.9610303820851],"hsluv":[46.2964172073191236,60.1139469393688586,66.9610303820851]},"#cc9977":{"lch":[67.2417240975963608,47.3725698769106316,39.5497292985384448],"luv":[67.2417240975963608,36.5276723895038842,30.1643751227811094],"rgb":[0.8,0.6,0.466666666666666674],"xyz":[0.396214370555768414,0.369529600468829322,0.22499100345458467],"hpluv":[39.5497292985384448,89.3979234879296598,67.2417240975963608],"hsluv":[39.5497292985384448,46.4000360859745484,67.2417240975963608]},"#cc9988":{"lch":[67.5749927230407508,39.5461637624335367,28.8927829606528306],"luv":[67.5749927230407508,34.6236706423047593,19.1076031876950658],"rgb":[0.8,0.6,0.533333333333333326],"xyz":[0.407354787657712214,0.37398576730960692,0.28366386685815681],"hpluv":[28.8927829606528306,74.2604675709266076,67.5749927230407508],"hsluv":[28.8927829606528306,33.7758353105824227,67.5749927230407508]},"#cc9999":{"lch":[67.962242737641,33.3028609095241,12.177050630062606],"luv":[67.962242737641,32.5535618700051401,7.02468179598591647],"rgb":[0.8,0.6,0.6],"xyz":[0.420411751766784914,0.379208552953236078,0.352430544499274745],"hpluv":[12.177050630062606,62.1803508213615217,67.962242737641],"hsluv":[12.177050630062606,35.0991912912463349,67.962242737641]},"#cc99aa":{"lch":[68.4044417972397838,30.9200145018949506,349.049331623372325],"luv":[68.4044417972397838,30.3569952347367966,-5.87368173427548168],"rgb":[0.8,0.6,0.66666666666666663],"xyz":[0.43546944473203747,0.3852316301393372,0.431734394116273346],"hpluv":[349.049331623372325,57.3580941092039609,68.4044417972397838],"hsluv":[349.049331623372325,36.4663034143199312,68.4044417972397838]},"#cc99bb":{"lch":[68.9021485343020856,34.1112448474386483,325.385883063702067],"luv":[68.9021485343020856,28.0734328763681233,-19.3767745401024669],"rgb":[0.8,0.6,0.733333333333333282],"xyz":[0.452607036839374144,0.392086666982271959,0.521992379214915],"hpluv":[325.385883063702067,62.8208966420876678,68.9021485343020856],"hsluv":[325.385883063702067,37.8410036888738404,68.9021485343020856]},"#cc99cc":{"lch":[69.4555411877739601,42.0770553751994854,307.715012949247],"luv":[69.4555411877739601,25.7399796927440505,-33.285613025220492],"rgb":[0.8,0.6,0.8],"xyz":[0.471899412283095843,0.39980361715976076,0.623598889885185192],"hpluv":[307.715012949247,76.8736967911951581,69.4555411877739601],"hsluv":[307.715012949247,39.1886552488513473,69.4555411877739601]},"#cc99dd":{"lch":[70.0644466506374215,52.8759829560521695,296.254085335195782],"luv":[70.0644466506374215,23.3898305690433475,-47.4213601610093534],"rgb":[0.8,0.6,0.866666666666666696],"xyz":[0.493417737833729442,0.408410947380014266,0.73692873778519119],"hpluv":[296.254085335195782,95.7635162234915498,70.0644466506374215],"hsluv":[296.254085335195782,58.3905887561973813,70.0644466506374215]},"#cc99ee":{"lch":[70.7283706212672,65.1265075826905218,288.858843135035954],"luv":[70.7283706212672,21.0513451251656711,-61.6303728557552191],"rgb":[0.8,0.6,0.933333333333333348],"xyz":[0.517229918099904151,0.417935819486484283,0.862339553853714413],"hpluv":[288.858843135035954,116.843205481858362,70.7283706212672],"hsluv":[288.858843135035954,78.6530020758075494,70.7283706212672]},"#cc99ff":{"lch":[71.4465289765693115,78.0706881495843561,283.894640570210413],"luv":[71.4465289765693115,18.7476796475605703,-75.7862576987549517],"rgb":[0.8,0.6,1],"xyz":[0.543400966509735572,0.428404238850417,1.00017374214549637],"hpluv":[283.894640570210413,138.658404713871533,71.4465289765693115],"hsluv":[283.894640570210413,99.9999999999978,71.4465289765693115]},"#990000":{"lch":[31.2857235930303546,105.214874065330946,12.1770506300617765],"luv":[31.2857235930303546,102.847587834444283,22.1933188419334826],"rgb":[0.6,0,0],"xyz":[0.131365760434599882,0.067735470224092,0.00615777002037173893],"hpluv":[12.1770506300617765,426.746789183125316,31.2857235930303546],"hsluv":[12.1770506300617765,100.000000000002217,31.2857235930303546]},"#990011":{"lch":[31.379701704172021,102.819321078199806,10.8595456684147944],"luv":[31.379701704172021,100.978030711674904,19.3713732237542438],"rgb":[0.6,0,0.0666666666666666657],"xyz":[0.132377425934237014,0.0681401364239468538,0.0114858749851273704],"hpluv":[10.8595456684147944,415.781582167217948,31.379701704172021],"hsluv":[10.8595456684147944,99.9999999999964473,31.379701704172021]},"#990022":{"lch":[31.5529326060038784,98.7447775317108807,8.37468971343924729],"luv":[31.5529326060038784,97.6918390895904309,14.3817824027706251],"rgb":[0.6,0,0.133333333333333331],"xyz":[0.134252784072714015,0.0688902796793376682,0.0213627611811065682],"hpluv":[8.37468971343924729,397.112659756655944,31.5529326060038784],"hsluv":[8.37468971343924729,99.999999999996632,31.5529326060038784]},"#990033":{"lch":[31.8354354483696653,92.9837515463916162,4.18138532137367758],"luv":[31.8354354483696653,92.7362491408617586,6.7798338419980837],"rgb":[0.6,0,0.2],"xyz":[0.137340534805171777,0.070125379972320781,0.0376249150387177114],"hpluv":[4.18138532137367758,370.62575576901952,31.8354354483696653],"hsluv":[4.18138532137367758,99.9999999999969,31.8354354483696653]},"#990044":{"lch":[32.2375108843075537,86.4821897260425771,357.977822115898675],"luv":[32.2375108843075537,86.4283323676992552,-3.05163955108307716],"rgb":[0.6,0,0.266666666666666663],"xyz":[0.141798530049390636,0.071908578070008361,0.0611036899916043499],"hpluv":[357.977822115898675,340.411718586576399,32.2375108843075537],"hsluv":[357.977822115898675,99.9999999999971294,32.2375108843075537]},"#990055":{"lch":[32.7650133258702,80.5606445545256804,349.629319937368109],"luv":[32.7650133258702,79.244583226626645,-14.502188809930411],"rgb":[0.6,0,0.333333333333333315],"xyz":[0.147760944088752622,0.0742935436857532,0.0925057372655782584],"hpluv":[349.629319937368109,311.998071704954214,32.7650133258702],"hsluv":[349.629319937368109,99.9999999999974847,32.7650133258702]},"#990066":{"lch":[33.4199981031921354,76.5714397631706589,339.419101050621862],"luv":[33.4199981031921354,71.6844038684648268,-26.9171252073414813],"rgb":[0.6,0,0.4],"xyz":[0.155345939862260807,0.0773275419951565124,0.13245338167272222],"hpluv":[339.419101050621862,290.7366076723265,33.4199981031921354],"hsluv":[339.419101050621862,99.9999999999978257,33.4199981031921354]},"#990077":{"lch":[34.2012599030024091,75.4745938555541187,328.234093427391315],"luv":[34.2012599030024091,64.1689603650959413,-39.7335984190155429],"rgb":[0.6,0,0.466666666666666674],"xyz":[0.164659952882462712,0.0810531472032373218,0.181507183579120129],"hpluv":[328.234093427391315,280.025774017920355,34.2012599030024091],"hsluv":[328.234093427391315,99.9999999999982094,34.2012599030024091]},"#990088":{"lch":[35.1048906557013396,77.5195253213057214,317.327493504651898],"luv":[35.1048906557013396,56.9954501323273419,-52.5432723595889613],"rgb":[0.6,0,0.533333333333333326],"xyz":[0.175800369984406568,0.0855093140440149196,0.240180046982692297],"hpluv":[317.327493504651898,280.209468657326,35.1048906557013396],"hsluv":[317.327493504651898,99.9999999999985505,35.1048906557013396]},"#990099":{"lch":[36.1248689761228263,82.286593786153162,307.715012949243601],"luv":[36.1248689761228263,50.3375351282041592,-65.0939019735657922],"rgb":[0.6,0,0.6],"xyz":[0.188857334093479268,0.0907320996876440772,0.308946724623810232],"hpluv":[307.715012949243601,289.042783730483336,36.1248689761228263],"hsluv":[307.715012949243601,99.9999999999988205,36.1248689761228263]},"#9900aa":{"lch":[37.2536516336468,89.0432435337247,299.813571633796073],"luv":[37.2536516336468,44.2704748017611038,-77.2581664281054685],"rgb":[0.6,0,0.66666666666666663],"xyz":[0.203915027058731824,0.0967551768737451856,0.388250574240808777],"hpluv":[299.813571633796073,303.299328566743952,37.2536516336468],"hsluv":[299.813571633796073,99.9999999999990905,37.2536516336468]},"#9900bb":{"lch":[38.4827280957899163,97.0854614833978786,293.557760104203282],"luv":[38.4827280957899163,38.802472411223853,-88.9941288300556579],"rgb":[0.6,0,0.733333333333333282],"xyz":[0.221052619166068443,0.103610213716679944,0.478508559339450579],"hpluv":[293.557760104203282,320.130957524774431,38.4827280957899163],"hsluv":[293.557760104203282,99.9999999999993179,38.4827280957899163]},"#9900cc":{"lch":[39.8031058181596933,105.884836559305498,288.673688741635],"luv":[39.8031058181596933,33.9019931565070394,-100.310784431221492],"rgb":[0.6,0,0.8],"xyz":[0.240344994609790197,0.111327163894168746,0.580115070009720735],"hpluv":[288.673688741635,337.564008898092311,39.8031058181596933],"hsluv":[288.673688741635,99.9999999999995879,39.8031058181596933]},"#9900dd":{"lch":[41.2057071388761145,115.092674624289529,284.860629917023232],"luv":[41.2057071388761145,29.5176685469448401,-111.243116621772529],"rgb":[0.6,0,0.866666666666666696],"xyz":[0.26186332016042374,0.11993449411442228,0.693444917909726732],"hpluv":[284.860629917023232,354.429316861661562,41.2057071388761145],"hsluv":[284.860629917023232,99.9999999999996732,41.2057071388761145]},"#9900ee":{"lch":[42.6816722484951754,124.494824438150232,281.862271937449748],"luv":[42.6816722484951754,25.5911328567321625,-121.836181945245357],"rgb":[0.6,0,0.933333333333333348],"xyz":[0.285675500426598505,0.129459366220892297,0.81885573397825],"hpluv":[281.862271937449748,370.125661914021862,42.6816722484951754],"hsluv":[281.862271937449748,99.9999999999998437,42.6816722484951754]},"#9900ff":{"lch":[44.2225734052255817,133.965544030308308,279.479958267333473],"luv":[44.2225734052255817,22.0644732467518,-132.136013288126151],"rgb":[0.6,0,1],"xyz":[0.311846548836429871,0.139927785584825,0.956689922270031801],"hpluv":[279.479958267333473,384.404468177447882,44.2225734052255817],"hsluv":[279.479958267333473,99.9999999999999574,44.2225734052255817]},"#bb0000":{"lch":[38.8409426943877918,130.623313921981463,12.1770506300617818],"luv":[38.8409426943877918,127.684349491075153,27.5528044852332741],"rgb":[0.733333333333333282,0,0],"xyz":[0.20493059501477473,0.105667338054495463,0.00960612164131736251],"hpluv":[12.1770506300617818,426.746789183125145,38.8409426943877918],"hsluv":[12.1770506300617818,100.000000000002217,38.8409426943877918]},"#bb0011":{"lch":[38.9108602521517142,128.680110500437479,11.3344428162225856],"luv":[38.9108602521517142,126.170422440132384,25.2902222149853806],"rgb":[0.733333333333333282,0,0.0666666666666666657],"xyz":[0.205942260514411862,0.106072004254350316,0.014934226606072994],"hpluv":[11.3344428162225856,419.642938315359174,38.9108602521517142],"hsluv":[11.3344428162225856,99.9999999999964189,38.9108602521517142]},"#bb0022":{"lch":[39.0399998564474373,125.270257566289573,9.75441483214293292],"luv":[39.0399998564474373,123.459226352671962,21.2239689767074431],"rgb":[0.733333333333333282,0,0.133333333333333331],"xyz":[0.207817618652888864,0.10682214750974113,0.0248111128020521918],"hpluv":[9.75441483214293292,407.171610230013243,39.0399998564474373],"hsluv":[9.75441483214293292,99.9999999999965326,39.0399998564474373]},"#bb0033":{"lch":[39.2513155564018916,120.169209623826248,7.10634666793171554],"luv":[39.2513155564018916,119.246098647877318,14.866300779810846],"rgb":[0.733333333333333282,0,0.2],"xyz":[0.210905369385346597,0.108057247802724243,0.041073266659663335],"hpluv":[7.10634666793171554,388.488631169232178,39.2513155564018916],"hsluv":[7.10634666793171554,99.9999999999967173,39.2513155564018916]},"#bb0044":{"lch":[39.5535843326651886,113.833969399977519,3.19865110237705785],"luv":[39.5535843326651886,113.656624965458903,6.3517077086437],"rgb":[0.733333333333333282,0,0.266666666666666663],"xyz":[0.215363364629565485,0.109840445900411823,0.0645520416125499735],"hpluv":[3.19865110237705785,365.195452768261646,39.5535843326651886],"hsluv":[3.19865110237705785,99.9999999999968878,39.5535843326651886]},"#bb0055":{"lch":[39.9527871554326666,107.03859947839959,357.869864695501747],"luv":[39.9527871554326666,106.964633924407806,-3.97855095665153691],"rgb":[0.733333333333333282,0,0.333333333333333315],"xyz":[0.221325778668927498,0.112225411516156656,0.095954088886523875],"hpluv":[357.869864695501747,339.963790558847222,39.9527871554326666],"hsluv":[357.869864695501747,99.9999999999971436,39.9527871554326666]},"#bb0066":{"lch":[40.452535568346093,100.749762000256624,351.053086521713055],"luv":[40.452535568346093,99.5239253968718884,-15.6685295004423661],"rgb":[0.733333333333333282,0,0.4],"xyz":[0.228910774442435655,0.115259409825559975,0.135901733293667837],"hpluv":[351.053086521713055,316.036764522848955,40.452535568346093],"hsluv":[351.053086521713055,99.999999999997442,40.452535568346093]},"#bb0077":{"lch":[41.0543478797665813,95.9494038996296581,342.883287985183927],"luv":[41.0543478797665813,91.699536963203,-28.2397420212797314],"rgb":[0.733333333333333282,0,0.466666666666666674],"xyz":[0.238224787462637588,0.118985015033640784,0.184955535200065746],"hpluv":[342.883287985183927,296.56674422547627,41.0543478797665813],"hsluv":[342.883287985183927,99.9999999999977,41.0543478797665813]},"#bb0088":{"lch":[41.7578935904565398,93.4210879643116243,333.788939203308246],"luv":[41.7578935904565398,83.8148890966975699,-41.2621381189091565],"rgb":[0.733333333333333282,0,0.533333333333333326],"xyz":[0.249365204564581389,0.123441181874418382,0.243628398603637913],"hpluv":[333.788939203308246,283.887103643995431,41.7578935904565398],"hsluv":[333.788939203308246,99.9999999999980531,41.7578935904565398]},"#bb0099":{"lch":[42.5612451572515,93.5592166386053918,324.452137443226093],"luv":[42.5612451572515,76.1225984195714318,-54.3937223205229472],"rgb":[0.733333333333333282,0,0.6],"xyz":[0.262422168673654088,0.12866396751804754,0.31239507624475582],"hpluv":[324.452137443226093,278.940502109978524,42.5612451572515],"hsluv":[324.452137443226093,99.9999999999983089,42.5612451572515]},"#bb00aa":{"lch":[43.461144448190268,96.3048592888224562,315.591494301740738],"luv":[43.461144448190268,68.7971872487792,-67.3911934105362747],"rgb":[0.733333333333333282,0,0.66666666666666663],"xyz":[0.277479861638906644,0.134687044704148634,0.391698925861754421],"hpluv":[315.591494301740738,281.181257774391042,43.461144448190268],"hsluv":[315.591494301740738,99.9999999999985647,43.461144448190268]},"#bb00bb":{"lch":[44.4532771259814652,101.257357078489918,307.715012949243601],"luv":[44.4532771259814652,61.9426024872754866,-80.100976021670192],"rgb":[0.733333333333333282,0,0.733333333333333282],"xyz":[0.294617453746243319,0.141542081547083393,0.481956910960396168],"hpluv":[307.715012949243601,289.042783730483507,44.4532771259814652],"hsluv":[307.715012949243601,99.9999999999988205,44.4532771259814652]},"#bb00cc":{"lch":[45.5325428123826796,107.876917991024385,301.028560594476971],"luv":[45.5325428123826796,55.6068066637028551,-92.44085940701639],"rgb":[0.733333333333333282,0,0.8],"xyz":[0.313909829189965,0.149259031724572194,0.583563421630666324],"hpluv":[301.028560594476971,300.639438898355309,45.5325428123826796],"hsluv":[301.028560594476971,99.999999999999,45.5325428123826796]},"#bb00dd":{"lch":[46.6933085129957348,115.650155059812704,295.504945579136574],"luv":[46.6933085129957348,49.7976850024997,-104.379830109799173],"rgb":[0.733333333333333282,0,0.866666666666666696],"xyz":[0.335428154740598616,0.157866361944825728,0.696893269530672321],"hpluv":[295.504945579136574,314.290242754568055,46.6933085129957348],"hsluv":[295.504945579136574,99.9999999999992468,46.6933085129957348]},"#bb00ee":{"lch":[47.929635203682146,124.167261181765113,290.999747870951808],"luv":[47.929635203682146,44.4970566855085821,-115.920320460682433],"rgb":[0.733333333333333282,0,0.933333333333333348],"xyz":[0.359240335006773326,0.167391234051295773,0.822304085599195544],"hpluv":[290.999747870951808,328.732244305823656,47.929635203682146],"hsluv":[290.999747870951808,99.9999999999993889,47.929635203682146]},"#bb00ff":{"lch":[49.2354711183318727,133.13261796854033,287.33664116340708],"luv":[49.2354711183318727,39.6715752597668896,-127.084460433075606],"rgb":[0.733333333333333282,0,1],"xyz":[0.385411383416604747,0.177859653415228469,0.96013827389097739],"hpluv":[287.33664116340708,343.119737385630629,49.2354711183318727],"hsluv":[287.33664116340708,99.9999999999995595,49.2354711183318727]},"#991100":{"lch":[32.2007428060931531,101.551746681272988,13.5001929330929755],"luv":[32.2007428060931531,98.7457840078795,23.707116962774041],"rgb":[0.6,0.0666666666666666657,0],"xyz":[0.133370160695528289,0.071744270745948871,0.00682590344068119],"hpluv":[13.5001929330929755,400.185025755779861,32.2007428060931531],"hsluv":[13.5001929330929755,100.000000000002359,32.2007428060931531]},"#991111":{"lch":[32.2911967351305,99.2607003603350506,12.1770506300617907],"luv":[32.2911967351305,97.0273802968116854,20.9373854328113431],"rgb":[0.6,0.0666666666666666657,0.0666666666666666657],"xyz":[0.134381826195165421,0.0721489369458037239,0.0121540084054368204],"hpluv":[12.1770506300617907,390.060992150638072,32.2911967351305],"hsluv":[12.1770506300617907,91.4033806551417,32.2911967351305]},"#991122":{"lch":[32.4579836187547883,95.3555453821432337,9.67722696349737355],"luv":[32.4579836187547883,93.9986702773161085,16.0290368151797],"rgb":[0.6,0.0666666666666666657,0.133333333333333331],"xyz":[0.136257184333642423,0.0728990802011945382,0.0220308946014160165],"hpluv":[9.67722696349737355,372.789562407290305,32.4579836187547883],"hsluv":[9.67722696349737355,91.6870397393079,32.4579836187547883]},"#991133":{"lch":[32.7301206059751877,89.8170234432985382,5.44607482402752385],"luv":[32.7301206059751877,89.4115862394302,8.52443231910342547],"rgb":[0.6,0.0666666666666666657,0.2],"xyz":[0.139344935066100184,0.0741341804941776511,0.0382930484590271597],"hpluv":[5.44607482402752385,348.217328437078379,32.7301206059751877],"hsluv":[5.44607482402752385,92.1153976677825312,32.7301206059751877]},"#991144":{"lch":[33.1177416447746893,83.547386161100178,359.159050762907725],"luv":[33.1177416447746893,83.5383872622118275,-1.22620878349376072],"rgb":[0.6,0.0666666666666666657,0.266666666666666663],"xyz":[0.143802930310319044,0.0759173785918652311,0.0617718234119138],"hpluv":[359.159050762907725,320.119020896680809,33.1177416447746893],"hsluv":[359.159050762907725,92.6613616101701609,33.1177416447746893]},"#991155":{"lch":[33.6267967661613341,77.8365467514172451,350.652860745276428],"luv":[33.6267967661613341,76.8030661853154,-12.6418762341523276],"rgb":[0.6,0.0666666666666666657,0.333333333333333315],"xyz":[0.149765344349681029,0.078302344207610064,0.0931738706858877136],"hpluv":[350.652860745276428,293.722615948770908,33.6267967661613341],"hsluv":[350.652860745276428,93.2833986807069664,33.6267967661613341]},"#991166":{"lch":[34.2596587707945375,74.039902428482776,340.197584074025258],"luv":[34.2596587707945375,69.661662743272629,-25.0830599301957804],"rgb":[0.6,0.0666666666666666657,0.4],"xyz":[0.157350340123189214,0.0813363425170133825,0.133121515093031662],"hpluv":[340.197584074025258,274.234525914752396,34.2596587707945375],"hsluv":[340.197584074025258,93.9371476037906774,34.2596587707945375]},"#991177":{"lch":[35.0156115165229096,73.1458980715855773,328.71391057162549],"luv":[35.0156115165229096,62.509382661628635,-37.9855167657472848],"rgb":[0.6,0.0666666666666666657,0.466666666666666674],"xyz":[0.16666435314339112,0.0850619477250941919,0.182175316999429571],"hpluv":[328.71391057162549,265.074278305330154,35.0156115165229096],"hsluv":[328.71391057162549,94.5844210689808165,35.0156115165229096]},"#991188":{"lch":[35.8913494409224185,75.4242755669397269,317.528981112118743],"luv":[35.8913494409224185,55.6343762077295239,-50.9277677576239398],"rgb":[0.6,0.0666666666666666657,0.533333333333333326],"xyz":[0.177804770245334975,0.0895181145658717897,0.240848180403001738],"hpluv":[317.528981112118743,266.661726649655066,35.8913494409224185],"hsluv":[317.528981112118743,95.1976582537924116,35.8913494409224185]},"#991199":{"lch":[36.8815072257793,80.448343562419069,307.715012949243601],"luv":[36.8815072257793,49.2130143411107568,-63.6397297401445599],"rgb":[0.6,0.0666666666666666657,0.6],"xyz":[0.190861734354407675,0.0947409002095009473,0.309614858044119645],"hpluv":[307.715012949243601,276.788327826692239,36.8815072257793],"hsluv":[307.715012949243601,95.7603314825458511,36.8815072257793]},"#9911aa":{"lch":[37.9791974354050694,87.4639739592788,299.695850237394552],"luv":[37.9791974354050694,43.3292813921454609,-75.9771025690614152],"rgb":[0.6,0.0666666666666666657,0.66666666666666663],"xyz":[0.205919427319660231,0.100763977395602056,0.388918707661118246],"hpluv":[299.695850237394552,292.228621346341356,37.9791974354050694],"hsluv":[299.695850237394552,96.26500390067784,37.9791974354050694]},"#9911bb":{"lch":[39.176522525078866,95.7489617369993624,293.383950362709356],"luv":[39.176522525078866,38.0018814997404846,-87.8847010360338459],"rgb":[0.6,0.0666666666666666657,0.733333333333333282],"xyz":[0.22305701942699685,0.107619014238536814,0.47917669275976],"hpluv":[293.383950362709356,310.132668732371314,39.176522525078866],"hsluv":[293.383950362709356,96.7106400677762537,39.176522525078866]},"#9911cc":{"lch":[40.465031277763515,104.765415075180798,288.480743990765689],"luv":[40.465031277763515,33.2091620218187842,-99.3626879350770622],"rgb":[0.6,0.0666666666666666657,0.8],"xyz":[0.242349394870718604,0.115335964416025616,0.580783203430030204],"hpluv":[288.480743990765689,328.531778006508034,40.465031277763515],"hsluv":[288.480743990765689,97.1001366995766,40.465031277763515]},"#9911dd":{"lch":[41.8361001822542917,114.161763941518927,284.668123617886636],"luv":[41.8361001822542917,28.9080153835727351,-110.441092863219225],"rgb":[0.6,0.0666666666666666657,0.866666666666666696],"xyz":[0.263867720421352148,0.12394329463627915,0.694113051330036201],"hpluv":[284.668123617886636,346.265164959266087,41.8361001822542917],"hsluv":[284.668123617886636,97.4384492036098,41.8361001822542917]},"#9911ee":{"lch":[43.2812320372341617,123.724619665436521,281.679545129349094],"luv":[43.2812320372341617,25.0465268392882301,-121.162919264293635],"rgb":[0.6,0.0666666666666666657,0.933333333333333348],"xyz":[0.287679900687526913,0.133468166742749167,0.819523867398559425],"hpluv":[281.679545129349094,362.740326129136179,43.2812320372341617],"hsluv":[281.679545129349094,97.7313369542794561,43.2812320372341617]},"#9911ff":{"lch":[44.7922739406791948,133.33068560825987,279.310828677429186],"luv":[44.7922739406791948,21.5716156333953251,-131.574074664174219],"rgb":[0.6,0.0666666666666666657,1],"xyz":[0.313850949097358278,0.143936586106681863,0.95735805569034127],"hpluv":[279.310828677429186,377.716823123197173,44.7922739406791948],"hsluv":[279.310828677429186,99.9999999999993179,44.7922739406791948]},"#bb1100":{"lch":[39.5258701457598747,127.514079962112703,13.0219609303782402],"luv":[39.5258701457598747,124.2348987579322,28.7320469022032583],"rgb":[0.733333333333333282,0.0666666666666666657,0],"xyz":[0.206934995275703137,0.109676138576352333,0.0102742550616268143],"hpluv":[13.0219609303782402,409.370014873310311,39.5258701457598747],"hsluv":[13.0219609303782402,100.000000000002203,39.5258701457598747]},"#bb1111":{"lch":[39.5940766091873897,125.63034182067031,12.177050630061796],"luv":[39.5940766091873897,122.803716963532779,26.4996204863200759],"rgb":[0.733333333333333282,0.0666666666666666657,0.0666666666666666657],"xyz":[0.20794666077534027,0.110080804776207186,0.0156023600263824457],"hpluv":[12.177050630061796,402.627698793753552,39.5940766091873897],"hsluv":[12.177050630061796,94.3481495348726753,39.5940766091873897]},"#bb1122":{"lch":[39.7200723855077413,122.321798686612851,10.5915831721034426],"luv":[39.7200723855077413,120.23772406897838,22.4835972353282152],"rgb":[0.733333333333333282,0.0666666666666666657,0.133333333333333331],"xyz":[0.209822018913817271,0.110830948031598,0.0254792462223616401],"hpluv":[10.5915831721034426,390.780742551338619,39.7200723855077413],"hsluv":[10.5915831721034426,94.4721603032542561,39.7200723855077413]},"#bb1133":{"lch":[39.9262897734852,117.365304386249704,7.93115519261489421],"luv":[39.9262897734852,116.242655940639409,16.194431559742192],"rgb":[0.733333333333333282,0.0666666666666666657,0.2],"xyz":[0.212909769646275,0.112066048324581113,0.0417414000799727902],"hpluv":[7.93115519261489421,373.009679290071517,39.9262897734852],"hsluv":[7.93115519261489421,94.6648992051481173,39.9262897734852]},"#bb1144":{"lch":[40.2213637516280755,111.198866264944101,3.99799547396429888],"luv":[40.2213637516280755,110.928262725239179,7.75295991020434627],"rgb":[0.733333333333333282,0.0666666666666666657,0.266666666666666663],"xyz":[0.217367764890493892,0.113849246422268693,0.0652201750328594287],"hpluv":[3.99799547396429888,350.818828640487084,40.2213637516280755],"hsluv":[3.99799547396429888,94.920595316052,40.2213637516280755]},"#bb1155":{"lch":[40.6112374139617245,104.574630781207446,358.621384873601698],"luv":[40.6112374139617245,104.544360517453882,-2.51596641918957786],"rgb":[0.733333333333333282,0.0666666666666666657,0.333333333333333315],"xyz":[0.223330178929855905,0.116234212038013526,0.0966222223068333302],"hpluv":[358.621384873601698,326.752894857139097,40.6112374139617245],"hsluv":[358.621384873601698,95.2265760165129791,40.6112374139617245]},"#bb1166":{"lch":[41.0995768863194755,98.4443929415329251,351.723860164231496],"luv":[41.0995768863194755,97.4191751888273672,-14.1704907168206535],"rgb":[0.733333333333333282,0.0666666666666666657,0.4],"xyz":[0.230915174703364062,0.119268210347416845,0.136569866713977306],"hpluv":[351.723860164231496,303.943570446579713,41.0995768863194755],"hsluv":[351.723860164231496,95.5663396203906643,41.0995768863194755]},"#bb1177":{"lch":[41.688035181331955,93.7889310063258,343.43446060875408],"luv":[41.688035181331955,89.8961490854954093,-26.7403432832812094],"rgb":[0.733333333333333282,0.0666666666666666657,0.466666666666666674],"xyz":[0.240229187723566,0.122993815555497654,0.185623668620375215],"hpluv":[343.43446060875408,285.48249634694713,41.688035181331955],"hsluv":[343.43446060875408,95.9227087501184883,41.688035181331955]},"#bb1188":{"lch":[42.3764815581906475,91.4027083669889606,334.189166164708297],"luv":[42.3764815581906475,82.2840505377722309,-39.7968607294366805],"rgb":[0.733333333333333282,0.0666666666666666657,0.533333333333333326],"xyz":[0.251369604825509796,0.127449982396275252,0.244296532023947383],"hpluv":[334.189166164708297,273.699179760613617,42.3764815581906475],"hsluv":[334.189166164708297,96.2803174994205,42.3764815581906475]},"#bb1199":{"lch":[43.1632358766101092,91.692942572352564,324.693570122963422],"luv":[43.1632358766101092,74.8281105443768269,-52.9938637007650755],"rgb":[0.733333333333333282,0.0666666666666666657,0.6],"xyz":[0.264426568934582495,0.13267276803990441,0.31306320966506529],"hpluv":[324.693570122963422,269.563595898888195,43.1632358766101092],"hsluv":[324.693570122963422,96.6270445785018239,43.1632358766101092]},"#bb11aa":{"lch":[44.0453166933651,94.6050581990027553,315.694091730478135],"luv":[44.0453166933651,67.7013389352867847,-66.0806003544619784],"rgb":[0.733333333333333282,0.0666666666666666657,0.66666666666666663],"xyz":[0.279484261899835051,0.138695845226005504,0.39236705928206389],"hpluv":[315.694091730478135,272.554870225691275,44.0453166933651],"hsluv":[315.694091730478135,96.9544350138240105,44.0453166933651]},"#bb11bb":{"lch":[45.0186979872658242,99.7328976909900717,307.715012949243601],"luv":[45.0186979872658242,61.0100383302365472,-78.8950321933172205],"rgb":[0.733333333333333282,0.0666666666666666657,0.733333333333333282],"xyz":[0.296621854007171726,0.145550882068940263,0.482625044380705637],"hpluv":[307.715012949243601,281.115526817766181,45.0186979872658242],"hsluv":[307.715012949243601,97.2574105430315115,45.0186979872658242]},"#bb11cc":{"lch":[46.0785638011469771,106.527215460047387,300.962972083371881],"luv":[46.0785638011469771,54.8065495444917161,-91.3470840295328372],"rgb":[0.733333333333333282,0.0666666666666666657,0.8],"xyz":[0.315914229450893425,0.153267832246429064,0.584231555050975793],"hpluv":[300.962972083371881,293.360047474541318,46.0785638011469771],"hsluv":[300.962972083371881,97.5336183018287528,46.0785638011469771]},"#bb11dd":{"lch":[47.2195492447565,114.4666153484132,295.402801066287566],"luv":[47.2195492447565,49.1038079522977853,-103.3993330438134],"rgb":[0.733333333333333282,0.0666666666666666657,0.866666666666666696],"xyz":[0.337432555001527,0.161875162466682598,0.69756140295098179],"hpluv":[295.402801066287566,307.607082675331128,47.2195492447565],"hsluv":[295.402801066287566,97.7826899351839813,47.2195492447565]},"#bb11ee":{"lch":[48.4359581768354701,123.136484869400022,290.880608651701721],"luv":[48.4359581768354701,43.8885280811888,-115.049515465553711],"rgb":[0.733333333333333282,0.0666666666666666657,0.933333333333333348],"xyz":[0.361244735267701733,0.171400034573152643,0.822972219019505],"hpluv":[290.880608651701721,322.595409245987128,48.4359581768354701],"hsluv":[290.880608651701721,98.0055710342431325,48.4359581768354701]},"#bb11ff":{"lch":[49.7219510368964,132.239138283310353,287.21247838519713],"luv":[49.7219510368964,39.1316890181496575,-126.316667975763593],"rgb":[0.733333333333333282,0.0666666666666666657,1],"xyz":[0.387415783677533154,0.181868453937085339,0.960806407311286859],"hpluv":[287.21247838519713,337.482436204013879,49.7219510368964],"hsluv":[287.21247838519713,99.9999999999991758,49.7219510368964]},"#992200":{"lch":[33.8105832897308716,95.4307991554818358,16.0266852535062476],"luv":[33.8105832897308716,91.7217107848809263,26.3470149760569932],"rgb":[0.6,0.133333333333333331,0],"xyz":[0.137085784430296231,0.0791755182154848525,0.0080644446856038],"hpluv":[16.0266852535062476,358.158468302090569,33.8105832897308716],"hsluv":[16.0266852535062476,100.000000000002331,33.8105832897308716]},"#992211":{"lch":[33.8952997814050718,93.2922690289088195,14.6972380002076104],"luv":[33.8952997814050718,90.239744522062125,23.669304365681274],"rgb":[0.6,0.133333333333333331,0.0666666666666666657],"xyz":[0.138097449929933364,0.0795801844153397,0.0133925496503594314],"hpluv":[14.6972380002076104,349.257308780581,33.8952997814050718],"hsluv":[14.6972380002076104,92.1483909924374274,33.8952997814050718]},"#992222":{"lch":[34.0515850466810335,89.6330213591727,12.1770506300618084],"luv":[34.0515850466810335,87.6163196410811338,18.9065874902323579],"rgb":[0.6,0.133333333333333331,0.133333333333333331],"xyz":[0.139972808068410365,0.0803303276707305197,0.0232694358463386292],"hpluv":[12.1770506300618084,334.018122077437397,34.0515850466810335],"hsluv":[12.1770506300618084,78.2707991117683,34.0515850466810335]},"#992233":{"lch":[34.3068003204445446,84.4135643942939282,7.88651435003668233],"luv":[34.3068003204445446,83.6151628365757773,11.58250394183076],"rgb":[0.6,0.133333333333333331,0.2],"xyz":[0.143060558800868098,0.0815654279637136326,0.0395315897039497724],"hpluv":[7.88651435003668233,312.227643050581207,34.3068003204445446],"hsluv":[7.88651435003668233,79.3008398259009226,34.3068003204445446]},"#992244":{"lch":[34.6707661525426,78.4682482149262199,1.45557545410962708],"luv":[34.6707661525426,78.4429281517087134,1.99323879782018309],"rgb":[0.6,0.133333333333333331,0.266666666666666663],"xyz":[0.147518554045086986,0.0833486260614012126,0.0630103646568364],"hpluv":[1.45557545410962708,287.190351340663,34.6707661525426],"hsluv":[1.45557545410962708,80.6267396657693212,34.6707661525426]},"#992255":{"lch":[35.149531709850983,73.0418005898087443,352.659616011821072],"luv":[35.149531709850983,72.4431965063170082,-9.33209051330535821],"rgb":[0.6,0.133333333333333331,0.333333333333333315],"xyz":[0.153480968084449,0.0857335916771460455,0.0944124119308103193],"hpluv":[352.659616011821072,263.688538908073838,35.149531709850983],"hsluv":[352.659616011821072,82.1555178352066804,35.149531709850983]},"#992266":{"lch":[35.7459223236079495,69.5043059181480203,341.734006615383123],"luv":[35.7459223236079495,66.0021002604389793,-21.7846574995905513],"rgb":[0.6,0.133333333333333331,0.4],"xyz":[0.161065963857957156,0.0887675899865493639,0.134360056337954281],"hpluv":[341.734006615383123,246.731460763727796,35.7459223236079495],"hsluv":[341.734006615383123,83.7834402291280753,35.7459223236079495]},"#992277":{"lch":[36.4599553630224946,68.9051746310403104,329.662355423262511],"luv":[36.4599553630224946,59.4695672743266783,-34.8036443370302],"rgb":[0.6,0.133333333333333331,0.466666666666666674],"xyz":[0.17037997687815909,0.0924931951946301734,0.18341385824435219],"hpluv":[329.662355423262511,239.814275331209444,36.4599553630224946],"hsluv":[329.662355423262511,85.4170781092293225,36.4599553630224946]},"#992288":{"lch":[37.2892540647929,71.5563678213307242,317.925484235555643],"luv":[37.2892540647929,53.1144286836587369,-47.9496740488411],"rgb":[0.6,0.133333333333333331,0.533333333333333326],"xyz":[0.18152039398010289,0.0969493620354077712,0.242086721647924358],"hpluv":[317.925484235555643,243.502777039008038,37.2892540647929],"hsluv":[317.925484235555643,86.9852623869732,37.2892540647929]},"#992299":{"lch":[38.2294870734457888,77.015786119064046,307.715012949243771],"luv":[38.2294870734457888,47.1132010795059841,-60.9243596238766827],"rgb":[0.6,0.133333333333333331,0.6],"xyz":[0.194577358089175617,0.102172147679036929,0.310853399289042265],"hpluv":[307.715012949243771,255.635172818446421,38.2294870734457888],"hsluv":[307.715012949243771,88.441984096309227,38.2294870734457888]},"#9922aa":{"lch":[39.2748221448681178,84.484081905089468,299.468150353755561],"luv":[39.2748221448681178,41.5610713460956234,-73.5543162833468],"rgb":[0.6,0.133333333333333331,0.66666666666666663],"xyz":[0.209635051054428145,0.108195224865138023,0.390157248906040865],"hpluv":[299.468150353755561,272.960615272696657,39.2748221448681178],"hsluv":[299.468150353755561,89.7633288768494708,39.2748221448681178]},"#9922bb":{"lch":[40.4183688993281436,93.2013493596814726,293.05045530637],"luv":[40.4183688993281436,36.4922039393154094,-85.7601922462677919],"rgb":[0.6,0.133333333333333331,0.733333333333333282],"xyz":[0.22677264316176482,0.115050261708072782,0.480415234004682612],"hpluv":[293.05045530637,292.605673863240838,40.4183688993281436],"hsluv":[293.05045530637,90.9419133161227222,40.4183688993281436]},"#9922cc":{"lch":[41.6525852773545182,102.609691310931794,288.11294916137831],"luv":[41.6525852773545182,31.900454524651952,-97.5249186210648702],"rgb":[0.6,0.133333333333333331,0.8],"xyz":[0.246065018605486546,0.122767211885561583,0.582021744674952712],"hpluv":[288.11294916137831,312.597676326075884,41.6525852773545182],"hsluv":[288.11294916137831,91.9812251551093851,41.6525852773545182]},"#9922dd":{"lch":[42.969628845807982,112.350489371469905,284.303043907998301],"luv":[42.969628845807982,27.7562437333976213,-108.867917201630149],"rgb":[0.6,0.133333333333333331,0.866666666666666696],"xyz":[0.267583344156120062,0.131374542105815117,0.69535159257495871],"hpluv":[284.303043907998301,331.781902020401162,42.969628845807982],"hsluv":[284.303043907998301,92.8910125551507235,42.969628845807982]},"#9922ee":{"lch":[44.361642902098545,122.210344632057584,281.334390799049743],"luv":[44.361642902098545,24.018574136526297,-119.826860225637532],"rgb":[0.6,0.133333333333333331,0.933333333333333348],"xyz":[0.291395524422294827,0.140899414212285162,0.820762408643481933],"hpluv":[281.334390799049743,349.574442537581717,44.361642902098545],"hsluv":[281.334390799049743,93.6839973987951566,44.361642902098545]},"#9922ff":{"lch":[45.8209755847726612,132.069283427413211,278.992348895848238],"luv":[45.8209755847726612,20.6427685166220094,-130.446049127597433],"rgb":[0.6,0.133333333333333331,1],"xyz":[0.317566572832126193,0.151367833576217858,0.958596596935263889],"hpluv":[278.992348895848238,365.74366826955071,45.8209755847726612],"hsluv":[278.992348895848238,99.9999999999993179,45.8209755847726612]},"#bb2200":{"lch":[40.7526421249889452,122.145166616692975,14.6188079362681389],"luv":[40.7526421249889452,118.190884669319914,30.8278528104570881],"rgb":[0.733333333333333282,0.133333333333333331,0],"xyz":[0.21065061901047108,0.117107386045888315,0.0115127963065494235],"hpluv":[14.6188079362681389,380.329350781024857,40.7526421249889452],"hsluv":[14.6188079362681389,100.000000000002217,40.7526421249889452]},"#bb2211":{"lch":[40.8179368215716849,120.355879944515436,13.7706881972771793],"luv":[40.8179368215716849,116.896392622501153,28.6491052053056343],"rgb":[0.733333333333333282,0.133333333333333331,0.0666666666666666657],"xyz":[0.211662284510108212,0.117512052245743168,0.0168409012713050532],"hpluv":[13.7706881972771793,374.158477594779924,40.8179368215716849],"hsluv":[13.7706881972771793,94.6800257514418,40.8179368215716849]},"#bb2222":{"lch":[40.9385803904414161,117.208042434762348,12.1770506300618102],"luv":[40.9385803904414161,114.570915436608942,24.7230772236478238],"rgb":[0.733333333333333282,0.133333333333333331,0.133333333333333331],"xyz":[0.213537642648585213,0.118262195501133982,0.0267177874672842527],"hpluv":[12.1770506300618102,363.298797482753,40.9385803904414161],"hsluv":[12.1770506300618102,85.1321689328196101,40.9385803904414161]},"#bb2233":{"lch":[41.136111673530813,112.480172956632245,9.49666640172232235],"luv":[41.136111673530813,110.938654987290519,18.5581286223806821],"rgb":[0.733333333333333282,0.133333333333333331,0.2],"xyz":[0.216625393381042974,0.119497295794117095,0.042979941324895396],"hpluv":[9.49666640172232235,346.970109935861444,41.136111673530813],"hsluv":[9.49666640172232235,85.6217357677037398,41.136111673530813]},"#bb2244":{"lch":[41.4189140922405201,106.57909239531196,5.51995404221549],"luv":[41.4189140922405201,106.084859394728952,10.2520994439692306],"rgb":[0.733333333333333282,0.133333333333333331,0.266666666666666663],"xyz":[0.221083388625261834,0.121280493891804675,0.0664587162777820345],"hpluv":[5.51995404221549,326.522141050690152,41.4189140922405201],"hsluv":[5.51995404221549,86.2742612371986297,41.4189140922405201]},"#bb2255":{"lch":[41.7928521194743823,100.22104851316422,0.0579838467833058424],"luv":[41.7928521194743823,100.220997191859041,0.101424589714973798],"rgb":[0.733333333333333282,0.133333333333333331,0.333333333333333315],"xyz":[0.227045802664623819,0.123665459507549508,0.097860763551755936],"hpluv":[0.0579838467833058424,304.296010337655673,41.7928521194743823],"hsluv":[0.0579838467833058424,87.0597094656736772,41.7928521194743823]},"#bb2266":{"lch":[42.2616671880265216,94.3342448936905,353.011685321171171],"luv":[42.2616671880265216,93.6334344607092106,-11.4773564358193614],"rgb":[0.733333333333333282,0.133333333333333331,0.4],"xyz":[0.234630798438132,0.126699457816952826,0.137808407958899898],"hpluv":[353.011685321171171,283.244886623536,42.2616671880265216],"hsluv":[353.011685321171171,87.937804292381287,42.2616671880265216]},"#bb2277":{"lch":[42.8272221099346666,89.9002723684957,344.496654306277264],"luv":[42.8272221099346666,86.6292371691086771,-24.0298614109202155],"rgb":[0.733333333333333282,0.133333333333333331,0.466666666666666674],"xyz":[0.24394481145833391,0.13042506302503365,0.186862209865297807],"hpluv":[344.496654306277264,266.367005402095344,42.8272221099346666],"hsluv":[344.496654306277264,88.8655868844719805,42.8272221099346666]},"#bb2288":{"lch":[43.4897067779173554,87.7363054907772693,334.961981200390596],"luv":[43.4897067779173554,79.4914755013727898,-37.1317199141871441],"rgb":[0.733333333333333282,0.133333333333333331,0.533333333333333326],"xyz":[0.255085228560277766,0.13488122986581122,0.245535073268869974],"hpluv":[334.961981200390596,255.995416581420926,43.4897067779173554],"hsluv":[334.961981200390596,89.8036443318747786,43.4897067779173554]},"#bb2299":{"lch":[44.2478449340908639,88.2751432264235092,325.159464012784042],"luv":[44.2478449340908639,72.4514028672968635,-50.4310929309115],"rgb":[0.733333333333333282,0.133333333333333331,0.6],"xyz":[0.268142192669350465,0.140104015509440405,0.314301750909987909],"hpluv":[325.159464012784042,253.154489640486645,44.2478449340908639],"hsluv":[325.159464012784042,90.7199745934293844,44.2478449340908639]},"#bb22aa":{"lch":[45.0991127685299062,91.4705260319517919,315.891475419905078],"luv":[45.0991127685299062,65.6779186933914758,-63.6652819727222195],"rgb":[0.733333333333333282,0.133333333333333331,0.66666666666666663],"xyz":[0.283199885634603,0.146127092695541499,0.39360560052698651],"hpluv":[315.891475419905078,257.366789521381691,45.0991127685299062],"hsluv":[315.891475419905078,91.5914304646717,45.0991127685299062]},"#bb22bb":{"lch":[46.0399667792549678,96.9048462314552,307.715012949243658],"luv":[46.0399667792549678,59.2800221375787615,-76.6578645574617497],"rgb":[0.733333333333333282,0.133333333333333331,0.733333333333333282],"xyz":[0.30033747774193964,0.152982129538476258,0.483863585625628256],"hpluv":[307.715012949243658,267.0851991180906,46.0399667792549678],"hsluv":[307.715012949243658,92.4033444706684,46.0399667792549678]},"#bb22cc":{"lch":[47.066072507765945,104.009692587178989,300.837938637053412],"luv":[47.066072507765945,53.3165662395356,-89.3048706202785496],"rgb":[0.733333333333333282,0.133333333333333331,0.8],"xyz":[0.319629853185661394,0.16069907971596506,0.585470096295898412],"hpluv":[300.837938637053412,280.417543020287,47.066072507765945],"hsluv":[300.837938637053412,93.1481326309998,47.066072507765945]},"#bb22dd":{"lch":[48.1725242595717589,112.247547842848149,295.20893392435471],"luv":[48.1725242595717589,47.808517424121824,-101.557164486017044],"rgb":[0.733333333333333282,0.133333333333333331,0.866666666666666696],"xyz":[0.341148178736294938,0.169306409936218594,0.69879994419590441],"hpluv":[295.20893392435471,295.676483579310798,48.1725242595717589],"hsluv":[295.20893392435471,93.8235497257627316,48.1725242595717589]},"#bb22ee":{"lch":[49.3540469689012724,121.194036197623419,290.655339197387],"luv":[49.3540469689012724,42.7506603945962169,-113.403595382583688],"rgb":[0.733333333333333282,0.133333333333333331,0.933333333333333348],"xyz":[0.364960359002469703,0.178831282042688611,0.824210760264427633],"hpluv":[290.655339197387,311.600255956968681,49.3540469689012724],"hsluv":[290.655339197387,94.4310255689598,49.3540469689012724]},"#bb22ff":{"lch":[50.6051737457033397,130.547024148317973,286.97844412333734],"luv":[50.6051737457033397,38.1212848334983647,-124.85709093449519],"rgb":[0.733333333333333282,0.133333333333333331,1],"xyz":[0.391131407412301069,0.189299701406621335,0.962044948556209478],"hpluv":[286.97844412333734,327.349274436557835,50.6051737457033397],"hsluv":[286.97844412333734,99.9999999999991616,50.6051737457033397]},"#993300":{"lch":[36.2545465004255476,86.9834057059747749,20.3835344027483316],"luv":[36.2545465004255476,81.5366895093473,30.2965531383769893],"rgb":[0.6,0.2,0],"xyz":[0.14320350651930705,0.0914109623935066423,0.0101036853819406816],"hpluv":[20.3835344027483316,304.448092478673459,36.2545465004255476],"hsluv":[20.3835344027483316,100.00000000000226,36.2545465004255476]},"#993311":{"lch":[36.3315413581227133,85.0112276295678839,19.0571063974297203],"luv":[36.3315413581227133,80.3520694714869279,27.7570487396543],"rgb":[0.6,0.2,0.0666666666666666657],"xyz":[0.144215172018944182,0.0918156285933615,0.0154317903466963131],"hpluv":[19.0571063974297203,296.914762557758195,36.3315413581227133],"hsluv":[19.0571063974297203,93.1288353931581,36.3315413581227133]},"#993322":{"lch":[36.4736730302835852,81.6150828115545863,16.5278497598068661],"luv":[36.4736730302835852,78.2428757472059573,23.217970134019108],"rgb":[0.6,0.2,0.133333333333333331],"xyz":[0.146090530157421183,0.0925657718487523096,0.0253086765426755109],"hpluv":[16.5278497598068661,283.942401799749632,36.4736730302835852],"hsluv":[16.5278497598068661,80.9121244795507124,36.4736730302835852]},"#993333":{"lch":[36.7060271438600836,76.7221326388105638,12.1770506300618369],"luv":[36.7060271438600836,74.9959199734098121,16.1832513417159589],"rgb":[0.6,0.2,0.2],"xyz":[0.149178280889878945,0.0938008721417354224,0.0415708304002866541],"hpluv":[12.1770506300618369,265.229979343802,36.7060271438600836],"hsluv":[12.1770506300618369,62.1516051360361459,36.7060271438600836]},"#993344":{"lch":[37.0379214664673668,71.077614272095758,5.55118145677439934],"luv":[37.0379214664673668,70.7442733159460744,6.87568495580995354],"rgb":[0.6,0.2,0.266666666666666663],"xyz":[0.153636276134097804,0.095584070239423,0.0650496053531732926],"hpluv":[5.55118145677439934,243.514912685509444,37.0379214664673668],"hsluv":[5.55118145677439934,64.3097526797848644,37.0379214664673668]},"#993355":{"lch":[37.4754277574064858,65.8722356173568073,356.298722520573506],"luv":[37.4754277574064858,65.7348379379961614,-4.25235305377523254],"rgb":[0.6,0.2,0.333333333333333315],"xyz":[0.15959869017345979,0.0979690358551678353,0.0964516526271472],"hpluv":[356.298722520573506,223.046355214908289,37.4754277574064858],"hsluv":[356.298722520573506,66.8387430740197885,37.4754277574064858]},"#993366":{"lch":[38.0218512407041942,62.5198646461221941,344.559385799457459],"luv":[38.0218512407041942,60.2633303059628602,-16.6452544529622166],"rgb":[0.6,0.2,0.4],"xyz":[0.167183685946967975,0.101003034164571154,0.136399297034291156],"hpluv":[344.559385799457459,208.652742449272864,38.0218512407041942],"hsluv":[344.559385799457459,69.5808124884664778,38.0218512407041942]},"#993377":{"lch":[38.6780657603296234,62.1964572713534949,331.414072321130675],"luv":[38.6780657603296234,54.6147414507713478,-29.7595247504508862],"rgb":[0.6,0.2,0.466666666666666674],"xyz":[0.17649769896716988,0.104728639372651963,0.185453098940689065],"hpluv":[331.414072321130675,204.051704505442274,38.6780657603296234],"hsluv":[331.414072321130675,72.3848063102254571,38.6780657603296234]},"#993388":{"lch":[39.4428302118465908,65.3028355433768155,318.6521895607018],"luv":[39.4428302118465908,49.0236963230770257,-43.1409031990296086],"rgb":[0.6,0.2,0.533333333333333326],"xyz":[0.187638116069113736,0.109184806213429561,0.244125962344261233],"hpluv":[318.6521895607018,210.08899125401652,39.4428302118465908],"hsluv":[318.6521895607018,75.1271370389489306,39.4428302118465908]},"#993399":{"lch":[40.3131218316236897,71.3679900272828149,307.715012949243942],"luv":[40.3131218316236897,43.6582502656979656,-56.4565955781255226],"rgb":[0.6,0.2,0.6],"xyz":[0.200695080178186436,0.114407591857058719,0.31289263998537914],"hpluv":[307.715012949243942,224.64479534599792,40.3131218316236897],"hsluv":[307.715012949243942,77.7202573427554313,40.3131218316236897]},"#9933aa":{"lch":[41.2844862133256925,79.5040030135899372,299.063916375798101],"luv":[41.2844862133256925,38.6218522191785354,-69.4927264276258825],"rgb":[0.6,0.2,0.66666666666666663],"xyz":[0.215752773143439,0.120430669043159827,0.39219648960237774],"hpluv":[299.063916375798101,244.366370382710016,41.2844862133256925],"hsluv":[299.063916375798101,80.1114582016200814,41.2844862133256925]},"#9933bb":{"lch":[42.3513893410192637,88.8787943355742,292.467029257400327],"luv":[42.3513893410192637,33.9651845170614,-82.1328577566084],"rgb":[0.6,0.2,0.733333333333333282],"xyz":[0.232890365250775611,0.127285705886094586,0.482454474701019487],"hpluv":[292.467029257400327,266.299173904300574,42.3513893410192637],"hsluv":[292.467029257400327,82.2764131802073848,42.3513893410192637]},"#9933cc":{"lch":[43.5075532005759911,98.8962106119506785,287.477062230467],"luv":[43.5075532005759911,29.700902070050418,-94.3308904316533],"rgb":[0.6,0.2,0.8],"xyz":[0.252182740694497365,0.135002656063583387,0.584060985371289698],"hpluv":[287.477062230467,288.439223502221068,43.5075532005759911],"hsluv":[287.477062230467,84.2111914011780129,43.5075532005759911]},"#9933dd":{"lch":[44.7462588110156716,109.182503226938962,283.677602435208257],"luv":[44.7462588110156716,25.8171133061496079,-106.086265234656878],"rgb":[0.6,0.2,0.866666666666666696],"xyz":[0.273701066245130908,0.143609986283836921,0.697390833271295696],"hpluv":[283.677602435208257,309.624731809924413,44.7462588110156716],"hsluv":[283.677602435208257,85.9249592908513478,44.7462588110156716]},"#9933ee":{"lch":[46.0606056636097208,119.52114969179982,280.747238708189116],"luv":[46.0606056636097208,22.2879081330132465,-117.42467532296601],"rgb":[0.6,0.2,0.933333333333333348],"xyz":[0.297513246511305618,0.153134858390306938,0.822801649339818919],"hpluv":[280.747238708189116,329.271729063034456,46.0606056636097208],"hsluv":[280.747238708189116,90.0471632149093324,46.0606056636097208]},"#9933ff":{"lch":[47.4437223771408512,129.794782591236896,278.453521985212944],"luv":[47.4437223771408512,19.0807517890999456,-128.38461940228359],"rgb":[0.6,0.2,1],"xyz":[0.323684294921137039,0.163603277754239662,0.960635837631600764],"hpluv":[278.453521985212944,347.150508646733101,47.4437223771408512],"hsluv":[278.453521985212944,99.999999999999261,47.4437223771408512]},"#bb3300":{"lch":[42.6640590509798585,114.303280915030754,17.3320761189885637],"luv":[42.6640590509798585,109.113245500432,34.0520143942012652],"rgb":[0.733333333333333282,0.2,0],"xyz":[0.216768341099481898,0.129342830223910105,0.0135520370028863052],"hpluv":[17.3320761189885637,339.966286272656077,42.6640590509798585],"hsluv":[17.3320761189885637,100.000000000002302,42.6640590509798585]},"#bb3311":{"lch":[42.7251747888925806,112.6335820513806,16.4819551739351198],"luv":[42.7251747888925806,108.005370801027979,31.9556518296457135],"rgb":[0.733333333333333282,0.2,0.0666666666666666657],"xyz":[0.21778000659911903,0.129747496423764958,0.0188801419676419349],"hpluv":[16.4819551739351198,334.52099084556113,42.7251747888925806],"hsluv":[16.4819551739351198,95.1490253673008368,42.7251747888925806]},"#bb3322":{"lch":[42.8381318005571785,109.688338781622747,14.8808580240480524],"luv":[42.8381318005571785,106.009603708482885,28.1690536980292627],"rgb":[0.733333333333333282,0.2,0.133333333333333331],"xyz":[0.219655364737596032,0.130497639679155786,0.0287570281636211345],"hpluv":[14.8808580240480524,324.914627119009424,42.8381318005571785],"hsluv":[14.8808580240480524,86.4181297836030211,42.8381318005571785]},"#bb3333":{"lch":[43.023174549414108,105.246046554892928,12.1770506300618351],"luv":[43.023174549414108,102.878058957341324,22.1998941575065203],"rgb":[0.733333333333333282,0.2,0.2],"xyz":[0.222743115470053765,0.131732739972138885,0.0450191820212322777],"hpluv":[12.1770506300618351,310.414975564112126,43.023174549414108],"hsluv":[12.1770506300618351,72.7398502888125762,43.023174549414108]},"#bb3344":{"lch":[43.2883038991094082,99.6704509181560496,8.14070356751482116],"luv":[43.2883038991094082,98.6661026897846085,14.1137863891102171],"rgb":[0.733333333333333282,0.2,0.266666666666666663],"xyz":[0.227201110714272653,0.133515938069826479,0.0684979569741189231],"hpluv":[8.14070356751482116,292.169703441320848,43.2883038991094082],"hsluv":[8.14070356751482116,73.8775464962187556,43.2883038991094082]},"#bb3355":{"lch":[43.6392404977582515,93.6285749325397632,2.54995992142812078],"luv":[43.6392404977582515,93.5358645919991289,4.16558266337591299],"rgb":[0.733333333333333282,0.2,0.333333333333333315],"xyz":[0.233163524753634666,0.135900903685571312,0.0999000042480928246],"hpluv":[2.54995992142812078,272.251672456619758,43.6392404977582515],"hsluv":[2.54995992142812078,75.2585830443305781,43.6392404977582515]},"#bb3366":{"lch":[44.0797950159491521,88.0182600678664784,355.263953050872033],"luv":[44.0797950159491521,87.7177339493983794,-7.26727295188107547],"rgb":[0.733333333333333282,0.2,0.4],"xyz":[0.240748520527142823,0.138934901994974602,0.1398476486552368],"hpluv":[355.263953050872033,253.380121177946961,44.0797950159491521],"hsluv":[355.263953050872033,76.8177075569623753,44.0797950159491521]},"#bb3377":{"lch":[44.6120878205181057,83.829516929164356,346.367941021132197],"luv":[44.6120878205181057,81.4679789337245239,-19.757437005625782],"rgb":[0.733333333333333282,0.2,0.466666666666666674],"xyz":[0.250062533547344756,0.142660507203055426,0.188901450561634709],"hpluv":[346.367941021132197,238.442541154787421,44.6120878205181057],"hsluv":[346.367941021132197,78.4827471040858597,44.6120878205181057]},"#bb3388":{"lch":[45.2367248685103078,81.924239827592,336.329010851829594],"luv":[45.2367248685103078,75.03162551729379,-32.8912791414593499],"rgb":[0.733333333333333282,0.2,0.533333333333333326],"xyz":[0.261202950649288557,0.147116674043833023,0.247574313965206849],"hpluv":[336.329010851829594,229.805591899252,45.2367248685103078],"hsluv":[336.329010851829594,80.18501002925629,45.2367248685103078]},"#bb3399":{"lch":[45.9529692994627226,82.7837935230449347,325.982908927834501],"luv":[45.9529692994627226,68.6170634488305495,-46.3125800806357404],"rgb":[0.733333333333333282,0.2,0.6],"xyz":[0.274259914758361312,0.152339459687462181,0.316340991606324784],"hpluv":[325.982908927834501,228.597286714525296,45.9529692994627226],"hsluv":[325.982908927834501,81.8663863744617402,45.9529692994627226]},"#bb33aa":{"lch":[46.7589216358443664,86.3774619636168524,316.238480868355282],"luv":[46.7589216358443664,62.3839556422166126,-59.7436859735489136],"rgb":[0.733333333333333282,0.2,0.66666666666666663],"xyz":[0.289317607723613812,0.158362536873563275,0.395644841223323385],"hpluv":[316.238480868355282,234.409537876970433,46.7589216358443664],"hsluv":[316.238480868355282,83.4827024616804181,46.7589216358443664]},"#bb33bb":{"lch":[47.6517090930198108,92.2657594707273461,307.715012949243828],"luv":[47.6517090930198108,56.4421334605023191,-72.9880534138084585],"rgb":[0.733333333333333282,0.2,0.733333333333333282],"xyz":[0.306455199830950487,0.165217573716498034,0.485902826321965131],"hpluv":[307.715012949243828,245.697877980233102,47.6517090930198108],"hsluv":[307.715012949243828,85.0039827354176,47.6517090930198108]},"#bb33cc":{"lch":[48.6276786348411179,99.8443429984049402,300.621719827817344],"luv":[48.6276786348411179,50.8574804969275078,-85.9209491700817551],"rgb":[0.733333333333333282,0.2,0.8],"xyz":[0.325747575274672241,0.172934523893986836,0.587509336992235287],"hpluv":[300.621719827817344,260.542905615006589,48.6276786348411179],"hsluv":[300.621719827817344,86.4127454729900535,48.6276786348411179]},"#bb33dd":{"lch":[49.6825862492002273,108.545865187730342,294.87630802524211],"luv":[49.6825862492002273,45.6609809337446322,-98.4747666639588459],"rgb":[0.733333333333333282,0.2,0.866666666666666696],"xyz":[0.347265900825305729,0.18154185411424037,0.700839184892241285],"hpluv":[294.87630802524211,277.235228758227834,49.6825862492002273],"hsluv":[294.87630802524211,87.70141038259,49.6825862492002273]},"#bb33ee":{"lch":[50.8117750205940695,117.927813495206621,290.271422146528892],"luv":[50.8117750205940695,40.8581913283156268,-110.623584271795281],"rgb":[0.733333333333333282,0.2,0.933333333333333348],"xyz":[0.371078081091480494,0.191066726220710414,0.826250000960764508],"hpluv":[290.271422146528892,294.504005794210514,50.8117750205940695],"hsluv":[290.271422146528892,88.8695912604113687,50.8117750205940695]},"#bb33ff":{"lch":[52.0103359867018611,127.679308171663493,286.581788346289272],"luv":[52.0103359867018611,36.4375993761859931,-122.36955130625914],"rgb":[0.733333333333333282,0.2,1],"xyz":[0.39724912950131186,0.201535145584643111,0.964084189252546353],"hpluv":[286.581788346289272,311.508705442628695,52.0103359867018611],"hsluv":[286.581788346289272,99.9999999999991616,52.0103359867018611]},"#994400":{"lch":[39.4244247356725168,77.6708634712958315,27.0445710144404678],"luv":[39.4244247356725168,69.1777945884316097,35.3156589667733627],"rgb":[0.6,0.266666666666666663,0],"xyz":[0.152036077002273062,0.109076103359438958,0.0130478755429292749],"hpluv":[27.0445710144404678,249.995444431237956,39.4244247356725168],"hsluv":[27.0445710144404678,100.000000000002302,39.4244247356725168]},"#994411":{"lch":[39.4928806474909351,75.8240556098730849,25.7566327743493559],"luv":[39.4928806474909351,68.2907795083206395,32.9493071744317447],"rgb":[0.6,0.266666666666666663,0.0666666666666666657],"xyz":[0.153047742501910194,0.109480769559293811,0.0183759805076849081],"hpluv":[25.7566327743493559,243.628181561178451,39.4928806474909351],"hsluv":[25.7566327743493559,94.1783894720599,39.4928806474909351]},"#994422":{"lch":[39.6193348047394807,72.6128884539244268,23.2788782073808527],"luv":[39.6193348047394807,66.7016282141236161,28.6971141964989123],"rgb":[0.6,0.266666666666666663,0.133333333333333331],"xyz":[0.154923100640387196,0.110230912814684626,0.0282528667036641],"hpluv":[23.2788782073808527,232.565805292122405,39.6193348047394807],"hsluv":[23.2788782073808527,83.7619004180350402,39.6193348047394807]},"#994433":{"lch":[39.8262957210095,67.9099451463512764,18.9473520481579776],"luv":[39.8262957210095,64.2304033034813671,22.0503047882012062],"rgb":[0.6,0.266666666666666663,0.2],"xyz":[0.158010851372844929,0.111466013107667739,0.0445150205612752509],"hpluv":[18.9473520481579776,216.372863201479333,39.8262957210095],"hsluv":[18.9473520481579776,67.5996848307310358,39.8262957210095]},"#994444":{"lch":[40.1224193460439267,62.3513134554678956,12.1770506300619097],"luv":[40.1224193460439267,60.9484376060972082,13.1519672672071142],"rgb":[0.6,0.266666666666666663,0.266666666666666663],"xyz":[0.162468846617063817,0.113249211205355318,0.0679937955141618894],"hpluv":[12.1770506300619097,197.195872414250289,40.1224193460439267],"hsluv":[12.1770506300619097,46.2091051210312429,40.1224193460439267]},"#994455":{"lch":[40.5136546800823041,57.0624194645929776,2.37288379618767387],"luv":[40.5136546800823041,57.0134905267935324,2.36254377830001205],"rgb":[0.6,0.266666666666666663,0.333333333333333315],"xyz":[0.16843126065642583,0.115634176821100151,0.0993958427881357909],"hpluv":[2.37288379618767387,178.726144329621945,40.5136546800823041],"hsluv":[2.37288379618767387,49.5312591923758063,40.5136546800823041]},"#994466":{"lch":[41.0036603670202382,53.5416261730848646,349.413399835018254],"luv":[41.0036603670202382,52.6302589877717111,-9.83674601372026558],"rgb":[0.6,0.266666666666666663,0.4],"xyz":[0.176016256429934,0.11866817513050347,0.139343487195279753],"hpluv":[349.413399835018254,165.694562401887765,41.0036603670202382],"hsluv":[349.413399835018254,53.2076295784804643,41.0036603670202382]},"#994477":{"lch":[41.594070304433572,53.2098960104776424,334.460192523955527],"luv":[41.594070304433572,48.0105420863306946,-22.9408125841809181],"rgb":[0.6,0.266666666666666663,0.466666666666666674],"xyz":[0.18533026945013592,0.122393780338584279,0.188397289101677662],"hpluv":[334.460192523955527,162.330570569563577,41.594070304433572],"hsluv":[334.460192523955527,57.0495308436177666,41.594070304433572]},"#994488":{"lch":[42.2847251453823887,56.6612659292255287,319.901700116735],"luv":[42.2847251453823887,43.3424978513170416,-36.4955742071691631],"rgb":[0.6,0.266666666666666663,0.533333333333333326],"xyz":[0.196470686552079721,0.126849947179361877,0.247070152505249829],"hpluv":[319.901700116735,170.036472949794188,42.2847251453823887],"hsluv":[319.901700116735,60.8903164523640683,42.2847251453823887]},"#994499":{"lch":[43.0739091348830314,63.3829857303906,307.715012949244226],"luv":[43.0739091348830314,38.7735489334465555,-50.1399519665159232],"rgb":[0.6,0.266666666666666663,0.6],"xyz":[0.209527650661152448,0.132072732822991035,0.315836830146367764],"hpluv":[307.715012949244226,186.722963823125951,43.0739091348830314],"hsluv":[307.715012949244226,64.600458594127474,43.0739091348830314]},"#9944aa":{"lch":[43.9586008361636686,72.3252063731545,298.405725418599673],"luv":[43.9586008361636686,34.4059763632637896,-63.6173267861038099],"rgb":[0.6,0.266666666666666663,0.66666666666666663],"xyz":[0.224585343626404976,0.138095810009092129,0.395140679763366365],"hpluv":[298.405725418599673,208.77819920337123,43.9586008361636686],"hsluv":[298.405725418599673,68.0913106207235,43.9586008361636686]},"#9944bb":{"lch":[44.9347323991438827,82.5300732915554676,291.540124858279853],"luv":[44.9347323991438827,30.3011407548278626,-76.7662286846607316],"rgb":[0.6,0.266666666666666663,0.733333333333333282],"xyz":[0.241722935733741651,0.144950846852026888,0.485398664862008111],"hpluv":[291.540124858279853,233.060888419388505,44.9347323991438827],"hsluv":[291.540124858279853,71.3111773355981882,44.9347323991438827]},"#9944cc":{"lch":[45.9974464532923903,93.3382836250318206,286.486143775676851],"luv":[45.9974464532923903,26.4878609436744341,-89.5009967134190561],"rgb":[0.6,0.266666666666666663,0.8],"xyz":[0.261015311177463349,0.152667797029515689,0.587005175532278267],"hpluv":[286.486143775676851,257.492992496327645,45.9974464532923903],"hsluv":[286.486143775676851,74.2376853125076792,45.9974464532923903]},"#9944dd":{"lch":[47.1413389271288139,104.350309752399141,282.717215233582351],"luv":[47.1413389271288139,22.9716047676972792,-101.790434323753402],"rgb":[0.6,0.266666666666666663,0.866666666666666696],"xyz":[0.282533636728096949,0.161275127249769223,0.700335023432284265],"hpluv":[282.717215233582351,280.886686990529654,47.1413389271288139],"hsluv":[282.717215233582351,78.691216526215527,47.1413389271288139]},"#9944ee":{"lch":[48.3606780479664593,115.341161543855208,279.855683836472622],"luv":[48.3606780479664593,19.7426125181249787,-113.638958096441911],"rgb":[0.6,0.266666666666666663,0.933333333333333348],"xyz":[0.306345816994271658,0.170799999356239268,0.825745839500807488],"hpluv":[279.855683836472622,302.643440789384783,48.3606780479664593],"hsluv":[279.855683836472622,89.2619995530309325,48.3606780479664593]},"#9944ff":{"lch":[49.6495929972458185,126.19285787586071,277.642335930208503],"luv":[49.6495929972458185,16.7822322716138856,-125.071955525044785],"rgb":[0.6,0.266666666666666663,1],"xyz":[0.332516865404103079,0.181268418720171964,0.963580027792589333],"hpluv":[277.642335930208503,322.521305960549284,49.6495929972458185],"hsluv":[277.642335930208503,99.9999999999991616,49.6495929972458185]},"#bb4400":{"lch":[45.2216387767487547,104.837609625168909,21.4216552556228201],"luv":[45.2216387767487547,97.5952013308911,38.2896992558330354],"rgb":[0.733333333333333282,0.266666666666666663,0],"xyz":[0.225600911582447911,0.147007971189842435,0.0164962271638749],"hpluv":[21.4216552556228201,294.177965476355098,45.2216387767487547],"hsluv":[21.4216552556228201,100.000000000002373,45.2216387767487547]},"#bb4411":{"lch":[45.2777618800582076,103.283777149094803,20.576768268141489],"luv":[45.2777618800582076,96.6944911384892123,36.3003306548646947],"rgb":[0.733333333333333282,0.266666666666666663,0.0666666666666666657],"xyz":[0.226612577082085043,0.147412637389697287,0.0218243321286305317],"hpluv":[20.576768268141489,289.458620037032802,45.2777618800582076],"hsluv":[20.576768268141489,95.6967439910137614,45.2777618800582076]},"#bb4422":{"lch":[45.3815280810129238,100.53232916519147,18.9799525675269258],"luv":[45.3815280810129238,95.0666309197234,32.6968636561903381],"rgb":[0.733333333333333282,0.266666666666666663,0.133333333333333331],"xyz":[0.228487935220562044,0.148162780645088116,0.0317012183246097243],"hpluv":[18.9799525675269258,281.103307599105051,45.3815280810129238],"hsluv":[18.9799525675269258,87.925891065222288,45.3815280810129238]},"#bb4433":{"lch":[45.5516172521931111,96.3559005693685862,16.2666991179303722],"luv":[45.5516172521931111,92.4986058403436147,26.9901369416087924],"rgb":[0.733333333333333282,0.266666666666666663,0.2],"xyz":[0.231575685953019805,0.149397880938071215,0.0479633721822208675],"hpluv":[16.2666991179303722,268.419362556396,45.5516172521931111],"hsluv":[16.2666991179303722,75.6846484949249572,45.5516172521931111]},"#bb4444":{"lch":[45.7955406359936816,91.066890863790789,12.177050630061844],"luv":[45.7955406359936816,89.0179277419259734,19.2090382927107299],"rgb":[0.733333333333333282,0.266666666666666663,0.266666666666666663],"xyz":[0.236033681197238665,0.151181079035758809,0.0714421471351075],"hpluv":[12.177050630061844,252.334507458167678,45.7955406359936816],"hsluv":[12.177050630061844,59.1297963696904461,45.7955406359936816]},"#bb4455":{"lch":[46.1187996938414813,85.2741675307746,6.43569277192082279],"luv":[46.1187996938414813,84.7367941199702273,9.55820957796975],"rgb":[0.733333333333333282,0.266666666666666663,0.333333333333333315],"xyz":[0.24199609523660065,0.153566044651503641,0.102844194409081421],"hpluv":[6.43569277192082279,234.627449284537505,46.1187996938414813],"hsluv":[6.43569277192082279,61.0765315010866274,46.1187996938414813]},"#bb4466":{"lch":[46.5252276318027427,79.8426568240615637,358.82639812637143],"luv":[46.5252276318027427,79.8259079304732779,-1.63532009113408461],"rgb":[0.733333333333333282,0.266666666666666663,0.4],"xyz":[0.249581091010108835,0.156600042960906932,0.142791838816225369],"hpluv":[358.82639812637143,217.763856882437722,46.5252276318027427],"hsluv":[358.82639812637143,63.3003300169989842,46.5252276318027427]},"#bb4477":{"lch":[47.0171837667790697,75.785442181693,349.367581794189107],"luv":[47.0171837667790697,74.484290362097866,-13.9829802234512588],"rgb":[0.733333333333333282,0.266666666666666663,0.466666666666666674],"xyz":[0.258895104030310741,0.160325648168987756,0.191845640722623278],"hpluv":[349.367581794189107,204.535408840651428,47.0171837667790697],"hsluv":[349.367581794189107,65.7062458495858266,47.0171837667790697]},"#bb4488":{"lch":[47.5956997014540235,74.0450948660102,338.538246495536782],"luv":[47.5956997014540235,68.9109568360576219,-27.0916241974425098],"rgb":[0.733333333333333282,0.266666666666666663,0.533333333333333326],"xyz":[0.270035521132254597,0.164781815009765353,0.250518504126195474],"hpluv":[338.538246495536782,197.409434601059019,47.5956997014540235],"hsluv":[338.538246495536782,68.1997676790361,47.5956997014540235]},"#bb4499":{"lch":[48.2606154557730633,75.1911240047971,327.313188255720945],"luv":[48.2606154557730633,63.2834900243205496,-40.6067115074158309],"rgb":[0.733333333333333282,0.266666666666666663,0.6],"xyz":[0.283092485241327296,0.170004600653394511,0.319285181767313353],"hpluv":[327.313188255720945,197.702903480158483,48.2606154557730633],"hsluv":[327.313188255720945,70.6969578310621074,48.2606154557730633]},"#bb44aa":{"lch":[49.0107199856960278,79.2228796099941093,316.794363507436401],"luv":[49.0107199856960278,57.7456584584256944,-54.2374739723603838],"rgb":[0.733333333333333282,0.266666666666666663,0.66666666666666663],"xyz":[0.298150178206579852,0.176027677839495605,0.398589031384311954],"hpluv":[316.794363507436401,205.115683333718124,49.0107199856960278],"hsluv":[316.794363507436401,73.1302855273877128,49.0107199856960278]},"#bb44bb":{"lch":[49.8438993628519427,85.6636869410227746,307.715012949243942],"luv":[49.8438993628519427,52.4034189799077268,-67.7653963284049752],"rgb":[0.733333333333333282,0.266666666666666663,0.733333333333333282],"xyz":[0.315287770313916471,0.182882714682430364,0.4888470164829537],"hpluv":[307.715012949243942,218.084137693810391,49.8438993628519427],"hsluv":[307.715012949243942,75.450469608388417,49.8438993628519427]},"#bb44cc":{"lch":[50.757290285110841,93.8478600934752905,300.284565440631638],"luv":[50.757290285110841,47.3270085455435918,-81.0405769121528152],"rgb":[0.733333333333333282,0.266666666666666663,0.8],"xyz":[0.334580145757638225,0.190599664859919166,0.590453527153223856],"hpluv":[300.284565440631638,234.620130462749955,50.757290285110841],"hsluv":[300.284565440631638,77.6254237907312898,50.757290285110841]},"#bb44dd":{"lch":[51.7474340276366291,103.158361374368454,294.364201848969515],"luv":[51.7474340276366291,42.5564715489483518,-93.971241615445],"rgb":[0.733333333333333282,0.266666666666666663,0.866666666666666696],"xyz":[0.356098471308271769,0.1992069950801727,0.703783375053229854],"hpluv":[294.364201848969515,252.961799427415912,51.7474340276366291],"hsluv":[294.364201848969515,79.6375689955678467,51.7474340276366291]},"#bb44ee":{"lch":[52.8104252671910217,113.122924260907325,289.686672533024307],"luv":[52.8104252671910217,38.1084271425454304,-106.510768347901248],"rgb":[0.733333333333333282,0.266666666666666663,0.933333333333333348],"xyz":[0.379910651574446478,0.208731867186642744,0.829194191121753077],"hpluv":[289.686672533024307,271.813038246621943,52.8104252671910217],"hsluv":[289.686672533024307,87.7449679178180872,52.8104252671910217]},"#bb44ff":{"lch":[53.942050711908152,123.415863319803691,285.982908620336502],"luv":[53.942050711908152,33.9826318144238115,-118.645084406973112],"rgb":[0.733333333333333282,0.266666666666666663,1],"xyz":[0.4060816999842779,0.219200286550575441,0.967028379413534922],"hpluv":[285.982908620336502,290.323946696930363,53.942050711908152],"hsluv":[285.982908620336502,99.9999999999990621,53.942050711908152]},"#995500":{"lch":[43.167672396478018,69.2675138179999,36.3951762413548678],"luv":[43.167672396478018,55.7564526526882105,41.099956911356287],"rgb":[0.6,0.333333333333333315,0],"xyz":[0.163849333716619028,0.132702616788131222,0.0169856277810444857],"hpluv":[36.3951762413548678,203.615246511519132,43.167672396478018],"hsluv":[36.3951762413548678,100.000000000002288,43.167672396478018]},"#995511":{"lch":[43.2277537555276865,67.4837391190291385,35.2266717066771307],"luv":[43.2277537555276865,55.1258789529511333,38.9254738590266101],"rgb":[0.6,0.333333333333333315,0.0666666666666666657],"xyz":[0.16486099921625616,0.133107282987986075,0.0223137327458001189],"hpluv":[35.2266717066771307,198.096040704981476,43.2277537555276865],"hsluv":[35.2266717066771307,95.1659583326808303,43.2277537555276865]},"#995522":{"lch":[43.3388072781739,64.3407602415628475,32.9528815923873708],"luv":[43.3388072781739,53.9895016234129059,34.998101990218963],"rgb":[0.6,0.333333333333333315,0.133333333333333331],"xyz":[0.166736357354733161,0.133857426243376904,0.0321906189417793115],"hpluv":[32.9528815923873708,188.385971738918272,43.3388072781739],"hsluv":[32.9528815923873708,86.4646465379692302,43.3388072781739]},"#995533":{"lch":[43.5207548807750584,59.6262244551406582,28.8908620435756234],"luv":[43.5207548807750584,52.2052395636471,28.8079781462883915],"rgb":[0.6,0.333333333333333315,0.2],"xyz":[0.169824108087190895,0.13509252653636,0.0484527727993904617],"hpluv":[28.8908620435756234,173.852210644027934,43.5207548807750584],"hsluv":[28.8908620435756234,72.8304069554253601,43.5207548807750584]},"#995544":{"lch":[43.7814988718974831,53.8284560366537335,22.2989672577237812],"luv":[43.7814988718974831,49.8029788080235036,20.4246415179685634],"rgb":[0.6,0.333333333333333315,0.266666666666666663],"xyz":[0.174282103331409782,0.136875724634047596,0.0719315477522771],"hpluv":[22.2989672577237812,156.01294104827457,43.7814988718974831],"hsluv":[22.2989672577237812,54.5318604429391058,43.7814988718974831]},"#995555":{"lch":[44.1267187000120629,47.9518139182857226,12.1770506300620411],"luv":[44.1267187000120629,46.8729201797035,10.1146335514957979],"rgb":[0.6,0.333333333333333315,0.333333333333333315],"xyz":[0.180244517370771795,0.139260690249792429,0.103333595026251],"hpluv":[12.1770506300620411,137.893162706519348,44.1267187000120629],"hsluv":[12.1770506300620411,32.3126421104369754,44.1267187000120629]},"#995566":{"lch":[44.5602350881765048,43.578232165907,357.727809148728397],"luv":[44.5602350881765048,43.5439690351937116,-1.72773822316436432],"rgb":[0.6,0.333333333333333315,0.4],"xyz":[0.187829513144279953,0.14229468855919572,0.143281239433394963],"hpluv":[357.727809148728397,124.097051059849122,44.5602350881765048],"hsluv":[357.727809148728397,36.5660257696708157,44.5602350881765048]},"#995577":{"lch":[45.0842241078155226,42.5628566452735342,339.858530865537546],"luv":[45.0842241078155226,39.9599368331855729,-14.6560640723873874],"rgb":[0.6,0.333333333333333315,0.466666666666666674],"xyz":[0.197143526164481886,0.146020293767276543,0.192335041339792873],"hpluv":[339.858530865537546,119.796876557388956,45.0842241078155226],"hsluv":[339.858530865537546,41.1101378179314167,45.0842241078155226]},"#995588":{"lch":[45.699386409692309,45.957423726275,322.088602167082399],"luv":[45.699386409692309,36.2586549471185506,-28.2381787122006145],"rgb":[0.6,0.333333333333333315,0.533333333333333326],"xyz":[0.208283943266425686,0.150476460608054141,0.25100790474336504],"hpluv":[322.088602167082399,127.609977655436467,45.699386409692309],"hsluv":[322.088602167082399,45.7577454208568852,45.699386409692309]},"#995599":{"lch":[46.4051108942887964,53.2218555896971921,307.715012949244795],"luv":[46.4051108942887964,32.5576366947089113,-42.1018551285561102],"rgb":[0.6,0.333333333333333315,0.6],"xyz":[0.221340907375498414,0.155699246251683299,0.319774582384483],"hpluv":[307.715012949244795,145.533684272522947,46.4051108942887964],"hsluv":[307.715012949244795,50.3502223422482516,46.4051108942887964]},"#9955aa":{"lch":[47.1996461355186625,63.0010233462712037,297.353030705211779],"luv":[47.1996461355186625,28.9471952899390068,-55.9570266143899246],"rgb":[0.6,0.333333333333333315,0.66666666666666663],"xyz":[0.236398600340750942,0.161722323437784393,0.399078432001481576],"hpluv":[297.353030705211779,169.374563019623821,47.1996461355186625],"hsluv":[297.353030705211779,54.7667714505238337,47.1996461355186625]},"#9955bb":{"lch":[48.0802807126223541,74.1194144420538,290.114722102094788],"luv":[48.0802807126223541,25.4897394646759068,-69.5985688017783701],"rgb":[0.6,0.333333333333333315,0.733333333333333282],"xyz":[0.253536192448087616,0.168577360280719152,0.489336417100123322],"hpluv":[290.114722102094788,195.615971831826613,48.0802807126223541],"hsluv":[290.114722102094788,58.9252289891592866,48.0802807126223541]},"#9955cc":{"lch":[49.0435277691913,85.8237639836856658,285.007043429489613],"luv":[49.0435277691913,22.2230153813451068,-82.8966588692685491],"rgb":[0.6,0.333333333333333315,0.8],"xyz":[0.272828567891809315,0.176294310458207953,0.590942927770393478],"hpluv":[285.007043429489613,222.057364979540267,49.0435277691913],"hsluv":[285.007043429489613,65.256702758776143,49.0435277691913]},"#9955dd":{"lch":[50.0853068419578875,97.6800340866365104,281.315028513382344],"luv":[50.0853068419578875,19.1651498984824649,-95.7814496055220843],"rgb":[0.6,0.333333333333333315,0.866666666666666696],"xyz":[0.294346893442442914,0.184901640678461487,0.704272775670399476],"hpluv":[281.315028513382344,247.476970093373268,50.0853068419578875],"hsluv":[281.315028513382344,76.6956878028438638,50.0853068419578875]},"#9955ee":{"lch":[51.2011159126469266,109.450459224116145,278.575243894560685],"luv":[51.2011159126469266,16.3199513369978568,-108.226901520499666],"rgb":[0.6,0.333333333333333315,0.933333333333333348],"xyz":[0.318159073708617623,0.194426512784931532,0.829683591738922699],"hpluv":[278.575243894560685,271.254835109068836,51.2011159126469266],"hsluv":[278.575243894560685,88.2491190723243335,51.2011159126469266]},"#9955ff":{"lch":[52.3861878346365444,121.012399839465246,276.491711029928183],"luv":[52.3861878346365444,13.6815981187824764,-120.2364952409323],"rgb":[0.6,0.333333333333333315,1],"xyz":[0.344330122118449045,0.204894932148864228,0.967517780030704544],"hpluv":[276.491711029928183,293.124692446110771,52.3861878346365444],"hsluv":[276.491711029928183,99.9999999999991,52.3861878346365444]},"#bb5500":{"lch":[48.3398816318057811,94.9450628471467724,27.1627331553413143],"luv":[48.3398816318057811,84.4739036935134,43.344256295703957],"rgb":[0.733333333333333282,0.333333333333333315,0],"xyz":[0.237414168296793876,0.170634484618534699,0.0204339794019901093],"hpluv":[27.1627331553413143,249.233335779464397,48.3398816318057811],"hsluv":[27.1627331553413143,100.000000000002217,48.3398816318057811]},"#bb5511":{"lch":[48.3907029738951735,93.4795954244126364,26.3417432533787057],"luv":[48.3907029738951735,83.7729911103365907,41.4791600823755289],"rgb":[0.733333333333333282,0.333333333333333315,0.0666666666666666657],"xyz":[0.238425833796431,0.171039150818389551,0.0257620843667457425],"hpluv":[26.3417432533787057,245.128732426237889,48.3907029738951735],"hsluv":[26.3417432533787057,96.2613278044251786,48.3907029738951735]},"#bb5522":{"lch":[48.4847005727335869,90.8707197847641623,24.7826102649670759],"luv":[48.4847005727335869,82.5019575685759321,38.090874386840035],"rgb":[0.733333333333333282,0.333333333333333315,0.133333333333333331],"xyz":[0.240301191934908,0.17178929407378038,0.0356389705627249351],"hpluv":[24.7826102649670759,237.825586669453713,48.4847005727335869],"hsluv":[24.7826102649670759,89.48684037186257,48.4847005727335869]},"#bb5533":{"lch":[48.6388719159228629,86.8743588299812473,22.1104535643633149],"luv":[48.6388719159228629,80.4856161939384407,32.6989267102511363],"rgb":[0.733333333333333282,0.333333333333333315,0.2],"xyz":[0.243388942667365771,0.173024394366763479,0.0519011244203360783],"hpluv":[22.1104535643633149,226.64567974804504,48.6388719159228629],"hsluv":[22.1104535643633149,78.7542493880857393,48.6388719159228629]},"#bb5544":{"lch":[48.8601705631915,81.7431600256382751,18.0266646696809296],"luv":[48.8601705631915,77.730600917119915,25.2962031151029265],"rgb":[0.733333333333333282,0.333333333333333315,0.266666666666666663],"xyz":[0.24784693791158463,0.174807592464451073,0.0753798993732227168],"hpluv":[18.0266646696809296,212.293047020031764,48.8601705631915],"hsluv":[18.0266646696809296,64.1199207289341,48.8601705631915]},"#bb5555":{"lch":[49.1538097277392154,76.0172073873862075,12.1770506300619399],"luv":[49.1538097277392154,74.3068552156307,16.0345591439297159],"rgb":[0.733333333333333282,0.333333333333333315,0.333333333333333315],"xyz":[0.253809351950946616,0.177192558080195905,0.106781946647196632],"hpluv":[12.1770506300619399,196.242945408672853,49.1538097277392154],"hsluv":[12.1770506300619399,45.9858047870319879,49.1538097277392154]},"#bb5566":{"lch":[49.523574907380123,70.5220596563995,4.21567942747197],"luv":[49.523574907380123,70.3312550088346882,5.18415538569556134],"rgb":[0.733333333333333282,0.333333333333333315,0.4],"xyz":[0.261394347724454801,0.180226556389599196,0.14672959105434058],"hpluv":[4.21567942747197,180.697576197923894,49.523574907380123],"hsluv":[4.21567942747197,48.7291682320237527,49.523574907380123]},"#bb5577":{"lch":[49.971995559373525,66.3094111666939341,354.014227306533371],"luv":[49.971995559373525,65.9478803557508257,-6.91484532417379327],"rgb":[0.733333333333333282,0.333333333333333315,0.466666666666666674],"xyz":[0.270708360744656706,0.18395216159768002,0.195783392960738489],"hpluv":[354.014227306533371,168.378953180241098,49.971995559373525],"hsluv":[354.014227306533371,51.7390719561838495,49.971995559373525]},"#bb5588":{"lch":[50.5004659153875508,64.4571905510646275,342.016521446261379],"luv":[50.5004659153875508,61.308172080607541,-19.9006896832966476],"rgb":[0.733333333333333282,0.333333333333333315,0.533333333333333326],"xyz":[0.281848777846600562,0.188408328438457617,0.254456256364310685],"hpluv":[342.016521446261379,161.962814057843559,50.5004659153875508],"hsluv":[342.016521446261379,54.9055054808170055,50.5004659153875508]},"#bb5599":{"lch":[51.1093507584050286,65.6961991151429459,329.411862939203161],"luv":[51.1093507584050286,56.5544024759803,-33.4303774845774342],"rgb":[0.733333333333333282,0.333333333333333315,0.6],"xyz":[0.294905741955673262,0.193631114082086775,0.323222934005428564],"hpluv":[329.411862939203161,163.109481188372769,51.1093507584050286],"hsluv":[329.411862939203161,58.1255686218068561,51.1093507584050286]},"#bb55aa":{"lch":[51.7980911374347386,70.0901192661774246,317.660759061539352],"luv":[51.7980911374347386,51.8085124997667563,-47.2070212077450151],"rgb":[0.733333333333333282,0.333333333333333315,0.66666666666666663],"xyz":[0.309963434920925818,0.199654191268187869,0.402526783622427164],"hpluv":[317.660759061539352,171.704773930815691,51.7980911374347386],"hsluv":[317.660759061539352,61.3115173935257403,51.7980911374347386]},"#bb55bb":{"lch":[52.5653152299933737,77.1031380177621344,307.715012949244226],"luv":[52.5653152299933737,47.1666372355911179,-60.9934605025180332],"rgb":[0.733333333333333282,0.333333333333333315,0.733333333333333282],"xyz":[0.327101027028262437,0.206509228111122628,0.492784768721068911],"hpluv":[307.715012949244226,186.128169856082764,52.5653152299933737],"hsluv":[307.715012949244226,64.3946779967479,52.5653152299933737]},"#bb55cc":{"lch":[53.4089544864585,85.9678373228364308,299.780474196008072],"luv":[53.4089544864585,42.6983512805399883,-74.6144748148057175],"rgb":[0.733333333333333282,0.333333333333333315,0.8],"xyz":[0.346393402471984191,0.21422617828861143,0.594391279391339067],"hpluv":[299.780474196008072,204.249617293250537,53.4089544864585],"hsluv":[299.780474196008072,67.3259326792693855,53.4089544864585]},"#bb55dd":{"lch":[54.3263625650166944,95.9883710948233926,293.613183872979789],"luv":[54.3263625650166944,38.4490902963257213,-87.9513208588848698],"rgb":[0.733333333333333282,0.333333333333333315,0.866666666666666696],"xyz":[0.367911728022617734,0.222833508508864964,0.707721127291345065],"hpluv":[293.613183872979789,224.206046477737118,54.3263625650166944],"hsluv":[293.613183872979789,73.8407928406032283,54.3263625650166944]},"#bb55ee":{"lch":[55.314433433552054,106.647677925948784,288.842761327535072],"luv":[55.314433433552054,34.444226028074695,-100.932266893812525],"rgb":[0.733333333333333282,0.333333333333333315,0.933333333333333348],"xyz":[0.391723908288792444,0.232358380615335,0.833131943359868288],"hpluv":[288.842761327535072,244.653966901481454,55.314433433552054],"hsluv":[288.842761327535072,86.7715876359309135,55.314433433552054]},"#bb55ff":{"lch":[56.3697148536960526,117.598184211748716,285.129655441003138],"luv":[56.3697148536960526,30.6936185759692179,-113.521956944959783],"rgb":[0.733333333333333282,0.333333333333333315,1],"xyz":[0.417894956698623865,0.242826799979267705,0.970966131651650133],"hpluv":[285.129655441003138,264.724480425834031,56.3697148536960526],"hsluv":[285.129655441003138,99.9999999999989,56.3697148536960526]},"#996600":{"lch":[47.3343652017352454,63.4240894393546952,48.3260196362919672],"luv":[47.3343652017352454,42.1701199842588,47.3740023823666476],"rgb":[0.6,0.4,0],"xyz":[0.178877391422465504,0.162758732199824563,0.0219949803496598331],"hpluv":[48.3260196362919672,170.026654750900292,47.3343652017352454],"hsluv":[48.3260196362919672,100.000000000002288,47.3343652017352454]},"#996611":{"lch":[47.3868110627231189,61.667674323653,47.4017350737566616],"luv":[47.3868110627231189,41.7399921999205,45.3946594616449133],"rgb":[0.6,0.4,0.0666666666666666657],"xyz":[0.179889056922102636,0.163163398399679416,0.0273230853144154628],"hpluv":[47.4017350737566616,165.135107398016657,47.3868110627231189],"hsluv":[47.4017350737566616,96.0239926064661,47.3868110627231189]},"#996622":{"lch":[47.4838028017404099,58.5263777304533406,45.5834379771503322],"luv":[47.4838028017404099,40.9608465044279413,41.8036594557031336],"rgb":[0.6,0.4,0.133333333333333331],"xyz":[0.181764415060579637,0.163913541655070244,0.0371999715103946624],"hpluv":[45.5834379771503322,156.40314428015364,47.4838028017404099],"hsluv":[45.5834379771503322,88.8298219708016177,47.4838028017404099]},"#996633":{"lch":[47.642855645786625,53.6803525088045674,42.2629253198225712],"luv":[47.642855645786625,39.7270268335614887,36.1018501525199724],"rgb":[0.6,0.4,0.2],"xyz":[0.184852165793037371,0.165148641948053343,0.0534621253680058056],"hpluv":[42.2629253198225712,142.973945144987511,47.642855645786625],"hsluv":[42.2629253198225712,77.4596172761956865,47.642855645786625]},"#996644":{"lch":[47.8710980897590872,47.4159845831850149,36.6424092143452071],"luv":[47.8710980897590872,38.045445264132745,28.298757722676072],"rgb":[0.6,0.4,0.266666666666666663],"xyz":[0.189310161037256258,0.166931840045740937,0.0769409003208924441],"hpluv":[36.6424092143452071,125.687101185572914,47.8710980897590872],"hsluv":[36.6424092143452071,62.0095295256686185,47.8710980897590872]},"#996655":{"lch":[48.173837669734425,40.4765536471140521,27.3183313201514686],"luv":[48.173837669734425,35.9622216701857838,18.5760600691352664],"rgb":[0.6,0.4,0.333333333333333315],"xyz":[0.195272575076618271,0.16931680566148577,0.108342947594866346],"hpluv":[27.3183313201514686,106.618264590322553,48.173837669734425],"hsluv":[27.3183313201514686,42.9499413016611484,48.173837669734425]},"#996666":{"lch":[48.5548823199147819,34.3240193245421,12.1770506300621335],"luv":[48.5548823199147819,33.551744690774747,7.24007809326721219],"rgb":[0.6,0.4,0.4],"xyz":[0.202857570850126429,0.17235080397088906,0.148290592002010307],"hpluv":[12.1770506300621335,89.702502372613651,48.5548823199147819],"hsluv":[12.1770506300621335,21.0200766933302461,48.5548823199147819]},"#996677":{"lch":[49.0167186013709,31.3606600839303482,350.2076113500313],"luv":[49.0167186013709,30.9037509766054157,-5.33377694282222681],"rgb":[0.6,0.4,0.466666666666666674],"xyz":[0.212171583870328362,0.176076409178969884,0.197344393908408217],"hpluv":[350.2076113500313,81.185839798992177,49.0167186013709],"hsluv":[350.2076113500313,25.8881256225468483,49.0167186013709]},"#996688":{"lch":[49.5606396668562752,33.7929953796712823,326.289263208678278],"luv":[49.5606396668562752,28.1107077320421368,-18.7551232343109682],"rgb":[0.6,0.4,0.533333333333333326],"xyz":[0.223312000972272162,0.180532576019747482,0.256017257311980384],"hpluv":[326.289263208678278,86.5225105267045365,49.5606396668562752],"hsluv":[326.289263208678278,30.9767265160446463,49.5606396668562752]},"#996699":{"lch":[50.1868595811773304,41.2886932006772,307.715012949245818],"luv":[50.1868595811773304,25.2577114783499113,-32.6619686653465351],"rgb":[0.6,0.4,0.6],"xyz":[0.236368965081344889,0.185755361663376639,0.324783934953098319],"hpluv":[307.715012949245818,104.395179003902854,50.1868595811773304],"hsluv":[307.715012949245818,36.1175524455388413,50.1868595811773304]},"#9966aa":{"lch":[50.8946289106688141,51.8448774557822,295.617938374847199],"luv":[50.8946289106688141,22.4160699516755599,-46.7483810021979451],"rgb":[0.6,0.4,0.66666666666666663],"xyz":[0.251426658046597418,0.191778438849477734,0.40408778457009692],"hpluv":[295.617938374847199,129.262701065701,50.8946289106688141],"hsluv":[295.617938374847199,41.1705422178494445,50.8946289106688141]},"#9966bb":{"lch":[51.6823563026294,63.8712345518136,287.908782454232437],"luv":[51.6823563026294,19.6405628457828776,-60.776499523036378],"rgb":[0.6,0.4,0.733333333333333282],"xyz":[0.268564250153934092,0.198633475692412492,0.494345769668738666],"hpluv":[287.908782454232437,156.820318415219759,51.6823563026294],"hsluv":[287.908782454232437,49.349420166275209,51.6823563026294]},"#9966cc":{"lch":[52.5477355185796569,76.4825896496335389,282.819195018988751],"luv":[52.5477355185796569,16.9695880464031816,-74.5762670093482285],"rgb":[0.6,0.4,0.8],"xyz":[0.287856625597655791,0.206350425869901294,0.595952280339008822],"hpluv":[282.819195018988751,184.691924030055,52.5477355185796569],"hsluv":[282.819195018988751,61.7185051859638136,52.5477355185796569]},"#9966dd":{"lch":[53.4878747475352725,89.2117449852098758,279.306611445978092],"luv":[53.4878747475352725,14.4271177471338046,-88.0374563286358],"rgb":[0.6,0.4,0.866666666666666696],"xyz":[0.30937495114828939,0.214957756090154828,0.70928212823901482],"hpluv":[279.306611445978092,211.644028054176175,53.4878747475352725],"hsluv":[279.306611445978092,74.2596178074049362,53.4878747475352725]},"#9966ee":{"lch":[54.4994239962059339,101.810849438236403,276.783380903602506],"luv":[54.4994239962059339,12.0254847729914225,-101.098154183495325],"rgb":[0.6,0.4,0.933333333333333348],"xyz":[0.333187131414464099,0.224482628196624873,0.834692944307538],"hpluv":[276.783380903602506,237.050827216632513,54.4994239962059339],"hsluv":[276.783380903602506,86.9990828065156734,54.4994239962059339]},"#9966ff":{"lch":[55.5786963614876,114.151421142661491,274.908981870437117],"luv":[55.5786963614876,9.76829238934238475,-113.732701597586171],"rgb":[0.6,0.4,1],"xyz":[0.359358179824295521,0.234951047560557569,0.972527132599319888],"hpluv":[274.908981870437117,260.622732185953453,55.5786963614876],"hsluv":[274.908981870437117,99.999999999998991,55.5786963614876]},"#bb6600":{"lch":[51.9152024616159622,85.9194467179265899,34.7713476038742],"luv":[51.9152024616159622,70.5771984524152884,49.0001059480794936],"rgb":[0.733333333333333282,0.4,0],"xyz":[0.252442226002640324,0.200690600030228039,0.0254433319706054567],"hpluv":[34.7713476038742,210.008196913669821,51.9152024616159622],"hsluv":[34.7713476038742,100.000000000002217,51.9152024616159622]},"#bb6611":{"lch":[51.960819173128,84.5067938711160735,34.0102696578751846],"luv":[51.960819173128,70.0508360673827184,47.2681560528436],"rgb":[0.733333333333333282,0.4,0.0666666666666666657],"xyz":[0.253453891502277429,0.201095266230082892,0.0307714369353610864],"hpluv":[34.0102696578751846,206.373990798532162,51.960819173128],"hsluv":[34.0102696578751846,96.7960731817087492,51.960819173128]},"#bb6622":{"lch":[52.0452187907305586,81.9745670334704215,32.5563816919222901],"luv":[52.0452187907305586,69.0932729256005587,44.1129150788451909],"rgb":[0.733333333333333282,0.4,0.133333333333333331],"xyz":[0.255329249640754485,0.20184540948547372,0.040648323131340286],"hpluv":[32.5563816919222901,199.865401092535734,52.0452187907305586],"hsluv":[32.5563816919222901,90.9716633106406221,52.0452187907305586]},"#bb6633":{"lch":[52.1837271506259412,78.04817012610809,30.0375791414029081],"luv":[52.1837271506259412,67.5660884046363,39.0684086920722109],"rgb":[0.733333333333333282,0.4,0.2],"xyz":[0.258417000373212191,0.203080509778456819,0.0569104769889514292],"hpluv":[30.0375791414029081,189.787216830323956,52.1837271506259412],"hsluv":[30.0375791414029081,81.6941023093515639,52.1837271506259412]},"#bb6644":{"lch":[52.3827138306128859,72.9081368603095257,26.1184165145312406],"luv":[52.3827138306128859,65.4632041398932,32.0961886238895318],"rgb":[0.733333333333333282,0.4,0.266666666666666663],"xyz":[0.262874995617431106,0.204863707876144413,0.0803892519418380747],"hpluv":[26.1184165145312406,176.614896915735159,52.3827138306128859],"hsluv":[26.1184165145312406,68.9437006343278824,52.3827138306128859]},"#bb6655":{"lch":[52.6470547760809637,67.004522830646,20.3474245095699864],"luv":[52.6470547760809637,62.823537757634746,23.2982656731697979],"rgb":[0.733333333333333282,0.4,0.333333333333333315],"xyz":[0.268837409656793092,0.207248673491889246,0.111791299215811976],"hpluv":[20.3474245095699864,161.498824171429789,52.6470547760809637],"hsluv":[20.3474245095699864,52.9816895309479534,52.6470547760809637]},"#bb6666":{"lch":[52.9804174131186727,61.0960132663801261,12.1770506300620109],"luv":[52.9804174131186727,59.7213810933874498,12.8871826767560087],"rgb":[0.733333333333333282,0.4,0.4],"xyz":[0.276422405430301277,0.210282671801292537,0.151738943622955924],"hpluv":[12.1770506300620109,146.331162504643544,52.9804174131186727],"hsluv":[12.1770506300620109,34.2899270044314335,52.9804174131186727]},"#bb6677":{"lch":[53.3854132757716826,56.2661599102721226,1.17050216666979279],"luv":[53.3854132757716826,56.2544190111897535,1.14938799445880213],"rgb":[0.733333333333333282,0.4,0.466666666666666674],"xyz":[0.285736418450503182,0.21400827700937336,0.200792745529353833],"hpluv":[1.17050216666979279,133.74082367080041,53.3854132757716826],"hsluv":[1.17050216666979279,37.694842795415525,53.3854132757716826]},"#bb6688":{"lch":[53.8636991644475387,53.7950791600554297,347.554026547444039],"luv":[53.8636991644475387,52.5308766640911458,-11.5938578022448873],"rgb":[0.733333333333333282,0.4,0.533333333333333326],"xyz":[0.296876835552447,0.218464443850150958,0.259465608932926028],"hpluv":[347.554026547444039,126.731828674836166,53.8636991644475387],"hsluv":[347.554026547444039,41.3310399817098855,53.8636991644475387]},"#bb6699":{"lch":[54.4160596975863484,54.7145736516266723,332.78581188167891],"luv":[54.4160596975863484,48.6578429809048814,-25.0219680745716886],"rgb":[0.733333333333333282,0.4,0.6],"xyz":[0.309933799661519682,0.223687229493780115,0.328232286574043908],"hpluv":[332.78581188167891,127.589593839900076,54.4160596975863484],"hsluv":[332.78581188167891,45.0871489409768813,54.4160596975863484]},"#bb66aa":{"lch":[55.0424859024436,59.2427277394444332,319.03138367428437],"luv":[55.0424859024436,44.7323366642012274,-38.8422301956323963],"rgb":[0.733333333333333282,0.4,0.66666666666666663],"xyz":[0.324991492626772238,0.22971030667988121,0.407536136191042508],"hpluv":[319.03138367428437,136.57661144398341,55.0424859024436],"hsluv":[319.03138367428437,48.8627280546895548,55.0424859024436]},"#bb66bb":{"lch":[55.7422560614222,66.7541112543564168,307.715012949244738],"luv":[55.7422560614222,40.8357821803987235,-52.8067255477370452],"rgb":[0.733333333333333282,0.4,0.733333333333333282],"xyz":[0.342129084734108913,0.236565343522815968,0.497794121289684255],"hpluv":[307.715012949244738,151.961230908585406,55.7422560614222],"hsluv":[307.715012949244738,52.5739577191036176,55.7422560614222]},"#bb66cc":{"lch":[56.5140206008290704,76.3075420390205466,299.031845144425],"luv":[56.5140206008290704,37.0317190732607671,-66.7195080506142801],"rgb":[0.733333333333333282,0.4,0.8],"xyz":[0.361421460177830611,0.24428229370030477,0.599400631959954411],"hpluv":[299.031845144425,171.336773989457299,56.5140206008290704],"hsluv":[299.031845144425,57.7422914315118732,56.5140206008290704]},"#bb66dd":{"lch":[57.3558903641351208,87.0819801731049523,292.529347086481266],"luv":[57.3558903641351208,33.3660351201831276,-80.4361794917420809],"rgb":[0.733333333333333282,0.4,0.866666666666666696],"xyz":[0.38293978572846421,0.252889623920558304,0.712730479859960409],"hpluv":[292.529347086481266,192.659130793538424,57.3558903641351208],"hsluv":[292.529347086481266,71.4699790991907,57.3558903641351208]},"#bb66ee":{"lch":[58.2655263288606164,98.4965661150924916,287.652756970849339],"luv":[58.2655263288606164,29.8688319231142287,-93.8585447149780805],"rgb":[0.733333333333333282,0.4,0.933333333333333348],"xyz":[0.40675196599463892,0.262414496027028321,0.838141295928483632],"hpluv":[287.652756970849339,214.510592558062115,58.2655263288606164],"hsluv":[287.652756970849339,85.5420625539119186,58.2655263288606164]},"#bb66ff":{"lch":[59.2402283004695533,110.175409569553764,283.948158265715847],"luv":[59.2402283004695533,26.5571064878979755,-106.926801919861816],"rgb":[0.733333333333333282,0.4,1],"xyz":[0.432923014404470341,0.272882915390961045,0.975975484220265477],"hpluv":[283.948158265715847,235.997431668916079,59.2402283004695533],"hsluv":[283.948158265715847,99.9999999999988205,59.2402283004695533]},"#997700":{"lch":[51.799451349173637,61.2288227532233265,61.7368019650066202],"luv":[51.799451349173637,28.9932293289078338,53.9292257391759406],"rgb":[0.6,0.466666666666666674,0],"xyz":[0.197331129475883132,0.19966620830666032,0.028146226367465537],"hpluv":[61.7368019650066202,149.992683828924328,51.799451349173637],"hsluv":[61.7368019650066202,100.000000000002373,51.799451349173637]},"#997711":{"lch":[51.8452237949875752,59.5195003520895298,61.1595916745536812],"luv":[51.8452237949875752,28.7105152364728049,52.1371003894409952],"rgb":[0.6,0.466666666666666674,0.0666666666666666657],"xyz":[0.198342794975520265,0.200070874506515173,0.0334743313322211702],"hpluv":[61.1595916745536812,145.676617799321178,51.8452237949875752],"hsluv":[61.1595916745536812,96.7355174862457687,51.8452237949875752]},"#997722":{"lch":[51.9299107218419778,56.4237897442973448,60.0184197539949],"luv":[51.9299107218419778,28.1961842142201746,48.8735024820856836],"rgb":[0.6,0.466666666666666674,0.133333333333333331],"xyz":[0.200218153113997266,0.200821017761906,0.0433512175282003628],"hpluv":[60.0184197539949,137.874516690543771,51.9299107218419778],"hsluv":[60.0184197539949,90.8032063934702762,51.9299107218419778]},"#997733":{"lch":[52.0688882655341843,51.532107019520943,57.9108306747127841],"luv":[52.0688882655341843,27.375836028403171,43.6591531710973797],"rgb":[0.6,0.466666666666666674,0.2],"xyz":[0.203305903846455027,0.2020561180548891,0.0596133713858115061],"hpluv":[57.9108306747127841,125.585333003110208,52.0688882655341843],"hsluv":[57.9108306747127841,81.359583819486275,52.0688882655341843]},"#997744":{"lch":[52.2685439893789265,44.9234500117750244,54.2507061045172563],"luv":[52.2685439893789265,26.2460613351246792,36.4590266649196622],"rgb":[0.6,0.466666666666666674,0.266666666666666663],"xyz":[0.207763899090673887,0.203839316152576694,0.0830921463386981446],"hpluv":[54.2507061045172563,109.061640425204757,52.2685439893789265],"hsluv":[54.2507061045172563,68.3925961892813632,52.2685439893789265]},"#997755":{"lch":[52.5337646967731615,36.9638675487782962,47.8040559904272229],"luv":[52.5337646967731615,24.8274523779219614,27.3847605902560787],"rgb":[0.6,0.466666666666666674,0.333333333333333315],"xyz":[0.213726313130035872,0.206224281768321527,0.11449419361267206],"hpluv":[47.8040559904272229,89.2849392346346,52.5337646967731615],"hsluv":[47.8040559904272229,52.1784042692219217,52.5337646967731615]},"#997766":{"lch":[52.8682223623880958,28.5307109293219519,35.7342712802299047],"luv":[52.8682223623880958,23.1593577603421643,16.6627012894371447],"rgb":[0.6,0.466666666666666674,0.4],"xyz":[0.221311308903544057,0.209258280077724818,0.154441838019816],"hpluv":[35.7342712802299047,68.4789688439394695,52.8682223623880958],"hsluv":[35.7342712802299047,33.2180784313787072,52.8682223623880958]},"#997777":{"lch":[53.2745272921510349,21.7835186536615062,12.1770506300626185],"luv":[53.2745272921510349,21.2933995119794766,4.59486911213486],"rgb":[0.6,0.466666666666666674,0.466666666666666674],"xyz":[0.230625321923745963,0.212983885285805641,0.203495639926213917],"hpluv":[12.1770506300626185,51.8857087556556777,53.2745272921510349],"hsluv":[12.1770506300626185,12.1864056638809046,53.2745272921510349]},"#997788":{"lch":[53.7543298043441524,21.0694932264164443,336.259644884191403],"luv":[53.7543298043441524,19.28657717102978,-8.48242216845644492],"rgb":[0.6,0.466666666666666674,0.533333333333333326],"xyz":[0.241765739025689819,0.217440052126583239,0.262168503329786085],"hpluv":[336.259644884191403,49.7370433553737143,53.7543298043441524],"hsluv":[336.259644884191403,17.3594920402921318,53.7543298043441524]},"#997799":{"lch":[54.308403390094881,28.1087123643927,307.715012949247921],"luv":[54.308403390094881,17.1950646022419384,-22.235769923906151],"rgb":[0.6,0.466666666666666674,0.6],"xyz":[0.254822703134762518,0.222662837770212396,0.330935180970904],"hpluv":[307.715012949247921,65.67699031054849,54.308403390094881],"hsluv":[307.715012949247921,22.7222383700086681,54.308403390094881]},"#9977aa":{"lch":[54.9367240193748785,39.361724048309469,292.510155009375],"luv":[54.9367240193748785,15.0695247856183894,-36.3628208860492137],"rgb":[0.6,0.466666666666666674,0.66666666666666663],"xyz":[0.269880396100015074,0.228685914956313491,0.41023903058790262],"hpluv":[292.510155009375,90.9181689788077847,54.9367240193748785],"hsluv":[292.510155009375,30.8964586946041671,54.9367240193748785]},"#9977bb":{"lch":[55.6385517902762388,52.2405182414828104,284.355371582691191],"luv":[55.6385517902762388,12.9522722169503091,-50.6093903397058824],"rgb":[0.6,0.466666666666666674,0.733333333333333282],"xyz":[0.287017988207351693,0.235540951799248249,0.500497015686544366],"hpluv":[284.355371582691191,119.143673365147691,55.6385517902762388],"hsluv":[284.355371582691191,44.025050152294007,55.6385517902762388]},"#9977cc":{"lch":[56.4125166695819615,65.6830300518217172,279.531250686135081],"luv":[56.4125166695819615,10.8761592408186605,-64.7763042860340192],"rgb":[0.6,0.466666666666666674,0.8],"xyz":[0.306310363651073447,0.243257901976737051,0.602103526356814522],"hpluv":[279.531250686135081,147.746441920881637,56.4125166695819615],"hsluv":[279.531250686135081,57.5215558896316352,56.4125166695819615]},"#9977dd":{"lch":[57.256707620000924,79.2159287347205,276.425234899334782],"luv":[57.256707620000924,8.86478593594131858,-78.718351962006011],"rgb":[0.6,0.466666666666666674,0.866666666666666696],"xyz":[0.327828689201707,0.251865232196990585,0.71543337425682052],"hpluv":[276.425234899334782,175.559960004438778,57.256707620000924],"hsluv":[276.425234899334782,71.3413917340773764,57.256707620000924]},"#9977ee":{"lch":[58.1687631275758434,92.5981917117116211,274.294200356840065],"luv":[58.1687631275758434,6.93354781471817905,-92.3382424728774822],"rgb":[0.6,0.466666666666666674,0.933333333333333348],"xyz":[0.351640869467881756,0.261390104303460602,0.840844190325343743],"hpluv":[274.294200356840065,202.000294664132923,58.1687631275758434],"hsluv":[274.294200356840065,85.4864748016987903,58.1687631275758434]},"#9977ff":{"lch":[59.1459606243173,105.700835267318482,272.760722153075335],"luv":[59.1459606243173,5.0910859147335179,-105.578157875659116],"rgb":[0.6,0.466666666666666674,1],"xyz":[0.377811917877713122,0.271858523667393326,0.978678378617125588],"hpluv":[272.760722153075335,226.773684284234889,59.1459606243173],"hsluv":[272.760722153075335,99.9999999999988,59.1459606243173]},"#bb7700":{"lch":[55.8465021194210323,78.9426527823167703,44.2288975260652037],"luv":[55.8465021194210323,56.5670601566064,55.0645996403160751],"rgb":[0.733333333333333282,0.466666666666666674,0],"xyz":[0.270895964056058,0.237598076137063796,0.0315945779884111572],"hpluv":[44.2288975260652037,179.372171604304526,55.8465021194210323],"hsluv":[44.2288975260652037,100.000000000002402,55.8465021194210323]},"#bb7711":{"lch":[55.8872675460691113,77.5581898683241775,43.5811171927028127],"luv":[55.8872675460691113,56.1830827877517081,53.4671303149482782],"rgb":[0.733333333333333282,0.466666666666666674,0.0666666666666666657],"xyz":[0.271907629555695085,0.238002742336918649,0.0369226829531667869],"hpluv":[43.5811171927028127,176.097874689063588,55.8872675460691113],"hsluv":[43.5811171927028127,97.2747266570755613,55.8872675460691113]},"#bb7722":{"lch":[55.9627137258116534,75.0570685818031365,42.3362918908129799],"luv":[55.9627137258116534,55.4825342436315907,50.549499878809371],"rgb":[0.733333333333333282,0.466666666666666674,0.133333333333333331],"xyz":[0.273782987694172142,0.238752885592309477,0.0467995691491459864],"hpluv":[42.3362918908129799,170.189263625481374,55.9627137258116534],"hsluv":[42.3362918908129799,92.3060252972229875,55.9627137258116534]},"#bb7733":{"lch":[56.086591241629975,71.12386069085467,40.1553843778465094],"luv":[56.086591241629975,54.3598535070873652,45.8651271257379562],"rgb":[0.733333333333333282,0.466666666666666674,0.2],"xyz":[0.276870738426629848,0.239987985885292576,0.0630617230067571366],"hpluv":[40.1553843778465094,160.914656808849855,56.086591241629975],"hsluv":[40.1553843778465094,84.3528141134219425,56.086591241629975]},"#bb7744":{"lch":[56.2646940492590346,65.8532423012147632,36.6949041745596887],"luv":[56.2646940492590346,52.8030258036740747,39.3508575199960617],"rgb":[0.733333333333333282,0.466666666666666674,0.266666666666666663],"xyz":[0.281328733670848763,0.24177118398298017,0.0865404979596437751],"hpluv":[36.6949041745596887,148.518490760970963,56.2646940492590346],"hsluv":[36.6949041745596887,73.3442464951488517,56.2646940492590346]},"#bb7755":{"lch":[56.5015366957073866,59.5720019456390375,31.4313823601585],"luv":[56.5015366957073866,50.8307220514796256,31.0654327434279267],"rgb":[0.733333333333333282,0.466666666666666674,0.333333333333333315],"xyz":[0.287291147710210748,0.244156149598725,0.117942545233617677],"hpluv":[31.4313823601585,133.789263155984059,56.5015366957073866],"hsluv":[31.4313823601585,59.433527841274838,56.5015366957073866]},"#bb7766":{"lch":[56.8006139195957758,52.9060784141758376,23.584548946691168],"luv":[56.8006139195957758,48.4868685528452588,21.1678225404983067],"rgb":[0.733333333333333282,0.466666666666666674,0.4],"xyz":[0.294876143483718933,0.247190147908128294,0.157890189640761625],"hpluv":[23.584548946691168,118.193030459121616,56.8006139195957758],"hsluv":[23.584548946691168,42.9582981176577476,56.8006139195957758]},"#bb7777":{"lch":[57.1645375630264851,46.8887603377642677,12.1770506300621175],"luv":[57.1645375630264851,45.8337848153679062,9.89040016939892652],"rgb":[0.733333333333333282,0.466666666666666674,0.466666666666666674],"xyz":[0.304190156503920839,0.250915753116209117,0.206943991547159534],"hpluv":[12.1770506300621175,104.083378979503351,57.1645375630264851],"hsluv":[12.1770506300621175,30.9338815185941769,57.1645375630264851]},"#bb7788":{"lch":[57.5951231639082408,43.0166042307866761,356.679907444569722],"luv":[57.5951231639082408,42.9444038116514264,-2.49126891562360298],"rgb":[0.733333333333333282,0.466666666666666674,0.533333333333333326],"xyz":[0.315330573605864639,0.255371919956986715,0.265616854950731729],"hpluv":[356.679907444569722,94.7741152880685149,57.5951231639082408],"hsluv":[356.679907444569722,32.9204937798227419,57.5951231639082408]},"#bb7799":{"lch":[58.0934559183715322,42.8683503206465062,338.533521874652],"luv":[58.0934559183715322,39.8946515879682408,-15.6879646190414519],"rgb":[0.733333333333333282,0.466666666666666674,0.6],"xyz":[0.328387537714937339,0.260594705600615872,0.334383532591849608],"hpluv":[338.533521874652,93.6373004736019823,58.0934559183715322],"hsluv":[338.533521874652,34.9811369830312131,58.0934559183715322]},"#bb77aa":{"lch":[58.6599497668646706,47.0820583870944276,321.324781752589786],"luv":[58.6599497668646706,36.7569990603765,-29.4218157502430451],"rgb":[0.733333333333333282,0.466666666666666674,0.66666666666666663],"xyz":[0.343445230680189895,0.266617782786717,0.413687382208848209],"hpluv":[321.324781752589786,101.848135129910219,58.6599497668646706],"hsluv":[321.324781752589786,37.0556810629478051,58.6599497668646706]},"#bb77bb":{"lch":[59.2944060970233693,54.9189596898792303,307.71501294924542],"luv":[59.2944060970233693,33.5958135510894706,-43.4443718479046765],"rgb":[0.733333333333333282,0.466666666666666674,0.733333333333333282],"xyz":[0.360582822787526569,0.273472819629651753,0.50394536730749],"hpluv":[307.71501294924542,117.529775077760561,59.2944060970233693],"hsluv":[307.71501294924542,40.6617226560308467,59.2944060970233693]},"#bb77cc":{"lch":[59.9960747587738155,65.1135012197087519,297.896140559284788],"luv":[59.9960747587738155,30.4646722292654815,-57.5471266620014177],"rgb":[0.733333333333333282,0.466666666666666674,0.8],"xyz":[0.379875198231248268,0.281189769807140555,0.605551877977760111],"hpluv":[297.896140559284788,137.716994859863917,59.9960747587738155],"hsluv":[297.896140559284788,53.5682479917909,59.9960747587738155]},"#bb77dd":{"lch":[60.7637179337253599,76.6332290650186394,290.953982706702106],"luv":[60.7637179337253599,27.4054240934965065,-71.5653165100750357],"rgb":[0.733333333333333282,0.466666666666666674,0.866666666666666696],"xyz":[0.401393523781881867,0.289797100027394061,0.718881725877766109],"hpluv":[290.953982706702106,160.033945707839,60.7637179337253599],"hsluv":[290.953982706702106,68.5485010485900119,60.7637179337253599]},"#bb77ee":{"lch":[61.5956761624293563,88.8082274030350902,285.979672103614405],"luv":[61.5956761624293563,24.4485758512518743,-85.3766267389077456],"rgb":[0.733333333333333282,0.466666666666666674,0.933333333333333348],"xyz":[0.425205704048056576,0.299321972133864078,0.844292541946289332],"hpluv":[285.979672103614405,182.954165183101395,61.5956761624293563],"hsluv":[285.979672103614405,84.0163684558434909,61.5956761624293563]},"#bb77ff":{"lch":[62.4899351736807773,101.23109143545085,282.328516880108566],"luv":[62.4899351736807773,21.6145233767131266,-98.8966442929694693],"rgb":[0.733333333333333282,0.466666666666666674,1],"xyz":[0.451376752457888,0.309790391497796802,0.982126730238071177],"hpluv":[282.328516880108566,205.562159598045383,62.4899351736807773],"hsluv":[282.328516880108566,99.9999999999986784,62.4899351736807773]},"#998800":{"lch":[56.4673516485332527,62.834492950420568,74.7562721675545561],"luv":[56.4673516485332527,16.5207966112614884,60.6237311922136897],"rgb":[0.6,0.533333333333333326,0],"xyz":[0.219403499200853586,0.243810947756601892,0.0355036829424554834],"hpluv":[74.7562721675545561,141.201731332299261,56.4673516485332527],"hsluv":[74.7562721675545561,100.000000000002331,56.4673516485332527]},"#998811":{"lch":[56.5074221469723881,61.2259080808398366,74.51872844438833],"luv":[56.5074221469723881,16.3426261455871646,59.0044946676862878],"rgb":[0.6,0.533333333333333326,0.0666666666666666657],"xyz":[0.220415164700490718,0.244215613956456745,0.0408317879072111131],"hpluv":[74.51872844438833,137.489352382480689,56.5074221469723881],"hsluv":[74.51872844438833,97.3110722480099781,56.5074221469723881]},"#998822":{"lch":[56.5815852437789744,58.2905156727598666,74.0508275651119],"luv":[56.5815852437789744,16.0173304476746452,56.0466711119068961],"rgb":[0.6,0.533333333333333326,0.133333333333333331],"xyz":[0.222290522838967719,0.244965757211847573,0.0507086741031903127],"hpluv":[74.0508275651119,130.726042229432494,56.5815852437789744],"hsluv":[74.0508275651119,92.4075523300517574,56.5815852437789744]},"#998833":{"lch":[56.7033645714083,53.5858970619529273,73.1917859227149],"luv":[56.7033645714083,15.4953822971072128,51.2966031175623911],"rgb":[0.6,0.533333333333333326,0.2],"xyz":[0.22537827357142548,0.246200857504830672,0.066970827960801449],"hpluv":[73.1917859227149,119.917068416956084,56.7033645714083],"hsluv":[73.1917859227149,84.5557602276611533,56.7033645714083]},"#998844":{"lch":[56.8784692361674189,47.0662938677721456,71.7105236832421156],"luv":[56.8784692361674189,14.7702533586865563,44.6886521856241927],"rgb":[0.6,0.533333333333333326,0.266666666666666663],"xyz":[0.22983626881564434,0.247984055602518266,0.0904496029136880875],"hpluv":[71.7105236832421156,105.00293267331034,56.8784692361674189],"hsluv":[71.7105236832421156,73.6816499137771075,56.8784692361674189]},"#998855":{"lch":[57.1113583918905761,38.8337969655052433,69.1066660847648393],"luv":[57.1113583918905761,13.8492700909341142,36.2803184206870242],"rgb":[0.6,0.533333333333333326,0.333333333333333315],"xyz":[0.235798682855006325,0.250369021218263099,0.121851650187662],"hpluv":[69.1066660847648393,86.2832891510872599,57.1113583918905761],"hsluv":[69.1066660847648393,59.9309888570698774,57.1113583918905761]},"#998866":{"lch":[57.4054971647218224,29.1657433305745144,64.0747883902216],"luv":[57.4054971647218224,12.7511922431808031,26.2306629806110223],"rgb":[0.6,0.533333333333333326,0.4],"xyz":[0.24338367862851451,0.253403019527666418,0.161799294594805965],"hpluv":[64.0747883902216,64.4701815948561574,57.4054971647218224],"hsluv":[64.0747883902216,43.6310875702010321,57.4054971647218224]},"#998877":{"lch":[57.7634914296009612,18.7238256654584347,52.0945218145914097],"luv":[57.7634914296009612,11.5031815844705712,14.773573060880608],"rgb":[0.6,0.533333333333333326,0.466666666666666674],"xyz":[0.252697691648716416,0.257128624735747213,0.210853096501203874],"hpluv":[52.0945218145914097,41.1320618043462858,57.7634914296009612],"hsluv":[52.0945218145914097,25.2418236256697028,57.7634914296009612]},"#998888":{"lch":[58.1871725604667489,10.3706980586515272,12.1770506300640946],"luv":[58.1871725604667489,10.1373621264743505,2.18752539195365081],"rgb":[0.6,0.533333333333333326,0.533333333333333326],"xyz":[0.263838108750660272,0.261584791576524811,0.269525959904776],"hpluv":[12.1770506300640946,22.6162221883482317,58.1871725604667489],"hsluv":[12.1770506300640946,7.14421708061451799,58.1871725604667489]},"#998899":{"lch":[58.6776613659523605,14.2013195506443459,307.715012949254117],"luv":[58.6776613659523605,8.6874348403017283,-11.2341422847952668],"rgb":[0.6,0.533333333333333326,0.6],"xyz":[0.276895072859732971,0.266807577220153969,0.338292637545893948],"hpluv":[307.715012949254117,30.7110899398720818,58.6776613659523605],"hsluv":[307.715012949254117,10.6251017733449729,58.6776613659523605]},"#9988aa":{"lch":[59.2354248002074399,26.2127450059066938,285.910383521223935],"luv":[59.2354248002074399,7.18579172527609789,-25.2085778659891844],"rgb":[0.6,0.533333333333333326,0.66666666666666663],"xyz":[0.291952765824985527,0.272830654406255091,0.417596487162892549],"hpluv":[285.910383521223935,56.1526584479988173,59.2354248002074399],"hsluv":[285.910383521223935,23.5088603674401817,59.2354248002074399]},"#9988bb":{"lch":[59.8603319378123189,39.8857557696632696,278.160160819701673],"luv":[59.8603319378123189,5.66141142610705117,-39.4819190767314581],"rgb":[0.6,0.533333333333333326,0.733333333333333282],"xyz":[0.309090357932322146,0.279685691249189849,0.507854472261534351],"hpluv":[278.160160819701673,84.5508603994872,59.8603319378123189],"hsluv":[278.160160819701673,37.7262541103550291,59.8603319378123189]},"#9988cc":{"lch":[60.55171199345871,53.9990869041691823,274.395593429514747],"luv":[60.55171199345871,4.13861667015410095,-53.8402566723222264],"rgb":[0.6,0.533333333333333326,0.8],"xyz":[0.3283827333760439,0.287402641426678651,0.609460982931804507],"hpluv":[274.395593429514747,113.161661700826286,60.55171199345871],"hsluv":[274.395593429514747,52.5240219153236723,60.55171199345871]},"#9988dd":{"lch":[61.3084150605589855,68.1648195931338563,272.216747448240312],"luv":[61.3084150605589855,2.63660773112319324,-68.1138086575451],"rgb":[0.6,0.533333333333333326,0.866666666666666696],"xyz":[0.349901058926677444,0.296009971646932157,0.722790830831810505],"hpluv":[272.216747448240312,141.084572716849891,61.3084150605589855],"hsluv":[272.216747448240312,67.8395486149695,61.3084150605589855]},"#9988ee":{"lch":[62.128875020953032,82.18421866163294,270.815422264053723],"luv":[62.128875020953032,1.1695901512833331,-82.1758958326656597],"rgb":[0.6,0.533333333333333326,0.933333333333333348],"xyz":[0.373713239192852154,0.305534843753402174,0.848201646900333728],"hpluv":[270.815422264053723,167.854994169255662,62.128875020953032],"hsluv":[270.815422264053723,83.6558877567472905,62.128875020953032]},"#9988ff":{"lch":[63.0111734122257303,95.9388777898474387,269.8490772999765],"luv":[63.0111734122257303,-0.252712116882344406,-95.9385449554102],"rgb":[0.6,0.533333333333333326,1],"xyz":[0.399884287602683575,0.316003263117334898,0.986035835192115462],"hpluv":[269.8490772999765,193.204124490752207,63.0111734122257303],"hsluv":[269.8490772999765,99.9999999999985363,63.0111734122257303]},"#bb8800":{"lch":[60.0458653136574,74.8864062555341832,55.056379834278971],"luv":[60.0458653136574,42.8926945435799,61.3855894869476728],"rgb":[0.733333333333333282,0.533333333333333326,0],"xyz":[0.292968333781028434,0.281742815587005313,0.038952034563401107],"hpluv":[55.056379834278971,158.255644288368103,60.0458653136574],"hsluv":[55.056379834278971,100.000000000002288,60.0458653136574]},"#bb8811":{"lch":[60.0822560315187957,73.5298298886522161,54.5759299869630823],"luv":[60.0822560315187957,42.619621560372849,59.9183089005750773],"rgb":[0.733333333333333282,0.533333333333333326,0.0666666666666666657],"xyz":[0.293979999280665538,0.282147481786860166,0.0442801395281567367],"hpluv":[54.5759299869630823,155.294707870281485,60.0822560315187957],"hsluv":[54.5759299869630823,97.6878818876268866,60.0822560315187957]},"#bb8822":{"lch":[60.1496227929862499,71.0610449842002367,53.6488709316330343],"luv":[60.1496227929862499,42.1201645307819774,57.2325419158225586],"rgb":[0.733333333333333282,0.533333333333333326,0.133333333333333331],"xyz":[0.295855357419142595,0.282897625042250966,0.0541570257241359362],"hpluv":[53.6488709316330343,149.912555699661567,60.1496227929862499],"hsluv":[53.6488709316330343,93.46183514856709,60.1496227929862499]},"#bb8833":{"lch":[60.2602822329103844,67.1261991777524,52.0115270519145412],"luv":[60.2602822329103844,41.3163720666953154,52.9044801061090197],"rgb":[0.733333333333333282,0.533333333333333326,0.2],"xyz":[0.298943108151600301,0.284132725335234093,0.0704191795817470795],"hpluv":[52.0115270519145412,141.351435183858257,60.2602822329103844],"hsluv":[52.0115270519145412,86.668700859176,60.2602822329103844]},"#bb8844":{"lch":[60.4194844691316746,61.7320119628667285,49.374045706205429],"luv":[60.4194844691316746,40.1948297943626258,46.8531424643613406],"rgb":[0.733333333333333282,0.533333333333333326,0.266666666666666663],"xyz":[0.303401103395819216,0.285915923432921659,0.093897954534633718],"hpluv":[49.374045706205429,129.650066203053939,60.4194844691316746],"hsluv":[49.374045706205429,77.207197386412,60.4194844691316746]},"#bb8855":{"lch":[60.6313805732006585,55.0590005000961682,45.2500033552910708],"luv":[60.6313805732006585,38.7623447760430935,39.1020992215604082],"rgb":[0.733333333333333282,0.533333333333333326,0.333333333333333315],"xyz":[0.309363517435181201,0.28830088904866652,0.125300001808607619],"hpluv":[45.2500033552910708,115.231228654446355,60.6313805732006585],"hsluv":[45.2500033552910708,65.1528926573884775,60.6313805732006585]},"#bb8866":{"lch":[60.8992588402534949,47.519038379270981,38.7816256818529581],"luv":[60.8992588402534949,37.0429375720225096,29.7637327048519147],"rgb":[0.733333333333333282,0.533333333333333326,0.4],"xyz":[0.316948513208689386,0.291334887358069838,0.165247646215751581],"hpluv":[38.7816256818529581,99.0136254476035305,60.8992588402534949],"hsluv":[38.7816256818529581,50.7321114426118,60.8992588402534949]},"#bb8877":{"lch":[61.2256685857267087,39.8992767652027354,28.4701407483744688],"luv":[61.2256685857267087,35.0740840991728362,19.0200134329710231],"rgb":[0.733333333333333282,0.533333333333333326,0.466666666666666674],"xyz":[0.326262526228891292,0.295060492566150634,0.21430144812214949],"hpluv":[28.4701407483744688,82.6933933486175761,61.2256685857267087],"hsluv":[28.4701407483744688,34.2887258466009897,61.2256685857267087]},"#bb8888":{"lch":[61.6124959728340684,33.6595928281588499,12.1770506300623627],"luv":[61.6124959728340684,32.9022674846918903,7.09992843085263114],"rgb":[0.733333333333333282,0.533333333333333326,0.533333333333333326],"xyz":[0.337402943330835092,0.299516659406928232,0.272974311525721658],"hpluv":[12.1770506300623627,69.3233245158679,61.6124959728340684],"hsluv":[12.1770506300623627,26.8235367690150284,61.6124959728340684]},"#bb8899":{"lch":[62.0610184830546388,31.1131530731089718,349.361203223606594],"luv":[62.0610184830546388,30.5783355372127765,-5.74401339869088723],"rgb":[0.733333333333333282,0.533333333333333326,0.6],"xyz":[0.350459907439907847,0.304739445050557389,0.341740989166839593],"hpluv":[349.361203223606594,63.6157209963685091,62.0610184830546388],"hsluv":[349.361203223606594,28.7433747177793393,62.0610184830546388]},"#bb88aa":{"lch":[62.5719506337331097,34.1093853871598185,325.627133749050586],"luv":[62.5719506337331097,28.1532372220531357,-19.2573467904743723],"rgb":[0.733333333333333282,0.533333333333333326,0.66666666666666663],"xyz":[0.365517600405160348,0.310762522236658512,0.421044838783838193],"hpluv":[325.627133749050586,69.1725086761469328,62.5719506337331097],"hsluv":[325.627133749050586,30.7007491098828176,62.5719506337331097]},"#bb88bb":{"lch":[63.1454872588298,41.9701566603395477,307.715012949246614],"luv":[63.1454872588298,25.674586077978244,-33.2010493782640808],"rgb":[0.733333333333333282,0.533333333333333326,0.733333333333333282],"xyz":[0.382655192512497,0.31761755907959327,0.51130282388247994],"hpluv":[307.715012949246614,84.3407770596407,63.1454872588298],"hsluv":[307.715012949246614,32.6446535119142354,63.1454872588298]},"#bb88cc":{"lch":[63.7813474201422,52.7335158558763055,296.081540752202443],"luv":[63.7813474201422,23.1842810338905281,-47.3636232510092228],"rgb":[0.733333333333333282,0.533333333333333326,0.8],"xyz":[0.401947567956218776,0.325334509257082072,0.612909334552750096],"hpluv":[296.081540752202443,104.913738848088499,63.7813474201422],"hsluv":[296.081540752202443,48.441096457031712,63.7813474201422]},"#bb88dd":{"lch":[64.4788201663492089,64.9599578897110916,288.597779393076337],"luv":[64.4788201663492089,20.7171971389296665,-61.56779898404492],"rgb":[0.733333333333333282,0.533333333333333326,0.866666666666666696],"xyz":[0.423465893506852264,0.333941839477335578,0.726239182452756094],"hpluv":[288.597779393076337,127.840358269428478,64.4788201663492089],"hsluv":[288.597779393076337,64.9415793589177,64.4788201663492089]},"#bb88ee":{"lch":[65.2368122498474463,77.8541115668441392,283.595470556329246],"luv":[65.2368122498474463,18.300798164755431,-75.6726071600252084],"rgb":[0.733333333333333282,0.533333333333333326,0.933333333333333348],"xyz":[0.44727807377302703,0.343466711583805595,0.851649998521279317],"hpluv":[283.595470556329246,151.435657753316406,65.2368122498474463],"hsluv":[283.595470556329246,82.1213401763518789,65.2368122498474463]},"#bb88ff":{"lch":[66.0538972531437452,90.9819525935223652,280.100148709787334],"luv":[66.0538972531437452,15.9554396417090967,-89.5719802369565201],"rgb":[0.733333333333333282,0.533333333333333326,1],"xyz":[0.473449122182858395,0.353935130947738319,0.989484186813061162],"hpluv":[280.100148709787334,174.781769995450787,66.0538972531437452],"hsluv":[280.100148709787334,99.99999999999838,66.0538972531437452]},"#999900":{"lch":[61.2683639221826866,67.5422828804358772,85.8743202181747449],"luv":[61.2683639221826866,4.85929488236129092,67.3672563635114869],"rgb":[0.6,0.6,0],"xyz":[0.245273099653321058,0.295550148661537559,0.0441268830932777384],"hpluv":[85.8743202181747449,139.887458074797593,61.2683639221826866],"hsluv":[85.8743202181747449,100.000000000002359,61.2683639221826866]},"#999911":{"lch":[61.3036130280217861,66.0751339072958785,85.8743202181746881],"luv":[61.3036130280217861,4.75374160235953358,65.9039093047224185],"rgb":[0.6,0.6,0.0666666666666666657],"xyz":[0.24628476515295819,0.295954814861392412,0.0494549880580333681],"hpluv":[85.8743202181746881,136.770144995815713,61.3036130280217861],"hsluv":[85.8743202181746881,97.7715564197957718,61.3036130280217861]},"#999922":{"lch":[61.3688705786650104,63.38848415762304,85.8743202181745744],"luv":[61.3688705786650104,4.56045196477970372,63.2242216375825663],"rgb":[0.6,0.6,0.133333333333333331],"xyz":[0.248160123291435192,0.296704958116783213,0.0593318742540125676],"hpluv":[85.8743202181745744,131.069475710796667,61.3688705786650104],"hsluv":[85.8743202181745744,93.6963738669960691,61.3688705786650104]},"#999933":{"lch":[61.4760769955270945,59.0559618954583243,85.8743202181743754],"luv":[61.4760769955270945,4.24875087387181871,58.9029265097210484],"rgb":[0.6,0.6,0.2],"xyz":[0.251247874023892925,0.29794005840976634,0.0755940281116237178],"hpluv":[85.8743202181743754,121.898097720990123,61.4760769955270945],"hsluv":[85.8743202181743754,87.1401192062652683,61.4760769955270945]},"#999944":{"lch":[61.6303367515695,52.9921690524208,85.8743202181739775],"luv":[61.6303367515695,3.81249440942850049,52.8548471500809569],"rgb":[0.6,0.6,0.266666666666666663],"xyz":[0.255705869268111841,0.299723256507453906,0.0990728030645103563],"hpluv":[85.8743202181739775,109.10797160418339,61.6303367515695],"hsluv":[85.8743202181739775,77.9969649215058,61.6303367515695]},"#999955":{"lch":[61.8357003743425935,45.2147461889200173,85.8743202181734517],"luv":[61.8357003743425935,3.25295171251598125,45.0975784059909],"rgb":[0.6,0.6,0.333333333333333315],"xyz":[0.261668283307473826,0.302108222123198766,0.130474850338484272],"hpluv":[85.8743202181734517,92.7855058259100218,61.8357003743425935],"hsluv":[85.8743202181734517,66.3286810003367577,61.8357003743425935]},"#999966":{"lch":[62.0953945325949377,35.8293841981041083,85.874320218172457],"luv":[62.0953945325949377,2.57772666020637553,35.7365372872164784],"rgb":[0.6,0.6,0.4],"xyz":[0.269253279080982,0.305142220432602085,0.170422494745628206],"hpluv":[85.874320218172457,73.2182390722606,62.0953945325949377],"hsluv":[85.874320218172457,52.3408174542086542,62.0953945325949377]},"#999977":{"lch":[62.4119425079225749,25.0116267171883422,85.8743202181703],"luv":[62.4119425079225749,1.79944864939855109,24.9468125338318],"rgb":[0.6,0.6,0.466666666666666674],"xyz":[0.278567292101183916,0.30886782564068288,0.219476296652026115],"hpluv":[85.8743202181703,50.8526471570801775,62.4119425079225749],"hsluv":[85.8743202181703,36.3525421484824918,62.4119425079225749]},"#999988":{"lch":[62.7872374999600567,12.9853368609797517,85.8743202181639589],"luv":[62.7872374999600567,0.934223397011331502,12.9516871502363],"rgb":[0.6,0.6,0.533333333333333326],"xyz":[0.289707709203127717,0.313323992481460478,0.27814916005559831],"hpluv":[85.8743202181639589,26.2434647477884546,62.7872374999600567],"hsluv":[85.8743202181639589,18.7604129126121961,62.7872374999600567]},"#999999":{"lch":[63.2225945523589843,3.33307052034688283e-12,0],"luv":[63.2225945523589843,3.14807442966336163e-12,1.09498241031769098e-12],"rgb":[0.6,0.6,0.6],"xyz":[0.302764673312200472,0.318546778125089636,0.346915837696716189],"hpluv":[0,6.68977504875838914e-12,63.2225945523589843],"hsluv":[0,3.10313074237261963e-12,63.2225945523589843]},"#9999aa":{"lch":[63.7187933641432238,13.6904464527836414,265.874320218190064],"luv":[63.7187933641432238,-0.984952144759020598,-13.6549695477167123],"rgb":[0.6,0.6,0.66666666666666663],"xyz":[0.317822366277453,0.324569855311190758,0.42621968731371479],"hpluv":[265.874320218190064,27.2639887848552753,63.7187933641432238],"hsluv":[265.874320218190064,14.5770868731616492,63.7187933641432238]},"#9999bb":{"lch":[64.276118203606174,27.8450519356751158,265.874320218183641],"luv":[64.276118203606174,-2.00329797275791854,-27.7728953213882335],"rgb":[0.6,0.6,0.733333333333333282],"xyz":[0.334959958384789647,0.331424892154125517,0.516477672412356537],"hpluv":[265.874320218183641,54.9715165011475904,64.276118203606174],"hsluv":[265.874320218183641,30.0955931685464577,64.276118203606174]},"#9999cc":{"lch":[64.8943980299807635,42.2483295275786332,265.874320218181538],"luv":[64.8943980299807635,-3.03953438803302189,-42.138848804575062],"rgb":[0.6,0.6,0.8],"xyz":[0.354252333828511401,0.339141842331614318,0.618084183082626692],"hpluv":[265.874320218181538,82.6117192029769,64.8943980299807635],"hsluv":[265.874320218181538,46.4456834766813316,64.8943980299807635]},"#9999dd":{"lch":[65.5730481583578353,56.7175687031348,265.874320218180458],"luv":[65.5730481583578353,-4.08051637559571567,-56.570592941061804],"rgb":[0.6,0.6,0.866666666666666696],"xyz":[0.375770659379144889,0.347749172551867824,0.73141403098263269],"hpluv":[265.874320218180458,109.756831209262941,65.5730481583578353],"hsluv":[265.874320218180458,63.5568222493012627,65.5730481583578353]},"#9999ee":{"lch":[66.311113738117,71.1055788100052695,265.874320218179832],"luv":[66.311113738117,-5.11565437949467672,-70.9213185027987691],"rgb":[0.6,0.6,0.933333333333333348],"xyz":[0.399582839645319654,0.357274044658337842,0.856824847051155913],"hpluv":[265.874320218179832,136.068212717368169,66.311113738117],"hsluv":[265.874320218179832,81.4020980414818922,66.311113738117]},"#9999ff":{"lch":[67.1073146704137145,85.2999068143523829,265.874320218179378],"luv":[67.1073146704137145,-6.13685802391602486,-85.0788638624864149],"rgb":[0.6,0.6,1],"xyz":[0.425753888055151,0.367742464022270565,0.994659035342937758],"hpluv":[265.874320218179378,161.293929533565688,67.1073146704137145],"hsluv":[265.874320218179378,99.9999999999983,67.1073146704137145]},"#bb9900":{"lch":[64.4418646198176219,74.1135014806344117,66.2793330800256228],"luv":[64.4418646198176219,29.8142337654579457,67.8522112145111],"rgb":[0.733333333333333282,0.6,0],"xyz":[0.318837934233495934,0.333482016491941036,0.047575234714223362],"hpluv":[66.2793330800256228,145.938057142603384,64.4418646198176219],"hsluv":[66.2793330800256228,100.000000000002416,64.4418646198176219]},"#bb9911":{"lch":[64.4743890579801331,72.806990252212529,65.9899074816349],"luv":[64.4743890579801331,29.6249863695688624,66.5072778888794147],"rgb":[0.733333333333333282,0.6,0.0666666666666666657],"xyz":[0.319849599733133039,0.333886682691795889,0.0529033396789789917],"hpluv":[65.9899074816349,143.29306400111571,64.4743890579801331],"hsluv":[65.9899074816349,98.0367215419372542,64.4743890579801331]},"#bb9922":{"lch":[64.5346112536789,70.4161712525116599,65.4311312102869636],"luv":[64.5346112536789,29.2781077929992222,64.0408430450799671],"rgb":[0.733333333333333282,0.6,0.133333333333333331],"xyz":[0.321724957871610096,0.334636825947186689,0.0627802258749581843],"hpluv":[65.4311312102869636,138.458312961065701,64.5346112536789],"hsluv":[65.4311312102869636,94.4406497380354892,64.5346112536789]},"#bb9933":{"lch":[64.6335704733000398,66.566957174521292,64.4427367566729146],"luv":[64.6335704733000398,28.7178476591491503,60.0536844273559396],"rgb":[0.733333333333333282,0.6,0.2],"xyz":[0.324812708604067801,0.335871926240169816,0.0790423797325693345],"hpluv":[64.4427367566729146,130.689255588928205,64.6335704733000398],"hsluv":[64.4427367566729146,88.6394107340449153,64.6335704733000398]},"#bb9944":{"lch":[64.7760175449466828,61.1991201001527685,62.8442649593615386],"luv":[64.7760175449466828,27.9319304868930693,54.4530950480162872],"rgb":[0.733333333333333282,0.6,0.266666666666666663],"xyz":[0.329270703848286717,0.337655124337857382,0.102521154685455973],"hpluv":[62.8442649593615386,119.886494259466,64.7760175449466828],"hsluv":[62.8442649593615386,80.5164965868838607,64.7760175449466828]},"#bb9955":{"lch":[64.965753761967747,54.3684881208399204,60.3198292286154],"luv":[64.965753761967747,26.9209928274273445,47.235501963369849],"rgb":[0.733333333333333282,0.6,0.333333333333333315],"xyz":[0.335233117887648702,0.340040089953602243,0.133923201959429888],"hpluv":[60.3198292286154,106.194518749025775,64.965753761967747],"hsluv":[60.3198292286154,70.0945405394646883,64.965753761967747]},"#bb9966":{"lch":[65.2058459998609,46.2670609228556557,56.2614414361724258],"luv":[65.2058459998609,25.6969192719684436,38.4747874116176689],"rgb":[0.733333333333333282,0.6,0.4],"xyz":[0.342818113661156887,0.343074088263005561,0.17387084636657385],"hpluv":[56.2614414361724258,90.0377647384168,65.2058459998609],"hsluv":[56.2614414361724258,57.5177389460533064,65.2058459998609]},"#bb9977":{"lch":[65.4987393303808147,37.2952826673053153,49.3796729345645886],"luv":[65.4987393303808147,24.280853083902965,28.3086255892461871],"rgb":[0.733333333333333282,0.6,0.466666666666666674],"xyz":[0.352132126681358792,0.346799693471086357,0.222924648272971759],"hpluv":[49.3796729345645886,72.2537327682772172,65.4987393303808147],"hsluv":[49.3796729345645886,43.0302399575574199,65.4987393303808147]},"#bb9988":{"lch":[65.8463246780106601,28.3139420599436384,36.7022131699001193],"luv":[65.8463246780106601,22.7007755052872291,16.9220006628175241],"rgb":[0.733333333333333282,0.6,0.533333333333333326],"xyz":[0.363272543783302593,0.351255860311863954,0.281597511676543899],"hpluv":[36.7022131699001193,54.564242001153282,65.8463246780106601],"hsluv":[36.7022131699001193,26.9495650592517677,65.8463246780106601]},"#bb9999":{"lch":[66.2499853133799377,21.4719543680734333,12.1770506300627517],"luv":[66.2499853133799377,20.9888452793887552,4.52914983440691099],"rgb":[0.733333333333333282,0.6,0.6],"xyz":[0.376329507892375292,0.356478645955493112,0.350364189317661834],"hpluv":[12.1770506300627517,41.1268186121042731,66.2499853133799377],"hsluv":[12.1770506300627517,20.948078856310218,66.2499853133799377]},"#bb99aa":{"lch":[66.7106335886793715,21.0368039825091344,335.738246937474969],"luv":[66.7106335886793715,19.1787866223333445,-8.64414631375011489],"rgb":[0.733333333333333282,0.6,0.66666666666666663],"xyz":[0.391387200857627848,0.362501723141594234,0.429668038934660435],"hpluv":[335.738246937474969,40.0151105801343192,66.7106335886793715],"hsluv":[335.738246937474969,22.766845509204984,66.7106335886793715]},"#bb99bb":{"lch":[67.2287438260669887,28.2861274819753,307.715012949249171],"luv":[67.2287438260669887,17.3035955220760833,-22.3761165070024362],"rgb":[0.733333333333333282,0.6,0.733333333333333282],"xyz":[0.408524792964964523,0.369356759984529,0.519926024033302125],"hpluv":[307.715012949249171,53.3897422679679323,67.2287438260669887],"hsluv":[307.715012949249171,24.5905380245485432,67.2287438260669887]},"#bb99cc":{"lch":[67.8043844715017343,39.5775547497090656,292.889275489017223],"luv":[67.8043844715017343,15.393749985076461,-36.4611478338680044],"rgb":[0.733333333333333282,0.6,0.8],"xyz":[0.427817168408686221,0.377073710162017794,0.621532534703572281],"hpluv":[292.889275489017223,74.0679810995506642,67.8043844715017343],"hsluv":[292.889275489017223,42.0187450252511,67.8043844715017343]},"#bb99dd":{"lch":[68.4372510447458353,52.4777928084534082,284.879936967142157],"luv":[68.4372510447458353,13.4760025497769718,-50.718005612655638],"rgb":[0.733333333333333282,0.6,0.866666666666666696],"xyz":[0.449335493959319821,0.385681040382271301,0.734862382603578279],"hpluv":[284.879936967142157,97.3021261982971737,68.4372510447458353],"hsluv":[284.879936967142157,60.4059975969609724,68.4372510447458353]},"#bb99ee":{"lch":[69.1267004581107898,66.0165196934359244,280.096152477623832],"luv":[69.1267004581107898,11.5727364631099334,-64.9942508472035456],"rgb":[0.733333333333333282,0.6,0.933333333333333348],"xyz":[0.47314767422549453,0.395205912488741318,0.860273198672101502],"hpluv":[280.096152477623832,121.184234531677617,69.1267004581107898],"hsluv":[280.096152477623832,79.7264365589122548,69.1267004581107898]},"#bb99ff":{"lch":[69.8717866786541,79.7596884688517207,276.986638727898821],"luv":[69.8717866786541,9.70179942494587877,-79.1674364405365765],"rgb":[0.733333333333333282,0.6,1],"xyz":[0.499318722635325951,0.405674331852674042,0.998107386963883347],"hpluv":[276.986638727898821,144.850809586534439,69.8717866786541],"hsluv":[276.986638727898821,99.9999999999980247,69.8717866786541]},"#880000":{"lch":[27.3946073685119416,92.1289276169810876,12.1770506300617765],"luv":[27.3946073685119416,90.0560691570773,19.4330571920800175],"rgb":[0.533333333333333326,0,0],"xyz":[0.101531161901381561,0.0523520053554009795,0.00475927321412716],"hpluv":[12.1770506300617765,426.746789183125316,27.3946073685119416],"hsluv":[12.1770506300617765,100.000000000002245,27.3946073685119416]},"#880011":{"lch":[27.5061298630582485,89.4551794237446529,10.4692299831444977],"luv":[27.5061298630582485,87.9659862388495242,16.254672889999533],"rgb":[0.533333333333333326,0,0.0666666666666666657],"xyz":[0.10254282740101868,0.0527566715552558324,0.0100873781788827915],"hpluv":[10.4692299831444977,412.68181181873,27.5061298630582485],"hsluv":[10.4692299831444977,99.9999999999965,27.5061298630582485]},"#880022":{"lch":[27.711363673312789,85.0234292319238421,7.23413932290422057],"luv":[27.711363673312789,84.3466296586470463,10.7065206104973338],"rgb":[0.533333333333333326,0,0.133333333333333331],"xyz":[0.104418185539495709,0.0535068148106466537,0.0199642643748619876],"hpluv":[7.23413932290422057,389.331950846774873,27.711363673312789],"hsluv":[7.23413932290422057,99.9999999999967,27.711363673312789]},"#880033":{"lch":[28.0451389930846,79.0521177396887396,1.75350406004841131],"luv":[28.0451389930846,79.0150993176991392,2.41896650323101259],"rgb":[0.533333333333333326,0,0.2],"xyz":[0.107505936271953442,0.0547419151036297666,0.0362264182324731343],"hpluv":[1.75350406004841131,357.680479105960103,28.0451389930846],"hsluv":[1.75350406004841131,99.9999999999969589,28.0451389930846]},"#880044":{"lch":[28.5182895144164306,72.8806899851902585,353.674121255230034],"luv":[28.5182895144164306,72.4369406321056459,-8.0302306678086488],"rgb":[0.533333333333333326,0,0.266666666666666663],"xyz":[0.111963931516172316,0.0565251132013173396,0.0597051931853597728],"hpluv":[353.674121255230034,324.286096087098713,28.5182895144164306],"hsluv":[353.674121255230034,99.9999999999972857,28.5182895144164306]},"#880055":{"lch":[29.1358047874334787,68.1690091719341922,343.056201782139055],"luv":[29.1358047874334787,65.2098664506571453,-19.866734230132252],"rgb":[0.533333333333333326,0,0.333333333333333315],"xyz":[0.117926345555534315,0.0589100788170621725,0.0911072404593336743],"hpluv":[343.056201782139055,296.892542908362316,29.1358047874334787],"hsluv":[343.056201782139055,99.9999999999977405,29.1358047874334787]},"#880066":{"lch":[29.8977347275108087,66.3157421691867768,330.790160549998632],"luv":[29.8977347275108087,57.8829185884671915,-32.3627161272186115],"rgb":[0.533333333333333326,0,0.4],"xyz":[0.125511341329042486,0.0619440771264654841,0.13105488486647765],"hpluv":[330.790160549998632,281.460643767249167,29.8977347275108087],"hsluv":[330.790160549998632,99.9999999999981384,29.8977347275108087]},"#880077":{"lch":[30.8000475559674527,67.8890879971799,318.512376228514142],"luv":[30.8000475559674527,50.8556366042998462,-44.9736866918894549],"rgb":[0.533333333333333326,0,0.466666666666666674],"xyz":[0.13482535434924442,0.0656696823345463,0.180108686772875559],"hpluv":[318.512376228514142,279.697068124812404,30.8000475559674527],"hsluv":[318.512376228514142,99.9999999999984652,30.8000475559674527]},"#880088":{"lch":[31.8355421357531156,72.5162027692933862,307.715012949243601],"luv":[31.8355421357531156,44.3606514294377803,-57.3649045046986288],"rgb":[0.533333333333333326,0,0.533333333333333326],"xyz":[0.14596577145118822,0.0701258491753239,0.238781550176447727],"hpluv":[307.715012949243601,289.042783730483279,31.8355421357531156],"hsluv":[307.715012949243601,99.9999999999987921,31.8355421357531156]},"#880099":{"lch":[32.9947769935272675,79.3376809512942,299.026215263792551],"luv":[32.9947769935272675,38.4954159686478121,-69.3726932454703444],"rgb":[0.533333333333333326,0,0.6],"xyz":[0.159022735560260947,0.0753486348189530558,0.307548227817565634],"hpluv":[299.026215263792551,305.122076286487129,32.9947769935272675],"hsluv":[299.026215263792551,99.9999999999991189,32.9947769935272675]},"#8800aa":{"lch":[34.2669429307518527,87.5167556566874651,292.341813883439613],"luv":[34.2669429307518527,33.2678552259606306,-80.9470958672197298],"rgb":[0.533333333333333326,0,0.66666666666666663],"xyz":[0.174080428525513475,0.0813717120050541642,0.386852077434564234],"hpluv":[292.341813883439613,324.082197305514,34.2669429307518527],"hsluv":[292.341813883439613,99.9999999999993605,34.2669429307518527]},"#8800bb":{"lch":[35.6406160405817047,96.4510237672048589,287.271351738157534],"luv":[35.6406160405817047,28.6360630376966157,-92.1019862947753296],"rgb":[0.533333333333333326,0,0.733333333333333282],"xyz":[0.19121802063285015,0.0882267488479889228,0.477110062533206],"hpluv":[287.271351738157534,343.400533998367337,35.6406160405817047],"hsluv":[287.271351738157534,99.999999999999531,35.6406160405817047]},"#8800cc":{"lch":[37.1043554501127346,105.765919518381835,283.413875530142832],"luv":[37.1043554501127346,24.5359458020369345,-102.880596300606314],"rgb":[0.533333333333333326,0,0.8],"xyz":[0.210510396076571876,0.0959436990254777244,0.578716573203476137],"hpluv":[283.413875530142832,361.709723992276565,37.1043554501127346],"hsluv":[283.413875530142832,99.9999999999998,37.1043554501127346]},"#8800dd":{"lch":[38.6471386159700145,115.245648848701009,280.44740978906907],"luv":[38.6471386159700145,20.8978330626497737,-113.335079087825761],"rgb":[0.533333333333333326,0,0.866666666666666696],"xyz":[0.23202872162720542,0.104551029245731258,0.692046421103482134],"hpluv":[280.44740978906907,378.39598449622531,38.6471386159700145],"hsluv":[280.44740978906907,99.9999999999998863,38.6471386159700145]},"#8800ee":{"lch":[40.258648150966188,124.7713904223,278.13468614008417],"luv":[40.258648150966188,17.6552208530237813,-123.515962711485074],"rgb":[0.533333333333333326,0,0.933333333333333348],"xyz":[0.255840901893380157,0.114075901352201275,0.817457237172005358],"hpluv":[278.13468614008417,393.273926011730225,40.258648150966188],"hsluv":[278.13468614008417,99.9999999999999858,40.258648150966188]},"#8800ff":{"lch":[41.9294357887748674,134.280036872974534,276.305800055850909],"luv":[41.9294357887748674,14.7486383519278057,-133.467621426964229],"rgb":[0.533333333333333326,0,1],"xyz":[0.282011950303211578,0.124544320716133985,0.955291425463787203],"hpluv":[276.305800055850909,406.37947026199555,41.9294357887748674],"hsluv":[276.305800055850909,100.000000000000171,41.9294357887748674]},"#aa0000":{"lch":[35.0982840320529732,118.036634932245676,12.1770506300617765],"luv":[35.0982840320529732,115.380864984340803,24.8978549596859438],"rgb":[0.66666666666666663,0,0],"xyz":[0.165771937912151307,0.08547615548595483,0.00777055958963192815],"hpluv":[12.1770506300617765,426.746789183125145,35.0982840320529732],"hsluv":[12.1770506300617765,100.000000000002217,35.0982840320529732]},"#aa0011":{"lch":[35.178794604810534,115.883637018633408,11.1343823918443601],"luv":[35.178794604810534,113.702354404428164,22.3783808966644813],"rgb":[0.66666666666666663,0,0.0666666666666666657],"xyz":[0.166783603411788439,0.0858808216858096829,0.0130986645543875596],"hpluv":[11.1343823918443601,418.004049663923468,35.178794604810534],"hsluv":[11.1343823918443601,99.9999999999964473,35.178794604810534]},"#aa0022":{"lch":[35.327373324777,112.154849255399441,9.17432067350408431],"luv":[35.327373324777,110.720144559212301,17.8818287736043224],"rgb":[0.66666666666666663,0,0.133333333333333331],"xyz":[0.16865896155026544,0.0866309649412005,0.0229755507503667557],"hpluv":[9.17432067350408431,402.852473647417696,35.327373324777],"hsluv":[9.17432067350408431,99.9999999999965752,35.327373324777]},"#aa0033":{"lch":[35.5701485089931921,106.706281850707128,5.8788523359554592],"luv":[35.5701485089931921,106.14508040487398,10.9294323844098908],"rgb":[0.66666666666666663,0,0.2],"xyz":[0.171746712282723202,0.0878660652341836101,0.0392377046079779],"hpluv":[5.8788523359554592,380.665602767339294,35.5701485089931921],"hsluv":[5.8788523359554592,99.9999999999967741,35.5701485089931921]},"#aa0044":{"lch":[35.9166782648329104,100.198740700315142,1.0062433800652546],"luv":[35.9166782648329104,100.183288799466339,1.75962588401964615],"rgb":[0.66666666666666663,0,0.266666666666666663],"xyz":[0.176204707526942062,0.0896492633318711901,0.0627164795608645409],"hpluv":[1.0062433800652546,354.001763490246503,35.9166782648329104],"hsluv":[1.0062433800652546,99.999999999997,35.9166782648329104]},"#aa0055":{"lch":[36.3730398367095,93.6502679946689369,354.384147096436777],"luv":[36.3730398367095,93.2007806216229113,-9.16445235643848832],"rgb":[0.66666666666666663,0,0.333333333333333315],"xyz":[0.182167121566304047,0.092034228947616023,0.0941185268348384424],"hpluv":[354.384147096436777,326.714758289773386,36.3730398367095],"hsluv":[354.384147096436777,99.9999999999973,36.3730398367095]},"#aa0066":{"lch":[36.9423385777606228,88.2319659172366926,346.039412913085584],"luv":[36.9423385777606228,85.6257622699194,-21.2863488018886251],"rgb":[0.66666666666666663,0,0.4],"xyz":[0.189752117339812232,0.0950682272570193415,0.134066171241982418],"hpluv":[346.039412913085584,303.068568849792825,36.9423385777606228],"hsluv":[346.039412913085584,99.9999999999976126,36.9423385777606228]},"#aa0077":{"lch":[37.6250775946346891,84.9907340508927689,336.365700313169],"luv":[37.6250775946346891,77.8619577045834319,-34.0725757306260348],"rgb":[0.66666666666666663,0,0.466666666666666674],"xyz":[0.199066130360014137,0.0987938324651001509,0.183119973148380327],"hpluv":[336.365700313169,286.637826777930513,37.6250775946346891],"hsluv":[336.365700313169,99.9999999999979536,37.6250775946346891]},"#aa0088":{"lch":[38.4195160158879432,84.5572797483387717,326.161033183527252],"luv":[38.4195160158879432,70.2337789048813761,-47.0866208086656215],"rgb":[0.66666666666666663,0,0.533333333333333326],"xyz":[0.210206547461958,0.103249999305877749,0.241792836551952495],"hpluv":[326.161033183527252,279.279102381419364,38.4195160158879432],"hsluv":[326.161033183527252,99.9999999999982379,38.4195160158879432]},"#aa0099":{"lch":[39.3220484546604681,86.9871636461465272,316.374304421046759],"luv":[39.3220484546604681,62.9667468975572859,-60.0162929906574334],"rgb":[0.66666666666666663,0,0.6],"xyz":[0.223263511571030693,0.108472784949506906,0.310559514193070374],"hpluv":[316.374304421046759,280.710309296009257,39.3220484546604681],"hsluv":[316.374304421046759,99.9999999999986,39.3220484546604681]},"#aa00aa":{"lch":[40.3276007574525863,91.8597353001339627,307.715012949243601],"luv":[40.3276007574525863,56.1937545325413,-72.6668626056414411],"rgb":[0.66666666666666663,0,0.66666666666666663],"xyz":[0.238321204536283249,0.114495862135608,0.389863363810069],"hpluv":[307.715012949243601,289.042783730483393,40.3276007574525863],"hsluv":[307.715012949243601,99.9999999999988205,40.3276007574525863]},"#aa00bb":{"lch":[41.4300227805658849,98.5480850422065089,300.471226581677797],"luv":[41.4300227805658849,49.974285465742625,-84.9370111180893304],"rgb":[0.66666666666666663,0,0.733333333333333282],"xyz":[0.255458796643619868,0.121350898978542759,0.480121348908710721],"hpluv":[300.471226581677797,301.836908489583834,41.4300227805658849],"hsluv":[300.471226581677797,99.9999999999990621,41.4300227805658849]},"#aa00cc":{"lch":[42.6224565622471445,106.453892931925211,294.601049164416338],"luv":[42.6224565622471445,44.3164832708711813,-96.7909119228886681],"rgb":[0.66666666666666663,0,0.8],"xyz":[0.274751172087341622,0.129067849156031561,0.581727859578980877],"hpluv":[294.601049164416338,316.929304470761622,42.6224565622471445],"hsluv":[294.601049164416338,99.9999999999992895,42.6224565622471445]},"#aa00dd":{"lch":[43.8976622887243266,115.112632227118652,289.907671140995035],"luv":[43.8976622887243266,39.1964773946494063,-108.233794436426436],"rgb":[0.66666666666666663,0,0.866666666666666696],"xyz":[0.296269497637975165,0.137675179376285095,0.695057707478986875],"hpluv":[289.907671140995035,332.752186796280228,43.8976622887243266],"hsluv":[289.907671140995035,99.9999999999994174,43.8976622887243266]},"#aa00ee":{"lch":[45.2482911917969233,124.202454763835647,286.162342623679535],"luv":[45.2482911917969233,34.5729825657367655,-119.293581746345012],"rgb":[0.66666666666666663,0,0.933333333333333348],"xyz":[0.320081677904149875,0.14720005148275514,0.820468523547510098],"hpluv":[286.162342623679535,348.311106794177135,45.2482911917969233],"hsluv":[286.162342623679535,99.9999999999996589,45.2482911917969233]},"#aa00ff":{"lch":[46.667101462293175,133.514790614533382,283.159905061129905],"luv":[46.667101462293175,30.397247590160724,-130.008486845225434],"rgb":[0.66666666666666663,0,1],"xyz":[0.346252726313981296,0.157668470846687836,0.958302711839291943],"hpluv":[283.159905061129905,363.042841924949244,46.667101462293175],"hsluv":[283.159905061129905,99.9999999999998153,46.667101462293175]},"#881100":{"lch":[28.4751123640698864,88.1761994811112,13.8943544232398857],"luv":[28.4751123640698864,85.5961768878489124,21.1739617718743069],"rgb":[0.533333333333333326,0.0666666666666666657,0],"xyz":[0.103535562162309969,0.0563608058772578496,0.00542740663443661096],"hpluv":[13.8943544232398857,392.939109149716501,28.4751123640698864],"hsluv":[13.8943544232398857,100.000000000002331,28.4751123640698864]},"#881111":{"lch":[28.5813012406410962,85.6429421929893522,12.1770506300617782],"luv":[28.5813012406410962,83.7160154193071548,18.0649469909557752],"rgb":[0.533333333333333326,0.0666666666666666657,0.0666666666666666657],"xyz":[0.104547227661947087,0.0567654720771127,0.0107555115991922433],"hpluv":[12.1770506300617782,380.232213605760478,28.5813012406410962],"hsluv":[12.1770506300617782,89.1001931926906536,28.5813012406410962]},"#881122":{"lch":[28.776819878520115,81.4294437186752589,8.91447414891876377],"luv":[28.776819878520115,80.445837197505071,12.6183034487767767],"rgb":[0.533333333333333326,0.0666666666666666657,0.133333333333333331],"xyz":[0.106422585800424116,0.0575156153325035238,0.0206323977951714393],"hpluv":[8.91447414891876377,359.069069298387092,28.776819878520115],"hsluv":[8.91447414891876377,89.5522119422979,28.776819878520115]},"#881133":{"lch":[29.0950676619922959,75.7256767264573227,3.35964558590209394],"luv":[29.0950676619922959,75.5955308554484162,4.43777313107212557],"rgb":[0.533333333333333326,0.0666666666666666657,0.2],"xyz":[0.10951033653288185,0.0587507156254866367,0.0368945516527825826],"hpluv":[3.35964558590209394,330.265430862114329,29.0950676619922959],"hsluv":[3.35964558590209394,90.2199940579986475,29.0950676619922959]},"#881144":{"lch":[29.5467689283324617,69.8105982852884779,355.112641815866198],"luv":[29.5467689283324617,69.5567752183087435,-5.94765955478224484],"rgb":[0.533333333333333326,0.0666666666666666657,0.266666666666666663],"xyz":[0.113968331777100723,0.0605339137231742097,0.0603733266056692211],"hpluv":[355.112641815866198,299.81315922456514,29.5467689283324617],"hsluv":[355.112641815866198,91.0462468049379083,29.5467689283324617]},"#881155":{"lch":[30.1372440361953267,65.3247498846549,344.189828060851937],"luv":[30.1372440361953267,62.8534910411243928,-17.7977979378353552],"rgb":[0.533333333333333326,0.0666666666666666657,0.333333333333333315],"xyz":[0.119930745816462722,0.0629188793389190426,0.0917753738796431295],"hpluv":[344.189828060851937,275.05120204756264,30.1372440361953267],"hsluv":[344.189828060851937,91.9552565263170294,30.1372440361953267]},"#881166":{"lch":[30.8672249177773494,63.7021552959616173,331.50461515751158],"luv":[30.8672249177773494,55.9849923977636479,-30.3915319714745138],"rgb":[0.533333333333333326,0.0666666666666666657,0.4],"xyz":[0.127515741589970893,0.0659528776483223611,0.131723018286787091],"hpluv":[331.50461515751158,261.876101180723595,30.8672249177773494],"hsluv":[331.50461515751158,92.8754029221989299,30.8672249177773494]},"#881177":{"lch":[31.7336031237729514,65.5512880923603376,318.81152503011009],"luv":[31.7336031237729514,49.3304506912780525,-43.1680206305895737],"rgb":[0.533333333333333326,0.0666666666666666657,0.466666666666666674],"xyz":[0.136829754610172827,0.0696784828564031705,0.180776820193185],"hpluv":[318.81152503011009,262.120610410187965,31.7336031237729514],"hsluv":[318.81152503011009,93.7528273751248094,31.7336031237729514]},"#881188":{"lch":[32.7302234117729114,70.4946015177073377,307.715012949243658],"luv":[32.7302234117729114,43.1239685223607268,-55.7656900075914663],"rgb":[0.533333333333333326,0.0666666666666666657,0.533333333333333326],"xyz":[0.147970171712116627,0.0741346496971807684,0.239449683596757168],"hpluv":[307.715012949243658,273.304143969878908,32.7302234117729114],"hsluv":[307.715012949243658,94.5549099834012736,32.7302234117729114]},"#881199":{"lch":[33.8487030992268245,77.6382380820710836,298.861624073140206],"luv":[33.8487030992268245,37.4756592651389795,-67.9946393117248249],"rgb":[0.533333333333333326,0.0666666666666666657,0.6],"xyz":[0.161027135821189354,0.0793574353408099259,0.308216361237875103],"hpluv":[298.861624073140206,291.053592363859707,33.8487030992268245],"hsluv":[298.861624073140206,95.267111116431,33.8487030992268245]},"#8811aa":{"lch":[35.0792182273937954,86.1162494337963551,292.107316515455238],"luv":[35.0792182273937954,32.4092110837954692,-79.7850327659882623],"rgb":[0.533333333333333326,0.0666666666666666657,0.66666666666666663],"xyz":[0.176084828786441883,0.0853805125269110343,0.387520210854873703],"hpluv":[292.107316515455238,311.511817997128389,35.0792182273937954],"hsluv":[292.107316515455238,95.8874450484264571,35.0792182273937954]},"#8811bb":{"lch":[36.4111998559147381,95.3124415598142,287.019214731984619],"luv":[36.4111998559147381,27.8972267898096504,-91.1383906678789515],"rgb":[0.533333333333333326,0.0666666666666666657,0.733333333333333282],"xyz":[0.193222420893778557,0.0922355493698457929,0.47777819595351545],"hpluv":[287.019214731984619,332.16504711372977,36.4111998559147381],"hsluv":[287.019214731984619,96.4212920970111753,36.4111998559147381]},"#8811cc":{"lch":[37.8339039869932847,104.849214202707898,283.169050576302368],"luv":[37.8339039869932847,23.8872658659353974,-102.091900993053514],"rgb":[0.533333333333333326,0.0666666666666666657,0.8],"xyz":[0.212514796337500284,0.0999524995473346,0.579384706623785606],"hpluv":[283.169050576302368,351.660305548048939,37.8339039869932847],"hsluv":[283.169050576302368,96.8775739500717776,37.8339039869932847]},"#8811dd":{"lch":[39.3368423655390274,114.513051177954694,280.22024610097435],"luv":[39.3368423655390274,20.3183376083265372,-112.696069349906494],"rgb":[0.533333333333333326,0.0666666666666666657,0.866666666666666696],"xyz":[0.234033121888133827,0.108559829767588129,0.692714554523791604],"hpluv":[280.22024610097435,369.398236331583689,39.3368423655390274],"hsluv":[280.22024610097435,97.2663289333616348,39.3368423655390274]},"#8811ee":{"lch":[40.9100807353410261,124.189527798253138,277.928390028110698],"luv":[40.9100807353410261,17.130123009315259,-123.002429652583771],"rgb":[0.533333333333333326,0.0666666666666666657,0.933333333333333348],"xyz":[0.257845302154308564,0.118084701874058146,0.818125370592314827],"hpluv":[277.928390028110698,385.206818333834917,40.9100807353410261],"hsluv":[277.928390028110698,97.5973562787359867,40.9100807353410261]},"#8811ff":{"lch":[42.5444231432324926,133.820472646418182,276.120297984259253],"luv":[42.5444231432324926,14.2674470621751119,-133.057727523202459],"rgb":[0.533333333333333326,0.0666666666666666657,1],"xyz":[0.28401635056414,0.128553121237990842,0.955959558884096672],"hpluv":[276.120297984259253,399.134479754608662,42.5444231432324926],"hsluv":[276.120297984259253,99.9999999999993605,42.5444231432324926]},"#aa1100":{"lch":[35.8849415951509485,114.659477700983,13.2232466646238507],"luv":[35.8849415951509485,111.619416231509064,26.2278810962561089],"rgb":[0.66666666666666663,0.0666666666666666657,0],"xyz":[0.167776338173079714,0.0894849560078117,0.00843869300994137816],"hpluv":[13.2232466646238507,405.449754626827882,35.8849415951509485],"hsluv":[13.2232466646238507,100.000000000002245,35.8849415951509485]},"#aa1111":{"lch":[35.9630348414680086,112.584844162769954,12.1770506300617871],"luv":[35.9630348414680086,110.051736997450746,23.747890832642895],"rgb":[0.66666666666666663,0.0666666666666666657,0.0666666666666666657],"xyz":[0.168788003672716846,0.089889622207666553,0.0137667979746970096],"hpluv":[12.1770506300617871,397.249101663635656,35.9630348414680086],"hsluv":[12.1770506300617871,93.0877775141683514,35.9630348414680086]},"#aa1122":{"lch":[36.1071812157442409,108.986817867719594,10.2082214608018411],"luv":[36.1071812157442409,107.261576994584843,19.3152936702042],"rgb":[0.66666666666666663,0.0666666666666666657,0.133333333333333331],"xyz":[0.170663361811193848,0.0906397654630573674,0.0236436841706762074],"hpluv":[10.2082214608018411,383.018466712830786,36.1071812157442409],"hsluv":[10.2082214608018411,93.272361347425246,36.1071812157442409]},"#aa1133":{"lch":[36.3427932754706546,103.718469067724868,6.89182233030552727],"luv":[36.3427932754706546,102.969049051934846,12.4457126390109512],"rgb":[0.66666666666666663,0.0666666666666666657,0.2],"xyz":[0.173751112543651609,0.0918748657560404802,0.0399058380282873507],"hpluv":[6.89182233030552727,362.140519718911037,36.3427932754706546],"hsluv":[6.89182233030552727,93.5557024333493388,36.3427932754706546]},"#aa1144":{"lch":[36.6792659124992824,97.4113439982971698,1.97455903872184],"luv":[36.6792659124992824,97.3535035649005778,3.35637947697775552],"rgb":[0.66666666666666663,0.0666666666666666657,0.266666666666666663],"xyz":[0.178209107787870469,0.0936580638537280602,0.0633846129811739822],"hpluv":[1.97455903872184,336.99870087691761,36.6792659124992824],"hsluv":[1.97455903872184,93.9250914747756696,36.6792659124992824]},"#aa1155":{"lch":[37.1226754299384396,91.055498296574811,355.267689161716703],"luv":[37.1226754299384396,90.7450919896636634,-7.51212685096688926],"rgb":[0.66666666666666663,0.0666666666666666657,0.333333333333333315],"xyz":[0.184171521827232454,0.0960430294694729,0.0947866602551479],"hpluv":[355.267689161716703,311.247759321881176,37.1226754299384396],"hsluv":[355.267689161716703,94.3576556410013154,37.1226754299384396]},"#aa1166":{"lch":[37.6762679798416,85.8108023849569577,346.783206271719791],"luv":[37.6762679798416,83.5378398512485205,-19.6194576616503156],"rgb":[0.66666666666666663,0.0666666666666666657,0.4],"xyz":[0.191756517600740639,0.0990770277788762116,0.134734304662291859],"hpluv":[346.783206271719791,289.010360822200312,37.6762679798416],"hsluv":[346.783206271719791,94.8263018378468558,37.6762679798416]},"#aa1177":{"lch":[38.3408051028578285,82.7345113545946163,336.916515476294876],"luv":[38.3408051028578285,76.110335477500783,-32.4378822148708],"rgb":[0.66666666666666663,0.0666666666666666657,0.466666666666666674],"xyz":[0.201070530620942545,0.102802632986957021,0.183788106568689769],"hpluv":[336.916515476294876,273.819772016881302,38.3408051028578285],"hsluv":[336.916515476294876,95.3051408978498387,38.3408051028578285]},"#aa1188":{"lch":[39.1148927869010379,82.477083595297529,326.495944929629673],"luv":[39.1148927869010379,68.7732486834780445,-45.5270203714912753],"rgb":[0.66666666666666663,0.0666666666666666657,0.533333333333333326],"xyz":[0.212210947722886401,0.107258799827734619,0.242460969972261936],"hpluv":[326.495944929629673,267.565723971153261,39.1148927869010379],"hsluv":[326.495944929629673,95.7730681487448,39.1148927869010379]},"#aa1199":{"lch":[39.9953287808464424,85.1038505069809617,316.515705271857257],"luv":[39.9953287808464424,61.7482074461545665,-58.5647013848890552],"rgb":[0.66666666666666663,0.0666666666666666657,0.6],"xyz":[0.2252679118319591,0.112481585471363776,0.311227647613379843],"hpluv":[316.515705271857257,270.00963724100518,39.9953287808464424],"hsluv":[316.515705271857257,96.2151887572794,39.9953287808464424]},"#aa11aa":{"lch":[40.9774666162921406,90.1875437006381588,307.715012949243601],"luv":[40.9774666162921406,55.1708175083225498,-71.3440532505540261],"rgb":[0.66666666666666663,0.0666666666666666657,0.66666666666666663],"xyz":[0.240325604797211656,0.118504662657464871,0.390531497230378444],"hpluv":[307.715012949243601,279.28060733669264,40.9774666162921406],"hsluv":[307.715012949243601,96.6225842874192864,40.9774666162921406]},"#aa11bb":{"lch":[42.0555802442747719,97.087212137786878,300.384453602166161],"luv":[42.0555802442747719,49.106684193967304,-83.7523750598249705],"rgb":[0.66666666666666663,0.0666666666666666657,0.733333333333333282],"xyz":[0.257463196904548275,0.12535969950039963,0.48078948232902019],"hpluv":[300.384453602166161,292.939359498794147,42.0555802442747719],"hsluv":[300.384453602166161,96.9911870522472697,42.0555802442747719]},"#aa11cc":{"lch":[43.2232098485165395,105.192683835863036,294.469145625450437],"luv":[43.2232098485165395,43.5711419401365,-95.7447456658814247],"rgb":[0.66666666666666663,0.0666666666666666657,0.8],"xyz":[0.276755572348270029,0.133076649677888431,0.582395992999290346],"hpluv":[294.469145625450437,308.821726609797679,43.2232098485165395],"hsluv":[294.469145625450437,97.3204020480748255,43.2232098485165395]},"#aa11dd":{"lch":[44.4734721926781518,114.032755796715193,289.757274940509092],"luv":[44.4734721926781518,38.5472014936014489,-107.320001172218454],"rgb":[0.66666666666666663,0.0666666666666666657,0.866666666666666696],"xyz":[0.298273897898903573,0.141683979898141965,0.695725840899296344],"hpluv":[289.757274940509092,325.362808980276498,44.4734721926781518],"hsluv":[289.757274940509092,97.611854654502622,44.4734721926781518]},"#aa11ee":{"lch":[45.7993244881172,123.283094749558884,286.008743686799619],"luv":[45.7993244881172,33.9995108001485136,-118.502129585840351],"rgb":[0.66666666666666663,0.0666666666666666657,0.933333333333333348],"xyz":[0.322086078165078282,0.151208852004612,0.821136656967819567],"hpluv":[286.008743686799619,341.573194884792258,45.7993244881172],"hsluv":[286.008743686799619,97.8684161167955153,45.7993244881172]},"#aa11ff":{"lch":[47.1937769411101868,132.735165800167636,283.011169167098501],"luv":[47.1937769411101868,29.8841269734434611,-129.327348983241365],"rgb":[0.66666666666666663,0.0666666666666666657,1],"xyz":[0.348257126574909703,0.161677271368544706,0.958970845259601412],"hpluv":[283.011169167098501,356.89510187446183,47.1937769411101868],"hsluv":[283.011169167098501,99.9999999999993321,47.1937769411101868]},"#882200":{"lch":[30.3496916993887922,81.7292062801124786,17.2000641303745212],"luv":[30.3496916993887922,78.0741152618852254,24.1680716080335465],"rgb":[0.533333333333333326,0.133333333333333331,0],"xyz":[0.107251185897077911,0.0637920533467938311,0.00666594787935922105],"hpluv":[17.2000641303745212,341.713647377264522,30.3496916993887922],"hsluv":[17.2000641303745212,100.000000000002359,30.3496916993887922]},"#882211":{"lch":[30.4474919309639347,79.3871193031655338,15.4743840495427136],"luv":[30.4474919309639347,76.5093230935452908,21.181080969170015],"rgb":[0.533333333333333326,0.133333333333333331,0.0666666666666666657],"xyz":[0.108262851396715029,0.064196719546648684,0.0119940528441148525],"hpluv":[15.4743840495427136,330.855109199112462,30.4474919309639347],"hsluv":[15.4743840495427136,90.2707057474005,30.4474919309639347]},"#882222":{"lch":[30.6277058928754826,75.4670009360781648,12.1770506300618102],"luv":[30.6277058928754826,73.7690281561900321,15.9185022906448506],"rgb":[0.533333333333333326,0.133333333333333331,0.133333333333333331],"xyz":[0.110138209535192058,0.0649468628020395,0.0218709390400940486],"hpluv":[12.1770506300618102,312.666930334371557,30.6277058928754826],"hsluv":[12.1770506300618102,73.2675530922876277,30.6277058928754826]},"#882233":{"lch":[30.9214262019897674,70.1124269978110135,6.50693872003014],"luv":[30.9214262019897674,69.6607724946186266,7.94538828354938],"rgb":[0.533333333333333326,0.133333333333333331,0.2],"xyz":[0.113225960267649792,0.0661819630950226112,0.0381330928977051953],"hpluv":[6.50693872003014,287.723152758323693,30.9214262019897674],"hsluv":[6.50693872003014,74.8097141082451458,30.9214262019897674]},"#882244":{"lch":[31.3391119188553589,64.5127804411509,357.965654494967],"luv":[31.3391119188553589,64.472119792654567,-2.29011128326569047],"rgb":[0.533333333333333326,0.133333333333333331,0.266666666666666663],"xyz":[0.117683955511868665,0.0679651611927101912,0.0616118678505918338],"hpluv":[357.965654494967,261.215173773686786,31.3391119188553589],"hsluv":[357.965654494967,76.7464797952550839,31.3391119188553589]},"#882255":{"lch":[31.8864840032734449,60.2907989794282599,346.464164292394514],"luv":[31.8864840032734449,58.6161449596217778,-14.1112717942230379],"rgb":[0.533333333333333326,0.133333333333333331,0.333333333333333315],"xyz":[0.123646369551230664,0.0703501268084550241,0.0930139151245657353],"hpluv":[346.464164292394514,239.929545755427228,31.8864840032734449],"hsluv":[346.464164292394514,78.9147131880069566,31.8864840032734449]},"#882266":{"lch":[32.565220274416383,58.9629659850378189,332.945096803324191],"luv":[32.565220274416383,52.5107124518348698,-26.8189566455043362],"rgb":[0.533333333333333326,0.133333333333333331,0.4],"xyz":[0.131231365324738836,0.0733841251178583426,0.132961559531709711],"hpluv":[332.945096803324191,229.754818264706444,32.565220274416383],"hsluv":[332.945096803324191,81.1505919454384923,32.565220274416383]},"#882277":{"lch":[33.3735533542235316,61.2256527964903086,319.411642653163199],"luv":[33.3735533542235316,46.4949769025583564,-39.8346291960518499],"rgb":[0.533333333333333326,0.133333333333333331,0.466666666666666674],"xyz":[0.140545378344940741,0.077109730325939152,0.18201536143810762],"hpluv":[319.411642653163199,232.79320602780777,33.3735533542235316],"hsluv":[319.411642653163199,83.3222334130424116,33.3735533542235316]},"#882288":{"lch":[34.3068967831130962,66.691064714973308,307.715012949243771],"luv":[34.3068967831130962,40.7972144472485709,-52.7568517461189046],"rgb":[0.533333333333333326,0.133333333333333331,0.533333333333333326],"xyz":[0.151685795446884597,0.0815658971667167498,0.240688224841679788],"hpluv":[307.715012949243771,246.675229855048,34.3068967831130962],"hsluv":[307.715012949243771,85.3421167175917,34.3068967831130962]},"#882299":{"lch":[35.3585028262625087,74.3915148492043699,298.539568373309862],"luv":[35.3585028262625087,35.5417034620318262,-65.3520068289902554],"rgb":[0.533333333333333326,0.133333333333333331,0.6],"xyz":[0.164742759555957297,0.0867886828103459074,0.309454902482797667],"hpluv":[298.539568373309862,266.973934190138948,35.3585028262625087],"hsluv":[298.539568373309862,87.1641407220543556,35.3585028262625087]},"#8822aa":{"lch":[36.5201138266519365,83.3993900511107142,291.653660077047903],"luv":[36.5201138266519365,30.7739719973965897,-77.5140045953036463],"rgb":[0.533333333333333326,0.133333333333333331,0.66666666666666663],"xyz":[0.179800452521209853,0.092811759996447,0.388758752099796268],"hpluv":[291.653660077047903,289.781114528802732,36.5201138266519365],"hsluv":[291.653660077047903,88.7734689989794532,36.5201138266519365]},"#8822bb":{"lch":[37.7825623664262196,93.0686060696910857,286.53575696187113],"luv":[37.7825623664262196,26.4885972028076893,-89.2195026548722],"rgb":[0.533333333333333326,0.133333333333333331,0.733333333333333282],"xyz":[0.196938044628546471,0.0996667968393817605,0.479016737198438],"hpluv":[286.53575696187113,312.57276028475934,37.7825623664262196],"hsluv":[286.53575696187113,90.1753980157506874,37.7825623664262196]},"#8822cc":{"lch":[39.1362858369643476,103.012880313051866,282.702767559286599],"luv":[39.1362858369643476,22.6518448072254479,-100.491529181421669],"rgb":[0.533333333333333326,0.133333333333333331,0.8],"xyz":[0.216230420072268226,0.107383747016870562,0.580623247868708225],"hpluv":[282.702767559286599,334.003678399645651,39.1362858369643476],"hsluv":[282.702767559286599,91.3862929083300628,39.1362858369643476]},"#8822dd":{"lch":[40.5717373677475379,113.020349666590874,279.789793007972776],"luv":[40.5717373677475379,19.2172965257181652,-111.374570495248548],"rgb":[0.533333333333333326,0.133333333333333331,0.866666666666666696],"xyz":[0.237748745622901769,0.115991077237124096,0.693953095768714223],"hpluv":[279.789793007972776,353.486121759760863,40.5717373677475379],"hsluv":[279.789793007972776,92.4273238443811209,40.5717373677475379]},"#8822ee":{"lch":[42.0796906219744145,122.982600065668066,277.538986095624125],"luv":[42.0796906219744145,16.1354126197819454,-121.919515986988074],"rgb":[0.533333333333333326,0.133333333333333331,0.933333333333333348],"xyz":[0.261560925889076534,0.125515949343594141,0.819363911837237446],"hpluv":[277.538986095624125,370.860397035002336,42.0796906219744145],"hsluv":[277.538986095624125,93.320628909539181,42.0796906219744145]},"#8822ff":{"lch":[43.6514473624058752,132.848943476626658,275.771185477405766],"luv":[43.6514473624058752,13.3587518063908028,-132.175585994657865],"rgb":[0.533333333333333326,0.133333333333333331,1],"xyz":[0.2877319742989079,0.135984368707526837,0.957198100129019291],"hpluv":[275.771185477405766,386.188007357759091,43.6514473624058752],"hsluv":[275.771185477405766,99.9999999999994,43.6514473624058752]},"#ffaa00":{"lch":[76.0766826449234799,103.646966048157225,46.9849230608437125],"luv":[76.0766826449234799,70.7070052858721,75.7839889059127785],"rgb":[1,0.66666666666666663,0],"xyz":[0.556131758114240538,0.500120923568095,0.0672444716650198171],"hpluv":[46.9849230608437125,173.218766512771339,76.0766826449234799],"hsluv":[46.9849230608437125,100.0000000000028,76.0766826449234799]},"#ffaa11":{"lch":[76.1015101579349533,102.726050652762069,46.6846637022245687],"luv":[76.1015101579349533,70.4714195905473275,74.7423608377930719],"rgb":[1,0.66666666666666663,0.0666666666666666657],"xyz":[0.557143423613877697,0.500525589767949919,0.0725725766297754538],"hpluv":[46.6846637022245687,171.896872437304751,76.1015101579349533],"hsluv":[46.6846637022245687,100.000000000002771,76.1015101579349533]},"#ffaa22":{"lch":[76.1474983763177,101.038792737361192,46.1176753587789605],"luv":[76.1474983763177,70.0380208569547591,72.8252241483965719],"rgb":[1,0.66666666666666663,0.133333333333333331],"xyz":[0.559018781752354643,0.501275733023340719,0.0824494628257546464],"hpluv":[46.1176753587789605,169.470349592440897,76.1474983763177],"hsluv":[46.1176753587789605,100.0000000000028,76.1474983763177]},"#ffaa33":{"lch":[76.2231174741888395,98.3169656691378577,45.1538509265191337],"luv":[76.2231174741888395,69.3336656617894533,69.7070193329597885],"rgb":[1,0.66666666666666663,0.2],"xyz":[0.56210653248481246,0.502510833316323846,0.0987116166833657827],"hpluv":[45.1538509265191337,165.543337136749699,76.2231174741888395],"hsluv":[45.1538509265191337,100.000000000002927,76.2231174741888395]},"#ffaa44":{"lch":[76.3320756204529118,94.5107446089494516,43.6926927141772694],"luv":[76.3320756204529118,68.3364903114306514,65.2870962629968119],"rgb":[1,0.66666666666666663,0.266666666666666663],"xyz":[0.56656452772903132,0.504294031414011412,0.122190391636252421],"hpluv":[43.6926927141772694,160.025535099593441,76.3320756204529118],"hsluv":[43.6926927141772694,100.000000000003,76.3320756204529118]},"#ffaa55":{"lch":[76.4774026026215,89.6489515946998807,41.6012791226812411],"luv":[76.4774026026215,67.0379860163697288,59.5217855318358247],"rgb":[1,0.66666666666666663,0.333333333333333315],"xyz":[0.572526941768393249,0.506678997029756162,0.153592438910226337],"hpluv":[41.6012791226812411,152.933128718005122,76.4774026026215],"hsluv":[41.6012791226812411,100.000000000003,76.4774026026215]},"#ffaa66":{"lch":[76.6616205587261,83.8466863985853905,38.6944265301345354],"luv":[76.6616205587261,65.4416029270402788,52.418159318716242],"rgb":[1,0.66666666666666663,0.4],"xyz":[0.58011193754190149,0.50971299533915948,0.193540083317370298],"hpluv":[38.6944265301345354,144.405277715469396,76.6616205587261],"hsluv":[38.6944265301345354,100.000000000003197,76.6616205587261]},"#ffaa77":{"lch":[76.8868341725165,77.3210793721064533,34.7099370327462324],"luv":[76.8868341725165,63.5614296008349058,44.0283315873505927],"rgb":[1,0.66666666666666663,0.466666666666666674],"xyz":[0.58942595056210334,0.513438600547240331,0.242593885223768208],"hpluv":[34.7099370327462324,134.738986801151128,76.8868341725165],"hsluv":[34.7099370327462324,100.000000000003354,76.8868341725165]},"#ffaa88":{"lch":[77.1547840912050873,70.4186738688562741,29.282319230158226],"luv":[77.1547840912050873,61.4205932059712723,34.4427112706728948],"rgb":[1,0.66666666666666663,0.533333333333333326],"xyz":[0.600566367664047251,0.517894767388017874,0.301266748627340375],"hpluv":[29.282319230158226,124.451835787871019,77.1547840912050873],"hsluv":[29.282319230158226,100.000000000003638,77.1547840912050873]},"#ffaa99":{"lch":[77.466881654564645,63.658531214354845,21.9370110659791244],"luv":[77.466881654564645,59.0493431107362383,23.7820031654092716],"rgb":[1,0.66666666666666663,0.6],"xyz":[0.613623331773119896,0.523117553031647087,0.370033426268458254],"hpluv":[21.9370110659791244,114.385173247539697,77.466881654564645],"hsluv":[21.9370110659791244,100.000000000003624,77.466881654564645]},"#ffaaaa":{"lch":[77.8242336850598,57.783013099698,12.1770506300621957],"luv":[77.8242336850598,56.482921905318662,12.1883606739193855],"rgb":[1,0.66666666666666663,0.66666666666666663],"xyz":[0.628681024738372507,0.529140630217748154,0.44933727588545691],"hpluv":[12.1770506300621957,105.841692205508735,77.8242336850598],"hsluv":[12.1770506300621957,100.000000000003837,77.8242336850598]},"#ffaabb":{"lch":[78.227662021793833,53.7597014753195,359.804273109779956],"luv":[78.227662021793833,53.7593877986938224,-0.183647012281759531],"rgb":[1,0.66666666666666663,0.733333333333333282],"xyz":[0.64581861684570907,0.535995667060682912,0.539595260984098601],"hpluv":[359.804273109779956,100.661858044669231,78.227662021793833],"hsluv":[359.804273109779956,100.000000000004135,78.227662021793833]},"#ffaacc":{"lch":[78.6777204654413254,52.5946111834740293,345.492217824016791],"luv":[78.6777204654413254,50.9175596191628586,-13.1755549397286202],"rgb":[1,0.66666666666666663,0.8],"xyz":[0.665110992289430825,0.543712617238171769,0.641201771654368757],"hpluv":[345.492217824016791,100.966318741741958,78.6777204654413254],"hsluv":[345.492217824016791,100.000000000004306,78.6777204654413254]},"#ffaadd":{"lch":[79.1747106956411244,54.8892328831665353,330.97422205899818],"luv":[79.1747106956411244,47.9952274547753177,-26.6324243745640352],"rgb":[1,0.66666666666666663,0.866666666666666696],"xyz":[0.686629317840064424,0.552319947458425275,0.754531619554374755],"hpluv":[330.97422205899818,108.36723319715793,79.1747106956411244],"hsluv":[330.97422205899818,100.000000000004704,79.1747106956411244]},"#ffaaee":{"lch":[79.718698064048283,60.5009523664383337,318.094564198374599],"luv":[79.718698064048283,45.0277239197174595,-40.4087777080146822],"rgb":[1,0.66666666666666663,0.933333333333333348],"xyz":[0.710441498106239133,0.561844819564895293,0.879942435622898],"hpluv":[318.094564198374599,123.247069988098687,79.718698064048283],"hsluv":[318.094564198374599,100.000000000004945,79.718698064048283]},"#ffaaff":{"lch":[80.3095277487323074,68.733917080261989,307.715012949245647],"luv":[80.3095277487323074,42.0468973903394,-54.3728772187255203],"rgb":[1,0.66666666666666663,1],"xyz":[0.736612546516070554,0.572313238928828,1.01777662391468],"hpluv":[307.715012949245647,144.979279509576116,80.3095277487323074],"hsluv":[307.715012949245647,100.000000000005301,80.3095277487323074]},"#aa2200":{"lch":[37.2831780533064929,108.910935722579069,15.2092016225530191],"luv":[37.2831780533064929,105.096262108869439,28.5721474641225],"rgb":[0.66666666666666663,0.133333333333333331,0],"xyz":[0.171491961907847656,0.0969162034773476816,0.00967723425486398912],"hpluv":[15.2092016225530191,370.67892165569458,37.2831780533064929],"hsluv":[15.2092016225530191,100.000000000002217,37.2831780533064929]},"#aa2211":{"lch":[37.3572350214345619,106.95640568906397,14.158492547926917],"luv":[37.3572350214345619,103.707370245599336,26.1620732103901794],"rgb":[0.66666666666666663,0.133333333333333331,0.0666666666666666657],"xyz":[0.172503627407484789,0.0973208696772025345,0.0150053392196196206],"hpluv":[14.158492547926917,363.305022455593,37.3572350214345619],"hsluv":[14.158492547926917,93.5777596020973732,37.3572350214345619]},"#aa2222":{"lch":[37.4939757158163331,103.55828406892158,12.1770506300617907],"luv":[37.4939757158163331,101.228270350344232,21.8438888748564],"rgb":[0.66666666666666663,0.133333333333333331,0.133333333333333331],"xyz":[0.17437898554596179,0.0980710129325933488,0.0248822254155988166],"hpluv":[12.1770506300617907,350.479546677114797,37.4939757158163331],"hsluv":[12.1770506300617907,82.128221128038831,37.4939757158163331]},"#aa2233":{"lch":[37.7176061419824791,98.5638584928897359,8.82735266140639],"luv":[37.7176061419824791,97.3963926843060506,15.125372494284127],"rgb":[0.66666666666666663,0.133333333333333331,0.2],"xyz":[0.177466736278419523,0.0993061132255764617,0.0411443792732099634],"hpluv":[8.82735266140639,331.598763076121088,37.7176061419824791],"hsluv":[8.82735266140639,82.8309253801110401,37.7176061419824791]},"#aa2244":{"lch":[38.0372287502177358,92.5577577991589209,3.83362915136278648],"luv":[38.0372287502177358,92.350650343690134,6.18836892123021798],"rgb":[0.66666666666666663,0.133333333333333331,0.266666666666666663],"xyz":[0.181924731522638411,0.101089311323264042,0.0646231542260966],"hpluv":[3.83362915136278648,308.775819843535,38.0372287502177358],"hsluv":[3.83362915136278648,83.7532195801290698,38.0372287502177358]},"#aa2255":{"lch":[38.4588905236098242,86.4856662057644172,356.973865768881865],"luv":[38.4588905236098242,86.3650670431288603,-4.56570407393633459],"rgb":[0.66666666666666663,0.133333333333333331,0.333333333333333315],"xyz":[0.187887145562000424,0.103474276939008875,0.0960252015000705],"hpluv":[356.973865768881865,285.355803984318584,38.4588905236098242],"hsluv":[356.973865768881865,84.8422496447961,38.4588905236098242]},"#aa2266":{"lch":[38.9860395203518237,81.4924101374980268,348.227712846231327],"luv":[38.9860395203518237,79.7783138580272464,-16.6262908668256522],"rgb":[0.66666666666666663,0.133333333333333331,0.4],"xyz":[0.195472141335508581,0.106508275248412193,0.135972845907214479],"hpluv":[348.227712846231327,265.245100213362434,38.9860395203518237],"hsluv":[348.227712846231327,86.0332228090823747,38.9860395203518237]},"#aa2277":{"lch":[39.619833929041036,78.6591168776988354,337.990195281021442],"luv":[39.619833929041036,72.9264197190586572,-29.4787037526953952],"rgb":[0.66666666666666663,0.133333333333333331,0.466666666666666674],"xyz":[0.204786154355710515,0.110233880456493,0.185026647813612388],"hpluv":[337.990195281021442,251.92759566726761,39.619833929041036],"hsluv":[337.990195281021442,87.2621982611374278,39.619833929041036]},"#aa2288":{"lch":[40.3594266716885386,78.6767938432408,327.148786779116733],"luv":[40.3594266716885386,66.0949636498191637,-42.6789605025813046],"rgb":[0.66666666666666663,0.133333333333333331,0.533333333333333326],"xyz":[0.215926571457654315,0.1146900472972706,0.243699511217184556],"hpluv":[327.148786779116733,247.366561360315984,40.3594266716885386],"hsluv":[327.148786779116733,88.4751585260979283,40.3594266716885386]},"#aa2299":{"lch":[41.2022629883412748,81.6302410017403162,316.790315261789033],"luv":[41.2022629883412748,59.4964385039503,-55.8898027492302489],"rgb":[0.66666666666666663,0.133333333333333331,0.6],"xyz":[0.228983535566727042,0.119912832940899758,0.312466188858302463],"hpluv":[316.790315261789033,251.402351399829286,41.2022629883412748],"hsluv":[316.790315261789033,89.6322731802278554,41.2022629883412748]},"#aa22aa":{"lch":[42.1443943233873242,87.0780915666379229,307.715012949243715],"luv":[42.1443943233873242,53.2686588598376076,-68.8842798769212834],"rgb":[0.66666666666666663,0.133333333333333331,0.66666666666666663],"xyz":[0.24404122853197957,0.125935910127000866,0.391770038475301063],"hpluv":[307.715012949243715,262.185344504614818,42.1443943233873242],"hsluv":[307.715012949243715,90.7081440057972515,42.1443943233873242]},"#aa22bb":{"lch":[43.1807973125030387,94.3504956605328573,300.218008125398399],"luv":[43.1807973125030387,47.4858085519839577,-81.5298351375283801],"rgb":[0.66666666666666663,0.133333333333333331,0.733333333333333282],"xyz":[0.261178820639316245,0.132790946969935625,0.48202802357394281],"hpluv":[300.218008125398399,277.263598469343151,43.1807973125030387],"hsluv":[300.218008125398399,91.6896384965505291,43.1807973125030387]},"#aa22cc":{"lch":[44.3056820912093627,102.813108633557576,294.217612554784239],"luv":[44.3056820912093627,42.1742864712375294,-93.764944769021767],"rgb":[0.66666666666666663,0.133333333333333331,0.8],"xyz":[0.280471196083037944,0.140507897147424426,0.583634534244213],"hpluv":[294.217612554784239,294.461411899371626,44.3056820912093627],"hsluv":[294.217612554784239,92.5728114271618097,44.3056820912093627]},"#aa22dd":{"lch":[45.5127751844210451,111.980933923074502,289.471886144522102],"luv":[45.5127751844210451,37.3282042805071441,-105.576203414769125],"rgb":[0.66666666666666663,0.133333333333333331,0.866666666666666696],"xyz":[0.301989521633671543,0.14911522736767796,0.696964382144219],"hpluv":[289.471886144522102,312.212361278410071,45.5127751844210451],"hsluv":[289.471886144522102,93.3598993754704622,45.5127751844210451]},"#aa22ee":{"lch":[46.7955661660676938,121.524022862348417,285.718434714393425],"luv":[46.7955661660676938,32.9220942551774698,-116.979587289842115],"rgb":[0.66666666666666663,0.133333333333333331,0.933333333333333348],"xyz":[0.325801701899846252,0.158640099474147978,0.822375198212742187],"hpluv":[285.718434714393425,329.531365671141714,46.7955661660676938],"hsluv":[285.718434714393425,94.0568560040361348,46.7955661660676938]},"#aa22ff":{"lch":[48.1475121680676921,131.233078667623346,282.730941389390409],"luv":[48.1475121680676921,28.9202258451599548,-128.006802450680539],"rgb":[0.66666666666666663,0.133333333333333331,1],"xyz":[0.351972750309677673,0.169108518838080701,0.960209386504524],"hpluv":[282.730941389390409,345.866733454918517,48.1475121680676921],"hsluv":[282.730941389390409,99.9999999999992,48.1475121680676921]},"#883300":{"lch":[33.1414787667816597,73.2165592554870841,22.9600016117944072],"luv":[33.1414787667816597,67.4161530625393084,28.5609323282788417],"rgb":[0.533333333333333326,0.2,0],"xyz":[0.113368907986088716,0.076027497524815621,0.00870518857569610102],"hpluv":[22.9600016117944072,280.334636286210525,33.1414787667816597],"hsluv":[22.9600016117944072,100.000000000002245,33.1414787667816597]},"#883311":{"lch":[33.2285118286029402,71.0572306739368287,21.2511434941679589],"luv":[33.2285118286029402,66.2253841559006844,25.7551650053430592],"rgb":[0.533333333333333326,0.2,0.0666666666666666657],"xyz":[0.114380573485725834,0.0764321637246704738,0.0140332935404517325],"hpluv":[21.2511434941679589,271.354302974885854,33.2285118286029402],"hsluv":[21.2511434941679589,91.7325092821930355,33.2285118286029402]},"#883322":{"lch":[33.389038834633638,67.403958774683133,17.9527330699243208],"luv":[33.389038834633638,64.1221355411587126,20.7760774002325519],"rgb":[0.533333333333333326,0.2,0.133333333333333331],"xyz":[0.116255931624202863,0.0771823069800612882,0.0239101797364309268],"hpluv":[17.9527330699243208,256.165602847605,33.389038834633638],"hsluv":[17.9527330699243208,77.1564226992543354,33.389038834633638]},"#883333":{"lch":[33.6510932573449324,62.3280121609532785,12.1770506300618564],"luv":[33.6510932573449324,60.9256605799824484,13.1470522486492083],"rgb":[0.533333333333333326,0.2,0.2],"xyz":[0.119343682356660596,0.0784174072730444,0.04017233359404207],"hpluv":[12.1770506300618564,235.030067027939708,33.6510932573449324],"hsluv":[12.1770506300618564,55.0748296144977,33.6510932573449324]},"#883344":{"lch":[34.0246284162643136,56.9037682047597428,3.23132728809417369],"luv":[34.0246284162643136,56.8132965471078748,3.20751794249172528],"rgb":[0.533333333333333326,0.2,0.266666666666666663],"xyz":[0.12380167760087947,0.080200605370731981,0.0636511085469287086],"hpluv":[3.23132728809417369,212.220318588139889,34.0246284162643136],"hsluv":[3.23132728809417369,58.083398150148156,34.0246284162643136]},"#883355":{"lch":[34.5156618951709859,52.7529688087382524,350.767304332875],"luv":[34.5156618951709859,52.0695471674777721,-8.46392201697997137],"rgb":[0.533333333333333326,0.2,0.333333333333333315],"xyz":[0.129764091640241469,0.0825855709864768139,0.0950531558209026239],"hpluv":[350.767304332875,193.941176615342812,34.5156618951709859],"hsluv":[350.767304332875,61.5291535706030714,34.5156618951709859]},"#883366":{"lch":[35.1268460128593318,51.5738240122621576,335.705329263136434],"luv":[35.1268460128593318,47.0065260432940519,-21.2189969741481157],"rgb":[0.533333333333333326,0.2,0.4],"xyz":[0.137349087413749654,0.0856195692958801324,0.135000800228046586],"hpluv":[335.705329263136434,186.307141954737205,35.1268460128593318],"hsluv":[335.705329263136434,65.1713869724459869,35.1268460128593318]},"#883377":{"lch":[35.8579115963162849,54.2604071268956929,320.552373035814298],"luv":[35.8579115963162849,41.9001950458929713,-34.4755773946224],"rgb":[0.533333333333333326,0.2,0.466666666666666674],"xyz":[0.14666310043395156,0.0893451745039609418,0.184054602134444495],"hpluv":[320.552373035814298,192.015984070736607,35.8579115963162849],"hsluv":[320.552373035814298,68.798738775930957,35.8579115963162849]},"#883388":{"lch":[36.7061150242973682,60.4128011412536097,307.715012949244056],"luv":[36.7061150242973682,36.9565850245806402,-47.7903480323547711],"rgb":[0.533333333333333326,0.2,0.533333333333333326],"xyz":[0.157803517535895388,0.0938013413447385397,0.242727465538016662],"hpluv":[307.715012949244056,208.847787272345244,36.7061150242973682],"hsluv":[307.715012949244056,72.2549736675254479,36.7061150242973682]},"#883399":{"lch":[37.6667130487112445,68.9141309342046213,297.955533412138379],"luv":[37.6667130487112445,32.3059919210196611,-60.8726566564636684],"rgb":[0.533333333333333326,0.2,0.6],"xyz":[0.170860481644968087,0.0990241269883677,0.311494143179134542],"hpluv":[297.955533412138379,232.161331922109071,37.6667130487112445],"hsluv":[297.955533412138379,75.4431641885032604,37.6667130487112445]},"#8833aa":{"lch":[38.7334497692602824,78.7159372772915162,290.848124870138179],"luv":[38.7334497692602824,28.0143748789862741,-73.5621749378178436],"rgb":[0.533333333333333326,0.2,0.66666666666666663],"xyz":[0.185918174610220643,0.105047204174468806,0.390797992796133142],"hpluv":[290.848124870138179,257.878905714084965,38.7334497692602824],"hsluv":[290.848124870138179,78.3166072053086282,38.7334497692602824]},"#8833bb":{"lch":[39.8990272727434743,89.1142300257769193,285.691107407551272],"luv":[39.8990272727434743,24.1010351313191435,-85.7932753698447073],"rgb":[0.533333333333333326,0.2,0.733333333333333282],"xyz":[0.20305576671755729,0.111902241017403564,0.481055977894774889],"hpluv":[285.691107407551272,283.415812953045702,39.8990272727434743],"hsluv":[285.691107407551272,80.8649153118493444,39.8990272727434743]},"#8833cc":{"lch":[41.1555326498064318,99.7027359993818578,281.897918690971494],"luv":[41.1555326498064318,20.5555775093346966,-97.560769774639283],"rgb":[0.533333333333333326,0.2,0.8],"xyz":[0.222348142161279017,0.119619191194892366,0.5826624885650451],"hpluv":[281.897918690971494,307.410130900702256,41.1555326498064318],"hsluv":[281.897918690971494,83.1006969987668356,41.1555326498064318]},"#8833dd":{"lch":[42.4948021164729042,110.266949448261684,279.053462184119098],"luv":[42.4948021164729042,17.3511661022166734,-108.893237510502843],"rgb":[0.533333333333333326,0.2,0.866666666666666696],"xyz":[0.24386646771191256,0.1282265214151459,0.695992336465051098],"hpluv":[279.053462184119098,329.267506795456711,42.4948021164729042],"hsluv":[279.053462184119098,85.0491409670088103,42.4948021164729042]},"#8833ee":{"lch":[43.9087129541284185,120.703343561802441,276.877390721452173],"luv":[43.9087129541284185,14.4536316684396038,-119.834843341123431],"rgb":[0.533333333333333326,0.2,0.933333333333333348],"xyz":[0.267678647978087325,0.137751393521615917,0.821403152533574321],"hpluv":[276.877390721452173,348.825254458779511,43.9087129541284185],"hsluv":[276.877390721452173,90.7214777394212177,43.9087129541284185]},"#8833ff":{"lch":[45.3894029264418037,130.969293653816607,275.181129330284705],"luv":[45.3894029264418037,11.8271264623124566,-130.43417864894198],"rgb":[0.533333333333333326,0.2,1],"xyz":[0.293849696387918691,0.148219812885548641,0.959237340825356166],"hpluv":[275.181129330284705,366.146040402293636,45.3894029264418037],"hsluv":[275.181129330284705,99.9999999999993179,45.3894029264418037]},"#ffbb00":{"lch":[80.0686585320779614,99.7432534700870832,55.1804439586775146],"luv":[80.0686585320779614,56.9527800089419642,81.8846595037867928],"rgb":[1,0.733333333333333282,0],"xyz":[0.590086256022839262,0.568029919385293569,0.0785626376345524291],"hpluv":[55.1804439586775146,207.400278899961506,80.0686585320779614],"hsluv":[55.1804439586775146,100.000000000004661,80.0686585320779614]},"#ffbb11":{"lch":[80.0914663159454,98.8408701901197304,54.9443852376931758],"luv":[80.0914663159454,56.7713575947746136,80.9106332739172558],"rgb":[1,0.733333333333333282,0.0666666666666666657],"xyz":[0.591097921522476422,0.568434585585148477,0.0838907425993080658],"hpluv":[54.9443852376931758,205.801067903733326,80.0914663159454],"hsluv":[54.9443852376931758,100.000000000004746,80.0914663159454]},"#ffbb22":{"lch":[80.1337172522408849,97.1832370837577173,54.4980435584705063],"luv":[80.1337172522408849,56.4372945908461148,79.11645435270664],"rgb":[1,0.733333333333333282,0.133333333333333331],"xyz":[0.592973279660953367,0.569184728840539278,0.0937676287952872584],"hpluv":[54.4980435584705063,202.856099527528187,80.1337172522408849],"hsluv":[54.4980435584705063,100.00000000000469,80.1337172522408849]},"#ffbb33":{"lch":[80.2032020182086569,94.4967793168558643,53.7374633716008248],"luv":[80.2032020182086569,55.8935303906135772,76.1941898161015558],"rgb":[1,0.733333333333333282,0.2],"xyz":[0.596061030393411184,0.570419829133522405,0.110029782652898395],"hpluv":[53.7374633716008248,198.062979410590685,80.2032020182086569],"hsluv":[53.7374633716008248,100.000000000004576,80.2032020182086569]},"#ffbb44":{"lch":[80.3033451682561,90.7120739700224874,52.5796541788809932],"luv":[80.3033451682561,55.1219083097901148,72.0434284874749835],"rgb":[1,0.733333333333333282,0.266666666666666663],"xyz":[0.60051902563763,0.57220302723121,0.133508557605785033],"hpluv":[52.5796541788809932,191.266883403483888,80.3033451682561],"hsluv":[52.5796541788809932,100.000000000004732,80.3033451682561]},"#ffbb55":{"lch":[80.4369584648287343,85.824023801574981,50.9113466162360169],"luv":[80.4369584648287343,54.1139445833304435,66.614143116349922],"rgb":[1,0.733333333333333282,0.333333333333333315],"xyz":[0.606481439676992,0.57458799284695472,0.164910604879758949],"hpluv":[50.9113466162360169,182.412290123698938,80.4369584648287343],"hsluv":[50.9113466162360169,100.000000000004846,80.4369584648287343]},"#ffbb66":{"lch":[80.6063993458739532,79.8959983704508545,48.5678239065140147],"luv":[80.6063993458739532,52.8698192869345931,59.9011916757752374],"rgb":[1,0.733333333333333282,0.4],"xyz":[0.614066435450500214,0.577621991156358,0.20485824928690291],"hpluv":[48.5678239065140147,171.553596694327723,80.6063993458739532],"hsluv":[48.5678239065140147,100.000000000004945,80.6063993458739532]},"#ffbb77":{"lch":[80.8136549908608828,73.0715029906331353,45.3006510664637219],"luv":[80.8136549908608828,51.397517928562209,51.9397699272266067],"rgb":[1,0.733333333333333282,0.466666666666666674],"xyz":[0.623380448470702064,0.58134759636443889,0.253912051193300847],"hpluv":[45.3006510664637219,158.885762577352,80.8136549908608828],"hsluv":[45.3006510664637219,100.000000000005144,80.8136549908608828]},"#ffbb88":{"lch":[81.0603921498240823,65.5982066090816,40.7273497798256443],"luv":[81.0603921498240823,49.7118280718431649,42.8002203275083914],"rgb":[1,0.733333333333333282,0.533333333333333326],"xyz":[0.634520865572646,0.585803763205216432,0.312584914596873],"hpluv":[40.7273497798256443,144.809180382553194,81.0603921498240823],"hsluv":[40.7273497798256443,100.0000000000054,81.0603921498240823]},"#ffbb99":{"lch":[81.347989327564818,57.8755898316684423,34.2609783084776538],"luv":[81.347989327564818,47.8331272298795724,32.5818329406692087],"rgb":[1,0.733333333333333282,0.6],"xyz":[0.64757782968171862,0.591026548848845645,0.381351592237990866],"hpluv":[34.2609783084776538,130.060421106466862,81.347989327564818],"hsluv":[34.2609783084776538,100.000000000005514,81.347989327564818]},"#ffbbaa":{"lch":[81.6775593509345725,50.5427251754064883,25.056975338279841],"luv":[81.6775593509345725,45.7860019440054415,21.405819165362459],"rgb":[1,0.733333333333333282,0.66666666666666663],"xyz":[0.662635522646971231,0.597049626034946712,0.460655441854989522],"hpluv":[25.056975338279841,115.96007016550756,81.6775593509345725],"hsluv":[25.056975338279841,100.000000000005954,81.6775593509345725]},"#ffbbbb":{"lch":[82.0499666293022,44.6012959670408264,12.1770506300623094],"luv":[82.0499666293022,43.5977873399533138,9.40789779917804125],"rgb":[1,0.733333333333333282,0.733333333333333282],"xyz":[0.679773114754307795,0.603904662877881471,0.550913426953631213],"hpluv":[12.1770506300623094,104.793068167285782,82.0499666293022],"hsluv":[12.1770506300623094,100.000000000006168,82.0499666293022]},"#ffbbcc":{"lch":[82.4658415859876,41.4263127316455169,355.474040938847054],"luv":[82.4658415859876,41.2971323922898534,-3.26898190783910625],"rgb":[1,0.733333333333333282,0.8],"xyz":[0.699065490198029549,0.611621613055370328,0.652519937623901369],"hpluv":[355.474040938847054,100.004408983591958,82.4658415859876],"hsluv":[355.474040938847054,100.000000000006509,82.4658415859876]},"#ffbbdd":{"lch":[82.9255937413379,42.2590852539423381,337.045135839305544],"luv":[82.9255937413379,38.9126886018087319,-16.4812909773061058],"rgb":[1,0.733333333333333282,0.866666666666666696],"xyz":[0.720583815748663148,0.620228943275623834,0.765849785523907367],"hpluv":[337.045135839305544,105.181583048825317,82.9255937413379],"hsluv":[337.045135839305544,100.000000000006992,82.9255937413379]},"#ffbbee":{"lch":[83.4294243398036315,47.2826492521794748,320.476273654572083],"luv":[83.4294243398036315,36.4719970678196077,-30.0905691237235686],"rgb":[1,0.733333333333333282,0.933333333333333348],"xyz":[0.744395996014837857,0.629753815382093851,0.89126060159243059],"hpluv":[320.476273654572083,121.793886282549721,83.4294243398036315],"hsluv":[320.476273654572083,100.000000000007375,83.4294243398036315]},"#ffbbff":{"lch":[83.9773390427358493,55.5806936350452148,307.715012949246614],"luv":[83.9773390427358493,34.0006189291922496,-43.9678452665650781],"rgb":[1,0.733333333333333282,1],"xyz":[0.770567044424669279,0.640222234746026575,1.02909478988421244],"hpluv":[307.715012949246614,148.765749509941259,83.9773390427358493],"hsluv":[307.715012949246614,100.00000000000793,83.9773390427358493]},"#aa3300":{"lch":[39.4372171279304595,100.717281062042773,18.6056676884160446],"luv":[39.4372171279304595,95.4534790945485838,32.1341568004684959],"rgb":[0.66666666666666663,0.2,0],"xyz":[0.177609683996858475,0.109151647655369471,0.0117164749512008691],"hpluv":[18.6056676884160446,324.068678498457416,39.4372171279304595],"hsluv":[18.6056676884160446,100.00000000000226,39.4372171279304595]},"#aa3311":{"lch":[39.5056415087576553,98.9056898290362199,17.5539290045831464],"luv":[39.5056415087576553,94.2999972712563,29.8302865423477179],"rgb":[0.66666666666666663,0.2,0.0666666666666666657],"xyz":[0.178621349496495607,0.109556313855224324,0.0170445799159565023],"hpluv":[17.5539290045831464,317.688492914835,39.5056415087576553],"hsluv":[17.5539290045831464,94.2489803369173558,39.5056415087576553]},"#aa3322":{"lch":[39.6320377265530155,95.7434230458582789,15.5633947922033684],"luv":[39.6320377265530155,92.2329117474569102,25.688383505468213],"rgb":[0.66666666666666663,0.2,0.133333333333333331],"xyz":[0.180496707634972609,0.110306457110615139,0.0269214661119356949],"hpluv":[15.5633947922033684,306.55039093266322,39.6320377265530155],"hsluv":[15.5633947922033684,83.9544037116345123,39.6320377265530155]},"#aa3333":{"lch":[39.8389046640011415,91.0660982539230162,12.1770506300618351],"luv":[39.8389046640011415,89.0171529654153488,19.2088711049089049],"rgb":[0.66666666666666663,0.2,0.2],"xyz":[0.18358445836743037,0.111541557403598252,0.0431836199695468381],"hpluv":[12.1770506300618351,290.060550373943784,39.8389046640011415],"hsluv":[12.1770506300618351,67.9701775681036366,39.8389046640011415]},"#aa3344":{"lch":[40.1348956250933142,85.3951569144799691,7.07959423789482756],"luv":[40.1348956250933142,84.7440953003879116,10.5247867516366789],"rgb":[0.66666666666666663,0.2,0.266666666666666663],"xyz":[0.18804245361164923,0.113324755501285832,0.0666623949224334766],"hpluv":[7.07959423789482756,269.991710008472637,40.1348956250933142],"hsluv":[7.07959423789482756,69.5294395234689659,40.1348956250933142]},"#aa3355":{"lch":[40.5259588707466,79.61783322386637,359.98582832830067],"luv":[40.5259588707466,79.6178307884273693,-0.0196928603108827253],"rgb":[0.66666666666666663,0.2,0.333333333333333315],"xyz":[0.194004867651011215,0.115709721117030664,0.098064442196407392],"hpluv":[359.98582832830067,249.296614878837403,40.5259588707466],"hsluv":[359.98582832830067,71.3920974276079079,40.5259588707466]},"#aa3366":{"lch":[41.0157539995587683,74.8661602955128558,350.806369630673316],"luv":[41.0157539995587683,73.9044320805857,-11.9614746682639641],"rgb":[0.66666666666666663,0.2,0.4],"xyz":[0.2015898634245194,0.118743719426433983,0.138012086603551354],"hpluv":[350.806369630673316,231.619002340768361,41.0157539995587683],"hsluv":[350.806369630673316,73.4562780141226597,41.0157539995587683]},"#aa3377":{"lch":[41.6059173351841167,72.2728884464882668,339.921631600955322],"luv":[41.6059173351841167,67.8804264173117531,-24.8116527825629412],"rgb":[0.66666666666666663,0.2,0.466666666666666674],"xyz":[0.210903876444721305,0.122469324634514792,0.187065888509949263],"hpluv":[339.921631600955322,220.424384448141751,41.6059173351841167],"hsluv":[339.921631600955322,75.6166865764569138,41.6059173351841167]},"#aa3388":{"lch":[42.296293156356171,72.6091331125239918,328.324027314743319],"luv":[42.296293156356171,61.7926517819245191,-38.1281313089174],"rgb":[0.66666666666666663,0.2,0.533333333333333326],"xyz":[0.222044293546665161,0.12692549147529239,0.24573875191352143],"hpluv":[328.324027314743319,217.83530631356345,42.296293156356171],"hsluv":[328.324027314743319,77.7798333688196237,42.296293156356171]},"#aa3399":{"lch":[43.0851702185186838,75.9982874692542794,317.281450106519685],"luv":[43.0851702185186838,55.835561651799118,-51.5570533805758799],"rgb":[0.66666666666666663,0.2,0.6],"xyz":[0.235101257655737861,0.132148277118921548,0.314505429554639337],"hpluv":[317.281450106519685,223.828466633931441,43.0851702185186838],"hsluv":[317.281450106519685,79.8726039522015441,43.0851702185186838]},"#aa33aa":{"lch":[43.9695321467927229,81.9717995507402861,307.715012949243828],"luv":[43.9695321467927229,50.1449646844158607,-64.8448798162617521],"rgb":[0.66666666666666663,0.2,0.66666666666666663],"xyz":[0.250158950620990417,0.138171354305022642,0.393809279171637938],"hpluv":[307.715012949243828,236.565795567314069,43.9695321467927229],"hsluv":[307.715012949243828,81.8445603498948628,43.9695321467927229]},"#aa33bb":{"lch":[44.9453163823579231,89.8045713491188593,299.92695612823394],"luv":[44.9453163823579231,44.8030997809084,-77.8302208992172],"rgb":[0.66666666666666663,0.2,0.733333333333333282],"xyz":[0.267296542728327036,0.145026391147957401,0.484067264270279685],"hpluv":[299.92695612823394,253.543994890590483,44.9453163823579231],"hsluv":[299.92695612823394,83.6659201788580305,44.9453163823579231]},"#aa33cc":{"lch":[46.0076707905516145,98.8168321279874249,293.782406660809556],"luv":[46.0076707905516145,39.8493034294229815,-90.425656359246986],"rgb":[0.66666666666666663,0.2,0.8],"xyz":[0.28658891817204879,0.152743341325446202,0.585673774940549841],"hpluv":[293.782406660809556,272.546121846523647,46.0076707905516145],"hsluv":[293.782406660809556,85.323407183561244,46.0076707905516145]},"#aa33dd":{"lch":[47.1511962508372804,108.497592079042477,288.982430572084695],"luv":[47.1511962508372804,35.2919015872993782,-102.597315604759743],"rgb":[0.66666666666666663,0.2,0.866666666666666696],"xyz":[0.308107243722682334,0.161350671545699736,0.699003622840555838],"hpluv":[288.982430572084695,291.989148013150611,47.1511962508372804],"hsluv":[288.982430572084695,86.8156421407842771,47.1511962508372804]},"#aa33ee":{"lch":[48.3701654903461247,118.505438755587946,285.224041333998457],"luv":[48.3701654903461247,31.1188262963008349,-114.346655677352729],"rgb":[0.66666666666666663,0.2,0.933333333333333348],"xyz":[0.331919423988857099,0.170875543652169781,0.824414438909079061],"hpluv":[285.224041333998457,310.885191630161273,48.3701654903461247],"hsluv":[285.224041333998457,89.3017266962351215,48.3701654903461247]},"#aa33ff":{"lch":[49.6587116356326135,128.627945638670809,282.256374557143658],"luv":[49.6587116356326135,27.305962831451918,-125.696192436653462],"rgb":[0.66666666666666663,0.2,1],"xyz":[0.358090472398688464,0.181343963016102477,0.962248627200860907],"hpluv":[282.256374557143658,328.684490794403757,49.6587116356326135],"hsluv":[282.256374557143658,99.9999999999991616,49.6587116356326135]},"#884400":{"lch":[36.685747441671559,64.5393704655657814,31.8123524502136021],"luv":[36.685747441671559,54.844205976921188,34.0212200082916922],"rgb":[0.533333333333333326,0.266666666666666663,0],"xyz":[0.122201478469054756,0.093692638490747937,0.0116493787366846978],"hpluv":[31.8123524502136021,223.237258003095718,36.685747441671559],"hsluv":[31.8123524502136021,100.000000000002245,36.685747441671559]},"#884411":{"lch":[36.7614898568215622,62.4864851085245405,30.2058215583615599],"luv":[36.7614898568215622,54.0023006087270119,31.4374354899146],"rgb":[0.533333333333333326,0.266666666666666663,0.0666666666666666657],"xyz":[0.123213143968691874,0.0940973046906027899,0.016977483701440331],"hpluv":[30.2058215583615599,215.691146343233044,36.7614898568215622],"hsluv":[30.2058215583615599,93.206231917801162,36.7614898568215622]},"#884422":{"lch":[36.9013237077522405,58.9550348899468375,27.0578850153250627],"luv":[36.9013237077522405,52.5022536375556825,26.8180816214102],"rgb":[0.533333333333333326,0.266666666666666663,0.133333333333333331],"xyz":[0.125088502107168903,0.0948474479459936,0.0268543698974195236],"hpluv":[27.0578850153250627,202.730122118290922,36.9013237077522405],"hsluv":[27.0578850153250627,81.1214838671569822,36.9013237077522405]},"#884433":{"lch":[37.1299605496210461,53.9021323280231357,21.3870333458705382],"luv":[37.1299605496210461,50.1903435049312,19.6562785990819577],"rgb":[0.533333333333333326,0.266666666666666663,0.2],"xyz":[0.128176252839626637,0.0960825482389767171,0.0431165237550306668],"hpluv":[21.3870333458705382,184.213216030002656,37.1299605496210461],"hsluv":[21.3870333458705382,62.5495295304316272,37.1299605496210461]},"#884444":{"lch":[37.4566279620983806,48.2433933618324389,12.1770506300619505],"luv":[37.4566279620983806,47.157939219998795,10.1761373608750691],"rgb":[0.533333333333333326,0.266666666666666663,0.266666666666666663],"xyz":[0.132634248083845524,0.0978657463366643,0.0665952987079173],"hpluv":[12.1770506300619505,163.436290620587812,37.4566279620983806],"hsluv":[12.1770506300619505,38.2981887065726,37.4566279620983806]},"#884455":{"lch":[37.8873893879065804,43.5926938841600631,358.470393497241901],"luv":[37.8873893879065804,43.5771602849424937,-1.16364151632571566],"rgb":[0.533333333333333326,0.266666666666666663,0.333333333333333315],"xyz":[0.138596662123207509,0.10025071195240913,0.0979973459818912207],"hpluv":[358.470393497241901,146.001848007416612,37.8873893879065804],"hsluv":[358.470393497241901,42.6300163695831245,37.8873893879065804]},"#884466":{"lch":[38.425613648805637,41.9872152878557756,340.815857604715632],"luv":[38.425613648805637,39.6555541095459816,-13.7972198610307206],"rgb":[0.533333333333333326,0.266666666666666663,0.4],"xyz":[0.146181657896715694,0.103284710261812449,0.137944990389035183],"hpluv":[340.815857604715632,138.655016432961,38.425613648805637],"hsluv":[340.815857604715632,47.3337116796912767,38.425613648805637]},"#884477":{"lch":[39.0722986805963117,44.7783217464764363,322.645837420375756],"luv":[39.0722986805963117,35.5943002873345478,-27.1688035343115608],"rgb":[0.533333333333333326,0.266666666666666663,0.466666666666666674],"xyz":[0.1554956709169176,0.107010315469893258,0.186998792295433092],"hpluv":[322.645837420375756,145.424700121889231,39.0722986805963117],"hsluv":[322.645837420375756,52.1510622716411,39.0722986805963117]},"#884488":{"lch":[39.8263740522966856,51.5911203050634839,307.71501294924451],"luv":[39.8263740522966856,31.5600599218946343,-40.8118403414738609],"rgb":[0.533333333333333326,0.266666666666666663,0.533333333333333326],"xyz":[0.166636088018861428,0.111466482310670856,0.245671655699005259],"hpluv":[307.71501294924451,164.377933698467302,39.8263740522966856],"hsluv":[307.71501294924451,56.8697587177058,39.8263740522966856]},"#884499":{"lch":[40.6850187117946192,61.0189075542410393,296.969581150574243],"luv":[40.6850187117946192,27.6731358367265301,-54.3829443123034295],"rgb":[0.533333333333333326,0.266666666666666663,0.6],"xyz":[0.179693052127934128,0.116689267954300013,0.314438333340123166],"hpluv":[296.969581150574243,190.313341437332326,40.6850187117946192],"hsluv":[296.969581150574243,61.3383523001243134,40.6850187117946192]},"#8844aa":{"lch":[41.643995358805,71.7935926347933417,289.536616505740085],"luv":[41.643995358805,24.0084388126510113,-67.6602897510042141],"rgb":[0.533333333333333326,0.266666666666666663,0.66666666666666663],"xyz":[0.194750745093186683,0.122712345140401108,0.393742182957121767],"hpluv":[289.536616505740085,218.762371943685849,41.643995358805],"hsluv":[289.536616505740085,65.4647221474276506,41.643995358805]},"#8844bb":{"lch":[42.6979882651059626,83.1164887776927515,284.352541737053286],"luv":[42.6979882651059626,20.6035404121657031,-80.5223250360828757],"rgb":[0.533333333333333326,0.266666666666666663,0.733333333333333282],"xyz":[0.21188833720052333,0.129567381983335866,0.484000168055763513],"hpluv":[284.352541737053286,247.012596783276,42.6979882651059626],"hsluv":[284.352541737053286,69.2054262339616741,42.6979882651059626]},"#8844cc":{"lch":[43.840927241858644,94.5481620176080924,280.647262826657595],"luv":[43.840927241858644,17.4689172853010533,-92.9203522904814463],"rgb":[0.533333333333333326,0.266666666666666663,0.8],"xyz":[0.231180712644245057,0.137284332160824668,0.585606678726033669],"hpluv":[280.647262826657595,273.660859280114778,43.840927241858644],"hsluv":[280.647262826657595,72.5522514276637764,43.840927241858644]},"#8844dd":{"lch":[45.0662821798681108,105.864396975636453,277.925647559652191],"luv":[45.0662821798681108,14.5974213234566292,-104.853163222292139],"rgb":[0.533333333333333326,0.266666666666666663,0.866666666666666696],"xyz":[0.2526990381948786,0.145891662381078202,0.698936526626039667],"hpluv":[277.925647559652191,298.083215805211921,45.0662821798681108],"hsluv":[277.925647559652191,79.9664783418063649,45.0662821798681108]},"#8844ee":{"lch":[46.3673172023828,116.961454232737537,275.874868362231723],"luv":[46.3673172023828,11.97173240994087,-116.347150370524886],"rgb":[0.533333333333333326,0.266666666666666663,0.933333333333333348],"xyz":[0.276511218461053365,0.155416534487548247,0.82434734269456289],"hpluv":[275.874868362231723,320.088534026972411,46.3673172023828],"hsluv":[275.874868362231723,89.9071832422553,46.3673172023828]},"#8844ff":{"lch":[47.7372988913525091,127.801124524511906,274.29427304351259],"luv":[47.7372988913525091,9.5696272486796623,-127.442338585146516],"rgb":[0.533333333333333326,0.266666666666666663,1],"xyz":[0.302682266870884731,0.165884953851480943,0.962181530986344735],"hpluv":[274.29427304351259,339.716123682654541,47.7372988913525091],"hsluv":[274.29427304351259,99.9999999999992468,47.7372988913525091]},"#ffcc00":{"lch":[84.1983464973243,98.3335943421723613,63.5926937648685069],"luv":[84.1983464973243,43.7338065737115329,88.0729807536005751],"rgb":[1,0.8,0],"xyz":[0.628309999332456237,0.644477406004528408,0.0913038854044243842],"hpluv":[63.5926937648685069,267.385577483165775,84.1983464973243],"hsluv":[63.5926937648685069,100.000000000007688,84.1983464973243]},"#ffcc11":{"lch":[84.2193135631731877,97.4576917861448777,63.4272907637844199],"luv":[84.2193135631731877,43.5960552023901897,87.1629833075564164],"rgb":[1,0.8,0.0666666666666666657],"xyz":[0.629321664832093397,0.644882072204383316,0.0966319903691800208],"hpluv":[63.4272907637844199,265.403720884510847,84.2193135631731877],"hsluv":[63.4272907637844199,100.000000000007645,84.2193135631731877]},"#ffcc22":{"lch":[84.2581577251319516,95.845309095571892,63.1144413478925301],"luv":[84.2581577251319516,43.342199386504106,85.4855369519677168],"rgb":[1,0.8,0.133333333333333331],"xyz":[0.631197022970570343,0.645632215459774117,0.106508876565159213],"hpluv":[63.1144413478925301,261.744085553517664,84.2581577251319516],"hsluv":[63.1144413478925301,100.00000000000766,84.2581577251319516]},"#ffcc33":{"lch":[84.3220485899852719,93.2224175872051148,62.5809741236821822],"luv":[84.3220485899852719,42.9284172035605494,82.7500461462124832],"rgb":[1,0.8,0.2],"xyz":[0.63428477370302816,0.646867315752757244,0.12277103042277035],"hpluv":[62.5809741236821822,255.758846695652977,84.3220485899852719],"hsluv":[62.5809741236821822,100.000000000007859,84.3220485899852719]},"#ffcc44":{"lch":[84.41414885501203,89.5051620308737,61.7678249437873745],"luv":[84.41414885501203,42.3400226901080785,78.8574442191356439],"rgb":[1,0.8,0.266666666666666663],"xyz":[0.638742768947247,0.64865051385044481,0.146249805375657],"hpluv":[61.7678249437873745,247.206609954939694,84.41414885501203],"hsluv":[61.7678249437873745,100.000000000007887,84.41414885501203]},"#ffcc55":{"lch":[84.5370662928161,84.6613331238571476,60.5932597011580469],"luv":[84.5370662928161,41.569242864558305,73.7532329730438221],"rgb":[1,0.8,0.333333333333333315],"xyz":[0.644705182986609,0.651035479466189559,0.177651852649630904],"hpluv":[60.5932597011580469,235.935294148211483,84.5370662928161],"hsluv":[60.5932597011580469,100.000000000008015,84.5370662928161]},"#ffcc66":{"lch":[84.6930007913096,78.7104448491835456,58.9357730127494222],"luv":[84.6930007913096,40.6144802919859131,67.4225342075500151],"rgb":[1,0.8,0.4],"xyz":[0.65229017876011719,0.654069477775592878,0.217599497056774865],"hpluv":[58.9357730127494222,221.881579382217893,84.6930007913096],"hsluv":[58.9357730127494222,100.000000000008285,84.6930007913096]},"#ffcc77":{"lch":[84.8838226897762809,71.7288671198513441,56.6053668146737863],"luv":[84.8838226897762809,39.4797505573258718,59.8863897244492378],"rgb":[1,0.8,0.466666666666666674],"xyz":[0.661604191780319,0.657795082983673729,0.266653298963172802],"hpluv":[56.6053668146737863,205.087229042099608,84.8838226897762809],"hsluv":[56.6053668146737863,100.000000000008399,84.8838226897762809]},"#ffcc88":{"lch":[85.1111193079521371,63.8628893840605159,53.2910582019814285],"luv":[85.1111193079521371,38.1740592359010691,51.1977523133063457],"rgb":[1,0.8,0.533333333333333326],"xyz":[0.672744608882263,0.662251249824451271,0.325326162366744942],"hpluv":[53.2910582019814285,185.743844227516831,85.1111193079521371],"hsluv":[53.2910582019814285,100.000000000008683,85.1111193079521371]},"#ffcc99":{"lch":[85.3762249003348899,55.3594884395636555,48.4608196634464292],"luv":[85.3762249003348899,36.710650975629143,41.436711563970924],"rgb":[1,0.8,0.6],"xyz":[0.685801572991335595,0.667474035468080484,0.394092840007862821],"hpluv":[48.4608196634464292,164.300705026796521,85.3762249003348899],"hsluv":[48.4608196634464292,100.000000000008811,85.3762249003348899]},"#ffccaa":{"lch":[85.6802414041430467,46.6394331206389836,41.1740083194267896],"luv":[85.6802414041430467,35.1061374539925311,30.7049806200222122],"rgb":[1,0.8,0.66666666666666663],"xyz":[0.700859265956588207,0.673497112654181551,0.473396689624861478],"hpluv":[41.1740083194267896,141.724192848301414,85.6802414041430467],"hsluv":[41.1740083194267896,100.000000000009393,85.6802414041430467]},"#ffccbb":{"lch":[86.0240539433014106,38.4677176438646384,29.8042196075727404],"luv":[86.0240539433014106,33.3795484258888635,19.1199123327444944],"rgb":[1,0.8,0.733333333333333282],"xyz":[0.71799685806392477,0.68035214949711631,0.563654674723503168],"hpluv":[29.8042196075727404,120.116808153279436,86.0240539433014106],"hsluv":[29.8042196075727404,100.000000000009621,86.0240539433014106]},"#ffcccc":{"lch":[86.4083433793485,32.2775975377643,12.1770506300627517],"luv":[86.4083433793485,31.5513664521307504,6.80841962670093892],"rgb":[1,0.8,0.8],"xyz":[0.737289233507646524,0.688069099674605167,0.665261185393773324],"hpluv":[12.1770506300627517,103.973607583717524,86.4083433793485],"hsluv":[12.1770506300627517,100.000000000010388,86.4083433793485]},"#ffccdd":{"lch":[86.8335972965778637,30.2635044437543748,348.373924949033096],"luv":[86.8335972965778637,29.6426074465171432,-6.09881340826452867],"rgb":[1,0.8,0.866666666666666696],"xyz":[0.758807559058280123,0.696676429894858673,0.778591033293779322],"hpluv":[348.373924949033096,100.994037434302086,86.8335972965778637],"hsluv":[348.373924949033096,100.000000000011042,86.8335972965778637]},"#ffccee":{"lch":[87.3001202800073344,33.8382691858854301,324.868297683069],"luv":[87.3001202800073344,27.6740002852911822,-19.4724977777928352],"rgb":[1,0.8,0.933333333333333348],"xyz":[0.782619739324454833,0.70620130200132869,0.904001849362302545],"hpluv":[324.868297683069,117.528800717138253,87.3001202800073344],"hsluv":[324.868297683069,100.000000000011482,87.3001202800073344]},"#ffccff":{"lch":[87.8080440143565255,41.9549825399590404,307.715012949248376],"luv":[87.8080440143565255,25.6653035474654807,-33.1890456889728],"rgb":[1,0.8,1],"xyz":[0.808790787734286254,0.716669721365261414,1.0418360376540845],"hpluv":[307.715012949248376,152.433043069806,87.8080440143565255],"hsluv":[307.715012949248376,100.000000000012506,87.8080440143565255]},"#aa4400":{"lch":[42.2796461632011074,91.196234940608619,23.7609213617016479],"luv":[42.2796461632011074,83.4659581293579578,36.7448921741641357],"rgb":[0.66666666666666663,0.266666666666666663,0],"xyz":[0.186442254479824487,0.126816788621301801,0.0146606651121894659],"hpluv":[23.7609213617016479,273.706361359402308,42.2796461632011074],"hsluv":[23.7609213617016479,100.000000000002331,42.2796461632011074]},"#aa4411":{"lch":[42.3415695164373815,89.5099073241138399,22.7237862619920179],"luv":[42.3415695164373815,82.5619515402106572,34.5766925405446202],"rgb":[0.66666666666666663,0.266666666666666663,0.0666666666666666657],"xyz":[0.18745391997946162,0.127221454821156654,0.0199887700769451],"hpluv":[22.7237862619920179,268.252316854423896,42.3415695164373815],"hsluv":[22.7237862619920179,95.0030043013494634,42.3415695164373815]},"#aa4422":{"lch":[42.4560124733741162,86.5487219398638,20.7501492775311753],"luv":[42.4560124733741162,80.9346773489764075,30.663647399501361],"rgb":[0.66666666666666663,0.266666666666666663,0.133333333333333331],"xyz":[0.189329278117938621,0.127971598076547483,0.0298656562729242916],"hpluv":[20.7501492775311753,258.678767688655569,42.4560124733741162],"hsluv":[20.7501492775311753,86.0172479577967692,42.4560124733741162]},"#aa4433":{"lch":[42.643470741830761,82.1252826930209494,17.3597256589108966],"luv":[42.643470741830761,78.3845002494828691,24.5037176372775498],"rgb":[0.66666666666666663,0.266666666666666663,0.2],"xyz":[0.192417028850396354,0.129206698369530582,0.0461278101305354349],"hpluv":[17.3597256589108966,244.378874013338617,42.643470741830761],"hsluv":[17.3597256589108966,71.9602068881057733,42.643470741830761]},"#aa4444":{"lch":[42.9120210749329871,76.685866981555165,12.1770506300619239],"luv":[42.9120210749329871,74.9604702767477704,16.1756017075590073],"rgb":[0.66666666666666663,0.266666666666666663,0.266666666666666663],"xyz":[0.196875024094615242,0.130989896467218175,0.0696065850834220734],"hpluv":[12.1770506300619239,226.764824908056937,42.9120210749329871],"hsluv":[12.1770506300619239,53.1380271992519795,42.9120210749329871]},"#aa4455":{"lch":[43.2674147484635299,71.0489272172787594,4.80785478807657096],"luv":[43.2674147484635299,70.7989329223205,5.9549270177674023],"rgb":[0.66666666666666663,0.266666666666666663,0.333333333333333315],"xyz":[0.202837438133977255,0.133374862082963,0.101008632357395989],"hpluv":[4.80785478807657096,208.370342069187018,43.2674147484635299],"hsluv":[4.80785478807657096,55.6796565441877931,43.2674147484635299]},"#aa4466":{"lch":[43.7134526285125489,66.3411716499448261,355.020980864279068],"luv":[43.7134526285125489,66.0908363196155477,-5.75781299290188],"rgb":[0.66666666666666663,0.266666666666666663,0.4],"xyz":[0.210422433907485412,0.136408860392366299,0.140956276764539951],"hpluv":[355.020980864279068,192.578302395247789,43.7134526285125489],"hsluv":[355.020980864279068,58.5402216503940949,43.7134526285125489]},"#aa4477":{"lch":[44.252209356870793,63.7921835342278598,343.127789968560137],"luv":[44.252209356870793,61.046215168807521,-18.5149208377531842],"rgb":[0.66666666666666663,0.266666666666666663,0.466666666666666674],"xyz":[0.219736446927687346,0.140134465600447122,0.19001007867093786],"hpluv":[343.127789968560137,182.924482874911519,44.252209356870793],"hsluv":[343.127789968560137,61.5848400189491372,44.252209356870793]},"#aa4488":{"lch":[44.8842146397509367,64.3242328637060865,330.281311898752961],"luv":[44.8842146397509367,55.8636578331810938,-31.8882214461946916],"rgb":[0.66666666666666663,0.266666666666666663,0.533333333333333326],"xyz":[0.230876864029631146,0.14459063244122472,0.248682942074510027],"hpluv":[330.281311898752961,181.852933643495049,44.8842146397509367],"hsluv":[330.281311898752961,64.6866121014520274,44.8842146397509367]},"#aa4499":{"lch":[45.6086312393750077,68.1395242873703779,318.091147538790551],"luv":[45.6086312393750077,50.7100032224043318,-45.5136281051387854],"rgb":[0.66666666666666663,0.266666666666666663,0.6],"xyz":[0.243933828138703873,0.149813418084853878,0.317449619715627906],"hpluv":[318.091147538790551,189.579504981677246,45.6086312393750077],"hsluv":[318.091147538790551,67.7395528675925,45.6086312393750077]},"#aa44aa":{"lch":[46.4234422285949293,74.7240378323112822,307.715012949244056],"luv":[46.4234422285949293,45.7112599542092468,-59.1114417296972476],"rgb":[0.66666666666666663,0.266666666666666663,0.66666666666666663],"xyz":[0.258991521103956401,0.155836495270954972,0.396753469332626507],"hpluv":[307.715012949244056,204.25011915803762,46.4234422285949293],"hsluv":[307.715012949244056,70.6643205278868862,46.4234422285949293]},"#aa44bb":{"lch":[47.3256474704596144,83.2556513741305224,299.464802712285689],"luv":[47.3256474704596144,40.9525224701243289,-72.4872015535482177],"rgb":[0.66666666666666663,0.266666666666666663,0.733333333333333282],"xyz":[0.276129113211293076,0.162691532113889731,0.487011454431268254],"hpluv":[299.464802712285689,223.2320179514779,47.3256474704596144],"hsluv":[299.464802712285689,73.4081717041738244,47.3256474704596144]},"#aa44cc":{"lch":[48.311463406953564,92.9774863668884564,293.103270963637385],"luv":[48.311463406953564,36.4834012629607827,-85.5206080625642073],"rgb":[0.66666666666666663,0.266666666666666663,0.8],"xyz":[0.29542148865501483,0.170408482291378532,0.58861796510153841],"hpluv":[293.103270963637385,244.211962975346665,48.311463406953564],"hsluv":[293.103270963637385,75.9413806031634806,48.311463406953564]},"#aa44dd":{"lch":[49.376518181476186,103.335675962773564,288.229438001673088],"luv":[49.376518181476186,32.3257723855767125,-98.1494083851717676],"rgb":[0.66666666666666663,0.266666666666666663,0.866666666666666696],"xyz":[0.316939814205648318,0.179015812511632066,0.701947813001544407],"hpluv":[288.229438001673088,265.563967984367252,49.376518181476186],"hsluv":[288.229438001673088,78.2521754793284572,49.376518181476186]},"#aa44ee":{"lch":[50.5160343838387149,113.969241853628489,284.471970959088878],"luv":[50.5160343838387149,28.4816380653286,-110.35299897060564],"rgb":[0.66666666666666663,0.266666666666666663,0.933333333333333348],"xyz":[0.340751994471823083,0.188540684618102111,0.82735862907006763],"hpluv":[284.471970959088878,286.284434407824506,50.5160343838387149],"hsluv":[284.471970959088878,88.5420288112715355,50.5160343838387149]},"#aa44ff":{"lch":[51.7249932896939271,124.658572052901789,281.540806859048416],"luv":[51.7249932896939271,24.9399169363974949,-122.138282816953421],"rgb":[0.66666666666666663,0.266666666666666663,1],"xyz":[0.366923042881654449,0.199009103982034807,0.965192817361849476],"hpluv":[281.540806859048416,305.816582895375404,51.7249932896939271],"hsluv":[281.540806859048416,99.9999999999991189,51.7249932896939271]},"#885500":{"lch":[40.7868302215615941,57.8204075903908716,44.0255445375638317],"luv":[40.7868302215615941,41.5746091122878738,40.1839695784202107],"rgb":[0.533333333333333326,0.333333333333333315,0],"xyz":[0.134014735183400707,0.117319151919440201,0.0155871309747999068],"hpluv":[44.0255445375638317,179.887306981779091,40.7868302215615941],"hsluv":[44.0255445375638317,100.000000000002402,40.7868302215615941]},"#885511":{"lch":[40.8520464566488215,55.8013246771799061,42.6953812551229817],"luv":[40.8520464566488215,41.012258348334349,37.838901951530346],"rgb":[0.533333333333333326,0.333333333333333315,0.0666666666666666657],"xyz":[0.135026400683037839,0.117723818119295054,0.0209152359395555383],"hpluv":[42.6953812551229817,173.328515822040885,40.8520464566488215],"hsluv":[42.6953812551229817,94.5141207032234121,40.8520464566488215]},"#885522":{"lch":[40.9725457623763205,52.2529579480882163,40.0436802938645613],"luv":[40.9725457623763205,40.0024704692244413,33.6180601862079769],"rgb":[0.533333333333333326,0.333333333333333315,0.133333333333333331],"xyz":[0.136901758821514841,0.118473961374685868,0.0307921221355347344],"hpluv":[40.0436802938645613,161.829338044896133,40.9725457623763205],"hsluv":[40.0436802938645613,84.6783920295854813,40.9725457623763205]},"#885533":{"lch":[41.169842808691,46.965215190705,35.0963808532685348],"luv":[41.169842808691,38.426283274472091,27.0028182162390955],"rgb":[0.533333333333333326,0.333333333333333315,0.2],"xyz":[0.139989509553972602,0.119709061667668981,0.0470542759931458776],"hpluv":[35.0963808532685348,144.75595347357384,41.169842808691],"hsluv":[35.0963808532685348,69.3663942781120113,41.169842808691]},"#885544":{"lch":[41.4523140669009891,40.5881659839312263,26.5063976077417607],"luv":[41.4523140669009891,36.321721997537459,18.1144066718387258],"rgb":[0.533333333333333326,0.333333333333333315,0.266666666666666663],"xyz":[0.144447504798191462,0.121492259765356561,0.0705330509460325161],"hpluv":[26.5063976077417607,124.248162385526584,41.4523140669009891],"hsluv":[26.5063976077417607,49.0053368988820708,41.4523140669009891]},"#885555":{"lch":[41.8258216452066449,34.5587016635497619,12.1770506300621708],"luv":[41.8258216452066449,33.7811467851905647,7.28958040957408926],"rgb":[0.533333333333333326,0.333333333333333315,0.333333333333333315],"xyz":[0.150409918837553447,0.123877225381101394,0.101935098220006432],"hpluv":[12.1770506300621708,104.846095879990827,41.8258216452066449],"hsluv":[12.1770506300621708,24.5686900376428454,41.8258216452066449]},"#885566":{"lch":[42.2941086985740071,31.3312262907584227,350.801819307985852],"luv":[42.2941086985740071,30.9283487442626033,-5.00829160852097477],"rgb":[0.533333333333333326,0.333333333333333315,0.4],"xyz":[0.157994914611061632,0.126911223690504699,0.141882742627150393],"hpluv":[350.801819307985852,94.0019456509277092,42.2941086985740071],"hsluv":[350.801819307985852,29.8132814869556348,42.2941086985740071]},"#885577":{"lch":[42.8590433503379202,33.3514130793808121,326.760730108285],"luv":[42.8590433503379202,27.8947491372056646,-18.2811302977648822],"rgb":[0.533333333333333326,0.333333333333333315,0.466666666666666674],"xyz":[0.167308927631263538,0.130636828898585522,0.190936544533548302],"hpluv":[326.760730108285,98.7440857113442263,42.8590433503379202],"hsluv":[326.760730108285,35.3342565461126838,42.8590433503379202]},"#885588":{"lch":[43.5208237898043535,40.5407907233736822,307.71501294924542],"luv":[43.5208237898043535,24.8001938501248809,-32.0703304858651137],"rgb":[0.533333333333333326,0.333333333333333315,0.533333333333333326],"xyz":[0.178449344733207393,0.13509299573936312,0.24960940793712047],"hpluv":[307.71501294924542,118.204615389413121,43.5208237898043535],"hsluv":[307.71501294924542,40.8951968507306276,43.5208237898043535]},"#885599":{"lch":[44.278184332936334,50.8805981998246,295.296495298175159],"luv":[44.278184332936334,21.7414099229374891,-46.0015909261276477],"rgb":[0.533333333333333326,0.333333333333333315,0.6],"xyz":[0.191506308842280093,0.140315781382992277,0.318376085578238377],"hpluv":[295.296495298175159,145.814841874582299,44.278184332936334],"hsluv":[295.296495298175159,46.3068912836000735,44.278184332936334]},"#8855aa":{"lch":[45.1286132569148819,62.6826496939872868,287.441560465434577],"luv":[45.1286132569148819,18.7880516159354372,-59.8006997378464717],"rgb":[0.533333333333333326,0.333333333333333315,0.66666666666666663],"xyz":[0.206564001807532649,0.146338858569093372,0.397679935195237],"hpluv":[287.441560465434577,176.252255995348207,45.1286132569148819],"hsluv":[287.441560465434577,51.4349240401982044,45.1286132569148819]},"#8855bb":{"lch":[46.0685799041538857,75.0110486022347374,282.303621490188448],"luv":[46.0685799041538857,15.9842650126874819,-73.2882029006783284],"rgb":[0.533333333333333326,0.333333333333333315,0.733333333333333282],"xyz":[0.223701593914869268,0.15319389541202813,0.487937920293878724],"hpluv":[282.303621490188448,206.613996430434867,46.0685799041538857],"hsluv":[282.303621490188448,56.1963190544194191,46.0685799041538857]},"#8855cc":{"lch":[47.0937627302438173,87.3889723072186229,278.789341148015808],"luv":[47.0937627302438173,13.3532090014702405,-86.3627482788434406],"rgb":[0.533333333333333326,0.333333333333333315,0.8],"xyz":[0.242993969358591022,0.160910845589516932,0.58954443096414888],"hpluv":[278.789341148015808,235.468364438494291,47.0937627302438173],"hsluv":[278.789341148015808,67.0071532265272083,47.0937627302438173]},"#8855dd":{"lch":[48.1992684502362323,99.579643468316263,276.285619014825784],"luv":[48.1992684502362323,10.9024601244232162,-98.9810171523426163],"rgb":[0.533333333333333326,0.333333333333333315,0.866666666666666696],"xyz":[0.264512294909224566,0.169518175809770466,0.702874278864154878],"hpluv":[276.285619014825784,262.161822059859048,48.1992684502362323],"hsluv":[276.285619014825784,77.9008511174594673,48.1992684502362323]},"#8855ee":{"lch":[49.3798334670730128,111.473561000814087,274.439637972028379],"luv":[49.3798334670730128,8.62903279282213198,-111.139077714648238],"rgb":[0.533333333333333326,0.333333333333333315,0.933333333333333348],"xyz":[0.288324475175399275,0.179043047916240511,0.828285094932678101],"hpluv":[274.439637972028379,286.45841220928196,49.3798334670730128],"hsluv":[274.439637972028379,88.8665998649397295,49.3798334670730128]},"#8855ff":{"lch":[50.6300011250937416,123.030386306339324,273.039422554437692],"luv":[50.6300011250937416,6.52344684402536235,-122.857318039912712],"rgb":[0.533333333333333326,0.333333333333333315,1],"xyz":[0.314495523585230696,0.189511467280173207,0.96611928322446],"hpluv":[273.039422554437692,308.349875308867752,50.6300011250937416],"hsluv":[273.039422554437692,99.9999999999992,50.6300011250937416]},"#ffdd00":{"lch":[88.435570144315335,99.3071523162376195,71.7429005549186911],"luv":[88.435570144315335,31.1110916577435432,94.3080615696447211],"rgb":[1,0.866666666666666696,0],"xyz":[0.670943989879631442,0.729745387098879927,0.105515215586815703],"hpluv":[71.7429005549186911,382.363935262913174,88.435570144315335],"hsluv":[71.7429005549186911,100.000000000012946,88.435570144315335]},"#ffdd11":{"lch":[88.454870819445,98.4678340856778,71.6448189166009826],"luv":[88.454870819445,31.0081800872079896,93.4580500395971683],"rgb":[1,0.866666666666666696,0.0666666666666666657],"xyz":[0.671955655379268602,0.730150053298734836,0.110843320551571339],"hpluv":[71.6448189166009826,379.826472639876158,88.454870819445],"hsluv":[71.6448189166009826,100.00000000001296,88.454870819445]},"#ffdd22":{"lch":[88.4906302718539735,96.9204819130462,71.4594307996413],"luv":[88.4906302718539735,30.8183922605744947,91.8901872494037093],"rgb":[1,0.866666666666666696,0.133333333333333331],"xyz":[0.673831013517745547,0.730900196554125636,0.120720206747550532],"hpluv":[71.4594307996413,375.129750349680876,88.4906302718539735],"hsluv":[71.4594307996413,100.00000000001296,88.4906302718539735]},"#ffdd33":{"lch":[88.5494544369894641,94.3967280931520776,71.1436744567929793],"luv":[88.5494544369894641,30.5086598694284135,89.330643945199526],"rgb":[1,0.866666666666666696,0.2],"xyz":[0.676918764250203364,0.732135296847108763,0.136982360605161668],"hpluv":[71.1436744567929793,367.416320973762822,88.5494544369894641],"hsluv":[71.1436744567929793,100.000000000013216,88.5494544369894641]},"#ffdd44":{"lch":[88.6342662809689301,90.8049878425315455,70.6631891871382152],"luv":[88.6342662809689301,30.0674100616276441,85.6825342136204284],"rgb":[1,0.866666666666666696,0.266666666666666663],"xyz":[0.681376759494422224,0.733918494944796329,0.160461135558048307],"hpluv":[70.6631891871382152,356.322085242203968,88.6342662809689301],"hsluv":[70.6631891871382152,100.000000000013173,88.6342662809689301]},"#ffdd55":{"lch":[88.7474847112806486,86.0957791731635353,69.970644696948483],"luv":[88.7474847112806486,29.4879375414461293,80.8884709398435433],"rgb":[1,0.866666666666666696,0.333333333333333315],"xyz":[0.687339173533784153,0.736303460560541079,0.191863182832022222],"hpluv":[69.970644696948483,341.559684906391112,88.7474847112806486],"hsluv":[69.970644696948483,100.000000000013429,88.7474847112806486]},"#ffdd66":{"lch":[88.8911610589964454,80.258955992054581,68.9956984045855819],"luv":[88.8911610589964454,28.7678627944319345,74.9260307715235427],"rgb":[1,0.866666666666666696,0.4],"xyz":[0.694924169307292394,0.739337458869944397,0.231810827239166184],"hpluv":[68.9956984045855819,322.902183683526573,88.8911610589964454],"hsluv":[68.9956984045855819,100.000000000013586,88.8911610589964454]},"#ffdd77":{"lch":[89.0670520916409885,73.323747836811151,67.6276760217336346],"luv":[89.0670520916409885,27.9087592291374555,67.8046691248198812],"rgb":[1,0.866666666666666696,0.466666666666666674],"xyz":[0.704238182327494244,0.743063064078025248,0.280864629145564093],"hpluv":[67.6276760217336346,300.178104609939055,89.0670520916409885],"hsluv":[67.6276760217336346,100.000000000014367,89.0670520916409885]},"#ffdd88":{"lch":[89.2766635023192379,65.3617696880632622,65.6822421460803554],"luv":[89.2766635023192379,26.9157684368328205,59.5625918359016637],"rgb":[1,0.866666666666666696,0.533333333333333326],"xyz":[0.715378599429438156,0.747519230918802791,0.339537492549136233],"hpluv":[65.6822421460803554,273.280966903928913,89.2766635023192379],"hsluv":[65.6822421460803554,100.00000000001468,89.2766635023192379]},"#ffdd99":{"lch":[89.5212778802452362,56.4966374008110606,62.8311838382076928],"luv":[89.5212778802452362,25.7971434460875209,50.2630821540094814],"rgb":[1,0.866666666666666696,0.6],"xyz":[0.7284355635385108,0.752742016562432,0.408304170190254168],"hpluv":[62.8311838382076928,242.212083001239,89.5212778802452362],"hsluv":[62.8311838382076928,100.000000000014893,89.5212778802452362]},"#ffddaa":{"lch":[89.8019739344538408,46.9317870748453103,58.439957868293348],"luv":[89.8019739344538408,24.5637119196041205,39.9902074859498],"rgb":[1,0.866666666666666696,0.66666666666666663],"xyz":[0.743493256503763411,0.75876509374853307,0.487608019807252768],"hpluv":[58.439957868293348,207.216087370130765,89.8019739344538408],"hsluv":[58.439957868293348,100.000000000015916,89.8019739344538408]},"#ffddbb":{"lch":[90.1196406145249114,37.0342016806554142,51.1553076529108282],"luv":[90.1196406145249114,23.228278171915747,28.8440494260352231],"rgb":[1,0.866666666666666696,0.733333333333333282],"xyz":[0.7606308486111,0.765620130591467829,0.57786600490589457],"hpluv":[51.1553076529108282,169.207898233907059,90.1196406145249114],"hsluv":[51.1553076529108282,100.00000000001647,90.1196406145249114]},"#ffddcc":{"lch":[90.4749882420216665,27.6093496047032829,37.8361109659034085],"luv":[90.4749882420216665,21.8049964890922183,16.9357111957368183],"rgb":[1,0.866666666666666696,0.8],"xyz":[0.779923224054821729,0.773337080768956686,0.679472515576164726],"hpluv":[37.8361109659034085,131.228146902908946,90.4749882420216665],"hsluv":[37.8361109659034085,100.000000000017565,90.4749882420216665]},"#ffdddd":{"lch":[90.8685579434819743,20.7762078419716971,12.1770506300632935],"luv":[90.8685579434819743,20.3087527298379129,4.38239373528981613],"rgb":[1,0.866666666666666696,0.866666666666666696],"xyz":[0.801441549605455328,0.781944410989210192,0.792802363476170724],"hpluv":[12.1770506300632935,103.332662997484363,90.8685579434819743],"hsluv":[12.1770506300632935,100.000000000018645,90.8685579434819743]},"#ffddee":{"lch":[91.3007301977477255,20.6730653908416642,335.121130580225611],"luv":[91.3007301977477255,18.7545890012647547,-8.69718483462634318],"rgb":[1,0.866666666666666696,0.933333333333333348],"xyz":[0.82525372987163,0.791469283095680209,0.918213179544694],"hpluv":[335.121130580225611,108.301670079840079,91.3007301977477255],"hsluv":[335.121130580225611,100.000000000019696,91.3007301977477255]},"#ffddff":{"lch":[91.7717330140538081,28.0468143452174594,307.715012949251673],"luv":[91.7717330140538081,17.1571994583452359,-22.1868046744377736],"rgb":[1,0.866666666666666696,1],"xyz":[0.851424778281461458,0.801937702459612933,1.05604736783647568],"hpluv":[307.715012949251673,155.925616416863875,91.7717330140538081],"hsluv":[307.715012949251673,100.000000000021274,91.7717330140538081]},"#aa5500":{"lch":[45.6948541105979729,81.8101604081173406,31.0178153240564285],"luv":[45.6948541105979729,70.1118895783240674,42.1571498770823254],"rgb":[0.66666666666666663,0.333333333333333315,0],"xyz":[0.198255511194170453,0.150443302049994065,0.0185984173503046732],"hpluv":[31.0178153240564285,227.184802334875343,45.6948541105979729],"hsluv":[31.0178153240564285,100.000000000002132,45.6948541105979729]},"#aa5511":{"lch":[45.7501207141343542,80.2053049231342357,30.0334267749456458],"luv":[45.7501207141343542,69.4364235827854088,40.1431690060082786],"rgb":[0.66666666666666663,0.333333333333333315,0.0666666666666666657],"xyz":[0.199267176693807585,0.150847968249848918,0.0239265223150603029],"hpluv":[30.0334267749456458,222.459100300712947,45.7501207141343542],"hsluv":[30.0334267749456458,95.7485290168496874,45.7501207141343542]},"#aa5522":{"lch":[45.8523093955831129,77.3637164970789826,28.1463245173948593],"luv":[45.8523093955831129,68.2151287979892231,36.4943945464800308],"rgb":[0.66666666666666663,0.333333333333333315,0.133333333333333331],"xyz":[0.201142534832284586,0.151598111505239747,0.0338034085110395],"hpluv":[28.1463245173948593,214.099393521154866,45.8523093955831129],"hsluv":[28.1463245173948593,88.0687786146531835,45.8523093955831129]},"#aa5533":{"lch":[46.0198296754266707,73.057054041475979,24.8605966968797674],"luv":[46.0198296754266707,66.2871018342682845,30.7140566456547255],"rgb":[0.66666666666666663,0.333333333333333315,0.2],"xyz":[0.20423028556474232,0.152833211798222846,0.0500655623686506457],"hpluv":[24.8605966968797674,201.444992058953261,46.0198296754266707],"hsluv":[24.8605966968797674,75.9647480733224683,46.0198296754266707]},"#aa5544":{"lch":[46.260105303202792,67.6400753638857,19.7251402693972757],"luv":[46.260105303202792,63.6711277752059743,22.829088529013422],"rgb":[0.66666666666666663,0.333333333333333315,0.266666666666666663],"xyz":[0.208688280808961207,0.154616409895910439,0.0735443373215372842],"hpluv":[19.7251402693972757,185.539675327038225,46.260105303202792],"hsluv":[19.7251402693972757,59.5831884891410581,46.260105303202792]},"#aa5555":{"lch":[46.5785950143652201,61.8404850960729462,12.1770506300619488],"luv":[46.5785950143652201,60.4491026496292108,13.0442165641410206],"rgb":[0.66666666666666663,0.333333333333333315,0.333333333333333315],"xyz":[0.21465069484832322,0.157001375511655272,0.1049463845955112],"hpluv":[12.1770506300619488,168.471262237657498,46.5785950143652201],"hsluv":[12.1770506300619488,39.4780386186733381,46.5785950143652201]},"#aa5566":{"lch":[46.9791292969753727,56.7719582569154682,1.70455911852653919],"luv":[46.9791292969753727,56.7468364589401801,1.68872621441415594],"rgb":[0.66666666666666663,0.333333333333333315,0.4],"xyz":[0.222235690621831378,0.160035373821058563,0.144894029002655161],"hpluv":[1.70455911852653919,153.34451205140752,46.9791292969753727],"hsluv":[1.70455911852653919,42.9013314457092818,46.9791292969753727]},"#aa5577":{"lch":[47.4641008255870247,53.815805251865207,348.374645401059922],"luv":[47.4641008255870247,52.7118371029350072,-10.8444974129891012],"rgb":[0.66666666666666663,0.333333333333333315,0.466666666666666674],"xyz":[0.231549703642033311,0.163760979029139386,0.193947830909053071],"hpluv":[348.374645401059922,143.874527939012694,47.4641008255870247],"hsluv":[348.374645401059922,46.6096363259647291,47.4641008255870247]},"#aa5588":{"lch":[48.0346061313586716,54.1759936988691209,333.519859036575326],"luv":[48.0346061313586716,48.4923339918738,-24.1564036495598238],"rgb":[0.66666666666666663,0.333333333333333315,0.533333333333333326],"xyz":[0.242690120743977111,0.168217145869916984,0.252620694312625238],"hpluv":[333.519859036575326,143.117248614217317,48.0346061313586716],"hsluv":[333.519859036575326,50.4580944804944309,48.0346061313586716]},"#aa5599":{"lch":[48.6905763376225,58.2309730669685877,319.412334073918828],"luv":[48.6905763376225,44.2212637341432782,-37.885697275903027],"rgb":[0.66666666666666663,0.333333333333333315,0.6],"xyz":[0.255747084853049866,0.173439931513546142,0.321387371953743117],"hpluv":[319.412334073918828,151.756904292295189,48.6905763376225],"hsluv":[319.412334073918828,54.3174516364451492,48.6905763376225]},"#aa55aa":{"lch":[49.4309115490906095,65.3990862514302904,307.715012949244453],"luv":[49.4309115490906095,40.0068668547544135,-51.7348150377284242],"rgb":[0.66666666666666663,0.333333333333333315,0.66666666666666663],"xyz":[0.270804777818302367,0.179463008699647236,0.400691221570741718],"hpluv":[307.715012949244453,167.885190443837445,49.4309115490906095],"hsluv":[307.715012949244453,58.0831627335764651,49.4309115490906095]},"#aa55bb":{"lch":[50.2536225490081137,74.6889496830887651,298.754319252296796],"luv":[50.2536225490081137,35.9294822147829578,-65.4790921786531896],"rgb":[0.66666666666666663,0.333333333333333315,0.733333333333333282],"xyz":[0.287942369925639041,0.186318045542582,0.490949206669383464],"hpluv":[298.754319252296796,188.594188212432869,50.2536225490081137],"hsluv":[298.754319252296796,61.6784311565058445,50.2536225490081137]},"#aa55cc":{"lch":[51.1559779262539394,85.2173265065914194,292.086991032215337],"luv":[51.1559779262539394,32.0428980728004476,-78.9635702082114],"rgb":[0.66666666666666663,0.333333333333333315,0.8],"xyz":[0.307234745369360795,0.194034995720070796,0.59255571733965362],"hpluv":[292.086991032215337,211.383381159177,51.1559779262539394],"hsluv":[292.086991032215337,65.0527897247966536,51.1559779262539394]},"#aa55dd":{"lch":[52.1346521614624407,96.3659410029227,287.126655540846059],"luv":[52.1346521614624407,28.3783197098194826,-92.0927008824589137],"rgb":[0.66666666666666663,0.333333333333333315,0.866666666666666696],"xyz":[0.328753070919994284,0.20264232594032433,0.705885565239659618],"hpluv":[287.126655540846059,234.550526854663673,52.1346521614624407],"hsluv":[287.126655540846059,75.3446722268955256,52.1346521614624407]},"#aa55ee":{"lch":[53.1858694266106227,107.745747725204239,283.388779775386126],"luv":[53.1858694266106227,24.9493252566021582,-104.817352199450397],"rgb":[0.66666666666666663,0.333333333333333315,0.933333333333333348],"xyz":[0.352565251186169049,0.212167198046794375,0.831296381308182841],"hpluv":[283.388779775386126,257.065149407391289,53.1858694266106227],"hsluv":[283.388779775386126,87.5522298773574335,53.1858694266106227]},"#aa55ff":{"lch":[54.3055382240479361,119.125691570750178,280.523377624217346],"luv":[54.3055382240479361,21.7567225446561139,-117.12205350114192],"rgb":[0.66666666666666663,0.333333333333333315,1],"xyz":[0.378736299596000414,0.222635617410727071,0.969130569599964686],"hpluv":[280.523377624217346,278.356033354379861,54.3055382240479361],"hsluv":[280.523377624217346,99.999999999999,54.3055382240479361]},"#886600":{"lch":[45.272583339231268,54.7393681124008964,58.6614018365849361],"luv":[45.272583339231268,28.4696504737342408,46.7533680417607513],"rgb":[0.533333333333333326,0.4,0],"xyz":[0.149042792889247183,0.147375267331133541,0.020596483543415256],"hpluv":[58.6614018365849361,153.427719347991228,45.272583339231268],"hsluv":[58.6614018365849361,100.000000000002288,45.272583339231268]},"#886611":{"lch":[45.3286132830504442,52.7569286908504935,57.8019218571504112],"luv":[45.3286132830504442,28.1114182485843394,44.6434954830448234],"rgb":[0.533333333333333326,0.4,0.0666666666666666657],"xyz":[0.150054458388884315,0.147779933530988394,0.0259245885081708857],"hpluv":[57.8019218571504112,147.688404254652824,45.3286132830504442],"hsluv":[57.8019218571504112,95.5933263309827765,45.3286132830504442]},"#886622":{"lch":[45.4322079122274616,49.2027541487777427,56.0700181971155658],"luv":[45.4322079122274616,27.4639619392241023,40.8245246197174367],"rgb":[0.533333333333333326,0.4,0.133333333333333331],"xyz":[0.151929816527361317,0.148530076786379223,0.0358014747041500853],"hpluv":[56.0700181971155658,137.424731357888106,45.4322079122274616],"hsluv":[56.0700181971155658,87.640709221506242,45.4322079122274616]},"#886633":{"lch":[45.6020177209920377,43.6934420281053448,52.7580970187872822],"luv":[45.6020177209920377,26.4424624059276816,34.7838045385277539],"rgb":[0.533333333333333326,0.4,0.2],"xyz":[0.155017567259819078,0.149765177079362322,0.0520636285617612285],"hpluv":[52.7580970187872822,121.582627853675135,45.6020177209920377],"hsluv":[52.7580970187872822,75.126145239043538,45.6020177209920377]},"#886644":{"lch":[45.8455444844743383,36.5157977851307862,46.6690567683987183],"luv":[45.8455444844743383,25.057552877875338,26.56167411246971],"rgb":[0.533333333333333326,0.4,0.266666666666666663],"xyz":[0.159475562504037938,0.151548375177049915,0.0755424035146478601],"hpluv":[46.6690567683987183,101.07016738030697,45.8455444844743383],"hsluv":[46.6690567683987183,58.2269221932267413,45.8455444844743383]},"#886655":{"lch":[46.1682850891648,28.5288655346450497,35.057100942904512],"luv":[46.1682850891648,23.3531590809093643,16.3867669061227161],"rgb":[0.533333333333333326,0.4,0.333333333333333315],"xyz":[0.165437976543399923,0.153933340792794748,0.106944450788621775],"hpluv":[35.057100942904512,78.4115584201214517,46.1682850891648],"hsluv":[35.057100942904512,37.5458750067509825,46.1682850891648]},"#886666":{"lch":[46.5740725388720946,21.8884171395184417,12.1770506300623786],"luv":[46.5740725388720946,21.3959378301945833,4.61699569417310141],"rgb":[0.533333333333333326,0.4,0.4],"xyz":[0.173022972316908108,0.156967339102198039,0.146892095195765737],"hpluv":[12.1770506300623786,59.6361320849851921,46.5740725388720946],"hsluv":[12.1770506300623786,13.9745942082290213,46.5740725388720946]},"#886677":{"lch":[47.0652698878111053,20.9860757761626395,336.621799391030947],"luv":[47.0652698878111053,19.2632377900225293,-8.32724722389627559],"rgb":[0.533333333333333326,0.4,0.466666666666666674],"xyz":[0.18233698533711,0.160692944310278862,0.195945897102163646],"hpluv":[336.621799391030947,56.5809206524471051,47.0652698878111053],"hsluv":[336.621799391030947,19.7183189325496855,47.0652698878111053]},"#886688":{"lch":[47.6429159175320649,27.8420771343032278,307.715012949247239],"luv":[47.6429159175320649,17.0319546757823481,-22.0248445868429776],"rgb":[0.533333333333333326,0.4,0.533333333333333326],"xyz":[0.193477402439053869,0.16514911115105646,0.254618760505735842],"hpluv":[307.715012949247239,74.1553731862279335,47.6429159175320649],"hsluv":[307.715012949247239,25.6555006249089494,47.6429159175320649]},"#886699":{"lch":[48.306860672000596,39.0046617113806562,292.251886736336132],"luv":[48.306860672000596,14.770249996667463,-36.0999078981538304],"rgb":[0.533333333333333326,0.4,0.6],"xyz":[0.206534366548126569,0.170371896794685618,0.323385438146853721],"hpluv":[292.251886736336132,102.458272059709785,48.306860672000596],"hsluv":[292.251886736336132,31.5854767603208231,48.306860672000596]},"#8866aa":{"lch":[49.0559053000777112,51.7871044207240132,284.005102499462396],"luv":[49.0559053000777112,12.5329093477081912,-50.2476901714407305],"rgb":[0.533333333333333326,0.4,0.66666666666666663],"xyz":[0.221592059513379125,0.176394973980786712,0.402689287763852322],"hpluv":[284.005102499462396,133.958310232957899,49.0559053000777112],"hsluv":[284.005102499462396,39.6059098285329867,49.0559053000777112]},"#8866bb":{"lch":[49.8879495217490074,65.0723394771694501,279.16089377463328],"luv":[49.8879495217490074,10.3599978518109275,-64.242352148271],"rgb":[0.533333333333333326,0.4,0.733333333333333282],"xyz":[0.238729651620715744,0.183250010823721471,0.492947272862494068],"hpluv":[279.16089377463328,165.516042277675325,49.8879495217490074],"hsluv":[279.16089377463328,51.4342030459355897,49.8879495217490074]},"#8866cc":{"lch":[50.800144438276476,78.3702679805165161,276.063171305995638],"luv":[50.800144438276476,8.2778522611756955,-77.9318680982312912],"rgb":[0.533333333333333326,0.4,0.8],"xyz":[0.258022027064437498,0.190966961001210273,0.594553783532764224],"hpluv":[276.063171305995638,195.760791019658512,50.800144438276476],"hsluv":[276.063171305995638,63.370404435102877,50.800144438276476]},"#8866dd":{"lch":[51.7890458420015278,91.4433004674113903,273.951375062119212],"luv":[51.7890458420015278,6.3013441888180548,-91.225929766636682],"rgb":[0.533333333333333326,0.4,0.866666666666666696],"xyz":[0.279540352615071042,0.199574291221463807,0.707883631432770222],"hpluv":[273.951375062119212,224.054313572832513,51.7890458420015278],"hsluv":[273.951375062119212,75.4110532620532,51.7890458420015278]},"#8866ee":{"lch":[52.8507624936088831,104.176067138923727,272.440799986921],"luv":[52.8507624936088831,4.4365578942807,-104.081554170680207],"rgb":[0.533333333333333326,0.4,0.933333333333333348],"xyz":[0.303352532881245751,0.209099163327933851,0.833294447501293445],"hpluv":[272.440799986921,250.124381092910085,52.8507624936088831],"hsluv":[272.440799986921,87.5962217171162365,52.8507624936088831]},"#8866ff":{"lch":[53.9810943197935273,116.520298408763196,271.319576027424205],"luv":[53.9810943197935273,2.6833355157121912,-116.48939716462327],"rgb":[0.533333333333333326,0.4,1],"xyz":[0.329523581291077172,0.219567582691866547,0.97112863579307529],"hpluv":[271.319576027424205,273.904539658900717,53.9810943197935273],"hsluv":[271.319576027424205,99.9999999999990621,53.9810943197935273]},"#ffee00":{"lch":[92.75564548426334,102.358730475882979,79.2433869538170228],"luv":[92.75564548426334,19.1039702538988,100.560171167180329],"rgb":[1,0.933333333333333348,0],"xyz":[0.718122766220146147,0.824102939779910892,0.121241474366986887],"hpluv":[79.2433869538170228,651.393632104361359,92.75564548426334],"hsluv":[79.2433869538170228,100.000000000024428,92.75564548426334]},"#ffee11":{"lch":[92.7734436379168,101.564402459740549,79.2015044483446218],"luv":[92.7734436379168,19.0286516433192254,99.765917344759373],"rgb":[1,0.933333333333333348,0.0666666666666666657],"xyz":[0.719134431719783307,0.824507605979765801,0.12656957933174251],"hpluv":[79.2015044483446218,648.021125158270593,92.7734436379168],"hsluv":[79.2015044483446218,100.000000000024428,92.7734436379168]},"#ffee22":{"lch":[92.8064212727168183,100.098587827824673,79.1224559985664797],"luv":[92.8064212727168183,18.8896613956421291,98.3000914418838079],"rgb":[1,0.933333333333333348,0.133333333333333331],"xyz":[0.721009789858260253,0.825257749235156601,0.136446465527721716],"hpluv":[79.1224559985664797,641.762708667564539,92.8064212727168183],"hsluv":[79.1224559985664797,100.000000000024357,92.8064212727168183]},"#ffee33":{"lch":[92.8606749716073665,97.7038183815635506,78.9881622996309147],"luv":[92.8606749716073665,18.6625824309063972,95.9048702796014396],"rgb":[1,0.933333333333333348,0.2],"xyz":[0.72409754059071807,0.826492849528139728,0.152708619385332867],"hpluv":[78.9881622996309147,631.438241912838748,92.8606749716073665],"hsluv":[78.9881622996309147,100.000000000024599,92.8606749716073665]},"#ffee44":{"lch":[92.9389094487226828,94.2867391890675606,78.7846200921967181],"luv":[92.9389094487226828,18.3385503337116411,92.4861436030564192],"rgb":[1,0.933333333333333348,0.266666666666666663],"xyz":[0.728555535834936929,0.828276047625827294,0.176187394338219505],"hpluv":[78.7846200921967181,616.484076987319668,92.9389094487226828],"hsluv":[78.7846200921967181,100.000000000025381,92.9389094487226828]},"#ffee55":{"lch":[93.0433700241155179,89.7896797607108,78.4929149488566082],"luv":[93.0433700241155179,17.9120631143144244,87.984911129805738],"rgb":[1,0.933333333333333348,0.333333333333333315],"xyz":[0.734517949874298859,0.830661013241572,0.207589441612193393],"hpluv":[78.4929149488566082,596.384103057951847,93.0433700241155179],"hsluv":[78.4929149488566082,100.000000000025906,93.0433700241155179]},"#ffee66":{"lch":[93.1759694096933,84.1867368500463,78.0854442567743661],"luv":[93.1759694096933,17.3805845725397461,82.3730656305550895],"rgb":[1,0.933333333333333348,0.4],"xyz":[0.7421029456478071,0.833695011550975362,0.247537086019337382],"hpluv":[78.0854442567743661,570.62648367707834,93.1759694096933],"hsluv":[78.0854442567743661,100.000000000026517,93.1759694096933]},"#ffee77":{"lch":[93.3383558005883742,77.4816602435733586,77.5195453952684659],"luv":[93.3383558005883742,16.7442947506152713,75.6507519288807515],"rgb":[1,0.933333333333333348,0.466666666666666674],"xyz":[0.751416958668009,0.837420616759056213,0.296590887925735291],"hpluv":[77.5195453952684659,538.663675570032183,93.3383558005883742],"hsluv":[77.5195453952684659,100.00000000002693,93.3383558005883742]},"#ffee88":{"lch":[93.5319535615141433,69.7063855050026433,76.7254067288761235],"luv":[93.5319535615141433,16.0058531534094222,67.8438858336072599],"rgb":[1,0.933333333333333348,0.533333333333333326],"xyz":[0.762557375769952861,0.841876783599833756,0.355263751329307431],"hpluv":[76.7254067288761235,499.867858345774721,93.5319535615141433],"hsluv":[76.7254067288761235,100.000000000028109,93.5319535615141433]},"#ffee99":{"lch":[93.7579894103796647,60.9203426164438397,75.5807218945013517],"luv":[93.7579894103796647,15.1701259512809905,59.0013171304435744],"rgb":[1,0.933333333333333348,0.6],"xyz":[0.775614339879025505,0.847099569243463,0.424030428970425366],"hpluv":[75.5807218945013517,453.479030486808085,93.7579894103796647],"hsluv":[75.5807218945013517,100.000000000029459,93.7579894103796647]},"#ffeeaa":{"lch":[94.0175103342715204,51.2122166590618946,73.8511258956299],"luv":[94.0175103342715204,14.2438643230739057,49.191497886124175],"rgb":[1,0.933333333333333348,0.66666666666666663],"xyz":[0.790672032844278116,0.853122646429564,0.503334278587424],"hpluv":[73.8511258956299,398.552269307706354,94.0175103342715204],"hsluv":[73.8511258956299,100.00000000003169,94.0175103342715204]},"#ffeebb":{"lch":[94.3113965930375855,40.7102572776027571,71.0277189369888],"luv":[94.3113965930375855,13.2353397134719373,38.4987120599845625],"rgb":[1,0.933333333333333348,0.733333333333333282],"xyz":[0.80780962495161468,0.859977683272498794,0.593592263686065658],"hpluv":[71.0277189369888,333.94796839081863,94.3113965930375855],"hsluv":[71.0277189369888,100.000000000032855,94.3113965930375855]},"#ffeecc":{"lch":[94.6403717602024841,29.6267857036886042,65.7803861656043125],"luv":[94.6403717602024841,12.1539519061426287,27.0190281874729799],"rgb":[1,0.933333333333333348,0.8],"xyz":[0.827102000395336434,0.867694633449987651,0.695198774356335814],"hpluv":[65.7803861656043125,258.601677072085806,94.6403717602024841],"hsluv":[65.7803861656043125,100.000000000035726,94.6403717602024841]},"#ffeedd":{"lch":[95.0050109981125814,18.4911495042727,53.4580761074439366],"luv":[95.0050109981125814,11.0098304435300403,14.8561853648264481],"rgb":[1,0.933333333333333348,0.866666666666666696],"xyz":[0.84862032594597,0.876301963670241157,0.808528622256341811],"hpluv":[53.4580761074439366,173.670551799097524,95.0050109981125814],"hsluv":[53.4580761074439366,100.000000000039279,95.0050109981125814]},"#ffeeee":{"lch":[95.4057483293867,10.0393308083340358,12.1770506300655121],"luv":[95.4057483293867,9.81345048674430487,2.11762900985580904],"rgb":[1,0.933333333333333348,0.933333333333333348],"xyz":[0.872432506212144743,0.885826835776711174,0.933939438324865],"hpluv":[12.1770506300655121,102.829227108855335,95.4057483293867],"hsluv":[12.1770506300655121,100.000000000042746,95.4057483293867]},"#ffeeff":{"lch":[95.8428833991312104,14.017983351086059,307.715012949261848],"luv":[95.8428833991312104,8.57528179129596,-11.0891117512266888],"rgb":[1,0.933333333333333348,1],"xyz":[0.898603554621976164,0.896295255140643898,1.07177362661664688],"hpluv":[307.715012949261848,159.207478793902965,95.8428833991312104],"hsluv":[307.715012949261848,100.000000000047876,95.8428833991312104]},"#aa6600":{"lch":[49.5566255632669623,74.0434564420528574,40.5370999312324685],"luv":[49.5566255632669623,56.2719368465296,48.1238253407432595],"rgb":[0.66666666666666663,0.4,0],"xyz":[0.213283568900016929,0.180499417461687406,0.0236077699189200241],"hpluv":[40.5370999312324685,189.593866720893345,49.5566255632669623],"hsluv":[40.5370999312324685,100.000000000002302,49.5566255632669623]},"#aa6611":{"lch":[49.6055800152373934,72.4782904829715449,39.6736286483530876],"luv":[49.6055800152373934,55.7860674256664097,46.2711278500211662],"rgb":[0.66666666666666663,0.4,0.0666666666666666657],"xyz":[0.214295234399654061,0.180904083661542259,0.0289358748836756538],"hpluv":[39.6736286483530876,185.402990863318706,49.6055800152373934],"hsluv":[39.6736286483530876,96.4267217319678878,49.6055800152373934]},"#aa6622":{"lch":[49.6961357673044404,69.6784302133091,38.0044715349972151],"luv":[49.6961357673044404,54.9040042209680124,42.902610147809348],"rgb":[0.66666666666666663,0.4,0.133333333333333331],"xyz":[0.216170592538131062,0.181654226916933087,0.0388127610796548533],"hpluv":[38.0044715349972151,177.916023719914563,49.6961357673044404],"hsluv":[38.0044715349972151,89.9454244119252593,49.6961357673044404]},"#aa6633":{"lch":[49.8446929303716502,65.3554895773238798,35.0519229290669685],"luv":[49.8446929303716502,53.5020897896209959,37.5348692023167061],"rgb":[0.66666666666666663,0.4,0.2],"xyz":[0.219258343270588796,0.182889327209916186,0.055074914937266],"hpluv":[35.0519229290669685,166.380518722129068,49.8446929303716502],"hsluv":[35.0519229290669685,79.6601301034586,49.8446929303716502]},"#aa6644":{"lch":[50.0579996788189163,59.7471791719702878,30.3078082111971625],"luv":[50.0579996788189163,51.5813401714318687,30.1511320703974341],"rgb":[0.66666666666666663,0.4,0.266666666666666663],"xyz":[0.223716338514807683,0.18467252530760378,0.0785536898901526282],"hpluv":[30.3078082111971625,151.454869534606559,50.0579996788189163],"hsluv":[30.3078082111971625,65.6016329960131,50.0579996788189163]},"#aa6655":{"lch":[50.3411543587309183,53.4384070136854916,23.0123473649378063],"luv":[50.3411543587309183,49.1858121787411307,20.8906492114991877],"rgb":[0.66666666666666663,0.4,0.333333333333333315],"xyz":[0.229678752554169696,0.187057490923348613,0.109955737164126544],"hpluv":[23.0123473649378063,134.70064023894011,50.3411543587309183],"hsluv":[23.0123473649378063,48.1262851503794238,50.3411543587309183]},"#aa6666":{"lch":[50.6979081899742283,47.4599132867605107,12.1770506300620198],"luv":[50.6979081899742283,46.3920870859415544,10.0108753362152232],"rgb":[0.66666666666666663,0.4,0.4],"xyz":[0.237263748327677854,0.190091489232751903,0.149903381571270505],"hpluv":[12.1770506300620198,118.788999996072334,50.6979081899742283],"hsluv":[12.1770506300620198,27.8359446414257086,50.6979081899742283]},"#aa6677":{"lch":[51.1308297914663399,43.3502150416948382,357.146673366158041],"luv":[51.1308297914663399,43.29647113668576,-2.15794607701909591],"rgb":[0.66666666666666663,0.4,0.466666666666666674],"xyz":[0.246577761347879787,0.193817094440832727,0.198957183477668414],"hpluv":[357.146673366158041,107.584013476394517,51.1308297914663399],"hsluv":[357.146673366158041,31.9217683762365354,51.1308297914663399]},"#aa6688":{"lch":[51.6414184020027,42.8134625942885876,339.120025752150127],"luv":[51.6414184020027,40.0018640870324234,-15.2592086582212207],"rgb":[0.66666666666666663,0.4,0.533333333333333326],"xyz":[0.257718178449823587,0.198273261281610325,0.257630046881240582],"hpluv":[339.120025752150127,105.201399585535427,51.6414184020027],"hsluv":[339.120025752150127,36.2396804223311,51.6414184020027]},"#aa6699":{"lch":[52.2302006219705675,46.6703467022409342,321.661853982703349],"luv":[52.2302006219705675,36.6065194780657563,-28.949680361091449],"rgb":[0.66666666666666663,0.4,0.6],"xyz":[0.270775142558896342,0.203496046925239482,0.326396724522358461],"hpluv":[321.661853982703349,113.385797667979,52.2302006219705675],"hsluv":[321.661853982703349,40.6514838109423,52.2302006219705675]},"#aa66aa":{"lch":[52.8968256208086274,54.2656136904176165,307.715012949245079],"luv":[52.8968256208086274,33.1961393674155048,-42.9275338250028753],"rgb":[0.66666666666666663,0.4,0.66666666666666663],"xyz":[0.285832835524148843,0.209519124111340577,0.405700574139357117],"hpluv":[307.715012949245079,130.177052782763241,52.8968256208086274],"hsluv":[307.715012949245079,45.0372955528084091,52.8968256208086274]},"#aa66bb":{"lch":[53.6401644756464293,64.2916348467718848,297.653919381785329],"luv":[53.6401644756464293,29.8396642728746109,-56.9474209016772193],"rgb":[0.66666666666666663,0.4,0.733333333333333282],"xyz":[0.302970427631485517,0.216374160954275335,0.495958559237998808],"hpluv":[297.653919381785329,152.091062924306783,53.6401644756464293],"hsluv":[297.653919381785329,49.3013965401631964,53.6401644756464293]},"#aa66cc":{"lch":[54.4584144535918853,75.6506824974921699,290.576693925999962],"luv":[54.4584144535918853,26.5882539678026326,-70.824363839571447],"rgb":[0.66666666666666663,0.4,0.8],"xyz":[0.322262803075207271,0.224091111131764137,0.597565069908269],"hpluv":[290.576693925999962,176.273563499159138,54.4584144535918853],"hsluv":[290.576693925999962,59.8478295858589107,54.4584144535918853]},"#aa66dd":{"lch":[55.3492064676394619,87.6329338161637423,285.539109011475546],"luv":[55.3492064676394619,23.4765185392287,-84.4297587732275],"rgb":[0.66666666666666663,0.4,0.866666666666666696],"xyz":[0.343781128625840759,0.232698441352017671,0.710894917808275],"hpluv":[285.539109011475546,200.907097340780666,55.3492064676394619],"hsluv":[285.539109011475546,72.9499123576365,55.3492064676394619]},"#aa66ee":{"lch":[56.3097127205812171,99.8160041995885337,281.866291349003632],"luv":[56.3097127205812171,20.525011879724925,-97.6829492885499775],"rgb":[0.66666666666666663,0.4,0.933333333333333348],"xyz":[0.367593308892015525,0.242223313458487716,0.836305733876798185],"hpluv":[281.866291349003632,224.934563930918017,56.3097127205812171],"hsluv":[281.866291349003632,86.3166325899195215,56.3097127205812171]},"#aa66ff":{"lch":[57.3367512293125543,111.956114799504135,279.118878442970129],"luv":[57.3367512293125543,17.7431860168323468,-110.541173283857603],"rgb":[0.66666666666666663,0.4,1],"xyz":[0.39376435730184689,0.252691732822420412,0.97413992216858],"hpluv":[279.118878442970129,247.773048158040382,57.3367512293125543],"hsluv":[279.118878442970129,99.9999999999988631,57.3367512293125543]},"#887700":{"lch":[50.0114915023736586,55.8665567864094825,73.357205010908],"luv":[50.0114915023736586,16.0004093344436384,53.5262465366231766],"rgb":[0.533333333333333326,0.466666666666666674,0],"xyz":[0.167496530942664812,0.184282743437969299,0.0267477295612209565],"hpluv":[73.357205010908,141.749463920516746,50.0114915023736586],"hsluv":[73.357205010908,100.000000000002359,50.0114915023736586]},"#887711":{"lch":[50.0597743565714524,53.993823922257576,73.0031869817398302],"luv":[50.0597743565714524,15.783394234863108,51.6354286142242103],"rgb":[0.533333333333333326,0.466666666666666674,0.0666666666666666657],"xyz":[0.168508196442301944,0.184687409637824151,0.0320758345259765862],"hpluv":[73.0031869817398302,136.865669051735267,50.0597743565714524],"hsluv":[73.0031869817398302,96.4507191106164328,50.0597743565714524]},"#887722":{"lch":[50.1490916772086592,50.5946145563497751,72.2920831328592755],"luv":[50.1490916772086592,15.3890953737340599,48.1974145124374616],"rgb":[0.533333333333333326,0.466666666666666674,0.133333333333333331],"xyz":[0.170383554580778945,0.18543755289321498,0.0419527207219557857],"hpluv":[72.2920831328592755,128.020802989304741,50.1490916772086592],"hsluv":[72.2920831328592755,90.012010730737714,50.1490916772086592]},"#887733":{"lch":[50.2956280558193356,45.1970113165044083,70.9372107781068735],"luv":[50.2956280558193356,14.7615306672340392,42.718462569532349],"rgb":[0.533333333333333326,0.466666666666666674,0.2],"xyz":[0.173471305313236679,0.186672653186198079,0.058214874579566929],"hpluv":[70.9372107781068735,114.029917097227894,50.2956280558193356],"hsluv":[70.9372107781068735,79.7918184760720237,50.2956280558193356]},"#887744":{"lch":[50.5060566549544916,37.8272673959478567,68.4411772520018076],"luv":[50.5060566549544916,13.89986571870684,35.1809023711225777],"rgb":[0.533333333333333326,0.466666666666666674,0.266666666666666663],"xyz":[0.177929300557455566,0.188455851283885673,0.0816936495324535605],"hpluv":[68.4411772520018076,95.0387759917387598,50.5060566549544916],"hsluv":[68.4411772520018076,65.8173762074568316,50.5060566549544916]},"#887755":{"lch":[50.7854328179731453,28.7445471843262688,63.5083223958924279],"luv":[50.7854328179731453,12.8220173934607509,25.7263456945161408],"rgb":[0.533333333333333326,0.466666666666666674,0.333333333333333315],"xyz":[0.183891714596817579,0.190840816899630505,0.113095696806427476],"hpluv":[63.5083223958924279,71.82169329487634,50.7854328179731453],"hsluv":[63.5083223958924279,48.4385690265679756,50.7854328179731453]},"#887766":{"lch":[51.1374932189691549,18.6360854649452037,51.6613245975388082],"luv":[51.1374932189691549,11.5601245482137447,14.6173596072111405],"rgb":[0.533333333333333326,0.466666666666666674,0.4],"xyz":[0.191476710370325737,0.193874815209033796,0.153043341213571438],"hpluv":[51.6613245975388082,46.2439140208651,51.1374932189691549],"hsluv":[51.6613245975388082,28.2492665088726049,51.1374932189691549]},"#887777":{"lch":[51.5648179079599629,10.388802862097231,12.1770506300635812],"luv":[51.5648179079599629,10.1550595801770775,2.19134429758843829],"rgb":[0.533333333333333326,0.466666666666666674,0.466666666666666674],"xyz":[0.20079072339052767,0.197600420417114619,0.202097143119969347],"hpluv":[12.1770506300635812,25.5653264810281158,51.5648179079599629],"hsluv":[12.1770506300635812,5.9907484084339373,51.5648179079599629]},"#887788":{"lch":[52.0689409540354262,14.1414171783799034,307.715012949252923],"luv":[52.0689409540354262,8.65079050214889378,-11.1867557182995974],"rgb":[0.533333333333333326,0.466666666666666674,0.533333333333333326],"xyz":[0.21193114049247147,0.202056587257892217,0.260770006523541542],"hpluv":[307.715012949252923,34.4630346227371902,52.0689409540354262],"hsluv":[307.715012949252923,11.9231603633022036,52.0689409540354262]},"#887799":{"lch":[52.6504441343355154,26.1446518461971777,285.73365348909897],"luv":[52.6504441343355154,7.08953673880610147,-25.1650807467009763],"rgb":[0.533333333333333326,0.466666666666666674,0.6],"xyz":[0.224988104601544198,0.207279372901521375,0.329536684164659421],"hpluv":[285.73365348909897,63.0115482025775862,52.6504441343355154],"hsluv":[285.73365348909897,20.7849368541844512,52.6504441343355154]},"#8877aa":{"lch":[53.3090485775123142,39.8165287152511951,277.951975125090712],"luv":[53.3090485775123142,5.50833871717125412,-39.4336678931764482],"rgb":[0.533333333333333326,0.466666666666666674,0.66666666666666663],"xyz":[0.240045797566796726,0.213302450087622469,0.408840533781658],"hpluv":[277.951975125090712,94.7767450693341118,53.3090485775123142],"hsluv":[277.951975125090712,33.2193336653547036,53.3090485775123142]},"#8877bb":{"lch":[54.043710164283695,53.8841311835491,274.190220195010625],"luv":[54.043710164283695,3.93720379281895738,-53.7400969453883732],"rgb":[0.533333333333333326,0.466666666666666674,0.733333333333333282],"xyz":[0.2571833896741334,0.220157486930557228,0.499098518880299769],"hpluv":[274.190220195010625,126.518797380186697,54.043710164283695],"hsluv":[274.190220195010625,46.027457746288988,54.043710164283695]},"#8877cc":{"lch":[54.8527197178713095,67.9360625264533695,272.023364737824068],"luv":[54.8527197178713095,2.39862107173988059,-67.8937052203839215],"rgb":[0.533333333333333326,0.466666666666666674,0.8],"xyz":[0.276475765117855099,0.22787443710804603,0.600705029550569924],"hpluv":[272.023364737824068,157.159823716941304,54.8527197178713095],"hsluv":[272.023364737824068,59.1220253911564413,54.8527197178713095]},"#8877dd":{"lch":[55.7338064566187228,81.7667290312133,270.636302714775695],"luv":[55.7338064566187228,0.90804807322034331,-81.7616867803042595],"rgb":[0.533333333333333326,0.466666666666666674,0.866666666666666696],"xyz":[0.297994090668488698,0.236481767328299564,0.714034877450575922],"hpluv":[270.636302714775695,186.164661983392193,55.7338064566187228],"hsluv":[270.636302714775695,72.4679508704990809,55.7338064566187228]},"#8877ee":{"lch":[56.6842419440431939,95.2620356561917419,269.684203716511661],"luv":[56.6842419440431939,-0.525051666249150784,-95.2605886928551229],"rgb":[0.533333333333333326,0.466666666666666674,0.933333333333333348],"xyz":[0.321806270934663408,0.246006639434769608,0.839445693519099145],"hpluv":[269.684203716511661,213.253830698535069,56.6842419440431939],"hsluv":[269.684203716511661,86.076772525698,56.6842419440431939]},"#8877ff":{"lch":[57.7009414002340577,108.362660778640901,268.997474997449615],"luv":[57.7009414002340577,-1.89596396936046907,-108.346073171359961],"rgb":[0.533333333333333326,0.466666666666666674,1],"xyz":[0.347977319344494829,0.256475058798702304,0.977279881810881],"hpluv":[268.997474997449615,238.306609639193027,57.7009414002340577],"hsluv":[268.997474997449615,99.9999999999988631,57.7009414002340577]},"#ffff00":{"lch":[97.1385593417967357,107.085608846920664,85.8743202181747307],"luv":[97.1385593417967357,7.70421917727499928,106.808111250898],"rgb":[1,1,0],"xyz":[0.76997513864982,0.92780768463926,0.138525598510210984],"hpluv":[85.8743202181747307,1784.23591835690763,97.1385593417967357],"hsluv":[85.8743202181747307,100.000000000072717,97.1385593417967357]},"#ffff11":{"lch":[97.1550055288865337,106.340968495662651,85.8743202181747307],"luv":[97.1550055288865337,7.65064640931757278,106.065400532478591],"rgb":[1,1,0.0666666666666666657],"xyz":[0.770986804149457194,0.928212350839114908,0.143853703474966621],"hpluv":[85.8743202181747307,1782.29032599077573,97.1550055288865337],"hsluv":[85.8743202181747307,100.000000000072447,97.1550055288865337]},"#ffff22":{"lch":[97.1854797367251564,104.966044999604463,85.8743202181747],"luv":[97.1854797367251564,7.5517282439387623,104.694039961158666],"rgb":[1,1,0.133333333333333331],"xyz":[0.77286216228793414,0.928962494094505709,0.1537305896709458],"hpluv":[85.8743202181747,1778.69938503976459,97.1854797367251564],"hsluv":[85.8743202181747,100.00000000007401,97.1854797367251564]},"#ffff33":{"lch":[97.2356193677236291,102.717517786777336,85.8743202181746312],"luv":[97.2356193677236291,7.38995910744871409,102.451339496695468],"rgb":[1,1,0.2],"xyz":[0.775949913020392,0.930197594387488835,0.16999274352855695],"hpluv":[85.8743202181746312,1772.83090468185333,97.2356193677236291],"hsluv":[85.8743202181746312,100.000000000075445,97.2356193677236291]},"#ffff44":{"lch":[97.3079311184623776,99.5042093292491,85.874320218174546],"luv":[97.3079311184623776,7.15877927938833114,99.2463578851537704],"rgb":[1,1,0.266666666666666663],"xyz":[0.780407908264610817,0.931980792485176401,0.193471518481443588],"hpluv":[85.874320218174546,1764.45330998562531,97.3079311184623776],"hsluv":[85.874320218174546,100.000000000077918,97.3079311184623776]},"#ffff55":{"lch":[97.4045015397841212,95.2663481722239283,85.8743202181744323],"luv":[97.4045015397841212,6.8538885331141568,95.0194785612246875],"rgb":[1,1,0.333333333333333315],"xyz":[0.786370322303972746,0.934365758100921151,0.224873565755417504],"hpluv":[85.8743202181744323,1753.42077174454698,97.4045015397841212],"hsluv":[85.8743202181744323,100.000000000080163,97.4045015397841212]},"#ffff66":{"lch":[97.5271149532436539,89.9715947326486258,85.8743202181742333],"luv":[97.5271149532436539,6.47296021391862286,89.7384457454272706],"rgb":[1,1,0.4],"xyz":[0.793955318077481,0.93739975641032447,0.264821210162561438],"hpluv":[85.8743202181742333,1739.66322518688298,97.5271149532436539],"hsluv":[85.8743202181742333,100.000000000084981,97.5271149532436539]},"#ffff77":{"lch":[97.6773170086398608,83.6127156419164663,85.8743202181740202],"luv":[97.6773170086398608,6.01547392080898469,83.3960448134325389],"rgb":[1,1,0.466666666666666674],"xyz":[0.803269331097682837,0.941125361618405321,0.313875012068959403],"hpluv":[85.8743202181740202,1723.18045161093028,97.6773170086398608],"hsluv":[85.8743202181740202,100.00000000009112,97.6773170086398608]},"#ffff88":{"lch":[97.8564527859654589,76.2055692953657342,85.8743202181736791],"luv":[97.8564527859654589,5.48257057790026181,76.0080930657330214],"rgb":[1,1,0.533333333333333326],"xyz":[0.814409748199626748,0.945581528459182863,0.372547875472531542],"hpluv":[85.8743202181736791,1704.03672017478311,97.8564527859654589],"hsluv":[85.8743202181736791,100.000000000099803,97.8564527859654589]},"#ffff99":{"lch":[98.0656913545514612,67.7868897983338741,85.8743202181732102],"luv":[98.0656913545514612,4.87689300155069283,67.6112294162950889],"rgb":[1,1,0.6],"xyz":[0.827466712308699393,0.950804314102812076,0.441314553113649422],"hpluv":[85.8743202181732102,1682.35465810463256,98.0656913545514612],"hsluv":[85.8743202181732102,100.000000000112891,98.0656913545514612]},"#ffffaa":{"lch":[98.3060425431328611,58.4116937234916094,85.8743202181725707],"luv":[98.3060425431328611,4.20239933084915052,58.260327869924204],"rgb":[1,1,0.66666666666666663],"xyz":[0.842524405273952,0.956827391288913143,0.520618402730648078],"hpluv":[85.8743202181725707,1658.30791632356272,98.3060425431328611],"hsluv":[85.8743202181725707,100.000000000127613,98.3060425431328611]},"#ffffbb":{"lch":[98.5783690162300559,48.1503065934375414,85.8743202181715759],"luv":[98.5783690162300559,3.46414909943131732,48.0255317103199246],"rgb":[1,1,0.733333333333333282],"xyz":[0.859661997381288567,0.963682428131847901,0.610876387829289769],"hpluv":[85.8743202181715759,1632.1126639545671,98.5783690162300559],"hsluv":[85.8743202181715759,100.000000000152809,98.5783690162300559]},"#ffffcc":{"lch":[98.8833954570195317,37.0851031688938804,85.8743202181698706],"luv":[98.8833954570195317,2.66806871718659799,36.9890022353654899],"rgb":[1,1,0.8],"xyz":[0.878954372825010322,0.971399378309336758,0.712482898499559925],"hpluv":[85.8743202181698706,1604.018210645404,98.8833954570195317],"hsluv":[85.8743202181698706,100.00000000019709,98.8833954570195317]},"#ffffdd":{"lch":[99.2217159651800245,25.3071072074552177,85.8743202181663889],"luv":[99.2217159651800245,1.82070684164607655,25.2415273271332552],"rgb":[1,1,0.866666666666666696],"xyz":[0.900472698375643921,0.980006708529590265,0.825812746399565922],"hpluv":[85.8743202181663889,1574.29719653830034,99.2217159651800245],"hsluv":[85.8743202181663889,100.000000000286278,99.2217159651800245]},"#ffffee":{"lch":[99.5938003805277248,12.9126149352850259,85.8743202181558161],"luv":[99.5938003805277248,0.928991455386458775,12.8791536733888243],"rgb":[1,1,0.933333333333333348],"xyz":[0.92428487864181863,0.989531580636060282,0.951223562468089145],"hpluv":[85.8743202181558161,1543.23583838085528,99.5938003805277248],"hsluv":[85.8743202181558161,100.000000000556355,99.5938003805277248]},"#ffffff":{"lch":[99.99999999999973,5.29610712429325706e-12,0],"luv":[99.99999999999973,4.97935026544381416e-12,1.80411241501587473e-12],"rgb":[1,1,1],"xyz":[0.95045592705165,0.999999999999993,1.0890577507598711],"hpluv":[0,0,100],"hsluv":[0,0,100]},"#aa7700":{"lch":[53.7507838912622304,69.116848270999057,51.9676330333141223],"luv":[53.7507838912622304,42.5833417137676875,54.4407726194696622],"rgb":[0.66666666666666663,0.466666666666666674,0],"xyz":[0.231737306953434558,0.217406893568523163,0.0297590159367257245],"hpluv":[51.9676330333141223,163.169299961930307,53.7507838912622304],"hsluv":[51.9676330333141223,100.000000000002359,53.7507838912622304]},"#aa7711":{"lch":[53.7940335015026,67.5786316453491906,51.3090056740019378],"luv":[53.7940335015026,42.244752971039,52.7470596476588653],"rgb":[0.66666666666666663,0.466666666666666674,0.0666666666666666657],"xyz":[0.23274897245307169,0.217811559768378016,0.0350871209014813543],"hpluv":[51.3090056740019378,159.40965108533166,53.7940335015026],"hsluv":[51.3090056740019378,97.0120153186068,53.7940335015026]},"#aa7722":{"lch":[53.874065271669366,64.7981771198060272,50.0272013346139],"luv":[53.874065271669366,41.6278947732915157,49.6580520640260588],"rgb":[0.66666666666666663,0.466666666666666674,0.133333333333333331],"xyz":[0.234624330591548691,0.218561703023768844,0.0449640070974605538],"hpluv":[50.0272013346139,152.623836787181489,53.874065271669366],"hsluv":[50.0272013346139,91.5730337049880632,53.874065271669366]},"#aa7733":{"lch":[54.0054384284815,60.4215101577181812,47.7291529037971785],"luv":[54.0054384284815,40.6416884431496115,44.7103125713654705],"rgb":[0.66666666666666663,0.466666666666666674,0.2],"xyz":[0.237712081324006452,0.219796803316751943,0.0612261609550717],"hpluv":[47.7291529037971785,141.968961696257139,54.0054384284815],"hsluv":[47.7291529037971785,82.890357503842381,54.0054384284815]},"#aa7744":{"lch":[54.1942453736720324,54.5501661616690754,43.9413891432679051],"luv":[54.1942453736720324,39.2788485799816911,37.8535689532252277],"rgb":[0.66666666666666663,0.466666666666666674,0.266666666666666663],"xyz":[0.242170076568225312,0.221580001414439537,0.0847049359079583286],"hpluv":[43.9413891432679051,127.726858599491337,54.1942453736720324],"hsluv":[43.9413891432679051,70.9191698542686453,54.1942453736720324]},"#aa7755":{"lch":[54.4451912879813307,47.55778496198932,37.8352816528713],"luv":[54.4451912879813307,37.5600659479400178,29.1716361638701045],"rgb":[0.66666666666666663,0.466666666666666674,0.333333333333333315],"xyz":[0.248132490607587297,0.22396496703018437,0.116106983181932244],"hpluv":[37.8352816528713,110.841250641501858,54.4451912879813307],"hsluv":[37.8352816528713,55.8697139193963039,54.4451912879813307]},"#aa7766":{"lch":[54.7618668139504621,40.2221891209492881,27.9562221290694595],"luv":[54.7618668139504621,35.5285027246357359,18.8560333004309904],"rgb":[0.66666666666666663,0.466666666666666674,0.4],"xyz":[0.255717486381095482,0.226998965339587661,0.156054627589076206],"hpluv":[27.9562221290694595,93.2023334238246264,54.7618668139504621],"hsluv":[27.9562221290694595,38.157009054435612,54.7618668139504621]},"#aa7777":{"lch":[55.1468928183874851,34.0080558607991321,12.1770506300622881],"luv":[55.1468928183874851,33.2428902595124569,7.17343088244713467],"rgb":[0.66666666666666663,0.466666666666666674,0.466666666666666674],"xyz":[0.265031499401297388,0.230724570547668484,0.205108429495474115],"hpluv":[12.1770506300622881,78.2528356679829074,55.1468928183874851],"hsluv":[12.1770506300622881,20.6006796366476941,55.1468928183874851]},"#aa7788":{"lch":[55.6020140468043849,31.2700131437067519,349.739442339375785],"luv":[55.6020140468043849,30.7699397165362107,-5.56996695217490778],"rgb":[0.66666666666666663,0.466666666666666674,0.533333333333333326],"xyz":[0.276171916503241244,0.235180737388446082,0.263781292899046282],"hpluv":[349.739442339375785,71.363619208349732,55.6020140468043849],"hsluv":[349.739442339375785,23.0952607722130772,55.6020140468043849]},"#aa7799":{"lch":[56.1281730235999845,34.0192547961324365,325.92167501088062],"luv":[56.1281730235999845,28.1772086346441704,-19.0618627223027133],"rgb":[0.66666666666666663,0.466666666666666674,0.6],"xyz":[0.289228880612313943,0.240403523032075239,0.332547970540164162],"hpluv":[325.92167501088062,76.9100717288581706,56.1281730235999845],"hsluv":[325.92167501088062,27.5449434619861648,56.1281730235999845]},"#aa77aa":{"lch":[56.7255784680210127,41.7295245342496131,307.715012949246272],"luv":[56.7255784680210127,25.5273831431779215,-33.0106941416859],"rgb":[0.66666666666666663,0.466666666666666674,0.66666666666666663],"xyz":[0.304286573577566499,0.246426600218176334,0.411851820157162818],"hpluv":[307.715012949246272,93.3477446513022642,56.7255784680210127],"hsluv":[307.715012949246272,32.2954766233998285,56.7255784680210127]},"#aa77bb":{"lch":[57.3937746480490176,52.417961949749369,295.873528074876958],"luv":[57.3937746480490176,22.8744713506946127,-47.1635589771554891],"rgb":[0.66666666666666663,0.466666666666666674,0.733333333333333282],"xyz":[0.321424165684903118,0.25328163706111112,0.502109805255804509],"hpluv":[295.873528074876958,115.892323381948941,57.3937746480490176],"hsluv":[295.873528074876958,41.7229864085831679,57.3937746480490176]},"#aa77cc":{"lch":[58.1317139736185,64.5762938068646548,288.286403622885132],"luv":[58.1317139736185,20.2619194712353625,-61.3151885031081],"rgb":[0.66666666666666663,0.466666666666666674,0.8],"xyz":[0.340716541128624872,0.260998587238599922,0.603716315926074665],"hpluv":[288.286403622885132,140.961111207958226,58.1317139736185],"hsluv":[288.286403622885132,55.678510160825347,58.1317139736185]},"#aa77dd":{"lch":[58.9378328182195759,77.3666791836153,283.242275299631103],"luv":[58.9378328182195759,17.7223199365118553,-75.3095108466943088],"rgb":[0.66666666666666663,0.466666666666666674,0.866666666666666696],"xyz":[0.362234866679258416,0.269605917458853428,0.717046163826080662],"hpluv":[283.242275299631103,166.570895286205939,58.9378328182195759],"hsluv":[283.242275299631103,70.0408478070886105,58.9378328182195759]},"#aa77ee":{"lch":[59.8101292792768646,90.3373867943789151,279.736895248195651],"luv":[59.8101292792768646,15.2782276108220607,-89.0360556960445138],"rgb":[0.66666666666666663,0.466666666666666674,0.933333333333333348],"xyz":[0.386047046945433125,0.279130789565323445,0.842456979894603886],"hpluv":[279.736895248195651,191.660275847677298,59.8101292792768646],"hsluv":[279.736895248195651,84.8029379630096685,59.8101292792768646]},"#aa77ff":{"lch":[60.7462409754246551,103.238062985892157,277.202485092995744],"luv":[60.7462409754246551,12.9436026905507742,-102.423438716283115],"rgb":[0.66666666666666663,0.466666666666666674,1],"xyz":[0.412218095355264547,0.289599208929256169,0.980291168186385731],"hpluv":[277.202485092995744,215.655115976047284,60.7462409754246551],"hsluv":[277.202485092995744,99.999999999998721,60.7462409754246551]},"#888800":{"lch":[54.9099926918455452,60.532810441385358,85.8743202181747449],"luv":[54.9099926918455452,4.35500198466006783,60.375948006191166],"rgb":[0.533333333333333326,0.533333333333333326,0],"xyz":[0.189568900667635265,0.228427482887910871,0.0341051861362109063],"hpluv":[85.8743202181747449,139.887458074797593,54.9099926918455452],"hsluv":[85.8743202181747449,100.000000000002331,54.9099926918455452]},"#888811":{"lch":[54.9518410557904673,58.8347385736240369,85.8743202181746739],"luv":[54.9518410557904673,4.23283507550337568,58.6822764576347353],"rgb":[0.533333333333333326,0.533333333333333326,0.0666666666666666657],"xyz":[0.190580566167272397,0.228832149087765724,0.039433291100966536],"hpluv":[85.8743202181746739,135.85978011465275,54.9518410557904673],"hsluv":[85.8743202181746739,97.1207726442580395,54.9518410557904673]},"#888822":{"lch":[55.0292864560463215,55.7361292450240882,85.8743202181745602],"luv":[55.0292864560463215,4.00990721741558787,55.5916967480373643],"rgb":[0.533333333333333326,0.533333333333333326,0.133333333333333331],"xyz":[0.192455924305749398,0.229582292343156552,0.0493101772969457355],"hpluv":[85.8743202181745602,128.523412903997382,55.0292864560463215],"hsluv":[85.8743202181745602,91.8762944675706,55.0292864560463215]},"#888833":{"lch":[55.1564325013520573,50.7686053645684225,85.8743202181742902],"luv":[55.1564325013520573,3.65252126093227947,50.6370455210582335],"rgb":[0.533333333333333326,0.533333333333333326,0.2],"xyz":[0.195543675038207132,0.230817392636139651,0.0655723311545568788],"hpluv":[85.8743202181742902,116.798802852822334,55.1564325013520573],"hsluv":[85.8743202181742902,83.4948353914423,55.1564325013520573]},"#888844":{"lch":[55.3392041906722767,43.8756115710196184,85.8743202181737786],"luv":[55.3392041906722767,3.15660835961073616,43.7619139708837039],"rgb":[0.533333333333333326,0.533333333333333326,0.266666666666666663],"xyz":[0.20000167028242602,0.232600590733827245,0.0890511061074435173],"hpluv":[85.8743202181737786,100.607324583255647,55.3392041906722767],"hsluv":[85.8743202181737786,71.9201892491773833,55.3392041906722767]},"#888855":{"lch":[55.5822005995452173,35.1333862553221152,85.8743202181729],"luv":[55.5822005995452173,2.5276534453655044,35.0423429271758167],"rgb":[0.533333333333333326,0.533333333333333326,0.333333333333333315],"xyz":[0.205964084321788032,0.234985556349572078,0.120453153381417433],"hpluv":[85.8743202181729,80.2090919262666233,55.5822005995452173],"hsluv":[85.8743202181729,57.3383011101545321,55.5822005995452173]},"#888866":{"lch":[55.8889601924437187,24.7258905438507242,85.874320218171],"luv":[55.8889601924437187,1.778891507033598,24.6618168064052092],"rgb":[0.533333333333333326,0.533333333333333326,0.4],"xyz":[0.21354908009529619,0.238019554658975369,0.160400797788561394],"hpluv":[85.874320218171,56.1390732800859524,55.8889601924437187],"hsluv":[85.874320218171,40.1315986813270698,55.8889601924437187]},"#888877":{"lch":[56.2621011123828509,12.9137749110131566,85.8743202181651668],"luv":[56.2621011123828509,0.929074909242871283,12.8803106431998842],"rgb":[0.533333333333333326,0.533333333333333326,0.466666666666666674],"xyz":[0.222863093115498123,0.241745159867056192,0.209454599694959304],"hpluv":[85.8743202181651668,29.1257147579972724,56.2621011123828509],"hsluv":[85.8743202181651668,20.8208192205656601,56.2621011123828509]},"#888888":{"lch":[56.703410756754252,2.95076376078202623e-12,0],"luv":[56.703410756754252,2.78254170310414444e-12,9.82073542272051e-13],"rgb":[0.533333333333333326,0.533333333333333326,0.533333333333333326],"xyz":[0.234003510217441923,0.24620132670783379,0.268127463098531471],"hpluv":[0,6.60335407213460764e-12,56.703410756754252],"hsluv":[0,2.14018342731852893e-12,56.703410756754252]},"#888899":{"lch":[57.2139150634865246,13.7029898302256612,265.874320218188814],"luv":[57.2139150634865246,-0.985854571612734376,-13.6674804207248872],"rgb":[0.533333333333333326,0.533333333333333326,0.6],"xyz":[0.247060474326514651,0.251424112351462947,0.33689414073964935],"hpluv":[265.874320218188814,30.3915601408835876,57.2139150634865246],"hsluv":[265.874320218188814,12.5386286039598396,57.2139150634865246]},"#8888aa":{"lch":[57.7939415002624486,27.9001972781706051,265.874320218182902],"luv":[57.7939415002624486,-2.00726537612613365,-27.8278977623291475],"rgb":[0.533333333333333326,0.533333333333333326,0.66666666666666663],"xyz":[0.262118167291767179,0.25744718953756407,0.416197990356647951],"hpluv":[265.874320218182902,61.2582077856443377,57.7939415002624486],"hsluv":[265.874320218182902,25.8334660761224093,57.7939415002624486]},"#8888bb":{"lch":[58.4431822360017605,42.3326731508362428,265.874320218181083],"luv":[58.4431822360017605,-3.04560244672749647,-42.2229738629578222],"rgb":[0.533333333333333326,0.533333333333333326,0.733333333333333282],"xyz":[0.279255759399103853,0.264302226380498828,0.506455975455289753],"hpluv":[265.874320218181083,91.9138937804104756,58.4431822360017605],"hsluv":[265.874320218181083,39.7348050695490116,58.4431822360017605]},"#8888cc":{"lch":[59.1607600358786812,56.7874726838639603,265.874320218180117],"luv":[59.1607600358786812,-4.0855455816182138,-56.6403157752595448],"rgb":[0.533333333333333326,0.533333333333333326,0.8],"xyz":[0.298548134842825608,0.27201917655798763,0.608062486125559909],"hpluv":[265.874320218180117,121.803038601679276,59.1607600358786812],"hsluv":[265.874320218180117,54.1372084350884322,59.1607600358786812]},"#8888dd":{"lch":[59.9452971965242654,71.1002375720468649,265.874320218179605],"luv":[59.9452971965242654,-5.11527010687093497,-70.9159911059223447],"rgb":[0.533333333333333326,0.533333333333333326,0.866666666666666696],"xyz":[0.320066460393459096,0.280626506778241136,0.721392334025565907],"hpluv":[265.874320218179605,150.506501481916018,59.9452971965242654],"hsluv":[265.874320218179605,68.9826297466640881,59.9452971965242654]},"#8888ee":{"lch":[60.7949865781877747,85.1524606014505,265.874320218179207],"luv":[60.7949865781877747,-6.12625008179143,-84.9317997361231676],"rgb":[0.533333333333333326,0.533333333333333326,0.933333333333333348],"xyz":[0.343878640659633861,0.290151378884711153,0.84680315009408913],"hpluv":[265.874320218179207,177.733282428962553,60.7949865781877747],"hsluv":[265.874320218179207,84.2595641984559194,60.7949865781877747]},"#8888ff":{"lch":[61.7076631467729726,98.8655769196339,265.874320218179],"luv":[61.7076631467729726,-7.11283319838656247,-98.6093804034077408],"rgb":[0.533333333333333326,0.533333333333333326,1],"xyz":[0.370049689069465226,0.300619798248643877,0.984637338385871],"hpluv":[265.874320218179,203.303722842755434,61.7076631467729726],"hsluv":[265.874320218179,99.9999999999986073,61.7076631467729726]},"#aa8800":{"lch":[58.1840377660698493,67.6904417424552634,64.2288134226940173],"luv":[58.1840377660698493,29.4303340948507071,60.9577832467208225],"rgb":[0.66666666666666663,0.533333333333333326,0],"xyz":[0.253809676678405038,0.261551633018464735,0.0371164725117156744],"hpluv":[64.2288134226940173,147.625988392398114,58.1840377660698493],"hsluv":[64.2288134226940173,100.000000000002373,58.1840377660698493]},"#aa8811":{"lch":[58.2222766199063955,66.2027965316335809,63.8264905250604926],"luv":[58.2222766199063955,29.2014551434886229,59.4145208354969085],"rgb":[0.66666666666666663,0.533333333333333326,0.0666666666666666657],"xyz":[0.254821342178042143,0.261956299218319588,0.0424445774764713041],"hpluv":[63.8264905250604926,144.286759049554206,58.2222766199063955],"hsluv":[63.8264905250604926,97.5015111084285877,58.2222766199063955]},"#aa8822":{"lch":[58.2930572278629,63.4916551128893474,63.0419050459203],"luv":[58.2930572278629,28.7832252220538578,56.5925455761676304],"rgb":[0.66666666666666663,0.533333333333333326,0.133333333333333331],"xyz":[0.2566967003165192,0.262706442473710389,0.0523214636724505036],"hpluv":[63.0419050459203,138.209896631886636,58.2930572278629],"hsluv":[63.0419050459203,92.9399945222758106,58.2930572278629]},"#aa8833":{"lch":[58.4093035212624585,59.1585039849960737,61.628621374019076],"luv":[58.4093035212624585,28.1112178941065629,52.0527426967384628],"rgb":[0.66666666666666663,0.533333333333333326,0.2],"xyz":[0.259784451048976905,0.263941542766693515,0.0685836175300616468],"hpluv":[61.628621374019076,128.521114132395894,58.4093035212624585],"hsluv":[61.628621374019076,85.621599137751673,58.4093035212624585]},"#aa8844":{"lch":[58.5764981609594315,53.1878639814319953,59.2736460930020499],"luv":[58.5764981609594315,27.1757201885359478,45.7212106919940453],"rgb":[0.66666666666666663,0.533333333333333326,0.266666666666666663],"xyz":[0.264242446293195821,0.265724740864381082,0.0920623924829482854],"hpluv":[59.2736460930020499,115.22015920662389,58.5764981609594315],"hsluv":[59.2736460930020499,75.4571473133808581,58.5764981609594315]},"#aa8855":{"lch":[58.7989500318507083,45.736161182952344,55.3795129841665315],"luv":[58.7989500318507083,25.9844527075537677,37.6378088793954433],"rgb":[0.66666666666666663,0.533333333333333326,0.333333333333333315],"xyz":[0.270204860332557806,0.268109706480125942,0.123464439756922201],"hpluv":[55.3795129841665315,98.7027982667044483,58.7989500318507083],"hsluv":[55.3795129841665315,62.5553187882680319,58.7989500318507083]},"#aa8866":{"lch":[59.0800404303715112,37.1980666756204,48.681601920545944],"luv":[59.0800404303715112,24.5597583059268025,27.9376884576795419],"rgb":[0.66666666666666663,0.533333333333333326,0.4],"xyz":[0.277789856106066,0.271143704789529261,0.163412084164066163],"hpluv":[48.681601920545944,79.8948730878687883,59.0800404303715112],"hsluv":[48.681601920545944,47.1909371341698645,59.0800404303715112]},"#aa8877":{"lch":[59.4223523155875881,28.4467220316745042,36.2691810942760355],"luv":[59.4223523155875881,22.9350730451589406,16.8285001934390941],"rgb":[0.66666666666666663,0.533333333333333326,0.466666666666666674],"xyz":[0.287103869126267897,0.274869309997610056,0.212465886070464072],"hpluv":[36.2691810942760355,60.7465636644032,59.4223523155875881],"hsluv":[36.2691810942760355,29.7643761063162415,59.4223523155875881]},"#aa8888":{"lch":[59.8277504540149323,21.6376696880998622,12.1770506300627677],"luv":[59.8277504540149323,21.1508320810015036,4.56410471095846049],"rgb":[0.66666666666666663,0.533333333333333326,0.533333333333333326],"xyz":[0.298244286228211697,0.279325476838387654,0.271138749474036211],"hpluv":[12.1770506300627677,45.8930730764781174,59.8277504540149323],"hsluv":[12.1770506300627677,15.9793094134510145,59.8277504540149323]},"#aa8899":{"lch":[60.2974403890441693,21.076671863141442,335.972081494736813],"luv":[60.2974403890441693,19.2503183610400761,-8.58203587880762697],"rgb":[0.66666666666666663,0.533333333333333326,0.6],"xyz":[0.311301250337284396,0.284548262482016812,0.339905427115154146],"hpluv":[335.972081494736813,44.3549898137704872,60.2974403890441693],"hsluv":[335.972081494736813,18.3674189175529285,60.2974403890441693]},"#aa88aa":{"lch":[60.8320193568852119,28.2409959286201691,307.715012949248376],"luv":[60.8320193568852119,17.2759870010776844,-22.3404145928166677],"rgb":[0.66666666666666663,0.533333333333333326,0.66666666666666663],"xyz":[0.326358943302536952,0.290571339668117934,0.419209276732152747],"hpluv":[307.715012949248376,58.9097393716334068,60.8320193568852119],"hsluv":[307.715012949248376,20.7885743891348937,60.8320193568852119]},"#aa88bb":{"lch":[61.4315255818646904,39.5305448534603343,292.718173175904553],"luv":[61.4315255818646904,15.2666424694527869,-36.4635928581008],"rgb":[0.66666666666666663,0.533333333333333326,0.733333333333333282],"xyz":[0.343496535409873627,0.297426376511052692,0.509467261830794493],"hpluv":[292.718173175904553,81.6546320542196185,61.4315255818646904],"hsluv":[292.718173175904553,35.3775178816614826,61.4315255818646904]},"#aa88cc":{"lch":[62.0954889075932783,52.4408733717370339,284.64164926901276],"luv":[62.0954889075932783,13.2556230251873277,-50.737891739849438],"rgb":[0.66666666666666663,0.533333333333333326,0.8],"xyz":[0.362788910853595326,0.305143326688541494,0.611073772501064649],"hpluv":[284.64164926901276,107.164068097081099,62.0954889075932783],"hsluv":[284.64164926901276,50.6369924233865092,62.0954889075932783]},"#aa88dd":{"lch":[62.8229837406334894,65.9589053782665644,279.83800714750987],"luv":[62.8229837406334894,11.2699451472508105,-64.988964717689413],"rgb":[0.66666666666666663,0.533333333333333326,0.866666666666666696],"xyz":[0.384307236404228925,0.313750656908795,0.724403620401070647],"hpluv":[279.83800714750987,133.227600809414753,62.8229837406334894],"hsluv":[279.83800714750987,66.50088929558828,62.8229837406334894]},"#aa88ee":{"lch":[63.6126841134072,79.6308922643202237,276.728713669089302],"luv":[63.6126841134072,9.33022805769535,-79.0823990986816767],"rgb":[0.66666666666666663,0.533333333333333326,0.933333333333333348],"xyz":[0.408119416670403634,0.323275529015265,0.84981443646959387],"hpluv":[276.728713669089302,158.846330872338797,63.6126841134072],"hsluv":[276.728713669089302,82.9476730407324112,63.6126841134072]},"#aa88ff":{"lch":[64.4629200033750323,93.219110130063271,274.584640952303687],"luv":[64.4629200033750323,7.4511637136690565,-92.9208407880221756],"rgb":[0.66666666666666663,0.533333333333333326,1],"xyz":[0.434290465080235055,0.333743948379197741,0.987648624761375715],"hpluv":[274.584640952303687,183.499254977583263,64.4629200033750323],"hsluv":[274.584640952303687,99.999999999998451,64.4629200033750323]},"#889900":{"lch":[59.9037942457991477,67.5360782410098892,95.4734085527772578],"luv":[59.9037942457991477,-6.44184579214223074,67.2281524881211396],"rgb":[0.533333333333333326,0.6,0],"xyz":[0.215438501120102766,0.280166683792846538,0.0427283862870331613],"hpluv":[95.4734085527772578,143.060860652479761,59.9037942457991477],"hsluv":[95.4734085527772578,100.000000000002359,59.9037942457991477]},"#889911":{"lch":[59.9403212197486,66.0293008977046867,95.6505578181906628],"luv":[59.9403212197486,-6.50131434341495318,65.7084582747741166],"rgb":[0.533333333333333326,0.6,0.0666666666666666657],"xyz":[0.216450166619739898,0.280571349992701391,0.048056491251788791],"hpluv":[95.6505578181906628,139.783837686775883,59.9403212197486],"hsluv":[95.6505578181906628,97.642419329775592,59.9403212197486]},"#889922":{"lch":[60.0079397017320275,63.2737960078627495,95.9966659299995655],"luv":[60.0079397017320275,-6.6102508868722456,62.9275602932231308],"rgb":[0.533333333333333326,0.6,0.133333333333333331],"xyz":[0.218325524758216899,0.281321493248092191,0.0579333774477679905],"hpluv":[95.9966659299995655,133.799503075015934,60.0079397017320275],"hsluv":[95.9966659299995655,93.3344688530494864,60.0079397017320275]},"#889933":{"lch":[60.1190111745068521,58.8410136656902196,96.6225595920901696],"luv":[60.1190111745068521,-6.78603238946032139,58.4483930798370039],"rgb":[0.533333333333333326,0.6,0.2],"xyz":[0.221413275490674633,0.282556593541075318,0.0741955313053791338],"hpluv":[96.6225595920901696,124.196009967059197,60.1190111745068521],"hsluv":[96.6225595920901696,86.4129060235578,60.1190111745068521]},"#889944":{"lch":[60.2788030378330859,52.6619605596060651,97.6740140778758104],"luv":[60.2788030378330859,-7.03230554676784081,52.1903129773946],"rgb":[0.533333333333333326,0.6,0.266666666666666663],"xyz":[0.22587127073489352,0.284339791638762884,0.0976743062582657723],"hpluv":[97.6740140778758104,110.859197411007315,60.2788030378330859],"hsluv":[97.6740140778758104,76.7791514013919,60.2788030378330859]},"#889955":{"lch":[60.491478208304315,44.7890969420590679,99.4433583384469557],"luv":[60.491478208304315,-7.34865909500015935,44.1821277711999301],"rgb":[0.533333333333333326,0.6,0.333333333333333315],"xyz":[0.231833684774255533,0.286724757254507745,0.129076353532239674],"hpluv":[99.4433583384469557,93.954467458231008,60.491478208304315],"hsluv":[99.4433583384469557,64.5165507795669555,60.491478208304315]},"#889966":{"lch":[60.7603321241253269,35.3998784596055387,102.614945913325585],"luv":[60.7603321241253269,-7.73125582812020351,34.5453191948634597],"rgb":[0.533333333333333326,0.6,0.4],"xyz":[0.23941868054776369,0.289758755563911063,0.169023997939383636],"hpluv":[102.614945913325585,73.9300429237522394,60.7603321241253269],"hsluv":[102.614945913325585,49.862982431557576,60.7603321241253269]},"#889977":{"lch":[61.0879169406466644,24.8557994274465628,109.198389045907604],"luv":[61.0879169406466644,-8.17358342252196,23.4734594640953418],"rgb":[0.533333333333333326,0.6,0.466666666666666674],"xyz":[0.248732693567965624,0.293484360771991859,0.218077799845781545],"hpluv":[109.198389045907604,51.6311437806165543,61.0879169406466644],"hsluv":[109.198389045907604,33.1759220302134779,61.0879169406466644]},"#889988":{"lch":[61.4761176658877702,14.1684419896747276,127.715012949229816],"luv":[61.4761176658877702,-8.66732250724137,11.2081340539023326],"rgb":[0.533333333333333326,0.6,0.533333333333333326],"xyz":[0.259873110669909424,0.297940527612769457,0.276750663249353712],"hpluv":[127.715012949229816,29.2452265306994263,61.4761176658877702],"hsluv":[127.715012949229816,14.8910328511789984,61.4761176658877702]},"#889999":{"lch":[61.9262069462763094,9.41507553536713537,192.177050630058915],"luv":[61.9262069462763094,-9.20324067004397861,-1.98595279549067061],"rgb":[0.533333333333333326,0.6,0.6],"xyz":[0.272930074778982124,0.303163313256398614,0.345517340890471647],"hpluv":[192.177050630058915,19.2925065058214678,61.9262069462763094],"hsluv":[192.177050630058915,19.2169899754877207,61.9262069462763094]},"#8899aa":{"lch":[62.4388911462841207,18.6148502867865133,238.334617604481764],"luv":[62.4388911462841207,-9.77200531832159669,-15.8436284751369474],"rgb":[0.533333333333333326,0.6,0.66666666666666663],"xyz":[0.28798776774423468,0.309186390442499737,0.424821190507470248],"hpluv":[238.334617604481764,37.8306403353000036,62.4388911462841207],"hsluv":[238.334617604481764,23.6900457250072343,62.4388911462841207]},"#8899bb":{"lch":[63.0143540484962,31.8509402607766567,251.009167860858838],"luv":[63.0143540484962,-10.3648329189902189,-30.1173145226625429],"rgb":[0.533333333333333326,0.6,0.733333333333333282],"xyz":[0.305125359851571354,0.316041427285434495,0.515079175606111939],"hpluv":[251.009167860858838,64.1389868285616132,63.0143540484962],"hsluv":[251.009167860858838,32.2218698989210282,63.0143540484962]},"#8899cc":{"lch":[63.6523012354060143,45.9199042321153357,256.173658840600297],"luv":[63.6523012354060143,-10.9739341944061159,-44.5893526863026821],"rgb":[0.533333333333333326,0.6,0.8],"xyz":[0.324417735295293053,0.323758377462923297,0.616685686276382095],"hpluv":[256.173658840600297,91.543221315317254,63.6523012354060143],"hsluv":[256.173658840600297,48.1563502503440546,63.6523012354060143]},"#8899dd":{"lch":[64.3520063546654,60.2052734177332738,258.898139298145679],"luv":[64.3520063546654,-11.5927562398827622,-59.0786166905309358],"rgb":[0.533333333333333326,0.6,0.866666666666666696],"xyz":[0.345936060845926652,0.332365707683176803,0.730015534176388092],"hpluv":[258.898139298145679,118.716686841439611,64.3520063546654],"hsluv":[258.898139298145679,64.7736147673059435,64.3520063546654]},"#8899ee":{"lch":[65.1123593572591091,74.4513212160393465,260.556144021857],"luv":[65.1123593572591091,-12.2160522582942246,-73.442271874149526],"rgb":[0.533333333333333326,0.6,0.933333333333333348],"xyz":[0.369748241112101361,0.34189057978964682,0.855426350244911315],"hpluv":[260.556144021857,145.093615685215838,65.1123593572591091],"hsluv":[260.556144021857,82.0482136329290626,65.1123593572591091]},"#8899ff":{"lch":[65.9319161385595862,88.5102230179824829,261.65889869963604],"luv":[65.9319161385595862,-12.8398242875011679,-87.5739601191992],"rgb":[0.533333333333333326,0.6,1],"xyz":[0.395919289521932782,0.352358999153579544,0.993260538536693161],"hpluv":[261.65889869963604,170.348009793708229,65.9319161385595862],"hsluv":[261.65889869963604,99.9999999999983373,65.9319161385595862]},"#aa9900":{"lch":[62.7844580943873609,69.6780489210530618,75.8779002673010297],"luv":[62.7844580943873609,17.0006834702273615,67.5722373685362072],"rgb":[0.66666666666666663,0.6,0],"xyz":[0.279679277130872483,0.313290833923400402,0.0457396726625379293],"hpluv":[75.8779002673010297,140.82610179048271,62.7844580943873609],"hsluv":[75.8779002673010297,100.000000000002217,62.7844580943873609]},"#aa9911":{"lch":[62.8183644916567232,68.2796688580209548,75.7117398414304],"luv":[62.8183644916567232,16.8514534980901978,66.1675274916835576],"rgb":[0.66666666666666663,0.6,0.0666666666666666657],"xyz":[0.280690942630509588,0.313695500123255255,0.0510677776272935591],"hpluv":[75.7117398414304,137.925354096716262,62.8183644916567232],"hsluv":[75.7117398414304,97.9039601429264792,62.8183644916567232]},"#aa9922":{"lch":[62.8811408657966098,65.7186920323652259,75.3888160486312415],"luv":[62.8811408657966098,16.5780820569936154,63.5933461751813311],"rgb":[0.66666666666666663,0.6,0.133333333333333331],"xyz":[0.282566300768986645,0.314445643378646056,0.0609446638232727586],"hpluv":[75.3888160486312415,132.619634057532949,62.8811408657966098],"hsluv":[75.3888160486312415,94.0678156084237287,62.8811408657966098]},"#aa9933":{"lch":[62.984284118013818,61.5887344728930373,74.8105333616033477],"luv":[62.984284118013818,16.1369729495721401,59.4371122952427768],"rgb":[0.66666666666666663,0.6,0.2],"xyz":[0.28565405150144435,0.315680743671629183,0.0772068176808839],"hpluv":[74.8105333616033477,124.08189266143988,62.984284118013818],"hsluv":[74.8105333616033477,87.8877322232676335,62.984284118013818]},"#aa9944":{"lch":[63.1327254984845325,55.810649390305,73.8551623649617284],"luv":[63.1327254984845325,15.5190685808424753,53.6095802609072862],"rgb":[0.66666666666666663,0.6,0.266666666666666663],"xyz":[0.290112046745663266,0.317463941769316749,0.10068559263377054],"hpluv":[73.8551623649617284,112.176494362550613,63.1327254984845325],"hsluv":[73.8551623649617284,79.2518346201028407,63.1327254984845325]},"#aa9955":{"lch":[63.330394330910508,48.4114193249398497,72.2912631539462893],"luv":[63.330394330910508,14.725704471349518,46.1174495053405593],"rgb":[0.66666666666666663,0.6,0.333333333333333315],"xyz":[0.296074460785025251,0.319848907385061609,0.132087639907744442],"hpluv":[72.2912631539462893,97.0007181904759,63.330394330910508],"hsluv":[72.2912631539462893,68.2014618333714253,63.330394330910508]},"#aa9966":{"lch":[63.5804407621292285,39.5252766283835086,69.6158026784446662],"luv":[63.5804407621292285,13.7671883687516523,37.0501284339143524],"rgb":[0.66666666666666663,0.6,0.4],"xyz":[0.303659456558533436,0.322882905694464928,0.172035284314888404],"hpluv":[69.6158026784446662,78.8843243984218105,63.5804407621292285],"hsluv":[69.6158026784446662,54.9106459007729129,63.5804407621292285]},"#aa9977":{"lch":[63.8853523521207762,29.4269320044373437,64.5162682653354835],"luv":[63.8853523521207762,12.6610788645847681,26.563911782313685],"rgb":[0.66666666666666663,0.6,0.466666666666666674],"xyz":[0.312973469578735342,0.326608510902545723,0.221089086221286313],"hpluv":[64.5162682653354835,58.4497984351079,63.8853523521207762],"hsluv":[64.5162682653354835,39.6604297676390303,63.8853523521207762]},"#aa9988":{"lch":[64.2470245358341288,18.7498828458428441,52.4386898809200943],"luv":[64.2470245358341288,11.4301164327749429,14.8630597477787205],"rgb":[0.66666666666666663,0.6,0.533333333333333326],"xyz":[0.324113886680679142,0.331064677743323321,0.279761949624858508],"hpluv":[52.4386898809200943,37.0326564248891472,64.2470245358341288],"hsluv":[52.4386898809200943,22.8076315183033955,64.2470245358341288]},"#aa9999":{"lch":[64.6668097656484,10.3324715423982241,12.1770506300641514],"luv":[64.6668097656484,10.0999956892392,2.17946214737001709],"rgb":[0.66666666666666663,0.6,0.6],"xyz":[0.337170850789751841,0.336287463386952479,0.348528627265976387],"hpluv":[12.1770506300641514,20.2750581327120152,64.6668097656484],"hsluv":[12.1770506300641514,9.39861318597140283,64.6668097656484]},"#aa99aa":{"lch":[65.1455571833188,14.2173372068657535,307.715012949255367],"luv":[65.1455571833188,8.69723339065650514,-11.2468132643064216],"rgb":[0.66666666666666663,0.6,0.66666666666666663],"xyz":[0.352228543755004397,0.342310540573053601,0.427832476882975],"hpluv":[307.715012949255367,27.6931773999722353,65.1455571833188],"hsluv":[307.715012949255367,11.6506794595111955,65.1455571833188]},"#aa99bb":{"lch":[65.6836488991384186,26.2061362707181722,286.054514249721478],"luv":[65.6836488991384186,7.24735484809431529,-25.1840708771488],"rgb":[0.66666666666666663,0.6,0.733333333333333282],"xyz":[0.369366135862341072,0.34916557741598836,0.51809046198161679],"hpluv":[286.054514249721478,50.6273330900370553,65.6836488991384186],"hsluv":[286.054514249721478,27.5721610485895,65.6836488991384186]},"#aa99cc":{"lch":[66.2810360009151651,39.8419200501833544,278.33213307587846],"luv":[66.2810360009151651,5.77353773601307907,-39.4213756139487757],"rgb":[0.66666666666666663,0.6,0.8],"xyz":[0.388658511306062771,0.356882527593477161,0.619696972651887],"hpluv":[278.33213307587846,76.2764194246967,66.2810360009151651],"hsluv":[278.33213307587846,44.416066179202609,66.2810360009151651]},"#aa99dd":{"lch":[66.937275739096421,53.9476968390211695,274.567192844176702],"luv":[66.937275739096421,4.29575598209881182,-53.7763932853180151],"rgb":[0.66666666666666663,0.6,0.866666666666666696],"xyz":[0.41017683685669637,0.365489857813730668,0.733026820551892944],"hpluv":[274.567192844176702,102.269045280662851,66.937275739096421],"hsluv":[274.567192844176702,62.1125641321495365,66.937275739096421]},"#aa99ee":{"lch":[67.6515703211096309,68.1578213039093299,272.380002942583644],"luv":[67.6515703211096309,2.83038594926376286,-68.0990273078393358],"rgb":[0.66666666666666663,0.6,0.933333333333333348],"xyz":[0.433989017122871079,0.375014729920200685,0.858437636620416167],"hpluv":[272.380002942583644,127.843056183363871,67.6515703211096309],"hsluv":[272.380002942583644,80.63443597048024,67.6515703211096309]},"#aa99ff":{"lch":[68.4228071241374778,82.2834014236355387,270.968064044661787],"luv":[68.4228071241374778,1.39018638405132466,-82.2716569157370543],"rgb":[0.66666666666666663,0.6,1],"xyz":[0.4601600655327025,0.385483149284133408,0.996271824912198],"hpluv":[270.968064044661787,152.598644218259693,68.4228071241374778],"hsluv":[270.968064044661787,99.9999999999981668,68.4228071241374778]},"#770000":{"lch":[23.4140868272264697,78.7423116347599432,12.177050630061796],"luv":[23.4140868272264697,76.9706458719381317,16.6093743302492847],"rgb":[0.466666666666666674,0,0],"xyz":[0.0760757904266185919,0.0392265794387260461,0.00356605267624767169],"hpluv":[12.177050630061796,426.746789183125429,23.4140868272264697],"hsluv":[12.177050630061796,100.000000000002359,23.4140868272264697]},"#770011":{"lch":[23.5491569362977273,75.7570426868466456,9.89164947332394462],"luv":[23.5491569362977273,74.6308667748156864,13.0139633123970793],"rgb":[0.466666666666666674,0,0.0666666666666666657],"xyz":[0.0770874559262557102,0.0396312456385809,0.00889415764100330228],"hpluv":[9.89164947332394462,408.213135586655085,23.5491569362977273],"hsluv":[9.89164947332394462,99.9999999999965183,23.5491569362977273]},"#770022":{"lch":[23.7971287372198219,70.9964864167640854,5.53723409440817704],"luv":[23.7971287372198219,70.6651956613751224,6.85063542055327357],"rgb":[0.466666666666666674,0,0.133333333333333331],"xyz":[0.0789628140647327392,0.0403813888939717203,0.0187710438369825],"hpluv":[5.53723409440817704,378.574731225432288,23.7971287372198219],"hsluv":[5.53723409440817704,99.9999999999967741,23.7971287372198219]},"#770033":{"lch":[24.198804347572846,65.0463245726941182,358.140059561726389],"luv":[24.198804347572846,65.0120550988218895,-2.11116845467566527],"rgb":[0.466666666666666674,0,0.2],"xyz":[0.0820505647971904728,0.0416164891869548331,0.0350331976945936416],"hpluv":[358.140059561726389,341.089366306392606,24.198804347572846],"hsluv":[358.140059561726389,99.9999999999971578,24.198804347572846]},"#770044":{"lch":[24.764944554878376,59.7650645123016702,347.391874641304071],"luv":[24.764944554878376,58.3238787679626398,-13.0456161839744915],"rgb":[0.466666666666666674,0,0.266666666666666663],"xyz":[0.0865085600414093464,0.0433996872846424062,0.0585119726474802801],"hpluv":[347.391874641304071,306.231145677972847,24.764944554878376],"hsluv":[347.391874641304071,99.9999999999975557,24.764944554878376]},"#770055":{"lch":[25.4983947844981387,57.0853266397623571,333.997796644431901],"luv":[25.4983947844981387,51.3069893372134587,-25.0265331742018731],"rgb":[0.466666666666666674,0,0.333333333333333315],"xyz":[0.0924709740807713454,0.0457846529003872391,0.0899140199214541885],"hpluv":[333.997796644431901,284.086748448009075,25.4983947844981387],"hsluv":[333.997796644431901,99.999999999998,25.4983947844981387]},"#770066":{"lch":[26.3955149445472088,58.0812929265372375,320.022905340944305],"luv":[26.3955149445472088,44.5077732621065394,-37.3161453966930949],"rgb":[0.466666666666666674,0,0.4],"xyz":[0.100055969854279517,0.0488186512097905506,0.129861664328598164],"hpluv":[320.022905340944305,279.219318659546161,26.3955149445472088],"hsluv":[320.022905340944305,99.9999999999984,26.3955149445472088]},"#770077":{"lch":[27.4476614837194361,62.5213221502200156,307.715012949243601],"luv":[27.4476614837194361,38.2464397320582776,-49.4583215569799322],"rgb":[0.466666666666666674,0,0.466666666666666674],"xyz":[0.109369982874481436,0.052544256417871367,0.178915466234996073],"hpluv":[307.715012949243601,289.04278373048345,27.4476614837194361],"hsluv":[307.715012949243601,99.9999999999988631,27.4476614837194361]},"#770088":{"lch":[28.6427236217895711,69.3985842918787341,298.067280282401043],"luv":[28.6427236217895711,32.6525926425722872,-61.2370124633397808],"rgb":[0.466666666666666674,0,0.533333333333333326],"xyz":[0.120510399976425264,0.0570004232586489579,0.237588329638568241],"hpluv":[298.067280282401043,307.450798390810235,28.6427236217895711],"hsluv":[298.067280282401043,99.9999999999991473,28.6427236217895711]},"#770099":{"lch":[29.9665727349335924,77.70857748467688,290.909274437861086],"luv":[29.9665727349335924,27.7333531267432782,-72.5912125469701],"rgb":[0.466666666666666674,0,0.6],"xyz":[0.133567364085497964,0.0622232089022781223,0.30635500727968612],"hpluv":[290.909274437861086,329.057057444315717,29.9665727349335924],"hsluv":[290.909274437861086,99.9999999999993605,29.9665727349335924]},"#7700aa":{"lch":[31.4042918618800115,86.7647813143177,285.668616902051383],"luv":[31.4042918618800115,23.4328336498598695,-83.5405864455078415],"rgb":[0.466666666666666674,0,0.66666666666666663],"xyz":[0.14862505705075052,0.0682462860883792238,0.385658856896684721],"hpluv":[285.668616902051383,350.585377409449279,31.4042918618800115],"hsluv":[285.668616902051383,99.9999999999996447,31.4042918618800115]},"#7700bb":{"lch":[32.9411141237069387,96.170393631615,281.802895608829544],"luv":[32.9411141237069387,19.6712233173334745,-94.1370680681067853],"rgb":[0.466666666666666674,0,0.733333333333333282],"xyz":[0.165762649158087166,0.0751013229313139824,0.475916841995326467],"hpluv":[281.802895608829544,370.460950364720645,32.9411141237069387],"hsluv":[281.802895608829544,99.9999999999998295,32.9411141237069387]},"#7700cc":{"lch":[34.5630635499026226,105.713400517707811,278.906152205018032],"luv":[34.5630635499026226,16.3661753747823724,-104.438840249301762],"rgb":[0.466666666666666674,0,0.8],"xyz":[0.185055024601808893,0.082818273108802784,0.577523352665596623],"hpluv":[278.906152205018032,388.112061604616713,34.5630635499026226],"hsluv":[278.906152205018032,99.9999999999998721,34.5630635499026226]},"#7700dd":{"lch":[36.2573361534597964,115.285120662302717,276.696107756350386],"luv":[36.2573361534597964,13.4426218553338188,-114.498711624961956],"rgb":[0.466666666666666674,0,0.866666666666666696],"xyz":[0.206573350152442436,0.091425603329056318,0.690853200565602621],"hpluv":[276.696107756350386,403.475057258468723,36.2573361534597964],"hsluv":[276.696107756350386,100.000000000000156,36.2573361534597964]},"#7700ee":{"lch":[38.012479203832,124.831519574090535,274.979891409884715],"luv":[38.012479203832,10.8361388436516783,-124.360308676593633],"rgb":[0.466666666666666674,0,0.933333333333333348],"xyz":[0.230385530418617201,0.100950475435526349,0.816264016634125844],"hpluv":[274.979891409884715,416.713325299391272,38.012479203832],"hsluv":[274.979891409884715,100.000000000000156,38.012479203832]},"#7700ff":{"lch":[39.8184284160989037,134.326708962856742,273.625091115001112],"luv":[39.8184284160989037,8.49315165227522861,-134.057939398617776],"rgb":[0.466666666666666674,0,1],"xyz":[0.256556578828448567,0.111418894799459045,0.954098204925907689],"hpluv":[273.625091115001112,428.072753406140123,39.8184284160989037],"hsluv":[273.625091115001112,100.000000000000313,39.8184284160989037]},"#771100":{"lch":[24.7134353555624457,74.5310598854495794,14.479461840222152],"luv":[24.7134353555624457,72.1637543524892351,18.6352205622059],"rgb":[0.466666666666666674,0.0666666666666666657,0],"xyz":[0.078080190687547,0.0432353799605829231,0.00423418609655712257],"hpluv":[14.479461840222152,382.686818993669249,24.7134353555624457],"hsluv":[14.479461840222152,100.000000000002174,24.7134353555624457]},"#771111":{"lch":[24.8400617115613187,71.7342088143168723,12.1770506300618244],"luv":[24.8400617115613187,70.1202221387804912,15.1311321924069837],"rgb":[0.466666666666666674,0.0666666666666666657,0.0666666666666666657],"xyz":[0.0790918561871841175,0.043640046160437776,0.00956229106131275403],"hpluv":[12.1770506300618244,366.448517223619376,24.8400617115613187],"hsluv":[12.1770506300618244,85.8702458957174173,24.8400617115613187]},"#771122":{"lch":[25.0727380413203562,67.2476760425649616,7.76714475492354417],"luv":[25.0727380413203562,66.6307123231625,9.0883501491595],"rgb":[0.466666666666666674,0.0666666666666666657,0.133333333333333331],"xyz":[0.0809672143256611465,0.0443901894158286,0.0194391772572919501],"hpluv":[7.76714475492354417,340.341449223453765,25.0727380413203562],"hsluv":[7.76714475492354417,86.6206298981217,25.0727380413203562]},"#771133":{"lch":[25.4501908259833556,61.6001849310061189,0.209311103178295294],"luv":[25.4501908259833556,61.599773884646936,0.225035318388215971],"rgb":[0.466666666666666674,0.0666666666666666657,0.2],"xyz":[0.0840549650581188801,0.0456252897088117101,0.0357013311149031],"hpluv":[0.209311103178295294,307.135699817562568,25.4501908259833556],"hsluv":[0.209311103178295294,87.6964449022470802,25.4501908259833556]},"#771144":{"lch":[25.9833113937366775,56.5829308746863688,349.098656617234155],"luv":[25.9833113937366775,55.5618510799655,-10.7008771106518541],"rgb":[0.466666666666666674,0.0666666666666666657,0.266666666666666663],"xyz":[0.0885129603023377537,0.0474084878064992832,0.0591801060677897353],"hpluv":[349.098656617234155,276.331419289390624,25.9833113937366775],"hsluv":[349.098656617234155,88.9762099121112442,25.9833113937366775]},"#771155":{"lch":[26.6758393728738312,54.157242934368746,335.112354986374442],"luv":[26.6758393728738312,49.127918835603694,-22.7915456504066185],"rgb":[0.466666666666666674,0.0666666666666666657,0.333333333333333315],"xyz":[0.0944753743416997527,0.0497934534222441161,0.0905821533417636438],"hpluv":[335.112354986374442,257.618934567198892,26.6758393728738312],"hsluv":[335.112354986374442,90.3225181656420375,26.6758393728738312]},"#771166":{"lch":[27.5255776115618076,55.4731266930874796,320.490705765847224],"luv":[27.5255776115618076,42.7987039146097388,-35.2921907557026557],"rgb":[0.466666666666666674,0.0666666666666666657,0.4],"xyz":[0.102060370115207924,0.0528274517316474276,0.130529797748907606],"hpluv":[320.490705765847224,255.732268141411282,27.5255776115618076],"hsluv":[320.490705765847224,91.6238582413064364,27.5255776115618076]},"#771177":{"lch":[28.525624322061,60.3055315504910538,307.715012949243658],"luv":[28.525624322061,36.8909645322892956,-47.7054909990940672],"rgb":[0.466666666666666674,0.0666666666666666657,0.466666666666666674],"xyz":[0.111374383135409843,0.056553056939728244,0.179583599655305515],"hpluv":[307.715012949243658,268.263334170626,28.525624322061],"hsluv":[307.715012949243658,92.8109433172232201,28.525624322061]},"#771188":{"lch":[29.665668786552871,67.5901402176946,297.828537901307072],"luv":[29.665668786552871,31.5529142063876336,-59.77324367751811],"rgb":[0.466666666666666674,0.0666666666666666657,0.533333333333333326],"xyz":[0.122514800237353672,0.0610092237805058418,0.238256463058877682],"hpluv":[297.828537901307072,289.113605882780575,29.665668786552871],"hsluv":[297.828537901307072,93.8529472884676892,29.665668786552871]},"#771199":{"lch":[30.9332504381216253,76.2730393291315494,290.583951381139741],"luv":[30.9332504381216253,26.816032696200331,-71.4036197887723461],"rgb":[0.466666666666666674,0.0666666666666666657,0.6],"xyz":[0.135571764346426371,0.066232009424135,0.307023140699995589],"hpluv":[290.583951381139741,312.885056330098905,30.9332504381216253],"hsluv":[290.583951381139741,94.745562802664864,30.9332504381216253]},"#7711aa":{"lch":[32.3148680584756391,85.6471240548678452,285.332056603477554],"luv":[32.3148680584756391,22.6461849228904,-82.5989114172104166],"rgb":[0.466666666666666674,0.0666666666666666657,0.66666666666666663],"xyz":[0.150629457311678927,0.0722550866102361078,0.38632699031699419],"hpluv":[285.332056603477554,336.317699636744408,32.3148680584756391],"hsluv":[285.332056603477554,95.4992611083078771,32.3148680584756391]},"#7711bb":{"lch":[33.796865882550442,95.3131880713117,281.486339493443666],"luv":[33.796865882550442,18.9801244444786903,-93.4042755787407],"rgb":[0.466666666666666674,0.0666666666666666657,0.733333333333333282],"xyz":[0.167767049419015574,0.0791101234531708664,0.476584975415635936],"hpluv":[281.486339493443666,357.862255189103962,33.796865882550442],"hsluv":[281.486339493443666,96.130904738193,33.796865882550442]},"#7711cc":{"lch":[35.36607449089243,105.064609202725904,278.619980375929231],"luv":[35.36607449089243,15.7470979978009513,-103.877817707002151],"rgb":[0.466666666666666674,0.0666666666666666657,0.8],"xyz":[0.1870594248627373,0.086827073630659668,0.578191486085906092],"hpluv":[278.619980375929231,376.971848031202455,35.36607449089243],"hsluv":[278.619980375929231,96.6587778670915441,35.36607449089243]},"#7711dd":{"lch":[37.0102245888209,114.800572621107989,276.441726024966442],"luv":[37.0102245888209,12.8797770828984923,-114.075776641796878],"rgb":[0.466666666666666674,0.0666666666666666657,0.866666666666666696],"xyz":[0.208577750413370844,0.0954344038509132,0.69152133398591209],"hpluv":[276.441726024966442,393.605954910771402,37.0102245888209],"hsluv":[276.441726024966442,97.1000737310191084,37.0102245888209]},"#7711ee":{"lch":[38.7181742300654648,124.475046910670883,274.755182332196796],"luv":[38.7181742300654648,10.3187754184265525,-124.046604859938796],"rgb":[0.466666666666666674,0.0666666666666666657,0.933333333333333348],"xyz":[0.232389930679545609,0.104959275957383219,0.816932150054435313],"hpluv":[274.755182332196796,407.949828918098,38.7181742300654648],"hsluv":[274.755182332196796,97.4698666617264706,38.7181742300654648]},"#7711ff":{"lch":[40.4799968781786,134.069342311184641,273.42679883886251],"luv":[40.4799968781786,8.01376323316973682,-133.829623576382744],"rgb":[0.466666666666666674,0.0666666666666666657,1],"xyz":[0.258560979089377,0.115427695321315929,0.954766338346217158],"hpluv":[273.42679883886251,420.269946860795244,40.4799968781786],"hsluv":[273.42679883886251,99.99999999999946,40.4799968781786]},"#772200":{"lch":[26.9238486490213944,67.8779226750429814,18.9619118830866213],"luv":[26.9238486490213944,64.1945131058521241,22.0562207502031953],"rgb":[0.466666666666666674,0.133333333333333331,0],"xyz":[0.0817958144223149414,0.0506666274301188907,0.00547272734147973266],"hpluv":[18.9619118830866213,319.912145739235086,26.9238486490213944],"hsluv":[18.9619118830866213,100.000000000002203,26.9238486490213944]},"#772211":{"lch":[27.0378210495853537,65.3114997865878451,16.6506371445360628],"luv":[27.0378210495853537,62.5729698674152957,18.7140440938083152],"rgb":[0.466666666666666674,0.133333333333333331,0.0666666666666666657],"xyz":[0.0828074799219520596,0.0510712936299737436,0.0108008323062353633],"hpluv":[16.6506371445360628,306.518925183772069,27.0378210495853537],"hsluv":[16.6506371445360628,87.77659617077137,27.0378210495853537]},"#772222":{"lch":[27.2475131582451553,61.1491638550902934,12.1770506300618262],"luv":[27.2475131582451553,59.7733358183195094,12.8983939049434628],"rgb":[0.466666666666666674,0.133333333333333331,0.133333333333333331],"xyz":[0.0846828380604290887,0.0518214368853645649,0.0206777185022145593],"hpluv":[12.1770506300618262,284.775733052529233,27.2475131582451553],"hsluv":[12.1770506300618262,66.7317810633447,27.2475131582451553]},"#772233":{"lch":[27.5884028886125066,55.830319472153235,4.36926883706767555],"luv":[27.5884028886125066,55.668063043001986,4.25339034219168255],"rgb":[0.466666666666666674,0.133333333333333331,0.2],"xyz":[0.0877705887928868222,0.0530565371783476777,0.0369398723598257],"hpluv":[4.36926883706767555,256.792821962959806,27.5884028886125066],"hsluv":[4.36926883706767555,69.0869865520346,27.5884028886125066]},"#772244":{"lch":[28.0713586292933357,51.0577981227000137,352.597218961633928],"luv":[28.0713586292933357,50.6322267647614197,-6.57847717790113862],"rgb":[0.466666666666666674,0.133333333333333331,0.266666666666666663],"xyz":[0.0922285840371057,0.0548397352760352508,0.0604186473127123411],"hpluv":[352.597218961633928,230.801153887638264,28.0713586292933357],"hsluv":[352.597218961633928,71.9536276136468871,28.0713586292933357]},"#772255":{"lch":[28.7011983995690869,48.8793621784160877,337.425357822166575],"luv":[28.7011983995690869,45.134235573623549,-18.7641367015226166],"rgb":[0.466666666666666674,0.133333333333333331,0.333333333333333315],"xyz":[0.0981909980764677,0.0572247008917800837,0.0918206945866862495],"hpluv":[337.425357822166575,216.105005327694982,28.7011983995690869],"hsluv":[337.425357822166575,75.0482997779786416,28.7011983995690869]},"#772266":{"lch":[29.4776386596593341,50.6214045611569148,321.457127980188602],"luv":[29.4776386596593341,39.5931335065919541,-31.5421999688275427],"rgb":[0.466666666666666674,0.133333333333333331,0.4],"xyz":[0.105775993849975866,0.0602586992011833952,0.131768338993830225],"hpluv":[321.457127980188602,217.911839443782668,29.4776386596593341],"hsluv":[321.457127980188602,78.1196257410634871,29.4776386596593341]},"#772277":{"lch":[30.3962065887853328,56.0773495547330114,307.715012949243828],"luv":[30.3962065887853328,34.3044404103525125,-44.3607315225559375],"rgb":[0.466666666666666674,0.133333333333333331,0.466666666666666674],"xyz":[0.115090006870177786,0.0639843044092642116,0.180822140900228134],"hpluv":[307.715012949243828,234.103236488433623,30.3962065887853328],"hsluv":[307.715012949243828,80.9925899090149,30.3962065887853328]},"#772288":{"lch":[31.4492100235983827,64.0564791390884,297.353574907339521],"luv":[31.4492100235983827,29.432687880373738,-56.8941948166328118],"rgb":[0.466666666666666674,0.133333333333333331,0.533333333333333326],"xyz":[0.126230423972121614,0.0684404712500418094,0.239495004303800302],"hpluv":[297.353574907339521,258.459589193709576,31.4492100235983827],"hsluv":[297.353574907339521,83.5725358287189692,31.4492100235983827]},"#772299":{"lch":[32.6267183371791276,73.3979299617999885,289.947447059718741],"luv":[32.6267183371791276,25.040297814612174,-68.9944896932561136],"rgb":[0.466666666666666674,0.133333333333333331,0.6],"xyz":[0.139287388081194341,0.073663256893670967,0.308261681944918209],"hpluv":[289.947447059718741,285.462946683821,32.6267183371791276],"hsluv":[289.947447059718741,85.8272099061853169,32.6267183371791276]},"#7722aa":{"lch":[33.91747454857272,83.3484305918169213,284.681710760769079],"luv":[33.91747454857272,21.1245907707188039,-80.6269963900962],"rgb":[0.466666666666666674,0.133333333333333331,0.66666666666666663],"xyz":[0.154345081046446869,0.0796863340797720754,0.38756553156191681],"hpluv":[284.681710760769079,311.826661765562392,33.91747454857272],"hsluv":[284.681710760769079,87.7639475735253,33.91747454857272]},"#7722bb":{"lch":[35.3096729107126137,93.4985765466947,280.880145280973409],"luv":[35.3096729107126137,17.6483381470917493,-91.8178630599952186],"rgb":[0.466666666666666674,0.133333333333333331,0.733333333333333282],"xyz":[0.171482673153783516,0.086541370922706834,0.477823516660558556],"hpluv":[280.880145280973409,336.008784107710085,35.3096729107126137],"hsluv":[280.880145280973409,89.410850129911168,35.3096729107126137]},"#7722cc":{"lch":[36.7915673195940158,103.646851370476796,278.075561058441508],"luv":[36.7915673195940158,14.5601992392030191,-102.619054746808203],"rgb":[0.466666666666666674,0.133333333333333331,0.8],"xyz":[0.19077504859750527,0.0942583211001956356,0.579430027330828712],"hpluv":[278.075561058441508,357.476214898523438,36.7915673195940158],"hsluv":[278.075561058441508,90.8041771911133395,36.7915673195940158]},"#7722dd":{"lch":[38.351906528896663,113.703099806952181,275.960131804992216],"luv":[38.351906528896663,11.8065226659589069,-113.088465053903391],"rgb":[0.466666666666666674,0.133333333333333331,0.866666666666666696],"xyz":[0.212293374148138814,0.10286565132044917,0.69275987523083471],"hpluv":[275.960131804992216,376.205095027198126,38.351906528896663],"hsluv":[275.960131804992216,91.9810564333708101,38.351906528896663]},"#7722ee":{"lch":[39.9802139341708269,123.633267676123751,274.331320845995606],"luv":[39.9802139341708269,9.33725773346982812,-123.280170726255989],"rgb":[0.466666666666666674,0.133333333333333331,0.933333333333333348],"xyz":[0.236105554414313523,0.112390523426919187,0.818170691299357933],"hpluv":[274.331320845995606,392.400507860275241,39.9802139341708269],"hsluv":[274.331320845995606,92.975835565241681,39.9802139341708269]},"#7722ff":{"lch":[41.6669409214524222,133.430100966175758,273.053819065229],"luv":[41.6669409214524222,7.10835060884393233,-133.240621416539511],"rgb":[0.466666666666666674,0.133333333333333331,1],"xyz":[0.262276602824144944,0.122858942790851897,0.956004879591139778],"hpluv":[273.053819065229,406.351179140502,41.6669409214524222],"hsluv":[273.053819065229,99.9999999999994,41.6669409214524222]},"#eeaa00":{"lch":[74.1441199778221716,94.3993067628715323,52.9277228913731435],"luv":[74.1441199778221716,56.9059790518510553,75.3189130661151438],"rgb":[0.933333333333333348,0.66666666666666663,0],"xyz":[0.496332043879122442,0.469286695915611562,0.0644413600602487119],"hpluv":[52.9277228913731435,161.559096825574699,74.1441199778221716],"hsluv":[52.9277228913731435,100.00000000000226,74.1441199778221716]},"#eeaa11":{"lch":[74.170022976797469,93.4032488378738748,52.6298301838218165],"luv":[74.170022976797469,56.6922374254564474,74.2304325001913412],"rgb":[0.933333333333333348,0.66666666666666663,0.0666666666666666657],"xyz":[0.497343709378759546,0.469691362115466415,0.0697694650250043485],"hpluv":[52.6298301838218165,159.798572537124,74.170022976797469],"hsluv":[52.6298301838218165,98.6103970010943698,74.170022976797469]},"#eeaa22":{"lch":[74.2180009061856794,91.5777923210439866,52.06484069365154],"luv":[74.2180009061856794,56.2992155036066038,72.2280442769616],"rgb":[0.933333333333333348,0.66666666666666663,0.133333333333333331],"xyz":[0.499219067517236603,0.470441505370857216,0.0796463512209835411],"hpluv":[52.06484069365154,156.574215350823607,74.2180009061856794],"hsluv":[52.06484069365154,96.0561964998804427,74.2180009061856794]},"#eeaa33":{"lch":[74.296884894391,88.6315089581908353,51.0969321655322659],"luv":[74.296884894391,55.6610065739707096,68.9738843866158646],"rgb":[0.933333333333333348,0.66666666666666663,0.2],"xyz":[0.502306818249694365,0.471676605663840343,0.0959085050785946913],"hpluv":[51.0969321655322659,151.375944062314744,74.296884894391],"hsluv":[51.0969321655322659,91.9112466174575786,74.296884894391]},"#eeaa44":{"lch":[74.4105324975616,84.5080331915566,49.6113532778883268],"luv":[74.4105324975616,54.7585847399730952,64.3669563610119582],"rgb":[0.933333333333333348,0.66666666666666663,0.266666666666666663],"xyz":[0.506764813493913224,0.473459803761527909,0.11938728003148133],"hpluv":[49.6113532778883268,144.112916810009352,74.4105324975616],"hsluv":[49.6113532778883268,86.056132752536,74.4105324975616]},"#eeaa55":{"lch":[74.5620870475656545,79.2349762990306203,47.4460085751506284],"luv":[74.5620870475656545,53.5853993814341081,58.3676832008958897],"rgb":[0.933333333333333348,0.66666666666666663,0.333333333333333315],"xyz":[0.512727227533275154,0.475844769377272769,0.150789327305455245],"hpluv":[47.4460085751506284,134.846041865267,74.5620870475656545],"hsluv":[47.4460085751506284,78.4547380743125302,74.5620870475656545]},"#eeaa66":{"lch":[74.7541548019056705,72.9335579755352512,44.3584242628533616],"luv":[74.7541548019056705,52.1460491859645643,50.9911113162453518],"rgb":[0.933333333333333348,0.66666666666666663,0.4],"xyz":[0.520312223306783395,0.478878767686676088,0.190736971712599179],"hpluv":[44.3584242628533616,123.803063546095515,74.7541548019056705],"hsluv":[44.3584242628533616,69.1456590086766,74.7541548019056705]},"#eeaa77":{"lch":[74.988898345165353,65.8409092602829702,39.9757578623994689],"luv":[74.988898345165353,50.4549646902964213,42.3003767160737851],"rgb":[0.933333333333333348,0.66666666666666663,0.466666666666666674],"xyz":[0.529626236326985245,0.482604372894756883,0.239790773618997088],"hpluv":[39.9757578623994689,111.41359114675457,74.988898345165353],"hsluv":[39.9757578623994689,69.3768546233612398,74.988898345165353]},"#eeaa88":{"lch":[75.268091919562039,58.355059996267,33.7246537035848917],"luv":[75.268091919562039,48.5347963512250544,32.3988668060016],"rgb":[0.933333333333333348,0.66666666666666663,0.533333333333333326],"xyz":[0.540766653428929156,0.487060539735534481,0.298463637022569284],"hpluv":[33.7246537035848917,98.3800275430836706,75.268091919562039],"hsluv":[33.7246537035848917,69.7313730072723388,75.268091919562039]},"#eeaa99":{"lch":[75.5931575717450102,51.1191249468368198,24.7740386445795764],"luv":[75.5931575717450102,46.4145012045046172,21.4209946843594],"rgb":[0.933333333333333348,0.66666666666666663,0.6],"xyz":[0.5538236175380018,0.492283325379163639,0.367230314663687163],"hpluv":[24.7740386445795764,85.8104641434512274,75.5931575717450102],"hsluv":[24.7740386445795764,70.1099573125584925,75.5931575717450102]},"#eeaaaa":{"lch":[75.9651912478537,45.142946910964838,12.1770506300622827],"luv":[75.9651912478537,44.1272513869876164,9.52215001119964199],"rgb":[0.933333333333333348,0.66666666666666663,0.66666666666666663],"xyz":[0.568881310503254412,0.498306402565264761,0.446534164280685764],"hpluv":[12.1770506300622827,75.4075094474617771,75.9651912478537],"hsluv":[12.1770506300622827,70.5013292017584661,75.9651912478537]},"#eeaabb":{"lch":[76.3849837125259512,41.8257198613105743,355.706426922992932],"luv":[76.3849837125259512,41.7083375548448743,-3.13136077895000353],"rgb":[0.933333333333333348,0.66666666666666663,0.733333333333333282],"xyz":[0.586018902610591,0.505161439408199464,0.53679214937932751],"hpluv":[355.706426922992932,71.0120800923082243,76.3849837125259512],"hsluv":[355.706426922992932,70.8933377227291857,76.3849837125259512]},"#eeaacc":{"lch":[76.8530390510081,42.4751513806234229,337.329003704434115],"luv":[76.8530390510081,39.1932374848878169,-16.3715796507258275],"rgb":[0.933333333333333348,0.66666666666666663,0.8],"xyz":[0.605311278054312729,0.512878389585688321,0.638398660049597666],"hpluv":[337.329003704434115,73.8860979443606283,76.8530390510081],"hsluv":[337.329003704434115,71.273377003825658,76.8530390510081]},"#eeaadd":{"lch":[77.3695923472492666,47.3596417233686893,320.637369166639587],"luv":[77.3695923472492666,36.6159833837478814,-30.0367345929437413],"rgb":[0.933333333333333348,0.66666666666666663,0.866666666666666696],"xyz":[0.626829603604946328,0.521485719805941828,0.751728507949603664],"hpluv":[320.637369166639587,84.6581146126829,77.3695923472492666],"hsluv":[320.637369166639587,71.6287050870027144,77.3695923472492666]},"#eeaaee":{"lch":[77.9346274334411078,55.5926087174301244,307.715012949246329],"luv":[77.9346274334411078,34.00790779424905,-43.9772708506012506],"rgb":[0.933333333333333348,0.66666666666666663,0.933333333333333348],"xyz":[0.650641783871121,0.531010591912411845,0.877139324018126887],"hpluv":[307.715012949246329,102.440850498764817,77.9346274334411078],"hsluv":[307.715012949246329,71.9466349992656,77.9346274334411078]},"#eeaaff":{"lch":[78.5478951631237123,66.0054362136172,298.40296943037481],"luv":[78.5478951631237123,31.3967924706888546,-58.0599606639755166],"rgb":[0.933333333333333348,0.66666666666666663,1],"xyz":[0.676812832280952459,0.541479011276344568,1.01497351230990884],"hpluv":[298.40296943037481,125.797711632464541,78.5478951631237123],"hsluv":[298.40296943037481,99.9999999999967457,78.5478951631237123]},"#773300":{"lch":[30.1331354048611715,59.6402239078303253,26.8671398719653283],"luv":[30.1331354048611715,53.2024709950710601,26.952799257122777],"rgb":[0.466666666666666674,0.2,0],"xyz":[0.0879135365113257461,0.0629020716081407,0.0075119680378166135],"hpluv":[26.8671398719653283,251.150628123644026,30.1331354048611715],"hsluv":[26.8671398719653283,100.000000000002174,30.1331354048611715]},"#773311":{"lch":[30.23185303241101,57.2493346092074376,24.6191658238461528],"luv":[30.23185303241101,52.0451874365790204,23.8492091669378929],"rgb":[0.466666666666666674,0.2,0.0666666666666666657],"xyz":[0.0889252020109628644,0.0633067378079955473,0.012840073002572245],"hpluv":[24.6191658238461528,240.295148301589592,30.23185303241101],"hsluv":[24.6191658238461528,89.9983576544591131,30.23185303241101]},"#773322":{"lch":[30.4137421865898716,53.2944669038914185,20.1857997859538507],"luv":[30.4137421865898716,50.0210446853216055,18.3900867632275506],"rgb":[0.466666666666666674,0.2,0.133333333333333331],"xyz":[0.0908005601494399,0.0640568810633863617,0.022716959198551441],"hpluv":[20.1857997859538507,222.35740076876786,30.4137421865898716],"hsluv":[20.1857997859538507,72.5478159849102,30.4137421865898716]},"#773333":{"lch":[30.7101510688592612,48.0738359215612618,12.1770506300619186],"luv":[30.7101510688592612,46.9921967440780932,10.1403720532853221],"rgb":[0.466666666666666674,0.2,0.2],"xyz":[0.093888310881897627,0.0652919813563694745,0.0389791130561625843],"hpluv":[12.1770506300619186,198.639745699191,30.7101510688592612],"hsluv":[12.1770506300619186,46.5474493854848177,30.7101510688592612]},"#773344":{"lch":[31.1315732769052218,43.177963340605487,359.450637080068248],"luv":[31.1315732769052218,43.1759786068728815,-0.413992248148033204],"rgb":[0.466666666666666674,0.2,0.266666666666666663],"xyz":[0.0983463061261165,0.0670751794540570545,0.0624578880090492228],"hpluv":[359.450637080068248,175.995032884643848,31.1315732769052218],"hsluv":[359.450637080068248,50.753084379908266,31.1315732769052218]},"#773355":{"lch":[31.6836931484193158,40.8566925980369149,342.103665666318761],"luv":[31.6836931484193158,38.8798033655970627,-12.5550874271345432],"rgb":[0.466666666666666674,0.2,0.333333333333333315],"xyz":[0.1043087201654785,0.0694601450698018874,0.0938599352830231382],"hpluv":[342.103665666318761,163.631433468067485,31.6836931484193158],"hsluv":[342.103665666318761,55.4419897041632623,31.6836931484193158]},"#773366":{"lch":[32.368092831934419,42.8604868736005429,323.403106692152903],"luv":[32.368092831934419,34.4105334223914952,-25.55262265656037],"rgb":[0.466666666666666674,0.2,0.4],"xyz":[0.111893715938986671,0.0724941433792052,0.1338075796901671],"hpluv":[323.403106692152903,168.027093700417197,32.368092831934419],"hsluv":[323.403106692152903,60.2559031079253913,32.368092831934419]},"#773377":{"lch":[33.18286532501061,49.0630735877418189,307.715012949244226],"luv":[33.18286532501061,30.0135669321659,-38.8119954380674201],"rgb":[0.466666666666666674,0.2,0.466666666666666674],"xyz":[0.12120772895918859,0.0762197485872860153,0.182861381596565],"hpluv":[307.715012949244226,187.620458725202155,33.18286532501061],"hsluv":[307.715012949244226,64.9109644958811458,33.18286532501061]},"#773388":{"lch":[34.1232577260479,58.0074356166469371,296.464975996700218],"luv":[34.1232577260479,25.8510525803809479,-51.9286594021626868],"rgb":[0.466666666666666674,0.2,0.533333333333333326],"xyz":[0.132348146061132432,0.0806759154280636132,0.241534245000137177],"hpluv":[296.464975996700218,215.711106662248483,34.1232577260479],"hsluv":[296.464975996700218,69.2226633917654226,34.1232577260479]},"#773399":{"lch":[35.1823459678372572,68.3160830057283,288.793689920994325],"luv":[35.1823459678372572,22.0088074868374761,-64.6737936899706369],"rgb":[0.466666666666666674,0.2,0.6],"xyz":[0.145405110170205132,0.0858987010716927707,0.310300922641255084],"hpluv":[288.793689920994325,246.398176299420243,35.1823459678372572],"hsluv":[288.793689920994325,73.0971646513407,35.1823459678372572]},"#7733aa":{"lch":[36.3517007299652,79.1457370086552316,283.529620316849901],"luv":[36.3517007299652,18.5159885211015585,-76.9493720294691741],"rgb":[0.466666666666666674,0.2,0.66666666666666663],"xyz":[0.160462803135457688,0.0919217782577938791,0.389604772258253684],"hpluv":[283.529620316849901,276.275338575971432,36.3517007299652],"hsluv":[283.529620316849901,76.5077273075914093,36.3517007299652]},"#7733bb":{"lch":[37.6219984216960484,90.0609255961329183,279.823655256592],"luv":[37.6219984216960484,15.3658639022925581,-88.7404110074345596],"rgb":[0.466666666666666674,0.2,0.733333333333333282],"xyz":[0.177600395242794307,0.0987768151007286377,0.479862757356895431],"hpluv":[279.823655256592,303.762299466947354,37.6219984216960484],"hsluv":[279.823655256592,79.4699002038008615,37.6219984216960484]},"#7733cc":{"lch":[38.9835424310364687,100.85881095677091,277.137789072490136],"luv":[38.9835424310364687,12.5323059717609908,-100.077175492935524],"rgb":[0.466666666666666674,0.2,0.8],"xyz":[0.196892770686516061,0.106493765278217439,0.581469268027165587],"hpluv":[277.137789072490136,328.300745951509327,38.9835424310364687],"hsluv":[277.137789072490136,82.0218198813884,38.9835424310364687]},"#7733dd":{"lch":[40.4266769703902469,111.457640409912926,275.137669231249674],"luv":[40.4266769703902469,9.98093438608736,-111.009848907770674],"rgb":[0.466666666666666674,0.2,0.866666666666666696],"xyz":[0.218411096237149605,0.115101095498470973,0.694799115927171584],"hpluv":[275.137669231249674,349.849394775278881,40.4266769703902469],"hsluv":[275.137669231249674,84.2108753320266459,40.4266769703902469]},"#7733ee":{"lch":[41.9420918590451066,121.83559331992231,273.612094072304103],"luv":[41.9420918590451066,7.67578650940870766,-121.593561100411392],"rgb":[0.466666666666666674,0.2,0.933333333333333348],"xyz":[0.242223276503324342,0.12462596760494099,0.820209931995694808],"hpluv":[273.612094072304103,368.606867281158145,41.9420918590451066],"hsluv":[273.612094072304103,91.3228806729277665,41.9420918590451066]},"#7733ff":{"lch":[43.521028110395612,131.998699032970592,272.424037139620168],"luv":[43.521028110395612,5.58285979872954208,-131.88058319125102],"rgb":[0.466666666666666674,0.2,1],"xyz":[0.268394324913155735,0.135094386968873714,0.958044120287476653],"hpluv":[272.424037139620168,384.866252510120546,43.521028110395612],"hsluv":[272.424037139620168,99.9999999999993605,43.521028110395612]},"#eebb00":{"lch":[78.2979307719844115,92.4506686575273307,61.8965912674010781],"luv":[78.2979307719844115,43.5502151824584587,81.5506277890334275],"rgb":[0.933333333333333348,0.733333333333333282,0],"xyz":[0.530286541787721277,0.537195691732810121,0.0757595260297813378],"hpluv":[61.8965912674010781,173.778692590363192,78.2979307719844115],"hsluv":[61.8965912674010781,100.000000000002373,78.2979307719844115]},"#eebb11":{"lch":[78.3216028454340858,91.4822746680663528,61.6861071172261504],"luv":[78.3216028454340858,43.3901974999079059,80.5375523551748],"rgb":[0.933333333333333348,0.733333333333333282,0.0666666666666666657],"xyz":[0.531298207287358437,0.537600357932665,0.0810876309945369744],"hpluv":[61.6861071172261504,172.182825477748111,78.3216028454340858],"hsluv":[61.6861071172261504,98.7812238781787642,78.3216028454340858]},"#eebb22":{"lch":[78.3654531575016335,89.702527227679937,61.2866058237147371],"luv":[78.3654531575016335,43.0956539167563477,78.672155204492924],"rgb":[0.933333333333333348,0.733333333333333282,0.133333333333333331],"xyz":[0.533173565425835383,0.53835050118805583,0.090964517190516167],"hpluv":[61.2866058237147371,169.241982225815036,78.3654531575016335],"hsluv":[61.2866058237147371,96.5386826089343,78.3654531575016335]},"#eebb33":{"lch":[78.4375634156200192,86.8156112143301897,60.6012126372659665],"luv":[78.4375634156200192,42.6165086308843897,75.6358614853528906],"rgb":[0.933333333333333348,0.733333333333333282,0.2],"xyz":[0.5362613161582932,0.539585601481039,0.107226671048127303],"hpluv":[60.6012126372659665,164.44952499458185,78.4375634156200192],"hsluv":[60.6012126372659665,92.89304460263088,78.4375634156200192]},"#eebb44":{"lch":[78.5414800230656,82.7424491039972878,59.5464137785053],"luv":[78.5414800230656,41.9372005918819397,71.3273025583039839],"rgb":[0.933333333333333348,0.733333333333333282,0.266666666666666663],"xyz":[0.540719311402512059,0.541368799578726523,0.130705446001013942],"hpluv":[59.5464137785053,157.640041580932575,78.5414800230656],"hsluv":[59.5464137785053,87.729612164687,78.5414800230656]},"#eebb55":{"lch":[78.6801087960333,77.4695312482544,58.0014729567720551],"luv":[78.6801087960333,41.0509080282697809,65.6989438414256455],"rgb":[0.933333333333333348,0.733333333333333282,0.333333333333333315],"xyz":[0.546681725441874,0.543753765194471272,0.162107493274987857],"hpluv":[58.0014729567720551,148.738759066450825,78.6801087960333],"hsluv":[58.0014729567720551,81.0022494643358613,78.6801087960333]},"#eebb66":{"lch":[78.8558787138066748,71.0520814803831229,55.7790951769469174],"luv":[78.8558787138066748,39.9586324736418845,58.7512210386423703],"rgb":[0.933333333333333348,0.733333333333333282,0.4],"xyz":[0.55426672121538223,0.546787763503874591,0.202055137682131819],"hpluv":[55.7790951769469174,137.768430134850121,78.8558787138066748],"hsluv":[55.7790951769469174,72.7264864885570574,78.8558787138066748]},"#eebb77":{"lch":[79.0708286262536,63.6259938562226566,52.5733668905169],"luv":[79.0708286262536,38.6683825737350801,50.5274507898760348],"rgb":[0.933333333333333348,0.733333333333333282,0.466666666666666674],"xyz":[0.56358073423558408,0.550513368711955442,0.251108939588529756],"hpluv":[52.5733668905169,124.876553308513152,79.0708286262536],"hsluv":[52.5733668905169,64.3532422469102841,79.0708286262536]},"#eebb88":{"lch":[79.3266586201773833,55.4370708593257149,47.8613800964459557],"luv":[79.3266586201773833,37.1942049853437169,41.1079060640423961],"rgb":[0.933333333333333348,0.733333333333333282,0.533333333333333326],"xyz":[0.574721151337528,0.554969535552733,0.309781802992101896],"hpluv":[47.8613800964459557,110.403075040931697,79.3266586201773833],"hsluv":[47.8613800964459557,64.6428486235092379,79.3266586201773833]},"#eebb99":{"lch":[79.6247632766216071,46.9114913521919519,40.7190885070752131],"luv":[79.6247632766216071,35.5550187983100727,30.6027557441907163],"rgb":[0.933333333333333348,0.733333333333333282,0.6],"xyz":[0.587778115446600635,0.560192321196362197,0.378548480633219775],"hpluv":[40.7190885070752131,95.0436922052712845,79.6247632766216071],"hsluv":[40.7190885070752131,64.94797236425741,79.6247632766216071]},"#eebbaa":{"lch":[79.9662551563314,38.821829319770238,29.5464132636418633],"luv":[79.9662551563314,33.7733033676501,19.1441482278540249],"rgb":[0.933333333333333348,0.733333333333333282,0.66666666666666663],"xyz":[0.602835808411853247,0.566215398382463264,0.457852330250218431],"hpluv":[29.5464132636418633,80.2381481795300573,79.9662551563314],"hsluv":[29.5464132636418633,65.2570717669902081,79.9662551563314]},"#eebbbb":{"lch":[80.3519829843595,32.6073830473385868,12.1770506300627979],"luv":[80.3519829843595,31.8737319395561,6.87798236703069765],"rgb":[0.933333333333333348,0.733333333333333282,0.733333333333333282],"xyz":[0.61997340051918981,0.573070435225398,0.548110315348860122],"hpluv":[12.1770506300627979,68.9527679352530498,80.3519829843595],"hsluv":[12.1770506300627979,65.5572779496269646,80.3519829843595]},"#eebbcc":{"lch":[80.7825470949933,30.4869713003172755,348.56539147946927],"luv":[80.7825470949933,29.8818538307637169,-6.04402437976891349],"rgb":[0.933333333333333348,0.733333333333333282,0.8],"xyz":[0.639265775962911564,0.58078738540288688,0.649716826019130278],"hpluv":[348.56539147946927,66.1649916626687542,80.7825470949933],"hsluv":[348.56539147946927,65.8346704867411,80.7825470949933]},"#eebbdd":{"lch":[81.2583136554081165,33.9595526191752555,325.014354592586812],"luv":[81.2583136554081165,27.8229160969035512,-19.4714291709468021],"rgb":[0.933333333333333348,0.733333333333333282,0.866666666666666696],"xyz":[0.660784101513545163,0.589394715623140386,0.763046673919136276],"hpluv":[325.014354592586812,75.8902298772919721,81.2583136554081165],"hsluv":[325.014354592586812,66.0744631525984119,81.2583136554081165]},"#eebbee":{"lch":[81.7794285687783429,42.0458499431423576,307.715012949247921],"luv":[81.7794285687783429,25.7208902583653902,-33.2609275540891716],"rgb":[0.933333333333333348,0.733333333333333282,0.933333333333333348],"xyz":[0.684596281779719873,0.598919587729610403,0.888457489987659499],"hpluv":[307.715012949247921,97.0917602325266245,81.7794285687783429],"hsluv":[307.715012949247921,66.2610602343042103,81.7794285687783429]},"#eebbff":{"lch":[82.3458315671937697,52.842459086223478,296.523687653639684],"luv":[82.3458315671937697,23.5977388768935938,-47.2807804734349446],"rgb":[0.933333333333333348,0.733333333333333282,1],"xyz":[0.710767330189551294,0.609388007093543127,1.02629167827944134],"hpluv":[296.523687653639684,126.563624284615543,82.3458315671937697],"hsluv":[296.523687653639684,99.9999999999958504,82.3458315671937697]},"#774400":{"lch":[34.1007355557283631,52.2824067620925845,38.9690248280103901],"luv":[34.1007355557283631,40.6488429776156863,32.8804139483986475],"rgb":[0.466666666666666674,0.266666666666666663,0],"xyz":[0.0967461069942917862,0.0805672125740730105,0.0104561581988052085],"hpluv":[38.9690248280103901,194.549962435525771,34.1007355557283631],"hsluv":[38.9690248280103901,100.000000000002302,34.1007355557283631]},"#774411":{"lch":[34.1844760931178726,49.9480603042207,37.0032460066389604],"luv":[34.1844760931178726,39.8885915773263164,30.0617529450848728],"rgb":[0.466666666666666674,0.266666666666666663,0.0666666666666666657],"xyz":[0.0977577724939289,0.0809718787739278634,0.0157842631635608383],"hpluv":[37.0032460066389604,185.408237524396696,34.1844760931178726],"hsluv":[37.0032460066389604,92.0774266797174477,34.1844760931178726]},"#774422":{"lch":[34.3389737161705639,45.9687551907429608,33.0232295817012798],"luv":[34.3389737161705639,38.542488289151045,25.0520069109664867],"rgb":[0.466666666666666674,0.266666666666666663,0.133333333333333331],"xyz":[0.0996331306324059335,0.0817220220293186778,0.0256611493595400378],"hpluv":[33.0232295817012798,169.869245826721482,34.3389737161705639],"hsluv":[33.0232295817012798,78.0803941927279794,34.3389737161705639]},"#774433":{"lch":[34.5913049894652787,40.4066166426811861,25.4401077009201266],"luv":[34.5913049894652787,36.4885814660887746,17.357364174931714],"rgb":[0.466666666666666674,0.266666666666666663,0.2],"xyz":[0.102720881364863667,0.0829571223223017906,0.041923303217151181],"hpluv":[25.4401077009201266,148.226163260119392,34.5913049894652787],"hsluv":[25.4401077009201266,56.8050953227402715,34.5913049894652787]},"#774444":{"lch":[34.9512320153617324,34.6101233100924119,12.1770506300620909],"luv":[34.9512320153617324,33.8314114683579277,7.30042694631360689],"rgb":[0.466666666666666674,0.266666666666666663,0.266666666666666663],"xyz":[0.107178876609082541,0.0847403204199893706,0.0654020781700378195],"hpluv":[12.1770506300620909,125.655060642768362,34.9512320153617324],"hsluv":[12.1770506300620909,29.4448754689639038,34.9512320153617324]},"#774455":{"lch":[35.4248138391838907,31.0799263948782318,351.580242092888511],"luv":[35.4248138391838907,30.7449438027498871,-4.55085214842230634],"rgb":[0.466666666666666674,0.266666666666666663,0.333333333333333315],"xyz":[0.11314129064844454,0.0871252860357342,0.0968041254440117349],"hpluv":[351.580242092888511,111.329877567225012,35.4248138391838907],"hsluv":[351.580242092888511,35.0525071981411855,35.4248138391838907]},"#774466":{"lch":[36.0149447056398699,32.55773059028094,327.386935336661793],"luv":[36.0149447056398699,27.4243377055297302,-17.5474078599198116],"rgb":[0.466666666666666674,0.266666666666666663,0.4],"xyz":[0.120726286421952711,0.090159284345137522,0.136751769851155697],"hpluv":[327.386935336661793,114.712488009680612,36.0149447056398699],"hsluv":[327.386935336661793,41.0162201785438469,36.0149447056398699]},"#774477":{"lch":[36.7217587051522898,39.3078830273429531,307.715012949244965],"luv":[36.7217587051522898,24.0459818745983789,-31.0950224919964064],"rgb":[0.466666666666666674,0.266666666666666663,0.466666666666666674],"xyz":[0.130040299442154617,0.0938848895532183314,0.185805571757553606],"hpluv":[307.715012949244965,135.82994003022975,36.7217587051522898],"hsluv":[307.715012949244965,46.9930223744603381,36.7217587051522898]},"#774488":{"lch":[37.5430301686231331,49.3077922843884906,294.880307130505798],"luv":[37.5430301686231331,20.7449732069104158,-44.731470651041306],"rgb":[0.466666666666666674,0.266666666666666663,0.533333333333333326],"xyz":[0.141180716544098472,0.0983410563939959292,0.244478435161125773],"hpluv":[294.880307130505798,166.657768282509579,37.5430301686231331],"hsluv":[294.880307130505798,52.7229750286883814,37.5430301686231331]},"#774499":{"lch":[38.4745988052595678,60.7540316024919775,286.849160899925266],"luv":[38.4745988052595678,17.609743748149274,-58.1459309073396042],"rgb":[0.466666666666666674,0.266666666666666663,0.6],"xyz":[0.154237680653171172,0.103563842037625087,0.313245112802243653],"hpluv":[286.849160899925266,200.373520820200838,38.4745988052595678],"hsluv":[286.849160899925266,58.0391908614757739,38.4745988052595678]},"#7744aa":{"lch":[39.5108096650206306,72.6607854160185695,281.662296555210446],"luv":[39.5108096650206306,14.6878600390207232,-71.1607792589909423],"rgb":[0.466666666666666674,0.266666666666666663,0.66666666666666663],"xyz":[0.169295373618423728,0.109586919223726181,0.392548962419242253],"hpluv":[281.662296555210446,233.358425064810547,39.5108096650206306],"hsluv":[281.662296555210446,62.855979622580108,39.5108096650206306]},"#7744bb":{"lch":[40.6449442050895,84.5532389367896684,278.156646558388104],"luv":[40.6449442050895,11.9964108827533504,-83.6978873128468],"rgb":[0.466666666666666674,0.266666666666666663,0.733333333333333282],"xyz":[0.186432965725760347,0.11644195606666094,0.482806947517884],"hpluv":[278.156646558388104,263.975148792079324,40.6449442050895],"hsluv":[278.156646558388104,67.1480450168623832,40.6449442050895]},"#7744cc":{"lch":[41.8696179576200223,96.2178725735773099,275.685728840067554],"luv":[41.8696179576200223,9.53248740063005151,-95.7445073439828747],"rgb":[0.466666666666666674,0.266666666666666663,0.8],"xyz":[0.205725341169482101,0.124158906244149742,0.584413458188154156],"hpluv":[275.685728840067554,291.605746800226,41.8696179576200223],"hsluv":[275.685728840067554,71.7563947172966721,41.8696179576200223]},"#7744dd":{"lch":[43.1771261833787037,107.572507589609089,273.881356516641858],"luv":[43.1771261833787037,7.28165300546471084,-107.325774717094461],"rgb":[0.466666666666666674,0.266666666666666663,0.866666666666666696],"xyz":[0.227243666720115645,0.132766236464403276,0.697743306088160153],"hpluv":[273.881356516641858,316.145413845169799,43.1771261833787037],"hsluv":[273.881356516641858,81.1040313116107683,43.1771261833787037]},"#7744ee":{"lch":[44.5597272061305958,118.600491111934247,272.524492751992966],"luv":[44.5597272061305958,5.22393127379498168,-118.485387428318177],"rgb":[0.466666666666666674,0.266666666666666663,0.933333333333333348],"xyz":[0.251055846986290354,0.14229110857087332,0.823154122156683377],"hpluv":[272.524492751992966,337.740615485066769,44.5597272061305958],"hsluv":[272.524492751992966,90.4775463334620866,44.5597272061305958]},"#7744ff":{"lch":[46.0098610845945188,129.316457315512423,271.478956563127554],"luv":[46.0098610845945188,3.33763127257498882,-129.273378350389976],"rgb":[0.466666666666666674,0.266666666666666663,1],"xyz":[0.277226895396121775,0.152759527934806016,0.960988310448465222],"hpluv":[271.478956563127554,356.649979093308843,46.0098610845945188],"hsluv":[271.478956563127554,99.9999999999992752,46.0098610845945188]},"#eecc00":{"lch":[82.5742071813858161,93.0890420253441278,70.6743105766144737],"luv":[82.5742071813858161,30.8066573410433797,87.8437226480516529],"rgb":[0.933333333333333348,0.8,0],"xyz":[0.568510285097338142,0.613643178352045071,0.088500773799653279],"hpluv":[70.6743105766144737,226.330948640265689,82.5742071813858161],"hsluv":[70.6743105766144737,100.000000000002331,82.5742071813858161]},"#eecc11":{"lch":[82.5958706312260773,92.1609271203023,70.5494354113464226],"luv":[82.5958706312260773,30.6889817522442812,86.9012248859824297],"rgb":[0.933333333333333348,0.8,0.0666666666666666657],"xyz":[0.569521950596975302,0.6140478445519,0.0938288787644089156],"hpluv":[70.5494354113464226,224.395635781555484,82.5958706312260773],"hsluv":[70.5494354113464226,98.9293851282895389,82.5958706312260773]},"#eecc22":{"lch":[82.636003730849751,90.4517890224530277,70.3125751850760849],"luv":[82.636003730849751,30.4721781878481224,85.1643851257694848],"rgb":[0.933333333333333348,0.8,0.133333333333333331],"xyz":[0.571397308735452247,0.61479798780729078,0.103705764960388108],"hpluv":[70.3125751850760849,220.820363432361461,82.636003730849751],"hsluv":[70.3125751850760849,96.9576791715233668,82.636003730849751]},"#eecc33":{"lch":[82.7020112487531,87.6695564091762236,69.9066450473675332],"luv":[82.7020112487531,30.1189443150749909,82.3334701948554084],"rgb":[0.933333333333333348,0.8,0.2],"xyz":[0.574485059467910064,0.616033088100273907,0.119967918817999258],"hpluv":[69.9066450473675332,214.968262161852493,82.7020112487531],"hsluv":[69.9066450473675332,93.7473974454290726,82.7020112487531]},"#eecc44":{"lch":[82.7971553193909102,83.7217279628800242,69.2828434677537786],"luv":[82.7971553193909102,29.6169744667019792,78.3081257375581],"rgb":[0.933333333333333348,0.8,0.266666666666666663],"xyz":[0.578943054712128924,0.617816286197961473,0.143446693770885897],"hpluv":[69.2828434677537786,206.594355258371763,82.7971553193909102],"hsluv":[69.2828434677537786,89.1900904304584685,82.7971553193909102]},"#eecc55":{"lch":[82.9241214704336471,78.5673404382155098,68.3706518767947387],"luv":[82.9241214704336471,28.9599810639926183,73.0352413585910085],"rgb":[0.933333333333333348,0.8,0.333333333333333315],"xyz":[0.584905468751490853,0.620201251813706222,0.174848741044859812],"hpluv":[68.3706518767947387,195.532369916851508,82.9241214704336471],"hsluv":[68.3706518767947387,83.2339277722755497,82.9241214704336471]},"#eecc66":{"lch":[83.0851700146488241,72.2150018940459688,67.0599726095305186],"luv":[83.0851700146488241,28.1470538355007811,66.503758231685552],"rgb":[0.933333333333333348,0.8,0.4],"xyz":[0.592490464524999094,0.623235250123109541,0.214796385452003746],"hpluv":[67.0599726095305186,181.688085793908328,83.0851700146488241],"hsluv":[67.0599726095305186,75.8779818086204898,83.0851700146488241]},"#eecc77":{"lch":[83.2822165713090925,64.7250307453925586,65.1677162202921778],"luv":[83.2822165713090925,27.1821511319325673,58.740618526133936],"rgb":[0.933333333333333348,0.8,0.466666666666666674],"xyz":[0.601804477545200944,0.626960855331190392,0.263850187358401655],"hpluv":[65.1677162202921778,165.044758034407693,83.2822165713090925],"hsluv":[65.1677162202921778,67.1675472191497533,83.2822165713090925]},"#eecc88":{"lch":[83.5168798492942699,56.2182636624862511,62.3679934299132839],"luv":[83.5168798492942699,26.0735255024375405,49.8062690541919793],"rgb":[0.933333333333333348,0.8,0.533333333333333326],"xyz":[0.612944894647144856,0.631417022171967934,0.322523050761973851],"hpluv":[62.3679934299132839,145.689263900370548,83.5168798492942699],"hsluv":[62.3679934299132839,57.1887031148042198,83.5168798492942699]},"#eecc99":{"lch":[83.79051243806407,46.9027423702446598,58.0311593919332083],"luv":[83.79051243806407,24.8330316313984234,39.7892923013655633],"rgb":[0.933333333333333348,0.8,0.6],"xyz":[0.6260018587562175,0.636639807815597147,0.39128972840309173],"hpluv":[58.0311593919332083,123.89218615802821,83.79051243806407],"hsluv":[58.0311593919332083,56.9799526918745158,83.79051243806407]},"#eeccaa":{"lch":[84.1042222244633,37.1556922719042646,50.8162292091241454],"luv":[84.1042222244633,23.475329457535171,28.8002495660129298],"rgb":[0.933333333333333348,0.8,0.66666666666666663],"xyz":[0.641059551721470111,0.642662885001698214,0.470593578020090331],"hpluv":[50.8162292091241454,100.353156070069275,84.1042222244633],"hsluv":[50.8162292091241454,57.1375361174420533,84.1042222244633]},"#eeccbb":{"lch":[84.4588885299527,27.7950211383377486,37.6158086991229084],"luv":[84.4588885299527,22.0170273242058485,16.9650731765535063],"rgb":[0.933333333333333348,0.8,0.733333333333333282],"xyz":[0.658197143828806674,0.649517921844633,0.560851563118732077],"hpluv":[37.6158086991229084,77.0182985337263517,84.4588885299527],"hsluv":[37.6158086991229084,57.2612530554736736,84.4588885299527]},"#eecccc":{"lch":[84.8551753311588897,20.9471233587290264,12.1770506300631585],"luv":[84.8551753311588897,20.4758227261490333,4.41844550641173317],"rgb":[0.933333333333333348,0.8,0.8],"xyz":[0.677489519272528429,0.65723487202212183,0.662458073789002233],"hpluv":[12.1770506300631585,59.764130158742411,84.8551753311588897],"hsluv":[12.1770506300631585,57.3329985994000637,84.8551753311588897]},"#eeccdd":{"lch":[85.2935429882433596,20.7797326136980232,335.241604291037675],"luv":[85.2935429882433596,18.8696973425293919,-8.70240252448279],"rgb":[0.933333333333333348,0.8,0.866666666666666696],"xyz":[0.699007844823162,0.665842202242375336,0.775787921689008231],"hpluv":[335.241604291037675,61.2821093808529582,85.2935429882433596],"hsluv":[335.241604291037675,57.3323512744098664,85.2935429882433596]},"#eeccee":{"lch":[85.7742593547863805,28.14328338963319,307.715012949251047],"luv":[85.7742593547863805,17.2162128855465397,-22.2631177921859056],"rgb":[0.933333333333333348,0.8,0.933333333333333348],"xyz":[0.722820025089336737,0.675367074348845353,0.901198737757531454],"hpluv":[307.715012949251047,86.153290074940827,85.7742593547863805],"hsluv":[307.715012949251047,57.2362127773837557,85.7742593547863805]},"#eeccff":{"lch":[86.2974107975625344,39.333162863939684,293.258584701896098],"luv":[86.2974107975625344,15.5319389668875889,-36.1366375415599919],"rgb":[0.933333333333333348,0.8,1],"xyz":[0.748991073499168158,0.685835493712778077,1.03903292604931341],"hpluv":[293.258584701896098,125.558261528980708,86.2974107975625344],"hsluv":[293.258584701896098,99.9999999999940314,86.2974107975625344]},"#775500":{"lch":[38.5848153490983421,48.2339285723334328,54.8056311564330656],"luv":[38.5848153490983421,27.7997213245256276,39.4168410682499868],"rgb":[0.466666666666666674,0.333333333333333315,0],"xyz":[0.108559363708637752,0.104193726002765275,0.0143939104369204193],"hpluv":[54.8056311564330656,158.626424871442595,38.5848153490983421],"hsluv":[54.8056311564330656,100.000000000002302,38.5848153490983421]},"#775511":{"lch":[38.6553893217116595,45.9150245993572952,53.4685955296553956],"luv":[38.6553893217116595,27.3315290852913257,36.8941323494598521],"rgb":[0.466666666666666674,0.333333333333333315,0.0666666666666666657],"xyz":[0.10957102920827487,0.104598392202620127,0.0197220154016760491],"hpluv":[53.4685955296553956,150.724584795248319,38.6553893217116595],"hsluv":[53.4685955296553956,93.8009130268131344,38.6553893217116595]},"#775522":{"lch":[38.7857346943923531,41.8305053308362176,50.7011784026830412],"luv":[38.7857346943923531,26.4939762066725,32.3706719268134577],"rgb":[0.466666666666666674,0.333333333333333315,0.133333333333333331],"xyz":[0.111446387346751899,0.105348535458010942,0.0295989015976552486],"hpluv":[50.7011784026830412,136.854920013655288,38.7857346943923531],"hsluv":[50.7011784026830412,82.7342982429400138,38.7857346943923531]},"#775533":{"lch":[38.9990050188249739,35.7224202133018096,45.1472123185964946],"luv":[38.9990050188249739,25.1945818654867857,25.3243825298663161],"rgb":[0.466666666666666674,0.333333333333333315,0.2],"xyz":[0.114534138079209633,0.106583635750994055,0.0458610554552663918],"hpluv":[45.1472123185964946,116.232257903435652,38.9990050188249739],"hsluv":[45.1472123185964946,65.6272728324870656,38.9990050188249739]},"#775544":{"lch":[39.3040305977305735,28.372964966311546,34.1730058033032336],"luv":[39.3040305977305735,23.4742392428959334,15.9369141601135258],"rgb":[0.466666666666666674,0.333333333333333315,0.266666666666666663],"xyz":[0.118992133323428506,0.108366833848681635,0.0693398304081530303],"hpluv":[34.1730058033032336,91.6024225041024,39.3040305977305735],"hsluv":[34.1730058033032336,43.1049791856067799,39.3040305977305735]},"#775555":{"lch":[39.7068052905653701,21.9117916496410494,12.1770506300624941],"luv":[39.7068052905653701,21.4187864245998618,4.62192615633957704],"rgb":[0.466666666666666674,0.333333333333333315,0.333333333333333315],"xyz":[0.124954547362790505,0.110751799464426468,0.100741877682126946],"hpluv":[12.1770506300624941,70.0248633547080601,39.7068052905653701],"hsluv":[12.1770506300624941,16.4089959502104463,39.7068052905653701]},"#775566":{"lch":[40.21091767922141,20.7753835118276839,337.09176723456028],"luv":[40.21091767922141,19.1368182791551824,-8.08694912894311],"rgb":[0.466666666666666674,0.333333333333333315,0.4],"xyz":[0.132539543136298676,0.113785797773829786,0.140689522089270908],"hpluv":[337.09176723456028,65.5608222190156482,40.21091767922141],"hsluv":[337.09176723456028,22.8015335286909036,40.21091767922141]},"#775577":{"lch":[40.8178321801082404,27.3616881241227183,307.715012949246557],"luv":[40.8178321801082404,16.7380842217685313,-21.6448264854847388],"rgb":[0.466666666666666674,0.333333333333333315,0.466666666666666674],"xyz":[0.141853556156500582,0.117511402981910595,0.189743323995668817],"hpluv":[307.715012949246557,85.0613515767839,40.8178321801082404],"hsluv":[307.715012949246557,29.4286369924042717,40.8178321801082404]},"#775588":{"lch":[41.5271394874135922,38.3484586217177892,291.922773984013077],"luv":[41.5271394874135922,14.317648223710199,-35.5754020076188269],"rgb":[0.466666666666666674,0.333333333333333315,0.533333333333333326],"xyz":[0.152993973258444438,0.121967569822688193,0.248416187399240984],"hpluv":[291.922773984013077,117.180466459805771,41.5271394874135922],"hsluv":[291.922773984013077,36.0000576829853429,41.5271394874135922]},"#775599":{"lch":[42.336815252734,50.9328741768069335,283.566916489070877],"luv":[42.336815252734,11.9478768110398388,-49.5116744982298442],"rgb":[0.466666666666666674,0.333333333333333315,0.6],"xyz":[0.166050937367517137,0.127190355466317351,0.317182865040358863],"hpluv":[283.566916489070877,152.657914615048412,42.336815252734],"hsluv":[283.566916489070877,42.2975255710275704,42.336815252734]},"#7755aa":{"lch":[43.2434937800222059,63.9392804809027098,278.705184193400783],"luv":[43.2434937800222059,9.67722671121172517,-63.202712533524668],"rgb":[0.466666666666666674,0.333333333333333315,0.66666666666666663],"xyz":[0.181108630332769693,0.133213432652418445,0.396486714657357464],"hpluv":[278.705184193400783,187.623095354238075,43.2434937800222059],"hsluv":[278.705184193400783,48.1780536314011272,43.2434937800222059]},"#7755bb":{"lch":[44.2427493107278096,76.8690732738289171,275.624120681329657],"luv":[44.2427493107278096,7.53331271169703509,-76.4990432983646116],"rgb":[0.466666666666666674,0.333333333333333315,0.733333333333333282],"xyz":[0.198246222440106312,0.140068469495353204,0.486744699755999211],"hpluv":[275.624120681329657,220.469676556121556,44.2427493107278096],"hsluv":[275.624120681329657,58.1137757976744496,44.2427493107278096]},"#7755cc":{"lch":[45.3293721892173949,89.4999308488430785,273.541003165926895],"luv":[45.3293721892173949,5.52776894932058127,-89.3290624175056536],"rgb":[0.466666666666666674,0.333333333333333315,0.8],"xyz":[0.217538597883828067,0.147785419672842,0.588351210426269366],"hpluv":[273.541003165926895,250.543028147628775,45.3293721892173949],"hsluv":[273.541003165926895,68.560007412736141,45.3293721892173949]},"#7755dd":{"lch":[46.4976270234735622,101.740884988783861,272.062259876532949],"luv":[46.4976270234735622,3.66119191329505167,-101.674988822595736],"rgb":[0.466666666666666674,0.333333333333333315,0.866666666666666696],"xyz":[0.23905692343446161,0.15639274989309554,0.701681058326275364],"hpluv":[272.062259876532949,277.654072578046794,46.4976270234735622],"hsluv":[272.062259876532949,78.9623412233913911,46.4976270234735622]},"#7755ee":{"lch":[47.7414825998049253,113.569026574645434,270.972372145675877],"luv":[47.7414825998049253,1.92729827623402139,-113.552672000560818],"rgb":[0.466666666666666674,0.333333333333333315,0.933333333333333348],"xyz":[0.26286910370063632,0.165917621999565584,0.827091874394798587],"hpluv":[270.972372145675877,301.858443342198598,47.7414825998049253],"hsluv":[270.972372145675877,89.4067229175139175,47.7414825998049253]},"#7755ff":{"lch":[49.0548071408334749,124.996939079083958,270.144864217432826],"luv":[49.0548071408334749,0.31603661949764611,-124.996539552082652],"rgb":[0.466666666666666674,0.333333333333333315,1],"xyz":[0.289040152110467741,0.17638604136349828,0.964926062686580432],"hpluv":[270.144864217432826,323.338286172745597,49.0548071408334749],"hsluv":[270.144864217432826,99.9999999999992184,49.0548071408334749]},"#eedd00":{"lch":[86.9434330779808562,96.0018853881048528,78.7633058197047831],"luv":[86.9434330779808562,18.7071720605167293,94.1615829920517],"rgb":[0.933333333333333348,0.866666666666666696,0],"xyz":[0.611144275644513346,0.69891115944639659,0.102712103982044597],"hpluv":[78.7633058197047831,323.365375109368927,86.9434330779808562],"hsluv":[78.7633058197047831,100.000000000002331,86.9434330779808562]},"#eedd11":{"lch":[86.9632971622836,95.1251800329902153,78.7103442402005555],"luv":[86.9632971622836,18.6225708681111755,93.2845095960255293],"rgb":[0.933333333333333348,0.866666666666666696,0.0666666666666666657],"xyz":[0.612155941144150506,0.699315825646251499,0.108040208946800234],"hpluv":[78.7103442402005555,320.953864246165836,86.9632971622836],"hsluv":[78.7103442402005555,99.0572185708442134,86.9632971622836]},"#eedd22":{"lch":[87.0000996195567,93.508678235103929,78.6100630695382421],"luv":[87.0000996195567,18.466577094457584,91.6671066178629559],"rgb":[0.933333333333333348,0.866666666666666696,0.133333333333333331],"xyz":[0.614031299282627452,0.700065968901642299,0.117917095142779427],"hpluv":[78.6100630695382421,316.490280961531141,87.0000996195567],"hsluv":[78.6100630695382421,97.3195837272491104,87.0000996195567]},"#eedd33":{"lch":[87.0606371109171704,90.8714304533391157,78.438725785200063],"luv":[87.0606371109171704,18.2120693177914781,89.0277339024194561],"rgb":[0.933333333333333348,0.866666666666666696,0.2],"xyz":[0.617119050015085269,0.701301069194625426,0.134179249000390577],"hpluv":[78.438725785200063,309.159510866930361,87.0606371109171704],"hsluv":[78.438725785200063,94.4866487647953335,87.0606371109171704]},"#eedd44":{"lch":[87.1479139339873399,87.1163282896156375,78.1766823729436737],"luv":[87.1479139339873399,17.8496481580416315,85.2680755927926839],"rgb":[0.933333333333333348,0.866666666666666696,0.266666666666666663],"xyz":[0.621577045259304128,0.703084267292313,0.157658023953277215],"hpluv":[78.1766823729436737,298.614243514229941,87.1479139339873399],"hsluv":[78.1766823729436737,90.4569971269957449,87.1479139339873399]},"#eedd55":{"lch":[87.2644132886328,82.1887294441124823,77.7961103956051119],"luv":[87.2644132886328,17.3739699699556027,80.3313912186301],"rgb":[0.933333333333333348,0.866666666666666696,0.333333333333333315],"xyz":[0.627539459298666058,0.705469232908057742,0.189060071227251103],"hpluv":[77.7961103956051119,284.577035202400168,87.2644132886328],"hsluv":[77.7961103956051119,85.1762064326895114,87.2644132886328]},"#eedd66":{"lch":[87.4122373516825775,76.0722975624531,77.2543738936701],"luv":[87.4122373516825775,16.7832968217641607,74.1978126646801428],"rgb":[0.933333333333333348,0.866666666666666696,0.4],"xyz":[0.635124455072174299,0.70850323121746106,0.229007715634395093],"hpluv":[77.2543738936701,266.820521177772889,87.4122373516825775],"hsluv":[77.2543738936701,78.6319742502837187,87.4122373516825775]},"#eedd77":{"lch":[87.5931821049200323,68.7867162946957,76.4818073814204666],"luv":[87.5931821049200323,16.0791769624109904,66.8810317415814524],"rgb":[0.933333333333333348,0.866666666666666696,0.466666666666666674],"xyz":[0.644438468092376149,0.712228836425541911,0.278061517540793],"hpluv":[76.4818073814204666,245.153905791490757,87.5931821049200323],"hsluv":[76.4818073814204666,70.850552214552053,87.5931821049200323]},"#eedd88":{"lch":[87.8087818591101694,60.3863988515096,75.3563176494847],"luv":[87.8087818591101694,15.266108392374667,58.4248500280990655],"rgb":[0.933333333333333348,0.866666666666666696,0.533333333333333326],"xyz":[0.65557888519432006,0.716685003266319454,0.336734380944365141],"hpluv":[75.3563176494847,219.413652035392374,87.8087818591101694],"hsluv":[75.3563176494847,61.8928475378351,87.8087818591101694]},"#eedd99":{"lch":[88.0603378936253165,50.9615259485641658,73.6438422487017164],"luv":[88.0603378936253165,14.3511385044238935,48.8990996914362483],"rgb":[0.933333333333333348,0.866666666666666696,0.6],"xyz":[0.668635849303392704,0.721907788909948667,0.405501058585483076],"hpluv":[73.6438422487017164,189.463858183723431,88.0603378936253165],"hsluv":[73.6438422487017164,51.8496821371243328,88.0603378936253165]},"#eeddaa":{"lch":[88.3489381850503719,40.6474355343677374,70.8361013393810595],"luv":[88.3489381850503719,13.3433963411670824,38.3948927541556],"rgb":[0.933333333333333348,0.866666666666666696,0.66666666666666663],"xyz":[0.683693542268645316,0.727930866096049733,0.484804908202481677],"hpluv":[70.8361013393810595,155.230940371192503,88.3489381850503719],"hsluv":[70.8361013393810595,42.897511243529749,88.3489381850503719]},"#eeddbb":{"lch":[88.6754719765582422,29.6681200622416164,65.6052069824857256],"luv":[88.6754719765582422,12.2535763784239329,27.0193858917206811],"rgb":[0.933333333333333348,0.866666666666666696,0.733333333333333282],"xyz":[0.700831134375981879,0.734785902938984492,0.575062893301123368],"hpluv":[65.6052069824857256,116.881954111652547,88.6754719765582422],"hsluv":[65.6052069824857256,42.5880034653653823,88.6754719765582422]},"#eeddcc":{"lch":[89.0406413623298,18.5684245799280596,53.3136761054906927],"luv":[89.0406413623298,11.093403559257359,14.8903589228712931],"rgb":[0.933333333333333348,0.866666666666666696,0.8],"xyz":[0.720123509819703633,0.742502853116473349,0.676669403971393524],"hpluv":[53.3136761054906927,75.8171941810365837,89.0406413623298],"hsluv":[53.3136761054906927,42.1389745374101,89.0406413623298]},"#eedddd":{"lch":[89.4449712115231677,10.1024117660870978,12.1770506300652031],"luv":[89.4449712115231677,9.87511215198720294,2.13093488339032255],"rgb":[0.933333333333333348,0.866666666666666696,0.866666666666666696],"xyz":[0.741641835370337232,0.751110183336726855,0.789999251871399522],"hpluv":[12.1770506300652031,42.9711785560074802,89.4449712115231677],"hsluv":[12.1770506300652031,41.5103310668104939,89.4449712115231677]},"#eeddee":{"lch":[89.8888182614484919,14.0763196099440542,307.715012949260654],"luv":[89.8888182614484919,8.61096808409750203,-11.1352594229299271],"rgb":[0.933333333333333348,0.866666666666666696,0.933333333333333348],"xyz":[0.765454015636511942,0.760635055443196872,0.915410067939922745],"hpluv":[307.715012949260654,62.7286135322124423,89.8888182614484919],"hsluv":[307.715012949260654,40.6526002298302203,89.8888182614484919]},"#eeddff":{"lch":[90.3723799019863776,25.8444533047225526,286.436741223308786],"luv":[90.3723799019863776,7.31285770395748802,-24.7882609075678033],"rgb":[0.933333333333333348,0.866666666666666696,1],"xyz":[0.791625064046343363,0.771103474807129596,1.05324425623170459],"hpluv":[286.436741223308786,121.429851146909542,90.3723799019863776],"hsluv":[286.436741223308786,99.9999999999912461,90.3723799019863776]},"#776600":{"lch":[43.3967364031710616,48.7618731822316747,71.5665709091534836],"luv":[43.3967364031710616,15.4186312136361749,46.2599836547520695],"rgb":[0.466666666666666674,0.4,0],"xyz":[0.123587421414484214,0.134249841414458615,0.0194032630055357667],"hpluv":[71.5665709091534836,142.581321953300886,43.3967364031710616],"hsluv":[71.5665709091534836,100.000000000002203,43.3967364031710616]},"#776611":{"lch":[43.4563559440565683,46.5521225716425278,71.0105555334865812],"luv":[43.4563559440565683,15.1477793781447385,44.0186880294754204],"rgb":[0.466666666666666674,0.4,0.0666666666666666657],"xyz":[0.124599086914121332,0.134654507614313468,0.0247313679702914],"hpluv":[71.0105555334865812,135.933189968578517,43.4563559440565683],"hsluv":[71.0105555334865812,95.1446041192036,43.4563559440565683]},"#776622":{"lch":[43.5665595032511135,42.5748985848782695,69.8598868578742582],"luv":[43.5665595032511135,14.6592646006394602,39.9715892964128727],"rgb":[0.466666666666666674,0.4,0.133333333333333331],"xyz":[0.126474445052598361,0.135404650869704296,0.0346082541662705925],"hpluv":[69.8598868578742582,124.005139157578384,43.5665595032511135],"hsluv":[69.8598868578742582,86.4059851293991699,43.5665595032511135]},"#776633":{"lch":[43.7471247164395862,36.3538810550032,67.535659471968259],"luv":[43.7471247164395862,13.8911218179866047,33.5952586297408544],"rgb":[0.466666666666666674,0.4,0.2],"xyz":[0.129562195785056095,0.136639751162687395,0.0508704080238817358],"hpluv":[67.535659471968259,105.448545621014873,43.7471247164395862],"hsluv":[67.535659471968259,72.7162107178341,43.7471247164395862]},"#776644":{"lch":[44.0059094002531381,28.0798421405657628,62.7556004259007807],"luv":[44.0059094002531381,12.8545871201011757,24.9647175952547435],"rgb":[0.466666666666666674,0.4,0.266666666666666663],"xyz":[0.134020191029274982,0.138422949260375,0.0743491829767683743],"hpluv":[62.7556004259007807,80.969785387169,44.0059094002531381],"hsluv":[62.7556004259007807,54.3487361937933,44.0059094002531381]},"#776655":{"lch":[44.348573895236818,18.4503377813959695,51.0995937541716287],"luv":[44.348573895236818,11.5862323365157813,14.3587668165439446],"rgb":[0.466666666666666674,0.4,0.333333333333333315],"xyz":[0.139982605068636967,0.140807914876119822,0.10575123025074229],"hpluv":[51.0995937541716287,52.7914984191523473,44.348573895236818],"hsluv":[51.0995937541716287,32.0544530960382303,44.348573895236818]},"#776666":{"lch":[44.7789425039584543,10.3722772339139464,12.177050630063178],"luv":[44.7789425039584543,10.1389057710203723,2.18785849257654696],"rgb":[0.466666666666666674,0.4,0.4],"xyz":[0.147567600842145152,0.143841913185523113,0.145698874657886251],"hpluv":[12.177050630063178,29.3927086392471182,44.7789425039584543],"hsluv":[12.177050630063178,6.88762268030489189,44.7789425039584543]},"#776677":{"lch":[45.2992151274866899,14.0123007519981453,307.715012949251729],"luv":[45.2992151274866899,8.57180555029232849,-11.0846164558105222],"rgb":[0.466666666666666674,0.4,0.466666666666666674],"xyz":[0.156881613862347058,0.147567518393603936,0.194752676564284161],"hpluv":[307.715012949251729,39.2516664249610088,45.2992151274866899],"hsluv":[307.715012949251729,13.5798811229143528,45.2992151274866899]},"#776688":{"lch":[45.9101336093725934,25.9566305949561666,285.511882327844],"luv":[45.9101336093725934,6.94179491604529719,-25.0111606125461954],"rgb":[0.466666666666666674,0.4,0.533333333333333326],"xyz":[0.168022030964290886,0.152023685234381534,0.253425539967856328],"hpluv":[285.511882327844,71.7429261821633304,45.9101336093725934],"hsluv":[285.511882327844,20.4210179876919788,45.9101336093725934]},"#776699":{"lch":[46.6111419677041781,39.5636276789354753,277.694853057332239],"luv":[46.6111419677041781,5.29745753469698322,-39.2073663842078446],"rgb":[0.466666666666666674,0.4,0.6],"xyz":[0.181078995073363613,0.157246470878010691,0.322192217608974207],"hpluv":[277.694853057332239,107.707436484347127,46.6111419677041781],"hsluv":[277.694853057332239,30.3115853005661187,46.6111419677041781]},"#7766aa":{"lch":[47.4005539940279945,53.5010996637438936,273.94010537559177],"luv":[47.4005539940279945,3.67625443841083355,-53.3746458398921959],"rgb":[0.466666666666666674,0.4,0.66666666666666663],"xyz":[0.196136688038616142,0.163269548064111786,0.401496067225972808],"hpluv":[273.94010537559177,143.224929654224553,47.4005539940279945],"hsluv":[273.94010537559177,41.7476492103462178,47.4005539940279945]},"#7766bb":{"lch":[48.2757296522395052,67.3356727079262356,271.790784098674919],"luv":[48.2757296522395052,2.10423911354751,-67.3027859511178],"rgb":[0.466666666666666674,0.4,0.733333333333333282],"xyz":[0.213274280145952788,0.170124584907046544,0.491754052324614555],"hpluv":[271.790784098674919,176.992833999799871,48.2757296522395052],"hsluv":[271.790784098674919,53.26174830093764,48.2757296522395052]},"#7766cc":{"lch":[49.2332558923506838,80.8618894300095263,270.423298283194697],"luv":[49.2332558923506838,0.597398061184884921,-80.8596826468393886],"rgb":[0.466666666666666674,0.4,0.8],"xyz":[0.232566655589674542,0.177841535084535346,0.59336056299488471],"hpluv":[270.423298283194697,208.412927467485218,49.2332558923506838],"hsluv":[270.423298283194697,64.812294986267446,49.2332558923506838]},"#7766dd":{"lch":[50.2691251722936698,93.9789905273776327,269.490145829531343],"luv":[50.2691251722936698,-0.836273601566472236,-93.9752696564806769],"rgb":[0.466666666666666674,0.4,0.866666666666666696],"xyz":[0.254084981140308086,0.18644886530478888,0.706690410894890708],"hpluv":[269.490145829531343,237.229544488008315,50.2691251722936698],"hsluv":[269.490145829531343,76.411365903071939,50.2691251722936698]},"#7766ee":{"lch":[51.378904811117593,106.647241299318011,268.82087794331261],"luv":[51.378904811117593,-2.19459861633770803,-106.624658562961542],"rgb":[0.466666666666666674,0.4,0.933333333333333348],"xyz":[0.277897161406482796,0.195973737411258925,0.832101226963413931],"hpluv":[268.82087794331261,263.392927722023558,51.378904811117593],"hsluv":[268.82087794331261,88.1124589032604177,51.378904811117593]},"#7766ff":{"lch":[52.5578914047646748,118.864223743766644,268.322642340607558],"luv":[52.5578914047646748,-3.47930230784918848,-118.81329109850806],"rgb":[0.466666666666666674,0.4,1],"xyz":[0.304068209816314217,0.206442156775191621,0.969935415255195776],"hpluv":[268.322642340607558,286.980608281330717,52.5578914047646748],"hsluv":[268.322642340607558,99.9999999999990621,52.5578914047646748]},"#eeee00":{"lch":[91.3819857871042416,100.73955854358779,85.8743202181747591],"luv":[91.3819857871042416,7.24765584469138,100.478505862268193],"rgb":[0.933333333333333348,0.933333333333333348,0],"xyz":[0.658323051985028163,0.793268712127427555,0.118438362762215782],"hpluv":[85.8743202181747591,533.074105620447313,91.3819857871042416],"hsluv":[85.8743202181747591,100.000000000002302,91.3819857871042416]},"#eeee11":{"lch":[91.4002420948697,99.9206079899190485,85.8743202181747449],"luv":[91.4002420948697,7.18873686735402107,99.6616775060856526],"rgb":[0.933333333333333348,0.933333333333333348,0.0666666666666666657],"xyz":[0.659334717484665322,0.793673378327282464,0.123766467726971419],"hpluv":[85.8743202181747449,529.940172906192515,91.4002420948697],"hsluv":[85.8743202181747449,99.1672499526241182,91.4002420948697]},"#eeee22":{"lch":[91.4340680155716,98.4094794247264559,85.8743202181747],"luv":[91.4340680155716,7.08001949817026599,98.1544648222952105],"rgb":[0.933333333333333348,0.933333333333333348,0.133333333333333331],"xyz":[0.661210075623142268,0.794423521582673264,0.133643353922950597],"hpluv":[85.8743202181747,524.128135432551403,91.4340680155716],"hsluv":[85.8743202181747,97.631382664670781,91.4340680155716]},"#eeee33":{"lch":[91.4897155548310224,95.9410009888260475,85.874320218174617],"luv":[91.4897155548310224,6.90242608380469225,95.6923831080380864],"rgb":[0.933333333333333348,0.933333333333333348,0.2],"xyz":[0.664297826355600085,0.795658621875656391,0.149905507780561748],"hpluv":[85.874320218174617,514.550466890897383,91.4897155548310224],"hsluv":[85.874320218174617,95.1245282264191,91.4897155548310224]},"#eeee44":{"lch":[91.569956182858661,92.4193611961338917,85.8743202181745],"luv":[91.569956182858661,6.64906351605686385,92.1798691594911],"rgb":[0.933333333333333348,0.933333333333333348,0.266666666666666663],"xyz":[0.668755821599819,0.797441819973344,0.173384282733448386],"hpluv":[85.8743202181745,500.701064757674544,91.569956182858661],"hsluv":[85.8743202181745,91.5525623856835438,91.569956182858661]},"#eeee55":{"lch":[91.6770884747666912,87.7855710128071536,85.8743202181743612],"luv":[91.6770884747666912,6.31568785915728625,87.5580868047623682],"rgb":[0.933333333333333348,0.933333333333333348,0.333333333333333315],"xyz":[0.674718235639180874,0.799826785589088707,0.204786330007422301],"hpluv":[85.8743202181743612,482.129233036801622,91.6770884747666912],"hsluv":[85.8743202181743612,86.8606098102410584,91.6770884747666912]},"#eeee66":{"lch":[91.8130678710263197,82.0131153940214261,85.8743202181741481],"luv":[91.8130678710263197,5.90039150181238092,81.8005897091115912],"rgb":[0.933333333333333348,0.933333333333333348,0.4],"xyz":[0.682303231412689115,0.802860783898492,0.244733974414566263],"hpluv":[85.8743202181741481,458.402522986492727,91.8130678710263197],"hsluv":[85.8743202181741481,81.0287908474737435,91.8130678710263197]},"#eeee77":{"lch":[91.9795762822891163,75.1051560234190703,85.8743202181738923],"luv":[91.9795762822891163,5.40340190972927914,74.9105313631138],"rgb":[0.933333333333333348,0.933333333333333348,0.466666666666666674],"xyz":[0.691617244432891,0.806586389106572876,0.2937877763209642],"hpluv":[85.8743202181738923,429.072804464814112,91.9795762822891163],"hsluv":[85.8743202181738923,74.0694118243717838,91.9795762822891163]},"#eeee88":{"lch":[92.1780636375363542,67.0918310376028444,85.8743202181734233],"luv":[92.1780636375363542,4.82688735568056,66.9179718045445497],"rgb":[0.933333333333333348,0.933333333333333348,0.533333333333333326],"xyz":[0.702757661534834877,0.811042555947350419,0.35246063972453634],"hpluv":[85.8743202181734233,393.637417052406249,92.1780636375363542],"hsluv":[85.8743202181734233,66.0241185279663085,92.1780636375363542]},"#eeee99":{"lch":[92.4097746137617264,58.0271343519240759,85.8743202181728549],"luv":[92.4097746137617264,4.17473240419888647,57.8767650309654],"rgb":[0.933333333333333348,0.933333333333333348,0.6],"xyz":[0.715814625643907521,0.816265341590979632,0.421227317365654219],"hpluv":[85.8743202181728549,351.489405737917593,92.4097746137617264],"hsluv":[85.8743202181728549,56.9604957584853295,92.4097746137617264]},"#eeeeaa":{"lch":[92.6757669457712,47.9852530272659195,85.8743202181718885],"luv":[92.6757669457712,3.45227440531043239,47.8609058577161903],"rgb":[0.933333333333333348,0.933333333333333348,0.66666666666666663],"xyz":[0.730872318609160132,0.822288418777080699,0.500531166982652875],"hpluv":[85.8743202181718885,301.850049763156903,92.6757669457712],"hsluv":[85.8743202181718885,46.9680087594427178,92.6757669457712]},"#eeeebb":{"lch":[92.9769247593952741,37.0564456712956627,85.8743202181703253],"luv":[92.9769247593952741,2.66600696822725,36.9604189997225347],"rgb":[0.933333333333333348,0.933333333333333348,0.733333333333333282],"xyz":[0.748009910716496695,0.829143455620015457,0.590789152081294566],"hpluv":[85.8743202181703253,243.673832720465015,92.9769247593952741],"hsluv":[85.8743202181703253,36.1533987495139,92.9769247593952741]},"#eeeecc":{"lch":[93.3139689281547788,25.3426537884513579,85.8743202181670711],"luv":[93.3139689281547788,1.82326422217474082,25.2769817940640493],"rgb":[0.933333333333333348,0.933333333333333348,0.8],"xyz":[0.76730228616021845,0.836860405797504314,0.692395662751564722],"hpluv":[85.8743202181670711,175.509740066336235,93.3139689281547788],"hsluv":[85.8743202181670711,24.635760697738192,93.3139689281547788]},"#eeeedd":{"lch":[93.6874656794852143,12.9530841337210045,85.8743202181571377],"luv":[93.6874656794852143,0.931902991100789779,12.919518001474831],"rgb":[0.933333333333333348,0.933333333333333348,0.866666666666666696],"xyz":[0.788820611710852,0.84546773601775782,0.80572551065157072],"hpluv":[85.8743202181571377,95.2907564198152812,93.6874656794852143],"hsluv":[85.8743202181571377,12.5415797244653469,93.6874656794852143]},"#eeeeee":{"lch":[94.0978342288501466,4.90671076366048496e-12,0],"luv":[94.0978342288501466,4.6515081442594671e-12,1.56182025281704723e-12],"rgb":[0.933333333333333348,0.933333333333333348,0.933333333333333348],"xyz":[0.812632791977026758,0.854992608124227838,0.931136326720093943],"hpluv":[0,3.87295813278393312e-11,94.0978342288501466],"hsluv":[0,3.8714510065860851e-11,94.0978342288501466]},"#eeeeff":{"lch":[94.5453539438838391,13.4050739145486393,265.874320218197],"luv":[94.5453539438838391,-0.964421163933715353,-13.3703365130825738],"rgb":[0.933333333333333348,0.933333333333333348,1],"xyz":[0.838803840386858179,0.865461027488160561,1.06897051501187579],"hpluv":[265.874320218197,114.885858328026472,94.5453539438838391],"hsluv":[265.874320218197,99.999999999981938,94.5453539438838391]},"#777700":{"lch":[48.4055282063088868,53.3622847060179737,85.8743202181747],"luv":[48.4055282063088868,3.83912219020021839,53.2240036999738706],"rgb":[0.466666666666666674,0.466666666666666674,0],"xyz":[0.142041159467901856,0.171157317521294372,0.0255545090233414707],"hpluv":[85.8743202181747,139.887458074797621,48.4055282063088868],"hsluv":[85.8743202181747,100.000000000002331,48.4055282063088868]},"#777711":{"lch":[48.4562461221814829,51.3697569370731628,85.874320218174617],"luv":[48.4562461221814829,3.69577080233359201,51.2366392921178502],"rgb":[0.466666666666666674,0.466666666666666674,0.0666666666666666657],"xyz":[0.143052824967539,0.171561983721149225,0.0308826139880971],"hpluv":[85.874320218174617,134.523163178361983,48.4562461221814829],"hsluv":[85.874320218174617,96.1652781669932324,48.4562461221814829]},"#777722":{"lch":[48.5500530694338579,47.7524066126053768,85.8743202181744323],"luv":[48.5500530694338579,3.43552238949120969,47.6286628324468282],"rgb":[0.466666666666666674,0.466666666666666674,0.133333333333333331],"xyz":[0.144928183106016,0.172312126976540053,0.0407595001840763],"hpluv":[85.8743202181744323,124.808706278838557,48.5500530694338579],"hsluv":[85.8743202181744323,89.2207979160694293,48.5500530694338579]},"#777733":{"lch":[48.7039135074563063,42.0024110114446501,85.874320218174],"luv":[48.7039135074563063,3.02184190658892726,41.8935675523809934],"rgb":[0.466666666666666674,0.466666666666666674,0.2],"xyz":[0.148015933838473723,0.173547227269523152,0.0570216540416874432],"hpluv":[85.874320218174,109.433348296247431,48.7039135074563063],"hsluv":[85.874320218174,78.2295638238963704,48.7039135074563063]},"#777744":{"lch":[48.9247697387985312,34.1210359912247227,85.8743202181732528],"luv":[48.9247697387985312,2.45482042510454956,34.0326160292585],"rgb":[0.466666666666666674,0.466666666666666674,0.266666666666666663],"xyz":[0.152473929082692611,0.175330425367210746,0.0805004289945740747],"hpluv":[85.8743202181732528,88.497855114462908,48.9247697387985312],"hsluv":[85.8743202181732528,63.2636094274766378,48.9247697387985312]},"#777755":{"lch":[49.2178287935421537,24.2815247917763841,85.8743202181716327],"luv":[49.2178287935421537,1.74692184102758041,24.2186025669317253],"rgb":[0.466666666666666674,0.466666666666666674,0.333333333333333315],"xyz":[0.158436343122054624,0.177715390982955579,0.11190247626854799],"hpluv":[85.8743202181716327,62.6026663147617,49.2178287935421537],"hsluv":[85.8743202181716327,44.7521651878825324,49.2178287935421537]},"#777766":{"lch":[49.5868745078829676,12.7836483150604128,85.8743202181664742],"luv":[49.5868745078829676,0.919713018071489197,12.750521252385596],"rgb":[0.466666666666666674,0.466666666666666674,0.4],"xyz":[0.166021338895562781,0.18074938929235887,0.151850120675691952],"hpluv":[85.8743202181664742,32.7135296885410085,49.5868745078829676],"hsluv":[85.8743202181664742,23.385605928338574,49.5868745078829676]},"#777777":{"lch":[50.0344387925380687,2.67192546523751356e-12,0],"luv":[50.0344387925380687,2.52749706171116152e-12,8.66570421158112546e-13],"rgb":[0.466666666666666674,0.466666666666666674,0.466666666666666674],"xyz":[0.175335351915764714,0.184474994500439693,0.200903922582089861],"hpluv":[0,6.77633132918180515e-12,50.0344387925380687],"hsluv":[0,1.94020402484744743e-12,50.0344387925380687]},"#777788":{"lch":[50.5619220099523545,13.6772258441596737,265.874320218187563],"luv":[50.5619220099523545,-0.984000994856362388,-13.6417831984777926],"rgb":[0.466666666666666674,0.466666666666666674,0.533333333333333326],"xyz":[0.186475769017708515,0.188931161341217291,0.259576785985662029],"hpluv":[265.874320218187563,34.3252548472133,50.5619220099523545],"hsluv":[265.874320218187563,11.1797639211738336,50.5619220099523545]},"#777799":{"lch":[51.1696982290560669,27.8798810968622455,265.87432021818239],"luv":[51.1696982290560669,-2.00580373888746255,-27.8076342276045096],"rgb":[0.466666666666666674,0.466666666666666674,0.6],"xyz":[0.199532733126781242,0.194153946984846448,0.328343463626779908],"hpluv":[265.87432021818239,69.1380916549642563,51.1696982290560669],"hsluv":[265.87432021818239,22.9846011782403536,51.1696982290560669]},"#7777aa":{"lch":[51.8572203345112,42.2927406525888614,265.874320218180628],"luv":[51.8572203345112,-3.04272952363285398,-42.1831448442758443],"rgb":[0.466666666666666674,0.466666666666666674,0.66666666666666663],"xyz":[0.21459042609203377,0.200177024170947543,0.407647313243778564],"hpluv":[265.874320218180628,103.489412577951782,51.8572203345112],"hsluv":[265.874320218180628,35.2207148819814435,51.8572203345112]},"#7777bb":{"lch":[52.6231302285762439,56.6671214785474,265.874320218179832],"luv":[52.6231302285762439,-4.07688697591046,-56.5202764435038816],"rgb":[0.466666666666666674,0.466666666666666674,0.733333333333333282],"xyz":[0.231728018199370445,0.207032061013882301,0.497905298342420255],"hpluv":[265.874320218179832,136.645017565491173,52.6231302285762439],"hsluv":[265.874320218179832,47.751077300634,52.6231302285762439]},"#7777cc":{"lch":[53.4653742998309696,70.8221320427834513,265.874320218179378],"luv":[53.4653742998309696,-5.09526194727884452,-70.6386062488075],"rgb":[0.466666666666666674,0.466666666666666674,0.8],"xyz":[0.251020393643092143,0.214749011191371103,0.599511809012690411],"hpluv":[265.874320218179378,168.087613695837888,53.4653742998309696],"hsluv":[265.874320218179378,60.4968982098403671,53.4653742998309696]},"#7777dd":{"lch":[54.3813217092404102,84.6378263199215581,265.874320218179037],"luv":[54.3813217092404102,-6.08922498249284594,-84.4184990584042083],"rgb":[0.466666666666666674,0.466666666666666674,0.866666666666666696],"xyz":[0.272538719193725743,0.223356341411624637,0.712841656912696409],"hpluv":[265.874320218179037,197.494074150637061,54.3813217092404102],"hsluv":[265.874320218179037,73.4330970128385445,54.3813217092404102]},"#7777ee":{"lch":[55.3678819060931,98.0443353361264656,265.874320218178809],"luv":[55.3678819060931,-7.05374939408338086,-97.7902669542745713],"rgb":[0.466666666666666674,0.466666666666666674,0.933333333333333348],"xyz":[0.296350899459900452,0.232881213518094682,0.838252472981219632],"hpluv":[265.874320218178809,224.700440227144242,55.3678819060931],"hsluv":[265.874320218178809,86.5809092876847,55.3678819060931]},"#7777ff":{"lch":[56.4216176153771158,111.010032393554411,265.874320218178696],"luv":[56.4216176153771158,-7.98655981550332,-110.722365194803288],"rgb":[0.466666666666666674,0.466666666666666674,1],"xyz":[0.322521947869731873,0.243349632882027378,0.976086661273001477],"hpluv":[265.874320218178696,249.664056525023511,56.4216176153771158],"hsluv":[265.874320218178696,99.99999999999892,56.4216176153771158]},"#eeff00":{"lch":[95.8710857598618702,106.837421111995667,91.929871543819857],"luv":[95.8710857598618702,-3.59788306357601462,106.776822332015158],"rgb":[0.933333333333333348,1,0],"xyz":[0.710175424414702,0.896973456986776663,0.135722486905439893],"hpluv":[91.929871543819857,1221.941869030823,95.8710857598618702],"hsluv":[91.929871543819857,100.000000000002217,95.8710857598618702]},"#eeff11":{"lch":[95.8879066370154192,106.077593073364397,91.9648080695471748],"luv":[95.8879066370154192,-3.63693915095535747,106.015227330089402],"rgb":[0.933333333333333348,1,0.0666666666666666657],"xyz":[0.71118708991433921,0.897378123186631571,0.14105059187019553],"hpluv":[91.9648080695471748,1218.36968740939687,95.8879066370154192],"hsluv":[91.9648080695471748,99.9999999999846096,95.8879066370154192]},"#eeff22":{"lch":[95.9190746883988083,104.674935415410417,92.0306447189025221],"luv":[95.9190746883988083,-3.7090534526558554,104.609201443781629],"rgb":[0.933333333333333348,1,0.133333333333333331],"xyz":[0.713062448052816156,0.898128266442022372,0.150927478066174708],"hpluv":[92.0306447189025221,1211.72771901411761,95.9190746883988083],"hsluv":[92.0306447189025221,99.9999999999843254,95.9190746883988083]},"#eeff33":{"lch":[95.9703546560603,102.38192729680722,92.1421884898051076],"luv":[95.9703546560603,-3.826988551916231,102.31037677397255],"rgb":[0.933333333333333348,1,0.2],"xyz":[0.716150198785274,0.899363366735005498,0.167189631923785859],"hpluv":[92.1421884898051076,1200.73225066318059,95.9703546560603],"hsluv":[92.1421884898051076,99.9999999999843,95.9703546560603]},"#eeff44":{"lch":[96.0443082677326316,99.1069805797193482,92.3105231291127666],"luv":[96.0443082677326316,-3.99552836231266495,99.0264073504377],"rgb":[0.933333333333333348,1,0.266666666666666663],"xyz":[0.720608194029492832,0.901146564832693064,0.190668406876672497],"hpluv":[92.3105231291127666,1184.71704479359755,96.0443082677326316],"hsluv":[92.3105231291127666,99.999999999984,96.0443082677326316]},"#eeff55":{"lch":[96.1430663154878,94.7914212488158086,92.5502587525383831],"luv":[96.1430663154878,-4.21781218752730513,94.6975374691506744],"rgb":[0.933333333333333348,1,0.333333333333333315],"xyz":[0.726570608068854762,0.903531530448437814,0.222070454150646412],"hpluv":[92.5502587525383831,1163.01160371768833,96.1430663154878],"hsluv":[92.5502587525383831,99.9999999999832312,96.1430663154878]},"#eeff66":{"lch":[96.2684490440968261,89.4056432425818315,92.8821944044194083],"luv":[96.2684490440968261,-4.49554545672610839,89.2925479234763912],"rgb":[0.933333333333333348,1,0.4],"xyz":[0.734155603842363,0.906565528757841133,0.262018098557790347],"hpluv":[92.8821944044194083,1134.86447310352946,96.2684490440968261],"hsluv":[92.8821944044194083,99.9999999999826912,96.2684490440968261]},"#eeff77":{"lch":[96.4220309754045104,82.947030730659,93.3376121292550494],"luv":[96.4220309754045104,-4.82912482473711879,82.8063370791148827],"rgb":[0.933333333333333348,1,0.466666666666666674],"xyz":[0.743469616862564853,0.910291133965922,0.311071900464188311],"hpluv":[93.3376121292550494,1099.34916045901696,96.4220309754045104],"hsluv":[93.3376121292550494,99.9999999999824354,96.4220309754045104]},"#eeff88":{"lch":[96.6051797330544559,75.4384320618763553,93.966065888554354],"luv":[96.6051797330544559,-5.21774760700183382,75.2577713054536446],"rgb":[0.933333333333333348,1,0.533333333333333326],"xyz":[0.754610033964508764,0.914747300806699526,0.369744763867760451],"hpluv":[93.966065888554354,1055.22684316018899,96.6051797330544559],"hsluv":[93.966065888554354,99.9999999999810711,96.6051797330544559]},"#eeff99":{"lch":[96.8190810543072,66.9270103141668926,94.8508818247366],"luv":[96.8190810543072,-5.65953211211599072,66.6872881879637589],"rgb":[0.933333333333333348,1,0.6],"xyz":[0.767666998073581408,0.919970086450328739,0.43851144150887833],"hpluv":[94.8508818247366,1000.72847038880911,96.8190810543072],"hsluv":[94.8508818247366,99.9999999999804,96.8190810543072]},"#eeffaa":{"lch":[97.0647558759300182,57.4841926777339438,96.1432585072641785],"luv":[97.0647558759300182,-6.15165762861061438,57.1540857352402938],"rgb":[0.933333333333333348,1,0.66666666666666663],"xyz":[0.782724691038834,0.925993163636429806,0.517815291125877],"hpluv":[96.1432585072641785,933.191048721381,97.0647558759300182],"hsluv":[96.1432585072641785,99.9999999999786127,97.0647558759300182]},"#eeffbb":{"lch":[97.3430726615411857,47.2094061136043166,98.1473956779809242],"luv":[97.3430726615411857,-6.69052372550339935,46.7329104366258861],"rgb":[0.933333333333333348,1,0.733333333333333282],"xyz":[0.799862283146170583,0.932848200479364564,0.608073276224518677],"hpluv":[98.1473956779809242,848.432918810296883,97.3430726615411857],"hsluv":[98.1473956779809242,99.9999999999760689,97.3430726615411857]},"#eeffcc":{"lch":[97.6547568121604,36.2474903433398126,101.573139749476653],"luv":[97.6547568121604,-7.27192346215819718,35.5105573787715443],"rgb":[0.933333333333333348,1,0.8],"xyz":[0.819154658589892337,0.940565150656853421,0.709679786894788833],"hpluv":[101.573139749476653,739.717147432346792,97.6547568121604],"hsluv":[101.573139749476653,99.999999999972971,97.6547568121604]},"#eeffdd":{"lch":[98.0003982932414743,24.8675243497069864,108.50155795297276],"luv":[98.0003982932414743,-7.89122250686935445,23.5822470225029335],"rgb":[0.933333333333333348,1,0.866666666666666696],"xyz":[0.840672984140525936,0.949172480877106928,0.823009634794794831],"hpluv":[108.50155795297276,596.728870831386416,98.0003982932414743],"hsluv":[108.50155795297276,99.9999999999688072,98.0003982932414743]},"#eeffee":{"lch":[98.3804582036479,13.96608756186059,127.715012949221688],"luv":[98.3804582036479,-8.54353535492541205,11.0480588984987129],"rgb":[0.933333333333333348,1,0.933333333333333348],"xyz":[0.864485164406700646,0.958697352983577,0.948420450863318],"hpluv":[127.715012949221688,414.943064796341446,98.3804582036479],"hsluv":[127.715012949221688,99.9999999999608491,98.3804582036479]},"#eeffff":{"lch":[98.7952747621608438,9.43620053547767768,192.177050630058204],"luv":[98.7952747621608438,-9.22389036737693679,-1.99040876112424892],"rgb":[0.933333333333333348,1,1],"xyz":[0.890656212816532067,0.969165772347509669,1.0862546391551],"hpluv":[192.177050630058204,378.040319927501173,98.7952747621608438],"hsluv":[192.177050630058204,99.999999999948713,98.7952747621608438]},"#778800":{"lch":[53.5249548615687303,60.5938372915660253,96.5029793655947259],"luv":[53.5249548615687303,-6.86254771619202231,60.2039745910497572],"rgb":[0.466666666666666674,0.533333333333333326,0],"xyz":[0.164113529192872309,0.215302056971235917,0.0329119655983314136],"hpluv":[96.5029793655947259,143.651932639250902,53.5249548615687303],"hsluv":[96.5029793655947259,100.000000000002373,53.5249548615687303]},"#778811":{"lch":[53.5684856288310272,58.8481082257442409,96.7583563096261088],"luv":[53.5684856288310272,-6.9253766303469888,58.4391906196240143],"rgb":[0.466666666666666674,0.533333333333333326,0.0666666666666666657],"xyz":[0.165125194692509442,0.21570672317109077,0.0382400705630870433],"hpluv":[96.7583563096261088,139.399900460742,53.5684856288310272],"hsluv":[96.7583563096261088,96.9357421545617,53.5684856288310272]},"#778822":{"lch":[53.6490362820541407,55.6690512282284615,97.2652817371477],"luv":[53.6490362820541407,-7.04010577997538,55.2220986133077147],"rgb":[0.466666666666666674,0.533333333333333326,0.133333333333333331],"xyz":[0.167000552830986443,0.216456866426481598,0.0481169567590662428],"hpluv":[97.2652817371477,131.671329649176641,53.6490362820541407],"hsluv":[97.2652817371477,91.3605066517003337,53.6490362820541407]},"#778833":{"lch":[53.7812573057213,50.5917713326567053,98.2096275165039856],"luv":[53.7812573057213,-7.22426441450666346,50.0733195448945381],"rgb":[0.466666666666666674,0.533333333333333326,0.2],"xyz":[0.170088303563444176,0.217691966719464697,0.064379110616677393],"hpluv":[98.2096275165039856,119.368094402160139,53.7812573057213],"hsluv":[98.2096275165039856,82.4672262716137539,53.7812573057213]},"#778844":{"lch":[53.9712743947247162,43.5928841845235198,99.8805739619221811],"luv":[53.9712743947247162,-7.48032491712259429,42.9462954241638357],"rgb":[0.466666666666666674,0.533333333333333326,0.266666666666666663],"xyz":[0.174546298807663064,0.219475164817152291,0.0878578855695640315],"hpluv":[99.8805739619221811,102.492540276722124,53.9712743947247162],"hsluv":[99.8805739619221811,70.2195807792145672,53.9712743947247162]},"#778855":{"lch":[54.2238135722873,34.8221097745323078,102.954066597198249],"luv":[54.2238135722873,-7.80606678579386326,33.9358903004666175],"rgb":[0.466666666666666674,0.533333333333333326,0.333333333333333315],"xyz":[0.180508712847025077,0.221860130432897124,0.119259932843537933],"hpluv":[102.954066597198249,81.4900057495692636,54.2238135722873],"hsluv":[102.954066597198249,54.8454134878709638,54.2238135722873]},"#778866":{"lch":[54.542475349788262,24.6519214642532667,109.417534351990682],"luv":[54.542475349788262,-8.19552569001744224,23.2497438812554442],"rgb":[0.466666666666666674,0.533333333333333326,0.4],"xyz":[0.188093708620533234,0.224894128742300414,0.159207577250681909],"hpluv":[109.417534351990682,57.3528835536874197,54.542475349788262],"hsluv":[109.417534351990682,36.7830408334215164,54.542475349788262]},"#778877":{"lch":[54.9298804020046703,14.1239929232838151,127.715012949231166],"luv":[54.9298804020046703,-8.6401314869560828,11.1729720300858784],"rgb":[0.466666666666666674,0.533333333333333326,0.466666666666666674],"xyz":[0.197407721640735168,0.228619733950381238,0.208261379157079818],"hpluv":[127.715012949231166,32.6278280107521041,54.9298804020046703],"hsluv":[127.715012949231166,16.6133799052879709,54.9298804020046703]},"#778888":{"lch":[55.3877640712208574,9.3400800844087577,192.177050630059369],"luv":[55.3877640712208574,-9.12993258220805437,-1.97013375878514596],"rgb":[0.466666666666666674,0.533333333333333326,0.533333333333333326],"xyz":[0.208548138742678968,0.233075900791158835,0.266934242560651958],"hpluv":[192.177050630059369,21.3981433643613,55.3877640712208574],"hsluv":[192.177050630059369,21.3143847536295468,55.3877640712208574]},"#778899":{"lch":[55.9170512374386703,18.5603965019494623,238.655736169794807],"luv":[55.9170512374386703,-9.65472976501325597,-15.851640655596027],"rgb":[0.466666666666666674,0.533333333333333326,0.6],"xyz":[0.221605102851751695,0.238298686434788,0.335700920201769892],"hpluv":[238.655736169794807,42.1194135101242679,55.9170512374386703],"hsluv":[238.655736169794807,26.1912729818073053,55.9170512374386703]},"#7788aa":{"lch":[56.5179258756863732,31.8473117719276075,251.310804784322386],"luv":[56.5179258756863732,-10.2049729927717898,-30.1680260095876527],"rgb":[0.466666666666666674,0.533333333333333326,0.66666666666666663],"xyz":[0.236662795817004223,0.244321763620889087,0.415004769818768493],"hpluv":[251.310804784322386,71.5032678590983721,56.5179258756863732],"hsluv":[251.310804784322386,31.1149405392867244,56.5179258756863732]},"#7788bb":{"lch":[57.1899017055338845,45.9393215269311881,256.438388794294667],"luv":[57.1899017055338845,-10.7723499078102041,-44.6584565319768387],"rgb":[0.466666666666666674,0.533333333333333326,0.733333333333333282],"xyz":[0.253800387924340898,0.251176800463823846,0.505262754917410239],"hpluv":[256.438388794294667,101.930593576715296,57.1899017055338845],"hsluv":[256.438388794294667,41.4357647235180622,57.1899017055338845]},"#7788cc":{"lch":[57.9318961804226547,60.1932243037694406,259.131204763586595],"luv":[57.9318961804226547,-11.3500713849249486,-59.1134513595764233],"rgb":[0.466666666666666674,0.533333333333333326,0.8],"xyz":[0.273092763368062652,0.258893750641312648,0.606869265587680395],"hpluv":[259.131204763586595,131.8466774878151,57.9318961804226547],"hsluv":[259.131204763586595,55.5026255722761661,57.9318961804226547]},"#7788dd":{"lch":[58.7423077351926679,74.3397271130694861,260.762999043897821],"luv":[58.7423077351926679,-11.9329115646152975,-73.3757497327060264],"rgb":[0.466666666666666674,0.533333333333333326,0.866666666666666696],"xyz":[0.29461108891869614,0.267501080861566209,0.720199113487686393],"hpluv":[260.762999043897821,160.586593274196787,58.7423077351926679],"hsluv":[260.762999043897821,69.9489143241080598,58.7423077351926679]},"#7788ee":{"lch":[59.6190949291064101,88.2283098571320465,261.84384456781811],"luv":[59.6190949291064101,-12.5170812067924775,-87.3358880318318285],"rgb":[0.466666666666666674,0.533333333333333326,0.933333333333333348],"xyz":[0.318423269184870905,0.277025952968036226,0.845609929556209616],"hpluv":[261.84384456781811,187.785436290663455,59.6190949291064101],"hsluv":[261.84384456781811,84.7689484415743237,59.6190949291064101]},"#7788ff":{"lch":[60.55985551741054,101.77153783075579,262.604380260147],"luv":[60.55985551741054,-13.1000102630052879,-100.924901008354297],"rgb":[0.466666666666666674,0.533333333333333326,1],"xyz":[0.344594317594702271,0.28749437233196895,0.983444117847991461],"hpluv":[262.604380260147,213.245970352856943,60.55985551741054],"hsluv":[262.604380260147,99.9999999999987921,60.55985551741054]},"#779900":{"lch":[58.6994568897504223,69.1976359459353603,103.993850276975294],"luv":[58.6994568897504223,-16.7332165977800322,67.1439668384135899],"rgb":[0.466666666666666674,0.6,0],"xyz":[0.189983129645339782,0.267041257876171612,0.0415351657491536685],"hpluv":[103.993850276975294,149.587912305351722,58.6994568897504223],"hsluv":[103.993850276975294,100.000000000002444,58.6994568897504223]},"#779911":{"lch":[58.7371702745588493,67.6759907780605232,104.326162498332039],"luv":[58.7371702745588493,-16.7458460058928829,65.5714600214076],"rgb":[0.466666666666666674,0.6,0.0666666666666666657],"xyz":[0.190994795144976914,0.267445924076026464,0.0468632707139093],"hpluv":[104.326162498332039,146.20456366036808,58.7371702745588493],"hsluv":[104.326162498332039,97.5197891999702,58.7371702745588493]},"#779922":{"lch":[58.8069803361006223,64.8997387816913,104.97431376012679],"luv":[58.8069803361006223,-16.7691829588827659,62.6958578920751464],"rgb":[0.466666666666666674,0.6,0.133333333333333331],"xyz":[0.192870153283453916,0.268196067331417265,0.0567401569098885],"hpluv":[104.97431376012679,140.04041716275114,58.8069803361006223],"hsluv":[104.97431376012679,92.9911396041894704,58.8069803361006223]},"#779933":{"lch":[58.9216385591388132,60.4528100001228097,106.14237332279157],"luv":[58.9216385591388132,-16.8074000849803582,58.0693855598141369],"rgb":[0.466666666666666674,0.6,0.2],"xyz":[0.195957904015911677,0.269431167624400392,0.0730023107674996341],"hpluv":[106.14237332279157,130.191012221085145,58.9216385591388132],"hsluv":[106.14237332279157,85.724115661044948,58.9216385591388132]},"#779944":{"lch":[59.0865618982540752,54.3006768161790845,108.091337704968765],"luv":[59.0865618982540752,-16.8621369683366211,51.6161974534756354],"rgb":[0.466666666666666674,0.6,0.266666666666666663],"xyz":[0.200415899260130537,0.271214365722087958,0.0964810857203862726],"hpluv":[108.091337704968765,116.615384645059635,59.0865618982540752],"hsluv":[108.091337704968765,75.6282332091309399,59.0865618982540752]},"#779955":{"lch":[59.3060149965037056,46.5647823410072945,111.326222899357617],"luv":[59.3060149965037056,-16.9345685221747893,43.3762532203180413],"rgb":[0.466666666666666674,0.6,0.333333333333333315],"xyz":[0.206378313299492522,0.273599331337832818,0.127883132994360188],"hpluv":[111.326222899357617,99.6318422422000367,59.3060149965037056],"hsluv":[111.326222899357617,62.8087826319283806,59.3060149965037056]},"#779966":{"lch":[59.5833535636433282,37.5662597340720836,116.949978591108717],"luv":[59.5833535636433282,-17.0254963867212936,33.4866591823296957],"rgb":[0.466666666666666674,0.6,0.4],"xyz":[0.213963309073000707,0.276633329647236137,0.16783077740150415],"hpluv":[116.949978591108717,80.0041177209304522,59.5833535636433282],"hsluv":[116.949978591108717,47.5357009492008,59.5833535636433282]},"#779977":{"lch":[59.921152065724,28.0111989307655129,127.71501294923614],"luv":[59.921152065724,-17.1354122862910181,22.1586306282167591],"rgb":[0.466666666666666674,0.6,0.466666666666666674],"xyz":[0.223277322093202613,0.280358934855316932,0.216884579307902059],"hpluv":[127.71501294923614,59.3185968765002301,59.921152065724],"hsluv":[127.71501294923614,30.2037385091367128,59.921152065724]},"#779988":{"lch":[60.3212826107906608,19.7788738743410271,150.794869664161695],"luv":[60.3212826107906608,-17.2645515875173317,9.65086059473676272],"rgb":[0.466666666666666674,0.6,0.533333333333333326],"xyz":[0.234417739195146468,0.28481510169609453,0.275557442711474199],"hpluv":[150.794869664161695,41.6073752981458043,60.3212826107906608],"hsluv":[150.794869664161695,33.5278156565034706,60.3212826107906608]},"#779999":{"lch":[60.7849725890424537,17.8137422376051369,192.177050630060307],"luv":[60.7849725890424537,-17.4129412378011317,-3.75751113860251662],"rgb":[0.466666666666666674,0.6,0.6],"xyz":[0.247474703304219168,0.290037887339723688,0.344324120352592133],"hpluv":[192.177050630060307,37.1876097830212373,60.7849725890424537],"hsluv":[192.177050630060307,37.0420465685486562,60.7849725890424537]},"#7799aa":{"lch":[61.3128540464897895,25.0117677757311512,225.340924984985747],"luv":[61.3128540464897895,-17.5804418295499474,-17.7909131959243076],"rgb":[0.466666666666666674,0.6,0.66666666666666663],"xyz":[0.262532396269471724,0.29606096452582481,0.423627969969590734],"hpluv":[225.340924984985747,51.7645188682129742,61.3128540464897895],"hsluv":[225.340924984985747,40.6599304384258815,61.3128540464897895]},"#7799bb":{"lch":[61.9050111975332129,36.7727368637825478,241.108601392342877],"luv":[61.9050111975332129,-17.766782778670386,-32.1958942436537],"rgb":[0.466666666666666674,0.6,0.733333333333333282],"xyz":[0.279669988376808343,0.302916001368759569,0.513885955068232425],"hpluv":[241.108601392342877,75.37710856774234,61.9050111975332129],"hsluv":[241.108601392342877,44.3026829048042927,61.9050111975332129]},"#7799cc":{"lch":[62.5610290710097274,50.0883036089361084,248.973595844380469],"luv":[62.5610290710097274,-17.971590279241223,-46.7531827927901],"rgb":[0.466666666666666674,0.6,0.8],"xyz":[0.298962363820530097,0.31063295154624837,0.615492465738502581],"hpluv":[248.973595844380469,101.594866952252644,62.5610290710097274],"hsluv":[248.973595844380469,49.5852758814030068,62.5610290710097274]},"#7799dd":{"lch":[63.2800443412030518,63.9273589508424962,253.464421950176984],"luv":[63.2800443412030518,-18.1944086519195096,-61.2835272829234228],"rgb":[0.466666666666666674,0.6,0.866666666666666696],"xyz":[0.320480689371163641,0.319240281766501877,0.728822313638508579],"hpluv":[253.464421950176984,128.191525099113591,63.2800443412030518],"hsluv":[253.464421950176984,65.7895471985927429,63.2800443412030518]},"#7799ee":{"lch":[64.0607982423263138,77.8622331281598292,256.304567564122067],"luv":[64.0607982423263138,-18.434716379612933,-75.6484539148497106],"rgb":[0.466666666666666674,0.6,0.933333333333333348],"xyz":[0.344292869637338406,0.328765153872971894,0.854233129707031802],"hpluv":[256.304567564122067,154.231767587931557,64.0607982423263138],"hsluv":[256.304567564122067,82.5871459557978085,64.0607982423263138]},"#7799ff":{"lch":[64.9016907971027,91.67329289213788,258.23504341307023],"luv":[64.9016907971027,-18.6919383586334327,-89.7474460365571929],"rgb":[0.466666666666666674,0.6,1],"xyz":[0.370463918047169771,0.339233573236904618,0.992067317998813758],"hpluv":[258.23504341307023,179.236372955016122,64.9016907971027],"hsluv":[258.23504341307023,99.9999999999984368,64.9016907971027]},"#660000":{"lch":[19.330201679573328,65.0080772249371819,12.1770506300617765],"luv":[19.330201679573328,63.5454254137925432,13.7123671721378795],"rgb":[0.4,0,0],"xyz":[0.0547936733227042463,0.0282529878070199789,0.00256845343700170745],"hpluv":[12.1770506300617765,426.746789183125202,19.330201679573328],"hsluv":[12.1770506300617765,100.000000000002217,19.330201679573328]},"#660011":{"lch":[19.4980803058243595,61.695772445130423,8.9911342856641614],"luv":[19.4980803058243595,60.9376877881905799,9.641916024853316],"rgb":[0.4,0,0.0666666666666666657],"xyz":[0.0558053388223413716,0.0286576540068748317,0.0078965584017573389],"hpluv":[8.9911342856641614,401.51602003210553,19.4980803058243595],"hsluv":[8.9911342856641614,99.9999999999966178,19.4980803058243595]},"#660022":{"lch":[19.8051492014688648,56.728751528179842,2.87530221933591967],"luv":[19.8051492014688648,56.6573341637173584,2.84565201787440492],"rgb":[0.4,0,0.133333333333333331],"xyz":[0.0576806969608183867,0.029407797262265653,0.0177734445977365332],"hpluv":[2.87530221933591967,363.466537566247382,19.8051492014688648],"hsluv":[2.87530221933591967,99.9999999999968594,19.8051492014688648]},"#660033":{"lch":[20.2995520444984123,51.2727836305606957,352.516911450402631],"luv":[20.2995520444984123,50.836110988726972,-6.67743669143524787],"rgb":[0.4,0,0.2],"xyz":[0.0607684476932761272,0.0306428975552487659,0.0340355984553476765],"hpluv":[352.516911450402631,320.508659944055125,20.2995520444984123],"hsluv":[352.516911450402631,99.9999999999973852,20.2995520444984123]},"#660044":{"lch":[20.9904438433464762,47.7800185043531087,338.095292373375855],"luv":[20.9904438433464762,44.3305689635839855,-17.8250055719836844],"rgb":[0.4,0,0.266666666666666663],"xyz":[0.0652264429374950078,0.0324260956529363389,0.057514373408234315],"hpluv":[338.095292373375855,288.844444062118953,20.9904438433464762],"hsluv":[338.095292373375855,99.999999999997911,20.9904438433464762]},"#660055":{"lch":[21.8759682447435324,48.0792454528985687,322.009867044845],"luv":[21.8759682447435324,37.8920594608334085,-29.5940141436867741],"rgb":[0.4,0,0.333333333333333315],"xyz":[0.071188856976857,0.0348110612686811718,0.0889164206822082304],"hpluv":[322.009867044845,278.887908627948889,21.8759682447435324],"hsluv":[322.009867044845,99.9999999999984,21.8759682447435324]},"#660066":{"lch":[22.9458380566939866,52.2668983658326383,307.715012949243601],"luv":[22.9458380566939866,31.9734565677830815,-41.3464235441515271],"rgb":[0.4,0,0.4],"xyz":[0.0787738527503651781,0.0378450595780844834,0.128864065089352192],"hpluv":[307.715012949243601,289.042783730483393,22.9458380566939866],"hsluv":[307.715012949243601,99.9999999999988,22.9458380566939866]},"#660077":{"lch":[24.1840444716539054,59.1802438936044553,296.875135467660698],"luv":[24.1840444716539054,26.7522904844618061,-52.7884099129864097],"rgb":[0.4,0,0.466666666666666674],"xyz":[0.0880878657705671,0.0415706647861653,0.177917866995750101],"hpluv":[296.875135467660698,310.518260327731298,24.1840444716539054],"hsluv":[296.875135467660698,99.9999999999992326,24.1840444716539054]},"#660088":{"lch":[25.5714349826340381,67.6035320092512819,289.201479741547303],"luv":[25.5714349826340381,22.2341957091879898,-63.8426039670327725],"rgb":[0.4,0,0.533333333333333326],"xyz":[0.0992282828725109256,0.0460268316269428907,0.236590730399322269],"hpluv":[289.201479741547303,335.469941782198191,25.5714349826340381],"hsluv":[289.201479741547303,99.9999999999995168,25.5714349826340381]},"#660099":{"lch":[27.0878540213863559,76.7583277742970296,283.827270614430063],"luv":[27.0878540213863559,18.3449067131383,-74.5339203342523291],"rgb":[0.4,0,0.6],"xyz":[0.112285246981583625,0.0512496172705720551,0.305357408040440148],"hpluv":[283.827270614430063,359.575614235331898,27.0878540213863559],"hsluv":[283.827270614430063,99.9999999999996732,27.0878540213863559]},"#6600aa":{"lch":[28.7136916664512327,86.2331190336617226,280.0081392435834],"luv":[28.7136916664512327,14.9862877024472088,-84.9209161465722246],"rgb":[0.4,0,0.66666666666666663],"xyz":[0.127342939946836181,0.0572726944566731566,0.384661257657438749],"hpluv":[280.0081392435834,381.087223541781498,28.7136916664512327],"hsluv":[280.0081392435834,99.9999999999998863,28.7136916664512327]},"#6600bb":{"lch":[30.4308478844127208,95.8259209373334784,277.232006261077231],"luv":[30.4308478844127208,12.063278317584528,-95.06358103774852],"rgb":[0.4,0,0.733333333333333282],"xyz":[0.144480532054172828,0.0641277312996079152,0.474919242756080495],"hpluv":[277.232006261077231,399.584170303460496,30.4308478844127208],"hsluv":[277.232006261077231,100.000000000000071,30.4308478844127208]},"#6600cc":{"lch":[32.2232190058254631,105.440117399912424,275.16595430901134],"luv":[32.2232190058254631,9.49391256045434,-105.011827817640437],"rgb":[0.4,0,0.8],"xyz":[0.163772907497894554,0.0718446814770967168,0.576525753426350707],"hpluv":[275.16595430901134,415.218107165999243,32.2232190058254631],"hsluv":[275.16595430901134,100.000000000000284,32.2232190058254631]},"#6600dd":{"lch":[34.0768449366564425,115.029794578821409,273.594219506454294],"luv":[34.0768449366564425,7.21119822634443164,-114.803537667557165],"rgb":[0.4,0,0.866666666666666696],"xyz":[0.185291233048528098,0.0804520116973502508,0.689855601326356704],"hpluv":[273.594219506454294,428.341637585051217,34.0768449366564425],"hsluv":[273.594219506454294,100.000000000000313,34.0768449366564425]},"#6600ee":{"lch":[35.9798440153965657,124.573148355199,272.374748889870204],"luv":[35.9798440153965657,5.16172842086039729,-124.466163477612255],"rgb":[0.4,0,0.933333333333333348],"xyz":[0.209103413314702835,0.0899768838038202817,0.815266417394879928],"hpluv":[272.374748889870204,439.343788723350144,35.9798440153965657],"hsluv":[272.374748889870204,100.000000000000313,35.9798440153965657]},"#6600ff":{"lch":[37.9222328155672699,134.059876636217865,271.411957283269032],"luv":[37.9222328155672699,3.30334385288953181,-134.01917192367489],"rgb":[0.4,0,1],"xyz":[0.235274461724534228,0.100445303167752992,0.953100605686661773],"hpluv":[271.411957283269032,448.58447779597617,37.9222328155672699],"hsluv":[271.411957283269032,100.00000000000054,37.9222328155672699]},"#661100":{"lch":[20.9278595225824304,60.6482483509225645,15.3961031612090817],"luv":[20.9278595225824304,58.4717927536604165,16.1015365791022269],"rgb":[0.4,0.0666666666666666657,0],"xyz":[0.0567980735836326536,0.0322617883288768559,0.00323658685731115833],"hpluv":[15.3961031612090817,367.733145903292666,20.9278595225824304],"hsluv":[15.3961031612090817,100.00000000000216,20.9278595225824304]},"#661111":{"lch":[21.0816163302651134,57.5811303886473453,12.1770506300618102],"luv":[21.0816163302651134,56.2855814623301782,12.1457768908291825],"rgb":[0.4,0.0666666666666666657,0.0666666666666666657],"xyz":[0.0578097390832697788,0.0326664545287317087,0.00856469182206678892],"hpluv":[12.1770506300618102,346.589664487627374,21.0816163302651134],"hsluv":[12.1770506300618102,81.2167011616125762,21.0816163302651134]},"#661122":{"lch":[21.363314856368774,52.932385078801687,5.93410154371749865],"luv":[21.363314856368774,52.6487447994206548,5.4723908098767966],"rgb":[0.4,0.0666666666666666657,0.133333333333333331],"xyz":[0.059685097221746794,0.0334165977841225301,0.018441578018045985],"hpluv":[5.93410154371749865,314.406957937895,21.363314856368774],"hsluv":[5.93410154371749865,82.5199513610387356,21.363314856368774]},"#661133":{"lch":[21.8180817632255923,47.7742586248590229,355.183549580278111],"luv":[21.8180817632255923,47.6055578330604661,-4.01131531521171425],"rgb":[0.4,0.0666666666666666657,0.2],"xyz":[0.0627728479542045414,0.0346516980771056429,0.0347037318756571317],"hpluv":[355.183549580278111,277.854041301729922,21.8180817632255923],"hsluv":[355.183549580278111,84.3121175303292603,21.8180817632255923]},"#661144":{"lch":[22.4559756968324393,44.5402485804784689,339.935360677682411],"luv":[22.4559756968324393,41.8369301419790247,-15.2808710453946635],"rgb":[0.4,0.0666666666666666657,0.266666666666666663],"xyz":[0.0672308431984234151,0.036434896174793216,0.0581825068285437702],"hpluv":[339.935360677682411,251.686564911624259,22.4559756968324393],"hsluv":[339.935360677682411,86.3348863624116518,22.4559756968324393]},"#661155":{"lch":[23.2773926977910151,45.1903944783221903,322.792583995755933],"luv":[23.2773926977910151,35.9919645110905364,-27.3267313035930464],"rgb":[0.4,0.0666666666666666657,0.333333333333333315],"xyz":[0.073193257237785414,0.0388198617905380489,0.0895845541025176717],"hpluv":[322.792583995755933,246.349182588766354,23.2773926977910151],"hsluv":[322.792583995755933,88.344826800164725,23.2773926977910151]},"#661166":{"lch":[24.275087751098269,49.8658315110702119,307.715012949243715],"luv":[24.275087751098269,30.5046415204515107,-39.4470277460696508],"rgb":[0.4,0.0666666666666666657,0.4],"xyz":[0.0807782530112935854,0.0418538600999413604,0.129532198509661634],"hpluv":[307.715012949243715,260.664316843383688,24.275087751098269],"hsluv":[307.715012949243715,90.1819147598703239,24.275087751098269]},"#661177":{"lch":[25.4363091503391701,57.3032374709331265,296.512546946797],"luv":[25.4363091503391701,25.5798087859014238,-51.2770358652572114],"rgb":[0.4,0.0666666666666666657,0.466666666666666674],"xyz":[0.0900922660314955,0.0455794653080221768,0.178586000416059543],"hpluv":[296.512546946797,285.867241464858182,25.4363091503391701],"hsluv":[296.512546946797,91.7740463972148461,25.4363091503391701]},"#661188":{"lch":[26.7449145171680129,66.1973281861227179,288.734792076243366],"luv":[26.7449145171680129,21.2617948521868456,-62.6898902427238127],"rgb":[0.4,0.0666666666666666657,0.533333333333333326],"xyz":[0.101232683133439333,0.0500356321487997746,0.23725886381963171],"hpluv":[288.734792076243366,314.078764213635395,26.7449145171680129],"hsluv":[288.734792076243366,93.110372692245349,26.7449145171680129]},"#661199":{"lch":[28.1832309630650286,75.7381406209258614,283.36677781159608],"luv":[28.1832309630650286,17.5094321789343716,-73.6864012521064637],"rgb":[0.4,0.0666666666666666657,0.6],"xyz":[0.114289647242512032,0.0552584177924289321,0.306025541460749617],"hpluv":[283.36677781159608,341.006914961476241,28.1832309630650286],"hsluv":[283.36677781159608,94.2123428080992,28.1832309630650286]},"#6611aa":{"lch":[29.733500038717203,85.5146667147819102,279.591039159426828],"luv":[29.733500038717203,14.2479867443400359,-84.3193518539685],"rgb":[0.4,0.0666666666666666657,0.66666666666666663],"xyz":[0.129347340207764588,0.0612814949785300336,0.385329391077748218],"hpluv":[279.591039159426828,364.950446526832081,29.733500038717203],"hsluv":[279.591039159426828,95.1136535912152254,29.733500038717203]},"#6611bb":{"lch":[31.378866229854367,95.3367425151459287,276.866082014695],"luv":[31.378866229854367,11.3974241300945351,-94.6530147253534153],"rgb":[0.4,0.0666666666666666657,0.733333333333333282],"xyz":[0.146484932315101235,0.0681365318214647853,0.475587376176389964],"hpluv":[276.866082014695,385.533736621086632,31.378866229854367],"hsluv":[276.866082014695,95.8493220980777636,31.378866229854367]},"#6611cc":{"lch":[33.1039576367877899,105.121866511028642,274.848446148865946],"luv":[33.1039576367877899,8.88494143701037409,-104.745714157780327],"rgb":[0.4,0.0666666666666666657,0.8],"xyz":[0.165777307758822962,0.0758534819989535869,0.577193886846660176],"hpluv":[274.848446148865946,402.951217622234481,33.1039576367877899],"hsluv":[274.848446148865946,96.4508528344463372,33.1039576367877899]},"#6611dd":{"lch":[34.8951509835915559,114.837148656435488,273.319244536407894],"luv":[34.8951509835915559,6.64899595047804048,-114.644500803094743],"rgb":[0.4,0.0666666666666666657,0.866666666666666696],"xyz":[0.187295633309456505,0.0844608122192071209,0.690523734746666173],"hpluv":[273.319244536407894,417.596303228590671,34.8951509835915559],"hsluv":[273.319244536407894,96.944722371929771,34.8951509835915559]},"#6611ee":{"lch":[36.7406193088150914,124.471664845310258,272.136065946829319],"luv":[36.7406193088150914,4.63940101804097527,-124.385173182164465],"rgb":[0.4,0.0666666666666666657,0.933333333333333348],"xyz":[0.211107813575631242,0.0939856843256771657,0.815934550815189397],"hpluv":[272.136065946829319,429.895948632666091,36.7406193088150914],"hsluv":[272.136065946829319,97.3524117238680446,36.7406193088150914]},"#6611ff":{"lch":[38.6302462525687815,134.023748920536207,271.203906716280642],"luv":[38.6302462525687815,2.81591803113255,-133.994163605572282],"rgb":[0.4,0.0666666666666666657,1],"xyz":[0.237278861985462636,0.104454103689609862,0.953768739106971242],"hpluv":[271.203906716280642,440.244168299440901,38.6302462525687815],"hsluv":[271.203906716280642,99.999999999999531,38.6302462525687815]},"#662200":{"lch":[23.5697003211059126,54.0433218319152,21.7646438431993481],"luv":[23.5697003211059126,50.1908335966774928,20.038983444740694],"rgb":[0.4,0.133333333333333331,0],"xyz":[0.0605136973184005889,0.0396930357984128235,0.00447512810223376842],"hpluv":[21.7646438431993481,290.955989204018863,23.5697003211059126],"hsluv":[21.7646438431993481,100.000000000002302,23.5697003211059126]},"#662211":{"lch":[23.7037155268300239,51.2256671637292627,18.5481266113504795],"luv":[23.7037155268300239,48.5648418325832196,16.2949413667354186],"rgb":[0.4,0.133333333333333331,0.0666666666666666657],"xyz":[0.0615253628180377071,0.0400977019982676763,0.0098032330669894],"hpluv":[18.5481266113504795,274.227196288753476,23.7037155268300239],"hsluv":[18.5481266113504795,84.4421944630679775,23.7037155268300239]},"#662222":{"lch":[23.9497782760704823,46.8639841586094761,12.177050630061828],"luv":[23.9497782760704823,45.8095660888384515,9.88517404858116],"rgb":[0.4,0.133333333333333331,0.133333333333333331],"xyz":[0.0634007209565147362,0.0408478452536585,0.0196801192629685942],"hpluv":[12.177050630061828,248.300181449835577,23.9497782760704823],"hsluv":[12.177050630061828,58.184428739378582,23.9497782760704823]},"#662233":{"lch":[24.3484354577474491,41.8866591548313139,0.79920805816821483],"luv":[24.3484354577474491,41.8825842907357284,0.584250188216085209],"rgb":[0.4,0.133333333333333331,0.2],"xyz":[0.0664884716889724697,0.0420829455466416105,0.0359422731205797374],"hpluv":[0.79920805816821483,218.295100847162672,24.3484354577474491],"hsluv":[0.79920805816821483,61.8388407102714908,24.3484354577474491]},"#662244":{"lch":[24.9104705449366364,38.7518995195090881,343.921953822216381],"luv":[24.9104705449366364,37.2361321960480467,-10.7322027305005232],"rgb":[0.4,0.133333333333333331,0.266666666666666663],"xyz":[0.0709464669331913433,0.0438661436443291836,0.059421048073466376],"hpluv":[343.921953822216381,197.40147375767063,24.9104705449366364],"hsluv":[343.921953822216381,66.1143919991375,24.9104705449366364]},"#662255":{"lch":[25.6388481254070371,39.7515606661792376,324.488651014584605],"luv":[25.6388481254070371,32.3577893991285421,-23.0902585650003651],"rgb":[0.4,0.133333333333333331,0.333333333333333315],"xyz":[0.0769088809725533423,0.0462511092600740165,0.0908230953474402913],"hpluv":[324.488651014584605,196.74105716675524,25.6388481254070371],"hsluv":[324.488651014584605,70.5303777194930746,25.6388481254070371]},"#662266":{"lch":[26.530115175026431,45.1550068711170525,307.715012949244],"luv":[26.530115175026431,27.6228683191850166,-35.7204674010796381],"rgb":[0.4,0.133333333333333331,0.4],"xyz":[0.0844938767460615137,0.049285107569477328,0.130770739754584253],"hpluv":[307.715012949244,215.976303505553034,26.530115175026431],"hsluv":[307.715012949244,74.7212231760600076,26.530115175026431]},"#662277":{"lch":[27.5758503181253047,53.47184404785515,295.772994892671647],"luv":[27.5758503181253047,23.2499163509258366,-48.1526686233805137],"rgb":[0.4,0.133333333333333331,0.466666666666666674],"xyz":[0.0938078897662634331,0.0530107127775581444,0.179824541660982162],"hpluv":[295.772994892671647,246.056915236342576,27.5758503181253047],"hsluv":[295.772994892671647,78.4792949436714622,27.5758503181253047]},"#662288":{"lch":[28.7641691288539221,63.1969785740596492,287.807032602413699],"luv":[28.7641691288539221,19.3264050913403267,-60.169329123196718],"rgb":[0.4,0.133333333333333331,0.533333333333333326],"xyz":[0.104948306868207261,0.0574668796183357422,0.23849740506455433],"hpluv":[287.807032602413699,278.794247273594806,28.7641691288539221],"hsluv":[287.807032602413699,81.7283139306751565,28.7641691288539221]},"#662299":{"lch":[30.081149723697223,73.446586603294,282.467625610713],"luv":[30.081149723697223,15.8562317990126083,-71.7145800853016766],"rgb":[0.4,0.133333333333333331,0.6],"xyz":[0.118005270977279975,0.0626896652619649,0.307264082705672237],"hpluv":[282.467625610713,309.825038390781458,30.081149723697223],"hsluv":[282.467625610713,84.475317587044259,30.081149723697223]},"#6622aa":{"lch":[31.512047889249807,83.7990879252892569,278.786617054458873],"luv":[31.512047889249807,12.8007301136733549,-82.8156292354725565],"rgb":[0.4,0.133333333333333331,0.66666666666666663],"xyz":[0.133062963942532531,0.068712742448066,0.386567932322670837],"hpluv":[278.786617054458873,337.444217562648532,31.512047889249807],"hsluv":[278.786617054458873,86.7692530837111349,31.512047889249807]},"#6622bb":{"lch":[33.0422299311305281,94.07636648958254,276.16643073789237],"luv":[33.0422299311305281,10.1053888262289746,-93.5320471739658643],"rgb":[0.4,0.133333333333333331,0.733333333333333282],"xyz":[0.150200556049869149,0.0755677792910007529,0.476825917421312584],"hpluv":[276.16643073789237,361.285484259324733,33.0422299311305281],"hsluv":[276.16643073789237,88.6739591516067662,33.0422299311305281]},"#6622cc":{"lch":[34.6578144612334853,104.214655833315277,274.245119058655746],"luv":[34.6578144612334853,7.71433729467952212,-103.928742369761551],"rgb":[0.4,0.133333333333333331,0.8],"xyz":[0.169492931493590904,0.0832847294684895545,0.578432428091582684],"hpluv":[274.245119058655746,381.563613242959605,34.6578144612334853],"hsluv":[274.245119058655746,90.2534916489383079,34.6578144612334853]},"#6622dd":{"lch":[36.346058304563158,114.200305800004017,272.799119030217753],"luv":[36.346058304563158,5.5769048208672336,-114.064052082299],"rgb":[0.4,0.133333333333333331,0.866666666666666696],"xyz":[0.191011257044224447,0.0918920596887430885,0.691762275991588682],"hpluv":[272.799119030217753,398.702789727268566,36.346058304563158],"hsluv":[272.799119030217753,91.5654894217155118,36.346058304563158]},"#6622ee":{"lch":[38.0955422395423,124.039689220569301,271.686141036519132],"luv":[38.0955422395423,3.64980151132168062,-123.985980864222597],"rgb":[0.4,0.133333333333333331,0.933333333333333348],"xyz":[0.214823437310399185,0.101416931795213133,0.817173092060111905],"hpluv":[271.686141036519132,413.167199445381073,38.0955422395423],"hsluv":[271.686141036519132,92.6590152569973498,38.0955422395423]},"#6622ff":{"lch":[39.8962147757429264,133.745689778340022,270.812765394378914],"luv":[39.8962147757429264,1.89717678294479941,-133.732233416399],"rgb":[0.4,0.133333333333333331,1],"xyz":[0.240994485720230578,0.111885351159145829,0.95500728035189375],"hpluv":[270.812765394378914,425.390148773484384,39.8962147757429264],"hsluv":[270.812765394378914,99.99999999999946,39.8962147757429264]},"#ddaa00":{"lch":[72.3107430320736881,86.5721801417344494,59.9465914104400071],"luv":[72.3107430320736881,43.355958426121056,74.9333253195491267],"rgb":[0.866666666666666696,0.66666666666666663,0],"xyz":[0.441922241377765923,0.441231641500849037,0.0618909005679976823],"hpluv":[59.9465914104400071,151.919966798177825,72.3107430320736881],"hsluv":[59.9465914104400071,100.000000000002402,72.3107430320736881]},"#ddaa11":{"lch":[72.3377322217577188,85.4954146103564625,59.6744594052448178],"luv":[72.3377322217577188,43.1676990261245663,73.7971251485224],"rgb":[0.866666666666666696,0.66666666666666663,0.0666666666666666657],"xyz":[0.442933906877403,0.44163630770070389,0.067219005532753312],"hpluv":[59.6744594052448178,149.974443711406025,72.3377322217577188],"hsluv":[59.6744594052448178,98.5180859943944398,72.3377322217577188]},"#ddaa22":{"lch":[72.3877194091470386,83.5208789068112623,59.1557200492863586],"luv":[72.3877194091470386,42.8217010650181038,71.708013019916109],"rgb":[0.866666666666666696,0.66666666666666663,0.133333333333333331],"xyz":[0.444809265015880084,0.44238645095609469,0.0770958917287325],"hpluv":[59.1557200492863586,146.409577733002152,72.3877194091470386],"hsluv":[59.1557200492863586,95.7957425728033911,72.3877194091470386]},"#ddaa33":{"lch":[72.4698996386445771,80.3304907566891,58.2589820164620633],"luv":[72.4698996386445771,42.2603136650720543,68.3158373595774435],"rgb":[0.866666666666666696,0.66666666666666663,0.2],"xyz":[0.44789701574833779,0.443621551249077817,0.0933580455863436548],"hpluv":[58.2589820164620633,140.657238526484292,72.4698996386445771],"hsluv":[58.2589820164620633,91.3821490755410082,72.4698996386445771]},"#ddaa44":{"lch":[72.5882801580772679,75.8571050863154,56.8623293870095949],"luv":[72.5882801580772679,41.467485474955744,63.5196665644635701],"rgb":[0.866666666666666696,0.66666666666666663,0.266666666666666663],"xyz":[0.452355010992556705,0.445404749346765383,0.116836820539230293],"hpluv":[56.8623293870095949,132.607804442486071,72.5882801580772679],"hsluv":[56.8623293870095949,85.1564308385751332,72.5882801580772679]},"#ddaa55":{"lch":[72.7461171317656579,70.1198989219024469,54.780917696258733],"luv":[72.7461171317656579,40.4384565855633085,57.2846528644045065],"rgb":[0.866666666666666696,0.66666666666666663,0.333333333333333315],"xyz":[0.45831742503191869,0.447789714962510244,0.148238867813204195],"hpluv":[54.780917696258733,122.3124851735341,72.7461171317656579],"hsluv":[54.780917696258733,77.0893717991816345,72.7461171317656579]},"#ddaa66":{"lch":[72.9460991959627307,63.2340905833455835,51.7145858463931702],"luv":[72.9460991959627307,39.17852917707404,49.6345954292357661],"rgb":[0.866666666666666696,0.66666666666666663,0.4],"xyz":[0.465902420805426876,0.450823713271913562,0.188186512220348157],"hpluv":[51.7145858463931702,109.998947735143361,72.9460991959627307],"hsluv":[51.7145858463931702,67.2337497701281421,72.9460991959627307]},"#ddaa77":{"lch":[73.1904440644495651,55.4382228560327377,47.150998877343909],"luv":[73.1904440644495651,37.7017926183457632,40.6444508733775294],"rgb":[0.866666666666666696,0.66666666666666663,0.466666666666666674],"xyz":[0.475216433825628781,0.454549318479994358,0.237240314126746066],"hpluv":[47.150998877343909,96.1156803308001173,73.1904440644495651],"hsluv":[47.150998877343909,55.7140089565642214,73.1904440644495651]},"#ddaa88":{"lch":[73.4809558021361511,47.1613293807763228,40.1850915920125189],"luv":[73.4809558021361511,36.0295555463961819,30.4312687229965526],"rgb":[0.866666666666666696,0.66666666666666663,0.533333333333333326],"xyz":[0.486356850927572582,0.459005485320771955,0.295913177530318261],"hpluv":[40.1850915920125189,81.4424009312931645,73.4809558021361511],"hsluv":[40.1850915920125189,45.325944585658668,73.4809558021361511]},"#ddaa99":{"lch":[73.8190624606049539,39.1833139250455389,29.2463480703396321],"luv":[73.8190624606049539,34.1885051927702435,19.1436204212419021],"rgb":[0.866666666666666696,0.66666666666666663,0.6],"xyz":[0.499413815036645281,0.464228270964401113,0.36467985517143614],"hpluv":[29.2463480703396321,67.3553294964948,73.8190624606049539],"hsluv":[29.2463480703396321,46.1073405736803323,73.8190624606049539]},"#ddaaaa":{"lch":[74.2058435914849923,32.9500913661112946,12.1770506300625296],"luv":[74.2058435914849923,32.2087294789219527,6.95027095793437244],"rgb":[0.866666666666666696,0.66666666666666663,0.66666666666666663],"xyz":[0.514471508001897893,0.470251348150502235,0.443983704788434741],"hpluv":[12.1770506300625296,56.3453191386000114,74.2058435914849923],"hsluv":[12.1770506300625296,46.9171896008106,74.2058435914849923]},"#ddaabb":{"lch":[74.6420527030620633,30.7078714289026884,348.787813428378513],"luv":[74.6420527030620633,30.1217754775259223,-5.97093039446416807],"rgb":[0.866666666666666696,0.66666666666666663,0.733333333333333282],"xyz":[0.531609100109234456,0.477106384993437,0.534241689887076543],"hpluv":[348.787813428378513,52.2042025244198,74.6420527030620633],"hsluv":[348.787813428378513,47.7320050944543937,74.6420527030620633]},"#ddaacc":{"lch":[75.1281375044867445,34.0548346014018435,325.184688201169763],"luv":[75.1281375044867445,27.9589055182432595,-19.4430286208394669],"rgb":[0.866666666666666696,0.66666666666666663,0.8],"xyz":[0.55090147555295621,0.484823335170925795,0.635848200557346699],"hpluv":[325.184688201169763,57.5195499622066393,75.1281375044867445],"hsluv":[325.184688201169763,48.5278754329488109,75.1281375044867445]},"#ddaadd":{"lch":[75.6642595524878772,42.092894356631966,307.715012949247466],"luv":[75.6642595524878772,25.749668941594777,-33.2981426616688125],"rgb":[0.866666666666666696,0.66666666666666663,0.866666666666666696],"xyz":[0.572419801103589809,0.493430665391179302,0.749178048457352697],"hpluv":[307.715012949247466,70.5922995729826255,75.6642595524878772],"hsluv":[307.715012949247466,49.2811497501269855,75.6642595524878772]},"#ddaaee":{"lch":[76.2503141773092636,52.9001531738191915,296.399494755977059],"luv":[76.2503141773092636,23.5208512504545659,-47.3834967290038875],"rgb":[0.866666666666666696,0.66666666666666663,0.933333333333333348],"xyz":[0.596231981369764519,0.502955537497649319,0.87458886452587592],"hpluv":[296.399494755977059,89.1958388421213,76.2503141773092636],"hsluv":[296.399494755977059,73.8038640729286,76.2503141773092636]},"#ddaaff":{"lch":[76.8859510948180542,65.1444004641461447,289.080822119258073],"luv":[76.8859510948180542,21.295808093697417,-61.565261872824486],"rgb":[0.866666666666666696,0.66666666666666663,1],"xyz":[0.62240302977959594,0.513423956861582,1.01242305281765765],"hpluv":[289.080822119258073,113.514774922986319,76.8859510948180542],"hsluv":[289.080822119258073,99.9999999999968736,76.8859510948180542]},"#663300":{"lch":[27.2772702365161024,46.6784293424923,33.1138040531735385],"luv":[27.2772702365161024,39.0972512948193938,25.5006020923387098],"rgb":[0.4,0.2,0],"xyz":[0.0666314194074114075,0.0519284799764346272,0.00651436879857064926],"hpluv":[33.1138040531735385,217.147410386557254,27.2772702365161024],"hsluv":[33.1138040531735385,100.000000000002288,27.2772702365161024]},"#663311":{"lch":[27.3893959478715772,43.971204952951652,30.1269617465812196],"luv":[27.3893959478715772,38.0313691656755353,22.0699303215615963],"rgb":[0.4,0.2,0.0666666666666666657],"xyz":[0.0676430849070485257,0.0523331461762894801,0.0118424737633262799],"hpluv":[30.1269617465812196,203.716046393577358,27.3893959478715772],"hsluv":[30.1269617465812196,87.8713966090680572,27.3893959478715772]},"#663322":{"lch":[27.5957277293980781,39.608651287835805,23.9834802389854467],"luv":[27.5957277293980781,36.1889469500517436,16.0998563809655693],"rgb":[0.4,0.2,0.133333333333333331],"xyz":[0.0695184430455255548,0.0530832894316803,0.0217193599593054759],"hpluv":[23.9834802389854467,182.132533879714401,27.5957277293980781],"hsluv":[23.9834802389854467,66.9779468056010501,27.5957277293980781]},"#663333":{"lch":[27.9312558147072,34.2527069144242517,12.1770506300619683],"luv":[27.9312558147072,33.482036777055967,7.2250359324586606],"rgb":[0.4,0.2,0.2],"xyz":[0.0726061937779832883,0.0543183897246634143,0.0379815138169166192],"hpluv":[12.1770506300619683,155.612242967619039,27.9312558147072],"hsluv":[12.1770506300619683,36.4647718300342518,27.9312558147072]},"#663344":{"lch":[28.4068233476218452,30.4023991370198274,352.642674566889241],"luv":[28.4068233476218452,30.1520905841737843,-3.89323858637544307],"rgb":[0.4,0.2,0.266666666666666663],"xyz":[0.0770641890222021619,0.0561015878223509873,0.0614602887698032577],"hpluv":[352.642674566889241,135.807736934047625,28.4068233476218452],"hsluv":[352.642674566889241,42.3197568133242044,28.4068233476218452]},"#663355":{"lch":[29.027378781744666,31.164203729876963,328.257954430910445],"luv":[29.027378781744666,26.5028264215118483,-16.3953586660521324],"rgb":[0.4,0.2,0.333333333333333315],"xyz":[0.0830266030615641609,0.0584865534380958202,0.0928623360437771661],"hpluv":[328.257954430910445,136.234637721643935,29.027378781744666],"hsluv":[328.257954430910445,48.648881209958347,29.027378781744666]},"#663366":{"lch":[29.7928910898429251,37.2833882928919067,307.715012949244567],"luv":[29.7928910898429251,22.8075289246907325,-29.4935190668720466],"rgb":[0.4,0.2,0.4],"xyz":[0.0906115988350723323,0.0615205517474991317,0.132809980450921128],"hpluv":[307.715012949244567,158.796911496206434,29.7928910898429251],"hsluv":[307.715012949244567,54.9388950129523792,29.7928910898429251]},"#663377":{"lch":[30.6992208566667273,46.7654342463890345,294.320996437271049],"luv":[30.6992208566667273,19.2602655771695837,-42.6151148086008646],"rgb":[0.4,0.2,0.466666666666666674],"xyz":[0.0999256118552742517,0.0652461569555799481,0.181863782357319037],"hpluv":[294.320996437271049,193.302265796468333,30.6992208566667273],"hsluv":[294.320996437271049,60.8304716126584424,30.6992208566667273]},"#663388":{"lch":[31.7390466224972485,57.6768981875091811,286.074834637191429],"luv":[31.7390466224972485,15.9703082974272554,-55.4217812544619122],"rgb":[0.4,0.2,0.533333333333333326],"xyz":[0.11106602895721808,0.0697023237963575459,0.240536645760891205],"hpluv":[286.074834637191429,230.593651019326217,31.7390466224972485],"hsluv":[286.074834637191429,66.1275975958513,31.7390466224972485]},"#663399":{"lch":[32.9028065942714818,68.9918273860838696,280.844497617061506],"luv":[32.9028065942714818,12.9804074562249703,-67.7597319087197292],"rgb":[0.4,0.2,0.6],"xyz":[0.124122993066290793,0.0749251094399867,0.309303323402009112],"hpluv":[280.844497617061506,266.074975063872387,32.9028065942714818],"hsluv":[280.844497617061506,70.7618769362906761,32.9028065942714818]},"#6633aa":{"lch":[34.1795810026756612,80.2563017922262,277.366876751775067],"luv":[34.1795810026756612,10.2906460265496023,-79.5938225097975],"rgb":[0.4,0.2,0.66666666666666663],"xyz":[0.139180686031543321,0.0809481866260878,0.388607173019007712],"hpluv":[277.366876751775067,297.955725741163178,34.1795810026756612],"hsluv":[277.366876751775067,74.7463951454814293,34.1795810026756612]},"#6633bb":{"lch":[35.5578512622049701,91.2933310256451875,274.950579703742051],"luv":[35.5578512622049701,7.87828999249439477,-90.9527615663878208],"rgb":[0.4,0.2,0.733333333333333282],"xyz":[0.15631827813888,0.0878032234690225566,0.478865158117649459],"hpluv":[274.950579703742051,325.793841875348,35.5578512622049701],"hsluv":[274.950579703742051,78.1373397599298158,35.5578512622049701]},"#6633cc":{"lch":[37.0261004663704369,102.052471518039624,273.208108112313198],"luv":[37.0261004663704369,5.71114175070883,-101.892540467119574],"rgb":[0.4,0.2,0.8],"xyz":[0.175610653582601722,0.0955201736465113582,0.58047166878791967],"hpluv":[273.208108112313198,349.747708937339723,37.0261004663704369],"hsluv":[273.208108112313198,81.008127051099,37.0261004663704369]},"#6633dd":{"lch":[38.5732487885037258,112.538160698021628,271.912259810227567],"luv":[38.5732487885037258,3.75528971541350476,-112.475488051606391],"rgb":[0.4,0.2,0.866666666666666696],"xyz":[0.197128979133235266,0.104127503866764892,0.693801516687925668],"hpluv":[271.912259810227567,370.214070757058153,38.5732487885037258],"hsluv":[271.912259810227567,83.8924044294761,38.5732487885037258]},"#6633ee":{"lch":[40.1889386764538372,122.775879994578517,270.923585069715159],"luv":[40.1889386764538372,1.97901241536538453,-122.759929204537158],"rgb":[0.4,0.2,0.933333333333333348],"xyz":[0.22094115939941,0.113652375973234937,0.819212332756448891],"hpluv":[270.923585069715159,387.655406037674595,40.1889386764538372],"hsluv":[270.923585069715159,91.8481370725274502,40.1889386764538372]},"#6633ff":{"lch":[41.8636962738951581,132.796565847050772,270.152898062524457],"luv":[41.8636962738951581,0.354377123439640451,-132.796093005873018],"rgb":[0.4,0.2,1],"xyz":[0.247112207809241397,0.124120795337167633,0.957046521048230736],"hpluv":[270.152898062524457,402.521052726566381,41.8636962738951581],"hsluv":[270.152898062524457,99.9999999999993747,41.8636962738951581]},"#ddbb00":{"lch":[76.6269242453545871,86.8164471599593,69.4373142874166263],"luv":[76.6269242453545871,30.4927107526369845,81.2852390562642],"rgb":[0.866666666666666696,0.733333333333333282,0],"xyz":[0.475876739286364758,0.509140637318047595,0.0732090665375303],"hpluv":[69.4373142874166263,149.25100710879434,76.6269242453545871],"hsluv":[69.4373142874166263,100.000000000002373,76.6269242453545871]},"#ddbb11":{"lch":[76.6514577805917412,85.7837129406502754,69.2755127455160391],"luv":[76.6514577805917412,30.3566774947925779,80.2328956062352461],"rgb":[0.866666666666666696,0.733333333333333282,0.0666666666666666657],"xyz":[0.476888404786001863,0.509545303517902504,0.0785371715022859379],"hpluv":[69.2755127455160391,147.663405788509436,76.6514577805917412],"hsluv":[69.2755127455160391,98.710789014839,76.6514577805917412]},"#ddbb22":{"lch":[76.6969020797125722,83.8847347199512257,68.9672438614109353],"luv":[76.6969020797125722,30.1063672837106679,78.2959473281657523],"rgb":[0.866666666666666696,0.733333333333333282,0.133333333333333331],"xyz":[0.478763762924478919,0.510295446773293304,0.0884140576982651305],"hpluv":[68.9672438614109353,144.735860207932831,76.6969020797125722],"hsluv":[68.9672438614109353,96.3396664069398554,76.6969020797125722]},"#ddbb33":{"lch":[76.7716285455552452,80.8014056767331823,68.4347482297151828],"luv":[76.7716285455552452,29.6994133556607949,75.1452726767666093],"rgb":[0.866666666666666696,0.733333333333333282,0.2],"xyz":[0.481851513656936625,0.511530547066276431,0.104676211555876281],"hpluv":[68.4347482297151828,139.9591753538609,76.7716285455552452],"hsluv":[68.4347482297151828,92.4878111801133542,76.7716285455552452]},"#ddbb44":{"lch":[76.8793043130786771,76.4437058057830683,67.6060651816737277],"luv":[76.8793043130786771,29.122950030038453,70.6788082728408398],"rgb":[0.866666666666666696,0.733333333333333282,0.266666666666666663],"xyz":[0.486309508901155541,0.513313745163964,0.128154986508762919],"hpluv":[67.6060651816737277,133.157612926581692,76.8793043130786771],"hsluv":[67.6060651816737277,87.0382611213693167,76.8793043130786771]},"#ddbb55":{"lch":[77.0229278214451654,70.786451757311653,66.3713649049339551],"luv":[77.0229278214451654,28.3717024864450664,64.851894732620238],"rgb":[0.866666666666666696,0.733333333333333282,0.333333333333333315],"xyz":[0.492271922940517526,0.515698710779708747,0.159557033782736835],"hpluv":[66.3713649049339551,124.235507886155276,77.0229278214451654],"hsluv":[66.3713649049339551,79.9485715087726,77.0229278214451654]},"#ddbb66":{"lch":[77.2049977781888259,63.8693414267369732,64.5489675558404912],"luv":[77.2049977781888259,27.4471820183984,57.6710063509733359],"rgb":[0.866666666666666696,0.733333333333333282,0.4],"xyz":[0.499856918714025711,0.518732709089112065,0.199504678189880769],"hpluv":[64.5489675558404912,113.177180957201557,77.2049977781888259],"hsluv":[64.5489675558404912,71.2432689272834665,77.2049977781888259]},"#ddbb77":{"lch":[77.4276024714994264,55.80459657383539,61.8158033937064815],"luv":[77.4276024714994264,26.3569386858829375,49.1880552764299495],"rgb":[0.866666666666666696,0.733333333333333282,0.466666666666666674],"xyz":[0.509170931734227561,0.522458314297192916,0.248558480096278678],"hpluv":[61.8158033937064815,100.062778032150931,77.4276024714994264],"hsluv":[61.8158033937064815,61.00659046349368,77.4276024714994264]},"#ddbb88":{"lch":[77.6924726660212883,46.8021917196541537,57.5480835848938881],"luv":[77.6924726660212883,25.1136643841879952,39.4936578574539112],"rgb":[0.866666666666666696,0.733333333333333282,0.533333333333333326],"xyz":[0.520311348836171472,0.526914481137970458,0.307231343499850873],"hpluv":[57.5480835848938881,85.1204314231653285,77.6924726660212883],"hsluv":[57.5480835848938881,49.3735690170151145,77.6924726660212883]},"#ddbb99":{"lch":[78.001015952892,37.2494741955694195,50.4191367157405352],"luv":[78.001015952892,23.7341209657771088,28.7091419207933036],"rgb":[0.866666666666666696,0.733333333333333282,0.6],"xyz":[0.533368312945244116,0.532137266781599672,0.375998021140968752],"hpluv":[50.4191367157405352,68.8881727109007471,78.001015952892],"hsluv":[50.4191367157405352,37.2278198354843894,78.001015952892]},"#ddbbaa":{"lch":[78.3543411988951135,27.9779961680489,37.3601297670291643],"luv":[78.3543411988951135,22.2379488027189254,16.9776883770144309],"rgb":[0.866666666666666696,0.733333333333333282,0.66666666666666663],"xyz":[0.548426005910496728,0.538160343967700738,0.455301870757967353],"hpluv":[37.3601297670291643,52.7537881236722086,78.3543411988951135],"hsluv":[37.3601297670291643,37.9002282962103152,78.3543411988951135]},"#ddbbbb":{"lch":[78.7532777240269724,21.1216737069600953,12.1770506300632171],"luv":[78.7532777240269724,20.6464457718990104,4.45526398447083238],"rgb":[0.866666666666666696,0.733333333333333282,0.733333333333333282],"xyz":[0.565563598017833291,0.545015380810635497,0.545559855856609155],"hpluv":[12.1770506300632171,40.7192307977840144,78.7532777240269724],"hsluv":[12.1770506300632171,38.5653299871361952,78.7532777240269724]},"#ddbbcc":{"lch":[79.1983918483363425,20.8793784390591419,335.381067074864461],"luv":[79.1983918483363425,18.9814116783666442,-8.69795692664743747],"rgb":[0.866666666666666696,0.733333333333333282,0.8],"xyz":[0.584855973461555,0.552732330988124354,0.647166366526879311],"hpluv":[335.381067074864461,41.2776027841095186,79.1983918483363425],"hsluv":[335.381067074864461,39.1976988204569,79.1983918483363425]},"#ddbbdd":{"lch":[79.6900023594157858,28.2216267397768341,307.715012949250536],"luv":[79.6900023594157858,17.264138203128045,-22.325092338948604],"rgb":[0.866666666666666696,0.733333333333333282,0.866666666666666696],"xyz":[0.606374299012188644,0.56133966120837786,0.760496214426885309],"hpluv":[307.715012949250536,57.3946451248898555,79.6900023594157858],"hsluv":[307.715012949250536,39.7709084435557401,79.6900023594157858]},"#ddbbee":{"lch":[80.2281958041266,39.4567857635703447,293.154060026294076],"luv":[80.2281958041266,15.5145982189510505,-36.2785774927409221],"rgb":[0.866666666666666696,0.733333333333333282,0.933333333333333348],"xyz":[0.630186479278363354,0.570864533314847877,0.885907030495408532],"hpluv":[293.154060026294076,82.8233888781043674,80.2281958041266],"hsluv":[293.154060026294076,68.7191774169969278,80.2281958041266]},"#ddbbff":{"lch":[80.8128420975971409,52.2658591287574765,285.253756774661895],"luv":[80.8128420975971409,13.7508586713070624,-50.4245368473411],"rgb":[0.866666666666666696,0.733333333333333282,1],"xyz":[0.656357527688194775,0.581332952678780601,1.02374121878719038],"hpluv":[285.253756774661895,113.64059963508393,80.8128420975971409],"hsluv":[285.253756774661895,99.9999999999962768,80.8128420975971409]},"#664400":{"lch":[31.7142168878436834,41.7146560735594463,49.9018869072924431],"luv":[31.7142168878436834,26.8683448374877969,31.9093180282686859],"rgb":[0.4,0.266666666666666663,0],"xyz":[0.0754639898903774337,0.0695936209423669294,0.00945855895955924342],"hpluv":[49.9018869072924431,166.906788900061372,31.7142168878436834],"hsluv":[49.9018869072924431,100.000000000002103,31.7142168878436834]},"#664411":{"lch":[31.8065195391856221,38.988494662362406,47.7128576067384387],"luv":[31.8065195391856221,26.2332728657793552,28.8429906699465946],"rgb":[0.4,0.266666666666666663,0.0666666666666666657],"xyz":[0.0764756553900145519,0.0699982871422217823,0.0147866639243148749],"hpluv":[47.7128576067384387,155.546285842055198,31.8065195391856221],"hsluv":[47.7128576067384387,90.7993319288460157,31.8065195391856221]},"#664422":{"lch":[31.9766874661881033,34.3475437583520318,43.0092135947734064],"luv":[31.9766874661881033,25.116436032279772,23.4290077311931029],"rgb":[0.4,0.266666666666666663,0.133333333333333331],"xyz":[0.078351013528491581,0.0707484303976126,0.0246635501202940727],"hpluv":[43.0092135947734064,136.301783870263904,31.9766874661881033],"hsluv":[43.0092135947734064,74.6688439558526227,31.9766874661881033]},"#664433":{"lch":[32.2542649002247757,27.9288783689085562,32.9719795273007179],"luv":[32.2542649002247757,23.4305644913898661,15.1997004759998031],"rgb":[0.4,0.266666666666666663,0.2],"xyz":[0.0814387642609493145,0.0719835306905957095,0.0409257039779052159],"hpluv":[32.9719795273007179,109.876716511985933,32.2542649002247757],"hsluv":[32.9719795273007179,50.4508902462759465,32.2542649002247757]},"#664444":{"lch":[32.6494757012261942,21.7704999617243,12.1770506300622419],"luv":[32.6494757012261942,21.2806737346177428,4.59212303669972144],"rgb":[0.4,0.266666666666666663,0.266666666666666663],"xyz":[0.0858967595051681881,0.0737667287882832895,0.0644044789307918475],"hpluv":[12.1770506300622419,84.6119136876739,32.6494757012261942],"hsluv":[12.1770506300622419,19.8271939783404392,32.6494757012261942]},"#664455":{"lch":[33.1682230288457163,20.3425996427482829,337.72581918360828],"luv":[33.1682230288457163,18.8246474429619,-7.71064257201243208],"rgb":[0.4,0.266666666666666663,0.333333333333333315],"xyz":[0.0918591735445301871,0.0761516944040281224,0.0958065262047657629],"hpluv":[337.72581918360828,77.8257963773028649,33.1682230288457163],"hsluv":[337.72581918360828,26.9902218950403885,33.1682230288457163]},"#664466":{"lch":[33.8127168447387447,26.5268160416637819,307.715012949245931],"luv":[33.8127168447387447,16.2273642995468066,-20.9843898457416387],"rgb":[0.4,0.266666666666666663,0.4],"xyz":[0.0994441693180383585,0.0791856927134314409,0.135754170611909725],"hpluv":[307.715012949245931,99.5507152142919125,33.8127168447387447],"hsluv":[307.715012949245931,34.4415155187259359,33.8127168447387447]},"#664477":{"lch":[34.5819879544663067,37.1994974310500766,291.489286484323088],"luv":[34.5819879544663067,13.6271894146704895,-34.6136146303646512],"rgb":[0.4,0.266666666666666663,0.466666666666666674],"xyz":[0.108758182338240278,0.0829112979215122503,0.184807972518307634],"hpluv":[291.489286484323088,136.49804898345451,34.5819879544663067],"hsluv":[291.489286484323088,41.7425383187140824,34.5819879544663067]},"#664488":{"lch":[35.4724176022540263,49.4256461635840623,283.003444619748336],"luv":[35.4724176022540263,11.1212465051830698,-48.1582015326441066],"rgb":[0.4,0.266666666666666663,0.533333333333333326],"xyz":[0.119898599440184106,0.0873674647622898481,0.243480835921879801],"hpluv":[283.003444619748336,176.807585609029246,35.4724176022540263],"hsluv":[283.003444619748336,48.5905204317402166,35.4724176022540263]},"#664499":{"lch":[36.4782980897457563,61.9753280698008169,278.131406705371774],"luv":[36.4782980897457563,8.76603164871553453,-61.3522450974139844],"rgb":[0.4,0.266666666666666663,0.6],"xyz":[0.132955563549256806,0.092590250405919,0.312247513562997736],"hpluv":[278.131406705371774,215.5875082467536,36.4782980897457563],"hsluv":[278.131406705371774,54.8155424382278511,36.4782980897457563]},"#6644aa":{"lch":[37.5923984663849922,74.3597011725147468,275.081334091822],"luv":[37.5923984663849922,6.58602388672208239,-74.0674655150911576],"rgb":[0.4,0.266666666666666663,0.66666666666666663],"xyz":[0.148013256514509361,0.0986133275920201,0.391551363179996281],"hpluv":[275.081334091822,251.001852587777108,37.5923984663849922],"hsluv":[275.081334091822,60.3520360208115179,37.5923984663849922]},"#6644bb":{"lch":[38.8064988843830392,86.3901107279874765,273.04172423936518],"luv":[38.8064988843830392,4.58413310153298603,-86.2684006766171905],"rgb":[0.4,0.266666666666666663,0.733333333333333282],"xyz":[0.165150848621846,0.105468364434954859,0.481809348278638083],"hpluv":[273.04172423936518,282.487278503057098,38.8064988843830392],"hsluv":[273.04172423936518,65.2044789549227346,38.8064988843830392]},"#6644cc":{"lch":[40.1118623747323184,98.0126069922284415,271.608181870646],"luv":[40.1118623747323184,2.75066337520804938,-97.9740015535209],"rgb":[0.4,0.266666666666666663,0.8],"xyz":[0.184443224065567735,0.11318531461244366,0.583415858948908239],"hpluv":[271.608181870646,310.061926380003911,40.1118623747323184],"hsluv":[271.608181870646,73.249037078124374,40.1118623747323184]},"#6644dd":{"lch":[41.4996246628331491,109.23540368219534,270.561113733160255],"luv":[41.4996246628331491,1.06975602599714947,-109.230165429047204],"rgb":[0.4,0.266666666666666663,0.866666666666666696],"xyz":[0.205961549616201278,0.121792644832697194,0.696745706848914237],"hpluv":[270.561113733160255,334.009312605211903,41.4996246628331491],"hsluv":[270.561113733160255,82.0982912580276434,41.4996246628331491]},"#6644ee":{"lch":[42.9610953823040305,120.093362966476874,269.772657810053431],"luv":[42.9610953823040305,-0.476513570908160711,-120.092417593346411],"rgb":[0.4,0.266666666666666663,0.933333333333333348],"xyz":[0.229773729882376043,0.131317516939167239,0.82215652291743746],"hpluv":[269.772657810053431,354.717803858999673,42.9610953823040305],"hsluv":[269.772657810053431,90.971694410809846,42.9610953823040305]},"#6644ff":{"lch":[44.4879743720372502,130.630057251556309,269.16406595263021],"luv":[44.4879743720372502,-1.90579898569535566,-130.61615439053088],"rgb":[0.4,0.266666666666666663,1],"xyz":[0.255944778292207409,0.141785936303099935,0.959990711209219305],"hpluv":[269.16406595263021,372.597392941492103,44.4879743720372502],"hsluv":[269.16406595263021,99.9999999999993463,44.4879743720372502]},"#ddcc00":{"lch":[81.0484811072975475,89.5621409057231119,78.2088923998372394],"luv":[81.0484811072975475,18.3014975440108643,87.6723004789036224],"rgb":[0.866666666666666696,0.8,0],"xyz":[0.514100482595981623,0.585588123937282434,0.0859503143074022424],"hpluv":[78.2088923998372394,197.564965691755532,81.0484811072975475],"hsluv":[78.2088923998372394,100.000000000002245,81.0484811072975475]},"#ddcc11":{"lch":[81.070830830397739,88.588371741804238,78.1407504993947413],"luv":[81.070830830397739,18.2056357525625714,86.6974880530521261],"rgb":[0.866666666666666696,0.8,0.0666666666666666657],"xyz":[0.515112148095618783,0.585992790137137343,0.0912784192721578791],"hpluv":[78.1407504993947413,195.686226016320433,81.070830830397739],"hsluv":[78.1407504993947413,98.8754134531589699,81.070830830397739]},"#ddcc22":{"lch":[81.1122340585289265,86.7947856050049751,78.0111959233441894],"luv":[81.1122340585289265,18.0290607078827385,84.9016358983162149],"rgb":[0.866666666666666696,0.8,0.133333333333333331],"xyz":[0.516987506234095728,0.586742933392528143,0.101155305468137072],"hpluv":[78.0111959233441894,192.214732219338657,81.1122340585289265],"hsluv":[78.0111959233441894,96.8049917221618443,81.1122340585289265]},"#ddcc33":{"lch":[81.1803270736657367,83.8738846457710139,77.7882255314295747],"luv":[81.1803270736657367,17.7414783140301893,81.9760237679585089],"rgb":[0.866666666666666696,0.8,0.2],"xyz":[0.520075256966553545,0.58797803368551127,0.117417459325748208],"hpluv":[77.7882255314295747,186.530107062901806,81.1803270736657367],"hsluv":[77.7882255314295747,93.4358723678778631,81.1803270736657367]},"#ddcc44":{"lch":[81.2784695635313312,79.7261575767135469,77.443216014682],"luv":[81.2784695635313312,17.3330313363216426,77.8191893214074213],"rgb":[0.866666666666666696,0.8,0.266666666666666663],"xyz":[0.524533252210772405,0.589761231783198836,0.140896234278634847],"hpluv":[77.443216014682,178.389435414851135,81.2784695635313312],"hsluv":[77.443216014682,88.6570950843060643,81.2784695635313312]},"#ddcc55":{"lch":[81.4094229919429893,74.303525235023784,76.9333685993953509],"luv":[81.4094229919429893,16.7988406729037365,72.37964364652683],"rgb":[0.866666666666666696,0.8,0.333333333333333315],"xyz":[0.530495666250134335,0.592146197398943586,0.172298281552608762],"hpluv":[76.9333685993953509,167.620308244181615,81.4094229919429893],"hsluv":[76.9333685993953509,82.4185745103993668,81.4094229919429893]},"#ddcc66":{"lch":[81.5755062452221154,67.6049359495878406,76.1891492108976252],"luv":[81.5755062452221154,16.1384724175358123,65.6504156329288548],"rgb":[0.866666666666666696,0.8,0.4],"xyz":[0.538080662023642575,0.595180195708346904,0.212245925959752724],"hpluv":[76.1891492108976252,154.10859642349061,81.5755062452221154],"hsluv":[76.1891492108976252,74.724981631947216,81.5755062452221154]},"#ddcc77":{"lch":[81.7786782860545571,59.6741108071854,75.0887439649445554],"luv":[81.7786782860545571,15.3554995822328237,57.6646176889111857],"rgb":[0.866666666666666696,0.8,0.466666666666666674],"xyz":[0.547394675043844425,0.598905800916427755,0.261299727866150633],"hpluv":[75.0887439649445554,137.792143148878608,81.7786782860545571],"hsluv":[75.0887439649445554,65.6305091544174104,81.7786782860545571]},"#ddcc88":{"lch":[82.020587165389415,50.599662209211,73.3985048227604722],"luv":[82.020587165389415,14.4570002873895778,48.4904213054152891],"rgb":[0.866666666666666696,0.8,0.533333333333333326],"xyz":[0.558535092145788337,0.603361967757205298,0.319972591269722773],"hpluv":[73.3985048227604722,118.661765286999071,82.020587165389415],"hsluv":[73.3985048227604722,55.2326761810852389,82.020587165389415]},"#ddcc99":{"lch":[82.3026016456871901,40.5232855707982438,70.6109505258247765],"luv":[82.3026016456871901,13.4529549720920478,38.2250529884698622],"rgb":[0.866666666666666696,0.8,0.6],"xyz":[0.571592056254861,0.608584753400834511,0.388739268910840707],"hpluv":[70.6109505258247765,96.7842051030752231,82.3026016456871901],"hsluv":[70.6109505258247765,43.6647666281718685,82.3026016456871901]},"#ddccaa":{"lch":[82.6258332993788542,29.6818113573176419,65.4008685536862231],"luv":[82.6258332993788542,12.3555588351715961,26.9879619705157374],"rgb":[0.866666666666666696,0.8,0.66666666666666663],"xyz":[0.586649749220113592,0.614607830586935577,0.468043118527839308],"hpluv":[65.4008685536862231,72.4135107626852,82.6258332993788542],"hsluv":[65.4008685536862231,31.0871436920773085,82.6258332993788542]},"#ddccbb":{"lch":[82.9911533066729419,18.6379527757414252,53.1465475992889],"luv":[82.9911533066729419,11.1784915779275345,14.9135713265793797],"rgb":[0.866666666666666696,0.8,0.733333333333333282],"xyz":[0.603787341327450156,0.621462867429870336,0.55830110362648111],"hpluv":[53.1465475992889,46.5946179098545272,82.9911533066729419],"hsluv":[53.1465475992889,24.678645774572626,82.9911533066729419]},"#ddcccc":{"lch":[83.3992063850657,10.164901186858037,12.1770506300648638],"luv":[83.3992063850657,9.93619558955776228,2.14411598208697862],"rgb":[0.866666666666666696,0.8,0.8],"xyz":[0.62307971677117191,0.629179817607359193,0.659907614296751266],"hpluv":[12.1770506300648638,26.1289592314662436,83.3992063850657],"hsluv":[12.1770506300648638,25.0002112827592455,83.3992063850657]},"#ddccdd":{"lch":[83.8504233095379163,14.1290270468723165,307.715012949259346],"luv":[83.8504233095379163,8.64321103323171513,-11.1769543403501022],"rgb":[0.866666666666666696,0.8,0.866666666666666696],"xyz":[0.644598042321805509,0.637787147827612699,0.773237462196757264],"hpluv":[307.715012949259346,37.4791950150616557,83.8504233095379163],"hsluv":[307.715012949259346,25.214872966603707,83.8504233095379163]},"#ddccee":{"lch":[84.3450329093034,25.9620569722210597,286.361909425528779],"luv":[84.3450329093034,7.31360586969829818,-24.9106316943502399],"rgb":[0.866666666666666696,0.8,0.933333333333333348],"xyz":[0.668410222587980218,0.647312019934082716,0.898648278265280487],"hpluv":[286.361909425528779,71.3464154396222199,84.3450329093034],"hsluv":[286.361909425528779,60.879598082714125,84.3450329093034]},"#ddccff":{"lch":[84.8830740665913623,39.380529428060008,278.705583312848262],"luv":[84.8830740665913623,5.96052452183370107,-38.926831947371717],"rgb":[0.866666666666666696,0.8,1],"xyz":[0.694581270997811639,0.65778043929801544,1.03648246655706222],"hpluv":[278.705583312848262,112.590543218900592,84.8830740665913623],"hsluv":[278.705583312848262,99.9999999999947704,84.8830740665913623]},"#665500":{"lch":[36.5970311204425656,41.5054710368830655,69.2006364019199651],"luv":[36.5970311204425656,14.7384507745119784,38.800543743107859],"rgb":[0.4,0.333333333333333315,0],"xyz":[0.0872772466047234,0.0932201343710592,0.0133963111976744542],"hpluv":[69.2006364019199651,143.912599562803223,36.5970311204425656],"hsluv":[69.2006364019199651,100.000000000002359,36.5970311204425656]},"#665511":{"lch":[36.673028710438345,38.8606023214232366,68.2658014049057869],"luv":[36.673028710438345,14.3901304021596417,36.0980686435250391],"rgb":[0.4,0.333333333333333315,0.0666666666666666657],"xyz":[0.0882889121043605174,0.0936248005709140463,0.0187244161624300839],"hpluv":[68.2658014049057869,134.462776824764262,36.673028710438345],"hsluv":[68.2658014049057869,93.0449405246809107,36.673028710438345]},"#665522":{"lch":[36.8133307706753357,34.1687527519613923,66.2355675996872719],"luv":[36.8133307706753357,13.769229594380441,31.2715842419585037],"rgb":[0.4,0.333333333333333315,0.133333333333333331],"xyz":[0.0901642702428375464,0.0943749438263048607,0.0286013023584092835],"hpluv":[66.2355675996872719,117.777773408929676,36.8133307706753357],"hsluv":[66.2355675996872719,80.6853283069105629,36.8133307706753357]},"#665533":{"lch":[37.0427251812615097,27.0303271109949854,61.7081001991288645],"luv":[37.0427251812615097,12.8113945713483854,23.8014023297917383],"rgb":[0.4,0.333333333333333315,0.2],"xyz":[0.09325202097529528,0.0956100441192879735,0.0448634562160204267],"hpluv":[61.7081001991288645,92.5950345984193177,37.0427251812615097],"hsluv":[61.7081001991288645,61.7209513910547045,37.0427251812615097]},"#665544":{"lch":[37.3704580906404473,18.1024774089589755,50.3425610862832542],"luv":[37.3704580906404473,11.5529306171195891,13.9366237840407656],"rgb":[0.4,0.333333333333333315,0.266666666666666663],"xyz":[0.0977100162195141536,0.0973932422169755535,0.0683422311689070583],"hpluv":[50.3425610862832542,61.4679768710498351,37.3704580906404473],"hsluv":[50.3425610862832542,37.0117339514184067,37.3704580906404473]},"#665555":{"lch":[37.8025949068387348,10.2943047784276782,12.1770506300631105],"luv":[37.8025949068387348,10.0626876598879917,2.1714115065313786],"rgb":[0.4,0.333333333333333315,0.333333333333333315],"xyz":[0.103672430258876153,0.0997782078327203864,0.0997442784428809737],"hpluv":[12.1770506300631105,34.5553054430909654,37.8025949068387348],"hsluv":[12.1770506300631105,8.09737912949257321,37.8025949068387348]},"#665566":{"lch":[38.3424918197480693,13.7697499972876347,307.715012949250308],"luv":[38.3424918197480693,8.42342892447929,-10.8927434626015351],"rgb":[0.4,0.333333333333333315,0.4],"xyz":[0.111257426032384324,0.102812206142123705,0.139691922850024935],"hpluv":[307.715012949250308,45.570631638882567,38.3424918197480693],"hsluv":[307.715012949250308,15.7660506346962208,38.3424918197480693]},"#665577":{"lch":[38.9911218270375812,25.5692820710091411,285.225395910208761],"luv":[38.9911218270375812,6.71492531026355,-24.671805035392353],"rgb":[0.4,0.333333333333333315,0.466666666666666674],"xyz":[0.120571439052586243,0.106537811350204514,0.188745724756422845],"hpluv":[285.225395910208761,83.2131821356252885,38.9911218270375812],"hsluv":[285.225395910208761,23.5948697041559434,38.9911218270375812]},"#665588":{"lch":[39.7473800461840554,39.003702064123587,277.369365694294345],"luv":[39.7473800461840554,5.00282395952989312,-38.6815269493963],"rgb":[0.4,0.333333333333333315,0.533333333333333326],"xyz":[0.131711856154530071,0.110993978190982112,0.247418588159995],"hpluv":[277.369365694294345,124.519293959659265,39.7473800461840554],"hsluv":[277.369365694294345,31.2388068533835614,39.7473800461840554]},"#665599":{"lch":[40.6084045881889466,52.6763518020623636,273.629018089310307],"luv":[40.6084045881889466,3.33420095564239061,-52.5707251534733189],"rgb":[0.4,0.333333333333333315,0.6],"xyz":[0.144768820263602771,0.11621676383461127,0.316185265801112947],"hpluv":[273.629018089310307,164.603508765513965,40.6084045881889466],"hsluv":[273.629018089310307,39.2894117268144569,40.6084045881889466]},"#6655aa":{"lch":[41.5699140891343575,66.1399121177165,271.505962745252077],"luv":[41.5699140891343575,1.73822184255944534,-66.1170670838121168],"rgb":[0.4,0.333333333333333315,0.66666666666666663],"xyz":[0.159826513228855327,0.122239841020712364,0.395489115418111492],"hpluv":[271.505962745252077,201.894186201954597,41.5699140891343575],"hsluv":[271.505962745252077,49.6682832978127067,41.5699140891343575]},"#6655bb":{"lch":[42.6265484117568647,79.2031960637105499,270.166039680829499],"luv":[42.6265484117568647,0.229525718995523903,-79.2028634876978],"rgb":[0.4,0.333333333333333315,0.733333333333333282],"xyz":[0.176964105336191974,0.129094877863647123,0.485747100516753294],"hpluv":[270.166039680829499,235.777232293519603,42.6265484117568647],"hsluv":[270.166039680829499,59.8653820834470309,42.6265484117568647]},"#6655cc":{"lch":[43.7721949853351333,91.7929775852419,269.258674658723919],"luv":[43.7721949853351333,-1.18763654850412936,-91.7852943199147688],"rgb":[0.4,0.333333333333333315,0.8],"xyz":[0.1962564807799137,0.136811828041135924,0.58735361118702345],"hpluv":[269.258674658723919,266.103421792879146,43.7721949853351333],"hsluv":[269.258674658723919,69.9112236392489734,43.7721949853351333]},"#6655dd":{"lch":[45.0002850881211458,103.899953671233533,268.61259940679895],"luv":[45.0002850881211458,-2.51566121975990953,-103.869494181457682],"rgb":[0.4,0.333333333333333315,0.866666666666666696],"xyz":[0.217774806330547244,0.145419158261389458,0.700683459087029448],"hpluv":[268.61259940679895,292.98097185143456,45.0002850881211458],"hsluv":[268.61259940679895,79.8793625185682714,45.0002850881211458]},"#6655ee":{"lch":[46.3040490971424106,115.549020689755764,268.134901078425969],"luv":[46.3040490971424106,-3.7607010001107648,-115.487805894602445],"rgb":[0.4,0.333333333333333315,0.933333333333333348],"xyz":[0.241586986596722,0.154944030367859503,0.826094275155552671],"hpluv":[268.134901078425969,316.655201018988919,46.3040490971424106],"hsluv":[268.134901078425969,89.8701820385079344,46.3040490971424106]},"#6655ff":{"lch":[47.6767252326213651,126.781348408818275,267.771145841725911],"luv":[47.6767252326213651,-4.93065761335473951,-126.685432942615918],"rgb":[0.4,0.333333333333333315,1],"xyz":[0.267758035006553374,0.165412449731792199,0.963928463447334516],"hpluv":[267.771145841725911,337.433561350206048,47.6767252326213651],"hsluv":[267.771145841725911,99.9999999999992468,47.6767252326213651]},"#dddd00":{"lch":[85.547159878993142,94.3072427966830844,85.8743202181747449],"luv":[85.547159878993142,6.78488618903739749,94.0628585750738466],"rgb":[0.866666666666666696,0.866666666666666696,0],"xyz":[0.556734473143156827,0.670856105031634,0.100161644489793561],"hpluv":[85.8743202181747449,283.614606809988061,85.547159878993142],"hsluv":[85.8743202181747449,100.000000000002203,85.547159878993142]},"#dddd11":{"lch":[85.5675738163798627,93.4011806547303394,85.8743202181746881],"luv":[85.5675738163798627,6.71970001318247423,93.159144368282],"rgb":[0.866666666666666696,0.866666666666666696,0.0666666666666666657],"xyz":[0.557746138642794,0.671260771231488862,0.105489749454549198],"hpluv":[85.8743202181746881,281.335749103468061,85.5675738163798627],"hsluv":[85.8743202181746881,99.0156164862488,85.5675738163798627]},"#dddd22":{"lch":[85.6053941241358558,91.7307060091609401,85.8743202181746739],"luv":[85.6053941241358558,6.59951857201479086,91.4929985275198447],"rgb":[0.866666666666666696,0.866666666666666696,0.133333333333333331],"xyz":[0.559621496781270933,0.672010914486879662,0.11536663565052839],"hpluv":[85.8743202181746739,277.118842420723468,85.6053941241358558],"hsluv":[85.8743202181746739,97.2017654403352083,85.6053941241358558]},"#dddd33":{"lch":[85.667603455332241,89.0058006932873,85.8743202181745602],"luv":[85.667603455332241,6.4034766573555908,88.775154428206335],"rgb":[0.866666666666666696,0.866666666666666696,0.2],"xyz":[0.56270924751372875,0.673246014779862789,0.131628789508139526],"hpluv":[85.8743202181745602,270.196330508983522,85.667603455332241],"hsluv":[85.8743202181745602,94.2458512979473113,85.667603455332241]},"#dddd44":{"lch":[85.7572852094861418,85.1265937151141117,85.8743202181744607],"luv":[85.7572852094861418,6.12438910193468278,84.9059998802570419],"rgb":[0.866666666666666696,0.866666666666666696,0.266666666666666663],"xyz":[0.567167242757947609,0.675029212877550355,0.155107564461026165],"hpluv":[85.8743202181744607,260.24482525674506,85.7572852094861418],"hsluv":[85.8743202181744607,90.0440000232135844,85.7572852094861418]},"#dddd55":{"lch":[85.8769849033878074,80.0369945631262,85.874320218174276],"luv":[85.8769849033878074,5.75822050268421481,79.8295897229865545],"rgb":[0.866666666666666696,0.866666666666666696,0.333333333333333315],"xyz":[0.573129656797309539,0.677414178493295105,0.18650961173500008],"hpluv":[85.874320218174276,247.008869171162701,85.8769849033878074],"hsluv":[85.874320218174276,84.5423921226573327,85.8769849033878074]},"#dddd66":{"lch":[86.0288537292730098,73.7198014533942398,85.8743202181739775],"luv":[86.0288537292730098,5.30373328608645522,73.5287667485177252],"rgb":[0.866666666666666696,0.866666666666666696,0.4],"xyz":[0.58071465257081778,0.680448176802698423,0.226457256142144042],"hpluv":[85.8743202181739775,230.281095596483937,86.0288537292730098],"hsluv":[85.8743202181739775,77.7321300368988,86.0288537292730098]},"#dddd77":{"lch":[86.2147251389940834,66.1931358813644124,85.8743202181736365],"luv":[86.2147251389940834,4.76223119383214133,66.0216054929389315],"rgb":[0.866666666666666696,0.866666666666666696,0.466666666666666674],"xyz":[0.59002866559101963,0.684173782010779274,0.275511058048541924],"hpluv":[85.8743202181736365,209.886373280136951,86.2147251389940834],"hsluv":[85.8743202181736365,69.6453389130317362,86.2147251389940834]},"#dddd88":{"lch":[86.4361603707972,57.5066396271378224,85.8743202181730823],"luv":[86.4361603707972,4.13728567831694072,57.3576190965201391],"rgb":[0.866666666666666696,0.866666666666666696,0.533333333333333326],"xyz":[0.601169082692963541,0.688629948851556817,0.334183921452114119],"hpluv":[85.8743202181730823,185.665493576193455,86.4361603707972],"hsluv":[85.8743202181730823,60.3508056243124429,86.4361603707972]},"#dddd99":{"lch":[86.6944777431662,47.7369558995854888,85.8743202181722154],"luv":[86.6944777431662,3.43441079587341314,47.613252157820078],"rgb":[0.866666666666666696,0.866666666666666696,0.6],"xyz":[0.614226046802036185,0.693852734495186,0.402950599093232054],"hpluv":[85.8743202181722154,157.456397081560084,86.6944777431662],"hsluv":[85.8743202181722154,49.9486591868920939,86.6944777431662]},"#ddddaa":{"lch":[86.990772885999732,36.9824894935128,85.874320218170638],"luv":[86.990772885999732,2.66068622896724838,36.886654469181245],"rgb":[0.866666666666666696,0.866666666666666696,0.66666666666666663],"xyz":[0.629283739767288797,0.699875811681287097,0.482254448710230599],"hpluv":[85.874320218170638,125.071764704863014,86.990772885999732],"hsluv":[85.874320218170638,38.5641267001819443,86.990772885999732]},"#ddddbb":{"lch":[87.3259337660435477,25.3576808227713499,85.8743202181676821],"luv":[87.3259337660435477,1.82434533444747116,25.2919698878957568],"rgb":[0.866666666666666696,0.866666666666666696,0.733333333333333282],"xyz":[0.64642133187462536,0.706730848524221855,0.572512433808872401],"hpluv":[85.8743202181676821,88.2719508819342735,87.3259337660435477],"hsluv":[85.8743202181676821,26.340671416181145,87.3259337660435477]},"#ddddcc":{"lch":[87.7006527393466797,12.9871390430395461,85.8743202181585445],"luv":[87.7006527393466797,0.934353054076054512,12.9534846621895881],"rgb":[0.866666666666666696,0.866666666666666696,0.8],"xyz":[0.665713707318347114,0.714447798701710712,0.674118944479142557],"hpluv":[85.8743202181585445,46.7319159493201113,87.7006527393466797],"hsluv":[85.8743202181585445,13.4329442518860063,87.7006527393466797]},"#dddddd":{"lch":[88.1154369871094,4.67545248961294327e-12,0],"luv":[88.1154369871094,4.4193702762792188e-12,1.52611347670073729e-12],"rgb":[0.866666666666666696,0.866666666666666696,0.866666666666666696],"xyz":[0.687232032868980713,0.723055128921964219,0.787448792379148554],"hpluv":[0,1.74708563976297451e-11,88.1154369871094],"hsluv":[0,1.74437740136320375e-11,88.1154369871094]},"#ddddee":{"lch":[88.5706181797242209,13.4751686036456029,265.874320218195521],"luv":[88.5706181797242209,-0.969464090371862097,-13.4402495614536726],"rgb":[0.866666666666666696,0.866666666666666696,0.933333333333333348],"xyz":[0.711044213135155423,0.732580001028434236,0.912859608447671778],"hpluv":[265.874320218195521,52.5550848411252431,88.5706181797242209],"hsluv":[265.874320218195521,47.1269490590101725,88.5706181797242209]},"#ddddff":{"lch":[89.0663618949558753,27.3146757005029208,265.874320218186369],"luv":[89.0663618949558753,-1.9651403266809826,-27.2438934831293338],"rgb":[0.866666666666666696,0.866666666666666696,1],"xyz":[0.737215261544986844,0.743048420392367,1.05069379673945362],"hpluv":[265.874320218186369,111.815120511018762,89.0663618949558753],"hsluv":[265.874320218186369,99.9999999999922125,89.0663618949558753]},"#666600":{"lch":[41.7321583215394583,46.0055575524193685,85.8743202181747449],"luv":[41.7321583215394583,3.30984623025532709,45.8863404908370924],"rgb":[0.4,0.4,0],"xyz":[0.102305304310569861,0.123276249782752534,0.0184056637662898],"hpluv":[85.8743202181747449,139.887458074797365,41.7321583215394583],"hsluv":[85.8743202181747449,100.000000000002203,41.7321583215394583]},"#666611":{"lch":[41.7952597887023742,43.6298127640598423,85.8743202181746],"luv":[41.7952597887023742,3.13892449057558931,43.5167521176544625],"rgb":[0.4,0.4,0.0666666666666666657],"xyz":[0.103316969810206979,0.123680915982607387,0.0237337687310454348],"hpluv":[85.8743202181746,132.463323325332908,41.7952597887023742],"hsluv":[85.8743202181746,94.6927802880713756,41.7952597887023742]},"#666622":{"lch":[41.9118699845736913,39.3503176022612067,85.874320218174276],"luv":[41.9118699845736913,2.83103840719259514,39.248346677737],"rgb":[0.4,0.4,0.133333333333333331],"xyz":[0.105192327948684008,0.124431059237998201,0.0336106549270246274],"hpluv":[85.874320218174276,119.138061739500813,41.9118699845736913],"hsluv":[85.874320218174276,85.1670788640685288,41.9118699845736913]},"#666633":{"lch":[42.1028501842444953,32.6344620115447057,85.8743202181736507],"luv":[42.1028501842444953,2.34786962297492563,32.5498943011565842],"rgb":[0.4,0.4,0.2],"xyz":[0.108280078681141742,0.125666159530981314,0.0498728087846357776],"hpluv":[85.8743202181736507,98.3567766096709306,42.1028501842444953],"hsluv":[85.8743202181736507,70.3113616926845,42.1028501842444953]},"#666644":{"lch":[42.3763861696741557,23.5947988734222314,85.8743202181723575],"luv":[42.3763861696741557,1.69751569722617934,23.5336562041455402],"rgb":[0.4,0.4,0.266666666666666663],"xyz":[0.112738073925360616,0.127449357628668908,0.0733515837375224161],"hpluv":[85.8743202181723575,70.6531759312171346,42.3763861696741557],"hsluv":[85.8743202181723575,50.5071554688203506,42.3763861696741557]},"#666655":{"lch":[42.7382714661199543,12.562340839470254,85.87432021816781],"luv":[42.7382714661199543,0.903791165304248856,12.5297872646162745],"rgb":[0.4,0.4,0.333333333333333315],"xyz":[0.118700487964722615,0.129834323244413741,0.104753631011496318],"hpluv":[85.87432021816781,37.2986356199978459,42.7382714661199543],"hsluv":[85.87432021816781,26.6633164497530721,42.7382714661199543]},"#666666":{"lch":[43.1922895629847048,2.27708065554704512e-12,0],"luv":[43.1922895629847048,2.15069538500574498e-12,7.48067960001998255e-13],"rgb":[0.4,0.4,0.4],"xyz":[0.126285483738230786,0.132868321553817031,0.144701275418640279],"hpluv":[0,6.68977504875838914e-12,43.1922895629847048],"hsluv":[0,1.91542116883063395e-12,43.1922895629847048]},"#666677":{"lch":[43.7404449074606489,13.5883126365404472,265.874320218186085],"luv":[43.7404449074606489,-0.977604179760566572,-13.5531003971814314],"rgb":[0.4,0.4,0.466666666666666674],"xyz":[0.135599496758432692,0.136593926761897855,0.193755077325038189],"hpluv":[265.874320218186085,39.4204575510779804,43.7404449074606489],"hsluv":[265.874320218186085,10.3527957183817456,43.7404449074606489]},"#666688":{"lch":[44.3831523723879684,27.7327571842679852,265.874320218181708],"luv":[44.3831523723879684,-1.9952189844931838,-27.660891566352042],"rgb":[0.4,0.4,0.533333333333333326],"xyz":[0.146739913860376547,0.141050093602675453,0.252427940728610356],"hpluv":[265.874320218181708,79.2892354857961692,44.3831523723879684],"hsluv":[265.874320218181708,21.2254167484079588,44.3831523723879684]},"#666699":{"lch":[45.1194249231942308,42.0446421145154,265.87432021818023],"luv":[45.1194249231942308,-3.02488020162380478,-41.9356892193690598],"rgb":[0.4,0.4,0.6],"xyz":[0.159796877969449247,0.14627287924630461,0.321194618369728291],"hpluv":[265.87432021818023,118.245992523098394,45.1194249231942308],"hsluv":[265.87432021818023,32.3647541960069702,45.1194249231942308]},"#6666aa":{"lch":[45.9470714788517682,56.2348015337582652,265.874320218179548],"luv":[45.9470714788517682,-4.04578393932889835,-56.0890767962662125],"rgb":[0.4,0.4,0.66666666666666663],"xyz":[0.174854570934701803,0.152295956432405705,0.400498467986726892],"hpluv":[265.874320218179548,155.305436018888514,45.9470714788517682],"hsluv":[265.874320218179548,43.5990379455573205,45.9470714788517682]},"#6666bb":{"lch":[46.8629040956598786,70.1103551977131,265.874320218179093],"luv":[46.8629040956598786,-5.04405352741049562,-69.9286738753289541],"rgb":[0.4,0.4,0.733333333333333282],"xyz":[0.191992163042038422,0.159150993275340463,0.490756453085368638],"hpluv":[265.874320218179093,189.841997809706953,46.8629040956598786],"hsluv":[265.874320218179093,54.8353857399755285,46.8629040956598786]},"#6666cc":{"lch":[47.8629477245616854,83.5592716582008,265.874320218178866],"luv":[47.8629477245616854,-6.01162892081844,-83.3427393224351505],"rgb":[0.4,0.4,0.8],"xyz":[0.211284538485760176,0.166867943452829265,0.592362963755638794],"hpluv":[265.874320218178866,221.531011478982748,47.8629477245616854],"hsluv":[265.874320218178866,66.0482344892977693,47.8629477245616854]},"#6666dd":{"lch":[48.9426439028117102,96.5306872715973583,265.874320218178696],"luv":[48.9426439028117102,-6.94485076081307,-96.2805413000828736],"rgb":[0.4,0.4,0.866666666666666696],"xyz":[0.23280286403639372,0.175475273673082799,0.705692811655644792],"hpluv":[265.874320218178696,250.274901054084751,48.9426439028117102],"hsluv":[265.874320218178696,77.2646968282616911,48.9426439028117102]},"#6666ee":{"lch":[50.0970402589656203,109.016062738443594,265.874320218178525],"luv":[50.0970402589656203,-7.84310469187671711,-108.73356263723052],"rgb":[0.4,0.4,0.933333333333333348],"xyz":[0.256615044302568429,0.185000145779552844,0.831103627724168],"hpluv":[265.874320218178525,276.132643737939816,50.0970402589656203],"hsluv":[265.874320218178525,88.5507283896609181,50.0970402589656203]},"#6666ff":{"lch":[51.3209595583197142,121.033610519319112,265.874320218178411],"luv":[51.3209595583197142,-8.70770100014002502,-120.719968599376287],"rgb":[0.4,0.4,1],"xyz":[0.28278609271239985,0.19546856514348554,0.96893781601594986],"hpluv":[265.874320218178411,299.261292593223402,51.3209595583197142],"hsluv":[265.874320218178411,99.9999999999991616,51.3209595583197142]},"#ddee00":{"lch":[90.1008574130140261,100.518542770188731,92.3281002120423295],"luv":[90.1008574130140261,-4.08324753875312307,100.435574027231638],"rgb":[0.866666666666666696,0.933333333333333348,0],"xyz":[0.603913249483671644,0.765213657712664919,0.115887903269964759],"hpluv":[92.3281002120423295,458.324419080212692,90.1008574130140261],"hsluv":[92.3281002120423295,100.000000000002288,90.1008574130140261]},"#ddee11":{"lch":[90.1195571422023676,99.6821059706602739,92.3717344777628284],"luv":[90.1195571422023676,-4.12512016496088219,99.5967149778072667],"rgb":[0.866666666666666696,0.933333333333333348,0.0666666666666666657],"xyz":[0.604924914983308804,0.765618323912519827,0.121216008234720396],"hpluv":[92.3717344777628284,455.439701471196656,90.1195571422023676],"hsluv":[92.3717344777628284,99.1349582088955827,90.1195571422023676]},"#ddee22":{"lch":[90.1542040339558213,98.139145338163118,92.4541942657322409],"luv":[90.1542040339558213,-4.20238430415396635,98.0491295925940562],"rgb":[0.866666666666666696,0.933333333333333348,0.133333333333333331],"xyz":[0.606800273121785749,0.766368467167910628,0.131092894430699575],"hpluv":[92.4541942657322409,450.094002053356689,90.1542040339558213],"hsluv":[92.4541942657322409,97.539848527320828,90.1542040339558213]},"#ddee33":{"lch":[90.2112004280082402,95.6198982889531237,92.5945991605726562],"luv":[90.2112004280082402,-4.32860020636881337,95.5218727257959728],"rgb":[0.866666666666666696,0.933333333333333348,0.2],"xyz":[0.609888023854243566,0.767603567460893754,0.147355048288310725],"hpluv":[92.5945991605726562,441.296742170845221,90.2112004280082402],"hsluv":[92.5945991605726562,94.9371734060285348,90.2112004280082402]},"#ddee44":{"lch":[90.2933822328294582,92.028546743238266,92.808164678773025],"luv":[90.2933822328294582,-4.50867173729536486,91.9180357429253689],"rgb":[0.866666666666666696,0.933333333333333348,0.266666666666666663],"xyz":[0.614346019098462426,0.76938676555858132,0.170833823241197363],"hpluv":[92.808164678773025,428.602609406071736,90.2933822328294582],"hsluv":[92.808164678773025,91.2305485856041827,90.2933822328294582]},"#ddee55":{"lch":[90.4030992965535,87.3081168904988658,93.1158428735316477],"luv":[90.4030992965535,-4.74562541158387852,87.1790474507375137],"rgb":[0.866666666666666696,0.933333333333333348,0.333333333333333315],"xyz":[0.620308433137824355,0.77177173117432607,0.202235870515171279],"hpluv":[93.1158428735316477,411.63119840797242,90.4030992965535],"hsluv":[93.1158428735316477,86.365058197250562,90.4030992965535]},"#ddee66":{"lch":[90.5423480313319828,81.4363754503924,93.5488244177654451],"luv":[90.5423480313319828,-5.04083628618753,81.2802141731499717],"rgb":[0.866666666666666696,0.933333333333333348,0.4],"xyz":[0.627893428911332596,0.774805729483729388,0.242183514922315241],"hpluv":[93.5488244177654451,390.03815237863023,90.5423480313319828],"hsluv":[93.5488244177654451,80.3228278296054583,90.5423480313319828]},"#ddee77":{"lch":[90.7128424721769449,74.4235139877598613,94.1564113073248],"luv":[90.7128424721769449,-5.39417557361030209,74.2277731322134855],"rgb":[0.866666666666666696,0.933333333333333348,0.466666666666666674],"xyz":[0.637207441931534446,0.77853133469181024,0.291237316828713122],"hpluv":[94.1564113073248,363.492124647987794,90.7128424721769449],"hsluv":[94.1564113073248,73.1200108954656116,90.7128424721769449]},"#ddee88":{"lch":[90.9160566530372449,66.3104835404903099,95.0215233218939801],"luv":[90.9160566530372449,-5.80415396856009735,66.0559764448523197],"rgb":[0.866666666666666696,0.933333333333333348,0.533333333333333326],"xyz":[0.648347859033478358,0.782987501532587782,0.349910180232285317],"hpluv":[95.0215233218939801,331.65301907995223,90.9160566530372449],"hsluv":[95.0215233218939801,64.803658473982523,90.9160566530372449]},"#ddee99":{"lch":[91.1532518637430798,57.1683554138076389,96.2947128608995513],"luv":[91.1532518637430798,-6.26808654843775237,56.8236918172404799],"rgb":[0.866666666666666696,0.933333333333333348,0.6],"xyz":[0.661404823142551,0.788210287176217,0.418676857873403252],"hpluv":[96.2947128608995513,294.152965661212647,91.1532518637430798],"hsluv":[96.2947128608995513,55.4479539090275679,91.1532518637430798]},"#ddeeaa":{"lch":[91.4254953447680805,47.1012792006961263,98.2790075719046712],"luv":[91.4254953447680805,-6.78228473243696595,46.6104185365255219],"rgb":[0.866666666666666696,0.933333333333333348,0.66666666666666663],"xyz":[0.676462516107803613,0.794233364362318062,0.497980707490401797],"hpluv":[98.2790075719046712,250.593114601078071,91.4254953447680805],"hsluv":[98.2790075719046712,45.1497304611624699,91.4254953447680805]},"#ddeebb":{"lch":[91.7336739482950634,36.2629153409390739,101.681625346389353],"luv":[91.7336739482950634,-7.34227032126066,35.5118303605101318],"rgb":[0.866666666666666696,0.933333333333333348,0.733333333333333282],"xyz":[0.693600108215140176,0.80108840120525282,0.588238692589043599],"hpluv":[101.681625346389353,200.613962446551909,91.7336739482950634],"hsluv":[101.681625346389353,34.0234190840686495,91.7336739482950634]},"#ddeecc":{"lch":[92.0785048140775189,24.9340669502590622,108.575873850927678],"luv":[92.0785048140775189,-7.94300120518182506,23.6350677285782567],"rgb":[0.866666666666666696,0.933333333333333348,0.8],"xyz":[0.712892483658861931,0.808805351382741677,0.689845203259313755],"hpluv":[108.575873850927678,144.339382081965653,92.0785048140775189],"hsluv":[108.575873850927678,22.1956929245148693,92.0785048140775189]},"#ddeedd":{"lch":[92.4605443140240908,14.0242187757329084,127.71501294922345],"luv":[92.4605443140240908,-8.57909621466854766,11.0940443666446207],"rgb":[0.866666666666666696,0.933333333333333348,0.866666666666666696],"xyz":[0.73441080920949553,0.817412681602995184,0.803175051159319753],"hpluv":[127.71501294922345,85.5555802205660854,92.4605443140240908],"hsluv":[127.71501294922345,19.0167034911391681,92.4605443140240908]},"#ddeeee":{"lch":[92.8801960589335636,9.45784403502816851,192.177050630058346],"luv":[92.8801960589335636,-9.24504689815110403,-1.99497409554724747],"rgb":[0.866666666666666696,0.933333333333333348,0.933333333333333348],"xyz":[0.758222989475670239,0.826937553709465201,0.928585867227843],"hpluv":[192.177050630058346,61.3009405779386327,92.8801960589335636],"hsluv":[192.177050630058346,16.5065503962475049,92.8801960589335636]},"#ddeeff":{"lch":[93.3377184761608305,18.4254994321377019,237.36941304521946],"luv":[93.3377184761608305,-9.93540601395951306,-15.5173044263971267],"rgb":[0.866666666666666696,0.933333333333333348,1],"xyz":[0.78439403788550166,0.837405973073397925,1.06642005551962482],"hpluv":[237.36941304521946,128.083838047846456,93.3377184761608305],"hsluv":[237.36941304521946,99.9999999999860592,93.3377184761608305]},"#667700":{"lch":[46.9985837429297462,53.5023535392226,97.7743932102929705],"luv":[46.9985837429297462,-7.23741162388150272,53.0105810873873509],"rgb":[0.4,0.466666666666666674,0],"xyz":[0.12075904236398749,0.160183725889588319,0.0245569097840955056],"hpluv":[97.7743932102929705,144.453291553004675,46.9985837429297462],"hsluv":[97.7743932102929705,100.000000000002416,46.9985837429297462]},"#667711":{"lch":[47.0515894602548315,51.4525286527524344,98.1592061252685681],"luv":[47.0515894602548315,-7.3023584206057679,50.9317019768564],"rgb":[0.4,0.466666666666666674,0.0666666666666666657],"xyz":[0.121770707863624608,0.160588392089443172,0.0298850147488511353],"hpluv":[98.1592061252685681,138.762383385982389,47.0515894602548315],"hsluv":[98.1592061252685681,95.8888552433840573,47.0515894602548315]},"#667722":{"lch":[47.1496128779850068,47.7434140964333835,98.9413563019921],"luv":[47.1496128779850068,-7.4204465613794337,47.1632331632727],"rgb":[0.4,0.466666666666666674,0.133333333333333331],"xyz":[0.123646066002101637,0.161338535344834,0.0397619009448303348],"hpluv":[98.9413563019921,128.491579290861381,47.1496128779850068],"hsluv":[98.9413563019921,88.4562635009272071,47.1496128779850068]},"#667733":{"lch":[47.3103471969426579,41.884713336750373,100.466311561708949],"luv":[47.3103471969426579,-7.6086666810921777,41.1878307590699961],"rgb":[0.4,0.466666666666666674,0.2],"xyz":[0.126733816734559357,0.162573635637817099,0.0560240548024414781],"hpluv":[100.466311561708949,112.341117260385403,47.3103471969426579],"hsluv":[100.466311561708949,76.7252257071794,47.3103471969426579]},"#667744":{"lch":[47.5409803755201068,33.9506682862991624,103.399633201782777],"luv":[47.5409803755201068,-7.86778476785512915,33.0264415269496823],"rgb":[0.4,0.466666666666666674,0.266666666666666663],"xyz":[0.131191811978778244,0.164356833735504693,0.0795028297553281166],"hpluv":[103.399633201782777,90.6190532449782324,47.5409803755201068],"hsluv":[103.399633201782777,60.8161329795325543,47.5409803755201068]},"#667755":{"lch":[47.8468512336942808,24.3055974565694441,109.700167733355244],"luv":[47.8468512336942808,-8.19336864569332768,22.8829800934354815],"rgb":[0.4,0.466666666666666674,0.333333333333333315],"xyz":[0.137154226018140257,0.166741799351249526,0.110904877029302018],"hpluv":[109.700167733355244,64.4602914823941262,47.8468512336942808],"hsluv":[109.700167733355244,41.23982633361328,47.8468512336942808]},"#667766":{"lch":[48.2317738399223543,14.0211946941261125,127.715012949232488],"luv":[48.2317738399223543,-8.57724628010491408,11.0916521267580634],"rgb":[0.4,0.466666666666666674,0.4],"xyz":[0.144739221791648415,0.169775797660652816,0.15085252143644598],"hpluv":[127.715012949232488,36.8885098590324958,48.2317738399223543],"hsluv":[127.715012949232488,18.7828263722028552,48.2317738399223543]},"#667777":{"lch":[48.6982180758881356,9.21652694043341,192.177050630059739],"luv":[48.6982180758881356,-9.00915932709454736,-1.94407228846053126],"rgb":[0.4,0.466666666666666674,0.466666666666666674],"xyz":[0.154053234811850348,0.17350140286873364,0.199906323342843889],"hpluv":[192.177050630059739,24.0156061835451808,48.6982180758881356],"hsluv":[192.177050630059739,23.9216020554503501,48.6982180758881356]},"#667788":{"lch":[49.2474401880289605,18.4334880243097601,239.056580638027469],"luv":[49.2474401880289605,-9.47834019220879398,-15.8099509152663327],"rgb":[0.4,0.466666666666666674,0.533333333333333326],"xyz":[0.165193651913794148,0.177957569709511237,0.258579186746416056],"hpluv":[239.056580638027469,47.4966726259429564,49.2474401880289605],"hsluv":[239.056580638027469,29.274081353383373,49.2474401880289605]},"#667799":{"lch":[49.8796002039077422,31.7351192214463786,251.680675473596239],"luv":[49.8796002039077422,-9.97474964621831,-30.126768188683684],"rgb":[0.4,0.466666666666666674,0.6],"xyz":[0.178250616022866876,0.183180355353140395,0.327345864387534],"hpluv":[251.680675473596239,80.734004933806176,49.8796002039077422],"hsluv":[251.680675473596239,34.661761655835349,49.8796002039077422]},"#6677aa":{"lch":[50.5938810850088174,45.7960576637453798,256.758518919433186],"luv":[50.5938810850088174,-10.4898463625666416,-44.5784928057335676],"rgb":[0.4,0.466666666666666674,0.66666666666666663],"xyz":[0.193308308988119404,0.18920343253924149,0.406649714004532592],"hpluv":[256.758518919433186,114.860161977636537,50.5938810850088174],"hsluv":[256.758518919433186,39.9381656359214858,50.5938810850088174]},"#6677bb":{"lch":[51.388614147457119,59.9444468574027738,259.409682348511467],"luv":[51.388614147457119,-11.0169047239158306,-58.9233783768730106],"rgb":[0.4,0.466666666666666674,0.733333333333333282],"xyz":[0.210445901095456078,0.196058469382176248,0.496907699103174338],"hpluv":[259.409682348511467,148.020333314730891,51.388614147457119],"hsluv":[259.409682348511467,49.2101017344363356,51.388614147457119]},"#6677cc":{"lch":[52.2614099661724225,73.9004259234932306,261.00752312302825],"luv":[52.2614099661724225,-11.5509895931656974,-72.9921063615257566],"rgb":[0.4,0.466666666666666674,0.8],"xyz":[0.229738276539177805,0.20377541955966505,0.598514209773444494],"hpluv":[261.00752312302825,179.434168102703751,52.2614099661724225],"hsluv":[261.00752312302825,61.6581230008595327,52.2614099661724225]},"#6677dd":{"lch":[53.2092913421323,87.5170631601914266,262.060353074135],"luv":[53.2092913421323,-12.0887245225321198,-86.6781349799548],"rgb":[0.4,0.466666666666666674,0.866666666666666696],"xyz":[0.251256602089811376,0.212382749779918584,0.711844057673450492],"hpluv":[262.060353074135,208.710638687620559,53.2092913421323],"hsluv":[262.060353074135,74.2459971892304083,53.2092913421323]},"#6677ee":{"lch":[54.2288239257805884,100.719531231348427,262.797438231409785],"luv":[54.2288239257805884,-12.6279723106459851,-99.9247631309883531],"rgb":[0.4,0.466666666666666674,0.933333333333333348],"xyz":[0.275068782355986086,0.221907621886388629,0.837254873741973715],"hpluv":[262.797438231409785,235.68005803746027,54.2288239257805884],"hsluv":[262.797438231409785,87.0042080584200193,54.2288239257805884]},"#6677ff":{"lch":[55.3162401631211793,113.47857319487936,263.336661992011841],"luv":[55.3162401631211793,-13.1675101506557386,-112.712036849566218],"rgb":[0.4,0.466666666666666674,1],"xyz":[0.301239830765817507,0.232376041250321325,0.97508906203375556],"hpluv":[263.336661992011841,260.315806593762318,55.3162401631211793],"hsluv":[263.336661992011841,99.999999999999,55.3162401631211793]},"#ddff00":{"lch":[94.69236188875891,107.73563953931891,97.6513944636985],"luv":[94.69236188875891,-14.3445112693176284,106.77641604488548],"rgb":[0.866666666666666696,1,0],"xyz":[0.65576562191334542,0.868918402572014,0.13317202741318887],"hpluv":[97.6513944636985,949.977135711580445,94.69236188875891],"hsluv":[97.6513944636985,100.000000000002302,94.69236188875891]},"#ddff11":{"lch":[94.7095428290633237,106.965998536257018,97.7198690947758308],"luv":[94.7095428290633237,-14.3687245726656343,105.996531061225838],"rgb":[0.866666666666666696,1,0.0666666666666666657],"xyz":[0.65677728741298258,0.869323068771868934,0.138500132377944507],"hpluv":[97.7198690947758308,946.378692368412885,94.7095428290633237],"hsluv":[97.7198690947758308,99.9999999999867697,94.7095428290633237]},"#ddff22":{"lch":[94.7413776147606086,105.545731309599958,97.8489007917202827],"luv":[94.7413776147606086,-14.4134418215914106,104.556941866783148],"rgb":[0.866666666666666696,1,0.133333333333333331],"xyz":[0.658652645551459526,0.870073212027259735,0.148377018573923686],"hpluv":[97.8489007917202827,939.695870823628752,94.7413776147606086],"hsluv":[97.8489007917202827,99.9999999999872,94.7413776147606086]},"#ddff33":{"lch":[94.7937532988665197,103.225383790498825,98.0674915546983],"luv":[94.7937532988665197,-14.4865977424562669,102.203807876928138],"rgb":[0.866666666666666696,1,0.2],"xyz":[0.661740396283917343,0.871308312320242861,0.164639172431534836],"hpluv":[98.0674915546983,928.656435156239354,94.7937532988665197],"hsluv":[98.0674915546983,99.9999999999868834,94.7937532988665197]},"#ddff44":{"lch":[94.8692843830354491,99.9146373114600692,98.397314807396512],"luv":[94.8692843830354491,-14.5912004882884094,98.8434702820129729],"rgb":[0.866666666666666696,1,0.266666666666666663],"xyz":[0.666198391528136202,0.873091510417930428,0.188117947384421474],"hpluv":[98.397314807396512,912.633071017653265,94.8692843830354491],"hsluv":[98.397314807396512,99.9999999999866276,94.8692843830354491]},"#ddff55":{"lch":[94.9701440016210654,95.558111661139634,98.8668834316730738],"luv":[94.9701440016210654,-14.7292629682473848,94.4161083536863828],"rgb":[0.866666666666666696,1,0.333333333333333315],"xyz":[0.672160805567498132,0.875476476033675177,0.21951999465839539],"hpluv":[98.8668834316730738,891.031026100052486,94.9701440016210654],"hsluv":[98.8668834316730738,99.9999999999861586,94.9701440016210654]},"#ddff66":{"lch":[95.0981866754888,90.1320341607989235,99.5166683548804798],"luv":[95.0981866754888,-14.9019372161492765,88.8915960547979438],"rgb":[0.866666666666666696,1,0.4],"xyz":[0.679745801341006373,0.878510474343078496,0.259467639065539379],"hpluv":[99.5166683548804798,863.234823568518,95.0981866754888],"hsluv":[99.5166683548804798,99.9999999999856186,95.0981866754888]},"#ddff77":{"lch":[95.2550143462764396,83.6430269583913599,100.407261812829162],"luv":[95.2550143462764396,-15.1095945804084604,82.2669806810598487],"rgb":[0.866666666666666696,1,0.466666666666666674],"xyz":[0.689059814361208223,0.882236079551159347,0.308521440971937233],"hpluv":[100.407261812829162,828.556184265804632,95.2550143462764396],"hsluv":[100.407261812829162,99.9999999999855476,95.2550143462764396]},"#ddff88":{"lch":[95.4420158908659175,76.1281736437493,101.633961649281417],"luv":[95.4420158908659175,-15.3518949618923237,74.5641880758576434],"rgb":[0.866666666666666696,1,0.533333333333333326],"xyz":[0.700200231463152134,0.886692246391936889,0.367194304375509428],"hpluv":[101.633961649281417,786.17501332264635,95.4420158908659175],"hsluv":[101.633961649281417,99.9999999999848512,95.4420158908659175]},"#ddff99":{"lch":[95.6603925662724208,67.6570848719276086,103.355147801887099],"luv":[95.6603925662724208,-15.6278614338241617,65.8274341013866859],"rgb":[0.866666666666666696,1,0.6],"xyz":[0.713257195572224778,0.891915032035566102,0.435960982016627363],"hpluv":[103.355147801887099,735.074270676232231,95.6603925662724208],"hsluv":[103.355147801887099,99.9999999999844107,95.6603925662724208]},"#ddffaa":{"lch":[95.9111754000973775,58.338925144698,105.852499131344544],"luv":[95.9111754000973775,-15.935965587620279,56.1201852084333268],"rgb":[0.866666666666666696,1,0.66666666666666663],"xyz":[0.72831488853747739,0.897938109221667169,0.515264831633625908],"hpluv":[105.852499131344544,673.992295850936557,95.9111754000973775],"hsluv":[105.852499131344544,99.9999999999831886,95.9111754000973775]},"#ddffbb":{"lch":[96.1952377631310185,48.3433070572267596,109.672211431084662],"luv":[96.1952377631310185,-16.2742233848326485,45.5216980180866813],"rgb":[0.866666666666666696,1,0.733333333333333282],"xyz":[0.745452480644814,0.904793146064601927,0.60552281673226771],"hpluv":[109.672211431084662,601.502194015230771,96.1952377631310185],"hsluv":[109.672211431084662,99.9999999999821654,96.1952377631310185]},"#ddffcc":{"lch":[96.513305005727517,37.9644197829535202,115.996292551248089],"luv":[96.513305005727517,-16.6402982513575566,34.1232712904577653],"rgb":[0.866666666666666696,1,0.8],"xyz":[0.764744856088535707,0.912510096242090785,0.707129327402537866],"hpluv":[115.996292551248089,516.693096965009204,96.513305005727517],"hsluv":[115.996292551248089,99.9999999999804885,96.513305005727517]},"#ddffdd":{"lch":[96.8659623148576,27.841508205801528,127.715012949232161],"luv":[96.8659623148576,-17.0316066426751398,22.0243945284064],"rgb":[0.866666666666666696,1,0.866666666666666696],"xyz":[0.786263181639169306,0.921117426462344291,0.820459175302543864],"hpluv":[127.715012949232161,422.676993554754517,96.8659623148576],"hsluv":[127.715012949232161,99.9999999999786411,96.8659623148576]},"#ddffee":{"lch":[97.2536615310726802,19.7831433293950418,151.864226334417424],"luv":[97.2536615310726802,-17.4454209009420502,9.32898974060759478],"rgb":[0.866666666666666696,1,0.933333333333333348],"xyz":[0.810075361905344,0.930642298568814308,0.945869991371067087],"hpluv":[151.864226334417424,343.73229759561508,97.2536615310726802],"hsluv":[151.864226334417424,99.9999999999752,97.2536615310726802]},"#ddffff":{"lch":[97.6767274082888406,18.2904922799610645,192.177050630059568],"luv":[97.6767274082888406,-17.878964623675607,-3.85807359036494368],"rgb":[0.866666666666666696,1,1],"xyz":[0.836246410315175437,0.941110717932747,1.08370417966284882],"hpluv":[192.177050630059568,376.852754928906336,97.6767274082888406],"hsluv":[192.177050630059568,99.9999999999715072,97.6767274082888406]},"#668800":{"lch":[52.32310792684153,62.4331707825390509,105.73052795354684],"luv":[52.32310792684153,-16.9264656143939405,60.0948881001240167],"rgb":[0.4,0.533333333333333326,0],"xyz":[0.142831412088957943,0.204328465339529863,0.0319143663590854554],"hpluv":[105.73052795354684,151.412310196323318,52.32310792684153],"hsluv":[105.73052795354684,100.000000000002359,52.32310792684153]},"#668811":{"lch":[52.3681821172622222,60.6739112189649603,106.201766876928076],"luv":[52.3681821172622222,-16.9292783492562116,58.26425179456308],"rgb":[0.4,0.533333333333333326,0.0666666666666666657],"xyz":[0.143843077588595075,0.204733131539384716,0.0372424713238410851],"hpluv":[106.201766876928076,147.019120365759306,52.3681821172622222],"hsluv":[106.201766876928076,96.7617570127925859,52.3681821172622222]},"#668822":{"lch":[52.4515808002199,57.4815115963739842,107.134347730867304],"luv":[52.4515808002199,-16.9348150675510247,54.9302850350507796],"rgb":[0.4,0.533333333333333326,0.133333333333333331],"xyz":[0.145718435727072076,0.205483274794775544,0.0471193575198202846],"hpluv":[107.134347730867304,139.062145386582984,52.4515808002199],"hsluv":[107.134347730867304,90.8761910280814647,52.4515808002199]},"#668833":{"lch":[52.5884544541714121,52.4173031151438593,108.860637572968898],"luv":[52.5884544541714121,-16.9448041098426323,49.6028958786070291],"rgb":[0.4,0.533333333333333326,0.2],"xyz":[0.14880618645952981,0.206718375087758643,0.0633815113774314209],"hpluv":[108.860637572968898,126.480505252334424,52.5884544541714121],"hsluv":[108.860637572968898,81.504484256448066,52.5884544541714121]},"#668844":{"lch":[52.7851097594501937,45.5231929703366234,111.874794573011059],"luv":[52.7851097594501937,-16.9610118856818559,42.2455343678863215],"rgb":[0.4,0.533333333333333326,0.266666666666666663],"xyz":[0.153264181703748698,0.208501573185446237,0.0868602863303180595],"hpluv":[111.874794573011059,109.436101408621766,52.7851097594501937],"hsluv":[111.874794573011059,68.6312430201703734,52.7851097594501937]},"#668855":{"lch":[53.0463844713544859,37.0894540992544819,117.255878513522262],"luv":[53.0463844713544859,-16.9856764955971045,32.9714179156375593],"rgb":[0.4,0.533333333333333326,0.333333333333333315],"xyz":[0.15922659574311071,0.21088653880119107,0.118262333604291975],"hpluv":[117.255878513522262,88.7225425584692715,53.0463844713544859],"hsluv":[117.255878513522262,52.5261258187504225,53.0463844713544859]},"#668866":{"lch":[53.3759296841588906,27.8248149657310222,127.715012949236794],"luv":[53.3759296841588906,-17.0213948144824521,22.0111891193247189],"rgb":[0.4,0.533333333333333326,0.4],"xyz":[0.166811591516618868,0.213920537110594361,0.158209978011435937],"hpluv":[127.715012949236794,66.1494380276081415,53.3759296841588906],"hsluv":[127.715012949236794,33.681854155652033,53.3759296841588906]},"#668877":{"lch":[53.7763606180623839,19.6211535767711887,150.461713858693599],"luv":[53.7763606180623839,-17.0709226847205855,9.67332757511772101],"rgb":[0.4,0.533333333333333326,0.466666666666666674],"xyz":[0.176125604536820801,0.217646142318675184,0.207263779917833846],"hpluv":[150.461713858693599,46.2990901048939207,53.7763606180623839],"hsluv":[150.461713858693599,37.1484166060608132,53.7763606180623839]},"#668888":{"lch":[54.2493559855519436,17.5313913512660982,192.17705063006045],"luv":[54.2493559855519436,-17.1369431164247104,-3.69795393909545],"rgb":[0.4,0.533333333333333326,0.533333333333333326],"xyz":[0.187266021638764601,0.222102309159452782,0.265936643321406],"hpluv":[192.17705063006045,41.0072951616226788,54.2493559855519436],"hsluv":[192.17705063006045,40.8467805779917228,54.2493559855519436]},"#668899":{"lch":[54.7957384612029728,24.7393499057112685,225.882505108050964],"luv":[54.7957384612029728,-17.2218541013304964,-17.7607200042594577],"rgb":[0.4,0.533333333333333326,0.6],"xyz":[0.200322985747837329,0.22732509480308194,0.33470332096252392],"hpluv":[225.882505108050964,57.2902642666713859,54.7957384612029728],"hsluv":[225.882505108050964,44.6631352998217963,54.7957384612029728]},"#6688aa":{"lch":[55.4155508256813363,36.5699037808867828,241.717344836465486],"luv":[55.4155508256813363,-17.3276119763631087,-32.2042190673817643],"rgb":[0.4,0.533333333333333326,0.66666666666666663],"xyz":[0.215380678713089857,0.233348171989183034,0.414007170579522521],"hpluv":[241.717344836465486,83.7397171719788389,55.4155508256813363],"hsluv":[241.717344836465486,48.4952118884804193,55.4155508256813363]},"#6688bb":{"lch":[56.1081340603271457,49.918102431374308,249.531909378681803],"luv":[56.1081340603271457,-17.4556451944419777,-46.7666270025424495],"rgb":[0.4,0.533333333333333326,0.733333333333333282],"xyz":[0.232518270820426531,0.240203208832117793,0.504265155678164323],"hpluv":[249.531909378681803,112.8941838879785,56.1081340603271457],"hsluv":[249.531909378681803,52.2580147864780216,56.1081340603271457]},"#6688cc":{"lch":[56.8722093096567107,63.7230017864969795,253.960340799970709],"luv":[56.8722093096567107,-17.6068348542363715,-61.2423082770199372],"rgb":[0.4,0.533333333333333326,0.8],"xyz":[0.251810646264148286,0.247920159009606594,0.605871666348434479],"hpluv":[253.960340799970709,142.178999158492672,56.8722093096567107],"hsluv":[253.960340799970709,56.6402695601832349,56.8722093096567107]},"#6688dd":{"lch":[57.7059632125805564,77.5471512008463719,256.744147904563079],"luv":[57.7059632125805564,-17.7815469636593271,-75.4809727477468755],"rgb":[0.4,0.533333333333333326,0.866666666666666696],"xyz":[0.273328971814781774,0.256527489229860128,0.719201514248440477],"hpluv":[256.744147904563079,170.523595036459966,57.7059632125805564],"hsluv":[256.744147904563079,70.7529337108087475,57.7059632125805564]},"#6688ee":{"lch":[58.6071348177704721,91.1720868217648501,258.626369492504523],"luv":[58.6071348177704721,-17.979697586292076,-89.3816529839368599],"rgb":[0.4,0.533333333333333326,0.933333333333333348],"xyz":[0.297141152080956539,0.266052361336330145,0.8446123303169637],"hpluv":[258.626369492504523,197.40162879311913,58.6071348177704721],"hsluv":[258.626369492504523,85.1920367601911295,58.6071348177704721]},"#6688ff":{"lch":[59.57310174908622,104.481663139573541,259.967822360236937],"luv":[59.57310174908622,-18.2008336002305597,-102.884146439906075],"rgb":[0.4,0.533333333333333326,1],"xyz":[0.323312200490787904,0.276520780700262869,0.982446518608745434],"hpluv":[259.967822360236937,222.550815911907222,59.57310174908622],"hsluv":[259.967822360236937,99.9999999999987352,59.57310174908622]},"#669900":{"lch":[57.6618978033021961,71.9113437902946373,111.072092359847389],"luv":[57.6618978033021961,-25.8551729794803826,67.1025438856612624],"rgb":[0.4,0.6,0],"xyz":[0.168701012541425444,0.25606766624446553,0.0405375665099077104],"hpluv":[111.072092359847389,158.251486754186431,57.6618978033021961],"hsluv":[111.072092359847389,100.000000000002444,57.6618978033021961]},"#669911":{"lch":[57.7006802499588929,70.3894808316696867,111.521292839157113],"luv":[57.7006802499588929,-25.8221679479897865,65.4820177928093727],"rgb":[0.4,0.6,0.0666666666666666657],"xyz":[0.169712678041062576,0.256472332444320383,0.0458656714746633401],"hpluv":[111.521292839157113,154.798288730060023,57.7006802499588929],"hsluv":[111.521292839157113,97.4070268725327821,57.7006802499588929]},"#669922":{"lch":[57.7724648019637499,67.6202459496272326,112.394641072548438],"luv":[57.7724648019637499,-25.7622250908158499,62.5204400229094404],"rgb":[0.4,0.6,0.133333333333333331],"xyz":[0.171588036179539577,0.257222475699711184,0.0557425576706425396],"hpluv":[112.394641072548438,148.523500329687067,57.7724648019637499],"hsluv":[112.394641072548438,92.6757293451634183,57.7724648019637499]},"#669933":{"lch":[57.8903535973237524,63.206621217633213,113.958803391015238],"luv":[57.8903535973237524,-25.6669247559924365,57.7605915769530824],"rgb":[0.4,0.6,0.2],"xyz":[0.174675786911997311,0.258457575992694311,0.0720047115282536898],"hpluv":[113.958803391015238,138.546544821103367,57.8903535973237524],"hsluv":[113.958803391015238,85.092275495173979,57.8903535973237524]},"#669944":{"lch":[58.0598969225296457,57.1535921702901888,116.538768682419729],"luv":[58.0598969225296457,-25.5364113217858204,51.131446241744662],"rgb":[0.4,0.6,0.266666666666666663],"xyz":[0.179133782156216198,0.260240774090381877,0.0954834864811403283],"hpluv":[116.538768682419729,124.912700512594284,58.0598969225296457],"hsluv":[116.538768682419729,74.5746503624431796,58.0598969225296457]},"#669955":{"lch":[58.2854489010818355,49.6561447471622515,120.7300937454592],"luv":[58.2854489010818355,-25.3740154630121886,42.6836274282534163],"rgb":[0.4,0.6,0.333333333333333315],"xyz":[0.185096196195578211,0.262625739706126737,0.126885533755114244],"hpluv":[120.7300937454592,108.106592630407334,58.2854489010818355],"hsluv":[120.7300937454592,61.2495338993745833,58.2854489010818355]},"#669966":{"lch":[58.5704165792398754,41.1710358166226,127.715012949238272],"luv":[58.5704165792398754,-25.1857364161826034,32.5688942303571949],"rgb":[0.4,0.6,0.4],"xyz":[0.192681191969086368,0.265659738015530056,0.166833178162258178],"hpluv":[127.715012949238272,89.1975256314243552,58.5704165792398754],"hsluv":[127.715012949238272,45.4174387408809324,58.5704165792398754]},"#669977":{"lch":[58.9173908027988489,32.643461159974926,139.926834832055846],"luv":[58.9173908027988489,-24.9795271581232114,21.0147276798767138],"rgb":[0.4,0.6,0.466666666666666674],"xyz":[0.201995204989288302,0.269385343223610851,0.215886980068656087],"hpluv":[139.926834832055846,70.3059403526018514,58.9173908027988489],"hsluv":[139.926834832055846,47.7876005322921813,58.9173908027988489]},"#669988":{"lch":[59.328227692638464,26.116847909850911,161.480821243886396],"luv":[59.328227692638464,-24.7644493579715288,8.29528738156475498],"rgb":[0.4,0.6,0.533333333333333326],"xyz":[0.213135622091232102,0.273841510064388449,0.274559843472228282],"hpluv":[161.480821243886396,55.8597144892801083,59.328227692638464],"hsluv":[161.480821243886396,50.3655359274122105,59.328227692638464]},"#669999":{"lch":[59.8041090330486043,25.1148951486962346,192.17705063006062],"luv":[59.8041090330486043,-24.5498215694726056,-5.29756729424584893],"rgb":[0.4,0.6,0.6],"xyz":[0.226192586200304829,0.279064295708017607,0.343326521113346161],"hpluv":[192.17705063006062,53.2892577697712042,59.8041090330486043],"hsluv":[192.17705063006062,53.0806679813151447,59.8041090330486043]},"#6699aa":{"lch":[60.3455948386344119,31.1785657150768039,218.6653689057203],"luv":[60.3455948386344119,-24.3444790905776323,-19.4794583563761137],"rgb":[0.4,0.6,0.66666666666666663],"xyz":[0.241250279165557358,0.285087372894118729,0.422630370730344762],"hpluv":[218.6653689057203,65.5616517705923911,60.3455948386344119],"hsluv":[218.6653689057203,55.8649153078387357,60.3455948386344119]},"#6699bb":{"lch":[60.9526745558420231,41.7013653705125407,234.60099737489486],"luv":[60.9526745558420231,-24.1562241025528444,-33.9923625373734168],"rgb":[0.4,0.6,0.733333333333333282],"xyz":[0.258387871272894032,0.291942409737053488,0.512888355828986509],"hpluv":[234.60099737489486,86.8154127469588,60.9526745558420231],"hsluv":[234.60099737489486,58.6571249967150123,60.9526745558420231]},"#6699cc":{"lch":[61.6248198105828493,54.2138016672169485,243.734276496040906],"luv":[61.6248198105828493,-23.9914938552849968,-48.6162988492970101],"rgb":[0.4,0.6,0.8],"xyz":[0.277680246716615731,0.299659359914542289,0.614494866499256664],"hpluv":[243.734276496040906,111.633239234030881,61.6248198105828493],"hsluv":[243.734276496040906,61.4057918386087067,61.6248198105828493]},"#6699dd":{"lch":[62.361039595623,67.5283063616342361,249.312993820438976],"luv":[62.361039595623,-23.8552311607989473,-63.1743627299522288],"rgb":[0.4,0.6,0.866666666666666696],"xyz":[0.29919857226724933,0.308266690134795796,0.727824714399262662],"hpluv":[249.312993820438976,137.407942777337979,62.361039595623],"hsluv":[249.312993820438976,66.62550454031512,62.361039595623]},"#6699ee":{"lch":[63.1599376048740453,81.0888167917790526,252.968345076420633],"luv":[63.1599376048740453,-23.7509145884581336,-77.5325110189427278],"rgb":[0.4,0.6,0.933333333333333348],"xyz":[0.323010752533424039,0.317791562241265813,0.853235530467785885],"hpluv":[252.968345076420633,162.914071535813093,63.1599376048740453],"hsluv":[252.968345076420633,83.0301883133999183,63.1599376048740453]},"#6699ff":{"lch":[64.0197707514621186,94.6074384193794771,255.504450424431923],"luv":[64.0197707514621186,-23.6806962224400728,-91.5958079318982499],"rgb":[0.4,0.6,1],"xyz":[0.34918180094325546,0.328259981605198536,0.99106971875956773],"hpluv":[255.504450424431923,187.521252715437782,64.0197707514621186],"hsluv":[255.504450424431923,99.9999999999985079,64.0197707514621186]},"#550000":{"lch":[15.1243819173422267,50.8637728648741643,12.1770506300617765],"luv":[15.1243819173422267,49.7193613905117289,10.7288626130266547],"rgb":[0.333333333333333315,0,0],"xyz":[0.0374622858816120868,0.019316491157706641,0.00175604465070052949],"hpluv":[12.1770506300617765,426.746789183125202,15.1243819173422267],"hsluv":[12.1770506300617765,100.000000000002203,15.1243819173422267]},"#550011":{"lch":[15.3402258633588957,47.2707050856887108,7.4875089370669734],"luv":[15.3402258633588957,46.8676416739534929,6.15984766208174239],"rgb":[0.333333333333333315,0,0.0666666666666666657],"xyz":[0.0384739513812492051,0.0197211573575614939,0.00708414961545616138],"hpluv":[7.4875089370669734,391.020613457768548,15.3402258633588957],"hsluv":[7.4875089370669734,99.9999999999966889,15.3402258633588957]},"#550022":{"lch":[15.7326592199860933,42.4312907985821823,358.411234527054887],"luv":[15.7326592199860933,42.4149789665186745,-1.17643448760390168],"rgb":[0.333333333333333315,0,0.133333333333333331],"xyz":[0.0403493095197262272,0.0204713006129523117,0.0169610358114353557],"hpluv":[358.411234527054887,342.234221563623748,15.7326592199860933],"hsluv":[358.411234527054887,99.9999999999971578,15.7326592199860933]},"#550033":{"lch":[16.358416636328208,38.360101220613565,343.406058671947278],"luv":[16.358416636328208,36.7625096026365128,-10.9551473459637485],"rgb":[0.333333333333333315,0,0.2],"xyz":[0.0434370602521839677,0.0217064009059354281,0.0332231896690465],"hpluv":[343.406058671947278,297.562230749163234,16.358416636328208],"hsluv":[343.406058671947278,99.9999999999977547,16.358416636328208]},"#550044":{"lch":[17.2212923868602061,37.8614359764106112,324.728975934647224],"luv":[17.2212923868602061,30.9112016871952413,-21.8628896637516235],"rgb":[0.333333333333333315,0,0.266666666666666663],"xyz":[0.0478950554964028483,0.0234895990036230046,0.0567019646219331375],"hpluv":[324.728975934647224,278.978456842737614,17.2212923868602061],"hsluv":[324.728975934647224,99.9999999999983089,17.2212923868602061]},"#550055":{"lch":[18.3096014215038,41.7063030886972754,307.715012949243544],"luv":[18.3096014215038,25.5131777875110508,-32.9923245090298636],"rgb":[0.333333333333333315,0,0.333333333333333315],"xyz":[0.0538574695357648403,0.025874564619367834,0.0881040118959070528],"hpluv":[307.715012949243544,289.042783730483393,18.3096014215038],"hsluv":[307.715012949243544,99.9999999999988,18.3096014215038]},"#550066":{"lch":[19.6013792550641099,48.6148100748190828,295.355623011865077],"luv":[19.6013792550641099,20.818580180871372,-43.9316113733990079],"rgb":[0.333333333333333315,0,0.4],"xyz":[0.0614424653092730116,0.028908562928771149,0.128051656303051015],"hpluv":[295.355623011865077,314.717786655224245,19.6013792550641099],"hsluv":[295.355623011865077,99.9999999999992468,19.6013792550641099]},"#550077":{"lch":[21.069395574911745,57.1127554515679421,287.139622223683091],"luv":[21.069395574911745,16.83119884103942,-54.5763463493480572],"rgb":[0.333333333333333315,0,0.466666666666666674],"xyz":[0.0707564783294749311,0.0326341681368519654,0.177105458209448924],"hpluv":[287.139622223683091,343.969838941793114,21.069395574911745],"hsluv":[287.139622223683091,99.9999999999995737,21.069395574911745]},"#550088":{"lch":[22.6852054601189934,66.3294491167530822,281.703433904835379],"luv":[22.6852054601189934,13.454662288017035,-64.9505033302079084],"rgb":[0.333333333333333315,0,0.533333333333333326],"xyz":[0.0818968954314187592,0.0370903349776295563,0.235778321613021091],"hpluv":[281.703433904835379,371.024851449370942,22.6852054601189934],"hsluv":[281.703433904835379,99.9999999999998721,22.6852054601189934]},"#550099":{"lch":[24.4218644362266417,75.8503102235033424,278.01254475278904],"luv":[24.4218644362266417,10.5727682252252198,-75.1098271403773339],"rgb":[0.333333333333333315,0,0.6],"xyz":[0.0949538595404914726,0.0423131206212587208,0.304544999254138971],"hpluv":[278.01254475278904,394.110378481836165,24.4218644362266417],"hsluv":[278.01254475278904,100.000000000000071,24.4218644362266417]},"#5500aa":{"lch":[26.2553935553790794,85.4876195151354,275.424483319872081],"luv":[26.2553935553790794,8.0814629277942,-85.1047768771603614],"rgb":[0.333333333333333315,0,0.66666666666666663],"xyz":[0.110011552505744015,0.0483361978073598153,0.383848848871137571],"hpluv":[275.424483319872081,413.165469396605374,26.2553935553790794],"hsluv":[275.424483319872081,100.00000000000027,26.2553935553790794]},"#5500bb":{"lch":[28.1653177219846,95.1546470205467756,273.553022331801344],"luv":[28.1653177219846,5.89694295360029841,-94.9717479748942708],"rgb":[0.333333333333333315,0,0.733333333333333282],"xyz":[0.127149144613080661,0.0551912346502945739,0.474106833969779318],"hpluv":[273.553022331801344,428.701175528050442,28.1653177219846],"hsluv":[273.553022331801344,100.000000000000355,28.1653177219846]},"#5500cc":{"lch":[30.1346298593711452,104.80902699908826,272.162345307959299],"luv":[30.1346298593711452,3.95455850560158062,-104.734395532324456],"rgb":[0.333333333333333315,0,0.8],"xyz":[0.146441520056802388,0.0629081848277833755,0.575713344640049529],"hpluv":[272.162345307959299,441.338845171454864,30.1346298593711452],"hsluv":[272.162345307959299,100.000000000000441,30.1346298593711452]},"#5500dd":{"lch":[32.1494591091083208,114.428501102308275,271.104225820707256],"luv":[32.1494591091083208,2.20517261265448461,-114.407250986418532],"rgb":[0.333333333333333315,0,0.866666666666666696],"xyz":[0.167959845607435931,0.0715155150480369095,0.689043192540055527],"hpluv":[271.104225820707256,451.647764573950099,32.1494591091083208],"hsluv":[271.104225820707256,100.000000000000483,32.1494591091083208]},"#5500ee":{"lch":[34.1986254005705774,124.000502171291956,270.282536199645165],"luv":[34.1986254005705774,0.611467178704377612,-123.998994538754019],"rgb":[0.333333333333333315,0,0.933333333333333348],"xyz":[0.191772025873610696,0.0810403871545069404,0.81445400860857875],"hpluv":[270.282536199645165,460.101999214721616,34.1986254005705774],"hsluv":[270.282536199645165,100.000000000000597,34.1986254005705774]},"#5500ff":{"lch":[36.2731838611955055,133.517545782829444,269.6330586770423],"luv":[36.2731838611955055,-0.855085145745556,-133.514807647929],"rgb":[0.333333333333333315,0,1],"xyz":[0.217943074283442062,0.0915088065184396504,0.952288196900360595],"hpluv":[269.6330586770423,467.080772865482345,36.2731838611955055],"hsluv":[269.6330586770423,100.000000000000668,36.2731838611955055]},"#551100":{"lch":[17.1436512350983392,46.6418802884309827,16.9386517648024579],"luv":[17.1436512350983392,44.618427652544149,13.5889996193616174],"rgb":[0.333333333333333315,0.0666666666666666657,0],"xyz":[0.0394666861425404941,0.0233252916795635146,0.00242417807100998037],"hpluv":[16.9386517648024579,345.232802292268,17.1436512350983392],"hsluv":[16.9386517648024579,100.000000000002245,17.1436512350983392]},"#551111":{"lch":[17.3342210988239742,43.3325537190722372,12.1770506300618173],"luv":[17.3342210988239742,42.3575912084996133,9.14027783111198566],"rgb":[0.333333333333333315,0.0666666666666666657,0.0666666666666666657],"xyz":[0.0404783516421776124,0.0237299578794183674,0.0077522830357656114],"hpluv":[12.1770506300618173,317.211759513802576,17.3342210988239742],"hsluv":[12.1770506300618173,74.3325474389658751,17.3342210988239742]},"#551122":{"lch":[17.681833534927847,38.7809423842287515,2.75476418742331486],"luv":[17.681833534927847,38.7361268795629599,1.86385798259144919],"rgb":[0.333333333333333315,0.0666666666666666657,0.133333333333333331],"xyz":[0.0423537097806546345,0.0244801011348091888,0.0176291692317448075],"hpluv":[2.75476418742331486,278.311009894887945,17.681833534927847],"hsluv":[2.75476418742331486,76.7057995287142234,17.681833534927847]},"#551133":{"lch":[18.2390179286851222,34.9181665436168771,346.660743506282301],"luv":[18.2390179286851222,33.9761101882180157,-8.05619582966011727],"rgb":[0.333333333333333315,0.0666666666666666657,0.2],"xyz":[0.045441460513112375,0.0257152014277923,0.0338913230893559542],"hpluv":[346.660743506282301,242.9345634355779,18.2390179286851222],"hsluv":[346.660743506282301,79.7834922439867285,18.2390179286851222]},"#551144":{"lch":[19.0128230091186055,34.7408929356053093,326.164658676814156],"luv":[19.0128230091186055,28.8572161490225767,-19.3440098762325228],"rgb":[0.333333333333333315,0.0666666666666666657,0.266666666666666663],"xyz":[0.0498994557573312555,0.0274983995254798746,0.0573700980422425927],"hpluv":[326.164658676814156,231.864199750183133,19.0128230091186055],"hsluv":[326.164658676814156,83.0221027238197706,19.0128230091186055]},"#551155":{"lch":[19.9971255718025702,39.1813209297373,307.715012949243771],"luv":[19.9971255718025702,23.9685594933690105,-30.9949038651824331],"rgb":[0.333333333333333315,0.0666666666666666657,0.333333333333333315],"xyz":[0.0558618697966932476,0.0298833651412247076,0.0887721453162165],"hpluv":[307.715012949243771,248.628452083429778,19.9971255718025702],"hsluv":[307.715012949243771,86.0178721207098391,19.9971255718025702]},"#551166":{"lch":[21.1763147828962417,46.7756191769153702,294.771362117319313],"luv":[21.1763147828962417,19.5989049109657927,-42.4716549674572263],"rgb":[0.333333333333333315,0.0666666666666666657,0.4],"xyz":[0.0634468655702014189,0.0329173634506280191,0.128719789723360456],"hpluv":[294.771362117319313,280.29057047770084,21.1763147828962417],"hsluv":[294.771362117319313,88.5810746573468464,21.1763147828962417]},"#551177":{"lch":[22.529041607596703,55.8726050260016436,286.442196236272423],"luv":[22.529041607596703,15.8146223861076685,-53.5877384405836494],"rgb":[0.333333333333333315,0.0666666666666666657,0.466666666666666674],"xyz":[0.0727608785904033384,0.0366429686587088355,0.177773591629758365],"hpluv":[286.442196236272423,314.699121073082495,22.529041607596703],"hsluv":[286.442196236272423,90.6792509168865166,22.529041607596703]},"#551188":{"lch":[24.0315326783493077,65.5523157673088548,281.05474383939486],"luv":[24.0315326783493077,12.5694476912001676,-64.3359548557037613],"rgb":[0.333333333333333315,0.0666666666666666657,0.533333333333333326],"xyz":[0.0839012956923471664,0.0410991354994864333,0.236446455033330533],"hpluv":[281.05474383939486,346.135302225987516,24.0315326783493077],"hsluv":[281.05474383939486,92.3586421581981654,24.0315326783493077]},"#551199":{"lch":[25.6600874124784752,75.409923320082811,277.450872837297311],"luv":[25.6600874124784752,9.77886091464338847,-74.7731931533810439],"rgb":[0.333333333333333315,0.0666666666666666657,0.6],"xyz":[0.0969582598014198799,0.0463219211431155908,0.30521313267444844],"hpluv":[277.450872837297311,372.914863977489176,25.6600874124784752],"hsluv":[277.450872837297311,93.6909530677945099,25.6600874124784752]},"#5511aa":{"lch":[27.3926712394503795,85.2829889480110097,274.948569823839534],"luv":[27.3926712394503795,7.3566383451248436,-84.9650991652784882],"rgb":[0.333333333333333315,0.0666666666666666657,0.66666666666666663],"xyz":[0.112015952766672422,0.0523449983292166923,0.38451698229144704],"hpluv":[274.948569823839534,395.063906765864772,27.3926712394503795],"hsluv":[274.948569823839534,94.7471527755802185,27.3926712394503795]},"#5511bb":{"lch":[29.2097366740877575,95.1102004757886732,273.151254165932869],"luv":[29.2097366740877575,5.22840137893499524,-94.9663838079847125],"rgb":[0.333333333333333315,0.0666666666666666657,0.733333333333333282],"xyz":[0.129153544874009069,0.0592000351721514509,0.474774967390088787],"hpluv":[273.151254165932869,413.179515249173164,29.2097366740877575],"hsluv":[273.151254165932869,95.5878244802283,29.2097366740877575]},"#5511cc":{"lch":[31.0944914716528729,104.870266468627406,271.822015936655589],"luv":[31.0944914716528729,3.33433100744475697,-104.81724584215],"rgb":[0.333333333333333315,0.0666666666666666657,0.8],"xyz":[0.148445920317730795,0.0669169853496402456,0.576381478060359],"hpluv":[271.822015936655589,427.964986778194486,31.0944914716528729],"hsluv":[271.822015936655589,96.2613872132177733,31.0944914716528729]},"#5511dd":{"lch":[33.0328257175950526,114.557035031638449,270.814150293263936],"luv":[33.0328257175950526,1.62775523553093748,-114.545469959022128],"rgb":[0.333333333333333315,0.0666666666666666657,0.866666666666666696],"xyz":[0.169964245868364339,0.0755243155698937796,0.689711325960365],"hpluv":[270.814150293263936,440.063516862193467,33.0328257175950526],"hsluv":[270.814150293263936,96.8053522828386832,33.0328257175950526]},"#5511ee":{"lch":[35.0130604571318926,124.169729525043778,270.033521846843314],"luv":[35.0130604571318926,0.0726475571782520396,-124.169708273213573],"rgb":[0.333333333333333315,0.0666666666666666657,0.933333333333333348],"xyz":[0.193776426134539104,0.0850491876763638244,0.815122142028888219],"hpluv":[270.033521846843314,450.012925469310176,35.0130604571318926],"hsluv":[270.033521846843314,97.2483877085506663,35.0130604571318926]},"#5511ff":{"lch":[37.0256255288684244,133.709282746677673,269.417732433602225],"luv":[37.0256255288684244,-1.35879534673770408,-133.702378317802101],"rgb":[0.333333333333333315,0.0666666666666666657,1],"xyz":[0.219947474544370469,0.0955176070402965205,0.952956330320670064],"hpluv":[269.417732433602225,458.245787382607887,37.0256255288684244],"hsluv":[269.417732433602225,99.999999999999531,37.0256255288684244]},"#552200":{"lch":[20.34436993371488,40.5799496107340403,26.5709502396200712],"luv":[20.34436993371488,36.2939416756913289,18.1516420207988389],"rgb":[0.333333333333333315,0.133333333333333331,0],"xyz":[0.0431823098773084293,0.0307565391490994891,0.0036627193159325909],"hpluv":[26.5709502396200712,253.10841584108,20.34436993371488],"hsluv":[26.5709502396200712,100.000000000002359,20.34436993371488]},"#552211":{"lch":[20.5030711832139332,37.4561676233306144,21.8926823519782197],"luv":[20.5030711832139332,34.7549742653004543,13.9662542166947503],"rgb":[0.333333333333333315,0.133333333333333331,0.0666666666666666657],"xyz":[0.0441939753769455546,0.031161205348954342,0.00899082428068822236],"hpluv":[21.8926823519782197,231.816181029165051,20.5030711832139332],"hsluv":[21.8926823519782197,79.998991439989,20.5030711832139332]},"#552222":{"lch":[20.7936643332181177,32.9512801850020054,12.1770506300619488],"luv":[20.7936643332181177,32.2098915499349658,6.95052171940595098],"rgb":[0.333333333333333315,0.133333333333333331,0.133333333333333331],"xyz":[0.0460693335154225697,0.0319113486043451633,0.0188677104766674167],"hpluv":[12.1770506300619488,201.08542320769223,20.7936643332181177],"hsluv":[12.1770506300619488,47.1205474310924046,20.7936643332181177]},"#552233":{"lch":[21.2623572347893699,28.8586800011052311,354.1745907436],"luv":[21.2623572347893699,28.7096478626609084,-2.92908364650122532],"rgb":[0.333333333333333315,0.133333333333333331,0.2],"xyz":[0.0491570842478803102,0.0331464488973282762,0.0351298643342785599],"hpluv":[354.1745907436,172.228245917758017,21.2623572347893699],"hsluv":[354.1745907436,52.8325366869496236,21.2623572347893699]},"#552244":{"lch":[21.9189283311679688,28.7014290952845421,329.54904741067952],"luv":[21.9189283311679688,24.7424491748557642,-14.5459011732283336],"rgb":[0.333333333333333315,0.133333333333333331,0.266666666666666663],"xyz":[0.0536150794920991908,0.0349296469950158492,0.0586086392871652],"hpluv":[329.54904741067952,166.158870546468904,21.9189283311679688],"hsluv":[329.54904741067952,59.1960886419386,21.9189283311679688]},"#552255":{"lch":[22.7630226511172538,33.9275210993755394,307.715012949244226],"luv":[22.7630226511172538,20.7546297224435,-26.8388157904337739],"rgb":[0.333333333333333315,0.133333333333333331,0.333333333333333315],"xyz":[0.0595774935314611828,0.0373146126107606821,0.0900106865611391138],"hpluv":[307.715012949244226,189.13048019699076,22.7630226511172538],"hsluv":[307.715012949244226,65.4333859354686211,22.7630226511172538]},"#552266":{"lch":[23.7863579144178132,42.6539605518829816,293.531429927677038],"luv":[23.7863579144178132,17.0296819355444384,-39.1069083914310625],"rgb":[0.333333333333333315,0.133333333333333331,0.4],"xyz":[0.0671624893049693611,0.0403486109201639936,0.129958330968283076],"hpluv":[293.531429927677038,227.546804006344104,23.7863579144178132],"hsluv":[293.531429927677038,71.0608597854246,23.7863579144178132]},"#552277":{"lch":[24.975052770659552,52.81712200152176,285.022920758889427],"luv":[24.975052770659552,13.6904851349353347,-51.0119495147337858],"rgb":[0.333333333333333315,0.133333333333333331,0.466666666666666674],"xyz":[0.0764765023251712805,0.04407421612824481,0.179012132874680985],"hpluv":[285.022920758889427,268.353735360872861,24.975052770659552],"hsluv":[285.022920758889427,75.8822745115455604,24.975052770659552]},"#552288":{"lch":[26.3119033569515395,63.3751525334233818,279.769698022236867],"luv":[26.3119033569515395,10.754023379801918,-62.4560720809542573],"rgb":[0.333333333333333315,0.133333333333333331,0.533333333333333326],"xyz":[0.0876169194271151086,0.0485303829690224,0.237684996278253152],"hpluv":[279.769698022236867,305.637106002952862,26.3119033569515395],"hsluv":[279.769698022236867,79.8897505498065357,26.3119033569515395]},"#552299":{"lch":[27.7783456471686065,73.9162973481211,276.357347681517297],"luv":[27.7783456471686065,8.18468635974612368,-73.4617582341209783],"rgb":[0.333333333333333315,0.133333333333333331,0.6],"xyz":[0.100673883536187808,0.0537531686126515654,0.306451673919371059],"hpluv":[276.357347681517297,337.654974874305083,27.7783456471686065],"hsluv":[276.357347681517297,83.1678045973750102,27.7783456471686065]},"#5522aa":{"lch":[29.3559430420228864,84.3037876124251824,274.032676149589577],"luv":[29.3559430420228864,5.92869585954675404,-84.0950603258353482],"rgb":[0.333333333333333315,0.133333333333333331,0.66666666666666663],"xyz":[0.115731576501440364,0.0597762457987526669,0.38575552353636966],"hpluv":[274.032676149589577,364.410076381253305,29.3559430420228864],"hsluv":[274.032676149589577,85.8312635149374898,29.3559430420228864]},"#5522bb":{"lch":[31.0273723986379082,94.5090555446981568,272.384235640696716],"luv":[31.0273723986379082,3.93164792491766635,-94.4272403734501324],"rgb":[0.333333333333333315,0.133333333333333331,0.733333333333333282],"xyz":[0.132869168608777,0.0666312826416874254,0.476013508635011406],"hpluv":[272.384235640696716,386.516244750379769,31.0273723986379082],"hsluv":[272.384235640696716,87.9935415010939437,31.0273723986379082]},"#5522cc":{"lch":[32.7769760620793207,104.54175742802569,271.176024316906762],"luv":[32.7769760620793207,2.1456208028374788,-104.519736688869415],"rgb":[0.333333333333333315,0.133333333333333331,0.8],"xyz":[0.152161544052498737,0.0743482328191762271,0.577620019305281507],"hpluv":[271.176024316906762,404.725193356887132,32.7769760620793207],"hsluv":[271.176024316906762,89.7538092894248507,32.7769760620793207]},"#5522dd":{"lch":[34.5909880118612847,114.421842397276407,270.265889656874094],"luv":[34.5909880118612847,0.530989812409553341,-114.420610326139567],"rgb":[0.333333333333333315,0.133333333333333331,0.866666666666666696],"xyz":[0.173679869603132281,0.0829555630394297611,0.690949867205287505],"hpluv":[270.265889656874094,419.744772471420788,34.5909880118612847],"hsluv":[270.265889656874094,91.1938440016712519,34.5909880118612847]},"#5522ee":{"lch":[36.4575428526747132,124.16924767107497,269.564389707514863],"luv":[36.4575428526747132,-0.94402906580191559,-124.165659005715739],"rgb":[0.333333333333333315,0.133333333333333331,0.933333333333333348],"xyz":[0.197492049869307018,0.092480435145899792,0.816360683273810728],"hpluv":[269.564389707514863,432.181309790662738,36.4575428526747132],"hsluv":[269.564389707514863,92.960018101107309,36.4575428526747132]},"#5522ff":{"lch":[38.3665568136218695,133.800754994484379,269.013084090219763],"luv":[38.3665568136218695,-2.30459494965050871,-133.780906258001124],"rgb":[0.333333333333333315,0.133333333333333331,1],"xyz":[0.223663098279138411,0.102948854509832488,0.954194871565592573],"hpluv":[269.013084090219763,442.532391911887146,38.3665568136218695],"hsluv":[269.013084090219763,99.9999999999994458,38.3665568136218695]},"#ccaa00":{"lch":[70.5858735612972623,80.4904122142546186,67.9906634155396],"luv":[70.5858735612972623,30.1643998932495876,74.6244962294604335],"rgb":[0.8,0.66666666666666663,0],"xyz":[0.392753797737474875,0.415879162748823417,0.059586129772359088],"hpluv":[67.9906634155396,144.699051457387782,70.5858735612972623],"hsluv":[67.9906634155396,100.000000000002373,70.5858735612972623]},"#ccaa11":{"lch":[70.6139482370970342,79.3332745728624786,67.7767588069511078],"luv":[70.6139482370970342,30.0051392857341135,73.4401802210267078],"rgb":[0.8,0.66666666666666663,0.0666666666666666657],"xyz":[0.393765463237112,0.416283828948678269,0.0649142347371147177],"hpluv":[67.7767588069511078,142.56214209062793,70.6139482370970342],"hsluv":[67.7767588069511078,98.4234445622979308,70.6139482370970342]},"#ccaa22":{"lch":[70.6659431154106,77.2098224605726529,67.3668792611096166],"luv":[70.6659431154106,29.7125737342128318,71.263733037795],"rgb":[0.8,0.66666666666666663,0.133333333333333331],"xyz":[0.395640821375589036,0.41703397220406907,0.0747911209330939103],"hpluv":[67.3668792611096166,138.644204697820271,70.6659431154106],"hsluv":[67.3668792611096166,95.5289103121581746,70.6659431154106]},"#ccaa33":{"lch":[70.7514162745237911,73.7740913884545,66.6515854645136159],"luv":[70.7514162745237911,29.2382542862800783,67.7328653349528622],"rgb":[0.8,0.66666666666666663,0.2],"xyz":[0.398728572108046742,0.418269072497052197,0.0910532747907050605],"hpluv":[66.6515854645136159,132.314688307412609,70.7514162745237911],"hsluv":[66.6515854645136159,90.8407422295077822,70.7514162745237911]},"#ccaa44":{"lch":[70.8745233475107597,68.9449101039795096,65.5199261400916271],"luv":[70.8745233475107597,28.5691680681362534,62.74713750555],"rgb":[0.8,0.66666666666666663,0.266666666666666663],"xyz":[0.403186567352265657,0.420052270594739763,0.114532049743591699],"hpluv":[65.5199261400916271,123.438713002021714,70.8745233475107597],"hsluv":[65.5199261400916271,84.237349466135143,70.8745233475107597]},"#ccaa55":{"lch":[71.0386313772099,62.7256766939065713,63.7915144306433959],"luv":[71.0386313772099,27.7020883768036121,56.2770363138665672],"rgb":[0.8,0.66666666666666663,0.333333333333333315],"xyz":[0.409148981391627642,0.422437236210484623,0.1459340970175656],"hpluv":[63.7915144306433959,112.044384698186093,71.0386313772099],"hsluv":[63.7915144306433959,75.6976413431368229,71.0386313772099]},"#ccaa66":{"lch":[71.2465086991263661,55.2096541299921952,61.1466680322388356],"luv":[71.2465086991263661,26.6424757380098143,48.3558103613508123],"rgb":[0.8,0.66666666666666663,0.4],"xyz":[0.416733977165135827,0.425471234519887942,0.185881741424709562],"hpluv":[61.1466680322388356,98.331070119416168,71.2465086991263661],"hsluv":[61.1466680322388356,65.2901205751262,71.2465086991263661]},"#ccaa77":{"lch":[71.5004247203994794,46.6032511345785068,56.9687004258729388],"luv":[71.5004247203994794,25.4032971934547263,39.0709035986321638],"rgb":[0.8,0.66666666666666663,0.466666666666666674],"xyz":[0.426047990185337733,0.429196839727968737,0.234935543331107471],"hpluv":[56.9687004258729388,82.707885898124573,71.5004247203994794],"hsluv":[56.9687004258729388,53.160756563752912,71.5004247203994794]},"#ccaa88":{"lch":[71.8022091544958556,37.3024926838847648,49.9478623796008847],"luv":[71.8022091544958556,24.003572993357885,28.5535364531929083],"rgb":[0.8,0.66666666666666663,0.533333333333333326],"xyz":[0.437188407287281533,0.433653006568746335,0.293608406734679639],"hpluv":[49.9478623796008847,65.9233659814751149,71.8022091544958556],"hsluv":[49.9478623796008847,39.5178130280575743,71.8022091544958556]},"#ccaa99":{"lch":[72.1532912119235874,28.1535194843350283,37.0598425499876214],"luv":[72.1532912119235874,22.4666918036374241,16.9666855559712388],"rgb":[0.8,0.66666666666666663,0.6],"xyz":[0.450245371396354233,0.438875792212375493,0.362375084375797574],"hpluv":[37.0598425499876214,49.5126161932360702,72.1532912119235874],"hsluv":[37.0598425499876214,26.6696495224772221,72.1532912119235874]},"#ccaaaa":{"lch":[72.5547286434336,21.297823518763618,12.177050630063027],"luv":[72.5547286434336,20.8186322940273918,4.49241984263274841],"rgb":[0.8,0.66666666666666663,0.66666666666666663],"xyz":[0.465303064361606789,0.444898869398476615,0.441678933992796174],"hpluv":[12.177050630063027,37.2485034287350203,72.5547286434336],"hsluv":[12.177050630063027,27.9047031904792959,72.5547286434336]},"#ccaabb":{"lch":[73.0072318845295,20.9674028584132515,335.544386587188285],"luv":[73.0072318845295,19.0862548050106788,-8.68025691700441193],"rgb":[0.8,0.66666666666666663,0.733333333333333282],"xyz":[0.482440656468943463,0.451753906241411374,0.531936919091437921],"hpluv":[335.544386587188285,36.4433325399841053,73.0072318845295],"hsluv":[335.544386587188285,29.1493731958161852,73.0072318845295]},"#ccaacc":{"lch":[73.5111862218870442,28.2733952257813925,307.715012949249683],"luv":[73.5111862218870442,17.2958067637387,-22.366044486780595],"rgb":[0.8,0.66666666666666663,0.8],"xyz":[0.501733031912665162,0.459470856418900175,0.633543429761708077],"hpluv":[307.715012949249683,48.8049486057506,73.5111862218870442],"hsluv":[307.715012949249683,30.3693282248248444,73.5111862218870442]},"#ccaadd":{"lch":[74.0666736076556,39.5441054640130645,293.032470315564865],"luv":[74.0666736076556,15.4717391639018693,-36.3917787995197202],"rgb":[0.8,0.66666666666666663,0.866666666666666696],"xyz":[0.523251357463298761,0.468078186639153682,0.746873277661714075],"hpluv":[293.032470315564865,67.7482749884916871,74.0666736076556],"hsluv":[293.032470315564865,52.1368854824616719,74.0666736076556]},"#ccaaee":{"lch":[74.6734949675833093,52.4074038625381462,285.081329657377239],"luv":[74.6734949675833093,13.6358764846886817,-50.6023601436286],"rgb":[0.8,0.66666666666666663,0.933333333333333348],"xyz":[0.54706353772947347,0.477603058745623699,0.872284093730237298],"hpluv":[285.081329657377239,89.0564736794959799,74.6734949675833093],"hsluv":[285.081329657377239,75.3315532053798194,74.6734949675833093]},"#ccaaff":{"lch":[75.3311933526529316,65.9300530396585458,280.316334998223624],"luv":[75.3311933526529316,11.8069327652914797,-64.8642292214135239],"rgb":[0.8,0.66666666666666663,1],"xyz":[0.573234586139304891,0.488071478109556423,1.01011828202201914],"hpluv":[280.316334998223624,111.057502918871393,75.3311933526529316],"hsluv":[280.316334998223624,99.9999999999973426,75.3311933526529316]},"#553300":{"lch":[24.6368918170402651,35.1311640480653367,43.6144672720514848],"luv":[24.6368918170402651,25.4348822629288698,24.2335604409056025],"rgb":[0.333333333333333315,0.2,0],"xyz":[0.049300031966319241,0.0429919833271212859,0.00570196001226947087],"hpluv":[43.6144672720514848,180.944734702515461,24.6368918170402651],"hsluv":[43.6144672720514848,100.000000000002245,24.6368918170402651]},"#553311":{"lch":[24.7639934196671305,31.9442274162558917,39.8156129865950632],"luv":[24.7639934196671305,24.536650698978292,20.4544967598277161],"rgb":[0.333333333333333315,0.2,0.0666666666666666657],"xyz":[0.0503116974659563593,0.0433966495269761388,0.0110300649770251023],"hpluv":[39.8156129865950632,163.685811409294416,24.7639934196671305],"hsluv":[39.8156129865950632,85.3309596574143256,24.7639934196671305]},"#553322":{"lch":[24.9975315322943885,26.9096454002331456,31.2519949010175395],"luv":[24.9975315322943885,23.0048892205904032,13.9608054035092266],"rgb":[0.333333333333333315,0.2,0.133333333333333331],"xyz":[0.0521870556044333814,0.0441467927823669601,0.0209069511730043],"hpluv":[31.2519949010175395,136.59983556614165,24.9975315322943885],"hsluv":[31.2519949010175395,60.4417762068684823,24.9975315322943885]},"#553333":{"lch":[25.3763514371309924,21.2787516643900716,12.1770506300621495],"luv":[25.3763514371309924,20.7999895475976082,4.48839695377019332],"rgb":[0.333333333333333315,0.2,0.2],"xyz":[0.0552748063368911219,0.0453818930753500729,0.0371691050306154416],"hpluv":[12.1770506300621495,106.403592780468983,25.3763514371309924],"hsluv":[12.1770506300621495,24.9336598370546909,25.3763514371309924]},"#553344":{"lch":[25.9113402150992655,19.4972565515274532,338.627269772390264],"luv":[25.9113402150992655,18.1564179844864455,-7.10545558065754257],"rgb":[0.333333333333333315,0.2,0.266666666666666663],"xyz":[0.05973280158111,0.047165091173037646,0.0606478799835020801],"hpluv":[338.627269772390264,95.4823185470749536,25.9113402150992655],"hsluv":[338.627269772390264,32.9723178491547841,25.9113402150992655]},"#553355":{"lch":[26.6061908173450519,25.0719265662328183,307.715012949245363],"luv":[26.6061908173450519,15.3373584467403763,-19.8334802195371829],"rgb":[0.333333333333333315,0.2,0.333333333333333315],"xyz":[0.065695215620472,0.0495500567887824789,0.0920499272574759886],"hpluv":[307.715012949245363,119.576085528419512,26.6061908173450519],"hsluv":[307.715012949245363,41.369683748934996,26.6061908173450519]},"#553366":{"lch":[27.4586282592714284,35.2024776289392847,290.893042573756475],"luv":[27.4586282592714284,12.5540679631371699,-32.8878367910220533],"rgb":[0.333333333333333315,0.2,0.4],"xyz":[0.0732802113939801658,0.0525840550981857904,0.13199757166461995],"hpluv":[290.893042573756475,162.679833835368925,27.4586282592714284],"hsluv":[290.893042573756475,49.429407074258,27.4586282592714284]},"#553377":{"lch":[28.461655060413058,46.8206771520520633,282.253113271302652],"luv":[28.461655060413058,9.93678843358592445,-45.7540822725452898],"rgb":[0.333333333333333315,0.2,0.466666666666666674],"xyz":[0.0825942244141820853,0.0563096603062666068,0.18105137357101786],"hpluv":[282.253113271302652,208.74537696470955,28.461655060413058],"hsluv":[282.253113271302652,56.732994513665389,28.461655060413058]},"#553388":{"lch":[29.6048600369324433,58.6666973974172876,277.388246485053742],"luv":[29.6048600369324433,7.54407762538358551,-58.1796207988872567],"rgb":[0.333333333333333315,0.2,0.533333333333333326],"xyz":[0.0937346415161259133,0.0607658271470442046,0.239724236974590027],"hpluv":[277.388246485053742,251.459446283522851,29.6048600369324433],"hsluv":[277.388246485053742,63.1061783000114715,29.6048600369324433]},"#553399":{"lch":[30.8756880539778678,70.2946203588512759,274.394660626066695],"luv":[30.8756880539778678,5.38640350826703,-70.0879469569565714],"rgb":[0.333333333333333315,0.2,0.6],"xyz":[0.106791605625198627,0.0659886127906733622,0.308490914615707934],"hpluv":[274.394660626066695,288.898157334443908,30.8756880539778678],"hsluv":[274.394660626066695,68.537799314251,30.8756880539778678]},"#5533aa":{"lch":[32.2605562861205,81.571224268378316,272.422737250332261],"luv":[32.2605562861205,3.44819039224039026,-81.498310483475251],"rgb":[0.333333333333333315,0.2,0.66666666666666663],"xyz":[0.121849298590451169,0.0720116899767744567,0.387794764232706535],"hpluv":[272.422737250332261,320.851781583216223,32.2605562861205],"hsluv":[272.422737250332261,73.1042224024611897,32.2605562861205]},"#5533bb":{"lch":[33.7457437232739395,92.4864953275551755,271.055064965734516],"luv":[33.7457437232739395,1.70298313903478205,-92.4708152143261231],"rgb":[0.333333333333333315,0.2,0.733333333333333282],"xyz":[0.138986890697787802,0.0788667268197092153,0.478052749331348281],"hpluv":[271.055064965734516,347.775228922495899,33.7457437232739395],"hsluv":[271.055064965734516,76.9172199670655772,33.7457437232739395]},"#5533cc":{"lch":[35.3180325241442,103.075547069605378,270.067872161558512],"luv":[35.3180325241442,0.12210251098248695,-103.075474748725966],"rgb":[0.333333333333333315,0.2,0.8],"xyz":[0.158279266141509556,0.0865836769971980169,0.579659260001618493],"hpluv":[270.067872161558512,370.338167129355497,35.3180325241442],"hsluv":[270.067872161558512,80.0940957669769205,35.3180325241442]},"#5533dd":{"lch":[36.9651203282397915,113.385246995104879,269.332372034398134],"luv":[36.9651203282397915,-1.32116971635525937,-113.377549570986602],"rgb":[0.333333333333333315,0.2,0.866666666666666696],"xyz":[0.179797591692143099,0.0951910072174515509,0.69298910790162449],"hpluv":[269.332372034398134,389.227711455139399,36.9651203282397915],"hsluv":[269.332372034398134,84.8119298710034855,36.9651203282397915]},"#5533ee":{"lch":[38.6758450270606247,123.460606758128,268.77009087446072],"luv":[38.6758450270606247,-2.64999738284680575,-123.432163292052948],"rgb":[0.333333333333333315,0.2,0.933333333333333348],"xyz":[0.203609771958317837,0.104715879323921596,0.818399923970147714],"hpluv":[268.77009087446072,405.067987408818738,38.6758450270606247],"hsluv":[268.77009087446072,92.2936685874649356,38.6758450270606247]},"#5533ff":{"lch":[40.4402700894382363,133.340096114557781,268.33094335317071],"luv":[40.4402700894382363,-3.88371885476632706,-133.283524712158766],"rgb":[0.333333333333333315,0.2,1],"xyz":[0.22978082036814923,0.115184298687854292,0.956234112261929559],"hpluv":[268.33094335317071,418.394573227645935,40.4402700894382363],"hsluv":[268.33094335317071,99.99999999999946,40.4402700894382363]},"#ccbb00":{"lch":[75.0632334950121418,83.0331806403360275,77.5616137481136292],"luv":[75.0632334950121418,17.8844849446013434,81.0842419062853423],"rgb":[0.8,0.733333333333333282,0],"xyz":[0.426708295646073654,0.483788158566022,0.0709042957418917],"hpluv":[77.5616137481136292,140.366584388758554,75.0632334950121418],"hsluv":[77.5616137481136292,100.000000000002373,75.0632334950121418]},"#ccbb11":{"lch":[75.0886164663743898,81.9438461169387438,77.472162284636525],"luv":[75.0886164663743898,17.7747618107910519,79.9928231718707394],"rgb":[0.8,0.733333333333333282,0.0666666666666666657],"xyz":[0.427719961145710759,0.484192824765876828,0.0762324007066473436],"hpluv":[77.472162284636525,138.478250548668058,75.0886164663743898],"hsluv":[77.472162284636525,98.6397508878022222,75.0886164663743898]},"#ccbb22":{"lch":[75.1356323460541802,79.9401497843360289,77.301186242421764],"luv":[75.1356323460541802,17.5729239259544805,77.9847414064744839],"rgb":[0.8,0.733333333333333282,0.133333333333333331],"xyz":[0.429595319284187815,0.484942968021267629,0.0861092869026265362],"hpluv":[77.301186242421764,135.007637737713509,75.1356323460541802],"hsluv":[77.301186242421764,96.1390577710114087,75.1356323460541802]},"#ccbb33":{"lch":[75.2129378077961235,76.6847204783522471,77.0041162235267223],"luv":[75.2129378077961235,17.2449407213965777,74.720535158405653],"rgb":[0.8,0.733333333333333282,0.2],"xyz":[0.432683070016645521,0.486178068314250755,0.102371440760237686],"hpluv":[77.0041162235267223,129.376563997369885,75.2129378077961235],"hsluv":[77.0041162235267223,92.0797058264172392,75.2129378077961235]},"#ccbb44":{"lch":[75.3243183189310628,72.0782997366288,76.5373230188340585],"luv":[75.3243183189310628,16.7806861485978907,70.0977165484408431],"rgb":[0.8,0.733333333333333282,0.266666666666666663],"xyz":[0.437141065260864436,0.487961266411938321,0.125850215713124325],"hpluv":[76.5373230188340585,121.425150369898518,75.3243183189310628],"hsluv":[76.5373230188340585,86.34290383100182,75.3243183189310628]},"#ccbb55":{"lch":[75.4728625341146397,66.0852327898053,75.831238609121371],"luv":[75.4728625341146397,16.1762634357197506,64.0748507149330351],"rgb":[0.8,0.733333333333333282,0.333333333333333315],"xyz":[0.443103479300226422,0.490346232027683182,0.157252262987098212],"hpluv":[75.831238609121371,111.10994393806304,75.4728625341146397],"hsluv":[75.831238609121371,78.8905565478608395,75.4728625341146397]},"#ccbb66":{"lch":[75.6611363515091284,58.7289677793131,74.7643785098968863],"luv":[75.6611363515091284,15.4333320312120961,56.6648384700597134],"rgb":[0.8,0.733333333333333282,0.4],"xyz":[0.450688475073734607,0.493380230337086501,0.197199907394242202],"hpluv":[74.7643785098968863,98.4960546107130739,75.6611363515091284],"hsluv":[74.7643785098968863,69.7569980114599701,75.6611363515091284]},"#ccbb77":{"lch":[75.8912747684230737,50.090867045562554,73.1036630558194389],"luv":[75.8912747684230737,14.5584607724557671,47.9285528814827799],"rgb":[0.8,0.733333333333333282,0.466666666666666674],"xyz":[0.460002488093936512,0.497105835545167296,0.246253709300640111],"hpluv":[73.1036630558194389,83.7540906733876795,75.8912747684230737],"hsluv":[73.1036630558194389,59.0406908273499624,75.8912747684230737]},"#ccbb88":{"lch":[76.1650362860674335,40.3168412407358332,70.3426656865815119],"luv":[76.1650362860674335,13.5623472284534756,37.9672283066009157],"rgb":[0.8,0.733333333333333282,0.533333333333333326],"xyz":[0.471142905195880313,0.501562002385944838,0.304926572704212251],"hpluv":[70.3426656865815119,67.6831847004182379,76.1650362860674335],"hsluv":[70.3426656865815119,46.8939441374685586,76.1650362860674335]},"#ccbb99":{"lch":[76.4838383644648871,29.6573629081618826,65.1594516064859732],"luv":[76.4838383644648871,12.4588924968264081,26.9134756658990248],"rgb":[0.8,0.733333333333333282,0.6],"xyz":[0.484199869304953068,0.506784788029574,0.373693250345330186],"hpluv":[65.1594516064859732,50.6096239917615662,76.4838383644648871],"hsluv":[65.1594516064859732,33.5105935092195324,76.4838383644648871]},"#ccbbaa":{"lch":[76.8487828748923,18.695758935396551,52.9508743401004551],"luv":[76.8487828748923,11.26418644921627,14.9214444946778713],"rgb":[0.8,0.733333333333333282,0.66666666666666663],"xyz":[0.499257562270205568,0.512807865215675118,0.452997099962328786],"hpluv":[52.9508743401004551,32.5142912020767696,76.8487828748923],"hsluv":[52.9508743401004551,19.1124274046376854,76.8487828748923]},"#ccbbbb":{"lch":[77.2606763328388126,10.2255548171674207,12.1770506300639045],"luv":[77.2606763328388126,9.99548454110707,2.15690985147396086],"rgb":[0.8,0.733333333333333282,0.733333333333333282],"xyz":[0.516395154377542243,0.519662902058609877,0.543255085060970533],"hpluv":[12.1770506300639045,18.1733155366010308,77.2606763328388126],"hsluv":[12.1770506300639045,17.1437484893634,77.2606763328388126]},"#ccbbcc":{"lch":[77.7200476270310361,14.1732404034447406,307.715012949257925],"luv":[77.7200476270310361,8.67025786172679247,-11.2119299027867267],"rgb":[0.8,0.733333333333333282,0.8],"xyz":[0.535687529821264,0.527379852236098734,0.644861595731240689],"hpluv":[307.715012949257925,25.815587331502627,77.7200476270310361],"hsluv":[307.715012949257925,18.1614974693692588,77.7200476270310361]},"#ccbbdd":{"lch":[78.2271648233418375,26.0669286991650679,286.275412631614586],"luv":[78.2271648233418375,7.3053819239814537,-25.022313377306272],"rgb":[0.8,0.733333333333333282,0.866666666666666696],"xyz":[0.557205855371897485,0.53598718245635224,0.758191443631246687],"hpluv":[286.275412631614586,48.8074477639820898,78.2271648233418375],"hsluv":[286.275412631614586,43.4510455050629929,78.2271648233418375]},"#ccbbee":{"lch":[78.7820519440635,39.5678846485468299,278.599571826643512],"luv":[78.7820519440635,5.9165048525659989,-39.1230426461218741],"rgb":[0.8,0.733333333333333282,0.933333333333333348],"xyz":[0.581018035638072305,0.545512054562822257,0.88360225969976991],"hpluv":[278.599571826643512,76.4037468789834,78.7820519440635],"hsluv":[278.599571826643512,70.6968150087455314,78.7820519440635]},"#ccbbff":{"lch":[79.3845061922316546,53.5695670840829834,274.837592460092935],"luv":[79.3845061922316546,4.51760925339512553,-53.3787385033564235],"rgb":[0.8,0.733333333333333282,1],"xyz":[0.607189084047903616,0.555980473926755,1.02143644799155164],"hpluv":[274.837592460092935,107.038572744282547,79.3845061922316546],"hsluv":[274.837592460092935,99.9999999999963762,79.3845061922316546]},"#554400":{"lch":[29.5776499109456879,34.0768703371065413,65.9474553070004674],"luv":[29.5776499109456879,13.8888553561515469,31.1180460322924546],"rgb":[0.333333333333333315,0.266666666666666663,0],"xyz":[0.0581326024492852811,0.0606571242930536,0.0086461501732580659],"hpluv":[65.9474553070004674,146.195957524823825,29.5776499109456879],"hsluv":[65.9474553070004674,100.000000000002217,29.5776499109456879]},"#554411":{"lch":[29.6787804923011507,30.8713815411758574,64.2244588846852906],"luv":[29.6787804923011507,13.4243191404277429,27.7998175151708296],"rgb":[0.333333333333333315,0.266666666666666663,0.0666666666666666657],"xyz":[0.0591442679489224,0.0610617904929084548,0.0139742551380136974],"hpluv":[64.2244588846852906,131.992525946838612,29.6787804923011507],"hsluv":[64.2244588846852906,89.4077694450363509,29.6787804923011507]},"#554422":{"lch":[29.8650740872788916,25.3442505658492152,60.1547603291711539],"luv":[29.8650740872788916,12.6127938179319639,21.9829131111162219],"rgb":[0.333333333333333315,0.266666666666666663,0.133333333333333331],"xyz":[0.0610196260873994215,0.0618119337482992762,0.0238511413339928952],"hpluv":[60.1547603291711539,107.684992873038837,29.8650740872788916],"hsluv":[60.1547603291711539,70.9921927199271892,29.8650740872788916]},"#554433":{"lch":[30.1685472793317686,17.4710669916127905,49.2680266756281497],"luv":[30.1685472793317686,11.400244593092479,13.2390560480378525],"rgb":[0.333333333333333315,0.266666666666666663,0.2],"xyz":[0.064107376819857162,0.0630470340412823821,0.0401132951916040384],"hpluv":[49.2680266756281497,73.4859575586117302,30.1685472793317686],"hsluv":[49.2680266756281497,43.7071568358896,30.1685472793317686]},"#554444":{"lch":[30.5997780424982437,10.1013456632853149,12.1770506300629258],"luv":[30.5997780424982437,9.87407003600776356,2.13071000682558],"rgb":[0.333333333333333315,0.266666666666666663,0.266666666666666663],"xyz":[0.0685653720640760356,0.0648302321389699621,0.06359207014449067],"hpluv":[12.1770506300629258,41.8890279889816597,30.5997780424982437],"hsluv":[12.1770506300629258,9.81589763549682282,30.5997780424982437]},"#554455":{"lch":[31.1643459369041338,13.3310860490153988,307.715012949249],"luv":[31.1643459369041338,8.15508312366709198,-10.5457325251654854],"rgb":[0.333333333333333315,0.266666666666666663,0.333333333333333315],"xyz":[0.0745277861034380346,0.0672151977547148,0.0949941174184645853],"hpluv":[307.715012949249,54.2808752323906702,31.1643459369041338],"hsluv":[307.715012949249,18.7795296363480162,31.1643459369041338]},"#554466":{"lch":[31.8635722620044533,24.8340912161126894,284.841165372516684],"luv":[31.8635722620044533,6.36101223964894835,-24.005616214070443],"rgb":[0.333333333333333315,0.266666666666666663,0.4],"xyz":[0.0821127818769462,0.0702491960641181135,0.134941761825608547],"hpluv":[284.841165372516684,98.8992811700442331,31.8635722620044533],"hsluv":[284.841165372516684,27.8963704264996828,31.8635722620044533]},"#554477":{"lch":[32.6951743277909443,37.9095930577936784,276.944338121378166],"luv":[32.6951743277909443,4.58346102749711282,-37.6314912117090259],"rgb":[0.333333333333333315,0.266666666666666663,0.466666666666666674],"xyz":[0.0914267948971481254,0.0739748012721989229,0.183995563732006456],"hpluv":[276.944338121378166,147.131204947893167,32.6951743277909443],"hsluv":[276.944338121378166,36.6308714978363952,32.6951743277909443]},"#554488":{"lch":[33.6539551717380903,51.1018638808679526,273.231940865766],"luv":[33.6539551717380903,2.88102600900669881,-51.0205858574182116],"rgb":[0.333333333333333315,0.266666666666666663,0.533333333333333326],"xyz":[0.102567211999091953,0.0784309681129765207,0.242668427135578624],"hpluv":[273.231940865766,192.681471981123309,33.6539551717380903],"hsluv":[273.231940865766,44.6505812495932801,33.6539551717380903]},"#554499":{"lch":[34.7325237210335871,63.9719124096453271,271.149517924849135],"luv":[34.7325237210335871,1.28337422751110575,-63.9590378909774913],"rgb":[0.333333333333333315,0.266666666666666663,0.6],"xyz":[0.115624176108164667,0.0836537537566056782,0.311435104776696559],"hpluv":[271.149517924849135,233.718085138698228,34.7325237210335871],"hsluv":[271.149517924849135,51.7999710200133876,34.7325237210335871]},"#5544aa":{"lch":[35.9219992682327671,76.3678985235758461,269.849629436139082],"luv":[35.9219992682327671,-0.200424374653859844,-76.367635520403681],"rgb":[0.333333333333333315,0.266666666666666663,0.66666666666666663],"xyz":[0.130681869073417223,0.0896768309427067867,0.390738954393695104],"hpluv":[269.849629436139082,269.767524553786757,35.9219992682327671],"hsluv":[269.849629436139082,58.0490239963672465,35.9219992682327671]},"#5544bb":{"lch":[37.2126506061998725,88.2627815084196925,268.978337620063314],"luv":[37.2126506061998725,-1.57376312233016602,-88.2487499584998574],"rgb":[0.333333333333333315,0.266666666666666663,0.733333333333333282],"xyz":[0.147819461180753842,0.0965318677856415452,0.480996939492336906],"hpluv":[268.978337620063314,300.972163983169935,37.2126506061998725],"hsluv":[268.978337620063314,66.0075029321504729,37.2126506061998725]},"#5544cc":{"lch":[38.5944341452357733,99.6871153018899605,268.363808876145868],"luv":[38.5944341452357733,-2.84637030136680202,-99.6464707519528758],"rgb":[0.333333333333333315,0.266666666666666663,0.8],"xyz":[0.167111836624475596,0.104248817963130347,0.582603450162607062],"hpluv":[268.363808876145868,327.758284181939189,38.5944341452357733],"hsluv":[268.363808876145868,74.5283681063652352,38.5944341452357733]},"#5544dd":{"lch":[40.0574145710935738,110.694467066426,267.913412719582],"luv":[40.0574145710935738,-4.03035995406870118,-110.621070496360275],"rgb":[0.333333333333333315,0.266666666666666663,0.866666666666666696],"xyz":[0.18863016217510914,0.112856148183383881,0.695933298062613059],"hpluv":[267.913412719582,350.65684831918054,40.0574145710935738],"hsluv":[267.913412719582,82.9425769408534,40.0574145710935738]},"#5544ee":{"lch":[41.5920687629554777,121.343449115737442,267.573227144435918],"luv":[41.5920687629554777,-5.13798666158471651,-121.23462268002875],"rgb":[0.333333333333333315,0.266666666666666663,0.933333333333333348],"xyz":[0.212442342441283877,0.122381020289853898,0.821344114131136283],"hpluv":[267.573227144435918,370.207437425804358,41.5920687629554777],"hsluv":[267.573227144435918,91.3878688389195872,41.5920687629554777]},"#5544ff":{"lch":[43.1894854939413833,131.689092168021887,267.309962581974105],"luv":[43.1894854939413833,-6.18053297470727,-131.543977468321657],"rgb":[0.333333333333333315,0.266666666666666663,1],"xyz":[0.23861339085111527,0.132849439653786594,0.959178302422918128],"hpluv":[267.309962581974105,386.911020330846497,43.1894854939413833],"hsluv":[267.309962581974105,99.9999999999994174,43.1894854939413833]},"#cccc00":{"lch":[79.627228346343,87.7811065558180132,85.8743202181747449],"luv":[79.627228346343,6.31536666608958797,87.5536339167982192],"rgb":[0.8,0.8,0],"xyz":[0.464932038955690574,0.560235645185256814,0.0836455435117636481],"hpluv":[85.8743202181747449,177.871840357077815,79.627228346343],"hsluv":[85.8743202181747449,100.000000000002245,79.627228346343]},"#cccc11":{"lch":[79.6502471087807891,86.7718911178833707,85.8743202181747],"luv":[79.6502471087807891,6.24275917928854351,86.5470337215737],"rgb":[0.8,0.8,0.0666666666666666657],"xyz":[0.465943704455327679,0.560640311385111723,0.0889736484765192848],"hpluv":[85.8743202181747,176.061859354342118,79.6502471087807891],"hsluv":[85.8743202181747,98.8217369524532927,79.6502471087807891]},"#cccc22":{"lch":[79.6928884771461838,84.9132131482774497,85.8743202181746597],"luv":[79.6928884771461838,6.10903754655005482,84.6931722597497298],"rgb":[0.8,0.8,0.133333333333333331],"xyz":[0.467819062593804735,0.561390454640502523,0.0988505346724984774],"hpluv":[85.8743202181746597,172.717957044242922,79.6928884771461838],"hsluv":[85.8743202181746597,96.653203912443459,79.6928884771461838]},"#cccc33":{"lch":[79.7630142061039891,81.8867831673476445,85.8743202181745602],"luv":[79.7630142061039891,5.89130259459140682,81.6745848549912665],"rgb":[0.8,0.8,0.2],"xyz":[0.470906813326262441,0.56262555493348565,0.115112688530109614],"hpluv":[85.8743202181745602,167.243641009868185,79.7630142061039891],"hsluv":[85.8743202181745602,93.1263971058523623,79.7630142061039891]},"#cccc44":{"lch":[79.8640786601047523,77.5899505798540901,85.8743202181744],"luv":[79.8640786601047523,5.58216917901353593,77.3888869169280156],"rgb":[0.8,0.8,0.266666666666666663],"xyz":[0.475364808570481356,0.564408753031173216,0.138591463482996252],"hpluv":[85.8743202181744,159.406599578518,79.8640786601047523],"hsluv":[85.8743202181744,88.1281264379617113,79.8640786601047523]},"#cccc55":{"lch":[79.9989166638852396,71.9729259129294832,85.8743202181741481],"luv":[79.9989166638852396,5.17805522174052,71.7864179952492236],"rgb":[0.8,0.8,0.333333333333333315],"xyz":[0.481327222609843342,0.566793718646918,0.169993510756970168],"hpluv":[85.8743202181741481,149.042041148428552,79.9989166638852396],"hsluv":[85.8743202181741481,81.6104176612222147,79.9989166638852396]},"#cccc66":{"lch":[80.1699032642976448,65.0330295388014,85.8743202181738],"luv":[80.1699032642976448,4.67876793832737103,64.8645054060685453],"rgb":[0.8,0.8,0.4],"xyz":[0.488912218383351527,0.569827716956321284,0.209941155164114129],"hpluv":[85.8743202181738,136.038559250079544,80.1699032642976448],"hsluv":[85.8743202181738,73.5839630734023,80.1699032642976448]},"#cccc77":{"lch":[80.3790384438565724,56.8098315426934803,85.8743202181733096],"luv":[80.3790384438565724,4.0871541782499472,56.6626166941875837],"rgb":[0.8,0.8,0.466666666666666674],"xyz":[0.498226231403553432,0.573553322164402135,0.258994957070512],"hpluv":[85.8743202181733096,120.326663009793734,80.3790384438565724],"hsluv":[85.8743202181733096,64.1122831116318252,80.3790384438565724]},"#cccc88":{"lch":[80.6279973255091704,47.3795499902223085,85.8743202181724854],"luv":[80.6279973255091704,3.40869741112766222,47.2567724166107865],"rgb":[0.8,0.8,0.533333333333333326],"xyz":[0.509366648505497288,0.578009489005179677,0.317667820474084206],"hpluv":[85.8743202181724854,101.866799769447482,80.6279973255091704],"hsluv":[85.8743202181724854,53.3047126681541172,80.6279973255091704]},"#cccc99":{"lch":[80.9181626169042119,36.8483625211582861,85.8743202181711496],"luv":[80.9181626169042119,2.65103653276840934,36.7528750683892724],"rgb":[0.8,0.8,0.6],"xyz":[0.522423612614569932,0.58323227464880889,0.386434498115202141],"hpluv":[85.8743202181711496,80.635831276566,80.9181626169042119],"hsluv":[85.8743202181711496,41.30786304104587,80.9181626169042119]},"#ccccaa":{"lch":[81.2506473976222452,25.3448572993520607,85.8743202181683216],"luv":[81.2506473976222452,1.82342275263520492,25.27917959487],"rgb":[0.8,0.8,0.66666666666666663],"xyz":[0.537481305579822544,0.58925535183491,0.465738347732200686],"hpluv":[85.8743202181683216,56.6117825452175509,81.2506473976222452],"hsluv":[85.8743202181683216,28.2959036617823898,81.2506473976222452]},"#ccccbb":{"lch":[81.6263125989092657,13.0121158497344798,85.8743202181599],"luv":[81.6263125989092657,0.936149997616518514,12.9783967449324749],"rgb":[0.8,0.8,0.733333333333333282],"xyz":[0.554618897687159107,0.596110388677844716,0.555996332830842488],"hpluv":[85.8743202181599,29.7570160502500514,81.6263125989092657],"hsluv":[85.8743202181599,14.4603328966824272,81.6263125989092657]},"#cccccc":{"lch":[82.0457816743453,4.34523248843710382e-12,0],"luv":[82.0457816743453,4.08534684758697557e-12,1.48019813318368677e-12],"rgb":[0.8,0.8,0.8],"xyz":[0.573911273130880861,0.603827338855333573,0.657602843501112644],"hpluv":[0,1.02065966511349575e-11,82.0457816743453],"hsluv":[0,1.01642596056880755e-11,82.0457816743453]},"#ccccdd":{"lch":[82.5094539517328087,13.5418343873660199,265.874320218194214],"luv":[82.5094539517328087,-0.974260325972223118,-13.5067425899839115],"rgb":[0.8,0.8,0.866666666666666696],"xyz":[0.59542959868151446,0.612434669075587079,0.770932691401118642],"hpluv":[265.874320218194214,32.7843842039110882,82.5094539517328087],"hsluv":[265.874320218194214,30.4637656032122131,82.5094539517328087]},"#ccccee":{"lch":[83.0175175610870895,27.4698052042972165,265.874320218185687],"luv":[83.0175175610870895,-1.97630103922669687,-27.3986209901955817],"rgb":[0.8,0.8,0.933333333333333348],"xyz":[0.61924177894768917,0.621959541182057096,0.896343507469641865],"hpluv":[265.874320218185687,68.7964750954906776,83.0175175610870895],"hsluv":[265.874320218185687,63.7216981471091941,83.0175175610870895]},"#ccccff":{"lch":[83.5699624582004219,41.6509292947620153,265.874320218182845],"luv":[83.5699624582004219,-2.99655473483939438,-41.5429966521238825],"rgb":[0.8,0.8,1],"xyz":[0.645412827357520591,0.63242796054598982,1.03417769576142371],"hpluv":[265.874320218182845,108.336501116640306,83.5699624582004219],"hsluv":[265.874320218182845,99.9999999999952536,83.5699624582004219]},"#555500":{"lch":[34.8595382729148753,38.4291768930055397,85.8743202181747307],"luv":[34.8595382729148753,2.76476741155027961,38.3295929776711901],"rgb":[0.333333333333333315,0.333333333333333315,0],"xyz":[0.0699458591636312466,0.084283637721745866,0.0125839024113732767],"hpluv":[85.8743202181747307,139.887458074797564,34.8595382729148753],"hsluv":[85.8743202181747307,100.000000000002331,34.8595382729148753]},"#555511":{"lch":[34.9408046802893,35.5443725161734108,85.8743202181745318],"luv":[34.9408046802893,2.55722164100294558,35.4522641737772517],"rgb":[0.333333333333333315,0.333333333333333315,0.0666666666666666657],"xyz":[0.0709575246632683648,0.0846883039216007188,0.0179120073761289064],"hpluv":[85.8743202181745318,129.085444875460666,34.9408046802893],"hsluv":[85.8743202181745318,92.2780688504912,34.9408046802893]},"#555522":{"lch":[35.0907688239250604,30.4130442263608813,85.8743202181740202],"luv":[35.0907688239250604,2.18805086034508589,30.3342330139914047],"rgb":[0.333333333333333315,0.333333333333333315,0.133333333333333331],"xyz":[0.0728328828017454,0.0854384471769915332,0.027788893572108106],"hpluv":[85.8743202181740202,109.978131404858061,35.0907688239250604],"hsluv":[85.8743202181740202,78.6190076783406653,35.0907688239250604]},"#555533":{"lch":[35.3357817552570097,22.5221214621125654,85.8743202181728549],"luv":[35.3357817552570097,1.62034247131604014,22.4637584885032275],"rgb":[0.333333333333333315,0.333333333333333315,0.2],"xyz":[0.0759206335342031274,0.0866735474699746461,0.0440510474297192492],"hpluv":[85.8743202181728549,80.8786547215116656,35.3357817552570097],"hsluv":[85.8743202181728549,57.8169450175211566,35.3357817552570097]},"#555544":{"lch":[35.6854507669058592,12.1926559388895619,85.8743202181691743],"luv":[35.6854507669058592,0.877194374836262392,12.1610603515028455],"rgb":[0.333333333333333315,0.333333333333333315,0.266666666666666663],"xyz":[0.080378628778422,0.0884567455676622261,0.0675298223826058808],"hpluv":[85.8743202181691743,43.355725530805,35.6854507669058592],"hsluv":[85.8743202181691743,30.9932899828832262,35.6854507669058592]},"#555555":{"lch":[36.1458508397197278,1.89718584003012571e-12,0],"luv":[36.1458508397197278,1.79982851973451413e-12,5.9994283991150471e-13],"rgb":[0.333333333333333315,0.333333333333333315,0.333333333333333315],"xyz":[0.086341042817784,0.090841711183407059,0.0989318696565798],"hpluv":[0,6.66025333978279224e-12,36.1458508397197278],"hsluv":[0,1.90696849203660445e-12,36.1458508397197278]},"#555566":{"lch":[36.7200402720523087,13.391014832031539,265.874320218184835],"luv":[36.7200402720523087,-0.963409690459316,-13.3563138627398903],"rgb":[0.333333333333333315,0.333333333333333315,0.4],"xyz":[0.0939260385912921714,0.0938757094928103775,0.138879514063723758],"hpluv":[265.874320218184835,46.2753453717946712,36.7200402720523087],"hsluv":[265.874320218184835,10.0205788523093844,36.7200402720523087]},"#555577":{"lch":[37.4084382237490445,27.3651172837118537,265.874320218181],"luv":[37.4084382237490445,-1.96876932050326592,-27.294204353927416],"rgb":[0.333333333333333315,0.333333333333333315,0.466666666666666674],"xyz":[0.103240051611494091,0.0976013147008911869,0.187933315970121667],"hpluv":[265.874320218181,92.8254499938530131,37.4084382237490445],"hsluv":[265.874320218181,20.457601163446,37.4084382237490445]},"#555588":{"lch":[38.2091925227490421,41.4380747403329508,265.874320218179832],"luv":[38.2091925227490421,-2.98124102314999906,-41.330693680935326],"rgb":[0.333333333333333315,0.333333333333333315,0.533333333333333326],"xyz":[0.114380468713437919,0.102057481541668785,0.246606179373693835],"hpluv":[265.874320218179832,137.616667264503377,38.2091925227490421],"hsluv":[265.874320218179832,30.9677616121988244,38.2091925227490421]},"#555599":{"lch":[39.1185695394092079,55.2798607696674651,265.874320218179207],"luv":[39.1185695394092079,-3.97708121608675258,-55.1366106295487626],"rgb":[0.333333333333333315,0.333333333333333315,0.6],"xyz":[0.127437432822510632,0.107280267185297942,0.315372857014811769],"hpluv":[265.874320218179207,179.317758559659353,39.1185695394092079],"hsluv":[265.874320218179207,41.3377460212352688,39.1185695394092079]},"#5555aa":{"lch":[40.1313601009005083,68.6985541131433166,265.874320218178866],"luv":[40.1313601009005083,-4.94248222285034178,-68.5205312786852829],"rgb":[0.333333333333333315,0.333333333333333315,0.66666666666666663],"xyz":[0.142495125787763188,0.113303344371399051,0.394676706631810315],"hpluv":[265.874320218178866,217.221618066114,40.1313601009005083],"hsluv":[265.874320218178866,51.4705865731736907,40.1313601009005083]},"#5555bb":{"lch":[41.2412811653463791,81.6070675548115787,265.874320218178639],"luv":[41.2412811653463791,-5.8711785983783864,-81.3955940869131],"rgb":[0.333333333333333315,0.333333333333333315,0.733333333333333282],"xyz":[0.159632717895099807,0.120158381214333809,0.484934691730452117],"hpluv":[265.874320218178639,251.093199488524249,41.2412811653463791],"hsluv":[265.874320218178639,61.3584924374872642,41.2412811653463791]},"#5555cc":{"lch":[42.4413509436270431,93.9883543596933,265.874320218178468],"luv":[42.4413509436270431,-6.76194392407029365,-93.7447964935174838],"rgb":[0.333333333333333315,0.333333333333333315,0.8],"xyz":[0.178925093338821561,0.127875331391822611,0.586541202400722272],"hpluv":[265.874320218178468,281.011551484187919,42.4413509436270431],"hsluv":[265.874320218178468,71.0546332315999791,42.4413509436270431]},"#5555dd":{"lch":[43.7242196004532389,105.866759380085014,265.874320218178411],"luv":[43.7242196004532389,-7.61652967783202328,-105.592420264465588],"rgb":[0.333333333333333315,0.333333333333333315,0.866666666666666696],"xyz":[0.200443418889455105,0.136482661612076145,0.69987105030072827],"hpluv":[265.874320218178411,307.239379297131052,43.7242196004532389],"hsluv":[265.874320218178411,80.6500300064864462,43.7242196004532389]},"#5555ee":{"lch":[45.0824447652298588,117.287521338877212,265.874320218178354],"luv":[45.0824447652298588,-8.43819053636753402,-116.983586892732674],"rgb":[0.333333333333333315,0.333333333333333315,0.933333333333333348],"xyz":[0.224255599155629842,0.146007533718546162,0.825281866369251493],"hpluv":[265.874320218178354,330.128999417958312,45.0824447652298588],"hsluv":[265.874320218178354,90.2572110855712708,45.0824447652298588]},"#5555ff":{"lch":[46.508708270344421,128.30356479361032,265.874320218178241],"luv":[46.508708270344421,-9.23073412981071,-127.971083789162734],"rgb":[0.333333333333333315,0.333333333333333315,1],"xyz":[0.250426647565461236,0.156475953082478858,0.963116054661033338],"hpluv":[265.874320218178241,350.061034522531031,46.508708270344421],"hsluv":[265.874320218178241,99.9999999999992468,46.508708270344421]},"#ccdd00":{"lch":[84.2515012159558552,94.1174138813685772,92.7819892835375555],"luv":[84.2515012159558552,-4.56806363508048818,94.0064912138661128],"rgb":[0.8,0.866666666666666696,0],"xyz":[0.507566029502865779,0.645503626279608334,0.0978568736941549666],"hpluv":[92.7819892835375555,256.902059824464118,84.2515012159558552],"hsluv":[92.7819892835375555,100.000000000002373,84.2515012159558552]},"#ccdd11":{"lch":[84.2724460606142287,93.1910749716768692,92.8373396690251695],"luv":[84.2724460606142287,-4.61302172096193619,93.0768310858219508],"rgb":[0.8,0.866666666666666696,0.0666666666666666657],"xyz":[0.508577695002502939,0.645908292479463242,0.103184978658910603],"hpluv":[92.8373396690251695,254.758074317949962,84.2724460606142287],"hsluv":[92.8373396690251695,98.9747327605244465,84.2724460606142287]},"#ccdd22":{"lch":[84.3112490917695396,91.4838404394451175,92.9423140418060711],"luv":[84.3112490917695396,-4.69591125178302349,91.3632392106652],"rgb":[0.8,0.866666666666666696,0.133333333333333331],"xyz":[0.510453053140979884,0.646658435734854,0.113061864854889796],"hpluv":[92.9423140418060711,250.792999873820406,84.3112490917695396],"hsluv":[92.9423140418060711,97.0860193213801637,84.3112490917695396]},"#ccdd33":{"lch":[84.3750724084435291,88.7007441607730271,93.1221866378423329],"luv":[84.3750724084435291,-4.83112791130122865,88.5690816130525],"rgb":[0.8,0.866666666666666696,0.2],"xyz":[0.513540803873437701,0.647893536027837169,0.129324018712500932],"hpluv":[93.1221866378423329,244.290353733928498,84.3750724084435291],"hsluv":[93.1221866378423329,94.0094146319777,84.3750724084435291]},"#ccdd44":{"lch":[84.4670755276021197,84.7426243382763857,93.3985511967960491],"luv":[84.4670755276021197,-5.02363867224446459,84.5935897939611152],"rgb":[0.8,0.866666666666666696,0.266666666666666663],"xyz":[0.517998799117656561,0.649676734125524735,0.152802793665387571],"hpluv":[93.3985511967960491,234.956854948695792,84.4670755276021197],"hsluv":[93.3985511967960491,89.638788485123,84.4670755276021197]},"#ccdd55":{"lch":[84.5898637292301601,79.5568981087007359,93.8026723407881633],"luv":[84.5898637292301601,-5.27624840258561711,79.3817437416967095],"rgb":[0.8,0.866666666666666696,0.333333333333333315],"xyz":[0.523961213157018491,0.652061699741269485,0.184204840939361486],"hpluv":[93.8026723407881633,222.570337020009788,84.5898637292301601],"hsluv":[93.8026723407881633,83.9211409492819485,84.5898637292301601]},"#ccdd66":{"lch":[84.7456349568684857,73.1331501088793772,94.3836122863904],"luv":[84.7456349568684857,-5.58984810871231,72.9192103836116],"rgb":[0.8,0.866666666666666696,0.4],"xyz":[0.531546208930526731,0.655095698050672803,0.224152485346505448],"hpluv":[94.3836122863904,206.963810787645969,84.7456349568684857],"hsluv":[94.3836122863904,76.851201462777,84.7456349568684857]},"#ccdd77":{"lch":[84.9362580835765186,65.5005774458529828,95.2238145131341156],"luv":[84.9362580835765186,-5.96359854749608687,65.2285300930849274],"rgb":[0.8,0.866666666666666696,0.466666666666666674],"xyz":[0.540860221950728581,0.658821303258753654,0.273206287252903357],"hpluv":[95.2238145131341156,188.015270942662227,84.9362580835765186],"hsluv":[95.2238145131341156,68.4671748287691,84.9362580835765186]},"#ccdd88":{"lch":[85.1633194008604733,56.7265968622164536,96.4730545580279],"luv":[85.1633194008604733,-6.39512608731957588,56.3649638862273221],"rgb":[0.8,0.866666666666666696,0.533333333333333326],"xyz":[0.552000639052672493,0.663277470099531197,0.331879150656475552],"hpluv":[96.4730545580279,165.642146962004915,85.1633194008604733],"hsluv":[96.4730545580279,58.8458897999489707,85.1633194008604733]},"#ccdd99":{"lch":[85.4281525463895548,46.9188240443766134,98.432972024211054],"luv":[85.4281525463895548,-6.88075351903593724,46.4115425375783843],"rgb":[0.8,0.866666666666666696,0.6],"xyz":[0.565057603161745137,0.66850025574316041,0.400645828297593432],"hpluv":[98.432972024211054,139.807612964747022,85.4281525463895548],"hsluv":[98.432972024211054,48.0968721297954644,85.4281525463895548]},"#ccddaa":{"lch":[85.7318592309590457,36.2402041704229134,101.807730551991185],"luv":[85.7318592309590457,-7.41576493035038453,35.4733537857886176],"rgb":[0.8,0.866666666666666696,0.66666666666666663],"xyz":[0.580115296126997748,0.674523332929261477,0.479949677914592032],"hpluv":[101.807730551991185,110.570541660882469,85.7318592309590457],"hsluv":[101.807730551991185,36.355428538792907,85.7318592309590457]},"#ccddbb":{"lch":[86.0753247228475828,24.9849555175277693,108.661729708420211],"luv":[86.0753247228475828,-7.99469198849898,23.671351930590518],"rgb":[0.8,0.866666666666666696,0.733333333333333282],"xyz":[0.597252888234334312,0.681378369772196235,0.570207663013233779],"hpluv":[108.661729708420211,78.3375416693066313,86.0753247228475828],"hsluv":[108.661729708420211,23.7751141135998658,86.0753247228475828]},"#ccddcc":{"lch":[86.4592303781436158,14.0773589090278701,127.715012949224516],"luv":[86.4592303781436158,-8.61160385902942771,11.1360815742673065],"rgb":[0.8,0.866666666666666696,0.8],"xyz":[0.616545263678056066,0.689095319949685092,0.671814173683503935],"hpluv":[127.715012949224516,45.5363150686036633,86.4592303781436158],"hsluv":[127.715012949224516,10.5200784033656536,86.4592303781436158]},"#ccdddd":{"lch":[86.8840646031333677,9.47353258269296106,192.177050630057835],"luv":[86.8840646031333677,-9.26038246071566817,-1.99828333241680145],"rgb":[0.8,0.866666666666666696,0.866666666666666696],"xyz":[0.638063589228689665,0.697702650169938599,0.785144021583509932],"hpluv":[192.177050630057835,31.7497104564534354,86.8840646031333677],"hsluv":[192.177050630057835,13.7818607651735867,86.8840646031333677]},"#ccddee":{"lch":[87.3501331068194276,18.4943223550678582,237.507437159903361],"luv":[87.3501331068194276,-9.9349674143158051,-15.5992429896340141],"rgb":[0.8,0.866666666666666696,0.933333333333333348],"xyz":[0.661875769494864374,0.707227522276408616,0.910554837652033155],"hpluv":[237.507437159903361,64.5162574350921432,87.3501331068194276],"hsluv":[237.507437159903361,51.9237885878372083,87.3501331068194276]},"#ccddff":{"lch":[87.8575689716950876,31.3946063828198874,250.2096672964189],"luv":[87.8575689716950876,-10.6295595905023852,-29.5403752996496962],"rgb":[0.8,0.866666666666666696,1],"xyz":[0.688046817904695795,0.717695941640341339,1.04838902594381489],"hpluv":[250.2096672964189,114.576774718516177,87.8575689716950876],"hsluv":[250.2096672964189,99.999999999992923,87.8575689716950876]},"#556600":{"lch":[40.3019892206732919,46.2375853800199934,99.381148915360626],"luv":[40.3019892206732919,-7.53678920078613679,45.6191967302971264],"rgb":[0.333333333333333315,0.4,0],"xyz":[0.0849739168694777086,0.114339753133439206,0.0175932549799886241],"hpluv":[99.381148915360626,145.582103533726,40.3019892206732919],"hsluv":[99.381148915360626,100.000000000002302,40.3019892206732919]},"#556611":{"lch":[40.3683315206726334,43.7939991819964618,99.9948312384981364],"luv":[40.3683315206726334,-7.60085740022420797,43.1293557931736729],"rgb":[0.333333333333333315,0.4,0.0666666666666666657],"xyz":[0.0859855823691148269,0.114744419333294059,0.0229213599447442573],"hpluv":[99.9948312384981364,137.661701347396985,40.3683315206726334],"hsluv":[99.9948312384981364,94.2576138599214204,40.3683315206726334]},"#556622":{"lch":[40.4909010608148421,39.4175015547736436,101.28961011017671],"luv":[40.4909010608148421,-7.7166980000465113,38.6547797923705758],"rgb":[0.333333333333333315,0.4,0.133333333333333331],"xyz":[0.0878609405075918559,0.115494562588684874,0.0327982461407234499],"hpluv":[101.28961011017671,123.529583899053776,40.4909010608148421],"hsluv":[101.28961011017671,83.977954812826539,40.4909010608148421]},"#556633":{"lch":[40.6915589391927455,32.6300466430477343,104.01044750968255],"luv":[40.6915589391927455,-7.89969574444685207,31.6593548745491518],"rgb":[0.333333333333333315,0.4,0.2],"xyz":[0.0909486912400495895,0.116729662881667987,0.0490603999983346],"hpluv":[104.01044750968255,101.754281640855311,40.6915589391927455],"hsluv":[104.01044750968255,68.015525760737134,40.6915589391927455]},"#556644":{"lch":[40.9787805135115306,23.7356999706126039,110.078417815454017],"luv":[40.9787805135115306,-8.1486066005911173,22.2931304119395044],"rgb":[0.333333333333333315,0.4,0.266666666666666663],"xyz":[0.0954066864842684631,0.118512860979355567,0.0725391749512212386],"hpluv":[110.078417815454017,73.4991539757345436,40.9787805135115306],"hsluv":[110.078417815454017,46.8659194429644117,40.9787805135115306]},"#556655":{"lch":[41.3584605937638372,13.8246485480389332,127.71501294923371],"luv":[41.3584605937638372,-8.45701225317865202,10.9361716896901875],"rgb":[0.333333333333333315,0.4,0.333333333333333315],"xyz":[0.101369100523630462,0.120897826595100399,0.10394122222519514],"hpluv":[127.71501294923371,42.4159365242361659,41.3584605937638372],"hsluv":[127.71501294923371,21.5972717302380097,41.3584605937638372]},"#556666":{"lch":[41.8343160733152146,9.01834401177998402,192.177050630060307],"luv":[41.8343160733152146,-8.8154354231024481,-1.90226891261946607],"rgb":[0.333333333333333315,0.4,0.4],"xyz":[0.108954096297138633,0.123931824904503718,0.143888866632339102],"hpluv":[192.177050630060307,27.3547941496945484,41.8343160733152146],"hsluv":[192.177050630060307,27.2477194602778816,41.8343160733152146]},"#556677":{"lch":[42.4081371223492525,18.1914318380534858,239.570903430569189],"luv":[42.4081371223492525,-9.21344558994119289,-15.6856817728697795],"rgb":[0.333333333333333315,0.4,0.466666666666666674],"xyz":[0.118268109317340553,0.127657430112584541,0.192942668538737],"hpluv":[239.570903430569189,54.4323412384199443,42.4081371223492525],"hsluv":[239.570903430569189,33.1626844996427934,42.4081371223492525]},"#556688":{"lch":[43.0800011190655425,31.444407039181371,252.144687081813345],"luv":[43.0800011190655425,-9.64130614192028546,-29.9298504828121246],"rgb":[0.333333333333333315,0.4,0.533333333333333326],"xyz":[0.129408526419284381,0.132113596953362111,0.251615531942309179],"hpluv":[252.144687081813345,92.6204805766441694,43.0800011190655425],"hsluv":[252.144687081813345,39.0862788716996903,43.0800011190655425]},"#556699":{"lch":[43.8484890486876964,45.3842681536749,257.153237313451427],"luv":[43.8484890486876964,-10.090933534038701,-44.2482186789059639],"rgb":[0.333333333333333315,0.4,0.6],"xyz":[0.142465490528357108,0.137336382596991269,0.320382209583427113],"hpluv":[257.153237313451427,131.337888607863903,43.8484890486876964],"hsluv":[257.153237313451427,44.8182326355090055,43.8484890486876964]},"#5566aa":{"lch":[44.7109144588579,59.3119903927914223,259.748012643434],"luv":[44.7109144588579,-10.5562103110165033,-58.3650462882037928],"rgb":[0.333333333333333315,0.4,0.66666666666666663],"xyz":[0.157523183493609636,0.143359459783092391,0.399686059200425714],"hpluv":[259.748012643434,168.332615885742257,44.7109144588579],"hsluv":[259.748012643434,50.2202557252039341,44.7109144588579]},"#5566bb":{"lch":[45.6635615252987463,72.9454914642558805,261.300749278862554],"luv":[45.6635615252987463,-11.0328519112314041,-72.1063166696695532],"rgb":[0.333333333333333315,0.4,0.733333333333333282],"xyz":[0.174660775600946283,0.15021449662602715,0.48994404429906746],"hpluv":[261.300749278862554,202.706651650989187,45.6635615252987463],"hsluv":[261.300749278862554,56.1551480082100767,45.6635615252987463]},"#5566cc":{"lch":[46.7019230239281953,86.153038102066219,262.316955218783903],"luv":[46.7019230239281953,-11.5180515282988498,-85.3796255742992],"rgb":[0.333333333333333315,0.4,0.8],"xyz":[0.193953151044668037,0.157931446803515951,0.591550554969337616],"hpluv":[262.316955218783903,234.085848684940913,46.7019230239281953],"hsluv":[262.316955218783903,67.0801136297732086,46.7019230239281953]},"#5566dd":{"lch":[47.8209277182799539,98.8836589551542,263.023825475898036],"luv":[47.8209277182799539,-12.010072956506761,-98.1515978267222664],"rgb":[0.333333333333333315,0.4,0.866666666666666696],"xyz":[0.215471476595301581,0.166538777023769485,0.704880402869343614],"hpluv":[263.023825475898036,262.38914084011509,47.8209277182799539],"hsluv":[263.023825475898036,77.9738615315733909,47.8209277182799539]},"#5566ee":{"lch":[49.0151480019121095,111.133834597019145,263.537783903780621],"luv":[49.0151480019121095,-12.5078880087352609,-110.427722650603215],"rgb":[0.333333333333333315,0.4,0.933333333333333348],"xyz":[0.23928365686147629,0.176063649130239502,0.830291218937866837],"hpluv":[263.537783903780621,287.710232398192659,49.0151480019121095],"hsluv":[263.537783903780621,88.9133133505171145,49.0151480019121095]},"#5566ff":{"lch":[50.2789812841098751,122.927042369796439,263.924295565134457],"luv":[50.2789812841098751,-13.0108962765956715,-122.236550687040406],"rgb":[0.333333333333333315,0.4,1],"xyz":[0.265454705271307712,0.186532068494172198,0.968125407229648682],"hpluv":[263.924295565134457,310.2417842032321,50.2789812841098751],"hsluv":[263.924295565134457,99.99999999999919,50.2789812841098751]},"#ccee00":{"lch":[88.9159222564839382,101.512339113439552,98.3897184755654],"luv":[88.9159222564839382,-14.8112090817394879,100.426007975120399],"rgb":[0.8,0.933333333333333348,0],"xyz":[0.554744805843380595,0.739861178960639299,0.113583132474326151],"hpluv":[98.3897184755654,409.405376777149172,88.9159222564839382],"hsluv":[98.3897184755654,100.000000000002402,88.9159222564839382]},"#ccee11":{"lch":[88.9350466502285855,100.665090554083037,98.4749110233884863],"luv":[88.9350466502285855,-14.8356507509631186,99.5658773027044],"rgb":[0.8,0.933333333333333348,0.0666666666666666657],"xyz":[0.555756471343017755,0.740265845160494207,0.118911237439081788],"hpluv":[98.4749110233884863,406.753799510206477,88.9350466502285855],"hsluv":[98.4749110233884863,99.103544824997428,88.9350466502285855]},"#ccee22":{"lch":[88.9704797513205108,99.1029038393990191,98.635890718104875],"luv":[88.9704797513205108,-14.8807650249594605,97.9793262973016823],"rgb":[0.8,0.933333333333333348,0.133333333333333331],"xyz":[0.557631829481494701,0.741015988415885,0.12878812363506098],"hpluv":[98.635890718104875,401.844579090604725,88.9704797513205108],"hsluv":[98.635890718104875,97.4508266239822376,88.9704797513205108]},"#ccee33":{"lch":[89.0287677898111696,96.5543294248683281,98.9099371535565837],"luv":[89.0287677898111696,-14.95450175665089,95.3892101230339335],"rgb":[0.8,0.933333333333333348,0.2],"xyz":[0.560719580213952518,0.742251088708868134,0.145050277492672131],"hpluv":[98.9099371535565837,393.778440936160052,89.0287677898111696],"hsluv":[98.9099371535565837,94.7550356083218333,89.0287677898111696]},"#ccee44":{"lch":[89.1128082270408157,92.9258219449750698,99.3266297509707101],"luv":[89.1128082270408157,-15.0597883526499068,91.6973890518296],"rgb":[0.8,0.933333333333333348,0.266666666666666663],"xyz":[0.565177575458171377,0.7440342868065557,0.168529052445558769],"hpluv":[99.3266297509707101,382.168331694223468,89.1128082270408157],"hsluv":[99.3266297509707101,90.9176847425828782,89.1128082270408157]},"#ccee55":{"lch":[89.224999764075946,88.1655281542066263,99.9265688821158591],"luv":[89.224999764075946,-15.1984931464969293,86.8456456063635187],"rgb":[0.8,0.933333333333333348,0.333333333333333315],"xyz":[0.571139989497533307,0.74641925242230045,0.199931099719532657],"hpluv":[99.9265688821158591,366.702481299920066,89.224999764075946],"hsluv":[99.9265688821158591,85.8839575374920372,89.224999764075946]},"#ccee66":{"lch":[89.3673776950467555,82.2600687786622444,100.76990980050725],"luv":[89.3673776950467555,-15.3715621348797811,80.8111006793235873],"rgb":[0.8,0.933333333333333348,0.4],"xyz":[0.578724985271041548,0.749453250731703768,0.239878744126676646],"hpluv":[100.76990980050725,347.124780760482849,89.3673776950467555],"hsluv":[100.76990980050725,79.6381055931254451,89.3673776950467555]},"#ccee77":{"lch":[89.5416863487684651,75.2338064272131817,101.95104715507324],"luv":[89.5416863487684651,-15.5791079616514043,73.6031047215169707],"rgb":[0.8,0.933333333333333348,0.466666666666666674],"xyz":[0.588038998291243398,0.753178855939784619,0.288932546033074555],"hpluv":[101.95104715507324,323.225079834159544,89.5416863487684651],"hsluv":[101.95104715507324,72.2002225208687349,89.5416863487684651]},"#ccee88":{"lch":[89.7494222523926481,67.150335761217363,103.626883623375818],"luv":[89.7494222523926481,-15.8204941270879562,65.2600916212887654],"rgb":[0.8,0.933333333333333348,0.533333333333333326],"xyz":[0.599179415393187309,0.757635022780562162,0.347605409436646695],"hpluv":[103.626883623375818,294.840431689210504,89.7494222523926481],"hsluv":[103.626883623375818,63.6228180815060256,89.7494222523926481]},"#ccee99":{"lch":[89.9918618926625697,58.1187887690418705,106.076645299715267],"luv":[89.9918618926625697,-16.094429395756972,55.8458857070554586],"rgb":[0.8,0.933333333333333348,0.6],"xyz":[0.61223637950226,0.762857808424191375,0.41637208707776463],"hpluv":[106.076645299715267,261.881276027636488,89.9918618926625697],"hsluv":[106.076645299715267,53.9866751643902418,89.9918618926625697]},"#cceeaa":{"lch":[90.2700807835134071,48.3136880988356481,109.842100564752428],"luv":[90.2700807835134071,-16.3990756203548145,45.4453823452884791],"rgb":[0.8,0.933333333333333348,0.66666666666666663],"xyz":[0.627294072467512565,0.768880885610292442,0.495675936694763231],"hpluv":[109.842100564752428,224.429228200920562,90.2700807835134071],"hsluv":[109.842100564752428,43.3959332818477037,90.2700807835134071]},"#cceebb":{"lch":[90.5849674500281736,38.0375276056681,116.096591597387416],"luv":[90.5849674500281736,-16.7321662581560417,34.1597441246474745],"rgb":[0.8,0.933333333333333348,0.733333333333333282],"xyz":[0.644431664574849128,0.7757359224532272,0.585933921793405],"hpluv":[116.096591597387416,183.067580850930824,90.5849674500281736],"hsluv":[116.096591597387416,31.9725829176952736,90.5849674500281736]},"#cceecc":{"lch":[90.9372344233822,27.9388105970907,127.715012949233042],"luv":[90.9372344233822,-17.0911298567764973,22.1013668762570106],"rgb":[0.8,0.933333333333333348,0.8],"xyz":[0.663724040018570882,0.783452872630716057,0.687540432463675133],"hpluv":[127.715012949233042,140.086760618050221,90.9372344233822],"hsluv":[127.715012949233042,30.3633811556705,90.9372344233822]},"#cceedd":{"lch":[91.327427526889025,19.8359452431300802,151.749458426713772],"luv":[91.327427526889025,-17.4732117028180483,9.38890816213244861],"rgb":[0.8,0.933333333333333348,0.866666666666666696],"xyz":[0.685242365569204481,0.792060202850969564,0.800870280363681131],"hpluv":[151.749458426713772,104.258293798779974,91.327427526889025],"hsluv":[151.749458426713772,29.0871711351253381,91.327427526889025]},"#cceeee":{"lch":[91.7559342603931,18.2870370266976643,192.177050630059739],"luv":[91.7559342603931,-17.87558711202,-3.8573447624494035],"rgb":[0.8,0.933333333333333348,0.933333333333333348],"xyz":[0.709054545835379191,0.801585074957439581,0.926281096432204354],"hpluv":[192.177050630059739,101.458793010104,91.7559342603931],"hsluv":[192.177050630059739,27.4217374065650326,91.7559342603931]},"#cceeff":{"lch":[92.2229917973594553,25.3309747642836847,223.758903531404655],"luv":[92.2229917973594553,-18.2954610486514362,-17.5195430170439934],"rgb":[0.8,0.933333333333333348,1],"xyz":[0.735225594245210612,0.812053494321372304,1.06411528472398609],"hpluv":[223.758903531404655,149.53216426558339,92.2229917973594553],"hsluv":[223.758903531404655,99.9999999999890861,92.2229917973594553]},"#557700":{"lch":[45.8045523271613533,55.5294361467329836,107.801769483020877],"luv":[45.8045523271613533,-16.9767207468495087,52.8706840456749276],"rgb":[0.333333333333333315,0.466666666666666674,0],"xyz":[0.103427654922895337,0.151247229240274977,0.023744500997794328],"hpluv":[107.801769483020877,153.83457187868342,45.8045523271613533],"hsluv":[107.801769483020877,100.000000000002288,45.8045523271613533]},"#557711":{"lch":[45.859623178970125,53.470483995502839,108.496139146384877],"luv":[45.859623178970125,-16.9630166203079504,50.7084679896019068],"rgb":[0.333333333333333315,0.466666666666666674,0.0666666666666666657],"xyz":[0.104439320422532456,0.15165189544012983,0.0290726059625499578],"hpluv":[108.496139146384877,147.952722071756682,45.859623178970125],"hsluv":[108.496139146384877,95.6324690191426,45.859623178970125]},"#557722":{"lch":[45.9614512879267494,49.76586948312967,109.899607245517743],"luv":[45.9614512879267494,-16.93896350220896,46.7943723206405409],"rgb":[0.333333333333333315,0.466666666666666674,0.133333333333333331],"xyz":[0.106314678561009485,0.152402038695520659,0.0389494921585291573],"hpluv":[109.899607245517743,137.396980684000368,45.9614512879267494],"hsluv":[109.899607245517743,87.7486210093461239,45.9614512879267494]},"#557733":{"lch":[46.1283843073061,43.9801463057798472,112.602269297118809],"luv":[46.1283843073061,-16.9029726498973396,40.6022509803905223],"rgb":[0.333333333333333315,0.466666666666666674,0.2],"xyz":[0.109402429293467218,0.153637138988503757,0.0552116460161403],"hpluv":[112.602269297118809,120.983948144693443,46.1283843073061],"hsluv":[112.602269297118809,75.3373974156097432,46.1283843073061]},"#557744":{"lch":[46.3678258482665413,36.3216896494577526,117.654446368962965],"luv":[46.3678258482665413,-16.8582748313623227,32.1724060135666861],"rgb":[0.333333333333333315,0.466666666666666674,0.266666666666666663],"xyz":[0.113860424537686092,0.155420337086191351,0.0786904209690269391],"hpluv":[117.654446368962965,99.4005156049610861,46.3678258482665413],"hsluv":[117.654446368962965,58.5682493514162346,46.3678258482665413]},"#557755":{"lch":[46.6852246722490349,27.4798560002662136,127.715012949237362],"luv":[46.6852246722490349,-16.8103715694690621,21.7383047520213317],"rgb":[0.333333333333333315,0.466666666666666674,0.333333333333333315],"xyz":[0.119822838577048091,0.157805302701936184,0.110092468243000841],"hpluv":[127.715012949237362,74.6920408293198506,46.6852246722490349],"hsluv":[127.715012949237362,38.0315615795731219,46.6852246722490349]},"#557766":{"lch":[47.0844103757355299,19.3533005907945039,150.034269154893224],"luv":[47.0844103757355299,-16.7662346577491,9.66662397939114371],"rgb":[0.333333333333333315,0.466666666666666674,0.4],"xyz":[0.127407834350556276,0.160839301011339475,0.150040112650144802],"hpluv":[150.034269154893224,52.1575559127659147,47.0844103757355299],"hsluv":[150.034269154893224,41.6155983808333403,47.0844103757355299]},"#557777":{"lch":[47.5677829408255519,17.1184872206298522,192.177050630060563],"luv":[47.5677829408255519,-16.733329138647683,-3.61085871511915846],"rgb":[0.333333333333333315,0.466666666666666674,0.466666666666666674],"xyz":[0.136721847370758182,0.164564906219420298,0.199093914556542712],"hpluv":[192.177050630060563,45.665876663612373,47.5677829408255519],"hsluv":[192.177050630060563,45.4871270252879683,47.5677829408255519]},"#557788":{"lch":[48.1364533988364371,24.3189053895014062,226.569261606948],"luv":[48.1364533988364371,-16.7186932071720697,-17.6605338760746164],"rgb":[0.333333333333333315,0.466666666666666674,0.533333333333333326],"xyz":[0.147862264472702,0.169021073060197896,0.257766777960114879],"hpluv":[226.569261606948,64.1075619232690173,48.1364533988364371],"hsluv":[226.569261606948,49.4930397679002567,48.1364533988364371]},"#557799":{"lch":[48.7903733600049776,36.1922931768580227,242.470518495943224],"luv":[48.7903733600049776,-16.7282575252316086,-32.0943528610435749],"rgb":[0.333333333333333315,0.466666666666666674,0.6],"xyz":[0.160919228581774709,0.174243858703827054,0.326533455601232814],"hpluv":[242.470518495943224,94.128532149155447,48.7903733600049776],"hsluv":[242.470518495943224,53.4981409183259657,48.7903733600049776]},"#5577aa":{"lch":[49.5284680294880957,49.5215284063763121,250.210257263218182],"luv":[49.5284680294880957,-16.7664778987851584,-46.5968560588918308],"rgb":[0.333333333333333315,0.466666666666666674,0.66666666666666663],"xyz":[0.175976921547027265,0.180266935889928148,0.405837305218231414],"hpluv":[250.210257263218182,126.875705911364861,49.5284680294880957],"hsluv":[250.210257263218182,57.3943781585142503,49.5284680294880957]},"#5577bb":{"lch":[50.3487764471929324,63.2168000831305,254.554261837862072],"luv":[50.3487764471929324,-16.8362555209572413,-60.9336057753316069],"rgb":[0.333333333333333315,0.466666666666666674,0.733333333333333282],"xyz":[0.193114513654363912,0.187121972732862907,0.496095290316873161],"hpluv":[254.554261837862072,159.324628464713726,50.3487764471929324],"hsluv":[254.554261837862072,61.1035457400689737,50.3487764471929324]},"#5577cc":{"lch":[51.2485971738404942,76.8367273058076279,257.264224247337211],"luv":[51.2485971738404942,-16.9390629845235594,-74.9463195111900546],"rgb":[0.333333333333333315,0.466666666666666674,0.8],"xyz":[0.212406889098085638,0.194838922910351708,0.597701800987143317],"hpluv":[257.264224247337211,190.250673687597981,51.2485971738404942],"hsluv":[257.264224247337211,64.5753193228694329,51.2485971738404942]},"#5577dd":{"lch":[52.2246350466270428,90.1721178795433502,259.084439545341468],"luv":[52.2246350466270428,-17.075183181685393,-88.5406627612090347],"rgb":[0.333333333333333315,0.466666666666666674,0.866666666666666696],"xyz":[0.233925214648719182,0.203446253130605242,0.711031648887149315],"hpluv":[259.084439545341468,219.096874823476185,52.2246350466270428],"hsluv":[259.084439545341468,74.9139940771913757,52.2246350466270428]},"#5577ee":{"lch":[53.2731438322457791,103.123503170291656,260.373961187264626],"luv":[53.2731438322457791,-17.2439851141504441,-101.671539200978515],"rgb":[0.333333333333333315,0.466666666666666674,0.933333333333333348],"xyz":[0.257737394914893947,0.212971125237075287,0.836442464955672538],"hpluv":[260.373961187264626,245.63410016831412,53.2731438322457791],"hsluv":[260.373961187264626,87.3510385353649,53.2731438322457791]},"#5577ff":{"lch":[54.3900599484937572,115.652149768064447,261.324783585170792],"luv":[54.3900599484937572,-17.4441870719707097,-114.32899931064253],"rgb":[0.333333333333333315,0.466666666666666674,1],"xyz":[0.283908443324725313,0.223439544601007983,0.974276653247454383],"hpluv":[261.324783585170792,269.819603010977914,54.3900599484937572],"hsluv":[261.324783585170792,99.9999999999989768,54.3900599484937572]},"#ccff00":{"lch":[93.605159534834371,109.568762044642341,102.903766821995461],"luv":[93.605159534834371,-24.4682604068618268,106.801768939739262],"rgb":[0.8,1,0],"xyz":[0.606597178273054372,0.843565923819988406,0.130867256617550276],"hpluv":[102.903766821995461,795.170643052662513,93.605159534834371],"hsluv":[102.903766821995461,100.000000000002359,93.605159534834371]},"#ccff11":{"lch":[93.6226829283917681,108.793716578542018,103.00230683973929],"luv":[93.6226829283917681,-24.4775292120886689,106.004355243751533],"rgb":[0.8,1,0.0666666666666666657],"xyz":[0.607608843772691531,0.843970590019843314,0.136195361582305913],"hpluv":[103.00230683973929,791.823376913543598,93.6226829283917681],"hsluv":[103.00230683973929,99.9999999999883755,93.6226829283917681]},"#ccff22":{"lch":[93.6551518183817535,107.364125357399203,103.187929529698394],"luv":[93.6551518183817535,-24.4946701604029187,104.532609971684906],"rgb":[0.8,1,0.133333333333333331],"xyz":[0.609484201911168477,0.844720733275234115,0.146072247778285091],"hpluv":[103.187929529698394,785.615721446726184,93.6551518183817535],"hsluv":[103.187929529698394,99.9999999999883613,93.6551518183817535]},"#ccff33":{"lch":[93.7085695338431464,105.030410790236445,103.502196488744218],"luv":[93.7085695338431464,-24.5227776356263192,102.127472150246831],"rgb":[0.8,1,0.2],"xyz":[0.612571952643626294,0.845955833568217241,0.162334401635896242],"hpluv":[103.502196488744218,775.386532390006209,93.7085695338431464],"hsluv":[103.502196488744218,99.9999999999882334,93.7085695338431464]},"#ccff44":{"lch":[93.7856006692118456,101.704796230104463,103.975902087852319],"luv":[93.7856006692118456,-24.5631097372148304,98.6940687997238],"rgb":[0.8,1,0.266666666666666663],"xyz":[0.617029947887845154,0.847739031665904808,0.18581317658878288],"hpluv":[103.975902087852319,760.597322717251814,93.7856006692118456],"hsluv":[103.975902087852319,99.9999999999883329,93.7856006692118456]},"#ccff55":{"lch":[93.8884584724407887,97.3367975087049473,104.649262803016768],"luv":[93.8884584724407887,-24.6166025777849207,94.1725810773922802],"rgb":[0.8,1,0.333333333333333315],"xyz":[0.622992361927207083,0.850123997281649557,0.217215223862756796],"hpluv":[104.649262803016768,740.773636872505676,93.8884584724407887],"hsluv":[104.649262803016768,99.999999999988,93.8884584724407887]},"#ccff66":{"lch":[94.0190298395239381,91.9106503723783561,105.578857731119598],"luv":[94.0190298395239381,-24.6839280463924027,88.5340123798424514],"rgb":[0.8,1,0.4],"xyz":[0.630577357700715324,0.853157995591052876,0.257162868269900757],"hpluv":[105.578857731119598,715.472563222964368,94.0190298395239381],"hsluv":[105.578857731119598,99.9999999999875371,94.0190298395239381]},"#ccff77":{"lch":[94.1789424927264349,85.4453105292158597,106.848417981185563],"luv":[94.1789424927264349,-24.7655268674123263,81.7775627566241781],"rgb":[0.8,1,0.466666666666666674],"xyz":[0.639891370720917174,0.856883600799133727,0.306216670176298666],"hpluv":[106.848417981185563,684.262206540111833,94.1789424927264349],"hsluv":[106.848417981185563,99.9999999999873381,94.1789424927264349]},"#ccff88":{"lch":[94.3696051468525781,77.9966506735583778,108.587502777405675],"luv":[94.3696051468525781,-24.8616333733667219,73.92818611532],"rgb":[0.8,1,0.533333333333333326],"xyz":[0.651031787822861086,0.861339767639911269,0.364889533579870862],"hpluv":[108.587502777405675,646.714804777793233,94.3696051468525781],"hsluv":[108.587502777405675,99.9999999999870397,94.3696051468525781]},"#ccff99":{"lch":[94.5922333645115572,69.6635615227201868,111.00626449694991],"luv":[94.5922333645115572,-24.9722983929036886,65.0338074927618],"rgb":[0.8,1,0.6],"xyz":[0.66408875193193373,0.866562553283540482,0.433656211220988741],"hpluv":[111.00626449694991,602.43247210261859,94.5922333645115572],"hsluv":[111.00626449694991,99.999999999986656,94.5922333645115572]},"#ccffaa":{"lch":[94.8478672375315881,60.6030718965076574,114.464397640121035],"luv":[94.8478672375315881,-25.0974127381864349,55.1620539605116],"rgb":[0.8,1,0.66666666666666663],"xyz":[0.679146444897186341,0.872585630469641549,0.512960060837987397],"hpluv":[114.464397640121035,551.164539659931279,94.8478672375315881],"hsluv":[114.464397640121035,99.9999999999858886,94.8478672375315881]},"#ccffbb":{"lch":[95.1373841969384,51.0680528276179899,119.615591899534252],"luv":[95.1373841969384,-25.2367319023901224,44.3965469658538439],"rgb":[0.8,1,0.733333333333333282],"xyz":[0.696284037004522904,0.879440667312576307,0.603218045936629088],"hpluv":[119.615591899534252,493.192076617112832,95.1373841969384],"hsluv":[119.615591899534252,99.999999999985036,95.1373841969384]},"#ccffcc":{"lch":[95.4615088709507802,41.5047839306073527,127.715012949235671],"luv":[95.4615088709507802,-25.3899015983654444,32.8329101048280876],"rgb":[0.8,1,0.8],"xyz":[0.715576412448244659,0.887157617490065165,0.704824556606899244],"hpluv":[127.715012949235671,430.524428546451247,95.4615088709507802],"hsluv":[127.715012949235671,99.9999999999844,95.4615088709507802]},"#ccffdd":{"lch":[95.8208211701733603,32.8093273722257,141.163585516297758],"luv":[95.8208211701733603,-25.5564832849791728,20.5746962243056899],"rgb":[0.8,1,0.866666666666666696],"xyz":[0.737094737998878258,0.895764947710318671,0.818154404506905242],"hpluv":[141.163585516297758,370.598640927928557,95.8208211701733603],"hsluv":[141.163585516297758,99.9999999999829612,95.8208211701733603]},"#ccffee":{"lch":[96.2157633520208293,26.8716381406037179,163.283084738459195],"luv":[96.2157633520208293,-25.7359786647352209,7.72944619800421506],"rgb":[0.8,1,0.933333333333333348],"xyz":[0.760906918265053,0.905289819816788688,0.943565220575428465],"hpluv":[163.283084738459195,336.210724351278486,96.2157633520208293],"hsluv":[163.283084738459195,99.9999999999813411,96.2157633520208293]},"#ccffff":{"lch":[96.6466465538527899,26.5246444827845806,192.177050630060279],"luv":[96.6466465538527899,-25.9278521925209873,-5.59493034995961125],"rgb":[0.8,1,1],"xyz":[0.787077966674884388,0.915758239180721412,1.08139940886721031],"hpluv":[192.177050630060279,375.729722461639881,96.6466465538527899],"hsluv":[192.177050630060279,99.9999999999789111,96.6466465538527899]},"#558800":{"lch":[51.3121649295003266,65.2833526322192,113.133039202335894],"luv":[51.3121649295003266,-25.6477049188799029,60.0342515843809466],"rgb":[0.333333333333333315,0.533333333333333326,0],"xyz":[0.125500024647865804,0.195391968690216522,0.0311019575727842744],"hpluv":[113.133039202335894,161.443824642532,51.3121649295003266],"hsluv":[113.133039202335894,100.000000000002416,51.3121649295003266]},"#558811":{"lch":[51.3586018009433758,63.5282336791645363,113.757082680238781],"luv":[51.3586018009433758,-25.5929736747770171,58.1449582756467862],"rgb":[0.333333333333333315,0.533333333333333326,0.0666666666666666657],"xyz":[0.126511690147502937,0.195796634890071375,0.0364300625375399076],"hpluv":[113.757082680238781,156.961418592175818,51.3586018009433758],"hsluv":[113.757082680238781,96.6047658949560315,51.3586018009433758]},"#558822":{"lch":[51.4445144263052754,60.3557257759597761,114.985955444381503],"luv":[51.4445144263052754,-25.4940226670596211,54.707115096615226],"rgb":[0.333333333333333315,0.533333333333333326,0.133333333333333331],"xyz":[0.128387048285979938,0.196546778145462203,0.0463069487335191],"hpluv":[114.985955444381503,148.873956641671725,51.4445144263052754],"hsluv":[114.985955444381503,90.4397474873449454,51.4445144263052754]},"#558833":{"lch":[51.5854933484676366,55.3603846502330512,117.238150003797628],"luv":[51.5854933484676366,-25.3378965271949284,49.2215723864945502],"rgb":[0.333333333333333315,0.533333333333333326,0.2],"xyz":[0.131474799018437671,0.197781878438445302,0.0625691025911302434],"hpluv":[117.238150003797628,136.179218375975154,51.5854933484676366],"hsluv":[117.238150003797628,80.6386945119108844,51.5854933484676366]},"#558844":{"lch":[51.788002513998137,48.6519311113283521,121.094634958525788],"luv":[51.788002513998137,-25.1264429677671792,41.6614001762900799],"rgb":[0.333333333333333315,0.533333333333333326,0.266666666666666663],"xyz":[0.135932794262656559,0.199565076536132896,0.0860478775440168819],"hpluv":[121.094634958525788,119.20933058927335,51.788002513998137],"hsluv":[121.094634958525788,67.2069053574962112,51.788002513998137]},"#558855":{"lch":[52.0569745246593669,40.6501953066927229,127.715012949238655],"luv":[52.0569745246593669,-24.8671203906742271,32.1568764333225801],"rgb":[0.333333333333333315,0.533333333333333326,0.333333333333333315],"xyz":[0.141895208302018572,0.201950042151877729,0.117449924817990797],"hpluv":[127.715012949238655,99.0884509425644495,52.0569745246593669],"hsluv":[127.715012949238655,50.4536826414745647,52.0569745246593669]},"#558866":{"lch":[52.3961000606252156,32.296627997442414,139.535908661945541],"luv":[52.3961000606252156,-24.57168930668605,20.9595864611130054],"rgb":[0.333333333333333315,0.533333333333333326,0.4],"xyz":[0.149480204075526729,0.20498404046128102,0.157397569225134759],"hpluv":[139.535908661945541,78.2163498792783258,52.3961000606252156],"hsluv":[139.535908661945541,52.7717106037122505,52.3961000606252156]},"#558877":{"lch":[52.8079833364028417,25.6675371494617757,160.900154113051656],"luv":[52.8079833364028417,-24.2545338981935465,8.39881233868101873],"rgb":[0.333333333333333315,0.533333333333333326,0.466666666666666674],"xyz":[0.158794217095728663,0.208709645669361843,0.206451371131532668],"hpluv":[160.900154113051656,61.6770996704155934,52.8079833364028417],"hsluv":[160.900154113051656,55.3375604028527732,52.8079833364028417]},"#558888":{"lch":[53.2942460543653311,24.4817100724115,192.177050630060762],"luv":[53.2942460543653311,-23.9308828659180151,-5.16400748714853908],"rgb":[0.333333333333333315,0.533333333333333326,0.533333333333333326],"xyz":[0.169934634197672463,0.213165812510139441,0.265124234535104808],"hpluv":[192.177050630060762,58.2908991249141764,53.2942460543653311],"hsluv":[192.177050630060762,58.0627314448554515,53.2942460543653311]},"#558899":{"lch":[53.8556132197311399,30.5464388010487,219.367537814697016],"luv":[53.8556132197311399,-23.6152401502492637,-19.3753801529742589],"rgb":[0.333333333333333315,0.533333333333333326,0.6],"xyz":[0.18299159830674519,0.218388598153768598,0.333890912176222743],"hpluv":[219.367537814697016,71.9728892793730921,53.8556132197311399],"hsluv":[219.367537814697016,60.861676067449,53.8556132197311399]},"#5588aa":{"lch":[54.491995562986105,41.1624410064978434,235.49057853568965],"luv":[54.491995562986105,-23.3202411533326384,-33.9192114024460452],"rgb":[0.333333333333333315,0.533333333333333326,0.66666666666666663],"xyz":[0.198049291271997718,0.224411675339869693,0.413194761793221343],"hpluv":[235.49057853568965,95.8534470006528494,54.491995562986105],"hsluv":[235.49057853568965,63.6587877222075207,54.491995562986105]},"#5588bb":{"lch":[55.2025746803936102,53.7318677649407164,244.589939769846183],"luv":[55.2025746803936102,-23.0560079965343867,-48.5338449823709865],"rgb":[0.333333333333333315,0.533333333333333326,0.733333333333333282],"xyz":[0.215186883379334393,0.231266712182804451,0.503452746891863],"hpluv":[244.589939769846183,123.512789385845494,55.2025746803936102],"hsluv":[244.589939769846183,66.3923972476147,55.2025746803936102]},"#5588cc":{"lch":[55.9858924676882,67.0258402153595227,250.085698604565607],"luv":[55.9858924676882,-22.8299557310329213,-63.0179052166444436],"rgb":[0.333333333333333315,0.533333333333333326,0.8],"xyz":[0.234479258823056119,0.238983662360293253,0.60505925756213319],"hpluv":[250.085698604565607,151.915814945370954,55.9858924676882],"hsluv":[250.085698604565607,69.0160689386852653,55.9858924676882]},"#5588dd":{"lch":[56.8399439373084761,80.4799585659197589,253.656315856923044],"luv":[56.8399439373084761,-22.6469326722406379,-77.2278458285038596],"rgb":[0.333333333333333315,0.533333333333333326,0.866666666666666696],"xyz":[0.255997584373689691,0.247590992580546787,0.718389105462139188],"hpluv":[253.656315856923044,179.669115472769334,56.8399439373084761],"hsluv":[253.656315856923044,71.4978966707909791,56.8399439373084761]},"#5588ee":{"lch":[57.7622712344346212,93.8110643698785083,256.11666422549024],"luv":[57.7622712344346212,-22.5095618551803298,-91.0704969970917517],"rgb":[0.333333333333333315,0.533333333333333326,0.933333333333333348],"xyz":[0.2798097646398644,0.257115864687016804,0.843799921530662411],"hpluv":[256.11666422549024,206.086302990026525,57.7622712344346212],"hsluv":[256.11666422549024,85.5354286092897098,57.7622712344346212]},"#5588ff":{"lch":[58.7500561820581169,106.871298098059711,257.890974112124525],"luv":[58.7500561820581169,-22.4186692043534066,-104.493433421771144],"rgb":[0.333333333333333315,0.533333333333333326,1],"xyz":[0.305980813049695821,0.267584284050949528,0.981634109822444256],"hpluv":[257.890974112124525,230.829932612430156,58.7500561820581169],"hsluv":[257.890974112124525,99.9999999999988489,58.7500561820581169]},"#559900":{"lch":[56.7948235068901113,75.0667586450735769,116.650835958582277],"luv":[56.7948235068901113,-33.6713638042581849,67.0914116190665766],"rgb":[0.333333333333333315,0.6,0],"xyz":[0.151369625100333277,0.247131169595152217,0.0397251577236065259],"hpluv":[116.650835958582277,167.717444253109818,56.7948235068901113],"hsluv":[116.650835958582277,100.000000000002373,56.7948235068901113]},"#559911":{"lch":[56.8345345919718,73.5501475520203343,117.179331557793219],"luv":[56.8345345919718,-33.596019870913949,65.4288289193465431],"rgb":[0.333333333333333315,0.6,0.0666666666666666657],"xyz":[0.152381290599970409,0.24753583579500707,0.0450532626883621556],"hpluv":[117.179331557793219,164.214146288467191,56.8345345919718],"hsluv":[117.179331557793219,97.3073310640873501,56.8345345919718]},"#559922":{"lch":[56.9080340332033785,70.7973668034807559,118.203267177206257],"luv":[56.9080340332033785,-33.458907670269852,62.3920559351826256],"rgb":[0.333333333333333315,0.6,0.133333333333333331],"xyz":[0.154256648738447411,0.248285979050397898,0.0549301488843413552],"hpluv":[118.203267177206257,157.863907732936383,56.9080340332033785],"hsluv":[118.203267177206257,92.3971004449738444,56.9080340332033785]},"#559933":{"lch":[57.0287279601738675,66.4302504595433163,120.024921583566851],"luv":[57.0287279601738675,-33.2401456716524066,57.5158316626386181],"rgb":[0.333333333333333315,0.6,0.2],"xyz":[0.157344399470905172,0.249521079343381,0.0711923027419525],"hpluv":[120.024921583566851,147.812625691912672,57.0287279601738675],"hsluv":[120.024921583566851,84.5348632876942645,57.0287279601738675]},"#559944":{"lch":[57.2022813646338335,60.4886548808755862,122.993651447985457],"luv":[57.2022813646338335,-32.9388613723515604,50.7337045837447178],"rgb":[0.333333333333333315,0.6,0.266666666666666663],"xyz":[0.161802394715124032,0.251304277441068591,0.0946710776948391369],"hpluv":[122.993651447985457,134.183743453609452,57.2022813646338335],"hsluv":[122.993651447985457,73.6468983233054075,57.2022813646338335]},"#559955":{"lch":[57.4331244004656583,53.227141365646645,127.715012949239252],"luv":[57.4331244004656583,-32.5608701853658573,42.1060365117673499],"rgb":[0.333333333333333315,0.6,0.333333333333333315],"xyz":[0.167764808754486017,0.253689243056813396,0.126073124968813038],"hpluv":[127.715012949239252,117.600732304920115,57.4331244004656583],"hsluv":[127.715012949239252,59.8797334066369444,57.4331244004656583]},"#559966":{"lch":[57.7247064038159152,45.1954856350919556,135.286653522876605],"luv":[57.7247064038159152,-32.1175213159608433,31.7977475037242847],"rgb":[0.333333333333333315,0.6,0.4],"xyz":[0.175349804527994202,0.256723241366216715,0.166020769375957],"hpluv":[135.286653522876605,99.3510934192793371,57.7247064038159152],"hsluv":[135.286653522876605,61.4133131906424055,57.7247064038159152]},"#559977":{"lch":[58.0796295741768631,37.4448814339638858,147.624029462041108],"luv":[58.0796295741768631,-31.624170974627738,20.0507096076703846],"rgb":[0.333333333333333315,0.6,0.466666666666666674],"xyz":[0.184663817548196107,0.260448846574297566,0.215074571282354909],"hpluv":[147.624029462041108,81.8102930750829671,58.0796295741768631],"hsluv":[147.624029462041108,63.1432913181764448,58.0796295741768631]},"#559988":{"lch":[58.4997327930321092,31.9103493306277741,167.047427400638497],"luv":[58.4997327930321092,-31.0984204046450543,7.15252701768072],"rgb":[0.333333333333333315,0.6,0.533333333333333326],"xyz":[0.195804234650139963,0.264905013415075108,0.273747434685927105],"hpluv":[167.047427400638497,69.2176742514874093,58.4997327930321092],"hsluv":[167.047427400638497,65.0191416919107752,58.4997327930321092]},"#559999":{"lch":[58.9861545428406373,31.2617491707160085,192.177050630060933],"luv":[58.9861545428406373,-30.5583742056962677,-6.59414339527129822],"rgb":[0.333333333333333315,0.6,0.6],"xyz":[0.208861198759212663,0.270127799058704321,0.342514112327045],"hpluv":[192.177050630060933,67.2515837667627494,58.9861545428406373],"hsluv":[192.177050630060933,66.9883413382070216,58.9861545428406373]},"#5599aa":{"lch":[59.5393884281606915,36.5784761777074152,214.841775998693208],"luv":[59.5393884281606915,-30.0211576326403424,-20.8977274812183715],"rgb":[0.333333333333333315,0.6,0.66666666666666663],"xyz":[0.223918891724465219,0.276150876244805388,0.421817961944043585],"hpluv":[214.841775998693208,77.957978019602777,59.5393884281606915],"hsluv":[214.841775998693208,69.0007957908225,59.5393884281606915]},"#5599bb":{"lch":[60.1593377819191488,46.1560476826162613,230.269588518041076],"luv":[60.1593377819191488,-29.5018430010724479,-35.4967885479802],"rgb":[0.333333333333333315,0.6,0.733333333333333282],"xyz":[0.241056483831801838,0.283005913087740146,0.512075947042685331],"hpluv":[230.269588518041076,97.3564866347465312,60.1593377819191488],"hsluv":[230.269588518041076,71.0120526680823758,60.1593377819191488]},"#5599cc":{"lch":[60.8453721774886276,57.9560381686168284,239.960256152221575],"luv":[60.8453721774886276,-29.0128279276179057,-50.1712883614184761],"rgb":[0.333333333333333315,0.6,0.8],"xyz":[0.260348859275523592,0.290722863265228948,0.613682457712955487],"hpluv":[239.960256152221575,120.867757439807349,60.8453721774886276],"hsluv":[239.960256152221575,72.9851794318318667,60.8453721774886276]},"#5599dd":{"lch":[61.596386585270082,70.7674616346471623,246.194917025964173],"luv":[61.596386585270082,-28.563620381934669,-64.7468394355121],"rgb":[0.333333333333333315,0.6,0.866666666666666696],"xyz":[0.281867184826157136,0.29933019348548251,0.727012305612961485],"hpluv":[246.194917025964173,145.7866339341696,61.596386585270082],"hsluv":[246.194917025964173,74.8914393241793164,61.596386585270082]},"#5599ee":{"lch":[62.4108626997728209,83.9573424358243,250.401946751580681],"luv":[62.4108626997728209,-28.1609349474859023,-79.0935970339554757],"rgb":[0.333333333333333315,0.6,0.933333333333333348],"xyz":[0.305679365092331845,0.308855065591952527,0.852423121681484708],"hpluv":[250.401946751580681,170.701691169737018,62.4108626997728209],"hsluv":[250.401946751580681,83.3865807682554845,62.4108626997728209]},"#5599ff":{"lch":[63.2869312953637,97.1853240423286309,253.372761171991215],"luv":[63.2869312953637,-27.8089904224615658,-93.1216798650875859],"rgb":[0.333333333333333315,0.6,1],"xyz":[0.331850413502163266,0.319323484955885251,0.990257309973266553],"hpluv":[253.372761171991215,194.861470594675211,63.2869312953637],"hsluv":[253.372761171991215,99.9999999999986215,63.2869312953637]},"#440000":{"lch":[10.7708306123528814,36.2226426723970221,12.1770506300617765],"luv":[10.7708306123528814,35.407649887332731,7.64056094984030221],"rgb":[0.266666666666666663,0,0],"xyz":[0.0238384275584062923,0.0122916892098035059,0.00111742629180027137],"hpluv":[12.1770506300617765,426.746789183125145,10.7708306123528814],"hsluv":[12.1770506300617765,100.000000000002203,10.7708306123528814]},"#440011":{"lch":[11.0614468716721248,32.5827232355020158,4.73042674181564848],"luv":[11.0614468716721248,32.4717377839629151,2.68702414036008763],"rgb":[0.266666666666666663,0,0.0666666666666666657],"xyz":[0.024850093058043414,0.0126963554096583605,0.00644553125655590239],"hpluv":[4.73042674181564848,373.778888471265759,11.0614468716721248],"hsluv":[4.73042674181564848,99.999999999996831,11.0614468716721248]},"#440022":{"lch":[11.5842423793746683,28.6540476811609395,350.304317532446703],"luv":[11.5842423793746683,28.2447579299318896,-4.82577434136679706],"rgb":[0.266666666666666663,0,0.133333333333333331],"xyz":[0.0267254511965204326,0.0134464986650491784,0.0163224174525351],"hpluv":[350.304317532446703,313.875682434467763,11.5842423793746683],"hsluv":[350.304317532446703,99.9999999999974847,11.5842423793746683]},"#440033":{"lch":[12.4041921203750505,27.3919603751935874,328.642516788172941],"luv":[12.4041921203750505,23.3910134404871357,-14.2541216293086901],"rgb":[0.266666666666666663,0,0.2],"xyz":[0.0298132019289781731,0.0146815989580322912,0.0325845713101462417],"hpluv":[328.642516788172941,280.216663156604227,12.4041921203750505],"hsluv":[328.642516788172941,99.9999999999981668,12.4041921203750505]},"#440044":{"lch":[13.5105146335658439,30.7747615701782742,307.715012949243601],"luv":[13.5105146335658439,18.8259784531467211,-24.3447835271332202],"rgb":[0.266666666666666663,0,0.266666666666666663],"xyz":[0.0342711971731970502,0.0164647970557198695,0.0560633462630328802],"hpluv":[307.715012949243601,289.042783730483222,13.5105146335658439],"hsluv":[307.715012949243601,99.9999999999987779,13.5105146335658439]},"#440055":{"lch":[14.871657786523194,37.5926423334987589,293.358518425732086],"luv":[14.871657786523194,14.9048564440935021,-34.5116214049025416],"rgb":[0.266666666666666663,0,0.333333333333333315],"xyz":[0.0402336112125590423,0.0188497626714647,0.0874653935370067886],"hpluv":[293.358518425732086,320.761913781574776,14.871657786523194],"hsluv":[293.358518425732086,99.999999999999261,14.871657786523194]},"#440066":{"lch":[16.4463097679727497,46.0898544445027,284.618444278650202],"luv":[16.4463097679727497,11.6321972733021664,-44.597832562922008],"rgb":[0.266666666666666663,0,0.4],"xyz":[0.0478186069860672205,0.0218837609808680139,0.127413037944150764],"hpluv":[284.618444278650202,355.611827609674208,16.4463097679727497],"hsluv":[284.618444278650202,99.9999999999996447,16.4463097679727497]},"#440077":{"lch":[18.1919811936642475,55.3198462112611651,279.251207899416613],"luv":[18.1919811936642475,8.8934050845755,-54.6002997321373],"rgb":[0.266666666666666663,0,0.466666666666666674],"xyz":[0.0571326200062691331,0.0256093661889488303,0.176466839850548673],"hpluv":[279.251207899416613,385.869357778503058,18.1919811936642475],"hsluv":[279.251207899416613,100.000000000000028,18.1919811936642475]},"#440088":{"lch":[20.0701231572475791,64.8751824688912,275.807883046004235],"luv":[20.0701231572475791,6.56492582220058196,-64.5421648949036353],"rgb":[0.266666666666666663,0,0.533333333333333326],"xyz":[0.0682730371082129611,0.0300655330297264212,0.235139703254120841],"hpluv":[275.807883046004235,410.173767132845569,20.0701231572475791],"hsluv":[275.807883046004235,100.000000000000284,20.0701231572475791]},"#440099":{"lch":[22.0482755473713041,74.5764302852581267,273.495279820248],"luv":[22.0482755473713041,4.54664979059262,-74.4377050275844283],"rgb":[0.266666666666666663,0,0.6],"xyz":[0.0813300012172856746,0.0352883186733555787,0.303906380895238748],"hpluv":[273.495279820248,429.20649964036636,22.0482755473713041],"hsluv":[273.495279820248,100.000000000000384,22.0482755473713041]},"#4400aa":{"lch":[24.1003299188330615,84.3353594354864811,271.878389761009714],"luv":[24.1003299188330615,2.7643624238057809,-84.290041828810061],"rgb":[0.266666666666666663,0,0.66666666666666663],"xyz":[0.0963876941825382166,0.0413113958594566871,0.383210230512237349],"hpluv":[271.878389761009714,444.044033459252,24.1003299188330615],"hsluv":[271.878389761009714,100.000000000000398,24.1003299188330615]},"#4400bb":{"lch":[26.2058661049044161,94.1030045511215434,270.708980538846049],"luv":[26.2058661049044161,1.16440507249082947,-94.0958002589677704],"rgb":[0.266666666666666663,0,0.733333333333333282],"xyz":[0.113525286289874863,0.0481664327023914457,0.473468215610879095],"hpluv":[270.708980538846049,455.663559843794246,26.2058661049044161],"hsluv":[270.708980538846049,100.000000000000597,26.2058661049044161]},"#4400cc":{"lch":[28.3491756730399374,103.84959146554381,269.838851579513857],"luv":[28.3491756730399374,-0.292083914573144032,-103.849180711969012],"rgb":[0.266666666666666663,0,0.8],"xyz":[0.132817661733596604,0.0558833828798802473,0.575074726281149196],"hpluv":[269.838851579513857,464.840204698682,28.3491756730399374],"hsluv":[269.838851579513857,100.00000000000054,28.3491756730399374]},"#4400dd":{"lch":[30.5182871942398464,113.556060117994207,269.175711116484081],"luv":[30.5182871942398464,-1.63362415099869285,-113.544308803456943],"rgb":[0.266666666666666663,0,0.866666666666666696],"xyz":[0.154335987284230147,0.0644907131001337813,0.688404574181155193],"hpluv":[269.175711116484081,472.160320460814546,30.5182871942398464],"hsluv":[269.175711116484081,100.000000000000583,30.5182871942398464]},"#4400ee":{"lch":[32.7041215904695406,123.209994802530275,268.6598990566049],"luv":[32.7041215904695406,-2.88151723804096926,-123.176295112519156],"rgb":[0.266666666666666663,0,0.933333333333333348],"xyz":[0.178148167550404884,0.0740155852066038122,0.813815390249678416],"hpluv":[268.6598990566049,478.060407115886846,32.7041215904695406],"hsluv":[268.6598990566049,100.000000000000682,32.7041215904695406]},"#4400ff":{"lch":[34.8998090420324161,132.803387625161918,268.251574356178935],"luv":[34.8998090420324161,-4.05197057625710322,-132.741558297197031],"rgb":[0.266666666666666663,0,1],"xyz":[0.204319215960236278,0.0844840045705365084,0.951649578541460262],"hpluv":[268.251574356178935,482.864668803745815,34.8998090420324161],"hsluv":[268.251574356178935,100.000000000000824,34.8998090420324161]},"#441100":{"lch":[13.412021407860891,32.8203905090178907,19.8063713084711637],"luv":[13.412021407860891,30.878837797926078,11.1209446277644677],"rgb":[0.266666666666666663,0.0666666666666666657,0],"xyz":[0.025842827819334703,0.0163004897316603795,0.00178555971210972225],"hpluv":[19.8063713084711637,310.519467471828818,13.412021407860891],"hsluv":[19.8063713084711637,100.00000000000226,13.412021407860891]},"#441111":{"lch":[13.6534230745514442,29.3615880370140658,12.1770506300618155],"luv":[13.6534230745514442,28.7009658227648572,6.19333616848069],"rgb":[0.266666666666666663,0.0666666666666666657,0.0666666666666666657],"xyz":[0.0268544933189718248,0.0167051559315152323,0.00711366467686535414],"hpluv":[12.1770506300618155,272.883526996448495,13.6534230745514442],"hsluv":[12.1770506300618155,63.9450685777404857,13.6534230745514442]},"#441122":{"lch":[14.0908014406849,25.4444274015795777,356.558123350094036],"luv":[14.0908014406849,25.3985311285907684,-1.52758053936917793],"rgb":[0.266666666666666663,0.0666666666666666657,0.133333333333333331],"xyz":[0.0287298514574488434,0.0174552991869060536,0.0169905508728445502],"hpluv":[356.558123350094036,229.137575437366081,14.0908014406849],"hsluv":[356.558123350094036,68.4589860949294,14.0908014406849]},"#441133":{"lch":[14.7844111345271223,24.27011571268606,331.648240125609],"luv":[14.7844111345271223,21.358884082162259,-11.5254755854986932],"rgb":[0.266666666666666663,0.0666666666666666657,0.2],"xyz":[0.0318176021899065839,0.0186903994798891665,0.0332527047304557],"hpluv":[331.648240125609,208.308572243058649,14.7844111345271223],"hsluv":[331.648240125609,73.8494669394836762,14.7844111345271223]},"#441144":{"lch":[15.733846020816415,28.3218749128348932,307.715012949243942],"luv":[15.733846020816415,17.3254634530922189,-22.4043949865608347],"rgb":[0.266666666666666663,0.0666666666666666657,0.266666666666666663],"xyz":[0.0362755974341254644,0.0204735975775767395,0.0567314796833423354],"hpluv":[307.715012949243942,228.415952286272613,15.733846020816415],"hsluv":[307.715012949243942,79.0249627886423127,15.733846020816415]},"#441155":{"lch":[16.9210970319156715,36.0495621705848492,292.339268883647492],"luv":[16.9210970319156715,13.7020846665308547,-33.3440220801582683],"rgb":[0.266666666666666663,0.0666666666666666657,0.333333333333333315],"xyz":[0.0422380114734874565,0.0228585631933215724,0.0881335269573162439],"hpluv":[292.339268883647492,270.340308544513618,16.9210970319156715],"hsluv":[292.339268883647492,83.4150097743113292,16.9210970319156715]},"#441166":{"lch":[18.3175541838796221,45.305096001334384,283.521508601515677],"luv":[18.3175541838796221,10.592801308498224,-44.0493392019540195],"rgb":[0.266666666666666663,0.0666666666666666657,0.4],"xyz":[0.0498230072469956348,0.025892561502724884,0.128081171364460206],"hpluv":[283.521508601515677,313.84766122316239,18.3175541838796221],"hsluv":[283.521508601515677,86.9023417707839485,18.3175541838796221]},"#441177":{"lch":[19.8903241139664431,55.0653797371295326,278.304914930180701],"luv":[19.8903241139664431,7.95370312292975612,-54.4879312529533735],"rgb":[0.266666666666666663,0.0666666666666666657,0.466666666666666674],"xyz":[0.0591370202671975473,0.0296181667108057,0.177134973270858115],"hpluv":[278.304914930180701,351.298345972174616,19.8903241139664431],"hsluv":[278.304914930180701,89.590178354910762,19.8903241139664431]},"#441188":{"lch":[21.6068634066631873,64.9598488176177824,275.03199667533886],"luv":[21.6068634066631873,5.69776159856002,-64.7094851716016422],"rgb":[0.266666666666666663,0.0666666666666666657,0.533333333333333326],"xyz":[0.0702774373691413823,0.0340743335515832912,0.235807836674430282],"hpluv":[275.03199667533886,381.498298720028686,21.6068634066631873],"hsluv":[275.03199667533886,91.6417594317348545,21.6068634066631873]},"#441199":{"lch":[23.437698327746169,74.8628785955689153,272.864058339832695],"luv":[23.437698327746169,3.74063102269824954,-74.769367197849931],"rgb":[0.266666666666666663,0.0666666666666666657,0.6],"xyz":[0.0833344014782140818,0.0392971191952124557,0.304574514315548162],"hpluv":[272.864058339832695,405.313331644098525,23.437698327746169],"hsluv":[272.864058339832695,93.2101268622270283,23.437698327746169]},"#4411aa":{"lch":[25.3575925472355337,84.7316846097945273,271.361966301038933],"luv":[25.3575925472355337,2.01394993465393446,-84.7077468858332878],"rgb":[0.266666666666666663,0.0666666666666666657,0.66666666666666663],"xyz":[0.0983920944434666378,0.0453201963813135572,0.383878363932546762],"hpluv":[271.361966301038933,424.011024215555381,25.3575925472355337],"hsluv":[271.361966301038933,94.4180404350203872,25.3575925472355337]},"#4411bb":{"lch":[27.345710117802,94.5503656807627,270.282295464151048],"luv":[27.345710117802,0.465846378280231621,-94.5492180693092337],"rgb":[0.266666666666666663,0.0666666666666666657,0.733333333333333282],"xyz":[0.115529686550803284,0.0521752332242483158,0.474136349031188509],"hpluv":[270.282295464151048,438.746165283595928,27.345710117802],"hsluv":[270.282295464151048,95.3579307613671,27.345710117802]},"#4411cc":{"lch":[29.3852471201757481,104.311620276565549,269.482476007084244],"luv":[29.3852471201757481,-0.942181651797373232,-104.307365120864873],"rgb":[0.266666666666666663,0.0666666666666666657,0.8],"xyz":[0.134822061994525,0.0598921834017371174,0.575742859701458665],"hpluv":[269.482476007084244,450.445933463405538,29.3852471201757481],"hsluv":[269.482476007084244,96.097629526357963,29.3852471201757481]},"#4411dd":{"lch":[31.4628506304707116,114.011096091836691,268.874895171215144],"luv":[31.4628506304707116,-2.23866735310417164,-113.989115272223103],"rgb":[0.266666666666666663,0.0666666666666666657,0.866666666666666696],"xyz":[0.156340387545158555,0.0684995136219906514,0.689072707601464662],"hpluv":[268.874895171215144,459.820552568088715,31.4628506304707116],"hsluv":[268.874895171215144,96.6865382756064378,31.4628506304707116]},"#4411ee":{"lch":[33.5680052377948073,123.64577428881995,268.40345713539682],"luv":[33.5680052377948073,-3.44493495426529961,-123.597774747940718],"rgb":[0.266666666666666663,0.0666666666666666657,0.933333333333333348],"xyz":[0.180152567811333292,0.0780243857284606823,0.814483523669987886],"hpluv":[268.40345713539682,467.404695294247745,33.5680052377948073],"hsluv":[268.40345713539682,97.1606953094382817,33.5680052377948073]},"#4411ff":{"lch":[35.6924730299026081,133.21354134861582,268.030966648817412],"luv":[35.6924730299026081,-4.57713081064657,-133.134884505082312],"rgb":[0.266666666666666663,0.0666666666666666657,1],"xyz":[0.206323616221164685,0.0884928050923933784,0.952317711961769731],"hpluv":[268.030966648817412,473.599309181226886,35.6924730299026081],"hsluv":[268.030966648817412,99.999999999999531,35.6924730299026081]},"#99aa00":{"lch":[66.1528677227115907,74.3468963767982842,94.6234982733471384],"luv":[66.1528677227115907,-5.99293371363564553,74.1049643840839565],"rgb":[0.6,0.66666666666666663,0],"xyz":[0.275106719282890377,0.355217387920677,0.0540714229698005533],"hpluv":[94.6234982733471384,142.611154102436132,66.1528677227115907],"hsluv":[94.6234982733471384,100.000000000002217,66.1528677227115907]},"#99aa11":{"lch":[66.184052262829,73.0311244080130706,94.7508326892346275],"luv":[66.184052262829,-6.04863423256243316,72.7802112955118901],"rgb":[0.6,0.66666666666666663,0.0666666666666666657],"xyz":[0.276118384782527482,0.355622054120531828,0.059399527934556183],"hpluv":[94.7508326892346275,140.021252931940353,66.184052262829],"hsluv":[94.7508326892346275,98.1390759685954,66.184052262829]},"#99aa22":{"lch":[66.2417975711995695,70.6178785015108872,94.9968669170454376],"luv":[66.2417975711995695,-6.15090676716144458,70.3494926065273],"rgb":[0.6,0.66666666666666663,0.133333333333333331],"xyz":[0.277993742921004539,0.356372197375922628,0.0692764141305353826],"hpluv":[94.9968669170454376,135.276352185575888,66.2417975711995695],"hsluv":[94.9968669170454376,94.7283581868373403,66.2417975711995695]},"#99aa33":{"lch":[66.3366981156763273,66.7162457715457,95.432805623918],"luv":[66.3366981156763273,-6.31658226271684953,66.416550937003791],"rgb":[0.6,0.66666666666666663,0.2],"xyz":[0.281081493653462244,0.357607297668905755,0.0855385679881465189],"hpluv":[95.432805623918,127.619510800204154,66.3366981156763273],"hsluv":[95.432805623918,89.220332613511431,66.3366981156763273]},"#99aa44":{"lch":[66.4733277612737652,61.2361369282317085,96.1403021162386],"luv":[66.4733277612737652,-6.55002950525979344,60.8848222414533211],"rgb":[0.6,0.66666666666666663,0.266666666666666663],"xyz":[0.28553948889768116,0.359390495766593321,0.109017342941033157],"hpluv":[96.1403021162386,116.896010950353556,66.4733277612737652],"hsluv":[96.1403021162386,81.495914591183535,66.4733277612737652]},"#99aa55":{"lch":[66.6553605356915853,54.1785870660784568,97.2658616968833769],"luv":[66.6553605356915853,-6.85216039608048888,53.7435316515674231],"rgb":[0.6,0.66666666666666663,0.333333333333333315],"xyz":[0.291501902937043145,0.361775461382338182,0.140419390215007073],"hpluv":[97.2658616968833769,103.141138146130345,66.6553605356915853],"hsluv":[97.2658616968833769,71.5645731506566563,66.6553605356915853]},"#99aa66":{"lch":[66.8857782590742573,45.6318272725976186,99.1048787772859328],"luv":[66.8857782590742573,-7.22087825912546055,45.0568815765480224],"rgb":[0.6,0.66666666666666663,0.4],"xyz":[0.29908689871055133,0.3648094596917415,0.180367034622151035],"hpluv":[99.1048787772859328,86.5711928674077882,66.8857782590742573],"hsluv":[99.1048787772859328,59.5487850828384495,66.8857782590742573]},"#99aa77":{"lch":[67.16697930835997,35.7793898766585272,102.348317274789],"luv":[67.16697930835997,-7.65157453727816339,34.9516544250255947],"rgb":[0.6,0.66666666666666663,0.466666666666666674],"xyz":[0.308400911730753235,0.368535064899822296,0.229420836528548944],"hpluv":[102.348317274789,67.5952906506277742,67.16697930835997],"hsluv":[102.348317274789,45.6652750399669927,67.16697930835997]},"#99aa88":{"lch":[67.5008436530857523,24.9656779050761699,109.02352802026725],"luv":[67.5008436530857523,-8.13772239581267165,23.6021725158659379],"rgb":[0.6,0.66666666666666663,0.533333333333333326],"xyz":[0.319541328832697036,0.372991231740599893,0.288093699932121083],"hpluv":[109.02352802026725,46.9324783865521482,67.5008436530857523],"hsluv":[109.02352802026725,30.201776912068496,67.5008436530857523]},"#99aa99":{"lch":[67.8887769686822509,14.1753245834603039,127.715012949228395],"luv":[67.8887769686822509,-8.67153282620695443,11.213578621049983],"rgb":[0.6,0.66666666666666663,0.6],"xyz":[0.332598292941769791,0.378214017384229051,0.356860377573239],"hpluv":[127.715012949228395,26.4956363039349618,67.8887769686822509],"hsluv":[127.715012949228395,13.4910013502760879,67.8887769686822509]},"#99aaaa":{"lch":[68.3317447891119798,9.45739632834534838,192.177050630059227],"luv":[68.3317447891119798,-9.24460926466251642,-1.99487965930680966],"rgb":[0.6,0.66666666666666663,0.66666666666666663],"xyz":[0.347655985907022291,0.384237094570330173,0.436164227190237619],"hpluv":[192.177050630059227,17.5625836428344968,68.3317447891119798],"hsluv":[192.177050630059227,17.4938385380963979,68.3317447891119798]},"#99aabb":{"lch":[68.8303024285350205,18.6222464744475609,238.07162859052869],"luv":[68.8303024285350205,-9.84853629911531137,-15.8048852105949411],"rgb":[0.6,0.66666666666666663,0.733333333333333282],"xyz":[0.364793578014358966,0.391092131413264932,0.52642221228887931],"hpluv":[238.07162859052869,34.3314162301526622,68.8303024285350205],"hsluv":[238.07162859052869,21.6214176811966929,68.8303024285350205]},"#99aacc":{"lch":[69.3846237501618646,31.7868422871013969,250.758533684062627],"luv":[69.3846237501618646,-10.475354770609286,-30.0111693376804425],"rgb":[0.6,0.66666666666666663,0.8],"xyz":[0.38408595345808072,0.398809081590753733,0.628028722959149466],"hpluv":[250.758533684062627,58.1330991079694357,69.3846237501618646],"hsluv":[250.758533684062627,38.7837447081888556,69.3846237501618646]},"#99aadd":{"lch":[69.9945303682966,45.800012761152324,255.951164454091042],"luv":[69.9945303682966,-11.1178995355210173,-44.4300965432191859],"rgb":[0.6,0.66666666666666663,0.866666666666666696],"xyz":[0.405604279008714208,0.40741641181100724,0.741358570859155463],"hpluv":[255.951164454091042,83.0311057452140346,69.9945303682966],"hsluv":[255.951164454091042,58.1375555879370935,69.9945303682966]},"#99aaee":{"lch":[70.6595219654936,60.0690973767372896,258.700300270425373],"luv":[70.6595219654936,-11.7699993169592201,-58.9046990972259],"rgb":[0.6,0.66666666666666663,0.933333333333333348],"xyz":[0.429416459274889,0.416941283917477257,0.866769386927678687],"hpluv":[258.700300270425373,107.874733956899746,70.6595219654936],"hsluv":[258.700300270425373,78.5353046306170199,70.6595219654936]},"#99aaff":{"lch":[71.378807837336737,74.3523754541628676,260.378973553217],"luv":[71.378807837336737,-12.4265554124673407,-73.3065921746310636],"rgb":[0.6,0.66666666666666663,1],"xyz":[0.455587507684720339,0.42740970328141,1.00460357521946064],"hpluv":[260.378973553217,132.179737350703419,71.378807837336737],"hsluv":[260.378973553217,99.99999999999784,71.378807837336737]},"#442200":{"lch":[17.3350542344952459,28.221345162136295,35.6239292836567927],"luv":[17.3350542344952459,22.9399340369809366,16.4378754448194186],"rgb":[0.266666666666666663,0.133333333333333331,0],"xyz":[0.0295584515541026382,0.023731737201196354,0.00302410095703233277],"hpluv":[35.6239292836567927,206.581692971425213,17.3350542344952459],"hsluv":[35.6239292836567927,100.000000000002331,17.3350542344952459]},"#442211":{"lch":[17.5234603686317101,24.6335663377647,28.604455948929278],"luv":[17.5234603686317101,21.6269347365689519,11.7935696215031331],"rgb":[0.266666666666666663,0.133333333333333331,0.0666666666666666657],"xyz":[0.03057011705373976,0.0241364034010512069,0.00835220592178796337],"hpluv":[28.604455948929278,178.380241443971528,17.5234603686317101],"hsluv":[28.604455948929278,74.2089163354216765,17.5234603686317101]},"#442222":{"lch":[17.8672188947691239,19.9697171584766728,12.1770506300619807],"luv":[17.8672188947691239,19.520407715454283,4.21227800744330061],"rgb":[0.266666666666666663,0.133333333333333331,0.133333333333333331],"xyz":[0.0324454751922167786,0.0248865466564420282,0.0182290921177671594],"hpluv":[12.1770506300619807,141.825486578211439,17.8672188947691239],"hsluv":[12.1770506300619807,33.2341074785113406,17.8672188947691239]},"#442233":{"lch":[18.4184657925371695,17.8165085202964129,340.00784749027008],"luv":[18.4184657925371695,16.7428760354525643,-6.09131167444770583],"rgb":[0.266666666666666663,0.133333333333333331,0.2],"xyz":[0.0355332259246745191,0.026121646949425141,0.0344912459753783],"hpluv":[340.00784749027008,122.746318288975218,18.4184657925371695],"hsluv":[340.00784749027008,42.0888291674463915,18.4184657925371695]},"#442244":{"lch":[19.1844846541763658,22.4593922221866436,307.715012949244738],"luv":[19.1844846541763658,13.7391814744519145,-17.7668002578431441],"rgb":[0.266666666666666663,0.133333333333333331,0.266666666666666663],"xyz":[0.0399912211688934,0.0279048450471127141,0.0579700209282649412],"hpluv":[307.715012949244738,148.554970924606664,19.1844846541763658],"hsluv":[307.715012949244738,51.3954955066877517,19.1844846541763658]},"#442255":{"lch":[20.1595909359386596,31.6741463862469885,290.023039430837684],"luv":[20.1595909359386596,10.8451637140407797,-29.7596030436068872],"rgb":[0.266666666666666663,0.133333333333333331,0.333333333333333315],"xyz":[0.0459536352082553917,0.030289810662857547,0.0893720682022388496],"hpluv":[290.023039430837684,199.371249454156271,20.1595909359386596],"hsluv":[290.023039430837684,59.9942694866150177,20.1595909359386596]},"#442266":{"lch":[21.3287002071660226,42.3208084503031685,281.207510247893651],"luv":[21.3287002071660226,8.22559640374024781,-41.5137373852322256],"rgb":[0.266666666666666663,0.133333333333333331,0.4],"xyz":[0.0535386309817635631,0.0333238089722608585,0.129319712609382825],"hpluv":[281.207510247893651,251.784442505332123,21.3287002071660226],"hsluv":[281.207510247893651,67.3437899952651406,21.3287002071660226]},"#442277":{"lch":[22.6709734328231463,53.1747129073287113,276.391210783405313],"luv":[22.6709734328231463,5.91922219198187882,-52.8442324328661215],"rgb":[0.266666666666666663,0.133333333333333331,0.466666666666666674],"xyz":[0.0628526440019654825,0.0370494141803416749,0.178373514515780734],"hpluv":[276.391210783405313,297.628360698128461,22.6709734328231463],"hsluv":[276.391210783405313,73.3546851738733,22.6709734328231463]},"#442288":{"lch":[24.1630625686767715,63.8732961962266543,273.501787345358252],"luv":[24.1630625686767715,3.90136026108148481,-63.7540379512086801],"rgb":[0.266666666666666663,0.133333333333333331,0.533333333333333326],"xyz":[0.0739930611039093106,0.0415055810211192727,0.237046377919352902],"hpluv":[273.501787345358252,335.433687598002,24.1630625686767715],"hsluv":[273.501787345358252,78.1624380374364875,24.1630625686767715]},"#442299":{"lch":[25.7815797239733442,74.3421908873045112,271.638748742297366],"luv":[25.7815797239733442,2.1260128283266071,-74.3117851715204836],"rgb":[0.266666666666666663,0.133333333333333331,0.6],"xyz":[0.087050025212982024,0.0467283666647484303,0.305813055560470781],"hpluv":[271.638748742297366,365.902315457699217,25.7815797239733442],"hsluv":[271.638748742297366,81.974423252689391,25.7815797239733442]},"#4422aa":{"lch":[27.5046927955253,84.5952413694672885,270.370058715866037],"luv":[27.5046927955253,0.546375125789773097,-84.5934769150692176],"rgb":[0.266666666666666663,0.133333333333333331,0.66666666666666663],"xyz":[0.102107718178234566,0.0527514438508495317,0.385116905177469382],"hpluv":[270.370058715866037,390.281946032504152,27.5046927955253],"hsluv":[270.370058715866037,84.9950544768410765,27.5046927955253]},"#4422bb":{"lch":[29.3129652277151251,94.666070770970677,269.4687873747244],"luv":[29.3129652277151251,-0.87767531850734,-94.6620020982533],"rgb":[0.266666666666666663,0.133333333333333331,0.733333333333333282],"xyz":[0.119245310285571213,0.0596064806937842903,0.475374890276111128],"hpluv":[269.4687873747244,409.801860030343846,29.3129652277151251],"hsluv":[269.4687873747244,87.3984435941311517,29.3129652277151251]},"#4422cc":{"lch":[31.1896477872922873,104.586362634530047,268.806646243455475],"luv":[31.1896477872922873,-2.17816227055809408,-104.563678484665701],"rgb":[0.266666666666666663,0.133333333333333331,0.8],"xyz":[0.138537685729292953,0.0673234308712731,0.576981400946381284],"hpluv":[268.806646243455475,425.504262664631483,31.1896477872922873],"hsluv":[268.806646243455475,89.3235413687926325,31.1896477872922873]},"#4422dd":{"lch":[33.1206275871571,114.38069493574325,268.306702684458742],"luv":[33.1206275871571,-3.37987077956927,-114.330747603157818],"rgb":[0.266666666666666663,0.133333333333333331,0.866666666666666696],"xyz":[0.160056011279926497,0.0759307610915266329,0.690311248846387282],"hpluv":[268.306702684458742,438.22131720165,33.1206275871571],"hsluv":[268.306702684458742,90.877884626449017,33.1206275871571]},"#4422ee":{"lch":[35.0941942457284952,124.066768949832422,267.920557621455941],"luv":[35.0941942457284952,-4.50178121539094178,-123.985068147498538],"rgb":[0.266666666666666663,0.133333333333333331,0.933333333333333348],"xyz":[0.183868191546101234,0.0854556331979966499,0.815722064914910505],"hpluv":[267.920557621455941,448.600262181889605,35.0941942457284952],"hsluv":[267.920557621455941,93.3452679661598523,35.0941942457284952]},"#4422ff":{"lch":[37.1007304630435,133.656986375695226,267.616535799179189],"luv":[37.1007304630435,-5.55843332369103926,-133.54135623850334],"rgb":[0.266666666666666663,0.133333333333333331,1],"xyz":[0.210039239955932627,0.0959240525619293599,0.95355625320669235],"hpluv":[267.616535799179189,457.139270395610822,37.1007304630435],"hsluv":[267.616535799179189,99.999999999999531,37.1007304630435]},"#bbaa00":{"lch":[68.9787767407419,76.4078567958722346,76.7962953219783344],"luv":[68.9787767407419,17.4526104568015299,74.3879490803561652],"rgb":[0.733333333333333282,0.66666666666666663,0],"xyz":[0.348671553863065253,0.393149255751080451,0.0575197745907461769],"hpluv":[76.7962953219783344,140.560034871296551,68.9787767407419],"hsluv":[76.7962953219783344,100.000000000002245,68.9787767407419]},"#bbaa11":{"lch":[69.0079227935645747,75.1793224892161902,76.6760735029220797],"luv":[69.0079227935645747,17.325534429098667,73.1556996185784811],"rgb":[0.733333333333333282,0.66666666666666663,0.0666666666666666657],"xyz":[0.349683219362702358,0.393553921950935304,0.0628478795555018],"hpluv":[76.6760735029220797,138.241608756115426,69.0079227935645747],"hsluv":[76.6760735029220797,98.327691673723,69.0079227935645747]},"#bbaa22":{"lch":[69.0618990033698168,72.923722885125926,76.4446579961253718],"luv":[69.0618990033698168,17.0921879270318975,70.8923583420220496],"rgb":[0.733333333333333282,0.66666666666666663,0.133333333333333331],"xyz":[0.351558577501179415,0.394304065206326104,0.072724765751481],"hpluv":[76.4446579961253718,133.98915323660276,69.0618990033698168],"hsluv":[76.4446579961253718,95.2591470849694701,69.0618990033698168]},"#bbaa33":{"lch":[69.1506211183474448,69.2704933393546298,76.037430434814425],"luv":[69.1506211183474448,16.7141363744442764,67.2237970716773248],"rgb":[0.733333333333333282,0.66666666666666663,0.2],"xyz":[0.35464632823363712,0.395539165499309231,0.0889869196090921494],"hpluv":[76.037430434814425,127.113454601419591,69.1506211183474448],"hsluv":[76.037430434814425,90.2940538071316752,69.1506211183474448]},"#bbaa44":{"lch":[69.2783900215706439,64.125663575375043,75.3840533289293688],"luv":[69.2783900215706439,16.1813855024742246,62.0504914743025964],"rgb":[0.733333333333333282,0.66666666666666663,0.266666666666666663],"xyz":[0.359104323477856036,0.397322363596996797,0.112465694561978788],"hpluv":[75.3840533289293688,117.455514697890109,69.2783900215706439],"hsluv":[75.3840533289293688,83.3108908827552455,69.2783900215706439]},"#bbaa55":{"lch":[69.4486803199850158,57.4759826537307603,74.3632861967268752],"luv":[69.4486803199850158,15.4919003466967737,55.3487994961044762],"rgb":[0.733333333333333282,0.66666666666666663,0.333333333333333315],"xyz":[0.365066737517218,0.399707329212741658,0.143867741835952689],"hpluv":[74.3632861967268752,105.017514149864908,69.4486803199850158],"hsluv":[74.3632861967268752,74.2978448337225501,69.4486803199850158]},"#bbaa66":{"lch":[69.6643364030220766,49.3851711615203186,72.7428070953876],"luv":[69.6643364030220766,14.6506772614363818,47.1619845472377079],"rgb":[0.733333333333333282,0.66666666666666663,0.4],"xyz":[0.372651733290726206,0.402741327522145,0.183815386243096651],"hpluv":[72.7428070953876,89.9550160304510342,69.6643364030220766],"hsluv":[72.7428070953876,63.3404983901227254,69.6643364030220766]},"#bbaa77":{"lch":[69.927675331165787,39.998456174204172,70.017617272721],"luv":[69.927675331165787,13.6687200676018641,37.5904587366697314],"rgb":[0.733333333333333282,0.66666666666666663,0.466666666666666674],"xyz":[0.381965746310928111,0.406466932730225772,0.23286918814949456],"hpluv":[70.017617272721,72.5827577171275635,69.927675331165787],"hsluv":[70.017617272721,50.6076787731359303,69.927675331165787]},"#bbaa88":{"lch":[70.2405480333122,29.5797452752191568,64.8698942165899837],"luv":[70.2405480333122,12.5617839686329518,26.7798975739685403],"rgb":[0.733333333333333282,0.66666666666666663,0.533333333333333326],"xyz":[0.393106163412871912,0.41092309957100337,0.291542051553066728],"hpluv":[64.8698942165899837,53.4374671266607422,70.2405480333122],"hsluv":[64.8698942165899837,36.3337734813298923,70.2405480333122]},"#bbaa99":{"lch":[70.6043801086793,18.7359983934483161,52.7186742094296079],"luv":[70.6043801086793,11.3489394865138475,14.907689570511744],"rgb":[0.733333333333333282,0.66666666666666663,0.6],"xyz":[0.406163127521944611,0.416145885214632527,0.360308729194184663],"hpluv":[52.7186742094296079,33.6732102985619051,70.6043801086793],"hsluv":[52.7186742094296079,20.7983697782308,70.6043801086793]},"#bbaaaa":{"lch":[71.0202025015365876,10.2824341490213804,12.177050630064155],"luv":[71.0202025015365876,10.0510841141786607,2.16890759569567715],"rgb":[0.733333333333333282,0.66666666666666663,0.66666666666666663],"xyz":[0.421220820487197167,0.422168962400733649,0.439612578811183263],"hpluv":[12.177050630064155,18.3718697222702261,71.0202025015365876],"hsluv":[12.177050630064155,12.5020210815887047,71.0202025015365876]},"#bbaabb":{"lch":[71.4886774714552615,14.2047670368859897,307.715012949256788],"luv":[71.4886774714552615,8.68954378602241562,-11.236869464535129],"rgb":[0.733333333333333282,0.66666666666666663,0.733333333333333282],"xyz":[0.438358412594533842,0.429023999243668408,0.529870563909825],"hpluv":[307.715012949256788,25.2136766683934965,71.4886774714552615],"hsluv":[307.715012949256788,14.1682246563909,71.4886774714552615]},"#bbaacc":{"lch":[72.010122844957138,26.1519063744379174,286.174295641089373],"luv":[72.010122844957138,7.28488198445553525,-25.1167812724863673],"rgb":[0.733333333333333282,0.66666666666666663,0.8],"xyz":[0.45765078803825554,0.43674094942115721,0.631477074580095166],"hpluv":[286.174295641089373,46.0838895939184923,72.010122844957138],"hsluv":[286.174295641089373,33.6938059680335442,72.010122844957138]},"#bbaadd":{"lch":[72.5845361735228494,39.7272427931479,278.476565574149959],"luv":[72.5845361735228494,5.85598959517198825,-39.2932717625671799],"rgb":[0.733333333333333282,0.66666666666666663,0.866666666666666696],"xyz":[0.47916911358888914,0.445348279641410716,0.744806922480101163],"hpluv":[278.476565574149959,69.451822258827633,72.5845361735228494],"hsluv":[278.476565574149959,54.5084651382981775,72.5845361735228494]},"#bbaaee":{"lch":[73.2116196006959825,53.7916684525604,274.71268656160521],"luv":[73.2116196006959825,4.41947960396952144,-53.6098106221266093],"rgb":[0.733333333333333282,0.66666666666666663,0.933333333333333348],"xyz":[0.502981293855063849,0.454873151747880733,0.870217738548624387],"hpluv":[274.71268656160521,93.2340021292866084,73.2116196006959825],"hsluv":[274.71268656160521,76.5987468488048506,73.2116196006959825]},"#bbaaff":{"lch":[73.8908057188696574,67.9996555049746121,272.519622378571285],"luv":[73.8908057188696574,2.98936916429642707,-67.9339150998584671],"rgb":[0.733333333333333282,0.66666666666666663,1],"xyz":[0.52915234226489527,0.465341571111813457,1.00805192684040623],"hpluv":[272.519622378571285,116.776549017196231,73.8908057188696574],"hsluv":[272.519622378571285,99.9999999999974847,73.8908057188696574]},"#99bb00":{"lch":[71.0859361318702696,82.3913749493211327,101.26222245755217],"luv":[71.0859361318702696,-16.0909976916487061,80.8048170552163185],"rgb":[0.6,0.733333333333333282,0],"xyz":[0.309061217191489157,0.423126383737875533,0.0653895889393331653],"hpluv":[101.26222245755217,147.074503152999483,71.0859361318702696],"hsluv":[101.26222245755217,100.000000000002302,71.0859361318702696]},"#99bb11":{"lch":[71.1136894680978457,81.2167121813616291,101.442926834262664],"luv":[71.1136894680978457,-16.1127230849120338,79.6023523040561685],"rgb":[0.6,0.733333333333333282,0.0666666666666666657],"xyz":[0.310072882691126261,0.423531049937730386,0.0707176939040888],"hpluv":[101.442926834262664,144.921066000062638,71.1136894680978457],"hsluv":[101.442926834262664,98.4331733262411,71.1136894680978457]},"#99bb22":{"lch":[71.1650900316793837,79.0601549481488917,101.789083890819583],"luv":[71.1650900316793837,-16.1527448632600859,77.392486287802754],"rgb":[0.6,0.733333333333333282,0.133333333333333331],"xyz":[0.311948240829603318,0.424281193193121187,0.080594580100068],"hpluv":[101.789083890819583,140.971066242853169,71.1650900316793837],"hsluv":[101.789083890819583,95.5563304227746357,71.1650900316793837]},"#99bb33":{"lch":[71.2495884989653,75.5680342451554168,102.392870056849247],"luv":[71.2495884989653,-16.2179420391938294,73.807222923575253],"rgb":[0.6,0.733333333333333282,0.2],"xyz":[0.315035991562061,0.425516293486104313,0.0968567339576791309],"hpluv":[102.392870056849247,134.584514176993849,71.2495884989653],"hsluv":[102.392870056849247,90.8963478676004826,71.2495884989653]},"#99bb44":{"lch":[71.3712967033779648,70.652786516275043,103.347443045401377],"luv":[71.3712967033779648,-16.3105834167977157,68.7443169368786471],"rgb":[0.6,0.733333333333333282,0.266666666666666663],"xyz":[0.319493986806279939,0.427299491583791879,0.120335508910565769],"hpluv":[103.347443045401377,125.616021445862458,71.3712967033779648],"hsluv":[103.347443045401377,84.331672265085615,71.3712967033779648]},"#99bb55":{"lch":[71.5335490617920442,64.3081830776187502,104.804237401434776],"luv":[71.5335490617920442,-16.4318507493525949,62.1734404042074189],"rgb":[0.6,0.733333333333333282,0.333333333333333315],"xyz":[0.325456400845641924,0.42968445719953674,0.151737556184539685],"hpluv":[104.804237401434776,114.076396323867073,71.5335490617920442],"hsluv":[104.804237401434776,75.8403293762878263,71.5335490617920442]},"#99bb66":{"lch":[71.7390905918245494,56.6109161874071347,107.032342660002968],"luv":[71.7390905918245494,-16.5819871692753225,54.1279367156704367],"rgb":[0.6,0.733333333333333282,0.4],"xyz":[0.33304139661915011,0.432718455508940059,0.191685200591683647],"hpluv":[107.032342660002968,100.134479122606095,71.7390905918245494],"hsluv":[107.032342660002968,65.4891515707011,71.7390905918245494]},"#99bb77":{"lch":[71.9901757540345102,47.73532562127712,110.555323727161408],"luv":[71.9901757540345102,-16.7604289857032249,44.6961892378372099],"rgb":[0.6,0.733333333333333282,0.466666666666666674],"xyz":[0.342355409639352,0.436444060717020854,0.240739002498081556],"hpluv":[110.555323727161408,84.1406731320706,71.9901757540345102],"hsluv":[110.555323727161408,53.4218452589237,71.9901757540345102]},"#99bb88":{"lch":[72.2886271035685581,38.007890289968195,116.511646356383693],"luv":[72.2886271035685581,-16.9659512259030869,34.0111191126451473],"rgb":[0.6,0.733333333333333282,0.533333333333333326],"xyz":[0.353495826741295815,0.440900227557798452,0.299411865901653695],"hpluv":[116.511646356383693,66.7180145269523592,72.2886271035685581],"hsluv":[116.511646356383693,39.8440619041218724,72.2886271035685581]},"#99bb99":{"lch":[72.6358740128595315,28.1115962970155238,127.715012949234961],"luv":[72.6358740128595315,-17.1968288028560856,22.2380512970816788],"rgb":[0.6,0.733333333333333282,0.6],"xyz":[0.366552790850368515,0.44612301320142761,0.36817854354277163],"hpluv":[127.715012949234961,49.1104221429672094,72.6358740128595315],"hsluv":[127.715012949234961,25.0059581073328268,72.6358740128595315]},"#99bbaa":{"lch":[73.0329812495468929,19.8989345424194468,151.280397210880039],"luv":[73.0329812495468929,-17.4510036711552878,9.56190706882358654],"rgb":[0.6,0.733333333333333282,0.66666666666666663],"xyz":[0.381610483815621071,0.452146090387528732,0.447482393159770231],"hpluv":[151.280397210880039,34.5740392557976648,73.0329812495468929],"hsluv":[151.280397210880039,28.0327457551748473,73.0329812495468929]},"#99bbbb":{"lch":[73.4806726048520602,18.1342571597367979,192.177050630060279],"luv":[73.4806726048520602,-17.7262447217336288,-3.82511840348453136],"rgb":[0.6,0.733333333333333282,0.733333333333333282],"xyz":[0.398748075922957745,0.45900112723046349,0.537740378258412],"hpluv":[192.177050630060279,31.3159775944509384,73.4806726048520602],"hsluv":[192.177050630060279,31.1933976709334857,73.4806726048520602]},"#99bbcc":{"lch":[73.9793524714423,25.2831678504957686,224.541830016242],"luv":[73.9793524714423,-18.0202882726228886,-17.734367401402082],"rgb":[0.6,0.733333333333333282,0.8],"xyz":[0.418040451366679444,0.466718077407952292,0.639346888928682189],"hpluv":[224.541830016242,43.3670907410057183,73.9793524714423],"hsluv":[224.541830016242,34.4349286550277398,73.9793524714423]},"#99bbdd":{"lch":[74.5291269946933284,36.8692317824205347,240.185846709470951],"luv":[74.5291269946933284,-18.3309507682094441,-31.9893184697537762],"rgb":[0.6,0.733333333333333282,0.866666666666666696],"xyz":[0.439558776917313043,0.475325407628205798,0.752676736828688187],"hpluv":[240.185846709470951,62.7736499155611796,74.5291269946933284],"hsluv":[240.185846709470951,50.9371920612126914,74.5291269946933284]},"#99bbee":{"lch":[75.129825653719962,50.0395173115419851,248.109771752659725],"luv":[75.129825653719962,-18.6562099892881648,-46.4316607672792],"rgb":[0.6,0.733333333333333282,0.933333333333333348],"xyz":[0.463370957183487753,0.484850279734675815,0.87808755289721141],"hpluv":[248.109771752659725,84.5162185097210568,75.129825653719962],"hsluv":[248.109771752659725,74.708817528734329,75.129825653719962]},"#99bbff":{"lch":[75.7810236401202104,63.8171103470632701,252.684342225014],"luv":[75.7810236401202104,-18.9942553989637197,-60.9248868270445527],"rgb":[0.6,0.733333333333333282,1],"xyz":[0.489542005593319174,0.495318699098608539,1.01592174118899314],"hpluv":[252.684342225014,106.860202909060845,75.7810236401202104],"hsluv":[252.684342225014,99.9999999999971,75.7810236401202104]},"#443300":{"lch":[22.2907133772276609,26.4379209369795269,61.2454831359909],"luv":[22.2907133772276609,12.7181702882918319,23.1778300966244757],"rgb":[0.266666666666666663,0.2,0],"xyz":[0.0356761736431134499,0.0359671813792181508,0.00506334165336921362],"hpluv":[61.2454831359909,150.502134175174433,22.2907133772276609],"hsluv":[61.2454831359909,100.000000000002217,22.2907133772276609]},"#443311":{"lch":[22.433780901835803,22.5495741902090607,57.6291729330006959],"luv":[22.433780901835803,12.072970412625418,19.0453847841311372],"rgb":[0.266666666666666663,0.2,0.0666666666666666657],"xyz":[0.0366878391427505751,0.0363718475790730036,0.0103914466181248451],"hpluv":[57.6291729330006959,127.548453681164943,22.433780901835803],"hsluv":[57.6291729330006959,82.4396262904162853,22.433780901835803]},"#443322":{"lch":[22.6962080128251955,16.3034653251506185,47.6268315603120129],"luv":[22.6962080128251955,10.9878263584328284,12.044527949459761],"rgb":[0.266666666666666663,0.2,0.133333333333333331],"xyz":[0.0385631972812275903,0.037121990834463825,0.0202683328141040411],"hpluv":[47.6268315603120129,91.1519465603444,22.6962080128251955],"hsluv":[47.6268315603120129,53.1527363908354289,22.6962080128251955]},"#443333":{"lch":[23.1206934094119845,9.67437860897999613,12.1770506300626202],"luv":[23.1206934094119845,9.4567095438703852,2.04064844418642899],"rgb":[0.266666666666666663,0.2,0.2],"xyz":[0.0416509480136853308,0.0383570911274469378,0.0365304866717151844],"hpluv":[12.1770506300626202,53.0959690287213917,23.1206934094119845],"hsluv":[12.1770506300626202,12.4420312875371923,23.1206934094119845]},"#443344":{"lch":[23.7177668131648574,12.5269391023357528,307.715012949247694],"luv":[23.7177668131648574,7.66315882209806354,-9.90960141180911],"rgb":[0.266666666666666663,0.2,0.266666666666666663],"xyz":[0.0461089432579042113,0.0401402892251345109,0.0600092616246018229],"hpluv":[307.715012949247694,67.0209373905010608,23.7177668131648574],"hsluv":[307.715012949247694,23.1872031280306743,23.7177668131648574]},"#443355":{"lch":[24.4893027034144382,23.4497607107203301,284.299245815683662],"luv":[24.4893027034144382,5.79176863833153277,-22.7232632654309157],"rgb":[0.266666666666666663,0.2,0.333333333333333315],"xyz":[0.0520713572972662,0.0425252548408793438,0.0914113088985757383],"hpluv":[284.299245815683662,121.507006770462795,24.4893027034144382],"hsluv":[284.299245815683662,34.0172562824217479,24.4893027034144382]},"#443366":{"lch":[25.4301832846655458,35.8361728283181407,276.366541048647719],"luv":[25.4301832846655458,3.97382245046802396,-35.6151655634680964],"rgb":[0.266666666666666663,0.2,0.4],"xyz":[0.0596563530707743817,0.0455592531502826553,0.1313589533057197],"hpluv":[276.366541048647719,178.818092823782393,25.4301832846655458],"hsluv":[276.366541048647719,44.0521665839457555,25.4301832846655458]},"#443377":{"lch":[26.5300434901181958,48.2102429207408818,272.708376965990851],"luv":[26.5300434901181958,2.27805419202829862,-48.1563909733176416],"rgb":[0.266666666666666663,0.2,0.466666666666666674],"xyz":[0.0689703660909762872,0.0492848583583634717,0.180412755212117609],"hpluv":[272.708376965990851,230.590114205629249,26.5300434901181958],"hsluv":[272.708376965990851,52.8563285469964583,26.5300434901181958]},"#443388":{"lch":[27.7750487339787355,60.1896827108213373,270.691543734184165],"luv":[27.7750487339787355,0.726454682878815761,-60.1852986070773568],"rgb":[0.266666666666666663,0.2,0.533333333333333326],"xyz":[0.0801107831929201153,0.0537410251991410626,0.239085618615689777],"hpluv":[270.691543734184165,274.983446475144433,27.7750487339787355],"hsluv":[270.691543734184165,60.324174233719404,27.7750487339787355]},"#443399":{"lch":[29.1495234429961272,71.6961686956082218,269.452076389218803],"luv":[29.1495234429961272,-0.685625105343165342,-71.6928903298230438],"rgb":[0.266666666666666663,0.2,0.6],"xyz":[0.0931677473019928426,0.058963810842770227,0.307852296256807656],"hpluv":[269.452076389218803,312.107220431461315,29.1495234429961272],"hsluv":[269.452076389218803,66.5368599437509,29.1495234429961272]},"#4433aa":{"lch":[30.6372824460415245,82.7612763398458924,268.632918119842316],"luv":[30.6372824460415245,-1.97450330946598829,-82.7377193188284821],"rgb":[0.266666666666666663,0.2,0.66666666666666663],"xyz":[0.108225440267245371,0.0649868880288713285,0.387156145873806257],"hpluv":[268.632918119842316,342.78062465137026,30.6372824460415245],"hsluv":[268.632918119842316,71.6553387322885698,30.6372824460415245]},"#4433bb":{"lch":[32.2226022397772525,93.4505902198726375,268.062492493372758],"luv":[32.2226022397772525,-3.15951219941267691,-93.3971642776391633],"rgb":[0.266666666666666663,0.2,0.733333333333333282],"xyz":[0.125363032374582017,0.0718419248718060871,0.477414130972448],"hpluv":[268.062492493372758,368.010970109266054,32.2226022397772525],"hsluv":[268.062492493372758,75.8581190135042789,32.2226022397772525]},"#4433cc":{"lch":[33.8908458580626331,103.832026214070311,267.649236367220567],"luv":[33.8908458580626331,-4.25888397543315911,-103.744646006447894],"rgb":[0.266666666666666663,0.2,0.8],"xyz":[0.144655407818303772,0.0795588750492948887,0.579020641642718159],"hpluv":[267.649236367220567,388.765974213008576,33.8908458580626331],"hsluv":[267.649236367220567,79.3114034284002,33.8908458580626331]},"#4433dd":{"lch":[35.628800942302739,113.96424557581804,267.340372831489958],"luv":[35.628800942302739,-5.28823530427115518,-113.841485571087048],"rgb":[0.266666666666666663,0.2,0.866666666666666696],"xyz":[0.166173733368937315,0.0881662052695484227,0.692350489542724157],"hpluv":[267.340372831489958,405.888493424646128,35.628800942302739],"hsluv":[267.340372831489958,85.5677988674314,35.628800942302739]},"#4433ee":{"lch":[37.4248062251042484,123.894025620863303,267.103630337901393],"luv":[37.4248062251042484,-6.26032296204841732,-123.73575853791813],"rgb":[0.266666666666666663,0.2,0.933333333333333348],"xyz":[0.189985913635112053,0.0976910773760184536,0.81776130561124738],"hpluv":[267.103630337901393,420.078186698807599,37.4248062251042484],"hsluv":[267.103630337901393,92.6566888343209,37.4248062251042484]},"#4433ff":{"lch":[39.2687372084732473,133.657198385904053,266.918330051954797],"luv":[39.2687372084732473,-7.18532525912719411,-133.4639193988003],"rgb":[0.266666666666666663,0.2,1],"xyz":[0.216156962044943446,0.10815949673995115,0.955595493903029225],"hpluv":[266.918330051954797,431.901531941155895,39.2687372084732473],"hsluv":[266.918330051954797,99.99999999999946,39.2687372084732473]},"#bbbb00":{"lch":[73.6141498101152223,81.1522849996882485,85.8743202181747591],"luv":[73.6141498101152223,5.83845950082822274,80.9419900380996],"rgb":[0.733333333333333282,0.733333333333333282,0],"xyz":[0.382626051771664,0.461058251568279,0.0688379405602788],"hpluv":[85.8743202181747591,139.887458074797564,73.6141498101152223],"hsluv":[85.8743202181747591,100.000000000002331,73.6141498101152223]},"#bbbb11":{"lch":[73.6403599567658205,80.0195247391518478,85.8743202181747449],"luv":[73.6403599567658205,5.75696364516240155,79.8121651696532695],"rgb":[0.733333333333333282,0.733333333333333282,0.0666666666666666657],"xyz":[0.383637717271301082,0.461462917768133862,0.0741660455250344325],"hpluv":[85.8743202181747449,137.885751829634614,73.6403599567658205],"hsluv":[85.8743202181747449,98.5690595334933732,73.6403599567658205]},"#bbbb22":{"lch":[73.6889060807276763,77.9361940700347873,85.8743202181746597],"luv":[73.6889060807276763,5.60707948923862176,77.7342331648256817],"rgb":[0.733333333333333282,0.733333333333333282,0.133333333333333331],"xyz":[0.385513075409778139,0.462213061023524663,0.0840429317210136251],"hpluv":[85.8743202181746597,134.207383902194948,73.6889060807276763],"hsluv":[85.8743202181746597,95.9395400768792541,73.6889060807276763]},"#bbbb33":{"lch":[73.768722281637082,74.5519121144895536,85.8743202181745318],"luv":[73.768722281637082,5.36359906059884217,74.3587211095223],"rgb":[0.733333333333333282,0.733333333333333282,0.2],"xyz":[0.388600826142235845,0.46344816131650779,0.100305085578624775],"hpluv":[85.8743202181745318,128.24069174643796,73.768722281637082],"hsluv":[85.8743202181745318,91.6741883163470419,73.768722281637082]},"#bbbb44":{"lch":[73.8837085661944144,69.7637661309282464,85.8743202181743328],"luv":[73.8837085661944144,5.01911835485944824,69.5829829463408629],"rgb":[0.733333333333333282,0.733333333333333282,0.266666666666666663],"xyz":[0.39305882138645476,0.465231359414195356,0.123783860531511414],"hpluv":[85.8743202181743328,119.817583791868643,73.8837085661944144],"hsluv":[85.8743202181743328,85.652842249664161,73.8837085661944144]},"#bbbb55":{"lch":[74.0370403615741,63.5337415760462747,85.8743202181740628],"luv":[74.0370403615741,4.57090243520957262,63.3691026414263376],"rgb":[0.733333333333333282,0.733333333333333282,0.333333333333333315],"xyz":[0.399021235425816745,0.467616325029940216,0.155185907805485301],"hpluv":[85.8743202181740628,108.891682763750694,74.0370403615741],"hsluv":[85.8743202181740628,77.8423486010655239,74.0370403615741]},"#bbbb66":{"lch":[74.2313474843288361,55.8815023675101799,85.8743202181735512],"luv":[74.2313474843288361,4.02036601211528843,55.7366931561128212],"rgb":[0.733333333333333282,0.733333333333333282,0.4],"xyz":[0.40660623119932493,0.470650323339343535,0.195133552212629291],"hpluv":[85.8743202181735512,95.5256619678334857,74.2313474843288361],"hsluv":[85.8743202181735512,68.2875100330713138,74.2313474843288361]},"#bbbb77":{"lch":[74.468808451125966,46.8772880877030289,85.8743202181728549],"luv":[74.468808451125966,3.37256243628739805,46.7558120565865849],"rgb":[0.733333333333333282,0.733333333333333282,0.466666666666666674],"xyz":[0.415920244219526836,0.47437592854742433,0.2441873541190272],"hpluv":[85.8743202181728549,79.8780401793102328,74.468808451125966],"hsluv":[85.8743202181728549,57.1016453359253688,74.468808451125966]},"#bbbb88":{"lch":[74.7512063572608128,36.6333476151433146,85.874320218171647],"luv":[74.7512063572608128,2.63556739569020726,36.5384173438683746],"rgb":[0.733333333333333282,0.733333333333333282,0.533333333333333326],"xyz":[0.427060661321470636,0.478832095388201928,0.30286021752259934],"hpluv":[85.874320218171647,62.1867310089120195,74.7512063572608128],"hsluv":[85.874320218171647,44.4548295213588744,74.7512063572608128]},"#bbbb99":{"lch":[75.079965438194165,25.2938928616919938,85.8743202181691316],"luv":[75.079965438194165,1.81975614231989979,25.2283472245258693],"rgb":[0.733333333333333282,0.733333333333333282,0.6],"xyz":[0.440117625430543336,0.484054881031831086,0.371626895163717275],"hpluv":[85.8743202181691316,42.7494899193068392,75.079965438194165],"hsluv":[85.8743202181691316,30.559916169503893,75.079965438194165]},"#bbbbaa":{"lch":[75.4561775549407372,13.0242335847304886,85.8743202181613583],"luv":[75.4561775549407372,0.937021801842234714,12.9904830784884187],"rgb":[0.733333333333333282,0.733333333333333282,0.66666666666666663],"xyz":[0.455175318395795891,0.490077958217932208,0.450930744780715875],"hpluv":[85.8743202181613583,21.9026519543336242,75.4561775549407372],"hsluv":[85.8743202181613583,15.6573378741524305,75.4561775549407372]},"#bbbbbb":{"lch":[75.8806235332097856,3.97454725928322e-12,0],"luv":[75.8806235332097856,3.75098259432623098e-12,1.31421287976393485e-12],"rgb":[0.733333333333333282,0.733333333333333282,0.733333333333333282],"xyz":[0.472312910503132566,0.496932995060866967,0.541188729879357622],"hpluv":[0,6.64654731741433278e-12,75.8806235332097856],"hsluv":[0,6.51507609526145538e-12,75.8806235332097856]},"#bbbbcc":{"lch":[76.3537921403793,13.6026726964261613,265.874320218192793],"luv":[76.3537921403793,-0.97863730689855577,-13.5674232449512715],"rgb":[0.733333333333333282,0.733333333333333282,0.8],"xyz":[0.491605285946854265,0.504649945238355713,0.642795240549627778],"hpluv":[265.874320218192793,23.0577392955455913,76.3537921403793],"hsluv":[265.874320218192793,22.3559583930985184,76.3537921403793]},"#bbbbdd":{"lch":[76.875898300454,27.6153317552162676,265.874320218184891],"luv":[76.875898300454,-1.98677087225565296,-27.543770429115412],"rgb":[0.733333333333333282,0.733333333333333282,0.866666666666666696],"xyz":[0.513123611497487864,0.51325727545860933,0.756125088449633775],"hpluv":[265.874320218184891,48.094692651754464,76.875898300454],"hsluv":[265.874320218184891,46.4508399898830717,76.875898300454]},"#bbbbee":{"lch":[77.4469014383288794,41.8833893600305487,265.874320218182334],"luv":[77.4469014383288794,-3.01327895494808,-41.7748543291725554],"rgb":[0.733333333333333282,0.733333333333333282,0.933333333333333348],"xyz":[0.536935791763662573,0.522782147565079347,0.881535904518157],"hpluv":[265.874320218182334,75.1781465494946,77.4469014383288794],"hsluv":[265.874320218182334,72.306149300046286,77.4469014383288794]},"#bbbbff":{"lch":[78.0665243938900915,56.270213901735211,265.874320218181083],"luv":[78.0665243938900915,-4.04833166396953814,-56.1243973979724444],"rgb":[0.733333333333333282,0.733333333333333282,1],"xyz":[0.563106840173494,0.533250566929012,1.01937009280993873],"hpluv":[265.874320218181083,104.437018855576454,78.0665243938900915],"hsluv":[265.874320218181083,99.9999999999968,78.0665243938900915]},"#99cc00":{"lch":[76.0430979526319,91.0941172293808,106.263360497649074],"luv":[76.0430979526319,-25.5111694560196547,87.4489475453331124],"rgb":[0.6,0.8,0],"xyz":[0.347284960501106077,0.499573870357110428,0.0781308367092051204],"hpluv":[106.263360497649074,152.00919412554731,76.0430979526319],"hsluv":[106.263360497649074,100.000000000002444,76.0430979526319]},"#99cc11":{"lch":[76.0679435797449202,90.0431717383104342,106.457693210299354],"luv":[76.0679435797449202,-25.5098862277023812,86.3540299079582496],"rgb":[0.6,0.8,0.0666666666666666657],"xyz":[0.348296626000743181,0.499978536556965281,0.083458941673960757],"hpluv":[106.457693210299354,150.416675371578,76.0679435797449202],"hsluv":[106.457693210299354,98.6698238814781377,76.0679435797449202]},"#99cc22":{"lch":[76.1139653123302224,88.1120975577654235,106.827460928226145],"luv":[76.1139653123302224,-25.5076232207001254,84.3392132620406301],"rgb":[0.6,0.8,0.133333333333333331],"xyz":[0.350171984139220238,0.500728679812356137,0.0933358278699399496],"hpluv":[106.827460928226145,147.536178080277807,76.1139653123302224],"hsluv":[106.827460928226145,96.2239688839219554,76.1139653123302224]},"#99cc33":{"lch":[76.1896394090333615,84.9806694979027668,107.464683868975555],"luv":[76.1896394090333615,-25.5042190273125513,81.0632407452271195],"rgb":[0.6,0.8,0.2],"xyz":[0.353259734871677944,0.501963780105339263,0.109597981727551086],"hpluv":[107.464683868975555,142.843382477451314,76.1896394090333615],"hsluv":[107.464683868975555,92.2523981769505497,76.1896394090333615]},"#99cc44":{"lch":[76.2986765643697566,80.5641186971074461,108.452476349375274],"luv":[76.2986765643697566,-25.4999909675489818,76.4220366262018445],"rgb":[0.6,0.8,0.266666666666666663],"xyz":[0.357717730115896859,0.503746978203026829,0.133076756680437724],"hpluv":[108.452476349375274,136.177549938509202,76.2986765643697566],"hsluv":[108.452476349375274,86.6370393323296,76.2986765643697566]},"#99cc55":{"lch":[76.4441084930992645,74.8483308647658276,109.915235611542258],"luv":[76.4441084930992645,-25.4955548836031696,70.3722197633315858],"rgb":[0.6,0.8,0.333333333333333315],"xyz":[0.363680144155258844,0.506131943818771579,0.16447880395441164],"hpluv":[109.915235611542258,127.465568679298812,76.4441084930992645],"hsluv":[109.915235611542258,79.3378797119037245,76.4441084930992645]},"#99cc66":{"lch":[76.6284587708723279,67.8919791104198111,112.053749389120497],"luv":[76.6284587708723279,-25.4918238993559072,62.9244606001029396],"rgb":[0.6,0.8,0.4],"xyz":[0.37126513992876703,0.509165942128174898,0.204426448361555602],"hpluv":[112.053749389120497,116.726185086844026,76.6284587708723279],"hsluv":[112.053749389120497,70.3850130172815796,76.6284587708723279]},"#99cc77":{"lch":[76.8538330837355801,59.8379910057359723,115.212918879407354],"luv":[76.8538330837355801,-25.4899847789994141,54.1372869986012262],"rgb":[0.6,0.8,0.466666666666666674],"xyz":[0.380579152948968935,0.512891547336255749,0.253480250267953511],"hpluv":[115.212918879407354,104.093311342856381,76.8538330837355801],"hsluv":[115.212918879407354,59.8707914454029577,76.8538330837355801]},"#99cc88":{"lch":[77.1219726780439885,50.9458531819172649,120.024060615406185],"luv":[77.1219726780439885,-25.4914521322680621,44.1097021597488919],"rgb":[0.6,0.8,0.533333333333333326],"xyz":[0.391719570050912735,0.517347714177033291,0.31215311367152565],"hpluv":[120.024060615406185,89.8814395273866324,77.1219726780439885],"hsluv":[120.024060615406185,47.9401368886289845,77.1219726780439885]},"#99cc99":{"lch":[77.4342891130262103,41.681173098632776,127.715012949236964],"luv":[77.4342891130262103,-25.4978049096247332,32.9724450969124447],"rgb":[0.6,0.8,0.6],"xyz":[0.40477653415998549,0.522570499820662504,0.380919791312643585],"hpluv":[127.715012949236964,74.7648437658604337,77.4342891130262103],"hsluv":[127.715012949236964,34.7788947556027495,77.4342891130262103]},"#99ccaa":{"lch":[77.7918890721377352,32.9651751214879525,140.702563314804109],"luv":[77.7918890721377352,-25.5107121176450882,20.8783701002018844],"rgb":[0.6,0.8,0.66666666666666663],"xyz":[0.419834227125238,0.528593577006763571,0.460223640929642186],"hpluv":[140.702563314804109,60.2770963674260756,77.7918890721377352],"hsluv":[140.702563314804109,37.0803100068772622,77.7918890721377352]},"#99ccbb":{"lch":[78.1955939192693421,26.7536671513630395,162.617393192268167],"luv":[78.1955939192693421,-25.5318556358660231,7.9926875226808507],"rgb":[0.6,0.8,0.733333333333333282],"xyz":[0.436971819232574665,0.535448613849698329,0.550481626028283877],"hpluv":[162.617393192268167,50.006554278151107,78.1955939192693421],"hsluv":[162.617393192268167,39.5096284608221353,78.1955939192693421]},"#99cccc":{"lch":[78.6459566685868481,26.1512486118356264,192.177050630060364],"luv":[78.6459566685868481,-25.562857556775878,-5.51616873291790277],"rgb":[0.6,0.8,0.8],"xyz":[0.45626419467629642,0.543165564027187187,0.652088136698554],"hpluv":[192.177050630060364,50.1138147500145,78.6459566685868481],"hsluv":[192.177050630060364,42.0292910605185952,78.6459566685868481]},"#99ccdd":{"lch":[79.1432779300782,32.1756084020034763,217.269502822152816],"luv":[79.1432779300782,-25.6052179328205156,-19.4844191766612091],"rgb":[0.6,0.8,0.866666666666666696],"xyz":[0.477782520226929908,0.551772894247440693,0.76541798459856],"hpluv":[217.269502822152816,63.4104034428488532,79.1432779300782],"hsluv":[217.269502822152816,44.6030324020319142,79.1432779300782]},"#99ccee":{"lch":[79.6876217339600146,42.4043636674930298,232.761609201673764],"luv":[79.6876217339600146,-25.6602666815912279,-33.7591583407321],"rgb":[0.6,0.8,0.933333333333333348],"xyz":[0.501594700493104728,0.56129776635391071,0.890828800667083254],"hpluv":[232.761609201673764,86.2263034184575901,79.6876217339600146],"hsluv":[232.761609201673764,69.2463215394111842,79.6876217339600146]},"#99ccff":{"lch":[80.278831719152322,54.6396736698167231,241.908088190648726],"luv":[80.278831719152322,-25.7291311718118969,-48.2027566419988105],"rgb":[0.6,0.8,1],"xyz":[0.527765748902936,0.571766185717843434,1.02866298895886521],"hpluv":[241.908088190648726,115.039816302159181,80.278831719152322],"hsluv":[241.908088190648726,99.9999999999963762,80.278831719152322]},"#444400":{"lch":[27.7455139749470092,30.5866720374503593,85.8743202181747307],"luv":[27.7455139749470092,2.20054242411605072,30.5074108925390952],"rgb":[0.266666666666666663,0.266666666666666663,0],"xyz":[0.044508744126079483,0.0536323223451504599,0.00800753181435780864],"hpluv":[85.8743202181747307,139.887458074797593,27.7455139749470092],"hsluv":[85.8743202181747307,100.000000000002331,27.7455139749470092]},"#444411":{"lch":[27.8552611903384602,27.0161424908788135,85.8743202181744],"luv":[27.8552611903384602,1.9436625081132386,26.9461338811715763],"rgb":[0.266666666666666663,0.266666666666666663,0.0666666666666666657],"xyz":[0.0455204096257166,0.0540369885450053128,0.0133356367791134401],"hpluv":[85.8743202181744,123.070915058641674,27.8552611903384602],"hsluv":[85.8743202181744,87.9785198418851451,27.8552611903384602]},"#444422":{"lch":[28.0572627170229296,20.802612285424587,85.8743202181735086],"luv":[28.0572627170229296,1.49663326596887214,20.7487051828516122],"rgb":[0.266666666666666663,0.266666666666666663,0.133333333333333331],"xyz":[0.0473957677641936234,0.0547871318003961341,0.0232125229750926379],"hpluv":[85.8743202181735086,94.0831614915658463,28.0572627170229296],"hsluv":[85.8743202181735086,67.2563236092702539,28.0572627170229296]},"#444433":{"lch":[28.3858756417530103,11.5666907278610811,85.8743202181704],"luv":[28.3858756417530103,0.832159628943940688,11.5367172430437677],"rgb":[0.266666666666666663,0.266666666666666663,0.2],"xyz":[0.0504835184966513639,0.056022232093379247,0.0394746768327037811],"hpluv":[85.8743202181704,51.7066205750809758,28.3858756417530103],"hsluv":[85.8743202181704,36.9630139018145201,28.3858756417530103]},"#444444":{"lch":[28.8519023983998864,1.56211738287899238e-12,0],"luv":[28.8519023983998864,1.45745810878583046e-12,5.6216241338882039e-13],"rgb":[0.266666666666666663,0.266666666666666663,0.266666666666666663],"xyz":[0.0549415137408702445,0.05780543019106682,0.0629534517855904197],"hpluv":[0,6.87034486140541504e-12,28.8519023983998864],"hsluv":[0,1.96712204652458306e-12,28.8519023983998864]},"#444455":{"lch":[29.4604491554767947,12.996237632929807,265.874320218183527],"luv":[29.4604491554767947,-0.935007647451096213,-12.9625596743385874],"rgb":[0.266666666666666663,0.266666666666666663,0.333333333333333315],"xyz":[0.0609039277802322365,0.0601903958068116529,0.094355499059564335],"hpluv":[265.874320218183527,55.9780294653588157,29.4604491554767947],"hsluv":[265.874320218183527,10.903125265393685,29.4604491554767947]},"#444466":{"lch":[30.2117995944983235,26.5936989313503034,265.874320218180401],"luv":[30.2117995944983235,-1.9132700229980284,-26.52478502590359],"rgb":[0.266666666666666663,0.266666666666666663,0.4],"xyz":[0.0684889235537404079,0.0632243941162149714,0.134303143466708297],"hpluv":[265.874320218180401,111.69699235114156,30.2117995944983235],"hsluv":[265.874320218180401,21.7557908165695544,30.2117995944983235]},"#444477":{"lch":[31.1022350000615333,40.188693881548005,265.874320218179378],"luv":[31.1022350000615333,-2.89135495838767076,-40.084550420447286],"rgb":[0.266666666666666663,0.266666666666666663,0.466666666666666674],"xyz":[0.0778029365739423273,0.0669499993242957808,0.183356945373106206],"hpluv":[265.874320218179378,163.965176201048621,31.1022350000615333],"hsluv":[265.874320218179378,31.9363305989270607,31.1022350000615333]},"#444488":{"lch":[32.1249060438116132,53.4239352836437,265.874320218178923],"luv":[32.1249060438116132,-3.84355760936744639,-53.2854945186250859],"rgb":[0.266666666666666663,0.266666666666666663,0.533333333333333326],"xyz":[0.0889433536758861554,0.0714061661650733787,0.242029808776678373],"hpluv":[265.874320218178923,211.024721596932807,32.1249060438116132],"hsluv":[265.874320218178923,41.1023574005893479,32.1249060438116132]},"#444499":{"lch":[33.2707247827276404,66.1374776044503818,265.874320218178639],"luv":[33.2707247827276404,-4.75822688765494473,-65.9660914467787336],"rgb":[0.266666666666666663,0.266666666666666663,0.6],"xyz":[0.102000317784958869,0.0766289518087025362,0.31079648641779628],"hpluv":[265.874320218178639,252.246234683596128,33.2707247827276404],"hsluv":[265.874320218178639,50.2337582903708224,33.2707247827276404]},"#4444aa":{"lch":[34.5292085317775772,78.2936422443982707,265.874320218178468],"luv":[34.5292085317775772,-5.63279591471267516,-78.090755061511743],"rgb":[0.266666666666666663,0.266666666666666663,0.66666666666666663],"xyz":[0.117058010750211411,0.0826520289948036446,0.390100336034794881],"hpluv":[265.874320218178468,287.726060771882089,34.5292085317775772],"hsluv":[265.874320218178468,59.0260968416557645,34.5292085317775772]},"#4444bb":{"lch":[35.8892144652077647,89.9250819913669801,265.874320218178354],"luv":[35.8892144652077647,-6.46961387860876,-89.6920535355044],"rgb":[0.266666666666666663,0.266666666666666663,0.733333333333333282],"xyz":[0.134195602857548058,0.0895070658377384,0.480358321133436628],"hpluv":[265.874320218178354,317.948086985701252,35.8892144652077647],"hsluv":[265.874320218178354,67.4283717547759807,35.8892144652077647]},"#4444cc":{"lch":[37.3395287853000397,101.093816173965237,265.874320218178298],"luv":[37.3395287853000397,-7.27314272811459173,-100.831845482823283],"rgb":[0.266666666666666663,0.266666666666666663,0.8],"xyz":[0.153487978301269812,0.0972240160152272,0.581964831803706728],"hpluv":[265.874320218178298,343.55405942077391,37.3395287853000397],"hsluv":[265.874320218178298,75.5808548987534294,37.3395287853000397]},"#4444dd":{"lch":[38.8693012328948697,111.868746538356049,265.874320218178241],"luv":[38.8693012328948697,-8.04833956400084105,-111.578854100252741],"rgb":[0.266666666666666663,0.266666666666666663,0.866666666666666696],"xyz":[0.175006303851903355,0.105831346235480739,0.695294679703712726],"hpluv":[265.874320218178241,365.208910634554,38.8693012328948697],"hsluv":[265.874320218178241,83.6313726076760702,38.8693012328948697]},"#4444ee":{"lch":[40.4683363226646691,122.314460404417545,265.874320218178127],"luv":[40.4683363226646691,-8.799851087852959,-121.997499338533331],"rgb":[0.266666666666666663,0.266666666666666663,0.933333333333333348],"xyz":[0.198818484118078065,0.115356218341950756,0.820705495772236],"hpluv":[265.874320218178127,383.532154053589807,40.4683363226646691],"hsluv":[265.874320218178127,91.7249319236633625,40.4683363226646691]},"#4444ff":{"lch":[42.1272645151277203,132.4867415013303,265.874320218178127],"luv":[42.1272645151277203,-9.53169063144130568,-132.143420370999962],"rgb":[0.266666666666666663,0.266666666666666663,1],"xyz":[0.224989532527909486,0.12582463770588348,0.958539684064017794],"hpluv":[265.874320218178127,399.069452944254863,42.1272645151277203],"hsluv":[265.874320218178127,99.9999999999994458,42.1272645151277203]},"#bbcc00":{"lch":[78.3160688649495711,87.6272661942945916,93.3039767998847651],"luv":[78.3160688649495711,-5.05025027162958828,87.4816137990130471],"rgb":[0.733333333333333282,0.8,0],"xyz":[0.420849795081280953,0.537505738187513904,0.081579188330150737],"hpluv":[93.3039767998847651,164.876849582678972,78.3160688649495711],"hsluv":[93.3039767998847651,100.000000000002302,78.3160688649495711]},"#bbcc11":{"lch":[78.3397318378619332,86.5943586896397193,93.3754549086192],"luv":[78.3397318378619332,-5.09856582429126703,86.4441298377475249],"rgb":[0.733333333333333282,0.8,0.0666666666666666657],"xyz":[0.421861460580918057,0.537910404387368812,0.0869072932949063737],"hpluv":[93.3754549086192,163.146061131239662,78.3397318378619332],"hsluv":[93.3754549086192,98.7690619278293,78.3397318378619332]},"#bbcc22":{"lch":[78.3835653101130134,84.6929692802742125,93.5116381573829329],"luv":[78.3835653101130134,-5.18755307791811582,84.5339478468458481],"rgb":[0.733333333333333282,0.8,0.133333333333333331],"xyz":[0.423736818719395114,0.538660547642759613,0.0967841794908855663],"hpluv":[93.5116381573829329,159.95035726483485,78.3835653101130134],"hsluv":[93.5116381573829329,96.5043106774720343,78.3835653101130134]},"#bbcc33":{"lch":[78.4556479267243,81.5996211754986405,93.7468972468941644],"luv":[78.4556479267243,-5.33246113691784,81.4251990123951],"rgb":[0.733333333333333282,0.8,0.2],"xyz":[0.42682456945185282,0.53989564793574274,0.113046333348496703],"hpluv":[93.7468972468941644,154.72407311273281,78.4556479267243],"hsluv":[93.7468972468941644,92.8230308779070157,78.4556479267243]},"#bbcc44":{"lch":[78.5595248117047475,77.2136355312914873,94.1131309849175],"luv":[78.5595248117047475,-5.53822791342104281,77.0147618547127877],"rgb":[0.733333333333333282,0.8,0.266666666666666663],"xyz":[0.431282564696071735,0.541678846033430306,0.136525108301383341],"hpluv":[94.1131309849175,147.254264694427633,78.5595248117047475],"hsluv":[94.1131309849175,87.6101015600037556,78.5595248117047475]},"#bbcc55":{"lch":[78.6981007967589079,71.4912273296626921,94.6593076474989488],"luv":[78.6981007967589079,-5.80727962831129307,71.2549723768110823],"rgb":[0.733333333333333282,0.8,0.333333333333333315],"xyz":[0.43724497873543372,0.544063811649175,0.167927155575357256],"hpluv":[94.6593076474989488,137.398731222980217,78.6981007967589079],"hsluv":[94.6593076474989488,80.8199795518833639,78.6981007967589079]},"#bbcc66":{"lch":[78.8738041161037273,64.440755538040392,95.4673459440295176],"luv":[78.8738041161037273,-6.13981465986491681,64.1475927081912403],"rgb":[0.733333333333333282,0.8,0.4],"xyz":[0.444829974508941905,0.547097809958578374,0.207874799982501218],"hpluv":[95.4673459440295176,125.075317361724217,78.8738041161037273],"hsluv":[95.4673459440295176,72.4696955468646848,78.8738041161037273]},"#bbcc77":{"lch":[79.0886730863018244,56.1202023011108153,96.6860819525870454],"luv":[79.0886730863018244,-6.5340457953894715,55.7385266387743386],"rgb":[0.733333333333333282,0.8,0.466666666666666674],"xyz":[0.454143987529143811,0.550823415166659225,0.2569286018888991],"hpluv":[96.6860819525870454,110.256785788709905,79.0886730863018244],"hsluv":[96.6860819525870454,62.6323703341884,79.0886730863018244]},"#bbcc88":{"lch":[79.3444074564468451,46.6379090458556931,98.6154841820407],"luv":[79.3444074564468451,-6.9864776714612713,46.1116437563841473],"rgb":[0.733333333333333282,0.8,0.533333333333333326],"xyz":[0.465284404631087611,0.555279582007436767,0.315601465292471295],"hpluv":[98.6154841820407,92.9740665461038702,79.3444074564468451],"hsluv":[98.6154841820407,51.4293340198482483,79.3444074564468451]},"#bbcc99":{"lch":[79.6424016540563,36.1659853952486898,101.956116252097843],"luv":[79.6424016540563,-7.49223418159530397,35.3814206410296137],"rgb":[0.733333333333333282,0.8,0.6],"xyz":[0.478341368740160311,0.560502367651066,0.38436814293358923],"hpluv":[101.956116252097843,73.3480812445522616,79.6424016540563],"hsluv":[101.956116252097843,39.0205672484538439,79.6424016540563]},"#bbccaa":{"lch":[79.9837682606211899,25.01387761080953,108.762036830266098],"luv":[79.9837682606211899,-8.04542335958215382,23.6847046866463593],"rgb":[0.733333333333333282,0.8,0.66666666666666663],"xyz":[0.493399061705412867,0.566525444837167,0.463671992550587775],"hpluv":[108.762036830266098,51.7527419020047645,79.9837682606211899],"hsluv":[108.762036830266098,25.5939208298632828,79.9837682606211899]},"#bbccbb":{"lch":[80.3693561861161356,14.1229851396422195,127.715012949226079],"luv":[80.3693561861161356,-8.63951499109438892,11.1721748094634776],"rgb":[0.733333333333333282,0.8,0.733333333333333282],"xyz":[0.510536653812749486,0.573380481680101806,0.553929977649229577],"hpluv":[127.715012949226079,29.8960175179438359,80.3693561861161356],"hsluv":[127.715012949226079,11.3539027840963094,80.3693561861161356]},"#bbcccc":{"lch":[80.7997661027856537,9.48102181692548207,192.177050630058517],"luv":[80.7997661027856537,-9.26770319062559622,-1.99986306118322021],"rgb":[0.733333333333333282,0.8,0.8],"xyz":[0.52982902925647124,0.581097431857590663,0.655536488319499733],"hpluv":[192.177050630058517,20.5979746439306091,80.7997661027856537],"hsluv":[192.177050630058517,14.8313634310922779,80.7997661027856537]},"#bbccdd":{"lch":[81.2753646562375138,18.5534915910332536,237.666646406054781],"luv":[81.2753646562375138,-9.9232294288842251,-15.6767843616051454],"rgb":[0.733333333333333282,0.8,0.866666666666666696],"xyz":[0.551347354807104839,0.589704762077844169,0.76886633621950573],"hpluv":[237.666646406054781,41.5059211719903089,81.2753646562375138],"hsluv":[237.666646406054781,34.6395739712995834,81.2753646562375138]},"#bbccee":{"lch":[81.7962983545147466,31.5457627715974915,250.366116177600304],"luv":[81.7962983545147466,-10.5996485000078611,-29.7116576534899401],"rgb":[0.733333333333333282,0.8,0.933333333333333348],"xyz":[0.575159535073279549,0.599229634184314186,0.894277152288029],"hpluv":[250.366116177600304,72.9233806917818725,81.7962983545147466],"hsluv":[250.366116177600304,65.9765826509477478,81.7962983545147466]},"#bbccff":{"lch":[82.3625076456434329,45.3963265868234203,255.598148289110497],"luv":[82.3625076456434329,-11.2910283768039683,-43.9697526234994669],"rgb":[0.733333333333333282,0.8,1],"xyz":[0.601330583483111,0.60969805354824691,1.0321113405798108],"hpluv":[255.598148289110497,108.847942718229262,82.3625076456434329],"hsluv":[255.598148289110497,99.9999999999958789,82.3625076456434329]},"#99dd00":{"lch":[81.0072374435841738,100.100388992767378,110.059278565234735],"luv":[81.0072374435841738,-34.3336498242400623,94.028125400062109],"rgb":[0.6,0.866666666666666696,0],"xyz":[0.389918951048281226,0.584841851451462,0.0923421668915964389],"hpluv":[110.059278565234735,220.251619684458433,81.0072374435841738],"hsluv":[110.059278565234735,100.000000000002245,81.0072374435841738]},"#99dd11":{"lch":[81.0296061686003,99.1554895677318626,110.248463134872608],"luv":[81.0296061686003,-34.3169109383134483,93.0277417498051733],"rgb":[0.6,0.866666666666666696,0.0666666666666666657],"xyz":[0.39093061654791833,0.585246517651316855,0.0976702718563520755],"hpluv":[110.248463134872608,218.472914234601802,81.0296061686003],"hsluv":[110.248463134872608,98.8616036668283,81.0296061686003]},"#99dd22":{"lch":[81.0710445633976,97.4178442494470431,110.606606003803336],"luv":[81.0710445633976,-34.2861684396920552,91.184949591117217],"rgb":[0.6,0.866666666666666696,0.133333333333333331],"xyz":[0.392805974686395387,0.585996660906707656,0.107547158052331268],"hpluv":[110.606606003803336,215.192819254761019,81.0710445633976],"hsluv":[110.606606003803336,96.7659338960775131,81.0710445633976]},"#99dd33":{"lch":[81.1391953168863154,94.5961335984436857,111.218234049095599],"luv":[81.1391953168863154,-34.2363517117206513,88.1833358024404106],"rgb":[0.6,0.866666666666666696,0.2],"xyz":[0.395893725418853093,0.587231761199690783,0.123809311909942404],"hpluv":[111.218234049095599,209.840835623165077,81.1391953168863154],"hsluv":[111.218234049095599,93.3562182204636599,81.1391953168863154]},"#99dd44":{"lch":[81.2374208116197565,90.6080011845065343,112.152709421166279],"luv":[81.2374208116197565,-34.1661449288095653,83.9195115533635487],"rgb":[0.6,0.866666666666666696,0.266666666666666663],"xyz":[0.400351720663072,0.589014959297378349,0.147288086862829043],"hpluv":[112.152709421166279,202.22119953609328,81.2374208116197565],"hsluv":[112.152709421166279,88.5208972681928827,81.2374208116197565]},"#99dd55":{"lch":[81.3684846041416421,85.4315699411036604,113.506988965296216],"luv":[81.3684846041416421,-34.0753153837539244,78.3417259453695607],"rgb":[0.6,0.866666666666666696,0.333333333333333315],"xyz":[0.406314134702434,0.591399924913123098,0.178690134136802958],"hpluv":[113.506988965296216,192.231211336261111,81.3684846041416421],"hsluv":[113.506988965296216,82.2103932307851579,81.3684846041416421]},"#99dd66":{"lch":[81.5347071887187695,79.1067404569191837,115.426438711198742],"luv":[81.5347071887187695,-33.9646313013793,71.4442454385217758],"rgb":[0.6,0.866666666666666696,0.4],"xyz":[0.413899130475942179,0.594433923222526417,0.21863777854394692],"hpluv":[115.426438711198742,179.864586291563711,81.5347071887187695],"hsluv":[115.426438711198742,74.4308834765056,81.5347071887187695]},"#99dd77":{"lch":[81.7380487099571,71.7428264562351217,118.139890255285593],"luv":[81.7380487099571,-33.8357763954940651,63.2627329764024324],"rgb":[0.6,0.866666666666666696,0.466666666666666674],"xyz":[0.423213143496144084,0.598159528430607268,0.267691580450344802],"hpluv":[118.139890255285593,165.232292085670224,81.7380487099571],"hsluv":[118.139890255285593,65.2389156719347,81.7380487099571]},"#99dd88":{"lch":[81.9801580086414248,63.5371271244577898,122.023063704989269],"luv":[81.9801580086414248,-33.6912346765093815,53.8689820694792942],"rgb":[0.6,0.866666666666666696,0.533333333333333326],"xyz":[0.434353560598087884,0.60261569527138481,0.326364443853917],"hpluv":[122.023063704989269,148.614644251947254,81.9801580086414248],"hsluv":[122.023063704989269,54.7350081565161943,81.9801580086414248]},"#99dd99":{"lch":[82.2624042681600827,54.8181455895933,127.715012949238044],"luv":[82.2624042681600827,-33.5341421039979721,43.3646215160552],"rgb":[0.6,0.866666666666666696,0.6],"xyz":[0.447410524707160584,0.607838480915014,0.395131121495034932],"hpluv":[127.715012949238044,130.58293025992694,82.2624042681600827],"hsluv":[127.715012949238044,43.0558433261763724,82.2624042681600827]},"#99ddaa":{"lch":[82.5858991321833855,46.1452119261310898,136.311935434488049],"luv":[82.5858991321833855,-33.3681126370237138,31.8739649675161907],"rgb":[0.6,0.866666666666666696,0.66666666666666663],"xyz":[0.46246821767241314,0.61386155810111509,0.474434971112033477],"hpluv":[136.311935434488049,112.281381223378744,82.5858991321833855],"hsluv":[136.311935434488049,44.8180878493830122,82.5858991321833855]},"#99ddbb":{"lch":[82.9515135213076,38.5190468703316,149.523212457301526],"luv":[82.9515135213076,-33.1970516149390349,19.536446347119437],"rgb":[0.6,0.866666666666666696,0.733333333333333282],"xyz":[0.479605809779749814,0.620716594944049849,0.564692956210675279],"hpluv":[149.523212457301526,96.0401150933983416,82.9515135213076],"hsluv":[149.523212457301526,46.6955526922259807,82.9515135213076]},"#99ddcc":{"lch":[83.3598915829196585,33.6584009809739158,168.866706644517421],"luv":[83.3598915829196585,-33.0249710093605202,6.49917274942921],"rgb":[0.6,0.866666666666666696,0.8],"xyz":[0.498898185223471513,0.628433545121538706,0.666299466880945435],"hpluv":[168.866706644517421,86.2854242091523,83.3598915829196585],"hsluv":[168.866706644517421,48.6618587245334879,83.3598915829196585]},"#99dddd":{"lch":[83.811463234187741,33.6120761253887,192.17705063006062],"luv":[83.811463234187741,-32.85581988586,-7.08990557672323529],"rgb":[0.6,0.866666666666666696,0.866666666666666696],"xyz":[0.520416510774105112,0.637040875341792212,0.779629314780951432],"hpluv":[192.17705063006062,88.9162454401141,83.811463234187741],"hsluv":[192.17705063006062,50.6906605199231777,83.811463234187741]},"#99ddee":{"lch":[84.3064561843391402,38.9043785470910208,212.822778279485817],"luv":[84.3064561843391402,-32.6933403312743565,-21.0878203738277712],"rgb":[0.6,0.866666666666666696,0.933333333333333348],"xyz":[0.544228691040279822,0.646565747448262229,0.905040130849474656],"hpluv":[212.822778279485817,106.615167592423816,84.3064561843391402],"hsluv":[212.822778279485817,60.6575363344623781,84.3064561843391402]},"#99ddff":{"lch":[84.8449079615810575,48.055447414973429,227.378328123916845],"luv":[84.8449079615810575,-32.5409551013358396,-35.3611689193969099],"rgb":[0.6,0.866666666666666696,1],"xyz":[0.570399739450111243,0.657034166812195,1.04287431914125639],"hpluv":[227.378328123916845,137.001856984753886,84.8449079615810575],"hsluv":[227.378328123916845,99.999999999994813,84.8449079615810575]},"#445500":{"lch":[33.4053570608210535,38.7644311760376397,101.469350612776353],"luv":[33.4053570608210535,-7.7080633936099785,37.9903525006263791],"rgb":[0.266666666666666663,0.333333333333333315,0],"xyz":[0.0563220008404254485,0.0772588357738427239,0.0119452840524730177],"hpluv":[101.469350612776353,147.25044771073371,33.4053570608210535],"hsluv":[101.469350612776353,100.000000000002245,33.4053570608210535]},"#445511":{"lch":[33.4914653280992525,35.8039831739898275,102.524785035338],"luv":[33.4914653280992525,-7.76452054412734,34.9519303021045076],"rgb":[0.266666666666666663,0.333333333333333315,0.0666666666666666657],"xyz":[0.0573336663400625668,0.0776635019736975768,0.0172733890172286492],"hpluv":[102.524785035338,135.655223597469387,33.4914653280992525],"hsluv":[102.524785035338,91.5452633494882093,33.4914653280992525]},"#445522":{"lch":[33.6502992474903806,30.5965852313305291,104.897478349629381],"luv":[33.6502992474903806,-7.86608410210478493,29.5681543001366229],"rgb":[0.266666666666666663,0.333333333333333315,0.133333333333333331],"xyz":[0.0592090244785395889,0.0784136452290883912,0.0271502752132078452],"hpluv":[104.897478349629381,115.378092601865731,33.6502992474903806],"hsluv":[104.897478349629381,76.6558497494370243,33.6502992474903806]},"#445533":{"lch":[33.9096245159150911,22.79863905315759,110.61032755328398],"luv":[33.9096245159150911,-8.02535730567797501,21.3394372651287],"rgb":[0.266666666666666663,0.333333333333333315,0.2],"xyz":[0.0622967752109973294,0.0796487455220715,0.0434124290708189919],"hpluv":[110.61032755328398,85.3149751467856419,33.9096245159150911],"hsluv":[110.61032755328398,54.1403397653178331,33.9096245159150911]},"#445544":{"lch":[34.2793424585633204,13.4702363502677187,127.715012949235046],"luv":[34.2793424585633204,-8.24020614134090401,10.6558092175245633],"rgb":[0.266666666666666663,0.333333333333333315,0.266666666666666663],"xyz":[0.0667547704552162,0.081431943619759084,0.0668912040237056305],"hpluv":[127.715012949235046,49.8634197051089814,34.2793424585633204],"hsluv":[127.715012949235046,25.3893680776039865,34.2793424585633204]},"#445555":{"lch":[34.7654846399243738,8.70030094248716424,192.177050630060222],"luv":[34.7654846399243738,-8.50454817645784544,-1.83518304377262664],"rgb":[0.266666666666666663,0.333333333333333315,0.333333333333333315],"xyz":[0.0727171844945782,0.0838169092355039169,0.098293251297679532],"hpluv":[192.177050630060222,31.7559649298661668,34.7654846399243738],"hsluv":[192.177050630060222,31.6316627668381969,34.7654846399243738]},"#445566":{"lch":[35.3707740335649916,17.7582093223154978,240.254504050727519],"luv":[35.3707740335649916,-8.81070452432763318,-15.4183489427423961],"rgb":[0.266666666666666663,0.333333333333333315,0.4],"xyz":[0.0803021802680863733,0.0868509075449072354,0.138240895704823508],"hpluv":[240.254504050727519,63.7079944588343352,35.3707740335649916],"hsluv":[240.254504050727519,38.2083413049732812,35.3707740335649916]},"#445577":{"lch":[36.0950574442792913,30.8488081821149329,252.743594747999822],"luv":[36.0950574442792913,-9.15124765847803623,-29.4602042177260124],"rgb":[0.266666666666666663,0.333333333333333315,0.466666666666666674],"xyz":[0.0896161932882882928,0.0905765127529880448,0.187294697611221417],"hpluv":[252.743594747999822,108.450105614435046,36.0950574442792913],"hsluv":[252.743594747999822,44.7362415879762878,36.0950574442792913]},"#445588":{"lch":[36.935739068143242,44.5159055243500319,257.651563208142],"luv":[36.935739068143242,-9.5200062368872409,-43.4860359874579245],"rgb":[0.266666666666666663,0.333333333333333315,0.533333333333333326],"xyz":[0.100756610390232121,0.0950326795937656427,0.245967561014793584],"hpluv":[257.651563208142,152.935302017774575,36.935739068143242],"hsluv":[257.651563208142,50.9359550606187952,36.935739068143242]},"#445599":{"lch":[37.8882410462664865,58.0440865604997711,260.167284745959819],"luv":[37.8882410462664865,-9.91231220062277885,-57.1914508600732674],"rgb":[0.266666666666666663,0.333333333333333315,0.6],"xyz":[0.113813574499304834,0.1002554652373948,0.314734238655911491],"hpluv":[260.167284745959819,194.398479571090235,37.8882410462664865],"hsluv":[260.167284745959819,56.6374271499956805,37.8882410462664865]},"#4455aa":{"lch":[38.9464770503006932,71.1678309986128141,261.658277796723496],"luv":[38.9464770503006932,-10.3247958657557941,-70.4149043837850144],"rgb":[0.266666666666666663,0.333333333333333315,0.66666666666666663],"xyz":[0.128871267464557376,0.106278542423495909,0.394038088272910092],"hpluv":[261.658277796723496,231.875507383352442,38.9464770503006932],"hsluv":[261.658277796723496,61.7617646139185652,38.9464770503006932]},"#4455bb":{"lch":[40.1033117689144,83.7900384834958,262.625350778636744],"luv":[40.1033117689144,-10.7550224317659584,-83.0969316013408417],"rgb":[0.266666666666666663,0.333333333333333315,0.733333333333333282],"xyz":[0.146008859571894023,0.113133579266430667,0.484296073371551838],"hpluv":[262.625350778636744,265.125486140416797,40.1033117689144],"hsluv":[262.625350778636744,66.2950009745661,40.1033117689144]},"#4455cc":{"lch":[41.3509797710146,95.8983760986006075,263.292411358069444],"luv":[41.3509797710146,-11.2011488171863753,-95.24196975873555],"rgb":[0.266666666666666663,0.333333333333333315,0.8],"xyz":[0.165301235015615777,0.120850529443919469,0.585902584041821939],"hpluv":[263.292411358069444,294.28272942652967,41.3509797710146],"hsluv":[263.292411358069444,71.9850161095278906,41.3509797710146]},"#4455dd":{"lch":[42.6814446156526657,107.523441304607104,263.773623462042394],"luv":[42.6814446156526657,-11.661670844638417,-106.88917561239117],"rgb":[0.266666666666666663,0.333333333333333315,0.866666666666666696],"xyz":[0.186819560566249321,0.129457859664173,0.699232431941827937],"hpluv":[263.773623462042394,319.67109728436958,42.6814446156526657],"hsluv":[263.773623462042394,81.2732363837730247,42.6814446156526657]},"#4455ee":{"lch":[44.0866885883675,118.714724855013472,264.132858108854521],"luv":[44.0866885883675,-12.1352655753704255,-118.092850024109339],"rgb":[0.266666666666666663,0.333333333333333315,0.933333333333333348],"xyz":[0.21063174083242403,0.13898273177064302,0.82464324801035116],"hpluv":[264.132858108854521,341.693279595385377,44.0866885883675],"hsluv":[264.132858108854521,90.5684283810677186,44.0866885883675]},"#4455ff":{"lch":[45.5589321196955765,129.526958246416882,264.408404412275218],"luv":[45.5589321196955765,-12.6207071057408875,-128.910630534181024],"rgb":[0.266666666666666663,0.333333333333333315,1],"xyz":[0.236802789242255451,0.149451151134575744,0.962477436302133],"hpluv":[264.408404412275218,360.766296003954039,45.5589321196955765],"hsluv":[264.408404412275218,99.9999999999992752,45.5589321196955765]},"#bbdd00":{"lch":[83.0607051195576673,95.2176030862527796,99.223939245402],"luv":[83.0607051195576673,-15.2627740644400269,93.9863802119702427],"rgb":[0.733333333333333282,0.866666666666666696,0],"xyz":[0.463483785628456102,0.622773719281865423,0.0957905185125420555],"hpluv":[99.223939245402,239.164338292747971,83.0607051195576673],"hsluv":[99.223939245402,100.00000000000216,83.0607051195576673]},"#bbdd11":{"lch":[83.082156377860457,94.2793845093074765,99.3314951275217481],"luv":[83.082156377860457,-15.2870500651298524,93.0317604034238457],"rgb":[0.733333333333333282,0.866666666666666696,0.0666666666666666657],"xyz":[0.464495451128093206,0.623178385481720332,0.101118623477297692],"hpluv":[99.3314951275217481,237.15213625798873,83.082156377860457],"hsluv":[99.3314951275217481,98.93507934353417,83.082156377860457]},"#bbdd22":{"lch":[83.1218967422411765,92.5513012339483794,99.5354402549794486],"luv":[83.1218967422411765,-15.3318301742674485,91.2725497814347],"rgb":[0.733333333333333282,0.866666666666666696,0.133333333333333331],"xyz":[0.466370809266570263,0.623928528737111132,0.110995509673276885],"hpluv":[99.5354402549794486,233.433860498438293,83.1218967422411765],"hsluv":[99.5354402549794486,96.9737920722735538,83.1218967422411765]},"#bbdd33":{"lch":[83.1872593514570298,89.7372330308786,99.8847694763800718],"luv":[83.1872593514570298,-15.4049421957575614,88.4050832700449263],"rgb":[0.733333333333333282,0.866666666666666696,0.2],"xyz":[0.469458559999027969,0.625163629030094259,0.127257663530888021],"hpluv":[99.8847694763800718,227.34486653748678,83.1872593514570298],"hsluv":[99.8847694763800718,93.7802848880547373,83.1872593514570298]},"#bbdd44":{"lch":[83.2814760883348697,85.7419087717973,100.421139587323779],"luv":[83.2814760883348697,-15.5091702542505097,84.3275788686944452],"rgb":[0.733333333333333282,0.866666666666666696,0.266666666666666663],"xyz":[0.473916555243246884,0.626946827127781825,0.15073643848377466],"hpluv":[100.421139587323779,218.62539011377612,83.2814760883348697],"hsluv":[100.421139587323779,89.2463889616074511,83.2814760883348697]},"#bbdd55":{"lch":[83.4072088624658,80.5207963453540572,101.204557559233223],"luv":[83.4072088624658,-15.6461875861262687,78.9860459708531835],"rgb":[0.733333333333333282,0.866666666666666696,0.333333333333333315],"xyz":[0.479878969282608869,0.629331792743526575,0.182138485757748575],"hpluv":[101.204557559233223,207.093501481883948,83.4072088624658],"hsluv":[101.204557559233223,83.3201121340644448,83.4072088624658]},"#bbdd66":{"lch":[83.5666996797624364,74.0772937371066149,102.328486133362119],"luv":[83.5666996797624364,-15.816696660053216,72.3690372616455164],"rgb":[0.733333333333333282,0.866666666666666696,0.4],"xyz":[0.487463965056117055,0.632365791052929893,0.222086130164892537],"hpluv":[102.328486133362119,192.635686460640301,83.5666996797624364],"hsluv":[102.328486133362119,75.9999631534792854,83.5666996797624364]},"#bbdd77":{"lch":[83.7618505003220122,66.4632811318093388,103.948126608074304],"luv":[83.7618505003220122,-16.0205304866066705,64.5035684418593149],"rgb":[0.733333333333333282,0.866666666666666696,0.466666666666666674],"xyz":[0.49677797807631896,0.636091396261010744,0.271139932071290446],"hpluv":[103.948126608074304,175.207590447676779,83.7618505003220122],"hsluv":[103.948126608074304,67.3303268013154,83.7618505003220122]},"#bbdd88":{"lch":[83.9942706402616,57.7845188457632091,106.339844930601203],"luv":[83.9942706402616,-16.2567564016803381,55.4505950331715454],"rgb":[0.733333333333333282,0.866666666666666696,0.533333333333333326],"xyz":[0.50791839517826276,0.640547563101788286,0.329812795474862641],"hpluv":[106.339844930601203,154.850612540446264,83.9942706402616],"hsluv":[106.339844930601203,57.39610210967858,83.9942706402616]},"#bbdd99":{"lch":[84.2653073070245711,48.2191913160874819,110.040291826115165],"luv":[84.2653073070245711,-16.5237946272095257,45.2996095159246153],"rgb":[0.733333333333333282,0.866666666666666696,0.6],"xyz":[0.520975359287335515,0.6457703487454175,0.39857947311598052],"hpluv":[110.040291826115165,131.749772406416298,84.2653073070245711],"hsluv":[110.040291826115165,46.3161497548768466,84.2653073070245711]},"#bbddaa":{"lch":[84.5760668100806328,38.0784660246866622,116.212889721452115],"luv":[84.5760668100806328,-16.8195514991441222,34.1624393473425059],"rgb":[0.733333333333333282,0.866666666666666696,0.66666666666666663],"xyz":[0.536033052252588,0.651793425931518566,0.477883322732979121],"hpluv":[116.212889721452115,106.421399158629868,84.5760668100806328],"hsluv":[116.212889721452115,34.2356923349747433,84.5760668100806328]},"#bbddbb":{"lch":[84.9274305013996553,28.0212505683590543,127.715012949233824],"luv":[84.9274305013996553,-17.1415612181778,22.1665821095230058],"rgb":[0.733333333333333282,0.866666666666666696,0.733333333333333282],"xyz":[0.55317064435992469,0.658648462774453325,0.568141307831620868],"hpluv":[127.715012949233824,80.3800713533813109,84.9274305013996553],"hsluv":[127.715012949233824,21.3181094477761164,84.9274305013996553]},"#bbddcc":{"lch":[85.3200677868051,19.876471170849122,151.617083508593169],"luv":[85.3200677868051,-17.4871274790593141,9.44851727715650291],"rgb":[0.733333333333333282,0.866666666666666696,0.8],"xyz":[0.572463019803646445,0.666365412951942182,0.669747818501891],"hpluv":[151.617083508593169,58.7374284962306703,85.3200677868051],"hsluv":[151.617083508593169,24.0698773292010699,85.3200677868051]},"#bbdddd":{"lch":[85.7544476215988,18.2643967282432129,192.177050630059739],"luv":[85.7544476215988,-17.8534562098583329,-3.85256916996079246],"rgb":[0.733333333333333282,0.866666666666666696,0.866666666666666696],"xyz":[0.593981345354279933,0.674972743172195688,0.783077666401897],"hpluv":[192.177050630059739,55.8245506661868234,85.7544476215988],"hsluv":[192.177050630059739,26.9205986284609722,85.7544476215988]},"#bbddee":{"lch":[86.2308493598319359,25.3453434934362818,223.980933900351914],"luv":[86.2308493598319359,-18.2377721186398958,-17.6002870700688909],"rgb":[0.733333333333333282,0.866666666666666696,0.933333333333333348],"xyz":[0.617793525620454753,0.684497615278665705,0.908488482470420244],"hpluv":[223.980933900351914,80.4705047412629142,86.2308493598319359],"hsluv":[223.980933900351914,55.5800524236117397,86.2308493598319359]},"#bbddff":{"lch":[86.7493734858622076,36.743147173338194,239.520163688183],"luv":[86.7493734858622076,-18.6374141011141354,-31.6655279416778761],"rgb":[0.733333333333333282,0.866666666666666696,1],"xyz":[0.643964574030286063,0.694966034642598429,1.0463226707622022],"hpluv":[239.520163688183,121.752323062157373,86.7493734858622076],"hsluv":[239.520163688183,99.9999999999938325,86.7493734858622076]},"#99ee00":{"lch":[85.9664003491010646,109.204546268980621,112.979852313128234],"luv":[85.9664003491010646,-42.6342645949387915,100.538313136150634],"rgb":[0.6,0.933333333333333348,0],"xyz":[0.437097727388796042,0.679199404132492912,0.108068425671767623],"hpluv":[112.979852313128234,339.428934639809256,85.9664003491010646],"hsluv":[112.979852313128234,100.000000000002444,85.9664003491010646]},"#99ee11":{"lch":[85.9866468155118326,108.350123359521945,113.156064955940181],"luv":[85.9866468155118326,-42.6072764400583495,99.6211284135251702],"rgb":[0.6,0.933333333333333348,0.0666666666666666657],"xyz":[0.438109392888433147,0.67960407033234782,0.11339653063652326],"hpluv":[113.156064955940181,337.317445797395,85.9866468155118326],"hsluv":[113.156064955940181,99.0182391276988,85.9866468155118326]},"#99ee22":{"lch":[86.0241571186350455,106.77763062148405,113.488368653358094],"luv":[86.0241571186350455,-42.5576013317541353,97.9301433166804287],"rgb":[0.6,0.933333333333333348,0.133333333333333331],"xyz":[0.439984751026910204,0.680354213587738621,0.123273416832502453],"hpluv":[113.488368653358094,333.419677856626379,86.0241571186350455],"hsluv":[113.488368653358094,97.2091916908085238,86.0241571186350455]},"#99ee33":{"lch":[86.0858572784747906,104.220652596579697,114.05202992935186],"luv":[86.0858572784747906,-42.476800751453851,95.1717701084636],"rgb":[0.6,0.933333333333333348,0.2],"xyz":[0.443072501759367909,0.681589313880721748,0.139535570690113603],"hpluv":[114.05202992935186,327.048640581280779,86.0858572784747906],"hsluv":[114.05202992935186,94.2610252844147709,86.0858572784747906]},"#99ee44":{"lch":[86.1748066309051239,100.599171066032113,114.904029942881266],"luv":[86.1748066309051239,-42.3622716989010186,91.2448966007484756],"rgb":[0.6,0.933333333333333348,0.266666666666666663],"xyz":[0.447530497003586825,0.683372511978409314,0.163014345643000241],"hpluv":[114.904029942881266,317.953677409096201,86.1748066309051239],"hsluv":[114.904029942881266,90.0700159696272777,86.1748066309051239]},"#99ee55":{"lch":[86.2935317577421586,95.884762204841536,116.119599614249481],"luv":[86.2935317577421586,-42.2129155656731854,86.0927254913233355],"rgb":[0.6,0.933333333333333348,0.333333333333333315],"xyz":[0.45349291104294881,0.685757477594154063,0.194416392916974157],"hpluv":[116.119599614249481,305.984138616458665,86.2935317577421586],"hsluv":[116.119599614249481,84.5822993375075924,86.2935317577421586]},"#99ee66":{"lch":[86.4441689863048879,90.1009507230509143,117.805124209421223],"luv":[86.4441689863048879,-42.0290075887870955,79.6978283411745565],"rgb":[0.6,0.933333333333333348,0.4],"xyz":[0.461077906816457,0.688791475903557382,0.234364037324118091],"hpluv":[117.805124209421223,291.090686380889622,86.4441689863048879],"hsluv":[117.805124209421223,77.7887546135139587,86.4441689863048879]},"#99ee77":{"lch":[86.6285404402691199,83.3280712532883712,120.117619079442107],"luv":[86.6285404402691199,-41.8120893585486826,72.0785449510868261],"rgb":[0.6,0.933333333333333348,0.466666666666666674],"xyz":[0.470391919836658901,0.692517081111638233,0.283417839230516],"hpluv":[120.117619079442107,273.344218704658658,86.6285404402691199],"hsluv":[120.117619079442107,69.7211272565473,86.6285404402691199]},"#99ee88":{"lch":[86.8481992617441563,75.7142340291470646,123.296374810060541],"luv":[86.8481992617441563,-41.5648380664255939,63.2851441582641],"rgb":[0.6,0.933333333333333348,0.533333333333333326],"xyz":[0.481532336938602701,0.696973247952415775,0.342090702634088195],"hpluv":[123.296374810060541,252.981665625798911,86.8481992617441563],"hsluv":[123.296374810060541,60.4476982156994964,86.8481992617441563]},"#99ee99":{"lch":[87.1044587056640864,67.4980907628946483,127.715012949238613],"luv":[87.1044587056640864,-41.2908999939099388,53.3952604107227131],"rgb":[0.6,0.933333333333333348,0.6],"xyz":[0.4945893010476754,0.702196033596045,0.410857380275206074],"hpluv":[127.715012949238613,230.504268403717248,87.1044587056640864],"hsluv":[127.715012949238613,50.0680020008431583,87.1044587056640864]},"#99eeaa":{"lch":[87.3984122167822477,59.0554460818204134,133.961345837807],"luv":[87.3984122167822477,-40.9946911699179566,42.5085992218733182],"rgb":[0.6,0.933333333333333348,0.66666666666666663],"xyz":[0.509646994012928,0.708219110782146,0.490161229892204675],"hpluv":[133.961345837807,206.883546406693341,87.3984122167822477],"hsluv":[133.961345837807,51.4281429353489514,87.3984122167822477]},"#99eebb":{"lch":[87.7309483141988409,50.9899623050450046,142.923108379062683],"luv":[87.7309483141988409,-40.6811762109167603,30.7411476358032338],"rgb":[0.6,0.933333333333333348,0.733333333333333282],"xyz":[0.526784586120264575,0.715074147625080814,0.580419214990846477],"hpluv":[142.923108379062683,183.977628608542716,87.7309483141988409],"hsluv":[142.923108379062683,52.8887094272277523,87.7309483141988409]},"#99eecc":{"lch":[88.1027624984453581,44.2777406304916781,155.702396707036257],"luv":[88.1027624984453581,-40.3556400464907483,18.219237958245273],"rgb":[0.6,0.933333333333333348,0.8],"xyz":[0.546076961563986329,0.722791097802569671,0.682025725661116633],"hpluv":[155.702396707036257,165.259943503195302,88.1027624984453581],"hsluv":[155.702396707036257,54.4312604691531305,88.1027624984453581]},"#99eedd":{"lch":[88.514367527899708,40.3437945821223494,172.775068456479858],"luv":[88.514367527899708,-40.023467685182176,5.07383442158517628],"rgb":[0.6,0.933333333333333348,0.866666666666666696],"xyz":[0.567595287114619929,0.731398428022823177,0.795355573561122631],"hpluv":[172.775068456479858,156.503534311163719,88.514367527899708],"hsluv":[172.775068456479858,56.0368199873083199,88.514367527899708]},"#99eeee":{"lch":[88.9661029048661476,40.6035054290346196,192.177050630060762],"luv":[88.9661029048661476,-39.6899452486728,-8.56463071492281891],"rgb":[0.6,0.933333333333333348,0.933333333333333348],"xyz":[0.591407467380794638,0.740923300129293194,0.920766389629645854],"hpluv":[192.177050630060762,164.568757380081195,88.9661029048661476],"hsluv":[192.177050630060762,57.6866071933722324,88.9661029048661476]},"#99eeff":{"lch":[89.4581440962481338,45.3723498615675496,209.831659516829347],"luv":[89.4581440962481338,-39.3600920674606272,-22.5706287994267498],"rgb":[0.6,0.933333333333333348,1],"xyz":[0.617578515790626059,0.751391719493225918,1.05860057792142759],"hpluv":[209.831659516829347,193.255751503994162,89.4581440962481338],"hsluv":[209.831659516829347,99.9999999999917293,89.4581440962481338]},"#446600":{"lch":[39.1245088935371612,48.4489514943966242,110.29724752770484],"luv":[39.1245088935371612,-16.806485623906017,45.4405429311736668],"rgb":[0.266666666666666663,0.4,0],"xyz":[0.0713500585462719106,0.107314951185536064,0.0169546366210883669],"hpluv":[110.29724752770484,157.13568029472475,39.1245088935371612],"hsluv":[110.29724752770484,100.000000000002302,39.1245088935371612]},"#446611":{"lch":[39.1937103273453289,46.0071342898824156,111.370502443062165],"luv":[39.1937103273453289,-16.7648801632844737,42.843846683952],"rgb":[0.266666666666666663,0.4,0.0666666666666666657],"xyz":[0.0723617240459090288,0.107719617385390917,0.022282741585844],"hpluv":[111.370502443062165,148.9526145018813,39.1937103273453289],"hsluv":[111.370502443062165,93.861989786091,39.1937103273453289]},"#446622":{"lch":[39.3215343087732165,41.6757739733598,113.610346420587263],"luv":[39.3215343087732165,-16.6917518579939177,38.1871124358693947],"rgb":[0.266666666666666663,0.4,0.133333333333333331],"xyz":[0.0742370821843860579,0.108469760640781732,0.0321596277818231926],"hpluv":[113.610346420587263,134.490790122462073,39.3215343087732165],"hsluv":[113.610346420587263,82.9003633409612,39.3215343087732165]},"#446633":{"lch":[39.530716823468623,35.0960892868442684,118.194686061271412],"luv":[39.530716823468623,-16.5818151114938139,30.931842668007679],"rgb":[0.266666666666666663,0.4,0.2],"xyz":[0.0773248329168437915,0.109704860933764844,0.0484217816394343359],"hpluv":[118.194686061271412,112.658344014206364,39.530716823468623],"hsluv":[118.194686061271412,65.945418212904,39.530716823468623]},"#446644":{"lch":[39.8299759493166761,26.8801274380109838,127.715012949238059],"luv":[39.8299759493166761,-16.4434970133495142,21.2638815143349724],"rgb":[0.266666666666666663,0.4,0.266666666666666663],"xyz":[0.0817828281610626651,0.111488059031452424,0.0719005565923209744],"hpluv":[127.715012949238059,85.6368345314009,39.8299759493166761],"hsluv":[127.715012949238059,43.6044123282566858,39.8299759493166761]},"#446655":{"lch":[40.2252775564066809,18.9132283301115756,149.466153210293243],"luv":[40.2252775564066809,-16.2905155992652197,9.6088140463343148],"rgb":[0.266666666666666663,0.4,0.333333333333333315],"xyz":[0.087745242200424664,0.113873024647197257,0.10330260386629489],"hpluv":[149.466153210293243,59.6631175613842473,40.2252775564066809],"hsluv":[149.466153210293243,47.2452022491104273,40.2252775564066809]},"#446666":{"lch":[40.7202569602655728,16.510473073285187,192.177050630060847],"luv":[40.7202569602655728,-16.1389950297194247,-3.48260829470770128],"rgb":[0.266666666666666663,0.4,0.4],"xyz":[0.0953302379739328354,0.116907022956600576,0.143250248273438852],"hpluv":[192.177050630060847,51.4503500463259655,40.7202569602655728],"hsluv":[192.177050630060847,51.2489582821824214,40.7202569602655728]},"#446677":{"lch":[41.3164898648363632,23.6752994583974647,227.46784435344162],"luv":[41.3164898648363632,-16.0045942322577233,-17.4462823519963166],"rgb":[0.266666666666666663,0.4,0.466666666666666674],"xyz":[0.104644250994134755,0.120632628164681385,0.192304050179836761],"hpluv":[227.46784435344162,72.7128872034151783,41.3164898648363632],"hsluv":[227.46784435344162,55.4049423234493261,41.3164898648363632]},"#446688":{"lch":[42.0137303768536654,35.5424939627414,243.425378218088099],"luv":[42.0137303768536654,-15.9003964812462133,-31.7875175002811758],"rgb":[0.266666666666666663,0.4,0.533333333333333326],"xyz":[0.115784668096078583,0.125088795005458969,0.2509769135834089],"hpluv":[243.425378218088099,107.348500116853913,42.0137303768536654],"hsluv":[243.425378218088099,59.5313600522085409,42.0137303768536654]},"#446699":{"lch":[42.8101553746289696,48.7666560663799089,251.050944767945737],"luv":[42.8101553746289696,-15.8358652521886238,-46.1238779333558782],"rgb":[0.266666666666666663,0.4,0.6],"xyz":[0.128841632205151296,0.130311580649088155,0.319743591224526835],"hpluv":[251.050944767945737,144.549135771893674,42.8101553746289696],"hsluv":[251.050944767945737,63.4907652576423231,42.8101553746289696]},"#4466aa":{"lch":[43.7026231888915078,62.2363741998113298,255.27738032783347],"luv":[43.7026231888915078,-15.8167390859625119,-60.1929982491778404],"rgb":[0.266666666666666663,0.4,0.66666666666666663],"xyz":[0.143899325170403825,0.136334657835189249,0.399047440841525436],"hpluv":[255.27738032783347,180.707469421570693,43.7026231888915078],"hsluv":[255.27738032783347,67.1924648453768896,43.7026231888915078]},"#4466bb":{"lch":[44.6869405362706402,75.5191451090451409,257.888120209084718],"luv":[44.6869405362706402,-15.8455247037125186,-73.83807029483539],"rgb":[0.266666666666666663,0.4,0.733333333333333282],"xyz":[0.161036917277740499,0.143189694678124,0.489305425940167182],"hpluv":[257.888120209084718,214.444923406304468,44.6869405362706402],"hsluv":[257.888120209084718,70.5866413561882098,44.6869405362706402]},"#4466cc":{"lch":[45.7581261645645299,88.428992560325014,259.626929599743789],"luv":[45.7581261645645299,-15.9222446749778896,-86.983727499712],"rgb":[0.266666666666666663,0.4,0.8],"xyz":[0.180329292721462225,0.150906644855612809,0.590911936610437283],"hpluv":[259.626929599743789,245.225581131482073,45.7581261645645299],"hsluv":[259.626929599743789,73.6549291646736179,45.7581261645645299]},"#4466dd":{"lch":[46.9106590907269165,100.895184366494064,260.849495088158733],"luv":[46.9106590907269165,-16.0451985527389489,-99.6111933055317422],"rgb":[0.266666666666666663,0.4,0.866666666666666696],"xyz":[0.201847618272095769,0.159513975075866343,0.704241784510443281],"hpluv":[260.849495088158733,272.92180192815988,46.9106590907269165],"hsluv":[260.849495088158733,78.541907894368677,46.9106590907269165]},"#4466ee":{"lch":[48.1387014995781897,112.90717489320852,261.744736192665698],"luv":[48.1387014995781897,-16.2116120228509466,-111.737253313235385],"rgb":[0.266666666666666663,0.4,0.933333333333333348],"xyz":[0.225659798538270506,0.16903884718233636,0.829652600578966504],"hpluv":[261.744736192665698,297.623004098842955,48.1387014995781897],"hsluv":[261.744736192665698,89.2025828989012126,48.1387014995781897]},"#4466ff":{"lch":[49.4362898036433194,124.485902067172418,262.421323096893047],"luv":[49.4362898036433194,-16.4181334215125325,-123.398479360286501],"rgb":[0.266666666666666663,0.4,1],"xyz":[0.251830846948101872,0.179507266546269084,0.967486788870748349],"hpluv":[262.421323096893047,319.531462910383539,49.4362898036433194],"hsluv":[262.421323096893047,99.9999999999992,49.4362898036433194]},"#bbee00":{"lch":[87.830324097455545,103.474670767003104,103.901308289378321],"luv":[87.830324097455545,-24.8598111448325625,100.444000717728017],"rgb":[0.733333333333333282,0.933333333333333348,0],"xyz":[0.510662561968970863,0.717131271962896388,0.111516777292713254],"hpluv":[103.901308289378321,376.707439149390723,87.830324097455545],"hsluv":[103.901308289378321,100.000000000002331,87.830324097455545]},"#bbee11":{"lch":[87.8498503793181413,102.621932764236291,104.023160127863235],"luv":[87.8498503793181413,-24.8667401733108697,99.5635792718425705],"rgb":[0.733333333333333282,0.933333333333333348,0.0666666666666666657],"xyz":[0.511674227468608,0.717535938162751297,0.116844882257468891],"hpluv":[104.023160127863235,374.263941750279344,87.8498503793181413],"hsluv":[104.023160127863235,99.0733759990956315,87.8498503793181413]},"#bbee22":{"lch":[87.8860274909110757,101.050540606732312,104.253301125000391],"luv":[87.8860274909110757,-24.8795662288424886,97.9398741125263],"rgb":[0.733333333333333282,0.933333333333333348,0.133333333333333331],"xyz":[0.513549585607085,0.718286081418142097,0.126721768453448069],"hpluv":[104.253301125000391,369.744422226518111,87.8860274909110757],"hsluv":[104.253301125000391,97.3653524759520224,87.8860274909110757]},"#bbee33":{"lch":[87.9455377581158899,98.4895893313188111,104.644745385959411],"luv":[87.9455377581158899,-24.9006321902472507,95.2898615970127878],"rgb":[0.733333333333333282,0.933333333333333348,0.2],"xyz":[0.516637336339542785,0.719521181711125224,0.142983922311059219],"hpluv":[104.644745385959411,362.331462484484575,87.9455377581158899],"hsluv":[104.644745385959411,94.5802259429375454,87.9455377581158899]},"#bbee44":{"lch":[88.03133674845418,94.8494424101932339,105.239087045756335],"luv":[88.03133674845418,-24.9309340294718567,91.5142898892991781],"rgb":[0.733333333333333282,0.933333333333333348,0.266666666666666663],"xyz":[0.521095331583761645,0.72130437980881279,0.166462697263945858],"hpluv":[105.239087045756335,351.690778632920285,88.03133674845418],"hsluv":[105.239087045756335,90.61757843521751,88.03133674845418]},"#bbee55":{"lch":[88.145869167101,90.085489786575252,106.092871571181419],"luv":[88.145869167101,-24.9712578135623886,86.5553681367929499],"rgb":[0.733333333333333282,0.933333333333333348,0.333333333333333315],"xyz":[0.527057745623123575,0.72368934542455754,0.197864744537919773],"hpluv":[106.092871571181419,337.573290416608245,88.145869167101],"hsluv":[106.092871571181419,85.422816781051381,88.145869167101]},"#bbee66":{"lch":[88.2912067804751786,84.1961694748550116,107.288882190620882],"luv":[88.2912067804751786,-25.0222263001917433,80.3920589686599527],"rgb":[0.733333333333333282,0.933333333333333348,0.4],"xyz":[0.534642741396631815,0.726723343733960858,0.237812388945063735],"hpluv":[107.288882190620882,319.804166688067426,88.2912067804751786],"hsluv":[107.288882190620882,78.9823949944632631,88.2912067804751786]},"#bbee77":{"lch":[88.4691221578712828,77.2243366572971439,108.954917992899311],"luv":[88.4691221578712828,-25.0843250262429365,73.0368044901840534],"rgb":[0.733333333333333282,0.933333333333333348,0.466666666666666674],"xyz":[0.543956754416833665,0.730448948942041709,0.286866190851461644],"hpluv":[108.954917992899311,298.285685525501094,88.4691221578712828],"hsluv":[108.954917992899311,71.3203705839542,88.4691221578712828]},"#bbee88":{"lch":[88.6811325759484106,69.2626802552854599,111.298371855766348],"luv":[88.6811325759484106,-25.1579200624522237,64.5321465184381822],"rgb":[0.733333333333333282,0.933333333333333348,0.533333333333333326],"xyz":[0.555097171518777577,0.734905115782819252,0.34553905425503384],"hpluv":[111.298371855766348,273.019747479454225,88.6811325759484106],"hsluv":[111.298371855766348,62.4946759175697224,88.6811325759484106]},"#bbee99":{"lch":[88.9285282571087095,60.4678989000773228,114.674688063820184],"luv":[88.9285282571087095,-25.2432722518949362,54.9467378777547069],"rgb":[0.733333333333333282,0.933333333333333348,0.6],"xyz":[0.568154135627850221,0.740127901426448465,0.414305731896151719],"hpluv":[114.674688063820184,244.173567048365754,88.9285282571087095],"hsluv":[114.674688063820184,52.5925914284503548,88.9285282571087095]},"#bbeeaa":{"lch":[89.2123917942545148,51.0969811847688931,119.731125412935242],"luv":[89.2123917942545148,-25.3405499711494109,44.3706886734509212],"rgb":[0.733333333333333282,0.933333333333333348,0.66666666666666663],"xyz":[0.583211828593102832,0.746150978612549531,0.493609581513150319],"hpluv":[119.731125412935242,212.254877789093854,89.2123917942545148],"hsluv":[119.731125412935242,41.7253920748903084,89.2123917942545148]},"#bbeebb":{"lch":[89.5336124490095,41.6027669810227181,127.715012949236097],"luv":[89.5336124490095,-25.4498411950279184,32.9104208971130276],"rgb":[0.733333333333333282,0.933333333333333348,0.733333333333333282],"xyz":[0.600349420700439396,0.75300601545548429,0.583867566611792066],"hpluv":[127.715012949236097,178.587287563939924,89.5336124490095],"hsluv":[127.715012949236097,37.7465419844818,89.5336124490095]},"#bbeecc":{"lch":[89.8928974614309766,32.8889663829363883,141.03222670888556],"luv":[89.8928974614309766,-25.571165029146556,20.6833176446640721],"rgb":[0.733333333333333282,0.933333333333333348,0.8],"xyz":[0.61964179614416115,0.760722965632973147,0.685474077282062222],"hpluv":[141.03222670888556,146.627829178506289,89.8928974614309766],"hsluv":[141.03222670888556,37.1073685119788,89.8928974614309766]},"#bbeedd":{"lch":[90.290781675649967,26.8655052232995288,163.094148385079734],"luv":[90.290781675649967,-25.704482585445124,7.81248653872008436],"rgb":[0.733333333333333282,0.933333333333333348,0.866666666666666696],"xyz":[0.641160121694794749,0.769330295853226653,0.79880392518206822],"hpluv":[163.094148385079734,125.084011642469022,90.290781675649967],"hsluv":[163.094148385079734,36.2429238875219255,90.290781675649967]},"#bbeeee":{"lch":[90.7276363011350782,26.4447005646089579,192.177050630060336],"luv":[90.7276363011350782,-25.8497069757021904,-5.5780675168164624],"rgb":[0.733333333333333282,0.933333333333333348,0.933333333333333348],"xyz":[0.664972301960969459,0.77885516795969667,0.924214741250591443],"hpluv":[192.177050630060336,129.38009793870765,90.7276363011350782],"hsluv":[192.177050630060336,36.8413123479339077,90.7276363011350782]},"#bbeeff":{"lch":[91.2036773284388289,32.4261328799939648,216.675663960190036],"luv":[91.2036773284388289,-26.0067122100428421,-19.367627980086624],"rgb":[0.733333333333333282,0.933333333333333348,1],"xyz":[0.69114335037080088,0.789323587323629394,1.06204892954237318],"hpluv":[216.675663960190036,167.86892764061264,91.2036773284388289],"hsluv":[216.675663960190036,99.9999999999901235,91.2036773284388289]},"#99ff00":{"lch":[90.9122626200542214,118.290950299530564,115.261698016578393],"luv":[90.9122626200542214,-50.4810643573161286,106.978554225220847],"rgb":[0.6,1,0],"xyz":[0.48895009981846993,0.782904148991842,0.125352549814991721],"hpluv":[115.261698016578393,591.369219456757151,90.9122626200542214],"hsluv":[115.261698016578393,100.000000000002402,90.9122626200542214]},"#99ff11":{"lch":[90.9306796583728,117.513960007406183,115.422432906031332],"luv":[90.9306796583728,-50.4474247175277384,106.134764031356056],"rgb":[0.6,1,0.0666666666666666657],"xyz":[0.489961765318107034,0.783308815191696928,0.130680654779747357],"hpluv":[115.422432906031332,588.764777700997797,90.9306796583728],"hsluv":[115.422432906031332,99.9999999999905356,90.9306796583728]},"#99ff22":{"lch":[90.9648031673089577,116.082935310332914,115.724658723180369],"luv":[90.9648031673089577,-50.3854319755480944,104.577990585497247],"rgb":[0.6,1,0.133333333333333331],"xyz":[0.491837123456584091,0.784058958447087728,0.140557540975726536],"hpluv":[115.724658723180369,583.951350293788323,90.9648031673089577],"hsluv":[115.724658723180369,99.9999999999904219,90.9648031673089577]},"#99ff33":{"lch":[91.0209396556716399,113.753057852482627,116.234667099004312],"luv":[91.0209396556716399,-50.2843870930134642,102.035477092383132],"rgb":[0.6,1,0.2],"xyz":[0.494924874189041797,0.785294058740070855,0.156819694833337686],"hpluv":[116.234667099004312,576.067585056329449,91.0209396556716399],"hsluv":[116.234667099004312,99.9999999999905924,91.0209396556716399]},"#99ff44":{"lch":[91.1018839706868562,110.446777199697451,116.999375135233294],"luv":[91.1018839706868562,-50.1407143313292565,98.409345898362929],"rgb":[0.6,1,0.266666666666666663],"xyz":[0.499382869433260712,0.787077256837758421,0.180298469786224325],"hpluv":[116.999375135233294,564.777897061868,91.1018839706868562],"hsluv":[116.999375135233294,99.9999999999903793,91.1018839706868562]},"#99ff55":{"lch":[91.2099533036034558,106.130684884370282,118.07780645420398],"luv":[91.2099533036034558,-49.9525457622324112,93.6400846106921279],"rgb":[0.6,1,0.333333333333333315],"xyz":[0.505345283472622642,0.789462222453503171,0.21170051706019824],"hpluv":[118.07780645420398,549.854625367801646,91.2099533036034558],"hsluv":[118.07780645420398,99.9999999999901377,91.2099533036034558]},"#99ff66":{"lch":[91.3471179899501351,100.815112661229691,119.549522622156928],"luv":[91.3471179899501351,-49.7195590247369807,87.7020660605103899],"rgb":[0.6,1,0.4],"xyz":[0.512930279246130882,0.792496220762906489,0.251648161467342202],"hpluv":[119.549522622156928,531.176396965461777,91.3471179899501351],"hsluv":[119.549522622156928,99.9999999999902656,91.3471179899501351]},"#99ff77":{"lch":[91.5150716426202,94.5571579863012488,121.52621580287979],"luv":[91.5150716426202,-49.442863485124569,80.6006164792656534],"rgb":[0.6,1,0.466666666666666674],"xyz":[0.522244292266332732,0.79622182597098734,0.300701963373740111],"hpluv":[121.52621580287979,508.746904082031563,91.5150716426202],"hsluv":[121.52621580287979,99.9999999999900098,91.5150716426202]},"#99ff88":{"lch":[91.7152730008064481,87.4673964918121385,124.169042550433474],"luv":[91.7152730008064481,-49.1248751175299461,72.3691377159004077],"rgb":[0.6,1,0.533333333333333326],"xyz":[0.533384709368276644,0.800677992811764883,0.359374826777312251],"hpluv":[124.169042550433474,482.74240688111388,91.7152730008064481],"hsluv":[124.169042550433474,99.999999999989754,91.7152730008064481]},"#99ff99":{"lch":[91.9489728509177,79.7227767672504,127.715012949239039],"luv":[91.9489728509177,-48.7691602166467675,63.0657604984184559],"rgb":[0.6,1,0.6],"xyz":[0.546441673477349288,0.805900778455394096,0.428141504418430185],"hpluv":[127.715012949239039,453.611771943482722,91.9489728509177],"hsluv":[127.715012949239039,99.9999999999896119,91.9489728509177]},"#99ffaa":{"lch":[92.2172324754492365,71.5909188251234525,132.515331265000469],"luv":[92.2172324754492365,-48.380245540777544,52.769418223432119],"rgb":[0.6,1,0.66666666666666663],"xyz":[0.561499366442601899,0.811923855641495162,0.507445354035428786],"hpluv":[132.515331265000469,422.278899597361089,92.2172324754492365],"hsluv":[132.515331265000469,99.999999999989285,92.2172324754492365]},"#99ffbb":{"lch":[92.5209371039878334,63.4744472180726902,139.080731133451],"luv":[92.5209371039878334,-47.9634018094000325,41.5754439123617558],"rgb":[0.6,1,0.733333333333333282],"xyz":[0.578636958549938463,0.818778892484429921,0.597703339134070477],"hpluv":[139.080731133451,390.542311531215887,92.5209371039878334],"hsluv":[139.080731133451,99.9999999999889866,92.5209371039878334]},"#99ffcc":{"lch":[92.8608063839845,55.9838497302527216,148.091690615728766],"luv":[92.8608063839845,-47.524412431304512,29.5909049148346774],"rgb":[0.6,1,0.8],"xyz":[0.597929333993660217,0.826495842661918778,0.699309849804340633],"hpluv":[148.091690615728766,361.818313682118117,92.8608063839845],"hsluv":[148.091690615728766,99.999999999988475,92.8608063839845]},"#99ffdd":{"lch":[93.237403107538583,50.0214511206169306,160.217319691395858],"luv":[93.237403107538583,-47.0693412211659066,16.9299347080170577],"rgb":[0.6,1,0.866666666666666696],"xyz":[0.619447659544293816,0.835103172882172284,0.812639697704346631],"hpluv":[160.217319691395858,342.295010089686684,93.237403107538583],"hsluv":[160.217319691395858,99.999999999988,93.237403107538583]},"#99ffee":{"lch":[93.6511409780710267,46.7516947594382444,175.449324589633676],"luv":[93.6511409780710267,-46.6043124006013088,3.70931645277729727],"rgb":[0.6,1,0.933333333333333348],"xyz":[0.643259839810468526,0.844628044988642301,0.938050513772869854],"hpluv":[175.449324589633676,341.869484566500148,93.6511409780710267],"hsluv":[175.449324589633676,99.9999999999875,93.6511409780710267]},"#99ffff":{"lch":[94.102291921527609,47.1972299789563579,192.177050630060847],"luv":[94.102291921527609,-46.1353140316371437,-9.95546668362271703],"rgb":[0.6,1,1],"xyz":[0.6694308882203,0.855096464352575,1.07588470206465181],"hpluv":[192.177050630060847,372.830957625984183,94.102291921527609],"hsluv":[192.177050630060847,99.999999999986585,94.102291921527609]},"#447700":{"lch":[44.83248944102629,58.4741115144389809,115.479055163134589],"luv":[44.83248944102629,-25.1544589141716,52.7870714677211339],"rgb":[0.266666666666666663,0.466666666666666674,0],"xyz":[0.0898037965996895393,0.144222427292371835,0.0231058826388940708],"hpluv":[115.479055163134589,165.50461307776385,44.83248944102629],"hsluv":[115.479055163134589,100.00000000000216,44.83248944102629]},"#447711":{"lch":[44.8893318820142468,56.4264635629906337,116.3750363045054],"luv":[44.8893318820142468,-25.0671673404006405,50.5527735317644158],"rgb":[0.266666666666666663,0.466666666666666674,0.0666666666666666657],"xyz":[0.0908154620993266576,0.144627093492226688,0.0284339876036497],"hpluv":[116.3750363045054,159.506732057184706,44.8893318820142468],"hsluv":[116.3750363045054,95.4073228169634433,44.8893318820142468]},"#447722":{"lch":[44.9944227930058389,52.7636609180533824,118.171656995978211],"luv":[44.9944227930058389,-24.9105023189221484,46.5131248971114388],"rgb":[0.266666666666666663,0.466666666666666674,0.133333333333333331],"xyz":[0.0926908202378036866,0.145377236747617516,0.0383108737996289],"hpluv":[118.171656995978211,148.804327803607492,44.9944227930058389],"hsluv":[118.171656995978211,87.128369469673089,44.9944227930058389]},"#447733":{"lch":[45.1666686690004795,47.1090234718488,121.574089601592789],"luv":[45.1666686690004795,-24.6663168629185812,40.1351828809748881],"rgb":[0.266666666666666663,0.466666666666666674,0.2],"xyz":[0.0957785709702614202,0.146612337040600615,0.0545730276572400433],"hpluv":[121.574089601592789,132.350433634303585,45.1666686690004795],"hsluv":[121.574089601592789,74.1245535442141232,45.1666686690004795]},"#447744":{"lch":[45.4136534494367368,39.7908238780444137,127.715012949239082],"luv":[45.4136534494367368,-24.3414133770851677,31.4770592606648769],"rgb":[0.266666666666666663,0.466666666666666674,0.266666666666666663],"xyz":[0.100236566214480294,0.148395535138288209,0.0780518026101266749],"hpluv":[127.715012949239082,111.18234158710581,45.4136534494367368],"hsluv":[127.715012949239082,56.6116285441109,45.4136534494367368]},"#447755":{"lch":[45.7409133262359902,31.7219583115713704,139.030718806592802],"luv":[45.7409133262359902,-23.9520203549447466,20.798638417872084],"rgb":[0.266666666666666663,0.466666666666666674,0.333333333333333315],"xyz":[0.106198980253842293,0.150780500754033042,0.10945384988410059],"hpluv":[139.030718806592802,88.0023935360314766,45.7409133262359902],"hsluv":[139.030718806592802,58.7992252631310066,45.7409133262359902]},"#447766":{"lch":[46.1522822994750328,25.0075472636366349,160.141849635166039],"luv":[46.1522822994750328,-23.5205108300662609,8.49488024846472],"rgb":[0.266666666666666663,0.466666666666666674,0.4],"xyz":[0.113783976027350464,0.153814499063436333,0.149401494291244552],"hpluv":[160.141849635166039,68.7570511480334,46.1522822994750328],"hsluv":[160.141849635166039,61.2825519214888672,46.1522822994750328]},"#447777":{"lch":[46.650089933282672,23.6026970305602966,192.177050630060933],"luv":[46.650089933282672,-23.0716472128555,-4.97859438013953248],"rgb":[0.266666666666666663,0.466666666666666674,0.466666666666666674],"xyz":[0.123097989047552384,0.157540104271517156,0.198455296197642461],"hpluv":[192.177050630060933,64.2019875277067,46.650089933282672],"hsluv":[192.177050630060933,63.9506821134950414,46.650089933282672]},"#447788":{"lch":[47.2353114433284134,29.6592888392359697,220.273189901853613],"luv":[47.2353114433284134,-22.6291741496980734,-19.1727382434503575],"rgb":[0.266666666666666663,0.466666666666666674,0.533333333333333326],"xyz":[0.134238406149496226,0.161996271112294754,0.257128159601214601],"hpluv":[220.273189901853613,79.6770556088496,47.2353114433284134],"hsluv":[220.273189901853613,66.6958169909158585,47.2353114433284134]},"#447799":{"lch":[47.9077085122244526,40.3569508451274856,236.603980798736757],"luv":[47.9077085122244526,-22.2133832668581981,-33.6934576046404],"rgb":[0.266666666666666663,0.466666666666666674,0.6],"xyz":[0.147295370258568925,0.167219056755923912,0.325894837242332536],"hpluv":[236.603980798736757,106.893740352524901,47.9077085122244526],"hsluv":[236.603980798736757,69.4246608010291197,47.9077085122244526]},"#4477aa":{"lch":[48.6659751090485,52.9419227285019574,245.636459716194196],"luv":[48.6659751090485,-21.8398581964299439,-48.2272513849846476],"rgb":[0.266666666666666663,0.466666666666666674,0.66666666666666663],"xyz":[0.162353063223821481,0.173242133942025,0.405198686859331136],"hpluv":[245.636459716194196,138.042751347741245,48.6659751090485],"hsluv":[245.636459716194196,72.0643617009564,48.6659751090485]},"#4477bb":{"lch":[49.5078912458612,66.145388752002,251.014275727268966],"luv":[49.5078912458612,-21.5192486824625604,-62.5470573991759125],"rgb":[0.266666666666666663,0.466666666666666674,0.733333333333333282],"xyz":[0.1794906553311581,0.180097170784959765,0.495456671957972883],"hpluv":[251.014275727268966,169.536991245322184,49.5078912458612],"hsluv":[251.014275727268966,74.5637193650047578,49.5078912458612]},"#4477cc":{"lch":[50.4304819457797606,79.4031370336833,254.471410742848605],"luv":[50.4304819457797606,-21.2577420931439356,-76.5046833330565761],"rgb":[0.266666666666666663,0.466666666666666674,0.8],"xyz":[0.198783030774879854,0.187814120962448566,0.597063182628243094],"hpluv":[254.471410742848605,199.794656417231295,50.4304819457797606],"hsluv":[254.471410742848605,76.8911855438839638,50.4304819457797606]},"#4477dd":{"lch":[51.4301761714764183,92.4467030892661654,256.833353640671476],"luv":[51.4301761714764183,-21.0578873175855144,-90.0164334652001514],"rgb":[0.266666666666666663,0.466666666666666674,0.866666666666666696],"xyz":[0.220301356325513398,0.1964214511827021,0.710393030528249092],"hpluv":[256.833353640671476,228.093412194404408,51.4301761714764183],"hsluv":[256.833353640671476,79.0312420746427904,51.4301761714764183]},"#4477ee":{"lch":[52.5029598761355913,105.148975578657073,258.524369979875587],"luv":[52.5029598761355913,-20.9195063280493,-103.046985983248078],"rgb":[0.266666666666666663,0.466666666666666674,0.933333333333333348],"xyz":[0.244113536591688135,0.205946323289172145,0.835803846596772315],"hpluv":[258.524369979875587,254.132720010738154,52.5029598761355913],"hsluv":[258.524369979875587,87.6254974090696,52.5029598761355913]},"#4477ff":{"lch":[53.6445179522116,117.458222301342076,259.779939364455799],"luv":[53.6445179522116,-20.8405325230258285,-115.594576820663164],"rgb":[0.266666666666666663,0.466666666666666674,1],"xyz":[0.270284585001519528,0.216414742653104841,0.973638034888554],"hpluv":[259.779939364455799,277.841684308431127,53.6445179522116],"hsluv":[259.779939364455799,99.999999999999,53.6445179522116]},"#bbff00":{"lch":[92.6117448358007778,112.09772632761252,107.605046807390437],"luv":[92.6117448358007778,-33.9043888880720843,106.847520616749406],"rgb":[0.733333333333333282,1,0],"xyz":[0.56251493439864475,0.820836016822245496,0.128800901435937365],"hpluv":[107.605046807390437,698.685604225905081,92.6117448358007778],"hsluv":[107.605046807390437,100.000000000002302,92.6117448358007778]},"#bbff11":{"lch":[92.6295901709342,111.320425805292416,107.729052066712285],"luv":[92.6295901709342,-33.8988588935206678,106.033506813595423],"rgb":[0.733333333333333282,1,0.0666666666666666657],"xyz":[0.56352659989828191,0.821240683022100404,0.134129006400693],"hpluv":[107.729052066712285,695.618439183936061,92.6295901709342],"hsluv":[107.729052066712285,99.9999999999893703,92.6295901709342]},"#bbff22":{"lch":[92.6626551654141,109.887399193340656,107.962519071076329],"luv":[92.6626551654141,-33.888700280085942,104.531318248662245],"rgb":[0.733333333333333282,1,0.133333333333333331],"xyz":[0.565401958036758856,0.821990826277491204,0.14400589259667218],"hpluv":[107.962519071076329,689.937572971075,92.6626551654141],"hsluv":[107.962519071076329,99.9999999999891713,92.6626551654141]},"#bbff33":{"lch":[92.7170524122382318,107.550157892444602,108.357408717671873],"luv":[92.7170524122382318,-33.8722333827189388,102.076972272674624],"rgb":[0.733333333333333282,1,0.2],"xyz":[0.568489708769216673,0.823225926570474331,0.160268046454283331],"hpluv":[108.357408717671873,680.59767216104342,92.7170524122382318],"hsluv":[108.357408717671873,99.9999999999894271,92.7170524122382318]},"#bbff44":{"lch":[92.7954935084343475,104.224206838295117,108.951712424811362],"luv":[92.7954935084343475,-33.8490183743317,98.5744857768270464],"rgb":[0.733333333333333282,1,0.266666666666666663],"xyz":[0.572947704013435533,0.825009124668161897,0.183746821407169969],"hpluv":[108.951712424811362,667.142517523628385,92.7954935084343475],"hsluv":[108.951712424811362,99.9999999999890576,92.7954935084343475]},"#bbff55":{"lch":[92.9002292713318809,99.8647848732016,109.794505003516988],"luv":[92.9002292713318809,-33.8189779888925628,93.9640994505754605],"rgb":[0.733333333333333282,1,0.333333333333333315],"xyz":[0.578910118052797462,0.827394090283906647,0.215148868681143884],"hpluv":[109.794505003516988,649.201221057988732,92.9002292713318809],"hsluv":[109.794505003516988,99.9999999999888445,92.9002292713318809]},"#bbff66":{"lch":[93.0331768315467826,94.4651128464689691,110.953951756581517],"luv":[93.0331768315467826,-33.7823795150753,88.2179595059619146],"rgb":[0.733333333333333282,1,0.4],"xyz":[0.586495113826305703,0.83042808859331,0.255096513088287846],"hpluv":[110.953951756581517,626.470359589551208,93.0331768315467826],"hsluv":[110.953951756581517,99.9999999999888871,93.0331768315467826]},"#bbff77":{"lch":[93.1959878807374196,88.0576290523864742,112.529317332402641],"luv":[93.1959878807374196,-33.7398191848892566,81.3373876867131571],"rgb":[0.733333333333333282,1,0.466666666666666674],"xyz":[0.595809126846507553,0.834153693801390816,0.304150314994685755],"hpluv":[112.529317332402641,598.713569857690459,93.1959878807374196],"hsluv":[112.529317332402641,99.9999999999886455,93.1959878807374196]},"#bbff88":{"lch":[93.3900894470196334,80.7182094219550805,114.670873894576516],"luv":[93.3900894470196334,-33.6921989698203319,73.3502901212028888],"rgb":[0.733333333333333282,1,0.533333333333333326],"xyz":[0.606949543948451464,0.838609860642168359,0.362823178398257951],"hpluv":[114.670873894576516,565.785048639302204,93.3900894470196334],"hsluv":[114.670873894576516,99.9999999999880913,93.3900894470196334]},"#bbff99":{"lch":[93.6167101348934239,72.575742292483838,117.61482369288214],"luv":[93.6167101348934239,-33.6406927329059684,64.3081811417119411],"rgb":[0.733333333333333282,1,0.6],"xyz":[0.620006508057524108,0.843832646285797572,0.43158985603937583],"hpluv":[117.61482369288214,527.702623330867254,93.6167101348934239],"hsluv":[117.61482369288214,99.9999999999881,93.6167101348934239]},"#bbffaa":{"lch":[93.8768980816178384,63.8331941826517948,121.746607961207644],"luv":[93.8768980816178384,-33.5867019719833948,54.2826872050868303],"rgb":[0.733333333333333282,1,0.66666666666666663],"xyz":[0.63506420102277672,0.849855723471898639,0.510893705656374486],"hpluv":[121.746607961207644,484.836572610502856,93.8768980816178384],"hsluv":[121.746607961207644,99.9999999999878781,93.8768980816178384]},"#bbffbb":{"lch":[94.1715339943383,54.8143223318485937,127.715012949237362],"luv":[94.1715339943383,-33.5318032859449531,43.3615970772812602],"rgb":[0.733333333333333282,1,0.733333333333333282],"xyz":[0.652201793130113283,0.856710760314833397,0.601151690755016177],"hpluv":[127.715012949237362,438.38038704048256,94.1715339943383],"hsluv":[127.715012949237362,99.999999999986926,94.1715339943383]},"#bbffcc":{"lch":[94.5013412228876888,46.0666753200389323,136.612331153023604],"luv":[94.5013412228876888,-33.4776907719138919,31.6446329670924698],"rgb":[0.733333333333333282,1,0.8],"xyz":[0.671494168573835,0.864427710492322254,0.702758201425286333],"hpluv":[136.612331153023604,391.513584290668746,94.5013412228876888],"hsluv":[136.612331153023604,99.9999999999865707,94.5013412228876888]},"#bbffdd":{"lch":[94.8668940681869515,38.5674836948257322,150.076437256866],"luv":[94.8668940681869515,-33.4261169986321818,19.2391658068743077],"rgb":[0.733333333333333282,1,0.866666666666666696],"xyz":[0.693012494124468637,0.873035040712575761,0.816088049325292331],"hpluv":[150.076437256866,352.109825744613431,94.8668940681869515],"hsluv":[150.076437256866,99.9999999999853628,94.8668940681869515]},"#bbffee":{"lch":[95.2686250900245568,33.9600576278843675,169.384373669661102],"luv":[95.2686250900245568,-33.3788361105619771,6.25610214058809699],"rgb":[0.733333333333333282,1,0.933333333333333348],"xyz":[0.716824674390643346,0.882559912819045778,0.941498865393815554],"hpluv":[169.384373669661102,337.406400875084444,95.2686250900245568],"hsluv":[169.384373669661102,99.9999999999845,95.2686250900245568]},"#bbffff":{"lch":[95.7068319095003,34.1048965933827191,192.177050630060478],"luv":[95.7068319095003,-33.3375521201936849,-7.19385781613020914],"rgb":[0.733333333333333282,1,1],"xyz":[0.742995722800474767,0.893028332182978501,1.0793330536855974],"hpluv":[192.177050630060478,374.679972152143307,95.7068319095003],"hsluv":[192.177050630060478,99.9999999999829186,95.7068319095003]},"#448800":{"lch":[50.4956227619448157,68.4221216779621244,118.715311426014551],"luv":[50.4956227619448157,-32.873947818662586,60.0074186224478723],"rgb":[0.266666666666666663,0.533333333333333326,0],"xyz":[0.111876166324659992,0.18836716674231338,0.0304633392138840171],"hpluv":[118.715311426014551,171.942062028892252,50.4956227619448157],"hsluv":[118.715311426014551,100.000000000002373,50.4956227619448157]},"#448811":{"lch":[50.543205868460916,66.6756511812714763,119.435612575278299],"luv":[50.543205868460916,-32.7674265649617098,58.0683925794095899],"rgb":[0.266666666666666663,0.533333333333333326,0.0666666666666666657],"xyz":[0.112887831824297111,0.188771832942168233,0.0357914441786396503],"hpluv":[119.435612575278299,167.395510973175305,50.543205868460916],"hsluv":[119.435612575278299,96.4702491056824272,50.543205868460916]},"#448822":{"lch":[50.6312327062127565,63.5295563644356918,120.846986072134357],"luv":[50.6312327062127565,-32.5745953261955492,54.5426463530750425],"rgb":[0.266666666666666663,0.533333333333333326,0.133333333333333331],"xyz":[0.11476318996277414,0.189521976197559061,0.0456683303746188429],"hpluv":[120.846986072134357,159.219643782083125,50.6312327062127565],"hsluv":[120.846986072134357,90.0662104861249,50.6312327062127565]},"#448833":{"lch":[50.775662969350762,58.6076690216783831,123.408487274566809],"luv":[50.775662969350762,-32.2696404838739213,48.9237076599487182],"rgb":[0.266666666666666663,0.533333333333333326,0.2],"xyz":[0.117850940695231873,0.19075707649054216,0.0619304842322299931],"hpluv":[123.408487274566809,146.466455796741883,50.775662969350762],"hsluv":[123.408487274566809,79.8990388198805732,50.775662969350762]},"#448844":{"lch":[50.9830910358637652,52.0733509329185,127.715012949239537],"luv":[50.9830910358637652,-31.855056956676961,41.1933152789351382],"rgb":[0.266666666666666663,0.533333333333333326,0.266666666666666663],"xyz":[0.122308935939450747,0.192540274588229754,0.0854092591851166316],"hpluv":[127.715012949239537,129.607069016793787,50.9830910358637652],"hsluv":[127.715012949239537,65.9930987522981241,50.9830910358637652]},"#448855":{"lch":[51.2585265038955384,44.4350179761376651,134.860489600104756],"luv":[51.2585265038955384,-31.3437036744621551,31.4967151066136601],"rgb":[0.266666666666666663,0.533333333333333326,0.333333333333333315],"xyz":[0.128271349978812732,0.194925240203974587,0.116811306459090533],"hpluv":[134.860489600104756,110.001490313735033,51.2585265038955384],"hsluv":[134.860489600104756,67.3517725464548676,51.2585265038955384]},"#448866":{"lch":[51.6056896491522537,36.7437212642011914,146.829747927558799],"luv":[51.6056896491522537,-30.7562765884277063,20.1035445321824895],"rgb":[0.266666666666666663,0.533333333333333326,0.4],"xyz":[0.135856345752320917,0.197959238513377878,0.156758950866234509],"hpluv":[146.829747927558799,90.3493178961374781,51.6056896491522537],"hsluv":[146.829747927558799,68.9308752248562797,51.6056896491522537]},"#448877":{"lch":[52.0271709342862039,31.0045548915217921,166.266503182991642],"luv":[52.0271709342862039,-30.1181499011556575,7.36067052332227245],"rgb":[0.266666666666666663,0.533333333333333326,0.466666666666666674],"xyz":[0.145170358772522823,0.201684843721458701,0.205812752772632418],"hpluv":[166.266503182991642,75.6196418937204555,52.0271709342862039],"hsluv":[166.266503182991642,70.6726995402934506,52.0271709342862039]},"#448888":{"lch":[52.5245390493459041,30.1341009641634088,192.177050630061],"luv":[52.5245390493459041,-29.456097564679137,-6.35628485662009179],"rgb":[0.266666666666666663,0.533333333333333326,0.533333333333333326],"xyz":[0.156310775874466679,0.206141010562236299,0.264485616176204585],"hpluv":[192.177050630061,72.8006598676027181,52.5245390493459041],"hsluv":[192.177050630061,72.5156967272479847,52.5245390493459041]},"#448899":{"lch":[53.0984315279962118,35.4547108695225,215.690916113393854],"luv":[53.0984315279962118,-28.7954664423823949,-20.6847198484066084],"rgb":[0.266666666666666663,0.533333333333333326,0.6],"xyz":[0.169367739983539378,0.211363796205865456,0.333252293817322465],"hpluv":[215.690916113393854,84.7289026839812,53.0984315279962118],"hsluv":[215.690916113393854,74.4011420122721319,53.0984315279962118]},"#4488aa":{"lch":[53.7486427971268625,45.1587425535104146,231.425064236121358],"luv":[53.7486427971268625,-28.1581765792043193,-35.3048030832715654],"rgb":[0.266666666666666663,0.533333333333333326,0.66666666666666663],"xyz":[0.184425432948791934,0.217386873391966551,0.412556143434321065],"hpluv":[231.425064236121358,106.613859301848393,53.7486427971268625],"hsluv":[231.425064236121358,76.2778611087785,53.7486427971268625]},"#4488bb":{"lch":[54.4742155909258514,57.0545505189943469,241.113543257937238],"luv":[54.4742155909258514,-27.5616516575745152,-49.9557513488787208],"rgb":[0.266666666666666663,0.533333333333333326,0.733333333333333282],"xyz":[0.201563025056128553,0.224241910234901309,0.502814128532962812],"hpluv":[241.113543257937238,132.904176722924205,54.4742155909258514],"hsluv":[241.113543257937238,78.1047803623200707,54.4742155909258514]},"#4488cc":{"lch":[55.273536978614473,69.875332030770025,247.25266296501286],"luv":[55.273536978614473,-27.0185618464256976,-64.4403549195783398],"rgb":[0.266666666666666663,0.533333333333333326,0.8],"xyz":[0.220855400499850307,0.231958860412390111,0.604420639203233],"hpluv":[247.25266296501286,160.415361718249983,55.273536978614473],"hsluv":[247.25266296501286,79.8515774594708603,55.273536978614473]},"#4488dd":{"lch":[56.1444377207636194,82.97891177410213,251.348812353132246],"luv":[56.1444377207636194,-26.53714651812043,-78.6211145551246631],"rgb":[0.266666666666666663,0.533333333333333326,0.866666666666666696],"xyz":[0.242373726050483851,0.240566190632643645,0.717750487103239],"hpluv":[251.348812353132246,187.542769341675751,56.1444377207636194],"hsluv":[251.348812353132246,81.4979766670821,56.1444377207636194]},"#4488ee":{"lch":[57.0842924141545609,96.0325607902411775,254.216059778839536],"luv":[57.0842924141545609,-26.1218678035424112,-92.4115834426919776],"rgb":[0.266666666666666663,0.533333333333333326,0.933333333333333348],"xyz":[0.266185906316658616,0.25009106273911369,0.843161303171762189],"hpluv":[254.216059778839536,213.472145126724115,57.0842924141545609],"hsluv":[254.216059778839536,85.8050168900109469,57.0842924141545609]},"#4488ff":{"lch":[58.090117466996233,108.861046277687535,256.304473865935392],"luv":[58.090117466996233,-25.7741898685227575,-105.765866579412872],"rgb":[0.266666666666666663,0.533333333333333326,1],"xyz":[0.29235695472649,0.260559482103046358,0.980995491463544],"hpluv":[256.304473865935392,237.798754650411269,58.090117466996233],"hsluv":[256.304473865935392,99.9999999999988631,58.090117466996233]},"#449900":{"lch":[56.0984423000037538,78.159424491283,120.852962610827774],"luv":[56.0984423000037538,-40.0830169860907191,67.0987882610508279],"rgb":[0.266666666666666663,0.6,0],"xyz":[0.137745766777127493,0.240106367647249075,0.0390865393647062687],"hpluv":[120.852962610827774,176.794958777624345,56.0984423000037538],"hsluv":[120.852962610827774,100.000000000002416,56.0984423000037538]},"#449911":{"lch":[56.1389235634784143,76.6482268999804859,121.431666795625887],"luv":[56.1389235634784143,-39.9706170908808929,65.4010738159938256],"rgb":[0.266666666666666663,0.6,0.0666666666666666657],"xyz":[0.138757432276764625,0.240511033847103928,0.0444146443294619],"hpluv":[121.431666795625887,173.251641588156104,56.1389235634784143],"hsluv":[121.431666795625887,97.2234127009916,56.1389235634784143]},"#449922":{"lch":[56.21384509356389,73.9109075723002746,122.549403254372123],"luv":[56.21384509356389,-39.7660359546788555,62.3015621201611793],"rgb":[0.266666666666666663,0.6,0.133333333333333331],"xyz":[0.140632790415241626,0.241261177102494756,0.0542915305254411],"hpluv":[122.549403254372123,166.841685682494415,56.21384509356389],"hsluv":[122.549403254372123,92.1627352690631,56.21384509356389]},"#449933":{"lch":[56.3368647095541064,69.5846668696270143,124.526315047954697],"luv":[56.3368647095541064,-39.4395235157555177,57.3284383897480296],"rgb":[0.266666666666666663,0.6,0.2],"xyz":[0.143720541147699388,0.242496277395477855,0.0705536843830522342],"hpluv":[124.526315047954697,156.73291295139785,56.3368647095541064],"hsluv":[124.526315047954697,84.0665441712718859,56.3368647095541064]},"#449944":{"lch":[56.5137417426914368,63.7361451042890153,127.715012949239735],"luv":[56.5137417426914368,-38.9895886498958575,50.4193233757345922],"rgb":[0.266666666666666663,0.6,0.266666666666666663],"xyz":[0.148178536391918247,0.244279475493165449,0.0940324593359388727],"hpluv":[127.715012949239735,143.110354253444,56.5137417426914368],"hsluv":[127.715012949239735,72.8686777069245,56.5137417426914368]},"#449955":{"lch":[56.7489681974646629,56.6620380577650309,132.698160989074609],"luv":[56.7489681974646629,-38.4245724364924328,41.642992086692793],"rgb":[0.266666666666666663,0.6,0.333333333333333315],"xyz":[0.154140950431280233,0.246664441108910282,0.125434506609912788],"hpluv":[132.698160989074609,126.69910537289924,56.7489681974646629],"hsluv":[132.698160989074609,73.7405349232989664,56.7489681974646629]},"#449966":{"lch":[57.0460268500437166,48.9673458777373511,140.456743036678859],"luv":[57.0460268500437166,-37.7608817984154683,31.1755796757022061],"rgb":[0.266666666666666663,0.6,0.4],"xyz":[0.161725946204788418,0.249698439418313572,0.16538215101705675],"hpluv":[140.456743036678859,108.923224533285605,57.0460268500437166],"hsluv":[140.456743036678859,74.7718537787272766,57.0460268500437166]},"#449977":{"lch":[57.4075272841014481,41.7361359201695734,152.500832231763781],"luv":[57.4075272841014481,-37.0206846158697,19.2710651526888199],"rgb":[0.266666666666666663,0.6,0.466666666666666674],"xyz":[0.171039959224990323,0.253424044626394396,0.214435952923454659],"hpluv":[152.500832231763781,92.2534727828265915,57.4075272841014481],"hsluv":[152.500832231763781,75.9325502249844817,57.4075272841014481]},"#449988":{"lch":[57.8352917232380861,36.7607331244742284,170.245603374965924],"luv":[57.8352917232380861,-36.2292854489646174,6.22819200942437323],"rgb":[0.266666666666666663,0.6,0.533333333333333326],"xyz":[0.182180376326934179,0.257880211467172,0.273108816327026827],"hpluv":[170.245603374965924,80.6548633994409414,57.8352917232380861],"hsluv":[170.245603374965924,77.1878957355486222,57.8352917232380861]},"#449999":{"lch":[58.3304201548299517,36.2276744984656105,192.17705063006116],"luv":[58.3304201548299517,-35.4125684996312486,-7.64162232943372643],"rgb":[0.266666666666666663,0.6,0.6],"xyz":[0.195237340436006879,0.263102997110801151,0.341875493968144761],"hpluv":[192.17705063006116,78.8106081595615251,58.3304201548299517],"hsluv":[192.17705063006116,78.5021203184449803,58.3304201548299517]},"#4499aa":{"lch":[58.8933484328044585,41.0197173156303379,212.502133513081617],"luv":[58.8933484328044585,-34.5948579745346478,-22.041166266239177],"rgb":[0.266666666666666663,0.6,0.66666666666666663],"xyz":[0.210295033401259435,0.269126074296902273,0.421179343585143307],"hpluv":[212.502133513081617,88.3823902117899536,58.8933484328044585],"hsluv":[212.502133513081617,79.8414276244135692,58.8933484328044585]},"#4499bb":{"lch":[59.523905851944221,49.8962585520308082,227.36281958486083],"luv":[59.523905851944221,-33.7974051546762055,-36.7065664738854878],"rgb":[0.266666666666666663,0.6,0.733333333333333282],"xyz":[0.227432625508596054,0.275981111139837032,0.511437328683785108],"hpluv":[227.36281958486083,106.36919851968392,59.523905851944221],"hsluv":[227.36281958486083,81.1761313086710885,59.523905851944221]},"#4499cc":{"lch":[60.2213749252976385,61.1171242450200438,237.278146949597897],"luv":[60.2213749252976385,-33.0375484580145766,-51.4181219791773],"rgb":[0.266666666666666663,0.6,0.8],"xyz":[0.246725000952317808,0.283698061317325834,0.613043839354055264],"hpluv":[237.278146949597897,128.780934100622716,60.2213749252976385],"hsluv":[237.278146949597897,82.4818489079811741,60.2213749252976385]},"#4499dd":{"lch":[60.9845539619455508,73.4958381074912,243.904542785491344],"luv":[60.9845539619455508,-32.3284648877968195,-66.0038527445257728],"rgb":[0.266666666666666663,0.6,0.866666666666666696],"xyz":[0.268243326502951351,0.29230539153757934,0.726373687254061262],"hpluv":[243.904542785491344,152.926314240713424,60.9845539619455508],"hsluv":[243.904542785491344,83.7398679369964469,60.9845539619455508]},"#4499ee":{"lch":[61.8118218103912653,86.3580647779335351,248.479300934605874],"luv":[61.8118218103912653,-31.6793620640961606,-80.3376211460214193],"rgb":[0.266666666666666663,0.6,0.933333333333333348],"xyz":[0.292055506769126061,0.301830263644049357,0.851784503322584485],"hpluv":[248.479300934605874,177.284466220706,61.8118218103912653],"hsluv":[248.479300934605874,84.9368954206658344,61.8118218103912653]},"#4499ff":{"lch":[62.7012034705467585,99.3269113509348,251.755860244601337],"luv":[62.7012034705467585,-31.0959452870692914,-94.3338619225358173],"rgb":[0.266666666666666663,0.6,1],"xyz":[0.318226555178957482,0.312298683007982081,0.98961869161436633],"hpluv":[251.755860244601337,201.015886170810859,62.7012034705467585],"hsluv":[251.755860244601337,99.9999999999986073,62.7012034705467585]},"#330000":{"lch":[6.35863201887414942,21.3842798011123882,12.1770506300617836],"luv":[6.35863201887414942,20.9031433498234946,4.51065635013277699],"rgb":[0.2,0,0],"xyz":[0.0136521011456799905,0.00703936465324139522,0.000639942241203736136],"hpluv":[12.1770506300617836,426.746789183125031,6.35863201887414942],"hsluv":[12.1770506300617836,100.000000000002217,6.35863201887414942]},"#330011":{"lch":[6.72416549840036915,18.2596394021459751,358.956333183931122],"luv":[6.72416549840036915,18.2566101970553,-0.332588648601129133],"rgb":[0.2,0,0.0666666666666666657],"xyz":[0.0146637666453171122,0.00744403085309625,0.00596804720595936738],"hpluv":[358.956333183931122,344.582429927088697,6.72416549840036915],"hsluv":[358.956333183931122,99.9999999999970868,6.72416549840036915]},"#330022":{"lch":[7.4017671226143058,16.6083885778583671,334.642609555635659],"luv":[7.4017671226143058,15.0082373074967617,-7.11276205668364714],"rgb":[0.2,0,0.133333333333333331],"xyz":[0.0165391247837941326,0.00819417410848706854,0.0158449334019385643],"hpluv":[334.642609555635659,284.728805881674077,7.4017671226143058],"hsluv":[334.642609555635659,99.999999999998,7.4017671226143058]},"#330033":{"lch":[8.50665746950019,19.3767863388894384,307.715012949243601],"luv":[8.50665746950019,11.8534455994177517,-15.3282639670843448],"rgb":[0.2,0,0.2],"xyz":[0.0196268755162518696,0.00942927440147018139,0.0321070872595497075],"hpluv":[307.715012949243601,289.042783730483279,8.50665746950019],"hsluv":[307.715012949243601,99.9999999999987921,8.50665746950019]},"#330044":{"lch":[9.96321399083228343,25.9151774110163871,290.632214162589],"luv":[9.96321399083228343,9.13167627644372,-24.2530185467023678],"rgb":[0.2,0,0.266666666666666663],"xyz":[0.0240848707604707502,0.0112124724991577579,0.0555858622124363461],"hpluv":[290.632214162589,330.060881015257678,9.96321399083228343],"hsluv":[290.632214162589,99.9999999999994,9.96321399083228343]},"#330055":{"lch":[11.6870713271151807,34.2775786608295405,281.502617436257196],"luv":[11.6870713271151807,6.83538450996046,-33.589133919325],"rgb":[0.2,0,0.333333333333333315],"xyz":[0.0300472847998327422,0.0135974381149025891,0.0869879094864102614],"hpluv":[281.502617436257196,372.172061509357604,11.6870713271151807],"hsluv":[281.502617436257196,99.9999999999999289,11.6870713271151807]},"#330066":{"lch":[13.6097387714237676,43.4818398400869768,276.434806151814087],"luv":[13.6097387714237676,4.87312317733106592,-43.2079051375733059],"rgb":[0.2,0,0.4],"xyz":[0.0376322805733409205,0.0166314364243059024,0.126935553893554209],"hpluv":[276.434806151814087,405.412793254212261,13.6097387714237676],"hsluv":[276.434806151814087,100.00000000000027,13.6097387714237676]},"#330077":{"lch":[15.6735112457106673,53.108485659557914,273.408523183706109],"luv":[15.6735112457106673,3.15755804167271537,-53.0145364618510655],"rgb":[0.2,0,0.466666666666666674],"xyz":[0.046946293593542833,0.0203570416323867187,0.175989355799952119],"hpluv":[273.408523183706109,429.968801903614121,15.6735112457106673],"hsluv":[273.408523183706109,100.000000000000313,15.6735112457106673]},"#330088":{"lch":[17.8339183845063687,62.9511834901283365,271.47985970994057],"luv":[17.8339183845063687,1.62574911173865799,-62.9301870538574448],"rgb":[0.2,0,0.533333333333333326],"xyz":[0.058086710695486661,0.0248132084731643096,0.234662219203524286],"hpluv":[271.47985970994057,447.91587095992594,17.8339183845063687],"hsluv":[271.47985970994057,100.000000000000441,17.8339183845063687]},"#330099":{"lch":[20.0583065104412341,72.8932825114363,270.184356583024851],"luv":[20.0583065104412341,0.234543162084408924,-72.8929051746271313],"rgb":[0.2,0,0.6],"xyz":[0.0711436748045593814,0.0300359941167934706,0.303428896844642193],"hpluv":[270.184356583024851,461.139761646516433,20.0583065104412341],"hsluv":[270.184356583024851,100.000000000000625,20.0583065104412341]},"#3300aa":{"lch":[22.3232943619689834,82.8637729479105474,269.276671227287579],"luv":[22.3232943619689834,-1.04608331699459467,-82.8571697371855578],"rgb":[0.2,0,0.66666666666666663],"xyz":[0.0862013677698119235,0.0360590713028945756,0.382732746461640794],"hpluv":[269.276671227287579,471.026936966419044,22.3232943619689834],"hsluv":[269.276671227287579,100.000000000000554,22.3232943619689834]},"#3300bb":{"lch":[24.6123405885396807,92.8181896970849,268.61855571411644],"luv":[24.6123405885396807,-2.23769945956788,-92.7912120826788538],"rgb":[0.2,0,0.733333333333333282],"xyz":[0.10333895987714857,0.0429141081458293341,0.47299073156028254],"hpluv":[268.61855571411644,478.541387025058441,24.6123405885396807],"hsluv":[268.61855571411644,100.000000000000625,24.6123405885396807]},"#3300cc":{"lch":[26.9138017967000778,102.728605647013808,268.127719933063759],"luv":[26.9138017967000778,-3.35631165306985224,-102.673762910819349],"rgb":[0.2,0,0.8],"xyz":[0.122631335320870311,0.0506310583233181358,0.574597242230552752],"hpluv":[268.127719933063759,484.345947247320225,26.9138017967000778],"hsluv":[268.127719933063759,100.000000000000881,26.9138017967000778]},"#3300dd":{"lch":[29.2194977691074271,112.577730384171886,267.752877980499],"luv":[29.2194977691074271,-4.41413050162269105,-112.49115889867052],"rgb":[0.2,0,0.866666666666666696],"xyz":[0.144149660871503854,0.0592383885435716698,0.687927090130558749],"hpluv":[267.752877980499,488.89890937186334,29.2194977691074271],"hsluv":[267.752877980499,100.000000000000753,29.2194977691074271]},"#3300ee":{"lch":[31.5236887929336334,122.355215968494591,267.460804758990776],"luv":[31.5236887929336334,-5.42068013199621,-122.235081304851008],"rgb":[0.2,0,0.933333333333333348],"xyz":[0.167961841137678591,0.0687632606500417,0.813337906199082],"hpluv":[267.460804758990776,492.52103452607281,31.5236887929336334],"hsluv":[267.460804758990776,100.000000000000824,31.5236887929336334]},"#3300ff":{"lch":[33.8223579343154,132.055276159319874,267.229255072945307],"luv":[33.8223579343154,-6.38352242786170443,-131.900896899631505],"rgb":[0.2,0,1],"xyz":[0.194132889547509985,0.0792316800139744,0.951172094490863818],"hpluv":[267.229255072945307,495.440155164142311,33.8223579343154],"hsluv":[267.229255072945307,100.000000000000881,33.8223579343154]},"#331100":{"lch":[9.83576796362177319,19.9321083570360571,25.9770166386959609],"luv":[9.83576796362177319,17.918363864654,8.73047421223431108],"rgb":[0.2,0.0666666666666666657,0],"xyz":[0.0156565014066084,0.0110481651750982679,0.00130807566151318702],"hpluv":[25.9770166386959609,257.148675223584291,9.83576796362177319],"hsluv":[25.9770166386959609,100.000000000002302,9.83576796362177319]},"#331111":{"lch":[10.1474261289244687,16.4836545456174051,12.1770506300618813],"luv":[10.1474261289244687,16.1127799065782149,3.4769513746129066],"rgb":[0.2,0.0666666666666666657,0.0666666666666666657],"xyz":[0.0166681669062455212,0.0114528313749531225,0.00663618062626881826],"hpluv":[12.1770506300618813,206.127972902374523,10.1474261289244687],"hsluv":[12.1770506300618813,48.3021731216650707,10.1474261289244687]},"#331122":{"lch":[10.7062693823806221,14.2435433110065777,342.375847990242676],"luv":[10.7062693823806221,13.5749958919169824,-4.31254131423193],"rgb":[0.2,0.0666666666666666657,0.133333333333333331],"xyz":[0.0185435250447225398,0.0122029746303439404,0.0165130668222480161],"hpluv":[342.375847990242676,168.818174775843545,10.7062693823806221],"hsluv":[342.375847990242676,57.1044970617697913,10.7062693823806221]},"#331133":{"lch":[11.5784810016780177,17.5377888786733784,307.715012949244169],"luv":[11.5784810016780177,10.7284677021084427,-13.8735006223280077],"rgb":[0.2,0.0666666666666666657,0.2],"xyz":[0.0216312757771802804,0.0134380749233270532,0.0327752206798591628],"hpluv":[307.715012949244169,192.204068690519591,11.5784810016780177],"hsluv":[307.715012949244169,66.4967539441281,11.5784810016780177]},"#331144":{"lch":[12.7480449023252049,25.2894553184220108,288.641508688419037],"luv":[12.7480449023252049,8.08366941467993172,-23.9626968243691536],"rgb":[0.2,0.0666666666666666657,0.266666666666666663],"xyz":[0.0260892710213991574,0.0152212730210146297,0.0562539956327458],"hpluv":[288.641508688419037,251.73014018207067,12.7480449023252049],"hsluv":[288.641508688419037,74.5439781366083309,12.7480449023252049]},"#331155":{"lch":[14.1772863520069095,34.570642435857458,279.659572498507771],"luv":[14.1772863520069095,5.80074057604611415,-34.0805036230000695],"rgb":[0.2,0.0666666666666666657,0.333333333333333315],"xyz":[0.0320516850607611564,0.0176062386367594609,0.0876560429067197],"hpluv":[279.659572498507771,309.423764447612427,14.1772863520069095],"hsluv":[279.659572498507771,80.733364837348816,14.1772863520069095]},"#331166":{"lch":[15.8197098676790517,44.2946391552180785,274.993838621827194],"luv":[15.8197098676790517,3.85578699555013271,-44.1264995726595686],"rgb":[0.2,0.0666666666666666657,0.4],"xyz":[0.0396366808342693278,0.0206402369461627724,0.127603687313863678],"hpluv":[274.993838621827194,355.297359803625511,15.8197098676790517],"hsluv":[274.993838621827194,85.2848648605675095,15.8197098676790517]},"#331177":{"lch":[17.6293493428787755,54.1580116435351115,272.303494486185969],"luv":[17.6293493428787755,2.17675853502087469,-54.1142490242773135],"rgb":[0.2,0.0666666666666666657,0.466666666666666674],"xyz":[0.0489506938544712472,0.0243658421542435888,0.176657489220261588],"hpluv":[272.303494486185969,389.821469213037517,17.6293493428787755],"hsluv":[272.303494486185969,88.5936990192462588,17.6293493428787755]},"#331188":{"lch":[19.5658128626021437,64.0679547566568,270.623065923527406],"luv":[19.5658128626021437,0.696696562564985133,-64.064166587888522],"rgb":[0.2,0.0666666666666666657,0.533333333333333326],"xyz":[0.0600911109564150753,0.0288220089950211832,0.235330352623833755],"hpluv":[270.623065923527406,415.51077593183,19.5658128626021437],"hsluv":[270.623065923527406,91.0112456871911348,19.5658128626021437]},"#331199":{"lch":[21.5959931816331263,73.9854871429769645,269.508319412823],"luv":[21.5959931816331263,-0.634894604710849,-73.9827629696574576],"rgb":[0.2,0.0666666666666666657,0.6],"xyz":[0.0731480750654877887,0.0340447946386503442,0.304097030264951662],"hpluv":[269.508319412823,434.723064450461493,21.5959931816331263],"hsluv":[269.508319412823,92.7998436287799,21.5959931816331263]},"#3311aa":{"lch":[23.6938673935249824,83.8866252842298792,268.733700318675346],"luv":[23.6938673935249824,-1.85383566080119344,-83.8661385478044821],"rgb":[0.2,0.0666666666666666657,0.66666666666666663],"xyz":[0.0882057680307403308,0.0400678718247514457,0.383400879881950263],"hpluv":[268.733700318675346,449.258286440651602,23.6938673935249824],"hsluv":[268.733700318675346,94.1436997610677,23.6938673935249824]},"#3311bb":{"lch":[25.8394818705352094,93.7535423490500079,268.175268957576],"luv":[25.8394818705352094,-2.98531729009247,-93.7060007879569525],"rgb":[0.2,0.0666666666666666657,0.733333333333333282],"xyz":[0.105343360138076977,0.0469229086676862042,0.473658864980592],"hpluv":[268.175268957576,460.408371224539451,25.8394818705352094],"hsluv":[268.175268957576,95.1697562295976525,25.8394818705352094]},"#3311cc":{"lch":[28.017750605254669,103.572636018550753,267.760492630427507],"luv":[28.017750605254669,-4.04728980779695124,-103.493528189171812],"rgb":[0.2,0.0666666666666666657,0.8],"xyz":[0.124635735581798718,0.0546398588451750059,0.57526537565086211],"hpluv":[267.760492630427507,469.084508820223505,28.017750605254669],"hsluv":[267.760492630427507,95.9655004656031423,28.017750605254669]},"#3311dd":{"lch":[30.2173526676312889,113.33386550323506,267.444704079349265],"luv":[30.2173526676312889,-5.05282540459801588,-113.221173043455181],"rgb":[0.2,0.0666666666666666657,0.866666666666666696],"xyz":[0.146154061132432261,0.0632471890654285329,0.688595223550868107],"hpluv":[267.444704079349265,475.929488946899937,30.2173526676312889],"hsluv":[267.444704079349265,96.591763702558211,30.2173526676312889]},"#3311ee":{"lch":[32.429822932533412,123.030197380053124,267.199217974228532],"luv":[32.429822932533412,-6.01167404447580456,-122.883234180085807],"rgb":[0.2,0.0666666666666666657,0.933333333333333348],"xyz":[0.169966241398607,0.0727720611718985777,0.814006039619391331],"hpluv":[267.199217974228532,481.400425551936735,32.429822932533412],"hsluv":[267.199217974228532,97.0913881744298095,32.429822932533412]},"#3311ff":{"lch":[34.6488414224811834,132.657034918193688,267.004954598207064],"luv":[34.6488414224811834,-6.93127707868383425,-132.475832933200962],"rgb":[0.2,0.0666666666666666657,1],"xyz":[0.196137289808438392,0.0832404805358312738,0.951840227911173176],"hpluv":[267.004954598207064,485.826158631145177,34.6488414224811834],"hsluv":[267.004954598207064,99.999999999999531,34.6488414224811834]},"#88aa00":{"lch":[64.9493872277699467,75.8454165204624502,102.522158340464031],"luv":[64.9493872277699467,-16.4445883060260414,74.0412231301438624],"rgb":[0.533333333333333326,0.66666666666666663,0],"xyz":[0.245272120749672057,0.339833923051985953,0.0526729261635559762],"hpluv":[102.522158340464031,148.181371186867864,64.9493872277699467],"hsluv":[102.522158340464031,100.000000000002217,64.9493872277699467]},"#88aa11":{"lch":[64.9815053546997206,74.514883993558044,102.764001416735823],"luv":[64.9815053546997206,-16.4630035423646639,72.6734989589568414],"rgb":[0.533333333333333326,0.66666666666666663,0.0666666666666666657],"xyz":[0.246283786249309189,0.340238589251840806,0.0580010311283116059],"hpluv":[102.764001416735823,145.509915409181133,64.9815053546997206],"hsluv":[102.764001416735823,98.0498740713468635,64.9815053546997206]},"#88aa22":{"lch":[65.040976504183746,72.0784265262596762,103.230826782560158],"luv":[65.040976504183746,-16.4969246852166869,70.1651697527462801],"rgb":[0.533333333333333326,0.66666666666666663,0.133333333333333331],"xyz":[0.24815914438778619,0.340988732507231607,0.0678779173242908],"hpluv":[103.230826782560158,140.623392494363173,65.040976504183746],"hsluv":[103.230826782560158,94.4776072436414296,65.040976504183746]},"#88aa33":{"lch":[65.138705174337673,68.1506383708936596,104.056367163177015],"luv":[65.138705174337673,-16.5521781693680836,66.1100212389152],"rgb":[0.533333333333333326,0.66666666666666663,0.2],"xyz":[0.251246895120243952,0.342223832800214733,0.0841400711819019487],"hpluv":[104.056367163177015,132.760883332008575,65.138705174337673],"hsluv":[104.056367163177015,88.7139905695652544,65.138705174337673]},"#88aa44":{"lch":[65.2793887406011,62.6606585185119442,105.391240881396499],"luv":[65.2793887406011,-16.6306856640551395,60.4133960336360687],"rgb":[0.533333333333333326,0.66666666666666663,0.266666666666666663],"xyz":[0.255704890364462811,0.344007030897902299,0.107618846134788587],"hpluv":[105.391240881396499,121.803060858356815,65.2793887406011],"hsluv":[105.391240881396499,80.6421361820775,65.2793887406011]},"#88aa55":{"lch":[65.4667902277309821,55.6467221212728731,107.50018297907917],"luv":[65.4667902277309821,-16.7334615527701551,53.0711687011330397],"rgb":[0.533333333333333326,0.66666666666666663,0.333333333333333315],"xyz":[0.261667304403824796,0.34639199651364716,0.139020893408762503],"hpluv":[107.50018297907917,107.859366541167589,65.4667902277309821],"hsluv":[107.50018297907917,70.2829236383929157,65.4667902277309821]},"#88aa66":{"lch":[65.7039511656785606,47.2674293485405386,110.898270106627507],"luv":[65.7039511656785606,-16.8607549547505542,44.1579530727492582],"rgb":[0.533333333333333326,0.66666666666666663,0.4],"xyz":[0.269252300177333,0.349425994823050479,0.178968537815906464],"hpluv":[110.898270106627507,91.2871867148882075,65.7039511656785606],"hsluv":[110.898270106627507,57.7776943224234358,65.7039511656785606]},"#88aa77":{"lch":[65.993303036365262,37.8517489546572605,116.707912668539493],"luv":[65.993303036365262,-17.0121797895697142,33.8133204186420073],"rgb":[0.533333333333333326,0.66666666666666663,0.466666666666666674],"xyz":[0.278566313197534887,0.353151600031131274,0.228022339722304374],"hpluv":[116.707912668539493,72.782239014817236,65.993303036365262],"hsluv":[116.707912668539493,43.3670204896631262,65.993303036365262]},"#88aa88":{"lch":[66.3367341259492,28.0952907790087707,127.715012949235486],"luv":[66.3367341259492,-17.1868541575625393,22.2251526006848934],"rgb":[0.533333333333333326,0.66666666666666663,0.533333333333333326],"xyz":[0.289706730299478743,0.357607766871908872,0.286695203125876541],"hpluv":[127.715012949235486,53.7426121206727316,66.3367341259492],"hsluv":[127.715012949235486,27.3645684281827677,66.3367341259492]},"#88aa99":{"lch":[66.7356352778598705,19.8636867466165334,151.061783220075199],"luv":[66.7356352778598705,-17.3835461247401071,9.6113669837720046],"rgb":[0.533333333333333326,0.66666666666666663,0.6],"xyz":[0.302763694408551443,0.36283055251553803,0.35546188076699442],"hpluv":[151.061783220075199,37.7695130125235536,66.7356352778598705],"hsluv":[151.061783220075199,30.5390729913306274,66.7356352778598705]},"#88aaaa":{"lch":[67.1909358184889811,18.0059400546344968,192.177050630060364],"luv":[67.1909358184889811,-17.6008146924254447,-3.79805205519771905],"rgb":[0.533333333333333326,0.66666666666666663,0.66666666666666663],"xyz":[0.317821387373804,0.368853629701639152,0.434765730383993],"hpluv":[192.177050630060364,34.0051297749840913,67.1909358184889811],"hsluv":[192.177050630060364,33.872023720911649,67.1909358184889811]},"#88aabb":{"lch":[67.7031355134684674,25.1829477340388976,224.903065382651],"luv":[67.7031355134684674,-17.8371340556046292,-17.7768812016541453],"rgb":[0.533333333333333326,0.66666666666666663,0.733333333333333282],"xyz":[0.334958979481140617,0.37570866654457391,0.525023715482634823],"hpluv":[224.903065382651,47.1994684953027459,67.7031355134684674],"hsluv":[224.903065382651,37.296330310174362,67.7031355134684674]},"#88aacc":{"lch":[68.2723356589922901,36.8600300209604939,240.606662797769701],"luv":[68.2723356589922901,-18.0909926283411373,-32.1150712106857341],"rgb":[0.533333333333333326,0.66666666666666663,0.8],"xyz":[0.354251354924862372,0.383425616722062712,0.626630226152905],"hpluv":[240.606662797769701,68.5094136262693,68.2723356589922901],"hsluv":[240.606662797769701,40.7502319604911136,68.2723356589922901]},"#88aadd":{"lch":[68.8982708583434,50.1120766914241216,248.506358436024811],"luv":[68.8982708583434,-18.3609632112572676,-46.6271944285953168],"rgb":[0.533333333333333326,0.66666666666666663,0.866666666666666696],"xyz":[0.375769680475495915,0.392032946942316218,0.739960074052911],"hpluv":[248.506358436024811,92.2939864083951278,68.8982708583434],"hsluv":[248.506358436024811,59.5109742880650217,68.8982708583434]},"#88aaee":{"lch":[69.5803420919898,63.9362726255054454,253.044423586561948],"luv":[69.5803420919898,-18.6457452648911577,-61.1570367231747554],"rgb":[0.533333333333333326,0.66666666666666663,0.933333333333333348],"xyz":[0.39958186074167068,0.401557819048786235,0.8653708901214342],"hpluv":[253.044423586561948,116.600410917186778,69.5803420919898],"hsluv":[253.044423586561948,79.2673662112875093,69.5803420919898]},"#88aaff":{"lch":[70.3176511000829549,77.916964899147743,255.928474825822],"luv":[70.3176511000829549,-18.9441834980668631,-75.578907974954177],"rgb":[0.533333333333333326,0.66666666666666663,1],"xyz":[0.425752909151502046,0.412026238412718959,1.00320507841321604],"hpluv":[255.928474825822,140.607018245256825,70.3176511000829549],"hsluv":[255.928474825822,99.9999999999979394,70.3176511000829549]},"#332200":{"lch":[14.6681357538016819,18.4720509904151484,54.0318728094203635],"luv":[14.6681357538016819,10.8492842291989344,14.9502407842332925],"rgb":[0.2,0.133333333333333331,0],"xyz":[0.0193721251413763347,0.0184794126446342424,0.00254661690643579732],"hpluv":[54.0318728094203635,159.801011716648361,14.6681357538016819],"hsluv":[54.0318728094203635,100.000000000002359,14.6681357538016819]},"#332211":{"lch":[14.8903804788128475,14.003495227987683,44.8263438888978243],"luv":[14.8903804788128475,9.93193249146711,9.87190941941900668],"rgb":[0.2,0.133333333333333331,0.0666666666666666657],"xyz":[0.0203837906410134564,0.0188840788444890953,0.00787472187119143],"hpluv":[44.8263438888978243,119.33558852926538,14.8903804788128475],"hsluv":[44.8263438888978243,67.0844803779226595,14.8903804788128475]},"#332222":{"lch":[15.2941064614028619,8.70381909014442101,12.1770506300622809],"luv":[15.2941064614028619,8.50798716741232397,1.83592513820952408],"rgb":[0.2,0.133333333333333331,0.133333333333333331],"xyz":[0.0222591487794904751,0.0196342220998799166,0.0177516080671706253],"hpluv":[12.1770506300622809,72.2146104972558476,15.2941064614028619],"hsluv":[12.1770506300622809,16.9221215783466867,15.2941064614028619]},"#332233":{"lch":[15.9369990430381634,10.9638268591401484,307.7150129492465],"luv":[15.9369990430381634,6.70694938589646661,-8.67308072902737],"rgb":[0.2,0.133333333333333331,0.2],"xyz":[0.0253468995119482156,0.0208693223928630295,0.0340137619247817685],"hpluv":[307.7150129492465,87.2961214462547,15.9369990430381634],"hsluv":[307.7150129492465,30.2017993044426838,15.9369990430381634]},"#332244":{"lch":[16.8218835175385664,20.7382675483863608,283.478697838556343],"luv":[16.8218835175385664,4.83375477674434428,-20.1670661145035197],"rgb":[0.2,0.133333333333333331,0.266666666666666663],"xyz":[0.0298048947561670927,0.0226525204905506025,0.057492536877668407],"hpluv":[283.478697838556343,156.436171283708973,16.8218835175385664],"hsluv":[283.478697838556343,43.2894908809756558,16.8218835175385664]},"#332255":{"lch":[17.9355503164319856,31.8518286021958055,275.537546938931484],"luv":[17.9355503164319856,3.0736387963894658,-31.7031816992078603],"rgb":[0.2,0.133333333333333331,0.333333333333333315],"xyz":[0.0357673087955290847,0.0250374861062954354,0.0888945841516423224],"hpluv":[275.537546938931484,225.350740722061715,17.9355503164319856],"hsluv":[275.537546938931484,54.6600619512456092,17.9355503164319856]},"#332266":{"lch":[19.2543827660255502,42.9346801988288,271.988815040461645],"luv":[19.2543827660255502,1.49002234071320738,-42.9088172430781114],"rgb":[0.2,0.133333333333333331,0.4],"xyz":[0.043352304569037263,0.028071484415698747,0.12884222855878627],"hpluv":[271.988815040461645,282.955381276792764,19.2543827660255502],"hsluv":[271.988815040461645,63.8744485302889515,19.2543827660255502]},"#332277":{"lch":[20.7496984269819,53.7295137018198687,270.083996688769219],"luv":[20.7496984269819,0.0787684479011579453,-53.7294559637975908],"rgb":[0.2,0.133333333333333331,0.466666666666666674],"xyz":[0.0526663175892391755,0.0317970896237795633,0.17789603046518418],"hpluv":[270.083996688769219,328.579487011522247,20.7496984269819],"hsluv":[270.083996688769219,71.0892762838988546,20.7496984269819]},"#332288":{"lch":[22.3919640579388926,64.2366699579867,268.940142222195846],"luv":[22.3919640579388926,-1.18818265954209568,-64.2256801385464087],"rgb":[0.2,0.133333333333333331,0.533333333333333326],"xyz":[0.063806734691183,0.0362532564645571542,0.236568893868756347],"hpluv":[268.940142222195846,364.024117005976393,22.3919640579388926],"hsluv":[268.940142222195846,76.6637840765232426,22.3919640579388926]},"#332299":{"lch":[24.1535324867621668,74.5121507797046689,268.199285594367666],"luv":[24.1535324867621668,-2.34141182983712737,-74.4753543426316469],"rgb":[0.2,0.133333333333333331,0.6],"xyz":[0.076863698800255717,0.0414760421081863187,0.305335571509874282],"hpluv":[268.199285594367666,391.458538227207669,24.1535324867621668],"hsluv":[268.199285594367666,80.9654036049547301,24.1535324867621668]},"#3322aa":{"lch":[26.0100477302332607,84.6098540849434926,267.692459882235937],"luv":[26.0100477302332607,-3.40667075751279169,-84.541244387726735],"rgb":[0.2,0.133333333333333331,0.66666666666666663],"xyz":[0.0919213917655082591,0.0474991192942874202,0.384639421126872882],"hpluv":[267.692459882235937,412.780453116303818,26.0100477302332607],"hsluv":[267.692459882235937,84.3023702715129,26.0100477302332607]},"#3322bb":{"lch":[27.9408960039881222,94.5690254119923281,267.330995248517297],"luv":[27.9408960039881222,-4.40370835341661504,-94.4664380619492761],"rgb":[0.2,0.133333333333333331,0.733333333333333282],"xyz":[0.109058983872844906,0.0543541561372221788,0.474897406225514629],"hpluv":[267.330995248517297,429.484911570580266,27.9408960039881222],"hsluv":[267.330995248517297,86.9134730370406743,27.9408960039881222]},"#3322cc":{"lch":[29.9290875828623939,104.415306333233346,267.064581258752071],"luv":[29.9290875828623939,-5.34714045276937444,-104.278302084572317],"rgb":[0.2,0.133333333333333331,0.8],"xyz":[0.12835135931656666,0.0620711063147109804,0.576503916895784729],"hpluv":[267.064581258752071,442.700503900749,29.9290875828623939],"hsluv":[267.064581258752071,88.9774620844202389,29.9290875828623939]},"#3322dd":{"lch":[31.9608605817263296,114.164622106097937,266.862904678446171],"luv":[31.9608605817263296,-6.2476920173399213,-113.993540541052639],"rgb":[0.2,0.133333333333333331,0.866666666666666696],"xyz":[0.149869684867200204,0.0706784365349645144,0.689833764795790727],"hpluv":[266.862904678446171,453.265229710644405,31.9608605817263296],"hsluv":[266.862904678446171,90.6264253960307826,31.9608605817263296]},"#3322ee":{"lch":[34.0251904593745635,123.826689560879501,266.706806867468629],"luv":[34.0251904593745635,-7.11327635006579229,-123.622208147136817],"rgb":[0.2,0.133333333333333331,0.933333333333333348],"xyz":[0.173681865133374941,0.0802033086414345453,0.815244580864314],"hpluv":[266.706806867468629,461.799038215803307,34.0251904593745635],"hsluv":[266.706806867468629,93.6430785136650741,34.0251904593745635]},"#3322ff":{"lch":[36.1133053940478774,133.407509730883817,266.583697157343806],"luv":[36.1133053940478774,-7.94980801741223875,-133.170432923686747],"rgb":[0.2,0.133333333333333331,1],"xyz":[0.199852913543206334,0.0906717280053672414,0.953078769156095795],"hpluv":[266.583697157343806,468.761962088723578,36.1133053940478774],"hsluv":[266.583697157343806,99.999999999999531,36.1133053940478774]},"#aaaa00":{"lch":[67.4983691984715506,74.4102446110960472,85.8743202181747449],"luv":[67.4983691984715506,5.35340686476390193,74.217420717938225],"rgb":[0.66666666666666663,0.66666666666666663,0],"xyz":[0.309512896760441802,0.372958073182539818,0.0556842125390607443],"hpluv":[85.8743202181747449,139.887458074797593,67.4983691984715506],"hsluv":[85.8743202181747449,100.000000000002373,67.4983691984715506]},"#aaaa11":{"lch":[67.528557359020084,73.1276023311446863,85.8743202181746881],"luv":[67.528557359020084,5.26112782412359792,72.9381022286724345],"rgb":[0.66666666666666663,0.66666666666666663,0.0666666666666666657],"xyz":[0.310524562260078907,0.373362739382394671,0.061012317503816374],"hpluv":[85.8743202181746881,137.414698385368666,67.528557359020084],"hsluv":[85.8743202181746881,98.2323220941626118,67.528557359020084]},"#aaaa22":{"lch":[67.5844605157977,70.7729399531690575,85.8743202181746],"luv":[67.5844605157977,5.09172284764045369,70.589541633712912],"rgb":[0.66666666666666663,0.66666666666666663,0.133333333333333331],"xyz":[0.312399920398555964,0.374112882637785471,0.0708892036997955666],"hpluv":[85.8743202181746,132.880028295953878,67.5844605157977],"hsluv":[85.8743202181746,94.9906661574379854,67.5844605157977]},"#aaaa33":{"lch":[67.6763416895574181,66.9597491826677924,85.8743202181744607],"luv":[67.6763416895574181,4.81738479440415723,66.7862322215321882],"rgb":[0.66666666666666663,0.66666666666666663,0.2],"xyz":[0.315487671131013669,0.375347982930768598,0.0871513575574067167],"hpluv":[85.8743202181744607,125.549870841925909,67.6763416895574181],"hsluv":[85.8743202181744607,89.7506270896691376,67.6763416895574181]},"#aaaa44":{"lch":[67.8086418759902898,61.5895608625658824,85.8743202181741623],"luv":[67.8086418759902898,4.43102935143870269,61.429960004304057],"rgb":[0.66666666666666663,0.66666666666666663,0.266666666666666663],"xyz":[0.319945666375232585,0.377131181028456164,0.110630132510293355],"hpluv":[85.8743202181741623,115.255428047766188,67.8086418759902898],"hsluv":[85.8743202181741623,82.3915379076671854,67.8086418759902898]},"#aaaa55":{"lch":[67.9849384953625844,54.6449851984581514,85.8743202181737786],"luv":[67.9849384953625844,3.93140541890911,54.5033802508787772],"rgb":[0.66666666666666663,0.66666666666666663,0.333333333333333315],"xyz":[0.32590808041459457,0.379516146644201,0.142032179784267271],"hpluv":[85.8743202181737786,101.994541545207838,67.9849384953625844],"hsluv":[85.8743202181737786,72.9118556794948631,67.9849384953625844]},"#aaaa66":{"lch":[68.2081473948541515,46.1798212544818156,85.8743202181731675],"luv":[68.2081473948541515,3.32238354287766668,46.0601526125338268],"rgb":[0.66666666666666663,0.66666666666666663,0.4],"xyz":[0.333493076188102755,0.382550144953604343,0.181979824191411232],"hpluv":[85.8743202181731675,85.9122949373369806,68.2081473948541515],"hsluv":[85.8743202181731675,61.415294923296095,68.2081473948541515]},"#aaaa77":{"lch":[68.4806287458147551,36.3079853189649668,85.874320218171988],"luv":[68.4806287458147551,2.61215937225179973,36.2138981792368284],"rgb":[0.66666666666666663,0.66666666666666663,0.466666666666666674],"xyz":[0.342807089208304661,0.386275750161685139,0.231033626097809142],"hpluv":[85.874320218171988,67.2781031791916604,68.4806287458147551],"hsluv":[85.874320218171988,48.0944497134402909,68.4806287458147551]},"#aaaa88":{"lch":[68.804250183835336,25.1900382005990835,85.8743202181696574],"luv":[68.804250183835336,1.81228437202058101,25.1247616884732103],"rgb":[0.66666666666666663,0.66666666666666663,0.533333333333333326],"xyz":[0.353947506310248461,0.390731917002462736,0.289706489501381281],"hpluv":[85.8743202181696574,46.4571845078746506,68.804250183835336],"hsluv":[85.8743202181696574,33.210400093935057,68.804250183835336]},"#aaaa99":{"lch":[69.1804292601881485,13.0180161266067085,85.8743202181625236],"luv":[69.1804292601881485,0.936574490007753058,12.9842817320504498],"rgb":[0.66666666666666663,0.66666666666666663,0.6],"xyz":[0.36700447041932116,0.395954702646091894,0.358473167142499216],"hpluv":[85.8743202181625236,23.8781611725121081,69.1804292601881485],"hsluv":[85.8743202181625236,17.0695511242654057,69.1804292601881485]},"#aaaaaa":{"lch":[69.6101658300367916,3.6866289517569387e-12,0],"luv":[69.6101658300367916,3.46613397703382525e-12,1.25584564385283521e-12],"rgb":[0.66666666666666663,0.66666666666666663,0.66666666666666663],"xyz":[0.382062163384573716,0.401977779832193,0.437777016759497817],"hpluv":[0,6.72041492281092149e-12,69.6101658300367916],"hsluv":[0,4.48262290109626775e-12,69.6101658300367916]},"#aaaabb":{"lch":[70.0940699613229441,13.6540669730780309,265.874320218191428],"luv":[70.0940699613229441,-0.982334841759501587,-13.618684340418703],"rgb":[0.66666666666666663,0.66666666666666663,0.733333333333333282],"xyz":[0.399199755491910391,0.408832816675127775,0.528035001858139563],"hpluv":[265.874320218191428,24.7183841606301087,70.0940699613229441],"hsluv":[265.874320218191428,17.6184615311656536,70.0940699613229441]},"#aaaacc":{"lch":[70.6323884029978188,27.7441307883788433,265.87432021818438],"luv":[70.6323884029978188,-1.99603725260327192,-27.6722356973355303],"rgb":[0.66666666666666663,0.66666666666666663,0.8],"xyz":[0.41849213093563209,0.416549766852616576,0.629641512528409719],"hpluv":[265.87432021818438,49.8432735452352063,70.6323884029978188],"hsluv":[265.87432021818438,36.467826786828347,70.6323884029978188]},"#aaaadd":{"lch":[71.2250312240615813,42.0886841218373817,265.874320218182],"luv":[71.2250312240615813,-3.02804878123905441,-41.979617097899343],"rgb":[0.66666666666666663,0.66666666666666663,0.866666666666666696],"xyz":[0.440010456486265689,0.425157097072870083,0.742971360428415717],"hpluv":[265.874320218182,74.9845908684596,71.2250312240615813],"hsluv":[265.874320218182,56.4865697219014891,71.2250312240615813]},"#aaaaee":{"lch":[71.8715993709786432,56.5301989351418541,265.874320218180742],"luv":[71.8715993709786432,-4.0670361537863835,-56.3837087159979902],"rgb":[0.66666666666666663,0.66666666666666663,0.933333333333333348],"xyz":[0.463822636752440398,0.4346819691793401,0.86838217649693894],"hpluv":[265.874320218180742,99.8073514218055,71.8715993709786432],"hsluv":[265.874320218180742,77.6546881169827259,71.8715993709786432]},"#aaaaff":{"lch":[72.5714133442747595,70.9376272522327,265.87432021818006],"luv":[72.5714133442747595,-5.10357119085512778,-70.7538021683399],"rgb":[0.66666666666666663,0.66666666666666663,1],"xyz":[0.489993685162271819,0.445150388543272824,1.00621636478872079],"hpluv":[265.87432021818006,124.036757123492009,72.5714133442747595],"hsluv":[265.87432021818006,99.999999999997641,72.5714133442747595]},"#88bb00":{"lch":[70.0174964893220135,84.793654921948729,107.670265811619984],"luv":[70.0174964893220135,-25.7381496181260658,80.7930168347331659],"rgb":[0.533333333333333326,0.733333333333333282,0],"xyz":[0.279226618658270809,0.407742918869184512,0.0639910921330886],"hpluv":[107.670265811619984,153.672481251000221,70.0174964893220135],"hsluv":[107.670265811619984,100.000000000002288,70.0174964893220135]},"#88bb11":{"lch":[70.045943224524,83.6147085810298,107.921872667069366],"luv":[70.045943224524,-25.7299069713944561,79.5574721715938296],"rgb":[0.533333333333333326,0.733333333333333282,0.0666666666666666657],"xyz":[0.280238284157907913,0.408147585069039365,0.0693191970978442318],"hpluv":[107.921872667069366,151.474322676164348,70.045943224524],"hsluv":[107.921872667069366,98.3704135852689,70.045943224524]},"#88bb22":{"lch":[70.0986261940145567,81.4532385975490172,108.403169751544382],"luv":[70.0986261940145567,-25.7149121100318041,77.2876016784231],"rgb":[0.533333333333333326,0.733333333333333282,0.133333333333333331],"xyz":[0.28211364229638497,0.408897728324430165,0.0791960832938234244],"hpluv":[108.403169751544382,147.447759071005407,70.0986261940145567],"hsluv":[108.403169751544382,95.3794817356858431,70.0986261940145567]},"#88bb33":{"lch":[70.185227758130182,77.9617926087192643,109.240455548552404],"luv":[70.185227758130182,-25.6910124331637526,73.6071530961765887],"rgb":[0.533333333333333326,0.733333333333333282,0.2],"xyz":[0.285201393028842676,0.410132828617413292,0.0954582371514345607],"hpluv":[109.240455548552404,140.95335886915251,70.185227758130182],"hsluv":[109.240455548552404,90.5378353052476399,70.185227758130182]},"#88bb44":{"lch":[70.3099541281250708,73.067556170236557,110.558097475340105],"luv":[70.3099541281250708,-25.6581823155790048,68.4143657790612281],"rgb":[0.533333333333333326,0.733333333333333282,0.266666666666666663],"xyz":[0.289659388273061591,0.411916026715100858,0.118937012104321199],"hpluv":[110.558097475340105,131.870330314080604,70.3099541281250708],"hsluv":[110.558097475340105,83.7238240635208655,70.3099541281250708]},"#88bb55":{"lch":[70.4762099132372,66.7907607981454845,112.553407091589676],"luv":[70.4762099132372,-25.6172250438111178,61.682765089203194],"rgb":[0.533333333333333326,0.733333333333333282,0.333333333333333315],"xyz":[0.295621802312423576,0.414300992330845719,0.150339059378295115],"hpluv":[112.553407091589676,120.257778383662554,70.4762099132372],"hsluv":[112.553407091589676,74.9213657205140606,70.4762099132372]},"#88bb66":{"lch":[70.6867901559138687,59.2534136994931373,115.564788197424377],"luv":[70.6867901559138687,-25.56971066242372,53.4523800375924836],"rgb":[0.533333333333333326,0.733333333333333282,0.4],"xyz":[0.303206798085931761,0.417334990640249037,0.190286703785439076],"hpluv":[115.564788197424377,106.368844477737383,70.6867901559138687],"hsluv":[115.564788197424377,64.2082802413586791,70.6867901559138687]},"#88bb77":{"lch":[70.9439811929011483,50.7088031944788611,120.213509646437856],"luv":[70.9439811929011483,-25.5178724843925657,43.8203252530908287],"rgb":[0.533333333333333326,0.733333333333333282,0.466666666666666674],"xyz":[0.312520811106133667,0.421060595848329833,0.239340505691836986],"hpluv":[120.213509646437856,90.6999673798200519,70.9439811929011483],"hsluv":[120.213509646437856,51.7430673824667338,70.9439811929011483]},"#88bb88":{"lch":[71.2496205680497781,41.6266624709187667,127.715012949237462],"luv":[71.2496205680497781,-25.4644588867656232,32.9293237414924747],"rgb":[0.533333333333333326,0.733333333333333282,0.533333333333333326],"xyz":[0.323661228208077467,0.425516762689107431,0.298013369095409153],"hpluv":[127.715012949237462,74.1358655131278397,71.2496205680497781],"hsluv":[127.715012949237462,37.7483692132655,71.2496205680497781]},"#88bb99":{"lch":[71.605136773449729,32.9376822973712677,140.491872589160209],"luv":[71.605136773449729,-25.4125532319559895,20.9545473192710077],"rgb":[0.533333333333333326,0.733333333333333282,0.6],"xyz":[0.336718192317150167,0.430739548332736588,0.366780046736527088],"hpluv":[140.491872589160209,58.3697971606621948,71.605136773449729],"hsluv":[140.491872589160209,40.0947707109065163,71.605136773449729]},"#88bbaa":{"lch":[72.0115788449514298,26.624214972975043,162.310745910586235],"luv":[72.0115788449514298,-25.3653817896029707,8.0898843993512255],"rgb":[0.533333333333333326,0.733333333333333282,0.66666666666666663],"xyz":[0.351775885282402723,0.43676262551883771,0.446083896353525633],"hpluv":[162.310745910586235,46.9152251525928463,72.0115788449514298],"hsluv":[162.310745910586235,42.5902472855224445,72.0115788449514298]},"#88bbbb":{"lch":[72.4696411221425478,25.9090725846495289,192.177050630060563],"luv":[72.4696411221425478,-25.3261303787159093,-5.46508574835939687],"rgb":[0.533333333333333326,0.733333333333333282,0.733333333333333282],"xyz":[0.368913477389739397,0.443617662361772469,0.536341881452167435],"hpluv":[192.177050630060563,45.3664800039612786,72.4696411221425478],"hsluv":[192.177050630060563,45.1889022919971595,72.4696411221425478]},"#88bbcc":{"lch":[72.9796861172365539,31.9509756483125074,217.648879320727843],"luv":[72.9796861172365539,-25.297786835453639,-19.5163220435359541],"rgb":[0.533333333333333326,0.733333333333333282,0.8],"xyz":[0.388205852833461096,0.451334612539261271,0.637948392122437591],"hpluv":[217.648879320727843,55.5547835161394303,72.9796861172365539],"hsluv":[217.648879320727843,47.846459663484211,72.9796861172365539]},"#88bbdd":{"lch":[73.5417671198988501,42.2771793498237827,233.271065498294831],"luv":[73.5417671198988501,-25.2830202693059967,-33.8840490472881442],"rgb":[0.533333333333333326,0.733333333333333282,0.866666666666666696],"xyz":[0.409724178384094695,0.459941942759514777,0.751278240022443589],"hpluv":[233.271065498294831,72.9476439375157781,73.5417671198988501],"hsluv":[233.271065498294831,52.600286903313318,73.5417671198988501]},"#88bbee":{"lch":[74.1556513704433655,54.6140049995012049,242.42172167609948],"luv":[74.1556513704433655,-25.2841013367454792,-48.4087157615106349],"rgb":[0.533333333333333326,0.733333333333333282,0.933333333333333348],"xyz":[0.433536358650269404,0.469466814865984794,0.876689056090966812],"hpluv":[242.42172167609948,93.4542589851821646,74.1556513704433655],"hsluv":[242.42172167609948,75.5983078602269387,74.1556513704433655]},"#88bbff":{"lch":[74.8208441285393206,67.8489412305869877,248.103607922481928],"luv":[74.8208441285393206,-25.3028619495915343,-62.9543009116260492],"rgb":[0.533333333333333326,0.733333333333333282,1],"xyz":[0.459707407060100826,0.479935234229917518,1.01452324438274855],"hpluv":[248.103607922481928,115.069386567942303,74.8208441285393206],"hsluv":[248.103607922481928,99.9999999999973568,74.8208441285393206]},"#333300":{"lch":[20.3279441284931792,22.4095383785379596,85.8743202181747449],"luv":[20.3279441284931792,1.61224273913978733,22.3514671484727536],"rgb":[0.2,0.2,0],"xyz":[0.0254898472303871464,0.0307148568226560392,0.00458585760277267773],"hpluv":[85.8743202181747449,139.887458074797735,20.3279441284931792],"hsluv":[85.8743202181747449,100.000000000002458,20.3279441284931792]},"#333311":{"lch":[20.4867879892499971,17.9332091798965507,85.8743202181741],"luv":[20.4867879892499971,1.2901955319819518,17.8867377399899183],"rgb":[0.2,0.2,0.0666666666666666657],"xyz":[0.0265015127300242681,0.0311195230225108921,0.00991396256752831],"hpluv":[85.8743202181741,111.076827622251201,20.4867879892499971],"hsluv":[85.8743202181741,79.4044220625277717,20.4867879892499971]},"#333322":{"lch":[20.7776374982028358,10.4602453251552614,85.8743202181717749],"luv":[20.7776374982028358,0.752556982220839221,10.4331390411008691],"rgb":[0.2,0.2,0.133333333333333331],"xyz":[0.0283768708685012867,0.0318696662779017134,0.019790848763507507],"hpluv":[85.8743202181717749,63.8829601302186703,20.7776374982028358],"hsluv":[85.8743202181717749,45.6673964981637113,20.7776374982028358]},"#333333":{"lch":[21.246731294981295,1.12524964979295229e-12,0],"luv":[21.246731294981295,1.05794917113478783e-12,3.83314917077821647e-13],"rgb":[0.2,0.2,0.2],"xyz":[0.0314646216009590307,0.0331047665708848263,0.0360530026211186502],"hpluv":[0,6.72041492281092149e-12,21.246731294981295],"hsluv":[0,1.92419399944792236e-12,21.246731294981295]},"#333344":{"lch":[21.9038391599933462,12.2084714240410825,265.874320218182163],"luv":[21.9038391599933462,-0.878332211796974,-12.176834853004598],"rgb":[0.2,0.2,0.266666666666666663],"xyz":[0.0359226168451779043,0.0348879646685724,0.0595317775740052887],"hpluv":[265.874320218182163,70.7262082967351517,21.9038391599933462],"hsluv":[265.874320218182163,13.7757030029577514,21.9038391599933462]},"#333355":{"lch":[22.7485838486986935,25.0264321710322868,265.874320218179776],"luv":[22.7485838486986935,-1.80051382017376982,-24.9615796213830023],"rgb":[0.2,0.2,0.333333333333333315],"xyz":[0.0418850308845399,0.0372729302843172322,0.0909338248479792],"hpluv":[265.874320218179776,139.599512106194084,22.7485838486986935],"hsluv":[265.874320218179776,27.1905063829271256,22.7485838486986935]},"#333366":{"lch":[23.7726526978294,37.7235732610660364,265.874320218179],"luv":[23.7726526978294,-2.71400312032964841,-37.625817820292724],"rgb":[0.2,0.2,0.4],"xyz":[0.0494700266580480746,0.0403069285937205438,0.130881469255123173],"hpluv":[265.874320218179,201.360603518100845,23.7726526978294],"hsluv":[265.874320218179,39.2200280117306193,23.7726526978294]},"#333377":{"lch":[24.9621315786770737,49.9646270765614062,265.874320218178639],"luv":[24.9621315786770737,-3.59467945556105306,-49.8351506319748268],"rgb":[0.2,0.2,0.466666666666666674],"xyz":[0.0587840396782499941,0.0440325338018013601,0.179935271161521082],"hpluv":[265.874320218178639,253.992158426909725,24.9621315786770737],"hsluv":[265.874320218178639,49.4713434217918646,24.9621315786770737]},"#333388":{"lch":[26.2997861111378413,61.6680265106551175,265.874320218178468],"luv":[26.2997861111378413,-4.43667452222106906,-61.5082223194812912],"rgb":[0.2,0.2,0.533333333333333326],"xyz":[0.0699244567801938222,0.048488700642578958,0.238608134565093222],"hpluv":[265.874320218178468,297.541234413863208,26.2997861111378413],"hsluv":[265.874320218178468,57.953618257344317,26.2997861111378413]},"#333399":{"lch":[27.7670269025285634,72.8744236647892336,265.874320218178354],"luv":[27.7670269025285634,-5.24291301488723782,-72.6855796399362788],"rgb":[0.2,0.2,0.6],"xyz":[0.0829814208892665356,0.0537114862862081155,0.307374812206211157],"hpluv":[265.874320218178354,333.031319879373427,27.7670269025285634],"hsluv":[265.874320218178354,64.8662025552495862,27.7670269025285634]},"#3333aa":{"lch":[29.34539826905295,83.6653121043175361,265.874320218178241],"luv":[29.34539826905295,-6.01925794630032573,-83.4485049793509575],"rgb":[0.2,0.2,0.66666666666666663],"xyz":[0.0980391138545190777,0.059734563472309217,0.386678661823209757],"hpluv":[265.874320218178241,361.780166220798492,29.34539826905295],"hsluv":[265.874320218178241,70.4657614516561353,29.34539826905295]},"#3333bb":{"lch":[31.0175640968910713,94.1237197643615247,265.874320218178184],"luv":[31.0175640968910713,-6.77168271864664284,-93.8798111173964855],"rgb":[0.2,0.2,0.733333333333333282],"xyz":[0.115176705961855724,0.0665896003152439686,0.476936646921851504],"hpluv":[265.874320218178184,385.062051502536349,31.0175640968910713],"hsluv":[265.874320218178184,75.0004925607309758,31.0175640968910713]},"#3333cc":{"lch":[32.7678589751368321,104.319620441623087,265.874320218178127],"luv":[32.7678589751368321,-7.50522156082274261,-104.049290523324899],"rgb":[0.2,0.2,0.8],"xyz":[0.134469081405577451,0.0743065504927327702,0.578543157592121604],"hpluv":[265.874320218178127,403.977575952485893,32.7678589751368321],"hsluv":[265.874320218178127,79.524052836351089,32.7678589751368321]},"#3333dd":{"lch":[34.5825131799139243,114.307143948468337,265.874320218178127],"luv":[34.5825131799139243,-8.22376881440244745,-114.010932739554079],"rgb":[0.2,0.2,0.866666666666666696],"xyz":[0.155987406956211,0.0829138807129863,0.691873005492127602],"hpluv":[265.874320218178127,419.426773039758132,34.5825131799139243],"hsluv":[265.874320218178127,86.1542613798901584,34.5825131799139243]},"#3333ee":{"lch":[36.4496605331747929,124.126383834434506,265.87432021817807],"luv":[36.4496605331747929,-8.93020898923314732,-123.80472741871364],"rgb":[0.2,0.2,0.933333333333333348],"xyz":[0.179799587222385732,0.092438752819456349,0.817283821560650825],"hpluv":[265.87432021817807,432.12554656995303,36.4496605331747929],"hsluv":[265.87432021817807,92.9362870993519,36.4496605331747929]},"#3333ff":{"lch":[38.3592184432327414,133.806417871427385,265.87432021817807],"luv":[38.3592184432327414,-9.62663407069321231,-133.45967698167118],"rgb":[0.2,0.2,1],"xyz":[0.205970635632217125,0.102907172183389045,0.95511800985243267],"hpluv":[265.87432021817807,442.635784237250618,38.3592184432327414],"hsluv":[265.87432021817807,99.99999999999946,38.3592184432327414]},"#aabb00":{"lch":[72.2864137555308162,81.0402066187271686,93.9104624709461291],"luv":[72.2864137555308162,-5.52673715975233737,80.8515322376329664],"rgb":[0.66666666666666663,0.733333333333333282,0],"xyz":[0.343467394669040582,0.440867068999738376,0.0670023785085933632],"hpluv":[93.9104624709461291,142.260125307220505,72.2864137555308162],"hsluv":[93.9104624709461291,100.00000000000226,72.2864137555308162]},"#aabb11":{"lch":[72.3134178153803759,79.8795424406406198,94.0047051989067199],"luv":[72.3134178153803759,-5.5786590117117969,79.6845020324350912],"rgb":[0.66666666666666663,0.733333333333333282,0.0666666666666666657],"xyz":[0.344479060168677687,0.441271735199593229,0.072330483473349],"hpluv":[94.0047051989067199,140.170301198642704,72.3134178153803759],"hsluv":[94.0047051989067199,98.4998030851846522,72.3134178153803759]},"#aabb22":{"lch":[72.3634325080893319,77.7463008610920667,94.1853407287125179],"luv":[72.3634325080893319,-5.67416055225396132,77.5389656857163],"rgb":[0.66666666666666663,0.733333333333333282,0.133333333333333331],"xyz":[0.346354418307154743,0.44202187845498403,0.0822073696693281925],"hpluv":[94.1853407287125179,136.332658010127801,72.3634325080893319],"hsluv":[94.1853407287125179,95.7441801677588131,72.3634325080893319]},"#aabb33":{"lch":[72.4456578556837343,74.284969405898,94.5007685828256427],"luv":[72.4456578556837343,-5.82932493434540167,74.0558954469191377],"rgb":[0.66666666666666663,0.733333333333333282,0.2],"xyz":[0.349442169039612449,0.443256978747967156,0.0984695235269393288],"hpluv":[94.5007685828256427,130.115164427369336,72.4456578556837343],"hsluv":[94.5007685828256427,91.2774770665997721,72.4456578556837343]},"#aabb44":{"lch":[72.5641031469497193,69.3968632274838768,95.0004815565242922],"luv":[72.5641031469497193,-6.04891620231322502,69.1327363742496317],"rgb":[0.66666666666666663,0.733333333333333282,0.266666666666666663],"xyz":[0.353900164283831364,0.445040176845654722,0.121948298479825967],"hpluv":[95.0004815565242922,121.354905136961719,72.5641031469497193],"hsluv":[95.0004815565242922,84.978619462346515,72.5641031469497193]},"#aabb55":{"lch":[72.7220260779140659,63.0543258899363366,95.7659530899235705],"luv":[72.7220260779140659,-6.33475857174489843,62.7353078200147181],"rgb":[0.66666666666666663,0.733333333333333282,0.333333333333333315],"xyz":[0.359862578323193349,0.447425142461399583,0.153350345753799883],"hpluv":[95.7659530899235705,110.024206089370551,72.7220260779140659],"hsluv":[95.7659530899235705,76.8198788639563475,72.7220260779140659]},"#aabb66":{"lch":[72.922116394456026,55.2958006214329245,96.9449007941817342],"luv":[72.922116394456026,-6.68608027099689206,54.8900892418207675],"rgb":[0.66666666666666663,0.733333333333333282,0.4],"xyz":[0.367447574096701535,0.450459140770802902,0.193297990160943844],"hpluv":[96.9449007941817342,96.2215198645611167,72.922116394456026],"hsluv":[96.9449007941817342,66.8569788454327778,72.922116394456026]},"#aabb77":{"lch":[73.1665925415562555,46.2248747385797927,98.8352478745929801],"luv":[73.1665925415562555,-7.09985217623529596,45.6763740206356488],"rgb":[0.66666666666666663,0.733333333333333282,0.466666666666666674],"xyz":[0.37676158711690344,0.454184745978883697,0.242351792067341754],"hpluv":[98.8352478745929801,80.1682197570307267,73.1665925415562555],"hsluv":[98.8352478745929801,55.2184354086421223,73.1665925415562555]},"#aabb88":{"lch":[73.4572589636137,36.0214199172978056,102.133241078873],"luv":[73.4572589636137,-7.57119112276486117,35.2167539367396216],"rgb":[0.66666666666666663,0.733333333333333282,0.533333333333333326],"xyz":[0.387902004218847241,0.458640912819661295,0.301024655470913949],"hpluv":[102.133241078873,62.2250760292602862,73.4572589636137],"hsluv":[102.133241078873,42.0922357464751116,73.4572589636137]},"#aabb99":{"lch":[73.7955437608147236,25.0118273668521454,108.880774444702425],"luv":[73.7955437608147236,-8.09382587885112592,23.6660408786948082],"rgb":[0.66666666666666663,0.733333333333333282,0.6],"xyz":[0.40095896832792,0.463863698463290453,0.369791333112031828],"hpluv":[108.880774444702425,43.0085312761643337,73.7955437608147236],"hsluv":[108.880774444702425,27.7101400322224,73.7955437608147236]},"#aabbaa":{"lch":[74.1825262226786464,14.1574418893213867,127.715012949227386],"luv":[74.1825262226786464,-8.66059336811296632,11.1994322785447302],"rgb":[0.66666666666666663,0.733333333333333282,0.66666666666666663],"xyz":[0.416016661293172496,0.469886775649391575,0.449095182729030429],"hpluv":[127.715012949227386,24.2171200924073027,74.1825262226786464],"hsluv":[127.715012949227386,12.3308304853939106,74.1825262226786464]},"#aabbbb":{"lch":[74.6189593067414734,9.47715438031144153,192.177050630059],"luv":[74.6189593067414734,-9.26392276955498417,-1.99904729008021675],"rgb":[0.66666666666666663,0.733333333333333282,0.733333333333333282],"xyz":[0.43315425340050917,0.476741812492326333,0.539353167827672175],"hpluv":[192.177050630059,16.1164020856357908,74.6189593067414734],"hsluv":[192.177050630059,16.0533177597809029,74.6189593067414734]},"#aabbcc":{"lch":[75.1052899078477623,18.5983929047544514,237.852316168687679],"luv":[75.1052899078477623,-9.89626817417043547,-15.7468757175676597],"rgb":[0.66666666666666663,0.733333333333333282,0.8],"xyz":[0.452446628844230925,0.484458762669815135,0.640959678497942331],"hpluv":[237.852316168687679,31.4227520087917149,75.1052899078477623],"hsluv":[237.852316168687679,25.8004515395991127,75.1052899078477623]},"#aabbdd":{"lch":[75.6416785331857682,31.6798915222297,250.547006926215033],"luv":[75.6416785331857682,-10.5504613433008458,-29.8714461033234144],"rgb":[0.66666666666666663,0.733333333333333282,0.866666666666666696],"xyz":[0.473964954394864413,0.493066092890068641,0.754289526397948329],"hpluv":[250.547006926215033,53.1449318902714438,75.6416785331857682],"hsluv":[250.547006926215033,48.9122949421499484,75.6416785331857682]},"#aabbee":{"lch":[76.2280192594463699,45.6175545861468166,255.761586302643195],"luv":[76.2280192594463699,-11.2199701465387403,-44.2162137267639],"rgb":[0.66666666666666663,0.733333333333333282,0.933333333333333348],"xyz":[0.497777134661039178,0.502590964996538658,0.879700342466471552],"hpluv":[255.761586302643195,76.8288153841444483,76.2280192594463699],"hsluv":[255.761586302643195,73.6249760737912311,76.2280192594463699]},"#aabbff":{"lch":[76.863960378353255,59.8395450787859247,258.530312903596609],"luv":[76.863960378353255,-11.8990616804050067,-58.6445520603744583],"rgb":[0.66666666666666663,0.733333333333333282,1],"xyz":[0.523948183070870543,0.513059384360471382,1.01753453075825329],"hpluv":[258.530312903596609,104.151140840900069,76.863960378353255],"hsluv":[258.530312903596609,99.9999999999969305,76.863960378353255]},"#88cc00":{"lch":[75.0884647575288,93.9986167747887,111.475410134903882],"luv":[75.0884647575288,-34.413070492851,87.4727416674912348],"rgb":[0.533333333333333326,0.8,0],"xyz":[0.317450361967887784,0.484190405488419406,0.0767323399029605363],"hpluv":[111.475410134903882,158.85012628624969,75.0884647575288],"hsluv":[111.475410134903882,100.000000000002288,75.0884647575288]},"#88cc11":{"lch":[75.1138336746799,92.9472917959209752,111.713770271434171],"luv":[75.1138336746799,-34.3877142984514421,86.3520941119794685],"rgb":[0.533333333333333326,0.8,0.0666666666666666657],"xyz":[0.318462027467524889,0.484595071688274259,0.082060444867716173],"hpluv":[111.713770271434171,157.020421425354783,75.1138336746799],"hsluv":[111.713770271434171,98.6248626695712289,75.1138336746799]},"#88cc22":{"lch":[75.1608235532889495,91.0175657840787551,112.166724150973],"luv":[75.1608235532889495,-34.3412008388942667,84.2904455214339805],"rgb":[0.533333333333333326,0.8,0.133333333333333331],"xyz":[0.320337385606001945,0.48534521494366506,0.0919373310636953656],"hpluv":[112.166724150973,153.664310911800271,75.1608235532889495],"hsluv":[112.166724150973,96.0970283406349,75.1608235532889495]},"#88cc33":{"lch":[75.2380863503033908,87.8942550668024865,112.94545296029041],"luv":[75.2380863503033908,-34.2659803117460342,80.9397471396048331],"rgb":[0.533333333333333326,0.8,0.2],"xyz":[0.323425136338459651,0.486580315236648187,0.108199484921306516],"hpluv":[112.94545296029041,148.2388630129999,75.2380863503033908],"hsluv":[112.94545296029041,91.9942509365254324,75.2380863503033908]},"#88cc44":{"lch":[75.3494055810326415,83.5027286146262,114.147802574759467],"luv":[75.3494055810326415,-34.1602904869016655,76.1956707427555244],"rgb":[0.533333333333333326,0.8,0.266666666666666663],"xyz":[0.327883131582678566,0.488363513334335753,0.131678259874193154],"hpluv":[114.147802574759467,140.624231819797672,75.3494055810326415],"hsluv":[114.147802574759467,86.1974134191241177,75.3494055810326415]},"#88cc55":{"lch":[75.4978684165763241,77.8461227965530469,115.917002828128631],"luv":[75.4978684165763241,-34.0241050685150555,70.0169915716368365],"rgb":[0.533333333333333326,0.8,0.333333333333333315],"xyz":[0.333845545622040552,0.490748478950080613,0.16308030714816707],"hpluv":[115.917002828128631,130.840327774204638,75.4978684165763241],"hsluv":[115.917002828128631,78.6694108520956092,75.4978684165763241]},"#88cc66":{"lch":[75.6860396561484663,71.0106875190110287,118.477611184333398],"luv":[75.6860396561484663,-33.8589835890750237,62.4186428259808963],"rgb":[0.533333333333333326,0.8,0.4],"xyz":[0.341430541395548737,0.493782477259483932,0.203027951555311],"hpluv":[118.477611184333398,119.054896833398359,75.6860396561484663],"hsluv":[118.477611184333398,69.4467240035668141,75.6860396561484663]},"#88cc77":{"lch":[75.9160535408259705,63.1826013081171638,122.199343200922883],"luv":[75.9160535408259705,-33.6678964132470924,53.4650713940171656],"rgb":[0.533333333333333326,0.8,0.466666666666666674],"xyz":[0.350744554415750642,0.497508082467564727,0.252081753461708913],"hpluv":[122.199343200922883,105.609553255175555,75.9160535408259705],"hsluv":[122.199343200922883,58.6308874961384063,75.9160535408259705]},"#88cc88":{"lch":[76.1896681333118124,54.6887581458639929,127.715012949238314],"luv":[76.1896681333118124,-33.4549913615237,43.2622678616965288],"rgb":[0.533333333333333326,0.8,0.533333333333333326],"xyz":[0.361884971517694443,0.50196424930834227,0.310754616865281108],"hpluv":[127.715012949238314,91.92606633748386,76.1896681333118124],"hsluv":[127.715012949238314,46.3779062484352878,76.1896681333118124]},"#88cc99":{"lch":[76.5083007543168492,46.0935908553499587,136.122445502284393],"luv":[76.5083007543168492,-33.2253063874269188,31.9483666781575764],"rgb":[0.533333333333333326,0.8,0.6],"xyz":[0.374941935626767142,0.507187034951971483,0.379521294506399],"hpluv":[136.122445502284393,78.7570782006024643,76.5083007543168492],"hsluv":[136.122445502284393,48.1280089891728622,76.5083007543168492]},"#88ccaa":{"lch":[76.8730534179438223,38.4110576559043437,149.173477570542047],"luv":[76.8730534179438223,-32.9844501501569098,19.6833787378341469],"rgb":[0.533333333333333326,0.8,0.66666666666666663],"xyz":[0.389999628592019698,0.513210112138072549,0.458825144123397588],"hpluv":[149.173477570542047,66.8865090410736229,76.8730534179438223],"hsluv":[149.173477570542047,50.0095890879800891,76.8730534179438223]},"#88ccbb":{"lch":[77.2847330465352087,33.404634806871222,168.536638924911273],"luv":[77.2847330465352087,-32.73827895277973,6.638879257104497],"rgb":[0.533333333333333326,0.8,0.733333333333333282],"xyz":[0.407137220699356372,0.520065148981007308,0.54908312922203939],"hpluv":[168.536638924911273,59.444025112992847,77.2847330465352087],"hsluv":[168.536638924911273,51.9915664660802292,77.2847330465352087]},"#88cccc":{"lch":[77.7438691793350074,33.2404934388306,192.177050630060876],"luv":[77.7438691793350074,-32.4925976386916417,-7.01152642061846443],"rgb":[0.533333333333333326,0.8,0.8],"xyz":[0.426429596143078071,0.527782099158496165,0.650689639892309546],"hpluv":[192.177050630060876,60.6231146417445359,77.7438691793350074],"hsluv":[192.177050630060876,54.0427382519684585,77.7438691793350074]},"#88ccdd":{"lch":[78.2507307533704,38.5418325774740964,213.193277164244591],"luv":[78.2507307533704,-32.2529061156020589,-21.1003058159876602],"rgb":[0.533333333333333326,0.8,0.866666666666666696],"xyz":[0.44794792169371167,0.536389429378749671,0.764019487792315544],"hpluv":[213.193277164244591,72.2588367593471759,78.2507307533704],"hsluv":[213.193277164244591,56.1332045791076126,78.2507307533704]},"#88ccee":{"lch":[78.8053428571366368,47.78945312574524,227.924421751618695],"luv":[78.8053428571366368,-32.0242046898233,-35.4722728908382834],"rgb":[0.533333333333333326,0.8,0.933333333333333348],"xyz":[0.47176010195988638,0.545914301485219688,0.889430303860838767],"hpluv":[227.924421751618695,92.3999074491721473,78.8053428571366368],"hsluv":[227.924421751618695,70.4270935368067796,78.8053428571366368]},"#88ccff":{"lch":[79.4075039272108114,59.2521837878726885,237.529017152572294],"luv":[79.4075039272108114,-31.8108626015509195,-49.9889018100727327],"rgb":[0.533333333333333326,0.8,1],"xyz":[0.497931150369717801,0.556382720849152412,1.02726449215262061],"hpluv":[237.529017152572294,118.549697277888072,79.4075039272108114],"hsluv":[237.529017152572294,99.999999999996561,79.4075039272108114]},"#334400":{"lch":[26.2681529832905483,31.0251081485104194,104.276907196552472],"luv":[26.2681529832905483,-7.65105337509169647,30.0669040288198879],"rgb":[0.2,0.266666666666666663,0],"xyz":[0.034322417713353183,0.0483799977885883553,0.00753004776376127276],"hpluv":[104.276907196552472,149.872894059772364,26.2681529832905483],"hsluv":[104.276907196552472,100.000000000002302,26.2681529832905483]},"#334411":{"lch":[26.3856741683463127,27.3886432490873446,106.295788944443402],"luv":[26.3856741683463127,-7.68514827558869662,26.2883296351821087],"rgb":[0.2,0.266666666666666663,0.0666666666666666657],"xyz":[0.0353340832129903082,0.0487846639884432082,0.0128581527285169042],"hpluv":[106.295788944443402,131.716945387015755,26.3856741683463127],"hsluv":[106.295788944443402,86.6296124974134614,26.3856741683463127]},"#334422":{"lch":[26.6018195362025054,21.2226436820006832,111.412237748000109],"luv":[26.6018195362025054,-7.74787020962619799,19.7578114189793403],"rgb":[0.2,0.266666666666666663,0.133333333333333331],"xyz":[0.0372094413514673233,0.0495348072438340295,0.0227350389244961],"hpluv":[111.412237748000109,101.234249163259577,26.6018195362025054],"hsluv":[111.412237748000109,63.7673799144094,26.6018195362025054]},"#334433":{"lch":[26.9529945323855813,12.8320575385027151,127.715012949236225],"luv":[26.9529945323855813,-7.8498102472204323,10.150969399721264],"rgb":[0.2,0.266666666666666663,0.2],"xyz":[0.0402971920839250639,0.0507699075368171424,0.038997192782107247],"hpluv":[127.715012949236225,60.4127494816677171,26.9529945323855813],"hsluv":[127.715012949236225,30.7608572023581708,26.9529945323855813]},"#334444":{"lch":[27.4501004194092673,8.17817622085537721,192.177050630060421],"luv":[27.4501004194092673,-7.99417102070306651,-1.72504956193021397],"rgb":[0.2,0.266666666666666663,0.266666666666666663],"xyz":[0.0447551873281439444,0.0525531056345047154,0.0624759677349938855],"hpluv":[192.177050630060421,37.8052272806132379,27.4501004194092673],"hsluv":[192.177050630060421,37.6572465300637518,27.4501004194092673]},"#334455":{"lch":[28.0976851129048839,16.9879579660521678,241.20654356816641],"luv":[28.0976851129048839,-8.1823109542023289,-14.8875956186718064],"rgb":[0.2,0.266666666666666663,0.333333333333333315],"xyz":[0.0507176013675059364,0.0549380712502495483,0.0938780150089678],"hpluv":[241.20654356816641,76.720241835207986,28.0976851129048839],"hsluv":[241.20654356816641,44.9859363973003568,28.0976851129048839]},"#334466":{"lch":[28.8949601880565652,29.7043747380071501,253.545194757545516],"luv":[28.8949601880565652,-8.41402976058801855,-28.487786536758108],"rgb":[0.2,0.266666666666666663,0.4],"xyz":[0.0583025971410141147,0.0579720695596528598,0.133825659416111742],"hpluv":[253.545194757545516,130.448064952476017,28.8949601880565652],"hsluv":[253.545194757545516,52.1427730716471629,28.8949601880565652]},"#334477":{"lch":[29.8367962202096138,42.8398018741040758,258.299336276781332],"luv":[29.8367962202096138,-8.68785350705267589,-41.9496105590085691],"rgb":[0.2,0.266666666666666663,0.466666666666666674],"xyz":[0.0676166101612160342,0.0616976747677336762,0.182879461322509651],"hpluv":[258.299336276781332,182.19421868795277,29.8367962202096138],"hsluv":[258.299336276781332,58.7347196438674857,29.8367962202096138]},"#334488":{"lch":[30.9147794404111025,55.6960507233291082,260.699324576281469],"luv":[30.9147794404111025,-9.00134255207500189,-54.9638599302837605],"rgb":[0.2,0.266666666666666663,0.533333333333333326],"xyz":[0.0787570272631598622,0.066153841608511274,0.241552324726081818],"hpluv":[260.699324576281469,228.611238042833349,30.9147794404111025],"hsluv":[260.699324576281469,64.5716173949788583,30.9147794404111025]},"#334499":{"lch":[32.1182691124294664,68.0605660836803281,262.102678541403236],"luv":[32.1182691124294664,-9.35140200670356769,-67.4150720250304],"rgb":[0.2,0.266666666666666663,0.6],"xyz":[0.0918139913722325618,0.0713766272521404316,0.310319002367199726],"hpluv":[262.102678541403236,268.895014901030436,32.1182691124294664],"hsluv":[262.102678541403236,69.6097770986353623,32.1182691124294664]},"#3344aa":{"lch":[33.435366318838156,79.8975403264742852,263.001802037450773],"luv":[33.435366318838156,-9.73456660877536528,-79.3023023824649158],"rgb":[0.2,0.266666666666666663,0.66666666666666663],"xyz":[0.106871684337485118,0.07739970443824154,0.389622851984198326],"hpluv":[263.001802037450773,303.226149032408784,33.435366318838156],"hsluv":[263.001802037450773,73.891501645941716,33.435366318838156]},"#3344bb":{"lch":[34.8537252521307721,91.2457354427413492,263.615054402289786],"luv":[34.8537252521307721,-10.1472390443123768,-90.6797539490724773],"rgb":[0.2,0.266666666666666663,0.733333333333333282],"xyz":[0.124009276444821764,0.0842547412811763,0.479880837082840073],"hpluv":[263.615054402289786,332.202349056841342,34.8537252521307721],"hsluv":[263.615054402289786,77.4995146205371412,34.8537252521307721]},"#3344cc":{"lch":[36.3611746115969083,102.170263494902102,264.052905077601281],"luv":[36.3611746115969083,-10.5858721727669973,-101.620382074461631],"rgb":[0.2,0.266666666666666663,0.8],"xyz":[0.143301651888543491,0.0919716914586651,0.581487347753110284],"hpluv":[264.052905077601281,356.55451128807033,36.3611746115969083],"hsluv":[264.052905077601281,80.5286468598271767,36.3611746115969083]},"#3344dd":{"lch":[37.9461503215655611,112.73940211649635,264.376684246138268],"luv":[37.9461503215655611,-11.0470957042534899,-112.196855865421313],"rgb":[0.2,0.266666666666666663,0.866666666666666696],"xyz":[0.164819977439177034,0.100579021678918634,0.694817195653116282],"hpluv":[264.376684246138268,377.005191833442723,37.9461503215655611],"hsluv":[264.376684246138268,84.1625325255073,37.9461503215655611]},"#3344ee":{"lch":[39.5979632159824462,123.014623823289881,264.622878978329823],"luv":[39.5979632159824462,-11.5277944422180187,-122.473293536523641],"rgb":[0.2,0.266666666666666663,0.933333333333333348],"xyz":[0.188632157705351772,0.110103893785388651,0.820228011721639505],"hpluv":[264.622878978329823,394.205992168221826,39.5979632159824462],"hsluv":[264.622878978329823,91.9832832027675664,39.5979632159824462]},"#3344ff":{"lch":[41.3069357297154482,133.047388274610427,264.814390787746049],"luv":[41.3069357297154482,-12.0251481753234213,-132.502842754623401],"rgb":[0.2,0.266666666666666663,1],"xyz":[0.214803206115183165,0.120572313149321361,0.95806220001342135],"hpluv":[264.814390787746049,408.716999433792864,41.3069357297154482],"hsluv":[264.814390787746049,99.9999999999994458,41.3069357297154482]},"#aacc00":{"lch":[77.1199831352121,88.8460909387721,100.173289143969555],"luv":[77.1199831352121,-15.692520471132994,87.4492577233428108],"rgb":[0.66666666666666663,0.8,0],"xyz":[0.381691137978657502,0.517314555618973326,0.0797436262784653],"hpluv":[100.173289143969555,156.730643533439519,77.1199831352121],"hsluv":[100.173289143969555,100.000000000002373,77.1199831352121]},"#aacc11":{"lch":[77.1442576556984676,87.800209961997254,100.311366942902],"luv":[77.1442576556984676,-15.7160097521192821,86.3821967007212237],"rgb":[0.66666666666666663,0.8,0.0666666666666666657],"xyz":[0.382702803478294606,0.517719221818828235,0.085071731243220941],"hpluv":[100.311366942902,155.08420894585916,77.1442576556984676],"hsluv":[100.311366942902,98.7181568051142,77.1442576556984676]},"#aacc22":{"lch":[77.1892227090432641,85.8765024717939411,100.574350259733862],"luv":[77.1892227090432641,-15.7593085348968636,84.4181134075499102],"rgb":[0.66666666666666663,0.8,0.133333333333333331],"xyz":[0.384578161616771663,0.518469365074219,0.0949486174392001336],"hpluv":[100.574350259733862,152.047171814071362,77.1892227090432641],"hsluv":[100.574350259733862,96.3604791744028404,77.1892227090432641]},"#aacc33":{"lch":[77.2631626362465482,82.7513779572315116,101.028364552392574],"luv":[77.2631626362465482,-15.8299191574657527,81.2231753460099668],"rgb":[0.66666666666666663,0.8,0.2],"xyz":[0.387665912349229369,0.519704465367202162,0.111210771296811284],"hpluv":[101.028364552392574,147.088857703341773,77.2631626362465482],"hsluv":[101.028364552392574,92.5301726329619,77.2631626362465482]},"#aacc44":{"lch":[77.3697083481362569,78.3307208035327278,101.734312614214147],"luv":[77.3697083481362569,-15.9304072801298968,76.6937021240348],"rgb":[0.66666666666666663,0.8,0.266666666666666663],"xyz":[0.392123907593448284,0.521487663464889728,0.134689546249697922],"hpluv":[101.734312614214147,140.021584702469511,77.3697083481362569],"hsluv":[101.734312614214147,87.1104907412273377,77.3697083481362569]},"#aacc55":{"lch":[77.5118305539362495,72.5836718124644875,102.784946304826448],"luv":[77.5118305539362495,-16.0622064150904862,70.7841432727597493],"rgb":[0.66666666666666663,0.8,0.333333333333333315],"xyz":[0.398086321632810269,0.523872629080634478,0.16609159352367181],"hpluv":[102.784946304826448,130.736122666873541,77.5118305539362495],"hsluv":[102.784946304826448,80.0585735006639,77.5118305539362495]},"#aacc66":{"lch":[77.6920071630818114,65.5409770618580865,104.333567867024144],"luv":[77.6920071630818114,-16.225762577214013,63.5007425390513731],"rgb":[0.66666666666666663,0.8,0.4],"xyz":[0.405671317406318455,0.526906627390037796,0.2060392379308158],"hpluv":[104.333567867024144,119.198186871977654,77.6920071630818114],"hsluv":[104.333567867024144,71.3979720959128,77.6920071630818114]},"#aacc77":{"lch":[77.912311817127474,57.2990991241466574,106.653185897117098],"luv":[77.912311817127474,-16.4206512214041886,54.8958010589496865],"rgb":[0.66666666666666663,0.8,0.466666666666666674],"xyz":[0.41498533042652036,0.530632232598118647,0.255093039837213709],"hpluv":[106.653185897117098,105.457526508453554,77.912311817127474],"hsluv":[106.653185897117098,61.2114900666368769,77.912311817127474]},"#aacc88":{"lch":[78.1744663257663,48.0371110011961946,110.274462486898784],"luv":[78.1744663257663,-16.6457037997795574,45.0608985524173633],"rgb":[0.66666666666666663,0.8,0.533333333333333326],"xyz":[0.42612574752846416,0.53508839943889619,0.313765903240785848],"hpluv":[110.274462486898784,89.6844859178180513,78.1744663257663],"hsluv":[110.274462486898784,49.6324036967210418,78.1744663257663]},"#aacc99":{"lch":[78.4798746855988583,38.0746183254558517,116.349336294343573],"luv":[78.4798746855988583,-16.8991518201031816,34.1188397866961779],"rgb":[0.66666666666666663,0.8,0.6],"xyz":[0.43918271163753686,0.540311185082525403,0.382532580881903783],"hpluv":[116.349336294343573,72.2917022308792383,78.4798746855988583],"hsluv":[116.349336294343573,36.8338589582570535,78.4798746855988583]},"#aaccaa":{"lch":[78.8296472340984593,28.0820980315160789,127.715012949234293],"luv":[78.8296472340984593,-17.1787837008838338,22.2147163027108476],"rgb":[0.66666666666666663,0.8,0.66666666666666663],"xyz":[0.454240404602789416,0.546334262268626469,0.461836430498902384],"hpluv":[127.715012949234293,54.3703242245777503,78.8296472340984593],"hsluv":[127.715012949234293,23.0170216670413055,78.8296472340984593]},"#aaccbb":{"lch":[79.2246195207133,19.8998018903229301,151.462718702096396],"luv":[79.2246195207133,-17.4821042808439238,9.50674209115818236],"rgb":[0.66666666666666663,0.8,0.733333333333333282],"xyz":[0.47137799671012609,0.553189299111561228,0.55209441559754413],"hpluv":[151.462718702096396,39.3999249764932173,79.2246195207133],"hsluv":[151.462718702096396,25.9022649263565761,79.2246195207133]},"#aacccc":{"lch":[79.665368512397464,18.216345023755192,192.177050630059796],"luv":[79.665368512397464,-17.80648564660072,-3.84243346616347603],"rgb":[0.66666666666666663,0.8,0.8],"xyz":[0.490670372153847789,0.560906249289050085,0.653700926267814286],"hpluv":[192.177050630059796,36.9937893704297878,79.665368512397464],"hsluv":[192.177050630059796,28.9019874878943099,79.665368512397464]},"#aaccdd":{"lch":[80.1522276755556504,25.332665849504842,224.238778454296437],"luv":[80.1522276755556504,-18.1492995031005968,-17.6733382978265112],"rgb":[0.66666666666666663,0.8,0.866666666666666696],"xyz":[0.512188697704481388,0.569513579509303591,0.767030774167820284],"hpluv":[224.238778454296437,52.9363308364733882,80.1522276755556504],"hsluv":[224.238778454296437,37.9969627853472787,80.1522276755556504]},"#aaccee":{"lch":[80.6853018377357216,36.8247992939862954,239.828051209207672],"luv":[80.6853018377357216,-18.5080244281037345,-31.8358112007702587],"rgb":[0.66666666666666663,0.8,0.933333333333333348],"xyz":[0.536000877970656098,0.579038451615773608,0.892441590236343507],"hpluv":[239.828051209207672,79.4490805971393854,80.6853018377357216],"hsluv":[239.828051209207672,67.7857500876551313,80.6853018377357216]},"#aaccff":{"lch":[81.2644823279674284,49.9029399741520834,247.769045833277914],"luv":[81.2644823279674284,-18.8803249793402337,-46.1934708236816434],"rgb":[0.66666666666666663,0.8,1],"xyz":[0.562171926380487519,0.589506870979706332,1.03027577852812535],"hpluv":[247.769045833277914,111.562078640814406,81.2644823279674284],"hsluv":[247.769045833277914,99.9999999999962625,81.2644823279674284]},"#88dd00":{"lch":[80.1491214608994085,103.252993693735874,114.339076779275487],"luv":[80.1491214608994085,-42.5542610136121837,94.0761158653142218],"rgb":[0.533333333333333326,0.866666666666666696,0],"xyz":[0.360084352515062933,0.569458386582770926,0.0909436700853518548],"hpluv":[114.339076779275487,215.722602995807392,80.1491214608994085],"hsluv":[114.339076779275487,100.000000000002288,80.1491214608994085]},"#88dd11":{"lch":[80.1718911006532551,102.308936337717924,114.55620444532569],"luv":[80.1718911006532551,-42.518128048011647,93.0555062414261727],"rgb":[0.533333333333333326,0.866666666666666696,0.0666666666666666657],"xyz":[0.361096018014700038,0.569863052782625834,0.0962717750501074915],"hpluv":[114.55620444532569,214.038948901986089,80.1718911006532551],"hsluv":[114.55620444532569,98.8288322371321186,80.1718911006532551]},"#88dd22":{"lch":[80.2140714473537315,100.574216022873557,114.966813202702411],"luv":[80.2140714473537315,-42.4516967311958453,91.1757992740300125],"rgb":[0.533333333333333326,0.866666666666666696,0.133333333333333331],"xyz":[0.362971376153177094,0.570613196038016635,0.106148661246086684],"hpluv":[114.966813202702411,210.937294411552,80.2140714473537315],"hsluv":[114.966813202702411,96.6732644510524,80.2140714473537315]},"#88dd33":{"lch":[80.283440325316,97.7612202004146695,115.666709499512805],"luv":[80.283440325316,-42.3438510501166832,88.1150069699792908],"rgb":[0.533333333333333326,0.866666666666666696,0.2],"xyz":[0.3660591268856348,0.571848296330999761,0.122410815103697834],"hpluv":[115.666709499512805,205.88559104418357,80.283440325316],"hsluv":[115.666709499512805,93.1672856447162303,80.283440325316]},"#88dd44":{"lch":[80.3834168948860821,93.7943752395521,116.732715571790365],"luv":[80.3834168948860821,-42.1914333437924896,83.7691338081886698],"rgb":[0.533333333333333326,0.866666666666666696,0.266666666666666663],"xyz":[0.370517122129853715,0.573631494428687327,0.145889590056584473],"hpluv":[116.732715571790365,198.714220363605108,80.3834168948860821],"hsluv":[116.732715571790365,88.1979852499996184,80.3834168948860821]},"#88dd55":{"lch":[80.5168087418625475,88.6629430887769,118.270203219525229],"luv":[80.5168087418625475,-41.9934519908601374,78.0875628192801088],"rgb":[0.533333333333333326,0.866666666666666696,0.333333333333333315],"xyz":[0.376479536169215701,0.576016460044432077,0.17729163733055836],"hpluv":[118.270203219525229,189.352414361266369,80.5168087418625475],"hsluv":[118.270203219525229,81.7170886524359474,80.5168087418625475]},"#88dd66":{"lch":[80.6859701106092757,82.4238546620344437,120.433562333743893],"luv":[80.6859701106092757,-41.7508898851674672,71.0672569552589266],"rgb":[0.533333333333333326,0.866666666666666696,0.4],"xyz":[0.384064531942723886,0.579050458353835396,0.21723928173770235],"hpluv":[120.433562333743893,177.835721711884361,80.6859701106092757],"hsluv":[120.433562333743893,73.7344666622195604,80.6859701106092757]},"#88dd77":{"lch":[80.8928858528116734,75.2114908165065827,123.458458278308711],"luv":[80.8928858528116734,-41.4665196955592208,62.7478772165182832],"rgb":[0.533333333333333326,0.866666666666666696,0.466666666666666674],"xyz":[0.393378544962925791,0.582776063561916247,0.266293083644100259],"hpluv":[123.458458278308711,164.332036041008877,80.8928858528116734],"hsluv":[123.458458278308711,64.312379996729149,80.8928858528116734]},"#88dd88":{"lch":[81.1392211885512,67.2590471315356524,127.71501294923884],"luv":[81.1392211885512,-41.1446687958856145,53.2061617739807531],"rgb":[0.533333333333333326,0.866666666666666696,0.533333333333333326],"xyz":[0.404518962064869592,0.587232230402693789,0.324965947047672399],"hpluv":[127.71501294923884,149.199726190229825,81.1392211885512],"hsluv":[127.71501294923884,53.5585775308776633,81.1392211885512]},"#88dd99":{"lch":[81.4263538436063072,58.943488890057,133.791370377408185],"luv":[81.4263538436063072,-40.7909253788266,42.5492102073736831],"rgb":[0.533333333333333326,0.866666666666666696,0.6],"xyz":[0.417575926173942347,0.592455016046323,0.393732624688790334],"hpluv":[133.791370377408185,133.11083868071384,81.4263538436063072],"hsluv":[133.791370377408185,54.8771054313611515,81.4263538436063072]},"#88ddaa":{"lch":[81.7553965772464437,50.8758256364689956,142.591286230634154],"luv":[81.7553965772464437,-40.4117997418374131,30.906893661738728],"rgb":[0.533333333333333326,0.866666666666666696,0.66666666666666663],"xyz":[0.432633619139194847,0.598478093232424069,0.473036474305788934],"hpluv":[142.591286230634154,117.302359569381537,81.7553965772464437],"hsluv":[142.591286230634154,56.3076629138628,81.7553965772464437]},"#88ddbb":{"lch":[82.1272144034785327,44.0521153731503716,155.27715859232552],"luv":[82.1272144034785327,-40.0143654100278567,18.4238820470094566],"rgb":[0.533333333333333326,0.866666666666666696,0.733333333333333282],"xyz":[0.449771211246531522,0.605333130075358827,0.563294459404430681],"hpluv":[155.27715859232552,104.020343594656595,82.1272144034785327],"hsluv":[155.27715859232552,57.829298146967858,82.1272144034785327]},"#88ddcc":{"lch":[82.542438979776648,39.9525966793572422,172.446474622419316],"luv":[82.542438979776648,-39.6059077008678173,5.25186220437346396],"rgb":[0.533333333333333326,0.866666666666666696,0.8],"xyz":[0.469063586690253276,0.613050080252847684,0.664900970074700837],"hpluv":[172.446474622419316,96.9346789585341355,82.542438979776648],"hsluv":[172.446474622419316,59.4202271347422908,82.542438979776648]},"#88dddd":{"lch":[83.0014816422074375,40.0957403917498354,192.177050630060734],"luv":[83.0014816422074375,-39.1936046909777,-8.4575261684472629],"rgb":[0.533333333333333326,0.866666666666666696,0.866666666666666696],"xyz":[0.490581912240886764,0.621657410473101191,0.778230817974706834],"hpluv":[192.177050630060734,100.308679558078737,83.0014816422074375],"hsluv":[192.177050630060734,61.0588228331018783,83.0014816422074375]},"#88ddee":{"lch":[83.5045459788204,44.8677054153188,210.184175125347622],"luv":[83.5045459788204,-38.7842593009493157,-22.5586395802706683],"rgb":[0.533333333333333326,0.866666666666666696,0.933333333333333348],"xyz":[0.514394092507061584,0.631182282579571208,0.903641634043230058],"hpluv":[210.184175125347622,116.175045715242419,83.5045459788204],"hsluv":[210.184175125347622,62.7244468832174746,83.5045459788204]},"#88ddff":{"lch":[84.0516404633952732,53.2556266987753659,223.883407592331508],"luv":[84.0516404633952732,-38.3840933399078779,-36.9164347351224436],"rgb":[0.533333333333333326,0.866666666666666696,1],"xyz":[0.540565140916892894,0.641650701943503932,1.04147582233501179],"hpluv":[223.883407592331508,143.298172182841085,84.0516404633952732],"hsluv":[223.883407592331508,99.9999999999952,84.0516404633952732]},"#335500":{"lch":[32.2593993637483862,41.1235506245754365,113.326494368716226],"luv":[32.2593993637483862,-16.2836990313566261,37.7622504868051223],"rgb":[0.2,0.333333333333333315,0],"xyz":[0.0461356744276991415,0.0720065112172806193,0.0114678000018764836],"hpluv":[113.326494368716226,161.760937136611716,32.2593993637483862],"hsluv":[113.326494368716226,100.000000000002288,32.2593993637483862]},"#335511":{"lch":[32.3496341583576381,38.1897920123001313,115.090818108356473],"luv":[32.3496341583576381,-16.1945453684027605,34.5860797757347456],"rgb":[0.2,0.333333333333333315,0.0666666666666666657],"xyz":[0.0471473399273362598,0.0724111774171354722,0.016795904966632115],"hpluv":[115.090818108356473,149.801873896373706,32.3496341583576381],"hsluv":[115.090818108356473,90.8995446090399923,32.3496341583576381]},"#335522":{"lch":[32.5160201858231659,33.1206139518783189,118.966642902489184],"luv":[32.5160201858231659,-16.0403246718637718,28.9772851207727022],"rgb":[0.2,0.333333333333333315,0.133333333333333331],"xyz":[0.0490226980658132819,0.0731613206725262866,0.0266727911626113111],"hpluv":[118.966642902489184,129.252907346834121,32.5160201858231659],"hsluv":[118.966642902489184,74.935129302234273,32.5160201858231659]},"#335533":{"lch":[32.7875119073456176,25.8516304293262671,127.715012949238741],"luv":[32.7875119073456176,-15.8143300747053051,20.4502753072602665],"rgb":[0.2,0.333333333333333315,0.2],"xyz":[0.0521104487982710224,0.0743964209655094,0.0429349450202224578],"hpluv":[127.715012949238741,100.050394151032577,32.7875119073456176],"hsluv":[127.715012949238741,50.9434831873252207,32.7875119073456176]},"#335544":{"lch":[33.1742322541989836,18.1915220066791647,148.674883917516439],"luv":[33.1742322541989836,-15.539762262897943,9.45765624941535421],"rgb":[0.2,0.333333333333333315,0.266666666666666663],"xyz":[0.0565684440424899,0.0761796190631969794,0.0664137199731090894],"hpluv":[148.674883917516439,69.5836942134034899,33.1742322541989836],"hsluv":[148.674883917516439,54.5088767633859703,33.1742322541989836]},"#335555":{"lch":[33.6821363315134121,15.5994691341387064,192.177050630060819],"luv":[33.6821363315134121,-15.2484882598238034,-3.29044724269541522],"rgb":[0.2,0.333333333333333315,0.333333333333333315],"xyz":[0.0625308580818519,0.0785645846789418123,0.097815767247083],"hpluv":[192.177050630060819,58.7691644617976934,33.6821363315134121],"hsluv":[192.177050630060819,58.539124710901028,33.6821363315134121]},"#335566":{"lch":[34.3136156967701496,22.6822476529859181,228.692277460856218],"luv":[34.3136156967701496,-14.9726179113300351,-17.0383412183435361],"rgb":[0.2,0.333333333333333315,0.4],"xyz":[0.0701158538553600663,0.0815985829883451308,0.137763411654226953],"hpluv":[228.692277460856218,83.8800984368335,34.3136156967701496],"hsluv":[228.692277460856218,62.7386213411417089,34.3136156967701496]},"#335577":{"lch":[35.0679836745485218,34.4527831327976131,244.673076132176305],"luv":[35.0679836745485218,-14.7383029974912176,-31.1412377780608658],"rgb":[0.2,0.333333333333333315,0.466666666666666674],"xyz":[0.0794298668755619858,0.0853241881964259402,0.186817213560624862],"hpluv":[244.673076132176305,124.667382519216758,35.0679836745485218],"hsluv":[244.673076132176305,66.8604241763398335,35.0679836745485218]},"#335588":{"lch":[35.9419713942028523,47.4274747217606318,252.117898483801355],"luv":[35.9419713942028523,-14.5630489263951493,-45.1362710516793229],"rgb":[0.2,0.333333333333333315,0.533333333333333326],"xyz":[0.0905702839775058138,0.089780355037203538,0.245490076964197029],"hpluv":[252.117898483801355,167.443168522882189,35.9419713942028523],"hsluv":[252.117898483801355,70.7327730687023433,35.9419713942028523]},"#335599":{"lch":[36.9302538454711851,60.4953772811161272,256.174865065393647],"luv":[36.9302538454711851,-14.4559426241851021,-58.7427986669927833],"rgb":[0.2,0.333333333333333315,0.6],"xyz":[0.103627248086578527,0.0950031406808327,0.314256754605314936],"hpluv":[256.174865065393647,207.863972679723531,36.9302538454711851],"hsluv":[256.174865065393647,74.2581677802949258,36.9302538454711851]},"#3355aa":{"lch":[38.0259842211890557,73.2582460718320903,258.648348715518409],"luv":[38.0259842211890557,-14.4194259870406505,-71.8251402485603165],"rgb":[0.2,0.333333333333333315,0.66666666666666663],"xyz":[0.118684941051831069,0.101026217866933804,0.393560604222313537],"hpluv":[258.648348715518409,244.464262316607687,38.0259842211890557],"hsluv":[258.648348715518409,77.3978910060545,38.0259842211890557]},"#3355bb":{"lch":[39.2213032744107579,85.5750988898230815,260.277622363739169],"luv":[39.2213032744107579,-14.4514388960387397,-84.3460340729607623],"rgb":[0.2,0.333333333333333315,0.733333333333333282],"xyz":[0.135822533159167702,0.107881254709868563,0.483818589320955283],"hpluv":[260.277622363739169,276.862869377010384,39.2213032744107579],"hsluv":[260.277622363739169,80.1529964351826578,39.2213032744107579]},"#3355cc":{"lch":[40.5077939091134667,97.4185991778777,261.412040351160215],"luv":[40.5077939091134667,-14.5472816309580448,-96.326320717286734],"rgb":[0.2,0.333333333333333315,0.8],"xyz":[0.155114908602889456,0.115598204887357364,0.585425099991225495],"hpluv":[261.412040351160215,305.17054630009352,40.5077939091134667],"hsluv":[261.412040351160215,82.5478264076183734,40.5077939091134667]},"#3355dd":{"lch":[41.8768615158020552,108.813506268261335,262.235450095721887],"luv":[41.8768615158020552,-14.7009821832840935,-107.815862790406285],"rgb":[0.2,0.333333333333333315,0.866666666666666696],"xyz":[0.176633234153523,0.124205535107610898,0.698754947891231493],"hpluv":[262.235450095721887,329.72206067647727,41.8768615158020552],"hsluv":[262.235450095721887,84.6180359154754456,41.8768615158020552]},"#3355ee":{"lch":[43.3200322197542533,119.805986402952101,262.852770803428143],"luv":[43.3200322197542533,-14.9061911990543372,-118.875059797762361],"rgb":[0.2,0.333333333333333315,0.933333333333333348],"xyz":[0.200445414419697737,0.133730407214080915,0.824165763959754716],"hpluv":[262.852770803428143,350.936931775297865,43.3200322197542533],"hsluv":[262.852770803428143,90.8055999978327577,43.3200322197542533]},"#3355ff":{"lch":[44.8291710285026497,130.447860525532377,263.327743444412704],"luv":[44.8291710285026497,-15.1567128937849134,-129.564340657235334],"rgb":[0.2,0.333333333333333315,1],"xyz":[0.226616462829529131,0.144198826578013639,0.961999952251536561],"hpluv":[263.327743444412704,369.245812735261836,44.8291710285026497],"hsluv":[263.327743444412704,99.9999999999993,44.8291710285026497]},"#aadd00":{"lch":[81.9783608763648175,97.3184216433040916,105.014728605041086],"luv":[81.9783608763648175,-25.2120246284188454,93.9958988747909245],"rgb":[0.66666666666666663,0.866666666666666696,0],"xyz":[0.424325128525832707,0.602582536713324846,0.0939549564608566229],"hpluv":[105.014728605041086,227.603505169437568,81.9783608763648175],"hsluv":[105.014728605041086,100.000000000002203,81.9783608763648175]},"#aadd11":{"lch":[82.0002885274849262,96.374791846509865,105.167446282879951],"luv":[82.0002885274849262,-25.2155818179290208,93.017605521973266],"rgb":[0.66666666666666663,0.866666666666666696,0.0666666666666666657],"xyz":[0.425336794025469811,0.602987202913179754,0.0992830614256122596],"hpluv":[105.167446282879951,225.71449396257529,82.0002885274849262],"hsluv":[105.167446282879951,98.8971907906987298,82.0002885274849262]},"#aadd22":{"lch":[82.0409106120811,94.6380623122949345,105.456830413527484],"luv":[82.0409106120811,-25.2222030700150874,91.2151484706391216],"rgb":[0.66666666666666663,0.866666666666666696,0.133333333333333331],"xyz":[0.427212152163946868,0.603737346168570554,0.109159947621591452],"hpluv":[105.456830413527484,222.227322886837186,82.0409106120811],"hsluv":[105.456830413527484,96.86659260915998,82.0409106120811]},"#aadd33":{"lch":[82.1077210543303693,91.8137349028061891,105.951891130476156],"luv":[82.1077210543303693,-25.2331804702422886,88.2782448860360773],"rgb":[0.66666666666666663,0.866666666666666696,0.2],"xyz":[0.430299902896404574,0.604972446461553681,0.125422101479202602],"hpluv":[105.951891130476156,216.526835376233663,82.1077210543303693],"hsluv":[105.951891130476156,93.5615293661406469,82.1077210543303693]},"#aadd44":{"lch":[82.204019596801416,87.812555976334508,106.710442618715334],"luv":[82.204019596801416,-25.2491908313752447,84.1042409718896238],"rgb":[0.66666666666666663,0.866666666666666696,0.266666666666666663],"xyz":[0.434757898140623489,0.606755644559241247,0.148900876432089241],"hpluv":[106.710442618715334,208.386709262610594,82.204019596801416],"hsluv":[106.710442618715334,88.8720213109455415,82.204019596801416]},"#aadd55":{"lch":[82.332521082647844,82.6008871447080537,107.814707884186447],"luv":[82.332521082647844,-25.2708912490316564,78.6402480449573],"rgb":[0.66666666666666663,0.866666666666666696,0.333333333333333315],"xyz":[0.440720312179985474,0.609140610174986,0.180302923706063156],"hpluv":[107.814707884186447,197.666387369374576,82.332521082647844],"hsluv":[107.814707884186447,82.7472331150865,82.332521082647844]},"#aadd66":{"lch":[82.495508489392364,76.2000100439918526,109.390646830849064],"luv":[82.495508489392364,-25.2989483474785786,71.8777068583581666],"rgb":[0.66666666666666663,0.866666666666666696,0.4],"xyz":[0.448305307953493659,0.612174608484389315,0.22025056811320709],"hpluv":[109.390646830849064,184.308617744019813,82.495508489392364],"hsluv":[109.390646830849064,75.1895211365387723,82.495508489392364]},"#aadd77":{"lch":[82.694914273715753,68.6905071379487,111.642517734809914],"luv":[82.694914273715753,-25.3340491820501299,63.8480361711309499],"rgb":[0.66666666666666663,0.866666666666666696,0.466666666666666674],"xyz":[0.457619320973695565,0.615900213692470166,0.269304370019605],"hpluv":[111.642517734809914,168.351618208890358,82.694914273715753],"hsluv":[111.642517734809914,66.2494286969421182,82.694914273715753]},"#aadd88":{"lch":[82.9323686283524921,60.2252781448786436,114.920875432447886],"luv":[82.9323686283524921,-25.3769003534370228,54.6177357282387277],"rgb":[0.66666666666666663,0.866666666666666696,0.533333333333333326],"xyz":[0.468759738075639365,0.620356380533247709,0.327977233423177195],"hpluv":[114.920875432447886,149.967217229555729,82.9323686283524921],"hsluv":[114.920875432447886,56.0198042099318698,82.9323686283524921]},"#aadd99":{"lch":[83.2092305924335,51.0640475908324305,119.865599423026282],"luv":[83.2092305924335,-25.4282188712646082,44.2825320120006438],"rgb":[0.66666666666666663,0.866666666666666696,0.6],"xyz":[0.481816702184712065,0.625579166176876922,0.396743911064295074],"hpluv":[119.865599423026282,129.562195810811914,83.2092305924335],"hsluv":[119.865599423026282,44.6286172342680487,83.2092305924335]},"#aaddaa":{"lch":[83.526609727912188,41.6663179647472717,127.715012949236481],"luv":[83.526609727912188,-25.4887175141036408,32.9606937461220255],"rgb":[0.66666666666666663,0.866666666666666696,0.66666666666666663],"xyz":[0.496874395149964621,0.631602243362978,0.476047760681293675],"hpluv":[127.715012949236481,108.050849780995421,83.526609727912188],"hsluv":[127.715012949236481,32.2306770176982198,83.526609727912188]},"#aaddbb":{"lch":[83.8853825066367449,32.9442078204095523,140.880295511025736],"luv":[83.8853825066367449,-25.5590871805440472,20.7859060762739638],"rgb":[0.66666666666666663,0.866666666666666696,0.733333333333333282],"xyz":[0.514011987257301239,0.638457280205912747,0.566305745779935421],"hpluv":[140.880295511025736,87.605014056209555,83.8853825066367449],"hsluv":[140.880295511025736,34.4766875289621382,83.8853825066367449]},"#aaddcc":{"lch":[84.2862057978904602,26.8294893367150316,162.87488866986746],"luv":[84.2862057978904602,-25.639978502468459,7.90018990036700242],"rgb":[0.66666666666666663,0.866666666666666696,0.8],"xyz":[0.533304362701023,0.646174230383401604,0.667912256450205577],"hpluv":[162.87488866986746,73.4171355960865526,84.2862057978904602],"hsluv":[162.87488866986746,36.8333761539634708,84.2862057978904602]},"#aadddd":{"lch":[84.729528894444158,26.3242685722419552,192.177050630060421],"luv":[84.729528894444158,-25.7319846477226655,-5.55266440124834],"rgb":[0.66666666666666663,0.866666666666666696,0.866666666666666696],"xyz":[0.554822688251656593,0.654781560603655111,0.781242104350211575],"hpluv":[192.177050630060421,74.4077864529294146,84.729528894444158],"hsluv":[192.177050630060421,39.269697519551606,84.729528894444158]},"#aaddee":{"lch":[85.2156049558348769,32.3281965376105802,216.94937298104162],"luv":[85.2156049558348769,-25.8356267715816657,-19.4327733659894548],"rgb":[0.66666666666666663,0.866666666666666696,0.933333333333333348],"xyz":[0.578634868517831302,0.664306432710125128,0.906652920418734798],"hpluv":[216.94937298104162,94.7745998726022094,85.2156049558348769],"hsluv":[216.94937298104162,58.4216362813771397,85.2156049558348769]},"#aaddff":{"lch":[85.744502396509489,42.4619511969095527,232.326067904807843],"luv":[85.744502396509489,-25.9513430438233641,-33.608705623253762],"rgb":[0.66666666666666663,0.866666666666666696,1],"xyz":[0.604805916927662723,0.674774852074057852,1.04448710871051675],"hpluv":[232.326067904807843,129.682154580054771,85.744502396509489],"hsluv":[232.326067904807843,99.9999999999945572,85.744502396509489]},"#88ee00":{"lch":[85.1906878331824515,112.448241602139106,116.535675589642423],"luv":[85.1906878331824515,-50.2368100475369914,100.602534538950536],"rgb":[0.533333333333333326,0.933333333333333348,0],"xyz":[0.40726312885557775,0.663815939263801891,0.106669928865523039],"hpluv":[116.535675589642423,329.03324103323672,85.1906878331824515],"hsluv":[116.535675589642423,100.000000000002416,85.1906878331824515]},"#88ee11":{"lch":[85.2112458075113182,111.594873497969587,116.730132104203335],"luv":[85.2112458075113182,-50.1941202672300193,99.669283541253],"rgb":[0.533333333333333326,0.933333333333333348,0.0666666666666666657],"xyz":[0.408274794355214854,0.664220605463656799,0.111998033830278676],"hpluv":[116.730132104203335,327.047318494663614,85.2112458075113182],"hsluv":[116.730132104203335,98.9939616796445,85.2112458075113182]},"#88ee22":{"lch":[85.2493327369145,110.025246585506409,117.096539077460619],"luv":[85.2493327369145,-50.115524286233132,97.9489107224652429],"rgb":[0.533333333333333326,0.933333333333333348,0.133333333333333331],"xyz":[0.410150152493691911,0.6649707487190476,0.121874920026257869],"hpluv":[117.096539077460619,323.384561507736407,85.2493327369145],"hsluv":[117.096539077460619,97.140453749143191,85.2493327369145]},"#88ee33":{"lch":[85.3119799721786,107.475578977757436,117.717135468026783],"luv":[85.3119799721786,-49.9876247553973769,95.1432469906181097],"rgb":[0.533333333333333326,0.933333333333333348,0.2],"xyz":[0.413237903226149617,0.666205849012030726,0.138137073883869],"hpluv":[117.717135468026783,317.406918528502,85.3119799721786],"hsluv":[117.717135468026783,94.120593299189423,85.3119799721786]},"#88ee44":{"lch":[85.4022915890189864,103.870397610997969,118.652974854946393],"luv":[85.4022915890189864,-49.8062112723248518,91.1504296126099],"rgb":[0.533333333333333326,0.933333333333333348,0.266666666666666663],"xyz":[0.417695898470368532,0.667989047109718292,0.161615848836755643],"hpluv":[118.652974854946393,308.894438519259097,85.4022915890189864],"hsluv":[118.652974854946393,89.8292917088674869,85.4022915890189864]},"#88ee55":{"lch":[85.5228293578601466,99.1885702075232,119.98340282305692],"luv":[85.5228293578601466,-49.5693999595221584,85.9141842041562],"rgb":[0.533333333333333326,0.933333333333333348,0.333333333333333315],"xyz":[0.423658312509730517,0.670374012725463,0.193017896110729559],"hpluv":[119.98340282305692,297.731707367046795,85.5228293578601466],"hsluv":[119.98340282305692,84.2131356884780473,85.5228293578601466]},"#88ee66":{"lch":[85.6757572108422,93.4644574192068234,121.818598205465591],"luv":[85.6757572108422,-49.2774194314266083,79.4187681524083189],"rgb":[0.533333333333333326,0.933333333333333348,0.4],"xyz":[0.431243308283238702,0.673408011034866361,0.232965540517873521],"hpluv":[121.818598205465591,283.912655540997662,85.6757572108422],"hsluv":[121.818598205465591,77.2651144072775082,85.6757572108422]},"#88ee77":{"lch":[85.8629182835971676,86.7937408847250822,124.317503927832064],"luv":[85.8629182835971676,-48.9324360738715,71.6852157466327071],"rgb":[0.533333333333333326,0.933333333333333348,0.466666666666666674],"xyz":[0.440557321303440608,0.677133616242947212,0.282019342424271402],"hpluv":[124.317503927832064,267.563092583833793,85.8629182835971676],"hsluv":[124.317503927832064,69.0205357789205749,85.8629182835971676]},"#88ee88":{"lch":[86.0858807036169793,79.3454652904755164,127.71501294923921],"luv":[86.0858807036169793,-48.5383458294846,62.7672832477191918],"rgb":[0.533333333333333326,0.933333333333333348,0.533333333333333326],"xyz":[0.451697738405384408,0.681589783083724754,0.340692205827843597],"hpluv":[127.71501294923921,248.989760930573482,86.0858807036169793],"hsluv":[127.71501294923921,59.5524101967812,86.0858807036169793]},"#88ee99":{"lch":[86.3459670558122525,71.3853284581525429,132.362204285947513],"luv":[86.3459670558122525,-48.1005130697284287,52.7466184841000825],"rgb":[0.533333333333333326,0.933333333333333348,0.6],"xyz":[0.464754702514457163,0.686812568727354,0.409458883468961532],"hpluv":[132.362204285947513,228.778132650246619,86.3459670558122525],"hsluv":[132.362204285947513,60.5562348819982645,86.3459670558122525]},"#88eeaa":{"lch":[86.6442747471204768,63.319361027400987,138.776693085718904],"luv":[86.6442747471204768,-47.625461320552418,41.7271723811105204],"rgb":[0.533333333333333326,0.933333333333333348,0.66666666666666663],"xyz":[0.479812395479709664,0.692835645913455,0.488762733085960077],"hpluv":[138.776693085718904,207.981038552319745,86.6442747471204768],"hsluv":[138.776693085718904,61.6537348625427342,86.6442747471204768]},"#88eebb":{"lch":[86.9816911545789679,55.7684583245382299,147.664608842749317],"luv":[86.9816911545789679,-47.1205330954276,29.8291184029711189],"rgb":[0.533333333333333326,0.933333333333333348,0.733333333333333282],"xyz":[0.496949987587046338,0.699690682756389792,0.579020718184601879],"hpluv":[147.664608842749317,188.458500832318975,86.9816911545789679],"hsluv":[147.664608842749317,62.830800627143077,86.9816911545789679]},"#88eecc":{"lch":[87.3589058048410294,49.6608679924305463,159.75715297219557],"luv":[87.3589058048410294,-46.5935415809549696,17.182656741768227],"rgb":[0.533333333333333326,0.933333333333333348,0.8],"xyz":[0.516242363030768092,0.70740763293387865,0.680627228854872],"hpluv":[159.75715297219557,173.371642714007834,87.3589058048410294],"hsluv":[159.75715297219557,64.0722902507549179,87.3589058048410294]},"#88eedd":{"lch":[87.7764209496729,46.2191498548509543,175.132102674355139],"luv":[87.7764209496729,-46.0524373199716166,3.92209512827700335],"rgb":[0.533333333333333326,0.933333333333333348,0.866666666666666696],"xyz":[0.53776068858140158,0.716014963154132156,0.793957076754878],"hpluv":[175.132102674355139,167.447502067072264,87.7764209496729],"hsluv":[175.132102674355139,65.3626972838926434,87.7764209496729]},"#88eeee":{"lch":[88.2345613859691866,46.5524177333431339,192.177050630060933],"luv":[88.2345613859691866,-45.5050097647113958,-9.8194543195231],"rgb":[0.533333333333333326,0.933333333333333348,0.933333333333333348],"xyz":[0.56157286884757629,0.725539835260602173,0.919367892823401256],"hpluv":[192.177050630060933,175.887543813927181,88.2345613859691866],"hsluv":[192.177050630060933,66.6867488369664443,88.2345613859691866]},"#88eeff":{"lch":[88.7334840469836763,50.9233073192915242,208.009521596121829],"luv":[88.7334840469836763,-44.9586380478967271,-23.9145163700465169],"rgb":[0.533333333333333326,0.933333333333333348,1],"xyz":[0.587743917257407711,0.736008254624534897,1.05720208111518299],"hpluv":[208.009521596121829,201.749007974481685,88.7334840469836763],"hsluv":[208.009521596121829,99.9999999999925109,88.7334840469836763]},"#336600":{"lch":[38.2101034680229574,51.4017776291135888,118.130952889189317],"luv":[38.2101034680229574,-24.2353400261634,45.3298029694491902],"rgb":[0.2,0.4,0],"xyz":[0.0611637321335456105,0.10206262662897396,0.0164771525704918292],"hpluv":[118.130952889189317,170.702252266418213,38.2101034680229574],"hsluv":[118.130952889189317,100.000000000002288,38.2101034680229574]},"#336611":{"lch":[38.2816545292110959,48.9828222693822468,119.470954908934345],"luv":[38.2816545292110959,-24.0986808399199681,42.6447002480913682],"rgb":[0.2,0.4,0.0666666666666666657],"xyz":[0.0621753976331827357,0.102467292828828813,0.021805257535247459],"hpluv":[119.470954908934345,162.365005406289157,38.2816545292110959],"hsluv":[119.470954908934345,93.5286374368429,38.2816545292110959]},"#336622":{"lch":[38.4137944304132617,44.7307250918699282,122.230818066602779],"luv":[38.4137944304132617,-23.8562978467226365,37.8380076152656173],"rgb":[0.2,0.4,0.133333333333333331],"xyz":[0.0640507557716597509,0.103217436084219627,0.0316821437312266585],"hpluv":[122.230818066602779,147.760399550800031,38.4137944304132617],"hsluv":[122.230818066602779,81.994947572555219,38.4137944304132617]},"#336633":{"lch":[38.6299730126545171,38.3921679396875817,127.715012949239437],"luv":[38.6299730126545171,-23.4858075099586969,30.3706339201924216],"rgb":[0.2,0.4,0.2],"xyz":[0.0671385065041174844,0.10445253637720274,0.0479442975888378],"hpluv":[127.715012949239437,126.112332565807833,38.6299730126545171],"hsluv":[127.715012949239437,64.2136550115152,38.6299730126545171]},"#336644":{"lch":[38.9390987599147635,30.7877900918170191,138.353415806708398],"luv":[38.9390987599147635,-23.0064236741332095,20.4595329483365589],"rgb":[0.2,0.4,0.266666666666666663],"xyz":[0.0715965017483363719,0.10623573447489032,0.0714230725417244472],"hpluv":[138.353415806708398,100.330262339301328,38.9390987599147635],"hsluv":[138.353415806708398,66.1490613915476899,38.9390987599147635]},"#336655":{"lch":[39.3471830293532108,24.0314899024670439,159.111050143656939],"luv":[39.3471830293532108,-22.4519783641565418,8.56861566811244479],"rgb":[0.2,0.4,0.333333333333333315],"xyz":[0.077558915787698357,0.108620700090635153,0.102825119815698349],"hpluv":[159.111050143656939,77.5008343503898089,39.3471830293532108],"hsluv":[159.111050143656939,68.4324421599544337,39.3471830293532108]},"#336666":{"lch":[39.8577781510875653,22.3660784387423632,192.177050630061],"luv":[39.8577781510875653,-21.8628519700770774,-4.71775036033837925],"rgb":[0.2,0.4,0.4],"xyz":[0.0851439115612065422,0.111654698400038471,0.142772764222842297],"hpluv":[192.177050630061,71.205917149352544,39.8577781510875653],"hsluv":[192.177050630061,70.9271962998489727,39.8577781510875653]},"#336677":{"lch":[40.4722660639059,28.403364995264031,221.483563289625266],"luv":[40.4722660639059,-21.2782609928981294,-18.8145356618838697],"rgb":[0.2,0.4,0.466666666666666674],"xyz":[0.0944579245814084478,0.115380303608119281,0.191826566129240206],"hpluv":[221.483563289625266,89.0536244466218534,40.4722660639059],"hsluv":[221.483563289625266,73.4989606489913,40.4722660639059]},"#336688":{"lch":[41.1901179582142731,39.1584560294521253,238.034471274574031],"luv":[41.1901179582142731,-20.7308371309926542,-33.2207325394668516],"rgb":[0.2,0.4,0.533333333333333326],"xyz":[0.105598341683352276,0.119836470448896878,0.250499429532812401],"hpluv":[238.034471274574031,120.634589470818128,41.1901179582142731],"hsluv":[238.034471274574031,76.0346320246428746,41.1901179582142731]},"#336699":{"lch":[42.0091634944821948,51.6886413393569626,246.942440261812],"luv":[42.0091634944821948,-20.2441498032976277,-47.5593318103852951],"rgb":[0.2,0.4,0.6],"xyz":[0.118655305792425,0.12505925609252605,0.31926610717393028],"hpluv":[246.942440261812,156.131455895945,42.0091634944821948],"hsluv":[246.942440261812,78.4511744564818514,42.0091634944821948]},"#3366aa":{"lch":[42.9258754740709847,64.6951641030825,252.148217293940775],"luv":[42.9258754740709847,-19.832670948043944,-61.5802681172418218],"rgb":[0.2,0.4,0.66666666666666663],"xyz":[0.133712998757677531,0.131082333278627144,0.398569956790928881],"hpluv":[252.148217293940775,191.245834212653307,42.9258754740709847],"hsluv":[252.148217293940775,80.6959595489171,42.9258754740709847]},"#3366bb":{"lch":[43.9356615222631106,77.6311657782158164,255.449757662516049],"luv":[43.9356615222631106,-19.5031901130623,-75.1413566253536374],"rgb":[0.2,0.4,0.733333333333333282],"xyz":[0.150850590865014178,0.137937370121561903,0.488827941889570627],"hpluv":[255.449757662516049,224.211696450950683,43.9356615222631106],"hsluv":[255.449757662516049,82.7420790911240402,43.9356615222631106]},"#3366cc":{"lch":[45.0331492258045287,90.2591849706621332,257.681278432902445],"luv":[45.0331492258045287,-19.2567634880452658,-88.1810497302775786],"rgb":[0.2,0.4,0.8],"xyz":[0.170142966308735932,0.145654320299050705,0.590434452559840839],"hpluv":[257.681278432902445,254.330482568364204,45.0331492258045287],"hsluv":[257.681278432902445,84.5818015821218694,45.0331492258045287]},"#3366dd":{"lch":[46.2124513047425367,102.485732700579547,259.264483160570819],"luv":[46.2124513047425367,-19.0906003056708045,-100.691977769551045],"rgb":[0.2,0.4,0.866666666666666696],"xyz":[0.191661291859369476,0.154261650519304239,0.703764300459846837],"hpluv":[259.264483160570819,281.412724566330553,46.2124513047425367],"hsluv":[259.264483160570819,86.2202337385041488,46.2124513047425367]},"#3366ee":{"lch":[47.467400384741687,114.289765210034219,260.43068521754094],"luv":[47.467400384741687,-18.99960653492559,-112.699447129445844],"rgb":[0.2,0.4,0.933333333333333348],"xyz":[0.215473472125544213,0.163786522625774256,0.82917511652837006],"hpluv":[260.43068521754094,305.528142270574733,47.467400384741687],"hsluv":[260.43068521754094,89.4216395109538524,47.467400384741687]},"#3366ff":{"lch":[48.7917470574018068,125.686826272807437,261.315666926990161],"luv":[48.7917470574018068,-18.9775194272026404,-124.245853270525785],"rgb":[0.2,0.4,1],"xyz":[0.241644520535375606,0.17425494198970698,0.967009304820151905],"hpluv":[261.315666926990161,326.875761207371056,48.7917470574018068],"hsluv":[261.315666926990161,99.9999999999992184,48.7917470574018068]},"#aaee00":{"lch":[86.8465682321076713,106.130019137569278,108.773889799394041],"luv":[86.8465682321076713,-34.1562767274136,100.483479847491182],"rgb":[0.66666666666666663,0.933333333333333348,0],"xyz":[0.471503904866347523,0.696940089394355811,0.109681215241027807],"hpluv":[108.773889799394041,354.560190530248747,86.8465682321076713],"hsluv":[108.773889799394041,100.000000000002302,86.8465682321076713]},"#aaee11":{"lch":[86.8664697406872364,105.275413073012288,108.926122010215039],"luv":[86.8664697406872364,-34.1459453835818323,99.5839696515197801],"rgb":[0.66666666666666663,0.933333333333333348,0.0666666666666666657],"xyz":[0.472515570365984627,0.697344755594210719,0.115009320205783444],"hpluv":[108.926122010215039,352.296735211520456,86.8664697406872364],"hsluv":[108.926122010215039,99.0448212343627,86.8664697406872364]},"#aaee22":{"lch":[86.9033414770782286,103.701584155213482,109.21343759479339],"luv":[86.9033414770782286,-34.1269596340241961,97.9253245204656224],"rgb":[0.66666666666666663,0.933333333333333348,0.133333333333333331],"xyz":[0.474390928504461684,0.69809489884960152,0.124886206401762637],"hpluv":[109.21343759479339,348.114419217609168,86.9033414770782286],"hsluv":[109.21343759479339,97.2844700630890742,86.9033414770782286]},"#aaee33":{"lch":[86.9639927659971,101.139559122436452,109.701502859778287],"luv":[86.9639927659971,-34.0961634116812462,95.2190215245081504],"rgb":[0.66666666666666663,0.933333333333333348,0.2],"xyz":[0.47747867923691939,0.699329999142584646,0.141148360259373773],"hpluv":[109.701502859778287,341.266668172598315,86.9639927659971],"hsluv":[109.701502859778287,94.4148698146506,86.9639927659971]},"#aaee44":{"lch":[87.0514332975086091,97.5044422856038864,110.440992284795044],"luv":[87.0514332975086091,-34.052698770047833,91.3648180204122298],"rgb":[0.66666666666666663,0.933333333333333348,0.266666666666666663],"xyz":[0.481936674481138305,0.701113197240272212,0.164627135212260411],"hpluv":[110.440992284795044,331.464832239423686,87.0514332975086091],"hsluv":[110.440992284795044,90.3338544995677353,87.0514332975086091]},"#aaee55":{"lch":[87.1681505263978,92.7597711807761556,111.499860176168639],"luv":[87.1681505263978,-33.9963593100021271,86.3054036730909644],"rgb":[0.66666666666666663,0.933333333333333348,0.333333333333333315],"xyz":[0.48789908852050029,0.703498162856017,0.196029182486234327],"hpluv":[111.499860176168639,318.513853400728863,87.1681505263978],"hsluv":[111.499860176168639,84.9871568734489813,87.1681505263978]},"#aaee66":{"lch":[87.3162499846890086,86.9168013961255923,112.975973936880195],"luv":[87.3162499846890086,-33.9275471197994563,80.0215715377255492],"rgb":[0.66666666666666663,0.933333333333333348,0.4],"xyz":[0.495484084294008476,0.70653216116542028,0.235976826893378289],"hpluv":[112.975973936880195,302.308385752370668,87.3162499846890086],"hsluv":[112.975973936880195,78.3634586897027106,87.3162499846890086]},"#aaee77":{"lch":[87.4975302296396,80.0378594698754853,115.017197938190947],"luv":[87.4975302296396,-33.8472328521792534,72.5287789554594298],"rgb":[0.66666666666666663,0.933333333333333348,0.466666666666666674],"xyz":[0.504798097314210326,0.710257766373501132,0.285030628799776198],"hpluv":[115.017197938190947,282.845349503141222,87.4975302296396],"hsluv":[115.017197938190947,70.4907283307095,87.4975302296396]},"#aaee88":{"lch":[87.7135274362348838,72.2451165326571072,117.856267937731204],"luv":[87.7135274362348838,-33.7569011423620324,63.8735351149597861],"rgb":[0.66666666666666663,0.933333333333333348,0.533333333333333326],"xyz":[0.515938514416154237,0.714713933214278674,0.343703492203348393],"hpluv":[117.856267937731204,260.261444274219798,87.7135274362348838],"hsluv":[117.856267937731204,61.4321883079204412,87.7135274362348838]},"#aaee99":{"lch":[87.9655440812905312,63.7405265694191954,121.874104620002555],"luv":[87.9655440812905312,-33.6584769753751445,54.1291202131068871],"rgb":[0.66666666666666663,0.933333333333333348,0.6],"xyz":[0.528995478525226881,0.719936718857907887,0.412470169844466272],"hpluv":[121.874104620002555,234.922523447188695,87.9655440812905312],"hsluv":[121.874104620002555,51.2814060811362182,87.9655440812905312]},"#aaeeaa":{"lch":[88.2546687059401,54.8509913255605497,127.715012949237604],"luv":[88.2546687059401,-33.5542349686064441,43.3906045713616138],"rgb":[0.66666666666666663,0.933333333333333348,0.66666666666666663],"xyz":[0.544053171490479492,0.725959796044009,0.491774019461464873],"hpluv":[127.715012949237604,207.631017102058365,88.2546687059401],"hsluv":[127.715012949237604,42.8122115000723795,88.2546687059401]},"#aaeebb":{"lch":[88.5817905154621457,46.1299748711590425,136.47329364537066],"luv":[88.5817905154621457,-33.4466969972147226,31.7693726974624511],"rgb":[0.66666666666666663,0.933333333333333348,0.733333333333333282],"xyz":[0.561190763597816056,0.732814832886943712,0.582032004560106619],"hpluv":[136.47329364537066,180.106084736741337,88.5817905154621457],"hsluv":[136.47329364537066,42.5306558804052,88.5817905154621457]},"#aaeecc":{"lch":[88.947610994722524,38.5659339652702471,149.820563383504265],"luv":[88.947610994722524,-33.3385252257337896,19.3874701388989088],"rgb":[0.66666666666666663,0.933333333333333348,0.8],"xyz":[0.58048313904153781,0.740531783064432569,0.683638515230376775],"hpluv":[149.820563383504265,156.025185046421541,88.947610994722524],"hsluv":[149.820563383504265,43.7743007306855176,88.947610994722524]},"#aaeedd":{"lch":[89.3526538659385636,33.8378115459028308,169.14561851222],"luv":[89.3526538659385636,-33.2324178366612202,6.37211856022751721],"rgb":[0.66666666666666663,0.933333333333333348,0.866666666666666696],"xyz":[0.602001464592171409,0.749139113284686076,0.796968363130382773],"hpluv":[169.14561851222,142.575756051086472,89.3526538659385636],"hsluv":[169.14561851222,45.7128350403065866,89.3526538659385636]},"#aaeeee":{"lch":[89.797274219494,33.893604395025335,192.177050630060734],"luv":[89.797274219494,-33.1310138990311174,-7.14928925898844092],"rgb":[0.66666666666666663,0.933333333333333348,0.933333333333333348],"xyz":[0.625813644858346119,0.758663985391156093,0.922379179198906],"hpluv":[192.177050630060734,149.574468983420843,89.797274219494],"hsluv":[192.177050630060734,47.7079369778472326,89.797274219494]},"#aaeeff":{"lch":[90.2816673401601406,39.1749897548907384,212.508271358442045],"luv":[90.2816673401601406,-33.0368122621910558,-21.0534761464356919],"rgb":[0.66666666666666663,0.933333333333333348,1],"xyz":[0.65198469326817754,0.769132404755088817,1.06021336749068773],"hpluv":[212.508271358442045,182.211685385120148,90.2816673401601406],"hsluv":[212.508271358442045,99.9999999999910898,90.2816673401601406]},"#88ff00":{"lch":[90.2073775103659727,121.530167505498795,118.25137340908573],"luv":[90.2073775103659727,-57.5251845782800331,107.053420090856534],"rgb":[0.533333333333333326,1,0],"xyz":[0.459115501285251582,0.767520684123151,0.12395405300874715],"hpluv":[118.25137340908573,560.639311859311,90.2073775103659727],"hsluv":[118.25137340908573,100.00000000000226,90.2073775103659727]},"#88ff11":{"lch":[90.2260397586701828,120.75410845816802,118.424372307304225],"luv":[90.2260397586701828,-57.4787561773275684,106.196738640291272],"rgb":[0.533333333333333326,1,0.0666666666666666657],"xyz":[0.460127166784888686,0.767925350323005906,0.129282157973502787],"hpluv":[118.424372307304225,558.207032378019221,90.2260397586701828],"hsluv":[118.424372307304225,99.9999999999909335,90.2260397586701828]},"#88ff22":{"lch":[90.260617257984066,119.32542599803422,118.749452026898098],"luv":[90.260617257984066,-57.393189210317729,104.616342518179295],"rgb":[0.533333333333333326,1,0.133333333333333331],"xyz":[0.462002524923365743,0.768675493578396707,0.139159044169481966],"hpluv":[118.749452026898098,553.71568515647823,90.260617257984066],"hsluv":[118.749452026898098,99.9999999999907772,90.260617257984066]},"#88ff33":{"lch":[90.3174996442954665,117.001153508636776,119.297411154505227],"luv":[90.3174996442954665,-57.253701051451273,102.035697862378711],"rgb":[0.533333333333333326,1,0.2],"xyz":[0.465090275655823449,0.769910593871379834,0.155421198027093116],"hpluv":[119.297411154505227,546.370637823869743,90.3174996442954665],"hsluv":[119.297411154505227,99.9999999999907914,90.3174996442954665]},"#88ff44":{"lch":[90.399517385893148,113.706822542904789,120.117552028257023],"luv":[90.399517385893148,-57.0553255590242614,98.3561452994036074],"rgb":[0.533333333333333326,1,0.266666666666666663],"xyz":[0.469548270900042364,0.7716937919690674,0.178899972979979754],"hpluv":[120.117552028257023,535.877566613280692,90.399517385893148],"hsluv":[120.117552028257023,99.9999999999907914,90.399517385893148]},"#88ff55":{"lch":[90.5090160073098389,109.413894688598035,121.271093020798972],"luv":[90.5090160073098389,-56.7954345723420317,93.518334901057969],"rgb":[0.533333333333333326,1,0.333333333333333315],"xyz":[0.475510684939404349,0.774078757584812149,0.21030202025395367],"hpluv":[121.271093020798972,522.05545338002139,90.5090160073098389],"hsluv":[121.271093020798972,99.9999999999906493,90.5090160073098389]},"#88ff66":{"lch":[90.6479884721694,104.139810410505333,122.839359042112989],"luv":[90.6479884721694,-56.4735097148607039,87.4976731851854908],"rgb":[0.533333333333333326,1,0.4],"xyz":[0.483095680712912534,0.777112755894215468,0.250249664661097659],"hpluv":[122.839359042112989,504.839052288882328,90.6479884721694],"hsluv":[122.839359042112989,99.9999999999905498,90.6479884721694]},"#88ff77":{"lch":[90.8181461195308515,97.9515013566305441,124.934550835890477],"luv":[90.8181461195308515,-56.0909812525741813,80.3012978733306],"rgb":[0.533333333333333326,1,0.466666666666666674],"xyz":[0.49240969373311444,0.780838361102296319,0.299303466567495513],"hpluv":[124.934550835890477,484.301391198376791,90.8181461195308515],"hsluv":[124.934550835890477,99.9999999999904,90.8181461195308515]},"#88ff88":{"lch":[91.0209609702079803,90.9725812653771,127.715012949239437],"luv":[91.0209609702079803,-55.6510519447396348,71.9650676337452779],"rgb":[0.533333333333333326,1,0.533333333333333326],"xyz":[0.503550110835058295,0.785294527943073861,0.357976329971067708],"hpluv":[127.715012949239437,460.703998076760797,91.0209609702079803],"hsluv":[127.715012949239437,99.9999999999902087,91.0209609702079803]},"#88ff99":{"lch":[91.2576929391802167,83.3964386150156116,131.406800448379954],"luv":[91.2576929391802167,-55.158478848678719,62.5500454417735057],"rgb":[0.533333333333333326,1,0.6],"xyz":[0.51660707494413094,0.790517313586703074,0.426743007612185643],"hpluv":[131.406800448379954,434.595507650037121,91.2576929391802167],"hsluv":[131.406800448379954,99.9999999999900524,91.2576929391802167]},"#88ffaa":{"lch":[91.5294084976530229,75.5094657025462226,136.33125230150921],"luv":[91.5294084976530229,-54.6193101996060264,52.1383770748881048],"rgb":[0.533333333333333326,1,0.66666666666666663],"xyz":[0.531664767909383551,0.796540390772804141,0.506046857229184188],"hpluv":[136.33125230150921,406.99849880976177,91.5294084976530229],"hsluv":[136.33125230150921,99.9999999999897824,91.5294084976530229]},"#88ffbb":{"lch":[91.8369943060547911,67.7301008509963225,142.928263991524119],"luv":[91.8369943060547911,-54.0405872892441,40.8286846067776423],"rgb":[0.533333333333333326,1,0.733333333333333282],"xyz":[0.548802360016720114,0.8033954276157389,0.596304842327826],"hpluv":[142.928263991524119,379.751065707187763,91.8369943060547911],"hsluv":[142.928263991524119,99.9999999999894413,91.8369943060547911]},"#88ffcc":{"lch":[92.1811678623774498,60.665065650155249,151.731515164157571],"luv":[92.1811678623774498,-53.4300279465168941,28.7312078404662543],"rgb":[0.533333333333333326,1,0.8],"xyz":[0.568094735460441869,0.811112377793227757,0.697911352998096146],"hpluv":[151.731515164157571,356.080713038752435,92.1811678623774498],"hsluv":[151.731515164157571,99.9999999999893134,92.1811678623774498]},"#88ffdd":{"lch":[92.5624864174544371,55.1561732277505712,163.177123134509742],"luv":[92.5624864174544371,-52.7957106082625316,15.9629692256241533],"rgb":[0.533333333333333326,1,0.866666666666666696],"xyz":[0.589613061011075468,0.819719708013481263,0.811241200898102144],"hpluv":[163.177123134509742,341.369587308077,92.5624864174544371],"hsluv":[163.177123134509742,99.9999999999887,92.5624864174544371]},"#88ffee":{"lch":[92.9813549493531752,52.2127257219241301,177.098205352907513],"luv":[92.9813549493531752,-52.1457771028834927,2.64322864112605771],"rgb":[0.533333333333333326,1,0.933333333333333348],"xyz":[0.613425241277250177,0.82924458011995128,0.936652016966625367],"hpluv":[177.098205352907513,343.566349205584061,92.9813549493531752],"hsluv":[177.098205352907513,99.9999999999882,92.9813549493531752]},"#88ffff":{"lch":[93.4380337051328524,52.6732939730945162,192.177050630061075],"luv":[93.4380337051328524,-51.4881691068088543,-11.1105508416409933],"rgb":[0.533333333333333326,1,1],"xyz":[0.639596289687081598,0.839712999483884,1.07448620525840721],"hpluv":[192.177050630061075,372.044084252862206,93.4380337051328524],"hsluv":[192.177050630061075,99.9999999999874802,93.4380337051328524]},"#337700":{"lch":[44.0848685544221084,61.4877933810524127,120.932619831412623],"luv":[44.0848685544221084,-31.6065510805688668,52.7425318283298168],"rgb":[0.2,0.466666666666666674,0],"xyz":[0.0796174701869632462,0.138970102735809731,0.0226283985882975332],"hpluv":[120.932619831412623,176.985906279588789,44.0848685544221084],"hsluv":[120.932619831412623,100.000000000002217,44.0848685544221084]},"#337711":{"lch":[44.1431322932100159,59.4532082216814146,121.943929432148849],"luv":[44.1431322932100159,-31.4560442613915434,50.449987584497805],"rgb":[0.2,0.466666666666666674,0.0666666666666666657],"xyz":[0.0806291356866003645,0.139374768935664584,0.0279565035530531664],"hpluv":[121.943929432148849,170.903703930819205,44.1431322932100159],"hsluv":[121.943929432148849,95.223210781581642,44.1431322932100159]},"#337722":{"lch":[44.2508401312458517,55.8308883755444327,123.957293362486936],"luv":[44.2508401312458517,-31.1857277137109214,46.3091619851707605],"rgb":[0.2,0.466666666666666674,0.133333333333333331],"xyz":[0.0825044938250774,0.140124912191055412,0.037833389749032359],"hpluv":[123.957293362486936,160.100373243526178,44.2508401312458517],"hsluv":[123.957293362486936,86.6219708852072,44.2508401312458517]},"#337733":{"lch":[44.4273451577554681,50.2894934834324943,127.715012949239792],"luv":[44.4273451577554681,-30.7638100974309978,39.782171171385329],"rgb":[0.2,0.466666666666666674,0.2],"xyz":[0.0855922445575351271,0.141360012484038511,0.0540955436066435091],"hpluv":[127.715012949239792,143.636966976451419,44.4273451577554681],"hsluv":[127.715012949239792,73.1368174441878409,44.4273451577554681]},"#337744":{"lch":[44.6803728315295743,43.2379901525315873,134.305487238163835],"luv":[44.6803728315295743,-30.2010367205865329,30.9422231494797764],"rgb":[0.2,0.466666666666666674,0.266666666666666663],"xyz":[0.090050239801754,0.143143210581726105,0.0775743185595301477],"hpluv":[134.305487238163835,122.797079037201513,44.6803728315295743],"hsluv":[134.305487238163835,74.2422920898123664,44.6803728315295743]},"#337755":{"lch":[45.0155248592042057,35.7001949681147,145.791078733963843],"luv":[45.0155248592042057,-29.5238129364495734,20.071083439987369],"rgb":[0.2,0.466666666666666674,0.333333333333333315],"xyz":[0.096012653841116,0.145528176197470938,0.108976365833504049],"hpluv":[145.791078733963843,100.634662922797503,45.0155248592042057],"hsluv":[145.791078733963843,75.5860232244433377,45.0155248592042057]},"#337766":{"lch":[45.436632811343884,29.7520619336037022,165.22669317203713],"luv":[45.436632811343884,-28.7685269489331041,7.58663604567268468],"rgb":[0.2,0.466666666666666674,0.4],"xyz":[0.103597649614624171,0.148562174506874228,0.148924010240648025],"hpluv":[165.22669317203713,83.0902864995861847,45.436632811343884],"hsluv":[165.22669317203713,77.1054195363406194,45.436632811343884]},"#337777":{"lch":[45.9459628200325696,28.6191137838588361,192.177050630061018],"luv":[45.9459628200325696,-27.9751968985082726,-6.03672363647301413],"rgb":[0.2,0.466666666666666674,0.466666666666666674],"xyz":[0.11291166263482609,0.152287779714955052,0.197977812147045934],"hpluv":[192.177050630061018,79.0402219352416324,45.9459628200325696],"hsluv":[192.177050630061018,78.7308353184449743,45.9459628200325696]},"#337788":{"lch":[46.5443737533918309,33.948531272854666,216.805091226728479],"luv":[46.5443737533918309,-27.1818468531358306,-20.3383867904182836],"rgb":[0.2,0.466666666666666674,0.533333333333333326],"xyz":[0.124052079736769919,0.156743946555732649,0.256650675550618101],"hpluv":[216.805091226728479,92.5535593562344587,46.5443737533918309],"hsluv":[216.805091226728479,80.3955897349876381,46.5443737533918309]},"#337799":{"lch":[47.2314677007312085,43.7891028043947799,232.889035089769209],"luv":[47.2314677007312085,-26.4206199262946413,-34.9204290798973105],"rgb":[0.2,0.466666666666666674,0.6],"xyz":[0.137109043845842632,0.161966732199361807,0.325417353191736],"hpluv":[232.889035089769209,117.645124104106614,47.2314677007312085],"hsluv":[232.889035089769209,82.0429045074046144,47.2314677007312085]},"#3377aa":{"lch":[48.0057466772197472,55.756363166772573,242.534195481556935],"luv":[48.0057466772197472,-25.7159019754829359,-49.471854818395343],"rgb":[0.2,0.466666666666666674,0.66666666666666663],"xyz":[0.15216673681109516,0.167989809385462902,0.404721202808734581],"hpluv":[242.534195481556935,147.380673097935755,48.0057466772197472],"hsluv":[242.534195481556935,83.6292827510673078,48.0057466772197472]},"#3377bb":{"lch":[48.8647777502949623,68.5281348418467076,248.528316013511841],"luv":[48.8647777502949623,-25.0841318464231762,-63.7721851155626],"rgb":[0.2,0.466666666666666674,0.733333333333333282],"xyz":[0.169304328918431835,0.17484484622839766,0.494979187907376328],"hpluv":[248.528316013511841,177.955866809146045,48.8647777502949623],"hsluv":[248.528316013511841,85.1249045257873,48.8647777502949623]},"#3377cc":{"lch":[49.8053630390326845,81.4640551302433096,252.471981644912631],"luv":[49.8053630390326845,-24.5347040681135518,-77.6816617648812553],"rgb":[0.2,0.466666666666666674,0.8],"xyz":[0.188596704362153561,0.182561796405886462,0.596585698577646539],"hpluv":[252.471981644912631,207.553107999557341,49.8053630390326845],"hsluv":[252.471981644912631,86.5120902950020678,49.8053630390326845]},"#3377dd":{"lch":[50.8237086019957047,94.2508792352234,255.202895611269554],"luv":[50.8237086019957047,-24.0713820337122506,-91.1251710758325],"rgb":[0.2,0.466666666666666674,0.866666666666666696],"xyz":[0.210115029912787105,0.19116912662614,0.709915546477652537],"hpluv":[255.202895611269554,235.319753343529385,50.8237086019957047],"hsluv":[255.202895611269554,87.7828608732328,50.8237086019957047]},"#3377ee":{"lch":[51.9155858415672498,106.73807185779232,257.174602046687482],"luv":[51.9155858415672498,-23.6937959642247655,-104.075069141100855],"rgb":[0.2,0.466666666666666674,0.933333333333333348],"xyz":[0.233927210178961842,0.200693998732610041,0.83532636254617576],"hpluv":[257.174602046687482,260.892095272406607,51.9155858415672498],"hsluv":[257.174602046687482,88.9363454602875692,51.9155858415672498]},"#3377ff":{"lch":[53.0764799083082721,118.861737619173724,258.646767383963777],"luv":[53.0764799083082721,-23.3987809317452253,-116.535873106771263],"rgb":[0.2,0.466666666666666674,1],"xyz":[0.260098258588793207,0.211162418096542737,0.973160550837957605],"hpluv":[258.646767383963777,284.170694785425781,53.0764799083082721],"hsluv":[258.646767383963777,99.9999999999990763,53.0764799083082721]},"#aaff00":{"lch":[91.7137860391432156,115.080534629040301,111.722667154579099],"luv":[91.7137860391432156,-42.5929524944460596,106.908230966149674],"rgb":[0.66666666666666663,1,0],"xyz":[0.523356277296021299,0.800644834253704918,0.126965339384251918],"hpluv":[111.722667154579099,635.020942157405898,91.7137860391432156],"hsluv":[111.722667154579099,100.000000000002359,91.7137860391432156]},"#aaff11":{"lch":[91.7319300755291209,114.302910123776968,111.867287470019974],"luv":[91.7319300755291209,-42.5730312099484394,106.078707931238455],"rgb":[0.66666666666666663,1,0.0666666666666666657],"xyz":[0.524367942795658459,0.801049500453559826,0.132293444349007555],"hpluv":[111.867287470019974,632.205251281199821,91.7319300755291209],"hsluv":[111.867287470019974,99.9999999999902087,91.7319300755291209]},"#aaff22":{"lch":[91.76554812600844,112.870020698142184,112.139393409643191],"luv":[91.76554812600844,-42.5363318976714595,104.548084827461963],"rgb":[0.66666666666666663,1,0.133333333333333331],"xyz":[0.526243300934135405,0.801799643708950627,0.142170330544986734],"hpluv":[112.139393409643191,626.996151229530483,91.76554812600844],"hsluv":[112.139393409643191,99.9999999999901,91.76554812600844]},"#aaff33":{"lch":[91.8208541183991116,110.535111156119868,112.599114759903571],"luv":[91.8208541183991116,-42.4765495373732875,102.047800258971023],"rgb":[0.66666666666666663,1,0.2],"xyz":[0.529331051666593222,0.803034744001933753,0.158432484402597884],"hpluv":[112.599114759903571,618.449193227995465,91.8208541183991116],"hsluv":[112.599114759903571,99.9999999999900808,91.8208541183991116]},"#aaff44":{"lch":[91.9006031807778498,107.217215837920833,113.289723447654],"luv":[91.9006031807778498,-42.3916247074254713,98.4808688360338],"rgb":[0.66666666666666663,1,0.266666666666666663],"xyz":[0.533789046910812082,0.80481794209962132,0.181911259355484523],"hpluv":[113.289723447654,606.175591066234915,91.9006031807778498],"hsluv":[113.289723447654,99.9999999999900808,91.9006031807778498]},"#aaff55":{"lch":[92.0070808640835338,102.877427982590888,114.266397603879824],"luv":[92.0070808640835338,-42.2805422001356135,93.7876374559873796],"rgb":[0.66666666666666663,1,0.333333333333333315],"xyz":[0.539751460950174,0.807202907715366069,0.213313306629458438],"hpluv":[114.266397603879824,589.885725054723707,92.0070808640835338],"hsluv":[114.266397603879824,99.9999999999897,92.0070808640835338]},"#aaff66":{"lch":[92.142232175119787,97.5178938455906,115.604656391492952],"luv":[92.142232175119787,-42.1432392632638226,87.9413839126902559],"rgb":[0.66666666666666663,1,0.4],"xyz":[0.547336456723682252,0.810236906024769388,0.2532609510366024],"hpluv":[115.604656391492952,569.381090837871511,92.142232175119787],"hsluv":[115.604656391492952,99.9999999999898,92.142232175119787]},"#aaff77":{"lch":[92.3077308115560555,91.1840841453542197,117.412488820025033],"luv":[92.3077308115560555,-41.9805406670279666,80.9454841651530899],"rgb":[0.66666666666666663,1,0.466666666666666674],"xyz":[0.556650469743884102,0.813962511232850239,0.302314752943000309],"hpluv":[117.412488820025033,544.56608764574878,92.3077308115560555],"hsluv":[117.412488820025033,99.9999999999895692,92.3077308115560555]},"#aaff88":{"lch":[92.5050204995058749,83.9705472319660657,119.849478645386625],"luv":[92.5050204995058749,-41.7940850853900727,72.8306752289927601],"rgb":[0.66666666666666663,1,0.533333333333333326],"xyz":[0.567790886845828,0.818418678073627781,0.360987616346572504],"hpluv":[119.849478645386625,515.487838204951345,92.5050204995058749],"hsluv":[119.849478645386625,99.9999999999892708,92.5050204995058749]},"#aaff99":{"lch":[92.7353415895377,76.0327408171719,123.158131820453576],"luv":[92.7353415895377,-41.5862309318022625,63.6518897838709137],"rgb":[0.66666666666666663,1,0.6],"xyz":[0.580847850954900657,0.823641463717257,0.429754293987690383],"hpluv":[123.158131820453576,482.430180447041607,92.7353415895377],"hsluv":[123.158131820453576,99.9999999999891145,92.7353415895377]},"#aaffaa":{"lch":[92.9997492696274435,67.6109506527765802,127.715012949238414],"luv":[92.9997492696274435,-41.3599402641421108,53.4845397242865488],"rgb":[0.66666666666666663,1,0.66666666666666663],"xyz":[0.595905543920153269,0.829664540903358061,0.509058143604689],"hpluv":[127.715012949238414,446.121940639593902,92.9997492696274435],"hsluv":[127.715012949238414,99.9999999999887308,92.9997492696274435]},"#aaffbb":{"lch":[93.2991268167713201,59.0781485982363,134.10730048328],"luv":[93.2991268167713201,-41.1186450338129887,42.4203332421914823],"rgb":[0.66666666666666663,1,0.733333333333333282],"xyz":[0.613043136027489832,0.836519577746292819,0.599316128703330731],"hpluv":[134.10730048328,408.190288953842469,93.2991268167713201],"hsluv":[134.10730048328,99.9999999999883613,93.2991268167713201]},"#aaffcc":{"lch":[93.6341958749929404,51.0306218960527929,143.208028901391231],"luv":[93.6341958749929404,-40.8661030238149436,30.5628204644932246],"rgb":[0.66666666666666663,1,0.8],"xyz":[0.632335511471211587,0.844236527923781677,0.700922639373600886],"hpluv":[143.208028901391231,372.11656739719416,93.6341958749929404],"hsluv":[143.208028901391231,99.9999999999879492,93.6341958749929404]},"#aaffdd":{"lch":[94.005524978734,44.4262644213682094,156.066165366624773],"luv":[94.005524978734,-40.6062520520773305,18.0229094410556279],"rgb":[0.66666666666666663,1,0.866666666666666696],"xyz":[0.653853837021845186,0.852843858144035183,0.814252487273606884],"hpluv":[156.066165366624773,345.018188987702331,94.005524978734],"hsluv":[156.066165366624773,99.999999999986926,94.005524978734]},"#aaffee":{"lch":[94.4135370960349576,40.641316399200953,173.054449077896464],"luv":[94.4135370960349576,-40.3430708217409446,4.91459411670529711],"rgb":[0.66666666666666663,1,0.933333333333333348],"xyz":[0.677666017288019895,0.8623687302505052,0.939663303342130107],"hpluv":[173.054449077896464,339.745490646316398,94.4135370960349576],"hsluv":[173.054449077896464,99.9999999999862865,94.4135370960349576]},"#aaffff":{"lch":[94.8585166918378633,41.0030022313427764,192.177050630060705],"luv":[94.8585166918378633,-40.0804535568370639,-8.64889788711415264],"rgb":[0.66666666666666663,1,1],"xyz":[0.703837065697851316,0.872837149614437924,1.07749749163391195],"hpluv":[192.177050630060705,373.711432895013843,94.8585166918378633],"hsluv":[192.177050630060705,99.9999999999852491,94.8585166918378633]},"#338800":{"lch":[49.8717454753508918,71.2965557675853461,122.69380865426514],"luv":[49.8717454753508918,-38.5107906934601871,60.0009821960016509],"rgb":[0.2,0.533333333333333326,0],"xyz":[0.101689839911933699,0.183114842185751275,0.0299858551632874795],"hpluv":[122.69380865426514,181.406693814272955,49.8717454753508918],"hsluv":[122.69380865426514,100.000000000002245,49.8717454753508918]},"#338811":{"lch":[49.9202331837381053,69.5570511040883162,123.47043015419375],"luv":[49.9202331837381053,-38.361169332567485,58.0224443274741475],"rgb":[0.2,0.533333333333333326,0.0666666666666666657],"xyz":[0.102701505411570818,0.183519508385606128,0.0353139601280431092],"hpluv":[123.47043015419375,176.808802540010674,49.9202331837381053],"hsluv":[123.47043015419375,96.3624965314944291,49.9202331837381053]},"#338822":{"lch":[50.0099282713402,66.4316762124597915,124.985970570646856],"luv":[50.0099282713402,-38.0903182709230137,54.426971791721833],"rgb":[0.2,0.533333333333333326,0.133333333333333331],"xyz":[0.104576863550047847,0.184269651640996956,0.0451908463240223088],"hpluv":[124.985970570646856,168.561468288507513,50.0099282713402],"hsluv":[124.985970570646856,89.7672781446156876,50.0099282713402]},"#338833":{"lch":[50.1570811029395429,61.5658815699287487,127.715012949239991],"luv":[50.1570811029395429,-37.6619639194057143,48.7025076070614134],"rgb":[0.2,0.533333333333333326,0.2],"xyz":[0.10766461428250558,0.185504751933980055,0.061453000181633452],"hpluv":[127.715012949239991,155.756856758587162,50.1570811029395429],"hsluv":[127.715012949239991,79.3080015418374416,50.1570811029395429]},"#338844":{"lch":[50.3683877843642165,55.1600753981733334,132.238380805917416],"luv":[50.3683877843642165,-37.0795228857786441,40.8380080377971524],"rgb":[0.2,0.533333333333333326,0.266666666666666663],"xyz":[0.112122609526724454,0.187287950031667649,0.0849317751345200905],"hpluv":[132.238380805917416,138.965222681713072,50.3683877843642165],"hsluv":[132.238380805917416,79.9701630926319922,50.3683877843642165]},"#338855":{"lch":[50.648916869713247,47.7759983149871488,139.558488969535745],"luv":[50.648916869713247,-36.3608093871966886,30.990926990033774],"rgb":[0.2,0.533333333333333326,0.333333333333333315],"xyz":[0.118085023566086453,0.189672915647412482,0.116333822408493992],"hpluv":[139.558488969535745,119.695806374350084,50.648916869713247],"hsluv":[139.558488969535745,80.7922551095087726,50.648916869713247]},"#338866":{"lch":[51.0024095938582747,40.50700493167151,151.3112863122482],"luv":[51.0024095938582747,-35.5343950908498,19.4454162738124445],"rgb":[0.2,0.533333333333333326,0.4],"xyz":[0.125670019339594624,0.192706913956815773,0.156281466815637954],"hpluv":[151.3112863122482,100.78102351571394,51.0024095938582747],"hsluv":[151.3112863122482,81.7453783644028249,51.0024095938582747]},"#338877":{"lch":[51.4314426692160964,35.2513066472794421,169.271441625736571],"luv":[51.4314426692160964,-34.635118433957949,6.56225505495134165],"rgb":[0.2,0.533333333333333326,0.466666666666666674],"xyz":[0.134984032359796557,0.196432519164896596,0.205335268722035863],"hpluv":[169.271441625736571,86.9732781104886499,51.4314426692160964],"hsluv":[169.271441625736571,82.7938072280844182,51.4314426692160964]},"#338888":{"lch":[51.9375397067754818,34.4751674240590873,192.177050630061075],"luv":[51.9375397067754818,-33.6994920276336458,-7.27196025816705482],"rgb":[0.2,0.533333333333333326,0.533333333333333326],"xyz":[0.146124449461740358,0.200888686005674194,0.26400813212560803],"hpluv":[192.177050630061075,84.229522237058,51.9375397067754818],"hsluv":[192.177050630061075,83.8998231764876579,51.9375397067754818]},"#338899":{"lch":[52.5212658253882267,39.2899369869163,213.503984387174484],"luv":[52.5212658253882267,-32.7618132949538179,-21.68784770470414],"rgb":[0.2,0.533333333333333326,0.6],"xyz":[0.159181413570813085,0.206111471649303352,0.332774809766725965],"hpluv":[213.503984387174484,94.9260641143146415,52.5212658253882267],"hsluv":[213.503984387174484,85.0278067813718081,52.5212658253882267]},"#3388aa":{"lch":[53.1823203703714142,48.3403865273999855,228.783963154055925],"luv":[53.1823203703714142,-31.8514822326876157,-36.3631138545534753],"rgb":[0.2,0.533333333333333326,0.66666666666666663],"xyz":[0.174239106536065613,0.212134548835404446,0.412078659383724566],"hpluv":[228.783963154055925,115.340588590435829,53.1823203703714142],"hsluv":[228.783963154055925,86.1470646970195588,53.1823203703714142]},"#3388bb":{"lch":[53.9196335036436238,59.7107302664646866,238.732819450220632],"luv":[53.9196335036436238,-30.9916356267104831,-51.0381213421469],"rgb":[0.2,0.533333333333333326,0.733333333333333282],"xyz":[0.191376698643402288,0.218989585678339205,0.502336644482366257],"hpluv":[238.732819450220632,140.522147305520861,53.9196335036436238],"hsluv":[238.732819450220632,87.2332789223686262,53.9196335036436238]},"#3388cc":{"lch":[54.7314676322995268,72.1439684856409826,245.254262274299492],"luv":[54.7314676322995268,-30.1989009668194051,-65.5192992121664446],"rgb":[0.2,0.533333333333333326,0.8],"xyz":[0.210669074087124014,0.226706535855828,0.603943155152636413],"hpluv":[245.254262274299492,167.263916186866481,54.7314676322995268],"hsluv":[245.254262274299492,88.2687848362996,54.7314676322995268]},"#3388dd":{"lch":[55.6155220749816692,84.9545141717074728,249.692682338977761],"luv":[55.6155220749816692,-29.4839257322198733,-79.6741338300441697],"rgb":[0.2,0.533333333333333326,0.866666666666666696],"xyz":[0.232187399637757558,0.23531386607608154,0.717273003052642411],"hpluv":[249.692682338977761,193.833915517882872,55.6155220749816692],"hsluv":[249.692682338977761,89.2420383366021923,55.6155220749816692]},"#3388ee":{"lch":[56.5690381344568323,97.7754852991564434,252.83721230554255],"luv":[56.5690381344568323,-28.8523290085395629,-93.4215640859675602],"rgb":[0.2,0.533333333333333326,0.933333333333333348],"xyz":[0.255999579903932295,0.244838738182551585,0.842683819121165634],"hpluv":[252.83721230554255,219.32619909500923,56.5690381344568323],"hsluv":[252.83721230554255,90.146641202583325,56.5690381344568323]},"#3388ff":{"lch":[57.5889013880528182,110.410831334845568,255.145344615238457],"luv":[57.5889013880528182,-28.3057941013035759,-106.720821287817699],"rgb":[0.2,0.533333333333333326,1],"xyz":[0.282170628313763716,0.255307157546484254,0.980518007412947479],"hpluv":[255.145344615238457,243.283252172694205,57.5889013880528182],"hsluv":[255.145344615238457,99.9999999999988489,57.5889013880528182]},"#339900":{"lch":[55.5688440832231,80.82821284508357,123.866754715109295],"luv":[55.5688440832231,-45.0426054376311527,67.1145564473163603],"rgb":[0.2,0.6,0],"xyz":[0.127559440364401172,0.23485404309068697,0.0386090553141097345],"hpluv":[123.866754715109295,184.574176757765827,55.5688440832231],"hsluv":[123.866754715109295,100.00000000000226,55.5688440832231]},"#339911":{"lch":[55.6099261578814463,79.3206910999707446,124.475743785225987],"luv":[55.6099261578814463,-44.9000555787807372,65.3892731692238556],"rgb":[0.2,0.6,0.0666666666666666657],"xyz":[0.128571105864038304,0.235258709290541823,0.0439371602788653642],"hpluv":[124.475743785225987,180.997883954149785,55.6099261578814463],"hsluv":[124.475743785225987,97.1571693172972601,55.6099261578814463]},"#339922":{"lch":[55.6859569378682124,76.5942224429011418,125.649114872203555],"luv":[55.6859569378682124,-44.6406262928881503,62.240576763164114],"rgb":[0.2,0.6,0.133333333333333331],"xyz":[0.130446464002515305,0.236008852545932651,0.0538140464748445638],"hpluv":[125.649114872203555,174.537861698610129,55.6859569378682124],"hsluv":[125.649114872203555,91.9778413864117113,55.6859569378682124]},"#339933":{"lch":[55.8107903110879278,72.2971425020977563,127.715012949240148],"luv":[55.8107903110879278,-44.2266447414942618,57.191613973364035],"rgb":[0.2,0.6,0.2],"xyz":[0.133534214734973067,0.23724395283891575,0.070076200332455707],"hpluv":[127.715012949240148,164.377468022308932,55.8107903110879278],"hsluv":[127.715012949240148,83.6974291768240874,55.8107903110879278]},"#339944":{"lch":[55.9902586993563602,66.5149718399310501,131.021169741293448],"luv":[55.9902586993563602,-43.6562926505411042,50.1833597009719128],"rgb":[0.2,0.6,0.266666666666666663],"xyz":[0.137992209979191927,0.239027150936603344,0.0935549752853423455],"hpluv":[131.021169741293448,150.746162046382238,55.9902586993563602],"hsluv":[131.021169741293448,84.1112663411127386,55.9902586993563602]},"#339955":{"lch":[56.2289015921924,59.572114639014508,136.121417864766215],"luv":[56.2289015921924,-42.9401916463123783,41.2913645202220323],"rgb":[0.2,0.6,0.333333333333333315],"xyz":[0.143954624018553912,0.241412116552348177,0.124957022559316261],"hpluv":[136.121417864766215,134.438216783596687,56.2289015921924],"hsluv":[136.121417864766215,84.6329955380286236,56.2289015921924]},"#339966":{"lch":[56.5302268191487514,52.1043875673731947,143.898662284026642],"luv":[56.5302268191487514,-42.0991012865816785,30.700698275986678],"rgb":[0.2,0.6,0.4],"xyz":[0.151539619792062097,0.244446114861751468,0.164904666966460223],"hpluv":[143.898662284026642,116.958797396111564,56.5302268191487514],"hsluv":[143.898662284026642,85.2491724948614689,56.5302268191487514]},"#339977":{"lch":[56.8968484427531678,45.1992705399313124,155.596009487994166],"luv":[56.8968484427531678,-41.1609366004351855,18.6748856895258584],"rgb":[0.2,0.6,0.466666666666666674],"xyz":[0.160853632812264,0.248171720069832291,0.213958468872858132],"hpluv":[155.596009487994166,100.805108459810327,56.8968484427531678],"hsluv":[155.596009487994166,85.9413862611579873,56.8968484427531678]},"#339988":{"lch":[57.330574208667926,40.5351988689668303,172.17134267960472],"luv":[57.330574208667926,-40.1574041849560217,5.52134371985359085],"rgb":[0.2,0.6,0.533333333333333326],"xyz":[0.171994049914207858,0.252627886910609889,0.272631332276430272],"hpluv":[172.17134267960472,89.7191897797317,57.330574208667926],"hsluv":[172.17134267960472,86.6885468018933665,57.330574208667926]},"#339999":{"lch":[57.8324724587931627,40.0212192418936539,192.177050630061103],"luv":[57.8324724587931627,-39.1207602326874735,-8.44180717763071],"rgb":[0.2,0.6,0.6],"xyz":[0.185051014023280558,0.257850672554239047,0.341398009917548206],"hpluv":[192.177050630061103,87.8128114771670312,57.8324724587931627],"hsluv":[192.177050630061103,87.4690863712762194,57.8324724587931627]},"#3399aa":{"lch":[58.4029323329449568,44.4430671798845367,211.035048784986628],"luv":[58.4029323329449568,-38.0811346860811923,-22.913170914918652],"rgb":[0.2,0.6,0.66666666666666663],"xyz":[0.200108706988533114,0.263873749740340169,0.420701859534546807],"hpluv":[211.035048784986628,96.5625435737210154,58.4029323329449568],"hsluv":[211.035048784986628,88.2627766327166,58.4029323329449568]},"#3399bb":{"lch":[59.0417237507550823,52.8166449153409445,225.431517702392057],"luv":[59.0417237507550823,-37.064675814253917,-37.6272213549907448],"rgb":[0.2,0.6,0.733333333333333282],"xyz":[0.217246299095869733,0.270728786583274927,0.510959844633188554],"hpluv":[225.431517702392057,113.514439229551684,59.0417237507550823],"hsluv":[225.431517702392057,89.0519907331041196,59.0417237507550823]},"#3399cc":{"lch":[59.7480598269018373,63.5982744854026194,235.423336237979868],"luv":[59.7480598269018373,-36.0925574956591646,-52.364757336811472],"rgb":[0.2,0.6,0.8],"xyz":[0.236538674539591487,0.278445736760763729,0.612566355303458709],"hpluv":[235.423336237979868,135.070607162709791,59.7480598269018373],"hsluv":[235.423336237979868,89.8223822716188636,59.7480598269018373]},"#3399dd":{"lch":[60.5206621982976856,75.6357863680042186,242.281144195606601],"luv":[60.5206621982976856,-35.1807304699237235,-66.9558689220665286],"rgb":[0.2,0.6,0.866666666666666696],"xyz":[0.25805700009022503,0.287053066981017235,0.725896203203464707],"hpluv":[242.281144195606601,158.58531958905732,60.5206621982976856],"hsluv":[242.281144195606601,90.5630616197976508,60.5206621982976856]},"#3399ee":{"lch":[61.3578284965586818,88.2341933332873083,247.095644636752098],"luv":[61.3578284965586818,-34.3402162860227946,-81.277441019049661],"rgb":[0.2,0.6,0.933333333333333348],"xyz":[0.28186918035639974,0.296577939087487252,0.85130701927198793],"hpluv":[247.095644636752098,182.476215369006297,61.3578284965586818],"hsluv":[247.095644636752098,91.2664056494933504,61.3578284965586818]},"#3399ff":{"lch":[62.2575005434706554,100.992674077385175,250.5808182685887],"luv":[62.2575005434706554,-33.5777301361133595,-95.2473425151972],"rgb":[0.2,0.6,1],"xyz":[0.308040228766231161,0.30704635845142,0.989141207563769775],"hpluv":[250.5808182685887,205.84367033720622,62.2575005434706554],"hsluv":[250.5808182685887,99.9999999999985789,62.2575005434706554]},"#220000":{"lch":[3.07250446727781679,10.3329293192956264,12.1770506300617765],"luv":[3.07250446727781679,10.1004431663672367,2.17955870775360072],"rgb":[0.133333333333333331,0,0],"xyz":[0.00659672420629513,0.00340143591887099878,0.000309221447170077699],"hpluv":[12.1770506300617765,426.746789183125429,3.07250446727781679],"hsluv":[12.1770506300617765,100.000000000002217,3.07250446727781679]},"#220011":{"lch":[3.43803794680403607,8.12070857757986353,344.488545895364155],"luv":[3.43803794680403607,7.82492808895188574,-2.17172931202554675],"rgb":[0.133333333333333331,0,0.0666666666666666657],"xyz":[0.00760838970593225201,0.00380610211872585338,0.00563732641192570948],"hpluv":[344.488545895364155,299.724735916282839,3.43803794680403607],"hsluv":[344.488545895364155,99.9999999999976836,3.43803794680403607]},"#220022":{"lch":[4.11563957101797229,9.37475958111893348,307.715012949243601],"luv":[4.11563957101797229,5.73486236359989565,-7.41602797151862436],"rgb":[0.133333333333333331,0,0.133333333333333331],"xyz":[0.00948374784440927,0.00455624537411667124,0.0155142126079049047],"hpluv":[307.715012949243601,289.042783730483393,4.11563957101797229],"hsluv":[307.715012949243601,99.9999999999988205,4.11563957101797229]},"#220033":{"lch":[5.23130109110515384,14.2535250315243012,286.735013267555587],"luv":[5.23130109110515384,4.10424250296207127,-13.6498413654214126],"rgb":[0.133333333333333331,0,0.2],"xyz":[0.0125714985768670112,0.00579134566709978496,0.0317763664655160497],"hpluv":[286.735013267555587,345.74180296647927,5.23130109110515384],"hsluv":[286.735013267555587,99.9999999999995737,5.23130109110515384]},"#220044":{"lch":[6.84205732813722722,21.3889830656619786,277.641816515271671],"luv":[6.84205732813722722,2.84430225454687724,-21.1990221771654959],"rgb":[0.133333333333333331,0,0.266666666666666663],"xyz":[0.01702949382108589,0.0075745437647873606,0.0552551414184026882],"hpluv":[277.641816515271671,396.682237683346386,6.84205732813722722],"hsluv":[277.641816515271671,100.000000000000085,6.84205732813722722]},"#220055":{"lch":[8.95766614306443,30.4428627575942237,273.263558660643355],"luv":[8.95766614306443,1.73308321478426808,-30.3934913336449455],"rgb":[0.133333333333333331,0,0.333333333333333315],"xyz":[0.0229919078604478855,0.00995950938053219263,0.0866571886923766],"hpluv":[273.263558660643355,431.250830347711485,8.95766614306443],"hsluv":[273.263558660643355,100.000000000000242,8.95766614306443]},"#220066":{"lch":[11.2709410858812937,40.3162667149428913,270.881506896841],"luv":[11.2709410858812937,0.620249265146302853,-40.3114952920317435],"rgb":[0.133333333333333331,0,0.4],"xyz":[0.0305769036339560568,0.0129935076899355059,0.126604833099520558],"hpluv":[270.881506896841,453.899240935372916,11.2709410858812937],"hsluv":[270.881506896841,100.000000000000469,11.2709410858812937]},"#220077":{"lch":[13.6616791408408957,50.492834518379162,269.459540268375122],"luv":[13.6616791408408957,-0.476281836738408071,-50.4905881656414763],"rgb":[0.133333333333333331,0,0.466666666666666674],"xyz":[0.0398909166541579763,0.0167191128980163223,0.175658635005918468],"hpluv":[269.459540268375122,468.991527020998944,13.6616791408408957],"hsluv":[269.459540268375122,100.000000000000711,13.6616791408408957]},"#220088":{"lch":[16.0923146306383913,60.7890037695263104,268.549935621017426],"luv":[16.0923146306383913,-1.53830805749361632,-60.7695366743217278],"rgb":[0.133333333333333331,0,0.533333333333333326],"xyz":[0.0510313337561018043,0.0211752797387939132,0.234331498409490635],"hpluv":[268.549935621017426,479.34239057424071,16.0923146306383913],"hsluv":[268.549935621017426,100.000000000000711,16.0923146306383913]},"#220099":{"lch":[18.5394450926422749,71.1015482986176437,267.936483797094468],"luv":[18.5394450926422749,-2.56017951479828287,-71.0554406876254916],"rgb":[0.133333333333333331,0,0.6],"xyz":[0.0640882978651745178,0.0263980653824230742,0.30309817605060857],"hpluv":[267.936483797094468,486.655519564945394,18.5394450926422749],"hsluv":[267.936483797094468,100.000000000000739,18.5394450926422749]},"#2200aa":{"lch":[20.9885603179873783,81.3727160976321,267.505178931910336],"luv":[20.9885603179873783,-3.54207977840461252,-81.2955878012407851],"rgb":[0.133333333333333331,0,0.66666666666666663],"xyz":[0.0791459908304270598,0.0324211425685241791,0.382402025667607171],"hpluv":[267.505178931910336,491.966452636739518,20.9885603179873783],"hsluv":[267.505178931910336,100.000000000000782,20.9885603179873783]},"#2200bb":{"lch":[23.4306921856835828,91.57073581353,267.191578225858507],"luv":[23.4306921856835828,-4.48665301772878333,-91.4607544366971155],"rgb":[0.133333333333333331,0,0.733333333333333282],"xyz":[0.0962835829377637,0.0392761794114589377,0.472660010766248917],"hpluv":[267.191578225858507,495.919187528698728,23.4306921856835828],"hsluv":[267.191578225858507,100.000000000000909,23.4306921856835828]},"#2200cc":{"lch":[25.860342630381858,101.678845182637474,266.957159441292106],"luv":[25.860342630381858,-5.39738007409318588,-101.535490573545474],"rgb":[0.133333333333333331,0,0.8],"xyz":[0.115575958381485447,0.0469931295889477393,0.574266521436519],"hpluv":[266.957159441292106,498.925449111647538,25.860342630381858],"hsluv":[266.957159441292106,100.000000000000881,25.860342630381858]},"#2200dd":{"lch":[28.2742062228116282,111.689036790699618,266.777814373778199],"luv":[28.2742062228116282,-6.27782958394359714,-111.512464751476173],"rgb":[0.133333333333333331,0,0.866666666666666696],"xyz":[0.137094283932118977,0.0556004598092012733,0.687596369336525],"hpluv":[266.777814373778199,501.255846139694427,28.2742062228116282],"hsluv":[266.777814373778199,100.000000000000838,28.2742062228116282]},"#2200ee":{"lch":[30.6703766456275062,121.598437280905173,266.637867063772376],"luv":[30.6703766456275062,-7.13133722672581882,-121.389142753859758],"rgb":[0.133333333333333331,0,0.933333333333333348],"xyz":[0.160906464198293714,0.0651253319156713,0.813007185405048238],"hpluv":[266.637867063772376,503.092926092128948,30.6703766456275062],"hsluv":[266.637867063772376,100.000000000000838,30.6703766456275062]},"#2200ff":{"lch":[33.0478477502328261,131.407178056457695,266.526788769360394],"luv":[33.0478477502328261,-7.96089030872800674,-131.165813649189772],"rgb":[0.133333333333333331,0,1],"xyz":[0.187077512608125107,0.0755937512796040073,0.950841373696830083],"hpluv":[266.526788769360394,504.562807291912918,33.0478477502328261],"hsluv":[266.526788769360394,100.000000000000824,33.0478477502328261]},"#221100":{"lch":[6.69363913087575835,9.72440836304526535,42.3457761997067053],"luv":[6.69363913087575835,7.18724369375563921,6.55039282011655288],"rgb":[0.133333333333333331,0.0666666666666666657,0],"xyz":[0.00860112446722354,0.00741023644072787233,0.000977354867479528471],"hpluv":[42.3457761997067053,184.348759610596915,6.69363913087575835],"hsluv":[42.3457761997067053,100.000000000002402,6.69363913087575835]},"#221111":{"lch":[7.0591726104019763,6.19439175917428564,12.1770506300621],"luv":[7.0591726104019763,6.05502079617615863,1.30660339200560327],"rgb":[0.133333333333333331,0.0666666666666666657,0.0666666666666666657],"xyz":[0.00961278996686066103,0.00781490264058272606,0.00630545983223516],"hpluv":[12.1770506300621,111.348454543071412,7.0591726104019763],"hsluv":[12.1770506300621,26.092394217240134,7.0591726104019763]},"#221122":{"lch":[7.73677423461591474,7.55259268754738677,307.715012949245249],"luv":[7.73677423461591474,4.62018030186617779,-5.97457866985129],"rgb":[0.133333333333333331,0.0666666666666666657,0.133333333333333331],"xyz":[0.0114881481053376797,0.00856504589597354565,0.0161823460282143547],"hpluv":[307.715012949245249,123.872660774597591,7.73677423461591474],"hsluv":[307.715012949245249,42.856167926372315,7.73677423461591474]},"#221133":{"lch":[8.8238329822443653,14.9761175001236957,282.095598903329574],"luv":[8.8238329822443653,3.13814740657790647,-14.6436377390353236],"rgb":[0.133333333333333331,0.0666666666666666657,0.2],"xyz":[0.0145758988377954202,0.00980014618895665851,0.0324444998858255],"hpluv":[282.095598903329574,215.36805510923017,8.8238329822443653],"hsluv":[282.095598903329574,58.3941618505161273,8.8238329822443653]},"#221144":{"lch":[10.2463738670161,23.9334379374521049,274.255517801158362],"luv":[10.2463738670161,1.77596948547040223,-23.8674544912638211],"rgb":[0.133333333333333331,0.0666666666666666657,0.266666666666666663],"xyz":[0.0190338940820143,0.011583344286644235,0.0559232748387121364],"hpluv":[274.255517801158362,296.397281412249697,10.2463738670161],"hsluv":[274.255517801158362,70.1230959508528287,10.2463738670161]},"#221155":{"lch":[11.9365395500671561,33.3852442414483903,270.945812779521702],"luv":[11.9365395500671561,0.551083463009601,-33.3806956200430349],"rgb":[0.133333333333333331,0.0666666666666666657,0.333333333333333315],"xyz":[0.0249963081213762928,0.0139683099023890662,0.0873253221126860518],"hpluv":[270.945812779521702,354.907717298979946,11.9365395500671561],"hsluv":[270.945812779521702,78.3035236172291,11.9365395500671561]},"#221166":{"lch":[13.8282163263251512,43.1006504094303509,269.247085426223],"luv":[13.8282163263251512,-0.566362377205730683,-43.0969291176716496],"rgb":[0.133333333333333331,0.0666666666666666657,0.4],"xyz":[0.0325813038948844641,0.0170023082117923795,0.12727296651983],"hpluv":[269.247085426223,395.509560036398682,13.8282163263251512],"hsluv":[269.247085426223,83.9084652674952167,13.8282163263251512]},"#221177":{"lch":[15.8647012598499089,52.9790758801604,268.263491631539182],"luv":[15.8647012598499089,-1.60543281970815044,-52.954745458525224],"rgb":[0.133333333333333331,0.0666666666666666657,0.466666666666666674],"xyz":[0.0418953169150863836,0.0207279134198731958,0.176326768426227909],"hpluv":[268.263491631539182,423.75204448359591,15.8647012598499089],"hsluv":[268.263491631539182,87.783734282584831,15.8647012598499089]},"#221188":{"lch":[18.0016522099437424,62.9493123294311872,267.645454528547475],"luv":[18.0016522099437424,-2.58614693443793442,-62.8961665507666297],"rgb":[0.133333333333333331,0.0666666666666666657,0.533333333333333326],"xyz":[0.0530357340170302116,0.0251840802606507867,0.234999631829800076],"hpluv":[267.645454528547475,443.729139668046173,18.0016522099437424],"hsluv":[267.645454528547475,90.5156952975567464,18.0016522099437424]},"#221199":{"lch":[20.2061107483083475,72.9561611588118524,267.23334268313738],"luv":[20.2061107483083475,-3.52148568403582729,-72.8711231531918742],"rgb":[0.133333333333333331,0.0666666666666666657,0.6],"xyz":[0.066092698126102925,0.0304068659042799477,0.303766309470918],"hpluv":[267.23334268313738,458.161478440778865,20.2061107483083475],"hsluv":[267.23334268313738,92.4853336382361704,20.2061107483083475]},"#2211aa":{"lch":[22.4542330055690798,82.9584275230068471,266.945798214496847],"luv":[22.4542330055690798,-4.42007776686241449,-82.8405915576709759],"rgb":[0.133333333333333331,0.0666666666666666657,0.66666666666666663],"xyz":[0.0811503910913554671,0.0364299430903810492,0.383070159087916584],"hpluv":[266.945798214496847,468.815123306781686,22.4542330055690798],"hsluv":[266.945798214496847,93.9373181855700921,22.4542330055690798]},"#2211bb":{"lch":[24.7289983316777295,92.9268656932788701,266.737844101991243],"luv":[24.7289983316777295,-5.28796663316276483,-92.7762888698575097],"rgb":[0.133333333333333331,0.0666666666666666657,0.733333333333333282],"xyz":[0.0982879831986921138,0.0432849799333158078,0.473328144186558331],"hpluv":[266.737844101991243,476.841549380862261,24.7289983316777295],"hsluv":[266.737844101991243,95.0302193246277369,24.7289983316777295]},"#2211cc":{"lch":[27.0183279904475668,102.841627589427389,266.583003116257],"luv":[27.0183279904475668,-6.12961814831514129,-102.658794784462174],"rgb":[0.133333333333333331,0.0666666666666666657,0.8],"xyz":[0.117580358642413854,0.0510019301108046094,0.574934654856828486],"hpluv":[266.583003116257,483.002966655360069,27.0183279904475668],"hsluv":[266.583003116257,95.8686128249461689,27.0183279904475668]},"#2211dd":{"lch":[29.313669578695368,112.689841457512074,266.464886381494523],"luv":[29.313669578695368,-6.94848190374932617,-112.475414944566779],"rgb":[0.133333333333333331,0.0666666666666666657,0.866666666666666696],"xyz":[0.139098684193047384,0.0596092603310581434,0.688264502756834484],"hpluv":[266.464886381494523,487.813602393737767,29.313669578695368],"hsluv":[266.464886381494523,96.5228774582602256,29.313669578695368]},"#2211ee":{"lch":[31.6089746608533417,122.463629630364608,266.372923821556242],"luv":[31.6089746608533417,-7.74731231829930689,-122.21832814306471],"rgb":[0.133333333333333331,0.0666666666666666657,0.933333333333333348],"xyz":[0.162910864459222149,0.0691341324375281813,0.813675318825357707],"hpluv":[266.372923821556242,491.627361233059389,31.6089746608533417],"hsluv":[266.372923821556242,97.0413663214109761,31.6089746608533417]},"#2211ff":{"lch":[33.8999739889387115,132.15860685194221,266.300059947999785],"luv":[33.8999739889387115,-8.52836196764118,-131.883146789857562],"rgb":[0.133333333333333331,0.0666666666666666657,1],"xyz":[0.189081912869053514,0.0796025518014608774,0.951509507117139552],"hpluv":[266.300059947999785,494.692599475339,33.8999739889387115],"hsluv":[266.300059947999785,99.9999999999995737,33.8999739889387115]},"#77aa00":{"lch":[63.8935034159882491,78.4053265973676616,109.262687899665323],"luv":[63.8935034159882491,-25.8658938451783591,74.0158819067222424],"rgb":[0.466666666666666674,0.66666666666666663,0],"xyz":[0.219816749274909073,0.326708497135311,0.0514797056256764834],"hpluv":[109.262687899665323,155.714190603412163,63.8935034159882491],"hsluv":[109.262687899665323,100.000000000002132,63.8935034159882491]},"#77aa11":{"lch":[63.9264755829735662,77.0719876411919,109.595002167467626],"luv":[63.9264755829735662,-25.8475857965541422,72.6084952843247464],"rgb":[0.466666666666666674,0.66666666666666663,0.0666666666666666657],"xyz":[0.220828414774546206,0.32711316333516588,0.0568078105904321132],"hpluv":[109.595002167467626,152.98720995680398,63.9264755829735662],"hsluv":[109.595002167467626,97.9667163347824612,63.9264755829735662]},"#77aa22":{"lch":[63.9875253363426424,74.6349938152274603,110.235118064089221],"luv":[63.9875253363426424,-25.8142561390327501,70.0286118796271],"rgb":[0.466666666666666674,0.66666666666666663,0.133333333333333331],"xyz":[0.222703772913023207,0.32786330659055668,0.0666846967864113127],"hpluv":[110.235118064089221,148.008450888663447,63.9875253363426424],"hsluv":[110.235118064089221,94.2440053809013421,63.9875253363426424]},"#77aa33":{"lch":[64.0878403339217328,70.7199026331045,111.362593229805157],"luv":[64.0878403339217328,-25.7610573917560757,65.8610093340090685],"rgb":[0.466666666666666674,0.66666666666666663,0.2],"xyz":[0.22579152364548094,0.329098406883539807,0.0829468506440224629],"hpluv":[111.362593229805157,140.024923426145421,64.0878403339217328],"hsluv":[111.362593229805157,88.2427941375042,64.0878403339217328]},"#77aa44":{"lch":[64.2322300921174616,65.2796522257345,113.17268826837423],"luv":[64.2322300921174616,-25.6877867579927681,60.0130869576689463],"rgb":[0.466666666666666674,0.66666666666666663,0.266666666666666663],"xyz":[0.230249518889699828,0.330881604981227373,0.106425625596909101],"hpluv":[113.17268826837423,128.962712139229978,64.2322300921174616],"hsluv":[113.17268826837423,79.8488372015295482,64.2322300921174616]},"#77aa55":{"lch":[64.4245377454048338,58.3957340906732298,115.996670283872277],"luv":[64.4245377454048338,-25.5959546947607706,52.487225714952487],"rgb":[0.466666666666666674,0.66666666666666663,0.333333333333333315],"xyz":[0.236211932929061841,0.333266570596972234,0.137827672870883],"hpluv":[115.996670283872277,115.018880896771989,64.4245377454048338],"hsluv":[115.996670283872277,69.0944053471027075,64.4245377454048338]},"#77aa66":{"lch":[64.6678576456364,50.3036055521827663,120.443938093288892],"luv":[64.6678576456364,-25.4885877435648602,43.368013862617552],"rgb":[0.466666666666666674,0.66666666666666663,0.4],"xyz":[0.24379692870257,0.336300568906375552,0.177775317278026979],"hpluv":[120.443938093288892,98.707457943709727,64.6678576456364],"hsluv":[120.443938093288892,56.1391996219007723,64.6678576456364]},"#77aa77":{"lch":[64.964649263009,41.4721527505437351,127.71501294923786],"luv":[64.964649263009,-25.3699399849719889,32.8070967768157118],"rgb":[0.466666666666666674,0.66666666666666663,0.466666666666666674],"xyz":[0.253110941722771932,0.340026174114456348,0.226829119184424888],"hpluv":[127.71501294923786,81.006302212696113,64.964649263009],"hsluv":[127.71501294923786,41.2466460512923874,64.964649263009]},"#77aa88":{"lch":[65.3168057391263375,32.8409027786736161,140.238161573904051],"luv":[65.3168057391263375,-25.2451203613846147,21.004970679758074],"rgb":[0.466666666666666674,0.66666666666666663,0.533333333333333326],"xyz":[0.264251358824715732,0.344482340955233945,0.285501982587997],"hpluv":[140.238161573904051,63.8012923553667,65.3168057391263375],"hsluv":[140.238161573904051,43.6199696205744232,65.3168057391263375]},"#77aa99":{"lch":[65.7257012160132,26.4214783611449491,161.939459903532622],"luv":[65.7257012160132,-25.1196781367095241,8.19123245284666],"rgb":[0.466666666666666674,0.66666666666666663,0.6],"xyz":[0.277308322933788487,0.349705126598863103,0.354268660229114962],"hpluv":[161.939459903532622,51.0106916742292213,65.7257012160132],"hsluv":[161.939459903532622,46.1685656356417766,65.7257012160132]},"#77aaaa":{"lch":[66.1922284915170565,25.5746156232648509,192.177050630060677],"luv":[66.1922284915170565,-24.9991985449953802,-5.39453764336142338],"rgb":[0.466666666666666674,0.66666666666666663,0.66666666666666663],"xyz":[0.292366015899041,0.355728203784964225,0.433572509846113563],"hpluv":[192.177050630060677,49.0276908522131265,66.1922284915170565],"hsluv":[192.177050630060677,48.8357820868943122,66.1922284915170565]},"#77aabb":{"lch":[66.7168329685055568,31.6300901405034409,218.105494045696133],"luv":[66.7168329685055568,-24.8889541052261336,-19.519287021925777],"rgb":[0.466666666666666674,0.66666666666666663,0.733333333333333282],"xyz":[0.309503608006377662,0.362583240627899,0.523830494944755309],"hpluv":[218.105494045696133,60.1595160354738923,66.7168329685055568],"hsluv":[218.105494045696133,51.56699221483656,66.7168329685055568]},"#77aacc":{"lch":[67.2995460165272306,42.0550186755790207,233.874741843371567],"luv":[67.2995460165272306,-24.7936410920562054,-33.9691029790543908],"rgb":[0.466666666666666674,0.66666666666666663,0.8],"xyz":[0.328795983450099416,0.370300190805387786,0.625437005615025465],"hpluv":[233.874741843371567,79.2948573353567099,67.2995460165272306],"hsluv":[233.874741843371567,54.3124963748670382,67.2995460165272306]},"#77aadd":{"lch":[67.9400192524912,54.4863937886276304,243.022531341574677],"luv":[67.9400192524912,-24.7172120267711577,-48.557456046554158],"rgb":[0.466666666666666674,0.66666666666666663,0.866666666666666696],"xyz":[0.350314309000732904,0.378907521025641292,0.738766853515031463],"hpluv":[243.022531341574677,101.765770647841308,67.9400192524912],"hsluv":[243.022531341574677,60.6446157506369659,67.9400192524912]},"#77aaee":{"lch":[68.6375602707836,67.7758398266106781,248.660849953701415],"luv":[68.6375602707836,-24.6627990544268876,-63.1293181256010882],"rgb":[0.466666666666666674,0.66666666666666663,0.933333333333333348],"xyz":[0.374126489266907669,0.388432393132111309,0.864177669583554686],"hpluv":[248.660849953701415,125.300382334337471,68.6375602707836],"hsluv":[248.660849953701415,79.8712566390148453,68.6375602707836]},"#77aaff":{"lch":[69.3911697465266428,81.3794470542267874,252.380781260055755],"luv":[69.3911697465266428,-24.6327125013740549,-77.5618712878715399],"rgb":[0.466666666666666674,0.66666666666666663,1],"xyz":[0.400297537676739035,0.398900812496044033,1.00201185787533653],"hpluv":[252.380781260055755,148.816077288451226,69.3911697465266428],"hsluv":[252.380781260055755,99.9999999999980531,69.3911697465266428]},"#222200":{"lch":[12.5069288045758107,13.787646171799997,85.8743202181747307],"luv":[12.5069288045758107,0.991945128669063814,13.751917387057734],"rgb":[0.133333333333333331,0.133333333333333331,0],"xyz":[0.0123167482019914745,0.014841483910263846,0.002215896112402139],"hpluv":[85.8743202181747307,139.887458074797621,12.5069288045758107],"hsluv":[85.8743202181747307,100.000000000002359,12.5069288045758107]},"#222211":{"lch":[12.7636979604368612,8.34346759842367,85.8743202181729828],"luv":[12.7636979604368612,0.600266494900015157,8.32184665209868513],"rgb":[0.133333333333333331,0.133333333333333331,0.0666666666666666657],"xyz":[0.0133284137016285963,0.0152461501101187,0.00754400107715777046],"hpluv":[85.8743202181729828,82.9486632734846552,12.7636979604368612],"hsluv":[85.8743202181729828,59.2967120963297631,12.7636979604368612]},"#222222":{"lch":[13.2279109842717837,6.86787642036123471e-13,0],"luv":[13.2279109842717837,6.53891093021720259e-13,2.10008818196756883e-13],"rgb":[0.133333333333333331,0.133333333333333331,0.133333333333333331],"xyz":[0.0152037718401056149,0.0159962933655095202,0.0174208872731369674],"hpluv":[0,6.58825703928357502e-12,13.2279109842717837],"hsluv":[0,1.88635445986832e-12,13.2279109842717837]},"#222233":{"lch":[13.9615854376221584,10.5260121123804868,265.874320218180912],"luv":[13.9615854376221584,-0.757288539977712838,-10.4987354027615698],"rgb":[0.133333333333333331,0.133333333333333331,0.2],"xyz":[0.0182915225725633554,0.017231393658492633,0.0336830411307481106],"hpluv":[265.874320218180912,95.6683874279760431,13.9615854376221584],"hsluv":[265.874320218180912,18.6338179823007195,13.9615854376221584]},"#222244":{"lch":[14.9613810506728697,21.7214686924654536,265.874320218179207],"luv":[14.9613810506728697,-1.5627399186581008,-21.6651805001571454],"rgb":[0.133333333333333331,0.133333333333333331,0.266666666666666663],"xyz":[0.0227495178167822359,0.0190145917561802061,0.0571618160836347491],"hpluv":[265.874320218179207,184.228505509793536,14.9613810506728697],"hsluv":[265.874320218179207,35.8831222215914138,14.9613810506728697]},"#222255":{"lch":[16.2052187005970154,32.8139057554865161,265.874320218178639],"luv":[16.2052187005970154,-2.3607796110480268,-32.728873041368395],"rgb":[0.133333333333333331,0.133333333333333331,0.333333333333333315],"xyz":[0.028711931856144228,0.021399557371925039,0.0885638633576086576],"hpluv":[265.874320218178639,256.946292996249099,16.2052187005970154],"hsluv":[265.874320218178639,50.0467352240393097,16.2052187005970154]},"#222266":{"lch":[17.6604729086265309,43.5908485911403716,265.874320218178354],"luv":[17.6604729086265309,-3.13612123314657865,-43.477888915018994],"rgb":[0.133333333333333331,0.133333333333333331,0.4],"xyz":[0.0362969276296524063,0.0244335556813283505,0.128511507764752619],"hpluv":[265.874320218178354,313.207621322876264,17.6604729086265309],"hsluv":[265.874320218178354,61.00504004829466,17.6604729086265309]},"#222277":{"lch":[19.2910482951380544,54.0745009411091573,265.874320218178241],"luv":[19.2910482951380544,-3.89036222175517965,-53.9343743248547867],"rgb":[0.133333333333333331,0.133333333333333331,0.466666666666666674],"xyz":[0.0456109406498543188,0.0281591608894091669,0.177565309671150529],"hpluv":[265.874320218178241,355.693573155256843,19.2910482951380544],"hsluv":[265.874320218178241,69.2802447897283429,19.2910482951380544]},"#222288":{"lch":[21.0622605487373207,64.3390225585563371,265.874320218178184],"luv":[21.0622605487373207,-4.62883796225993471,-64.1722968492601353],"rgb":[0.133333333333333331,0.133333333333333331,0.533333333333333326],"xyz":[0.0567513577517981468,0.0326153277301867578,0.236238173074722696],"hpluv":[265.874320218178184,387.622344883614403,21.0622605487373207],"hsluv":[265.874320218178184,75.4991739133377706,21.0622605487373207]},"#222299":{"lch":[22.9434551626666803,74.4470789880776351,265.874320218178127],"luv":[22.9434551626666803,-5.35605689510984373,-74.2541596437089737],"rgb":[0.133333333333333331,0.133333333333333331,0.6],"xyz":[0.0698083218608708533,0.0378381133738159223,0.305004850715840603],"hpluv":[265.874320218178127,411.744842564929684,22.9434551626666803],"hsluv":[265.874320218178127,80.1976353712613559,22.9434551626666803]},"#2222aa":{"lch":[24.9089307040763188,84.4389391258505526,265.87432021817807],"luv":[24.9089307040763188,-6.07491614537627278,-84.2201272530844705],"rgb":[0.133333333333333331,0.133333333333333331,0.66666666666666663],"xyz":[0.0848660148261234093,0.0438611905599170238,0.384308700332839204],"hpluv":[265.87432021817807,430.157015573344836,24.9089307040763188],"hsluv":[265.87432021817807,83.7838678741945557,24.9089307040763188]},"#2222bb":{"lch":[26.937850813592469,94.3371638934954149,265.87432021817807],"luv":[26.937850813592469,-6.78703884698804139,-94.0927021354881106],"rgb":[0.133333333333333331,0.133333333333333331,0.733333333333333282],"xyz":[0.102003606933460056,0.0507162274028517823,0.47456668543148095],"hpluv":[265.87432021817807,444.384803230596,26.937850813592469],"hsluv":[265.87432021817807,86.5550863782758,26.937850813592469]},"#2222cc":{"lch":[29.0136770200274086,104.153206308830732,265.874320218178],"luv":[29.0136770200274086,-7.49324898143496743,-103.883307629821275],"rgb":[0.133333333333333331,0.133333333333333331,0.8],"xyz":[0.121295982377181782,0.058433177580340584,0.576173196101751106],"hpluv":[265.874320218178,455.521834046362642,29.0136770200274086],"hsluv":[265.874320218178,88.7243024658832695,29.0136770200274086]},"#2222dd":{"lch":[31.1234509916598299,113.892375340460845,265.874320218178],"luv":[31.1234509916598299,-8.19392849973896809,-113.597238947227837],"rgb":[0.133333333333333331,0.133333333333333331,0.866666666666666696],"xyz":[0.142814307927815326,0.067040507800594118,0.689503044001757104],"hpluv":[265.874320218178,464.350835522916555,31.1234509916598299],"hsluv":[265.874320218178,90.4439719502614565,31.1234509916598299]},"#2222ee":{"lch":[33.2570959032629503,123.556928623667645,265.874320218178],"luv":[33.2570959032629503,-8.88923982631188103,-123.236747872639071],"rgb":[0.133333333333333331,0.133333333333333331,0.933333333333333348],"xyz":[0.166626488193990063,0.0765653799070641489,0.814913860070280327],"hpluv":[265.874320218178,471.435310205520636,33.2570959032629503],"hsluv":[265.874320218178,93.8546607467714296,33.2570959032629503]},"#2222ff":{"lch":[35.4068078244889,133.147814572056944,265.874320218177957],"luv":[35.4068078244889,-9.57925119428392335,-132.802780361977625],"rgb":[0.133333333333333331,0.133333333333333331,1],"xyz":[0.192797536603821457,0.0870337992709968589,0.952748048362062172],"hpluv":[265.874320218177957,477.184793215987838,35.4068078244889],"hsluv":[265.874320218177957,99.999999999999531,35.4068078244889]},"#77bb00":{"lch":[69.0844312744863629,87.8096536524333544,113.037133893102563],"luv":[69.0844312744863629,-34.3623439699837476,80.8069588058406225],"rgb":[0.466666666666666674,0.733333333333333282,0],"xyz":[0.253771247183507853,0.394617492952509585,0.0627978715952091093],"hpluv":[113.037133893102563,161.287757631366873,69.0844312744863629],"hsluv":[113.037133893102563,100.000000000002331,69.0844312744863629]},"#77bb11":{"lch":[69.1135050244688216,86.6316159473835654,113.342165034517933],"luv":[69.1135050244688216,-34.3252912529264051,79.5412550948043275],"rgb":[0.466666666666666674,0.733333333333333282,0.0666666666666666657],"xyz":[0.254782912683144958,0.395022159152364438,0.068125976559964746],"hpluv":[113.342165034517933,159.057013433643618,69.1135050244688216],"hsluv":[113.342165034517933,98.3127503818399,69.1135050244688216]},"#77bb22":{"lch":[69.1673475306790664,84.4748154027895595,113.924619678029501],"luv":[69.1673475306790664,-34.2574435126740582,77.2167209955934197],"rgb":[0.466666666666666674,0.733333333333333282,0.133333333333333331],"xyz":[0.256658270821622,0.395772302407755239,0.0780028627559439386],"hpluv":[113.924619678029501,154.976360107776344,69.1673475306790664],"hsluv":[113.924619678029501,95.2170715716625438,69.1673475306790664]},"#77bb33":{"lch":[69.2558504240405313,80.9996568929936132,114.934551128374181],"luv":[69.2558504240405313,-34.1480550559542593,73.4496749664571666],"rgb":[0.466666666666666674,0.733333333333333282,0.2],"xyz":[0.25974602155407972,0.397007402700738365,0.0942650166135550749],"hpluv":[114.934551128374181,148.410982175614635,69.2558504240405313],"hsluv":[114.934551128374181,90.2088459481891363,69.2558504240405313]},"#77bb44":{"lch":[69.3833048234310752,76.148419012573342,116.514961433737128],"luv":[69.3833048234310752,-33.9950520676451049,68.1389620777462426],"rgb":[0.466666666666666674,0.733333333333333282,0.266666666666666663],"xyz":[0.264204016798298635,0.398790600798425932,0.117743791566441713],"hpluv":[116.514961433737128,139.266042804817573,69.3833048234310752],"hsluv":[116.514961433737128,83.166634884803841,69.3833048234310752]},"#77bb55":{"lch":[69.5531781358710788,69.9670725739878918,118.886197685461212],"luv":[69.5531781358710788,-33.7990968432466516,61.2618339356121666],"rgb":[0.466666666666666674,0.733333333333333282,0.333333333333333315],"xyz":[0.270166430837660621,0.401175566414170792,0.149145838840415629],"hpluv":[118.886197685461212,127.648598426560824,69.5531781358710788],"hsluv":[118.886197685461212,74.0801666731923092,69.5531781358710788]},"#77bb66":{"lch":[69.7683097004737647,62.6192143930699672,122.411113057511386],"luv":[69.7683097004737647,-33.5633071802414804,52.8646424591145],"rgb":[0.466666666666666674,0.733333333333333282,0.4],"xyz":[0.277751426611168806,0.404209564723574111,0.189093483247559591],"hpluv":[122.411113057511386,113.8908252780179,69.7683097004737647],"hsluv":[122.411113057511386,63.0377921091212627,69.7683097004737647]},"#77bb77":{"lch":[70.0310134677453391,54.4237865803123384,127.71501294923867],"luv":[70.0310134677453391,-33.2928991557924476,43.0526585885427053],"rgb":[0.466666666666666674,0.733333333333333282,0.466666666666666674],"xyz":[0.287065439631370711,0.407935169931654906,0.2381472851539575],"hpluv":[127.71501294923867,98.6137944921033522,70.0310134677453391],"hsluv":[127.71501294923867,50.2119979074062357,70.0310134677453391]},"#77bb88":{"lch":[70.3431390634792422,45.948041729110173,135.896820739423845],"luv":[70.3431390634792422,-32.9947227526694,31.9776610966863863],"rgb":[0.466666666666666674,0.733333333333333282,0.533333333333333326],"xyz":[0.298205856733314512,0.412391336772432504,0.296820148557529695],"hpluv":[135.896820739423845,82.8866502392756246,70.3431390634792422],"hsluv":[135.896820739423845,51.9268484553617711,70.3431390634792422]},"#77bb99":{"lch":[70.7061124793432612,38.2197788608509725,148.75629343317604],"luv":[70.7061124793432612,-32.6767203094589,19.8238100775241328],"rgb":[0.466666666666666674,0.733333333333333282,0.6],"xyz":[0.311262820842387211,0.417614122416061662,0.365586826198647574],"hpluv":[148.75629343317604,68.5915373148405,70.7061124793432612],"hsluv":[148.75629343317604,53.7921873551213565,70.7061124793432612]},"#77bbaa":{"lch":[71.1209666334754615,33.0529501718716148,168.140026251468868],"luv":[71.1209666334754615,-32.3473621836046874,6.79306078486928744],"rgb":[0.466666666666666674,0.733333333333333282,0.66666666666666663],"xyz":[0.326320513807639767,0.423637199602162784,0.444890675815646175],"hpluv":[168.140026251468868,58.9728212370576585,71.1209666334754615],"hsluv":[168.140026251468868,55.7713219876506372,71.1209666334754615]},"#77bbbb":{"lch":[71.5883672123020744,32.7520226121926044,192.177050630060876],"luv":[71.5883672123020744,-32.0151171807858432,-6.90849166534396097],"rgb":[0.466666666666666674,0.733333333333333282,0.733333333333333282],"xyz":[0.343458105914976441,0.430492236445097542,0.535148660914287921],"hpluv":[192.177050630060876,58.0543804308889762,71.5883672123020744],"hsluv":[192.177050630060876,57.8271385543864938,71.5883672123020744]},"#77bbcc":{"lch":[72.1086367753872111,38.0603267014846267,213.636027248927832],"luv":[72.1086367753872111,-31.6880044447458609,-21.0821925551758049],"rgb":[0.466666666666666674,0.733333333333333282,0.8],"xyz":[0.36275048135869814,0.438209186622586344,0.636755171584558077],"hpluv":[213.636027248927832,66.97682452789428,72.1086367753872111],"hsluv":[213.636027248927832,59.9241419588218278,72.1086367753872111]},"#77bbdd":{"lch":[72.6817787487410101,47.4106862821029651,228.567760630430627],"luv":[72.6817787487410101,-31.3732552756954277,-35.5456330249727728],"rgb":[0.466666666666666674,0.733333333333333282,0.866666666666666696],"xyz":[0.384268806909331739,0.44681651684283985,0.750085019484564075],"hpluv":[228.567760630430627,82.7732525696479371,72.6817787487410101],"hsluv":[228.567760630430627,62.0300015657167449,72.6817787487410101]},"#77bbee":{"lch":[73.3075021126589803,58.9885691422652769,238.208313348868131],"luv":[73.3075021126589803,-31.0770938488335098,-50.1384635520735316],"rgb":[0.466666666666666674,0.733333333333333282,0.933333333333333348],"xyz":[0.408080987175506449,0.456341388949309867,0.875495835553087298],"hpluv":[238.208313348868131,102.107764199280055,73.3075021126589803],"hsluv":[238.208313348868131,76.3238953534044,73.3075021126589803]},"#77bbff":{"lch":[73.9852470697490219,71.6819577745528846,244.548916872628638],"luv":[73.9852470697490219,-30.8046295043453391,-64.7254036023940102],"rgb":[0.466666666666666674,0.733333333333333282,1],"xyz":[0.43425203558533787,0.466809808313242591,1.01333002384486903],"hpluv":[244.548916872628638,122.943070755930805,73.9852470697490219],"hsluv":[244.548916872628638,99.9999999999974,73.9852470697490219]},"#223300":{"lch":[18.8330192465532917,22.9063411551717806,108.204985820955727],"luv":[18.8330192465532917,-7.15634373768739707,21.7597612446731326],"rgb":[0.133333333333333331,0.2,0],"xyz":[0.0184344702910022862,0.0270769280882856428,0.00425513680873902],"hpluv":[108.204985820955727,154.338793470845559,18.8330192465532917],"hsluv":[108.204985820955727,100.000000000002331,18.8330192465532917]},"#223311":{"lch":[19.0056890338669575,18.4529510656336271,112.754551304246377],"luv":[19.0056890338669575,-7.13731020483261602,17.0167625026225657],"rgb":[0.133333333333333331,0.2,0.0666666666666666657],"xyz":[0.0194461357906394079,0.0274815942881404957,0.0095832417734946513],"hpluv":[112.754551304246377,123.203072156705915,19.0056890338669575],"hsluv":[112.754551304246377,76.6034511576994248,19.0056890338669575]},"#223322":{"lch":[19.3213416797184507,11.6344605438365232,127.71501294923759],"luv":[19.3213416797184507,-7.11719904028337247,9.20359440474635],"rgb":[0.133333333333333331,0.2,0.133333333333333331],"xyz":[0.0213214939291164265,0.028231737543531317,0.0194601279694738491],"hpluv":[127.71501294923759,76.4096652359405084,19.3213416797184507],"hsluv":[127.71501294923759,38.9061385447444366,19.3213416797184507]},"#223333":{"lch":[19.8290945906418372,7.27996715422488894,192.177050630060677],"luv":[19.8290945906418372,-7.11617124458192585,-1.53558737438758408],"rgb":[0.133333333333333331,0.2,0.2],"xyz":[0.0244092446615741671,0.0294668378365144298,0.0357222818270849923],"hpluv":[192.177050630060677,46.5871198449043149,19.8290945906418372],"hsluv":[192.177050630060677,46.4047641905018935,19.8290945906418372]},"#223344":{"lch":[20.5377244517829496,15.5714684077650816,242.621028364370432],"luv":[20.5377244517829496,-7.16091210703038339,-13.8272183091687548],"rgb":[0.133333333333333331,0.2,0.266666666666666663],"xyz":[0.0288672399057930476,0.031250035934202,0.0592010567799716309],"hpluv":[242.621028364370432,96.2091932027738181,20.5377244517829496],"hsluv":[242.621028364370432,54.472556800898019,20.5377244517829496]},"#223355":{"lch":[21.4445377167678828,27.4997828393463344,254.670418676715883],"luv":[21.4445377167678828,-7.27014529691604761,-26.5213695644274097],"rgb":[0.133333333333333331,0.2,0.333333333333333315],"xyz":[0.0348296539451550397,0.0336350015499468358,0.0906031040539455323],"hpluv":[254.670418676715883,162.72410902482622,21.4445377167678828],"hsluv":[254.670418676715883,62.1025047738862597,21.4445377167678828]},"#223366":{"lch":[22.538163137523668,39.6650934211933617,259.172698399253136],"luv":[22.538163137523668,-7.45106225263504562,-38.9589695374422647],"rgb":[0.133333333333333331,0.2,0.4],"xyz":[0.042414649718663211,0.0366689998593501473,0.130550748461089494],"hpluv":[259.172698399253136,223.320859110196579,22.538163137523668],"hsluv":[259.172698399253136,68.7622962285398103,22.538163137523668]},"#223377":{"lch":[23.8014699151847751,51.4679604591091,261.393782909523054],"luv":[23.8014699151847751,-7.70180102721624227,-50.8884389105972517],"rgb":[0.133333333333333331,0.2,0.466666666666666674],"xyz":[0.0517286627388651304,0.0403946050674309637,0.179604550367487403],"hpluv":[261.393782909523054,274.392670476726266,23.8014699151847751],"hsluv":[261.393782909523054,74.3066649079193837,23.8014699151847751]},"#223388":{"lch":[25.214303338898695,62.8010579136007649,262.667168962641028],"luv":[25.214303338898695,-8.01548446335257658,-62.2874376089207189],"rgb":[0.133333333333333331,0.2,0.533333333333333326],"xyz":[0.0628690798408089585,0.0448507719082085615,0.238277413771059571],"hpluv":[262.667168962641028,316.052560368409843,25.214303338898695],"hsluv":[262.667168962641028,78.8060188103052184,25.214303338898695]},"#223399":{"lch":[26.7557115473943199,73.7050787305795723,263.468936800572067],"luv":[26.7557115473943199,-8.38335327394953111,-73.2267575314180732],"rgb":[0.133333333333333331,0.2,0.6],"xyz":[0.0759260439498816719,0.0500735575518377191,0.307044091412177478],"hpluv":[263.468936800572067,349.558796760350788,26.7557115473943199],"hsluv":[263.468936800572067,82.4151943494814105,26.7557115473943199]},"#2233aa":{"lch":[28.4055164492709622,84.2578478733767184,264.007358934798901],"luv":[28.4055164492709622,-8.79658068794244485,-83.7974050699281],"rgb":[0.133333333333333331,0.2,0.66666666666666663],"xyz":[0.090983736915134214,0.0560966347379388205,0.386347941029176078],"hpluv":[264.007358934798901,376.397732872534505,28.4055164492709622],"hsluv":[264.007358934798901,85.301735461295209,28.4055164492709622]},"#2233bb":{"lch":[30.1452579578322855,94.5340435151979506,264.386468786418391],"luv":[30.1452579578322855,-9.24712484322681583,-94.0806891209195868],"rgb":[0.133333333333333331,0.2,0.733333333333333282],"xyz":[0.108121329022470861,0.0629516715808735861,0.476605926127817825],"hpluv":[264.386468786418391,397.931717533943186,30.1452579578322855],"hsluv":[264.386468786418391,87.6154589527103553,30.1452579578322855]},"#2233cc":{"lch":[31.9586404471462444,104.593501952517812,264.663323368501551],"luv":[31.9586404471462444,-9.72802821613955615,-104.140127317558722],"rgb":[0.133333333333333331,0.2,0.8],"xyz":[0.127413704466192601,0.0706686217583623877,0.578212436798088],"hpluv":[264.663323368501551,415.294074833826699,31.9586404471462444],"hsluv":[264.663323368501551,89.4797268300864,31.9586404471462444]},"#2233dd":{"lch":[33.8316358854510284,114.480561125644712,264.87147297862515],"luv":[33.8316358854510284,-10.233440845943651,-114.022259072932982],"rgb":[0.133333333333333331,0.2,0.866666666666666696],"xyz":[0.148932030016826145,0.0792759519786159217,0.691542284698094],"hpluv":[264.87147297862515,429.386195390892226,33.8316358854510284],"hsluv":[264.87147297862515,90.9921469937159,33.8316358854510284]},"#2233ee":{"lch":[35.7523793143002209,124.226868169083772,265.031742065807748],"luv":[35.7523793143002209,-10.7585230682670669,-123.760126682580946],"rgb":[0.133333333333333331,0.2,0.933333333333333348],"xyz":[0.172744210283000882,0.0888008240850859387,0.816953100766617202],"hpluv":[265.031742065807748,440.909964314972513,35.7523793143002209],"hsluv":[265.031742065807748,93.1343838757889557,35.7523793143002209]},"#2233ff":{"lch":[37.7109573358094536,133.854664271403067,265.157628752861342],"luv":[37.7109573358094536,-11.2993072928814158,-133.376897556927247],"rgb":[0.133333333333333331,0.2,1],"xyz":[0.198915258692832275,0.0992692434490186487,0.954787289058399],"hpluv":[265.157628752861342,450.407151983715153,37.7109573358094536],"hsluv":[265.157628752861342,99.9999999999994884,37.7109573358094536]},"#77cc00":{"lch":[74.2578384949046892,97.2071675743180776,115.806356387580706],"luv":[74.2578384949046892,-42.3172913249353897,87.5127435448238202],"rgb":[0.466666666666666674,0.8,0],"xyz":[0.291994990493124773,0.47106497957174448,0.0755391193650810505],"hpluv":[115.806356387580706,166.109821583261578,74.2578384949046892],"hsluv":[115.806356387580706,100.000000000002331,74.2578384949046892]},"#77cc11":{"lch":[74.283676291108776,96.1575231653334441,116.077287726142885],"luv":[74.283676291108776,-42.2692272766684525,86.3688698937585144],"rgb":[0.466666666666666674,0.8,0.0666666666666666657],"xyz":[0.293006655992761877,0.471469645771599333,0.0808672243298366872],"hpluv":[116.077287726142885,164.2590118749402,74.283676291108776],"hsluv":[116.077287726142885,98.5840266713216522,74.283676291108776]},"#77cc22":{"lch":[74.3315335987815331,94.2328042547367914,116.591431825394338],"luv":[74.3315335987815331,-42.1809937248656581,84.2649699821603519],"rgb":[0.466666666666666674,0.8,0.133333333333333331],"xyz":[0.294882014131238934,0.472219789026990133,0.0907441105258158798],"hpluv":[116.591431825394338,160.867513369155,74.3315335987815331],"hsluv":[116.591431825394338,95.9817736999432611,74.3315335987815331]},"#77cc33":{"lch":[74.410219680569412,91.1231466477069176,117.473161926834081],"luv":[74.410219680569412,-42.0381214847294515,80.8469182901527148],"rgb":[0.466666666666666674,0.8,0.2],"xyz":[0.29796976486369664,0.47345488931997326,0.10700626438342703],"hpluv":[117.473161926834081,155.394430123968846,74.410219680569412],"hsluv":[117.473161926834081,91.7599970515073551,74.410219680569412]},"#77cc44":{"lch":[74.5235830687713445,86.7634188586395,118.828926444460791],"luv":[74.5235830687713445,-41.8369758074171045,76.0102513305232748],"rgb":[0.466666666666666674,0.8,0.266666666666666663],"xyz":[0.302427760107915555,0.475238087417660826,0.130485039336313668],"hpluv":[118.828926444460791,147.734611978654129,74.5235830687713445],"hsluv":[118.828926444460791,85.7987877580492153,74.5235830687713445]},"#77cc55":{"lch":[74.6747602628398,81.1723246922669688,120.810965560633605],"luv":[74.6747602628398,-41.5770530159641396,69.7158156981220571],"rgb":[0.466666666666666674,0.8,0.333333333333333315],"xyz":[0.30839017414727754,0.477623053033405687,0.161887086610287556],"hpluv":[120.810965560633605,137.934680546119694,74.6747602628398],"hsluv":[120.810965560633605,78.0638956664307671,74.6747602628398]},"#77cc66":{"lch":[74.866352492363319,74.4599116278811692,123.651008617564372],"luv":[74.866352492363319,-41.2606832822808798,61.982533464768764],"rgb":[0.466666666666666674,0.8,0.4],"xyz":[0.315975169920785726,0.480657051342809,0.201834731017431546],"hpluv":[123.651008617564372,126.204595224585091,74.866352492363319],"hsluv":[123.651008617564372,68.5978490432360388,74.866352492363319]},"#77cc77":{"lch":[75.1005189251371519,66.8471540376336719,127.715012949239053],"luv":[75.1005189251371519,-40.8926996459993219,52.8803282761483189],"rgb":[0.466666666666666674,0.8,0.466666666666666674],"xyz":[0.325289182940987631,0.484382656550889801,0.250888532923829455],"hpluv":[127.715012949239053,112.948199149412858,75.1005189251371519],"hsluv":[127.715012949239053,57.5107647824030153,75.1005189251371519]},"#77cc88":{"lch":[75.3790318815133,58.7087525381891311,133.590980823477452],"luv":[75.3790318815133,-40.4800101313413947,42.5215992685696946],"rgb":[0.466666666666666674,0.8,0.533333333333333326],"xyz":[0.336429600042931432,0.488838823391667399,0.309561396327401595],"hpluv":[133.590980823477452,98.8306436104363542,75.3790318815133],"hsluv":[133.590980823477452,58.7660231359317748,75.3790318815133]},"#77cc99":{"lch":[75.7033128937519848,50.6622606125816759,142.200076129410462],"luv":[75.7033128937519848,-40.0310804193600305,31.0512036938324556],"rgb":[0.466666666666666674,0.8,0.6],"xyz":[0.349486564152004187,0.494061609035296556,0.378328073968519529],"hpluv":[142.200076129410462,84.9198084445103802,75.7033128937519848],"hsluv":[142.200076129410462,60.1459848784672815,75.7033128937519848]},"#77ccaa":{"lch":[76.0744587192654,43.7254195479873289,154.773618890386814],"luv":[76.0744587192654,-39.5553661600219684,18.6355928962322395],"rgb":[0.466666666666666674,0.8,0.66666666666666663],"xyz":[0.364544257117256687,0.500084686221397678,0.45763192358551813],"hpluv":[154.773618890386814,73.067319501552376,76.0744587192654],"hsluv":[154.773618890386814,61.6269813218812459,76.0744587192654]},"#77ccbb":{"lch":[76.4932621718819235,39.4413790272598561,172.054536865796422],"luv":[76.4932621718819235,-39.0627454070693716,5.45199970968949721],"rgb":[0.466666666666666674,0.8,0.733333333333333282],"xyz":[0.381681849224593361,0.506939723064332437,0.547889908684159876],"hpluv":[172.054536865796422,67.3385729198675733,76.4932621718819235],"hsluv":[172.054536865796422,63.1840553036415713,76.4932621718819235]},"#77cccc":{"lch":[76.9602305249106,39.4506200876857847,192.177050630060961],"luv":[76.9602305249106,-38.5629992967744357,-8.32144882456723778],"rgb":[0.466666666666666674,0.8,0.8],"xyz":[0.400974224668315116,0.514656673241821183,0.64949641935443],"hpluv":[192.177050630060961,69.0111626451701312,76.9602305249106],"hsluv":[192.177050630060961,64.792316690459316,76.9602305249106]},"#77ccdd":{"lch":[77.4756030772436475,44.2250390945155942,210.602473757279853],"luv":[77.4756030772436475,-38.0653777824919359,-22.5140200139291444],"rgb":[0.466666666666666674,0.8,0.866666666666666696],"xyz":[0.422492550218948604,0.5232640034620748,0.762826267254436],"hpluv":[210.602473757279853,79.5030322309331439,77.4756030772436475],"hsluv":[210.602473757279853,66.4280770246703156,77.4756030772436475]},"#77ccee":{"lch":[78.0393687787239116,52.7144148097026246,224.531483635923479],"luv":[78.0393687787239116,-37.5782716813780482,-36.9686762837126182],"rgb":[0.466666666666666674,0.8,0.933333333333333348],"xyz":[0.446304730485123369,0.532788875568544817,0.888237083322959253],"hpluv":[224.531483635923479,97.6926138158747648,78.0393687787239116],"hsluv":[224.531483635923479,71.3781641956177282,78.0393687787239116]},"#77ccff":{"lch":[78.6512843692400736,63.5145451324089052,234.249283216901347],"luv":[78.6512843692400736,-37.1089966152940249,-51.5462880679385549],"rgb":[0.466666666666666674,0.8,1],"xyz":[0.472475778894954734,0.54325729493247743,1.0260712716147411],"hpluv":[234.249283216901347,121.749546403725816,78.6512843692400736],"hsluv":[234.249283216901347,99.9999999999968168,78.6512843692400736]},"#224400":{"lch":[25.1809799681870601,33.4179584834008523,116.999863609689683],"luv":[25.1809799681870601,-15.1713647924420147,29.7756551486773162],"rgb":[0.133333333333333331,0.266666666666666663,0],"xyz":[0.0272670407739683193,0.0447420690542179589,0.00719932696972761486],"hpluv":[116.999863609689683,168.401755360818214,25.1809799681870601],"hsluv":[116.999863609689683,100.000000000002217,25.1809799681870601]},"#224411":{"lch":[25.304760275593587,29.8643723317269938,120.153298663054528],"luv":[25.304760275593587,-15.0013316265206242,25.8232605261065515],"rgb":[0.133333333333333331,0.266666666666666663,0.0666666666666666657],"xyz":[0.0282787062736054411,0.0451467352540728117,0.0125274319344832463],"hpluv":[120.153298663054528,149.758158325470362,25.304760275593587],"hsluv":[120.153298663054528,85.5029145399767287,25.304760275593587]},"#224422":{"lch":[25.5322735505540379,24.0578500603585184,127.715012949239281],"luv":[25.5322735505540379,-14.7170130248608242,19.0312815425753499],"rgb":[0.133333333333333331,0.266666666666666663,0.133333333333333331],"xyz":[0.0301540644120824597,0.0458968785094636331,0.0224043181304624424],"hpluv":[127.715012949239281,119.565711231297882,25.5322735505540379],"hsluv":[127.715012949239281,60.8802579098014363,25.5322735505540379]},"#224433":{"lch":[25.9015299317797343,16.981905402382786,147.498859327993841],"luv":[25.9015299317797343,-14.3222120947549634,9.12465625699578098],"rgb":[0.133333333333333331,0.266666666666666663,0.2],"xyz":[0.0332418151445402,0.0471319788024467459,0.0386664719880735891],"hpluv":[147.498859327993841,83.1955939146196357,25.9015299317797343],"hsluv":[147.498859327993841,64.09678513773909,25.9015299317797343]},"#224444":{"lch":[26.423438440277998,14.1959776348833024,192.177050630061],"luv":[26.423438440277998,-13.8765746732054378,-2.99440417262938974],"rgb":[0.133333333333333331,0.266666666666666663,0.266666666666666663],"xyz":[0.0376998103887590807,0.048915176900134319,0.0621452469409602276],"hpluv":[192.177050630061,68.1734546180548762,26.423438440277998],"hsluv":[192.177050630061,67.9066037165366367,26.423438440277998]},"#224455":{"lch":[27.1020089847707979,21.1158760403194243,230.453768193421723],"luv":[27.1020089847707979,-13.4444916811297333,-16.2826860310628518],"rgb":[0.133333333333333331,0.266666666666666663,0.333333333333333315],"xyz":[0.0436622244281210728,0.0513001425158791519,0.0935472942149341291],"hpluv":[230.453768193421723,98.865995891455,27.1020089847707979],"hsluv":[230.453768193421723,71.8953118433392717,27.1020089847707979]},"#224466":{"lch":[27.935501760142138,32.6185654266362306,246.366656325875056],"luv":[27.935501760142138,-13.0762038460066634,-29.8828329224226863],"rgb":[0.133333333333333331,0.266666666666666663,0.4],"xyz":[0.0512472202016292511,0.0543341408252824634,0.133494938622078091],"hpluv":[246.366656325875056,148.165710166053657,27.935501760142138],"hsluv":[246.366656325875056,75.7322080769735351,27.935501760142138]},"#224477":{"lch":[28.9175817086007072,45.1016041758277453,253.511262930840303],"luv":[28.9175817086007072,-12.8010466495854338,-43.2468253621948548],"rgb":[0.133333333333333331,0.266666666666666663,0.466666666666666674],"xyz":[0.0605612332218311636,0.0580597460333632798,0.182548740528476],"hpluv":[253.511262930840303,197.910731630760921,28.9175817086007072],"hsluv":[253.511262930840303,79.2164102145581381,28.9175817086007072]},"#224488":{"lch":[30.0385370730522183,57.5093846577101502,257.31357801273],"luv":[30.0385370730522183,-12.6299243743950456,-56.1053859625395432],"rgb":[0.133333333333333331,0.266666666666666663,0.533333333333333326],"xyz":[0.0717016503237749847,0.0625159128741408776,0.241221603932048168],"hpluv":[257.31357801273,242.94013543841632,30.0385370730522183],"hsluv":[257.31357801273,82.2624245727818106,30.0385370730522183]},"#224499":{"lch":[31.2864747985506213,69.5224780150470139,259.59064804278853],"luv":[31.2864747985506213,-12.5612993437317204,-68.3782765807230675],"rgb":[0.133333333333333331,0.266666666666666663,0.6],"xyz":[0.084758614432847712,0.0677386985177700351,0.309988281573166102],"hpluv":[259.59064804278853,281.973268281811727,31.2864747985506213],"hsluv":[259.59064804278853,84.8626039888072796,31.2864747985506213]},"#2244aa":{"lch":[32.6483868166792277,81.0719578322086676,261.068394107427196],"luv":[32.6483868166792277,-12.5868550230291323,-80.0889095154670372],"rgb":[0.133333333333333331,0.266666666666666663,0.66666666666666663],"xyz":[0.0998163073981002402,0.0737617757038711297,0.389292131190164703],"hpluv":[261.068394107427196,315.099896322028769,32.6483868166792277],"hsluv":[261.068394107427196,87.0515845849570695,32.6483868166792277]},"#2244bb":{"lch":[34.1110146972578292,92.183713113584,262.084105297610279],"luv":[34.1110146972578292,-12.6954785449376448,-91.3053217940914266],"rgb":[0.133333333333333331,0.266666666666666663,0.733333333333333282],"xyz":[0.116953899505436887,0.0806168125468058883,0.479550116288806449],"hpluv":[262.084105297610279,342.924793116778346,34.1110146972578292],"hsluv":[262.084105297610279,88.8814901896574128,34.1110146972578292]},"#2244cc":{"lch":[35.6614866183058439,102.915147630289923,262.812952152813068],"luv":[35.6614866183058439,-12.875606592693158,-102.106544191029045],"rgb":[0.133333333333333331,0.266666666666666663,0.8],"xyz":[0.136246274949158641,0.0883337627242946899,0.58115662695907655],"hpluv":[262.812952152813068,366.200711918304478,35.6614866183058439],"hsluv":[262.812952152813068,90.4075680541016453,35.6614866183058439]},"#2244dd":{"lch":[37.2877389569632456,113.32806156453313,263.353781276912969],"luv":[37.2877389569632456,-13.1164125913708496,-112.566465959927598],"rgb":[0.133333333333333331,0.266666666666666663,0.866666666666666696],"xyz":[0.157764600499792185,0.0969410929445482239,0.694486474859082548],"hpluv":[263.353781276912969,385.665452845521429,37.2877389569632456],"hsluv":[263.353781276912969,91.6811227311716408,37.2877389569632456]},"#2244ee":{"lch":[38.9787575249373575,123.477944203962494,263.76603971616106],"luv":[38.9787575249373575,-13.4082956886680194,-122.74779147325674],"rgb":[0.133333333333333331,0.266666666666666663,0.933333333333333348],"xyz":[0.181576780765966922,0.106465965051018269,0.819897290927605771],"hpluv":[263.76603971616106,401.976556214066079,38.9787575249373575],"hsluv":[263.76603971616106,92.7467647141115208,38.9787575249373575]},"#2244ff":{"lch":[40.7246816385265333,133.410810959437413,264.087324287658078],"luv":[40.7246816385265333,-13.7429938745542355,-132.701072340123574],"rgb":[0.133333333333333331,0.266666666666666663,1],"xyz":[0.207747829175798315,0.116934384414950965,0.957731479219387616],"hpluv":[264.087324287658078,415.692943868353552,40.7246816385265333],"hsluv":[264.087324287658078,99.9999999999994174,40.7246816385265333]},"#77dd00":{"lch":[79.4046595803128525,106.500737968556749,117.886764510297155],"luv":[79.4046595803128525,-49.8131268255250319,94.1332012826045457],"rgb":[0.466666666666666674,0.866666666666666696,0],"xyz":[0.3346289810403,0.556332960666096,0.089750449547472369],"hpluv":[117.886764510297155,213.048114553231642,79.4046595803128525],"hsluv":[117.886764510297155,100.000000000002288,79.4046595803128525]},"#77dd11":{"lch":[79.427785829561941,105.558219679332908,118.124490997004173],"luv":[79.427785829561941,-49.7589732732473422,93.0944806133132801],"rgb":[0.466666666666666674,0.866666666666666696,0.0666666666666666657],"xyz":[0.335640646539937082,0.556737626865951,0.095078554512228],"hpluv":[118.124490997004173,211.44368721760469,79.427785829561941],"hsluv":[118.124490997004173,98.7993418471683498,79.427785829561941]},"#77dd22":{"lch":[79.4706261070012658,103.827566318990023,118.57359388187615],"luv":[79.4706261070012658,-49.6593926395600249,91.1817319993116],"rgb":[0.466666666666666674,0.866666666666666696,0.133333333333333331],"xyz":[0.337516004678414139,0.557487770121341764,0.104955440708207198],"hpluv":[118.57359388187615,208.49071074424171,79.4706261070012658],"hsluv":[118.57359388187615,96.5898934808467,79.4706261070012658]},"#77dd33":{"lch":[79.5410783702752582,101.02472031386101,119.337697767432388],"luv":[79.5410783702752582,-49.4976803830995067,88.0680063995226874],"rgb":[0.466666666666666674,0.866666666666666696,0.2],"xyz":[0.340603755410871845,0.55872287041432489,0.121217594565818348],"hpluv":[119.337697767432388,203.689012727245881,79.5410783702752582],"hsluv":[119.337697767432388,92.9973786049096276,79.5410783702752582]},"#77dd44":{"lch":[79.6426121547728485,97.0801788178617073,120.498016398630853],"luv":[79.6426121547728485,-49.2690191092090188,83.6488187323909642],"rgb":[0.466666666666666674,0.866666666666666696,0.266666666666666663],"xyz":[0.34506175065509076,0.560506068512012456,0.144696369518705],"hpluv":[120.498016398630853,196.890303230407255,79.6426121547728485],"hsluv":[120.498016398630853,87.9077551580221126,79.6426121547728485]},"#77dd55":{"lch":[79.7780740091910729,91.9929116678805912,122.163902680224],"luv":[79.7780740091910729,-48.9717875622404577,77.8746417012192325],"rgb":[0.466666666666666674,0.866666666666666696,0.333333333333333315],"xyz":[0.351024164694452745,0.562891034127757206,0.176098416792678902],"hpluv":[122.163902680224,188.049297266091,79.7780740091910729],"hsluv":[122.163902680224,81.2740392578912889,79.7780740091910729]},"#77dd66":{"lch":[79.9498479155991788,85.8342168020908645,124.492086237753256],"luv":[79.9498479155991788,-48.6072648253697466,70.7449403153661],"rgb":[0.466666666666666674,0.866666666666666696,0.4],"xyz":[0.35860916046796093,0.565925032437160525,0.216046061199822836],"hpluv":[124.492086237753256,177.233761467474238,79.9498479155991788],"hsluv":[124.492086237753256,73.1095665987697174,79.9498479155991788]},"#77dd77":{"lch":[80.1599403321921,78.7586110849663896,127.715012949239352],"luv":[80.1599403321921,-48.1793469594900188,62.3030444407821093],"rgb":[0.466666666666666674,0.866666666666666696,0.466666666666666674],"xyz":[0.367923173488162836,0.569650637645241376,0.265099863106220746],"hpluv":[127.715012949239352,164.652954432832814,80.1599403321921],"hsluv":[127.715012949239352,63.4818861677236654,80.1599403321921]},"#77dd88":{"lch":[80.4100305893493754,71.0258644695610855,132.183293417803185],"luv":[80.4100305893493754,-47.69419139775556,52.6301959958607597],"rgb":[0.466666666666666674,0.866666666666666696,0.533333333333333326],"xyz":[0.379063590590106636,0.574106804486018918,0.323772726509792941],"hpluv":[132.183293417803185,150.716476916292407,80.4100305893493754],"hsluv":[132.183293417803185,64.4129914780986184,80.4100305893493754]},"#77dd99":{"lch":[80.7015034668449829,63.0436351039456042,138.421724913218469],"luv":[80.7015034668449829,-47.1597772740100254,41.838443261971527],"rgb":[0.466666666666666674,0.866666666666666696,0.6],"xyz":[0.392120554699179391,0.579329590129648131,0.39253940415091082],"hpluv":[138.421724913218469,136.149613262507529,80.7015034668449829],"hsluv":[138.421724913218469,65.4455974050235909,80.7015034668449829]},"#77ddaa":{"lch":[81.0354720941451916,55.4433276111880673,147.164903113494319],"luv":[81.0354720941451916,-46.5854032558204594,30.0626475895607292],"rgb":[0.466666666666666674,0.866666666666666696,0.66666666666666663],"xyz":[0.407178247664431892,0.585352667315749198,0.471843253767909421],"hpluv":[147.164903113494319,122.204418643173668,81.0354720941451916],"hsluv":[147.164903113494319,66.5644374268903505,81.0354720941451916]},"#77ddbb":{"lch":[81.4127955433910415,49.1817473647014651,159.215751775487576],"luv":[81.4127955433910415,-45.9811599326092804,17.452140415923953],"rgb":[0.466666666666666674,0.866666666666666696,0.733333333333333282],"xyz":[0.424315839771768566,0.592207704158684,0.562101238866551167],"hpluv":[159.215751775487576,110.971854928909636,81.4127955433910415],"hsluv":[159.215751775487576,67.7527973989238461,81.4127955433910415]},"#77ddcc":{"lch":[81.8340936239464298,45.5480287935550479,174.756411210455894],"luv":[81.8340936239464298,-45.3574175840417197,4.16264304083146897],"rgb":[0.466666666666666674,0.866666666666666696,0.8],"xyz":[0.44360821521549032,0.599924654336172813,0.663707749536821323],"hpluv":[174.756411210455894,105.54602277980743,81.8340936239464298],"hsluv":[174.756411210455894,68.9933910523739371,81.8340936239464298]},"#77dddd":{"lch":[82.299760373596115,45.7538051586653296,192.177050630060847],"luv":[82.299760373596115,-44.7243656053231931,-9.65100034703627],"rgb":[0.466666666666666674,0.866666666666666696,0.866666666666666696],"xyz":[0.465126540766123808,0.60853198455642632,0.777037597436827321],"hpluv":[192.177050630060847,109.256318691998032,82.299760373596115],"hsluv":[192.177050630060847,70.2691471280789557,82.299760373596115]},"#77ddee":{"lch":[82.8099771424448221,50.1244355238275574,208.400620203695752],"luv":[82.8099771424448221,-44.0916301090396274,-23.8408722766172367],"rgb":[0.466666666666666674,0.866666666666666696,0.933333333333333348],"xyz":[0.488938721032298573,0.618056856662896337,0.902448413505350544],"hpluv":[208.400620203695752,123.794681382199428,82.8099771424448221],"hsluv":[208.400620203695752,71.5638635335918,82.8099771424448221]},"#77ddff":{"lch":[83.364725787715372,57.9146258331384161,221.361714592462022],"luv":[83.364725787715372,-43.4679842885535521,-38.2705921992655504],"rgb":[0.466666666666666674,0.866666666666666696,1],"xyz":[0.515109769442129939,0.628525276026829061,1.0402826017971325],"hpluv":[221.361714592462022,148.517135389694232,83.364725787715372],"hsluv":[221.361714592462022,99.9999999999953531,83.364725787715372]},"#225500":{"lch":[31.4325909084541877,43.9203091385023825,121.065637009975248],"luv":[31.4325909084541877,-22.6637443991712324,37.6211143459447541],"rgb":[0.133333333333333331,0.333333333333333315,0],"xyz":[0.0390802974883142848,0.0683685824829102229,0.0111370792078428239],"hpluv":[121.065637009975248,177.306450001223254,31.4325909084541877],"hsluv":[121.065637009975248,100.000000000002373,31.4325909084541877]},"#225511":{"lch":[31.5259896590935043,41.027632513747335,123.178290947815412],"luv":[31.5259896590935043,-22.452213479362328,34.3389682366875704],"rgb":[0.133333333333333331,0.333333333333333315,0.0666666666666666657],"xyz":[0.04009196298795141,0.0687732486827650757,0.0164651841725984571],"hpluv":[123.178290947815412,165.138012967735222,31.5259896590935043],"hsluv":[123.178290947815412,90.3912533003173877,31.5259896590935043]},"#225522":{"lch":[31.6981615382414716,36.1013694166085486,127.715012949239792],"luv":[31.6981615382414716,-22.0844473877159331,28.5584673491706482],"rgb":[0.133333333333333331,0.333333333333333315,0.133333333333333331],"xyz":[0.0419673211264284252,0.0695233919381558901,0.0263420703685776497],"hpluv":[127.715012949239792,144.520324593974209,31.6981615382414716],"hsluv":[127.715012949239792,73.5866039174798345,31.6981615382414716]},"#225533":{"lch":[31.9789617713411829,29.2625646618711706,137.400330584271074],"luv":[31.9789617713411829,-21.5402028917408828,19.8070025489176231],"rgb":[0.133333333333333331,0.333333333333333315,0.2],"xyz":[0.0450550718588861657,0.070758492231139,0.0426042242261888],"hpluv":[137.400330584271074,116.114739730974975,31.9789617713411829],"hsluv":[137.400330584271074,75.0932106461487,31.9789617713411829]},"#225544":{"lch":[32.3786649626227785,22.5648709259736577,157.632626155133437],"luv":[32.3786649626227785,-20.8671549807805796,8.58692278490586247],"rgb":[0.133333333333333331,0.333333333333333315,0.266666666666666663],"xyz":[0.0495130671031050462,0.072541690328826583,0.0660829991790754384],"hpluv":[157.632626155133437,88.4327727432137465,32.3786649626227785],"hsluv":[157.632626155133437,76.9882679005547459,32.3786649626227785]},"#225555":{"lch":[32.9031430542149863,20.5945867127178737,192.177050630061132],"luv":[32.9031430542149863,-20.1312179923833199,-4.34408379417313384],"rgb":[0.133333333333333331,0.333333333333333315,0.333333333333333315],"xyz":[0.0554754811424670383,0.0749266559445714159,0.0974850464530493399],"hpluv":[192.177050630061132,79.4245973683706268,32.9031430542149863],"hsluv":[192.177050630061132,79.1137061933639245,32.9031430542149863]},"#225566":{"lch":[33.5545056011551,26.6006796322727546,223.177731373198952],"luv":[33.5545056011551,-19.398136743372234,-18.2018803364993715],"rgb":[0.133333333333333331,0.333333333333333315,0.4],"xyz":[0.0630604769159752165,0.0779606542539747344,0.137432690860193302],"hpluv":[223.177731373198952,100.596116474312993,33.5545056011551],"hsluv":[223.177731373198952,81.3097794801720113,33.5545056011551]},"#225577":{"lch":[34.3316296590174,37.3644949384619807,239.932022094073261],"luv":[34.3316296590174,-18.7206257951117045,-32.3364137134245127],"rgb":[0.133333333333333331,0.333333333333333315,0.466666666666666674],"xyz":[0.0723744899361771221,0.0816862594620555438,0.186486492766591211],"hpluv":[239.932022094073261,138.103289638438355,34.3316296590174],"hsluv":[239.932022094073261,83.4469752602442298,34.3316296590174]},"#225588":{"lch":[35.230707776085,49.7211482448765594,248.610781811292384],"luv":[35.230707776085,-18.1333810040152876,-46.2965773697387775],"rgb":[0.133333333333333331,0.333333333333333315,0.533333333333333326],"xyz":[0.0835149070381209502,0.0861424263028331416,0.245159356170163378],"hpluv":[248.610781811292384,179.084957393431893,35.230707776085],"hsluv":[248.610781811292384,85.4385601139613158,35.230707776085]},"#225599":{"lch":[36.2458273864096512,62.3718238545276336,253.557833057747018],"luv":[36.2458273864096512,-17.6541819100499602,-59.8211858126123],"rgb":[0.133333333333333331,0.333333333333333315,0.6],"xyz":[0.0965718711471936775,0.0913652119464623,0.313926033811281313],"hpluv":[253.557833057747018,218.35832406203005,36.2458273864096512],"hsluv":[253.557833057747018,87.2381583586425791,36.2458273864096512]},"#2255aa":{"lch":[37.3695533294905928,74.8190204360075,256.640324292617947],"luv":[37.3695533294905928,-17.2879233745104131,-72.7943234352841841],"rgb":[0.133333333333333331,0.333333333333333315,0.66666666666666663],"xyz":[0.111629564112446206,0.0973882891325634,0.393229883428279914],"hpluv":[256.640324292617947,254.058329165629146,37.3695533294905928],"hsluv":[256.640324292617947,88.8301308270208807,37.3695533294905928]},"#2255bb":{"lch":[38.5934754222231291,86.8805221786483,258.695157685582501],"luv":[38.5934754222231291,-17.0311035792378,-85.1948745225196831],"rgb":[0.133333333333333331,0.333333333333333315,0.733333333333333282],"xyz":[0.128767156219782852,0.104243325975498152,0.48348786852692166],"hpluv":[258.695157685582501,285.658965815982469,38.5934754222231291],"hsluv":[258.695157685582501,90.2188193496234874,38.5934754222231291]},"#2255cc":{"lch":[39.9086891196534097,98.5112685419302,260.136263381096],"luv":[39.9086891196534097,-16.8755295039118458,-97.0550695930042],"rgb":[0.133333333333333331,0.333333333333333315,0.8],"xyz":[0.148059531663504607,0.111960276152986954,0.585094379197191761],"hpluv":[260.136263381096,313.22597901471056,39.9086891196534097],"hsluv":[260.136263381096,91.4196885710314433,39.9086891196534097]},"#2255dd":{"lch":[41.3061900239028503,109.727240919989157,261.187210775965298],"luv":[41.3061900239028503,-16.8109176424286737,-108.431823962952976],"rgb":[0.133333333333333331,0.333333333333333315,0.866666666666666696],"xyz":[0.16957785721413815,0.120567606373240488,0.698424227097197758],"hpluv":[261.187210775965298,337.084394380702577,41.3061900239028503],"hsluv":[261.187210775965298,92.4531471705562353,41.3061900239028503]},"#2255ee":{"lch":[42.7771763125841602,120.569176865205208,261.977669343247612],"luv":[42.7771763125841602,-16.8265186863462972,-119.389256965822398],"rgb":[0.133333333333333331,0.333333333333333315,0.933333333333333348],"xyz":[0.193390037480312887,0.130092478479710533,0.823835043165721],"hpluv":[261.977669343247612,357.654347674158601,42.7771763125841602],"hsluv":[261.977669343247612,93.3407272081067,42.7771763125841602]},"#2255ff":{"lch":[44.3132637322964129,131.084767922007643,262.587267096581058],"luv":[44.3132637322964129,-16.9120289519133,-129.989229007238322],"rgb":[0.133333333333333331,0.333333333333333315,1],"xyz":[0.219561085890144281,0.140560897843643229,0.961669231457502827],"hpluv":[262.587267096581058,375.368494421854962,44.3132637322964129],"hsluv":[262.587267096581058,99.9999999999993463,44.3132637322964129]},"#77ee00":{"lch":[84.5193058633960703,115.647601499010833,119.483871035599748],"luv":[84.5193058633960703,-56.9192667804191,100.670575649757225],"rgb":[0.466666666666666674,0.933333333333333348,0],"xyz":[0.381807757380814794,0.650690513347127,0.105476708327643554],"hpluv":[119.483871035599748,321.869538605652735,84.5193058633960703],"hsluv":[119.483871035599748,100.000000000002359,84.5193058633960703]},"#77ee11":{"lch":[84.5401392884337355,114.795422022346642,119.691827475064969],"luv":[84.5401392884337355,-56.862163274863434,99.7230329712822083],"rgb":[0.466666666666666674,0.933333333333333348,0.0666666666666666657],"xyz":[0.382819422880451898,0.651095179546981928,0.11080481329239919],"hpluv":[119.691827475064969,319.985367790437692,84.5401392884337355],"hsluv":[119.691827475064969,98.9722780394741477,84.5401392884337355]},"#77ee22":{"lch":[84.5787360835130499,113.228793274865538,120.083373039169615],"luv":[84.5787360835130499,-56.7570256545281637,97.9765260934141651],"rgb":[0.466666666666666674,0.933333333333333348,0.133333333333333331],"xyz":[0.384694781018928955,0.651845322802372729,0.120681699488378383],"hpluv":[120.083373039169615,316.512949618186383,84.5787360835130499],"hsluv":[120.083373039169615,97.0790709390529,84.5787360835130499]},"#77ee33":{"lch":[84.6422206992536275,110.686316006337648,120.745647293955486],"luv":[84.6422206992536275,-56.585921413754825,95.1288286946244313],"rgb":[0.466666666666666674,0.933333333333333348,0.2],"xyz":[0.387782531751386661,0.653080423095355855,0.136943853345989519],"hpluv":[120.745647293955486,310.853610471304819,84.6422206992536275],"hsluv":[120.745647293955486,93.9952250088888093,84.6422206992536275]},"#77ee44":{"lch":[84.7337366993681513,107.096480548503891,121.742158736883837],"luv":[84.7337366993681513,-56.3431952848259598,91.0774422728923412],"rgb":[0.466666666666666674,0.933333333333333348,0.266666666666666663],"xyz":[0.392240526995605576,0.654863621193043421,0.160422628298876158],"hpluv":[121.742158736883837,302.811644310583176,84.7337366993681513],"hsluv":[121.742158736883837,89.6144795711786628,84.7337366993681513]},"#77ee55":{"lch":[84.8558768548969766,102.444399932600575,123.154228511336783],"luv":[84.8558768548969766,-56.0262879596216621,85.7666026785261266],"rgb":[0.466666666666666674,0.933333333333333348,0.333333333333333315],"xyz":[0.398202941034967561,0.657248586808788171,0.191824675572850073],"hpluv":[123.154228511336783,292.298881153811294,84.8558768548969766],"hsluv":[123.154228511336783,83.883891015311761,84.8558768548969766]},"#77ee66":{"lch":[85.0108293450033159,96.7735040486586,125.092887734820366],"luv":[85.0108293450033159,-55.6354444449268186,79.1821217654036],"rgb":[0.466666666666666674,0.933333333333333348,0.4],"xyz":[0.405787936808475747,0.66028258511819149,0.231772319979994035],"hpluv":[125.092887734820366,279.341716913636219,85.0108293450033159],"hsluv":[125.092887734820366,76.7984153057879411,85.0108293450033159]},"#77ee77":{"lch":[85.2004556710930814,90.1918871908529667,127.71501294923965],"luv":[85.2004556710930814,-55.1734745704367882,71.3474892261312306],"rgb":[0.466666666666666674,0.933333333333333348,0.466666666666666674],"xyz":[0.415101949828677652,0.664008190326272341,0.280826121886391944],"hpluv":[127.71501294923965,264.105357222364148,85.2004556710930814],"hsluv":[127.71501294923965,68.3966317942099522,85.2004556710930814]},"#77ee88":{"lch":[85.4263369442757323,82.8846309918514521,131.246169999264879],"luv":[85.4263369442757323,-54.6454688778224167,62.3196179848555],"rgb":[0.466666666666666674,0.933333333333333348,0.533333333333333326],"xyz":[0.426242366930621452,0.668464357167049883,0.339498985289964139],"hpluv":[131.246169999264879,246.94310788397641,85.4263369442757323],"hsluv":[131.246169999264879,69.0963798671032379,85.4263369442757323]},"#77ee99":{"lch":[85.6898036798217,75.1362836057233,136.010896750223054],"luv":[85.6898036798217,-54.0584447513185395,52.1837682153016473],"rgb":[0.466666666666666674,0.933333333333333348,0.6],"xyz":[0.439299331039694207,0.673687142810679096,0.408265662931082],"hpluv":[136.010896750223054,228.489214549916312,85.6898036798217],"hsluv":[136.010896750223054,69.8780652000076827,85.6898036798217]},"#77eeaa":{"lch":[85.9919564191548602,67.3699388554866232,142.461966648640384],"luv":[85.9919564191548602,-53.4209300451477489,41.0476904892764551],"rgb":[0.466666666666666674,0.933333333333333348,0.66666666666666663],"xyz":[0.454357024004946708,0.679710219996780163,0.487569512548080619],"hpluv":[142.461966648640384,209.826142071523691,85.9919564191548602],"hsluv":[142.461966648640384,70.7318226594993575,85.9919564191548602]},"#77eebb":{"lch":[86.3336811163097337,60.2064759054885243,151.166773543866697],"luv":[86.3336811163097337,-52.7425080063862524,29.0352818163428843],"rgb":[0.466666666666666674,0.933333333333333348,0.733333333333333282],"xyz":[0.471494616112283382,0.686565256839714921,0.577827497646722366],"hpluv":[151.166773543866697,192.758378827545073,86.3336811163097337],"hsluv":[151.166773543866697,71.6464628016145895,86.3336811163097337]},"#77eecc":{"lch":[86.7156615657761449,54.5207620102438284,162.626180625161169],"luv":[86.7156615657761449,-52.0333543078463094,16.2801575438255028],"rgb":[0.466666666666666674,0.933333333333333348,0.8],"xyz":[0.490786991556005137,0.694282207017203778,0.679434008316992522],"hpluv":[162.626180625161169,180.150974339718545,86.7156615657761449],"hsluv":[162.626180625161169,72.6100300694190111,86.7156615657761449]},"#77eedd":{"lch":[87.1383902516757445,51.3868015721907483,176.742975614533037],"luv":[87.1383902516757445,-51.3037971188162771,2.91955082350760353],"rgb":[0.466666666666666674,0.933333333333333348,0.866666666666666696],"xyz":[0.512305317106638625,0.702889537237457285,0.792763856216998519],"hpluv":[176.742975614533037,175.997429168902841,87.1383902516757445],"hsluv":[176.742975614533037,73.6103328445444305,87.1383902516757445]},"#77eeee":{"lch":[87.6021784736708327,51.7277775307036,192.177050630061075],"luv":[87.6021784736708327,-50.5639263491039941,-10.9111099540033418],"rgb":[0.466666666666666674,0.933333333333333348,0.933333333333333348],"xyz":[0.536117497372813334,0.712414409343927302,0.918174672285521742],"hpluv":[192.177050630061075,184.503896016801804,87.6021784736708327],"hsluv":[192.177050630061075,74.6354143053272594,87.6021784736708327]},"#77eeff":{"lch":[88.107166277409533,55.7808213308350673,206.722210113893169],"luv":[88.107166277409533,-49.8232704905303336,-25.0826981397535107],"rgb":[0.466666666666666674,0.933333333333333348,1],"xyz":[0.562288545782644755,0.72288282870786,1.05600886057730348],"hpluv":[206.722210113893169,208.278116369071,88.107166277409533],"hsluv":[206.722210113893169,99.9999999999928804,88.107166277409533]},"#226600":{"lch":[37.5582057574881532,54.1200869321592961,123.236537452327113],"luv":[37.5582057574881532,-29.6630419039077431,45.2668505040000824],"rgb":[0.133333333333333331,0.4,0],"xyz":[0.0541083551941607538,0.0984246978946035633,0.0161464317764581713],"hpluv":[123.236537452327113,182.849162381267462,37.5582057574881532],"hsluv":[123.236537452327113,100.000000000002288,37.5582057574881532]},"#226611":{"lch":[37.6315056544729529,51.7196180195473119,124.710513292064419],"luv":[37.6315056544729529,-29.4507212427394194,42.5155725160833242],"rgb":[0.133333333333333331,0.4,0.0666666666666666657],"xyz":[0.0551200206937978721,0.0988293640944584162,0.0214745367412138],"hpluv":[124.710513292064419,174.398618448608886,37.6315056544729529],"hsluv":[124.710513292064419,93.2756924270169918,37.6315056544729529]},"#226622":{"lch":[37.7668566222969062,47.5272711912458519,127.715012949240034],"luv":[37.7668566222969062,-29.0740638670039928,37.5970785719263176],"rgb":[0.133333333333333331,0.4,0.133333333333333331],"xyz":[0.0569953788322748942,0.0995795073498492306,0.031351422937193],"hpluv":[127.715012949240034,159.687663587322874,37.7668566222969062],"hsluv":[127.715012949240034,81.309482828258183,37.7668566222969062]},"#226633":{"lch":[37.9882367851431084,41.3581300307957349,133.555287588173542],"luv":[37.9882367851431084,-28.497993426715972,29.9726423642471254],"rgb":[0.133333333333333331,0.4,0.2],"xyz":[0.0600831295647326347,0.100814607642832343,0.0476135767948041438],"hpluv":[133.555287588173542,138.150062101989391,37.9882367851431084],"hsluv":[133.555287588173542,82.0766642375396742,37.9882367851431084]},"#226644":{"lch":[38.3046909892153806,34.1393686276432291,144.379277801066621],"luv":[38.3046909892153806,-27.7515572052733894,19.8833488873617412],"rgb":[0.133333333333333331,0.4,0.266666666666666663],"xyz":[0.0645411248089515083,0.102597805740519923,0.0710923517476907824],"hpluv":[144.379277801066621,113.094855071532635,38.3046909892153806],"hsluv":[144.379277801066621,83.0794073538424414,38.3046909892153806]},"#226655":{"lch":[38.7222568592555234,28.0005039743963025,163.778220785970291],"luv":[38.7222568592555234,-26.8857357715149732,7.82211191715276755],"rgb":[0.133333333333333331,0.4,0.333333333333333315],"xyz":[0.0705035388483135073,0.104982771356264756,0.102494399021664684],"hpluv":[163.778220785970291,91.7581213405574516,38.7222568592555234],"hsluv":[163.778220785970291,84.2573678500350809,38.7222568592555234]},"#226666":{"lch":[39.2444156655659739,26.5583838540848376,192.177050630061103],"luv":[39.2444156655659739,-25.9608324434988,-5.60204710632589631],"rgb":[0.133333333333333331,0.4,0.4],"xyz":[0.0780885346218216786,0.108016769665668075,0.142442043428808646],"hpluv":[192.177050630061103,85.8742788705857691,39.2444156655659739],"hsluv":[192.177050630061103,85.5381417500271652,39.2444156655659739]},"#226677":{"lch":[39.8723950361637449,31.9118423017057466,218.325872967111877],"luv":[39.8723950361637449,-25.034725973132506,-19.7895976345933065],"rgb":[0.133333333333333331,0.4,0.466666666666666674],"xyz":[0.0874025476420236,0.111742374873748884,0.191495845335206555],"hpluv":[218.325872967111877,101.559108573692257,39.8723950361637449],"hsluv":[218.325872967111877,86.8516914397336137,39.8723950361637449]},"#226688":{"lch":[40.6054458094686836,41.8995680003496318,234.7955790683381],"luv":[40.6054458094686836,-24.1549067561574908,-34.2361545477476241],"rgb":[0.133333333333333331,0.4,0.533333333333333326],"xyz":[0.0985429647439674261,0.116198541714526482,0.250168708738778722],"hpluv":[234.7955790683381,130.937664052949941,40.6054458094686836],"hsluv":[234.7955790683381,88.1401386465251733,40.6054458094686836]},"#226699":{"lch":[41.4411308461218226,53.8933488408681782,244.319142730286046],"luv":[41.4411308461218226,-23.3551142576285748,-48.5698639826860301],"rgb":[0.133333333333333331,0.4,0.6],"xyz":[0.11159992885304014,0.12142132735815564,0.318935386379896657],"hpluv":[244.319142730286046,165.022400136876769,41.4411308461218226],"hsluv":[244.319142730286046,89.3619383181549267,41.4411308461218226]},"#2266aa":{"lch":[42.3756299296545578,66.5269840788925251,250.089735516440328],"luv":[42.3756299296545578,-22.655631138578233,-62.5504755245386193],"rgb":[0.133333333333333331,0.4,0.66666666666666663],"xyz":[0.126657621818292682,0.127444404544256734,0.398239235996895258],"hpluv":[250.089735516440328,199.214522587526545,42.3756299296545578],"hsluv":[250.089735516440328,90.4915899210210597,42.3756299296545578]},"#2266bb":{"lch":[43.404050412459263,79.1834510223872599,253.819475134999237],"luv":[43.404050412459263,-22.0656311263342282,-76.0468726432017803],"rgb":[0.133333333333333331,0.4,0.733333333333333282],"xyz":[0.143795213925629328,0.134299441387191493,0.488497221095537],"hpluv":[253.819475134999237,231.496000814517572,43.404050412459263],"hsluv":[253.819475134999237,91.5168425909476895,43.404050412459263]},"#2266cc":{"lch":[44.520728505208055,91.5877705166709,256.367788484306971],"luv":[44.520728505208055,-21.5861851194902563,-89.0076194502553193],"rgb":[0.133333333333333331,0.4,0.8],"xyz":[0.163087589369351083,0.142016391564680294,0.590103731765807105],"hpluv":[256.367788484306971,261.044502527732277,44.520728505208055],"hsluv":[256.367788484306971,92.43509558526695,44.520728505208055]},"#2266dd":{"lch":[45.7195068588792211,103.627896901795907,258.1878164043369],"luv":[45.7195068588792211,-21.2130654589597789,-101.433460308337743],"rgb":[0.133333333333333331,0.4,0.866666666666666696],"xyz":[0.184605914919984626,0.150623721784933828,0.703433579665813102],"hpluv":[258.1878164043369,287.616948003961852,45.7195068588792211],"hsluv":[258.1878164043369,93.2500413525610696,45.7195068588792211]},"#2266ee":{"lch":[46.9939777237187144,115.273293340910215,259.534328145616598],"luv":[46.9939777237187144,-20.9389771714321675,-113.35559709460216],"rgb":[0.133333333333333331,0.4,0.933333333333333348],"xyz":[0.208418095186159336,0.160148593891403873,0.828844395734336326],"hpluv":[259.534328145616598,311.261797341727515,46.9939777237187144],"hsluv":[259.534328145616598,93.969002023907521,46.9939777237187144]},"#2266ff":{"lch":[48.3376856243364728,126.534150990995641,260.559220542156197],"luv":[48.3376856243364728,-20.75515631493003,-124.820330288598825],"rgb":[0.133333333333333331,0.4,1],"xyz":[0.234589143595990757,0.170617013255336569,0.966678584026118171],"hpluv":[260.559220542156197,332.170629177470857,48.3376856243364728],"hsluv":[260.559220542156197,99.9999999999992184,48.3376856243364728]},"#77ff00":{"lch":[89.5984732569245921,124.632639236881928,120.733702851753719],"luv":[89.5984732569245921,-63.6933378884713406,107.128210438594465],"rgb":[0.466666666666666674,1,0],"xyz":[0.433660129810488626,0.754395258206476127,0.122760832470867665],"hpluv":[120.733702851753719,538.628162219261071,89.5984732569245921],"hsluv":[120.733702851753719,100.000000000002359,89.5984732569245921]},"#77ff11":{"lch":[89.6173512893739144,123.857431845856226,120.915842858481739],"luv":[89.6173512893739144,-63.635285050623331,106.260123846986147],"rgb":[0.466666666666666674,1,0.0666666666666666657],"xyz":[0.43467179531012573,0.754799924406331,0.128088937435623301],"hpluv":[120.915842858481739,536.333532616984598,89.6173512893739144],"hsluv":[120.915842858481739,99.9999999999912461,89.6173512893739144]},"#77ff22":{"lch":[89.6523282897647107,122.430860002153082,121.257903913559275],"luv":[89.6523282897647107,-63.5282943614823736,104.658832863679763],"rgb":[0.466666666666666674,1,0.133333333333333331],"xyz":[0.436547153448602787,0.755550067661721836,0.13796582363160248],"hpluv":[121.257903913559275,532.099457877515,89.6523282897647107],"hsluv":[121.257903913559275,99.9999999999912319,89.6523282897647107]},"#77ff33":{"lch":[89.7098670229763684,120.111567958755899,121.833904144252088],"luv":[89.7098670229763684,-63.3538816193187557,102.044472860004433],"rgb":[0.466666666666666674,1,0.2],"xyz":[0.439634904181060493,0.756785167954705,0.15422797748921363],"hpluv":[121.833904144252088,525.184015431200237,89.7098670229763684],"hsluv":[121.833904144252088,99.9999999999911893,89.7098670229763684]},"#77ff44":{"lch":[89.7928292607091834,116.827732221897932,122.694629127971339],"luv":[89.7928292607091834,-63.1058355300939766,98.317712230097257],"rgb":[0.466666666666666674,1,0.266666666666666663],"xyz":[0.444092899425279408,0.758568366052392529,0.177706752442100269],"hpluv":[122.694629127971339,515.324540814372313,89.7928292607091834],"hsluv":[122.694629127971339,99.9999999999912319,89.7928292607091834]},"#77ff55":{"lch":[89.9035853929870683,112.554947355203538,123.902387884937639],"luv":[89.9035853929870683,-62.7808648215699492,93.4193726503684161],"rgb":[0.466666666666666674,1,0.333333333333333315],"xyz":[0.450055313464641393,0.760953331668137278,0.209108799716074184],"hpluv":[123.902387884937639,502.374863630046946,89.9035853929870683],"hsluv":[123.902387884937639,99.9999999999911466,89.9035853929870683]},"#77ff66":{"lch":[90.0441481999633169,107.316590618570714,125.538864396596409],"luv":[90.0441481999633169,-62.3783098318914213,87.3258099562234662],"rgb":[0.466666666666666674,1,0.4],"xyz":[0.457640309238149579,0.763987329977540597,0.249056444123218146],"hpluv":[125.538864396596409,486.310350268178581,90.0441481999633169],"hsluv":[125.538864396596409,99.9999999999909193,90.0441481999633169]},"#77ff77":{"lch":[90.2162444924982,101.18761180958829,127.715012949239778],"luv":[90.2162444924982,-61.8999369112410065,80.0458031011764746],"rgb":[0.466666666666666674,1,0.466666666666666674],"xyz":[0.466954322258351484,0.767712935185621448,0.298110246029616055],"hpluv":[127.715012949239778,467.252180695244249,90.2162444924982],"hsluv":[127.715012949239778,99.9999999999908908,90.2162444924982]},"#77ff88":{"lch":[90.4213578195287084,94.3018691223763312,130.584388318929172],"luv":[90.4213578195287084,-61.3497133683486666,71.6174223886566352],"rgb":[0.466666666666666674,1,0.533333333333333326],"xyz":[0.478094739360295284,0.772169102026399,0.35678310943318825],"hpluv":[130.584388318929172,445.517691352744919,90.4213578195287084],"hsluv":[130.584388318929172,99.999999999990834,90.4213578195287084]},"#77ff99":{"lch":[90.660755936805927,86.8649116623181,134.360625617567337],"luv":[90.660755936805927,-60.7335297134313734,62.1043577106315],"rgb":[0.466666666666666674,1,0.6],"xyz":[0.491151703469368,0.777391887670028203,0.425549787074306129],"hpluv":[134.360625617567337,421.714412879972315,90.660755936805927],"hsluv":[134.360625617567337,99.9999999999904645,90.660755936805927]},"#77ffaa":{"lch":[90.9355096576679927,79.1755179707932513,139.336843070371486],"luv":[90.9355096576679927,-60.0588662825700368,51.5916197341755947],"rgb":[0.466666666666666674,1,0.66666666666666663],"xyz":[0.506209396434620595,0.78341496485612927,0.504853636691304786],"hpluv":[139.336843070371486,396.909453229520182,90.9355096576679927],"hsluv":[139.336843070371486,99.9999999999902371,90.9355096576679927]},"#77ffbb":{"lch":[91.2465066485729466,71.6593730134265599,145.894485367843032],"luv":[91.2465066485729466,-59.3344173347434776,40.1807498713488229],"rgb":[0.466666666666666674,1,0.733333333333333282],"xyz":[0.523346988541957159,0.790270001699064,0.595111621789946477],"hpluv":[145.894485367843032,372.920765055848051,91.2465066485729466],"hsluv":[145.894485367843032,99.9999999999901803,91.2465066485729466]},"#77ffcc":{"lch":[91.5944622372901591,64.9119206982031329,154.461378490718602],"luv":[91.5944622372901591,-58.5696939322881676,27.9847887504604707],"rgb":[0.466666666666666674,1,0.8],"xyz":[0.542639363985678913,0.797986951876552886,0.696718132460216633],"hpluv":[154.461378490718602,352.767904832744364,91.5944622372901591],"hsluv":[154.461378490718602,99.999999999989825,91.5944622372901591]},"#77ffdd":{"lch":[91.9799284987297,59.7212008687906604,165.331177548206284],"luv":[91.9799284987297,-57.7746296637575298,15.1232933062250314],"rgb":[0.466666666666666674,1,0.866666666666666696],"xyz":[0.564157689536312512,0.806594282096806392,0.81004798036022263],"hpluv":[165.331177548206284,341.200809564626638,91.9799284987297],"hsluv":[165.331177548206284,99.9999999999894698,91.9799284987297]},"#77ffee":{"lch":[92.4033024177180238,56.9851054432815545,178.272694676027839],"luv":[92.4033024177180238,-56.9592119034112,1.71767916801026743],"rgb":[0.466666666666666674,1,0.933333333333333348],"xyz":[0.587969869802487222,0.816119154203276409,0.935458796428745853],"hpluv":[178.272694676027839,344.865805035808421,92.4033024177180238],"hsluv":[178.272694676027839,99.9999999999889582,92.4033024177180238]},"#77ffff":{"lch":[92.8648336399367196,57.4251975820971623,192.177050630061018],"luv":[92.8648336399367196,-56.1331570721439945,-12.112885471963672],"rgb":[0.466666666666666674,1,1],"xyz":[0.614140918212318643,0.826587573567209133,1.0732929847205277],"hpluv":[192.177050630061018,371.354821198433683,92.8648336399367196],"hsluv":[192.177050630061018,99.9999999999883187,92.8648336399367196]},"#227700":{"lch":[43.5559297152692295,63.9882214930525208,124.519604676885976],"luv":[43.5559297152692295,-36.2613695379953711,52.7219647687080268],"rgb":[0.133333333333333331,0.466666666666666674,0],"xyz":[0.0725620932475783825,0.13533217400143932,0.0222976777942638753],"hpluv":[124.519604676885976,186.419817132403381,43.5559297152692295],"hsluv":[124.519604676885976,100.000000000002331,43.5559297152692295]},"#227711":{"lch":[43.6152314308602769,61.9621092027414093,125.591738779589861],"luv":[43.6152314308602769,-36.0623023987336282,50.3866383335378174],"rgb":[0.133333333333333331,0.466666666666666674,0.0666666666666666657],"xyz":[0.0735737587472155,0.135736840201294173,0.0276257827590195085],"hpluv":[125.591738779589861,180.271610265320959,43.6152314308602769],"hsluv":[125.591738779589861,95.0867888092805345,43.6152314308602769]},"#227722":{"lch":[43.7248500006056062,58.3665782213362476,127.715012949240148],"luv":[43.7248500006056062,-35.7048401974777292,46.1716562377823081],"rgb":[0.133333333333333331,0.466666666666666674,0.133333333333333331],"xyz":[0.0754491168856925298,0.136486983456685,0.0375026689549987],"hpluv":[127.715012949240148,169.385110384242353,43.7248500006056062],"hsluv":[127.715012949240148,86.2472116803111248,43.7248500006056062]},"#227733":{"lch":[43.9044636679785,52.8998675233047422,131.63685913347058],"luv":[43.9044636679785,-35.1470498804547518,39.5358175416168365],"rgb":[0.133333333333333331,0.466666666666666674,0.2],"xyz":[0.0785368676181502634,0.137722083749668101,0.0537648228126098443],"hpluv":[131.63685913347058,152.892166506547881,43.9044636679785],"hsluv":[131.63685913347058,86.6671370230467204,43.9044636679785]},"#227744":{"lch":[44.1618994548856207,46.0187725021067919,138.382113458020484],"luv":[44.1618994548856207,-34.403210499316,30.5638107889119937],"rgb":[0.133333333333333331,0.466666666666666674,0.266666666666666663],"xyz":[0.082994862862369137,0.139505281847355694,0.0772435977654964828],"hpluv":[138.382113458020484,132.228969104156789,44.1618994548856207],"hsluv":[138.382113458020484,87.230083060842972,44.1618994548856207]},"#227755":{"lch":[44.5028042963196171,38.7961505601339098,149.7341572603126],"luv":[44.5028042963196171,-33.5080868304533865,19.5537570621958743],"rgb":[0.133333333333333331,0.466666666666666674,0.333333333333333315],"xyz":[0.088957276901731136,0.141890247463100527,0.108645645039470398],"hpluv":[149.7341572603126,110.621765171639552,44.5028042963196171],"hsluv":[149.7341572603126,87.9126674499387235,44.5028042963196171]},"#227766":{"lch":[44.9310046324235657,33.2418513983527504,167.948858330193701],"luv":[44.9310046324235657,-32.5092552143098246,6.94038974417402166],"rgb":[0.133333333333333331,0.466666666666666674,0.4],"xyz":[0.0965422726752393073,0.144924245772503818,0.148593289446614346],"hpluv":[167.948858330193701,93.8811500215461,44.9310046324235657],"hsluv":[167.948858330193701,88.6822605795820778,44.9310046324235657]},"#227777":{"lch":[45.4487163896678652,32.1827345016432886,192.177050630061217],"luv":[45.4487163896678652,-31.4586377906525136,-6.7884098550242733],"rgb":[0.133333333333333331,0.466666666666666674,0.466666666666666674],"xyz":[0.105856285695441227,0.148649850980584641,0.197647091353012255],"hpluv":[192.177050630061217,89.8546686552558,45.4487163896678652],"hsluv":[192.177050630061217,89.5029511213474,45.4487163896678652]},"#227788":{"lch":[46.0567093690380389,37.0457871068229778,214.840569513336618],"luv":[46.0567093690380389,-30.4051407329018595,-21.1640676472289648],"rgb":[0.133333333333333331,0.466666666666666674,0.533333333333333326],"xyz":[0.116996702797385055,0.153106017821362239,0.256319954756584423],"hpluv":[214.840569513336618,102.066975938242322,46.0567093690380389],"hsluv":[214.840569513336618,90.3407286635711415,46.0567093690380389]},"#227799":{"lch":[46.7544651468991219,46.3079141704010908,230.605362437026685],"luv":[46.7544651468991219,-29.3896969252833173,-35.7864308006991223],"rgb":[0.133333333333333331,0.466666666666666674,0.6],"xyz":[0.130053666906457754,0.158328803464991397,0.325086632397702358],"hpluv":[230.605362437026685,125.681528260779189,46.7544651468991219],"hsluv":[230.605362437026685,91.1669787694701,46.7544651468991219]},"#2277aa":{"lch":[47.5403420753171133,57.8256716053654429,240.536105931551504],"luv":[47.5403420753171133,-28.4430017925967782,-50.3468365007961935],"rgb":[0.133333333333333331,0.466666666666666674,0.66666666666666663],"xyz":[0.14511135987171031,0.164351880651092491,0.404390482014700958],"hpluv":[240.536105931551504,154.346828351852139,47.5403420753171133],"hsluv":[240.536105931551504,91.9600907928071365,47.5403420753171133]},"#2277bb":{"lch":[48.4117490016133161,70.2708193466387172,246.886175208709233],"luv":[48.4117490016133161,-27.5854458877112236,-64.6299561103370337],"rgb":[0.133333333333333331,0.466666666666666674,0.733333333333333282],"xyz":[0.162248951979046957,0.17120691749402725,0.494648467113342705],"hpluv":[246.886175208709233,184.188949495161438,48.4117490016133161],"hsluv":[246.886175208709233,92.7055270960754427,48.4117490016133161]},"#2277cc":{"lch":[49.3653235224945348,82.9601291275659634,251.131977113837081],"luv":[49.3653235224945348,-26.8284223951791141,-78.5023488607078],"rgb":[0.133333333333333331,0.466666666666666674,0.8],"xyz":[0.181541327422768684,0.178923867671516051,0.596254977783612805],"hpluv":[251.131977113837081,213.248879712122147,49.3653235224945348],"hsluv":[251.131977113837081,93.3949294454883301,49.3653235224945348]},"#2277dd":{"lch":[50.3971082370692898,95.5506012475210156,254.100456017762497],"luv":[50.3971082370692898,-26.1762366694964186,-91.8951687118820928],"rgb":[0.133333333333333331,0.466666666666666674,0.866666666666666696],"xyz":[0.203059652973402227,0.187531197891769585,0.709584825683618803],"hpluv":[254.100456017762497,240.584217083197558,50.3971082370692898],"hsluv":[254.100456017762497,94.0248036114472399,50.3971082370692898]},"#2277ee":{"lch":[51.5027182397596448,107.874744495734575,256.256689112315712],"luv":[51.5027182397596448,-25.6280715933506258,-104.786270314512635],"rgb":[0.133333333333333331,0.466666666666666674,0.933333333333333348],"xyz":[0.226871833239577,0.19705606999823963,0.834995641752142],"hpluv":[256.256689112315712,265.784074864026707,51.5027182397596448],"hsluv":[256.256689112315712,94.5951642228933594,51.5027182397596448]},"#2277ff":{"lch":[52.6774941409559432,119.859275592882611,257.873120264558906],"luv":[52.6774941409559432,-25.1797078347732324,-117.18459053564186],"rgb":[0.133333333333333331,0.466666666666666674,1],"xyz":[0.253042881649408358,0.207524489362172326,0.972829830043923871],"hpluv":[257.873120264558906,288.725982332353851,52.6774941409559432],"hsluv":[257.873120264558906,99.9999999999990195,52.6774941409559432]},"#228800":{"lch":[49.4326013626652951,73.5543249838887903,125.335546592141156],"luv":[49.4326013626652951,-42.5411625112882845,60.0040683289365475],"rgb":[0.133333333333333331,0.533333333333333326,0],"xyz":[0.0946344629725488357,0.179476913451380865,0.0296551343692538216],"hpluv":[125.335546592141156,188.81394887832684,49.4326013626652951],"hsluv":[125.335546592141156,100.000000000002359,49.4326013626652951]},"#228811":{"lch":[49.4817413630627669,71.8188220709608,126.143293588176633],"luv":[49.4817413630627669,-42.3592238010278379,57.9968909738682825],"rgb":[0.133333333333333331,0.533333333333333326,0.0666666666666666657],"xyz":[0.0956461284721859539,0.179881579651235718,0.0349832393340094513],"hpluv":[126.143293588176633,184.175827324420425,49.4817413630627669],"hsluv":[126.143293588176633,96.2839239867753776,49.4817413630627669]},"#228822":{"lch":[49.5726392440562904,68.7061860444130161,127.715012949240233],"luv":[49.5726392440562904,-42.0299333634258545,54.3509402148249521],"rgb":[0.133333333333333331,0.533333333333333326,0.133333333333333331],"xyz":[0.097521486610662983,0.180631722906626546,0.0448601255299886509],"hpluv":[127.715012949240233,175.870551812838869,49.5726392440562904],"hsluv":[127.715012949240233,89.549457305464,49.5726392440562904]},"#228833":{"lch":[49.7217546026668913,63.8760413965615115,130.529662443073192],"luv":[49.7217546026668913,-41.5093107949551552,48.5502397710151357],"rgb":[0.133333333333333331,0.533333333333333326,0.2],"xyz":[0.100609237343120717,0.181866823199609645,0.0611222793875997941],"hpluv":[130.529662443073192,163.016240956960957,49.7217546026668913],"hsluv":[130.529662443073192,89.7937238944362122,49.7217546026668913]},"#228844":{"lch":[49.9358562328630171,57.5522088774297558,135.149605574971361],"luv":[49.9358562328630171,-40.8016788905052792,40.5891579906186308],"rgb":[0.133333333333333331,0.533333333333333326,0.266666666666666663],"xyz":[0.10506723258733959,0.183650021297297239,0.0846010543404864257],"hpluv":[135.149605574971361,146.247625060139768,49.9358562328630171],"hsluv":[135.149605574971361,90.1269016918236616,49.9358562328630171]},"#228855":{"lch":[50.2200542052193697,50.3265642713731509,142.503880569306347],"luv":[50.2200542052193697,-39.9288227743001443,30.6341669254964764],"rgb":[0.133333333333333331,0.533333333333333326,0.333333333333333315],"xyz":[0.111029646626701589,0.186034986913042072,0.116003101614460341],"hpluv":[142.503880569306347,127.162609675202816,50.2200542052193697],"hsluv":[142.503880569306347,90.5399352865824341,50.2200542052193697]},"#228866":{"lch":[50.5781035519961648,43.3062651916131074,154.006170397495453],"luv":[50.5781035519961648,-38.9254575775356315,18.9800252166796355],"rgb":[0.133333333333333331,0.533333333333333326,0.4],"xyz":[0.11861464240020976,0.189068985222445363,0.155950746021604303],"hpluv":[154.006170397495453,108.649446020320369,50.5781035519961648],"hsluv":[154.006170397495453,91.0179493017372607,50.5781035519961648]},"#228877":{"lch":[51.0125694858746357,38.3061120533697519,170.992189866461246],"luv":[51.0125694858746357,-37.8336830583721451,5.997553408179356],"rgb":[0.133333333333333331,0.533333333333333326,0.466666666666666674],"xyz":[0.12792865542041168,0.192794590430526186,0.205004547928002212],"hpluv":[170.992189866461246,95.2862426106229634,51.0125694858746357],"hsluv":[170.992189866461246,91.5427076584867621,51.0125694858746357]},"#228888":{"lch":[51.5249413470067594,37.5420496271247259,192.177050630061103],"luv":[51.5249413470067594,-36.6973707929670923,-7.91886779085127834],"rgb":[0.133333333333333331,0.533333333333333326,0.533333333333333326],"xyz":[0.139069072522355508,0.197250757271303784,0.263677411331574407],"hpluv":[192.177050630061103,92.4570004995607775,51.5249413470067594],"hsluv":[192.177050630061103,92.0950966753639761,51.5249413470067594]},"#228899":{"lch":[52.1157302062907064,42.0223592343639183,212.203992327233067],"luv":[52.1157302062907064,-35.5574728144251,-22.3951959730954577],"rgb":[0.133333333333333331,0.533333333333333326,0.6],"xyz":[0.152126036631428208,0.202473542914932941,0.332444088972692287],"hpluv":[212.203992327233067,102.317738016510475,52.1157302062907064],"hsluv":[212.203992327233067,92.6571999954113465,52.1157302062907064]},"#2288aa":{"lch":[52.784565077464336,50.6329849579481888,227.127925237574203],"luv":[52.784565077464336,-34.4488478228089221,-37.1076279143892478],"rgb":[0.133333333333333331,0.533333333333333326,0.66666666666666663],"xyz":[0.167183729596680763,0.208496620101034036,0.411747938589690887],"hpluv":[227.127925237574203,121.72111165959474,52.784565077464336],"hsluv":[227.127925237574203,93.213704377986,52.784565077464336]},"#2288bb":{"lch":[53.5302933631107294,61.6316847476891141,237.186375672219185],"luv":[53.5302933631107294,-33.3987075035381409,-51.7975955226846381],"rgb":[0.133333333333333331,0.533333333333333326,0.733333333333333282],"xyz":[0.18432132170401741,0.215351656943968794,0.502005923688332634],"hpluv":[237.186375672219185,146.097822373379188,53.5302933631107294],"hsluv":[237.186375672219185,93.7525919029994,53.5302933631107294]},"#2288cc":{"lch":[54.351086283976727,73.7818378825302261,243.928624140525301],"luv":[54.351086283976727,-32.4264148607849876,-66.274333045306733],"rgb":[0.133333333333333331,0.533333333333333326,0.8],"xyz":[0.203613697147739137,0.223068607121457596,0.60361243435860279],"hpluv":[243.928624140525301,172.258462735913952,54.351086283976727],"hsluv":[243.928624140525301,94.2652369190112864,54.351086283976727]},"#2288dd":{"lch":[55.2445474530087779,86.375042864399532,248.580085361336785],"luv":[55.2445474530087779,-31.544198041281593,-80.4090268549449831],"rgb":[0.133333333333333331,0.533333333333333326,0.866666666666666696],"xyz":[0.22513202269837268,0.23167593734171113,0.716942282258608787],"hpluv":[248.580085361336785,198.39840761978212,55.2445474530087779],"hsluv":[248.580085361336785,94.7460999996689566,55.2445474530087779]},"#2288ee":{"lch":[56.2078215466105604,99.0227420546019772,251.903461744910402],"luv":[56.2078215466105604,-30.7583451142169402,-94.1245326673496265],"rgb":[0.133333333333333331,0.533333333333333326,0.933333333333333348],"xyz":[0.248944202964547445,0.241200809448181175,0.842353098327132],"hpluv":[251.903461744910402,223.551465466634539,56.2078215466105604],"hsluv":[251.903461744910402,95.1922101623356838,56.2078215466105604]},"#2288ff":{"lch":[57.2376997180489866,111.514610807296222,254.356224713070389],"luv":[57.2376997180489866,-30.0705415498761575,-107.383755542446536],"rgb":[0.133333333333333331,0.533333333333333326,1],"xyz":[0.275115251374378811,0.251669228812113843,0.980187286618913856],"hpluv":[254.356224713070389,247.223031548482197,57.2376997180489866],"hsluv":[254.356224713070389,99.9999999999988773,57.2376997180489866]},"#229900":{"lch":[55.1973816023000694,82.8565734474734086,125.883775052172936],"luv":[55.1973816023000694,-48.5657961090338617,67.1310301704979508],"rgb":[0.133333333333333331,0.6,0],"xyz":[0.120504063425016322,0.23121611435631656,0.0382783345200760766],"hpluv":[125.883775052172936,190.479314261094402,55.1973816023000694],"hsluv":[125.883775052172936,100.000000000002331,55.1973816023000694]},"#229911":{"lch":[55.2388931006948951,81.3509781714907376,126.510168490119042],"luv":[55.2388931006948951,-48.4010205856972817,65.3859530459048273],"rgb":[0.133333333333333331,0.6,0.0666666666666666657],"xyz":[0.121515728924653441,0.231620780556171413,0.0436064394848317063],"hpluv":[126.510168490119042,186.877552842351321,55.2388931006948951],"hsluv":[126.510168490119042,97.109403045153627,55.2388931006948951]},"#229922":{"lch":[55.3157166450500739,78.6308396618125869,127.715012949240275],"luv":[55.3157166450500739,-48.1011847922964293,62.2019691609440102],"rgb":[0.133333333333333331,0.6,0.133333333333333331],"xyz":[0.12339108706313047,0.232370923811562241,0.0534833256808109059],"hpluv":[127.715012949240275,180.378053709807,55.3157166450500739],"hsluv":[127.715012949240275,91.8445791693357592,55.3157166450500739]},"#229933":{"lch":[55.4418461137647,74.3518111171957656,129.829614369777261],"luv":[55.4418461137647,-47.6228343175573201,57.0986643273697],"rgb":[0.133333333333333331,0.6,0.2],"xyz":[0.126478837795588217,0.23360602410454534,0.0697454795384220561],"hpluv":[129.829614369777261,170.173995330187722,55.4418461137647],"hsluv":[129.829614369777261,91.9941043082508827,55.4418461137647]},"#229944":{"lch":[55.6231658975890042,68.6117263626113925,133.195472742568398],"luv":[55.6231658975890042,-46.964006542137362,50.0195070344354846],"rgb":[0.133333333333333331,0.6,0.266666666666666663],"xyz":[0.130936833039807077,0.235389222202232934,0.0932242544913087],"hpluv":[133.195472742568398,156.524371813771666,55.6231658975890042],"hsluv":[133.195472742568398,92.2005608183228844,55.6231658975890042]},"#229955":{"lch":[55.8642490130281715,61.7521412094073696,138.342726405552],"luv":[55.8642490130281715,-46.1371272258517706,41.0450049980768625],"rgb":[0.133333333333333331,0.6,0.333333333333333315],"xyz":[0.136899247079169062,0.237774187817977767,0.124626301765282596],"hpluv":[138.342726405552,140.267605312348593,55.8642490130281715],"hsluv":[138.342726405552,92.4605995247666357,55.8642490130281715]},"#229966":{"lch":[56.1686206396836383,54.4254646973719787,146.085824005346524],"luv":[56.1686206396836383,-45.1662924386951516,30.3667126121210664],"rgb":[0.133333333333333331,0.6,0.4],"xyz":[0.144484242852677247,0.240808186127381058,0.164573946172426544],"hpluv":[146.085824005346524,122.955430161041207,56.1686206396836383],"hsluv":[146.085824005346524,92.7673635780271,56.1686206396836383]},"#229977":{"lch":[56.5388973522399,47.7139826201784629,157.505617321427167],"luv":[56.5388973522399,-44.0837619060267798,18.2550287233801534],"rgb":[0.133333333333333331,0.6,0.466666666666666674],"xyz":[0.153798255872879153,0.244533791335461881,0.213627748078824453],"hpluv":[157.505617321427167,107.087223886255089,56.5388973522399],"hsluv":[157.505617321427167,93.1115325865156,56.5388973522399]},"#229988":{"lch":[56.9768757530356,43.2189787336254057,173.325138204180888],"luv":[56.9768757530356,-42.9260293704251126,5.02355703331473169],"rgb":[0.133333333333333331,0.6,0.533333333333333326],"xyz":[0.164938672974823,0.248989958176239479,0.272300611482396648],"hpluv":[173.325138204180888,96.2532040641867,56.9768757530356],"hsluv":[173.325138204180888,93.4824878896153706,56.9768757530356]},"#229999":{"lch":[57.4836007022547477,42.6905833214490045,192.177050630061103],"luv":[57.4836007022547477,-41.7300648492924537,-9.00486490733903366],"rgb":[0.133333333333333331,0.6,0.6],"xyz":[0.177995637083895708,0.254212743819868636,0.341067289123514528],"hpluv":[192.177050630061103,94.2383018299879467,57.4836007022547477],"hsluv":[192.177050630061103,93.8694254698009587,57.4836007022547477]},"#2299aa":{"lch":[58.0594270662980563,46.8633307325653,210.133219640519371],"luv":[58.0594270662980563,-40.5302437993065823,-23.5259666096543114],"rgb":[0.133333333333333331,0.6,0.66666666666666663],"xyz":[0.193053330049148264,0.260235821005969759,0.420371138740513128],"hpluv":[210.133219640519371,102.423528384682896,58.0594270662980563],"hsluv":[210.133219640519371,94.2622655036202701,58.0594270662980563]},"#2299bb":{"lch":[58.704081470592044,54.8976329577059445,224.200669016044458],"luv":[58.704081470592044,-39.3562485070025474,-38.2731734745639],"rgb":[0.133333333333333331,0.6,0.733333333333333282],"xyz":[0.210190922156484883,0.267090857848904517,0.51062912383915493],"hpluv":[224.200669016044458,118.665547847191604,58.704081470592044],"hsluv":[224.200669016044458,94.6522748426748279,58.704081470592044]},"#2299cc":{"lch":[59.4167266489170771,65.3729917945351247,234.209137470411804],"luv":[59.4167266489170771,-38.231976961148348,-53.0277662532618663],"rgb":[0.133333333333333331,0.6,0.8],"xyz":[0.229483297600206637,0.274807808026393319,0.612235634509425086],"hpluv":[234.209137470411804,139.613998456385502,59.4167266489170771],"hsluv":[234.209137470411804,95.032392249276171,59.4167266489170771]},"#2299dd":{"lch":[60.1960287785942114,77.1664383037622201,241.199920521286145],"luv":[60.1960287785942114,-37.1753089722913614,-67.6214137925481],"rgb":[0.133333333333333331,0.6,0.866666666666666696],"xyz":[0.251001623150840181,0.283415138246646825,0.725565482409431084],"hpluv":[241.199920521286145,162.667181112599422,60.1960287785942114],"hsluv":[241.199920521286145,95.397300800485425,60.1960287785942114]},"#2299ee":{"lch":[61.0402269370523243,89.5733454479413211,246.163931095701571],"luv":[61.0402269370523243,-36.1984881015500051,-81.9332269222821],"rgb":[0.133333333333333331,0.6,0.933333333333333348],"xyz":[0.27481380341701489,0.292940010353116842,0.850976298477954307],"hpluv":[246.163931095701571,186.209563381880429,61.0402269370523243],"hsluv":[246.163931095701571,95.74331870201,61.0402269370523243]},"#2299ff":{"lch":[61.9472031658153384,102.178145565387652,249.783903318571561],"luv":[61.9472031658153384,-35.3088685699608078,-95.8835607989752532],"rgb":[0.133333333333333331,0.6,1],"xyz":[0.300984851826846311,0.303408429717049566,0.988810486769736152],"hpluv":[249.783903318571561,209.303089797111312,61.9472031658153384],"hsluv":[249.783903318571561,99.9999999999986,61.9472031658153384]},"#110000":{"lch":[1.07666134976862637,3.62084603829176643,12.1770506300617818],"luv":[1.07666134976862637,3.53937866928378497,0.763756943295526236],"rgb":[0.0666666666666666657,0,0],"xyz":[0.00231161193210362246,0.00119192490249095569,0.000108356809317355026],"hpluv":[12.1770506300617818,426.746789183125145,1.07666134976862637],"hsluv":[12.1770506300617818,100.000000000002203,1.07666134976862637]},"#110011":{"lch":[1.44219482929484544,3.28508596549136378,307.715012949243601],"luv":[1.44219482929484544,2.00959989444743092,-2.59871084672866193],"rgb":[0.0666666666666666657,0,0.0666666666666666657],"xyz":[0.0033232774317407442,0.00159659110234581,0.00543646177407298634],"hpluv":[307.715012949243601,289.042783730483393,1.44219482929484544],"hsluv":[307.715012949243601,99.9999999999988347,1.44219482929484544]},"#110022":{"lch":[2.1197964535087821,6.27745605271938789,280.884754167684719],"luv":[2.1197964535087821,1.18539805862553327,-6.16451830530416167],"rgb":[0.0666666666666666657,0,0.133333333333333331],"xyz":[0.00519863557021776369,0.00234673435773662814,0.0153133479700521824],"hpluv":[280.884754167684719,375.775833064690062,2.1197964535087821],"hsluv":[280.884754167684719,99.9999999999998721,2.1197964535087821]},"#110033":{"lch":[3.23545797359596321,11.0622687483975319,272.972319481398301],"luv":[3.23545797359596321,0.57361730895702967,-11.0473867065762477],"rgb":[0.0666666666666666657,0,0.2],"xyz":[0.00828638630267550247,0.00358183465071974143,0.0315755018276633256],"hpluv":[272.972319481398301,433.858158519435221,3.23545797359596321],"hsluv":[272.972319481398301,100.000000000000355,3.23545797359596321]},"#110044":{"lch":[4.84621421062803659,17.7312810137515946,269.891014646828467],"luv":[4.84621421062803659,-0.0337275934556249754,-17.7312489362161827],"rgb":[0.0666666666666666657,0,0.266666666666666663],"xyz":[0.012744381546894383,0.0053650327484073175,0.0550542767805499642],"hpluv":[269.891014646828467,464.276639746945534,4.84621421062803659],"hsluv":[269.891014646828467,100.000000000000711,4.84621421062803659]},"#110055":{"lch":[7.00054481789469563,26.532890242342738,268.413820694361107],"luv":[7.00054481789469563,-0.734444075336115332,-26.5227233992365541],"rgb":[0.0666666666666666657,0,0.333333333333333315],"xyz":[0.0187067955862563751,0.00774999836415214954,0.0864563240545238726],"hpluv":[268.413820694361107,480.941270902403687,7.00054481789469563],"hsluv":[268.413820694361107,100.000000000000682,7.00054481789469563]},"#110066":{"lch":[9.62818818466394,37.2351477319955,267.604082628906383],"luv":[9.62818818466394,-1.55659527409507947,-37.20259719127408],"rgb":[0.0666666666666666657,0,0.4],"xyz":[0.0262917913597645499,0.010783996673555462,0.126403968461667848],"hpluv":[267.604082628906383,490.735908571457742,9.62818818466394],"hsluv":[267.604082628906383,100.000000000000753,9.62818818466394]},"#110077":{"lch":[12.2928363787590555,48.1341065988899643,267.117295446388],"luv":[12.2928363787590555,-2.42073458662620622,-48.0731969202633138],"rgb":[0.0666666666666666657,0,0.466666666666666674],"xyz":[0.0356058043799664659,0.0145096018816362783,0.175457770368065757],"hpluv":[267.117295446388,496.866985521105335,12.2928363787590555],"hsluv":[267.117295446388,100.000000000000739,12.2928363787590555]},"#110088":{"lch":[14.9348588897968106,58.9551979191609803,266.804247897724281],"luv":[14.9348588897968106,-3.28660375460643372,-58.8635166928348781],"rgb":[0.0666666666666666657,0,0.533333333333333326],"xyz":[0.0467462214819102939,0.0189657687224138727,0.234130633771637925],"hpluv":[266.804247897724281,500.910695182750828,14.9348588897968106],"hsluv":[266.804247897724281,100.000000000000753,14.9348588897968106]},"#110099":{"lch":[17.5475874535139624,69.6538923837914297,266.59230255326986],"luv":[17.5475874535139624,-4.14026096141065292,-69.5307339482636],"rgb":[0.0666666666666666657,0,0.6],"xyz":[0.0598031855909830073,0.0241885543660430302,0.302897311412755832],"hpluv":[266.59230255326986,503.694607743992833,17.5475874535139624],"hsluv":[266.59230255326986,100.000000000000796,17.5475874535139624]},"#1100aa":{"lch":[20.1284543895036734,80.2134478690449,266.442863009455],"luv":[20.1284543895036734,-4.97675334080985809,-80.0589104673847203],"rgb":[0.0666666666666666657,0,0.66666666666666663],"xyz":[0.0748608785562355494,0.0302116315521441317,0.382201161029754433],"hpluv":[266.442863009455,505.680355905096519,20.1284543895036734],"hsluv":[266.442863009455,100.000000000000782,20.1284543895036734]},"#1100bb":{"lch":[22.6769756305364183,90.6302333913987894,266.3339747285724],"luv":[22.6769756305364183,-5.79494806122388795,-90.444777525002138],"rgb":[0.0666666666666666657,0,0.733333333333333282],"xyz":[0.0919984706635722,0.0370666683950788903,0.472459146128396179],"hpluv":[266.3339747285724,507.139328846885462,22.6769756305364183],"hsluv":[266.3339747285724,100.000000000001,22.6769756305364183]},"#1100cc":{"lch":[25.1937235339869332,100.906819147977927,266.252448568601267],"luv":[25.1937235339869332,-6.59531864805210422,-100.691051849175651],"rgb":[0.0666666666666666657,0,0.8],"xyz":[0.111290846107293936,0.0447836185725676919,0.574065656798666279],"hpluv":[266.252448568601267,508.238409831726415,25.1937235339869332],"hsluv":[266.252448568601267,100.000000000000824,25.1937235339869332]},"#1100dd":{"lch":[27.6797893663012289,111.048607057141055,266.189998210144608],"luv":[27.6797893663012289,-7.37896669992084409,-110.803176758488192],"rgb":[0.0666666666666666657,0,0.866666666666666696],"xyz":[0.132809171657927494,0.0533909487928212259,0.687395504698672277],"hpluv":[266.189998210144608,509.084249760461944,27.6797893663012289],"hsluv":[266.189998210144608,100.000000000000938,27.6797893663012289]},"#1100ee":{"lch":[30.1364964584496846,121.062148077250455,266.141219022825339],"luv":[30.1364964584496846,-8.14718371295858823,-120.787694301304626],"rgb":[0.0666666666666666657,0,0.933333333333333348],"xyz":[0.156621351924102231,0.0629158208992912638,0.8128063207671955],"hpluv":[266.141219022825339,509.74730741907581,30.1364964584496846],"hsluv":[266.141219022825339,100.000000000000952,30.1364964584496846]},"#1100ff":{"lch":[32.5652456752648263,130.954293728553409,266.102472093749839],"luv":[32.5652456752648263,-8.90125725083502495,-130.651424275813781],"rgb":[0.0666666666666666657,0,1],"xyz":[0.182792400333933625,0.0733842402632239599,0.950640509058977345],"hpluv":[266.102472093749839,510.275492181060656,32.5652456752648263],"hsluv":[266.102472093749839,100.000000000001108,32.5652456752648263]},"#111100":{"lch":[4.69779601336656771,5.17885327658484673,85.8743202181747307],"luv":[4.69779601336656771,0.372589941443898953,5.16543299210515716],"rgb":[0.0666666666666666657,0.0666666666666666657,0],"xyz":[0.00431601219303203148,0.00520072542434782924,0.000776490229626805866],"hpluv":[85.8743202181747307,139.887458074797621,4.69779601336656771],"hsluv":[85.8743202181747307,100.000000000002359,4.69779601336656771]},"#111111":{"lch":[5.06332949289278655,2.68159353999537178e-13,0],"luv":[5.06332949289278655,2.52120910544652531e-13,9.13481559944393266e-14],"rgb":[0.0666666666666666657,0.0666666666666666657,0.0666666666666666657],"xyz":[0.00532767769266915322,0.00560539162420268383,0.00610459519438243722],"hpluv":[0,6.72041492281092e-12,5.06332949289278655],"hsluv":[0,1.92419399944792277e-12,5.06332949289278655]},"#111122":{"lch":[5.74093111710672321,6.60006851394265048,265.874320218179719],"luv":[5.74093111710672321,-0.474838542395297381,-6.58296534605743222],"rgb":[0.0666666666666666657,0.0666666666666666657,0.133333333333333331],"xyz":[0.00720303583114617271,0.00635553487959350169,0.0159814813903616341],"hpluv":[265.874320218179719,145.883251481840432,5.74093111710672321],"hsluv":[265.874320218179719,28.41442223352254,5.74093111710672321]},"#111133":{"lch":[6.85659263719390388,14.212336546779186,265.874320218178582],"luv":[6.85659263719390388,-1.02249925976518052,-14.1755072354640976],"rgb":[0.0666666666666666657,0.0666666666666666657,0.2],"xyz":[0.0102907865636039132,0.00759063517257661455,0.0322436352479727809],"hpluv":[265.874320218178582,263.024656142887807,6.85659263719390388],"hsluv":[265.874320218178582,51.2306489028398957,6.85659263719390388]},"#111144":{"lch":[8.45853257854777141,22.7927945223118087,265.874320218178241],"luv":[8.45853257854777141,-1.63981590573345759,-22.7337301367732181],"rgb":[0.0666666666666666657,0.0666666666666666657,0.266666666666666663],"xyz":[0.0147487818078227903,0.00937383327026419105,0.0557224102008594194],"hpluv":[265.874320218178241,341.933676209697239,8.45853257854777141],"hsluv":[265.874320218178241,66.600159737267461,8.45853257854777141]},"#111155":{"lch":[10.3782295585045325,32.1242805487719707,265.874320218178127],"luv":[10.3782295585045325,-2.31116487943396587,-32.0410349033279545],"rgb":[0.0666666666666666657,0.0666666666666666657,0.333333333333333315],"xyz":[0.0207111958471847858,0.011758798886009024,0.0871244574748333278],"hpluv":[265.874320218178127,392.780088665713265,10.3782295585045325],"hsluv":[265.874320218178127,76.5037738801481453,10.3782295585045325]},"#111166":{"lch":[12.4757228248048477,41.8651930040424887,265.87432021817807],"luv":[12.4757228248048477,-3.01196982745712916,-41.7567051265328644],"rgb":[0.0666666666666666657,0.0666666666666666657,0.4],"xyz":[0.0282961916206929606,0.0147927971954123355,0.12707210188197729],"hpluv":[265.87432021817807,425.820638501567,12.4757228248048477],"hsluv":[265.87432021817807,82.9392496755345263,12.4757228248048477]},"#111177":{"lch":[14.6896895275036599,51.8467212520223697,265.874320218178],"luv":[14.6896895275036599,-3.73008575521422614,-51.7123676197837199],"rgb":[0.0666666666666666657,0.0666666666666666657,0.466666666666666674],"xyz":[0.0376102046408948731,0.0185184024034931519,0.176125903788375199],"hpluv":[265.874320218178,447.865910041391658,14.6896895275036599],"hsluv":[265.874320218178,87.2331192419333235,14.6896895275036599]},"#111188":{"lch":[16.9766940539391484,61.9476661879793511,265.874320218178],"luv":[16.9766940539391484,-4.45679305530888747,-61.7871373491236469],"rgb":[0.0666666666666666657,0.0666666666666666657,0.533333333333333326],"xyz":[0.0487506217428387,0.0229745692442707428,0.234798767191947366],"hpluv":[265.874320218178,463.03215765547759,16.9766940539391484],"hsluv":[265.874320218178,90.1871263608273495,16.9766940539391484]},"#111199":{"lch":[19.3069968916820471,72.0861980616198537,265.874320218178],"luv":[19.3069968916820471,-5.18620452834737478,-71.8993966147786],"rgb":[0.0666666666666666657,0.0666666666666666657,0.6],"xyz":[0.0618075858519114146,0.0281973548878999072,0.303565444833065246],"hpluv":[265.874320218178,473.779996738615694,19.3069968916820471],"hsluv":[265.874320218178,92.280537596895428,19.3069968916820471]},"#1111aa":{"lch":[21.6605350192491244,82.2093341223612839,265.874320218177957],"luv":[21.6605350192491244,-5.91450835752722703,-81.9962999636616274],"rgb":[0.0666666666666666657,0.0666666666666666657,0.66666666666666663],"xyz":[0.0768652788171639567,0.0342204320740010087,0.382869294450063846],"hpluv":[265.874320218177957,481.605322004481,21.6605350192491244],"hsluv":[265.874320218177957,93.8047159652847569,21.6605350192491244]},"#1111bb":{"lch":[24.0238472654082429,92.2838634174554215,265.874320218177957],"luv":[24.0238472654082429,-6.63931519789526092,-92.0447225046312241],"rgb":[0.0666666666666666657,0.0666666666666666657,0.733333333333333282],"xyz":[0.0940028709245006,0.0410754689169357673,0.473127279548705593],"hpluv":[265.874320218177957,487.441538809997496,24.0238472654082429],"hsluv":[265.874320218177957,94.9414655706975736,24.0238472654082429]},"#1111cc":{"lch":[26.3879200105999,102.289669569688542,265.874320218177957],"luv":[26.3879200105999,-7.35917778701558589,-102.024599989292597],"rgb":[0.0666666666666666657,0.0666666666666666657,0.8],"xyz":[0.113295246368222344,0.0487924190944245689,0.574733790218975749],"hpluv":[265.874320218177957,491.887677819884516,26.3879200105999],"hsluv":[265.874320218177957,95.8074626598259727,26.3879200105999]},"#1111dd":{"lch":[28.7467318202544035,112.215160110792439,265.874320218177957],"luv":[28.7467318202544035,-8.07326211070735766,-111.924369989661315],"rgb":[0.0666666666666666657,0.0666666666666666657,0.866666666666666696],"xyz":[0.134813571918855901,0.0573997493146781,0.688063638118981746],"hpluv":[265.874320218177957,495.338839734480189,28.7467318202544035],"hsluv":[265.874320218177957,96.479663003878315,28.7467318202544035]},"#1111ee":{"lch":[31.096282761883856,122.054240127147821,265.874320218177957],"luv":[31.096282761883856,-8.78112967353786367,-121.737953386246701],"rgb":[0.0666666666666666657,0.0666666666666666657,0.933333333333333348],"xyz":[0.158625752185030638,0.0669246214211481338,0.813474454187505],"hpluv":[265.874320218177957,498.062358817216193,31.096282761883856],"hsluv":[265.874320218177957,97.0101366558694451,31.096282761883856]},"#1111ff":{"lch":[33.4339475813396589,131.804336466263976,265.874320218177957],"luv":[33.4339475813396589,-9.48259535137154863,-131.462783694528071],"rgb":[0.0666666666666666657,0.0666666666666666657,1],"xyz":[0.184796800594862032,0.07739304078508083,0.951308642479286815],"hpluv":[265.874320218177957,500.243401112503761,33.4339475813396589],"hsluv":[265.874320218177957,99.9999999999995168,33.4339475813396589]},"#66aa00":{"lch":[62.9888010115071921,81.5107592316300185,114.758667910078074],"luv":[62.9888010115071921,-34.136471206054587,74.0182761493062884],"rgb":[0.4,0.66666666666666663,0],"xyz":[0.198534632170994735,0.315734905503604946,0.0504821063864305253],"hpluv":[114.758667910078074,164.206718875588678,62.9888010115071921],"hsluv":[114.758667910078074,100.000000000002245,62.9888010115071921]},"#66aa11":{"lch":[63.0225323172591345,80.1801511939703744,115.156040801232848],"luv":[63.0225323172591345,-34.0833758310267285,72.5753411114886262],"rgb":[0.4,0.66666666666666663,0.0666666666666666657],"xyz":[0.199546297670631867,0.316139571703459799,0.055810211351186155],"hpluv":[115.156040801232848,161.439702186697787,63.0225323172591345],"hsluv":[115.156040801232848,97.8915472494395,63.0225323172591345]},"#66aa22":{"lch":[63.0849851082382287,77.7526522520100372,115.919582231606014],"luv":[63.0849851082382287,-33.9864002990590066,69.9313915701248],"rgb":[0.4,0.66666666666666663,0.133333333333333331],"xyz":[0.201421655809108868,0.316889714958850599,0.0656870975471653545],"hpluv":[115.919582231606014,156.397041701241,63.0849851082382287],"hsluv":[115.919582231606014,94.0329763727763748,63.0849851082382287]},"#66aa33":{"lch":[63.1875983682703577,73.8659889058236416,117.258215410479664],"luv":[63.1875983682703577,-33.8307250746429062,65.6632801340230827],"rgb":[0.4,0.66666666666666663,0.2],"xyz":[0.20450940654156663,0.318124815251833726,0.0819492514047764908],"hpluv":[117.258215410479664,148.337854737344315,63.1875983682703577],"hsluv":[117.258215410479664,87.8175568215645228,63.1875983682703577]},"#66aa44":{"lch":[63.3352806074861121,68.495891054581449,119.389904478135335],"luv":[63.3352806074861121,-33.6143748396710436,59.6804900742209057],"rgb":[0.4,0.66666666666666663,0.266666666666666663],"xyz":[0.208967401785785489,0.319908013349521292,0.105428026357663129],"hpluv":[119.389904478135335,137.232870385557277,63.3352806074861121],"hsluv":[119.389904478135335,79.1339200396795093,63.3352806074861121]},"#66aa55":{"lch":[63.5319451116367162,61.7628687774086131,122.670093374403834],"luv":[63.5319451116367162,-33.3396585938880747,51.9915293529473],"rgb":[0.4,0.66666666666666663,0.333333333333333315],"xyz":[0.214929815825147474,0.322292978965266153,0.136830073631637045],"hpluv":[122.670093374403834,123.360077774302084,63.5319451116367162],"hsluv":[122.670093374403834,68.0252461175988401,63.5319451116367162]},"#66aa66":{"lch":[63.7807317293932101,53.9656100581627314,127.715012949238869],"luv":[63.7807317293932101,-33.0126168434810836,42.6902119706049703],"rgb":[0.4,0.66666666666666663,0.4],"xyz":[0.22251481159865566,0.325326977274669471,0.176777718038781],"hpluv":[127.715012949238869,107.366036241042551,63.7807317293932101],"hsluv":[127.715012949238869,54.6684489206366493,63.7807317293932101]},"#66aa77":{"lch":[64.0841229578331308,45.668717811445795,135.623736827110406],"luv":[64.0841229578331308,-32.6422859505805931,31.9392071670853355],"rgb":[0.4,0.66666666666666663,0.466666666666666674],"xyz":[0.231828824618857565,0.329052582482750267,0.225831519945178916],"hpluv":[135.623736827110406,90.428994130424627,64.0841229578331308],"hsluv":[135.623736827110406,56.3153951517164302,64.0841229578331308]},"#66aa88":{"lch":[64.4440140424290888,37.9133385548872752,148.25026899586868],"luv":[64.4440140424290888,-32.239785461804118,19.9503752785341248],"rgb":[0.4,0.66666666666666663,0.533333333333333326],"xyz":[0.242969241720801421,0.333508749323527864,0.284504383348751055],"hpluv":[148.25026899586868,74.65325904191441,64.4440140424290888],"hsluv":[148.25026899586868,58.1346686170252127,64.4440140424290888]},"#66aa99":{"lch":[64.861761772217136,32.5704605989434484,167.654678216446086],"luv":[64.861761772217136,-31.8173259789585323,6.96366793981576304],"rgb":[0.4,0.66666666666666663,0.6],"xyz":[0.256026205829874121,0.338731534967157,0.353271060989869],"hpluv":[167.654678216446086,63.7198120272805681,64.861761772217136],"hsluv":[167.654678216446086,60.083023100845935,64.861761772217136]},"#66aaaa":{"lch":[65.3382237636027,32.1097126044189949,192.177050630060876],"luv":[65.3382237636027,-31.387258852500235,-6.77300710648746396],"rgb":[0.4,0.66666666666666663,0.66666666666666663],"xyz":[0.271083898795126677,0.344754612153258144,0.432574910606867591],"hpluv":[192.177050630060876,62.3603323483304592,65.3382237636027],"hsluv":[192.177050630060876,62.1162357127798757,65.3382237636027]},"#66aabb":{"lch":[65.8737942906507641,37.4229485671739255,214.174175962111633],"luv":[65.8737942906507641,-30.9612713447490577,-21.020864781881972],"rgb":[0.4,0.66666666666666663,0.733333333333333282],"xyz":[0.288221490902463295,0.351609648996192903,0.522832895705509282],"hpluv":[214.174175962111633,72.0882777495769744,65.8737942906507641],"hsluv":[214.174175962111633,64.192083786910942,65.8737942906507641]},"#66aacc":{"lch":[66.4684397846860833,46.8829891397435361,229.336310284400895],"luv":[66.4684397846860833,-30.5497910563422188,-35.5629714322516],"rgb":[0.4,0.66666666666666663,0.8],"xyz":[0.30751386634618505,0.359326599173681704,0.624439406375779438],"hpluv":[229.336310284400895,89.5033179536005,66.4684397846860833],"hsluv":[229.336310284400895,66.2725553364081748,66.4684397846860833]},"#66aadd":{"lch":[67.1217354618507471,58.5746749070863473,239.007496148652194],"luv":[67.1217354618507471,-30.1616186688116876,-50.2122425285710676],"rgb":[0.4,0.66666666666666663,0.866666666666666696],"xyz":[0.329032191896818593,0.367933929393935211,0.737769254275785435],"hpluv":[239.007496148652194,110.735287258409116,67.1217354618507471],"hsluv":[239.007496148652194,68.3252248927570349,67.1217354618507471]},"#66aaee":{"lch":[67.8329035309127,71.3390505041132,245.305718817638592],"luv":[67.8329035309127,-29.803771094245274,-64.8150858627082584],"rgb":[0.4,0.66666666666666663,0.933333333333333348],"xyz":[0.352844372162993358,0.377458801500405228,0.863180070344308659],"hpluv":[245.305718817638592,133.452355648257935,67.8329035309127],"hsluv":[245.305718817638592,80.362890995181445,67.8329035309127]},"#66aaff":{"lch":[68.6008528128324144,84.5574659264264312,249.594848961048797],"luv":[68.6008528128324144,-29.4814940521041038,-79.2515397475312],"rgb":[0.4,0.66666666666666663,1],"xyz":[0.379015420572824724,0.387927220864337952,1.00101425863609061],"hpluv":[249.594848961048797,156.409011428865199,68.6008528128324144],"hsluv":[249.594848961048797,99.9999999999981,68.6008528128324144]},"#112200":{"lch":[11.0156269675282488,14.1286449823385087,113.920199516574741],"luv":[11.0156269675282488,-5.72865521459208082,12.9151507335100835],"rgb":[0.0666666666666666657,0.133333333333333331,0],"xyz":[0.00803163592779996757,0.0126319728938838038,0.00201503147454941628],"hpluv":[113.920199516574741,162.753605553330914,11.0156269675282488],"hsluv":[113.920199516574741,100.000000000002302,11.0156269675282488]},"#112211":{"lch":[11.3010826742418828,9.17677244733547,127.715012949238741],"luv":[11.3010826742418828,-5.61374683501564142,7.25940762201209555],"rgb":[0.0666666666666666657,0.133333333333333331,0.0666666666666666657],"xyz":[0.00904330142743709,0.0130366390937386584,0.00734313643930504731],"hpluv":[127.715012949238741,103.040803658029205,11.3010826742418828],"hsluv":[127.715012949238741,52.4661346244892783,11.3010826742418828]},"#112222":{"lch":[11.8149934741043623,5.60956124878379736,192.177050630060876],"luv":[11.8149934741043623,-5.48334870304322308,-1.18324317225625331],"rgb":[0.0666666666666666657,0.133333333333333331,0.133333333333333331],"xyz":[0.0109186595659141079,0.0137867823491294762,0.0172200226352842434],"hpluv":[192.177050630060876,60.2469040904941551,11.8149934741043623],"hsluv":[192.177050630060876,60.0110800331641911,11.8149934741043623]},"#112233":{"lch":[12.6219648570067733,12.7575995118883281,244.93155638428982],"luv":[12.6219648570067733,-5.40540262923445,-11.5558629154900672],"rgb":[0.0666666666666666657,0.133333333333333331,0.2],"xyz":[0.0140064102983718484,0.0150218826421125891,0.0334821764928953866],"hpluv":[244.93155638428982,128.257072990564865,12.6219648570067733],"hsluv":[244.93155638428982,68.2965554989448265,12.6219648570067733]},"#112244":{"lch":[13.7124312845167182,23.0561698733830092,256.354402060867073],"luv":[13.7124312845167182,-5.43930918870511082,-22.4053762472305387],"rgb":[0.0666666666666666657,0.133333333333333331,0.266666666666666663],"xyz":[0.0184644055425907255,0.0168050807398001656,0.0569609514457820251],"hpluv":[256.354402060867073,213.359519949101497,13.7124312845167182],"hsluv":[256.354402060867073,75.5965994738604508,13.7124312845167182]},"#112255":{"lch":[15.056320299603339,33.5848303856462849,260.40485184836416],"luv":[15.056320299603339,-5.59809589119781581,-33.114983835502386],"rgb":[0.0666666666666666657,0.133333333333333331,0.333333333333333315],"xyz":[0.024426819581952721,0.019190046355545,0.0883629987197559336],"hpluv":[260.40485184836416,283.050313811336878,15.056320299603339],"hsluv":[260.40485184836416,81.3424686793067,15.056320299603339]},"#112266":{"lch":[16.6136212231118279,43.9645077489691118,262.329755848243337],"luv":[16.6136212231118279,-5.86800935048734384,-43.5711419160865958],"rgb":[0.0666666666666666657,0.133333333333333331,0.4],"xyz":[0.0320118153554608958,0.02222404466494831,0.128310643126899909],"hpluv":[262.329755848243337,335.797328537363626,16.6136212231118279],"hsluv":[262.329755848243337,85.6428490187558396,16.6136212231118279]},"#112277":{"lch":[18.3427569840269769,54.1821774694947678,263.400149453671133],"luv":[18.3427569840269769,-6.22740469049246936,-53.8231157232341815],"rgb":[0.0666666666666666657,0.133333333333333331,0.466666666666666674],"xyz":[0.0413258283756628153,0.0259496498730291264,0.177364445033297818],"hpluv":[263.400149453671133,374.827260372181627,18.3427569840269769],"hsluv":[263.400149453671133,88.8099744527525559,18.3427569840269769]},"#112288":{"lch":[20.2056943122802366,64.2803592359499,264.056887374403459],"luv":[20.2056943122802366,-6.65565132438349316,-63.9348644242795103],"rgb":[0.0666666666666666657,0.133333333333333331,0.533333333333333326],"xyz":[0.0524662454776066434,0.0304058167138067173,0.236037308436869986],"hpluv":[264.056887374403459,403.686144257890874,20.2056943122802366],"hsluv":[264.056887374403459,91.1461001738222762,20.2056943122802366]},"#112299":{"lch":[22.17018380613613,74.2918952905243799,264.488199331991609],"luv":[22.17018380613613,-7.13579321215933149,-73.9484020185124677],"rgb":[0.0666666666666666657,0.133333333333333331,0.6],"xyz":[0.0655232095866793568,0.0356286023574358818,0.304803986077987865],"hpluv":[264.488199331991609,425.217833826531262,22.17018380613613],"hsluv":[264.488199331991609,92.8866294242426136,22.17018380613613]},"#1122aa":{"lch":[24.2101316823922517,84.2333021684004848,264.786067280823943],"luv":[24.2101316823922517,-7.6546801533155886,-83.8847725510625537],"rgb":[0.0666666666666666657,0.133333333333333331,0.66666666666666663],"xyz":[0.0805809025519319,0.0416516795435369833,0.384107835694986466],"hpluv":[264.786067280823943,441.495215422381477,24.2101316823922517],"hsluv":[264.786067280823943,94.2012423737010209,24.2101316823922517]},"#1122bb":{"lch":[26.3050242232650149,94.1101405136049891,264.999933480500431],"luv":[26.3050242232650149,-8.20234804116949334,-93.7520134935884926],"rgb":[0.0666666666666666657,0.133333333333333331,0.733333333333333282],"xyz":[0.0977184946592685455,0.0485067163864717418,0.474365820793628212],"hpluv":[264.999933480500431,453.98033637772636,26.3050242232650149],"hsluv":[264.999933480500431,95.2089691602506605,26.3050242232650149]},"#1122cc":{"lch":[28.4390102065576187,103.92243186966887,265.158337172634162],"luv":[28.4390102065576187,-8.77130520241401612,-103.551610565708117],"rgb":[0.0666666666666666657,0.133333333333333331,0.8],"xyz":[0.117010870102990286,0.0562236665639605435,0.575972331463898368],"hpluv":[265.158337172634162,463.69685512523705,28.4390102065576187],"hsluv":[265.158337172634162,95.9928942328389496,28.4390102065576187]},"#1122dd":{"lch":[30.599961250020371,113.668086087716972,265.278693166229971],"luv":[30.599961250020371,-9.35592092097037664,-113.282392888591403],"rgb":[0.0666666666666666657,0.133333333333333331,0.866666666666666696],"xyz":[0.138529195653623816,0.0648309967842140705,0.689302179363904366],"hpluv":[265.278693166229971,471.364637015548908,30.599961250020371],"hsluv":[265.278693166229971,96.6113336559982,30.599961250020371]},"#1122ee":{"lch":[32.7786459144851463,123.344693870669801,265.37211393361406],"luv":[32.7786459144851463,-9.95194954038693247,-122.942556531067964],"rgb":[0.0666666666666666657,0.133333333333333331,0.933333333333333348],"xyz":[0.162341375919798553,0.0743558688906841,0.814712995432427589],"hpluv":[265.37211393361406,477.494956838131543,32.7786459144851463],"hsluv":[265.37211393361406,97.1056530386567118,32.7786459144851463]},"#1122ff":{"lch":[34.9680553815075,132.950321242967135,265.445956583698],"luv":[34.9680553815075,-10.5561742154436597,-132.530581770930752],"rgb":[0.0666666666666666657,0.133333333333333331,1],"xyz":[0.188512424329629946,0.0848242882546168114,0.952547183724209434],"hpluv":[265.445956583698,482.455471693424897,34.9680553815075],"hsluv":[265.445956583698,99.9999999999995595,34.9680553815075]},"#66bb00":{"lch":[68.2883247343563,91.0397787832552297,117.384795663234385],"luv":[68.2883247343563,-41.875036539852637,80.8376313092488914],"rgb":[0.4,0.733333333333333282,0],"xyz":[0.232489130079593515,0.383643901320803504,0.0618002723559631373],"hpluv":[117.384795663234385,169.170277477244,68.2883247343563],"hsluv":[117.384795663234385,100.000000000002402,68.2883247343563]},"#66bb11":{"lch":[68.3179499939719079,89.8644626985519466,117.727722441428654],"luv":[68.3179499939719079,-41.8112733484955896,79.5452014710932644],"rgb":[0.4,0.733333333333333282,0.0666666666666666657],"xyz":[0.233500795579230647,0.384048567520658357,0.0671283773207187739],"hpluv":[117.727722441428654,166.91389144855998,68.3179499939719079],"hsluv":[117.727722441428654,98.2613130840239108,68.3179499939719079]},"#66bb22":{"lch":[68.3728123300379309,87.7153655991844374,118.381366327960222],"luv":[68.3728123300379309,-41.6944557120635579,77.1722600749346839],"rgb":[0.4,0.733333333333333282,0.133333333333333331],"xyz":[0.235376153717707648,0.384798710776049158,0.0770052635166979665],"hpluv":[118.381366327960222,162.791438416492724,68.3728123300379309],"hsluv":[118.381366327960222,95.072259168186676,68.3728123300379309]},"#66bb33":{"lch":[68.4629872592027766,84.2604886941914515,119.511012469656151],"luv":[68.4629872592027766,-41.5059446288263274,73.3286200296498691],"rgb":[0.4,0.733333333333333282,0.2],"xyz":[0.238463904450165409,0.386033811069032284,0.0932674173743091],"hpluv":[119.511012469656151,156.173540237969377,68.4629872592027766],"hsluv":[119.511012469656151,89.9157079277594846,68.4629872592027766]},"#66bb44":{"lch":[68.5928402387875451,79.4555052917154683,121.268984442668796],"luv":[68.5928402387875451,-41.2418962487648457,67.9137932600435761],"rgb":[0.4,0.733333333333333282,0.266666666666666663],"xyz":[0.242921899694384269,0.38781700916671985,0.116746192327195741],"hpluv":[121.268984442668796,146.988898097842537,68.5928402387875451],"hsluv":[121.268984442668796,82.6706505658268,68.5928402387875451]},"#66bb55":{"lch":[68.7658933773114711,73.3682686647690474,123.883282583110088],"luv":[68.7658933773114711,-40.9030232283392365,60.9085013577552417],"rgb":[0.4,0.733333333333333282,0.333333333333333315],"xyz":[0.248884313733746254,0.390201974782464711,0.148148239601169657],"hpluv":[123.883282583110088,135.386233996967292,68.7658933773114711],"hsluv":[123.883282583110088,73.3323147762666565,68.7658933773114711]},"#66bb66":{"lch":[68.985024233854773,66.1955602149500493,127.715012949239338],"luv":[68.985024233854773,-40.4940973290304953,52.3648763359380354],"rgb":[0.4,0.733333333333333282,0.4],"xyz":[0.256469309507254439,0.39323597309186803,0.188095884008313619],"hpluv":[127.715012949239338,121.76244699215377,68.985024233854773],"hsluv":[127.715012949239338,61.9987879490855889,68.985024233854773]},"#66bb77":{"lch":[69.2525700917713,58.3030977404443149,133.351332140289912],"luv":[69.2525700917713,-40.0233333378199134,42.395565742911792],"rgb":[0.4,0.733333333333333282,0.466666666666666674],"xyz":[0.265783322527456345,0.396961578299948825,0.237149685914711528],"hpluv":[133.351332140289912,106.830450835327468,69.2525700917713],"hsluv":[133.351332140289912,63.1630001095548,69.2525700917713]},"#66bb88":{"lch":[69.5703900447947632,50.3125315521488901,141.732198444264128],"luv":[69.5703900447947632,-39.5016033478381487,31.1604583428427624],"rgb":[0.4,0.733333333333333282,0.533333333333333326],"xyz":[0.276923739629400201,0.401417745140726423,0.295822549318283667],"hpluv":[141.732198444264128,91.7679559652102625,69.5703900447947632],"hsluv":[141.732198444264128,64.4651291783298888,69.5703900447947632]},"#66bb99":{"lch":[69.9399065468101924,43.264635747530761,154.168279853010262],"luv":[69.9399065468101924,-38.9415329854338594,18.8516767188195544],"rgb":[0.4,0.733333333333333282,0.6],"xyz":[0.2899807037384729,0.406640530784355581,0.364589226959401602],"hpluv":[154.168279853010262,78.4959645714096865,69.9399065468101924],"hsluv":[154.168279853010262,65.8787579381207848,69.9399065468101924]},"#66bbaa":{"lch":[70.3621368583926881,38.7745898249838348,171.579209782291855],"luv":[70.3621368583926881,-38.3565710720190296,5.67822786553099768],"rgb":[0.4,0.733333333333333282,0.66666666666666663],"xyz":[0.305038396703725456,0.412663607970456703,0.443893076576400203],"hpluv":[171.579209782291855,69.9274221790226278,70.3621368583926881],"hsluv":[171.579209782291855,67.37547943529961,70.3621368583926881]},"#66bbbb":{"lch":[70.8377198879813221,38.6292683935386592,192.177050630060933],"luv":[70.8377198879813221,-37.7601276376370194,-8.14819841495072161],"rgb":[0.4,0.733333333333333282,0.733333333333333282],"xyz":[0.322175988811062075,0.419518644813391461,0.534151061675042],"hpluv":[192.177050630060933,69.1976324805594629,70.8377198879813221],"hsluv":[192.177050630060933,68.9267726464228758,70.8377198879813221]},"#66bbcc":{"lch":[71.3669414392261103,43.4063518114314,211.106579982723787],"luv":[71.3669414392261103,-37.1648552128157,-22.4250956427882215],"rgb":[0.4,0.733333333333333282,0.8],"xyz":[0.341468364254783829,0.427235594990880263,0.635757572345312161],"hpluv":[211.106579982723787,77.1783568223693806,71.3669414392261103],"hsluv":[211.106579982723787,70.5055674968506736,71.3669414392261103]},"#66bbdd":{"lch":[71.9497594848613602,52.0084901368895629,225.300588521911806],"luv":[71.9497594848613602,-36.5821167433876298,-36.9679831866995059],"rgb":[0.4,0.733333333333333282,0.866666666666666696],"xyz":[0.362986689805417373,0.435842925211133769,0.749087420245318159],"hpluv":[225.300588521911806,91.724261948179759,71.9497594848613602],"hsluv":[225.300588521911806,72.0874065633031336,71.9497594848613602]},"#66bbee":{"lch":[72.5858302461357852,62.9426478584387183,235.089705553804919],"luv":[72.5858302461357852,-36.0216507769597953,-51.6160594653851135],"rgb":[0.4,0.733333333333333282,0.933333333333333348],"xyz":[0.386798870071592082,0.445367797317603786,0.874498236313841382],"hpluv":[235.089705553804919,110.035415213757233,72.5858302461357852],"hsluv":[235.089705553804919,76.908955535231712,72.5858302461357852]},"#66bbff":{"lch":[73.2745353232689638,75.1445669264803513,241.815748730615525],"luv":[73.2745353232689638,-35.4914181095182641,-66.2349241650025817],"rgb":[0.4,0.733333333333333282,1],"xyz":[0.412969918481423504,0.45583621668153651,1.01233242460562312],"hpluv":[241.815748730615525,130.131920555189879,73.2745353232689638],"hsluv":[241.815748730615525,99.9999999999976552,73.2745353232689638]},"#113300":{"lch":[17.8585390793191152,25.0449080182821966,121.332554648991049],"luv":[17.8585390793191152,-13.0234653569097247,21.3924465113644295],"rgb":[0.0666666666666666657,0.2,0],"xyz":[0.0141493580168107792,0.0248674170719056023,0.00405427217088629669],"hpluv":[121.332554648991049,177.956083469309505,17.8585390793191152],"hsluv":[121.332554648991049,100.000000000002288,17.8585390793191152]},"#113311":{"lch":[18.041211184449395,20.8015074137336562,127.715012949239792],"luv":[18.041211184449395,-12.7249964056056086,16.4553084796651738],"rgb":[0.0666666666666666657,0.2,0.0666666666666666657],"xyz":[0.015161023516447901,0.0252720832717604552,0.00938237713564192902],"hpluv":[127.715012949239792,146.308124837666583,18.041211184449395],"hsluv":[127.715012949239792,74.4969128915689254,18.041211184449395]},"#113322":{"lch":[18.3747440863758129,14.8635488733567129,145.575764327225926],"luv":[18.3747440863758129,-12.2605616690393529,8.40260154180516672],"rgb":[0.0666666666666666657,0.2,0.133333333333333331],"xyz":[0.0170363816549249196,0.0260222265271512765,0.0192592633316211251],"hpluv":[145.575764327225926,102.645648490479701,18.3747440863758129],"hsluv":[145.575764327225926,76.8412554017051,18.3747440863758129]},"#113333":{"lch":[18.910205854271,11.9516732098830207,192.177050630061075],"luv":[18.910205854271,-11.6827660646039035,-2.5210056714682163],"rgb":[0.0666666666666666657,0.2,0.2],"xyz":[0.0201241323873826601,0.0272573268201343893,0.0355214171892322683],"hpluv":[192.177050630061075,80.19952200231,18.910205854271],"hsluv":[192.177050630061075,79.885597544945341,18.910205854271]},"#113344":{"lch":[19.6554681695294136,18.5554908550806559,233.185939638237187],"luv":[19.6554681695294136,-11.1188227079461566,-14.8552355236207116],"rgb":[0.0666666666666666657,0.2,0.266666666666666663],"xyz":[0.0245821276316015372,0.0290405249178219624,0.0590001921421189068],"hpluv":[233.185939638237187,119.79215597403514,19.6554681695294136],"hsluv":[233.185939638237187,83.0941728600946163,19.6554681695294136]},"#113355":{"lch":[20.6059777210847557,29.4541985213363553,248.778672986371305],"luv":[20.6059777210847557,-10.6615827984222822,-27.4568837045772334],"rgb":[0.0666666666666666657,0.2,0.333333333333333315],"xyz":[0.0305445416709635327,0.0314254905335667953,0.0904022394160928222],"hpluv":[248.778672986371305,181.381634101163,20.6059777210847557],"hsluv":[248.778672986371305,86.0667890851332089,20.6059777210847557]},"#113366":{"lch":[21.7480278014825927,41.0513772817531262,255.392805777322508],"luv":[21.7480278014825927,-10.3527823296753354,-39.7244946445288178],"rgb":[0.0666666666666666657,0.2,0.4],"xyz":[0.0381295374444717075,0.0344594888429701068,0.130349883823236784],"hpluv":[255.392805777322508,239.522976201191227,21.7480278014825927],"hsluv":[255.392805777322508,88.6137215649990537,21.7480278014825927]},"#113377":{"lch":[23.0621320749224097,52.4639032010768602,258.793139915612699],"luv":[23.0621320749224097,-10.1964540550792755,-51.4635158514711293],"rgb":[0.0666666666666666657,0.2,0.466666666666666674],"xyz":[0.04744355046467362,0.0381850940510509232,0.179403685729634693],"hpluv":[258.793139915612699,288.669213908808,23.0621320749224097],"hsluv":[258.793139915612699,90.7010140503724926,23.0621320749224097]},"#113388":{"lch":[24.5260866455155693,63.5079254673071389,260.778240759541745],"luv":[24.5260866455155693,-10.1775299952298717,-62.6871157444433322],"rgb":[0.0666666666666666657,0.2,0.533333333333333326],"xyz":[0.0585839675666174481,0.0426412608918285141,0.238076549133206861],"hpluv":[260.778240759541745,328.5783880762134,24.5260866455155693],"hsluv":[260.778240759541745,92.3732755032704,24.5260866455155693]},"#113399":{"lch":[26.1173586094444445,74.1961224571638667,262.040130643645512],"luv":[26.1173586094444445,-10.2746398160742789,-73.4812653968914447],"rgb":[0.0666666666666666657,0.2,0.6],"xyz":[0.0716409316756901615,0.0478640465354576786,0.30684322677432474],"hpluv":[262.040130643645512,360.488391101723778,26.1173586094444445],"hsluv":[262.040130643645512,93.700931793532277,26.1173586094444445]},"#1133aa":{"lch":[27.8146812937100378,84.589542856674214,262.892366774415223],"luv":[27.8146812937100378,-10.4665753413372666,-83.9395113240792767],"rgb":[0.0666666666666666657,0.2,0.66666666666666663],"xyz":[0.0866986246409427,0.0538871237215587801,0.386147076391323341],"hpluv":[262.892366774415223,385.906342473210088,27.8146812937100378],"hsluv":[262.892366774415223,94.7540719156047544,27.8146812937100378]},"#1133bb":{"lch":[29.5989386642012917,94.7497677250031245,263.494633441352278],"luv":[29.5989386642012917,-10.734795769033445,-94.1396974912241],"rgb":[0.0666666666666666657,0.2,0.733333333333333282],"xyz":[0.10383621674827935,0.0607421605644935386,0.476405061489965087],"hpluv":[263.494633441352278,406.201330660618282,29.5989386642012917],"hsluv":[263.494633441352278,95.59270717643426,29.5989386642012917]},"#1133cc":{"lch":[31.4535171675710927,104.725970292241058,263.935552719695806],"luv":[31.4535171675710927,-11.0639900580249932,-104.139891384844844],"rgb":[0.0666666666666666657,0.2,0.8],"xyz":[0.123128592192001091,0.0684591107419823403,0.578011572160235243],"hpluv":[263.935552719695806,422.497850271701509,31.4535171675710927],"hsluv":[263.935552719695806,96.2648935085394299,31.4535171675710927]},"#1133dd":{"lch":[33.3643121953656845,114.554023382916327,264.267643395871801],"luv":[33.3643121953656845,-11.4418472625073555,-113.981175658242762],"rgb":[0.0666666666666666657,0.2,0.866666666666666696],"xyz":[0.144646917742634634,0.0770664409622358743,0.691341420060241241],"hpluv":[264.267643395871801,435.679872957086786,33.3643121953656845],"hsluv":[264.267643395871801,96.8079128297289913,33.3643121953656845]},"#1133ee":{"lch":[35.3195411096734375,124.259061611723823,264.523680461367292],"luv":[35.3195411096734375,-11.8585821660500468,-123.691909281234786],"rgb":[0.0666666666666666657,0.2,0.933333333333333348],"xyz":[0.168459098008809371,0.0865913130687059,0.816752236128764464],"hpluv":[264.523680461367292,446.428943593210363,35.3195411096734375],"hsluv":[264.523680461367292,97.2502875158067752,35.3195411096734375]},"#1133ff":{"lch":[37.3094684856901466,133.858437412957159,264.724991571549936],"luv":[37.3094684856901466,-12.3064438760062309,-133.291532760957],"rgb":[0.0666666666666666657,0.2,1],"xyz":[0.194630146418640765,0.0970597324326386,0.954586424420546309],"hpluv":[264.724991571549936,455.266836240216,37.3094684856901466],"hsluv":[264.724991571549936,99.9999999999995168,37.3094684856901466]},"#66cc00":{"lch":[73.5514640948473328,100.417876322708906,119.311479215942285],"luv":[73.5514640948473328,-49.1602904566029579,87.5614968315714322],"rgb":[0.4,0.8,0],"xyz":[0.270712873389210462,0.460091387940038399,0.0745415201258350923],"hpluv":[119.311479215942285,173.244332851636557,73.5514640948473328],"hsluv":[119.311479215942285,100.00000000000226,73.5514640948473328]},"#66cc11":{"lch":[73.5777109322390572,99.3703085818509,119.605548775623987],"luv":[73.5777109322390572,-49.0915230219986611,86.397225621155485],"rgb":[0.4,0.8,0.0666666666666666657],"xyz":[0.271724538888847567,0.460496054139893252,0.079869625090590729],"hpluv":[119.605548775623987,171.375877908330068,73.5777109322390572],"hsluv":[119.605548775623987,98.5479766016144652,73.5777109322390572]},"#66cc22":{"lch":[73.626324929263788,97.4510710028789333,120.162888823436575],"luv":[73.626324929263788,-48.965269014871545,84.2562381661406192],"rgb":[0.4,0.8,0.133333333333333331],"xyz":[0.273599897027324623,0.461246197395284052,0.0897465112865699216],"hpluv":[120.162888823436575,167.954954584373922,73.626324929263788],"hsluv":[120.162888823436575,95.8800576342850377,73.626324929263788]},"#66cc33":{"lch":[73.7062524827218084,94.3550745227874,121.116489614327122],"luv":[73.7062524827218084,-48.7607908304490252,80.779114663321],"rgb":[0.4,0.8,0.2],"xyz":[0.276687647759782329,0.462481297688267179,0.106008665144181058],"hpluv":[121.116489614327122,162.442721914772306,73.7062524827218084],"hsluv":[121.116489614327122,91.5533619475712896,73.7062524827218084]},"#66cc44":{"lch":[73.8213986639243,90.0253172969507318,122.577193203242018],"luv":[73.8213986639243,-48.472817822786439,75.8613451418811451],"rgb":[0.4,0.8,0.266666666666666663],"xyz":[0.281145643004001244,0.464264495785954745,0.129487440097067696],"hpluv":[122.577193203242018,154.746814564283426,73.8213986639243],"hsluv":[122.577193203242018,85.4474048693987527,73.8213986639243]},"#66cc55":{"lch":[73.974942724102462,84.4934421806047879,124.700104619680829],"luv":[73.974942724102462,-48.100513339115345,69.4656921655632118],"rgb":[0.4,0.8,0.333333333333333315],"xyz":[0.28710805704336323,0.466649461401699606,0.160889487371041612],"hpluv":[124.700104619680829,144.936474170198323,73.974942724102462],"hsluv":[124.700104619680829,77.5306238992907,73.974942724102462]},"#66cc66":{"lch":[74.1695172801941567,77.8884466842553564,127.715012949239551],"luv":[74.1695172801941567,-47.6470375142611218,61.6146893443493937],"rgb":[0.4,0.8,0.4],"xyz":[0.294693052816871415,0.469683459711102924,0.200837131778185574],"hpluv":[127.715012949239551,133.256044234036153,74.1695172801941567],"hsluv":[127.715012949239551,67.8510775159793,74.1695172801941567]},"#66cc77":{"lch":[74.407302734023375,70.4570986939790203,131.971622948486811],"luv":[74.407302734023375,-47.1190629819757234,52.3831715350808551],"rgb":[0.4,0.8,0.466666666666666674],"xyz":[0.30400706583707332,0.47340906491918372,0.249890933684583483],"hpluv":[131.971622948486811,120.156846155807528,74.407302734023375],"hsluv":[131.971622948486811,68.6882673601907499,74.407302734023375]},"#66cc88":{"lch":[74.6900832163393602,62.6050444414555045,138.002106903522986],"luv":[74.6900832163393602,-46.5261552249599859,41.8892404980031543],"rgb":[0.4,0.8,0.533333333333333326],"xyz":[0.315147482939017121,0.477865231759961318,0.308563797088155622],"hpluv":[138.002106903522986,106.361808066007058,74.6900832163393602],"hsluv":[138.002106903522986,69.6340873295455367,74.6900832163393602]},"#66cc99":{"lch":[75.0192831982140405,54.9734389641357382,146.572693391746668],"luv":[75.0192831982140405,-45.8800303566060634,30.2836887782922481],"rgb":[0.4,0.8,0.6],"xyz":[0.32820444704808982,0.483088017403590475,0.377330474729273557],"hpluv":[146.572693391746668,92.9863760296957338,75.0192831982140405],"hsluv":[146.572693391746668,70.6723780843603,75.0192831982140405]},"#66ccaa":{"lch":[75.3959940236094,48.5503126646653,158.569930493367366],"luv":[75.3959940236094,-45.1937477629490587,17.7386026218441692],"rgb":[0.4,0.8,0.66666666666666663],"xyz":[0.343262140013342376,0.489111094589691597,0.456634324346272158],"hpluv":[158.569930493367366,81.7114817988577187,75.3959940236094],"hsluv":[158.569930493367366,71.7849539596152368,75.3959940236094]},"#66ccbb":{"lch":[75.8209952994642,44.7015709258060667,174.304687468137473],"luv":[75.8209952994642,-44.4809102105153755,4.43610979112772],"rgb":[0.4,0.8,0.733333333333333282],"xyz":[0.360399732120679051,0.495966131432626356,0.546892309444913849],"hpluv":[174.304687468137473,74.8122352806046109,75.8209952994642],"hsluv":[174.304687468137473,72.9527506991265113,75.8209952994642]},"#66cccc":{"lch":[76.2947739303160262,44.7620652034609634,192.177050630061018],"luv":[76.2947739303160262,-43.7549393425641924,-9.44180938207391],"rgb":[0.4,0.8,0.8],"xyz":[0.379692107564400749,0.503683081610115102,0.648498820115184],"hpluv":[192.177050630061018,75.6461904464395,76.2947739303160262],"hsluv":[192.177050630061018,74.1568646821725679,76.2947739303160262]},"#66ccdd":{"lch":[76.8175423984245782,49.1342213212598082,208.868111129197587],"luv":[76.8175423984245782,-43.0284772118039101,-23.7217590764220851],"rgb":[0.4,0.8,0.866666666666666696],"xyz":[0.401210433115034348,0.512290411830368719,0.76182866801519],"hpluv":[208.868111129197587,85.3113130970085791,76.8175423984245782],"hsluv":[208.868111129197587,75.3794120212671714,76.8175423984245782]},"#66ccee":{"lch":[77.3892571801628435,57.0358051623713038,222.109360872917676],"luv":[77.3892571801628435,-42.312941633688304,-38.245235531031426],"rgb":[0.4,0.8,0.933333333333333348],"xyz":[0.425022613381209058,0.521815283936838736,0.887239484083713226],"hpluv":[222.109360872917676,102.061631830010029,77.3892571801628435],"hsluv":[222.109360872917676,76.6041682601332923,77.3892571801628435]},"#66ccff":{"lch":[78.0096377377628158,67.2874731922355664,231.792303901557148],"luv":[78.0096377377628158,-41.6182406850010267,-52.872734853430309],"rgb":[0.4,0.8,1],"xyz":[0.451193661791040479,0.53228370330077146,1.02507367237549518],"hpluv":[231.792303901557148,124.498094909356865,78.0096377377628158],"hsluv":[231.792303901557148,99.9999999999966604,78.0096377377628158]},"#114400":{"lch":[24.4916204196936391,35.767443133059956,124.131260038140155],"luv":[24.4916204196936391,-20.0687794552527912,29.6066559991685239],"rgb":[0.0666666666666666657,0.266666666666666663,0],"xyz":[0.0229819284997768124,0.0425325580378379114,0.00699846233187489172],"hpluv":[124.131260038140155,185.314627891622,24.4916204196936391],"hsluv":[124.131260038140155,100.000000000002416,24.4916204196936391]},"#114411":{"lch":[24.6196313539200702,32.2821952767626144,127.715012949240105],"luv":[24.6196313539200702,-19.7481274165088401,25.5372589646650674],"rgb":[0.0666666666666666657,0.266666666666666663,0.0666666666666666657],"xyz":[0.0239935939994139341,0.0429372242376927643,0.0123265672966305223],"hpluv":[127.715012949240105,166.387555424049935,24.6196313539200702],"hsluv":[127.715012949240105,84.7209219338948,24.6196313539200702]},"#114422":{"lch":[24.8548180969752792,26.7199561105771828,135.968420687644709],"luv":[24.8548180969752792,-19.2104947057918238,18.5718321042894203],"rgb":[0.0666666666666666657,0.266666666666666663,0.133333333333333331],"xyz":[0.0258689521378909527,0.0436873674930835856,0.0222034534926097184],"hpluv":[135.968420687644709,136.415738329938534,24.8548180969752792],"hsluv":[135.968420687644709,85.5945702875542338,24.8548180969752792]},"#114433":{"lch":[25.2362525898650887,20.3101465248311648,155.348193219538018],"luv":[25.2362525898650887,-18.4590663004995292,8.4714180143512],"rgb":[0.0666666666666666657,0.266666666666666663,0.2],"xyz":[0.0289567028703486933,0.0449224677860667,0.0384656073502208651],"hpluv":[155.348193219538018,102.123929581721498,25.2362525898650887],"hsluv":[155.348193219538018,86.8340768870874911,25.2362525898650887]},"#114444":{"lch":[25.774812755707849,18.0038630185053101,192.177050630061132],"luv":[25.774812755707849,-17.5987843886529483,-3.79761393914762779],"rgb":[0.0666666666666666657,0.266666666666666663,0.266666666666666663],"xyz":[0.0334146981145675703,0.0467056658837542715,0.0619443823031075036],"hpluv":[192.177050630061132,88.6358691141452226,25.774812755707849],"hsluv":[192.177050630061132,88.2889223192016743,25.774812755707849]},"#114455":{"lch":[26.4741010086829718,23.9697809957076196,225.699525295295985],"luv":[26.4741010086829718,-16.7410035671662349,-17.1548593857925162],"rgb":[0.0666666666666666657,0.266666666666666663,0.333333333333333315],"xyz":[0.0393771121539295693,0.0490906314994991044,0.0933464295770814],"hpluv":[225.699525295295985,114.889984549549212,26.4741010086829718],"hsluv":[225.699525295295985,89.7968555301121398,26.4741010086829718]},"#114466":{"lch":[27.3316922889079734,34.6428172107851182,242.548035964380944],"luv":[27.3316922889079734,-15.9705048052882308,-30.7419544037807526],"rgb":[0.0666666666666666657,0.266666666666666663,0.4],"xyz":[0.0469621079274377407,0.052124629808902416,0.133294073984225381],"hpluv":[242.548035964380944,160.837015687659374,27.3316922889079734],"hsluv":[242.548035964380944,91.2329185483074525,27.3316922889079734]},"#114477":{"lch":[28.3404051997208484,46.6267191674415,250.798290317077829],"luv":[28.3404051997208484,-15.3352867062553546,-44.0327142242719844],"rgb":[0.0666666666666666657,0.266666666666666663,0.466666666666666674],"xyz":[0.0562761209476396601,0.0558502350169832323,0.18234787589062329],"hpluv":[250.798290317077829,208.770018220734585,28.3404051997208484],"hsluv":[250.798290317077829,92.5248535524246734,28.3404051997208484]},"#114488":{"lch":[29.4896359978219706,58.6954673108201632,255.342505689020953],"luv":[29.4896359978219706,-14.8523182742844106,-56.7852667926718055],"rgb":[0.0666666666666666657,0.266666666666666663,0.533333333333333326],"xyz":[0.0674165380495834882,0.0603064018577608302,0.241020739294195457],"hpluv":[255.342505689020953,252.565763352450517,29.4896359978219706],"hsluv":[255.342505689020953,93.6449802292742817,29.4896359978219706]},"#114499":{"lch":[30.7666487879374699,70.4540899928233699,258.107815399211404],"luv":[30.7666487879374699,-14.5185243824624628,-68.9419411278265102],"rgb":[0.0666666666666666657,0.266666666666666663,0.6],"xyz":[0.0804735021586562,0.0655291875013899877,0.309787416935313364],"hpluv":[258.107815399211404,290.579747717257874,30.7666487879374699],"hsluv":[258.107815399211404,94.5943513350065359,30.7666487879374699]},"#1144aa":{"lch":[32.1577052090601185,81.8040240174920541,259.917940759024589],"luv":[32.1577052090601185,-14.3204852090806973,-80.5408098347099894],"rgb":[0.0666666666666666657,0.266666666666666663,0.66666666666666663],"xyz":[0.0955311951239087437,0.0715522646874911,0.389091266552311965],"hpluv":[259.917940759024589,322.796594575352628,32.1577052090601185],"hsluv":[259.917940759024589,95.3887741756132925,32.1577052090601185]},"#1144bb":{"lch":[33.6489603009756664,92.7573184463875435,261.168522985608377],"luv":[33.6489603009756664,-14.2409127099882671,-91.6576048702508928],"rgb":[0.0666666666666666657,0.266666666666666663,0.733333333333333282],"xyz":[0.11266878723124539,0.0784073015304258547,0.479349251650953712],"hpluv":[261.168522985608377,349.796823816496214,33.6489603009756664],"hsluv":[261.168522985608377,96.0495339612535872,33.6489603009756664]},"#1144cc":{"lch":[35.2271045850644597,103.362934076908545,262.068884255867147],"luv":[35.2271045850644597,-14.262270250582695,-102.374234005860515],"rgb":[0.0666666666666666657,0.266666666666666663,0.8],"xyz":[0.131961162674967131,0.0861242517079146563,0.580955762321223812],"hpluv":[262.068884255867147,372.329293739207799,35.2271045850644597],"hsluv":[262.068884255867147,96.5982694251149638,35.2271045850644597]},"#1144dd":{"lch":[36.8797734412618,113.676357292171801,262.73849416957313],"luv":[36.8797734412618,-14.3684841809298494,-112.764625967365617],"rgb":[0.0666666666666666657,0.266666666666666663,0.866666666666666696],"xyz":[0.153479488225600674,0.0947315819281681903,0.69428561022122981],"hpluv":[262.73849416957313,391.13009227787353,36.8797734412618],"hsluv":[262.73849416957313,97.0546019825808,36.8797734412618]},"#1144ee":{"lch":[38.5957670998368911,123.747928777943088,263.249741523271325],"luv":[38.5957670998368911,-14.5455638799169762,-122.890099065165245],"rgb":[0.0666666666666666657,0.266666666666666663,0.933333333333333348],"xyz":[0.177291668491775412,0.104256454034638207,0.819696426289753],"hpluv":[263.249741523271325,406.853061330967478,38.5957670998368911],"hsluv":[263.249741523271325,97.4353215147193623,38.5957670998368911]},"#1144ff":{"lch":[40.3651306844127546,133.619394536005728,263.648645306126298],"luv":[40.3651306844127546,-14.7816672391382209,-132.799265471613751],"rgb":[0.0666666666666666657,0.266666666666666663,1],"xyz":[0.203462716901606805,0.114724873398570917,0.957530614581534878],"hpluv":[263.648645306126298,420.051425771921231,40.3651306844127546],"hsluv":[263.648645306126298,99.9999999999994458,40.3651306844127546]},"#66dd00":{"lch":[78.7732081443282084,109.616469768408933,120.762072840728067],"luv":[78.7732081443282084,-56.0659919017112145,94.1932853050883],"rgb":[0.4,0.866666666666666696,0],"xyz":[0.313346863936385611,0.54535936903439,0.0887528503082264109],"hpluv":[120.762072840728067,211.559351010719155,78.7732081443282084],"hsluv":[120.762072840728067,100.000000000002444,78.7732081443282084]},"#66dd11":{"lch":[78.7966434753788576,108.675393583239966,121.014553037765893],"luv":[78.7966434753788576,-55.9956244091473678,93.1387739746547],"rgb":[0.4,0.866666666666666696,0.0666666666666666657],"xyz":[0.314358529436022716,0.545764035234244882,0.0940809552729820475],"hpluv":[121.014553037765893,210.019013530063148,78.7966434753788576],"hsluv":[121.014553037765893,98.7735218244661866,78.7966434753788576]},"#66dd22":{"lch":[78.8400557089289435,106.948443645027297,121.491090191754736],"luv":[78.8400557089289435,-55.866227309203758,91.1972271745690506],"rgb":[0.4,0.866666666666666696,0.133333333333333331],"xyz":[0.316233887574499772,0.546514178489635682,0.10395784146896124],"hpluv":[121.491090191754736,207.186246213049145,78.8400557089289435],"hsluv":[121.491090191754736,96.5169147905729,78.8400557089289435]},"#66dd33":{"lch":[78.911446872650572,104.154611952746194,122.300539429107701],"luv":[78.911446872650572,-55.6560904548950788,88.037394249850891],"rgb":[0.4,0.866666666666666696,0.2],"xyz":[0.319321638306957478,0.547749278782618809,0.120219995326572376],"hpluv":[122.300539429107701,202.586476802368111,78.911446872650572],"hsluv":[122.300539429107701,92.8487034899531807,78.911446872650572]},"#66dd44":{"lch":[79.0143300648071687,100.229492569308348,123.526451276321851],"luv":[79.0143300648071687,-55.3589437481663,83.5544045983716899],"rgb":[0.4,0.866666666666666696,0.266666666666666663],"xyz":[0.323779633551176393,0.549532476880306375,0.143698770279459015],"hpluv":[123.526451276321851,196.088207898644384,79.0143300648071687],"hsluv":[123.526451276321851,87.6539206040991843,79.0143300648071687]},"#66dd55":{"lch":[79.1515854502963,95.1800529291645603,125.27945296022996],"luv":[79.1515854502963,-54.9726586351532518,77.699737954393882],"rgb":[0.4,0.866666666666666696,0.333333333333333315],"xyz":[0.329742047590538379,0.551917442496051125,0.17510081755343293],"hpluv":[125.27945296022996,187.665730733793509,79.1515854502963],"hsluv":[125.27945296022996,80.8868034505971707,79.1515854502963]},"#66dd66":{"lch":[79.3256225689869723,89.0890908185611607,127.715012949239735],"luv":[79.3256225689869723,-54.4988561596450722,70.4751075215082921],"rgb":[0.4,0.866666666666666696,0.4],"xyz":[0.337327043364046564,0.554951440805454443,0.215048461960576892],"hpluv":[127.715012949239735,177.410630109117562,79.3256225689869723],"hsluv":[127.715012949239735,72.5638298210149,79.3256225689869723]},"#66dd77":{"lch":[79.538466322575843,82.1265081512392072,131.057978326052336],"luv":[79.538466322575843,-53.9425296262626048,61.9271090770055395],"rgb":[0.4,0.866666666666666696,0.466666666666666674],"xyz":[0.346641056384248469,0.558677046013535294,0.264102263866974774],"hpluv":[131.057978326052336,165.560886464635786,79.538466322575843],"hsluv":[131.057978326052336,73.175897046832489,79.538466322575843]},"#66dd88":{"lch":[79.7918079202835173,74.5708009722257543,135.636001638862723],"luv":[79.7918079202835173,-53.3115731427918,52.1409678341327378],"rgb":[0.4,0.866666666666666696,0.533333333333333326],"xyz":[0.35778147348619227,0.563133212854312837,0.322775127270546969],"hpluv":[135.636001638862723,152.557764790666909,79.7918079202835173],"hsluv":[135.636001638862723,73.8730513922454435,79.7918079202835173]},"#66dd99":{"lch":[80.0870378401123162,66.8478260511747919,141.915708870878916],"luv":[80.0870378401123162,-52.6162023759431392,41.2330825345609924],"rgb":[0.4,0.866666666666666696,0.6],"xyz":[0.370838437595265,0.568355998497942,0.391541804911664904],"hpluv":[141.915708870878916,139.150468179242381,80.0870378401123162],"hsluv":[141.915708870878916,74.6453790933081791,80.0870378401123162]},"#66ddaa":{"lch":[80.4252690581998877,59.592891473004542,150.502508447871207],"luv":[80.4252690581998877,-51.8682972227800931,29.3426729750825572],"rgb":[0.4,0.866666666666666696,0.66666666666666663],"xyz":[0.385896130560517525,0.574379075684043117,0.470845654528663449],"hpluv":[150.502508447871207,126.571308780245914,80.4252690581998877],"hsluv":[150.502508447871207,75.4812281571350638,80.4252690581998877]},"#66ddbb":{"lch":[80.807354973374558,53.7174771102931672,161.973645166837599],"luv":[80.807354973374558,-51.0807157732000334,16.6231111165276104],"rgb":[0.4,0.866666666666666696,0.733333333333333282],"xyz":[0.4030337226678542,0.581234112526977875,0.561103639627305251],"hpluv":[161.973645166837599,116.757770235740637,80.807354973374558],"hsluv":[161.973645166837599,76.3679029554368753,80.807354973374558]},"#66ddcc":{"lch":[81.2339045655681389,50.3705316419042148,176.319314132685548],"luv":[81.2339045655681389,-50.2666331071559256,3.23358221770368903],"rgb":[0.4,0.866666666666666696,0.8],"xyz":[0.422326098111575954,0.588951062704466732,0.662710150297575407],"hpluv":[176.319314132685548,112.393665646206941,81.2339045655681389],"hsluv":[176.319314132685548,77.2923330418296501,81.2339045655681389]},"#66dddd":{"lch":[81.7052962965957903,50.5769089008318389,192.177050630061],"luv":[81.7052962965957903,-49.4389517336029,-10.6683534552210038],"rgb":[0.4,0.866666666666666696,0.866666666666666696],"xyz":[0.443844423662209442,0.597558392924720239,0.776039998197581404],"hpluv":[192.177050630061,116.242714563462513,81.7052962965957903],"hsluv":[192.177050630061,78.2416694753709407,81.7052962965957903]},"#66ddee":{"lch":[82.2216916522674524,54.6311568672274745,207.154140846621715],"luv":[82.2216916522674524,-48.6098170936026577,-24.9328895793911158],"rgb":[0.4,0.866666666666666696,0.933333333333333348],"xyz":[0.467656603928384207,0.607083265031190256,0.901450814266104627],"hpluv":[207.154140846621715,129.793318723999505,82.2216916522674524],"hsluv":[207.154140846621715,79.2037752530793,82.2216916522674524]},"#66ddff":{"lch":[82.7830488398693376,61.9519841783888339,219.519505956683815],"luv":[82.7830488398693376,-47.7902556034158366,-39.4225799891321387],"rgb":[0.4,0.866666666666666696,1],"xyz":[0.493827652338215572,0.617551684395123,1.03928500255788636],"hpluv":[219.519505956683815,152.730665075356086,82.7830488398693376],"hsluv":[219.519505956683815,99.9999999999957,82.7830488398693376]},"#115500":{"lch":[30.9160157060817227,46.0913193883500583,125.457330883646421],"luv":[30.9160157060817227,-26.7374134918097575,37.543580579466358],"rgb":[0.0666666666666666657,0.333333333333333315,0],"xyz":[0.0347951852141227744,0.0661590714665301755,0.0109362145699901016],"hpluv":[125.457330883646421,189.179880792461034,30.9160157060817227],"hsluv":[125.457330883646421,100.000000000002402,30.9160157060817227]},"#115511":{"lch":[31.0114762783458957,43.2230667766736616,127.715012949240275],"luv":[31.0114762783458957,-26.4410342208804181,34.1921805521528697],"rgb":[0.0666666666666666657,0.333333333333333315,0.0666666666666666657],"xyz":[0.0358068507137599,0.0665637376663850283,0.0162643195347457331],"hpluv":[127.715012949240275,176.861157643680144,31.0114762783458957],"hsluv":[127.715012949240275,90.0538522348087156,31.0114762783458957]},"#115522":{"lch":[31.1874163697014737,38.3803455570512071,132.492971129528541],"luv":[31.1874163697014737,-25.925914044022,28.3001396827055132],"rgb":[0.0666666666666666657,0.333333333333333315,0.133333333333333331],"xyz":[0.0376822088522369147,0.0673138809217758427,0.0261412057307249292],"hpluv":[132.492971129528541,156.159643444286843,31.1874163697014737],"hsluv":[132.492971129528541,90.4316047034468653,31.1874163697014737]},"#115533":{"lch":[31.4742731349983,31.7764378074468219,142.363318860140765],"luv":[31.4742731349983,-25.163724938647551,19.4043538140960301],"rgb":[0.0666666666666666657,0.333333333333333315,0.2],"xyz":[0.0407699595846946553,0.0685489812147589556,0.0424033595883360759],"hpluv":[142.363318860140765,128.111709873485438,31.4742731349983],"hsluv":[142.363318860140765,90.9947325890089616,31.4742731349983]},"#115544":{"lch":[31.8824114421380642,25.5202649789159608,161.635705606154772],"luv":[31.8824114421380642,-24.2205825435089714,8.04035483341083435],"rgb":[0.0666666666666666657,0.333333333333333315,0.266666666666666663],"xyz":[0.0452279548289135358,0.0703321793124465355,0.0658821345412227144],"hpluv":[161.635705606154772,101.571845607751229,31.8824114421380642],"hsluv":[161.635705606154772,91.6999843863076194,31.8824114421380642]},"#115555":{"lch":[32.417637609391285,23.7206023942150033,192.177050630061103],"luv":[32.417637609391285,-23.1868997601056,-5.00346454561771115],"rgb":[0.0666666666666666657,0.333333333333333315,0.333333333333333315],"xyz":[0.0511903688682755278,0.0727171449281913684,0.0972841818151966159],"hpluv":[192.177050630061103,92.8503782686988899,32.417637609391285],"hsluv":[192.177050630061103,92.4869346485079,32.417637609391285]},"#115566":{"lch":[33.0818646063754045,29.1355194477524577,220.509575549450261],"luv":[33.0818646063754045,-22.1516601517912761,-18.9257085999416219],"rgb":[0.0666666666666666657,0.333333333333333315,0.4],"xyz":[0.0587753646417837061,0.0757511432375946869,0.137231826222340592],"hpluv":[220.509575549450261,111.756325010930979,33.0818646063754045],"hsluv":[220.509575549450261,93.2955878193037904,33.0818646063754045]},"#115577":{"lch":[33.8736729304774826,39.2775515041961185,237.359341141202208],"luv":[33.8736729304774826,-21.1850732372535866,-33.0744421585153958],"rgb":[0.0666666666666666657,0.333333333333333315,0.466666666666666674],"xyz":[0.0680893776619856117,0.0794767484456755,0.186285628128738501],"hpluv":[237.359341141202208,147.13684637222039,33.8736729304774826],"hsluv":[237.359341141202208,94.078253732623736,33.8736729304774826]},"#115588":{"lch":[34.7888943497230514,51.2161985161337938,246.60972521059881],"luv":[34.7888943497230514,-20.3324266151093482,-47.0073549392562455],"rgb":[0.0666666666666666657,0.333333333333333315,0.533333333333333326],"xyz":[0.0792297947639294398,0.0839329152864531,0.244958491532310668],"hpluv":[246.60972521059881,186.812546427038342,34.7888943497230514],"hsluv":[246.60972521059881,94.8038015691112719,34.7888943497230514]},"#115599":{"lch":[35.8212274371681403,63.5782184467896,252.028930114170464],"luv":[35.8212274371681403,-19.6162163870228632,-60.476391389741444],"rgb":[0.0666666666666666657,0.333333333333333315,0.6],"xyz":[0.0922867588730021671,0.0891557009300822517,0.313725169173428575],"hpluv":[252.028930114170464,225.22013661091745,35.8212274371681403],"hsluv":[252.028930114170464,95.4562831747131355,35.8212274371681403]},"#1155aa":{"lch":[36.9628521043173777,75.808874965898184,255.452401876993463],"luv":[36.9628521043173777,-19.0419916394553752,-73.3783897206670588],"rgb":[0.0666666666666666657,0.333333333333333315,0.66666666666666663],"xyz":[0.107344451838254695,0.0951787781161833601,0.393029018790427176],"hpluv":[255.452401876993463,260.251896817562397,36.9628521043173777],"hsluv":[255.452401876993463,96.0310300088164155,36.9628521043173777]},"#1155bb":{"lch":[38.2050019251475845,87.6984258792502089,257.752076786877694],"luv":[38.2050019251475845,-18.6045414354547205,-85.7023041678273216],"rgb":[0.0666666666666666657,0.333333333333333315,0.733333333333333282],"xyz":[0.124482043945591342,0.102033814959118119,0.483287003889068922],"hpluv":[257.752076786877694,291.280156181798475,38.2050019251475845],"hsluv":[257.752076786877694,96.5305142623785,38.2050019251475845]},"#1155cc":{"lch":[39.5384610498345523,99.1886562531622,259.372402836059223],"luv":[39.5384610498345523,-18.292845239891637,-97.4872368176334447],"rgb":[0.0666666666666666657,0.333333333333333315,0.8],"xyz":[0.143774419389313096,0.10975076513660692,0.584893514559339],"hpluv":[259.372402836059223,318.332933912315752,39.5384610498345523],"hsluv":[259.372402836059223,96.9610449958707,39.5384610498345523]},"#1155dd":{"lch":[40.9539668975822053,110.288480556245688,260.557616930578945],"luv":[40.9539668975822053,-18.0934548393737415,-108.7941902648341],"rgb":[0.0666666666666666657,0.333333333333333315,0.866666666666666696],"xyz":[0.16529274493994664,0.118358095356860454,0.698223362459345],"hpluv":[260.557616930578945,341.722445031840948,40.9539668975822053],"hsluv":[260.557616930578945,97.330522563257,40.9539668975822053]},"#1155ee":{"lch":[42.4425141949683038,121.034132372772049,261.450904748640312],"luv":[42.4425141949683038,-17.992549051743687,-119.689303523123172],"rgb":[0.0666666666666666657,0.333333333333333315,0.933333333333333348],"xyz":[0.189104925206121377,0.127882967463330471,0.823634178527868244],"hpluv":[261.450904748640312,361.864588035447412,42.4425141949683038],"hsluv":[261.450904748640312,97.6470858685672596,42.4425141949683038]},"#1155ff":{"lch":[43.9955669218353762,131.469960671873054,262.140820458865903],"luv":[43.9955669218353762,-17.9770474653633769,-130.235081001594637],"rgb":[0.0666666666666666657,0.333333333333333315,1],"xyz":[0.21527597361595277,0.138351386827263168,0.961468366819650089],"hpluv":[262.140820458865903,379.190057269809415,43.9955669218353762],"hsluv":[262.140820458865903,99.9999999999993321,43.9955669218353762]},"#66ee00":{"lch":[83.9510288300903511,118.631054776009961,121.878900606421581],"luv":[83.9510288300903511,-62.6521043104729145,100.737485489455693],"rgb":[0.4,0.933333333333333348,0],"xyz":[0.360525640276900428,0.639716921715420939,0.104479109088397595],"hpluv":[121.878900606421581,316.932305812441825,83.9510288300903511],"hsluv":[121.878900606421581,100.000000000002245,83.9510288300903511]},"#66ee11":{"lch":[83.9720997528394406,117.779830021225337,122.096631719604488],"luv":[83.9720997528394406,-62.5821687959979371,99.7775551344988401],"rgb":[0.4,0.933333333333333348,0.0666666666666666657],"xyz":[0.361537305776537532,0.640121587915275847,0.109807214053153232],"hpluv":[122.096631719604488,315.12898496103287,83.9720997528394406],"hsluv":[122.096631719604488,98.9534187198870825,83.9720997528394406]},"#66ee22":{"lch":[84.0111361497279461,116.215639794016113,122.506307539641156],"luv":[84.0111361497279461,-62.4534076072217061,98.0084017366813498],"rgb":[0.4,0.933333333333333348,0.133333333333333331],"xyz":[0.363412663915014589,0.640871731170666648,0.119684100249132425],"hpluv":[122.506307539641156,311.807725961995743,84.0111361497279461],"hsluv":[122.506307539641156,97.0256918708191,84.0111361497279461]},"#66ee33":{"lch":[84.0753427139745213,113.679067087327056,123.198426402241765],"luv":[84.0753427139745213,-62.2438639038254564,95.1242960560921],"rgb":[0.4,0.933333333333333348,0.2],"xyz":[0.366500414647472295,0.642106831463649774,0.135946254106743575],"hpluv":[123.198426402241765,306.400922934277446,84.0753427139745213],"hsluv":[123.198426402241765,93.8862320250161133,84.0753427139745213]},"#66ee44":{"lch":[84.1678970009459704,110.10189342016568,124.237870325737177],"luv":[84.1678970009459704,-61.946619900698991,91.0222127702015626],"rgb":[0.4,0.933333333333333348,0.266666666666666663],"xyz":[0.37095840989169121,0.64389002956133734,0.159425029059630213],"hpluv":[124.237870325737177,298.731636810455427,84.1678970009459704],"hsluv":[124.237870325737177,89.4277949312148337,84.1678970009459704]},"#66ee55":{"lch":[84.2914184237995414,105.474359140243067,125.706632503417083],"luv":[84.2914184237995414,-61.5585501093914829,85.6468641835444657],"rgb":[0.4,0.933333333333333348,0.333333333333333315],"xyz":[0.376920823931053195,0.64627499517708209,0.190827076333604129],"hpluv":[125.706632503417083,288.732343582820249,84.2914184237995414],"hsluv":[125.706632503417083,83.5978964235977315,84.2914184237995414]},"#66ee66":{"lch":[84.4481159447294374,99.8471979874678652,127.715012949239849],"luv":[84.4481159447294374,-61.0799597466417339,78.9854509596370633],"rgb":[0.4,0.933333333333333348,0.4],"xyz":[0.38450581970456138,0.649308993486485408,0.230774720740748063],"hpluv":[127.715012949239849,276.453302697114395,84.4481159447294374],"hsluv":[127.715012949239849,76.3932656313124454,84.4481159447294374]},"#66ee77":{"lch":[84.6398667383604391,93.3381964812165,130.416076861551431],"luv":[84.6398667383604391,-60.5142850922984863,71.0636350191446127],"rgb":[0.4,0.933333333333333348,0.466666666666666674],"xyz":[0.393819832724763286,0.65303459869456626,0.279828522647145972],"hpluv":[130.416076861551431,262.087365127001192,84.6398667383604391],"hsluv":[130.416076861551431,76.8478121958162461,84.6398667383604391]},"#66ee88":{"lch":[84.8682629083727704,86.1443361377895513,134.024834696689027],"luv":[84.8682629083727704,-59.8677379892917187,61.9411058721588503],"rgb":[0.4,0.933333333333333348,0.533333333333333326],"xyz":[0.404960249826707086,0.657490765535343802,0.338501386050718167],"hpluv":[134.024834696689027,246.018013362770375,84.8682629083727704],"hsluv":[134.024834696689027,77.3690194462974858,84.8682629083727704]},"#66ee99":{"lch":[85.1346415661787432,78.5628931277068,138.840952739605655],"luv":[85.1346415661787432,-59.1488647733143296,51.7062856200641718],"rgb":[0.4,0.933333333333333348,0.6],"xyz":[0.418017213935779841,0.662713551178973,0.407268063691836046],"hpluv":[138.840952739605655,228.905884969324347,85.1346415661787432],"hsluv":[138.840952739605655,77.9507906120806,85.1346415661787432]},"#66eeaa":{"lch":[85.4401056772853451,71.025817565124143,145.263991147699045],"luv":[85.4401056772853451,-58.3680297483556387,40.4702342974360576],"rgb":[0.4,0.933333333333333348,0.66666666666666663],"xyz":[0.433074906901032342,0.668736628365074082,0.486571913308834647],"hpluv":[145.263991147699045,211.83630636980061,85.4401056772853451],"hsluv":[145.263991147699045,78.5856392083502868,85.4401056772853451]},"#66eebb":{"lch":[85.7855396574798448,64.1465768711300228,153.7611846199909],"luv":[85.7855396574798448,-57.5368534805651,28.3600743271201026],"rgb":[0.4,0.933333333333333348,0.733333333333333282],"xyz":[0.450212499008369,0.67559166520800884,0.576829898407476449],"hpluv":[153.7611846199909,196.542528595596508,85.7855396574798448],"hsluv":[153.7611846199909,79.2651091664321683,85.7855396574798448]},"#66eecc":{"lch":[86.1716220205593,58.7524914026155827,164.690737532459508],"luv":[86.1716220205593,-56.6676444389915517,15.5123602250092176],"rgb":[0.4,0.933333333333333348,0.8],"xyz":[0.46950487445209077,0.683308615385497697,0.678436409077746605],"hpluv":[164.690737532459508,185.645341664818176,86.1716220205593],"hsluv":[164.690737532459508,79.9801993176568118,86.1716220205593]},"#66eedd":{"lch":[86.5988364705929285,55.8111450312658164,177.877712634427581],"luv":[86.5988364705929285,-55.7728621696499403,2.06682246606168096],"rgb":[0.4,0.933333333333333348,0.866666666666666696],"xyz":[0.491023200002724258,0.691915945605751204,0.791766256977752603],"hpluv":[177.877712634427581,182.628088950326941,86.5988364705929285],"hsluv":[177.877712634427581,80.7217641095277543,86.5988364705929285]},"#66eeee":{"lch":[87.0674822997282263,56.1274864183573783,192.177050630061075],"luv":[87.0674822997282263,-54.8646438121880493,-11.8391549953798521],"rgb":[0.4,0.933333333333333348,0.933333333333333348],"xyz":[0.514835380268899,0.701440817712221221,0.917177073046275826],"hpluv":[192.177050630061075,191.066910285097691,87.0674822997282263],"hsluv":[192.177050630061075,81.4808670778618165,87.0674822997282263]},"#66eeff":{"lch":[87.5776846199412518,59.9248574237073512,205.793536431897621],"luv":[87.5776846199412518,-53.9544158989052178,-26.0750751151289606],"rgb":[0.4,0.933333333333333348,1],"xyz":[0.541006428678730389,0.711909237076154,1.05501126133805756],"hpluv":[205.793536431897621,213.276590696447101,87.5776846199412518],"hsluv":[205.793536431897621,99.9999999999933351,87.5776846199412518]},"#116600":{"lch":[37.1543973335168118,56.0416844920186463,126.180156646926719],"luv":[37.1543973335168118,-33.0828721903909511,45.2348755755691201],"rgb":[0.0666666666666666657,0.4,0],"xyz":[0.0498232429199692434,0.0962151868782235159,0.0159455671386054508],"hpluv":[126.180156646926719,191.399273993181851,37.1543973335168118],"hsluv":[126.180156646926719,100.000000000002359,37.1543973335168118]},"#116611":{"lch":[37.2288128297302237,53.6508389550451668,127.715012949240304],"luv":[37.2288128297302237,-32.820060550512963,42.4412081124095124],"rgb":[0.0666666666666666657,0.4,0.0666666666666666657],"xyz":[0.0508349084196063616,0.0966198530780783688,0.021273672103361084],"hpluv":[127.715012949240304,182.867554307566394,37.2288128297302237],"hsluv":[127.715012949240304,93.1121786917857719,37.2288128297302237]},"#116622":{"lch":[37.366211587350719,49.4912288674311,130.823584918521846],"luv":[37.366211587350719,-32.3540076461773722,37.4513006989015125],"rgb":[0.0666666666666666657,0.4,0.133333333333333331],"xyz":[0.0527102665580833837,0.0973699963334691831,0.0311505582993402766],"hpluv":[130.823584918521846,168.069340269208539,37.366211587350719],"hsluv":[130.823584918521846,93.2954788878505639,37.366211587350719]},"#116633":{"lch":[37.5909073580641291,43.4152735453156,136.786924005406348],"luv":[37.5909073580641291,-31.6415889136076061,29.7270218494359924],"rgb":[0.0666666666666666657,0.4,0.2],"xyz":[0.0557980172905411242,0.0986050966264523,0.0474127121569514198],"hpluv":[136.786924005406348,146.554466726503705,37.5909073580641291],"hsluv":[136.786924005406348,93.5769168130898095,37.5909073580641291]},"#116644":{"lch":[37.9120295698984506,36.3990668435195417,147.559563985674146],"luv":[37.9120295698984506,-30.7189764474867033,19.525279846848818],"rgb":[0.0666666666666666657,0.4,0.266666666666666663],"xyz":[0.0602560125347600048,0.100388294724139876,0.0708914871098380583],"hpluv":[147.559563985674146,121.829522477327146,37.9120295698984506],"hsluv":[147.559563985674146,93.9439470857740559,37.9120295698984506]},"#116655":{"lch":[38.335629212958338,30.5483862618043851,166.063087397862887],"luv":[38.335629212958338,-29.6490880228798659,7.35768187759708869],"rgb":[0.0666666666666666657,0.4,0.333333333333333315],"xyz":[0.066218426574122,0.102773260339884709,0.102293534383811974],"hpluv":[166.063087397862887,101.117192726530064,38.335629212958338],"hsluv":[166.063087397862887,94.3739252192313529,38.335629212958338]},"#116666":{"lch":[38.8651381017916293,29.1618890828208741,192.177050630061217],"luv":[38.8651381017916293,-28.5057600031098204,-6.15121301239451324],"rgb":[0.0666666666666666657,0.4,0.4],"xyz":[0.0738034223476301682,0.105807258649288027,0.142241178790955936],"hpluv":[192.177050630061217,95.2126746116157392,38.8651381017916293],"hsluv":[192.177050630061217,94.8399842705083245,38.8651381017916293]},"#116677":{"lch":[39.5016809883423079,34.1234106492309124,216.700227589977857],"luv":[39.5016809883423079,-27.3592385518708738,-20.3931169809293316],"rgb":[0.0666666666666666657,0.4,0.466666666666666674],"xyz":[0.0831174353678320876,0.109532863857368837,0.191294980697353845],"hpluv":[216.700227589977857,109.616563248578402,39.5016809883423079],"hsluv":[216.700227589977857,95.3164106037614687,39.5016809883423079]},"#116688":{"lch":[40.2443638992953723,43.6497103352843823,233.004065811630028],"luv":[40.2443638992953723,-26.2665776267255495,-34.862072688430807],"rgb":[0.0666666666666666657,0.4,0.533333333333333326],"xyz":[0.0942578524697759157,0.113989030698146435,0.249967844100926],"hpluv":[233.004065811630028,137.630797119362086,40.2443638992953723],"hsluv":[233.004065811630028,95.7822055324918864,40.2443638992953723]},"#116699":{"lch":[41.090575936542443,55.3002439505846866,242.81143298809],"luv":[41.090575936542443,-25.2678118474637223,-49.189985418125],"rgb":[0.0666666666666666657,0.4,0.6],"xyz":[0.107314816578848629,0.119211816341775592,0.318734521742043919],"hpluv":[242.81143298809,170.774941475023041,41.090575936542443],"hsluv":[242.81143298809,96.2225162944548202,41.090575936542443]},"#1166aa":{"lch":[42.0363074660961757,67.6887016451143,248.882871092507173],"luv":[42.0363074660961757,-24.3865946332867658,-63.1431257746482615],"rgb":[0.0666666666666666657,0.4,0.66666666666666663],"xyz":[0.122372509544101171,0.125234893527876701,0.39803837135904252],"hpluv":[248.882871092507173,204.329442679703192,42.0363074660961757],"hsluv":[248.882871092507173,96.6284204735347885,42.0363074660961757]},"#1166bb":{"lch":[43.0764730814379746,80.16050208662584,252.853006907061769],"luv":[43.0764730814379746,-23.6332520973097289,-76.5974901030376429],"rgb":[0.0666666666666666657,0.4,0.733333333333333282],"xyz":[0.139510101651437818,0.132089930370811459,0.488296356457684266],"hpluv":[252.853006907061769,236.134594524550181,43.0764730814379746],"hsluv":[252.853006907061769,96.9958197331145,43.0764730814379746]},"#1166cc":{"lch":[44.2052232400861271,92.4179309088515737,255.583916344807051],"luv":[44.2052232400861271,-23.008531750755072,-89.5079964033815259],"rgb":[0.0666666666666666657,0.4,0.8],"xyz":[0.158802477095159544,0.139806880548300261,0.589902867127954367],"hpluv":[255.583916344807051,265.290671800528912,44.2052232400861271],"hsluv":[255.583916344807051,97.3240770235992159,44.2052232400861271]},"#1166dd":{"lch":[45.4162296513266455,104.336857924373376,257.542523527564185],"luv":[45.4162296513266455,-22.507022318245486,-101.880390006599782],"rgb":[0.0666666666666666657,0.4,0.866666666666666696],"xyz":[0.180320802645793088,0.148414210768553795,0.703232715027960364],"hpluv":[257.542523527564185,291.518421142394175,45.4162296513266455],"hsluv":[257.542523527564185,97.6147741074162,45.4162296513266455]},"#1166ee":{"lch":[46.7029335650228674,115.880201424536907,258.995545526323895],"luv":[46.7029335650228674,-22.1198283610194721,-113.74943637429719],"rgb":[0.0666666666666666657,0.4,0.933333333333333348],"xyz":[0.204132982911967853,0.157939082875023812,0.828643531096483588],"hpluv":[258.995545526323895,314.850514307077333,46.7029335650228674],"hsluv":[258.995545526323895,97.870742288996567,46.7029335650228674]},"#1166ff":{"lch":[48.0587511138394348,127.054293237547355,260.103604495506659],"luv":[48.0587511138394348,-21.8364562757409573,-125.163743182322264],"rgb":[0.0666666666666666657,0.4,1],"xyz":[0.230304031321799219,0.168407502238956508,0.966477719388265433],"hpluv":[260.103604495506659,335.471932494038299,48.0587511138394348],"hsluv":[260.103604495506659,99.9999999999992184,48.0587511138394348]},"#66ff00":{"lch":[89.0839511722278417,127.467952451328657,122.755484474710229],"luv":[89.0839511722278417,-68.9671698198214074,107.198919720201],"rgb":[0.4,1,0],"xyz":[0.41237801270657426,0.74342166657477,0.121763233231621706],"hpluv":[122.755484474710229,522.717702913530729,89.0839511722278417],"hsluv":[122.755484474710229,100.000000000002402,89.0839511722278417]},"#66ff11":{"lch":[89.1030144718140917,126.693355761899767,122.944319876693868],"luv":[89.1030144718140917,-68.8988566751164342,106.320994836735167],"rgb":[0.4,1,0.0666666666666666657],"xyz":[0.413389678206211364,0.743826332774625,0.127091338196377329],"hpluv":[122.944319876693868,520.53129302948,89.1030144718140917],"hsluv":[122.944319876693868,99.9999999999913456,89.1030144718140917]},"#66ff22":{"lch":[89.1383344673707825,125.268361506965746,123.29878008449495],"luv":[89.1383344673707825,-68.7729595958538482,104.70168300016438],"rgb":[0.4,1,0.133333333333333331],"xyz":[0.415265036344688421,0.744576476030015755,0.136968224392356536],"hpluv":[123.29878008449495,516.49933125362179,89.1383344673707825],"hsluv":[123.29878008449495,99.9999999999914877,89.1383344673707825]},"#66ff33":{"lch":[89.1964366933732,122.952924407393425,123.895139690212403],"luv":[89.1964366933732,-68.5677350303770368,102.0582546055644],"rgb":[0.4,1,0.2],"xyz":[0.418352787077146127,0.745811576322998881,0.153230378249967686],"hpluv":[123.895139690212403,509.920932540516333,89.1964366933732],"hsluv":[123.895139690212403,99.9999999999913456,89.1964366933732]},"#66ff44":{"lch":[89.2802097655713,119.677402261160566,124.785058224819977],"luv":[89.2802097655713,-68.2758869475835439,98.2908127624369143],"rgb":[0.4,1,0.266666666666666663],"xyz":[0.422810782321365042,0.747594774420686448,0.176709153202854324],"hpluv":[124.785058224819977,500.557479589511445,89.2802097655713],"hsluv":[124.785058224819977,99.9999999999914451,89.2802097655713]},"#66ff55":{"lch":[89.392045372062455,115.420778437487911,126.031255758612545],"luv":[89.392045372062455,-67.8935601171189802,93.3403481337991536],"rgb":[0.4,1,0.333333333333333315],"xyz":[0.428773196360727,0.749979740036431197,0.20811120047682824],"hpluv":[126.031255758612545,488.288652672415253,89.392045372062455],"hsluv":[126.031255758612545,99.9999999999912177,89.392045372062455]},"#66ff66":{"lch":[89.5339732348528088,110.211236984550467,127.715012949239977],"luv":[89.5339732348528088,-67.4199983006921428,87.1840615410833664],"rgb":[0.4,1,0.4],"xyz":[0.436358192134235212,0.753013738345834516,0.248058844883972174],"hpluv":[127.715012949239977,473.1190638884799,89.5339732348528088],"hsluv":[127.715012949239977,99.9999999999912177,89.5339732348528088]},"#66ff77":{"lch":[89.7077333531255,104.130085615398272,129.945267186452298],"luv":[89.7077333531255,-66.8572982376138754,79.8321764869086223],"rgb":[0.4,1,0.466666666666666674],"xyz":[0.445672205154437118,0.756739343553915367,0.297112646790370083],"hpluv":[129.945267186452298,455.203211628206077,89.7077333531255],"hsluv":[129.945267186452298,99.9999999999911466,89.7077333531255]},"#66ff88":{"lch":[89.9148190538961529,97.3190386909276413,132.870301628739924],"luv":[89.9148190538961529,-66.2101394375234378,71.3246992800528687],"rgb":[0.4,1,0.533333333333333326],"xyz":[0.456812622256380918,0.761195510394692909,0.355785510193942278],"hpluv":[132.870301628739924,434.894743355908361,89.9148190538961529],"hsluv":[132.870301628739924,99.999999999990834,89.9148190538961529]},"#66ff99":{"lch":[90.1565046807361,89.9924560427222247,136.692010716646195],"luv":[90.1565046807361,-65.4854512845448795,61.7276098246221707],"rgb":[0.4,1,0.6],"xyz":[0.469869586365453618,0.766418296038322122,0.424552187835060157],"hpluv":[136.692010716646195,412.835114866532763,90.1565046807361],"hsluv":[136.692010716646195,99.9999999999909903,90.1565046807361]},"#66ffaa":{"lch":[90.4338646074596113,82.4570841698328678,141.679424663280656],"luv":[90.4338646074596113,-64.6920148236146,51.1284064669742264],"rgb":[0.4,1,0.66666666666666663],"xyz":[0.484927279330706174,0.772441373224423189,0.503856037452058758],"hpluv":[141.679424663280656,390.10709074414774,90.4338646074596113],"hsluv":[141.679424663280656,99.9999999999905924,90.4338646074596113]},"#66ffbb":{"lch":[90.747787175062669,75.1410408914244101,148.168460326052468],"luv":[90.747787175062669,-63.84001546278364,39.631155067172358],"rgb":[0.4,1,0.733333333333333282],"xyz":[0.502064871438042792,0.779296410067358,0.59411402255070056],"hpluv":[148.168460326052468,368.486167720556807,90.747787175062669],"hsluv":[148.168460326052468,99.9999999999904077,90.747787175062669]},"#66ffcc":{"lch":[91.0989856399247486,68.6265957122477,156.512275503644645],"luv":[91.0989856399247486,-62.9405723747737085,27.3513068826366492],"rgb":[0.4,1,0.8],"xyz":[0.521357246881764547,0.787013360244846805,0.695720533220970716],"hpluv":[156.512275503644645,350.804850059399143,91.0989856399247486],"hsluv":[156.512275503644645,99.9999999999903508,91.0989856399247486]},"#66ffdd":{"lch":[91.4880074096490716,63.6578272942329875,166.916209854529029],"luv":[91.4880074096490716,-62.0052733715472826,14.410588119229697],"rgb":[0.4,1,0.866666666666666696],"xyz":[0.542875572432398146,0.795620690465100311,0.809050381120976714],"hpluv":[166.916209854529029,341.336295176875581,91.4880074096490716],"hsluv":[166.916209854529029,99.9999999999898819,91.4880074096490716]},"#66ffee":{"lch":[91.9152423718395113,61.0528599966611765,179.125088100836763],"luv":[91.9152423718395113,-61.045742111776633,0.93224663816584552],"rgb":[0.4,1,0.933333333333333348],"xyz":[0.566687752698572855,0.805145562571570328,0.934461197189499937],"hpluv":[179.125088100836763,345.840646438583576,91.9152423718395113],"hsluv":[179.125088100836763,99.9999999999894,91.9152423718395113]},"#66ffff":{"lch":[92.3809308294128,61.4559907165056,192.17705063006116],"luv":[92.3809308294128,-60.0732592166006256,-12.9631139022354667],"rgb":[0.4,1,1],"xyz":[0.592858801108404276,0.815613981935503,1.07229538548128178],"hpluv":[192.17705063006116,370.76546272919029,92.3809308294128],"hsluv":[192.17705063006116,99.9999999999889866,92.3809308294128]},"#117700":{"lch":[43.2300348418233042,65.6725964696673685,126.613348243544976],"luv":[43.2300348418233042,-39.1679175007181684,52.7139845365981],"rgb":[0.0666666666666666657,0.466666666666666674,0],"xyz":[0.0682769809733868721,0.133122662985059287,0.0220968131564111547],"hpluv":[126.613348243544976,192.769325646383436,43.2300348418233042],"hsluv":[126.613348243544976,100.000000000002359,43.2300348418233042]},"#117711":{"lch":[43.289989941732955,63.6505577690815443,127.715012949240403],"luv":[43.289989941732955,-38.9372319378938414,50.351618378457772],"rgb":[0.0666666666666666657,0.466666666666666674,0.0666666666666666657],"xyz":[0.0692886464730239904,0.13352732918491414,0.0274249181211667845],"hpluv":[127.715012949240403,186.57525992916959,43.289989941732955],"hsluv":[127.715012949240403,95.0000616991484321,43.289989941732955]},"#117722":{"lch":[43.400811094951429,60.069144786817489,129.889765673233825],"luv":[43.400811094951429,-38.5230987158151308,46.089836414888758],"rgb":[0.0666666666666666657,0.466666666666666674,0.133333333333333331],"xyz":[0.0711640046115010194,0.134277472440304968,0.037301804317145984],"hpluv":[129.889765673233825,175.627665872500842,43.400811094951429],"hsluv":[129.889765673233825,95.0973605906006725,43.400811094951429]},"#117733":{"lch":[43.5823807888255317,54.6433249694405205,133.881596062605809],"luv":[43.5823807888255317,-37.8771324094584756,39.3854770715327476],"rgb":[0.0666666666666666657,0.466666666666666674,0.2],"xyz":[0.074251755343958753,0.135512572733288067,0.0535639581747571272],"hpluv":[133.881596062605809,159.098283206795713,43.5823807888255317],"hsluv":[133.881596062605809,95.249567515942033,43.5823807888255317]},"#117744":{"lch":[43.8425891980029,47.8554364611196803,140.669149905405504],"luv":[43.8425891980029,-37.0161352468332083,30.3306533110056051],"rgb":[0.0666666666666666657,0.466666666666666674,0.266666666666666663],"xyz":[0.0787097505881776266,0.137295770830975661,0.0770427331276437588],"hpluv":[140.669149905405504,138.507858249946878,43.8425891980029],"hsluv":[140.669149905405504,95.4533619015585373,43.8425891980029]},"#117755":{"lch":[44.18711059062651,40.7988283335817243,151.872601466806259],"luv":[44.18711059062651,-35.9805491223838843,19.2339407882209947],"rgb":[0.0666666666666666657,0.466666666666666674,0.333333333333333315],"xyz":[0.0846721646275396256,0.139680736446720494,0.108444780401617674],"hpluv":[151.872601466806259,117.163251003272293,44.18711059062651],"hsluv":[151.872601466806259,95.7000805167539426,44.18711059062651]},"#117766":{"lch":[44.6197667240920879,35.4343089397309186,169.362936023125116],"luv":[44.6197667240920879,-34.8254110013137463,6.54071850990925796],"rgb":[0.0666666666666666657,0.466666666666666674,0.4],"xyz":[0.0922571604010478,0.142714734756123784,0.148392424808761636],"hpluv":[169.362936023125116,100.771099800457392,44.6197667240920879],"hsluv":[169.362936023125116,95.9777414193434453,44.6197667240920879]},"#117777":{"lch":[45.1427402486772138,34.384087641882445,192.177050630061217],"luv":[45.1427402486772138,-33.6104614986274584,-7.25274850066749],"rgb":[0.0666666666666666657,0.466666666666666674,0.466666666666666674],"xyz":[0.101571173421249716,0.146440339964204608,0.197446226715159545],"hpluv":[192.177050630061217,96.651570122263351,45.1427402486772138],"hsluv":[192.177050630061217,96.2732475219964385,45.1427402486772138]},"#117788":{"lch":[45.7567431438856502,38.9735922704815891,213.78628123605418],"luv":[45.7567431438856502,-32.3916401681270685,-21.6730833451154119],"rgb":[0.0666666666666666657,0.466666666666666674,0.533333333333333326],"xyz":[0.112711590523193544,0.150896506804982206,0.256119090118731685],"hpluv":[213.78628123605418,108.082320192335175,45.7567431438856502],"hsluv":[213.78628123605418,96.5742797371803192,45.7567431438856502]},"#117799":{"lch":[46.4611794427891169,47.8902134896154763,229.321579893426758],"luv":[46.4611794427891169,-31.2154548044213769,-36.3189747850083791],"rgb":[0.0666666666666666657,0.466666666666666674,0.6],"xyz":[0.125768554632266272,0.156119292448611363,0.32488576775984962],"hpluv":[229.321579893426758,130.796423620493698,46.4611794427891169],"hsluv":[229.321579893426758,96.8705519561321,46.4611794427891169]},"#1177aa":{"lch":[47.254315604307827,59.1280670765604199,239.379878554404911],"luv":[47.254315604307827,-30.1165063567495856,-50.8834389666627231],"rgb":[0.0666666666666666657,0.466666666666666674,0.66666666666666663],"xyz":[0.1408262475975188,0.162142369634712458,0.40418961737684822],"hpluv":[239.379878554404911,158.77844008322549,47.254315604307827],"hsluv":[239.379878554404911,97.1543662497403488,47.254315604307827]},"#1177bb":{"lch":[48.1334597651774914,71.3648635001192133,245.920143546346225],"luv":[48.1334597651774914,-29.1175429122131746,-65.1545273725937761],"rgb":[0.0666666666666666657,0.466666666666666674,0.733333333333333282],"xyz":[0.157963839704855447,0.168997406477647216,0.494447602475489967],"hpluv":[245.920143546346225,188.138070935962588,48.1334597651774914],"hsluv":[245.920143546346225,97.4206074841270464,48.1334597651774914]},"#1177cc":{"lch":[49.0951452720171488,83.8954152066927463,250.336037436893122],"luv":[49.0951452720171488,-28.2310616920000612,-79.0028344329863756],"rgb":[0.0666666666666666657,0.466666666666666674,0.8],"xyz":[0.177256215148577201,0.176714356655136018,0.596054113145760178],"hpluv":[250.336037436893122,216.83980339157776,49.0951452720171488],"hsluv":[250.336037436893122,97.666394869173061,49.0951452720171488]},"#1177dd":{"lch":[50.1353116048344702,96.3594544857749,253.441700788778064],"luv":[50.1353116048344702,-27.4615589113116805,-92.3634519220491512],"rgb":[0.0666666666666666657,0.466666666666666674,0.866666666666666696],"xyz":[0.198774540699210744,0.185321686875389552,0.709383961045766176],"hpluv":[253.441700788778064,243.887723915279508,50.1353116048344702],"hsluv":[253.441700788778064,97.8905898818146341,50.1353116048344702]},"#1177ee":{"lch":[51.2494756916451593,108.579054392530807,255.706052301270915],"luv":[51.2494756916451593,-26.8078049752198453,-105.217644172385562],"rgb":[0.0666666666666666657,0.466666666666666674,0.933333333333333348],"xyz":[0.222586720965385454,0.194846558981859597,0.834794777114289399],"hpluv":[255.706052301270915,268.841280267375566,51.2494756916451593],"hsluv":[255.706052301270915,98.0932983984315,51.2494756916451593]},"#1177ff":{"lch":[52.4328877873246739,120.474912105814852,257.407785454377859],"luv":[52.4328877873246739,-26.2648114927385947,-117.577056112809359],"rgb":[0.0666666666666666657,0.466666666666666674,1],"xyz":[0.248757769375216875,0.205314978345792293,0.972628965406071133],"hpluv":[257.407785454377859,291.562836812545811,52.4328877873246739],"hsluv":[257.407785454377859,99.9999999999990905,52.4328877873246739]},"#118800":{"lch":[49.1629818744817157,75.0325981068150725,126.891404302910644],"luv":[49.1629818744817157,-45.0420871994947447,60.0091756264985],"rgb":[0.0666666666666666657,0.533333333333333326,0],"xyz":[0.0903493506983573252,0.177267402435000831,0.0294542697314011],"hpluv":[126.891404302910644,193.664979881129256,49.1629818744817157],"hsluv":[126.891404302910644,100.000000000002487,49.1629818744817157]},"#118811":{"lch":[49.2125288978643,73.2988946552939211,127.715012949240403],"luv":[49.2125288978643,-44.8394509336223663,57.9840633075946883],"rgb":[0.0666666666666666657,0.533333333333333326,0.0666666666666666657],"xyz":[0.0913610161979944435,0.177672068634855684,0.0347823746961567343],"hpluv":[127.715012949240403,188.999680167490567,49.2125288978643],"hsluv":[127.715012949240403,96.2345237189928326,49.2125288978643]},"#118822":{"lch":[49.3041772439320312,70.1927728141533,129.31476933948187],"luv":[49.3041772439320312,-44.4727599639014315,54.3065279366352556],"rgb":[0.0666666666666666657,0.533333333333333326,0.133333333333333331],"xyz":[0.0932363743364714725,0.178422211890246513,0.0446592608921359269],"hpluv":[129.31476933948187,180.6541776618526,49.3041772439320312],"hsluv":[129.31476933948187,96.2899748067816859,49.3041772439320312]},"#118833":{"lch":[49.454516912369769,65.3819990709954766,132.170105234646456],"luv":[49.454516912369769,-43.8931572746598917,48.4581938064309767],"rgb":[0.0666666666666666657,0.533333333333333326,0.2],"xyz":[0.0963241250689292,0.179657312183229612,0.060921414749747077],"hpluv":[132.170105234646456,167.761213036429979,49.454516912369769],"hsluv":[132.170105234646456,96.3778002926358,49.454516912369769]},"#118844":{"lch":[49.6703617695526,59.1036258375550787,136.829676092870073],"luv":[49.6703617695526,-43.1056388924535057,40.4368950689726887],"rgb":[0.0666666666666666657,0.533333333333333326,0.266666666666666663],"xyz":[0.10078212031314808,0.181440510280917205,0.0844001897026337156],"hpluv":[136.829676092870073,150.9927614306973,49.6703617695526],"hsluv":[136.829676092870073,96.4975069627829356,49.6703617695526]},"#118855":{"lch":[49.9568473676091145,51.9652717779864091,144.176427678513875],"luv":[49.9568473676091145,-42.1346422468413806,30.4148219408018328],"rgb":[0.0666666666666666657,0.533333333333333326,0.333333333333333315],"xyz":[0.106744534352510079,0.183825475896662038,0.115802236976607617],"hpluv":[144.176427678513875,131.995007799011802,49.9568473676091145],"hsluv":[144.176427678513875,96.6457662191899658,49.9568473676091145]},"#118866":{"lch":[50.3177367885428879,45.0776565581224133,155.49998607369966],"luv":[50.3177367885428879,-41.0189171061503615,18.6934095394821433],"rgb":[0.0666666666666666657,0.533333333333333326,0.4],"xyz":[0.11432953012601825,0.186859474206065329,0.155749881383751593],"hpluv":[155.49998607369966,113.67882025976219,50.3177367885428879],"hsluv":[155.49998607369966,96.8171590628882512,50.3177367885428879]},"#118877":{"lch":[50.7555873970602391,40.2042284802375036,171.921706717236162],"luv":[50.7555873970602391,-39.8052806191025255,5.64974535051283322],"rgb":[0.0666666666666666657,0.533333333333333326,0.466666666666666674],"xyz":[0.12364354314622017,0.190585079414146152,0.204803683290149502],"hpluv":[171.921706717236162,100.514149141729121,50.7555873970602391],"hsluv":[171.921706717236162,97.0050762990714333,50.7555873970602391]},"#118888":{"lch":[51.2718664023781088,39.4294820301430349,192.17705063006116],"luv":[51.2718664023781088,-38.5423368357954814,-8.3169901046866368],"rgb":[0.0666666666666666657,0.533333333333333326,0.533333333333333326],"xyz":[0.134783960248164,0.19504124625492375,0.263476546693721669],"hpluv":[192.17705063006116,97.5845966821491118,51.2718664023781088],"hsluv":[192.17705063006116,97.2026219422035,51.2718664023781088]},"#118899":{"lch":[51.8670503792929907,43.7110075029310678,211.486174513119295],"luv":[51.8670503792929907,-37.2752705782940623,-22.8299448145688864],"rgb":[0.0666666666666666657,0.533333333333333326,0.6],"xyz":[0.147840924357236725,0.200264031898552908,0.332243224334839549],"hpluv":[211.486174513119295,106.93960912970239,51.8670503792929907],"hsluv":[211.486174513119295,97.4033619208845,51.8670503792929907]},"#1188aa":{"lch":[52.5407237145479371,52.059033028958666,226.184651315961702],"luv":[52.5407237145479371,-36.0423686073764102,-37.5644856890150507],"rgb":[0.0666666666666666657,0.533333333333333326,0.66666666666666663],"xyz":[0.162898617322489253,0.206287109084654,0.411547073951838149],"hpluv":[226.184651315961702,125.730132415512543,52.5407237145479371],"hsluv":[226.184651315961702,97.6018250350267,52.5407237145479371]},"#1188bb":{"lch":[53.2916815113449047,62.8295543710454396,236.286042109927791],"luv":[53.2916815113449047,-34.8733609598062557,-52.2628127623381573],"rgb":[0.0666666666666666657,0.533333333333333326,0.733333333333333282],"xyz":[0.1800362094298259,0.213142145927588761,0.501805059050479896],"hpluv":[236.286042109927791,149.604233097343041,53.2916815113449047],"hsluv":[236.286042109927791,97.7937430875757201,53.2916815113449047]},"#1188cc":{"lch":[54.1180375597057548,74.8024459991104607,243.146336149822275],"luv":[54.1180375597057548,-33.7892633498457826,-66.735984369188742],"rgb":[0.0666666666666666657,0.533333333333333326,0.8],"xyz":[0.199328584873547654,0.220859096105077563,0.60341156972075],"hpluv":[243.146336149822275,175.393335022858878,54.1180375597057548],"hsluv":[243.146336149822275,97.9760759990174819,54.1180375597057548]},"#1188dd":{"lch":[55.0173353812408266,87.2581949437380331,247.918019831454984],"luv":[55.0173353812408266,-32.8032215872693484,-80.8575366823396138],"rgb":[0.0666666666666666657,0.533333333333333326,0.866666666666666696],"xyz":[0.220846910424181198,0.229466426325331097,0.716741417620756],"hpluv":[247.918019831454984,201.254684785248685,55.0173353812408266],"hsluv":[247.918019831454984,98.1468934162311513,55.0173353812408266]},"#1188ee":{"lch":[55.9866591638471363,99.7959623087877645,251.344854654704591],"luv":[55.9866591638471363,-31.921869990719685,-94.5527805483930734],"rgb":[0.0666666666666666657,0.533333333333333326,0.933333333333333348],"xyz":[0.244659090690355907,0.238991298431801141,0.842152233689279273],"hpluv":[251.344854654704591,226.187053837960264,55.9866591638471363],"hsluv":[251.344854654704591,98.3051827042817,55.9866591638471363]},"#1188ff":{"lch":[57.0227411270994082,112.196885547184024,253.882464988485651],"luv":[57.0227411270994082,-31.1468293758358783,-107.786901552649141],"rgb":[0.0666666666666666657,0.533333333333333326,1],"xyz":[0.270830139100187328,0.249459717795733837,0.979986421981061118],"hpluv":[253.882464988485651,249.673263359937977,57.0227411270994082],"hsluv":[253.882464988485651,99.9999999999988916,57.0227411270994082]},"#119900":{"lch":[54.9698669410824721,84.160615619067471,127.079428544988929],"luv":[54.9698669410824721,-50.7422517332937772,67.1433772639973],"rgb":[0.0666666666666666657,0.6,0],"xyz":[0.116218951150824812,0.229006603339936526,0.0380774698822233526],"hpluv":[127.079428544988929,194.277964405092661,54.9698669410824721],"hsluv":[127.079428544988929,100.000000000002373,54.9698669410824721]},"#119911":{"lch":[55.0116447857556494,82.6558224500047,127.715012949240403],"luv":[55.0116447857556494,-50.563404981135136,65.3859852078442],"rgb":[0.0666666666666666657,0.6,0.0666666666666666657],"xyz":[0.11723061665046193,0.229411269539791379,0.0434055748469789823],"hpluv":[127.715012949240403,190.659367551848248,55.0116447857556494],"hsluv":[127.715012949240403,97.0796004133795094,55.0116447857556494]},"#119922":{"lch":[55.0889600096002852,79.9388272851777657,128.936266554168185],"luv":[55.0889600096002852,-50.237998627918941,62.1800579091938204],"rgb":[0.0666666666666666657,0.6,0.133333333333333331],"xyz":[0.119105974788938959,0.230161412795182208,0.0532824610429581819],"hpluv":[128.936266554168185,184.133380166819137,55.0889600096002852],"hsluv":[128.936266554168185,97.113065541928691,55.0889600096002852]},"#119933":{"lch":[55.215893256771821,75.6695179958245916,131.075562701176153],"luv":[55.215893256771821,-49.7189430335536,57.0429895547794175],"rgb":[0.0666666666666666657,0.6,0.2],"xyz":[0.122193725521396693,0.231396513088165307,0.0695446149005693182],"hpluv":[131.075562701176153,173.898642472918851,55.215893256771821],"hsluv":[131.075562701176153,97.1665253707361,55.215893256771821]},"#119944":{"lch":[55.398361036949,69.9528706873860671,134.469703140623466],"luv":[55.398361036949,-49.0042253731102591,49.9198358669935303],"rgb":[0.0666666666666666657,0.6,0.266666666666666663],"xyz":[0.126651720765615566,0.2331797111858529,0.0930233898534559567],"hpluv":[134.469703140623466,160.231519707698453,55.398361036949],"hsluv":[134.469703140623466,97.2403070889690184,55.398361036949]},"#119955":{"lch":[55.6409569880907497,63.1400511875114887,139.633471194580181],"luv":[55.6409569880907497,-48.1074656204671172,40.8942271664002206],"rgb":[0.0666666666666666657,0.6,0.333333333333333315],"xyz":[0.132614134804977579,0.235564676801597733,0.124425437127429872],"hpluv":[139.633471194580181,143.995747016857166,55.6409569880907497],"hsluv":[139.633471194580181,97.3331834328701575,55.6409569880907497]},"#119966":{"lch":[55.9472168173363,55.8918514512489466,147.340496807064056],"luv":[55.9472168173363,-47.0549257965888,30.1617807320125095],"rgb":[0.0666666666666666657,0.6,0.4],"xyz":[0.140199130578485737,0.238598675111001024,0.164373081534573834],"hpluv":[147.340496807064056,126.76791164907155,55.9472168173363],"hsluv":[147.340496807064056,97.4426708460479,55.9472168173363]},"#119977":{"lch":[56.319758368673476,49.2851425936320169,158.582299284916047],"luv":[56.319758368673476,-45.8816608646539308,17.9971796894826],"rgb":[0.0666666666666666657,0.6,0.466666666666666674],"xyz":[0.14951314359868767,0.242324280319081847,0.213426883440971743],"hpluv":[158.582299284916047,111.043862853999471,56.319758368673476],"hsluv":[158.582299284916047,97.5654087237770398,56.319758368673476]},"#119988":{"lch":[56.7603710001512951,44.8759084930006864,173.96527373508107],"luv":[56.7603710001512951,-44.6272223318454451,4.71785862613608131],"rgb":[0.0666666666666666657,0.6,0.533333333333333326],"xyz":[0.16065356070063147,0.246780447159859445,0.27209974684454391],"hpluv":[173.96527373508107,100.324581054675164,56.7603710001512951],"hsluv":[173.96527373508107,97.6975811674153647,56.7603710001512951]},"#119999":{"lch":[57.2700846473106822,44.3289506401906692,192.177050630061103],"luv":[57.2700846473106822,-43.3315696575835219,-9.35045110518458422],"rgb":[0.0666666666666666657,0.6,0.6],"xyz":[0.173710524809704198,0.252003232803488575,0.340866424485661845],"hpluv":[192.177050630061103,98.2197789195824384,57.2700846473106822],"hsluv":[192.177050630061103,97.8353178900151903,57.2700846473106822]},"#1199aa":{"lch":[57.849232550626823,48.3524707931101716,209.625127722111756],"luv":[57.849232550626823,-42.0317498411296384,-23.9017454821038378],"rgb":[0.0666666666666666657,0.6,0.66666666666666663],"xyz":[0.188768217774956726,0.258026309989589697,0.42017027410266039],"hpluv":[209.625127722111756,106.062142541807418,57.849232550626823],"hsluv":[209.625127722111756,97.9750198241805492,57.849232550626823]},"#1199bb":{"lch":[58.4975141278551263,56.1838887208170235,223.492153209811363],"luv":[58.4975141278551263,-40.7596491137071553,-38.6688551152037832],"rgb":[0.0666666666666666657,0.6,0.733333333333333282],"xyz":[0.2059058098822934,0.264881346832524456,0.510428259201302192],"hpluv":[223.492153209811363,121.8747424026255,58.4975141278551263],"hsluv":[223.492153209811363,98.1135798876595686,58.4975141278551263]},"#1199cc":{"lch":[59.2140605434028515,66.4726101728698211,233.498474693243395],"luv":[59.2140605434028515,-39.5408457239066138,-53.4334111079625274],"rgb":[0.0666666666666666657,0.6,0.8],"xyz":[0.225198185326015127,0.272598297010013257,0.612034769871572348],"hpluv":[233.498474693243395,142.448281943894045,59.2140605434028515],"hsluv":[233.498474693243395,98.2484961488154482,59.2140605434028515]},"#1199dd":{"lch":[59.9975033067865553,78.1149919905427907,240.560044488236258],"luv":[59.9975033067865553,-38.3943918665613637,-68.0281018909060151],"rgb":[0.0666666666666666657,0.6,0.866666666666666696],"xyz":[0.24671651087664867,0.281205627230266819,0.725364617771578346],"hpluv":[240.560044488236258,165.211601361935521,59.9975033067865553],"hsluv":[240.560044488236258,98.3778942246892285,59.9975033067865553]},"#1199ee":{"lch":[60.8460449735814706,90.4022578402124,245.60857134482],"luv":[60.8460449735814706,-37.3332566635070862,-82.3334450239084106],"rgb":[0.0666666666666666657,0.6,0.933333333333333348],"xyz":[0.270528691142823408,0.290730499336736836,0.850775433840101569],"hpluv":[245.60857134482,188.532510112076068,60.8460449735814706],"hsluv":[245.60857134482,98.5004851129029788,60.8460449735814706]},"#1199ff":{"lch":[61.7575303771721877,102.910627792409826,249.306643617498082],"luv":[61.7575303771721877,-36.3651553748586,-96.2713497733895167],"rgb":[0.0666666666666666657,0.6,1],"xyz":[0.296699739552654829,0.301198918700669505,0.988609622131883414],"hpluv":[249.306643617498082,211.450946466820028,61.7575303771721877],"hsluv":[249.306643617498082,99.9999999999986215,61.7575303771721877]},"#000000":{"lch":[0,0,0],"luv":[0,0,0],"rgb":[0,0,0],"xyz":[0,0,0],"hpluv":[0,0,0],"hsluv":[0,0,0]},"#000011":{"lch":[0.365533479526218952,1.47895322486610792,265.8743202181779],"luv":[0.365533479526218952,-0.106402530834795422,-1.47512072142377915],"rgb":[0,0,0.0666666666666666657],"xyz":[0.00101166549963712174,0.000404666199854854377,0.00532810496475563146],"hpluv":[265.8743202181779,513.41269684428039,0.365533479526218952],"hsluv":[265.8743202181779,100.000000000000867,0.365533479526218952]},"#000022":{"lch":[1.04313510374015572,4.22053823263236,265.8743202181779],"luv":[1.04313510374015572,-0.303644457367982512,-4.20960128950726],"rgb":[0,0,0.133333333333333331],"xyz":[0.0028870236381141408,0.00115480945524567245,0.0152049911607348275],"hpluv":[265.8743202181779,513.41269684428039,1.04313510374015572],"hsluv":[265.8743202181779,100.000000000000838,1.04313510374015572]},"#000033":{"lch":[2.15879662382733661,8.73451929157831,265.8743202181779],"luv":[2.15879662382733661,-0.62840050829424543,-8.71188498868810868],"rgb":[0,0,0.2],"xyz":[0.00597477437057188088,0.00238990974822878574,0.0314671450183459725],"hpluv":[265.8743202181779,513.412696844280276,2.15879662382733661],"hsluv":[265.8743202181779,100.000000000000838,2.15879662382733661]},"#000044":{"lch":[3.76955286085941,15.251660031516769,265.874320218177957],"luv":[3.76955286085941,-1.0972728545435857,-15.2121374566379668],"rgb":[0,0,0.266666666666666663],"xyz":[0.0104327696147907597,0.00417310784591636182,0.054945919971232611],"hpluv":[265.874320218177957,513.41269684428039,3.76955286085941],"hsluv":[265.874320218177957,100.000000000000981,3.76955286085941]},"#000055":{"lch":[5.92388346812606947,23.9681097618519345,265.8743202181779],"luv":[5.92388346812606947,-1.7243733575266309,-23.905999708860417],"rgb":[0,0,0.333333333333333315],"xyz":[0.0163951836541527535,0.00655807346166119385,0.0863479672452065194],"hpluv":[265.8743202181779,513.41269684428039,5.92388346812606947],"hsluv":[265.8743202181779,100.000000000000838,5.92388346812606947]},"#000066":{"lch":[8.64689012997685,34.9854302247980513,265.8743202181779],"luv":[8.64689012997685,-2.51700882467034193,-34.8947703043127149],"rgb":[0,0,0.4],"xyz":[0.0239801794276609283,0.00959207177106450627,0.126295611652350481],"hpluv":[265.8743202181779,513.412696844280276,8.64689012997685],"hsluv":[265.8743202181779,100.000000000000838,8.64689012997685]},"#000077":{"lch":[11.4958709948623863,46.5124439559768703,265.874320218177957],"luv":[11.4958709948623863,-3.34631391244679577,-46.3919133681426672],"rgb":[0,0,0.466666666666666674],"xyz":[0.0332941924478628443,0.0133176769791453226,0.17534941355874839],"hpluv":[265.874320218177957,513.412696844280276,11.4958709948623863],"hsluv":[265.874320218177957,100.000000000001,11.4958709948623863]},"#000088":{"lch":[14.2727431262745554,57.7477048111956535,265.874320218177957],"luv":[14.2727431262745554,-4.15462898927595781,-57.598059593379169],"rgb":[0,0,0.533333333333333326],"xyz":[0.0444346095498066723,0.0177738438199229153,0.234022276962320558],"hpluv":[265.874320218177957,513.41269684428039,14.2727431262745554],"hsluv":[265.874320218177957,100.000000000000952,14.2727431262745554]},"#000099":{"lch":[16.9872454361813823,68.7306165552763701,265.874320218177957],"luv":[16.9872454361813823,-4.94478893879780923,-68.5525106354185567],"rgb":[0,0,0.6],"xyz":[0.0574915736588793858,0.0229966294635520763,0.302788954603438465],"hpluv":[265.874320218177957,513.412696844280163,16.9872454361813823],"hsluv":[265.874320218177957,100.000000000000952,16.9872454361813823]},"#0000aa":{"lch":[19.6469460262523299,79.4917998262647529,265.8743202181779],"luv":[19.6469460262523299,-5.71899674710351302,-79.2858077831434116],"rgb":[0,0,0.66666666666666663],"xyz":[0.0725492666241319278,0.0290197066496531778,0.382092804220437066],"hpluv":[265.8743202181779,513.41269684428039,19.6469460262523299],"hsluv":[265.8743202181779,100.000000000000824,19.6469460262523299]},"#0000bb":{"lch":[22.2578820656552736,90.0556810893410926,265.8743202181779],"luv":[22.2578820656552736,-6.47900976369593895,-89.8223142039161644],"rgb":[0,0,0.733333333333333282],"xyz":[0.0896868587314685745,0.0358747434925879363,0.472350789319078812],"hpluv":[265.8743202181779,513.41269684428039,22.2578820656552736],"hsluv":[265.8743202181779,100.000000000000796,22.2578820656552736]},"#0000cc":{"lch":[24.8249727536546274,100.442163488877583,265.874320218177957],"luv":[24.8249727536546274,-7.22625991008361535,-100.18188146585355],"rgb":[0,0,0.8],"xyz":[0.108979234175190315,0.043591693670076738,0.573957299989349],"hpluv":[265.874320218177957,513.41269684428039,24.8249727536546274],"hsluv":[265.874320218177957,100.000000000001,24.8249727536546274]},"#0000dd":{"lch":[27.3522973211786535,110.667751646404724,265.8743202181779],"luv":[27.3522973211786535,-7.96193460279319343,-110.380971421034161],"rgb":[0,0,0.866666666666666696],"xyz":[0.130497559725823858,0.052199023890330272,0.687287147889355],"hpluv":[265.8743202181779,513.412696844280276,27.3522973211786535],"hsluv":[265.8743202181779,100.000000000000824,27.3522973211786535]},"#0000ee":{"lch":[29.8432887766479737,120.746335558760222,265.8743202181779],"luv":[29.8432887766479737,-8.68703315051946,-120.433438072283309],"rgb":[0,0,0.933333333333333348],"xyz":[0.154309739991998596,0.0617238959968003,0.812697963957878189],"hpluv":[265.8743202181779,513.41269684428039,29.8432887766479737],"hsluv":[265.8743202181779,100.000000000000838,29.8432887766479737]},"#0000ff":{"lch":[32.3008729039800215,130.68975298582734,265.8743202181779],"luv":[32.3008729039800215,-9.40240721482262,-130.351088503561101],"rgb":[0,0,1],"xyz":[0.18048078840183,0.072192315360733,0.95053215224966],"hpluv":[265.8743202181779,513.41269684428039,32.3008729039800215],"hsluv":[265.8743202181779,100.000000000000824,32.3008729039800215]},"#001100":{"lch":[3.62113466359794112,5.60448249758782424,127.715012949240474],"luv":[3.62113466359794112,-3.42845440085753106,4.43350025228474376],"rgb":[0,0.0666666666666666657,0],"xyz":[0.00200440026092840902,0.00400880052185687355,0.00066813342030945088],"hpluv":[127.715012949240474,196.394882900214469,3.62113466359794112],"hsluv":[127.715012949240474,100.000000000002217,3.62113466359794112]},"#001111":{"lch":[3.9866681431241604,3.15408977882195618,192.17705063006116],"luv":[3.9866681431241604,-3.08312421078118115,-0.665302512969894178],"rgb":[0,0.0666666666666666657,0.0666666666666666657],"xyz":[0.00301606576056553076,0.00441346672171172814,0.00599623838506508234],"hpluv":[192.17705063006116,100.392967527320764,3.9866681431241604],"hsluv":[192.17705063006116,99.9999999999914,3.9866681431241604]},"#001122":{"lch":[4.66426976733809706,7.30142401028103372,246.87889630792742],"luv":[4.66426976733809706,-2.86709314837997242,-6.71495118794031054],"rgb":[0,0.0666666666666666657,0.133333333333333331],"xyz":[0.00489142389904254939,0.005163609977102546,0.0158731245810442775],"hpluv":[246.87889630792742,198.638412351210178,4.66426976733809706],"hsluv":[246.87889630792742,99.9999999999921414,4.66426976733809706]},"#001133":{"lch":[5.77993128742527773,13.8979406242137369,257.974087263939282],"luv":[5.77993128742527773,-2.89569220292521434,-13.5929290537429299],"rgb":[0,0.0666666666666666657,0.2],"xyz":[0.00797917463150029,0.00639871027008565886,0.0321352784386554208],"hpluv":[257.974087263939282,305.117489912579458,5.77993128742527773],"hsluv":[257.974087263939282,99.9999999999925,5.77993128742527773]},"#001144":{"lch":[7.39068752445735111,21.802452480470059,261.611708702028636],"luv":[7.39068752445735111,-3.1805605696034065,-21.569213444774455],"rgb":[0,0.0666666666666666657,0.266666666666666663],"xyz":[0.0124371698757191687,0.00818190836777323537,0.0556140533915420593],"hpluv":[261.611708702028636,374.334482048802613,7.39068752445735111],"hsluv":[261.611708702028636,99.9999999999929656,7.39068752445735111]},"#001155":{"lch":[9.4550232844459714,31.0886305445366773,263.238579866128873],"luv":[9.4550232844459714,-3.6602302532303379,-30.8724094237562916],"rgb":[0,0.0666666666666666657,0.333333333333333315],"xyz":[0.0183995839150811608,0.0105668739835180665,0.0870161006655159747],"hpluv":[263.238579866128873,417.232678203522596,9.4550232844459714],"hsluv":[263.238579866128873,99.9999999999929514,9.4550232844459714]},"#001166":{"lch":[11.6894020192987682,40.9340765206813302,264.100423242359113],"luv":[11.6894020192987682,-4.20741678933990659,-40.7172723123955791],"rgb":[0,0.0666666666666666657,0.4],"xyz":[0.025984579688589339,0.0136008722929213798,0.126963745072659923],"hpluv":[264.100423242359113,444.357002567308371,11.6894020192987682],"hsluv":[264.100423242359113,99.9999999999928235,11.6894020192987682]},"#001177":{"lch":[14.0165943101603965,51.0460922578313898,264.608714664977526],"luv":[14.0165943101603965,-4.79613195559092276,-50.8202779710972621],"rgb":[0,0.0666666666666666657,0.466666666666666674],"xyz":[0.0352985927087912515,0.0173264775010021979,0.176017546979057832],"hpluv":[264.608714664977526,462.124851551559573,14.0165943101603965],"hsluv":[264.608714664977526,99.9999999999931504,14.0165943101603965]},"#001188":{"lch":[16.3962585295353378,61.2721603523949625,264.931782730652174],"luv":[16.3962585295353378,-5.41289085195630371,-61.0325998698597871],"rgb":[0,0.0666666666666666657,0.533333333333333326],"xyz":[0.0464390098107350796,0.0217826443417797888,0.23469041038263],"hpluv":[264.931782730652174,474.195864485329537,16.3962585295353378],"hsluv":[264.931782730652174,99.9999999999933209,16.3962585295353378]},"#001199":{"lch":[18.8023327262484941,71.5200065602600148,265.148843888859801],"luv":[18.8023327262484941,-6.04826966448705239,-71.2638040834565771],"rgb":[0,0.0666666666666666657,0.6],"xyz":[0.059495973919807793,0.0270054299854089498,0.303457088023747934],"hpluv":[265.148843888859801,482.675370310212884,18.8023327262484941],"hsluv":[265.148843888859801,99.9999999999930651,18.8023327262484941]},"#0011aa":{"lch":[21.2181090603332123,81.7349311996174919,265.301088447161305],"luv":[21.2181090603332123,-6.69569086805443892,-81.4602154551880488],"rgb":[0,0.0666666666666666657,0.66666666666666663],"xyz":[0.0745536668850603351,0.0330285071715100548,0.382760937640746535],"hpluv":[265.301088447161305,488.81030222212587,21.2181090603332123],"hsluv":[265.301088447161305,99.9999999999931788,21.2181090603332123]},"#0011bb":{"lch":[23.6329047323064216,91.8852368853417,265.411605614461337],"luv":[23.6329047323064216,-7.35054503717070418,-91.590754146539723],"rgb":[0,0.0666666666666666657,0.733333333333333282],"xyz":[0.0916912589923969817,0.0398835440144448133,0.473018922739388281],"hpluv":[265.411605614461337,493.364573724961247,23.6329047323064216],"hsluv":[265.411605614461337,99.999999999993,23.6329047323064216]},"#0011cc":{"lch":[26.0399131129061345,101.953231398784169,265.494123438592396],"luv":[26.0399131129061345,-8.00958293333115,-101.638122640513785],"rgb":[0,0.0666666666666666657,0.8],"xyz":[0.110983634436118722,0.047600494191933615,0.574625433409658437],"hpluv":[265.494123438592396,496.821968194535657,26.0399131129061345],"hsluv":[265.494123438592396,99.9999999999927383,26.0399131129061345]},"#0011dd":{"lch":[28.43483595206839,111.929749681002491,265.557201901085818],"luv":[28.43483595206839,-8.67050070949402496,-111.593419524175076],"rgb":[0,0.0666666666666666657,0.866666666666666696],"xyz":[0.132501959986752266,0.056207824412187149,0.687955281309664435],"hpluv":[265.557201901085818,499.498435149301031,28.43483595206839],"hsluv":[265.557201901085818,99.9999999999932214,28.43483595206839]},"#0011ee":{"lch":[30.8150119654139019,121.810820553676152,265.60639254385444],"luv":[30.8150119654139019,-9.33165721729429798,-121.452855781734542],"rgb":[0,0.0666666666666666657,0.933333333333333348],"xyz":[0.156314140252927,0.0657326965186571799,0.813366097378187658],"hpluv":[265.60639254385444,501.606152289563909,30.8150119654139019],"hsluv":[265.60639254385444,99.9999999999933635,30.8150119654139019]},"#0011ff":{"lch":[33.1788572452669683,131.59562707663585,265.645416939351662],"luv":[33.1788572452669683,-9.99188030865750321,-131.215743695604147],"rgb":[0,0.0666666666666666657,1],"xyz":[0.182485188662758396,0.076201115882589876,0.951200285669969503],"hpluv":[265.645416939351662,503.291227463659,33.1788572452669683],"hsluv":[265.645416939351662,99.9999999999995,33.1788572452669683]},"#55aa00":{"lch":[62.2364297391950743,84.7105424007581291,119.071642820441127],"luv":[62.2364297391950743,-41.1610955154551661,74.0380997176333437],"rgb":[0.333333333333333315,0.66666666666666663,0],"xyz":[0.181203244729902568,0.306798408854291604,0.0496696976001293408],"hpluv":[119.071642820441127,172.715819722381468,62.2364297391950743],"hsluv":[119.071642820441127,100.00000000000216,62.2364297391950743]},"#55aa11":{"lch":[62.270812500354296,83.3839078255156352,119.512873370738717],"luv":[62.270812500354296,-41.0765057562956173,72.5644317769187808],"rgb":[0.333333333333333315,0.66666666666666663,0.0666666666666666657],"xyz":[0.182214910229539701,0.307203075054146457,0.0549978025648849705],"hpluv":[119.512873370738717,169.917081036602212,62.270812500354296],"hsluv":[119.512873370738717,97.826098763204655,62.270812500354296]},"#55aa22":{"lch":[62.3344691942433826,80.9675552156414,120.358690899927907],"luv":[62.3344691942433826,-40.9219560187625078,69.8651451955580285],"rgb":[0.333333333333333315,0.66666666666666663,0.133333333333333331],"xyz":[0.184090268368016702,0.307953218309537258,0.0648746887608641631],"hpluv":[120.358690899927907,164.824621464176317,62.3344691942433826],"hsluv":[120.358690899927907,93.8493385636837729,62.3344691942433826]},"#55aa33":{"lch":[62.4390542004851312,77.1100321042589343,121.835090998601942],"luv":[62.4390542004851312,-40.6737079775314143,65.5103543760705094],"rgb":[0.333333333333333315,0.66666666666666663,0.2],"xyz":[0.187178019100474435,0.309188318602520384,0.0811368426184753133],"hpluv":[121.835090998601942,156.708983850290963,62.4390542004851312],"hsluv":[121.835090998601942,87.4478443822902,62.4390542004851312]},"#55aa44":{"lch":[62.5895604608427192,71.8060360850404322,124.168545167949461],"luv":[62.5895604608427192,-40.3283690350335959,59.4115264003566281],"rgb":[0.333333333333333315,0.66666666666666663,0.266666666666666663],"xyz":[0.191636014344693323,0.310971516700207951,0.104615617571361952],"hpluv":[124.168545167949461,145.578881327618376,62.5895604608427192],"hsluv":[124.168545167949461,78.5131262768233569,62.5895604608427192]},"#55aa55":{"lch":[62.7899606618147317,65.2067785819955361,127.715012949239551],"luv":[62.7899606618147317,-39.8892256495404212,51.582687503865472],"rgb":[0.333333333333333315,0.66666666666666663,0.333333333333333315],"xyz":[0.197598428384055336,0.313356482315952811,0.136017664845335867],"hpluv":[127.715012949239551,131.777681042751937,62.7899606618147317],"hsluv":[127.715012949239551,67.0983271543339583,62.7899606618147317]},"#55aa66":{"lch":[63.0434325957243402,57.6560159218084,133.059858461454269],"luv":[63.0434325957243402,-39.3653397911167744,42.1258376190401904],"rgb":[0.333333333333333315,0.66666666666666663,0.4],"xyz":[0.205183424157563493,0.31639048062535613,0.175965309252479829],"hpluv":[133.059858461454269,116.049721847977636,63.0434325957243402],"hsluv":[133.059858461454269,68.1368400599560289,63.0434325957243402]},"#55aa77":{"lch":[63.3524771250310863,49.7736139598232441,141.163090238883626],"luv":[63.3524771250310863,-38.7703675351212311,31.2133184364163512],"rgb":[0.333333333333333315,0.66666666666666663,0.466666666666666674],"xyz":[0.214497437177765427,0.320116085833436925,0.225019111158877738],"hpluv":[141.163090238883626,99.6953496544650903,63.3524771250310863],"hsluv":[141.163090238883626,69.3257510819996696,63.3524771250310863]},"#55aa88":{"lch":[63.7189896387035901,42.62351374085884,153.427389325734708],"luv":[63.7189896387035901,-38.1211143540371324,19.0668446268281784],"rgb":[0.333333333333333315,0.66666666666666663,0.533333333333333326],"xyz":[0.225637854279709227,0.324572252674214523,0.283691974562449878],"hpluv":[153.427389325734708,84.882799477410984,63.7189896387035901],"hsluv":[153.427389325734708,70.6362499177174783,63.7189896387035901]},"#55aa99":{"lch":[64.1443101574831473,37.9035590936142697,170.991128647613664],"luv":[64.1443101574831473,-37.4359848569684885,5.93521943587048106],"rgb":[0.333333333333333315,0.66666666666666663,0.6],"xyz":[0.238694818388781954,0.329795038317843681,0.352458652203567813],"hpluv":[170.991128647613664,74.9827180661079211,64.1443101574831473],"hsluv":[170.991128647613664,72.0364673991159918,64.1443101574831473]},"#55aaaa":{"lch":[64.6292640862610881,37.5790288142004414,192.177050630061],"luv":[64.6292640862610881,-36.7335179653569526,-7.92666793219602717],"rgb":[0.333333333333333315,0.66666666666666663,0.66666666666666663],"xyz":[0.253752511354034482,0.335818115503944803,0.431762501820566413],"hpluv":[192.177050630061,73.7828909738526,64.6292640862610881],"hsluv":[192.177050630061,73.4940830927894808,64.6292640862610881]},"#55aabb":{"lch":[65.1741997434662466,42.3607987370151307,211.725401595501864],"luv":[65.1741997434662466,-36.0311661131296148,-22.2753751520813346],"rgb":[0.333333333333333315,0.66666666666666663,0.733333333333333282],"xyz":[0.270890103461371157,0.342673152346879561,0.522020486919208104],"hpluv":[211.725401595501864,82.4760322189960249,65.1741997434662466],"hsluv":[211.725401595501864,74.9784994025983,65.1741997434662466]},"#55aacc":{"lch":[65.7790257871148327,51.0903516363502916,226.227071697937646],"luv":[65.7790257871148327,-35.3444111183519212,-36.8916878581455236],"rgb":[0.333333333333333315,0.66666666666666663,0.8],"xyz":[0.290182478905092855,0.350390102524368363,0.62362699758947826],"hpluv":[226.227071697937646,98.5577501957325808,65.7790257871148327],"hsluv":[226.227071697937646,76.4624197891718,65.7790257871148327]},"#55aadd":{"lch":[66.4432499478878071,62.1650528283955595,236.084470311275709],"luv":[66.4432499478878071,-34.6862381636523693,-51.5883579425784404],"rgb":[0.333333333333333315,0.66666666666666663,0.866666666666666696],"xyz":[0.311700804455726455,0.358997432744621869,0.736956845489484258],"hpluv":[236.084470311275709,118.722973851074883,66.4432499478878071],"hsluv":[236.084470311275709,77.9227939155192928,66.4432499478878071]},"#55aaee":{"lch":[67.1660194476775274,74.4631251020179832,242.774049894046698],"luv":[67.1660194476775274,-34.0669326024190866,-66.2133000462974763],"rgb":[0.333333333333333315,0.66666666666666663,0.933333333333333348],"xyz":[0.335512984721901164,0.368522304851091886,0.862367661558007481],"hpluv":[242.774049894046698,140.679551339708695,67.1660194476775274],"hsluv":[242.774049894046698,80.7550915423080085,67.1660194476775274]},"#55aaff":{"lch":[67.9461628502375135,87.3278464079016,247.446578213330071],"luv":[67.9461628502375135,-33.4941307575646476,-80.6492155140842897],"rgb":[0.333333333333333315,0.66666666666666663,1],"xyz":[0.361684033131732585,0.37899072421502461,1.00020184984978933],"hpluv":[247.446578213330071,163.089927997179217,67.9461628502375135],"hsluv":[247.446578213330071,99.9999999999981,67.9461628502375135]},"#002200":{"lch":[10.1376941245203973,15.6902558355344119,127.715012949240474],"luv":[10.1376941245203973,-9.59826829561359141,12.4119850914324186],"rgb":[0,0.133333333333333331,0],"xyz":[0.00572002399569634425,0.0114400479913928481,0.00190667466523206119],"hpluv":[127.715012949240474,196.394882900214583,10.1376941245203973],"hsluv":[127.715012949240474,100.000000000002331,10.1376941245203973]},"#002211":{"lch":[10.4423176349325608,11.2803579121031614,143.951720967420982],"luv":[10.4423176349325608,-9.12041102953238614,6.63811549142769763],"rgb":[0,0.133333333333333331,0.0666666666666666657],"xyz":[0.00673168949533346599,0.0118447141912477027,0.00723477962998769243],"hpluv":[143.951720967420982,137.077225818420459,10.4423176349325608],"hsluv":[143.951720967420982,99.9999999999911,10.4423176349325608]},"#002222":{"lch":[10.9891417742670896,8.69416226881610399,192.17705063006116],"luv":[10.9891417742670896,-8.49854762011842,-1.83388819318003415],"rgb":[0,0.133333333333333331,0.133333333333333331],"xyz":[0.00860704763381048461,0.0125948574466385205,0.0171116658259668902],"hpluv":[192.17705063006116,100.392967527320849,10.9891417742670896],"hsluv":[192.17705063006116,99.9999999999915,10.9891417742670896]},"#002233":{"lch":[11.8439988341371283,14.4341695325786503,236.81663495428262],"luv":[11.8439988341371283,-7.90011340243738758,-12.0802921456333543],"rgb":[0,0.133333333333333331,0.2],"xyz":[0.0116947983662682251,0.0138299577396216334,0.0333738196835780335],"hpluv":[236.81663495428262,154.643892414528665,11.8439988341371283],"hsluv":[236.81663495428262,99.9999999999918572,11.8439988341371283]},"#002244":{"lch":[12.9926705590666103,23.9154033254141893,251.756603241059679],"luv":[12.9926705590666103,-7.48682111947174356,-22.713300635140282],"rgb":[0,0.133333333333333331,0.266666666666666663],"xyz":[0.0161527936104871039,0.0156131558373092099,0.056852594636464672],"hpluv":[251.756603241059679,233.570832873869165,12.9926705590666103],"hsluv":[251.756603241059679,99.9999999999922551,12.9926705590666103]},"#002255":{"lch":[14.3995425627967926,34.0053227001087492,257.612107564284656],"luv":[14.3995425627967926,-7.29512566501762105,-33.2135983216232162],"rgb":[0,0.133333333333333331,0.333333333333333315],"xyz":[0.022115207649849096,0.0179981214530540411,0.0882546419104385804],"hpluv":[257.612107564284656,299.666041626864057,14.3995425627967926],"hsluv":[257.612107564284656,99.9999999999922551,14.3995425627967926]},"#002266":{"lch":[16.0198287291043684,44.1221041927951489,260.479541157990241],"luv":[16.0198287291043684,-7.29778599254304705,-43.514392998258792],"rgb":[0,0.133333333333333331,0.4],"xyz":[0.0297002034233572743,0.0210321197624573561,0.128202286317582542],"hpluv":[260.479541157990241,349.492349810916096,16.0198287291043684],"hsluv":[260.479541157990241,99.9999999999926672,16.0198287291043684]},"#002277":{"lch":[17.8086814865908138,54.1839210795750787,262.094384047744654],"luv":[17.8086814865908138,-7.45254493353373,-53.6689563674502708],"rgb":[0,0.133333333333333331,0.466666666666666674],"xyz":[0.0390142164435591868,0.0247577249705381724,0.177256088223980451],"hpluv":[262.094384047744654,386.080609388904179,17.8086814865908138],"hsluv":[262.094384047744654,99.9999999999926246,17.8086814865908138]},"#002288":{"lch":[19.7262797638069571,64.1945165648047862,263.091662768615947],"luv":[19.7262797638069571,-7.7213996360385595,-63.7284547486409778],"rgb":[0,0.133333333333333331,0.533333333333333326],"xyz":[0.0501546335455030148,0.0292138918113157633,0.235928951627552619],"hpluv":[263.091662768615947,412.944865974292611,19.7262797638069571],"hsluv":[263.091662768615947,99.9999999999928093,19.7262797638069571]},"#002299":{"lch":[21.7396965211461932,74.1610579713059082,263.749129578079874],"luv":[21.7396965211461932,-8.0748025544340809,-73.7201470639492129],"rgb":[0,0.133333333333333331,0.6],"xyz":[0.0632115976545757352,0.0344366774549449278,0.304695629268670554],"hpluv":[263.749129578079874,432.874263951475,21.7396965211461932],"hsluv":[263.749129578079874,99.9999999999928662,21.7396965211461932]},"#0022aa":{"lch":[23.8228560713303921,84.0831956926279389,264.204285416148139],"luv":[23.8228560713303921,-8.49087961251211532,-83.6533846373868641],"rgb":[0,0.133333333333333331,0.66666666666666663],"xyz":[0.0782692906198282773,0.0404597546410460224,0.383999478885669154],"hpluv":[264.204285416148139,447.872821658188343,23.8228560713303921],"hsluv":[264.204285416148139,99.9999999999925251,23.8228560713303921]},"#0022bb":{"lch":[25.9556350824861326,93.9557715434331868,264.531619021467236],"luv":[25.9556350824861326,-8.95364890679069,-93.5281731756572725],"rgb":[0,0.133333333333333331,0.733333333333333282],"xyz":[0.0954068827271649239,0.0473147914839807809,0.474257463984310901],"hpluv":[264.531619021467236,459.336683180505304,25.9556350824861326],"hsluv":[264.531619021467236,99.9999999999932783,25.9556350824861326]},"#0022cc":{"lch":[28.122733334265547,103.772183036952711,264.774345627526145],"luv":[28.122733334265547,-9.45141286238599143,-103.340876555018355],"rgb":[0,0.133333333333333331,0.8],"xyz":[0.114699258170886664,0.0550317416614695826,0.575863974654581057],"hpluv":[264.774345627526145,468.233789407088068,28.122733334265547],"hsluv":[264.774345627526145,99.9999999999932,28.122733334265547]},"#0022dd":{"lch":[30.3126112219004114,113.526334495176528,264.958927468127968],"luv":[30.3126112219004114,-9.97554123069502552,-113.087210599012522],"rgb":[0,0.133333333333333331,0.866666666666666696],"xyz":[0.136217583721520208,0.0636390718817231166,0.689193822554587],"hpluv":[264.958927468127968,475.239568383116307,30.3126112219004114],"hsluv":[264.958927468127968,99.9999999999930651,30.3126112219004114]},"#0022ee":{"lch":[32.516600051948771,123.213441320075319,265.102292473050682],"luv":[32.516600051948771,-10.519601137712538,-122.76355368691101],"rgb":[0,0.133333333333333331,0.933333333333333348],"xyz":[0.160029763987694945,0.0731639439881931475,0.814604638623110278],"hpluv":[265.102292473050682,480.830806343612153,32.516600051948771],"hsluv":[265.102292473050682,99.9999999999931504,32.516600051948771]},"#0022ff":{"lch":[34.728199222084136,132.830192238289243,265.215668718406278],"luv":[34.728199222084136,-11.0787458291525667,-132.367372720447662],"rgb":[0,0.133333333333333331,1],"xyz":[0.186200812397526339,0.0836323633521258575,0.952438826914892123],"hpluv":[265.215668718406278,485.348691920142073,34.728199222084136],"hsluv":[265.215668718406278,99.9999999999995595,34.728199222084136]},"#55bb00":{"lch":[67.6287132051522093,94.1564927152114421,120.799924159261636],"luv":[67.6287132051522093,-48.2120532219748839,80.8767150949587403],"rgb":[0.333333333333333315,0.733333333333333282,0],"xyz":[0.215157742638501348,0.374707404671490163,0.0609878635696619598],"hpluv":[120.799924159261636,176.668237076728246,67.6287132051522093],"hsluv":[120.799924159261636,100.000000000002245,67.6287132051522093]},"#55bb11":{"lch":[67.658807387059241,92.983820197622,121.168613223743336],"luv":[67.658807387059241,-48.1245535730997,79.5614112615755],"rgb":[0.333333333333333315,0.733333333333333282,0.0666666666666666657],"xyz":[0.21616940813813848,0.375112070871345,0.0663159685344176],"hpluv":[121.168613223743336,174.390319462510746,67.658807387059241],"hsluv":[121.168613223743336,98.2170484527892853,67.658807387059241]},"#55bb22":{"lch":[67.7145367797011,90.8418307914021739,121.8702408444057],"luv":[67.7145367797011,-47.9642424389893733,77.1470651987980318],"rgb":[0.333333333333333315,0.733333333333333282,0.133333333333333331],"xyz":[0.218044766276615481,0.375862214126735816,0.076192854730396789],"hpluv":[121.8702408444057,170.232819736279453,67.7145367797011],"hsluv":[121.8702408444057,94.9476871157098401,67.7145367797011]},"#55bb33":{"lch":[67.8061331119394595,87.4049119918652337,123.079288563119889],"luv":[67.8061331119394595,-47.7055226907732077,73.2379802090816128],"rgb":[0.333333333333333315,0.733333333333333282,0.2],"xyz":[0.221132517009073215,0.377097314419718943,0.0924550085880079253],"hpluv":[123.079288563119889,163.570954697809668,67.8061331119394595],"hsluv":[123.079288563119889,89.6636954368763526,67.8061331119394595]},"#55bb44":{"lch":[67.9380247917114701,82.6396215824211851,124.951716096499126],"luv":[67.9380247917114701,-47.3430758547011195,67.7343356349037293],"rgb":[0.333333333333333315,0.733333333333333282,0.266666666666666663],"xyz":[0.225590512253292103,0.378880512517406509,0.115933783540894564],"hpluv":[124.951716096499126,154.352877500253584,67.9380247917114701],"hsluv":[124.951716096499126,82.2446152582935213,67.9380247917114701]},"#55bb55":{"lch":[68.1137800414251,76.6309713561306154,127.715012949239735],"luv":[68.1137800414251,-46.8777966745344372,60.6199467990950964],"rgb":[0.333333333333333315,0.733333333333333282,0.333333333333333315],"xyz":[0.231552926292654115,0.38126547813315137,0.147335830814868479],"hpluv":[127.715012949239735,142.760701907139094,68.1137800414251],"hsluv":[127.715012949239735,72.6906423420812189,68.1137800414251]},"#55bb66":{"lch":[68.3363083667640723,69.6002362161904813,131.717534816394789],"luv":[68.3363083667640723,-46.3160914021311,51.9520216986687728],"rgb":[0.333333333333333315,0.733333333333333282,0.4],"xyz":[0.239137922066162273,0.384299476442554688,0.187283475222012441],"hpluv":[131.717534816394789,129.240469264566769,68.3363083667640723],"hsluv":[131.717534816394789,73.4099839145656432,68.3363083667640723]},"#55bb77":{"lch":[68.6079661831172416,61.943926665161591,137.498849513297245],"luv":[68.6079661831172416,-45.6690129611091,41.8496273084595956],"rgb":[0.333333333333333315,0.733333333333333282,0.466666666666666674],"xyz":[0.248451935086364206,0.388025081650635484,0.23633727712841035],"hpluv":[137.498849513297245,114.568047908441656,68.6079661831172416],"hsluv":[137.498849513297245,74.2430874467708719,68.6079661831172416]},"#55bb88":{"lch":[68.930619778887035,54.3103726013937376,145.860320527647957],"luv":[68.930619778887035,-44.9511677919681389,30.4796503628330058],"rgb":[0.333333333333333315,0.733333333333333282,0.533333333333333326],"xyz":[0.259592352188308,0.392481248491413082,0.29501014053198249],"hpluv":[145.860320527647957,99.9792617157038421,68.930619778887035],"hsluv":[145.860320527647957,75.173468866550067,68.930619778887035]},"#55bb99":{"lch":[69.3056876145919176,47.7211055743842465,157.786981113384826],"luv":[69.3056876145919176,-44.1794697421466793,18.0410191104680564],"rgb":[0.333333333333333315,0.733333333333333282,0.6],"xyz":[0.272649316297380762,0.397704034135042239,0.363776818173100425],"hpluv":[157.786981113384826,87.3737441175344713,69.3056876145919176],"hsluv":[157.786981113384826,76.1818306173187807,69.3056876145919176]},"#55bbaa":{"lch":[69.7341725511637378,43.6310575063277497,173.751690425302456],"luv":[69.7341725511637378,-43.37186937951342,4.74869725787034813],"rgb":[0.333333333333333315,0.733333333333333282,0.66666666666666663],"xyz":[0.287707009262633262,0.403727111321143362,0.443080667790099],"hpluv":[173.751690425302456,79.3943164161001675,69.7341725511637378],"hsluv":[173.751690425302456,77.247554342351421,69.7341725511637378]},"#55bbbb":{"lch":[70.2166895771587605,43.5254926875218899,192.177050630061075],"luv":[70.2166895771587605,-42.5461891389785691,-9.18097508120914796],"rgb":[0.333333333333333315,0.733333333333333282,0.733333333333333282],"xyz":[0.304844601369969936,0.41058214816407812,0.533338652888740716],"hpluv":[192.177050630061075,78.6579587560082274,70.2166895771587605],"hsluv":[192.177050630061075,78.350068429440185,70.2166895771587605]},"#55bbcc":{"lch":[70.753492069254392,47.9033609117661214,209.436295084806801],"luv":[70.753492069254392,-41.719164640327179,-23.5423721905035848],"rgb":[0.333333333333333315,0.733333333333333282,0.8],"xyz":[0.324136976813691691,0.418299098341566922,0.634945163559010872],"hpluv":[209.436295084806801,85.9127126132272849,70.753492069254392],"hsluv":[209.436295084806801,79.4699741443966445,70.753492069254392]},"#55bbdd":{"lch":[71.3444981992470701,55.9344204047748121,223.003151043067675],"luv":[71.3444981992470701,-40.905747403701568,-38.1494327004039633],"rgb":[0.333333333333333315,0.733333333333333282,0.866666666666666696],"xyz":[0.345655302364325179,0.426906428561820428,0.74827501145901687],"hpluv":[223.003151043067675,99.4850863142100081,71.3444981992470701],"hsluv":[223.003151043067675,80.5898663629362,71.3444981992470701]},"#55bbee":{"lch":[71.9893182406489,66.3452770137575385,232.793079173014576],"luv":[71.9893182406489,-40.1186787976363846,-52.8411524624918272],"rgb":[0.333333333333333315,0.733333333333333282,0.933333333333333348],"xyz":[0.369467482630499944,0.436431300668290445,0.873685827527540093],"hpluv":[232.793079173014576,116.944897502912525,71.9893182406489],"hsluv":[232.793079173014576,81.6948376758296888,71.9893182406489]},"#55bbff":{"lch":[72.6872829834048417,78.1278426582451146,239.741904567598624],"luv":[72.6872829834048417,-39.3683093588317803,-67.4840426816504788],"rgb":[0.333333333333333315,0.733333333333333282,1],"xyz":[0.395638531040331309,0.446899720032223169,1.01152001581932205],"hpluv":[239.741904567598624,136.39131713467242,72.6872829834048417],"hsluv":[239.741904567598624,99.9999999999976126,72.6872829834048417]},"#003300":{"lch":[17.3086983277836381,26.7889227675687067,127.71501294924046],"luv":[17.3086983277836381,-16.3877039844862402,21.1917328494772867],"rgb":[0,0.2,0],"xyz":[0.0118377460847071559,0.0236754921694146449,0.00394591536156894181],"hpluv":[127.71501294924046,196.394882900214611,17.3086983277836381],"hsluv":[127.71501294924046,100.000000000002402,17.3086983277836381]},"#003311":{"lch":[17.4974002223845133,22.6621201022865968,134.58430385811792],"luv":[17.4974002223845133,-15.9078557679049606,16.1403783226414816],"rgb":[0,0.2,0.0666666666666666657],"xyz":[0.0128494115843442776,0.0240801583692694977,0.00927402032632457241],"hpluv":[134.58430385811792,164.348724425256108,17.4974002223845133],"hsluv":[134.58430385811792,99.9999999999909335,17.4974002223845133]},"#003322":{"lch":[17.8416856931397234,17.1190432019509622,152.323942273369369],"luv":[17.8416856931397234,-15.1604156821769873,7.95131665159082601],"rgb":[0,0.2,0.133333333333333331],"xyz":[0.0147247697228212963,0.0248303016246603156,0.0191509065223037685],"hpluv":[152.323942273369369,121.753913655152402,17.8416856931397234],"hsluv":[152.323942273369369,99.9999999999912177,17.8416856931397234]},"#003333":{"lch":[18.3937448040413543,14.5523831926532932,192.17705063006116],"luv":[18.3937448040413543,-14.2249612699966086,-3.06958196712752551],"rgb":[0,0.2,0.2],"xyz":[0.017812520455279035,0.0260654019176434319,0.0354130603799149152],"hpluv":[192.17705063006116,100.392967527320849,18.3937448040413543],"hsluv":[192.17705063006116,99.9999999999915,18.3937448040413543]},"#003344":{"lch":[19.1608294605123817,20.3566459399555,229.223567805483242],"luv":[19.1608294605123817,-13.2951121246929258,-15.41535038578591],"rgb":[0,0.2,0.266666666666666663],"xyz":[0.0222705156994979156,0.0278486000153310084,0.0588918353328015537],"hpluv":[229.223567805483242,134.812835768594709,19.1608294605123817],"hsluv":[229.223567805483242,99.9999999999917577,19.1608294605123817]},"#003355":{"lch":[20.1371955335767296,30.6237106081975696,245.893961784182551],"luv":[20.1371955335767296,-12.5075398018694361,-27.9530517031554915],"rgb":[0,0.2,0.333333333333333315],"xyz":[0.0282329297388599076,0.0302335656310758379,0.0902938826067754552],"hpluv":[245.893961784182551,192.973712242731381,20.1371955335767296],"hsluv":[245.893961784182551,99.9999999999920419,20.1371955335767296]},"#003366":{"lch":[21.3076868402923836,41.8514919359335167,253.451236278131262],"luv":[21.3076868402923836,-11.9206140697212764,-40.1179054471226308],"rgb":[0,0.2,0.4],"xyz":[0.0358179255123680859,0.0332675639404791529,0.130241527013919417],"hpluv":[253.451236278131262,249.237832456686277,21.3076868402923836],"hsluv":[253.451236278131262,99.9999999999920846,21.3076868402923836]},"#003377":{"lch":[22.6513946103128916,53.0186284648852251,257.430711853641924],"luv":[22.6513946103128916,-11.5379190314963687,-51.7479602372902434],"rgb":[0,0.2,0.466666666666666674],"xyz":[0.04513193853257,0.0369931691485599692,0.179295328920317326],"hpluv":[257.430711853641924,297.011229333042763,22.6513946103128916],"hsluv":[257.430711853641924,99.9999999999922409,22.6513946103128916]},"#003388":{"lch":[24.1449124481648099,63.8887963004775941,259.778872090702237],"luv":[24.1449124481648099,-11.3369168899634012,-62.8748964862287636],"rgb":[0,0.2,0.533333333333333326],"xyz":[0.0562723556345138265,0.0414493359893375601,0.237968192323889494],"hpluv":[259.778872090702237,335.767299249073346,24.1449124481648099],"hsluv":[259.778872090702237,99.9999999999925677,24.1449124481648099]},"#003399":{"lch":[25.764809398314533,74.4520642325545481,261.279947020055374],"luv":[25.764809398314533,-11.2874373109462987,-73.5914643653724596],"rgb":[0,0.2,0.6],"xyz":[0.0693293197435865399,0.0466721216329667177,0.306734869965007428],"hpluv":[261.279947020055374,366.681615332004242,25.764809398314533],"hsluv":[261.279947020055374,99.9999999999928662,25.764809398314533]},"#0033aa":{"lch":[27.4892253326185596,84.7561178753388447,262.297068677869788],"luv":[27.4892253326185596,-11.360446037840406,-83.9913077831251],"rgb":[0,0.2,0.66666666666666663],"xyz":[0.084387012708839082,0.0526951988190678261,0.386038719582006029],"hpluv":[262.297068677869788,391.244172205097584,27.4892253326185596],"hsluv":[262.297068677869788,99.9999999999925819,27.4892253326185596]},"#0033bb":{"lch":[29.2987082140811808,94.8530383242648725,263.01737082090068],"luv":[29.2987082140811808,-11.531133966499155,-94.1495184734957178],"rgb":[0,0.2,0.733333333333333282],"xyz":[0.101524604816175729,0.0595502356620025847,0.476296704680647776],"hpluv":[263.01737082090068,410.811034734971429,29.2987082140811808],"hsluv":[263.01737082090068,99.999999999992923,29.2987082140811808]},"#0033cc":{"lch":[31.1765026722858281,104.784892642773883,263.545454640352943],"luv":[31.1765026722858281,-11.7793879173059235,-104.120697973319764],"rgb":[0,0.2,0.8],"xyz":[0.120816980259897469,0.0672671858394913863,0.577903215350917931],"hpluv":[263.545454640352943,426.491720029659064,31.1765026722858281],"hsluv":[263.545454640352943,99.9999999999928519,31.1765026722858281]},"#0033dd":{"lch":[33.108496036114694,114.582250296133722,263.943596884481394],"luv":[33.108496036114694,-12.0892798728815123,-113.942711022166648],"rgb":[0,0.2,0.866666666666666696],"xyz":[0.142335305810531026,0.0758745160597449203,0.691233063250923929],"hpluv":[263.943596884481394,439.154381827523366,33.108496036114694],"hsluv":[263.943596884481394,99.999999999992724,33.108496036114694]},"#0033ee":{"lch":[35.0829820911796091,124.266344101148519,264.250786122927309],"luv":[35.0829820911796091,-12.4483077284590724,-123.641271066592637],"rgb":[0,0.2,0.933333333333333348],"xyz":[0.166147486076705764,0.0853993881662149512,0.816643879319447152],"hpluv":[264.250786122927309,449.46548401365061,35.0829820911796091],"hsluv":[264.250786122927309,99.9999999999932214,35.0829820911796091]},"#0033ff":{"lch":[37.0903499028545482,133.851694130242549,264.492451291459133],"luv":[37.0903499028545482,-12.8466699872586325,-133.233776092154926],"rgb":[0,0.2,1],"xyz":[0.192318534486537157,0.0958678075301476473,0.954478067611229],"hpluv":[264.492451291459133,457.933345064777,37.0903499028545482],"hsluv":[264.492451291459133,99.999999999999531,37.0903499028545482]},"#55cc00":{"lch":[72.9678739916599,103.392643433537373,122.072672834653702],"luv":[72.9678739916599,-54.9009234662034089,87.6123696673744661],"rgb":[0.333333333333333315,0.8,0],"xyz":[0.253381485948118268,0.451154891290725057,0.0737291113395339148],"hpluv":[122.072672834653702,179.803140433373983,72.9678739916599],"hsluv":[122.072672834653702,100.000000000002444,72.9678739916599]},"#55cc11":{"lch":[72.9944661394807497,102.34674561848017,122.382691003133885],"luv":[72.9944661394807497,-54.8140205324080085,86.4307786136781431],"rgb":[0.333333333333333315,0.8,0.0666666666666666657],"xyz":[0.254393151447755372,0.45155955749057991,0.0790572163042895515],"hpluv":[122.382691003133885,177.91945009175069,72.9944661394807497],"hsluv":[122.382691003133885,98.5172338886757757,72.9944661394807497]},"#55cc22":{"lch":[73.0437189009647909,100.431941691916791,122.969611448584445],"luv":[73.0437189009647909,-54.6544745496639663,84.2583130836875114],"rgb":[0.333333333333333315,0.8,0.133333333333333331],"xyz":[0.256268509586232429,0.452309700745970711,0.0889341025002687441],"hpluv":[122.969611448584445,174.473032354427772,73.0437189009647909],"hsluv":[122.969611448584445,95.7933392549395,73.0437189009647909]},"#55cc33":{"lch":[73.1246943704287702,97.3470237033586,123.971835615120114],"luv":[73.1246943704287702,-54.3960871275936384,80.7310889875115123],"rgb":[0.333333333333333315,0.8,0.2],"xyz":[0.259356260318690135,0.453544801038953838,0.10519625635787988],"hpluv":[123.971835615120114,168.926560877595364,73.1246943704287702],"hsluv":[123.971835615120114,91.3772697810403542,73.1246943704287702]},"#55cc44":{"lch":[73.2413452172043,93.0415252478239836,125.502056943833935],"luv":[73.2413452172043,-54.0322080150887771,75.7446098244333399],"rgb":[0.333333333333333315,0.8,0.266666666666666663],"xyz":[0.26381425556290905,0.455327999136641404,0.128675031310766519],"hpluv":[125.502056943833935,161.198069131808353,73.2413452172043],"hsluv":[125.502056943833935,85.148140842768953,73.2413452172043]},"#55cc55":{"lch":[73.3968865779486919,87.5572640326508207,127.71501294923992],"luv":[73.3968865779486919,-53.5617851120033066,69.2633356148757144],"rgb":[0.333333333333333315,0.8,0.333333333333333315],"xyz":[0.269776669602271035,0.457712964752386264,0.160077078584740434],"hpluv":[127.71501294923992,151.374900584602614,73.3968865779486919],"hsluv":[127.71501294923992,77.0768048277098,73.3968865779486919]},"#55cc66":{"lch":[73.5939772793636,81.0375847478920832,130.834727778769576],"luv":[73.5939772793636,-52.9887999422805,61.3129449826769175],"rgb":[0.333333333333333315,0.8,0.4],"xyz":[0.277361665375779221,0.460746963061789583,0.200024722991884396],"hpluv":[130.834727778769576,139.728031568505,73.5939772793636],"hsluv":[130.834727778769576,77.5857883184082766,73.5939772793636]},"#55cc77":{"lch":[73.8348152761848553,73.7475179973278898,135.191797127350526],"luv":[73.8348152761848553,-52.3216404431773,51.972515352838883],"rgb":[0.333333333333333315,0.8,0.466666666666666674],"xyz":[0.286675678395981126,0.464472568269870378,0.249078524898282305],"hpluv":[135.191797127350526,126.743455190439619,73.8348152761848553],"hsluv":[135.191797127350526,78.1806978106980779,73.8348152761848553]},"#55cc88":{"lch":[74.1211942127210648,66.1117924559585646,141.267644806662588],"luv":[74.1211942127210648,-51.5723023085178269,41.3650424433311343],"rgb":[0.333333333333333315,0.8,0.533333333333333326],"xyz":[0.297816095497924926,0.468928735110648,0.307751388301854445],"hpluv":[141.267644806662588,113.181605649052202,74.1211942127210648],"hsluv":[141.267644806662588,78.852064841283763,74.1211942127210648]},"#55cc99":{"lch":[74.4545405069311,58.7794373107374923,149.710693018120253],"luv":[74.4545405069311,-50.7554383804248,29.646377947024483],"rgb":[0.333333333333333315,0.8,0.6],"xyz":[0.310873059606997626,0.474151520754277134,0.37651806594297238],"hpluv":[149.710693018120253,100.178278207809555,74.4545405069311],"hsluv":[149.710693018120253,79.5881732610030355,74.4545405069311]},"#55ccaa":{"lch":[74.8359403329188808,52.7021878309829361,161.189357777818884],"luv":[74.8359403329188808,-49.8873315971569866,16.9933736582089097],"rgb":[0.333333333333333315,0.8,0.66666666666666663],"xyz":[0.325930752572250182,0.480174597940378256,0.455821915559971],"hpluv":[161.189357777818884,89.3630022499163772,74.8359403329188808],"hsluv":[161.189357777818884,80.3759073289738097,74.8359403329188808]},"#55ccbb":{"lch":[75.2661614985634,49.1164256219739315,175.805780272408356],"luv":[75.2661614985634,-48.9848849956305372,3.59225665059547428],"rgb":[0.333333333333333315,0.8,0.733333333333333282],"xyz":[0.343068344679586856,0.487029634783313,0.546079900658612782],"hpluv":[175.805780272408356,82.8068592257523619,75.2661614985634],"hsluv":[175.805780272408356,81.2015846585734238,75.2661614985634]},"#55cccc":{"lch":[75.7456730324682894,49.1710405410584386,192.177050630061103],"luv":[75.7456730324682894,-48.0647147647340063,-10.3718090261618983],"rgb":[0.333333333333333315,0.8,0.8],"xyz":[0.362360720123308555,0.494746584960801816,0.647686411328882938],"hpluv":[192.177050630061103,82.3741405590198639,75.7456730324682894],"hsluv":[192.177050630061103,82.0517040066532815,75.7456730324682894]},"#55ccdd":{"lch":[76.2746640882933349,53.2320113470533514,207.674227909684788],"luv":[76.2746640882933349,-47.1424090239802069,-24.7232745296525458],"rgb":[0.333333333333333315,0.8,0.866666666666666696],"xyz":[0.383879045673942154,0.503353915181055322,0.761016259228888936],"hpluv":[207.674227909684788,89.8673986045394,76.2746640882933349],"hsluv":[207.674227909684788,82.913556803619926,76.2746640882933349]},"#55ccee":{"lch":[76.8530630513789674,60.6801737900983298,220.368363670310828],"luv":[76.8530630513789674,-46.2319850937693673,-39.3025068600722207],"rgb":[0.333333333333333315,0.8,0.933333333333333348],"xyz":[0.407691225940116864,0.51287878728752534,0.886427075297412159],"hpluv":[220.368363670310828,105.55411204702996,76.8530630513789674],"hsluv":[220.368363670310828,83.7756757275922865,76.8530630513789674]},"#55ccff":{"lch":[77.4805572724897758,70.4908339109135511,229.9629437526429],"luv":[77.4805572724897758,-45.3455492712466395,-53.9697955040126445],"rgb":[0.333333333333333315,0.8,1],"xyz":[0.433862274349948285,0.523347206651458063,1.02426126358919389],"hpluv":[229.9629437526429,126.754412601721029,77.4805572724897758],"hsluv":[229.9629437526429,99.9999999999968878,77.4805572724897758]},"#004400":{"lch":[24.1097877444294397,37.3150672336374782,127.715012949240432],"luv":[24.1097877444294397,-22.8269080205926969,29.5185791133361732],"rgb":[0,0.266666666666666663,0],"xyz":[0.0206703165676731908,0.0413406331353469575,0.00689010552255753684],"hpluv":[127.715012949240432,196.39488290021464,24.1097877444294397],"hsluv":[127.715012949240432,100.000000000002458,24.1097877444294397]},"#004411":{"lch":[24.2402356883412295,33.8624764720942082,131.447767669063751],"luv":[24.2402356883412295,-22.4148262696793807,25.3819399598065552],"rgb":[0,0.266666666666666663,0.0666666666666666657],"xyz":[0.0216819820673103125,0.0417452993352018104,0.0122182104873131692],"hpluv":[131.447767669063751,177.264269230781338,24.2402356883412295],"hsluv":[131.447767669063751,99.9999999999909335,24.2402356883412295]},"#004422":{"lch":[24.4798388415780295,28.4164365287723264,139.862893984056171],"luv":[24.4798388415780295,-21.7244820008415864,18.3177713379345413],"rgb":[0,0.266666666666666663,0.133333333333333331],"xyz":[0.0235573402057873311,0.0424954425905926317,0.0220950966832923652],"hpluv":[139.862893984056171,147.299199898382369,24.4798388415780295],"hsluv":[139.862893984056171,99.9999999999911466,24.4798388415780295]},"#004433":{"lch":[24.8682723444395748,22.2877633761795622,158.664607016269599],"luv":[24.8682723444395748,-20.760308528761005,8.10888316004269427],"rgb":[0,0.266666666666666663,0.2],"xyz":[0.0266450909382450717,0.0437305428835757445,0.0383572505409035119],"hpluv":[158.664607016269599,113.726114076625834,24.8682723444395748],"hsluv":[158.664607016269599,99.9999999999913172,24.8682723444395748]},"#004444":{"lch":[25.4163828994624552,20.1084089871091685,192.17705063006116],"luv":[25.4163828994624552,-19.6559790417892835,-4.24153273022775057],"rgb":[0,0.266666666666666663,0.266666666666666663],"xyz":[0.0311030861824639487,0.0455137409812633176,0.0618360254937901505],"hpluv":[192.17705063006116,100.392967527320792,25.4163828994624552],"hsluv":[192.17705063006116,99.9999999999914166,25.4163828994624552]},"#004455":{"lch":[26.1275223832094383,25.5944772375096541,223.546306053382096],"luv":[26.1275223832094383,-18.5513329588178841,-17.6330743352507042],"rgb":[0,0.266666666666666663,0.333333333333333315],"xyz":[0.0370655002218259477,0.0478987065970081505,0.093238072767764052],"hpluv":[223.546306053382096,124.304646155287358,26.1275223832094383],"hsluv":[223.546306053382096,99.999999999991644,26.1275223832094383]},"#004466":{"lch":[26.9988561724938734,35.8050932952910514,240.647496291889979],"luv":[26.9988561724938734,-17.5509899640931621,-31.2084516944496499],"rgb":[0,0.266666666666666663,0.4],"xyz":[0.0446504959953341191,0.050932704906411462,0.133185717174908],"hpluv":[240.647496291889979,168.282428552664811,26.9988561724938734],"hsluv":[240.647496291889979,99.9999999999920135,26.9988561724938734]},"#004477":{"lch":[28.0227048150185141,47.4927479988473422,249.396343090395135],"luv":[28.0227048150185141,-16.7127641209025413,-44.4549730392572684],"rgb":[0,0.266666666666666663,0.466666666666666674],"xyz":[0.0539645090155360385,0.0546583101144922784,0.182239519081305923],"hpluv":[249.396343090395135,215.05848085050232,28.0227048150185141],"hsluv":[249.396343090395135,99.9999999999921698,28.0227048150185141]},"#004488":{"lch":[29.1879465441319326,59.3592998069098,254.306666373838311],"luv":[29.1879465441319326,-16.0560040952153962,-57.1465765034181956],"rgb":[0,0.266666666666666663,0.533333333333333326],"xyz":[0.0651049261174798666,0.0591144769552698762,0.24091238248487809],"hpluv":[254.306666373838311,258.06229412425995,29.1879465441319326],"hsluv":[254.306666373838311,99.9999999999923,29.1879465441319326]},"#004499":{"lch":[30.4813623757938217,70.9684349502494,257.321762040288718],"luv":[30.4813623757938217,-15.5758442205369825,-69.2380808233832141],"rgb":[0,0.266666666666666663,0.6],"xyz":[0.07816189022655258,0.0643372625988990338,0.309679060125996],"hpluv":[257.321762040288718,295.440602563868879,30.4813623757938217],"hsluv":[257.321762040288718,99.9999999999926672,30.4813623757938217]},"#0044aa":{"lch":[31.8888011745219231,82.2033012029853,259.305022310013101],"luv":[31.8888011745219231,-15.2553283345918977,-80.7753532092093138],"rgb":[0,0.266666666666666663,0.66666666666666663],"xyz":[0.0932195831918051221,0.0703603397850001422,0.388982909742994598],"hpluv":[259.305022310013101,327.107417663034141,31.8888011745219231],"hsluv":[259.305022310013101,99.9999999999925109,31.8888011745219231]},"#0044bb":{"lch":[33.3960915948532602,93.0667571364503,260.679203518012741],"luv":[33.3960915948532602,-15.0732787327803415,-91.8379962332527],"rgb":[0,0.266666666666666663,0.733333333333333282],"xyz":[0.110357175299141769,0.0772153766279349,0.479240894841636345],"hpluv":[260.679203518012741,353.621176249907,33.3960915948532602],"hsluv":[260.679203518012741,99.9999999999929656,33.3960915948532602]},"#0044cc":{"lch":[34.9896851087579108,103.60206818965716,261.670396128603272],"luv":[34.9896851087579108,-15.0085679377548828,-102.509177255659253],"rgb":[0,0.266666666666666663,0.8],"xyz":[0.129649550742863495,0.0849323268054237,0.5808474055119065],"hpluv":[261.670396128603272,375.722944942957042,34.9896851087579108],"hsluv":[261.670396128603272,99.999999999992923,34.9896851087579108]},"#0044dd":{"lch":[36.6570567010139499,113.860579159150092,262.408492682931296],"luv":[36.6570567010139499,-15.0420602661110987,-112.862606338006245],"rgb":[0,0.266666666666666663,0.866666666666666696],"xyz":[0.151167876293497039,0.0935396570256772364,0.694177253411912498],"hpluv":[262.408492682931296,394.144185167595538,36.6570567010139499],"hsluv":[262.408492682931296,99.9999999999929088,36.6570567010139499]},"#0044ee":{"lch":[38.386911506645724,123.889384104134805,262.972536787865295],"luv":[38.386911506645724,-15.1572566165017264,-122.958680318078251],"rgb":[0,0.266666666666666663,0.933333333333333348],"xyz":[0.174980056559671776,0.103064529132147253,0.819588069480435721],"hpluv":[262.972536787865295,409.534269399062566,38.386911506645724],"hsluv":[262.972536787865295,99.9999999999931,38.386911506645724]},"#0044ff":{"lch":[40.1692504091911928,133.727629508879147,263.412926975584469],"luv":[40.1692504091911928,-15.3403008413028115,-132.844849595919101],"rgb":[0,0.266666666666666663,1],"xyz":[0.201151104969503169,0.113532948496079963,0.957422257772217566],"hpluv":[263.412926975584469,422.441664595501038,40.1692504091911928],"hsluv":[263.412926975584469,99.9999999999994174,40.1692504091911928]},"#55dd00":{"lch":[78.2526895057908121,112.425836873112019,123.034721453117925],"luv":[78.2526895057908121,-61.2886270790004488,94.2511166373683267],"rgb":[0.333333333333333315,0.866666666666666696,0],"xyz":[0.296015476495293473,0.536422872385076577,0.0879404415219252333],"hpluv":[123.034721453117925,210.800433631405241,78.2526895057908121],"hsluv":[123.034721453117925,100.000000000002288,78.2526895057908121]},"#55dd11":{"lch":[78.2763843013059102,111.485784004679431,123.297526334296066],"luv":[78.2763843013059102,-61.2042162992655108,93.1832814529020368],"rgb":[0.333333333333333315,0.866666666666666696,0.0666666666666666657],"xyz":[0.297027141994930577,0.536827538584931485,0.09326854648668087],"hpluv":[123.297526334296066,209.310421322213443,78.2763843013059102],"hsluv":[123.297526334296066,98.7516598856555561,78.2763843013059102]},"#55dd22":{"lch":[78.3202766586626353,109.761570808260174,123.793166282380056],"luv":[78.3202766586626353,-61.0490014413279738,91.2174426812846235],"rgb":[0.333333333333333315,0.866666666666666696,0.133333333333333331],"xyz":[0.298902500133407634,0.537577681840322286,0.103145432682660063],"hpluv":[123.793166282380056,206.571995072092733,78.3202766586626353],"hsluv":[123.793166282380056,96.4551350157602201,78.3202766586626353]},"#55dd33":{"lch":[78.3924559312840898,106.97461234521991,124.633900466047606],"luv":[78.3924559312840898,-60.7969536029841819,88.018737317724927],"rgb":[0.333333333333333315,0.866666666666666696,0.2],"xyz":[0.30199025086586534,0.538812782133305412,0.119407586540271199],"hpluv":[124.633900466047606,202.130538056106332,78.3924559312840898],"hsluv":[124.633900466047606,92.7228817840519355,78.3924559312840898]},"#55dd44":{"lch":[78.4964717161501255,103.064578059178857,125.904361390923313],"luv":[78.4964717161501255,-60.4405744101571756,83.4819993500804],"rgb":[0.333333333333333315,0.866666666666666696,0.266666666666666663],"xyz":[0.306448246110084255,0.540595980230993,0.142886361493157837],"hpluv":[125.904361390923313,195.867385876976442,78.4964717161501255],"hsluv":[125.904361390923313,87.4391970363123221,78.4964717161501255]},"#55dd55":{"lch":[78.635232286968062,98.0447483954765175,127.715012949239977],"luv":[78.635232286968062,-59.9773394353739,77.559599291037074],"rgb":[0.333333333333333315,0.866666666666666696,0.333333333333333315],"xyz":[0.31241066014944624,0.542980945846737728,0.174288408767131753],"hpluv":[127.715012949239977,187.771435495127037,78.635232286968062],"hsluv":[127.715012949239977,80.5594181605674891,78.635232286968062]},"#55dd66":{"lch":[78.8111684825228451,92.0067823672703469,130.218539636235505],"luv":[78.8111684825228451,-59.4092211255214551,70.2551951590567],"rgb":[0.333333333333333315,0.866666666666666696,0.4],"xyz":[0.319995655922954425,0.546014944156141,0.214236053174275715],"hpluv":[130.218539636235505,177.951388767985407,78.8111684825228451],"hsluv":[130.218539636235505,80.9267337864342693,78.8111684825228451]},"#55dd77":{"lch":[79.0263204832261863,85.1319563310668315,133.631202536406704],"luv":[79.0263204832261863,-58.7422260542947043,61.618186170487121],"rgb":[0.333333333333333315,0.866666666666666696,0.466666666666666674],"xyz":[0.329309668943156331,0.549740549364221898,0.263289855080673596],"hpluv":[133.631202536406704,166.66460441184762,79.0263204832261863],"hsluv":[133.631202536406704,81.3592233632428,79.0263204832261863]},"#55dd88":{"lch":[79.2823892178289,77.7115996221609322,138.259418470179128],"luv":[79.2823892178289,-57.9858175415186921,51.7371982221375],"rgb":[0.333333333333333315,0.866666666666666696,0.533333333333333326],"xyz":[0.340450086045100131,0.55419671620499944,0.321962718484245791],"hpluv":[138.259418470179128,154.371102046011828,79.2823892178289],"hsluv":[138.259418470179128,81.8514411788724,79.2823892178289]},"#55dd99":{"lch":[79.5807696492298504,70.1818875082800133,144.522564094970761],"luv":[79.5807696492298504,-57.1522092721799737,40.7323251181885624],"rgb":[0.333333333333333315,0.866666666666666696,0.6],"xyz":[0.353507050154172831,0.559419501848628653,0.390729396125363726],"hpluv":[144.522564094970761,141.828030979619143,79.5807696492298504],"hsluv":[144.522564094970761,82.3962440946128538,79.5807696492298504]},"#55ddaa":{"lch":[79.9225742847085,63.1747442044720913,152.933070337002903],"luv":[79.9225742847085,-56.2555676549498145,28.7464678372812266],"rgb":[0.333333333333333315,0.866666666666666696,0.66666666666666663],"xyz":[0.368564743119425386,0.56544257903472972,0.470033245742362271],"hpluv":[152.933070337002903,130.236824512138128,79.9225742847085],"hsluv":[152.933070337002903,82.9852754707380313,79.9225742847085]},"#55ddbb":{"lch":[80.3086513857730466,57.5612329714098649,163.927126105934775],"luv":[80.3086513857730466,-55.3111838467604926,15.9363886328987263],"rgb":[0.333333333333333315,0.866666666666666696,0.733333333333333282],"xyz":[0.385702335226762061,0.572297615877664478,0.560291230841004073],"hpluv":[163.927126105934775,121.406580229851471,80.3086513857730466],"hsluv":[163.927126105934775,83.6094665313934,80.3086513857730466]},"#55ddcc":{"lch":[80.7396004409482657,54.3905283694756534,177.403333860877041],"luv":[80.7396004409482657,-54.3346805898883076,2.46415533308082235],"rgb":[0.333333333333333315,0.866666666666666696,0.8],"xyz":[0.40499471067048376,0.580014566055153336,0.661897741511274229],"hpluv":[177.403333860877041,117.73427745544555,80.7396004409482657],"hsluv":[177.403333860877041,84.2595162876674664,80.7396004409482657]},"#55dddd":{"lch":[81.2157864208401605,54.5690893966631236,192.177050630061103],"luv":[81.2157864208401605,-53.3413100060750764,-11.5104371948595805],"rgb":[0.333333333333333315,0.866666666666666696,0.866666666666666696],"xyz":[0.426513036221117359,0.588621896275406842,0.775227589411280227],"hpluv":[192.177050630061103,121.625211000731653,81.2157864208401605],"hsluv":[192.177050630061103,84.9263164151063847,81.2157864208401605]},"#55ddee":{"lch":[81.73735371635685,58.3741450028570412,206.269517439458],"luv":[81.73735371635685,-52.3453816136692609,-25.8360567528002605],"rgb":[0.333333333333333315,0.866666666666666696,0.933333333333333348],"xyz":[0.450325216487292068,0.598146768381876859,0.90063840547980345],"hpluv":[206.269517439458,134.436687270459231,81.73735371635685],"hsluv":[206.269517439458,85.6012975649288421,81.73735371635685]},"#55ddff":{"lch":[82.3042402700550753,65.3293790133507599,218.171205050819623],"luv":[82.3042402700550753,-51.3598401525014268,-40.374429801293],"rgb":[0.333333333333333315,0.866666666666666696,1],"xyz":[0.476496264897123489,0.608615187745809583,1.0384725937715853],"hpluv":[218.171205050819623,156.046773818868189,82.3042402700550753],"hsluv":[218.171205050819623,99.9999999999958078,82.3042402700550753]},"#005500":{"lch":[30.6325595368381371,47.4104554868850059,127.715012949240474],"luv":[30.6325595368381371,-29.0026036892131067,37.5046699588244152],"rgb":[0,0.333333333333333315,0],"xyz":[0.0324835732820191528,0.0649671465640392215,0.0108278577606727468],"hpluv":[127.715012949240474,196.39488290021464,30.6325595368381371],"hsluv":[127.715012949240474,100.000000000002331,30.6325595368381371]},"#005511":{"lch":[30.7291805540017933,44.5531719728198325,130.030983014983661],"luv":[30.7291805540017933,-28.6566785608310113,34.1142185415534129],"rgb":[0,0.333333333333333315,0.0666666666666666657],"xyz":[0.033495238781656278,0.0653718127638940744,0.01615596272542838],"hpluv":[130.030983014983661,183.978458821492183,30.7291805540017933],"hsluv":[130.030983014983661,99.9999999999909335,30.7291805540017933]},"#005522":{"lch":[30.9072407208055395,39.7502752239143149,134.89425658266407],"luv":[30.9072407208055395,-28.0557665948475297,28.1595159964153758],"rgb":[0,0.333333333333333315,0.133333333333333331],"xyz":[0.0353705969201332932,0.0661219560192848888,0.0260328489214075726],"hpluv":[134.89425658266407,163.199653312489744,30.9072407208055395],"hsluv":[134.89425658266407,99.9999999999909903,30.9072407208055395]},"#005533":{"lch":[31.1975029455576802,33.2574057268159,144.773587953954916],"luv":[31.1975029455576802,-27.1672793055155033,19.1831689460880241],"rgb":[0,0.333333333333333315,0.2],"xyz":[0.0384583476525910337,0.067357056312268,0.0422950027790187227],"hpluv":[144.773587953954916,135.271984326190278,31.1975029455576802],"hsluv":[144.773587953954916,99.9999999999912177,31.1975029455576802]},"#005544":{"lch":[31.6103799108948778,27.1932751339722678,163.464109831123295],"luv":[31.6103799108948778,-26.0686058468900157,7.73963834500076331],"rgb":[0,0.333333333333333315,0.266666666666666663],"xyz":[0.0429163428968099142,0.0691402544099555816,0.0657737777319053613],"hpluv":[163.464109831123295,109.16191048912313,31.6103799108948778],"hsluv":[163.464109831123295,99.999999999991374,31.6103799108948778]},"#005555":{"lch":[32.1516370434520482,25.4370682812028797,192.17705063006116],"luv":[32.1516370434520482,-24.8647459548099441,-5.36552433088697445],"rgb":[0,0.333333333333333315,0.333333333333333315],"xyz":[0.0488787569361719063,0.0715252200257004145,0.0971758250058792628],"hpluv":[192.17705063006116,100.392967527320877,32.1516370434520482],"hsluv":[192.17705063006116,99.9999999999915,32.1516370434520482]},"#005566":{"lch":[32.8230722751799036,30.545644410021449,219.238547792689275],"luv":[32.8230722751799036,-23.6581848019048806,-19.3216636007977201],"rgb":[0,0.333333333333333315,0.4],"xyz":[0.0564637527096800845,0.074559218335103733,0.137123469413023225],"hpluv":[219.238547792689275,118.088984839520307,32.8230722751799036],"hsluv":[219.238547792689275,99.9999999999916298,32.8230722751799036]},"#005577":{"lch":[33.6230950493472065,40.3511971197610322,236.060106868306946],"luv":[33.6230950493472065,-22.5289967279924532,-33.4763112577822142],"rgb":[0,0.333333333333333315,0.466666666666666674],"xyz":[0.065777765729882,0.0782848235431845424,0.186177271319421134],"hpluv":[236.060106868306946,152.285327594300298,33.6230950493472065],"hsluv":[236.060106868306946,99.9999999999918,33.6230950493472065]},"#005588":{"lch":[34.5473308406039266,52.0529464564925703,245.569923252468897],"luv":[34.5473308406039266,-21.5281838547339461,-47.3924733973576764],"rgb":[0,0.333333333333333315,0.533333333333333326],"xyz":[0.076918182831825832,0.0827409903839621402,0.244850134722993301],"hpluv":[245.569923252468897,191.192188881903292,34.5473308406039266],"hsluv":[245.569923252468897,99.9999999999919709,34.5473308406039266]},"#005599":{"lch":[35.5892574919693772,64.2489447401961655,251.22324643469841],"luv":[35.5892574919693772,-20.6805523421639172,-60.8296116628390067],"rgb":[0,0.333333333333333315,0.6],"xyz":[0.0899751469408985316,0.0879637760275913,0.313616812364111208],"hpluv":[251.22324643469841,229.079590546614583,35.5892574919693772],"hsluv":[251.22324643469841,99.9999999999922125,35.5892574919693772]},"#0055aa":{"lch":[36.7408379507026,76.3552968047486189,254.821646708521541],"luv":[36.7408379507026,-19.9916927982920107,-73.6916791042243347],"rgb":[0,0.333333333333333315,0.66666666666666663],"xyz":[0.105032839906151088,0.0939868532136924,0.392920661981109809],"hpluv":[254.821646708521541,263.711724718685957,36.7408379507026],"hsluv":[254.821646708521541,99.9999999999921556,36.7408379507026]},"#0055bb":{"lch":[37.993106438468665,88.146943006458784,257.249085911334646],"luv":[37.993106438468665,-19.4551758320548949,-85.9731335635018],"rgb":[0,0.333333333333333315,0.733333333333333282],"xyz":[0.122170432013487734,0.100841890056627165,0.483178647079751555],"hpluv":[257.249085911334646,294.402692429224658,37.993106438468665],"hsluv":[257.249085911334646,99.9999999999924114,37.993106438468665]},"#0055cc":{"lch":[39.3366742314503384,99.5579220492412,258.963845190076711],"luv":[39.3366742314503384,-19.0582121518786707,-97.7167559446012888],"rgb":[0,0.333333333333333315,0.8],"xyz":[0.141462807457209461,0.108558840234115966,0.584785157750021711],"hpluv":[258.963845190076711,321.157087606315883,39.3366742314503384],"hsluv":[258.963845190076711,99.9999999999926,39.3366742314503384]},"#0055dd":{"lch":[40.7621365800243538,110.592821589198408,260.220233587680809],"luv":[40.7621365800243538,-18.7854624460211568,-108.985680654613518],"rgb":[0,0.333333333333333315,0.866666666666666696],"xyz":[0.162981133007843,0.1171661704543695,0.698115005650027709],"hpluv":[260.220233587680809,344.278042660470817,40.7621365800243538],"hsluv":[260.220233587680809,99.9999999999926672,40.7621365800243538]},"#0055ee":{"lch":[42.2603772648371105,121.285075365136905,261.168248695532611],"luv":[42.2603772648371105,-18.6213165580406681,-119.847052846418293],"rgb":[0,0.333333333333333315,0.933333333333333348],"xyz":[0.186793313274017742,0.126691042560839517,0.823525821718550932],"hpluv":[261.168248695532611,364.177675198016914,42.2603772648371105],"hsluv":[261.168248695532611,99.9999999999924256,42.2603772648371105]},"#0055ff":{"lch":[43.8227784910393,131.676969611306021,261.90102950371454],"luv":[43.8227784910393,-18.5511048350842884,-130.363648443170376],"rgb":[0,0.333333333333333315,1],"xyz":[0.212964361683849135,0.137159461924772241,0.961360010010332777],"hpluv":[261.90102950371454,381.28457852045068,43.8227784910393],"hsluv":[261.90102950371454,99.9999999999993321,43.8227784910393]},"#55ee00":{"lch":[83.4834241678481277,121.26988118033438,123.77813801339137],"luv":[83.4834241678481277,-67.423446821455,100.799121524975831],"rgb":[0.333333333333333315,0.933333333333333348,0],"xyz":[0.343194252835808289,0.630780425066107542,0.103666700302096418],"hpluv":[123.77813801339137,313.542875178701877,83.4834241678481277],"hsluv":[123.77813801339137,100.000000000002402,83.4834241678481277]},"#55ee11":{"lch":[83.5046935730824487,120.419265504422668,124.002811201886018],"luv":[83.5046935730824487,-67.3424968648776456,99.8287915414615412],"rgb":[0.333333333333333315,0.933333333333333348,0.0666666666666666657],"xyz":[0.344205918335445393,0.63118509126596245,0.108994805266852055],"hpluv":[124.002811201886018,311.80236567126093,83.5046935730824487],"hsluv":[124.002811201886018,98.9375412624106616,83.5046935730824487]},"#55ee22":{"lch":[83.5440973470955868,118.856748008926118,124.425313598414533],"luv":[83.5440973470955868,-67.1934622190367463,98.0406302625408728],"rgb":[0.333333333333333315,0.933333333333333348,0.133333333333333331],"xyz":[0.34608127647392245,0.631935234521353251,0.118871691462831247],"hpluv":[124.425313598414533,308.59848358059196,83.5440973470955868],"hsluv":[124.425313598414533,96.9807587800033133,83.5440973470955868]},"#55ee33":{"lch":[83.6089072227085524,116.32446068797897,125.138397832270286],"luv":[83.6089072227085524,-66.950941309724243,95.1259775880964469],"rgb":[0.333333333333333315,0.933333333333333348,0.2],"xyz":[0.349169027206380156,0.633170334814336377,0.135133845320442397],"hpluv":[125.138397832270286,303.387603747434184,83.6089072227085524],"hsluv":[125.138397832270286,93.7945051225822084,83.6089072227085524]},"#55ee44":{"lch":[83.7023291233000748,112.756808619009803,126.207644663357115],"luv":[83.7023291233000748,-66.6069499756988535,90.9813832873448547],"rgb":[0.333333333333333315,0.933333333333333348,0.266666666666666663],"xyz":[0.353627022450599071,0.634953532912023944,0.158612620273329036],"hpluv":[126.207644663357115,296.007020538140409,83.7023291233000748],"hsluv":[126.207644663357115,89.2707337544585,83.7023291233000748]},"#55ee55":{"lch":[83.8270046653184,108.148092962556504,127.715012949240077],"luv":[83.8270046653184,-66.1579022543843,85.5519840841642747],"rgb":[0.333333333333333315,0.933333333333333348,0.333333333333333315],"xyz":[0.359589436489961056,0.637338498527768693,0.190014667547302951],"hpluv":[127.715012949240077,286.404562223907249,83.8270046653184],"hsluv":[127.715012949240077,83.3573838846113091,83.8270046653184]},"#55ee66":{"lch":[83.985160091985378,102.554744038676162,129.769393513035965],"luv":[83.985160091985378,-65.6041880698479645,78.8261760618539853],"rgb":[0.333333333333333315,0.933333333333333348,0.4],"xyz":[0.367174432263469241,0.640372496837172,0.229962311954446885],"hpluv":[129.769393513035965,274.647728218817576,83.985160091985378],"hsluv":[129.769393513035965,83.6273111034757477,83.985160091985378]},"#55ee77":{"lch":[84.1786855608653752,96.1019099790829756,132.519661951802362],"luv":[84.1786855608653752,-64.9498200787083,70.8314758661090451],"rgb":[0.333333333333333315,0.933333333333333348,0.466666666666666674],"xyz":[0.376488445283671147,0.644098102045252863,0.279016113860844794],"hpluv":[132.519661951802362,260.948457539577589,84.1786855608653752],"hsluv":[132.519661951802362,83.9470254314832687,84.1786855608653752]},"#55ee88":{"lch":[84.4091822183787741,88.9952087097784,136.170997575445568],"luv":[84.4091822183787741,-64.2020140446184371,61.6299323860706],"rgb":[0.333333333333333315,0.933333333333333348,0.533333333333333326],"xyz":[0.387628862385614947,0.648554268886030405,0.337688977264417],"hpluv":[136.170997575445568,245.709397001158351,84.4091822183787741],"hsluv":[136.170997575445568,84.3134084109568533,84.4091822183787741]},"#55ee99":{"lch":[84.6779925165317877,81.540352796223317,141.002136712429774],"luv":[84.6779925165317877,-63.3706695007570531,51.3126434824633151],"rgb":[0.333333333333333315,0.933333333333333348,0.6],"xyz":[0.400685826494687647,0.653777054529659618,0.406455654905534869],"hpluv":[141.002136712429774,229.604367075154897,84.6779925165317877],"hsluv":[141.002136712429774,84.7220894550445394,84.6779925165317877]},"#55eeaa":{"lch":[84.9862212486181363,74.1734332109310373,147.37159021859884],"luv":[84.9862212486181363,-62.4677637576075426,39.9934580327855755],"rgb":[0.333333333333333315,0.933333333333333348,0.66666666666666663],"xyz":[0.415743519459940203,0.659800131715760685,0.48575950452253347],"hpluv":[147.37159021859884,213.709694911287,84.9862212486181363],"hsluv":[147.37159021859884,85.1677250765186358,84.9862212486181363]},"#55eebb":{"lch":[85.334751323756052,67.4984157699475418,155.676120933413],"luv":[85.334751323756052,-61.5066955643592337,27.8022037293077737],"rgb":[0.333333333333333315,0.933333333333333348,0.733333333333333282],"xyz":[0.432881111567276877,0.666655168558695443,0.576017489621175272],"hpluv":[155.676120933413,199.690784145783283,85.334751323756052],"hsluv":[155.676120933413,85.6443005177139298,85.334751323756052]},"#55eecc":{"lch":[85.7242566025865784,62.3040769944455,166.184583472908372],"luv":[85.7242566025865784,-60.5016239571924643,14.8778865660505755],"rgb":[0.333333333333333315,0.933333333333333348,0.8],"xyz":[0.452173487010998576,0.674372118736184301,0.677624000291445427],"hpluv":[166.184583472908372,189.979166061651426,85.7242566025865784],"hsluv":[166.184583472908372,86.1454332210543186,85.7242566025865784]},"#55eedd":{"lch":[86.1552131978466349,59.4824491826881427,178.687660418725557],"luv":[86.1552131978466349,-59.4668469392298462,1.36230535390821395],"rgb":[0.333333333333333315,0.933333333333333348,0.866666666666666696],"xyz":[0.473691812561632175,0.682979448956437807,0.790953848191451425],"hpluv":[178.687660418725557,187.703134777137279,86.1552131978466349],"hsluv":[178.687660418725557,86.6646578889921,86.1552131978466349]},"#55eeee":{"lch":[86.6279101052896578,59.7608483004272202,192.177050630061245],"luv":[86.6279101052896578,-58.4162567245265265,-12.6055519466972967],"rgb":[0.333333333333333315,0.933333333333333348,0.933333333333333348],"xyz":[0.497503992827806885,0.692504321062907824,0.916364664259974648],"hpluv":[192.177050630061245,196.025490067494644,86.6279101052896578],"hsluv":[192.177050630061245,87.195676441965972,86.6279101052896578]},"#55eeff":{"lch":[87.1424596935915901,63.3545065705612274,205.119112492248092],"luv":[87.1424596935915901,-57.3628964007582169,-26.8940814923128677],"rgb":[0.333333333333333315,0.933333333333333348,1],"xyz":[0.523675041237638306,0.702972740426840548,1.05419885255175649],"hpluv":[205.119112492248092,217.06231600799947,87.1424596935915901],"hsluv":[205.119112492248092,99.9999999999933,87.1424596935915901]},"#006600":{"lch":[36.9339903888407548,57.1632711650289735,127.71501294924046],"luv":[36.9339903888407548,-34.9687359497521086,45.2197642227726249],"rgb":[0,0.4,0],"xyz":[0.0475116309878656218,0.0950232619757325619,0.0158372103292880942],"hpluv":[127.71501294924046,196.394882900214554,36.9339903888407548],"hsluv":[127.71501294924046,100.000000000002331,36.9339903888407548]},"#006611":{"lch":[37.0090255636121412,54.7765813256580216,129.276595687178855],"luv":[37.0090255636121412,-34.6771211058740789,42.4024897091546933],"rgb":[0,0.4,0.0666666666666666657],"xyz":[0.04852329648750274,0.0954279281755874148,0.0211653152940437239],"hpluv":[129.276595687178855,187.813410896691579,37.0090255636121412],"hsluv":[129.276595687178855,99.9999999999908908,37.0090255636121412]},"#006622":{"lch":[37.1475616040544949,50.6324758020482761,132.428423847637788],"luv":[37.1475616040544949,-34.160143827310165,37.3728802682170453],"rgb":[0,0.4,0.133333333333333331],"xyz":[0.0503986546259797621,0.0961780714309782292,0.0310422014900229234],"hpluv":[132.428423847637788,172.957013965329963,37.1475616040544949],"hsluv":[132.428423847637788,99.9999999999909619,37.1475616040544949]},"#006633":{"lch":[37.3740982281225911,44.601943170857588,138.432874640413417],"luv":[37.3740982281225911,-33.3702331720845464,29.5932572160807972],"rgb":[0,0.4,0.2],"xyz":[0.0534864053584375,0.0974131717239613421,0.0473043553476340667],"hpluv":[138.432874640413417,151.43364776149042,37.3740982281225911],"hsluv":[138.432874640413417,99.9999999999910187,37.3740982281225911]},"#006644":{"lch":[37.6978110334583292,37.6830106217376226,149.139540405640531],"luv":[37.6978110334583292,-32.3478161181420845,19.3294615006434647],"rgb":[0,0.4,0.266666666666666663],"xyz":[0.0579444006026563832,0.099196369821648922,0.0707831303005207],"hpluv":[149.139540405640531,126.843666215367492,37.6978110334583292],"hsluv":[149.139540405640531,99.9999999999911893,37.6978110334583292]},"#006655":{"lch":[38.1247572916394191,31.9621551107412678,167.158861879927684],"luv":[38.1247572916394191,-31.1627826377188839,7.10354401671241],"rgb":[0,0.4,0.333333333333333315],"xyz":[0.0639068146420183752,0.101581335437393755,0.102185177574494607],"hpluv":[167.158861879927684,106.382034992292617,38.1247572916394191],"hsluv":[167.158861879927684,99.9999999999912461,38.1247572916394191]},"#006666":{"lch":[38.6583399620500714,30.584907136256998,192.177050630061132],"luv":[38.6583399620500714,-29.8967608054288689,-6.45137488264605441],"rgb":[0,0.4,0.4],"xyz":[0.0714918104155265466,0.104615333746797073,0.142132821981638569],"hpluv":[192.177050630061132,100.392967527320849,38.6583399620500714],"hsluv":[192.177050630061132,99.9999999999914877,38.6583399620500714]},"#006677":{"lch":[39.2996251720959648,35.3400629634721852,215.899751113488037],"luv":[39.2996251720959648,-28.6270125920824867,-20.7223116547099835],"rgb":[0,0.4,0.466666666666666674],"xyz":[0.080805823435728466,0.108340938954877883,0.191186623888036478],"hpluv":[215.899751113488037,114.108563264217921,39.2996251720959648],"hsluv":[215.899751113488037,99.999999999991644,39.2996251720959648]},"#006688":{"lch":[40.0476371065618721,44.619030030948764,232.088426656893603],"luv":[40.0476371065618721,-27.4159210327312195,-35.2026293738089109],"rgb":[0,0.4,0.533333333333333326],"xyz":[0.0919462405376723,0.112797105795655481,0.249859487291608645],"hpluv":[232.088426656893603,141.378234692038774,40.0476371065618721],"hsluv":[232.088426656893603,99.9999999999918145,40.0476371065618721]},"#006699":{"lch":[40.8996671875350728,56.0796471869528546,242.024131169727298],"luv":[40.8996671875350728,-26.3069429553173038,-49.5264735364712863],"rgb":[0,0.4,0.6],"xyz":[0.105003204646745008,0.118019891439284638,0.318626164932726552],"hpluv":[242.024131169727298,173.990215160848891,40.8996671875350728],"hsluv":[242.024131169727298,99.9999999999919,40.8996671875350728]},"#0066aa":{"lch":[41.8515997707465104,68.3303466488807345,248.245335088520562],"luv":[41.8515997707465104,-25.3254853434547229,-63.4638169768779861],"rgb":[0,0.4,0.66666666666666663],"xyz":[0.12006089761199755,0.124042968625385747,0.397930014549725153],"hpluv":[248.245335088520562,207.176688473106537,41.8515997707465104],"hsluv":[248.245335088520562,99.9999999999921,41.8515997707465104]},"#0066bb":{"lch":[42.8982420202673396,80.6980154219041452,252.339105133311591],"luv":[42.8982420202673396,-24.4823887435570384,-76.8946183711398],"rgb":[0,0.4,0.733333333333333282],"xyz":[0.137198489719334182,0.130898005468320505,0.488187999648366899],"hpluv":[252.339105133311591,238.705643004687346,42.8982420202673396],"hsluv":[252.339105133311591,99.9999999999922125,42.8982420202673396]},"#0066cc":{"lch":[44.0336413015701211,92.8728169416488356,255.165448618736946],"luv":[44.0336413015701211,-23.7781103155697018,-89.7772888680517696],"rgb":[0,0.4,0.8],"xyz":[0.156490865163055937,0.138614955645809307,0.589794510318637],"hpluv":[255.165448618736946,267.63526922347819,44.0336413015701211],"hsluv":[255.165448618736946,99.9999999999922835,44.0336413015701211]},"#0066dd":{"lch":[45.2513748624169807,104.723900430114114,257.197154574648096],"luv":[45.2513748624169807,-23.2064943358636171,-102.120291528843495],"rgb":[0,0.4,0.866666666666666696],"xyz":[0.17800919071368948,0.147222285866062841,0.703124358218643],"hpluv":[257.197154574648096,293.665789717253858,45.2513748624169807],"hsluv":[257.197154574648096,99.9999999999923119,45.2513748624169807]},"#0066ee":{"lch":[46.5448008930790422,116.210429262859975,258.70668283343889],"luv":[46.5448008930790422,-22.7576936505684415,-113.960305585607557],"rgb":[0,0.4,0.933333333333333348],"xyz":[0.201821370979864217,0.156747157972532858,0.828535174287166276],"hpluv":[258.70668283343889,316.82048544727013,46.5448008930790422],"hsluv":[258.70668283343889,99.9999999999923119,46.5448008930790422]},"#0066ff":{"lch":[47.9072652547968758,127.336469583599694,259.859032010401279],"luv":[47.9072652547968758,-22.4202120236612075,-125.347160234402949],"rgb":[0,0.4,1],"xyz":[0.227992419389695611,0.167215577336465582,0.966369362578948121],"hpluv":[259.859032010401279,337.280125749862,47.9072652547968758],"hsluv":[259.859032010401279,99.9999999999992326,47.9072652547968758]},"#55ff00":{"lch":[88.6611895097861691,129.940408372856581,124.363532639485271],"luv":[88.6611895097861691,-73.3437881830395213,107.262288168144963],"rgb":[0.333333333333333315,1,0],"xyz":[0.395046625265482121,0.734485169925456649,0.120950824445320529],"hpluv":[124.363532639485271,511.214684976108288,88.6611895097861691],"hsluv":[124.363532639485271,100.000000000002203,88.6611895097861691]},"#55ff11":{"lch":[88.6804070841335488,129.16615931328721,124.557188606571273],"luv":[88.6804070841335488,-73.2667318726085597,106.376137890284312],"rgb":[0.333333333333333315,1,0.0666666666666666657],"xyz":[0.396058290765119225,0.734889836125311557,0.126278929410076152],"hpluv":[124.557188606571273,509.111714190739917,88.6804070841335488],"hsluv":[124.557188606571273,99.999999999991374,88.6804070841335488]},"#55ff22":{"lch":[88.7160126920472862,127.742171235629925,124.920549061750862],"luv":[88.7160126920472862,-73.1247263453711867,104.741762009752222],"rgb":[0.333333333333333315,1,0.133333333333333331],"xyz":[0.397933648903596282,0.735639979380702358,0.136155815606055358],"hpluv":[124.920549061750862,505.235489858807625,88.7160126920472862],"hsluv":[124.920549061750862,99.9999999999912461,88.7160126920472862]},"#55ff33":{"lch":[88.7745841250638819,125.429409451765778,125.531442964179078],"luv":[88.7745841250638819,-72.893256299655377,102.074041467218606],"rgb":[0.333333333333333315,1,0.2],"xyz":[0.401021399636054,0.736875079673685485,0.152417969463666508],"hpluv":[125.531442964179078,498.916518871762833,88.7745841250638819],"hsluv":[125.531442964179078,99.9999999999915445,88.7745841250638819]},"#55ff44":{"lch":[88.8590323294941271,122.159967165607114,126.442013329478428],"luv":[88.8590323294941271,-72.5641116581323189,98.2726171279075658],"rgb":[0.333333333333333315,1,0.266666666666666663],"xyz":[0.405479394880272903,0.738658277771373,0.175896744416553147],"hpluv":[126.442013329478428,489.934204596741552,88.8590323294941271],"hsluv":[126.442013329478428,99.9999999999914735,88.8590323294941271]},"#55ff55":{"lch":[88.9717666926620154,117.915518658848484,127.715012949240119],"luv":[88.9717666926620154,-72.1329719647303,93.2786357968462],"rgb":[0.333333333333333315,1,0.333333333333333315],"xyz":[0.411441808919634888,0.7410432433871178,0.207298791690527062],"hpluv":[127.715012949240119,478.187207442594797,88.9717666926620154],"hsluv":[127.715012949240119,99.9999999999912461,88.9717666926620154]},"#55ff66":{"lch":[89.1148309932425,112.728028648536309,129.430986513959965],"luv":[89.1148309932425,-71.5990188667543919,87.0700232014633713],"rgb":[0.333333333333333315,1,0.4],"xyz":[0.419026804693143073,0.744077241696521119,0.247246436097671],"hpluv":[129.430986513959965,463.701047487447568,89.1148309932425],"hsluv":[129.430986513959965,99.999999999991374,89.1148309932425]},"#55ff77":{"lch":[89.2899761450384233,106.6837193332601,131.696695826109391],"luv":[89.2899761450384233,-70.9646547782272705,79.6582308552282825],"rgb":[0.333333333333333315,1,0.466666666666666674],"xyz":[0.428340817713345,0.747802846904602,0.296300238004068905],"hpluv":[131.696695826109391,446.653165807945641,89.2899761450384233],"hsluv":[131.696695826109391,99.9999999999911466,89.2899761450384233]},"#55ff88":{"lch":[89.4987035327786344,99.9302046144725722,134.655503696120093],"luv":[89.4987035327786344,-70.2351927280585784,71.0849034376696807],"rgb":[0.333333333333333315,1,0.533333333333333326],"xyz":[0.439481234815288779,0.752259013745379512,0.354973101407641101],"hpluv":[134.655503696120093,427.420708471833962,89.4987035327786344],"hsluv":[134.655503696120093,99.9999999999910472,89.4987035327786344]},"#55ff99":{"lch":[89.7422928839939544,92.6881300553494185,138.499225093055145],"luv":[89.7422928839939544,-69.4184746025382395,61.4179520744067275],"rgb":[0.333333333333333315,1,0.6],"xyz":[0.452538198924361534,0.757481799389008725,0.423739779048759],"hpluv":[138.499225093055145,406.664135605650245,89.7422928839939544],"hsluv":[138.499225093055145,99.9999999999909193,89.7422928839939544]},"#55ffaa":{"lch":[90.021821419032733,85.2692799565717081,143.477548510033301],"luv":[90.021821419032733,-68.524415632830582,50.7469660816416095],"rgb":[0.333333333333333315,1,0.66666666666666663],"xyz":[0.467595891889614035,0.763504876575109792,0.503043628665757581],"hpluv":[143.477548510033301,385.467603776639692,90.021821419032733],"hsluv":[143.477548510033301,99.9999999999908908,90.021821419032733]},"#55ffbb":{"lch":[90.3381779071049635,78.1017696608261929,149.892156464581973],"luv":[90.3381779071049635,-67.5644942943643514,39.178125719584358],"rgb":[0.333333333333333315,1,0.733333333333333282],"xyz":[0.484733483996950709,0.770359913418044551,0.593301613764399383],"hpluv":[149.892156464581973,365.560319764238727,90.3381779071049635],"hsluv":[149.892156464581973,99.9999999999906,90.3381779071049635]},"#55ffcc":{"lch":[90.6920737330737836,71.7555158590460849,158.04408297895796],"luv":[90.6920737330737836,-66.5512174426729217,26.828893251416094],"rgb":[0.333333333333333315,1,0.8],"xyz":[0.504025859440672463,0.778076863595533408,0.694908124434669539],"hpluv":[158.04408297895796,349.620992563925881,90.6920737330737836],"hsluv":[158.04408297895796,99.9999999999905214,90.6920737330737836]},"#55ffdd":{"lch":[91.0840522607878142,66.9403052018893874,168.083008151042208],"luv":[91.0840522607878142,-65.4975936461766,13.8227959213187273],"rgb":[0.333333333333333315,1,0.866666666666666696],"xyz":[0.525544184991306,0.786684193815786914,0.808237972334675536],"hpluv":[168.083008151042208,341.570927955438208,91.0840522607878142],"hsluv":[168.083008151042208,99.9999999999901092,91.0840522607878142]},"#55ffee":{"lch":[91.5144973031429,64.4172738793593,179.746868091755],"luv":[91.5144973031429,-64.4166452130874347,0.284593639433804613],"rgb":[0.333333333333333315,1,0.933333333333333348],"xyz":[0.549356365257480661,0.796209065922256931,0.933648788403198759],"hpluv":[179.746868091755,346.559914030924404,91.5144973031429],"hsluv":[179.746868091755,99.9999999999898108,91.5144973031429]},"#55ffff":{"lch":[91.9836412143362,64.7784688708661918,192.177050630061103],"luv":[91.9836412143362,-63.3209831419883,-13.663935128132529],"rgb":[0.333333333333333315,1,1],"xyz":[0.575527413667312082,0.806677485286189655,1.07148297669498049],"hpluv":[192.177050630061103,370.276433987554753,91.9836412143362],"hsluv":[192.177050630061103,99.9999999999890719,91.9836412143362]},"#007700":{"lch":[43.052730924646589,66.6333343982289534,127.715012949240503],"luv":[43.052730924646589,-40.7618988300426395,52.7111834129681611],"rgb":[0,0.466666666666666674,0],"xyz":[0.0659653690412832505,0.131930738082568333,0.0219884563470937981],"hpluv":[127.715012949240503,196.394882900214441,43.052730924646589],"hsluv":[127.715012949240503,100.000000000002217,43.052730924646589]},"#007711":{"lch":[43.1130460407029,64.6129906803504497,128.830381027920708],"luv":[43.1130460407029,-40.513441406878222,50.333881531534],"rgb":[0,0.466666666666666674,0.0666666666666666657],"xyz":[0.0669770345409203688,0.132335404282423186,0.0273165613118494313],"hpluv":[128.830381027920708,190.173702516526191,43.1130460407029],"hsluv":[128.830381027920708,99.9999999999908908,43.1130460407029]},"#007722":{"lch":[43.2245297597171856,61.038201507507992,131.028383581415682],"luv":[43.2245297597171856,-40.0674788501528809,46.0462721820529381],"rgb":[0,0.466666666666666674,0.133333333333333331],"xyz":[0.0688523926793974,0.133085547537814014,0.0371934475078286239],"hpluv":[131.028383581415682,179.188765673473426,43.2245297597171856],"hsluv":[131.028383581415682,99.9999999999909193,43.2245297597171856]},"#007733":{"lch":[43.4071769639209251,55.6324991773261601,135.049443606961],"luv":[43.4071769639209251,-39.3720497464739694,39.3041558041433419],"rgb":[0,0.466666666666666674,0.2],"xyz":[0.0719401434118551314,0.134320647830797113,0.0534556013654397671],"hpluv":[135.049443606961,162.632131787412106,43.4071769639209251],"hsluv":[135.049443606961,99.9999999999909193,43.4071769639209251]},"#007744":{"lch":[43.6689123670523855,48.8909209361139787,141.845848120172377],"luv":[43.6689123670523855,-38.4454486392046704,30.2038015639029105],"rgb":[0,0.466666666666666674,0.266666666666666663],"xyz":[0.076398138656074,0.136103845928484707,0.0769343763183264],"hpluv":[141.845848120172377,142.067640978907804,43.6689123670523855],"hsluv":[141.845848120172377,99.9999999999910614,43.6689123670523855]},"#007755":{"lch":[44.0154249216106,41.9153980271179,152.953344682219807],"luv":[44.0154249216106,-37.3313854656975224,19.0595973457790286],"rgb":[0,0.466666666666666674,0.333333333333333315],"xyz":[0.082360552695436,0.13848881154422954,0.108336423592300321],"hpluv":[152.953344682219807,120.839250305189026,44.0154249216106],"hsluv":[152.953344682219807,99.9999999999912461,44.0154249216106]},"#007766":{"lch":[44.4505333250062549,36.6388362985735725,170.062665906075836],"luv":[44.4505333250062549,-36.0891470448365865,6.32279929223085357],"rgb":[0,0.466666666666666674,0.4],"xyz":[0.0899455484689441753,0.141522809853632831,0.148284067999444269],"hpluv":[170.062665906075836,104.593337643625588,44.4505333250062549],"hsluv":[170.062665906075836,99.9999999999913314,44.4505333250062549]},"#007777":{"lch":[44.9764013416840669,35.58350047386471,192.17705063006116],"luv":[44.9764013416840669,-34.7828880940388601,-7.50574458738768],"rgb":[0,0.466666666666666674,0.466666666666666674],"xyz":[0.0992595614891461,0.145248415061713654,0.197337869905842178],"hpluv":[192.17705063006116,100.392967527320835,44.9764013416840669],"hsluv":[192.17705063006116,99.9999999999914451,44.9764013416840669]},"#007788":{"lch":[45.5937085159301603,40.0276538709377,213.25546015720218],"luv":[45.5937085159301603,-33.4724811425817,-21.9500815618326577],"rgb":[0,0.466666666666666674,0.533333333333333326],"xyz":[0.110399978591089923,0.149704581902491252,0.256010733309414373],"hpluv":[213.25546015720218,111.402399127386914,45.5937085159301603],"hsluv":[213.25546015720218,99.9999999999916156,45.5937085159301603]},"#007799":{"lch":[46.3018156057360244,48.7595612734022907,228.659125647543163],"luv":[46.3018156057360244,-32.2075160625452597,-36.6083422822662357],"rgb":[0,0.466666666666666674,0.6],"xyz":[0.123456942700162636,0.154927367546120409,0.324777410950532253],"hpluv":[228.659125647543163,133.62911578541167,46.3018156057360244],"hsluv":[228.659125647543163,99.9999999999917577,46.3018156057360244]},"#0077aa":{"lch":[47.0989379645613795,59.8445186957143,238.773531847525192],"luv":[47.0989379645613795,-31.0247207616125031,-51.1745358511991597],"rgb":[0,0.466666666666666674,0.66666666666666663],"xyz":[0.138514635665415164,0.160950444732221504,0.404081260567530853],"hpluv":[238.773531847525192,161.232500989130415,47.0989379645613795],"hsluv":[238.773531847525192,99.999999999991914,47.0989379645613795]},"#0077bb":{"lch":[47.9823278818304146,71.9659744020705432,245.408717039049918],"luv":[47.9823278818304146,-29.9480972873728,-65.4386196408934495],"rgb":[0,0.466666666666666674,0.733333333333333282],"xyz":[0.155652227772751839,0.167805481575156262,0.4943392456661726],"hpluv":[245.408717039049918,190.32034768447943,47.9823278818304146],"hsluv":[245.408717039049918,99.9999999999920561,47.9823278818304146]},"#0077cc":{"lch":[48.9484610491917067,84.4081580704908276,249.9122747909542],"luv":[48.9484610491917067,-28.9906993044602252,-79.2734287305105454],"rgb":[0,0.466666666666666674,0.8],"xyz":[0.174944603216473565,0.175522431752645064,0.595945756336442756],"hpluv":[249.9122747909542,218.818838178067409,48.9484610491917067],"hsluv":[249.9122747909542,99.9999999999922125,48.9484610491917067]},"#0077dd":{"lch":[49.9932200675849,96.8017840095652389,253.089738624096071],"luv":[49.9932200675849,-28.15707849035525,-92.6162206005108715],"rgb":[0,0.466666666666666674,0.866666666666666696],"xyz":[0.196462928767107109,0.184129761972898598,0.709275604236448753],"hpluv":[253.089738624096071,245.70363248193695,49.9932200675849],"hsluv":[253.089738624096071,99.9999999999921272,49.9932200675849]},"#0077ee":{"lch":[51.1120678627821547,108.963279527823246,255.411176145550684],"luv":[51.1120678627821547,-27.4457353077348785,-105.450120430828804],"rgb":[0,0.466666666666666674,0.933333333333333348],"xyz":[0.220275109033281846,0.193654634079368643,0.834686420304972],"hpluv":[255.411176145550684,270.517920771775039,51.1120678627821547],"hsluv":[255.411176145550684,99.9999999999922551,51.1120678627821547]},"#0077ff":{"lch":[52.300205122294,120.810007187166491,257.158195690943],"luv":[52.300205122294,-26.851223719183885,-117.788240590245493],"rgb":[0,0.466666666666666674,1],"xyz":[0.24644615744311324,0.204123053443301339,0.972520608596753822],"hpluv":[257.158195690943,293.11554041762389,52.300205122294],"hsluv":[257.158195690943,99.9999999999991189,52.300205122294]},"#008800":{"lch":[49.0166039301270473,75.8637069146273291,127.71501294924046],"luv":[49.0166039301270473,-46.4084346679225348,60.0129920808956214],"rgb":[0,0.533333333333333326,0],"xyz":[0.0880377387662537,0.176075477532509878,0.0293459129220837445],"hpluv":[127.71501294924046,196.394882900214583,49.0166039301270473],"hsluv":[127.71501294924046,100.000000000002359,49.0166039301270473]},"#008811":{"lch":[49.066374048408079,74.1307167522113133,128.546257021813432],"luv":[49.066374048408079,-46.1942790787678064,57.9780281364371461],"rgb":[0,0.533333333333333326,0.0666666666666666657],"xyz":[0.0890494042658908219,0.17648014373236473,0.0346740178868393742],"hpluv":[128.546257021813432,191.713881645209739,49.066374048408079],"hsluv":[128.546257021813432,99.9999999999908908,49.066374048408079]},"#008822":{"lch":[49.1584337135343503,71.0276132120671,130.159311596065152],"luv":[49.1584337135343503,-45.8067815452400779,54.2831521106656112],"rgb":[0,0.533333333333333326,0.133333333333333331],"xyz":[0.090924762404367851,0.177230286987755559,0.0445509040828185737],"hpluv":[130.159311596065152,183.344763498744726,49.1584337135343503],"hsluv":[130.159311596065152,99.9999999999909335,49.1584337135343503]},"#008833":{"lch":[49.3094443496477197,66.226384742663825,133.033255321350083],"luv":[49.3094443496477197,-45.1943905199784481,48.4086882864121648],"rgb":[0,0.533333333333333326,0.2],"xyz":[0.0940125131368255845,0.178465387280738658,0.060813057940429717],"hpluv":[133.033255321350083,170.427732437953466,49.3094443496477197],"hsluv":[133.033255321350083,99.9999999999909903,49.3094443496477197]},"#008844":{"lch":[49.5262444349700388,59.9709063982634589,137.708745518338219],"luv":[49.5262444349700388,-44.3625073014275202,40.3543995143041],"rgb":[0,0.533333333333333326,0.266666666666666663],"xyz":[0.0984705083810444581,0.180248585378426252,0.0842918328933163485],"hpluv":[137.708745518338219,153.654237765673173,49.5262444349700388],"hsluv":[137.708745518338219,99.9999999999910756,49.5262444349700388]},"#008855":{"lch":[49.8139833497656355,52.876539169604392,145.043769270071607],"luv":[49.8139833497656355,-43.3370811793054074,30.2956397756013871],"rgb":[0,0.533333333333333326,0.333333333333333315],"xyz":[0.104432922420406457,0.182633550994171084,0.115693880167290264],"hpluv":[145.043769270071607,134.694876863850226,49.8139833497656355],"hsluv":[145.043769270071607,99.9999999999911893,49.8139833497656355]},"#008866":{"lch":[50.1764284055384593,46.0546718070978613,156.264738854980266],"luv":[50.1764284055384593,-42.1591397878491918,18.5375221539472825],"rgb":[0,0.533333333333333326,0.4],"xyz":[0.112017918193914628,0.185667549303574375,0.155641524574434226],"hpluv":[156.264738854980266,116.469784961641182,50.1764284055384593],"hsluv":[156.264738854980266,99.9999999999912461,50.1764284055384593]},"#008877":{"lch":[50.6161324463586766,41.2412500498738694,172.391379993232761],"luv":[50.6161324463586766,-40.8781468825216336,5.46056893805106114],"rgb":[0,0.533333333333333326,0.466666666666666674],"xyz":[0.121331931214116548,0.189393154511655198,0.204695326480832135],"hpluv":[172.391379993232761,103.390869865470918,50.6161324463586766],"hsluv":[172.391379993232761,99.9999999999913456,50.6161324463586766]},"#008888":{"lch":[51.1345503085294695,40.4555776108317602,192.177050630061132],"luv":[51.1345503085294695,-39.545345738280993,-8.53342781453345],"rgb":[0,0.533333333333333326,0.533333333333333326],"xyz":[0.132472348316060362,0.193849321352432796,0.263368189884404302],"hpluv":[192.177050630061132,100.392967527320849,51.1345503085294695],"hsluv":[192.177050630061132,99.9999999999914877,51.1345503085294695]},"#008899":{"lch":[51.7321394091786715,44.6308971675799881,211.11913642158629],"luv":[51.7321394091786715,-38.208266400248,-23.066108485628412],"rgb":[0,0.533333333333333326,0.6],"xyz":[0.145529312425133089,0.199072106996061954,0.332134867525522237],"hpluv":[211.11913642158629,109.474886689832829,51.7321394091786715],"hsluv":[211.11913642158629,99.999999999991573,51.7321394091786715]},"#0088aa":{"lch":[52.4084594351014914,52.8385448128107598,225.694192047300788],"luv":[52.4084594351014914,-36.9070805124816346,-37.8124215831333572],"rgb":[0,0.533333333333333326,0.66666666666666663],"xyz":[0.160587005390385618,0.205095184182163048,0.411438717142520782],"hpluv":[225.694192047300788,127.934825585488483,52.4084594351014914],"hsluv":[225.694192047300788,99.9999999999917,52.4084594351014914]},"#0088bb":{"lch":[53.1622766119302952,63.4852929684367,235.812153399491365],"luv":[53.1622766119302952,-35.672889398211332,-52.5150205681309856],"rgb":[0,0.533333333333333326,0.733333333333333282],"xyz":[0.177724597497722292,0.211950221025097807,0.501696702241162584],"hpluv":[235.812153399491365,151.533580059798538,53.1622766119302952],"hsluv":[235.812153399491365,99.9999999999918572,53.1622766119302952]},"#0088cc":{"lch":[53.9916730817088961,75.3609801883338406,242.731381598031476],"luv":[53.9916730817088961,-34.5275961267233455,-66.9859868976812578],"rgb":[0,0.533333333333333326,0.8],"xyz":[0.197016972941444019,0.219667171202586609,0.60330321291143274],"hpluv":[242.731381598031476,177.116523654060018,53.9916730817088961],"hsluv":[242.731381598031476,99.9999999999919282,53.9916730817088961]},"#0088dd":{"lch":[54.894159312243417,87.7409205251226,247.565131731451658],"luv":[54.894159312243417,-33.4848266090853,-81.1001573460580545],"rgb":[0,0.533333333333333326,0.866666666666666696],"xyz":[0.218535298492077562,0.228274501422840143,0.716633060811438738],"hpluv":[247.565131731451658,202.822146488853946,54.894159312243417],"hsluv":[247.565131731451658,99.9999999999921414,54.894159312243417]},"#0088ee":{"lch":[55.8667862779657725,100.217939448335898,251.046181944553609],"luv":[55.8667862779657725,-32.551381555669181,-94.7841914355319091],"rgb":[0,0.533333333333333326,0.933333333333333348],"xyz":[0.242347478758252299,0.237799373529310187,0.842043876879962],"hpluv":[251.046181944553609,227.630842720065772,55.8667862779657725],"hsluv":[251.046181944553609,99.9999999999923261,55.8667862779657725]},"#0088ff":{"lch":[56.9062538959811803,112.568622459607909,253.628629682131134],"luv":[56.9062538959811803,-31.728824885135996,-108.00452043253614],"rgb":[0,0.533333333333333326,1],"xyz":[0.268518527168083665,0.248267792893242883,0.979878065171743806],"hpluv":[253.628629682131134,251.013269675548315,56.9062538959811803],"hsluv":[253.628629682131134,99.9999999999989,56.9062538959811803]},"#009900":{"lch":[54.8465256129575778,84.8867610313905629,127.71501294924046],"luv":[54.8465256129575778,-51.9281467214630865,67.1507987776363677],"rgb":[0,0.6,0],"xyz":[0.11390733921872119,0.227814678437445572,0.037969113072906],"hpluv":[127.71501294924046,196.394882900214611,54.8465256129575778],"hsluv":[127.71501294924046,100.000000000002359,54.8465256129575778]},"#009911":{"lch":[54.8884489227774139,83.3822613920475533,128.355135015114286],"luv":[54.8884489227774139,-51.7415219578455918,65.3866685214771195],"rgb":[0,0.6,0.0666666666666666657],"xyz":[0.114919004718358309,0.228219344637300425,0.0432972180376616292],"hpluv":[128.355135015114286,192.766711025891595,54.8884489227774139],"hsluv":[128.355135015114286,99.9999999999908908,54.8884489227774139]},"#009922":{"lch":[54.9660326693047665,80.6666974094322882,129.584419925030318],"luv":[54.9660326693047665,-51.4019848556742147,62.168738316310943],"rgb":[0,0.6,0.133333333333333331],"xyz":[0.116794362856835338,0.228969487892691254,0.0531741042336408287],"hpluv":[129.584419925030318,186.225526863887183,54.9660326693047665],"hsluv":[129.584419925030318,99.9999999999908766,54.9660326693047665]},"#009933":{"lch":[55.0934048637144826,76.4021664793699529,131.735569901926],"luv":[55.0934048637144826,-50.8604445821364948,57.0132109221080725],"rgb":[0,0.6,0.2],"xyz":[0.119882113589293071,0.230204588185674353,0.0694362580912519789],"hpluv":[131.735569901926,175.972736191316358,55.0934048637144826],"hsluv":[131.735569901926,99.9999999999909903,55.0934048637144826]},"#009944":{"lch":[55.2764995203901321,70.6973886175228614,135.142608572152881],"luv":[55.2764995203901321,-50.1148739946869739,49.8660221176072795],"rgb":[0,0.6,0.266666666666666663],"xyz":[0.124340108833511945,0.231987786283361946,0.0929150330441386174],"hpluv":[135.142608572152881,162.293888564466016,55.2764995203901321],"hsluv":[135.142608572152881,99.9999999999910472,55.2764995203901321]},"#009955":{"lch":[55.5199214835444792,63.9084670453141044,140.311824754994205],"luv":[55.5199214835444792,-49.1795700812718,40.8125231602173173],"rgb":[0,0.6,0.333333333333333315],"xyz":[0.130302522872873944,0.234372751899106779,0.124317080318112519],"hpluv":[140.311824754994205,146.065915008593578,55.5199214835444792],"hsluv":[140.311824754994205,99.999999999991033,55.5199214835444792]},"#009966":{"lch":[55.8272121342916847,56.7002292022714229,147.995210176352344],"luv":[55.8272121342916847,-48.0820094218291771,30.0505634148387166],"rgb":[0,0.6,0.4],"xyz":[0.137887518646382129,0.23740675020851007,0.164264724725256495],"hpluv":[147.995210176352344,128.877825594911201,55.8272121342916847],"hsluv":[147.995210176352344,99.9999999999911893,55.8272121342916847]},"#009977":{"lch":[56.2009899164422393,50.1460500452165832,159.138923639260469],"luv":[56.2009899164422393,-46.85880632633,17.8571723631952],"rgb":[0,0.6,0.466666666666666674],"xyz":[0.147201531666584035,0.241132355416590893,0.213318526631654404],"hpluv":[159.138923639260469,113.222330796973324,56.2009899164422393],"hsluv":[159.138923639260469,99.9999999999912887,56.2009899164422393]},"#009988":{"lch":[56.6430401241061077,45.7780774967248476,174.293450088826631],"luv":[56.6430401241061077,-45.5512109338885409,4.55187453172192669],"rgb":[0,0.6,0.533333333333333326],"xyz":[0.158341948768527863,0.245588522257368491,0.271991390035226543],"hpluv":[174.293450088826631,102.553461073272217,56.6430401241061077],"hsluv":[174.293450088826631,99.9999999999913456,56.6430401241061077]},"#009999":{"lch":[57.1543844255405133,45.2182256610376498,192.177050630061132],"luv":[57.1543844255405133,-44.2008363998384866,-9.53802880511673301],"rgb":[0,0.6,0.6],"xyz":[0.171398912877600562,0.250811307900997649,0.340758067676344478],"hpluv":[192.177050630061132,100.392967527320849,57.1543844255405133],"hsluv":[192.177050630061132,99.9999999999914877,57.1543844255405133]},"#0099aa":{"lch":[57.7353441317496,49.1617433665336065,209.362441333496832],"luv":[57.7353441317496,-42.8462007667450138,-24.1056028900479831],"rgb":[0,0.6,0.66666666666666663],"xyz":[0.186456605842853118,0.256834385087098771,0.420061917293343079],"hpluv":[209.362441333496832,108.050017888493571,57.7353441317496],"hsluv":[209.362441333496832,99.9999999999915872,57.7353441317496]},"#0099bb":{"lch":[58.3856036871333686,56.8846197873520509,223.121526867409756],"luv":[58.3856036871333686,-41.5203973647636531,-38.8833713947714656],"rgb":[0,0.6,0.733333333333333282],"xyz":[0.203594197950189765,0.26368942193003353,0.51031990239198477],"hpluv":[223.121526867409756,123.631292939903787,58.3856036871333686],"hsluv":[223.121526867409756,99.9999999999917151,58.3856036871333686]},"#0099cc":{"lch":[59.1042769117952531,67.0724902608298237,233.123241992210865],"luv":[59.1042769117952531,-40.2499186561976856,-53.6531732328907225],"rgb":[0,0.6,0.8],"xyz":[0.222886573393911491,0.271406372107522331,0.611926413062254926],"hpluv":[233.123241992210865,144.000781521109104,59.1042769117952531],"hsluv":[233.123241992210865,99.9999999999918572,59.1042769117952531]},"#0099dd":{"lch":[59.889976295668248,78.6325369214165448,240.220044999287609],"luv":[59.889976295668248,-39.0544489896310338,-68.2482664747921888],"rgb":[0,0.6,0.866666666666666696],"xyz":[0.244404898944545035,0.280013702327775837,0.725256260962260924],"hpluv":[240.220044999287609,166.60478591483178,59.889976295668248],"hsluv":[240.220044999287609,99.9999999999918288,59.889976295668248]},"#0099ee":{"lch":[60.7408843834734853,90.8542474807105549,245.312254820906361],"luv":[60.7408843834734853,-37.9473430473261288,-82.5499451298106521],"rgb":[0,0.6,0.933333333333333348],"xyz":[0.2682170792107198,0.289538574434245854,0.850667077030784147],"hpluv":[245.312254820906361,189.803165481490907,60.7408843834734853],"hsluv":[245.312254820906361,99.9999999999919424,60.7408843834734853]},"#0099ff":{"lch":[61.6548256470178444,103.309645725501895,249.051296659176671],"luv":[61.6548256470178444,-36.936501733242423,-96.4809708680364082],"rgb":[0,0.6,1],"xyz":[0.294388127620551165,0.300006993798178578,0.988501265322566],"hpluv":[249.051296659176671,212.624411607996194,61.6548256470178444],"hsluv":[249.051296659176671,99.9999999999986926,61.6548256470178444]},"#44aa00":{"lch":[61.6346835386869714,87.655425968627469,122.331376925101353],"luv":[61.6346835386869714,-46.8794507107122556,74.0661245293922],"rgb":[0.266666666666666663,0.66666666666666663,0],"xyz":[0.167579386406696784,0.29977360690638849,0.0490310792412290836],"hpluv":[122.331376925101353,180.464989524422549,61.6346835386869714],"hsluv":[122.331376925101353,100.00000000000226,61.6346835386869714]},"#44aa11":{"lch":[61.6696010074672927,86.3319887480293175,122.80087722620695],"luv":[61.6696010074672927,-46.7678581574140253,72.5670705248452492],"rgb":[0.266666666666666663,0.66666666666666663,0.0666666666666666657],"xyz":[0.168591051906333916,0.300178273106243343,0.0543591842059847133],"hpluv":[122.80087722620695,177.639660035048053,61.6696010074672927],"hsluv":[122.80087722620695,97.7717273205757778,61.6696010074672927]},"#44aa22":{"lch":[61.7342457720645541,83.9245562706402097,123.699102784065559],"luv":[61.7342457720645541,-46.5639790081192,69.8221097085679],"rgb":[0.266666666666666663,0.66666666666666663,0.133333333333333331],"xyz":[0.170466410044810918,0.300928416361634143,0.0642360704019639128],"hpluv":[123.699102784065559,172.505216938407472,61.7342457720645541],"hsluv":[123.699102784065559,93.6968530578778882,61.7342457720645541]},"#44aa33":{"lch":[61.8404488118369784,80.0901636841586111,125.261260913590505],"luv":[61.8404488118369784,-46.2365065380172098,65.3958697634278],"rgb":[0.266666666666666663,0.66666666666666663,0.2],"xyz":[0.173554160777268651,0.30216351665461727,0.080498224259575063],"hpluv":[125.261260913590505,164.340980941234676,61.8404488118369784],"hsluv":[125.261260913590505,87.1410828818075913,61.8404488118369784]},"#44aa44":{"lch":[61.9932720073472,74.8379874444649573,127.71501294923992],"luv":[61.9932720073472,-45.7809668449718501,59.2015830825281526],"rgb":[0.266666666666666663,0.66666666666666663,0.266666666666666663],"xyz":[0.178012156021487539,0.303946714752304836,0.103976999212461702],"hpluv":[127.71501294923992,153.185220958209158,61.9932720073472],"hsluv":[127.71501294923992,77.998580561819125,61.9932720073472]},"#44aa55":{"lch":[62.1967362447927883,68.3415808764166854,131.40733952388851],"luv":[62.1967362447927883,-45.2016647888952292,51.2579864704043118],"rgb":[0.266666666666666663,0.66666666666666663,0.333333333333333315],"xyz":[0.183974570060849552,0.306331680368049697,0.135379046486435617],"hpluv":[131.40733952388851,139.430168232009549,62.1967362447927883],"hsluv":[131.40733952388851,78.575415606985473,62.1967362447927883]},"#44aa66":{"lch":[62.4540496972210377,60.9745995384144,136.885019691281769],"luv":[62.4540496972210377,-44.510458035487396,41.6739836629655684],"rgb":[0.266666666666666663,0.66666666666666663,0.4],"xyz":[0.191559565834357709,0.309365678677453,0.175326690893579551],"hpluv":[136.885019691281769,123.88755407265441,62.4540496972210377],"hsluv":[136.885019691281769,79.2669246679894854,62.4540496972210377]},"#44aa77":{"lch":[62.7677273349888196,53.3862032124370103,144.988299459670287],"luv":[62.7677273349888196,-43.7251633677153,30.629998072253084],"rgb":[0.266666666666666663,0.66666666666666663,0.466666666666666674],"xyz":[0.200873578854559642,0.313091283885533811,0.22438049279997746],"hpluv":[144.988299459670287,107.927460302012818,62.7677273349888196],"hsluv":[144.988299459670287,80.0573307147673603,62.7677273349888196]},"#44aa88":{"lch":[63.1396635168947142,46.6323085826041606,156.819414130132799],"luv":[63.1396635168947142,-42.8676249510766354,18.3558964585511255],"rgb":[0.266666666666666663,0.66666666666666663,0.533333333333333326],"xyz":[0.212013995956503443,0.317547450726311409,0.283053356203549655],"hpluv":[156.819414130132799,93.7182088199909,63.1396635168947142],"hsluv":[156.819414130132799,80.9270306732118456,63.1396635168947142]},"#44aa99":{"lch":[63.5711832083111,42.2713825005608328,173.059905511526438],"luv":[63.5711832083111,-41.9616613239929848,5.10771548142927578],"rgb":[0.266666666666666663,0.66666666666666663,0.6],"xyz":[0.22507096006557617,0.322770236369940566,0.351820033844667535],"hpluv":[173.059905511526438,84.3772726773670598,63.5711832083111],"hsluv":[173.059905511526438,81.8544924931781281,63.5711832083111]},"#44aaaa":{"lch":[64.0630839897801536,41.9755778813547948,192.177050630061],"luv":[64.0630839897801536,-41.03114670244819,-8.85404646225986802],"rgb":[0.266666666666666663,0.66666666666666663,0.66666666666666663],"xyz":[0.240128653030828698,0.328793313556041689,0.431123883461666135],"hpluv":[192.177050630061,83.1434743556685731,64.0630839897801536],"hsluv":[192.177050630061,82.8180264051213868,64.0630839897801536]},"#44aabb":{"lch":[64.6156750410269893,46.3675567205894481,210.140689328835606],"luv":[64.6156750410269893,-40.0984334486196374,-23.2823098339426302],"rgb":[0.266666666666666663,0.66666666666666663,0.733333333333333282],"xyz":[0.257266245138165373,0.335648350398976447,0.521381868560307882],"hpluv":[210.140689328835606,91.0574853549996135,64.6156750410269893],"hsluv":[210.140689328835606,83.7972417316187,64.6156750410269893]},"#44aacc":{"lch":[65.2288162125558131,54.5527176111565382,224.088695054270687],"luv":[65.2288162125558131,-39.1832309762682058,-37.956203827872514],"rgb":[0.266666666666666663,0.66666666666666663,0.8],"xyz":[0.276558620581887071,0.343365300576465249,0.622988379230578],"hpluv":[224.088695054270687,106.124637545316332,65.2288162125558131],"hsluv":[224.088695054270687,84.7740840933985424,65.2288162125558131]},"#44aadd":{"lch":[65.9019585504415772,65.1392687949415574,233.984713087438024],"luv":[65.9019585504415772,-38.3019605797345406,-52.6885581021924381],"rgb":[0.266666666666666663,0.66666666666666663,0.866666666666666696],"xyz":[0.29807694613252067,0.351972630796718755,0.736318227130584],"hpluv":[233.984713087438024,125.424934833645892,65.9019585504415772],"hsluv":[233.984713087438024,85.7334354760652246,65.9019585504415772]},"#44aaee":{"lch":[66.634186587349916,77.0517400481588,240.904642753345257],"luv":[66.634186587349916,-37.4675316968449081,-67.3287064556787698],"rgb":[0.266666666666666663,0.66666666666666663,0.933333333333333348],"xyz":[0.32188912639869538,0.361497502903188772,0.861729043199107259],"hpluv":[240.904642753345257,146.73194579095005,66.634186587349916],"hsluv":[240.904642753345257,86.6633273618325717,66.634186587349916]},"#44aaff":{"lch":[67.4242620727880677,89.6163291450103827,245.832487512483851],"luv":[67.4242620727880677,-36.6894434071527229,-81.7616731231704534],"rgb":[0.266666666666666663,0.66666666666666663,1],"xyz":[0.348060174808526801,0.371965922267121496,0.999563231490889104],"hpluv":[245.832487512483851,168.659292786049974,67.4242620727880677],"hsluv":[245.832487512483851,99.9999999999982094,67.4242620727880677]},"#44bb00":{"lch":[67.1028050092269126,96.9162111575721497,123.392710981560953],"luv":[67.1028050092269126,-53.3402140179528601,80.9170782570533476],"rgb":[0.266666666666666663,0.733333333333333282,0],"xyz":[0.201533884315295564,0.367682602723587049,0.0603492452107617],"hpluv":[123.392710981560953,183.271561122122193,67.1028050092269126],"hsluv":[123.392710981560953,100.00000000000226,67.1028050092269126]},"#44bb11":{"lch":[67.1332810832727347,95.7453830613523138,123.778355355208646],"luv":[67.1332810832727347,-53.2326764896654581,79.5830417319651673],"rgb":[0.266666666666666663,0.733333333333333282,0.0666666666666666657],"xyz":[0.202545549814932696,0.368087268923441902,0.0656773501755173322],"hpluv":[123.778355355208646,180.975295348072393,67.1332810832727347],"hsluv":[123.778355355208646,98.1806384027583334,67.1332810832727347]},"#44bb22":{"lch":[67.1897165718252438,93.6085464076245728,124.511290753684577],"luv":[67.1897165718252438,-53.03566579282883,77.1348048189646391],"rgb":[0.266666666666666663,0.733333333333333282,0.133333333333333331],"xyz":[0.204420907953409697,0.368837412178832702,0.0755542363714965248],"hpluv":[124.511290753684577,176.787689053856155,67.1897165718252438],"hsluv":[124.511290753684577,94.8452524510698538,67.1897165718252438]},"#44bb33":{"lch":[67.2824703298360873,90.1849869824975627,125.771296969252688],"luv":[67.2824703298360873,-52.7177504009765485,73.1721987485246501],"rgb":[0.266666666666666663,0.733333333333333282,0.2],"xyz":[0.207508658685867431,0.370072512471815829,0.091816390229107675],"hpluv":[125.771296969252688,170.087205132927863,67.2824703298360873],"hsluv":[125.771296969252688,89.4565739304913308,67.2824703298360873]},"#44bb44":{"lch":[67.4160218575577375,85.4495691526201284,127.715012949240077],"luv":[67.4160218575577375,-52.2724357759646807,67.5960156105081182],"rgb":[0.266666666666666663,0.733333333333333282,0.266666666666666663],"xyz":[0.211966653930086318,0.371855710569503395,0.115295165181994314],"hpluv":[127.715012949240077,160.837043785954393,67.4160218575577375],"hsluv":[127.715012949240077,81.8947222100884318,67.4160218575577375]},"#44bb55":{"lch":[67.5939766620447813,79.5000401119176,130.566112214394138],"luv":[67.5939766620447813,-51.7008659583180759,60.3926886051327756],"rgb":[0.266666666666666663,0.733333333333333282,0.333333333333333315],"xyz":[0.217929067969448331,0.374240676185248256,0.146697212455968229],"hpluv":[130.566112214394138,149.244617358403957,67.5939766620447813],"hsluv":[130.566112214394138,82.2871698148834412,67.5939766620447813]},"#44bb66":{"lch":[67.8192698910356313,72.5749222232247,134.657948179728322],"luv":[67.8192698910356313,-51.0109407747319139,51.6236695420221778],"rgb":[0.266666666666666663,0.733333333333333282,0.4],"xyz":[0.225514063742956489,0.377274674494651574,0.186644856863112191],"hpluv":[134.657948179728322,135.791565604529097,67.8192698910356313],"hsluv":[134.657948179728322,82.7624878443234451,67.8192698910356313]},"#44bb77":{"lch":[68.0942730594189527,65.0902087481164671,140.487577627549143],"luv":[68.0942730594189527,-50.2162275054035163,41.4133525568618168],"rgb":[0.266666666666666663,0.733333333333333282,0.466666666666666674],"xyz":[0.234828076763158422,0.38100027970273237,0.2356986587695101],"hpluv":[140.487577627549143,121.295420087000366,68.0942730594189527],"hsluv":[140.487577627549143,83.3123735080707206,68.0942730594189527]},"#44bb88":{"lch":[68.4208577329380461,57.7058903955470939,148.752185803016886],"luv":[68.4208577329380461,-49.3345927236295907,29.9343907092910229],"rgb":[0.266666666666666663,0.733333333333333282,0.533333333333333326],"xyz":[0.245968493865102222,0.385456446543509967,0.294371522173082267],"hpluv":[148.752185803016886,107.021481540968693,68.4208577329380461],"hsluv":[148.752185803016886,83.9257037652282776,68.4208577329380461]},"#44bb99":{"lch":[68.8004384509552267,51.4171630403873507,160.23039633414129],"luv":[68.8004384509552267,-48.3866530594068536,17.3912754227620781],"rgb":[0.266666666666666663,0.733333333333333282,0.6],"xyz":[0.259025457974175,0.390679232187139125,0.363138199814200147],"hpluv":[160.23039633414129,94.8322885243955,68.8004384509552267],"hsluv":[160.23039633414129,84.5895330052649683,68.8004384509552267]},"#44bbaa":{"lch":[69.2340056114394571,47.5630236168925,175.171204236910796],"luv":[69.2340056114394571,-47.3942071553531576,4.003791165451279],"rgb":[0.266666666666666663,0.733333333333333282,0.66666666666666663],"xyz":[0.274083150939427478,0.396702309373240247,0.442442049431198747],"hpluv":[175.171204236910796,87.1744714415039113,69.2340056114394571],"hsluv":[175.171204236910796,85.2901010545764251,69.2340056114394571]},"#44bbbb":{"lch":[69.722153945093,47.4463312905994243,192.177050630061103],"luv":[69.722153945093,-46.3788106784417877,-10.0080104411700219],"rgb":[0.266666666666666663,0.733333333333333282,0.733333333333333282],"xyz":[0.291220743046764152,0.403557346216175,0.532700034529840494],"hpluv":[192.177050630061103,86.3517549054621156,69.722153945093],"hsluv":[192.177050630061103,86.0137488036252,69.722153945093]},"#44bbcc":{"lch":[70.265109629848,51.5238495855336254,208.311647260201596],"luv":[70.265109629848,-45.3606162241423405,-24.4360711219862],"rgb":[0.266666666666666663,0.733333333333333282,0.8],"xyz":[0.310513118490485907,0.411274296393663807,0.63430654520011065],"hpluv":[208.311647260201596,93.0481841100277478,70.265109629848],"hsluv":[208.311647260201596,86.7476639801695484,70.265109629848]},"#44bbdd":{"lch":[70.8627576511434683,59.1258582536945,221.390354970453018],"luv":[70.8627576511434683,-44.357542252504274,-39.0931651258026491],"rgb":[0.266666666666666663,0.733333333333333282,0.866666666666666696],"xyz":[0.332031444041119395,0.419881626613917314,0.747636393100116647],"hpluv":[221.390354970453018,105.876295000483495,70.8627576511434683],"hsluv":[221.390354970453018,87.4804162985680449,70.8627576511434683]},"#44bbee":{"lch":[71.5146701379092207,69.1277260896420813,231.126492355228834],"luv":[71.5146701379092207,-43.3847784652122499,-53.8182451576511269],"rgb":[0.266666666666666663,0.733333333333333282,0.933333333333333348],"xyz":[0.35584362430729416,0.429406498720387331,0.873047209168639871],"hpluv":[231.126492355228834,122.65816352572412,71.5146701379092207],"hsluv":[231.126492355228834,88.202277385306985,71.5146701379092207]},"#44bbff":{"lch":[72.2201358507708,80.5712163793027685,238.202407995552562],"luv":[72.2201358507708,-42.4545914747530801,-68.4786723845625573],"rgb":[0.266666666666666663,0.733333333333333282,1],"xyz":[0.382014672717125525,0.439874918084320055,1.01088139746042183],"hpluv":[238.202407995552562,141.566646923483631,72.2201358507708],"hsluv":[238.202407995552562,99.9999999999976694,72.2201358507708]},"#44cc00":{"lch":[72.503692055952385,105.959797206167082,124.178253965335855],"luv":[72.503692055952385,-59.5249745926526543,87.6598883396283384],"rgb":[0.266666666666666663,0.8,0],"xyz":[0.239757627624912484,0.444130089342821943,0.0730904929806336506],"hpluv":[124.178253965335855,185.447217969921951,72.503692055952385],"hsluv":[124.178253965335855,100.000000000002359,72.503692055952385]},"#44cc11":{"lch":[72.5305637479271752,104.914943747871533,124.498982817725434],"luv":[72.5305637479271752,-59.4229434801529877,86.4642076802510928],"rgb":[0.266666666666666663,0.8,0.0666666666666666657],"xyz":[0.240769293124549616,0.444534755542676796,0.0784185979453892873],"hpluv":[124.498982817725434,183.55052269402043,72.5305637479271752],"hsluv":[124.498982817725434,98.4921383302381628,72.5305637479271752]},"#44cc22":{"lch":[72.5803335982668,103.003123626508128,125.105641856618192],"luv":[72.5803335982668,-59.2356349500081265,84.2661440252673088],"rgb":[0.266666666666666663,0.8,0.133333333333333331],"xyz":[0.242644651263026617,0.445284898798067597,0.0882954841413684799],"hpluv":[125.105641856618192,180.082189217111164,72.5803335982668],"hsluv":[125.105641856618192,95.7225658430248387,72.5803335982668]},"#44cc33":{"lch":[72.6621573160580283,99.9260617146724144,126.139923542820412],"luv":[72.6621573160580283,-58.9323161564504758,80.6982027200153],"rgb":[0.266666666666666663,0.8,0.2],"xyz":[0.245732401995484351,0.446519999091050723,0.10455763799897963],"hpluv":[126.139923542820412,174.505777504147545,72.6621573160580283],"hsluv":[126.139923542820412,91.233607132201584,72.6621573160580283]},"#44cc44":{"lch":[72.780026014363628,95.6382843785450518,127.715012949240148],"luv":[72.780026014363628,-58.5052227586060383,75.6559339961998],"rgb":[0.266666666666666663,0.8,0.266666666666666663],"xyz":[0.250190397239703266,0.448303197188738289,0.128036412951866269],"hpluv":[127.715012949240148,166.747333178852926,72.780026014363628],"hsluv":[127.715012949240148,84.9041129363740339,72.780026014363628]},"#44cc55":{"lch":[72.9371837422115732,90.1892610669535912,129.983942971096695],"luv":[72.9371837422115732,-57.9531752136704,69.1052262456084492],"rgb":[0.266666666666666663,0.8,0.333333333333333315],"xyz":[0.256152811279065251,0.45068816280448315,0.159438460225840184],"hpluv":[129.983942971096695,156.908028239254975,72.9371837422115732],"hsluv":[129.983942971096695,85.1779272269293557,72.9371837422115732]},"#44cc66":{"lch":[73.1363103507417236,83.732792729713168,133.164212643981188],"luv":[73.1363103507417236,-57.28090462038152,61.074368962666],"rgb":[0.266666666666666663,0.8,0.4],"xyz":[0.263737807052573436,0.453722161113886469,0.199386104632984118],"hpluv":[133.164212643981188,145.278670258241675,73.1363103507417236],"hsluv":[133.164212643981188,85.5122241677148764,73.1363103507417236]},"#44cc77":{"lch":[73.3796177536812309,76.5464624175537,137.569101073773794],"luv":[73.3796177536812309,-56.4983001604517625,51.6459387330839],"rgb":[0.266666666666666663,0.8,0.466666666666666674],"xyz":[0.273051820072775342,0.457447766321967264,0.248439906539382027],"hpluv":[137.569101073773794,132.369828459728325,73.3796177536812309],"hsluv":[137.569101073773794,85.9026534082125153,73.3796177536812309]},"#44cc88":{"lch":[73.6689069899719442,69.0664605730878378,143.639563525196422],"luv":[73.6689069899719442,-55.6194534086204087,40.9469459010095278],"rgb":[0.266666666666666663,0.8,0.533333333333333326],"xyz":[0.284192237174719142,0.461903933162744862,0.307112769942954222],"hpluv":[143.639563525196422,118.965846887396481,73.6689069899719442],"hsluv":[143.639563525196422,86.3428682965135863,73.6689069899719442]},"#44cc99":{"lch":[74.0056056952011,61.9424628035573548,151.940118655705163],"luv":[74.0056056952011,-54.661526046940331,29.1373689338922652],"rgb":[0.266666666666666663,0.8,0.6],"xyz":[0.297249201283791842,0.467126718806374,0.375879447584072102],"hpluv":[151.940118655705163,106.209454381597496,74.0056056952011],"hsluv":[151.940118655705163,86.8250568088678,74.0056056952011]},"#44ccaa":{"lch":[74.3907954563299256,56.0938540204294327,163.002493202880316],"luv":[74.3907954563299256,-53.6435329798001206,16.3979214631106132],"rgb":[0.266666666666666663,0.8,0.66666666666666663],"xyz":[0.312306894249044398,0.473149795992475142,0.455183297201070702],"hpluv":[163.002493202880316,95.6831366692641581,74.3907954563299256],"hsluv":[163.002493202880316,87.3405106459777727,74.3907954563299256]},"#44ccbb":{"lch":[74.8252340948823331,52.6660587979454959,176.823724318960615],"luv":[74.8252340948823331,-52.5851528012588929,2.91812511330579927],"rgb":[0.266666666666666663,0.8,0.733333333333333282],"xyz":[0.329444486356381072,0.4800048328354099,0.545441282299712449],"hpluv":[176.823724318960615,89.3145186414393493,74.8252340948823331],"hsluv":[176.823724318960615,87.8801809558037235,74.8252340948823331]},"#44cccc":{"lch":[75.3093757141467393,52.6911947618550442,192.177050630061103],"luv":[75.3093757141467393,-51.5056671360628826,-11.1143267137884898],"rgb":[0.266666666666666663,0.8,0.8],"xyz":[0.348736861800102771,0.487721783012898702,0.647047792969982605],"hpluv":[192.177050630061103,88.7826952764381758,75.3093757141467393],"hsluv":[192.177050630061103,88.4351737608208168,75.3093757141467393]},"#44ccdd":{"lch":[75.8433901234223669,56.5143539908888,206.846753698803184],"luv":[75.8433901234223669,-50.423101427505074,-25.5222069860548118],"rgb":[0.266666666666666663,0.8,0.866666666666666696],"xyz":[0.37025518735073637,0.496329113233152208,0.760377640869988602],"hpluv":[206.846753698803184,94.5540981724771257,75.8433901234223669],"hsluv":[206.846753698803184,88.9971515077065334,75.8433901234223669]},"#44ccee":{"lch":[76.4271825186181104,63.6191993934700264,219.125479385679029],"luv":[76.4271825186181104,-49.3536035237008,-40.1450414209705926],"rgb":[0.266666666666666663,0.8,0.933333333333333348],"xyz":[0.39406736761691108,0.505853985339622225,0.885788456938511826],"hpluv":[219.125479385679029,108.248092211119214,76.4271825186181104],"hsluv":[219.125479385679029,89.5586239337052,76.4271825186181104]},"#44ccff":{"lch":[77.0604138316104752,73.087044724203011,228.6232677289035],"luv":[77.0604138316104752,-48.3110621928290342,-54.8430248647743426],"rgb":[0.266666666666666663,0.8,1],"xyz":[0.420238416026742501,0.516322404703555,1.02362264523029367],"hpluv":[228.6232677289035,128.526456918779161,77.0604138316104752],"hsluv":[228.6232677289035,99.9999999999969731,77.0604138316104752]},"#44dd00":{"lch":[77.8394471675691193,114.806757868746558,124.774603647715026],"luv":[77.8394471675691193,-65.4799812263264869,94.3025116894186],"rgb":[0.266666666666666663,0.866666666666666696,0],"xyz":[0.282391618172087688,0.529398070437173462,0.0873018231630249691],"hpluv":[124.774603647715026,210.465861771712326,77.8394471675691193],"hsluv":[124.774603647715026,100.000000000002174,77.8394471675691193]},"#44dd11":{"lch":[77.8633510332093692,113.867279553553601,125.04447057905567],"luv":[77.8633510332093692,-65.3839645843072503,93.2238946202376724],"rgb":[0.266666666666666663,0.866666666666666696,0.0666666666666666657],"xyz":[0.283403283671724793,0.529802736637028371,0.0926299281277806],"hpluv":[125.04447057905567,209.014039294370775,77.8633510332093692],"hsluv":[125.04447057905567,98.7339197526847272,77.8633510332093692]},"#44dd22":{"lch":[77.9076302523257738,112.144788460185168,125.553114236235714],"luv":[77.9076302523257738,-65.2074178024426914,91.2384033306006472],"rgb":[0.266666666666666663,0.866666666666666696,0.133333333333333331],"xyz":[0.28527864181020185,0.530552879892419171,0.102506814323759798],"hpluv":[125.553114236235714,206.347170822894697,77.9076302523257738],"hsluv":[125.553114236235714,96.4050109160080382,77.9076302523257738]},"#44dd33":{"lch":[77.9804445180848802,109.362510567887881,126.41495586461761],"luv":[77.9804445180848802,-64.9207541848309546,88.0082632130877869],"rgb":[0.266666666666666663,0.866666666666666696,0.2],"xyz":[0.288366392542659555,0.531787980185402298,0.118768968181370949],"hpluv":[126.41495586461761,202.025685311970193,77.9804445180848802],"hsluv":[126.41495586461761,92.6208241654068729,77.9804445180848802]},"#44dd44":{"lch":[78.0853727898892345,105.463232003770898,127.715012949240119],"luv":[78.0853727898892345,-64.5154806081751389,83.428089194092081],"rgb":[0.266666666666666663,0.866666666666666696,0.266666666666666663],"xyz":[0.292824387786878471,0.533571178283089864,0.142247743134257587],"hpluv":[127.715012949240119,195.940425098340825,78.0853727898892345],"hsluv":[127.715012949240119,87.2650912217990395,78.0853727898892345]},"#44dd55":{"lch":[78.2253459168282888,100.46502238820301,129.562971792001804],"luv":[78.2253459168282888,-63.9887749627021662,77.4510000079714303],"rgb":[0.266666666666666663,0.866666666666666696,0.333333333333333315],"xyz":[0.298786801826240456,0.535956143898834614,0.173649790408231475],"hpluv":[129.562971792001804,188.090878204767051,78.2253459168282888],"hsluv":[129.562971792001804,87.4605090914447,78.2253459168282888]},"#44dd66":{"lch":[78.4028117957757615,94.4661355921174,132.108441056441876],"luv":[78.4028117957757615,-63.3429373931831776,70.0822592109557],"rgb":[0.266666666666666663,0.866666666666666696,0.4],"xyz":[0.306371797599748641,0.538990142208237932,0.213597434815375464],"hpluv":[132.108441056441876,178.59774401526758,78.4028117957757615],"hsluv":[132.108441056441876,87.7006053461373654,78.4028117957757615]},"#44dd77":{"lch":[78.6198227824069278,87.656024220764337,135.559861003190832],"luv":[78.6198227824069278,-62.584854150819659,61.3735660778470375],"rgb":[0.266666666666666663,0.866666666666666696,0.466666666666666674],"xyz":[0.315685810619950546,0.542715747416318783,0.262651236721773373],"hpluv":[135.559861003190832,167.73117312681623,78.6198227824069278],"hsluv":[135.559861003190832,87.9831439767702221,78.6198227824069278]},"#44dd88":{"lch":[78.8780874692010201,80.3346414261830404,140.206181380764804],"luv":[78.8780874692010201,-61.7253288138421823,51.416324216113189],"rgb":[0.266666666666666663,0.866666666666666696,0.533333333333333326],"xyz":[0.326826227721894347,0.547171914257096326,0.321324100125345513],"hpluv":[140.206181380764804,155.961921377148798,78.8780874692010201],"hsluv":[140.206181380764804,88.3044935606717729,78.8780874692010201]},"#44dd99":{"lch":[79.1790042342924,72.9438114093828602,146.430978952194238],"luv":[79.1790042342924,-60.7782665628728651,40.3336328210091182],"rgb":[0.266666666666666663,0.866666666666666696,0.6],"xyz":[0.339883191830967046,0.552394699900725539,0.390090777766463448],"hpluv":[146.430978952194238,144.047423549525234,79.1790042342924],"hsluv":[146.430978952194238,88.6599152631773109,79.1790042342924]},"#44ddaa":{"lch":[79.5236849812282,66.109750002698334,154.681927012774025],"luv":[79.5236849812282,-59.7597565852220498,28.2713731236083063],"rgb":[0.266666666666666663,0.866666666666666696,0.66666666666666663],"xyz":[0.354940884796219602,0.558417777086826606,0.469394627383462049],"hpluv":[154.681927012774025,133.15854000611057,79.5236849812282],"hsluv":[154.681927012774025,89.0438856180527267,79.5236849812282]},"#44ddbb":{"lch":[79.9129735834354733,60.6712530747818448,165.306614809553963],"luv":[79.9129735834354733,-58.687123678359157,15.3890371376899697],"rgb":[0.266666666666666663,0.866666666666666696,0.733333333333333282],"xyz":[0.372078476903556277,0.565272813929761364,0.55965261248210374],"hpluv":[165.306614809553963,125.005338667233715,79.9129735834354733],"hsluv":[165.306614809553963,89.4504295982059574,79.9129735834354733]},"#44ddcc":{"lch":[80.3474616163736783,57.6077690930220925,178.158710030216184],"luv":[80.3474616163736783,-57.5780241737671616,1.85099760130491053],"rgb":[0.266666666666666663,0.866666666666666696,0.8],"xyz":[0.391370852347278,0.572989764107250221,0.661259123152373895],"hpluv":[178.158710030216184,121.786592068950441,80.3474616163736783],"hsluv":[178.158710030216184,89.8734379183952399,80.3474616163736783]},"#44dddd":{"lch":[80.8275029051271758,57.7489755309586,192.177050630061132],"luv":[80.8275029051271758,-56.4496501662069505,-12.1811810177875159],"rgb":[0.266666666666666663,0.866666666666666696,0.866666666666666696],"xyz":[0.412889177897911575,0.581597094327503727,0.774588971052379893],"hpluv":[192.177050630061132,125.674721736272474,80.8275029051271758],"hsluv":[192.177050630061132,90.3069463225795204,80.8275029051271758]},"#44ddee":{"lch":[81.3532277894993143,61.361693698739991,205.642938459455962],"luv":[81.3532277894993143,-55.3180860243278758,-26.5549771640468073],"rgb":[0.266666666666666663,0.866666666666666696,0.933333333333333348],"xyz":[0.436701358164086284,0.591121966433973745,0.899999787120903116],"hpluv":[205.642938459455962,137.939634766348263,81.3532277894993143],"hsluv":[205.642938459455962,90.7453615563817806,81.3532277894993143]},"#44ddff":{"lch":[81.9245576129038113,68.0382655080336463,217.195369709248553],"luv":[81.9245576129038113,-54.1978382178125813,-41.1314953029609],"rgb":[0.266666666666666663,0.866666666666666696,1],"xyz":[0.462872406573917705,0.601590385797906468,1.03783397541268507],"hpluv":[217.195369709248553,158.576151866946,81.9245576129038113],"hsluv":[217.195369709248553,99.9999999999957367,81.9245576129038113]},"#44ee00":{"lch":[83.112739541513335,123.476763986331008,125.23710114083579],"luv":[83.112739541513335,-71.241317589729718,100.852297507867192],"rgb":[0.266666666666666663,0.933333333333333348,0],"xyz":[0.329570394512602505,0.623755623118204428,0.103028081943196154],"hpluv":[125.23710114083579,311.240798427125753,83.112739541513335],"hsluv":[125.23710114083579,100.000000000002402,83.112739541513335]},"#44ee11":{"lch":[83.1341682891089135,122.626446998812852,125.466600012922257],"luv":[83.1341682891089135,-71.1513320296005674,99.8735873690646656],"rgb":[0.266666666666666663,0.933333333333333348,0.0666666666666666657],"xyz":[0.330582060012239609,0.624160289318059336,0.10835618690795179],"hpluv":[125.466600012922257,309.547675363147619,83.1341682891089135],"hsluv":[125.466600012922257,98.9247180409442279,83.1341682891089135]},"#44ee22":{"lch":[83.1738669889620184,121.064908518289769,125.897986234483838],"luv":[83.1738669889620184,-70.9856689153146192,98.0701120789979],"rgb":[0.266666666666666663,0.933333333333333348,0.133333333333333331],"xyz":[0.332457418150716666,0.624910432573450136,0.118233073103930983],"hpluv":[125.897986234483838,306.432309176179558,83.1738669889620184],"hsluv":[125.897986234483838,96.9444732717922,83.1738669889620184]},"#44ee33":{"lch":[83.2391611795664517,118.535427876706891,126.625494433478437],"luv":[83.2391611795664517,-70.7161072615436694,95.1308563805026921],"rgb":[0.266666666666666663,0.933333333333333348,0.2],"xyz":[0.335545168883174372,0.626145532866433263,0.134495226961542119],"hpluv":[126.625494433478437,301.369067751793693,83.2391611795664517],"hsluv":[126.625494433478437,93.7204451717133651,83.2391611795664517]},"#44ee44":{"lch":[83.3332795320092714,114.974418092600288,127.715012949240275],"luv":[83.3332795320092714,-70.3337997514069855,90.9520391649414],"rgb":[0.266666666666666663,0.933333333333333348,0.266666666666666663],"xyz":[0.340003164127393287,0.627928730964120829,0.157974001914428758],"hpluv":[127.715012949240275,294.205765091151079,83.3332795320092714],"hsluv":[127.715012949240275,89.1439564147074321,83.3332795320092714]},"#44ee55":{"lch":[83.4588814464859183,110.379279114867671,129.248151137931956],"luv":[83.4588814464859183,-69.8347997913980123,85.479155330485213],"rgb":[0.266666666666666663,0.933333333333333348,0.333333333333333315],"xyz":[0.345965578166755272,0.630313696579865579,0.189376049188402673],"hpluv":[129.248151137931956,284.901382538762221,83.4588814464859183],"hsluv":[129.248151137931956,89.2862876088480419,83.4588814464859183]},"#44ee66":{"lch":[83.6182069813856,104.810737833959209,131.33226272314829],"luv":[83.6182069813856,-69.2195888954281,78.7015837099029],"rgb":[0.266666666666666663,0.933333333333333348,0.4],"xyz":[0.353550573940263457,0.633347694889268897,0.229323693595546635],"hpluv":[131.33226272314829,273.53562680177663,83.6182069813856],"hsluv":[131.33226272314829,89.462046779026835,83.6182069813856]},"#44ee77":{"lch":[83.8131566406418642,98.3993759238413759,134.112401675041724],"luv":[83.8131566406418642,-68.4926783274834889,70.6483559449852123],"rgb":[0.266666666666666663,0.933333333333333348,0.466666666666666674],"xyz":[0.362864586960465363,0.637073300097349748,0.278377495501944572],"hpluv":[134.112401675041724,260.333399951005049,83.8131566406418642],"hsluv":[134.112401675041724,89.6701381262035682,83.8131566406418642]},"#44ee88":{"lch":[84.045338735079568,91.3569443918750892,137.785521400150031],"luv":[84.045338735079568,-67.6621349200187439,61.3834406553211949],"rgb":[0.266666666666666663,0.933333333333333348,0.533333333333333326],"xyz":[0.374005004062409163,0.641529466938127291,0.337050358905516712],"hpluv":[137.785521400150031,245.709311488591595,84.045338735079568],"hsluv":[137.785521400150031,89.9084899734552323,84.045338735079568]},"#44ee99":{"lch":[84.3160998906388386,83.9946679616676306,142.613931790318958],"luv":[84.3160998906388386,-66.738995210465,51.0001055321292895],"rgb":[0.266666666666666663,0.933333333333333348,0.6],"xyz":[0.387061968171481863,0.646752252581756504,0.405817036546634591],"hpluv":[142.613931790318958,230.343048149298568,84.3160998906388386],"hsluv":[142.613931790318958,90.1742147406472725,84.3160998906388386]},"#44eeaa":{"lch":[84.626546237332235,76.7502660373389887,148.925817786423067],"luv":[84.626546237332235,-65.7365837009088239,39.6144531722415607],"rgb":[0.266666666666666663,0.933333333333333348,0.66666666666666663],"xyz":[0.402119661136734419,0.652775329767857571,0.485120886163633247],"hpluv":[148.925817786423067,215.298316825794302,84.626546237332235],"hsluv":[148.925817786423067,90.4637941794664897,84.626546237332235]},"#44eebb":{"lch":[84.9775593290447,70.218708007349818,157.069253127653155],"luv":[84.9775593290447,-64.6697768267590618,27.3584889823731068],"rgb":[0.266666666666666663,0.933333333333333348,0.733333333333333282],"xyz":[0.419257253244071093,0.659630366610792329,0.575378871262274938],"hpluv":[157.069253127653155,202.183693696822303,84.9775593290447],"hsluv":[157.069253127653155,90.7732788992861401,84.9775593290447]},"#44eecc":{"lch":[85.3698091329633826,65.1592886039499462,167.256585364158155],"luv":[85.3698091329633826,-63.5542641697608914,14.3731832665241086],"rgb":[0.266666666666666663,0.933333333333333348,0.8],"xyz":[0.438549628687792792,0.667347316788281186,0.676985381932545094],"hpluv":[167.256585364158155,193.290067765431047,85.3698091329633826],"hsluv":[167.256585364158155,91.0984884260964,85.3698091329633826]},"#44eedd":{"lch":[85.803765500838054,62.4110099600490216,179.263728091065275],"luv":[85.803765500838054,-62.4058570040272613,0.801982435119061421],"rgb":[0.266666666666666663,0.933333333333333348,0.866666666666666696],"xyz":[0.460067954238426391,0.675954647008534693,0.790315229832551092],"hpluv":[179.263728091065275,191.499842549603557,85.803765500838054],"hsluv":[179.263728091065275,91.4351983708881875,85.803765500838054]},"#44eeee":{"lch":[86.2797089909746546,62.6494691870182407,192.17705063006116],"luv":[86.2797089909746546,-61.2398849709435922,-13.2148582346064085],"rgb":[0.266666666666666663,0.933333333333333348,0.933333333333333348],"xyz":[0.4838801345046011,0.68547951911500471,0.915726045901074315],"hpluv":[192.17705063006116,199.700166684316315,86.2797089909746546],"hsluv":[192.17705063006116,91.7793037580661775,86.2797089909746546]},"#44eeff":{"lch":[86.7977415696122847,66.0848691943621134,204.633388514668525],"luv":[86.7977415696122847,-60.0707080483631159,-27.5448719547627086],"rgb":[0.266666666666666663,0.933333333333333348,1],"xyz":[0.510051182914432522,0.695947938478937433,1.05356023419285627],"hpluv":[204.633388514668525,219.870556477974674,86.7977415696122847],"hsluv":[204.633388514668525,99.9999999999936904,86.7977415696122847]},"#44ff00":{"lch":[88.3264513606833,131.987460278186802,125.602389702763816],"luv":[88.3264513606833,-76.837408418496949,107.315899745634312],"rgb":[0.266666666666666663,1,0],"xyz":[0.381422766942276337,0.727460367977553535,0.120312206086420265],"hpluv":[125.602389702763816,502.990651378155178,88.3264513606833],"hsluv":[125.602389702763816,100.000000000002331,88.3264513606833]},"#44ff11":{"lch":[88.3457924202418496,131.213348009411362,125.799444038401859],"luv":[88.3457924202418496,-76.7532223203665609,106.423143908077066],"rgb":[0.266666666666666663,1,0.0666666666666666657],"xyz":[0.382434432441913441,0.727865034177408443,0.125640311051175901],"hpluv":[125.799444038401859,500.950310911531346,88.3457924202418496],"hsluv":[125.799444038401859,99.9999999999917577,88.3457924202418496]},"#44ff22":{"lch":[88.3816266358799538,129.789896608084,126.169061428897493],"luv":[88.3816266358799538,-76.5980824061806089,104.776672180562713],"rgb":[0.266666666666666663,1,0.133333333333333331],"xyz":[0.384309790580390498,0.728615177432799244,0.13551719724715508],"hpluv":[126.169061428897493,497.190929074143924,88.3816266358799538],"hsluv":[126.169061428897493,99.9999999999915445,88.3816266358799538]},"#44ff33":{"lch":[88.4405736189592204,127.478814054469,126.790121098902588],"luv":[88.4405736189592204,-76.3452168675528071,102.089450454884],"rgb":[0.266666666666666663,1,0.2],"xyz":[0.387397541312848204,0.72985027772578237,0.15177935110476623],"hpluv":[126.790121098902588,491.06642972530841,88.4405736189592204],"hsluv":[126.790121098902588,99.9999999999916,88.4405736189592204]},"#44ff44":{"lch":[88.5255621746627099,124.213522374992053,127.715012949240247],"luv":[88.5255621746627099,-75.9856771103925,98.2607552122302],"rgb":[0.266666666666666663,1,0.266666666666666663],"xyz":[0.391855536557067119,0.731633475823469936,0.175258126057652869],"hpluv":[127.715012949240247,482.369437382385513,88.5255621746627099],"hsluv":[127.715012949240247,99.9999999999915872,88.5255621746627099]},"#44ff55":{"lch":[88.6390158335401,119.977757557138,129.006344472088813],"luv":[88.6390158335401,-75.5147735105559832,93.2318684253877734],"rgb":[0.266666666666666663,1,0.333333333333333315],"xyz":[0.397817950596429104,0.734018441439214686,0.206660173331626784],"hpluv":[129.006344472088813,471.012302242813519,88.6390158335401],"hsluv":[129.006344472088813,99.9999999999916724,88.6390158335401]},"#44ff66":{"lch":[88.7829895920100256,114.806361082699226,130.743859599912923],"luv":[88.7829895920100256,-74.9316504675157518,86.9813100801842438],"rgb":[0.266666666666666663,1,0.4],"xyz":[0.405402946369937289,0.737052439748618,0.246607817738770746],"hpluv":[130.743859599912923,457.03528250903878,88.7829895920100256],"hsluv":[130.743859599912923,99.999999999991374,88.7829895920100256]},"#44ff77":{"lch":[88.9592430558717524,108.789243130847709,133.032335199193767],"luv":[88.9592430558717524,-74.2389756563468239,79.5215311376676226],"rgb":[0.266666666666666663,1,0.466666666666666674],"xyz":[0.414716959390139195,0.740778044956698856,0.295661619645168683],"hpluv":[133.032335199193767,440.631455855157412,88.9592430558717524],"hsluv":[133.032335199193767,99.999999999991374,88.9592430558717524]},"#44ff88":{"lch":[89.1692840038805343,102.078340317719523,136.01097660716411],"luv":[89.1692840038805343,-73.4425963051882462,70.8955048643657904],"rgb":[0.266666666666666663,1,0.533333333333333326],"xyz":[0.425857376492083,0.745234211797476398,0.354334483048740823],"hpluv":[136.01097660716411,422.1930512248951,89.1692840038805343],"hsluv":[136.01097660716411,99.9999999999912177,89.1692840038805343]},"#44ff99":{"lch":[89.4143964062191117,94.8987049380611438,139.863519733640288],"luv":[89.4143964062191117,-72.5511163277215303,61.1727040314764139],"rgb":[0.266666666666666663,1,0.6],"xyz":[0.43891434060115575,0.750456997441105611,0.423101160689858702],"hpluv":[139.863519733640288,402.3908266141122,89.4143964062191117],"hsluv":[139.863519733640288,99.9999999999912,89.4143964062191117]},"#44ffaa":{"lch":[89.695659684091666,87.5652599917726207,144.82485232612342],"luv":[89.695659684091666,-71.5753927145854192,50.4444042008586777],"rgb":[0.266666666666666663,1,0.66666666666666663],"xyz":[0.453972033566408251,0.756480074627206678,0.502405010306857358],"hpluv":[144.82485232612342,382.304282325397367,89.695659684091666],"hsluv":[144.82485232612342,99.9999999999909335,89.695659684091666]},"#44ffbb":{"lch":[90.0139628620153616,80.5050918065685153,151.171682460988421],"luv":[90.0139628620153616,-70.527972915407986,38.8184858440859557],"rgb":[0.266666666666666663,1,0.733333333333333282],"xyz":[0.471109625673744925,0.763335111470141436,0.592662995405499],"hpluv":[151.171682460988421,363.621116250194575,90.0139628620153616],"hsluv":[151.171682460988421,99.999999999990834,90.0139628620153616]},"#44ffcc":{"lch":[90.3700157308713443,74.2777558665274853,159.169074542576084],"luv":[90.3700157308713443,-69.4225064855060481,26.4140229771485018],"rgb":[0.266666666666666663,1,0.8],"xyz":[0.490402001117466679,0.771052061647630294,0.694269506075769205],"hpluv":[159.169074542576084,348.900804743837909,90.3700157308713443],"hsluv":[159.169074542576084,99.9999999999905924,90.3700157308713443]},"#44ffdd":{"lch":[90.7643583149998,69.56728840997188,168.931262835156701],"luv":[90.7643583149998,-68.2731674827513899,13.3559806299794577],"rgb":[0.266666666666666663,1,0.866666666666666696],"xyz":[0.511920326668100167,0.7796593918678838,0.807599353975775203],"hpluv":[168.931262835156701,341.810509676969502,90.7643583149998],"hsluv":[168.931262835156701,99.9999999999902798,90.7643583149998]},"#44ffee":{"lch":[91.1973694573754869,67.0945142582603182,180.196137266844971],"luv":[91.1973694573754869,-67.094121132442,-0.229680249688981986],"rgb":[0.266666666666666663,1,0.933333333333333348],"xyz":[0.535732506934274877,0.789184263974353817,0.933010170044298426],"hpluv":[180.196137266844971,347.079488330816218,91.1973694573754869],"hsluv":[180.196137266844971,99.999999999989825,91.1973694573754869]},"#44ffff":{"lch":[91.6692750397398726,67.4158875874256,192.177050630061103],"luv":[91.6692750397398726,-65.8990611515587261,-14.2202545175369188],"rgb":[0.266666666666666663,1,1],"xyz":[0.561903555344106298,0.799652683338286541,1.07084435833608027],"hpluv":[192.177050630061103,369.886157390881351,91.6692750397398726],"hsluv":[192.177050630061103,99.9999999999897,91.6692750397398726]},"#33aa00":{"lch":[61.1785977172963129,90.1064171712311435,124.683940112874311],"luv":[61.1785977172963129,-51.2749716142469723,74.09482911373847],"rgb":[0.2,0.66666666666666663,0],"xyz":[0.157393059993970491,0.294521282349826385,0.0485535951906325494],"hpluv":[124.683940112874311,186.894073454811917,61.1785977172963129],"hsluv":[124.683940112874311,100.000000000002302,61.1785977172963129]},"#33aa11":{"lch":[61.2139288108167818,88.7849168066190089,125.171000261233829],"luv":[61.2139288108167818,-51.1417680861379793,72.5760360544852148],"rgb":[0.2,0.66666666666666663,0.0666666666666666657],"xyz":[0.158404725493607623,0.294925948549681238,0.0538817001553881791],"hpluv":[125.171000261233829,184.046797309440706,61.2139288108167818],"hsluv":[125.171000261233829,97.729263879491441,61.2139288108167818]},"#33aa22":{"lch":[61.2793378507832642,86.3832953662584657,126.10140218084841],"luv":[61.2793378507832642,-50.8984310656693708,69.7955831939783593],"rgb":[0.2,0.66666666666666663,0.133333333333333331],"xyz":[0.160280083632084625,0.295676091805072039,0.0637585863513673717],"hpluv":[126.10140218084841,178.877217305585333,61.2793378507832642],"hsluv":[126.10140218084841,93.5778090815338146,61.2793378507832642]},"#33aa33":{"lch":[61.3867923044640946,82.5646745763668548,127.715012949240119],"luv":[61.3867923044640946,-50.5076466968263134,65.3138814728533],"rgb":[0.2,0.66666666666666663,0.2],"xyz":[0.163367834364542386,0.296911192098055166,0.0800207402089785219],"hpluv":[127.715012949240119,170.670578118814461,61.3867923044640946],"hsluv":[127.715012949240119,86.9017438736093339,61.3867923044640946]},"#33aa44":{"lch":[61.5414071550205364,77.3485744588317488,130.237764523164799],"luv":[61.5414071550205364,-49.9641607354037305,59.0456146789935588],"rgb":[0.2,0.66666666666666663,0.266666666666666663],"xyz":[0.167825829608761246,0.298694390195742732,0.10349951516186516],"hpluv":[130.237764523164799,159.486606837004757,61.5414071550205364],"hsluv":[130.237764523164799,87.1702267355774723,61.5414071550205364]},"#33aa55":{"lch":[61.7472402279952775,70.9239260559490106,134.00596147156574],"luv":[61.7472402279952775,-49.2732069613111605,51.0132763399638876],"rgb":[0.2,0.66666666666666663,0.333333333333333315],"xyz":[0.173788243648123231,0.301079355811487592,0.134901562435839062],"hpluv":[134.00596147156574,145.752006815371971,61.7472402279952775],"hsluv":[134.00596147156574,87.512567621072165,61.7472402279952775]},"#33aa66":{"lch":[62.0075227235960824,63.6834089970413046,139.532932917076664],"luv":[62.0075227235960824,-48.4490087982300253,41.3312246123130436],"rgb":[0.2,0.66666666666666663,0.4],"xyz":[0.181373239421631416,0.304113354120890911,0.174849206842983024],"hpluv":[139.532932917076664,130.323054003441854,62.0075227235960824],"hsluv":[139.532932917076664,87.9225345315596769,62.0075227235960824]},"#33aa77":{"lch":[62.3247799262656201,56.2910074750267,147.571074265173024],"luv":[62.3247799262656201,-47.5128361285441727,30.1862207898839152],"rgb":[0.2,0.66666666666666663,0.466666666666666674],"xyz":[0.190687252441833321,0.307838959328971706,0.223903008749380933],"hpluv":[147.571074265173024,114.608702125460667,62.3247799262656201],"hsluv":[147.571074265173024,88.3905588997681519,62.3247799262656201]},"#33aa88":{"lch":[62.7009046876535052,49.786919253891476,159.033972270618222],"luv":[62.7009046876535052,-46.4906641824602147,17.8144736848221363],"rgb":[0.2,0.66666666666666663,0.533333333333333326],"xyz":[0.201827669543777177,0.312295126169749304,0.2825758721529531],"hpluv":[159.033972270618222,100.758286424528237,62.7009046876535052],"hsluv":[159.033972270618222,88.9048289963628804,62.7009046876535052]},"#33aa99":{"lch":[63.1372095297142835,45.6309193537352797,174.368717478757389],"luv":[63.1372095297142835,-45.4107033068770818,4.47759156711236095],"rgb":[0.2,0.66666666666666663,0.6],"xyz":[0.214884633652849877,0.317517911813378462,0.351342549794071035],"hpluv":[174.368717478757389,91.7092542399893631,63.1372095297142835],"hsluv":[174.368717478757389,89.4524406674979,63.1372095297142835]},"#33aaaa":{"lch":[63.6344696573538897,45.3208071547743288,192.17705063006116],"luv":[63.6344696573538897,-44.3011098571894,-9.5596666563997],"rgb":[0.2,0.66666666666666663,0.66666666666666663],"xyz":[0.229942326618102433,0.323540988999479584,0.430646399411069636],"hpluv":[192.17705063006116,90.3742140686623117,63.6344696573538897],"hsluv":[192.17705063006116,90.0204628815860559,63.6344696573538897]},"#33aabb":{"lch":[64.1929631055189844,49.4317459506583177,209.109442205543161],"luv":[64.1929631055189844,-43.188124160558381,-24.0475245965695663],"rgb":[0.2,0.66666666666666663,0.733333333333333282],"xyz":[0.247079918725439052,0.330396025842414343,0.520904384509711327],"hpluv":[209.109442205543161,97.7142389408223835,64.1929631055189844],"hsluv":[209.109442205543161,90.5968047396532228,64.1929631055189844]},"#33aacc":{"lch":[64.8125111239688181,57.2242456540803062,222.641155468482083],"luv":[64.8125111239688181,-42.0947673064025736,-38.7639633693247347],"rgb":[0.2,0.66666666666666663,0.8],"xyz":[0.266372294169160806,0.338112976019903144,0.622510895179981483],"hpluv":[222.641155468482083,112.036763534802631,64.8125111239688181],"hsluv":[222.641155468482083,91.1708232266795875,64.8125111239688181]},"#33aadd":{"lch":[65.4925201274692199,67.4454999587780151,232.519386199289158],"luv":[65.4925201274692199,-41.0401119544032653,-53.5220017886062465],"rgb":[0.2,0.66666666666666663,0.866666666666666696],"xyz":[0.28789061971979435,0.34672030624015665,0.73584074307998748],"hpluv":[232.519386199289158,130.67743538587149,65.4925201274692199],"hsluv":[232.519386199289158,91.7336648454097485,65.4925201274692199]},"#33aaee":{"lch":[66.23202547083838,79.0605595482254,239.573325902293959],"luv":[66.23202547083838,-40.039054494753934,-68.1721804788773],"rgb":[0.2,0.66666666666666663,0.933333333333333348],"xyz":[0.311702799985969059,0.356245178346626667,0.861251559148510704],"hpluv":[239.573325902293959,151.471586303299148,66.23202547083838],"hsluv":[239.573325902293959,92.278374899274425,66.23202547083838]},"#33aaff":{"lch":[67.0297366624436,91.3892467801412778,244.667711773110682],"luv":[67.0297366624436,-39.1024682991195291,-82.6014007142609898],"rgb":[0.2,0.66666666666666663,1],"xyz":[0.33787384839580048,0.366713597710559391,0.999085747440292549],"hpluv":[244.667711773110682,173.00828905748071,67.0297366624436],"hsluv":[244.667711773110682,99.9999999999982094,67.0297366624436]},"#33bb00":{"lch":[66.705199456007648,99.1588934495857757,125.274120260315158],"luv":[66.705199456007648,-57.2631629787864327,80.9531735993793262],"rgb":[0.2,0.733333333333333282,0],"xyz":[0.191347557902569271,0.362430278167024944,0.0598717611601651684],"hpluv":[125.274120260315158,188.630237299381349,66.705199456007648],"hsluv":[125.274120260315158,100.000000000002331,66.705199456007648]},"#33bb11":{"lch":[66.7359690986495764,97.9890755357957914,125.670572132139952],"luv":[66.7359690986495764,-57.1397853669544133,79.6046723036925385],"rgb":[0.2,0.733333333333333282,0.0666666666666666657],"xyz":[0.192359223402206403,0.362834944366879797,0.0651998661249208],"hpluv":[125.670572132139952,186.318944611331347,66.7359690986495764],"hsluv":[125.670572132139952,98.1524285745497451,66.7359690986495764]},"#33bb22":{"lch":[66.7929473545782,95.8553977164860243,126.423299967719473],"luv":[66.7929473545782,-56.9137739802675,77.1302768224563],"rgb":[0.2,0.733333333333333282,0.133333333333333331],"xyz":[0.194234581540683404,0.363585087622270597,0.0750767523209],"hpluv":[126.423299967719473,182.106434833594022,66.7929473545782],"hsluv":[126.423299967719473,94.7659081903439073,66.7929473545782]},"#33bb33":{"lch":[66.8865907457163,92.4406335233364302,127.715012949240233],"luv":[66.8865907457163,-56.5491099236273058,73.126389853740946],"rgb":[0.2,0.733333333333333282,0.2],"xyz":[0.197322332273141166,0.364820187915253724,0.0913389061785111478],"hpluv":[127.715012949240233,175.373180985258983,66.8865907457163],"hsluv":[127.715012949240233,89.2962069049265637,66.8865907457163]},"#33bb44":{"lch":[67.0214179407225572,87.725631811763563,129.70178400392939],"luv":[67.0214179407225572,-56.0384119529137763,67.4943172612971409],"rgb":[0.2,0.733333333333333282,0.266666666666666663],"xyz":[0.201780327517360025,0.36660338601294129,0.114817681131397786],"hpluv":[129.70178400392939,166.093340387543549,67.0214179407225572],"hsluv":[129.70178400392939,89.4761749642590871,67.0214179407225572]},"#33bb55":{"lch":[67.2010629421400552,81.8171313208689099,132.60288320444127],"luv":[67.2010629421400552,-55.3830806540106479,60.2225651632978796],"rgb":[0.2,0.733333333333333282,0.333333333333333315],"xyz":[0.207742741556722,0.368988351628686151,0.146219728405371674],"hpluv":[132.60288320444127,154.492511096020365,67.2010629421400552],"hsluv":[132.60288320444127,89.7076242739581,67.2010629421400552]},"#33bb66":{"lch":[67.4284803792762091,74.9653268862145,136.738510871982356],"luv":[67.4284803792762091,-54.5922668909562248,51.3759148907695788],"rgb":[0.2,0.733333333333333282,0.4],"xyz":[0.215327737330230196,0.372022349938089469,0.186167372812515663],"hpluv":[136.738510871982356,141.07705768332076,67.4284803792762091],"hsluv":[136.738510871982356,89.9877463438330096,67.4284803792762091]},"#33bb77":{"lch":[67.7060530794905446,67.5982244112705,142.572908280802977],"luv":[67.7060530794905446,-53.681598162732449,41.0829156980295878],"rgb":[0.2,0.733333333333333282,0.466666666666666674],"xyz":[0.224641750350432101,0.375747955146170265,0.235221174718913573],"hpluv":[142.572908280802977,126.69139486293237,67.7060530794905446],"hsluv":[142.572908280802977,90.3115397167098,67.7060530794905446]},"#33bb88":{"lch":[68.0356563096068641,60.380187227113133,150.730801091974854],"luv":[68.0356563096068641,-52.67158330257773,29.5206931148449],"rgb":[0.2,0.733333333333333282,0.533333333333333326],"xyz":[0.235782167452375957,0.380204121986947863,0.293894038122485712],"hpluv":[150.730801091974854,112.615249481580875,68.0356563096068641],"hsluv":[150.730801091974854,90.6723452470342437,68.0356563096068641]},"#33bb99":{"lch":[68.4187011865960244,54.2829584497859159,161.862695711717],"luv":[68.4187011865960244,-51.585814888834193,16.8980259295610082],"rgb":[0.2,0.733333333333333282,0.6],"xyz":[0.248839131561448657,0.385426907630577,0.362660715763603647],"hpluv":[161.862695711717,100.676477021468287,68.4187011865960244],"hsluv":[161.862695711717,91.0624469223214,68.4187011865960244]},"#33bbaa":{"lch":[68.8561680799326439,50.5661966451060749,176.101011456941364],"luv":[68.8561680799326439,-50.4491601398581224,3.43838397135738649],"rgb":[0.2,0.733333333333333282,0.66666666666666663],"xyz":[0.263896824526701212,0.391449984816678143,0.441964565380602248],"hpluv":[176.101011456941364,93.1873079321678404,68.8561680799326439],"hsluv":[176.101011456941364,91.473675634614068,68.8561680799326439]},"#33bbbb":{"lch":[69.3486356756669835,50.4205674478029,192.177050630061103],"luv":[69.3486356756669835,-49.286127891295429,-10.635375839212843],"rgb":[0.2,0.733333333333333282,0.733333333333333282],"xyz":[0.281034416634037831,0.398305021659612901,0.532222550479243939],"hpluv":[192.177050630061103,92.2590830970113132,69.3486356756669835],"hsluv":[192.177050630061103,91.8979539795913922,69.3486356756669835]},"#33bbcc":{"lch":[69.8963087653012423,54.2786660468549442,207.559867588447844],"luv":[69.8963087653012423,-48.1195504219082224,-25.1133919457216273],"rgb":[0.2,0.733333333333333282,0.8],"xyz":[0.300326792077759586,0.406021971837101703,0.633829061149514095],"hpluv":[207.559867588447844,98.540384199822455,69.8963087653012423],"hsluv":[207.559867588447844,92.3277362004695306,69.8963087653012423]},"#33bbdd":{"lch":[70.4990463576295241,61.569428837921933,220.28187220447964],"luv":[70.4990463576295241,-46.9696505240293618,-39.807618580850594],"rgb":[0.2,0.733333333333333282,0.866666666666666696],"xyz":[0.321845117628393129,0.414629302057355209,0.747158909049520092],"hpluv":[220.28187220447964,110.820781636478685,70.4990463576295241],"hsluv":[220.28187220447964,92.7563200135089119,70.4990463576295241]},"#33bbee":{"lch":[71.1563908243766576,71.2672074810155181,229.953995552192254],"luv":[71.1563908243766576,-45.8534981630350487,-54.557048750410388],"rgb":[0.2,0.733333333333333282,0.933333333333333348],"xyz":[0.345657297894567894,0.424154174163825226,0.872569725118043316],"hpluv":[229.953995552192254,127.091105244163856,71.1563908243766576],"hsluv":[229.953995552192254,93.1780289437208893,71.1563908243766576]},"#33bbff":{"lch":[71.8675982303626597,82.4526478797043296,237.101125866277243],"luv":[71.8675982303626597,-44.7848112977892,-69.2297610814592161],"rgb":[0.2,0.733333333333333282,1],"xyz":[0.37182834630439926,0.43462259352775795,1.01040391340982527],"hpluv":[237.101125866277243,145.583046200088774,71.8675982303626597],"hsluv":[237.101125866277243,99.9999999999977831,71.8675982303626597]},"#33cc00":{"lch":[72.1534232831706532,108.011475964841438,125.713046635977918],"luv":[72.1534232831706532,-63.0491190384013507,87.6999859098336287],"rgb":[0.2,0.8,0],"xyz":[0.229571301212186191,0.438877764786259839,0.0726130089300371234],"hpluv":[125.713046635977918,189.955680955455,72.1534232831706532],"hsluv":[125.713046635977918,100.000000000002402,72.1534232831706532]},"#33cc11":{"lch":[72.1805088449519,106.967132064598133,126.040754358939225],"luv":[72.1805088449519,-62.9352412435677095,86.493483868665578],"rgb":[0.2,0.8,0.0666666666666666657],"xyz":[0.230582966711823323,0.439282430986114691,0.0779411138947927601],"hpluv":[126.040754358939225,188.048441784684599,72.1805088449519],"hsluv":[126.040754358939225,98.4728126855506645,72.1805088449519]},"#33cc22":{"lch":[72.2306742907645543,105.057034533260762,126.660198785960176],"luv":[72.2306742907645543,-62.7261976516662614,84.2757653960309199],"rgb":[0.2,0.8,0.133333333333333331],"xyz":[0.232458324850300324,0.440032574241505492,0.0878180000907719527],"hpluv":[126.660198785960176,184.562215611711281,72.2306742907645543],"hsluv":[126.660198785960176,95.6680740449206866,72.2306742907645543]},"#33cc33":{"lch":[72.31314692234902,101.984984863208481,127.715012949240304],"luv":[72.31314692234902,-62.3877173898115416,80.6765756365369668],"rgb":[0.2,0.8,0.2],"xyz":[0.235546075582758085,0.441267674534488619,0.104080153948383103],"hpluv":[127.715012949240304,178.960959976488198,72.31314692234902],"hsluv":[127.715012949240304,91.1230258822071306,72.31314692234902]},"#33cc44":{"lch":[72.4319472107582669,97.7091257880760651,129.318260791805528],"luv":[72.4319472107582669,-61.9111863445413135,75.5915224590797123],"rgb":[0.2,0.8,0.266666666666666663],"xyz":[0.240004070826976945,0.443050872632176185,0.127558928901269741],"hpluv":[129.318260791805528,171.176559629977817,72.4319472107582669],"hsluv":[129.318260791805528,91.2471619418673612,72.4319472107582669]},"#33cc55":{"lch":[72.590341240881628,92.2844112105744756,131.621023493746776],"luv":[72.590341240881628,-61.2953573189119396,68.9876200751215407],"rgb":[0.2,0.8,0.333333333333333315],"xyz":[0.24596648486633893,0.445435838247921045,0.158960976175243629],"hpluv":[131.621023493746776,161.32023063104279,72.590341240881628],"hsluv":[131.621023493746776,91.4078622695478,72.590341240881628]},"#33cc66":{"lch":[72.7910248315973405,85.8719567505974197,134.835055825888389],"luv":[72.7910248315973405,-60.5455878238572112,60.8951948123993319],"rgb":[0.2,0.8,0.4],"xyz":[0.253551480639847115,0.448469836557324364,0.198908620582387619],"hpluv":[134.835055825888389,149.696915507144809,72.7910248315973405],"hsluv":[134.835055825888389,91.6039613293452533,72.7910248315973405]},"#33cc77":{"lch":[73.0362204241858421,78.757716060864837,139.259917231121676],"luv":[73.0362204241858421,-59.6729854923348,51.3995393126768079],"rgb":[0.2,0.8,0.466666666666666674],"xyz":[0.262865493660049,0.452195441765405159,0.247962422488785528],"hpluv":[139.259917231121676,136.834039856532058,73.0362204241858421],"hsluv":[139.259917231121676,91.8328510325735294,73.0362204241858421]},"#33cc88":{"lch":[73.3277345291399,71.3846311778678597,145.306874573990314],"luv":[73.3277345291399,-58.6933246064594201,40.6307668527313197],"rgb":[0.2,0.8,0.533333333333333326],"xyz":[0.274005910761992877,0.456651608606182757,0.306635285892357667],"hpluv":[145.306874573990314,123.530949311180805,73.3277345291399],"hsluv":[145.306874573990314,92.0907512285691894,73.3277345291399]},"#33cc99":{"lch":[73.6669954969027714,64.400374936046,153.483372150156],"luv":[73.6669954969027714,-57.6257667092137709,28.7520312861295437],"rgb":[0.2,0.8,0.6],"xyz":[0.287062874871065576,0.461874394249811915,0.375401963533475602],"hpluv":[153.483372150156,110.931469165383049,73.6669954969027714],"hsluv":[153.483372150156,92.3730273510429072,73.6669954969027714]},"#33ccaa":{"lch":[74.0550811623464114,58.6991946004706691,164.236139418897579],"luv":[74.0550811623464114,-56.4914910882685106,15.9470022690160835],"rgb":[0.2,0.8,0.66666666666666663],"xyz":[0.302120567836318132,0.467897471435913037,0.454705813150474203],"hpluv":[164.236139418897579,100.581152280716978,74.0550811623464114],"hsluv":[164.236139418897579,92.6745296641919794,74.0550811623464114]},"#33ccbb":{"lch":[74.4927414449451106,55.3647402049724846,177.507530206592946],"luv":[74.4927414449451106,-55.3123621552270137,2.40770653799565881],"rgb":[0.2,0.8,0.733333333333333282],"xyz":[0.319258159943654751,0.474752508278847796,0.544963798249115894],"hpluv":[177.507530206592946,94.310193436061823,74.4927414449451106],"hsluv":[177.507530206592946,92.9899230693886,74.4927414449451106]},"#33cccc":{"lch":[74.9804187561532416,55.3552144916165361,192.177050630061132],"luv":[74.9804187561532416,-54.1097476482840918,-11.6762571422475752],"rgb":[0.2,0.8,0.8],"xyz":[0.338550535387376506,0.482469458456336597,0.646570308919386],"hpluv":[192.177050630061132,93.6806731785530928,74.9804187561532416],"hsluv":[192.177050630061132,93.3139795405001422,74.9804187561532416]},"#33ccdd":{"lch":[75.5182678303382602,59.0031963362726231,206.282454691493683],"luv":[75.5182678303382602,-52.9035678654544128,-26.1264173778571198],"rgb":[0.2,0.8,0.866666666666666696],"xyz":[0.360068860938010049,0.491076788676590104,0.759900156819392],"hpluv":[206.282454691493683,99.1431801932779564,75.5182678303382602],"hsluv":[206.282454691493683,93.6418135046530296,75.5182678303382602]},"#33ccee":{"lch":[76.106175853756767,65.8577115847402439,218.26062431545347],"luv":[76.106175853756767,-51.7116147040808585,-40.7817003063324606],"rgb":[0.2,0.8,0.933333333333333348],"xyz":[0.383881041204184759,0.500601660783060121,0.885310972887915271],"hpluv":[218.26062431545347,110.229350215344013,76.106175853756767],"hsluv":[218.26062431545347,93.969050662624,76.106175853756767]},"#33ccff":{"lch":[76.7437832939395435,75.0714180144803,227.674056146546604],"luv":[76.7437832939395435,-50.5491406549608,-55.5022718611574248],"rgb":[0.2,0.8,1],"xyz":[0.41005208961401618,0.511070080146992844,1.02314516117969712],"hpluv":[227.674056146546604,129.845560156838474,76.7437832939395435],"hsluv":[227.674056146546604,99.9999999999969731,76.7437832939395435]},"#33dd00":{"lch":[77.5280782787270653,116.686614644285086,126.047543424376144],"luv":[77.5280782787270653,-68.6649809221669187,94.3445092843369508],"rgb":[0.2,0.866666666666666696,0],"xyz":[0.272205291759361367,0.524145745880611358,0.0868243391124284419],"hpluv":[126.047543424376144,210.356208283509261,77.5280782787270653],"hsluv":[126.047543424376144,100.000000000002416,77.5280782787270653]},"#33dd11":{"lch":[77.5521415069474926,115.747372453695789,126.322097671746874],"luv":[77.5521415069474926,-68.5599423432795,93.2576459912042],"rgb":[0.2,0.866666666666666696,0.0666666666666666657],"xyz":[0.273216957258998472,0.524550412080466266,0.0921524440771840786],"hpluv":[126.322097671746874,208.932074165120611,77.5521415069474926],"hsluv":[126.322097671746874,98.7203227917640902,77.5521415069474926]},"#33dd22":{"lch":[77.5967156031793337,114.025807364398673,126.839335004613],"luv":[77.5967156031793337,-68.36681588768,91.2571270119929778],"rgb":[0.2,0.866666666666666696,0.133333333333333331],"xyz":[0.275092315397475529,0.525300555335857067,0.102029330273163271],"hpluv":[126.839335004613,206.31706664059891,77.5967156031793337],"hsluv":[126.839335004613,96.3665979525037102,77.5967156031793337]},"#33dd33":{"lch":[77.670013861504259,111.246421345384377,127.715012949240332],"luv":[77.670013861504259,-68.0532561222895,88.0029578668175247],"rgb":[0.2,0.866666666666666696,0.2],"xyz":[0.278180066129933234,0.526535655628840193,0.118291484130774421],"hpluv":[127.715012949240332,202.082466523340599,77.670013861504259],"hsluv":[127.715012949240332,92.5426273046004439,77.670013861504259]},"#33dd44":{"lch":[77.7756375941771267,107.354265763003397,129.034195217585733],"luv":[77.7756375941771267,-67.6100090567609726,83.3895979895470134],"rgb":[0.2,0.866666666666666696,0.266666666666666663],"xyz":[0.28263806137415215,0.52831885372652776,0.14177025908366106],"hpluv":[129.034195217585733,196.125875311323085,77.7756375941771267],"hsluv":[129.034195217585733,92.6304308505642098,77.7756375941771267]},"#33dd55":{"lch":[77.9165348137244,102.370875286307594,130.905664069221132],"luv":[77.9165348137244,-67.0340391276217105,77.3707548439410431],"rgb":[0.2,0.866666666666666696,0.333333333333333315],"xyz":[0.288600475413514135,0.530703819342272509,0.173172306357634975],"hpluv":[130.905664069221132,188.454179514464698,77.9165348137244],"hsluv":[130.905664069221132,92.7446831943234287,77.9165348137244]},"#33dd66":{"lch":[78.095166356878579,96.3992072274516261,133.476315028685519],"luv":[78.095166356878579,-66.3279238591037767,69.9529389705828777],"rgb":[0.2,0.866666666666666696,0.4],"xyz":[0.29618547118702232,0.533737817651675828,0.213119950764778909],"hpluv":[133.476315028685519,179.196222734944627,78.095166356878579],"hsluv":[133.476315028685519,92.8850067954864187,78.095166356878579]},"#33dd77":{"lch":[78.3135937781308513,89.6343875602499196,136.948304354896891],"luv":[78.3135937781308513,-65.499258897229538,61.1896275296294192],"rgb":[0.2,0.866666666666666696,0.466666666666666674],"xyz":[0.305499484207224226,0.537463422859756679,0.262173752671176818],"hpluv":[136.948304354896891,168.630388284117117,78.3135937781308513],"hsluv":[136.948304354896891,93.050064801238122,78.3135937781308513]},"#33dd88":{"lch":[78.5735314106716487,82.3820261839553609,141.59738099104726],"luv":[78.5735314106716487,-64.5599157920348432,51.1743638074698],"rgb":[0.2,0.866666666666666696,0.533333333333333326],"xyz":[0.316639901309168,0.541919589700534221,0.320846616074749],"hpluv":[141.59738099104726,157.233383580683977,78.5735314106716487],"hsluv":[141.59738099104726,93.2377028740416449,78.5735314106716487]},"#33dd99":{"lch":[78.8763801167060592,75.0869406053615762,147.781507566587862],"luv":[78.8763801167060592,-63.5251386535812799,40.0325543591259105],"rgb":[0.2,0.866666666666666696,0.6],"xyz":[0.329696865418240725,0.547142375344163434,0.389613293715866893],"hpluv":[147.781507566587862,145.760006886720333,78.8763801167060592],"hsluv":[147.781507566587862,93.4451205095912343,78.8763801167060592]},"#33ddaa":{"lch":[79.2232512041385633,68.3697583649377094,155.904677195463563],"luv":[79.2232512041385633,-62.4125308872686801,27.9123601138582131],"rgb":[0.2,0.866666666666666696,0.66666666666666663],"xyz":[0.344754558383493281,0.553165452530264501,0.468917143332865494],"hpluv":[155.904677195463563,135.355769729163313,79.2232512041385633],"hsluv":[155.904677195463563,93.6690625743759,79.2232512041385633]},"#33ddbb":{"lch":[79.6149850527770866,63.045401416642612,166.259028854183981],"luv":[79.6149850527770866,-61.2410113290283604,14.9753521221847095],"rgb":[0.2,0.866666666666666696,0.733333333333333282],"xyz":[0.361892150490829956,0.560020489373199259,0.559175128431507296],"hpluv":[166.259028854183981,127.658944712944631,79.6149850527770866],"hsluv":[166.259028854183981,93.9060163408359614,79.6149850527770866]},"#33ddcc":{"lch":[80.0521670478692613,60.0458591823856054,178.675787060338223],"luv":[80.0521670478692613,-60.0298228841068138,1.3876488942262355],"rgb":[0.2,0.866666666666666696,0.8],"xyz":[0.381184525934551655,0.567737439550688117,0.660781639101777452],"hpluv":[178.675787060338223,124.734340702728062,80.0521670478692613],"hsluv":[178.675787060338223,94.1523985056595905,80.0521670478692613]},"#33dddd":{"lch":[80.5351423549551555,60.1510343961145963,192.177050630061245],"luv":[80.5351423549551555,-58.7976638126828,-12.6878551809710149],"rgb":[0.2,0.866666666666666696,0.866666666666666696],"xyz":[0.402702851485185254,0.576344769770941623,0.774111487001783449],"hpluv":[192.177050630061245,128.603021497070955,80.5351423549551555],"hsluv":[192.177050630061245,94.4047190696773271,80.5351423549551555]},"#33ddee":{"lch":[81.0640304387754,63.6213092914002303,205.209077734070348],"luv":[81.0640304387754,-57.5619892131040913,-27.0977562499646396],"rgb":[0.2,0.866666666666666696,0.933333333333333348],"xyz":[0.426515031751359963,0.58586964187741164,0.899522303070306672],"hpluv":[205.209077734070348,140.476637056352985,81.0640304387754],"hsluv":[205.209077734070348,94.6597131799347835,81.0640304387754]},"#33ddff":{"lch":[81.6387398294900208,70.0938175080633528,216.50946924270437],"luv":[81.6387398294900208,-56.3385046754299452,-41.7027114680837769],"rgb":[0.2,0.866666666666666696,1],"xyz":[0.452686080161191384,0.596338061241344364,1.03735649136208852],"hpluv":[216.50946924270437,160.421433033358312,81.6387398294900208],"hsluv":[216.50946924270437,99.999999999996,81.6387398294900208]},"#33ee00":{"lch":[82.833762600699373,125.203353646442437,126.3077634478595],"luv":[82.833762600699373,-74.1357070958390239,100.894879442497455],"rgb":[0.2,0.933333333333333348,0],"xyz":[0.319384068099876184,0.618503298561642323,0.102550597892599626],"hpluv":[126.3077634478595,309.713105305240845,82.833762600699373],"hsluv":[126.3077634478595,100.000000000002302,82.833762600699373]},"#33ee11":{"lch":[82.85531245284119,124.353122892884315,126.540515263097504],"luv":[82.85531245284119,-74.0387382831010541,99.9097813362598544],"rgb":[0.2,0.933333333333333348,0.0666666666666666657],"xyz":[0.320395733599513288,0.618907964761497231,0.107878702857355263],"hpluv":[126.540515263097504,308.054239915702169,82.85531245284119],"hsluv":[126.540515263097504,98.9149262576223833,82.85531245284119]},"#33ee22":{"lch":[82.8952353009988,122.792060636983948,126.977870705292972],"luv":[82.8952353009988,-73.860225327277135,98.0946342573363808],"rgb":[0.2,0.933333333333333348,0.133333333333333331],"xyz":[0.322271091737990345,0.619658108016888,0.117755589053334456],"hpluv":[126.977870705292972,305.002845011722627,82.8952353009988],"hsluv":[126.977870705292972,96.9167682151396264,82.8952353009988]},"#33ee33":{"lch":[82.9608975691188846,120.264250910780831,127.715012949240375],"luv":[82.9608975691188846,-73.5697721383487391,95.1366316128687259],"rgb":[0.2,0.933333333333333348,0.2],"xyz":[0.325358842470448051,0.620893208309871159,0.134017742910945592],"hpluv":[127.715012949240375,300.046240285686,82.9608975691188846],"hsluv":[127.715012949240375,93.6639064416312834,82.9608975691188846]},"#33ee44":{"lch":[83.0555452014946241,116.707569363843,128.817932535493583],"luv":[83.0555452014946241,-73.1578713419028,90.9317469728687513],"rgb":[0.2,0.933333333333333348,0.266666666666666663],"xyz":[0.329816837714666966,0.622676406407558725,0.157496517863832231],"hpluv":[128.817932535493583,293.039720989359807,83.0555452014946241],"hsluv":[128.817932535493583,93.7274034182796356,83.0555452014946241]},"#33ee55":{"lch":[83.1818510898783643,112.121671621867506,130.367812557605703],"luv":[83.1818510898783643,-72.6203079673681202,85.4257579305358092],"rgb":[0.2,0.933333333333333348,0.333333333333333315],"xyz":[0.335779251754028951,0.625061372023303474,0.188898565137806146],"hpluv":[130.367812557605703,283.950089878719211,83.1818510898783643],"hsluv":[130.367812557605703,93.8103653792530139,83.1818510898783643]},"#33ee66":{"lch":[83.3420657578551,106.5703857928128,132.470647679843353],"luv":[83.3420657578551,-71.9576476395269,78.6088040502757224],"rgb":[0.2,0.933333333333333348,0.4],"xyz":[0.343364247527537136,0.628095370332706793,0.228846209544950108],"hpluv":[132.470647679843353,272.865433725808,83.3420657578551],"hsluv":[132.470647679843353,93.912785079345241,83.3420657578551]},"#33ee77":{"lch":[83.5380975272703523,100.188150337510052,135.268396470867572],"luv":[83.5380975272703523,-71.1748024762597851,70.5110839550557387],"rgb":[0.2,0.933333333333333348,0.466666666666666674],"xyz":[0.352678260547739042,0.631820975540787644,0.277900011451348],"hpluv":[135.268396470867572,260.019238129472967,83.5380975272703523],"hsluv":[135.268396470867572,94.0340074276028304,83.5380975272703523]},"#33ee88":{"lch":[83.7715600973053682,93.1909370684561651,138.951686086792108],"luv":[83.7715600973053682,-70.2805135444840801,61.1980405537673],"rgb":[0.2,0.933333333333333348,0.533333333333333326],"xyz":[0.363818677649682842,0.636277142381565186,0.336572874854920157],"hpluv":[138.951686086792108,245.83342468256393,83.7715600973053682],"hsluv":[138.951686086792108,94.1728069818675237,83.7715600973053682]},"#33ee99":{"lch":[84.0438031984902807,85.8935006436990278,143.770719305914184],"luv":[84.0438031984902807,-69.2867121669879822,50.7646035138469784],"rgb":[0.2,0.933333333333333348,0.6],"xyz":[0.376875641758755542,0.641499928025194399,0.405339552496038091],"hpluv":[143.770719305914184,230.989810482694878,84.0438031984902807],"hsluv":[143.770719305914184,94.3274826341768886,84.0438031984902807]},"#33eeaa":{"lch":[84.3559338989094698,78.7339796376561907,150.032255922422308],"luv":[84.3559338989094698,-68.2077782157370223,39.328596980513943],"rgb":[0.2,0.933333333333333348,0.66666666666666663],"xyz":[0.391933334724008098,0.647523005211295466,0.484643402113036692],"hpluv":[150.032255922422308,216.540119706931335,84.3559338989094698],"hsluv":[150.032255922422308,94.495967075681591,84.3559338989094698]},"#33eebb":{"lch":[84.7088326356722,72.2999891840671,158.051587623557367],"luv":[84.7088326356722,-67.0597412553262,27.0236847743774931],"rgb":[0.2,0.933333333333333348,0.733333333333333282],"xyz":[0.409070926831344772,0.654378042054230225,0.574901387211678383],"hpluv":[158.051587623557367,204.04938686040532,84.7088326356722],"hsluv":[158.051587623557367,94.6759444498571838,84.7088326356722]},"#33eecc":{"lch":[85.1031663228954,67.3294619946068451,168.005441410177127],"luv":[85.1031663228954,-65.8594808644086,13.992327638881461],"rgb":[0.2,0.933333333333333348,0.8],"xyz":[0.428363302275066471,0.662094992231719082,0.676507897881948539],"hpluv":[168.005441410177127,195.708498626929867,85.1031663228954],"hsluv":[168.005441410177127,94.8649680125767389,85.1031663228954]},"#33eedd":{"lch":[85.539399954776755,64.6250931348259314,179.663789762776076],"luv":[85.539399954776755,-64.6239805156479861,0.37921629457989664],"rgb":[0.2,0.933333333333333348,0.866666666666666696],"xyz":[0.44988162782570007,0.670702322451972588,0.789837745781954537],"hpluv":[179.663789762776076,194.233009793031641,85.539399954776755],"hsluv":[179.663789762776076,95.0605698730458926,85.539399954776755]},"#33eeee":{"lch":[86.0178075751720286,64.8282855412949601,192.177050630061217],"luv":[86.0178075751720286,-63.3696789602654533,-13.6744431219908602],"rgb":[0.2,0.933333333333333348,0.933333333333333348],"xyz":[0.47369380809187478,0.680227194558442605,0.91524856185047776],"hpluv":[192.177050630061217,202.327515221469156,86.0178075751720286],"hsluv":[192.177050630061217,95.2603564020327127,86.0178075751720286]},"#33eeff":{"lch":[86.538483142230433,68.1460620684978124,204.293044736593487],"luv":[86.538483142230433,-62.1119480142598803,-28.035543321245509],"rgb":[0.2,0.933333333333333348,1],"xyz":[0.499864856501706201,0.690695613922375329,1.05308275014225972],"hpluv":[204.293044736593487,221.878852364873978,86.538483142230433],"hsluv":[204.293044736593487,99.999999999993932,86.538483142230433]},"#33ff00":{"lch":[88.074762753062231,133.577745567808222,126.513803819973305],"luv":[88.074762753062231,-79.4809541468946,107.358241597361044],"rgb":[0.2,1,0],"xyz":[0.37123644052955,0.72220804342099143,0.119834722035823737],"hpluv":[126.513803819973305,497.272976699974663,88.074762753062231],"hsluv":[126.513803819973305,100.00000000000226,88.074762753062231]},"#33ff11":{"lch":[88.0941974462199,132.80363803677966,126.71317891025123],"luv":[88.0941974462199,-79.3912833442141448,106.460464045403725],"rgb":[0.2,1,0.0666666666666666657],"xyz":[0.37224810602918712,0.722612709620846339,0.125162827000579374],"hpluv":[126.71317891025123,495.277769978645495,88.0941974462199],"hsluv":[126.71317891025123,99.9999999999917861,88.0941974462199]},"#33ff22":{"lch":[88.1302050034733355,131.38040615815558,127.087058789859782],"luv":[88.1302050034733355,-79.2260405323659285,104.804797713872986],"rgb":[0.2,1,0.133333333333333331],"xyz":[0.374123464167664177,0.723362852876237139,0.135039713196558553],"hpluv":[127.087058789859782,491.602558840386564,88.1302050034733355],"hsluv":[127.087058789859782,99.9999999999915161,88.1302050034733355]},"#33ff33":{"lch":[88.1894367416410745,129.070276381710187,127.715012949240347],"luv":[88.1894367416410745,-78.9567203165017162,102.10275491931047],"rgb":[0.2,1,0.2],"xyz":[0.377211214900121883,0.724597953169220266,0.151301867054169703],"hpluv":[127.715012949240347,485.618062737129037,88.1894367416410745],"hsluv":[127.715012949240347,99.9999999999917577,88.1894367416410745]},"#33ff44":{"lch":[88.2748349985884,125.807640063387211,128.649544439126117],"luv":[88.2748349985884,-78.5738101086462137,98.2533391968394909],"rgb":[0.2,1,0.266666666666666663],"xyz":[0.381669210144340798,0.726381151266907832,0.174780642007056342],"hpluv":[128.649544439126117,477.126267833886629,88.2748349985884],"hsluv":[128.649544439126117,99.9999999999917151,88.2748349985884]},"#33ff55":{"lch":[88.3888340150102181,121.57774004888698,129.95306271607248],"luv":[88.3888340150102181,-78.0723424240601,93.1979410921456122],"rgb":[0.2,1,0.333333333333333315],"xyz":[0.387631624183702783,0.728766116882652581,0.206182689281030257],"hpluv":[129.95306271607248,466.04908765344419,88.3888340150102181],"hsluv":[129.95306271607248,99.999999999991644,88.3888340150102181]},"#33ff66":{"lch":[88.5334972733264,116.417510431790106,131.704600668064415],"luv":[88.5334972733264,-77.4514410423726929,86.9155395518881],"rgb":[0.2,1,0.4],"xyz":[0.395216619957210968,0.7318001151920559,0.246130333688174219],"hpluv":[131.704600668064415,452.43688525451455,88.5334972733264],"hsluv":[131.704600668064415,99.9999999999913882,88.5334972733264]},"#33ff77":{"lch":[88.7105909437740081,110.419515958012653,134.007319384137503],"luv":[88.7105909437740081,-76.7139872603015505,79.419353202025647],"rgb":[0.2,1,0.466666666666666674],"xyz":[0.404530632977412874,0.735525720400136751,0.295184135594572128],"hpluv":[134.007319384137503,436.493157669178117,88.7105909437740081],"hsluv":[134.007319384137503,99.9999999999915,88.7105909437740081]},"#33ff88":{"lch":[88.9216276204312379,103.738746998712813,136.99719245927011],"luv":[88.9216276204312379,-75.8662497359534882,70.7533729221786558],"rgb":[0.2,1,0.533333333333333326],"xyz":[0.415671050079356674,0.739981887240914293,0.353856998998144268],"hpluv":[136.99719245927011,418.619650658891032,88.9216276204312379],"hsluv":[136.99719245927011,99.9999999999912603,88.9216276204312379]},"#33ff99":{"lch":[89.1678944508512359,96.6032590942606788,140.85189111032139],"luv":[89.1678944508512359,-74.9174292298428242,60.9882649796200695],"rgb":[0.2,1,0.6],"xyz":[0.428728014188429429,0.745204672884543506,0.422623676639262202],"hpluv":[140.85189111032139,399.492483487252343,89.1678944508512359],"hsluv":[140.85189111032139,99.9999999999913456,89.1678944508512359]},"#33ffaa":{"lch":[89.4504724790268426,89.3298939826383105,145.795546705853383],"luv":[89.4504724790268426,-73.8791171714821,50.2165909327964926],"rgb":[0.2,1,0.66666666666666663],"xyz":[0.44378570715368193,0.751227750070644573,0.501927526256260803],"hpluv":[145.795546705853383,380.184928602968114,89.4504724790268426],"hsluv":[145.795546705853383,99.9999999999912,89.4504724790268426]},"#33ffbb":{"lch":[89.7702508712150262,82.3444719603705,152.087330110215447],"luv":[89.7702508712150262,-72.7646918614874494,38.5475249625060314],"rgb":[0.2,1,0.733333333333333282],"xyz":[0.460923299261018604,0.758082786913579332,0.592185511354902605],"hpluv":[152.087330110215447,362.351543222333419,89.7702508712150262],"hsluv":[152.087330110215447,99.9999999999909761,89.7702508712150262]},"#33ffcc":{"lch":[90.127938152783571,76.1985663634222,159.968053619612647],"luv":[90.127938152783571,-71.5886883295869723,26.1013643147272063],"rgb":[0.2,1,0.8],"xyz":[0.480215674704740358,0.765799737091068189,0.693792022025172761],"hpluv":[159.968053619612647,348.464440630653087,90.127938152783571],"hsluv":[159.968053619612647,99.999999999990834,90.127938152783571]},"#33ffdd":{"lch":[90.5240717550146314,71.5577226375514357,169.529475161807255],"luv":[90.5240717550146314,-70.3661811113599924,13.0041618290463337],"rgb":[0.2,1,0.866666666666666696],"xyz":[0.501734000255373846,0.774407067311321695,0.807121869925178759],"hpluv":[169.529475161807255,342.013155745428833,90.5240717550146314],"hsluv":[169.529475161807255,99.9999999999904077,90.5240717550146314]},"#33ffee":{"lch":[90.9590266887802,69.1149718308150511,180.51167449693034],"luv":[90.9590266887802,-69.1122158161064561,-0.61721646306864264],"rgb":[0.2,1,0.933333333333333348],"xyz":[0.525546180521548667,0.783931939417791712,0.932532685993702],"hpluv":[180.51167449693034,347.442342228089899,90.9590266887802],"hsluv":[180.51167449693034,99.9999999999901519,90.9590266887802]},"#33ffff":{"lch":[91.4330238629877243,69.4028497051403122,192.177050630061132],"luv":[91.4330238629877243,-67.8413175363212702,-14.6393709608822622],"rgb":[0.2,1,1],"xyz":[0.55171722893138,0.794400358781724436,1.07036687428548372],"hpluv":[192.177050630061132,369.590917988860895,91.4330238629877243],"hsluv":[192.177050630061132,99.9999999999897256,91.4330238629877243]},"#22aa00":{"lch":[60.8595101229647923,91.9296409673314656,126.268252023172565],"luv":[60.8595101229647923,-54.3824975763784053,74.1188427172042594],"rgb":[0.133333333333333331,0.66666666666666663,0],"xyz":[0.150337683054585614,0.290883353615456,0.0482228743965988915],"hpluv":[126.268252023172565,191.675426474830772,60.8595101229647923],"hsluv":[126.268252023172565,100.000000000002288,60.8595101229647923]},"#22aa11":{"lch":[60.8951349805759605,90.6090655032342482,126.765726538166419],"luv":[60.8951349805759605,-54.2335583573106,72.5859759132132893],"rgb":[0.133333333333333331,0.66666666666666663,0.0666666666666666657],"xyz":[0.151349348554222746,0.291288019815310828,0.0535509793613545212],"hpluv":[126.765726538166419,188.811473003651798,60.8951349805759605],"hsluv":[126.765726538166419,97.6988909499644365,60.8951349805759605]},"#22aa22":{"lch":[60.9610867967894592,88.21068058626,127.715012949240347],"luv":[60.9610867967894592,-53.9615024560723953,69.7802294505720226],"rgb":[0.133333333333333331,0.66666666666666663,0.133333333333333331],"xyz":[0.153224706692699747,0.292038163070701628,0.0634278655573337208],"hpluv":[127.715012949240347,183.614848439340193,60.9610867967894592],"hsluv":[127.715012949240347,93.4926845994439475,60.9610867967894592]},"#22aa33":{"lch":[61.0694299105106495,84.4016098893730629,129.358188857231823],"luv":[61.0694299105106495,-53.5246691509727626,65.259034196016259],"rgb":[0.133333333333333331,0.66666666666666663,0.2],"xyz":[0.156312457425157481,0.293273263363684755,0.0796900194149448571],"hpluv":[129.358188857231823,175.374397166590711,61.0694299105106495],"hsluv":[129.358188857231823,93.5882360519160699,61.0694299105106495]},"#22aa44":{"lch":[61.2253168994486145,79.2082340196825214,131.918899994809664],"luv":[61.2253168994486145,-52.917281977470445,58.938150671985575],"rgb":[0.133333333333333331,0.66666666666666663,0.266666666666666663],"xyz":[0.160770452669376368,0.295056461461372321,0.103168794367831496],"hpluv":[131.918899994809664,164.164260791814144,61.2253168994486145],"hsluv":[131.918899994809664,93.7213426507132397,61.2253168994486145]},"#22aa55":{"lch":[61.4328316402448422,72.8294169380228169,135.724592815827151],"luv":[61.4328316402448422,-52.1453123372646488,50.8428005993127883],"rgb":[0.133333333333333331,0.66666666666666663,0.333333333333333315],"xyz":[0.166732866708738381,0.297441427077117182,0.134570841641805411],"hpluv":[135.724592815827151,150.433869175471955,61.4328316402448422],"hsluv":[135.724592815827151,93.8909627694616802,61.4328316402448422]},"#22aa66":{"lch":[61.695221435526193,65.6694032551541511,141.26425661379642],"luv":[61.695221435526193,-51.2247747289881588,41.0912761769754056],"rgb":[0.133333333333333331,0.66666666666666663,0.4],"xyz":[0.174317862482246538,0.3004754253865205,0.174518486048949373],"hpluv":[141.26425661379642,135.067502346464636,61.695221435526193],"hsluv":[141.26425661379642,94.0939374356695737,61.695221435526193]},"#22aa77":{"lch":[62.015018576984005,58.3994247120946,149.232117680428786],"luv":[62.015018576984005,-50.1795183581889,29.8748848373309741],"rgb":[0.133333333333333331,0.66666666666666663,0.466666666666666674],"xyz":[0.183631875502448472,0.304201030594601296,0.223572287955347282],"hpluv":[149.232117680428786,119.495353216490457,62.015018576984005],"hsluv":[149.232117680428786,94.3254538020573534,62.015018576984005]},"#22aa88":{"lch":[62.3941144695078265,52.0455462506657582,160.428514439052776],"luv":[62.3941144695078265,-49.0385773736463904,17.4343572780611709],"rgb":[0.133333333333333331,0.66666666666666663,0.533333333333333326],"xyz":[0.194772292604392272,0.308657197435378894,0.282245151358919477],"hpluv":[160.428514439052776,105.847175197261592,62.3941144695078265],"hsluv":[160.428514439052776,94.5795977554836753,62.3941144695078265]},"#22aa99":{"lch":[62.8338123759312168,48.0032947436357915,175.177921691935865],"luv":[62.8338123759312168,-47.8333890460383486,4.03524455451089725],"rgb":[0.133333333333333331,0.66666666666666663,0.6],"xyz":[0.207829256713465,0.313879983079008051,0.351011829000037356],"hpluv":[175.177921691935865,96.9431131493944918,62.8338123759312168],"hsluv":[175.177921691935865,94.8499327714938119,62.8338123759312168]},"#22aaaa":{"lch":[63.334871160235295,47.6677335272966047,192.177050630061132],"luv":[63.334871160235295,-46.595231466735612,-10.0547115418935782],"rgb":[0.133333333333333331,0.66666666666666663,0.66666666666666663],"xyz":[0.222886949678717528,0.319903060265109174,0.430315678617035957],"hpluv":[192.177050630061132,95.5038628742744748,63.334871160235295],"hsluv":[192.177050630061132,95.1300327368807075,63.334871160235295]},"#22aabb":{"lch":[63.8975462810157211,51.5875561200845425,208.460106210027732],"luv":[63.8975462810157211,-45.3531553267970224,-24.5838818811491713],"rgb":[0.133333333333333331,0.66666666666666663,0.733333333333333282],"xyz":[0.240024541786054202,0.326758097108043932,0.520573663715677704],"hpluv":[208.460106210027732,102.447201536891086,63.8975462810157211],"hsluv":[208.460106210027732,95.4139121453229393,63.8975462810157211]},"#22aacc":{"lch":[64.5216311304052681,59.1142282054053112,221.706391964203618],"luv":[64.5216311304052681,-44.1325525375176184,-39.3295027027292079],"rgb":[0.133333333333333331,0.66666666666666663,0.8],"xyz":[0.259316917229775901,0.334475047285532734,0.62218017438594786],"hpluv":[221.706391964203618,116.258847224370101,64.5216311304052681],"hsluv":[221.706391964203618,95.6963242429470853,64.5216311304052681]},"#22aadd":{"lch":[65.2065000175346796,69.0826091468118619,231.553565124642319],"luv":[65.2065000175346796,-42.9543721979751538,-54.1047945713593279],"rgb":[0.133333333333333331,0.66666666666666663,0.866666666666666696],"xyz":[0.2808352427804095,0.34308237750578624,0.735510022285953857],"hpluv":[231.553565124642319,134.436491082611866,65.2065000175346796],"hsluv":[231.553565124642319,95.9729250289437,65.2065000175346796]},"#22aaee":{"lch":[65.951153016283925,80.4876559434330687,238.683318882444183],"luv":[65.951153016283925,-41.8348964739996418,-68.7612114224159825],"rgb":[0.133333333333333331,0.66666666666666663,0.933333333333333348],"xyz":[0.304647423046584209,0.352607249612256257,0.86092083835447708],"hpluv":[238.683318882444183,154.862481256054423,65.951153016283925],"hsluv":[238.683318882444183,96.2403212652285305,65.951153016283925]},"#22aaff":{"lch":[66.7542622474436911,92.6475815050926741,243.881654723446388],"luv":[66.7542622474436911,-40.785937465112724,-83.187028218555227],"rgb":[0.133333333333333331,0.66666666666666663,1],"xyz":[0.33081847145641563,0.363075668976189,0.998755026646258925],"hpluv":[243.881654723446388,176.114215620682756,66.7542622474436911],"hsluv":[243.881654723446388,99.9999999999982521,66.7542622474436911]},"#22bb00":{"lch":[66.4275479271698117,100.802558180890344,126.547308547849156],"luv":[66.4275479271698117,-60.0265444602621798,80.9812922592122533],"rgb":[0.133333333333333331,0.733333333333333282,0],"xyz":[0.184292180963184393,0.358792349432654534,0.0595410403661315105],"hpluv":[126.547308547849156,192.558484368086766,66.4275479271698117],"hsluv":[126.547308547849156,100.000000000002402,66.4275479271698117]},"#22bb11":{"lch":[66.4585250929908682,99.6331665050874449,126.950333401467461],"luv":[66.4585250929908682,-59.891738470658936,79.6225315522727612],"rgb":[0.133333333333333331,0.733333333333333282,0.0666666666666666657],"xyz":[0.185303846462821525,0.359197015632509387,0.0648691453308871402],"hpluv":[126.950333401467461,190.235936561387632,66.4585250929908682],"hsluv":[126.950333401467461,98.1323711753334464,66.4585250929908682]},"#22bb22":{"lch":[66.5158870179191553,97.5011623585143496,127.715012949240375],"luv":[66.5158870179191553,-59.6448091899021904,77.1295883430057785],"rgb":[0.133333333333333331,0.733333333333333282,0.133333333333333331],"xyz":[0.187179204601298527,0.359947158887900187,0.0747460315268663328],"hpluv":[127.715012949240375,186.004620566556611,66.5158870179191553],"hsluv":[127.715012949240375,94.7095045552014341,66.5158870179191553]},"#22bb33":{"lch":[66.6101592341861561,94.091611241079562,129.025604662043349],"luv":[66.6101592341861561,-59.2464412491434089,73.0964465979998721],"rgb":[0.133333333333333331,0.733333333333333282,0.2],"xyz":[0.19026695533375626,0.361182259180883314,0.091008185384477483],"hpluv":[129.025604662043349,179.246118589082698,66.6101592341861561],"hsluv":[129.025604662043349,94.7728361420699628,66.6101592341861561]},"#22bb44":{"lch":[66.7458880420052907,89.3893698914418735,131.03732282887168],"luv":[66.7458880420052907,-58.6886365964374903,67.424797990356],"rgb":[0.133333333333333331,0.733333333333333282,0.266666666666666663],"xyz":[0.194724950577975148,0.36296545727857088,0.114486960337364121],"hpluv":[131.03732282887168,169.941985039444177,66.7458880420052907],"hsluv":[131.03732282887168,94.8616428317247511,66.7458880420052907]},"#22bb55":{"lch":[66.9267274999506,83.5071173210959472,133.96576260666626],"luv":[66.9267274999506,-57.9730125462468777,60.1046459068846488],"rgb":[0.133333333333333331,0.733333333333333282,0.333333333333333315],"xyz":[0.200687364617337161,0.365350422894315741,0.145889007611338023],"hpluv":[133.96576260666626,158.330006142604873,66.9267274999506],"hsluv":[133.96576260666626,94.9758066387206128,66.9267274999506]},"#22bb66":{"lch":[67.1556458878222315,76.7025221245859541,138.121353671725132],"luv":[67.1556458878222315,-57.1096598103208919,51.2031606116460054],"rgb":[0.133333333333333331,0.733333333333333282,0.4],"xyz":[0.208272360390845318,0.368384421203719059,0.185836652018481985],"hpluv":[138.121353671725132,144.932719296840418,67.1556458878222315],"hsluv":[138.121353671725132,95.1139083236691363,67.1556458878222315]},"#22bb77":{"lch":[67.4350338747947831,69.4107315991336407,143.945643371462126],"luv":[67.4350338747947831,-56.1157304677756557,40.8518598743670935],"rgb":[0.133333333333333331,0.733333333333333282,0.466666666666666674],"xyz":[0.217586373411047251,0.372110026411799855,0.234890453924879894],"hpluv":[143.945643371462126,130.611184627207962,67.4350338747947831],"hsluv":[143.945643371462126,95.2734443978328471,67.4350338747947831]},"#22bb88":{"lch":[67.7667691572368653,62.2973404800357571,152.016434409622292],"luv":[67.7667691572368653,-55.0136735570032656,29.2310511724943218],"rgb":[0.133333333333333331,0.733333333333333282,0.533333333333333326],"xyz":[0.228726790512991052,0.376566193252577452,0.293563317328452089],"hpluv":[152.016434409622292,116.65196328010299,67.7667691572368653],"hsluv":[152.016434409622292,95.4510958201536823,67.7667691572368653]},"#22bb99":{"lch":[68.1522602188863402,56.3167420179958214,162.907285030510934],"luv":[68.1522602188863402,-53.8292536917802948,16.552549003324323],"rgb":[0.133333333333333331,0.733333333333333282,0.6],"xyz":[0.241783754622063779,0.38178897889620661,0.362329994969569968],"hpluv":[162.907285030510934,104.856796539193,68.1522602188863402],"hsluv":[162.907285030510934,95.6430286983925555,68.1522602188863402]},"#22bbaa":{"lch":[68.5924801056558238,52.6774965449754617,176.68900923381463],"luv":[68.5924801056558238,-52.5895649511659542,3.04241688349887474],"rgb":[0.133333333333333331,0.733333333333333282,0.66666666666666663],"xyz":[0.256841447587316307,0.387812056082307732,0.441633844586568569],"hpluv":[176.68900923381463,97.4513697523019,68.5924801056558238],"hsluv":[176.68900923381463,95.8451953079369616,68.5924801056558238]},"#22bbbb":{"lch":[69.087995915136645,52.5025293878432677,192.177050630061075],"luv":[69.087995915136645,-51.3212466461144174,-11.0745309069971647],"rgb":[0.133333333333333331,0.733333333333333282,0.733333333333333282],"xyz":[0.273979039694653,0.394667092925242491,0.531891829685210316],"hpluv":[192.177050630061075,96.4310638968393903,69.087995915136645],"hsluv":[192.177050630061075,96.05360442262905,69.087995915136645]},"#22bbcc":{"lch":[69.6389970716796824,56.2104265974936,207.07804051519031],"luv":[69.6389970716796824,-50.0490518690675117,-25.5871933841835393],"rgb":[0.133333333333333331,0.733333333333333282,0.8],"xyz":[0.293271415138374736,0.402384043102731292,0.633498340355480472],"hpluv":[207.07804051519031,102.424464009042,69.6389970716796824],"hsluv":[207.07804051519031,96.2645382772070519,69.6389970716796824]},"#22bbdd":{"lch":[70.2453239794146924,63.2897284454122868,219.558412279776348],"luv":[70.2453239794146924,-48.7948432782897541,-40.3069844585422956],"rgb":[0.133333333333333331,0.733333333333333282,0.866666666666666696],"xyz":[0.314789740689008224,0.410991373322984799,0.746828188255486469],"hpluv":[219.558412279776348,114.328666738486675,70.2453239794146924],"hsluv":[219.558412279776348,96.4747049793171101,70.2453239794146924]},"#22bbee":{"lch":[70.9064977498674409,72.7777709471329644,229.176572531806158],"luv":[70.9064977498674409,-47.5770176148035588,-55.072963774560229],"rgb":[0.133333333333333331,0.733333333333333282,0.933333333333333348],"xyz":[0.338601920955183,0.420516245429454816,0.872239004324009692],"hpluv":[229.176572531806158,130.242295294742263,70.9064977498674409],"hsluv":[229.176572531806158,96.6813261778791286,70.9064977498674409]},"#22bbff":{"lch":[71.621751136046143,83.782469360031385,236.362391595167765],"luv":[71.621751136046143,-46.4103062114400586,-69.7537500742789121],"rgb":[0.133333333333333331,0.733333333333333282,1],"xyz":[0.364772969365014355,0.43098466479338754,1.01007319261579154],"hpluv":[236.362391595167765,148.438838585801221,71.621751136046143],"hsluv":[236.362391595167765,99.9999999999977405,71.621751136046143]},"#22cc00":{"lch":[71.9091745039523431,109.499123564337054,126.755635680122666],"luv":[71.9091745039523431,-65.5246489265194185,87.7301455852794732],"rgb":[0.133333333333333331,0.8,0],"xyz":[0.222515924272801313,0.435239836051889428,0.0722822881360034586],"hpluv":[126.755635680122666,193.226045742870838,71.9091745039523431],"hsluv":[126.755635680122666,100.000000000002288,71.9091745039523431]},"#22cc11":{"lch":[71.9364107151438077,108.454952609175663,127.087674169957992],"luv":[71.9364107151438077,-65.4022833696805,86.5159989567857508],"rgb":[0.133333333333333331,0.8,0.0666666666666666657],"xyz":[0.223527589772438445,0.435644502251744281,0.0776103931007591],"hpluv":[127.087674169957992,191.311003889673145,71.9364107151438077],"hsluv":[127.087674169957992,98.4591341389350418,71.9364107151438077]},"#22cc22":{"lch":[71.9868548113652196,106.54571101335867,127.715012949240403],"luv":[71.9868548113652196,-65.1776701905061771,84.2843985793322332],"rgb":[0.133333333333333331,0.8,0.133333333333333331],"xyz":[0.225402947910915447,0.436394645507135082,0.0874872792967382878],"hpluv":[127.715012949240403,187.811464536348922,71.9868548113652196],"hsluv":[127.715012949240403,95.6295101801496,71.9868548113652196]},"#22cc33":{"lch":[72.0697845089905229,103.47656324227728,128.782383231673776],"luv":[72.0697845089905229,-64.8140104316899084,80.6631464312780224],"rgb":[0.133333333333333331,0.8,0.2],"xyz":[0.22849069864337318,0.437629745800118208,0.103749433154349424],"hpluv":[128.782383231673776,182.191494825933376,72.0697845089905229],"hsluv":[128.782383231673776,95.6728206524347,72.0697845089905229]},"#22cc44":{"lch":[72.1892409305665126,99.2080881077430092,130.402545810446583],"luv":[72.1892409305665126,-64.3020931154350563,75.5479024657046381],"rgb":[0.133333333333333331,0.8,0.266666666666666663],"xyz":[0.232948693887592068,0.439412943897805774,0.127228208107236063],"hpluv":[130.402545810446583,174.38692971209278,72.1892409305665126],"hsluv":[130.402545810446583,95.7338579762306807,72.1892409305665126]},"#22cc55":{"lch":[72.3485056391290584,93.798910065649892,132.724941359454647],"luv":[72.3485056391290584,-63.6406395178356732,68.9064912128369116],"rgb":[0.133333333333333331,0.8,0.333333333333333315],"xyz":[0.23891110792695408,0.441797909513550635,0.158630255381209978],"hpluv":[132.724941359454647,164.515777124050715,72.3485056391290584],"hsluv":[132.724941359454647,95.8128514989610665,72.3485056391290584]},"#22cc66":{"lch":[72.5502856399570106,87.4149553130202577,135.957009780349864],"luv":[72.5502856399570106,-62.8354766726053597,60.7706942835425821],"rgb":[0.133333333333333331,0.8,0.4],"xyz":[0.246496103700462238,0.444831907822953954,0.19857789978835394],"hpluv":[135.957009780349864,152.89241471165704,72.5502856399570106],"hsluv":[135.957009780349864,95.9092114165347454,72.5502856399570106]},"#22cc77":{"lch":[72.7968107106438,80.347487444586676,140.388595454497391],"luv":[72.7968107106438,-61.8986076052927601,51.2277377519640922],"rgb":[0.133333333333333331,0.8,0.466666666666666674],"xyz":[0.255810116720664171,0.448557513031034749,0.247631701694751849],"hpluv":[140.388595454497391,140.055211607516185,72.7968107106438],"hsluv":[140.388595454497391,96.0216367005683651,72.7968107106438]},"#22cc88":{"lch":[73.0898911189871399,73.0433057087839899,146.410934307510047],"luv":[73.0898911189871399,-60.8470337434031379,40.4099368162836328],"rgb":[0.133333333333333331,0.8,0.533333333333333326],"xyz":[0.266950533822607972,0.453013679871812347,0.306304565098324044],"hpluv":[146.410934307510047,126.812607157634474,73.0898911189871399],"hsluv":[146.410934307510047,96.1482500942118463,73.0898911189871399]},"#22cc99":{"lch":[73.4309556061454316,66.1476907411168,154.494840416347301],"luv":[73.4309556061454316,-59.7013675833161201,28.4826912187770667],"rgb":[0.133333333333333331,0.8,0.6],"xyz":[0.280007497931680671,0.458236465515441505,0.375071242739441923],"hpluv":[154.494840416347301,114.307528246897718,73.4309556061454316],"hsluv":[154.494840416347301,96.2867563581127826,73.4309556061454316]},"#22ccaa":{"lch":[73.8210792378530272,60.5373530055450857,165.03572853292485],"luv":[73.8210792378530272,-58.4843517505691963,15.631753236079188],"rgb":[0.133333333333333331,0.8,0.66666666666666663],"xyz":[0.295065190896933227,0.464259542701542627,0.454375092356440524],"hpluv":[165.03572853292485,104.059650734936554,73.8210792378530272],"hsluv":[165.03572853292485,96.4346108423233233,73.8210792378530272]},"#22ccbb":{"lch":[74.2610062314211916,57.2561659312404601,177.947236116536601],"luv":[74.2610062314211916,-57.2194225987583565,2.05090580243043252],"rgb":[0.133333333333333331,0.8,0.733333333333333282],"xyz":[0.312202783004269901,0.471114579544477385,0.544633077455082271],"hpluv":[177.947236116536601,97.8364666306377302,74.2610062314211916],"hsluv":[177.947236116536601,96.5891828531354406,74.2610062314211916]},"#22cccc":{"lch":[74.7511706210643467,57.2167927817266,192.177050630061132],"luv":[74.7511706210643467,-55.9294412838427633,-12.0689259631595149],"rgb":[0.133333333333333331,0.8,0.8],"xyz":[0.3314951584479916,0.478831529721966187,0.646239588125352427],"hpluv":[192.177050630061132,97.128087782713564,74.7511706210643467],"hsluv":[192.177050630061132,96.747899952527,74.7511706210643467]},"#22ccdd":{"lch":[75.2917163799825602,60.7443465218384091,205.915913497891523],"luv":[75.2917163799825602,-54.6356779140553357,-26.5484148912282159],"rgb":[0.133333333333333331,0.8,0.866666666666666696],"xyz":[0.353013483998625199,0.487438859942219693,0.759569436025358424],"hpluv":[205.915913497891523,102.375961416692178,75.2917163799825602],"hsluv":[205.915913497891523,96.9083635301369,75.2917163799825602]},"#22ccee":{"lch":[75.8825178700112843,67.4282526949852894,217.691288579377613],"luv":[75.8825178700112843,-53.3570890727704779,-41.2260877015904583],"rgb":[0.133333333333333331,0.8,0.933333333333333348],"xyz":[0.376825664264799909,0.49696373204868971,0.884980252093881647],"hpluv":[217.691288579377613,112.755958051566466,75.8825178700112843],"hsluv":[217.691288579377613,97.0684311053177851,75.8825178700112843]},"#22ccff":{"lch":[76.5232010138481,76.4669756721874165,227.041443142980768],"luv":[76.5232010138481,-52.1098871667616095,-55.9621124325938553],"rgb":[0.133333333333333331,0.8,1],"xyz":[0.40299671267463133,0.507432151412622434,1.02281444038566338],"hpluv":[227.041443142980768,130.754689276117347,76.5232010138481],"hsluv":[227.041443142980768,99.999999999997,76.5232010138481]},"#22dd00":{"lch":[77.3111928538645543,118.038829613749726,126.914864539429317],"luv":[77.3111928538645543,-70.8973873693031607,94.3754510494695],"rgb":[0.133333333333333331,0.866666666666666696,0],"xyz":[0.265149914819976518,0.520507817146241,0.0864936183183947771],"hpluv":[126.914864539429317,210.347075729226248,77.3111928538645543],"hsluv":[126.914864539429317,100.000000000002288,77.3111928538645543]},"#22dd11":{"lch":[77.3353680300965323,117.099630973594756,127.192375056145337],"luv":[77.3353680300965323,-70.7859197567446756,93.2827805028547346],"rgb":[0.133333333333333331,0.866666666666666696,0.0666666666666666657],"xyz":[0.266161580319613622,0.520912483346095856,0.0918217232831504138],"hpluv":[127.192375056145337,208.941659016378082,77.3353680300965323],"hsluv":[127.192375056145337,98.7107326231664217,77.3353680300965323]},"#22dd22":{"lch":[77.3801492665193535,115.37848303888174,127.715012949240432],"luv":[77.3801492665193535,-70.5809801545768636,91.2716801027172409],"rgb":[0.133333333333333331,0.866666666666666696,0.133333333333333331],"xyz":[0.268036938458090679,0.521662626601486656,0.101698609479129606],"hpluv":[127.715012949240432,206.361699793513822,77.3801492665193535],"hsluv":[127.715012949240432,96.3395071146262154,77.3801492665193535]},"#22dd33":{"lch":[77.4537875025684315,112.600723810091978,128.59932725776207],"luv":[77.4537875025684315,-70.24826089977104,88.0005956974969195],"rgb":[0.133333333333333331,0.866666666666666696,0.2],"xyz":[0.271124689190548385,0.522897726894469783,0.117960763336740743],"hpluv":[128.59932725776207,202.185786680839726,77.4537875025684315],"hsluv":[128.59932725776207,96.3699377868481122,77.4537875025684315]},"#22dd44":{"lch":[77.5598997380018,108.71293616133481,129.930302741787841],"luv":[77.5598997380018,-69.7779723132927217,83.3638834787812],"rgb":[0.133333333333333331,0.866666666666666696,0.266666666666666663],"xyz":[0.2755826844347673,0.524680924992157349,0.141439538289627381],"hpluv":[129.930302741787841,196.316024449944422,77.5598997380018],"hsluv":[129.930302741787841,96.4129906320409162,77.5598997380018]},"#22dd55":{"lch":[77.7014460191091416,103.73899221962921,131.815952634500974],"luv":[77.7014460191091416,-69.1669361195931,77.3156740549574266],"rgb":[0.133333333333333331,0.866666666666666696,0.333333333333333315],"xyz":[0.281545098474129285,0.527065890607902099,0.172841585563601297],"hpluv":[131.815952634500974,188.764163413831653,77.7014460191091416],"hsluv":[131.815952634500974,96.4690009350202189,77.7014460191091416]},"#22dd66":{"lch":[77.880896240080375,97.784990294992113,134.401120560320578],"luv":[77.880896240080375,-68.4179393254247117,69.8633659756971923],"rgb":[0.133333333333333331,0.866666666666666696,0.4],"xyz":[0.28913009424763747,0.530099888917305417,0.212789229970745258],"hpluv":[134.401120560320578,179.664283635232721,77.880896240080375],"hsluv":[134.401120560320578,96.5377748783722467,77.880896240080375]},"#22dd77":{"lch":[78.1003183749745205,91.0497694522495635,137.883451987021573],"luv":[78.1003183749745205,-67.5390964016577584,61.0616980975421],"rgb":[0.133333333333333331,0.866666666666666696,0.466666666666666674],"xyz":[0.298444107267839376,0.533825494125386268,0.261843031877143195],"hpluv":[137.883451987021573,169.299836923025936,78.1003183749745205],"hsluv":[137.883451987021573,96.6186469084632478,78.1003183749745205]},"#22dd88":{"lch":[78.3614307373917285,83.8424849668191143,142.529576014285681],"luv":[78.3614307373917285,-66.5430534683674608,51.0057283108209205],"rgb":[0.133333333333333331,0.866666666666666696,0.533333333333333326],"xyz":[0.309584524369783176,0.538281660966163811,0.320515895280715335],"hpluv":[142.529576014285681,158.150702843881334,78.3614307373917285],"hsluv":[142.529576014285681,96.7105501690208,78.3614307373917285]},"#22dd99":{"lch":[78.665635872828048,76.6094810635621144,148.680389056502293],"luv":[78.665635872828048,-65.4460211356496586,39.8224924677044854],"rgb":[0.133333333333333331,0.866666666666666696,0.6],"xyz":[0.322641488478855876,0.543504446609793,0.389282572921833214],"hpluv":[148.680389056502293,146.968629494944878,78.665635872828048],"hsluv":[148.680389056502293,96.8121015046769884,78.665635872828048]},"#22ddaa":{"lch":[79.0140446006893882,69.96699558248838,156.711923446039975],"luv":[79.0140446006893882,-64.2666918031728613,27.6617569130368608],"rgb":[0.133333333333333331,0.866666666666666696,0.66666666666666663],"xyz":[0.337699181444108432,0.549527523795894091,0.46858642253883187],"hpluv":[156.711923446039975,136.880679993502099,79.0140446006893882],"hsluv":[156.711923446039975,96.9216963326973513,79.0140446006893882]},"#22ddbb":{"lch":[79.4074947696843196,64.7136880558744849,166.88262774299784],"luv":[79.4074947696843196,-63.0251268096233161,14.6865520944819572],"rgb":[0.133333333333333331,0.866666666666666696,0.733333333333333282],"xyz":[0.354836773551445106,0.556382560638828849,0.558844407637473561],"hpluv":[166.88262774299784,129.476815865977585,79.4074947696843196],"hsluv":[166.88262774299784,97.0376060255481,79.4074947696843196]},"#22ddcc":{"lch":[79.8465673347569123,61.7508733998812431,179.012513434233142],"luv":[79.8465673347569123,-61.7417023409151184,1.06421693934889783],"rgb":[0.133333333333333331,0.866666666666666696,0.8],"xyz":[0.374129148995166805,0.564099510816317706,0.660450918307743717],"hpluv":[179.012513434233142,126.735630147597362,79.8465673347569123],"hsluv":[179.012513434233142,97.1580701030331824,79.8465673347569123]},"#22dddd":{"lch":[80.3316012938198867,61.8272738566169,192.177050630061245],"luv":[80.3316012938198867,-60.4361886569793,-13.0414298740249546],"rgb":[0.133333333333333331,0.866666666666666696,0.866666666666666696],"xyz":[0.395647474545800404,0.572706841036571213,0.773780766207749715],"hpluv":[192.177050630061245,130.583134255532286,80.3316012938198867],"hsluv":[192.177050630061245,97.2813767637234434,80.3316012938198867]},"#22ddee":{"lch":[80.8627083873859078,65.1993477029452606,204.924336649163848],"luv":[80.8627083873859078,-59.1270126845314579,-27.4763773429615092],"rgb":[0.133333333333333331,0.866666666666666696,0.933333333333333348],"xyz":[0.419459654811975113,0.58223171314304123,0.899191582276272938],"hpluv":[204.924336649163848,142.193638870282854,80.8627083873859078],"hsluv":[204.924336649163848,97.405927410883,80.8627083873859078]},"#22ddff":{"lch":[81.4397880620905141,71.5324096951162574,216.054756332513932],"luv":[81.4397880620905141,-57.8307265123863,-42.1009822669203544],"rgb":[0.133333333333333331,0.866666666666666696,1],"xyz":[0.445630703221806534,0.592700132506974,1.03702577056805478],"hpluv":[216.054756332513932,161.676156351457934,81.4397880620905141],"hsluv":[216.054756332513932,99.9999999999961,81.4397880620905141]},"#22ee00":{"lch":[82.639607109796458,126.437751030410212,127.039022267349651],"luv":[82.639607109796458,-76.1608929793909368,100.92583052028732],"rgb":[0.133333333333333331,0.933333333333333348,0],"xyz":[0.312328691160491334,0.614865369827271913,0.102219877098565962],"hpluv":[127.039022267349651,308.746810598848469,82.639607109796458],"hsluv":[127.039022267349651,100.000000000002203,82.639607109796458]},"#22ee11":{"lch":[82.6612418520526262,125.587498690937579,127.273852876359626],"luv":[82.6612418520526262,-76.0589691017437,99.9362449095734462],"rgb":[0.133333333333333331,0.933333333333333348,0.0666666666666666657],"xyz":[0.313340356660128438,0.615270036027126821,0.107547982063321598],"hpluv":[127.273852876359626,307.111076239802628,82.6612418520526262],"hsluv":[127.273852876359626,98.9080389542438638,82.6612418520526262]},"#22ee22":{"lch":[82.7013218186993271,124.026614606467561,127.715012949240375],"luv":[82.7013218186993271,-75.8713392100017643,98.112899341636421],"rgb":[0.133333333333333331,0.933333333333333348,0.133333333333333331],"xyz":[0.315215714798605495,0.616020179282517621,0.117424868259300791],"hpluv":[127.715012949240375,304.102865014696874,82.7013218186993271],"hsluv":[127.715012949240375,96.8972824334497176,82.7013218186993271]},"#22ee33":{"lch":[82.7672420886773921,121.499708898279266,128.458265706389938],"luv":[82.7672420886773921,-75.5660658728233443,95.1417308591278754],"rgb":[0.133333333333333331,0.933333333333333348,0.2],"xyz":[0.318303465531063201,0.617255279575500748,0.133687022116911941],"hpluv":[128.458265706389938,299.21821405622444,82.7672420886773921],"hsluv":[128.458265706389938,96.9191735237910308,82.7672420886773921]},"#22ee44":{"lch":[82.8622607061112575,117.945648419515081,129.569612755667265],"luv":[82.8622607061112575,-75.1331770294334,90.918544261133448],"rgb":[0.133333333333333331,0.933333333333333348,0.266666666666666663],"xyz":[0.322761460775282116,0.619038477673188314,0.15716579706979858],"hpluv":[129.569612755667265,292.317409010606752,82.8622607061112575],"hsluv":[129.569612755667265,96.9502397298715692,82.8622607061112575]},"#22ee55":{"lch":[82.9890600071846194,113.365618159982461,131.129866929811442],"luv":[82.9890600071846194,-74.5682726576598185,85.3893207236587],"rgb":[0.133333333333333331,0.933333333333333348,0.333333333333333315],"xyz":[0.328723874814644101,0.621423443288933064,0.188567844343772495],"hpluv":[131.129866929811442,283.372415217622233,82.9890600071846194],"hsluv":[131.129866929811442,96.9908233877961266,82.9890600071846194]},"#22ee66":{"lch":[83.1498978333136,107.825536766413322,133.243989823694022],"luv":[83.1498978333136,-73.8719849852999175,78.5447402013449647],"rgb":[0.133333333333333331,0.933333333333333348,0.4],"xyz":[0.336308870588152287,0.624457441598336382,0.228515488750916429],"hpluv":[133.243989823694022,272.476761047092111,83.1498978333136],"hsluv":[133.243989823694022,97.0409162623008683,83.1498978333136]},"#22ee77":{"lch":[83.3466879629012709,101.462411308546436,136.05169958656856],"luv":[83.3466879629012709,-73.0495185954435726,70.415827350948561],"rgb":[0.133333333333333331,0.933333333333333348,0.466666666666666674],"xyz":[0.345622883608354192,0.628183046806417233,0.277569290657314338],"hpluv":[136.05169958656856,259.869348467080897,83.3466879629012709],"hsluv":[136.05169958656856,97.1001922741487391,83.3466879629012709]},"#22ee88":{"lch":[83.5810478428977746,94.494960715205238,139.739189865999265],"luv":[83.5810478428977746,-72.1101014829990277,61.0690663485185681],"rgb":[0.133333333333333331,0.933333333333333348,0.533333333333333326],"xyz":[0.356763300710298,0.632639213647194776,0.336242154060886533],"hpluv":[139.739189865999265,245.976403795765407,83.5810478428977746],"hsluv":[139.739189865999265,97.1680458209452098,83.5810478428977746]},"#22ee99":{"lch":[83.8543293451422187,87.2401092672494514,144.548413258572367],"luv":[83.8543293451422187,-71.0663081347816,50.6005584263049286],"rgb":[0.133333333333333331,0.933333333333333348,0.6],"xyz":[0.369820264819370692,0.637861999290824,0.405008831702004413],"hpluv":[144.548413258572367,231.480208097577446,83.8543293451422187],"hsluv":[144.548413258572367,97.2436385928483844,83.8543293451422187]},"#22eeaa":{"lch":[84.1676401551603846,80.1359348037682508,150.771943883792943],"luv":[84.1676401551603846,-69.9332745317766324,39.1293388665967328],"rgb":[0.133333333333333331,0.933333333333333348,0.66666666666666663],"xyz":[0.384877957784623248,0.643885076476925056,0.484312681319003],"hpluv":[150.771943883792943,217.42312560604816,84.1676401551603846],"hsluv":[150.771943883792943,97.3259536357082311,84.1676401551603846]},"#22eebb":{"lch":[84.5218598825754697,73.7647249619211181,158.704077932293842],"luv":[84.5218598825754697,-68.7278540770417834,26.7902355844945639],"rgb":[0.133333333333333331,0.933333333333333348,0.733333333333333282],"xyz":[0.402015549891959922,0.650740113319859814,0.57457066641764476],"hpluv":[158.704077932293842,205.339796192481117,84.5218598825754697],"hsluv":[158.704077932293842,97.4138533690930331,84.5218598825754697]},"#22eecc":{"lch":[84.9176532530853621,68.8500130904050422,168.499772582144715],"luv":[84.9176532530853621,-67.467774257192545,13.7267526869778429],"rgb":[0.133333333333333331,0.933333333333333348,0.8],"xyz":[0.421307925335681621,0.658457063497348671,0.676177177087914916],"hpluv":[168.499772582144715,197.354512375483154,84.9176532530853621],"hsluv":[168.499772582144715,97.5061375012374896,84.9176532530853621]},"#22eedd":{"lch":[85.3554818050158275,66.1709053937965166,179.926877690260085],"luv":[85.3554818050158275,-66.170851505859261,0.0844489448895467398],"rgb":[0.133333333333333331,0.933333333333333348,0.866666666666666696],"xyz":[0.44282625088631522,0.667064393717602178,0.789507024987920913],"hpluv":[179.926877690260085,196.075052309852396,85.3554818050158275],"hsluv":[179.926877690260085,97.6015969291830174,85.3554818050158275]},"#22eeee":{"lch":[85.8356149635753667,66.3470894225537648,192.177050630061245],"luv":[85.8356149635753667,-64.8543104533760868,-13.9948094114017536],"rgb":[0.133333333333333331,0.933333333333333348,0.933333333333333348],"xyz":[0.46663843115248993,0.676589265824072195,0.914917841056444137],"hpluv":[192.177050630061245,204.089886920334152,85.8356149635753667],"hsluv":[192.177050630061245,97.6990604766853608,85.8356149635753667]},"#22eeff":{"lch":[86.35814102124138,69.583621560973242,204.067857145017655],"luv":[86.35814102124138,-63.5342376580599435,-28.377474072755291],"rgb":[0.133333333333333331,0.933333333333333348,1],"xyz":[0.492809479562321351,0.687057685188004919,1.05275202934822598],"hpluv":[204.067857145017655,223.225826840448832,86.35814102124138],"hsluv":[204.067857145017655,99.9999999999940883,86.35814102124138]},"#22ff00":{"lch":[87.8997189713237361,134.70927246092154,127.137510750393233],"luv":[87.8997189713237361,-81.328032504319566,107.388729464162736],"rgb":[0.133333333333333331,1,0],"xyz":[0.364181063590165166,0.718570114686621,0.119504001241790073],"hpluv":[127.137510750393233,493.515561032875894,87.8997189713237361],"hsluv":[127.137510750393233,100.000000000002359,87.8997189713237361]},"#22ff11":{"lch":[87.9192191859362708,133.935112153716517,127.338384986715198],"luv":[87.9192191859362708,-81.2344832365115792,106.487431187561],"rgb":[0.133333333333333331,1,0.0666666666666666657],"xyz":[0.36519272908980227,0.718974780886475928,0.124832106206545709],"hpluv":[127.338384986715198,491.550771148457443,87.9192191859362708],"hsluv":[127.338384986715198,99.9999999999918572,87.9192191859362708]},"#22ff22":{"lch":[87.9553480404818089,132.511927889398493,127.71501294924046],"luv":[87.9553480404818089,-81.0620967295481449,104.825319015849075],"rgb":[0.133333333333333331,1,0.133333333333333331],"xyz":[0.367068087228279327,0.719724924141866729,0.134708992402524902],"hpluv":[127.71501294924046,487.932270281505453,87.9553480404818089],"hsluv":[127.71501294924046,99.9999999999918,87.9553480404818089]},"#22ff33":{"lch":[88.0147790356886,130.202284180175667,128.347396099003475],"luv":[88.0147790356886,-80.7811428723405101,102.112887345201102],"rgb":[0.133333333333333331,1,0.2],"xyz":[0.370155837960737033,0.720960024434849855,0.150971146260136052],"hpluv":[128.347396099003475,482.0420586134328,88.0147790356886],"hsluv":[128.347396099003475,99.9999999999918572,88.0147790356886]},"#22ff44":{"lch":[88.1004639745127349,126.941230298117631,129.288082018787549],"luv":[88.1004639745127349,-80.3817123888383,98.2489504424236486],"rgb":[0.133333333333333331,1,0.266666666666666663],"xyz":[0.374613833204955948,0.722743222532537422,0.174449921213022691],"hpluv":[129.288082018787549,473.688351575452941,88.1004639745127349],"hsluv":[129.288082018787549,99.9999999999917719,88.1004639745127349]},"#22ff55":{"lch":[88.2148445849976497,122.715034192366474,130.599301535876663],"luv":[88.2148445849976497,-79.8586444797792865,93.1749779645044498],"rgb":[0.133333333333333331,1,0.333333333333333315],"xyz":[0.380576247244317933,0.725128188148282171,0.205851968486996606],"hpluv":[130.599301535876663,462.799362736769183,88.2148445849976497],"hsluv":[130.599301535876663,99.9999999999917,88.2148445849976497]},"#22ff66":{"lch":[88.3599902775167863,117.562049147645283,132.359544385640646],"luv":[88.3599902775167863,-79.2110524978463104,86.8702743288911279],"rgb":[0.133333333333333331,1,0.4],"xyz":[0.388161243017826119,0.72816218645768549,0.24579961289414054],"hpluv":[132.359544385640646,449.432018335727776,88.3599902775167863],"hsluv":[132.359544385640646,99.999999999991644,88.3599902775167863]},"#22ff77":{"lch":[88.5376718023346427,111.576626717172417,134.67079586388752],"luv":[88.5376718023346427,-78.441973739162,79.3486004003085839],"rgb":[0.133333333333333331,1,0.466666666666666674],"xyz":[0.397475256038028,0.731887791665766341,0.294853414800538449],"hpluv":[134.67079586388752,433.796433649144,88.5376718023346427],"hsluv":[134.67079586388752,99.9999999999914593,88.5376718023346427]},"#22ff88":{"lch":[88.7494051061703,104.915784817642518,137.666744209541747],"luv":[88.7494051061703,-77.5579802767934581,70.6546643845003786],"rgb":[0.133333333333333331,1,0.533333333333333326],"xyz":[0.408615673139971824,0.736343958506543883,0.353526278204110644],"hpluv":[137.666744209541747,416.300130961303353,88.7494051061703],"hsluv":[137.666744209541747,99.9999999999915161,88.7494051061703]},"#22ff99":{"lch":[88.996479539624346,97.8095196496336143,141.520869213027311],"luv":[88.996479539624346,-76.5687003963823827,60.8599725082183696],"rgb":[0.133333333333333331,1,0.6],"xyz":[0.42167263724904458,0.741566744150173096,0.422292955845228524],"hpluv":[141.520869213027311,397.621886071746928,88.996479539624346],"hsluv":[141.520869213027311,99.9999999999913882,88.996479539624346]},"#22ffaa":{"lch":[89.2799772586324281,90.5758041558366784,146.450029989774293],"luv":[89.2799772586324281,-75.4862499862398,50.057989986528554],"rgb":[0.133333333333333331,1,0.66666666666666663],"xyz":[0.43673033021429708,0.747589821336274163,0.50159680546222718],"hpluv":[146.450029989774293,378.829469872945424,89.2799772586324281],"hsluv":[146.450029989774293,99.9999999999911893,89.2799772586324281]},"#22ffbb":{"lch":[89.6007875020334552,83.6393655876379825,152.701818689515648],"luv":[89.6007875020334552,-74.3245992165371661,38.3587985630895787],"rgb":[0.133333333333333331,1,0.733333333333333282],"xyz":[0.453867922321633754,0.754444858179208921,0.591854790560868871],"hpluv":[152.701818689515648,361.553698033539774,89.6007875020334552],"hsluv":[152.701818689515648,99.9999999999909903,89.6007875020334552]},"#22ffcc":{"lch":[89.9596178804745,77.5461751086222,160.50148390925915],"luv":[89.9596178804745,-73.0989125181650223,25.8835519710636532],"rgb":[0.133333333333333331,1,0.8],"xyz":[0.473160297765355509,0.762161808356697779,0.693461301231139],"hpluv":[160.50148390925915,348.207300802542932,89.9596178804745],"hsluv":[160.50148390925915,99.999999999990834,89.9596178804745]},"#22ffdd":{"lch":[90.3570039795250466,72.9493687180361,169.926987012389134],"luv":[90.3570039795250466,-71.8249031216737421,12.7590629719491808],"rgb":[0.133333333333333331,1,0.866666666666666696],"xyz":[0.494678623315989,0.770769138576951285,0.806791149131145],"hpluv":[169.926987012389134,342.16275562632859,90.3570039795250466],"hsluv":[169.926987012389134,99.9999999999906,90.3570039795250466]},"#22ffee":{"lch":[90.793318095908873,70.5238201303846637,180.720785562676866],"luv":[90.793318095908873,-70.5182397089352,-0.887171987837557796],"rgb":[0.133333333333333331,1,0.933333333333333348],"xyz":[0.518490803582163817,0.780294010683421302,0.932201965199668248],"hpluv":[180.720785562676866,347.681124246536797,90.793318095908873],"hsluv":[180.720785562676866,99.9999999999901661,90.793318095908873]},"#22ffff":{"lch":[91.2687776254429082,70.7867026205843786,192.177050630061217],"luv":[91.2687776254429082,-69.1940343982234225,-14.9312715999851058],"rgb":[0.133333333333333331,1,1],"xyz":[0.544661851991995127,0.790762430047354,1.0700361534914502],"hpluv":[192.177050630061217,369.384676987995,91.2687776254429082],"hsluv":[192.177050630061217,99.9999999999901803,91.2687776254429082]},"#11aa00":{"lch":[60.6644104521350869,93.0873160838275,127.211890667698796],"luv":[60.6644104521350869,-56.2958954857129186,74.1351506854346241],"rgb":[0.0666666666666666657,0.66666666666666663,0],"xyz":[0.146052570780394131,0.288673842599075969,0.0480220097587461675],"hpluv":[127.211890667698796,194.713406103753528,60.6644104521350869],"hsluv":[127.211890667698796,100.000000000002444,60.6644104521350869]},"#11aa11":{"lch":[60.7002167335786424,91.7670835597914447,127.715012949240375],"luv":[60.7002167335786424,-56.1370762813229547,72.5935692169401],"rgb":[0.0666666666666666657,0.66666666666666663,0.0666666666666666657],"xyz":[0.147064236280031263,0.289078508798930822,0.0533501147235018],"hpluv":[127.715012949240375,191.838607973199288,60.7002167335786424],"hsluv":[127.715012949240375,97.6800439707354826,60.7002167335786424]},"#11aa22":{"lch":[60.7665037483511696,89.3702510768545153,128.6744569519864],"luv":[60.7665037483511696,-55.8469935821418844,69.7721655488506229],"rgb":[0.0666666666666666657,0.66666666666666663,0.133333333333333331],"xyz":[0.148939594418508264,0.289828652054321623,0.063227000919481],"hpluv":[128.6744569519864,186.624241227076766,60.7665037483511696],"hsluv":[128.6744569519864,97.7012125574833163,60.7665037483511696]},"#11aa33":{"lch":[60.8753956347493101,85.5662665428975799,130.333267948257316],"luv":[60.8753956347493101,-55.3812688292774595,65.2265362636212274],"rgb":[0.0666666666666666657,0.66666666666666663,0.2],"xyz":[0.152027345150966,0.291063752347304749,0.0794891547770921469],"hpluv":[130.333267948257316,178.361088002118152,60.8753956347493101],"hsluv":[130.333267948257316,97.7352371443594876,60.8753956347493101]},"#11aa44":{"lch":[61.0320681383245898,80.3855440613202603,132.913331110856149],"luv":[61.0320681383245898,-54.7338170014505394,58.8731260464924233],"rgb":[0.0666666666666666657,0.66666666666666663,0.266666666666666663],"xyz":[0.156485340395184885,0.292846950444992316,0.102967929729978785],"hpluv":[132.913331110856149,167.131840298358668,61.0320681383245898],"hsluv":[132.913331110856149,97.7826211010278428,61.0320681383245898]},"#11aa55":{"lch":[61.2406211479126199,74.0326893716562466,136.73626291081149],"luv":[61.2406211479126199,-53.9110982897111626,50.7388665304739064],"rgb":[0.0666666666666666657,0.66666666666666663,0.333333333333333315],"xyz":[0.162447754434546898,0.295231916060737176,0.134369977003952701],"hpluv":[136.73626291081149,153.399260409180499,61.2406211479126199],"hsluv":[136.73626291081149,97.8429805383323412,61.2406211479126199]},"#11aa66":{"lch":[61.5043118059827236,66.9183608277608926,142.276062400218507],"luv":[61.5043118059827236,-52.9302802927860938,40.944504442006675],"rgb":[0.0666666666666666657,0.66666666666666663,0.4],"xyz":[0.170032750208055056,0.298265914370140495,0.174317621411096635],"hpluv":[142.276062400218507,138.063556785316223,61.5043118059827236],"hsluv":[142.276062400218507,97.9151756761398246,61.5043118059827236]},"#11aa77":{"lch":[61.8256765996828648,59.7171413308715628,150.193024237310198],"luv":[61.8256765996828648,-51.8168585560505335,29.6841731923518672],"rgb":[0.0666666666666666657,0.66666666666666663,0.466666666666666674],"xyz":[0.179346763228257,0.30199151957822129,0.223371423317494544],"hpluv":[150.193024237310198,122.565843528602272,61.8256765996828648],"hsluv":[150.193024237310198,97.9974781059027578,61.8256765996828648]},"#11aa88":{"lch":[62.2066058842594,53.445591933814967,161.225226782668472],"luv":[62.2066058842594,-50.6018085779820197,17.201403018159084],"rgb":[0.0666666666666666657,0.66666666666666663,0.533333333333333326],"xyz":[0.190487180330200789,0.306447686418998888,0.282044286721066739],"hpluv":[161.225226782668472,109.022142353571084,62.2066058842594],"hsluv":[161.225226782668472,98.0877698343988698,62.2066058842594]},"#11aa99":{"lch":[62.6483970296267643,49.4620441969123803,175.635441576327452],"luv":[62.6483970296267643,-49.3186051456987613,3.76417356400704],"rgb":[0.0666666666666666657,0.66666666666666663,0.6],"xyz":[0.203544144439273517,0.311670472062628046,0.350810964362184619],"hpluv":[175.635441576327452,100.184705161952,62.6483970296267643],"hsluv":[175.635441576327452,98.1837511724305756,62.6483970296267643]},"#11aaaa":{"lch":[63.1517986220979424,49.10533458105958,192.177050630061103],"luv":[63.1517986220979424,-48.0004871585874326,-10.3579494522848794],"rgb":[0.0666666666666666657,0.66666666666666663,0.66666666666666663],"xyz":[0.218601837404526045,0.317693549248729168,0.430114813979183219],"hpluv":[192.177050630061103,98.6693521766944741,63.1517986220979424],"hsluv":[192.177050630061103,98.283131385506934,63.1517986220979424]},"#11aabb":{"lch":[63.7170519890822931,52.9100997091116483,208.088870357104184],"luv":[63.7170519890822931,-46.6782604891356812,-24.9122188681885817],"rgb":[0.0666666666666666657,0.66666666666666663,0.733333333333333282],"xyz":[0.235739429511862719,0.324548586091663926,0.520372799077825],"hpluv":[208.088870357104184,105.371274370578277,63.7170519890822931],"hsluv":[208.088870357104184,98.3837818799450474,63.7170519890822931]},"#11aacc":{"lch":[64.3439331362496603,60.2774830024396,221.163749704229559],"luv":[64.3439331362496603,-45.3787880982832661,-39.6754401089704345],"rgb":[0.0666666666666666657,0.66666666666666663,0.8],"xyz":[0.255031804955584418,0.332265536269152728,0.621979309748095122],"hpluv":[221.163749704229559,118.873987633214512,64.3439331362496603],"hsluv":[221.163749704229559,98.4838416101877385,64.3439331362496603]},"#11aadd":{"lch":[65.0317963778061738,70.0923801470555,230.985682804055784],"luv":[65.0317963778061738,-44.1241742926816372,-54.4609860144708762],"rgb":[0.0666666666666666657,0.66666666666666663,0.866666666666666696],"xyz":[0.276550130506218,0.340872866489406234,0.735309157648101119],"hpluv":[230.985682804055784,136.767964522831733,65.0317963778061738],"hsluv":[230.985682804055784,98.5817742563244,65.0317963778061738]},"#11aaee":{"lch":[65.7796198544585877,81.3683973110580325,238.155251398024461],"luv":[65.7796198544585877,-42.9315457639956293,-69.1208974137644248],"rgb":[0.0666666666666666657,0.66666666666666663,0.933333333333333348],"xyz":[0.300362310772392727,0.350397738595876251,0.860719973716624343],"hpluv":[238.155251398024461,156.965326989669,65.7796198544585877],"hsluv":[238.155251398024461,98.676383948407647,65.7796198544585877]},"#11aaff":{"lch":[66.5860524818013317,93.423779787985481,243.412392023658668],"luv":[66.5860524818013317,-41.8132782993845566,-83.5443139162218529],"rgb":[0.0666666666666666657,0.66666666666666663,1],"xyz":[0.326533359182224148,0.360866157959809,0.998554162008406188],"hpluv":[243.412392023658668,178.038321821181739,66.5860524818013317],"hsluv":[243.412392023658668,99.9999999999982805,66.5860524818013317]},"#11bb00":{"lch":[66.2579979425279788,101.837028338191359,127.308350947248712],"luv":[66.2579979425279788,-61.7238643700190792,80.9996599251199285],"rgb":[0.0666666666666666657,0.733333333333333282,0],"xyz":[0.180007068688992911,0.356582838416274528,0.0593401757282787864],"hpluv":[127.308350947248712,195.032386644097869,66.2579979425279788],"hsluv":[127.308350947248712,100.000000000002416,66.2579979425279788]},"#11bb11":{"lch":[66.2891028676776,100.667761827005108,127.715012949240403],"luv":[66.2891028676776,-61.5819268253258301,79.6345688739434507],"rgb":[0.0666666666666666657,0.733333333333333282,0.0666666666666666657],"xyz":[0.181018734188630043,0.356987504616129381,0.0646682806930344162],"hpluv":[127.715012949240403,192.702610495025482,66.2891028676776],"hsluv":[127.715012949240403,98.1199752505464318,66.2891028676776]},"#11bb22":{"lch":[66.3467009890152895,98.5365229927559199,128.48627008521666],"luv":[66.3467009890152895,-61.3219466901703356,77.130183570569983],"rgb":[0.0666666666666666657,0.733333333333333282,0.133333333333333331],"xyz":[0.182894092327107044,0.357737647871520181,0.0745451668890136088],"hpluv":[128.48627008521666,188.459149582366734,66.3467009890152895],"hsluv":[128.48627008521666,98.1339007760711155,66.3467009890152895]},"#11bb33":{"lch":[66.4413603116689586,95.1297105779412107,129.807139434656818],"luv":[66.4413603116689586,-60.9025570517959949,73.0790009455219121],"rgb":[0.0666666666666666657,0.733333333333333282,0.2],"xyz":[0.185981843059564778,0.358972748164503308,0.0908073207466247589],"hpluv":[129.807139434656818,181.684126992490178,66.4413603116689586],"hsluv":[129.807139434656818,98.1563849168539093,66.4413603116689586]},"#11bb44":{"lch":[66.5776441235544,90.4345556189602888,131.832147550242752],"luv":[66.5776441235544,-60.3153845158839061,67.3829595721343679],"rgb":[0.0666666666666666657,0.733333333333333282,0.266666666666666663],"xyz":[0.190439838303783665,0.360755946262190874,0.114286095699511397],"hpluv":[131.832147550242752,172.363503065423913,66.5776441235544],"hsluv":[131.832147550242752,98.1879073212924567,66.5776441235544]},"#11bb55":{"lch":[66.7592187944261,84.5672269635890501,134.774448398028227],"luv":[66.7592187944261,-59.5621947933412841,60.0329978237906374],"rgb":[0.0666666666666666657,0.733333333333333282,0.333333333333333315],"xyz":[0.196402252343145678,0.363140911877935735,0.145688142973485313],"hpluv":[134.774448398028227,160.742297130584,66.7592187944261],"hsluv":[134.774448398028227,98.2284201297941451,66.7592187944261]},"#11bb66":{"lch":[66.9890609579081513,77.7896938122995749,138.938350400658521],"luv":[66.9890609579081513,-58.6536805127572336,51.0977712402284752],"rgb":[0.0666666666666666657,0.733333333333333282,0.4],"xyz":[0.203987248116653835,0.366174910187339053,0.185635787380629275],"hpluv":[138.938350400658521,147.352496635070423,66.9890609579081513],"hsluv":[138.938350400658521,98.2774122804504486,66.9890609579081513]},"#11bb77":{"lch":[67.2695660469751573,70.5410036497719375,144.751753478195667],"luv":[67.2695660469751573,-57.6079608572489548,40.7106379437464625],"rgb":[0.0666666666666666657,0.733333333333333282,0.466666666666666674],"xyz":[0.213301261136855769,0.369900515395419849,0.234689589287027184],"hpluv":[144.751753478195667,133.064539371584743,67.2695660469751573],"hsluv":[144.751753478195667,98.33398740837616,67.2695660469751573]},"#11bb88":{"lch":[67.6026131767386289,63.4868829762913904,152.765342955174589],"luv":[67.6026131767386289,-56.44870944299889,29.0538725863731493],"rgb":[0.0666666666666666657,0.733333333333333282,0.533333333333333326],"xyz":[0.224441678238799569,0.374356682236197447,0.293362452690599351],"hpluv":[152.765342955174589,119.168054047142519,67.6026131767386289],"hsluv":[152.765342955174589,98.3969602233376293,67.6026131767386289]},"#11bb99":{"lch":[67.9896091217093357,57.5709210660889568,163.510238814203348],"luv":[67.9896091217093357,-55.2030563361408468,16.3411604100414145],"rgb":[0.0666666666666666657,0.733333333333333282,0.6],"xyz":[0.237498642347872296,0.379579467879826604,0.362129130331717231],"hpluv":[163.510238814203348,107.448401728013394,67.9896091217093357],"hsluv":[163.510238814203348,98.464964167861,67.9896091217093357]},"#11bbaa":{"lch":[68.431522322705149,53.97217733059707,177.026074660918823],"luv":[68.431522322705149,-53.8994902384006807,2.80015675382041573],"rgb":[0.0666666666666666657,0.733333333333333282,0.66666666666666663],"xyz":[0.252556335313124825,0.385602545065927726,0.441432979948715831],"hpluv":[177.026074660918823,100.081328983600983,68.431522322705149],"hsluv":[177.026074660918823,98.5365589333087684,68.431522322705149]},"#11bbbb":{"lch":[68.9289126417652511,53.7759127589290102,192.177050630061103],"luv":[68.9289126417652511,-52.5659794775517426,-11.3431298424003177],"rgb":[0.0666666666666666657,0.733333333333333282,0.733333333333333282],"xyz":[0.269693927420461499,0.392457581908862485,0.531690965047357578],"hpluv":[192.177050630061103,98.9978332941913095,68.9289126417652511],"hsluv":[192.177050630061103,98.6103267315429122,68.9289126417652511]},"#11bbcc":{"lch":[69.4819599404948463,57.3930965266865485,206.799543430538137],"luv":[69.4819599404948463,-51.2284702417124365,-25.8768499940688805],"rgb":[0.0666666666666666657,0.733333333333333282,0.8],"xyz":[0.288986302864183253,0.400174532086351287,0.633297475717627734],"hpluv":[206.799543430538137,104.81584090136549,69.4819599404948463],"hsluv":[206.799543430538137,98.6849492658553658,69.4819599404948463]},"#11bbdd":{"lch":[70.0904930703520535,64.3454332007566876,219.135570681285316],"luv":[70.0904930703520535,-49.9098388382008054,-40.6121011637893901],"rgb":[0.0666666666666666657,0.733333333333333282,0.866666666666666696],"xyz":[0.310504628414816741,0.408781862306604793,0.746627323617633731],"hpluv":[219.135570681285316,116.492493254234162,70.0904930703520535],"hsluv":[219.135570681285316,98.7592614999562244,70.0904930703520535]},"#11bbee":{"lch":[70.7540199625255184,73.7064384587933858,228.717665412779098],"luv":[70.7540199625255184,-48.6292974270947838,-55.3879996211006826],"rgb":[0.0666666666666666657,0.733333333333333282,0.933333333333333348],"xyz":[0.334316808680991506,0.41830673441307481,0.872038139686157],"hpluv":[228.717665412779098,132.188487390259695,70.7540199625255184],"hsluv":[228.717665412779098,98.8322822642660412,70.7540199625255184]},"#11bbff":{"lch":[71.471758937406932,84.600620314641418,235.923069973878228],"luv":[71.471758937406932,-47.4021956671632836,-70.0735099988154246],"rgb":[0.0666666666666666657,0.733333333333333282,1],"xyz":[0.360487857090822872,0.428775153777007534,1.00987232797793891],"hpluv":[235.923069973878228,150.202929688167188,71.471758937406932],"hsluv":[235.923069973878228,99.9999999999978115,71.471758937406932]},"#11cc00":{"lch":[71.760164015117,110.429324102022079,127.380540485202317],"luv":[71.760164015117,-67.042304751477019,87.7494444155603617],"rgb":[0.0666666666666666657,0.8,0],"xyz":[0.21823081199860983,0.433030325035509422,0.0720814234981507346],"hpluv":[127.380540485202317,195.272154443078705,71.760164015117],"hsluv":[127.380540485202317,100.000000000002245,71.760164015117]},"#11cc11":{"lch":[71.7874927519263366,109.385174124956521,127.715012949240432],"luv":[71.7874927519263366,-66.9146672826053219,86.5305935539869466],"rgb":[0.0666666666666666657,0.8,0.0666666666666666657],"xyz":[0.219242477498246963,0.433434991235364275,0.0774095284629063712],"hpluv":[127.715012949240432,193.352149077988855,71.7874927519263366],"hsluv":[127.715012949240432,98.4507061603193563,71.7874927519263366]},"#11cc22":{"lch":[71.8381079866900905,107.476295008714118,128.346772012349533],"luv":[71.8381079866900905,-66.680384726115463,84.2904519004221129],"rgb":[0.0666666666666666657,0.8,0.133333333333333331],"xyz":[0.221117835636723964,0.434185134490755076,0.0872864146588855638],"hpluv":[128.346772012349533,189.84411001864018,71.8381079866900905],"hsluv":[128.346772012349533,98.4601754700601361,71.8381079866900905]},"#11cc33":{"lch":[71.9213183931711626,104.40864440796355,129.421122123890029],"luv":[71.9213183931711626,-66.3010906987881441,80.6556284412913556],"rgb":[0.0666666666666666657,0.8,0.2],"xyz":[0.224205586369181697,0.435420234783738203,0.103548568516496714],"hpluv":[129.421122123890029,184.212095875088124,71.9213183931711626],"hsluv":[129.421122123890029,98.4755168761512749,71.9213183931711626]},"#11cc44":{"lch":[72.0411777660314669,100.144250866202455,131.050559631523186],"luv":[72.0411777660314669,-65.7672084530810395,75.5218198525557085],"rgb":[0.0666666666666666657,0.8,0.266666666666666663],"xyz":[0.228663581613400585,0.437203432881425769,0.127027343469383353],"hpluv":[131.050559631523186,176.394298837834185,72.0411777660314669],"hsluv":[131.050559631523186,98.4971346697200261,72.0411777660314669]},"#11cc55":{"lch":[72.2009771566369523,94.7439152050601621,133.383427271112737],"luv":[72.2009771566369523,-65.077446685205,68.8573554627095],"rgb":[0.0666666666666666657,0.8,0.333333333333333315],"xyz":[0.234625995652762598,0.439588398497170629,0.158429390743357268],"hpluv":[133.383427271112737,166.512782767528847,72.2009771566369523],"hsluv":[133.383427271112737,98.5251071985599225,72.2009771566369523]},"#11cc66":{"lch":[72.4034304155724,88.37638367841096,136.624435218533876],"luv":[72.4034304155724,-64.2379326004453333,60.6949191225620339],"rgb":[0.0666666666666666657,0.8,0.4],"xyz":[0.242210991426270755,0.442622396806573948,0.198377035150501202],"hpluv":[136.624435218533876,154.887514188688357,72.4034304155724],"hsluv":[136.624435218533876,98.5592219307307289,72.4034304155724]},"#11cc77":{"lch":[72.6507717937069657,81.3359578844494422,141.057484765247835],"luv":[72.6507717937069657,-63.261234579889333,51.1229326663597],"rgb":[0.0666666666666666657,0.8,0.466666666666666674],"xyz":[0.251525004446472689,0.446348002014654743,0.247430837056899111],"hpluv":[141.057484765247835,142.063228414279422,72.6507717937069657],"hsluv":[141.057484765247835,98.5990140248714795,72.6507717937069657]},"#11cc88":{"lch":[72.9448138267759703,74.0714793913140284,147.061910762632237],"luv":[72.9448138267759703,-62.1651250648783815,40.2750702654370087],"rgb":[0.0666666666666666657,0.8,0.533333333333333326],"xyz":[0.262665421548416489,0.450804168855432341,0.306103700460471306],"hpluv":[147.061910762632237,128.853412583983044,72.9448138267759703],"hsluv":[147.061910762632237,98.6438145792393755,72.9448138267759703]},"#11cc99":{"lch":[73.286985449663689,67.2264361640895203,155.087429558943455],"luv":[73.286985449663689,-60.9711251229010074,28.3181147072320734],"rgb":[0.0666666666666666657,0.8,0.6],"xyz":[0.275722385657489188,0.456026954499061499,0.374870378101589186],"hpluv":[155.087429558943455,116.399886643338576,73.286985449663689],"hsluv":[155.087429558943455,98.6928071276572609,73.286985449663689]},"#11ccaa":{"lch":[73.6783599756885224,61.6669147974486336,165.501022011161467],"luv":[73.6783599756885224,-59.7029534543248275,15.4390974304365383],"rgb":[0.0666666666666666657,0.8,0.66666666666666663],"xyz":[0.290780078622741744,0.462050031685162621,0.454174227718587786],"hpluv":[165.501022011161467,106.206622375239988,73.6783599756885224],"hsluv":[165.501022011161467,98.7450877264532494,73.6783599756885224]},"#11ccbb":{"lch":[74.1196780643846864,58.4137876130139801,178.201908682105085],"luv":[74.1196780643846864,-58.3850250256368426,1.83287644266177074],"rgb":[0.0666666666666666657,0.8,0.733333333333333282],"xyz":[0.307917670730078419,0.46890506852809738,0.544432212817229533],"hpluv":[178.201908682105085,100.004874571957387,74.1196780643846864],"hsluv":[178.201908682105085,98.7997230732590452,74.1196780643846864]},"#11cccc":{"lch":[74.6113685470067,58.3540675645504,192.177050630061103],"luv":[74.6113685470067,-57.0411279075965751,-12.3088150671508707],"rgb":[0.0666666666666666657,0.8,0.8],"xyz":[0.327210046173800118,0.476622018705586181,0.646038723487499689],"hpluv":[192.177050630061103,99.244272920381249,74.6113685470067],"hsluv":[192.177050630061103,98.8558017207376167,74.6113685470067]},"#11ccdd":{"lch":[75.1535687293590087,61.8087365466066316,205.702276410621693],"luv":[75.1535687293590087,-55.6933672323303881,-26.8061328768737823],"rgb":[0.0666666666666666657,0.8,0.866666666666666696],"xyz":[0.348728371724433717,0.485229348925839687,0.759368571387505686],"hpluv":[205.702276410621693,104.361325002032586,75.1535687293590087],"hsluv":[205.702276410621693,98.9124749687685352,75.1535687293590087]},"#11ccee":{"lch":[75.7461450403856418,68.3900229325434168,217.356690237772426],"luv":[75.7461450403856418,-54.3614174191380712,-41.4973677827407],"rgb":[0.0666666666666666657,0.8,0.933333333333333348],"xyz":[0.372540551990608426,0.494754221032309704,0.88477938745602891],"hpluv":[217.356690237772426,114.570165581500433,75.7461450403856418],"hsluv":[217.356690237772426,98.968985855810871,75.7461450403856418]},"#11ccff":{"lch":[76.3887144168947714,77.3228649101567811,226.666757851513921],"luv":[76.3887144168947714,-53.0620799518220849,-56.2426982736496726],"rgb":[0.0666666666666666657,0.8,1],"xyz":[0.398711600400439847,0.505222640396242428,1.02261357574781075],"hpluv":[226.666757851513921,131.304642630845649,76.3887144168947714],"hsluv":[226.666757851513921,99.9999999999969162,76.3887144168947714]},"#11dd00":{"lch":[77.1789729208637851,118.880191052714352,127.435820588671049],"luv":[77.1789729208637851,-72.2639845338074,94.3950017957916572],"rgb":[0.0666666666666666657,0.866666666666666696,0],"xyz":[0.260864802545785,0.518298306129860942,0.0862927536805420531],"hpluv":[127.435820588671049,210.367240137055802,77.1789729208637851],"hsluv":[127.435820588671049,100.000000000002302,77.1789729208637851]},"#11dd11":{"lch":[77.2032167276219,117.940964566200989,127.715012949240474],"luv":[77.2032167276219,-72.148538100067,93.2987651195291],"rgb":[0.0666666666666666657,0.866666666666666696,0.0666666666666666657],"xyz":[0.261876468045422084,0.51870297232971585,0.0916208586452976897],"hpluv":[127.715012949240474,208.973000844217893,77.2032167276219],"hsluv":[127.715012949240474,98.7048375113237739,77.2032167276219]},"#11dd22":{"lch":[77.2481249515021773,116.219968574506154,128.240715222563949],"luv":[77.2481249515021773,-71.936288170647174,91.2811674974022509],"rgb":[0.0666666666666666657,0.866666666666666696,0.133333333333333331],"xyz":[0.263751826183899141,0.519453115585106651,0.101497744841276882],"hpluv":[128.240715222563949,206.413967447437244,77.2481249515021773],"hsluv":[128.240715222563949,98.7114617332334348,77.2481249515021773]},"#11dd33":{"lch":[77.3219716074714114,113.443027450646795,129.129905575085218],"luv":[77.3219716074714114,-71.591714193384675,87.9996984996024],"rgb":[0.0666666666666666657,0.866666666666666696,0.2],"xyz":[0.266839576916356847,0.520688215878089777,0.117759898698888033],"hpluv":[129.129905575085218,202.273081507843187,77.3219716074714114],"hsluv":[129.129905575085218,98.7222220245650419,77.3219716074714114]},"#11dd44":{"lch":[77.4283833065767,109.557638087167803,130.467479357182611],"luv":[77.4283833065767,-71.1046976382296378,83.3486534805139],"rgb":[0.0666666666666666657,0.866666666666666696,0.266666666666666663],"xyz":[0.271297572160575762,0.522471413975777343,0.141238673651774671],"hpluv":[130.467479357182611,196.45511110559741,77.4283833065767],"hsluv":[130.467479357182611,98.737444128486942,77.4283833065767]},"#11dd55":{"lch":[77.5703274630482156,104.589066335953675,132.360930841179908],"luv":[77.5703274630482156,-70.4719757705036471,77.2824263854860192],"rgb":[0.0666666666666666657,0.866666666666666696,0.333333333333333315],"xyz":[0.277259986199937747,0.524856379591522093,0.172640720925748559],"hpluv":[132.360930841179908,188.974657198429043,77.5703274630482156],"hsluv":[132.360930841179908,98.7572451358875583,77.5703274630482156]},"#11dd66":{"lch":[77.7502795105496176,98.645271303892585,134.953797592355841],"luv":[77.7502795105496176,-69.6964700953403167,69.8089650895062732],"rgb":[0.0666666666666666657,0.866666666666666696,0.4],"xyz":[0.284844981973445932,0.527890377900925412,0.212588365332892548],"hpluv":[134.953797592355841,179.968822287066047,77.7502795105496176],"hsluv":[134.953797592355841,98.7815546318288114,77.7502795105496176]},"#11dd77":{"lch":[77.9703113413929714,91.9272626112809377,138.440937564009943],"luv":[77.9703113413929714,-68.7866216277350588,60.9837871589344616],"rgb":[0.0666666666666666657,0.866666666666666696,0.466666666666666674],"xyz":[0.294158994993647838,0.531615983109006263,0.261642167239290457],"hpluv":[138.440937564009943,169.723893920939275,77.9703113413929714],"hsluv":[138.440937564009943,98.8101351189296,77.9703113413929714]},"#11dd88":{"lch":[78.2321436880382919,84.7462074021241705,143.083472555296623],"luv":[78.2321436880382919,-67.7555613828794492,50.90288371727776],"rgb":[0.0666666666666666657,0.866666666666666696,0.533333333333333326],"xyz":[0.305299412095591638,0.536072149949783805,0.320315030642862597],"hpluv":[143.083472555296623,158.721324423216174,78.2321436880382919],"hsluv":[143.083472555296623,98.842607114853692,78.2321436880382919]},"#11dd99":{"lch":[78.5371801027425,77.5491781494168748,149.212222309724666],"luv":[78.5371801027425,-66.6201031545698,39.6942928810235145],"rgb":[0.0666666666666666657,0.866666666666666696,0.6],"xyz":[0.318356376204664393,0.541294935593413,0.389081708283980532],"hpluv":[149.212222309724666,147.710574340426348,78.5371801027425],"hsluv":[149.212222309724666,98.8784794246756746,78.5371801027425]},"#11ddaa":{"lch":[78.8865310768390771,70.9495750262721288,157.187121587348372],"luv":[78.8865310768390771,-65.3996173248364414,27.5087667875819264],"rgb":[0.0666666666666666657,0.866666666666666696,0.66666666666666663],"xyz":[0.333414069169916893,0.547318012779514085,0.468385557900979133],"hpluv":[157.187121587348372,137.807232739715857,78.8865310768390771],"hsluv":[157.187121587348372,98.9171828916172728,78.8865310768390771]},"#11ddbb":{"lch":[79.2810328759594398,65.7363215025974483,167.247861929956969],"luv":[79.2810328759594398,-64.1148749316804611,14.5102300873497096],"rgb":[0.0666666666666666657,0.866666666666666696,0.733333333333333282],"xyz":[0.350551661277253568,0.554173049622448843,0.558643542999620824],"hpluv":[167.247861929956969,130.572542181043048,79.2810328759594398],"hsluv":[167.247861929956969,98.9581049946704496,79.2810328759594398]},"#11ddcc":{"lch":[79.7212637056701396,62.7929370759791,179.209087927276954],"luv":[79.7212637056701396,-62.7869545437069903,0.866767416521026846],"rgb":[0.0666666666666666657,0.866666666666666696,0.8],"xyz":[0.369844036720975322,0.561889999799937701,0.660250053669891],"hpluv":[179.209087927276954,127.935201467087722,79.7212637056701396],"hsluv":[179.209087927276954,99.0006225499112,79.7212637056701396]},"#11dddd":{"lch":[80.2075587483664378,62.8503941808937796,192.177050630061132],"luv":[80.2075587483664378,-61.4362892449526,-13.2572400032679489],"rgb":[0.0666666666666666657,0.866666666666666696,0.866666666666666696],"xyz":[0.39136236227160881,0.570497330020191207,0.773579901569897],"hpluv":[192.177050630061132,131.767009082741112,80.2075587483664378],"hsluv":[192.177050630061132,99.0441302201931109,80.2075587483664378]},"#11ddee":{"lch":[80.7400249746916643,66.1629514334268691,204.757295278220823],"luv":[80.7400249746916643,-60.0819052998990202,-27.707414132610225],"rgb":[0.0666666666666666657,0.866666666666666696,0.933333333333333348],"xyz":[0.415174542537783575,0.580022202126661224,0.8989907176384202],"hpluv":[204.757295278220823,143.22067561241397,80.7400249746916643],"hsluv":[204.757295278220823,99.0880633014724594,80.7400249746916643]},"#11ddff":{"lch":[81.3185562290371848,72.4120095186264194,215.786316478612605],"luv":[81.3185562290371848,-58.7408753400219084,-42.3439332940817934],"rgb":[0.0666666666666666657,0.866666666666666696,1],"xyz":[0.441345590947614941,0.590490621490594,1.03682490593020216],"hpluv":[215.786316478612605,162.428807277722512,81.3185562290371848],"hsluv":[215.786316478612605,99.9999999999959925,81.3185562290371848]}} \ No newline at end of file diff --git a/vendor/github.com/lucasb-eyer/go-colorful/hsluv.go b/vendor/github.com/lucasb-eyer/go-colorful/hsluv.go deleted file mode 100644 index d19fb6443d..0000000000 --- a/vendor/github.com/lucasb-eyer/go-colorful/hsluv.go +++ /dev/null @@ -1,207 +0,0 @@ -package colorful - -import "math" - -// Source: https://github.com/hsluv/hsluv-go -// Under MIT License -// Modified so that Saturation and Luminance are in [0..1] instead of [0..100]. - -// HSLuv uses a rounded version of the D65. This has no impact on the final RGB -// values, but to keep high levels of accuracy for internal operations and when -// comparing to the test values, this modified white reference is used internally. -// -// See this GitHub thread for details on these values: -// https://github.com/hsluv/hsluv/issues/79 -var hSLuvD65 = [3]float64{0.95045592705167, 1.0, 1.089057750759878} - -func LuvLChToHSLuv(l, c, h float64) (float64, float64, float64) { - // [-1..1] but the code expects it to be [-100..100] - c *= 100.0 - l *= 100.0 - - var s, max float64 - if l > 99.9999999 || l < 0.00000001 { - s = 0.0 - } else { - max = maxChromaForLH(l, h) - s = c / max * 100.0 - } - return h, clamp01(s / 100.0), clamp01(l / 100.0) -} - -func HSLuvToLuvLCh(h, s, l float64) (float64, float64, float64) { - l *= 100.0 - s *= 100.0 - - var c, max float64 - if l > 99.9999999 || l < 0.00000001 { - c = 0.0 - } else { - max = maxChromaForLH(l, h) - c = max / 100.0 * s - } - - // c is [-100..100], but for LCh it's supposed to be almost [-1..1] - return clamp01(l / 100.0), c / 100.0, h -} - -func LuvLChToHPLuv(l, c, h float64) (float64, float64, float64) { - // [-1..1] but the code expects it to be [-100..100] - c *= 100.0 - l *= 100.0 - - var s, max float64 - if l > 99.9999999 || l < 0.00000001 { - s = 0.0 - } else { - max = maxSafeChromaForL(l) - s = c / max * 100.0 - } - return h, s / 100.0, l / 100.0 -} - -func HPLuvToLuvLCh(h, s, l float64) (float64, float64, float64) { - // [-1..1] but the code expects it to be [-100..100] - l *= 100.0 - s *= 100.0 - - var c, max float64 - if l > 99.9999999 || l < 0.00000001 { - c = 0.0 - } else { - max = maxSafeChromaForL(l) - c = max / 100.0 * s - } - return l / 100.0, c / 100.0, h -} - -// HSLuv creates a new Color from values in the HSLuv color space. -// Hue in [0..360], a Saturation [0..1], and a Luminance (lightness) in [0..1]. -// -// The returned color values are clamped (using .Clamped), so this will never output -// an invalid color. -func HSLuv(h, s, l float64) Color { - // HSLuv -> LuvLCh -> CIELUV -> CIEXYZ -> Linear RGB -> sRGB - l, u, v := LuvLChToLuv(HSLuvToLuvLCh(h, s, l)) - return LinearRgb(XyzToLinearRgb(LuvToXyzWhiteRef(l, u, v, hSLuvD65))).Clamped() -} - -// HPLuv creates a new Color from values in the HPLuv color space. -// Hue in [0..360], a Saturation [0..1], and a Luminance (lightness) in [0..1]. -// -// The returned color values are clamped (using .Clamped), so this will never output -// an invalid color. -func HPLuv(h, s, l float64) Color { - // HPLuv -> LuvLCh -> CIELUV -> CIEXYZ -> Linear RGB -> sRGB - l, u, v := LuvLChToLuv(HPLuvToLuvLCh(h, s, l)) - return LinearRgb(XyzToLinearRgb(LuvToXyzWhiteRef(l, u, v, hSLuvD65))).Clamped() -} - -// HSLuv returns the Hue, Saturation and Luminance of the color in the HSLuv -// color space. Hue in [0..360], a Saturation [0..1], and a Luminance -// (lightness) in [0..1]. -func (col Color) HSLuv() (h, s, l float64) { - // sRGB -> Linear RGB -> CIEXYZ -> CIELUV -> LuvLCh -> HSLuv - return LuvLChToHSLuv(col.LuvLChWhiteRef(hSLuvD65)) -} - -// HPLuv returns the Hue, Saturation and Luminance of the color in the HSLuv -// color space. Hue in [0..360], a Saturation [0..1], and a Luminance -// (lightness) in [0..1]. -// -// Note that HPLuv can only represent pastel colors, and so the Saturation -// value could be much larger than 1 for colors it can't represent. -func (col Color) HPLuv() (h, s, l float64) { - return LuvLChToHPLuv(col.LuvLChWhiteRef(hSLuvD65)) -} - -// DistanceHSLuv calculates Euclidan distance in the HSLuv colorspace. No idea -// how useful this is. -// -// The Hue value is divided by 100 before the calculation, so that H, S, and L -// have the same relative ranges. -func (c1 Color) DistanceHSLuv(c2 Color) float64 { - h1, s1, l1 := c1.HSLuv() - h2, s2, l2 := c2.HSLuv() - return math.Sqrt(sq((h1-h2)/100.0) + sq(s1-s2) + sq(l1-l2)) -} - -// DistanceHPLuv calculates Euclidean distance in the HPLuv colorspace. No idea -// how useful this is. -// -// The Hue value is divided by 100 before the calculation, so that H, S, and L -// have the same relative ranges. -func (c1 Color) DistanceHPLuv(c2 Color) float64 { - h1, s1, l1 := c1.HPLuv() - h2, s2, l2 := c2.HPLuv() - return math.Sqrt(sq((h1-h2)/100.0) + sq(s1-s2) + sq(l1-l2)) -} - -var m = [3][3]float64{ - {3.2409699419045214, -1.5373831775700935, -0.49861076029300328}, - {-0.96924363628087983, 1.8759675015077207, 0.041555057407175613}, - {0.055630079696993609, -0.20397695888897657, 1.0569715142428786}, -} - -const kappa = 903.2962962962963 -const epsilon = 0.0088564516790356308 - -func maxChromaForLH(l, h float64) float64 { - hRad := h / 360.0 * math.Pi * 2.0 - minLength := math.MaxFloat64 - for _, line := range getBounds(l) { - length := lengthOfRayUntilIntersect(hRad, line[0], line[1]) - if length > 0.0 && length < minLength { - minLength = length - } - } - return minLength -} - -func getBounds(l float64) [6][2]float64 { - var sub2 float64 - var ret [6][2]float64 - sub1 := math.Pow(l+16.0, 3.0) / 1560896.0 - if sub1 > epsilon { - sub2 = sub1 - } else { - sub2 = l / kappa - } - for i := range m { - for k := 0; k < 2; k++ { - top1 := (284517.0*m[i][0] - 94839.0*m[i][2]) * sub2 - top2 := (838422.0*m[i][2]+769860.0*m[i][1]+731718.0*m[i][0])*l*sub2 - 769860.0*float64(k)*l - bottom := (632260.0*m[i][2]-126452.0*m[i][1])*sub2 + 126452.0*float64(k) - ret[i*2+k][0] = top1 / bottom - ret[i*2+k][1] = top2 / bottom - } - } - return ret -} - -func lengthOfRayUntilIntersect(theta, x, y float64) (length float64) { - length = y / (math.Sin(theta) - x*math.Cos(theta)) - return -} - -func maxSafeChromaForL(l float64) float64 { - minLength := math.MaxFloat64 - for _, line := range getBounds(l) { - m1 := line[0] - b1 := line[1] - x := intersectLineLine(m1, b1, -1.0/m1, 0.0) - dist := distanceFromPole(x, b1+x*m1) - if dist < minLength { - minLength = dist - } - } - return minLength -} - -func intersectLineLine(x1, y1, x2, y2 float64) float64 { - return (y1 - y2) / (x2 - x1) -} - -func distanceFromPole(x, y float64) float64 { - return math.Sqrt(math.Pow(x, 2.0) + math.Pow(y, 2.0)) -} diff --git a/vendor/github.com/lucasb-eyer/go-colorful/soft_palettegen.go b/vendor/github.com/lucasb-eyer/go-colorful/soft_palettegen.go deleted file mode 100644 index 9f7bf6f7c7..0000000000 --- a/vendor/github.com/lucasb-eyer/go-colorful/soft_palettegen.go +++ /dev/null @@ -1,185 +0,0 @@ -// Largely inspired by the descriptions in http://lab.medialab.sciences-po.fr/iwanthue/ -// but written from scratch. - -package colorful - -import ( - "fmt" - "math" - "math/rand" -) - -// The algorithm works in L*a*b* color space and converts to RGB in the end. -// L* in [0..1], a* and b* in [-1..1] -type lab_t struct { - L, A, B float64 -} - -type SoftPaletteSettings struct { - // A function which can be used to restrict the allowed color-space. - CheckColor func(l, a, b float64) bool - - // The higher, the better quality but the slower. Usually two figures. - Iterations int - - // Use up to 160000 or 8000 samples of the L*a*b* space (and thus calls to CheckColor). - // Set this to true only if your CheckColor shapes the Lab space weirdly. - ManySamples bool -} - -// Yeah, windows-stype Foo, FooEx, screw you golang... -// Uses K-means to cluster the color-space and return the means of the clusters -// as a new palette of distinctive colors. Falls back to K-medoid if the mean -// happens to fall outside of the color-space, which can only happen if you -// specify a CheckColor function. -func SoftPaletteEx(colorsCount int, settings SoftPaletteSettings) ([]Color, error) { - - // Checks whether it's a valid RGB and also fulfills the potentially provided constraint. - check := func(col lab_t) bool { - c := Lab(col.L, col.A, col.B) - return c.IsValid() && (settings.CheckColor == nil || settings.CheckColor(col.L, col.A, col.B)) - } - - // Sample the color space. These will be the points k-means is run on. - dl := 0.05 - dab := 0.1 - if settings.ManySamples { - dl = 0.01 - dab = 0.05 - } - - samples := make([]lab_t, 0, int(1.0/dl*2.0/dab*2.0/dab)) - for l := 0.0; l <= 1.0; l += dl { - for a := -1.0; a <= 1.0; a += dab { - for b := -1.0; b <= 1.0; b += dab { - if check(lab_t{l, a, b}) { - samples = append(samples, lab_t{l, a, b}) - } - } - } - } - - // That would cause some infinite loops down there... - if len(samples) < colorsCount { - return nil, fmt.Errorf("palettegen: more colors requested (%v) than samples available (%v). Your requested color count may be wrong, you might want to use many samples or your constraint function makes the valid color space too small", colorsCount, len(samples)) - } else if len(samples) == colorsCount { - return labs2cols(samples), nil // Oops? - } - - // We take the initial means out of the samples, so they are in fact medoids. - // This helps us avoid infinite loops or arbitrary cutoffs with too restrictive constraints. - means := make([]lab_t, colorsCount) - for i := 0; i < colorsCount; i++ { - for means[i] = samples[rand.Intn(len(samples))]; in(means, i, means[i]); means[i] = samples[rand.Intn(len(samples))] { - } - } - - clusters := make([]int, len(samples)) - samples_used := make([]bool, len(samples)) - - // The actual k-means/medoid iterations - for i := 0; i < settings.Iterations; i++ { - // Reassing the samples to clusters, i.e. to their closest mean. - // By the way, also check if any sample is used as a medoid and if so, mark that. - for isample, sample := range samples { - samples_used[isample] = false - mindist := math.Inf(+1) - for imean, mean := range means { - dist := lab_dist(sample, mean) - if dist < mindist { - mindist = dist - clusters[isample] = imean - } - - // Mark samples which are used as a medoid. - if lab_eq(sample, mean) { - samples_used[isample] = true - } - } - } - - // Compute new means according to the samples. - for imean := range means { - // The new mean is the average of all samples belonging to it.. - nsamples := 0 - newmean := lab_t{0.0, 0.0, 0.0} - for isample, sample := range samples { - if clusters[isample] == imean { - nsamples++ - newmean.L += sample.L - newmean.A += sample.A - newmean.B += sample.B - } - } - if nsamples > 0 { - newmean.L /= float64(nsamples) - newmean.A /= float64(nsamples) - newmean.B /= float64(nsamples) - } else { - // That mean doesn't have any samples? Get a new mean from the sample list! - var inewmean int - for inewmean = rand.Intn(len(samples_used)); samples_used[inewmean]; inewmean = rand.Intn(len(samples_used)) { - } - newmean = samples[inewmean] - samples_used[inewmean] = true - } - - // But now we still need to check whether the new mean is an allowed color. - if nsamples > 0 && check(newmean) { - // It does, life's good (TM) - means[imean] = newmean - } else { - // New mean isn't an allowed color or doesn't have any samples! - // Switch to medoid mode and pick the closest (unused) sample. - // This should always find something thanks to len(samples) >= colorsCount - mindist := math.Inf(+1) - for isample, sample := range samples { - if !samples_used[isample] { - dist := lab_dist(sample, newmean) - if dist < mindist { - mindist = dist - newmean = sample - } - } - } - } - } - } - return labs2cols(means), nil -} - -// A wrapper which uses common parameters. -func SoftPalette(colorsCount int) ([]Color, error) { - return SoftPaletteEx(colorsCount, SoftPaletteSettings{nil, 50, false}) -} - -func in(haystack []lab_t, upto int, needle lab_t) bool { - for i := 0; i < upto && i < len(haystack); i++ { - if haystack[i] == needle { - return true - } - } - return false -} - -const LAB_DELTA = 1e-6 - -func lab_eq(lab1, lab2 lab_t) bool { - return math.Abs(lab1.L-lab2.L) < LAB_DELTA && - math.Abs(lab1.A-lab2.A) < LAB_DELTA && - math.Abs(lab1.B-lab2.B) < LAB_DELTA -} - -// That's faster than using colorful's DistanceLab since we would have to -// convert back and forth for that. Here is no conversion. -func lab_dist(lab1, lab2 lab_t) float64 { - return math.Sqrt(sq(lab1.L-lab2.L) + sq(lab1.A-lab2.A) + sq(lab1.B-lab2.B)) -} - -func labs2cols(labs []lab_t) (cols []Color) { - cols = make([]Color, len(labs)) - for k, v := range labs { - cols[k] = Lab(v.L, v.A, v.B) - } - return cols -} diff --git a/vendor/github.com/lucasb-eyer/go-colorful/warm_palettegen.go b/vendor/github.com/lucasb-eyer/go-colorful/warm_palettegen.go deleted file mode 100644 index 00f42a5cc7..0000000000 --- a/vendor/github.com/lucasb-eyer/go-colorful/warm_palettegen.go +++ /dev/null @@ -1,25 +0,0 @@ -package colorful - -import ( - "math/rand" -) - -// Uses the HSV color space to generate colors with similar S,V but distributed -// evenly along their Hue. This is fast but not always pretty. -// If you've got time to spare, use Lab (the non-fast below). -func FastWarmPalette(colorsCount int) (colors []Color) { - colors = make([]Color, colorsCount) - - for i := 0; i < colorsCount; i++ { - colors[i] = Hsv(float64(i)*(360.0/float64(colorsCount)), 0.55+rand.Float64()*0.2, 0.35+rand.Float64()*0.2) - } - return -} - -func WarmPalette(colorsCount int) ([]Color, error) { - warmy := func(l, a, b float64) bool { - _, c, _ := LabToHcl(l, a, b) - return 0.1 <= c && c <= 0.4 && 0.2 <= l && l <= 0.5 - } - return SoftPaletteEx(colorsCount, SoftPaletteSettings{warmy, 50, true}) -} diff --git a/vendor/github.com/macabu/inamedparam/.gitignore b/vendor/github.com/macabu/inamedparam/.gitignore deleted file mode 100644 index f8d51e94cb..0000000000 --- a/vendor/github.com/macabu/inamedparam/.gitignore +++ /dev/null @@ -1,22 +0,0 @@ -# If you prefer the allow list template instead of the deny list, see community template: -# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore -# -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib -inamedparam - -# Test binary, built with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -# Dependency directories (remove the comment below to include it) -# vendor/ - -# Go workspace file -go.work diff --git a/vendor/github.com/macabu/inamedparam/.golangci.yml b/vendor/github.com/macabu/inamedparam/.golangci.yml deleted file mode 100644 index 7f301af5a3..0000000000 --- a/vendor/github.com/macabu/inamedparam/.golangci.yml +++ /dev/null @@ -1,21 +0,0 @@ -run: - timeout: 30s - -linters: - enable-all: true - disable: - - cyclop - - depguard - - exhaustruct - - forcetypeassert - - gochecknoglobals - - gocognit - - nilnil - - paralleltest - -linters-settings: - gci: - sections: - - standard - - default - - localmodule diff --git a/vendor/github.com/macabu/inamedparam/LICENSE-MIT b/vendor/github.com/macabu/inamedparam/LICENSE-MIT deleted file mode 100644 index b95f480ee5..0000000000 --- a/vendor/github.com/macabu/inamedparam/LICENSE-MIT +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 Matheus Macabu - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/macabu/inamedparam/README.md b/vendor/github.com/macabu/inamedparam/README.md deleted file mode 100644 index 56fce4ff0f..0000000000 --- a/vendor/github.com/macabu/inamedparam/README.md +++ /dev/null @@ -1,44 +0,0 @@ -# inamedparam - -A linter that reports interfaces with unnamed method parameters. - -## Flags/Config -```sh --skip-single-param - skip interfaces with a single unnamed parameter -``` - -## Usage - -### Standalone -You can run it standalone through `go vet`. - -You must install the binary to your `$GOBIN` folder like so: -```sh -$ go install github.com/macabu/inamedparam/cmd/inamedparam@latest -``` - -And then navigate to your Go project's root folder, where can run `go vet` in the following way: -```sh -$ go vet -vettool=$(which inamedparam) ./... -``` - -### golangci-lint -`inamedparam` was added as a linter to `golangci-lint` on version `v1.55.0`. It is disabled by default. - -To enable it, you can add it to your `.golangci.yml` file, as such: -```yaml -run: - timeout: 30s - -linters: - disable-all: true - enable: - - inamedparam - -linters-settings: - inamedparam: - # Skips check for interface methods with only a single parameter. - # Default: false - skip-single-param: true -``` diff --git a/vendor/github.com/macabu/inamedparam/inamedparam.go b/vendor/github.com/macabu/inamedparam/inamedparam.go deleted file mode 100644 index 932bd3b593..0000000000 --- a/vendor/github.com/macabu/inamedparam/inamedparam.go +++ /dev/null @@ -1,97 +0,0 @@ -package inamedparam - -import ( - "flag" - "go/ast" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/inspector" -) - -const ( - analyzerName = "inamedparam" - - flagSkipSingleParam = "skip-single-param" -) - -var Analyzer = &analysis.Analyzer{ - Name: analyzerName, - Doc: "reports interfaces with unnamed method parameters", - Run: run, - Flags: flags(), - Requires: []*analysis.Analyzer{ - inspect.Analyzer, - }, -} - -func flags() flag.FlagSet { - flags := flag.NewFlagSet(analyzerName, flag.ExitOnError) - - flags.Bool(flagSkipSingleParam, false, "skip interface methods with a single unnamed parameter") - - return *flags -} - -func run(pass *analysis.Pass) (any, error) { - inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - - types := []ast.Node{ - &ast.InterfaceType{}, - } - - var skipSingleParam bool - if f := pass.Analyzer.Flags.Lookup(flagSkipSingleParam); f != nil { - skipSingleParam, _ = f.Value.(flag.Getter).Get().(bool) - } - - inspect.Preorder(types, func(n ast.Node) { - interfaceType, ok := n.(*ast.InterfaceType) - if !ok || interfaceType == nil || interfaceType.Methods == nil { - return - } - - for _, method := range interfaceType.Methods.List { - interfaceFunc, ok := method.Type.(*ast.FuncType) - if !ok || interfaceFunc == nil || interfaceFunc.Params == nil { - continue - } - - // Improvement: add test case to reproduce this. Help wanted. - if len(method.Names) == 0 { - continue - } - - methodName := method.Names[0].Name - - if skipSingleParam && len(interfaceFunc.Params.List) == 1 { - continue - } - - for _, param := range interfaceFunc.Params.List { - if param.Names == nil { - var builtParamType string - - switch paramType := param.Type.(type) { - case *ast.SelectorExpr: - if ident := paramType.X.(*ast.Ident); ident != nil { - builtParamType += ident.Name + "." - } - - builtParamType += paramType.Sel.Name - case *ast.Ident: - builtParamType = paramType.Name - } - - if builtParamType != "" { - pass.Reportf(param.Pos(), "interface method %v must have named param for type %v", methodName, builtParamType) - } else { - pass.Reportf(param.Pos(), "interface method %v must have all named params", methodName) - } - } - } - } - }) - - return nil, nil -} diff --git a/vendor/github.com/magiconair/properties/.gitignore b/vendor/github.com/magiconair/properties/.gitignore deleted file mode 100644 index e7081ff522..0000000000 --- a/vendor/github.com/magiconair/properties/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -*.sublime-project -*.sublime-workspace -*.un~ -*.swp -.idea/ -*.iml diff --git a/vendor/github.com/magiconair/properties/.travis.yml b/vendor/github.com/magiconair/properties/.travis.yml deleted file mode 100644 index baf9031dfe..0000000000 --- a/vendor/github.com/magiconair/properties/.travis.yml +++ /dev/null @@ -1,17 +0,0 @@ -language: go -go: - - 1.3.x - - 1.4.x - - 1.5.x - - 1.6.x - - 1.7.x - - 1.8.x - - 1.9.x - - "1.10.x" - - "1.11.x" - - "1.12.x" - - "1.13.x" - - "1.14.x" - - "1.15.x" - - "1.16.x" - - tip diff --git a/vendor/github.com/magiconair/properties/CHANGELOG.md b/vendor/github.com/magiconair/properties/CHANGELOG.md deleted file mode 100644 index ff8d02535a..0000000000 --- a/vendor/github.com/magiconair/properties/CHANGELOG.md +++ /dev/null @@ -1,160 +0,0 @@ -## Changelog - -### [1.8.2](https://github.com/magiconair/properties/tree/v1.8.2) - 25 Aug 2020 - - * [PR #36](https://github.com/magiconair/properties/pull/36): Escape backslash on write - - This patch ensures that backslashes are escaped on write. Existing applications which - rely on the old behavior may need to be updated. - - Thanks to [@apesternikov](https://github.com/apesternikov) for the patch. - - * [PR #42](https://github.com/magiconair/properties/pull/42): Made Content-Type check whitespace agnostic in LoadURL() - - Thanks to [@aliras1](https://github.com/aliras1) for the patch. - - * [PR #41](https://github.com/magiconair/properties/pull/41): Make key/value separator configurable on Write() - - Thanks to [@mkjor](https://github.com/mkjor) for the patch. - - * [PR #40](https://github.com/magiconair/properties/pull/40): Add method to return a sorted list of keys - - Thanks to [@mkjor](https://github.com/mkjor) for the patch. - -### [1.8.1](https://github.com/magiconair/properties/tree/v1.8.1) - 10 May 2019 - - * [PR #35](https://github.com/magiconair/properties/pull/35): Close body always after request - - This patch ensures that in `LoadURL` the response body is always closed. - - Thanks to [@liubog2008](https://github.com/liubog2008) for the patch. - -### [1.8](https://github.com/magiconair/properties/tree/v1.8) - 15 May 2018 - - * [PR #26](https://github.com/magiconair/properties/pull/26): Disable expansion during loading - - This adds the option to disable property expansion during loading. - - Thanks to [@kmala](https://github.com/kmala) for the patch. - -### [1.7.6](https://github.com/magiconair/properties/tree/v1.7.6) - 14 Feb 2018 - - * [PR #29](https://github.com/magiconair/properties/pull/29): Reworked expansion logic to handle more complex cases. - - See PR for an example. - - Thanks to [@yobert](https://github.com/yobert) for the fix. - -### [1.7.5](https://github.com/magiconair/properties/tree/v1.7.5) - 13 Feb 2018 - - * [PR #28](https://github.com/magiconair/properties/pull/28): Support duplicate expansions in the same value - - Values which expand the same key multiple times (e.g. `key=${a} ${a}`) will no longer fail - with a `circular reference error`. - - Thanks to [@yobert](https://github.com/yobert) for the fix. - -### [1.7.4](https://github.com/magiconair/properties/tree/v1.7.4) - 31 Oct 2017 - - * [Issue #23](https://github.com/magiconair/properties/issues/23): Ignore blank lines with whitespaces - - * [PR #24](https://github.com/magiconair/properties/pull/24): Update keys when DisableExpansion is enabled - - Thanks to [@mgurov](https://github.com/mgurov) for the fix. - -### [1.7.3](https://github.com/magiconair/properties/tree/v1.7.3) - 10 Jul 2017 - - * [Issue #17](https://github.com/magiconair/properties/issues/17): Add [SetValue()](http://godoc.org/github.com/magiconair/properties#Properties.SetValue) method to set values generically - * [Issue #22](https://github.com/magiconair/properties/issues/22): Add [LoadMap()](http://godoc.org/github.com/magiconair/properties#LoadMap) function to load properties from a string map - -### [1.7.2](https://github.com/magiconair/properties/tree/v1.7.2) - 20 Mar 2017 - - * [Issue #15](https://github.com/magiconair/properties/issues/15): Drop gocheck dependency - * [PR #21](https://github.com/magiconair/properties/pull/21): Add [Map()](http://godoc.org/github.com/magiconair/properties#Properties.Map) and [FilterFunc()](http://godoc.org/github.com/magiconair/properties#Properties.FilterFunc) - -### [1.7.1](https://github.com/magiconair/properties/tree/v1.7.1) - 13 Jan 2017 - - * [Issue #14](https://github.com/magiconair/properties/issues/14): Decouple TestLoadExpandedFile from `$USER` - * [PR #12](https://github.com/magiconair/properties/pull/12): Load from files and URLs - * [PR #16](https://github.com/magiconair/properties/pull/16): Keep gofmt happy - * [PR #18](https://github.com/magiconair/properties/pull/18): Fix Delete() function - -### [1.7.0](https://github.com/magiconair/properties/tree/v1.7.0) - 20 Mar 2016 - - * [Issue #10](https://github.com/magiconair/properties/issues/10): Add [LoadURL,LoadURLs,MustLoadURL,MustLoadURLs](http://godoc.org/github.com/magiconair/properties#LoadURL) method to load properties from a URL. - * [Issue #11](https://github.com/magiconair/properties/issues/11): Add [LoadString,MustLoadString](http://godoc.org/github.com/magiconair/properties#LoadString) method to load properties from an UTF8 string. - * [PR #8](https://github.com/magiconair/properties/pull/8): Add [MustFlag](http://godoc.org/github.com/magiconair/properties#Properties.MustFlag) method to provide overrides via command line flags. (@pascaldekloe) - -### [1.6.0](https://github.com/magiconair/properties/tree/v1.6.0) - 11 Dec 2015 - - * Add [Decode](http://godoc.org/github.com/magiconair/properties#Properties.Decode) method to populate struct from properties via tags. - -### [1.5.6](https://github.com/magiconair/properties/tree/v1.5.6) - 18 Oct 2015 - - * Vendored in gopkg.in/check.v1 - -### [1.5.5](https://github.com/magiconair/properties/tree/v1.5.5) - 31 Jul 2015 - - * [PR #6](https://github.com/magiconair/properties/pull/6): Add [Delete](http://godoc.org/github.com/magiconair/properties#Properties.Delete) method to remove keys including comments. (@gerbenjacobs) - -### [1.5.4](https://github.com/magiconair/properties/tree/v1.5.4) - 23 Jun 2015 - - * [Issue #5](https://github.com/magiconair/properties/issues/5): Allow disabling of property expansion [DisableExpansion](http://godoc.org/github.com/magiconair/properties#Properties.DisableExpansion). When property expansion is disabled Properties become a simple key/value store and don't check for circular references. - -### [1.5.3](https://github.com/magiconair/properties/tree/v1.5.3) - 02 Jun 2015 - - * [Issue #4](https://github.com/magiconair/properties/issues/4): Maintain key order in [Filter()](http://godoc.org/github.com/magiconair/properties#Properties.Filter), [FilterPrefix()](http://godoc.org/github.com/magiconair/properties#Properties.FilterPrefix) and [FilterRegexp()](http://godoc.org/github.com/magiconair/properties#Properties.FilterRegexp) - -### [1.5.2](https://github.com/magiconair/properties/tree/v1.5.2) - 10 Apr 2015 - - * [Issue #3](https://github.com/magiconair/properties/issues/3): Don't print comments in [WriteComment()](http://godoc.org/github.com/magiconair/properties#Properties.WriteComment) if they are all empty - * Add clickable links to README - -### [1.5.1](https://github.com/magiconair/properties/tree/v1.5.1) - 08 Dec 2014 - - * Added [GetParsedDuration()](http://godoc.org/github.com/magiconair/properties#Properties.GetParsedDuration) and [MustGetParsedDuration()](http://godoc.org/github.com/magiconair/properties#Properties.MustGetParsedDuration) for values specified compatible with - [time.ParseDuration()](http://golang.org/pkg/time/#ParseDuration). - -### [1.5.0](https://github.com/magiconair/properties/tree/v1.5.0) - 18 Nov 2014 - - * Added support for single and multi-line comments (reading, writing and updating) - * The order of keys is now preserved - * Calling [Set()](http://godoc.org/github.com/magiconair/properties#Properties.Set) with an empty key now silently ignores the call and does not create a new entry - * Added a [MustSet()](http://godoc.org/github.com/magiconair/properties#Properties.MustSet) method - * Migrated test library from launchpad.net/gocheck to [gopkg.in/check.v1](http://gopkg.in/check.v1) - -### [1.4.2](https://github.com/magiconair/properties/tree/v1.4.2) - 15 Nov 2014 - - * [Issue #2](https://github.com/magiconair/properties/issues/2): Fixed goroutine leak in parser which created two lexers but cleaned up only one - -### [1.4.1](https://github.com/magiconair/properties/tree/v1.4.1) - 13 Nov 2014 - - * [Issue #1](https://github.com/magiconair/properties/issues/1): Fixed bug in Keys() method which returned an empty string - -### [1.4.0](https://github.com/magiconair/properties/tree/v1.4.0) - 23 Sep 2014 - - * Added [Keys()](http://godoc.org/github.com/magiconair/properties#Properties.Keys) to get the keys - * Added [Filter()](http://godoc.org/github.com/magiconair/properties#Properties.Filter), [FilterRegexp()](http://godoc.org/github.com/magiconair/properties#Properties.FilterRegexp) and [FilterPrefix()](http://godoc.org/github.com/magiconair/properties#Properties.FilterPrefix) to get a subset of the properties - -### [1.3.0](https://github.com/magiconair/properties/tree/v1.3.0) - 18 Mar 2014 - -* Added support for time.Duration -* Made MustXXX() failure beha[ior configurable (log.Fatal, panic](https://github.com/magiconair/properties/tree/vior configurable (log.Fatal, panic) - custom) -* Changed default of MustXXX() failure from panic to log.Fatal - -### [1.2.0](https://github.com/magiconair/properties/tree/v1.2.0) - 05 Mar 2014 - -* Added MustGet... functions -* Added support for int and uint with range checks on 32 bit platforms - -### [1.1.0](https://github.com/magiconair/properties/tree/v1.1.0) - 20 Jan 2014 - -* Renamed from goproperties to properties -* Added support for expansion of environment vars in - filenames and value expressions -* Fixed bug where value expressions were not at the - start of the string - -### [1.0.0](https://github.com/magiconair/properties/tree/v1.0.0) - 7 Jan 2014 - -* Initial release diff --git a/vendor/github.com/magiconair/properties/LICENSE.md b/vendor/github.com/magiconair/properties/LICENSE.md deleted file mode 100644 index 79c87e3e6f..0000000000 --- a/vendor/github.com/magiconair/properties/LICENSE.md +++ /dev/null @@ -1,24 +0,0 @@ -Copyright (c) 2013-2020, Frank Schroeder - -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/magiconair/properties/README.md b/vendor/github.com/magiconair/properties/README.md deleted file mode 100644 index e2edda025b..0000000000 --- a/vendor/github.com/magiconair/properties/README.md +++ /dev/null @@ -1,128 +0,0 @@ -[![](https://img.shields.io/github/tag/magiconair/properties.svg?style=flat-square&label=release)](https://github.com/magiconair/properties/releases) -[![Travis CI Status](https://img.shields.io/travis/magiconair/properties.svg?branch=master&style=flat-square&label=travis)](https://travis-ci.org/magiconair/properties) -[![License](https://img.shields.io/badge/License-BSD%202--Clause-orange.svg?style=flat-square)](https://raw.githubusercontent.com/magiconair/properties/master/LICENSE) -[![GoDoc](http://img.shields.io/badge/godoc-reference-5272B4.svg?style=flat-square)](http://godoc.org/github.com/magiconair/properties) - -# Overview - -#### Please run `git pull --tags` to update the tags. See [below](#updated-git-tags) why. - -properties is a Go library for reading and writing properties files. - -It supports reading from multiple files or URLs and Spring style recursive -property expansion of expressions like `${key}` to their corresponding value. -Value expressions can refer to other keys like in `${key}` or to environment -variables like in `${USER}`. Filenames can also contain environment variables -like in `/home/${USER}/myapp.properties`. - -Properties can be decoded into structs, maps, arrays and values through -struct tags. - -Comments and the order of keys are preserved. Comments can be modified -and can be written to the output. - -The properties library supports both ISO-8859-1 and UTF-8 encoded data. - -Starting from version 1.3.0 the behavior of the MustXXX() functions is -configurable by providing a custom `ErrorHandler` function. The default has -changed from `panic` to `log.Fatal` but this is configurable and custom -error handling functions can be provided. See the package documentation for -details. - -Read the full documentation on [![GoDoc](http://img.shields.io/badge/godoc-reference-5272B4.svg?style=flat-square)](http://godoc.org/github.com/magiconair/properties) - -## Getting Started - -```go -import ( - "flag" - "github.com/magiconair/properties" -) - -func main() { - // init from a file - p := properties.MustLoadFile("${HOME}/config.properties", properties.UTF8) - - // or multiple files - p = properties.MustLoadFiles([]string{ - "${HOME}/config.properties", - "${HOME}/config-${USER}.properties", - }, properties.UTF8, true) - - // or from a map - p = properties.LoadMap(map[string]string{"key": "value", "abc": "def"}) - - // or from a string - p = properties.MustLoadString("key=value\nabc=def") - - // or from a URL - p = properties.MustLoadURL("http://host/path") - - // or from multiple URLs - p = properties.MustLoadURL([]string{ - "http://host/config", - "http://host/config-${USER}", - }, true) - - // or from flags - p.MustFlag(flag.CommandLine) - - // get values through getters - host := p.MustGetString("host") - port := p.GetInt("port", 8080) - - // or through Decode - type Config struct { - Host string `properties:"host"` - Port int `properties:"port,default=9000"` - Accept []string `properties:"accept,default=image/png;image;gif"` - Timeout time.Duration `properties:"timeout,default=5s"` - } - var cfg Config - if err := p.Decode(&cfg); err != nil { - log.Fatal(err) - } -} - -``` - -## Installation and Upgrade - -``` -$ go get -u github.com/magiconair/properties -``` - -## License - -2 clause BSD license. See [LICENSE](https://github.com/magiconair/properties/blob/master/LICENSE) file for details. - -## ToDo - -* Dump contents with passwords and secrets obscured - -## Updated Git tags - -#### 13 Feb 2018 - -I realized that all of the git tags I had pushed before v1.7.5 were lightweight tags -and I've only recently learned that this doesn't play well with `git describe` 😞 - -I have replaced all lightweight tags with signed tags using this script which should -retain the commit date, name and email address. Please run `git pull --tags` to update them. - -Worst case you have to reclone the repo. - -```shell -#!/bin/bash -tag=$1 -echo "Updating $tag" -date=$(git show ${tag}^0 --format=%aD | head -1) -email=$(git show ${tag}^0 --format=%aE | head -1) -name=$(git show ${tag}^0 --format=%aN | head -1) -GIT_COMMITTER_DATE="$date" GIT_COMMITTER_NAME="$name" GIT_COMMITTER_EMAIL="$email" git tag -s -f ${tag} ${tag}^0 -m ${tag} -``` - -I apologize for the inconvenience. - -Frank - diff --git a/vendor/github.com/magiconair/properties/decode.go b/vendor/github.com/magiconair/properties/decode.go deleted file mode 100644 index 3ebf8049c7..0000000000 --- a/vendor/github.com/magiconair/properties/decode.go +++ /dev/null @@ -1,289 +0,0 @@ -// Copyright 2018 Frank Schroeder. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package properties - -import ( - "fmt" - "reflect" - "strconv" - "strings" - "time" -) - -// Decode assigns property values to exported fields of a struct. -// -// Decode traverses v recursively and returns an error if a value cannot be -// converted to the field type or a required value is missing for a field. -// -// The following type dependent decodings are used: -// -// String, boolean, numeric fields have the value of the property key assigned. -// The property key name is the name of the field. A different key and a default -// value can be set in the field's tag. Fields without default value are -// required. If the value cannot be converted to the field type an error is -// returned. -// -// time.Duration fields have the result of time.ParseDuration() assigned. -// -// time.Time fields have the vaule of time.Parse() assigned. The default layout -// is time.RFC3339 but can be set in the field's tag. -// -// Arrays and slices of string, boolean, numeric, time.Duration and time.Time -// fields have the value interpreted as a comma separated list of values. The -// individual values are trimmed of whitespace and empty values are ignored. A -// default value can be provided as a semicolon separated list in the field's -// tag. -// -// Struct fields are decoded recursively using the field name plus "." as -// prefix. The prefix (without dot) can be overridden in the field's tag. -// Default values are not supported in the field's tag. Specify them on the -// fields of the inner struct instead. -// -// Map fields must have a key of type string and are decoded recursively by -// using the field's name plus ".' as prefix and the next element of the key -// name as map key. The prefix (without dot) can be overridden in the field's -// tag. Default values are not supported. -// -// Examples: -// -// // Field is ignored. -// Field int `properties:"-"` -// -// // Field is assigned value of 'Field'. -// Field int -// -// // Field is assigned value of 'myName'. -// Field int `properties:"myName"` -// -// // Field is assigned value of key 'myName' and has a default -// // value 15 if the key does not exist. -// Field int `properties:"myName,default=15"` -// -// // Field is assigned value of key 'Field' and has a default -// // value 15 if the key does not exist. -// Field int `properties:",default=15"` -// -// // Field is assigned value of key 'date' and the date -// // is in format 2006-01-02 -// Field time.Time `properties:"date,layout=2006-01-02"` -// -// // Field is assigned the non-empty and whitespace trimmed -// // values of key 'Field' split by commas. -// Field []string -// -// // Field is assigned the non-empty and whitespace trimmed -// // values of key 'Field' split by commas and has a default -// // value ["a", "b", "c"] if the key does not exist. -// Field []string `properties:",default=a;b;c"` -// -// // Field is decoded recursively with "Field." as key prefix. -// Field SomeStruct -// -// // Field is decoded recursively with "myName." as key prefix. -// Field SomeStruct `properties:"myName"` -// -// // Field is decoded recursively with "Field." as key prefix -// // and the next dotted element of the key as map key. -// Field map[string]string -// -// // Field is decoded recursively with "myName." as key prefix -// // and the next dotted element of the key as map key. -// Field map[string]string `properties:"myName"` -func (p *Properties) Decode(x interface{}) error { - t, v := reflect.TypeOf(x), reflect.ValueOf(x) - if t.Kind() != reflect.Ptr || v.Elem().Type().Kind() != reflect.Struct { - return fmt.Errorf("not a pointer to struct: %s", t) - } - if err := dec(p, "", nil, nil, v); err != nil { - return err - } - return nil -} - -func dec(p *Properties, key string, def *string, opts map[string]string, v reflect.Value) error { - t := v.Type() - - // value returns the property value for key or the default if provided. - value := func() (string, error) { - if val, ok := p.Get(key); ok { - return val, nil - } - if def != nil { - return *def, nil - } - return "", fmt.Errorf("missing required key %s", key) - } - - // conv converts a string to a value of the given type. - conv := func(s string, t reflect.Type) (val reflect.Value, err error) { - var v interface{} - - switch { - case isDuration(t): - v, err = time.ParseDuration(s) - - case isTime(t): - layout := opts["layout"] - if layout == "" { - layout = time.RFC3339 - } - v, err = time.Parse(layout, s) - - case isBool(t): - v, err = boolVal(s), nil - - case isString(t): - v, err = s, nil - - case isFloat(t): - v, err = strconv.ParseFloat(s, 64) - - case isInt(t): - v, err = strconv.ParseInt(s, 10, 64) - - case isUint(t): - v, err = strconv.ParseUint(s, 10, 64) - - default: - return reflect.Zero(t), fmt.Errorf("unsupported type %s", t) - } - if err != nil { - return reflect.Zero(t), err - } - return reflect.ValueOf(v).Convert(t), nil - } - - // keydef returns the property key and the default value based on the - // name of the struct field and the options in the tag. - keydef := func(f reflect.StructField) (string, *string, map[string]string) { - _key, _opts := parseTag(f.Tag.Get("properties")) - - var _def *string - if d, ok := _opts["default"]; ok { - _def = &d - } - if _key != "" { - return _key, _def, _opts - } - return f.Name, _def, _opts - } - - switch { - case isDuration(t) || isTime(t) || isBool(t) || isString(t) || isFloat(t) || isInt(t) || isUint(t): - s, err := value() - if err != nil { - return err - } - val, err := conv(s, t) - if err != nil { - return err - } - v.Set(val) - - case isPtr(t): - return dec(p, key, def, opts, v.Elem()) - - case isStruct(t): - for i := 0; i < v.NumField(); i++ { - fv := v.Field(i) - fk, def, opts := keydef(t.Field(i)) - if !fv.CanSet() { - return fmt.Errorf("cannot set %s", t.Field(i).Name) - } - if fk == "-" { - continue - } - if key != "" { - fk = key + "." + fk - } - if err := dec(p, fk, def, opts, fv); err != nil { - return err - } - } - return nil - - case isArray(t): - val, err := value() - if err != nil { - return err - } - vals := split(val, ";") - a := reflect.MakeSlice(t, 0, len(vals)) - for _, s := range vals { - val, err := conv(s, t.Elem()) - if err != nil { - return err - } - a = reflect.Append(a, val) - } - v.Set(a) - - case isMap(t): - valT := t.Elem() - m := reflect.MakeMap(t) - for postfix := range p.FilterStripPrefix(key + ".").m { - pp := strings.SplitN(postfix, ".", 2) - mk, mv := pp[0], reflect.New(valT) - if err := dec(p, key+"."+mk, nil, nil, mv); err != nil { - return err - } - m.SetMapIndex(reflect.ValueOf(mk), mv.Elem()) - } - v.Set(m) - - default: - return fmt.Errorf("unsupported type %s", t) - } - return nil -} - -// split splits a string on sep, trims whitespace of elements -// and omits empty elements -func split(s string, sep string) []string { - var a []string - for _, v := range strings.Split(s, sep) { - if v = strings.TrimSpace(v); v != "" { - a = append(a, v) - } - } - return a -} - -// parseTag parses a "key,k=v,k=v,..." -func parseTag(tag string) (key string, opts map[string]string) { - opts = map[string]string{} - for i, s := range strings.Split(tag, ",") { - if i == 0 { - key = s - continue - } - - pp := strings.SplitN(s, "=", 2) - if len(pp) == 1 { - opts[pp[0]] = "" - } else { - opts[pp[0]] = pp[1] - } - } - return key, opts -} - -func isArray(t reflect.Type) bool { return t.Kind() == reflect.Array || t.Kind() == reflect.Slice } -func isBool(t reflect.Type) bool { return t.Kind() == reflect.Bool } -func isDuration(t reflect.Type) bool { return t == reflect.TypeOf(time.Second) } -func isMap(t reflect.Type) bool { return t.Kind() == reflect.Map } -func isPtr(t reflect.Type) bool { return t.Kind() == reflect.Ptr } -func isString(t reflect.Type) bool { return t.Kind() == reflect.String } -func isStruct(t reflect.Type) bool { return t.Kind() == reflect.Struct } -func isTime(t reflect.Type) bool { return t == reflect.TypeOf(time.Time{}) } -func isFloat(t reflect.Type) bool { - return t.Kind() == reflect.Float32 || t.Kind() == reflect.Float64 -} -func isInt(t reflect.Type) bool { - return t.Kind() == reflect.Int || t.Kind() == reflect.Int8 || t.Kind() == reflect.Int16 || t.Kind() == reflect.Int32 || t.Kind() == reflect.Int64 -} -func isUint(t reflect.Type) bool { - return t.Kind() == reflect.Uint || t.Kind() == reflect.Uint8 || t.Kind() == reflect.Uint16 || t.Kind() == reflect.Uint32 || t.Kind() == reflect.Uint64 -} diff --git a/vendor/github.com/magiconair/properties/doc.go b/vendor/github.com/magiconair/properties/doc.go deleted file mode 100644 index f8822da2ba..0000000000 --- a/vendor/github.com/magiconair/properties/doc.go +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright 2018 Frank Schroeder. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package properties provides functions for reading and writing -// ISO-8859-1 and UTF-8 encoded .properties files and has -// support for recursive property expansion. -// -// Java properties files are ISO-8859-1 encoded and use Unicode -// literals for characters outside the ISO character set. Unicode -// literals can be used in UTF-8 encoded properties files but -// aren't necessary. -// -// To load a single properties file use MustLoadFile(): -// -// p := properties.MustLoadFile(filename, properties.UTF8) -// -// To load multiple properties files use MustLoadFiles() -// which loads the files in the given order and merges the -// result. Missing properties files can be ignored if the -// 'ignoreMissing' flag is set to true. -// -// Filenames can contain environment variables which are expanded -// before loading. -// -// f1 := "/etc/myapp/myapp.conf" -// f2 := "/home/${USER}/myapp.conf" -// p := MustLoadFiles([]string{f1, f2}, properties.UTF8, true) -// -// All of the different key/value delimiters ' ', ':' and '=' are -// supported as well as the comment characters '!' and '#' and -// multi-line values. -// -// ! this is a comment -// # and so is this -// -// # the following expressions are equal -// key value -// key=value -// key:value -// key = value -// key : value -// key = val\ -// ue -// -// Properties stores all comments preceding a key and provides -// GetComments() and SetComments() methods to retrieve and -// update them. The convenience functions GetComment() and -// SetComment() allow access to the last comment. The -// WriteComment() method writes properties files including -// the comments and with the keys in the original order. -// This can be used for sanitizing properties files. -// -// Property expansion is recursive and circular references -// and malformed expressions are not allowed and cause an -// error. Expansion of environment variables is supported. -// -// # standard property -// key = value -// -// # property expansion: key2 = value -// key2 = ${key} -// -// # recursive expansion: key3 = value -// key3 = ${key2} -// -// # circular reference (error) -// key = ${key} -// -// # malformed expression (error) -// key = ${ke -// -// # refers to the users' home dir -// home = ${HOME} -// -// # local key takes precedence over env var: u = foo -// USER = foo -// u = ${USER} -// -// The default property expansion format is ${key} but can be -// changed by setting different pre- and postfix values on the -// Properties object. -// -// p := properties.NewProperties() -// p.Prefix = "#[" -// p.Postfix = "]#" -// -// Properties provides convenience functions for getting typed -// values with default values if the key does not exist or the -// type conversion failed. -// -// # Returns true if the value is either "1", "on", "yes" or "true" -// # Returns false for every other value and the default value if -// # the key does not exist. -// v = p.GetBool("key", false) -// -// # Returns the value if the key exists and the format conversion -// # was successful. Otherwise, the default value is returned. -// v = p.GetInt64("key", 999) -// v = p.GetUint64("key", 999) -// v = p.GetFloat64("key", 123.0) -// v = p.GetString("key", "def") -// v = p.GetDuration("key", 999) -// -// As an alternative properties may be applied with the standard -// library's flag implementation at any time. -// -// # Standard configuration -// v = flag.Int("key", 999, "help message") -// flag.Parse() -// -// # Merge p into the flag set -// p.MustFlag(flag.CommandLine) -// -// Properties provides several MustXXX() convenience functions -// which will terminate the app if an error occurs. The behavior -// of the failure is configurable and the default is to call -// log.Fatal(err). To have the MustXXX() functions panic instead -// of logging the error set a different ErrorHandler before -// you use the Properties package. -// -// properties.ErrorHandler = properties.PanicHandler -// -// # Will panic instead of logging an error -// p := properties.MustLoadFile("config.properties") -// -// You can also provide your own ErrorHandler function. The only requirement -// is that the error handler function must exit after handling the error. -// -// properties.ErrorHandler = func(err error) { -// fmt.Println(err) -// os.Exit(1) -// } -// -// # Will write to stdout and then exit -// p := properties.MustLoadFile("config.properties") -// -// Properties can also be loaded into a struct via the `Decode` -// method, e.g. -// -// type S struct { -// A string `properties:"a,default=foo"` -// D time.Duration `properties:"timeout,default=5s"` -// E time.Time `properties:"expires,layout=2006-01-02,default=2015-01-01"` -// } -// -// See `Decode()` method for the full documentation. -// -// The following documents provide a description of the properties -// file format. -// -// http://en.wikipedia.org/wiki/.properties -// -// http://docs.oracle.com/javase/7/docs/api/java/util/Properties.html#load%28java.io.Reader%29 -// -package properties diff --git a/vendor/github.com/magiconair/properties/integrate.go b/vendor/github.com/magiconair/properties/integrate.go deleted file mode 100644 index 74d38dc677..0000000000 --- a/vendor/github.com/magiconair/properties/integrate.go +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2018 Frank Schroeder. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package properties - -import "flag" - -// MustFlag sets flags that are skipped by dst.Parse when p contains -// the respective key for flag.Flag.Name. -// -// It's use is recommended with command line arguments as in: -// flag.Parse() -// p.MustFlag(flag.CommandLine) -func (p *Properties) MustFlag(dst *flag.FlagSet) { - m := make(map[string]*flag.Flag) - dst.VisitAll(func(f *flag.Flag) { - m[f.Name] = f - }) - dst.Visit(func(f *flag.Flag) { - delete(m, f.Name) // overridden - }) - - for name, f := range m { - v, ok := p.Get(name) - if !ok { - continue - } - - if err := f.Value.Set(v); err != nil { - ErrorHandler(err) - } - } -} diff --git a/vendor/github.com/magiconair/properties/lex.go b/vendor/github.com/magiconair/properties/lex.go deleted file mode 100644 index e1e9dd7b12..0000000000 --- a/vendor/github.com/magiconair/properties/lex.go +++ /dev/null @@ -1,395 +0,0 @@ -// Copyright 2018 Frank Schroeder. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. -// -// Parts of the lexer are from the template/text/parser package -// For these parts the following applies: -// -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file of the go 1.2 -// distribution. - -package properties - -import ( - "fmt" - "strconv" - "strings" - "unicode/utf8" -) - -// item represents a token or text string returned from the scanner. -type item struct { - typ itemType // The type of this item. - pos int // The starting position, in bytes, of this item in the input string. - val string // The value of this item. -} - -func (i item) String() string { - switch { - case i.typ == itemEOF: - return "EOF" - case i.typ == itemError: - return i.val - case len(i.val) > 10: - return fmt.Sprintf("%.10q...", i.val) - } - return fmt.Sprintf("%q", i.val) -} - -// itemType identifies the type of lex items. -type itemType int - -const ( - itemError itemType = iota // error occurred; value is text of error - itemEOF - itemKey // a key - itemValue // a value - itemComment // a comment -) - -// defines a constant for EOF -const eof = -1 - -// permitted whitespace characters space, FF and TAB -const whitespace = " \f\t" - -// stateFn represents the state of the scanner as a function that returns the next state. -type stateFn func(*lexer) stateFn - -// lexer holds the state of the scanner. -type lexer struct { - input string // the string being scanned - state stateFn // the next lexing function to enter - pos int // current position in the input - start int // start position of this item - width int // width of last rune read from input - lastPos int // position of most recent item returned by nextItem - runes []rune // scanned runes for this item - items chan item // channel of scanned items -} - -// next returns the next rune in the input. -func (l *lexer) next() rune { - if l.pos >= len(l.input) { - l.width = 0 - return eof - } - r, w := utf8.DecodeRuneInString(l.input[l.pos:]) - l.width = w - l.pos += l.width - return r -} - -// peek returns but does not consume the next rune in the input. -func (l *lexer) peek() rune { - r := l.next() - l.backup() - return r -} - -// backup steps back one rune. Can only be called once per call of next. -func (l *lexer) backup() { - l.pos -= l.width -} - -// emit passes an item back to the client. -func (l *lexer) emit(t itemType) { - i := item{t, l.start, string(l.runes)} - l.items <- i - l.start = l.pos - l.runes = l.runes[:0] -} - -// ignore skips over the pending input before this point. -func (l *lexer) ignore() { - l.start = l.pos -} - -// appends the rune to the current value -func (l *lexer) appendRune(r rune) { - l.runes = append(l.runes, r) -} - -// accept consumes the next rune if it's from the valid set. -func (l *lexer) accept(valid string) bool { - if strings.ContainsRune(valid, l.next()) { - return true - } - l.backup() - return false -} - -// acceptRun consumes a run of runes from the valid set. -func (l *lexer) acceptRun(valid string) { - for strings.ContainsRune(valid, l.next()) { - } - l.backup() -} - -// lineNumber reports which line we're on, based on the position of -// the previous item returned by nextItem. Doing it this way -// means we don't have to worry about peek double counting. -func (l *lexer) lineNumber() int { - return 1 + strings.Count(l.input[:l.lastPos], "\n") -} - -// errorf returns an error token and terminates the scan by passing -// back a nil pointer that will be the next state, terminating l.nextItem. -func (l *lexer) errorf(format string, args ...interface{}) stateFn { - l.items <- item{itemError, l.start, fmt.Sprintf(format, args...)} - return nil -} - -// nextItem returns the next item from the input. -func (l *lexer) nextItem() item { - i := <-l.items - l.lastPos = i.pos - return i -} - -// lex creates a new scanner for the input string. -func lex(input string) *lexer { - l := &lexer{ - input: input, - items: make(chan item), - runes: make([]rune, 0, 32), - } - go l.run() - return l -} - -// run runs the state machine for the lexer. -func (l *lexer) run() { - for l.state = lexBeforeKey(l); l.state != nil; { - l.state = l.state(l) - } -} - -// state functions - -// lexBeforeKey scans until a key begins. -func lexBeforeKey(l *lexer) stateFn { - switch r := l.next(); { - case isEOF(r): - l.emit(itemEOF) - return nil - - case isEOL(r): - l.ignore() - return lexBeforeKey - - case isComment(r): - return lexComment - - case isWhitespace(r): - l.ignore() - return lexBeforeKey - - default: - l.backup() - return lexKey - } -} - -// lexComment scans a comment line. The comment character has already been scanned. -func lexComment(l *lexer) stateFn { - l.acceptRun(whitespace) - l.ignore() - for { - switch r := l.next(); { - case isEOF(r): - l.ignore() - l.emit(itemEOF) - return nil - case isEOL(r): - l.emit(itemComment) - return lexBeforeKey - default: - l.appendRune(r) - } - } -} - -// lexKey scans the key up to a delimiter -func lexKey(l *lexer) stateFn { - var r rune - -Loop: - for { - switch r = l.next(); { - - case isEscape(r): - err := l.scanEscapeSequence() - if err != nil { - return l.errorf(err.Error()) - } - - case isEndOfKey(r): - l.backup() - break Loop - - case isEOF(r): - break Loop - - default: - l.appendRune(r) - } - } - - if len(l.runes) > 0 { - l.emit(itemKey) - } - - if isEOF(r) { - l.emit(itemEOF) - return nil - } - - return lexBeforeValue -} - -// lexBeforeValue scans the delimiter between key and value. -// Leading and trailing whitespace is ignored. -// We expect to be just after the key. -func lexBeforeValue(l *lexer) stateFn { - l.acceptRun(whitespace) - l.accept(":=") - l.acceptRun(whitespace) - l.ignore() - return lexValue -} - -// lexValue scans text until the end of the line. We expect to be just after the delimiter. -func lexValue(l *lexer) stateFn { - for { - switch r := l.next(); { - case isEscape(r): - if isEOL(l.peek()) { - l.next() - l.acceptRun(whitespace) - } else { - err := l.scanEscapeSequence() - if err != nil { - return l.errorf(err.Error()) - } - } - - case isEOL(r): - l.emit(itemValue) - l.ignore() - return lexBeforeKey - - case isEOF(r): - l.emit(itemValue) - l.emit(itemEOF) - return nil - - default: - l.appendRune(r) - } - } -} - -// scanEscapeSequence scans either one of the escaped characters -// or a unicode literal. We expect to be after the escape character. -func (l *lexer) scanEscapeSequence() error { - switch r := l.next(); { - - case isEscapedCharacter(r): - l.appendRune(decodeEscapedCharacter(r)) - return nil - - case atUnicodeLiteral(r): - return l.scanUnicodeLiteral() - - case isEOF(r): - return fmt.Errorf("premature EOF") - - // silently drop the escape character and append the rune as is - default: - l.appendRune(r) - return nil - } -} - -// scans a unicode literal in the form \uXXXX. We expect to be after the \u. -func (l *lexer) scanUnicodeLiteral() error { - // scan the digits - d := make([]rune, 4) - for i := 0; i < 4; i++ { - d[i] = l.next() - if d[i] == eof || !strings.ContainsRune("0123456789abcdefABCDEF", d[i]) { - return fmt.Errorf("invalid unicode literal") - } - } - - // decode the digits into a rune - r, err := strconv.ParseInt(string(d), 16, 0) - if err != nil { - return err - } - - l.appendRune(rune(r)) - return nil -} - -// decodeEscapedCharacter returns the unescaped rune. We expect to be after the escape character. -func decodeEscapedCharacter(r rune) rune { - switch r { - case 'f': - return '\f' - case 'n': - return '\n' - case 'r': - return '\r' - case 't': - return '\t' - default: - return r - } -} - -// atUnicodeLiteral reports whether we are at a unicode literal. -// The escape character has already been consumed. -func atUnicodeLiteral(r rune) bool { - return r == 'u' -} - -// isComment reports whether we are at the start of a comment. -func isComment(r rune) bool { - return r == '#' || r == '!' -} - -// isEndOfKey reports whether the rune terminates the current key. -func isEndOfKey(r rune) bool { - return strings.ContainsRune(" \f\t\r\n:=", r) -} - -// isEOF reports whether we are at EOF. -func isEOF(r rune) bool { - return r == eof -} - -// isEOL reports whether we are at a new line character. -func isEOL(r rune) bool { - return r == '\n' || r == '\r' -} - -// isEscape reports whether the rune is the escape character which -// prefixes unicode literals and other escaped characters. -func isEscape(r rune) bool { - return r == '\\' -} - -// isEscapedCharacter reports whether we are at one of the characters that need escaping. -// The escape character has already been consumed. -func isEscapedCharacter(r rune) bool { - return strings.ContainsRune(" :=fnrt", r) -} - -// isWhitespace reports whether the rune is a whitespace character. -func isWhitespace(r rune) bool { - return strings.ContainsRune(whitespace, r) -} diff --git a/vendor/github.com/magiconair/properties/load.go b/vendor/github.com/magiconair/properties/load.go deleted file mode 100644 index c83c2dadd6..0000000000 --- a/vendor/github.com/magiconair/properties/load.go +++ /dev/null @@ -1,293 +0,0 @@ -// Copyright 2018 Frank Schroeder. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package properties - -import ( - "fmt" - "io/ioutil" - "net/http" - "os" - "strings" -) - -// Encoding specifies encoding of the input data. -type Encoding uint - -const ( - // utf8Default is a private placeholder for the zero value of Encoding to - // ensure that it has the correct meaning. UTF8 is the default encoding but - // was assigned a non-zero value which cannot be changed without breaking - // existing code. Clients should continue to use the public constants. - utf8Default Encoding = iota - - // UTF8 interprets the input data as UTF-8. - UTF8 - - // ISO_8859_1 interprets the input data as ISO-8859-1. - ISO_8859_1 -) - -type Loader struct { - // Encoding determines how the data from files and byte buffers - // is interpreted. For URLs the Content-Type header is used - // to determine the encoding of the data. - Encoding Encoding - - // DisableExpansion configures the property expansion of the - // returned property object. When set to true, the property values - // will not be expanded and the Property object will not be checked - // for invalid expansion expressions. - DisableExpansion bool - - // IgnoreMissing configures whether missing files or URLs which return - // 404 are reported as errors. When set to true, missing files and 404 - // status codes are not reported as errors. - IgnoreMissing bool -} - -// Load reads a buffer into a Properties struct. -func (l *Loader) LoadBytes(buf []byte) (*Properties, error) { - return l.loadBytes(buf, l.Encoding) -} - -// LoadAll reads the content of multiple URLs or files in the given order into -// a Properties struct. If IgnoreMissing is true then a 404 status code or -// missing file will not be reported as error. Encoding sets the encoding for -// files. For the URLs see LoadURL for the Content-Type header and the -// encoding. -func (l *Loader) LoadAll(names []string) (*Properties, error) { - all := NewProperties() - for _, name := range names { - n, err := expandName(name) - if err != nil { - return nil, err - } - - var p *Properties - switch { - case strings.HasPrefix(n, "http://"): - p, err = l.LoadURL(n) - case strings.HasPrefix(n, "https://"): - p, err = l.LoadURL(n) - default: - p, err = l.LoadFile(n) - } - if err != nil { - return nil, err - } - all.Merge(p) - } - - all.DisableExpansion = l.DisableExpansion - if all.DisableExpansion { - return all, nil - } - return all, all.check() -} - -// LoadFile reads a file into a Properties struct. -// If IgnoreMissing is true then a missing file will not be -// reported as error. -func (l *Loader) LoadFile(filename string) (*Properties, error) { - data, err := ioutil.ReadFile(filename) - if err != nil { - if l.IgnoreMissing && os.IsNotExist(err) { - LogPrintf("properties: %s not found. skipping", filename) - return NewProperties(), nil - } - return nil, err - } - return l.loadBytes(data, l.Encoding) -} - -// LoadURL reads the content of the URL into a Properties struct. -// -// The encoding is determined via the Content-Type header which -// should be set to 'text/plain'. If the 'charset' parameter is -// missing, 'iso-8859-1' or 'latin1' the encoding is set to -// ISO-8859-1. If the 'charset' parameter is set to 'utf-8' the -// encoding is set to UTF-8. A missing content type header is -// interpreted as 'text/plain; charset=utf-8'. -func (l *Loader) LoadURL(url string) (*Properties, error) { - resp, err := http.Get(url) - if err != nil { - return nil, fmt.Errorf("properties: error fetching %q. %s", url, err) - } - defer resp.Body.Close() - - if resp.StatusCode == 404 && l.IgnoreMissing { - LogPrintf("properties: %s returned %d. skipping", url, resp.StatusCode) - return NewProperties(), nil - } - - if resp.StatusCode != 200 { - return nil, fmt.Errorf("properties: %s returned %d", url, resp.StatusCode) - } - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, fmt.Errorf("properties: %s error reading response. %s", url, err) - } - - ct := resp.Header.Get("Content-Type") - ct = strings.Join(strings.Fields(ct), "") - var enc Encoding - switch strings.ToLower(ct) { - case "text/plain", "text/plain;charset=iso-8859-1", "text/plain;charset=latin1": - enc = ISO_8859_1 - case "", "text/plain;charset=utf-8": - enc = UTF8 - default: - return nil, fmt.Errorf("properties: invalid content type %s", ct) - } - - return l.loadBytes(body, enc) -} - -func (l *Loader) loadBytes(buf []byte, enc Encoding) (*Properties, error) { - p, err := parse(convert(buf, enc)) - if err != nil { - return nil, err - } - p.DisableExpansion = l.DisableExpansion - if p.DisableExpansion { - return p, nil - } - return p, p.check() -} - -// Load reads a buffer into a Properties struct. -func Load(buf []byte, enc Encoding) (*Properties, error) { - l := &Loader{Encoding: enc} - return l.LoadBytes(buf) -} - -// LoadString reads an UTF8 string into a properties struct. -func LoadString(s string) (*Properties, error) { - l := &Loader{Encoding: UTF8} - return l.LoadBytes([]byte(s)) -} - -// LoadMap creates a new Properties struct from a string map. -func LoadMap(m map[string]string) *Properties { - p := NewProperties() - for k, v := range m { - p.Set(k, v) - } - return p -} - -// LoadFile reads a file into a Properties struct. -func LoadFile(filename string, enc Encoding) (*Properties, error) { - l := &Loader{Encoding: enc} - return l.LoadAll([]string{filename}) -} - -// LoadFiles reads multiple files in the given order into -// a Properties struct. If 'ignoreMissing' is true then -// non-existent files will not be reported as error. -func LoadFiles(filenames []string, enc Encoding, ignoreMissing bool) (*Properties, error) { - l := &Loader{Encoding: enc, IgnoreMissing: ignoreMissing} - return l.LoadAll(filenames) -} - -// LoadURL reads the content of the URL into a Properties struct. -// See Loader#LoadURL for details. -func LoadURL(url string) (*Properties, error) { - l := &Loader{Encoding: UTF8} - return l.LoadAll([]string{url}) -} - -// LoadURLs reads the content of multiple URLs in the given order into a -// Properties struct. If IgnoreMissing is true then a 404 status code will -// not be reported as error. See Loader#LoadURL for the Content-Type header -// and the encoding. -func LoadURLs(urls []string, ignoreMissing bool) (*Properties, error) { - l := &Loader{Encoding: UTF8, IgnoreMissing: ignoreMissing} - return l.LoadAll(urls) -} - -// LoadAll reads the content of multiple URLs or files in the given order into a -// Properties struct. If 'ignoreMissing' is true then a 404 status code or missing file will -// not be reported as error. Encoding sets the encoding for files. For the URLs please see -// LoadURL for the Content-Type header and the encoding. -func LoadAll(names []string, enc Encoding, ignoreMissing bool) (*Properties, error) { - l := &Loader{Encoding: enc, IgnoreMissing: ignoreMissing} - return l.LoadAll(names) -} - -// MustLoadString reads an UTF8 string into a Properties struct and -// panics on error. -func MustLoadString(s string) *Properties { - return must(LoadString(s)) -} - -// MustLoadFile reads a file into a Properties struct and -// panics on error. -func MustLoadFile(filename string, enc Encoding) *Properties { - return must(LoadFile(filename, enc)) -} - -// MustLoadFiles reads multiple files in the given order into -// a Properties struct and panics on error. If 'ignoreMissing' -// is true then non-existent files will not be reported as error. -func MustLoadFiles(filenames []string, enc Encoding, ignoreMissing bool) *Properties { - return must(LoadFiles(filenames, enc, ignoreMissing)) -} - -// MustLoadURL reads the content of a URL into a Properties struct and -// panics on error. -func MustLoadURL(url string) *Properties { - return must(LoadURL(url)) -} - -// MustLoadURLs reads the content of multiple URLs in the given order into a -// Properties struct and panics on error. If 'ignoreMissing' is true then a 404 -// status code will not be reported as error. -func MustLoadURLs(urls []string, ignoreMissing bool) *Properties { - return must(LoadURLs(urls, ignoreMissing)) -} - -// MustLoadAll reads the content of multiple URLs or files in the given order into a -// Properties struct. If 'ignoreMissing' is true then a 404 status code or missing file will -// not be reported as error. Encoding sets the encoding for files. For the URLs please see -// LoadURL for the Content-Type header and the encoding. It panics on error. -func MustLoadAll(names []string, enc Encoding, ignoreMissing bool) *Properties { - return must(LoadAll(names, enc, ignoreMissing)) -} - -func must(p *Properties, err error) *Properties { - if err != nil { - ErrorHandler(err) - } - return p -} - -// expandName expands ${ENV_VAR} expressions in a name. -// If the environment variable does not exist then it will be replaced -// with an empty string. Malformed expressions like "${ENV_VAR" will -// be reported as error. -func expandName(name string) (string, error) { - return expand(name, []string{}, "${", "}", make(map[string]string)) -} - -// Interprets a byte buffer either as an ISO-8859-1 or UTF-8 encoded string. -// For ISO-8859-1 we can convert each byte straight into a rune since the -// first 256 unicode code points cover ISO-8859-1. -func convert(buf []byte, enc Encoding) string { - switch enc { - case utf8Default, UTF8: - return string(buf) - case ISO_8859_1: - runes := make([]rune, len(buf)) - for i, b := range buf { - runes[i] = rune(b) - } - return string(runes) - default: - ErrorHandler(fmt.Errorf("unsupported encoding %v", enc)) - } - panic("ErrorHandler should exit") -} diff --git a/vendor/github.com/magiconair/properties/parser.go b/vendor/github.com/magiconair/properties/parser.go deleted file mode 100644 index 430e4fcd2c..0000000000 --- a/vendor/github.com/magiconair/properties/parser.go +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2018 Frank Schroeder. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package properties - -import ( - "fmt" - "runtime" -) - -type parser struct { - lex *lexer -} - -func parse(input string) (properties *Properties, err error) { - p := &parser{lex: lex(input)} - defer p.recover(&err) - - properties = NewProperties() - key := "" - comments := []string{} - - for { - token := p.expectOneOf(itemComment, itemKey, itemEOF) - switch token.typ { - case itemEOF: - goto done - case itemComment: - comments = append(comments, token.val) - continue - case itemKey: - key = token.val - if _, ok := properties.m[key]; !ok { - properties.k = append(properties.k, key) - } - } - - token = p.expectOneOf(itemValue, itemEOF) - if len(comments) > 0 { - properties.c[key] = comments - comments = []string{} - } - switch token.typ { - case itemEOF: - properties.m[key] = "" - goto done - case itemValue: - properties.m[key] = token.val - } - } - -done: - return properties, nil -} - -func (p *parser) errorf(format string, args ...interface{}) { - format = fmt.Sprintf("properties: Line %d: %s", p.lex.lineNumber(), format) - panic(fmt.Errorf(format, args...)) -} - -func (p *parser) expectOneOf(expected ...itemType) (token item) { - token = p.lex.nextItem() - for _, v := range expected { - if token.typ == v { - return token - } - } - p.unexpected(token) - panic("unexpected token") -} - -func (p *parser) unexpected(token item) { - p.errorf(token.String()) -} - -// recover is the handler that turns panics into returns from the top level of Parse. -func (p *parser) recover(errp *error) { - e := recover() - if e != nil { - if _, ok := e.(runtime.Error); ok { - panic(e) - } - *errp = e.(error) - } -} diff --git a/vendor/github.com/magiconair/properties/properties.go b/vendor/github.com/magiconair/properties/properties.go deleted file mode 100644 index 62ae2d67ab..0000000000 --- a/vendor/github.com/magiconair/properties/properties.go +++ /dev/null @@ -1,853 +0,0 @@ -// Copyright 2018 Frank Schroeder. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package properties - -// BUG(frank): Set() does not check for invalid unicode literals since this is currently handled by the lexer. -// BUG(frank): Write() does not allow to configure the newline character. Therefore, on Windows LF is used. - -import ( - "bytes" - "fmt" - "io" - "log" - "os" - "regexp" - "sort" - "strconv" - "strings" - "time" - "unicode/utf8" -) - -const maxExpansionDepth = 64 - -// ErrorHandlerFunc defines the type of function which handles failures -// of the MustXXX() functions. An error handler function must exit -// the application after handling the error. -type ErrorHandlerFunc func(error) - -// ErrorHandler is the function which handles failures of the MustXXX() -// functions. The default is LogFatalHandler. -var ErrorHandler ErrorHandlerFunc = LogFatalHandler - -// LogHandlerFunc defines the function prototype for logging errors. -type LogHandlerFunc func(fmt string, args ...interface{}) - -// LogPrintf defines a log handler which uses log.Printf. -var LogPrintf LogHandlerFunc = log.Printf - -// LogFatalHandler handles the error by logging a fatal error and exiting. -func LogFatalHandler(err error) { - log.Fatal(err) -} - -// PanicHandler handles the error by panicking. -func PanicHandler(err error) { - panic(err) -} - -// ----------------------------------------------------------------------------- - -// A Properties contains the key/value pairs from the properties input. -// All values are stored in unexpanded form and are expanded at runtime -type Properties struct { - // Pre-/Postfix for property expansion. - Prefix string - Postfix string - - // DisableExpansion controls the expansion of properties on Get() - // and the check for circular references on Set(). When set to - // true Properties behaves like a simple key/value store and does - // not check for circular references on Get() or on Set(). - DisableExpansion bool - - // Stores the key/value pairs - m map[string]string - - // Stores the comments per key. - c map[string][]string - - // Stores the keys in order of appearance. - k []string - - // WriteSeparator specifies the separator of key and value while writing the properties. - WriteSeparator string -} - -// NewProperties creates a new Properties struct with the default -// configuration for "${key}" expressions. -func NewProperties() *Properties { - return &Properties{ - Prefix: "${", - Postfix: "}", - m: map[string]string{}, - c: map[string][]string{}, - k: []string{}, - } -} - -// Load reads a buffer into the given Properties struct. -func (p *Properties) Load(buf []byte, enc Encoding) error { - l := &Loader{Encoding: enc, DisableExpansion: p.DisableExpansion} - newProperties, err := l.LoadBytes(buf) - if err != nil { - return err - } - p.Merge(newProperties) - return nil -} - -// Get returns the expanded value for the given key if exists. -// Otherwise, ok is false. -func (p *Properties) Get(key string) (value string, ok bool) { - v, ok := p.m[key] - if p.DisableExpansion { - return v, ok - } - if !ok { - return "", false - } - - expanded, err := p.expand(key, v) - - // we guarantee that the expanded value is free of - // circular references and malformed expressions - // so we panic if we still get an error here. - if err != nil { - ErrorHandler(err) - } - - return expanded, true -} - -// MustGet returns the expanded value for the given key if exists. -// Otherwise, it panics. -func (p *Properties) MustGet(key string) string { - if v, ok := p.Get(key); ok { - return v - } - ErrorHandler(invalidKeyError(key)) - panic("ErrorHandler should exit") -} - -// ---------------------------------------------------------------------------- - -// ClearComments removes the comments for all keys. -func (p *Properties) ClearComments() { - p.c = map[string][]string{} -} - -// ---------------------------------------------------------------------------- - -// GetComment returns the last comment before the given key or an empty string. -func (p *Properties) GetComment(key string) string { - comments, ok := p.c[key] - if !ok || len(comments) == 0 { - return "" - } - return comments[len(comments)-1] -} - -// ---------------------------------------------------------------------------- - -// GetComments returns all comments that appeared before the given key or nil. -func (p *Properties) GetComments(key string) []string { - if comments, ok := p.c[key]; ok { - return comments - } - return nil -} - -// ---------------------------------------------------------------------------- - -// SetComment sets the comment for the key. -func (p *Properties) SetComment(key, comment string) { - p.c[key] = []string{comment} -} - -// ---------------------------------------------------------------------------- - -// SetComments sets the comments for the key. If the comments are nil then -// all comments for this key are deleted. -func (p *Properties) SetComments(key string, comments []string) { - if comments == nil { - delete(p.c, key) - return - } - p.c[key] = comments -} - -// ---------------------------------------------------------------------------- - -// GetBool checks if the expanded value is one of '1', 'yes', -// 'true' or 'on' if the key exists. The comparison is case-insensitive. -// If the key does not exist the default value is returned. -func (p *Properties) GetBool(key string, def bool) bool { - v, err := p.getBool(key) - if err != nil { - return def - } - return v -} - -// MustGetBool checks if the expanded value is one of '1', 'yes', -// 'true' or 'on' if the key exists. The comparison is case-insensitive. -// If the key does not exist the function panics. -func (p *Properties) MustGetBool(key string) bool { - v, err := p.getBool(key) - if err != nil { - ErrorHandler(err) - } - return v -} - -func (p *Properties) getBool(key string) (value bool, err error) { - if v, ok := p.Get(key); ok { - return boolVal(v), nil - } - return false, invalidKeyError(key) -} - -func boolVal(v string) bool { - v = strings.ToLower(v) - return v == "1" || v == "true" || v == "yes" || v == "on" -} - -// ---------------------------------------------------------------------------- - -// GetDuration parses the expanded value as an time.Duration (in ns) if the -// key exists. If key does not exist or the value cannot be parsed the default -// value is returned. In almost all cases you want to use GetParsedDuration(). -func (p *Properties) GetDuration(key string, def time.Duration) time.Duration { - v, err := p.getInt64(key) - if err != nil { - return def - } - return time.Duration(v) -} - -// MustGetDuration parses the expanded value as an time.Duration (in ns) if -// the key exists. If key does not exist or the value cannot be parsed the -// function panics. In almost all cases you want to use MustGetParsedDuration(). -func (p *Properties) MustGetDuration(key string) time.Duration { - v, err := p.getInt64(key) - if err != nil { - ErrorHandler(err) - } - return time.Duration(v) -} - -// ---------------------------------------------------------------------------- - -// GetParsedDuration parses the expanded value with time.ParseDuration() if the key exists. -// If key does not exist or the value cannot be parsed the default -// value is returned. -func (p *Properties) GetParsedDuration(key string, def time.Duration) time.Duration { - s, ok := p.Get(key) - if !ok { - return def - } - v, err := time.ParseDuration(s) - if err != nil { - return def - } - return v -} - -// MustGetParsedDuration parses the expanded value with time.ParseDuration() if the key exists. -// If key does not exist or the value cannot be parsed the function panics. -func (p *Properties) MustGetParsedDuration(key string) time.Duration { - s, ok := p.Get(key) - if !ok { - ErrorHandler(invalidKeyError(key)) - } - v, err := time.ParseDuration(s) - if err != nil { - ErrorHandler(err) - } - return v -} - -// ---------------------------------------------------------------------------- - -// GetFloat64 parses the expanded value as a float64 if the key exists. -// If key does not exist or the value cannot be parsed the default -// value is returned. -func (p *Properties) GetFloat64(key string, def float64) float64 { - v, err := p.getFloat64(key) - if err != nil { - return def - } - return v -} - -// MustGetFloat64 parses the expanded value as a float64 if the key exists. -// If key does not exist or the value cannot be parsed the function panics. -func (p *Properties) MustGetFloat64(key string) float64 { - v, err := p.getFloat64(key) - if err != nil { - ErrorHandler(err) - } - return v -} - -func (p *Properties) getFloat64(key string) (value float64, err error) { - if v, ok := p.Get(key); ok { - value, err = strconv.ParseFloat(v, 64) - if err != nil { - return 0, err - } - return value, nil - } - return 0, invalidKeyError(key) -} - -// ---------------------------------------------------------------------------- - -// GetInt parses the expanded value as an int if the key exists. -// If key does not exist or the value cannot be parsed the default -// value is returned. If the value does not fit into an int the -// function panics with an out of range error. -func (p *Properties) GetInt(key string, def int) int { - v, err := p.getInt64(key) - if err != nil { - return def - } - return intRangeCheck(key, v) -} - -// MustGetInt parses the expanded value as an int if the key exists. -// If key does not exist or the value cannot be parsed the function panics. -// If the value does not fit into an int the function panics with -// an out of range error. -func (p *Properties) MustGetInt(key string) int { - v, err := p.getInt64(key) - if err != nil { - ErrorHandler(err) - } - return intRangeCheck(key, v) -} - -// ---------------------------------------------------------------------------- - -// GetInt64 parses the expanded value as an int64 if the key exists. -// If key does not exist or the value cannot be parsed the default -// value is returned. -func (p *Properties) GetInt64(key string, def int64) int64 { - v, err := p.getInt64(key) - if err != nil { - return def - } - return v -} - -// MustGetInt64 parses the expanded value as an int if the key exists. -// If key does not exist or the value cannot be parsed the function panics. -func (p *Properties) MustGetInt64(key string) int64 { - v, err := p.getInt64(key) - if err != nil { - ErrorHandler(err) - } - return v -} - -func (p *Properties) getInt64(key string) (value int64, err error) { - if v, ok := p.Get(key); ok { - value, err = strconv.ParseInt(v, 10, 64) - if err != nil { - return 0, err - } - return value, nil - } - return 0, invalidKeyError(key) -} - -// ---------------------------------------------------------------------------- - -// GetUint parses the expanded value as an uint if the key exists. -// If key does not exist or the value cannot be parsed the default -// value is returned. If the value does not fit into an int the -// function panics with an out of range error. -func (p *Properties) GetUint(key string, def uint) uint { - v, err := p.getUint64(key) - if err != nil { - return def - } - return uintRangeCheck(key, v) -} - -// MustGetUint parses the expanded value as an int if the key exists. -// If key does not exist or the value cannot be parsed the function panics. -// If the value does not fit into an int the function panics with -// an out of range error. -func (p *Properties) MustGetUint(key string) uint { - v, err := p.getUint64(key) - if err != nil { - ErrorHandler(err) - } - return uintRangeCheck(key, v) -} - -// ---------------------------------------------------------------------------- - -// GetUint64 parses the expanded value as an uint64 if the key exists. -// If key does not exist or the value cannot be parsed the default -// value is returned. -func (p *Properties) GetUint64(key string, def uint64) uint64 { - v, err := p.getUint64(key) - if err != nil { - return def - } - return v -} - -// MustGetUint64 parses the expanded value as an int if the key exists. -// If key does not exist or the value cannot be parsed the function panics. -func (p *Properties) MustGetUint64(key string) uint64 { - v, err := p.getUint64(key) - if err != nil { - ErrorHandler(err) - } - return v -} - -func (p *Properties) getUint64(key string) (value uint64, err error) { - if v, ok := p.Get(key); ok { - value, err = strconv.ParseUint(v, 10, 64) - if err != nil { - return 0, err - } - return value, nil - } - return 0, invalidKeyError(key) -} - -// ---------------------------------------------------------------------------- - -// GetString returns the expanded value for the given key if exists or -// the default value otherwise. -func (p *Properties) GetString(key, def string) string { - if v, ok := p.Get(key); ok { - return v - } - return def -} - -// MustGetString returns the expanded value for the given key if exists or -// panics otherwise. -func (p *Properties) MustGetString(key string) string { - if v, ok := p.Get(key); ok { - return v - } - ErrorHandler(invalidKeyError(key)) - panic("ErrorHandler should exit") -} - -// ---------------------------------------------------------------------------- - -// Filter returns a new properties object which contains all properties -// for which the key matches the pattern. -func (p *Properties) Filter(pattern string) (*Properties, error) { - re, err := regexp.Compile(pattern) - if err != nil { - return nil, err - } - - return p.FilterRegexp(re), nil -} - -// FilterRegexp returns a new properties object which contains all properties -// for which the key matches the regular expression. -func (p *Properties) FilterRegexp(re *regexp.Regexp) *Properties { - pp := NewProperties() - for _, k := range p.k { - if re.MatchString(k) { - // TODO(fs): we are ignoring the error which flags a circular reference. - // TODO(fs): since we are just copying a subset of keys this cannot happen (fingers crossed) - pp.Set(k, p.m[k]) - } - } - return pp -} - -// FilterPrefix returns a new properties object with a subset of all keys -// with the given prefix. -func (p *Properties) FilterPrefix(prefix string) *Properties { - pp := NewProperties() - for _, k := range p.k { - if strings.HasPrefix(k, prefix) { - // TODO(fs): we are ignoring the error which flags a circular reference. - // TODO(fs): since we are just copying a subset of keys this cannot happen (fingers crossed) - pp.Set(k, p.m[k]) - } - } - return pp -} - -// FilterStripPrefix returns a new properties object with a subset of all keys -// with the given prefix and the prefix removed from the keys. -func (p *Properties) FilterStripPrefix(prefix string) *Properties { - pp := NewProperties() - n := len(prefix) - for _, k := range p.k { - if len(k) > len(prefix) && strings.HasPrefix(k, prefix) { - // TODO(fs): we are ignoring the error which flags a circular reference. - // TODO(fs): since we are modifying keys I am not entirely sure whether we can create a circular reference - // TODO(fs): this function should probably return an error but the signature is fixed - pp.Set(k[n:], p.m[k]) - } - } - return pp -} - -// Len returns the number of keys. -func (p *Properties) Len() int { - return len(p.m) -} - -// Keys returns all keys in the same order as in the input. -func (p *Properties) Keys() []string { - keys := make([]string, len(p.k)) - copy(keys, p.k) - return keys -} - -// Set sets the property key to the corresponding value. -// If a value for key existed before then ok is true and prev -// contains the previous value. If the value contains a -// circular reference or a malformed expression then -// an error is returned. -// An empty key is silently ignored. -func (p *Properties) Set(key, value string) (prev string, ok bool, err error) { - if key == "" { - return "", false, nil - } - - // if expansion is disabled we allow circular references - if p.DisableExpansion { - prev, ok = p.Get(key) - p.m[key] = value - if !ok { - p.k = append(p.k, key) - } - return prev, ok, nil - } - - // to check for a circular reference we temporarily need - // to set the new value. If there is an error then revert - // to the previous state. Only if all tests are successful - // then we add the key to the p.k list. - prev, ok = p.Get(key) - p.m[key] = value - - // now check for a circular reference - _, err = p.expand(key, value) - if err != nil { - - // revert to the previous state - if ok { - p.m[key] = prev - } else { - delete(p.m, key) - } - - return "", false, err - } - - if !ok { - p.k = append(p.k, key) - } - - return prev, ok, nil -} - -// SetValue sets property key to the default string value -// as defined by fmt.Sprintf("%v"). -func (p *Properties) SetValue(key string, value interface{}) error { - _, _, err := p.Set(key, fmt.Sprintf("%v", value)) - return err -} - -// MustSet sets the property key to the corresponding value. -// If a value for key existed before then ok is true and prev -// contains the previous value. An empty key is silently ignored. -func (p *Properties) MustSet(key, value string) (prev string, ok bool) { - prev, ok, err := p.Set(key, value) - if err != nil { - ErrorHandler(err) - } - return prev, ok -} - -// String returns a string of all expanded 'key = value' pairs. -func (p *Properties) String() string { - var s string - for _, key := range p.k { - value, _ := p.Get(key) - s = fmt.Sprintf("%s%s = %s\n", s, key, value) - } - return s -} - -// Sort sorts the properties keys in alphabetical order. -// This is helpfully before writing the properties. -func (p *Properties) Sort() { - sort.Strings(p.k) -} - -// Write writes all unexpanded 'key = value' pairs to the given writer. -// Write returns the number of bytes written and any write error encountered. -func (p *Properties) Write(w io.Writer, enc Encoding) (n int, err error) { - return p.WriteComment(w, "", enc) -} - -// WriteComment writes all unexpanced 'key = value' pairs to the given writer. -// If prefix is not empty then comments are written with a blank line and the -// given prefix. The prefix should be either "# " or "! " to be compatible with -// the properties file format. Otherwise, the properties parser will not be -// able to read the file back in. It returns the number of bytes written and -// any write error encountered. -func (p *Properties) WriteComment(w io.Writer, prefix string, enc Encoding) (n int, err error) { - var x int - - for _, key := range p.k { - value := p.m[key] - - if prefix != "" { - if comments, ok := p.c[key]; ok { - // don't print comments if they are all empty - allEmpty := true - for _, c := range comments { - if c != "" { - allEmpty = false - break - } - } - - if !allEmpty { - // add a blank line between entries but not at the top - if len(comments) > 0 && n > 0 { - x, err = fmt.Fprintln(w) - if err != nil { - return - } - n += x - } - - for _, c := range comments { - x, err = fmt.Fprintf(w, "%s%s\n", prefix, c) - if err != nil { - return - } - n += x - } - } - } - } - sep := " = " - if p.WriteSeparator != "" { - sep = p.WriteSeparator - } - x, err = fmt.Fprintf(w, "%s%s%s\n", encode(key, " :", enc), sep, encode(value, "", enc)) - if err != nil { - return - } - n += x - } - return -} - -// Map returns a copy of the properties as a map. -func (p *Properties) Map() map[string]string { - m := make(map[string]string) - for k, v := range p.m { - m[k] = v - } - return m -} - -// FilterFunc returns a copy of the properties which includes the values which passed all filters. -func (p *Properties) FilterFunc(filters ...func(k, v string) bool) *Properties { - pp := NewProperties() -outer: - for k, v := range p.m { - for _, f := range filters { - if !f(k, v) { - continue outer - } - pp.Set(k, v) - } - } - return pp -} - -// ---------------------------------------------------------------------------- - -// Delete removes the key and its comments. -func (p *Properties) Delete(key string) { - delete(p.m, key) - delete(p.c, key) - newKeys := []string{} - for _, k := range p.k { - if k != key { - newKeys = append(newKeys, k) - } - } - p.k = newKeys -} - -// Merge merges properties, comments and keys from other *Properties into p -func (p *Properties) Merge(other *Properties) { - for k, v := range other.m { - p.m[k] = v - } - for k, v := range other.c { - p.c[k] = v - } - -outer: - for _, otherKey := range other.k { - for _, key := range p.k { - if otherKey == key { - continue outer - } - } - p.k = append(p.k, otherKey) - } -} - -// ---------------------------------------------------------------------------- - -// check expands all values and returns an error if a circular reference or -// a malformed expression was found. -func (p *Properties) check() error { - for key, value := range p.m { - if _, err := p.expand(key, value); err != nil { - return err - } - } - return nil -} - -func (p *Properties) expand(key, input string) (string, error) { - // no pre/postfix -> nothing to expand - if p.Prefix == "" && p.Postfix == "" { - return input, nil - } - - return expand(input, []string{key}, p.Prefix, p.Postfix, p.m) -} - -// expand recursively expands expressions of '(prefix)key(postfix)' to their corresponding values. -// The function keeps track of the keys that were already expanded and stops if it -// detects a circular reference or a malformed expression of the form '(prefix)key'. -func expand(s string, keys []string, prefix, postfix string, values map[string]string) (string, error) { - if len(keys) > maxExpansionDepth { - return "", fmt.Errorf("expansion too deep") - } - - for { - start := strings.Index(s, prefix) - if start == -1 { - return s, nil - } - - keyStart := start + len(prefix) - keyLen := strings.Index(s[keyStart:], postfix) - if keyLen == -1 { - return "", fmt.Errorf("malformed expression") - } - - end := keyStart + keyLen + len(postfix) - 1 - key := s[keyStart : keyStart+keyLen] - - // fmt.Printf("s:%q pp:%q start:%d end:%d keyStart:%d keyLen:%d key:%q\n", s, prefix + "..." + postfix, start, end, keyStart, keyLen, key) - - for _, k := range keys { - if key == k { - var b bytes.Buffer - b.WriteString("circular reference in:\n") - for _, k1 := range keys { - fmt.Fprintf(&b, "%s=%s\n", k1, values[k1]) - } - return "", fmt.Errorf(b.String()) - } - } - - val, ok := values[key] - if !ok { - val = os.Getenv(key) - } - new_val, err := expand(val, append(keys, key), prefix, postfix, values) - if err != nil { - return "", err - } - s = s[:start] + new_val + s[end+1:] - } -} - -// encode encodes a UTF-8 string to ISO-8859-1 and escapes some characters. -func encode(s string, special string, enc Encoding) string { - switch enc { - case UTF8: - return encodeUtf8(s, special) - case ISO_8859_1: - return encodeIso(s, special) - default: - panic(fmt.Sprintf("unsupported encoding %v", enc)) - } -} - -func encodeUtf8(s string, special string) string { - v := "" - for pos := 0; pos < len(s); { - r, w := utf8.DecodeRuneInString(s[pos:]) - pos += w - v += escape(r, special) - } - return v -} - -func encodeIso(s string, special string) string { - var r rune - var w int - var v string - for pos := 0; pos < len(s); { - switch r, w = utf8.DecodeRuneInString(s[pos:]); { - case r < 1<<8: // single byte rune -> escape special chars only - v += escape(r, special) - case r < 1<<16: // two byte rune -> unicode literal - v += fmt.Sprintf("\\u%04x", r) - default: // more than two bytes per rune -> can't encode - v += "?" - } - pos += w - } - return v -} - -func escape(r rune, special string) string { - switch r { - case '\f': - return "\\f" - case '\n': - return "\\n" - case '\r': - return "\\r" - case '\t': - return "\\t" - case '\\': - return "\\\\" - default: - if strings.ContainsRune(special, r) { - return "\\" + string(r) - } - return string(r) - } -} - -func invalidKeyError(key string) error { - return fmt.Errorf("unknown property: %s", key) -} diff --git a/vendor/github.com/magiconair/properties/rangecheck.go b/vendor/github.com/magiconair/properties/rangecheck.go deleted file mode 100644 index b013a2e5e1..0000000000 --- a/vendor/github.com/magiconair/properties/rangecheck.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2018 Frank Schroeder. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package properties - -import ( - "fmt" - "math" -) - -// make this a var to overwrite it in a test -var is32Bit = ^uint(0) == math.MaxUint32 - -// intRangeCheck checks if the value fits into the int type and -// panics if it does not. -func intRangeCheck(key string, v int64) int { - if is32Bit && (v < math.MinInt32 || v > math.MaxInt32) { - panic(fmt.Sprintf("Value %d for key %s out of range", v, key)) - } - return int(v) -} - -// uintRangeCheck checks if the value fits into the uint type and -// panics if it does not. -func uintRangeCheck(key string, v uint64) uint { - if is32Bit && v > math.MaxUint32 { - panic(fmt.Sprintf("Value %d for key %s out of range", v, key)) - } - return uint(v) -} diff --git a/vendor/github.com/manuelarte/embeddedstructfieldcheck/LICENSE b/vendor/github.com/manuelarte/embeddedstructfieldcheck/LICENSE deleted file mode 100644 index 261eeb9e9f..0000000000 --- a/vendor/github.com/manuelarte/embeddedstructfieldcheck/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/manuelarte/embeddedstructfieldcheck/analyzer/analyzer.go b/vendor/github.com/manuelarte/embeddedstructfieldcheck/analyzer/analyzer.go deleted file mode 100644 index dc137d71e6..0000000000 --- a/vendor/github.com/manuelarte/embeddedstructfieldcheck/analyzer/analyzer.go +++ /dev/null @@ -1,64 +0,0 @@ -package analyzer - -import ( - "go/ast" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/inspector" - - "github.com/manuelarte/embeddedstructfieldcheck/internal" -) - -const ( - EmptyLineCheck = "empty-line" - ForbidMutexCheck = "forbid-mutex" -) - -func NewAnalyzer() *analysis.Analyzer { - var ( - emptyLine bool - forbidMutex bool - ) - - a := &analysis.Analyzer{ - Name: "embeddedstructfieldcheck", - Doc: "Embedded types should be at the top of the field list of a struct, " + - "and there must be an empty line separating embedded fields from regular fields.", - URL: "https://github.com/manuelarte/embeddedstructfieldcheck", - Run: func(pass *analysis.Pass) (any, error) { - run(pass, emptyLine, forbidMutex) - - //nolint:nilnil // impossible case. - return nil, nil - }, - Requires: []*analysis.Analyzer{inspect.Analyzer}, - } - - a.Flags.BoolVar(&emptyLine, EmptyLineCheck, true, - "Checks that there is an empty space between the embedded fields and regular fields.") - a.Flags.BoolVar(&forbidMutex, ForbidMutexCheck, false, - "Checks that sync.Mutex and sync.RWMutex are not used as an embedded fields.") - - return a -} - -func run(pass *analysis.Pass, emptyLine, forbidMutex bool) { - insp, found := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - if !found { - return - } - - nodeFilter := []ast.Node{ - (*ast.StructType)(nil), - } - - insp.Preorder(nodeFilter, func(n ast.Node) { - node, ok := n.(*ast.StructType) - if !ok { - return - } - - internal.Analyze(pass, node, emptyLine, forbidMutex) - }) -} diff --git a/vendor/github.com/manuelarte/embeddedstructfieldcheck/internal/diag.go b/vendor/github.com/manuelarte/embeddedstructfieldcheck/internal/diag.go deleted file mode 100644 index 337b0dff78..0000000000 --- a/vendor/github.com/manuelarte/embeddedstructfieldcheck/internal/diag.go +++ /dev/null @@ -1,48 +0,0 @@ -package internal - -import ( - "fmt" - "go/ast" - - "golang.org/x/tools/go/analysis" -) - -func NewMisplacedEmbeddedFieldDiag(embeddedField *ast.Field) analysis.Diagnostic { - return analysis.Diagnostic{ - Pos: embeddedField.Pos(), - Message: "embedded fields should be listed before regular fields", - } -} - -func NewMissingSpaceDiag( - lastEmbeddedField *ast.Field, - firstRegularField *ast.Field, -) analysis.Diagnostic { - suggestedPos := firstRegularField.Pos() - if firstRegularField.Doc != nil { - suggestedPos = firstRegularField.Doc.Pos() - } - - return analysis.Diagnostic{ - Pos: lastEmbeddedField.Pos(), - Message: "there must be an empty line separating embedded fields from regular fields", - SuggestedFixes: []analysis.SuggestedFix{ - { - Message: "adding extra line separating embedded fields from regular fields", - TextEdits: []analysis.TextEdit{ - { - Pos: suggestedPos, - NewText: []byte("\n\n"), - }, - }, - }, - }, - } -} - -func NewForbiddenEmbeddedFieldDiag(forbidField *ast.SelectorExpr) analysis.Diagnostic { - return analysis.Diagnostic{ - Pos: forbidField.Pos(), - Message: fmt.Sprintf("%s.%s should not be embedded", forbidField.X, forbidField.Sel.Name), - } -} diff --git a/vendor/github.com/manuelarte/embeddedstructfieldcheck/internal/structanalyzer.go b/vendor/github.com/manuelarte/embeddedstructfieldcheck/internal/structanalyzer.go deleted file mode 100644 index 2df53692a4..0000000000 --- a/vendor/github.com/manuelarte/embeddedstructfieldcheck/internal/structanalyzer.go +++ /dev/null @@ -1,88 +0,0 @@ -package internal - -import ( - "go/ast" - - "golang.org/x/tools/go/analysis" -) - -func Analyze(pass *analysis.Pass, st *ast.StructType, emptyLine, forbidMutex bool) { - var firstEmbeddedField *ast.Field - - var lastEmbeddedField *ast.Field - - var firstNotEmbeddedField *ast.Field - - for _, field := range st.Fields.List { - if isFieldEmbedded(field) { - checkForbiddenEmbeddedField(pass, field, forbidMutex) - - if firstEmbeddedField == nil { - firstEmbeddedField = field - } - - if lastEmbeddedField == nil || lastEmbeddedField.Pos() < field.Pos() { - lastEmbeddedField = field - } - - if firstNotEmbeddedField != nil && firstNotEmbeddedField.Pos() < field.Pos() { - pass.Report(NewMisplacedEmbeddedFieldDiag(field)) - return - } - } else if firstNotEmbeddedField == nil { - firstNotEmbeddedField = field - } - } - - if emptyLine { - checkMissingSpace(pass, lastEmbeddedField, firstNotEmbeddedField) - } -} - -func checkForbiddenEmbeddedField(pass *analysis.Pass, field *ast.Field, forbidMutex bool) { - if !forbidMutex { - return - } - - switch e := field.Type.(type) { - case *ast.StarExpr: - if se, isSelectorExpr := e.X.(*ast.SelectorExpr); isSelectorExpr { - reportSyncMutex(pass, se) - } - - case *ast.SelectorExpr: - reportSyncMutex(pass, e) - } -} - -func checkMissingSpace(pass *analysis.Pass, lastEmbeddedField, firstNotEmbeddedField *ast.Field) { - if lastEmbeddedField != nil && firstNotEmbeddedField != nil { - // check for missing space - // TODO: isn't it easy to remove as many lines as comments between last embedded type and first not embedded - line := pass.Fset.Position(lastEmbeddedField.End()).Line - - nextLine := pass.Fset.Position(firstNotEmbeddedField.Pos()).Line - if firstNotEmbeddedField.Doc != nil { - nextLine = pass.Fset.Position(firstNotEmbeddedField.Doc.Pos()).Line - } - - if nextLine != line+2 { - pass.Report(NewMissingSpaceDiag(lastEmbeddedField, firstNotEmbeddedField)) - } - } -} - -func isFieldEmbedded(field *ast.Field) bool { - return len(field.Names) == 0 -} - -func reportSyncMutex(pass *analysis.Pass, se *ast.SelectorExpr) { - packageName, isIdent := se.X.(*ast.Ident) - if !isIdent { - return - } - - if packageName.Name == "sync" && (se.Sel.Name == "Mutex" || se.Sel.Name == "RWMutex") { - pass.Report(NewForbiddenEmbeddedFieldDiag(se)) - } -} diff --git a/vendor/github.com/manuelarte/funcorder/LICENSE b/vendor/github.com/manuelarte/funcorder/LICENSE deleted file mode 100644 index 261eeb9e9f..0000000000 --- a/vendor/github.com/manuelarte/funcorder/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/manuelarte/funcorder/analyzer/analyzer.go b/vendor/github.com/manuelarte/funcorder/analyzer/analyzer.go deleted file mode 100644 index c3112107dd..0000000000 --- a/vendor/github.com/manuelarte/funcorder/analyzer/analyzer.go +++ /dev/null @@ -1,97 +0,0 @@ -package analyzer - -import ( - "go/ast" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/inspector" - - "github.com/manuelarte/funcorder/internal" -) - -const ( - ConstructorCheckName = "constructor" - StructMethodCheckName = "struct-method" - AlphabeticalCheckName = "alphabetical" -) - -func NewAnalyzer() *analysis.Analyzer { - f := funcorder{} - - a := &analysis.Analyzer{ - Name: "funcorder", - Doc: "checks the order of functions, methods, and constructors", - URL: "https://github.com/manuelarte/funcorder", - Run: f.run, - Requires: []*analysis.Analyzer{inspect.Analyzer}, - } - - a.Flags.BoolVar(&f.constructorCheck, ConstructorCheckName, true, - "Checks that constructors are placed after the structure declaration.") - a.Flags.BoolVar(&f.structMethodCheck, StructMethodCheckName, true, - "Checks if the exported methods of a structure are placed before the unexported ones.") - a.Flags.BoolVar(&f.alphabeticalCheck, AlphabeticalCheckName, false, - "Checks if the constructors and/or structure methods are sorted alphabetically.") - - return a -} - -type funcorder struct { - constructorCheck bool - structMethodCheck bool - alphabeticalCheck bool -} - -func (f *funcorder) run(pass *analysis.Pass) (any, error) { - var enabledCheckers internal.Feature - if f.constructorCheck { - enabledCheckers.Enable(internal.ConstructorCheck) - } - - if f.structMethodCheck { - enabledCheckers.Enable(internal.StructMethodCheck) - } - - if f.alphabeticalCheck { - enabledCheckers.Enable(internal.AlphabeticalCheck) - } - - fp := internal.NewFileProcessor(pass.Fset, enabledCheckers) - - insp, found := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - if !found { - //nolint:nilnil // impossible case. - return nil, nil - } - - nodeFilter := []ast.Node{ - (*ast.File)(nil), - (*ast.FuncDecl)(nil), - (*ast.TypeSpec)(nil), - } - - insp.Preorder(nodeFilter, func(n ast.Node) { - switch node := n.(type) { - case *ast.File: - for _, report := range fp.Analyze() { - pass.Report(report) - } - - fp.NewFileNode(node) - - case *ast.FuncDecl: - fp.NewFuncDecl(node) - - case *ast.TypeSpec: - fp.NewTypeSpec(node) - } - }) - - for _, report := range fp.Analyze() { - pass.Report(report) - } - - //nolint:nilnil //any, error - return nil, nil -} diff --git a/vendor/github.com/manuelarte/funcorder/internal/astutils.go b/vendor/github.com/manuelarte/funcorder/internal/astutils.go deleted file mode 100644 index af7fa8c81d..0000000000 --- a/vendor/github.com/manuelarte/funcorder/internal/astutils.go +++ /dev/null @@ -1,93 +0,0 @@ -package internal - -import ( - "bytes" - "go/ast" - "go/format" - "go/token" - "strings" -) - -func FuncCanBeConstructor(n *ast.FuncDecl) bool { - if !n.Name.IsExported() || n.Recv != nil { - return false - } - - if n.Type.Results == nil || len(n.Type.Results.List) == 0 { - return false - } - - for _, prefix := range []string{"new", "must"} { - if strings.HasPrefix(strings.ToLower(n.Name.Name), prefix) && - len(n.Name.Name) > len(prefix) { // TODO(ldez): bug if the name is just `New`. - return true - } - } - - return false -} - -func FuncIsMethod(n *ast.FuncDecl) (*ast.Ident, bool) { - if n.Recv == nil { - return nil, false - } - - if len(n.Recv.List) != 1 { - return nil, false - } - - if recv, ok := GetIdent(n.Recv.List[0].Type); ok { - return recv, true - } - - return nil, false -} - -func GetIdent(expr ast.Expr) (*ast.Ident, bool) { - switch exp := expr.(type) { - case *ast.StarExpr: - return GetIdent(exp.X) - - case *ast.Ident: - return exp, true - - default: - return nil, false - } -} - -// GetStartingPos returns the token starting position of the function -// taking into account if there are comments. -func GetStartingPos(function *ast.FuncDecl) token.Pos { - startingPos := function.Pos() - if function.Doc != nil { - startingPos = function.Doc.Pos() - } - - return startingPos -} - -// NodeToBytes convert the ast.Node in bytes. -func NodeToBytes(fset *token.FileSet, node ast.Node) ([]byte, error) { - var buf bytes.Buffer - if err := format.Node(&buf, fset, node); err != nil { - return nil, err - } - - return buf.Bytes(), nil -} - -// SplitExportedUnexported split functions/methods based on whether they are exported or not. -// -//nolint:nonamedreturns // names serve as documentation -func SplitExportedUnexported(funcDecls []*ast.FuncDecl) (exported, unexported []*ast.FuncDecl) { - for _, f := range funcDecls { - if f.Name.IsExported() { - exported = append(exported, f) - } else { - unexported = append(unexported, f) - } - } - - return exported, unexported -} diff --git a/vendor/github.com/manuelarte/funcorder/internal/diag.go b/vendor/github.com/manuelarte/funcorder/internal/diag.go deleted file mode 100644 index faf2ffdd16..0000000000 --- a/vendor/github.com/manuelarte/funcorder/internal/diag.go +++ /dev/null @@ -1,69 +0,0 @@ -package internal - -import ( - "fmt" - "go/ast" - - "golang.org/x/tools/go/analysis" -) - -func NewConstructorNotAfterStructType(structSpec *ast.TypeSpec, constructor *ast.FuncDecl) analysis.Diagnostic { - return analysis.Diagnostic{ - Pos: constructor.Pos(), - Message: fmt.Sprintf("constructor %q for struct %q should be placed after the struct declaration", - constructor.Name, structSpec.Name), - URL: "https://github.com/manuelarte/funcorder?tab=readme-ov-file#check-constructors-functions-are-placed-after-struct-declaration", //nolint:lll // url - } -} - -func NewConstructorNotBeforeStructMethod( - structSpec *ast.TypeSpec, - constructor *ast.FuncDecl, - method *ast.FuncDecl, -) analysis.Diagnostic { - return analysis.Diagnostic{ - Pos: constructor.Pos(), - URL: "https://github.com/manuelarte/funcorder?tab=readme-ov-file#check-constructors-functions-are-placed-after-struct-declaration", //nolint:lll // url - Message: fmt.Sprintf("constructor %q for struct %q should be placed before struct method %q", - constructor.Name, structSpec.Name, method.Name), - } -} - -func NewAdjacentConstructorsNotSortedAlphabetically( - structSpec *ast.TypeSpec, - constructorNotSorted *ast.FuncDecl, - otherConstructorNotSorted *ast.FuncDecl, -) analysis.Diagnostic { - return analysis.Diagnostic{ - Pos: otherConstructorNotSorted.Pos(), - URL: "https://github.com/manuelarte/funcorder?tab=readme-ov-file#check-constructorsmethods-are-sorted-alphabetically", - Message: fmt.Sprintf("constructor %q for struct %q should be placed before constructor %q", - otherConstructorNotSorted.Name, structSpec.Name, constructorNotSorted.Name), - } -} - -func NewUnexportedMethodBeforeExportedForStruct( - structSpec *ast.TypeSpec, - privateMethod *ast.FuncDecl, - publicMethod *ast.FuncDecl, -) analysis.Diagnostic { - return analysis.Diagnostic{ - Pos: privateMethod.Pos(), - URL: "https://github.com/manuelarte/funcorder?tab=readme-ov-file#check-exported-methods-are-placed-before-unexported-methods", //nolint:lll // url - Message: fmt.Sprintf("unexported method %q for struct %q should be placed after the exported method %q", - privateMethod.Name, structSpec.Name, publicMethod.Name), - } -} - -func NewAdjacentStructMethodsNotSortedAlphabetically( - structSpec *ast.TypeSpec, - method *ast.FuncDecl, - otherMethod *ast.FuncDecl, -) analysis.Diagnostic { - return analysis.Diagnostic{ - Pos: otherMethod.Pos(), - URL: "https://github.com/manuelarte/funcorder?tab=readme-ov-file#check-constructorsmethods-are-sorted-alphabetically", - Message: fmt.Sprintf("method %q for struct %q should be placed before method %q", - otherMethod.Name, structSpec.Name, method.Name), - } -} diff --git a/vendor/github.com/manuelarte/funcorder/internal/features.go b/vendor/github.com/manuelarte/funcorder/internal/features.go deleted file mode 100644 index 55d5caba3b..0000000000 --- a/vendor/github.com/manuelarte/funcorder/internal/features.go +++ /dev/null @@ -1,17 +0,0 @@ -package internal - -const ( - ConstructorCheck Feature = 1 << iota - StructMethodCheck - AlphabeticalCheck -) - -type Feature uint8 - -func (f *Feature) Enable(other Feature) { - *f |= other -} - -func (f *Feature) IsEnabled(other Feature) bool { - return *f&other != 0 -} diff --git a/vendor/github.com/manuelarte/funcorder/internal/file_processor.go b/vendor/github.com/manuelarte/funcorder/internal/file_processor.go deleted file mode 100644 index 88ae00f2e6..0000000000 --- a/vendor/github.com/manuelarte/funcorder/internal/file_processor.go +++ /dev/null @@ -1,82 +0,0 @@ -package internal - -import ( - "go/ast" - "go/token" - - "golang.org/x/tools/go/analysis" -) - -// FileProcessor Holder to store all the functions that are potential to be constructors and all the structs. -type FileProcessor struct { - fset *token.FileSet - structs map[string]*StructHolder - features Feature -} - -// NewFileProcessor creates a new file processor. -func NewFileProcessor(fset *token.FileSet, checkers Feature) *FileProcessor { - return &FileProcessor{ - fset: fset, - structs: make(map[string]*StructHolder), - features: checkers, - } -} - -// Analyze check whether the order of the methods in the constructor is correct. -func (fp *FileProcessor) Analyze() []analysis.Diagnostic { - var reports []analysis.Diagnostic - - for _, sh := range fp.structs { - // filter out structs that are not declared inside that file - if sh.Struct != nil { - reports = append(reports, sh.Analyze()...) - } - } - - return reports -} - -func (fp *FileProcessor) NewFileNode(_ *ast.File) { - fp.structs = make(map[string]*StructHolder) -} - -func (fp *FileProcessor) NewFuncDecl(n *ast.FuncDecl) { - if sc, ok := NewStructConstructor(n); ok { - fp.addConstructor(sc) - return - } - - if st, ok := FuncIsMethod(n); ok { - fp.addMethod(st.Name, n) - } -} - -func (fp *FileProcessor) NewTypeSpec(n *ast.TypeSpec) { - sh := fp.getOrCreate(n.Name.Name) - sh.Struct = n -} - -func (fp *FileProcessor) addConstructor(sc StructConstructor) { - sh := fp.getOrCreate(sc.GetStructReturn().Name) - sh.AddConstructor(sc.GetConstructor()) -} - -func (fp *FileProcessor) addMethod(st string, n *ast.FuncDecl) { - sh := fp.getOrCreate(st) - sh.AddMethod(n) -} - -func (fp *FileProcessor) getOrCreate(structName string) *StructHolder { - if holder, ok := fp.structs[structName]; ok { - return holder - } - - created := &StructHolder{ - Fset: fp.fset, - Features: fp.features, - } - fp.structs[structName] = created - - return created -} diff --git a/vendor/github.com/manuelarte/funcorder/internal/struct_constructor.go b/vendor/github.com/manuelarte/funcorder/internal/struct_constructor.go deleted file mode 100644 index fc4b252dfe..0000000000 --- a/vendor/github.com/manuelarte/funcorder/internal/struct_constructor.go +++ /dev/null @@ -1,37 +0,0 @@ -package internal - -import ( - "go/ast" -) - -type StructConstructor struct { - constructor *ast.FuncDecl - structReturn *ast.Ident -} - -func NewStructConstructor(funcDec *ast.FuncDecl) (StructConstructor, bool) { - if !FuncCanBeConstructor(funcDec) { - return StructConstructor{}, false - } - - expr := funcDec.Type.Results.List[0].Type - - returnType, ok := GetIdent(expr) - if !ok { - return StructConstructor{}, false - } - - return StructConstructor{ - constructor: funcDec, - structReturn: returnType, - }, true -} - -// GetStructReturn Return the struct linked to this "constructor". -func (sc StructConstructor) GetStructReturn() *ast.Ident { - return sc.structReturn -} - -func (sc StructConstructor) GetConstructor() *ast.FuncDecl { - return sc.constructor -} diff --git a/vendor/github.com/manuelarte/funcorder/internal/structholder.go b/vendor/github.com/manuelarte/funcorder/internal/structholder.go deleted file mode 100644 index 424b2ddd71..0000000000 --- a/vendor/github.com/manuelarte/funcorder/internal/structholder.go +++ /dev/null @@ -1,141 +0,0 @@ -package internal - -import ( - "cmp" - "go/ast" - "go/token" - "slices" - - "golang.org/x/tools/go/analysis" -) - -type ( - ExportedMethods []*ast.FuncDecl - UnexportedMethods []*ast.FuncDecl -) - -// StructHolder contains all the information around a Go struct. -type StructHolder struct { - // The fileset - Fset *token.FileSet - // The features to be analyzed - Features Feature - - // The struct declaration - Struct *ast.TypeSpec - - // A Struct constructor is considered if starts with `New...` and the 1st output parameter is a struct - Constructors []*ast.FuncDecl - - // Struct methods - StructMethods []*ast.FuncDecl -} - -func (sh *StructHolder) AddConstructor(fn *ast.FuncDecl) { - sh.Constructors = append(sh.Constructors, fn) -} - -func (sh *StructHolder) AddMethod(fn *ast.FuncDecl) { - sh.StructMethods = append(sh.StructMethods, fn) -} - -// Analyze applies the linter to the struct holder. -func (sh *StructHolder) Analyze() []analysis.Diagnostic { - // TODO maybe sort constructors and then report also, like NewXXX before MustXXX - slices.SortFunc(sh.StructMethods, func(a, b *ast.FuncDecl) int { - return cmp.Compare(a.Pos(), b.Pos()) - }) - - var reports []analysis.Diagnostic - - if sh.Features.IsEnabled(ConstructorCheck) { - reports = append(reports, sh.analyzeConstructor()...) - } - - if sh.Features.IsEnabled(StructMethodCheck) { - reports = append(reports, sh.analyzeStructMethod()...) - } - - // TODO also check that the methods are declared after the struct - return reports -} - -func (sh *StructHolder) analyzeConstructor() []analysis.Diagnostic { - var reports []analysis.Diagnostic - - for i, constructor := range sh.Constructors { - if constructor.Pos() < sh.Struct.Pos() { - reports = append(reports, NewConstructorNotAfterStructType(sh.Struct, constructor)) - } - - if len(sh.StructMethods) > 0 && constructor.Pos() > sh.StructMethods[0].Pos() { - reports = append(reports, NewConstructorNotBeforeStructMethod(sh.Struct, constructor, sh.StructMethods[0])) - } - - if sh.Features.IsEnabled(AlphabeticalCheck) && - i < len(sh.Constructors)-1 && sh.Constructors[i].Name.Name > sh.Constructors[i+1].Name.Name { - reports = append(reports, - NewAdjacentConstructorsNotSortedAlphabetically(sh.Struct, sh.Constructors[i], sh.Constructors[i+1]), - ) - } - } - - return reports -} - -func (sh *StructHolder) analyzeStructMethod() []analysis.Diagnostic { - var lastExportedMethod *ast.FuncDecl - - for _, m := range sh.StructMethods { - if !m.Name.IsExported() { - continue - } - - if lastExportedMethod == nil { - lastExportedMethod = m - } - - if lastExportedMethod.Pos() < m.Pos() { - lastExportedMethod = m - } - } - - var reports []analysis.Diagnostic - - if lastExportedMethod != nil { - for _, m := range sh.StructMethods { - if m.Name.IsExported() || m.Pos() >= lastExportedMethod.Pos() { - continue - } - - reports = append(reports, NewUnexportedMethodBeforeExportedForStruct(sh.Struct, m, lastExportedMethod)) - } - } - - if sh.Features.IsEnabled(AlphabeticalCheck) { - exported, unexported := SplitExportedUnexported(sh.StructMethods) - reports = slices.Concat(reports, - sortDiagnostics(sh.Struct, exported), - sortDiagnostics(sh.Struct, unexported), - ) - } - - return reports -} - -func sortDiagnostics(typeSpec *ast.TypeSpec, funcDecls []*ast.FuncDecl) []analysis.Diagnostic { - var reports []analysis.Diagnostic - - for i := range funcDecls { - if i >= len(funcDecls)-1 { - continue - } - - if funcDecls[i].Name.Name > funcDecls[i+1].Name.Name { - reports = append(reports, - NewAdjacentStructMethodsNotSortedAlphabetically(typeSpec, funcDecls[i], funcDecls[i+1])) - } - } - - return reports -} diff --git a/vendor/github.com/maratori/testableexamples/LICENSE b/vendor/github.com/maratori/testableexamples/LICENSE deleted file mode 100644 index e8b68be3eb..0000000000 --- a/vendor/github.com/maratori/testableexamples/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2022 Marat Reymers - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/maratori/testableexamples/pkg/testableexamples/testableexamples.go b/vendor/github.com/maratori/testableexamples/pkg/testableexamples/testableexamples.go deleted file mode 100644 index 91a8509d2a..0000000000 --- a/vendor/github.com/maratori/testableexamples/pkg/testableexamples/testableexamples.go +++ /dev/null @@ -1,34 +0,0 @@ -package testableexamples - -import ( - "go/ast" - "go/doc" - "strings" - - "golang.org/x/tools/go/analysis" -) - -// NewAnalyzer returns Analyzer that checks if examples are testable. -func NewAnalyzer() *analysis.Analyzer { - return &analysis.Analyzer{ - Name: "testableexamples", - Doc: "linter checks if examples are testable (have an expected output)", - Run: func(pass *analysis.Pass) (any, error) { - testFiles := make([]*ast.File, 0, len(pass.Files)) - for _, file := range pass.Files { - fileName := pass.Fset.File(file.Pos()).Name() - if strings.HasSuffix(fileName, "_test.go") { - testFiles = append(testFiles, file) - } - } - - for _, example := range doc.Examples(testFiles...) { - if example.Output == "" && !example.EmptyOutput { - pass.Reportf(example.Code.Pos(), "missing output for example, go test can't validate it") - } - } - - return nil, nil - }, - } -} diff --git a/vendor/github.com/maratori/testpackage/LICENSE b/vendor/github.com/maratori/testpackage/LICENSE deleted file mode 100644 index 644d0b1c8c..0000000000 --- a/vendor/github.com/maratori/testpackage/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2019 Marat Reymers - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/maratori/testpackage/pkg/testpackage/testpackage.go b/vendor/github.com/maratori/testpackage/pkg/testpackage/testpackage.go deleted file mode 100644 index 6eebabc2db..0000000000 --- a/vendor/github.com/maratori/testpackage/pkg/testpackage/testpackage.go +++ /dev/null @@ -1,71 +0,0 @@ -package testpackage - -import ( - "flag" - "go/ast" - "regexp" - "slices" - "strings" - - "golang.org/x/tools/go/analysis" -) - -const ( - SkipRegexpFlagName = "skip-regexp" - SkipRegexpFlagUsage = `regexp pattern to skip file by name. To not skip files use -skip-regexp="^$"` - SkipRegexpFlagDefault = `(export|internal)_test\.go` -) - -const ( - AllowPackagesFlagName = "allow-packages" - AllowPackagesFlagUsage = `comma separated list of packages that don't end with _test that tests are allowed to be in` - AllowPackagesFlagDefault = `main` -) - -func processTestFile(pass *analysis.Pass, f *ast.File, allowedPackages []string) { - packageName := f.Name.Name - - if slices.Contains(allowedPackages, packageName) { - return - } - - if !strings.HasSuffix(packageName, "_test") { - pass.Reportf(f.Name.Pos(), "package should be `%s_test` instead of `%s`", packageName, packageName) - } -} - -// NewAnalyzer returns Analyzer that makes you use a separate _test package. -func NewAnalyzer() *analysis.Analyzer { - var ( - skipFileRegexp = SkipRegexpFlagDefault - allowPackagesStr = AllowPackagesFlagDefault - fs flag.FlagSet - ) - - fs.StringVar(&skipFileRegexp, SkipRegexpFlagName, skipFileRegexp, SkipRegexpFlagUsage) - fs.StringVar(&allowPackagesStr, AllowPackagesFlagName, allowPackagesStr, AllowPackagesFlagUsage) - - return &analysis.Analyzer{ - Name: "testpackage", - Doc: "linter that makes you use a separate _test package", - Flags: fs, - Run: func(pass *analysis.Pass) (any, error) { - allowedPackages := strings.Split(allowPackagesStr, ",") - skipFile, err := regexp.Compile(skipFileRegexp) - if err != nil { - return nil, err - } - - for _, f := range pass.Files { - fileName := pass.Fset.Position(f.Pos()).Filename - if !strings.HasSuffix(fileName, "_test.go") || skipFile.MatchString(fileName) { - continue - } - - processTestFile(pass, f, allowedPackages) - } - - return nil, nil - }, - } -} diff --git a/vendor/github.com/matoous/godox/.gitignore b/vendor/github.com/matoous/godox/.gitignore deleted file mode 100644 index 30d94b1021..0000000000 --- a/vendor/github.com/matoous/godox/.gitignore +++ /dev/null @@ -1,19 +0,0 @@ -# Binaries for programs and plugins -*.exe -*.dll -*.so -*.dylib -.idea - -# Test binary, build with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 -.glide/ - -.vscode/ -debug -debug.test diff --git a/vendor/github.com/matoous/godox/.golangci.yml b/vendor/github.com/matoous/godox/.golangci.yml deleted file mode 100644 index 8d080b28aa..0000000000 --- a/vendor/github.com/matoous/godox/.golangci.yml +++ /dev/null @@ -1,72 +0,0 @@ -linters-settings: - dupl: - threshold: 100 - gocritic: - # Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint` run to see all tags and checks. - # Empty list by default. See https://github.com/go-critic/go-critic#usage -> section "Tags". - enabled-tags: - - performance - - diagnostic - - style - disabled-checks: - - emptyStringTest - - unnamedResult # it is experimental currently and doesn't handle typed channels correctly - gocyclo: - min-complexity: 14 # TODO go lower - govet: - enable: - - shadow - goconst: - min-len: 2 - min-occurrences: 3 - goimports: - local-prefixes: gitlab.skypicker.com/search-team/gonuts/conveyance-store - lll: - line-length: 140 - misspell: - locale: US - -linters: - enable-all: true - disable: - - depguard - # prealloc is not recommended by `golangci-lint` developers. - - prealloc - - gochecknoglobals - - # deprecated - - maligned - - exhaustivestruct - - nosnakecase - - scopelint - - structcheck - - ifshort - - varcheck - - deadcode - - golint - - interfacer - -issues: - exclude-dirs: - - "fixtures" - exclude-rules: - - path: _test\.go - linters: - - exhaustruct - - goconst - - dupl - -run: - modules-download-mode: readonly - -# output configuration options -output: - # colored-line-number|line-number|json|tab|checkstyle|code-climate, default is "colored-line-number" - formats: - - format: tab - - # print lines of code with issue, default is true - print-issued-lines: true - - # print linter name in the end of issue text, default is true - print-linter-name: true diff --git a/vendor/github.com/matoous/godox/.revive.toml b/vendor/github.com/matoous/godox/.revive.toml deleted file mode 100644 index a4a30464da..0000000000 --- a/vendor/github.com/matoous/godox/.revive.toml +++ /dev/null @@ -1,136 +0,0 @@ -ignoreGeneratedHeader = false -severity = "warning" -exclude = ["./fixtures/..."] - -# confidence <= 0.2 generate a lot of errors from package-comments rule. It marks files that do not contain -# package-level comments as a warning irrespective of existing package-level coment in one file. -confidence = 0.25 -errorCode = 1 -warningCode = 1 - -# Rules block. -# ⚠ Make sure to sort rules alpabetically for readability! ⚠ - -# argument-limit rule is setting up a maximum number of parameters that can be passed to the functions/methods. -[rule.argument-limit] - arguments = [5] - -# atomic rule checks for commonly mistaken usages of the sync/atomic package. -[rule.atomic] - -# blank-imports rule disallows blank imports. -[rule.blank-imports] - -# bool-literal-in-expr suggests removing boolean literals from logic expressions like `bar == true`, `arg == false`, -# `r != true`, `false && boolExpr` and `boolExpr || true`. -[rule.bool-literal-in-expr] - -# constant-logical-expr rule warns on constant logical expressions, like `name == name`. -[rule.constant-logical-expr] - -# context-as-argument rule makes sure that context.Context is the first argument of a function. -[rule.context-as-argument] - -# context-keys-type rule disallows the usage of basic types in context.WithValue -[rule.context-keys-type] - -# confusing-naming rule warns on methods with names that differ only by capitalization. -[rule.confusing-naming] - -# confusing-results rule suggests to name potentially confusing function results. -[rule.confusing-results] - -# cyclomatic rule sets restriction for maximum Cyclomatic complexity. -[rule.cyclomatic] - arguments = [15] - -# deep-exit rule looks for program exits in funcs other than `main()` or `init()`. -[rule.deep-exit] - -# dot-imports rule forbids `.` imports. -[rule.dot-imports] - -# empty-block warns on empty code blocks. -[rule.empty-block] - -# error-return rule ensure that the error return parameter is the last. -[rule.error-return] - -# error-strings rule ensure conventions around error strings. -[rule.error-strings] - -# error-naming rule ensure naming of error variables (has `Err` or `err` prefix). -[rule.error-naming] - -# errorf rule warns on usage errors.New(fmt.Sprintf()) instead of fmt.Errorf() -[rule.errorf] - -# exported rule ensure naming and commenting conventions on exported symbols. -[rule.exported] - -# flag-parameter rule warns on boolean parameters that create a control coupling. -[rule.flag-parameter] - -# get-return rule warns on getters that do not yield any result. -[rule.get-return] - -# if-return rule warns redundant if when returning an error. -[rule.if-return] - -# increment-decrement rule forces to use `i++` and `i--` instead of `i += 1` and `i -= 1`. -[rule.increment-decrement] - -# indent-error-flow rule prevents redundant else statements. -[rule.indent-error-flow] - -# modifies-value-receiver warns on assignments to value-passed method receivers. -[rule.modifies-value-receiver] - -# package-comments rule ensures package commenting conventions. -[rule.package-comments] - -# range rule prevents redundant variables when iterating over a collection. -[rule.range] - -# range-val-in-closure warns if range value is used in a closure dispatched as goroutine. -[rule.range-val-in-closure] - -# receiver-naming ensures conventions around the naming of receivers. -[rule.receiver-naming] - -# redefines-builtin-id warns on redefinitions of built-in (constants, variables, function and types) identifiers, -# like `true := "false"` etc. -[rule.redefines-builtin-id] - -# rule.superfluous-else prevents redundant else statements (extends indent-error-flow). Checks for `if-then-else`where -# the then block ends with branching statement like `continue`, `break`, or `goto`. -[rule.superfluous-else] - -# rule.struct-tag checks common struct tags like `json`, `xml`, `yaml`. -[rule.struct-tag] - -# time-naming rule conventions around the naming of time variables. Like not to use unit suffixes (sec, min etc.) in -# naming variables of type `time.Time` or `time.Duration`. -[rule.time-naming] - -# unexported-return rule warns when a public return is from unexported type. -[rule.unexported-return] - -# unnecessary-stmt suggests removing or simplifying unnecessary statements like breaks at the end of cases or return at -# the end of bodies of functions returning nothing. -[rule.unnecessary-stmt] - -# unreachable-code rule warns on the unreachable code. -[rule.unreachable-code] - -# unused-parameter rule suggests to rename or remove unused function parameters. -[rule.unused-parameter] - -# var-declaration rule reduces redundancies around variable declaration. -[rule.var-declaration] - -# var-naming checks naming rules. -[rule.var-naming] - -# waitgroup-by-value rule warns on functions taking `sync.WaitGroup` as a by-value parameter. -[rule.waitgroup-by-value] diff --git a/vendor/github.com/matoous/godox/LICENSE b/vendor/github.com/matoous/godox/LICENSE deleted file mode 100644 index 49e1b1e3ab..0000000000 --- a/vendor/github.com/matoous/godox/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2018 Matous Dzivjak - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/matoous/godox/Makefile b/vendor/github.com/matoous/godox/Makefile deleted file mode 100644 index 694aa21d64..0000000000 --- a/vendor/github.com/matoous/godox/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -## Help display. -## Pulls comments from beside commands and prints a nicely formatted -## display with the commands and their usage information. - -.DEFAULT_GOAL := help - -help: ## Prints this help - @grep -h -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' - -.PHONY: lint -lint: ## Lint the application - golangci-lint run --max-same-issues=0 --timeout=1m ./... - -.PHONY: test -test: ## Run unit tests - go test -race -shuffle=on ./... - -.PHONY: vet -vet: ## Run go vet - go vet ./... diff --git a/vendor/github.com/matoous/godox/README.md b/vendor/github.com/matoous/godox/README.md deleted file mode 100644 index 9c58e28ce7..0000000000 --- a/vendor/github.com/matoous/godox/README.md +++ /dev/null @@ -1,23 +0,0 @@ -GoDoX -=== - -[![Tests](https://github.com/matoous/godox/actions/workflows/test.yml/badge.svg)](https://github.com/matoous/godox/actions/workflows/test.yml) -[![Lint](https://github.com/matoous/godox/actions/workflows/lint.yml/badge.svg)](https://github.com/matoous/godox/actions/workflows/lint.yml) -[![GoDoc](https://godoc.org/github.com/matoous/godox?status.svg)](https://godoc.org/github.com/matoous/godox) -[![Go Report Card](https://goreportcard.com/badge/github.com/matoous/godox)](https://goreportcard.com/report/github.com/matoous/godox) -[![GitHub issues](https://img.shields.io/github/issues/matoous/godox.svg)](https://github.com/matoous/godox/issues) -[![License](https://img.shields.io/badge/license-MIT%20License-blue.svg)](https://github.com/matoous/godox/LICENSE) - -GoDoX extracts comments from Go code based on keywords. This repository is fork of https://github.com/766b/godox -but a lot of code has changed, this repository is updated and the code was adjusted for better integration with -https://github.com/golangci/golangci-lint. - -Installation ---- - - go get github.com/matoous/godox - -The main idea ---- - -The main idea of godox is the keywords like TODO, FIX, OPTIMIZE is temporary and for development purpose only. You should create tasks if some TODOs cannot be fixed in the current merge request. diff --git a/vendor/github.com/matoous/godox/godox.go b/vendor/github.com/matoous/godox/godox.go deleted file mode 100644 index 5bcc7e980a..0000000000 --- a/vendor/github.com/matoous/godox/godox.go +++ /dev/null @@ -1,122 +0,0 @@ -// Package godox is a linter that scans Go code for comments containing certain keywords -// (like TODO, BUG, FIXME) which typically indicate areas that require attention. -package godox - -import ( - "bufio" - "bytes" - "fmt" - "go/ast" - "go/token" - "path/filepath" - "strings" - "unicode" - "unicode/utf8" -) - -var defaultKeywords = []string{"TODO", "BUG", "FIXME"} - -// Message contains a message and position. -type Message struct { - Pos token.Position - Message string -} - -func getMessages(comment *ast.Comment, fset *token.FileSet, keywords []string) ([]Message, error) { - commentText := extractComment(comment.Text) - - scanner := bufio.NewScanner(bytes.NewBufferString(commentText)) - - var comments []Message - - for lineNum := 0; scanner.Scan(); lineNum++ { - const minimumSize = 4 - - sComment := bytes.TrimSpace(scanner.Bytes()) - if len(sComment) < minimumSize { - continue - } - - for _, kw := range keywords { - if lkw := len(kw); !(bytes.EqualFold([]byte(kw), sComment[0:lkw]) && - !hasAlphanumRuneAdjacent(sComment[lkw:])) { - continue - } - - pos := fset.Position(comment.Pos()) - // trim the comment - const commentLimit = 40 - if len(sComment) > commentLimit { - sComment = []byte(fmt.Sprintf("%.40s...", sComment)) - } - - comments = append(comments, Message{ - Pos: pos, - Message: fmt.Sprintf( - "%s:%d: Line contains %s: %q", - filepath.Clean(pos.Filename), - pos.Line+lineNum, - strings.Join(keywords, "/"), - sComment, - ), - }) - - break - } - } - - if err := scanner.Err(); err != nil { - return nil, fmt.Errorf("scan: %w", err) - } - - return comments, nil -} - -func extractComment(commentText string) string { - switch commentText[1] { - case '/': - return strings.TrimPrefix(commentText[2:], " ") - case '*': - return commentText[2 : len(commentText)-2] - default: - return commentText - } -} - -func hasAlphanumRuneAdjacent(rest []byte) bool { - if len(rest) == 0 { - return false - } - - switch rest[0] { // most common cases - case ':', ' ', '(': - return false - } - - r, _ := utf8.DecodeRune(rest) - - return unicode.IsLetter(r) || unicode.IsNumber(r) || unicode.IsDigit(r) -} - -// Run runs the godox linter on given file. -// Godox searches for comments starting with given keywords and reports them. -func Run(file *ast.File, fset *token.FileSet, keywords ...string) ([]Message, error) { - if len(keywords) == 0 { - keywords = defaultKeywords - } - - var messages []Message - - for _, c := range file.Comments { - for _, ci := range c.List { - msgs, err := getMessages(ci, fset, keywords) - if err != nil { - return nil, err - } - - messages = append(messages, msgs...) - } - } - - return messages, nil -} diff --git a/vendor/github.com/mattn/go-runewidth/LICENSE b/vendor/github.com/mattn/go-runewidth/LICENSE deleted file mode 100644 index 91b5cef30e..0000000000 --- a/vendor/github.com/mattn/go-runewidth/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2016 Yasuhiro Matsumoto - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/mattn/go-runewidth/README.md b/vendor/github.com/mattn/go-runewidth/README.md deleted file mode 100644 index 5e2cfd98cb..0000000000 --- a/vendor/github.com/mattn/go-runewidth/README.md +++ /dev/null @@ -1,27 +0,0 @@ -go-runewidth -============ - -[![Build Status](https://github.com/mattn/go-runewidth/workflows/test/badge.svg?branch=master)](https://github.com/mattn/go-runewidth/actions?query=workflow%3Atest) -[![Codecov](https://codecov.io/gh/mattn/go-runewidth/branch/master/graph/badge.svg)](https://codecov.io/gh/mattn/go-runewidth) -[![GoDoc](https://godoc.org/github.com/mattn/go-runewidth?status.svg)](http://godoc.org/github.com/mattn/go-runewidth) -[![Go Report Card](https://goreportcard.com/badge/github.com/mattn/go-runewidth)](https://goreportcard.com/report/github.com/mattn/go-runewidth) - -Provides functions to get fixed width of the character or string. - -Usage ------ - -```go -runewidth.StringWidth("つのだ☆HIRO") == 12 -``` - - -Author ------- - -Yasuhiro Matsumoto - -License -------- - -under the MIT License: http://mattn.mit-license.org/2013 diff --git a/vendor/github.com/mattn/go-runewidth/runewidth.go b/vendor/github.com/mattn/go-runewidth/runewidth.go deleted file mode 100644 index 7dfbb3be91..0000000000 --- a/vendor/github.com/mattn/go-runewidth/runewidth.go +++ /dev/null @@ -1,358 +0,0 @@ -package runewidth - -import ( - "os" - "strings" - - "github.com/rivo/uniseg" -) - -//go:generate go run script/generate.go - -var ( - // EastAsianWidth will be set true if the current locale is CJK - EastAsianWidth bool - - // StrictEmojiNeutral should be set false if handle broken fonts - StrictEmojiNeutral bool = true - - // DefaultCondition is a condition in current locale - DefaultCondition = &Condition{ - EastAsianWidth: false, - StrictEmojiNeutral: true, - } -) - -func init() { - handleEnv() -} - -func handleEnv() { - env := os.Getenv("RUNEWIDTH_EASTASIAN") - if env == "" { - EastAsianWidth = IsEastAsian() - } else { - EastAsianWidth = env == "1" - } - // update DefaultCondition - if DefaultCondition.EastAsianWidth != EastAsianWidth { - DefaultCondition.EastAsianWidth = EastAsianWidth - if len(DefaultCondition.combinedLut) > 0 { - DefaultCondition.combinedLut = DefaultCondition.combinedLut[:0] - CreateLUT() - } - } -} - -type interval struct { - first rune - last rune -} - -type table []interval - -func inTables(r rune, ts ...table) bool { - for _, t := range ts { - if inTable(r, t) { - return true - } - } - return false -} - -func inTable(r rune, t table) bool { - if r < t[0].first { - return false - } - - bot := 0 - top := len(t) - 1 - for top >= bot { - mid := (bot + top) >> 1 - - switch { - case t[mid].last < r: - bot = mid + 1 - case t[mid].first > r: - top = mid - 1 - default: - return true - } - } - - return false -} - -var private = table{ - {0x00E000, 0x00F8FF}, {0x0F0000, 0x0FFFFD}, {0x100000, 0x10FFFD}, -} - -var nonprint = table{ - {0x0000, 0x001F}, {0x007F, 0x009F}, {0x00AD, 0x00AD}, - {0x070F, 0x070F}, {0x180B, 0x180E}, {0x200B, 0x200F}, - {0x2028, 0x202E}, {0x206A, 0x206F}, {0xD800, 0xDFFF}, - {0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFB}, {0xFFFE, 0xFFFF}, -} - -// Condition have flag EastAsianWidth whether the current locale is CJK or not. -type Condition struct { - combinedLut []byte - EastAsianWidth bool - StrictEmojiNeutral bool -} - -// NewCondition return new instance of Condition which is current locale. -func NewCondition() *Condition { - return &Condition{ - EastAsianWidth: EastAsianWidth, - StrictEmojiNeutral: StrictEmojiNeutral, - } -} - -// RuneWidth returns the number of cells in r. -// See http://www.unicode.org/reports/tr11/ -func (c *Condition) RuneWidth(r rune) int { - if r < 0 || r > 0x10FFFF { - return 0 - } - if len(c.combinedLut) > 0 { - return int(c.combinedLut[r>>1]>>(uint(r&1)*4)) & 3 - } - // optimized version, verified by TestRuneWidthChecksums() - if !c.EastAsianWidth { - switch { - case r < 0x20: - return 0 - case (r >= 0x7F && r <= 0x9F) || r == 0xAD: // nonprint - return 0 - case r < 0x300: - return 1 - case inTable(r, narrow): - return 1 - case inTables(r, nonprint, combining): - return 0 - case inTable(r, doublewidth): - return 2 - default: - return 1 - } - } else { - switch { - case inTables(r, nonprint, combining): - return 0 - case inTable(r, narrow): - return 1 - case inTables(r, ambiguous, doublewidth): - return 2 - case !c.StrictEmojiNeutral && inTables(r, ambiguous, emoji, narrow): - return 2 - default: - return 1 - } - } -} - -// CreateLUT will create an in-memory lookup table of 557056 bytes for faster operation. -// This should not be called concurrently with other operations on c. -// If options in c is changed, CreateLUT should be called again. -func (c *Condition) CreateLUT() { - const max = 0x110000 - lut := c.combinedLut - if len(c.combinedLut) != 0 { - // Remove so we don't use it. - c.combinedLut = nil - } else { - lut = make([]byte, max/2) - } - for i := range lut { - i32 := int32(i * 2) - x0 := c.RuneWidth(i32) - x1 := c.RuneWidth(i32 + 1) - lut[i] = uint8(x0) | uint8(x1)<<4 - } - c.combinedLut = lut -} - -// StringWidth return width as you can see -func (c *Condition) StringWidth(s string) (width int) { - g := uniseg.NewGraphemes(s) - for g.Next() { - var chWidth int - for _, r := range g.Runes() { - chWidth = c.RuneWidth(r) - if chWidth > 0 { - break // Our best guess at this point is to use the width of the first non-zero-width rune. - } - } - width += chWidth - } - return -} - -// Truncate return string truncated with w cells -func (c *Condition) Truncate(s string, w int, tail string) string { - if c.StringWidth(s) <= w { - return s - } - w -= c.StringWidth(tail) - var width int - pos := len(s) - g := uniseg.NewGraphemes(s) - for g.Next() { - var chWidth int - for _, r := range g.Runes() { - chWidth = c.RuneWidth(r) - if chWidth > 0 { - break // See StringWidth() for details. - } - } - if width+chWidth > w { - pos, _ = g.Positions() - break - } - width += chWidth - } - return s[:pos] + tail -} - -// TruncateLeft cuts w cells from the beginning of the `s`. -func (c *Condition) TruncateLeft(s string, w int, prefix string) string { - if c.StringWidth(s) <= w { - return prefix - } - - var width int - pos := len(s) - - g := uniseg.NewGraphemes(s) - for g.Next() { - var chWidth int - for _, r := range g.Runes() { - chWidth = c.RuneWidth(r) - if chWidth > 0 { - break // See StringWidth() for details. - } - } - - if width+chWidth > w { - if width < w { - _, pos = g.Positions() - prefix += strings.Repeat(" ", width+chWidth-w) - } else { - pos, _ = g.Positions() - } - - break - } - - width += chWidth - } - - return prefix + s[pos:] -} - -// Wrap return string wrapped with w cells -func (c *Condition) Wrap(s string, w int) string { - width := 0 - out := "" - for _, r := range s { - cw := c.RuneWidth(r) - if r == '\n' { - out += string(r) - width = 0 - continue - } else if width+cw > w { - out += "\n" - width = 0 - out += string(r) - width += cw - continue - } - out += string(r) - width += cw - } - return out -} - -// FillLeft return string filled in left by spaces in w cells -func (c *Condition) FillLeft(s string, w int) string { - width := c.StringWidth(s) - count := w - width - if count > 0 { - b := make([]byte, count) - for i := range b { - b[i] = ' ' - } - return string(b) + s - } - return s -} - -// FillRight return string filled in left by spaces in w cells -func (c *Condition) FillRight(s string, w int) string { - width := c.StringWidth(s) - count := w - width - if count > 0 { - b := make([]byte, count) - for i := range b { - b[i] = ' ' - } - return s + string(b) - } - return s -} - -// RuneWidth returns the number of cells in r. -// See http://www.unicode.org/reports/tr11/ -func RuneWidth(r rune) int { - return DefaultCondition.RuneWidth(r) -} - -// IsAmbiguousWidth returns whether is ambiguous width or not. -func IsAmbiguousWidth(r rune) bool { - return inTables(r, private, ambiguous) -} - -// IsNeutralWidth returns whether is neutral width or not. -func IsNeutralWidth(r rune) bool { - return inTable(r, neutral) -} - -// StringWidth return width as you can see -func StringWidth(s string) (width int) { - return DefaultCondition.StringWidth(s) -} - -// Truncate return string truncated with w cells -func Truncate(s string, w int, tail string) string { - return DefaultCondition.Truncate(s, w, tail) -} - -// TruncateLeft cuts w cells from the beginning of the `s`. -func TruncateLeft(s string, w int, prefix string) string { - return DefaultCondition.TruncateLeft(s, w, prefix) -} - -// Wrap return string wrapped with w cells -func Wrap(s string, w int) string { - return DefaultCondition.Wrap(s, w) -} - -// FillLeft return string filled in left by spaces in w cells -func FillLeft(s string, w int) string { - return DefaultCondition.FillLeft(s, w) -} - -// FillRight return string filled in left by spaces in w cells -func FillRight(s string, w int) string { - return DefaultCondition.FillRight(s, w) -} - -// CreateLUT will create an in-memory lookup table of 557055 bytes for faster operation. -// This should not be called concurrently with other operations. -func CreateLUT() { - if len(DefaultCondition.combinedLut) > 0 { - return - } - DefaultCondition.CreateLUT() -} diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_appengine.go b/vendor/github.com/mattn/go-runewidth/runewidth_appengine.go deleted file mode 100644 index 84b6528dfe..0000000000 --- a/vendor/github.com/mattn/go-runewidth/runewidth_appengine.go +++ /dev/null @@ -1,9 +0,0 @@ -//go:build appengine -// +build appengine - -package runewidth - -// IsEastAsian return true if the current locale is CJK -func IsEastAsian() bool { - return false -} diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_js.go b/vendor/github.com/mattn/go-runewidth/runewidth_js.go deleted file mode 100644 index c2abbc2db3..0000000000 --- a/vendor/github.com/mattn/go-runewidth/runewidth_js.go +++ /dev/null @@ -1,9 +0,0 @@ -//go:build js && !appengine -// +build js,!appengine - -package runewidth - -func IsEastAsian() bool { - // TODO: Implement this for the web. Detect east asian in a compatible way, and return true. - return false -} diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_posix.go b/vendor/github.com/mattn/go-runewidth/runewidth_posix.go deleted file mode 100644 index 5a31d738ec..0000000000 --- a/vendor/github.com/mattn/go-runewidth/runewidth_posix.go +++ /dev/null @@ -1,81 +0,0 @@ -//go:build !windows && !js && !appengine -// +build !windows,!js,!appengine - -package runewidth - -import ( - "os" - "regexp" - "strings" -) - -var reLoc = regexp.MustCompile(`^[a-z][a-z][a-z]?(?:_[A-Z][A-Z])?\.(.+)`) - -var mblenTable = map[string]int{ - "utf-8": 6, - "utf8": 6, - "jis": 8, - "eucjp": 3, - "euckr": 2, - "euccn": 2, - "sjis": 2, - "cp932": 2, - "cp51932": 2, - "cp936": 2, - "cp949": 2, - "cp950": 2, - "big5": 2, - "gbk": 2, - "gb2312": 2, -} - -func isEastAsian(locale string) bool { - charset := strings.ToLower(locale) - r := reLoc.FindStringSubmatch(locale) - if len(r) == 2 { - charset = strings.ToLower(r[1]) - } - - if strings.HasSuffix(charset, "@cjk_narrow") { - return false - } - - for pos, b := range []byte(charset) { - if b == '@' { - charset = charset[:pos] - break - } - } - max := 1 - if m, ok := mblenTable[charset]; ok { - max = m - } - if max > 1 && (charset[0] != 'u' || - strings.HasPrefix(locale, "ja") || - strings.HasPrefix(locale, "ko") || - strings.HasPrefix(locale, "zh")) { - return true - } - return false -} - -// IsEastAsian return true if the current locale is CJK -func IsEastAsian() bool { - locale := os.Getenv("LC_ALL") - if locale == "" { - locale = os.Getenv("LC_CTYPE") - } - if locale == "" { - locale = os.Getenv("LANG") - } - - // ignore C locale - if locale == "POSIX" || locale == "C" { - return false - } - if len(locale) > 1 && locale[0] == 'C' && (locale[1] == '.' || locale[1] == '-') { - return false - } - - return isEastAsian(locale) -} diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_table.go b/vendor/github.com/mattn/go-runewidth/runewidth_table.go deleted file mode 100644 index ad025ad529..0000000000 --- a/vendor/github.com/mattn/go-runewidth/runewidth_table.go +++ /dev/null @@ -1,450 +0,0 @@ -// Code generated by script/generate.go. DO NOT EDIT. - -package runewidth - -var combining = table{ - {0x0300, 0x036F}, {0x0483, 0x0489}, {0x07EB, 0x07F3}, - {0x0C00, 0x0C00}, {0x0C04, 0x0C04}, {0x0CF3, 0x0CF3}, - {0x0D00, 0x0D01}, {0x135D, 0x135F}, {0x1A7F, 0x1A7F}, - {0x1AB0, 0x1ACE}, {0x1B6B, 0x1B73}, {0x1DC0, 0x1DFF}, - {0x20D0, 0x20F0}, {0x2CEF, 0x2CF1}, {0x2DE0, 0x2DFF}, - {0x3099, 0x309A}, {0xA66F, 0xA672}, {0xA674, 0xA67D}, - {0xA69E, 0xA69F}, {0xA6F0, 0xA6F1}, {0xA8E0, 0xA8F1}, - {0xFE20, 0xFE2F}, {0x101FD, 0x101FD}, {0x10376, 0x1037A}, - {0x10EAB, 0x10EAC}, {0x10F46, 0x10F50}, {0x10F82, 0x10F85}, - {0x11300, 0x11301}, {0x1133B, 0x1133C}, {0x11366, 0x1136C}, - {0x11370, 0x11374}, {0x16AF0, 0x16AF4}, {0x1CF00, 0x1CF2D}, - {0x1CF30, 0x1CF46}, {0x1D165, 0x1D169}, {0x1D16D, 0x1D172}, - {0x1D17B, 0x1D182}, {0x1D185, 0x1D18B}, {0x1D1AA, 0x1D1AD}, - {0x1D242, 0x1D244}, {0x1E000, 0x1E006}, {0x1E008, 0x1E018}, - {0x1E01B, 0x1E021}, {0x1E023, 0x1E024}, {0x1E026, 0x1E02A}, - {0x1E08F, 0x1E08F}, {0x1E8D0, 0x1E8D6}, -} - -var doublewidth = table{ - {0x1100, 0x115F}, {0x231A, 0x231B}, {0x2329, 0x232A}, - {0x23E9, 0x23EC}, {0x23F0, 0x23F0}, {0x23F3, 0x23F3}, - {0x25FD, 0x25FE}, {0x2614, 0x2615}, {0x2648, 0x2653}, - {0x267F, 0x267F}, {0x2693, 0x2693}, {0x26A1, 0x26A1}, - {0x26AA, 0x26AB}, {0x26BD, 0x26BE}, {0x26C4, 0x26C5}, - {0x26CE, 0x26CE}, {0x26D4, 0x26D4}, {0x26EA, 0x26EA}, - {0x26F2, 0x26F3}, {0x26F5, 0x26F5}, {0x26FA, 0x26FA}, - {0x26FD, 0x26FD}, {0x2705, 0x2705}, {0x270A, 0x270B}, - {0x2728, 0x2728}, {0x274C, 0x274C}, {0x274E, 0x274E}, - {0x2753, 0x2755}, {0x2757, 0x2757}, {0x2795, 0x2797}, - {0x27B0, 0x27B0}, {0x27BF, 0x27BF}, {0x2B1B, 0x2B1C}, - {0x2B50, 0x2B50}, {0x2B55, 0x2B55}, {0x2E80, 0x2E99}, - {0x2E9B, 0x2EF3}, {0x2F00, 0x2FD5}, {0x2FF0, 0x303E}, - {0x3041, 0x3096}, {0x3099, 0x30FF}, {0x3105, 0x312F}, - {0x3131, 0x318E}, {0x3190, 0x31E3}, {0x31EF, 0x321E}, - {0x3220, 0x3247}, {0x3250, 0x4DBF}, {0x4E00, 0xA48C}, - {0xA490, 0xA4C6}, {0xA960, 0xA97C}, {0xAC00, 0xD7A3}, - {0xF900, 0xFAFF}, {0xFE10, 0xFE19}, {0xFE30, 0xFE52}, - {0xFE54, 0xFE66}, {0xFE68, 0xFE6B}, {0xFF01, 0xFF60}, - {0xFFE0, 0xFFE6}, {0x16FE0, 0x16FE4}, {0x16FF0, 0x16FF1}, - {0x17000, 0x187F7}, {0x18800, 0x18CD5}, {0x18D00, 0x18D08}, - {0x1AFF0, 0x1AFF3}, {0x1AFF5, 0x1AFFB}, {0x1AFFD, 0x1AFFE}, - {0x1B000, 0x1B122}, {0x1B132, 0x1B132}, {0x1B150, 0x1B152}, - {0x1B155, 0x1B155}, {0x1B164, 0x1B167}, {0x1B170, 0x1B2FB}, - {0x1F004, 0x1F004}, {0x1F0CF, 0x1F0CF}, {0x1F18E, 0x1F18E}, - {0x1F191, 0x1F19A}, {0x1F200, 0x1F202}, {0x1F210, 0x1F23B}, - {0x1F240, 0x1F248}, {0x1F250, 0x1F251}, {0x1F260, 0x1F265}, - {0x1F300, 0x1F320}, {0x1F32D, 0x1F335}, {0x1F337, 0x1F37C}, - {0x1F37E, 0x1F393}, {0x1F3A0, 0x1F3CA}, {0x1F3CF, 0x1F3D3}, - {0x1F3E0, 0x1F3F0}, {0x1F3F4, 0x1F3F4}, {0x1F3F8, 0x1F43E}, - {0x1F440, 0x1F440}, {0x1F442, 0x1F4FC}, {0x1F4FF, 0x1F53D}, - {0x1F54B, 0x1F54E}, {0x1F550, 0x1F567}, {0x1F57A, 0x1F57A}, - {0x1F595, 0x1F596}, {0x1F5A4, 0x1F5A4}, {0x1F5FB, 0x1F64F}, - {0x1F680, 0x1F6C5}, {0x1F6CC, 0x1F6CC}, {0x1F6D0, 0x1F6D2}, - {0x1F6D5, 0x1F6D7}, {0x1F6DC, 0x1F6DF}, {0x1F6EB, 0x1F6EC}, - {0x1F6F4, 0x1F6FC}, {0x1F7E0, 0x1F7EB}, {0x1F7F0, 0x1F7F0}, - {0x1F90C, 0x1F93A}, {0x1F93C, 0x1F945}, {0x1F947, 0x1F9FF}, - {0x1FA70, 0x1FA7C}, {0x1FA80, 0x1FA88}, {0x1FA90, 0x1FABD}, - {0x1FABF, 0x1FAC5}, {0x1FACE, 0x1FADB}, {0x1FAE0, 0x1FAE8}, - {0x1FAF0, 0x1FAF8}, {0x20000, 0x2FFFD}, {0x30000, 0x3FFFD}, -} - -var ambiguous = table{ - {0x00A1, 0x00A1}, {0x00A4, 0x00A4}, {0x00A7, 0x00A8}, - {0x00AA, 0x00AA}, {0x00AD, 0x00AE}, {0x00B0, 0x00B4}, - {0x00B6, 0x00BA}, {0x00BC, 0x00BF}, {0x00C6, 0x00C6}, - {0x00D0, 0x00D0}, {0x00D7, 0x00D8}, {0x00DE, 0x00E1}, - {0x00E6, 0x00E6}, {0x00E8, 0x00EA}, {0x00EC, 0x00ED}, - {0x00F0, 0x00F0}, {0x00F2, 0x00F3}, {0x00F7, 0x00FA}, - {0x00FC, 0x00FC}, {0x00FE, 0x00FE}, {0x0101, 0x0101}, - {0x0111, 0x0111}, {0x0113, 0x0113}, {0x011B, 0x011B}, - {0x0126, 0x0127}, {0x012B, 0x012B}, {0x0131, 0x0133}, - {0x0138, 0x0138}, {0x013F, 0x0142}, {0x0144, 0x0144}, - {0x0148, 0x014B}, {0x014D, 0x014D}, {0x0152, 0x0153}, - {0x0166, 0x0167}, {0x016B, 0x016B}, {0x01CE, 0x01CE}, - {0x01D0, 0x01D0}, {0x01D2, 0x01D2}, {0x01D4, 0x01D4}, - {0x01D6, 0x01D6}, {0x01D8, 0x01D8}, {0x01DA, 0x01DA}, - {0x01DC, 0x01DC}, {0x0251, 0x0251}, {0x0261, 0x0261}, - {0x02C4, 0x02C4}, {0x02C7, 0x02C7}, {0x02C9, 0x02CB}, - {0x02CD, 0x02CD}, {0x02D0, 0x02D0}, {0x02D8, 0x02DB}, - {0x02DD, 0x02DD}, {0x02DF, 0x02DF}, {0x0300, 0x036F}, - {0x0391, 0x03A1}, {0x03A3, 0x03A9}, {0x03B1, 0x03C1}, - {0x03C3, 0x03C9}, {0x0401, 0x0401}, {0x0410, 0x044F}, - {0x0451, 0x0451}, {0x2010, 0x2010}, {0x2013, 0x2016}, - {0x2018, 0x2019}, {0x201C, 0x201D}, {0x2020, 0x2022}, - {0x2024, 0x2027}, {0x2030, 0x2030}, {0x2032, 0x2033}, - {0x2035, 0x2035}, {0x203B, 0x203B}, {0x203E, 0x203E}, - {0x2074, 0x2074}, {0x207F, 0x207F}, {0x2081, 0x2084}, - {0x20AC, 0x20AC}, {0x2103, 0x2103}, {0x2105, 0x2105}, - {0x2109, 0x2109}, {0x2113, 0x2113}, {0x2116, 0x2116}, - {0x2121, 0x2122}, {0x2126, 0x2126}, {0x212B, 0x212B}, - {0x2153, 0x2154}, {0x215B, 0x215E}, {0x2160, 0x216B}, - {0x2170, 0x2179}, {0x2189, 0x2189}, {0x2190, 0x2199}, - {0x21B8, 0x21B9}, {0x21D2, 0x21D2}, {0x21D4, 0x21D4}, - {0x21E7, 0x21E7}, {0x2200, 0x2200}, {0x2202, 0x2203}, - {0x2207, 0x2208}, {0x220B, 0x220B}, {0x220F, 0x220F}, - {0x2211, 0x2211}, {0x2215, 0x2215}, {0x221A, 0x221A}, - {0x221D, 0x2220}, {0x2223, 0x2223}, {0x2225, 0x2225}, - {0x2227, 0x222C}, {0x222E, 0x222E}, {0x2234, 0x2237}, - {0x223C, 0x223D}, {0x2248, 0x2248}, {0x224C, 0x224C}, - {0x2252, 0x2252}, {0x2260, 0x2261}, {0x2264, 0x2267}, - {0x226A, 0x226B}, {0x226E, 0x226F}, {0x2282, 0x2283}, - {0x2286, 0x2287}, {0x2295, 0x2295}, {0x2299, 0x2299}, - {0x22A5, 0x22A5}, {0x22BF, 0x22BF}, {0x2312, 0x2312}, - {0x2460, 0x24E9}, {0x24EB, 0x254B}, {0x2550, 0x2573}, - {0x2580, 0x258F}, {0x2592, 0x2595}, {0x25A0, 0x25A1}, - {0x25A3, 0x25A9}, {0x25B2, 0x25B3}, {0x25B6, 0x25B7}, - {0x25BC, 0x25BD}, {0x25C0, 0x25C1}, {0x25C6, 0x25C8}, - {0x25CB, 0x25CB}, {0x25CE, 0x25D1}, {0x25E2, 0x25E5}, - {0x25EF, 0x25EF}, {0x2605, 0x2606}, {0x2609, 0x2609}, - {0x260E, 0x260F}, {0x261C, 0x261C}, {0x261E, 0x261E}, - {0x2640, 0x2640}, {0x2642, 0x2642}, {0x2660, 0x2661}, - {0x2663, 0x2665}, {0x2667, 0x266A}, {0x266C, 0x266D}, - {0x266F, 0x266F}, {0x269E, 0x269F}, {0x26BF, 0x26BF}, - {0x26C6, 0x26CD}, {0x26CF, 0x26D3}, {0x26D5, 0x26E1}, - {0x26E3, 0x26E3}, {0x26E8, 0x26E9}, {0x26EB, 0x26F1}, - {0x26F4, 0x26F4}, {0x26F6, 0x26F9}, {0x26FB, 0x26FC}, - {0x26FE, 0x26FF}, {0x273D, 0x273D}, {0x2776, 0x277F}, - {0x2B56, 0x2B59}, {0x3248, 0x324F}, {0xE000, 0xF8FF}, - {0xFE00, 0xFE0F}, {0xFFFD, 0xFFFD}, {0x1F100, 0x1F10A}, - {0x1F110, 0x1F12D}, {0x1F130, 0x1F169}, {0x1F170, 0x1F18D}, - {0x1F18F, 0x1F190}, {0x1F19B, 0x1F1AC}, {0xE0100, 0xE01EF}, - {0xF0000, 0xFFFFD}, {0x100000, 0x10FFFD}, -} -var narrow = table{ - {0x0020, 0x007E}, {0x00A2, 0x00A3}, {0x00A5, 0x00A6}, - {0x00AC, 0x00AC}, {0x00AF, 0x00AF}, {0x27E6, 0x27ED}, - {0x2985, 0x2986}, -} - -var neutral = table{ - {0x0000, 0x001F}, {0x007F, 0x00A0}, {0x00A9, 0x00A9}, - {0x00AB, 0x00AB}, {0x00B5, 0x00B5}, {0x00BB, 0x00BB}, - {0x00C0, 0x00C5}, {0x00C7, 0x00CF}, {0x00D1, 0x00D6}, - {0x00D9, 0x00DD}, {0x00E2, 0x00E5}, {0x00E7, 0x00E7}, - {0x00EB, 0x00EB}, {0x00EE, 0x00EF}, {0x00F1, 0x00F1}, - {0x00F4, 0x00F6}, {0x00FB, 0x00FB}, {0x00FD, 0x00FD}, - {0x00FF, 0x0100}, {0x0102, 0x0110}, {0x0112, 0x0112}, - {0x0114, 0x011A}, {0x011C, 0x0125}, {0x0128, 0x012A}, - {0x012C, 0x0130}, {0x0134, 0x0137}, {0x0139, 0x013E}, - {0x0143, 0x0143}, {0x0145, 0x0147}, {0x014C, 0x014C}, - {0x014E, 0x0151}, {0x0154, 0x0165}, {0x0168, 0x016A}, - {0x016C, 0x01CD}, {0x01CF, 0x01CF}, {0x01D1, 0x01D1}, - {0x01D3, 0x01D3}, {0x01D5, 0x01D5}, {0x01D7, 0x01D7}, - {0x01D9, 0x01D9}, {0x01DB, 0x01DB}, {0x01DD, 0x0250}, - {0x0252, 0x0260}, {0x0262, 0x02C3}, {0x02C5, 0x02C6}, - {0x02C8, 0x02C8}, {0x02CC, 0x02CC}, {0x02CE, 0x02CF}, - {0x02D1, 0x02D7}, {0x02DC, 0x02DC}, {0x02DE, 0x02DE}, - {0x02E0, 0x02FF}, {0x0370, 0x0377}, {0x037A, 0x037F}, - {0x0384, 0x038A}, {0x038C, 0x038C}, {0x038E, 0x0390}, - {0x03AA, 0x03B0}, {0x03C2, 0x03C2}, {0x03CA, 0x0400}, - {0x0402, 0x040F}, {0x0450, 0x0450}, {0x0452, 0x052F}, - {0x0531, 0x0556}, {0x0559, 0x058A}, {0x058D, 0x058F}, - {0x0591, 0x05C7}, {0x05D0, 0x05EA}, {0x05EF, 0x05F4}, - {0x0600, 0x070D}, {0x070F, 0x074A}, {0x074D, 0x07B1}, - {0x07C0, 0x07FA}, {0x07FD, 0x082D}, {0x0830, 0x083E}, - {0x0840, 0x085B}, {0x085E, 0x085E}, {0x0860, 0x086A}, - {0x0870, 0x088E}, {0x0890, 0x0891}, {0x0898, 0x0983}, - {0x0985, 0x098C}, {0x098F, 0x0990}, {0x0993, 0x09A8}, - {0x09AA, 0x09B0}, {0x09B2, 0x09B2}, {0x09B6, 0x09B9}, - {0x09BC, 0x09C4}, {0x09C7, 0x09C8}, {0x09CB, 0x09CE}, - {0x09D7, 0x09D7}, {0x09DC, 0x09DD}, {0x09DF, 0x09E3}, - {0x09E6, 0x09FE}, {0x0A01, 0x0A03}, {0x0A05, 0x0A0A}, - {0x0A0F, 0x0A10}, {0x0A13, 0x0A28}, {0x0A2A, 0x0A30}, - {0x0A32, 0x0A33}, {0x0A35, 0x0A36}, {0x0A38, 0x0A39}, - {0x0A3C, 0x0A3C}, {0x0A3E, 0x0A42}, {0x0A47, 0x0A48}, - {0x0A4B, 0x0A4D}, {0x0A51, 0x0A51}, {0x0A59, 0x0A5C}, - {0x0A5E, 0x0A5E}, {0x0A66, 0x0A76}, {0x0A81, 0x0A83}, - {0x0A85, 0x0A8D}, {0x0A8F, 0x0A91}, {0x0A93, 0x0AA8}, - {0x0AAA, 0x0AB0}, {0x0AB2, 0x0AB3}, {0x0AB5, 0x0AB9}, - {0x0ABC, 0x0AC5}, {0x0AC7, 0x0AC9}, {0x0ACB, 0x0ACD}, - {0x0AD0, 0x0AD0}, {0x0AE0, 0x0AE3}, {0x0AE6, 0x0AF1}, - {0x0AF9, 0x0AFF}, {0x0B01, 0x0B03}, {0x0B05, 0x0B0C}, - {0x0B0F, 0x0B10}, {0x0B13, 0x0B28}, {0x0B2A, 0x0B30}, - {0x0B32, 0x0B33}, {0x0B35, 0x0B39}, {0x0B3C, 0x0B44}, - {0x0B47, 0x0B48}, {0x0B4B, 0x0B4D}, {0x0B55, 0x0B57}, - {0x0B5C, 0x0B5D}, {0x0B5F, 0x0B63}, {0x0B66, 0x0B77}, - {0x0B82, 0x0B83}, {0x0B85, 0x0B8A}, {0x0B8E, 0x0B90}, - {0x0B92, 0x0B95}, {0x0B99, 0x0B9A}, {0x0B9C, 0x0B9C}, - {0x0B9E, 0x0B9F}, {0x0BA3, 0x0BA4}, {0x0BA8, 0x0BAA}, - {0x0BAE, 0x0BB9}, {0x0BBE, 0x0BC2}, {0x0BC6, 0x0BC8}, - {0x0BCA, 0x0BCD}, {0x0BD0, 0x0BD0}, {0x0BD7, 0x0BD7}, - {0x0BE6, 0x0BFA}, {0x0C00, 0x0C0C}, {0x0C0E, 0x0C10}, - {0x0C12, 0x0C28}, {0x0C2A, 0x0C39}, {0x0C3C, 0x0C44}, - {0x0C46, 0x0C48}, {0x0C4A, 0x0C4D}, {0x0C55, 0x0C56}, - {0x0C58, 0x0C5A}, {0x0C5D, 0x0C5D}, {0x0C60, 0x0C63}, - {0x0C66, 0x0C6F}, {0x0C77, 0x0C8C}, {0x0C8E, 0x0C90}, - {0x0C92, 0x0CA8}, {0x0CAA, 0x0CB3}, {0x0CB5, 0x0CB9}, - {0x0CBC, 0x0CC4}, {0x0CC6, 0x0CC8}, {0x0CCA, 0x0CCD}, - {0x0CD5, 0x0CD6}, {0x0CDD, 0x0CDE}, {0x0CE0, 0x0CE3}, - {0x0CE6, 0x0CEF}, {0x0CF1, 0x0CF3}, {0x0D00, 0x0D0C}, - {0x0D0E, 0x0D10}, {0x0D12, 0x0D44}, {0x0D46, 0x0D48}, - {0x0D4A, 0x0D4F}, {0x0D54, 0x0D63}, {0x0D66, 0x0D7F}, - {0x0D81, 0x0D83}, {0x0D85, 0x0D96}, {0x0D9A, 0x0DB1}, - {0x0DB3, 0x0DBB}, {0x0DBD, 0x0DBD}, {0x0DC0, 0x0DC6}, - {0x0DCA, 0x0DCA}, {0x0DCF, 0x0DD4}, {0x0DD6, 0x0DD6}, - {0x0DD8, 0x0DDF}, {0x0DE6, 0x0DEF}, {0x0DF2, 0x0DF4}, - {0x0E01, 0x0E3A}, {0x0E3F, 0x0E5B}, {0x0E81, 0x0E82}, - {0x0E84, 0x0E84}, {0x0E86, 0x0E8A}, {0x0E8C, 0x0EA3}, - {0x0EA5, 0x0EA5}, {0x0EA7, 0x0EBD}, {0x0EC0, 0x0EC4}, - {0x0EC6, 0x0EC6}, {0x0EC8, 0x0ECE}, {0x0ED0, 0x0ED9}, - {0x0EDC, 0x0EDF}, {0x0F00, 0x0F47}, {0x0F49, 0x0F6C}, - {0x0F71, 0x0F97}, {0x0F99, 0x0FBC}, {0x0FBE, 0x0FCC}, - {0x0FCE, 0x0FDA}, {0x1000, 0x10C5}, {0x10C7, 0x10C7}, - {0x10CD, 0x10CD}, {0x10D0, 0x10FF}, {0x1160, 0x1248}, - {0x124A, 0x124D}, {0x1250, 0x1256}, {0x1258, 0x1258}, - {0x125A, 0x125D}, {0x1260, 0x1288}, {0x128A, 0x128D}, - {0x1290, 0x12B0}, {0x12B2, 0x12B5}, {0x12B8, 0x12BE}, - {0x12C0, 0x12C0}, {0x12C2, 0x12C5}, {0x12C8, 0x12D6}, - {0x12D8, 0x1310}, {0x1312, 0x1315}, {0x1318, 0x135A}, - {0x135D, 0x137C}, {0x1380, 0x1399}, {0x13A0, 0x13F5}, - {0x13F8, 0x13FD}, {0x1400, 0x169C}, {0x16A0, 0x16F8}, - {0x1700, 0x1715}, {0x171F, 0x1736}, {0x1740, 0x1753}, - {0x1760, 0x176C}, {0x176E, 0x1770}, {0x1772, 0x1773}, - {0x1780, 0x17DD}, {0x17E0, 0x17E9}, {0x17F0, 0x17F9}, - {0x1800, 0x1819}, {0x1820, 0x1878}, {0x1880, 0x18AA}, - {0x18B0, 0x18F5}, {0x1900, 0x191E}, {0x1920, 0x192B}, - {0x1930, 0x193B}, {0x1940, 0x1940}, {0x1944, 0x196D}, - {0x1970, 0x1974}, {0x1980, 0x19AB}, {0x19B0, 0x19C9}, - {0x19D0, 0x19DA}, {0x19DE, 0x1A1B}, {0x1A1E, 0x1A5E}, - {0x1A60, 0x1A7C}, {0x1A7F, 0x1A89}, {0x1A90, 0x1A99}, - {0x1AA0, 0x1AAD}, {0x1AB0, 0x1ACE}, {0x1B00, 0x1B4C}, - {0x1B50, 0x1B7E}, {0x1B80, 0x1BF3}, {0x1BFC, 0x1C37}, - {0x1C3B, 0x1C49}, {0x1C4D, 0x1C88}, {0x1C90, 0x1CBA}, - {0x1CBD, 0x1CC7}, {0x1CD0, 0x1CFA}, {0x1D00, 0x1F15}, - {0x1F18, 0x1F1D}, {0x1F20, 0x1F45}, {0x1F48, 0x1F4D}, - {0x1F50, 0x1F57}, {0x1F59, 0x1F59}, {0x1F5B, 0x1F5B}, - {0x1F5D, 0x1F5D}, {0x1F5F, 0x1F7D}, {0x1F80, 0x1FB4}, - {0x1FB6, 0x1FC4}, {0x1FC6, 0x1FD3}, {0x1FD6, 0x1FDB}, - {0x1FDD, 0x1FEF}, {0x1FF2, 0x1FF4}, {0x1FF6, 0x1FFE}, - {0x2000, 0x200F}, {0x2011, 0x2012}, {0x2017, 0x2017}, - {0x201A, 0x201B}, {0x201E, 0x201F}, {0x2023, 0x2023}, - {0x2028, 0x202F}, {0x2031, 0x2031}, {0x2034, 0x2034}, - {0x2036, 0x203A}, {0x203C, 0x203D}, {0x203F, 0x2064}, - {0x2066, 0x2071}, {0x2075, 0x207E}, {0x2080, 0x2080}, - {0x2085, 0x208E}, {0x2090, 0x209C}, {0x20A0, 0x20A8}, - {0x20AA, 0x20AB}, {0x20AD, 0x20C0}, {0x20D0, 0x20F0}, - {0x2100, 0x2102}, {0x2104, 0x2104}, {0x2106, 0x2108}, - {0x210A, 0x2112}, {0x2114, 0x2115}, {0x2117, 0x2120}, - {0x2123, 0x2125}, {0x2127, 0x212A}, {0x212C, 0x2152}, - {0x2155, 0x215A}, {0x215F, 0x215F}, {0x216C, 0x216F}, - {0x217A, 0x2188}, {0x218A, 0x218B}, {0x219A, 0x21B7}, - {0x21BA, 0x21D1}, {0x21D3, 0x21D3}, {0x21D5, 0x21E6}, - {0x21E8, 0x21FF}, {0x2201, 0x2201}, {0x2204, 0x2206}, - {0x2209, 0x220A}, {0x220C, 0x220E}, {0x2210, 0x2210}, - {0x2212, 0x2214}, {0x2216, 0x2219}, {0x221B, 0x221C}, - {0x2221, 0x2222}, {0x2224, 0x2224}, {0x2226, 0x2226}, - {0x222D, 0x222D}, {0x222F, 0x2233}, {0x2238, 0x223B}, - {0x223E, 0x2247}, {0x2249, 0x224B}, {0x224D, 0x2251}, - {0x2253, 0x225F}, {0x2262, 0x2263}, {0x2268, 0x2269}, - {0x226C, 0x226D}, {0x2270, 0x2281}, {0x2284, 0x2285}, - {0x2288, 0x2294}, {0x2296, 0x2298}, {0x229A, 0x22A4}, - {0x22A6, 0x22BE}, {0x22C0, 0x2311}, {0x2313, 0x2319}, - {0x231C, 0x2328}, {0x232B, 0x23E8}, {0x23ED, 0x23EF}, - {0x23F1, 0x23F2}, {0x23F4, 0x2426}, {0x2440, 0x244A}, - {0x24EA, 0x24EA}, {0x254C, 0x254F}, {0x2574, 0x257F}, - {0x2590, 0x2591}, {0x2596, 0x259F}, {0x25A2, 0x25A2}, - {0x25AA, 0x25B1}, {0x25B4, 0x25B5}, {0x25B8, 0x25BB}, - {0x25BE, 0x25BF}, {0x25C2, 0x25C5}, {0x25C9, 0x25CA}, - {0x25CC, 0x25CD}, {0x25D2, 0x25E1}, {0x25E6, 0x25EE}, - {0x25F0, 0x25FC}, {0x25FF, 0x2604}, {0x2607, 0x2608}, - {0x260A, 0x260D}, {0x2610, 0x2613}, {0x2616, 0x261B}, - {0x261D, 0x261D}, {0x261F, 0x263F}, {0x2641, 0x2641}, - {0x2643, 0x2647}, {0x2654, 0x265F}, {0x2662, 0x2662}, - {0x2666, 0x2666}, {0x266B, 0x266B}, {0x266E, 0x266E}, - {0x2670, 0x267E}, {0x2680, 0x2692}, {0x2694, 0x269D}, - {0x26A0, 0x26A0}, {0x26A2, 0x26A9}, {0x26AC, 0x26BC}, - {0x26C0, 0x26C3}, {0x26E2, 0x26E2}, {0x26E4, 0x26E7}, - {0x2700, 0x2704}, {0x2706, 0x2709}, {0x270C, 0x2727}, - {0x2729, 0x273C}, {0x273E, 0x274B}, {0x274D, 0x274D}, - {0x274F, 0x2752}, {0x2756, 0x2756}, {0x2758, 0x2775}, - {0x2780, 0x2794}, {0x2798, 0x27AF}, {0x27B1, 0x27BE}, - {0x27C0, 0x27E5}, {0x27EE, 0x2984}, {0x2987, 0x2B1A}, - {0x2B1D, 0x2B4F}, {0x2B51, 0x2B54}, {0x2B5A, 0x2B73}, - {0x2B76, 0x2B95}, {0x2B97, 0x2CF3}, {0x2CF9, 0x2D25}, - {0x2D27, 0x2D27}, {0x2D2D, 0x2D2D}, {0x2D30, 0x2D67}, - {0x2D6F, 0x2D70}, {0x2D7F, 0x2D96}, {0x2DA0, 0x2DA6}, - {0x2DA8, 0x2DAE}, {0x2DB0, 0x2DB6}, {0x2DB8, 0x2DBE}, - {0x2DC0, 0x2DC6}, {0x2DC8, 0x2DCE}, {0x2DD0, 0x2DD6}, - {0x2DD8, 0x2DDE}, {0x2DE0, 0x2E5D}, {0x303F, 0x303F}, - {0x4DC0, 0x4DFF}, {0xA4D0, 0xA62B}, {0xA640, 0xA6F7}, - {0xA700, 0xA7CA}, {0xA7D0, 0xA7D1}, {0xA7D3, 0xA7D3}, - {0xA7D5, 0xA7D9}, {0xA7F2, 0xA82C}, {0xA830, 0xA839}, - {0xA840, 0xA877}, {0xA880, 0xA8C5}, {0xA8CE, 0xA8D9}, - {0xA8E0, 0xA953}, {0xA95F, 0xA95F}, {0xA980, 0xA9CD}, - {0xA9CF, 0xA9D9}, {0xA9DE, 0xA9FE}, {0xAA00, 0xAA36}, - {0xAA40, 0xAA4D}, {0xAA50, 0xAA59}, {0xAA5C, 0xAAC2}, - {0xAADB, 0xAAF6}, {0xAB01, 0xAB06}, {0xAB09, 0xAB0E}, - {0xAB11, 0xAB16}, {0xAB20, 0xAB26}, {0xAB28, 0xAB2E}, - {0xAB30, 0xAB6B}, {0xAB70, 0xABED}, {0xABF0, 0xABF9}, - {0xD7B0, 0xD7C6}, {0xD7CB, 0xD7FB}, {0xD800, 0xDFFF}, - {0xFB00, 0xFB06}, {0xFB13, 0xFB17}, {0xFB1D, 0xFB36}, - {0xFB38, 0xFB3C}, {0xFB3E, 0xFB3E}, {0xFB40, 0xFB41}, - {0xFB43, 0xFB44}, {0xFB46, 0xFBC2}, {0xFBD3, 0xFD8F}, - {0xFD92, 0xFDC7}, {0xFDCF, 0xFDCF}, {0xFDF0, 0xFDFF}, - {0xFE20, 0xFE2F}, {0xFE70, 0xFE74}, {0xFE76, 0xFEFC}, - {0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFC}, {0x10000, 0x1000B}, - {0x1000D, 0x10026}, {0x10028, 0x1003A}, {0x1003C, 0x1003D}, - {0x1003F, 0x1004D}, {0x10050, 0x1005D}, {0x10080, 0x100FA}, - {0x10100, 0x10102}, {0x10107, 0x10133}, {0x10137, 0x1018E}, - {0x10190, 0x1019C}, {0x101A0, 0x101A0}, {0x101D0, 0x101FD}, - {0x10280, 0x1029C}, {0x102A0, 0x102D0}, {0x102E0, 0x102FB}, - {0x10300, 0x10323}, {0x1032D, 0x1034A}, {0x10350, 0x1037A}, - {0x10380, 0x1039D}, {0x1039F, 0x103C3}, {0x103C8, 0x103D5}, - {0x10400, 0x1049D}, {0x104A0, 0x104A9}, {0x104B0, 0x104D3}, - {0x104D8, 0x104FB}, {0x10500, 0x10527}, {0x10530, 0x10563}, - {0x1056F, 0x1057A}, {0x1057C, 0x1058A}, {0x1058C, 0x10592}, - {0x10594, 0x10595}, {0x10597, 0x105A1}, {0x105A3, 0x105B1}, - {0x105B3, 0x105B9}, {0x105BB, 0x105BC}, {0x10600, 0x10736}, - {0x10740, 0x10755}, {0x10760, 0x10767}, {0x10780, 0x10785}, - {0x10787, 0x107B0}, {0x107B2, 0x107BA}, {0x10800, 0x10805}, - {0x10808, 0x10808}, {0x1080A, 0x10835}, {0x10837, 0x10838}, - {0x1083C, 0x1083C}, {0x1083F, 0x10855}, {0x10857, 0x1089E}, - {0x108A7, 0x108AF}, {0x108E0, 0x108F2}, {0x108F4, 0x108F5}, - {0x108FB, 0x1091B}, {0x1091F, 0x10939}, {0x1093F, 0x1093F}, - {0x10980, 0x109B7}, {0x109BC, 0x109CF}, {0x109D2, 0x10A03}, - {0x10A05, 0x10A06}, {0x10A0C, 0x10A13}, {0x10A15, 0x10A17}, - {0x10A19, 0x10A35}, {0x10A38, 0x10A3A}, {0x10A3F, 0x10A48}, - {0x10A50, 0x10A58}, {0x10A60, 0x10A9F}, {0x10AC0, 0x10AE6}, - {0x10AEB, 0x10AF6}, {0x10B00, 0x10B35}, {0x10B39, 0x10B55}, - {0x10B58, 0x10B72}, {0x10B78, 0x10B91}, {0x10B99, 0x10B9C}, - {0x10BA9, 0x10BAF}, {0x10C00, 0x10C48}, {0x10C80, 0x10CB2}, - {0x10CC0, 0x10CF2}, {0x10CFA, 0x10D27}, {0x10D30, 0x10D39}, - {0x10E60, 0x10E7E}, {0x10E80, 0x10EA9}, {0x10EAB, 0x10EAD}, - {0x10EB0, 0x10EB1}, {0x10EFD, 0x10F27}, {0x10F30, 0x10F59}, - {0x10F70, 0x10F89}, {0x10FB0, 0x10FCB}, {0x10FE0, 0x10FF6}, - {0x11000, 0x1104D}, {0x11052, 0x11075}, {0x1107F, 0x110C2}, - {0x110CD, 0x110CD}, {0x110D0, 0x110E8}, {0x110F0, 0x110F9}, - {0x11100, 0x11134}, {0x11136, 0x11147}, {0x11150, 0x11176}, - {0x11180, 0x111DF}, {0x111E1, 0x111F4}, {0x11200, 0x11211}, - {0x11213, 0x11241}, {0x11280, 0x11286}, {0x11288, 0x11288}, - {0x1128A, 0x1128D}, {0x1128F, 0x1129D}, {0x1129F, 0x112A9}, - {0x112B0, 0x112EA}, {0x112F0, 0x112F9}, {0x11300, 0x11303}, - {0x11305, 0x1130C}, {0x1130F, 0x11310}, {0x11313, 0x11328}, - {0x1132A, 0x11330}, {0x11332, 0x11333}, {0x11335, 0x11339}, - {0x1133B, 0x11344}, {0x11347, 0x11348}, {0x1134B, 0x1134D}, - {0x11350, 0x11350}, {0x11357, 0x11357}, {0x1135D, 0x11363}, - {0x11366, 0x1136C}, {0x11370, 0x11374}, {0x11400, 0x1145B}, - {0x1145D, 0x11461}, {0x11480, 0x114C7}, {0x114D0, 0x114D9}, - {0x11580, 0x115B5}, {0x115B8, 0x115DD}, {0x11600, 0x11644}, - {0x11650, 0x11659}, {0x11660, 0x1166C}, {0x11680, 0x116B9}, - {0x116C0, 0x116C9}, {0x11700, 0x1171A}, {0x1171D, 0x1172B}, - {0x11730, 0x11746}, {0x11800, 0x1183B}, {0x118A0, 0x118F2}, - {0x118FF, 0x11906}, {0x11909, 0x11909}, {0x1190C, 0x11913}, - {0x11915, 0x11916}, {0x11918, 0x11935}, {0x11937, 0x11938}, - {0x1193B, 0x11946}, {0x11950, 0x11959}, {0x119A0, 0x119A7}, - {0x119AA, 0x119D7}, {0x119DA, 0x119E4}, {0x11A00, 0x11A47}, - {0x11A50, 0x11AA2}, {0x11AB0, 0x11AF8}, {0x11B00, 0x11B09}, - {0x11C00, 0x11C08}, {0x11C0A, 0x11C36}, {0x11C38, 0x11C45}, - {0x11C50, 0x11C6C}, {0x11C70, 0x11C8F}, {0x11C92, 0x11CA7}, - {0x11CA9, 0x11CB6}, {0x11D00, 0x11D06}, {0x11D08, 0x11D09}, - {0x11D0B, 0x11D36}, {0x11D3A, 0x11D3A}, {0x11D3C, 0x11D3D}, - {0x11D3F, 0x11D47}, {0x11D50, 0x11D59}, {0x11D60, 0x11D65}, - {0x11D67, 0x11D68}, {0x11D6A, 0x11D8E}, {0x11D90, 0x11D91}, - {0x11D93, 0x11D98}, {0x11DA0, 0x11DA9}, {0x11EE0, 0x11EF8}, - {0x11F00, 0x11F10}, {0x11F12, 0x11F3A}, {0x11F3E, 0x11F59}, - {0x11FB0, 0x11FB0}, {0x11FC0, 0x11FF1}, {0x11FFF, 0x12399}, - {0x12400, 0x1246E}, {0x12470, 0x12474}, {0x12480, 0x12543}, - {0x12F90, 0x12FF2}, {0x13000, 0x13455}, {0x14400, 0x14646}, - {0x16800, 0x16A38}, {0x16A40, 0x16A5E}, {0x16A60, 0x16A69}, - {0x16A6E, 0x16ABE}, {0x16AC0, 0x16AC9}, {0x16AD0, 0x16AED}, - {0x16AF0, 0x16AF5}, {0x16B00, 0x16B45}, {0x16B50, 0x16B59}, - {0x16B5B, 0x16B61}, {0x16B63, 0x16B77}, {0x16B7D, 0x16B8F}, - {0x16E40, 0x16E9A}, {0x16F00, 0x16F4A}, {0x16F4F, 0x16F87}, - {0x16F8F, 0x16F9F}, {0x1BC00, 0x1BC6A}, {0x1BC70, 0x1BC7C}, - {0x1BC80, 0x1BC88}, {0x1BC90, 0x1BC99}, {0x1BC9C, 0x1BCA3}, - {0x1CF00, 0x1CF2D}, {0x1CF30, 0x1CF46}, {0x1CF50, 0x1CFC3}, - {0x1D000, 0x1D0F5}, {0x1D100, 0x1D126}, {0x1D129, 0x1D1EA}, - {0x1D200, 0x1D245}, {0x1D2C0, 0x1D2D3}, {0x1D2E0, 0x1D2F3}, - {0x1D300, 0x1D356}, {0x1D360, 0x1D378}, {0x1D400, 0x1D454}, - {0x1D456, 0x1D49C}, {0x1D49E, 0x1D49F}, {0x1D4A2, 0x1D4A2}, - {0x1D4A5, 0x1D4A6}, {0x1D4A9, 0x1D4AC}, {0x1D4AE, 0x1D4B9}, - {0x1D4BB, 0x1D4BB}, {0x1D4BD, 0x1D4C3}, {0x1D4C5, 0x1D505}, - {0x1D507, 0x1D50A}, {0x1D50D, 0x1D514}, {0x1D516, 0x1D51C}, - {0x1D51E, 0x1D539}, {0x1D53B, 0x1D53E}, {0x1D540, 0x1D544}, - {0x1D546, 0x1D546}, {0x1D54A, 0x1D550}, {0x1D552, 0x1D6A5}, - {0x1D6A8, 0x1D7CB}, {0x1D7CE, 0x1DA8B}, {0x1DA9B, 0x1DA9F}, - {0x1DAA1, 0x1DAAF}, {0x1DF00, 0x1DF1E}, {0x1DF25, 0x1DF2A}, - {0x1E000, 0x1E006}, {0x1E008, 0x1E018}, {0x1E01B, 0x1E021}, - {0x1E023, 0x1E024}, {0x1E026, 0x1E02A}, {0x1E030, 0x1E06D}, - {0x1E08F, 0x1E08F}, {0x1E100, 0x1E12C}, {0x1E130, 0x1E13D}, - {0x1E140, 0x1E149}, {0x1E14E, 0x1E14F}, {0x1E290, 0x1E2AE}, - {0x1E2C0, 0x1E2F9}, {0x1E2FF, 0x1E2FF}, {0x1E4D0, 0x1E4F9}, - {0x1E7E0, 0x1E7E6}, {0x1E7E8, 0x1E7EB}, {0x1E7ED, 0x1E7EE}, - {0x1E7F0, 0x1E7FE}, {0x1E800, 0x1E8C4}, {0x1E8C7, 0x1E8D6}, - {0x1E900, 0x1E94B}, {0x1E950, 0x1E959}, {0x1E95E, 0x1E95F}, - {0x1EC71, 0x1ECB4}, {0x1ED01, 0x1ED3D}, {0x1EE00, 0x1EE03}, - {0x1EE05, 0x1EE1F}, {0x1EE21, 0x1EE22}, {0x1EE24, 0x1EE24}, - {0x1EE27, 0x1EE27}, {0x1EE29, 0x1EE32}, {0x1EE34, 0x1EE37}, - {0x1EE39, 0x1EE39}, {0x1EE3B, 0x1EE3B}, {0x1EE42, 0x1EE42}, - {0x1EE47, 0x1EE47}, {0x1EE49, 0x1EE49}, {0x1EE4B, 0x1EE4B}, - {0x1EE4D, 0x1EE4F}, {0x1EE51, 0x1EE52}, {0x1EE54, 0x1EE54}, - {0x1EE57, 0x1EE57}, {0x1EE59, 0x1EE59}, {0x1EE5B, 0x1EE5B}, - {0x1EE5D, 0x1EE5D}, {0x1EE5F, 0x1EE5F}, {0x1EE61, 0x1EE62}, - {0x1EE64, 0x1EE64}, {0x1EE67, 0x1EE6A}, {0x1EE6C, 0x1EE72}, - {0x1EE74, 0x1EE77}, {0x1EE79, 0x1EE7C}, {0x1EE7E, 0x1EE7E}, - {0x1EE80, 0x1EE89}, {0x1EE8B, 0x1EE9B}, {0x1EEA1, 0x1EEA3}, - {0x1EEA5, 0x1EEA9}, {0x1EEAB, 0x1EEBB}, {0x1EEF0, 0x1EEF1}, - {0x1F000, 0x1F003}, {0x1F005, 0x1F02B}, {0x1F030, 0x1F093}, - {0x1F0A0, 0x1F0AE}, {0x1F0B1, 0x1F0BF}, {0x1F0C1, 0x1F0CE}, - {0x1F0D1, 0x1F0F5}, {0x1F10B, 0x1F10F}, {0x1F12E, 0x1F12F}, - {0x1F16A, 0x1F16F}, {0x1F1AD, 0x1F1AD}, {0x1F1E6, 0x1F1FF}, - {0x1F321, 0x1F32C}, {0x1F336, 0x1F336}, {0x1F37D, 0x1F37D}, - {0x1F394, 0x1F39F}, {0x1F3CB, 0x1F3CE}, {0x1F3D4, 0x1F3DF}, - {0x1F3F1, 0x1F3F3}, {0x1F3F5, 0x1F3F7}, {0x1F43F, 0x1F43F}, - {0x1F441, 0x1F441}, {0x1F4FD, 0x1F4FE}, {0x1F53E, 0x1F54A}, - {0x1F54F, 0x1F54F}, {0x1F568, 0x1F579}, {0x1F57B, 0x1F594}, - {0x1F597, 0x1F5A3}, {0x1F5A5, 0x1F5FA}, {0x1F650, 0x1F67F}, - {0x1F6C6, 0x1F6CB}, {0x1F6CD, 0x1F6CF}, {0x1F6D3, 0x1F6D4}, - {0x1F6E0, 0x1F6EA}, {0x1F6F0, 0x1F6F3}, {0x1F700, 0x1F776}, - {0x1F77B, 0x1F7D9}, {0x1F800, 0x1F80B}, {0x1F810, 0x1F847}, - {0x1F850, 0x1F859}, {0x1F860, 0x1F887}, {0x1F890, 0x1F8AD}, - {0x1F8B0, 0x1F8B1}, {0x1F900, 0x1F90B}, {0x1F93B, 0x1F93B}, - {0x1F946, 0x1F946}, {0x1FA00, 0x1FA53}, {0x1FA60, 0x1FA6D}, - {0x1FB00, 0x1FB92}, {0x1FB94, 0x1FBCA}, {0x1FBF0, 0x1FBF9}, - {0xE0001, 0xE0001}, {0xE0020, 0xE007F}, -} - -var emoji = table{ - {0x203C, 0x203C}, {0x2049, 0x2049}, {0x2122, 0x2122}, - {0x2139, 0x2139}, {0x2194, 0x2199}, {0x21A9, 0x21AA}, - {0x231A, 0x231B}, {0x2328, 0x2328}, {0x2388, 0x2388}, - {0x23CF, 0x23CF}, {0x23E9, 0x23F3}, {0x23F8, 0x23FA}, - {0x24C2, 0x24C2}, {0x25AA, 0x25AB}, {0x25B6, 0x25B6}, - {0x25C0, 0x25C0}, {0x25FB, 0x25FE}, {0x2600, 0x2605}, - {0x2607, 0x2612}, {0x2614, 0x2685}, {0x2690, 0x2705}, - {0x2708, 0x2712}, {0x2714, 0x2714}, {0x2716, 0x2716}, - {0x271D, 0x271D}, {0x2721, 0x2721}, {0x2728, 0x2728}, - {0x2733, 0x2734}, {0x2744, 0x2744}, {0x2747, 0x2747}, - {0x274C, 0x274C}, {0x274E, 0x274E}, {0x2753, 0x2755}, - {0x2757, 0x2757}, {0x2763, 0x2767}, {0x2795, 0x2797}, - {0x27A1, 0x27A1}, {0x27B0, 0x27B0}, {0x27BF, 0x27BF}, - {0x2934, 0x2935}, {0x2B05, 0x2B07}, {0x2B1B, 0x2B1C}, - {0x2B50, 0x2B50}, {0x2B55, 0x2B55}, {0x3030, 0x3030}, - {0x303D, 0x303D}, {0x3297, 0x3297}, {0x3299, 0x3299}, - {0x1F000, 0x1F0FF}, {0x1F10D, 0x1F10F}, {0x1F12F, 0x1F12F}, - {0x1F16C, 0x1F171}, {0x1F17E, 0x1F17F}, {0x1F18E, 0x1F18E}, - {0x1F191, 0x1F19A}, {0x1F1AD, 0x1F1E5}, {0x1F201, 0x1F20F}, - {0x1F21A, 0x1F21A}, {0x1F22F, 0x1F22F}, {0x1F232, 0x1F23A}, - {0x1F23C, 0x1F23F}, {0x1F249, 0x1F3FA}, {0x1F400, 0x1F53D}, - {0x1F546, 0x1F64F}, {0x1F680, 0x1F6FF}, {0x1F774, 0x1F77F}, - {0x1F7D5, 0x1F7FF}, {0x1F80C, 0x1F80F}, {0x1F848, 0x1F84F}, - {0x1F85A, 0x1F85F}, {0x1F888, 0x1F88F}, {0x1F8AE, 0x1F8FF}, - {0x1F90C, 0x1F93A}, {0x1F93C, 0x1F945}, {0x1F947, 0x1FAFF}, - {0x1FC00, 0x1FFFD}, -} diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_windows.go b/vendor/github.com/mattn/go-runewidth/runewidth_windows.go deleted file mode 100644 index 5f987a310f..0000000000 --- a/vendor/github.com/mattn/go-runewidth/runewidth_windows.go +++ /dev/null @@ -1,28 +0,0 @@ -//go:build windows && !appengine -// +build windows,!appengine - -package runewidth - -import ( - "syscall" -) - -var ( - kernel32 = syscall.NewLazyDLL("kernel32") - procGetConsoleOutputCP = kernel32.NewProc("GetConsoleOutputCP") -) - -// IsEastAsian return true if the current locale is CJK -func IsEastAsian() bool { - r1, _, _ := procGetConsoleOutputCP.Call() - if r1 == 0 { - return false - } - - switch int(r1) { - case 932, 51932, 936, 949, 950: - return true - } - - return false -} diff --git a/vendor/github.com/matttproud/golang_protobuf_extensions/LICENSE b/vendor/github.com/matttproud/golang_protobuf_extensions/LICENSE deleted file mode 100644 index 8dada3edaf..0000000000 --- a/vendor/github.com/matttproud/golang_protobuf_extensions/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/matttproud/golang_protobuf_extensions/NOTICE b/vendor/github.com/matttproud/golang_protobuf_extensions/NOTICE deleted file mode 100644 index 5d8cb5b72e..0000000000 --- a/vendor/github.com/matttproud/golang_protobuf_extensions/NOTICE +++ /dev/null @@ -1 +0,0 @@ -Copyright 2012 Matt T. Proud (matt.proud@gmail.com) diff --git a/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/.gitignore b/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/.gitignore deleted file mode 100644 index e16fb946bb..0000000000 --- a/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/.gitignore +++ /dev/null @@ -1 +0,0 @@ -cover.dat diff --git a/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/Makefile b/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/Makefile deleted file mode 100644 index 81be214370..0000000000 --- a/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -all: - -cover: - go test -cover -v -coverprofile=cover.dat ./... - go tool cover -func cover.dat - -.PHONY: cover diff --git a/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/decode.go b/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/decode.go deleted file mode 100644 index 258c0636aa..0000000000 --- a/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/decode.go +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright 2013 Matt T. Proud -// -// 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. - -package pbutil - -import ( - "encoding/binary" - "errors" - "io" - - "github.com/golang/protobuf/proto" -) - -var errInvalidVarint = errors.New("invalid varint32 encountered") - -// ReadDelimited decodes a message from the provided length-delimited stream, -// where the length is encoded as 32-bit varint prefix to the message body. -// It returns the total number of bytes read and any applicable error. This is -// roughly equivalent to the companion Java API's -// MessageLite#parseDelimitedFrom. As per the reader contract, this function -// calls r.Read repeatedly as required until exactly one message including its -// prefix is read and decoded (or an error has occurred). The function never -// reads more bytes from the stream than required. The function never returns -// an error if a message has been read and decoded correctly, even if the end -// of the stream has been reached in doing so. In that case, any subsequent -// calls return (0, io.EOF). -func ReadDelimited(r io.Reader, m proto.Message) (n int, err error) { - // Per AbstractParser#parsePartialDelimitedFrom with - // CodedInputStream#readRawVarint32. - var headerBuf [binary.MaxVarintLen32]byte - var bytesRead, varIntBytes int - var messageLength uint64 - for varIntBytes == 0 { // i.e. no varint has been decoded yet. - if bytesRead >= len(headerBuf) { - return bytesRead, errInvalidVarint - } - // We have to read byte by byte here to avoid reading more bytes - // than required. Each read byte is appended to what we have - // read before. - newBytesRead, err := r.Read(headerBuf[bytesRead : bytesRead+1]) - if newBytesRead == 0 { - if err != nil { - return bytesRead, err - } - // A Reader should not return (0, nil), but if it does, - // it should be treated as no-op (according to the - // Reader contract). So let's go on... - continue - } - bytesRead += newBytesRead - // Now present everything read so far to the varint decoder and - // see if a varint can be decoded already. - messageLength, varIntBytes = proto.DecodeVarint(headerBuf[:bytesRead]) - } - - messageBuf := make([]byte, messageLength) - newBytesRead, err := io.ReadFull(r, messageBuf) - bytesRead += newBytesRead - if err != nil { - return bytesRead, err - } - - return bytesRead, proto.Unmarshal(messageBuf, m) -} diff --git a/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/doc.go b/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/doc.go deleted file mode 100644 index c318385cbe..0000000000 --- a/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/doc.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2013 Matt T. Proud -// -// 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. - -// Package pbutil provides record length-delimited Protocol Buffer streaming. -package pbutil diff --git a/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/encode.go b/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/encode.go deleted file mode 100644 index 8fb59ad226..0000000000 --- a/vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/encode.go +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2013 Matt T. Proud -// -// 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. - -package pbutil - -import ( - "encoding/binary" - "io" - - "github.com/golang/protobuf/proto" -) - -// WriteDelimited encodes and dumps a message to the provided writer prefixed -// with a 32-bit varint indicating the length of the encoded message, producing -// a length-delimited record stream, which can be used to chain together -// encoded messages of the same type together in a file. It returns the total -// number of bytes written and any applicable error. This is roughly -// equivalent to the companion Java API's MessageLite#writeDelimitedTo. -func WriteDelimited(w io.Writer, m proto.Message) (n int, err error) { - buffer, err := proto.Marshal(m) - if err != nil { - return 0, err - } - - var buf [binary.MaxVarintLen32]byte - encodedLength := binary.PutUvarint(buf[:], uint64(len(buffer))) - - sync, err := w.Write(buf[:encodedLength]) - if err != nil { - return sync, err - } - - n, err = w.Write(buffer) - return n + sync, err -} diff --git a/vendor/github.com/mgechev/revive/LICENSE b/vendor/github.com/mgechev/revive/LICENSE deleted file mode 100644 index c617c7e012..0000000000 --- a/vendor/github.com/mgechev/revive/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2018 Minko Gechev - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/mgechev/revive/config/config.go b/vendor/github.com/mgechev/revive/config/config.go deleted file mode 100644 index e03d337ff2..0000000000 --- a/vendor/github.com/mgechev/revive/config/config.go +++ /dev/null @@ -1,284 +0,0 @@ -// Package config implements revive's configuration data structures and related methods -package config - -import ( - "errors" - "fmt" - "os" - - "github.com/BurntSushi/toml" - - "github.com/mgechev/revive/formatter" - "github.com/mgechev/revive/lint" - "github.com/mgechev/revive/rule" -) - -var defaultRules = []lint.Rule{ - &rule.VarDeclarationsRule{}, - &rule.PackageCommentsRule{}, - &rule.DotImportsRule{}, - &rule.BlankImportsRule{}, - &rule.ExportedRule{}, - &rule.VarNamingRule{}, - &rule.IndentErrorFlowRule{}, - &rule.RangeRule{}, - &rule.ErrorfRule{}, - &rule.ErrorNamingRule{}, - &rule.ErrorStringsRule{}, - &rule.ReceiverNamingRule{}, - &rule.IncrementDecrementRule{}, - &rule.ErrorReturnRule{}, - &rule.UnexportedReturnRule{}, - &rule.TimeNamingRule{}, - &rule.ContextKeysType{}, - &rule.ContextAsArgumentRule{}, - &rule.EmptyBlockRule{}, - &rule.SuperfluousElseRule{}, - &rule.UnusedParamRule{}, - &rule.UnreachableCodeRule{}, - &rule.RedefinesBuiltinIDRule{}, -} - -var allRules = append([]lint.Rule{ - &rule.ArgumentsLimitRule{}, - &rule.CyclomaticRule{}, - &rule.FileHeaderRule{}, - &rule.ConfusingNamingRule{}, - &rule.GetReturnRule{}, - &rule.ModifiesParamRule{}, - &rule.ConfusingResultsRule{}, - &rule.DeepExitRule{}, - &rule.AddConstantRule{}, - &rule.FlagParamRule{}, - &rule.UnnecessaryStmtRule{}, - &rule.StructTagRule{}, - &rule.ModifiesValRecRule{}, - &rule.ConstantLogicalExprRule{}, - &rule.BoolLiteralRule{}, - &rule.ImportsBlocklistRule{}, - &rule.FunctionResultsLimitRule{}, - &rule.MaxPublicStructsRule{}, - &rule.RangeValInClosureRule{}, - &rule.RangeValAddress{}, - &rule.WaitGroupByValueRule{}, - &rule.AtomicRule{}, - &rule.EmptyLinesRule{}, - &rule.LineLengthLimitRule{}, - &rule.CallToGCRule{}, - &rule.DuplicatedImportsRule{}, - &rule.ImportShadowingRule{}, - &rule.BareReturnRule{}, - &rule.UnusedReceiverRule{}, - &rule.UnhandledErrorRule{}, - &rule.CognitiveComplexityRule{}, - &rule.StringOfIntRule{}, - &rule.StringFormatRule{}, - &rule.EarlyReturnRule{}, - &rule.UnconditionalRecursionRule{}, - &rule.IdenticalBranchesRule{}, - &rule.DeferRule{}, - &rule.UnexportedNamingRule{}, - &rule.FunctionLength{}, - &rule.NestedStructs{}, - &rule.UselessBreak{}, - &rule.UncheckedTypeAssertionRule{}, - &rule.TimeEqualRule{}, - &rule.TimeDateRule{}, - &rule.BannedCharsRule{}, - &rule.OptimizeOperandsOrderRule{}, - &rule.UseAnyRule{}, - &rule.DataRaceRule{}, - &rule.CommentSpacingsRule{}, - &rule.IfReturnRule{}, - &rule.RedundantImportAlias{}, - &rule.ImportAliasNamingRule{}, - &rule.EnforceMapStyleRule{}, - &rule.EnforceRepeatedArgTypeStyleRule{}, - &rule.EnforceSliceStyleRule{}, - &rule.MaxControlNestingRule{}, - &rule.CommentsDensityRule{}, - &rule.FileLengthLimitRule{}, - &rule.FilenameFormatRule{}, - &rule.RedundantBuildTagRule{}, - &rule.UseErrorsNewRule{}, - &rule.RedundantTestMainExitRule{}, - &rule.UnnecessaryFormatRule{}, - &rule.UseFmtPrintRule{}, - &rule.EnforceSwitchStyleRule{}, - &rule.IdenticalSwitchConditionsRule{}, - &rule.IdenticalIfElseIfConditionsRule{}, - &rule.IdenticalIfElseIfBranchesRule{}, - &rule.IdenticalSwitchBranchesRule{}, - &rule.UselessFallthroughRule{}, - &rule.PackageDirectoryMismatchRule{}, - &rule.UseWaitGroupGoRule{}, - &rule.UnsecureURLSchemeRule{}, -}, defaultRules...) - -// allFormatters is a list of all available formatters to output the linting results. -// Keep the list sorted and in sync with available formatters in README.md. -var allFormatters = []lint.Formatter{ - &formatter.Checkstyle{}, - &formatter.Default{}, - &formatter.Friendly{}, - &formatter.JSON{}, - &formatter.NDJSON{}, - &formatter.Plain{}, - &formatter.Sarif{}, - &formatter.Stylish{}, - &formatter.Unix{}, -} - -func getFormatters() map[string]lint.Formatter { - result := map[string]lint.Formatter{} - for _, f := range allFormatters { - result[f.Name()] = f - } - return result -} - -// GetLintingRules yields the linting rules that must be applied by the linter. -func GetLintingRules(config *lint.Config, extraRules []lint.Rule) ([]lint.Rule, error) { - rulesMap := map[string]lint.Rule{} - for _, r := range allRules { - rulesMap[r.Name()] = r - } - for _, r := range extraRules { - if _, ok := rulesMap[r.Name()]; ok { - continue - } - rulesMap[r.Name()] = r - } - - var lintingRules []lint.Rule - for name, ruleConfig := range config.Rules { - actualName := actualRuleName(name) - r, ok := rulesMap[actualName] - if !ok { - return nil, fmt.Errorf("cannot find rule: %s", name) - } - - if ruleConfig.Disabled { - continue // skip disabled rules - } - - if r, ok := r.(lint.ConfigurableRule); ok { - if err := r.Configure(ruleConfig.Arguments); err != nil { - return nil, fmt.Errorf("cannot configure rule: %q: %w", name, err) - } - } - - lintingRules = append(lintingRules, r) - } - - return lintingRules, nil -} - -func actualRuleName(name string) string { - switch name { - case "imports-blacklist": - return "imports-blocklist" - default: - return name - } -} - -func parseConfig(path string, config *lint.Config) error { - file, err := os.ReadFile(path) - if err != nil { - return errors.New("cannot read the config file") - } - err = toml.Unmarshal(file, config) - if err != nil { - return fmt.Errorf("cannot parse the config file: %w", err) - } - for k, r := range config.Rules { - err := r.Initialize() - if err != nil { - return fmt.Errorf("error in config of rule [%s] : [%w]", k, err) - } - config.Rules[k] = r - } - - return nil -} - -func normalizeConfig(config *lint.Config) { - if len(config.Rules) == 0 { - config.Rules = map[string]lint.RuleConfig{} - } - if config.EnableAllRules { - // Add to the configuration all rules not yet present in it - for _, r := range allRules { - ruleName := r.Name() - _, alreadyInConf := config.Rules[ruleName] - if alreadyInConf { - continue - } - // Add the rule with an empty conf for - config.Rules[ruleName] = lint.RuleConfig{} - } - } - - severity := config.Severity - if severity != "" { - for k, v := range config.Rules { - if v.Severity == "" { - v.Severity = severity - } - config.Rules[k] = v - } - for k, v := range config.Directives { - if v.Severity == "" { - v.Severity = severity - } - config.Directives[k] = v - } - } -} - -const defaultConfidence = 0.8 - -// GetConfig yields the configuration. -func GetConfig(configPath string) (*lint.Config, error) { - config := &lint.Config{} - switch { - case configPath != "": - config.Confidence = defaultConfidence - err := parseConfig(configPath, config) - if err != nil { - return nil, err - } - - default: // no configuration provided - config = defaultConfig() - } - - normalizeConfig(config) - return config, nil -} - -// GetFormatter yields the formatter for lint failures. -func GetFormatter(formatterName string) (lint.Formatter, error) { - formatters := getFormatters() - if formatterName == "" { - return formatters["default"], nil - } - f, ok := formatters[formatterName] - if !ok { - return nil, fmt.Errorf("unknown formatter %v", formatterName) - } - return f, nil -} - -func defaultConfig() *lint.Config { - defaultConfig := lint.Config{ - Confidence: defaultConfidence, - Severity: lint.SeverityWarning, - Rules: map[string]lint.RuleConfig{}, - } - for _, r := range defaultRules { - defaultConfig.Rules[r.Name()] = lint.RuleConfig{} - } - return &defaultConfig -} diff --git a/vendor/github.com/mgechev/revive/formatter/checkstyle.go b/vendor/github.com/mgechev/revive/formatter/checkstyle.go deleted file mode 100644 index 1fb17d4d94..0000000000 --- a/vendor/github.com/mgechev/revive/formatter/checkstyle.go +++ /dev/null @@ -1,77 +0,0 @@ -package formatter - -import ( - "bytes" - "encoding/xml" - plain "text/template" - - "github.com/mgechev/revive/lint" -) - -// Checkstyle is an implementation of the Formatter interface -// which formats the errors to Checkstyle-like format. -type Checkstyle struct { - Metadata lint.FormatterMetadata -} - -// Name returns the name of the formatter. -func (*Checkstyle) Name() string { - return "checkstyle" -} - -type issue struct { - Line int - Col int - What string - Confidence float64 - Severity lint.Severity - RuleName string -} - -// Format formats the failures gotten from the lint. -func (*Checkstyle) Format(failures <-chan lint.Failure, config lint.Config) (string, error) { - issues := map[string][]issue{} - for failure := range failures { - buf := new(bytes.Buffer) - xml.Escape(buf, []byte(failure.Failure)) - what := buf.String() - iss := issue{ - Line: failure.Position.Start.Line, - Col: failure.Position.Start.Column, - What: what, - Confidence: failure.Confidence, - Severity: severity(config, failure), - RuleName: failure.RuleName, - } - fn := failure.Filename() - if issues[fn] == nil { - issues[fn] = []issue{} - } - issues[fn] = append(issues[fn], iss) - } - - t, err := plain.New("revive").Parse(checkstyleTemplate) - if err != nil { - return "", err - } - - buf := new(bytes.Buffer) - - err = t.Execute(buf, issues) - if err != nil { - return "", err - } - - return buf.String(), nil -} - -const checkstyleTemplate = ` - -{{- range $k, $v := . }} - - {{- range $i, $issue := $v }} - - {{- end }} - -{{- end }} -` diff --git a/vendor/github.com/mgechev/revive/formatter/default.go b/vendor/github.com/mgechev/revive/formatter/default.go deleted file mode 100644 index ffb9d5f3f3..0000000000 --- a/vendor/github.com/mgechev/revive/formatter/default.go +++ /dev/null @@ -1,34 +0,0 @@ -package formatter - -import ( - "bytes" - "fmt" - - "github.com/mgechev/revive/lint" -) - -// Default is an implementation of the Formatter interface -// which formats the errors to text. -type Default struct { - Metadata lint.FormatterMetadata -} - -// Name returns the name of the formatter. -func (*Default) Name() string { - return "default" -} - -// Format formats the failures gotten from the lint. -func (*Default) Format(failures <-chan lint.Failure, _ lint.Config) (string, error) { - var buf bytes.Buffer - prefix := "" - for failure := range failures { - fmt.Fprintf(&buf, "%s%v: %s", prefix, failure.Position.Start, failure.Failure) - prefix = "\n" - } - return buf.String(), nil -} - -func ruleDescriptionURL(ruleName string) string { - return "https://revive.run/r#" + ruleName -} diff --git a/vendor/github.com/mgechev/revive/formatter/doc.go b/vendor/github.com/mgechev/revive/formatter/doc.go deleted file mode 100644 index bb89f20ea6..0000000000 --- a/vendor/github.com/mgechev/revive/formatter/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package formatter implements the linter output formatters. -package formatter diff --git a/vendor/github.com/mgechev/revive/formatter/friendly.go b/vendor/github.com/mgechev/revive/formatter/friendly.go deleted file mode 100644 index de24df887d..0000000000 --- a/vendor/github.com/mgechev/revive/formatter/friendly.go +++ /dev/null @@ -1,139 +0,0 @@ -package formatter - -import ( - "bytes" - "cmp" - "fmt" - "io" - "slices" - "strings" - "text/tabwriter" - - "github.com/fatih/color" - - "github.com/mgechev/revive/lint" -) - -// Friendly is an implementation of the Formatter interface -// which formats the errors to JSON. -type Friendly struct { - Metadata lint.FormatterMetadata -} - -// Name returns the name of the formatter. -func (*Friendly) Name() string { - return "friendly" -} - -// Format formats the failures gotten from the lint. -func (f *Friendly) Format(failures <-chan lint.Failure, config lint.Config) (string, error) { - var buf strings.Builder - errorMap := map[string]int{} - warningMap := map[string]int{} - totalErrors := 0 - totalWarnings := 0 - for failure := range failures { - sev := severity(config, failure) - f.printFriendlyFailure(&buf, failure, sev) - switch sev { - case lint.SeverityWarning: - warningMap[failure.RuleName]++ - totalWarnings++ - case lint.SeverityError: - errorMap[failure.RuleName]++ - totalErrors++ - } - } - - f.printSummary(&buf, totalErrors, totalWarnings) - f.printStatistics(&buf, color.RedString("Errors:"), errorMap) - f.printStatistics(&buf, color.YellowString("Warnings:"), warningMap) - return buf.String(), nil -} - -func (f *Friendly) printFriendlyFailure(sb *strings.Builder, failure lint.Failure, severity lint.Severity) { - f.printHeaderRow(sb, failure, severity) - f.printFilePosition(sb, failure) - sb.WriteString("\n\n") -} - -var errorEmoji = color.RedString("✘") -var warningEmoji = color.YellowString("⚠") - -func (*Friendly) printHeaderRow(sb *strings.Builder, failure lint.Failure, severity lint.Severity) { - emoji := warningEmoji - if severity == lint.SeverityError { - emoji = errorEmoji - } - sb.WriteString(table([][]string{{emoji, ruleDescriptionURL(failure.RuleName), color.GreenString(failure.Failure)}})) -} - -func (*Friendly) printFilePosition(sb *strings.Builder, failure lint.Failure) { - fmt.Fprintf(sb, " %s:%d:%d", failure.Filename(), failure.Position.Start.Line, failure.Position.Start.Column) -} - -type statEntry struct { - name string - failures int -} - -func (*Friendly) printSummary(w io.Writer, errors, warnings int) { - emoji := warningEmoji - if errors > 0 { - emoji = errorEmoji - } - problemsLabel := "problems" - if errors+warnings == 1 { - problemsLabel = "problem" - } - warningsLabel := "warnings" - if warnings == 1 { - warningsLabel = "warning" - } - errorsLabel := "errors" - if errors == 1 { - errorsLabel = "error" - } - str := fmt.Sprintf("%d %s (%d %s, %d %s)", errors+warnings, problemsLabel, errors, errorsLabel, warnings, warningsLabel) - if errors > 0 { - fmt.Fprintf(w, "%s %s\n\n", emoji, color.RedString(str)) - return - } - if warnings > 0 { - fmt.Fprintf(w, "%s %s\n\n", emoji, color.YellowString(str)) - return - } -} - -func (*Friendly) printStatistics(w io.Writer, header string, stats map[string]int) { - if len(stats) == 0 { - return - } - data := make([]statEntry, 0, len(stats)) - for name, total := range stats { - data = append(data, statEntry{name, total}) - } - slices.SortFunc(data, func(a, b statEntry) int { - return -cmp.Compare(a.failures, b.failures) - }) - formatted := [][]string{} - for _, entry := range data { - formatted = append(formatted, []string{color.GreenString(fmt.Sprintf("%d", entry.failures)), entry.name}) - } - fmt.Fprintln(w, header) - fmt.Fprintln(w, table(formatted)) -} - -func table(rows [][]string) string { - var buf bytes.Buffer - tw := tabwriter.NewWriter(&buf, 0, 0, 2, ' ', 0) - for _, row := range rows { - tw.Write([]byte{'\t'}) - for _, col := range row { - tw.Write(append([]byte(col), '\t')) - } - tw.Write([]byte{'\n'}) - } - tw.Flush() - return buf.String() -} diff --git a/vendor/github.com/mgechev/revive/formatter/json.go b/vendor/github.com/mgechev/revive/formatter/json.go deleted file mode 100644 index 292c06b36d..0000000000 --- a/vendor/github.com/mgechev/revive/formatter/json.go +++ /dev/null @@ -1,40 +0,0 @@ -package formatter - -import ( - "encoding/json" - - "github.com/mgechev/revive/lint" -) - -// JSON is an implementation of the Formatter interface -// which formats the errors to JSON. -type JSON struct { - Metadata lint.FormatterMetadata -} - -// Name returns the name of the formatter. -func (*JSON) Name() string { - return "json" -} - -// jsonObject defines a JSON object of an failure. -type jsonObject struct { - Severity lint.Severity `json:"Severity"` - lint.Failure `json:",inline"` -} - -// Format formats the failures gotten from the lint. -func (*JSON) Format(failures <-chan lint.Failure, config lint.Config) (string, error) { - var slice []jsonObject - for failure := range failures { - obj := jsonObject{} - obj.Severity = severity(config, failure) - obj.Failure = failure - slice = append(slice, obj) - } - result, err := json.Marshal(slice) - if err != nil { - return "", err - } - return string(result), err -} diff --git a/vendor/github.com/mgechev/revive/formatter/ndjson.go b/vendor/github.com/mgechev/revive/formatter/ndjson.go deleted file mode 100644 index 66acff3206..0000000000 --- a/vendor/github.com/mgechev/revive/formatter/ndjson.go +++ /dev/null @@ -1,35 +0,0 @@ -package formatter - -import ( - "bytes" - "encoding/json" - - "github.com/mgechev/revive/lint" -) - -// NDJSON is an implementation of the Formatter interface -// which formats the errors to NDJSON stream. -type NDJSON struct { - Metadata lint.FormatterMetadata -} - -// Name returns the name of the formatter. -func (*NDJSON) Name() string { - return "ndjson" -} - -// Format formats the failures gotten from the lint. -func (*NDJSON) Format(failures <-chan lint.Failure, config lint.Config) (string, error) { - var buf bytes.Buffer - enc := json.NewEncoder(&buf) - for failure := range failures { - obj := jsonObject{} - obj.Severity = severity(config, failure) - obj.Failure = failure - err := enc.Encode(obj) - if err != nil { - return "", err - } - } - return buf.String(), nil -} diff --git a/vendor/github.com/mgechev/revive/formatter/plain.go b/vendor/github.com/mgechev/revive/formatter/plain.go deleted file mode 100644 index 6c77926ea9..0000000000 --- a/vendor/github.com/mgechev/revive/formatter/plain.go +++ /dev/null @@ -1,28 +0,0 @@ -package formatter - -import ( - "fmt" - "strings" - - "github.com/mgechev/revive/lint" -) - -// Plain is an implementation of the Formatter interface -// which formats the errors to JSON. -type Plain struct { - Metadata lint.FormatterMetadata -} - -// Name returns the name of the formatter. -func (*Plain) Name() string { - return "plain" -} - -// Format formats the failures gotten from the lint. -func (*Plain) Format(failures <-chan lint.Failure, _ lint.Config) (string, error) { - var sb strings.Builder - for failure := range failures { - sb.WriteString(fmt.Sprintf("%v: %s %s\n", failure.Position.Start, failure.Failure, ruleDescriptionURL(failure.RuleName))) - } - return sb.String(), nil -} diff --git a/vendor/github.com/mgechev/revive/formatter/sarif.go b/vendor/github.com/mgechev/revive/formatter/sarif.go deleted file mode 100644 index c177649026..0000000000 --- a/vendor/github.com/mgechev/revive/formatter/sarif.go +++ /dev/null @@ -1,108 +0,0 @@ -package formatter - -import ( - "bytes" - "fmt" - "strings" - - "codeberg.org/chavacava/garif" - - "github.com/mgechev/revive/lint" -) - -// Sarif is an implementation of the Formatter interface -// which formats revive failures into SARIF format. -type Sarif struct { - Metadata lint.FormatterMetadata -} - -// Name returns the name of the formatter. -func (*Sarif) Name() string { - return "sarif" -} - -const reviveSite = "https://revive.run" - -// Format formats the failures gotten from the lint. -func (*Sarif) Format(failures <-chan lint.Failure, cfg lint.Config) (string, error) { - sarifLog := newReviveRunLog(cfg) - - for failure := range failures { - sarifLog.addResult(failure) - } - - buf := new(bytes.Buffer) - sarifLog.PrettyWrite(buf) - - return buf.String(), nil -} - -type reviveRunLog struct { - *garif.LogFile - run *garif.Run - rules map[string]lint.RuleConfig -} - -func newReviveRunLog(cfg lint.Config) *reviveRunLog { - run := garif.NewRun(garif.NewTool(garif.NewDriver("revive").WithInformationUri(reviveSite))) - log := garif.NewLogFile([]*garif.Run{run}, garif.Version210) - - reviveLog := &reviveRunLog{ - log, - run, - cfg.Rules, - } - - reviveLog.addRules(cfg.Rules) - - return reviveLog -} - -func (l *reviveRunLog) addRules(cfg map[string]lint.RuleConfig) { - for name, ruleCfg := range cfg { - rule := garif.NewRule(name).WithHelpUri(reviveSite + "/r#" + name) - setRuleProperties(rule, ruleCfg) - driver := l.run.Tool.Driver - - if driver.Rules == nil { - driver.Rules = []*garif.ReportingDescriptor{rule} - return - } - - driver.Rules = append(driver.Rules, rule) - } -} - -func (l *reviveRunLog) addResult(failure lint.Failure) { - positiveOrZero := func(x int) int { - if x > 0 { - return x - } - return 0 - } - position := failure.Position - filename := position.Start.Filename - line := positiveOrZero(position.Start.Line) // https://docs.oasis-open.org/sarif/sarif/v2.1.0/csprd01/sarif-v2.1.0-csprd01.html#def_line - column := positiveOrZero(position.Start.Column) // https://docs.oasis-open.org/sarif/sarif/v2.1.0/csprd01/sarif-v2.1.0-csprd01.html#def_column - - result := garif.NewResult(garif.NewMessageFromText(failure.Failure)) - location := garif.NewLocation().WithURI(filename).WithLineColumn(line, column) - result.Locations = append(result.Locations, location) - result.RuleId = failure.RuleName - result.Level = garif.ResultLevel(l.rules[failure.RuleName].Severity) - - l.run.Results = append(l.run.Results, result) -} - -func setRuleProperties(sarifRule *garif.ReportingDescriptor, lintRule lint.RuleConfig) { - arguments := make([]string, len(lintRule.Arguments)) - for i, arg := range lintRule.Arguments { - arguments[i] = fmt.Sprintf("%+v", arg) - } - - if len(arguments) > 0 { - sarifRule.WithProperties("arguments", strings.Join(arguments, ",")) - } - - sarifRule.WithProperties("severity", string(lintRule.Severity)) -} diff --git a/vendor/github.com/mgechev/revive/formatter/severity.go b/vendor/github.com/mgechev/revive/formatter/severity.go deleted file mode 100644 index a43bf31923..0000000000 --- a/vendor/github.com/mgechev/revive/formatter/severity.go +++ /dev/null @@ -1,13 +0,0 @@ -package formatter - -import "github.com/mgechev/revive/lint" - -func severity(config lint.Config, failure lint.Failure) lint.Severity { - if config, ok := config.Rules[failure.RuleName]; ok && config.Severity == lint.SeverityError { - return lint.SeverityError - } - if config, ok := config.Directives[failure.RuleName]; ok && config.Severity == lint.SeverityError { - return lint.SeverityError - } - return lint.SeverityWarning -} diff --git a/vendor/github.com/mgechev/revive/formatter/stylish.go b/vendor/github.com/mgechev/revive/formatter/stylish.go deleted file mode 100644 index 8185e8b8a5..0000000000 --- a/vendor/github.com/mgechev/revive/formatter/stylish.go +++ /dev/null @@ -1,91 +0,0 @@ -package formatter - -import ( - "fmt" - - "github.com/fatih/color" - - "github.com/mgechev/revive/lint" -) - -// Stylish is an implementation of the Formatter interface -// which formats the errors to JSON. -type Stylish struct { - Metadata lint.FormatterMetadata -} - -// Name returns the name of the formatter. -func (*Stylish) Name() string { - return "stylish" -} - -func formatFailure(failure lint.Failure, severity lint.Severity) []string { - fString := color.CyanString(failure.Failure) - lineColumn := failure.Position - pos := fmt.Sprintf("(%d, %d)", lineColumn.Start.Line, lineColumn.Start.Column) - fURL := ruleDescriptionURL(failure.RuleName) - fName := color.RedString(fURL) - if severity == lint.SeverityWarning { - fName = color.YellowString(fURL) - } - return []string{failure.Filename(), pos, fName, fString} -} - -// Format formats the failures gotten from the lint. -func (*Stylish) Format(failures <-chan lint.Failure, config lint.Config) (string, error) { - var result [][]string - totalErrors := 0 - total := 0 - - for f := range failures { - total++ - currentType := severity(config, f) - if currentType == lint.SeverityError { - totalErrors++ - } - result = append(result, formatFailure(f, lint.Severity(currentType))) - } - - fileReport := map[string][][]string{} - - for _, row := range result { - if _, ok := fileReport[row[0]]; !ok { - fileReport[row[0]] = [][]string{} - } - - fileReport[row[0]] = append(fileReport[row[0]], []string{row[1], row[2], row[3]}) - } - - output := "" - for filename, val := range fileReport { - c := color.New(color.Underline) - output += c.SprintfFunc()(filename + "\n") - output += table(val) + "\n" - } - - problemsLabel := "problems" - if total == 1 { - problemsLabel = "problem" - } - totalWarnings := total - totalErrors - warningsLabel := "warnings" - if totalWarnings == 1 { - warningsLabel = "warning" - } - errorsLabel := "errors" - if totalErrors == 1 { - errorsLabel = "error" - } - suffix := fmt.Sprintf(" %d %s (%d %s) (%d %s)", total, problemsLabel, totalErrors, errorsLabel, totalWarnings, warningsLabel) - - switch { - case total > 0 && totalErrors > 0: - suffix = color.RedString("\n ✖" + suffix) - case total > 0 && totalErrors == 0: - suffix = color.YellowString("\n ✖" + suffix) - default: - suffix, output = "", "" - } - - return output + suffix, nil -} diff --git a/vendor/github.com/mgechev/revive/formatter/unix.go b/vendor/github.com/mgechev/revive/formatter/unix.go deleted file mode 100644 index dd063a0d81..0000000000 --- a/vendor/github.com/mgechev/revive/formatter/unix.go +++ /dev/null @@ -1,30 +0,0 @@ -package formatter - -import ( - "fmt" - "strings" - - "github.com/mgechev/revive/lint" -) - -// Unix is an implementation of the Formatter interface -// which formats the errors to a simple line based error format -// -// main.go:24:9: [errorf] should replace errors.New(fmt.Sprintf(...)) with fmt.Errorf(...) -type Unix struct { - Metadata lint.FormatterMetadata -} - -// Name returns the name of the formatter. -func (*Unix) Name() string { - return "unix" -} - -// Format formats the failures gotten from the lint. -func (*Unix) Format(failures <-chan lint.Failure, _ lint.Config) (string, error) { - var sb strings.Builder - for failure := range failures { - sb.WriteString(fmt.Sprintf("%v: [%s] %s\n", failure.Position.Start, failure.RuleName, failure.Failure)) - } - return sb.String(), nil -} diff --git a/vendor/github.com/mgechev/revive/internal/astutils/ast_utils.go b/vendor/github.com/mgechev/revive/internal/astutils/ast_utils.go deleted file mode 100644 index fca3ee5a90..0000000000 --- a/vendor/github.com/mgechev/revive/internal/astutils/ast_utils.go +++ /dev/null @@ -1,216 +0,0 @@ -// Package astutils provides utility functions for working with AST nodes -package astutils - -import ( - "bytes" - "crypto/md5" - "encoding/hex" - "fmt" - "go/ast" - "go/printer" - "go/token" - "regexp" - "slices" -) - -// FuncSignatureIs returns true if the given func decl satisfies a signature characterized -// by the given name, parameters types and return types; false otherwise. -// -// Example: to check if a function declaration has the signature Foo(int, string) (bool,error) -// call to FuncSignatureIs(funcDecl,"Foo",[]string{"int","string"},[]string{"bool","error"}). -func FuncSignatureIs(funcDecl *ast.FuncDecl, wantName string, wantParametersTypes, wantResultsTypes []string) bool { - if wantName != funcDecl.Name.String() { - return false // func name doesn't match expected one - } - - funcResultsTypes := GetTypeNames(funcDecl.Type.Results) - if !slices.Equal(wantResultsTypes, funcResultsTypes) { - return false // func has not the expected return values - } - - // Name and return values are those we expected, - // the final result depends on parameters being what we want. - return funcParametersSignatureIs(funcDecl, wantParametersTypes) -} - -// funcParametersSignatureIs returns true if the function has parameters of the given type and order, -// false otherwise. -func funcParametersSignatureIs(funcDecl *ast.FuncDecl, wantParametersTypes []string) bool { - funcParametersTypes := GetTypeNames(funcDecl.Type.Params) - - return slices.Equal(wantParametersTypes, funcParametersTypes) -} - -// GetTypeNames yields an slice with the string representation of the types of given fields. -// It yields nil if the field list is nil. -func GetTypeNames(fields *ast.FieldList) []string { - if fields == nil { - return nil - } - - result := []string{} - - for _, field := range fields.List { - typeName := getFieldTypeName(field.Type) - if field.Names == nil { // unnamed field - result = append(result, typeName) - continue - } - - for range field.Names { // add one type name for each field name - result = append(result, typeName) - } - } - - return result -} - -func getFieldTypeName(typ ast.Expr) string { - switch f := typ.(type) { - case *ast.Ident: - return f.Name - case *ast.SelectorExpr: - return getFieldTypeName(f.X) + "." + getFieldTypeName(f.Sel) - case *ast.StarExpr: - return "*" + getFieldTypeName(f.X) - case *ast.IndexExpr: - return getFieldTypeName(f.X) + "[" + getFieldTypeName(f.Index) + "]" - case *ast.ArrayType: - return "[]" + getFieldTypeName(f.Elt) - case *ast.InterfaceType: - return "interface{}" - default: - return "UNHANDLED_TYPE" - } -} - -// IsStringLiteral returns true if the given expression is a string literal, false otherwise. -func IsStringLiteral(e ast.Expr) bool { - sl, ok := e.(*ast.BasicLit) - - return ok && sl.Kind == token.STRING -} - -// IsCgoExported returns true if the given function declaration is exported as Cgo function, false otherwise. -func IsCgoExported(f *ast.FuncDecl) bool { - if f.Recv != nil || f.Doc == nil { - return false - } - - cgoExport := regexp.MustCompile(fmt.Sprintf("(?m)^//export %s$", regexp.QuoteMeta(f.Name.Name))) - for _, c := range f.Doc.List { - if cgoExport.MatchString(c.Text) { - return true - } - } - return false -} - -// IsIdent returns true if the given expression is the identifier with name ident, false otherwise. -func IsIdent(expr ast.Expr, ident string) bool { - id, ok := expr.(*ast.Ident) - return ok && id.Name == ident -} - -// IsPkgDotName returns true if the given expression is a selector expression of the form ., false otherwise. -func IsPkgDotName(expr ast.Expr, pkg, name string) bool { - sel, ok := expr.(*ast.SelectorExpr) - return ok && IsIdent(sel.X, pkg) && IsIdent(sel.Sel, name) -} - -// PickNodes yields a list of nodes by picking them from a sub-ast with root node n. -// Nodes are selected by applying the selector function. -func PickNodes(n ast.Node, selector func(n ast.Node) bool) []ast.Node { - var result []ast.Node - - if n == nil { - return result - } - - onSelect := func(n ast.Node) { - result = append(result, n) - } - p := picker{selector: selector, onSelect: onSelect} - ast.Walk(p, n) - return result -} - -type picker struct { - selector func(n ast.Node) bool - onSelect func(n ast.Node) -} - -func (p picker) Visit(node ast.Node) ast.Visitor { - if p.selector == nil { - return nil - } - - if p.selector(node) { - p.onSelect(node) - } - - return p -} - -// SeekNode yields the first node selected by the given selector function in the AST subtree with root n. -// The function returns nil if no matching node is found in the subtree. -func SeekNode[T ast.Node](n ast.Node, selector func(n ast.Node) bool) T { - var result T - - if n == nil { - return result - } - - if selector == nil { - return result - } - - onSelect := func(n ast.Node) { - result, _ = n.(T) - } - - p := &seeker{selector: selector, onSelect: onSelect, found: false} - ast.Walk(p, n) - - return result -} - -type seeker struct { - selector func(n ast.Node) bool - onSelect func(n ast.Node) - found bool -} - -func (s *seeker) Visit(node ast.Node) ast.Visitor { - if s.found { - return nil // stop visiting subtree - } - - if s.selector(node) { - s.onSelect(node) - s.found = true - return nil // skip visiting node children - } - - return s -} - -var gofmtConfig = &printer.Config{Tabwidth: 8} - -// GoFmt returns a string representation of an AST subtree. -func GoFmt(x any) string { - buf := bytes.Buffer{} - fs := token.NewFileSet() - gofmtConfig.Fprint(&buf, fs, x) - return buf.String() -} - -// NodeHash yields the MD5 hash of the given AST node. -func NodeHash(node ast.Node) string { - hasher := func(in string) string { - binHash := md5.Sum([]byte(in)) - return hex.EncodeToString(binHash[:]) - } - str := GoFmt(node) - return hasher(str) -} diff --git a/vendor/github.com/mgechev/revive/internal/ifelse/args.go b/vendor/github.com/mgechev/revive/internal/ifelse/args.go deleted file mode 100644 index 288a8e6300..0000000000 --- a/vendor/github.com/mgechev/revive/internal/ifelse/args.go +++ /dev/null @@ -1,8 +0,0 @@ -package ifelse - -// Args contains arguments common to the early-return, indent-error-flow, -// and superfluous-else rules. -type Args struct { - PreserveScope bool - AllowJump bool -} diff --git a/vendor/github.com/mgechev/revive/internal/ifelse/branch.go b/vendor/github.com/mgechev/revive/internal/ifelse/branch.go deleted file mode 100644 index 5183627810..0000000000 --- a/vendor/github.com/mgechev/revive/internal/ifelse/branch.go +++ /dev/null @@ -1,117 +0,0 @@ -package ifelse - -import ( - "fmt" - "go/ast" - "go/token" -) - -// Branch contains information about a branch within an if-else chain. -type Branch struct { - BranchKind - Call // The function called at the end for kind Panic or Exit. - block []ast.Stmt -} - -// BlockBranch gets the Branch of an ast.BlockStmt. -func BlockBranch(block *ast.BlockStmt) Branch { - blockLen := len(block.List) - if blockLen == 0 { - return Empty.Branch() - } - - branch := StmtBranch(block.List[blockLen-1]) - branch.block = block.List - return branch -} - -// StmtBranch gets the Branch of an ast.Stmt. -func StmtBranch(stmt ast.Stmt) Branch { - switch stmt := stmt.(type) { - case *ast.ReturnStmt: - return Return.Branch() - case *ast.BlockStmt: - return BlockBranch(stmt) - case *ast.BranchStmt: - switch stmt.Tok { - case token.BREAK: - return Break.Branch() - case token.CONTINUE: - return Continue.Branch() - case token.GOTO: - return Goto.Branch() - } - case *ast.ExprStmt: - fn, ok := ExprCall(stmt) - if !ok { - break - } - kind, ok := DeviatingFuncs[fn] - if ok { - return Branch{BranchKind: kind, Call: fn} - } - case *ast.EmptyStmt: - return Empty.Branch() - case *ast.LabeledStmt: - return StmtBranch(stmt.Stmt) - } - return Regular.Branch() -} - -// String returns a brief string representation. -func (b Branch) String() string { - switch b.BranchKind { - case Empty: - return "{ }" - case Regular: - return "{ ... }" - case Panic, Exit: - return fmt.Sprintf("{ ... %v() }", b.Call) - } - return fmt.Sprintf("{ ... %v }", b.BranchKind) -} - -// LongString returns a longer form string representation. -func (b Branch) LongString() string { - switch b.BranchKind { - case Panic, Exit: - return fmt.Sprintf("call to %v function", b.Call) - } - return b.BranchKind.LongString() -} - -// HasDecls returns whether the branch has any top-level declarations. -func (b Branch) HasDecls() bool { - for _, stmt := range b.block { - switch stmt := stmt.(type) { - case *ast.DeclStmt: - return true - case *ast.AssignStmt: - if stmt.Tok == token.DEFINE { - return true - } - } - } - return false -} - -// IsShort returns whether the branch is empty or consists of a single statement. -func (b Branch) IsShort() bool { - switch len(b.block) { - case 0: - return true - case 1: - return isShortStmt(b.block[0]) - case 2: - return isShortStmt(b.block[1]) - } - return false -} - -func isShortStmt(stmt ast.Stmt) bool { - switch stmt.(type) { - case *ast.BlockStmt, *ast.IfStmt, *ast.SwitchStmt, *ast.TypeSwitchStmt, *ast.SelectStmt, *ast.ForStmt, *ast.RangeStmt: - return false - } - return true -} diff --git a/vendor/github.com/mgechev/revive/internal/ifelse/branch_kind.go b/vendor/github.com/mgechev/revive/internal/ifelse/branch_kind.go deleted file mode 100644 index 3f6c769961..0000000000 --- a/vendor/github.com/mgechev/revive/internal/ifelse/branch_kind.go +++ /dev/null @@ -1,96 +0,0 @@ -package ifelse - -// BranchKind is a classifier for if-else branches. It says whether the branch is empty, -// and whether the branch ends with a statement that deviates control flow. -type BranchKind int - -const ( - // Empty branches do nothing. - Empty BranchKind = iota - - // Return branches return from the current function. - Return - - // Continue branches continue a surrounding "for" loop. - Continue - - // Break branches break a surrounding "for" loop. - Break - - // Goto branches conclude with a "goto" statement. - Goto - - // Panic branches panic the current function. - Panic - - // Exit branches end the program. - Exit - - // Regular branches do not fit any category above. - Regular -) - -// IsEmpty tests if the branch is empty. -func (k BranchKind) IsEmpty() bool { return k == Empty } - -// Returns tests if the branch returns from the current function. -func (k BranchKind) Returns() bool { return k == Return } - -// Deviates tests if the control does not flow to the first -// statement following the if-else chain. -func (k BranchKind) Deviates() bool { - switch k { - case Empty, Regular: - return false - case Return, Continue, Break, Goto, Panic, Exit: - return true - } - panic("invalid kind") -} - -// Branch returns a Branch with the given kind. -func (k BranchKind) Branch() Branch { return Branch{BranchKind: k} } - -// String returns a brief string representation. -func (k BranchKind) String() string { - switch k { - case Empty, Regular: - return "" - case Return: - return "return" - case Continue: - return "continue" - case Break: - return "break" - case Goto: - return "goto" - case Panic: - return "panic()" - case Exit: - return "os.Exit()" - } - panic("invalid kind") -} - -// LongString returns a longer form string representation. -func (k BranchKind) LongString() string { - switch k { - case Empty: - return "an empty block" - case Regular: - return "a regular statement" - case Return: - return "a return statement" - case Continue: - return "a continue statement" - case Break: - return "a break statement" - case Goto: - return "a goto statement" - case Panic: - return "a function call that panics" - case Exit: - return "a function call that exits the program" - } - panic("invalid kind") -} diff --git a/vendor/github.com/mgechev/revive/internal/ifelse/chain.go b/vendor/github.com/mgechev/revive/internal/ifelse/chain.go deleted file mode 100644 index e3c8898ceb..0000000000 --- a/vendor/github.com/mgechev/revive/internal/ifelse/chain.go +++ /dev/null @@ -1,12 +0,0 @@ -package ifelse - -// Chain contains information about an if-else chain. -type Chain struct { - If Branch // what happens at the end of the "if" block - HasElse bool // is there an "else" block? - Else Branch // what happens at the end of the "else" block - HasInitializer bool // is there an "if"-initializer somewhere in the chain? - HasPriorNonDeviating bool // is there a prior "if" block that does NOT deviate control flow? - AtBlockEnd bool // whether the chain is placed at the end of the surrounding block - BlockEndKind BranchKind // control flow at end of surrounding block (e.g. "return" for function body) -} diff --git a/vendor/github.com/mgechev/revive/internal/ifelse/doc.go b/vendor/github.com/mgechev/revive/internal/ifelse/doc.go deleted file mode 100644 index 7461b12aa1..0000000000 --- a/vendor/github.com/mgechev/revive/internal/ifelse/doc.go +++ /dev/null @@ -1,6 +0,0 @@ -// Package ifelse provides helpers for analyzing the control flow in if-else chains, -// presently used by the following rules: -// - early-return -// - indent-error-flow -// - superfluous-else -package ifelse diff --git a/vendor/github.com/mgechev/revive/internal/ifelse/func.go b/vendor/github.com/mgechev/revive/internal/ifelse/func.go deleted file mode 100644 index 89e2511298..0000000000 --- a/vendor/github.com/mgechev/revive/internal/ifelse/func.go +++ /dev/null @@ -1,49 +0,0 @@ -package ifelse - -import ( - "fmt" - "go/ast" -) - -// Call contains the name of a function that deviates control flow. -type Call struct { - Pkg string // The package qualifier of the function, if not built-in. - Name string // The function name. -} - -// DeviatingFuncs lists known control flow deviating function calls. -var DeviatingFuncs = map[Call]BranchKind{ - {"os", "Exit"}: Exit, - {"log", "Fatal"}: Exit, - {"log", "Fatalf"}: Exit, - {"log", "Fatalln"}: Exit, - {"", "panic"}: Panic, - {"log", "Panic"}: Panic, - {"log", "Panicf"}: Panic, - {"log", "Panicln"}: Panic, -} - -// ExprCall gets the Call of an ExprStmt, if any. -func ExprCall(expr *ast.ExprStmt) (Call, bool) { - call, ok := expr.X.(*ast.CallExpr) - if !ok { - return Call{}, false - } - switch v := call.Fun.(type) { - case *ast.Ident: - return Call{Name: v.Name}, true - case *ast.SelectorExpr: - if ident, ok := v.X.(*ast.Ident); ok { - return Call{Name: v.Sel.Name, Pkg: ident.Name}, true - } - } - return Call{}, false -} - -// String returns the function name with package qualifier (if any). -func (f Call) String() string { - if f.Pkg != "" { - return fmt.Sprintf("%s.%s", f.Pkg, f.Name) - } - return f.Name -} diff --git a/vendor/github.com/mgechev/revive/internal/ifelse/rule.go b/vendor/github.com/mgechev/revive/internal/ifelse/rule.go deleted file mode 100644 index 799f8b83d8..0000000000 --- a/vendor/github.com/mgechev/revive/internal/ifelse/rule.go +++ /dev/null @@ -1,136 +0,0 @@ -package ifelse - -import ( - "go/ast" - "go/token" - - "github.com/mgechev/revive/lint" -) - -// CheckFunc evaluates a rule against the given if-else chain and returns a message -// describing the proposed refactor, along with a indicator of whether such a refactor -// could be found. -type CheckFunc func(Chain) (string, bool) - -// Apply evaluates the given Rule on if-else chains found within the given AST, -// and returns the failures. -// -// Note that in if-else chain with multiple "if" blocks, only the *last* one is checked, -// that is to say, given: -// -// if foo { -// ... -// } else if bar { -// ... -// } else { -// ... -// } -// -// Only the block following "bar" is linted. This is because the rules that use this function -// do not presently have anything to say about earlier blocks in the chain. -func Apply(check CheckFunc, node ast.Node, target Target, args Args) []lint.Failure { - v := &visitor{check: check, target: target} - v.args = args - ast.Walk(v, node) - return v.failures -} - -type visitor struct { - failures []lint.Failure - target Target - check CheckFunc - args Args -} - -func (v *visitor) Visit(node ast.Node) ast.Visitor { - switch stmt := node.(type) { - case *ast.FuncDecl: - v.visitBody(stmt.Body, Return) - case *ast.FuncLit: - v.visitBody(stmt.Body, Return) - case *ast.ForStmt: - v.visitBody(stmt.Body, Continue) - case *ast.RangeStmt: - v.visitBody(stmt.Body, Continue) - case *ast.CaseClause: - v.visitBlock(stmt.Body, Break) - case *ast.BlockStmt: - v.visitBlock(stmt.List, Regular) - default: - return v - } - return nil -} - -func (v *visitor) visitBody(body *ast.BlockStmt, endKind BranchKind) { - if body != nil { - v.visitBlock(body.List, endKind) - } -} - -func (v *visitor) visitBlock(stmts []ast.Stmt, endKind BranchKind) { - for i, stmt := range stmts { - ifStmt, ok := stmt.(*ast.IfStmt) - if !ok { - ast.Walk(v, stmt) - continue - } - var chain Chain - if i == len(stmts)-1 { - chain.AtBlockEnd = true - chain.BlockEndKind = endKind - } - v.visitIf(ifStmt, chain) - } -} - -func (v *visitor) visitIf(ifStmt *ast.IfStmt, chain Chain) { - // look for other if-else chains nested inside this if { } block - v.visitBlock(ifStmt.Body.List, chain.BlockEndKind) - - if as, ok := ifStmt.Init.(*ast.AssignStmt); ok && as.Tok == token.DEFINE { - chain.HasInitializer = true - } - chain.If = BlockBranch(ifStmt.Body) - - if ifStmt.Else == nil { - if v.args.AllowJump { - v.checkRule(ifStmt, chain) - } - return - } - - switch elseBlock := ifStmt.Else.(type) { - case *ast.IfStmt: - if !chain.If.Deviates() { - chain.HasPriorNonDeviating = true - } - v.visitIf(elseBlock, chain) - case *ast.BlockStmt: - // look for other if-else chains nested inside this else { } block - v.visitBlock(elseBlock.List, chain.BlockEndKind) - - chain.HasElse = true - chain.Else = BlockBranch(elseBlock) - v.checkRule(ifStmt, chain) - default: - panic("unexpected node type for else") - } -} - -func (v *visitor) checkRule(ifStmt *ast.IfStmt, chain Chain) { - msg, found := v.check(chain) - if !found { - return // passed the check - } - if chain.HasInitializer { - // if statement has a := initializer, so we might need to move the assignment - // onto its own line in case the body references it - msg += " (move short variable declaration to its own line if necessary)" - } - v.failures = append(v.failures, lint.Failure{ - Confidence: 1, - Node: v.target.node(ifStmt), - Failure: msg, - }) -} diff --git a/vendor/github.com/mgechev/revive/internal/ifelse/target.go b/vendor/github.com/mgechev/revive/internal/ifelse/target.go deleted file mode 100644 index d54fc537b9..0000000000 --- a/vendor/github.com/mgechev/revive/internal/ifelse/target.go +++ /dev/null @@ -1,24 +0,0 @@ -package ifelse - -import "go/ast" - -// Target decides what line/column should be indicated by the rule in question. -type Target int - -const ( - // TargetIf means the text refers to the "if". - TargetIf Target = iota - - // TargetElse means the text refers to the "else". - TargetElse -) - -func (t Target) node(ifStmt *ast.IfStmt) ast.Node { - switch t { - case TargetIf: - return ifStmt - case TargetElse: - return ifStmt.Else - } - panic("bad target") -} diff --git a/vendor/github.com/mgechev/revive/internal/rule/name.go b/vendor/github.com/mgechev/revive/internal/rule/name.go deleted file mode 100644 index 60257674aa..0000000000 --- a/vendor/github.com/mgechev/revive/internal/rule/name.go +++ /dev/null @@ -1,135 +0,0 @@ -// Package rule defines utility functions some revive rules can share. -package rule - -import ( - "strings" - "unicode" -) - -// commonInitialisms is a set of common initialisms. -// Only add entries that are highly unlikely to be non-initialisms. -// For instance, "ID" is fine (Freudian code is rare), but "AND" is not. -var commonInitialisms = map[string]bool{ - "ACL": true, - "API": true, - "ASCII": true, - "CPU": true, - "CSS": true, - "DNS": true, - "EOF": true, - "GUID": true, - "HTML": true, - "HTTP": true, - "HTTPS": true, - "ID": true, - "IDS": true, - "IP": true, - "JSON": true, - "LHS": true, - "QPS": true, - "RAM": true, - "RHS": true, - "RPC": true, - "SLA": true, - "SMTP": true, - "SQL": true, - "SSH": true, - "TCP": true, - "TLS": true, - "TTL": true, - "UDP": true, - "UI": true, - "UID": true, - "UUID": true, - "URI": true, - "URL": true, - "UTF8": true, - "VM": true, - "XML": true, - "XMPP": true, - "XSRF": true, - "XSS": true, -} - -// Name returns a different name of struct, var, const, or function if it should be different. -func Name(name string, allowlist, blocklist []string, skipInitialismNameChecks bool) (should string) { - // Fast path for simple cases: "_" and all lowercase. - if name == "_" { - return name - } - allLower := true - for _, r := range name { - if !unicode.IsLower(r) { - allLower = false - break - } - } - if allLower { - return name - } - - // Split camelCase at any lower->upper transition, and split on underscores. - // Check each word for common initialisms. - runes := []rune(name) - w, i := 0, 0 // index of start of word, scan - for i+1 <= len(runes) { - eow := false // whether we hit the end of a word - switch { - case i+1 == len(runes): - eow = true - case runes[i+1] == '_': - // underscore; shift the remainder forward over any run of underscores - eow = true - n := 1 - for i+n+1 < len(runes) && runes[i+n+1] == '_' { - n++ - } - - // Leave at most one underscore if the underscore is between two digits - if i+n+1 < len(runes) && unicode.IsDigit(runes[i]) && unicode.IsDigit(runes[i+n+1]) { - n-- - } - - copy(runes[i+1:], runes[i+n+1:]) - runes = runes[:len(runes)-n] - case unicode.IsLower(runes[i]) && !unicode.IsLower(runes[i+1]): - // lower->non-lower - eow = true - } - i++ - if !eow { - continue - } - - // [w,i) is a word. - word := string(runes[w:i]) - ignoreInitWarnings := map[string]bool{} - for _, i := range allowlist { - ignoreInitWarnings[i] = true - } - - extraInits := map[string]bool{} - for _, i := range blocklist { - extraInits[i] = true - } - - if u := strings.ToUpper(word); !skipInitialismNameChecks && (commonInitialisms[u] || extraInits[u]) && !ignoreInitWarnings[u] { - // Keep consistent case, which is lowercase only at the start. - if w == 0 && unicode.IsLower(runes[w]) { - u = strings.ToLower(u) - } - // Keep lowercase s for IDs - if u == "IDS" { - u = "IDs" - } - // All the common initialisms are ASCII, - // so we can replace the bytes exactly. - copy(runes[w:], []rune(u)) - } else if w > 0 && strings.ToLower(word) == word { - // already all lowercase, and not the first word, so uppercase the first character. - runes[w] = unicode.ToUpper(runes[w]) - } - w = i - } - return string(runes) -} diff --git a/vendor/github.com/mgechev/revive/internal/typeparams/typeparams.go b/vendor/github.com/mgechev/revive/internal/typeparams/typeparams.go deleted file mode 100644 index e3e0ecd771..0000000000 --- a/vendor/github.com/mgechev/revive/internal/typeparams/typeparams.go +++ /dev/null @@ -1,31 +0,0 @@ -// Package typeparams provides utilities for working with Go ASTs with support -// for type parameters when built with Go 1.18 and higher. -package typeparams - -import ( - "go/ast" -) - -// ReceiverType returns the named type of the method receiver, sans "*" and type -// parameters, or "invalid-type" if fn.Recv is ill formed. -func ReceiverType(fn *ast.FuncDecl) string { - e := fn.Recv.List[0].Type - if s, ok := e.(*ast.StarExpr); ok { - e = s.X - } - e = unpackIndexExpr(e) - if id, ok := e.(*ast.Ident); ok { - return id.Name - } - return "invalid-type" -} - -func unpackIndexExpr(e ast.Expr) ast.Expr { - switch e := e.(type) { - case *ast.IndexExpr: - return e.X - case *ast.IndexListExpr: - return e.X - } - return e -} diff --git a/vendor/github.com/mgechev/revive/lint/config.go b/vendor/github.com/mgechev/revive/lint/config.go deleted file mode 100644 index ae9a20a7cf..0000000000 --- a/vendor/github.com/mgechev/revive/lint/config.go +++ /dev/null @@ -1,71 +0,0 @@ -package lint - -import ( - goversion "github.com/hashicorp/go-version" -) - -// Arguments is type used for the arguments of a rule. -type Arguments = []any - -// FileFilters is type used for modeling file filters to apply to rules. -type FileFilters = []*FileFilter - -// RuleConfig is type used for the rule configuration. -type RuleConfig struct { - Arguments Arguments - Severity Severity - Disabled bool - // Exclude - rule-level file excludes, TOML related (strings) - Exclude []string - // excludeFilters - regex-based file filters, initialized from Exclude - excludeFilters []*FileFilter -} - -// Initialize should be called after reading from TOML file. -func (rc *RuleConfig) Initialize() error { - for _, f := range rc.Exclude { - ff, err := ParseFileFilter(f) - if err != nil { - return err - } - rc.excludeFilters = append(rc.excludeFilters, ff) - } - return nil -} - -// RulesConfig defines the config for all rules. -type RulesConfig = map[string]RuleConfig - -// MustExclude checks if given filename `name` must be excluded. -func (rc *RuleConfig) MustExclude(name string) bool { - for _, exclude := range rc.excludeFilters { - if exclude.MatchFileName(name) { - return true - } - } - return false -} - -// DirectiveConfig is type used for the linter directive configuration. -type DirectiveConfig struct { - Severity Severity -} - -// DirectivesConfig defines the config for all directives. -type DirectivesConfig = map[string]DirectiveConfig - -// Config defines the config of the linter. -type Config struct { - IgnoreGeneratedHeader bool `toml:"ignoreGeneratedHeader"` - Confidence float64 `toml:"confidence"` - Severity Severity `toml:"severity"` - EnableAllRules bool `toml:"enableAllRules"` - Rules RulesConfig `toml:"rule"` - ErrorCode int `toml:"errorCode"` - WarningCode int `toml:"warningCode"` - Directives DirectivesConfig `toml:"directive"` - Exclude []string `toml:"exclude"` - // If set, overrides the go language version specified in go.mod of - // packages being linted, and assumes this specific language version. - GoVersion *goversion.Version `toml:"goVersion"` -} diff --git a/vendor/github.com/mgechev/revive/lint/doc.go b/vendor/github.com/mgechev/revive/lint/doc.go deleted file mode 100644 index 7048adf4b6..0000000000 --- a/vendor/github.com/mgechev/revive/lint/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package lint implements the linting machinery. -package lint diff --git a/vendor/github.com/mgechev/revive/lint/failure.go b/vendor/github.com/mgechev/revive/lint/failure.go deleted file mode 100644 index d9ff93e823..0000000000 --- a/vendor/github.com/mgechev/revive/lint/failure.go +++ /dev/null @@ -1,106 +0,0 @@ -package lint - -import ( - "go/ast" - "go/token" -) - -const ( - // FailureCategoryArgOrder indicates argument order issues. - FailureCategoryArgOrder FailureCategory = "arg-order" - // FailureCategoryBadPractice indicates bad practice issues. - FailureCategoryBadPractice FailureCategory = "bad practice" - // FailureCategoryCodeStyle indicates code style issues. - FailureCategoryCodeStyle FailureCategory = "code-style" - // FailureCategoryComments indicates comment issues. - FailureCategoryComments FailureCategory = "comments" - // FailureCategoryComplexity indicates complexity issues. - FailureCategoryComplexity FailureCategory = "complexity" - // FailureCategoryContent indicates content issues. - FailureCategoryContent FailureCategory = "content" - // FailureCategoryErrors indicates error handling issues. - FailureCategoryErrors FailureCategory = "errors" - // FailureCategoryImports indicates import issues. - FailureCategoryImports FailureCategory = "imports" - // FailureCategoryLogic indicates logic issues. - FailureCategoryLogic FailureCategory = "logic" - // FailureCategoryMaintenance indicates maintenance issues. - FailureCategoryMaintenance FailureCategory = "maintenance" - // FailureCategoryNaming indicates naming issues. - FailureCategoryNaming FailureCategory = "naming" - // FailureCategoryOptimization indicates optimization issues. - FailureCategoryOptimization FailureCategory = "optimization" - // FailureCategoryStyle indicates style issues. - FailureCategoryStyle FailureCategory = "style" - // FailureCategoryTime indicates time-related issues. - FailureCategoryTime FailureCategory = "time" - // FailureCategoryTypeInference indicates type inference issues. - FailureCategoryTypeInference FailureCategory = "type-inference" - // FailureCategoryUnaryOp indicates unary operation issues. - FailureCategoryUnaryOp FailureCategory = "unary-op" - // FailureCategoryUnexportedTypeInAPI indicates unexported type in API issues. - FailureCategoryUnexportedTypeInAPI FailureCategory = "unexported-type-in-api" - // FailureCategoryZeroValue indicates zero value issues. - FailureCategoryZeroValue FailureCategory = "zero-value" - - // failureCategoryInternal indicates internal failures. - failureCategoryInternal FailureCategory = "REVIVE_INTERNAL" - // failureCategoryValidity indicates validity issues. - failureCategoryValidity FailureCategory = "validity" -) - -// FailureCategory is the type for the failure categories. -type FailureCategory string - -const ( - // SeverityWarning declares failures of type warning. - SeverityWarning = "warning" - // SeverityError declares failures of type error. - SeverityError = "error" -) - -// Severity is the type for the failure types. -type Severity string - -// FailurePosition returns the failure position. -type FailurePosition struct { - Start token.Position `json:"Start"` - End token.Position `json:"End"` -} - -// Failure defines a struct for a linting failure. -type Failure struct { - Failure string `json:"Failure"` - RuleName string `json:"RuleName"` - Category FailureCategory `json:"Category"` - Position FailurePosition `json:"Position"` - Node ast.Node `json:"-"` - Confidence float64 `json:"Confidence"` - // For future use - ReplacementLine string `json:"ReplacementLine"` -} - -// GetFilename returns the filename. -// -// Deprecated: Use [Filename]. -func (f *Failure) GetFilename() string { - return f.Filename() -} - -// Filename returns the filename. -func (f *Failure) Filename() string { - return f.Position.Start.Filename -} - -// IsInternal returns true if this failure is internal, false otherwise. -func (f *Failure) IsInternal() bool { - return f.Category == failureCategoryInternal -} - -// NewInternalFailure yields an internal failure with the given message as failure message. -func NewInternalFailure(message string) Failure { - return Failure{ - Category: failureCategoryInternal, - Failure: message, - } -} diff --git a/vendor/github.com/mgechev/revive/lint/file.go b/vendor/github.com/mgechev/revive/lint/file.go deleted file mode 100644 index bf6aed452a..0000000000 --- a/vendor/github.com/mgechev/revive/lint/file.go +++ /dev/null @@ -1,303 +0,0 @@ -package lint - -import ( - "bytes" - "errors" - "go/ast" - "go/parser" - "go/printer" - "go/token" - "go/types" - "math" - "regexp" - "strings" -) - -// File abstraction used for representing files. -type File struct { - Name string - Pkg *Package - content []byte - AST *ast.File -} - -// IsTest returns if the file contains tests. -func (f *File) IsTest() bool { return strings.HasSuffix(f.Name, "_test.go") } - -// IsImportable returns if the symbols defined in this file can be imported in other packages. -// -// Symbols from the package `main` or test files are not exported, so they cannot be imported. -func (f *File) IsImportable() bool { - if f.IsTest() { - // Test files cannot be imported. - return false - } - - if f.Pkg.IsMain() { - // The package `main` cannot be imported. - return false - } - - return true -} - -// Content returns the file's content. -func (f *File) Content() []byte { - return f.content -} - -// NewFile creates a new file. -func NewFile(name string, content []byte, pkg *Package) (*File, error) { - f, err := parser.ParseFile(pkg.fset, name, content, parser.ParseComments) - if err != nil { - return nil, err - } - return &File{ - Name: name, - content: content, - Pkg: pkg, - AST: f, - }, nil -} - -// ToPosition returns line and column for given position. -func (f *File) ToPosition(pos token.Pos) token.Position { - return f.Pkg.fset.Position(pos) -} - -// Render renders a node. -func (f *File) Render(x any) string { - var buf bytes.Buffer - if err := printer.Fprint(&buf, f.Pkg.fset, x); err != nil { - panic(err) - } - return buf.String() -} - -// CommentMap builds a comment map for the file. -func (f *File) CommentMap() ast.CommentMap { - return ast.NewCommentMap(f.Pkg.fset, f.AST, f.AST.Comments) -} - -var basicTypeKinds = map[types.BasicKind]string{ - types.UntypedBool: "bool", - types.UntypedInt: "int", - types.UntypedRune: "rune", - types.UntypedFloat: "float64", - types.UntypedComplex: "complex128", - types.UntypedString: "string", -} - -// IsUntypedConst reports whether expr is an untyped constant, -// and indicates what its default type is. -// Scope may be nil. -func (f *File) IsUntypedConst(expr ast.Expr) (defType string, ok bool) { - // Re-evaluate expr outside its context to see if it's untyped. - // (An expr evaluated within, for example, an assignment context will get the type of the LHS.) - exprStr := f.Render(expr) - tv, err := types.Eval(f.Pkg.fset, f.Pkg.TypesPkg(), expr.Pos(), exprStr) - if err != nil { - return "", false - } - if b, ok := tv.Type.(*types.Basic); ok { - if dt, ok := basicTypeKinds[b.Kind()]; ok { - return dt, true - } - } - - return "", false -} - -func (f *File) isMain() bool { - return f.AST.Name.Name == "main" -} - -const directiveSpecifyDisableReason = "specify-disable-reason" - -func (f *File) lint(rules []Rule, config Config, failures chan Failure) error { - rulesConfig := config.Rules - _, mustSpecifyDisableReason := config.Directives[directiveSpecifyDisableReason] - disabledIntervals := f.disabledIntervals(rules, mustSpecifyDisableReason, failures) - for _, currentRule := range rules { - ruleConfig := rulesConfig[currentRule.Name()] - if ruleConfig.MustExclude(f.Name) { - continue - } - currentFailures := currentRule.Apply(f, ruleConfig.Arguments) - for idx, failure := range currentFailures { - if failure.IsInternal() { - return errors.New(failure.Failure) - } - - if failure.RuleName == "" { - failure.RuleName = currentRule.Name() - } - if failure.Node != nil { - failure.Position = ToFailurePosition(failure.Node.Pos(), failure.Node.End(), f) - } - currentFailures[idx] = failure - } - currentFailures = f.filterFailures(currentFailures, disabledIntervals) - for _, failure := range currentFailures { - if failure.Confidence >= config.Confidence { - failures <- failure - } - } - } - return nil -} - -type enableDisableConfig struct { - enabled bool - position int -} - -type disabledIntervalsMap = map[string][]DisabledInterval - -const ( - directivePos = 1 - modifierPos = 2 - rulesPos = 3 - reasonPos = 4 -) - -var directiveRegexp = regexp.MustCompile(`^//[\s]*revive:(enable|disable)(?:-(line|next-line))?(?::([^\s]+))?[\s]*(?: (.+))?$`) - -func (f *File) disabledIntervals(rules []Rule, mustSpecifyDisableReason bool, failures chan Failure) disabledIntervalsMap { - enabledDisabledRulesMap := map[string][]enableDisableConfig{} - - getEnabledDisabledIntervals := func() disabledIntervalsMap { - result := disabledIntervalsMap{} - - for ruleName, disabledArr := range enabledDisabledRulesMap { - ruleResult := []DisabledInterval{} - for i := range disabledArr { - interval := DisabledInterval{ - RuleName: ruleName, - From: token.Position{ - Filename: f.Name, - Line: disabledArr[i].position, - }, - To: token.Position{ - Filename: f.Name, - Line: math.MaxInt32, - }, - } - if i%2 == 0 { - ruleResult = append(ruleResult, interval) - } else { - ruleResult[len(ruleResult)-1].To.Line = disabledArr[i].position - } - } - result[ruleName] = ruleResult - } - - return result - } - - handleConfig := func(isEnabled bool, line int, name string) { - existing, ok := enabledDisabledRulesMap[name] - if !ok { - existing = []enableDisableConfig{} - enabledDisabledRulesMap[name] = existing - } - if (len(existing) > 1 && existing[len(existing)-1].enabled == isEnabled) || - (len(existing) == 0 && isEnabled) { - return - } - existing = append(existing, enableDisableConfig{ - enabled: isEnabled, - position: line, - }) - enabledDisabledRulesMap[name] = existing - } - - handleRules := func(modifier string, isEnabled bool, line int, ruleNames []string) { - for _, name := range ruleNames { - switch modifier { - case "line": - handleConfig(isEnabled, line, name) - handleConfig(!isEnabled, line, name) - case "next-line": - handleConfig(isEnabled, line+1, name) - handleConfig(!isEnabled, line+1, name) - default: - handleConfig(isEnabled, line, name) - } - } - } - - handleComment := func(c *ast.CommentGroup, line int) { - comments := c.List - for _, c := range comments { - match := directiveRegexp.FindStringSubmatch(c.Text) - if len(match) == 0 { - continue - } - ruleNames := []string{} - tempNames := strings.Split(match[rulesPos], ",") - - for _, name := range tempNames { - name = strings.Trim(name, "\n") - if name != "" { - ruleNames = append(ruleNames, name) - } - } - - mustCheckDisablingReason := mustSpecifyDisableReason && match[directivePos] == "disable" - if mustCheckDisablingReason && strings.Trim(match[reasonPos], " ") == "" { - failures <- Failure{ - Confidence: 1, - RuleName: directiveSpecifyDisableReason, - Failure: "reason of lint disabling not found", - Position: ToFailurePosition(c.Pos(), c.End(), f), - Node: c, - } - continue // skip this linter disabling directive - } - - // TODO: optimize - if len(ruleNames) == 0 { - for _, rule := range rules { - ruleNames = append(ruleNames, rule.Name()) - } - } - - handleRules(match[modifierPos], match[directivePos] == "enable", line, ruleNames) - } - } - - for _, c := range f.AST.Comments { - handleComment(c, f.ToPosition(c.End()).Line) - } - - return getEnabledDisabledIntervals() -} - -func (File) filterFailures(failures []Failure, disabledIntervals disabledIntervalsMap) []Failure { - result := []Failure{} - for _, failure := range failures { - fStart := failure.Position.Start.Line - fEnd := failure.Position.End.Line - intervals, ok := disabledIntervals[failure.RuleName] - if !ok { - result = append(result, failure) - continue - } - - include := true - for _, interval := range intervals { - intStart := interval.From.Line - intEnd := interval.To.Line - if (fStart >= intStart && fStart <= intEnd) || - (fEnd >= intStart && fEnd <= intEnd) { - include = false - break - } - } - if include { - result = append(result, failure) - } - } - return result -} diff --git a/vendor/github.com/mgechev/revive/lint/filefilter.go b/vendor/github.com/mgechev/revive/lint/filefilter.go deleted file mode 100644 index 9978597f30..0000000000 --- a/vendor/github.com/mgechev/revive/lint/filefilter.go +++ /dev/null @@ -1,130 +0,0 @@ -package lint - -import ( - "fmt" - "regexp" - "strings" -) - -// FileFilter filters file to exclude some files for a rule. -// Supports the following: -// - File or directory names: pkg/mypkg/my.go -// - Globs: **/*.pb.go, -// - Regexes (with ~ prefix): ~-tmp\.\d+\.go -// - Special test marker `TEST` (treated as `~_test\.go`). -type FileFilter struct { - // raw definition of filter inside config - raw string - // don't care what was at start, will use regexes inside - rx *regexp.Regexp - // marks filter as matching everything - matchesAll bool - // marks filter as matching nothing - matchesNothing bool -} - -// ParseFileFilter creates a [FileFilter] for the given raw filter. -// If the string is empty, it matches nothing. -// If the string is `*` or `~`, it matches everything. -// If the regular expression is invalid, it returns a compilation error. -func ParseFileFilter(rawFilter string) (*FileFilter, error) { - rawFilter = strings.TrimSpace(rawFilter) - result := new(FileFilter) - result.raw = rawFilter - result.matchesNothing = result.raw == "" - result.matchesAll = result.raw == "*" || result.raw == "~" - if !result.matchesAll && !result.matchesNothing { - if err := result.prepareRegexp(); err != nil { - return nil, err - } - } - return result, nil -} - -func (ff *FileFilter) String() string { return ff.raw } - -// MatchFileName checks if the file name matches the filter. -func (ff *FileFilter) MatchFileName(name string) bool { - if ff.matchesAll { - return true - } - if ff.matchesNothing { - return false - } - name = strings.ReplaceAll(name, "\\", "/") - return ff.rx.MatchString(name) -} - -var ( - fileFilterInvalidGlobRegexp = regexp.MustCompile(`[^/]\*\*[^/]`) - escapeRegexSymbols = ".+{}()[]^$" -) - -func (ff *FileFilter) prepareRegexp() error { - var err error - src := ff.raw - if src == "TEST" { - src = "~_test\\.go" - } - if strings.HasPrefix(src, "~") { - ff.rx, err = regexp.Compile(src[1:]) - if err != nil { - return fmt.Errorf("invalid file filter [%s], regexp compile error: [%w]", ff.raw, err) - } - return nil - } - /* globs */ - if strings.Contains(src, "*") { - if fileFilterInvalidGlobRegexp.MatchString(src) { - return fmt.Errorf("invalid file filter [%s], invalid glob pattern", ff.raw) - } - var rxBuild strings.Builder - rxBuild.WriteByte('^') - wasStar := false - justDirGlob := false - for _, c := range src { - if c == '*' { - if wasStar { - rxBuild.WriteString(`[\s\S]*`) - wasStar = false - justDirGlob = true - continue - } - wasStar = true - continue - } - if wasStar { - rxBuild.WriteString("[^/]*") - wasStar = false - } - if strings.ContainsRune(escapeRegexSymbols, c) { - rxBuild.WriteByte('\\') - } - rxBuild.WriteRune(c) - if c == '/' && justDirGlob { - rxBuild.WriteRune('?') - } - justDirGlob = false - } - if wasStar { - rxBuild.WriteString("[^/]*") - } - rxBuild.WriteByte('$') - ff.rx, err = regexp.Compile(rxBuild.String()) - if err != nil { - return fmt.Errorf("invalid file filter [%s], regexp compile error after glob expand: [%w]", ff.raw, err) - } - return nil - } - - // it's whole file mask, just escape dots and normalize separators - fillRx := src - fillRx = strings.ReplaceAll(fillRx, "\\", "/") - fillRx = strings.ReplaceAll(fillRx, ".", `\.`) - fillRx = "^" + fillRx + "$" - ff.rx, err = regexp.Compile(fillRx) - if err != nil { - return fmt.Errorf("invalid file filter [%s], regexp compile full path: [%w]", ff.raw, err) - } - return nil -} diff --git a/vendor/github.com/mgechev/revive/lint/formatter.go b/vendor/github.com/mgechev/revive/lint/formatter.go deleted file mode 100644 index c770fdf2d4..0000000000 --- a/vendor/github.com/mgechev/revive/lint/formatter.go +++ /dev/null @@ -1,14 +0,0 @@ -package lint - -// FormatterMetadata configuration of a formatter. -type FormatterMetadata struct { - Name string - Description string - Sample string -} - -// Formatter defines an interface for failure formatters. -type Formatter interface { - Format(<-chan Failure, Config) (string, error) - Name() string -} diff --git a/vendor/github.com/mgechev/revive/lint/linter.go b/vendor/github.com/mgechev/revive/lint/linter.go deleted file mode 100644 index 2abbb699d4..0000000000 --- a/vendor/github.com/mgechev/revive/lint/linter.go +++ /dev/null @@ -1,258 +0,0 @@ -package lint - -import ( - "bufio" - "bytes" - "fmt" - "go/token" - "os" - "path/filepath" - "regexp" - "strconv" - "strings" - - goversion "github.com/hashicorp/go-version" - "golang.org/x/mod/modfile" - "golang.org/x/sync/errgroup" -) - -// ReadFile defines an abstraction for reading files. -type ReadFile func(path string) (result []byte, err error) - -// Linter is used for linting set of files. -type Linter struct { - reader ReadFile - fileReadTokens chan struct{} -} - -// New creates a new Linter. -func New(reader ReadFile, maxOpenFiles int) Linter { - var fileReadTokens chan struct{} - if maxOpenFiles > 0 { - fileReadTokens = make(chan struct{}, maxOpenFiles) - } - return Linter{ - reader: reader, - fileReadTokens: fileReadTokens, - } -} - -func (l Linter) readFile(path string) (result []byte, err error) { - if l.fileReadTokens != nil { - // "take" a token by writing to the channel. - // It will block if no more space in the channel's buffer - l.fileReadTokens <- struct{}{} - defer func() { - // "free" a token by reading from the channel - <-l.fileReadTokens - }() - } - - return l.reader(path) -} - -var ( - generatedPrefix = []byte("// Code generated ") - generatedSuffix = []byte(" DO NOT EDIT.") - defaultGoVersion = goversion.Must(goversion.NewVersion("1.0")) -) - -// Lint lints a set of files with the specified rule. -func (l *Linter) Lint(packages [][]string, ruleSet []Rule, config Config) (<-chan Failure, error) { - failures := make(chan Failure) - - perModVersions := map[string]*goversion.Version{} - perPkgVersions := make([]*goversion.Version, len(packages)) - for n, files := range packages { - if len(files) == 0 { - continue - } - if config.GoVersion != nil { - perPkgVersions[n] = config.GoVersion - continue - } - - dir, err := filepath.Abs(filepath.Dir(files[0])) - if err != nil { - return nil, err - } - - alreadyKnownMod := false - for d, v := range perModVersions { - if strings.HasPrefix(dir, d) { - perPkgVersions[n] = v - alreadyKnownMod = true - break - } - } - if alreadyKnownMod { - continue - } - - d, v, err := detectGoMod(dir) - if err != nil { - // No luck finding the go.mod file thus set the default Go version - v = defaultGoVersion - d = dir - } - perModVersions[d] = v - perPkgVersions[n] = v - } - - var wg errgroup.Group - for n := range packages { - wg.Go(func() error { - pkg := packages[n] - gover := perPkgVersions[n] - if err := l.lintPackage(pkg, gover, ruleSet, config, failures); err != nil { - return fmt.Errorf("error during linting: %w", err) - } - return nil - }) - } - - go func() { - err := wg.Wait() - if err != nil { - failures <- NewInternalFailure(err.Error()) - } - close(failures) - }() - - return failures, nil -} - -func (l *Linter) lintPackage(filenames []string, gover *goversion.Version, ruleSet []Rule, config Config, failures chan Failure) error { - if len(filenames) == 0 { - return nil - } - - pkg := &Package{ - fset: token.NewFileSet(), - files: map[string]*File{}, - goVersion: gover, - } - for _, filename := range filenames { - content, err := l.readFile(filename) - if err != nil { - return err - } - if !config.IgnoreGeneratedHeader && isGenerated(content) { - continue - } - - file, err := NewFile(filename, content, pkg) - if err != nil { - addInvalidFileFailure(filename, err.Error(), failures) - continue - } - pkg.files[filename] = file - } - - if len(pkg.files) == 0 { - return nil - } - - return pkg.lint(ruleSet, config, failures) -} - -func detectGoMod(dir string) (rootDir string, ver *goversion.Version, err error) { - modFileName, err := retrieveModFile(dir) - if err != nil { - return "", nil, fmt.Errorf("%q doesn't seem to be part of a Go module", dir) - } - - mod, err := os.ReadFile(modFileName) - if err != nil { - return "", nil, fmt.Errorf("failed to read %q, got %w", modFileName, err) - } - - modAst, err := modfile.ParseLax(modFileName, mod, nil) - if err != nil { - return "", nil, fmt.Errorf("failed to parse %q, got %w", modFileName, err) - } - - if modAst.Go == nil { - return "", nil, fmt.Errorf("%q does not specify a Go version", modFileName) - } - - ver, err = goversion.NewVersion(modAst.Go.Version) - return filepath.Dir(modFileName), ver, err -} - -func retrieveModFile(dir string) (string, error) { - const lookingForFile = "go.mod" - for { - // filepath.Dir returns 'C:\' on Windows, and '/' on Unix - isRootDir := (dir == filepath.VolumeName(dir)+string(filepath.Separator)) - if dir == "." || isRootDir { - return "", fmt.Errorf("did not found %q file", lookingForFile) - } - - lookingForFilePath := filepath.Join(dir, lookingForFile) - info, err := os.Stat(lookingForFilePath) - if err != nil || info.IsDir() { - // lets check the parent dir - dir = filepath.Dir(dir) - continue - } - - return lookingForFilePath, nil - } -} - -// isGenerated reports whether the source file is generated code -// according the rules from https://golang.org/s/generatedcode. -// This is inherited from the original go lint. -func isGenerated(src []byte) bool { - sc := bufio.NewScanner(bytes.NewReader(src)) - for sc.Scan() { - b := sc.Bytes() - if bytes.HasPrefix(b, generatedPrefix) && bytes.HasSuffix(b, generatedSuffix) && len(b) >= len(generatedPrefix)+len(generatedSuffix) { - return true - } - } - return false -} - -// addInvalidFileFailure adds a failure for an invalid formatted file. -func addInvalidFileFailure(filename, errStr string, failures chan Failure) { - position := getPositionInvalidFile(filename, errStr) - failures <- Failure{ - Confidence: 1, - Failure: fmt.Sprintf("invalid file %s: %v", filename, errStr), - Category: failureCategoryValidity, - Position: position, - } -} - -// errPosRegexp matches with a NewFile error message: -// -// corrupted.go:10:4: expected '}', found 'EOF -// -// The first group matches the line, and the second group matches the column. -var errPosRegexp = regexp.MustCompile(`.*:(\d*):(\d*):.*$`) - -// getPositionInvalidFile gets the position of the error in an invalid file. -func getPositionInvalidFile(filename, s string) FailurePosition { - pos := errPosRegexp.FindStringSubmatch(s) - if len(pos) < 3 { - return FailurePosition{} - } - line, err := strconv.Atoi(pos[1]) - if err != nil { - return FailurePosition{} - } - column, err := strconv.Atoi(pos[2]) - if err != nil { - return FailurePosition{} - } - - return FailurePosition{ - Start: token.Position{ - Filename: filename, - Line: line, - Column: column, - }, - } -} diff --git a/vendor/github.com/mgechev/revive/lint/name.go b/vendor/github.com/mgechev/revive/lint/name.go deleted file mode 100644 index 23ca06c22f..0000000000 --- a/vendor/github.com/mgechev/revive/lint/name.go +++ /dev/null @@ -1,10 +0,0 @@ -package lint - -import "github.com/mgechev/revive/internal/rule" - -// Name returns a different name if it should be different. -// -// Deprecated: Do not use this function, it will be removed in the next major release. -func Name(name string, allowlist, blocklist []string) string { - return rule.Name(name, allowlist, blocklist, false) -} diff --git a/vendor/github.com/mgechev/revive/lint/package.go b/vendor/github.com/mgechev/revive/lint/package.go deleted file mode 100644 index cb78cb452d..0000000000 --- a/vendor/github.com/mgechev/revive/lint/package.go +++ /dev/null @@ -1,237 +0,0 @@ -package lint - -import ( - "errors" - "go/ast" - "go/importer" - "go/token" - "go/types" - "sync" - - goversion "github.com/hashicorp/go-version" - "golang.org/x/sync/errgroup" - - "github.com/mgechev/revive/internal/astutils" - "github.com/mgechev/revive/internal/typeparams" -) - -// Package represents a package in the project. -type Package struct { - fset *token.FileSet - - mu sync.RWMutex - files map[string]*File - goVersion *goversion.Version - typesPkg *types.Package - typesInfo *types.Info - // sortable is the set of types in the package that implement sort.Interface. - sortable map[string]bool - // main is whether this is a "main" package. - main int -} - -var ( - trueValue = 1 - falseValue = 2 - - // Go115 is a constant representing the Go version 1.15. - Go115 = goversion.Must(goversion.NewVersion("1.15")) - // Go121 is a constant representing the Go version 1.21. - Go121 = goversion.Must(goversion.NewVersion("1.21")) - // Go122 is a constant representing the Go version 1.22. - Go122 = goversion.Must(goversion.NewVersion("1.22")) - // Go124 is a constant representing the Go version 1.24. - Go124 = goversion.Must(goversion.NewVersion("1.24")) - // Go125 is a constant representing the Go version 1.25. - Go125 = goversion.Must(goversion.NewVersion("1.25")) -) - -// Files return package's files. -func (p *Package) Files() map[string]*File { - p.mu.RLock() - defer p.mu.RUnlock() - - return p.files -} - -// IsMain returns if that's the main package. -func (p *Package) IsMain() bool { - p.mu.Lock() - defer p.mu.Unlock() - - switch p.main { - case trueValue: - return true - case falseValue: - return false - } - for _, f := range p.files { - if f.isMain() { - p.main = trueValue - return true - } - } - p.main = falseValue - return false -} - -// TypesPkg yields information on this package. -func (p *Package) TypesPkg() *types.Package { - p.mu.RLock() - defer p.mu.RUnlock() - - return p.typesPkg -} - -// TypesInfo yields type information of this package identifiers. -func (p *Package) TypesInfo() *types.Info { - p.mu.RLock() - defer p.mu.RUnlock() - - return p.typesInfo -} - -// Sortable yields a map of sortable types in this package. -func (p *Package) Sortable() map[string]bool { - p.mu.RLock() - defer p.mu.RUnlock() - - return p.sortable -} - -// TypeCheck performs type checking for given package. -func (p *Package) TypeCheck() error { - p.mu.Lock() - defer p.mu.Unlock() - - alreadyTypeChecked := p.typesInfo != nil || p.typesPkg != nil - if alreadyTypeChecked { - return nil - } - - config := &types.Config{ - // By setting a no-op error reporter, the type checker does as much work as possible. - Error: func(error) {}, - Importer: importer.Default(), - } - info := &types.Info{ - Types: map[ast.Expr]types.TypeAndValue{}, - Defs: map[*ast.Ident]types.Object{}, - Uses: map[*ast.Ident]types.Object{}, - Scopes: map[ast.Node]*types.Scope{}, - } - var anyFile *File - var astFiles []*ast.File - for _, f := range p.files { - anyFile = f - astFiles = append(astFiles, f.AST) - } - - if anyFile == nil { - // this is unlikely to happen, but technically guarantees anyFile to not be nil - return errors.New("no ast.File found") - } - - typesPkg, err := check(config, anyFile.AST.Name.Name, p.fset, astFiles, info) - - // Remember the typechecking info, even if config.Check failed, - // since we will get partial information. - p.typesPkg = typesPkg - p.typesInfo = info - - return err -} - -// check function encapsulates the call to go/types.Config.Check method and -// recovers if the called method panics (see issue #59). -func check(config *types.Config, n string, fset *token.FileSet, astFiles []*ast.File, info *types.Info) (p *types.Package, err error) { - defer func() { - if r := recover(); r != nil { - err, _ = r.(error) - p = nil - return - } - }() - - return config.Check(n, fset, astFiles, info) -} - -// TypeOf returns the type of expression. -func (p *Package) TypeOf(expr ast.Expr) types.Type { - p.mu.RLock() - defer p.mu.RUnlock() - - if p.typesInfo == nil { - return nil - } - - return p.typesInfo.TypeOf(expr) -} - -type sortableMethodsFlags int - -// flags for sortable interface methods. -const ( - bfLen sortableMethodsFlags = 1 << iota - bfLess - bfSwap -) - -func (p *Package) scanSortable() { - p.mu.Lock() - defer p.mu.Unlock() - - sortableFlags := map[string]sortableMethodsFlags{} - for _, f := range p.files { - for _, decl := range f.AST.Decls { - fn, ok := decl.(*ast.FuncDecl) - isAMethodDeclaration := ok && fn.Recv != nil && len(fn.Recv.List) != 0 - if !isAMethodDeclaration { - continue - } - - recvType := typeparams.ReceiverType(fn) - sortableFlags[recvType] |= getSortableMethodFlagForFunction(fn) - } - } - - p.sortable = make(map[string]bool, len(sortableFlags)) - for typ, ms := range sortableFlags { - if ms == bfLen|bfLess|bfSwap { - p.sortable[typ] = true - } - } -} - -func (p *Package) lint(rules []Rule, config Config, failures chan Failure) error { - p.scanSortable() - var eg errgroup.Group - for _, file := range p.Files() { - eg.Go(func() error { - return file.lint(rules, config, failures) - }) - } - - return eg.Wait() -} - -// IsAtLeastGoVersion returns true if the Go version for this package is v or higher, false otherwise. -func (p *Package) IsAtLeastGoVersion(v *goversion.Version) bool { - p.mu.RLock() - defer p.mu.RUnlock() - - return p.goVersion.GreaterThanOrEqual(v) -} - -func getSortableMethodFlagForFunction(fn *ast.FuncDecl) sortableMethodsFlags { - switch { - case astutils.FuncSignatureIs(fn, "Len", []string{}, []string{"int"}): - return bfLen - case astutils.FuncSignatureIs(fn, "Less", []string{"int", "int"}, []string{"bool"}): - return bfLess - case astutils.FuncSignatureIs(fn, "Swap", []string{"int", "int"}, []string{}): - return bfSwap - default: - return 0 - } -} diff --git a/vendor/github.com/mgechev/revive/lint/rule.go b/vendor/github.com/mgechev/revive/lint/rule.go deleted file mode 100644 index e682c1c801..0000000000 --- a/vendor/github.com/mgechev/revive/lint/rule.go +++ /dev/null @@ -1,31 +0,0 @@ -package lint - -import ( - "go/token" -) - -// DisabledInterval contains a single disabled interval and the associated rule name. -type DisabledInterval struct { - From token.Position - To token.Position - RuleName string -} - -// Rule defines an abstract rule interface. -type Rule interface { - Name() string - Apply(*File, Arguments) []Failure -} - -// ConfigurableRule defines an abstract configurable rule interface. -type ConfigurableRule interface { - Configure(Arguments) error -} - -// ToFailurePosition returns the failure position. -func ToFailurePosition(start, end token.Pos, file *File) FailurePosition { - return FailurePosition{ - Start: file.ToPosition(start), - End: file.ToPosition(end), - } -} diff --git a/vendor/github.com/mgechev/revive/logging/logger.go b/vendor/github.com/mgechev/revive/logging/logger.go deleted file mode 100644 index 212419f270..0000000000 --- a/vendor/github.com/mgechev/revive/logging/logger.go +++ /dev/null @@ -1,37 +0,0 @@ -// Package logging provides a logger and related methods. -package logging - -import ( - "io" - "log/slog" - "os" -) - -const logFile = "revive.log" - -var logger *slog.Logger - -// GetLogger retrieves an instance of an application logger which outputs -// to a file if the debug flag is enabled. -func GetLogger() (*slog.Logger, error) { - if logger != nil { - return logger, nil - } - - debugModeEnabled := os.Getenv("DEBUG") != "" - if !debugModeEnabled { - // by default, suppress all logging output - return slog.New(slog.NewTextHandler(io.Discard, nil)), nil // TODO: change to slog.New(slog.DiscardHandler) when we switch to Go 1.24 - } - - fileWriter, err := os.Create(logFile) - if err != nil { - return nil, err - } - - logger = slog.New(slog.NewTextHandler(io.MultiWriter(os.Stderr, fileWriter), nil)) - - logger.Info("Logger initialized", "logFile", logFile) - - return logger, nil -} diff --git a/vendor/github.com/mgechev/revive/rule/add_constant.go b/vendor/github.com/mgechev/revive/rule/add_constant.go deleted file mode 100644 index 90abd4e623..0000000000 --- a/vendor/github.com/mgechev/revive/rule/add_constant.go +++ /dev/null @@ -1,267 +0,0 @@ -package rule - -import ( - "errors" - "fmt" - "go/ast" - "regexp" - "strconv" - "strings" - - "github.com/mgechev/revive/lint" -) - -const ( - defaultStrLitLimit = 2 - kindFLOAT = "FLOAT" - kindINT = "INT" - kindSTRING = "STRING" -) - -type allowList map[string]map[string]bool - -func newAllowList() allowList { - return map[string]map[string]bool{kindINT: {}, kindFLOAT: {}, kindSTRING: {}} -} - -func (wl allowList) add(kind, list string) { - elems := strings.Split(list, ",") - for _, e := range elems { - wl[kind][e] = true - } -} - -// AddConstantRule suggests using constants instead of magic numbers and string literals. -type AddConstantRule struct { - allowList allowList - ignoreFunctions []*regexp.Regexp - strLitLimit int -} - -// Apply applies the rule to given file. -func (r *AddConstantRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - onFailure := func(failure lint.Failure) { - failures = append(failures, failure) - } - - w := &lintAddConstantRule{ - onFailure: onFailure, - strLits: map[string]int{}, - strLitLimit: r.strLitLimit, - allowList: r.allowList, - ignoreFunctions: r.ignoreFunctions, - structTags: map[*ast.BasicLit]struct{}{}, - } - - ast.Walk(w, file.AST) - - return failures -} - -// Name returns the rule name. -func (*AddConstantRule) Name() string { - return "add-constant" -} - -type lintAddConstantRule struct { - onFailure func(lint.Failure) - strLits map[string]int - strLitLimit int - allowList allowList - ignoreFunctions []*regexp.Regexp - structTags map[*ast.BasicLit]struct{} -} - -func (w *lintAddConstantRule) Visit(node ast.Node) ast.Visitor { - if node == nil { - return nil - } - - switch n := node.(type) { - case *ast.CallExpr: - w.checkFunc(n) - return nil - case *ast.GenDecl: - return nil // skip declarations - case *ast.BasicLit: - if !w.isStructTag(n) { - w.checkLit(n) - } - case *ast.StructType: - if n.Fields != nil { - for _, field := range n.Fields.List { - if field.Tag != nil { - w.structTags[field.Tag] = struct{}{} - } - } - } - } - - return w -} - -func (w *lintAddConstantRule) checkFunc(expr *ast.CallExpr) { - fName := w.getFuncName(expr) - - for _, arg := range expr.Args { - switch t := arg.(type) { - case *ast.CallExpr: - w.checkFunc(t) - case *ast.BasicLit: - if w.isIgnoredFunc(fName) { - continue - } - w.checkLit(t) - } - } -} - -func (*lintAddConstantRule) getFuncName(expr *ast.CallExpr) string { - switch f := expr.Fun.(type) { - case *ast.SelectorExpr: - switch prefix := f.X.(type) { - case *ast.Ident: - return prefix.Name + "." + f.Sel.Name - case *ast.CallExpr: - // If the selector is an CallExpr, like `fn().Info`, we return `.Info` as function name - if f.Sel != nil { - return "." + f.Sel.Name - } - } - case *ast.Ident: - return f.Name - } - - return "" -} - -func (w *lintAddConstantRule) checkLit(n *ast.BasicLit) { - switch kind := n.Kind.String(); kind { - case kindFLOAT, kindINT: - w.checkNumLit(kind, n) - case kindSTRING: - w.checkStrLit(n) - } -} - -func (w *lintAddConstantRule) isIgnoredFunc(fName string) bool { - for _, pattern := range w.ignoreFunctions { - if pattern.MatchString(fName) { - return true - } - } - - return false -} - -func (w *lintAddConstantRule) checkStrLit(n *ast.BasicLit) { - const ignoreMarker = -1 - - if w.allowList[kindSTRING][n.Value] { - return - } - - count := w.strLits[n.Value] - mustCheck := count > ignoreMarker - if mustCheck { - w.strLits[n.Value] = count + 1 - if w.strLits[n.Value] > w.strLitLimit { - w.onFailure(lint.Failure{ - Confidence: 1, - Node: n, - Category: lint.FailureCategoryStyle, - Failure: fmt.Sprintf("string literal %s appears, at least, %d times, create a named constant for it", n.Value, w.strLits[n.Value]), - }) - w.strLits[n.Value] = -1 // mark it to avoid failing again on the same literal - } - } -} - -func (w *lintAddConstantRule) checkNumLit(kind string, n *ast.BasicLit) { - if w.allowList[kind][n.Value] { - return - } - - w.onFailure(lint.Failure{ - Confidence: 1, - Node: n, - Category: lint.FailureCategoryStyle, - Failure: fmt.Sprintf("avoid magic numbers like '%s', create a named constant for it", n.Value), - }) -} - -func (w *lintAddConstantRule) isStructTag(n *ast.BasicLit) bool { - _, ok := w.structTags[n] - return ok -} - -// Configure validates the rule configuration, and configures the rule accordingly. -// -// Configuration implements the [lint.ConfigurableRule] interface. -func (r *AddConstantRule) Configure(arguments lint.Arguments) error { - r.strLitLimit = defaultStrLitLimit - r.allowList = newAllowList() - if len(arguments) == 0 { - return nil - } - args, ok := arguments[0].(map[string]any) - if !ok { - return fmt.Errorf("invalid argument to the add-constant rule, expecting a k,v map. Got %T", arguments[0]) - } - for k, v := range args { - kind := "" - switch { - case isRuleOption(k, "allowFloats"): - kind = kindFLOAT - fallthrough - case isRuleOption(k, "allowInts"): - if kind == "" { - kind = kindINT - } - fallthrough - case isRuleOption(k, "allowStrs"): - if kind == "" { - kind = kindSTRING - } - list, ok := v.(string) - if !ok { - return fmt.Errorf("invalid argument to the add-constant rule, string expected. Got '%v' (%T)", v, v) - } - r.allowList.add(kind, list) - case isRuleOption(k, "maxLitCount"): - sl, ok := v.(string) - if !ok { - return fmt.Errorf("invalid argument to the add-constant rule, expecting string representation of an integer. Got '%v' (%T)", v, v) - } - - limit, err := strconv.Atoi(sl) - if err != nil { - return fmt.Errorf("invalid argument to the add-constant rule, expecting string representation of an integer. Got '%v'", v) - } - r.strLitLimit = limit - case isRuleOption(k, "ignoreFuncs"): - excludes, ok := v.(string) - if !ok { - return fmt.Errorf("invalid argument to the ignoreFuncs parameter of add-constant rule, string expected. Got '%v' (%T)", v, v) - } - - for _, exclude := range strings.Split(excludes, ",") { - exclude = strings.Trim(exclude, " ") - if exclude == "" { - return errors.New("invalid argument to the ignoreFuncs parameter of add-constant rule, expected regular expression must not be empty") - } - - exp, err := regexp.Compile(exclude) - if err != nil { - return fmt.Errorf("invalid argument to the ignoreFuncs parameter of add-constant rule: regexp %q does not compile: %w", exclude, err) - } - - r.ignoreFunctions = append(r.ignoreFunctions, exp) - } - } - } - - return nil -} diff --git a/vendor/github.com/mgechev/revive/rule/argument_limit.go b/vendor/github.com/mgechev/revive/rule/argument_limit.go deleted file mode 100644 index 7fd6a382d0..0000000000 --- a/vendor/github.com/mgechev/revive/rule/argument_limit.go +++ /dev/null @@ -1,67 +0,0 @@ -package rule - -import ( - "errors" - "fmt" - "go/ast" - - "github.com/mgechev/revive/lint" -) - -// ArgumentsLimitRule lints the number of arguments a function can receive. -type ArgumentsLimitRule struct { - max int -} - -const defaultArgumentsLimit = 8 - -// Configure validates the rule configuration, and configures the rule accordingly. -// -// Configuration implements the [lint.ConfigurableRule] interface. -func (r *ArgumentsLimitRule) Configure(arguments lint.Arguments) error { - if len(arguments) < 1 { - r.max = defaultArgumentsLimit - return nil - } - - maxArguments, ok := arguments[0].(int64) // Alt. non panicking version - if !ok { - return errors.New(`invalid value passed as argument number to the "argument-limit" rule`) - } - r.max = int(maxArguments) - return nil -} - -// Apply applies the rule to given file. -func (r *ArgumentsLimitRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - for _, decl := range file.AST.Decls { - funcDecl, ok := decl.(*ast.FuncDecl) - if !ok { - continue - } - - numParams := 0 - for _, l := range funcDecl.Type.Params.List { - numParams += len(l.Names) - } - - if numParams <= r.max { - continue - } - - failures = append(failures, lint.Failure{ - Confidence: 1, - Failure: fmt.Sprintf("maximum number of arguments per function exceeded; max %d but got %d", r.max, numParams), - Node: funcDecl.Type, - }) - } - - return failures -} - -// Name returns the rule name. -func (*ArgumentsLimitRule) Name() string { - return "argument-limit" -} diff --git a/vendor/github.com/mgechev/revive/rule/atomic.go b/vendor/github.com/mgechev/revive/rule/atomic.go deleted file mode 100644 index 83a7daeae4..0000000000 --- a/vendor/github.com/mgechev/revive/rule/atomic.go +++ /dev/null @@ -1,95 +0,0 @@ -package rule - -import ( - "go/ast" - "go/token" - "go/types" - - "github.com/mgechev/revive/internal/astutils" - "github.com/mgechev/revive/lint" -) - -// AtomicRule lints usages of the `sync/atomic` package. -type AtomicRule struct{} - -// Apply applies the rule to given file. -func (*AtomicRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - walker := atomic{ - pkgTypesInfo: file.Pkg.TypesInfo(), - onFailure: func(failure lint.Failure) { - failures = append(failures, failure) - }, - } - - ast.Walk(walker, file.AST) - - return failures -} - -// Name returns the rule name. -func (*AtomicRule) Name() string { - return "atomic" -} - -type atomic struct { - pkgTypesInfo *types.Info - onFailure func(lint.Failure) -} - -func (w atomic) Visit(node ast.Node) ast.Visitor { - n, ok := node.(*ast.AssignStmt) - if !ok { - return w - } - - if len(n.Lhs) != len(n.Rhs) { - return nil // skip assignment sub-tree - } - if len(n.Lhs) == 1 && n.Tok == token.DEFINE { - return nil // skip assignment sub-tree - } - - for i, right := range n.Rhs { - call, ok := right.(*ast.CallExpr) - if !ok { - continue - } - sel, ok := call.Fun.(*ast.SelectorExpr) - if !ok { - continue - } - pkgIdent, _ := sel.X.(*ast.Ident) - if w.pkgTypesInfo != nil { - pkgName, ok := w.pkgTypesInfo.Uses[pkgIdent].(*types.PkgName) - if !ok || pkgName.Imported().Path() != "sync/atomic" { - continue - } - } - - switch sel.Sel.Name { - case "AddInt32", "AddInt64", "AddUint32", "AddUint64", "AddUintptr": - left := n.Lhs[i] - if len(call.Args) != 2 { - continue - } - arg := call.Args[0] - broken := false - - if uarg, ok := arg.(*ast.UnaryExpr); ok && uarg.Op == token.AND { - broken = astutils.GoFmt(left) == astutils.GoFmt(uarg.X) - } else if star, ok := left.(*ast.StarExpr); ok { - broken = astutils.GoFmt(star.X) == astutils.GoFmt(arg) - } - - if broken { - w.onFailure(lint.Failure{ - Confidence: 1, - Failure: "direct assignment to atomic value", - Node: n, - }) - } - } - } - return w -} diff --git a/vendor/github.com/mgechev/revive/rule/banned_characters.go b/vendor/github.com/mgechev/revive/rule/banned_characters.go deleted file mode 100644 index 228156bb45..0000000000 --- a/vendor/github.com/mgechev/revive/rule/banned_characters.go +++ /dev/null @@ -1,96 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - "strings" - - "github.com/mgechev/revive/lint" -) - -// BannedCharsRule checks if a file contains banned characters. -type BannedCharsRule struct { - bannedCharList []string -} - -const bannedCharsRuleName = "banned-characters" - -// Configure validates the rule configuration, and configures the rule accordingly. -// -// Configuration implements the [lint.ConfigurableRule] interface. -func (r *BannedCharsRule) Configure(arguments lint.Arguments) error { - if len(arguments) > 0 { - err := checkNumberOfArguments(1, arguments, bannedCharsRuleName) - if err != nil { - return err - } - list, err := r.getBannedCharsList(arguments) - if err != nil { - return err - } - - r.bannedCharList = list - } - return nil -} - -// Apply applied the rule to the given file. -func (r *BannedCharsRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - onFailure := func(failure lint.Failure) { - failures = append(failures, failure) - } - - w := lintBannedCharsRule{ - bannedChars: r.bannedCharList, - onFailure: onFailure, - } - - ast.Walk(w, file.AST) - return failures -} - -// Name returns the rule name. -func (*BannedCharsRule) Name() string { - return bannedCharsRuleName -} - -// getBannedCharsList converts arguments into the banned characters list. -func (r *BannedCharsRule) getBannedCharsList(args lint.Arguments) ([]string, error) { - var bannedChars []string - for _, char := range args { - charStr, ok := char.(string) - if !ok { - return nil, fmt.Errorf("invalid argument for the %s rule: expecting a string, got %T", r.Name(), char) - } - bannedChars = append(bannedChars, charStr) - } - - return bannedChars, nil -} - -type lintBannedCharsRule struct { - bannedChars []string - onFailure func(lint.Failure) -} - -// Visit checks for each node if an identifier contains banned characters. -func (w lintBannedCharsRule) Visit(node ast.Node) ast.Visitor { - n, ok := node.(*ast.Ident) - if !ok { - return w - } - for _, c := range w.bannedChars { - ok := strings.Contains(n.Name, c) - if ok { - w.onFailure(lint.Failure{ - Confidence: 1, - Failure: fmt.Sprintf("banned character found: %s", c), - RuleName: bannedCharsRuleName, - Node: n, - }) - } - } - - return w -} diff --git a/vendor/github.com/mgechev/revive/rule/bare_return.go b/vendor/github.com/mgechev/revive/rule/bare_return.go deleted file mode 100644 index f2c907405b..0000000000 --- a/vendor/github.com/mgechev/revive/rule/bare_return.go +++ /dev/null @@ -1,84 +0,0 @@ -package rule - -import ( - "go/ast" - - "github.com/mgechev/revive/lint" -) - -// BareReturnRule lints bare returns. -type BareReturnRule struct{} - -// Apply applies the rule to given file. -func (*BareReturnRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - onFailure := func(failure lint.Failure) { - failures = append(failures, failure) - } - - w := lintBareReturnRule{onFailure: onFailure} - ast.Walk(w, file.AST) - return failures -} - -// Name returns the rule name. -func (*BareReturnRule) Name() string { - return "bare-return" -} - -type lintBareReturnRule struct { - onFailure func(lint.Failure) -} - -func (w lintBareReturnRule) Visit(node ast.Node) ast.Visitor { - switch n := node.(type) { - case *ast.FuncDecl: - w.checkFunc(n.Type.Results, n.Body) - case *ast.FuncLit: // to cope with deferred functions and go-routines - w.checkFunc(n.Type.Results, n.Body) - } - - return w -} - -// checkFunc will verify if the given function has named result and bare returns. -func (w lintBareReturnRule) checkFunc(results *ast.FieldList, body *ast.BlockStmt) { - hasNamedResults := results != nil && len(results.List) > 0 && results.List[0].Names != nil - if !hasNamedResults || body == nil { - return // nothing to do - } - - brf := bareReturnFinder(w) - ast.Walk(brf, body) -} - -type bareReturnFinder struct { - onFailure func(lint.Failure) -} - -func (w bareReturnFinder) Visit(node ast.Node) ast.Visitor { - _, ok := node.(*ast.FuncLit) - if ok { - // skip analyzing function literals - // they will be analyzed by the lintBareReturnRule.Visit method - return nil - } - - rs, ok := node.(*ast.ReturnStmt) - if !ok { - return w - } - - if len(rs.Results) > 0 { - return w - } - - w.onFailure(lint.Failure{ - Confidence: 1, - Node: rs, - Failure: "avoid using bare returns, please add return expressions", - }) - - return w -} diff --git a/vendor/github.com/mgechev/revive/rule/blank_imports.go b/vendor/github.com/mgechev/revive/rule/blank_imports.go deleted file mode 100644 index b3f7a3cdc2..0000000000 --- a/vendor/github.com/mgechev/revive/rule/blank_imports.go +++ /dev/null @@ -1,78 +0,0 @@ -package rule - -import ( - "go/ast" - "strings" - - "github.com/mgechev/revive/lint" -) - -// BlankImportsRule lints blank imports. -type BlankImportsRule struct{} - -// Name returns the rule name. -func (*BlankImportsRule) Name() string { - return "blank-imports" -} - -// Apply applies the rule to given file. -func (r *BlankImportsRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - if file.Pkg.IsMain() || file.IsTest() { - return nil - } - - const ( - message = "a blank import should be only in a main or test package, or have a comment justifying it" - embedImportPath = `"embed"` - ) - - var failures []lint.Failure - - // The first element of each contiguous group of blank imports should have - // an explanatory comment of some kind. - for i, imp := range file.AST.Imports { - pos := file.ToPosition(imp.Pos()) - - if !isBlank(imp.Name) { - continue // Ignore non-blank imports. - } - - isNotFirstElement := i > 0 - if isNotFirstElement { - prev := file.AST.Imports[i-1] - prevPos := file.ToPosition(prev.Pos()) - - isSubsequentBlancInAGroup := prevPos.Line+1 == pos.Line && prev.Path.Value != embedImportPath && isBlank(prev.Name) - if isSubsequentBlancInAGroup { - continue - } - } - - if imp.Path.Value == embedImportPath && r.fileHasValidEmbedComment(file.AST) { - continue - } - - // This is the first blank import of a group. - if imp.Doc == nil && imp.Comment == nil { - failures = append(failures, lint.Failure{Failure: message, Category: lint.FailureCategoryImports, Node: imp, Confidence: 1}) - } - } - - return failures -} - -func (*BlankImportsRule) fileHasValidEmbedComment(fileAst *ast.File) bool { - for _, commentGroup := range fileAst.Comments { - for _, comment := range commentGroup.List { - if strings.HasPrefix(comment.Text, "//go:embed ") { - return true - } - } - } - - return false -} - -// isBlank returns whether id is the blank identifier "_". -// If id == nil, the answer is false. -func isBlank(id *ast.Ident) bool { return id != nil && id.Name == "_" } diff --git a/vendor/github.com/mgechev/revive/rule/bool_literal_in_expr.go b/vendor/github.com/mgechev/revive/rule/bool_literal_in_expr.go deleted file mode 100644 index c510ecc3e3..0000000000 --- a/vendor/github.com/mgechev/revive/rule/bool_literal_in_expr.go +++ /dev/null @@ -1,91 +0,0 @@ -package rule - -import ( - "go/ast" - "go/token" - - "github.com/mgechev/revive/lint" -) - -// BoolLiteralRule warns when logic expressions contains Boolean literals. -type BoolLiteralRule struct{} - -// Apply applies the rule to given file. -func (*BoolLiteralRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - onFailure := func(failure lint.Failure) { - failures = append(failures, failure) - } - - astFile := file.AST - w := &lintBoolLiteral{astFile, onFailure} - ast.Walk(w, astFile) - - return failures -} - -// Name returns the rule name. -func (*BoolLiteralRule) Name() string { - return "bool-literal-in-expr" -} - -type lintBoolLiteral struct { - file *ast.File - onFailure func(lint.Failure) -} - -func (w *lintBoolLiteral) Visit(node ast.Node) ast.Visitor { - if n, ok := node.(*ast.BinaryExpr); ok { - if !isBoolOp(n.Op) { - return w - } - - lexeme, ok := isExprABooleanLit(n.X) - if !ok { - lexeme, ok = isExprABooleanLit(n.Y) - if !ok { - return w - } - } - - isConstant := (n.Op == token.LAND && lexeme == "false") || (n.Op == token.LOR && lexeme == "true") - - if isConstant { - w.addFailure(n, "Boolean expression seems to always evaluate to "+lexeme, lint.FailureCategoryLogic) - } else { - w.addFailure(n, "omit Boolean literal in expression", lint.FailureCategoryStyle) - } - } - - return w -} - -func (w lintBoolLiteral) addFailure(node ast.Node, msg string, cat lint.FailureCategory) { - w.onFailure(lint.Failure{ - Confidence: 1, - Node: node, - Category: cat, - Failure: msg, - }) -} - -// isBoolOp returns true if the given token corresponds to a bool operator. -func isBoolOp(t token.Token) bool { - switch t { - case token.LAND, token.LOR, token.EQL, token.NEQ: - return true - } - - return false -} - -func isExprABooleanLit(n ast.Node) (lexeme string, ok bool) { - oper, ok := n.(*ast.Ident) - - if !ok { - return "", false - } - - return oper.Name, oper.Name == "true" || oper.Name == "false" -} diff --git a/vendor/github.com/mgechev/revive/rule/call_to_gc.go b/vendor/github.com/mgechev/revive/rule/call_to_gc.go deleted file mode 100644 index b0bc8bbd4e..0000000000 --- a/vendor/github.com/mgechev/revive/rule/call_to_gc.go +++ /dev/null @@ -1,53 +0,0 @@ -package rule - -import ( - "go/ast" - - "github.com/mgechev/revive/internal/astutils" - "github.com/mgechev/revive/lint" -) - -// CallToGCRule lints calls to the garbage collector. -type CallToGCRule struct{} - -// Apply applies the rule to given file. -func (*CallToGCRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - onFailure := func(failure lint.Failure) { - failures = append(failures, failure) - } - - w := lintCallToGC{onFailure} - ast.Walk(w, file.AST) - - return failures -} - -// Name returns the rule name. -func (*CallToGCRule) Name() string { - return "call-to-gc" -} - -type lintCallToGC struct { - onFailure func(lint.Failure) -} - -func (w lintCallToGC) Visit(node ast.Node) ast.Visitor { - ce, ok := node.(*ast.CallExpr) - if !ok { - return w // nothing to do, the node is not a function call - } - - if !astutils.IsPkgDotName(ce.Fun, "runtime", "GC") { - return nil // nothing to do, the call is not a call to the Garbage Collector - } - - w.onFailure(lint.Failure{ - Confidence: 1, - Node: node, - Category: lint.FailureCategoryBadPractice, - Failure: "explicit call to the garbage collector", - }) - - return w -} diff --git a/vendor/github.com/mgechev/revive/rule/cognitive_complexity.go b/vendor/github.com/mgechev/revive/rule/cognitive_complexity.go deleted file mode 100644 index 901fc60bef..0000000000 --- a/vendor/github.com/mgechev/revive/rule/cognitive_complexity.go +++ /dev/null @@ -1,241 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - "go/token" - - "golang.org/x/tools/go/ast/astutil" - - "github.com/mgechev/revive/lint" -) - -// CognitiveComplexityRule sets restriction for maximum cognitive complexity. -type CognitiveComplexityRule struct { - maxComplexity int -} - -const defaultMaxCognitiveComplexity = 7 - -// Configure validates the rule configuration, and configures the rule accordingly. -// -// Configuration implements the [lint.ConfigurableRule] interface. -func (r *CognitiveComplexityRule) Configure(arguments lint.Arguments) error { - if len(arguments) < 1 { - r.maxComplexity = defaultMaxCognitiveComplexity - return nil - } - - complexity, ok := arguments[0].(int64) - if !ok { - return fmt.Errorf("invalid argument type for cognitive-complexity, expected int64, got %T", arguments[0]) - } - - r.maxComplexity = int(complexity) - return nil -} - -// Apply applies the rule to given file. -func (r *CognitiveComplexityRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - linter := cognitiveComplexityLinter{ - file: file, - maxComplexity: r.maxComplexity, - onFailure: func(failure lint.Failure) { - failures = append(failures, failure) - }, - } - - linter.lintCognitiveComplexity() - - return failures -} - -// Name returns the rule name. -func (*CognitiveComplexityRule) Name() string { - return "cognitive-complexity" -} - -type cognitiveComplexityLinter struct { - file *lint.File - maxComplexity int - onFailure func(lint.Failure) -} - -func (w cognitiveComplexityLinter) lintCognitiveComplexity() { - f := w.file - for _, decl := range f.AST.Decls { - if fn, ok := decl.(*ast.FuncDecl); ok && fn.Body != nil { - v := cognitiveComplexityVisitor{ - name: fn.Name, - } - c := v.subTreeComplexity(fn.Body) - if c > w.maxComplexity { - w.onFailure(lint.Failure{ - Confidence: 1, - Category: lint.FailureCategoryMaintenance, - Failure: fmt.Sprintf("function %s has cognitive complexity %d (> max enabled %d)", funcName(fn), c, w.maxComplexity), - Node: fn, - }) - } - } - } -} - -type cognitiveComplexityVisitor struct { - name *ast.Ident - complexity int - nestingLevel int -} - -// subTreeComplexity calculates the cognitive complexity of an AST-subtree. -func (v *cognitiveComplexityVisitor) subTreeComplexity(n ast.Node) int { - ast.Walk(v, n) - return v.complexity -} - -// Visit implements the ast.Visitor interface. -func (v *cognitiveComplexityVisitor) Visit(n ast.Node) ast.Visitor { - switch n := n.(type) { - case *ast.IfStmt: - v.walkIfElse(n) - return nil - case *ast.ForStmt: - targets := []ast.Node{n.Cond, n.Body} - v.walk(1, targets...) - return nil - case *ast.RangeStmt: - v.walk(1, n.Body) - return nil - case *ast.SelectStmt: - v.walk(1, n.Body) - return nil - case *ast.SwitchStmt: - v.walk(1, n.Body) - return nil - case *ast.TypeSwitchStmt: - v.walk(1, n.Body) - return nil - case *ast.FuncLit: - v.walk(0, n.Body) // do not increment the complexity, just do the nesting - return nil - case *ast.BinaryExpr: - v.complexity += v.binExpComplexity(n) - return nil // skip visiting binexp subtree (already visited by binExpComplexity) - case *ast.BranchStmt: - if n.Label != nil { - v.complexity++ - } - case *ast.CallExpr: - if ident, ok := n.Fun.(*ast.Ident); ok { - if ident.Obj == v.name.Obj && ident.Name == v.name.Name { - // called by same function directly (direct recursion) - v.complexity++ - return nil - } - } - } - - return v -} - -func (v *cognitiveComplexityVisitor) walk(complexityIncrement int, targets ...ast.Node) { - v.complexity += complexityIncrement + v.nestingLevel - nesting := v.nestingLevel - v.nestingLevel++ - - for _, t := range targets { - if t == nil { - continue - } - - ast.Walk(v, t) - } - - v.nestingLevel = nesting -} - -func (v *cognitiveComplexityVisitor) walkIfElse(n *ast.IfStmt) { - var w func(n *ast.IfStmt) - w = func(n *ast.IfStmt) { - ast.Walk(v, n.Cond) - ast.Walk(v, n.Body) - if n.Else != nil { - if elif, ok := n.Else.(*ast.IfStmt); ok { - v.complexity++ - w(elif) - } else { - ast.Walk(v, n.Else) - } - } - } - - // Nesting level is incremented in 'if' and 'else' blocks, but only the first 'if' in an 'if-else-if' chain sees its - // complexity increased by the nesting level. - v.complexity += 1 + v.nestingLevel - v.nestingLevel++ - w(n) - v.nestingLevel-- -} - -func (*cognitiveComplexityVisitor) binExpComplexity(n *ast.BinaryExpr) int { - calculator := binExprComplexityCalculator{opsStack: []token.Token{}} - - astutil.Apply(n, calculator.pre, calculator.post) - - return calculator.complexity -} - -type binExprComplexityCalculator struct { - complexity int - opsStack []token.Token // stack of bool operators - subexpStarted bool -} - -func (becc *binExprComplexityCalculator) pre(c *astutil.Cursor) bool { - switch n := c.Node().(type) { - case *ast.BinaryExpr: - isBoolOp := n.Op == token.LAND || n.Op == token.LOR - if !isBoolOp { - break - } - - ops := len(becc.opsStack) - // if - // is the first boolop in the expression OR - // is the first boolop inside a subexpression (...) OR - // is not the same to the previous one - // then - // increment complexity - if ops == 0 || becc.subexpStarted || n.Op != becc.opsStack[ops-1] { - becc.complexity++ - becc.subexpStarted = false - } - - becc.opsStack = append(becc.opsStack, n.Op) - case *ast.ParenExpr: - becc.subexpStarted = true - } - - return true -} - -func (becc *binExprComplexityCalculator) post(c *astutil.Cursor) bool { - switch n := c.Node().(type) { - case *ast.BinaryExpr: - isBoolOp := n.Op == token.LAND || n.Op == token.LOR - if !isBoolOp { - break - } - - ops := len(becc.opsStack) - if ops > 0 { - becc.opsStack = becc.opsStack[:ops-1] - } - case *ast.ParenExpr: - becc.subexpStarted = false - } - - return true -} diff --git a/vendor/github.com/mgechev/revive/rule/comment_spacings.go b/vendor/github.com/mgechev/revive/rule/comment_spacings.go deleted file mode 100644 index 0c35fe3925..0000000000 --- a/vendor/github.com/mgechev/revive/rule/comment_spacings.go +++ /dev/null @@ -1,81 +0,0 @@ -package rule - -import ( - "fmt" - "strings" - - "github.com/mgechev/revive/lint" -) - -// CommentSpacingsRule check whether there is a space between -// the comment symbol( // ) and the start of the comment text. -type CommentSpacingsRule struct { - allowList []string -} - -// Configure validates the rule configuration, and configures the rule accordingly. -// -// Configuration implements the [lint.ConfigurableRule] interface. -func (r *CommentSpacingsRule) Configure(arguments lint.Arguments) error { - r.allowList = []string{} - for _, arg := range arguments { - allow, ok := arg.(string) // Alt. non panicking version - if !ok { - return fmt.Errorf("invalid argument %v for %s; expected string but got %T", arg, r.Name(), arg) - } - r.allowList = append(r.allowList, `//`+allow) - } - return nil -} - -// Apply the rule. -func (r *CommentSpacingsRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - for _, cg := range file.AST.Comments { - for _, comment := range cg.List { - commentLine := comment.Text - if len(commentLine) < 3 { - continue // nothing to do - } - - isMultiLineComment := commentLine[1] == '*' - isOK := commentLine[2] == '\n' - if isMultiLineComment && isOK { - continue - } - - isOK = (commentLine[2] == ' ') || (commentLine[2] == '\t') - if isOK { - continue - } - - if r.isAllowed(commentLine) { - continue - } - - failures = append(failures, lint.Failure{ - Node: comment, - Confidence: 1, - Category: lint.FailureCategoryStyle, - Failure: "no space between comment delimiter and comment text", - }) - } - } - return failures -} - -// Name yields this rule name. -func (*CommentSpacingsRule) Name() string { - return "comment-spacings" -} - -func (r *CommentSpacingsRule) isAllowed(line string) bool { - for _, allow := range r.allowList { - if strings.HasPrefix(line, allow) { - return true - } - } - - return isDirectiveComment(line) -} diff --git a/vendor/github.com/mgechev/revive/rule/comments_density.go b/vendor/github.com/mgechev/revive/rule/comments_density.go deleted file mode 100644 index e83c20add9..0000000000 --- a/vendor/github.com/mgechev/revive/rule/comments_density.go +++ /dev/null @@ -1,86 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - "strings" - - "github.com/mgechev/revive/lint" -) - -// CommentsDensityRule enforces a minimum comment / code relation. -type CommentsDensityRule struct { - minimumCommentsDensity int64 -} - -const defaultMinimumCommentsPercentage = 0 - -// Configure validates the rule configuration, and configures the rule accordingly. -// -// Configuration implements the [lint.ConfigurableRule] interface. -func (r *CommentsDensityRule) Configure(arguments lint.Arguments) error { - if len(arguments) < 1 { - r.minimumCommentsDensity = defaultMinimumCommentsPercentage - return nil - } - - var ok bool - r.minimumCommentsDensity, ok = arguments[0].(int64) - if !ok { - return fmt.Errorf("invalid argument for %q rule: argument should be an int, got %T", r.Name(), arguments[0]) - } - return nil -} - -// Apply applies the rule to given file. -func (r *CommentsDensityRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - commentsLines := countDocLines(file.AST.Comments) - statementsCount := countStatements(file.AST) - density := (float32(commentsLines) / float32(statementsCount+commentsLines)) * 100 - - if density < float32(r.minimumCommentsDensity) { - return []lint.Failure{ - { - Node: file.AST, - Confidence: 1, - Failure: fmt.Sprintf("the file has a comment density of %2.f%% (%d comment lines for %d code lines) but expected a minimum of %d%%", - density, commentsLines, statementsCount, r.minimumCommentsDensity), - }, - } - } - - return nil -} - -// Name returns the rule name. -func (*CommentsDensityRule) Name() string { - return "comments-density" -} - -// countStatements counts the number of program statements in the given AST. -func countStatements(node ast.Node) int { - counter := 0 - - ast.Inspect(node, func(n ast.Node) bool { - switch n.(type) { - case *ast.ExprStmt, *ast.AssignStmt, *ast.ReturnStmt, *ast.GoStmt, *ast.DeferStmt, - *ast.BranchStmt, *ast.IfStmt, *ast.SwitchStmt, *ast.TypeSwitchStmt, - *ast.SelectStmt, *ast.ForStmt, *ast.RangeStmt, *ast.CaseClause, *ast.CommClause, - *ast.DeclStmt, *ast.FuncDecl: - counter++ - } - return true - }) - - return counter -} - -func countDocLines(comments []*ast.CommentGroup) int { - acc := 0 - for _, c := range comments { - lines := strings.Split(c.Text(), "\n") - acc += len(lines) - 1 - } - - return acc -} diff --git a/vendor/github.com/mgechev/revive/rule/confusing_naming.go b/vendor/github.com/mgechev/revive/rule/confusing_naming.go deleted file mode 100644 index 774eb04ee1..0000000000 --- a/vendor/github.com/mgechev/revive/rule/confusing_naming.go +++ /dev/null @@ -1,204 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - "strings" - "sync" - - "github.com/mgechev/revive/internal/astutils" - "github.com/mgechev/revive/lint" -) - -type referenceMethod struct { - fileName string - id *ast.Ident -} - -type pkgMethods struct { - pkg *lint.Package - methods map[string]map[string]*referenceMethod - mu *sync.Mutex -} - -type packages struct { - pkgs []pkgMethods - mu sync.Mutex -} - -func (ps *packages) methodNames(lp *lint.Package) pkgMethods { - ps.mu.Lock() - defer ps.mu.Unlock() - - for _, pkg := range ps.pkgs { - if pkg.pkg == lp { - return pkg - } - } - - pkgm := pkgMethods{pkg: lp, methods: map[string]map[string]*referenceMethod{}, mu: &sync.Mutex{}} - ps.pkgs = append(ps.pkgs, pkgm) - - return pkgm -} - -var allPkgs = packages{pkgs: make([]pkgMethods, 1)} - -// ConfusingNamingRule lints method names that differ only by capitalization. -type ConfusingNamingRule struct{} - -// Apply applies the rule to given file. -func (*ConfusingNamingRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - fileAst := file.AST - pkgm := allPkgs.methodNames(file.Pkg) - walker := lintConfusingNames{ - fileName: file.Name, - pkgm: pkgm, - onFailure: func(failure lint.Failure) { - failures = append(failures, failure) - }, - } - - ast.Walk(&walker, fileAst) - - return failures -} - -// Name returns the rule name. -func (*ConfusingNamingRule) Name() string { - return "confusing-naming" -} - -// checkMethodName checks if a given method/function name is similar (just case differences) to other method/function of the same struct/file. -func checkMethodName(holder string, id *ast.Ident, w *lintConfusingNames) { - if id.Name == "init" && holder == defaultStructName { - // ignore init functions - return - } - - pkgm := w.pkgm - name := strings.ToUpper(id.Name) - - pkgm.mu.Lock() - defer pkgm.mu.Unlock() - - if pkgm.methods[holder] != nil { - if pkgm.methods[holder][name] != nil { - refMethod := pkgm.methods[holder][name] - // confusing names - var kind string - if holder == defaultStructName { - kind = "function" - } else { - kind = "method" - } - var fileName string - if w.fileName == refMethod.fileName { - fileName = "the same source file" - } else { - fileName = refMethod.fileName - } - w.onFailure(lint.Failure{ - Failure: fmt.Sprintf("Method '%s' differs only by capitalization to %s '%s' in %s", id.Name, kind, refMethod.id.Name, fileName), - Confidence: 1, - Node: id, - Category: lint.FailureCategoryNaming, - }) - - return - } - } else { - pkgm.methods[holder] = make(map[string]*referenceMethod, 1) - } - - // update the block list - pkgm.methods[holder][name] = &referenceMethod{fileName: w.fileName, id: id} -} - -type lintConfusingNames struct { - fileName string - pkgm pkgMethods - onFailure func(lint.Failure) -} - -const defaultStructName = "_" // used to map functions - -// getStructName of a function receiver. Defaults to defaultStructName. -func getStructName(r *ast.FieldList) string { - result := defaultStructName - - if r == nil || len(r.List) < 1 { - return result - } - - t := r.List[0].Type - - switch v := t.(type) { - case *ast.StarExpr: - return extractFromStarExpr(v) - case *ast.IndexExpr: - return extractFromIndexExpr(v) - case *ast.Ident: - return v.Name - } - - return defaultStructName -} - -func extractFromStarExpr(expr *ast.StarExpr) string { - switch v := expr.X.(type) { - case *ast.IndexExpr: - return extractFromIndexExpr(v) - case *ast.Ident: - return v.Name - } - return defaultStructName -} - -func extractFromIndexExpr(expr *ast.IndexExpr) string { - if v, ok := expr.X.(*ast.Ident); ok { - return v.Name - } - return defaultStructName -} - -func checkStructFields(fields *ast.FieldList, structName string, w *lintConfusingNames) { - bl := make(map[string]bool, len(fields.List)) - for _, f := range fields.List { - for _, id := range f.Names { - normName := strings.ToUpper(id.Name) - if bl[normName] { - w.onFailure(lint.Failure{ - Failure: fmt.Sprintf("Field '%s' differs only by capitalization to other field in the struct type %s", id.Name, structName), - Confidence: 1, - Node: id, - Category: lint.FailureCategoryNaming, - }) - } else { - bl[normName] = true - } - } - } -} - -func (w *lintConfusingNames) Visit(n ast.Node) ast.Visitor { - switch v := n.(type) { - case *ast.FuncDecl: - // Exclude naming warnings for functions that are exported to C but - // not exported in the Go API. - // See https://github.com/golang/lint/issues/144. - if ast.IsExported(v.Name.Name) || !astutils.IsCgoExported(v) { - checkMethodName(getStructName(v.Recv), v.Name, w) - } - case *ast.TypeSpec: - if s, ok := v.Type.(*ast.StructType); ok { - checkStructFields(s.Fields, v.Name.Name, w) - } - - default: - // will add other checks like field names, struct names, etc. - } - - return w -} diff --git a/vendor/github.com/mgechev/revive/rule/confusing_results.go b/vendor/github.com/mgechev/revive/rule/confusing_results.go deleted file mode 100644 index 559c357f9b..0000000000 --- a/vendor/github.com/mgechev/revive/rule/confusing_results.go +++ /dev/null @@ -1,55 +0,0 @@ -package rule - -import ( - "go/ast" - - "github.com/mgechev/revive/internal/astutils" - "github.com/mgechev/revive/lint" -) - -// ConfusingResultsRule lints given function declarations. -type ConfusingResultsRule struct{} - -// Apply applies the rule to given file. -func (*ConfusingResultsRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - for _, decl := range file.AST.Decls { - funcDecl, ok := decl.(*ast.FuncDecl) - - isFunctionWithMoreThanOneResult := ok && funcDecl.Type.Results != nil && len(funcDecl.Type.Results.List) > 1 - if !isFunctionWithMoreThanOneResult { - continue - } - - resultsAreNamed := len(funcDecl.Type.Results.List[0].Names) > 0 - if resultsAreNamed { - continue - } - - lastType := "" - for _, result := range funcDecl.Type.Results.List { - resultTypeName := astutils.GoFmt(result.Type) - - if resultTypeName == lastType { - failures = append(failures, lint.Failure{ - Node: result, - Confidence: 1, - Category: lint.FailureCategoryNaming, - Failure: "unnamed results of the same type may be confusing, consider using named results", - }) - - break - } - - lastType = resultTypeName - } - } - - return failures -} - -// Name returns the rule name. -func (*ConfusingResultsRule) Name() string { - return "confusing-results" -} diff --git a/vendor/github.com/mgechev/revive/rule/constant_logical_expr.go b/vendor/github.com/mgechev/revive/rule/constant_logical_expr.go deleted file mode 100644 index 9bee07e028..0000000000 --- a/vendor/github.com/mgechev/revive/rule/constant_logical_expr.go +++ /dev/null @@ -1,101 +0,0 @@ -package rule - -import ( - "go/ast" - "go/token" - - "github.com/mgechev/revive/internal/astutils" - "github.com/mgechev/revive/lint" -) - -// ConstantLogicalExprRule warns on constant logical expressions. -type ConstantLogicalExprRule struct{} - -// Apply applies the rule to given file. -func (*ConstantLogicalExprRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - onFailure := func(failure lint.Failure) { - failures = append(failures, failure) - } - - astFile := file.AST - w := &lintConstantLogicalExpr{astFile, onFailure} - ast.Walk(w, astFile) - return failures -} - -// Name returns the rule name. -func (*ConstantLogicalExprRule) Name() string { - return "constant-logical-expr" -} - -type lintConstantLogicalExpr struct { - file *ast.File - onFailure func(lint.Failure) -} - -func (w *lintConstantLogicalExpr) Visit(node ast.Node) ast.Visitor { - if n, ok := node.(*ast.BinaryExpr); ok { - if !w.isOperatorWithLogicalResult(n.Op) { - return w - } - - subExpressionsAreNotEqual := astutils.GoFmt(n.X) != astutils.GoFmt(n.Y) - if subExpressionsAreNotEqual { - return w // nothing to say - } - - // Handles cases like: a <= a, a == a, a >= a - if w.isEqualityOperator(n.Op) { - w.newFailure(n, "expression always evaluates to true") - return w - } - - // Handles cases like: a < a, a > a, a != a - if w.isInequalityOperator(n.Op) { - w.newFailure(n, "expression always evaluates to false") - return w - } - - w.newFailure(n, "left and right hand-side sub-expressions are the same") - } - - return w -} - -func (*lintConstantLogicalExpr) isOperatorWithLogicalResult(t token.Token) bool { - switch t { - case token.LAND, token.LOR, token.EQL, token.LSS, token.GTR, token.NEQ, token.LEQ, token.GEQ: - return true - } - - return false -} - -func (*lintConstantLogicalExpr) isEqualityOperator(t token.Token) bool { - switch t { - case token.EQL, token.LEQ, token.GEQ: - return true - } - - return false -} - -func (*lintConstantLogicalExpr) isInequalityOperator(t token.Token) bool { - switch t { - case token.LSS, token.GTR, token.NEQ: - return true - } - - return false -} - -func (w *lintConstantLogicalExpr) newFailure(node ast.Node, msg string) { - w.onFailure(lint.Failure{ - Confidence: 1, - Node: node, - Category: lint.FailureCategoryLogic, - Failure: msg, - }) -} diff --git a/vendor/github.com/mgechev/revive/rule/context_as_argument.go b/vendor/github.com/mgechev/revive/rule/context_as_argument.go deleted file mode 100644 index 5a3e2cf698..0000000000 --- a/vendor/github.com/mgechev/revive/rule/context_as_argument.go +++ /dev/null @@ -1,96 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - "strings" - - "github.com/mgechev/revive/internal/astutils" - "github.com/mgechev/revive/lint" -) - -// ContextAsArgumentRule suggests that `context.Context` should be the first argument of a function. -type ContextAsArgumentRule struct { - allowTypes map[string]struct{} -} - -// Apply applies the rule to given file. -func (r *ContextAsArgumentRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - for _, decl := range file.AST.Decls { - fn, ok := decl.(*ast.FuncDecl) - if !ok || len(fn.Type.Params.List) <= 1 { - continue // not a function or a function with less than 2 parameters - } - - fnArgs := fn.Type.Params.List - - // A context.Context should be the first parameter of a function. - // Flag any that show up after the first. - isCtxStillAllowed := true - for _, arg := range fnArgs { - argIsCtx := astutils.IsPkgDotName(arg.Type, "context", "Context") - if argIsCtx && !isCtxStillAllowed { - failures = append(failures, lint.Failure{ - Node: arg, - Category: lint.FailureCategoryArgOrder, - Failure: "context.Context should be the first parameter of a function", - Confidence: 0.9, - }) - - break // only flag one - } - - typeName := astutils.GoFmt(arg.Type) - // a parameter of type context.Context is still allowed if the current arg type is in the allow types LookUpTable - _, isCtxStillAllowed = r.allowTypes[typeName] - } - } - - return failures -} - -// Name returns the rule name. -func (*ContextAsArgumentRule) Name() string { - return "context-as-argument" -} - -// Configure validates the rule configuration, and configures the rule accordingly. -// -// Configuration implements the [lint.ConfigurableRule] interface. -func (r *ContextAsArgumentRule) Configure(arguments lint.Arguments) error { - types, err := r.getAllowTypesFromArguments(arguments) - if err != nil { - return err - } - r.allowTypes = types - return nil -} - -func (*ContextAsArgumentRule) getAllowTypesFromArguments(args lint.Arguments) (map[string]struct{}, error) { - allowTypesBefore := []string{} - if len(args) >= 1 { - argKV, ok := args[0].(map[string]any) - if !ok { - return nil, fmt.Errorf("invalid argument to the context-as-argument rule. Expecting a k,v map, got %T", args[0]) - } - for k, v := range argKV { - if !isRuleOption(k, "allowTypesBefore") { - return nil, fmt.Errorf("invalid argument to the context-as-argument rule. Unrecognized key %s", k) - } - typesBefore, ok := v.(string) - if !ok { - return nil, fmt.Errorf("invalid argument to the context-as-argument.allowTypesBefore rule. Expecting a string, got %T", v) - } - allowTypesBefore = append(allowTypesBefore, strings.Split(typesBefore, ",")...) - } - } - - result := make(map[string]struct{}, len(allowTypesBefore)) - for _, v := range allowTypesBefore { - result[v] = struct{}{} - } - - result["context.Context"] = struct{}{} // context.Context is always allowed before another context.Context - return result, nil -} diff --git a/vendor/github.com/mgechev/revive/rule/context_keys_type.go b/vendor/github.com/mgechev/revive/rule/context_keys_type.go deleted file mode 100644 index 562f31b22b..0000000000 --- a/vendor/github.com/mgechev/revive/rule/context_keys_type.go +++ /dev/null @@ -1,73 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - "go/types" - - "github.com/mgechev/revive/internal/astutils" - "github.com/mgechev/revive/lint" -) - -// ContextKeysType disallows the usage of basic types in `context.WithValue`. -type ContextKeysType struct{} - -// Apply applies the rule to given file. -func (*ContextKeysType) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - fileAst := file.AST - walker := lintContextKeyTypes{ - file: file, - fileAst: fileAst, - onFailure: func(failure lint.Failure) { - failures = append(failures, failure) - }, - } - - file.Pkg.TypeCheck() - ast.Walk(walker, fileAst) - - return failures -} - -// Name returns the rule name. -func (*ContextKeysType) Name() string { - return "context-keys-type" -} - -type lintContextKeyTypes struct { - file *lint.File - fileAst *ast.File - onFailure func(lint.Failure) -} - -func (w lintContextKeyTypes) Visit(n ast.Node) ast.Visitor { - if n, ok := n.(*ast.CallExpr); ok { - checkContextKeyType(w, n) - } - - return w -} - -func checkContextKeyType(w lintContextKeyTypes, x *ast.CallExpr) { - f := w.file - if !astutils.IsPkgDotName(x.Fun, "context", "WithValue") { - return - } - - // key is second argument to context.WithValue - if len(x.Args) != 3 { - return - } - key := f.Pkg.TypesInfo().Types[x.Args[1]] - - if ktyp, ok := key.Type.(*types.Basic); ok && ktyp.Kind() != types.Invalid { - w.onFailure(lint.Failure{ - Confidence: 1, - Node: x, - Category: lint.FailureCategoryContent, - Failure: fmt.Sprintf("should not use basic type %s as key in context.WithValue", key.Type), - }) - } -} diff --git a/vendor/github.com/mgechev/revive/rule/cyclomatic.go b/vendor/github.com/mgechev/revive/rule/cyclomatic.go deleted file mode 100644 index 088c45c85b..0000000000 --- a/vendor/github.com/mgechev/revive/rule/cyclomatic.go +++ /dev/null @@ -1,113 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - "go/token" - - "github.com/mgechev/revive/lint" -) - -// Based on https://github.com/fzipp/gocyclo - -// CyclomaticRule sets restriction for maximum cyclomatic complexity. -type CyclomaticRule struct { - maxComplexity int -} - -const defaultMaxCyclomaticComplexity = 10 - -// Configure validates the rule configuration, and configures the rule accordingly. -// -// Configuration implements the [lint.ConfigurableRule] interface. -func (r *CyclomaticRule) Configure(arguments lint.Arguments) error { - if len(arguments) < 1 { - r.maxComplexity = defaultMaxCyclomaticComplexity - return nil - } - - complexity, ok := arguments[0].(int64) // Alt. non panicking version - if !ok { - return fmt.Errorf("invalid argument for cyclomatic complexity; expected int but got %T", arguments[0]) - } - r.maxComplexity = int(complexity) - return nil -} - -// Apply applies the rule to given file. -func (r *CyclomaticRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - for _, decl := range file.AST.Decls { - fn, ok := decl.(*ast.FuncDecl) - if !ok { - continue - } - - c := complexity(fn) - if c > r.maxComplexity { - failures = append(failures, lint.Failure{ - Confidence: 1, - Category: lint.FailureCategoryMaintenance, - Failure: fmt.Sprintf("function %s has cyclomatic complexity %d (> max enabled %d)", - funcName(fn), c, r.maxComplexity), - Node: fn, - }) - } - } - - return failures -} - -// Name returns the rule name. -func (*CyclomaticRule) Name() string { - return "cyclomatic" -} - -// funcName returns the name representation of a function or method: -// "(Type).Name" for methods or simply "Name" for functions. -func funcName(fn *ast.FuncDecl) string { - declarationHasReceiver := fn.Recv != nil && fn.Recv.NumFields() > 0 - if declarationHasReceiver { - typ := fn.Recv.List[0].Type - return fmt.Sprintf("(%s).%s", recvString(typ), fn.Name) - } - - return fn.Name.Name -} - -// recvString returns a string representation of recv of the -// form "T", "*T", or "BADRECV" (if not a proper receiver type). -func recvString(recv ast.Expr) string { - switch t := recv.(type) { - case *ast.Ident: - return t.Name - case *ast.StarExpr: - return "*" + recvString(t.X) - } - return "BADRECV" -} - -// complexity calculates the cyclomatic complexity of a function. -func complexity(fn *ast.FuncDecl) int { - v := complexityVisitor{} - ast.Walk(&v, fn) - return v.Complexity -} - -type complexityVisitor struct { - // Complexity is the cyclomatic complexity - Complexity int -} - -// Visit implements the ast.Visitor interface. -func (v *complexityVisitor) Visit(n ast.Node) ast.Visitor { - switch n := n.(type) { - case *ast.FuncDecl, *ast.IfStmt, *ast.ForStmt, *ast.RangeStmt, *ast.CaseClause, *ast.CommClause: - v.Complexity++ - case *ast.BinaryExpr: - if n.Op == token.LAND || n.Op == token.LOR { - v.Complexity++ - } - } - return v -} diff --git a/vendor/github.com/mgechev/revive/rule/datarace.go b/vendor/github.com/mgechev/revive/rule/datarace.go deleted file mode 100644 index de63c068de..0000000000 --- a/vendor/github.com/mgechev/revive/rule/datarace.go +++ /dev/null @@ -1,144 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - - "github.com/mgechev/revive/internal/astutils" - "github.com/mgechev/revive/lint" -) - -//nolint:staticcheck // TODO: ast.Object is deprecated -type nodeUID *ast.Object // type of the unique id for AST nodes - -// DataRaceRule lints assignments to value method-receivers. -type DataRaceRule struct{} - -// Apply applies the rule to given file. -func (r *DataRaceRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - isGo122 := file.Pkg.IsAtLeastGoVersion(lint.Go122) - var failures []lint.Failure - for _, decl := range file.AST.Decls { - funcDecl, ok := decl.(*ast.FuncDecl) - if !ok || funcDecl.Body == nil { - continue // not function declaration or empty function - } - - funcResults := funcDecl.Type.Results - - returnIDs := map[nodeUID]struct{}{} - if funcResults != nil { - returnIDs = r.extractReturnIDs(funcResults.List) - } - - onFailure := func(failure lint.Failure) { - failures = append(failures, failure) - } - - fl := &lintFunctionForDataRaces{ - onFailure: onFailure, - returnIDs: returnIDs, - rangeIDs: map[nodeUID]struct{}{}, - go122for: isGo122, - } - - ast.Walk(fl, funcDecl.Body) - } - - return failures -} - -// Name returns the rule name. -func (*DataRaceRule) Name() string { - return "datarace" -} - -func (*DataRaceRule) extractReturnIDs(fields []*ast.Field) map[nodeUID]struct{} { - r := map[nodeUID]struct{}{} - for _, f := range fields { - for _, id := range f.Names { - r[id.Obj] = struct{}{} - } - } - - return r -} - -type lintFunctionForDataRaces struct { - _ struct{} - onFailure func(failure lint.Failure) - returnIDs map[nodeUID]struct{} - rangeIDs map[nodeUID]struct{} - - go122for bool -} - -func (w lintFunctionForDataRaces) Visit(node ast.Node) ast.Visitor { - switch n := node.(type) { - case *ast.RangeStmt: - if n.Body == nil { - return nil - } - - getIDs := func(exprs ...ast.Expr) []*ast.Ident { - r := []*ast.Ident{} - for _, expr := range exprs { - if id, ok := expr.(*ast.Ident); ok { - r = append(r, id) - } - } - return r - } - - ids := getIDs(n.Key, n.Value) - for _, id := range ids { - w.rangeIDs[id.Obj] = struct{}{} - } - - ast.Walk(w, n.Body) - - for _, id := range ids { - delete(w.rangeIDs, id.Obj) - } - - return nil // do not visit the body of the range, it has been already visited - case *ast.GoStmt: - f := n.Call.Fun - funcLit, ok := f.(*ast.FuncLit) - if !ok { - return nil - } - selectIDs := func(n ast.Node) bool { - _, ok := n.(*ast.Ident) - return ok - } - - ids := astutils.PickNodes(funcLit.Body, selectIDs) - for _, id := range ids { - id := id.(*ast.Ident) - _, isRangeID := w.rangeIDs[id.Obj] - _, isReturnID := w.returnIDs[id.Obj] - - switch { - case isRangeID && !w.go122for: - w.onFailure(lint.Failure{ - Confidence: 1, - Node: id, - Category: lint.FailureCategoryLogic, - Failure: fmt.Sprintf("datarace: range value %s is captured (by-reference) in goroutine", id.Name), - }) - case isReturnID: - w.onFailure(lint.Failure{ - Confidence: 0.8, - Node: id, - Category: lint.FailureCategoryLogic, - Failure: fmt.Sprintf("potential datarace: return value %s is captured (by-reference) in goroutine", id.Name), - }) - } - } - - return nil - } - - return w -} diff --git a/vendor/github.com/mgechev/revive/rule/deep_exit.go b/vendor/github.com/mgechev/revive/rule/deep_exit.go deleted file mode 100644 index 6f7acd305f..0000000000 --- a/vendor/github.com/mgechev/revive/rule/deep_exit.go +++ /dev/null @@ -1,110 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - "strings" - "unicode" - "unicode/utf8" - - "github.com/mgechev/revive/lint" -) - -// DeepExitRule lints program exit at functions other than main or init. -type DeepExitRule struct{} - -// Apply applies the rule to given file. -func (*DeepExitRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - onFailure := func(failure lint.Failure) { - failures = append(failures, failure) - } - - w := &lintDeepExit{onFailure: onFailure, isTestFile: file.IsTest()} - ast.Walk(w, file.AST) - return failures -} - -// Name returns the rule name. -func (*DeepExitRule) Name() string { - return "deep-exit" -} - -type lintDeepExit struct { - onFailure func(lint.Failure) - isTestFile bool -} - -func (w *lintDeepExit) Visit(node ast.Node) ast.Visitor { - if fd, ok := node.(*ast.FuncDecl); ok { - if w.mustIgnore(fd) { - return nil // skip analysis of this function - } - - return w - } - - se, ok := node.(*ast.ExprStmt) - if !ok { - return w - } - ce, ok := se.X.(*ast.CallExpr) - if !ok { - return w - } - - fc, ok := ce.Fun.(*ast.SelectorExpr) - if !ok { - return w - } - id, ok := fc.X.(*ast.Ident) - if !ok { - return w - } - - pkg := id.Name - fn := fc.Sel.Name - if isCallToExitFunction(pkg, fn) { - w.onFailure(lint.Failure{ - Confidence: 1, - Node: ce, - Category: lint.FailureCategoryBadPractice, - Failure: fmt.Sprintf("calls to %s.%s only in main() or init() functions", pkg, fn), - }) - } - - return w -} - -func (w *lintDeepExit) mustIgnore(fd *ast.FuncDecl) bool { - fn := fd.Name.Name - - return fn == "init" || fn == "main" || w.isTestMain(fd) || w.isTestExample(fd) -} - -func (w *lintDeepExit) isTestMain(fd *ast.FuncDecl) bool { - return w.isTestFile && fd.Name.Name == "TestMain" -} - -// isTestExample returns true if the function is a testable example function. -// See https://go.dev/blog/examples#examples-are-tests for more information. -// -// Inspired by https://github.com/golang/go/blob/go1.23.0/src/go/doc/example.go#L72-L77 -func (w *lintDeepExit) isTestExample(fd *ast.FuncDecl) bool { - if !w.isTestFile { - return false - } - name := fd.Name.Name - const prefix = "Example" - if !strings.HasPrefix(name, prefix) { - return false - } - if len(name) == len(prefix) { // "Example" is a package level example - return len(fd.Type.Params.List) == 0 - } - r, _ := utf8.DecodeRuneInString(name[len(prefix):]) - if unicode.IsLower(r) { - return false - } - return len(fd.Type.Params.List) == 0 -} diff --git a/vendor/github.com/mgechev/revive/rule/defer.go b/vendor/github.com/mgechev/revive/rule/defer.go deleted file mode 100644 index 9cab004aee..0000000000 --- a/vendor/github.com/mgechev/revive/rule/defer.go +++ /dev/null @@ -1,187 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - - "github.com/mgechev/revive/internal/astutils" - "github.com/mgechev/revive/lint" -) - -var ( - deferOptionLoop = normalizeRuleOption("loop") - deferOptionCallChain = normalizeRuleOption("callChain") - deferOptionMethodCall = normalizeRuleOption("methodCall") - deferOptionReturn = normalizeRuleOption("return") - deferOptionRecover = normalizeRuleOption("recover") - deferOptionImmediateRecover = normalizeRuleOption("immediateRecover") -) - -// DeferRule lints gotchas in defer statements. -type DeferRule struct { - allow map[string]bool -} - -// Configure validates the rule configuration, and configures the rule accordingly. -// -// Configuration implements the [lint.ConfigurableRule] interface. -func (r *DeferRule) Configure(arguments lint.Arguments) error { - list, err := r.allowFromArgs(arguments) - if err != nil { - return err - } - r.allow = list - return nil -} - -// Apply applies the rule to given file. -func (r *DeferRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - onFailure := func(failure lint.Failure) { - failures = append(failures, failure) - } - w := lintDeferRule{onFailure: onFailure, allow: r.allow} - - ast.Walk(w, file.AST) - - return failures -} - -// Name returns the rule name. -func (*DeferRule) Name() string { - return "defer" -} - -func (*DeferRule) allowFromArgs(args lint.Arguments) (map[string]bool, error) { - if len(args) < 1 { - allow := map[string]bool{ - deferOptionLoop: true, - deferOptionCallChain: true, - deferOptionMethodCall: true, - deferOptionReturn: true, - deferOptionRecover: true, - deferOptionImmediateRecover: true, - } - - return allow, nil - } - - aa, ok := args[0].([]any) - if !ok { - return nil, fmt.Errorf("invalid argument '%v' for 'defer' rule. Expecting []string, got %T", args[0], args[0]) - } - - allow := make(map[string]bool, len(aa)) - for _, subcase := range aa { - sc, ok := subcase.(string) - if !ok { - return nil, fmt.Errorf("invalid argument '%v' for 'defer' rule. Expecting string, got %T", subcase, subcase) - } - allow[normalizeRuleOption(sc)] = true - } - - return allow, nil -} - -type lintDeferRule struct { - onFailure func(lint.Failure) - inALoop bool - inADefer bool - inAFuncLit bool - allow map[string]bool -} - -func (w lintDeferRule) Visit(node ast.Node) ast.Visitor { - switch n := node.(type) { - case *ast.ForStmt: - w.visitSubtree(n.Body, w.inADefer, true, w.inAFuncLit) - return nil - case *ast.RangeStmt: - w.visitSubtree(n.Body, w.inADefer, true, w.inAFuncLit) - return nil - case *ast.FuncLit: - w.visitSubtree(n.Body, w.inADefer, false, true) - return nil - case *ast.ReturnStmt: - if len(n.Results) != 0 && w.inADefer && w.inAFuncLit { - w.newFailure("return in a defer function has no effect", n, 1.0, lint.FailureCategoryLogic, deferOptionReturn) - } - case *ast.CallExpr: - isCallToRecover := astutils.IsIdent(n.Fun, "recover") - switch { - case !w.inADefer && isCallToRecover: - // func fn() { recover() } - // - // confidence is not 1 because recover can be in a function that is deferred elsewhere - w.newFailure("recover must be called inside a deferred function", n, 0.8, lint.FailureCategoryLogic, deferOptionRecover) - case w.inADefer && !w.inAFuncLit && isCallToRecover: - // defer helper(recover()) - // - // confidence is not truly 1 because this could be in a correctly-deferred func, - // but it is very likely to be a misunderstanding of defer's behavior around arguments. - w.newFailure("recover must be called inside a deferred function, this is executing recover immediately", n, 1, lint.FailureCategoryLogic, deferOptionImmediateRecover) - } - return nil // no need to analyze the arguments of the function call - case *ast.DeferStmt: - if astutils.IsIdent(n.Call.Fun, "recover") { - // defer recover() - // - // confidence is not truly 1 because this could be in a correctly-deferred func, - // but normally this doesn't suppress a panic, and even if it did it would silently discard the value. - w.newFailure("recover must be called inside a deferred function, this is executing recover immediately", n, 1, lint.FailureCategoryLogic, deferOptionImmediateRecover) - } - w.visitSubtree(n.Call.Fun, true, false, false) - for _, a := range n.Call.Args { - switch a.(type) { - case *ast.FuncLit: - continue // too hard to analyze deferred calls with func literals args - default: - w.visitSubtree(a, true, false, false) // check arguments, they should not contain recover() - } - } - - if w.inALoop { - w.newFailure("prefer not to defer inside loops", n, 1.0, lint.FailureCategoryBadPractice, deferOptionLoop) - } - - switch fn := n.Call.Fun.(type) { - case *ast.CallExpr: - w.newFailure("prefer not to defer chains of function calls", fn, 1.0, lint.FailureCategoryBadPractice, deferOptionCallChain) - case *ast.SelectorExpr: - if id, ok := fn.X.(*ast.Ident); ok { - isMethodCall := id != nil && id.Obj != nil && id.Obj.Kind == ast.Typ - if isMethodCall { - w.newFailure("be careful when deferring calls to methods without pointer receiver", fn, 0.8, lint.FailureCategoryBadPractice, deferOptionMethodCall) - } - } - } - - return nil - } - - return w -} - -func (w lintDeferRule) visitSubtree(n ast.Node, inADefer, inALoop, inAFuncLit bool) { - nw := lintDeferRule{ - onFailure: w.onFailure, - inADefer: inADefer, - inALoop: inALoop, - inAFuncLit: inAFuncLit, - allow: w.allow, - } - ast.Walk(nw, n) -} - -func (w lintDeferRule) newFailure(msg string, node ast.Node, confidence float64, cat lint.FailureCategory, subcase string) { - if !w.allow[subcase] { - return - } - - w.onFailure(lint.Failure{ - Confidence: confidence, - Node: node, - Category: cat, - Failure: msg, - }) -} diff --git a/vendor/github.com/mgechev/revive/rule/doc.go b/vendor/github.com/mgechev/revive/rule/doc.go deleted file mode 100644 index 55bf6caa6f..0000000000 --- a/vendor/github.com/mgechev/revive/rule/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package rule implements revive's linting rules. -package rule diff --git a/vendor/github.com/mgechev/revive/rule/dot_imports.go b/vendor/github.com/mgechev/revive/rule/dot_imports.go deleted file mode 100644 index a5f2210c51..0000000000 --- a/vendor/github.com/mgechev/revive/rule/dot_imports.go +++ /dev/null @@ -1,104 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - "strconv" - - "github.com/mgechev/revive/lint" -) - -// DotImportsRule forbids . imports. -type DotImportsRule struct { - allowedPackages allowPackages -} - -// Apply applies the rule to given file. -func (r *DotImportsRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - fileAst := file.AST - walker := lintImports{ - file: file, - fileAst: fileAst, - onFailure: func(failure lint.Failure) { - failures = append(failures, failure) - }, - allowPackages: r.allowedPackages, - } - - ast.Walk(walker, fileAst) - - return failures -} - -// Name returns the rule name. -func (*DotImportsRule) Name() string { - return "dot-imports" -} - -// Configure validates the rule configuration, and configures the rule accordingly. -// -// Configuration implements the [lint.ConfigurableRule] interface. -func (r *DotImportsRule) Configure(arguments lint.Arguments) error { - r.allowedPackages = allowPackages{} - if len(arguments) == 0 { - return nil - } - - args, ok := arguments[0].(map[string]any) - if !ok { - return fmt.Errorf("invalid argument to the dot-imports rule. Expecting a k,v map, got %T", arguments[0]) - } - - for k, v := range args { - if !isRuleOption(k, "allowedPackages") { - continue - } - pkgs, ok := v.([]any) - if !ok { - return fmt.Errorf("invalid argument to the dot-imports rule, []string expected. Got '%v' (%T)", v, v) - } - for _, p := range pkgs { - pkg, ok := p.(string) - if !ok { - return fmt.Errorf("invalid argument to the dot-imports rule, string expected. Got '%v' (%T)", p, p) - } - r.allowedPackages.add(pkg) - } - } - return nil -} - -type lintImports struct { - file *lint.File - fileAst *ast.File - onFailure func(lint.Failure) - allowPackages allowPackages -} - -func (w lintImports) Visit(_ ast.Node) ast.Visitor { - for _, importSpec := range w.fileAst.Imports { - isDotImport := importSpec.Name != nil && importSpec.Name.Name == "." - if isDotImport && !w.allowPackages.isAllowedPackage(importSpec.Path.Value) { - w.onFailure(lint.Failure{ - Confidence: 1, - Failure: "should not use dot imports", - Node: importSpec, - Category: lint.FailureCategoryImports, - }) - } - } - return nil -} - -type allowPackages map[string]struct{} - -func (ap allowPackages) add(pkg string) { - ap[strconv.Quote(pkg)] = struct{}{} // import path strings are with double quotes -} - -func (ap allowPackages) isAllowedPackage(pkg string) bool { - _, allowed := ap[pkg] - return allowed -} diff --git a/vendor/github.com/mgechev/revive/rule/duplicated_imports.go b/vendor/github.com/mgechev/revive/rule/duplicated_imports.go deleted file mode 100644 index 60955c4278..0000000000 --- a/vendor/github.com/mgechev/revive/rule/duplicated_imports.go +++ /dev/null @@ -1,39 +0,0 @@ -package rule - -import ( - "fmt" - - "github.com/mgechev/revive/lint" -) - -// DuplicatedImportsRule looks for packages that are imported two or more times. -type DuplicatedImportsRule struct{} - -// Apply applies the rule to given file. -func (*DuplicatedImportsRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - impPaths := map[string]struct{}{} - for _, imp := range file.AST.Imports { - path := imp.Path.Value - _, ok := impPaths[path] - if ok { - failures = append(failures, lint.Failure{ - Confidence: 1, - Failure: fmt.Sprintf("Package %s already imported", path), - Node: imp, - Category: lint.FailureCategoryImports, - }) - continue - } - - impPaths[path] = struct{}{} - } - - return failures -} - -// Name returns the rule name. -func (*DuplicatedImportsRule) Name() string { - return "duplicated-imports" -} diff --git a/vendor/github.com/mgechev/revive/rule/early_return.go b/vendor/github.com/mgechev/revive/rule/early_return.go deleted file mode 100644 index 2c2b67f4d8..0000000000 --- a/vendor/github.com/mgechev/revive/rule/early_return.go +++ /dev/null @@ -1,89 +0,0 @@ -package rule - -import ( - "fmt" - - "github.com/mgechev/revive/internal/ifelse" - "github.com/mgechev/revive/lint" -) - -// EarlyReturnRule finds opportunities to reduce nesting by inverting -// the condition of an "if" block. -type EarlyReturnRule struct { - // preserveScope prevents suggestions that would enlarge variable scope. - preserveScope bool - // allowJump permits early-return to suggest introducing a new jump - // (return, continue, etc) statement to reduce nesting. - // By default, suggestions only bring existing jumps earlier. - allowJump bool -} - -// Configure validates the rule configuration, and configures the rule accordingly. -// -// Configuration implements the [lint.ConfigurableRule] interface. -func (e *EarlyReturnRule) Configure(arguments lint.Arguments) error { - for _, arg := range arguments { - sarg, ok := arg.(string) - if !ok { - continue - } - switch { - case isRuleOption(sarg, "preserveScope"): - e.preserveScope = true - case isRuleOption(sarg, "allowJump"): - e.allowJump = true - } - } - return nil -} - -// Apply applies the rule to given file. -func (e *EarlyReturnRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - return ifelse.Apply(e.checkIfElse, file.AST, ifelse.TargetIf, ifelse.Args{ - PreserveScope: e.preserveScope, - AllowJump: e.allowJump, - }) -} - -// Name returns the rule name. -func (*EarlyReturnRule) Name() string { - return "early-return" -} - -func (e *EarlyReturnRule) checkIfElse(chain ifelse.Chain) (string, bool) { - if chain.HasElse { - if !chain.Else.Deviates() { - // this rule only applies if the else-block deviates control flow - return "", false - } - } else if !e.allowJump || !chain.AtBlockEnd || !chain.BlockEndKind.Deviates() || chain.If.IsShort() { - // this kind of refactor requires introducing a new indented "return", "continue" or "break" statement, - // so ignore unless we are able to outdent multiple statements in exchange. - return "", false - } - - if chain.HasPriorNonDeviating && !chain.If.IsEmpty() { - // if we de-indent this block then a previous branch - // might flow into it, affecting program behavior - return "", false - } - - if chain.HasElse && chain.If.Deviates() { - // avoid overlapping with superfluous-else - return "", false - } - - if e.preserveScope && !chain.AtBlockEnd && (chain.HasInitializer || chain.If.HasDecls()) { - // avoid increasing variable scope - return "", false - } - - if !chain.HasElse { - return fmt.Sprintf("if c { ... } can be rewritten if !c { %v } ... to reduce nesting", chain.BlockEndKind), true - } - - if chain.If.IsEmpty() { - return fmt.Sprintf("if c { } else %[1]v can be simplified to if !c %[1]v", chain.Else), true - } - return fmt.Sprintf("if c { ... } else %[1]v can be simplified to if !c %[1]v ...", chain.Else), true -} diff --git a/vendor/github.com/mgechev/revive/rule/empty_block.go b/vendor/github.com/mgechev/revive/rule/empty_block.go deleted file mode 100644 index 210692c947..0000000000 --- a/vendor/github.com/mgechev/revive/rule/empty_block.go +++ /dev/null @@ -1,75 +0,0 @@ -package rule - -import ( - "go/ast" - - "github.com/mgechev/revive/lint" -) - -// EmptyBlockRule warns on empty code blocks. -type EmptyBlockRule struct{} - -// Apply applies the rule to given file. -func (*EmptyBlockRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - onFailure := func(failure lint.Failure) { - failures = append(failures, failure) - } - - w := lintEmptyBlock{map[*ast.BlockStmt]bool{}, onFailure} - ast.Walk(w, file.AST) - return failures -} - -// Name returns the rule name. -func (*EmptyBlockRule) Name() string { - return "empty-block" -} - -type lintEmptyBlock struct { - ignore map[*ast.BlockStmt]bool - onFailure func(lint.Failure) -} - -func (w lintEmptyBlock) Visit(node ast.Node) ast.Visitor { - switch n := node.(type) { - case *ast.FuncDecl: - w.ignore[n.Body] = true - return w - case *ast.FuncLit: - w.ignore[n.Body] = true - return w - case *ast.SelectStmt: - w.ignore[n.Body] = true - return w - case *ast.ForStmt: - if len(n.Body.List) == 0 && n.Init == nil && n.Post == nil && n.Cond != nil { - if _, isCall := n.Cond.(*ast.CallExpr); isCall { - w.ignore[n.Body] = true - return w - } - } - case *ast.RangeStmt: - if len(n.Body.List) == 0 { - w.onFailure(lint.Failure{ - Confidence: 0.9, - Node: n, - Category: lint.FailureCategoryLogic, - Failure: "this block is empty, you can remove it", - }) - return nil // skip visiting the range subtree (it will produce a duplicated failure) - } - case *ast.BlockStmt: - if !w.ignore[n] && len(n.List) == 0 { - w.onFailure(lint.Failure{ - Confidence: 1, - Node: n, - Category: lint.FailureCategoryLogic, - Failure: "this block is empty, you can remove it", - }) - } - } - - return w -} diff --git a/vendor/github.com/mgechev/revive/rule/empty_lines.go b/vendor/github.com/mgechev/revive/rule/empty_lines.go deleted file mode 100644 index a2f8dc6fde..0000000000 --- a/vendor/github.com/mgechev/revive/rule/empty_lines.go +++ /dev/null @@ -1,105 +0,0 @@ -package rule - -import ( - "go/ast" - "go/token" - - "github.com/mgechev/revive/lint" -) - -// EmptyLinesRule lints empty lines in blocks. -type EmptyLinesRule struct{} - -// Apply applies the rule to given file. -func (r *EmptyLinesRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - onFailure := func(failure lint.Failure) { - failures = append(failures, failure) - } - - w := lintEmptyLines{file, r.commentLines(file.CommentMap(), file), onFailure} - ast.Walk(w, file.AST) - return failures -} - -// Name returns the rule name. -func (*EmptyLinesRule) Name() string { - return "empty-lines" -} - -type lintEmptyLines struct { - file *lint.File - cmap map[int]struct{} - onFailure func(lint.Failure) -} - -func (w lintEmptyLines) Visit(node ast.Node) ast.Visitor { - block, ok := node.(*ast.BlockStmt) - if !ok || len(block.List) == 0 { - return w - } - - w.checkStart(block) - w.checkEnd(block) - - return w -} - -func (w lintEmptyLines) checkStart(block *ast.BlockStmt) { - blockStart := w.position(block.Lbrace) - firstNode := block.List[0] - firstStmt := w.position(firstNode.Pos()) - - firstBlockLineIsStmt := firstStmt.Line-(blockStart.Line+1) <= 0 - _, firstBlockLineIsComment := w.cmap[blockStart.Line+1] - if firstBlockLineIsStmt || firstBlockLineIsComment { - return - } - - w.onFailure(lint.Failure{ - Confidence: 1, - Node: block, - Category: lint.FailureCategoryStyle, - Failure: "extra empty line at the start of a block", - }) -} - -func (w lintEmptyLines) checkEnd(block *ast.BlockStmt) { - blockEnd := w.position(block.Rbrace) - lastNode := block.List[len(block.List)-1] - lastStmt := w.position(lastNode.End()) - - lastBlockLineIsStmt := (blockEnd.Line-1)-lastStmt.Line <= 0 - _, lastBlockLineIsComment := w.cmap[blockEnd.Line-1] - if lastBlockLineIsStmt || lastBlockLineIsComment { - return - } - - w.onFailure(lint.Failure{ - Confidence: 1, - Node: block, - Category: lint.FailureCategoryStyle, - Failure: "extra empty line at the end of a block", - }) -} - -func (w lintEmptyLines) position(pos token.Pos) token.Position { - return w.file.ToPosition(pos) -} - -func (*EmptyLinesRule) commentLines(cmap ast.CommentMap, file *lint.File) map[int]struct{} { - result := map[int]struct{}{} - - for _, comments := range cmap { - for _, comment := range comments { - start := file.ToPosition(comment.Pos()) - end := file.ToPosition(comment.End()) - for i := start.Line; i <= end.Line; i++ { - result[i] = struct{}{} - } - } - } - - return result -} diff --git a/vendor/github.com/mgechev/revive/rule/enforce_map_style.go b/vendor/github.com/mgechev/revive/rule/enforce_map_style.go deleted file mode 100644 index 3292db0ba1..0000000000 --- a/vendor/github.com/mgechev/revive/rule/enforce_map_style.go +++ /dev/null @@ -1,153 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - - "github.com/mgechev/revive/internal/astutils" - "github.com/mgechev/revive/lint" -) - -type enforceMapStyleType string - -const ( - enforceMapStyleTypeAny enforceMapStyleType = "any" - enforceMapStyleTypeMake enforceMapStyleType = "make" - enforceMapStyleTypeLiteral enforceMapStyleType = "literal" -) - -func mapStyleFromString(s string) (enforceMapStyleType, error) { - switch s { - case string(enforceMapStyleTypeAny), "": - return enforceMapStyleTypeAny, nil - case string(enforceMapStyleTypeMake): - return enforceMapStyleTypeMake, nil - case string(enforceMapStyleTypeLiteral): - return enforceMapStyleTypeLiteral, nil - default: - return enforceMapStyleTypeAny, fmt.Errorf( - "invalid map style: %s (expecting one of %v)", - s, - []enforceMapStyleType{ - enforceMapStyleTypeAny, - enforceMapStyleTypeMake, - enforceMapStyleTypeLiteral, - }, - ) - } -} - -// EnforceMapStyleRule implements a rule to enforce `make(map[type]type)` over `map[type]type{}`. -type EnforceMapStyleRule struct { - enforceMapStyle enforceMapStyleType -} - -// Configure validates the rule configuration, and configures the rule accordingly. -// -// Configuration implements the [lint.ConfigurableRule] interface. -func (r *EnforceMapStyleRule) Configure(arguments lint.Arguments) error { - if len(arguments) < 1 { - r.enforceMapStyle = enforceMapStyleTypeAny - return nil - } - - enforceMapStyle, ok := arguments[0].(string) - if !ok { - return fmt.Errorf("invalid argument '%v' for 'enforce-map-style' rule. Expecting string, got %T", arguments[0], arguments[0]) - } - - var err error - r.enforceMapStyle, err = mapStyleFromString(enforceMapStyle) - if err != nil { - return fmt.Errorf("invalid argument to the enforce-map-style rule: %w", err) - } - - return nil -} - -// Apply applies the rule to given file. -func (r *EnforceMapStyleRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - if r.enforceMapStyle == enforceMapStyleTypeAny { - // this linter is not configured - return nil - } - var failures []lint.Failure - astFile := file.AST - ast.Inspect(astFile, func(n ast.Node) bool { - switch v := n.(type) { - case *ast.CompositeLit: - if r.enforceMapStyle != enforceMapStyleTypeMake { - return true - } - - if !r.isMapType(v.Type) { - return true - } - - isEmptyMap := len(v.Elts) > 0 - if isEmptyMap { - return true - } - - failures = append(failures, lint.Failure{ - Confidence: 1, - Node: v, - Category: lint.FailureCategoryStyle, - Failure: "use make(map[type]type) instead of map[type]type{}", - }) - case *ast.CallExpr: - if r.enforceMapStyle != enforceMapStyleTypeLiteral { - // skip any function calls, even if it's make(map[type]type) - // we don't want to report it if literals are not enforced - return true - } - - if !astutils.IsIdent(v.Fun, "make") { - return true - } - - if len(v.Args) != 1 { - // skip make(map[type]type, size) and invalid empty declarations - return true - } - - if !r.isMapType(v.Args[0]) { - // not a map type - return true - } - - failures = append(failures, lint.Failure{ - Confidence: 1, - Node: v.Args[0], - Category: lint.FailureCategoryStyle, - Failure: "use map[type]type{} instead of make(map[type]type)", - }) - } - return true - }) - - return failures -} - -// Name returns the rule name. -func (*EnforceMapStyleRule) Name() string { - return "enforce-map-style" -} - -func (r *EnforceMapStyleRule) isMapType(v ast.Expr) bool { - switch t := v.(type) { - case *ast.MapType: - return true - case *ast.Ident: - if t.Obj == nil { - return false - } - typeSpec, ok := t.Obj.Decl.(*ast.TypeSpec) - if !ok { - return false - } - return r.isMapType(typeSpec.Type) - default: - return false - } -} diff --git a/vendor/github.com/mgechev/revive/rule/enforce_repeated_arg_type_style.go b/vendor/github.com/mgechev/revive/rule/enforce_repeated_arg_type_style.go deleted file mode 100644 index 9def128aa6..0000000000 --- a/vendor/github.com/mgechev/revive/rule/enforce_repeated_arg_type_style.go +++ /dev/null @@ -1,191 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - - "github.com/mgechev/revive/internal/astutils" - "github.com/mgechev/revive/lint" -) - -type enforceRepeatedArgTypeStyleType string - -const ( - enforceRepeatedArgTypeStyleTypeAny enforceRepeatedArgTypeStyleType = "any" - enforceRepeatedArgTypeStyleTypeShort enforceRepeatedArgTypeStyleType = "short" - enforceRepeatedArgTypeStyleTypeFull enforceRepeatedArgTypeStyleType = "full" -) - -func repeatedArgTypeStyleFromString(s string) (enforceRepeatedArgTypeStyleType, error) { - switch s { - case string(enforceRepeatedArgTypeStyleTypeAny), "": - return enforceRepeatedArgTypeStyleTypeAny, nil - case string(enforceRepeatedArgTypeStyleTypeShort): - return enforceRepeatedArgTypeStyleTypeShort, nil - case string(enforceRepeatedArgTypeStyleTypeFull): - return enforceRepeatedArgTypeStyleTypeFull, nil - default: - err := fmt.Errorf( - "invalid repeated arg type style: %s (expecting one of %v)", - s, - []enforceRepeatedArgTypeStyleType{ - enforceRepeatedArgTypeStyleTypeAny, - enforceRepeatedArgTypeStyleTypeShort, - enforceRepeatedArgTypeStyleTypeFull, - }, - ) - - return "", fmt.Errorf("invalid argument to the enforce-repeated-arg-type-style rule: %w", err) - } -} - -// EnforceRepeatedArgTypeStyleRule implements a rule to enforce repeated argument type style. -type EnforceRepeatedArgTypeStyleRule struct { - funcArgStyle enforceRepeatedArgTypeStyleType - funcRetValStyle enforceRepeatedArgTypeStyleType -} - -// Configure validates the rule configuration, and configures the rule accordingly. -// -// Configuration implements the [lint.ConfigurableRule] interface. -func (r *EnforceRepeatedArgTypeStyleRule) Configure(arguments lint.Arguments) error { - r.funcArgStyle = enforceRepeatedArgTypeStyleTypeAny - r.funcRetValStyle = enforceRepeatedArgTypeStyleTypeAny - - if len(arguments) == 0 { - return nil - } - - switch funcArgStyle := arguments[0].(type) { - case string: - argstyle, err := repeatedArgTypeStyleFromString(funcArgStyle) - if err != nil { - return err - } - r.funcArgStyle = argstyle - valstyle, err := repeatedArgTypeStyleFromString(funcArgStyle) - if err != nil { - return err - } - r.funcRetValStyle = valstyle - case map[string]any: // expecting map[string]string - for k, v := range funcArgStyle { - switch { - case isRuleOption(k, "funcArgStyle"): - val, ok := v.(string) - if !ok { - return fmt.Errorf("invalid map value type for 'enforce-repeated-arg-type-style' rule. Expecting string, got %T", v) - } - valstyle, err := repeatedArgTypeStyleFromString(val) - if err != nil { - return err - } - r.funcArgStyle = valstyle - case isRuleOption(k, "funcRetValStyle"): - val, ok := v.(string) - if !ok { - return fmt.Errorf("invalid map value '%v' for 'enforce-repeated-arg-type-style' rule. Expecting string, got %T", v, v) - } - argstyle, err := repeatedArgTypeStyleFromString(val) - if err != nil { - return err - } - r.funcRetValStyle = argstyle - default: - return fmt.Errorf("invalid map key for 'enforce-repeated-arg-type-style' rule. Expecting 'funcArgStyle' or 'funcRetValStyle', got %v", k) - } - } - default: - return fmt.Errorf("invalid argument '%v' for 'import-alias-naming' rule. Expecting string or map[string]string, got %T", arguments[0], arguments[0]) - } - return nil -} - -// Apply applies the rule to a given file. -func (r *EnforceRepeatedArgTypeStyleRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - if r.funcArgStyle == enforceRepeatedArgTypeStyleTypeAny && r.funcRetValStyle == enforceRepeatedArgTypeStyleTypeAny { - // This linter is not configured, return no failures. - return nil - } - - var failures []lint.Failure - - astFile := file.AST - ast.Inspect(astFile, func(n ast.Node) bool { - if fn, ok := n.(*ast.FuncDecl); ok { - switch r.funcArgStyle { - case enforceRepeatedArgTypeStyleTypeFull: - if fn.Type.Params != nil { - for _, field := range fn.Type.Params.List { - if len(field.Names) > 1 { - failures = append(failures, lint.Failure{ - Confidence: 1, - Node: field, - Category: lint.FailureCategoryStyle, - Failure: "argument types should not be omitted", - }) - } - } - } - case enforceRepeatedArgTypeStyleTypeShort: - if fn.Type.Params != nil { - var prevType ast.Expr - for _, field := range fn.Type.Params.List { - prevTypeStr := astutils.GoFmt(prevType) - currentTypeStr := astutils.GoFmt(field.Type) - if currentTypeStr == prevTypeStr { - failures = append(failures, lint.Failure{ - Confidence: 1, - Node: prevType, - Category: lint.FailureCategoryStyle, - Failure: fmt.Sprintf("repeated argument type %q can be omitted", prevTypeStr), - }) - } - prevType = field.Type - } - } - } - - switch r.funcRetValStyle { - case enforceRepeatedArgTypeStyleTypeFull: - if fn.Type.Results != nil { - for _, field := range fn.Type.Results.List { - if len(field.Names) > 1 { - failures = append(failures, lint.Failure{ - Confidence: 1, - Node: field, - Category: lint.FailureCategoryStyle, - Failure: "return types should not be omitted", - }) - } - } - } - case enforceRepeatedArgTypeStyleTypeShort: - if fn.Type.Results != nil { - var prevType ast.Expr - for _, field := range fn.Type.Results.List { - prevTypeStr := astutils.GoFmt(prevType) - currentTypeStr := astutils.GoFmt(field.Type) - if field.Names != nil && currentTypeStr == prevTypeStr { - failures = append(failures, lint.Failure{ - Confidence: 1, - Node: prevType, - Category: lint.FailureCategoryStyle, - Failure: fmt.Sprintf("repeated return type %q can be omitted", prevTypeStr), - }) - } - prevType = field.Type - } - } - } - } - return true - }) - - return failures -} - -// Name returns the name of the linter rule. -func (*EnforceRepeatedArgTypeStyleRule) Name() string { - return "enforce-repeated-arg-type-style" -} diff --git a/vendor/github.com/mgechev/revive/rule/enforce_slice_style.go b/vendor/github.com/mgechev/revive/rule/enforce_slice_style.go deleted file mode 100644 index 9bc26a6a45..0000000000 --- a/vendor/github.com/mgechev/revive/rule/enforce_slice_style.go +++ /dev/null @@ -1,204 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - - "github.com/mgechev/revive/internal/astutils" - "github.com/mgechev/revive/lint" -) - -type enforceSliceStyleType string - -const ( - enforceSliceStyleTypeAny enforceSliceStyleType = "any" - enforceSliceStyleTypeMake enforceSliceStyleType = "make" - enforceSliceStyleTypeLiteral enforceSliceStyleType = "literal" - enforceSliceStyleTypeNil enforceSliceStyleType = "nil" -) - -func sliceStyleFromString(s string) (enforceSliceStyleType, error) { - switch s { - case string(enforceSliceStyleTypeAny), "": - return enforceSliceStyleTypeAny, nil - case string(enforceSliceStyleTypeMake): - return enforceSliceStyleTypeMake, nil - case string(enforceSliceStyleTypeLiteral): - return enforceSliceStyleTypeLiteral, nil - case string(enforceSliceStyleTypeNil): - return enforceSliceStyleTypeNil, nil - default: - return enforceSliceStyleTypeAny, fmt.Errorf( - "invalid slice style: %s (expecting one of %v)", - s, - []enforceSliceStyleType{ - enforceSliceStyleTypeAny, - enforceSliceStyleTypeMake, - enforceSliceStyleTypeLiteral, - enforceSliceStyleTypeNil, - }, - ) - } -} - -// EnforceSliceStyleRule implements a rule to enforce `make([]type)` over `[]type{}`. -type EnforceSliceStyleRule struct { - enforceSliceStyle enforceSliceStyleType -} - -// Configure validates the rule configuration, and configures the rule accordingly. -// -// Configuration implements the [lint.ConfigurableRule] interface. -func (r *EnforceSliceStyleRule) Configure(arguments lint.Arguments) error { - if len(arguments) < 1 { - r.enforceSliceStyle = enforceSliceStyleTypeAny - return nil - } - - enforceSliceStyle, ok := arguments[0].(string) - if !ok { - return fmt.Errorf("invalid argument '%v' for 'enforce-slice-style' rule. Expecting string, got %T", arguments[0], arguments[0]) - } - - var err error - r.enforceSliceStyle, err = sliceStyleFromString(enforceSliceStyle) - if err != nil { - return fmt.Errorf("invalid argument to the enforce-slice-style rule: %w", err) - } - return nil -} - -// Apply applies the rule to given file. -func (r *EnforceSliceStyleRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - if r.enforceSliceStyle == enforceSliceStyleTypeAny { - // this linter is not configured - return nil - } - - var failures []lint.Failure - - astFile := file.AST - ast.Inspect(astFile, func(n ast.Node) bool { - switch v := n.(type) { - case *ast.CompositeLit: - switch r.enforceSliceStyle { - case enforceSliceStyleTypeMake, enforceSliceStyleTypeNil: - // continue - default: - return true - } - - if !r.isSliceType(v.Type) { - return true - } - - isNotEmptySlice := len(v.Elts) > 0 - if isNotEmptySlice { - return true - } - - var failureMessage string - if r.enforceSliceStyle == enforceSliceStyleTypeNil { - failureMessage = "use nil slice declaration (e.g. var args []type) instead of []type{}" - } else { - failureMessage = "use make([]type) instead of []type{} (or declare nil slice)" - } - failures = append(failures, lint.Failure{ - Confidence: 1, - Node: v, - Category: lint.FailureCategoryStyle, - Failure: failureMessage, - }) - case *ast.CallExpr: - switch r.enforceSliceStyle { - case enforceSliceStyleTypeLiteral, enforceSliceStyleTypeNil: - default: - // skip any function calls, even if it's make([]type) - // we don't want to report it if literals are not enforced - return true - } - - if !astutils.IsIdent(v.Fun, "make") { - return true - } - - isInvalidMakeDeclaration := len(v.Args) < 2 - if isInvalidMakeDeclaration { - return true - } - - if !r.isSliceType(v.Args[0]) { - // not a slice type - return true - } - - arg, ok := v.Args[1].(*ast.BasicLit) - if !ok { - // skip invalid make declarations - return true - } - - isSliceSizeNotZero := arg.Value != "0" - if isSliceSizeNotZero { - return true - } - - if len(v.Args) > 2 { - arg, ok := v.Args[2].(*ast.BasicLit) - if !ok { - // skip invalid make declarations - return true - } - - isNonZeroCapacitySlice := arg.Value != "0" - if isNonZeroCapacitySlice { - return true - } - } - - var failureMessage string - if r.enforceSliceStyle == enforceSliceStyleTypeNil { - failureMessage = "use nil slice declaration (e.g. var args []type) instead of make([]type, 0)" - } else { - failureMessage = "use []type{} instead of make([]type, 0) (or declare nil slice)" - } - failures = append(failures, lint.Failure{ - Confidence: 1, - Node: v.Args[0], - Category: lint.FailureCategoryStyle, - Failure: failureMessage, - }) - } - return true - }) - - return failures -} - -// Name returns the rule name. -func (*EnforceSliceStyleRule) Name() string { - return "enforce-slice-style" -} - -func (r *EnforceSliceStyleRule) isSliceType(v ast.Expr) bool { - switch t := v.(type) { - case *ast.ArrayType: - if t.Len != nil { - // array - return false - } - // slice - return true - case *ast.Ident: - if t.Obj == nil { - return false - } - typeSpec, ok := t.Obj.Decl.(*ast.TypeSpec) - if !ok { - return false - } - return r.isSliceType(typeSpec.Type) - default: - return false - } -} diff --git a/vendor/github.com/mgechev/revive/rule/enforce_switch_style.go b/vendor/github.com/mgechev/revive/rule/enforce_switch_style.go deleted file mode 100644 index 96093d6203..0000000000 --- a/vendor/github.com/mgechev/revive/rule/enforce_switch_style.go +++ /dev/null @@ -1,134 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - "go/token" - - "github.com/mgechev/revive/lint" -) - -// EnforceSwitchStyleRule implements a rule to enforce default clauses use and/or position. -type EnforceSwitchStyleRule struct { - allowNoDefault bool // allow absence of default - allowDefaultNotLast bool // allow default, if present, not being the last case -} - -// Configure validates the rule configuration, and configures the rule accordingly. -// -// Configuration implements the [lint.ConfigurableRule] interface. -func (r *EnforceSwitchStyleRule) Configure(arguments lint.Arguments) error { - if len(arguments) < 1 { - return nil - } - - for _, arg := range arguments { - argStr, ok := arg.(string) - if !ok { - return fmt.Errorf("invalid argument for rule %s; expected string but got %T", r.Name(), arg) - } - switch { - case isRuleOption(argStr, "allowNoDefault"): - r.allowNoDefault = true - case isRuleOption(argStr, "allowDefaultNotLast"): - r.allowDefaultNotLast = true - default: - return fmt.Errorf(`invalid argument %q for rule %s; expected "allowNoDefault" or "allowDefaultNotLast"`, argStr, r.Name()) - } - } - - return nil -} - -// Apply applies the rule to given file. -func (r *EnforceSwitchStyleRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - astFile := file.AST - ast.Inspect(astFile, func(n ast.Node) bool { - switchNode, ok := n.(*ast.SwitchStmt) - if !ok { - return true // not a switch statement - } - - defaultClause, isLast := r.seekDefaultCase(switchNode.Body) - hasDefault := defaultClause != nil - - if !hasDefault && r.allowNoDefault { - return true // switch without default but the rule is configured to don´t care - } - - if !hasDefault && !r.allowNoDefault { - // switch without default - if !r.allBranchesEndWithJumpStmt(switchNode) { - failures = append(failures, lint.Failure{ - Confidence: 1, - Node: switchNode, - Category: lint.FailureCategoryStyle, - Failure: "switch must have a default case clause", - }) - } - - return true - } - - // the switch has a default - - if r.allowDefaultNotLast || isLast { - return true - } - - failures = append(failures, lint.Failure{ - Confidence: 1, - Node: defaultClause, - Category: lint.FailureCategoryStyle, - Failure: "default case clause must be the last one", - }) - - return true - }) - - return failures -} - -func (*EnforceSwitchStyleRule) seekDefaultCase(body *ast.BlockStmt) (defaultClause *ast.CaseClause, isLast bool) { - var last *ast.CaseClause - for _, stmt := range body.List { - cc, _ := stmt.(*ast.CaseClause) // no need to check for ok - last = cc - if cc.List == nil { // a nil List means "default" - defaultClause = cc - } - } - - return defaultClause, defaultClause == last -} - -func (*EnforceSwitchStyleRule) allBranchesEndWithJumpStmt(switchStmt *ast.SwitchStmt) bool { - for _, stmt := range switchStmt.Body.List { - caseClause := stmt.(*ast.CaseClause) // safe to assume stmt is a case clause - - caseBody := caseClause.Body - if caseBody == nil { - return false - } - - lastStmt := caseBody[len(caseBody)-1] - - if _, ok := lastStmt.(*ast.ReturnStmt); ok { - continue - } - - if jump, ok := lastStmt.(*ast.BranchStmt); ok && jump.Tok == token.BREAK { - continue - } - - return false - } - - return true -} - -// Name returns the rule name. -func (*EnforceSwitchStyleRule) Name() string { - return "enforce-switch-style" -} diff --git a/vendor/github.com/mgechev/revive/rule/error_naming.go b/vendor/github.com/mgechev/revive/rule/error_naming.go deleted file mode 100644 index 6de9c31160..0000000000 --- a/vendor/github.com/mgechev/revive/rule/error_naming.go +++ /dev/null @@ -1,91 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - "go/token" - "strings" - - "github.com/mgechev/revive/internal/astutils" - "github.com/mgechev/revive/lint" -) - -// ErrorNamingRule lints naming of error variables. -type ErrorNamingRule struct{} - -// Apply applies the rule to given file. -func (*ErrorNamingRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - fileAst := file.AST - walker := lintErrors{ - file: file, - fileAst: fileAst, - onFailure: func(failure lint.Failure) { - failures = append(failures, failure) - }, - } - - ast.Walk(walker, fileAst) - - return failures -} - -// Name returns the rule name. -func (*ErrorNamingRule) Name() string { - return "error-naming" -} - -type lintErrors struct { - file *lint.File - fileAst *ast.File - onFailure func(lint.Failure) -} - -func (w lintErrors) Visit(_ ast.Node) ast.Visitor { - for _, decl := range w.fileAst.Decls { - gd, ok := decl.(*ast.GenDecl) - if !ok || gd.Tok != token.VAR { - continue - } - for _, spec := range gd.Specs { - spec := spec.(*ast.ValueSpec) - if len(spec.Names) != 1 || len(spec.Values) != 1 { - continue - } - ce, ok := spec.Values[0].(*ast.CallExpr) - if !ok { - continue - } - if !astutils.IsPkgDotName(ce.Fun, "errors", "New") && !astutils.IsPkgDotName(ce.Fun, "fmt", "Errorf") { - continue - } - - id := spec.Names[0] - if id.Name == "_" { - // avoid false positive for blank identifier - - // The fact that the error variable is not used - // is out of the scope of the rule - - // This pattern that can be found in benchmarks and examples - // should be allowed. - continue - } - - prefix := "err" - if id.IsExported() { - prefix = "Err" - } - if !strings.HasPrefix(id.Name, prefix) { - w.onFailure(lint.Failure{ - Node: id, - Confidence: 0.9, - Category: lint.FailureCategoryNaming, - Failure: fmt.Sprintf("error var %s should have name of the form %sFoo", id.Name, prefix), - }) - } - } - } - return nil -} diff --git a/vendor/github.com/mgechev/revive/rule/error_return.go b/vendor/github.com/mgechev/revive/rule/error_return.go deleted file mode 100644 index 812ca753c9..0000000000 --- a/vendor/github.com/mgechev/revive/rule/error_return.go +++ /dev/null @@ -1,52 +0,0 @@ -package rule - -import ( - "go/ast" - - "github.com/mgechev/revive/internal/astutils" - "github.com/mgechev/revive/lint" -) - -// ErrorReturnRule ensures that the error return parameter is the last parameter. -type ErrorReturnRule struct{} - -// Apply applies the rule to given file. -func (*ErrorReturnRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - for _, decl := range file.AST.Decls { - funcDecl, ok := decl.(*ast.FuncDecl) - isFunctionWithMoreThanOneResult := ok && funcDecl.Type.Results != nil && len(funcDecl.Type.Results.List) > 1 - if !isFunctionWithMoreThanOneResult { - continue - } - - funcResults := funcDecl.Type.Results.List - isLastResultError := astutils.IsIdent(funcResults[len(funcResults)-1].Type, "error") - if isLastResultError { - continue - } - - // An error return parameter should be the last parameter. - // Flag any error parameters found before the last. - for _, r := range funcResults[:len(funcResults)-1] { - if astutils.IsIdent(r.Type, "error") { - failures = append(failures, lint.Failure{ - Category: lint.FailureCategoryStyle, - Confidence: 0.9, - Node: funcDecl, - Failure: "error should be the last type when returning multiple items", - }) - - break // only flag one - } - } - } - - return failures -} - -// Name returns the rule name. -func (*ErrorReturnRule) Name() string { - return "error-return" -} diff --git a/vendor/github.com/mgechev/revive/rule/error_strings.go b/vendor/github.com/mgechev/revive/rule/error_strings.go deleted file mode 100644 index 53a585bfb0..0000000000 --- a/vendor/github.com/mgechev/revive/rule/error_strings.go +++ /dev/null @@ -1,206 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - "go/token" - "strconv" - "strings" - "unicode" - "unicode/utf8" - - "github.com/mgechev/revive/lint" -) - -// ErrorStringsRule lints error strings. -type ErrorStringsRule struct { - errorFunctions map[string]map[string]struct{} -} - -// Configure validates the rule configuration, and configures the rule accordingly. -// -// Configuration implements the [lint.ConfigurableRule] interface. -func (r *ErrorStringsRule) Configure(arguments lint.Arguments) error { - r.errorFunctions = map[string]map[string]struct{}{ - "fmt": { - "Errorf": {}, - }, - "errors": { - "Errorf": {}, - "WithMessage": {}, - "Wrap": {}, - "New": {}, - "WithMessagef": {}, - "Wrapf": {}, - }, - } - - var invalidCustomFunctions []string - for _, argument := range arguments { - pkgFunction, ok := argument.(string) - if !ok { - continue - } - pkg, function, ok := strings.Cut(strings.TrimSpace(pkgFunction), ".") - if !ok || pkg == "" || function == "" { - invalidCustomFunctions = append(invalidCustomFunctions, pkgFunction) - continue - } - if _, ok := r.errorFunctions[pkg]; !ok { - r.errorFunctions[pkg] = map[string]struct{}{} - } - r.errorFunctions[pkg][function] = struct{}{} - } - if len(invalidCustomFunctions) != 0 { - return fmt.Errorf("found invalid custom function: %s", strings.Join(invalidCustomFunctions, ",")) - } - return nil -} - -// Apply applies the rule to given file. -func (r *ErrorStringsRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - fileAst := file.AST - walker := lintErrorStrings{ - file: file, - fileAst: fileAst, - errorFunctions: r.errorFunctions, - onFailure: func(failure lint.Failure) { - failures = append(failures, failure) - }, - } - - ast.Walk(walker, fileAst) - - return failures -} - -// Name returns the rule name. -func (*ErrorStringsRule) Name() string { - return "error-strings" -} - -type lintErrorStrings struct { - file *lint.File - fileAst *ast.File - errorFunctions map[string]map[string]struct{} - onFailure func(lint.Failure) -} - -// Visit browses the AST. -func (w lintErrorStrings) Visit(n ast.Node) ast.Visitor { - ce, ok := n.(*ast.CallExpr) - if !ok { - return w - } - - if len(ce.Args) < 1 { - return w - } - - // expression matches the known pkg.function - ok = w.match(ce) - if !ok { - return w - } - - str, ok := w.getMessage(ce) - if !ok { - return w - } - s, _ := strconv.Unquote(str.Value) // can assume well-formed Go - if s == "" { - return w - } - clean, conf := lintErrorString(s) - if clean { - return w - } - w.onFailure(lint.Failure{ - Node: str, - Confidence: conf, - Category: lint.FailureCategoryErrors, - Failure: "error strings should not be capitalized or end with punctuation or a newline", - }) - return w -} - -// match returns true if the expression corresponds to the known pkg.function, -// i.e.: errors.Wrap. -func (w lintErrorStrings) match(expr *ast.CallExpr) bool { - sel, ok := expr.Fun.(*ast.SelectorExpr) - if !ok { - return false - } - // retrieve the package - id, ok := sel.X.(*ast.Ident) - if !ok { - return false - } - functions, ok := w.errorFunctions[id.Name] - if !ok { - return false - } - // retrieve the function - _, ok = functions[sel.Sel.Name] - return ok -} - -// getMessage returns the message depending on its position. -// Returns false if the cast is unsuccessful. -func (w lintErrorStrings) getMessage(expr *ast.CallExpr) (s *ast.BasicLit, success bool) { - str, ok := w.checkArg(expr, 0) - if ok { - return str, true - } - if len(expr.Args) < 2 { - return s, false - } - str, ok = w.checkArg(expr, 1) - if !ok { - return s, false - } - return str, true -} - -func (lintErrorStrings) checkArg(expr *ast.CallExpr, arg int) (s *ast.BasicLit, success bool) { - str, ok := expr.Args[arg].(*ast.BasicLit) - if !ok { - return s, false - } - if str.Kind != token.STRING { - return s, false - } - return str, true -} - -func lintErrorString(s string) (isClean bool, conf float64) { - const basicConfidence = 0.8 - const capConfidence = basicConfidence - 0.2 - - last, _ := utf8.DecodeLastRuneInString(s) - if last == '.' || last == ':' || last == '!' || last == '\n' { - return false, basicConfidence - } - - first, firstN := utf8.DecodeRuneInString(s) - if !unicode.IsUpper(first) { - return true, 0 - } - - // People use proper nouns and exported Go identifiers in error strings, - // so decrease the confidence of warnings for capitalization. - for _, r := range s[firstN:] { - if unicode.IsSpace(r) { - break - } - - if unicode.IsUpper(r) || unicode.IsDigit(r) { - return true, 0 // accept words with more than 2 capital letters or digits (e.g. GitHub, URLs, I2000) - } - } - - // Flag strings starting with something that doesn't look like an initialism. - return false, capConfidence -} diff --git a/vendor/github.com/mgechev/revive/rule/errorf.go b/vendor/github.com/mgechev/revive/rule/errorf.go deleted file mode 100644 index a7c115944b..0000000000 --- a/vendor/github.com/mgechev/revive/rule/errorf.go +++ /dev/null @@ -1,94 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - "regexp" - "strings" - - "github.com/mgechev/revive/internal/astutils" - "github.com/mgechev/revive/lint" -) - -// ErrorfRule suggests using `fmt.Errorf` instead of `errors.New(fmt.Sprintf())`. -type ErrorfRule struct{} - -// Apply applies the rule to given file. -func (*ErrorfRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - fileAst := file.AST - walker := lintErrorf{ - file: file, - fileAst: fileAst, - onFailure: func(failure lint.Failure) { - failures = append(failures, failure) - }, - } - - file.Pkg.TypeCheck() - ast.Walk(walker, fileAst) - - return failures -} - -// Name returns the rule name. -func (*ErrorfRule) Name() string { - return "errorf" -} - -type lintErrorf struct { - file *lint.File - fileAst *ast.File - onFailure func(lint.Failure) -} - -func (w lintErrorf) Visit(n ast.Node) ast.Visitor { - ce, ok := n.(*ast.CallExpr) - if !ok || len(ce.Args) != 1 { - return w - } - isErrorsNew := astutils.IsPkgDotName(ce.Fun, "errors", "New") - var isTestingError bool - se, ok := ce.Fun.(*ast.SelectorExpr) - if ok && se.Sel.Name == "Error" { - if typ := w.file.Pkg.TypeOf(se.X); typ != nil { - isTestingError = typ.String() == "*testing.T" - } - } - if !isErrorsNew && !isTestingError { - return w - } - arg := ce.Args[0] - ce, ok = arg.(*ast.CallExpr) - if !ok || !astutils.IsPkgDotName(ce.Fun, "fmt", "Sprintf") { - return w - } - errorfPrefix := "fmt" - if isTestingError { - errorfPrefix = w.file.Render(se.X) - } - - failure := lint.Failure{ - Category: lint.FailureCategoryErrors, - Node: n, - Confidence: 1, - Failure: fmt.Sprintf("should replace %s(fmt.Sprintf(...)) with %s.Errorf(...)", w.file.Render(se), errorfPrefix), - } - - m := srcLineWithMatch(w.file, ce, `^(.*)`+w.file.Render(se)+`\(fmt\.Sprintf\((.*)\)\)(.*)$`) - if m != nil { - failure.ReplacementLine = m[1] + errorfPrefix + ".Errorf(" + m[2] + ")" + m[3] - } - - w.onFailure(failure) - - return w -} - -func srcLineWithMatch(file *lint.File, node ast.Node, pattern string) (m []string) { - line := srcLine(file.Content(), file.ToPosition(node.Pos())) - line = strings.TrimSuffix(line, "\n") - rx := regexp.MustCompile(pattern) - return rx.FindStringSubmatch(line) -} diff --git a/vendor/github.com/mgechev/revive/rule/exported.go b/vendor/github.com/mgechev/revive/rule/exported.go deleted file mode 100644 index eb351cf4d3..0000000000 --- a/vendor/github.com/mgechev/revive/rule/exported.go +++ /dev/null @@ -1,547 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - "go/token" - "strings" - "unicode" - "unicode/utf8" - - "github.com/mgechev/revive/internal/typeparams" - "github.com/mgechev/revive/lint" -) - -// disabledChecks store ignored warnings types. -type disabledChecks struct { - Const bool - Function bool - Method bool - PrivateReceivers bool - PublicInterfaces bool - RepetitiveNames bool - Type bool - Var bool -} - -const ( - checkNamePrivateReceivers = "privateReceivers" - checkNamePublicInterfaces = "publicInterfaces" - checkNameStuttering = "stuttering" -) - -// isDisabled returns true if the given check is disabled, false otherwise. -func (dc *disabledChecks) isDisabled(checkName string) bool { - switch checkName { - case "var": - return dc.Var - case "const": - return dc.Const - case "function": - return dc.Function - case "method": - return dc.Method - case checkNamePrivateReceivers: - return dc.PrivateReceivers - case checkNamePublicInterfaces: - return dc.PublicInterfaces - case checkNameStuttering: - return dc.RepetitiveNames - case "type": - return dc.Type - default: - return false - } -} - -var commonMethods = map[string]bool{ - "Error": true, - "Read": true, - "ServeHTTP": true, - "String": true, - "Write": true, - "Unwrap": true, -} - -// ExportedRule lints naming and commenting conventions on exported symbols. -type ExportedRule struct { - isRepetitiveMsg string - disabledChecks disabledChecks -} - -// Configure validates the rule configuration, and configures the rule accordingly. -// -// Configure makes the rule implement the [lint.ConfigurableRule] interface. -func (r *ExportedRule) Configure(arguments lint.Arguments) error { - r.disabledChecks = disabledChecks{PrivateReceivers: true, PublicInterfaces: true} - r.isRepetitiveMsg = "stutters" - for _, flag := range arguments { - switch flag := flag.(type) { - case string: - switch { - case isRuleOption(flag, "checkPrivateReceivers"): - r.disabledChecks.PrivateReceivers = false - case isRuleOption(flag, "disableStutteringCheck"): - r.disabledChecks.RepetitiveNames = true - case isRuleOption(flag, "sayRepetitiveInsteadOfStutters"): - r.isRepetitiveMsg = "is repetitive" - case isRuleOption(flag, "checkPublicInterface"): - r.disabledChecks.PublicInterfaces = false - case isRuleOption(flag, "disableChecksOnConstants"): - r.disabledChecks.Const = true - case isRuleOption(flag, "disableChecksOnFunctions"): - r.disabledChecks.Function = true - case isRuleOption(flag, "disableChecksOnMethods"): - r.disabledChecks.Method = true - case isRuleOption(flag, "disableChecksOnTypes"): - r.disabledChecks.Type = true - case isRuleOption(flag, "disableChecksOnVariables"): - r.disabledChecks.Var = true - default: - return fmt.Errorf("unknown configuration flag %s for %s rule", flag, r.Name()) - } - default: - return fmt.Errorf("invalid argument for the %s rule: expecting a string, got %T", r.Name(), flag) - } - } - - return nil -} - -// Apply applies the rule to given file. -func (r *ExportedRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - if !file.IsImportable() { - return nil - } - - var failures []lint.Failure - walker := lintExported{ - file: file, - onFailure: func(failure lint.Failure) { - failures = append(failures, failure) - }, - genDeclMissingComments: map[*ast.GenDecl]bool{}, - isRepetitiveMsg: r.isRepetitiveMsg, - disabledChecks: r.disabledChecks, - } - - ast.Walk(&walker, file.AST) - - return failures -} - -// Name returns the rule name. -func (*ExportedRule) Name() string { - return "exported" -} - -type lintExported struct { - file *lint.File - lastGenDecl *ast.GenDecl // the last visited general declaration in the AST - genDeclMissingComments map[*ast.GenDecl]bool - onFailure func(lint.Failure) - isRepetitiveMsg string - disabledChecks disabledChecks -} - -func (w *lintExported) lintFuncDoc(fn *ast.FuncDecl) { - if !ast.IsExported(fn.Name.Name) { - return // func is unexported, nothing to do - } - - kind := "function" - name := fn.Name.Name - if isMethod := fn.Recv != nil && len(fn.Recv.List) > 0; isMethod { - if !w.mustCheckMethod(fn) { - return - } - - kind = "method" - recv := typeparams.ReceiverType(fn) - name = recv + "." + name - } - - if w.disabledChecks.isDisabled(kind) { - return - } - - status := w.checkGoDocStatus(fn.Doc, fn.Name.Name) - switch status { - case exportedGoDocStatusOK: - return // comment is fine - case exportedGoDocStatusMissing: - w.addFailuref(fn, status.Confidence(), lint.FailureCategoryComments, - "exported %s %s should have comment or be unexported", kind, name, - ) - return - } - - firstCommentLine := w.firstCommentLine(fn.Doc) - w.addFailuref(fn.Doc, status.Confidence(), lint.FailureCategoryComments, - `comment on exported %s %s should be of the form "%s ..."%s`, kind, name, fn.Name.Name, status.CorrectionHint(firstCommentLine), - ) -} - -func (*lintExported) hasPrefixInsensitive(s, prefix string) bool { - return strings.HasPrefix(strings.ToLower(s), strings.ToLower(prefix)) -} - -func (*lintExported) stripFirstRune(s string) string { - // Decode the first rune to handle multi-byte characters. - firstRune, size := utf8.DecodeRuneInString(s) - if firstRune == utf8.RuneError { - return s // no valid first rune found - } - - // Return the string without the first rune. - return s[size:] -} - -func (w *lintExported) checkRepetitiveNames(id *ast.Ident, thing string) { - if w.disabledChecks.RepetitiveNames { - return - } - - pkg, name := w.file.AST.Name.Name, id.Name - if !ast.IsExported(name) { - // unexported name - return - } - // A name is repetitive if the package name is a strict prefix - // and the next character of the name starts a new word. - if len(name) <= len(pkg) { - // name is too short to be a repetition. - // This permits the name to be the same as the package name. - return - } - if !strings.EqualFold(pkg, name[:len(pkg)]) { - return - } - // We can assume the name is well-formed UTF-8. - // If the next rune after the package name is uppercase or an underscore - // the it's starting a new word and thus this name is repetitive. - rem := name[len(pkg):] - if next, _ := utf8.DecodeRuneInString(rem); next == '_' || unicode.IsUpper(next) { - w.addFailuref(id, 0.8, lint.FailureCategoryNaming, - "%s name will be used as %s.%s by other packages, and that %s; consider calling this %s", thing, pkg, name, w.isRepetitiveMsg, rem, - ) - } -} - -var articles = [...]string{"A", "An", "The", "This"} - -func (w *lintExported) lintTypeDoc(t *ast.TypeSpec, doc *ast.CommentGroup, firstCommentLine string) { - if w.disabledChecks.isDisabled("type") { - return - } - - typeName := t.Name.Name - - if !ast.IsExported(typeName) { - return - } - - if firstCommentLine == "" { - w.addFailuref(t, 1, lint.FailureCategoryComments, - "exported type %v should have comment or be unexported", t.Name, - ) - return - } - - expectedPrefix := typeName - for _, a := range articles { - if typeName == a { - continue - } - var found bool - if firstCommentLine, found = strings.CutPrefix(firstCommentLine, a+" "); found { - expectedPrefix = a + " " + typeName - break - } - } - - status := w.checkGoDocStatus(doc, expectedPrefix) - if status == exportedGoDocStatusOK { - return - } - w.addFailuref(doc, status.Confidence(), lint.FailureCategoryComments, - `comment on exported type %v should be of the form "%s ..." (with optional leading article)%s`, t.Name, typeName, status.CorrectionHint(firstCommentLine), - ) -} - -// checkValueNames returns true if names check, false otherwise. -func (w *lintExported) checkValueNames(names []*ast.Ident, nodeToBlame ast.Node, kind string) bool { - // Check that none are exported except for the first. - if len(names) < 2 { - return true // nothing to check - } - - for _, n := range names[1:] { - if ast.IsExported(n.Name) { - w.addFailuref(nodeToBlame, 1, lint.FailureCategoryComments, - "exported %s %s should have its own declaration", kind, n.Name, - ) - return false - } - } - - return true -} - -func (w *lintExported) lintValueSpecDoc(vs *ast.ValueSpec, gd *ast.GenDecl, genDeclMissingComments map[*ast.GenDecl]bool) { - kind := "var" - if gd.Tok == token.CONST { - kind = "const" - } - - if w.disabledChecks.isDisabled(kind) { - return - } - - if !w.checkValueNames(vs.Names, vs, kind) { - return - } - - // Only one name. - name := vs.Names[0].Name - if !ast.IsExported(name) { - return - } - - vsFirstCommentLine := w.firstCommentLine(vs.Doc) - gdFirstCommentLine := w.firstCommentLine(gd.Doc) - if vsFirstCommentLine == "" && gdFirstCommentLine == "" { - if genDeclMissingComments[gd] { - return - } - block := "" - if kind == "const" && gd.Lparen.IsValid() { - block = " (or a comment on this block)" - } - w.addFailuref(vs, 1, lint.FailureCategoryComments, - "exported %s %s should have comment%s or be unexported", kind, name, block, - ) - genDeclMissingComments[gd] = true - return - } - - // If this GenDecl has parens and a comment, we don't check its comment form. - if gdFirstCommentLine != "" && gd.Lparen.IsValid() { - return - } - - // The relevant text to check will be on either vs.Doc or gd.Doc. - // Use vs.Doc preferentially. - var doc *ast.CommentGroup - switch { - case vsFirstCommentLine != "": - doc = vs.Doc - case vsFirstCommentLine != "" && gdFirstCommentLine == "": - doc = vs.Comment - default: - doc = gd.Doc - } - firstCommentLine := w.firstCommentLine(doc) - - status := w.checkGoDocStatus(doc, name) - if status == exportedGoDocStatusOK { - return - } - w.addFailuref(doc, status.Confidence(), lint.FailureCategoryComments, - `comment on exported %s %s should be of the form "%s ..."%s`, kind, name, name, status.CorrectionHint(firstCommentLine), - ) -} - -type exportedGoDocStatus int - -const ( - exportedGoDocStatusOK exportedGoDocStatus = iota - exportedGoDocStatusMissing - exportedGoDocStatusCaseMismatch - exportedGoDocStatusFirstLetterMismatch - exportedGoDocStatusUnexpected -) - -func (gds exportedGoDocStatus) Confidence() float64 { - if gds == exportedGoDocStatusUnexpected { - return 0.8 - } - return 1 -} - -func (gds exportedGoDocStatus) CorrectionHint(firstCommentLine string) string { - firstWord := strings.Split(firstCommentLine, " ")[0] - switch gds { - case exportedGoDocStatusCaseMismatch: - return ` by using its correct casing, not "` + firstWord + ` ..."` - case exportedGoDocStatusFirstLetterMismatch: - return ` to match its exported status, not "` + firstWord + ` ..."` - } - - return "" -} - -func (w *lintExported) checkGoDocStatus(comment *ast.CommentGroup, name string) exportedGoDocStatus { - firstCommentLine := w.firstCommentLine(comment) - if firstCommentLine == "" { - return exportedGoDocStatusMissing - } - - name = strings.TrimSpace(name) - // Make sure the expected prefix has a space at the end. - expectedPrefix := name + " " - if strings.HasPrefix(firstCommentLine, expectedPrefix) { - return exportedGoDocStatusOK - } - - if !w.hasPrefixInsensitive(firstCommentLine, expectedPrefix) { - return exportedGoDocStatusUnexpected - } - - if strings.HasPrefix(w.stripFirstRune(firstCommentLine), w.stripFirstRune(expectedPrefix)) { - // Only the first character differs, such as "sendJSON" became "SendJSON". - // so we consider the scope has changed. - return exportedGoDocStatusFirstLetterMismatch - } - - return exportedGoDocStatusCaseMismatch -} - -// firstCommentLine yields the first line of interest in comment group or "" if there is nothing of interest. -// An "interesting line" is a comment line that is neither a directive (e.g. //go:...) or a deprecation comment -// (lines from the first line with a prefix // Deprecated: to the end of the comment group) -// Empty or spaces-only lines are discarded. -func (lintExported) firstCommentLine(comment *ast.CommentGroup) (result string) { - if comment == nil { - return "" - } - - commentWithoutDirectives := comment.Text() // removes directives from the comment block - lines := strings.Split(commentWithoutDirectives, "\n") - for _, line := range lines { - line := strings.TrimSpace(line) - if line == "" { - continue // ignore empty lines - } - if strings.HasPrefix(line, "Deprecated: ") { - break // ignore deprecation comment line and the subsequent lines of the original comment - } - - result = line - break // first non-directive/non-empty/non-deprecation comment line found - } - - return result -} - -func (w *lintExported) Visit(n ast.Node) ast.Visitor { - switch v := n.(type) { - case *ast.GenDecl: - switch v.Tok { - case token.IMPORT: - return nil - case token.CONST, token.TYPE, token.VAR: - w.lastGenDecl = v - } - return w - case *ast.FuncDecl: - w.lintFuncDoc(v) - if v.Recv == nil { - // Only check for repetitive names on functions, not methods. - // Method names are not used package-qualified. - w.checkRepetitiveNames(v.Name, "func") - } - // Don't proceed inside funcs. - return nil - case *ast.TypeSpec: - // inside a GenDecl, which usually has the doc - doc := v.Doc - - fcl := w.firstCommentLine(doc) - if fcl == "" { - doc = w.lastGenDecl.Doc - fcl = w.firstCommentLine(doc) - } - w.lintTypeDoc(v, doc, fcl) - w.checkRepetitiveNames(v.Name, "type") - - if !w.disabledChecks.PublicInterfaces { - if iface, ok := v.Type.(*ast.InterfaceType); ok { - if ast.IsExported(v.Name.Name) { - w.doCheckPublicInterface(v.Name.Name, iface) - } - } - } - - return nil - case *ast.ValueSpec: - w.lintValueSpecDoc(v, w.lastGenDecl, w.genDeclMissingComments) - return nil - } - return w -} - -func (w *lintExported) doCheckPublicInterface(typeName string, iface *ast.InterfaceType) { - for _, m := range iface.Methods.List { - w.lintInterfaceMethod(typeName, m) - } -} - -func (w *lintExported) lintInterfaceMethod(typeName string, m *ast.Field) { - if len(m.Names) == 0 { - return - } - if !ast.IsExported(m.Names[0].Name) { - return - } - - name := m.Names[0].Name - status := w.checkGoDocStatus(m.Doc, name) - switch status { - case exportedGoDocStatusOK: - return // comment is fine - case exportedGoDocStatusMissing: - w.addFailuref(m, status.Confidence(), lint.FailureCategoryComments, - "public interface method %s.%s should be commented", typeName, name, - ) - return - } - - firstCommentLine := w.firstCommentLine(m.Doc) - w.addFailuref(m.Doc, status.Confidence(), lint.FailureCategoryComments, - `comment on exported interface method %s.%s should be of the form "%s ..."%s`, typeName, name, name, status.CorrectionHint(firstCommentLine), - ) -} - -// mustCheckMethod returns true if the method must be checked by this rule, false otherwise. -func (w *lintExported) mustCheckMethod(fn *ast.FuncDecl) bool { - recv := typeparams.ReceiverType(fn) - - if !ast.IsExported(recv) && w.disabledChecks.PrivateReceivers { - return false - } - - name := fn.Name.Name - if commonMethods[name] { - return false - } - - switch name { - case "Len", "Less", "Swap": - sortables := w.file.Pkg.Sortable() - if sortables[recv] { - return false - } - } - - return true -} - -func (w *lintExported) addFailuref(node ast.Node, confidence float64, category lint.FailureCategory, message string, args ...any) { - w.onFailure(lint.Failure{ - Node: node, - Confidence: confidence, - Category: category, - Failure: fmt.Sprintf(message, args...), - }) -} diff --git a/vendor/github.com/mgechev/revive/rule/file_header.go b/vendor/github.com/mgechev/revive/rule/file_header.go deleted file mode 100644 index 53d7ea9d03..0000000000 --- a/vendor/github.com/mgechev/revive/rule/file_header.go +++ /dev/null @@ -1,83 +0,0 @@ -package rule - -import ( - "fmt" - "regexp" - - "github.com/mgechev/revive/lint" -) - -// FileHeaderRule lints the header that each file should have. -type FileHeaderRule struct { - header string -} - -var ( - multiRegexp = regexp.MustCompile(`^/\*`) - singleRegexp = regexp.MustCompile("^//") -) - -// Configure validates the rule configuration, and configures the rule accordingly. -// -// Configuration implements the [lint.ConfigurableRule] interface. -func (r *FileHeaderRule) Configure(arguments lint.Arguments) error { - if len(arguments) < 1 { - return nil - } - - var ok bool - r.header, ok = arguments[0].(string) - if !ok { - return fmt.Errorf(`invalid argument for "file-header" rule: argument should be a string, got %T`, arguments[0]) - } - return nil -} - -// Apply applies the rule to given file. -func (r *FileHeaderRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - if r.header == "" { - return nil - } - - failure := []lint.Failure{ - { - Node: file.AST, - Confidence: 1, - Failure: "the file doesn't have an appropriate header", - }, - } - - if len(file.AST.Comments) == 0 { - return failure - } - - g := file.AST.Comments[0] - if g == nil { - return failure - } - comment := "" - for _, c := range g.List { - text := c.Text - if multiRegexp.MatchString(text) { - text = text[2 : len(text)-2] - } else if singleRegexp.MatchString(text) { - text = text[2:] - } - comment += text - } - - regex, err := regexp.Compile(r.header) - if err != nil { - return newInternalFailureError(err) - } - - if !regex.MatchString(comment) { - return failure - } - return nil -} - -// Name returns the rule name. -func (*FileHeaderRule) Name() string { - return "file-header" -} diff --git a/vendor/github.com/mgechev/revive/rule/file_length_limit.go b/vendor/github.com/mgechev/revive/rule/file_length_limit.go deleted file mode 100644 index a9b4e8da93..0000000000 --- a/vendor/github.com/mgechev/revive/rule/file_length_limit.go +++ /dev/null @@ -1,131 +0,0 @@ -package rule - -import ( - "bufio" - "bytes" - "fmt" - "go/ast" - "go/token" - "strings" - - "github.com/mgechev/revive/lint" -) - -// FileLengthLimitRule lints the number of lines in a file. -type FileLengthLimitRule struct { - // max is the maximum number of lines allowed in a file. 0 means the rule is disabled. - max int - // skipComments indicates whether to skip comment lines when counting lines. - skipComments bool - // skipBlankLines indicates whether to skip blank lines when counting lines. - skipBlankLines bool -} - -// Apply applies the rule to given file. -func (r *FileLengthLimitRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - if r.max <= 0 { - // when max is negative or 0 the rule is disabled - return nil - } - - all := 0 - blank := 0 - scanner := bufio.NewScanner(bytes.NewReader(file.Content())) - for scanner.Scan() { - all++ - if len(bytes.TrimSpace(scanner.Bytes())) == 0 { - blank++ - } - } - - if err := scanner.Err(); err != nil { - return newInternalFailureError(err) - } - - lines := all - if r.skipComments { - lines -= countCommentLines(file.AST.Comments) - } - - if r.skipBlankLines { - lines -= blank - } - - if lines <= r.max { - return nil - } - - return []lint.Failure{ - { - Category: lint.FailureCategoryCodeStyle, - Confidence: 1, - Position: lint.FailurePosition{ - Start: token.Position{ - Filename: file.Name, - Line: all, - }, - }, - Failure: fmt.Sprintf("file length is %d lines, which exceeds the limit of %d", lines, r.max), - }, - } -} - -// Configure validates the rule configuration, and configures the rule accordingly. -// -// Configuration implements the [lint.ConfigurableRule] interface. -func (r *FileLengthLimitRule) Configure(arguments lint.Arguments) error { - if len(arguments) < 1 { - return nil // use default - } - - argKV, ok := arguments[0].(map[string]any) - if !ok { - return fmt.Errorf(`invalid argument to the "file-length-limit" rule. Expecting a k,v map, got %T`, arguments[0]) - } - for k, v := range argKV { - switch { - case isRuleOption(k, "max"): - maxLines, ok := v.(int64) - if !ok || maxLines < 0 { - return fmt.Errorf(`invalid configuration value for max lines in "file-length-limit" rule; need positive int64 but got %T`, v) - } - r.max = int(maxLines) - case isRuleOption(k, "skipComments"): - skipComments, ok := v.(bool) - if !ok { - return fmt.Errorf(`invalid configuration value for skip comments in "file-length-limit" rule; need bool but got %T`, v) - } - r.skipComments = skipComments - case isRuleOption(k, "skipBlankLines"): - skipBlankLines, ok := v.(bool) - if !ok { - return fmt.Errorf(`invalid configuration value for skip blank lines in "file-length-limit" rule; need bool but got %T`, v) - } - r.skipBlankLines = skipBlankLines - } - } - return nil -} - -// Name returns the rule name. -func (*FileLengthLimitRule) Name() string { - return "file-length-limit" -} - -func countCommentLines(comments []*ast.CommentGroup) int { - count := 0 - for _, cg := range comments { - for _, comment := range cg.List { - if len(comment.Text) < 2 { - continue - } - switch comment.Text[1] { - case '/': // single-line comment - count++ - case '*': // multi-line comment - count += strings.Count(comment.Text, "\n") + 1 - } - } - } - return count -} diff --git a/vendor/github.com/mgechev/revive/rule/filename_format.go b/vendor/github.com/mgechev/revive/rule/filename_format.go deleted file mode 100644 index 200ffbde08..0000000000 --- a/vendor/github.com/mgechev/revive/rule/filename_format.go +++ /dev/null @@ -1,81 +0,0 @@ -package rule - -import ( - "fmt" - "path/filepath" - "regexp" - "unicode" - - "github.com/mgechev/revive/lint" -) - -// FilenameFormatRule lints source filenames according to a set of regular expressions given as arguments. -type FilenameFormatRule struct { - format *regexp.Regexp -} - -// Apply applies the rule to the given file. -func (r *FilenameFormatRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - filename := filepath.Base(file.Name) - if r.format.MatchString(filename) { - return nil - } - - failureMsg := fmt.Sprintf("Filename %s is not of the format %s.%s", filename, r.format.String(), r.getMsgForNonASCIIChars(filename)) - return []lint.Failure{{ - Confidence: 1, - Failure: failureMsg, - RuleName: r.Name(), - Node: file.AST.Name, - }} -} - -func (*FilenameFormatRule) getMsgForNonASCIIChars(str string) string { - result := "" - for _, c := range str { - if c <= unicode.MaxASCII { - continue - } - - result += fmt.Sprintf(" Non ASCII character %c (%U) found.", c, c) - } - - return result -} - -// Name returns the rule name. -func (*FilenameFormatRule) Name() string { - return "filename-format" -} - -var defaultFormat = regexp.MustCompile(`^[_A-Za-z0-9][_A-Za-z0-9-]*\.go$`) - -// Configure validates the rule configuration, and configures the rule accordingly. -// -// Configuration implements the [lint.ConfigurableRule] interface. -func (r *FilenameFormatRule) Configure(arguments lint.Arguments) error { - argsCount := len(arguments) - if argsCount == 0 { - r.format = defaultFormat - return nil - } - - if argsCount > 1 { - return fmt.Errorf("rule %q expects only one argument, got %d %v", r.Name(), argsCount, arguments) - } - - arg := arguments[0] - str, ok := arg.(string) - if !ok { - return fmt.Errorf("rule %q expects a string argument, got %v of type %T", r.Name(), arg, arg) - } - - format, err := regexp.Compile(str) - if err != nil { - return fmt.Errorf("rule %q expects a valid regexp argument, got error for %s: %w", r.Name(), str, err) - } - - r.format = format - - return nil -} diff --git a/vendor/github.com/mgechev/revive/rule/flag_param.go b/vendor/github.com/mgechev/revive/rule/flag_param.go deleted file mode 100644 index 54edcadc62..0000000000 --- a/vendor/github.com/mgechev/revive/rule/flag_param.go +++ /dev/null @@ -1,94 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - - "github.com/mgechev/revive/internal/astutils" - "github.com/mgechev/revive/lint" -) - -// FlagParamRule warns on boolean parameters that create a control coupling. -type FlagParamRule struct{} - -// Apply applies the rule to given file. -func (*FlagParamRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - onFailure := func(failure lint.Failure) { - failures = append(failures, failure) - } - - for _, decl := range file.AST.Decls { - fd, ok := decl.(*ast.FuncDecl) - isFuncWithNonEmptyBody := ok && fd.Body != nil - if !isFuncWithNonEmptyBody { - continue - } - - boolParams := map[string]struct{}{} - for _, param := range fd.Type.Params.List { - if !astutils.IsIdent(param.Type, "bool") { - continue - } - - for _, paramIdent := range param.Names { - boolParams[paramIdent.Name] = struct{}{} - } - } - - if len(boolParams) == 0 { - continue - } - - cv := conditionVisitor{boolParams, fd, onFailure} - ast.Walk(cv, fd.Body) - } - - return failures -} - -// Name returns the rule name. -func (*FlagParamRule) Name() string { - return "flag-parameter" -} - -type conditionVisitor struct { - idents map[string]struct{} - fd *ast.FuncDecl - onFailure func(lint.Failure) -} - -func (w conditionVisitor) Visit(node ast.Node) ast.Visitor { - ifStmt, ok := node.(*ast.IfStmt) - if !ok { - return w - } - - findUsesOfIdents := func(n ast.Node) bool { - ident, ok := n.(*ast.Ident) - if !ok { - return false - } - - _, ok = w.idents[ident.Name] - if !ok { - return false - } - - return w.idents[ident.Name] == struct{}{} - } - - uses := astutils.SeekNode[*ast.Ident](ifStmt.Cond, findUsesOfIdents) - if uses == nil { - return w - } - - w.onFailure(lint.Failure{ - Confidence: 1, - Node: w.fd.Type.Params, - Category: lint.FailureCategoryBadPractice, - Failure: fmt.Sprintf("parameter '%s' seems to be a control flag, avoid control coupling", uses.Name), - }) - - return nil -} diff --git a/vendor/github.com/mgechev/revive/rule/function_length.go b/vendor/github.com/mgechev/revive/rule/function_length.go deleted file mode 100644 index 53cb6827c9..0000000000 --- a/vendor/github.com/mgechev/revive/rule/function_length.go +++ /dev/null @@ -1,158 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - "reflect" - - "github.com/mgechev/revive/lint" -) - -// FunctionLength lint. -type FunctionLength struct { - maxStmt int - maxLines int -} - -// Configure validates the rule configuration, and configures the rule accordingly. -// -// Configuration implements the [lint.ConfigurableRule] interface. -func (r *FunctionLength) Configure(arguments lint.Arguments) error { - maxStmt, maxLines, err := r.parseArguments(arguments) - if err != nil { - return err - } - r.maxStmt = int(maxStmt) - r.maxLines = int(maxLines) - return nil -} - -// Apply applies the rule to given file. -func (r *FunctionLength) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - for _, decl := range file.AST.Decls { - funcDecl, ok := decl.(*ast.FuncDecl) - if !ok { - continue - } - - body := funcDecl.Body - emptyBody := body == nil || len(body.List) == 0 - if emptyBody { - return nil - } - - if r.maxStmt > 0 { - stmtCount := r.countStmts(body.List) - if stmtCount > r.maxStmt { - failures = append(failures, lint.Failure{ - Confidence: 1, - Failure: fmt.Sprintf("maximum number of statements per function exceeded; max %d but got %d", r.maxStmt, stmtCount), - Node: funcDecl, - }) - } - } - - if r.maxLines > 0 { - lineCount := r.countLines(body, file) - if lineCount > r.maxLines { - failures = append(failures, lint.Failure{ - Confidence: 1, - Failure: fmt.Sprintf("maximum number of lines per function exceeded; max %d but got %d", r.maxLines, lineCount), - Node: funcDecl, - }) - } - } - } - - return failures -} - -// Name returns the rule name. -func (*FunctionLength) Name() string { - return "function-length" -} - -const ( - defaultFuncStmtsLimit = 50 - defaultFuncLinesLimit = 75 -) - -func (*FunctionLength) parseArguments(arguments lint.Arguments) (maxStmt, maxLines int64, err error) { - if len(arguments) == 0 { - return defaultFuncStmtsLimit, defaultFuncLinesLimit, nil - } - - const minArguments = 2 - if len(arguments) != minArguments { - return 0, 0, fmt.Errorf(`invalid configuration for "function-length" rule, expected %d arguments but got %d`, minArguments, len(arguments)) - } - - maxStmt, maxStmtOk := arguments[0].(int64) - if !maxStmtOk { - return 0, 0, fmt.Errorf(`invalid configuration value for max statements in "function-length" rule; need int64 but got %T`, arguments[0]) - } - if maxStmt < 0 { - return 0, 0, fmt.Errorf(`the configuration value for max statements in "function-length" rule cannot be negative, got %d`, maxStmt) - } - - maxLines, maxLinesOk := arguments[1].(int64) - if !maxLinesOk { - return 0, 0, fmt.Errorf(`invalid configuration value for max lines in "function-length" rule; need int64 but got %T`, arguments[1]) - } - if maxLines < 0 { - return 0, 0, fmt.Errorf(`the configuration value for max statements in "function-length" rule cannot be negative, got %d`, maxLines) - } - - return maxStmt, maxLines, nil -} - -func (*FunctionLength) countLines(b *ast.BlockStmt, file *lint.File) int { - return file.ToPosition(b.End()).Line - file.ToPosition(b.Pos()).Line - 1 -} - -func (r *FunctionLength) countStmts(b []ast.Stmt) int { - count := 0 - for _, s := range b { - switch stmt := s.(type) { - case *ast.BlockStmt: - count += r.countStmts(stmt.List) - case *ast.IfStmt: - count += 1 + r.countBodyListStmts(stmt) - if stmt.Else != nil { - elseBody, ok := stmt.Else.(*ast.BlockStmt) - if ok { - count += r.countStmts(elseBody.List) - } - } - case *ast.ForStmt, *ast.RangeStmt, - *ast.SwitchStmt, *ast.TypeSwitchStmt, *ast.SelectStmt: - count += 1 + r.countBodyListStmts(stmt) - case *ast.CaseClause: - count += r.countStmts(stmt.Body) - case *ast.AssignStmt: - count += 1 + r.countFuncLitStmts(stmt.Rhs[0]) - case *ast.GoStmt: - count += 1 + r.countFuncLitStmts(stmt.Call.Fun) - case *ast.DeferStmt: - count += 1 + r.countFuncLitStmts(stmt.Call.Fun) - default: - count++ - } - } - - return count -} - -func (r *FunctionLength) countFuncLitStmts(stmt ast.Expr) int { - if block, ok := stmt.(*ast.FuncLit); ok { - return r.countStmts(block.Body.List) - } - - return 0 -} - -func (r *FunctionLength) countBodyListStmts(t any) int { - i := reflect.ValueOf(t).Elem().FieldByName(`Body`).Elem().FieldByName(`List`).Interface() - return r.countStmts(i.([]ast.Stmt)) -} diff --git a/vendor/github.com/mgechev/revive/rule/function_result_limit.go b/vendor/github.com/mgechev/revive/rule/function_result_limit.go deleted file mode 100644 index b5508f3683..0000000000 --- a/vendor/github.com/mgechev/revive/rule/function_result_limit.go +++ /dev/null @@ -1,71 +0,0 @@ -package rule - -import ( - "errors" - "fmt" - "go/ast" - - "github.com/mgechev/revive/lint" -) - -// FunctionResultsLimitRule limits the maximum number of results a function can return. -type FunctionResultsLimitRule struct { - max int -} - -// Apply applies the rule to given file. -func (r *FunctionResultsLimitRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - for _, decl := range file.AST.Decls { - funcDecl, ok := decl.(*ast.FuncDecl) - if !ok { - continue - } - - num := 0 - hasResults := funcDecl.Type.Results != nil - if hasResults { - num = funcDecl.Type.Results.NumFields() - } - - if num <= r.max { - continue - } - - failures = append(failures, lint.Failure{ - Confidence: 1, - Failure: fmt.Sprintf("maximum number of return results per function exceeded; max %d but got %d", r.max, num), - Node: funcDecl.Type, - }) - } - - return failures -} - -// Name returns the rule name. -func (*FunctionResultsLimitRule) Name() string { - return "function-result-limit" -} - -const defaultResultsLimit = 3 - -// Configure validates the rule configuration, and configures the rule accordingly. -// -// Configuration implements the [lint.ConfigurableRule] interface. -func (r *FunctionResultsLimitRule) Configure(arguments lint.Arguments) error { - if len(arguments) < 1 { - r.max = defaultResultsLimit - return nil - } - - maxResults, ok := arguments[0].(int64) // Alt. non panicking version - if !ok { - return fmt.Errorf(`invalid value passed as return results number to the "function-result-limit" rule; need int64 but got %T`, arguments[0]) - } - if maxResults < 0 { - return errors.New(`the value passed as return results number to the "function-result-limit" rule cannot be negative`) - } - - r.max = int(maxResults) - return nil -} diff --git a/vendor/github.com/mgechev/revive/rule/get_return.go b/vendor/github.com/mgechev/revive/rule/get_return.go deleted file mode 100644 index a6230e082d..0000000000 --- a/vendor/github.com/mgechev/revive/rule/get_return.go +++ /dev/null @@ -1,88 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - "strings" - - "github.com/mgechev/revive/internal/astutils" - "github.com/mgechev/revive/lint" -) - -// GetReturnRule warns on getters that do not yield any result. -type GetReturnRule struct{} - -// Apply applies the rule to given file. -func (*GetReturnRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - for _, decl := range file.AST.Decls { - fd, ok := decl.(*ast.FuncDecl) - if !ok { - continue - } - - if !isGetter(fd.Name.Name) { - continue - } - - if hasResults(fd.Type.Results) { - continue - } - - if isHTTPHandler(fd.Type.Params) { - continue // the Get prefix in the function name refers to HTTP GET - } - - failures = append(failures, lint.Failure{ - Confidence: 0.8, - Node: fd, - Category: lint.FailureCategoryLogic, - Failure: fmt.Sprintf("function '%s' seems to be a getter but it does not return any result", fd.Name.Name), - }) - } - - return failures -} - -// Name returns the rule name. -func (*GetReturnRule) Name() string { - return "get-return" -} - -const getterPrefix = "GET" - -var lenGetterPrefix = len(getterPrefix) - -func isGetter(name string) bool { - nameHasGetterPrefix := strings.HasPrefix(strings.ToUpper(name), getterPrefix) - if !nameHasGetterPrefix { - return false - } - - isJustGet := len(name) == lenGetterPrefix - if isJustGet { - return false - } - - c := name[lenGetterPrefix] - lowerCaseAfterGetterPrefix := c >= 'a' && c <= 'z' - - return !lowerCaseAfterGetterPrefix -} - -func hasResults(rs *ast.FieldList) bool { - return rs != nil && len(rs.List) > 0 -} - -// isHTTPHandler returns true if the given params match with the signature of an HTTP handler, false otherwise -// A params list is considered to be an HTTP handler if the first two parameters are -// http.ResponseWriter, *http.Request in that order. -func isHTTPHandler(params *ast.FieldList) bool { - typeNames := astutils.GetTypeNames(params) - if len(typeNames) < 2 { - return false - } - - return typeNames[0] == "http.ResponseWriter" && typeNames[1] == "*http.Request" -} diff --git a/vendor/github.com/mgechev/revive/rule/identical_branches.go b/vendor/github.com/mgechev/revive/rule/identical_branches.go deleted file mode 100644 index 22895cde65..0000000000 --- a/vendor/github.com/mgechev/revive/rule/identical_branches.go +++ /dev/null @@ -1,81 +0,0 @@ -package rule - -import ( - "go/ast" - - "github.com/mgechev/revive/internal/astutils" - "github.com/mgechev/revive/lint" -) - -// IdenticalBranchesRule warns on if...else statements with both branches being the same. -type IdenticalBranchesRule struct{} - -// Apply applies the rule to given file. -func (*IdenticalBranchesRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - onFailure := func(failure lint.Failure) { - failures = append(failures, failure) - } - - w := &lintIdenticalBranches{onFailure: onFailure} - for _, decl := range file.AST.Decls { - fn, ok := decl.(*ast.FuncDecl) - if !ok || fn.Body == nil { - continue - } - - ast.Walk(w, fn.Body) - } - - return failures -} - -// Name returns the rule name. -func (*IdenticalBranchesRule) Name() string { - return "identical-branches" -} - -type lintIdenticalBranches struct { - onFailure func(lint.Failure) -} - -func (w *lintIdenticalBranches) Visit(node ast.Node) ast.Visitor { - ifStmt, ok := node.(*ast.IfStmt) - if !ok { - return w - } - - if ifStmt.Else == nil { - return w // if without else - } - - elseBranch, ok := ifStmt.Else.(*ast.BlockStmt) - if !ok { // if-else-if construction, the rule only copes with single if...else statements - return w - } - - if w.identicalBranches(ifStmt.Body, elseBranch) { - w.onFailure(lint.Failure{ - Confidence: 1.0, - Node: ifStmt, - Category: lint.FailureCategoryLogic, - Failure: "both branches of the if are identical", - }) - } - - ast.Walk(w, ifStmt.Body) - ast.Walk(w, ifStmt.Else) - return nil -} - -func (*lintIdenticalBranches) identicalBranches(body, elseBranch *ast.BlockStmt) bool { - if len(body.List) != len(elseBranch.List) { - return false // branches don't have the same number of statements - } - - bodyStr := astutils.GoFmt(body) - elseStr := astutils.GoFmt(elseBranch) - - return bodyStr == elseStr -} diff --git a/vendor/github.com/mgechev/revive/rule/identical_ifelseif_branches.go b/vendor/github.com/mgechev/revive/rule/identical_ifelseif_branches.go deleted file mode 100644 index b661e44f83..0000000000 --- a/vendor/github.com/mgechev/revive/rule/identical_ifelseif_branches.go +++ /dev/null @@ -1,186 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - - "github.com/mgechev/revive/internal/astutils" - "github.com/mgechev/revive/lint" -) - -// IdenticalIfElseIfBranchesRule warns on if...else if chains with identical branches. -type IdenticalIfElseIfBranchesRule struct{} - -// Apply applies the rule to given file. -func (*IdenticalIfElseIfBranchesRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - onFailure := func(failure lint.Failure) { - failures = append(failures, failure) - } - - getStmtLine := func(s ast.Stmt) int { - return file.ToPosition(s.Pos()).Line - } - - w := &rootWalkerIfElseIfIdenticalBranches{getStmtLine: getStmtLine, onFailure: onFailure} - for _, decl := range file.AST.Decls { - fn, ok := decl.(*ast.FuncDecl) - if !ok || fn.Body == nil { - continue - } - - ast.Walk(w, fn.Body) - } - - return failures -} - -// Name returns the rule name. -func (*IdenticalIfElseIfBranchesRule) Name() string { - return "identical-ifelseif-branches" -} - -type rootWalkerIfElseIfIdenticalBranches struct { - getStmtLine func(ast.Stmt) int - onFailure func(lint.Failure) -} - -func (w *rootWalkerIfElseIfIdenticalBranches) Visit(node ast.Node) ast.Visitor { - n, ok := node.(*ast.IfStmt) - if !ok { - return w - } - - _, isIfElseIf := n.Else.(*ast.IfStmt) - if isIfElseIf { - walker := &lintIfChainIdenticalBranches{ - onFailure: w.onFailure, - getStmtLine: w.getStmtLine, - rootWalker: w, - } - - ast.Walk(walker, n) - return nil // the walker already analyzed inner branches - } - - return w -} - -// walkBranch analyzes the given branch. -func (w *rootWalkerIfElseIfIdenticalBranches) walkBranch(branch ast.Stmt) { - if branch == nil { - return - } - - walker := &rootWalkerIfElseIfIdenticalBranches{ - onFailure: w.onFailure, - getStmtLine: w.getStmtLine, - } - - ast.Walk(walker, branch) -} - -type lintIfChainIdenticalBranches struct { - getStmtLine func(ast.Stmt) int - onFailure func(lint.Failure) - branches []ast.Stmt // hold branches to compare - rootWalker *rootWalkerIfElseIfIdenticalBranches // the walker to use to recursively analyze inner branches - hasComplexCondition bool // indicates if one of the if conditions is "complex" -} - -// addBranch adds a branch to the list of branches to be compared. -func (w *lintIfChainIdenticalBranches) addBranch(branch ast.Stmt) { - if branch == nil { - return - } - - if w.branches == nil { - w.resetBranches() - } - - w.branches = append(w.branches, branch) -} - -// resetBranches resets (clears) the list of branches to compare. -func (w *lintIfChainIdenticalBranches) resetBranches() { - w.branches = []ast.Stmt{} - w.hasComplexCondition = false -} - -func (w *lintIfChainIdenticalBranches) Visit(node ast.Node) ast.Visitor { - n, ok := node.(*ast.IfStmt) - if !ok { - return w - } - - // recursively analyze the then-branch - w.rootWalker.walkBranch(n.Body) - - if n.Init == nil { // only check if without initialization to avoid false positives - w.addBranch(n.Body) - } - - if w.isComplexCondition(n.Cond) { - w.hasComplexCondition = true - } - - if n.Else != nil { - if chainedIf, ok := n.Else.(*ast.IfStmt); ok { - w.Visit(chainedIf) - } else { - w.addBranch(n.Else) - w.rootWalker.walkBranch(n.Else) - } - } - - identicalBranches := w.identicalBranches(w.branches) - for _, branchPair := range identicalBranches { - msg := fmt.Sprintf(`"if...else if" chain with identical branches (lines %d and %d)`, branchPair[0], branchPair[1]) - confidence := 1.0 - if w.hasComplexCondition { - confidence = 0.8 - } - w.onFailure(lint.Failure{ - Confidence: confidence, - Node: w.branches[0], - Category: lint.FailureCategoryLogic, - Failure: msg, - }) - } - - w.resetBranches() - return nil -} - -// isComplexCondition returns true if the given expression is "complex", false otherwise. -// An expression is considered complex if it has a function call. -func (*lintIfChainIdenticalBranches) isComplexCondition(expr ast.Expr) bool { - call := astutils.SeekNode[*ast.CallExpr](expr, func(n ast.Node) bool { - _, ok := n.(*ast.CallExpr) - return ok - }) - - return call != nil -} - -// identicalBranches yields pairs of (line numbers) of identical branches from the given branches. -func (w *lintIfChainIdenticalBranches) identicalBranches(branches []ast.Stmt) [][]int { - result := [][]int{} - if len(branches) < 2 { - return result // no other branch to compare thus we return - } - - hashes := map[string]int{} // branch code hash -> branch line - for _, branch := range branches { - hash := astutils.NodeHash(branch) - branchLine := w.getStmtLine(branch) - if match, ok := hashes[hash]; ok { - result = append(result, []int{match, branchLine}) - } - - hashes[hash] = branchLine - } - - return result -} diff --git a/vendor/github.com/mgechev/revive/rule/identical_ifelseif_condition.go b/vendor/github.com/mgechev/revive/rule/identical_ifelseif_condition.go deleted file mode 100644 index 0ba9d68c93..0000000000 --- a/vendor/github.com/mgechev/revive/rule/identical_ifelseif_condition.go +++ /dev/null @@ -1,148 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - - "github.com/mgechev/revive/internal/astutils" - "github.com/mgechev/revive/lint" -) - -// IdenticalIfElseIfConditionsRule warns on if...else if chains with identical conditions. -type IdenticalIfElseIfConditionsRule struct{} - -// Apply applies the rule to given file. -func (*IdenticalIfElseIfConditionsRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - onFailure := func(failure lint.Failure) { - failures = append(failures, failure) - } - - getStmtLine := func(s ast.Stmt) int { - return file.ToPosition(s.Pos()).Line - } - - w := &rootWalkerIfElseIfIdenticalConditions{getStmtLine: getStmtLine, onFailure: onFailure} - for _, decl := range file.AST.Decls { - fn, ok := decl.(*ast.FuncDecl) - if !ok || fn.Body == nil { - continue - } - - ast.Walk(w, fn.Body) - } - - return failures -} - -// Name returns the rule name. -func (*IdenticalIfElseIfConditionsRule) Name() string { - return "identical-ifelseif-conditions" -} - -type rootWalkerIfElseIfIdenticalConditions struct { - getStmtLine func(ast.Stmt) int - onFailure func(lint.Failure) -} - -func (w *rootWalkerIfElseIfIdenticalConditions) Visit(node ast.Node) ast.Visitor { - n, ok := node.(*ast.IfStmt) - if !ok { - return w - } - - _, isIfElseIf := n.Else.(*ast.IfStmt) - if isIfElseIf { - walker := &lintIfChainIdenticalConditions{ - onFailure: w.onFailure, - getStmtLine: w.getStmtLine, - rootWalker: w, - } - - ast.Walk(walker, n) - return nil // the walker already analyzed inner branches - } - - return w -} - -// walkBranch analyzes the given branch. -func (w *rootWalkerIfElseIfIdenticalConditions) walkBranch(branch ast.Stmt) { - if branch == nil { - return - } - - walker := &rootWalkerIfElseIfIdenticalConditions{ - onFailure: w.onFailure, - getStmtLine: w.getStmtLine, - } - - ast.Walk(walker, branch) -} - -type lintIfChainIdenticalConditions struct { - getStmtLine func(ast.Stmt) int - onFailure func(lint.Failure) - conditions map[string]int // condition hash -> line of the condition - rootWalker *rootWalkerIfElseIfIdenticalConditions // the walker to use to recursively analyze inner branches -} - -// addCondition adds a condition to the set of if...else if conditions. -// If the set already contains the same condition it returns the line number of the identical condition. -func (w *lintIfChainIdenticalConditions) addCondition(condition ast.Expr, conditionLine int) (line int, match bool) { - if condition == nil { - return 0, false - } - - if w.conditions == nil { - w.resetConditions() - } - - hash := astutils.NodeHash(condition) - identical, ok := w.conditions[hash] - if ok { - return identical, true - } - - w.conditions[hash] = conditionLine - return 0, false -} - -func (w *lintIfChainIdenticalConditions) resetConditions() { - w.conditions = map[string]int{} -} - -func (w *lintIfChainIdenticalConditions) Visit(node ast.Node) ast.Visitor { - n, ok := node.(*ast.IfStmt) - if !ok { - return w - } - - // recursively analyze the then-branch - w.rootWalker.walkBranch(n.Body) - - if n.Init == nil { // only check if without initialization to avoid false positives - currentCondLine := w.rootWalker.getStmtLine(n) - identicalCondLine, match := w.addCondition(n.Cond, currentCondLine) - if match { - w.onFailure(lint.Failure{ - Confidence: 1.0, - Node: n, - Category: lint.FailureCategoryLogic, - Failure: fmt.Sprintf(`"if...else if" chain with identical conditions (lines %d and %d)`, identicalCondLine, currentCondLine), - }) - } - } - - if n.Else != nil { - if chainedIf, ok := n.Else.(*ast.IfStmt); ok { - w.Visit(chainedIf) - } else { - w.rootWalker.walkBranch(n.Else) - } - } - - w.resetConditions() - return nil -} diff --git a/vendor/github.com/mgechev/revive/rule/identical_switch_branches.go b/vendor/github.com/mgechev/revive/rule/identical_switch_branches.go deleted file mode 100644 index fc1d620b36..0000000000 --- a/vendor/github.com/mgechev/revive/rule/identical_switch_branches.go +++ /dev/null @@ -1,94 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - "go/token" - - "github.com/mgechev/revive/internal/astutils" - "github.com/mgechev/revive/lint" -) - -// IdenticalSwitchBranchesRule warns on identical switch branches. -type IdenticalSwitchBranchesRule struct{} - -// Apply applies the rule to given file. -func (*IdenticalSwitchBranchesRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - onFailure := func(failure lint.Failure) { - failures = append(failures, failure) - } - - getStmtLine := func(s ast.Stmt) int { - return file.ToPosition(s.Pos()).Line - } - - w := &lintIdenticalSwitchBranches{getStmtLine: getStmtLine, onFailure: onFailure} - for _, decl := range file.AST.Decls { - fn, ok := decl.(*ast.FuncDecl) - if !ok || fn.Body == nil { - continue - } - - ast.Walk(w, fn.Body) - } - - return failures -} - -// Name returns the rule name. -func (*IdenticalSwitchBranchesRule) Name() string { - return "identical-switch-branches" -} - -type lintIdenticalSwitchBranches struct { - getStmtLine func(ast.Stmt) int - onFailure func(lint.Failure) -} - -func (w *lintIdenticalSwitchBranches) Visit(node ast.Node) ast.Visitor { - switchStmt, ok := node.(*ast.SwitchStmt) - if !ok { - return w - } - - if switchStmt.Tag == nil { - return w // do not lint untagged switches (order of case evaluation might be important) - } - - doesFallthrough := func(stmts []ast.Stmt) bool { - if len(stmts) == 0 { - return false - } - - ft, ok := stmts[len(stmts)-1].(*ast.BranchStmt) - return ok && ft.Tok == token.FALLTHROUGH - } - - hashes := map[string]int{} // map hash(branch code) -> branch line - for _, cc := range switchStmt.Body.List { - caseClause := cc.(*ast.CaseClause) - if doesFallthrough(caseClause.Body) { - continue // skip fallthrough branches - } - branch := &ast.BlockStmt{ - List: caseClause.Body, - } - hash := astutils.NodeHash(branch) - branchLine := w.getStmtLine(caseClause) - if matchLine, ok := hashes[hash]; ok { - w.onFailure(lint.Failure{ - Confidence: 1.0, - Node: node, - Category: lint.FailureCategoryLogic, - Failure: fmt.Sprintf(`"switch" with identical branches (lines %d and %d)`, matchLine, branchLine), - }) - } - - hashes[hash] = branchLine - ast.Walk(w, branch) - } - - return nil // switch branches already analyzed -} diff --git a/vendor/github.com/mgechev/revive/rule/identical_switch_conditions.go b/vendor/github.com/mgechev/revive/rule/identical_switch_conditions.go deleted file mode 100644 index 15826d9b07..0000000000 --- a/vendor/github.com/mgechev/revive/rule/identical_switch_conditions.go +++ /dev/null @@ -1,78 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - "go/token" - - "github.com/mgechev/revive/internal/astutils" - "github.com/mgechev/revive/lint" -) - -// IdenticalSwitchConditionsRule warns on switch case clauses with identical conditions. -type IdenticalSwitchConditionsRule struct{} - -// Apply applies the rule to given file. -func (*IdenticalSwitchConditionsRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - onFailure := func(failure lint.Failure) { - failures = append(failures, failure) - } - - w := &lintIdenticalSwitchConditions{toPosition: file.ToPosition, onFailure: onFailure} - for _, decl := range file.AST.Decls { - fn, ok := decl.(*ast.FuncDecl) - if !ok || fn.Body == nil { - continue - } - - ast.Walk(w, fn.Body) - } - - return failures -} - -// Name returns the rule name. -func (*IdenticalSwitchConditionsRule) Name() string { - return "identical-switch-conditions" -} - -type lintIdenticalSwitchConditions struct { - toPosition func(token.Pos) token.Position - onFailure func(lint.Failure) -} - -func (w *lintIdenticalSwitchConditions) Visit(node ast.Node) ast.Visitor { - switchStmt, ok := node.(*ast.SwitchStmt) - if !ok { // not a switch statement, keep walking the AST - return w - } - - if switchStmt.Tag != nil { - return w // Not interested in tagged switches - } - - hashes := map[string]int{} // map hash(condition code) -> condition line - for _, cc := range switchStmt.Body.List { - caseClause := cc.(*ast.CaseClause) - caseClauseLine := w.toPosition(caseClause.Pos()).Line - for _, expr := range caseClause.List { - hash := astutils.NodeHash(expr) - if matchLine, ok := hashes[hash]; ok { - w.onFailure(lint.Failure{ - Confidence: 1.0, - Node: caseClause, - Category: lint.FailureCategoryLogic, - Failure: fmt.Sprintf(`case clause at line %d has the same condition`, matchLine), - }) - } - - hashes[hash] = caseClauseLine - } - - ast.Walk(w, caseClause) - } - - return nil // switch branches already analyzed -} diff --git a/vendor/github.com/mgechev/revive/rule/if_return.go b/vendor/github.com/mgechev/revive/rule/if_return.go deleted file mode 100644 index 15c7ca18ab..0000000000 --- a/vendor/github.com/mgechev/revive/rule/if_return.go +++ /dev/null @@ -1,115 +0,0 @@ -package rule - -import ( - "go/ast" - "go/token" - "strings" - - "github.com/mgechev/revive/lint" -) - -// IfReturnRule searches for redundant `if` when returning an error. -type IfReturnRule struct{} - -// Apply applies the rule to given file. -func (*IfReturnRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - onFailure := func(failure lint.Failure) { - failures = append(failures, failure) - } - - astFile := file.AST - w := &lintElseError{astFile, onFailure} - ast.Walk(w, astFile) - return failures -} - -// Name returns the rule name. -func (*IfReturnRule) Name() string { - return "if-return" -} - -type lintElseError struct { - file *ast.File - onFailure func(lint.Failure) -} - -func (w *lintElseError) Visit(node ast.Node) ast.Visitor { - if v, ok := node.(*ast.BlockStmt); ok { - for i := range len(v.List) - 1 { - // if var := whatever; var != nil { return var } - s, ok := v.List[i].(*ast.IfStmt) - if !ok || s.Body == nil || len(s.Body.List) != 1 || s.Else != nil { - continue - } - assign, ok := s.Init.(*ast.AssignStmt) - //nolint:staticcheck // QF1001: it's readable enough - if !ok || len(assign.Lhs) != 1 || !(assign.Tok == token.DEFINE || assign.Tok == token.ASSIGN) { - continue - } - id, ok := assign.Lhs[0].(*ast.Ident) - if !ok { - continue - } - expr, ok := s.Cond.(*ast.BinaryExpr) - if !ok || expr.Op != token.NEQ { - continue - } - if lhs, ok := expr.X.(*ast.Ident); !ok || lhs.Name != id.Name { - continue - } - if rhs, ok := expr.Y.(*ast.Ident); !ok || rhs.Name != "nil" { - continue - } - r, ok := s.Body.List[0].(*ast.ReturnStmt) - if !ok || len(r.Results) != 1 { - continue - } - if r, ok := r.Results[0].(*ast.Ident); !ok || r.Name != id.Name { - continue - } - - // return nil - r, ok = v.List[i+1].(*ast.ReturnStmt) - if !ok || len(r.Results) != 1 { - continue - } - if r, ok := r.Results[0].(*ast.Ident); !ok || r.Name != "nil" { - continue - } - - // check if there are any comments explaining the construct, don't emit an error if there are some. - if containsComments(s.Pos(), r.Pos(), w.file) { - continue - } - - w.onFailure(lint.Failure{ - Confidence: .9, - Node: v.List[i], - Failure: "redundant if ...; err != nil check, just return error instead.", - }) - } - } - return w -} - -func containsComments(start, end token.Pos, f *ast.File) bool { - for _, cgroup := range f.Comments { - comments := cgroup.List - if comments[0].Slash >= end { - // All comments starting with this group are after end pos. - return false - } - if comments[len(comments)-1].Slash < start { - // Comments group ends before start pos. - continue - } - for _, c := range comments { - if start <= c.Slash && c.Slash < end && !strings.HasPrefix(c.Text, "// MATCH ") { - return true - } - } - } - return false -} diff --git a/vendor/github.com/mgechev/revive/rule/import_alias_naming.go b/vendor/github.com/mgechev/revive/rule/import_alias_naming.go deleted file mode 100644 index a46c331efa..0000000000 --- a/vendor/github.com/mgechev/revive/rule/import_alias_naming.go +++ /dev/null @@ -1,132 +0,0 @@ -package rule - -import ( - "fmt" - "regexp" - - "github.com/mgechev/revive/lint" -) - -// ImportAliasNamingRule lints import alias naming. -type ImportAliasNamingRule struct { - allowRegexp *regexp.Regexp - denyRegexp *regexp.Regexp -} - -const defaultImportAliasNamingAllowRule = "^[a-z][a-z0-9]{0,}$" - -//nolint:gocritic // regexpSimplify: backward compatibility -var defaultImportAliasNamingAllowRegexp = regexp.MustCompile(defaultImportAliasNamingAllowRule) - -// Configure validates the rule configuration, and configures the rule accordingly. -// -// Configuration implements the [lint.ConfigurableRule] interface. -func (r *ImportAliasNamingRule) Configure(arguments lint.Arguments) error { - if len(arguments) == 0 { - r.allowRegexp = defaultImportAliasNamingAllowRegexp - return nil - } - - switch namingRule := arguments[0].(type) { - case string: - err := r.setAllowRule(namingRule) - if err != nil { - return err - } - case map[string]any: // expecting map[string]string - for k, v := range namingRule { - switch { - case isRuleOption(k, "allowRegex"): - err := r.setAllowRule(v) - if err != nil { - return err - } - case isRuleOption(k, "denyRegex"): - err := r.setDenyRule(v) - if err != nil { - return err - } - - default: - return fmt.Errorf("invalid map key for 'import-alias-naming' rule. Expecting 'allowRegex' or 'denyRegex', got %v", k) - } - } - default: - return fmt.Errorf("invalid argument '%v' for 'import-alias-naming' rule. Expecting string or map[string]string, got %T", arguments[0], arguments[0]) - } - - if r.allowRegexp == nil && r.denyRegexp == nil { - r.allowRegexp = defaultImportAliasNamingAllowRegexp - } - return nil -} - -// Apply applies the rule to given file. -func (r *ImportAliasNamingRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - for _, is := range file.AST.Imports { - path := is.Path - if path == nil { - continue - } - - alias := is.Name - if alias == nil || alias.Name == "_" || alias.Name == "." { // "_" and "." are special types of import aliases and should be processed by another linter rule - continue - } - - if r.allowRegexp != nil && !r.allowRegexp.MatchString(alias.Name) { - failures = append(failures, lint.Failure{ - Confidence: 1, - Failure: fmt.Sprintf("import name (%s) must match the regular expression: %s", alias.Name, r.allowRegexp.String()), - Node: alias, - Category: lint.FailureCategoryImports, - }) - } - - if r.denyRegexp != nil && r.denyRegexp.MatchString(alias.Name) { - failures = append(failures, lint.Failure{ - Confidence: 1, - Failure: fmt.Sprintf("import name (%s) must NOT match the regular expression: %s", alias.Name, r.denyRegexp.String()), - Node: alias, - Category: lint.FailureCategoryImports, - }) - } - } - - return failures -} - -// Name returns the rule name. -func (*ImportAliasNamingRule) Name() string { - return "import-alias-naming" -} - -func (r *ImportAliasNamingRule) setAllowRule(value any) error { - namingRule, ok := value.(string) - if !ok { - return fmt.Errorf("invalid argument '%v' for import-alias-naming allowRegexp rule. Expecting string, got %T", value, value) - } - - namingRuleRegexp, err := regexp.Compile(namingRule) - if err != nil { - return fmt.Errorf("invalid argument to the import-alias-naming allowRegexp rule. Expecting %q to be a valid regular expression, got: %w", namingRule, err) - } - r.allowRegexp = namingRuleRegexp - return nil -} - -func (r *ImportAliasNamingRule) setDenyRule(value any) error { - namingRule, ok := value.(string) - if !ok { - return fmt.Errorf("invalid argument '%v' for import-alias-naming denyRegexp rule. Expecting string, got %T", value, value) - } - - namingRuleRegexp, err := regexp.Compile(namingRule) - if err != nil { - return fmt.Errorf("invalid argument to the import-alias-naming denyRegexp rule. Expecting %q to be a valid regular expression, got: %w", namingRule, err) - } - r.denyRegexp = namingRuleRegexp - return nil -} diff --git a/vendor/github.com/mgechev/revive/rule/import_shadowing.go b/vendor/github.com/mgechev/revive/rule/import_shadowing.go deleted file mode 100644 index 09520785c0..0000000000 --- a/vendor/github.com/mgechev/revive/rule/import_shadowing.go +++ /dev/null @@ -1,115 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - "go/token" - "strings" - - "github.com/mgechev/revive/lint" -) - -// ImportShadowingRule spots identifiers that shadow an import. -type ImportShadowingRule struct{} - -// Apply applies the rule to given file. -func (*ImportShadowingRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - importNames := map[string]struct{}{} - for _, imp := range file.AST.Imports { - importNames[getName(imp)] = struct{}{} - } - - fileAst := file.AST - walker := importShadowing{ - packageNameIdent: fileAst.Name, - importNames: importNames, - onFailure: func(failure lint.Failure) { - failures = append(failures, failure) - }, - alreadySeen: map[*ast.Object]struct{}{}, //nolint:staticcheck // TODO: ast.Object is deprecated - skipIdents: map[*ast.Ident]struct{}{}, - } - - ast.Walk(walker, fileAst) - - return failures -} - -// Name returns the rule name. -func (*ImportShadowingRule) Name() string { - return "import-shadowing" -} - -func getName(imp *ast.ImportSpec) string { - const pathSep = "/" - const strDelim = `"` - if imp.Name != nil { - return imp.Name.Name - } - - path := imp.Path.Value - i := strings.LastIndex(path, pathSep) - if i == -1 { - return strings.Trim(path, strDelim) - } - - return strings.Trim(path[i+1:], strDelim) -} - -type importShadowing struct { - packageNameIdent *ast.Ident - importNames map[string]struct{} - onFailure func(lint.Failure) - alreadySeen map[*ast.Object]struct{} //nolint:staticcheck // TODO: ast.Object is deprecated - skipIdents map[*ast.Ident]struct{} -} - -// Visit visits AST nodes and checks if id nodes (ast.Ident) shadow an import name. -func (w importShadowing) Visit(n ast.Node) ast.Visitor { - switch n := n.(type) { - case *ast.AssignStmt: - if n.Tok == token.DEFINE { - return w // analyze variable declarations of the form id := expr - } - - return nil // skip assigns of the form id = expr (not an id declaration) - case *ast.CallExpr, // skip call expressions (not an id declaration) - *ast.ImportSpec, // skip import section subtree because we already have the list of imports - *ast.KeyValueExpr, // skip analysis of key-val expressions ({key:value}): ids of such expressions, even the same of an import name, do not shadow the import name - *ast.ReturnStmt, // skip skipping analysis of returns, ids in expression were already analyzed - *ast.SelectorExpr, // skip analysis of selector expressions (anId.otherId): because if anId shadows an import name, it was already detected, and otherId does not shadows the import name - *ast.StructType: // skip analysis of struct type because struct fields can not shadow an import name - return nil - case *ast.FuncDecl: - if n.Recv != nil { - w.skipIdents[n.Name] = struct{}{} - } - case *ast.Ident: - if n == w.packageNameIdent { - return nil // skip the ident corresponding to the package name of this file - } - - id := n.Name - if id == "_" { - return w // skip _ id - } - - _, isImportName := w.importNames[id] - _, alreadySeen := w.alreadySeen[n.Obj] - _, skipIdent := w.skipIdents[n] - if isImportName && !alreadySeen && !skipIdent { - w.onFailure(lint.Failure{ - Confidence: 1, - Node: n, - Category: lint.FailureCategoryNaming, - Failure: fmt.Sprintf("The name '%s' shadows an import name", id), - }) - - w.alreadySeen[n.Obj] = struct{}{} - } - } - - return w -} diff --git a/vendor/github.com/mgechev/revive/rule/imports_blocklist.go b/vendor/github.com/mgechev/revive/rule/imports_blocklist.go deleted file mode 100644 index 8d3b08693c..0000000000 --- a/vendor/github.com/mgechev/revive/rule/imports_blocklist.go +++ /dev/null @@ -1,67 +0,0 @@ -package rule - -import ( - "fmt" - "regexp" - - "github.com/mgechev/revive/lint" -) - -// ImportsBlocklistRule disallows importing the specified packages. -type ImportsBlocklistRule struct { - blocklist []*regexp.Regexp -} - -var replaceImportRegexp = regexp.MustCompile(`/?\*\*/?`) - -// Configure validates the rule configuration, and configures the rule accordingly. -// -// Configuration implements the [lint.ConfigurableRule] interface. -func (r *ImportsBlocklistRule) Configure(arguments lint.Arguments) error { - r.blocklist = []*regexp.Regexp{} - for _, arg := range arguments { - argStr, ok := arg.(string) - if !ok { - return fmt.Errorf("invalid argument to the imports-blocklist rule. Expecting a string, got %T", arg) - } - regStr, err := regexp.Compile(fmt.Sprintf(`(?m)"%s"$`, replaceImportRegexp.ReplaceAllString(argStr, `(\W|\w)*`))) //nolint:gocritic // regexpSimplify: false positive - if err != nil { - return fmt.Errorf("invalid argument to the imports-blocklist rule. Expecting %q to be a valid regular expression, got: %w", argStr, err) - } - r.blocklist = append(r.blocklist, regStr) - } - return nil -} - -func (r *ImportsBlocklistRule) isBlocklisted(path string) bool { - for _, regex := range r.blocklist { - if regex.MatchString(path) { - return true - } - } - return false -} - -// Apply applies the rule to given file. -func (r *ImportsBlocklistRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - for _, is := range file.AST.Imports { - path := is.Path - if path != nil && r.isBlocklisted(path.Value) { - failures = append(failures, lint.Failure{ - Confidence: 1, - Failure: "should not use the following blocklisted import: " + path.Value, - Node: is, - Category: lint.FailureCategoryImports, - }) - } - } - - return failures -} - -// Name returns the rule name. -func (*ImportsBlocklistRule) Name() string { - return "imports-blocklist" -} diff --git a/vendor/github.com/mgechev/revive/rule/increment_decrement.go b/vendor/github.com/mgechev/revive/rule/increment_decrement.go deleted file mode 100644 index d8cebcf252..0000000000 --- a/vendor/github.com/mgechev/revive/rule/increment_decrement.go +++ /dev/null @@ -1,73 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - "go/token" - - "github.com/mgechev/revive/lint" -) - -// IncrementDecrementRule lints `i += 1` and `i -= 1` constructs. -type IncrementDecrementRule struct{} - -// Apply applies the rule to given file. -func (*IncrementDecrementRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - fileAst := file.AST - walker := lintIncrementDecrement{ - file: file, - onFailure: func(failure lint.Failure) { - failures = append(failures, failure) - }, - } - - ast.Walk(walker, fileAst) - - return failures -} - -// Name returns the rule name. -func (*IncrementDecrementRule) Name() string { - return "increment-decrement" -} - -type lintIncrementDecrement struct { - file *lint.File - onFailure func(lint.Failure) -} - -func (w lintIncrementDecrement) Visit(n ast.Node) ast.Visitor { - as, ok := n.(*ast.AssignStmt) - if !ok { - return w - } - if len(as.Lhs) != 1 { - return w - } - if !isOne(as.Rhs[0]) { - return w - } - var suffix string - switch as.Tok { - case token.ADD_ASSIGN: - suffix = "++" - case token.SUB_ASSIGN: - suffix = "--" - default: - return w - } - w.onFailure(lint.Failure{ - Confidence: 0.8, - Node: as, - Category: lint.FailureCategoryUnaryOp, - Failure: fmt.Sprintf("should replace %s with %s%s", w.file.Render(as), w.file.Render(as.Lhs[0]), suffix), - }) - return w -} - -func isOne(expr ast.Expr) bool { - lit, ok := expr.(*ast.BasicLit) - return ok && lit.Kind == token.INT && lit.Value == "1" -} diff --git a/vendor/github.com/mgechev/revive/rule/indent_error_flow.go b/vendor/github.com/mgechev/revive/rule/indent_error_flow.go deleted file mode 100644 index be4734bad2..0000000000 --- a/vendor/github.com/mgechev/revive/rule/indent_error_flow.go +++ /dev/null @@ -1,70 +0,0 @@ -package rule - -import ( - "github.com/mgechev/revive/internal/ifelse" - "github.com/mgechev/revive/lint" -) - -// IndentErrorFlowRule prevents redundant else statements. -type IndentErrorFlowRule struct { - // preserveScope prevents suggestions that would enlarge variable scope. - preserveScope bool -} - -// Configure validates the rule configuration, and configures the rule accordingly. -// -// Configuration implements the [lint.ConfigurableRule] interface. -func (e *IndentErrorFlowRule) Configure(arguments lint.Arguments) error { - for _, arg := range arguments { - sarg, ok := arg.(string) - if !ok { - continue - } - if isRuleOption(sarg, "preserveScope") { - e.preserveScope = true - } - } - return nil -} - -// Apply applies the rule to given file. -func (e *IndentErrorFlowRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - return ifelse.Apply(e.checkIfElse, file.AST, ifelse.TargetElse, ifelse.Args{ - PreserveScope: e.preserveScope, - // AllowJump is not used by this rule - }) -} - -// Name returns the rule name. -func (*IndentErrorFlowRule) Name() string { - return "indent-error-flow" -} - -func (e *IndentErrorFlowRule) checkIfElse(chain ifelse.Chain) (string, bool) { - if !chain.HasElse { - return "", false - } - - if !chain.If.Deviates() { - // this rule only applies if the if-block deviates control flow - return "", false - } - - if chain.HasPriorNonDeviating { - // if we de-indent the "else" block then a previous branch - // might flow into it, affecting program behavior - return "", false - } - - if !chain.If.Returns() { - // avoid overlapping with superfluous-else - return "", false - } - - if e.preserveScope && !chain.AtBlockEnd && (chain.HasInitializer || chain.Else.HasDecls()) { - // avoid increasing variable scope - return "", false - } - - return "if block ends with a return statement, so drop this else and outdent its block", true -} diff --git a/vendor/github.com/mgechev/revive/rule/line_length_limit.go b/vendor/github.com/mgechev/revive/rule/line_length_limit.go deleted file mode 100644 index 0c4c57691b..0000000000 --- a/vendor/github.com/mgechev/revive/rule/line_length_limit.go +++ /dev/null @@ -1,99 +0,0 @@ -package rule - -import ( - "bufio" - "bytes" - "errors" - "fmt" - "go/token" - "strings" - "unicode/utf8" - - "github.com/mgechev/revive/lint" -) - -// LineLengthLimitRule lints number of characters in a line. -type LineLengthLimitRule struct { - max int -} - -const defaultLineLengthLimit = 80 - -// Configure validates the rule configuration, and configures the rule accordingly. -// -// Configuration implements the [lint.ConfigurableRule] interface. -func (r *LineLengthLimitRule) Configure(arguments lint.Arguments) error { - if len(arguments) < 1 { - r.max = defaultLineLengthLimit - return nil - } - - maxLength, ok := arguments[0].(int64) // Alt. non panicking version - if !ok || maxLength < 0 { - return errors.New(`invalid value passed as argument number to the "line-length-limit" rule`) - } - - r.max = int(maxLength) - return nil -} - -// Apply applies the rule to given file. -func (r *LineLengthLimitRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - checker := lintLineLengthNum{ - max: r.max, - file: file, - onFailure: func(failure lint.Failure) { - failures = append(failures, failure) - }, - } - - checker.check() - - return failures -} - -// Name returns the rule name. -func (*LineLengthLimitRule) Name() string { - return "line-length-limit" -} - -type lintLineLengthNum struct { - max int - file *lint.File - onFailure func(lint.Failure) -} - -func (r lintLineLengthNum) check() { - f := bytes.NewReader(r.file.Content()) - spaces := strings.Repeat(" ", 4) // tab width = 4 - l := 1 - s := bufio.NewScanner(f) - for s.Scan() { - t := s.Text() - t = strings.ReplaceAll(t, "\t", spaces) - c := utf8.RuneCountInString(t) - if c > r.max { - r.onFailure(lint.Failure{ - Category: lint.FailureCategoryCodeStyle, - Position: lint.FailurePosition{ - // Offset not set; it is non-trivial, and doesn't appear to be needed. - Start: token.Position{ - Filename: r.file.Name, - Line: l, - Column: 0, - }, - End: token.Position{ - Filename: r.file.Name, - Line: l, - Column: c, - }, - }, - Confidence: 1, - Failure: fmt.Sprintf("line is %d characters, out of limit %d", c, r.max), - }) - } - l++ - } -} diff --git a/vendor/github.com/mgechev/revive/rule/max_control_nesting.go b/vendor/github.com/mgechev/revive/rule/max_control_nesting.go deleted file mode 100644 index 5bb11d098b..0000000000 --- a/vendor/github.com/mgechev/revive/rule/max_control_nesting.go +++ /dev/null @@ -1,126 +0,0 @@ -package rule - -import ( - "errors" - "fmt" - "go/ast" - - "github.com/mgechev/revive/lint" -) - -// MaxControlNestingRule sets restriction for maximum nesting of control structures. -type MaxControlNestingRule struct { - max int64 -} - -const defaultMaxControlNesting = 5 - -// Apply applies the rule to given file. -func (r *MaxControlNestingRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - fileAst := file.AST - - walker := &lintMaxControlNesting{ - onFailure: func(failure lint.Failure) { - failures = append(failures, failure) - }, - max: int(r.max), - } - - ast.Walk(walker, fileAst) - - return failures -} - -// Name returns the rule name. -func (*MaxControlNestingRule) Name() string { - return "max-control-nesting" -} - -type lintMaxControlNesting struct { - max int - onFailure func(lint.Failure) - nestingLevelAcc int - lastCtrlStmt ast.Node -} - -func (w *lintMaxControlNesting) Visit(n ast.Node) ast.Visitor { - if w.nestingLevelAcc > w.max { // we are visiting a node beyond the max nesting level - w.onFailure(lint.Failure{ - Failure: fmt.Sprintf("control flow nesting exceeds %d", w.max), - Confidence: 1, - Node: w.lastCtrlStmt, - Category: lint.FailureCategoryComplexity, - }) - return nil // stop visiting deeper - } - - switch v := n.(type) { - case *ast.IfStmt: - w.lastCtrlStmt = v - w.walkControlledBlock(v.Body) // "then" branch block - if v.Else != nil { - w.walkControlledBlock(v.Else) // "else" branch block - } - return nil // stop re-visiting nesting blocks (already visited by w.walkControlledBlock) - - case *ast.ForStmt: - w.lastCtrlStmt = v - w.walkControlledBlock(v.Body) - return nil // stop re-visiting nesting blocks (already visited by w.walkControlledBlock) - - case *ast.CaseClause: // switch case - w.lastCtrlStmt = v - for _, s := range v.Body { // visit each statement in the case clause - w.walkControlledBlock(s) - } - return nil // stop re-visiting nesting blocks (already visited by w.walkControlledBlock) - - case *ast.CommClause: // select case - w.lastCtrlStmt = v - for _, s := range v.Body { // visit each statement in the select case clause - w.walkControlledBlock(s) - } - return nil // stop re-visiting nesting blocks (already visited by w.walkControlledBlock) - - case *ast.FuncLit: - walker := &lintMaxControlNesting{ - onFailure: w.onFailure, - max: w.max, - } - ast.Walk(walker, v.Body) - return nil - } - - return w -} - -func (w *lintMaxControlNesting) walkControlledBlock(b ast.Node) { - oldNestingLevel := w.nestingLevelAcc - w.nestingLevelAcc++ - ast.Walk(w, b) - w.nestingLevelAcc = oldNestingLevel -} - -// Configure validates the rule configuration, and configures the rule accordingly. -// -// Configuration implements the [lint.ConfigurableRule] interface. -func (r *MaxControlNestingRule) Configure(arguments lint.Arguments) error { - if len(arguments) < 1 { - r.max = defaultMaxControlNesting - return nil - } - - check := checkNumberOfArguments(1, arguments, r.Name()) - if check != nil { - return check - } - - maxNesting, ok := arguments[0].(int64) // Alt. non panicking version - if !ok { - return errors.New(`invalid value passed as argument number to the "max-control-nesting" rule`) - } - r.max = maxNesting - return nil -} diff --git a/vendor/github.com/mgechev/revive/rule/max_public_structs.go b/vendor/github.com/mgechev/revive/rule/max_public_structs.go deleted file mode 100644 index c78116d3a2..0000000000 --- a/vendor/github.com/mgechev/revive/rule/max_public_structs.go +++ /dev/null @@ -1,92 +0,0 @@ -package rule - -import ( - "errors" - "fmt" - "go/ast" - "strings" - - "github.com/mgechev/revive/lint" -) - -// MaxPublicStructsRule lints the number of public structs in a file. -type MaxPublicStructsRule struct { - max int64 -} - -const defaultMaxPublicStructs = 5 - -// Configure validates the rule configuration, and configures the rule accordingly. -// -// Configuration implements the [lint.ConfigurableRule] interface. -func (r *MaxPublicStructsRule) Configure(arguments lint.Arguments) error { - if len(arguments) < 1 { - r.max = defaultMaxPublicStructs - return nil - } - - err := checkNumberOfArguments(1, arguments, r.Name()) - if err != nil { - return err - } - - maxStructs, ok := arguments[0].(int64) // Alt. non panicking version - if !ok { - return errors.New(`invalid value passed as argument number to the "max-public-structs" rule`) - } - r.max = maxStructs - return nil -} - -// Apply applies the rule to given file. -func (r *MaxPublicStructsRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - if r.max < 1 { - return failures - } - - fileAst := file.AST - - walker := &lintMaxPublicStructs{ - fileAst: fileAst, - onFailure: func(failure lint.Failure) { - failures = append(failures, failure) - }, - } - - ast.Walk(walker, fileAst) - - if walker.current > r.max { - walker.onFailure(lint.Failure{ - Failure: fmt.Sprintf("you have exceeded the maximum number (%d) of public struct declarations", r.max), - Confidence: 1, - Node: fileAst, - Category: lint.FailureCategoryStyle, - }) - } - - return failures -} - -// Name returns the rule name. -func (*MaxPublicStructsRule) Name() string { - return "max-public-structs" -} - -type lintMaxPublicStructs struct { - current int64 - fileAst *ast.File - onFailure func(lint.Failure) -} - -func (w *lintMaxPublicStructs) Visit(n ast.Node) ast.Visitor { - if v, ok := n.(*ast.TypeSpec); ok { - name := v.Name.Name - first := string(name[0]) - if strings.ToUpper(first) == first { - w.current++ - } - } - return w -} diff --git a/vendor/github.com/mgechev/revive/rule/modifies_param.go b/vendor/github.com/mgechev/revive/rule/modifies_param.go deleted file mode 100644 index 687ee84460..0000000000 --- a/vendor/github.com/mgechev/revive/rule/modifies_param.go +++ /dev/null @@ -1,133 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - - "github.com/mgechev/revive/internal/astutils" - "github.com/mgechev/revive/lint" -) - -// ModifiesParamRule warns on assignments to function parameters. -type ModifiesParamRule struct{} - -// modifyingParamPositions are parameter positions that are modified by a function. -type modifyingParamPositions = []int - -// modifyingFunctions maps function names to the positions of parameters they modify. -var modifyingFunctions = map[string]modifyingParamPositions{ - "slices.Delete": {0}, - "slices.DeleteFunc": {0}, -} - -// Apply applies the rule to given file. -func (*ModifiesParamRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - onFailure := func(failure lint.Failure) { - failures = append(failures, failure) - } - - w := lintModifiesParamRule{onFailure: onFailure} - ast.Walk(w, file.AST) - return failures -} - -// Name returns the rule name. -func (*ModifiesParamRule) Name() string { - return "modifies-parameter" -} - -type lintModifiesParamRule struct { - params map[string]bool - onFailure func(lint.Failure) -} - -func retrieveParamNames(pl []*ast.Field) map[string]bool { - result := make(map[string]bool, len(pl)) - for _, p := range pl { - for _, n := range p.Names { - if n.Name == "_" { - continue - } - - result[n.Name] = true - } - } - return result -} - -func (w lintModifiesParamRule) Visit(node ast.Node) ast.Visitor { - switch v := node.(type) { - case *ast.FuncDecl: - w.params = retrieveParamNames(v.Type.Params.List) - case *ast.IncDecStmt: - if id, ok := v.X.(*ast.Ident); ok { - checkParam(id, &w) - } - case *ast.AssignStmt: - lhs := v.Lhs - for i, e := range lhs { - id, ok := e.(*ast.Ident) - if !ok { - continue - } - - if i < len(v.Rhs) { - w.checkModifyingFunction(v.Rhs[i]) - } - checkParam(id, &w) - } - case *ast.ExprStmt: - w.checkModifyingFunction(v.X) - } - - return w -} - -func checkParam(id *ast.Ident, w *lintModifiesParamRule) { - if w.params[id.Name] { - w.onFailure(lint.Failure{ - Confidence: 0.5, // confidence is low because of shadow variables - Node: id, - Category: lint.FailureCategoryBadPractice, - Failure: fmt.Sprintf("parameter '%s' seems to be modified", id), - }) - } -} - -func (w *lintModifiesParamRule) checkModifyingFunction(callNode ast.Node) { - callExpr, ok := callNode.(*ast.CallExpr) - if !ok { - return - } - - funcName := astutils.GoFmt(callExpr.Fun) - positions, found := modifyingFunctions[funcName] - if !found { - return - } - - for _, pos := range positions { - if pos >= len(callExpr.Args) { - return - } - - id, ok := callExpr.Args[pos].(*ast.Ident) - if !ok { - continue - } - - _, match := w.params[id.Name] - if !match { - continue - } - - w.onFailure(lint.Failure{ - Confidence: 0.5, // confidence is low because of shadow variables - Node: callExpr, - Category: lint.FailureCategoryBadPractice, - Failure: fmt.Sprintf("parameter '%s' seems to be modified by '%s'", id.Name, funcName), - }) - } -} diff --git a/vendor/github.com/mgechev/revive/rule/modifies_value_receiver.go b/vendor/github.com/mgechev/revive/rule/modifies_value_receiver.go deleted file mode 100644 index d8daace08d..0000000000 --- a/vendor/github.com/mgechev/revive/rule/modifies_value_receiver.go +++ /dev/null @@ -1,184 +0,0 @@ -package rule - -import ( - "go/ast" - "go/token" - "strings" - - "github.com/mgechev/revive/internal/astutils" - "github.com/mgechev/revive/lint" -) - -// ModifiesValRecRule lints assignments to value method-receivers. -type ModifiesValRecRule struct{} - -// Apply applies the rule to given file. -func (r *ModifiesValRecRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - file.Pkg.TypeCheck() - for _, decl := range file.AST.Decls { - funcDecl, ok := decl.(*ast.FuncDecl) - isAMethod := ok && funcDecl.Recv != nil - if !isAMethod { - continue // skip, not a method - } - - receiver := funcDecl.Recv.List[0] - if r.mustSkip(receiver, file.Pkg) { - continue - } - - receiverName := receiver.Names[0].Name - assignmentsToReceiver := r.getReceiverModifications(receiverName, funcDecl.Body) - if len(assignmentsToReceiver) == 0 { - continue // receiver is not modified - } - - methodReturnsReceiver := r.seekReturnReceiverStatement(receiverName, funcDecl.Body) != nil - if methodReturnsReceiver { - continue // modification seems legit (see issue #1066) - } - - for _, assignment := range assignmentsToReceiver { - failures = append(failures, lint.Failure{ - Node: assignment, - Confidence: 1, - Failure: "suspicious assignment to a by-value method receiver", - }) - } - } - - return failures -} - -// Name returns the rule name. -func (*ModifiesValRecRule) Name() string { - return "modifies-value-receiver" -} - -func (*ModifiesValRecRule) skipType(t ast.Expr, pkg *lint.Package) bool { - rt := pkg.TypeOf(t) - if rt == nil { - return false - } - - rt = rt.Underlying() - rtName := rt.String() - - // skip when receiver is a map or array - return strings.HasPrefix(rtName, "[]") || strings.HasPrefix(rtName, "map[") -} - -func (*ModifiesValRecRule) getNameFromExpr(ie ast.Expr) string { - ident, ok := ie.(*ast.Ident) - if !ok { - return "" - } - - return ident.Name -} - -func (r *ModifiesValRecRule) seekReturnReceiverStatement(receiverName string, target ast.Node) ast.Node { - finder := func(n ast.Node) bool { - // look for returns with the receiver as value - returnStatement, ok := n.(*ast.ReturnStmt) - if !ok { - return false - } - - for _, exp := range returnStatement.Results { - switch e := exp.(type) { - case *ast.SelectorExpr: // receiver.field = ... - name := r.getNameFromExpr(e.X) - if name == "" || name != receiverName { - continue - } - case *ast.Ident: // receiver := ... - if e.Name != receiverName { - continue - } - case *ast.UnaryExpr: - if e.Op != token.AND { - continue - } - name := r.getNameFromExpr(e.X) - if name == "" || name != receiverName { - continue - } - - default: - continue - } - - return true - } - - return false - } - - return astutils.SeekNode[ast.Node](target, finder) -} - -func (r *ModifiesValRecRule) mustSkip(receiver *ast.Field, pkg *lint.Package) bool { - if _, ok := receiver.Type.(*ast.StarExpr); ok { - return true // skip, method with pointer receiver - } - - if len(receiver.Names) < 1 { - return true // skip, anonymous receiver - } - - receiverName := receiver.Names[0].Name - if receiverName == "_" { - return true // skip, anonymous receiver - } - - if r.skipType(receiver.Type, pkg) { - return true // skip, receiver is a map or array - } - - return false -} - -func (r *ModifiesValRecRule) getReceiverModifications(receiverName string, funcBody *ast.BlockStmt) []ast.Node { - receiverModificationFinder := func(n ast.Node) bool { - switch node := n.(type) { - case *ast.IncDecStmt: - se, ok := node.X.(*ast.SelectorExpr) - if !ok { - return false - } - - name := r.getNameFromExpr(se.X) - return name == receiverName - case *ast.AssignStmt: - // look for assignments with the receiver in the right hand - for _, exp := range node.Lhs { - switch e := exp.(type) { - case *ast.IndexExpr: // receiver...[] = ... - continue - case *ast.StarExpr: // *receiver = ... - continue - case *ast.SelectorExpr: // receiver.field = ... - name := r.getNameFromExpr(e.X) - if name == "" || name != receiverName { - continue - } - case *ast.Ident: // receiver := ... - if e.Name != receiverName { - continue - } - default: - continue - } - - return true - } - } - - return false - } - - return astutils.PickNodes(funcBody, receiverModificationFinder) -} diff --git a/vendor/github.com/mgechev/revive/rule/nested_structs.go b/vendor/github.com/mgechev/revive/rule/nested_structs.go deleted file mode 100644 index 49e240b6f0..0000000000 --- a/vendor/github.com/mgechev/revive/rule/nested_structs.go +++ /dev/null @@ -1,75 +0,0 @@ -package rule - -import ( - "go/ast" - - "github.com/mgechev/revive/lint" -) - -// NestedStructs lints nested structs. -type NestedStructs struct{} - -// Apply applies the rule to given file. -func (*NestedStructs) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - walker := &lintNestedStructs{ - onFailure: func(failure lint.Failure) { - failures = append(failures, failure) - }, - } - - ast.Walk(walker, file.AST) - - return failures -} - -// Name returns the rule name. -func (*NestedStructs) Name() string { - return "nested-structs" -} - -type lintNestedStructs struct { - onFailure func(lint.Failure) -} - -func (l *lintNestedStructs) Visit(n ast.Node) ast.Visitor { - if v, ok := n.(*ast.StructType); ok { - ls := &lintStruct{l.onFailure} - ast.Walk(ls, v.Fields) - } - - return l -} - -type lintStruct struct { - onFailure func(lint.Failure) -} - -func (l *lintStruct) Visit(n ast.Node) ast.Visitor { - switch s := n.(type) { - case *ast.StructType: - l.fail(s) - return nil - case *ast.ArrayType: - if _, ok := s.Elt.(*ast.StructType); ok { - l.fail(s) - } - return nil - case *ast.ChanType: - return nil - case *ast.MapType: - return nil - default: - return l - } -} - -func (l *lintStruct) fail(n ast.Node) { - l.onFailure(lint.Failure{ - Failure: "no nested structs are allowed", - Category: lint.FailureCategoryStyle, - Node: n, - Confidence: 1, - }) -} diff --git a/vendor/github.com/mgechev/revive/rule/optimize_operands_order.go b/vendor/github.com/mgechev/revive/rule/optimize_operands_order.go deleted file mode 100644 index e384f48760..0000000000 --- a/vendor/github.com/mgechev/revive/rule/optimize_operands_order.go +++ /dev/null @@ -1,87 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - "go/token" - - "github.com/mgechev/revive/internal/astutils" - "github.com/mgechev/revive/lint" -) - -// OptimizeOperandsOrderRule checks inefficient conditional expressions. -type OptimizeOperandsOrderRule struct{} - -// Apply applies the rule to given file. -func (*OptimizeOperandsOrderRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - onFailure := func(failure lint.Failure) { - failures = append(failures, failure) - } - w := lintOptimizeOperandsOrderExpr{ - onFailure: onFailure, - } - ast.Walk(w, file.AST) - return failures -} - -// Name returns the rule name. -func (*OptimizeOperandsOrderRule) Name() string { - return "optimize-operands-order" -} - -type lintOptimizeOperandsOrderExpr struct { - onFailure func(failure lint.Failure) -} - -// Visit checks boolean AND and OR expressions to determine -// if swapping their operands may result in an execution speedup. -func (w lintOptimizeOperandsOrderExpr) Visit(node ast.Node) ast.Visitor { - binExpr, ok := node.(*ast.BinaryExpr) - if !ok { - return w - } - - switch binExpr.Op { - case token.LAND, token.LOR: - default: - return w - } - - isCaller := func(n ast.Node) bool { - ce, ok := n.(*ast.CallExpr) - if !ok { - return false - } - - ident, isIdent := ce.Fun.(*ast.Ident) - if !isIdent { - return true - } - - return ident.Name != "len" || ident.Obj != nil - } - - // check if the left sub-expression contains a function call - call := astutils.SeekNode[*ast.CallExpr](binExpr.X, isCaller) - if call == nil { - return w - } - - // check if the right sub-expression does not contain a function call - call = astutils.SeekNode[*ast.CallExpr](binExpr.Y, isCaller) - if call != nil { - return w - } - - newExpr := ast.BinaryExpr{X: binExpr.Y, Y: binExpr.X, Op: binExpr.Op} - w.onFailure(lint.Failure{ - Failure: fmt.Sprintf("for better performance '%v' might be rewritten as '%v'", astutils.GoFmt(binExpr), astutils.GoFmt(&newExpr)), - Node: node, - Category: lint.FailureCategoryOptimization, - Confidence: 0.3, - }) - - return w -} diff --git a/vendor/github.com/mgechev/revive/rule/package_comments.go b/vendor/github.com/mgechev/revive/rule/package_comments.go deleted file mode 100644 index 74af626799..0000000000 --- a/vendor/github.com/mgechev/revive/rule/package_comments.go +++ /dev/null @@ -1,168 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - "go/token" - "strings" - "sync" - - "github.com/mgechev/revive/lint" -) - -// PackageCommentsRule lints the package comments. It complains if -// there is no package comment, or if it is not of the right form. -// This has a notable false positive in that a package comment -// could rightfully appear in a different file of the same package, -// but that's not easy to fix since this linter is file-oriented. -type PackageCommentsRule struct { - checkPackageCommentCache sync.Map -} - -// Apply applies the rule to given file. -func (r *PackageCommentsRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - if file.IsTest() { - return failures - } - - onFailure := func(failure lint.Failure) { - failures = append(failures, failure) - } - - fileAst := file.AST - w := &lintPackageComments{fileAst, file, onFailure, r} - ast.Walk(w, fileAst) - return failures -} - -// Name returns the rule name. -func (*PackageCommentsRule) Name() string { - return "package-comments" -} - -type lintPackageComments struct { - fileAst *ast.File - file *lint.File - onFailure func(lint.Failure) - rule *PackageCommentsRule -} - -func (l *lintPackageComments) checkPackageComment() []lint.Failure { - // deduplicate warnings in package - if _, exists := l.rule.checkPackageCommentCache.LoadOrStore(l.file.Pkg, struct{}{}); exists { - return nil - } - var docFile *ast.File // which name is doc.go - var packageFile *ast.File // which name is $package.go - var firstFile *ast.File - var firstFileName string - var fileSource string - for name, file := range l.file.Pkg.Files() { - if file.AST.Doc != nil { - return nil - } - if name == "doc.go" { - docFile = file.AST - fileSource = "doc.go" - } - if name == file.AST.Name.String()+".go" { - packageFile = file.AST - } - if firstFileName == "" || firstFileName > name { - firstFile = file.AST - firstFileName = name - } - } - // prefer warning on doc.go, $package.go over first file - if docFile == nil { - docFile = packageFile - fileSource = l.fileAst.Name.String() + ".go" - } - if docFile == nil { - docFile = firstFile - fileSource = firstFileName - } - - if docFile != nil { - pkgFile := l.file.Pkg.Files()[fileSource] - return []lint.Failure{{ - Category: lint.FailureCategoryComments, - Position: lint.FailurePosition{ - Start: pkgFile.ToPosition(docFile.Pos()), - End: pkgFile.ToPosition(docFile.Name.End()), - }, - Confidence: 1, - Failure: "should have a package comment", - }} - } - return nil -} - -func (l *lintPackageComments) Visit(_ ast.Node) ast.Visitor { - if l.file.IsTest() { - return nil - } - - prefix := "Package " + l.fileAst.Name.Name + " " - - // Look for a detached package comment. - // First, scan for the last comment that occurs before the "package" keyword. - var lastCG *ast.CommentGroup - for _, cg := range l.fileAst.Comments { - if cg.Pos() > l.fileAst.Package { - // Gone past "package" keyword. - break - } - lastCG = cg - } - if lastCG != nil && strings.HasPrefix(lastCG.Text(), prefix) { - endPos := l.file.ToPosition(lastCG.End()) - pkgPos := l.file.ToPosition(l.fileAst.Package) - if endPos.Line+1 < pkgPos.Line { - // There isn't a great place to anchor this error; - // the start of the blank lines between the doc and the package statement - // is at least pointing at the location of the problem. - pos := token.Position{ - Filename: endPos.Filename, - // Offset not set; it is non-trivial, and doesn't appear to be needed. - Line: endPos.Line + 1, - Column: 1, - } - l.onFailure(lint.Failure{ - Category: lint.FailureCategoryComments, - Position: lint.FailurePosition{ - Start: pos, - End: pos, - }, - Confidence: 0.9, - Failure: "package comment is detached; there should be no blank lines between it and the package statement", - }) - return nil - } - } - - if isEmptyDoc(l.fileAst.Doc) { - for _, failure := range l.checkPackageComment() { - l.onFailure(failure) - } - return nil - } - s := l.fileAst.Doc.Text() - - // Only non-main packages need to keep to this form. - if !l.file.Pkg.IsMain() && !strings.HasPrefix(s, prefix) && !isDirectiveComment(s) { - l.onFailure(lint.Failure{ - Category: lint.FailureCategoryComments, - Node: l.fileAst.Doc, - Confidence: 1, - Failure: fmt.Sprintf(`package comment should be of the form "%s..."`, prefix), - }) - } - return nil -} - -func isEmptyDoc(commentGroup *ast.CommentGroup) bool { - return commentGroup == nil || commentGroup.Text() == "" -} diff --git a/vendor/github.com/mgechev/revive/rule/package_directory_mismatch.go b/vendor/github.com/mgechev/revive/rule/package_directory_mismatch.go deleted file mode 100644 index b150ae6070..0000000000 --- a/vendor/github.com/mgechev/revive/rule/package_directory_mismatch.go +++ /dev/null @@ -1,156 +0,0 @@ -package rule - -import ( - "fmt" - "path/filepath" - "regexp" - "strings" - - "github.com/mgechev/revive/lint" -) - -// PackageDirectoryMismatchRule detects when package name doesn't match directory name. -type PackageDirectoryMismatchRule struct { - ignoredDirs *regexp.Regexp -} - -const defaultIgnoredDirs = "testdata" - -// Configure the rule to exclude certain directories. -func (r *PackageDirectoryMismatchRule) Configure(arguments lint.Arguments) error { - if len(arguments) < 1 { - var err error - r.ignoredDirs, err = r.buildIgnoreRegex([]string{defaultIgnoredDirs}) - return err - } - - args, ok := arguments[0].(map[string]any) - if !ok { - return fmt.Errorf("invalid argument type: expected map[string]any, got %T", arguments[0]) - } - - for k, v := range args { - if !isRuleOption(k, "ignoreDirectories") { - return fmt.Errorf("unknown argument %s for %s rule", k, r.Name()) - } - - ignoredAny, ok := v.([]any) - if !ok { - return fmt.Errorf("invalid value %v for argument %s of rule %s, expected []string got %T", v, k, r.Name(), v) - } - - ignoredDirs := make([]string, len(ignoredAny)) - for i, item := range ignoredAny { - str, ok := item.(string) - if !ok { - return fmt.Errorf("invalid value in %s argument of rule %s: expected string, got %T", k, r.Name(), item) - } - ignoredDirs[i] = str - } - - var err error - r.ignoredDirs, err = r.buildIgnoreRegex(ignoredDirs) - return err - } - - return nil -} - -func (*PackageDirectoryMismatchRule) buildIgnoreRegex(ignoredDirs []string) (*regexp.Regexp, error) { - if len(ignoredDirs) == 0 { - return nil, nil - } - - patterns := make([]string, len(ignoredDirs)) - for i, dir := range ignoredDirs { - patterns[i] = regexp.QuoteMeta(dir) - } - pattern := strings.Join(patterns, "|") - - regex, err := regexp.Compile(pattern) - if err != nil { - return nil, fmt.Errorf("failed to compile regex for ignored directories: %w", err) - } - - return regex, nil -} - -// skipDirs contains directory names that should be unconditionally ignored when checking. -// These entries handle edge cases where filepath.Base might return these values. -var skipDirs = map[string]struct{}{ - ".": {}, // Current directory - "/": {}, // Root directory - "": {}, // Empty path -} - -// semanticallyEqual checks if package and directory names are semantically equal to each other. -func (PackageDirectoryMismatchRule) semanticallyEqual(packageName, dirName string) bool { - normDir := normalizePath(dirName) - normPkg := normalizePath(packageName) - return normDir == normPkg || normDir == "go"+normPkg -} - -// Apply applies the rule to the given file. -func (r *PackageDirectoryMismatchRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - if file.Pkg.IsMain() { - return nil - } - - dirPath := filepath.Dir(file.Name) - dirName := filepath.Base(dirPath) - - if r.ignoredDirs != nil && r.ignoredDirs.MatchString(dirPath) { - return nil - } - - // Check if we got an invalid directory. - if _, skipDir := skipDirs[dirName]; skipDir { - return nil - } - - // Files directly in 'internal/' (like 'internal/abcd.go') should not be checked. - // But files in subdirectories of 'internal/' (like 'internal/foo/abcd.go') should be checked. - if dirName == "internal" { - return nil - } - - packageName := file.AST.Name.Name - - if r.semanticallyEqual(packageName, dirName) { - return nil - } - - if file.IsTest() { - // External test package (directory + '_test' suffix) - if r.semanticallyEqual(packageName, dirName+"_test") { - return nil - } - } - - // define a default failure message - failure := fmt.Sprintf("package name %q does not match directory name %q", packageName, dirName) - - // For version directories (v1, v2, etc.), we need to check also the parent directory - if isVersionPath(dirName) { - parentDirName := filepath.Base(filepath.Dir(dirPath)) - if r.semanticallyEqual(packageName, parentDirName) { - return nil - } - - failure = fmt.Sprintf("package name %q does not match directory name %q or parent directory name %q", packageName, dirName, parentDirName) - } - - return []lint.Failure{ - { - Failure: failure, - Confidence: 1, - Node: file.AST.Name, - Category: lint.FailureCategoryNaming, - }, - } -} - -// Name returns the rule name. -func (*PackageDirectoryMismatchRule) Name() string { - return "package-directory-mismatch" -} diff --git a/vendor/github.com/mgechev/revive/rule/range.go b/vendor/github.com/mgechev/revive/rule/range.go deleted file mode 100644 index 2772f11b83..0000000000 --- a/vendor/github.com/mgechev/revive/rule/range.go +++ /dev/null @@ -1,83 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - "strings" - - "github.com/mgechev/revive/internal/astutils" - "github.com/mgechev/revive/lint" -) - -// RangeRule prevents redundant variables when iterating over a collection. -type RangeRule struct{} - -// Apply applies the rule to given file. -func (*RangeRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - onFailure := func(failure lint.Failure) { - failures = append(failures, failure) - } - - w := &lintRanges{file, onFailure} - ast.Walk(w, file.AST) - return failures -} - -// Name returns the rule name. -func (*RangeRule) Name() string { - return "range" -} - -type lintRanges struct { - file *lint.File - onFailure func(lint.Failure) -} - -func (w *lintRanges) Visit(node ast.Node) ast.Visitor { - rs, ok := node.(*ast.RangeStmt) - if !ok { - return w - } - if rs.Value == nil { - // for x = range m { ... } - return w // single var form - } - if !astutils.IsIdent(rs.Value, "_") { - // for ?, y = range m { ... } - return w - } - - newRS := *rs // shallow copy - newRS.Value = nil - - w.onFailure(lint.Failure{ - Failure: fmt.Sprintf("should omit 2nd value from range; this loop is equivalent to `for %s %s range ...`", w.file.Render(rs.Key), rs.Tok), - Confidence: 1, - Node: rs.Value, - ReplacementLine: firstLineOf(w.file, &newRS, rs), - }) - - return w -} - -func firstLineOf(f *lint.File, node, match ast.Node) string { - line := f.Render(node) - if i := strings.Index(line, "\n"); i >= 0 { - line = line[:i] - } - return indentOf(f, match) + line -} - -func indentOf(f *lint.File, node ast.Node) string { - line := srcLine(f.Content(), f.ToPosition(node.Pos())) - for i, r := range line { - switch r { - case ' ', '\t': - default: - return line[:i] - } - } - return line // unusual or empty line -} diff --git a/vendor/github.com/mgechev/revive/rule/range_val_address.go b/vendor/github.com/mgechev/revive/rule/range_val_address.go deleted file mode 100644 index 6622cd5a50..0000000000 --- a/vendor/github.com/mgechev/revive/rule/range_val_address.go +++ /dev/null @@ -1,166 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - "go/token" - "strings" - - "github.com/mgechev/revive/lint" -) - -// RangeValAddress warns if address of range value is used dangerously. -type RangeValAddress struct{} - -// Apply applies the rule to given file. -func (*RangeValAddress) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - if file.Pkg.IsAtLeastGoVersion(lint.Go122) { - return failures - } - - walker := rangeValAddress{ - file: file, - onFailure: func(failure lint.Failure) { - failures = append(failures, failure) - }, - } - - file.Pkg.TypeCheck() - ast.Walk(walker, file.AST) - - return failures -} - -// Name returns the rule name. -func (*RangeValAddress) Name() string { - return "range-val-address" -} - -type rangeValAddress struct { - file *lint.File - onFailure func(lint.Failure) -} - -func (w rangeValAddress) Visit(node ast.Node) ast.Visitor { - n, ok := node.(*ast.RangeStmt) - if !ok { - return w - } - - value, ok := n.Value.(*ast.Ident) - if !ok { - return w - } - - valueIsStarExpr := false - if t := w.file.Pkg.TypeOf(value); t != nil { - valueIsStarExpr = strings.HasPrefix(t.String(), "*") - } - - ast.Walk(rangeBodyVisitor{ - valueIsStarExpr: valueIsStarExpr, - valueID: value.Obj, - onFailure: w.onFailure, - }, n.Body) - - return w -} - -type rangeBodyVisitor struct { - valueIsStarExpr bool - valueID *ast.Object //nolint:staticcheck // TODO: ast.Object is deprecated - onFailure func(lint.Failure) -} - -func (bw rangeBodyVisitor) Visit(node ast.Node) ast.Visitor { - asgmt, ok := node.(*ast.AssignStmt) - if !ok { - return bw - } - - for _, exp := range asgmt.Lhs { - e, ok := exp.(*ast.IndexExpr) - if !ok { - continue - } - if bw.isAccessingRangeValueAddress(e.Index) { // e.g. a[&value]... - bw.onFailure(bw.newFailure(e.Index)) - } - } - - for _, exp := range asgmt.Rhs { - switch e := exp.(type) { - case *ast.UnaryExpr: // e.g. ...&value, ...&value.id - if bw.isAccessingRangeValueAddress(e) { - bw.onFailure(bw.newFailure(e)) - } - case *ast.CallExpr: - if fun, ok := e.Fun.(*ast.Ident); ok && fun.Name == "append" { // e.g. ...append(arr, &value) - for _, v := range e.Args { - if lit, ok := v.(*ast.CompositeLit); ok { // e.g. ...append(arr, v{id:&value}) - bw.checkCompositeLit(lit) - continue - } - if bw.isAccessingRangeValueAddress(v) { // e.g. ...append(arr, &value) - bw.onFailure(bw.newFailure(v)) - } - } - } - case *ast.CompositeLit: // e.g. ...v{id:&value} - bw.checkCompositeLit(e) - } - } - return bw -} - -func (bw rangeBodyVisitor) checkCompositeLit(comp *ast.CompositeLit) { - for _, exp := range comp.Elts { - e, ok := exp.(*ast.KeyValueExpr) - if !ok { - continue - } - if bw.isAccessingRangeValueAddress(e.Value) { - bw.onFailure(bw.newFailure(e.Value)) - } - } -} - -func (bw rangeBodyVisitor) isAccessingRangeValueAddress(exp ast.Expr) bool { - u, ok := exp.(*ast.UnaryExpr) - if !ok { - return false - } - - if u.Op != token.AND { - return false - } - - v, ok := u.X.(*ast.Ident) - if !ok { - var s *ast.SelectorExpr - s, ok = u.X.(*ast.SelectorExpr) // TODO: possible BUG: if it's `=` and not `:=`, it means that in the last return `ok` is always true - if !ok { - return false - } - v, ok = s.X.(*ast.Ident) - if !ok { - return false - } - - if bw.valueIsStarExpr { // check type of value - return false - } - } - - return ok && v.Obj == bw.valueID // TODO: ok is always true due to the previous TODO remark -} - -func (bw rangeBodyVisitor) newFailure(node ast.Node) lint.Failure { - return lint.Failure{ - Node: node, - Confidence: 1, - Failure: fmt.Sprintf("suspicious assignment of '%s'. range-loop variables always have the same address", bw.valueID.Name), - } -} diff --git a/vendor/github.com/mgechev/revive/rule/range_val_in_closure.go b/vendor/github.com/mgechev/revive/rule/range_val_in_closure.go deleted file mode 100644 index a99376fbf7..0000000000 --- a/vendor/github.com/mgechev/revive/rule/range_val_in_closure.go +++ /dev/null @@ -1,125 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - - "github.com/mgechev/revive/lint" -) - -// RangeValInClosureRule warns if range value is used in a closure dispatched as goroutine. -type RangeValInClosureRule struct{} - -// Apply applies the rule to given file. -func (*RangeValInClosureRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - if file.Pkg.IsAtLeastGoVersion(lint.Go122) { - return failures - } - - walker := rangeValInClosure{ - onFailure: func(failure lint.Failure) { - failures = append(failures, failure) - }, - } - - ast.Walk(walker, file.AST) - - return failures -} - -// Name returns the rule name. -func (*RangeValInClosureRule) Name() string { - return "range-val-in-closure" -} - -type rangeValInClosure struct { - onFailure func(lint.Failure) -} - -func (w rangeValInClosure) Visit(node ast.Node) ast.Visitor { - // Find the variables updated by the loop statement. - var vars []*ast.Ident - addVar := func(expr ast.Expr) { - if id, ok := expr.(*ast.Ident); ok { - vars = append(vars, id) - } - } - var body *ast.BlockStmt - switch n := node.(type) { - case *ast.RangeStmt: - body = n.Body - addVar(n.Key) - addVar(n.Value) - case *ast.ForStmt: - body = n.Body - switch post := n.Post.(type) { - case *ast.AssignStmt: - // e.g. for p = head; p != nil; p = p.next - for _, lhs := range post.Lhs { - addVar(lhs) - } - case *ast.IncDecStmt: - // e.g. for i := 0; i < n; i++ - addVar(post.X) - } - } - if vars == nil { - return w - } - - // Inspect a go or defer statement - // if it's the last one in the loop body. - // (We give up if there are following statements, - // because it's hard to prove go isn't followed by wait, - // or defer by return.) - if len(body.List) == 0 { - return w - } - var last *ast.CallExpr - switch s := body.List[len(body.List)-1].(type) { - case *ast.GoStmt: - last = s.Call - case *ast.DeferStmt: - last = s.Call - default: - return w - } - lit, ok := last.Fun.(*ast.FuncLit) - if !ok { - return w - } - - if lit.Type == nil { - // Not referring to a variable (e.g. struct field name) - return w - } - - var inspector func(n ast.Node) bool - inspector = func(n ast.Node) bool { - kv, ok := n.(*ast.KeyValueExpr) - if ok { - // do not check identifiers acting as key in key-value expressions (see issue #637) - ast.Inspect(kv.Value, inspector) - return false - } - id, ok := n.(*ast.Ident) - if !ok || id.Obj == nil { - return true - } - - for _, v := range vars { - if v.Obj == id.Obj { - w.onFailure(lint.Failure{ - Confidence: 1, - Failure: fmt.Sprintf("loop variable %v captured by func literal", id.Name), - Node: n, - }) - } - } - return true - } - ast.Inspect(lit.Body, inspector) - return w -} diff --git a/vendor/github.com/mgechev/revive/rule/receiver_naming.go b/vendor/github.com/mgechev/revive/rule/receiver_naming.go deleted file mode 100644 index e2737ed895..0000000000 --- a/vendor/github.com/mgechev/revive/rule/receiver_naming.go +++ /dev/null @@ -1,110 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - - "github.com/mgechev/revive/internal/typeparams" - "github.com/mgechev/revive/lint" -) - -// ReceiverNamingRule lints a receiver name. -type ReceiverNamingRule struct { - receiverNameMaxLength int -} - -const defaultReceiverNameMaxLength = -1 // thus will not check -// Configure validates the rule configuration, and configures the rule accordingly. -// -// Configuration implements the [lint.ConfigurableRule] interface. -func (r *ReceiverNamingRule) Configure(arguments lint.Arguments) error { - r.receiverNameMaxLength = defaultReceiverNameMaxLength - if len(arguments) < 1 { - return nil - } - - args, ok := arguments[0].(map[string]any) - if !ok { - return fmt.Errorf("unable to get arguments for rule %s. Expected object of key-value-pairs", r.Name()) - } - - for k, v := range args { - if !isRuleOption(k, "maxLength") { - return fmt.Errorf("unknown argument %s for %s rule", k, r.Name()) - } - value, ok := v.(int64) - if !ok { - return fmt.Errorf("invalid value %v for argument %s of rule %s, expected integer value got %T", v, k, r.Name(), v) - } - r.receiverNameMaxLength = int(value) - } - return nil -} - -// Apply applies the rule to given file. -func (r *ReceiverNamingRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - typeReceiver := map[string]string{} - var failures []lint.Failure - for _, decl := range file.AST.Decls { - fn, ok := decl.(*ast.FuncDecl) - if !ok || fn.Recv == nil || len(fn.Recv.List) == 0 { - continue - } - - names := fn.Recv.List[0].Names - if len(names) < 1 { - continue - } - name := names[0].Name - - if name == "_" { - failures = append(failures, lint.Failure{ - Node: decl, - Confidence: 1, - Category: lint.FailureCategoryNaming, - Failure: "receiver name should not be an underscore, omit the name if it is unused", - }) - continue - } - - if name == "this" || name == "self" { - failures = append(failures, lint.Failure{ - Node: decl, - Confidence: 1, - Category: lint.FailureCategoryNaming, - Failure: `receiver name should be a reflection of its identity; don't use generic names such as "this" or "self"`, - }) - continue - } - - if r.receiverNameMaxLength > 0 && len([]rune(name)) > r.receiverNameMaxLength { - failures = append(failures, lint.Failure{ - Node: decl, - Confidence: 1, - Category: lint.FailureCategoryNaming, - Failure: fmt.Sprintf("receiver name %s is longer than %d characters", name, r.receiverNameMaxLength), - }) - continue - } - - recv := typeparams.ReceiverType(fn) - if prev, ok := typeReceiver[recv]; ok && prev != name { - failures = append(failures, lint.Failure{ - Node: decl, - Confidence: 1, - Category: lint.FailureCategoryNaming, - Failure: fmt.Sprintf("receiver name %s should be consistent with previous receiver name %s for %s", name, prev, recv), - }) - continue - } - - typeReceiver[recv] = name - } - - return failures -} - -// Name returns the rule name. -func (*ReceiverNamingRule) Name() string { - return "receiver-naming" -} diff --git a/vendor/github.com/mgechev/revive/rule/redefines_builtin_id.go b/vendor/github.com/mgechev/revive/rule/redefines_builtin_id.go deleted file mode 100644 index 52c679f17a..0000000000 --- a/vendor/github.com/mgechev/revive/rule/redefines_builtin_id.go +++ /dev/null @@ -1,224 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - "go/token" - "maps" - - "github.com/mgechev/revive/lint" -) - -var builtInConstAndVars = map[string]bool{ - "true": true, - "false": true, - "iota": true, - "nil": true, -} - -var builtFunctions = map[string]bool{ - "append": true, - "cap": true, - "close": true, - "complex": true, - "copy": true, - "delete": true, - "imag": true, - "len": true, - "make": true, - "new": true, - "panic": true, - "print": true, - "println": true, - "real": true, - "recover": true, -} - -var builtFunctionsAfterGo121 = map[string]bool{ - "clear": true, - "max": true, - "min": true, -} - -var builtInTypes = map[string]bool{ - "bool": true, - "byte": true, - "complex128": true, - "complex64": true, - "error": true, - "float32": true, - "float64": true, - "int": true, - "int16": true, - "int32": true, - "int64": true, - "int8": true, - "rune": true, - "string": true, - "uint": true, - "uint16": true, - "uint32": true, - "uint64": true, - "uint8": true, - "uintptr": true, - "any": true, -} - -// RedefinesBuiltinIDRule warns when a builtin identifier is shadowed. -type RedefinesBuiltinIDRule struct{} - -// Apply applies the rule to given file. -func (*RedefinesBuiltinIDRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - onFailure := func(failure lint.Failure) { - failures = append(failures, failure) - } - - astFile := file.AST - - builtFuncs := maps.Clone(builtFunctions) - if file.Pkg.IsAtLeastGoVersion(lint.Go121) { - maps.Copy(builtFuncs, builtFunctionsAfterGo121) - } - w := &lintRedefinesBuiltinID{ - onFailure: onFailure, - builtInConstAndVars: builtInConstAndVars, - builtFunctions: builtFuncs, - builtInTypes: builtInTypes, - } - ast.Walk(w, astFile) - - return failures -} - -// Name returns the rule name. -func (*RedefinesBuiltinIDRule) Name() string { - return "redefines-builtin-id" -} - -type lintRedefinesBuiltinID struct { - onFailure func(lint.Failure) - builtInConstAndVars map[string]bool - builtFunctions map[string]bool - builtInTypes map[string]bool -} - -func (w *lintRedefinesBuiltinID) Visit(node ast.Node) ast.Visitor { - switch n := node.(type) { - case *ast.GenDecl: - switch n.Tok { - case token.TYPE: - if len(n.Specs) < 1 { - return nil - } - typeSpec, ok := n.Specs[0].(*ast.TypeSpec) - if !ok { - return nil - } - id := typeSpec.Name.Name - if ok, bt := w.isBuiltIn(id); ok { - w.addFailure(n, fmt.Sprintf("redefinition of the built-in %s %s", bt, id)) - } - case token.VAR, token.CONST: - for _, vs := range n.Specs { - valSpec, ok := vs.(*ast.ValueSpec) - if !ok { - continue - } - for _, name := range valSpec.Names { - if ok, bt := w.isBuiltIn(name.Name); ok { - w.addFailure(n, fmt.Sprintf("redefinition of the built-in %s %s", bt, name)) - } - } - } - default: - return nil // skip if not type/var/const declaration - } - - case *ast.FuncDecl: - if n.Recv != nil { - return w // skip methods - } - - id := n.Name.Name - if ok, bt := w.isBuiltIn(id); ok { - w.addFailure(n, fmt.Sprintf("redefinition of the built-in %s %s", bt, id)) - } - case *ast.FuncType: - var fields []*ast.Field - if n.TypeParams != nil { - fields = append(fields, n.TypeParams.List...) - } - if n.Params != nil { - fields = append(fields, n.Params.List...) - } - if n.Results != nil { - fields = append(fields, n.Results.List...) - } - for _, field := range fields { - for _, name := range field.Names { - obj := name.Obj - isTypeOrName := obj != nil && (obj.Kind == ast.Var || obj.Kind == ast.Typ) - if !isTypeOrName { - continue - } - - id := obj.Name - if ok, bt := w.isBuiltIn(id); ok { - w.addFailure(name, fmt.Sprintf("redefinition of the built-in %s %s", bt, id)) - } - } - } - case *ast.AssignStmt: - for _, e := range n.Lhs { - id, ok := e.(*ast.Ident) - if !ok { - continue - } - - if ok, bt := w.isBuiltIn(id.Name); ok { - var msg string - switch bt { - case "constant or variable": - if n.Tok == token.DEFINE { - msg = fmt.Sprintf("assignment creates a shadow of built-in identifier %s", id.Name) - } else { - msg = fmt.Sprintf("assignment modifies built-in identifier %s", id.Name) - } - default: - msg = fmt.Sprintf("redefinition of the built-in %s %s", bt, id) - } - - w.addFailure(n, msg) - } - } - } - - return w -} - -func (w *lintRedefinesBuiltinID) addFailure(node ast.Node, msg string) { - w.onFailure(lint.Failure{ - Confidence: 1, - Node: node, - Category: lint.FailureCategoryLogic, - Failure: msg, - }) -} - -func (w *lintRedefinesBuiltinID) isBuiltIn(id string) (r bool, builtInKind string) { - if w.builtFunctions[id] { - return true, "function" - } - - if w.builtInConstAndVars[id] { - return true, "constant or variable" - } - - if w.builtInTypes[id] { - return true, "type" - } - - return false, "" -} diff --git a/vendor/github.com/mgechev/revive/rule/redundant_build_tag.go b/vendor/github.com/mgechev/revive/rule/redundant_build_tag.go deleted file mode 100644 index d195ce6e42..0000000000 --- a/vendor/github.com/mgechev/revive/rule/redundant_build_tag.go +++ /dev/null @@ -1,41 +0,0 @@ -package rule - -import ( - "strings" - - "github.com/mgechev/revive/lint" -) - -// RedundantBuildTagRule lints the presence of redundant build tags. -type RedundantBuildTagRule struct{} - -// Apply triggers if an old build tag `// +build` is found after a new one `//go:build`. -// `//go:build` comments are automatically added by gofmt when Go 1.17+ is used. -// See https://pkg.go.dev/cmd/go#hdr-Build_constraints -func (*RedundantBuildTagRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - for _, group := range file.AST.Comments { - hasGoBuild := false - for _, comment := range group.List { - if strings.HasPrefix(comment.Text, "//go:build ") { - hasGoBuild = true - continue - } - - if hasGoBuild && strings.HasPrefix(comment.Text, "// +build ") { - return []lint.Failure{{ - Category: lint.FailureCategoryStyle, - Confidence: 1, - Node: comment, - Failure: `The build tag "// +build" is redundant since Go 1.17 and can be removed`, - }} - } - } - } - - return []lint.Failure{} -} - -// Name returns the rule name. -func (*RedundantBuildTagRule) Name() string { - return "redundant-build-tag" -} diff --git a/vendor/github.com/mgechev/revive/rule/redundant_import_alias.go b/vendor/github.com/mgechev/revive/rule/redundant_import_alias.go deleted file mode 100644 index 9c2edb0139..0000000000 --- a/vendor/github.com/mgechev/revive/rule/redundant_import_alias.go +++ /dev/null @@ -1,52 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - "strings" - - "github.com/mgechev/revive/lint" -) - -// RedundantImportAlias warns on import aliases matching the imported package name. -type RedundantImportAlias struct{} - -// Apply applies the rule to given file. -func (*RedundantImportAlias) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - for _, imp := range file.AST.Imports { - if imp.Name == nil { - continue - } - - if getImportPackageName(imp) == imp.Name.Name { - failures = append(failures, lint.Failure{ - Confidence: 1, - Failure: fmt.Sprintf("Import alias %q is redundant", imp.Name.Name), - Node: imp, - Category: lint.FailureCategoryImports, - }) - } - } - - return failures -} - -// Name returns the rule name. -func (*RedundantImportAlias) Name() string { - return "redundant-import-alias" -} - -func getImportPackageName(imp *ast.ImportSpec) string { - const pathSep = "/" - const strDelim = `"` - - path := imp.Path.Value - i := strings.LastIndex(path, pathSep) - if i == -1 { - return strings.Trim(path, strDelim) - } - - return strings.Trim(path[i+1:], strDelim) -} diff --git a/vendor/github.com/mgechev/revive/rule/redundant_test_main_exit.go b/vendor/github.com/mgechev/revive/rule/redundant_test_main_exit.go deleted file mode 100644 index 01a90a47c6..0000000000 --- a/vendor/github.com/mgechev/revive/rule/redundant_test_main_exit.go +++ /dev/null @@ -1,79 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - - "github.com/mgechev/revive/lint" -) - -// RedundantTestMainExitRule suggests removing Exit call in TestMain function for test files. -type RedundantTestMainExitRule struct{} - -// Apply applies the rule to given file. -func (*RedundantTestMainExitRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - if !file.IsTest() || !file.Pkg.IsAtLeastGoVersion(lint.Go115) { - // skip analysis for non-test files or for Go versions before 1.15 - return failures - } - - onFailure := func(failure lint.Failure) { - failures = append(failures, failure) - } - - w := &lintRedundantTestMainExit{onFailure: onFailure} - ast.Walk(w, file.AST) - return failures -} - -// Name returns the rule name. -func (*RedundantTestMainExitRule) Name() string { - return "redundant-test-main-exit" -} - -type lintRedundantTestMainExit struct { - onFailure func(lint.Failure) -} - -func (w *lintRedundantTestMainExit) Visit(node ast.Node) ast.Visitor { - if fd, ok := node.(*ast.FuncDecl); ok { - if fd.Name.Name != "TestMain" { - return nil // skip analysis for other functions than TestMain - } - - return w - } - - se, ok := node.(*ast.ExprStmt) - if !ok { - return w - } - ce, ok := se.X.(*ast.CallExpr) - if !ok { - return w - } - - fc, ok := ce.Fun.(*ast.SelectorExpr) - if !ok { - return w - } - id, ok := fc.X.(*ast.Ident) - if !ok { - return w - } - - pkg := id.Name - fn := fc.Sel.Name - if isCallToExitFunction(pkg, fn) { - w.onFailure(lint.Failure{ - Confidence: 1, - Node: ce, - Category: lint.FailureCategoryStyle, - Failure: fmt.Sprintf("redundant call to %s.%s in TestMain function, the test runner will handle it automatically as of Go 1.15", pkg, fn), - }) - } - - return w -} diff --git a/vendor/github.com/mgechev/revive/rule/string_format.go b/vendor/github.com/mgechev/revive/rule/string_format.go deleted file mode 100644 index b653cb13e8..0000000000 --- a/vendor/github.com/mgechev/revive/rule/string_format.go +++ /dev/null @@ -1,308 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - "go/token" - "regexp" - "strconv" - "strings" - - "github.com/mgechev/revive/lint" -) - -// StringFormatRule lints strings and/or comments according to a set of regular expressions given as Arguments. -type StringFormatRule struct { - rules []stringFormatSubrule -} - -// Apply applies the rule to the given file. -func (r *StringFormatRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - onFailure := func(failure lint.Failure) { - failures = append(failures, failure) - } - - for i := range r.rules { - r.rules[i].onFailure = onFailure - } - - w := &lintStringFormatRule{ - rules: r.rules, - } - - ast.Walk(w, file.AST) - - return failures -} - -// Name returns the rule name. -func (*StringFormatRule) Name() string { - return "string-format" -} - -// Configure validates the rule configuration, and configures the rule accordingly. -// -// Configuration implements the [lint.ConfigurableRule] interface. -func (r *StringFormatRule) Configure(arguments lint.Arguments) error { - for i, argument := range arguments { - scopes, regex, negated, errorMessage, err := r.parseArgument(argument, i) - if err != nil { - return err - } - r.rules = append(r.rules, stringFormatSubrule{ - scopes: scopes, - regexp: regex, - negated: negated, - errorMessage: errorMessage, - }) - } - return nil -} - -type lintStringFormatRule struct { - rules []stringFormatSubrule -} - -type stringFormatSubrule struct { - onFailure func(lint.Failure) - scopes stringFormatSubruleScopes - regexp *regexp.Regexp - negated bool - errorMessage string -} - -type stringFormatSubruleScopes []*stringFormatSubruleScope - -type stringFormatSubruleScope struct { - funcName string // Function name the rule is scoped to - argument int // (optional) Which argument in calls to the function is checked against the rule (the first argument is checked by default) - field string // (optional) If the argument to be checked is a struct, which member of the struct is checked against the rule (top level members only) -} - -// Regex inserted to match valid function/struct field identifiers. -const identRegex = "[_A-Za-z][_A-Za-z0-9]*" - -var parseStringFormatScope = regexp.MustCompile( - fmt.Sprintf("^(%s(?:\\.%s)?)(?:\\[([0-9]+)\\](?:\\.(%s))?)?$", identRegex, identRegex, identRegex)) - -func (r *StringFormatRule) parseArgument(argument any, ruleNum int) (scopes stringFormatSubruleScopes, regex *regexp.Regexp, negated bool, errorMessage string, err error) { - g, ok := argument.([]any) // Cast to generic slice first - if !ok { - return stringFormatSubruleScopes{}, regex, false, "", r.configError("argument is not a slice", ruleNum, 0) - } - if len(g) < 2 { - return stringFormatSubruleScopes{}, regex, false, "", r.configError("less than two slices found in argument, scope and regex are required", ruleNum, len(g)-1) - } - rule := make([]string, len(g)) - for i, obj := range g { - val, ok := obj.(string) - if !ok { - return stringFormatSubruleScopes{}, regex, false, "", r.configError("unexpected value, string was expected", ruleNum, i) - } - rule[i] = val - } - - // Validate scope and regex length - if rule[0] == "" { - return stringFormatSubruleScopes{}, regex, false, "", r.configError("empty scope provided", ruleNum, 0) - } else if len(rule[1]) < 2 { - return stringFormatSubruleScopes{}, regex, false, "", r.configError("regex is too small (regexes should begin and end with '/')", ruleNum, 1) - } - - // Parse rule scopes - rawScopes := strings.Split(rule[0], ",") - - scopes = make([]*stringFormatSubruleScope, 0, len(rawScopes)) - for scopeNum, rawScope := range rawScopes { - rawScope = strings.TrimSpace(rawScope) - - if rawScope == "" { - return stringFormatSubruleScopes{}, regex, false, "", r.parseScopeError("empty scope in rule scopes:", ruleNum, 0, scopeNum) - } - - scope := stringFormatSubruleScope{} - matches := parseStringFormatScope.FindStringSubmatch(rawScope) - if matches == nil { - // The rule's scope didn't match the parsing regex at all, probably a configuration error - return stringFormatSubruleScopes{}, regex, false, "", r.parseScopeError("unable to parse rule scope", ruleNum, 0, scopeNum) - } else if len(matches) != 4 { - // The rule's scope matched the parsing regex, but an unexpected number of submatches was returned, probably a bug - return stringFormatSubruleScopes{}, regex, false, "", - r.parseScopeError(fmt.Sprintf("unexpected number of submatches when parsing scope: %d, expected 4", len(matches)), ruleNum, 0, scopeNum) - } - scope.funcName = matches[1] - if matches[2] != "" { - var err error - scope.argument, err = strconv.Atoi(matches[2]) - if err != nil { - return stringFormatSubruleScopes{}, regex, false, "", r.parseScopeError("unable to parse argument number in rule scope", ruleNum, 0, scopeNum) - } - } - if matches[3] != "" { - scope.field = matches[3] - } - - scopes = append(scopes, &scope) - } - - // Strip / characters from the beginning and end of rule[1] before compiling - negated = rule[1][0] == '!' - offset := 1 - if negated { - offset++ - } - regex, errr := regexp.Compile(rule[1][offset : len(rule[1])-1]) - if errr != nil { - return stringFormatSubruleScopes{}, regex, false, "", r.parseError(fmt.Sprintf("unable to compile %s as regexp", rule[1]), ruleNum, 1) - } - - // Use custom error message if provided - if len(rule) == 3 { - errorMessage = rule[2] - } - return scopes, regex, negated, errorMessage, nil -} - -// Report an invalid config, this is specifically the user's fault. -func (*StringFormatRule) configError(msg string, ruleNum, option int) error { - return fmt.Errorf("invalid configuration for string-format: %s [argument %d, option %d]", msg, ruleNum, option) -} - -// Report a general config parsing failure, this may be the user's fault, but it isn't known for certain. -func (*StringFormatRule) parseError(msg string, ruleNum, option int) error { - return fmt.Errorf("failed to parse configuration for string-format: %s [argument %d, option %d]", msg, ruleNum, option) -} - -// Report a general scope config parsing failure, this may be the user's fault, but it isn't known for certain. -func (*StringFormatRule) parseScopeError(msg string, ruleNum, option, scopeNum int) error { - return fmt.Errorf("failed to parse configuration for string-format: %s [argument %d, option %d, scope index %d]", msg, ruleNum, option, scopeNum) -} - -func (w *lintStringFormatRule) Visit(node ast.Node) ast.Visitor { - // First, check if node is a call expression - call, ok := node.(*ast.CallExpr) - if !ok { - return w - } - - // Get the name of the call expression to check against rule scope - callName, ok := w.getCallName(call) - if !ok { - return w - } - - for _, rule := range w.rules { - for _, scope := range rule.scopes { - if scope.funcName == callName { - rule.apply(call, scope) - } - } - } - - return w -} - -// Return the name of a call expression in the form of package.Func or Func. -func (*lintStringFormatRule) getCallName(call *ast.CallExpr) (callName string, ok bool) { - if ident, ok := call.Fun.(*ast.Ident); ok { - // Local function call - return ident.Name, true - } - - if selector, ok := call.Fun.(*ast.SelectorExpr); ok { - // Scoped function call - scope, ok := selector.X.(*ast.Ident) - if ok { - return scope.Name + "." + selector.Sel.Name, true - } - // Scoped function call inside structure - recv, ok := selector.X.(*ast.SelectorExpr) - if ok { - return recv.Sel.Name + "." + selector.Sel.Name, true - } - } - - return "", false -} - -// apply a single format rule to a call expression (should be done after verifying the that the call expression matches the rule's scope). -func (r *stringFormatSubrule) apply(call *ast.CallExpr, scope *stringFormatSubruleScope) { - if len(call.Args) <= scope.argument { - return - } - - arg := call.Args[scope.argument] - var lit *ast.BasicLit - if scope.field != "" { - // Try finding the scope's Field, treating arg as a composite literal - composite, ok := arg.(*ast.CompositeLit) - if !ok { - return - } - for _, el := range composite.Elts { - kv, ok := el.(*ast.KeyValueExpr) - if !ok { - continue - } - key, ok := kv.Key.(*ast.Ident) - if !ok || key.Name != scope.field { - continue - } - - // We're now dealing with the exact field in the rule's scope, so if anything fails, we can safely return instead of continuing the loop - lit, ok = kv.Value.(*ast.BasicLit) - if !ok || lit.Kind != token.STRING { - return - } - } - } else { - var ok bool - // Treat arg as a string literal - lit, ok = arg.(*ast.BasicLit) - if !ok || lit.Kind != token.STRING { - return - } - } - - // extra safety check - if lit == nil { - return - } - - // Unquote the string literal before linting - unquoted := lit.Value[1 : len(lit.Value)-1] - if r.stringIsOK(unquoted) { - return - } - - r.generateFailure(lit) -} - -func (r *stringFormatSubrule) stringIsOK(s string) bool { - matches := r.regexp.MatchString(s) - if r.negated { - return !matches - } - - return matches -} - -func (r *stringFormatSubrule) generateFailure(node ast.Node) { - var failure string - switch { - case r.errorMessage != "": - failure = r.errorMessage - case r.negated: - failure = fmt.Sprintf("string literal matches user defined regex /%s/", r.regexp.String()) - case !r.negated: - failure = fmt.Sprintf("string literal doesn't match user defined regex /%s/", r.regexp.String()) - } - - r.onFailure(lint.Failure{ - Confidence: 1, - Failure: failure, - Node: node, - }) -} diff --git a/vendor/github.com/mgechev/revive/rule/string_of_int.go b/vendor/github.com/mgechev/revive/rule/string_of_int.go deleted file mode 100644 index 3bec1d6ac5..0000000000 --- a/vendor/github.com/mgechev/revive/rule/string_of_int.go +++ /dev/null @@ -1,95 +0,0 @@ -package rule - -import ( - "go/ast" - "go/types" - - "github.com/mgechev/revive/lint" -) - -// StringOfIntRule warns when logic expressions contains Boolean literals. -type StringOfIntRule struct{} - -// Apply applies the rule to given file. -func (*StringOfIntRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - - onFailure := func(failure lint.Failure) { - failures = append(failures, failure) - } - - astFile := file.AST - file.Pkg.TypeCheck() - - w := &lintStringInt{file, onFailure} - ast.Walk(w, astFile) - - return failures -} - -// Name returns the rule name. -func (*StringOfIntRule) Name() string { - return "string-of-int" -} - -type lintStringInt struct { - file *lint.File - onFailure func(lint.Failure) -} - -func (w *lintStringInt) Visit(node ast.Node) ast.Visitor { - ce, ok := node.(*ast.CallExpr) - if !ok { - return w - } - - if !w.isCallStringCast(ce.Fun) { - return w - } - - if !w.isIntExpression(ce.Args) { - return w - } - - w.onFailure(lint.Failure{ - Confidence: 1, - Node: ce, - Failure: "dubious conversion of an integer into a string, use strconv.Itoa", - }) - - return w -} - -func (w *lintStringInt) isCallStringCast(e ast.Expr) bool { - t := w.file.Pkg.TypeOf(e) - if t == nil { - return false - } - - tb, _ := t.Underlying().(*types.Basic) - - return tb != nil && tb.Kind() == types.String -} - -func (w *lintStringInt) isIntExpression(es []ast.Expr) bool { - if len(es) != 1 { - return false - } - - t := w.file.Pkg.TypeOf(es[0]) - if t == nil { - return false - } - - ut, _ := t.Underlying().(*types.Basic) - if ut == nil || ut.Info()&types.IsInteger == 0 { - return false - } - - switch ut.Kind() { - case types.Byte, types.Rune, types.UntypedRune: - return false - } - - return true -} diff --git a/vendor/github.com/mgechev/revive/rule/struct_tag.go b/vendor/github.com/mgechev/revive/rule/struct_tag.go deleted file mode 100644 index edb6f9581b..0000000000 --- a/vendor/github.com/mgechev/revive/rule/struct_tag.go +++ /dev/null @@ -1,856 +0,0 @@ -package rule - -import ( - "fmt" - "go/ast" - "slices" - "strconv" - "strings" - - "github.com/fatih/structtag" - - "github.com/mgechev/revive/internal/astutils" - "github.com/mgechev/revive/lint" -) - -// StructTagRule lints struct tags. -type StructTagRule struct { - userDefined map[tagKey][]string // map: key -> []option -} - -type tagKey string - -const ( - keyASN1 tagKey = "asn1" - keyBSON tagKey = "bson" - keyDatastore tagKey = "datastore" - keyDefault tagKey = "default" - keyJSON tagKey = "json" - keyMapstructure tagKey = "mapstructure" - keyProperties tagKey = "properties" - keyProtobuf tagKey = "protobuf" - keyRequired tagKey = "required" - keySpanner tagKey = "spanner" - keyTOML tagKey = "toml" - keyURL tagKey = "url" - keyValidate tagKey = "validate" - keyXML tagKey = "xml" - keyYAML tagKey = "yaml" -) - -type tagChecker func(checkCtx *checkContext, tag *structtag.Tag, fieldType ast.Expr) (message string, succeeded bool) - -var tagCheckers = map[tagKey]tagChecker{ - keyASN1: checkASN1Tag, - keyBSON: checkBSONTag, - keyDatastore: checkDatastoreTag, - keyDefault: checkDefaultTag, - keyJSON: checkJSONTag, - keyMapstructure: checkMapstructureTag, - keyProperties: checkPropertiesTag, - keyProtobuf: checkProtobufTag, - keyRequired: checkRequiredTag, - keySpanner: checkSpannerTag, - keyTOML: checkTOMLTag, - keyURL: checkURLTag, - keyValidate: checkValidateTag, - keyXML: checkXMLTag, - keyYAML: checkYAMLTag, -} - -type checkContext struct { - userDefined map[tagKey][]string // map: key -> []option - usedTagNbr map[int]bool // list of used tag numbers - usedTagName map[string]bool // list of used tag keys - isAtLeastGo124 bool -} - -func (checkCtx checkContext) isUserDefined(key tagKey, opt string) bool { - if checkCtx.userDefined == nil { - return false - } - - options := checkCtx.userDefined[key] - return slices.Contains(options, opt) -} - -// Configure validates the rule configuration, and configures the rule accordingly. -// -// Configuration implements the [lint.ConfigurableRule] interface. -func (r *StructTagRule) Configure(arguments lint.Arguments) error { - if len(arguments) == 0 { - return nil - } - - err := checkNumberOfArguments(1, arguments, r.Name()) - if err != nil { - return err - } - - r.userDefined = make(map[tagKey][]string, len(arguments)) - for _, arg := range arguments { - item, ok := arg.(string) - if !ok { - return fmt.Errorf("invalid argument to the %s rule. Expecting a string, got %v (of type %T)", r.Name(), arg, arg) - } - parts := strings.Split(item, ",") - if len(parts) < 2 { - return fmt.Errorf("invalid argument to the %s rule. Expecting a string of the form key[,option]+, got %s", r.Name(), item) - } - key := tagKey(strings.TrimSpace(parts[0])) - for i := 1; i < len(parts); i++ { - option := strings.TrimSpace(parts[i]) - r.userDefined[key] = append(r.userDefined[key], option) - } - } - - return nil -} - -// Apply applies the rule to given file. -func (r *StructTagRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { - var failures []lint.Failure - onFailure := func(failure lint.Failure) { - failures = append(failures, failure) - } - - w := lintStructTagRule{ - onFailure: onFailure, - userDefined: r.userDefined, - isAtLeastGo124: file.Pkg.IsAtLeastGoVersion(lint.Go124), - tagCheckers: tagCheckers, - } - - ast.Walk(w, file.AST) - - return failures -} - -// Name returns the rule name. -func (*StructTagRule) Name() string { - return "struct-tag" -} - -type lintStructTagRule struct { - onFailure func(lint.Failure) - userDefined map[tagKey][]string // map: key -> []option - isAtLeastGo124 bool - tagCheckers map[tagKey]tagChecker -} - -func (w lintStructTagRule) Visit(node ast.Node) ast.Visitor { - if n, ok := node.(*ast.StructType); ok { - isEmptyStruct := n.Fields == nil || n.Fields.NumFields() < 1 - if isEmptyStruct { - return nil // skip empty structs - } - - checkCtx := &checkContext{ - userDefined: w.userDefined, - usedTagNbr: map[int]bool{}, - usedTagName: map[string]bool{}, - isAtLeastGo124: w.isAtLeastGo124, - } - - for _, f := range n.Fields.List { - if f.Tag != nil { - w.checkTaggedField(checkCtx, f) - } - } - } - - return w -} - -// checkTaggedField checks the tag of the given field. -// precondition: the field has a tag -func (w lintStructTagRule) checkTaggedField(checkCtx *checkContext, f *ast.Field) { - if len(f.Names) > 0 && !f.Names[0].IsExported() { - w.addFailuref(f, "tag on not-exported field %s", f.Names[0].Name) - } - - tags, err := structtag.Parse(strings.Trim(f.Tag.Value, "`")) - if err != nil || tags == nil { - w.addFailuref(f.Tag, "malformed tag") - return - } - - for _, tag := range tags.Tags() { - if msg, ok := w.checkTagNameIfNeed(checkCtx, tag); !ok { - w.addFailureWithTagKey(f.Tag, msg, tag.Key) - } - - if msg, ok := checkOptionsOnIgnoredField(tag); !ok { - w.addFailureWithTagKey(f.Tag, msg, tag.Key) - } - - checker, ok := w.tagCheckers[tagKey(tag.Key)] - if !ok { - continue // we don't have a checker for the tag - } - - msg, ok := checker(checkCtx, tag, f.Type) - if !ok { - w.addFailureWithTagKey(f.Tag, msg, tag.Key) - } - } -} - -func (w lintStructTagRule) checkTagNameIfNeed(checkCtx *checkContext, tag *structtag.Tag) (message string, succeeded bool) { - isUnnamedTag := tag.Name == "" || tag.Name == "-" - if isUnnamedTag { - return "", true - } - - key := tagKey(tag.Key) - switch key { - case keyBSON, keyJSON, keyXML, keyYAML, keyProtobuf, keySpanner: - default: - return "", true - } - - tagName := w.getTagName(tag) - if tagName == "" { - return "", true // No tag name found - } - - // We concat the key and name as the mapping key here - // to allow the same tag name in different tag type. - mapKey := tag.Key + ":" + tagName - if _, ok := checkCtx.usedTagName[mapKey]; ok { - return fmt.Sprintf("duplicated tag name %q", tagName), false - } - - checkCtx.usedTagName[mapKey] = true - - return "", true -} - -func (lintStructTagRule) getTagName(tag *structtag.Tag) string { - key := tagKey(tag.Key) - switch key { - case keyProtobuf: - for _, option := range tag.Options { - if tagKey, found := strings.CutPrefix(option, "name="); found { - return tagKey - } - } - return "" // protobuf tag lacks 'name' option - default: - return tag.Name - } -} - -func checkASN1Tag(checkCtx *checkContext, tag *structtag.Tag, fieldType ast.Expr) (message string, succeeded bool) { - checkList := slices.Concat(tag.Options, []string{tag.Name}) - for _, opt := range checkList { - switch opt { - case "application", "explicit", "generalized", "ia5", "omitempty", "optional", "set", "utf8": - // do nothing - default: - msg, ok := checkCompoundANS1Option(checkCtx, opt, fieldType) - if !ok { - return msg, false - } - } - } - - return "", true -} - -func checkCompoundANS1Option(checkCtx *checkContext, opt string, fieldType ast.Expr) (message string, succeeded bool) { - key, value, _ := strings.Cut(opt, ":") - switch key { - case "tag": - number, err := strconv.Atoi(value) - if err != nil { - return fmt.Sprintf("tag must be a number but is %q", value), false - } - if checkCtx.usedTagNbr[number] { - return fmt.Sprintf(msgDuplicatedTagNumber, number), false - } - checkCtx.usedTagNbr[number] = true - case "default": - if !typeValueMatch(fieldType, value) { - return msgTypeMismatch, false - } - default: - if !checkCtx.isUserDefined(keyASN1, opt) { - return fmt.Sprintf(msgUnknownOption, opt), false - } - } - return "", true -} - -func checkDatastoreTag(checkCtx *checkContext, tag *structtag.Tag, _ ast.Expr) (message string, succeeded bool) { - for _, opt := range tag.Options { - switch opt { - case "flatten", "noindex", "omitempty": - default: - if checkCtx.isUserDefined(keyDatastore, opt) { - continue - } - return fmt.Sprintf(msgUnknownOption, opt), false - } - } - - return "", true -} - -func checkDefaultTag(_ *checkContext, tag *structtag.Tag, fieldType ast.Expr) (message string, succeeded bool) { - if !typeValueMatch(fieldType, tag.Name) { - return msgTypeMismatch, false - } - - return "", true -} - -func checkBSONTag(checkCtx *checkContext, tag *structtag.Tag, _ ast.Expr) (message string, succeeded bool) { - for _, opt := range tag.Options { - switch opt { - case "inline", "minsize", "omitempty": - default: - if checkCtx.isUserDefined(keyBSON, opt) { - continue - } - return fmt.Sprintf(msgUnknownOption, opt), false - } - } - - return "", true -} - -func checkJSONTag(checkCtx *checkContext, tag *structtag.Tag, _ ast.Expr) (message string, succeeded bool) { - for _, opt := range tag.Options { - switch opt { - case "omitempty", "string": - case "": - // special case for JSON key "-" - if tag.Name != "-" { - return "option can not be empty", false - } - case "omitzero": - if checkCtx.isAtLeastGo124 { - continue - } - return `prior Go 1.24, option "omitzero" is unsupported`, false - default: - if checkCtx.isUserDefined(keyJSON, opt) { - continue - } - return fmt.Sprintf(msgUnknownOption, opt), false - } - } - - return "", true -} - -func checkMapstructureTag(checkCtx *checkContext, tag *structtag.Tag, _ ast.Expr) (message string, succeeded bool) { - for _, opt := range tag.Options { - switch opt { - case "omitempty", "reminder", "squash": - default: - if checkCtx.isUserDefined(keyMapstructure, opt) { - continue - } - return fmt.Sprintf(msgUnknownOption, opt), false - } - } - - return "", true -} - -func checkPropertiesTag(_ *checkContext, tag *structtag.Tag, fieldType ast.Expr) (message string, succeeded bool) { - options := tag.Options - if len(options) == 0 { - return "", true - } - - seenOptions := map[string]bool{} - for _, opt := range options { - msg, ok := fmt.Sprintf("unknown or malformed option %q", opt), false - if key, value, found := strings.Cut(opt, "="); found { - msg, ok = checkCompoundPropertiesOption(key, value, fieldType, seenOptions) - } - - if !ok { - return msg, false - } - } - - return "", true -} - -func checkCompoundPropertiesOption(key, value string, fieldType ast.Expr, seenOptions map[string]bool) (message string, succeeded bool) { - if _, ok := seenOptions[key]; ok { - return fmt.Sprintf(msgDuplicatedOption, key), false - } - seenOptions[key] = true - - if strings.TrimSpace(value) == "" { - return fmt.Sprintf("option %q not of the form %s=value", key, key), false - } - - switch key { - case "default": - if !typeValueMatch(fieldType, value) { - return msgTypeMismatch, false - } - case "layout": - if astutils.GoFmt(fieldType) != "time.Time" { - return "layout option is only applicable to fields of type time.Time", false - } - } - - return "", true -} - -func checkProtobufTag(checkCtx *checkContext, tag *structtag.Tag, _ ast.Expr) (message string, succeeded bool) { - // check name - switch tag.Name { - case "bytes", "fixed32", "fixed64", "group", "varint", "zigzag32", "zigzag64": - // do nothing - default: - return fmt.Sprintf("invalid tag name %q", tag.Name), false - } - - return checkProtobufOptions(checkCtx, tag.Options) -} - -func checkProtobufOptions(checkCtx *checkContext, options []string) (message string, succeeded bool) { - seenOptions := map[string]bool{} - hasName := false - for _, opt := range options { - opt := strings.Split(opt, "=")[0] - - if number, err := strconv.Atoi(opt); err == nil { - _, alreadySeen := checkCtx.usedTagNbr[number] - if alreadySeen { - return fmt.Sprintf(msgDuplicatedTagNumber, number), false - } - checkCtx.usedTagNbr[number] = true - continue // option is an integer - } - - switch opt { - case "json", "opt", "proto3", "rep", "req": - // do nothing - case "name": - hasName = true - default: - if checkCtx.isUserDefined(keyProtobuf, opt) { - continue - } - return fmt.Sprintf(msgUnknownOption, opt), false - } - - _, alreadySeen := seenOptions[opt] - if alreadySeen { - return fmt.Sprintf(msgDuplicatedOption, opt), false - } - seenOptions[opt] = true - } - - if !hasName { - return `mandatory option "name" not found`, false - } - - return "", true -} - -func checkRequiredTag(_ *checkContext, tag *structtag.Tag, _ ast.Expr) (message string, succeeded bool) { - switch tag.Name { - case "true", "false": - return "", true - default: - return `required should be "true" or "false"`, false - } -} - -func checkTOMLTag(checkCtx *checkContext, tag *structtag.Tag, _ ast.Expr) (message string, succeeded bool) { - for _, opt := range tag.Options { - switch opt { - case "omitempty": - default: - if checkCtx.isUserDefined(keyTOML, opt) { - continue - } - return fmt.Sprintf(msgUnknownOption, opt), false - } - } - - return "", true -} - -func checkURLTag(checkCtx *checkContext, tag *structtag.Tag, _ ast.Expr) (message string, succeeded bool) { - var delimiter = "" - for _, opt := range tag.Options { - switch opt { - case "int", "omitempty", "numbered", "brackets", - "unix", "unixmilli", "unixnano": // TODO : check that the field is of type time.Time - case "comma", "semicolon", "space": - if delimiter == "" { - delimiter = opt - continue - } - return fmt.Sprintf("can not set both %q and %q as delimiters", opt, delimiter), false - default: - if checkCtx.isUserDefined(keyURL, opt) { - continue - } - return fmt.Sprintf(msgUnknownOption, opt), false - } - } - - return "", true -} - -func checkValidateTag(checkCtx *checkContext, tag *structtag.Tag, _ ast.Expr) (message string, succeeded bool) { - previousOption := "" - seenKeysOption := false - options := append([]string{tag.Name}, tag.Options...) - for _, opt := range options { - switch opt { - case "keys": - if previousOption != "dive" { - return `option "keys" must follow a "dive" option`, false - } - seenKeysOption = true - case "endkeys": - if !seenKeysOption { - return `option "endkeys" without a previous "keys" option`, false - } - seenKeysOption = false - default: - parts := strings.Split(opt, "|") - errMsg, ok := checkValidateOptionsAlternatives(checkCtx, parts) - if !ok { - return errMsg, false - } - } - previousOption = opt - } - - return "", true -} - -func checkXMLTag(checkCtx *checkContext, tag *structtag.Tag, _ ast.Expr) (message string, succeeded bool) { - for _, opt := range tag.Options { - switch opt { - case "any", "attr", "cdata", "chardata", "comment", "innerxml", "omitempty", "typeattr": - default: - if checkCtx.isUserDefined(keyXML, opt) { - continue - } - return fmt.Sprintf(msgUnknownOption, opt), false - } - } - - return "", true -} - -func checkYAMLTag(checkCtx *checkContext, tag *structtag.Tag, _ ast.Expr) (message string, succeeded bool) { - for _, opt := range tag.Options { - switch opt { - case "flow", "inline", "omitempty": - default: - if checkCtx.isUserDefined(keyYAML, opt) { - continue - } - return fmt.Sprintf(msgUnknownOption, opt), false - } - } - - return "", true -} - -func checkSpannerTag(checkCtx *checkContext, tag *structtag.Tag, _ ast.Expr) (message string, succeeded bool) { - for _, opt := range tag.Options { - if !checkCtx.isUserDefined(keySpanner, opt) { - return fmt.Sprintf(msgUnknownOption, opt), false - } - } - - return "", true -} - -// checkOptionsOnIgnoredField checks if an ignored struct field (tag name "-") has any options specified. -// It returns a message and false if there are useless options present, or an empty message and true if valid. -func checkOptionsOnIgnoredField(tag *structtag.Tag) (message string, succeeded bool) { - if tag.Name != "-" { - return "", true - } - - switch len(tag.Options) { - case 0: - return "", true - case 1: - opt := strings.TrimSpace(tag.Options[0]) - if opt == "" { - return "", true // accept "-," as options - } - - return fmt.Sprintf("useless option %s for ignored field", opt), false - default: - return fmt.Sprintf("useless options %s for ignored field", strings.Join(tag.Options, ",")), false - } -} - -func checkValidateOptionsAlternatives(checkCtx *checkContext, alternatives []string) (message string, succeeded bool) { - for _, alternative := range alternatives { - alternative := strings.TrimSpace(alternative) - lhs, _, found := strings.Cut(alternative, "=") - if found { - _, ok := validateLHS[lhs] - if ok || checkCtx.isUserDefined(keyValidate, lhs) { - continue - } - return fmt.Sprintf(msgUnknownOption, lhs), false - } - - badOpt, ok := areValidateOpts(alternative) - if ok || checkCtx.isUserDefined(keyValidate, badOpt) { - continue - } - - return fmt.Sprintf(msgUnknownOption, badOpt), false - } - - return "", true -} - -func typeValueMatch(t ast.Expr, val string) bool { - tID, ok := t.(*ast.Ident) - if !ok { - return true - } - - typeMatches := true - switch tID.Name { - case "bool": - typeMatches = val == "true" || val == "false" - case "float64": - _, err := strconv.ParseFloat(val, 64) - typeMatches = err == nil - case "int": - _, err := strconv.ParseInt(val, 10, 64) - typeMatches = err == nil - default: // "string", "nil", ... - // unchecked type - } - - return typeMatches -} - -func (w lintStructTagRule) addFailureWithTagKey(n ast.Node, msg, tagKey string) { - w.addFailuref(n, "%s in %s tag", msg, tagKey) -} - -func (w lintStructTagRule) addFailuref(n ast.Node, msg string, args ...any) { - w.onFailure(lint.Failure{ - Node: n, - Failure: fmt.Sprintf(msg, args...), - Confidence: 1, - }) -} - -func areValidateOpts(opts string) (string, bool) { - parts := strings.Split(opts, "|") - for _, opt := range parts { - _, ok := validateSingleOptions[opt] - if !ok { - return opt, false - } - } - - return "", true -} - -const ( - msgDuplicatedOption = "duplicated option %q" - msgDuplicatedTagNumber = "duplicated tag number %v" - msgUnknownOption = "unknown option %q" - msgTypeMismatch = "type mismatch between field type and default value type" -) - -var validateSingleOptions = map[string]struct{}{ - "alpha": {}, - "alphanum": {}, - "alphanumunicode": {}, - "alphaunicode": {}, - "ascii": {}, - "base32": {}, - "base64": {}, - "base64rawurl": {}, - "base64url": {}, - "bcp47_language_tag": {}, - "bic": {}, - "boolean": {}, - "btc_addr": {}, - "btc_addr_bech32": {}, - "cidr": {}, - "cidrv4": {}, - "cidrv6": {}, - "credit_card": {}, - "cron": {}, - "cve": {}, - "datauri": {}, - "dir": {}, - "dirpath": {}, - "dive": {}, - "dns_rfc1035_label": {}, - "e164": {}, - "ein": {}, - "email": {}, - "eth_addr": {}, - "eth_addr_checksum": {}, - "file": {}, - "filepath": {}, - "fqdn": {}, - "hexadecimal": {}, - "hexcolor": {}, - "hostname": {}, - "hostname_port": {}, - "hostname_rfc1123": {}, - "hsl": {}, - "hsla": {}, - "html": {}, - "html_encoded": {}, - "http_url": {}, - "image": {}, - "ip": {}, - "ip_addr": {}, - "ip4_addr": {}, - "ip6_addr": {}, - "ipv4": {}, - "ipv6": {}, - "isbn": {}, - "isbn10": {}, - "isbn13": {}, - "isdefault": {}, - "iso3166_1_alpha_numeric": {}, - "iso3166_1_alpha_numeric_eu": {}, - "iso3166_1_alpha2": {}, - "iso3166_1_alpha2_eu": {}, - "iso3166_1_alpha3": {}, - "iso3166_1_alpha3_eu": {}, - "iso3166_2": {}, - "iso4217": {}, - "iso4217_numeric": {}, - "issn": {}, - "json": {}, - "jwt": {}, - "latitude": {}, - "longitude": {}, - "lowercase": {}, - "luhn_checksum": {}, - "mac": {}, - "md4": {}, - "md5": {}, - "mongodb": {}, - "mongodb_connection_string": {}, - "multibyte": {}, - "number": {}, - "numeric": {}, - "port": {}, - "postcode_iso3166_alpha2": {}, - "postcode_iso3166_alpha2_field": {}, - "printascii": {}, - "required": {}, - "rgb": {}, - "rgba": {}, - "ripemd128": {}, - "ripemd160": {}, - "semver": {}, - "sha256": {}, - "sha384": {}, - "sha512": {}, - "ssn": {}, - "tcp_addr": {}, - "tcp4_addr": {}, - "tcp6_addr": {}, - "tiger128": {}, - "tiger160": {}, - "tiger192": {}, - "timezone": {}, - "udp_addr": {}, - "udp4_addr": {}, - "udp6_addr": {}, - "ulid": {}, - "unix_addr": {}, - "uppercase": {}, - "uri": {}, - "url": {}, - "url_encoded": {}, - "urn_rfc2141": {}, - "uuid": {}, - "uuid_rfc4122": {}, - "uuid3": {}, - "uuid3_rfc4122": {}, - "uuid4": {}, - "uuid4_rfc4122": {}, - "uuid5": {}, - "uuid5_rfc4122": {}, -} - -// These are options that are used in expressions of the form: -// -//